[
  {
    "path": ".cargo/config.toml",
    "content": "[alias]\nbless = \"test --config env.RUSTC_BLESS='1'\"\nuitest = \"test --test compile-test\"\nuibless = \"bless --test compile-test\"\ndev = \"run --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --\"\nlintcheck = \"run --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml  -- \"\ncollect-metadata = \"test --test compile-test --config env.COLLECT_METADATA='1'\"\n\n[build]\n# -Zbinary-dep-depinfo allows us to track which rlib files to use for compiling UI tests\nrustflags = [\"-Zunstable-options\", \"-Zbinary-dep-depinfo\"]\ntarget-dir = \"target\"\n\n[unstable]\nbinary-dep-depinfo = true\nprofile-rustflags = true\n\n[profile.dev]\nsplit-debuginfo = \"unpacked\"\n\n# Add back the containing directory of the packages we have to refer to using --manifest-path\n[profile.dev.package.clippy_dev]\nrustflags = [\"--remap-path-prefix\", \"=clippy_dev\"]\n[profile.dev.package.lintcheck]\nrustflags = [\"--remap-path-prefix\", \"=lintcheck\"]\n\n# quine-mc_cluskey makes up a significant part of the runtime in dogfood\n# due to the number of conditions in the clippy_lints crate\n# and enabling optimizations for that specific dependency helps a bit\n# without increasing total build times.\n[profile.dev.package.quine-mc_cluskey]\nopt-level = 3\n"
  },
  {
    "path": ".editorconfig",
    "content": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# editorconfig.org\n\nroot = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\nindent_style = space\nindent_size = 4\nmax_line_length = 120\n\n[*.md]\n# double whitespace at end of line\n# denotes a line break in Markdown\ntrim_trailing_whitespace = false\n\n[*.yml]\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n*.rs text eol=lf whitespace=tab-in-indent,trailing-space,tabwidth=4\n*.fixed linguist-language=Rust\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/blank_issue.yml",
    "content": "name: Blank Issue\ndescription: Create a blank issue.\nbody:\n  - type: markdown\n    attributes:\n      value: Thank you for filing an issue!\n  - type: textarea\n    id: problem\n    attributes:\n      label: Description\n      description: >\n        Please provide a description of the issue, along with any information\n        you feel relevant to replicate it.\n    validations:\n      required: true\n  - type: textarea\n    id: version\n    attributes:\n      label: Version\n      description: \"Rust version (`rustc -Vv`)\"\n      placeholder: |\n        rustc 1.46.0-nightly (f455e46ea 2020-06-20)\n        binary: rustc\n        commit-hash: f455e46eae1a227d735091091144601b467e1565\n        commit-date: 2020-06-20\n        host: x86_64-unknown-linux-gnu\n        release: 1.46.0-nightly\n        LLVM version: 10.0\n      render: text\n  - type: textarea\n    id: labels\n    attributes:\n      label: Additional Labels\n      description: >\n        Additional labels can be added to this issue by including the following\n        command\n      placeholder: |\n        @rustbot label +<label>\n\n        Common labels for this issue type are:\n        * C-an-interesting-project\n        * C-enhancement\n        * C-question\n        * C-tracking-issue\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "content": "name: Bug Report\ndescription: Create a bug report for Clippy\nlabels: [\"C-bug\"]\nbody:\n  - type: markdown\n    attributes:\n      value: Thank you for filing a bug report! 🐛\n  - type: textarea\n    id: problem\n    attributes:\n      label: Summary\n      description: >\n        Please provide a short summary of the bug, along with any information\n        you feel relevant to replicate the bug.\n    validations:\n      required: true\n  - type: textarea\n    id: reproducer\n    attributes:\n      label: Reproducer\n      description: Please provide the code and steps to reproduce the bug\n      value: |\n        Code:\n\n        ```rust\n        <code>\n        ```\n\n        Current output:\n\n        Desired output:\n  - type: textarea\n    id: version\n    attributes:\n      label: Version\n      description: \"Rust version (`rustc -Vv`)\"\n      placeholder: |\n        rustc 1.46.0-nightly (f455e46ea 2020-06-20)\n        binary: rustc\n        commit-hash: f455e46eae1a227d735091091144601b467e1565\n        commit-date: 2020-06-20\n        host: x86_64-unknown-linux-gnu\n        release: 1.46.0-nightly\n        LLVM version: 10.0\n      render: text\n  - type: textarea\n    id: labels\n    attributes:\n      label: Additional Labels\n      description: >\n        Additional labels can be added to this issue by including the following\n        command\n      placeholder: |\n        @rustbot label +<label>\n\n        Common labels for this issue type are:\n        * `I-suggestion-causes-error`\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: true\ncontact_links:\n  - name: Rust Programming Language Forum\n    url: https://users.rust-lang.org\n    about: Please ask and answer questions about Rust here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/false_negative.yml",
    "content": "name: Bug Report (False Negative)\ndescription: Create a bug report about missing warnings from a lint\nlabels: [\"C-bug\", \"I-false-negative\"]\nbody:\n  - type: markdown\n    attributes:\n      value: Thank you for filing a bug report! 🐛\n  - type: textarea\n    id: problem\n    attributes:\n      label: Summary\n      description: >\n        Please provide a short summary of the bug, along with any information\n        you feel relevant to replicate the bug.\n    validations:\n      required: true\n  - type: input\n    id: lint-name\n    attributes:\n      label: Lint Name\n      description: Please provide the lint name.\n  - type: textarea\n    id: reproducer\n    attributes:\n      label: Reproducer\n      description: Please provide the code and steps to reproduce the bug\n      value: |\n        I tried this code:\n\n        ```rust\n        <code>\n        ```\n\n        I expected to see this happen:\n\n        Instead, this happened:\n  - type: textarea\n    id: version\n    attributes:\n      label: Version\n      description: \"Rust version (`rustc -Vv`)\"\n      placeholder: |\n        rustc 1.46.0-nightly (f455e46ea 2020-06-20)\n        binary: rustc\n        commit-hash: f455e46eae1a227d735091091144601b467e1565\n        commit-date: 2020-06-20\n        host: x86_64-unknown-linux-gnu\n        release: 1.46.0-nightly\n        LLVM version: 10.0\n      render: text\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/false_positive.yml",
    "content": "name: Bug Report (False Positive)\ndescription: Create a bug report about a wrongly emitted lint warning\nlabels: [\"C-bug\", \"I-false-positive\"]\nbody:\n  - type: markdown\n    attributes:\n      value: Thank you for filing a bug report! 🐛\n  - type: textarea\n    id: problem\n    attributes:\n      label: Summary\n      description: >\n        Please provide a short summary of the bug, along with any information\n        you feel relevant to replicate the bug.\n    validations:\n      required: true\n  - type: input\n    id: lint-name\n    attributes:\n      label: Lint Name\n      description: Please provide the lint name.\n  - type: textarea\n    id: reproducer\n    attributes:\n      label: Reproducer\n      description: >\n        Please provide the code and steps to reproduce the bug together with the\n        output from Clippy.\n      value: |\n        I tried this code:\n\n        ```rust\n        <code>\n        ```\n\n        I saw this happen:\n\n        ```\n        <output>\n        ```\n\n        I expected to see this happen:\n  - type: textarea\n    id: version\n    attributes:\n      label: Version\n      description: \"Rust version (`rustc -Vv`)\"\n      placeholder: |\n        rustc 1.46.0-nightly (f455e46ea 2020-06-20)\n        binary: rustc\n        commit-hash: f455e46eae1a227d735091091144601b467e1565\n        commit-date: 2020-06-20\n        host: x86_64-unknown-linux-gnu\n        release: 1.46.0-nightly\n        LLVM version: 10.0\n      render: text\n  - type: textarea\n    id: labels\n    attributes:\n      label: Additional Labels\n      description: >\n        Additional labels can be added to this issue by including the following\n        command\n      placeholder: |\n        @rustbot label +<label>\n\n        Common labels for this issue type are:\n        * `I-suggestion-causes-error`\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/ice.yml",
    "content": "name: Internal Compiler Error\ndescription: Create a report for an internal compiler error (ICE) in Clippy.\nlabels: [\"C-bug\", \"I-ICE\"]\nbody:\n  - type: markdown\n    attributes:\n      value: Thank you for finding an Internal Compiler Error! 🧊\n  - type: textarea\n    id: problem\n    attributes:\n      label: Summary\n      description: |\n        If possible, try to provide a minimal verifiable example. You can read [\"Rust Bug Minimization Patterns\"][mve] for how to create smaller examples. Otherwise, provide the crate where the ICE occurred.\n\n        [mve]: http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/\n    validations:\n      required: true\n  - type: textarea\n    id: version\n    attributes:\n      label: Version\n      description: \"Rust version (`rustc -Vv`)\"\n      placeholder: |\n        rustc 1.46.0-nightly (f455e46ea 2020-06-20)\n        binary: rustc\n        commit-hash: f455e46eae1a227d735091091144601b467e1565\n        commit-date: 2020-06-20\n        host: x86_64-unknown-linux-gnu\n        release: 1.46.0-nightly\n        LLVM version: 10.0\n      render: text\n  - type: textarea\n    id: error\n    attributes:\n      label: Error output\n      description: >\n        Include a backtrace in the code block by setting `RUST_BACKTRACE=1` in\n        your environment. E.g. `RUST_BACKTRACE=1 cargo clippy`.\n      value: |\n        <details><summary>Backtrace</summary>\n          <p>\n\n          ```\n          <backtrace>\n          ```\n\n          </p>\n        </details>\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/new_lint.yml",
    "content": "name: New lint suggestion\ndescription: Suggest a new Clippy lint.\nlabels: [\"A-lint\"]\nbody:\n  - type: markdown\n    attributes:\n      value: Thank you for your lint idea!\n  - type: textarea\n    id: what\n    attributes:\n      label: What it does\n      description: What does this lint do?\n    validations:\n      required: true\n  - type: textarea\n    id: advantage\n    attributes:\n      label: Advantage\n      description: >\n        What is the advantage of the recommended code over the original code?\n      placeholder: |\n        - Remove bounds check inserted by ...\n        - Remove the need to duplicate/store ...\n        - Remove typo ...\n  - type: textarea\n    id: drawbacks\n    attributes:\n      label: Drawbacks\n      description: What might be possible drawbacks of such a lint?\n  - type: textarea\n    id: example\n    attributes:\n      label: Example\n      description: >\n        Include a short example showing when the lint should trigger together\n        with the improved code.\n      value: |\n        ```rust\n        <code>\n        ```\n\n        Could be written as:\n\n        ```rust\n        <code>\n        ```\n    validations:\n      required: true\n  - type: textarea\n    id: comparison\n    attributes:\n      label: Comparison with existing lints\n      description: |\n        What makes this lint different from any existing lints that are similar, and how are those differences useful?\n\n        You can [use this playground template to see what existing lints are triggered by the bad code][playground]\n        (make sure to use \"Tools > Clippy\" and not \"Build\").\n        You can also look through the list of [rustc's allowed-by-default lints][allowed-by-default],\n        as those won't show up in the playground above.\n\n        [allowed-by-default]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html\n\n        [playground]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&code=%23%21%5Bwarn%28clippy%3A%3Apedantic%29%5D%0A%23%21%5Bwarn%28clippy%3A%3Anursery%29%5D%0A%23%21%5Bwarn%28clippy%3A%3Arestriction%29%5D%0A%23%21%5Bwarn%28clippy%3A%3Aall%29%5D%0A%23%21%5Ballow%28clippy%3A%3Ablanket_clippy_restriction_lints%2C+reason+%3D+%22testing+to+see+if+any+restriction+lints+match+given+code%22%29%5D%0A%0A%2F%2F%21+Template+that+can+be+used+to+see+what+clippy+lints+a+given+piece+of+code+would+trigger\n      placeholder: Unlike `clippy::...`, the proposed lint would...\n  - type: textarea\n    id: context\n    attributes:\n      label: Additional Context\n      description: Any additional context that you believe may be relevant.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "Thank you for making Clippy better!\n\nWe're collecting our changelog from pull request descriptions.\nIf your PR only includes internal changes, you can just write\n`changelog: none`. Otherwise, please write a short comment\nexplaining your change.\n\nIt's also helpful for us that the lint name is put within backticks (`` ` ` ``),\nand then encapsulated by square brackets (`[]`), for example:\n```\nchangelog: [`lint_name`]: your change\n```\n\nIf your PR fixes an issue, you can add `fixes #issue_number` into this\nPR description. This way the issue will be automatically closed when\nyour PR is merged.\n\nIf you added a new lint, here's a checklist for things that will be\nchecked during review or continuous integration.\n\n- \\[ ] Followed [lint naming conventions][lint_naming]\n- \\[ ] Added passing UI tests (including committed `.stderr` file)\n- \\[ ] `cargo test` passes locally\n- \\[ ] Executed `cargo dev update_lints`\n- \\[ ] Added lint documentation\n- \\[ ] Run `cargo dev fmt`\n\n[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints\n\nNote that you can skip the above if you are just opening a WIP PR in\norder to get feedback.\n\nDelete this line and everything above before opening your PR.\n\n---\n\n*Please write a short comment explaining your change (or \"none\" for internal only changes)*\n\nchangelog:\n"
  },
  {
    "path": ".github/deploy.sh",
    "content": "#!/bin/bash\n\nset -ex\n\necho \"Removing the current docs for master\"\nrm -rf out/master/ || exit 0\n\necho \"Making the docs for master\"\nmkdir out/master/\ncp util/gh-pages/index.html out/master\ncp util/gh-pages/theme.js out/master\ncp util/gh-pages/script.js out/master\ncp util/gh-pages/style.css out/master\n\nif [[ -n $TAG_NAME ]]; then\n  echo \"Save the doc for the current tag ($TAG_NAME) and point stable/ to it\"\n  cp -Tr out/master \"out/$TAG_NAME\"\n  rm -f out/stable\n  ln -s \"$TAG_NAME\" out/stable\nfi\n\nif [[ $BETA = \"true\" ]]; then\n  echo \"Update documentation for the beta release\"\n  cp -r out/master/* out/beta\nfi\n\n# Generate version index that is shown as root index page\npython3 ./util/versions.py ./util/gh-pages/versions.html out\n\n# Now let's go have some fun with the cloned repo\ncd out\ngit config user.name \"GHA CI\"\ngit config user.email \"gha@ci.invalid\"\n\ngit status\n\nif [[ -n $TAG_NAME ]]; then\n  # track files, so that the following check works\n  git add --intent-to-add \"$TAG_NAME\"\n  if git diff --exit-code --quiet -- $TAG_NAME/; then\n    echo \"No changes to the output on this push; exiting.\"\n    exit 0\n  fi\n  # Add the new dir\n  git add \"$TAG_NAME\"\n  # Update the symlink\n  git add stable\n  # Update the index.html file\n  git add index.html\n  git commit -m \"Add documentation for ${TAG_NAME} release: ${SHA}\"\nelif [[ $BETA = \"true\" ]]; then\n  if git diff --exit-code --quiet -- beta/; then\n    echo \"No changes to the output on this push; exiting.\"\n    exit 0\n  fi\n  git add beta\n  git commit -m \"Automatic deploy to GitHub Pages (beta): ${SHA}\"\nelse\n  if git diff --exit-code --quiet; then\n    echo \"No changes to the output on this push; exiting.\"\n    exit 0\n  fi\n  git add .\n  git commit -m \"Automatic deploy to GitHub Pages: ${SHA}\"\nfi\n\ngit push \"$SSH_REPO\" \"$TARGET_BRANCH\"\n"
  },
  {
    "path": ".github/driver.sh",
    "content": "#!/bin/bash\n\nset -ex\n\nsysroot=\"$(rustc --print sysroot)\"\ncase $OS in\n    Linux) export LD_LIBRARY_PATH=\"$sysroot/lib\" ;;\n    macOS) export DYLD_FALLBACK_LIBRARY_PATH=\"$sysroot/lib\" ;;\n    Windows) export PATH=\"$(cygpath \"$sysroot\")/bin:$PATH\" ;;\n    *) exit 1\nesac\n\n# Check sysroot handling\ntest \"$(./target/debug/clippy-driver --print sysroot)\" = \"$sysroot\"\n\ndesired_sysroot=\"target/sysroot\"\n# Set --sysroot in command line\nsysroot=$(./target/debug/clippy-driver --sysroot $desired_sysroot --print sysroot)\ntest \"$sysroot\" = $desired_sysroot\n\n# Set --sysroot in arg_file.txt and pass @arg_file.txt to command line\necho \"--sysroot=$desired_sysroot\" > arg_file.txt\nsysroot=$(./target/debug/clippy-driver @arg_file.txt --print sysroot)\ntest \"$sysroot\" = $desired_sysroot\n\n# Setting SYSROOT in command line\nsysroot=$(SYSROOT=$desired_sysroot ./target/debug/clippy-driver --print sysroot)\ntest \"$sysroot\" = $desired_sysroot\n\n# Check that the --sysroot argument is only passed once (SYSROOT is ignored)\n(\n    cd rustc_tools_util\n    touch src/lib.rs\n    SYSROOT=/tmp RUSTFLAGS=\"--sysroot=$(rustc --print sysroot)\" ../target/debug/cargo-clippy clippy --verbose\n)\n\n# Check that the --sysroot argument is only passed once via arg_file.txt (SYSROOT is ignored)\n(\n    echo \"fn main() {}\" > target/driver_test.rs\n    echo \"--sysroot=\"$(./target/debug/clippy-driver --print sysroot)\"\" > arg_file.txt\n    echo \"--verbose\" >> arg_file.txt\n    SYSROOT=/tmp ./target/debug/clippy-driver @arg_file.txt ./target/driver_test.rs\n)\n\n# Make sure this isn't set - clippy-driver should cope without it\nunset CARGO_MANIFEST_DIR\n\n# Run a lint and make sure it produces the expected output. It's also expected to exit with code 1\n# FIXME: How to match the clippy invocation in compile-test.rs?\n./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/char_lit_as_u8.rs 2>char_lit_as_u8.stderr && exit 1\nsed -e \"/= help: for/d\" char_lit_as_u8.stderr > normalized.stderr\ndiff -u normalized.stderr tests/ui/char_lit_as_u8.stderr\n\n# make sure \"clippy-driver --rustc --arg\" and \"rustc --arg\" behave the same\nSYSROOT=$(rustc --print sysroot)\ndiff -u <(./target/debug/clippy-driver --rustc --version --verbose) <(rustc --version --verbose)\n\necho \"fn main() {}\" >target/driver_test.rs\n# we can't run 2 rustcs on the same file at the same time\nCLIPPY=$(./target/debug/clippy-driver ./target/driver_test.rs --rustc)\nRUSTC=$(rustc ./target/driver_test.rs)\ndiff -u <($CLIPPY) <($RUSTC)\n\n# TODO: CLIPPY_CONF_DIR / CARGO_MANIFEST_DIR\n"
  },
  {
    "path": ".github/workflows/clippy_changelog.yml",
    "content": "name: Clippy changelog check\n\non:\n  merge_group:\n  pull_request:\n    types: [opened, reopened, synchronize, edited]\n\nconcurrency:\n  # For a given workflow, if we push to the same PR, cancel all previous builds on that PR.\n  # If the push is not attached to a PR, we will cancel all builds on the same branch.\n  group: \"${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\"\n  cancel-in-progress: true\n\njobs:\n  changelog:\n    runs-on: ubuntu-latest\n\n    steps:\n    # Run\n    - name: Check Changelog\n      if: ${{ github.event_name == 'pull_request' }}\n      run: |\n        # Checks that the PR body contains a changelog entry, ignoring the placeholder from the PR template.\n        if [[ -z $(grep -oP 'changelog: *\\K(?!\\[`lint_name`\\])\\S+' <<< \"$PR_BODY\") ]]; then\n          echo \"::error::Pull request message must contain 'changelog: ...' with your changelog. Please add it.\"\n          exit 1\n        fi\n      env:\n        PR_BODY: ${{ github.event.pull_request.body }})\n\n\n  # We need to have the \"conclusion\" job also on PR CI, to make it possible\n  # to add PRs to a merge queue.\n  conclusion_changelog:\n    needs: [ changelog ]\n    # We need to ensure this job does *not* get skipped if its dependencies fail,\n    # because a skipped job is considered a success by GitHub. So we have to\n    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run\n    # when the workflow is canceled manually.\n    #\n    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!\n    if: ${{ !cancelled() }}\n    runs-on: ubuntu-latest\n    steps:\n      # Manually check the status of all dependencies. `if: failure()` does not work.\n      - name: Conclusion\n        run: |\n          # Print the dependent jobs to see them in the CI log\n          jq -C <<< '${{ toJson(needs) }}'\n          # Check if all jobs that we depend on (in the needs array) were successful.\n          jq --exit-status 'all(.result == \"success\")' <<< '${{ toJson(needs) }}'\n"
  },
  {
    "path": ".github/workflows/clippy_dev.yml",
    "content": "name: Clippy Dev Test\n\non:\n  merge_group:\n  pull_request:\n\nenv:\n  RUST_BACKTRACE: 1\n  CARGO_INCREMENTAL: 0\n  RUSTFLAGS: -D warnings\n\njobs:\n  clippy_dev:\n    runs-on: ubuntu-latest\n\n    steps:\n    # Setup\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        # Unsetting this would make so that any malicious package could get our Github Token\n        persist-credentials: false\n\n    # Run\n    - name: Build\n      run: cargo build\n      working-directory: clippy_dev\n\n    - name: Test update_lints\n      run: cargo dev update_lints --check\n\n    - name: Test fmt\n      run: cargo dev fmt --check\n\n    - name: Test cargo dev new lint\n      env:\n        RUSTFLAGS: -A unused-imports\n      run: |\n        cargo dev new_lint --name new_early_pass --pass early\n        cargo dev new_lint --name new_late_pass --pass late\n        cargo check\n        git reset --hard HEAD\n\n  conclusion_dev:\n    needs: [ clippy_dev ]\n    # We need to ensure this job does *not* get skipped if its dependencies fail,\n    # because a skipped job is considered a success by GitHub. So we have to\n    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run\n    # when the workflow is canceled manually.\n    #\n    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!\n    if: ${{ !cancelled() }}\n    runs-on: ubuntu-latest\n    steps:\n      # Manually check the status of all dependencies. `if: failure()` does not work.\n      - name: Conclusion\n        run: |\n          # Print the dependent jobs to see them in the CI log\n          jq -C <<< '${{ toJson(needs) }}'\n          # Check if all jobs that we depend on (in the needs array) were successful.\n          jq --exit-status 'all(.result == \"success\")' <<< '${{ toJson(needs) }}'\n"
  },
  {
    "path": ".github/workflows/clippy_mq.yml",
    "content": "name: Clippy Test (merge queue)\n\non:\n  merge_group:\n\nenv:\n  RUST_BACKTRACE: 1\n  CARGO_TARGET_DIR: '${{ github.workspace }}/target'\n  NO_FMT_TEST: 1\n  CARGO_INCREMENTAL: 0\n  RUSTFLAGS: -D warnings\n\ndefaults:\n  run:\n    shell: bash\n\njobs:\n  base:\n    strategy:\n      matrix:\n        include:\n        - os: ubuntu-latest\n          host: x86_64-unknown-linux-gnu\n        - os: ubuntu-latest\n          host: i686-unknown-linux-gnu\n        - os: windows-latest\n          host: x86_64-pc-windows-msvc\n        - os: macos-latest\n          host: aarch64-apple-darwin\n\n    runs-on: ${{ matrix.os }}\n\n    # NOTE: If you modify this job, make sure you copy the changes to clippy.yml\n    steps:\n    # Setup\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        persist-credentials: false\n\n    - name: Install i686 dependencies\n      if: matrix.host == 'i686-unknown-linux-gnu'\n      run: |\n        sudo dpkg --add-architecture i386\n        sudo apt-get update\n        sudo apt-get install gcc-multilib zlib1g-dev:i386\n\n    - name: Install toolchain\n      run: |\n        rustup set default-host ${{ matrix.host }}\n        # Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0\n        rustup show active-toolchain || rustup toolchain install\n\n    # Run\n    - name: Build\n      run: cargo build --tests --features internal\n\n    - name: Test\n      if: matrix.host == 'x86_64-unknown-linux-gnu'\n      run: cargo test --features internal\n\n    - name: Test\n      if: matrix.host != 'x86_64-unknown-linux-gnu'\n      run: cargo test --features internal -- --skip dogfood\n\n    - name: Test clippy_lints\n      run: cargo test\n      working-directory: clippy_lints\n\n    - name: Test clippy_utils\n      run: cargo test\n      working-directory: clippy_utils\n\n    - name: Test clippy_config\n      run: cargo test\n      working-directory: clippy_config\n\n    - name: Test rustc_tools_util\n      run: cargo test\n      working-directory: rustc_tools_util\n\n    - name: Test clippy_dev\n      run: cargo test\n      working-directory: clippy_dev\n\n    - name: Test clippy-driver\n      run: .github/driver.sh\n      env:\n        OS: ${{ runner.os }}\n\n  metadata_collection:\n    runs-on: ubuntu-latest\n\n    steps:\n     # Setup\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        persist-credentials: false\n\n    - name: Install toolchain\n      run: |\n        # Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0\n        rustup show active-toolchain || rustup toolchain install\n\n    - name: Test metadata collection\n      run: cargo collect-metadata\n\n  integration_build:\n    runs-on: ubuntu-latest\n\n    steps:\n    # Setup\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        persist-credentials: false\n\n    - name: Install toolchain\n      run: |\n        # Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0\n        rustup show active-toolchain || rustup toolchain install\n\n    # Run\n    - name: Build Integration Test\n      env:\n        CARGO_PROFILE_DEV_SPLIT_DEBUGINFO: off\n      run: cargo test --test integration --features integration --no-run\n\n    # Upload\n    - name: Extract Binaries\n      run: |\n        DIR=$CARGO_TARGET_DIR/debug\n        find $DIR/deps/integration-* -executable ! -type d | xargs -I {} mv {} $DIR/integration\n        find $DIR ! -executable -o -type d ! -path $DIR | xargs rm -rf\n\n    - name: Upload Binaries\n      uses: actions/upload-artifact@v4\n      with:\n        name: binaries\n        path: target/debug\n\n  integration:\n    needs: integration_build\n    strategy:\n      fail-fast: false\n      max-parallel: 6\n      matrix:\n        integration:\n        - 'matthiaskrgr/clippy_ci_panic_test'\n        - 'rust-lang/cargo'\n        - 'rust-lang/chalk'\n        - 'rust-lang/rustfmt'\n        - 'Marwes/combine'\n        - 'Geal/nom'\n        - 'rust-lang/stdarch'\n        - 'serde-rs/serde'\n        - 'chronotope/chrono'\n        - 'hyperium/hyper'\n        - 'rust-random/rand'\n        - 'rust-lang/futures-rs'\n        - 'rust-itertools/itertools'\n        - 'rust-lang-nursery/failure'\n        - 'rust-lang/log'\n\n    runs-on: ubuntu-latest\n\n    steps:\n    # Setup\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        persist-credentials: false\n\n    - name: Install toolchain\n      run: |\n        # Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0\n        rustup show active-toolchain || rustup toolchain install\n\n    # Download\n    - name: Download target dir\n      uses: actions/download-artifact@v6\n      with:\n        name: binaries\n        path: target/debug\n\n    - name: Make Binaries Executable\n      run: chmod +x $CARGO_TARGET_DIR/debug/*\n\n    # Run\n    - name: Test ${{ matrix.integration }}\n      run: |\n          TOOLCHAIN=$(rustup show active-toolchain | head -n 1 | cut -f1 -d' ')\n          rustup run $TOOLCHAIN $CARGO_TARGET_DIR/debug/integration --show-output\n      env:\n        INTEGRATION: ${{ matrix.integration }}\n\n  conclusion:\n    needs: [ base, metadata_collection, integration_build, integration ]\n    # We need to ensure this job does *not* get skipped if its dependencies fail,\n    # because a skipped job is considered a success by GitHub. So we have to\n    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run\n    # when the workflow is canceled manually.\n    #\n    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!\n    if: ${{ !cancelled() }}\n    runs-on: ubuntu-latest\n    steps:\n      # Manually check the status of all dependencies. `if: failure()` does not work.\n      - name: Conclusion\n        run: |\n          # Print the dependent jobs to see them in the CI log\n          jq -C <<< '${{ toJson(needs) }}'\n          # Check if all jobs that we depend on (in the needs array) were successful.\n          jq --exit-status 'all(.result == \"success\")' <<< '${{ toJson(needs) }}'\n"
  },
  {
    "path": ".github/workflows/clippy_pr.yml",
    "content": "name: Clippy Test\n\non:\n  pull_request:\n\nenv:\n  RUST_BACKTRACE: 1\n  CARGO_TARGET_DIR: '${{ github.workspace }}/target'\n  NO_FMT_TEST: 1\n  CARGO_INCREMENTAL: 0\n  RUSTFLAGS: -D warnings\n\nconcurrency:\n  # For a given workflow, if we push to the same PR, cancel all previous builds on that PR.\n  # If the push is not attached to a PR, we will cancel all builds on the same branch.\n  group: \"${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\"\n  cancel-in-progress: true\n\njobs:\n  base:\n    # NOTE: If you modify this job, make sure you copy the changes to clippy_mq.yml\n    runs-on: ubuntu-latest\n\n    steps:\n    # Setup\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        # Unsetting this would make so that any malicious package could get our Github Token\n        persist-credentials: false\n\n    - name: Install toolchain\n      run: |\n        # Use a way compatible with Rustup pre-1.28.0 and Rustup 1.28.0\n        rustup show active-toolchain || rustup toolchain install\n\n    # Run\n    - name: Build\n      run: cargo build --tests --features internal\n\n    - name: Test\n      run: cargo test --features internal\n\n    - name: Test clippy_lints\n      run: cargo test\n      working-directory: clippy_lints\n\n    - name: Test clippy_utils\n      run: cargo test\n      working-directory: clippy_utils\n\n    - name: Test rustc_tools_util\n      run: cargo test\n      working-directory: rustc_tools_util\n\n    - name: Test clippy_dev\n      run: cargo test\n      working-directory: clippy_dev\n\n    - name: Test clippy-driver\n      run: .github/driver.sh\n      env:\n        OS: ${{ runner.os }}\n\n  # We need to have the \"conclusion\" job also on PR CI, to make it possible\n  # to add PRs to a merge queue.\n  conclusion:\n    needs: [ base ]\n    # We need to ensure this job does *not* get skipped if its dependencies fail,\n    # because a skipped job is considered a success by GitHub. So we have to\n    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run\n    # when the workflow is canceled manually.\n    #\n    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!\n    if: ${{ !cancelled() }}\n    runs-on: ubuntu-latest\n    steps:\n      # Manually check the status of all dependencies. `if: failure()` does not work.\n      - name: Conclusion\n        run: |\n          # Print the dependent jobs to see them in the CI log\n          jq -C <<< '${{ toJson(needs) }}'\n          # Check if all jobs that we depend on (in the needs array) were successful.\n          jq --exit-status 'all(.result == \"success\")' <<< '${{ toJson(needs) }}'\n"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "content": "name: Deploy\n\non:\n  push:\n    branches:\n      - master\n      - beta\n    tags:\n      - rust-1.**\n\nconcurrency:\n  group: ${{ github.workflow }}\n  cancel-in-progress: false\n\nenv:\n  TARGET_BRANCH: 'gh-pages'\n  SHA: '${{ github.sha }}'\n  SSH_REPO: 'git@github.com:${{ github.repository }}.git'\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    if: github.repository == 'rust-lang/rust-clippy'\n\n    steps:\n    # Setup\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        # Unsetting this would make so that any malicious package could get our Github Token\n        persist-credentials: false\n\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        ref: ${{ env.TARGET_BRANCH }}\n        path: 'out'\n        # Unsetting this would make so that any malicious package could get our Github Token\n        persist-credentials: false\n\n    # Run\n    - name: Set tag name\n      if: startswith(github.ref, 'refs/tags/')\n      run: |\n        TAG=$(basename \"${TAGNAME}\")\n        echo \"TAG_NAME=$TAG\" >> $GITHUB_ENV\n      env:\n        # Make sure that the reference gets expanded before injecting it\n        TAGNAME: ${{ github.ref }}\n    - name: Set beta to true\n      if: github.ref == 'refs/heads/beta'\n      run: echo \"BETA=true\" >> $GITHUB_ENV\n\n    # We need to check out all files that (transitively) depend on the\n    # structure of the gh-pages branch, so that we're able to change that\n    # structure without breaking the deployment.\n    - name: Use deploy files from master branch\n      run: |\n        git fetch --no-tags --prune --depth=1 origin master\n        git checkout origin/master -- .github/deploy.sh util/versions.py util/gh-pages/versions.html\n\n    # Generate lockfile for caching to avoid build problems with cached deps\n    - name: cargo generate-lockfile\n      run: cargo generate-lockfile\n\n    - name: Cache\n      uses: Swatinem/rust-cache@v2\n      with:\n        save-if: ${{ github.ref == 'refs/heads/master' }}\n\n    - name: cargo collect-metadata\n      run: cargo collect-metadata\n\n    - name: Deploy\n      run: |\n        eval \"$(ssh-agent -s)\"\n        ssh-add - <<< \"${{ secrets.DEPLOY_KEY }}\"\n        bash .github/deploy.sh\n"
  },
  {
    "path": ".github/workflows/lintcheck.yml",
    "content": "name: Lintcheck\n\non:\n  pull_request:\n    paths-ignore:\n      - 'book/**'\n      - 'util/**'\n      - 'tests/**'\n      - '*.md'\n\nenv:\n  RUST_BACKTRACE: 1\n  CARGO_INCREMENTAL: 0\n\nconcurrency:\n  # For a given workflow, if we push to the same PR, cancel all previous builds on that PR.\n  group: \"${{ github.workflow }}-${{ github.event.pull_request.number}}\"\n  cancel-in-progress: true\n\njobs:\n  # Runs lintcheck on the PR's target branch and stores the results as an artifact\n  base:\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        fetch-depth: 2\n        # Unsetting this would make so that any malicious package could get our Github Token\n        persist-credentials: false\n\n    # HEAD is the generated merge commit `refs/pull/N/merge` between the PR and `master`, `HEAD^`\n    # being the commit from `master` that is the base of the merge\n    - name: Checkout base\n      run: git checkout HEAD^\n\n    # Use the lintcheck from the PR to generate the JSON in case the PR modifies lintcheck in some\n    # way\n    - name: Checkout current lintcheck\n      run: |\n        rm -rf lintcheck\n        git checkout ${{ github.sha }} -- lintcheck\n\n    - name: Cache lintcheck bin\n      id: cache-lintcheck-bin\n      uses: actions/cache@v4\n      with:\n        path: target/debug/lintcheck\n        key: lintcheck-bin-${{ hashfiles('lintcheck/**') }}\n\n    - name: Build lintcheck\n      if: steps.cache-lintcheck-bin.outputs.cache-hit != 'true'\n      run: cargo build --manifest-path=lintcheck/Cargo.toml\n\n    - name: Create cache key\n      id: key\n      run: echo \"key=lintcheck-base-${{ hashfiles('lintcheck/**') }}-$(git rev-parse HEAD)\" >> \"$GITHUB_OUTPUT\"\n\n    - name: Cache results JSON\n      id: cache-json\n      uses: actions/cache@v4\n      with:\n        path: lintcheck-logs/ci_crates_logs.json\n        key: ${{ steps.key.outputs.key }}\n\n    - name: Run lintcheck\n      if: steps.cache-json.outputs.cache-hit != 'true'\n      run: env CLIPPY_CONF_DIR=\"$PWD/lintcheck/ci-config\" ./target/debug/lintcheck --format json --all-lints --crates-toml ./lintcheck/ci_crates.toml\n\n    - name: Upload base JSON\n      uses: actions/upload-artifact@v4\n      with:\n        name: base\n        path: lintcheck-logs/ci_crates_logs.json\n\n  # Runs lintcheck on the PR and stores the results as an artifact\n  head:\n    runs-on: ubuntu-latest\n\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        # Unsetting this would make so that any malicious package could get our Github Token\n        persist-credentials: false\n\n    - name: Cache lintcheck bin\n      id: cache-lintcheck-bin\n      uses: actions/cache@v4\n      with:\n        path: target/debug/lintcheck\n        key: lintcheck-bin-${{ hashfiles('lintcheck/**') }}\n\n    - name: Build lintcheck\n      if: steps.cache-lintcheck-bin.outputs.cache-hit != 'true'\n      run: cargo build --manifest-path=lintcheck/Cargo.toml\n\n    - name: Run lintcheck\n      run: env CLIPPY_CONF_DIR=\"$PWD/lintcheck/ci-config\" ./target/debug/lintcheck --format json --all-lints --crates-toml ./lintcheck/ci_crates.toml\n\n    - name: Upload head JSON\n      uses: actions/upload-artifact@v4\n      with:\n        name: head\n        path: lintcheck-logs/ci_crates_logs.json\n\n  # Retrieves the head and base JSON results and prints the diff to the GH actions step summary\n  diff:\n    runs-on: ubuntu-latest\n\n    needs: [base, head]\n\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        # Unsetting this would make so that any malicious package could get our Github Token\n        persist-credentials: false\n\n    - name: Restore lintcheck bin\n      uses: actions/cache/restore@v4\n      with:\n        path: target/debug/lintcheck\n        key: lintcheck-bin-${{ hashfiles('lintcheck/**') }}\n        fail-on-cache-miss: true\n\n    - name: Download JSON\n      uses: actions/download-artifact@v5\n\n    - name: Store PR number\n      run: echo ${{ github.event.pull_request.number }} > pr.txt\n\n    - name: Diff results\n      # GH's summery has a maximum size of 1MiB:\n      # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#step-isolation-and-limits\n      # We upload the full diff as an artifact in case it's truncated\n      run: |\n        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --truncate | head -c 1M > $GITHUB_STEP_SUMMARY\n        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --write-summary summary.json > full_diff.md\n\n    - name: Upload full diff\n      uses: actions/upload-artifact@v4\n      with:\n        name: full_diff\n        path: full_diff.md\n\n    - name: Upload summary\n      uses: actions/upload-artifact@v4\n      with:\n        name: summary\n        path: |\n          summary.json\n          pr.txt\n"
  },
  {
    "path": ".github/workflows/lintcheck_summary.yml",
    "content": "name: Lintcheck summary\n\n# The workflow_run event runs in the context of the Clippy repo giving it write\n# access, needed here to create a PR comment when the PR originates from a fork\n#\n# The summary artifact is a JSON file that we verify in this action to prevent\n# the creation of arbitrary comments\n#\n# This action must not checkout/run code from the originating workflow_run\n# or directly interpolate ${{}} untrusted fields into code\n#\n# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run\n# https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#understanding-the-risk-of-script-injections\n\non:\n  workflow_run:\n    workflows: [Lintcheck]\n    types: [completed]\n\n# Restrict the default permission scope https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#defining-access-for-the-github_token-scopes\npermissions:\n  pull-requests: write\n\njobs:\n  download:\n    runs-on: ubuntu-latest\n    if: ${{ github.event.workflow_run.conclusion == 'success' }}\n    steps:\n      - name: Download artifact\n        uses: actions/download-artifact@v5\n        with:\n          name: summary\n          path: untrusted\n          run-id: ${{ github.event.workflow_run.id }}\n          github-token: ${{ github.token }}\n\n      - name: Format comment\n        uses: actions/github-script@v8\n        with:\n          script: |\n            const fs = require(\"fs\");\n            const assert = require(\"assert/strict\");\n\n            function validateName(s) {\n              assert.match(s, /^[a-z0-9_:]+$/);\n              return s;\n            }\n\n            function validateInt(i) {\n              assert.ok(Number.isInteger(i));\n              return i;\n            }\n\n            function tryReadSummary() {\n              try {\n                return JSON.parse(fs.readFileSync(\"untrusted/summary.json\"));\n              } catch {\n                return null;\n              }\n            }\n\n            const prNumber = parseInt(fs.readFileSync(\"untrusted/pr.txt\"), 10);\n            core.exportVariable(\"PR\", prNumber.toString());\n\n            const untrustedSummary = tryReadSummary();\n            if (!Array.isArray(untrustedSummary)) {\n              return;\n            }\n\n            let summary = `Lintcheck changes for ${context.payload.workflow_run.head_sha}\n            \n            | Lint | Added | Removed | Changed |\n            | ---- | ----: | ------: | ------: |\n            `;\n\n            for (const untrustedRow of untrustedSummary) {\n              const name = validateName(untrustedRow.name);\n\n              const added = validateInt(untrustedRow.added);\n              const removed = validateInt(untrustedRow.removed);\n              const changed = validateInt(untrustedRow.changed);\n\n              const id = name.replace(\"clippy::\", \"user-content-\").replaceAll(\"_\", \"-\");\n              const url = `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${context.payload.workflow_run.id}#${id}`;\n\n              summary += `| [\\`${name}\\`](${url}) | ${added} | ${removed} | ${changed} |\\n`;\n            }\n\n            summary += \"\\nThis comment will be updated if you push new changes\";\n\n            fs.writeFileSync(\"summary.md\", summary);\n\n      - name: Create/update comment\n        run: |\n          if [[ -f summary.md ]]; then\n             gh pr comment \"$PR\" --body-file summary.md --edit-last --create-if-none\n          else\n            # There were no changes detected by Lintcheck\n            # - If a comment exists from a previous run that did detect changes, edit it (--edit-last)\n            # - If no comment exists do not create one, the `gh` command exits with an error which\n            #   `|| true` ignores\n            gh pr comment \"$PR\" --body \"No changes for ${{ github.event.workflow_run.head_sha }}\" --edit-last || true\n          fi\n        env:\n          GH_TOKEN: ${{ github.token }}\n          GH_REPO: ${{ github.repository }}\n"
  },
  {
    "path": ".github/workflows/remark.yml",
    "content": "name: Remark\n\non:\n  merge_group:\n  pull_request:\n\nenv:\n  MDBOOK_VERSION: 0.5.1\n\njobs:\n  remark:\n    runs-on: ubuntu-latest\n\n    steps:\n    # Setup\n    - name: Checkout\n      uses: actions/checkout@v6\n      with:\n        # Unsetting this would make so that any malicious package could get our Github Token\n        persist-credentials: false\n\n    - name: Setup Node.js\n      uses: actions/setup-node@v6\n      with:\n        node-version: '24.x'\n\n    - name: Install remark\n      run: npm install remark-cli remark-lint remark-lint-maximum-line-length@^3.1.3 remark-preset-lint-recommended remark-gfm\n\n    - name: Install mdbook\n      run: |\n        mkdir mdbook\n        curl -Lf https://github.com/rust-lang/mdBook/releases/download/v${MDBOOK_VERSION}/mdbook-v${MDBOOK_VERSION}-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook\n        echo `pwd`/mdbook >> $GITHUB_PATH\n\n    # Run\n    - name: Check *.md files\n      run: ./node_modules/.bin/remark -u lint -f .\n\n    - name: Linkcheck book\n      run: |\n        rustup toolchain install nightly --component rust-docs\n        rustup override set nightly\n        curl https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh -o linkcheck.sh\n        sh linkcheck.sh clippy --path ./book\n\n    - name: Build mdbook\n      run: mdbook build book\n\n  conclusion_remark:\n    needs: [ remark ]\n    # We need to ensure this job does *not* get skipped if its dependencies fail,\n    # because a skipped job is considered a success by GitHub. So we have to\n    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run\n    # when the workflow is canceled manually.\n    #\n    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!\n    if: ${{ !cancelled() }}\n    runs-on: ubuntu-latest\n    steps:\n      # Manually check the status of all dependencies. `if: failure()` does not work.\n      - name: Conclusion\n        run: |\n          # Print the dependent jobs to see them in the CI log\n          jq -C <<< '${{ toJson(needs) }}'\n          # Check if all jobs that we depend on (in the needs array) were successful.\n          jq --exit-status 'all(.result == \"success\")' <<< '${{ toJson(needs) }}'\n"
  },
  {
    "path": ".gitignore",
    "content": "# Generated by ui-test\nrustc-ice-*\n\n# Used by CI to be able to push:\n/.github/deploy_key\nout\n\n# Compiled files\n*.o\n*.d\n*.so\n*.rlib\n*.dll\n*.pyc\n*.rmeta\n\n# Executables\n*.exe\n\n# Generated by Cargo\n*Cargo.lock\n!/clippy_test_deps/Cargo.lock\n/target\n/clippy_lints/target\n/clippy_lints_internal/target\n/clippy_utils/target\n/clippy_dev/target\n/lintcheck/target\n/rustc_tools_util/target\n\n# Generated by dogfood\n/target_recur/\n\n# Generated by lintcheck\n/lintcheck-logs\n\n# gh pages docs\nutil/gh-pages/lints.json\nutil/gh-pages/index.html\n\n# rustfmt backups\n*.rs.bk\n\nhelper.txt\n*.iml\n.vscode\n.idea\n\n# mdbook generated output\n/book/book\n\n# Remove jujutsu directory from search tools\n.jj\n"
  },
  {
    "path": ".remarkrc",
    "content": "{\n  \"plugins\": [\n    \"remark-preset-lint-recommended\",\n    \"remark-gfm\",\n    [\"remark-lint-list-item-indent\", false],\n    [\"remark-lint-no-literal-urls\", false],\n    [\"remark-lint-no-shortcut-reference-link\", false],\n    [\"remark-lint-maximum-line-length\", 120]\n  ],\n  \"settings\": {\n    \"commonmark\": true\n  }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\nSee [Changelog Update](book/src/development/infrastructure/changelog_update.md) if you want to update this\ndocument.\n\n## Unreleased / Beta / In Rust Nightly\n\n[500e0ff...master](https://github.com/rust-lang/rust-clippy/compare/500e0ff...master)\n\n## Rust 1.94\n\nCurrent stable, released 2026-03-05\n\n[View all 94 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-11-29T21%3A01%3A29Z..2026-01-08T20%3A33%3A22Z+base%3Amaster)\n\n### New Lints\n\n* Added [`same_length_and_capacity`] to `pedantic`\n  [#15656](https://github.com/rust-lang/rust-clippy/pull/15656)\n* Added [`manual_ilog2`] to `pedantic`\n  [#15865](https://github.com/rust-lang/rust-clippy/pull/15865)\n* Added [`needless_type_cast`] to `nursery`\n  [#16139](https://github.com/rust-lang/rust-clippy/pull/16139)\n* Added [`ptr_offset_by_literal`] to `pedantic`\n  [#15606](https://github.com/rust-lang/rust-clippy/pull/15606)\n* Added [`decimal_bitwise_operands`] to `pedantic`\n  [#15215](https://github.com/rust-lang/rust-clippy/pull/15215)\n\n### Moves and Deprecations\n\n* Moved [`multiple_bound_locations`] from `suspicious` to `style`\n  [#16302](https://github.com/rust-lang/rust-clippy/pull/16302)\n* Moved [`collapsible_else_if`] from `style` to `pedantic`\n  [#16211](https://github.com/rust-lang/rust-clippy/pull/16211)\n* Moved [`needless_type_cast`] from `pedantic` to `nursery`\n  [#16246](https://github.com/rust-lang/rust-clippy/pull/16246)\n\n### Enhancements\n\n* [`never_loop`] do not consider `return` as preventing the iterator from looping; lint diverging\n  iterator reduction closures like `for_each` and `fold`\n  [#16364](https://github.com/rust-lang/rust-clippy/pull/16364)\n* [`single_range_in_vec_init`] don't apply the suggestion automatically\n  [#16365](https://github.com/rust-lang/rust-clippy/pull/16365)\n* [`useless_conversion`] refine `.into_iter()` suggestions to stop at final target type\n  [#16238](https://github.com/rust-lang/rust-clippy/pull/16238)\n* Multiple lints fix wrongly unmangled macros\n  [#16337](https://github.com/rust-lang/rust-clippy/pull/16337)\n* [`large_stack_arrays`] do not warn for libtest harness\n  [#16347](https://github.com/rust-lang/rust-clippy/pull/16347)\n* [`derive_ord_xor_partial_ord`] allow `expect` on `impl` block\n  [#16303](https://github.com/rust-lang/rust-clippy/pull/16303)\n* [`match_bool`] restrict to 2 arms\n  [#16333](https://github.com/rust-lang/rust-clippy/pull/16333)\n* [`multiple_inherent_impl`] fix false negatives for generic impl blocks\n  [#16284](https://github.com/rust-lang/rust-clippy/pull/16284)\n* [`unnecessary_fold`] warn about semantics change and lint `Add::add`/`Mul::mul` folds\n  [#16324](https://github.com/rust-lang/rust-clippy/pull/16324)\n* [`transmuting_null`] check const blocks and const integer casts\n  [#16260](https://github.com/rust-lang/rust-clippy/pull/16260)\n* [`needless_pass_by_ref_mut`] preserve user-provided lifetime information\n  [#16273](https://github.com/rust-lang/rust-clippy/pull/16273)\n* [`while_let_on_iterator`] use reborrow for non-`Sized` trait references\n  [#16100](https://github.com/rust-lang/rust-clippy/pull/16100)\n* [`collapsible_else_if`] prevent emitting when arms only `if {..} else {..}`\n  [#16286](https://github.com/rust-lang/rust-clippy/pull/16286)\n* [`multiple_unsafe_ops_per_block`] count only towards innermost unsafe block\n  [#16117](https://github.com/rust-lang/rust-clippy/pull/16117)\n* [`manual_saturating_arithmetic`] lint `x.checked_sub(y).unwrap_or_default()`\n  [#15845](https://github.com/rust-lang/rust-clippy/pull/15845)\n* [`transmute_ptr_to_ref`] handle pointer in struct\n  [#15948](https://github.com/rust-lang/rust-clippy/pull/15948)\n* [`disallowed_methods`] skip compiler-generated code\n  [#16186](https://github.com/rust-lang/rust-clippy/pull/16186)\n* [`missing_enforced_import_renames`] do not enforce for \"as _\"\n  [#16352](https://github.com/rust-lang/rust-clippy/pull/16352)\n\n### False Positive Fixes\n\n* [`double_parens`] fix FP on macro repetition patterns\n  [#16301](https://github.com/rust-lang/rust-clippy/pull/16301)\n* [`assertions_on_constants`] fix false positive when there is non-constant value in condition expr\n  [#16297](https://github.com/rust-lang/rust-clippy/pull/16297)\n* [`use_self`] fix FP on type in const generics\n  [#16172](https://github.com/rust-lang/rust-clippy/pull/16172)\n* [`set_contains_or_insert`] fix FP when set is mutated before `insert`\n  [#16009](https://github.com/rust-lang/rust-clippy/pull/16009)\n* [`if_then_some_else_none`] fix FP when then block contains `await`\n  [#16178](https://github.com/rust-lang/rust-clippy/pull/16178)\n* [`match_like_matches_macro`] fix FP with guards containing `if let`\n  [#15876](https://github.com/rust-lang/rust-clippy/pull/15876)\n* [`tuple_array_conversions`] fix FP when binded vars are used before conversion\n  [#16197](https://github.com/rust-lang/rust-clippy/pull/16197)\n* [`map_entry`] fix FP when it would cause `MutexGuard` to be held across await\n  [#16199](https://github.com/rust-lang/rust-clippy/pull/16199)\n* [`panicking_unwrap`] fix FP on field access with implicit deref\n  [#16196](https://github.com/rust-lang/rust-clippy/pull/16196)\n* [`large_stack_frames`] fix FP on compiler generated targets\n  [#15101](https://github.com/rust-lang/rust-clippy/pull/15101)\n\n### ICE Fixes\n\n* [`needless_type_cast`] do not ICE on struct constructor\n  [#16245](https://github.com/rust-lang/rust-clippy/pull/16245)\n\n### New Lints\n\n* Added [`unnecessary_trailing_comma`] to `style` (single-line format-like macros only)\n  [#13965](https://github.com/rust-lang/rust-clippy/issues/13965)\n\n## Rust 1.93\n\nCurrent stable, released 2026-01-22\n\n[View all 96 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-10-17T15%3A48%3A11Z..2025-11-28T19%3A22%3A54Z+base%3Amaster)\n\n### New Lints\n\n* Added [`doc_paragraphs_missing_punctuation`] to `restriction`\n  [#15758](https://github.com/rust-lang/rust-clippy/pull/15758)\n\n### Moves and Deprecations\n\n* Renamed [`needless_if`] to [`needless_ifs`]\n  [#15961](https://github.com/rust-lang/rust-clippy/pull/15961)\n* Renamed [`empty_enum`] to [`empty_enums`]\n  [#15912](https://github.com/rust-lang/rust-clippy/pull/15912)\n\n### Enhancements\n\n* [`result_large_err`] added `large_error_ignored` configuration\n  [#15697](https://github.com/rust-lang/rust-clippy/pull/15697)\n* [`explicit_deref_methods`] don't lint in `impl Deref(Mut)`\n  [#16113](https://github.com/rust-lang/rust-clippy/pull/16113)\n* [`missing_docs_in_private_items`] don't lint items in bodies and automatically derived impls;\n  better detect when things are accessible from the crate root; lint unnameable items which are\n  accessible outside the crate\n  [#14741](https://github.com/rust-lang/rust-clippy/pull/14741)\n* [`unnecessary_unwrap`] and [`panicking_unwrap`] lint field accesses\n  [#15949](https://github.com/rust-lang/rust-clippy/pull/15949)\n* [`ok_expect`] add autofix\n  [#15867](https://github.com/rust-lang/rust-clippy/pull/15867)\n* [`let_and_return`] disallow _any_ text between let and return\n  [#16006](https://github.com/rust-lang/rust-clippy/pull/16006)\n* [`needless_collect`] extend to lint more cases\n  [#14361](https://github.com/rust-lang/rust-clippy/pull/14361)\n* [`needless_doctest_main`] and [`test_attr_in_doctest`] now handle whitespace in language tags\n  [#15967](https://github.com/rust-lang/rust-clippy/pull/15967)\n* [`search_is_some`] now fixes code spanning multiple lines\n  [#15902](https://github.com/rust-lang/rust-clippy/pull/15902)\n* [`unnecessary_find_map`] and [`unnecessary_filter_map`] make diagnostic spans more precise\n  [#15929](https://github.com/rust-lang/rust-clippy/pull/15929)\n* [`precedence`] warn about ambiguity when a closure is used as a method call receiver\n  [#14421](https://github.com/rust-lang/rust-clippy/pull/14421)\n* [`match_as_ref`] suggest `as_ref` when the reference needs to be cast; improve diagnostics\n  [#15934](https://github.com/rust-lang/rust-clippy/pull/15934)\n  [#15928](https://github.com/rust-lang/rust-clippy/pull/15928)\n\n### False Positive Fixes\n\n* [`single_range_in_vec_init`] fix FP for explicit `Range`\n  [#16043](https://github.com/rust-lang/rust-clippy/pull/16043)\n* [`mod_module_files`] fix false positive for integration tests in workspace crates\n  [#16048](https://github.com/rust-lang/rust-clippy/pull/16048)\n* [`replace_box`] fix FP when the box is moved\n  [#15984](https://github.com/rust-lang/rust-clippy/pull/15984)\n* [`len_zero`] fix FP on unstable methods\n  [#15894](https://github.com/rust-lang/rust-clippy/pull/15894)\n\n## Rust 1.92\n\nCurrent stable, released 2025-12-11\n\n[View all 124 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-09-05T18%3A24%3A03Z..2025-10-16T14%3A13%3A43Z+base%3Amaster)\n\n### New Lints\n\n* Added [`unnecessary_option_map_or_else`] to `suspicious`\n  [#14662](https://github.com/rust-lang/rust-clippy/pull/14662)\n* Added [`replace_box`] to `perf`\n  [#14953](https://github.com/rust-lang/rust-clippy/pull/14953)\n* Added [`volatile_composites`] to `nursery`\n  [#15686](https://github.com/rust-lang/rust-clippy/pull/15686)\n* Added [`self_only_used_in_recursion`] to `pedantic`\n  [#14787](https://github.com/rust-lang/rust-clippy/pull/14787)\n* Added [`redundant_iter_cloned`] to `perf`\n  [#15277](https://github.com/rust-lang/rust-clippy/pull/15277)  \n\n### Moves and Deprecations\n\n* Renamed [`unchecked_duration_subtraction`] to [`unchecked_time_subtraction`]\n  [#13800](https://github.com/rust-lang/rust-clippy/pull/13800)\n\n### Enhancements\n\n* [`mutex_atomic`] and [`mutex_integer`] overhauled to only lint definitions, not uses; added suggestions\n  and better help messages\n  [#15632](https://github.com/rust-lang/rust-clippy/pull/15632)\n* [`manual_rotate`] now recognizes non-const rotation amounts\n  [#15402](https://github.com/rust-lang/rust-clippy/pull/15402)\n* [`multiple_inherent_impl`] added `inherent-impl-lint-scope` config option (`module`, `file`,\n  or `crate`)\n  [#15843](https://github.com/rust-lang/rust-clippy/pull/15843)\n* [`use_self`] now checks structs and enums\n  [#15566](https://github.com/rust-lang/rust-clippy/pull/15566)\n* [`while_let_loop`] extended to lint on `loop { let else }`\n  [#15701](https://github.com/rust-lang/rust-clippy/pull/15701)\n* [`mut_mut`] overhauled with structured suggestions and improved documentation\n  [#15417](https://github.com/rust-lang/rust-clippy/pull/15417)\n* [`nonstandard_macro_braces`] now suggests trailing semicolon when needed\n  [#15593](https://github.com/rust-lang/rust-clippy/pull/15593)\n* [`ptr_offset_with_cast`] now respects MSRV when suggesting fix, and lints more cases\n  [#15613](https://github.com/rust-lang/rust-clippy/pull/15613)\n* [`cast_sign_loss`] and [`cast_possible_wrap`] added suggestions using `cast_{un,}signed()` methods\n  (MSRV 1.87+)\n  [#15384](https://github.com/rust-lang/rust-clippy/pull/15384)\n* [`unchecked_time_subtraction`] extended to include `Duration - Duration` operations\n  [#13800](https://github.com/rust-lang/rust-clippy/pull/13800)\n* [`filter_next`] now suggests replacing `filter().next_back()` with `rfind()` for\n  `DoubleEndedIterator`\n  [#15748](https://github.com/rust-lang/rust-clippy/pull/15748)\n\n### False Positive Fixes\n\n* [`unnecessary_safety_comment`] fixed FPs with comments above attributes\n  [#15678](https://github.com/rust-lang/rust-clippy/pull/15678)\n* [`manual_unwrap_or`] fixed FP edge case\n  [#15812](https://github.com/rust-lang/rust-clippy/pull/15812)\n* [`needless_continue`] fixed FP when match type is not unit or never\n  [#15547](https://github.com/rust-lang/rust-clippy/pull/15547)\n* [`if_then_some_else_none`] fixed FP when return exists in block expr\n  [#15783](https://github.com/rust-lang/rust-clippy/pull/15783)\n* [`new_without_default`] fixed to copy `#[cfg]` onto `impl Default` and fixed FP on private type\n  with trait impl\n  [#15720](https://github.com/rust-lang/rust-clippy/pull/15720)\n  [#15782](https://github.com/rust-lang/rust-clippy/pull/15782)\n* [`question_mark`] fixed FP on variables used after\n  [#15644](https://github.com/rust-lang/rust-clippy/pull/15644)\n* [`needless_return`] fixed FP with `cfg`d code after `return`\n  [#15669](https://github.com/rust-lang/rust-clippy/pull/15669)\n* [`useless_attribute`] fixed FP on `deprecated_in_future`\n  [#15645](https://github.com/rust-lang/rust-clippy/pull/15645)\n* [`double_parens`] fixed FP when macros are involved\n  [#15420](https://github.com/rust-lang/rust-clippy/pull/15420)\n\n## Rust 1.91\n\nCurrent stable, released 2025-10-30\n\n[View all 146 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-07-25T21%3A05%3A11Z..2025-09-04T22%3A34%3A27Z+base%3Amaster)\n\n### New Lints\n\n* Added [`possible_missing_else`] to `suspicious`\n  [#15317](https://github.com/rust-lang/rust-clippy/pull/15317)\n\n### Moves and Deprecations\n\n* Moved [`cognitive_complexity`] from `nursery` to `restriction`\n  [#15415](https://github.com/rust-lang/rust-clippy/pull/15415)\n* Moved [`declare_interior_mutable_const`] from `style` to `suspicious`\n  [#15454](https://github.com/rust-lang/rust-clippy/pull/15454)\n* Moved [`crosspointer_transmute`] from `complexity` to `suspicious`\n  [#15403](https://github.com/rust-lang/rust-clippy/pull/15403)\n\n### Enhancements\n\n* [`excessive_precision`] added `const_literal_digits_threshold` option to suppress overly precise constants.\n  [#15193](https://github.com/rust-lang/rust-clippy/pull/15193)\n* [`unwrap_in_result`] rewritten for better accuracy; now lints on `.unwrap()` and `.expect()` \n  directly and no longer mixes `Result` and `Option`.\n  [#15445](https://github.com/rust-lang/rust-clippy/pull/15445)\n* [`panic`] now works in `const` contexts.\n  [#15565](https://github.com/rust-lang/rust-clippy/pull/15565)\n* [`implicit_clone`] now also lints `to_string` calls (merging [`string_to_string`] behavior).\n  [#14177](https://github.com/rust-lang/rust-clippy/pull/14177)\n* [`collapsible_match`] improved suggestions to handle necessary ref/dereferencing.\n  [#14221](https://github.com/rust-lang/rust-clippy/pull/14221)\n* [`map_identity`] now suggests making variables mutable when required; recognizes tuple struct restructuring.\n  [#15261](https://github.com/rust-lang/rust-clippy/pull/15261)\n* [`option_map_unit_fn`] preserves `unsafe` blocks in suggestions.\n  [#15570](https://github.com/rust-lang/rust-clippy/pull/15570)\n* [`unnecessary_mut_passed`] provides structured, clearer fix suggestions.\n  [#15438](https://github.com/rust-lang/rust-clippy/pull/15438)\n* [`float_equality_without_abs`] now checks `f16` and `f128` types.\n  [#15054](https://github.com/rust-lang/rust-clippy/pull/15054)\n* [`doc_markdown`] expanded whitelist (`InfiniBand`, `RoCE`, `PowerPC`) and improved handling of \n  identifiers like NixOS.\n  [#15558](https://github.com/rust-lang/rust-clippy/pull/15558)\n* [`clone_on_ref_ptr`] now suggests fully qualified paths to avoid resolution errors.\n  [#15561](https://github.com/rust-lang/rust-clippy/pull/15561)\n* [`manual_assert`] simplifies boolean expressions in suggested fixes.\n  [#15368](https://github.com/rust-lang/rust-clippy/pull/15368)\n* [`four_forward_slashes`] warns about bare CR in comments and avoids invalid autofixes.\n  [#15175](https://github.com/rust-lang/rust-clippy/pull/15175)\n\n### False Positive Fixes\n\n* [`alloc_instead_of_core`] fixed FP when `alloc` is an alias\n  [#15581](https://github.com/rust-lang/rust-clippy/pull/15581)\n* [`needless_range_loop`] fixed FP and FN when meeting multidimensional array\n  [#15486](https://github.com/rust-lang/rust-clippy/pull/15486)\n* [`semicolon_inside_block`] fixed FP when attribute over expr is not enabled\n  [#15476](https://github.com/rust-lang/rust-clippy/pull/15476)\n* [`unnested_or_patterns`] fixed FP on structs with only shorthand field patterns\n  [#15343](https://github.com/rust-lang/rust-clippy/pull/15343)\n* [`match_ref_pats`] fixed FP on match scrutinee of never type\n  [#15474](https://github.com/rust-lang/rust-clippy/pull/15474)\n* [`infinite_loop`] fixed FP in async blocks that are not awaited\n  [#15157](https://github.com/rust-lang/rust-clippy/pull/15157)\n* [`iter_on_single_items`] fixed FP on function pointers and let statements\n  [#15013](https://github.com/rust-lang/rust-clippy/pull/15013)\n\n### ICE Fixes\n\n* [`len_zero`] fix ICE when fn len has a return type without generic type params\n  [#15660](https://github.com/rust-lang/rust-clippy/pull/15660)\n\n### Documentation Improvements\n\n* [`cognitive_complexity`] corrected documentation to state lint is in `restriction`, not `nursery`\n  [#15563](https://github.com/rust-lang/rust-clippy/pull/15563)\n\n### Performance Improvements\n\n* [`doc_broken_link`] optimized by 99.77% (12M → 27k instructions)\n  [#15385](https://github.com/rust-lang/rust-clippy/pull/15385)\n\n## Rust 1.90\n\nCurrent stable, released 2025-09-18\n\n[View all 118 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-06-13T15%3A55%3A04Z..2025-07-25T13%3A24%3A00Z+base%3Amaster)\n\nNote: This Clippy release does not introduce many new lints and is focused entirely on bug fixes — see\n[#15086](https://github.com/rust-lang/rust-clippy/issues/15086) for more details.\n\n### New Lints\n\n* Added [`manual_is_multiple_of`] to `complexity` [#14292](https://github.com/rust-lang/rust-clippy/pull/14292)\n* Added [`doc_broken_link`] to `pedantic` [#13696](https://github.com/rust-lang/rust-clippy/pull/13696)\n\n### Moves and Deprecations\n\n* Move [`uninlined_format_args`] to `pedantic` (from `style`, now allow-by-default) [#15287](https://github.com/rust-lang/rust-clippy/pull/15287)\n\n### Enhancements\n\n* [`or_fun_call`] now lints `Option::get_or_insert`, `Result::map_or`, `Option/Result::and` methods\n  [#15071](https://github.com/rust-lang/rust-clippy/pull/15071)\n  [#15073](https://github.com/rust-lang/rust-clippy/pull/15073)\n  [#15074](https://github.com/rust-lang/rust-clippy/pull/15074)\n* [`incompatible_msrv`] now recognizes types exceeding MSRV\n  [#15296](https://github.com/rust-lang/rust-clippy/pull/15296)\n* [`incompatible_msrv`] now checks the right MSRV when in a `const` context\n  [#15297](https://github.com/rust-lang/rust-clippy/pull/15297)\n* [`zero_ptr`] now lints in `const` context as well\n  [#15152](https://github.com/rust-lang/rust-clippy/pull/15152)\n* [`map_identity`],[`flat_map_identity`] now recognizes `|[x, y]| [x, y]` as an identity function\n  [#15229](https://github.com/rust-lang/rust-clippy/pull/15229)\n* [`exit`] no longer fails on the main function when using `--test` or `--all-targets` flag\n  [#15222](https://github.com/rust-lang/rust-clippy/pull/15222)\n\n### False Positive Fixes\n\n* [`if_then_some_else_none`] fixed FP when require type coercion\n  [#15267](https://github.com/rust-lang/rust-clippy/pull/15267)\n* [`module_name_repetitions`] fixed FP on exported macros\n  [#15319](https://github.com/rust-lang/rust-clippy/pull/15319)\n* [`unused_async`] fixed FP on function with `todo!`\n  [#15308](https://github.com/rust-lang/rust-clippy/pull/15308)\n* [`useless_attribute`] fixed FP when using `#[expect(redundant_imports)]` and similar lint attributes\n  on `use` statements\n  [#15318](https://github.com/rust-lang/rust-clippy/pull/15318)\n* [`pattern_type_mismatch`] fixed FP in external macro\n  [#15306](https://github.com/rust-lang/rust-clippy/pull/15306)\n* [`large_enum_variant`] fixed FP by not suggesting `Box` in `no_std` mode\n  [#15241](https://github.com/rust-lang/rust-clippy/pull/15241)\n* [`missing_inline_in_public_items`] fixed FP on functions with `extern`\n  [#15313](https://github.com/rust-lang/rust-clippy/pull/15313)\n* [`needless_range_loop`] fixed FP on array literals\n  [#15314](https://github.com/rust-lang/rust-clippy/pull/15314)\n* [`ptr_as_ptr`] fixed wrong suggestions with turbo fish\n  [#15289](https://github.com/rust-lang/rust-clippy/pull/15289)\n* [`range_plus_one`], [`range_minus_one`] fixed FP by restricting lint to cases where it is safe\n  to switch the range type\n  [#14432](https://github.com/rust-lang/rust-clippy/pull/14432)\n* [`ptr_arg`] fixed FP with underscore binding to `&T` or `&mut T` argument\n  [#15105](https://github.com/rust-lang/rust-clippy/pull/15105)\n* [`unsafe_derive_deserialize`] fixed FP caused by the standard library's `pin!()` macro\n  [#15137](https://github.com/rust-lang/rust-clippy/pull/15137)\n* [`unused_trait_names`] fixed FP in macros\n  [#14947](https://github.com/rust-lang/rust-clippy/pull/14947)\n* [`expect_fun_call`] fixed invalid suggestions\n  [#15122](https://github.com/rust-lang/rust-clippy/pull/15122)\n* [`manual_is_multiple_of`] fixed various false positives\n  [#15205](https://github.com/rust-lang/rust-clippy/pull/15205)\n* [`manual_assert`] fixed wrong suggestions for macros\n  [#15264](https://github.com/rust-lang/rust-clippy/pull/15264)\n* [`expect_used`] fixed false negative when meeting `Option::ok().expect`\n  [#15253](https://github.com/rust-lang/rust-clippy/pull/15253)\n* [`manual_abs_diff`] fixed wrong suggestions behind refs\n  [#15265](https://github.com/rust-lang/rust-clippy/pull/15265)\n* [`approx_constant`] fixed FP with overly precise literals and non trivially formatted numerals\n  [#15236](https://github.com/rust-lang/rust-clippy/pull/15236)\n* [`arithmetic_side_effects`] fixed FP on `NonZeroU*.get() - 1`\n  [#15238](https://github.com/rust-lang/rust-clippy/pull/15238)\n* [`legacy_numeric_constants`] fixed suggestion when call is inside parentheses\n  [#15191](https://github.com/rust-lang/rust-clippy/pull/15191)\n* [`manual_is_variant_and`] fixed inverted suggestions that could lead to code with different semantics\n  [#15206](https://github.com/rust-lang/rust-clippy/pull/15206)\n* [`unnecessary_map_or`] fixed FP by not proposing to replace `map_or` call when types wouldn't be correct\n  [#15181](https://github.com/rust-lang/rust-clippy/pull/15181)\n* [`return_and_then`] fixed FP in case of a partially used expression\n  [#15115](https://github.com/rust-lang/rust-clippy/pull/15115)\n* [`manual_let_else`] fixed FP with binding subpattern with unused name\n  [#15118](https://github.com/rust-lang/rust-clippy/pull/15118)\n* [`suboptimal_flops`] fixed FP with ambiguous float types in mul_add suggestions\n  [#15133](https://github.com/rust-lang/rust-clippy/pull/15133)\n* [`borrow_as_ptr`] fixed FP by not removing cast to trait object pointer\n  [#15145](https://github.com/rust-lang/rust-clippy/pull/15145)\n* [`unnecessary_operation`] fixed FP by not removing casts if they are useful to type the expression\n  [#15182](https://github.com/rust-lang/rust-clippy/pull/15182)\n* [`empty_loop`] fixed FP on intrinsic function declaration\n  [#15201](https://github.com/rust-lang/rust-clippy/pull/15201)\n* [`doc_nested_refdefs`] fixed FP where task lists are reported as refdefs\n  [#15146](https://github.com/rust-lang/rust-clippy/pull/15146)\n* [`std_instead_of_core`] fixed FP when not all items come from the new crate\n  [#15165](https://github.com/rust-lang/rust-clippy/pull/15165)\n* [`swap_with_temporary`] fixed FP leading to different semantics being suggested\n  [#15172](https://github.com/rust-lang/rust-clippy/pull/15172)\n* [`cast_possible_truncation`] fixed FP by not giving suggestions inside const context\n  [#15164](https://github.com/rust-lang/rust-clippy/pull/15164)\n* [`missing_panics_doc`] fixed FP by allowing unwrap() and expect()s in const-only contexts\n  [#15170](https://github.com/rust-lang/rust-clippy/pull/15170)\n* [`disallowed_script_idents`] fixed FP on identifiers with `_`\n  [#15123](https://github.com/rust-lang/rust-clippy/pull/15123)\n* [`wildcard_enum_match_arm`] fixed wrong suggestions with raw identifiers\n  [#15093](https://github.com/rust-lang/rust-clippy/pull/15093)\n* [`borrow_deref_ref`] fixed FP by not proposing replacing a reborrow when the reborrow is itself mutably borrowed\n  [#14967](https://github.com/rust-lang/rust-clippy/pull/14967)\n* [`manual_ok_err`] fixed wrong suggestions with references\n  [#15053](https://github.com/rust-lang/rust-clippy/pull/15053)\n* [`identity_op`] fixed FP when encountering `Default::default()`\n  [#15028](https://github.com/rust-lang/rust-clippy/pull/15028)\n* [`exhaustive_structs`] fixed FP on structs with default valued field\n  [#15022](https://github.com/rust-lang/rust-clippy/pull/15022)\n* [`collapsible_else_if`] fixed FP on conditionally compiled stmt\n  [#14906](https://github.com/rust-lang/rust-clippy/pull/14906)\n* [`missing_const_for_fn`] fixed FP by checking MSRV before emitting lint on function containing\n  non-`Sized` trait bounds\n  [#15080](https://github.com/rust-lang/rust-clippy/pull/15080)\n* [`question_mark`] fixed FP when else branch of let-else contains `#[cfg]`\n  [#15082](https://github.com/rust-lang/rust-clippy/pull/15082)\n\n### ICE Fixes\n\n* [`single_match`] fixed ICE with deref patterns and string literals\n  [#15124](https://github.com/rust-lang/rust-clippy/pull/15124)\n* [`needless_doctest_main`] fixed panic when doctest is invalid\n  [#15052](https://github.com/rust-lang/rust-clippy/pull/15052)\n* [`zero_sized_map_values`] do not attempt to compute size of a type with escaping lifetimes\n  [#15434](https://github.com/rust-lang/rust-clippy/pull/15434)\n\n### Documentation Improvements\n\n* [`manual_is_variant_and`] improved documentation to include equality comparison patterns\n  [#15239](https://github.com/rust-lang/rust-clippy/pull/15239)\n* [`uninlined_format_args`] improved documentation with example of how to fix a `{:?}` parameter\n  [#15228](https://github.com/rust-lang/rust-clippy/pull/15228)\n* [`undocumented_unsafe_blocks`] improved documentation wording\n  [#15213](https://github.com/rust-lang/rust-clippy/pull/15213)\n\n## Rust 1.89\n\nCurrent stable, released 2025-08-07\n\n[View all 137 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-05-01T16%3A52%3A57Z..2025-06-13T08%3A33%3A27Z+base%3Amaster)\n\n### New Lints\n\n* Added [`coerce_container_to_any`] to `nursery` [#14812](https://github.com/rust-lang/rust-clippy/pull/14812)\n* Added [`ip_constant`] to `pedantic` [#14878](https://github.com/rust-lang/rust-clippy/pull/14878)\n* Added [`infallible_try_from`] to `suspicious` [#14813](https://github.com/rust-lang/rust-clippy/pull/14813)\n* Added [`doc_suspicious_footnotes`] to `suspicious` [#14708](https://github.com/rust-lang/rust-clippy/pull/14708)\n* Added [`pointer_format`] to `restriction` [#14792](https://github.com/rust-lang/rust-clippy/pull/14792)\n* Added [`useless_concat`] to `complexity` [#13829](https://github.com/rust-lang/rust-clippy/pull/13829)\n* Added [`cloned_ref_to_slice_refs`] to `perf` [#14284](https://github.com/rust-lang/rust-clippy/pull/14284)\n* Added [`confusing_method_to_numeric_cast`] to `suspicious` [#13979](https://github.com/rust-lang/rust-clippy/pull/13979)\n\n### Moves and Deprecations\n\n* Removed superseded lints: `transmute_float_to_int`, `transmute_int_to_char`,\n  `transmute_int_to_float`, `transmute_num_to_bytes` (now in rustc)\n  [#14703](https://github.com/rust-lang/rust-clippy/pull/14703)\n* Move [`uninlined_format_args`] to `pedantic` (from `style`, now allow-by-default)\n  [#15287](https://github.com/rust-lang/rust-clippy/pull/15287)\n\n### Enhancements\n\n* [`module_name_repetitions`] added `allow_exact_repetitions` configuration option\n  [#14261](https://github.com/rust-lang/rust-clippy/pull/14261)\n* [`missing_docs_in_private_items`] added `allow_unused` config for underscored fields\n  [#14453](https://github.com/rust-lang/rust-clippy/pull/14453)\n* [`unnecessary_unwrap`] fixed being emitted twice in closure\n  [#14763](https://github.com/rust-lang/rust-clippy/pull/14763)\n* [`needless_return`] lint span no longer wraps to previous line\n  [#14790](https://github.com/rust-lang/rust-clippy/pull/14790)\n* [`trivial-copy-size-limit`] now defaults to `target_pointer_width`\n  [#13319](https://github.com/rust-lang/rust-clippy/pull/13319)\n* [`integer_division`] fixed false negative for NonZero denominators\n  [#14664](https://github.com/rust-lang/rust-clippy/pull/14664)\n* [`arbitrary_source_item_ordering`] no longer lints inside items with `#[repr]` attribute\n  [#14610](https://github.com/rust-lang/rust-clippy/pull/14610)\n* [`excessive_precision`] no longer triggers on exponent with leading zeros\n  [#14824](https://github.com/rust-lang/rust-clippy/pull/14824)\n* [`to_digit_is_some`] no longer lints in const contexts when MSRV is below 1.87\n  [#14771](https://github.com/rust-lang/rust-clippy/pull/14771)\n\n### False Positive Fixes\n\n* [`std_instead_of_core`] fixed FP when part of the `use` cannot be replaced\n  [#15016](https://github.com/rust-lang/rust-clippy/pull/15016)\n* [`unused_unit`] fixed FP for `Fn` bounds\n  [#14962](https://github.com/rust-lang/rust-clippy/pull/14962)\n* [`unnecessary_debug_formatting`] fixed FP inside `Debug` impl\n  [#14955](https://github.com/rust-lang/rust-clippy/pull/14955)\n* [`assign_op_pattern`] fixed FP on unstable const trait\n  [#14886](https://github.com/rust-lang/rust-clippy/pull/14886)\n* [`useless_conversion`] fixed FP when using `.into_iter().any()`\n  [#14800](https://github.com/rust-lang/rust-clippy/pull/14800)\n* [`collapsible_if`] fixed FP on block stmt before expr\n  [#14730](https://github.com/rust-lang/rust-clippy/pull/14730)\n* [`manual_unwrap_or_default`] fixed FP on ref binding\n  [#14731](https://github.com/rust-lang/rust-clippy/pull/14731)\n* [`unused_async`] fixed FP on default impl\n  [#14720](https://github.com/rust-lang/rust-clippy/pull/14720)\n* [`manual_slice_fill`] fixed FP on `IndexMut` overload\n  [#14719](https://github.com/rust-lang/rust-clippy/pull/14719)\n* [`unnecessary_to_owned`] fixed FP when map key is a reference\n  [#14834](https://github.com/rust-lang/rust-clippy/pull/14834)\n* [`swap_with_temporary`]: fix false positive leading to different semantics\n  being suggested, and use the right number of dereferences in suggestion\n  [#15172](https://github.com/rust-lang/rust-clippy/pull/15172)\n\n### ICE Fixes\n\n* [`mutable_key_type`] fixed ICE when infinitely associated generic types are used\n  [#14965](https://github.com/rust-lang/rust-clippy/pull/14965)\n* [`zero_sized_map_values`] fixed ICE while computing type layout\n  [#14837](https://github.com/rust-lang/rust-clippy/pull/14837)\n* [`useless_asref`] fixed ICE on trait method\n  [#14830](https://github.com/rust-lang/rust-clippy/pull/14830)\n* [`manual_slice_size_calculation`] fixed ICE in suggestion and triggers in `const` context\n  [#14804](https://github.com/rust-lang/rust-clippy/pull/14804)\n* [`missing_const_for_fn`]: fix ICE with some compilation options\n  [#14776](https://github.com/rust-lang/rust-clippy/pull/14776)\n\n### Documentation Improvements\n\n* [`manual_contains`] improved documentation wording\n  [#14917](https://github.com/rust-lang/rust-clippy/pull/14917)\n\n### Performance improvements\n\n* [`strlen_on_c_strings`] optimized by 99.75% (31M → 76k instructions)\n  [#15043](https://github.com/rust-lang/rust-clippy/pull/15043)\n* Reduced documentation lints execution time by 85% (7.5% → 1% of total runtime)\n  [#14870](https://github.com/rust-lang/rust-clippy/pull/14870)\n* [`unit_return_expecting_ord`] optimized to reduce binder instantiation from 95k to 10k calls\n  [#14905](https://github.com/rust-lang/rust-clippy/pull/14905)\n* [`doc_markdown`] optimized by 50%\n  [#14693](https://github.com/rust-lang/rust-clippy/pull/14693)\n* Refactor and speed up `cargo dev fmt`\n  [#14638](https://github.com/rust-lang/rust-clippy/pull/14638)\n\n## Rust 1.88\n\nCurrent stable, released 2025-06-26\n\n[View all 126 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-03-21T10%3A30%3A57Z..2025-05-01T08%3A03%3A26Z+base%3Amaster)\n\n### New Lints\n\n* Added [`swap_with_temporary`] to `complexity` [#14046](https://github.com/rust-lang/rust-clippy/pull/14046)\n* Added [`redundant_test_prefix`] to `restriction` [#13710](https://github.com/rust-lang/rust-clippy/pull/13710)\n* Added [`manual_dangling_ptr`] to `style` [#14107](https://github.com/rust-lang/rust-clippy/pull/14107)\n* Added [`char_indices_as_byte_indices`] to `correctness` [#13435](https://github.com/rust-lang/rust-clippy/pull/13435)\n* Added [`manual_abs_diff`] to `complexity` [#14482](https://github.com/rust-lang/rust-clippy/pull/14482)\n* Added [`ignore_without_reason`] to `pedantic` [#13931](https://github.com/rust-lang/rust-clippy/pull/13931)\n\n### Moves and Deprecations\n\n* Moved [`uninlined_format_args`] to `style` (from `pedantic`)\n  [#14160](https://github.com/rust-lang/rust-clippy/pull/14160)\n* [`match_on_vec_items`] deprecated in favor of [`indexing_slicing`]\n  [#14217](https://github.com/rust-lang/rust-clippy/pull/14217)\n* Removed superseded lints: `transmute_float_to_int`, `transmute_int_to_char`,\n  `transmute_int_to_float`, `transmute_num_to_bytes` (now in rustc)\n  [#14703](https://github.com/rust-lang/rust-clippy/pull/14703)\n\n### Enhancements\n\n* Configuration renamed from `lint-inconsistent-struct-field-initializers`\n  to `check-inconsistent-struct-field-initializers`\n  [#14280](https://github.com/rust-lang/rust-clippy/pull/14280)\n* Paths in `disallowed_*` configurations are now validated\n  [#14397](https://github.com/rust-lang/rust-clippy/pull/14397)\n* [`borrow_as_ptr`] now lints implicit casts as well\n  [#14408](https://github.com/rust-lang/rust-clippy/pull/14408)\n* [`iter_kv_map`] now recognizes references on maps\n  [#14596](https://github.com/rust-lang/rust-clippy/pull/14596)\n* [`empty_enum_variants_with_brackets`] no longer lints reachable enums or enums used\n  as functions within same crate [#12971](https://github.com/rust-lang/rust-clippy/pull/12971)\n* [`needless_lifetimes`] now checks for lifetime uses in closures\n  [#14608](https://github.com/rust-lang/rust-clippy/pull/14608)\n* [`wildcard_imports`] now lints on `pub use` when `warn_on_all_wildcard_imports` is enabled\n  [#14182](https://github.com/rust-lang/rust-clippy/pull/14182)\n* [`collapsible_if`] now recognizes the `let_chains` feature\n  [#14481](https://github.com/rust-lang/rust-clippy/pull/14481)\n* [`match_single_binding`] now allows macros in scrutinee and patterns\n  [#14635](https://github.com/rust-lang/rust-clippy/pull/14635)\n* [`needless_borrow`] does not contradict the compiler's\n  `dangerous_implicit_autorefs` lint even though the references\n  are not mandatory\n  [#14810](https://github.com/rust-lang/rust-clippy/pull/14810)\n\n### False Positive Fixes\n\n* [`double_ended_iterator_last`] and [`needless_collect`] fixed FP when iter has side effects\n  [#14490](https://github.com/rust-lang/rust-clippy/pull/14490)\n* [`mut_from_ref`] fixed FP where lifetimes nested in types were not considered\n  [#14471](https://github.com/rust-lang/rust-clippy/pull/14471)\n* [`redundant_clone`] fixed FP in overlapping lifetime\n  [#14237](https://github.com/rust-lang/rust-clippy/pull/14237)\n* [`map_entry`] fixed FP where lint would trigger without insert calls present\n  [#14568](https://github.com/rust-lang/rust-clippy/pull/14568)\n* [`iter_cloned_collect`] fixed FP with custom `From`/`IntoIterator` impl\n  [#14473](https://github.com/rust-lang/rust-clippy/pull/14473)\n* [`shadow_unrelated`] fixed FP in destructuring assignments\n  [#14381](https://github.com/rust-lang/rust-clippy/pull/14381)\n* [`redundant_clone`] fixed FP on enum cast\n  [#14395](https://github.com/rust-lang/rust-clippy/pull/14395)\n* [`collapsible_if`] fixed FP on block stmt before expr\n  [#14730](https://github.com/rust-lang/rust-clippy/pull/14730)\n\n### ICE Fixes\n\n* [`missing_const_for_fn`] fix ICE with `-Z validate-mir` compilation option\n  [#14776](https://github.com/rust-lang/rust-clippy/pull/14776)\n\n### Documentation Improvements\n\n* [`missing_asserts_for_indexing`] improved documentation and examples\n  [#14108](https://github.com/rust-lang/rust-clippy/pull/14108)\n\n### Others\n\n* We're testing with edition 2024 now\n  [#14602](https://github.com/rust-lang/rust-clippy/pull/14602)\n* Don't warn about unloaded crates in `clippy.toml` disallowed paths\n  [#14733](https://github.com/rust-lang/rust-clippy/pull/14733)\n\n## Rust 1.87\n\nCurrent stable, released 2025-05-15\n\n[View all 127 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-02-06T14%3A54%3A28Z..2025-03-20T20%3A07%3A53Z+base%3Amaster)\n\n### New Lints\n\n* Added [`doc_comment_double_space_linebreaks`] to `pedantic` [#12876](https://github.com/rust-lang/rust-clippy/pull/12876)\n* Added [`manual_midpoint`] to `pedantic` [#13851](https://github.com/rust-lang/rust-clippy/pull/13851)\n* Added [`io_other_error`] to `style` [#14022](https://github.com/rust-lang/rust-clippy/pull/14022)\n* Added [`owned_cow`] to `pedantic` [#13948](https://github.com/rust-lang/rust-clippy/pull/13948)\n* Added [`manual_contains`] to `perf` [#13817](https://github.com/rust-lang/rust-clippy/pull/13817)\n* Added [`unnecessary_debug_formatting`] to `pedantic` [#13893](https://github.com/rust-lang/rust-clippy/pull/13893)\n* Added [`elidable_lifetime_names`] to `pedantic` [#13960](https://github.com/rust-lang/rust-clippy/pull/13960)\n* Added [`mem_replace_option_with_some`] to `style` [#14197](https://github.com/rust-lang/rust-clippy/pull/14197)\n* Added [`unbuffered_bytes`] to `perf` [#14089](https://github.com/rust-lang/rust-clippy/pull/14089)\n* Added [`single_option_map`] to `nursery` [#14033](https://github.com/rust-lang/rust-clippy/pull/14033)\n\n### Moves and Deprecations\n\n* Moved [`comparison_chain`] to `pedantic` (from `style`)\n  [#14219](https://github.com/rust-lang/rust-clippy/pull/14219)\n* Moved [`manual_ok_or`] to `style` (from `pedantic`)\n  [#14027](https://github.com/rust-lang/rust-clippy/pull/14027)\n* Deprecated [`option_map_or_err_ok`] in favor of [`manual_ok_or`]\n  [#14027](https://github.com/rust-lang/rust-clippy/pull/14027)\n\n### Enhancements\n\n* Add `allow_expect_in_consts` and `allow_unwrap_in_consts` configuration options to [`unwrap_used`], [`expect_used`]\n  [#14200](https://github.com/rust-lang/rust-clippy/pull/14200)\n* Add `check-incompatible-msrv-in-tests` configuration option to [`incompatible_msrv`]\n  [#14279](https://github.com/rust-lang/rust-clippy/pull/14279)\n* [`len_zero`] now also triggers if deref target implements `is_empty()`\n  [#13871](https://github.com/rust-lang/rust-clippy/pull/13871)\n* [`ptr_eq`] now handles more cases, including `!=` in addition to `==`\n  [#14339](https://github.com/rust-lang/rust-clippy/pull/14339)\n* [`struct_field_names`] now also checks private fields of public structs\n  [#14076](https://github.com/rust-lang/rust-clippy/pull/14076)\n* [`needless_pass_by_value`] suggests using a reference on the innermost `Option` content\n  [#14392](https://github.com/rust-lang/rust-clippy/pull/14392)\n* [`obfuscated_if_else`] now supports `then().unwrap_or_else()` and `then_some().unwrap_or_else()`\n  [#14165](https://github.com/rust-lang/rust-clippy/pull/14165)\n* Format macros: all format-handling lints now validate `todo!` and `unimplemented!` macros\n  [#14266](https://github.com/rust-lang/rust-clippy/pull/14266)\n* [`disallowed_methods`] now supports replacements\n  [#13669](https://github.com/rust-lang/rust-clippy/pull/13669)\n* Added MSRV checks for several lints:\n  * [`question_mark`] [#14436](https://github.com/rust-lang/rust-clippy/pull/14436)\n  * [`repeat_vec_with_capacity`] [#14126](https://github.com/rust-lang/rust-clippy/pull/14126)\n  * [`manual_flatten`] [#14086](https://github.com/rust-lang/rust-clippy/pull/14086)\n  * [`lines_filter_map_ok`] [#14130](https://github.com/rust-lang/rust-clippy/pull/14130)\n\n### False Positive Fixes\n\n* [`missing_const_for_fn`] no longer triggers on unstable const traits [#14294](https://github.com/rust-lang/rust-clippy/pull/14294)\n* [`unnecessary_to_owned`] now avoids suggesting to call `iter()` on a temporary object [#14243](https://github.com/rust-lang/rust-clippy/pull/14243)\n* [`unnecessary_debug_formatting`] no longer triggers in tests [#14347](https://github.com/rust-lang/rust-clippy/pull/14347)\n* [`option_if_let_else`] now handles cases when value is partially moved [#14209](https://github.com/rust-lang/rust-clippy/pull/14209)\n* [`blocks_in_conditions`] no longer triggers when the condition contains a `return` [#14338](https://github.com/rust-lang/rust-clippy/pull/14338)\n* [`undocumented_unsafe_blocks`] no longer triggers on trait/impl items [#13888](https://github.com/rust-lang/rust-clippy/pull/13888)\n* [`manual_slice_fill`] no longer triggers due to missing index checks [#14193](https://github.com/rust-lang/rust-clippy/pull/14193)\n* [`useless_asref`] no longer suggests using `.clone()` if the target type doesn't implement `Clone` [#14174](https://github.com/rust-lang/rust-clippy/pull/14174)\n* [`unnecessary_safety_comment`] no longer triggers on desugared assign [#14371](https://github.com/rust-lang/rust-clippy/pull/14371)\n* [`unnecessary_map_or`] no longer consumes the comparison value if it does not implement `Copy` [#14207](https://github.com/rust-lang/rust-clippy/pull/14207)\n* [`let_and_return`] no longer triggers involving short-lived block temporary variables [#14180](https://github.com/rust-lang/rust-clippy/pull/14180)\n* [`manual_async_fn`] no longer emits suggestions inside macros [#14142](https://github.com/rust-lang/rust-clippy/pull/14142)\n* [`use_self`] skips analysis inside macro expansions of a `impl Self` block [#13128](https://github.com/rust-lang/rust-clippy/pull/13128)\n* [`double_ended_iterator_last`] no longer triggers on non-reference immutable receiver [#14140](https://github.com/rust-lang/rust-clippy/pull/14140)\n\n### ICE Fixes\n\n* [`macro_use_imports`] Fix ICE when checking attributes\n  [#14317](https://github.com/rust-lang/rust-clippy/pull/14317)\n* [`doc_nested_refdefs`] Fix ICE by avoiding invalid ranges\n  [#14308](https://github.com/rust-lang/rust-clippy/pull/14308)\n* [`just_underscores_and_digits`] Fix ICE in error recovery scenario\n  [#14168](https://github.com/rust-lang/rust-clippy/pull/14168)\n* [`declare_interior_mutable_const`], [`borrow_interior_mutable_const`] Fix ICE by properly resolving `<T as Trait>::AssocT` projections\n  [#14125](https://github.com/rust-lang/rust-clippy/pull/14125)\n\n### Documentation Improvements\n\n* [`struct_excessive_bools`] Documentation improved with rationale\n  [#14351](https://github.com/rust-lang/rust-clippy/pull/14351)\n\n### Others\n\n* Use edition=2021 in `rustc_tools_util`\n  [#14211](https://github.com/rust-lang/rust-clippy/pull/14211)\n* Fix rustc_tools_util's `version.host_compiler` release channel, expose the rustc version, and add tests\n  [#14123](https://github.com/rust-lang/rust-clippy/pull/14123)\n* Make UI test annotations mandatory\n  [#11421](https://github.com/rust-lang/rust-clippy/pull/11421)\n  [#14388](https://github.com/rust-lang/rust-clippy/pull/14388)\n  [#14393](https://github.com/rust-lang/rust-clippy/pull/14393)\n\n## Rust 1.86\n\nCurrent stable, released 2025-04-03\n\n[View all 108 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-12-27T15%3A11%3A38Z..2025-02-06T13%3A57%3A58Z+base%3Amaster)\n\n### New Lints\n\n* Added [`unneeded_struct_pattern`] to `style` [#13465](https://github.com/rust-lang/rust-clippy/pull/13465)\n* Added [`doc_overindented_list_items`] to `style` [#13711](https://github.com/rust-lang/rust-clippy/pull/13711)\n* Added [`manual_ok_err`] to `complexity` [#13740](https://github.com/rust-lang/rust-clippy/pull/13740)\n* Added [`non_std_lazy_statics`] to `pedantic` [#13770](https://github.com/rust-lang/rust-clippy/pull/13770)\n* Added [`manual_repeat_n`] to `style` [#13858](https://github.com/rust-lang/rust-clippy/pull/13858)\n* Added [`manual_option_as_slice`] to `complexity` [#13901](https://github.com/rust-lang/rust-clippy/pull/13901)\n* Added [`double_ended_iterator_last`] to `perf` [#13922](https://github.com/rust-lang/rust-clippy/pull/13922)\n* Added [`useless_nonzero_new_unchecked`] to `complexity` [#13993](https://github.com/rust-lang/rust-clippy/pull/13993)\n* Added [`sliced_string_as_bytes`] to `perf` [#14002](https://github.com/rust-lang/rust-clippy/pull/14002)\n* Added [`unnecessary_semicolon`] to `pedantic` [#14032](https://github.com/rust-lang/rust-clippy/pull/14032)\n* Added [`return_and_then`] to `restriction` [#14051](https://github.com/rust-lang/rust-clippy/pull/14051)\n* Added [`manual_slice_fill`] to `style` [#14082](https://github.com/rust-lang/rust-clippy/pull/14082)\n* Added [`precedence_bits`] to `restriction` [#14115](https://github.com/rust-lang/rust-clippy/pull/14115)\n\n### Moves and Deprecations\n\n* Moved [`redundant_locals`] to `suspicious` (from `correctness`, now warn-by-default)\n  [#13747](https://github.com/rust-lang/rust-clippy/pull/13747)\n* Moved [`format_push_string`] to `pedantic` (from `restriction`)\n  [#13894](https://github.com/rust-lang/rust-clippy/pull/13894)\n* Moved [`format_collect`] to `pedantic` (from `perf`, now allow-by-default)\n  [#13894](https://github.com/rust-lang/rust-clippy/pull/13894)\n* Moved [`mutex_integer`] to `restriction` (from `nursery`) [#14110](https://github.com/rust-lang/rust-clippy/pull/14110)\n\n### Enhancements\n\n* Add `lint-inconsistent-struct-field-initializers` configuration option to [`inconsistent_struct_constructor`]\n  [#13737](https://github.com/rust-lang/rust-clippy/pull/13737)\n* [`len_zero`] now also triggers if deref target implements `is_empty()`\n  [#13871](https://github.com/rust-lang/rust-clippy/pull/13871)\n* [`obfuscated_if_else`] now also triggers for the `.then(..).unwrap_or(..)` pattern\n  [#14021](https://github.com/rust-lang/rust-clippy/pull/14021)\n\n### False Positive Fixes\n\n* [`trailing_empty_array`] no longer triggers in tests [#13844](https://github.com/rust-lang/rust-clippy/pull/13844)\n* [`missing_const_for_fn`] no longer triggers in tests [#13945](https://github.com/rust-lang/rust-clippy/pull/13945)\n* [`significant_drop_in_scrutinee`]: do not falsely warn for temporaries created by `.await` expansion\n  [#13985](https://github.com/rust-lang/rust-clippy/pull/13985)\n\n### ICE Fixes\n\n* [`borrow_interior_mutable_const`] Fix an ICE that can occur when taking a reference to a tuple/`struct` field of an\n  interior mutable `const` [#13877](https://github.com/rust-lang/rust-clippy/pull/13877)\n\n### Others\n\n* Clippy now uses Rust edition 2024 [#13751](https://github.com/rust-lang/rust-clippy/pull/13751)\n\n## Rust 1.85\n\nReleased 2025-02-20\n\n[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-11-15T19%3A31%3A08Z..2024-12-26T13%3A59%3A48Z+base%3Amaster)\n\n### New Lints\n\n* Added [`repr_packed_without_abi`] to `suspicious`\n  [#13398](https://github.com/rust-lang/rust-clippy/pull/13398)\n* Added [`as_pointer_underscore`] to `restriction`\n  [#13251](https://github.com/rust-lang/rust-clippy/pull/13251)\n* Added [`doc_nested_refdefs`] to `suspicious`\n  [#13707](https://github.com/rust-lang/rust-clippy/pull/13707)\n* Added [`literal_string_with_formatting_args`] to `nursery`\n  [#13410](https://github.com/rust-lang/rust-clippy/pull/13410)\n* Added [`doc_include_without_cfg`] to `restriction`\n  [#13625](https://github.com/rust-lang/rust-clippy/pull/13625)\n\n### Enhancements\n\n* [`indexing_slicing`]: Can now be allowed in tests using the [`allow-indexing-slicing-in-tests`]\n  configuration\n  [#13854](https://github.com/rust-lang/rust-clippy/pull/13854)\n* [`if_let_mutex`]: disable lint from Edition 2024 since\n  [if_let_rescope](https://github.com/rust-lang/rust/issues/131154) was stabilized\n  [#13695](https://github.com/rust-lang/rust-clippy/pull/13695)\n* [`format_in_format_args`], [`recursive_format_impl`], [`to_string_in_format_args`],\n  [`uninlined_format_args`], [`unused_format_specs`]: Can now support 3rd party format macros\n  if they're marked with the `#[clippy::format_args]` attribute\n  [#9948](https://github.com/rust-lang/rust-clippy/pull/9948)\n\n### ICE Fixes\n\n* [`trait_duplication_in_bounds`]: fix ICE on duplicate type or constant bound\n  [#13722](https://github.com/rust-lang/rust-clippy/pull/13722)\n\n### Others\n\n* `clippy_utils` is now published to crates.io. Note that this crate is and will remain unstable.\n  [#13700](https://github.com/rust-lang/rust-clippy/pull/13700)\n\n## Rust 1.84\n\nReleased 2025-01-09\n\n[View all 84 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-10-03T21%3A23%3A58Z..2024-11-14T17%3A41%3A37Z+base%3Amaster)\n\n### New Lints\n\n* Added [`unnecessary_map_or`] to `style`\n  [#11796](https://github.com/rust-lang/rust-clippy/pull/11796)\n* Added [`arbitrary_source_item_ordering`] to `restriction`\n  [#13376](https://github.com/rust-lang/rust-clippy/pull/13376)\n* Added [`map_with_unused_argument_over_ranges`] to `restriction`\n  [#13034](https://github.com/rust-lang/rust-clippy/pull/13034)\n* Added [`map_all_any_identity`] to `complexity`\n  [#13499](https://github.com/rust-lang/rust-clippy/pull/13499)\n* Added [`needless_as_bytes`] to `complexity`\n  [#13437](https://github.com/rust-lang/rust-clippy/pull/13437)\n* Added [`unnecessary_literal_bound`] to `pedantic`\n  [#13395](https://github.com/rust-lang/rust-clippy/pull/13395)\n* Added [`manual_ignore_case_cmp`] to `perf`\n  [#13334](https://github.com/rust-lang/rust-clippy/pull/13334)\n* Added [`regex_creation_in_loops`] to `perf`\n  [#13412](https://github.com/rust-lang/rust-clippy/pull/13412)\n\n### Moves and Deprecations\n\n* Moved [`manual_is_power_of_two`] to `pedantic` (From `complexity`, now allow-by-default)\n  [#13553](https://github.com/rust-lang/rust-clippy/pull/13553)\n* Move [`module_name_repetitions`] to `restriction` (from `pedantic`)\n  [#13541](https://github.com/rust-lang/rust-clippy/pull/13541)\n\n### Enhancements\n\n* [`doc_markdown`]: Added the following identifiers to [`doc-valid-idents`]:\n  CoAP, MHz, GHz, and THz\n  [#13633](https://github.com/rust-lang/rust-clippy/pull/13633)\n  [#13460](https://github.com/rust-lang/rust-clippy/pull/13460)\n* [`large_const_arrays`]: Changed the default of [`array-size-threshold`] to `16kb` (from `512kb`)\n  [#13485](https://github.com/rust-lang/rust-clippy/pull/13485)\n\n## Rust 1.83\n\nReleased 2024-11-28\n\n[View all 64 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-08-25T09%3A59%3A01Z..2024-10-03T13%3A42%3A56Z+base%3Amaster)\n\n### Important Change\n\n* Removed the implicit `cargo-clippy` feature set by Clippy as announced here:\n  <https://blog.rust-lang.org/2024/02/28/Clippy-deprecating-feature-cargo-clippy.html>\n  [#13246](https://github.com/rust-lang/rust-clippy/pull/13246)\n\n### New Lints\n\n* Added [`unused_trait_names`] to `restriction`\n  [#13322](https://github.com/rust-lang/rust-clippy/pull/13322)\n* Added [`unnecessary_first_then_check`] to `complexity`\n  [#13421](https://github.com/rust-lang/rust-clippy/pull/13421)\n* Added [`non_zero_suggestions`] to `restriction`\n  [#13167](https://github.com/rust-lang/rust-clippy/pull/13167)\n* Added [`manual_is_power_of_two`] to `pedantic`\n  [#13327](https://github.com/rust-lang/rust-clippy/pull/13327)\n* Added [`manual_div_ceil`] to `complexity`\n  [#12987](https://github.com/rust-lang/rust-clippy/pull/12987)\n* Added [`zombie_processes`] to `suspicious`\n  [#11476](https://github.com/rust-lang/rust-clippy/pull/11476)\n* Added [`used_underscore_items`] to `pedantic`\n  [#13294](https://github.com/rust-lang/rust-clippy/pull/13294)\n\n### Moves and Deprecations\n\n* Moved [`ref_option`] to `pedantic` (From `nursery`)\n  [#13469](https://github.com/rust-lang/rust-clippy/pull/13469)\n* Moved [`manual_c_str_literals`] to `complexity` (From `pedantic`, now warn-by-default)\n  [#13263](https://github.com/rust-lang/rust-clippy/pull/13263)\n* Moved [`empty_line_after_doc_comments`] to `suspicious` (From `nursery`, now warn-by-default)\n  [#13091](https://github.com/rust-lang/rust-clippy/pull/13091)\n* Moved [`empty_line_after_outer_attr`] to `suspicious` (From `nursery`, now warn-by-default)\n  [#13091](https://github.com/rust-lang/rust-clippy/pull/13091)\n\n### Enhancements\n\n* [`missing_panics_doc`]: No longer lints in const environments\n  [#13382](https://github.com/rust-lang/rust-clippy/pull/13382)\n\n## Rust 1.82\n\nReleased 2024-10-17\n\n[View all 108 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-07-11T20%3A12%3A07Z..2024-08-24T20%3A55%3A35Z+base%3Amaster)\n\n### New Lints\n\n* Added [`too_long_first_doc_paragraph`] to `nursery`\n  [#12993](https://github.com/rust-lang/rust-clippy/pull/12993)\n* Added [`unused_result_ok`] to `restriction`\n  [#12150](https://github.com/rust-lang/rust-clippy/pull/12150)\n* Added [`pathbuf_init_then_push`] to `restriction`\n  [#11700](https://github.com/rust-lang/rust-clippy/pull/11700)\n\n### Enhancements\n\n* [`explicit_iter_loop`]: Now respects the `msrv` configuration\n  [#13288](https://github.com/rust-lang/rust-clippy/pull/13288)\n* [`assigning_clones`]: No longer lints in test code\n  [#13273](https://github.com/rust-lang/rust-clippy/pull/13273)\n* [`inconsistent_struct_constructor`]: Lint attributes now work on the struct definition\n  [#13211](https://github.com/rust-lang/rust-clippy/pull/13211)\n* [`set_contains_or_insert`]: Now also checks for `BTreeSet`\n  [#13053](https://github.com/rust-lang/rust-clippy/pull/13053)\n* [`doc_markdown`]: Added the following identifiers to [`doc-valid-idents`]: AccessKit,\n  CoreFoundation, CoreGraphics, CoreText, Direct2D, Direct3D, DirectWrite, PostScript,\n  OpenAL, OpenType, WebRTC, WebSocket, WebTransport, NetBSD, and OpenBSD\n  [#13093](https://github.com/rust-lang/rust-clippy/pull/13093)\n\n### ICE Fixes\n\n* [`uninit_vec`]\n  [rust#128720](https://github.com/rust-lang/rust/pull/128720)\n\n## Rust 1.81\n\nReleased 2024-09-05\n\n### New Lints\n\n* Added [`cfg_not_test`] to `restriction`\n  [#11293](https://github.com/rust-lang/rust-clippy/pull/11293)\n* Added [`byte_char_slices`] to `style`\n  [#10155](https://github.com/rust-lang/rust-clippy/pull/10155)\n* Added [`set_contains_or_insert`] to `nursery`\n  [#12873](https://github.com/rust-lang/rust-clippy/pull/12873)\n* Added [`manual_rotate`] to `style`\n  [#12983](https://github.com/rust-lang/rust-clippy/pull/12983)\n* Added [`unnecessary_min_or_max`] to `complexity`\n  [#12368](https://github.com/rust-lang/rust-clippy/pull/12368)\n* Added [`manual_inspect`] to `complexity`\n  [#12287](https://github.com/rust-lang/rust-clippy/pull/12287)\n* Added [`field_scoped_visibility_modifiers`] to `restriction`\n  [#12893](https://github.com/rust-lang/rust-clippy/pull/12893)\n* Added [`manual_pattern_char_comparison`] to `style`\n  [#12849](https://github.com/rust-lang/rust-clippy/pull/12849)\n* Added [`needless_maybe_sized`] to `suspicious`\n  [#10632](https://github.com/rust-lang/rust-clippy/pull/10632)\n* Added [`needless_character_iteration`] to `suspicious`\n  [#12815](https://github.com/rust-lang/rust-clippy/pull/12815)\n\n### Moves and Deprecations\n\n* [`allow_attributes`], [`allow_attributes_without_reason`]: Now work on stable\n  [rust#120924](https://github.com/rust-lang/rust/pull/120924)\n* Renamed `overflow_check_conditional` to [`panicking_overflow_checks`]\n  [#12944](https://github.com/rust-lang/rust-clippy/pull/12944)\n* Moved [`panicking_overflow_checks`] to `correctness` (From `complexity` now deny-by-default)\n  [#12944](https://github.com/rust-lang/rust-clippy/pull/12944)\n* Renamed `thread_local_initializer_can_be_made_const` to [`missing_const_for_thread_local`]\n  [#12974](https://github.com/rust-lang/rust-clippy/pull/12974)\n* Deprecated [`maybe_misused_cfg`] and [`mismatched_target_os`] as they are now caught by cargo\n  and rustc\n  [#12875](https://github.com/rust-lang/rust-clippy/pull/12875)\n\n### Enhancements\n\n* [`significant_drop_in_scrutinee`]: Now also checks scrutinies of `while let` and `for let`\n  expressions\n  [#12870](https://github.com/rust-lang/rust-clippy/pull/12870)\n* [`std_instead_of_core`]: Now respects the `msrv` configuration\n  [#13168](https://github.com/rust-lang/rust-clippy/pull/13168)\n\n### ICE Fixes\n\n* [`suboptimal_flops`]: No longer crashes on custom `.log()` functions\n  [#12884](https://github.com/rust-lang/rust-clippy/pull/12884)\n\n## Rust 1.80\n\nCurrent stable, released 2024-07-25\n\n[View all 68 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-04-18T22%3A50%3A22Z..2024-05-30T08%3A26%3A18Z+base%3Amaster)\n\n### New Lints\n\n* Added [`while_float`] to `nursery`\n  [#12765](https://github.com/rust-lang/rust-clippy/pull/12765)\n* Added [`macro_metavars_in_unsafe`] to `suspicious`\n  [#12107](https://github.com/rust-lang/rust-clippy/pull/12107)\n* Added [`renamed_function_params`] to `restriction`\n  [#11540](https://github.com/rust-lang/rust-clippy/pull/11540)\n* Added [`doc_lazy_continuation`] to `style`\n  [#12770](https://github.com/rust-lang/rust-clippy/pull/12770)\n\n### Moves and Deprecations\n\n* Moved [`assigning_clones`] to `pedantic` (From `perf` now allow-by-default)\n  [#12779](https://github.com/rust-lang/rust-clippy/pull/12779)\n* Moved [`single_char_pattern`] to `pedantic` (From `perf` now allow-by-default)\n  [#11852](https://github.com/rust-lang/rust-clippy/pull/11852)\n\n### Enhancements\n\n* [`panic`]: Added [`allow-panic-in-tests`] configuration to allow the lint in tests\n  [#12803](https://github.com/rust-lang/rust-clippy/pull/12803)\n* [`missing_const_for_fn`]: Now respects the [`msrv`] configuration\n  [#12713](https://github.com/rust-lang/rust-clippy/pull/12713)\n* [`missing_panics_doc`]: No longer lints on compile-time panics\n  [#12790](https://github.com/rust-lang/rust-clippy/pull/12790)\n* [`collapsible_match`]: Now considers the [`msrv`] configuration for the suggestion\n  [#12745](https://github.com/rust-lang/rust-clippy/pull/12745)\n* [`useless_vec`]: Added [`allow-useless-vec-in-tests`] configuration to allow the lint in tests\n  [#12725](https://github.com/rust-lang/rust-clippy/pull/12725)\n\n### Suggestion Fixes/Improvements\n\n* [`single_match`], [`single_match_else`]: Suggestions are now machine-applicable\n  [#12726](https://github.com/rust-lang/rust-clippy/pull/12726)\n\n## Rust 1.79\n\nReleased 2024-06-13\n\n[View all 102 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-03-08T11%3A13%3A58Z..2024-04-18T15%3A50%3A50Z+base%3Amaster)\n\n### New Lints\n\n* Added [`legacy_numeric_constants`] to `style`\n  [#12312](https://github.com/rust-lang/rust-clippy/pull/12312)\n* Added [`missing_transmute_annotations`] to `suspicious`\n  [#12239](https://github.com/rust-lang/rust-clippy/pull/12239)\n* Added [`integer_division_remainder_used`] to `restriction`\n  [#12451](https://github.com/rust-lang/rust-clippy/pull/12451)\n* Added [`duplicated_attributes`] to `suspicious`\n  [#12378](https://github.com/rust-lang/rust-clippy/pull/12378)\n* Added [`manual_unwrap_or_default`] to `suspicious`\n  [#12440](https://github.com/rust-lang/rust-clippy/pull/12440)\n* Added [`zero_repeat_side_effects`] to `suspicious`\n  [#12449](https://github.com/rust-lang/rust-clippy/pull/12449)\n* Added [`const_is_empty`] to `suspicious`\n  [#12310](https://github.com/rust-lang/rust-clippy/pull/12310)\n\n### Moves and Deprecations\n\n* Moved [`box_default`] to `style` (From `perf`)\n  [#12601](https://github.com/rust-lang/rust-clippy/pull/12601)\n* Moved [`manual_clamp`] to `complexity` (From `nursery` now warn-by-default)\n  [#12543](https://github.com/rust-lang/rust-clippy/pull/12543)\n* Moved [`readonly_write_lock`] to `perf` (From `nursery` now warn-by-default)\n  [#12479](https://github.com/rust-lang/rust-clippy/pull/12479)\n\n### Enhancements\n\n* [`module_name_repetitions`]: Added the [`allowed-prefixes`] configuration to allow common prefixes.\n  [#12573](https://github.com/rust-lang/rust-clippy/pull/12573)\n* [`cast_sign_loss`], [`cast_possible_truncation`], [`cast_lossless`]: Are now allowed in macros\n  [#12631](https://github.com/rust-lang/rust-clippy/pull/12631)\n* [`manual_clamp`]: Now only lints on constant min and max values\n  [#12543](https://github.com/rust-lang/rust-clippy/pull/12543)\n* [`assigning_clones`]: Now considers the [`msrv`] configuration\n  [#12511](https://github.com/rust-lang/rust-clippy/pull/12511)\n* [`needless_return`], [`useless_let_if_seq`], [`mut_mut`], [`read_zero_byte_vec`], [`unused_io_amount`],\n  [`unused_peekable`]: Now respects `#[allow]` attributes on the affected statement instead\n  [#12446](https://github.com/rust-lang/rust-clippy/pull/12446)\n\n### False Positive Fixes\n\n* [`cast_lossless`]: No longer lints when casting to `u128`\n  [#12496](https://github.com/rust-lang/rust-clippy/pull/12496)\n* [`std_instead_of_core`] No longer lints on modules that are only in `std`\n  [#12447](https://github.com/rust-lang/rust-clippy/pull/12447)\n\n### ICE Fixes\n\n* [`needless_return`]: No longer crashes on non-ascii characters\n  [#12493](https://github.com/rust-lang/rust-clippy/pull/12493)\n\n## Rust 1.78\n\nReleased 2024-05-02\n\n[View all 112 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2024-01-26T05%3A46%3A23Z..2024-03-07T16%3A25%3A52Z+base%3Amaster)\n\n### New Lints\n\n* [`assigning_clones`]\n  [#12077](https://github.com/rust-lang/rust-clippy/pull/12077)\n* [`mixed_attributes_style`]\n  [#12354](https://github.com/rust-lang/rust-clippy/pull/12354)\n* [`empty_docs`]\n  [#12342](https://github.com/rust-lang/rust-clippy/pull/12342)\n* [`unnecessary_get_then_check`]\n  [#12339](https://github.com/rust-lang/rust-clippy/pull/12339)\n* [`multiple_bound_locations`]\n  [#12259](https://github.com/rust-lang/rust-clippy/pull/12259)\n* [`unnecessary_clippy_cfg`]\n  [#12303](https://github.com/rust-lang/rust-clippy/pull/12303)\n* [`deprecated_clippy_cfg_attr`]\n  [#12292](https://github.com/rust-lang/rust-clippy/pull/12292)\n* [`manual_c_str_literals`]\n  [#11919](https://github.com/rust-lang/rust-clippy/pull/11919)\n* [`ref_as_ptr`]\n  [#12087](https://github.com/rust-lang/rust-clippy/pull/12087)\n* [`lint_groups_priority`]\n  [#11832](https://github.com/rust-lang/rust-clippy/pull/11832)\n* [`unnecessary_result_map_or_else`]\n  [#12169](https://github.com/rust-lang/rust-clippy/pull/12169)\n* [`to_string_trait_impl`]\n  [#12122](https://github.com/rust-lang/rust-clippy/pull/12122)\n* [`incompatible_msrv`]\n  [#12160](https://github.com/rust-lang/rust-clippy/pull/12160)\n\n### Enhancements\n\n* [`thread_local_initializer_can_be_made_const`]: Now checks the [`msrv`] configuration\n  [#12405](https://github.com/rust-lang/rust-clippy/pull/12405)\n* [`disallowed_macros`]: Code generated by derive macros can no longer allow this lint\n  [#12267](https://github.com/rust-lang/rust-clippy/pull/12267)\n* [`wildcard_imports`]: Add configuration [`allowed-wildcard-imports`] to allow preconfigured wildcards\n  [#11979](https://github.com/rust-lang/rust-clippy/pull/11979)\n\n### ICE Fixes\n\n* [`ptr_as_ptr`]: No longer ICEs when the cast source is a function call to a local variable\n  [#12617](https://github.com/rust-lang/rust-clippy/pull/12617)\n* [`cast_sign_loss`]: Avoids an infinite loop when casting two chained `.unwrap()` calls\n  [#12508](https://github.com/rust-lang/rust-clippy/pull/12508)\n\n## Rust 1.77\n\nReleased 2024-03-18\n\n[View all 93 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-12-16T18%3A20%3A00Z..2024-01-25T18%3A15%3A56Z+base%3Amaster)\n\n### New Lints\n\n* [`suspicious_open_options`]\n  [#11608](https://github.com/rust-lang/rust-clippy/pull/11608)\n* [`option_as_ref_cloned`]\n  [#12051](https://github.com/rust-lang/rust-clippy/pull/12051)\n* [`thread_local_initializer_can_be_made_const`]\n  [#12026](https://github.com/rust-lang/rust-clippy/pull/12026)\n* [`str_split_at_newline`]\n  [#11987](https://github.com/rust-lang/rust-clippy/pull/11987)\n* [`empty_enum_variants_with_brackets`]\n  [#12047](https://github.com/rust-lang/rust-clippy/pull/12047)\n* [`manual_is_variant_and`]\n  [#11865](https://github.com/rust-lang/rust-clippy/pull/11865)\n* [`pub_underscore_fields`]\n  [#10283](https://github.com/rust-lang/rust-clippy/pull/10283)\n* [`eager_transmute`]\n  [#11981](https://github.com/rust-lang/rust-clippy/pull/11981)\n* [`iter_filter_is_some`]\n  [#12004](https://github.com/rust-lang/rust/pull/12004)\n* [`iter_filter_is_ok`]\n  [#12004](https://github.com/rust-lang/rust/pull/12004)\n* [`result_filter_map`]\n  [#11869](https://github.com/rust-lang/rust-clippy/pull/11869)\n* [`unconditional_recursion`]\n  [#11938](https://github.com/rust-lang/rust-clippy/pull/11938)\n\n### Enhancements\n\n* [`multiple_crate_versions`]: Added the [`allowed-duplicate-crates`] configuration to allow specific crates\n  [#12179](https://github.com/rust-lang/rust-clippy/pull/12179)\n* [`single_call_fn`]: No longer ignores `#[allow]` attributes\n  [#12183](https://github.com/rust-lang/rust-clippy/pull/12183)\n* [`read_zero_byte_vec`]: Updated the heuristics used for linting\n  [#11766](https://github.com/rust-lang/rust-clippy/pull/11766)\n\n### ICE Fixes\n\n* [`unit_arg`]: No longer crashes when checking for const in nested bodies\n  [#11977](https://github.com/rust-lang/rust-clippy/pull/11977)\n* [`indexing_slicing`]: No longer crashes when the array index exceeds `usize`\n  [#12266](https://github.com/rust-lang/rust-clippy/pull/12266)\n\n### Others\n\n* Warnings about invalid fields inside `clippy.toml` files now include suggestions for existing fields\n  [#12180](https://github.com/rust-lang/rust-clippy/pull/12180)\n\n## Rust 1.76\n\nReleased 2024-02-08\n\n[View all 85 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-11-02T20%3A23%3A40Z..2023-12-16T13%3A11%3A08Z+base%3Amaster)\n\n### New Lints\n\n* [`infinite_loop`]\n  [#11829](https://github.com/rust-lang/rust-clippy/pull/11829)\n* [`ineffective_open_options`]\n  [#11902](https://github.com/rust-lang/rust-clippy/pull/11902)\n* [`uninhabited_references`]\n  [#11878](https://github.com/rust-lang/rust-clippy/pull/11878)\n* [`repeat_vec_with_capacity`]\n  [#11597](https://github.com/rust-lang/rust-clippy/pull/11597)\n* [`test_attr_in_doctest`]\n  [#11872](https://github.com/rust-lang/rust-clippy/pull/11872)\n* [`option_map_or_err_ok`]\n  [#11864](https://github.com/rust-lang/rust-clippy/pull/11864)\n* [`join_absolute_paths`]\n  [#11453](https://github.com/rust-lang/rust-clippy/pull/11453)\n* [`impl_hash_borrow_with_str_and_bytes`]\n  [#11781](https://github.com/rust-lang/rust-clippy/pull/11781)\n* [`iter_over_hash_type`]\n  [#11791](https://github.com/rust-lang/rust-clippy/pull/11791)\n\n### Moves and Deprecations\n\n* Renamed `blocks_in_if_conditions` to [`blocks_in_conditions`]\n  [#11853](https://github.com/rust-lang/rust-clippy/pull/11853)\n* Moved [`implied_bounds_in_impls`] to `complexity` (Now warn-by-default)\n  [#11867](https://github.com/rust-lang/rust-clippy/pull/11867)\n* Moved [`if_same_then_else`] to `style` (Now warn-by-default)\n  [#11809](https://github.com/rust-lang/rust-clippy/pull/11809)\n\n### Enhancements\n\n* [`missing_safety_doc`], [`unnecessary_safety_doc`], [`missing_panics_doc`], [`missing_errors_doc`]:\n  Added the [`check-private-items`] configuration to enable lints on private items\n  [#11842](https://github.com/rust-lang/rust-clippy/pull/11842)\n\n### ICE Fixes\n\n* [`impl_trait_in_params`]: No longer crashes when a function has generics but no function parameters\n  [#11804](https://github.com/rust-lang/rust-clippy/pull/11804)\n* [`unused_enumerate_index`]: No longer crashes on empty tuples\n  [#11756](https://github.com/rust-lang/rust-clippy/pull/11756)\n\n### Others\n\n* Clippy now respects the `CARGO` environment value\n  [#11944](https://github.com/rust-lang/rust-clippy/pull/11944)\n\n## Rust 1.75\n\nReleased 2023-12-28\n\n[View all 69 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-09-25T11%3A47%3A47Z..2023-11-02T16%3A41%3A59Z+base%3Amaster)\n\n### New Lints\n\n* [`unused_enumerate_index`]\n  [#10404](https://github.com/rust-lang/rust-clippy/pull/10404)\n* [`unnecessary_fallible_conversions`]\n  [#11669](https://github.com/rust-lang/rust-clippy/pull/11669)\n* [`waker_clone_wake`]\n  [#11698](https://github.com/rust-lang/rust-clippy/pull/11698)\n* [`struct_field_names`]\n  [#11496](https://github.com/rust-lang/rust-clippy/pull/11496)\n* [`into_iter_without_iter`]\n  [#11587](https://github.com/rust-lang/rust-clippy/pull/11587)\n* [`iter_without_into_iter`]\n  [#11527](https://github.com/rust-lang/rust-clippy/pull/11527)\n* [`manual_hash_one`]\n  [#11556](https://github.com/rust-lang/rust-clippy/pull/11556)\n\n### Moves and Deprecations\n\n* Moved [`read_zero_byte_vec`] to `nursery` (Now allow-by-default)\n  [#11727](https://github.com/rust-lang/rust-clippy/pull/11727)\n* Moved [`missing_enforced_import_renames`] to `style` (Now warn-by-default)\n  [#11539](https://github.com/rust-lang/rust-clippy/pull/11539)\n* Moved [`needless_raw_string_hashes`] to `pedantic` (Now allow-by-default)\n  [#11415](https://github.com/rust-lang/rust-clippy/pull/11415)\n* Moved [`needless_pass_by_ref_mut`] to `nursery` (Now allow-by-default)\n  [#11596](https://github.com/rust-lang/rust-clippy/pull/11596)\n\n### Enhancements\n\n* [`declare_interior_mutable_const`] and [`borrow_interior_mutable_const`]: Now check the\n  [`ignore-interior-mutability`] config value\n  [#11678](https://github.com/rust-lang/rust-clippy/pull/11678)\n\n### Suggestion Fixes/Improvements\n\n* [`items_after_test_module`]: The suggestion is now machine-applicable\n  [#11611](https://github.com/rust-lang/rust-clippy/pull/11611)\n\n### ICE Fixes\n\n* [`redundant_locals`]: No longer crashes if variables are rebound above macros\n  [#11623](https://github.com/rust-lang/rust-clippy/pull/11623)\n* [`implicit_hasher`]: No longer lints inside macros, which could cause ICEs\n  [#11593](https://github.com/rust-lang/rust-clippy/pull/11593)\n\n### Documentation Improvements\n\n* `cargo clippy --help` now uses colors for readability :tada:\n\n## Rust 1.74\n\nReleased 2023-11-16\n\n[View all 94 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-08-11T15%3A29%3A18Z..2023-09-25T08%3A48%3A22Z+base%3Amaster)\n\n### New Lints\n\n* [`redundant_as_str`]\n  [#11526](https://github.com/rust-lang/rust-clippy/pull/11526)\n* [`needless_borrows_for_generic_args`]\n  [#11511](https://github.com/rust-lang/rust-clippy/pull/11511)\n* [`path_ends_with_ext`]\n  [#11483](https://github.com/rust-lang/rust-clippy/pull/11483)\n* [`unnecessary_map_on_constructor`]\n  [#11413](https://github.com/rust-lang/rust-clippy/pull/11413)\n* [`missing_asserts_for_indexing`]\n  [#10692](https://github.com/rust-lang/rust-clippy/pull/10692)\n* [`iter_out_of_bounds`]\n  [#11396](https://github.com/rust-lang/rust-clippy/pull/11396)\n* [`implied_bounds_in_impls`]\n  [#11362](https://github.com/rust-lang/rust-clippy/pull/11362)\n* [`reserve_after_initialization`]\n  [#11373](https://github.com/rust-lang/rust-clippy/pull/11373)\n* [`should_panic_without_expect`]\n  [#11204](https://github.com/rust-lang/rust-clippy/pull/11204)\n\n### Moves and Deprecations\n\n* Renamed `incorrect_clone_impl_on_copy_type` to [`non_canonical_clone_impl`]\n  [#11358](https://github.com/rust-lang/rust-clippy/pull/11358)\n* Renamed `incorrect_partial_ord_impl_on_ord_type` to [`non_canonical_partial_ord_impl`]\n  [#11358](https://github.com/rust-lang/rust-clippy/pull/11358)\n* Moved [`non_canonical_clone_impl`] to `suspicious` (Now warn-by-default)\n  [#11358](https://github.com/rust-lang/rust-clippy/pull/11358)\n* Moved [`non_canonical_partial_ord_impl`] to `suspicious` (Now warn-by-default)\n  [#11358](https://github.com/rust-lang/rust-clippy/pull/11358)\n* Moved [`needless_pass_by_ref_mut`] to `nursery` (Now allow-by-default)\n  [#11596](https://github.com/rust-lang/rust-clippy/pull/11596)\n\n### Enhancements\n\n* [`undocumented_unsafe_blocks`]: The config values [`accept-comment-above-statement`] and\n  [`accept-comment-above-attributes`] are now `true` by default\n  [#11170](https://github.com/rust-lang/rust-clippy/pull/11170)\n* [`explicit_iter_loop`]: Added [`enforce-iter-loop-reborrow`] to disable reborrow linting by default\n  [#11418](https://github.com/rust-lang/rust-clippy/pull/11418)\n\n### ICE Fixes\n\n* [`enum_variant_names`]: No longer crashes if the threshold is 0 and the enum has no variants\n  [#11552](https://github.com/rust-lang/rust-clippy/pull/11552)\n* [`cast_possible_truncation`]: No longer crashes on values larger than `u64::MAX`\n  [#11517](https://github.com/rust-lang/rust-clippy/pull/11517)\n* [`tuple_array_conversions`]: No longer crashes if the array length is not usize\n  [#11379](https://github.com/rust-lang/rust-clippy/pull/11379)\n* [`useless_conversion`]: No longer crashes, when the receiver is a non-fn item\n  [#11070](https://github.com/rust-lang/rust-clippy/pull/11070)\n\n## Rust 1.73\n\nReleased 2023-10-05\n\n[View all 103 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-07-02T12%3A24%3A40Z..2023-08-11T11%3A09%3A56Z+base%3Amaster)\n\n### New Lints\n\n* [`impossible_comparisons`]\n  [#10843](https://github.com/rust-lang/rust-clippy/pull/10843)\n* [`redundant_comparisons`]\n  [#10843](https://github.com/rust-lang/rust-clippy/pull/10843)\n* [`ignored_unit_patterns`]\n  [#11242](https://github.com/rust-lang/rust-clippy/pull/11242)\n* [`readonly_write_lock`]\n  [#11210](https://github.com/rust-lang/rust-clippy/pull/11210)\n* [`filter_map_bool_then`]\n  [#11115](https://github.com/rust-lang/rust-clippy/pull/11115)\n* [`needless_return_with_question_mark`]\n  [#11031](https://github.com/rust-lang/rust-clippy/pull/11031)\n* [`redundant_guards`]\n  [#10955](https://github.com/rust-lang/rust-clippy/pull/10955)\n* [`redundant_locals`]\n  [#10885](https://github.com/rust-lang/rust-clippy/pull/10885)\n* [`absolute_paths`]\n  [#11003](https://github.com/rust-lang/rust-clippy/pull/11003)\n* [`error_impl_error`]\n  [#11107](https://github.com/rust-lang/rust-clippy/pull/11107)\n* [`iter_skip_zero`]\n  [#11046](https://github.com/rust-lang/rust-clippy/pull/11046)\n* [`string_lit_chars_any`]\n  [#11052](https://github.com/rust-lang/rust-clippy/pull/11052)\n* [`four_forward_slashes`]\n  [#11140](https://github.com/rust-lang/rust-clippy/pull/11140)\n* [`format_collect`]\n  [#11116](https://github.com/rust-lang/rust-clippy/pull/11116)\n* [`needless_pass_by_ref_mut`]\n  [#10900](https://github.com/rust-lang/rust-clippy/pull/10900)\n* [`manual_is_infinite`]\n  [#11049](https://github.com/rust-lang/rust-clippy/pull/11049)\n* [`manual_is_finite`]\n  [#11049](https://github.com/rust-lang/rust-clippy/pull/11049)\n* [`incorrect_partial_ord_impl_on_ord_type`]\n  [#10788](https://github.com/rust-lang/rust-clippy/pull/10788)\n* [`read_line_without_trim`]\n  [#10970](https://github.com/rust-lang/rust-clippy/pull/10970)\n* [`type_id_on_box`]\n  [#10987](https://github.com/rust-lang/rust-clippy/pull/10987)\n\n### Moves and Deprecations\n\n* Renamed `unwrap_or_else_default` to [`unwrap_or_default`]\n  [#10120](https://github.com/rust-lang/rust-clippy/pull/10120)\n* Moved [`tuple_array_conversions`] to `pedantic` (Now allow-by-default)\n  [#11146](https://github.com/rust-lang/rust-clippy/pull/11146)\n* Moved [`arc_with_non_send_sync`] to `suspicious` (Now warn-by-default)\n  [#11104](https://github.com/rust-lang/rust-clippy/pull/11104)\n* Moved [`needless_raw_string_hashes`] to `pedantic` (Now allow-by-default)\n  [#11415](https://github.com/rust-lang/rust-clippy/pull/11415)\n\n### Enhancements\n\n* [`unwrap_used`]: No longer lints on the never-type or never-like enums\n  [#11252](https://github.com/rust-lang/rust-clippy/pull/11252)\n* [`expect_used`]: No longer lints on the never-type or never-like enums\n  [#11252](https://github.com/rust-lang/rust-clippy/pull/11252)\n\n### False Positive Fixes\n\n* [`panic_in_result_fn`]: No longer triggers on `todo!`, `unimplemented!`, `unreachable!`\n  [#11123](https://github.com/rust-lang/rust-clippy/pull/11123)\n\n### Suggestion Fixes/Improvements\n\n* [`semicolon_if_nothing_returned`]: The suggestion is now machine-applicable with rustfix\n  [#11083](https://github.com/rust-lang/rust-clippy/pull/11083)\n\n### ICE Fixes\n\n* [`filter_map_bool_then`]: No longer crashes on late-bound regions\n  [#11318](https://github.com/rust-lang/rust-clippy/pull/11318)\n* [`unwrap_or_default`]: No longer crashes on alias types for local items\n  [#11258](https://github.com/rust-lang/rust-clippy/pull/11258)\n* [`unnecessary_literal_unwrap`]: No longer crashes on `None.unwrap_or_default()`\n  [#11106](https://github.com/rust-lang/rust-clippy/pull/11106)\n* Fixed MIR-related ICE\n  [#11130](https://github.com/rust-lang/rust-clippy/pull/11130)\n* [`missing_fields_in_debug`]: No longer crashes on non-ADT self types\n  [#11069](https://github.com/rust-lang/rust-clippy/pull/11069)\n\n## Rust 1.72\n\nReleased 2023-08-24\n\n[View all 131 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-05-22T14%3A53%3A59Z..2023-07-01T22%3A57%3A20Z+base%3Amaster)\n\n### New Lints\n\n* [`manual_try_fold`]\n  [#11012](https://github.com/rust-lang/rust-clippy/pull/11012)\n* [`tuple_array_conversions`]\n  [#11020](https://github.com/rust-lang/rust-clippy/pull/11020)\n* [`redundant_at_rest_pattern`]\n  [#11013](https://github.com/rust-lang/rust-clippy/pull/11013)\n* [`needless_pub_self`]\n  [#10967](https://github.com/rust-lang/rust-clippy/pull/10967)\n* [`pub_with_shorthand`]\n  [#10967](https://github.com/rust-lang/rust-clippy/pull/10967)\n* [`pub_without_shorthand`]\n  [#10967](https://github.com/rust-lang/rust-clippy/pull/10967)\n* [`manual_range_patterns`]\n  [#10968](https://github.com/rust-lang/rust-clippy/pull/10968)\n* [`needless_raw_string_hashes`]\n  [#10884](https://github.com/rust-lang/rust-clippy/pull/10884)\n* [`needless_raw_strings`]\n  [#10884](https://github.com/rust-lang/rust-clippy/pull/10884)\n* [`incorrect_clone_impl_on_copy_type`]\n  [#10925](https://github.com/rust-lang/rust-clippy/pull/10925)\n* [`drain_collect`]\n  [#10835](https://github.com/rust-lang/rust-clippy/pull/10835)\n* [`single_range_in_vec_init`]\n  [#10934](https://github.com/rust-lang/rust-clippy/pull/10934)\n* [`unnecessary_literal_unwrap`]\n  [#10358](https://github.com/rust-lang/rust-clippy/pull/10358)\n* [`large_stack_frames`]\n  [#10827](https://github.com/rust-lang/rust-clippy/pull/10827)\n* [`min_ident_chars`]\n  [#10916](https://github.com/rust-lang/rust-clippy/pull/10916)\n* [`needless_if`]\n  [#10921](https://github.com/rust-lang/rust-clippy/pull/10921)\n* [`excessive_nesting`]\n  [#10672](https://github.com/rust-lang/rust-clippy/pull/10672)\n* [`arc_with_non_send_sync`]\n  [#10898](https://github.com/rust-lang/rust-clippy/pull/10898)\n* [`redundant_type_annotations`]\n  [#10570](https://github.com/rust-lang/rust-clippy/pull/10570)\n* [`host_endian_bytes`]\n  [#10826](https://github.com/rust-lang/rust-clippy/pull/10826)\n* [`little_endian_bytes`]\n  [#10826](https://github.com/rust-lang/rust-clippy/pull/10826)\n* [`big_endian_bytes`]\n  [#10826](https://github.com/rust-lang/rust-clippy/pull/10826)\n* [`ptr_cast_constness`]\n  [#10779](https://github.com/rust-lang/rust-clippy/pull/10779)\n* [`needless_else`]\n  [#10810](https://github.com/rust-lang/rust-clippy/pull/10810)\n\n### Moves and Deprecations\n\n* Moved [`redundant_clone`] to `nursery` (Now allow-by-default)\n  [#10873](https://github.com/rust-lang/rust-clippy/pull/10873)\n\n### Enhancements\n\n* [`undocumented_unsafe_blocks`]: Added [`accept-comment-above-attributes`] configuration\n  [#10986](https://github.com/rust-lang/rust-clippy/pull/10986)\n* [`undocumented_unsafe_blocks`]: Added [`accept-comment-above-statement`] configuration.\n  [#10886](https://github.com/rust-lang/rust-clippy/pull/10886)\n* [`missing_panics_doc`]: No longer lints on `todo!()`\n  [#10976](https://github.com/rust-lang/rust-clippy/pull/10976)\n* [`module_inception`]: Added `allow-private-module-inception` configuration.\n  [#10917](https://github.com/rust-lang/rust-clippy/pull/10917)\n* Errors and warnings generated while parsing `clippy.toml` now point to the location in the TOML\n  file the error/warning occurred in.\n  [#10607](https://github.com/rust-lang/rust-clippy/pull/10607)\n\n### False Positive Fixes\n\n* [`excessive_precision`]: No longer lints overflowing literals\n  [#10952](https://github.com/rust-lang/rust-clippy/pull/10952)\n\n### Suggestion Fixes/Improvements\n\n* [`option_map_unwrap_or`]: The suggestion now considers the set [`msrv`] config value\n  [#11030](https://github.com/rust-lang/rust-clippy/pull/11030)\n\n### Documentation Improvements\n\n* [Clippy's lint list] now stores filter parameters in the URL, to allow easy sharing\n  [#10834](https://github.com/rust-lang/rust-clippy/pull/10834)\n\n## Rust 1.71\n\nReleased 2023-07-13\n\nNote: Clippy will use a shorter changelog format from now on, if you want a detailed list of\nall changes, please check out the list of merged pull requests.\n\n[View all 78 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-04-11T20%3A05%3A26Z..2023-05-20T13%3A48%3A17Z+base%3Amaster)\n\n### New Lints\n\n* [`non_minimal_cfg`]\n  [#10763](https://github.com/rust-lang/rust-clippy/pull/10763)\n* [`manual_next_back`]\n  [#10769](https://github.com/rust-lang/rust-clippy/pull/10769)\n* [`ref_patterns`]\n  [#10736](https://github.com/rust-lang/rust-clippy/pull/10736)\n* [`default_constructed_unit_structs`]\n  [#10716](https://github.com/rust-lang/rust-clippy/pull/10716)\n* [`manual_while_let_some`]\n  [#10647](https://github.com/rust-lang/rust-clippy/pull/10647)\n* [`needless_bool_assign`]\n  [#10432](https://github.com/rust-lang/rust-clippy/pull/10432)\n* [`items_after_test_module`]\n  [#10578](https://github.com/rust-lang/rust-clippy/pull/10578)\n\n### Moves and Deprecations\n\n* Rename `integer_arithmetic` to `arithmetic_side_effects`\n  [#10674](https://github.com/rust-lang/rust-clippy/pull/10674)\n* Moved [`redundant_clone`] to `nursery` (Now allow-by-default)\n  [#10873](https://github.com/rust-lang/rust-clippy/pull/10873)\n\n### Enhancements\n\n* [`invalid_regex`]: Now supports the new syntax introduced after regex v1.8.0\n  [#10682](https://github.com/rust-lang/rust-clippy/pull/10682)\n* [`semicolon_outside_block`]: Added [`semicolon-outside-block-ignore-multiline`] as a new config value.\n  [#10656](https://github.com/rust-lang/rust-clippy/pull/10656)\n* [`semicolon_inside_block`]: Added [`semicolon-inside-block-ignore-singleline`] as a new config value.\n  [#10656](https://github.com/rust-lang/rust-clippy/pull/10656)\n* [`unnecessary_box_returns`]: Added [`unnecessary-box-size`] as a new config value to set the maximum\n  size of `T` in `Box<T>` to be linted.\n  [#10651](https://github.com/rust-lang/rust-clippy/pull/10651)\n\n### Documentation Improvements\n\n* `cargo clippy --explain LINT` now shows possible configuration options for the explained lint\n  [#10751](https://github.com/rust-lang/rust-clippy/pull/10751)\n* New config values mentioned in this changelog will now be linked.\n  [#10889](https://github.com/rust-lang/rust-clippy/pull/10889)\n* Several sections of [Clippy's book] have been reworked\n  [#10652](https://github.com/rust-lang/rust-clippy/pull/10652)\n  [#10622](https://github.com/rust-lang/rust-clippy/pull/10622)\n\n[Clippy's book]: https://doc.rust-lang.org/clippy/\n\n## Rust 1.70\n\nReleased 2023-06-01\n\n[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-02-26T01%3A05%3A43Z..2023-04-11T13%3A27%3A30Z+base%3Amaster)\n\n### New Lints\n\n* [`large_futures`]\n  [#10414](https://github.com/rust-lang/rust-clippy/pull/10414)\n* [`missing_assert_message`]\n  [#10362](https://github.com/rust-lang/rust-clippy/pull/10362)\n* [`clear_with_drain`]\n  [#10528](https://github.com/rust-lang/rust-clippy/pull/10528)\n* [`redundant_async_block`]\n  [#10448](https://github.com/rust-lang/rust-clippy/pull/10448)\n* [`collection_is_never_read`]\n  [#10415](https://github.com/rust-lang/rust-clippy/pull/10415)\n* [`let_with_type_underscore`]\n  [#10467](https://github.com/rust-lang/rust-clippy/pull/10467)\n* [`tests_outside_test_module`]\n  [#10543](https://github.com/rust-lang/rust-clippy/pull/10543)\n* [`allow_attributes`]\n  [#10481](https://github.com/rust-lang/rust-clippy/pull/10481)\n* [`suspicious_doc_comments`]\n  [#10497](https://github.com/rust-lang/rust-clippy/pull/10497)\n* [`unnecessary_box_returns`]\n  [#9102](https://github.com/rust-lang/rust-clippy/pull/9102)\n* [`manual_main_separator_str`]\n  [#10483](https://github.com/rust-lang/rust-clippy/pull/10483)\n* [`unnecessary_struct_initialization`]\n  [#10489](https://github.com/rust-lang/rust-clippy/pull/10489)\n* [`manual_slice_size_calculation`]\n  [#10601](https://github.com/rust-lang/rust-clippy/pull/10601)\n* [`lines_filter_map_ok`]\n  [#10534](https://github.com/rust-lang/rust-clippy/pull/10534)\n\n### Moves and Deprecations\n\n* Moved [`let_underscore_untyped`] to `restriction`\n  [#10442](https://github.com/rust-lang/rust-clippy/pull/10442)\n\n### Enhancements\n\n* [`extra_unused_type_parameters`]: No longer lints on public items if `avoid-breaking-exported-api` is set\n  [#10536](https://github.com/rust-lang/rust-clippy/pull/10536)\n* [`len_without_is_empty`]: Now also detects `async` functions\n  [#10359](https://github.com/rust-lang/rust-clippy/pull/10359)\n* [`arithmetic_side_effects`]: Now correctly handles divisions and modulo expressions if the right-hand-side\n  is unknown\n  [#10585](https://github.com/rust-lang/rust-clippy/pull/10585)\n* [`nonminimal_bool`]: No longer ignores `#[allow]` attributes\n  [#10588](https://github.com/rust-lang/rust-clippy/pull/10588)\n* [`uninit_vec`], [`uninit_assumed_init`]: Now uses a better heuristic\n  [#10520](https://github.com/rust-lang/rust-clippy/pull/10520)\n* [`ifs_same_cond`]: Now also detects immutable method calls.\n  [#10350](https://github.com/rust-lang/rust-clippy/pull/10350)\n* [`arithmetic_side_effects`]: No longer lints on right or left shifts with constant integers, as the\n  compiler warns about them\n  [#10309](https://github.com/rust-lang/rust-clippy/pull/10309)\n* [`items_after_statements`]: `#[allow(items_after_statements)]` now works on items\n  [#10542](https://github.com/rust-lang/rust-clippy/pull/10542)\n* [`significant_drop_tightening`]: Was optimized\n  [#10533](https://github.com/rust-lang/rust-clippy/pull/10533)\n\n### False Positive Fixes\n\n* [`single_component_path_imports`]: No longer lints if the import is used relative to `self`\n  [#10566](https://github.com/rust-lang/rust-clippy/pull/10566)\n* [`derivable_impls`]: No longer suggests deriving `Default` on generics with implicit arguments\n  [#10399](https://github.com/rust-lang/rust-clippy/pull/10399)\n* [`let_unit_value`]: No longer lints if the expression contains an `await`\n  [#10439](https://github.com/rust-lang/rust-clippy/pull/10439)\n* [`double_must_use`]: Now ignores `async` functions\n  [#10589](https://github.com/rust-lang/rust-clippy/pull/10589)\n* [`manual_clamp`]: No longer lints in constant context\n  [#10479](https://github.com/rust-lang/rust-clippy/pull/10479)\n* [`almost_swapped`]: Now ignores external macros\n  [#10502](https://github.com/rust-lang/rust-clippy/pull/10502)\n* [`nonminimal_bool`]: Now ignores macros\n  [#10527](https://github.com/rust-lang/rust-clippy/pull/10527)\n* [`needless_return`]: No longer lints match statements with incompatible branches\n  [#10593](https://github.com/rust-lang/rust-clippy/pull/10593)\n* [`use_self`]: Do not suggest using `Self` in const generic parameters\n  [#10375](https://github.com/rust-lang/rust-clippy/pull/10375)\n* [`mem_replace_option_with_none`]: No longer lints on field expressions\n  [#10594](https://github.com/rust-lang/rust-clippy/pull/10594)\n* [`items_after_statements`]: No longer lints on items from macros\n  [#10542](https://github.com/rust-lang/rust-clippy/pull/10542)\n* [`print_literal`], [`write_literal`]: No longer lint strings coming from the `file!()` macro\n  [#10573](https://github.com/rust-lang/rust-clippy/pull/10573)\n* [`uninit_vec`], [`uninit_assumed_init`]: Now check the types inside arrays and tuples\n  [#10553](https://github.com/rust-lang/rust-clippy/pull/10553)\n* [`almost_swapped`]: No longer lints if a variable is assigned to itself\n  [#10499](https://github.com/rust-lang/rust-clippy/pull/10499)\n* [`missing_docs_in_private_items`]: No longer lints on public items\n  [#10324](https://github.com/rust-lang/rust-clippy/pull/10324)\n\n### Suggestion Fixes/Improvements\n\n* [`extra_unused_type_parameters`]: The suggestion is now machine applicable\n  [#10536](https://github.com/rust-lang/rust-clippy/pull/10536)\n* [`match_single_binding`]: Now adds a semicolon after the suggestion\n  [#10470](https://github.com/rust-lang/rust-clippy/pull/10470)\n* [`missing_const_for_fn`]: Now includes a note if the change could break compatibility\n  [#10618](https://github.com/rust-lang/rust-clippy/pull/10618)\n* [`cast_possible_truncation`]: Corrected suggestion for float and wildcard casts\n  [#10496](https://github.com/rust-lang/rust-clippy/pull/10496)\n* [`transmutes_expressible_as_ptr_casts`]: The suggestion now includes parentheses when they are required\n  [#10454](https://github.com/rust-lang/rust-clippy/pull/10454)\n\n### ICE Fixes\n\n* [`needless_borrow`]: No longer panics on ambiguous projections\n  [#10403](https://github.com/rust-lang/rust-clippy/pull/10403)\n* [`multiple_unsafe_ops_per_block`]: Fix ICE when calling a function-like object in an unsafe block\n  [#10405](https://github.com/rust-lang/rust-clippy/pull/10405)\n\n### Others\n\n* `clippy-driver` now searches parent directories for `clippy.toml` files\n  [#10592](https://github.com/rust-lang/rust-clippy/pull/10592)\n* Fixed a deserialization error for the `array-size-threshold` config value\n  [#10423](https://github.com/rust-lang/rust-clippy/pull/10423)\n\n## Rust 1.69\n\nReleased 2023-04-20\n\n[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-01-13T06%3A12%3A46Z..2023-02-25T23%3A48%3A10Z+base%3Amaster)\n\n### New Lints\n\n* [`no_mangle_with_rust_abi`]\n  [#10369](https://github.com/rust-lang/rust-clippy/pull/10369)\n* [`significant_drop_tightening`]\n  [#10163](https://github.com/rust-lang/rust-clippy/pull/10163)\n* [`suspicious_command_arg_space`]\n  [#10317](https://github.com/rust-lang/rust-clippy/pull/10317)\n* [`let_underscore_untyped`]\n  [#10356](https://github.com/rust-lang/rust-clippy/pull/10356)\n* [`question_mark_used`]\n  [#10342](https://github.com/rust-lang/rust-clippy/pull/10342)\n* [`extra_unused_type_parameters`]\n  [#10028](https://github.com/rust-lang/rust-clippy/pull/10028)\n* [`impl_trait_in_params`]\n  [10197](https://github.com/rust-lang/rust-clippy/pull/10197)\n* [`transmute_int_to_non_zero`]\n  [#10360](https://github.com/rust-lang/rust-clippy/pull/10360)\n* [`multiple_unsafe_ops_per_block`]\n  [#10206](https://github.com/rust-lang/rust-clippy/pull/10206)\n\n### Moves and Deprecations\n\n* Moved [`uninlined_format_args`] to `pedantic` (Now allow-by-default)\n  [#10265](https://github.com/rust-lang/rust-clippy/pull/10265)\n* Moved [`unchecked_duration_subtraction`] to `pedantic` (Now allow-by-default)\n  [#10194](https://github.com/rust-lang/rust-clippy/pull/10194)\n\n### Enhancements\n\n* [`arithmetic_side_effects`]: No longer lints if safe constant values are used.\n  [#10310](https://github.com/rust-lang/rust-clippy/pull/10310)\n* [`needless_lifetimes`]: Now works in local macros\n  [#10257](https://github.com/rust-lang/rust-clippy/pull/10257)\n* [`unused_io_amount`]: Now detects usages of `is_ok` and `is_err`\n  [#10225](https://github.com/rust-lang/rust-clippy/pull/10225)\n* [`missing_docs_in_private_items`]: Added new configuration `missing-docs-in-crate-items` to lint\n  on items visible within the current crate. For example, `pub(crate)` items.\n  [#10303](https://github.com/rust-lang/rust-clippy/pull/10303)\n* [`almost_swapped`]: Now detects almost swaps using `let` statements\n  [#10177](https://github.com/rust-lang/rust-clippy/pull/10177)\n* [`wildcard_enum_match_arm`]: Now lints missing private variants, for local enums\n  [#10250](https://github.com/rust-lang/rust-clippy/pull/10250)\n\n### False Positive Fixes\n\n* [`explicit_auto_deref`]: Now considers projections when determining if auto deref is applicable\n  [#10386](https://github.com/rust-lang/rust-clippy/pull/10386)\n* [`manual_let_else`]: Now considers side effects of branches before linting\n  [#10336](https://github.com/rust-lang/rust-clippy/pull/10336)\n* [`uninlined_format_args`]: No longer lints for arguments with generic parameters\n  [#10343](https://github.com/rust-lang/rust-clippy/pull/10343)\n* [`needless_lifetimes`]: No longer lints signatures in macros if the lifetime is a metavariable\n  [#10380](https://github.com/rust-lang/rust-clippy/pull/10380)\n* [`len_without_is_empty`]: No longer lints if `len` as a non-default signature\n  [#10255](https://github.com/rust-lang/rust-clippy/pull/10255)\n* [`unusual_byte_groupings`]: Relaxed the required restrictions for specific sizes to reduce false\n  positives\n  [#10353](https://github.com/rust-lang/rust-clippy/pull/10353)\n* [`manual_let_else`]: No longer lints `if-else` blocks if they can divergent\n  [#10332](https://github.com/rust-lang/rust-clippy/pull/10332)\n* [`expect_used`], [`unwrap_used`], [`dbg_macro`], [`print_stdout`], [`print_stderr`]: No longer lint\n  in test functions if `allow-expect-in-tests` is set\n  [#10391](https://github.com/rust-lang/rust-clippy/pull/10391)\n* [`unnecessary_safety_comment`]: No longer lints code inside macros\n  [#10106](https://github.com/rust-lang/rust-clippy/pull/10106)\n* [`never_loop`]: No longer lints statements following break statements for outer blocks.\n  [#10311](https://github.com/rust-lang/rust-clippy/pull/10311)\n\n### Suggestion Fixes/Improvements\n\n* [`box_default`]: The suggestion now includes the type for trait objects when needed\n  [#10382](https://github.com/rust-lang/rust-clippy/pull/10382)\n* [`cast_possible_truncation`]: Now suggests using `try_from` or allowing the lint\n  [#10038](https://github.com/rust-lang/rust-clippy/pull/10038)\n* [`invalid_regex`]: Regex errors for non-literals or regular strings containing escape sequences will\n  now show the complete error\n  [#10231](https://github.com/rust-lang/rust-clippy/pull/10231)\n* [`transmutes_expressible_as_ptr_casts`]: The suggestion now works if the base type is borrowed\n  [#10193](https://github.com/rust-lang/rust-clippy/pull/10193)\n* [`needless_return`]: Now removes all semicolons on the same line\n  [#10187](https://github.com/rust-lang/rust-clippy/pull/10187)\n* [`suspicious_to_owned`]: The suggestion now shows all options clearly\n  [#10295](https://github.com/rust-lang/rust-clippy/pull/10295)\n* [`bytes_nth`]: Now suggests the correct replacement based on the context\n  [#10361](https://github.com/rust-lang/rust-clippy/pull/10361)\n* [`bool_assert_comparison`]: The suggestion is now machine applicable\n  [#10218](https://github.com/rust-lang/rust-clippy/pull/10218)\n* [`cast_possible_truncation`]: Corrected the lint name in the help message\n  [#10330](https://github.com/rust-lang/rust-clippy/pull/10330)\n* [`needless_return`]: The suggestion now works on if sequences\n  [#10345](https://github.com/rust-lang/rust-clippy/pull/10345)\n* [`needless_lifetimes`]: The suggestion is now machine applicable\n  [#10222](https://github.com/rust-lang/rust-clippy/pull/10222)\n* [`map_entry`]: The suggestion no longer expands macros\n  [#10346](https://github.com/rust-lang/rust-clippy/pull/10346)\n\n### ICE Fixes\n\n* [`needless_pass_by_value`]: Fixed an ICE caused by how late bounds were handled\n  [#10328](https://github.com/rust-lang/rust-clippy/pull/10328)\n* [`needless_borrow`]: No longer panics on ambiguous projections\n  [#10403](https://github.com/rust-lang/rust-clippy/pull/10403)\n\n### Documentation Improvements\n\n* All configurations are now documented in the Clippy Book\n  [#10199](https://github.com/rust-lang/rust-clippy/pull/10199)\n\n## Rust 1.68\n\nReleased 2023-03-09\n\n[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-12-01T20%3A40%3A04Z..2023-01-12T18%3A58%3A59Z+base%3Amaster)\n\n### New Lints\n\n* [`permissions_set_readonly_false`]\n  [#10063](https://github.com/rust-lang/rust-clippy/pull/10063)\n* [`almost_complete_range`]\n  [#10043](https://github.com/rust-lang/rust-clippy/pull/10043)\n* [`size_of_ref`]\n  [#10098](https://github.com/rust-lang/rust-clippy/pull/10098)\n* [`semicolon_outside_block`]\n  [#9826](https://github.com/rust-lang/rust-clippy/pull/9826)\n* [`semicolon_inside_block`]\n  [#9826](https://github.com/rust-lang/rust-clippy/pull/9826)\n* [`transmute_null_to_fn`]\n  [#10099](https://github.com/rust-lang/rust-clippy/pull/10099)\n* [`fn_null_check`]\n  [#10099](https://github.com/rust-lang/rust-clippy/pull/10099)\n\n### Moves and Deprecations\n\n* Moved [`manual_clamp`] to `nursery` (Now allow-by-default)\n  [#10101](https://github.com/rust-lang/rust-clippy/pull/10101)\n* Moved [`mutex_atomic`] to `restriction`\n  [#10115](https://github.com/rust-lang/rust-clippy/pull/10115)\n* Renamed `derive_hash_xor_eq` to [`derived_hash_with_manual_eq`]\n  [#10184](https://github.com/rust-lang/rust-clippy/pull/10184)\n\n### Enhancements\n\n* [`collapsible_str_replace`]: Now takes MSRV into consideration. The minimal version is 1.58\n  [#10047](https://github.com/rust-lang/rust-clippy/pull/10047)\n* [`unused_self`]: No longer lints, if the method body contains a `todo!()` call\n  [#10166](https://github.com/rust-lang/rust-clippy/pull/10166)\n* [`derivable_impls`]: Now suggests deriving `Default` for enums with default unit variants\n  [#10161](https://github.com/rust-lang/rust-clippy/pull/10161)\n* [`arithmetic_side_effects`]: Added two new config values\n  `arithmetic-side-effects-allowed-binary` and `arithmetic-side-effects-allowed-unary`\n  to allow operation on user types\n  [#9840](https://github.com/rust-lang/rust-clippy/pull/9840)\n* [`large_const_arrays`], [`large_stack_arrays`]: avoid integer overflow when calculating\n  total array size\n  [#10103](https://github.com/rust-lang/rust-clippy/pull/10103)\n* [`indexing_slicing`]: add new config `suppress-restriction-lint-in-const` to enable\n  restriction lints, even if the suggestion might not be applicable\n  [#9920](https://github.com/rust-lang/rust-clippy/pull/9920)\n* [`needless_borrow`], [`redundant_clone`]: Now track references better and detect more cases\n  [#9701](https://github.com/rust-lang/rust-clippy/pull/9701)\n* [`derived_hash_with_manual_eq`]: Now allows `#[derive(PartialEq)]` with custom `Hash`\n  implementations\n  [#10184](https://github.com/rust-lang/rust-clippy/pull/10184)\n* [`manual_is_ascii_check`]: Now detects ranges with `.contains()` calls\n  [#10053](https://github.com/rust-lang/rust-clippy/pull/10053)\n* [`transmuting_null`]: Now detects `const` pointers to all types\n  [#10099](https://github.com/rust-lang/rust-clippy/pull/10099)\n* [`needless_return`]: Now detects more cases for returns of owned values\n  [#10110](https://github.com/rust-lang/rust-clippy/pull/10110)\n\n### False Positive Fixes\n\n* [`field_reassign_with_default`]: No longer lints cases, where values are initializes from\n  closures capturing struct values\n  [#10143](https://github.com/rust-lang/rust-clippy/pull/10143)\n* [`seek_to_start_instead_of_rewind`]: No longer lints, if the return of `seek` is used.\n  [#10096](https://github.com/rust-lang/rust-clippy/pull/10096)\n* [`manual_filter`]: Now ignores if expressions where the else branch has side effects or\n  doesn't return `None`\n  [#10091](https://github.com/rust-lang/rust-clippy/pull/10091)\n* [`implicit_clone`]: No longer lints if the type doesn't implement clone\n  [#10022](https://github.com/rust-lang/rust-clippy/pull/10022)\n* [`match_wildcard_for_single_variants`]: No longer lints on wildcards with a guard\n  [#10056](https://github.com/rust-lang/rust-clippy/pull/10056)\n* [`drop_ref`]: No longer lints idiomatic expression in `match` arms\n  [#10142](https://github.com/rust-lang/rust-clippy/pull/10142)\n* [`arithmetic_side_effects`]: No longer lints on corner cases with negative number literals\n  [#9867](https://github.com/rust-lang/rust-clippy/pull/9867)\n* [`string_lit_as_bytes`]: No longer lints in scrutinies of `match` statements\n  [#10012](https://github.com/rust-lang/rust-clippy/pull/10012)\n* [`manual_assert`]: No longer lints in `else if` statements\n  [#10013](https://github.com/rust-lang/rust-clippy/pull/10013)\n* [`needless_return`]: don't lint when using `do yeet`\n  [#10109](https://github.com/rust-lang/rust-clippy/pull/10109)\n* All lints: No longer lint in enum discriminant values when the suggestion won't work in a\n  const context\n  [#10008](https://github.com/rust-lang/rust-clippy/pull/10008)\n* [`single_element_loop`]: No longer lints, if the loop contains a `break` or `continue`\n  [#10162](https://github.com/rust-lang/rust-clippy/pull/10162)\n* [`uninlined_format_args`]: No longer suggests inlining arguments in `assert!` and\n  `debug_assert!` macros before 2021 edition\n  [#10055](https://github.com/rust-lang/rust-clippy/pull/10055)\n* [`explicit_counter_loop`]: No longer ignores counter changes after `continue` expressions\n  [#10094](https://github.com/rust-lang/rust-clippy/pull/10094)\n* [`from_over_into`]: No longer lints on opaque types\n  [#9982](https://github.com/rust-lang/rust-clippy/pull/9982)\n* [`expl_impl_clone_on_copy`]: No longer lints on `#[repr(packed)]` structs with generic\n  parameters\n  [#10189](https://github.com/rust-lang/rust-clippy/pull/10189)\n\n### Suggestion Fixes/Improvements\n\n* [`zero_ptr`]: Now suggests `core::` paths for `no_std` crates\n  [#10023](https://github.com/rust-lang/rust-clippy/pull/10023)\n* [`useless_conversion`]: Now suggests removing calls to `into_iter()` on an expression\n  implementing `Iterator`\n  [#10020](https://github.com/rust-lang/rust-clippy/pull/10020)\n* [`box_default`]: The suggestion now uses short paths\n  [#10153](https://github.com/rust-lang/rust-clippy/pull/10153)\n* [`default_trait_access`], [`clone_on_copy`]: The suggestion now uses short paths\n  [#10160](https://github.com/rust-lang/rust-clippy/pull/10160)\n* [`comparison_to_empty`]: The suggestion now removes unused deref operations\n  [#9962](https://github.com/rust-lang/rust-clippy/pull/9962)\n* [`manual_let_else`]: Suggestions for or-patterns now include required brackets.\n  [#9966](https://github.com/rust-lang/rust-clippy/pull/9966)\n* [`match_single_binding`]: suggestion no longer introduces unneeded semicolons\n  [#10060](https://github.com/rust-lang/rust-clippy/pull/10060)\n* [`case_sensitive_file_extension_comparisons`]: Now displays a suggestion with `Path`\n  [#10107](https://github.com/rust-lang/rust-clippy/pull/10107)\n* [`empty_structs_with_brackets`]: The suggestion is no longer machine applicable, to avoid\n  errors when accessing struct fields\n  [#10141](https://github.com/rust-lang/rust-clippy/pull/10141)\n* [`identity_op`]: Removes borrows in the suggestion when needed\n  [#10004](https://github.com/rust-lang/rust-clippy/pull/10004)\n* [`suboptimal_flops`]: The suggestion now includes parentheses when required\n  [#10113](https://github.com/rust-lang/rust-clippy/pull/10113)\n* [`iter_kv_map`]: Now handles `mut` and reference annotations in the suggestion\n  [#10159](https://github.com/rust-lang/rust-clippy/pull/10159)\n* [`redundant_static_lifetimes`]: The suggestion no longer removes `mut` from references\n  [#10006](https://github.com/rust-lang/rust-clippy/pull/10006)\n\n### ICE Fixes\n\n* [`new_ret_no_self`]: Now avoids a stack overflow for `impl Trait` types\n  [#10086](https://github.com/rust-lang/rust-clippy/pull/10086)\n* [`unnecessary_to_owned`]: Now handles compiler generated notes better\n  [#10027](https://github.com/rust-lang/rust-clippy/pull/10027)\n\n### Others\n\n* `SYSROOT` and `--sysroot` can now be set at the same time\n  [#10149](https://github.com/rust-lang/rust-clippy/pull/10149)\n* Fix error when providing an `array-size-threshold` in `clippy.toml`\n  [#10423](https://github.com/rust-lang/rust-clippy/pull/10423)\n\n## Rust 1.67\n\nReleased 2023-01-26\n\n[View all 104 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-10-23T13%3A35%3A19Z..2022-12-01T13%3A34%3A39Z+base%3Amaster)\n\n### New Lints\n\n* [`seek_from_current`]\n  [#9681](https://github.com/rust-lang/rust-clippy/pull/9681)\n* [`from_raw_with_void_ptr`]\n  [#9690](https://github.com/rust-lang/rust-clippy/pull/9690)\n* [`misnamed_getters`]\n  [#9770](https://github.com/rust-lang/rust-clippy/pull/9770)\n* [`seek_to_start_instead_of_rewind`]\n  [#9667](https://github.com/rust-lang/rust-clippy/pull/9667)\n* [`suspicious_xor_used_as_pow`]\n  [#9506](https://github.com/rust-lang/rust-clippy/pull/9506)\n* [`unnecessary_safety_doc`]\n  [#9822](https://github.com/rust-lang/rust-clippy/pull/9822)\n* [`unchecked_duration_subtraction`]\n  [#9570](https://github.com/rust-lang/rust-clippy/pull/9570)\n* [`manual_is_ascii_check`]\n  [#9765](https://github.com/rust-lang/rust-clippy/pull/9765)\n* [`unnecessary_safety_comment`]\n  [#9851](https://github.com/rust-lang/rust-clippy/pull/9851)\n* [`let_underscore_future`]\n  [#9760](https://github.com/rust-lang/rust-clippy/pull/9760)\n* [`manual_let_else`]\n  [#8437](https://github.com/rust-lang/rust-clippy/pull/8437)\n\n### Moves and Deprecations\n\n* Moved [`needless_collect`] to `nursery` (Now allow-by-default)\n  [#9705](https://github.com/rust-lang/rust-clippy/pull/9705)\n* Moved [`or_fun_call`] to `nursery` (Now allow-by-default)\n  [#9829](https://github.com/rust-lang/rust-clippy/pull/9829)\n* Uplifted [`let_underscore_lock`] into rustc\n  [#9697](https://github.com/rust-lang/rust-clippy/pull/9697)\n* Uplifted [`let_underscore_drop`] into rustc\n  [#9697](https://github.com/rust-lang/rust-clippy/pull/9697)\n* Moved [`bool_to_int_with_if`] to `pedantic` (Now allow-by-default)\n  [#9830](https://github.com/rust-lang/rust-clippy/pull/9830)\n* Move `index_refutable_slice` to `pedantic` (Now warn-by-default)\n  [#9975](https://github.com/rust-lang/rust-clippy/pull/9975)\n* Moved [`manual_clamp`] to `nursery` (Now allow-by-default)\n  [#10101](https://github.com/rust-lang/rust-clippy/pull/10101)\n\n### Enhancements\n\n* The scope of `#![clippy::msrv]` is now tracked correctly\n  [#9924](https://github.com/rust-lang/rust-clippy/pull/9924)\n* `#[clippy::msrv]` can now be used as an outer attribute\n  [#9860](https://github.com/rust-lang/rust-clippy/pull/9860)\n* Clippy will now avoid Cargo's cache, if `Cargo.toml` or `clippy.toml` have changed\n  [#9707](https://github.com/rust-lang/rust-clippy/pull/9707)\n* [`uninlined_format_args`]: Added a new config `allow-mixed-uninlined-format-args` to allow the\n  lint, if only some arguments can be inlined\n  [#9865](https://github.com/rust-lang/rust-clippy/pull/9865)\n* [`needless_lifetimes`]: Now provides suggests for individual lifetimes\n  [#9743](https://github.com/rust-lang/rust-clippy/pull/9743)\n* [`needless_collect`]: Now detects needless `is_empty` and `contains` calls\n  [#8744](https://github.com/rust-lang/rust-clippy/pull/8744)\n* [`blanket_clippy_restriction_lints`]: Now lints, if `clippy::restriction` is enabled via the\n  command line arguments\n  [#9755](https://github.com/rust-lang/rust-clippy/pull/9755)\n* [`mutable_key_type`]: Now has the `ignore-interior-mutability` configuration, to add types which\n  should be ignored by the lint\n  [#9692](https://github.com/rust-lang/rust-clippy/pull/9692)\n* [`uninlined_format_args`]: Now works for multiline `format!` expressions\n  [#9945](https://github.com/rust-lang/rust-clippy/pull/9945)\n* [`cognitive_complexity`]: Now works for async functions\n  [#9828](https://github.com/rust-lang/rust-clippy/pull/9828)\n  [#9836](https://github.com/rust-lang/rust-clippy/pull/9836)\n* [`vec_box`]: Now avoids an off-by-one error when using the `vec-box-size-threshold` configuration\n  [#9848](https://github.com/rust-lang/rust-clippy/pull/9848)\n* [`never_loop`]: Now correctly handles breaks in nested labeled blocks\n  [#9858](https://github.com/rust-lang/rust-clippy/pull/9858)\n  [#9837](https://github.com/rust-lang/rust-clippy/pull/9837)\n* [`disallowed_methods`], [`disallowed_types`], [`disallowed_macros`]: Now correctly resolve\n  paths, if a crate is used multiple times with different versions\n  [#9800](https://github.com/rust-lang/rust-clippy/pull/9800)\n* [`disallowed_methods`]: Can now be used for local methods\n  [#9800](https://github.com/rust-lang/rust-clippy/pull/9800)\n* [`print_stdout`], [`print_stderr`]: Can now be enabled in test with the `allow-print-in-tests`\n  config value\n  [#9797](https://github.com/rust-lang/rust-clippy/pull/9797)\n* [`from_raw_with_void_ptr`]: Now works for `Rc`, `Arc`, `alloc::rc::Weak` and\n  `alloc::sync::Weak` types.\n  [#9700](https://github.com/rust-lang/rust-clippy/pull/9700)\n* [`needless_borrowed_reference`]: Now works for struct and tuple patterns with wildcards\n  [#9855](https://github.com/rust-lang/rust-clippy/pull/9855)\n* [`or_fun_call`]: Now supports `map_or` methods\n  [#9689](https://github.com/rust-lang/rust-clippy/pull/9689)\n* [`unwrap_used`], [`expect_used`]: No longer lints in test code\n  [#9686](https://github.com/rust-lang/rust-clippy/pull/9686)\n* [`fn_params_excessive_bools`]: Is now emitted with the lint level at the linted function\n  [#9698](https://github.com/rust-lang/rust-clippy/pull/9698)\n\n### False Positive Fixes\n\n* [`new_ret_no_self`]: No longer lints when `impl Trait<Self>` is returned\n  [#9733](https://github.com/rust-lang/rust-clippy/pull/9733)\n* [`unnecessary_lazy_evaluations`]: No longer lints, if the type has a significant drop\n  [#9750](https://github.com/rust-lang/rust-clippy/pull/9750)\n* [`option_if_let_else`]: No longer lints, if any arm has guard\n  [#9747](https://github.com/rust-lang/rust-clippy/pull/9747)\n* [`explicit_auto_deref`]: No longer lints, if the target type is a projection with generic\n  arguments\n  [#9813](https://github.com/rust-lang/rust-clippy/pull/9813)\n* [`unnecessary_to_owned`]: No longer lints, if the suggestion effects types\n  [#9796](https://github.com/rust-lang/rust-clippy/pull/9796)\n* [`needless_borrow`]: No longer lints, if the suggestion is affected by `Deref`\n  [#9674](https://github.com/rust-lang/rust-clippy/pull/9674)\n* [`unused_unit`]: No longer lints, if lifetimes are bound to the return type\n  [#9849](https://github.com/rust-lang/rust-clippy/pull/9849)\n* [`mut_mut`]: No longer lints cases with unsized mutable references\n  [#9835](https://github.com/rust-lang/rust-clippy/pull/9835)\n* [`bool_to_int_with_if`]: No longer lints in const context\n  [#9738](https://github.com/rust-lang/rust-clippy/pull/9738)\n* [`use_self`]: No longer lints in macros\n  [#9704](https://github.com/rust-lang/rust-clippy/pull/9704)\n* [`unnecessary_operation`]: No longer lints, if multiple macros are involved\n  [#9981](https://github.com/rust-lang/rust-clippy/pull/9981)\n* [`allow_attributes_without_reason`]: No longer lints inside external macros\n  [#9630](https://github.com/rust-lang/rust-clippy/pull/9630)\n* [`question_mark`]: No longer lints for `if let Err()` with an `else` branch\n  [#9722](https://github.com/rust-lang/rust-clippy/pull/9722)\n* [`unnecessary_cast`]: No longer lints if the identifier and cast originate from different macros\n  [#9980](https://github.com/rust-lang/rust-clippy/pull/9980)\n* [`arithmetic_side_effects`]: Now detects operations with associated constants\n  [#9592](https://github.com/rust-lang/rust-clippy/pull/9592)\n* [`explicit_auto_deref`]: No longer lints, if the initial value is not a reference or reference\n  receiver\n  [#9997](https://github.com/rust-lang/rust-clippy/pull/9997)\n* [`module_name_repetitions`], [`single_component_path_imports`]: Now handle `#[allow]`\n  attributes correctly\n  [#9879](https://github.com/rust-lang/rust-clippy/pull/9879)\n* [`bool_to_int_with_if`]: No longer lints `if let` statements\n  [#9714](https://github.com/rust-lang/rust-clippy/pull/9714)\n* [`needless_borrow`]: No longer lints, `if`-`else`-statements that require the borrow\n  [#9791](https://github.com/rust-lang/rust-clippy/pull/9791)\n* [`needless_borrow`]: No longer lints borrows, if moves were illegal\n  [#9711](https://github.com/rust-lang/rust-clippy/pull/9711)\n* [`manual_swap`]: No longer lints in const context\n  [#9871](https://github.com/rust-lang/rust-clippy/pull/9871)\n\n### Suggestion Fixes/Improvements\n\n* [`missing_safety_doc`], [`missing_errors_doc`], [`missing_panics_doc`]: No longer show the\n  entire item in the lint emission.\n  [#9772](https://github.com/rust-lang/rust-clippy/pull/9772)\n* [`needless_lifetimes`]: Only suggests `'_` when it's applicable\n  [#9743](https://github.com/rust-lang/rust-clippy/pull/9743)\n* [`use_self`]: Now suggests full paths correctly\n  [#9726](https://github.com/rust-lang/rust-clippy/pull/9726)\n* [`redundant_closure_call`]: Now correctly deals with macros during suggestion creation\n  [#9987](https://github.com/rust-lang/rust-clippy/pull/9987)\n* [`unnecessary_cast`]: Suggestions now correctly deal with references\n  [#9996](https://github.com/rust-lang/rust-clippy/pull/9996)\n* [`unnecessary_join`]: Suggestions now correctly use [turbofish] operators\n  [#9779](https://github.com/rust-lang/rust-clippy/pull/9779)\n* [`equatable_if_let`]: Can now suggest `matches!` replacements\n  [#9368](https://github.com/rust-lang/rust-clippy/pull/9368)\n* [`string_extend_chars`]: Suggestions now correctly work for `str` slices\n  [#9741](https://github.com/rust-lang/rust-clippy/pull/9741)\n* [`redundant_closure_for_method_calls`]: Suggestions now include angle brackets and generic\n  arguments if needed\n  [#9745](https://github.com/rust-lang/rust-clippy/pull/9745)\n* [`manual_let_else`]: Suggestions no longer expand macro calls\n  [#9943](https://github.com/rust-lang/rust-clippy/pull/9943)\n* [`infallible_destructuring_match`]: Suggestions now preserve references\n  [#9850](https://github.com/rust-lang/rust-clippy/pull/9850)\n* [`result_large_err`]: The error now shows the largest enum variant\n  [#9662](https://github.com/rust-lang/rust-clippy/pull/9662)\n* [`needless_return`]: Suggestions are now formatted better\n  [#9967](https://github.com/rust-lang/rust-clippy/pull/9967)\n* [`unused_rounding`]: The suggestion now preserves the original float literal notation\n  [#9870](https://github.com/rust-lang/rust-clippy/pull/9870)\n\n[turbofish]: https://turbo.fish/::%3CClippy%3E\n\n### ICE Fixes\n\n* [`result_large_err`]: Fixed ICE for empty enums\n  [#10007](https://github.com/rust-lang/rust-clippy/pull/10007)\n* [`redundant_allocation`]: Fixed ICE for types with bounded variables\n  [#9773](https://github.com/rust-lang/rust-clippy/pull/9773)\n* [`unused_rounding`]: Fixed ICE, if `_` was used as a separator\n  [#10001](https://github.com/rust-lang/rust-clippy/pull/10001)\n\n## Rust 1.66\n\nReleased 2022-12-15\n\n[View all 116 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-09-09T17%3A32%3A39Z..2022-10-23T11%3A27%3A24Z+base%3Amaster)\n\n### New Lints\n\n* [`manual_clamp`]\n  [#9484](https://github.com/rust-lang/rust-clippy/pull/9484)\n* [`missing_trait_methods`]\n  [#9670](https://github.com/rust-lang/rust-clippy/pull/9670)\n* [`unused_format_specs`]\n  [#9637](https://github.com/rust-lang/rust-clippy/pull/9637)\n* [`iter_kv_map`]\n  [#9409](https://github.com/rust-lang/rust-clippy/pull/9409)\n* [`manual_filter`]\n  [#9451](https://github.com/rust-lang/rust-clippy/pull/9451)\n* [`box_default`]\n  [#9511](https://github.com/rust-lang/rust-clippy/pull/9511)\n* [`implicit_saturating_add`]\n  [#9549](https://github.com/rust-lang/rust-clippy/pull/9549)\n* [`as_ptr_cast_mut`]\n  [#9572](https://github.com/rust-lang/rust-clippy/pull/9572)\n* [`disallowed_macros`]\n  [#9495](https://github.com/rust-lang/rust-clippy/pull/9495)\n* [`partial_pub_fields`]\n  [#9658](https://github.com/rust-lang/rust-clippy/pull/9658)\n* [`uninlined_format_args`]\n  [#9233](https://github.com/rust-lang/rust-clippy/pull/9233)\n* [`cast_nan_to_int`]\n  [#9617](https://github.com/rust-lang/rust-clippy/pull/9617)\n\n### Moves and Deprecations\n\n* `positional_named_format_parameters` was uplifted to rustc under the new name\n  `named_arguments_used_positionally`\n  [#8518](https://github.com/rust-lang/rust-clippy/pull/8518)\n* Moved [`implicit_saturating_sub`] to `style` (Now warn-by-default)\n  [#9584](https://github.com/rust-lang/rust-clippy/pull/9584)\n* Moved `derive_partial_eq_without_eq` to `nursery` (now allow-by-default)\n  [#9536](https://github.com/rust-lang/rust-clippy/pull/9536)\n\n### Enhancements\n\n* [`nonstandard_macro_braces`]: Now includes `matches!()` in the default lint config\n  [#9471](https://github.com/rust-lang/rust-clippy/pull/9471)\n* [`suboptimal_flops`]: Now supports multiplication and subtraction operations\n  [#9581](https://github.com/rust-lang/rust-clippy/pull/9581)\n* [`arithmetic_side_effects`]: Now detects cases with literals behind references\n  [#9587](https://github.com/rust-lang/rust-clippy/pull/9587)\n* [`upper_case_acronyms`]: Now also checks enum names\n  [#9580](https://github.com/rust-lang/rust-clippy/pull/9580)\n* [`needless_borrowed_reference`]: Now lints nested patterns\n  [#9573](https://github.com/rust-lang/rust-clippy/pull/9573)\n* [`unnecessary_cast`]: Now works for non-trivial non-literal expressions\n  [#9576](https://github.com/rust-lang/rust-clippy/pull/9576)\n* [`arithmetic_side_effects`]: Now detects operations with custom types\n  [#9559](https://github.com/rust-lang/rust-clippy/pull/9559)\n* [`disallowed_methods`], [`disallowed_types`]: Not correctly lints types, functions and macros\n  with the same path\n  [#9495](https://github.com/rust-lang/rust-clippy/pull/9495)\n* [`self_named_module_files`], [`mod_module_files`]: Now take remapped path prefixes into account\n  [#9475](https://github.com/rust-lang/rust-clippy/pull/9475)\n* [`bool_to_int_with_if`]: Now detects the inverse if case\n  [#9476](https://github.com/rust-lang/rust-clippy/pull/9476)\n\n### False Positive Fixes\n\n* [`arithmetic_side_effects`]: Now allows operations that can't overflow\n  [#9474](https://github.com/rust-lang/rust-clippy/pull/9474)\n* [`unnecessary_lazy_evaluations`]: No longer lints in external macros\n  [#9486](https://github.com/rust-lang/rust-clippy/pull/9486)\n* [`needless_borrow`], [`explicit_auto_deref`]: No longer lint on unions that require the reference\n  [#9490](https://github.com/rust-lang/rust-clippy/pull/9490)\n* [`almost_complete_letter_range`]: No longer lints in external macros\n  [#9467](https://github.com/rust-lang/rust-clippy/pull/9467)\n* [`drop_copy`]: No longer lints on idiomatic cases in match arms\n  [#9491](https://github.com/rust-lang/rust-clippy/pull/9491)\n* [`question_mark`]: No longer lints in const context\n  [#9487](https://github.com/rust-lang/rust-clippy/pull/9487)\n* [`collapsible_if`]: Suggestion now work in macros\n  [#9410](https://github.com/rust-lang/rust-clippy/pull/9410)\n* [`std_instead_of_core`]: No longer triggers on unstable modules\n  [#9545](https://github.com/rust-lang/rust-clippy/pull/9545)\n* [`unused_peekable`]: No longer lints, if the peak is done in a closure or function\n  [#9465](https://github.com/rust-lang/rust-clippy/pull/9465)\n* [`useless_attribute`]: No longer lints on `#[allow]` attributes for [`unsafe_removed_from_name`]\n  [#9593](https://github.com/rust-lang/rust-clippy/pull/9593)\n* [`unnecessary_lazy_evaluations`]: No longer suggest switching to early evaluation when type has\n  custom `Drop` implementation\n  [#9551](https://github.com/rust-lang/rust-clippy/pull/9551)\n* [`unnecessary_cast`]: No longer lints on negative hexadecimal literals when cast as floats\n  [#9609](https://github.com/rust-lang/rust-clippy/pull/9609)\n* [`use_self`]: No longer lints in proc macros\n  [#9454](https://github.com/rust-lang/rust-clippy/pull/9454)\n* [`never_loop`]: Now takes `let ... else` statements into consideration.\n  [#9496](https://github.com/rust-lang/rust-clippy/pull/9496)\n* [`default_numeric_fallback`]: Now ignores constants\n  [#9636](https://github.com/rust-lang/rust-clippy/pull/9636)\n* [`uninit_vec`]: No longer lints `Vec::set_len(0)`\n  [#9519](https://github.com/rust-lang/rust-clippy/pull/9519)\n* [`arithmetic_side_effects`]: Now ignores references to integer types\n  [#9507](https://github.com/rust-lang/rust-clippy/pull/9507)\n* [`large_stack_arrays`]: No longer lints inside static items\n  [#9466](https://github.com/rust-lang/rust-clippy/pull/9466)\n* [`ref_option_ref`]: No longer lints if the inner reference is mutable\n  [#9684](https://github.com/rust-lang/rust-clippy/pull/9684)\n* [`ptr_arg`]: No longer lints if the argument is used as an incomplete trait object\n  [#9645](https://github.com/rust-lang/rust-clippy/pull/9645)\n* [`should_implement_trait`]: Now also works for `default` methods\n  [#9546](https://github.com/rust-lang/rust-clippy/pull/9546)\n\n### Suggestion Fixes/Improvements\n\n* [`derivable_impls`]: The suggestion is now machine applicable\n  [#9429](https://github.com/rust-lang/rust-clippy/pull/9429)\n* [`match_single_binding`]: The suggestion now handles scrutinies with side effects better\n  [#9601](https://github.com/rust-lang/rust-clippy/pull/9601)\n* [`zero_prefixed_literal`]: Only suggests using octal numbers, if this is possible\n  [#9652](https://github.com/rust-lang/rust-clippy/pull/9652)\n* [`rc_buffer`]: The suggestion is no longer machine applicable to avoid semantic changes\n  [#9633](https://github.com/rust-lang/rust-clippy/pull/9633)\n* [`print_literal`], [`write_literal`], [`uninlined_format_args`]: The suggestion now ignores\n  comments after the macro call.\n  [#9586](https://github.com/rust-lang/rust-clippy/pull/9586)\n* [`expect_fun_call`]:Improved the suggestion for `format!` calls with captured variables\n  [#9586](https://github.com/rust-lang/rust-clippy/pull/9586)\n* [`nonstandard_macro_braces`]: The suggestion is now machine applicable and will no longer\n  replace brackets inside the macro argument.\n  [#9499](https://github.com/rust-lang/rust-clippy/pull/9499)\n* [`from_over_into`]: The suggestion is now a machine applicable and contains explanations\n  [#9649](https://github.com/rust-lang/rust-clippy/pull/9649)\n* [`needless_return`]: The automatic suggestion now removes all required semicolons\n  [#9497](https://github.com/rust-lang/rust-clippy/pull/9497)\n* [`to_string_in_format_args`]: The suggestion now keeps parenthesis around values\n  [#9590](https://github.com/rust-lang/rust-clippy/pull/9590)\n* [`manual_assert`]: The suggestion now preserves comments\n  [#9479](https://github.com/rust-lang/rust-clippy/pull/9479)\n* [`redundant_allocation`]: The suggestion applicability is now marked `MaybeIncorrect` to\n  avoid semantic changes\n  [#9634](https://github.com/rust-lang/rust-clippy/pull/9634)\n* [`assertions_on_result_states`]: The suggestion has been corrected, for cases where the\n  `assert!` is not in a statement.\n  [#9453](https://github.com/rust-lang/rust-clippy/pull/9453)\n* [`nonminimal_bool`]: The suggestion no longer expands macros\n  [#9457](https://github.com/rust-lang/rust-clippy/pull/9457)\n* [`collapsible_match`]: Now specifies field names, when a struct is destructed\n  [#9685](https://github.com/rust-lang/rust-clippy/pull/9685)\n* [`unnecessary_cast`]: The suggestion now adds parenthesis for negative numbers\n  [#9577](https://github.com/rust-lang/rust-clippy/pull/9577)\n* [`redundant_closure`]: The suggestion now works for `impl FnMut` arguments\n  [#9556](https://github.com/rust-lang/rust-clippy/pull/9556)\n\n### ICE Fixes\n\n* [`unnecessary_to_owned`]: Avoid ICEs in favor of false negatives if information is missing\n  [#9505](https://github.com/rust-lang/rust-clippy/pull/9505)\n  [#10027](https://github.com/rust-lang/rust-clippy/pull/10027)\n* [`manual_range_contains`]: No longer ICEs on values behind references\n  [#9627](https://github.com/rust-lang/rust-clippy/pull/9627)\n* [`needless_pass_by_value`]: No longer ICEs on unsized `dyn Fn` arguments\n  [#9531](https://github.com/rust-lang/rust-clippy/pull/9531)\n* `*_interior_mutable_const` lints: no longer ICE on const unions containing `!Freeze` types\n  [#9539](https://github.com/rust-lang/rust-clippy/pull/9539)\n\n### Others\n\n* Released `rustc_tools_util` for version information on `Crates.io`. (Further adjustments will\n  not be published as part of this changelog)\n\n## Rust 1.65\n\nReleased 2022-11-03\n\n[View all 86 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-07-29T01%3A09%3A31Z..2022-09-09T00%3A01%3A54Z+base%3Amaster)\n\n### Important Changes\n\n* Clippy now has an `--explain <LINT>` command to show the lint description in the console\n  [#8952](https://github.com/rust-lang/rust-clippy/pull/8952)\n\n### New Lints\n\n* [`unused_peekable`]\n  [#9258](https://github.com/rust-lang/rust-clippy/pull/9258)\n* [`collapsible_str_replace`]\n  [#9269](https://github.com/rust-lang/rust-clippy/pull/9269)\n* [`manual_string_new`]\n  [#9295](https://github.com/rust-lang/rust-clippy/pull/9295)\n* [`iter_on_empty_collections`]\n  [#9187](https://github.com/rust-lang/rust-clippy/pull/9187)\n* [`iter_on_single_items`]\n  [#9187](https://github.com/rust-lang/rust-clippy/pull/9187)\n* [`bool_to_int_with_if`]\n  [#9412](https://github.com/rust-lang/rust-clippy/pull/9412)\n* [`multi_assignments`]\n  [#9379](https://github.com/rust-lang/rust-clippy/pull/9379)\n* [`result_large_err`]\n  [#9373](https://github.com/rust-lang/rust-clippy/pull/9373)\n* [`partialeq_to_none`]\n  [#9288](https://github.com/rust-lang/rust-clippy/pull/9288)\n* [`suspicious_to_owned`]\n  [#8984](https://github.com/rust-lang/rust-clippy/pull/8984)\n* [`cast_slice_from_raw_parts`]\n  [#9247](https://github.com/rust-lang/rust-clippy/pull/9247)\n* [`manual_instant_elapsed`]\n  [#9264](https://github.com/rust-lang/rust-clippy/pull/9264)\n\n### Moves and Deprecations\n\n* Moved [`significant_drop_in_scrutinee`] to `nursery` (now allow-by-default)\n  [#9302](https://github.com/rust-lang/rust-clippy/pull/9302)\n* Rename `logic_bug` to [`overly_complex_bool_expr`]\n  [#9306](https://github.com/rust-lang/rust-clippy/pull/9306)\n* Rename `arithmetic` to [`arithmetic_side_effects`]\n  [#9443](https://github.com/rust-lang/rust-clippy/pull/9443)\n* Moved [`only_used_in_recursion`] to complexity (now warn-by-default)\n  [#8804](https://github.com/rust-lang/rust-clippy/pull/8804)\n* Moved [`assertions_on_result_states`] to restriction (now allow-by-default)\n  [#9273](https://github.com/rust-lang/rust-clippy/pull/9273)\n* Renamed `blacklisted_name` to [`disallowed_names`]\n  [#8974](https://github.com/rust-lang/rust-clippy/pull/8974)\n\n### Enhancements\n\n* [`option_if_let_else`]: Now also checks for match expressions\n  [#8696](https://github.com/rust-lang/rust-clippy/pull/8696)\n* [`explicit_auto_deref`]: Now lints on implicit returns in closures\n  [#9126](https://github.com/rust-lang/rust-clippy/pull/9126)\n* [`needless_borrow`]: Now considers trait implementations\n  [#9136](https://github.com/rust-lang/rust-clippy/pull/9136)\n* [`suboptimal_flops`], [`imprecise_flops`]: Now lint on constant expressions\n  [#9404](https://github.com/rust-lang/rust-clippy/pull/9404)\n* [`if_let_mutex`]: Now detects mutex behind references and warns about deadlocks\n  [#9318](https://github.com/rust-lang/rust-clippy/pull/9318)\n\n### False Positive Fixes\n\n* [`unit_arg`] [`default_trait_access`] [`missing_docs_in_private_items`]: No longer\n  trigger in code generated from proc-macros\n  [#8694](https://github.com/rust-lang/rust-clippy/pull/8694)\n* [`unwrap_used`]: Now lints uses of `unwrap_err`\n  [#9338](https://github.com/rust-lang/rust-clippy/pull/9338)\n* [`expect_used`]: Now lints uses of `expect_err`\n  [#9338](https://github.com/rust-lang/rust-clippy/pull/9338)\n* [`transmute_undefined_repr`]: Now longer lints if the first field is compatible\n  with the other type\n  [#9287](https://github.com/rust-lang/rust-clippy/pull/9287)\n* [`unnecessary_to_owned`]: No longer lints, if type change cased errors in\n  the caller function\n  [#9424](https://github.com/rust-lang/rust-clippy/pull/9424)\n* [`match_like_matches_macro`]: No longer lints, if there are comments inside the\n  match expression\n  [#9276](https://github.com/rust-lang/rust-clippy/pull/9276)\n* [`partialeq_to_none`]: No longer trigger in code generated from macros\n  [#9389](https://github.com/rust-lang/rust-clippy/pull/9389)\n* [`arithmetic_side_effects`]: No longer lints expressions that only use literals\n  [#9365](https://github.com/rust-lang/rust-clippy/pull/9365)\n* [`explicit_auto_deref`]: Now ignores references on block expressions when the type\n  is `Sized`, on `dyn Trait` returns and when the suggestion is non-trivial\n  [#9126](https://github.com/rust-lang/rust-clippy/pull/9126)\n* [`trait_duplication_in_bounds`]: Now better tracks bounds to avoid false positives\n  [#9167](https://github.com/rust-lang/rust-clippy/pull/9167)\n* [`format_in_format_args`]: Now suggests cases where the result is formatted again\n  [#9349](https://github.com/rust-lang/rust-clippy/pull/9349)\n* [`only_used_in_recursion`]: No longer lints on function without recursions and\n  takes external functions into account\n  [#8804](https://github.com/rust-lang/rust-clippy/pull/8804)\n* [`missing_const_for_fn`]: No longer lints in proc-macros\n  [#9308](https://github.com/rust-lang/rust-clippy/pull/9308)\n* [`non_ascii_literal`]: Allow non-ascii comments in tests and make sure `#[allow]`\n  attributes work in tests\n  [#9327](https://github.com/rust-lang/rust-clippy/pull/9327)\n* [`question_mark`]: No longer lint `if let`s with subpatterns\n  [#9348](https://github.com/rust-lang/rust-clippy/pull/9348)\n* [`needless_collect`]: No longer lints in loops\n  [#8992](https://github.com/rust-lang/rust-clippy/pull/8992)\n* [`mut_mutex_lock`]: No longer lints if the mutex is behind an immutable reference\n  [#9418](https://github.com/rust-lang/rust-clippy/pull/9418)\n* [`needless_return`]: Now ignores returns with arguments\n  [#9381](https://github.com/rust-lang/rust-clippy/pull/9381)\n* [`range_plus_one`], [`range_minus_one`]: Now ignores code with macros\n  [#9446](https://github.com/rust-lang/rust-clippy/pull/9446)\n* [`assertions_on_result_states`]: No longer lints on the unit type\n  [#9273](https://github.com/rust-lang/rust-clippy/pull/9273)\n\n### Suggestion Fixes/Improvements\n\n* [`unwrap_or_else_default`]: Now suggests `unwrap_or_default()` for empty strings\n  [#9421](https://github.com/rust-lang/rust-clippy/pull/9421)\n* [`if_then_some_else_none`]: Now also suggests `bool::then_some`\n  [#9289](https://github.com/rust-lang/rust-clippy/pull/9289)\n* [`redundant_closure_call`]: The suggestion now works for async closures\n  [#9053](https://github.com/rust-lang/rust-clippy/pull/9053)\n* [`suboptimal_flops`]: Now suggests parenthesis when they are required\n  [#9394](https://github.com/rust-lang/rust-clippy/pull/9394)\n* [`case_sensitive_file_extension_comparisons`]: Now suggests `map_or(..)` instead of `map(..).unwrap_or`\n  [#9341](https://github.com/rust-lang/rust-clippy/pull/9341)\n* Deprecated configuration values can now be updated automatically\n  [#9252](https://github.com/rust-lang/rust-clippy/pull/9252)\n* [`or_fun_call`]: Now suggest `Entry::or_default` for `Entry::or_insert(Default::default())`\n  [#9342](https://github.com/rust-lang/rust-clippy/pull/9342)\n* [`unwrap_used`]: Only suggests `expect` if [`expect_used`] is allowed\n  [#9223](https://github.com/rust-lang/rust-clippy/pull/9223)\n\n### ICE Fixes\n\n* Fix ICE in [`useless_format`] for literals\n  [#9406](https://github.com/rust-lang/rust-clippy/pull/9406)\n* Fix infinite loop in [`vec_init_then_push`]\n  [#9441](https://github.com/rust-lang/rust-clippy/pull/9441)\n* Fix ICE when reading literals with weird proc-macro spans\n  [#9303](https://github.com/rust-lang/rust-clippy/pull/9303)\n\n## Rust 1.64\n\nReleased 2022-09-22\n\n[View all 110 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-06-17T21%3A25%3A31Z..2022-07-28T17%3A11%3A18Z+base%3Amaster)\n\n### New Lints\n\n* [`arithmetic_side_effects`]\n  [#9130](https://github.com/rust-lang/rust-clippy/pull/9130)\n* [`invalid_utf8_in_unchecked`]\n  [#9105](https://github.com/rust-lang/rust-clippy/pull/9105)\n* [`assertions_on_result_states`]\n  [#9225](https://github.com/rust-lang/rust-clippy/pull/9225)\n* [`manual_find`]\n  [#8649](https://github.com/rust-lang/rust-clippy/pull/8649)\n* [`manual_retain`]\n  [#8972](https://github.com/rust-lang/rust-clippy/pull/8972)\n* [`default_instead_of_iter_empty`]\n  [#8989](https://github.com/rust-lang/rust-clippy/pull/8989)\n* [`manual_rem_euclid`]\n  [#9031](https://github.com/rust-lang/rust-clippy/pull/9031)\n* [`obfuscated_if_else`]\n  [#9148](https://github.com/rust-lang/rust-clippy/pull/9148)\n* [`std_instead_of_core`]\n  [#9103](https://github.com/rust-lang/rust-clippy/pull/9103)\n* [`std_instead_of_alloc`]\n  [#9103](https://github.com/rust-lang/rust-clippy/pull/9103)\n* [`alloc_instead_of_core`]\n  [#9103](https://github.com/rust-lang/rust-clippy/pull/9103)\n* [`explicit_auto_deref`]\n  [#8355](https://github.com/rust-lang/rust-clippy/pull/8355)\n\n### Moves and Deprecations\n\n* Moved [`format_push_string`] to `restriction` (now allow-by-default)\n  [#9161](https://github.com/rust-lang/rust-clippy/pull/9161)\n\n### Enhancements\n\n* [`significant_drop_in_scrutinee`]: Now gives more context in the lint message\n  [#8981](https://github.com/rust-lang/rust-clippy/pull/8981)\n* [`single_match`], [`single_match_else`]: Now catches more `Option` cases\n  [#8985](https://github.com/rust-lang/rust-clippy/pull/8985)\n* [`unused_async`]: Now works for async methods\n  [#9025](https://github.com/rust-lang/rust-clippy/pull/9025)\n* [`manual_filter_map`], [`manual_find_map`]: Now lint more expressions\n  [#8958](https://github.com/rust-lang/rust-clippy/pull/8958)\n* [`question_mark`]: Now works for simple `if let` expressions\n  [#8356](https://github.com/rust-lang/rust-clippy/pull/8356)\n* [`undocumented_unsafe_blocks`]: Now finds comments before the start of closures\n  [#9117](https://github.com/rust-lang/rust-clippy/pull/9117)\n* [`trait_duplication_in_bounds`]: Now catches duplicate bounds in where clauses\n  [#8703](https://github.com/rust-lang/rust-clippy/pull/8703)\n* [`shadow_reuse`], [`shadow_same`], [`shadow_unrelated`]: Now lint in const blocks\n  [#9124](https://github.com/rust-lang/rust-clippy/pull/9124)\n* [`slow_vector_initialization`]: Now detects cases with `vec.capacity()`\n  [#8953](https://github.com/rust-lang/rust-clippy/pull/8953)\n* [`unused_self`]: Now respects the `avoid-breaking-exported-api` config option\n  [#9199](https://github.com/rust-lang/rust-clippy/pull/9199)\n* [`box_collection`]: Now supports all std collections\n  [#9170](https://github.com/rust-lang/rust-clippy/pull/9170)\n\n### False Positive Fixes\n\n* [`significant_drop_in_scrutinee`]: Now ignores calls to `IntoIterator::into_iter`\n  [#9140](https://github.com/rust-lang/rust-clippy/pull/9140)\n* [`while_let_loop`]: Now ignores cases when the significant drop order would change\n  [#8981](https://github.com/rust-lang/rust-clippy/pull/8981)\n* [`branches_sharing_code`]: Now ignores cases where moved variables have a significant\n  drop or variable modifications can affect the conditions\n  [#9138](https://github.com/rust-lang/rust-clippy/pull/9138)\n* [`let_underscore_lock`]: Now ignores bindings that aren't locked\n  [#8990](https://github.com/rust-lang/rust-clippy/pull/8990)\n* [`trivially_copy_pass_by_ref`]: Now tracks lifetimes and ignores cases where unsafe\n  pointers are used\n  [#8639](https://github.com/rust-lang/rust-clippy/pull/8639)\n* [`let_unit_value`]: No longer ignores `#[allow]` attributes on the value\n  [#9082](https://github.com/rust-lang/rust-clippy/pull/9082)\n* [`declare_interior_mutable_const`]: Now ignores the `thread_local!` macro\n  [#9015](https://github.com/rust-lang/rust-clippy/pull/9015)\n* [`if_same_then_else`]: Now ignores branches with `todo!` and `unimplemented!`\n  [#9006](https://github.com/rust-lang/rust-clippy/pull/9006)\n* [`enum_variant_names`]: Now ignores names with `_` prefixes\n  [#9032](https://github.com/rust-lang/rust-clippy/pull/9032)\n* [`let_unit_value`]: Now ignores cases, where the unit type is manually specified\n  [#9056](https://github.com/rust-lang/rust-clippy/pull/9056)\n* [`match_same_arms`]: Now ignores branches with `todo!`\n  [#9207](https://github.com/rust-lang/rust-clippy/pull/9207)\n* [`assign_op_pattern`]: Ignores cases that break borrowing rules\n  [#9214](https://github.com/rust-lang/rust-clippy/pull/9214)\n* [`extra_unused_lifetimes`]: No longer triggers in derive macros\n  [#9037](https://github.com/rust-lang/rust-clippy/pull/9037)\n* [`mismatching_type_param_order`]: Now ignores complicated generic parameters\n  [#9146](https://github.com/rust-lang/rust-clippy/pull/9146)\n* [`equatable_if_let`]: No longer lints in macros\n  [#9074](https://github.com/rust-lang/rust-clippy/pull/9074)\n* [`new_without_default`]: Now ignores generics and lifetime parameters on `fn new`\n  [#9115](https://github.com/rust-lang/rust-clippy/pull/9115)\n* [`needless_borrow`]: Now ignores cases that result in the execution of different traits\n  [#9096](https://github.com/rust-lang/rust-clippy/pull/9096)\n* [`declare_interior_mutable_const`]: No longer triggers in thread-local initializers\n  [#9246](https://github.com/rust-lang/rust-clippy/pull/9246)\n\n### Suggestion Fixes/Improvements\n\n* [`type_repetition_in_bounds`]: The suggestion now works with maybe bounds\n  [#9132](https://github.com/rust-lang/rust-clippy/pull/9132)\n* [`transmute_ptr_to_ref`]: Now suggests `pointer::cast` when possible\n  [#8939](https://github.com/rust-lang/rust-clippy/pull/8939)\n* [`useless_format`]: Now suggests the correct variable name\n  [#9237](https://github.com/rust-lang/rust-clippy/pull/9237)\n* [`or_fun_call`]: The lint emission will now only span over the `unwrap_or` call\n  [#9144](https://github.com/rust-lang/rust-clippy/pull/9144)\n* [`neg_multiply`]: Now suggests adding parentheses around suggestion if needed\n  [#9026](https://github.com/rust-lang/rust-clippy/pull/9026)\n* [`unnecessary_lazy_evaluations`]: Now suggest for `bool::then_some` for lazy evaluation\n  [#9099](https://github.com/rust-lang/rust-clippy/pull/9099)\n* [`manual_flatten`]: Improved message for long code snippets\n  [#9156](https://github.com/rust-lang/rust-clippy/pull/9156)\n* [`explicit_counter_loop`]: The suggestion is now machine applicable\n  [#9149](https://github.com/rust-lang/rust-clippy/pull/9149)\n* [`needless_borrow`]: Now keeps parentheses around fields, when needed\n  [#9210](https://github.com/rust-lang/rust-clippy/pull/9210)\n* [`while_let_on_iterator`]: The suggestion now works in `FnOnce` closures\n  [#9134](https://github.com/rust-lang/rust-clippy/pull/9134)\n\n### ICE Fixes\n\n* Fix ICEs related to `#![feature(generic_const_exprs)]` usage\n  [#9241](https://github.com/rust-lang/rust-clippy/pull/9241)\n* Fix ICEs related to reference lints\n  [#9093](https://github.com/rust-lang/rust-clippy/pull/9093)\n* [`question_mark`]: Fix ICE on zero field tuple structs\n  [#9244](https://github.com/rust-lang/rust-clippy/pull/9244)\n\n### Documentation Improvements\n\n* [`needless_option_take`]: Now includes a \"What it does\" and \"Why is this bad?\" section.\n  [#9022](https://github.com/rust-lang/rust-clippy/pull/9022)\n\n### Others\n\n* Using `--cap-lints=allow` and only `--force-warn`ing some will now work with Clippy's driver\n  [#9036](https://github.com/rust-lang/rust-clippy/pull/9036)\n* Clippy now tries to read the `rust-version` from `Cargo.toml` to identify the\n  minimum supported rust version\n  [#8774](https://github.com/rust-lang/rust-clippy/pull/8774)\n\n## Rust 1.63\n\nReleased 2022-08-11\n\n[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-05-05T17%3A24%3A22Z..2022-06-16T14%3A24%3A48Z+base%3Amaster)\n\n### New Lints\n\n* [`borrow_deref_ref`]\n  [#7930](https://github.com/rust-lang/rust-clippy/pull/7930)\n* [`doc_link_with_quotes`]\n  [#8385](https://github.com/rust-lang/rust-clippy/pull/8385)\n* [`no_effect_replace`]\n  [#8754](https://github.com/rust-lang/rust-clippy/pull/8754)\n* [`rc_clone_in_vec_init`]\n  [#8769](https://github.com/rust-lang/rust-clippy/pull/8769)\n* [`derive_partial_eq_without_eq`]\n  [#8796](https://github.com/rust-lang/rust-clippy/pull/8796)\n* [`mismatching_type_param_order`]\n  [#8831](https://github.com/rust-lang/rust-clippy/pull/8831)\n* [`duplicate_mod`] [#8832](https://github.com/rust-lang/rust-clippy/pull/8832)\n* [`unused_rounding`]\n  [#8866](https://github.com/rust-lang/rust-clippy/pull/8866)\n* [`get_first`] [#8882](https://github.com/rust-lang/rust-clippy/pull/8882)\n* [`swap_ptr_to_ref`]\n  [#8916](https://github.com/rust-lang/rust-clippy/pull/8916)\n* [`almost_complete_letter_range`]\n  [#8918](https://github.com/rust-lang/rust-clippy/pull/8918)\n* [`needless_parens_on_range_literals`]\n  [#8933](https://github.com/rust-lang/rust-clippy/pull/8933)\n* [`as_underscore`] [#8934](https://github.com/rust-lang/rust-clippy/pull/8934)\n\n### Moves and Deprecations\n\n* Rename `eval_order_dependence` to [`mixed_read_write_in_expression`], move to\n  `nursery` [#8621](https://github.com/rust-lang/rust-clippy/pull/8621)\n\n### Enhancements\n\n* [`undocumented_unsafe_blocks`]: Now also lints on unsafe trait implementations\n  [#8761](https://github.com/rust-lang/rust-clippy/pull/8761)\n* [`empty_line_after_outer_attr`]: Now also lints on argumentless macros\n  [#8790](https://github.com/rust-lang/rust-clippy/pull/8790)\n* [`expect_used`]: Now can be disabled in tests with the `allow-expect-in-tests`\n  option [#8802](https://github.com/rust-lang/rust-clippy/pull/8802)\n* [`unwrap_used`]: Now can be disabled in tests with the `allow-unwrap-in-tests`\n  option [#8802](https://github.com/rust-lang/rust-clippy/pull/8802)\n* [`disallowed_methods`]: Now also lints indirect usages\n  [#8852](https://github.com/rust-lang/rust-clippy/pull/8852)\n* [`get_last_with_len`]: Now also lints `VecDeque` and any deref to slice\n  [#8862](https://github.com/rust-lang/rust-clippy/pull/8862)\n* [`manual_range_contains`]: Now also lints on chains of `&&` and `||`\n  [#8884](https://github.com/rust-lang/rust-clippy/pull/8884)\n* [`rc_clone_in_vec_init`]: Now also lints on `Weak`\n  [#8885](https://github.com/rust-lang/rust-clippy/pull/8885)\n* [`dbg_macro`]: Introduce `allow-dbg-in-tests` config option\n  [#8897](https://github.com/rust-lang/rust-clippy/pull/8897)\n* [`use_self`]: Now also lints on `TupleStruct` and `Struct` patterns\n  [#8899](https://github.com/rust-lang/rust-clippy/pull/8899)\n* [`manual_find_map`] and [`manual_filter_map`]: Now also lints on more complex\n  method chains inside `map`\n  [#8930](https://github.com/rust-lang/rust-clippy/pull/8930)\n* [`needless_return`]: Now also lints on macro expressions in return statements\n  [#8932](https://github.com/rust-lang/rust-clippy/pull/8932)\n* [`doc_markdown`]: Users can now indicate, that the `doc-valid-idents` config\n  should extend the default and not replace it\n  [#8944](https://github.com/rust-lang/rust-clippy/pull/8944)\n* [`disallowed_names`]: Users can now indicate, that the `disallowed-names`\n  config should extend the default and not replace it\n  [#8944](https://github.com/rust-lang/rust-clippy/pull/8944)\n* [`never_loop`]: Now checks for `continue` in struct expression\n  [#9002](https://github.com/rust-lang/rust-clippy/pull/9002)\n\n### False Positive Fixes\n\n* [`useless_transmute`]: No longer lints on types with erased regions\n  [#8564](https://github.com/rust-lang/rust-clippy/pull/8564)\n* [`vec_init_then_push`]: No longer lints when further extended\n  [#8699](https://github.com/rust-lang/rust-clippy/pull/8699)\n* [`cmp_owned`]: No longer lints on `From::from` for `Copy` types\n  [#8807](https://github.com/rust-lang/rust-clippy/pull/8807)\n* [`redundant_allocation`]: No longer lints on fat pointers that would become\n  thin pointers [#8813](https://github.com/rust-lang/rust-clippy/pull/8813)\n* [`derive_partial_eq_without_eq`]:\n  * Handle differing predicates applied by `#[derive(PartialEq)]` and\n      `#[derive(Eq)]`\n      [#8869](https://github.com/rust-lang/rust-clippy/pull/8869)\n  * No longer lints on non-public types and better handles generics\n      [#8950](https://github.com/rust-lang/rust-clippy/pull/8950)\n* [`empty_line_after_outer_attr`]: No longer lints empty lines in inner\n  string values [#8892](https://github.com/rust-lang/rust-clippy/pull/8892)\n* [`branches_sharing_code`]: No longer lints when using different binding names\n  [#8901](https://github.com/rust-lang/rust-clippy/pull/8901)\n* [`significant_drop_in_scrutinee`]: No longer lints on Try `?` and `await`\n  desugared expressions [#8902](https://github.com/rust-lang/rust-clippy/pull/8902)\n* [`checked_conversions`]: No longer lints in `const` contexts\n  [#8907](https://github.com/rust-lang/rust-clippy/pull/8907)\n* [`iter_overeager_cloned`]: No longer lints on `.cloned().flatten()` when\n  `T::Item` doesn't implement `IntoIterator`\n  [#8960](https://github.com/rust-lang/rust-clippy/pull/8960)\n\n### Suggestion Fixes/Improvements\n\n* [`vec_init_then_push`]: Suggest to remove `mut` binding when possible\n  [#8699](https://github.com/rust-lang/rust-clippy/pull/8699)\n* [`manual_range_contains`]: Fix suggestion for integers with different signs\n  [#8763](https://github.com/rust-lang/rust-clippy/pull/8763)\n* [`identity_op`]: Add parenthesis to suggestions where required\n  [#8786](https://github.com/rust-lang/rust-clippy/pull/8786)\n* [`cast_lossless`]: No longer gives wrong suggestion on `usize`/`isize`->`f64`\n  [#8778](https://github.com/rust-lang/rust-clippy/pull/8778)\n* [`rc_clone_in_vec_init`]: Add suggestion\n  [#8814](https://github.com/rust-lang/rust-clippy/pull/8814)\n* The \"unknown field\" error messages for config files now wraps the field names\n  [#8823](https://github.com/rust-lang/rust-clippy/pull/8823)\n* [`cast_abs_to_unsigned`]: Do not remove cast if it's required\n  [#8876](https://github.com/rust-lang/rust-clippy/pull/8876)\n* [`significant_drop_in_scrutinee`]: Improve lint message for types that are not\n  references and not trivially clone-able\n  [#8902](https://github.com/rust-lang/rust-clippy/pull/8902)\n* [`for_loops_over_fallibles`]: Now suggests the correct variant of `iter()`,\n  `iter_mut()` or `into_iter()`\n  [#8941](https://github.com/rust-lang/rust-clippy/pull/8941)\n\n### ICE Fixes\n\n* Fix ICE in [`let_unit_value`] when calling a `static`/`const` callable type\n  [#8835](https://github.com/rust-lang/rust-clippy/pull/8835)\n* Fix ICEs on callable `static`/`const`s\n  [#8896](https://github.com/rust-lang/rust-clippy/pull/8896)\n* [`needless_late_init`]\n  [#8912](https://github.com/rust-lang/rust-clippy/pull/8912)\n* Fix ICE in shadow lints\n  [#8913](https://github.com/rust-lang/rust-clippy/pull/8913)\n\n### Documentation Improvements\n\n* Clippy has a [Book](https://doc.rust-lang.org/nightly/clippy/) now!\n  [#7359](https://github.com/rust-lang/rust-clippy/pull/7359)\n* Add a *copy lint name*-button to Clippy's lint list\n  [#8839](https://github.com/rust-lang/rust-clippy/pull/8839)\n* Display past names of renamed lints on Clippy's lint list\n  [#8843](https://github.com/rust-lang/rust-clippy/pull/8843)\n* Add the ability to show the lint output in the lint list\n  [#8947](https://github.com/rust-lang/rust-clippy/pull/8947)\n\n## Rust 1.62\n\nReleased 2022-06-30\n\n[View all 90 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-03-25T17%3A22%3A30Z..2022-05-05T13%3A29%3A44Z+base%3Amaster)\n\n### New Lints\n\n* [`large_include_file`]\n  [#8727](https://github.com/rust-lang/rust-clippy/pull/8727)\n* [`cast_abs_to_unsigned`]\n  [#8635](https://github.com/rust-lang/rust-clippy/pull/8635)\n* [`err_expect`]\n  [#8606](https://github.com/rust-lang/rust-clippy/pull/8606)\n* [`unnecessary_owned_empty_strings`]\n  [#8660](https://github.com/rust-lang/rust-clippy/pull/8660)\n* [`empty_structs_with_brackets`]\n  [#8594](https://github.com/rust-lang/rust-clippy/pull/8594)\n* [`crate_in_macro_def`]\n  [#8576](https://github.com/rust-lang/rust-clippy/pull/8576)\n* [`needless_option_take`]\n  [#8665](https://github.com/rust-lang/rust-clippy/pull/8665)\n* [`bytes_count_to_len`]\n  [#8711](https://github.com/rust-lang/rust-clippy/pull/8711)\n* [`is_digit_ascii_radix`]\n  [#8624](https://github.com/rust-lang/rust-clippy/pull/8624)\n* [`await_holding_invalid_type`]\n  [#8707](https://github.com/rust-lang/rust-clippy/pull/8707)\n* [`trim_split_whitespace`]\n  [#8575](https://github.com/rust-lang/rust-clippy/pull/8575)\n* [`pub_use`]\n  [#8670](https://github.com/rust-lang/rust-clippy/pull/8670)\n* [`format_push_string`]\n  [#8626](https://github.com/rust-lang/rust-clippy/pull/8626)\n* [`empty_drop`]\n  [#8571](https://github.com/rust-lang/rust-clippy/pull/8571)\n* [`drop_non_drop`]\n  [#8630](https://github.com/rust-lang/rust-clippy/pull/8630)\n* [`forget_non_drop`]\n  [#8630](https://github.com/rust-lang/rust-clippy/pull/8630)\n\n### Moves and Deprecations\n\n* Move [`only_used_in_recursion`] to `nursery` (now allow-by-default)\n  [#8783](https://github.com/rust-lang/rust-clippy/pull/8783)\n* Move [`stable_sort_primitive`] to `pedantic` (now allow-by-default)\n  [#8716](https://github.com/rust-lang/rust-clippy/pull/8716)\n\n### Enhancements\n\n* Remove overlap between [`manual_split_once`] and [`needless_splitn`]\n  [#8631](https://github.com/rust-lang/rust-clippy/pull/8631)\n* [`map_identity`]: Now checks for needless `map_err`\n  [#8487](https://github.com/rust-lang/rust-clippy/pull/8487)\n* [`extra_unused_lifetimes`]: Now checks for impl lifetimes\n  [#8737](https://github.com/rust-lang/rust-clippy/pull/8737)\n* [`cast_possible_truncation`]: Now catches more cases with larger shift or divide operations\n  [#8687](https://github.com/rust-lang/rust-clippy/pull/8687)\n* [`identity_op`]: Now checks for modulo expressions\n  [#8519](https://github.com/rust-lang/rust-clippy/pull/8519)\n* [`panic`]: No longer lint in constant context\n  [#8592](https://github.com/rust-lang/rust-clippy/pull/8592)\n* [`manual_split_once`]: Now lints manual iteration of `splitn`\n  [#8717](https://github.com/rust-lang/rust-clippy/pull/8717)\n* [`self_named_module_files`], [`mod_module_files`]: Now handle relative module paths\n  [#8611](https://github.com/rust-lang/rust-clippy/pull/8611)\n* [`unsound_collection_transmute`]: Now has better size and alignment checks\n  [#8648](https://github.com/rust-lang/rust-clippy/pull/8648)\n* [`unnested_or_patterns`]: Ignore cases, where the suggestion would be longer\n  [#8619](https://github.com/rust-lang/rust-clippy/pull/8619)\n\n### False Positive Fixes\n\n* [`rest_pat_in_fully_bound_structs`]: Now ignores structs marked with `#[non_exhaustive]`\n  [#8690](https://github.com/rust-lang/rust-clippy/pull/8690)\n* [`needless_late_init`]: No longer lints `if let` statements, `let mut` bindings or instances that\n  changes the drop order significantly\n  [#8617](https://github.com/rust-lang/rust-clippy/pull/8617)\n* [`unnecessary_cast`]: No longer lints to casts to aliased or non-primitive types\n  [#8596](https://github.com/rust-lang/rust-clippy/pull/8596)\n* [`init_numbered_fields`]: No longer lints type aliases\n  [#8780](https://github.com/rust-lang/rust-clippy/pull/8780)\n* [`needless_option_as_deref`]: No longer lints for `as_deref_mut` on `Option` values that can't be moved\n  [#8646](https://github.com/rust-lang/rust-clippy/pull/8646)\n* [`mistyped_literal_suffixes`]: Now ignores float literals without an exponent\n  [#8742](https://github.com/rust-lang/rust-clippy/pull/8742)\n* [`undocumented_unsafe_blocks`]: Now ignores unsafe blocks from proc-macros and works better for sub-expressions\n  [#8450](https://github.com/rust-lang/rust-clippy/pull/8450)\n* [`same_functions_in_if_condition`]: Now allows different constants, even if they have the same value\n  [#8673](https://github.com/rust-lang/rust-clippy/pull/8673)\n* [`needless_match`]: Now checks for more complex types and ignores type coercion\n  [#8549](https://github.com/rust-lang/rust-clippy/pull/8549)\n* [`assertions_on_constants`]: Now ignores constants from `cfg!` macros\n  [#8614](https://github.com/rust-lang/rust-clippy/pull/8614)\n* [`indexing_slicing`]: Fix false positives with constant indices in\n  [#8588](https://github.com/rust-lang/rust-clippy/pull/8588)\n* [`iter_with_drain`]: Now ignores iterator references\n  [#8668](https://github.com/rust-lang/rust-clippy/pull/8668)\n* [`useless_attribute`]: Now allows [`redundant_pub_crate`] on `use` items\n  [#8743](https://github.com/rust-lang/rust-clippy/pull/8743)\n* [`cast_ptr_alignment`]: Now ignores expressions, when used for unaligned reads and writes\n  [#8632](https://github.com/rust-lang/rust-clippy/pull/8632)\n* [`wrong_self_convention`]: Now allows `&mut self` and no self as arguments for `is_*` methods\n  [#8738](https://github.com/rust-lang/rust-clippy/pull/8738)\n* [`mut_from_ref`]: Only lint in unsafe code\n  [#8647](https://github.com/rust-lang/rust-clippy/pull/8647)\n* [`redundant_pub_crate`]: Now allows macro exports\n  [#8736](https://github.com/rust-lang/rust-clippy/pull/8736)\n* [`needless_match`]: Ignores cases where the else block expression is different\n  [#8700](https://github.com/rust-lang/rust-clippy/pull/8700)\n* [`transmute_int_to_char`]: Now allows transmutations in `const` code\n  [#8610](https://github.com/rust-lang/rust-clippy/pull/8610)\n* [`manual_non_exhaustive`]: Ignores cases, where the enum value is used\n  [#8645](https://github.com/rust-lang/rust-clippy/pull/8645)\n* [`redundant_closure`]: Now ignores coerced closure\n  [#8431](https://github.com/rust-lang/rust-clippy/pull/8431)\n* [`identity_op`]: Is now ignored in cases where extra brackets would be needed\n  [#8730](https://github.com/rust-lang/rust-clippy/pull/8730)\n* [`let_unit_value`]: Now ignores cases which are used for type inference\n  [#8563](https://github.com/rust-lang/rust-clippy/pull/8563)\n\n### Suggestion Fixes/Improvements\n\n* [`manual_split_once`]: Fixed incorrect suggestions for single result accesses\n  [#8631](https://github.com/rust-lang/rust-clippy/pull/8631)\n* [`bytes_nth`]: Fix typos in the diagnostic message\n  [#8403](https://github.com/rust-lang/rust-clippy/pull/8403)\n* [`mistyped_literal_suffixes`]: Now suggests the correct integer types\n  [#8742](https://github.com/rust-lang/rust-clippy/pull/8742)\n* [`unnecessary_to_owned`]: Fixed suggestion based on the configured msrv\n  [#8692](https://github.com/rust-lang/rust-clippy/pull/8692)\n* [`single_element_loop`]: Improve lint for Edition 2021 arrays\n  [#8616](https://github.com/rust-lang/rust-clippy/pull/8616)\n* [`manual_bits`]: Now includes a cast for proper type conversion, when needed\n  [#8677](https://github.com/rust-lang/rust-clippy/pull/8677)\n* [`option_map_unit_fn`], [`result_map_unit_fn`]: Fix some incorrect suggestions\n  [#8584](https://github.com/rust-lang/rust-clippy/pull/8584)\n* [`collapsible_else_if`]: Add whitespace in suggestion\n  [#8729](https://github.com/rust-lang/rust-clippy/pull/8729)\n* [`transmute_bytes_to_str`]: Now suggest `from_utf8_unchecked` in `const` context\n  [#8612](https://github.com/rust-lang/rust-clippy/pull/8612)\n* [`map_clone`]: Improve message and suggestion based on the msrv\n  [#8688](https://github.com/rust-lang/rust-clippy/pull/8688)\n* [`needless_late_init`]: Now shows the `let` statement where it was first initialized\n  [#8779](https://github.com/rust-lang/rust-clippy/pull/8779)\n\n### ICE Fixes\n\n* [`only_used_in_recursion`]\n  [#8691](https://github.com/rust-lang/rust-clippy/pull/8691)\n* [`cast_slice_different_sizes`]\n  [#8720](https://github.com/rust-lang/rust-clippy/pull/8720)\n* [`iter_overeager_cloned`]\n  [#8602](https://github.com/rust-lang/rust-clippy/pull/8602)\n* [`undocumented_unsafe_blocks`]\n  [#8686](https://github.com/rust-lang/rust-clippy/pull/8686)\n\n## Rust 1.61\n\nReleased 2022-05-19\n\n[View all 60 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2022-02-11T16%3A54%3A41Z..2022-03-24T13%3A42%3A25Z+base%3Amaster)\n\n### New Lints\n\n* [`only_used_in_recursion`]\n  [#8422](https://github.com/rust-lang/rust-clippy/pull/8422)\n* [`cast_enum_truncation`]\n  [#8381](https://github.com/rust-lang/rust-clippy/pull/8381)\n* [`missing_spin_loop`]\n  [#8174](https://github.com/rust-lang/rust-clippy/pull/8174)\n* [`deref_by_slicing`]\n  [#8218](https://github.com/rust-lang/rust-clippy/pull/8218)\n* [`needless_match`]\n  [#8471](https://github.com/rust-lang/rust-clippy/pull/8471)\n* [`allow_attributes_without_reason`]\n  [#8504](https://github.com/rust-lang/rust-clippy/pull/8504)\n* [`print_in_format_impl`]\n  [#8253](https://github.com/rust-lang/rust-clippy/pull/8253)\n* [`unnecessary_find_map`]\n  [#8489](https://github.com/rust-lang/rust-clippy/pull/8489)\n* [`or_then_unwrap`]\n  [#8561](https://github.com/rust-lang/rust-clippy/pull/8561)\n* [`unnecessary_join`]\n  [#8579](https://github.com/rust-lang/rust-clippy/pull/8579)\n* [`iter_with_drain`]\n  [#8483](https://github.com/rust-lang/rust-clippy/pull/8483)\n* [`cast_enum_constructor`]\n  [#8562](https://github.com/rust-lang/rust-clippy/pull/8562)\n* [`cast_slice_different_sizes`]\n  [#8445](https://github.com/rust-lang/rust-clippy/pull/8445)\n\n### Moves and Deprecations\n\n* Moved [`transmute_undefined_repr`] to `nursery` (now allow-by-default)\n  [#8432](https://github.com/rust-lang/rust-clippy/pull/8432)\n* Moved [`try_err`] to `restriction`\n  [#8544](https://github.com/rust-lang/rust-clippy/pull/8544)\n* Move [`iter_with_drain`] to `nursery`\n  [#8541](https://github.com/rust-lang/rust-clippy/pull/8541)\n* Renamed `to_string_in_display` to [`recursive_format_impl`]\n  [#8188](https://github.com/rust-lang/rust-clippy/pull/8188)\n\n### Enhancements\n\n* [`dbg_macro`]: The lint level can now be set with crate attributes and works inside macros\n  [#8411](https://github.com/rust-lang/rust-clippy/pull/8411)\n* [`ptr_as_ptr`]: Now works inside macros\n  [#8442](https://github.com/rust-lang/rust-clippy/pull/8442)\n* [`use_self`]: Now works for variants in match expressions\n  [#8456](https://github.com/rust-lang/rust-clippy/pull/8456)\n* [`await_holding_lock`]: Now lints for `parking_lot::{Mutex, RwLock}`\n  [#8419](https://github.com/rust-lang/rust-clippy/pull/8419)\n* [`recursive_format_impl`]: Now checks for format calls on `self`\n  [#8188](https://github.com/rust-lang/rust-clippy/pull/8188)\n\n### False Positive Fixes\n\n* [`new_without_default`]: No longer lints for `new()` methods with `#[doc(hidden)]`\n  [#8472](https://github.com/rust-lang/rust-clippy/pull/8472)\n* [`transmute_undefined_repr`]: No longer lints for single field structs with `#[repr(C)]`,\n  generic parameters, wide pointers, unions, tuples and allow several forms of type erasure\n  [#8425](https://github.com/rust-lang/rust-clippy/pull/8425)\n  [#8553](https://github.com/rust-lang/rust-clippy/pull/8553)\n  [#8440](https://github.com/rust-lang/rust-clippy/pull/8440)\n  [#8547](https://github.com/rust-lang/rust-clippy/pull/8547)\n* [`match_single_binding`], [`match_same_arms`], [`match_as_ref`], [`match_bool`]: No longer\n  lint `match` expressions with `cfg`ed arms\n  [#8443](https://github.com/rust-lang/rust-clippy/pull/8443)\n* [`single_component_path_imports`]: No longer lint on macros\n  [#8537](https://github.com/rust-lang/rust-clippy/pull/8537)\n* [`ptr_arg`]: Allow `&mut` arguments for `Cow<_>`\n  [#8552](https://github.com/rust-lang/rust-clippy/pull/8552)\n* [`needless_borrow`]: No longer lints for method calls\n  [#8441](https://github.com/rust-lang/rust-clippy/pull/8441)\n* [`match_same_arms`]: Now ensures that interposing arm patterns don't overlap\n  [#8232](https://github.com/rust-lang/rust-clippy/pull/8232)\n* [`default_trait_access`]: Now allows `Default::default` in update expressions\n  [#8433](https://github.com/rust-lang/rust-clippy/pull/8433)\n\n### Suggestion Fixes/Improvements\n\n* [`redundant_slicing`]: Fixed suggestion for a method calls\n  [#8218](https://github.com/rust-lang/rust-clippy/pull/8218)\n* [`map_flatten`]: Long suggestions will now be split up into two help messages\n  [#8520](https://github.com/rust-lang/rust-clippy/pull/8520)\n* [`unnecessary_lazy_evaluations`]: Now shows suggestions for longer code snippets\n  [#8543](https://github.com/rust-lang/rust-clippy/pull/8543)\n* [`unnecessary_sort_by`]: Now suggests `Reverse` including the path\n  [#8462](https://github.com/rust-lang/rust-clippy/pull/8462)\n* [`search_is_some`]: More suggestions are now `MachineApplicable`\n  [#8536](https://github.com/rust-lang/rust-clippy/pull/8536)\n\n### Documentation Improvements\n\n* [`new_without_default`]: Document `pub` requirement for the struct and fields\n  [#8429](https://github.com/rust-lang/rust-clippy/pull/8429)\n\n## Rust 1.60\n\nReleased 2022-04-07\n\n[View all 73 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-12-31T17%3A53%3A37Z..2022-02-10T17%3A31%3A37Z+base%3Amaster)\n\n### New Lints\n\n* [`single_char_lifetime_names`]\n  [#8236](https://github.com/rust-lang/rust-clippy/pull/8236)\n* [`iter_overeager_cloned`]\n  [#8203](https://github.com/rust-lang/rust-clippy/pull/8203)\n* [`transmute_undefined_repr`]\n  [#8398](https://github.com/rust-lang/rust-clippy/pull/8398)\n* [`default_union_representation`]\n  [#8289](https://github.com/rust-lang/rust-clippy/pull/8289)\n* [`manual_bits`]\n  [#8213](https://github.com/rust-lang/rust-clippy/pull/8213)\n* [`borrow_as_ptr`]\n  [#8210](https://github.com/rust-lang/rust-clippy/pull/8210)\n\n### Moves and Deprecations\n\n* Moved [`disallowed_methods`] and [`disallowed_types`] to `style` (now warn-by-default)\n  [#8261](https://github.com/rust-lang/rust-clippy/pull/8261)\n* Rename `ref_in_deref` to [`needless_borrow`]\n  [#8217](https://github.com/rust-lang/rust-clippy/pull/8217)\n* Moved [`mutex_atomic`] to `nursery` (now allow-by-default)\n  [#8260](https://github.com/rust-lang/rust-clippy/pull/8260)\n\n### Enhancements\n\n* [`ptr_arg`]: Now takes the argument usage into account and lints for mutable references\n  [#8271](https://github.com/rust-lang/rust-clippy/pull/8271)\n* [`unused_io_amount`]: Now supports async read and write traits\n  [#8179](https://github.com/rust-lang/rust-clippy/pull/8179)\n* [`while_let_on_iterator`]: Improved detection to catch more cases\n  [#8221](https://github.com/rust-lang/rust-clippy/pull/8221)\n* [`trait_duplication_in_bounds`]: Now covers trait functions with `Self` bounds\n  [#8252](https://github.com/rust-lang/rust-clippy/pull/8252)\n* [`unwrap_used`]: Now works for `.get(i).unwrap()` and `.get_mut(i).unwrap()`\n  [#8372](https://github.com/rust-lang/rust-clippy/pull/8372)\n* [`map_clone`]: The suggestion takes `msrv` into account\n  [#8280](https://github.com/rust-lang/rust-clippy/pull/8280)\n* [`manual_bits`] and [`borrow_as_ptr`]: Now track the `clippy::msrv` attribute\n  [#8280](https://github.com/rust-lang/rust-clippy/pull/8280)\n* [`disallowed_methods`]: Now works for methods on primitive types\n  [#8112](https://github.com/rust-lang/rust-clippy/pull/8112)\n* [`not_unsafe_ptr_arg_deref`]: Now works for type aliases\n  [#8273](https://github.com/rust-lang/rust-clippy/pull/8273)\n* [`needless_question_mark`]: Now works for async functions\n  [#8311](https://github.com/rust-lang/rust-clippy/pull/8311)\n* [`iter_not_returning_iterator`]: Now handles type projections\n  [#8228](https://github.com/rust-lang/rust-clippy/pull/8228)\n* [`wrong_self_convention`]: Now detects wrong `self` references in more cases\n  [#8208](https://github.com/rust-lang/rust-clippy/pull/8208)\n* [`single_match`]: Now works for `match` statements with tuples\n  [#8322](https://github.com/rust-lang/rust-clippy/pull/8322)\n\n### False Positive Fixes\n\n* [`erasing_op`]: No longer triggers if the output type changes\n  [#8204](https://github.com/rust-lang/rust-clippy/pull/8204)\n* [`if_same_then_else`]: No longer triggers for `if let` statements\n  [#8297](https://github.com/rust-lang/rust-clippy/pull/8297)\n* [`manual_memcpy`]: No longer lints on `VecDeque`\n  [#8226](https://github.com/rust-lang/rust-clippy/pull/8226)\n* [`trait_duplication_in_bounds`]: Now takes path segments into account\n  [#8315](https://github.com/rust-lang/rust-clippy/pull/8315)\n* [`deref_addrof`]: No longer lints when the dereference or borrow occurs in different a context\n  [#8268](https://github.com/rust-lang/rust-clippy/pull/8268)\n* [`type_repetition_in_bounds`]: Now checks for full equality to prevent false positives\n  [#8224](https://github.com/rust-lang/rust-clippy/pull/8224)\n* [`ptr_arg`]: No longer lint for mutable references in traits\n  [#8369](https://github.com/rust-lang/rust-clippy/pull/8369)\n* [`implicit_clone`]: No longer lints for double references\n  [#8231](https://github.com/rust-lang/rust-clippy/pull/8231)\n* [`needless_lifetimes`]: No longer lints lifetimes for explicit `self` types\n  [#8278](https://github.com/rust-lang/rust-clippy/pull/8278)\n* [`op_ref`]: No longer lints in `BinOp` impl if that can cause recursion\n  [#8298](https://github.com/rust-lang/rust-clippy/pull/8298)\n* [`enum_variant_names`]: No longer triggers for empty variant names\n  [#8329](https://github.com/rust-lang/rust-clippy/pull/8329)\n* [`redundant_closure`]: No longer lints for `Arc<T>` or `Rc<T>`\n  [#8193](https://github.com/rust-lang/rust-clippy/pull/8193)\n* [`iter_not_returning_iterator`]: No longer lints on trait implementations but therefore on trait definitions\n  [#8228](https://github.com/rust-lang/rust-clippy/pull/8228)\n* [`single_match`]: No longer lints on exhaustive enum patterns without a wildcard\n  [#8322](https://github.com/rust-lang/rust-clippy/pull/8322)\n* [`manual_swap`]: No longer lints on cases that involve automatic dereferences\n  [#8220](https://github.com/rust-lang/rust-clippy/pull/8220)\n* [`useless_format`]: Now works for implicit named arguments\n  [#8295](https://github.com/rust-lang/rust-clippy/pull/8295)\n\n### Suggestion Fixes/Improvements\n\n* [`needless_borrow`]: Prevent mutable borrows being moved and suggest removing the borrow on method calls\n  [#8217](https://github.com/rust-lang/rust-clippy/pull/8217)\n* [`chars_next_cmp`]: Correctly escapes the suggestion\n  [#8376](https://github.com/rust-lang/rust-clippy/pull/8376)\n* [`explicit_write`]: Add suggestions for `write!`s with format arguments\n  [#8365](https://github.com/rust-lang/rust-clippy/pull/8365)\n* [`manual_memcpy`]: Suggests `copy_from_slice` when applicable\n  [#8226](https://github.com/rust-lang/rust-clippy/pull/8226)\n* [`or_fun_call`]: Improved suggestion display for long arguments\n  [#8292](https://github.com/rust-lang/rust-clippy/pull/8292)\n* [`unnecessary_cast`]: Now correctly includes the sign\n  [#8350](https://github.com/rust-lang/rust-clippy/pull/8350)\n* [`cmp_owned`]: No longer flips the comparison order\n  [#8299](https://github.com/rust-lang/rust-clippy/pull/8299)\n* [`explicit_counter_loop`]: Now correctly suggests `iter()` on references\n  [#8382](https://github.com/rust-lang/rust-clippy/pull/8382)\n\n### ICE Fixes\n\n* [`manual_split_once`]\n  [#8250](https://github.com/rust-lang/rust-clippy/pull/8250)\n\n### Documentation Improvements\n\n* [`map_flatten`]: Add documentation for the `Option` type\n  [#8354](https://github.com/rust-lang/rust-clippy/pull/8354)\n* Document that Clippy's driver might use a different code generation than rustc\n  [#8037](https://github.com/rust-lang/rust-clippy/pull/8037)\n* Clippy's lint list will now automatically focus the search box\n  [#8343](https://github.com/rust-lang/rust-clippy/pull/8343)\n\n### Others\n\n* Clippy now warns if we find multiple Clippy config files exist\n  [#8326](https://github.com/rust-lang/rust-clippy/pull/8326)\n\n## Rust 1.59\n\nReleased 2022-02-24\n\n[View all 94 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-11-04T12%3A40%3A18Z..2021-12-30T13%3A36%3A20Z+base%3Amaster)\n\n### New Lints\n\n* [`index_refutable_slice`]\n  [#7643](https://github.com/rust-lang/rust-clippy/pull/7643)\n* [`needless_splitn`]\n  [#7896](https://github.com/rust-lang/rust-clippy/pull/7896)\n* [`unnecessary_to_owned`]\n  [#7978](https://github.com/rust-lang/rust-clippy/pull/7978)\n* [`needless_late_init`]\n  [#7995](https://github.com/rust-lang/rust-clippy/pull/7995)\n* [`octal_escapes`] [#8007](https://github.com/rust-lang/rust-clippy/pull/8007)\n* [`return_self_not_must_use`]\n  [#8071](https://github.com/rust-lang/rust-clippy/pull/8071)\n* [`init_numbered_fields`]\n  [#8170](https://github.com/rust-lang/rust-clippy/pull/8170)\n\n### Moves and Deprecations\n\n* Move `if_then_panic` to `pedantic` and rename to [`manual_assert`] (now\n  allow-by-default) [#7810](https://github.com/rust-lang/rust-clippy/pull/7810)\n* Rename `disallow_type` to [`disallowed_types`] and `disallowed_method` to\n  [`disallowed_methods`]\n  [#7984](https://github.com/rust-lang/rust-clippy/pull/7984)\n* Move [`map_flatten`] to `complexity` (now warn-by-default)\n  [#8054](https://github.com/rust-lang/rust-clippy/pull/8054)\n\n### Enhancements\n\n* [`match_overlapping_arm`]: Fix false negative where after included ranges,\n  overlapping ranges weren't linted anymore\n  [#7909](https://github.com/rust-lang/rust-clippy/pull/7909)\n* [`deprecated_cfg_attr`]: Now takes the specified MSRV into account\n  [#7944](https://github.com/rust-lang/rust-clippy/pull/7944)\n* [`cast_lossless`]: Now also lints for `bool` to integer casts\n  [#7948](https://github.com/rust-lang/rust-clippy/pull/7948)\n* [`let_underscore_lock`]: Also emit lints for the `parking_lot` crate\n  [#7957](https://github.com/rust-lang/rust-clippy/pull/7957)\n* [`needless_borrow`]\n  [#7977](https://github.com/rust-lang/rust-clippy/pull/7977)\n  * Lint when a borrow is auto-dereffed more than once\n  * Lint in the trailing expression of a block for a match arm\n* [`strlen_on_c_strings`]\n  [8001](https://github.com/rust-lang/rust-clippy/pull/8001)\n  * Lint when used without a fully-qualified path\n  * Suggest removing the surrounding unsafe block when possible\n* [`non_ascii_literal`]: Now also lints on `char`s, not just `string`s\n  [#8034](https://github.com/rust-lang/rust-clippy/pull/8034)\n* [`single_char_pattern`]: Now also lints on `split_inclusive`, `split_once`,\n  `rsplit_once`, `replace`, and `replacen`\n  [#8077](https://github.com/rust-lang/rust-clippy/pull/8077)\n* [`unwrap_or_else_default`]: Now also lints on `std` constructors like\n  `Vec::new`, `HashSet::new`, and `HashMap::new`\n  [#8163](https://github.com/rust-lang/rust-clippy/pull/8163)\n* [`shadow_reuse`]: Now also lints on shadowed `if let` bindings, instead of\n  [`shadow_unrelated`]\n  [#8165](https://github.com/rust-lang/rust-clippy/pull/8165)\n\n### False Positive Fixes\n\n* [`or_fun_call`], [`unnecessary_lazy_evaluations`]: Improve heuristics, so that\n  cheap functions (e.g. calling `.len()` on a `Vec`) won't get linted anymore\n  [#7639](https://github.com/rust-lang/rust-clippy/pull/7639)\n* [`manual_split_once`]: No longer suggests code changing the original behavior\n  [#7896](https://github.com/rust-lang/rust-clippy/pull/7896)\n* Don't show [`no_effect`] or [`unnecessary_operation`] warning for unit struct\n  implementing `FnOnce`\n  [#7898](https://github.com/rust-lang/rust-clippy/pull/7898)\n* [`semicolon_if_nothing_returned`]: Fixed a bug, where the lint wrongly\n  triggered on `let-else` statements\n  [#7955](https://github.com/rust-lang/rust-clippy/pull/7955)\n* [`if_then_some_else_none`]: No longer lints if there is an early return\n  [#7980](https://github.com/rust-lang/rust-clippy/pull/7980)\n* [`needless_collect`]: No longer suggests removal of `collect` when removal\n  would create code requiring mutably borrowing a value multiple times\n  [#7982](https://github.com/rust-lang/rust-clippy/pull/7982)\n* [`shadow_same`]: Fix false positive for `async` function's params\n  [#7997](https://github.com/rust-lang/rust-clippy/pull/7997)\n* [`suboptimal_flops`]: No longer triggers in constant functions\n  [#8009](https://github.com/rust-lang/rust-clippy/pull/8009)\n* [`type_complexity`]: No longer lints on associated types in traits\n  [#8030](https://github.com/rust-lang/rust-clippy/pull/8030)\n* [`question_mark`]: No longer lints if returned object is not local\n  [#8080](https://github.com/rust-lang/rust-clippy/pull/8080)\n* [`option_if_let_else`]: No longer lint on complex sub-patterns\n  [#8086](https://github.com/rust-lang/rust-clippy/pull/8086)\n* [`blocks_in_if_conditions`]: No longer lints on empty closures\n  [#8100](https://github.com/rust-lang/rust-clippy/pull/8100)\n* [`enum_variant_names`]: No longer lint when first prefix is only a substring\n  of a camel-case word\n  [#8127](https://github.com/rust-lang/rust-clippy/pull/8127)\n* [`identity_op`]: Only lint on integral operands\n  [#8183](https://github.com/rust-lang/rust-clippy/pull/8183)\n\n### Suggestion Fixes/Improvements\n\n* [`search_is_some`]: Fix suggestion for `any()` not taking item by reference\n  [#7463](https://github.com/rust-lang/rust-clippy/pull/7463)\n* [`almost_swapped`]: Now detects if there is a `no_std` or `no_core` attribute\n  and adapts the suggestion accordingly\n  [#7877](https://github.com/rust-lang/rust-clippy/pull/7877)\n* [`redundant_pattern_matching`]: Fix suggestion for deref expressions\n  [#7949](https://github.com/rust-lang/rust-clippy/pull/7949)\n* [`explicit_counter_loop`]: Now also produces a suggestion for non-`usize`\n  types [#7950](https://github.com/rust-lang/rust-clippy/pull/7950)\n* [`manual_map`]: Fix suggestion when used with unsafe functions and blocks\n  [#7968](https://github.com/rust-lang/rust-clippy/pull/7968)\n* [`option_map_or_none`]: Suggest `map` over `and_then` when possible\n  [#7971](https://github.com/rust-lang/rust-clippy/pull/7971)\n* [`option_if_let_else`]: No longer expands macros in the suggestion\n  [#7974](https://github.com/rust-lang/rust-clippy/pull/7974)\n* [`iter_cloned_collect`]: Suggest `copied` over `cloned` when possible\n  [#8006](https://github.com/rust-lang/rust-clippy/pull/8006)\n* [`doc_markdown`]: No longer uses inline hints to improve readability of\n  suggestion [#8011](https://github.com/rust-lang/rust-clippy/pull/8011)\n* [`needless_question_mark`]: Now better explains the suggestion\n  [#8028](https://github.com/rust-lang/rust-clippy/pull/8028)\n* [`single_char_pattern`]: Escape backslash `\\` in suggestion\n  [#8067](https://github.com/rust-lang/rust-clippy/pull/8067)\n* [`needless_bool`]: Suggest `a != b` over `!(a == b)`\n  [#8117](https://github.com/rust-lang/rust-clippy/pull/8117)\n* [`iter_skip_next`]: Suggest to add a `mut` if it is necessary in order to\n  apply this lints suggestion\n  [#8133](https://github.com/rust-lang/rust-clippy/pull/8133)\n* [`neg_multiply`]: Now produces a suggestion\n  [#8144](https://github.com/rust-lang/rust-clippy/pull/8144)\n* [`needless_return`]: Now suggests the unit type `()` over an empty block `{}`\n  in match arms [#8185](https://github.com/rust-lang/rust-clippy/pull/8185)\n* [`suboptimal_flops`]: Now gives a syntactically correct suggestion for\n  `to_radians` and `to_degrees`\n  [#8187](https://github.com/rust-lang/rust-clippy/pull/8187)\n\n### ICE Fixes\n\n* [`undocumented_unsafe_blocks`]\n  [#7945](https://github.com/rust-lang/rust-clippy/pull/7945)\n  [#7988](https://github.com/rust-lang/rust-clippy/pull/7988)\n* [`unnecessary_cast`]\n  [#8167](https://github.com/rust-lang/rust-clippy/pull/8167)\n\n### Documentation Improvements\n\n* [`print_stdout`], [`print_stderr`], [`dbg_macro`]: Document how the lint level\n  can be changed crate-wide\n  [#8040](https://github.com/rust-lang/rust-clippy/pull/8040)\n* Added a note to the `README` that config changes don't apply to already\n  compiled code [#8175](https://github.com/rust-lang/rust-clippy/pull/8175)\n\n### Others\n\n* [Clippy's lint\n  list](https://rust-lang.github.io/rust-clippy/master/index.html) now displays\n  the version a lint was added. :tada:\n  [#7813](https://github.com/rust-lang/rust-clippy/pull/7813)\n* New and improved issue templates\n  [#8032](https://github.com/rust-lang/rust-clippy/pull/8032)\n* *Dev:* Add `cargo dev lint` command, to run your modified Clippy version on a\n  file [#7917](https://github.com/rust-lang/rust-clippy/pull/7917)\n\n## Rust 1.58\n\nReleased 2022-01-13\n\n[View all 68 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-10-07T09%3A49%3A18Z..2021-11-04T12%3A20%3A12Z+base%3Amaster)\n\n### Rust 1.58.1\n\n* Move [`non_send_fields_in_send_ty`] to `nursery` (now allow-by-default)\n  [#8075](https://github.com/rust-lang/rust-clippy/pull/8075)\n* [`useless_format`]: Handle implicit named arguments\n  [#8295](https://github.com/rust-lang/rust-clippy/pull/8295)\n\n### New lints\n\n* [`transmute_num_to_bytes`]\n  [#7805](https://github.com/rust-lang/rust-clippy/pull/7805)\n* [`match_str_case_mismatch`]\n  [#7806](https://github.com/rust-lang/rust-clippy/pull/7806)\n* [`format_in_format_args`], [`to_string_in_format_args`]\n  [#7743](https://github.com/rust-lang/rust-clippy/pull/7743)\n* [`uninit_vec`]\n  [#7682](https://github.com/rust-lang/rust-clippy/pull/7682)\n* [`fn_to_numeric_cast_any`]\n  [#7705](https://github.com/rust-lang/rust-clippy/pull/7705)\n* [`undocumented_unsafe_blocks`]\n  [#7748](https://github.com/rust-lang/rust-clippy/pull/7748)\n* [`trailing_empty_array`]\n  [#7838](https://github.com/rust-lang/rust-clippy/pull/7838)\n* [`string_slice`]\n  [#7878](https://github.com/rust-lang/rust-clippy/pull/7878)\n\n### Moves or deprecations of lints\n\n* Move [`non_send_fields_in_send_ty`] to `suspicious`\n  [#7874](https://github.com/rust-lang/rust-clippy/pull/7874)\n* Move [`non_ascii_literal`] to `restriction`\n  [#7907](https://github.com/rust-lang/rust-clippy/pull/7907)\n\n### Changes that expand what code existing lints cover\n\n* [`question_mark`] now covers `Result`\n  [#7840](https://github.com/rust-lang/rust-clippy/pull/7840)\n* Make [`useless_format`] recognize bare `format!(\"\")`\n  [#7801](https://github.com/rust-lang/rust-clippy/pull/7801)\n* Lint on underscored variables with no side effects in [`no_effect`]\n  [#7775](https://github.com/rust-lang/rust-clippy/pull/7775)\n* Expand [`match_ref_pats`] to check for multiple reference patterns\n  [#7800](https://github.com/rust-lang/rust-clippy/pull/7800)\n\n### False positive fixes\n\n* Fix false positive of [`implicit_saturating_sub`] with `else` clause\n  [#7832](https://github.com/rust-lang/rust-clippy/pull/7832)\n* Fix [`question_mark`] when there is call in conditional predicate\n  [#7860](https://github.com/rust-lang/rust-clippy/pull/7860)\n* [`mut_mut`] no longer lints when type is defined in external macros\n  [#7795](https://github.com/rust-lang/rust-clippy/pull/7795)\n* Avoid [`eq_op`] in test functions\n  [#7811](https://github.com/rust-lang/rust-clippy/pull/7811)\n* [`cast_possible_truncation`] no longer lints when cast is coming from `signum`\n  method call [#7850](https://github.com/rust-lang/rust-clippy/pull/7850)\n* [`match_str_case_mismatch`] no longer lints on uncased characters\n  [#7865](https://github.com/rust-lang/rust-clippy/pull/7865)\n* [`ptr_arg`] no longer lints references to type aliases\n  [#7890](https://github.com/rust-lang/rust-clippy/pull/7890)\n* [`missing_safety_doc`] now also accepts \"implementation safety\" headers\n  [#7856](https://github.com/rust-lang/rust-clippy/pull/7856)\n* [`missing_safety_doc`] no longer lints if any parent has `#[doc(hidden)]`\n  attribute [#7849](https://github.com/rust-lang/rust-clippy/pull/7849)\n* [`if_not_else`] now ignores else-if statements\n  [#7895](https://github.com/rust-lang/rust-clippy/pull/7895)\n* Avoid linting [`cast_possible_truncation`] on bit-reducing operations\n  [#7819](https://github.com/rust-lang/rust-clippy/pull/7819)\n* Avoid linting [`field_reassign_with_default`] when `Drop` and `Copy` are\n  involved [#7794](https://github.com/rust-lang/rust-clippy/pull/7794)\n* [`unnecessary_sort_by`] now checks if argument implements `Ord` trait\n  [#7824](https://github.com/rust-lang/rust-clippy/pull/7824)\n* Fix false positive in [`match_overlapping_arm`]\n  [#7847](https://github.com/rust-lang/rust-clippy/pull/7847)\n* Prevent [`needless_lifetimes`] false positive in `async` function definition\n  [#7901](https://github.com/rust-lang/rust-clippy/pull/7901)\n\n### Suggestion fixes/improvements\n\n* Keep an initial `::` when [`doc_markdown`] suggests to use ticks\n  [#7916](https://github.com/rust-lang/rust-clippy/pull/7916)\n* Add a machine applicable suggestion for the [`doc_markdown`] missing backticks\n  lint [#7904](https://github.com/rust-lang/rust-clippy/pull/7904)\n* [`equatable_if_let`] no longer expands macros in the suggestion\n  [#7788](https://github.com/rust-lang/rust-clippy/pull/7788)\n* Make [`shadow_reuse`] suggestion less verbose\n  [#7782](https://github.com/rust-lang/rust-clippy/pull/7782)\n\n### ICE fixes\n\n* Fix ICE in [`enum_variant_names`]\n  [#7873](https://github.com/rust-lang/rust-clippy/pull/7873)\n* Fix ICE in [`undocumented_unsafe_blocks`]\n  [#7891](https://github.com/rust-lang/rust-clippy/pull/7891)\n\n### Documentation improvements\n\n* Fixed naive doc formatting for `#[must_use]` lints ([`must_use_unit`],\n  [`double_must_use`], [`must_use_candidate`], [`let_underscore_must_use`])\n  [#7827](https://github.com/rust-lang/rust-clippy/pull/7827)\n* Fix typo in example for [`match_result_ok`]\n  [#7815](https://github.com/rust-lang/rust-clippy/pull/7815)\n\n### Others\n\n* Allow giving reasons for [`disallowed_types`]\n  [#7791](https://github.com/rust-lang/rust-clippy/pull/7791)\n* Fix [`manual_assert`] and [`match_wild_err_arm`] for `#![no_std]` and Rust\n  2021. [#7851](https://github.com/rust-lang/rust-clippy/pull/7851)\n* Fix regression in [`semicolon_if_nothing_returned`] on macros containing while\n  loops [#7789](https://github.com/rust-lang/rust-clippy/pull/7789)\n* Added a new configuration `literal-suffix-style` to enforce a certain style\n  writing [`unseparated_literal_suffix`]\n  [#7726](https://github.com/rust-lang/rust-clippy/pull/7726)\n\n## Rust 1.57\n\nReleased 2021-12-02\n\n[View all 148 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-08-12T20%3A36%3A04Z..2021-11-03T17%3A57%3A59Z+base%3Amaster)\n\n### New Lints\n\n* [`negative_feature_names`]\n  [#7539](https://github.com/rust-lang/rust-clippy/pull/7539)\n* [`redundant_feature_names`]\n  [#7539](https://github.com/rust-lang/rust-clippy/pull/7539)\n* [`mod_module_files`]\n  [#7543](https://github.com/rust-lang/rust-clippy/pull/7543)\n* [`self_named_module_files`]\n  [#7543](https://github.com/rust-lang/rust-clippy/pull/7543)\n* [`manual_split_once`]\n  [#7565](https://github.com/rust-lang/rust-clippy/pull/7565)\n* [`derivable_impls`]\n  [#7570](https://github.com/rust-lang/rust-clippy/pull/7570)\n* [`needless_option_as_deref`]\n  [#7596](https://github.com/rust-lang/rust-clippy/pull/7596)\n* [`iter_not_returning_iterator`]\n  [#7610](https://github.com/rust-lang/rust-clippy/pull/7610)\n* [`same_name_method`]\n  [#7653](https://github.com/rust-lang/rust-clippy/pull/7653)\n* [`manual_assert`] [#7669](https://github.com/rust-lang/rust-clippy/pull/7669)\n* [`non_send_fields_in_send_ty`]\n  [#7709](https://github.com/rust-lang/rust-clippy/pull/7709)\n* [`equatable_if_let`]\n  [#7762](https://github.com/rust-lang/rust-clippy/pull/7762)\n\n### Moves and Deprecations\n\n* Move [`shadow_unrelated`] to `restriction`\n  [#7338](https://github.com/rust-lang/rust-clippy/pull/7338)\n* Move [`option_if_let_else`] to `nursery`\n  [#7568](https://github.com/rust-lang/rust-clippy/pull/7568)\n* Move [`branches_sharing_code`] to `nursery`\n  [#7595](https://github.com/rust-lang/rust-clippy/pull/7595)\n* Rename `if_let_some_result` to [`match_result_ok`] which now also handles\n  `while let` cases [#7608](https://github.com/rust-lang/rust-clippy/pull/7608)\n* Move [`many_single_char_names`] to `pedantic`\n  [#7671](https://github.com/rust-lang/rust-clippy/pull/7671)\n* Move [`float_cmp`] to `pedantic`\n  [#7692](https://github.com/rust-lang/rust-clippy/pull/7692)\n* Rename `box_vec` to [`box_collection`] and lint on more general cases\n  [#7693](https://github.com/rust-lang/rust-clippy/pull/7693)\n* Uplift `invalid_atomic_ordering` to rustc\n  [rust-lang/rust#84039](https://github.com/rust-lang/rust/pull/84039)\n\n### Enhancements\n\n* Rewrite the `shadow*` lints, so that they find a lot more shadows and are not\n  limited to certain patterns\n  [#7338](https://github.com/rust-lang/rust-clippy/pull/7338)\n* The `avoid-breaking-exported-api` configuration now also works for\n  [`box_collection`], [`redundant_allocation`], [`rc_buffer`], [`vec_box`],\n  [`option_option`], [`linkedlist`], [`rc_mutex`]\n  [#7560](https://github.com/rust-lang/rust-clippy/pull/7560)\n* [`unnecessary_unwrap`]: Now also checks for `expect`s\n  [#7584](https://github.com/rust-lang/rust-clippy/pull/7584)\n* [`disallowed_methods`]: Allow adding a reason that will be displayed with the\n  lint message\n  [#7621](https://github.com/rust-lang/rust-clippy/pull/7621)\n* [`approx_constant`]: Now checks the MSRV for `LOG10_2` and `LOG2_10`\n  [#7629](https://github.com/rust-lang/rust-clippy/pull/7629)\n* [`approx_constant`]: Add `TAU`\n  [#7642](https://github.com/rust-lang/rust-clippy/pull/7642)\n* [`needless_borrow`]: Now also lints on needless mutable borrows\n  [#7657](https://github.com/rust-lang/rust-clippy/pull/7657)\n* [`missing_safety_doc`]: Now also lints on unsafe traits\n  [#7734](https://github.com/rust-lang/rust-clippy/pull/7734)\n\n### False Positive Fixes\n\n* [`manual_map`]: No longer lints when the option is borrowed in the match and\n  also consumed in the arm\n  [#7531](https://github.com/rust-lang/rust-clippy/pull/7531)\n* [`filter_next`]: No longer lints if `filter` method is not the\n  `Iterator::filter` method\n  [#7562](https://github.com/rust-lang/rust-clippy/pull/7562)\n* [`manual_flatten`]: No longer lints if expression is used after `if let`\n  [#7566](https://github.com/rust-lang/rust-clippy/pull/7566)\n* [`option_if_let_else`]: Multiple fixes\n  [#7573](https://github.com/rust-lang/rust-clippy/pull/7573)\n  * `break` and `continue` statements local to the would-be closure are\n      allowed\n  * Don't lint in const contexts\n  * Don't lint when yield expressions are used\n  * Don't lint when the captures made by the would-be closure conflict with\n      the other branch\n  * Don't lint when a field of a local is used when the type could be\n      potentially moved from\n  * In some cases, don't lint when scrutinee expression conflicts with the\n      captures of the would-be closure\n* [`redundant_allocation`]: No longer lints on `Box<Box<dyn T>>` which replaces\n  wide pointers with thin pointers\n  [#7592](https://github.com/rust-lang/rust-clippy/pull/7592)\n* [`bool_assert_comparison`]: No longer lints on types that do not implement the\n  `Not` trait with `Output = bool`\n  [#7605](https://github.com/rust-lang/rust-clippy/pull/7605)\n* [`mut_range_bound`]: No longer lints on range bound mutations, that are\n  immediately followed by a `break;`\n  [#7607](https://github.com/rust-lang/rust-clippy/pull/7607)\n* [`mutable_key_type`]: Improve accuracy and document remaining false positives\n  and false negatives\n  [#7640](https://github.com/rust-lang/rust-clippy/pull/7640)\n* [`redundant_closure`]: Rewrite the lint to fix various false positives and\n  false negatives [#7661](https://github.com/rust-lang/rust-clippy/pull/7661)\n* [`large_enum_variant`]: No longer wrongly identifies the second largest\n  variant [#7677](https://github.com/rust-lang/rust-clippy/pull/7677)\n* [`needless_return`]: No longer lints on let-else expressions\n  [#7685](https://github.com/rust-lang/rust-clippy/pull/7685)\n* [`suspicious_else_formatting`]: No longer lints in proc-macros\n  [#7707](https://github.com/rust-lang/rust-clippy/pull/7707)\n* [`excessive_precision`]: No longer lints when in some cases the float was\n  already written in the shortest form\n  [#7722](https://github.com/rust-lang/rust-clippy/pull/7722)\n* [`doc_markdown`]: No longer lints on intra-doc links\n  [#7772](https://github.com/rust-lang/rust-clippy/pull/7772)\n\n### Suggestion Fixes/Improvements\n\n* [`unnecessary_operation`]: Recommend using an `assert!` instead of using a\n  function call in an indexing operation\n  [#7453](https://github.com/rust-lang/rust-clippy/pull/7453)\n* [`manual_split_once`]: Produce semantically equivalent suggestion when\n  `rsplitn` is used [#7663](https://github.com/rust-lang/rust-clippy/pull/7663)\n* [`while_let_on_iterator`]: Produce correct suggestion when using `&mut`\n  [#7690](https://github.com/rust-lang/rust-clippy/pull/7690)\n* [`manual_assert`]: No better handles complex conditions\n  [#7741](https://github.com/rust-lang/rust-clippy/pull/7741)\n* Correctly handle signs in exponents in numeric literals lints\n  [#7747](https://github.com/rust-lang/rust-clippy/pull/7747)\n* [`suspicious_map`]: Now also suggests to use `inspect` as an alternative\n  [#7770](https://github.com/rust-lang/rust-clippy/pull/7770)\n* Drop exponent from suggestion if it is 0 in numeric literals lints\n  [#7774](https://github.com/rust-lang/rust-clippy/pull/7774)\n\n### ICE Fixes\n\n* [`implicit_hasher`]\n  [#7761](https://github.com/rust-lang/rust-clippy/pull/7761)\n\n### Others\n\n* Clippy now uses the 2021\n  [Edition!](https://www.youtube.com/watch?v=q0aNduqb2Ro)\n  [#7664](https://github.com/rust-lang/rust-clippy/pull/7664)\n\n## Rust 1.56\n\nReleased 2021-10-21\n\n[View all 38 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-07-19T14%3A33%3A33Z..2021-08-12T09%3A28%3A38Z+base%3Amaster)\n\n### New Lints\n\n* [`unwrap_or_else_default`]\n  [#7516](https://github.com/rust-lang/rust-clippy/pull/7516)\n\n### Enhancements\n\n* [`needless_continue`]: Now also lints in `loop { continue; }` case\n  [#7477](https://github.com/rust-lang/rust-clippy/pull/7477)\n* [`disallowed_types`]: Now also primitive types can be disallowed\n  [#7488](https://github.com/rust-lang/rust-clippy/pull/7488)\n* [`manual_swap`]: Now also lints on xor swaps\n  [#7506](https://github.com/rust-lang/rust-clippy/pull/7506)\n* [`map_flatten`]: Now also lints on the `Result` type\n  [#7522](https://github.com/rust-lang/rust-clippy/pull/7522)\n* [`no_effect`]: Now also lints on inclusive ranges\n  [#7556](https://github.com/rust-lang/rust-clippy/pull/7556)\n\n### False Positive Fixes\n\n* [`nonstandard_macro_braces`]: No longer lints on similar named nested macros\n  [#7478](https://github.com/rust-lang/rust-clippy/pull/7478)\n* [`too_many_lines`]: No longer lints in closures to avoid duplicated diagnostics\n  [#7534](https://github.com/rust-lang/rust-clippy/pull/7534)\n* [`similar_names`]: No longer complains about `iter` and `item` being too\n  similar [#7546](https://github.com/rust-lang/rust-clippy/pull/7546)\n\n### Suggestion Fixes/Improvements\n\n* [`similar_names`]: No longer suggests to insert or add an underscore as a fix\n  [#7221](https://github.com/rust-lang/rust-clippy/pull/7221)\n* [`new_without_default`]: No longer shows the full qualified type path when\n  suggesting adding a `Default` implementation\n  [#7493](https://github.com/rust-lang/rust-clippy/pull/7493)\n* [`while_let_on_iterator`]: Now suggests re-borrowing mutable references\n  [#7520](https://github.com/rust-lang/rust-clippy/pull/7520)\n* [`extend_with_drain`]: Improve code suggestion for mutable and immutable\n  references [#7533](https://github.com/rust-lang/rust-clippy/pull/7533)\n* [`trivially_copy_pass_by_ref`]: Now properly handles `Self` type\n  [#7535](https://github.com/rust-lang/rust-clippy/pull/7535)\n* [`never_loop`]: Now suggests using `if let` instead of a `for` loop when\n  applicable [#7541](https://github.com/rust-lang/rust-clippy/pull/7541)\n\n### Documentation Improvements\n\n* Clippy now uses a lint to generate its lint documentation. [Lints all the way\n  down](https://en.wikipedia.org/wiki/Turtles_all_the_way_down).\n  [#7502](https://github.com/rust-lang/rust-clippy/pull/7502)\n* Reworked Clippy's website:\n  [#7172](https://github.com/rust-lang/rust-clippy/issues/7172)\n  [#7279](https://github.com/rust-lang/rust-clippy/pull/7279)\n  * Added applicability information about lints\n  * Added a link to jump into the implementation\n  * Improved loading times\n  * Adapted some styling\n* `cargo clippy --help` now also explains the `--fix` and `--no-deps` flag\n  [#7492](https://github.com/rust-lang/rust-clippy/pull/7492)\n* [`unnested_or_patterns`]: Removed `or_patterns` feature gate in the code\n  example [#7507](https://github.com/rust-lang/rust-clippy/pull/7507)\n\n## Rust 1.55\n\nReleased 2021-09-09\n\n[View all 83 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-06-03T07%3A23%3A59Z..2021-07-29T11%3A47%3A32Z+base%3Amaster)\n\n### Important Changes\n\n* Stabilized `cargo clippy --fix` :tada:\n  [#7405](https://github.com/rust-lang/rust-clippy/pull/7405)\n\n### New Lints\n\n* [`rc_mutex`]\n  [#7316](https://github.com/rust-lang/rust-clippy/pull/7316)\n* [`nonstandard_macro_braces`]\n  [#7299](https://github.com/rust-lang/rust-clippy/pull/7299)\n* [`strlen_on_c_strings`]\n  [#7243](https://github.com/rust-lang/rust-clippy/pull/7243)\n* [`self_named_constructors`]\n  [#7403](https://github.com/rust-lang/rust-clippy/pull/7403)\n* [`disallowed_script_idents`]\n  [#7400](https://github.com/rust-lang/rust-clippy/pull/7400)\n* [`disallowed_types`]\n  [#7315](https://github.com/rust-lang/rust-clippy/pull/7315)\n* [`missing_enforced_import_renames`]\n  [#7300](https://github.com/rust-lang/rust-clippy/pull/7300)\n* [`extend_with_drain`]\n  [#7270](https://github.com/rust-lang/rust-clippy/pull/7270)\n\n### Moves and Deprecations\n\n* Moved [`from_iter_instead_of_collect`] to `pedantic`\n  [#7375](https://github.com/rust-lang/rust-clippy/pull/7375)\n* Added `suspicious` as a new lint group for *code that is most likely wrong or useless*\n  [#7350](https://github.com/rust-lang/rust-clippy/pull/7350)\n  * Moved [`blanket_clippy_restriction_lints`] to `suspicious`\n  * Moved [`empty_loop`] to `suspicious`\n  * Moved [`eval_order_dependence`] to `suspicious`\n  * Moved [`float_equality_without_abs`] to `suspicious`\n  * Moved [`for_loops_over_fallibles`] to `suspicious`\n  * Moved [`misrefactored_assign_op`] to `suspicious`\n  * Moved [`mut_range_bound`] to `suspicious`\n  * Moved [`mutable_key_type`] to `suspicious`\n  * Moved [`suspicious_arithmetic_impl`] to `suspicious`\n  * Moved [`suspicious_assignment_formatting`] to `suspicious`\n  * Moved [`suspicious_else_formatting`] to `suspicious`\n  * Moved [`suspicious_map`] to `suspicious`\n  * Moved [`suspicious_op_assign_impl`] to `suspicious`\n  * Moved [`suspicious_unary_op_formatting`] to `suspicious`\n\n### Enhancements\n\n* [`while_let_on_iterator`]: Now suggests `&mut iter` inside closures\n  [#7262](https://github.com/rust-lang/rust-clippy/pull/7262)\n* [`doc_markdown`]:\n  * Now detects unbalanced ticks\n    [#7357](https://github.com/rust-lang/rust-clippy/pull/7357)\n  * Add `FreeBSD` to the default configuration as an allowed identifier\n    [#7334](https://github.com/rust-lang/rust-clippy/pull/7334)\n* [`wildcard_enum_match_arm`], [`match_wildcard_for_single_variants`]: Now allows wildcards for enums with unstable\n  or hidden variants\n  [#7407](https://github.com/rust-lang/rust-clippy/pull/7407)\n* [`redundant_allocation`]: Now additionally supports the `Arc<>` type\n  [#7308](https://github.com/rust-lang/rust-clippy/pull/7308)\n* [`disallowed_names`]: Now allows disallowed names in test code\n  [#7379](https://github.com/rust-lang/rust-clippy/pull/7379)\n* [`redundant_closure`]: Suggests `&mut` for `FnMut`\n  [#7437](https://github.com/rust-lang/rust-clippy/pull/7437)\n* [`disallowed_methods`], [`disallowed_types`]: The configuration values `disallowed-method` and `disallowed-type`\n  no longer require fully qualified paths\n  [#7345](https://github.com/rust-lang/rust-clippy/pull/7345)\n* [`zst_offset`]: Fixed lint invocation after it was accidentally suppressed\n  [#7396](https://github.com/rust-lang/rust-clippy/pull/7396)\n\n### False Positive Fixes\n\n* [`default_numeric_fallback`]: No longer lints on float literals as function arguments\n  [#7446](https://github.com/rust-lang/rust-clippy/pull/7446)\n* [`use_self`]: No longer lints on type parameters\n  [#7288](https://github.com/rust-lang/rust-clippy/pull/7288)\n* [`unimplemented`]: Now ignores the `assert` and `debug_assert` macros\n  [#7439](https://github.com/rust-lang/rust-clippy/pull/7439)\n* [`branches_sharing_code`]: Now always checks for block expressions\n  [#7462](https://github.com/rust-lang/rust-clippy/pull/7462)\n* [`field_reassign_with_default`]: No longer triggers in macros\n  [#7160](https://github.com/rust-lang/rust-clippy/pull/7160)\n* [`redundant_clone`]: No longer lints on required clones for borrowed data\n  [#7346](https://github.com/rust-lang/rust-clippy/pull/7346)\n* [`default_numeric_fallback`]: No longer triggers in external macros\n  [#7325](https://github.com/rust-lang/rust-clippy/pull/7325)\n* [`needless_bool`]: No longer lints in macros\n  [#7442](https://github.com/rust-lang/rust-clippy/pull/7442)\n* [`useless_format`]: No longer triggers when additional text is being appended\n  [#7442](https://github.com/rust-lang/rust-clippy/pull/7442)\n* [`assertions_on_constants`]: `cfg!(...)` is no longer considered to be a constant\n  [#7319](https://github.com/rust-lang/rust-clippy/pull/7319)\n\n### Suggestion Fixes/Improvements\n\n* [`needless_collect`]: Now show correct lint messages for shadowed values\n  [#7289](https://github.com/rust-lang/rust-clippy/pull/7289)\n* [`wrong_pub_self_convention`]: The deprecated message now suggest the correct configuration value\n  [#7382](https://github.com/rust-lang/rust-clippy/pull/7382)\n* [`semicolon_if_nothing_returned`]: Allow missing semicolon in blocks with only one expression\n  [#7326](https://github.com/rust-lang/rust-clippy/pull/7326)\n\n### ICE Fixes\n\n* [`zero_sized_map_values`]\n  [#7470](https://github.com/rust-lang/rust-clippy/pull/7470)\n* [`redundant_pattern_matching`]\n  [#7471](https://github.com/rust-lang/rust-clippy/pull/7471)\n* [`modulo_one`]\n  [#7473](https://github.com/rust-lang/rust-clippy/pull/7473)\n* [`use_self`]\n  [#7428](https://github.com/rust-lang/rust-clippy/pull/7428)\n\n## Rust 1.54\n\nReleased 2021-07-29\n\n[View all 74 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-04-27T23%3A51%3A18Z..2021-06-03T06%3A54%3A07Z+base%3Amaster)\n\n### New Lints\n\n* [`ref_binding_to_reference`]\n  [#7105](https://github.com/rust-lang/rust-clippy/pull/7105)\n* [`needless_bitwise_bool`]\n  [#7133](https://github.com/rust-lang/rust-clippy/pull/7133)\n* [`unused_async`] [#7225](https://github.com/rust-lang/rust-clippy/pull/7225)\n* [`manual_str_repeat`]\n  [#7265](https://github.com/rust-lang/rust-clippy/pull/7265)\n* [`suspicious_splitn`]\n  [#7292](https://github.com/rust-lang/rust-clippy/pull/7292)\n\n### Moves and Deprecations\n\n* Deprecate `pub_enum_variant_names` and `wrong_pub_self_convention` in favor of\n  the new `avoid-breaking-exported-api` config option (see\n  [Enhancements](#1-54-enhancements))\n  [#7187](https://github.com/rust-lang/rust-clippy/pull/7187)\n* Move [`inconsistent_struct_constructor`] to `pedantic`\n  [#7193](https://github.com/rust-lang/rust-clippy/pull/7193)\n* Move [`needless_borrow`] to `style` (now warn-by-default)\n  [#7254](https://github.com/rust-lang/rust-clippy/pull/7254)\n* Move [`suspicious_operation_groupings`] to `nursery`\n  [#7266](https://github.com/rust-lang/rust-clippy/pull/7266)\n* Move [`semicolon_if_nothing_returned`] to `pedantic`\n  [#7268](https://github.com/rust-lang/rust-clippy/pull/7268)\n\n### Enhancements <a name=\"1-54-enhancements\"></a>\n\n* [`while_let_on_iterator`]: Now also lints in nested loops\n  [#6966](https://github.com/rust-lang/rust-clippy/pull/6966)\n* [`single_char_pattern`]: Now also lints on `strip_prefix` and `strip_suffix`\n  [#7156](https://github.com/rust-lang/rust-clippy/pull/7156)\n* [`needless_collect`]: Now also lints on assignments with type annotations\n  [#7163](https://github.com/rust-lang/rust-clippy/pull/7163)\n* [`if_then_some_else_none`]: Now works with the MSRV config\n  [#7177](https://github.com/rust-lang/rust-clippy/pull/7177)\n* Add `avoid-breaking-exported-api` config option for the lints\n  [`enum_variant_names`], [`large_types_passed_by_value`],\n  [`trivially_copy_pass_by_ref`], [`unnecessary_wraps`],\n  [`upper_case_acronyms`], and [`wrong_self_convention`]. We recommend to set\n  this configuration option to `false` before a major release (1.0/2.0/...) to\n  clean up the API [#7187](https://github.com/rust-lang/rust-clippy/pull/7187)\n* [`needless_collect`]: Now lints on even more data structures\n  [#7188](https://github.com/rust-lang/rust-clippy/pull/7188)\n* [`missing_docs_in_private_items`]: No longer sees `#[<name> = \"<value>\"]` like\n  attributes as sufficient documentation\n  [#7281](https://github.com/rust-lang/rust-clippy/pull/7281)\n* [`needless_collect`], [`short_circuit_statement`], [`unnecessary_operation`]:\n  Now work as expected when used with `allow`\n  [#7282](https://github.com/rust-lang/rust-clippy/pull/7282)\n\n### False Positive Fixes\n\n* [`implicit_return`]: Now takes all diverging functions in account to avoid\n  false positives [#6951](https://github.com/rust-lang/rust-clippy/pull/6951)\n* [`while_let_on_iterator`]: No longer lints when the iterator is a struct field\n  and the struct is used in the loop\n  [#6966](https://github.com/rust-lang/rust-clippy/pull/6966)\n* [`multiple_inherent_impl`]: No longer lints with generic arguments\n  [#7089](https://github.com/rust-lang/rust-clippy/pull/7089)\n* [`comparison_chain`]: No longer lints in a `const` context\n  [#7118](https://github.com/rust-lang/rust-clippy/pull/7118)\n* [`while_immutable_condition`]: Fix false positive where mutation in the loop\n  variable wasn't picked up\n  [#7144](https://github.com/rust-lang/rust-clippy/pull/7144)\n* [`default_trait_access`]: No longer lints in macros\n  [#7150](https://github.com/rust-lang/rust-clippy/pull/7150)\n* [`needless_question_mark`]: No longer lints when the inner value is implicitly\n  dereferenced [#7165](https://github.com/rust-lang/rust-clippy/pull/7165)\n* [`unused_unit`]: No longer lints when multiple macro contexts are involved\n  [#7167](https://github.com/rust-lang/rust-clippy/pull/7167)\n* [`eval_order_dependence`]: Fix false positive in async context\n  [#7174](https://github.com/rust-lang/rust-clippy/pull/7174)\n* [`unnecessary_filter_map`]: No longer lints if the `filter_map` changes the\n  type [#7175](https://github.com/rust-lang/rust-clippy/pull/7175)\n* [`wrong_self_convention`]: No longer lints in trait implementations of\n  non-`Copy` types [#7182](https://github.com/rust-lang/rust-clippy/pull/7182)\n* [`suboptimal_flops`]: No longer lints on `powi(2)`\n  [#7201](https://github.com/rust-lang/rust-clippy/pull/7201)\n* [`wrong_self_convention`]: No longer lints if there is no implicit `self`\n  [#7215](https://github.com/rust-lang/rust-clippy/pull/7215)\n* [`option_if_let_else`]: No longer lints on `else if let` pattern\n  [#7216](https://github.com/rust-lang/rust-clippy/pull/7216)\n* [`use_self`], [`useless_conversion`]: Fix false positives when generic\n  arguments are involved\n  [#7223](https://github.com/rust-lang/rust-clippy/pull/7223)\n* [`manual_unwrap_or`]: Fix false positive with deref coercion\n  [#7233](https://github.com/rust-lang/rust-clippy/pull/7233)\n* [`similar_names`]: No longer lints on `wparam`/`lparam`\n  [#7255](https://github.com/rust-lang/rust-clippy/pull/7255)\n* [`redundant_closure`]: No longer lints on using the `vec![]` macro in a\n  closure [#7263](https://github.com/rust-lang/rust-clippy/pull/7263)\n\n### Suggestion Fixes/Improvements\n\n* [`implicit_return`]\n  [#6951](https://github.com/rust-lang/rust-clippy/pull/6951)\n  * Fix suggestion for async functions\n  * Improve suggestion with macros\n  * Suggest to change `break` to `return` when appropriate\n* [`while_let_on_iterator`]: Now suggests `&mut iter` when necessary\n  [#6966](https://github.com/rust-lang/rust-clippy/pull/6966)\n* [`match_single_binding`]: Improve suggestion when match scrutinee has side\n  effects [#7095](https://github.com/rust-lang/rust-clippy/pull/7095)\n* [`needless_borrow`]: Now suggests to also change usage sites as needed\n  [#7105](https://github.com/rust-lang/rust-clippy/pull/7105)\n* [`write_with_newline`]: Improve suggestion when only `\\n` is written to the\n  buffer [#7183](https://github.com/rust-lang/rust-clippy/pull/7183)\n* [`from_iter_instead_of_collect`]: The suggestion is now auto applicable also\n  when a `<_ as Trait>::_` is involved\n  [#7264](https://github.com/rust-lang/rust-clippy/pull/7264)\n* [`not_unsafe_ptr_arg_deref`]: Improved error message\n  [#7294](https://github.com/rust-lang/rust-clippy/pull/7294)\n\n### ICE Fixes\n\n* Fix ICE when running Clippy on `libstd`\n  [#7140](https://github.com/rust-lang/rust-clippy/pull/7140)\n* [`implicit_return`]\n  [#7242](https://github.com/rust-lang/rust-clippy/pull/7242)\n\n## Rust 1.53\n\nReleased 2021-06-17\n\n[View all 126 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-03-12T22%3A49%3A20Z..2021-04-27T14%3A38%3A20Z+base%3Amaster)\n\n### New Lints\n\n* [`option_filter_map`]\n  [#6342](https://github.com/rust-lang/rust-clippy/pull/6342)\n* [`branches_sharing_code`]\n  [#6463](https://github.com/rust-lang/rust-clippy/pull/6463)\n* [`needless_for_each`]\n  [#6706](https://github.com/rust-lang/rust-clippy/pull/6706)\n* [`if_then_some_else_none`]\n  [#6859](https://github.com/rust-lang/rust-clippy/pull/6859)\n* [`non_octal_unix_permissions`]\n  [#7001](https://github.com/rust-lang/rust-clippy/pull/7001)\n* [`unnecessary_self_imports`]\n  [#7072](https://github.com/rust-lang/rust-clippy/pull/7072)\n* [`bool_assert_comparison`]\n  [#7083](https://github.com/rust-lang/rust-clippy/pull/7083)\n* [`cloned_instead_of_copied`]\n  [#7098](https://github.com/rust-lang/rust-clippy/pull/7098)\n* [`flat_map_option`]\n  [#7101](https://github.com/rust-lang/rust-clippy/pull/7101)\n\n### Moves and Deprecations\n\n* Deprecate [`filter_map`] lint\n  [#7059](https://github.com/rust-lang/rust-clippy/pull/7059)\n* Move [`transmute_ptr_to_ptr`] to `pedantic`\n  [#7102](https://github.com/rust-lang/rust-clippy/pull/7102)\n\n### Enhancements\n\n* [`mem_replace_with_default`]: Also lint on common std constructors\n  [#6820](https://github.com/rust-lang/rust-clippy/pull/6820)\n* [`wrong_self_convention`]: Also lint on `to_*_mut` methods\n  [#6828](https://github.com/rust-lang/rust-clippy/pull/6828)\n* [`wildcard_enum_match_arm`], [`match_wildcard_for_single_variants`]:\n  [#6863](https://github.com/rust-lang/rust-clippy/pull/6863)\n  * Attempt to find a common path prefix in suggestion\n  * Don't lint on `Option` and `Result`\n  * Consider `Self` prefix\n* [`explicit_deref_methods`]: Also lint on chained `deref` calls\n  [#6865](https://github.com/rust-lang/rust-clippy/pull/6865)\n* [`or_fun_call`]: Also lint on `unsafe` blocks\n  [#6928](https://github.com/rust-lang/rust-clippy/pull/6928)\n* [`vec_box`], [`linkedlist`], [`option_option`]: Also lint in `const` and\n  `static` items [#6938](https://github.com/rust-lang/rust-clippy/pull/6938)\n* [`search_is_some`]: Also check for `is_none`\n  [#6942](https://github.com/rust-lang/rust-clippy/pull/6942)\n* [`string_lit_as_bytes`]: Also lint on `into_bytes`\n  [#6959](https://github.com/rust-lang/rust-clippy/pull/6959)\n* [`len_without_is_empty`]: Also lint if function signatures of `len` and\n  `is_empty` don't match\n  [#6980](https://github.com/rust-lang/rust-clippy/pull/6980)\n* [`redundant_pattern_matching`]: Also lint if the pattern is a `&` pattern\n  [#6991](https://github.com/rust-lang/rust-clippy/pull/6991)\n* [`clone_on_copy`]: Also lint on chained method calls taking `self` by value\n  [#7000](https://github.com/rust-lang/rust-clippy/pull/7000)\n* [`missing_panics_doc`]: Also lint on `assert_eq!` and `assert_ne!`\n  [#7029](https://github.com/rust-lang/rust-clippy/pull/7029)\n* [`needless_return`]: Also lint in `async` functions\n  [#7067](https://github.com/rust-lang/rust-clippy/pull/7067)\n* [`unused_io_amount`]: Also lint on expressions like `_.read().ok()?`\n  [#7100](https://github.com/rust-lang/rust-clippy/pull/7100)\n* [`iter_cloned_collect`]: Also lint on large arrays, since const-generics are\n  now stable [#7138](https://github.com/rust-lang/rust-clippy/pull/7138)\n\n### False Positive Fixes\n\n* [`upper_case_acronyms`]: No longer lints on public items\n  [#6805](https://github.com/rust-lang/rust-clippy/pull/6805)\n* [`suspicious_map`]: No longer lints when side effects may occur inside the\n  `map` call [#6831](https://github.com/rust-lang/rust-clippy/pull/6831)\n* [`manual_map`], [`manual_unwrap_or`]: No longer lints in `const` functions\n  [#6917](https://github.com/rust-lang/rust-clippy/pull/6917)\n* [`wrong_self_convention`]: Now respects `Copy` types\n  [#6924](https://github.com/rust-lang/rust-clippy/pull/6924)\n* [`needless_question_mark`]: No longer lints if the `?` and the `Some(..)` come\n  from different macro contexts [#6935](https://github.com/rust-lang/rust-clippy/pull/6935)\n* [`map_entry`]: Better detect if the entry API can be used\n  [#6937](https://github.com/rust-lang/rust-clippy/pull/6937)\n* [`or_fun_call`]: No longer lints on some `len` function calls\n  [#6950](https://github.com/rust-lang/rust-clippy/pull/6950)\n* [`new_ret_no_self`]: No longer lints when `Self` is returned with different\n  generic arguments [#6952](https://github.com/rust-lang/rust-clippy/pull/6952)\n* [`upper_case_acronyms`]: No longer lints on public items\n  [#6981](https://github.com/rust-lang/rust-clippy/pull/6981)\n* [`explicit_into_iter_loop`]: Only lint when `into_iter` is an implementation\n  of `IntoIterator` [#6982](https://github.com/rust-lang/rust-clippy/pull/6982)\n* [`expl_impl_clone_on_copy`]: Take generic constraints into account before\n  suggesting to use `derive` instead\n  [#6993](https://github.com/rust-lang/rust-clippy/pull/6993)\n* [`missing_panics_doc`]: No longer lints when only debug-assertions are used\n  [#6996](https://github.com/rust-lang/rust-clippy/pull/6996)\n* [`clone_on_copy`]: Only lint when using the `Clone` trait\n  [#7000](https://github.com/rust-lang/rust-clippy/pull/7000)\n* [`wrong_self_convention`]: No longer lints inside a trait implementation\n  [#7002](https://github.com/rust-lang/rust-clippy/pull/7002)\n* [`redundant_clone`]: No longer lints when the cloned value is modified while\n  the clone is in use\n  [#7011](https://github.com/rust-lang/rust-clippy/pull/7011)\n* [`same_item_push`]: No longer lints if the `Vec` is used in the loop body\n  [#7018](https://github.com/rust-lang/rust-clippy/pull/7018)\n* [`cargo_common_metadata`]: Remove author requirement\n  [#7026](https://github.com/rust-lang/rust-clippy/pull/7026)\n* [`panic_in_result_fn`]: No longer lints on `debug_assert` family\n  [#7060](https://github.com/rust-lang/rust-clippy/pull/7060)\n* [`panic`]: No longer wrongfully lints on `debug_assert` with message\n  [#7063](https://github.com/rust-lang/rust-clippy/pull/7063)\n* [`wrong_self_convention`]: No longer lints in trait implementations where no\n  `self` is involved [#7064](https://github.com/rust-lang/rust-clippy/pull/7064)\n* [`missing_const_for_fn`]: No longer lints when unstable `const` function is\n  involved [#7076](https://github.com/rust-lang/rust-clippy/pull/7076)\n* [`suspicious_else_formatting`]: Allow Allman style braces\n  [#7087](https://github.com/rust-lang/rust-clippy/pull/7087)\n* [`inconsistent_struct_constructor`]: No longer lints in macros\n  [#7097](https://github.com/rust-lang/rust-clippy/pull/7097)\n* [`single_component_path_imports`]: No longer lints on macro re-exports\n  [#7120](https://github.com/rust-lang/rust-clippy/pull/7120)\n\n### Suggestion Fixes/Improvements\n\n* [`redundant_pattern_matching`]: Add a note when applying this lint would\n  change the drop order\n  [#6568](https://github.com/rust-lang/rust-clippy/pull/6568)\n* [`write_literal`], [`print_literal`]: Add auto-applicable suggestion\n  [#6821](https://github.com/rust-lang/rust-clippy/pull/6821)\n* [`manual_map`]: Fix suggestion for complex `if let ... else` chains\n  [#6856](https://github.com/rust-lang/rust-clippy/pull/6856)\n* [`inconsistent_struct_constructor`]: Make lint description and message clearer\n  [#6892](https://github.com/rust-lang/rust-clippy/pull/6892)\n* [`map_entry`]: Now suggests `or_insert`, `insert_with` or `match _.entry(_)`\n  as appropriate [#6937](https://github.com/rust-lang/rust-clippy/pull/6937)\n* [`manual_flatten`]: Suggest to insert `copied` if necessary\n  [#6962](https://github.com/rust-lang/rust-clippy/pull/6962)\n* [`redundant_slicing`]: Fix suggestion when a re-borrow might be required or\n  when the value is from a macro call\n  [#6975](https://github.com/rust-lang/rust-clippy/pull/6975)\n* [`match_wildcard_for_single_variants`]: Fix suggestion for hidden variant\n  [#6988](https://github.com/rust-lang/rust-clippy/pull/6988)\n* [`clone_on_copy`]: Correct suggestion when the cloned value is a macro call\n  [#7000](https://github.com/rust-lang/rust-clippy/pull/7000)\n* [`manual_map`]: Fix suggestion at the end of an if chain\n  [#7004](https://github.com/rust-lang/rust-clippy/pull/7004)\n* Fix needless parenthesis output in multiple lint suggestions\n  [#7013](https://github.com/rust-lang/rust-clippy/pull/7013)\n* [`needless_collect`]: Better explanation in the lint message\n  [#7020](https://github.com/rust-lang/rust-clippy/pull/7020)\n* [`useless_vec`]: Now considers mutability\n  [#7036](https://github.com/rust-lang/rust-clippy/pull/7036)\n* [`useless_format`]: Wrap the content in braces if necessary\n  [#7092](https://github.com/rust-lang/rust-clippy/pull/7092)\n* [`single_match`]: Don't suggest an equality check for types which don't\n  implement `PartialEq`\n  [#7093](https://github.com/rust-lang/rust-clippy/pull/7093)\n* [`from_over_into`]: Mention type in help message\n  [#7099](https://github.com/rust-lang/rust-clippy/pull/7099)\n* [`manual_unwrap_or`]: Fix invalid code suggestion due to a macro call\n  [#7136](https://github.com/rust-lang/rust-clippy/pull/7136)\n\n### ICE Fixes\n\n* [`macro_use_imports`]\n  [#7022](https://github.com/rust-lang/rust-clippy/pull/7022)\n* [`missing_panics_doc`]\n  [#7034](https://github.com/rust-lang/rust-clippy/pull/7034)\n* [`tabs_in_doc_comments`]\n  [#7039](https://github.com/rust-lang/rust-clippy/pull/7039)\n* [`missing_const_for_fn`]\n  [#7128](https://github.com/rust-lang/rust-clippy/pull/7128)\n\n### Others\n\n* [Clippy's lint\n  list](https://rust-lang.github.io/rust-clippy/master/index.html) now supports\n  themes [#7030](https://github.com/rust-lang/rust-clippy/pull/7030)\n* Lints that were uplifted to `rustc` now mention the new `rustc` name in the\n  deprecation warning\n  [#7056](https://github.com/rust-lang/rust-clippy/pull/7056)\n\n## Rust 1.52\n\nReleased 2021-05-06\n\n[View all 102 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2021-02-03T15%3A59%3A06Z..2021-03-11T20%3A06%3A43Z+base%3Amaster)\n\n### New Lints\n\n* [`from_str_radix_10`]\n  [#6717](https://github.com/rust-lang/rust-clippy/pull/6717)\n* [`implicit_clone`]\n  [#6730](https://github.com/rust-lang/rust-clippy/pull/6730)\n* [`semicolon_if_nothing_returned`]\n  [#6681](https://github.com/rust-lang/rust-clippy/pull/6681)\n* [`manual_flatten`]\n  [#6646](https://github.com/rust-lang/rust-clippy/pull/6646)\n* [`inconsistent_struct_constructor`]\n  [#6769](https://github.com/rust-lang/rust-clippy/pull/6769)\n* [`iter_count`]\n  [#6791](https://github.com/rust-lang/rust-clippy/pull/6791)\n* [`default_numeric_fallback`]\n  [#6662](https://github.com/rust-lang/rust-clippy/pull/6662)\n* [`bytes_nth`]\n  [#6695](https://github.com/rust-lang/rust-clippy/pull/6695)\n* [`filter_map_identity`]\n  [#6685](https://github.com/rust-lang/rust-clippy/pull/6685)\n* [`manual_map`]\n  [#6573](https://github.com/rust-lang/rust-clippy/pull/6573)\n\n### Moves and Deprecations\n\n* Moved [`upper_case_acronyms`] to `pedantic`\n  [#6775](https://github.com/rust-lang/rust-clippy/pull/6775)\n* Moved [`manual_map`] to `nursery`\n  [#6796](https://github.com/rust-lang/rust-clippy/pull/6796)\n* Moved [`unnecessary_wraps`] to `pedantic`\n  [#6765](https://github.com/rust-lang/rust-clippy/pull/6765)\n* Moved [`trivial_regex`] to `nursery`\n  [#6696](https://github.com/rust-lang/rust-clippy/pull/6696)\n* Moved [`naive_bytecount`] to `pedantic`\n  [#6825](https://github.com/rust-lang/rust-clippy/pull/6825)\n* Moved [`upper_case_acronyms`] to `style`\n  [#6788](https://github.com/rust-lang/rust-clippy/pull/6788)\n* Moved [`manual_map`] to `style`\n  [#6801](https://github.com/rust-lang/rust-clippy/pull/6801)\n\n### Enhancements\n\n* [`disallowed_methods`]: Now supports functions in addition to methods\n  [#6674](https://github.com/rust-lang/rust-clippy/pull/6674)\n* [`upper_case_acronyms`]: Added a new configuration `upper-case-acronyms-aggressive` to\n  trigger the lint if there is more than one uppercase character next to each other\n  [#6788](https://github.com/rust-lang/rust-clippy/pull/6788)\n* [`collapsible_match`]: Now supports block comparison with different value names\n  [#6754](https://github.com/rust-lang/rust-clippy/pull/6754)\n* [`unnecessary_wraps`]: Will now suggest removing unnecessary wrapped return unit type, like `Option<()>`\n  [#6665](https://github.com/rust-lang/rust-clippy/pull/6665)\n* Improved value usage detection in closures\n  [#6698](https://github.com/rust-lang/rust-clippy/pull/6698)\n\n### False Positive Fixes\n\n* [`use_self`]: No longer lints in macros\n  [#6833](https://github.com/rust-lang/rust-clippy/pull/6833)\n* [`use_self`]: Fixed multiple false positives for: generics, associated types and derive implementations\n  [#6179](https://github.com/rust-lang/rust-clippy/pull/6179)\n* [`missing_inline_in_public_items`]: No longer lints for procedural macros\n  [#6814](https://github.com/rust-lang/rust-clippy/pull/6814)\n* [`inherent_to_string`]: No longer lints on functions with function generics\n  [#6771](https://github.com/rust-lang/rust-clippy/pull/6771)\n* [`doc_markdown`]: Add `OpenDNS` to the default configuration as an allowed identifier\n  [#6783](https://github.com/rust-lang/rust-clippy/pull/6783)\n* [`missing_panics_doc`]: No longer lints on [`unreachable!`](https://doc.rust-lang.org/std/macro.unreachable.html)\n  [#6700](https://github.com/rust-lang/rust-clippy/pull/6700)\n* [`collapsible_if`]: No longer lints on if statements with attributes\n  [#6701](https://github.com/rust-lang/rust-clippy/pull/6701)\n* [`match_same_arms`]: Only considers empty blocks as equal if the tokens contained are the same\n  [#6843](https://github.com/rust-lang/rust-clippy/pull/6843)\n* [`redundant_closure`]: Now ignores macros\n  [#6871](https://github.com/rust-lang/rust-clippy/pull/6871)\n* [`manual_map`]: Fixed false positives when control flow statements like `return`, `break` etc. are used\n  [#6801](https://github.com/rust-lang/rust-clippy/pull/6801)\n* [`vec_init_then_push`]: Fixed false positives for loops and if statements\n  [#6697](https://github.com/rust-lang/rust-clippy/pull/6697)\n* [`len_without_is_empty`]: Will now consider multiple impl blocks and `#[allow]` on\n  the `len` method as well as the type definition.\n  [#6853](https://github.com/rust-lang/rust-clippy/pull/6853)\n* [`let_underscore_drop`]: Only lints on types which implement `Drop`\n  [#6682](https://github.com/rust-lang/rust-clippy/pull/6682)\n* [`unit_arg`]: No longer lints on unit arguments when they come from a path expression.\n  [#6601](https://github.com/rust-lang/rust-clippy/pull/6601)\n* [`cargo_common_metadata`]: No longer lints if\n  [`publish = false`](https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field)\n  is defined in the manifest\n  [#6650](https://github.com/rust-lang/rust-clippy/pull/6650)\n\n### Suggestion Fixes/Improvements\n\n* [`collapsible_match`]: Fixed lint message capitalization\n  [#6766](https://github.com/rust-lang/rust-clippy/pull/6766)\n* [`or_fun_call`]: Improved suggestions for `or_insert(vec![])`\n  [#6790](https://github.com/rust-lang/rust-clippy/pull/6790)\n* [`manual_map`]: No longer expands macros in the suggestions\n  [#6801](https://github.com/rust-lang/rust-clippy/pull/6801)\n* Aligned Clippy's lint messages with the rustc dev guide\n  [#6787](https://github.com/rust-lang/rust-clippy/pull/6787)\n\n### ICE Fixes\n\n* [`zero_sized_map_values`]\n  [#6866](https://github.com/rust-lang/rust-clippy/pull/6866)\n\n### Documentation Improvements\n\n* [`useless_format`]: Improved the documentation example\n  [#6854](https://github.com/rust-lang/rust-clippy/pull/6854)\n* Clippy's [`README.md`]: Includes a new subsection on running Clippy as a rustc wrapper\n  [#6782](https://github.com/rust-lang/rust-clippy/pull/6782)\n\n### Others\n\n* Running `cargo clippy` after `cargo check` now works as expected\n  (`cargo clippy` and `cargo check` no longer shares the same build cache)\n  [#6687](https://github.com/rust-lang/rust-clippy/pull/6687)\n* Cargo now re-runs Clippy if arguments after `--` provided to `cargo clippy` are changed.\n  [#6834](https://github.com/rust-lang/rust-clippy/pull/6834)\n* Extracted Clippy's `utils` module into the new `clippy_utils` crate\n  [#6756](https://github.com/rust-lang/rust-clippy/pull/6756)\n* Clippy lintcheck tool improvements\n  [#6800](https://github.com/rust-lang/rust-clippy/pull/6800)\n  [#6735](https://github.com/rust-lang/rust-clippy/pull/6735)\n  [#6764](https://github.com/rust-lang/rust-clippy/pull/6764)\n  [#6708](https://github.com/rust-lang/rust-clippy/pull/6708)\n  [#6780](https://github.com/rust-lang/rust-clippy/pull/6780)\n  [#6686](https://github.com/rust-lang/rust-clippy/pull/6686)\n\n## Rust 1.51\n\nReleased 2021-03-25\n\n[View all 78 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-12-21T15%3A43%3A04Z..2021-02-03T04%3A21%3A10Z+base%3Amaster)\n\n### New Lints\n\n* [`upper_case_acronyms`]\n  [#6475](https://github.com/rust-lang/rust-clippy/pull/6475)\n* [`from_over_into`] [#6476](https://github.com/rust-lang/rust-clippy/pull/6476)\n* [`case_sensitive_file_extension_comparisons`]\n  [#6500](https://github.com/rust-lang/rust-clippy/pull/6500)\n* [`needless_question_mark`]\n  [#6507](https://github.com/rust-lang/rust-clippy/pull/6507)\n* [`missing_panics_doc`]\n  [#6523](https://github.com/rust-lang/rust-clippy/pull/6523)\n* [`redundant_slicing`]\n  [#6528](https://github.com/rust-lang/rust-clippy/pull/6528)\n* [`vec_init_then_push`]\n  [#6538](https://github.com/rust-lang/rust-clippy/pull/6538)\n* [`ptr_as_ptr`] [#6542](https://github.com/rust-lang/rust-clippy/pull/6542)\n* [`collapsible_else_if`] (split out from `collapsible_if`)\n  [#6544](https://github.com/rust-lang/rust-clippy/pull/6544)\n* [`inspect_for_each`] [#6577](https://github.com/rust-lang/rust-clippy/pull/6577)\n* [`manual_filter_map`]\n  [#6591](https://github.com/rust-lang/rust-clippy/pull/6591)\n* [`exhaustive_enums`]\n  [#6617](https://github.com/rust-lang/rust-clippy/pull/6617)\n* [`exhaustive_structs`]\n  [#6617](https://github.com/rust-lang/rust-clippy/pull/6617)\n\n### Moves and Deprecations\n\n* Replace [`find_map`] with [`manual_find_map`]\n  [#6591](https://github.com/rust-lang/rust-clippy/pull/6591)\n* `unknown_clippy_lints` Now integrated in the `unknown_lints` rustc lint\n  [#6653](https://github.com/rust-lang/rust-clippy/pull/6653)\n\n### Enhancements\n\n* [`ptr_arg`] Now also suggests to use `&Path` instead of `&PathBuf`\n  [#6506](https://github.com/rust-lang/rust-clippy/pull/6506)\n* [`cast_ptr_alignment`] Also lint when the `pointer::cast` method is used\n  [#6557](https://github.com/rust-lang/rust-clippy/pull/6557)\n* [`collapsible_match`] Now also deals with `&` and `*` operators in the `match`\n  scrutinee [#6619](https://github.com/rust-lang/rust-clippy/pull/6619)\n\n### False Positive Fixes\n\n* [`similar_names`] Ignore underscore prefixed names\n  [#6403](https://github.com/rust-lang/rust-clippy/pull/6403)\n* [`print_literal`] and [`write_literal`] No longer lint numeric literals\n  [#6408](https://github.com/rust-lang/rust-clippy/pull/6408)\n* [`large_enum_variant`] No longer lints in external macros\n  [#6485](https://github.com/rust-lang/rust-clippy/pull/6485)\n* [`empty_enum`] Only lint if `never_type` feature is enabled\n  [#6513](https://github.com/rust-lang/rust-clippy/pull/6513)\n* [`field_reassign_with_default`] No longer lints in macros\n  [#6553](https://github.com/rust-lang/rust-clippy/pull/6553)\n* [`size_of_in_element_count`] No longer lints when dividing by element size\n  [#6578](https://github.com/rust-lang/rust-clippy/pull/6578)\n* [`needless_return`] No longer lints in macros\n  [#6586](https://github.com/rust-lang/rust-clippy/pull/6586)\n* [`match_overlapping_arm`] No longer lint when first arm is completely included\n  in second arm [#6603](https://github.com/rust-lang/rust-clippy/pull/6603)\n* [`doc_markdown`] Add `WebGL` to the default configuration as an allowed\n  identifier [#6605](https://github.com/rust-lang/rust-clippy/pull/6605)\n\n### Suggestion Fixes/Improvements\n\n* [`field_reassign_with_default`] Don't expand macro in lint suggestion\n  [#6531](https://github.com/rust-lang/rust-clippy/pull/6531)\n* [`match_like_matches_macro`] Strip references in suggestion\n  [#6532](https://github.com/rust-lang/rust-clippy/pull/6532)\n* [`single_match`] Suggest `if` over `if let` when possible\n  [#6574](https://github.com/rust-lang/rust-clippy/pull/6574)\n* `ref_in_deref` Use parentheses correctly in suggestion\n  [#6609](https://github.com/rust-lang/rust-clippy/pull/6609)\n* [`stable_sort_primitive`] Clarify error message\n  [#6611](https://github.com/rust-lang/rust-clippy/pull/6611)\n\n### ICE Fixes\n\n* [`zero_sized_map_values`]\n  [#6582](https://github.com/rust-lang/rust-clippy/pull/6582)\n\n### Documentation Improvements\n\n* Improve search performance on the Clippy website and make it possible to\n  directly search for lints on the GitHub issue tracker\n  [#6483](https://github.com/rust-lang/rust-clippy/pull/6483)\n* Clean up `README.md` by removing outdated paragraph\n  [#6488](https://github.com/rust-lang/rust-clippy/pull/6488)\n* [`await_holding_refcell_ref`] and [`await_holding_lock`]\n  [#6585](https://github.com/rust-lang/rust-clippy/pull/6585)\n* [`as_conversions`] [#6608](https://github.com/rust-lang/rust-clippy/pull/6608)\n\n### Others\n\n* Clippy now has a [Roadmap] for 2021. If you like to get involved in a bigger\n  project, take a look at the [Roadmap project page]. All issues listed there\n  are actively mentored\n  [#6462](https://github.com/rust-lang/rust-clippy/pull/6462)\n* The Clippy version number now corresponds to the Rust version number\n  [#6526](https://github.com/rust-lang/rust-clippy/pull/6526)\n* Fix oversight which caused Clippy to lint deps in some environments, where\n  `CLIPPY_TESTS=true` was set somewhere\n  [#6575](https://github.com/rust-lang/rust-clippy/pull/6575)\n* Add `cargo dev-lintcheck` tool to the Clippy Dev Tool\n  [#6469](https://github.com/rust-lang/rust-clippy/pull/6469)\n\n[Roadmap]: https://github.com/rust-lang/rust-clippy/blob/master/book/src/development/proposals/roadmap-2021.md\n[Roadmap project page]: https://github.com/rust-lang/rust-clippy/projects/3\n\n## Rust 1.50\n\nReleased 2021-02-11\n\n[View all 119 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-11-06T18%3A32%3A40Z..2021-01-03T14%3A51%3A18Z+base%3Amaster)\n\n### New Lints\n\n* [`suspicious_operation_groupings`] [#6086](https://github.com/rust-lang/rust-clippy/pull/6086)\n* [`size_of_in_element_count`] [#6394](https://github.com/rust-lang/rust-clippy/pull/6394)\n* [`unnecessary_wraps`] [#6070](https://github.com/rust-lang/rust-clippy/pull/6070)\n* [`let_underscore_drop`] [#6305](https://github.com/rust-lang/rust-clippy/pull/6305)\n* [`collapsible_match`] [#6402](https://github.com/rust-lang/rust-clippy/pull/6402)\n* [`redundant_else`] [#6330](https://github.com/rust-lang/rust-clippy/pull/6330)\n* [`zero_sized_map_values`] [#6218](https://github.com/rust-lang/rust-clippy/pull/6218)\n* [`print_stderr`] [#6367](https://github.com/rust-lang/rust-clippy/pull/6367)\n* [`string_from_utf8_as_bytes`] [#6134](https://github.com/rust-lang/rust-clippy/pull/6134)\n\n### Moves and Deprecations\n\n* Previously deprecated [`str_to_string`] and [`string_to_string`] have been un-deprecated\n  as `restriction` lints [#6333](https://github.com/rust-lang/rust-clippy/pull/6333)\n* Deprecate `panic_params` lint. This is now available in rustc as `non_fmt_panics`\n  [#6351](https://github.com/rust-lang/rust-clippy/pull/6351)\n* Move [`map_err_ignore`] to `restriction`\n  [#6416](https://github.com/rust-lang/rust-clippy/pull/6416)\n* Move [`await_holding_refcell_ref`] to `pedantic`\n  [#6354](https://github.com/rust-lang/rust-clippy/pull/6354)\n* Move [`await_holding_lock`] to `pedantic`\n  [#6354](https://github.com/rust-lang/rust-clippy/pull/6354)\n\n### Enhancements\n\n* Add the `unreadable-literal-lint-fractions` configuration to disable\n  the `unreadable_literal` lint for fractions\n  [#6421](https://github.com/rust-lang/rust-clippy/pull/6421)\n* [`clone_on_copy`]: Now shows the type in the lint message\n  [#6443](https://github.com/rust-lang/rust-clippy/pull/6443)\n* [`redundant_pattern_matching`]: Now also lints on `std::task::Poll`\n  [#6339](https://github.com/rust-lang/rust-clippy/pull/6339)\n* [`redundant_pattern_matching`]: Additionally also lints on `std::net::IpAddr`\n  [#6377](https://github.com/rust-lang/rust-clippy/pull/6377)\n* [`search_is_some`]: Now suggests `contains` instead of `find(foo).is_some()`\n  [#6119](https://github.com/rust-lang/rust-clippy/pull/6119)\n* [`clone_double_ref`]: Now prints the reference type in the lint message\n  [#6442](https://github.com/rust-lang/rust-clippy/pull/6442)\n* [`modulo_one`]: Now also lints on -1.\n  [#6360](https://github.com/rust-lang/rust-clippy/pull/6360)\n* [`empty_loop`]: Now lints no_std crates, too\n  [#6205](https://github.com/rust-lang/rust-clippy/pull/6205)\n* [`or_fun_call`]: Now also lints when indexing `HashMap` or `BTreeMap`\n  [#6267](https://github.com/rust-lang/rust-clippy/pull/6267)\n* [`wrong_self_convention`]: Now also lints in trait definitions\n  [#6316](https://github.com/rust-lang/rust-clippy/pull/6316)\n* [`needless_borrow`]: Print the type in the lint message\n  [#6449](https://github.com/rust-lang/rust-clippy/pull/6449)\n\n[msrv_readme]: https://github.com/rust-lang/rust-clippy#specifying-the-minimum-supported-rust-version\n\n### False Positive Fixes\n\n* [`manual_range_contains`]: No longer lints in `const fn`\n  [#6382](https://github.com/rust-lang/rust-clippy/pull/6382)\n* [`unnecessary_lazy_evaluations`]: No longer lints if closure argument is used\n  [#6370](https://github.com/rust-lang/rust-clippy/pull/6370)\n* [`match_single_binding`]: Now ignores cases with `#[cfg()]` macros\n  [#6435](https://github.com/rust-lang/rust-clippy/pull/6435)\n* [`match_like_matches_macro`]: No longer lints on arms with attributes\n  [#6290](https://github.com/rust-lang/rust-clippy/pull/6290)\n* [`map_clone`]: No longer lints with deref and clone\n  [#6269](https://github.com/rust-lang/rust-clippy/pull/6269)\n* [`map_clone`]: No longer lints in the case of &mut\n  [#6301](https://github.com/rust-lang/rust-clippy/pull/6301)\n* [`needless_update`]: Now ignores `non_exhaustive` structs\n  [#6464](https://github.com/rust-lang/rust-clippy/pull/6464)\n* [`needless_collect`]: No longer lints when a collect is needed multiple times\n  [#6313](https://github.com/rust-lang/rust-clippy/pull/6313)\n* [`unnecessary_cast`] No longer lints cfg-dependent types\n  [#6369](https://github.com/rust-lang/rust-clippy/pull/6369)\n* [`declare_interior_mutable_const`] and [`borrow_interior_mutable_const`]:\n  Both now ignore enums with frozen variants\n  [#6110](https://github.com/rust-lang/rust-clippy/pull/6110)\n* [`field_reassign_with_default`] No longer lint for private fields\n  [#6537](https://github.com/rust-lang/rust-clippy/pull/6537)\n\n### Suggestion Fixes/Improvements\n\n* [`vec_box`]: Provide correct type scope suggestion\n  [#6271](https://github.com/rust-lang/rust-clippy/pull/6271)\n* [`manual_range_contains`]: Give correct suggestion when using floats\n  [#6320](https://github.com/rust-lang/rust-clippy/pull/6320)\n* [`unnecessary_lazy_evaluations`]: Don't always mark suggestion as MachineApplicable\n  [#6272](https://github.com/rust-lang/rust-clippy/pull/6272)\n* [`manual_async_fn`]: Improve suggestion formatting\n  [#6294](https://github.com/rust-lang/rust-clippy/pull/6294)\n* [`unnecessary_cast`]: Fix incorrectly formatted float literal suggestion\n  [#6362](https://github.com/rust-lang/rust-clippy/pull/6362)\n\n### ICE Fixes\n\n* Fix a crash in [`from_iter_instead_of_collect`]\n  [#6304](https://github.com/rust-lang/rust-clippy/pull/6304)\n* Fix a silent crash when parsing doc comments in [`needless_doctest_main`]\n  [#6458](https://github.com/rust-lang/rust-clippy/pull/6458)\n\n### Documentation Improvements\n\n* The lint website search has been improved ([#6477](https://github.com/rust-lang/rust-clippy/pull/6477)):\n  * Searching for lints with dashes and spaces is possible now. For example\n    `missing-errors-doc` and `missing errors doc` are now valid aliases for lint names\n  * Improved fuzzy search in lint descriptions\n* Various README improvements\n  [#6287](https://github.com/rust-lang/rust-clippy/pull/6287)\n* Add known problems to [`comparison_chain`] documentation\n  [#6390](https://github.com/rust-lang/rust-clippy/pull/6390)\n* Fix example used in [`cargo_common_metadata`]\n  [#6293](https://github.com/rust-lang/rust-clippy/pull/6293)\n* Improve [`map_clone`] documentation\n  [#6340](https://github.com/rust-lang/rust-clippy/pull/6340)\n\n### Others\n\n* You can now tell Clippy about the MSRV your project supports. Please refer to\n  the specific README section to learn more about MSRV support [here][msrv_readme]\n  [#6201](https://github.com/rust-lang/rust-clippy/pull/6201)\n* Add `--no-deps` option to avoid running on path dependencies in workspaces\n  [#6188](https://github.com/rust-lang/rust-clippy/pull/6188)\n\n## Rust 1.49\n\nReleased 2020-12-31\n\n[View all 107 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-09-24T14%3A05%3A12Z..2020-11-05T13%3A35%3A44Z+base%3Amaster)\n\n### New Lints\n\n* [`field_reassign_with_default`] [#5911](https://github.com/rust-lang/rust-clippy/pull/5911)\n* [`await_holding_refcell_ref`] [#6029](https://github.com/rust-lang/rust-clippy/pull/6029)\n* [`disallowed_methods`] [#6081](https://github.com/rust-lang/rust-clippy/pull/6081)\n* [`inline_asm_x86_att_syntax`] [#6092](https://github.com/rust-lang/rust-clippy/pull/6092)\n* [`inline_asm_x86_intel_syntax`] [#6092](https://github.com/rust-lang/rust-clippy/pull/6092)\n* [`from_iter_instead_of_collect`] [#6101](https://github.com/rust-lang/rust-clippy/pull/6101)\n* [`mut_mutex_lock`] [#6103](https://github.com/rust-lang/rust-clippy/pull/6103)\n* [`single_element_loop`] [#6109](https://github.com/rust-lang/rust-clippy/pull/6109)\n* [`manual_unwrap_or`] [#6123](https://github.com/rust-lang/rust-clippy/pull/6123)\n* [`large_types_passed_by_value`] [#6135](https://github.com/rust-lang/rust-clippy/pull/6135)\n* [`result_unit_err`] [#6157](https://github.com/rust-lang/rust-clippy/pull/6157)\n* [`ref_option_ref`] [#6165](https://github.com/rust-lang/rust-clippy/pull/6165)\n* [`manual_range_contains`] [#6177](https://github.com/rust-lang/rust-clippy/pull/6177)\n* [`unusual_byte_groupings`] [#6183](https://github.com/rust-lang/rust-clippy/pull/6183)\n* [`comparison_to_empty`] [#6226](https://github.com/rust-lang/rust-clippy/pull/6226)\n* [`map_collect_result_unit`] [#6227](https://github.com/rust-lang/rust-clippy/pull/6227)\n* [`manual_ok_or`] [#6233](https://github.com/rust-lang/rust-clippy/pull/6233)\n\n### Moves and Deprecations\n\n* Rename `single_char_push_str` to [`single_char_add_str`]\n  [#6037](https://github.com/rust-lang/rust-clippy/pull/6037)\n* Rename `zero_width_space` to [`invisible_characters`]\n  [#6105](https://github.com/rust-lang/rust-clippy/pull/6105)\n* Deprecate `drop_bounds` (uplifted)\n  [#6111](https://github.com/rust-lang/rust-clippy/pull/6111)\n* Move [`string_lit_as_bytes`] to `nursery`\n  [#6117](https://github.com/rust-lang/rust-clippy/pull/6117)\n* Move [`rc_buffer`] to `restriction`\n  [#6128](https://github.com/rust-lang/rust-clippy/pull/6128)\n\n### Enhancements\n\n* [`manual_memcpy`]: Also lint when there are loop counters (and produce a\n  reliable suggestion)\n  [#5727](https://github.com/rust-lang/rust-clippy/pull/5727)\n* [`single_char_add_str`]: Also lint on `String::insert_str`\n  [#6037](https://github.com/rust-lang/rust-clippy/pull/6037)\n* [`invisible_characters`]: Also lint the characters `\\u{AD}` and `\\u{2060}`\n  [#6105](https://github.com/rust-lang/rust-clippy/pull/6105)\n* [`eq_op`]: Also lint on the `assert_*!` macro family\n  [#6167](https://github.com/rust-lang/rust-clippy/pull/6167)\n* [`items_after_statements`]: Also lint in local macro expansions\n  [#6176](https://github.com/rust-lang/rust-clippy/pull/6176)\n* [`unnecessary_cast`]: Also lint casts on integer and float literals\n  [#6187](https://github.com/rust-lang/rust-clippy/pull/6187)\n* [`manual_unwrap_or`]: Also lint `Result::unwrap_or`\n  [#6190](https://github.com/rust-lang/rust-clippy/pull/6190)\n* [`match_like_matches_macro`]: Also lint when `match` has more than two arms\n  [#6216](https://github.com/rust-lang/rust-clippy/pull/6216)\n* [`integer_arithmetic`]: Better handle `/` an `%` operators\n  [#6229](https://github.com/rust-lang/rust-clippy/pull/6229)\n\n### False Positive Fixes\n\n* [`needless_lifetimes`]: Bail out if the function has a `where` clause with the\n  lifetime [#5978](https://github.com/rust-lang/rust-clippy/pull/5978)\n* [`explicit_counter_loop`]: No longer lints, when loop counter is used after it\n  is incremented [#6076](https://github.com/rust-lang/rust-clippy/pull/6076)\n* [`or_fun_call`]: Revert changes addressing the handling of `const fn`\n  [#6077](https://github.com/rust-lang/rust-clippy/pull/6077)\n* [`needless_range_loop`]: No longer lints, when the iterable is used in the\n  range [#6102](https://github.com/rust-lang/rust-clippy/pull/6102)\n* [`inconsistent_digit_grouping`]: Fix bug when using floating point exponent\n  [#6104](https://github.com/rust-lang/rust-clippy/pull/6104)\n* [`mistyped_literal_suffixes`]: No longer lints on the fractional part of a\n  float (e.g. `713.32_64`)\n  [#6114](https://github.com/rust-lang/rust-clippy/pull/6114)\n* [`invalid_regex`]: No longer lint on unicode characters within `bytes::Regex`\n  [#6132](https://github.com/rust-lang/rust-clippy/pull/6132)\n* [`boxed_local`]: No longer lints on `extern fn` arguments\n  [#6133](https://github.com/rust-lang/rust-clippy/pull/6133)\n* [`needless_lifetimes`]: Fix regression, where lifetime is used in `where`\n  clause [#6198](https://github.com/rust-lang/rust-clippy/pull/6198)\n\n### Suggestion Fixes/Improvements\n\n* [`unnecessary_sort_by`]: Avoid dereferencing the suggested closure parameter\n  [#6078](https://github.com/rust-lang/rust-clippy/pull/6078)\n* [`needless_arbitrary_self_type`]: Correctly handle expanded code\n  [#6093](https://github.com/rust-lang/rust-clippy/pull/6093)\n* [`useless_format`]: Preserve raw strings in suggestion\n  [#6151](https://github.com/rust-lang/rust-clippy/pull/6151)\n* [`empty_loop`]: Suggest alternatives\n  [#6162](https://github.com/rust-lang/rust-clippy/pull/6162)\n* [`borrowed_box`]: Correctly add parentheses in suggestion\n  [#6200](https://github.com/rust-lang/rust-clippy/pull/6200)\n* [`unused_unit`]: Improve suggestion formatting\n  [#6247](https://github.com/rust-lang/rust-clippy/pull/6247)\n\n### Documentation Improvements\n\n* Some doc improvements:\n  * [`rc_buffer`] [#6090](https://github.com/rust-lang/rust-clippy/pull/6090)\n  * [`empty_loop`] [#6162](https://github.com/rust-lang/rust-clippy/pull/6162)\n* [`doc_markdown`]: Document problematic link text style\n  [#6107](https://github.com/rust-lang/rust-clippy/pull/6107)\n\n## Rust 1.48\n\nReleased 2020-11-19\n\n[View all 99 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-08-11T13%3A14%3A38Z..2020-09-23T18%3A55%3A22Z+base%3Amaster)\n\n### New lints\n\n* [`self_assignment`] [#5894](https://github.com/rust-lang/rust-clippy/pull/5894)\n* [`unnecessary_lazy_evaluations`] [#5720](https://github.com/rust-lang/rust-clippy/pull/5720)\n* [`manual_strip`] [#6038](https://github.com/rust-lang/rust-clippy/pull/6038)\n* [`map_err_ignore`] [#5998](https://github.com/rust-lang/rust-clippy/pull/5998)\n* [`rc_buffer`] [#6044](https://github.com/rust-lang/rust-clippy/pull/6044)\n* `to_string_in_display` [#5831](https://github.com/rust-lang/rust-clippy/pull/5831)\n* `single_char_push_str` [#5881](https://github.com/rust-lang/rust-clippy/pull/5881)\n\n### Moves and Deprecations\n\n* Downgrade [`verbose_bit_mask`] to pedantic\n  [#6036](https://github.com/rust-lang/rust-clippy/pull/6036)\n\n### Enhancements\n\n* Extend [`precedence`] to handle chains of methods combined with unary negation\n  [#5928](https://github.com/rust-lang/rust-clippy/pull/5928)\n* [`useless_vec`]: add a configuration value for the maximum allowed size on the stack\n  [#5907](https://github.com/rust-lang/rust-clippy/pull/5907)\n* [`suspicious_arithmetic_impl`]: extend to implementations of `BitAnd`, `BitOr`, `BitXor`, `Rem`, `Shl`, and `Shr`\n  [#5884](https://github.com/rust-lang/rust-clippy/pull/5884)\n* `invalid_atomic_ordering`: detect misuse of `compare_exchange`, `compare_exchange_weak`, and `fetch_update`\n  [#6025](https://github.com/rust-lang/rust-clippy/pull/6025)\n* Avoid [`redundant_pattern_matching`] triggering in macros\n  [#6069](https://github.com/rust-lang/rust-clippy/pull/6069)\n* [`option_if_let_else`]: distinguish pure from impure `else` expressions\n  [#5937](https://github.com/rust-lang/rust-clippy/pull/5937)\n* [`needless_doctest_main`]: parse doctests instead of using textual search\n  [#5912](https://github.com/rust-lang/rust-clippy/pull/5912)\n* [`wildcard_imports`]: allow `prelude` to appear in any segment of an import\n  [#5929](https://github.com/rust-lang/rust-clippy/pull/5929)\n* Re-enable [`len_zero`] for ranges now that `range_is_empty` is stable\n  [#5961](https://github.com/rust-lang/rust-clippy/pull/5961)\n* [`option_as_ref_deref`]: catch fully-qualified calls to `Deref::deref` and `DerefMut::deref_mut`\n  [#5933](https://github.com/rust-lang/rust-clippy/pull/5933)\n\n### False Positive Fixes\n\n* [`useless_attribute`]: permit allowing [`wildcard_imports`] and [`enum_glob_use`]\n  [#5994](https://github.com/rust-lang/rust-clippy/pull/5994)\n* [`transmute_ptr_to_ptr`]: avoid suggesting dereferencing raw pointers in const contexts\n  [#5999](https://github.com/rust-lang/rust-clippy/pull/5999)\n* [`redundant_closure_call`]: take into account usages of the closure in nested functions and closures\n  [#5920](https://github.com/rust-lang/rust-clippy/pull/5920)\n* Fix false positive in [`borrow_interior_mutable_const`] when referencing a field behind a pointer\n  [#5949](https://github.com/rust-lang/rust-clippy/pull/5949)\n* [`doc_markdown`]: allow using \"GraphQL\" without backticks\n  [#5996](https://github.com/rust-lang/rust-clippy/pull/5996)\n* `to_string_in_display`: avoid linting when calling `to_string()` on anything that is not `self`\n  [#5971](https://github.com/rust-lang/rust-clippy/pull/5971)\n* [`indexing_slicing`] and [`out_of_bounds_indexing`] treat references to arrays as arrays\n  [#6034](https://github.com/rust-lang/rust-clippy/pull/6034)\n* [`should_implement_trait`]: ignore methods with lifetime parameters\n  [#5725](https://github.com/rust-lang/rust-clippy/pull/5725)\n* [`needless_return`]: avoid linting if a temporary borrows a local variable\n  [#5903](https://github.com/rust-lang/rust-clippy/pull/5903)\n* Restrict [`unnecessary_sort_by`] to non-reference, Copy types\n  [#6006](https://github.com/rust-lang/rust-clippy/pull/6006)\n* Avoid suggesting `from_bits`/`to_bits` in const contexts in [`transmute_int_to_float`]\n  [#5919](https://github.com/rust-lang/rust-clippy/pull/5919)\n* [`declare_interior_mutable_const`] and [`borrow_interior_mutable_const`]: improve detection of interior mutable types\n  [#6046](https://github.com/rust-lang/rust-clippy/pull/6046)\n\n### Suggestion Fixes/Improvements\n\n* [`let_and_return`]: add a cast to the suggestion when the return expression has adjustments\n  [#5946](https://github.com/rust-lang/rust-clippy/pull/5946)\n* [`useless_conversion`]: show the type in the error message\n  [#6035](https://github.com/rust-lang/rust-clippy/pull/6035)\n* [`unnecessary_mut_passed`]: discriminate between functions and methods in the error message\n  [#5892](https://github.com/rust-lang/rust-clippy/pull/5892)\n* [`float_cmp`] and [`float_cmp_const`]: change wording to make margin of error less ambiguous\n  [#6043](https://github.com/rust-lang/rust-clippy/pull/6043)\n* [`default_trait_access`]: do not use unnecessary type parameters in the suggestion\n  [#5993](https://github.com/rust-lang/rust-clippy/pull/5993)\n* [`collapsible_if`]: don't use expanded code in the suggestion\n  [#5992](https://github.com/rust-lang/rust-clippy/pull/5992)\n* Do not suggest empty format strings in [`print_with_newline`] and [`write_with_newline`]\n  [#6042](https://github.com/rust-lang/rust-clippy/pull/6042)\n* [`unit_arg`]: improve the readability of the suggestion\n  [#5931](https://github.com/rust-lang/rust-clippy/pull/5931)\n* [`stable_sort_primitive`]: print the type that is being sorted in the lint message\n  [#5935](https://github.com/rust-lang/rust-clippy/pull/5935)\n* Show line count and max lines in [`too_many_lines`] lint message\n  [#6009](https://github.com/rust-lang/rust-clippy/pull/6009)\n* Keep parentheses in the suggestion of [`useless_conversion`] where applicable\n  [#5900](https://github.com/rust-lang/rust-clippy/pull/5900)\n* [`option_map_unit_fn`] and [`result_map_unit_fn`]: print the unit type `()` explicitly\n  [#6024](https://github.com/rust-lang/rust-clippy/pull/6024)\n* [`redundant_allocation`]: suggest replacing `Rc<Box<T>>` with `Rc<T>`\n  [#5899](https://github.com/rust-lang/rust-clippy/pull/5899)\n* Make lint messages adhere to rustc dev guide conventions\n  [#5893](https://github.com/rust-lang/rust-clippy/pull/5893)\n\n### ICE Fixes\n\n* Fix ICE in [`repeat_once`]\n  [#5948](https://github.com/rust-lang/rust-clippy/pull/5948)\n\n### Documentation Improvements\n\n* [`mutable_key_type`]: explain potential for false positives when the interior mutable type is not accessed in the `Hash` implementation\n  [#6019](https://github.com/rust-lang/rust-clippy/pull/6019)\n* [`unnecessary_mut_passed`]: fix typo\n  [#5913](https://github.com/rust-lang/rust-clippy/pull/5913)\n* Add example of false positive to [`ptr_arg`] docs.\n  [#5885](https://github.com/rust-lang/rust-clippy/pull/5885)\n* [`box_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection), [`vec_box`] and [`borrowed_box`]: add link to the documentation of `Box`\n  [#6023](https://github.com/rust-lang/rust-clippy/pull/6023)\n\n## Rust 1.47\n\nReleased 2020-10-08\n\n[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-06-23T16%3A27%3A11Z..2020-08-11T12%3A52%3A41Z+base%3Amaster)\n\n### New lints\n\n* [`derive_ord_xor_partial_ord`] [#5848](https://github.com/rust-lang/rust-clippy/pull/5848)\n* [`trait_duplication_in_bounds`] [#5852](https://github.com/rust-lang/rust-clippy/pull/5852)\n* [`map_identity`] [#5694](https://github.com/rust-lang/rust-clippy/pull/5694)\n* [`unit_return_expecting_ord`] [#5737](https://github.com/rust-lang/rust-clippy/pull/5737)\n* [`pattern_type_mismatch`] [#4841](https://github.com/rust-lang/rust-clippy/pull/4841)\n* [`repeat_once`] [#5773](https://github.com/rust-lang/rust-clippy/pull/5773)\n* [`same_item_push`] [#5825](https://github.com/rust-lang/rust-clippy/pull/5825)\n* [`needless_arbitrary_self_type`] [#5869](https://github.com/rust-lang/rust-clippy/pull/5869)\n* [`match_like_matches_macro`] [#5769](https://github.com/rust-lang/rust-clippy/pull/5769)\n* [`stable_sort_primitive`] [#5809](https://github.com/rust-lang/rust-clippy/pull/5809)\n* [`blanket_clippy_restriction_lints`] [#5750](https://github.com/rust-lang/rust-clippy/pull/5750)\n* [`option_if_let_else`] [#5301](https://github.com/rust-lang/rust-clippy/pull/5301)\n\n### Moves and Deprecations\n\n* Deprecate [`regex_macro`] lint\n  [#5760](https://github.com/rust-lang/rust-clippy/pull/5760)\n* Move [`range_minus_one`] to `pedantic`\n  [#5752](https://github.com/rust-lang/rust-clippy/pull/5752)\n\n### Enhancements\n\n* Improve [`needless_collect`] by catching `collect` calls followed by `iter` or `into_iter` calls\n  [#5837](https://github.com/rust-lang/rust-clippy/pull/5837)\n* [`panic`], [`todo`], [`unimplemented`] and [`unreachable`] now detect calls with formatting\n  [#5811](https://github.com/rust-lang/rust-clippy/pull/5811)\n* Detect more cases of [`suboptimal_flops`] and [`imprecise_flops`]\n  [#5443](https://github.com/rust-lang/rust-clippy/pull/5443)\n* Handle asymmetrical implementations of `PartialEq` in [`cmp_owned`]\n  [#5701](https://github.com/rust-lang/rust-clippy/pull/5701)\n* Make it possible to allow [`unsafe_derive_deserialize`]\n  [#5870](https://github.com/rust-lang/rust-clippy/pull/5870)\n* Catch `ord.min(a).max(b)` where a < b in [`min_max`]\n  [#5871](https://github.com/rust-lang/rust-clippy/pull/5871)\n* Make [`clone_on_copy`] suggestion machine applicable\n  [#5745](https://github.com/rust-lang/rust-clippy/pull/5745)\n* Enable [`len_zero`] on ranges now that `is_empty` is stable on them\n  [#5961](https://github.com/rust-lang/rust-clippy/pull/5961)\n\n### False Positive Fixes\n\n* Avoid triggering [`or_fun_call`] with const fns that take no arguments\n  [#5889](https://github.com/rust-lang/rust-clippy/pull/5889)\n* Fix [`redundant_closure_call`] false positive for closures that have multiple calls\n  [#5800](https://github.com/rust-lang/rust-clippy/pull/5800)\n* Don't lint cases involving `ManuallyDrop` in [`redundant_clone`]\n  [#5824](https://github.com/rust-lang/rust-clippy/pull/5824)\n* Treat a single expression the same as a single statement in the 2nd arm of a match in [`single_match_else`]\n  [#5771](https://github.com/rust-lang/rust-clippy/pull/5771)\n* Don't trigger [`unnested_or_patterns`] if the feature `or_patterns` is not enabled\n  [#5758](https://github.com/rust-lang/rust-clippy/pull/5758)\n* Avoid linting if key borrows in [`unnecessary_sort_by`]\n  [#5756](https://github.com/rust-lang/rust-clippy/pull/5756)\n* Consider `Try` impl for `Poll` when generating suggestions in [`try_err`]\n  [#5857](https://github.com/rust-lang/rust-clippy/pull/5857)\n* Take input lifetimes into account in `manual_async_fn`\n  [#5859](https://github.com/rust-lang/rust-clippy/pull/5859)\n* Fix multiple false positives in [`type_repetition_in_bounds`] and add a configuration option\n  [#5761](https://github.com/rust-lang/rust-clippy/pull/5761)\n* Limit the [`suspicious_arithmetic_impl`] lint to one binary operation\n  [#5820](https://github.com/rust-lang/rust-clippy/pull/5820)\n\n### Suggestion Fixes/Improvements\n\n* Improve readability of [`shadow_unrelated`] suggestion by truncating the RHS snippet\n  [#5788](https://github.com/rust-lang/rust-clippy/pull/5788)\n* Suggest `filter_map` instead of `flat_map` when mapping to `Option` in [`map_flatten`]\n  [#5846](https://github.com/rust-lang/rust-clippy/pull/5846)\n* Ensure suggestion is shown correctly for long method call chains in [`iter_nth_zero`]\n  [#5793](https://github.com/rust-lang/rust-clippy/pull/5793)\n* Drop borrow operator in suggestions of [`redundant_pattern_matching`]\n  [#5815](https://github.com/rust-lang/rust-clippy/pull/5815)\n* Add suggestion for [`iter_skip_next`]\n  [#5843](https://github.com/rust-lang/rust-clippy/pull/5843)\n* Improve [`collapsible_if`] fix suggestion\n  [#5732](https://github.com/rust-lang/rust-clippy/pull/5732)\n\n### ICE Fixes\n\n* Fix ICE caused by [`needless_collect`]\n  [#5877](https://github.com/rust-lang/rust-clippy/pull/5877)\n* Fix ICE caused by [`unnested_or_patterns`]\n  [#5784](https://github.com/rust-lang/rust-clippy/pull/5784)\n\n### Documentation Improvements\n\n* Fix grammar of [`await_holding_lock`] documentation\n  [#5748](https://github.com/rust-lang/rust-clippy/pull/5748)\n\n### Others\n\n* Make lints adhere to the rustc dev guide\n  [#5888](https://github.com/rust-lang/rust-clippy/pull/5888)\n\n## Rust 1.46\n\nReleased 2020-08-27\n\n[View all 48 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-05-31T12%3A50%3A53Z..2020-06-23T15%3A00%3A32Z+base%3Amaster)\n\n### New lints\n\n* [`unnested_or_patterns`] [#5378](https://github.com/rust-lang/rust-clippy/pull/5378)\n* [`iter_next_slice`] [#5597](https://github.com/rust-lang/rust-clippy/pull/5597)\n* [`unnecessary_sort_by`] [#5623](https://github.com/rust-lang/rust-clippy/pull/5623)\n* [`vec_resize_to_zero`] [#5637](https://github.com/rust-lang/rust-clippy/pull/5637)\n\n### Moves and Deprecations\n\n* Move [`cast_ptr_alignment`] to pedantic [#5667](https://github.com/rust-lang/rust-clippy/pull/5667)\n\n### Enhancements\n\n* Improve [`mem_replace_with_uninit`] lint [#5695](https://github.com/rust-lang/rust-clippy/pull/5695)\n\n### False Positive Fixes\n\n* [`len_zero`]: Avoid linting ranges when the `range_is_empty` feature is not enabled\n  [#5656](https://github.com/rust-lang/rust-clippy/pull/5656)\n* [`let_and_return`]: Don't lint if a temporary borrow is involved\n  [#5680](https://github.com/rust-lang/rust-clippy/pull/5680)\n* [`reversed_empty_ranges`]: Avoid linting `N..N` in for loop arguments in\n  [#5692](https://github.com/rust-lang/rust-clippy/pull/5692)\n* [`if_same_then_else`]: Don't assume multiplication is always commutative\n  [#5702](https://github.com/rust-lang/rust-clippy/pull/5702)\n* [`disallowed_names`]: Remove `bar` from the default configuration\n  [#5712](https://github.com/rust-lang/rust-clippy/pull/5712)\n* [`redundant_pattern_matching`]: Avoid suggesting non-`const fn` calls in const contexts\n  [#5724](https://github.com/rust-lang/rust-clippy/pull/5724)\n\n### Suggestion Fixes/Improvements\n\n* Fix suggestion of [`unit_arg`] lint, so that it suggest semantic equivalent code\n  [#4455](https://github.com/rust-lang/rust-clippy/pull/4455)\n* Add auto applicable suggestion to [`macro_use_imports`]\n  [#5279](https://github.com/rust-lang/rust-clippy/pull/5279)\n\n### ICE Fixes\n\n* Fix ICE in the `consts` module of Clippy [#5709](https://github.com/rust-lang/rust-clippy/pull/5709)\n\n### Documentation Improvements\n\n* Improve code examples across multiple lints [#5664](https://github.com/rust-lang/rust-clippy/pull/5664)\n\n### Others\n\n* Introduce a `--rustc` flag to `clippy-driver`, which turns `clippy-driver`\n  into `rustc` and passes all the given arguments to `rustc`. This is especially\n  useful for tools that need the `rustc` version Clippy was compiled with,\n  instead of the Clippy version. E.g. `clippy-driver --rustc --version` will\n  print the output of `rustc --version`.\n  [#5178](https://github.com/rust-lang/rust-clippy/pull/5178)\n* New issue templates now make it easier to complain if Clippy is too annoying\n  or not annoying enough! [#5735](https://github.com/rust-lang/rust-clippy/pull/5735)\n\n## Rust 1.45\n\nReleased 2020-07-16\n\n[View all 81 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-04-18T20%3A18%3A04Z..2020-05-27T19%3A25%3A04Z+base%3Amaster)\n\n### New lints\n\n* [`match_wildcard_for_single_variants`] [#5582](https://github.com/rust-lang/rust-clippy/pull/5582)\n* [`unsafe_derive_deserialize`] [#5493](https://github.com/rust-lang/rust-clippy/pull/5493)\n* [`if_let_mutex`] [#5332](https://github.com/rust-lang/rust-clippy/pull/5332)\n* [`mismatched_target_os`] [#5506](https://github.com/rust-lang/rust-clippy/pull/5506)\n* [`await_holding_lock`] [#5439](https://github.com/rust-lang/rust-clippy/pull/5439)\n* [`match_on_vec_items`] [#5522](https://github.com/rust-lang/rust-clippy/pull/5522)\n* [`manual_async_fn`] [#5576](https://github.com/rust-lang/rust-clippy/pull/5576)\n* [`reversed_empty_ranges`] [#5583](https://github.com/rust-lang/rust-clippy/pull/5583)\n* [`manual_non_exhaustive`] [#5550](https://github.com/rust-lang/rust-clippy/pull/5550)\n\n### Moves and Deprecations\n\n* Downgrade [`match_bool`] to pedantic [#5408](https://github.com/rust-lang/rust-clippy/pull/5408)\n* Downgrade [`match_wild_err_arm`] to pedantic and update help messages. [#5622](https://github.com/rust-lang/rust-clippy/pull/5622)\n* Downgrade [`useless_let_if_seq`] to nursery. [#5599](https://github.com/rust-lang/rust-clippy/pull/5599)\n* Generalize `option_and_then_some` and rename to [`bind_instead_of_map`]. [#5529](https://github.com/rust-lang/rust-clippy/pull/5529)\n* Rename `identity_conversion` to [`useless_conversion`]. [#5568](https://github.com/rust-lang/rust-clippy/pull/5568)\n* Merge `block_in_if_condition_expr` and `block_in_if_condition_stmt` into [`blocks_in_if_conditions`].\n[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)\n* Merge `option_map_unwrap_or`, `option_map_unwrap_or_else` and `result_map_unwrap_or_else` into [`map_unwrap_or`].\n[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)\n* Merge `option_unwrap_used` and `result_unwrap_used` into [`unwrap_used`].\n[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)\n* Merge `option_expect_used` and `result_expect_used` into [`expect_used`].\n[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)\n* Merge `for_loop_over_option` and `for_loop_over_result` into [`for_loops_over_fallibles`].\n[#5563](https://github.com/rust-lang/rust-clippy/pull/5563)\n\n### Enhancements\n\n* Avoid running cargo lints when not enabled to improve performance. [#5505](https://github.com/rust-lang/rust-clippy/pull/5505)\n* Extend [`useless_conversion`] with `TryFrom` and `TryInto`. [#5631](https://github.com/rust-lang/rust-clippy/pull/5631)\n* Lint also in type parameters and where clauses in [`unused_unit`]. [#5592](https://github.com/rust-lang/rust-clippy/pull/5592)\n* Do not suggest deriving `Default` in [`new_without_default`]. [#5616](https://github.com/rust-lang/rust-clippy/pull/5616)\n\n### False Positive Fixes\n\n* [`while_let_on_iterator`] [#5525](https://github.com/rust-lang/rust-clippy/pull/5525)\n* [`empty_line_after_outer_attr`] [#5609](https://github.com/rust-lang/rust-clippy/pull/5609)\n* [`unnecessary_unwrap`] [#5558](https://github.com/rust-lang/rust-clippy/pull/5558)\n* [`comparison_chain`] [#5596](https://github.com/rust-lang/rust-clippy/pull/5596)\n* Don't trigger [`used_underscore_binding`] in await desugaring. [#5535](https://github.com/rust-lang/rust-clippy/pull/5535)\n* Don't trigger [`borrowed_box`] on mutable references. [#5491](https://github.com/rust-lang/rust-clippy/pull/5491)\n* Allow `1 << 0` in [`identity_op`]. [#5602](https://github.com/rust-lang/rust-clippy/pull/5602)\n* Allow `use super::*;` glob imports in [`wildcard_imports`]. [#5564](https://github.com/rust-lang/rust-clippy/pull/5564)\n* Whitelist more words in [`doc_markdown`]. [#5611](https://github.com/rust-lang/rust-clippy/pull/5611)\n* Skip dev and build deps in [`multiple_crate_versions`]. [#5636](https://github.com/rust-lang/rust-clippy/pull/5636)\n* Honor `allow` attribute on arguments in [`ptr_arg`]. [#5647](https://github.com/rust-lang/rust-clippy/pull/5647)\n* Honor lint level attributes for [`redundant_field_names`], [`just_underscores_and_digits`], [`many_single_char_names`]\nand [`similar_names`]. [#5651](https://github.com/rust-lang/rust-clippy/pull/5651)\n* Ignore calls to `len` in [`or_fun_call`]. [#4429](https://github.com/rust-lang/rust-clippy/pull/4429)\n\n### Suggestion Improvements\n\n* Simplify suggestions in [`manual_memcpy`]. [#5536](https://github.com/rust-lang/rust-clippy/pull/5536)\n* Fix suggestion in [`redundant_pattern_matching`] for macros. [#5511](https://github.com/rust-lang/rust-clippy/pull/5511)\n* Avoid suggesting `copied()` for mutable references in [`map_clone`]. [#5530](https://github.com/rust-lang/rust-clippy/pull/5530)\n* Improve help message for [`clone_double_ref`]. [#5547](https://github.com/rust-lang/rust-clippy/pull/5547)\n\n### ICE Fixes\n\n* Fix ICE caused in unwrap module. [#5590](https://github.com/rust-lang/rust-clippy/pull/5590)\n* Fix ICE on rustc test issue-69020-assoc-const-arith-overflow.rs [#5499](https://github.com/rust-lang/rust-clippy/pull/5499)\n\n### Documentation\n\n* Clarify the documentation of [`unnecessary_mut_passed`]. [#5639](https://github.com/rust-lang/rust-clippy/pull/5639)\n* Extend example for [`unneeded_field_pattern`]. [#5541](https://github.com/rust-lang/rust-clippy/pull/5541)\n\n## Rust 1.44\n\nReleased 2020-06-04\n\n[View all 124 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-03-05T17%3A30%3A53Z..2020-04-18T09%3A20%3A51Z+base%3Amaster)\n\n### New lints\n\n* [`explicit_deref_methods`] [#5226](https://github.com/rust-lang/rust-clippy/pull/5226)\n* [`implicit_saturating_sub`] [#5427](https://github.com/rust-lang/rust-clippy/pull/5427)\n* [`macro_use_imports`] [#5230](https://github.com/rust-lang/rust-clippy/pull/5230)\n* [`verbose_file_reads`] [#5272](https://github.com/rust-lang/rust-clippy/pull/5272)\n* [`future_not_send`] [#5423](https://github.com/rust-lang/rust-clippy/pull/5423)\n* [`redundant_pub_crate`] [#5319](https://github.com/rust-lang/rust-clippy/pull/5319)\n* [`large_const_arrays`] [#5248](https://github.com/rust-lang/rust-clippy/pull/5248)\n* [`result_map_or_into_option`] [#5415](https://github.com/rust-lang/rust-clippy/pull/5415)\n* [`redundant_allocation`] [#5349](https://github.com/rust-lang/rust-clippy/pull/5349)\n* [`fn_address_comparisons`] [#5294](https://github.com/rust-lang/rust-clippy/pull/5294)\n* [`vtable_address_comparisons`] [#5294](https://github.com/rust-lang/rust-clippy/pull/5294)\n\n### Moves and Deprecations\n\n* Deprecate [`replace_consts`] lint [#5380](https://github.com/rust-lang/rust-clippy/pull/5380)\n* Move [`cognitive_complexity`] to nursery [#5428](https://github.com/rust-lang/rust-clippy/pull/5428)\n* Move [`useless_transmute`] to nursery [#5364](https://github.com/rust-lang/rust-clippy/pull/5364)\n* Downgrade [`inefficient_to_string`] to pedantic [#5412](https://github.com/rust-lang/rust-clippy/pull/5412)\n* Downgrade [`option_option`] to pedantic [#5401](https://github.com/rust-lang/rust-clippy/pull/5401)\n* Downgrade [`unreadable_literal`] to pedantic [#5419](https://github.com/rust-lang/rust-clippy/pull/5419)\n* Downgrade [`let_unit_value`] to pedantic [#5409](https://github.com/rust-lang/rust-clippy/pull/5409)\n* Downgrade [`trivially_copy_pass_by_ref`] to pedantic [#5410](https://github.com/rust-lang/rust-clippy/pull/5410)\n* Downgrade [`implicit_hasher`] to pedantic [#5411](https://github.com/rust-lang/rust-clippy/pull/5411)\n\n### Enhancements\n\n* On *nightly* you can now use `cargo clippy --fix -Z unstable-options` to\n  auto-fix lints that support this [#5363](https://github.com/rust-lang/rust-clippy/pull/5363)\n* Make [`redundant_clone`] also trigger on cases where the cloned value is not\n  consumed. [#5304](https://github.com/rust-lang/rust-clippy/pull/5304)\n* Expand [`integer_arithmetic`] to also disallow bit-shifting [#5430](https://github.com/rust-lang/rust-clippy/pull/5430)\n* [`option_as_ref_deref`] now detects more deref cases [#5425](https://github.com/rust-lang/rust-clippy/pull/5425)\n* [`large_enum_variant`] now report the sizes of the largest and second-largest variants [#5466](https://github.com/rust-lang/rust-clippy/pull/5466)\n* [`bool_comparison`] now also checks for inequality comparisons that can be\n  written more concisely [#5365](https://github.com/rust-lang/rust-clippy/pull/5365)\n* Expand [`clone_on_copy`] to work in method call arguments as well [#5441](https://github.com/rust-lang/rust-clippy/pull/5441)\n* [`redundant_pattern_matching`] now also handles `while let` [#5483](https://github.com/rust-lang/rust-clippy/pull/5483)\n* [`integer_arithmetic`] now also lints references of integers [#5329](https://github.com/rust-lang/rust-clippy/pull/5329)\n* Expand [`float_cmp_const`] to also work on arrays [#5345](https://github.com/rust-lang/rust-clippy/pull/5345)\n* Trigger [`map_flatten`] when map is called on an `Option` [#5473](https://github.com/rust-lang/rust-clippy/pull/5473)\n\n### False Positive Fixes\n\n* [`many_single_char_names`] [#5468](https://github.com/rust-lang/rust-clippy/pull/5468)\n* [`should_implement_trait`] [#5437](https://github.com/rust-lang/rust-clippy/pull/5437)\n* [`unused_self`] [#5387](https://github.com/rust-lang/rust-clippy/pull/5387)\n* [`redundant_clone`] [#5453](https://github.com/rust-lang/rust-clippy/pull/5453)\n* [`precedence`] [#5445](https://github.com/rust-lang/rust-clippy/pull/5445)\n* [`suspicious_op_assign_impl`] [#5424](https://github.com/rust-lang/rust-clippy/pull/5424)\n* [`needless_lifetimes`] [#5293](https://github.com/rust-lang/rust-clippy/pull/5293)\n* [`redundant_pattern`] [#5287](https://github.com/rust-lang/rust-clippy/pull/5287)\n* [`inconsistent_digit_grouping`] [#5451](https://github.com/rust-lang/rust-clippy/pull/5451)\n\n### Suggestion Improvements\n\n* Improved [`question_mark`] lint suggestion so that it doesn't add redundant `as_ref()` [#5481](https://github.com/rust-lang/rust-clippy/pull/5481)\n* Improve the suggested placeholder in [`option_map_unit_fn`] [#5292](https://github.com/rust-lang/rust-clippy/pull/5292)\n* Improve suggestion for [`match_single_binding`] when triggered inside a closure [#5350](https://github.com/rust-lang/rust-clippy/pull/5350)\n\n### ICE Fixes\n\n* Handle the unstable `trivial_bounds` feature [#5296](https://github.com/rust-lang/rust-clippy/pull/5296)\n* `shadow_*` lints [#5297](https://github.com/rust-lang/rust-clippy/pull/5297)\n\n### Documentation\n\n* Fix documentation generation for configurable lints [#5353](https://github.com/rust-lang/rust-clippy/pull/5353)\n* Update documentation for [`new_ret_no_self`] [#5448](https://github.com/rust-lang/rust-clippy/pull/5448)\n* The documentation for [`option_option`] now suggest using a tri-state enum [#5403](https://github.com/rust-lang/rust-clippy/pull/5403)\n* Fix bit mask example in [`verbose_bit_mask`] documentation [#5454](https://github.com/rust-lang/rust-clippy/pull/5454)\n* [`wildcard_imports`] documentation now mentions that `use ...::prelude::*` is\n  not linted [#5312](https://github.com/rust-lang/rust-clippy/pull/5312)\n\n## Rust 1.43\n\nReleased 2020-04-23\n\n[View all 91 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2020-01-26T16%3A01%3A11Z..2020-03-04T16%3A45%3A37Z+base%3Amaster)\n\n### New lints\n\n* [`imprecise_flops`] [#4897](https://github.com/rust-lang/rust-clippy/pull/4897)\n* [`suboptimal_flops`] [#4897](https://github.com/rust-lang/rust-clippy/pull/4897)\n* [`wildcard_imports`] [#5029](https://github.com/rust-lang/rust-clippy/pull/5029)\n* [`single_component_path_imports`] [#5058](https://github.com/rust-lang/rust-clippy/pull/5058)\n* [`match_single_binding`] [#5061](https://github.com/rust-lang/rust-clippy/pull/5061)\n* [`let_underscore_lock`] [#5101](https://github.com/rust-lang/rust-clippy/pull/5101)\n* [`struct_excessive_bools`] [#5125](https://github.com/rust-lang/rust-clippy/pull/5125)\n* [`fn_params_excessive_bools`] [#5125](https://github.com/rust-lang/rust-clippy/pull/5125)\n* [`option_env_unwrap`] [#5148](https://github.com/rust-lang/rust-clippy/pull/5148)\n* [`lossy_float_literal`] [#5202](https://github.com/rust-lang/rust-clippy/pull/5202)\n* [`rest_pat_in_fully_bound_structs`] [#5258](https://github.com/rust-lang/rust-clippy/pull/5258)\n\n### Moves and Deprecations\n\n* Move [`unneeded_field_pattern`] to pedantic group [#5200](https://github.com/rust-lang/rust-clippy/pull/5200)\n\n### Enhancements\n\n* Make [`missing_errors_doc`] lint also trigger on `async` functions\n  [#5181](https://github.com/rust-lang/rust-clippy/pull/5181)\n* Add more constants to [`approx_constant`] [#5193](https://github.com/rust-lang/rust-clippy/pull/5193)\n* Extend [`question_mark`] lint [#5266](https://github.com/rust-lang/rust-clippy/pull/5266)\n\n### False Positive Fixes\n\n* [`use_debug`] [#5047](https://github.com/rust-lang/rust-clippy/pull/5047)\n* [`unnecessary_unwrap`] [#5132](https://github.com/rust-lang/rust-clippy/pull/5132)\n* [`zero_prefixed_literal`] [#5170](https://github.com/rust-lang/rust-clippy/pull/5170)\n* [`missing_const_for_fn`] [#5216](https://github.com/rust-lang/rust-clippy/pull/5216)\n\n### Suggestion Improvements\n\n* Improve suggestion when blocks of code are suggested [#5134](https://github.com/rust-lang/rust-clippy/pull/5134)\n\n### ICE Fixes\n\n* `misc_early` lints [#5129](https://github.com/rust-lang/rust-clippy/pull/5129)\n* [`missing_errors_doc`] [#5213](https://github.com/rust-lang/rust-clippy/pull/5213)\n* Fix ICE when evaluating `usize`s [#5256](https://github.com/rust-lang/rust-clippy/pull/5256)\n\n### Documentation\n\n* Improve documentation of [`iter_nth_zero`]\n* Add documentation pages for stable releases [#5171](https://github.com/rust-lang/rust-clippy/pull/5171)\n\n### Others\n\n* Clippy now completely runs on GitHub Actions [#5190](https://github.com/rust-lang/rust-clippy/pull/5190)\n\n## Rust 1.42\n\nReleased 2020-03-12\n\n[View all 101 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-12-15T01%3A40%3A34Z..2020-01-26T11%3A22%3A13Z+base%3Amaster)\n\n### New lints\n\n* [`filetype_is_file`] [#4543](https://github.com/rust-lang/rust-clippy/pull/4543)\n* [`let_underscore_must_use`] [#4823](https://github.com/rust-lang/rust-clippy/pull/4823)\n* [`modulo_arithmetic`] [#4867](https://github.com/rust-lang/rust-clippy/pull/4867)\n* [`mem_replace_with_default`] [#4881](https://github.com/rust-lang/rust-clippy/pull/4881)\n* [`mutable_key_type`] [#4885](https://github.com/rust-lang/rust-clippy/pull/4885)\n* [`option_as_ref_deref`] [#4945](https://github.com/rust-lang/rust-clippy/pull/4945)\n* [`wildcard_in_or_patterns`] [#4960](https://github.com/rust-lang/rust-clippy/pull/4960)\n* [`iter_nth_zero`] [#4966](https://github.com/rust-lang/rust-clippy/pull/4966)\n* `invalid_atomic_ordering` [#4999](https://github.com/rust-lang/rust-clippy/pull/4999)\n* [`skip_while_next`] [#5067](https://github.com/rust-lang/rust-clippy/pull/5067)\n\n### Moves and Deprecations\n\n* Move [`transmute_float_to_int`] from nursery to complexity group\n  [#5015](https://github.com/rust-lang/rust-clippy/pull/5015)\n* Move [`range_plus_one`] to pedantic group [#5057](https://github.com/rust-lang/rust-clippy/pull/5057)\n* Move [`debug_assert_with_mut_call`] to nursery group [#5106](https://github.com/rust-lang/rust-clippy/pull/5106)\n* Deprecate `unused_label` [#4930](https://github.com/rust-lang/rust-clippy/pull/4930)\n\n### Enhancements\n\n* Lint vectored IO in [`unused_io_amount`] [#5027](https://github.com/rust-lang/rust-clippy/pull/5027)\n* Make [`vec_box`] configurable by adding a size threshold [#5081](https://github.com/rust-lang/rust-clippy/pull/5081)\n* Also lint constants in [`cmp_nan`] [#4910](https://github.com/rust-lang/rust-clippy/pull/4910)\n* Fix false negative in [`expect_fun_call`] [#4915](https://github.com/rust-lang/rust-clippy/pull/4915)\n* Fix false negative in [`redundant_clone`] [#5017](https://github.com/rust-lang/rust-clippy/pull/5017)\n\n### False Positive Fixes\n\n* [`map_clone`] [#4937](https://github.com/rust-lang/rust-clippy/pull/4937)\n* [`replace_consts`] [#4977](https://github.com/rust-lang/rust-clippy/pull/4977)\n* [`let_and_return`] [#5008](https://github.com/rust-lang/rust-clippy/pull/5008)\n* [`eq_op`] [#5079](https://github.com/rust-lang/rust-clippy/pull/5079)\n* [`possible_missing_comma`] [#5083](https://github.com/rust-lang/rust-clippy/pull/5083)\n* [`debug_assert_with_mut_call`] [#5106](https://github.com/rust-lang/rust-clippy/pull/5106)\n* Don't trigger [`let_underscore_must_use`] in external macros\n  [#5082](https://github.com/rust-lang/rust-clippy/pull/5082)\n* Don't trigger [`empty_loop`] in `no_std` crates [#5086](https://github.com/rust-lang/rust-clippy/pull/5086)\n\n### Suggestion Improvements\n\n* `option_map_unwrap_or` [#4634](https://github.com/rust-lang/rust-clippy/pull/4634)\n* [`wildcard_enum_match_arm`] [#4934](https://github.com/rust-lang/rust-clippy/pull/4934)\n* [`cognitive_complexity`] [#4935](https://github.com/rust-lang/rust-clippy/pull/4935)\n* [`decimal_literal_representation`] [#4956](https://github.com/rust-lang/rust-clippy/pull/4956)\n* `unknown_clippy_lints` [#4963](https://github.com/rust-lang/rust-clippy/pull/4963)\n* [`explicit_into_iter_loop`] [#4978](https://github.com/rust-lang/rust-clippy/pull/4978)\n* [`useless_attribute`] [#5022](https://github.com/rust-lang/rust-clippy/pull/5022)\n* `if_let_some_result` [#5032](https://github.com/rust-lang/rust-clippy/pull/5032)\n\n### ICE fixes\n\n* [`unsound_collection_transmute`] [#4975](https://github.com/rust-lang/rust-clippy/pull/4975)\n\n### Documentation\n\n* Improve documentation of [`empty_enum`], [`replace_consts`], [`redundant_clone`], and [`iterator_step_by_zero`]\n\n## Rust 1.41\n\nReleased 2020-01-30\n\n[View all 74 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-10-28T20%3A50%3A24Z..2019-12-12T00%3A53%3A03Z+base%3Amaster)\n\n* New Lints:\n  * [`exit`] [#4697](https://github.com/rust-lang/rust-clippy/pull/4697)\n  * [`to_digit_is_some`] [#4801](https://github.com/rust-lang/rust-clippy/pull/4801)\n  * [`tabs_in_doc_comments`] [#4806](https://github.com/rust-lang/rust-clippy/pull/4806)\n  * [`large_stack_arrays`] [#4807](https://github.com/rust-lang/rust-clippy/pull/4807)\n  * [`same_functions_in_if_condition`] [#4814](https://github.com/rust-lang/rust-clippy/pull/4814)\n  * [`zst_offset`] [#4816](https://github.com/rust-lang/rust-clippy/pull/4816)\n  * [`as_conversions`] [#4821](https://github.com/rust-lang/rust-clippy/pull/4821)\n  * [`missing_errors_doc`] [#4884](https://github.com/rust-lang/rust-clippy/pull/4884)\n  * [`transmute_float_to_int`] [#4889](https://github.com/rust-lang/rust-clippy/pull/4889)\n* Remove plugin interface, see\n  [Inside Rust Blog](https://blog.rust-lang.org/inside-rust/2019/11/04/Clippy-removes-plugin-interface.html) for\n  details [#4714](https://github.com/rust-lang/rust-clippy/pull/4714)\n* Move [`use_self`] to nursery group [#4863](https://github.com/rust-lang/rust-clippy/pull/4863)\n* Deprecate `into_iter_on_array` [#4788](https://github.com/rust-lang/rust-clippy/pull/4788)\n* Expand [`string_lit_as_bytes`] to also trigger when literal has escapes\n  [#4808](https://github.com/rust-lang/rust-clippy/pull/4808)\n* Fix false positive in `comparison_chain` [#4842](https://github.com/rust-lang/rust-clippy/pull/4842)\n* Fix false positive in `while_immutable_condition` [#4730](https://github.com/rust-lang/rust-clippy/pull/4730)\n* Fix false positive in `explicit_counter_loop` [#4803](https://github.com/rust-lang/rust-clippy/pull/4803)\n* Fix false positive in `must_use_candidate` [#4794](https://github.com/rust-lang/rust-clippy/pull/4794)\n* Fix false positive in `print_with_newline` and `write_with_newline`\n  [#4769](https://github.com/rust-lang/rust-clippy/pull/4769)\n* Fix false positive in `derive_hash_xor_eq` [#4766](https://github.com/rust-lang/rust-clippy/pull/4766)\n* Fix false positive in `missing_inline_in_public_items` [#4870](https://github.com/rust-lang/rust-clippy/pull/4870)\n* Fix false positive in `string_add` [#4880](https://github.com/rust-lang/rust-clippy/pull/4880)\n* Fix false positive in `float_arithmetic` [#4851](https://github.com/rust-lang/rust-clippy/pull/4851)\n* Fix false positive in `cast_sign_loss` [#4883](https://github.com/rust-lang/rust-clippy/pull/4883)\n* Fix false positive in `manual_swap` [#4877](https://github.com/rust-lang/rust-clippy/pull/4877)\n* Fix ICEs occurring while checking some block expressions [#4772](https://github.com/rust-lang/rust-clippy/pull/4772)\n* Fix ICE in `use_self` [#4776](https://github.com/rust-lang/rust-clippy/pull/4776)\n* Fix ICEs related to `const_generics` [#4780](https://github.com/rust-lang/rust-clippy/pull/4780)\n* Display help when running `clippy-driver` without arguments, instead of ICEing\n  [#4810](https://github.com/rust-lang/rust-clippy/pull/4810)\n* Clippy has its own ICE message now [#4588](https://github.com/rust-lang/rust-clippy/pull/4588)\n* Show deprecated lints in the documentation again [#4757](https://github.com/rust-lang/rust-clippy/pull/4757)\n* Improve Documentation by adding positive examples to some lints\n  [#4832](https://github.com/rust-lang/rust-clippy/pull/4832)\n\n## Rust 1.40\n\nReleased 2019-12-19\n\n[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-09-23T06%3A18%3A04Z..2019-10-28T17%3A34%3A55Z+base%3Amaster)\n\n* New Lints:\n  * [`unneeded_wildcard_pattern`] [#4537](https://github.com/rust-lang/rust-clippy/pull/4537)\n  * [`needless_doctest_main`] [#4603](https://github.com/rust-lang/rust-clippy/pull/4603)\n  * [`suspicious_unary_op_formatting`] [#4615](https://github.com/rust-lang/rust-clippy/pull/4615)\n  * [`debug_assert_with_mut_call`] [#4680](https://github.com/rust-lang/rust-clippy/pull/4680)\n  * [`unused_self`] [#4619](https://github.com/rust-lang/rust-clippy/pull/4619)\n  * [`inefficient_to_string`] [#4683](https://github.com/rust-lang/rust-clippy/pull/4683)\n  * [`must_use_unit`] [#4560](https://github.com/rust-lang/rust-clippy/pull/4560)\n  * [`must_use_candidate`] [#4560](https://github.com/rust-lang/rust-clippy/pull/4560)\n  * [`double_must_use`] [#4560](https://github.com/rust-lang/rust-clippy/pull/4560)\n  * [`comparison_chain`] [#4569](https://github.com/rust-lang/rust-clippy/pull/4569)\n  * [`unsound_collection_transmute`] [#4592](https://github.com/rust-lang/rust-clippy/pull/4592)\n  * [`panic`] [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)\n  * [`unreachable`] [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)\n  * [`todo`] [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)\n  * `option_expect_used` [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)\n  * `result_expect_used` [#4657](https://github.com/rust-lang/rust-clippy/pull/4657)\n* Move `redundant_clone` to perf group [#4509](https://github.com/rust-lang/rust-clippy/pull/4509)\n* Move `manual_mul_add` to nursery group [#4736](https://github.com/rust-lang/rust-clippy/pull/4736)\n* Expand `unit_cmp` to also work with `assert_eq!`, `debug_assert_eq!`, `assert_ne!` and `debug_assert_ne!` [#4613](https://github.com/rust-lang/rust-clippy/pull/4613)\n* Expand `integer_arithmetic` to also detect mutating arithmetic like `+=` [#4585](https://github.com/rust-lang/rust-clippy/pull/4585)\n* Fix false positive in `nonminimal_bool` [#4568](https://github.com/rust-lang/rust-clippy/pull/4568)\n* Fix false positive in `missing_safety_doc` [#4611](https://github.com/rust-lang/rust-clippy/pull/4611)\n* Fix false positive in `cast_sign_loss` [#4614](https://github.com/rust-lang/rust-clippy/pull/4614)\n* Fix false positive in `redundant_clone` [#4509](https://github.com/rust-lang/rust-clippy/pull/4509)\n* Fix false positive in `try_err` [#4721](https://github.com/rust-lang/rust-clippy/pull/4721)\n* Fix false positive in `toplevel_ref_arg` [#4570](https://github.com/rust-lang/rust-clippy/pull/4570)\n* Fix false positive in `multiple_inherent_impl` [#4593](https://github.com/rust-lang/rust-clippy/pull/4593)\n* Improve more suggestions and tests in preparation for the unstable `cargo fix --clippy` [#4575](https://github.com/rust-lang/rust-clippy/pull/4575)\n* Improve suggestion for `zero_ptr` [#4599](https://github.com/rust-lang/rust-clippy/pull/4599)\n* Improve suggestion for `explicit_counter_loop` [#4691](https://github.com/rust-lang/rust-clippy/pull/4691)\n* Improve suggestion for `mul_add` [#4602](https://github.com/rust-lang/rust-clippy/pull/4602)\n* Improve suggestion for `assertions_on_constants` [#4635](https://github.com/rust-lang/rust-clippy/pull/4635)\n* Fix ICE in `use_self` [#4671](https://github.com/rust-lang/rust-clippy/pull/4671)\n* Fix ICE when encountering const casts [#4590](https://github.com/rust-lang/rust-clippy/pull/4590)\n\n## Rust 1.39\n\nReleased 2019-11-07\n\n[View all 100 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-08-11T19%3A21%3A38Z..2019-09-22T12%3A07%3A39Z+base%3Amaster)\n\n* New Lints:\n  * [`uninit_assumed_init`] [#4479](https://github.com/rust-lang/rust-clippy/pull/4479)\n  * [`flat_map_identity`] [#4231](https://github.com/rust-lang/rust-clippy/pull/4231)\n  * [`missing_safety_doc`] [#4535](https://github.com/rust-lang/rust-clippy/pull/4535)\n  * [`mem_replace_with_uninit`] [#4511](https://github.com/rust-lang/rust-clippy/pull/4511)\n  * [`suspicious_map`] [#4394](https://github.com/rust-lang/rust-clippy/pull/4394)\n  * `option_and_then_some` [#4386](https://github.com/rust-lang/rust-clippy/pull/4386)\n  * [`manual_saturating_arithmetic`] [#4498](https://github.com/rust-lang/rust-clippy/pull/4498)\n* Deprecate `unused_collect` lint. This is fully covered by rustc's `#[must_use]` on `collect` [#4348](https://github.com/rust-lang/rust-clippy/pull/4348)\n* Move `type_repetition_in_bounds` to pedantic group [#4403](https://github.com/rust-lang/rust-clippy/pull/4403)\n* Move `cast_lossless` to pedantic group [#4539](https://github.com/rust-lang/rust-clippy/pull/4539)\n* `temporary_cstring_as_ptr` now catches more cases [#4425](https://github.com/rust-lang/rust-clippy/pull/4425)\n* `use_self` now works in constructors, too [#4525](https://github.com/rust-lang/rust-clippy/pull/4525)\n* `cargo_common_metadata` now checks for license files [#4518](https://github.com/rust-lang/rust-clippy/pull/4518)\n* `cognitive_complexity` now includes the measured complexity in the warning message [#4469](https://github.com/rust-lang/rust-clippy/pull/4469)\n* Fix false positives in `block_in_if_*` lints [#4458](https://github.com/rust-lang/rust-clippy/pull/4458)\n* Fix false positive in `cast_lossless` [#4473](https://github.com/rust-lang/rust-clippy/pull/4473)\n* Fix false positive in `clone_on_copy` [#4411](https://github.com/rust-lang/rust-clippy/pull/4411)\n* Fix false positive in `deref_addrof` [#4487](https://github.com/rust-lang/rust-clippy/pull/4487)\n* Fix false positive in `too_many_lines` [#4490](https://github.com/rust-lang/rust-clippy/pull/4490)\n* Fix false positive in `new_ret_no_self` [#4365](https://github.com/rust-lang/rust-clippy/pull/4365)\n* Fix false positive in `manual_swap` [#4478](https://github.com/rust-lang/rust-clippy/pull/4478)\n* Fix false positive in `missing_const_for_fn` [#4450](https://github.com/rust-lang/rust-clippy/pull/4450)\n* Fix false positive in `extra_unused_lifetimes` [#4477](https://github.com/rust-lang/rust-clippy/pull/4477)\n* Fix false positive in `inherent_to_string` [#4460](https://github.com/rust-lang/rust-clippy/pull/4460)\n* Fix false positive in `map_entry` [#4495](https://github.com/rust-lang/rust-clippy/pull/4495)\n* Fix false positive in `unused_unit` [#4445](https://github.com/rust-lang/rust-clippy/pull/4445)\n* Fix false positive in `redundant_pattern` [#4489](https://github.com/rust-lang/rust-clippy/pull/4489)\n* Fix false positive in `wrong_self_convention` [#4369](https://github.com/rust-lang/rust-clippy/pull/4369)\n* Improve various suggestions and tests in preparation for the unstable `cargo fix --clippy` [#4558](https://github.com/rust-lang/rust-clippy/pull/4558)\n* Improve suggestions for `redundant_pattern_matching` [#4352](https://github.com/rust-lang/rust-clippy/pull/4352)\n* Improve suggestions for `explicit_write` [#4544](https://github.com/rust-lang/rust-clippy/pull/4544)\n* Improve suggestion for `or_fun_call` [#4522](https://github.com/rust-lang/rust-clippy/pull/4522)\n* Improve suggestion for `match_as_ref` [#4446](https://github.com/rust-lang/rust-clippy/pull/4446)\n* Improve suggestion for `unnecessary_fold_span` [#4382](https://github.com/rust-lang/rust-clippy/pull/4382)\n* Add suggestions for `unseparated_literal_suffix` [#4401](https://github.com/rust-lang/rust-clippy/pull/4401)\n* Add suggestions for `char_lit_as_u8` [#4418](https://github.com/rust-lang/rust-clippy/pull/4418)\n\n## Rust 1.38\n\nReleased 2019-09-26\n\n[View all 76 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-06-30T13%3A40%3A26Z..2019-08-11T09%3A47%3A27Z+base%3Amaster)\n\n* New Lints:\n  * [`main_recursion`] [#4203](https://github.com/rust-lang/rust-clippy/pull/4203)\n  * [`inherent_to_string`] [#4259](https://github.com/rust-lang/rust-clippy/pull/4259)\n  * [`inherent_to_string_shadow_display`] [#4259](https://github.com/rust-lang/rust-clippy/pull/4259)\n  * [`type_repetition_in_bounds`] [#3766](https://github.com/rust-lang/rust-clippy/pull/3766)\n  * [`try_err`] [#4222](https://github.com/rust-lang/rust-clippy/pull/4222)\n* Move `{unnecessary,panicking}_unwrap` out of nursery [#4307](https://github.com/rust-lang/rust-clippy/pull/4307)\n* Extend the `use_self` lint to suggest uses of `Self::Variant` [#4308](https://github.com/rust-lang/rust-clippy/pull/4308)\n* Improve suggestion for needless return [#4262](https://github.com/rust-lang/rust-clippy/pull/4262)\n* Add auto-fixable suggestion for `let_unit` [#4337](https://github.com/rust-lang/rust-clippy/pull/4337)\n* Fix false positive in `pub_enum_variant_names` and `enum_variant_names` [#4345](https://github.com/rust-lang/rust-clippy/pull/4345)\n* Fix false positive in `cast_ptr_alignment` [#4257](https://github.com/rust-lang/rust-clippy/pull/4257)\n* Fix false positive in `string_lit_as_bytes` [#4233](https://github.com/rust-lang/rust-clippy/pull/4233)\n* Fix false positive in `needless_lifetimes` [#4266](https://github.com/rust-lang/rust-clippy/pull/4266)\n* Fix false positive in `float_cmp` [#4275](https://github.com/rust-lang/rust-clippy/pull/4275)\n* Fix false positives in `needless_return` [#4274](https://github.com/rust-lang/rust-clippy/pull/4274)\n* Fix false negative in `match_same_arms` [#4246](https://github.com/rust-lang/rust-clippy/pull/4246)\n* Fix incorrect suggestion for `needless_bool` [#4335](https://github.com/rust-lang/rust-clippy/pull/4335)\n* Improve suggestion for `cast_ptr_alignment` [#4257](https://github.com/rust-lang/rust-clippy/pull/4257)\n* Improve suggestion for `single_char_literal` [#4361](https://github.com/rust-lang/rust-clippy/pull/4361)\n* Improve suggestion for `len_zero` [#4314](https://github.com/rust-lang/rust-clippy/pull/4314)\n* Fix ICE in `implicit_hasher` [#4268](https://github.com/rust-lang/rust-clippy/pull/4268)\n* Fix allow bug in `trivially_copy_pass_by_ref` [#4250](https://github.com/rust-lang/rust-clippy/pull/4250)\n\n## Rust 1.37\n\nReleased 2019-08-15\n\n[View all 72 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-05-19T08%3A11%3A23Z..2019-06-25T23%3A22%3A22Z+base%3Amaster)\n\n* New Lints:\n  * [`checked_conversions`] [#4088](https://github.com/rust-lang/rust-clippy/pull/4088)\n  * [`get_last_with_len`] [#3832](https://github.com/rust-lang/rust-clippy/pull/3832)\n  * [`integer_division`] [#4195](https://github.com/rust-lang/rust-clippy/pull/4195)\n* Renamed Lint: `const_static_lifetime` is now called [`redundant_static_lifetimes`].\n  The lint now covers statics in addition to consts [#4162](https://github.com/rust-lang/rust-clippy/pull/4162)\n* [`match_same_arms`] now warns for all identical arms, instead of only the first one [#4102](https://github.com/rust-lang/rust-clippy/pull/4102)\n* [`needless_return`] now works with void functions [#4220](https://github.com/rust-lang/rust-clippy/pull/4220)\n* Fix false positive in [`redundant_closure`] [#4190](https://github.com/rust-lang/rust-clippy/pull/4190)\n* Fix false positive in [`useless_attribute`] [#4107](https://github.com/rust-lang/rust-clippy/pull/4107)\n* Fix incorrect suggestion for [`float_cmp`] [#4214](https://github.com/rust-lang/rust-clippy/pull/4214)\n* Add suggestions for [`print_with_newline`] and [`write_with_newline`] [#4136](https://github.com/rust-lang/rust-clippy/pull/4136)\n* Improve suggestions for `option_map_unwrap_or_else` and `result_map_unwrap_or_else` [#4164](https://github.com/rust-lang/rust-clippy/pull/4164)\n* Improve suggestions for [`non_ascii_literal`] [#4119](https://github.com/rust-lang/rust-clippy/pull/4119)\n* Improve diagnostics for [`let_and_return`] [#4137](https://github.com/rust-lang/rust-clippy/pull/4137)\n* Improve diagnostics for [`trivially_copy_pass_by_ref`] [#4071](https://github.com/rust-lang/rust-clippy/pull/4071)\n* Add macro check for [`unreadable_literal`] [#4099](https://github.com/rust-lang/rust-clippy/pull/4099)\n\n## Rust 1.36\n\nReleased 2019-07-04\n\n[View all 81 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-04-10T09%3A41%3A56Z..2019-05-18T00%3A29%3A40Z+base%3Amaster)\n\n* New lints: [`find_map`], [`filter_map_next`] [#4039](https://github.com/rust-lang/rust-clippy/pull/4039)\n* New lint: [`path_buf_push_overwrite`] [#3954](https://github.com/rust-lang/rust-clippy/pull/3954)\n* Move `path_buf_push_overwrite` to the nursery [#4013](https://github.com/rust-lang/rust-clippy/pull/4013)\n* Split [`redundant_closure`] into [`redundant_closure`] and [`redundant_closure_for_method_calls`] [#4110](https://github.com/rust-lang/rust-clippy/pull/4101)\n* Allow allowing of [`toplevel_ref_arg`] lint [#4007](https://github.com/rust-lang/rust-clippy/pull/4007)\n* Fix false negative in [`or_fun_call`] pertaining to nested constructors [#4084](https://github.com/rust-lang/rust-clippy/pull/4084)\n* Fix false positive in [`or_fun_call`] pertaining to enum variant constructors [#4018](https://github.com/rust-lang/rust-clippy/pull/4018)\n* Fix false positive in [`useless_let_if_seq`] pertaining to interior mutability [#4035](https://github.com/rust-lang/rust-clippy/pull/4035)\n* Fix false positive in [`redundant_closure`] pertaining to non-function types [#4008](https://github.com/rust-lang/rust-clippy/pull/4008)\n* Fix false positive in [`let_and_return`] pertaining to attributes on `let`s [#4024](https://github.com/rust-lang/rust-clippy/pull/4024)\n* Fix false positive in [`module_name_repetitions`] lint pertaining to attributes [#4006](https://github.com/rust-lang/rust-clippy/pull/4006)\n* Fix false positive on [`assertions_on_constants`] pertaining to `debug_assert!` [#3989](https://github.com/rust-lang/rust-clippy/pull/3989)\n* Improve suggestion in [`map_clone`] to suggest `.copied()` where applicable  [#3970](https://github.com/rust-lang/rust-clippy/pull/3970) [#4043](https://github.com/rust-lang/rust-clippy/pull/4043)\n* Improve suggestion for [`search_is_some`] [#4049](https://github.com/rust-lang/rust-clippy/pull/4049)\n* Improve suggestion applicability for [`naive_bytecount`] [#3984](https://github.com/rust-lang/rust-clippy/pull/3984)\n* Improve suggestion applicability for [`while_let_loop`] [#3975](https://github.com/rust-lang/rust-clippy/pull/3975)\n* Improve diagnostics for [`too_many_arguments`] [#4053](https://github.com/rust-lang/rust-clippy/pull/4053)\n* Improve diagnostics for [`cast_lossless`] [#4021](https://github.com/rust-lang/rust-clippy/pull/4021)\n* Deal with macro checks in desugarings better [#4082](https://github.com/rust-lang/rust-clippy/pull/4082)\n* Add macro check for [`unnecessary_cast`]  [#4026](https://github.com/rust-lang/rust-clippy/pull/4026)\n* Remove [`approx_constant`]'s documentation's \"Known problems\" section. [#4027](https://github.com/rust-lang/rust-clippy/pull/4027)\n* Fix ICE in [`suspicious_else_formatting`] [#3960](https://github.com/rust-lang/rust-clippy/pull/3960)\n* Fix ICE in [`decimal_literal_representation`] [#3931](https://github.com/rust-lang/rust-clippy/pull/3931)\n\n## Rust 1.35\n\nReleased 2019-05-20\n\n[1fac380..37f5c1e](https://github.com/rust-lang/rust-clippy/compare/1fac380...37f5c1e)\n\n* New lint: `drop_bounds` to detect `T: Drop` bounds\n* Split [`redundant_closure`] into [`redundant_closure`] and [`redundant_closure_for_method_calls`] [#4110](https://github.com/rust-lang/rust-clippy/pull/4101)\n* Rename `cyclomatic_complexity` to [`cognitive_complexity`], start work on making lint more practical for Rust code\n* Move [`get_unwrap`] to the restriction category\n* Improve suggestions for [`iter_cloned_collect`]\n* Improve suggestions for [`cast_lossless`] to suggest suffixed literals\n* Fix false positives in [`print_with_newline`] and [`write_with_newline`] pertaining to raw strings\n* Fix false positive in [`needless_range_loop`] pertaining to structs without a `.iter()`\n* Fix false positive in [`bool_comparison`] pertaining to non-bool types\n* Fix false positive in [`redundant_closure`] pertaining to differences in borrows\n* Fix false positive in `option_map_unwrap_or` on non-copy types\n* Fix false positives in [`missing_const_for_fn`] pertaining to macros and trait method impls\n* Fix false positive in [`needless_pass_by_value`] pertaining to procedural macros\n* Fix false positive in [`needless_continue`] pertaining to loop labels\n* Fix false positive for [`boxed_local`] pertaining to arguments moved into closures\n* Fix false positive for [`use_self`] in nested functions\n* Fix suggestion for [`expect_fun_call`] (<https://github.com/rust-lang/rust-clippy/pull/3846>)\n* Fix suggestion for [`explicit_counter_loop`] to deal with parenthesizing range variables\n* Fix suggestion for [`single_char_pattern`] to correctly escape single quotes\n* Avoid triggering [`redundant_closure`] in macros\n* ICE fixes: [#3805](https://github.com/rust-lang/rust-clippy/pull/3805), [#3772](https://github.com/rust-lang/rust-clippy/pull/3772), [#3741](https://github.com/rust-lang/rust-clippy/pull/3741)\n\n## Rust 1.34\n\nReleased 2019-04-10\n\n[View all 61 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2019-01-17T17%3A45%3A39Z..2019-02-19T08%3A24%3A05Z+base%3Amaster)\n\n* New lint: [`assertions_on_constants`] to detect for example `assert!(true)`\n* New lint: [`dbg_macro`] to detect uses of the `dbg!` macro\n* New lint: [`missing_const_for_fn`] that can suggest functions to be made `const`\n* New lint: [`too_many_lines`] to detect functions with excessive LOC. It can be\n  configured using the `too-many-lines-threshold` configuration.\n* New lint: [`wildcard_enum_match_arm`] to check for wildcard enum matches using `_`\n* Expand `redundant_closure` to also work for methods (not only functions)\n* Fix ICEs in `vec_box`, `needless_pass_by_value` and `implicit_hasher`\n* Fix false positive in `cast_sign_loss`\n* Fix false positive in `integer_arithmetic`\n* Fix false positive in `unit_arg`\n* Fix false positives in `implicit_return`\n* Add suggestion to `explicit_write`\n* Improve suggestions for `question_mark` lint\n* Fix incorrect suggestion for `cast_lossless`\n* Fix incorrect suggestion for `expect_fun_call`\n* Fix incorrect suggestion for `needless_bool`\n* Fix incorrect suggestion for `needless_range_loop`\n* Fix incorrect suggestion for `use_self`\n* Fix incorrect suggestion for `while_let_on_iterator`\n* Clippy is now slightly easier to invoke in non-cargo contexts. See\n  [#3665][pull3665] for more details.\n* We now have [improved documentation][adding_lints] on how to add new lints\n\n## Rust 1.33\n\nReleased 2019-02-26\n\n[View all 120 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-11-28T06%3A19%3A50Z..2019-01-15T09%3A27%3A02Z+base%3Amaster)\n\n* New lints: [`implicit_return`], [`vec_box`], [`cast_ref_to_mut`]\n* The `rust-clippy` repository is now part of the `rust-lang` org.\n* Rename `stutter` to `module_name_repetitions`\n* Merge `new_without_default_derive` into `new_without_default` lint\n* Move `large_digit_groups` from `style` group to `pedantic`\n* Expand `bool_comparison` to check for `<`, `<=`, `>`, `>=`, and `!=`\n  comparisons against booleans\n* Expand `no_effect` to detect writes to constants such as `A_CONST.field = 2`\n* Expand `redundant_clone` to work on struct fields\n* Expand `suspicious_else_formatting` to detect `if .. {..} {..}`\n* Expand `use_self` to work on tuple structs and also in local macros\n* Fix ICE in `result_map_unit_fn` and `option_map_unit_fn`\n* Fix false positives in `implicit_return`\n* Fix false positives in `use_self`\n* Fix false negative in `clone_on_copy`\n* Fix false positive in `doc_markdown`\n* Fix false positive in `empty_loop`\n* Fix false positive in `if_same_then_else`\n* Fix false positive in `infinite_iter`\n* Fix false positive in `question_mark`\n* Fix false positive in `useless_asref`\n* Fix false positive in `wildcard_dependencies`\n* Fix false positive in `write_with_newline`\n* Add suggestion to `explicit_write`\n* Improve suggestions for `question_mark` lint\n* Fix incorrect suggestion for `get_unwrap`\n\n## Rust 1.32\n\nReleased 2019-01-17\n\n[View all 71 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-10-24T05%3A02%3A21Z..2018-11-27T17%3A29%3A34Z+base%3Amaster)\n\n* New lints: [`slow_vector_initialization`], `mem_discriminant_non_enum`,\n  [`redundant_clone`], [`wildcard_dependencies`],\n  [`into_iter_on_ref`], `into_iter_on_array`, [`deprecated_cfg_attr`],\n  [`cargo_common_metadata`]\n* Add support for `u128` and `i128` to integer related lints\n* Add float support to `mistyped_literal_suffixes`\n* Fix false positives in `use_self`\n* Fix false positives in `missing_comma`\n* Fix false positives in `new_ret_no_self`\n* Fix false positives in `possible_missing_comma`\n* Fix false positive in `integer_arithmetic` in constant items\n* Fix false positive in `needless_borrow`\n* Fix false positive in `out_of_bounds_indexing`\n* Fix false positive in `new_without_default_derive`\n* Fix false positive in `string_lit_as_bytes`\n* Fix false negative in `out_of_bounds_indexing`\n* Fix false negative in `use_self`. It will now also check existential types\n* Fix incorrect suggestion for `redundant_closure_call`\n* Fix various suggestions that contained expanded macros\n* Fix `bool_comparison` triggering 3 times on on on the same code\n* Expand `trivially_copy_pass_by_ref` to work on trait methods\n* Improve suggestion for `needless_range_loop`\n* Move `needless_pass_by_value` from `pedantic` group to `style`\n\n## Rust 1.31\n\nReleased 2018-12-06\n\n[125907ad..2e26fdc2](https://github.com/rust-lang/rust-clippy/compare/125907ad..2e26fdc2)\n\n* Clippy has been relicensed under a dual MIT / Apache license.\n  See [#3093](https://github.com/rust-lang/rust-clippy/issues/3093) for more\n  information.\n* With Rust 1.31, Clippy is no longer available via crates.io. The recommended\n  installation method is via `rustup component add clippy`.\n* New lints: [`redundant_pattern_matching`], [`unnecessary_filter_map`],\n  [`unused_unit`], [`map_flatten`], [`mem_replace_option_with_none`]\n* Fix ICE in `if_let_redundant_pattern_matching`\n* Fix ICE in `needless_pass_by_value` when encountering a generic function\n  argument with a lifetime parameter\n* Fix ICE in `needless_range_loop`\n* Fix ICE in `single_char_pattern` when encountering a constant value\n* Fix false positive in `assign_op_pattern`\n* Fix false positive in `boxed_local` on trait implementations\n* Fix false positive in `cmp_owned`\n* Fix false positive in `collapsible_if` when conditionals have comments\n* Fix false positive in `double_parens`\n* Fix false positive in `excessive_precision`\n* Fix false positive in `explicit_counter_loop`\n* Fix false positive in `fn_to_numeric_cast_with_truncation`\n* Fix false positive in `map_clone`\n* Fix false positive in `new_ret_no_self`\n* Fix false positive in `new_without_default` when `new` is unsafe\n* Fix false positive in `type_complexity` when using extern types\n* Fix false positive in `useless_format`\n* Fix false positive in `wrong_self_convention`\n* Fix incorrect suggestion for `excessive_precision`\n* Fix incorrect suggestion for `expect_fun_call`\n* Fix incorrect suggestion for `get_unwrap`\n* Fix incorrect suggestion for `useless_format`\n* `fn_to_numeric_cast_with_truncation` lint can be disabled again\n* Improve suggestions for `manual_memcpy`\n* Improve help message for `needless_lifetimes`\n\n## Rust 1.30\n\nReleased 2018-10-25\n\n[View all 88 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2018-08-02T16%3A54%3A12Z..2018-09-17T09%3A44%3A06Z+base%3Amaster)\n\n* Deprecate `assign_ops` lint\n* New lints: [`mistyped_literal_suffixes`], [`ptr_offset_with_cast`],\n  [`needless_collect`], [`copy_iterator`]\n* `cargo clippy -V` now includes the Clippy commit hash of the Rust\n  Clippy component\n* Fix ICE in `implicit_hasher`\n* Fix ICE when encountering `println!(\"{}\" a);`\n* Fix ICE when encountering a macro call in match statements\n* Fix false positive in `default_trait_access`\n* Fix false positive in `trivially_copy_pass_by_ref`\n* Fix false positive in `similar_names`\n* Fix false positive in `redundant_field_name`\n* Fix false positive in `expect_fun_call`\n* Fix false negative in `identity_conversion`\n* Fix false negative in `explicit_counter_loop`\n* Fix `range_plus_one` suggestion and false negative\n* `print_with_newline` / `write_with_newline`: don't warn about string with several `\\n`s in them\n* Fix `useless_attribute` to also whitelist `unused_extern_crates`\n* Fix incorrect suggestion for `single_char_pattern`\n* Improve suggestion for `identity_conversion` lint\n* Move `explicit_iter_loop` and `explicit_into_iter_loop` from `style` group to `pedantic`\n* Move `range_plus_one` and `range_minus_one` from `nursery` group to `complexity`\n* Move `shadow_unrelated` from `restriction` group to `pedantic`\n* Move `indexing_slicing` from `pedantic` group to `restriction`\n\n## Rust 1.29\n\nReleased 2018-09-13\n\n[v0.0.212...14207503](https://github.com/rust-lang/rust-clippy/compare/v0.0.212...14207503)\n\n* :tada: :tada: **Rust 1.29 is the first stable Rust that includes a bundled Clippy** :tada:\n  :tada:\n  You can now run `rustup component add clippy-preview` and then `cargo\n  clippy` to run Clippy. This should put an end to the continuous nightly\n  upgrades for Clippy users.\n* Clippy now follows the Rust versioning scheme instead of its own\n* Fix ICE when encountering a `while let (..) = x.iter()` construct\n* Fix false positives in `use_self`\n* Fix false positive in `trivially_copy_pass_by_ref`\n* Fix false positive in `useless_attribute` lint\n* Fix false positive in `print_literal`\n* Fix `use_self` regressions\n* Improve lint message for `neg_cmp_op_on_partial_ord`\n* Improve suggestion highlight for `single_char_pattern`\n* Improve suggestions for various print/write macro lints\n* Improve website header\n\n## 0.0.212 (2018-07-10)\n\n* Rustup to *rustc 1.29.0-nightly (e06c87544 2018-07-06)*\n\n## 0.0.211\n\n* Rustup to *rustc 1.28.0-nightly (e3bf634e0 2018-06-28)*\n\n## 0.0.210\n\n* Rustup to *rustc 1.28.0-nightly (01cc982e9 2018-06-24)*\n\n## 0.0.209\n\n* Rustup to *rustc 1.28.0-nightly (523097979 2018-06-18)*\n\n## 0.0.208\n\n* Rustup to *rustc 1.28.0-nightly (86a8f1a63 2018-06-17)*\n\n## 0.0.207\n\n* Rustup to *rustc 1.28.0-nightly (2a0062974 2018-06-09)*\n\n## 0.0.206\n\n* Rustup to *rustc 1.28.0-nightly (5bf68db6e 2018-05-28)*\n\n## 0.0.205\n\n* Rustup to *rustc 1.28.0-nightly (990d8aa74 2018-05-25)*\n* Rename `unused_lifetimes` to `extra_unused_lifetimes` because of naming conflict with new rustc lint\n\n## 0.0.204\n\n* Rustup to *rustc 1.28.0-nightly (71e87be38 2018-05-22)*\n\n## 0.0.203\n\n* Rustup to *rustc 1.28.0-nightly (a3085756e 2018-05-19)*\n* Clippy attributes are now of the form `clippy::cyclomatic_complexity` instead of `clippy(cyclomatic_complexity)`\n\n## 0.0.202\n\n* Rustup to *rustc 1.28.0-nightly (952f344cd 2018-05-18)*\n\n## 0.0.201\n\n* Rustup to *rustc 1.27.0-nightly (2f2a11dfc 2018-05-16)*\n\n## 0.0.200\n\n* Rustup to *rustc 1.27.0-nightly (9fae15374 2018-05-13)*\n\n## 0.0.199\n\n* Rustup to *rustc 1.27.0-nightly (ff2ac35db 2018-05-12)*\n\n## 0.0.198\n\n* Rustup to *rustc 1.27.0-nightly (acd3871ba 2018-05-10)*\n\n## 0.0.197\n\n* Rustup to *rustc 1.27.0-nightly (428ea5f6b 2018-05-06)*\n\n## 0.0.196\n\n* Rustup to *rustc 1.27.0-nightly (e82261dfb 2018-05-03)*\n\n## 0.0.195\n\n* Rustup to *rustc 1.27.0-nightly (ac3c2288f 2018-04-18)*\n\n## 0.0.194\n\n* Rustup to *rustc 1.27.0-nightly (bd40cbbe1 2018-04-14)*\n* New lints: [`cast_ptr_alignment`], [`transmute_ptr_to_ptr`], [`write_literal`], [`write_with_newline`], [`writeln_empty_string`]\n\n## 0.0.193\n\n* Rustup to *rustc 1.27.0-nightly (eeea94c11 2018-04-06)*\n\n## 0.0.192\n\n* Rustup to *rustc 1.27.0-nightly (fb44b4c0e 2018-04-04)*\n* New lint: [`print_literal`]\n\n## 0.0.191\n\n* Rustup to *rustc 1.26.0-nightly (ae544ee1c 2018-03-29)*\n* Lint audit; categorize lints as style, correctness, complexity, pedantic, nursery, restriction.\n\n## 0.0.190\n\n* Fix a bunch of intermittent cargo bugs\n\n## 0.0.189\n\n* Rustup to *rustc 1.26.0-nightly (5508b2714 2018-03-18)*\n\n## 0.0.188\n\n* Rustup to *rustc 1.26.0-nightly (392645394 2018-03-15)*\n* New lint: [`while_immutable_condition`]\n\n## 0.0.187\n\n* Rustup to *rustc 1.26.0-nightly (322d7f7b9 2018-02-25)*\n* New lints: [`redundant_field_names`], [`suspicious_arithmetic_impl`], [`suspicious_op_assign_impl`]\n\n## 0.0.186\n\n* Rustup to *rustc 1.25.0-nightly (0c6091fbd 2018-02-04)*\n* Various false positive fixes\n\n## 0.0.185\n\n* Rustup to *rustc 1.25.0-nightly (56733bc9f 2018-02-01)*\n* New lint: [`question_mark`]\n\n## 0.0.184\n\n* Rustup to *rustc 1.25.0-nightly (90eb44a58 2018-01-29)*\n* New lints: [`double_comparisons`], [`empty_line_after_outer_attr`]\n\n## 0.0.183\n\n* Rustup to *rustc 1.25.0-nightly (21882aad7 2018-01-28)*\n* New lint: [`misaligned_transmute`]\n\n## 0.0.182\n\n* Rustup to *rustc 1.25.0-nightly (a0dcecff9 2018-01-24)*\n* New lint: [`decimal_literal_representation`]\n\n## 0.0.181\n\n* Rustup to *rustc 1.25.0-nightly (97520ccb1 2018-01-21)*\n* New lints: [`else_if_without_else`], [`option_option`], [`unit_arg`], [`unnecessary_fold`]\n* Removed `unit_expr`\n* Various false positive fixes for [`needless_pass_by_value`]\n\n## 0.0.180\n\n* Rustup to *rustc 1.25.0-nightly (3f92e8d89 2018-01-14)*\n\n## 0.0.179\n\n* Rustup to *rustc 1.25.0-nightly (61452e506 2018-01-09)*\n\n## 0.0.178\n\n* Rustup to *rustc 1.25.0-nightly (ee220daca 2018-01-07)*\n\n## 0.0.177\n\n* Rustup to *rustc 1.24.0-nightly (250b49205 2017-12-21)*\n* New lint: [`match_as_ref`]\n\n## 0.0.176\n\n* Rustup to *rustc 1.24.0-nightly (0077d128d 2017-12-14)*\n\n## 0.0.175\n\n* Rustup to *rustc 1.24.0-nightly (bb42071f6 2017-12-01)*\n\n## 0.0.174\n\n* Rustup to *rustc 1.23.0-nightly (63739ab7b 2017-11-21)*\n\n## 0.0.173\n\n* Rustup to *rustc 1.23.0-nightly (33374fa9d 2017-11-20)*\n\n## 0.0.172\n\n* Rustup to *rustc 1.23.0-nightly (d0f8e2913 2017-11-16)*\n\n## 0.0.171\n\n* Rustup to *rustc 1.23.0-nightly (ff0f5de3b 2017-11-14)*\n\n## 0.0.170\n\n* Rustup to *rustc 1.23.0-nightly (d6b06c63a 2017-11-09)*\n\n## 0.0.169\n\n* Rustup to *rustc 1.23.0-nightly (3b82e4c74 2017-11-05)*\n* New lints: [`just_underscores_and_digits`], `result_map_unwrap_or_else`, [`transmute_bytes_to_str`]\n\n## 0.0.168\n\n* Rustup to *rustc 1.23.0-nightly (f0fe716db 2017-10-30)*\n\n## 0.0.167\n\n* Rustup to *rustc 1.23.0-nightly (90ef3372e 2017-10-29)*\n* New lints: `const_static_lifetime`, [`erasing_op`], [`fallible_impl_from`], [`println_empty_string`], [`useless_asref`]\n\n## 0.0.166\n\n* Rustup to *rustc 1.22.0-nightly (b7960878b 2017-10-18)*\n* New lints: [`explicit_write`], `identity_conversion`, [`implicit_hasher`], `invalid_ref`, [`option_map_or_none`],\n  [`range_minus_one`], [`range_plus_one`], [`transmute_int_to_bool`], [`transmute_int_to_char`],\n  [`transmute_int_to_float`]\n\n## 0.0.165\n\n* Rust upgrade to rustc 1.22.0-nightly (0e6f4cf51 2017-09-27)\n* New lint: [`mut_range_bound`]\n\n## 0.0.164\n\n* Update to *rustc 1.22.0-nightly (6c476ce46 2017-09-25)*\n* New lint: [`int_plus_one`]\n\n## 0.0.163\n\n* Update to *rustc 1.22.0-nightly (14039a42a 2017-09-22)*\n\n## 0.0.162\n\n* Update to *rustc 1.22.0-nightly (0701b37d9 2017-09-18)*\n* New lint: [`chars_last_cmp`]\n* Improved suggestions for [`needless_borrow`], [`ptr_arg`],\n\n## 0.0.161\n\n* Update to *rustc 1.22.0-nightly (539f2083d 2017-09-13)*\n\n## 0.0.160\n\n* Update to *rustc 1.22.0-nightly (dd08c3070 2017-09-12)*\n\n## 0.0.159\n\n* Update to *rustc 1.22.0-nightly (eba374fb2 2017-09-11)*\n* New lint: [`clone_on_ref_ptr`]\n\n## 0.0.158\n\n* New lint: [`manual_memcpy`]\n* [`cast_lossless`] no longer has redundant parentheses in its suggestions\n* Update to *rustc 1.22.0-nightly (dead08cb3 2017-09-08)*\n\n## 0.0.157 - 2017-09-04\n\n* Update to *rustc 1.22.0-nightly (981ce7d8d 2017-09-03)*\n* New lint: `unit_expr`\n\n## 0.0.156 - 2017-09-03\n\n* Update to *rustc 1.22.0-nightly (744dd6c1d 2017-09-02)*\n\n## 0.0.155\n\n* Update to *rustc 1.21.0-nightly (c11f689d2 2017-08-29)*\n* New lint: [`infinite_iter`], [`maybe_infinite_iter`], [`cast_lossless`]\n\n## 0.0.154\n\n* Update to *rustc 1.21.0-nightly (2c0558f63 2017-08-24)*\n* Fix [`use_self`] triggering inside derives\n* Add support for linting an entire workspace with `cargo clippy --all`\n* New lint: [`naive_bytecount`]\n\n## 0.0.153\n\n* Update to *rustc 1.21.0-nightly (8c303ed87 2017-08-20)*\n* New lint: [`use_self`]\n\n## 0.0.152\n\n* Update to *rustc 1.21.0-nightly (df511d554 2017-08-14)*\n\n## 0.0.151\n\n* Update to *rustc 1.21.0-nightly (13d94d5fa 2017-08-10)*\n\n## 0.0.150\n\n* Update to *rustc 1.21.0-nightly (215e0b10e 2017-08-08)*\n\n## 0.0.148\n\n* Update to *rustc 1.21.0-nightly (37c7d0ebb 2017-07-31)*\n* New lints: [`unreadable_literal`], [`inconsistent_digit_grouping`], [`large_digit_groups`]\n\n## 0.0.147\n\n* Update to *rustc 1.21.0-nightly (aac223f4f 2017-07-30)*\n\n## 0.0.146\n\n* Update to *rustc 1.21.0-nightly (52a330969 2017-07-27)*\n* Fixes false positives in `inline_always`\n* Fixes false negatives in `panic_params`\n\n## 0.0.145\n\n* Update to *rustc 1.20.0-nightly (afe145d22 2017-07-23)*\n\n## 0.0.144\n\n* Update to *rustc 1.20.0-nightly (086eaa78e 2017-07-15)*\n\n## 0.0.143\n\n* Update to *rustc 1.20.0-nightly (d84693b93 2017-07-09)*\n* Fix `cargo clippy` crashing on `dylib` projects\n* Fix false positives around `nested_while_let` and `never_loop`\n\n## 0.0.142\n\n* Update to *rustc 1.20.0-nightly (067971139 2017-07-02)*\n\n## 0.0.141\n\n* Rewrite of the `doc_markdown` lint.\n* Deprecated [`range_step_by_zero`]\n* New lint: [`iterator_step_by_zero`]\n* New lint: [`needless_borrowed_reference`]\n* Update to *rustc 1.20.0-nightly (69c65d296 2017-06-28)*\n\n## 0.0.140 - 2017-06-16\n\n* Update to *rustc 1.19.0-nightly (258ae6dd9 2017-06-15)*\n\n## 0.0.139 — 2017-06-10\n\n* Update to *rustc 1.19.0-nightly (4bf5c99af 2017-06-10)*\n* Fix bugs with for loop desugaring\n* Check for [`AsRef`]/[`AsMut`] arguments in [`wrong_self_convention`]\n\n## 0.0.138 — 2017-06-05\n\n* Update to *rustc 1.19.0-nightly (0418fa9d3 2017-06-04)*\n\n## 0.0.137 — 2017-06-05\n\n* Update to *rustc 1.19.0-nightly (6684d176c 2017-06-03)*\n\n## 0.0.136 — 2017—05—26\n\n* Update to *rustc 1.19.0-nightly (557967766 2017-05-26)*\n\n## 0.0.135 — 2017—05—24\n\n* Update to *rustc 1.19.0-nightly (5b13bff52 2017-05-23)*\n\n## 0.0.134 — 2017—05—19\n\n* Update to *rustc 1.19.0-nightly (0ed1ec9f9 2017-05-18)*\n\n## 0.0.133 — 2017—05—14\n\n* Update to *rustc 1.19.0-nightly (826d8f385 2017-05-13)*\n\n## 0.0.132 — 2017—05—05\n\n* Fix various bugs and some ices\n\n## 0.0.131 — 2017—05—04\n\n* Update to *rustc 1.19.0-nightly (2d4ed8e0c 2017-05-03)*\n\n## 0.0.130 — 2017—05—03\n\n* Update to *rustc 1.19.0-nightly (6a5fc9eec 2017-05-02)*\n\n## 0.0.129 — 2017-05-01\n\n* Update to *rustc 1.19.0-nightly (06fb4d256 2017-04-30)*\n\n## 0.0.128 — 2017-04-28\n\n* Update to *rustc 1.18.0-nightly (94e884b63 2017-04-27)*\n\n## 0.0.127 — 2017-04-27\n\n* Update to *rustc 1.18.0-nightly (036983201 2017-04-26)*\n* New lint: [`needless_continue`]\n\n## 0.0.126 — 2017-04-24\n\n* Update to *rustc 1.18.0-nightly (2bd4b5c6d 2017-04-23)*\n\n## 0.0.125 — 2017-04-19\n\n* Update to *rustc 1.18.0-nightly (9f2abadca 2017-04-18)*\n\n## 0.0.124 — 2017-04-16\n\n* Update to *rustc 1.18.0-nightly (d5cf1cb64 2017-04-15)*\n\n## 0.0.123 — 2017-04-07\n\n* Fix various false positives\n\n## 0.0.122 — 2017-04-07\n\n* Rustup to *rustc 1.18.0-nightly (91ae22a01 2017-04-05)*\n* New lint: [`op_ref`]\n\n## 0.0.121 — 2017-03-21\n\n* Rustup to *rustc 1.17.0-nightly (134c4a0f0 2017-03-20)*\n\n## 0.0.120 — 2017-03-17\n\n* Rustup to *rustc 1.17.0-nightly (0aeb9c129 2017-03-15)*\n\n## 0.0.119 — 2017-03-13\n\n* Rustup to *rustc 1.17.0-nightly (824c9ebbd 2017-03-12)*\n\n## 0.0.118 — 2017-03-05\n\n* Rustup to *rustc 1.17.0-nightly (b1e31766d 2017-03-03)*\n\n## 0.0.117 — 2017-03-01\n\n* Rustup to *rustc 1.17.0-nightly (be760566c 2017-02-28)*\n\n## 0.0.116 — 2017-02-28\n\n* Fix `cargo clippy` on 64 bit windows systems\n\n## 0.0.115 — 2017-02-27\n\n* Rustup to *rustc 1.17.0-nightly (60a0edc6c 2017-02-26)*\n* New lints: [`zero_ptr`], [`never_loop`], [`mut_from_ref`]\n\n## 0.0.114 — 2017-02-08\n\n* Rustup to *rustc 1.17.0-nightly (c49d10207 2017-02-07)*\n* Tests are now ui tests (testing the exact output of rustc)\n\n## 0.0.113 — 2017-02-04\n\n* Rustup to *rustc 1.16.0-nightly (eedaa94e3 2017-02-02)*\n* New lint: [`large_enum_variant`]\n* `explicit_into_iter_loop` provides suggestions\n\n## 0.0.112 — 2017-01-27\n\n* Rustup to *rustc 1.16.0-nightly (df8debf6d 2017-01-25)*\n\n## 0.0.111 — 2017-01-21\n\n* Rustup to *rustc 1.16.0-nightly (a52da95ce 2017-01-20)*\n\n## 0.0.110 — 2017-01-20\n\n* Add badges and categories to `Cargo.toml`\n\n## 0.0.109 — 2017-01-19\n\n* Update to *rustc 1.16.0-nightly (c07a6ae77 2017-01-17)*\n\n## 0.0.108 — 2017-01-12\n\n* Update to *rustc 1.16.0-nightly (2782e8f8f 2017-01-12)*\n\n## 0.0.107 — 2017-01-11\n\n* Update regex dependency\n* Fix FP when matching `&&mut` by `&ref`\n* Reintroduce `for (_, x) in &mut hash_map` -> `for x in hash_map.values_mut()`\n* New lints: [`unused_io_amount`], [`forget_ref`], [`short_circuit_statement`]\n\n## 0.0.106 — 2017-01-04\n\n* Fix FP introduced by rustup in [`wrong_self_convention`]\n\n## 0.0.105 — 2017-01-04\n\n* Update to *rustc 1.16.0-nightly (468227129 2017-01-03)*\n* New lints: [`deref_addrof`], [`double_parens`], [`pub_enum_variant_names`]\n* Fix suggestion in [`new_without_default`]\n* FP fix in [`absurd_extreme_comparisons`]\n\n## 0.0.104 — 2016-12-15\n\n* Update to *rustc 1.15.0-nightly (8f02c429a 2016-12-15)*\n\n## 0.0.103 — 2016-11-25\n\n* Update to *rustc 1.15.0-nightly (d5814b03e 2016-11-23)*\n\n## 0.0.102 — 2016-11-24\n\n* Update to *rustc 1.15.0-nightly (3bf2be9ce 2016-11-22)*\n\n## 0.0.101 — 2016-11-23\n\n* Update to *rustc 1.15.0-nightly (7b3eeea22 2016-11-21)*\n* New lint: [`string_extend_chars`]\n\n## 0.0.100 — 2016-11-20\n\n* Update to *rustc 1.15.0-nightly (ac635aa95 2016-11-18)*\n\n## 0.0.99 — 2016-11-18\n\n* Update to rustc 1.15.0-nightly (0ed951993 2016-11-14)\n* New lint: [`get_unwrap`]\n\n## 0.0.98 — 2016-11-08\n\n* Fixes an issue due to a change in how cargo handles `--sysroot`, which broke `cargo clippy`\n\n## 0.0.97 — 2016-11-03\n\n* For convenience, `cargo clippy` defines a `cargo-clippy` feature. This was\n  previously added for a short time under the name `clippy` but removed for\n  compatibility.\n* `cargo clippy --help` is more helping (and less helpful :smile:)\n* Rustup to *rustc 1.14.0-nightly (5665bdf3e 2016-11-02)*\n* New lints: [`if_let_redundant_pattern_matching`], [`partialeq_ne_impl`]\n\n## 0.0.96 — 2016-10-22\n\n* Rustup to *rustc 1.14.0-nightly (f09420685 2016-10-20)*\n* New lint: [`iter_skip_next`]\n\n## 0.0.95 — 2016-10-06\n\n* Rustup to *rustc 1.14.0-nightly (3210fd5c2 2016-10-05)*\n\n## 0.0.94 — 2016-10-04\n\n* Fixes bustage on Windows due to forbidden directory name\n\n## 0.0.93 — 2016-10-03\n\n* Rustup to *rustc 1.14.0-nightly (144af3e97 2016-10-02)*\n* `option_map_unwrap_or` and `option_map_unwrap_or_else` are now\n  allowed by default.\n* New lint: [`explicit_into_iter_loop`]\n\n## 0.0.92 — 2016-09-30\n\n* Rustup to *rustc 1.14.0-nightly (289f3a4ca 2016-09-29)*\n\n## 0.0.91 — 2016-09-28\n\n* Rustup to *rustc 1.13.0-nightly (d0623cf7b 2016-09-26)*\n\n## 0.0.90 — 2016-09-09\n\n* Rustup to *rustc 1.13.0-nightly (f1f40f850 2016-09-09)*\n\n## 0.0.89 — 2016-09-06\n\n* Rustup to *rustc 1.13.0-nightly (cbe4de78e 2016-09-05)*\n\n## 0.0.88 — 2016-09-04\n\n* Rustup to *rustc 1.13.0-nightly (70598e04f 2016-09-03)*\n* The following lints are not new but were only usable through the `clippy`\n  lint groups: [`filter_next`], `for_loop_over_option`,\n  `for_loop_over_result` and [`match_overlapping_arm`]. You should now be\n  able to `#[allow/deny]` them individually and they are available directly\n  through `cargo clippy`.\n\n## 0.0.87 — 2016-08-31\n\n* Rustup to *rustc 1.13.0-nightly (eac41469d 2016-08-30)*\n* New lints: [`builtin_type_shadow`]\n* Fix FP in [`zero_prefixed_literal`] and `0b`/`0o`\n\n## 0.0.86 — 2016-08-28\n\n* Rustup to *rustc 1.13.0-nightly (a23064af5 2016-08-27)*\n* New lints: [`missing_docs_in_private_items`], [`zero_prefixed_literal`]\n\n## 0.0.85 — 2016-08-19\n\n* Fix ICE with [`useless_attribute`]\n* [`useless_attribute`] ignores `unused_imports` on `use` statements\n\n## 0.0.84 — 2016-08-18\n\n* Rustup to *rustc 1.13.0-nightly (aef6971ca 2016-08-17)*\n\n## 0.0.83 — 2016-08-17\n\n* Rustup to *rustc 1.12.0-nightly (1bf5fa326 2016-08-16)*\n* New lints: [`print_with_newline`], [`useless_attribute`]\n\n## 0.0.82 — 2016-08-17\n\n* Rustup to *rustc 1.12.0-nightly (197be89f3 2016-08-15)*\n* New lint: [`module_inception`]\n\n## 0.0.81 — 2016-08-14\n\n* Rustup to *rustc 1.12.0-nightly (1deb02ea6 2016-08-12)*\n* New lints: [`eval_order_dependence`], [`mixed_case_hex_literals`], [`unseparated_literal_suffix`]\n* False positive fix in [`too_many_arguments`]\n* Addition of functionality to [`needless_borrow`]\n* Suggestions for [`clone_on_copy`]\n* Bug fix in [`wrong_self_convention`]\n* Doc improvements\n\n## 0.0.80 — 2016-07-31\n\n* Rustup to *rustc 1.12.0-nightly (1225e122f 2016-07-30)*\n* New lints: [`misrefactored_assign_op`], [`serde_api_misuse`]\n\n## 0.0.79 — 2016-07-10\n\n* Rustup to *rustc 1.12.0-nightly (f93aaf84c 2016-07-09)*\n* Major suggestions refactoring\n\n## 0.0.78 — 2016-07-02\n\n* Rustup to *rustc 1.11.0-nightly (01411937f 2016-07-01)*\n* New lints: [`wrong_transmute`], [`double_neg`], [`filter_map`]\n* For compatibility, `cargo clippy` does not defines the `clippy` feature\n  introduced in 0.0.76 anymore\n* [`collapsible_if`] now considers `if let`\n\n## 0.0.77 — 2016-06-21\n\n* Rustup to *rustc 1.11.0-nightly (5522e678b 2016-06-20)*\n* New lints: `stutter` and [`iter_nth`]\n\n## 0.0.76 — 2016-06-10\n\n* Rustup to *rustc 1.11.0-nightly (7d2f75a95 2016-06-09)*\n* `cargo clippy` now automatically defines the `clippy` feature\n* New lint: [`not_unsafe_ptr_arg_deref`]\n\n## 0.0.75 — 2016-06-08\n\n* Rustup to *rustc 1.11.0-nightly (763f9234b 2016-06-06)*\n\n## 0.0.74 — 2016-06-07\n\n* Fix bug with `cargo-clippy` JSON parsing\n* Add the `CLIPPY_DISABLE_DOCS_LINKS` environment variable to deactivate the\n  “for further information visit *lint-link*” message.\n\n## 0.0.73 — 2016-06-05\n\n* Fix false positives in [`useless_let_if_seq`]\n\n## 0.0.72 — 2016-06-04\n\n* Fix false positives in [`useless_let_if_seq`]\n\n## 0.0.71 — 2016-05-31\n\n* Rustup to *rustc 1.11.0-nightly (a967611d8 2016-05-30)*\n* New lint: [`useless_let_if_seq`]\n\n## 0.0.70 — 2016-05-28\n\n* Rustup to *rustc 1.10.0-nightly (7bddce693 2016-05-27)*\n* [`invalid_regex`] and [`trivial_regex`] can now warn on `RegexSet::new`,\n  `RegexBuilder::new` and byte regexes\n\n## 0.0.69 — 2016-05-20\n\n* Rustup to *rustc 1.10.0-nightly (476fe6eef 2016-05-21)*\n* [`used_underscore_binding`] has been made `Allow` temporarily\n\n## 0.0.68 — 2016-05-17\n\n* Rustup to *rustc 1.10.0-nightly (cd6a40017 2016-05-16)*\n* New lint: [`unnecessary_operation`]\n\n## 0.0.67 — 2016-05-12\n\n* Rustup to *rustc 1.10.0-nightly (22ac88f1a 2016-05-11)*\n\n## 0.0.66 — 2016-05-11\n\n* New `cargo clippy` subcommand\n* New lints: [`assign_op_pattern`], [`assign_ops`], [`needless_borrow`]\n\n## 0.0.65 — 2016-05-08\n\n* Rustup to *rustc 1.10.0-nightly (62e2b2fb7 2016-05-06)*\n* New lints: [`float_arithmetic`], [`integer_arithmetic`]\n\n## 0.0.64 — 2016-04-26\n\n* Rustup to *rustc 1.10.0-nightly (645dd013a 2016-04-24)*\n* New lints: `temporary_cstring_as_ptr`, [`unsafe_removed_from_name`], and [`mem_forget`]\n\n## 0.0.63 — 2016-04-08\n\n* Rustup to *rustc 1.9.0-nightly (7979dd608 2016-04-07)*\n\n## 0.0.62 — 2016-04-07\n\n* Rustup to *rustc 1.9.0-nightly (bf5da36f1 2016-04-06)*\n\n## 0.0.61 — 2016-04-03\n\n* Rustup to *rustc 1.9.0-nightly (5ab11d72c 2016-04-02)*\n* New lint: [`invalid_upcast_comparisons`]\n\n## 0.0.60 — 2016-04-01\n\n* Rustup to *rustc 1.9.0-nightly (e1195c24b 2016-03-31)*\n\n## 0.0.59 — 2016-03-31\n\n* Rustup to *rustc 1.9.0-nightly (30a3849f2 2016-03-30)*\n* New lints: [`logic_bug`], [`nonminimal_bool`]\n* Fixed: [`match_same_arms`] now ignores arms with guards\n* Improved: [`useless_vec`] now warns on `for … in vec![…]`\n\n## 0.0.58 — 2016-03-27\n\n* Rustup to *rustc 1.9.0-nightly (d5a91e695 2016-03-26)*\n* New lint: [`doc_markdown`]\n\n## 0.0.57 — 2016-03-27\n\n* Update to *rustc 1.9.0-nightly (a1e29daf1 2016-03-25)*\n* Deprecated lints: [`str_to_string`], [`string_to_string`], [`unstable_as_slice`], [`unstable_as_mut_slice`]\n* New lint: [`crosspointer_transmute`]\n\n## 0.0.56 — 2016-03-23\n\n* Update to *rustc 1.9.0-nightly (0dcc413e4 2016-03-22)*\n* New lints: [`many_single_char_names`] and [`similar_names`]\n\n## 0.0.55 — 2016-03-21\n\n* Update to *rustc 1.9.0-nightly (02310fd31 2016-03-19)*\n\n## 0.0.54 — 2016-03-16\n\n* Update to *rustc 1.9.0-nightly (c66d2380a 2016-03-15)*\n\n## 0.0.53 — 2016-03-15\n\n* Add a [configuration file]\n\n## ~~0.0.52~~\n\n## 0.0.51 — 2016-03-13\n\n* Add `str` to types considered by [`len_zero`]\n* New lints: [`indexing_slicing`]\n\n## 0.0.50 — 2016-03-11\n\n* Update to *rustc 1.9.0-nightly (c9629d61c 2016-03-10)*\n\n## 0.0.49 — 2016-03-09\n\n* Update to *rustc 1.9.0-nightly (eabfc160f 2016-03-08)*\n* New lints: [`overflow_check_conditional`], `unused_label`, [`new_without_default`]\n\n## 0.0.48 — 2016-03-07\n\n* Fixed: ICE in [`needless_range_loop`] with globals\n\n## 0.0.47 — 2016-03-07\n\n* Update to *rustc 1.9.0-nightly (998a6720b 2016-03-07)*\n* New lint: [`redundant_closure_call`]\n\n[`AsMut`]: https://doc.rust-lang.org/std/convert/trait.AsMut.html\n[`AsRef`]: https://doc.rust-lang.org/std/convert/trait.AsRef.html\n[configuration file]: ./rust-clippy#configuration\n[pull3665]: https://github.com/rust-lang/rust-clippy/pull/3665\n[adding_lints]: https://github.com/rust-lang/rust-clippy/blob/master/book/src/development/adding_lints.md\n[`README.md`]: https://github.com/rust-lang/rust-clippy/blob/master/README.md\n[Clippy's lint list]: https://rust-lang.github.io/rust-clippy/master/index.html\n\n<!-- lint disable no-unused-definitions -->\n<!-- begin autogenerated links to lint list -->\n[`absolute_paths`]: https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths\n[`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons\n[`alloc_instead_of_core`]: https://rust-lang.github.io/rust-clippy/master/index.html#alloc_instead_of_core\n[`allow_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes\n[`allow_attributes_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason\n[`almost_complete_letter_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_letter_range\n[`almost_complete_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range\n[`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped\n[`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant\n[`arbitrary_source_item_ordering`]: https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering\n[`arc_with_non_send_sync`]: https://rust-lang.github.io/rust-clippy/master/index.html#arc_with_non_send_sync\n[`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects\n[`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions\n[`as_pointer_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_pointer_underscore\n[`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut\n[`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore\n[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants\n[`assertions_on_result_states`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_result_states\n[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern\n[`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops\n[`assigning_clones`]: https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones\n[`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async\n[`await_holding_invalid_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type\n[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock\n[`await_holding_refcell_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_refcell_ref\n[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask\n[`big_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#big_endian_bytes\n[`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map\n[`blacklisted_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#blacklisted_name\n[`blanket_clippy_restriction_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#blanket_clippy_restriction_lints\n[`block_in_if_condition_expr`]: https://rust-lang.github.io/rust-clippy/master/index.html#block_in_if_condition_expr\n[`block_in_if_condition_stmt`]: https://rust-lang.github.io/rust-clippy/master/index.html#block_in_if_condition_stmt\n[`blocks_in_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_conditions\n[`blocks_in_if_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_if_conditions\n[`bool_assert_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_assert_comparison\n[`bool_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison\n[`bool_to_int_with_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_to_int_with_if\n[`borrow_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr\n[`borrow_deref_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_deref_ref\n[`borrow_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const\n[`borrowed_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#borrowed_box\n[`box_collection`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_collection\n[`box_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_default\n[`box_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#box_vec\n[`boxed_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local\n[`branches_sharing_code`]: https://rust-lang.github.io/rust-clippy/master/index.html#branches_sharing_code\n[`builtin_type_shadow`]: https://rust-lang.github.io/rust-clippy/master/index.html#builtin_type_shadow\n[`byte_char_slices`]: https://rust-lang.github.io/rust-clippy/master/index.html#byte_char_slices\n[`bytes_count_to_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#bytes_count_to_len\n[`bytes_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#bytes_nth\n[`cargo_common_metadata`]: https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata\n[`case_sensitive_file_extension_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#case_sensitive_file_extension_comparisons\n[`cast_abs_to_unsigned`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned\n[`cast_enum_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_constructor\n[`cast_enum_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_enum_truncation\n[`cast_lossless`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_lossless\n[`cast_nan_to_int`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_nan_to_int\n[`cast_possible_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_possible_truncation\n[`cast_possible_wrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_possible_wrap\n[`cast_precision_loss`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_precision_loss\n[`cast_ptr_alignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_ptr_alignment\n[`cast_ref_to_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_ref_to_mut\n[`cast_sign_loss`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_sign_loss\n[`cast_slice_different_sizes`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_slice_different_sizes\n[`cast_slice_from_raw_parts`]: https://rust-lang.github.io/rust-clippy/master/index.html#cast_slice_from_raw_parts\n[`cfg_not_test`]: https://rust-lang.github.io/rust-clippy/master/index.html#cfg_not_test\n[`char_indices_as_byte_indices`]: https://rust-lang.github.io/rust-clippy/master/index.html#char_indices_as_byte_indices\n[`char_lit_as_u8`]: https://rust-lang.github.io/rust-clippy/master/index.html#char_lit_as_u8\n[`chars_last_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#chars_last_cmp\n[`chars_next_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#chars_next_cmp\n[`checked_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions\n[`clear_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#clear_with_drain\n[`clone_double_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_double_ref\n[`clone_on_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_copy\n[`clone_on_ref_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#clone_on_ref_ptr\n[`cloned_instead_of_copied`]: https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied\n[`cloned_ref_to_slice_refs`]: https://rust-lang.github.io/rust-clippy/master/index.html#cloned_ref_to_slice_refs\n[`cmp_nan`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_nan\n[`cmp_null`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_null\n[`cmp_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#cmp_owned\n[`coerce_container_to_any`]: https://rust-lang.github.io/rust-clippy/master/index.html#coerce_container_to_any\n[`cognitive_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity\n[`collapsible_else_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if\n[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if\n[`collapsible_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match\n[`collapsible_str_replace`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace\n[`collection_is_never_read`]: https://rust-lang.github.io/rust-clippy/master/index.html#collection_is_never_read\n[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain\n[`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_to_empty\n[`confusing_method_to_numeric_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#confusing_method_to_numeric_cast\n[`const_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_is_empty\n[`const_static_lifetime`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_static_lifetime\n[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator\n[`crate_in_macro_def`]: https://rust-lang.github.io/rust-clippy/master/index.html#crate_in_macro_def\n[`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir\n[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute\n[`cyclomatic_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#cyclomatic_complexity\n[`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro\n[`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call\n[`decimal_bitwise_operands`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_bitwise_operands\n[`decimal_literal_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation\n[`declare_interior_mutable_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const\n[`default_constructed_unit_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs\n[`default_instead_of_iter_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_instead_of_iter_empty\n[`default_numeric_fallback`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_numeric_fallback\n[`default_trait_access`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_trait_access\n[`default_union_representation`]: https://rust-lang.github.io/rust-clippy/master/index.html#default_union_representation\n[`deprecated_cfg_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr\n[`deprecated_clippy_cfg_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_clippy_cfg_attr\n[`deprecated_semver`]: https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_semver\n[`deref_addrof`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_addrof\n[`deref_by_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_by_slicing\n[`derivable_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls\n[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq\n[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord\n[`derive_partial_eq_without_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq\n[`derived_hash_with_manual_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derived_hash_with_manual_eq\n[`disallowed_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_fields\n[`disallowed_macros`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_macros\n[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method\n[`disallowed_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods\n[`disallowed_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names\n[`disallowed_script_idents`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents\n[`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type\n[`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types\n[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression\n[`doc_broken_link`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_broken_link\n[`doc_comment_double_space_linebreaks`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_comment_double_space_linebreaks\n[`doc_include_without_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_include_without_cfg\n[`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation\n[`doc_link_code`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_code\n[`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes\n[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown\n[`doc_nested_refdefs`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_nested_refdefs\n[`doc_overindented_list_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_overindented_list_items\n[`doc_paragraphs_missing_punctuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_paragraphs_missing_punctuation\n[`doc_suspicious_footnotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_suspicious_footnotes\n[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons\n[`double_ended_iterator_last`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_ended_iterator_last\n[`double_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use\n[`double_neg`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_neg\n[`double_parens`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_parens\n[`drain_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#drain_collect\n[`drop_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_bounds\n[`drop_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_copy\n[`drop_non_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_non_drop\n[`drop_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#drop_ref\n[`duplicate_mod`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_mod\n[`duplicate_underscore_argument`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicate_underscore_argument\n[`duplicated_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#duplicated_attributes\n[`duration_suboptimal_units`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_suboptimal_units\n[`duration_subsec`]: https://rust-lang.github.io/rust-clippy/master/index.html#duration_subsec\n[`eager_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#eager_transmute\n[`elidable_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#elidable_lifetime_names\n[`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else\n[`empty_docs`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_docs\n[`empty_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_drop\n[`empty_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum\n[`empty_enum_variants_with_brackets`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum_variants_with_brackets\n[`empty_enums`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enums\n[`empty_line_after_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_doc_comments\n[`empty_line_after_outer_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_outer_attr\n[`empty_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_loop\n[`empty_structs_with_brackets`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_structs_with_brackets\n[`enum_clike_unportable_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_clike_unportable_variant\n[`enum_glob_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_glob_use\n[`enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names\n[`eq_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#eq_op\n[`equatable_if_let`]: https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let\n[`erasing_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#erasing_op\n[`err_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#err_expect\n[`error_impl_error`]: https://rust-lang.github.io/rust-clippy/master/index.html#error_impl_error\n[`eval_order_dependence`]: https://rust-lang.github.io/rust-clippy/master/index.html#eval_order_dependence\n[`excessive_nesting`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting\n[`excessive_precision`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision\n[`exhaustive_enums`]: https://rust-lang.github.io/rust-clippy/master/index.html#exhaustive_enums\n[`exhaustive_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#exhaustive_structs\n[`exit`]: https://rust-lang.github.io/rust-clippy/master/index.html#exit\n[`expect_fun_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#expect_fun_call\n[`expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#expect_used\n[`expl_impl_clone_on_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#expl_impl_clone_on_copy\n[`explicit_auto_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref\n[`explicit_counter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_counter_loop\n[`explicit_deref_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_deref_methods\n[`explicit_into_iter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_into_iter_loop\n[`explicit_iter_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop\n[`explicit_write`]: https://rust-lang.github.io/rust-clippy/master/index.html#explicit_write\n[`extend_from_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_from_slice\n[`extend_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#extend_with_drain\n[`extra_unused_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes\n[`extra_unused_type_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters\n[`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from\n[`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default\n[`field_scoped_visibility_modifiers`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_scoped_visibility_modifiers\n[`filetype_is_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#filetype_is_file\n[`filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map\n[`filter_map_bool_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_bool_then\n[`filter_map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_identity\n[`filter_map_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next\n[`filter_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_next\n[`find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#find_map\n[`flat_map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#flat_map_identity\n[`flat_map_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#flat_map_option\n[`float_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_arithmetic\n[`float_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp\n[`float_cmp_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_cmp_const\n[`float_equality_without_abs`]: https://rust-lang.github.io/rust-clippy/master/index.html#float_equality_without_abs\n[`fn_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_address_comparisons\n[`fn_null_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_null_check\n[`fn_params_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools\n[`fn_to_numeric_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_to_numeric_cast\n[`fn_to_numeric_cast_any`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_to_numeric_cast_any\n[`fn_to_numeric_cast_with_truncation`]: https://rust-lang.github.io/rust-clippy/master/index.html#fn_to_numeric_cast_with_truncation\n[`for_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_kv_map\n[`for_loop_over_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loop_over_option\n[`for_loop_over_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loop_over_result\n[`for_loops_over_fallibles`]: https://rust-lang.github.io/rust-clippy/master/index.html#for_loops_over_fallibles\n[`forget_copy`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_copy\n[`forget_non_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_non_drop\n[`forget_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_ref\n[`format_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_collect\n[`format_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_in_format_args\n[`format_push_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_push_string\n[`four_forward_slashes`]: https://rust-lang.github.io/rust-clippy/master/index.html#four_forward_slashes\n[`from_iter_instead_of_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_iter_instead_of_collect\n[`from_over_into`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into\n[`from_raw_with_void_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_raw_with_void_ptr\n[`from_str_radix_10`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_str_radix_10\n[`future_not_send`]: https://rust-lang.github.io/rust-clippy/master/index.html#future_not_send\n[`get_first`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_first\n[`get_last_with_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_last_with_len\n[`get_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_unwrap\n[`host_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#host_endian_bytes\n[`identity_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_conversion\n[`identity_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_op\n[`if_let_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_mutex\n[`if_let_redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_redundant_pattern_matching\n[`if_let_some_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_some_result\n[`if_not_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else\n[`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else\n[`if_then_some_else_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none\n[`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond\n[`ignore_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#ignore_without_reason\n[`ignored_unit_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ignored_unit_patterns\n[`impl_hash_borrow_with_str_and_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#impl_hash_borrow_with_str_and_bytes\n[`impl_trait_in_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#impl_trait_in_params\n[`implicit_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_clone\n[`implicit_hasher`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_hasher\n[`implicit_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_return\n[`implicit_saturating_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_add\n[`implicit_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#implicit_saturating_sub\n[`implied_bounds_in_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#implied_bounds_in_impls\n[`impossible_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#impossible_comparisons\n[`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops\n[`incompatible_msrv`]: https://rust-lang.github.io/rust-clippy/master/index.html#incompatible_msrv\n[`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping\n[`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor\n[`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_clone_impl_on_copy_type\n[`incorrect_partial_ord_impl_on_ord_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_partial_ord_impl_on_ord_type\n[`index_refutable_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice\n[`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing\n[`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask\n[`ineffective_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_open_options\n[`inefficient_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string\n[`infallible_destructuring_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#infallible_destructuring_match\n[`infallible_try_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#infallible_try_from\n[`infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#infinite_iter\n[`infinite_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#infinite_loop\n[`inherent_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string\n[`inherent_to_string_shadow_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string_shadow_display\n[`init_numbered_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#init_numbered_fields\n[`inline_always`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_always\n[`inline_asm_x86_att_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_att_syntax\n[`inline_asm_x86_intel_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_intel_syntax\n[`inline_fn_without_body`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_fn_without_body\n[`inspect_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#inspect_for_each\n[`int_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#int_plus_one\n[`integer_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_arithmetic\n[`integer_division`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_division\n[`integer_division_remainder_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_division_remainder_used\n[`into_iter_on_array`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_array\n[`into_iter_on_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_ref\n[`into_iter_without_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_without_iter\n[`invalid_atomic_ordering`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_atomic_ordering\n[`invalid_null_ptr_usage`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_null_ptr_usage\n[`invalid_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_ref\n[`invalid_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_regex\n[`invalid_upcast_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_upcast_comparisons\n[`invalid_utf8_in_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_utf8_in_unchecked\n[`inverted_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#inverted_saturating_sub\n[`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters\n[`io_other_error`]: https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error\n[`ip_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#ip_constant\n[`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/master/index.html#is_digit_ascii_radix\n[`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements\n[`items_after_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_test_module\n[`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect\n[`iter_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_count\n[`iter_filter_is_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_filter_is_ok\n[`iter_filter_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_filter_is_some\n[`iter_kv_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map\n[`iter_next_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_loop\n[`iter_next_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_slice\n[`iter_not_returning_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_not_returning_iterator\n[`iter_nth`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth\n[`iter_nth_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_nth_zero\n[`iter_on_empty_collections`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_empty_collections\n[`iter_on_single_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_on_single_items\n[`iter_out_of_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_out_of_bounds\n[`iter_over_hash_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_over_hash_type\n[`iter_overeager_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_overeager_cloned\n[`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next\n[`iter_skip_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_zero\n[`iter_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_with_drain\n[`iter_without_into_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_without_into_iter\n[`iterator_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iterator_step_by_zero\n[`join_absolute_paths`]: https://rust-lang.github.io/rust-clippy/master/index.html#join_absolute_paths\n[`just_underscores_and_digits`]: https://rust-lang.github.io/rust-clippy/master/index.html#just_underscores_and_digits\n[`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays\n[`large_digit_groups`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_digit_groups\n[`large_enum_variant`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant\n[`large_futures`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_futures\n[`large_include_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file\n[`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays\n[`large_stack_frames`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames\n[`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value\n[`legacy_numeric_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants\n[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty\n[`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero\n[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return\n[`let_underscore_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop\n[`let_underscore_future`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_future\n[`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_lock\n[`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use\n[`let_underscore_untyped`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped\n[`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value\n[`let_with_type_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_with_type_underscore\n[`lines_filter_map_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok\n[`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist\n[`lint_groups_priority`]: https://rust-lang.github.io/rust-clippy/master/index.html#lint_groups_priority\n[`literal_string_with_formatting_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#literal_string_with_formatting_args\n[`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes\n[`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug\n[`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal\n[`macro_metavars_in_unsafe`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_metavars_in_unsafe\n[`macro_use_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_use_imports\n[`main_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#main_recursion\n[`manual_abs_diff`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_abs_diff\n[`manual_assert`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert\n[`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn\n[`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits\n[`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals\n[`manual_checked_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_checked_ops\n[`manual_clamp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp\n[`manual_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_contains\n[`manual_dangling_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_dangling_ptr\n[`manual_div_ceil`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_div_ceil\n[`manual_filter`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter\n[`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map\n[`manual_find`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find\n[`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map\n[`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten\n[`manual_hash_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one\n[`manual_ignore_case_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ignore_case_cmp\n[`manual_ilog2`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ilog2\n[`manual_inspect`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect\n[`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed\n[`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check\n[`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite\n[`manual_is_infinite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_infinite\n[`manual_is_multiple_of`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_multiple_of\n[`manual_is_power_of_two`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_power_of_two\n[`manual_is_variant_and`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_variant_and\n[`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else\n[`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str\n[`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map\n[`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy\n[`manual_midpoint`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_midpoint\n[`manual_next_back`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_next_back\n[`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive\n[`manual_ok_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err\n[`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or\n[`manual_option_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice\n[`manual_pattern_char_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison\n[`manual_pop_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pop_if\n[`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains\n[`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_patterns\n[`manual_rem_euclid`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid\n[`manual_repeat_n`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_repeat_n\n[`manual_retain`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain\n[`manual_rotate`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rotate\n[`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic\n[`manual_slice_fill`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill\n[`manual_slice_size_calculation`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_size_calculation\n[`manual_split_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once\n[`manual_str_repeat`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat\n[`manual_string_new`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_string_new\n[`manual_strip`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip\n[`manual_swap`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_swap\n[`manual_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_take\n[`manual_try_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold\n[`manual_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or\n[`manual_unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or_default\n[`manual_while_let_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_while_let_some\n[`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names\n[`map_all_any_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_all_any_identity\n[`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone\n[`map_collect_result_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_collect_result_unit\n[`map_entry`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_entry\n[`map_err_ignore`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_err_ignore\n[`map_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten\n[`map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_identity\n[`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or\n[`map_with_unused_argument_over_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges\n[`match_as_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_as_ref\n[`match_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_bool\n[`match_like_matches_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro\n[`match_on_vec_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_on_vec_items\n[`match_overlapping_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_overlapping_arm\n[`match_ref_pats`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_ref_pats\n[`match_result_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_result_ok\n[`match_same_arms`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_same_arms\n[`match_single_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_single_binding\n[`match_str_case_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_str_case_mismatch\n[`match_wild_err_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wild_err_arm\n[`match_wildcard_for_single_variants`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants\n[`maybe_infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_infinite_iter\n[`maybe_misused_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_misused_cfg\n[`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_discriminant_non_enum\n[`mem_forget`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_forget\n[`mem_replace_option_with_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_none\n[`mem_replace_option_with_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_some\n[`mem_replace_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default\n[`mem_replace_with_uninit`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_uninit\n[`min_ident_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars\n[`min_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_max\n[`misaligned_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#misaligned_transmute\n[`mismatched_target_os`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatched_target_os\n[`mismatching_type_param_order`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatching_type_param_order\n[`misnamed_getters`]: https://rust-lang.github.io/rust-clippy/master/index.html#misnamed_getters\n[`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op\n[`missing_assert_message`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_assert_message\n[`missing_asserts_for_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_asserts_for_indexing\n[`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn\n[`missing_const_for_thread_local`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_thread_local\n[`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items\n[`missing_enforced_import_renames`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames\n[`missing_errors_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc\n[`missing_fields_in_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_fields_in_debug\n[`missing_inline_in_public_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_inline_in_public_items\n[`missing_panics_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc\n[`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc\n[`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_spin_loop\n[`missing_trait_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_trait_methods\n[`missing_transmute_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_transmute_annotations\n[`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes\n[`mixed_attributes_style`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_attributes_style\n[`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals\n[`mixed_read_write_in_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_read_write_in_expression\n[`mod_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#mod_module_files\n[`module_inception`]: https://rust-lang.github.io/rust-clippy/master/index.html#module_inception\n[`module_name_repetitions`]: https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions\n[`modulo_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic\n[`modulo_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#modulo_one\n[`multi_assignments`]: https://rust-lang.github.io/rust-clippy/master/index.html#multi_assignments\n[`multiple_bound_locations`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_bound_locations\n[`multiple_crate_versions`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions\n[`multiple_inherent_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl\n[`multiple_unsafe_ops_per_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#multiple_unsafe_ops_per_block\n[`must_use_candidate`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_candidate\n[`must_use_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#must_use_unit\n[`mut_from_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_from_ref\n[`mut_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_mut\n[`mut_mutex_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_mutex_lock\n[`mut_range_bound`]: https://rust-lang.github.io/rust-clippy/master/index.html#mut_range_bound\n[`mutable_key_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type\n[`mutex_atomic`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_atomic\n[`mutex_integer`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer\n[`naive_bytecount`]: https://rust-lang.github.io/rust-clippy/master/index.html#naive_bytecount\n[`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type\n[`needless_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_as_bytes\n[`needless_bitwise_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bitwise_bool\n[`needless_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool\n[`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign\n[`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow\n[`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference\n[`needless_borrows_for_generic_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args\n[`needless_character_iteration`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_character_iteration\n[`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect\n[`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue\n[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main\n[`needless_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_else\n[`needless_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_for_each\n[`needless_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_if\n[`needless_ifs`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_ifs\n[`needless_late_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init\n[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes\n[`needless_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_match\n[`needless_maybe_sized`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_maybe_sized\n[`needless_option_as_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_as_deref\n[`needless_option_take`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_option_take\n[`needless_parens_on_range_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_parens_on_range_literals\n[`needless_pass_by_ref_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut\n[`needless_pass_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value\n[`needless_pub_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_pub_self\n[`needless_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_question_mark\n[`needless_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_range_loop\n[`needless_raw_string_hashes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes\n[`needless_raw_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_strings\n[`needless_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return\n[`needless_return_with_question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_return_with_question_mark\n[`needless_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_splitn\n[`needless_type_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_type_cast\n[`needless_update`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_update\n[`neg_cmp_op_on_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_cmp_op_on_partial_ord\n[`neg_multiply`]: https://rust-lang.github.io/rust-clippy/master/index.html#neg_multiply\n[`negative_feature_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#negative_feature_names\n[`never_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#never_loop\n[`new_ret_no_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#new_ret_no_self\n[`new_without_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default\n[`new_without_default_derive`]: https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default_derive\n[`no_effect`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect\n[`no_effect_replace`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect_replace\n[`no_effect_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect_underscore_binding\n[`no_mangle_with_rust_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_mangle_with_rust_abi\n[`non_ascii_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_ascii_literal\n[`non_canonical_clone_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_canonical_clone_impl\n[`non_canonical_partial_ord_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_canonical_partial_ord_impl\n[`non_minimal_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_minimal_cfg\n[`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_octal_unix_permissions\n[`non_send_fields_in_send_ty`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty\n[`non_std_lazy_statics`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics\n[`non_zero_suggestions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_zero_suggestions\n[`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool\n[`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options\n[`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces\n[`not_unsafe_ptr_arg_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#not_unsafe_ptr_arg_deref\n[`obfuscated_if_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#obfuscated_if_else\n[`octal_escapes`]: https://rust-lang.github.io/rust-clippy/master/index.html#octal_escapes\n[`ok_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#ok_expect\n[`only_used_in_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#only_used_in_recursion\n[`op_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#op_ref\n[`option_and_then_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_and_then_some\n[`option_as_ref_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_cloned\n[`option_as_ref_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref\n[`option_env_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_env_unwrap\n[`option_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_expect_used\n[`option_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_filter_map\n[`option_if_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_if_let_else\n[`option_map_or_err_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_or_err_ok\n[`option_map_or_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_or_none\n[`option_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unit_fn\n[`option_map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or\n[`option_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or_else\n[`option_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_option\n[`option_unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#option_unwrap_used\n[`or_fun_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call\n[`or_then_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#or_then_unwrap\n[`out_of_bounds_indexing`]: https://rust-lang.github.io/rust-clippy/master/index.html#out_of_bounds_indexing\n[`overflow_check_conditional`]: https://rust-lang.github.io/rust-clippy/master/index.html#overflow_check_conditional\n[`overly_complex_bool_expr`]: https://rust-lang.github.io/rust-clippy/master/index.html#overly_complex_bool_expr\n[`owned_cow`]: https://rust-lang.github.io/rust-clippy/master/index.html#owned_cow\n[`panic`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic\n[`panic_in_result_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_in_result_fn\n[`panic_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#panic_params\n[`panicking_overflow_checks`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_overflow_checks\n[`panicking_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#panicking_unwrap\n[`partial_pub_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#partial_pub_fields\n[`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl\n[`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none\n[`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite\n[`path_ends_with_ext`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext\n[`pathbuf_init_then_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#pathbuf_init_then_push\n[`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch\n[`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/master/index.html#permissions_set_readonly_false\n[`pointer_format`]: https://rust-lang.github.io/rust-clippy/master/index.html#pointer_format\n[`pointers_in_nomem_asm_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#pointers_in_nomem_asm_block\n[`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters\n[`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma\n[`possible_missing_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_else\n[`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence\n[`precedence_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence_bits\n[`print_in_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_in_format_impl\n[`print_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_literal\n[`print_stderr`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr\n[`print_stdout`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout\n[`print_with_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_with_newline\n[`println_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#println_empty_string\n[`ptr_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg\n[`ptr_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr\n[`ptr_cast_constness`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_cast_constness\n[`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq\n[`ptr_offset_by_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_by_literal\n[`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast\n[`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names\n[`pub_underscore_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields\n[`pub_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_use\n[`pub_with_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_with_shorthand\n[`pub_without_shorthand`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_without_shorthand\n[`question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark\n[`question_mark_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark_used\n[`range_minus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_minus_one\n[`range_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one\n[`range_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_step_by_zero\n[`range_zip_with_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_zip_with_len\n[`rc_buffer`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer\n[`rc_clone_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_clone_in_vec_init\n[`rc_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex\n[`read_line_without_trim`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_line_without_trim\n[`read_zero_byte_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_zero_byte_vec\n[`readonly_write_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#readonly_write_lock\n[`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl\n[`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation\n[`redundant_as_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_as_str\n[`redundant_async_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_async_block\n[`redundant_at_rest_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_at_rest_pattern\n[`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone\n[`redundant_closure`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure\n[`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call\n[`redundant_closure_for_method_calls`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls\n[`redundant_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_comparisons\n[`redundant_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else\n[`redundant_feature_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_feature_names\n[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names\n[`redundant_guards`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_guards\n[`redundant_iter_cloned`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_iter_cloned\n[`redundant_locals`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_locals\n[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern\n[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching\n[`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate\n[`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing\n[`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes\n[`redundant_test_prefix`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_test_prefix\n[`redundant_type_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_type_annotations\n[`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr\n[`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference\n[`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref\n[`ref_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option\n[`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref\n[`ref_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_patterns\n[`regex_creation_in_loops`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_creation_in_loops\n[`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro\n[`renamed_function_params`]: https://rust-lang.github.io/rust-clippy/master/index.html#renamed_function_params\n[`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once\n[`repeat_vec_with_capacity`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity\n[`replace_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_box\n[`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts\n[`repr_packed_without_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#repr_packed_without_abi\n[`reserve_after_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#reserve_after_initialization\n[`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pat_in_fully_bound_structs\n[`result_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_expect_used\n[`result_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_filter_map\n[`result_large_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err\n[`result_map_or_into_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_or_into_option\n[`result_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unit_fn\n[`result_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else\n[`result_unit_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unit_err\n[`result_unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unwrap_used\n[`return_and_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#return_and_then\n[`return_self_not_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#return_self_not_must_use\n[`reverse_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#reverse_range_loop\n[`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges\n[`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_functions_in_if_condition\n[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push\n[`same_length_and_capacity`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_length_and_capacity\n[`same_name_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_name_method\n[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some\n[`seek_from_current`]: https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current\n[`seek_to_start_instead_of_rewind`]: https://rust-lang.github.io/rust-clippy/master/index.html#seek_to_start_instead_of_rewind\n[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment\n[`self_named_constructors`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructors\n[`self_named_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_module_files\n[`self_only_used_in_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_only_used_in_recursion\n[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned\n[`semicolon_inside_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block\n[`semicolon_outside_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block\n[`separated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#separated_literal_suffix\n[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse\n[`set_contains_or_insert`]: https://rust-lang.github.io/rust-clippy/master/index.html#set_contains_or_insert\n[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse\n[`shadow_same`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_same\n[`shadow_unrelated`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_unrelated\n[`short_circuit_statement`]: https://rust-lang.github.io/rust-clippy/master/index.html#short_circuit_statement\n[`should_assert_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_assert_eq\n[`should_implement_trait`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait\n[`should_panic_without_expect`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_panic_without_expect\n[`significant_drop_in_scrutinee`]: https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_in_scrutinee\n[`significant_drop_tightening`]: https://rust-lang.github.io/rust-clippy/master/index.html#significant_drop_tightening\n[`similar_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#similar_names\n[`single_call_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn\n[`single_char_add_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str\n[`single_char_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_lifetime_names\n[`single_char_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern\n[`single_char_push_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_push_str\n[`single_component_path_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_component_path_imports\n[`single_element_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_element_loop\n[`single_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match\n[`single_match_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else\n[`single_option_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_option_map\n[`single_range_in_vec_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_range_in_vec_init\n[`size_of_in_element_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_in_element_count\n[`size_of_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_ref\n[`skip_while_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#skip_while_next\n[`sliced_string_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#sliced_string_as_bytes\n[`slow_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#slow_vector_initialization\n[`stable_sort_primitive`]: https://rust-lang.github.io/rust-clippy/master/index.html#stable_sort_primitive\n[`std_instead_of_alloc`]: https://rust-lang.github.io/rust-clippy/master/index.html#std_instead_of_alloc\n[`std_instead_of_core`]: https://rust-lang.github.io/rust-clippy/master/index.html#std_instead_of_core\n[`str_split_at_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#str_split_at_newline\n[`str_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#str_to_string\n[`string_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add\n[`string_add_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add_assign\n[`string_extend_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_extend_chars\n[`string_from_utf8_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_from_utf8_as_bytes\n[`string_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_as_bytes\n[`string_lit_chars_any`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_chars_any\n[`string_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_slice\n[`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string\n[`strlen_on_c_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#strlen_on_c_strings\n[`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools\n[`struct_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names\n[`stutter`]: https://rust-lang.github.io/rust-clippy/master/index.html#stutter\n[`suboptimal_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#suboptimal_flops\n[`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_arithmetic_impl\n[`suspicious_assignment_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_assignment_formatting\n[`suspicious_command_arg_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_command_arg_space\n[`suspicious_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_doc_comments\n[`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting\n[`suspicious_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_map\n[`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl\n[`suspicious_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_open_options\n[`suspicious_operation_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_operation_groupings\n[`suspicious_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_splitn\n[`suspicious_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_to_owned\n[`suspicious_unary_op_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_unary_op_formatting\n[`suspicious_xor_used_as_pow`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_xor_used_as_pow\n[`swap_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#swap_ptr_to_ref\n[`swap_with_temporary`]: https://rust-lang.github.io/rust-clippy/master/index.html#swap_with_temporary\n[`tabs_in_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#tabs_in_doc_comments\n[`temporary_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_assignment\n[`temporary_cstring_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#temporary_cstring_as_ptr\n[`test_attr_in_doctest`]: https://rust-lang.github.io/rust-clippy/master/index.html#test_attr_in_doctest\n[`tests_outside_test_module`]: https://rust-lang.github.io/rust-clippy/master/index.html#tests_outside_test_module\n[`thread_local_initializer_can_be_made_const`]: https://rust-lang.github.io/rust-clippy/master/index.html#thread_local_initializer_can_be_made_const\n[`to_digit_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some\n[`to_string_in_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_display\n[`to_string_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_format_args\n[`to_string_trait_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_trait_impl\n[`todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo\n[`too_long_first_doc_paragraph`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_long_first_doc_paragraph\n[`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments\n[`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines\n[`toplevel_ref_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#toplevel_ref_arg\n[`trailing_empty_array`]: https://rust-lang.github.io/rust-clippy/master/index.html#trailing_empty_array\n[`trait_duplication_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#trait_duplication_in_bounds\n[`transmute_bytes_to_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_bytes_to_str\n[`transmute_float_to_int`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_float_to_int\n[`transmute_int_to_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_bool\n[`transmute_int_to_char`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_char\n[`transmute_int_to_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_float\n[`transmute_int_to_non_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_int_to_non_zero\n[`transmute_null_to_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_null_to_fn\n[`transmute_num_to_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_num_to_bytes\n[`transmute_ptr_to_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ptr\n[`transmute_ptr_to_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref\n[`transmute_undefined_repr`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmute_undefined_repr\n[`transmutes_expressible_as_ptr_casts`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmutes_expressible_as_ptr_casts\n[`transmuting_null`]: https://rust-lang.github.io/rust-clippy/master/index.html#transmuting_null\n[`trim_split_whitespace`]: https://rust-lang.github.io/rust-clippy/master/index.html#trim_split_whitespace\n[`trivial_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivial_regex\n[`trivially_copy_pass_by_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref\n[`try_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#try_err\n[`tuple_array_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions\n[`type_complexity`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity\n[`type_id_on_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_id_on_box\n[`type_repetition_in_bounds`]: https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds\n[`unbuffered_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#unbuffered_bytes\n[`unchecked_duration_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction\n[`unchecked_time_subtraction`]: https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_time_subtraction\n[`unconditional_recursion`]: https://rust-lang.github.io/rust-clippy/master/index.html#unconditional_recursion\n[`undocumented_unsafe_blocks`]: https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks\n[`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/master/index.html#undropped_manually_drops\n[`unicode_not_nfc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unicode_not_nfc\n[`unimplemented`]: https://rust-lang.github.io/rust-clippy/master/index.html#unimplemented\n[`uninhabited_references`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninhabited_references\n[`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_assumed_init\n[`uninit_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_vec\n[`uninlined_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args\n[`unit_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_arg\n[`unit_cmp`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_cmp\n[`unit_hash`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_hash\n[`unit_return_expecting_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#unit_return_expecting_ord\n[`unknown_clippy_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#unknown_clippy_lints\n[`unnecessary_box_returns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns\n[`unnecessary_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast\n[`unnecessary_clippy_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_clippy_cfg\n[`unnecessary_debug_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_debug_formatting\n[`unnecessary_fallible_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions\n[`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map\n[`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_find_map\n[`unnecessary_first_then_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_first_then_check\n[`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold\n[`unnecessary_get_then_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check\n[`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_join\n[`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations\n[`unnecessary_literal_bound`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_bound\n[`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap\n[`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor\n[`unnecessary_map_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_or\n[`unnecessary_min_or_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_min_or_max\n[`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed\n[`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation\n[`unnecessary_option_map_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_option_map_or_else\n[`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings\n[`unnecessary_result_map_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_result_map_or_else\n[`unnecessary_safety_comment`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_comment\n[`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc\n[`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports\n[`unnecessary_semicolon`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_semicolon\n[`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by\n[`unnecessary_struct_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_struct_initialization\n[`unnecessary_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned\n[`unnecessary_trailing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_trailing_comma\n[`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap\n[`unnecessary_wraps`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps\n[`unneeded_field_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_field_pattern\n[`unneeded_struct_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern\n[`unneeded_wildcard_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_wildcard_pattern\n[`unnested_or_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns\n[`unreachable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreachable\n[`unreadable_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal\n[`unsafe_derive_deserialize`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_derive_deserialize\n[`unsafe_removed_from_name`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_removed_from_name\n[`unsafe_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_vector_initialization\n[`unseparated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#unseparated_literal_suffix\n[`unsound_collection_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#unsound_collection_transmute\n[`unstable_as_mut_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_mut_slice\n[`unstable_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#unstable_as_slice\n[`unused_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_async\n[`unused_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_collect\n[`unused_enumerate_index`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_enumerate_index\n[`unused_format_specs`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_format_specs\n[`unused_io_amount`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_io_amount\n[`unused_label`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_label\n[`unused_peekable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_peekable\n[`unused_result_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_result_ok\n[`unused_rounding`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_rounding\n[`unused_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_self\n[`unused_trait_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names\n[`unused_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit\n[`unusual_byte_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unusual_byte_groupings\n[`unwrap_in_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_in_result\n[`unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_or_default\n[`unwrap_or_else_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_or_else_default\n[`unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used\n[`upper_case_acronyms`]: https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms\n[`use_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_debug\n[`use_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_self\n[`used_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_binding\n[`used_underscore_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_items\n[`useless_asref`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_asref\n[`useless_attribute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_attribute\n[`useless_concat`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_concat\n[`useless_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion\n[`useless_format`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_format\n[`useless_let_if_seq`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_let_if_seq\n[`useless_nonzero_new_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_nonzero_new_unchecked\n[`useless_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_transmute\n[`useless_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec\n[`vec_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_box\n[`vec_init_then_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_init_then_push\n[`vec_resize_to_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_resize_to_zero\n[`verbose_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask\n[`verbose_file_reads`]: https://rust-lang.github.io/rust-clippy/master/index.html#verbose_file_reads\n[`volatile_composites`]: https://rust-lang.github.io/rust-clippy/master/index.html#volatile_composites\n[`vtable_address_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#vtable_address_comparisons\n[`waker_clone_wake`]: https://rust-lang.github.io/rust-clippy/master/index.html#waker_clone_wake\n[`while_float`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_float\n[`while_immutable_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_immutable_condition\n[`while_let_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_loop\n[`while_let_on_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator\n[`wildcard_dependencies`]: https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_dependencies\n[`wildcard_enum_match_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_enum_match_arm\n[`wildcard_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports\n[`wildcard_in_or_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_in_or_patterns\n[`write_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#write_literal\n[`write_with_newline`]: https://rust-lang.github.io/rust-clippy/master/index.html#write_with_newline\n[`writeln_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#writeln_empty_string\n[`wrong_pub_self_convention`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_pub_self_convention\n[`wrong_self_convention`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention\n[`wrong_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#wrong_transmute\n[`zero_divided_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_divided_by_zero\n[`zero_prefixed_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_prefixed_literal\n[`zero_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr\n[`zero_repeat_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_repeat_side_effects\n[`zero_sized_map_values`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_sized_map_values\n[`zero_width_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_width_space\n[`zombie_processes`]: https://rust-lang.github.io/rust-clippy/master/index.html#zombie_processes\n[`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset\n<!-- end autogenerated links to lint list -->\n<!-- begin autogenerated links to configuration documentation -->\n[`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates\n[`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments\n[`accept-comment-above-attributes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-attributes\n[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement\n[`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero\n[`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests\n[`allow-exact-repetitions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-exact-repetitions\n[`allow-expect-in-consts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-consts\n[`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests\n[`allow-indexing-slicing-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-indexing-slicing-in-tests\n[`allow-large-stack-frames-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-large-stack-frames-in-tests\n[`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args\n[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings\n[`allow-panic-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-panic-in-tests\n[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests\n[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception\n[`allow-renamed-params-for`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-renamed-params-for\n[`allow-unwrap-in-consts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-consts\n[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests\n[`allow-unwrap-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-types\n[`allow-useless-vec-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-useless-vec-in-tests\n[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles\n[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates\n[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars\n[`allowed-prefixes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-prefixes\n[`allowed-scripts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-scripts\n[`allowed-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-wildcard-imports\n[`arithmetic-side-effects-allowed`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed\n[`arithmetic-side-effects-allowed-binary`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed-binary\n[`arithmetic-side-effects-allowed-unary`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed-unary\n[`array-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#array-size-threshold\n[`avoid-breaking-exported-api`]: https://doc.rust-lang.org/clippy/lint_configuration.html#avoid-breaking-exported-api\n[`await-holding-invalid-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#await-holding-invalid-types\n[`cargo-ignore-publish`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cargo-ignore-publish\n[`check-incompatible-msrv-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-incompatible-msrv-in-tests\n[`check-inconsistent-struct-field-initializers`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-inconsistent-struct-field-initializers\n[`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items\n[`cognitive-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cognitive-complexity-threshold\n[`const-literal-digits-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#const-literal-digits-threshold\n[`disallowed-fields`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-fields\n[`disallowed-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-macros\n[`disallowed-methods`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-methods\n[`disallowed-names`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-names\n[`disallowed-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-types\n[`doc-valid-idents`]: https://doc.rust-lang.org/clippy/lint_configuration.html#doc-valid-idents\n[`enable-raw-pointer-heuristic-for-send`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enable-raw-pointer-heuristic-for-send\n[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow\n[`enforced-import-renames`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforced-import-renames\n[`enum-variant-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-name-threshold\n[`enum-variant-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-size-threshold\n[`excessive-nesting-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#excessive-nesting-threshold\n[`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold\n[`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability\n[`inherent-impl-lint-scope`]: https://doc.rust-lang.org/clippy/lint_configuration.html#inherent-impl-lint-scope\n[`large-error-ignored`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-ignored\n[`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold\n[`lint-commented-code`]: https://doc.rust-lang.org/clippy/lint_configuration.html#lint-commented-code\n[`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold\n[`matches-for-let-else`]: https://doc.rust-lang.org/clippy/lint_configuration.html#matches-for-let-else\n[`max-fn-params-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-fn-params-bools\n[`max-include-file-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-include-file-size\n[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools\n[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length\n[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds\n[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold\n[`missing-docs-allow-unused`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-allow-unused\n[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items\n[`module-item-order-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-item-order-groupings\n[`module-items-ordered-within-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-items-ordered-within-groupings\n[`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv\n[`pass-by-value-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pass-by-value-size-limit\n[`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior\n[`recursive-self-in-type-definitions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#recursive-self-in-type-definitions\n[`semicolon-inside-block-ignore-singleline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-inside-block-ignore-singleline\n[`semicolon-outside-block-ignore-multiline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-outside-block-ignore-multiline\n[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold\n[`source-item-ordering`]: https://doc.rust-lang.org/clippy/lint_configuration.html#source-item-ordering\n[`stack-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#stack-size-threshold\n[`standard-macro-braces`]: https://doc.rust-lang.org/clippy/lint_configuration.html#standard-macro-braces\n[`struct-field-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#struct-field-name-threshold\n[`suppress-restriction-lint-in-const`]: https://doc.rust-lang.org/clippy/lint_configuration.html#suppress-restriction-lint-in-const\n[`too-large-for-stack`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-large-for-stack\n[`too-many-arguments-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-arguments-threshold\n[`too-many-lines-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-lines-threshold\n[`trait-assoc-item-kinds-order`]: https://doc.rust-lang.org/clippy/lint_configuration.html#trait-assoc-item-kinds-order\n[`trivial-copy-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#trivial-copy-size-limit\n[`type-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#type-complexity-threshold\n[`unnecessary-box-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unnecessary-box-size\n[`unreadable-literal-lint-fractions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unreadable-literal-lint-fractions\n[`upper-case-acronyms-aggressive`]: https://doc.rust-lang.org/clippy/lint_configuration.html#upper-case-acronyms-aggressive\n[`vec-box-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#vec-box-size-threshold\n[`verbose-bit-mask-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#verbose-bit-mask-threshold\n[`warn-on-all-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#warn-on-all-wildcard-imports\n[`warn-unsafe-macro-metavars-in-private-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#warn-unsafe-macro-metavars-in-private-macros\n<!-- end autogenerated links to configuration documentation -->\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# The Rust Code of Conduct\n\nThe Code of Conduct for this repository [can be found online](https://rust-lang.org/policies/code-of-conduct/).\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Clippy\n\nHello fellow Rustacean! Great to see your interest in compiler internals and lints!\n\n**First**: if you're unsure or afraid of _anything_, just ask or submit the issue or pull request anyway. You won't be\nyelled at for giving it your best effort. The worst that can happen is that you'll be politely asked to change\nsomething. We appreciate any sort of contributions, and don't want a wall of rules to get in the way of that.\n\nClippy welcomes contributions from everyone. There are many ways to contribute to Clippy and the following document\nexplains how you can contribute and how to get started.  If you have any questions about contributing or need help with\nanything, feel free to ask questions on issues or visit the `#clippy` on [Zulip].\n\nAll contributors are expected to follow the [Rust Code of Conduct].\n\n- [Contributing to Clippy](#contributing-to-clippy)\n  - [The Clippy book](#the-clippy-book)\n  - [High level approach](#high-level-approach)\n  - [Finding something to fix/improve](#finding-something-to-fiximprove)\n  - [Getting code-completion for rustc internals to work](#getting-code-completion-for-rustc-internals-to-work)\n    - [RustRover](#rustrover)\n    - [Rust Analyzer](#rust-analyzer)\n  - [How Clippy works](#how-clippy-works)\n  - [Issue and PR triage](#issue-and-pr-triage)\n  - [Contributions](#contributions)\n  - [License](#license)\n\n[Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/clippy\n[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct\n\n## The Clippy book\n\nIf you're new to Clippy and don't know where to start, the [Clippy book] includes\na [developer guide] and is a good place to start your journey.\n\n[Clippy book]: https://doc.rust-lang.org/nightly/clippy/index.html\n[developer guide]: https://doc.rust-lang.org/nightly/clippy/development/index.html\n\n## High level approach\n\n1. Find something to fix/improve\n2. Change code (likely some file in `clippy_lints/src/`)\n3. Follow the instructions in the [Basics docs](book/src/development/basics.md)\n   to get set up\n4. Run `cargo test` in the root directory and wiggle code until it passes\n5. Open a PR (also can be done after 2. if you run into problems)\n\n## Finding something to fix/improve\n\nAll issues on Clippy are mentored, if you want help simply ask someone from the\nClippy team directly by mentioning them in the issue or over on [Zulip]. All\ncurrently active team members can be found\n[here](https://github.com/rust-lang/rust-clippy/blob/master/triagebot.toml#L18)\n\nSome issues are easier than others. The [`good first issue`] label can be used to find the easy\nissues. You can use `@rustbot claim` to assign the issue to yourself.\n\nThere are also some abandoned PRs, marked with [`S-inactive-closed`].\nPretty often these PRs are nearly completed and just need some extra steps\n(formatting, addressing review comments, ...) to be merged. If you want to\ncomplete such a PR, please leave a comment in the PR and open a new one based\non it.\n\nIssues marked [`T-AST`] involve simple matching of the syntax tree structure,\nand are generally easier than [`T-middle`] issues, which involve types\nand resolved paths.\n\n[`T-AST`] issues will generally need you to match against a predefined syntax structure.\nTo figure out how this syntax structure is encoded in the AST, it is recommended to run\n`rustc -Z unpretty=ast-tree` on an example of the structure and compare with the [nodes in the AST docs].\nUsually the lint will end up to be a nested series of matches and ifs, [like so][deep-nesting].\nBut we can make it nest-less by using [let chains], [like this][nest-less].\n\n[`E-medium`] issues are generally pretty easy too, though it's recommended you work on an [`good first issue`]\nfirst. Sometimes they are only somewhat involved code wise, but not difficult per-se.\nNote that [`E-medium`] issues may require some knowledge of Clippy internals or some\ndebugging to find the actual problem behind the issue.\n\n[`T-middle`] issues can be more involved and require verifying types. The [`ty`] module contains a\nlot of methods that are useful, though one of the most useful would be `expr_ty` (gives the type of\nan AST expression).\n\n[`good first issue`]: https://github.com/rust-lang/rust-clippy/labels/good%20first%20issue\n[`S-inactive-closed`]: https://github.com/rust-lang/rust-clippy/pulls?q=is%3Aclosed+label%3AS-inactive-closed\n[`T-AST`]: https://github.com/rust-lang/rust-clippy/labels/T-AST\n[`T-middle`]: https://github.com/rust-lang/rust-clippy/labels/T-middle\n[`E-medium`]: https://github.com/rust-lang/rust-clippy/labels/E-medium\n[`ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty\n[nodes in the AST docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/\n[deep-nesting]: https://github.com/rust-lang/rust-clippy/blob/5e4f0922911536f80d9591180fa604229ac13939/clippy_lints/src/mem_forget.rs#L31-L45\n[let chains]: https://github.com/rust-lang/rust/pull/94927\n[nest-less]: https://github.com/rust-lang/rust-clippy/blob/5e4f0922911536f80d9591180fa604229ac13939/clippy_lints/src/bit_mask.rs#L133-L159\n\n## Getting code-completion for rustc internals to work\n\n### RustRover\nUnfortunately, [`RustRover`][RustRover_homepage] does not (yet?) understand how Clippy uses compiler-internals\nusing `extern crate` and it also needs to be able to read the source files of the rustc-compiler which are not\navailable via a `rustup` component at the time of writing.\nTo work around this, you need to have a copy of the [rustc-repo][rustc_repo] available which can be obtained via\n`git clone https://github.com/rust-lang/rust/`.\nThen you can run a `cargo dev` command to automatically make Clippy use the rustc-repo via path-dependencies\nwhich `RustRover` will be able to understand.\nRun `cargo dev setup intellij --repo-path <repo-path>` where `<repo-path>` is a path to the rustc repo\nyou just cloned.\nThe command will add path-dependencies pointing towards rustc-crates inside the rustc repo to\nClippy's `Cargo.toml`s and should allow `RustRover` to understand most of the types that Clippy uses.\nJust make sure to remove the dependencies again before finally making a pull request!\n\n[rustc_repo]: https://github.com/rust-lang/rust/\n[RustRover_homepage]: https://www.jetbrains.com/rust/\n\n### Rust Analyzer\nFor [`rust-analyzer`][ra_homepage] to work correctly make sure that in the `rust-analyzer` configuration you set\n\n```json\n{ \"rust-analyzer.rustc.source\": \"discover\" }\n```\n\nYou should be able to see information on things like `Expr` or `EarlyContext` now if you hover them, also\na lot more type hints.\n\nTo have `rust-analyzer` also work in the `clippy_dev` and `lintcheck` crates, add the following configuration\n\n```json\n{\n    \"rust-analyzer.linkedProjects\": [\n        \"./Cargo.toml\",\n        \"clippy_dev/Cargo.toml\",\n        \"lintcheck/Cargo.toml\",\n    ]\n}\n```\n\n[ra_homepage]: https://rust-analyzer.github.io/\n\n## How Clippy works\n\n[`clippy_lints/src/lib.rs`][lint_crate_entry] imports all the different lint modules and registers in the [`LintStore`].\nFor example, the [`else_if_without_else`][else_if_without_else] lint is registered like this:\n\n```rust\n// ./clippy_lints/src/lib.rs\n\n// ...\npub mod else_if_without_else;\n// ...\n\npub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {\n    // ...\n    store.register_early_pass(|| Box::new(else_if_without_else::ElseIfWithoutElse));\n    // ...\n}\n```\n\nThe [`rustc_lint::LintStore`][`LintStore`] provides two methods to register lints:\n[register_early_pass][reg_early_pass] and [register_late_pass][reg_late_pass]. Both take an object\nthat implements an [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass] respectively. This is done in\nevery single lint. It's worth noting that the majority of `clippy_lints/src/lib.rs` is autogenerated by `cargo dev\nupdate_lints`. When you are writing your own lint, you can use that script to save you some time.\n\n```rust\n// ./clippy_lints/src/else_if_without_else.rs\n\nuse rustc_lint::{EarlyLintPass, EarlyContext};\n\n// ...\n\npub struct ElseIfWithoutElse;\n\n// ...\n\nimpl EarlyLintPass for ElseIfWithoutElse {\n    // ... the functions needed, to make the lint work\n}\n```\n\nThe difference between `EarlyLintPass` and `LateLintPass` is that the methods of the `EarlyLintPass` trait only provide\nAST information. The methods of the `LateLintPass` trait are executed after type checking and contain type information\nvia the `LateContext` parameter.\n\nThat's why the `else_if_without_else` example uses the `register_early_pass` function. Because the\n[actual lint logic][else_if_without_else] does not depend on any type information.\n\n[lint_crate_entry]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/lib.rs\n[else_if_without_else]: https://github.com/rust-lang/rust-clippy/blob/4253aa7137cb7378acc96133c787e49a345c2b3c/clippy_lints/src/else_if_without_else.rs\n[`LintStore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html\n[reg_early_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_early_pass\n[reg_late_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_late_pass\n[early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html\n[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html\n\n## Issue and PR triage\n\nClippy is following the [Rust triage procedure][triage] for issues and pull\nrequests.\n\nHowever, we are a smaller project with all contributors being volunteers\ncurrently. Between writing new lints, fixing issues, reviewing pull requests and\nresponding to issues there may not always be enough time to stay on top of it\nall.\n\nTo find things to fix, go to the [tracking issue][tracking_issue], find an issue that you like, \nand claim it with `@rustbot claim`.\n\nAs a general metric and always taking into account your skill and knowledge level, you can use this guide:\n\n- 🟥 [ICEs][search_ice], these are compiler errors that causes Clippy to panic and crash. Usually involves high-level\ndebugging, sometimes interacting directly with the upstream compiler. Difficult to fix but a great challenge that\nimproves a lot developer workflows!\n\n- 🟧 [Suggestion causes bug][sugg_causes_bug], Clippy suggested code that changed logic in some silent way.\nUnacceptable, as this may have disastrous consequences. Easier to fix than ICEs\n\n- 🟨 [Suggestion causes error][sugg_causes_error], Clippy suggested code snippet that caused a compiler error\nwhen applied. We need to make sure that Clippy doesn't suggest using a variable twice at the same time or similar\neasy-to-happen occurrences.\n\n- 🟩 [False positives][false_positive], a lint should not have fired, the easiest of them all, as this is \"just\"\nidentifying the root of a false positive and making an exception for those cases.\n\nNote that false negatives do not have priority unless the case is very clear, as they are a feature-request in a\ntrench coat.\n\n[triage]: https://forge.rust-lang.org/release/triage-procedure.html\n[search_ice]: https://github.com/rust-lang/rust-clippy/issues?q=sort%3Aupdated-desc+state%3Aopen+label%3A%22I-ICE%22\n[sugg_causes_bug]: https://github.com/rust-lang/rust-clippy/issues?q=sort%3Aupdated-desc%20state%3Aopen%20label%3AI-suggestion-causes-bug\n[sugg_causes_error]: https://github.com/rust-lang/rust-clippy/issues?q=sort%3Aupdated-desc%20state%3Aopen%20label%3AI-suggestion-causes-error%20\n[false_positive]: https://github.com/rust-lang/rust-clippy/issues?q=sort%3Aupdated-desc%20state%3Aopen%20label%3AI-false-positive\n[tracking_issue]: https://github.com/rust-lang/rust-clippy/issues/15086\n\n## Contributions\n\nContributions to Clippy should be made in the form of GitHub pull requests. Each pull request will\nbe reviewed by a core contributor (someone with permission to land patches) and either landed in the\nmain tree or given feedback for changes that would be required.\n\nAll PRs should include a `changelog` entry with a short comment explaining the change. The rule of thumb is basically,\n\"what do you believe is important from an outsider's perspective?\" Often, PRs are only related to a single property of a\nlint, and then it's good to mention that one. Otherwise, it's better to include too much detail than too little.\n\nClippy's [changelog] is created from these comments. Every release, someone gets all merge commits with a\n`changelog: XYZ` entry and combines them into the changelog. This is a manual process.\n\nExamples:\n- New lint\n  ```\n  changelog: new lint: [`missing_trait_methods`]\n  ```\n- False positive fix\n  ```\n  changelog: Fix [`unused_peekable`] false positive when peeked in a closure or called as `f(&mut peekable)`\n  ```\n- Purely internal change\n  ```\n  changelog: none\n  ```\n\nNote this it is fine for a PR to include multiple `changelog` entries, e.g.:\n```\nchangelog: Something 1\nchangelog: Something 2\nchangelog: Something 3\n```\n\n[changelog]: CHANGELOG.md\n\n## License\n\nAll code in this repository is under the [Apache-2.0] or the [MIT] license.\n\n<!-- adapted from https://github.com/servo/servo/blob/master/CONTRIBUTING.md -->\n\n[Apache-2.0]: https://www.apache.org/licenses/LICENSE-2.0\n[MIT]: https://opensource.org/licenses/MIT\n"
  },
  {
    "path": "COPYRIGHT",
    "content": "// REUSE-IgnoreStart\n\nCopyright (c) The Rust Project Contributors\n\nLicensed under the Apache License, Version 2.0 <LICENSE-APACHE or\nhttp://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n<LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\noption. All files in the project carrying such notice may not be\ncopied, modified, or distributed except according to those terms.\n\n// REUSE-IgnoreEnd\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[package]\nname = \"clippy\"\nversion = \"0.1.96\"\ndescription = \"A bunch of helpful lints to avoid common pitfalls in Rust\"\nrepository = \"https://github.com/rust-lang/rust-clippy\"\nreadme = \"README.md\"\nlicense = \"MIT OR Apache-2.0\"\nkeywords = [\"clippy\", \"lint\", \"plugin\"]\ncategories = [\"development-tools\", \"development-tools::cargo-plugins\"]\nbuild = \"build.rs\"\nedition = \"2024\"\npublish = false\n\n[[bin]]\nname = \"cargo-clippy\"\ntest = false\npath = \"src/main.rs\"\n\n[[bin]]\nname = \"clippy-driver\"\npath = \"src/driver.rs\"\n\n[dependencies]\nclippy_config = { path = \"clippy_config\" }\nclippy_lints = { path = \"clippy_lints\" }\nclippy_utils = { path = \"clippy_utils\" }\ndeclare_clippy_lint = { path = \"declare_clippy_lint\" }\nrustc_tools_util = { path = \"rustc_tools_util\", version = \"0.4.2\" }\nclippy_lints_internal = { path = \"clippy_lints_internal\", optional = true }\ntempfile = { version = \"3.20\", optional = true }\ntermize = \"0.2\"\ncolor-print = \"0.3.4\"\nanstream = \"0.6.18\"\n\n[dev-dependencies]\ncargo_metadata = \"0.18.1\"\nui_test = \"0.30.2\"\nregex = \"1.5.5\"\nserde = { version = \"1.0.145\", features = [\"derive\"] }\nserde_json = \"1.0.122\"\nwalkdir = \"2.3\"\nfiletime = \"0.2.9\"\nitertools = \"0.12\"\npulldown-cmark = { version = \"0.11\", default-features = false, features = [\"html\"] }\naskama = { version = \"0.15.4\", default-features = false, features = [\"alloc\", \"config\", \"derive\"] }\n\n[dev-dependencies.toml]\nversion = \"0.9.7\"\ndefault-features = false\n# preserve_order keeps diagnostic output in file order\nfeatures = [\"parse\", \"preserve_order\"]\n\n[build-dependencies]\nrustc_tools_util = { path = \"rustc_tools_util\", version = \"0.4.2\" }\n\n[features]\nintegration = [\"dep:tempfile\"]\ninternal = [\"dep:clippy_lints_internal\", \"dep:tempfile\"]\njemalloc = []\n\n[package.metadata.rust-analyzer]\n# This package uses #[feature(rustc_private)]\nrustc_private = true\n\n[[test]]\nname = \"compile-test\"\nharness = false\n\n[[test]]\nname = \"dogfood\"\nharness = false\n\n[lints.rust.unexpected_cfgs]\nlevel = \"warn\"\ncheck-cfg = ['cfg(bootstrap)']\n"
  },
  {
    "path": "LICENSE-APACHE",
    "content": "                              Apache License\n                        Version 2.0, January 2004\n                     http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n   \"License\" shall mean the terms and conditions for use, reproduction,\n   and distribution as defined by Sections 1 through 9 of this document.\n\n   \"Licensor\" shall mean the copyright owner or entity authorized by\n   the copyright owner that is granting the License.\n\n   \"Legal Entity\" shall mean the union of the acting entity and all\n   other entities that control, are controlled by, or are under common\n   control with that entity. For the purposes of this definition,\n   \"control\" means (i) the power, direct or indirect, to cause the\n   direction or management of such entity, whether by contract or\n   otherwise, or (ii) ownership of fifty percent (50%) or more of the\n   outstanding shares, or (iii) beneficial ownership of such entity.\n\n   \"You\" (or \"Your\") shall mean an individual or Legal Entity\n   exercising permissions granted by this License.\n\n   \"Source\" form shall mean the preferred form for making modifications,\n   including but not limited to software source code, documentation\n   source, and configuration files.\n\n   \"Object\" form shall mean any form resulting from mechanical\n   transformation or translation of a Source form, including but\n   not limited to compiled object code, generated documentation,\n   and conversions to other media types.\n\n   \"Work\" shall mean the work of authorship, whether in Source or\n   Object form, made available under the License, as indicated by a\n   copyright notice that is included in or attached to the work\n   (an example is provided in the Appendix below).\n\n   \"Derivative Works\" shall mean any work, whether in Source or Object\n   form, that is based on (or derived from) the Work and for which the\n   editorial revisions, annotations, elaborations, or other modifications\n   represent, as a whole, an original work of authorship. For the purposes\n   of this License, Derivative Works shall not include works that remain\n   separable from, or merely link (or bind by name) to the interfaces of,\n   the Work and Derivative Works thereof.\n\n   \"Contribution\" shall mean any work of authorship, including\n   the original version of the Work and any modifications or additions\n   to that Work or Derivative Works thereof, that is intentionally\n   submitted to Licensor for inclusion in the Work by the copyright owner\n   or by an individual or Legal Entity authorized to submit on behalf of\n   the copyright owner. For the purposes of this definition, \"submitted\"\n   means any form of electronic, verbal, or written communication sent\n   to the Licensor or its representatives, including but not limited to\n   communication on electronic mailing lists, source code control systems,\n   and issue tracking systems that are managed by, or on behalf of, the\n   Licensor for the purpose of discussing and improving the Work, but\n   excluding communication that is conspicuously marked or otherwise\n   designated in writing by the copyright owner as \"Not a Contribution.\"\n\n   \"Contributor\" shall mean Licensor and any individual or Legal Entity\n   on behalf of whom a Contribution has been received by Licensor and\n   subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   copyright license to reproduce, prepare Derivative Works of,\n   publicly display, publicly perform, sublicense, and distribute the\n   Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   (except as stated in this section) patent license to make, have made,\n   use, offer to sell, sell, import, and otherwise transfer the Work,\n   where such license applies only to those patent claims licensable\n   by such Contributor that are necessarily infringed by their\n   Contribution(s) alone or by combination of their Contribution(s)\n   with the Work to which such Contribution(s) was submitted. If You\n   institute patent litigation against any entity (including a\n   cross-claim or counterclaim in a lawsuit) alleging that the Work\n   or a Contribution incorporated within the Work constitutes direct\n   or contributory patent infringement, then any patent licenses\n   granted to You under this License for that Work shall terminate\n   as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n   Work or Derivative Works thereof in any medium, with or without\n   modifications, and in Source or Object form, provided that You\n   meet the following conditions:\n\n   (a) You must give any other recipients of the Work or\n       Derivative Works a copy of this License; and\n\n   (b) You must cause any modified files to carry prominent notices\n       stating that You changed the files; and\n\n   (c) You must retain, in the Source form of any Derivative Works\n       that You distribute, all copyright, patent, trademark, and\n       attribution notices from the Source form of the Work,\n       excluding those notices that do not pertain to any part of\n       the Derivative Works; and\n\n   (d) If the Work includes a \"NOTICE\" text file as part of its\n       distribution, then any Derivative Works that You distribute must\n       include a readable copy of the attribution notices contained\n       within such NOTICE file, excluding those notices that do not\n       pertain to any part of the Derivative Works, in at least one\n       of the following places: within a NOTICE text file distributed\n       as part of the Derivative Works; within the Source form or\n       documentation, if provided along with the Derivative Works; or,\n       within a display generated by the Derivative Works, if and\n       wherever such third-party notices normally appear. The contents\n       of the NOTICE file are for informational purposes only and\n       do not modify the License. You may add Your own attribution\n       notices within Derivative Works that You distribute, alongside\n       or as an addendum to the NOTICE text from the Work, provided\n       that such additional attribution notices cannot be construed\n       as modifying the License.\n\n   You may add Your own copyright statement to Your modifications and\n   may provide additional or different license terms and conditions\n   for use, reproduction, or distribution of Your modifications, or\n   for any such Derivative Works as a whole, provided Your use,\n   reproduction, and distribution of the Work otherwise complies with\n   the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n   any Contribution intentionally submitted for inclusion in the Work\n   by You to the Licensor shall be under the terms and conditions of\n   this License, without any additional terms or conditions.\n   Notwithstanding the above, nothing herein shall supersede or modify\n   the terms of any separate license agreement you may have executed\n   with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n   names, trademarks, service marks, or product names of the Licensor,\n   except as required for reasonable and customary use in describing the\n   origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n   agreed to in writing, Licensor provides the Work (and each\n   Contributor provides its Contributions) on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n   implied, including, without limitation, any warranties or conditions\n   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n   PARTICULAR PURPOSE. You are solely responsible for determining the\n   appropriateness of using or redistributing the Work and assume any\n   risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n   whether in tort (including negligence), contract, or otherwise,\n   unless required by applicable law (such as deliberate and grossly\n   negligent acts) or agreed to in writing, shall any Contributor be\n   liable to You for damages, including any direct, indirect, special,\n   incidental, or consequential damages of any character arising as a\n   result of this License or out of the use or inability to use the\n   Work (including but not limited to damages for loss of goodwill,\n   work stoppage, computer failure or malfunction, or any and all\n   other commercial damages or losses), even if such Contributor\n   has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n   the Work or Derivative Works thereof, You may choose to offer,\n   and charge a fee for, acceptance of support, warranty, indemnity,\n   or other liability obligations and/or rights consistent with this\n   License. However, in accepting such obligations, You may act only\n   on Your own behalf and on Your sole responsibility, not on behalf\n   of any other Contributor, and only if You agree to indemnify,\n   defend, and hold each Contributor harmless for any liability\n   incurred by, or claims asserted against, such Contributor by reason\n   of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n   To apply the Apache License to your work, attach the following\n   boilerplate notice, with the fields enclosed by brackets \"[]\"\n   replaced with your own identifying information. (Don't include\n   the brackets!)  The text should be enclosed in the appropriate\n   comment syntax for the file format. We also recommend that a\n   file or class name and description of purpose be included on the\n   same \"printed page\" as the copyright notice for easier\n   identification within third-party archives.\n\nCopyright (c) The Rust Project Contributors\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "LICENSE-MIT",
    "content": "MIT License\n\nCopyright (c) The Rust Project Contributors\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Clippy\n\n[![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](#license)\n\nA collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.\n\n[There are over 800 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)\n\nLints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html).\nYou can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category.\n\n| Category              | Description                                                                         | Default level |\n|-----------------------|-------------------------------------------------------------------------------------|---------------|\n| `clippy::all`         | all lints that are on by default (correctness, suspicious, style, complexity, perf) | **warn/deny** |\n| `clippy::correctness` | code that is outright wrong or useless                                              | **deny**      |\n| `clippy::suspicious`  | code that is most likely wrong or useless                                           | **warn**      |\n| `clippy::style`       | code that should be written in a more idiomatic way                                 | **warn**      |\n| `clippy::complexity`  | code that does something simple but in a complex way                                | **warn**      |\n| `clippy::perf`        | code that can be written to run faster                                              | **warn**      |\n| `clippy::pedantic`    | lints which are rather strict or have occasional false positives                    | allow         |\n| `clippy::restriction` | lints which prevent the use of language and library features[^restrict]             | allow         |\n| `clippy::nursery`     | new lints that are still under development                                          | allow         |\n| `clippy::cargo`       | lints for the cargo manifest                                                        | allow         |\n\nMore to come, please [file an issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas!\n\nThe `restriction` category should, *emphatically*, not be enabled as a whole. The contained\nlints may lint against perfectly reasonable code, may not have an alternative suggestion,\nand may contradict any other lints (including other categories). Lints should be considered\non a case-by-case basis before enabling.\n\n[^restrict]: Some use cases for `restriction` lints include:\n    - Strict coding styles (e.g. [`clippy::else_if_without_else`]).\n    - Additional restrictions on CI (e.g. [`clippy::todo`]).\n    - Preventing panicking in certain functions (e.g. [`clippy::unwrap_used`]).\n    - Running a lint only on a subset of code (e.g. `#[forbid(clippy::float_arithmetic)]` on a module).\n\n[`clippy::else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else\n[`clippy::todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo\n[`clippy::unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used\n\n---\n\nTable of contents:\n\n* [Usage instructions](#usage)\n* [Configuration](#configuration)\n* [Contributing](#contributing)\n* [License](#license)\n\n## Usage\n\nBelow are instructions on how to use Clippy as a cargo subcommand,\nin projects that do not use cargo, or in Travis CI.\n\n### As a cargo subcommand (`cargo clippy`)\n\nOne way to use Clippy is by installing Clippy through rustup as a cargo\nsubcommand.\n\n#### Step 1: Install Rustup\n\nYou can install [Rustup](https://rustup.rs/) on supported platforms. This will help\nus install Clippy and its dependencies.\n\nIf you already have Rustup installed, update to ensure you have the latest\nRustup and compiler:\n\n```terminal\nrustup update\n```\n\n#### Step 2: Install Clippy\n\nOnce you have rustup and the latest stable release (at least Rust 1.29) installed, run the following command:\n\n```terminal\nrustup component add clippy\n```\n\nIf it says that it can't find the `clippy` component, please run `rustup self update`.\n\n#### Step 3: Run Clippy\n\nNow you can run Clippy by invoking the following command:\n\n```terminal\ncargo clippy\n```\n\n#### Automatically applying Clippy suggestions\n\nClippy can automatically apply some lint suggestions, just like the compiler. Note that `--fix` implies\n`--all-targets`, so it can fix as much code as it can.\n\n```terminal\ncargo clippy --fix\n```\n\n#### Workspaces\n\nAll the usual workspace options should work with Clippy. For example the following command\nwill run Clippy on the `example` crate:\n\n```terminal\ncargo clippy -p example\n```\n\nAs with `cargo check`, this includes dependencies that are members of the workspace, like path dependencies.\nIf you want to run Clippy **only** on the given crate, use the `--no-deps` option like this:\n\n```terminal\ncargo clippy -p example -- --no-deps\n```\n\n### Using `clippy-driver`\n\nClippy can also be used in projects that do not use cargo. To do so, run `clippy-driver`\nwith the same arguments you use for `rustc`. For example:\n\n```terminal\nclippy-driver --edition 2018 -Cpanic=abort foo.rs\n```\n\nNote that `clippy-driver` is designed for running Clippy only and should not be used as a general\nreplacement for `rustc`. `clippy-driver` may produce artifacts that are not optimized as expected,\nfor example.\n\n### Travis CI\n\nYou can add Clippy to Travis CI in the same way you use it locally:\n\n```yaml\nlanguage: rust\nrust:\n  - stable\n  - beta\nbefore_script:\n  - rustup component add clippy\nscript:\n  - cargo clippy\n  # if you want the build job to fail when encountering warnings, use\n  - cargo clippy -- -D warnings\n  # in order to also check tests and non-default crate features, use\n  - cargo clippy --all-targets --all-features -- -D warnings\n  - cargo test\n  # etc.\n```\n\nNote that adding `-D warnings` will cause your build to fail if **any** warnings are found in your code.\nThat includes warnings found by rustc (e.g. `dead_code`, etc.). If you want to avoid this and only cause\nan error for Clippy warnings, use `#![deny(clippy::all)]` in your code or `-D clippy::all` on the command\nline. (You can swap `clippy::all` with the specific lint category you are targeting.)\n\n## Configuration\n\n### Allowing/denying lints\n\nYou can add options to your code to `allow`/`warn`/`deny` Clippy lints:\n\n* the whole set of `Warn` lints using the `clippy` lint group (`#![deny(clippy::all)]`).\n  Note that `rustc` has additional [lint groups](https://doc.rust-lang.org/rustc/lints/groups.html).\n\n* all lints using both the `clippy` and `clippy::pedantic` lint groups (`#![deny(clippy::all)]`,\n  `#![deny(clippy::pedantic)]`). Note that `clippy::pedantic` contains some very aggressive\n  lints prone to false positives.\n\n* only some lints (`#![deny(clippy::single_match, clippy::box_vec)]`, etc.)\n\n* `allow`/`warn`/`deny` can be limited to a single function or module using `#[allow(...)]`, etc.\n\nNote: `allow` means to suppress the lint for your code. With `warn` the lint\nwill only emit a warning, while with `deny` the lint will emit an error, when\ntriggering for your code. An error causes Clippy to exit with an error code, so\nis useful in scripts like CI/CD.\n\nIf you do not want to include your lint levels in your code, you can globally\nenable/disable lints by passing extra flags to Clippy during the run:\n\nTo allow `lint_name`, run\n\n```terminal\ncargo clippy -- -A clippy::lint_name\n```\n\nAnd to warn on `lint_name`, run\n\n```terminal\ncargo clippy -- -W clippy::lint_name\n```\n\nThis also works with lint groups. For example, you\ncan run Clippy with warnings for all lints enabled:\n\n```terminal\ncargo clippy -- -W clippy::pedantic\n```\n\nIf you care only about a single lint, you can allow all others and then explicitly warn on\nthe lint(s) you are interested in:\n\n```terminal\ncargo clippy -- -A clippy::all -W clippy::useless_format -W clippy::...\n```\n\n### Configure the behavior of some lints\n\nSome lints can be configured in a TOML file named `clippy.toml` or `.clippy.toml`. It contains a basic `variable =\nvalue` mapping e.g.\n\n```toml\navoid-breaking-exported-api = false\ndisallowed-names = [\"toto\", \"tata\", \"titi\"]\n```\n\nThe [table of configurations](https://doc.rust-lang.org/nightly/clippy/lint_configuration.html)\ncontains all config values, their default, and a list of lints they affect.\nEach [configurable lint](https://rust-lang.github.io/rust-clippy/master/index.html#Configuration)\n, also contains information about these values.\n\nFor configurations that are a list type with default values such as\n[disallowed-names](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names),\nyou can use the unique value `\"..\"` to extend the default values instead of replacing them.\n\n```toml\n# default of disallowed-names is [\"foo\", \"baz\", \"quux\"]\ndisallowed-names = [\"bar\", \"..\"] # -> [\"bar\", \"foo\", \"baz\", \"quux\"]\n```\n\n> **Note**\n>\n> `clippy.toml` or `.clippy.toml` cannot be used to allow/deny lints.\n\nTo deactivate the “for further information visit *lint-link*” message you can\ndefine the `CLIPPY_DISABLE_DOCS_LINKS` environment variable.\n\n### Specifying the minimum supported Rust version\n\nProjects that intend to support old versions of Rust can disable lints pertaining to newer features by\nspecifying the minimum supported Rust version (MSRV) in the Clippy configuration file.\n\n```toml\nmsrv = \"1.30.0\"\n```\n\nAlternatively, the [`rust-version` field](https://doc.rust-lang.org/cargo/reference/manifest.html#the-rust-version-field)\nin the `Cargo.toml` can be used.\n\n```toml\n# Cargo.toml\nrust-version = \"1.30\"\n```\n\nThe MSRV can also be specified as an attribute, like below.\n\n```rust,ignore\n#![feature(custom_inner_attributes)]\n#![clippy::msrv = \"1.30.0\"]\n\nfn main() {\n  ...\n}\n```\n\nYou can also omit the patch version when specifying the MSRV, so `msrv = 1.30`\nis equivalent to `msrv = 1.30.0`.\n\nNote: `custom_inner_attributes` is an unstable feature, so it has to be enabled explicitly.\n\nLints that recognize this configuration option can be found [here](https://rust-lang.github.io/rust-clippy/master/index.html#msrv)\n\n## Contributing\n\nIf you want to contribute to Clippy, you can find more information in [CONTRIBUTING.md](https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md).\n\n## License\n\n<!-- REUSE-IgnoreStart -->\n\nCopyright (c) The Rust Project Contributors\n\nLicensed under the Apache License, Version 2.0 <LICENSE-APACHE or\n[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license\n<LICENSE-MIT or [https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT)>, at your\noption. Files in the project may not be\ncopied, modified, or distributed except according to those terms.\n\n<!-- REUSE-IgnoreEnd -->\n"
  },
  {
    "path": "askama.toml",
    "content": "[general]\ndirs = [\"util/gh-pages/\"]\nwhitespace = \"suppress\"\n"
  },
  {
    "path": "book/README.md",
    "content": "# Clippy Book\n\nThis is the source for the Clippy Book. See the\n[book](src/development/infrastructure/book.md) for more information.\n"
  },
  {
    "path": "book/book.toml",
    "content": "[book]\nauthors = [\"The Rust Clippy Developers\"]\nlanguage = \"en\"\ntitle = \"Clippy Documentation\"\n\n[rust]\nedition = \"2024\"\n\n[output.html]\nedit-url-template = \"https://github.com/rust-lang/rust-clippy/edit/master/book/{path}\"\ngit-repository-url = \"https://github.com/rust-lang/rust-clippy/tree/master/book\"\nmathjax-support = true\nsite-url = \"/rust-clippy/\"\n\n[output.html.playground]\neditable = true\nline-numbers = true\n\n[output.html.search]\nboost-hierarchy = 2\nboost-paragraph = 1\nboost-title = 2\nexpand = true\nheading-split-level = 2\nlimit-results = 20\nuse-boolean-and = true\n"
  },
  {
    "path": "book/src/README.md",
    "content": "# Clippy\n\n[![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](https://github.com/rust-lang/rust-clippy#license)\n\nA collection of lints to catch common mistakes and improve your\n[Rust](https://github.com/rust-lang/rust) code.\n\n[There are over 800 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)\n\nLints are divided into categories, each with a default [lint\nlevel](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how\nmuch Clippy is supposed to ~~annoy~~ help you by changing the lint level by\ncategory.\n\n| Category              | Description                                                                         | Default level |\n|-----------------------|-------------------------------------------------------------------------------------|---------------|\n| `clippy::all`         | all lints that are on by default (correctness, suspicious, style, complexity, perf) | **warn/deny** |\n| `clippy::correctness` | code that is outright wrong or useless                                              | **deny**      |\n| `clippy::suspicious`  | code that is most likely wrong or useless                                           | **warn**      |\n| `clippy::style`       | code that should be written in a more idiomatic way                                 | **warn**      |\n| `clippy::complexity`  | code that does something simple but in a complex way                                | **warn**      |\n| `clippy::perf`        | code that can be written to run faster                                              | **warn**      |\n| `clippy::pedantic`    | lints which are rather strict or have occasional false positives                    | allow         |\n| `clippy::restriction` | lints which prevent the use of language and library features[^restrict]             | allow         |\n| `clippy::nursery`     | new lints that are still under development                                          | allow         |\n| `clippy::cargo`       | lints for the cargo manifest                                                        | allow         |\n\nMore to come, please [file an issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas!\n\nThe `restriction` category should, *emphatically*, not be enabled as a whole. The contained\nlints may lint against perfectly reasonable code, may not have an alternative suggestion,\nand may contradict any other lints (including other categories). Lints should be considered\non a case-by-case basis before enabling.\n\n[^restrict]: Some use cases for `restriction` lints include:\n    - Strict coding styles (e.g. [`clippy::else_if_without_else`]).\n    - Additional restrictions on CI (e.g. [`clippy::todo`]).\n    - Preventing panicking in certain functions (e.g. [`clippy::unwrap_used`]).\n    - Running a lint only on a subset of code (e.g. `#[forbid(clippy::float_arithmetic)]` on a module).\n\n[`clippy::else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else\n[`clippy::todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo\n[`clippy::unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used\n"
  },
  {
    "path": "book/src/SUMMARY.md",
    "content": "# Summary\n\n[Introduction](README.md)\n\n- [Installation](installation.md)\n- [Usage](usage.md)\n- [Configuration](configuration.md)\n    - [Lint Configuration](lint_configuration.md)\n- [Clippy's Lints](lints.md)\n- [Attributes for Crate Authors](attribs.md)\n- [Continuous Integration](continuous_integration/README.md)\n    - [GitHub Actions](continuous_integration/github_actions.md)\n    - [GitLab CI](continuous_integration/gitlab.md)\n    - [Travis CI](continuous_integration/travis.md)\n- [Development](development/README.md)\n    - [Basics](development/basics.md)\n    - [Adding Lints](development/adding_lints.md)\n    - [Defining Lints](development/defining_lints.md)\n    - [Writing tests](development/writing_tests.md)\n    - [Lint Passes](development/lint_passes.md)\n    - [Emitting lints](development/emitting_lints.md)\n    - [Type Checking](development/type_checking.md)\n    - [Trait Checking](development/trait_checking.md)\n    - [Method Checking](development/method_checking.md)\n    - [Macro Expansions](development/macro_expansions.md)\n    - [Common Tools](development/common_tools_writing_lints.md)\n    - [Infrastructure](development/infrastructure/README.md)\n        - [Syncing changes between Clippy and rust-lang/rust](development/infrastructure/sync.md)\n        - [Backporting Changes](development/infrastructure/backport.md)\n        - [Updating the Changelog](development/infrastructure/changelog_update.md)\n        - [Release a New Version](development/infrastructure/release.md)\n        - [The Clippy Book](development/infrastructure/book.md)\n        - [Benchmarking Clippy](development/infrastructure/benchmarking.md)\n    - [Proposals](development/proposals/README.md)\n        - [Roadmap 2021](development/proposals/roadmap-2021.md)\n        - [Syntax Tree Patterns](development/proposals/syntax-tree-patterns.md)\n    - [The Team](development/the_team.md)\n"
  },
  {
    "path": "book/src/attribs.md",
    "content": "# Attributes for Crate Authors\n\nIn some cases it is possible to extend Clippy coverage to 3rd party libraries.\nTo do this, Clippy provides attributes that can be applied to items in the 3rd party crate.\n\n## `#[clippy::format_args]`\n\n_Available since Clippy v1.85_\n\nThis attribute can be added to a macro that supports `format!`, `println!`, or similar syntax.\nIt tells Clippy that the macro is a formatting macro, and that the arguments to the macro\nshould be linted as if they were arguments to `format!`. Any lint that would apply to a\n`format!` call will also apply to the macro call. The macro may have additional arguments\nbefore the format string, and these will be ignored.\n\n### Example\n\n```rust\n/// A macro that prints a message if a condition is true.\n#[macro_export]\n#[clippy::format_args]\nmacro_rules! print_if {\n    ($condition:expr, $($args:tt)+) => {{\n        if $condition {\n            println!($($args)+)\n        }\n    }};\n}\n```\n\n## `#[clippy::has_significant_drop]`\n\n_Available since Clippy v1.60_\n\nThe `clippy::has_significant_drop` attribute can be added to types whose Drop impls have an important side effect,\nsuch as unlocking a mutex, making it important for users to be able to accurately understand their lifetimes.\nWhen a temporary is returned in a function call in a match scrutinee, its lifetime lasts until the end of the match\nblock, which may be surprising.\n\n### Example\n\n```rust\n#[clippy::has_significant_drop]\nstruct CounterWrapper<'a> {\n    counter: &'a Counter,\n}\n\nimpl<'a> Drop for CounterWrapper<'a> {\n    fn drop(&mut self) {\n        self.counter.i.fetch_sub(1, Ordering::Relaxed);\n    }\n}\n```\n"
  },
  {
    "path": "book/src/configuration.md",
    "content": "# Configuring Clippy\n\n> **Note:** The configuration file is unstable and may be deprecated in the future.\n\nSome lints can be configured in a TOML file named `clippy.toml` or `.clippy.toml`, which is searched for starting in the\nfirst defined directory according to the following priority order:\n\n1. The directory specified by the `CLIPPY_CONF_DIR` environment variable, or\n2. The directory specified by the\n[CARGO_MANIFEST_DIR](https://doc.rust-lang.org/cargo/reference/environment-variables.html) environment variable, or\n3. The current directory.\n\nIf the chosen directory does not contain a configuration file, Clippy will walk up the directory tree, searching each\nparent directory until it finds one or reaches the filesystem root.\n\nIt contains a basic `variable = value` mapping e.g.\n\n```toml\navoid-breaking-exported-api = false\ndisallowed-names = [\"toto\", \"tata\", \"titi\"]\n```\n\nThe [table of configurations](./lint_configuration.md)\ncontains all config values, their default, and a list of lints they affect.\nEach [configurable lint](https://rust-lang.github.io/rust-clippy/master/index.html#Configuration)\n, also contains information about these values.\n\nFor configurations that are a list type with default values such as\n[disallowed-names](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names),\nyou can use the unique value `\"..\"` to extend the default values instead of replacing them.\n\n```toml\n# default of disallowed-names is [\"foo\", \"baz\", \"quux\"]\ndisallowed-names = [\"bar\", \"..\"] # -> [\"bar\", \"foo\", \"baz\", \"quux\"]\n```\n\nTo deactivate the \"for further information visit *lint-link*\" message you can define the `CLIPPY_DISABLE_DOCS_LINKS`\nenvironment variable.\n\n### Allowing/Denying Lints\n\n#### Attributes in Code\n\nYou can add attributes to your code to `allow`/`warn`/`deny` Clippy lints:\n\n* the whole set of `warn`-by-default lints using the `clippy` lint group (`#![allow(clippy::all)]`)\n\n* all lints using both the `clippy` and `clippy::pedantic` lint groups (`#![warn(clippy::all, clippy::pedantic)]`. Note\n  that `clippy::pedantic` contains some very aggressive lints prone to false positives.\n\n* only some lints (`#![deny(clippy::single_match, clippy::box_vec)]`, etc.)\n\n* `allow`/`warn`/`deny` can be limited to a single function or module using `#[allow(...)]`, etc.\n\nNote: `allow` means to suppress the lint for your code. With `warn` the lint will only emit a warning, while with `deny`\nthe lint will emit an error, when triggering for your code. An error causes Clippy to exit with an error code, so is\nmost useful in scripts used in CI/CD.\n\n#### Command Line Flags\n\nIf you do not want to include your lint levels in the code, you can globally enable/disable lints by passing extra flags\nto Clippy during the run:\n\nTo allow `lint_name`, run\n\n```terminal\ncargo clippy -- -A clippy::lint_name\n```\n\nAnd to warn on `lint_name`, run\n\n```terminal\ncargo clippy -- -W clippy::lint_name\n```\n\nThis also works with lint groups. For example, you can run Clippy with warnings for all pedantic lints enabled:\n\n```terminal\ncargo clippy -- -W clippy::pedantic\n```\n\nIf you care only about a certain lints, you can allow all others and then explicitly warn on the lints you are\ninterested in:\n\n```terminal\ncargo clippy -- -A clippy::all -W clippy::useless_format -W clippy::...\n```\n\n#### Lints Section in `Cargo.toml`\n\nFinally, lints can be allowed/denied using [the lints\nsection](https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-lints-section)) in the `Cargo.toml` file:\n\nTo deny `clippy::enum_glob_use`, put the following in the `Cargo.toml`:\n\n```toml\n[lints.clippy]\nenum_glob_use = \"deny\"\n```\n\nFor more details and options, refer to the Cargo documentation.\n\n### Specifying the minimum supported Rust version\n\nProjects that intend to support old versions of Rust can disable lints pertaining to newer features by specifying the\nminimum supported Rust version (MSRV) in the Clippy configuration file.\n\n```toml\nmsrv = \"1.30.0\"\n```\n\nThe MSRV can also be specified as an attribute, like below.\n\n```rust,ignore\n#![feature(custom_inner_attributes)]\n#![clippy::msrv = \"1.30.0\"]\n\nfn main() {\n    ...\n}\n```\n\nYou can also omit the patch version when specifying the MSRV, so `msrv = 1.30`\nis equivalent to `msrv = 1.30.0`.\n\nNote: `custom_inner_attributes` is an unstable feature, so it has to be enabled explicitly.\n\nLints that recognize this configuration option can be\nfound [here](https://rust-lang.github.io/rust-clippy/master/index.html#msrv)\n\n### Disabling evaluation of certain code\n\n> **Note:** This should only be used in cases where other solutions, like `#[allow(clippy::all)]`, are not sufficient.\n\nVery rarely, you may wish to prevent Clippy from evaluating certain sections of code entirely. You can do this with\n[conditional compilation](https://doc.rust-lang.org/reference/conditional-compilation.html) by checking that the\n`clippy` cfg is not set. You may need to provide a stub so that the code compiles:\n\n```rust\n#[cfg(not(clippy))]\ninclude!(concat!(env!(\"OUT_DIR\"), \"/my_big_function-generated.rs\"));\n\n#[cfg(clippy)]\nfn my_big_function(_input: &str) -> Option<MyStruct> {\n    None\n}\n```\n"
  },
  {
    "path": "book/src/continuous_integration/README.md",
    "content": "# Continuous Integration\n\nIt is recommended to run Clippy on CI with `-Dwarnings`, so that Clippy lints\nprevent CI from passing. To enforce errors on warnings on all `cargo` commands\nnot just `cargo clippy`, you can set the env var `RUSTFLAGS=\"-Dwarnings\"`.\n\nWe recommend to use Clippy from the same toolchain, that you use for compiling\nyour crate for maximum compatibility. E.g. if your crate is compiled with the\n`stable` toolchain, you should also use `stable` Clippy.\n\n> _Note:_ New Clippy lints are first added to the `nightly` toolchain. If you\n> want to help with improving Clippy and have CI resources left, please consider\n> adding a `nightly` Clippy check to your CI and report problems like false\n> positives back to us. With that we can fix bugs early, before they can get to\n> stable.\n\nThis chapter will give an overview on how to use Clippy on different popular CI\nproviders.\n"
  },
  {
    "path": "book/src/continuous_integration/github_actions.md",
    "content": "# GitHub Actions\n\nGitHub hosted runners using the latest stable version of Rust have Clippy pre-installed.\nIt is as simple as running `cargo clippy` to run lints against the codebase.\n\n```yml\non: push\nname: Clippy check\n\n# Make sure CI fails on all warnings, including Clippy lints\nenv:\n  RUSTFLAGS: \"-Dwarnings\"\n\njobs:\n  clippy_check:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n      - name: Run Clippy\n        run: cargo clippy --all-targets --all-features\n```\n"
  },
  {
    "path": "book/src/continuous_integration/gitlab.md",
    "content": "# GitLab CI\n\nYou can add Clippy to GitLab CI by using the latest stable [rust docker image](https://hub.docker.com/_/rust),\nas it is shown in the `.gitlab-ci.yml` CI configuration file below,\n\n```yml\n# Make sure CI fails on all warnings, including Clippy lints\nvariables:\n  RUSTFLAGS: \"-Dwarnings\"\n\nclippy_check:\n  image: rust:latest\n  script:\n    - rustup component add clippy\n    - cargo clippy --all-targets --all-features\n```\n"
  },
  {
    "path": "book/src/continuous_integration/travis.md",
    "content": "# Travis CI\n\nYou can add Clippy to Travis CI in the same way you use it locally:\n\n```yml\nlanguage: rust\nrust:\n  - stable\n  - beta\nbefore_script:\n  - rustup component add clippy\nscript:\n  - cargo clippy\n  # if you want the build job to fail when encountering warnings, use\n  - cargo clippy -- -D warnings\n  # in order to also check tests and non-default crate features, use\n  - cargo clippy --all-targets --all-features -- -D warnings\n  - cargo test\n  # etc.\n```\n"
  },
  {
    "path": "book/src/development/README.md",
    "content": "# Clippy Development\n\nHello fellow Rustacean! If you made it here, you're probably interested in\nmaking Clippy better by contributing to it. In that case, welcome to the\nproject!\n\n> _Note:_ If you're just interested in using Clippy, there's nothing to see from\n> this point onward, and you should return to one of the earlier chapters.\n\n## Getting started\n\nIf this is your first time contributing to Clippy, you should first read the\n[Basics docs](basics.md). This will explain the basics on how to get the source\ncode and how to compile and test the code.\n\n## Additional Readings for Beginners\n\nIf a dear reader of this documentation has never taken a class on compilers\nand interpreters, it might be confusing as to why AST level deals with only\nthe language's syntax. And some readers might not even understand what lexing,\nparsing, and AST mean.\n\nThis documentation serves by no means as a crash course on compilers or language design.\nAnd for details specifically related to Rust, the [Rustc Development Guide][rustc_dev_guide]\nis a far better choice to peruse.\n\nThe [Syntax and AST][ast] chapter and the [High-Level IR][hir] chapter are\ngreat introduction to the concepts mentioned in this chapter.\n\nSome readers might also find the [introductory chapter][map_of_territory] of\nRobert Nystrom's _Crafting Interpreters_ a helpful overview of compiled and\ninterpreted languages before jumping back to the Rustc guide.\n\n## Writing code\n\nIf you have done the basic setup, it's time to start hacking.\n\nThe [Adding lints](adding_lints.md) chapter is a walk through on how to add a\nnew lint to Clippy. This is also interesting if you just want to fix a lint,\nbecause it also covers how to test lints and gives an overview of the bigger\npicture.\n\nIf you want to add a new lint or change existing ones apart from bugfixing, it's\nalso a good idea to give the [stability guarantees][rfc_stability] and\n[lint categories][rfc_lint_cats] sections of the [Clippy 1.0 RFC][clippy_rfc] a\nquick read. The lint categories are also described [earlier in this\nbook](../lints.md).\n\n> _Note:_ Some higher level things about contributing to Clippy are still\n> covered in the [`CONTRIBUTING.md`] document. Some of those will be moved to\n> the book over time, like:\n> - Finding something to fix\n> - IDE setup\n> - High level overview on how Clippy works\n> - Triage procedure\n\n[ast]: https://rustc-dev-guide.rust-lang.org/syntax-intro.html\n[hir]: https://rustc-dev-guide.rust-lang.org/hir.html\n[rustc_dev_guide]: https://rustc-dev-guide.rust-lang.org/\n[map_of_territory]: https://craftinginterpreters.com/a-map-of-the-territory.html\n[clippy_rfc]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md\n[rfc_stability]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#stability-guarantees\n[rfc_lint_cats]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#lint-audit-and-categories\n[`CONTRIBUTING.md`]: https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md\n"
  },
  {
    "path": "book/src/development/adding_lints.md",
    "content": "# Adding a new lint\n\nYou are probably here because you want to add a new lint to Clippy. If this is\nthe first time you're contributing to Clippy, this document guides you through\ncreating an example lint from scratch.\n\nTo get started, we will create a lint that detects functions called `foo`,\nbecause that's clearly a non-descriptive name.\n\n- [Adding a new lint](#adding-a-new-lint)\n  - [Setup](#setup)\n  - [Getting Started](#getting-started)\n    - [Defining Our Lint](#defining-our-lint)\n      - [Standalone](#standalone)\n      - [Specific Type](#specific-type)\n      - [Tests Location](#tests-location)\n  - [Testing](#testing)\n    - [Cargo lints](#cargo-lints)\n  - [Rustfix tests](#rustfix-tests)\n  - [Testing manually](#testing-manually)\n  - [Lint declaration](#lint-declaration)\n  - [Lint registration](#lint-registration)\n  - [Lint passes](#lint-passes)\n  - [Emitting a lint](#emitting-a-lint)\n  - [Adding the lint logic](#adding-the-lint-logic)\n  - [Specifying the lint's minimum supported Rust version (MSRV)](#specifying-the-lints-minimum-supported-rust-version-msrv)\n  - [Author lint](#author-lint)\n  - [Print HIR lint](#print-hir-lint)\n  - [Documentation](#documentation)\n  - [Running rustfmt](#running-rustfmt)\n  - [Debugging](#debugging)\n  - [Conflicting lints](#conflicting-lints)\n  - [PR Checklist](#pr-checklist)\n  - [Adding configuration to a lint](#adding-configuration-to-a-lint)\n  - [Cheat Sheet](#cheat-sheet)\n\n## Setup\n\nSee the [Basics](basics.md#get-the-code) documentation.\n\n## Getting Started\n\nThere is a bit of boilerplate code that needs to be set up when creating a new\nlint. Fortunately, you can use the Clippy dev tools to handle this for you. We\nare naming our new lint `foo_functions` (lints are generally written in snake\ncase), and we don't need type information, so it will have an early pass type\n(more on this later). If you're unsure if the name you chose fits the lint,\ntake a look at our [lint naming guidelines][lint_naming].\n\n## Defining Our Lint\nTo get started, there are two ways to define our lint.\n\n### Standalone\nCommand: `cargo dev new_lint --name=foo_functions --pass=early --category=pedantic`\n(category will default to nursery if not provided)\n\nThis command will create a new file: `clippy_lints/src/foo_functions.rs`, as well\nas [register the lint](#lint-registration).\n\n### Specific Type\nCommand: `cargo dev new_lint --name=foo_functions --type=functions --category=pedantic`\n\nThis command will create a new file: `clippy_lints/src/{type}/foo_functions.rs`.\n\nNotice how this command has a `--type` flag instead of `--pass`. Unlike a standalone\ndefinition, this lint won't be registered in the traditional sense. Instead, you will\ncall your lint from within the type's lint pass, found in `clippy_lints/src/{type}/mod.rs`.\n\nA \"type\" is just the name of a directory in `clippy_lints/src`, like `functions` in\nthe example command. These are groupings of lints with common behaviors, so if your\nlint falls into one, it would be best to add it to that type.\n\n### Tests Location\nBoth commands will create a file: `tests/ui/foo_functions.rs`. For cargo lints,\ntwo project hierarchies (fail/pass) will be created by default under `tests/ui-cargo`.\n\nNext, we'll open up these files and add our lint!\n\n## Testing\n\nLet's write some tests first that we can execute while we iterate on our lint.\n\nClippy uses UI tests for testing. UI tests check that the output of Clippy is\nexactly as expected. Each test is just a plain Rust file that contains the code\nwe want to check. The output of Clippy is compared against a `.stderr` file.\nNote that you don't have to create this file yourself, we'll get to generating\nthe `.stderr` files further down.\n\nWe start by opening the test file created at `tests/ui/foo_functions.rs`.\n\nUpdate the file with some examples to get started:\n\n```rust\n#![allow(unused)]\n#![warn(clippy::foo_functions)]\n\n// Impl methods\nstruct A;\nimpl A {\n    pub fn fo(&self) {}\n    pub fn foo(&self) {}\n    //~^ foo_functions\n    pub fn food(&self) {}\n}\n\n// Default trait methods\ntrait B {\n    fn fo(&self) {}\n    fn foo(&self) {}\n    //~^ foo_functions\n    fn food(&self) {}\n}\n\n// Plain functions\nfn fo() {}\nfn foo() {}\n//~^ foo_functions\nfn food() {}\n\nfn main() {\n    // We also don't want to lint method calls\n    foo();\n    let a = A;\n    a.foo();\n}\n```\n\nNote that we are adding comment annotations with the name of our lint to mark\nlines where we expect an error. Except for very specific situations\n(`//@check-pass`), at least one error marker must be present in a test file for\nit to be accepted.\n\nOnce we have implemented our lint we can run `TESTNAME=foo_functions cargo\nuibless` to generate the `.stderr` file. If our lint makes use of structured\nsuggestions then this command will also generate the corresponding `.fixed`\nfile.\n\nWhile we are working on implementing our lint, we can keep running the UI test.\nThat allows us to check if the output is turning into what we want by checking the\n`.stderr` file that gets updated on every test run.\n\nOnce we have implemented our lint running `TESTNAME=foo_functions cargo uitest`\nshould pass on its own. When we commit our lint, we need to commit the generated\n `.stderr` and if applicable `.fixed` files, too. In general, you should only\n commit files changed by `cargo bless` for the specific lint you are creating/editing.\n\n> _Note:_ you can run multiple test files by specifying a comma separated list:\n> `TESTNAME=foo_functions,test2,test3`.\n\n### Cargo lints\n\nFor cargo lints, the process of testing differs in that we are interested in the\n`Cargo.toml` manifest file. We also need a minimal crate associated with that\nmanifest.\n\nIf our new lint is named e.g. `foo_categories`, after running `cargo dev\nnew_lint --name=foo_categories --type=cargo --category=cargo` we will find by\ndefault two new crates, each with its manifest file:\n\n* `tests/ui-cargo/foo_categories/fail/Cargo.toml`: this file should cause the\n  new lint to raise an error.\n* `tests/ui-cargo/foo_categories/pass/Cargo.toml`: this file should not trigger\n  the lint.\n\nIf you need more cases, you can copy one of those crates (under\n`foo_categories`) and rename it.\n\nThe process of generating the `.stderr` file is the same, and prepending the\n`TESTNAME` variable to `cargo uitest` works too.\n\n## Rustfix tests\n\nIf the lint you are working on is making use of structured suggestions, the test\nwill create a `.fixed` file by running [rustfix] for that test.\nRustfix will apply the suggestions\nfrom the lint to the code of the test file and compare that to the contents of a\n`.fixed` file.\n\nUse `cargo bless` to automatically generate the `.fixed` file while running\nthe tests.\n\n[rustfix]: https://github.com/rust-lang/cargo/tree/master/crates/rustfix\n\n## Testing manually\n\nManually testing against an example file can be useful if you have added some\n`println!`s and the test suite output becomes unreadable. To try Clippy with\nyour local modifications, run the following from the Clippy directory:\n\n```bash\ncargo dev lint input.rs\n```\n\nTo run Clippy on an existing project rather than a single file you can use\n\n```bash\ncargo dev lint /path/to/project\n```\n\nOr set up a rustup toolchain that points to the local Clippy binaries\n\n```bash\ncargo dev setup toolchain\n\n# Then in `/path/to/project` you can run\ncargo +clippy clippy\n```\n\n## Lint declaration\n\nLet's start by opening the new file created in the `clippy_lints` crate at\n`clippy_lints/src/foo_functions.rs`. That's the crate where all the lint code\nis. This file has already imported some initial things we will need:\n\n```rust\nuse rustc_lint::{EarlyLintPass, EarlyContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_ast::ast::*;\n```\n\nThe next step is to update the lint declaration. Lints are declared using the\n[`declare_clippy_lint!`][declare_clippy_lint] macro, and we just need to update\nthe auto-generated lint declaration to have a real description, something like\nthis:\n\n```rust\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// ### Why is this bad?\n    ///\n    /// ### Example\n    /// ```rust\n    /// // example code\n    /// ```\n    #[clippy::version = \"1.29.0\"]\n    pub FOO_FUNCTIONS,\n    pedantic,\n    \"function named `foo`, which is not a descriptive name\"\n}\n```\n\n* The section of lines prefixed with `///` constitutes the lint documentation\n  section. This is the default documentation style and will be displayed [like\n  this][example_lint_page]. To render and open this documentation locally in a\n  browser, run `cargo dev serve`.\n* The `#[clippy::version]` attribute will be rendered as part of the lint\n  documentation. The value should be set to the current Rust version that the\n  lint is developed in, it can be retrieved by running `rustc -vV` in the\n  rust-clippy directory. The version is listed under *release*. (Use the version\n  without the `-nightly`) suffix.\n* `FOO_FUNCTIONS` is the name of our lint. Be sure to follow the [lint naming\n  guidelines][lint_naming] here when naming your lint. In short, the name should\n  state the thing that is being checked for and read well when used with\n  `allow`/`warn`/`deny`.\n* `pedantic` sets the lint level to `Allow`. The exact mapping can be found\n  [here][category_level_mapping]\n* The last part should be a text that explains what exactly is wrong with the\n  code\n\nThe rest of this file contains an empty implementation for our lint pass, which\nin this case is `EarlyLintPass` and should look like this:\n\n```rust\n// clippy_lints/src/foo_functions.rs\n\n// .. imports and lint declaration ..\n\ndeclare_lint_pass!(FooFunctions => [FOO_FUNCTIONS]);\n\nimpl EarlyLintPass for FooFunctions {}\n```\n\n[declare_clippy_lint]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L60\n[example_lint_page]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure\n[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints\n[category_level_mapping]: ../index.html\n\n## Lint registration\n\nWhen using `cargo dev new_lint`, the lint is automatically registered and\nnothing more has to be done.\n\nWhen declaring a new lint by hand and `cargo dev update_lints` is used, the lint\npass may have to be registered manually in the `register_lints` function in\n`clippy_lints/src/lib.rs`:\n\n```rust,ignore\nstore.register_early_pass(|| Box::new(foo_functions::FooFunctions));\n```\n\nAs one may expect, there is a corresponding `register_late_pass` method\navailable as well. Without a call to one of `register_early_pass` or\n`register_late_pass`, the lint pass in question will not be run.\n\nOne reason that `cargo dev update_lints` does not automate this step is that\nmultiple lints can use the same lint pass, so registering the lint pass may\nalready be done when adding a new lint. Another reason that this step is not\nautomated is that the order that the passes are registered determines the order\nthe passes actually run, which in turn affects the order that any emitted lints\nare output in.\n\n## Lint passes\n\nWriting a lint that only checks for the name of a function means that we only\nhave to deal with the AST and don't have to deal with the type system at all.\nThis is good, because it makes writing this particular lint less complicated.\n\nWe have to make this decision with every new Clippy lint. It boils down to using\neither [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass].\n\n`EarlyLintPass` runs before type checking and\n[HIR](https://rustc-dev-guide.rust-lang.org/hir.html) lowering, while `LateLintPass`\nruns after these stages, providing access to type information. The `cargo dev new_lint` command\ndefaults to the recommended `LateLintPass`, but you can specify `--pass=early` if your lint\nonly needs AST level analysis.\n\nSince we don't need type information for checking the function name, we used\n`--pass=early` when running the new lint automation and all the imports were\nadded accordingly.\n\n[early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html\n[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html\n\n## Emitting a lint\n\nWith UI tests and the lint declaration in place, we can start working on the\nimplementation of the lint logic.\n\nLet's start by implementing the `EarlyLintPass` for our `FooFunctions`:\n\n```rust,ignore\nimpl EarlyLintPass for FooFunctions {\n    fn check_fn(&mut self, cx: &EarlyContext<'_>, fn_kind: FnKind<'_>, span: Span, _: NodeId) {\n        // TODO: Emit lint here\n    }\n}\n```\n\nWe implement the [`check_fn`][check_fn] method from the\n[`EarlyLintPass`][early_lint_pass] trait. This gives us access to various\ninformation about the function that is currently being checked. More on that in\nthe next section. Let's worry about the details later and emit our lint for\n*every* function definition first.\n\nDepending on how complex we want our lint message to be, we can choose from a\nvariety of lint emission functions. They can all be found in\n[`clippy_utils/src/diagnostics.rs`][diagnostics].\n\n`span_lint_and_help` seems most appropriate in this case. It allows us to\nprovide an extra help message, and we can't really suggest a better name\nautomatically. This is how it looks:\n\n```rust,ignore\nimpl EarlyLintPass for FooFunctions {\n    fn check_fn(&mut self, cx: &EarlyContext<'_>, fn_kind: FnKind<'_>, span: Span, _: NodeId) {\n        span_lint_and_help(\n            cx,\n            FOO_FUNCTIONS,\n            span,\n            \"function named `foo`\",\n            None,\n            \"consider using a more meaningful name\"\n        );\n    }\n}\n```\n\nRunning our UI test should now produce output that contains the lint message.\n\nAccording to [the rustc-dev-guide], the text should be matter of fact and avoid\ncapitalization and periods, unless multiple sentences are needed. When code or\nan identifier must appear in a message or label, it should be surrounded with\nsingle grave accents \\`.\n\n[check_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html#method.check_fn\n[diagnostics]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_utils/src/diagnostics.rs\n[the rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/diagnostics.html\n\n## Adding the lint logic\n\nWriting the logic for your lint will most likely be different from our example,\nso this section is kept rather short.\n\nUsing the [`check_fn`][check_fn] method gives us access to [`FnKind`][fn_kind]\nthat has the [`FnKind::Fn`] variant. It provides access to the name of the\nfunction/method via an [`Ident`][ident].\n\nWith that we can expand our `check_fn` method to:\n\n```rust\nimpl EarlyLintPass for FooFunctions {\n    fn check_fn(&mut self, cx: &EarlyContext<'_>, fn_kind: FnKind<'_>, span: Span, _: NodeId) {\n        if is_foo_fn(fn_kind) {\n            span_lint_and_help(\n                cx,\n                FOO_FUNCTIONS,\n                span,\n                \"function named `foo`\",\n                None,\n                \"consider using a more meaningful name\"\n            );\n        }\n    }\n}\n```\n\nWe separate the lint conditional from the lint emissions because it makes the\ncode a bit easier to read. In some cases this separation would also allow to\nwrite some unit tests (as opposed to only UI tests) for the separate function.\n\nIn our example, `is_foo_fn` looks like:\n\n```rust\n// use statements, impl EarlyLintPass, check_fn, ..\n\nfn is_foo_fn(fn_kind: FnKind<'_>) -> bool {\n    match fn_kind {\n        FnKind::Fn(_, _, Fn { ident, .. }) => {\n            // check if `fn` name is `foo`\n            ident.name.as_str() == \"foo\"\n        }\n        // ignore closures\n        FnKind::Closure(..) => false\n    }\n}\n```\n\nNow we should also run the full test suite with `cargo test`. At this point\nrunning `cargo test` should produce the expected output. Remember to run `cargo\nbless` to update the `.stderr` file.\n\n`cargo test` (as opposed to `cargo uitest`) will also ensure that our lint\nimplementation is not violating any Clippy lints itself.\n\nThat should be it for the lint implementation. Running `cargo test` should now\npass.\n\n[fn_kind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/visit/enum.FnKind.html\n[`FnKind::Fn`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/visit/enum.FnKind.html#variant.Fn\n[ident]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Ident.html\n\n## Specifying the lint's minimum supported Rust version (MSRV)\n\nSometimes a lint makes suggestions that require a certain version of Rust. For\nexample, the `manual_strip` lint suggests using `str::strip_prefix` and\n`str::strip_suffix` which is only available after Rust 1.45. In such cases, you\nneed to ensure that the MSRV configured for the project is >= the MSRV of the\nrequired Rust feature. If multiple features are required, just use the one with\na lower MSRV.\n\nFirst, add an MSRV alias for the required feature in [`clippy_utils::msrvs`].\nThis can be accessed later as `msrvs::STR_STRIP_PREFIX`, for example.\n\n```rust\nmsrv_aliases! {\n    ..\n    1,45,0 { STR_STRIP_PREFIX }\n}\n```\n\nIn order to access the project-configured MSRV, you need to have an `msrv` field\nin the LintPass struct, and a constructor to initialize the field. The `msrv`\nvalue is passed to the constructor in `clippy_lints/lib.rs`.\n\n```rust\npub struct ManualStrip {\n    msrv: Msrv,\n}\n\nimpl ManualStrip {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n```\n\nThe project's MSRV can then be matched against the feature MSRV in the LintPass\nusing the `Msrv::meets` method.\n\n``` rust\nif !self.msrv.meets(cx, msrvs::STR_STRIP_PREFIX) {\n    return;\n}\n```\n\nEarly lint passes should instead use `MsrvStack` coupled with\n`extract_msrv_attr!()`\n\nOnce the `msrv` is added to the lint, a relevant test case should be added to\nthe lint's test file, `tests/ui/manual_strip.rs` in this example. It should\nhave a case for the version below the MSRV and one with the same contents but\nfor the MSRV version itself.\n\n```rust,ignore\n...\n\n#[clippy::msrv = \"1.44\"]\nfn msrv_1_44() {\n    /* something that would trigger the lint */\n}\n\n#[clippy::msrv = \"1.45\"]\nfn msrv_1_45() {\n    /* something that would trigger the lint */\n}\n```\n\nAs a last step, the lint should be added to the lint documentation. This is done\nin `clippy_config/src/conf.rs`:\n\n```rust\ndefine_Conf! {\n    #[lints(\n        allow_attributes,\n        allow_attributes_without_reason,\n        ..\n        <the newly added lint name>,\n        ..\n        unused_trait_names,\n        use_self,\n    )]\n    msrv: Msrv = Msrv::default(),\n    ...\n}\n```\n\n[`clippy_utils::msrvs`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_config/msrvs/index.html\n\nAfterwards update the documentation for the book as described in [Adding configuration to a lint](#adding-configuration-to-a-lint).\n\n## Author lint\n\nIf you have trouble implementing your lint, there is also the internal `author`\nlint to generate Clippy code that detects the offending pattern. It does not\nwork for all the Rust syntax, but can give a good starting point.\n\nThe quickest way to use it, is the [Rust playground:\nplay.rust-lang.org][author_example]. Put the code you want to lint into the\neditor and add the `#[clippy::author]` attribute above the item. Then run Clippy\nvia `Tools -> Clippy` and you should see the generated code in the output below.\n\n[Here][author_example] is an example on the playground.\n\nIf the command was executed successfully, you can copy the code over to where\nyou are implementing your lint.\n\n[author_example]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=9a12cb60e5c6ad4e3003ac6d5e63cf55\n\n## Print HIR lint\n\nTo implement a lint, it's helpful to first understand the internal\nrepresentation that rustc uses. Clippy has the `#[clippy::dump]` attribute that\nprints the [_High-Level Intermediate Representation (HIR)_] of the item,\nstatement, or expression that the attribute is attached to. To attach the\nattribute to expressions you often need to enable\n`#![feature(stmt_expr_attributes)]`.\n\n[Here][print_hir_example] you can find an example, just select _Tools_ and run\n_Clippy_.\n\n[_High-Level Intermediate Representation (HIR)_]: https://rustc-dev-guide.rust-lang.org/hir.html\n[print_hir_example]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=daf14db3a7f39ca467cd1b86c34b9afb\n\n## Documentation\n\nThe final thing before submitting our PR is to add some documentation to our\nlint declaration.\n\nPlease document your lint with a doc comment akin to the following:\n\n```rust\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for ... (describe what the lint matches).\n    ///\n    /// ### Why is this bad?\n    /// Supply the reason for linting the code.\n    ///\n    /// ### Example\n    ///\n    /// ```rust,ignore\n    /// // A short example of code that triggers the lint\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// // A short example of improved code that doesn't trigger the lint\n    /// ```\n    #[clippy::version = \"1.29.0\"]\n    pub FOO_FUNCTIONS,\n    pedantic,\n    \"function named `foo`, which is not a descriptive name\"\n}\n```\n\nIf the lint is in the `restriction` group because it lints things that are not\nnecessarily “bad” but are more of a style choice, then replace the\n“Why is this bad?” section heading with “Why restrict this?”, to avoid writing\n“Why is this bad? It isn't, but ...”.\n\nOnce your lint is merged, this documentation will show up in the [lint\nlist][lint_list].\n\n[lint_list]: https://rust-lang.github.io/rust-clippy/master/index.html\n\n## Running rustfmt\n\n[Rustfmt] is a tool for formatting Rust code according to style guidelines. Your\ncode has to be formatted by `rustfmt` before a PR can be merged. Clippy uses\nnightly `rustfmt` in the CI.\n\nIt can be installed via `rustup`:\n\n```bash\nrustup component add rustfmt --toolchain=nightly\n```\n\nUse `cargo dev fmt` to format the whole codebase. Make sure that `rustfmt` is\ninstalled for the nightly toolchain.\n\n[Rustfmt]: https://github.com/rust-lang/rustfmt\n\n## Debugging\n\nIf you want to debug parts of your lint implementation, you can use the [`dbg!`]\nmacro anywhere in your code. Running the tests should then include the debug\noutput in the `stdout` part.\n\n[`dbg!`]: https://doc.rust-lang.org/std/macro.dbg.html\n\n## Conflicting lints\n\nThere are several lints that deal with the same pattern but suggest different approaches. In other words, some lints\nmay suggest modifications that go in the opposite direction to what some other lints already propose for the same\ncode, creating conflicting diagnostics.\n\nWhen you are creating a lint that ends up in this scenario, the following tips should be encouraged to guide\nclassification:\n\n* The only case where they should be in the same category is if that category is `restriction`. For example,\n`semicolon_inside_block` and `semicolon_outside_block`.\n* For all the other cases, they should be in different categories with different levels of allowance. For example,\n`implicit_return` (restriction, allow) and `needless_return` (style, warn).\n\nFor lints that are in different categories, it is also recommended that at least one of them should be in the\n`restriction` category. The reason for this is that the `restriction` group is the only group where we don't\nrecommend to enable the entire set, but cherry pick lints out of.\n\n## PR Checklist\n\nBefore submitting your PR make sure you followed all the basic requirements:\n\n<!-- Sync this with `.github/PULL_REQUEST_TEMPLATE` -->\n\n- \\[ ] Followed [lint naming conventions][lint_naming]\n- \\[ ] Added passing UI tests (including committed `.stderr` file)\n- \\[ ] `cargo test` passes locally\n- \\[ ] Executed `cargo dev update_lints`\n- \\[ ] Added lint documentation\n- \\[ ] Run `cargo dev fmt`\n\n## Adding configuration to a lint\n\nClippy supports the configuration of lints values using a `clippy.toml` file which is searched for in:\n\n1. The directory specified by the `CLIPPY_CONF_DIR` environment variable, or\n2. The directory specified by the\n[CARGO_MANIFEST_DIR](https://doc.rust-lang.org/cargo/reference/environment-variables.html) environment variable, or\n3. The current directory.\n\nAdding a configuration to a lint can be useful for\nthresholds or to constrain some behavior that can be seen as a false positive\nfor some users. Adding a configuration is done in the following steps:\n\n1. Adding a new configuration entry to [`clippy_config::conf`] like this:\n\n   ```rust,ignore\n   /// Lint: LINT_NAME.\n   ///\n   /// <The configuration field doc comment>\n   (configuration_ident: Type = DefaultValue),\n   ```\n\n   The doc comment is automatically added to the documentation of the listed\n   lints. The default value will be formatted using the `Debug` implementation\n   of the type.\n2. Adding the configuration value to the lint impl struct:\n    1. This first requires the definition of a lint impl struct. Lint impl\n       structs are usually generated with the `declare_lint_pass!` macro. This\n       struct needs to be defined manually to add some kind of metadata to it:\n       ```rust\n       // Generated struct definition\n       declare_lint_pass!(StructName => [\n           LINT_NAME\n       ]);\n\n       // New manual definition struct\n       pub struct StructName {}\n\n       impl_lint_pass!(StructName => [\n           LINT_NAME\n       ]);\n       ```\n\n    2. Next add the configuration value and a corresponding creation method like\n       this:\n       ```rust\n       pub struct StructName {\n           configuration_ident: Type,\n       }\n\n       // ...\n\n       impl StructName {\n           pub fn new(conf: &'static Conf) -> Self {\n               Self {\n                   configuration_ident: conf.configuration_ident,\n               }\n           }\n       }\n       ```\n3. Passing the configuration value to the lint impl struct:\n\n   First find the struct construction in the [`clippy_lints` lib file]. The\n   configuration value is now cloned or copied into a local value that is then\n   passed to the impl struct like this:\n\n   ```rust,ignore\n   // Default generated registration:\n   store.register_*_pass(|| box module::StructName);\n\n   // New registration with configuration value\n   store.register_*_pass(move || box module::StructName::new(conf));\n   ```\n\n   Congratulations the work is almost done. The configuration value can now be\n   accessed in the linting code via `self.configuration_ident`.\n\n4. Adding tests:\n    1. The default configured value can be tested like any normal lint in\n       [`tests/ui`].\n    2. The configuration itself will be tested separately in [`tests/ui-toml`].\n       Simply add a new subfolder with a fitting name. This folder contains a\n       `clippy.toml` file with the configuration value and a rust file that\n       should be linted by Clippy. The test can otherwise be written as usual.\n\n5. Update [Lint Configuration](../lint_configuration.md)\n\n   Run `cargo bless --test config-metadata` to generate documentation changes for the book.\n\n[`clippy_config::conf`]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_config/src/conf.rs\n[`clippy_lints` lib file]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/lib.rs\n[`tests/ui`]: https://github.com/rust-lang/rust-clippy/blob/master/tests/ui\n[`tests/ui-toml`]: https://github.com/rust-lang/rust-clippy/blob/master/tests/ui-toml\n\n## Cheat Sheet\n\nHere are some pointers to things you are likely going to need for every lint:\n\n* [Clippy utils][utils] - Various helper functions. Maybe the function you need\n  is already in here ([`implements_trait`], [`snippet`], etc)\n* [Clippy diagnostics][diagnostics]\n* [Let chains][let-chains]\n* [`from_expansion`][from_expansion] and\n  [`in_external_macro`][in_external_macro]\n* [`Span`][span]\n* [`Applicability`][applicability]\n* [Common tools for writing lints](common_tools_writing_lints.md) helps with\n  common operations\n* [The rustc-dev-guide][rustc-dev-guide] explains a lot of internal compiler\n  concepts\n* [The nightly rustc docs][nightly_docs] which has been linked to throughout\n  this guide\n\nFor `EarlyLintPass` lints:\n\n* [`EarlyLintPass`][early_lint_pass]\n* [`rustc_ast::ast`][ast]\n\nFor `LateLintPass` lints:\n\n* [`LateLintPass`][late_lint_pass]\n* [`Ty::TyKind`][ty]\n\nWhile most of Clippy's lint utils are documented, most of rustc's internals lack\ndocumentation currently. This is unfortunate, but in most cases you can probably\nget away with copying things from existing similar lints. If you are stuck,\ndon't hesitate to ask on [Zulip] or in the issue/PR.\n\n[utils]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/index.html\n[`implements_trait`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.implements_trait.html\n[`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html\n[let-chains]: https://github.com/rust-lang/rust/pull/94927\n[from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion\n[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro\n[span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html\n[applicability]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html\n[rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/\n[nightly_docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/\n[ast]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html\n[ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/sty/index.html\n[Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/clippy\n"
  },
  {
    "path": "book/src/development/basics.md",
    "content": "# Basics for hacking on Clippy\n\nThis document explains the basics for hacking on Clippy. Besides others, this\nincludes how to build and test Clippy. For a more in depth description on the\ncodebase take a look at [Adding Lints] or [Common Tools].\n\n[Adding Lints]: adding_lints.md\n[Common Tools]: common_tools_writing_lints.md\n\n- [Basics for hacking on Clippy](#basics-for-hacking-on-clippy)\n  - [Get the Code](#get-the-code)\n  - [Building and Testing](#building-and-testing)\n  - [`cargo dev`](#cargo-dev)\n  - [lintcheck](#lintcheck)\n  - [PR](#pr)\n  - [Common Abbreviations](#common-abbreviations)\n  - [Install from source](#install-from-source)\n\n## Get the Code\n\nFirst, make sure you have checked out the latest version of Clippy. If this is\nyour first time working on Clippy, create a fork of the repository and clone it\nafterwards with the following command:\n\n```bash\ngit clone git@github.com:<your-username>/rust-clippy\n```\n\nIf you've already cloned Clippy in the past, update it to the latest version:\n\n```bash\n# If the upstream remote has not been added yet\ngit remote add upstream https://github.com/rust-lang/rust-clippy\n# upstream has to be the remote of the rust-lang/rust-clippy repo\ngit fetch upstream\n# make sure that you are on the master branch\ngit checkout master\n# rebase your master branch on the upstream master\ngit rebase upstream/master\n# push to the master branch of your fork\ngit push\n```\n\n## Building and Testing\n\nYou can build and test Clippy like every other Rust project:\n\n```bash\ncargo build  # builds Clippy\ncargo test   # tests Clippy\n```\n\nSince Clippy's test suite is pretty big, there are some commands that only run a\nsubset of Clippy's tests:\n\n```bash\n# only run UI tests\ncargo uitest\n# only run UI tests starting with `test_`\nTESTNAME=\"test_\" cargo uitest\n# only run dogfood tests\ncargo dev dogfood\n```\n\nIf the output of a [UI test] differs from the expected output, you can update\nthe reference file with:\n\n```bash\ncargo bless\n```\n\nFor example, this is necessary if you fix a typo in an error message of a lint,\nor if you modify a test file to add a test case.\n\n> _Note:_ This command may update more files than you intended. In that case\n> only commit the files you wanted to update.\n\n[UI test]: https://rustc-dev-guide.rust-lang.org/tests/adding.html#ui-test-walkthrough\n\n## `cargo dev`\n\nClippy has some dev tools to make working on Clippy more convenient. These tools\ncan be accessed through the `cargo dev` command. Available tools are listed\nbelow. To get more information about these commands, just call them with\n`--help`.\n\n```bash\n# formats the whole Clippy codebase and all tests\ncargo dev fmt\n# register or update lint names/groups/...\ncargo dev update_lints\n# create a new lint and register it\ncargo dev new_lint\n# deprecate a lint and attempt to remove code relating to it\ncargo dev deprecate\n# automatically formatting all code before each commit\ncargo dev setup git-hook\n# (experimental) Setup Clippy to work with RustRover\ncargo dev setup intellij\n# runs the `dogfood` tests\ncargo dev dogfood\n```\n\nMore about [intellij] command usage and reasons.\n\n[intellij]: https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md#rustrover\n\n## lintcheck\n\n`cargo lintcheck` will build and run Clippy on a fixed set of crates and\ngenerate a log of the results.  You can `git diff` the updated log against its\nprevious version and see what impact your lint made on a small set of crates.\nIf you add a new lint, please audit the resulting warnings and make sure there\nare no false positives and that the suggestions are valid.\n\nRefer to the tools [README] for more details.\n\n[README]: https://github.com/rust-lang/rust-clippy/blob/master/lintcheck/README.md\n\n## PR\n\nWe follow a rustc no merge-commit policy. See\n<https://rustc-dev-guide.rust-lang.org/contributing.html#opening-a-pr>.\n\n## Common Abbreviations\n\n| Abbreviation | Meaning                                |\n|--------------|----------------------------------------|\n| UB           | Undefined Behavior                     |\n| FP           | False Positive                         |\n| FN           | False Negative                         |\n| ICE          | Internal Compiler Error                |\n| AST          | Abstract Syntax Tree                   |\n| MIR          | Mid-Level Intermediate Representation  |\n| HIR          | High-Level Intermediate Representation |\n| TCX          | Type context                           |\n\nThis is a concise list of abbreviations that can come up during Clippy\ndevelopment. An extensive general list can be found in the [rustc-dev-guide\nglossary][glossary]. Always feel free to ask if an abbreviation or meaning is\nunclear to you.\n\n## Install from source\n\nIf you are hacking on Clippy and want to install it from source, do the\nfollowing:\n\nFrom the Clippy project root, run the following command to build the Clippy\nbinaries and copy them into the toolchain directory. This will create a new\ntoolchain called `clippy` by default, see `cargo dev setup toolchain --help`\nfor other options.\n\n```terminal\ncargo dev setup toolchain\n```\n\nNow you may run `cargo +clippy clippy` in any project using the new toolchain.\n\n```terminal\ncd my-project\ncargo +clippy clippy\n```\n\n...or `clippy-driver`\n\n```terminal\nclippy-driver +clippy <filename>\n```\n\nIf you no longer need the toolchain it can be uninstalled using `rustup`:\n\n```terminal\nrustup toolchain uninstall clippy\n```\n\n> **DO NOT** install using `cargo install --path . --force` since this will\n> overwrite rustup\n> [proxies](https://rust-lang.github.io/rustup/concepts/proxies.html). That is,\n> `~/.cargo/bin/cargo-clippy` and `~/.cargo/bin/clippy-driver` should be hard or\n> soft links to `~/.cargo/bin/rustup`. You can repair these by running `rustup\n> update`.\n\n[glossary]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html\n"
  },
  {
    "path": "book/src/development/common_tools_writing_lints.md",
    "content": "# Common tools for writing lints\n\nYou may need following tooltips to catch up with common operations.\n\n- [Common tools for writing lints](#common-tools-for-writing-lints)\n  - [Retrieving the type of expression](#retrieving-the-type-of-expression)\n  - [Checking if an expr is calling a specific method](#checking-if-an-expr-is-calling-a-specific-method)\n  - [Checking for a specific type](#checking-for-a-specific-type)\n  - [Checking if a type implements a specific trait](#checking-if-a-type-implements-a-specific-trait)\n  - [Checking if a type defines a specific method](#checking-if-a-type-defines-a-specific-method)\n  - [Dealing with macros](#dealing-with-macros-and-expansions)\n\nUseful Rustc dev guide links:\n- [Stages of compilation](https://rustc-dev-guide.rust-lang.org/compiler-src.html#the-main-stages-of-compilation)\n- [Diagnostic items](https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html)\n- [Type checking](https://rustc-dev-guide.rust-lang.org/type-checking.html)\n- [Ty module](https://rustc-dev-guide.rust-lang.org/ty.html)\n\n## Retrieving the type of expression\n\nSometimes you may want to retrieve the type `Ty` of an expression `Expr`, for\nexample to answer following questions:\n\n- which type does this expression correspond to (using its [`TyKind`][TyKind])?\n- is it a sized type?\n- is it a primitive type?\n- does it implement a trait?\n\nThis operation is performed using the [`expr_ty()`][expr_ty] method from the\n[`TypeckResults`][TypeckResults] struct, that gives you access to the underlying\nstructure [`Ty`][Ty].\n\nExample of use:\n```rust\nimpl LateLintPass<'_> for MyStructLint {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        // Get type of `expr`\n        let ty = cx.typeck_results().expr_ty(expr);\n        // Match its kind to enter its type\n        match ty.kind() {\n            ty::Adt(adt_def, _) if adt_def.is_struct() => println!(\"Our `expr` is a struct!\"),\n            _ => ()\n        }\n    }\n}\n```\n\nSimilarly, in [`TypeckResults`][TypeckResults] methods, you have the\n[`pat_ty()`][pat_ty] method to retrieve a type from a pattern.\n\nTwo noticeable items here:\n- `cx` is the lint context [`LateContext`][LateContext]. The two most useful\n  data structures in this context are `tcx` and the `TypeckResults` returned by\n  `LateContext::typeck_results`, allowing us to jump to type definitions and\n  other compilation stages such as HIR.\n- `typeck_results`'s return value is [`TypeckResults`][TypeckResults] and is\n  created by type checking step, it includes useful information such as types of\n  expressions, ways to resolve methods and so on.\n\n## Checking if an expr is calling a specific method\n\nStarting with an `expr`, you can check whether it is calling a specific method\n`some_method`:\n\n```rust\nimpl<'tcx> LateLintPass<'tcx> for MyStructLint {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        // Check our expr is calling a method\n        if let hir::ExprKind::MethodCall(path, _, _self_arg, ..) = &expr.kind\n            // Check the name of this method is `some_method`\n            && path.ident.name == sym::some_method\n            // Optionally, check the type of the self argument.\n            // - See \"Checking for a specific type\"\n        {\n                // ...\n        }\n    }\n}\n```\n\n## Checking for a specific type\n\nThere are three ways to check if an expression type is a specific type we want\nto check for. All of these methods only check for the base type, generic\narguments have to be checked separately.\n\n```rust\nuse clippy_utils::{paths, sym};\nuse clippy_utils::res::MaybeDef;\nuse rustc_hir::LangItem;\n\nimpl LateLintPass<'_> for MyStructLint {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        // Getting the expression type\n        let ty = cx.typeck_results().expr_ty(expr);\n\n        // 1. Using diagnostic items\n        // The last argument is the diagnostic item to check for\n        if ty.is_diag_item(cx, sym::Option) {\n            // The type is an `Option`\n        }\n\n        // 2. Using lang items\n        if ty.is_lang_item(cx, LangItem::RangeFull) {\n            // The type is a full range like `.drain(..)`\n        }\n\n        // 3. Using the type path\n        // This method should be avoided if possible\n        if paths::RESULT.matches_ty(cx, ty) {\n            // The type is a `core::result::Result`\n        }\n    }\n}\n```\n\nPrefer using diagnostic items and lang items where possible.\n\n## Checking if a type implements a specific trait\n\nThere are three ways to do this, depending on if the target trait has a\ndiagnostic item, lang item or neither.\n\n```rust\nuse clippy_utils::sym;\nuse clippy_utils::ty::implements_trait;\n\nimpl LateLintPass<'_> for MyStructLint {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n\n        // 1. Get the `DefId` of the trait.\n        // via lang items\n        let trait_id = cx.tcx.lang_items().drop_trait();\n        // via diagnostic items\n        let trait_id = cx.tcx.get_diagnostic_item(sym::Eq);\n\n        // 2. Check for the trait implementation via the `implements_trait` util.\n        let ty = cx.typeck_results().expr_ty(expr);\n        if trait_id.is_some_and(|id| implements_trait(cx, ty, id, &[])) {\n            // `ty` implements the trait.\n        }\n\n        // 3. If the trait requires additional generic arguments\n        let trait_id = cx.tcx.lang_items().eq_trait();\n        if trait_id.is_some_and(|id| implements_trait(cx, ty, id, &[ty])) {\n            // `ty` implements `PartialEq<Self>`\n        }\n    }\n}\n```\n\n> Prefer using diagnostic and lang items, if the target trait has one.\n\nWe access lang items through the type context `tcx`. `tcx` is of type\n[`TyCtxt`][TyCtxt] and is defined in the `rustc_middle` crate. A list of defined\npaths for Clippy can be found in [paths.rs][paths]\n\n## Checking if a type defines a specific method\n\nTo check if our type defines a method called `some_method`:\n\n```rust\nuse clippy_utils::ty::is_type_lang_item;\nuse clippy_utils::{sym, return_ty};\n\nimpl<'tcx> LateLintPass<'tcx> for MyTypeImpl {\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {\n        // Check if item is a method/function\n        if let ImplItemKind::Fn(ref signature, _) = impl_item.kind\n            // Check the method is named `some_method`\n            //\n            // Add `some_method` to `clippy_utils::sym` if it's not already there\n            && impl_item.ident.name == sym::some_method\n            // We can also check it has a parameter `self`\n            && signature.decl.implicit_self.has_implicit_self()\n            // We can go further and even check if its return type is `String`\n            && return_ty(cx, impl_item.hir_id).is_lang_item(cx, LangItem::String)\n        {\n            // ...\n        }\n    }\n}\n```\n\n## Dealing with macros and expansions\n\nKeep in mind that macros are already expanded and desugaring is already applied\nto the code representation that you are working with in Clippy. This\nunfortunately causes a lot of false positives because macro expansions are\n\"invisible\" unless you actively check for them. Generally speaking, code with\nmacro expansions should just be ignored by Clippy because that code can be\ndynamic in ways that are difficult or impossible to see. Use the following\nfunctions to deal with macros:\n\n- `span.from_expansion()`: detects if a span is from macro expansion or\n  desugaring. Checking this is a common first step in a lint.\n\n   ```rust,ignore\n   if expr.span.from_expansion() {\n       // just forget it\n       return;\n   }\n   ```\n\n- `span.ctxt()`: the span's context represents whether it is from expansion, and\n  if so, which macro call expanded it. It is sometimes useful to check if the\n  context of two spans are equal.\n\n  ```rust,ignore\n  // expands to `1 + 0`, but don't lint\n  1 + mac!()\n  ```\n  ```rust,ignore\n  if left.span.ctxt() != right.span.ctxt() {\n      // the coder most likely cannot modify this expression\n      return;\n  }\n  ```\n  > Note: Code that is not from expansion is in the \"root\" context. So any spans\n  > where `from_expansion` returns `true` can be assumed to have the same\n  > context. And so just using `span.from_expansion()` is often good enough.\n\n\n- `span.in_external_macro(sm)`: detect if the given span is from a macro defined in\n  a foreign crate. If you want the lint to work with macro-generated code, this\n  is the next line of defense to avoid macros not defined in the current crate.\n  It doesn't make sense to lint code that the coder can't change.\n\n  You may want to use it for example to not start linting in macros from other\n  crates\n\n  ```rust\n  use a_crate_with_macros::foo;\n\n  // `foo` is defined in `a_crate_with_macros`\n  foo!(\"bar\");\n\n  // if we lint the `match` of `foo` call and test its span\n  assert_eq!(match_span.in_external_macro(cx.sess().source_map()), true);\n  ```\n\n- `span.ctxt()`: the span's context represents whether it is from expansion, and\n  if so, what expanded it\n\n  One thing `SpanContext` is useful for is to check if two spans are in the same\n  context. For example, in `a == b`, `a` and `b` have the same context. In a\n  `macro_rules!` with `a == $b`, `$b` is expanded to some expression with a\n  different context from `a`.\n\n   ```rust,ignore\n   macro_rules! m {\n       ($a:expr, $b:expr) => {\n           if $a.is_some() {\n               $b;\n           }\n       }\n   }\n\n   let x: Option<u32> = Some(42);\n   m!(x, x.unwrap());\n\n   // These spans are not from the same context\n   // x.is_some() is from inside the macro\n   // x.unwrap() is from outside the macro\n   assert_eq!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());\n   ```\n\n[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html\n[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html\n[TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html\n[expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty\n[LateContext]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LateContext.html\n[TyCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html\n[pat_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.pat_ty\n[paths]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/paths/index.html\n"
  },
  {
    "path": "book/src/development/defining_lints.md",
    "content": "# Define New Lints\n\nThe first step in the journey of a new lint is the definition\nand registration of the lint in Clippy's codebase.\nWe can use the Clippy dev tools to handle this step since setting up the\nlint involves some boilerplate code.\n\n#### Lint types\n\nA lint type is the category of items and expressions in which your lint focuses on.\n\nAs of the writing of this documentation update, there are 11 _types_ of lints\nbesides the numerous standalone lints living under `clippy_lints/src/`:\n\n- `cargo`\n- `casts`\n- `functions`\n- `loops`\n- `matches`\n- `methods`\n- `misc_early`\n- `operators`\n- `transmute`\n- `types`\n- `unit_types`\n\nThese types group together lints that share some common behaviors. For instance,\n`functions` groups together lints that deal with some aspects of functions in\nRust, like definitions, signatures and attributes.\n\nFor more information, feel free to compare the lint files under any category\nwith [All Clippy lints][all_lints] or ask one of the maintainers.\n\n## Lint name\n\nA good lint name is important, make sure to check the [lint naming\nguidelines][lint_naming]. Don't worry, if the lint name doesn't fit, a Clippy\nteam member will alert you in the PR process.\n\n---\n\nWe'll name our example lint that detects functions named \"foo\" `foo_functions`.\nCheck the [lint naming guidelines][lint_naming] to see why this name makes\nsense.\n\n## Add and Register the Lint\n\nNow that a name is chosen, we shall register `foo_functions` as a lint to the\ncodebase. There are two ways to register a lint.\n\n### Standalone\n\nIf you believe that this new lint is a standalone lint (that doesn't belong to\nany specific [type](#lint-types) like `functions` or `loops`), you can run the\nfollowing command in your Clippy project:\n\n```sh\n$ cargo dev new_lint --name=lint_name --pass=late --category=pedantic\n```\n\nThere are two things to note here:\n\n1. `--pass`: We set `--pass=late` in this command to do a late lint pass. The\n   alternative is an `early` lint pass. We will discuss this difference in the\n   [Lint Passes] chapter.\n2. `--category`: If not provided, the `category` of this new lint will default\n   to `nursery`.\n\nThe `cargo dev new_lint` command will create a new file:\n`clippy_lints/src/foo_functions.rs` as well as [register the\nlint](#lint-registration).\n\nOverall, you should notice that the following files are modified or created:\n\n```sh\n$ git status\nOn branch foo_functions\nChanges not staged for commit:\n  (use \"git add <file>...\" to update what will be committed)\n  (use \"git restore <file>...\" to discard changes in working directory)\n\tmodified:   CHANGELOG.md\n\tmodified:   clippy_lints/src/lib.register_lints.rs\n\tmodified:   clippy_lints/src/lib.register_pedantic.rs\n\tmodified:   clippy_lints/src/lib.rs\n\nUntracked files:\n  (use \"git add <file>...\" to include in what will be committed)\n\tclippy_lints/src/foo_functions.rs\n\ttests/ui/foo_functions.rs\n```\n\n\n### Specific Type\n\n> **Note**: Lint types are listed in the [\"Lint types\"](#lint-types) section\n\nIf you believe that this new lint belongs to a specific type of lints,\nyou can run `cargo dev new_lint` with a `--type` option.\n\nSince our `foo_functions` lint is related to function calls, one could\nargue that we should put it into a group of lints that detect some behaviors\nof functions, we can put it in the `functions` group.\n\nLet's run the following command in your Clippy project:\n\n```sh\n$ cargo dev new_lint --name=foo_functions --type=functions --category=pedantic\n```\n\nThis command will create, among other things, a new file:\n`clippy_lints/src/{type}/foo_functions.rs`.\nIn our case, the path will be `clippy_lints/src/functions/foo_functions.rs`.\n\nNotice how this command has a `--type` flag instead of `--pass`. Unlike a standalone\ndefinition, this lint won't be registered in the traditional sense. Instead, you will\ncall your lint from within the type's lint pass, found in `clippy_lints/src/{type}/mod.rs`.\n\nA _type_ is just the name of a directory in `clippy_lints/src`, like `functions` in\nthe example command. Clippy groups together some lints that share common behaviors,\nso if your lint falls into one, it would be best to add it to that type.\n\nOverall, you should notice that the following files are modified or created:\n\n```sh\n$ git status\nOn branch foo_functions\nChanges not staged for commit:\n  (use \"git add <file>...\" to update what will be committed)\n  (use \"git restore <file>...\" to discard changes in working directory)\n\tmodified:   CHANGELOG.md\n\tmodified:   clippy_lints/src/declared_lints.rs\n\tmodified:   clippy_lints/src/functions/mod.rs\n\nUntracked files:\n  (use \"git add <file>...\" to include in what will be committed)\n\tclippy_lints/src/functions/foo_functions.rs\n\ttests/ui/foo_functions.rs\n```\n\n\n## The `declare_clippy_lint` macro\n\nAfter `cargo dev new_lint`, you should see a macro with the name\n`declare_clippy_lint`. It will be in the same file if you defined a standalone\nlint, and it will be in `mod.rs` if you defined a type-specific lint.\n\nThe macro looks something like this:\n\n```rust\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// // Describe here what does the lint do.\n    ///\n    /// Triggers when detects...\n    ///\n    /// ### Why is this bad?\n    ///\n    /// // Describe why this pattern would be bad\n    ///\n    /// It can lead to...\n    ///\n    /// ### Example\n    /// ```rust\n    /// // example code where Clippy issues a warning\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// // example code which does not raise Clippy warning\n    /// ```\n    #[clippy::version = \"1.70.0\"] // <- In which version was this implemented, keep it up to date!\n    pub LINT_NAME, // <- The lint name IN_ALL_CAPS\n    pedantic, // <- The lint group\n    \"default lint description\" // <- A lint description, e.g. \"A function has an unit return type.\"\n}\n```\n\n## Lint registration\n\nIf we run the `cargo dev new_lint` command for a new lint, the lint will be\nautomatically registered and there is nothing more to do.\n\nHowever, sometimes we might want to declare a new lint by hand. In this case,\nwe'd use `cargo dev update_lints` command afterwards.\n\nWhen a lint is manually declared, we might need to register the lint pass\nmanually in the `register_lints` function in `clippy_lints/src/lib.rs`:\n\n```rust\nstore.register_late_pass(|_| Box::new(foo_functions::FooFunctions));\n```\n\nAs you might have guessed, where there's something late, there is something\nearly: in Clippy there is a `register_early_pass` method as well. More on early\nvs. late passes in the [Lint Passes] chapter.\n\nWithout a call to one of `register_early_pass` or `register_late_pass`, the lint\npass in question will not be run.\n\n\n[all_lints]: https://rust-lang.github.io/rust-clippy/master/\n[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints\n[Lint Passes]: lint_passes.md\n"
  },
  {
    "path": "book/src/development/emitting_lints.md",
    "content": "# Emitting a lint\n\nOnce we have [defined a lint](defining_lints.md), written [UI\ntests](writing_tests.md) and chosen [the lint pass](lint_passes.md) for the lint,\nwe can begin the implementation of the lint logic so that we can emit it and\ngradually work towards a lint that behaves as expected.\n\nNote that we will not go into concrete implementation of a lint logic in this\nchapter. We will go into details in later chapters as well as in two examples of\nreal Clippy lints.\n\nTo emit a lint, we must implement a pass (see [Lint Passes](lint_passes.md)) for\nthe lint that we have declared. In this example we'll implement a \"late\" lint,\nso take a look at the [LateLintPass][late_lint_pass] documentation, which\nprovides an abundance of methods that we can implement for our lint.\n\n```rust\npub trait LateLintPass<'tcx>: LintPass {\n    // Trait methods\n}\n```\n\nBy far the most common method used for Clippy lints is [`check_expr`\nmethod][late_check_expr], this is because Rust is an expression language and,\nmore often than not, the lint we want to work on must examine expressions.\n\n> _Note:_ If you don't fully understand what expressions are in Rust, take a\n> look at the official documentation on [expressions][rust_expressions]\n\nOther common ones include the [`check_fn` method][late_check_fn] and the\n[`check_item` method][late_check_item].\n\n### Emitting a lint\n\nInside the trait method that we implement, we can write down the lint logic and\nemit the lint with suggestions.\n\nClippy's [diagnostics] provides quite a few diagnostic functions that we can use\nto emit lints. Take a look at the documentation to pick one that suits your\nlint's needs the best. Some common ones you will encounter in the Clippy\nrepository includes:\n\n- [`span_lint`]: Emits a lint without providing any other information\n- [`span_lint_and_note`]: Emits a lint and adds a note\n- [`span_lint_and_help`]: Emits a lint and provides a helpful message\n- [`span_lint_and_sugg`]: Emits a lint and provides a suggestion to fix the code\n- [`span_lint_and_then`]: Like `span_lint`, but allows for a lot of output\n  customization.\n\n```rust\nimpl<'tcx> LateLintPass<'tcx> for LintName {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>)  {\n        // Imagine that `some_lint_expr_logic` checks for requirements for emitting the lint\n        if some_lint_expr_logic(expr) {\n            span_lint_and_help(\n                cx, // < The context\n                LINT_NAME, // < The name of the lint in ALL CAPS\n                expr.span, // < The span to lint\n                \"message on why the lint is emitted\",\n                None, // < An optional help span (to highlight something in the lint)\n                \"message that provides a helpful suggestion\",\n            );\n        }\n    }\n}\n```\n\n> Note: The message should be matter of fact and avoid capitalization and\n> punctuation. If multiple sentences are needed, the messages should probably be\n> split up into an error + a help / note / suggestion message.\n\n## Suggestions: Automatic fixes\n\nSome lints know what to change in order to fix the code. For example, the lint\n[`range_plus_one`][range_plus_one] warns for ranges where the user wrote `x..y +\n1` instead of using an [inclusive range][inclusive_range] (`x..=y`). The fix to\nthis code would be changing the `x..y + 1` expression to `x..=y`. **This is\nwhere suggestions come in**.\n\nA suggestion is a change that the lint provides to fix the issue it is linting.\nThe output looks something like this (from the example earlier):\n\n```text\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:37:14\n   |\nLL |     for _ in 1..1 + 1 {}\n   |              ^^^^^^^^ help: use: `1..=1`\n```\n\n**Not all suggestions are always right**, some of them require human\nsupervision, that's why we have [Applicability][applicability].\n\nApplicability indicates confidence in the correctness of the suggestion, some\nare always right (`Applicability::MachineApplicable`), but we use\n`Applicability::MaybeIncorrect` and others when talking about a suggestion that\nmay be incorrect.\n\n### Example\n\nThe same lint `LINT_NAME` but that emits a suggestion would look something like this:\n\n```rust\nimpl<'tcx> LateLintPass<'tcx> for LintName {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>)  {\n        // Imagine that `some_lint_expr_logic` checks for requirements for emitting the lint\n        if some_lint_expr_logic(expr) {\n            span_lint_and_sugg( // < Note this change\n                cx,\n                LINT_NAME,\n                span,\n                \"message on why the lint is emitted\",\n                \"use\",\n                format!(\"foo + {} * bar\", snippet(cx, expr.span, \"<default>\")), // < Suggestion\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n```\n\nSuggestions generally use the [`format!`][format_macro] macro to interpolate the\nold values with the new ones. To get code snippets, use one of the `snippet*`\nfunctions from `clippy_utils::source`.\n\n## How to choose between notes, help messages and suggestions\n\nNotes are presented separately from the main lint message, they provide useful\ninformation that the user needs to understand why the lint was activated. They\nare the most helpful when attached to a span.\n\nExamples:\n\n### Notes\n\n```text\nerror: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing.\n  --> tests/ui/drop_forget_ref.rs:10:5\n   |\n10 |     forget(&SomeStruct);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::forget-ref` implied by `-D warnings`\nnote: argument has type &SomeStruct\n  --> tests/ui/drop_forget_ref.rs:10:12\n   |\n10 |     forget(&SomeStruct);\n   |            ^^^^^^^^^^^\n```\n\n### Help Messages\n\nHelp messages are specifically to help the user. These are used in situation\nwhere you can't provide a specific machine applicable suggestion. They can also\nbe attached to a span.\n\nExample:\n\n```text\nerror: constant division of 0.0 with 0.0 will always result in NaN\n  --> tests/ui/zero_div_zero.rs:6:25\n   |\n6  |     let other_f64_nan = 0.0f64 / 0.0;\n   |                         ^^^^^^^^^^^^\n   |\n   = help: consider using `f64::NAN` if you would like a constant representing NaN\n```\n\n### Suggestions\n\nSuggestions are the most helpful, they are changes to the source code to fix the\nerror. The magic in suggestions is that tools like `rustfix` can detect them and\nautomatically fix your code.\n\nExample:\n\n```text\nerror: This `.fold` can be more succinctly expressed as `.any`\n--> tests/ui/methods.rs:390:13\n    |\n390 |     let _ = (0..3).fold(false, |acc, x| acc || x > 2);\n    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.any(|x| x > 2)`\n    |\n```\n\n### Snippets\n\nSnippets are pieces of the source code (as a string), they are extracted\ngenerally using the [`snippet`][snippet_fn] function.\n\nFor example, if you want to know how an item looks (and you know the item's\nspan), you could use `snippet(cx, span, \"..\")`.\n\n## Final: Run UI Tests to Emit the Lint\n\nNow, if we run our [UI test](writing_tests.md), we should see that Clippy now\nproduces output that contains the lint message we designed.\n\nThe next step is to implement the logic properly, which is a detail that we will\ncover in the next chapters.\n\n[diagnostics]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/index.html\n[late_check_expr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_expr\n[late_check_fn]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_fn\n[late_check_item]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_item\n[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html\n[rust_expressions]: https://doc.rust-lang.org/reference/expressions.html\n[`span_lint`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint.html\n[`span_lint_and_note`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_note.html\n[`span_lint_and_help`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_help.html\n[`span_lint_and_sugg`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html\n[`span_lint_and_then`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_then.html\n[range_plus_one]: https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one\n[inclusive_range]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html\n[applicability]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_errors/enum.Applicability.html\n[snippet_fn]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/source/fn.snippet.html\n[format_macro]: https://doc.rust-lang.org/std/macro.format.html\n"
  },
  {
    "path": "book/src/development/infrastructure/README.md",
    "content": "# Infrastructure\n\nIn order to deploy Clippy over `rustup`, some infrastructure is necessary. This\nchapter describes the different parts of the Clippy infrastructure that need to\nbe maintained to make this possible.\n\nThe most important part is the sync between the `rust-lang/rust` repository and\nthe Clippy repository that takes place every two weeks. This process is\ndescribed in the [Syncing changes between Clippy and `rust-lang/rust`](sync.md)\nsection.\n\nA new Clippy release is done together with every Rust release, so every six\nweeks. The release process is described in the [Release a new Clippy\nVersion](release.md) section. During a release cycle a changelog entry for the\nnext release has to be written. The format of that and how to do that is\ndocumented in the [Changelog Update](changelog_update.md) section.\n\n> _Note:_ The Clippy CI should also be described in this chapter, but for now is\n> left as a TODO.\n"
  },
  {
    "path": "book/src/development/infrastructure/backport.md",
    "content": "# Backport Changes\n\nSometimes it is necessary to backport changes to the beta release of Clippy.\nBackports in Clippy are rare and should be approved by the Clippy team. For\nexample, a backport is done, if a crucial ICE was fixed or a lint is broken to a\npoint, that it has to be disabled, before landing on stable.\n\n> Note: If you think a PR should be backported you can label it with\n> `beta-nominated`. This has to be done before the Thursday the week before the\n> release.\n\n## Filtering PRs to backport\n\nFirst, find all labeled PRs using [this filter][beta-accepted-prs].\n\nNext, look at each PR individually. There are a few things to check. Those need\nsome explanation and are quite subjective. Good judgement is required.\n\n1. **Is the fix worth a backport?**\n\n   This is really subjective. An ICE fix usually is. Moving a lint to a _lower_\n   group (from warn- to allow-by-default) usually as well. An FP fix usually not\n   (on its own). If a backport is done anyway, FP fixes might also be included.\n   If the PR has a lot of changes, backports must be considered more carefully.\n\n2. **Is the problem that was fixed by the PR already in `beta`?**\n\n   It could be that the problem that was fixed by the PR hasn't made it to the\n   `beta` branch of the Rust repo yet. If that's the case, and the fix is\n   already synced to the Rust repo, the fix doesn't need to be backported, as it\n   will hit stable together with the commit that introduced the problem. If the\n   fix PR is not synced yet, the fix PR either needs to be \"backported\" to the\n   Rust `master` branch or to `beta` in the next backport cycle.\n\n3. **Make sure that the fix is on `master` before porting to `beta`**\n\n   The fix must already be synced to the Rust `master` branch. Otherwise, the\n   next `beta` will be missing this fix again. If it is not yet in `master` it\n   should probably not be backported. If the backport is really important, do an\n   out-of-cycle sync first. However, the out-of-cycle sync should be small,\n   because the changes in that sync will get right into `beta`, without being\n   tested in `nightly` first.\n\n[beta-accepted-prs]: https://github.com/rust-lang/rust-clippy/issues?q=label%3Abeta-nominated\n\n## Preparation\n\n> Note: All commands in this chapter will be run in the Rust clone.\n\nFollow the instructions in [defining remotes] to define the `clippy-upstream`\nremote in the Rust repository.\n\nAfter that, fetch the remote with\n\n```bash\ngit fetch clippy-upstream master\n```\n\nThen, switch to the `beta` branch:\n\n```bash\ngit switch beta\ngit fetch upstream\ngit reset --hard upstream/beta\n```\n\n[defining remotes]: release.md#defining-remotes\n\n## Backport the changes\n\nWhen a PR is merged with the GitHub merge queue, the PR is closed with the message\n\n> \\<PR title\\> (#\\<PR number\\>)\n\nThis commit needs to be backported. To do that, find the `<sha1>` of that commit\nand run the following command in the clone of the **Rust repository**:\n\n```bash\ngit cherry-pick -m 1 `<sha1>`\n```\n\nDo this for all PRs that should be backported.\n\n## Open PR in the Rust repository\n\nNext, open the PR for the backport. Make sure, the PR is opened towards the\n`beta` branch and not the `master` branch. The PR description should look like\nthis:\n\n```\n[beta] Clippy backports\n\nr? @Mark-Simulacrum\n\nBackports:\n- <Link to the Clippy PR>\n- ...\n\n<Short summary of what is backported and why>\n```\n\nMark is from the release team and they ultimately have to merge the PR before\nbranching a new `beta` version. Tag them to take care of the backport. Next,\nlist all the backports and give a short summary what's backported and why it is\nworth backporting this.\n\n## Relabel backported PRs\n\nWhen a PR is backported to Rust `beta`, label the PR with `beta-accepted`. This\nwill then get picked up when [writing the changelog].\n\n[writing the changelog]: changelog_update.md#4-include-beta-accepted-prs\n"
  },
  {
    "path": "book/src/development/infrastructure/benchmarking.md",
    "content": "# Benchmarking Clippy\n\nBenchmarking Clippy is similar to using our Lintcheck tool, in fact, it even\nuses the same tool! Just by adding a `--perf` flag it will transform Lintcheck\ninto a very simple but powerful benchmarking tool!\n\nIt requires having the [`perf` tool][perf] installed, as `perf` is what's actually\nprofiling Clippy under the hood.\n\nThe lintcheck `--perf` tool generates a series of `perf.data` in the\n`target/lintcheck/sources/<package>-<version>` directories. Each `perf.data`\ncorresponds to the package which is contained.\n\nLintcheck uses the `-g` flag, meaning that you can get stack traces for richer\nanalysis, including with tools such as [flamegraph][flamegraph-perf]\n(or [`flamegraph-rs`][flamegraph-rs]).\n\nCurrently, we only measure instruction count, as it's the most reproducible metric\nand [rustc-perf][rustc-perf] also considers it the main number to focus on.\n\n## Benchmarking a PR\n\nHaving a benchmarking tool directly implemented into lintcheck gives us the\nability to benchmark any given PR just by making a before and after \n\nHere's the way you can get into any PR, benchmark it, and then benchmark\n`master`.\n\nThe first `perf.data` will not have any numbers appended, but any subsequent\nbenchmark will be written to `perf.data.number` with a number growing for 0.\nAll benchmarks are compressed so that you can\n\n```bash\ngit fetch upstream pull/<PR_NUMBER>/head:<BRANCH_NAME>\ngit switch BRANCHNAME\n\n# Bench\ncargo lintcheck --perf\n\n# Get last common commit, checkout that\nLAST_COMMIT=$(git log BRANCHNAME..master --oneline | tail -1 | cut -c 1-11)\ngit switch -c temporary $LAST_COMMIT\n\n# We're now on master\n\n# Bench\ncargo lintcheck --perf\nperf diff ./target/lintcheck/sources/CRATE/perf.data ./target/lintcheck/sources/CRATE/perf.data.0\n```\n\n\n[perf]: https://perfwiki.github.io/main/\n[flamegraph-perf]: https://github.com/brendangregg/FlameGraph\n[flamegraph-rs]: https://github.com/flamegraph-rs/flamegraph\n[rustc-perf]: https://github.com/rust-lang/rustc-perf\n"
  },
  {
    "path": "book/src/development/infrastructure/book.md",
    "content": "# The Clippy Book\n\nThis document explains how to make additions and changes to the Clippy book, the\nguide to Clippy that you're reading right now. The Clippy book is formatted with\n[Markdown](https://www.markdownguide.org) and generated by\n[mdBook](https://github.com/rust-lang/mdBook).\n\n- [Get mdBook](#get-mdbook)\n- [Make changes](#make-changes)\n\n## Get mdBook\n\nWhile not strictly necessary since the book source is simply Markdown text\nfiles, having mdBook locally will allow you to build, test and serve the book\nlocally to view changes before you commit them to the repository. You likely\nalready have `cargo` installed, so the easiest option is to:\n\n```shell\ncargo install mdbook\n```\n\nSee the mdBook [installation](https://github.com/rust-lang/mdBook#installation)\ninstructions for other options.\n\n## Make changes\n\nThe book's\n[src](https://github.com/rust-lang/rust-clippy/tree/master/book/src)\ndirectory contains all the markdown files used to generate the book. If you\nwant to see your changes in real time, you can use the mdBook `serve` command to\nrun a web server locally that will automatically update changes as they are\nmade. From the top level of your `rust-clippy` directory:\n\n```shell\nmdbook serve book --open\n```\n\nThen navigate to `http://localhost:3000` to see the generated book. While the\nserver is running, changes you make will automatically be updated.\n\nFor more information, see the mdBook\n[guide](https://rust-lang.github.io/mdBook/).\n"
  },
  {
    "path": "book/src/development/infrastructure/changelog_update.md",
    "content": "# Changelog Update\n\nIf you want to help with updating the [changelog], you're in the right place.\n\n## When to update\n\nTypos and other small fixes/additions are _always_ welcome.\n\nSpecial care needs to be taken when it comes to updating the changelog for a new\nRust release. For that purpose, the changelog is ideally updated during the week\nbefore an upcoming stable release. You can find the release dates on the [Rust\nForge][forge].\n\nMost of the time we only need to update the changelog for minor Rust releases.\nIt's been very rare that Clippy changes were included in a patch release.\n\n## Changelog update walkthrough\n\n### 1. Finding the relevant Clippy commits\n\nEach Rust release ships with its own version of Clippy. The Clippy subtree can\nbe found in the `tools` directory of the Rust repository.\n\nDepending on the current time and what exactly you want to update, the following\nbullet points might be helpful:\n\n* When writing the release notes for the **upcoming stable release** you need to\n  check out the Clippy commit of the current Rust `beta` branch.\n  [Link][rust_beta_tools]\n* When writing the release notes for the **upcoming beta release**, you need to\n  check out the Clippy commit of the current Rust `main`.\n  [Link][rust_main_tools]\n* When writing the (forgotten) release notes for a **past stable release**, you\n  need to check out the Rust release tag of the stable release.\n  [Link][rust_stable_tools]\n\nUsually you want to write the changelog of the **upcoming stable release**. Make\nsure though, that `beta` was already branched in the Rust repository.\n\nTo find the commit hash, issue the following command when in a `rust-lang/rust`\ncheckout (most of the time on the `upstream/beta` branch):\n```\ngit log --oneline -- src/tools/clippy/ | grep -o \"Merge commit '[a-f0-9]*' into .*\" | head -1 | sed -e \"s/Merge commit '\\([a-f0-9]*\\)' into .*/\\1/g\"\n```\n\n### 2. Fetching the PRs between those commits\n\nOnce you've got the correct commit range, run\n\n```\nutil/fetch_prs_between.sh start_commit end_commit > changes.txt\n```\n\nwhere `end_commit` is the commit hash from the previous command and `start_commit`\nis [the commit hash][beta_section] from the current CHANGELOG file.\nOpen `changes.txt` file in your editor of choice.\n\n### 3. Authoring the final changelog\n\nThe above script should have dumped all the relevant PRs to the file you\nspecified. It should have filtered out most of the irrelevant PRs already, but\nit's a good idea to do a manual cleanup pass and choose valuable PRs.\nIf you're not sure about some PRs, just leave them in for the review and\nask for feedback.\n\nWith the PRs filtered, you can start to take each PR and move the `changelog: `\ncontent to `CHANGELOG.md`. Adapt the wording as you see fit but try to keep it\nsomewhat coherent.\n\nThe sections order should roughly be:\n\n```\n### New Lints\n* Added [`LINT`] to `GROUP`\n\n### Moves and Deprecations\n* Moved [`LINT`] to `GROUP` (From `GROUP`, now LEVEL-by-default)\n* Renamed `LINT` to [`LINT`]\n\n### Enhancements\n### False Positive Fixes\n### ICE Fixes\n### Documentation Improvements\n### Others\n```\n\nPlease also be sure to update [the `Unreleased/Beta/In Rust Nightly` section][beta_section] at the top with the\nrelevant commits ranges and to add the `Rust <version>` section with release date and PR ranges.\n\n### 4. Include `beta-accepted` PRs\n\nLook for the [`beta-accepted`] label and make sure to also include the PRs with\nthat label in the changelog. If you can, remove the `beta-accepted` labels\n**after** the changelog PR was merged.\n\n> _Note:_ Some of those PRs might even get backported to the previous `beta`.\n> Those have to be included in the changelog of the _previous_ release.\n\n### 5. Update `clippy::version` attributes\n\nNext, make sure to check that the `#[clippy::version]` attributes for the added\nlints contain the correct version. \nIn order to find lints that need a version update, go through the lints in the \n\"New Lints\" section and run the following command for each lint name:\n\n```\ngrep -rB1 \"pub $LINT_NAME\" .\n```\n\nThe version shown should match the version of the release the changelog is \nwritten for. If not, update the version to the changelog version.\n\n[changelog]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md\n[forge]: https://forge.rust-lang.org/\n[rust_main_tools]: https://github.com/rust-lang/rust/tree/HEAD/src/tools/clippy\n[rust_beta_tools]: https://github.com/rust-lang/rust/tree/beta/src/tools/clippy\n[rust_stable_tools]: https://github.com/rust-lang/rust/releases\n[`beta-accepted`]: https://github.com/rust-lang/rust-clippy/issues?q=label%3Abeta-accepted+\n[beta_section]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#unreleased--beta--in-rust-nightly\n"
  },
  {
    "path": "book/src/development/infrastructure/release.md",
    "content": "# Release a new Clippy Version\n\n> _NOTE:_ This document is probably only relevant to you, if you're a member of\n> the Clippy team.\n\nClippy is released together with stable Rust releases. The dates for these\nreleases can be found at the [Rust Forge]. This document explains the necessary\nsteps to create a Clippy release.\n\n1. [Defining Remotes](#defining-remotes)\n1. [Bump Version](#bump-version)\n1. [Find the Clippy commit](#find-the-clippy-commit)\n1. [Update the `beta` branch](#update-the-beta-branch)\n1. [Update the `stable` branch](#update-the-stable-branch)\n1. [Tag the stable commit](#tag-the-stable-commit)\n1. [Update `CHANGELOG.md`](#update-changelogmd)\n\n[Rust Forge]: https://forge.rust-lang.org/\n\n## Defining Remotes\n\nYou may want to define the `upstream` remote of the Clippy project to simplify\nthe following steps. However, this is optional and you can replace `upstream`\nwith the full URL instead.\n\n```bash\ngit remote add upstream git@github.com:rust-lang/rust-clippy\n```\n\n## Bump Version\n\nWhen a release needs to be done, `cargo test` will fail, if the versions in the\n`Cargo.toml` are not correct. During that sync, the versions need to be bumped.\nThis is done by running:\n\n```bash\ncargo dev release bump_version\n```\n\nThis will increase the version number of each relevant `Cargo.toml` file. After\nthat, just commit the updated files with:\n\n```bash\ngit commit -m \"Bump Clippy version -> 0.1.XY\" **/*Cargo.toml\n```\n\n`XY` should be exchanged with the corresponding version\n\n## Find the Clippy commit\n\nFor both updating the `beta` and the `stable` branch, the first step is to find\nthe Clippy commit of the last Clippy sync done in the respective Rust branch.\n\nRunning the following commands _in the Rust repo_ will get the commit for the\nspecified `<branch>`:\n\n```bash\ngit switch <branch>\nSHA=$(git log --oneline -- src/tools/clippy/ | grep -o \"Merge commit '[a-f0-9]*' into .*\" | head -1 | sed -e \"s/Merge commit '\\([a-f0-9]*\\)' into .*/\\1/g\")\n```\n\nWhere `<branch>` is one of `stable`, `beta`, or `master`.\n\n## Update the `beta` branch\n\nAfter getting the commit of the `beta` branch, the `beta` branch in the Clippy\nrepository can be updated.\n\n```bash\ngit checkout beta\ngit reset --hard $SHA\ngit push upstream beta\n```\n\n## Update the `stable` branch\n\nAfter getting the commit of the `stable` branch, the `stable` branch in the\nClippy repository can be updated.\n\n```bash\ngit checkout stable\ngit reset --hard $SHA\ngit push upstream stable\n```\n\n## Tag the `stable` commit\n\nAfter updating the `stable` branch, tag the HEAD commit and push it to the\nClippy repo.\n\n```bash\ngit tag rust-1.XX.0               # XX should be exchanged with the corresponding version\ngit push upstream rust-1.XX.0     # `upstream` is the `rust-lang/rust-clippy` remote\n```\n\nAfter this, the release should be available on the Clippy [tags page].\n\n[tags page]: https://github.com/rust-lang/rust-clippy/tags\n\n## Publish `clippy_utils`\n\nThe `clippy_utils` crate is published to `crates.io` without any stability\nguarantees. To do this, after the [sync] and the release is done, switch back to\nthe `upstream/master` branch and publish `clippy_utils`:\n\n> Note: The Rustup PR bumping the nightly and Clippy version **must** be merged\n> before doing this.\n\n```bash\ngit switch master && git pull upstream master\ncargo publish --manifest-path clippy_utils/Cargo.toml\n```\n\n[sync]: sync.md\n\n## Update `CHANGELOG.md`\n\nFor this see the document on [how to update the changelog].\n\nIf you don't have time to do a complete changelog update right away, just update\nthe following parts:\n\n- Remove the `(beta)` from the new stable version:\n\n  ```markdown\n  ## Rust 1.XX (beta) -> ## Rust 1.XX\n  ```\n\n- Update the release date line of the new stable version:\n\n  ```markdown\n  Current beta, release 20YY-MM-DD -> Current stable, released 20YY-MM-DD\n  ```\n\n- Update the release date line of the previous stable version:\n\n  ```markdown\n  Current stable, released 20YY-MM-DD -> Released 20YY-MM-DD\n  ```\n\n[how to update the changelog]: changelog_update.md\n"
  },
  {
    "path": "book/src/development/infrastructure/sync.md",
    "content": "# Syncing changes between Clippy and [`rust-lang/rust`]\n\nClippy currently gets built with a pinned nightly version.\n\nIn the `rust-lang/rust` repository, where rustc resides, there's a copy of\nClippy that compiler hackers modify from time to time to adapt to changes in the\nunstable API of the compiler.\n\nWe need to sync these changes back to this repository periodically, and the\nchanges made to this repository in the meantime also need to be synced to the\n`rust-lang/rust` repository.\n\nTo avoid flooding the `rust-lang/rust` PR queue, this two-way sync process is\ndone in a bi-weekly basis if there's no urgent changes. This is done starting on\nthe day of the Rust stable release and then every other week. That way we\nguarantee that we keep this repo up to date with the latest compiler API, and\nevery feature in Clippy is available for 2 weeks in nightly, before it can get\nto beta. For reference, the first sync following this cadence was performed the\n2020-08-27.\n\nThis process is described in detail in the following sections. For general\ninformation about `subtree`s in the Rust repository see [the rustc-dev-guide][subtree].\n\n[subtree]: https://rustc-dev-guide.rust-lang.org/external-repos.html#external-dependencies-subtree\n\n## Patching git-subtree to work with big repos\n\nCurrently, there's a bug in `git-subtree` that prevents it from working properly\nwith the [`rust-lang/rust`] repo. There's an open PR to fix that, but it's\nstale. Before continuing with the following steps, we need to manually apply\nthat fix to our local copy of `git-subtree`.\n\nYou can get the patched version of `git-subtree` from [here][gitgitgadget-pr].\nPut this file under `/usr/lib/git-core` (making a backup of the previous file)\nand make sure it has the proper permissions:\n\n```bash\nsudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree\nsudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree\nsudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree\n```\n\n> _Note:_ The first time running `git subtree push` a cache has to be built.\n> This involves going through the complete Clippy history once. For this you\n> have to increase the stack limit though, which you can do with `ulimit -s\n> 60000`. Make sure to run the `ulimit` command from the same session you call\n> git subtree.\n\n> _Note:_ If you are a Debian user, `dash` is the shell used by default for\n> scripts instead of `sh`. This shell has a hardcoded recursion limit set to\n> 1,000. In order to make this process work, you need to force the script to run\n> `bash` instead. You can do this by editing the first line of the `git-subtree`\n> script and changing `sh` to `bash`.\n\n> Note: The following sections assume that you have set up remotes following the\n> instructions in [defining remotes].\n\n[gitgitgadget-pr]: https://github.com/gitgitgadget/git/pull/493\n[defining remotes]: release.md#defining-remotes\n\n## Performing the sync from [`rust-lang/rust`] to Clippy\n\nHere is a TL;DR version of the sync process (all the following commands have\nto be run inside the `rust` directory):\n\n1. Clone the [`rust-lang/rust`] repository or make sure it is up-to-date.\n2. Checkout the commit from the latest available nightly. You can get it using\n   `rustup check`.\n3. Sync the changes to the rust-copy of Clippy to your Clippy fork:\n    ```bash\n    # Be sure to either use a net-new branch, e.g. `rustup`, or delete the branch beforehand\n    # because changes cannot be fast forwarded and you have to run this command again.\n    git subtree push -P src/tools/clippy clippy-local rustup\n    ```\n\n    > _Note:_ Most of the time you have to create a merge commit in the\n    > `rust-clippy` repo (this has to be done in the Clippy repo, not in the\n    > rust-copy of Clippy):\n    ```bash\n    git fetch upstream  # assuming upstream is the rust-lang/rust remote\n    git switch rustup\n    git merge upstream/main --no-ff\n    ```\n    > Note: This is one of the few instances where a merge commit is allowed in\n    > a PR.\n4. Bump the nightly version in the Clippy repository by running these commands:\n   ```bash\n   cargo dev sync update_nightly\n   git commit -m \"Bump nightly version -> YYYY-MM-DD\" rust-toolchain.toml clippy_utils/README.md\n   ```\n5. Open a PR to `rust-lang/rust-clippy` and wait for it to get merged (to\n   accelerate the process ping the `@rust-lang/clippy` team in your PR and/or\n   ask them in the [Zulip] stream.)\n\n[Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/clippy\n[`rust-lang/rust`]: https://github.com/rust-lang/rust\n\n## Performing the sync from Clippy to [`rust-lang/rust`]\n\nAll the following commands have to be run inside the `rust` directory.\n\n1. Make sure you have checked out the latest `main` of `rust-lang/rust`.\n2. Sync the `rust-lang/rust-clippy` master to the rust-copy of Clippy:\n    ```bash\n    git switch -c clippy-subtree-update\n    git subtree pull -P src/tools/clippy clippy-upstream master\n    ```\n3. Open a PR to [`rust-lang/rust`]\n"
  },
  {
    "path": "book/src/development/lint_passes.md",
    "content": "# Lint passes\n\nBefore working on the logic of a new lint, there is an important decision\nthat every Clippy developer must make: to use\n[`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass].\n\nIn short, the `LateLintPass` has access to type and symbol information while the\n`EarlyLintPass` doesn't. If you don't need access to type information, use the\n`EarlyLintPass`.\n\nLet us expand on these two traits more below.\n\n## `EarlyLintPass`\n\nIf you examine the documentation on [`EarlyLintPass`][early_lint_pass] closely,\nyou'll see that every method defined for this trait utilizes a\n[`EarlyContext`][early_context]. In `EarlyContext`'s documentation, it states:\n\n> Context for lint checking of the AST, after expansion, before lowering to HIR.\n\nVoilà. `EarlyLintPass` works only on the Abstract Syntax Tree (AST) level.\nAnd AST is generated during the [lexing and parsing][lexing_and_parsing] phase\nof code compilation. Therefore, it doesn't know what a symbol means or information about types, and it should\nbe our trait choice for a new lint if the lint only deals with syntax-related issues.\n\nWhile linting speed has not been a concern for Clippy,\nthe `EarlyLintPass` is faster, and it should be your choice\nif you know for sure a lint does not need type information.\n\nAs a reminder, run the following command to generate boilerplate for lints\nthat use `EarlyLintPass`:\n\n```sh\n$ cargo dev new_lint --name=<your_new_lint> --pass=early --category=<your_category_choice>\n```\n\n### Example for `EarlyLintPass`\n\nTake a look at the following code:\n\n```rust\nlet x = OurUndefinedType;\nx.non_existing_method();\n```\n\nFrom the AST perspective, both lines are \"grammatically\" correct.\nThe assignment uses a `let` and ends with a semicolon. The invocation\nof a method looks fine, too. As programmers, we might raise a few\nquestions already, but the parser is okay with it. This is what we\nmean when we say `EarlyLintPass` deals with only syntax on the AST level.\n\nAlternatively, think of the `foo_functions` lint we mentioned in\nthe [Define New Lints](defining_lints.md) chapter.\n\nWe want the `foo_functions` lint to detect functions with `foo` as their name.\nWriting a lint that only checks for the name of a function means that we only\nwork with the AST and don't have to access the type system at all (the type system is where\n`LateLintPass` comes into the picture).\n\n## `LateLintPass`\n\nIn contrast to `EarlyLintPass`, `LateLintPass` contains type information.\n\nIf you examine the documentation on [`LateLintPass`][late_lint_pass] closely,\nyou see that every method defined in this trait utilizes a\n[`LateContext`][late_context].\n\nIn `LateContext`'s documentation we will find methods that\ndeal with type-checking, which do not exist in `EarlyContext`, such as:\n\n- [`maybe_typeck_results`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#method.maybe_typeck_results)\n- [`typeck_results`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html#method.typeck_results)\n\n### Example for `LateLintPass`\n\nLet us take a look with the following example:\n\n```rust\nlet x = OurUndefinedType;\nx.non_existing_method();\n```\n\nThese two lines of code are syntactically correct code from the perspective\nof the AST. We have an assignment and invoke a method on the variable that\nis of a type. Grammatically, everything is in order for the parser.\n\nHowever, going down a level and looking at the type information,\nthe compiler will notice that both `OurUndefinedType` and `non_existing_method()`\n**are undefined**.\n\nAs Clippy developers, to access such type information, we must implement\n`LateLintPass` on our lint.\nWhen you browse through Clippy's lints, you will notice that almost every lint\nis implemented in a `LateLintPass`, specifically because we often need to check\nnot only for syntactic issues but also type information.\n\nAnother limitation of the `EarlyLintPass` is that the nodes are only identified\nby their position in the AST. This means that you can't just get an `id` and\nrequest a certain node. For most lints that is fine, but we have some lints\nthat require the inspection of other nodes, which is easier at the HIR level.\nIn these cases, `LateLintPass` is the better choice.\n\nAs a reminder, run the following command to generate boilerplate for lints\nthat use `LateLintPass`:\n\n```sh\n$ cargo dev new_lint --name=<your_new_lint> --pass=late --category=<your_category_choice>\n```\n\n[early_context]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.EarlyContext.html\n[early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html\n[late_context]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/context/struct.LateContext.html\n[late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html\n[lexing_and_parsing]: https://rustc-dev-guide.rust-lang.org/overview.html#lexing-and-parsing\n"
  },
  {
    "path": "book/src/development/macro_expansions.md",
    "content": "# Dealing with macros and expansions\n\nSometimes we might encounter Rust macro expansions while working with Clippy.\nWhile macro expansions are not as dramatic and profound as the expansion\nof our universe, they can certainly bring chaos to the orderly world\nof code and logic.\n\nThe general rule of thumb is that we should ignore code with macro\nexpansions when working with Clippy because the code can be dynamic\nin ways that are difficult or impossible for us to foresee.\n\n## False Positives\n\nWhat exactly do we mean by _dynamic in ways that are difficult to foresee_?\n\nMacros are [expanded][expansion] in the `EarlyLintPass` level,\nso the Abstract Syntax Tree (AST) is generated in place of macros.\nThis means the code which we work with in Clippy is already expanded.\n\nIf we wrote a new lint, there is a possibility that the lint is\ntriggered in macro-generated code. Since this expanded macro code\nis not written by the macro's user but really by the macro's author,\nthe user cannot and should not be responsible for fixing the issue\nthat triggers the lint.\n\nBesides, a [Span] in a macro can be changed by the macro author.\nTherefore, any lint check related to lines or columns should be\navoided since they might be changed at any time and become unreliable\nor incorrect information.\n\nBecause of these unforeseeable or unstable behaviors, macro expansion\nshould often not be regarded as a part of the stable API.\nThis is also why most lints check if they are inside a macro or not\nbefore emitting suggestions to the end user to avoid false positives.\n\n## How to Work with Macros\n\nSeveral functions are available for working with macros.\n\n### The `Span::from_expansion` method\n\nWe could utilize a `span`'s [`from_expansion`] method, which\ndetects if the `span` is from a macro expansion / desugaring.\nThis is a very common first step in a lint:\n\n```rust\nif expr.span.from_expansion() {\n    // We most likely want to ignore it.\n    return;\n}\n```\n\n### `Span::ctxt` method\n\nThe `span`'s context, given by the method [`ctxt`] and returning [SyntaxContext],\nrepresents if the span is from a macro expansion and, if it is, which\nmacro call expanded this span.\n\nSometimes, it is useful to check if the context of two spans are equal.\nFor instance, suppose we have the following line of code that would\nexpand into `1 + 0`:\n\n```rust\n// The following code expands to `1 + 0` for both `EarlyLintPass` and `LateLintPass`\n1 + mac!()\n```\n\nAssuming that we'd collect the `1` expression as a variable `left` and the\n`0`/`mac!()` expression as a variable `right`, we can simply compare their\ncontexts. If the context is different, then we most likely are dealing with a\nmacro expansion and should just ignore it:\n\n```rust\nif left.span.ctxt() != right.span.ctxt() {\n    // The code author most likely cannot modify this expression\n    return;\n}\n```\n\n> **Note**: Code that is not from expansion is in the \"root\" context.\n> So any spans whose `from_expansion` returns `false` can be assumed\n> to have the same context. Because of this, using `span.from_expansion()`\n> is often sufficient.\n\nGoing a bit deeper, in a simple expression such as `a == b`,\n`a` and `b` have the same context.\nHowever, in a `macro_rules!` with `a == $b`, `$b` is expanded to\nan expression that contains a different context from `a`.\n\nTake a look at the following macro `m`:\n\n```rust\nmacro_rules! m {\n    ($a:expr, $b:expr) => {\n        if $a.is_some() {\n            $b;\n        }\n    }\n}\n\nlet x: Option<u32> = Some(42);\nm!(x, x.unwrap());\n```\n\nIf the `m!(x, x.unwrap());` line is expanded, we would get two expanded\nexpressions:\n\n- `x.is_some()` (from the `$a.is_some()` line in the `m` macro)\n- `x.unwrap()` (corresponding to `$b` in the `m` macro)\n\nSuppose `x.is_some()` expression's span is associated with the `x_is_some_span` variable\nand `x.unwrap()` expression's span is associated with `x_unwrap_span` variable,\nwe could assume that these two spans do not share the same context:\n\n```rust\n// x.is_some() is from inside the macro\n// x.unwrap() is from outside the macro\nassert_ne!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());\n```\n\n### The `in_external_macro` function\n\n`Span` provides a method ([`in_external_macro`]) that can\ndetect if the given span is from a macro defined in a foreign crate.\n\nTherefore, if we really want a new lint to work with macro-generated code,\nthis is the next line of defense to avoid macros not defined inside\nthe current crate since it is unfair to the user if Clippy lints code\nwhich the user cannot change.\n\nFor example, assume we have the following code that is being examined\nby Clippy:\n\n```rust\n#[macro_use]\nextern crate a_foreign_crate_with_macros;\n\n// `foo` macro is defined in `a_foreign_crate_with_macros`\nfoo!(\"bar\");\n```\n\nAlso assume that we get the corresponding variable `foo_span` for the\n`foo` macro call, we could decide not to lint if `in_external_macro`\nresults in `true` (note that `cx` can be `EarlyContext` or `LateContext`):\n\n```rust\nif foo_span.in_external_macro(cx.sess().source_map()) {\n    // We should ignore macro from a foreign crate.\n    return;\n}\n```\n\n### The `is_from_proc_macro` function\nA common point of confusion is the existence of [`is_from_proc_macro`]\nand how it differs from the other [`in_external_macro`]/[`from_expansion`] functions.\n\nWhile [`in_external_macro`] and [`from_expansion`] both work perfectly fine for detecting expanded code\nfrom *declarative* macros (i.e. `macro_rules!` and macros 2.0),\ndetecting *proc macro*-generated code is a bit more tricky, as proc macros can (and often do)\nfreely manipulate the span of returned tokens.\n\nIn practice, this often happens through the use of [`quote::quote_spanned!`] with a span from the input tokens. \n\nIn those cases, there is no *reliable* way for the compiler (and tools like Clippy)\nto distinguish code that comes from such a proc macro from code that the user wrote directly,\nand [`in_external_macro`] will return `false`.\n\nThis is usually not an issue for the compiler and actually helps proc macro authors create better error messages,\nas it allows associating parts of the expansion with parts of the macro input and lets the compiler\npoint the user to the relevant code in case of a compile error.\n\nHowever, for Clippy this is inconvenient, because most of the time *we don't* want\nto lint proc macro-generated code and this makes it impossible to tell what is and isn't proc macro code.\n\n> NOTE: this is specifically only an issue when a proc macro explicitly sets the span to that of an **input span**.\n>\n> For example, other common ways of creating `TokenStream`s, such as `\"fn foo() {...}\".parse::<TokenStream>()`,\n> sets each token's span to `Span::call_site()`, which already marks the span as coming from a proc macro\n> and the usual span methods have no problem detecting that as a macro span.\n\nAs such, Clippy has its own `is_from_proc_macro` function which tries to *approximate*\nwhether a span comes from a proc macro, by checking whether the source text at the given span\nlines up with the given AST node.\n\nThis function is typically used in combination with the other mentioned macro span functions,\nbut is usually called much later into the condition chain as it's a bit heavier than most other conditions,\nso that the other cheaper conditions can fail faster. For example, the `borrow_deref_ref` lint:\n```rs\nimpl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) {\n        if let ... = ...\n            && ...\n            && !e.span.from_expansion()\n            && ...\n            && ...\n            && !is_from_proc_macro(cx, e)\n            && ...\n        {\n            ...\n        }\n    }\n}\n```\n\n### Testing lints with macro expansions\nTo test that all of these cases are handled correctly in your lint,\nwe have a helper auxiliary crate that exposes various macros, used by tests like so:\n```rust\n//@aux-build:proc_macros.rs\n\nextern crate proc_macros;\n\nfn main() {\n    proc_macros::external!{ code_that_should_trigger_your_lint }\n    proc_macros::with_span!{ span code_that_should_trigger_your_lint }\n}\n```\nThis exercises two cases:\n- `proc_macros::external!` is a simple proc macro that echos the input tokens back but with a macro span:\nthis represents the usual, common case where an external macro expands to code that your lint would trigger,\nand is correctly handled by `in_external_macro` and `Span::from_expansion`.\n\n- `proc_macros::with_span!` echos back the input tokens starting from the second token\nwith the span of the first token: this is where the other functions will fail and `is_from_proc_macro` is needed\n\n\n[`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt\n[expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration\n[`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion\n[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro\n[Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html\n[SyntaxContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html\n[`is_from_proc_macro`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/fn.is_from_proc_macro.html\n[`quote::quote_spanned!`]: https://docs.rs/quote/latest/quote/macro.quote_spanned.html\n"
  },
  {
    "path": "book/src/development/method_checking.md",
    "content": "# Method Checking\n\nIn some scenarios we might want to check for methods when developing\na lint. There are two kinds of questions that we might be curious about:\n\n-   Invocation: Does an expression call a specific method?\n-   Definition: Does an `impl` define a method?\n\n## Checking if an `expr` is calling a specific method\n\nSuppose we have an `expr`, we can check whether it calls a specific\nmethod, e.g. `our_fancy_method`, by performing a pattern match on\nthe [`ExprKind`] that we can access from `expr.kind`:\n\n```rust\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::sym;\n\nimpl<'tcx> LateLintPass<'tcx> for OurFancyMethodLint {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        // Check our expr is calling a method with pattern matching\n        if let hir::ExprKind::MethodCall(path, _, _, _) = &expr.kind\n            // Check if the name of this method is `our_fancy_method`\n            && path.ident.name == sym::our_fancy_method\n            // Check if the method belongs to the `sym::OurFancyTrait` trait.\n            // (for example, a `map` method could belong to user-defined trait instead of to `Iterator`)\n            // See the next section for more information.\n            && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::OurFancyTrait)\n        {\n            println!(\"`expr` is a method call for `our_fancy_method`\");\n        }\n    }\n}\n```\n\nTake a closer look at the `ExprKind` enum variant [`MethodCall`] for more\ninformation on the pattern matching. As mentioned in [Define\nLints](defining_lints.md#lint-types), the `methods` lint type is full of pattern\nmatching with `MethodCall` in case the reader wishes to explore more.\n\nNew symbols such as `our_fancy_method` need to be added to the `clippy_utils::sym` module.\nThis module extends the list of symbols already provided by the compiler crates\nin `rustc_span::sym`.\n\nIf a trait defines only one method (such as the `std::ops::Deref` trait, which only has the `deref()` method),\none might be tempted to omit the method name check. This would work, but is not always advisable because:\n- If a new method (possibly with a default implementation) were to be added to the trait, there would be a risk of\n  matching the wrong method.\n- Comparing symbols is very cheap and might prevent a more expensive lookup.\n\n## Checking if a `impl` block implements a method\n\nWhile sometimes we want to check whether a method is being called or not, other\ntimes we want to know if our `Ty` defines a method.\n\nTo check if our `impl` block defines a method `our_fancy_method`, we will\nutilize the [`check_impl_item`] method that is available in our beloved\n[`LateLintPass`] (for more information, refer to the [\"Lint\nPasses\"](lint_passes.md) chapter in the Clippy book). This method provides us\nwith an [`ImplItem`] struct, which represents anything within an `impl` block.\n\nLet us take a look at how we might check for the implementation of\n`our_fancy_method` on a type:\n\n```rust\nuse clippy_utils::{return_ty, sym};\nuse clippy_utils::res::MaybeDef;\nuse rustc_hir::{ImplItem, ImplItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\n\nimpl<'tcx> LateLintPass<'tcx> for MyTypeImpl {\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {\n        // Check if item is a method/function\n        if let ImplItemKind::Fn(ref signature, _) = impl_item.kind\n            // Check the method is named `our_fancy_method`\n            && impl_item.ident.name.as_str() == \"our_fancy_method\"\n            // We can also check it has a parameter `self`\n            && signature.decl.implicit_self.has_implicit_self()\n            // We can go even further and even check if its return type is `String`\n            && return_ty(cx, impl_item.hir_id).is_diag_item(cx, sym::String)\n        {\n            println!(\"`our_fancy_method` is implemented!\");\n        }\n    }\n}\n```\n\n[`check_impl_item`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_impl_item\n[`ExprKind`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/enum.ExprKind.html\n[`ImplItem`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_hir/hir/struct.ImplItem.html\n[`LateLintPass`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/trait.LateLintPass.html\n[`MethodCall`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/enum.ExprKind.html#variant.MethodCall\n"
  },
  {
    "path": "book/src/development/proposals/README.md",
    "content": "# Proposals\n\nThis chapter is about accepted proposals for changes that should be worked on in\nor around Clippy in the long run.\n\nBesides adding more and more lints and improve the lints that Clippy already\nhas, Clippy is also interested in making the experience of its users, developers\nand maintainers better over time. Projects that address bigger picture things\nlike this usually take more time, and it is useful to have a proposal for those\nfirst. This is the place where such proposals are collected, so that we can\nrefer to them when working on them.\n"
  },
  {
    "path": "book/src/development/proposals/roadmap-2021.md",
    "content": "# Roadmap 2021\n\n# Summary\n\nThis Roadmap lays out the plans for Clippy in 2021:\n\n- Improving usability and reliability\n- Improving experience of contributors and maintainers\n- Develop and specify processes\n\nMembers of the Clippy team will be assigned tasks from one or more of these\ntopics. The team member is then responsible to complete the assigned tasks. This\ncan either be done by implementing them or by providing mentorship to interested\ncontributors.\n\n# Motivation\n\nWith the ongoing growth of the Rust language and with that of the whole\necosystem, also Clippy gets more and more users and contributors. This is good\nfor the project, but also brings challenges along. Some of these challenges are:\n\n- More issues about reliability or usability are popping up\n- Traffic is hard to handle for a small team\n- Bigger projects don't get completed due to the lack of processes and/or time\n  of the team members\n\nAdditionally, according to the [Rust Roadmap 2021], clear processes should be\ndefined by every team and unified across teams. This Roadmap is the first step\ntowards this.\n\n[Rust Roadmap 2021]: https://github.com/rust-lang/rfcs/pull/3037\n\n# Explanation\n\nThis section will explain the things that should be done in 2021. It is\nimportant to note, that this document focuses on the \"What?\", not the \"How?\".\nThe later will be addressed in follow-up tracking issue, with an assigned team\nmember.\n\nThe following is split up in two major sections. The first section covers the\nuser facing plans, the second section the internal plans.\n\n## User Facing\n\nClippy should be as pleasant to use and configure as possible. This section\ncovers plans that should be implemented to improve the situation of Clippy in\nthis regard.\n\n### Usability\n\nIn the following, plans to improve the usability are covered.\n\n#### No Output After `cargo check`\n\nCurrently, when `cargo clippy` is run after `cargo check`, it does not produce\nany output. This is especially problematic since `rust-analyzer` is on the rise,\nand it uses `cargo check` for checking code. A fix is already implemented, but\nit still has to be pushed over the finish line. This also includes the\nstabilization of the `cargo clippy --fix` command or the support of multi-span\nsuggestions in `rustfix`.\n\n- [#4612](https://github.com/rust-lang/rust-clippy/issues/4612)\n\n#### `lints.toml` Configuration\n\nThis is something that comes up every now and then: a reusable configuration\nfile, where lint levels can be defined. Discussions about this often lead to\nnothing specific or to \"we need an RFC for this\". And this is exactly what needs\nto be done. Get together with the cargo team and write an RFC and implement such\na configuration file somehow and somewhere.\n\n- [#3164](https://github.com/rust-lang/rust-clippy/issues/3164)\n- [cargo#5034](https://github.com/rust-lang/cargo/issues/5034)\n- [IRLO](https://internals.rust-lang.org/t/proposal-cargo-lint-configuration/9135/8)\n\n#### Lint Groups\n\nThere are more and more issues about managing lints in Clippy popping up. Lints\nare hard to implement with a guarantee of no/few false positives (FPs). One way\nto address this might be to introduce more lint groups to give users the ability\nto better manage lints, or improve the process of classifying lints, so that\ndisabling lints due to FPs becomes rare. It is important to note, that Clippy\nlints are less conservative than `rustc` lints, which won't change in the\nfuture.\n\n- [#5537](https://github.com/rust-lang/rust-clippy/issues/5537)\n- [#6366](https://github.com/rust-lang/rust-clippy/issues/6366)\n\n### Reliability\n\nIn the following, plans to improve the reliability are covered.\n\n#### False Positive Rate\n\nIn the worst case, new lints are only available in nightly for 2 weeks, before\nhitting beta and ultimately stable. This and the fact that fewer people use\nnightly Rust nowadays makes it more probable that a lint with many FPs hits\nstable. This leads to annoyed users, that will disable these new lints in the\nbest case and to more annoyed users, that will stop using Clippy in the worst.\nA process should be developed and implemented to prevent this from happening.\n\n- [#6429](https://github.com/rust-lang/rust-clippy/issues/6429)\n\n## Internal\n\n(The end of) 2020 has shown, that Clippy has to think about the available\nresources, especially regarding management and maintenance of the project. This\nsection address issues affecting team members and contributors.\n\n### Management\n\nIn 2020 Clippy achieved over 1000 open issues with regularly between 25-35 open\nPRs. This is simultaneously a win and a loss. More issues and PRs means more\npeople are interested in Clippy and in contributing to it. On the other hand, it\nmeans for team members more work and for contributors longer wait times for\nreviews. The following will describe plans how to improve the situation for both\nteam members and contributors.\n\n#### Clear Expectations for Team Members\n\nAccording to the [Rust Roadmap 2021], a document specifying what it means to be\na member of the team should be produced. This should not put more pressure on\nthe team members, but rather help them and interested folks to know what the\nexpectations are. With this it should also be easier to recruit new team members\nand may encourage people to get in touch, if they're interested to join.\n\n#### Scaling up the Team\n\nMore people means less work for each individual. Together with the document\nabout expectations for team members, a document defining the process of how to\njoin the team should be produced. This can also increase the stability of the\nteam, in case of current members dropping out (temporarily). There can also be\ndifferent roles in the team, like people triaging vs. people reviewing.\n\n#### Regular Meetings\n\nOther teams have regular meetings. Clippy is big enough that it might be worth\nto also do them. Especially if more people join the team, this can be important\nfor sync-ups. Besides the asynchronous communication, that works well for\nworking on separate lints, a meeting adds a synchronous alternative at a known\ntime. This is especially helpful if there are bigger things that need to be\ndiscussed (like the projects in this roadmap). For starters bi-weekly meetings\nbefore Rust syncs might make sense.\n\n#### Triaging\n\nTo get a handle on the influx of open issues, a process for triaging issues and\nPRs should be developed. Officially, Clippy follows the Rust triage process, but\ncurrently no one enforces it. This can be improved by sharing triage teams\nacross projects or by implementing dashboards / tools which simplify triaging.\n\n### Development\n\nImproving the developer and contributor experience is something the Clippy team\nworks on regularly. Though, some things might need special attention and\nplaning. These topics are listed in the following.\n\n#### Process for New and Existing Lints\n\nAs already mentioned above, classifying new lints gets quite hard, because the\nprobability of a buggy lint getting into stable is quite high. A process should\nbe implemented on how to classify lints. In addition, a test system should be\ndeveloped to find out which lints are currently problematic in real world code\nto fix or disable them.\n\n- [#6429 (comment)](https://github.com/rust-lang/rust-clippy/issues/6429#issuecomment-741056379)\n- [#6429 (comment)](https://github.com/rust-lang/rust-clippy/issues/6429#issuecomment-741153345)\n\n#### Processes\n\nRelated to the point before, a process for suggesting and discussing major\nchanges should be implemented. It's also not clearly defined when a lint should\nbe enabled or disabled by default. This can also be improved by the test system\nmentioned above.\n\n#### Dev-Tools\n\nThere's already `cargo dev` which makes Clippy development easier and more\npleasant. This can still be expanded, so that it covers more areas of the\ndevelopment process.\n\n- [#5394](https://github.com/rust-lang/rust-clippy/issues/5394)\n\n#### Contributor Guide\n\nSimilar to a Clippy Book, which describes how to use Clippy, a book about how to\ncontribute to Clippy might be helpful for new and existing contributors. There's\nalready the `doc` directory in the Clippy repo, this can be turned into a\n`mdbook`.\n\n#### `rustc` integration\n\nRecently Clippy was integrated with `git subtree` into the `rust-lang/rust`\nrepository. This made syncing between the two repositories easier. A\n`#[non_exhaustive]` list of things that still can be improved is:\n\n1. Use the same `rustfmt` version and configuration as `rustc`.\n2. Make `cargo dev` work in the Rust repo, just as it works in the Clippy repo.\n   E.g. `cargo dev bless` or `cargo dev update_lints`. And even add more things\n   to it that might be useful for the Rust repo, e.g. `cargo dev deprecate`.\n3. Easier sync process. The `subtree` situation is not ideal.\n\n## Prioritization\n\nThe most pressing issues for users of Clippy are of course the user facing\nissues. So there should be a priority on those issues, but without losing track\nof the internal issues listed in this document.\n\nGetting the FP rate of warn/deny-by-default lints under control should have the\nhighest priority. Other user facing issues should also get a high priority, but\nshouldn't be in the way of addressing internal issues.\n\nTo better manage the upcoming projects, the basic internal processes, like\nmeetings, tracking issues and documentation, should be established as soon as\npossible. They might even be necessary to properly manage the projects,\nregarding the user facing issues.\n\n# Prior Art\n\n## Rust Roadmap\n\nRust's roadmap process was established by [RFC 1728] in 2016. Since then every\nyear a roadmap was published, that defined the bigger plans for the coming\nyears. This year roadmap can be found [here][Rust Roadmap 2021].\n\n[RFC 1728]: https://rust-lang.github.io/rfcs/1728-north-star.html\n\n# Drawbacks\n\n## Big Roadmap\n\nThis roadmap is pretty big and not all items listed in this document might be\naddressed during 2021. Because this is the first roadmap for Clippy, having open\ntasks at the end of 2021 is fine, but they should be revisited in the 2022\nroadmap.\n"
  },
  {
    "path": "book/src/development/proposals/syntax-tree-patterns.md",
    "content": "- Feature Name: syntax-tree-patterns\n- Start Date: 2019-03-12\n- RFC PR: [#3875](https://github.com/rust-lang/rust-clippy/pull/3875)\n\n# Summary\n\nIntroduce a domain-specific language (similar to regular expressions) that\nallows to describe lints using *syntax tree patterns*.\n\n\n# Motivation\n\nFinding parts of a syntax tree (AST, HIR, ...) that have certain properties\n(e.g. \"*an if that has a block as its condition*\") is a major task when writing\nlints. For non-trivial lints, it often requires nested pattern matching of AST /\nHIR nodes. For example, testing that an expression is a boolean literal requires\nthe following checks:\n\n```rust,ignore\nif let ast::ExprKind::Lit(lit) = &expr.node {\n    if let ast::LitKind::Bool(_) = &lit.node {\n        ...\n    }\n}\n```\n\nWriting this kind of matching code quickly becomes a complex task and the\nresulting code is often hard to comprehend. The code below shows a simplified\nversion of the pattern matching required by the `collapsible_if` lint:\n\n```rust,ignore\n// simplified version of the collapsible_if lint\nif let ast::ExprKind::If(check, then, None) = &expr.node {\n    if then.stmts.len() == 1 {\n        if let ast::StmtKind::Expr(inner) | ast::StmtKind::Semi(inner) = &then.stmts[0].node {\n            if let ast::ExprKind::If(check_inner, content, None) = &inner.node {\n                ...\n            }\n        }\n    }\n}\n```\n\nThe `if_chain` macro can improve readability by flattening the nested if\nstatements, but the resulting code is still quite hard to read:\n\n```rust\n// simplified version of the collapsible_if lint\nif_chain! {\n    if let ast::ExprKind::If(check, then, None) = &expr.node;\n    if then.stmts.len() == 1;\n    if let ast::StmtKind::Expr(inner) | ast::StmtKind::Semi(inner) = &then.stmts[0].node;\n    if let ast::ExprKind::If(check_inner, content, None) = &inner.node;\n    then {\n        ...\n    }\n}\n```\n\nThe code above matches if expressions that contain only another if expression\n(where both ifs don't have an else branch). While it's easy to explain what the\nlint does, it's hard to see that from looking at the code samples above.\n\nFollowing the motivation above, the first goal this RFC is to **simplify writing\nand reading lints**.\n\nThe second part of the motivation is clippy's dependence on unstable\ncompiler-internal data structures. Clippy lints are currently written against\nthe compiler's AST / HIR which means that even small changes in these data\nstructures might break a lot of lints. The second goal of this RFC is to **make\nlints independent of the compiler's AST / HIR data structures**.\n\n# Approach\n\nA lot of complexity in writing lints currently seems to come from having to\nmanually implement the matching logic (see code samples above). It's an\nimperative style that describes *how* to match a syntax tree node instead of\nspecifying *what* should be matched against declaratively. In other areas, it's\ncommon to use declarative patterns to describe desired information and let the\nimplementation do the actual matching. A well-known example of this approach are\n[regular expressions](https://en.wikipedia.org/wiki/Regular_expression). Instead\nof writing code that detects certain character sequences, one can describe a\nsearch pattern using a domain-specific language and search for matches using\nthat pattern. The advantage of using a declarative domain-specific language is\nthat its limited domain (e.g. matching character sequences in the case of\nregular expressions) allows to express entities in that domain in a very natural\nand expressive way.\n\nWhile regular expressions are very useful when searching for patterns in flat\ncharacter sequences, they cannot easily be applied to hierarchical data\nstructures like syntax trees. This RFC therefore proposes a pattern matching\nsystem that is inspired by regular expressions and designed for hierarchical\nsyntax trees.\n\n# Guide-level explanation\n\nThis proposal adds a `pattern!` macro that can be used to specify a syntax tree\npattern to search for. A simple pattern is shown below:\n\n```rust\npattern!{\n    my_pattern: Expr =\n        Lit(Bool(false))\n}\n```\n\nThis macro call defines a pattern named `my_pattern` that can be matched against\nan `Expr` syntax tree node. The actual pattern (`Lit(Bool(false))` in this case)\ndefines which syntax trees should match the pattern. This pattern matches\nexpressions that are boolean literals with value `false`.\n\nThe pattern can then be used to implement lints in the following way:\n\n```rust,ignore\n...\n\nimpl EarlyLintPass for MyAwesomeLint {\n    fn check_expr(&mut self, cx: &EarlyContext, expr: &syntax::ast::Expr) {\n\n        if my_pattern(expr).is_some() {\n            cx.span_lint(\n                MY_AWESOME_LINT,\n                expr.span,\n                \"This is a match for a simple pattern. Well done!\",\n            );\n        }\n\n    }\n}\n```\n\nThe `pattern!` macro call expands to a function `my_pattern` that expects a\nsyntax tree expression as its argument and returns an `Option` that indicates\nwhether the pattern matched.\n\n> Note: The result type is explained in more detail in [a later\n> section](#the-result-type). For now, it's enough to know that the result is\n> `Some` if the pattern matched and `None` otherwise.\n\n## Pattern syntax\n\nThe following examples demonstrate the pattern syntax:\n\n\n#### Any (`_`)\n\nThe simplest pattern is the any pattern. It matches anything and is therefore\nsimilar to regex's `*`.\n\n```rust\npattern!{\n    // matches any expression\n    my_pattern: Expr =\n        _\n}\n```\n\n#### Node (`<node-name>(<args>)`)\n\nNodes are used to match a specific variant of an AST node. A node has a name and\na number of arguments that depends on the node type. For example, the `Lit` node\nhas a single argument that describes the type of the literal. As another\nexample, the `If` node has three arguments describing the if's condition, then\nblock and else block.\n\n```rust\npattern!{\n    // matches any expression that is a literal\n    my_pattern: Expr =\n        Lit(_)\n}\n\npattern!{\n    // matches any expression that is a boolean literal\n    my_pattern: Expr =\n        Lit(Bool(_))\n}\n\npattern!{\n    // matches if expressions that have a boolean literal in their condition\n    // Note: The `_?` syntax here means that the else branch is optional and can be anything.\n    //       This is discussed in more detail in the section `Repetition`.\n    my_pattern: Expr =\n        If( Lit(Bool(_)) , _, _?)\n}\n```\n\n\n#### Literal (`<lit>`)\n\nA pattern can also contain Rust literals. These literals match themselves.\n\n```rust\npattern!{\n    // matches the boolean literal false\n    my_pattern: Expr =\n        Lit(Bool(false))\n}\n\npattern!{\n    // matches the character literal 'x'\n    my_pattern: Expr =\n        Lit(Char('x'))\n}\n```\n\n#### Alternations (`a | b`)\n\n```rust\npattern!{\n    // matches if the literal is a boolean or integer literal\n    my_pattern: Lit =\n        Bool(_) | Int(_)\n}\n\npattern!{\n    // matches if the expression is a char literal with value 'x' or 'y'\n    my_pattern: Expr =\n        Lit( Char('x' | 'y') )\n}\n```\n\n#### Empty (`()`)\n\nThe empty pattern represents an empty sequence or the `None` variant of an\noptional.\n\n```rust\npattern!{\n    // matches if the expression is an empty array\n    my_pattern: Expr =\n        Array( () )\n}\n\npattern!{\n    // matches if expressions that don't have an else clause\n    my_pattern: Expr =\n        If(_, _, ())\n}\n```\n\n#### Sequence (`<a> <b>`)\n\n```rust\npattern!{\n    // matches the array [true, false]\n    my_pattern: Expr =\n        Array( Lit(Bool(true)) Lit(Bool(false)) )\n}\n```\n\n#### Repetition (`<a>*`, `<a>+`, `<a>?`, `<a>{n}`, `<a>{n,m}`, `<a>{n,}`)\n\nElements may be repeated. The syntax for specifying repetitions is identical to\n[regex's syntax](https://docs.rs/regex/1.1.2/regex/#repetitions).\n\n```rust\npattern!{\n    // matches arrays that contain 2 'x's as their last or second-last elements\n    // Examples:\n    //     ['x', 'x']                         match\n    //     ['x', 'x', 'y']                    match\n    //     ['a', 'b', 'c', 'x', 'x', 'y']     match\n    //     ['x', 'x', 'y', 'z']               no match\n    my_pattern: Expr =\n        Array( _* Lit(Char('x')){2} _? )\n}\n\npattern!{\n    // matches if expressions that **may or may not** have an else block\n    // Attn: `If(_, _, _)` matches only ifs that **have** an else block\n    //\n    //              | if with else block | if without else block\n    // If(_, _, _)  |       match        |       no match\n    // If(_, _, _?) |       match        |        match\n    // If(_, _, ()) |      no match      |        match\n    my_pattern: Expr =\n        If(_, _, _?)\n}\n```\n\n#### Named submatch (`<a>#<name>`)\n\n```rust\npattern!{\n    // matches character literals and gives the literal the name foo\n    my_pattern: Expr =\n        Lit(Char(_)#foo)\n}\n\npattern!{\n    // matches character literals and gives the char the name bar\n    my_pattern: Expr =\n        Lit(Char(_#bar))\n}\n\npattern!{\n    // matches character literals and gives the expression the name baz\n    my_pattern: Expr =\n        Lit(Char(_))#baz\n}\n```\n\nThe reason for using named submatches is described in the section [The result\ntype](#the-result-type).\n\n### Summary\n\nThe following table gives an summary of the pattern syntax:\n\n| Syntax                  | Concept          | Examples                                   |\n|-------------------------|------------------|--------------------------------------------|\n|`_`                      | Any              | `_`                                        |\n|`<node-name>(<args>)`    | Node             | `Lit(Bool(true))`, `If(_, _, _)`           |\n|`<lit>`                  | Literal          | `'x'`, `false`, `101`                      |\n|`<a> \\| <b>`             | Alternation      | `Char(_) \\| Bool(_)`                       |\n|`()`                     | Empty            | `Array( () )`                              |\n|`<a> <b>`                | Sequence         | `Tuple( Lit(Bool(_)) Lit(Int(_)) Lit(_) )` |\n|`<a>*` <br> `<a>+` <br> `<a>?` <br> `<a>{n}` <br> `<a>{n,m}` <br> `<a>{n,}` | Repetition <br> <br> <br> <br> <br><br> | `Array( _* )`, <br> `Block( Semi(_)+ )`, <br> `If(_, _, Block(_)?)`, <br> `Array( Lit(_){10} )`, <br> `Lit(_){5,10}`, <br> `Lit(Bool(_)){10,}` |\n|`<a>#<name>`             | Named submatch   | `Lit(Int(_))#foo` `Lit(Int(_#bar))`        |\n\n\n## The result type\n\nA lot of lints require checks that go beyond what the pattern syntax described\nabove can express. For example, a lint might want to check whether a node was\ncreated as part of a macro expansion or whether there's no comment above a node.\nAnother example would be a lint that wants to match two nodes that have the same\nvalue (as needed by lints like `almost_swapped`). Instead of allowing users to\nwrite these checks into the pattern directly (which might make patterns hard to\nread), the proposed solution allows users to assign names to parts of a pattern\nexpression. When matching a pattern against a syntax tree node, the return value\nwill contain references to all nodes that were matched by these named\nsubpatterns. This is similar to capture groups in regular expressions.\n\nFor example, given the following pattern\n\n```rust\npattern!{\n    // matches character literals\n    my_pattern: Expr =\n        Lit(Char(_#val_inner)#val)#val_outer\n}\n```\n\none could get references to the nodes that matched the subpatterns in the\nfollowing way:\n\n```rust,ignore\n...\nfn check_expr(expr: &syntax::ast::Expr) {\n    if let Some(result) = my_pattern(expr) {\n        result.val_inner  // type: &char\n        result.val        // type: &syntax::ast::Lit\n        result.val_outer  // type: &syntax::ast::Expr\n    }\n}\n```\n\nThe types in the `result` struct depend on the pattern. For example, the\nfollowing pattern\n\n```rust\npattern!{\n    // matches arrays of character literals\n    my_pattern_seq: Expr =\n        Array( Lit(_)*#foo )\n}\n```\n\nmatches arrays that consist of any number of literal expressions. Because those\nexpressions are named `foo`, the result struct contains a `foo` attribute which\nis a vector of expressions:\n\n```rust,ignore\n...\nif let Some(result) = my_pattern_seq(expr) {\n    result.foo        // type: Vec<&syntax::ast::Expr>\n}\n```\n\nAnother result type occurs when a name is only defined in one branch of an\nalternation:\n\n```rust\npattern!{\n    // matches if expression is a boolean or integer literal\n    my_pattern_alt: Expr =\n        Lit( Bool(_#bar) | Int(_) )\n}\n```\n\nIn the pattern above, the `bar` name is only defined if the pattern matches a\nboolean literal. If it matches an integer literal, the name isn't set. To\naccount for this, the result struct's `bar` attribute is an option type:\n\n```rust,ignore\n...\nif let Some(result) = my_pattern_alt(expr) {\n    result.bar        // type: Option<&bool>\n}\n```\n\nIt's also possible to use a name in multiple alternation branches if they have\ncompatible types:\n\n```rust,ignore\npattern!{\n    // matches if expression is a boolean or integer literal\n    my_pattern_mult: Expr =\n        Lit(_#baz) | Array( Lit(_#baz) )\n}\n...\nif let Some(result) = my_pattern_mult(expr) {\n    result.baz        // type: &syntax::ast::Lit\n}\n```\n\nNamed submatches are a **flat** namespace and this is intended. In the example\nabove, two different sub-structures are assigned to a flat name. I expect that\nfor most lints, a flat namespace is sufficient and easier to work with than a\nhierarchical one.\n\n#### Two stages\n\nUsing named subpatterns, users can write lints in two stages. First, a coarse\nselection of possible matches is produced by the pattern syntax. In the second\nstage, the named subpattern references can be used to do additional tests like\nasserting that a node hasn't been created as part of a macro expansion.\n\n## Implementing Clippy lints using patterns\n\nAs a \"real-world\" example, I re-implemented the `collapsible_if` lint using\npatterns. The code can be found\n[here](https://github.com/fkohlgrueber/rust-clippy-pattern/blob/039b07ecccaf96d6aa7504f5126720d2c9cceddd/clippy_lints/src/collapsible_if.rs#L88-L163).\nThe pattern-based version passes all test cases that were written for\n`collapsible_if`.\n\n\n# Reference-level explanation\n\n## Overview\n\nThe following diagram shows the dependencies between the main parts of the\nproposed solution:\n\n```\n                          Pattern syntax\n                                |\n                                |  parsing / lowering\n                                v\n                           PatternTree\n                                ^\n                                |\n                                |\n                          IsMatch trait\n                                |\n                                |\n             +---------------+-----------+---------+\n             |               |           |         |\n             v               v           v         v\n        syntax::ast     rustc::hir      syn       ...\n```\n\nThe pattern syntax described in the previous section is parsed / lowered into\nthe so-called *PatternTree* data structure that represents a valid syntax tree\npattern. Matching a *PatternTree* against an actual syntax tree (e.g. rust ast /\nhir or the syn ast, ...) is done using the *IsMatch* trait.\n\nThe *PatternTree* and the *IsMatch* trait are introduced in more detail in the\nfollowing sections.\n\n## PatternTree\n\nThe core data structure of this RFC is the **PatternTree**.\n\nIt's a data structure similar to rust's AST / HIR, but with the following\ndifferences:\n\n- The PatternTree doesn't contain parsing information like `Span`s\n- The PatternTree can represent alternatives, sequences and optionals\n\nThe code below shows a simplified version of the current PatternTree:\n\n> Note: The current implementation can be found\n> [here](https://github.com/fkohlgrueber/pattern-matching/blob/dfb3bc9fbab69cec7c91e72564a63ebaa2ede638/pattern-match/src/pattern_tree.rs#L50-L96).\n\n\n```rust\npub enum Expr {\n    Lit(Alt<Lit>),\n    Array(Seq<Expr>),\n    Block_(Alt<BlockType>),\n    If(Alt<Expr>, Alt<BlockType>, Opt<Expr>),\n    IfLet(\n        Alt<BlockType>,\n        Opt<Expr>,\n    ),\n}\n\npub enum Lit {\n    Char(Alt<char>),\n    Bool(Alt<bool>),\n    Int(Alt<u128>),\n}\n\npub enum Stmt {\n    Expr(Alt<Expr>),\n    Semi(Alt<Expr>),\n}\n\npub enum BlockType {\n    Block(Seq<Stmt>),\n}\n```\n\nThe `Alt`, `Seq` and `Opt` structs look like these:\n\n> Note: The current implementation can be found\n> [here](https://github.com/fkohlgrueber/pattern-matching/blob/dfb3bc9fbab69cec7c91e72564a63ebaa2ede638/pattern-match/src/matchers.rs#L35-L60).\n\n```rust,ignore\npub enum Alt<T> {\n    Any,\n    Elmt(Box<T>),\n    Alt(Box<Self>, Box<Self>),\n    Named(Box<Self>, ...)\n}\n\npub enum Opt<T> {\n    Any,  // anything, but not None\n    Elmt(Box<T>),\n    None,\n    Alt(Box<Self>, Box<Self>),\n    Named(Box<Self>, ...)\n}\n\npub enum Seq<T> {\n    Any,\n    Empty,\n    Elmt(Box<T>),\n    Repeat(Box<Self>, RepeatRange),\n    Seq(Box<Self>, Box<Self>),\n    Alt(Box<Self>, Box<Self>),\n    Named(Box<Self>, ...)\n}\n\npub struct RepeatRange {\n    pub start: usize,\n    pub end: Option<usize>  // exclusive\n}\n```\n\n## Parsing / Lowering\n\nThe input of a `pattern!` macro call is parsed into a `ParseTree` first and then\nlowered to a `PatternTree`.\n\nValid patterns depend on the *PatternTree* definitions. For example, the pattern\n`Lit(Bool(_)*)` isn't valid because the parameter type of the `Lit` variant of\nthe `Expr` enum is `Any<Lit>` and therefore doesn't support repetition (`*`). As\nanother example, `Array( Lit(_)* )` is a valid pattern because the parameter of\n`Array` is of type `Seq<Expr>` which allows sequences and repetitions.\n\n> Note: names in the pattern syntax correspond to *PatternTree* enum\n> **variants**. For example, the `Lit` in the pattern above refers to the `Lit`\n> variant of the `Expr` enum (`Expr::Lit`), not the `Lit` enum.\n\n## The IsMatch Trait\n\nThe pattern syntax and the *PatternTree* are independent of specific syntax tree\nimplementations (rust ast / hir, syn, ...). When looking at the different\npattern examples in the previous sections, it can be seen that the patterns\ndon't contain any information specific to a certain syntax tree implementation.\nIn contrast, Clippy lints currently match against ast / hir syntax tree nodes\nand therefore directly depend on their implementation.\n\nThe connection between the *PatternTree* and specific syntax tree\nimplementations is the `IsMatch` trait. It defines how to match *PatternTree*\nnodes against specific syntax tree nodes. A simplified implementation of the\n`IsMatch` trait is shown below:\n\n```rust,ignore\npub trait IsMatch<O> {\n    fn is_match(&self, other: &'o O) -> bool;\n}\n```\n\nThis trait needs to be implemented on each enum of the *PatternTree* (for the\ncorresponding syntax tree types). For example, the `IsMatch` implementation for\nmatching `ast::LitKind` against the *PatternTree's* `Lit` enum might look like\nthis:\n\n```rust\nimpl IsMatch<ast::LitKind> for Lit {\n    fn is_match(&self, other: &ast::LitKind) -> bool {\n        match (self, other) {\n            (Lit::Char(i), ast::LitKind::Char(j)) => i.is_match(j),\n            (Lit::Bool(i), ast::LitKind::Bool(j)) => i.is_match(j),\n            (Lit::Int(i), ast::LitKind::Int(j, _)) => i.is_match(j),\n            _ => false,\n        }\n    }\n}\n```\n\nAll `IsMatch` implementations for matching the current *PatternTree* against\n`syntax::ast` can be found\n[here](https://github.com/fkohlgrueber/pattern-matching/blob/dfb3bc9fbab69cec7c91e72564a63ebaa2ede638/pattern-match/src/ast_match.rs).\n\n\n# Drawbacks\n\n#### Performance\n\nThe pattern matching code is currently not optimized for performance, so it\nmight be slower than hand-written matching code. Additionally, the two-stage\napproach (matching against the coarse pattern first and checking for additional\nproperties later) might be slower than the current practice of checking for\nstructure and additional properties in one pass. For example, the following lint\n\n```rust,ignore\npattern!{\n    pat_if_without_else: Expr =\n        If(\n            _,\n            Block(\n                Expr( If(_, _, ())#inner )\n                | Semi( If(_, _, ())#inner )\n            )#then,\n            ()\n        )\n}\n...\nfn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {\n    if let Some(result) = pat_if_without_else(expr) {\n        if !block_starts_with_comment(cx, result.then) {\n            ...\n        }\n}\n```\n\nfirst matches against the pattern and then checks that the `then` block doesn't\nstart with a comment. Using clippy's current approach, it's possible to check\nfor these conditions earlier:\n\n```rust,ignore\nfn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {\n    if_chain! {\n        if let ast::ExprKind::If(ref check, ref then, None) = expr.node;\n        if !block_starts_with_comment(cx, then);\n        if let Some(inner) = expr_block(then);\n        if let ast::ExprKind::If(ref check_inner, ref content, None) = inner.node;\n        then {\n            ...\n        }\n    }\n}\n```\n\nWhether or not this causes performance regressions depends on actual patterns.\nIf it turns out to be a problem, the pattern matching algorithms could be\nextended to allow \"early filtering\" (see the [Early Filtering](#early-filtering)\nsection in Future Possibilities).\n\nThat being said, I don't see any conceptual limitations regarding pattern\nmatching performance.\n\n#### Applicability\n\nEven though I'd expect that a lot of lints can be written using the proposed\npattern syntax, it's unlikely that all lints can be expressed using patterns. I\nsuspect that there will still be lints that need to be implemented by writing\ncustom pattern matching code. This would lead to mix within clippy's codebase\nwhere some lints are implemented using patterns and others aren't. This\ninconsistency might be considered a drawback.\n\n\n# Rationale and alternatives\n\nSpecifying lints using syntax tree patterns has a couple of advantages compared\nto the current approach of manually writing matching code. First, syntax tree\npatterns allow users to describe patterns in a simple and expressive way. This\nmakes it easier to write new lints for both novices and experts and also makes\nreading / modifying existing lints simpler.\n\nAnother advantage is that lints are independent of specific syntax tree\nimplementations (e.g. AST / HIR, ...). When these syntax tree implementations\nchange, only the `IsMatch` trait implementations need to be adapted and existing\nlints can remain unchanged. This also means that if the `IsMatch` trait\nimplementations were integrated into the compiler, updating the `IsMatch`\nimplementations would be required for the compiler to compile successfully. This\ncould reduce the number of times Clippy breaks because of changes in the\ncompiler. Another advantage of the pattern's independence is that converting an\n`EarlyLintPass` lint into a `LatePassLint` wouldn't require rewriting the whole\npattern matching code. In fact, the pattern might work just fine without any\nadaptions.\n\n\n## Alternatives\n\n### Rust-like pattern syntax\n\nThe proposed pattern syntax requires users to know the structure of the\n`PatternTree` (which is very similar to the AST's / HIR's structure) and also\nthe pattern syntax. An alternative would be to introduce a pattern syntax that\nis similar to actual Rust syntax (probably like the `quote!` macro). For\nexample, a pattern that matches `if` expressions that have `false` in their\ncondition could look like this:\n\n```rust,ignore\nif false {\n    #[*]\n}\n```\n\n#### Problems\n\nExtending Rust syntax (which is quite complex by itself) with additional syntax\nneeded for specifying patterns (alternations, sequences, repetitions, named\nsubmatches, ...) might become difficult to read and really hard to parse\nproperly.\n\nFor example, a pattern that matches a binary operation that has `0` on both\nsides might look like this:\n\n```\n0 #[*:BinOpKind] 0\n```\n\nNow consider this slightly more complex example:\n\n```\n1 + 0 #[*:BinOpKind] 0\n```\n\nThe parser would need to know the precedence of `#[*:BinOpKind]` because it\naffects the structure of the resulting AST. `1 + 0 + 0` is parsed as `(1 + 0) +\n0` while `1 + 0 * 0` is parsed as `1 + (0 * 0)`. Since the pattern could be any\n`BinOpKind`, the precedence cannot be known in advance.\n\nAnother example of a problem would be named submatches. Take a look at this\npattern:\n\n```rust,ignore\nfn test() {\n    1 #foo\n}\n```\n\nWhich node is `#foo` referring to? `int`, `ast::Lit`, `ast::Expr`, `ast::Stmt`?\nNaming subpatterns in a rust-like syntax is difficult because a lot of AST nodes\ndon't have a syntactic element that can be used to put the name tag on. In these\nsituations, the only sensible option would be to assign the name tag to the\noutermost node (`ast::Stmt` in the example above), because the information of\nall child nodes can be retrieved through the outermost node. The problem with\nthis then would be that accessing inner nodes (like `ast::Lit`) would again\nrequire manual pattern matching.\n\nIn general, Rust syntax contains a lot of code structure implicitly. This\nstructure is reconstructed during parsing (e.g. binary operations are\nreconstructed using operator precedence and left-to-right) and is one of the\nreasons why parsing is a complex task. The advantage of this approach is that\nwriting code is simpler for users.\n\nWhen writing *syntax tree patterns*, each element of the hierarchy might have\nalternatives, repetitions, etc.. Respecting that while still allowing\nhuman-friendly syntax that contains structure implicitly seems to be really\ncomplex, if not impossible.\n\nDeveloping such a syntax would also require to maintain a custom parser that is\nat least as complex as the Rust parser itself. Additionally, future changes in\nthe Rust syntax might be incompatible with such a syntax.\n\nIn summary, I think that developing such a syntax would introduce a lot of\ncomplexity to solve a relatively minor problem.\n\nThe issue of users not knowing about the *PatternTree* structure could be solved\nby a tool that, given a rust program, generates a pattern that matches only this\nprogram (similar to the Clippy author lint).\n\nFor some simple cases (like the first example above), it might be possible to\nsuccessfully mix Rust and pattern syntax. This space could be further explored\nin a future extension.\n\n# Prior art\n\nThe pattern syntax is heavily inspired by regular expressions (repetitions,\nalternatives, sequences, ...).\n\nFrom what I've seen until now, other linters also implement lints that directly\nwork on syntax tree data structures, just like Clippy does currently. I would\ntherefore consider the pattern syntax to be *new*, but please correct me if I'm\nwrong.\n\n# Unresolved questions\n\n#### How to handle multiple matches?\n\nWhen matching a syntax tree node against a pattern, there are possibly multiple\nways in which the pattern can be matched. A simple example of this would be the\nfollowing pattern:\n\n```rust\npattern!{\n    my_pattern: Expr =\n        Array( _* Lit(_)+#literals)\n}\n```\n\nThis pattern matches arrays that end with at least one literal. Now given the\narray `[x, 1, 2]`, should `1` be matched as part of the `_*` or the `Lit(_)+`\npart of the pattern? The difference is important because the named submatch\n`#literals` would contain 1 or 2 elements depending how the pattern is matched.\nIn regular expressions, this problem is solved by matching \"greedy\" by default\nand \"non-greedy\" optionally.\n\nI haven't looked much into this yet because I don't know how relevant it is for\nmost lints. The current implementation simply returns the first match it finds.\n\n# Future possibilities\n\n#### Implement rest of Rust Syntax\n\nThe current project only implements a small part of the Rust syntax. In the\nfuture, this should incrementally be extended to more syntax to allow\nimplementing more lints. Implementing more of the Rust syntax requires extending\nthe `PatternTree` and `IsMatch` implementations, but should be relatively\nstraight-forward.\n\n#### Early filtering\n\nAs described in the *Drawbacks/Performance* section, allowing additional checks\nduring the pattern matching might be beneficial.\n\nThe pattern below shows how this could look like:\n\n```rust\npattern!{\n    pat_if_without_else: Expr =\n        If(\n            _,\n            Block(\n                Expr( If(_, _, ())#inner )\n                | Semi( If(_, _, ())#inner )\n            )#then,\n            ()\n        )\n    where\n        !in_macro(#then.span);\n}\n```\n\nThe difference compared to the currently proposed two-stage filtering is that\nusing early filtering, the condition (`!in_macro(#then.span)` in this case)\nwould be evaluated as soon as the `Block(_)#then` was matched.\n\nAnother idea in this area would be to introduce a syntax for backreferences.\nThey could be used to require that multiple parts of a pattern should match the\nsame value. For example, the `assign_op_pattern` lint that searches for `a = a\nop b` and recommends changing it to `a op= b` requires that both occurrences of\n`a` are the same. Using `=#...` as syntax for backreferences, the lint could be\nimplemented like this:\n\n```rust,ignore\npattern!{\n    assign_op_pattern: Expr =\n        Assign(_#target, Binary(_, =#target, _)\n}\n```\n\n#### Match descendant\n\nA lot of lints currently implement custom visitors that check whether any\nsubtree (which might not be a direct descendant) of the current node matches\nsome properties. This cannot be expressed with the proposed pattern syntax.\nExtending the pattern syntax to allow patterns like \"a function that contains at\nleast two return statements\" could be a practical addition.\n\n#### Negation operator for alternatives\n\nFor patterns like \"a literal that is not a boolean literal\" one currently needs\nto list all alternatives except the boolean case. Introducing a negation\noperator that allows to write `Lit(!Bool(_))` might be a good idea. This pattern\nwould be equivalent to `Lit( Char(_) | Int(_) )` (given that currently only three\nliteral types are implemented).\n\n#### Functional composition\n\nPatterns currently don't have any concept of composition. This leads to\nrepetitions within patterns. For example, one of the collapsible-if patterns\ncurrently has to be written like this:\n\n```rust\npattern!{\n    pat_if_else: Expr =\n        If(\n            _,\n            _,\n            Block_(\n                Block(\n                    Expr((If(_, _, _?) | IfLet(_, _?))#else_) |\n                    Semi((If(_, _, _?) | IfLet(_, _?))#else_)\n                )#block_inner\n            )#block\n        ) |\n        IfLet(\n            _,\n            Block_(\n                Block(\n                    Expr((If(_, _, _?) | IfLet(_, _?))#else_) |\n                    Semi((If(_, _, _?) | IfLet(_, _?))#else_)\n                )#block_inner\n            )#block\n        )\n}\n```\n\nIf patterns supported defining functions of subpatterns, the code could be\nsimplified as follows:\n\n```rust\npattern!{\n    fn expr_or_semi(expr: Expr) -> Stmt {\n        Expr(expr) | Semi(expr)\n    }\n    fn if_or_if_let(then: Block, else: Opt<Expr>) -> Expr {\n        If(_, then, else) | IfLet(then, else)\n    }\n    pat_if_else: Expr =\n        if_or_if_let(\n            _,\n            Block_(\n                Block(\n                    expr_or_semi( if_or_if_let(_, _?)#else_ )\n                )#block_inner\n            )#block\n        )\n}\n```\n\nAdditionally, common patterns like `expr_or_semi` could be shared between\ndifferent lints.\n\n#### Clippy Pattern Author\n\nAnother improvement could be to create a tool that, given some valid Rust\nsyntax, generates a pattern that matches this syntax exactly. This would make\nstarting to write a pattern easier. A user could take a look at the patterns\ngenerated for a couple of Rust code examples and use that information to write a\npattern that matches all of them.\n\nThis is similar to clippy's author lint.\n\n#### Supporting other syntaxes\n\nMost of the proposed system is language-agnostic. For example, the pattern\nsyntax could also be used to describe patterns for other programming languages.\n\nIn order to support other languages' syntaxes, one would need to implement\nanother `PatternTree` that sufficiently describes the languages' AST and\nimplement `IsMatch` for this `PatternTree` and the languages' AST.\n\nOne aspect of this is that it would even be possible to write lints that work on\nthe pattern syntax itself. For example, when writing the following pattern\n\n\n```rust\npattern!{\n    my_pattern: Expr =\n        Array( Lit(Bool(false)) Lit(Bool(false)) )\n}\n```\n\na lint that works on the pattern syntax's AST could suggest using this pattern\ninstead:\n\n```rust\npattern!{\n    my_pattern: Expr =\n        Array( Lit(Bool(false)){2} )\n}\n```\n\nIn the future, Clippy could use this system to also provide lints for custom\nsyntaxes like those found in macros.\n"
  },
  {
    "path": "book/src/development/speedtest.md",
    "content": "# Speedtest\n`SPEEDTEST` is the tool we use to measure lint's performance, it works by executing the same test several times.\n\nIt's useful for measuring changes to current lints and deciding if the performance changes too much. `SPEEDTEST` is\naccessed by the `SPEEDTEST` (and `SPEEDTEST_*`) environment variables.\n\n## Checking Speedtest\n\nTo do a simple speed test of a lint (e.g. `allow_attributes`), use this command.\n\n```sh\n$ SPEEDTEST=ui TESTNAME=\"allow_attributes\" cargo uitest\n```\n\nThis will test all `ui` tests (`SPEEDTEST=ui`) whose names start with `allow_attributes`. By default, `SPEEDTEST` will\niterate your test 1000 times. But you can change this with `SPEEDTEST_ITERATIONS`.\n\n```sh\n$ SPEEDTEST=toml SPEEDTEST_ITERATIONS=100 TESTNAME=\"semicolon_block\" cargo uitest\n```\n"
  },
  {
    "path": "book/src/development/the_team.md",
    "content": "# The team\n\nEveryone who contributes to Clippy makes the project what it is. Collaboration\nand discussions are the lifeblood of every open-source project. Clippy has a\nvery flat hierarchy. The teams mainly have additional access rights to the repo.\n\nThis document outlines the onboarding process, as well as duties, and access\nrights for members of a group.\n\nAll regular events mentioned in this chapter are tracked in the [calendar repository].\nThe calendar file is also available for download: [clippy.ics]\n\n## Everyone\n\nEveryone, including you, is welcome to join discussions and contribute in other\nways, like PRs.\n\nYou also have some triage rights, using `@rustbot` to add labels and claim\nissues. See [labeling with @rustbot].\n\nA rule for everyone should be to keep a healthy work-life balance. Take a break\nwhen you need one.\n\n## Clippy-Contributors\n\nThis is a group of regular contributors to Clippy to help with triaging.\n\n### Duties\n\nThis team exists to make contributing easier for regular members. It doesn't\ncarry any duties that need to be done. However, we want to encourage members of\nthis group to help with triaging, which can include:\n\n1. **Labeling issues**\n\n    For the `good first issue` label, it can still be good to use `@rustbot` to\n    subscribe to the issue and help interested parties, if they post questions\n    in the comments. \n\n2. **Closing duplicate or resolved issues**\n\n    When you manually close an issue, it's often a good idea, to add a short\n    comment explaining the reason.\n\n3. **Ping people after two weeks of inactivity**\n\n    We try to keep issue assignments and PRs fairly up-to-date. After two weeks,\n    it can be good to send a friendly ping to the delaying party.\n\n    You might close a PR with the `I-inactive-closed` label if the author is\n    busy or wants to abandon it. If the reviewer is busy, the PR can be\n    reassigned to someone else.\n\n    Checkout: <https://triage.rust-lang.org/triage/rust-lang/rust-clippy> to\n    monitor PRs.\n\nWhile not part of their duties, contributors are encouraged to review PRs\nand help on Zulip. The team always appreciates help!\n\n### Membership\n\nIf you have been contributing to Clippy for some time, we'll probably ask you if\nyou want to join this team. Members of this team are also welcome to suggest\npeople who they think would make a great addition to this group.\n\nFor this group, there is no direct onboarding process. You're welcome to just\ncontinue what you've been doing. If you like, you can ask for someone to mentor\nyou, either in the Clippy stream on Zulip or privately via a PM.\n\nIf you have been inactive in Clippy for over three months, we'll probably move\nyou to the alumni group. You're always welcome to come back.\n\n## The Clippy Team\n\n[The Clippy team](https://www.rust-lang.org/governance/teams/dev-tools#team-clippy)\nis responsible for maintaining Clippy.\n\n### Duties\n\n1. **Respond to PRs in a timely manner**\n\n    It's totally fine, if you don't have the time for reviews right now.\n    You can reassign the PR to a random member by commenting `r? clippy`.\n\n2. **Take a break when you need one**\n\n    You are valuable! Clippy wouldn't be what it is without you. So take a break\n    early and recharge some energy when you need to.\n\n3. **Be responsive on Zulip**\n\n    This means in a reasonable time frame, so responding within one or two days\n    is totally fine.\n\n    It's also good, if you answer threads on Zulip and take part in our Clippy\n    meetings, every two weeks. The meeting dates are tracked in the [calendar repository].\n    \n\n4. **Sync Clippy with the rust-lang/rust repo**\n\n    This is done every two weeks, usually by @flip1995.\n\n5. **Update the changelog**\n\n    This needs to be done for every release, every six weeks.\n\n### Membership\n\nIf you have been active for some time, we'll probably reach out and ask\nif you want to help with reviews and eventually join the Clippy team.\n\nDuring the onboarding process, you'll be assigned pull requests to review.\nYou'll also have an active team member as a mentor who'll stay in contact via\nZulip DMs to provide advice and feedback. If you have questions, you're always\nwelcome to ask, that is the best way to learn. Once you're done with the review,\nyou can ping your mentor for a full review and to r+ the PR in both of your names.\n\nWhen your mentor is confident that you can handle reviews on your own, they'll\nstart an informal vote among the active team members to officially add you to\nthe team. This vote is usually accepted unanimously. Then you'll be added to\nthe team once you've confirmed that you're still interested in joining. The\nonboarding phase typically takes a couple of weeks to a few months.\n\nIf you have been inactive in Clippy for over three months, we'll probably move\nyou to the alumni group. You're always welcome to come back.\n\n[calendar repository]: https://github.com/rust-lang/calendar/blob/main/clippy.toml\n[clippy.ics]: https://rust-lang.github.io/calendar/clippy.ics\n[labeling with @rustbot]: https://forge.rust-lang.org/triagebot/labeling.html\n"
  },
  {
    "path": "book/src/development/trait_checking.md",
    "content": "# Trait Checking\n\nBesides [type checking](type_checking.md), we might want to examine if\na specific type `Ty` implements certain trait when implementing a lint.\nThere are three approaches to achieve this, depending on if the target trait\nthat we want to examine has a [diagnostic item][diagnostic_items],\n[lang item][lang_items], or neither.\n\n## Using Diagnostic Items\n\nAs explained in the [Rust Compiler Development Guide][rustc_dev_guide], diagnostic items\nare introduced for identifying types via [Symbols][symbol].\n\nFor instance, if we want to examine whether an expression implements\nthe `Iterator` trait, we could simply write the following code,\nproviding the `LateContext` (`cx`), our expression at hand, and\nthe symbol of the trait in question:\n\n```rust\nuse clippy_utils::sym;\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir::Expr;\nuse rustc_lint::{LateContext, LateLintPass};\n\nimpl LateLintPass<'_> for CheckIteratorTraitLint {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let implements_iterator = (cx.tcx.get_diagnostic_item(sym::Iterator))\n            .is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(expr), id, &[]));\n        if implements_iterator {\n            // [...]\n        }\n\n    }\n}\n```\n\n> **Note**: Refer to [this index][symbol_index] for all the defined `Symbol`s.\n\n## Using Lang Items\n\nBesides diagnostic items, we can also use [`lang_items`][lang_items].\nTake a look at the documentation to find that `LanguageItems` contains\nall language items defined in the compiler.\n\nUsing one of its `*_trait` method, we could obtain the [DefId] of any\nspecific item, such as `Clone`, `Copy`, `Drop`, `Eq`, which are familiar\nto many Rustaceans.\n\nFor instance, if we want to examine whether an expression `expr` implements\n`Drop` trait, we could access `LanguageItems` via our `LateContext`'s\n[TyCtxt], which provides a `lang_items` method that will return the id of\n`Drop` trait to us. Then, by calling Clippy utils function `implements_trait`\nwe can check that the `Ty` of the `expr` implements the trait:\n\n```rust\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir::Expr;\nuse rustc_lint::{LateContext, LateLintPass};\n\nimpl LateLintPass<'_> for CheckDropTraitLint {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let ty = cx.typeck_results().expr_ty(expr);\n        if cx.tcx.lang_items()\n            .drop_trait()\n            .map_or(false, |id| implements_trait(cx, ty, id, &[])) {\n                println!(\"`expr` implements `Drop` trait!\");\n            }\n    }\n}\n```\n\n## Using Type Path\n\nIf neither diagnostic item nor a language item is available, we can use\n[`clippy_utils::paths`][paths] to determine get a trait's `DefId`.\n\n> **Note**: This approach should be avoided if possible, the best thing to do would be to make a PR to [`rust-lang/rust`][rust] adding a diagnostic item.\n\nBelow, we check if the given `expr` implements [`core::iter::Step`](https://doc.rust-lang.org/std/iter/trait.Step.html):\n\n```rust\nuse clippy_utils::paths;\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir::Expr;\nuse rustc_lint::{LateContext, LateLintPass};\n\nimpl LateLintPass<'_> for CheckIterStep {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let ty = cx.typeck_results().expr_ty(expr);\n        if let Some(trait_def_id) = paths::ITER_STEP.first(cx)\n            && implements_trait(cx, ty, trait_def_id, &[])\n        {\n            println!(\"`expr` implements the `core::iter::Step` trait!\");\n        }\n    }\n}\n```\n\n## Creating Types Programmatically\n\nTraits are often generic over a type parameter, e.g. `Borrow<T>` is generic\nover `T`. Rust allows us to implement a trait for a specific type. For example,\nwe can implement `Borrow<[u8]>` for a hypothetical type `Foo`. Let's suppose\nthat we would like to find whether our type actually implements `Borrow<[u8]>`.\n\nTo do so, we can use the same `implements_trait` function as above, and supply\na type parameter that represents `[u8]`. Since `[u8]` is a specialization of\n`[T]`, we can use the  [`Ty::new_slice`][new_slice] method to create a type\nthat represents `[T]` and supply `u8` as a type parameter.\nTo create a `ty::Ty` programmatically, we rely on `Ty::new_*` methods. These\nmethods create a `TyKind` and then wrap it in a `Ty` struct. This means we\nhave access to all the primitive types, such as `Ty::new_char`,\n`Ty::new_bool`, `Ty::new_int`, etc. We can also create more complex types,\nsuch as slices, tuples, and references out of these basic building blocks.\n\nFor trait checking, it is not enough to create the types, we need to convert\nthem into [GenericArg]. In rustc, a generic is an entity that the compiler\nunderstands and has three kinds, type, const and lifetime. By calling\n`.into()` on a constructed [Ty], we wrap the type into a generic which can\nthen be used by the query system to decide whether the specialized trait\nis implemented.\n\nThe following code demonstrates how to do this:\n\n```rust\n\nuse rustc_middle::ty::Ty;\nuse clippy_utils::sym;\nuse clippy_utils::ty::implements_trait;\n\nlet ty = todo!(\"Get the `Foo` type to check for a trait implementation\");\nlet borrow_id = cx.tcx.get_diagnostic_item(sym::Borrow).unwrap(); // avoid unwrap in real code\nlet slice_of_bytes_t = Ty::new_slice(cx.tcx, cx.tcx.types.u8);\nlet generic_param = slice_of_bytes_t.into();\nif implements_trait(cx, ty, borrow_id, &[generic_param]) {\n    todo!(\"Rest of lint implementation\")\n}\n```\n\nIn essence, the [Ty] struct allows us to create types programmatically in a\nrepresentation that can be used by the compiler and the query engine. We then\nuse the `rustc_middle::Ty` of the type we are interested in, and query the\ncompiler to see if it indeed implements the trait we are interested in.\n\n\n[DefId]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html\n[diagnostic_items]: https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html\n[lang_items]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/lang_items/struct.LanguageItems.html\n[paths]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_utils/src/paths.rs\n[rustc_dev_guide]: https://rustc-dev-guide.rust-lang.org/\n[symbol]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html\n[symbol_index]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/sym/index.html\n[TyCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html\n[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html\n[rust]: https://github.com/rust-lang/rust\n[new_slice]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.new_slice\n[GenericArg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.GenericArg.html\n"
  },
  {
    "path": "book/src/development/type_checking.md",
    "content": "# Type Checking\n\nWhen we work on a new lint or improve an existing lint, we might want\nto retrieve the type `Ty` of an expression `Expr` for a variety of\nreasons. This can be achieved by utilizing the [`LateContext`][LateContext]\nthat is available for [`LateLintPass`][LateLintPass].\n\n## `LateContext` and `TypeckResults`\n\nThe lint context [`LateContext`][LateContext] and [`TypeckResults`][TypeckResults]\n(returned by `LateContext::typeck_results`) are the two most useful data structures\nin `LateLintPass`. They allow us to jump to type definitions and other compilation\nstages such as HIR.\n\n> Note: `LateContext.typeck_results`'s return value is [`TypeckResults`][TypeckResults]\n> and is created in the type checking step, it includes useful information such as types of\n> expressions, ways to resolve methods and so on.\n\n`TypeckResults` contains useful methods such as [`expr_ty`][expr_ty],\nwhich gives us access to the underlying structure [`Ty`][Ty] of a given expression.\n\n```rust\npub fn expr_ty(&self, expr: &Expr<'_>) -> Ty<'tcx>\n```\n\nAs a side note, besides `expr_ty`, [`TypeckResults`][TypeckResults] contains a\n[`pat_ty()`][pat_ty] method that is useful for retrieving a type from a pattern.\n\n## `Ty`\n\n`Ty` struct contains the type information of an expression.\nLet's take a look at `rustc_middle`'s [`Ty`][Ty] struct to examine this struct:\n\n```rust\npub struct Ty<'tcx>(Interned<'tcx, WithStableHash<TyS<'tcx>>>);\n```\n\nAt a first glance, this struct looks quite esoteric. But at a closer look,\nwe will see that this struct contains many useful methods for type checking.\n\nFor instance, [`is_char`][is_char] checks if the given `Ty` struct corresponds\nto the primitive character type.\n\n### `is_*` Usage\n\nIn some scenarios, all we need to do is check if the `Ty` of an expression\nis a specific type, such as `char` type, so we could write the following:\n\n```rust\nimpl LateLintPass<'_> for MyStructLint {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        // Get type of `expr`\n        let ty = cx.typeck_results().expr_ty(expr);\n\n        // Check if the `Ty` of this expression is of character type\n        if ty.is_char() {\n            println!(\"Our expression is a char!\");\n        }\n    }\n}\n```\n\nFurthermore, if we examine the [source code][is_char_source] for `is_char`,\nwe find something very interesting:\n\n```rust\n#[inline]\npub fn is_char(self) -> bool {\n    matches!(self.kind(), Char)\n}\n```\n\nIndeed, we just discovered `Ty`'s [`kind()` method][kind], which provides us\nwith [`TyKind`][TyKind] of a `Ty`.\n\n## `TyKind`\n\n`TyKind` defines the kinds of types in Rust's type system.\nPeeking into [`TyKind` documentation][TyKind], we will see that it is an\nenum of over 25 variants, including items such as `Bool`, `Int`, `Ref`, etc.\n\n### `kind` Usage\n\nThe `TyKind` of `Ty` can be returned by calling [`Ty.kind()` method][kind].\nWe often use this method to perform pattern matching in Clippy.\n\nFor instance, if we want to check for a `struct`, we could examine if the\n`ty.kind` corresponds to an [`Adt`][Adt] (algebraic data type) and if its\n[`AdtDef`][AdtDef] is a struct:\n\n```rust\nimpl LateLintPass<'_> for MyStructLint {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        // Get type of `expr`\n        let ty = cx.typeck_results().expr_ty(expr);\n        // Match its kind to enter the type\n        match ty.kind() {\n            ty::Adt(adt_def, _) if adt_def.is_struct() => println!(\"Our `expr` is a struct!\"),\n            _ => ()\n        }\n    }\n}\n```\n\n## `hir::Ty` and `ty::Ty`\n\nWe've been talking about [`ty::Ty`][middle_ty] this whole time without addressing [`hir::Ty`][hir_ty], but the latter\nis also important to understand.\n\n`hir::Ty` would represent *what* the user wrote, while `ty::Ty` is how the compiler sees the type and has more\ninformation. Example:\n\n```rust\nfn foo(x: u32) -> u32 { x }\n```\n\nHere the HIR sees the types without \"thinking\" about them, it knows that the function takes an `u32` and returns\nan `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler\nunderstands that they're the same type, in-depth lifetimes, etc...\n\nTo get from a `hir::Ty` to a `ty::Ty`, you can use the [`lower_ty`][lower_ty] function outside of bodies or\nthe [`TypeckResults::node_type()`][node_type] method inside of bodies.\n\n> **Warning**: Don't use `lower_ty` inside of bodies, because this can cause ICEs.\n\n## Creating Types programmatically\n\nA common usecase for creating types programmatically is when we want to check if a type implements a trait (see\n[Trait Checking](trait_checking.md)).\n\nHere's an example of how to create a `Ty` for a slice of `u8`, i.e. `[u8]`\n\n```rust\nuse rustc_middle::ty::Ty;\n// assume we have access to a LateContext\nlet ty = Ty::new_slice(cx.tcx, Ty::new_u8());\n```\n\nIn general, we rely on `Ty::new_*` methods. These methods define the basic building-blocks that the\ntype-system and trait-system use to define and understand the written code.\n\n## Useful Links\n\nBelow are some useful links to further explore the concepts covered\nin this chapter:\n\n- [Stages of compilation](https://rustc-dev-guide.rust-lang.org/compiler-src.html#the-main-stages-of-compilation)\n- [Diagnostic items](https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html)\n- [Type checking](https://rustc-dev-guide.rust-lang.org/hir-typeck/summary.html)\n- [Ty module](https://rustc-dev-guide.rust-lang.org/ty.html)\n\n[Adt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html#variant.Adt\n[AdtDef]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/adt/struct.AdtDef.html\n[expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty\n[node_type]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.node_type\n[is_char]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.is_char\n[is_char_source]: https://github.com/rust-lang/rust/blob/d34f1f931489618efffc4007e6b6bdb9e10f6467/compiler/rustc_middle/src/ty/sty.rs#L1429-L1432\n[kind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.kind\n[LateContext]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LateContext.html\n[LateLintPass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html\n[pat_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/typeck_results/struct.TypeckResults.html#method.pat_ty\n[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html\n[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html\n[TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html\n[middle_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html\n[hir_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.Ty.html\n[lower_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/fn.lower_ty.html\n"
  },
  {
    "path": "book/src/development/writing_tests.md",
    "content": "# Testing\n\nDeveloping lints for Clippy is a Test-Driven Development (TDD) process because\nour first task before implementing any logic for a new lint is to write some test cases.\n\n## Develop Lints with Tests\n\nWhen we develop Clippy, we enter a complex and chaotic realm full of\nprogrammatic issues, stylistic errors, illogical code and non-adherence to convention.\nTests are the first layer of order we can leverage to define when and where\nwe want a new lint to trigger or not.\n\nMoreover, writing tests first help Clippy developers to find a balance for\nthe first iteration of and further enhancements for a lint.\nWith test cases on our side, we will not have to worry about over-engineering\na lint on its first version nor missing out some obvious edge cases of the lint.\nThis approach empowers us to iteratively enhance each lint.\n\n## Clippy UI Tests\n\nWe use **UI tests** for testing in Clippy. These UI tests check that the output\nof Clippy is exactly as we expect it to be. Each test is just a plain Rust file\nthat contains the code we want to check.\n\nThe output of Clippy is compared against a `.stderr` file. Note that you don't\nhave to create this file yourself. We'll get to generating the `.stderr` files\nwith the command [`cargo bless`](#cargo-bless) (seen later on).\n\n### Write Test Cases\n\nLet us now think about some tests for our imaginary `foo_functions` lint. We\nstart by opening the test file `tests/ui/foo_functions.rs` that was created by\n`cargo dev new_lint`.\n\nUpdate the file with some examples to get started:\n\n```rust\n#![warn(clippy::foo_functions)] // < Add this, so the lint is guaranteed to be enabled in this file\n\n// Impl methods\nstruct A;\nimpl A {\n    pub fn fo(&self) {}\n    pub fn foo(&self) {}\n    //~^ foo_functions\n    pub fn food(&self) {}\n}\n\n// Default trait methods\ntrait B {\n    fn fo(&self) {}\n    fn foo(&self) {}\n    //~^ foo_functions\n    fn food(&self) {}\n}\n\n// Plain functions\nfn fo() {}\nfn foo() {}\n//~^ foo_functions\nfn food() {}\n\nfn main() {\n    // We also don't want to lint method calls\n    foo();\n    let a = A;\n    a.foo();\n}\n```\n\nWithout actual lint logic to emit the lint when we see a `foo` function name,\nthis test will fail, because we expect errors at lines marked with\n`//~^ foo_functions`. However, we can now run the test with the following command:\n\n```sh\n$ TESTNAME=foo_functions cargo uitest\n```\n\nClippy will compile and it will fail complaining it didn't receive any errors:\n\n```\n...Clippy warnings and test outputs...\nerror: diagnostic code `clippy::foo_functions` not found on line 8\n --> tests/ui/foo_functions.rs:9:10\n  |\n9 |     //~^ foo_functions\n  |          ^^^^^^^^^^^^^ expected because of this pattern\n  |\n\nerror: diagnostic code `clippy::foo_functions` not found on line 16\n  --> tests/ui/foo_functions.rs:17:10\n   |\n17 |     //~^ foo_functions\n   |          ^^^^^^^^^^^^^ expected because of this pattern\n   |\n\nerror: diagnostic code `clippy::foo_functions` not found on line 23\n  --> tests/ui/foo_functions.rs:24:6\n   |\n24 | //~^ foo_functions\n   |      ^^^^^^^^^^^^^ expected because of this pattern\n   |\n\n```\n\nThis is normal. After all, we wrote a bunch of Rust code but we haven't really\nimplemented any logic for Clippy to detect `foo` functions and emit a lint.\n\nAs we gradually implement our lint logic, we will keep running this UI test command.\nClippy will begin outputting information that allows us to check if the output is\nturning into what we want it to be.\n\n### Example output\n\nAs our `foo_functions` lint is tested, the output would look something like this:\n\n```\nfailures:\n---- compile_test stdout ----\nnormalized stderr:\nerror: function called \"foo\"\n  --> tests/ui/foo_functions.rs:6:12\n   |\nLL |     pub fn foo(&self) {}\n   |            ^^^\n   |\n   = note: `-D clippy::foo-functions` implied by `-D warnings`\nerror: function called \"foo\"\n  --> tests/ui/foo_functions.rs:13:8\n   |\nLL |     fn foo(&self) {}\n   |        ^^^\nerror: function called \"foo\"\n  --> tests/ui/foo_functions.rs:19:4\n   |\nLL | fn foo() {}\n   |    ^^^\nerror: aborting due to 3 previous errors\n```\n\nNote the *failures* label at the top of the fragment, we'll get rid of it\n(saving this output) in the next section.\n\n> _Note:_ You can run multiple test files by specifying a comma separated list:\n> `TESTNAME=foo_functions,bar_methods,baz_structs`.\n\n### `cargo bless`\n\nOnce we are satisfied with the output, we need to run this command to\ngenerate or update the `.stderr` file for our lint:\n\n```sh\n$ TESTNAME=foo_functions cargo uibless\n```\n\nThis writes the emitted lint suggestions and fixes to the `.stderr` file, with\nthe reason for the lint, suggested fixes, and line numbers, etc.\n\nRunning `TESTNAME=foo_functions cargo uitest` should pass then. When we commit\nour lint, we need to commit the generated `.stderr` files, too.\n\nIn general, you should only commit files changed by `cargo bless` for the\nspecific lint you are creating/editing.\n\n> _Note:_ If the generated `.stderr`, and `.fixed` files are empty,\n> they should be removed.\n\n## `toml` Tests\n\nSome lints can be configured through a `clippy.toml` file. Those configuration\nvalues are tested in `tests/ui-toml`.\n\nTo add a new test there, create a new directory and add the files:\n\n- `clippy.toml`: Put here the configuration value you want to test.\n- `lint_name.rs`: A test file where you put the testing code, that should see a\n  different lint behavior according to the configuration set in the\n  `clippy.toml` file.\n\nThe potential `.stderr` and `.fixed` files can again be generated with `cargo\nbless`.\n\n## Cargo Lints\n\nThe process of testing is different for Cargo lints in that now we are\ninterested in the `Cargo.toml` manifest file. In this case, we also need a\nminimal crate associated with that manifest. Those tests are generated in\n`tests/ui-cargo`.\n\nImagine we have a new example lint that is named `foo_categories`, we can run:\n\n```sh\n$ cargo dev new_lint --name=foo_categories --pass=late --category=cargo\n```\n\nAfter running `cargo dev new_lint` we will find by default two new crates,\neach with its manifest file:\n\n* `tests/ui-cargo/foo_categories/fail/Cargo.toml`: this file should cause the\n  new lint to raise an error.\n* `tests/ui-cargo/foo_categories/pass/Cargo.toml`: this file should not trigger\n  the lint.\n\nIf you need more cases, you can copy one of those crates (under\n`foo_categories`) and rename it.\n\nThe process of generating the `.stderr` file is the same as for other lints\nand prepending the `TESTNAME` variable to `cargo uitest` works for Cargo lints too.\n\n## Rustfix Tests\n\nIf the lint you are working on is making use of structured suggestions,\n[`rustfix`] will apply the suggestions from the lint to the test file code and\ncompare that to the contents of a `.fixed` file.\n\nStructured suggestions tell a user how to fix or re-write certain code that has\nbeen linted with [`span_lint_and_sugg`].\n\nShould `span_lint_and_sugg` be used to generate a suggestion, but not all\nsuggestions lead to valid code, you can use the `//@no-rustfix` comment on top\nof the test file, to not run `rustfix` on that file.\n\nWe'll talk about suggestions more in depth in a [later chapter](emitting_lints.md).\n\nUse `cargo bless` to automatically generate the `.fixed` file after running\nthe tests.\n\n[`rustfix`]: https://github.com/rust-lang/cargo/tree/master/crates/rustfix\n[`span_lint_and_sugg`]: https://doc.rust-lang.org/beta/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_sugg.html\n\n## Testing Manually\n\nManually testing against an example file can be useful if you have added some\n`println!`s and the test suite output becomes unreadable.\n\nTo try Clippy with your local modifications, run from the working copy root.\n\n```sh\n$ cargo dev lint input.rs\n```\n"
  },
  {
    "path": "book/src/installation.md",
    "content": "# Installation\n\nIf you're using `rustup` to install and manage your Rust toolchains, Clippy is\nusually **already installed**. In that case you can skip this chapter and go to\nthe [Usage] chapter.\n\n> Note: If you used the `minimal` profile when installing a Rust toolchain,\n> Clippy is not automatically installed.\n\n## Using Rustup\n\nIf Clippy was not installed for a toolchain, it can be installed with\n\n```\n$ rustup component add clippy [--toolchain=<name>]\n```\n\n## From Source\n\nTake a look at the [Basics] chapter in the Clippy developer guide to find step-by-step\ninstructions on how to build and install Clippy from source.\n\n[Basics]: development/basics.md#install-from-source\n[Usage]: usage.md\n"
  },
  {
    "path": "book/src/lint_configuration.md",
    "content": "<!--\nThis file is generated by `cargo bless --test config-metadata`.\nPlease use that command to update the file and do not edit it by hand.\n-->\n\n# Lint Configuration Options\n\nThe following list shows each configuration option, along with a description, its default value, an example\nand lints affected.\n\n---\n\n## `absolute-paths-allowed-crates`\nWhich crates to allow absolute paths from\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)\n\n\n## `absolute-paths-max-segments`\nThe maximum number of segments a path can have before being linted, anything above this will\nbe linted.\n\n**Default Value:** `2`\n\n---\n**Affected lints:**\n* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)\n\n\n## `accept-comment-above-attributes`\nWhether to accept a safety comment to be placed above the attributes for the `unsafe` block\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)\n\n\n## `accept-comment-above-statement`\nWhether to accept a safety comment to be placed above the statement containing the `unsafe` block\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)\n\n\n## `allow-comparison-to-zero`\nDon't lint when comparing the result of a modulo operation to zero.\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic)\n\n\n## `allow-dbg-in-tests`\nWhether `dbg!` should be allowed in test functions or `#[cfg(test)]`\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro)\n\n\n## `allow-exact-repetitions`\nWhether an item should be allowed to have the same name as its containing module\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`module_name_repetitions`](https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions)\n\n\n## `allow-expect-in-consts`\nWhether `expect` should be allowed in code always evaluated at compile time\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)\n\n\n## `allow-expect-in-tests`\nWhether `expect` should be allowed in test functions or `#[cfg(test)]`\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)\n\n\n## `allow-indexing-slicing-in-tests`\nWhether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]`\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing)\n\n\n## `allow-large-stack-frames-in-tests`\nWhether functions inside `#[cfg(test)]` modules or test functions should be checked.\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames)\n\n\n## `allow-mixed-uninlined-format-args`\nWhether to allow mixed uninlined format args, e.g. `format!(\"{} {}\", a, foo.bar)`\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)\n\n\n## `allow-one-hash-in-raw-strings`\nWhether to allow `r#\"\"#` when `r\"\"` can be used\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`needless_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes)\n\n\n## `allow-panic-in-tests`\nWhether `panic` should be allowed in test functions or `#[cfg(test)]`\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`panic`](https://rust-lang.github.io/rust-clippy/master/index.html#panic)\n\n\n## `allow-print-in-tests`\nWhether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`print_stderr`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr)\n* [`print_stdout`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout)\n\n\n## `allow-private-module-inception`\nWhether to allow module inception if it's not public.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception)\n\n\n## `allow-renamed-params-for`\nList of trait paths to ignore when checking renamed function parameters.\n\n#### Example\n\n```toml\nallow-renamed-params-for = [ \"std::convert::From\" ]\n```\n\n#### Noteworthy\n\n- By default, the following traits are ignored: `From`, `TryFrom`, `FromStr`\n- `\"..\"` can be used as part of the list to indicate that the configured values should be appended to the\ndefault configuration of Clippy. By default, any configuration will replace the default value.\n\n**Default Value:** `[\"core::convert::From\", \"core::convert::TryFrom\", \"core::str::FromStr\"]`\n\n---\n**Affected lints:**\n* [`renamed_function_params`](https://rust-lang.github.io/rust-clippy/master/index.html#renamed_function_params)\n\n\n## `allow-unwrap-in-consts`\nWhether `unwrap` should be allowed in code always evaluated at compile time\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)\n\n\n## `allow-unwrap-in-tests`\nWhether `unwrap` should be allowed in test functions or `#[cfg(test)]`\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)\n\n\n## `allow-unwrap-types`\nList of types to allow `unwrap()` and `expect()` on.\n\n#### Example\n\n```toml\nallow-unwrap-types = [ \"std::sync::LockResult\" ]\n```\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)\n* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)\n\n\n## `allow-useless-vec-in-tests`\nWhether `useless_vec` should ignore test functions or `#[cfg(test)]`\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)\n\n\n## `allowed-dotfiles`\nAdditional dotfiles (files or directories starting with a dot) to allow\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)\n\n\n## `allowed-duplicate-crates`\nA list of crate names to allow duplicates of\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)\n\n\n## `allowed-idents-below-min-chars`\nAllowed names below the minimum allowed characters. The value `\"..\"` can be used as part of\nthe list to indicate that the configured values should be appended to the default\nconfiguration of Clippy. By default, any configuration will replace the default value.\n\n**Default Value:** `[\"i\", \"j\", \"x\", \"y\", \"z\", \"w\", \"n\"]`\n\n---\n**Affected lints:**\n* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)\n\n\n## `allowed-prefixes`\nList of prefixes to allow when determining whether an item's name ends with the module's name.\nIf the rest of an item's name is an allowed prefix (e.g. item `ToFoo` or `to_foo` in module `foo`),\nthen don't emit a warning.\n\n#### Example\n\n```toml\nallowed-prefixes = [ \"to\", \"from\" ]\n```\n\n#### Noteworthy\n\n- By default, the following prefixes are allowed: `to`, `as`, `into`, `from`, `try_into` and `try_from`\n- PascalCase variant is included automatically for each snake_case variant (e.g. if `try_into` is included,\n  `TryInto` will also be included)\n- Use `\"..\"` as part of the list to indicate that the configured values should be appended to the\ndefault configuration of Clippy. By default, any configuration will replace the default value\n\n**Default Value:** `[\"to\", \"as\", \"into\", \"from\", \"try_into\", \"try_from\"]`\n\n---\n**Affected lints:**\n* [`module_name_repetitions`](https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions)\n\n\n## `allowed-scripts`\nThe list of unicode scripts allowed to be used in the scope.\n\n**Default Value:** `[\"Latin\"]`\n\n---\n**Affected lints:**\n* [`disallowed_script_idents`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents)\n\n\n## `allowed-wildcard-imports`\nList of path segments allowed to have wildcard imports.\n\n#### Example\n\n```toml\nallowed-wildcard-imports = [ \"utils\", \"common\" ]\n```\n\n#### Noteworthy\n\n1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.\n2. Paths with any segment that containing the word 'prelude'\nare already allowed by default.\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)\n\n\n## `arithmetic-side-effects-allowed`\nSuppress checking of the passed type names in all types of operations.\n\nIf a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.\n\n#### Example\n\n```toml\narithmetic-side-effects-allowed = [\"SomeType\", \"AnotherType\"]\n```\n\n#### Noteworthy\n\nA type, say `SomeType`, listed in this configuration has the same behavior of\n`[\"SomeType\" , \"*\"], [\"*\", \"SomeType\"]` in `arithmetic_side_effects_allowed_binary`.\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)\n\n\n## `arithmetic-side-effects-allowed-binary`\nSuppress checking of the passed type pair names in binary operations like addition or\nmultiplication.\n\nSupports the \"*\" wildcard to indicate that a certain type won't trigger the lint regardless\nof the involved counterpart. For example, `[\"SomeType\", \"*\"]` or `[\"*\", \"AnotherType\"]`.\n\nPairs are asymmetric, which means that `[\"SomeType\", \"AnotherType\"]` is not the same as\n`[\"AnotherType\", \"SomeType\"]`.\n\n#### Example\n\n```toml\narithmetic-side-effects-allowed-binary = [[\"SomeType\" , \"f32\"], [\"AnotherType\", \"*\"]]\n```\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)\n\n\n## `arithmetic-side-effects-allowed-unary`\nSuppress checking of the passed type names in unary operations like \"negation\" (`-`).\n\n#### Example\n\n```toml\narithmetic-side-effects-allowed-unary = [\"SomeType\", \"AnotherType\"]\n```\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)\n\n\n## `array-size-threshold`\nThe maximum allowed size for arrays on the stack\n\n**Default Value:** `16384`\n\n---\n**Affected lints:**\n* [`large_const_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays)\n* [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays)\n\n\n## `avoid-breaking-exported-api`\nSuppress lints whenever the suggested change would cause breakage for other crates.\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`box_collection`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection)\n* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)\n* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)\n* [`linkedlist`](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist)\n* [`needless_pass_by_ref_mut`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut)\n* [`option_option`](https://rust-lang.github.io/rust-clippy/master/index.html#option_option)\n* [`owned_cow`](https://rust-lang.github.io/rust-clippy/master/index.html#owned_cow)\n* [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer)\n* [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex)\n* [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation)\n* [`ref_option`](https://rust-lang.github.io/rust-clippy/master/index.html#ref_option)\n* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn)\n* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)\n* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)\n* [`unnecessary_wraps`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps)\n* [`unused_self`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self)\n* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)\n* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)\n* [`wrong_self_convention`](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention)\n\n\n## `await-holding-invalid-types`\nThe list of types which may not be held across an await point.\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type)\n\n\n## `cargo-ignore-publish`\nFor internal testing only, ignores the current `publish` settings in the Cargo manifest.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata)\n\n\n## `check-incompatible-msrv-in-tests`\nWhether to check MSRV compatibility in `#[test]` and `#[cfg(test)]` code.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`incompatible_msrv`](https://rust-lang.github.io/rust-clippy/master/index.html#incompatible_msrv)\n\n\n## `check-inconsistent-struct-field-initializers`\nWhether to suggest reordering constructor fields when initializers are present.\n\nWarnings produced by this configuration aren't necessarily fixed by just reordering the fields. Even if the\nsuggested code would compile, it can change semantics if the initializer expressions have side effects. The\nfollowing example [from rust-clippy#11846] shows how the suggestion can run into borrow check errors:\n\n```rust\nstruct MyStruct {\n    vector: Vec<u32>,\n    length: usize\n}\nfn main() {\n    let vector = vec![1,2,3];\n    MyStruct { length: vector.len(), vector};\n}\n```\n\n[from rust-clippy#11846]: https://github.com/rust-lang/rust-clippy/issues/11846#issuecomment-1820747924\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`inconsistent_struct_constructor`](https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor)\n\n\n## `check-private-items`\nWhether to also run the listed lints on private items.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`missing_errors_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc)\n* [`missing_panics_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc)\n* [`missing_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc)\n* [`unnecessary_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc)\n\n\n## `cognitive-complexity-threshold`\nThe maximum cognitive complexity a function can have\n\n**Default Value:** `25`\n\n---\n**Affected lints:**\n* [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity)\n\n\n## `const-literal-digits-threshold`\nThe minimum digits a const float literal must have to supress the `excessive_precicion` lint\n\n**Default Value:** `30`\n\n---\n**Affected lints:**\n* [`excessive_precision`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision)\n\n\n## `disallowed-fields`\nThe list of disallowed fields, written as fully qualified paths.\n\n**Fields:**\n- `path` (required): the fully qualified path to the field that should be disallowed\n- `reason` (optional): explanation why this field is disallowed\n- `replacement` (optional): suggested alternative method\n- `allow-invalid` (optional, `false` by default): when set to `true`, it will ignore this entry\n  if the path doesn't exist, instead of emitting an error\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`disallowed_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_fields)\n\n\n## `disallowed-macros`\nThe list of disallowed macros, written as fully qualified paths.\n\n**Fields:**\n- `path` (required): the fully qualified path to the macro that should be disallowed\n- `reason` (optional): explanation why this macro is disallowed\n- `replacement` (optional): suggested alternative macro\n- `allow-invalid` (optional, `false` by default): when set to `true`, it will ignore this entry\n  if the path doesn't exist, instead of emitting an error\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`disallowed_macros`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_macros)\n\n\n## `disallowed-methods`\nThe list of disallowed methods, written as fully qualified paths.\n\n**Fields:**\n- `path` (required): the fully qualified path to the method that should be disallowed\n- `reason` (optional): explanation why this method is disallowed\n- `replacement` (optional): suggested alternative method\n- `allow-invalid` (optional, `false` by default): when set to `true`, it will ignore this entry\n  if the path doesn't exist, instead of emitting an error\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`disallowed_methods`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods)\n\n\n## `disallowed-names`\nThe list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value\n`\"..\"` can be used as part of the list to indicate that the configured values should be appended to the\ndefault configuration of Clippy. By default, any configuration will replace the default value.\n\n**Default Value:** `[\"foo\", \"baz\", \"quux\"]`\n\n---\n**Affected lints:**\n* [`disallowed_names`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names)\n\n\n## `disallowed-types`\nThe list of disallowed types, written as fully qualified paths.\n\n**Fields:**\n- `path` (required): the fully qualified path to the type that should be disallowed\n- `reason` (optional): explanation why this type is disallowed\n- `replacement` (optional): suggested alternative type\n- `allow-invalid` (optional, `false` by default): when set to `true`, it will ignore this entry\n  if the path doesn't exist, instead of emitting an error\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`disallowed_types`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types)\n\n\n## `doc-valid-idents`\nThe list of words this lint should not consider as identifiers needing ticks. The value\n`\"..\"` can be used as part of the list to indicate that the configured values should be appended to the\ndefault configuration of Clippy. By default, any configuration will replace the default value. For example:\n* `doc-valid-idents = [\"ClipPy\"]` would replace the default list with `[\"ClipPy\"]`.\n* `doc-valid-idents = [\"ClipPy\", \"..\"]` would append `ClipPy` to the default list.\n\n**Default Value:** `[\"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"MHz\", \"GHz\", \"THz\", \"AccessKit\", \"CoAP\", \"CoreFoundation\", \"CoreGraphics\", \"CoreText\", \"DevOps\", \"Direct2D\", \"Direct3D\", \"DirectWrite\", \"DirectX\", \"ECMAScript\", \"GPLv2\", \"GPLv3\", \"GitHub\", \"GitLab\", \"IPv4\", \"IPv6\", \"InfiniBand\", \"RoCE\", \"ClojureScript\", \"CoffeeScript\", \"JavaScript\", \"PostScript\", \"PureScript\", \"TypeScript\", \"PowerPC\", \"PowerShell\", \"WebAssembly\", \"NaN\", \"NaNs\", \"OAuth\", \"GraphQL\", \"OCaml\", \"OpenAL\", \"OpenDNS\", \"OpenGL\", \"OpenMP\", \"OpenSSH\", \"OpenSSL\", \"OpenStreetMap\", \"OpenTelemetry\", \"OpenType\", \"WebGL\", \"WebGL2\", \"WebGPU\", \"WebRTC\", \"WebSocket\", \"WebTransport\", \"WebP\", \"OpenExr\", \"YCbCr\", \"sRGB\", \"TensorFlow\", \"TrueType\", \"iOS\", \"macOS\", \"FreeBSD\", \"NetBSD\", \"OpenBSD\", \"NixOS\", \"TeX\", \"LaTeX\", \"BibTeX\", \"BibLaTeX\", \"MinGW\", \"CamelCase\"]`\n\n---\n**Affected lints:**\n* [`doc_markdown`](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown)\n\n\n## `enable-raw-pointer-heuristic-for-send`\nWhether to apply the raw pointer heuristic to determine if a type is `Send`.\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`non_send_fields_in_send_ty`](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty)\n\n\n## `enforce-iter-loop-reborrow`\nWhether to recommend using implicit into iter for reborrowed values.\n\n#### Example\n```no_run\nlet mut vec = vec![1, 2, 3];\nlet rmvec = &mut vec;\nfor _ in rmvec.iter() {}\nfor _ in rmvec.iter_mut() {}\n```\n\nUse instead:\n```no_run\nlet mut vec = vec![1, 2, 3];\nlet rmvec = &mut vec;\nfor _ in &*rmvec {}\nfor _ in &mut *rmvec {}\n```\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`explicit_iter_loop`](https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop)\n\n\n## `enforced-import-renames`\nThe list of imports to always rename, a fully qualified path followed by the rename.\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`missing_enforced_import_renames`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames)\n\n\n## `enum-variant-name-threshold`\nThe minimum number of enum variants for the lints about variant names to trigger\n\n**Default Value:** `3`\n\n---\n**Affected lints:**\n* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)\n\n\n## `enum-variant-size-threshold`\nThe maximum size of an enum's variant to avoid box suggestion\n\n**Default Value:** `200`\n\n---\n**Affected lints:**\n* [`large_enum_variant`](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant)\n\n\n## `excessive-nesting-threshold`\nThe maximum amount of nesting a block can reside in\n\n**Default Value:** `0`\n\n---\n**Affected lints:**\n* [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting)\n\n\n## `future-size-threshold`\nThe maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint\n\n**Default Value:** `16384`\n\n---\n**Affected lints:**\n* [`large_futures`](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures)\n\n\n## `ignore-interior-mutability`\nA list of paths to types that should be treated as if they do not contain interior mutability\n\n**Default Value:** `[\"bytes::Bytes\"]`\n\n---\n**Affected lints:**\n* [`borrow_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const)\n* [`declare_interior_mutable_const`](https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const)\n* [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond)\n* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type)\n\n\n## `inherent-impl-lint-scope`\nSets the scope (\"crate\", \"file\", or \"module\") in which duplicate inherent `impl` blocks for the same type are linted.\n\n**Default Value:** `\"crate\"`\n\n---\n**Affected lints:**\n* [`multiple_inherent_impl`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_inherent_impl)\n\n\n## `large-error-ignored`\nA list of paths to types that should be ignored as overly large `Err`-variants in a\n`Result` returned from a function\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)\n\n\n## `large-error-threshold`\nThe maximum size of the `Err`-variant in a `Result` returned from a function\n\n**Default Value:** `128`\n\n---\n**Affected lints:**\n* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)\n\n\n## `lint-commented-code`\nWhether collapsible `if` and `else if` chains are linted if they contain comments inside the parts\nthat would be collapsed.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`collapsible_else_if`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_else_if)\n* [`collapsible_if`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if)\n\n\n## `literal-representation-threshold`\nThe lower bound for linting decimal literals\n\n**Default Value:** `16384`\n\n---\n**Affected lints:**\n* [`decimal_literal_representation`](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation)\n\n\n## `matches-for-let-else`\nWhether the matches should be considered by the lint, and whether there should\nbe filtering for common types.\n\n**Default Value:** `\"WellKnownTypes\"`\n\n---\n**Affected lints:**\n* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)\n\n\n## `max-fn-params-bools`\nThe maximum number of bool parameters a function can have\n\n**Default Value:** `3`\n\n---\n**Affected lints:**\n* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools)\n\n\n## `max-include-file-size`\nThe maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes\n\n**Default Value:** `1000000`\n\n---\n**Affected lints:**\n* [`large_include_file`](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file)\n\n\n## `max-struct-bools`\nThe maximum number of bool fields a struct can have\n\n**Default Value:** `3`\n\n---\n**Affected lints:**\n* [`struct_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools)\n\n\n## `max-suggested-slice-pattern-length`\nWhen Clippy suggests using a slice pattern, this is the maximum number of elements allowed in\nthe slice pattern that is suggested. If more elements are necessary, the lint is suppressed.\nFor example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.\n\n**Default Value:** `3`\n\n---\n**Affected lints:**\n* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)\n\n\n## `max-trait-bounds`\nThe maximum number of bounds a trait can have to be linted\n\n**Default Value:** `3`\n\n---\n**Affected lints:**\n* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)\n\n\n## `min-ident-chars-threshold`\nMinimum chars an ident can have, anything below or equal to this will be linted.\n\n**Default Value:** `1`\n\n---\n**Affected lints:**\n* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)\n\n\n## `missing-docs-allow-unused`\nWhether to allow fields starting with an underscore to skip documentation requirements\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items)\n\n\n## `missing-docs-in-crate-items`\nWhether to **only** check for missing documentation in items visible within the current\ncrate. For example, `pub(crate)` items.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items)\n\n\n## `module-item-order-groupings`\nThe named groupings of different source item kinds within modules.\n\n**Default Value:** `[[\"modules\", [\"extern_crate\", \"mod\", \"foreign_mod\"]], [\"use\", [\"use\"]], [\"macros\", [\"macro\"]], [\"global_asm\", [\"global_asm\"]], [\"UPPER_SNAKE_CASE\", [\"static\", \"const\"]], [\"PascalCase\", [\"ty_alias\", \"enum\", \"struct\", \"union\", \"trait\", \"trait_alias\", \"impl\"]], [\"lower_snake_case\", [\"fn\"]]]`\n\n---\n**Affected lints:**\n* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)\n\n\n## `module-items-ordered-within-groupings`\nWhether the items within module groups should be ordered alphabetically or not.\n\nThis option can be configured to \"all\", \"none\", or a list of specific grouping names that should be checked\n(e.g. only \"enums\").\n\n**Default Value:** `\"none\"`\n\n---\n**Affected lints:**\n* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)\n\n\n## `msrv`\nThe minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`\n\n**Default Value:** `current version`\n\n---\n**Affected lints:**\n* [`allow_attributes`](https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes)\n* [`allow_attributes_without_reason`](https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason)\n* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range)\n* [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant)\n* [`assigning_clones`](https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones)\n* [`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr)\n* [`cast_abs_to_unsigned`](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned)\n* [`checked_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions)\n* [`cloned_instead_of_copied`](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied)\n* [`collapsible_match`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match)\n* [`collapsible_str_replace`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace)\n* [`deprecated_cfg_attr`](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr)\n* [`derivable_impls`](https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls)\n* [`err_expect`](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect)\n* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next)\n* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into)\n* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)\n* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)\n* [`inefficient_to_string`](https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string)\n* [`io_other_error`](https://rust-lang.github.io/rust-clippy/master/index.html#io_other_error)\n* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)\n* [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants)\n* [`len_zero`](https://rust-lang.github.io/rust-clippy/master/index.html#len_zero)\n* [`lines_filter_map_ok`](https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok)\n* [`manual_abs_diff`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_abs_diff)\n* [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits)\n* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals)\n* [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp)\n* [`manual_div_ceil`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_div_ceil)\n* [`manual_flatten`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten)\n* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one)\n* [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check)\n* [`manual_is_power_of_two`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_power_of_two)\n* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)\n* [`manual_midpoint`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_midpoint)\n* [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive)\n* [`manual_option_as_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice)\n* [`manual_pattern_char_comparison`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison)\n* [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains)\n* [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid)\n* [`manual_repeat_n`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_repeat_n)\n* [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain)\n* [`manual_slice_fill`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill)\n* [`manual_slice_size_calculation`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_size_calculation)\n* [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once)\n* [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat)\n* [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip)\n* [`manual_take`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_take)\n* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)\n* [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone)\n* [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or)\n* [`map_with_unused_argument_over_ranges`](https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges)\n* [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro)\n* [`mem_replace_option_with_some`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_option_with_some)\n* [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default)\n* [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn)\n* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)\n* [`non_std_lazy_statics`](https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics)\n* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)\n* [`or_fun_call`](https://rust-lang.github.io/rust-clippy/master/index.html#or_fun_call)\n* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)\n* [`question_mark`](https://rust-lang.github.io/rust-clippy/master/index.html#question_mark)\n* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)\n* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)\n* [`repeat_vec_with_capacity`](https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity)\n* [`same_item_push`](https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push)\n* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)\n* [`to_digit_is_some`](https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some)\n* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)\n* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)\n* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)\n* [`unchecked_time_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_time_subtraction)\n* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)\n* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations)\n* [`unnecessary_unwrap`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap)\n* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)\n* [`unused_trait_names`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names)\n* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)\n* [`zero_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr)\n\n\n## `pass-by-value-size-limit`\nThe minimum size (in bytes) to consider a type for passing by reference instead of by value.\n\n**Default Value:** `256`\n\n---\n**Affected lints:**\n* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)\n\n\n## `pub-underscore-fields-behavior`\nLint \"public\" fields in a struct that are prefixed with an underscore based on their\nexported visibility, or whether they are marked as \"pub\".\n\n**Default Value:** `\"PubliclyExported\"`\n\n---\n**Affected lints:**\n* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)\n\n\n## `recursive-self-in-type-definitions`\nWhether the type itself in a struct or enum should be replaced with `Self` when encountering recursive types.\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)\n\n\n## `semicolon-inside-block-ignore-singleline`\nWhether to lint only if it's multiline.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`semicolon_inside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block)\n\n\n## `semicolon-outside-block-ignore-multiline`\nWhether to lint only if it's singleline.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`semicolon_outside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block)\n\n\n## `single-char-binding-names-threshold`\nThe maximum number of single char bindings a scope may have\n\n**Default Value:** `4`\n\n---\n**Affected lints:**\n* [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names)\n\n\n## `source-item-ordering`\nWhich kind of elements should be ordered internally, possible values being `enum`, `impl`, `module`, `struct`, `trait`.\n\n**Default Value:** `[\"enum\", \"impl\", \"module\", \"struct\", \"trait\"]`\n\n---\n**Affected lints:**\n* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)\n\n\n## `stack-size-threshold`\nThe maximum allowed stack size for functions in bytes\n\n**Default Value:** `512000`\n\n---\n**Affected lints:**\n* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames)\n\n\n## `standard-macro-braces`\nEnforce the named macros always use the braces specified.\n\nA `MacroMatcher` can be added like so `{ name = \"macro_name\", brace = \"(\" }`. If the macro\ncould be used with a full path two `MacroMatcher`s have to be added one with the full path\n`crate_name::macro_name` and one with just the macro name.\n\n**Default Value:** `[]`\n\n---\n**Affected lints:**\n* [`nonstandard_macro_braces`](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces)\n\n\n## `struct-field-name-threshold`\nThe minimum number of struct fields for the lints about field names to trigger\n\n**Default Value:** `3`\n\n---\n**Affected lints:**\n* [`struct_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names)\n\n\n## `suppress-restriction-lint-in-const`\nWhether to suppress a restriction lint in constant code. In same\ncases the restructured operation might not be unavoidable, as the\nsuggested counterparts are unavailable in constant code. This\nconfiguration will cause restriction lints to trigger even\nif no suggestion can be made.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing)\n\n\n## `too-large-for-stack`\nThe maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap\n\n**Default Value:** `200`\n\n---\n**Affected lints:**\n* [`boxed_local`](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local)\n* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)\n\n\n## `too-many-arguments-threshold`\nThe maximum number of argument a function or method can have\n\n**Default Value:** `7`\n\n---\n**Affected lints:**\n* [`too_many_arguments`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments)\n\n\n## `too-many-lines-threshold`\nThe maximum number of lines a function or method can have\n\n**Default Value:** `100`\n\n---\n**Affected lints:**\n* [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)\n\n\n## `trait-assoc-item-kinds-order`\nThe order of associated items in traits.\n\n**Default Value:** `[\"const\", \"type\", \"fn\"]`\n\n---\n**Affected lints:**\n* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)\n\n\n## `trivial-copy-size-limit`\nThe maximum size (in bytes) to consider a `Copy` type for passing by value instead of by\nreference.\n\n**Default Value:** `target_pointer_width`\n\n---\n**Affected lints:**\n* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)\n\n\n## `type-complexity-threshold`\nThe maximum complexity a type can have\n\n**Default Value:** `250`\n\n---\n**Affected lints:**\n* [`type_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity)\n\n\n## `unnecessary-box-size`\nThe byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint\n\n**Default Value:** `128`\n\n---\n**Affected lints:**\n* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)\n\n\n## `unreadable-literal-lint-fractions`\nShould the fraction of a decimal be linted to include separators.\n\n**Default Value:** `true`\n\n---\n**Affected lints:**\n* [`unreadable_literal`](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal)\n\n\n## `upper-case-acronyms-aggressive`\nEnables verbose mode. Triggers if there is more than one uppercase char next to each other\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)\n\n\n## `vec-box-size-threshold`\nThe size of the boxed type in bytes, where boxing in a `Vec` is allowed\n\n**Default Value:** `4096`\n\n---\n**Affected lints:**\n* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)\n\n\n## `verbose-bit-mask-threshold`\nThe maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'\n\n**Default Value:** `1`\n\n---\n**Affected lints:**\n* [`verbose_bit_mask`](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask)\n\n\n## `warn-on-all-wildcard-imports`\nWhether to emit warnings on all wildcard imports, including those from `prelude`, from `super` in tests,\nor for `pub use` reexports.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)\n\n\n## `warn-unsafe-macro-metavars-in-private-macros`\nWhether to also emit warnings for unsafe blocks with metavariable expansions in **private** macros.\n\n**Default Value:** `false`\n\n---\n**Affected lints:**\n* [`macro_metavars_in_unsafe`](https://rust-lang.github.io/rust-clippy/master/index.html#macro_metavars_in_unsafe)\n"
  },
  {
    "path": "book/src/lints.md",
    "content": "# Clippy's Lints\n\nClippy offers a bunch of additional lints, to help its users write more correct\nand idiomatic Rust code. A full list of all lints, that can be filtered by\ncategory, lint level or keywords, can be found in the [Clippy lint\ndocumentation].\n\nThis chapter will give an overview of the different lint categories, which kind\nof lints they offer and recommended actions when you should see a lint out of\nthat category. For examples, see the [Clippy lint documentation] and filter by\ncategory.\n\nThe different lint groups were defined in the [Clippy 1.0 RFC].\n\n## Correctness\n\nThe `clippy::correctness` group is the only lint group in Clippy which lints are\ndeny-by-default and abort the compilation when triggered. This is for good\nreason: If you see a `correctness` lint, it means that your code is outright\nwrong or useless, and you should try to fix it.\n\nLints in this category are carefully picked and should be free of false\npositives. So just `#[allow]`ing those lints is not recommended.\n\n## Suspicious\n\nThe `clippy::suspicious` group is similar to the correctness lints in that it\ncontains lints that trigger on code that is really _sus_ and should be fixed. As\nopposed to correctness lints, it might be possible that the linted code is\nintentionally written like it is.\n\nIt is still recommended to fix code that is linted by lints out of this group\ninstead of `#[allow]`ing the lint. In case you intentionally have written code\nthat offends the lint you should specifically and locally `#[allow]` the lint\nand add give a reason why the code is correct as written.\n\n## Complexity\n\nThe `clippy::complexity` group offers lints that give you suggestions on how to\nsimplify your code. It mostly focuses on code that can be written in a shorter\nand more readable way, while preserving the semantics.\n\nIf you should see a complexity lint, it usually means that you can remove or\nreplace some code, and it is recommended to do so. However, if you need the more\ncomplex code for some expressiveness reason, it is recommended to allow\ncomplexity lints on a case-by-case basis.\n\n## Perf\n\nThe `clippy::perf` group gives you suggestions on how you can increase the\nperformance of your code. Those lints are mostly about code that the compiler\ncan't trivially optimize, but has to be written in a slightly different way to\nmake the optimizer job easier.\n\nPerf lints are usually easy to apply, and it is recommended to do so.\n\n## Style\n\nThe `clippy::style` group is mostly about writing idiomatic code. Because style\nis subjective, this lint group is the most opinionated warn-by-default group in\nClippy.\n\nIf you see a style lint, applying the suggestion usually makes your code more\nreadable and idiomatic. But because we know that this is opinionated, feel free\nto sprinkle `#[allow]`s for style lints in your code or `#![allow]` a style lint\non your whole crate if you disagree with the suggested style completely.\n\n## Pedantic\n\nThe `clippy::pedantic` group makes Clippy even more _pedantic_. You can enable\nthe whole group with `#![warn(clippy::pedantic)]` in the `lib.rs`/`main.rs` of\nyour crate. This lint group is for Clippy power users that want an in depth\ncheck of their code.\n\n> _Note:_ Instead of enabling the whole group (like Clippy itself does), you may\n> want to cherry-pick lints out of the pedantic group.\n\nIf you enable this group, expect to also use `#[allow]` attributes generously\nthroughout your code. Lints in this group are designed to be pedantic and false\npositives sometimes are intentional in order to prevent false negatives.\n\n## Restriction\n\nThe `clippy::restriction` group contains lints that will _restrict_ you from\nusing certain parts of the Rust language. It is **not** recommended to enable\nthe whole group, but rather cherry-pick lints that are useful for your code base\nand your use case.\n\n> _Note:_ Clippy will produce a warning if it finds a\n> `#![warn(clippy::restriction)]` attribute in your code!\n\nLints from this group will restrict you in some way. If you enable a restriction\nlint for your crate it is recommended to also fix code that this lint triggers\non. However, those lints are really strict by design, and you might want to\n`#[allow]` them in some special cases, with a comment justifying that.\n\n## Cargo\n\nThe `clippy::cargo` group gives you suggestions on how to improve your\n`Cargo.toml` file. This might be especially interesting if you want to publish\nyour crate and are not sure if you have all useful information in your\n`Cargo.toml`.\n\n## Nursery\n\nThe `clippy::nursery` group contains lints which are buggy or need more work. It is **not** \nrecommended to enable the whole group, but rather cherry-pick lints that are useful for your \ncode base and your use case. \n\n## Deprecated\n\nThe `clippy::deprecated` is empty lints that exist to ensure that `#[allow(lintname)]` still \ncompiles after the lint was deprecated. Deprecation \"removes\" lints by removing their \nfunctionality and marking them as deprecated, which may cause further warnings but cannot \ncause a compiler error.\n\n[Clippy lint documentation]: https://rust-lang.github.io/rust-clippy/\n[Clippy 1.0 RFC]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#lint-audit-and-categories\n"
  },
  {
    "path": "book/src/usage.md",
    "content": "# Usage\n\nThis chapter describes how to use Clippy to get the most out of it. Clippy can\nbe used as a `cargo` subcommand or, like `rustc`, directly with the\n`clippy-driver` binary.\n\n> _Note:_ This chapter assumes that you have Clippy installed already. If you're\n> not sure, take a look at the [Installation] chapter.\n\n## Cargo subcommand\n\nThe easiest and most common way to run Clippy is through `cargo`. To do that,\njust run\n\n```bash\ncargo clippy\n```\n\n### Lint configuration\n\nThe above command will run the default set of lints, which are included in the\nlint group `clippy::all`. You might want to use even more lints, or you may not\nagree with every Clippy lint, and for that there are ways to configure lint\nlevels.\n\n> _Note:_ Clippy is meant to be used with a generous sprinkling of\n> `#[allow(..)]`s through your code. So if you disagree with a lint, don't feel\n> bad disabling them for parts of your code or the whole project.\n\n#### Command line\n\nYou can configure lint levels on the command line by adding\n`-A/W/D clippy::lint_name` like this:\n\n```bash\ncargo clippy -- -Aclippy::style -Wclippy::box_default -Dclippy::perf\n```\n\nFor [CI] all warnings can be elevated to errors which will in turn fail\nthe build and cause Clippy to exit with a code other than `0`.\n\n```\ncargo clippy -- -Dwarnings\n```\n\n> _Note:_ Adding `-D warnings` will cause your build to fail if **any** warnings\n> are found in your code. That includes warnings found by rustc (e.g.\n> `dead_code`, etc.).\n\nFor more information on configuring lint levels, see the [rustc documentation].\n\n[rustc documentation]: https://doc.rust-lang.org/rustc/lints/levels.html#configuring-warning-levels\n\n#### Even more lints\n\nClippy has lint groups which are allow-by-default. This means, that you will\nhave to enable the lints in those groups manually.\n\nFor a full list of all lints with their description and examples, please refer\nto [Clippy's lint list]. The two most important allow-by-default groups are\ndescribed below:\n\n[Clippy's lint list]: https://rust-lang.github.io/rust-clippy/master/index.html\n\n##### `clippy::pedantic`\n\nThe first group is the `pedantic` group. This group contains really opinionated\nlints, that may have some intentional false positives in order to prevent false\nnegatives. So while this group is ready to be used in production, you can expect\nto sprinkle multiple `#[allow(..)]`s in your code. If you find any false\npositives, you're still welcome to report them to us for future improvements.\n\n> FYI: Clippy uses the whole group to lint itself.\n\n##### `clippy::restriction`\n\nThe second group is the `restriction` group. This group contains lints that\n\"restrict\" the language in some way. For example the `clippy::unwrap` lint from\nthis group won't allow you to use `.unwrap()` in your code. You may want to look\nthrough the lints in this group and enable the ones that fit your need.\n\n> _Note:_ You shouldn't enable the whole lint group, but cherry-pick lints from\n> this group. Some lints in this group will even contradict other Clippy lints!\n\n#### Too many lints\n\nThe most opinionated warn-by-default group of Clippy is the `clippy::style`\ngroup. Some people prefer to disable this group completely and then cherry-pick\nsome lints they like from this group. The same is of course possible with every\nother of Clippy's lint groups.\n\n> _Note:_ We try to keep the warn-by-default groups free from false positives\n> (FP). If you find that a lint wrongly triggers, please report it in an issue\n> (if there isn't an issue for that FP already)\n\n#### Source Code\n\nYou can configure lint levels in source code the same way you can configure\n`rustc` lints:\n\n```rust,ignore\n#![allow(clippy::style)]\n\n#[warn(clippy::box_default)]\nfn main() {\n    let _ = Box::<String>::new(Default::default());\n    // ^ warning: `Box::new(_)` of default value\n}\n```\n\n### Automatically applying Clippy suggestions\n\nClippy can automatically apply some lint suggestions, just like the compiler. Note that `--fix` implies\n`--all-targets`, so it can fix as much code as it can.\n\n```terminal\ncargo clippy --fix\n```\n\n### Workspaces\n\nAll the usual workspace options should work with Clippy. For example the\nfollowing command will run Clippy on the `example` crate in your workspace:\n\n```terminal\ncargo clippy -p example\n```\n\nAs with `cargo check`, this includes dependencies that are members of the\nworkspace, like path dependencies. If you want to run Clippy **only** on the\ngiven crate, use the `--no-deps` option like this:\n\n```terminal\ncargo clippy -p example -- --no-deps\n```\n\n## Using Clippy without `cargo`: `clippy-driver`\n\nClippy can also be used in projects that do not use cargo. To do so, run\n`clippy-driver` with the same arguments you use for `rustc`. For example:\n\n```terminal\nclippy-driver --edition 2018 -Cpanic=abort foo.rs\n```\n\n> _Note:_ `clippy-driver` is designed for running Clippy and should not be used\n> as a general replacement for `rustc`. `clippy-driver` may produce artifacts\n> that are not optimized as expected, for example.\n\n[Installation]: installation.md\n[CI]: continuous_integration/index.md\n"
  },
  {
    "path": "build.rs",
    "content": "fn main() {\n    // Forward the profile to the main compilation\n    println!(\"cargo:rustc-env=PROFILE={}\", std::env::var(\"PROFILE\").unwrap());\n    // Don't rebuild even if nothing changed\n    println!(\"cargo:rerun-if-changed=build.rs\");\n    rustc_tools_util::setup_version_info!();\n}\n"
  },
  {
    "path": "clippy.toml",
    "content": "avoid-breaking-exported-api = false\n\ncheck-inconsistent-struct-field-initializers = true\n\nlint-commented-code = true\n\n[[disallowed-methods]]\npath = \"rustc_lint::context::LintContext::lint\"\nreason = \"this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead\"\n\n[[disallowed-methods]]\npath = \"rustc_lint::context::LintContext::span_lint\"\nreason = \"this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead\"\n\n[[disallowed-methods]]\npath = \"rustc_middle::ty::context::TyCtxt::node_span_lint\"\nreason = \"this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead\"\n"
  },
  {
    "path": "clippy_config/Cargo.toml",
    "content": "[package]\nname = \"clippy_config\"\nversion = \"0.1.96\"\nedition = \"2024\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\nclippy_utils = { path = \"../clippy_utils\" }\nitertools = \"0.12\"\nserde = { version = \"1.0\", features = [\"derive\"] }\ntoml = \"0.7.3\"\n\n[dev-dependencies]\nwalkdir = \"2.3\"\n\n[package.metadata.rust-analyzer]\n# This crate uses #[feature(rustc_private)]\nrustc_private = true\n"
  },
  {
    "path": "clippy_config/src/conf.rs",
    "content": "use crate::ClippyConfiguration;\nuse crate::types::{\n    DisallowedPath, DisallowedPathWithoutReplacement, InherentImplLintScope, MacroMatcher, MatchLintBehaviour,\n    PubUnderscoreFieldsBehaviour, Rename, SourceItemOrdering, SourceItemOrderingCategory,\n    SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind, SourceItemOrderingTraitAssocItemKind,\n    SourceItemOrderingTraitAssocItemKinds, SourceItemOrderingWithinModuleItemGroupings,\n};\nuse clippy_utils::msrvs::Msrv;\nuse itertools::Itertools;\nuse rustc_errors::Applicability;\nuse rustc_session::Session;\nuse rustc_span::edit_distance::edit_distance;\nuse rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};\nuse serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor};\nuse serde::{Deserialize, Deserializer, Serialize};\nuse std::collections::HashMap;\nuse std::fmt::{Debug, Display, Formatter};\nuse std::ops::Range;\nuse std::path::PathBuf;\nuse std::str::FromStr;\nuse std::sync::OnceLock;\nuse std::{cmp, env, fmt, fs, io};\n\n#[rustfmt::skip]\nconst DEFAULT_DOC_VALID_IDENTS: &[&str] = &[\n    \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\",\n    \"MHz\", \"GHz\", \"THz\",\n    \"AccessKit\",\n    \"CoAP\", \"CoreFoundation\", \"CoreGraphics\", \"CoreText\",\n    \"DevOps\",\n    \"Direct2D\", \"Direct3D\", \"DirectWrite\", \"DirectX\",\n    \"ECMAScript\",\n    \"GPLv2\", \"GPLv3\",\n    \"GitHub\", \"GitLab\",\n    \"IPv4\", \"IPv6\",\n    \"InfiniBand\", \"RoCE\",\n    \"ClojureScript\", \"CoffeeScript\", \"JavaScript\", \"PostScript\", \"PureScript\", \"TypeScript\",\n    \"PowerPC\", \"PowerShell\", \"WebAssembly\",\n    \"NaN\", \"NaNs\",\n    \"OAuth\", \"GraphQL\",\n    \"OCaml\",\n    \"OpenAL\", \"OpenDNS\", \"OpenGL\", \"OpenMP\", \"OpenSSH\", \"OpenSSL\", \"OpenStreetMap\", \"OpenTelemetry\",\n    \"OpenType\",\n    \"WebGL\", \"WebGL2\", \"WebGPU\", \"WebRTC\", \"WebSocket\", \"WebTransport\",\n    \"WebP\", \"OpenExr\", \"YCbCr\", \"sRGB\",\n    \"TensorFlow\",\n    \"TrueType\",\n    \"iOS\", \"macOS\", \"FreeBSD\", \"NetBSD\", \"OpenBSD\", \"NixOS\",\n    \"TeX\", \"LaTeX\", \"BibTeX\", \"BibLaTeX\",\n    \"MinGW\",\n    \"CamelCase\",\n];\nconst DEFAULT_DISALLOWED_NAMES: &[&str] = &[\"foo\", \"baz\", \"quux\"];\nconst DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &[\"i\", \"j\", \"x\", \"y\", \"z\", \"w\", \"n\"];\nconst DEFAULT_ALLOWED_PREFIXES: &[&str] = &[\"to\", \"as\", \"into\", \"from\", \"try_into\", \"try_from\"];\nconst DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS: &[&str] =\n    &[\"core::convert::From\", \"core::convert::TryFrom\", \"core::str::FromStr\"];\nconst DEFAULT_MODULE_ITEM_ORDERING_GROUPS: &[(&str, &[SourceItemOrderingModuleItemKind])] = {\n    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.\n    use SourceItemOrderingModuleItemKind::*;\n    &[\n        (\"modules\", &[ExternCrate, Mod, ForeignMod]),\n        (\"use\", &[Use]),\n        (\"macros\", &[Macro]),\n        (\"global_asm\", &[GlobalAsm]),\n        (\"UPPER_SNAKE_CASE\", &[Static, Const]),\n        (\"PascalCase\", &[TyAlias, Enum, Struct, Union, Trait, TraitAlias, Impl]),\n        (\"lower_snake_case\", &[Fn]),\n    ]\n};\nconst DEFAULT_TRAIT_ASSOC_ITEM_KINDS_ORDER: &[SourceItemOrderingTraitAssocItemKind] = {\n    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.\n    use SourceItemOrderingTraitAssocItemKind::*;\n    &[Const, Type, Fn]\n};\nconst DEFAULT_SOURCE_ITEM_ORDERING: &[SourceItemOrderingCategory] = {\n    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.\n    use SourceItemOrderingCategory::*;\n    &[Enum, Impl, Module, Struct, Trait]\n};\n\n/// Conf with parse errors\n#[derive(Default)]\nstruct TryConf {\n    conf: Conf,\n    value_spans: HashMap<String, Range<usize>>,\n    errors: Vec<ConfError>,\n    warnings: Vec<ConfError>,\n}\n\nimpl TryConf {\n    fn from_toml_error(file: &SourceFile, error: &toml::de::Error) -> Self {\n        Self {\n            conf: Conf::default(),\n            value_spans: HashMap::default(),\n            errors: vec![ConfError::from_toml(file, error)],\n            warnings: vec![],\n        }\n    }\n}\n\n#[derive(Debug)]\nstruct ConfError {\n    message: String,\n    suggestion: Option<Suggestion>,\n    span: Span,\n}\n\nimpl ConfError {\n    fn from_toml(file: &SourceFile, error: &toml::de::Error) -> Self {\n        let span = error.span().unwrap_or(0..file.normalized_source_len.0 as usize);\n        Self::spanned(file, error.message(), None, span)\n    }\n\n    fn spanned(\n        file: &SourceFile,\n        message: impl Into<String>,\n        suggestion: Option<Suggestion>,\n        span: Range<usize>,\n    ) -> Self {\n        Self {\n            message: message.into(),\n            suggestion,\n            span: span_from_toml_range(file, span),\n        }\n    }\n}\n\n// Remove code tags and code behind '# 's, as they are not needed for the lint docs and --explain\npub fn sanitize_explanation(raw_docs: &str) -> String {\n    // Remove tags and hidden code:\n    let mut explanation = String::with_capacity(128);\n    let mut in_code = false;\n    for line in raw_docs.lines() {\n        let line = line.strip_prefix(' ').unwrap_or(line);\n\n        if let Some(lang) = line.strip_prefix(\"```\") {\n            let tag = lang.split_once(',').map_or(lang, |(left, _)| left);\n            if !in_code && matches!(tag, \"\" | \"rust\" | \"ignore\" | \"should_panic\" | \"no_run\" | \"compile_fail\") {\n                explanation += \"```rust\\n\";\n            } else {\n                explanation += line;\n                explanation.push('\\n');\n            }\n            in_code = !in_code;\n        } else if !(in_code && line.starts_with(\"# \")) {\n            explanation += line;\n            explanation.push('\\n');\n        }\n    }\n\n    explanation\n}\n\nmacro_rules! wrap_option {\n    () => {\n        None\n    };\n    ($x:literal) => {\n        Some($x)\n    };\n}\n\nmacro_rules! default_text {\n    ($value:expr) => {{\n        let mut text = String::new();\n        $value.serialize(toml::ser::ValueSerializer::new(&mut text)).unwrap();\n        text\n    }};\n    ($value:expr, $override:expr) => {\n        $override.to_string()\n    };\n}\n\nmacro_rules! deserialize {\n    ($map:expr, $ty:ty, $errors:expr, $file:expr) => {{\n        let raw_value = $map.next_value::<toml::Spanned<toml::Value>>()?;\n        let value_span = raw_value.span();\n        let value = match <$ty>::deserialize(raw_value.into_inner()) {\n            Err(e) => {\n                $errors.push(ConfError::spanned(\n                    $file,\n                    e.to_string().replace('\\n', \" \").trim(),\n                    None,\n                    value_span,\n                ));\n                continue;\n            },\n            Ok(value) => value,\n        };\n        (value, value_span)\n    }};\n\n    ($map:expr, $ty:ty, $errors:expr, $file:expr, $replacements_allowed:expr) => {{\n        let array = $map.next_value::<Vec<toml::Spanned<toml::Value>>>()?;\n        let mut disallowed_paths_span = Range {\n            start: usize::MAX,\n            end: usize::MIN,\n        };\n        let mut disallowed_paths = Vec::new();\n        for raw_value in array {\n            let value_span = raw_value.span();\n            let mut disallowed_path = match DisallowedPath::<$replacements_allowed>::deserialize(raw_value.into_inner())\n            {\n                Err(e) => {\n                    $errors.push(ConfError::spanned(\n                        $file,\n                        e.to_string().replace('\\n', \" \").trim(),\n                        None,\n                        value_span,\n                    ));\n                    continue;\n                },\n                Ok(disallowed_path) => disallowed_path,\n            };\n            disallowed_paths_span = union(&disallowed_paths_span, &value_span);\n            disallowed_path.set_span(span_from_toml_range($file, value_span));\n            disallowed_paths.push(disallowed_path);\n        }\n        (disallowed_paths, disallowed_paths_span)\n    }};\n}\n\nmacro_rules! define_Conf {\n    ($(\n        $(#[doc = $doc:literal])+\n        $(#[conf_deprecated($dep:literal, $new_conf:ident)])?\n        $(#[default_text = $default_text:expr])?\n        $(#[disallowed_paths_allow_replacements = $replacements_allowed:expr])?\n        $(#[lints($($for_lints:ident),* $(,)?)])?\n        $name:ident: $ty:ty = $default:expr,\n    )*) => {\n        /// Clippy lint configuration\n        pub struct Conf {\n            $($(#[cfg_attr(doc, doc = $doc)])+ pub $name: $ty,)*\n        }\n\n        mod defaults {\n            use super::*;\n            $(pub fn $name() -> $ty { $default })*\n        }\n\n        impl Default for Conf {\n            fn default() -> Self {\n                Self { $($name: defaults::$name(),)* }\n            }\n        }\n\n        #[derive(Deserialize)]\n        #[serde(field_identifier, rename_all = \"kebab-case\")]\n        #[expect(non_camel_case_types)]\n        enum Field { $($name,)* third_party, }\n\n        struct ConfVisitor<'a>(&'a SourceFile);\n\n        impl<'de> Visitor<'de> for ConfVisitor<'_> {\n            type Value = TryConf;\n\n            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n                formatter.write_str(\"Conf\")\n            }\n\n            fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error> where V: MapAccess<'de> {\n                let mut value_spans = HashMap::new();\n                let mut errors = Vec::new();\n                let mut warnings = Vec::new();\n\n                // Declare a local variable for each field available to a configuration file.\n                $(let mut $name = None;)*\n\n                // could get `Field` here directly, but get `String` first for diagnostics\n                while let Some(name) = map.next_key::<toml::Spanned<String>>()? {\n                    let field = match Field::deserialize(name.get_ref().as_str().into_deserializer()) {\n                        Err(e) => {\n                            let e: FieldError = e;\n                            errors.push(ConfError::spanned(self.0, e.error, e.suggestion, name.span()));\n                            continue;\n                        }\n                        Ok(field) => field\n                    };\n\n                    match field {\n                        $(Field::$name => {\n                            // Is this a deprecated field, i.e., is `$dep` set? If so, push a warning.\n                            $(warnings.push(ConfError::spanned(self.0, format!(\"deprecated field `{}`. {}\", name.get_ref(), $dep), None, name.span()));)?\n                            let (value, value_span) =\n                                deserialize!(map, $ty, errors, self.0 $(, $replacements_allowed)?);\n                            // Was this field set previously?\n                            if $name.is_some() {\n                                errors.push(ConfError::spanned(self.0, format!(\"duplicate field `{}`\", name.get_ref()), None, name.span()));\n                                continue;\n                            }\n                            $name = Some(value);\n                            value_spans.insert(name.get_ref().as_str().to_string(), value_span);\n                            // If this is a deprecated field, was the new field (`$new_conf`) set previously?\n                            // Note that `$new_conf` is one of the defined `$name`s.\n                            $(match $new_conf {\n                                Some(_) => errors.push(ConfError::spanned(self.0, concat!(\n                                    \"duplicate field `\", stringify!($new_conf),\n                                    \"` (provided as `\", stringify!($name), \"`)\"\n                                ), None, name.span())),\n                                None => $new_conf = $name.clone(),\n                            })?\n                        })*\n                        // ignore contents of the third_party key\n                        Field::third_party => drop(map.next_value::<IgnoredAny>())\n                    }\n                }\n                let conf = Conf { $($name: $name.unwrap_or_else(defaults::$name),)* };\n                Ok(TryConf { conf, value_spans, errors, warnings })\n            }\n        }\n\n        pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {\n            vec![$(\n                ClippyConfiguration {\n                    name: stringify!($name).replace('_', \"-\"),\n                    default: default_text!(defaults::$name() $(, $default_text)?),\n                    lints: &[$($(stringify!($for_lints)),*)?],\n                    doc: concat!($($doc, '\\n',)*),\n                    deprecation_reason: wrap_option!($($dep)?)\n                },\n            )*]\n        }\n    };\n}\n\nfn union(x: &Range<usize>, y: &Range<usize>) -> Range<usize> {\n    Range {\n        start: cmp::min(x.start, y.start),\n        end: cmp::max(x.end, y.end),\n    }\n}\n\nfn span_from_toml_range(file: &SourceFile, span: Range<usize>) -> Span {\n    Span::new(\n        file.start_pos + BytePos::from_usize(span.start),\n        file.start_pos + BytePos::from_usize(span.end),\n        SyntaxContext::root(),\n        None,\n    )\n}\n\ndefine_Conf! {\n    /// Which crates to allow absolute paths from\n    #[lints(absolute_paths)]\n    absolute_paths_allowed_crates: Vec<String> = Vec::new(),\n    /// The maximum number of segments a path can have before being linted, anything above this will\n    /// be linted.\n    #[lints(absolute_paths)]\n    absolute_paths_max_segments: u64 = 2,\n    /// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block\n    #[lints(undocumented_unsafe_blocks)]\n    accept_comment_above_attributes: bool = true,\n    /// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block\n    #[lints(undocumented_unsafe_blocks)]\n    accept_comment_above_statement: bool = true,\n    /// Don't lint when comparing the result of a modulo operation to zero.\n    #[lints(modulo_arithmetic)]\n    allow_comparison_to_zero: bool = true,\n    /// Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`\n    #[lints(dbg_macro)]\n    allow_dbg_in_tests: bool = false,\n    /// Whether an item should be allowed to have the same name as its containing module\n    #[lints(module_name_repetitions)]\n    allow_exact_repetitions: bool = true,\n    /// Whether `expect` should be allowed in code always evaluated at compile time\n    #[lints(expect_used)]\n    allow_expect_in_consts: bool = true,\n    /// Whether `expect` should be allowed in test functions or `#[cfg(test)]`\n    #[lints(expect_used)]\n    allow_expect_in_tests: bool = false,\n    /// Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]`\n    #[lints(indexing_slicing)]\n    allow_indexing_slicing_in_tests: bool = false,\n    /// Whether functions inside `#[cfg(test)]` modules or test functions should be checked.\n    #[lints(large_stack_frames)]\n    allow_large_stack_frames_in_tests: bool = true,\n    /// Whether to allow mixed uninlined format args, e.g. `format!(\"{} {}\", a, foo.bar)`\n    #[lints(uninlined_format_args)]\n    allow_mixed_uninlined_format_args: bool = true,\n    /// Whether to allow `r#\"\"#` when `r\"\"` can be used\n    #[lints(needless_raw_string_hashes)]\n    allow_one_hash_in_raw_strings: bool = false,\n    /// Whether `panic` should be allowed in test functions or `#[cfg(test)]`\n    #[lints(panic)]\n    allow_panic_in_tests: bool = false,\n    /// Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`\n    #[lints(print_stderr, print_stdout)]\n    allow_print_in_tests: bool = false,\n    /// Whether to allow module inception if it's not public.\n    #[lints(module_inception)]\n    allow_private_module_inception: bool = false,\n    /// List of trait paths to ignore when checking renamed function parameters.\n    ///\n    /// #### Example\n    ///\n    /// ```toml\n    /// allow-renamed-params-for = [ \"std::convert::From\" ]\n    /// ```\n    ///\n    /// #### Noteworthy\n    ///\n    /// - By default, the following traits are ignored: `From`, `TryFrom`, `FromStr`\n    /// - `\"..\"` can be used as part of the list to indicate that the configured values should be appended to the\n    /// default configuration of Clippy. By default, any configuration will replace the default value.\n    #[lints(renamed_function_params)]\n    allow_renamed_params_for: Vec<String> =\n        DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS.iter().map(ToString::to_string).collect(),\n    /// Whether `unwrap` should be allowed in code always evaluated at compile time\n    #[lints(unwrap_used)]\n    allow_unwrap_in_consts: bool = true,\n    /// Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`\n    #[lints(unwrap_used)]\n    allow_unwrap_in_tests: bool = false,\n    /// List of types to allow `unwrap()` and `expect()` on.\n    ///\n    /// #### Example\n    ///\n    /// ```toml\n    /// allow-unwrap-types = [ \"std::sync::LockResult\" ]\n    /// ```\n    #[lints(expect_used, unwrap_used)]\n    allow_unwrap_types: Vec<String> = Vec::new(),\n    /// Whether `useless_vec` should ignore test functions or `#[cfg(test)]`\n    #[lints(useless_vec)]\n    allow_useless_vec_in_tests: bool = false,\n    /// Additional dotfiles (files or directories starting with a dot) to allow\n    #[lints(path_ends_with_ext)]\n    allowed_dotfiles: Vec<String> = Vec::default(),\n    /// A list of crate names to allow duplicates of\n    #[lints(multiple_crate_versions)]\n    allowed_duplicate_crates: Vec<String> = Vec::new(),\n    /// Allowed names below the minimum allowed characters. The value `\"..\"` can be used as part of\n    /// the list to indicate that the configured values should be appended to the default\n    /// configuration of Clippy. By default, any configuration will replace the default value.\n    #[lints(min_ident_chars)]\n    allowed_idents_below_min_chars: Vec<String> =\n        DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string).collect(),\n    /// List of prefixes to allow when determining whether an item's name ends with the module's name.\n    /// If the rest of an item's name is an allowed prefix (e.g. item `ToFoo` or `to_foo` in module `foo`),\n    /// then don't emit a warning.\n    ///\n    /// #### Example\n    ///\n    /// ```toml\n    /// allowed-prefixes = [ \"to\", \"from\" ]\n    /// ```\n    ///\n    /// #### Noteworthy\n    ///\n    /// - By default, the following prefixes are allowed: `to`, `as`, `into`, `from`, `try_into` and `try_from`\n    /// - PascalCase variant is included automatically for each snake_case variant (e.g. if `try_into` is included,\n    ///   `TryInto` will also be included)\n    /// - Use `\"..\"` as part of the list to indicate that the configured values should be appended to the\n    /// default configuration of Clippy. By default, any configuration will replace the default value\n    #[lints(module_name_repetitions)]\n    allowed_prefixes: Vec<String> = DEFAULT_ALLOWED_PREFIXES.iter().map(ToString::to_string).collect(),\n    /// The list of unicode scripts allowed to be used in the scope.\n    #[lints(disallowed_script_idents)]\n    allowed_scripts: Vec<String> = vec![\"Latin\".to_string()],\n    /// List of path segments allowed to have wildcard imports.\n    ///\n    /// #### Example\n    ///\n    /// ```toml\n    /// allowed-wildcard-imports = [ \"utils\", \"common\" ]\n    /// ```\n    ///\n    /// #### Noteworthy\n    ///\n    /// 1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.\n    /// 2. Paths with any segment that containing the word 'prelude'\n    /// are already allowed by default.\n    #[lints(wildcard_imports)]\n    allowed_wildcard_imports: Vec<String> = Vec::new(),\n    /// Suppress checking of the passed type names in all types of operations.\n    ///\n    /// If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.\n    ///\n    /// #### Example\n    ///\n    /// ```toml\n    /// arithmetic-side-effects-allowed = [\"SomeType\", \"AnotherType\"]\n    /// ```\n    ///\n    /// #### Noteworthy\n    ///\n    /// A type, say `SomeType`, listed in this configuration has the same behavior of\n    /// `[\"SomeType\" , \"*\"], [\"*\", \"SomeType\"]` in `arithmetic_side_effects_allowed_binary`.\n    #[lints(arithmetic_side_effects)]\n    arithmetic_side_effects_allowed: Vec<String> = <_>::default(),\n    /// Suppress checking of the passed type pair names in binary operations like addition or\n    /// multiplication.\n    ///\n    /// Supports the \"*\" wildcard to indicate that a certain type won't trigger the lint regardless\n    /// of the involved counterpart. For example, `[\"SomeType\", \"*\"]` or `[\"*\", \"AnotherType\"]`.\n    ///\n    /// Pairs are asymmetric, which means that `[\"SomeType\", \"AnotherType\"]` is not the same as\n    /// `[\"AnotherType\", \"SomeType\"]`.\n    ///\n    /// #### Example\n    ///\n    /// ```toml\n    /// arithmetic-side-effects-allowed-binary = [[\"SomeType\" , \"f32\"], [\"AnotherType\", \"*\"]]\n    /// ```\n    #[lints(arithmetic_side_effects)]\n    arithmetic_side_effects_allowed_binary: Vec<(String, String)> = <_>::default(),\n    /// Suppress checking of the passed type names in unary operations like \"negation\" (`-`).\n    ///\n    /// #### Example\n    ///\n    /// ```toml\n    /// arithmetic-side-effects-allowed-unary = [\"SomeType\", \"AnotherType\"]\n    /// ```\n    #[lints(arithmetic_side_effects)]\n    arithmetic_side_effects_allowed_unary: Vec<String> = <_>::default(),\n    /// The maximum allowed size for arrays on the stack\n    #[lints(large_const_arrays, large_stack_arrays)]\n    array_size_threshold: u64 = 16 * 1024,\n    /// Suppress lints whenever the suggested change would cause breakage for other crates.\n    #[lints(\n        box_collection,\n        enum_variant_names,\n        large_types_passed_by_value,\n        linkedlist,\n        needless_pass_by_ref_mut,\n        option_option,\n        owned_cow,\n        rc_buffer,\n        rc_mutex,\n        redundant_allocation,\n        ref_option,\n        single_call_fn,\n        trivially_copy_pass_by_ref,\n        unnecessary_box_returns,\n        unnecessary_wraps,\n        unused_self,\n        upper_case_acronyms,\n        vec_box,\n        wrong_self_convention,\n    )]\n    avoid_breaking_exported_api: bool = true,\n    /// The list of types which may not be held across an await point.\n    #[disallowed_paths_allow_replacements = false]\n    #[lints(await_holding_invalid_type)]\n    await_holding_invalid_types: Vec<DisallowedPathWithoutReplacement> = Vec::new(),\n    /// DEPRECATED LINT: BLACKLISTED_NAME.\n    ///\n    /// Use the Disallowed Names lint instead\n    #[conf_deprecated(\"Please use `disallowed-names` instead\", disallowed_names)]\n    blacklisted_names: Vec<String> = Vec::new(),\n    /// For internal testing only, ignores the current `publish` settings in the Cargo manifest.\n    #[lints(cargo_common_metadata)]\n    cargo_ignore_publish: bool = false,\n    /// Whether to check MSRV compatibility in `#[test]` and `#[cfg(test)]` code.\n    #[lints(incompatible_msrv)]\n    check_incompatible_msrv_in_tests: bool = false,\n    /// Whether to suggest reordering constructor fields when initializers are present.\n    ///\n    /// Warnings produced by this configuration aren't necessarily fixed by just reordering the fields. Even if the\n    /// suggested code would compile, it can change semantics if the initializer expressions have side effects. The\n    /// following example [from rust-clippy#11846] shows how the suggestion can run into borrow check errors:\n    ///\n    /// ```rust\n    /// struct MyStruct {\n    ///     vector: Vec<u32>,\n    ///     length: usize\n    /// }\n    /// fn main() {\n    ///     let vector = vec![1,2,3];\n    ///     MyStruct { length: vector.len(), vector};\n    /// }\n    /// ```\n    ///\n    /// [from rust-clippy#11846]: https://github.com/rust-lang/rust-clippy/issues/11846#issuecomment-1820747924\n    #[lints(inconsistent_struct_constructor)]\n    check_inconsistent_struct_field_initializers: bool = false,\n    /// Whether to also run the listed lints on private items.\n    #[lints(missing_errors_doc, missing_panics_doc, missing_safety_doc, unnecessary_safety_doc)]\n    check_private_items: bool = false,\n    /// The maximum cognitive complexity a function can have\n    #[lints(cognitive_complexity)]\n    cognitive_complexity_threshold: u64 = 25,\n    /// The minimum digits a const float literal must have to supress the `excessive_precicion` lint\n    #[lints(excessive_precision)]\n    const_literal_digits_threshold: usize = 30,\n    /// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY.\n    ///\n    /// Use the Cognitive Complexity lint instead.\n    #[conf_deprecated(\"Please use `cognitive-complexity-threshold` instead\", cognitive_complexity_threshold)]\n    cyclomatic_complexity_threshold: u64 = 25,\n    /// The list of disallowed fields, written as fully qualified paths.\n    ///\n    /// **Fields:**\n    /// - `path` (required): the fully qualified path to the field that should be disallowed\n    /// - `reason` (optional): explanation why this field is disallowed\n    /// - `replacement` (optional): suggested alternative method\n    /// - `allow-invalid` (optional, `false` by default): when set to `true`, it will ignore this entry\n    ///   if the path doesn't exist, instead of emitting an error\n    #[disallowed_paths_allow_replacements = true]\n    #[lints(disallowed_fields)]\n    disallowed_fields: Vec<DisallowedPath> = Vec::new(),\n    /// The list of disallowed macros, written as fully qualified paths.\n    ///\n    /// **Fields:**\n    /// - `path` (required): the fully qualified path to the macro that should be disallowed\n    /// - `reason` (optional): explanation why this macro is disallowed\n    /// - `replacement` (optional): suggested alternative macro\n    /// - `allow-invalid` (optional, `false` by default): when set to `true`, it will ignore this entry\n    ///   if the path doesn't exist, instead of emitting an error\n    #[disallowed_paths_allow_replacements = true]\n    #[lints(disallowed_macros)]\n    disallowed_macros: Vec<DisallowedPath> = Vec::new(),\n    /// The list of disallowed methods, written as fully qualified paths.\n    ///\n    /// **Fields:**\n    /// - `path` (required): the fully qualified path to the method that should be disallowed\n    /// - `reason` (optional): explanation why this method is disallowed\n    /// - `replacement` (optional): suggested alternative method\n    /// - `allow-invalid` (optional, `false` by default): when set to `true`, it will ignore this entry\n    ///   if the path doesn't exist, instead of emitting an error\n    #[disallowed_paths_allow_replacements = true]\n    #[lints(disallowed_methods)]\n    disallowed_methods: Vec<DisallowedPath> = Vec::new(),\n    /// The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value\n    /// `\"..\"` can be used as part of the list to indicate that the configured values should be appended to the\n    /// default configuration of Clippy. By default, any configuration will replace the default value.\n    #[lints(disallowed_names)]\n    disallowed_names: Vec<String> = DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect(),\n    /// The list of disallowed types, written as fully qualified paths.\n    ///\n    /// **Fields:**\n    /// - `path` (required): the fully qualified path to the type that should be disallowed\n    /// - `reason` (optional): explanation why this type is disallowed\n    /// - `replacement` (optional): suggested alternative type\n    /// - `allow-invalid` (optional, `false` by default): when set to `true`, it will ignore this entry\n    ///   if the path doesn't exist, instead of emitting an error\n    #[disallowed_paths_allow_replacements = true]\n    #[lints(disallowed_types)]\n    disallowed_types: Vec<DisallowedPath> = Vec::new(),\n    /// The list of words this lint should not consider as identifiers needing ticks. The value\n    /// `\"..\"` can be used as part of the list to indicate that the configured values should be appended to the\n    /// default configuration of Clippy. By default, any configuration will replace the default value. For example:\n    /// * `doc-valid-idents = [\"ClipPy\"]` would replace the default list with `[\"ClipPy\"]`.\n    /// * `doc-valid-idents = [\"ClipPy\", \"..\"]` would append `ClipPy` to the default list.\n    #[lints(doc_markdown)]\n    doc_valid_idents: Vec<String> = DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string).collect(),\n    /// Whether to apply the raw pointer heuristic to determine if a type is `Send`.\n    #[lints(non_send_fields_in_send_ty)]\n    enable_raw_pointer_heuristic_for_send: bool = true,\n    /// Whether to recommend using implicit into iter for reborrowed values.\n    ///\n    /// #### Example\n    /// ```no_run\n    /// let mut vec = vec![1, 2, 3];\n    /// let rmvec = &mut vec;\n    /// for _ in rmvec.iter() {}\n    /// for _ in rmvec.iter_mut() {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let mut vec = vec![1, 2, 3];\n    /// let rmvec = &mut vec;\n    /// for _ in &*rmvec {}\n    /// for _ in &mut *rmvec {}\n    /// ```\n    #[lints(explicit_iter_loop)]\n    enforce_iter_loop_reborrow: bool = false,\n    /// The list of imports to always rename, a fully qualified path followed by the rename.\n    #[lints(missing_enforced_import_renames)]\n    enforced_import_renames: Vec<Rename> = Vec::new(),\n    /// The minimum number of enum variants for the lints about variant names to trigger\n    #[lints(enum_variant_names)]\n    enum_variant_name_threshold: u64 = 3,\n    /// The maximum size of an enum's variant to avoid box suggestion\n    #[lints(large_enum_variant)]\n    enum_variant_size_threshold: u64 = 200,\n    /// The maximum amount of nesting a block can reside in\n    #[lints(excessive_nesting)]\n    excessive_nesting_threshold: u64 = 0,\n    /// The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint\n    #[lints(large_futures)]\n    future_size_threshold: u64 = 16 * 1024,\n    /// A list of paths to types that should be treated as if they do not contain interior mutability\n    #[lints(borrow_interior_mutable_const, declare_interior_mutable_const, ifs_same_cond, mutable_key_type)]\n    ignore_interior_mutability: Vec<String> = Vec::from([\"bytes::Bytes\".into()]),\n    /// Sets the scope (\"crate\", \"file\", or \"module\") in which duplicate inherent `impl` blocks for the same type are linted.\n    #[lints(multiple_inherent_impl)]\n    inherent_impl_lint_scope: InherentImplLintScope = InherentImplLintScope::Crate,\n    /// A list of paths to types that should be ignored as overly large `Err`-variants in a\n    /// `Result` returned from a function\n    #[lints(result_large_err)]\n    large_error_ignored: Vec<String> = Vec::default(),\n    /// The maximum size of the `Err`-variant in a `Result` returned from a function\n    #[lints(result_large_err)]\n    large_error_threshold: u64 = 128,\n    /// Whether collapsible `if` and `else if` chains are linted if they contain comments inside the parts\n    /// that would be collapsed.\n    #[lints(collapsible_else_if, collapsible_if)]\n    lint_commented_code: bool = false,\n    /// Whether to suggest reordering constructor fields when initializers are present.\n    /// DEPRECATED CONFIGURATION: lint-inconsistent-struct-field-initializers\n    ///\n    /// Use the `check-inconsistent-struct-field-initializers` configuration instead.\n    #[conf_deprecated(\"Please use `check-inconsistent-struct-field-initializers` instead\", check_inconsistent_struct_field_initializers)]\n    lint_inconsistent_struct_field_initializers: bool = false,\n    /// The lower bound for linting decimal literals\n    #[lints(decimal_literal_representation)]\n    literal_representation_threshold: u64 = 16384,\n    /// Whether the matches should be considered by the lint, and whether there should\n    /// be filtering for common types.\n    #[lints(manual_let_else)]\n    matches_for_let_else: MatchLintBehaviour = MatchLintBehaviour::WellKnownTypes,\n    /// The maximum number of bool parameters a function can have\n    #[lints(fn_params_excessive_bools)]\n    max_fn_params_bools: u64 = 3,\n    /// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes\n    #[lints(large_include_file)]\n    max_include_file_size: u64 = 1_000_000,\n    /// The maximum number of bool fields a struct can have\n    #[lints(struct_excessive_bools)]\n    max_struct_bools: u64 = 3,\n    /// When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in\n    /// the slice pattern that is suggested. If more elements are necessary, the lint is suppressed.\n    /// For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.\n    #[lints(index_refutable_slice)]\n    max_suggested_slice_pattern_length: u64 = 3,\n    /// The maximum number of bounds a trait can have to be linted\n    #[lints(type_repetition_in_bounds)]\n    max_trait_bounds: u64 = 3,\n    /// Minimum chars an ident can have, anything below or equal to this will be linted.\n    #[lints(min_ident_chars)]\n    min_ident_chars_threshold: u64 = 1,\n    /// Whether to allow fields starting with an underscore to skip documentation requirements\n    #[lints(missing_docs_in_private_items)]\n    missing_docs_allow_unused: bool = false,\n    /// Whether to **only** check for missing documentation in items visible within the current\n    /// crate. For example, `pub(crate)` items.\n    #[lints(missing_docs_in_private_items)]\n    missing_docs_in_crate_items: bool = false,\n    /// The named groupings of different source item kinds within modules.\n    #[lints(arbitrary_source_item_ordering)]\n    module_item_order_groupings: SourceItemOrderingModuleItemGroupings = DEFAULT_MODULE_ITEM_ORDERING_GROUPS.into(),\n    /// Whether the items within module groups should be ordered alphabetically or not.\n    ///\n    /// This option can be configured to \"all\", \"none\", or a list of specific grouping names that should be checked\n    /// (e.g. only \"enums\").\n    #[lints(arbitrary_source_item_ordering)]\n    module_items_ordered_within_groupings: SourceItemOrderingWithinModuleItemGroupings =\n        SourceItemOrderingWithinModuleItemGroupings::None,\n    /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`\n    #[default_text = \"current version\"]\n    #[lints(\n        allow_attributes,\n        allow_attributes_without_reason,\n        almost_complete_range,\n        approx_constant,\n        assigning_clones,\n        borrow_as_ptr,\n        cast_abs_to_unsigned,\n        checked_conversions,\n        cloned_instead_of_copied,\n        collapsible_match,\n        collapsible_str_replace,\n        deprecated_cfg_attr,\n        derivable_impls,\n        err_expect,\n        filter_map_next,\n        from_over_into,\n        if_then_some_else_none,\n        index_refutable_slice,\n        inefficient_to_string,\n        io_other_error,\n        iter_kv_map,\n        legacy_numeric_constants,\n        len_zero,\n        lines_filter_map_ok,\n        manual_abs_diff,\n        manual_bits,\n        manual_c_str_literals,\n        manual_clamp,\n        manual_div_ceil,\n        manual_flatten,\n        manual_hash_one,\n        manual_is_ascii_check,\n        manual_is_power_of_two,\n        manual_let_else,\n        manual_midpoint,\n        manual_non_exhaustive,\n        manual_option_as_slice,\n        manual_pattern_char_comparison,\n        manual_range_contains,\n        manual_rem_euclid,\n        manual_repeat_n,\n        manual_retain,\n        manual_slice_fill,\n        manual_slice_size_calculation,\n        manual_split_once,\n        manual_str_repeat,\n        manual_strip,\n        manual_take,\n        manual_try_fold,\n        map_clone,\n        map_unwrap_or,\n        map_with_unused_argument_over_ranges,\n        match_like_matches_macro,\n        mem_replace_option_with_some,\n        mem_replace_with_default,\n        missing_const_for_fn,\n        needless_borrow,\n        non_std_lazy_statics,\n        option_as_ref_deref,\n        or_fun_call,\n        ptr_as_ptr,\n        question_mark,\n        redundant_field_names,\n        redundant_static_lifetimes,\n        repeat_vec_with_capacity,\n        same_item_push,\n        seek_from_current,\n        to_digit_is_some,\n        transmute_ptr_to_ref,\n        tuple_array_conversions,\n        type_repetition_in_bounds,\n        unchecked_time_subtraction,\n        uninlined_format_args,\n        unnecessary_lazy_evaluations,\n        unnecessary_unwrap,\n        unnested_or_patterns,\n        unused_trait_names,\n        use_self,\n        zero_ptr,\n    )]\n    msrv: Msrv = Msrv::default(),\n    /// The minimum size (in bytes) to consider a type for passing by reference instead of by value.\n    #[lints(large_types_passed_by_value)]\n    pass_by_value_size_limit: u64 = 256,\n    /// Lint \"public\" fields in a struct that are prefixed with an underscore based on their\n    /// exported visibility, or whether they are marked as \"pub\".\n    #[lints(pub_underscore_fields)]\n    pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PubliclyExported,\n    /// Whether the type itself in a struct or enum should be replaced with `Self` when encountering recursive types.\n    #[lints(use_self)]\n    recursive_self_in_type_definitions: bool = true,\n    /// Whether to lint only if it's multiline.\n    #[lints(semicolon_inside_block)]\n    semicolon_inside_block_ignore_singleline: bool = false,\n    /// Whether to lint only if it's singleline.\n    #[lints(semicolon_outside_block)]\n    semicolon_outside_block_ignore_multiline: bool = false,\n    /// The maximum number of single char bindings a scope may have\n    #[lints(many_single_char_names)]\n    single_char_binding_names_threshold: u64 = 4,\n    /// Which kind of elements should be ordered internally, possible values being `enum`, `impl`, `module`, `struct`, `trait`.\n    #[lints(arbitrary_source_item_ordering)]\n    source_item_ordering: SourceItemOrdering = DEFAULT_SOURCE_ITEM_ORDERING.into(),\n    /// The maximum allowed stack size for functions in bytes\n    #[lints(large_stack_frames)]\n    stack_size_threshold: u64 = 512_000,\n    /// Enforce the named macros always use the braces specified.\n    ///\n    /// A `MacroMatcher` can be added like so `{ name = \"macro_name\", brace = \"(\" }`. If the macro\n    /// could be used with a full path two `MacroMatcher`s have to be added one with the full path\n    /// `crate_name::macro_name` and one with just the macro name.\n    #[lints(nonstandard_macro_braces)]\n    standard_macro_braces: Vec<MacroMatcher> = Vec::new(),\n    /// The minimum number of struct fields for the lints about field names to trigger\n    #[lints(struct_field_names)]\n    struct_field_name_threshold: u64 = 3,\n    /// Whether to suppress a restriction lint in constant code. In same\n    /// cases the restructured operation might not be unavoidable, as the\n    /// suggested counterparts are unavailable in constant code. This\n    /// configuration will cause restriction lints to trigger even\n    /// if no suggestion can be made.\n    #[lints(indexing_slicing)]\n    suppress_restriction_lint_in_const: bool = false,\n    /// The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap\n    #[lints(boxed_local, useless_vec)]\n    too_large_for_stack: u64 = 200,\n    /// The maximum number of argument a function or method can have\n    #[lints(too_many_arguments)]\n    too_many_arguments_threshold: u64 = 7,\n    /// The maximum number of lines a function or method can have\n    #[lints(too_many_lines)]\n    too_many_lines_threshold: u64 = 100,\n    /// The order of associated items in traits.\n    #[lints(arbitrary_source_item_ordering)]\n    trait_assoc_item_kinds_order: SourceItemOrderingTraitAssocItemKinds = DEFAULT_TRAIT_ASSOC_ITEM_KINDS_ORDER.into(),\n    /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by\n    /// reference.\n    #[default_text = \"target_pointer_width\"]\n    #[lints(trivially_copy_pass_by_ref)]\n    trivial_copy_size_limit: Option<u64> = None,\n    /// The maximum complexity a type can have\n    #[lints(type_complexity)]\n    type_complexity_threshold: u64 = 250,\n    /// The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint\n    #[lints(unnecessary_box_returns)]\n    unnecessary_box_size: u64 = 128,\n    /// Should the fraction of a decimal be linted to include separators.\n    #[lints(unreadable_literal)]\n    unreadable_literal_lint_fractions: bool = true,\n    /// Enables verbose mode. Triggers if there is more than one uppercase char next to each other\n    #[lints(upper_case_acronyms)]\n    upper_case_acronyms_aggressive: bool = false,\n    /// The size of the boxed type in bytes, where boxing in a `Vec` is allowed\n    #[lints(vec_box)]\n    vec_box_size_threshold: u64 = 4096,\n    /// The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'\n    #[lints(verbose_bit_mask)]\n    verbose_bit_mask_threshold: u64 = 1,\n    /// Whether to emit warnings on all wildcard imports, including those from `prelude`, from `super` in tests,\n    /// or for `pub use` reexports.\n    #[lints(wildcard_imports)]\n    warn_on_all_wildcard_imports: bool = false,\n    /// Whether to also emit warnings for unsafe blocks with metavariable expansions in **private** macros.\n    #[lints(macro_metavars_in_unsafe)]\n    warn_unsafe_macro_metavars_in_private_macros: bool = false,\n}\n\n/// Search for the configuration file.\n///\n/// # Errors\n///\n/// Returns any unexpected filesystem error encountered when searching for the config file\npub fn lookup_conf_file() -> io::Result<(Option<PathBuf>, Vec<String>)> {\n    /// Possible filename to search for.\n    const CONFIG_FILE_NAMES: [&str; 2] = [\".clippy.toml\", \"clippy.toml\"];\n\n    // Start looking for a config file in CLIPPY_CONF_DIR, or failing that, CARGO_MANIFEST_DIR.\n    // If neither of those exist, use \".\". (Update documentation if this priority changes)\n    let mut current = env::var_os(\"CLIPPY_CONF_DIR\")\n        .or_else(|| env::var_os(\"CARGO_MANIFEST_DIR\"))\n        .map_or_else(|| PathBuf::from(\".\"), PathBuf::from)\n        .canonicalize()?;\n\n    let mut found_config: Option<PathBuf> = None;\n    let mut warnings = vec![];\n\n    loop {\n        for config_file_name in &CONFIG_FILE_NAMES {\n            if let Ok(config_file) = current.join(config_file_name).canonicalize() {\n                match fs::metadata(&config_file) {\n                    Err(e) if e.kind() == io::ErrorKind::NotFound => {},\n                    Err(e) => return Err(e),\n                    Ok(md) if md.is_dir() => {},\n                    Ok(_) => {\n                        // warn if we happen to find two config files #8323\n                        if let Some(ref found_config) = found_config {\n                            warnings.push(format!(\n                                \"using config file `{}`, `{}` will be ignored\",\n                                found_config.display(),\n                                config_file.display()\n                            ));\n                        } else {\n                            found_config = Some(config_file);\n                        }\n                    },\n                }\n            }\n        }\n\n        if found_config.is_some() {\n            return Ok((found_config, warnings));\n        }\n\n        // If the current directory has no parent, we're done searching.\n        if !current.pop() {\n            return Ok((None, warnings));\n        }\n    }\n}\n\nfn deserialize(file: &SourceFile) -> TryConf {\n    match toml::de::Deserializer::new(file.src.as_ref().unwrap()).deserialize_map(ConfVisitor(file)) {\n        Ok(mut conf) => {\n            extend_vec_if_indicator_present(&mut conf.conf.disallowed_names, DEFAULT_DISALLOWED_NAMES);\n            extend_vec_if_indicator_present(&mut conf.conf.allowed_prefixes, DEFAULT_ALLOWED_PREFIXES);\n            extend_vec_if_indicator_present(\n                &mut conf.conf.allow_renamed_params_for,\n                DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS,\n            );\n\n            // Confirms that the user has not accidentally configured ordering requirements for groups that\n            // aren't configured.\n            if let SourceItemOrderingWithinModuleItemGroupings::Custom(groupings) =\n                &conf.conf.module_items_ordered_within_groupings\n            {\n                for grouping in groupings {\n                    if !conf.conf.module_item_order_groupings.is_grouping(grouping) {\n                        // Since this isn't fixable by rustfix, don't emit a `Suggestion`. This just adds some useful\n                        // info for the user instead.\n\n                        let names = conf.conf.module_item_order_groupings.grouping_names();\n                        let suggestion = suggest_candidate(grouping, names.iter().map(String::as_str))\n                            .map(|s| format!(\" perhaps you meant `{s}`?\"))\n                            .unwrap_or_default();\n                        let names = names.iter().map(|s| format!(\"`{s}`\")).join(\", \");\n                        let message = format!(\n                            \"unknown ordering group: `{grouping}` was not specified in `module-items-ordered-within-groupings`,{suggestion} expected one of: {names}\"\n                        );\n\n                        let span = conf\n                            .value_spans\n                            .get(\"module_item_order_groupings\")\n                            .cloned()\n                            .unwrap_or_default();\n                        conf.errors.push(ConfError::spanned(file, message, None, span));\n                    }\n                }\n            }\n\n            // TODO: THIS SHOULD BE TESTED, this comment will be gone soon\n            if conf.conf.allowed_idents_below_min_chars.iter().any(|e| e == \"..\") {\n                conf.conf\n                    .allowed_idents_below_min_chars\n                    .extend(DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS.iter().map(ToString::to_string));\n            }\n            if conf.conf.doc_valid_idents.iter().any(|e| e == \"..\") {\n                conf.conf\n                    .doc_valid_idents\n                    .extend(DEFAULT_DOC_VALID_IDENTS.iter().map(ToString::to_string));\n            }\n\n            conf\n        },\n        Err(e) => TryConf::from_toml_error(file, &e),\n    }\n}\n\nfn extend_vec_if_indicator_present(vec: &mut Vec<String>, default: &[&str]) {\n    if vec.contains(&\"..\".to_string()) {\n        vec.extend(default.iter().map(ToString::to_string));\n    }\n}\n\nimpl Conf {\n    pub fn read(sess: &Session, path: &io::Result<(Option<PathBuf>, Vec<String>)>) -> &'static Conf {\n        static CONF: OnceLock<Conf> = OnceLock::new();\n        CONF.get_or_init(|| Conf::read_inner(sess, path))\n    }\n\n    fn read_inner(sess: &Session, path: &io::Result<(Option<PathBuf>, Vec<String>)>) -> Conf {\n        match path {\n            Ok((_, warnings)) => {\n                for warning in warnings {\n                    sess.dcx().warn(warning.clone());\n                }\n            },\n            Err(error) => {\n                sess.dcx()\n                    .err(format!(\"error finding Clippy's configuration file: {error}\"));\n            },\n        }\n\n        let TryConf {\n            mut conf,\n            value_spans: _,\n            errors,\n            warnings,\n        } = match path {\n            Ok((Some(path), _)) => match sess.source_map().load_file(path) {\n                Ok(file) => deserialize(&file),\n                Err(error) => {\n                    sess.dcx().err(format!(\"failed to read `{}`: {error}\", path.display()));\n                    TryConf::default()\n                },\n            },\n            _ => TryConf::default(),\n        };\n\n        conf.msrv.read_cargo(sess);\n\n        // all conf errors are non-fatal, we just use the default conf in case of error\n        for error in errors {\n            let mut diag = sess.dcx().struct_span_err(\n                error.span,\n                format!(\"error reading Clippy's configuration file: {}\", error.message),\n            );\n\n            if let Some(sugg) = error.suggestion {\n                diag.span_suggestion(error.span, sugg.message, sugg.suggestion, Applicability::MaybeIncorrect);\n            }\n\n            diag.emit();\n        }\n\n        for warning in warnings {\n            sess.dcx().span_warn(\n                warning.span,\n                format!(\"error reading Clippy's configuration file: {}\", warning.message),\n            );\n        }\n\n        conf\n    }\n}\n\nconst SEPARATOR_WIDTH: usize = 4;\n\n#[derive(Debug)]\nstruct FieldError {\n    error: String,\n    suggestion: Option<Suggestion>,\n}\n\n#[derive(Debug)]\nstruct Suggestion {\n    message: &'static str,\n    suggestion: &'static str,\n}\n\nimpl std::error::Error for FieldError {}\n\nimpl Display for FieldError {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        f.pad(&self.error)\n    }\n}\n\nimpl serde::de::Error for FieldError {\n    fn custom<T: Display>(msg: T) -> Self {\n        Self {\n            error: msg.to_string(),\n            suggestion: None,\n        }\n    }\n\n    fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {\n        // List the available fields sorted and at least one per line, more if `CLIPPY_TERMINAL_WIDTH` is\n        // set and allows it.\n        use fmt::Write;\n\n        let metadata = get_configuration_metadata();\n        let deprecated = metadata\n            .iter()\n            .filter_map(|conf| {\n                if conf.deprecation_reason.is_some() {\n                    Some(conf.name.as_str())\n                } else {\n                    None\n                }\n            })\n            .collect::<Vec<_>>();\n\n        let mut expected = expected\n            .iter()\n            .copied()\n            .filter(|name| !deprecated.contains(name))\n            .collect::<Vec<_>>();\n        expected.sort_unstable();\n\n        let (rows, column_widths) = calculate_dimensions(&expected);\n\n        let mut msg = format!(\"unknown field `{field}`, expected one of\");\n        for row in 0..rows {\n            writeln!(msg).unwrap();\n            for (column, column_width) in column_widths.iter().copied().enumerate() {\n                let index = column * rows + row;\n                let field = expected.get(index).copied().unwrap_or_default();\n                write!(msg, \"{:SEPARATOR_WIDTH$}{field:column_width$}\", \" \").unwrap();\n            }\n        }\n\n        let suggestion = suggest_candidate(field, expected).map(|suggestion| Suggestion {\n            message: \"perhaps you meant\",\n            suggestion,\n        });\n\n        Self { error: msg, suggestion }\n    }\n}\n\nfn calculate_dimensions(fields: &[&str]) -> (usize, Vec<usize>) {\n    let columns = env::var(\"CLIPPY_TERMINAL_WIDTH\")\n        .ok()\n        .and_then(|s| <usize as FromStr>::from_str(&s).ok())\n        .map_or(1, |terminal_width| {\n            let max_field_width = fields.iter().map(|field| field.len()).max().unwrap();\n            cmp::max(1, terminal_width / (SEPARATOR_WIDTH + max_field_width))\n        });\n\n    let rows = fields.len().div_ceil(columns);\n\n    let column_widths = (0..columns)\n        .map(|column| {\n            if column < columns - 1 {\n                (0..rows)\n                    .map(|row| {\n                        let index = column * rows + row;\n                        let field = fields.get(index).copied().unwrap_or_default();\n                        field.len()\n                    })\n                    .max()\n                    .unwrap()\n            } else {\n                // Avoid adding extra space to the last column.\n                0\n            }\n        })\n        .collect::<Vec<_>>();\n\n    (rows, column_widths)\n}\n\n/// Given a user-provided value that couldn't be matched to a known option, finds the most likely\n/// candidate among candidates that the user might have meant.\nfn suggest_candidate<'a, I>(value: &str, candidates: I) -> Option<&'a str>\nwhere\n    I: IntoIterator<Item = &'a str>,\n{\n    candidates\n        .into_iter()\n        .filter_map(|expected| {\n            let dist = edit_distance(value, expected, 4)?;\n            Some((dist, expected))\n        })\n        .min_by_key(|&(dist, _)| dist)\n        .map(|(_, suggestion)| suggestion)\n}\n\n#[cfg(test)]\nmod tests {\n    use serde::de::IgnoredAny;\n    use std::collections::{HashMap, HashSet};\n    use std::fs;\n    use walkdir::WalkDir;\n\n    #[test]\n    fn configs_are_tested() {\n        let mut names: HashSet<String> = crate::get_configuration_metadata()\n            .into_iter()\n            .filter_map(|meta| {\n                if meta.deprecation_reason.is_none() {\n                    Some(meta.name.replace('_', \"-\"))\n                } else {\n                    None\n                }\n            })\n            .collect();\n\n        let toml_files = WalkDir::new(\"../tests\")\n            .into_iter()\n            .map(Result::unwrap)\n            .filter(|entry| entry.file_name() == \"clippy.toml\");\n\n        for entry in toml_files {\n            let file = fs::read_to_string(entry.path()).unwrap();\n            #[expect(clippy::zero_sized_map_values)]\n            if let Ok(map) = toml::from_str::<HashMap<String, IgnoredAny>>(&file) {\n                for name in map.keys() {\n                    names.remove(name.as_str());\n                }\n            }\n        }\n\n        assert!(\n            names.is_empty(),\n            \"Configuration variable lacks test: {names:?}\\nAdd a test to `tests/ui-toml`\"\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_config/src/lib.rs",
    "content": "#![feature(rustc_private)]\n#![warn(\n    trivial_casts,\n    trivial_numeric_casts,\n    rust_2018_idioms,\n    unused_lifetimes,\n    unused_qualifications\n)]\n#![allow(clippy::must_use_candidate, clippy::missing_panics_doc)]\n#![deny(clippy::derive_deserialize_allowing_unknown)]\n\nextern crate rustc_data_structures;\nextern crate rustc_errors;\nextern crate rustc_hir;\nextern crate rustc_middle;\nextern crate rustc_session;\nextern crate rustc_span;\n\nmod conf;\nmod metadata;\npub mod types;\n\npub use conf::{Conf, get_configuration_metadata, lookup_conf_file, sanitize_explanation};\npub use metadata::ClippyConfiguration;\n"
  },
  {
    "path": "clippy_config/src/metadata.rs",
    "content": "use itertools::Itertools;\nuse std::fmt;\n\n#[derive(Debug, Clone, Default)]\npub struct ClippyConfiguration {\n    pub name: String,\n    pub default: String,\n    pub lints: &'static [&'static str],\n    pub doc: &'static str,\n    pub deprecation_reason: Option<&'static str>,\n}\n\nimpl fmt::Display for ClippyConfiguration {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"- `{}`: {}\", self.name, self.doc)?;\n        if !self.default.is_empty() {\n            write!(f, \"\\n\\n   (default: `{}`)\", self.default)?;\n        }\n        Ok(())\n    }\n}\n\nimpl ClippyConfiguration {\n    pub fn to_markdown_paragraph(&self) -> String {\n        format!(\n            \"## `{}`\\n{}\\n\\n**Default Value:** `{}`\\n\\n---\\n**Affected lints:**\\n{}\\n\\n\",\n            self.name,\n            self.doc.lines().map(|x| x.strip_prefix(' ').unwrap_or(x)).join(\"\\n\"),\n            self.default,\n            self.lints.iter().format_with(\"\\n\", |name, f| f(&format_args!(\n                \"* [`{name}`](https://rust-lang.github.io/rust-clippy/master/index.html#{name})\"\n            ))),\n        )\n    }\n\n    pub fn to_markdown_link(&self) -> String {\n        const BOOK_CONFIGS_PATH: &str = \"https://doc.rust-lang.org/clippy/lint_configuration.html\";\n        format!(\"[`{}`]: {BOOK_CONFIGS_PATH}#{}\", self.name, self.name)\n    }\n}\n"
  },
  {
    "path": "clippy_config/src/types.rs",
    "content": "use clippy_utils::paths::{PathNS, find_crates, lookup_path};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::PrimTy;\nuse rustc_hir::def::DefKind;\nuse rustc_hir::def_id::DefIdMap;\nuse rustc_middle::ty::TyCtxt;\nuse rustc_span::{Span, Symbol};\nuse serde::de::{self, Deserializer, Visitor};\nuse serde::{Deserialize, Serialize, ser};\nuse std::collections::HashMap;\nuse std::fmt;\n\n#[derive(Debug, Deserialize)]\n#[serde(deny_unknown_fields)]\npub struct Rename {\n    pub path: String,\n    pub rename: String,\n}\n\npub type DisallowedPathWithoutReplacement = DisallowedPath<false>;\n\n#[derive(Debug, Serialize)]\npub struct DisallowedPath<const REPLACEMENT_ALLOWED: bool = true> {\n    path: String,\n    reason: Option<String>,\n    replacement: Option<String>,\n    /// Setting `allow_invalid` to true suppresses a warning if `path` does not refer to an existing\n    /// definition.\n    ///\n    /// This could be useful when conditional compilation is used, or when a clippy.toml file is\n    /// shared among multiple projects.\n    allow_invalid: bool,\n    /// The span of the `DisallowedPath`.\n    ///\n    /// Used for diagnostics.\n    #[serde(skip_serializing)]\n    span: Span,\n}\n\nimpl<'de, const REPLACEMENT_ALLOWED: bool> Deserialize<'de> for DisallowedPath<REPLACEMENT_ALLOWED> {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let enum_ = DisallowedPathEnum::deserialize(deserializer)?;\n        if !REPLACEMENT_ALLOWED && enum_.replacement().is_some() {\n            return Err(de::Error::custom(\"replacement not allowed for this configuration\"));\n        }\n        Ok(Self {\n            path: enum_.path().to_owned(),\n            reason: enum_.reason().map(ToOwned::to_owned),\n            replacement: enum_.replacement().map(ToOwned::to_owned),\n            allow_invalid: enum_.allow_invalid(),\n            span: Span::default(),\n        })\n    }\n}\n\n// `DisallowedPathEnum` is an implementation detail to enable the `Deserialize` implementation just\n// above. `DisallowedPathEnum` is not meant to be used outside of this file.\n#[derive(Debug, Deserialize, Serialize)]\n#[serde(untagged, deny_unknown_fields)]\nenum DisallowedPathEnum {\n    Simple(String),\n    WithReason {\n        path: String,\n        reason: Option<String>,\n        replacement: Option<String>,\n        #[serde(rename = \"allow-invalid\")]\n        allow_invalid: Option<bool>,\n    },\n}\n\nimpl<const REPLACEMENT_ALLOWED: bool> DisallowedPath<REPLACEMENT_ALLOWED> {\n    pub fn path(&self) -> &str {\n        &self.path\n    }\n\n    pub fn diag_amendment(&self, span: Span) -> impl FnOnce(&mut Diag<'_, ()>) {\n        move |diag| {\n            if let Some(replacement) = &self.replacement {\n                diag.span_suggestion(\n                    span,\n                    self.reason.as_ref().map_or_else(|| String::from(\"use\"), Clone::clone),\n                    replacement,\n                    Applicability::MachineApplicable,\n                );\n            } else if let Some(reason) = &self.reason {\n                diag.note(reason.clone());\n            }\n        }\n    }\n\n    pub fn span(&self) -> Span {\n        self.span\n    }\n\n    pub fn set_span(&mut self, span: Span) {\n        self.span = span;\n    }\n}\n\nimpl DisallowedPathEnum {\n    pub fn path(&self) -> &str {\n        let (Self::Simple(path) | Self::WithReason { path, .. }) = self;\n\n        path\n    }\n\n    fn reason(&self) -> Option<&str> {\n        match &self {\n            Self::WithReason { reason, .. } => reason.as_deref(),\n            Self::Simple(_) => None,\n        }\n    }\n\n    fn replacement(&self) -> Option<&str> {\n        match &self {\n            Self::WithReason { replacement, .. } => replacement.as_deref(),\n            Self::Simple(_) => None,\n        }\n    }\n\n    fn allow_invalid(&self) -> bool {\n        match &self {\n            Self::WithReason { allow_invalid, .. } => allow_invalid.unwrap_or_default(),\n            Self::Simple(_) => false,\n        }\n    }\n}\n\n/// Creates a map of disallowed items to the reason they were disallowed.\n#[expect(clippy::type_complexity)]\npub fn create_disallowed_map<const REPLACEMENT_ALLOWED: bool>(\n    tcx: TyCtxt<'_>,\n    disallowed_paths: &'static [DisallowedPath<REPLACEMENT_ALLOWED>],\n    ns: PathNS,\n    def_kind_predicate: impl Fn(DefKind) -> bool,\n    predicate_description: &str,\n    allow_prim_tys: bool,\n) -> (\n    DefIdMap<(&'static str, &'static DisallowedPath<REPLACEMENT_ALLOWED>)>,\n    FxHashMap<PrimTy, (&'static str, &'static DisallowedPath<REPLACEMENT_ALLOWED>)>,\n) {\n    let mut def_ids: DefIdMap<(&'static str, &'static DisallowedPath<REPLACEMENT_ALLOWED>)> = DefIdMap::default();\n    let mut prim_tys: FxHashMap<PrimTy, (&'static str, &'static DisallowedPath<REPLACEMENT_ALLOWED>)> =\n        FxHashMap::default();\n    for disallowed_path in disallowed_paths {\n        let path = disallowed_path.path();\n        let sym_path: Vec<Symbol> = path.split(\"::\").map(Symbol::intern).collect();\n        let mut resolutions = lookup_path(tcx, ns, &sym_path);\n        resolutions.retain(|&def_id| def_kind_predicate(tcx.def_kind(def_id)));\n\n        let (prim_ty, found_prim_ty) = if let &[name] = sym_path.as_slice()\n            && let Some(prim) = PrimTy::from_name(name)\n        {\n            (allow_prim_tys.then_some(prim), true)\n        } else {\n            (None, false)\n        };\n\n        if resolutions.is_empty()\n            && prim_ty.is_none()\n            && !disallowed_path.allow_invalid\n            // Don't warn about unloaded crates:\n            // https://github.com/rust-lang/rust-clippy/pull/14397#issuecomment-2848328221\n            && (sym_path.len() < 2 || !find_crates(tcx, sym_path[0]).is_empty())\n        {\n            // Relookup the path in an arbitrary namespace to get a good `expected, found` message\n            let found_def_ids = lookup_path(tcx, PathNS::Arbitrary, &sym_path);\n            let message = if let Some(&def_id) = found_def_ids.first() {\n                let (article, description) = tcx.article_and_description(def_id);\n                format!(\"expected a {predicate_description}, found {article} {description}\")\n            } else if found_prim_ty {\n                format!(\"expected a {predicate_description}, found a primitive type\")\n            } else {\n                format!(\"`{path}` does not refer to a reachable {predicate_description}\")\n            };\n            tcx.sess\n                .dcx()\n                .struct_span_warn(disallowed_path.span(), message)\n                .with_help(\"add `allow-invalid = true` to the entry to suppress this warning\")\n                .emit();\n        }\n\n        for def_id in resolutions {\n            def_ids.insert(def_id, (path, disallowed_path));\n        }\n        if let Some(ty) = prim_ty {\n            prim_tys.insert(ty, (path, disallowed_path));\n        }\n    }\n\n    (def_ids, prim_tys)\n}\n\n#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]\npub enum MatchLintBehaviour {\n    AllTypes,\n    WellKnownTypes,\n    Never,\n}\n\n#[derive(Debug)]\npub struct MacroMatcher {\n    pub name: String,\n    pub braces: (char, char),\n}\n\nimpl<'de> Deserialize<'de> for MacroMatcher {\n    fn deserialize<D>(deser: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        #[derive(Deserialize)]\n        #[serde(field_identifier, rename_all = \"lowercase\")]\n        enum Field {\n            Name,\n            Brace,\n        }\n        struct MacVisitor;\n        impl<'de> Visitor<'de> for MacVisitor {\n            type Value = MacroMatcher;\n\n            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n                formatter.write_str(\"struct MacroMatcher\")\n            }\n\n            fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>\n            where\n                V: de::MapAccess<'de>,\n            {\n                let mut name = None;\n                let mut brace: Option<char> = None;\n                while let Some(key) = map.next_key()? {\n                    match key {\n                        Field::Name => {\n                            if name.is_some() {\n                                return Err(de::Error::duplicate_field(\"name\"));\n                            }\n                            name = Some(map.next_value()?);\n                        },\n                        Field::Brace => {\n                            if brace.is_some() {\n                                return Err(de::Error::duplicate_field(\"brace\"));\n                            }\n                            brace = Some(map.next_value()?);\n                        },\n                    }\n                }\n                let name = name.ok_or_else(|| de::Error::missing_field(\"name\"))?;\n                let brace = brace.ok_or_else(|| de::Error::missing_field(\"brace\"))?;\n                Ok(MacroMatcher {\n                    name,\n                    braces: [('(', ')'), ('{', '}'), ('[', ']')]\n                        .into_iter()\n                        .find(|b| b.0 == brace)\n                        .map(|(o, c)| (o.to_owned(), c.to_owned()))\n                        .ok_or_else(|| de::Error::custom(format!(\"expected one of `(`, `{{`, `[` found `{brace}`\")))?,\n                })\n            }\n        }\n\n        const FIELDS: &[&str] = &[\"name\", \"brace\"];\n        deser.deserialize_struct(\"MacroMatcher\", FIELDS, MacVisitor)\n    }\n}\n\n/// Represents the item categories that can be ordered by the source ordering lint.\n#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum SourceItemOrderingCategory {\n    Enum,\n    Impl,\n    Module,\n    Struct,\n    Trait,\n}\n\n/// Represents which item categories are enabled for ordering.\n///\n/// The [`Deserialize`] implementation checks that there are no duplicates in\n/// the user configuration.\npub struct SourceItemOrdering(Vec<SourceItemOrderingCategory>);\n\nimpl SourceItemOrdering {\n    pub fn contains(&self, category: &SourceItemOrderingCategory) -> bool {\n        self.0.contains(category)\n    }\n}\n\nimpl<T> From<T> for SourceItemOrdering\nwhere\n    T: Into<Vec<SourceItemOrderingCategory>>,\n{\n    fn from(value: T) -> Self {\n        Self(value.into())\n    }\n}\n\nimpl core::fmt::Debug for SourceItemOrdering {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.0.fmt(f)\n    }\n}\n\nimpl<'de> Deserialize<'de> for SourceItemOrdering {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let items = Vec::<SourceItemOrderingCategory>::deserialize(deserializer)?;\n        let mut items_set = std::collections::HashSet::new();\n\n        for item in &items {\n            if items_set.contains(item) {\n                return Err(de::Error::custom(format!(\n                    \"The category \\\"{item:?}\\\" was enabled more than once in the source ordering configuration.\"\n                )));\n            }\n            items_set.insert(item);\n        }\n\n        Ok(Self(items))\n    }\n}\n\nimpl Serialize for SourceItemOrdering {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: ser::Serializer,\n    {\n        self.0.serialize(serializer)\n    }\n}\n\n/// Represents the items that can occur within a module.\n#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum SourceItemOrderingModuleItemKind {\n    ExternCrate,\n    Mod,\n    ForeignMod,\n    Use,\n    Macro,\n    GlobalAsm,\n    Static,\n    Const,\n    TyAlias,\n    Enum,\n    Struct,\n    Union,\n    Trait,\n    TraitAlias,\n    Impl,\n    Fn,\n}\n\nimpl SourceItemOrderingModuleItemKind {\n    pub fn all_variants() -> Vec<Self> {\n        #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.\n        use SourceItemOrderingModuleItemKind::*;\n        vec![\n            ExternCrate,\n            Mod,\n            ForeignMod,\n            Use,\n            Macro,\n            GlobalAsm,\n            Static,\n            Const,\n            TyAlias,\n            Enum,\n            Struct,\n            Union,\n            Trait,\n            TraitAlias,\n            Impl,\n            Fn,\n        ]\n    }\n}\n\n/// Represents the configured ordering of items within a module.\n///\n/// The [`Deserialize`] implementation checks that no item kinds have been\n/// omitted and that there are no duplicates in the user configuration.\n#[derive(Clone)]\npub struct SourceItemOrderingModuleItemGroupings {\n    groups: Vec<(String, Vec<SourceItemOrderingModuleItemKind>)>,\n    lut: HashMap<SourceItemOrderingModuleItemKind, usize>,\n    back_lut: HashMap<SourceItemOrderingModuleItemKind, String>,\n}\n\nimpl SourceItemOrderingModuleItemGroupings {\n    fn build_lut(\n        groups: &[(String, Vec<SourceItemOrderingModuleItemKind>)],\n    ) -> HashMap<SourceItemOrderingModuleItemKind, usize> {\n        let mut lut = HashMap::new();\n        for (group_index, (_, items)) in groups.iter().enumerate() {\n            for item in items {\n                lut.insert(item.clone(), group_index);\n            }\n        }\n        lut\n    }\n\n    fn build_back_lut(\n        groups: &[(String, Vec<SourceItemOrderingModuleItemKind>)],\n    ) -> HashMap<SourceItemOrderingModuleItemKind, String> {\n        let mut lut = HashMap::new();\n        for (group_name, items) in groups {\n            for item in items {\n                lut.insert(item.clone(), group_name.clone());\n            }\n        }\n        lut\n    }\n\n    pub fn grouping_name_of(&self, item: &SourceItemOrderingModuleItemKind) -> Option<&String> {\n        self.back_lut.get(item)\n    }\n\n    pub fn grouping_names(&self) -> Vec<String> {\n        self.groups.iter().map(|(name, _)| name.clone()).collect()\n    }\n\n    pub fn is_grouping(&self, grouping: &str) -> bool {\n        self.groups.iter().any(|(g, _)| g == grouping)\n    }\n\n    pub fn module_level_order_of(&self, item: &SourceItemOrderingModuleItemKind) -> Option<usize> {\n        self.lut.get(item).copied()\n    }\n}\n\nimpl From<&[(&str, &[SourceItemOrderingModuleItemKind])]> for SourceItemOrderingModuleItemGroupings {\n    fn from(value: &[(&str, &[SourceItemOrderingModuleItemKind])]) -> Self {\n        let groups: Vec<(String, Vec<SourceItemOrderingModuleItemKind>)> =\n            value.iter().map(|item| (item.0.to_string(), item.1.to_vec())).collect();\n        let lut = Self::build_lut(&groups);\n        let back_lut = Self::build_back_lut(&groups);\n        Self { groups, lut, back_lut }\n    }\n}\n\nimpl core::fmt::Debug for SourceItemOrderingModuleItemGroupings {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.groups.fmt(f)\n    }\n}\n\nimpl<'de> Deserialize<'de> for SourceItemOrderingModuleItemGroupings {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let groups = Vec::<(String, Vec<SourceItemOrderingModuleItemKind>)>::deserialize(deserializer)?;\n        let items_total: usize = groups.iter().map(|(_, v)| v.len()).sum();\n        let lut = Self::build_lut(&groups);\n        let back_lut = Self::build_back_lut(&groups);\n\n        let mut expected_items = SourceItemOrderingModuleItemKind::all_variants();\n        for item in lut.keys() {\n            expected_items.retain(|i| i != item);\n        }\n\n        let all_items = SourceItemOrderingModuleItemKind::all_variants();\n        if expected_items.is_empty() && items_total == all_items.len() {\n            let Some(use_group_index) = lut.get(&SourceItemOrderingModuleItemKind::Use) else {\n                return Err(de::Error::custom(\"Error in internal LUT.\"));\n            };\n            let Some((_, use_group_items)) = groups.get(*use_group_index) else {\n                return Err(de::Error::custom(\"Error in internal LUT.\"));\n            };\n            if use_group_items.len() > 1 {\n                return Err(de::Error::custom(\n                    \"The group containing the \\\"use\\\" item kind may not contain any other item kinds. \\\n                    The \\\"use\\\" items will (generally) be sorted by rustfmt already. \\\n                    Therefore it makes no sense to implement linting rules that may conflict with rustfmt.\",\n                ));\n            }\n\n            Ok(Self { groups, lut, back_lut })\n        } else if items_total != all_items.len() {\n            Err(de::Error::custom(format!(\n                \"Some module item kinds were configured more than once, or were missing, in the source ordering configuration. \\\n                The module item kinds are: {all_items:?}\"\n            )))\n        } else {\n            Err(de::Error::custom(format!(\n                \"Not all module item kinds were part of the configured source ordering rule. \\\n                All item kinds must be provided in the config, otherwise the required source ordering would remain ambiguous. \\\n                The module item kinds are: {all_items:?}\"\n            )))\n        }\n    }\n}\n\nimpl Serialize for SourceItemOrderingModuleItemGroupings {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: ser::Serializer,\n    {\n        self.groups.serialize(serializer)\n    }\n}\n\n/// Represents all kinds of trait associated items.\n#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum SourceItemOrderingTraitAssocItemKind {\n    Const,\n    Fn,\n    Type,\n}\n\nimpl SourceItemOrderingTraitAssocItemKind {\n    pub fn all_variants() -> Vec<Self> {\n        #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.\n        use SourceItemOrderingTraitAssocItemKind::*;\n        vec![Const, Fn, Type]\n    }\n}\n\n/// Represents the order in which associated trait items should be ordered.\n///\n/// The reason to wrap a `Vec` in a newtype is to be able to implement\n/// [`Deserialize`]. Implementing `Deserialize` allows for implementing checks\n/// on configuration completeness at the time of loading the clippy config,\n/// letting the user know if there's any issues with the config (e.g. not\n/// listing all item kinds that should be sorted).\n#[derive(Clone)]\npub struct SourceItemOrderingTraitAssocItemKinds(Vec<SourceItemOrderingTraitAssocItemKind>);\n\nimpl SourceItemOrderingTraitAssocItemKinds {\n    pub fn index_of(&self, item: &SourceItemOrderingTraitAssocItemKind) -> Option<usize> {\n        self.0.iter().position(|i| i == item)\n    }\n}\n\nimpl<T> From<T> for SourceItemOrderingTraitAssocItemKinds\nwhere\n    T: Into<Vec<SourceItemOrderingTraitAssocItemKind>>,\n{\n    fn from(value: T) -> Self {\n        Self(value.into())\n    }\n}\n\nimpl core::fmt::Debug for SourceItemOrderingTraitAssocItemKinds {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.0.fmt(f)\n    }\n}\n\nimpl<'de> Deserialize<'de> for SourceItemOrderingTraitAssocItemKinds {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let items = Vec::<SourceItemOrderingTraitAssocItemKind>::deserialize(deserializer)?;\n\n        let mut expected_items = SourceItemOrderingTraitAssocItemKind::all_variants();\n        for item in &items {\n            expected_items.retain(|i| i != item);\n        }\n\n        let all_items = SourceItemOrderingTraitAssocItemKind::all_variants();\n        if expected_items.is_empty() && items.len() == all_items.len() {\n            Ok(Self(items))\n        } else if items.len() != all_items.len() {\n            Err(de::Error::custom(format!(\n                \"Some trait associated item kinds were configured more than once, or were missing, in the source ordering configuration. \\\n                The trait associated item kinds are: {all_items:?}\",\n            )))\n        } else {\n            Err(de::Error::custom(format!(\n                \"Not all trait associated item kinds were part of the configured source ordering rule. \\\n                All item kinds must be provided in the config, otherwise the required source ordering would remain ambiguous. \\\n                The trait associated item kinds are: {all_items:?}\"\n            )))\n        }\n    }\n}\n\nimpl Serialize for SourceItemOrderingTraitAssocItemKinds {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: ser::Serializer,\n    {\n        self.0.serialize(serializer)\n    }\n}\n\n/// Describes which specific groupings should have their items ordered\n/// alphabetically.\n///\n/// This is separate from defining and enforcing groupings. For example,\n/// defining enums are grouped before structs still allows for an enum B to be\n/// placed before an enum A. Only when enforcing ordering within the grouping,\n/// will it be checked if A is placed before B.\n#[derive(Clone, Debug)]\npub enum SourceItemOrderingWithinModuleItemGroupings {\n    /// All groupings should have their items ordered.\n    All,\n\n    /// None of the groupings should have their order checked.\n    None,\n\n    /// Only the specified groupings should have their order checked.\n    Custom(Vec<String>),\n}\n\nimpl SourceItemOrderingWithinModuleItemGroupings {\n    pub fn ordered_within(&self, grouping_name: &String) -> bool {\n        match self {\n            SourceItemOrderingWithinModuleItemGroupings::All => true,\n            SourceItemOrderingWithinModuleItemGroupings::None => false,\n            SourceItemOrderingWithinModuleItemGroupings::Custom(groups) => groups.contains(grouping_name),\n        }\n    }\n}\n\n/// Helper struct for deserializing the [`SourceItemOrderingWithinModuleItemGroupings`].\n#[derive(Deserialize)]\n#[serde(untagged)]\nenum StringOrVecOfString {\n    String(String),\n    Vec(Vec<String>),\n}\n\nimpl<'de> Deserialize<'de> for SourceItemOrderingWithinModuleItemGroupings {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let description = \"The available options for configuring an ordering within module item groups are: \\\n                    \\\"all\\\", \\\"none\\\", or a list of module item group names \\\n                    (as configured with the `module-item-order-groupings` configuration option).\";\n\n        match StringOrVecOfString::deserialize(deserializer) {\n            Ok(StringOrVecOfString::String(preset)) if preset == \"all\" => {\n                Ok(SourceItemOrderingWithinModuleItemGroupings::All)\n            },\n            Ok(StringOrVecOfString::String(preset)) if preset == \"none\" => {\n                Ok(SourceItemOrderingWithinModuleItemGroupings::None)\n            },\n            Ok(StringOrVecOfString::String(preset)) => Err(de::Error::custom(format!(\n                \"Unknown configuration option: {preset}.\\n{description}\"\n            ))),\n            Ok(StringOrVecOfString::Vec(groupings)) => {\n                Ok(SourceItemOrderingWithinModuleItemGroupings::Custom(groupings))\n            },\n            Err(e) => Err(de::Error::custom(format!(\"{e}\\n{description}\"))),\n        }\n    }\n}\n\nimpl Serialize for SourceItemOrderingWithinModuleItemGroupings {\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: ser::Serializer,\n    {\n        match self {\n            SourceItemOrderingWithinModuleItemGroupings::All => serializer.serialize_str(\"all\"),\n            SourceItemOrderingWithinModuleItemGroupings::None => serializer.serialize_str(\"none\"),\n            SourceItemOrderingWithinModuleItemGroupings::Custom(vec) => vec.serialize(serializer),\n        }\n    }\n}\n\n// these impls are never actually called but are used by the various config options that default to\n// empty lists\nmacro_rules! unimplemented_serialize {\n    ($($t:ty,)*) => {\n        $(\n            impl Serialize for $t {\n                fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>\n                where\n                    S: ser::Serializer,\n                {\n                    Err(ser::Error::custom(\"unimplemented\"))\n                }\n            }\n        )*\n    }\n}\n\nunimplemented_serialize! {\n    Rename,\n    MacroMatcher,\n}\n\n#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]\npub enum PubUnderscoreFieldsBehaviour {\n    PubliclyExported,\n    AllPubFields,\n}\n\n#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]\n#[serde(rename_all = \"lowercase\")]\npub enum InherentImplLintScope {\n    Crate,\n    File,\n    Module,\n}\n"
  },
  {
    "path": "clippy_dev/Cargo.toml",
    "content": "[package]\nname = \"clippy_dev\"\ndescription = \"Clippy developer tooling\"\nversion = \"0.0.1\"\nedition = \"2024\"\n\n[dependencies]\nchrono = { version = \"0.4.38\", default-features = false, features = [\"clock\"] }\nclap = { version = \"4.4\", features = [\"derive\"] }\nindoc = \"1.0\"\nitertools = \"0.12\"\nopener = \"0.7\"\nrustc-literal-escaper = \"0.0.7\"\nwalkdir = \"2.3\"\n\n[package.metadata.rust-analyzer]\n# This package uses #[feature(rustc_private)]\nrustc_private = true\n"
  },
  {
    "path": "clippy_dev/src/deprecate_lint.rs",
    "content": "use crate::parse::{DeprecatedLint, Lint, ParseCx, RenamedLint};\nuse crate::update_lints::generate_lint_files;\nuse crate::utils::{UpdateMode, Version};\nuse std::ffi::OsStr;\nuse std::path::{Path, PathBuf};\nuse std::{fs, io};\n\n/// Runs the `deprecate` command\n///\n/// This does the following:\n/// * Adds an entry to `deprecated_lints.rs`.\n/// * Removes the lint declaration (and the entire file if applicable)\n///\n/// # Panics\n///\n/// If a file path could not read from or written to\npub fn deprecate<'cx>(cx: ParseCx<'cx>, clippy_version: Version, name: &'cx str, reason: &'cx str) {\n    let mut lints = cx.find_lint_decls();\n    let (mut deprecated_lints, renamed_lints) = cx.read_deprecated_lints();\n\n    let Some(lint) = lints.iter().find(|l| l.name == name) else {\n        eprintln!(\"error: failed to find lint `{name}`\");\n        return;\n    };\n\n    let prefixed_name = cx.str_buf.with(|buf| {\n        buf.extend([\"clippy::\", name]);\n        cx.arena.alloc_str(buf)\n    });\n    match deprecated_lints.binary_search_by(|x| x.name.cmp(prefixed_name)) {\n        Ok(_) => {\n            println!(\"`{name}` is already deprecated\");\n            return;\n        },\n        Err(idx) => deprecated_lints.insert(\n            idx,\n            DeprecatedLint {\n                name: prefixed_name,\n                reason,\n                version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),\n            },\n        ),\n    }\n\n    let mod_path = {\n        let mut mod_path = PathBuf::from(format!(\"clippy_lints/src/{}\", lint.module));\n        if mod_path.is_dir() {\n            mod_path = mod_path.join(\"mod\");\n        }\n\n        mod_path.set_extension(\"rs\");\n        mod_path\n    };\n\n    if remove_lint_declaration(name, &mod_path, &mut lints).unwrap_or(false) {\n        generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);\n        println!(\"info: `{name}` has successfully been deprecated\");\n        println!(\"note: you must run `cargo uitest` to update the test results\");\n    } else {\n        eprintln!(\"error: lint not found\");\n    }\n}\n\npub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'env str, new_name: &'env str) {\n    let mut lints = cx.find_lint_decls();\n    let (deprecated_lints, mut renamed_lints) = cx.read_deprecated_lints();\n\n    let Some(lint) = lints.iter().find(|l| l.name == old_name) else {\n        eprintln!(\"error: failed to find lint `{old_name}`\");\n        return;\n    };\n\n    let old_name_prefixed = cx.str_buf.with(|buf| {\n        buf.extend([\"clippy::\", old_name]);\n        cx.arena.alloc_str(buf)\n    });\n    for lint in &mut renamed_lints {\n        if lint.new_name == old_name_prefixed {\n            lint.new_name = new_name;\n        }\n    }\n    match renamed_lints.binary_search_by(|x| x.old_name.cmp(old_name_prefixed)) {\n        Ok(_) => {\n            println!(\"`{old_name}` is already deprecated\");\n            return;\n        },\n        Err(idx) => renamed_lints.insert(\n            idx,\n            RenamedLint {\n                old_name: old_name_prefixed,\n                new_name,\n                version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),\n            },\n        ),\n    }\n\n    let mod_path = {\n        let mut mod_path = PathBuf::from(format!(\"clippy_lints/src/{}\", lint.module));\n        if mod_path.is_dir() {\n            mod_path = mod_path.join(\"mod\");\n        }\n\n        mod_path.set_extension(\"rs\");\n        mod_path\n    };\n\n    if remove_lint_declaration(old_name, &mod_path, &mut lints).unwrap_or(false) {\n        generate_lint_files(UpdateMode::Change, &lints, &deprecated_lints, &renamed_lints);\n        println!(\"info: `{old_name}` has successfully been uplifted\");\n        println!(\"note: you must run `cargo uitest` to update the test results\");\n    } else {\n        eprintln!(\"error: lint not found\");\n    }\n}\n\nfn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint<'_>>) -> io::Result<bool> {\n    fn remove_lint(name: &str, lints: &mut Vec<Lint<'_>>) {\n        lints.iter().position(|l| l.name == name).map(|pos| lints.remove(pos));\n    }\n\n    fn remove_test_assets(name: &str) {\n        let test_file_stem = format!(\"tests/ui/{name}\");\n        let path = Path::new(&test_file_stem);\n\n        // Some lints have their own directories, delete them\n        if path.is_dir() {\n            let _ = fs::remove_dir_all(path);\n            return;\n        }\n\n        // Remove all related test files\n        let _ = fs::remove_file(path.with_extension(\"rs\"));\n        let _ = fs::remove_file(path.with_extension(\"stderr\"));\n        let _ = fs::remove_file(path.with_extension(\"fixed\"));\n    }\n\n    fn remove_impl_lint_pass(lint_name_upper: &str, content: &mut String) {\n        let impl_lint_pass_start = content.find(\"impl_lint_pass!\").unwrap_or_else(|| {\n            content\n                .find(\"declare_lint_pass!\")\n                .unwrap_or_else(|| panic!(\"failed to find `impl_lint_pass`\"))\n        });\n        let mut impl_lint_pass_end = content[impl_lint_pass_start..]\n            .find(']')\n            .expect(\"failed to find `impl_lint_pass` terminator\");\n\n        impl_lint_pass_end += impl_lint_pass_start;\n        if let Some(lint_name_pos) = content[impl_lint_pass_start..impl_lint_pass_end].find(lint_name_upper) {\n            let mut lint_name_end = impl_lint_pass_start + (lint_name_pos + lint_name_upper.len());\n            for c in content[lint_name_end..impl_lint_pass_end].chars() {\n                // Remove trailing whitespace\n                if c == ',' || c.is_whitespace() {\n                    lint_name_end += 1;\n                } else {\n                    break;\n                }\n            }\n\n            content.replace_range(impl_lint_pass_start + lint_name_pos..lint_name_end, \"\");\n        }\n    }\n\n    if path.exists()\n        && let Some(lint) = lints.iter().find(|l| l.name == name)\n    {\n        if lint.module == name {\n            // The lint name is the same as the file, we can just delete the entire file\n            fs::remove_file(path)?;\n        } else {\n            // We can't delete the entire file, just remove the declaration\n\n            if let Some(Some(\"mod.rs\")) = path.file_name().map(OsStr::to_str) {\n                // Remove clippy_lints/src/some_mod/some_lint.rs\n                let mut lint_mod_path = path.to_path_buf();\n                lint_mod_path.set_file_name(name);\n                lint_mod_path.set_extension(\"rs\");\n\n                let _ = fs::remove_file(lint_mod_path);\n            }\n\n            let mut content =\n                fs::read_to_string(path).unwrap_or_else(|_| panic!(\"failed to read `{}`\", path.to_string_lossy()));\n\n            eprintln!(\n                \"warn: you will have to manually remove any code related to `{name}` from `{}`\",\n                path.display()\n            );\n\n            assert!(\n                content[lint.declaration_range].contains(&name.to_uppercase()),\n                \"error: `{}` does not contain lint `{}`'s declaration\",\n                path.display(),\n                lint.name\n            );\n\n            // Remove lint declaration (declare_clippy_lint!)\n            content.replace_range(lint.declaration_range, \"\");\n\n            // Remove the module declaration (mod xyz;)\n            let mod_decl = format!(\"\\nmod {name};\");\n            content = content.replacen(&mod_decl, \"\", 1);\n\n            remove_impl_lint_pass(&lint.name.to_uppercase(), &mut content);\n            fs::write(path, content).unwrap_or_else(|_| panic!(\"failed to write to `{}`\", path.to_string_lossy()));\n        }\n\n        remove_test_assets(name);\n        remove_lint(name, lints);\n        return Ok(true);\n    }\n\n    Ok(false)\n}\n"
  },
  {
    "path": "clippy_dev/src/dogfood.rs",
    "content": "use crate::utils::{cargo_cmd, run_exit_on_err};\nuse itertools::Itertools;\n\n/// # Panics\n///\n/// Panics if unable to run the dogfood test\n#[expect(clippy::fn_params_excessive_bools)]\npub fn dogfood(fix: bool, allow_dirty: bool, allow_staged: bool, allow_no_vcs: bool) {\n    run_exit_on_err(\n        \"cargo test\",\n        cargo_cmd()\n            .args([\"test\", \"--test\", \"dogfood\"])\n            .args([\"--features\", \"internal\"])\n            .args([\"--\", \"dogfood_clippy\", \"--nocapture\"])\n            .env(\n                \"__CLIPPY_DOGFOOD_ARGS\",\n                [\n                    if fix { \"--fix\" } else { \"\" },\n                    if allow_dirty { \"--allow-dirty\" } else { \"\" },\n                    if allow_staged { \"--allow-staged\" } else { \"\" },\n                    if allow_no_vcs { \"--allow-no-vcs\" } else { \"\" },\n                ]\n                .iter()\n                .filter(|x| !x.is_empty())\n                .join(\" \"),\n            ),\n    );\n}\n"
  },
  {
    "path": "clippy_dev/src/edit_lints.rs",
    "content": "use crate::parse::cursor::{self, Capture, Cursor};\nuse crate::parse::{ActiveLint, DeprecatedLint, Lint, LintData, LintName, ParseCx, RenamedLint};\nuse crate::utils::{\n    ErrAction, FileUpdater, UpdateMode, UpdateStatus, Version, delete_dir_if_exists, delete_file_if_exists,\n    expect_action, try_rename_dir, try_rename_file, walk_dir_no_dot_or_target,\n};\nuse core::mem;\nuse rustc_lexer::TokenKind;\nuse std::collections::hash_map::Entry;\nuse std::ffi::OsString;\nuse std::fs;\nuse std::path::Path;\n\n/// Runs the `deprecate` command\n///\n/// This does the following:\n/// * Adds an entry to `deprecated_lints.rs`.\n/// * Removes the lint declaration (and the entire file if applicable)\n///\n/// # Panics\n///\n/// If a file path could not read from or written to\npub fn deprecate<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, name: &'env str, reason: &'env str) {\n    let mut data = cx.parse_lint_decls();\n\n    let Entry::Occupied(mut lint) = data.lints.entry(name) else {\n        eprintln!(\"error: failed to find lint `{name}`\");\n        return;\n    };\n    let Lint::Active(prev_lint) = mem::replace(\n        lint.get_mut(),\n        Lint::Deprecated(DeprecatedLint {\n            reason,\n            version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),\n        }),\n    ) else {\n        eprintln!(\"error: `{name}` is already deprecated\");\n        return;\n    };\n\n    remove_lint_declaration(name, &prev_lint, &data, &mut FileUpdater::default());\n    data.gen_decls(UpdateMode::Change);\n    println!(\"info: `{name}` has successfully been deprecated\");\n    println!(\"note: you must run `cargo uitest` to update the test results\");\n}\n\npub fn uplift<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'env str, new_name: &'env str) {\n    let mut data = cx.parse_lint_decls();\n\n    update_rename_targets(&mut data, old_name, LintName::new_rustc(new_name));\n\n    let Entry::Occupied(mut lint) = data.lints.entry(old_name) else {\n        eprintln!(\"error: failed to find lint `{old_name}`\");\n        return;\n    };\n    let Lint::Active(prev_lint) = mem::replace(\n        lint.get_mut(),\n        Lint::Renamed(RenamedLint {\n            new_name: LintName::new_rustc(new_name),\n            version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),\n        }),\n    ) else {\n        eprintln!(\"error: `{old_name}` is already deprecated\");\n        return;\n    };\n\n    let mut updater = FileUpdater::default();\n    let remove_mod = remove_lint_declaration(old_name, &prev_lint, &data, &mut updater);\n    let mut update_fn = uplift_update_fn(old_name, new_name, remove_mod);\n    for e in walk_dir_no_dot_or_target(\".\") {\n        let e = expect_action(e, ErrAction::Read, \".\");\n        if e.path().as_os_str().as_encoded_bytes().ends_with(b\".rs\") {\n            updater.update_file(e.path(), &mut update_fn);\n        }\n    }\n    data.gen_decls(UpdateMode::Change);\n    println!(\"info: `{old_name}` has successfully been uplifted as `{new_name}`\");\n    println!(\"note: you must run `cargo uitest` to update the test results\");\n}\n\n/// Runs the `rename_lint` command.\n///\n/// This does the following:\n/// * Adds an entry to `renamed_lints.rs`.\n/// * Renames all lint attributes to the new name (e.g. `#[allow(clippy::lint_name)]`).\n/// * Renames the lint struct to the new name.\n/// * Renames the module containing the lint struct to the new name if it shares a name with the\n///   lint.\n///\n/// # Panics\n/// Panics for the following conditions:\n/// * If a file path could not read from or then written to\n/// * If either lint name has a prefix\n/// * If `old_name` doesn't name an existing lint.\n/// * If `old_name` names a deprecated or renamed lint.\npub fn rename<'cx, 'env: 'cx>(cx: ParseCx<'cx>, clippy_version: Version, old_name: &'env str, new_name: &'env str) {\n    let mut updater = FileUpdater::default();\n    let mut data = cx.parse_lint_decls();\n\n    update_rename_targets(&mut data, old_name, LintName::new_clippy(new_name));\n\n    let Entry::Occupied(mut lint) = data.lints.entry(old_name) else {\n        eprintln!(\"error: failed to find lint `{old_name}`\");\n        return;\n    };\n    let Lint::Active(mut prev_lint) = mem::replace(\n        lint.get_mut(),\n        Lint::Renamed(RenamedLint {\n            new_name: LintName::new_clippy(new_name),\n            version: cx.str_buf.alloc_display(cx.arena, clippy_version.rust_display()),\n        }),\n    ) else {\n        eprintln!(\"error: `{old_name}` is already deprecated\");\n        return;\n    };\n\n    let mut rename_mod = false;\n    if let Entry::Vacant(e) = data.lints.entry(new_name) {\n        if prev_lint.module.ends_with(old_name)\n            && prev_lint\n                .path\n                .file_stem()\n                .is_some_and(|x| x.as_encoded_bytes() == old_name.as_bytes())\n        {\n            let mut new_path = prev_lint.path.with_file_name(new_name).into_os_string();\n            new_path.push(\".rs\");\n            if try_rename_file(prev_lint.path.as_ref(), new_path.as_ref()) {\n                rename_mod = true;\n            }\n\n            prev_lint.module = cx.str_buf.with(|buf| {\n                buf.push_str(&prev_lint.module[..prev_lint.module.len() - old_name.len()]);\n                buf.push_str(new_name);\n                cx.arena.alloc_str(buf)\n            });\n        }\n        e.insert(Lint::Active(prev_lint));\n\n        rename_test_files(old_name, new_name, &create_ignored_prefixes(old_name, &data));\n    } else {\n        println!(\"Renamed `{old_name}` to `{new_name}`\");\n        println!(\"Since `{new_name}` already exists the existing code has not been changed\");\n        return;\n    }\n\n    let mut update_fn = rename_update_fn(old_name, new_name, rename_mod);\n    for e in walk_dir_no_dot_or_target(\".\") {\n        let e = expect_action(e, ErrAction::Read, \".\");\n        if e.path().as_os_str().as_encoded_bytes().ends_with(b\".rs\") {\n            updater.update_file(e.path(), &mut update_fn);\n        }\n    }\n    data.gen_decls(UpdateMode::Change);\n\n    println!(\"Renamed `{old_name}` to `{new_name}`\");\n    println!(\"All code referencing the old name has been updated\");\n    println!(\"Make sure to inspect the results as some things may have been missed\");\n    println!(\"note: `cargo uibless` still needs to be run to update the test results\");\n}\n\n/// Removes a lint's declaration and test files. Returns whether the module containing the\n/// lint was deleted.\nfn remove_lint_declaration(name: &str, lint: &ActiveLint<'_>, data: &LintData<'_>, updater: &mut FileUpdater) -> bool {\n    let delete_mod = if data.lints.iter().all(|(_, l)| {\n        if let Lint::Active(l) = l {\n            l.module != lint.module\n        } else {\n            true\n        }\n    }) {\n        delete_file_if_exists(lint.path.as_ref())\n    } else {\n        updater.update_file(&lint.path, &mut |_, src, dst| -> UpdateStatus {\n            let mut start = &src[..lint.declaration_range.start as usize];\n            if start.ends_with(\"\\n\\n\") {\n                start = &start[..start.len() - 1];\n            }\n            let mut end = &src[lint.declaration_range.end as usize..];\n            if end.starts_with(\"\\n\\n\") {\n                end = &end[1..];\n            }\n            dst.push_str(start);\n            dst.push_str(end);\n            UpdateStatus::Changed\n        });\n        false\n    };\n    delete_test_files(name, &create_ignored_prefixes(name, data));\n\n    delete_mod\n}\n\n/// Updates all renames to the old name to be renames to the new name.\n///\n/// This is needed because rustc doesn't allow a lint to be renamed to a lint that has\n/// also been renamed.\nfn update_rename_targets<'cx>(data: &mut LintData<'cx>, old_name: &str, new_name: LintName<'cx>) {\n    let old_name = LintName::new_clippy(old_name);\n    for lint in data.lints.values_mut() {\n        if let Lint::Renamed(lint) = lint\n            && lint.new_name == old_name\n        {\n            lint.new_name = new_name;\n        }\n    }\n}\n\n/// Creates a list of prefixes to ignore when\nfn create_ignored_prefixes<'cx>(name: &str, data: &LintData<'cx>) -> Vec<&'cx str> {\n    data.lints\n        .keys()\n        .copied()\n        .filter(|&x| x.len() > name.len() && x.starts_with(name))\n        .collect()\n}\n\nfn collect_ui_test_names(lint: &str, ignored_prefixes: &[&str], dst: &mut Vec<(OsString, bool)>) {\n    for e in fs::read_dir(\"tests/ui\").expect(\"error reading `tests/ui`\") {\n        let e = e.expect(\"error reading `tests/ui`\");\n        let name = e.file_name();\n        if name.as_encoded_bytes().starts_with(lint.as_bytes())\n            && !ignored_prefixes\n                .iter()\n                .any(|&pre| name.as_encoded_bytes().starts_with(pre.as_bytes()))\n            && let Ok(ty) = e.file_type()\n            && (ty.is_file() || ty.is_dir())\n        {\n            dst.push((name, ty.is_file()));\n        }\n    }\n}\n\nfn collect_ui_toml_test_names(lint: &str, ignored_prefixes: &[&str], dst: &mut Vec<(OsString, bool)>) {\n    for e in fs::read_dir(\"tests/ui-toml\").expect(\"error reading `tests/ui-toml`\") {\n        let e = e.expect(\"error reading `tests/ui-toml`\");\n        let name = e.file_name();\n        if name.as_encoded_bytes().starts_with(lint.as_bytes())\n            && !ignored_prefixes\n                .iter()\n                .any(|&pre| name.as_encoded_bytes().starts_with(pre.as_bytes()))\n            && e.file_type().is_ok_and(|ty| ty.is_dir())\n        {\n            dst.push((name, false));\n        }\n    }\n}\n\n/// Renames all test files for the given lint where the file name does not start with any\n/// of the given prefixes.\nfn rename_test_files(old_name: &str, new_name: &str, ignored_prefixes: &[&str]) {\n    let mut tests: Vec<(OsString, bool)> = Vec::new();\n\n    let mut old_buf = OsString::from(\"tests/ui/\");\n    let mut new_buf = OsString::from(\"tests/ui/\");\n    collect_ui_test_names(old_name, ignored_prefixes, &mut tests);\n    for &(ref name, is_file) in &tests {\n        old_buf.push(name);\n        new_buf.extend([new_name.as_ref(), name.slice_encoded_bytes(old_name.len()..)]);\n        if is_file {\n            try_rename_file(old_buf.as_ref(), new_buf.as_ref());\n        } else {\n            try_rename_dir(old_buf.as_ref(), new_buf.as_ref());\n        }\n        old_buf.truncate(\"tests/ui/\".len());\n        new_buf.truncate(\"tests/ui/\".len());\n    }\n\n    tests.clear();\n    old_buf.truncate(\"tests/ui\".len());\n    new_buf.truncate(\"tests/ui\".len());\n    old_buf.push(\"-toml/\");\n    new_buf.push(\"-toml/\");\n    collect_ui_toml_test_names(old_name, ignored_prefixes, &mut tests);\n    for (name, _) in &tests {\n        old_buf.push(name);\n        new_buf.extend([new_name.as_ref(), name.slice_encoded_bytes(old_name.len()..)]);\n        try_rename_dir(old_buf.as_ref(), new_buf.as_ref());\n        old_buf.truncate(\"tests/ui/\".len());\n        new_buf.truncate(\"tests/ui/\".len());\n    }\n}\n\n/// Deletes all test files for the given lint where the file name does not start with any\n/// of the given prefixes.\nfn delete_test_files(lint: &str, ignored_prefixes: &[&str]) {\n    let mut tests = Vec::new();\n\n    let mut buf = OsString::from(\"tests/ui/\");\n    collect_ui_test_names(lint, ignored_prefixes, &mut tests);\n    for &(ref name, is_file) in &tests {\n        buf.push(name);\n        if is_file {\n            delete_file_if_exists(buf.as_ref());\n        } else {\n            delete_dir_if_exists(buf.as_ref());\n        }\n        buf.truncate(\"tests/ui/\".len());\n    }\n\n    buf.truncate(\"tests/ui\".len());\n    buf.push(\"-toml/\");\n\n    tests.clear();\n    collect_ui_toml_test_names(lint, ignored_prefixes, &mut tests);\n    for (name, _) in &tests {\n        buf.push(name);\n        delete_dir_if_exists(buf.as_ref());\n        buf.truncate(\"tests/ui/\".len());\n    }\n}\n\nfn snake_to_pascal(s: &str) -> String {\n    let mut dst = Vec::with_capacity(s.len());\n    let mut iter = s.bytes();\n    || -> Option<()> {\n        dst.push(iter.next()?.to_ascii_uppercase());\n        while let Some(c) = iter.next() {\n            if c == b'_' {\n                dst.push(iter.next()?.to_ascii_uppercase());\n            } else {\n                dst.push(c);\n            }\n        }\n        Some(())\n    }();\n    String::from_utf8(dst).unwrap()\n}\n\n/// Creates an update function which replaces all instances of `clippy::old_name` with\n/// `new_name`.\nfn uplift_update_fn<'a>(\n    old_name: &'a str,\n    new_name: &'a str,\n    remove_mod: bool,\n) -> impl use<'a> + FnMut(&Path, &str, &mut String) -> UpdateStatus {\n    move |_, src, dst| {\n        let mut copy_pos = 0u32;\n        let mut changed = false;\n        let mut cursor = Cursor::new(src);\n        while let Some(ident) = cursor.find_any_ident() {\n            match cursor.get_text(ident) {\n                \"mod\"\n                    if remove_mod && cursor.match_all(&[cursor::Pat::Ident(old_name), cursor::Pat::Semi], &mut []) =>\n                {\n                    dst.push_str(&src[copy_pos as usize..ident.pos as usize]);\n                    dst.push_str(new_name);\n                    copy_pos = cursor.pos();\n                    if src[copy_pos as usize..].starts_with('\\n') {\n                        copy_pos += 1;\n                    }\n                    changed = true;\n                },\n                \"clippy\" if cursor.match_all(&[cursor::Pat::DoubleColon, cursor::Pat::Ident(old_name)], &mut []) => {\n                    dst.push_str(&src[copy_pos as usize..ident.pos as usize]);\n                    dst.push_str(new_name);\n                    copy_pos = cursor.pos();\n                    changed = true;\n                },\n\n                _ => {},\n            }\n        }\n        dst.push_str(&src[copy_pos as usize..]);\n        UpdateStatus::from_changed(changed)\n    }\n}\n\nfn rename_update_fn<'a>(\n    old_name: &'a str,\n    new_name: &'a str,\n    rename_mod: bool,\n) -> impl use<'a> + FnMut(&Path, &str, &mut String) -> UpdateStatus {\n    let old_name_pascal = snake_to_pascal(old_name);\n    let new_name_pascal = snake_to_pascal(new_name);\n    let old_name_upper = old_name.to_ascii_uppercase();\n    let new_name_upper = new_name.to_ascii_uppercase();\n    move |_, src, dst| {\n        let mut copy_pos = 0u32;\n        let mut changed = false;\n        let mut cursor = Cursor::new(src);\n        let mut captures = [Capture::EMPTY];\n        loop {\n            match cursor.peek() {\n                TokenKind::Eof => break,\n                TokenKind::Ident => {\n                    let match_start = cursor.pos();\n                    let text = cursor.peek_text();\n                    cursor.step();\n                    match text {\n                        // clippy::line_name or clippy::lint-name\n                        \"clippy\" => {\n                            if cursor.match_all(&[cursor::Pat::DoubleColon, cursor::Pat::CaptureIdent], &mut captures)\n                                && cursor.get_text(captures[0]) == old_name\n                            {\n                                dst.push_str(&src[copy_pos as usize..captures[0].pos as usize]);\n                                dst.push_str(new_name);\n                                copy_pos = cursor.pos();\n                                changed = true;\n                            }\n                        },\n                        // mod lint_name\n                        \"mod\" => {\n                            if rename_mod && let Some(pos) = cursor.match_ident(old_name) {\n                                dst.push_str(&src[copy_pos as usize..pos as usize]);\n                                dst.push_str(new_name);\n                                copy_pos = cursor.pos();\n                                changed = true;\n                            }\n                        },\n                        // lint_name::\n                        name if rename_mod && name == old_name => {\n                            let name_end = cursor.pos();\n                            if cursor.match_pat(cursor::Pat::DoubleColon) {\n                                dst.push_str(&src[copy_pos as usize..match_start as usize]);\n                                dst.push_str(new_name);\n                                copy_pos = name_end;\n                                changed = true;\n                            }\n                        },\n                        // LINT_NAME or LintName\n                        name => {\n                            let replacement = if name == old_name_upper {\n                                &new_name_upper\n                            } else if name == old_name_pascal {\n                                &new_name_pascal\n                            } else {\n                                continue;\n                            };\n                            dst.push_str(&src[copy_pos as usize..match_start as usize]);\n                            dst.push_str(replacement);\n                            copy_pos = cursor.pos();\n                            changed = true;\n                        },\n                    }\n                },\n                // //~ lint_name\n                TokenKind::LineComment { doc_style: None } => {\n                    let text = cursor.peek_text();\n                    if text.starts_with(\"//~\")\n                        && let Some(text) = text.strip_suffix(old_name)\n                        && !text.ends_with(|c| matches!(c, 'a'..='z' | 'A'..='Z' | '0'..='9' | '_'))\n                    {\n                        dst.push_str(&src[copy_pos as usize..cursor.pos() as usize + text.len()]);\n                        dst.push_str(new_name);\n                        copy_pos = cursor.pos() + cursor.peek_len();\n                        changed = true;\n                    }\n                    cursor.step();\n                },\n                // ::lint_name\n                TokenKind::Colon\n                    if cursor.match_all(&[cursor::Pat::DoubleColon, cursor::Pat::CaptureIdent], &mut captures)\n                        && cursor.get_text(captures[0]) == old_name =>\n                {\n                    dst.push_str(&src[copy_pos as usize..captures[0].pos as usize]);\n                    dst.push_str(new_name);\n                    copy_pos = cursor.pos();\n                    changed = true;\n                },\n                _ => cursor.step(),\n            }\n        }\n\n        dst.push_str(&src[copy_pos as usize..]);\n        UpdateStatus::from_changed(changed)\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/fmt.rs",
    "content": "use crate::generate::gen_sorted_lints_file;\nuse crate::new_parse_cx;\nuse crate::parse::VecBuf;\nuse crate::utils::{\n    ErrAction, FileUpdater, UpdateMode, UpdateStatus, expect_action, run_with_output, split_args_for_threads,\n    walk_dir_no_dot_or_target,\n};\nuse itertools::Itertools;\nuse rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};\nuse std::fmt::Write;\nuse std::fs;\nuse std::io::{self, Read};\nuse std::ops::ControlFlow;\nuse std::path::PathBuf;\nuse std::process::{self, Command, Stdio};\n\npub enum Error {\n    Io(io::Error),\n    Parse(PathBuf, usize, String),\n    CheckFailed,\n}\n\nimpl From<io::Error> for Error {\n    fn from(error: io::Error) -> Self {\n        Self::Io(error)\n    }\n}\n\nimpl Error {\n    fn display(&self) {\n        match self {\n            Self::CheckFailed => {\n                eprintln!(\"Formatting check failed!\\nRun `cargo dev fmt` to update.\");\n            },\n            Self::Io(err) => {\n                eprintln!(\"error: {err}\");\n            },\n            Self::Parse(path, line, msg) => {\n                eprintln!(\"error parsing `{}:{line}`: {msg}\", path.display());\n            },\n        }\n    }\n}\n\nstruct ClippyConf<'a> {\n    name: &'a str,\n    attrs: &'a str,\n    lints: Vec<&'a str>,\n    field: &'a str,\n}\n\nfn offset_to_line(text: &str, offset: usize) -> usize {\n    match text.split('\\n').try_fold((1usize, 0usize), |(line, pos), s| {\n        let pos = pos + s.len() + 1;\n        if pos > offset {\n            ControlFlow::Break(line)\n        } else {\n            ControlFlow::Continue((line + 1, pos))\n        }\n    }) {\n        ControlFlow::Break(x) | ControlFlow::Continue((x, _)) => x,\n    }\n}\n\n/// Formats the configuration list in `clippy_config/src/conf.rs`\n#[expect(clippy::too_many_lines)]\nfn fmt_conf(check: bool) -> Result<(), Error> {\n    #[derive(Clone, Copy)]\n    enum State {\n        Start,\n        Docs,\n        Pound,\n        OpenBracket,\n        Attr(u32),\n        Lints,\n        EndLints,\n        Field,\n    }\n\n    let path = \"clippy_config/src/conf.rs\";\n    let text = fs::read_to_string(path)?;\n\n    let (pre, conf) = text\n        .split_once(\"define_Conf! {\\n\")\n        .expect(\"can't find config definition\");\n    let (conf, post) = conf.split_once(\"\\n}\\n\").expect(\"can't find config definition\");\n    let conf_offset = pre.len() + 15;\n\n    let mut pos = 0u32;\n    let mut attrs_start = 0;\n    let mut attrs_end = 0;\n    let mut field_start = 0;\n    let mut lints = Vec::new();\n    let mut name = \"\";\n    let mut fields = Vec::new();\n    let mut state = State::Start;\n\n    for (i, t) in tokenize(conf, FrontmatterAllowed::No)\n        .map(|x| {\n            let start = pos;\n            pos += x.len;\n            (start as usize, x)\n        })\n        .filter(|(_, t)| !matches!(t.kind, TokenKind::Whitespace))\n    {\n        match (state, t.kind) {\n            (State::Start, TokenKind::LineComment { doc_style: Some(_) }) => {\n                attrs_start = i;\n                attrs_end = i + t.len as usize;\n                state = State::Docs;\n            },\n            (State::Start, TokenKind::Pound) => {\n                attrs_start = i;\n                attrs_end = i;\n                state = State::Pound;\n            },\n            (State::Docs, TokenKind::LineComment { doc_style: Some(_) }) => attrs_end = i + t.len as usize,\n            (State::Docs, TokenKind::Pound) => state = State::Pound,\n            (State::Pound, TokenKind::OpenBracket) => state = State::OpenBracket,\n            (State::OpenBracket, TokenKind::Ident) => {\n                state = if conf[i..i + t.len as usize] == *\"lints\" {\n                    State::Lints\n                } else {\n                    State::Attr(0)\n                };\n            },\n            (State::Attr(0), TokenKind::CloseBracket) => {\n                attrs_end = i + 1;\n                state = State::Docs;\n            },\n            (State::Attr(x), TokenKind::OpenParen | TokenKind::OpenBracket | TokenKind::OpenBrace) => {\n                state = State::Attr(x + 1);\n            },\n            (State::Attr(x), TokenKind::CloseParen | TokenKind::CloseBracket | TokenKind::CloseBrace) => {\n                state = State::Attr(x - 1);\n            },\n            (State::Lints, TokenKind::Ident) => lints.push(&conf[i..i + t.len as usize]),\n            (State::Lints, TokenKind::CloseBracket) => state = State::EndLints,\n            (State::EndLints | State::Docs, TokenKind::Ident) => {\n                field_start = i;\n                name = &conf[i..i + t.len as usize];\n                state = State::Field;\n            },\n            (State::Field, TokenKind::LineComment { doc_style: Some(_) }) => {\n                #[expect(clippy::drain_collect)]\n                fields.push(ClippyConf {\n                    name,\n                    attrs: &conf[attrs_start..attrs_end],\n                    lints: lints.drain(..).collect(),\n                    field: conf[field_start..i].trim_end(),\n                });\n                attrs_start = i;\n                attrs_end = i + t.len as usize;\n                state = State::Docs;\n            },\n            (State::Field, TokenKind::Pound) => {\n                #[expect(clippy::drain_collect)]\n                fields.push(ClippyConf {\n                    name,\n                    attrs: &conf[attrs_start..attrs_end],\n                    lints: lints.drain(..).collect(),\n                    field: conf[field_start..i].trim_end(),\n                });\n                attrs_start = i;\n                attrs_end = i;\n                state = State::Pound;\n            },\n            (State::Field | State::Attr(_), _)\n            | (State::Lints, TokenKind::Comma | TokenKind::OpenParen | TokenKind::CloseParen) => {},\n            _ => {\n                return Err(Error::Parse(\n                    PathBuf::from(path),\n                    offset_to_line(&text, conf_offset + i),\n                    format!(\"unexpected token `{}`\", &conf[i..i + t.len as usize]),\n                ));\n            },\n        }\n    }\n\n    if !matches!(state, State::Field) {\n        return Err(Error::Parse(\n            PathBuf::from(path),\n            offset_to_line(&text, conf_offset + conf.len()),\n            \"incomplete field\".into(),\n        ));\n    }\n    fields.push(ClippyConf {\n        name,\n        attrs: &conf[attrs_start..attrs_end],\n        lints,\n        field: conf[field_start..].trim_end(),\n    });\n\n    for field in &mut fields {\n        field.lints.sort_unstable();\n    }\n    fields.sort_by_key(|x| x.name);\n\n    let new_text = format!(\n        \"{pre}define_Conf! {{\\n{}}}\\n{post}\",\n        fields.iter().format_with(\"\", |field, f| {\n            if field.lints.is_empty() {\n                f(&format_args!(\"    {}\\n    {}\\n\", field.attrs, field.field))\n            } else if field.lints.iter().map(|x| x.len() + 2).sum::<usize>() < 120 - 14 {\n                f(&format_args!(\n                    \"    {}\\n    #[lints({})]\\n    {}\\n\",\n                    field.attrs,\n                    field.lints.iter().join(\", \"),\n                    field.field,\n                ))\n            } else {\n                f(&format_args!(\n                    \"    {}\\n    #[lints({}\\n    )]\\n    {}\\n\",\n                    field.attrs,\n                    field\n                        .lints\n                        .iter()\n                        .format_with(\"\", |x, f| f(&format_args!(\"\\n        {x},\"))),\n                    field.field,\n                ))\n            }\n        })\n    );\n\n    if text != new_text {\n        if check {\n            return Err(Error::CheckFailed);\n        }\n        fs::write(path, new_text)?;\n    }\n    Ok(())\n}\n\n/// Format the symbols list\nfn fmt_syms(update_mode: UpdateMode) {\n    FileUpdater::default().update_file_checked(\n        \"cargo dev fmt\",\n        update_mode,\n        \"clippy_utils/src/sym.rs\",\n        &mut |_, text: &str, new_text: &mut String| {\n            let (pre, conf) = text.split_once(\"generate! {\\n\").expect(\"can't find generate! call\");\n            let (conf, post) = conf.split_once(\"\\n}\\n\").expect(\"can't find end of generate! call\");\n            let mut lines = conf\n                .lines()\n                .map(|line| {\n                    let line = line.trim();\n                    line.strip_suffix(',').unwrap_or(line).trim_end()\n                })\n                .collect::<Vec<_>>();\n            lines.sort_unstable();\n            write!(\n                new_text,\n                \"{pre}generate! {{\\n    {},\\n}}\\n{post}\",\n                lines.join(\",\\n    \"),\n            )\n            .unwrap();\n            if text == new_text {\n                UpdateStatus::Unchanged\n            } else {\n                UpdateStatus::Changed\n            }\n        },\n    );\n}\n\nfn run_rustfmt(update_mode: UpdateMode) {\n    let mut rustfmt_path = String::from_utf8(run_with_output(\n        \"rustup which rustfmt\",\n        Command::new(\"rustup\").args([\"which\", \"rustfmt\"]),\n    ))\n    .expect(\"invalid rustfmt path\");\n    rustfmt_path.truncate(rustfmt_path.trim_end().len());\n\n    let args: Vec<_> = walk_dir_no_dot_or_target(\".\")\n        .filter_map(|e| {\n            let e = expect_action(e, ErrAction::Read, \".\");\n            e.path()\n                .as_os_str()\n                .as_encoded_bytes()\n                .ends_with(b\".rs\")\n                .then(|| e.into_path().into_os_string())\n        })\n        .collect();\n\n    let mut children: Vec<_> = split_args_for_threads(\n        32,\n        || {\n            let mut cmd = Command::new(&rustfmt_path);\n            if update_mode.is_check() {\n                cmd.arg(\"--check\");\n            }\n            cmd.stdout(Stdio::null())\n                .stdin(Stdio::null())\n                .stderr(Stdio::piped())\n                .args([\"--unstable-features\", \"--skip-children\"]);\n            cmd\n        },\n        args.iter(),\n    )\n    .map(|mut cmd| expect_action(cmd.spawn(), ErrAction::Run, \"rustfmt\"))\n    .collect();\n\n    for child in &mut children {\n        let status = expect_action(child.wait(), ErrAction::Run, \"rustfmt\");\n        match (update_mode, status.exit_ok()) {\n            (UpdateMode::Check | UpdateMode::Change, Ok(())) => {},\n            (UpdateMode::Check, Err(_)) => {\n                let mut s = String::new();\n                if let Some(mut stderr) = child.stderr.take()\n                    && stderr.read_to_string(&mut s).is_ok()\n                {\n                    eprintln!(\"{s}\");\n                }\n                eprintln!(\"Formatting check failed!\\nRun `cargo dev fmt` to update.\");\n                process::exit(1);\n            },\n            (UpdateMode::Change, e) => {\n                let mut s = String::new();\n                if let Some(mut stderr) = child.stderr.take()\n                    && stderr.read_to_string(&mut s).is_ok()\n                {\n                    eprintln!(\"{s}\");\n                }\n                expect_action(e, ErrAction::Run, \"rustfmt\");\n            },\n        }\n    }\n}\n\n// the \"main\" function of cargo dev fmt\npub fn run(update_mode: UpdateMode) {\n    fmt_syms(update_mode);\n    if let Err(e) = fmt_conf(update_mode.is_check()) {\n        e.display();\n        process::exit(1);\n    }\n\n    new_parse_cx(|cx| {\n        let mut data = cx.parse_lint_decls();\n        let (mut lints, passes) = data.split_by_lint_file();\n        let mut updater = FileUpdater::default();\n        let mut ranges = VecBuf::with_capacity(256);\n\n        for passes in passes {\n            let path = passes[0].path.clone();\n            let mut lints = lints.remove(&*path);\n            let lints = lints.as_deref_mut().unwrap_or_default();\n            updater.update_file_checked(\"cargo dev fmt\", update_mode, &path, &mut |_, src, dst| {\n                gen_sorted_lints_file(src, dst, lints, passes, &mut ranges);\n                UpdateStatus::from_changed(src != dst)\n            });\n        }\n\n        for (&path, lints) in &mut lints {\n            updater.update_file_checked(\"cargo dev fmt\", update_mode, path, &mut |_, src, dst| {\n                gen_sorted_lints_file(src, dst, lints, &mut [], &mut ranges);\n                UpdateStatus::from_changed(src != dst)\n            });\n        }\n    });\n\n    run_rustfmt(update_mode);\n}\n"
  },
  {
    "path": "clippy_dev/src/generate.rs",
    "content": "use crate::parse::cursor::Cursor;\nuse crate::parse::{Lint, LintData, LintPass, VecBuf};\nuse crate::utils::{FileUpdater, UpdateMode, UpdateStatus, update_text_region_fn};\nuse core::range::Range;\nuse itertools::Itertools;\nuse std::collections::HashSet;\nuse std::fmt::Write;\nuse std::path::{self, Path};\n\nconst GENERATED_FILE_COMMENT: &str = \"// This file was generated by `cargo dev update_lints`.\\n\\\n     // Use that command to update this file and do not edit by hand.\\n\\\n     // Manual edits will be overwritten.\\n\\n\";\n\nconst DOCS_LINK: &str = \"https://rust-lang.github.io/rust-clippy/master/index.html\";\n\nimpl LintData<'_> {\n    #[expect(clippy::too_many_lines)]\n    pub fn gen_decls(&self, update_mode: UpdateMode) {\n        let mut updater = FileUpdater::default();\n\n        let mut lints: Vec<_> = self.lints.iter().map(|(&x, y)| (x, y)).collect();\n        lints.sort_by_key(|&(x, _)| x);\n        updater.update_file_checked(\n            \"cargo dev update_lints\",\n            update_mode,\n            \"CHANGELOG.md\",\n            &mut update_text_region_fn(\n                \"<!-- begin autogenerated links to lint list -->\\n\",\n                \"<!-- end autogenerated links to lint list -->\",\n                |dst| {\n                    for &(lint, _) in &lints {\n                        writeln!(dst, \"[`{lint}`]: {DOCS_LINK}#{lint}\").unwrap();\n                    }\n                },\n            ),\n        );\n\n        let mut active = Vec::with_capacity(lints.len());\n        let mut deprecated = Vec::with_capacity(lints.len() / 8);\n        let mut renamed = Vec::with_capacity(lints.len() / 8);\n        for &(name, lint) in &lints {\n            match lint {\n                Lint::Active(lint) => active.push((name, lint)),\n                Lint::Deprecated(lint) => deprecated.push((name, lint)),\n                Lint::Renamed(lint) => renamed.push((name, lint)),\n            }\n        }\n        active.sort_by_key(|&(_, lint)| lint.module);\n\n        // Round to avoid updating the readme every time a lint is added/deprecated.\n        let lint_count = active.len() / 50 * 50;\n        updater.update_file_checked(\n            \"cargo dev update_lints\",\n            update_mode,\n            \"README.md\",\n            &mut update_text_region_fn(\"[There are over \", \" lints included in this crate!]\", |dst| {\n                write!(dst, \"{lint_count}\").unwrap();\n            }),\n        );\n        updater.update_file_checked(\n            \"cargo dev update_lints\",\n            update_mode,\n            \"book/src/README.md\",\n            &mut update_text_region_fn(\"[There are over \", \" lints included in this crate!]\", |dst| {\n                write!(dst, \"{lint_count}\").unwrap();\n            }),\n        );\n\n        updater.update_file_checked(\n            \"cargo dev update_lints\",\n            update_mode,\n            \"clippy_lints/src/deprecated_lints.rs\",\n            &mut |_, src, dst| {\n                let mut cursor = Cursor::new(src);\n                assert!(\n                    cursor.find_ident(\"declare_with_version\").is_some()\n                        && cursor.find_ident(\"declare_with_version\").is_some(),\n                    \"error reading deprecated lints\"\n                );\n                dst.push_str(&src[..cursor.pos() as usize]);\n                dst.push_str(\"! { DEPRECATED(DEPRECATED_VERSION) = [\\n\");\n                for &(name, data) in &deprecated {\n                    write!(\n                        dst,\n                        \"    #[clippy::version = \\\"{}\\\"]\\n    (\\\"clippy::{name}\\\", \\\"{}\\\"),\\n\",\n                        data.version, data.reason,\n                    )\n                    .unwrap();\n                }\n                dst.push_str(\n                    \"]}\\n\\n\\\n                        #[rustfmt::skip]\\n\\\n                        declare_with_version! { RENAMED(RENAMED_VERSION) = [\\n\\\n                    \",\n                );\n                for &(name, data) in &renamed {\n                    write!(\n                        dst,\n                        \"    #[clippy::version = \\\"{}\\\"]\\n    (\\\"clippy::{name}\\\", \\\"{}\\\"),\\n\",\n                        data.version, data.new_name,\n                    )\n                    .unwrap();\n                }\n                dst.push_str(\"]}\\n\");\n                UpdateStatus::from_changed(src != dst)\n            },\n        );\n        updater.update_file_checked(\n            \"cargo dev update_lints\",\n            update_mode,\n            \"tests/ui/deprecated.rs\",\n            &mut |_, src, dst| {\n                dst.push_str(GENERATED_FILE_COMMENT);\n                for &(lint, _) in &deprecated {\n                    writeln!(dst, \"#![warn(clippy::{lint})] //~ ERROR: lint `clippy::{lint}`\").unwrap();\n                }\n                dst.push_str(\"\\nfn main() {}\\n\");\n                UpdateStatus::from_changed(src != dst)\n            },\n        );\n        updater.update_file_checked(\n            \"cargo dev update_lints\",\n            update_mode,\n            \"tests/ui/rename.rs\",\n            &mut move |_, src, dst| {\n                let mut seen_lints = HashSet::new();\n                dst.push_str(GENERATED_FILE_COMMENT);\n                dst.push_str(\"#![allow(clippy::duplicated_attributes)]\\n\");\n                for &(_, lint) in &renamed {\n                    if seen_lints.insert(lint.new_name) {\n                        writeln!(dst, \"#![allow({})]\", lint.new_name).unwrap();\n                    }\n                }\n                for &(lint, _) in &renamed {\n                    writeln!(dst, \"#![warn(clippy::{lint})] //~ ERROR: lint `clippy::{lint}`\").unwrap();\n                }\n                dst.push_str(\"\\nfn main() {}\\n\");\n                UpdateStatus::from_changed(src != dst)\n            },\n        );\n        for (crate_name, lints) in active.iter().copied().into_group_map_by(|&(_, lint)| {\n            let Some(path::Component::Normal(name)) = lint.path.components().next() else {\n                // All paths should start with `{crate_name}/src` when parsed from `find_lint_decls`\n                panic!(\n                    \"internal error: can't read crate name from path `{}`\",\n                    lint.path.display()\n                );\n            };\n            name\n        }) {\n            updater.update_file_checked(\n                \"cargo dev update_lints\",\n                update_mode,\n                Path::new(crate_name).join(\"src/lib.rs\"),\n                &mut update_text_region_fn(\n                    \"// begin lints modules, do not remove this comment, it's used in `update_lints`\\n\",\n                    \"// end lints modules, do not remove this comment, it's used in `update_lints`\",\n                    |dst| {\n                        let mut prev = \"\";\n                        for &(_, lint) in &lints {\n                            if lint.module != prev {\n                                writeln!(dst, \"mod {};\", lint.module).unwrap();\n                                prev = lint.module;\n                            }\n                        }\n                    },\n                ),\n            );\n            updater.update_file_checked(\n                \"cargo dev update_lints\",\n                update_mode,\n                Path::new(crate_name).join(\"src/declared_lints.rs\"),\n                &mut |_, src, dst| {\n                    dst.push_str(GENERATED_FILE_COMMENT);\n                    dst.push_str(\"pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[\\n\");\n                    let mut buf = String::new();\n                    for &(name, lint) in &lints {\n                        buf.clear();\n                        buf.push_str(name);\n                        buf.make_ascii_uppercase();\n                        if lint.module.is_empty() {\n                            writeln!(dst, \"    crate::{buf}_INFO,\").unwrap();\n                        } else {\n                            writeln!(dst, \"    crate::{}::{buf}_INFO,\", lint.module).unwrap();\n                        }\n                    }\n                    dst.push_str(\"];\\n\");\n                    UpdateStatus::from_changed(src != dst)\n                },\n            );\n        }\n    }\n}\n\nimpl LintPass<'_> {\n    pub fn gen_mac(&self, dst: &mut String) {\n        let mut line_start = dst.len();\n        dst.extend([self.mac.name(), \"!(\"]);\n        let has_docs = write_comment_lines(self.docs, \"\\n    \", dst);\n        let (list_indent, list_multi_end, end) = if has_docs {\n            dst.push_str(\"\\n    \");\n            line_start = dst.len() - 4;\n            (\"        \", \"\\n    \", \"]\\n);\")\n        } else {\n            (\"    \", \"\\n\", \"]);\")\n        };\n        dst.push_str(self.name);\n        if let Some(lt) = self.lt {\n            dst.extend([\"<\", lt, \">\"]);\n        }\n        dst.push_str(\" => [\");\n        let fmt = write_list(\n            self.lints.iter().copied(),\n            80usize.saturating_sub(dst.len() - line_start),\n            list_indent,\n            dst,\n        );\n        if matches!(fmt, ListFmt::MultiLine) {\n            dst.push_str(list_multi_end);\n        }\n        dst.push_str(end);\n    }\n}\n\nfn write_comment_lines(s: &str, prefix: &str, dst: &mut String) -> bool {\n    let mut has_doc = false;\n    for line in s.split('\\n') {\n        let line = line.trim_start();\n        if !line.is_empty() {\n            has_doc = true;\n            dst.extend([prefix, line]);\n        }\n    }\n    has_doc\n}\n\n#[derive(Clone, Copy)]\nenum ListFmt {\n    SingleLine,\n    MultiLine,\n}\n\nfn write_list<'a>(\n    items: impl Iterator<Item = &'a str> + Clone,\n    single_line_limit: usize,\n    indent: &str,\n    dst: &mut String,\n) -> ListFmt {\n    let len = items.clone().map(str::len).sum::<usize>();\n    if len > single_line_limit {\n        for item in items {\n            dst.extend([\"\\n\", indent, item, \",\"]);\n        }\n        ListFmt::MultiLine\n    } else {\n        let _ = write!(dst, \"{}\", items.format(\", \"));\n        ListFmt::SingleLine\n    }\n}\n\n/// Generates the contents of a lint's source file with all the lint and lint pass\n/// declarations sorted.\npub fn gen_sorted_lints_file(\n    src: &str,\n    dst: &mut String,\n    lints: &mut [(&str, Range<u32>)],\n    passes: &mut [LintPass<'_>],\n    ranges: &mut VecBuf<Range<u32>>,\n) {\n    ranges.with(|ranges| {\n        ranges.extend(lints.iter().map(|&(_, x)| x));\n        ranges.extend(passes.iter().map(|x| x.decl_range));\n        ranges.sort_unstable_by_key(|x| x.start);\n\n        lints.sort_unstable_by_key(|&(x, _)| x);\n        passes.sort_by_key(|x| x.name);\n\n        let mut ranges = ranges.iter();\n        let pos = if let Some(range) = ranges.next() {\n            dst.push_str(&src[..range.start as usize]);\n            for &(_, range) in &*lints {\n                dst.push_str(&src[range.start as usize..range.end as usize]);\n                dst.push_str(\"\\n\\n\");\n            }\n            for pass in passes {\n                pass.gen_mac(dst);\n                dst.push_str(\"\\n\\n\");\n            }\n            range.end\n        } else {\n            dst.push_str(src);\n            return;\n        };\n\n        let pos = ranges.fold(pos, |start, range| {\n            let s = &src[start as usize..range.start as usize];\n            dst.push_str(if s.trim_start().is_empty() {\n                // Only whitespace between this and the previous item. No need to keep that.\n                \"\"\n            } else if src[..pos as usize].ends_with(\"\\n\\n\")\n                && let Some(s) = s.strip_prefix(\"\\n\\n\")\n            {\n                // Empty line before and after. Remove one of them.\n                s\n            } else {\n                // Remove only full lines unless something is in the way.\n                s.strip_prefix('\\n').unwrap_or(s)\n            });\n            range.end\n        });\n\n        // Since we always generate an empty line at the end, make sure to always skip it.\n        let s = &src[pos as usize..];\n        dst.push_str(s.strip_prefix('\\n').map_or(s, |s| s.strip_prefix('\\n').unwrap_or(s)));\n    });\n}\n"
  },
  {
    "path": "clippy_dev/src/lib.rs",
    "content": "#![feature(\n    exit_status_error,\n    new_range,\n    new_range_api,\n    os_str_slice,\n    os_string_truncate,\n    pattern,\n    rustc_private,\n    slice_split_once\n)]\n#![warn(\n    trivial_casts,\n    trivial_numeric_casts,\n    rust_2018_idioms,\n    unused_lifetimes,\n    unused_qualifications\n)]\n#![allow(clippy::missing_panics_doc)]\n\nextern crate rustc_arena;\nextern crate rustc_data_structures;\n#[expect(unused_extern_crates, reason = \"required to link to rustc crates\")]\nextern crate rustc_driver;\nextern crate rustc_lexer;\n\npub mod dogfood;\npub mod edit_lints;\npub mod fmt;\npub mod lint;\npub mod new_lint;\npub mod release;\npub mod serve;\npub mod setup;\npub mod sync;\n\nmod generate;\nmod parse;\nmod utils;\n\npub use self::parse::{ParseCx, new_parse_cx};\npub use self::utils::{ClippyInfo, UpdateMode};\n"
  },
  {
    "path": "clippy_dev/src/lint.rs",
    "content": "use crate::utils::{ErrAction, cargo_cmd, expect_action, run_exit_on_err};\nuse std::process::Command;\nuse std::{env, fs};\n\n#[cfg(not(windows))]\nstatic CARGO_CLIPPY_EXE: &str = \"cargo-clippy\";\n#[cfg(windows)]\nstatic CARGO_CLIPPY_EXE: &str = \"cargo-clippy.exe\";\n\npub fn run<'a>(path: &str, edition: &str, args: impl Iterator<Item = &'a String>) {\n    let is_file = expect_action(fs::metadata(path), ErrAction::Read, path).is_file();\n    if is_file {\n        run_exit_on_err(\n            \"cargo run\",\n            cargo_cmd()\n                .args([\"run\", \"--bin\", \"clippy-driver\", \"--\"])\n                .args([\"-L\", \"./target/debug\"])\n                .args([\"-Z\", \"no-codegen\"])\n                .args([\"--edition\", edition])\n                .arg(path)\n                .args(args)\n                // Prevent rustc from creating `rustc-ice-*` files the console output is enough.\n                .env(\"RUSTC_ICE\", \"0\"),\n        );\n    } else {\n        // Ideally this would just be `cargo run`, but the working directory needs to be\n        // set to clippy's directory when building, and the target project's directory\n        // when running clippy. `cargo` can only set a single working directory for both\n        // when using `run`.\n        run_exit_on_err(\"cargo build\", cargo_cmd().arg(\"build\"));\n\n        let mut exe = env::current_exe().expect(\"failed to get current executable name\");\n        exe.set_file_name(CARGO_CLIPPY_EXE);\n        run_exit_on_err(\n            \"cargo clippy\",\n            Command::new(exe)\n                .arg(\"clippy\")\n                .args(args)\n                // Prevent rustc from creating `rustc-ice-*` files the console output is enough.\n                .env(\"RUSTC_ICE\", \"0\")\n                .current_dir(path),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/main.rs",
    "content": "#![feature(rustc_private)]\n// warn on lints, that are included in `rust-lang/rust`s bootstrap\n#![warn(rust_2018_idioms, unused_lifetimes)]\n\nuse clap::{Args, Parser, Subcommand};\nuse clippy_dev::{\n    ClippyInfo, UpdateMode, dogfood, edit_lints, fmt, lint, new_lint, new_parse_cx, release, serve, setup, sync,\n};\nuse std::env;\n\nfn main() {\n    let dev = Dev::parse();\n    let clippy = ClippyInfo::search_for_manifest();\n    if let Err(e) = env::set_current_dir(&clippy.path) {\n        panic!(\"error setting current directory to `{}`: {e}\", clippy.path.display());\n    }\n\n    match dev.command {\n        DevCommand::Bless => {\n            eprintln!(\"use `cargo bless` to automatically replace `.stderr` and `.fixed` files as tests are being run\");\n        },\n        DevCommand::Dogfood {\n            fix,\n            allow_dirty,\n            allow_staged,\n            allow_no_vcs,\n        } => dogfood::dogfood(fix, allow_dirty, allow_staged, allow_no_vcs),\n        DevCommand::Fmt { check } => fmt::run(UpdateMode::from_check(check)),\n        DevCommand::UpdateLints { check } => {\n            new_parse_cx(|cx| cx.parse_lint_decls().gen_decls(UpdateMode::from_check(check)));\n        },\n        DevCommand::NewLint {\n            pass,\n            name,\n            category,\n            r#type,\n            msrv,\n        } => match new_lint::create(clippy.version, pass, &name, &category, r#type.as_deref(), msrv) {\n            Ok(()) => new_parse_cx(|cx| cx.parse_lint_decls().gen_decls(UpdateMode::Change)),\n            Err(e) => eprintln!(\"Unable to create lint: {e}\"),\n        },\n        DevCommand::Setup(SetupCommand { subcommand }) => match subcommand {\n            SetupSubcommand::Intellij { remove, repo_path } => {\n                if remove {\n                    setup::intellij::remove_rustc_src();\n                } else {\n                    setup::intellij::setup_rustc_src(&repo_path);\n                }\n            },\n            SetupSubcommand::GitHook { remove, force_override } => {\n                if remove {\n                    setup::git_hook::remove_hook();\n                } else {\n                    setup::git_hook::install_hook(force_override);\n                }\n            },\n            SetupSubcommand::Toolchain {\n                standalone,\n                force,\n                release,\n                name,\n            } => setup::toolchain::create(standalone, force, release, &name),\n            SetupSubcommand::VscodeTasks { remove, force_override } => {\n                if remove {\n                    setup::vscode::remove_tasks();\n                } else {\n                    setup::vscode::install_tasks(force_override);\n                }\n            },\n        },\n        DevCommand::Remove(RemoveCommand { subcommand }) => match subcommand {\n            RemoveSubcommand::Intellij => setup::intellij::remove_rustc_src(),\n            RemoveSubcommand::GitHook => setup::git_hook::remove_hook(),\n            RemoveSubcommand::VscodeTasks => setup::vscode::remove_tasks(),\n        },\n        DevCommand::Serve { port, lint } => serve::run(port, lint),\n        DevCommand::Lint { path, edition, args } => lint::run(&path, &edition, args.iter()),\n        DevCommand::RenameLint { old_name, new_name } => new_parse_cx(|cx| {\n            edit_lints::rename(cx, clippy.version, &old_name, &new_name);\n        }),\n        DevCommand::Uplift { old_name, new_name } => new_parse_cx(|cx| {\n            edit_lints::uplift(cx, clippy.version, &old_name, new_name.as_deref().unwrap_or(&old_name));\n        }),\n        DevCommand::Deprecate { name, reason } => {\n            new_parse_cx(|cx| edit_lints::deprecate(cx, clippy.version, &name, &reason));\n        },\n        DevCommand::Sync(SyncCommand { subcommand }) => match subcommand {\n            SyncSubcommand::UpdateNightly => sync::update_nightly(),\n        },\n        DevCommand::Release(ReleaseCommand { subcommand }) => match subcommand {\n            ReleaseSubcommand::BumpVersion => release::bump_version(clippy.version),\n        },\n    }\n}\n\nfn lint_name(name: &str) -> Result<String, String> {\n    let name = name.replace('-', \"_\");\n    if let Some((pre, _)) = name.split_once(\"::\") {\n        Err(format!(\"lint name should not contain the `{pre}` prefix\"))\n    } else if name\n        .bytes()\n        .any(|x| !matches!(x, b'_' | b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z'))\n    {\n        Err(\"lint name contains invalid characters\".to_owned())\n    } else {\n        Ok(name)\n    }\n}\n\n#[derive(Parser)]\n#[command(name = \"dev\", about)]\nstruct Dev {\n    #[command(subcommand)]\n    command: DevCommand,\n}\n\n#[derive(Subcommand)]\nenum DevCommand {\n    /// Bless the test output changes\n    Bless,\n    /// Runs the dogfood test\n    Dogfood {\n        #[arg(long)]\n        /// Apply the suggestions when possible\n        fix: bool,\n        #[arg(long, requires = \"fix\")]\n        /// Fix code even if the working directory has changes\n        allow_dirty: bool,\n        #[arg(long, requires = \"fix\")]\n        /// Fix code even if the working directory has staged changes\n        allow_staged: bool,\n        #[arg(long, requires = \"fix\")]\n        /// Fix code even if a VCS was not detected\n        allow_no_vcs: bool,\n    },\n    /// Run rustfmt on all projects and tests\n    Fmt {\n        #[arg(long)]\n        /// Use the rustfmt --check option\n        check: bool,\n    },\n    #[command(name = \"update_lints\")]\n    /// Updates lint registration and information from the source code\n    ///\n    /// Makes sure that: {n}\n    /// * the lint count in README.md is correct {n}\n    /// * the changelog contains markdown link references at the bottom {n}\n    /// * all lint groups include the correct lints {n}\n    /// * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod` {n}\n    /// * all lints are registered in the lint store\n    UpdateLints {\n        #[arg(long)]\n        /// Checks that `cargo dev update_lints` has been run. Used on CI.\n        check: bool,\n    },\n    #[command(name = \"new_lint\")]\n    /// Create a new lint and run `cargo dev update_lints`\n    NewLint {\n        #[arg(short, long, conflicts_with = \"type\", default_value = \"late\")]\n        /// Specify whether the lint runs during the early or late pass\n        pass: new_lint::Pass,\n        #[arg(\n            short,\n            long,\n            value_parser = lint_name,\n        )]\n        /// Name of the new lint in snake case, ex: `fn_too_long`\n        name: String,\n        #[arg(\n            short,\n            long,\n            value_parser = [\n                \"style\",\n                \"correctness\",\n                \"suspicious\",\n                \"complexity\",\n                \"perf\",\n                \"pedantic\",\n                \"restriction\",\n                \"cargo\",\n                \"nursery\",\n            ],\n            default_value = \"nursery\",\n        )]\n        /// What category the lint belongs to\n        category: String,\n        #[arg(long)]\n        /// What directory the lint belongs in\n        r#type: Option<String>,\n        #[arg(long)]\n        /// Add MSRV config code to the lint\n        msrv: bool,\n    },\n    /// Support for setting up your personal development environment\n    Setup(SetupCommand),\n    /// Support for removing changes done by the setup command\n    Remove(RemoveCommand),\n    /// Launch a local 'ALL the Clippy Lints' website in a browser\n    Serve {\n        #[arg(short, long, default_value = \"8000\")]\n        /// Local port for the http server\n        port: u16,\n        #[arg(long)]\n        /// Which lint's page to load initially (optional)\n        lint: Option<String>,\n    },\n    #[expect(clippy::doc_markdown)]\n    /// Manually run clippy on a file or package\n    ///\n    /// ## Examples\n    ///\n    /// Lint a single file: {n}\n    ///     cargo dev lint tests/ui/attrs.rs\n    ///\n    /// Lint a package directory: {n}\n    ///     cargo dev lint tests/ui-cargo/wildcard_dependencies/fail {n}\n    ///     cargo dev lint ~/my-project\n    ///\n    /// Run rustfix: {n}\n    ///     cargo dev lint ~/my-project -- --fix\n    ///\n    /// Set lint levels: {n}\n    ///     cargo dev lint file.rs -- -W clippy::pedantic {n}\n    ///     cargo dev lint ~/my-project -- -- -W clippy::pedantic\n    Lint {\n        /// The Rust edition to use\n        #[arg(long, default_value = \"2024\")]\n        edition: String,\n        /// The path to a file or package directory to lint\n        path: String,\n        /// Pass extra arguments to cargo/clippy-driver\n        args: Vec<String>,\n    },\n    #[command(name = \"rename_lint\")]\n    /// Rename a lint\n    RenameLint {\n        /// The name of the lint to rename\n        #[arg(value_parser = lint_name)]\n        old_name: String,\n        #[arg(value_parser = lint_name)]\n        /// The new name of the lint\n        new_name: String,\n    },\n    /// Deprecate the given lint\n    Deprecate {\n        /// The name of the lint to deprecate\n        #[arg(value_parser = lint_name)]\n        name: String,\n        #[arg(long, short)]\n        /// The reason for deprecation\n        reason: String,\n    },\n    /// Sync between the rust repo and the Clippy repo\n    Sync(SyncCommand),\n    /// Manage Clippy releases\n    Release(ReleaseCommand),\n    /// Marks a lint as uplifted into rustc and removes its code\n    Uplift {\n        /// The name of the lint to uplift\n        #[arg(value_parser = lint_name)]\n        old_name: String,\n        /// The name of the lint in rustc\n        #[arg(value_parser = lint_name)]\n        new_name: Option<String>,\n    },\n}\n\n#[derive(Args)]\nstruct SetupCommand {\n    #[command(subcommand)]\n    subcommand: SetupSubcommand,\n}\n\n#[derive(Subcommand)]\nenum SetupSubcommand {\n    /// Alter dependencies so Intellij Rust can find rustc internals\n    Intellij {\n        #[arg(long)]\n        /// Remove the dependencies added with 'cargo dev setup intellij'\n        remove: bool,\n        #[arg(long, short, conflicts_with = \"remove\")]\n        /// The path to a rustc repo that will be used for setting the dependencies\n        repo_path: String,\n    },\n    /// Add a pre-commit git hook that formats your code to make it look pretty\n    GitHook {\n        #[arg(long)]\n        /// Remove the pre-commit hook added with 'cargo dev setup git-hook'\n        remove: bool,\n        #[arg(long, short)]\n        /// Forces the override of an existing git pre-commit hook\n        force_override: bool,\n    },\n    /// Install a rustup toolchain pointing to the local clippy build\n    ///\n    /// This creates a toolchain with symlinks pointing at\n    /// `target/.../{clippy-driver,cargo-clippy}`, rebuilds of the project will be reflected in the\n    /// created toolchain unless `--standalone` is passed\n    Toolchain {\n        #[arg(long, short)]\n        /// Create a standalone toolchain by copying the clippy binaries instead\n        /// of symlinking them\n        ///\n        /// Use this for example to create a toolchain, make a small change and then make another\n        /// toolchain with a different name in order to easily compare the two\n        standalone: bool,\n        #[arg(long, short)]\n        /// Override an existing toolchain\n        force: bool,\n        #[arg(long, short)]\n        /// Point to --release clippy binary\n        release: bool,\n        #[arg(long, short, default_value = \"clippy\")]\n        /// Name of the toolchain\n        name: String,\n    },\n    /// Add several tasks to vscode for formatting, validation and testing\n    VscodeTasks {\n        #[arg(long)]\n        /// Remove the tasks added with 'cargo dev setup vscode-tasks'\n        remove: bool,\n        #[arg(long, short)]\n        /// Forces the override of existing vscode tasks\n        force_override: bool,\n    },\n}\n\n#[derive(Args)]\nstruct RemoveCommand {\n    #[command(subcommand)]\n    subcommand: RemoveSubcommand,\n}\n\n#[derive(Subcommand)]\nenum RemoveSubcommand {\n    /// Remove the dependencies added with 'cargo dev setup intellij'\n    Intellij,\n    /// Remove the pre-commit git hook\n    GitHook,\n    /// Remove the tasks added with 'cargo dev setup vscode-tasks'\n    VscodeTasks,\n}\n\n#[derive(Args)]\nstruct SyncCommand {\n    #[command(subcommand)]\n    subcommand: SyncSubcommand,\n}\n\n#[derive(Subcommand)]\nenum SyncSubcommand {\n    #[command(name = \"update_nightly\")]\n    /// Update nightly version in `rust-toolchain.toml` and `clippy_utils`\n    UpdateNightly,\n}\n\n#[derive(Args)]\nstruct ReleaseCommand {\n    #[command(subcommand)]\n    subcommand: ReleaseSubcommand,\n}\n\n#[derive(Subcommand)]\nenum ReleaseSubcommand {\n    #[command(name = \"bump_version\")]\n    /// Bump the version in the Cargo.toml files\n    BumpVersion,\n}\n"
  },
  {
    "path": "clippy_dev/src/new_lint.rs",
    "content": "use crate::parse::cursor::{self, Capture, Cursor};\nuse crate::utils::Version;\nuse clap::ValueEnum;\nuse indoc::{formatdoc, writedoc};\nuse std::fmt::{self, Write as _};\nuse std::fs::{self, OpenOptions};\nuse std::io::{self, Write as _};\nuse std::path::{Path, PathBuf};\n\n#[derive(Clone, Copy, PartialEq, ValueEnum)]\npub enum Pass {\n    Early,\n    Late,\n}\n\nimpl fmt::Display for Pass {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(match self {\n            Pass::Early => \"early\",\n            Pass::Late => \"late\",\n        })\n    }\n}\n\nstruct LintData<'a> {\n    clippy_version: Version,\n    pass: Pass,\n    name: &'a str,\n    category: &'a str,\n    ty: Option<&'a str>,\n}\n\ntrait Context {\n    fn context<C: AsRef<str>>(self, text: C) -> Self;\n}\n\nimpl<T> Context for io::Result<T> {\n    fn context<C: AsRef<str>>(self, text: C) -> Self {\n        match self {\n            Ok(t) => Ok(t),\n            Err(e) => {\n                let message = format!(\"{}: {e}\", text.as_ref());\n                Err(io::Error::other(message))\n            },\n        }\n    }\n}\n\n/// Creates the files required to implement and test a new lint and runs `update_lints`.\n///\n/// # Errors\n///\n/// This function errors out if the files couldn't be created or written to.\npub fn create(\n    clippy_version: Version,\n    pass: Pass,\n    name: &str,\n    category: &str,\n    mut ty: Option<&str>,\n    msrv: bool,\n) -> io::Result<()> {\n    if category == \"cargo\" && ty.is_none() {\n        // `cargo` is a special category, these lints should always be in `clippy_lints/src/cargo`\n        ty = Some(\"cargo\");\n    }\n\n    let lint = LintData {\n        clippy_version,\n        pass,\n        name,\n        category,\n        ty,\n    };\n\n    create_lint(&lint, msrv).context(\"Unable to create lint implementation\")?;\n    create_test(&lint, msrv).context(\"Unable to create a test for the new lint\")?;\n\n    if lint.ty.is_none() {\n        add_lint(&lint, msrv).context(\"Unable to add lint to clippy_lints/src/lib.rs\")?;\n    }\n\n    if pass == Pass::Early {\n        println!(\n            \"\\n\\\n            NOTE: Use a late pass unless you need something specific from\\n\\\n            an early pass, as they lack many features and utilities\"\n        );\n    }\n\n    Ok(())\n}\n\nfn create_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {\n    if let Some(ty) = lint.ty {\n        create_lint_for_ty(lint, enable_msrv, ty)\n    } else {\n        let lint_contents = get_lint_file_contents(lint, enable_msrv);\n        let lint_path = format!(\"clippy_lints/src/{}.rs\", lint.name);\n        write_file(&lint_path, lint_contents.as_bytes())?;\n        println!(\"Generated lint file: `{lint_path}`\");\n\n        Ok(())\n    }\n}\n\nfn create_test(lint: &LintData<'_>, msrv: bool) -> io::Result<()> {\n    fn create_project_layout<P: Into<PathBuf>>(\n        lint_name: &str,\n        location: P,\n        case: &str,\n        hint: &str,\n        msrv: bool,\n    ) -> io::Result<()> {\n        let mut path = location.into().join(case);\n        fs::create_dir(&path)?;\n        write_file(path.join(\"Cargo.toml\"), get_manifest_contents(lint_name, hint))?;\n\n        path.push(\"src\");\n        fs::create_dir(&path)?;\n        write_file(path.join(\"main.rs\"), get_test_file_contents(lint_name, msrv))?;\n\n        Ok(())\n    }\n\n    if lint.category == \"cargo\" {\n        let test_dir = format!(\"tests/ui-cargo/{}\", lint.name);\n        fs::create_dir(&test_dir)?;\n\n        create_project_layout(\n            lint.name,\n            &test_dir,\n            \"fail\",\n            \"Content that triggers the lint goes here\",\n            msrv,\n        )?;\n        create_project_layout(\n            lint.name,\n            &test_dir,\n            \"pass\",\n            \"This file should not trigger the lint\",\n            false,\n        )?;\n\n        println!(\"Generated test directories: `{test_dir}/pass`, `{test_dir}/fail`\");\n    } else {\n        let test_path = format!(\"tests/ui/{}.rs\", lint.name);\n        let test_contents = get_test_file_contents(lint.name, msrv);\n        write_file(&test_path, test_contents)?;\n\n        println!(\"Generated test file: `{test_path}`\");\n    }\n\n    Ok(())\n}\n\nfn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {\n    let path = \"clippy_lints/src/lib.rs\";\n    let mut lib_rs = fs::read_to_string(path).context(\"reading\")?;\n\n    let (comment, ctor_arg) = if lint.pass == Pass::Late {\n        (\"// add late passes here\", \"_\")\n    } else {\n        (\"// add early passes here\", \"\")\n    };\n    let comment_start = lib_rs.find(comment).expect(\"Couldn't find comment\");\n    let module_name = lint.name;\n    let camel_name = to_camel_case(lint.name);\n\n    let new_lint = if enable_msrv {\n        format!(\"Box::new(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(conf))),\\n        \")\n    } else {\n        format!(\"Box::new(|{ctor_arg}| Box::new({module_name}::{camel_name})),\\n        \")\n    };\n\n    lib_rs.insert_str(comment_start, &new_lint);\n\n    fs::write(path, lib_rs).context(\"writing\")\n}\n\nfn write_file<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {\n    fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {\n        OpenOptions::new()\n            .write(true)\n            .create_new(true)\n            .open(path)?\n            .write_all(contents)\n    }\n\n    inner(path.as_ref(), contents.as_ref()).context(format!(\"writing to file: {}\", path.as_ref().display()))\n}\n\nfn to_camel_case(name: &str) -> String {\n    name.split('_')\n        .map(|s| {\n            if s.is_empty() {\n                String::new()\n            } else {\n                [&s[0..1].to_uppercase(), &s[1..]].concat()\n            }\n        })\n        .collect()\n}\n\nfn get_test_file_contents(lint_name: &str, msrv: bool) -> String {\n    let mut test = formatdoc!(\n        r\"\n        #![warn(clippy::{lint_name})]\n\n        fn main() {{\n            // test code goes here\n        }}\n    \"\n    );\n\n    if msrv {\n        let _ = writedoc!(\n            test,\n            r#\"\n\n                // TODO: set xx to the version one below the MSRV used by the lint, and yy to\n                // the version used by the lint\n                #[clippy::msrv = \"1.xx\"]\n                fn msrv_1_xx() {{\n                    // a simple example that would trigger the lint if the MSRV were met\n                }}\n\n                #[clippy::msrv = \"1.yy\"]\n                fn msrv_1_yy() {{\n                    // the same example as above\n                }}\n            \"#\n        );\n    }\n\n    test\n}\n\nfn get_manifest_contents(lint_name: &str, hint: &str) -> String {\n    formatdoc!(\n        r#\"\n        # {hint}\n\n        [package]\n        name = \"{lint_name}\"\n        version = \"0.1.0\"\n        publish = false\n\n        [workspace]\n    \"#\n    )\n}\n\nfn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {\n    let mut result = String::new();\n\n    let (pass_type, pass_lifetimes, pass_import, context_import) = match lint.pass {\n        Pass::Early => (\"EarlyLintPass\", \"\", \"use rustc_ast::ast::*;\", \"EarlyContext\"),\n        Pass::Late => (\"LateLintPass\", \"<'_>\", \"use rustc_hir::*;\", \"LateContext\"),\n    };\n    let (msrv_ty, msrv_ctor, extract_msrv) = match lint.pass {\n        Pass::Early => (\n            \"MsrvStack\",\n            \"MsrvStack::new(conf.msrv)\",\n            \"\\n    extract_msrv_attr!();\\n\",\n        ),\n        Pass::Late => (\"Msrv\", \"conf.msrv\", \"\"),\n    };\n\n    let lint_name = lint.name;\n    let category = lint.category;\n    let name_camel = to_camel_case(lint.name);\n    let name_upper = lint_name.to_uppercase();\n\n    if enable_msrv {\n        let _: fmt::Result = writedoc!(\n            result,\n            r\"\n            use clippy_utils::msrvs::{{self, {msrv_ty}}};\n            use clippy_config::Conf;\n            {pass_import}\n            use rustc_lint::{{{context_import}, {pass_type}}};\n            use rustc_session::impl_lint_pass;\n\n        \"\n        );\n    } else {\n        let _: fmt::Result = writedoc!(\n            result,\n            r\"\n            {pass_import}\n            use rustc_lint::{{{context_import}, {pass_type}}};\n            use rustc_session::declare_lint_pass;\n\n        \"\n        );\n    }\n\n    let _: fmt::Result = writeln!(\n        result,\n        \"{}\",\n        get_lint_declaration(lint.clippy_version, &name_upper, category)\n    );\n\n    if enable_msrv {\n        let _: fmt::Result = writedoc!(\n            result,\n            r\"\n            pub struct {name_camel} {{\n                msrv: {msrv_ty},\n            }}\n\n            impl {name_camel} {{\n                pub fn new(conf: &'static Conf) -> Self {{\n                    Self {{ msrv: {msrv_ctor} }}\n                }}\n            }}\n\n            impl_lint_pass!({name_camel} => [{name_upper}]);\n\n            impl {pass_type}{pass_lifetimes} for {name_camel} {{{extract_msrv}}}\n\n            // TODO: Add MSRV level to `clippy_config/src/msrvs.rs` if needed.\n            // TODO: Update msrv config comment in `clippy_config/src/conf.rs`\n        \"\n        );\n    } else {\n        let _: fmt::Result = writedoc!(\n            result,\n            r\"\n            declare_lint_pass!({name_camel} => [{name_upper}]);\n\n            impl {pass_type}{pass_lifetimes} for {name_camel} {{}}\n        \"\n        );\n    }\n\n    result\n}\n\nfn get_lint_declaration(version: Version, name_upper: &str, category: &str) -> String {\n    let justification_heading = if category == \"restriction\" {\n        \"Why restrict this?\"\n    } else {\n        \"Why is this bad?\"\n    };\n    formatdoc!(\n        r#\"\n            declare_clippy_lint! {{\n                /// ### What it does\n                ///\n                /// ### {justification_heading}\n                ///\n                /// ### Example\n                /// ```no_run\n                /// // example code where clippy issues a warning\n                /// ```\n                /// Use instead:\n                /// ```no_run\n                /// // example code which does not raise clippy warning\n                /// ```\n                #[clippy::version = \"{}\"]\n                pub {name_upper},\n                {category},\n                \"default lint description\"\n            }}\"#,\n        version.rust_display(),\n    )\n}\n\nfn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::Result<()> {\n    match ty {\n        \"cargo\" => assert_eq!(\n            lint.category, \"cargo\",\n            \"Lints of type `cargo` must have the `cargo` category\"\n        ),\n        _ if lint.category == \"cargo\" => panic!(\"Lints of category `cargo` must have the `cargo` type\"),\n        _ => {},\n    }\n\n    let ty_dir = PathBuf::from(format!(\"clippy_lints/src/{ty}\"));\n    assert!(\n        ty_dir.exists() && ty_dir.is_dir(),\n        \"Directory `{}` does not exist!\",\n        ty_dir.display()\n    );\n\n    let lint_file_path = ty_dir.join(format!(\"{}.rs\", lint.name));\n    assert!(\n        !lint_file_path.exists(),\n        \"File `{}` already exists\",\n        lint_file_path.display()\n    );\n\n    let mod_file_path = ty_dir.join(\"mod.rs\");\n    let context_import = setup_mod_file(&mod_file_path, lint)?;\n    let (pass_lifetimes, msrv_ty, msrv_ref, msrv_cx) = match context_import {\n        \"LateContext\" => (\"<'_>\", \"Msrv\", \"\", \"cx, \"),\n        _ => (\"\", \"MsrvStack\", \"&\", \"\"),\n    };\n\n    let name_upper = lint.name.to_uppercase();\n    let mut lint_file_contents = String::new();\n\n    if enable_msrv {\n        let _: fmt::Result = writedoc!(\n            lint_file_contents,\n            r#\"\n                use clippy_utils::msrvs::{{self, {msrv_ty}}};\n                use rustc_lint::{{{context_import}, LintContext}};\n\n                use super::{name_upper};\n\n                // TODO: Adjust the parameters as necessary\n                pub(super) fn check(cx: &{context_import}{pass_lifetimes}, msrv: {msrv_ref}{msrv_ty}) {{\n                    if !msrv.meets({msrv_cx}todo!(\"Add a new entry in `clippy_utils/src/msrvs`\")) {{\n                        return;\n                    }}\n                    todo!();\n                }}\n           \"#\n        );\n    } else {\n        let _: fmt::Result = writedoc!(\n            lint_file_contents,\n            r\"\n                use rustc_lint::{{{context_import}, LintContext}};\n\n                use super::{name_upper};\n\n                // TODO: Adjust the parameters as necessary\n                pub(super) fn check(cx: &{context_import}{pass_lifetimes}) {{\n                    todo!();\n                }}\n           \"\n        );\n    }\n\n    write_file(lint_file_path.as_path(), lint_file_contents)?;\n    println!(\"Generated lint file: `clippy_lints/src/{ty}/{}.rs`\", lint.name);\n    println!(\n        \"Be sure to add a call to `{}::check` in `clippy_lints/src/{ty}/mod.rs`!\",\n        lint.name\n    );\n\n    Ok(())\n}\n\nfn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str> {\n    let lint_name_upper = lint.name.to_uppercase();\n\n    let mut file_contents = fs::read_to_string(path)?;\n    assert!(\n        !file_contents.contains(&format!(\"pub {lint_name_upper},\")),\n        \"Lint `{}` already defined in `{}`\",\n        lint.name,\n        path.display()\n    );\n\n    let (lint_context, lint_decl_end) = parse_mod_file(path, &file_contents);\n\n    // Add the lint declaration to `mod.rs`\n    file_contents.insert_str(\n        lint_decl_end,\n        &format!(\n            \"\\n\\n{}\",\n            get_lint_declaration(lint.clippy_version, &lint_name_upper, lint.category)\n        ),\n    );\n\n    // Add the lint to `impl_lint_pass`/`declare_lint_pass`\n    let impl_lint_pass_start = file_contents.find(\"impl_lint_pass!\").unwrap_or_else(|| {\n        file_contents\n            .find(\"declare_lint_pass!\")\n            .unwrap_or_else(|| panic!(\"failed to find `impl_lint_pass`/`declare_lint_pass`\"))\n    });\n\n    let mut arr_start = file_contents[impl_lint_pass_start..].find('[').unwrap_or_else(|| {\n        panic!(\"malformed `impl_lint_pass`/`declare_lint_pass`\");\n    });\n\n    arr_start += impl_lint_pass_start;\n\n    let mut arr_end = file_contents[arr_start..]\n        .find(']')\n        .expect(\"failed to find `impl_lint_pass` terminator\");\n\n    arr_end += arr_start;\n\n    let mut arr_content = file_contents[arr_start + 1..arr_end].to_string();\n    arr_content.retain(|c| !c.is_whitespace());\n\n    let mut new_arr_content = String::new();\n    for ident in arr_content\n        .split(',')\n        .chain(std::iter::once(&*lint_name_upper))\n        .filter(|s| !s.is_empty())\n    {\n        let _: fmt::Result = write!(new_arr_content, \"\\n    {ident},\");\n    }\n    new_arr_content.push('\\n');\n\n    file_contents.replace_range(arr_start + 1..arr_end, &new_arr_content);\n\n    // Just add the mod declaration at the top, it'll be fixed by rustfmt\n    file_contents.insert_str(0, &format!(\"mod {};\\n\", &lint.name));\n\n    let mut file = OpenOptions::new()\n        .write(true)\n        .truncate(true)\n        .open(path)\n        .context(format!(\"trying to open: `{}`\", path.display()))?;\n    file.write_all(file_contents.as_bytes())\n        .context(format!(\"writing to file: `{}`\", path.display()))?;\n\n    Ok(lint_context)\n}\n\n// Find both the last lint declaration (declare_clippy_lint!) and the lint pass impl\nfn parse_mod_file(path: &Path, contents: &str) -> (&'static str, usize) {\n    #[allow(clippy::enum_glob_use)]\n    use cursor::Pat::*;\n\n    let mut context = None;\n    let mut decl_end = None;\n    let mut cursor = Cursor::new(contents);\n    let mut captures = [Capture::EMPTY];\n    while let Some(name) = cursor.find_any_ident() {\n        match cursor.get_text(name) {\n            \"declare_clippy_lint\" if cursor.match_all(&[Bang, OpenBrace], &mut []) && cursor.find_pat(CloseBrace) => {\n                decl_end = Some(cursor.pos());\n            },\n            \"impl\" if cursor.match_all(&[Lt, Lifetime, Gt, CaptureIdent], &mut captures) => {\n                match cursor.get_text(captures[0]) {\n                    \"LateLintPass\" => context = Some(\"LateContext\"),\n                    \"EarlyLintPass\" => context = Some(\"EarlyContext\"),\n                    _ => {},\n                }\n            },\n            _ => {},\n        }\n    }\n\n    (\n        context.unwrap_or_else(|| panic!(\"No lint pass implementation found in `{}`\", path.display())),\n        decl_end.unwrap_or_else(|| panic!(\"No lint declarations found in `{}`\", path.display())) as usize,\n    )\n}\n\n#[test]\nfn test_camel_case() {\n    let s = \"a_lint\";\n    let s2 = to_camel_case(s);\n    assert_eq!(s2, \"ALint\");\n\n    let name = \"a_really_long_new_lint\";\n    let name2 = to_camel_case(name);\n    assert_eq!(name2, \"AReallyLongNewLint\");\n\n    let name3 = \"lint__name\";\n    let name4 = to_camel_case(name3);\n    assert_eq!(name4, \"LintName\");\n}\n"
  },
  {
    "path": "clippy_dev/src/parse/cursor.rs",
    "content": "use core::slice;\nuse rustc_lexer::{self as lex, LiteralKind, Token, TokenKind};\n\n/// A token pattern used for searching and matching by the [`Cursor`].\n///\n/// In the event that a pattern is a multi-token sequence, earlier tokens will be consumed\n/// even if the pattern ultimately isn't matched. e.g. With the sequence `:*` matching\n/// `DoubleColon` will consume the first `:` and then fail to match, leaving the cursor at\n/// the `*`.\n#[derive(Clone, Copy)]\npub enum Pat<'a> {\n    /// Matches any number of comments and doc comments.\n    AnyComment,\n    Ident(&'a str),\n    CaptureDocLines,\n    CaptureIdent,\n    LitStr,\n    CaptureLitStr,\n    Bang,\n    CloseBrace,\n    CloseBracket,\n    CloseParen,\n    Comma,\n    DoubleColon,\n    Eq,\n    FatArrow,\n    Lifetime,\n    Lt,\n    Gt,\n    OpenBrace,\n    OpenBracket,\n    OpenParen,\n    CaptureOptLifetimeArg,\n    Pound,\n    Semi,\n}\n\n#[derive(Clone, Copy)]\npub struct Capture {\n    pub pos: u32,\n    pub len: u32,\n}\nimpl Capture {\n    pub const EMPTY: Self = Self { pos: 0, len: 0 };\n}\n\n/// A unidirectional cursor over a token stream that is lexed on demand.\npub struct Cursor<'txt> {\n    next_token: Token,\n    pos: u32,\n    inner: lex::Cursor<'txt>,\n    text: &'txt str,\n}\nimpl<'txt> Cursor<'txt> {\n    #[must_use]\n    pub fn new(text: &'txt str) -> Self {\n        let mut inner = lex::Cursor::new(text, lex::FrontmatterAllowed::Yes);\n        Self {\n            next_token: inner.advance_token(),\n            pos: 0,\n            inner,\n            text,\n        }\n    }\n\n    /// Gets the text of the captured token assuming it came from this cursor.\n    #[must_use]\n    pub fn get_text(&self, capture: Capture) -> &'txt str {\n        &self.text[capture.pos as usize..(capture.pos + capture.len) as usize]\n    }\n\n    /// Gets the text that makes up the next token in the stream, or the empty string if\n    /// stream is exhausted.\n    #[must_use]\n    pub fn peek_text(&self) -> &'txt str {\n        &self.text[self.pos as usize..(self.pos + self.next_token.len) as usize]\n    }\n\n    /// Gets the length of the next token in bytes, or zero if the stream is exhausted.\n    #[must_use]\n    pub fn peek_len(&self) -> u32 {\n        self.next_token.len\n    }\n\n    /// Gets the next token in the stream, or [`TokenKind::Eof`] if the stream is\n    /// exhausted.\n    #[must_use]\n    pub fn peek(&self) -> TokenKind {\n        self.next_token.kind\n    }\n\n    /// Gets the offset of the next token in the source string, or the string's length if\n    /// the stream is exhausted.\n    #[must_use]\n    pub fn pos(&self) -> u32 {\n        self.pos\n    }\n\n    /// Gets whether the cursor has exhausted its input.\n    #[must_use]\n    pub fn at_end(&self) -> bool {\n        self.next_token.kind == TokenKind::Eof\n    }\n\n    /// Advances the cursor to the next token. If the stream is exhausted this will set\n    /// the next token to [`TokenKind::Eof`].\n    pub fn step(&mut self) {\n        // `next_token.len` is zero for the eof marker.\n        self.pos += self.next_token.len;\n        self.next_token = self.inner.advance_token();\n    }\n\n    /// Consumes tokens until the given pattern is either fully matched of fails to match.\n    /// Returns whether the pattern was fully matched.\n    ///\n    /// For each capture made by the pattern one item will be taken from the capture\n    /// sequence with the result placed inside.\n    #[expect(clippy::too_many_lines)]\n    fn match_impl(&mut self, pat: Pat<'_>, captures: &mut slice::IterMut<'_, Capture>) -> bool {\n        loop {\n            match (pat, self.next_token.kind) {\n                #[rustfmt::skip] // rustfmt bug: https://github.com/rust-lang/rustfmt/issues/6697\n                (_, TokenKind::Whitespace)\n                | (\n                    Pat::AnyComment,\n                    TokenKind::BlockComment { terminated: true, .. } | TokenKind::LineComment { .. },\n                ) => self.step(),\n                (Pat::Bang, TokenKind::Bang)\n                | (Pat::CloseBrace, TokenKind::CloseBrace)\n                | (Pat::CloseBracket, TokenKind::CloseBracket)\n                | (Pat::CloseParen, TokenKind::CloseParen)\n                | (Pat::Comma, TokenKind::Comma)\n                | (Pat::Eq, TokenKind::Eq)\n                | (Pat::Lifetime, TokenKind::Lifetime { .. })\n                | (Pat::Lt, TokenKind::Lt)\n                | (Pat::Gt, TokenKind::Gt)\n                | (Pat::OpenBrace, TokenKind::OpenBrace)\n                | (Pat::OpenBracket, TokenKind::OpenBracket)\n                | (Pat::OpenParen, TokenKind::OpenParen)\n                | (Pat::Pound, TokenKind::Pound)\n                | (Pat::Semi, TokenKind::Semi)\n                | (\n                    Pat::LitStr,\n                    TokenKind::Literal {\n                        kind: LiteralKind::Str { terminated: true } | LiteralKind::RawStr { .. },\n                        ..\n                    },\n                ) => {\n                    self.step();\n                    return true;\n                },\n                (Pat::Ident(x), TokenKind::Ident) if x == self.peek_text() => {\n                    self.step();\n                    return true;\n                },\n                (Pat::DoubleColon, TokenKind::Colon) => {\n                    self.step();\n                    if matches!(self.next_token.kind, TokenKind::Colon) {\n                        self.step();\n                        return true;\n                    }\n                    return false;\n                },\n                (Pat::FatArrow, TokenKind::Eq) => {\n                    self.step();\n                    if matches!(self.next_token.kind, TokenKind::Gt) {\n                        self.step();\n                        return true;\n                    }\n                    return false;\n                },\n                (Pat::CaptureOptLifetimeArg, TokenKind::Lt) => {\n                    self.step();\n                    loop {\n                        match self.next_token.kind {\n                            TokenKind::Lifetime { .. } => break,\n                            TokenKind::Whitespace => self.step(),\n                            _ => return false,\n                        }\n                    }\n                    *captures.next().unwrap() = Capture {\n                        pos: self.pos,\n                        len: self.next_token.len,\n                    };\n                    self.step();\n                    loop {\n                        match self.next_token.kind {\n                            TokenKind::Gt => break,\n                            TokenKind::Whitespace => self.step(),\n                            _ => return false,\n                        }\n                    }\n                    self.step();\n                    return true;\n                },\n                (Pat::CaptureOptLifetimeArg, _) => {\n                    *captures.next().unwrap() = Capture { pos: 0, len: 0 };\n                    return true;\n                },\n                #[rustfmt::skip]\n                (\n                    Pat::CaptureLitStr,\n                    TokenKind::Literal {\n                        kind:\n                            LiteralKind::Str { terminated: true }\n                            | LiteralKind::RawStr { n_hashes: Some(_) },\n                        ..\n                    },\n                )\n                | (Pat::CaptureIdent, TokenKind::Ident) => {\n                    *captures.next().unwrap() = Capture { pos: self.pos, len: self.next_token.len };\n                    self.step();\n                    return true;\n                },\n                (Pat::CaptureDocLines, TokenKind::LineComment { doc_style: Some(_) }) => {\n                    let pos = self.pos;\n                    loop {\n                        self.step();\n                        if !matches!(\n                            self.next_token.kind,\n                            TokenKind::Whitespace | TokenKind::LineComment { doc_style: Some(_) }\n                        ) {\n                            break;\n                        }\n                    }\n                    *captures.next().unwrap() = Capture {\n                        pos,\n                        len: self.pos - pos,\n                    };\n                    return true;\n                },\n                (Pat::CaptureDocLines, _) => {\n                    *captures.next().unwrap() = Capture::EMPTY;\n                    return true;\n                },\n                (Pat::AnyComment, _) => return true,\n                _ => return false,\n            }\n        }\n    }\n\n    /// Consumes all tokens until the specified identifier is found and returns its\n    /// position. Returns `None` if the identifier could not be found.\n    ///\n    /// The cursor will be positioned immediately after the identifier, or at the end if\n    /// it is not.\n    pub fn find_ident(&mut self, ident: &str) -> Option<u32> {\n        loop {\n            match self.next_token.kind {\n                TokenKind::Ident if self.peek_text() == ident => {\n                    let pos = self.pos;\n                    self.step();\n                    return Some(pos);\n                },\n                TokenKind::Eof => return None,\n                _ => self.step(),\n            }\n        }\n    }\n\n    /// Consumes all tokens until the next identifier is found and captures it. Returns\n    /// `None` if no identifier could be found.\n    ///\n    /// The cursor will be positioned immediately after the identifier, or at the end if\n    /// it is not.\n    pub fn find_any_ident(&mut self) -> Option<Capture> {\n        loop {\n            match self.next_token.kind {\n                TokenKind::Ident => {\n                    let res = Capture {\n                        pos: self.pos,\n                        len: self.next_token.len,\n                    };\n                    self.step();\n                    return Some(res);\n                },\n                TokenKind::Eof => return None,\n                _ => self.step(),\n            }\n        }\n    }\n\n    /// Consume the returns the position of the next non-whitespace token if it's the\n    /// specified identifier. Returns `None` otherwise.\n    pub fn match_ident(&mut self, s: &str) -> Option<u32> {\n        loop {\n            match self.next_token.kind {\n                TokenKind::Ident if s == self.peek_text() => {\n                    let pos = self.pos;\n                    self.step();\n                    return Some(pos);\n                },\n                TokenKind::Whitespace => self.step(),\n                _ => return None,\n            }\n        }\n    }\n\n    /// Consumes and captures the next non-whitespace token if it's an identifier. Returns\n    /// `None` otherwise.\n    pub fn capture_ident(&mut self) -> Option<Capture> {\n        loop {\n            match self.next_token.kind {\n                TokenKind::Ident => {\n                    let pos = self.pos;\n                    let len = self.next_token.len;\n                    self.step();\n                    return Some(Capture { pos, len });\n                },\n                TokenKind::Whitespace => self.step(),\n                _ => return None,\n            }\n        }\n    }\n\n    /// Continually attempt to match the pattern on subsequent tokens until a match is\n    /// found. Returns whether the pattern was successfully matched.\n    ///\n    /// Not generally suitable for multi-token patterns or patterns that can match\n    /// nothing.\n    #[must_use]\n    pub fn find_pat(&mut self, pat: Pat<'_>) -> bool {\n        let mut capture = [].iter_mut();\n        while !self.match_impl(pat, &mut capture) {\n            self.step();\n            if self.at_end() {\n                return false;\n            }\n        }\n        true\n    }\n\n    /// Attempts to match a sequence of patterns at the current position. Returns whether\n    /// all patterns were successfully matched.\n    ///\n    /// Captures will be written to the given slice in the order they're matched. If a\n    /// capture is matched, but there are no more capture slots this will panic. If the\n    /// match is completed without filling all the capture slots they will be left\n    /// unmodified.\n    ///\n    /// If the match fails the cursor will be positioned at the first failing token.\n    #[must_use]\n    pub fn match_all(&mut self, pats: &[Pat<'_>], captures: &mut [Capture]) -> bool {\n        let mut captures = captures.iter_mut();\n        pats.iter().all(|&p| self.match_impl(p, &mut captures))\n    }\n\n    /// Attempts to match a single pattern at the current position. Returns whether the\n    /// pattern was successfully matched.\n    ///\n    /// If the pattern attempts to capture anything this will panic. If the match fails\n    /// the cursor will be positioned at the first failing token.\n    #[must_use]\n    pub fn match_pat(&mut self, pat: Pat<'_>) -> bool {\n        self.match_impl(pat, &mut [].iter_mut())\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/parse.rs",
    "content": "pub mod cursor;\n\nuse self::cursor::{Capture, Cursor};\nuse crate::utils::{ErrAction, File, Scoped, expect_action, slice_groups_mut, walk_dir_no_dot_or_target};\nuse core::fmt::{self, Display, Write as _};\nuse core::range::Range;\nuse rustc_arena::DroplessArena;\nuse rustc_data_structures::fx::FxHashMap;\nuse std::fs;\nuse std::path::{self, Path, PathBuf};\nuse std::str::pattern::Pattern;\n\npub struct ParseCxImpl<'cx> {\n    pub arena: &'cx DroplessArena,\n    pub str_buf: StrBuf,\n    pub str_list_buf: VecBuf<&'cx str>,\n}\npub type ParseCx<'cx> = &'cx mut ParseCxImpl<'cx>;\n\n/// Calls the given function inside a newly created parsing context.\npub fn new_parse_cx<'env, T>(f: impl for<'cx> FnOnce(&'cx mut Scoped<'cx, 'env, ParseCxImpl<'cx>>) -> T) -> T {\n    let arena = DroplessArena::default();\n    f(&mut Scoped::new(ParseCxImpl {\n        arena: &arena,\n        str_buf: StrBuf::with_capacity(128),\n        str_list_buf: VecBuf::with_capacity(128),\n    }))\n}\n\n/// A string used as a temporary buffer used to avoid allocating for short lived strings.\npub struct StrBuf(String);\nimpl StrBuf {\n    /// Creates a new buffer with the specified initial capacity.\n    pub fn with_capacity(cap: usize) -> Self {\n        Self(String::with_capacity(cap))\n    }\n\n    /// Allocates the result of formatting the given value onto the arena.\n    pub fn alloc_display<'cx>(&mut self, arena: &'cx DroplessArena, value: impl Display) -> &'cx str {\n        self.0.clear();\n        write!(self.0, \"{value}\").expect(\"`Display` impl returned an error\");\n        arena.alloc_str(&self.0)\n    }\n\n    /// Allocates the string onto the arena with all ascii characters converted to\n    /// lowercase.\n    pub fn alloc_ascii_lower<'cx>(&mut self, arena: &'cx DroplessArena, s: &str) -> &'cx str {\n        self.0.clear();\n        self.0.push_str(s);\n        self.0.make_ascii_lowercase();\n        arena.alloc_str(&self.0)\n    }\n\n    /// Allocates the result of replacing all instances the pattern with the given string\n    /// onto the arena.\n    pub fn alloc_replaced<'cx>(\n        &mut self,\n        arena: &'cx DroplessArena,\n        s: &str,\n        pat: impl Pattern,\n        replacement: &str,\n    ) -> &'cx str {\n        let mut parts = s.split(pat);\n        let Some(first) = parts.next() else {\n            return \"\";\n        };\n        self.0.clear();\n        self.0.push_str(first);\n        for part in parts {\n            self.0.push_str(replacement);\n            self.0.push_str(part);\n        }\n        if self.0.is_empty() {\n            \"\"\n        } else {\n            arena.alloc_str(&self.0)\n        }\n    }\n\n    /// Performs an operation with the freshly cleared buffer.\n    pub fn with<T>(&mut self, f: impl FnOnce(&mut String) -> T) -> T {\n        self.0.clear();\n        f(&mut self.0)\n    }\n}\n\npub struct VecBuf<T>(Vec<T>);\nimpl<T> VecBuf<T> {\n    /// Creates a new buffer with the specified initial capacity.\n    pub fn with_capacity(cap: usize) -> Self {\n        Self(Vec::with_capacity(cap))\n    }\n\n    /// Performs an operation with the freshly cleared buffer.\n    pub fn with<R>(&mut self, f: impl FnOnce(&mut Vec<T>) -> R) -> R {\n        self.0.clear();\n        f(&mut self.0)\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Eq, Hash)]\npub enum LintTool {\n    Rustc,\n    Clippy,\n}\nimpl LintTool {\n    /// Gets the namespace prefix to use when naming a lint including the `::`.\n    pub fn prefix(self) -> &'static str {\n        match self {\n            Self::Rustc => \"\",\n            Self::Clippy => \"clippy::\",\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Eq, Hash)]\npub struct LintName<'cx> {\n    pub name: &'cx str,\n    pub tool: LintTool,\n}\nimpl<'cx> LintName<'cx> {\n    pub fn new_rustc(name: &'cx str) -> Self {\n        Self {\n            name,\n            tool: LintTool::Rustc,\n        }\n    }\n\n    pub fn new_clippy(name: &'cx str) -> Self {\n        Self {\n            name,\n            tool: LintTool::Clippy,\n        }\n    }\n}\nimpl Display for LintName<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(self.tool.prefix())?;\n        f.write_str(self.name)\n    }\n}\n\npub struct ActiveLint<'cx> {\n    pub group: &'cx str,\n    pub module: &'cx str,\n    pub path: PathBuf,\n    pub declaration_range: Range<u32>,\n}\n\npub struct DeprecatedLint<'cx> {\n    pub reason: &'cx str,\n    pub version: &'cx str,\n}\n\npub struct RenamedLint<'cx> {\n    pub new_name: LintName<'cx>,\n    pub version: &'cx str,\n}\n\npub enum Lint<'cx> {\n    Active(ActiveLint<'cx>),\n    Deprecated(DeprecatedLint<'cx>),\n    Renamed(RenamedLint<'cx>),\n}\n\n#[derive(Clone, Copy)]\npub enum LintPassMac {\n    Declare,\n    Impl,\n}\nimpl LintPassMac {\n    pub fn name(self) -> &'static str {\n        match self {\n            Self::Declare => \"declare_lint_pass\",\n            Self::Impl => \"impl_lint_pass\",\n        }\n    }\n}\n\npub struct LintPass<'cx> {\n    /// The raw text of the documentation comments. May include leading/trailing\n    /// whitespace and empty lines.\n    pub docs: &'cx str,\n    pub name: &'cx str,\n    pub lt: Option<&'cx str>,\n    pub mac: LintPassMac,\n    pub decl_range: Range<u32>,\n    pub lints: &'cx [&'cx str],\n    pub path: PathBuf,\n}\n\npub struct LintData<'cx> {\n    pub lints: FxHashMap<&'cx str, Lint<'cx>>,\n    pub lint_passes: Vec<LintPass<'cx>>,\n}\nimpl<'cx> LintData<'cx> {\n    #[expect(clippy::type_complexity)]\n    pub fn split_by_lint_file<'s>(\n        &'s mut self,\n    ) -> (\n        FxHashMap<&'s Path, Vec<(&'s str, Range<u32>)>>,\n        impl Iterator<Item = &'s mut [LintPass<'cx>]>,\n    ) {\n        #[expect(clippy::default_trait_access)]\n        let mut lints = FxHashMap::with_capacity_and_hasher(500, Default::default());\n        for (&name, lint) in &self.lints {\n            if let Lint::Active(lint) = lint {\n                lints\n                    .entry(&*lint.path)\n                    .or_insert_with(|| Vec::with_capacity(8))\n                    .push((name, lint.declaration_range));\n            }\n        }\n        let passes = slice_groups_mut(&mut self.lint_passes, |head, tail| {\n            tail.iter().take_while(|&x| x.path == head.path).count()\n        });\n        (lints, passes)\n    }\n}\n\nimpl<'cx> ParseCxImpl<'cx> {\n    /// Finds and parses all lint declarations.\n    #[must_use]\n    pub fn parse_lint_decls(&mut self) -> LintData<'cx> {\n        let mut data = LintData {\n            #[expect(clippy::default_trait_access)]\n            lints: FxHashMap::with_capacity_and_hasher(1000, Default::default()),\n            lint_passes: Vec::with_capacity(400),\n        };\n\n        let mut contents = String::new();\n        for e in expect_action(fs::read_dir(\".\"), ErrAction::Read, \".\") {\n            let e = expect_action(e, ErrAction::Read, \".\");\n\n            // Skip if this isn't a lint crate's directory.\n            let mut crate_path = if expect_action(e.file_type(), ErrAction::Read, \".\").is_dir()\n                && let Ok(crate_path) = e.file_name().into_string()\n                && crate_path.starts_with(\"clippy_lints\")\n                && crate_path != \"clippy_lints_internal\"\n            {\n                crate_path\n            } else {\n                continue;\n            };\n\n            crate_path.push(path::MAIN_SEPARATOR);\n            crate_path.push_str(\"src\");\n            for e in walk_dir_no_dot_or_target(&crate_path) {\n                let e = expect_action(e, ErrAction::Read, &crate_path);\n                if let Some(path) = e.path().to_str()\n                    && let Some(path) = path.strip_suffix(\".rs\")\n                    && let Some(path) = path.get(crate_path.len() + 1..)\n                {\n                    let module = if path == \"lib\" {\n                        \"\"\n                    } else {\n                        let path = path\n                            .strip_suffix(\"mod\")\n                            .and_then(|x| x.strip_suffix(path::MAIN_SEPARATOR))\n                            .unwrap_or(path);\n                        self.str_buf\n                            .alloc_replaced(self.arena, path, path::MAIN_SEPARATOR, \"::\")\n                    };\n                    self.parse_lint_src_file(\n                        e.path(),\n                        File::open_read_to_cleared_string(e.path(), &mut contents),\n                        module,\n                        &mut data,\n                    );\n                }\n            }\n        }\n\n        self.read_deprecated_lints(&mut data);\n        data\n    }\n\n    /// Parse a source file looking for `declare_clippy_lint` macro invocations.\n    fn parse_lint_src_file(&mut self, path: &Path, contents: &str, module: &'cx str, data: &mut LintData<'cx>) {\n        #[allow(clippy::enum_glob_use)]\n        use cursor::Pat::*;\n        #[rustfmt::skip]\n        static LINT_DECL_TOKENS: &[cursor::Pat<'_>] = &[\n            // !{ /// docs\n            Bang, OpenBrace, AnyComment,\n            // #[clippy::version = \"version\"]\n            Pound, OpenBracket, Ident(\"clippy\"), DoubleColon, Ident(\"version\"), Eq, LitStr, CloseBracket,\n            // pub NAME, GROUP,\n            Ident(\"pub\"), CaptureIdent, Comma, AnyComment, CaptureIdent, Comma,\n        ];\n        #[rustfmt::skip]\n        static PASS_DECL_TOKENS: &[cursor::Pat<'_>] = &[\n            // !( NAME <'lt> => [\n            Bang, OpenParen, CaptureDocLines, CaptureIdent, CaptureOptLifetimeArg, FatArrow, OpenBracket,\n        ];\n\n        let mut cursor = Cursor::new(contents);\n        let mut captures = [Capture::EMPTY; 3];\n        while let Some(mac_name) = cursor.find_any_ident() {\n            match cursor.get_text(mac_name) {\n                \"declare_clippy_lint\"\n                    if cursor.match_all(LINT_DECL_TOKENS, &mut captures) && cursor.find_pat(CloseBrace) =>\n                {\n                    assert!(\n                        data.lints\n                            .insert(\n                                self.str_buf.alloc_ascii_lower(self.arena, cursor.get_text(captures[0])),\n                                Lint::Active(ActiveLint {\n                                    group: self.arena.alloc_str(cursor.get_text(captures[1])),\n                                    module,\n                                    path: path.into(),\n                                    declaration_range: mac_name.pos..cursor.pos(),\n                                }),\n                            )\n                            .is_none()\n                    );\n                },\n                mac @ (\"declare_lint_pass\" | \"impl_lint_pass\") if cursor.match_all(PASS_DECL_TOKENS, &mut captures) => {\n                    let mac = if matches!(mac, \"declare_lint_pass\") {\n                        LintPassMac::Declare\n                    } else {\n                        LintPassMac::Impl\n                    };\n                    let docs = match cursor.get_text(captures[0]) {\n                        \"\" => \"\",\n                        x => self.arena.alloc_str(x),\n                    };\n                    let name = self.arena.alloc_str(cursor.get_text(captures[1]));\n                    let lt = cursor.get_text(captures[2]);\n                    let lt = if lt.is_empty() {\n                        None\n                    } else {\n                        Some(self.arena.alloc_str(lt))\n                    };\n\n                    let lints = self.str_list_buf.with(|buf| {\n                        // Parses a comma separated list of paths and converts each path\n                        // to a string with whitespace removed.\n                        while !cursor.match_pat(CloseBracket) {\n                            buf.push(self.str_buf.with(|buf| {\n                                if cursor.match_pat(DoubleColon) {\n                                    buf.push_str(\"::\");\n                                }\n                                let capture = cursor.capture_ident()?;\n                                buf.push_str(cursor.get_text(capture));\n                                while cursor.match_pat(DoubleColon) {\n                                    buf.push_str(\"::\");\n                                    let capture = cursor.capture_ident()?;\n                                    buf.push_str(cursor.get_text(capture));\n                                }\n                                Some(self.arena.alloc_str(buf))\n                            })?);\n\n                            if !cursor.match_pat(Comma) {\n                                if !cursor.match_pat(CloseBracket) {\n                                    return None;\n                                }\n                                break;\n                            }\n                        }\n\n                        // The arena panics when allocating a size of zero.\n                        Some(if buf.is_empty() {\n                            &[]\n                        } else {\n                            buf.sort_unstable();\n                            &*self.arena.alloc_slice(buf)\n                        })\n                    });\n\n                    if let Some(lints) = lints\n                        && cursor.match_all(&[CloseParen, Semi], &mut [])\n                    {\n                        data.lint_passes.push(LintPass {\n                            docs,\n                            name,\n                            lt,\n                            mac,\n                            decl_range: mac_name.pos..cursor.pos(),\n                            lints,\n                            path: path.into(),\n                        });\n                    }\n                },\n                _ => {},\n            }\n        }\n    }\n\n    fn read_deprecated_lints(&mut self, data: &mut LintData<'cx>) {\n        #[allow(clippy::enum_glob_use)]\n        use cursor::Pat::*;\n        #[rustfmt::skip]\n        static DECL_TOKENS: &[cursor::Pat<'_>] = &[\n            // #[clippy::version = \"version\"]\n            Pound, OpenBracket, Ident(\"clippy\"), DoubleColon, Ident(\"version\"), Eq, CaptureLitStr, CloseBracket,\n            // (\"first\", \"second\"),\n            OpenParen, CaptureLitStr, Comma, CaptureLitStr, CloseParen, Comma,\n        ];\n        #[rustfmt::skip]\n        static DEPRECATED_TOKENS: &[cursor::Pat<'_>] = &[\n            // !{ DEPRECATED(DEPRECATED_VERSION) = [\n            Bang, OpenBrace, Ident(\"DEPRECATED\"), OpenParen, Ident(\"DEPRECATED_VERSION\"), CloseParen, Eq, OpenBracket,\n        ];\n        #[rustfmt::skip]\n        static RENAMED_TOKENS: &[cursor::Pat<'_>] = &[\n            // !{ RENAMED(RENAMED_VERSION) = [\n            Bang, OpenBrace, Ident(\"RENAMED\"), OpenParen, Ident(\"RENAMED_VERSION\"), CloseParen, Eq, OpenBracket,\n        ];\n\n        let path = \"clippy_lints/src/deprecated_lints.rs\";\n        let mut contents = String::new();\n        File::open_read_to_cleared_string(path, &mut contents);\n\n        let mut cursor = Cursor::new(&contents);\n        let mut captures = [Capture::EMPTY; 3];\n\n        // First instance is the macro definition.\n        assert!(\n            cursor.find_ident(\"declare_with_version\").is_some(),\n            \"error reading deprecated lints\"\n        );\n\n        if cursor.find_ident(\"declare_with_version\").is_some() && cursor.match_all(DEPRECATED_TOKENS, &mut []) {\n            while cursor.match_all(DECL_TOKENS, &mut captures) {\n                assert!(\n                    data.lints\n                        .insert(\n                            self.parse_clippy_lint_name(path.as_ref(), cursor.get_text(captures[1])),\n                            Lint::Deprecated(DeprecatedLint {\n                                reason: self.parse_str_single_line(path.as_ref(), cursor.get_text(captures[2])),\n                                version: self.parse_str_single_line(path.as_ref(), cursor.get_text(captures[0])),\n                            }),\n                        )\n                        .is_none()\n                );\n            }\n        } else {\n            panic!(\"error reading deprecated lints\");\n        }\n\n        if cursor.find_ident(\"declare_with_version\").is_some() && cursor.match_all(RENAMED_TOKENS, &mut []) {\n            while cursor.match_all(DECL_TOKENS, &mut captures) {\n                assert!(\n                    data.lints\n                        .insert(\n                            self.parse_clippy_lint_name(path.as_ref(), cursor.get_text(captures[1])),\n                            Lint::Renamed(RenamedLint {\n                                new_name: self.parse_lint_name(path.as_ref(), cursor.get_text(captures[2])),\n                                version: self.parse_str_single_line(path.as_ref(), cursor.get_text(captures[0])),\n                            }),\n                        )\n                        .is_none()\n                );\n            }\n        } else {\n            panic!(\"error reading renamed lints\");\n        }\n    }\n\n    /// Removes the line splices and surrounding quotes from a string literal\n    fn parse_str_lit(&mut self, s: &str) -> &'cx str {\n        let (s, is_raw) = if let Some(s) = s.strip_prefix(\"r\") {\n            (s.trim_matches('#'), true)\n        } else {\n            (s, false)\n        };\n        let s = s\n            .strip_prefix('\"')\n            .and_then(|s| s.strip_suffix('\"'))\n            .unwrap_or_else(|| panic!(\"expected quoted string, found `{s}`\"));\n\n        if is_raw {\n            if s.is_empty() { \"\" } else { self.arena.alloc_str(s) }\n        } else {\n            self.str_buf.with(|buf| {\n                rustc_literal_escaper::unescape_str(s, &mut |_, ch| {\n                    if let Ok(ch) = ch {\n                        buf.push(ch);\n                    }\n                });\n                if buf.is_empty() { \"\" } else { self.arena.alloc_str(buf) }\n            })\n        }\n    }\n\n    fn parse_str_single_line(&mut self, path: &Path, s: &str) -> &'cx str {\n        let value = self.parse_str_lit(s);\n        assert!(\n            !value.contains('\\n'),\n            \"error parsing `{}`: `{s}` should be a single line string\",\n            path.display(),\n        );\n        value\n    }\n\n    fn parse_clippy_lint_name(&mut self, path: &Path, s: &str) -> &'cx str {\n        match self.parse_str_single_line(path, s).strip_prefix(\"clippy::\") {\n            Some(x) => x,\n            None => panic!(\n                \"error parsing `{}`: `{s}` should be a string starting with `clippy::`\",\n                path.display()\n            ),\n        }\n    }\n\n    fn parse_lint_name(&mut self, path: &Path, s: &str) -> LintName<'cx> {\n        let s = self.parse_str_single_line(path, s);\n        let (name, tool) = match s.strip_prefix(\"clippy::\") {\n            Some(s) => (s, LintTool::Clippy),\n            None => (s, LintTool::Rustc),\n        };\n        LintName { name, tool }\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/release.rs",
    "content": "use crate::utils::{FileUpdater, UpdateStatus, Version, parse_cargo_package};\nuse std::fmt::Write;\n\nstatic CARGO_TOML_FILES: &[&str] = &[\n    \"clippy_config/Cargo.toml\",\n    \"clippy_lints/Cargo.toml\",\n    \"clippy_utils/Cargo.toml\",\n    \"declare_clippy_lint/Cargo.toml\",\n    \"Cargo.toml\",\n];\n\npub fn bump_version(mut version: Version) {\n    version.minor += 1;\n\n    let mut updater = FileUpdater::default();\n    for file in CARGO_TOML_FILES {\n        updater.update_file(file, &mut |_, src, dst| {\n            let package = parse_cargo_package(src);\n            if package.version_range.is_empty() {\n                dst.push_str(src);\n                UpdateStatus::Unchanged\n            } else {\n                dst.push_str(&src[..package.version_range.start]);\n                write!(dst, \"\\\"{}\\\"\", version.toml_display()).unwrap();\n                dst.push_str(&src[package.version_range.end..]);\n                UpdateStatus::from_changed(src.get(package.version_range) != dst.get(package.version_range))\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/serve.rs",
    "content": "use crate::utils::{ErrAction, cargo_cmd, expect_action};\nuse core::fmt::Display;\nuse core::mem;\nuse std::path::Path;\nuse std::process::Command;\nuse std::time::{Duration, SystemTime};\nuse std::{fs, thread};\nuse walkdir::WalkDir;\n\n#[cfg(windows)]\nconst PYTHON: &str = \"python\";\n\n#[cfg(not(windows))]\nconst PYTHON: &str = \"python3\";\n\n/// # Panics\n///\n/// Panics if the python commands could not be spawned\npub fn run(port: u16, lint: Option<String>) -> ! {\n    let mut url = Some(match lint {\n        None => format!(\"http://localhost:{port}\"),\n        Some(lint) => format!(\"http://localhost:{port}/#{lint}\"),\n    });\n\n    let mut last_update = mtime(\"util/gh-pages/index.html\");\n    loop {\n        if is_metadata_outdated(mem::replace(&mut last_update, SystemTime::now())) {\n            // Ignore the command result; we'll fall back to displaying the old metadata.\n            let _ = expect_action(\n                cargo_cmd().arg(\"collect-metadata\").status(),\n                ErrAction::Run,\n                \"cargo collect-metadata\",\n            );\n            last_update = SystemTime::now();\n        }\n\n        // Only start the web server the first time around.\n        if let Some(url) = url.take() {\n            thread::spawn(move || {\n                let mut child = expect_action(\n                    Command::new(PYTHON)\n                        .args([\"-m\", \"http.server\", port.to_string().as_str()])\n                        .current_dir(\"util/gh-pages\")\n                        .spawn(),\n                    ErrAction::Run,\n                    \"python -m http.server\",\n                );\n                // Give some time for python to start\n                thread::sleep(Duration::from_millis(500));\n                // Launch browser after first export.py has completed and http.server is up\n                let _result = opener::open(url);\n                expect_action(child.wait(), ErrAction::Run, \"python -m http.server\");\n            });\n        }\n\n        // Delay to avoid updating the metadata too aggressively.\n        thread::sleep(Duration::from_secs(1));\n    }\n}\n\nfn log_err_and_continue<T>(res: Result<T, impl Display>, path: &Path) -> Option<T> {\n    match res {\n        Ok(x) => Some(x),\n        Err(ref e) => {\n            eprintln!(\"error reading `{}`: {e}\", path.display());\n            None\n        },\n    }\n}\n\nfn mtime(path: &str) -> SystemTime {\n    log_err_and_continue(fs::metadata(path), path.as_ref())\n        .and_then(|metadata| log_err_and_continue(metadata.modified(), path.as_ref()))\n        .unwrap_or(SystemTime::UNIX_EPOCH)\n}\n\nfn is_metadata_outdated(time: SystemTime) -> bool {\n    // Ignore all IO errors here. We don't want to stop them from hosting the server.\n    if time < mtime(\"util/gh-pages/index_template.html\") || time < mtime(\"tests/compile-test.rs\") {\n        return true;\n    }\n    let Some(dir) = log_err_and_continue(fs::read_dir(\".\"), \".\".as_ref()) else {\n        return false;\n    };\n    dir.map_while(|e| log_err_and_continue(e, \".\".as_ref())).any(|e| {\n        let name = e.file_name();\n        let name_bytes = name.as_encoded_bytes();\n        if (name_bytes.starts_with(b\"clippy_lints\") && name_bytes != b\"clippy_lints_internal\")\n            || name_bytes == b\"clippy_config\"\n        {\n            WalkDir::new(&name)\n                .into_iter()\n                .map_while(|e| log_err_and_continue(e, name.as_ref()))\n                .filter(|e| e.file_type().is_file())\n                .filter_map(|e| {\n                    log_err_and_continue(e.metadata(), e.path())\n                        .and_then(|m| log_err_and_continue(m.modified(), e.path()))\n                })\n                .any(|ftime| time < ftime)\n        } else {\n            false\n        }\n    })\n}\n"
  },
  {
    "path": "clippy_dev/src/setup/git_hook.rs",
    "content": "use std::fs;\nuse std::path::Path;\n\n/// Rusts setup uses `git rev-parse --git-common-dir` to get the root directory of the repo.\n/// I've decided against this for the sake of simplicity and to make sure that it doesn't install\n/// the hook if `clippy_dev` would be used in the rust tree. The hook also references this tool\n/// for formatting and should therefore only be used in a normal clone of clippy\nconst REPO_GIT_DIR: &str = \".git\";\nconst HOOK_SOURCE_FILE: &str = \"util/etc/pre-commit.sh\";\nconst HOOK_TARGET_FILE: &str = \".git/hooks/pre-commit\";\n\npub fn install_hook(force_override: bool) {\n    if !check_precondition(force_override) {\n        return;\n    }\n\n    // So a little bit of a funny story. Git on unix requires the pre-commit file\n    // to have the `execute` permission to be set. The Rust functions for modifying\n    // these flags doesn't seem to work when executed with normal user permissions.\n    //\n    // However, there is a little hack that is also being used by Rust itself in their\n    // setup script. Git saves the `execute` flag when syncing files. This means\n    // that we can check in a file with execution permissions and the sync it to create\n    // a file with the flag set. We then copy this file here. The copy function will also\n    // include the `execute` permission.\n    match fs::copy(HOOK_SOURCE_FILE, HOOK_TARGET_FILE) {\n        Ok(_) => {\n            println!(\"info: the hook can be removed with `cargo dev remove git-hook`\");\n            println!(\"git hook successfully installed\");\n        },\n        Err(err) => eprintln!(\"error: unable to copy `{HOOK_SOURCE_FILE}` to `{HOOK_TARGET_FILE}` ({err})\"),\n    }\n}\n\nfn check_precondition(force_override: bool) -> bool {\n    // Make sure that we can find the git repository\n    let git_path = Path::new(REPO_GIT_DIR);\n    if !git_path.exists() || !git_path.is_dir() {\n        eprintln!(\"error: clippy_dev was unable to find the `.git` directory\");\n        return false;\n    }\n\n    // Make sure that we don't override an existing hook by accident\n    let path = Path::new(HOOK_TARGET_FILE);\n    if path.exists() {\n        if force_override {\n            return delete_git_hook_file(path);\n        }\n\n        eprintln!(\"error: there is already a pre-commit hook installed\");\n        println!(\"info: use the `--force-override` flag to override the existing hook\");\n        return false;\n    }\n\n    true\n}\n\npub fn remove_hook() {\n    let path = Path::new(HOOK_TARGET_FILE);\n    if path.exists() {\n        if delete_git_hook_file(path) {\n            println!(\"git hook successfully removed\");\n        }\n    } else {\n        println!(\"no pre-commit hook was found\");\n    }\n}\n\nfn delete_git_hook_file(path: &Path) -> bool {\n    if let Err(err) = fs::remove_file(path) {\n        eprintln!(\"error: unable to delete existing pre-commit git hook ({err})\");\n        false\n    } else {\n        true\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/setup/intellij.rs",
    "content": "use std::fs;\nuse std::fs::File;\nuse std::io::prelude::*;\nuse std::path::{Path, PathBuf};\n\n// This module takes an absolute path to a rustc repo and alters the dependencies to point towards\n// the respective rustc subcrates instead of using extern crate xyz.\n// This allows IntelliJ to analyze rustc internals and show proper information inside Clippy\n// code. See https://github.com/rust-lang/rust-clippy/issues/5514 for details\n\nconst RUSTC_PATH_SECTION: &str = \"[target.'cfg(NOT_A_PLATFORM)'.dependencies]\";\nconst DEPENDENCIES_SECTION: &str = \"[dependencies]\";\n\nconst CLIPPY_PROJECTS: &[ClippyProjectInfo] = &[\n    ClippyProjectInfo::new(\"root\", \"Cargo.toml\", \"src/driver.rs\"),\n    ClippyProjectInfo::new(\"clippy_lints\", \"clippy_lints/Cargo.toml\", \"clippy_lints/src/lib.rs\"),\n    ClippyProjectInfo::new(\"clippy_utils\", \"clippy_utils/Cargo.toml\", \"clippy_utils/src/lib.rs\"),\n];\n\n/// Used to store clippy project information to later inject the dependency into.\nstruct ClippyProjectInfo {\n    /// Only used to display information to the user\n    name: &'static str,\n    cargo_file: &'static str,\n    lib_rs_file: &'static str,\n}\n\nimpl ClippyProjectInfo {\n    const fn new(name: &'static str, cargo_file: &'static str, lib_rs_file: &'static str) -> Self {\n        Self {\n            name,\n            cargo_file,\n            lib_rs_file,\n        }\n    }\n}\n\npub fn setup_rustc_src(rustc_path: &str) {\n    let Ok(rustc_source_dir) = check_and_get_rustc_dir(rustc_path) else {\n        return;\n    };\n\n    for project in CLIPPY_PROJECTS {\n        if inject_deps_into_project(&rustc_source_dir, project).is_err() {\n            return;\n        }\n    }\n\n    println!(\"info: the source paths can be removed again with `cargo dev remove intellij`\");\n}\n\nfn check_and_get_rustc_dir(rustc_path: &str) -> Result<PathBuf, ()> {\n    let mut path = PathBuf::from(rustc_path);\n\n    if path.is_relative() {\n        match path.canonicalize() {\n            Ok(absolute_path) => {\n                println!(\"info: the rustc path was resolved to: `{}`\", absolute_path.display());\n                path = absolute_path;\n            },\n            Err(err) => {\n                eprintln!(\"error: unable to get the absolute path of rustc ({err})\");\n                return Err(());\n            },\n        }\n    }\n\n    let path = path.join(\"compiler\");\n    println!(\"info: looking for compiler sources at: {}\", path.display());\n\n    if !path.exists() {\n        eprintln!(\"error: the given path does not exist\");\n        return Err(());\n    }\n\n    if !path.is_dir() {\n        eprintln!(\"error: the given path is not a directory\");\n        return Err(());\n    }\n\n    Ok(path)\n}\n\nfn inject_deps_into_project(rustc_source_dir: &Path, project: &ClippyProjectInfo) -> Result<(), ()> {\n    let cargo_content = read_project_file(project.cargo_file)?;\n    let lib_content = read_project_file(project.lib_rs_file)?;\n\n    if inject_deps_into_manifest(rustc_source_dir, project.cargo_file, &cargo_content, &lib_content).is_err() {\n        eprintln!(\n            \"error: unable to inject dependencies into {} with the Cargo file {}\",\n            project.name, project.cargo_file\n        );\n        Err(())\n    } else {\n        Ok(())\n    }\n}\n\n/// `clippy_dev` expects to be executed in the root directory of Clippy. This function\n/// loads the given file or returns an error. Having it in this extra function ensures\n/// that the error message looks nice.\nfn read_project_file(file_path: &str) -> Result<String, ()> {\n    let path = Path::new(file_path);\n    if !path.exists() {\n        eprintln!(\"error: unable to find the file `{file_path}`\");\n        return Err(());\n    }\n\n    match fs::read_to_string(path) {\n        Ok(content) => Ok(content),\n        Err(err) => {\n            eprintln!(\"error: the file `{file_path}` could not be read ({err})\");\n            Err(())\n        },\n    }\n}\n\nfn inject_deps_into_manifest(\n    rustc_source_dir: &Path,\n    manifest_path: &str,\n    cargo_toml: &str,\n    lib_rs: &str,\n) -> std::io::Result<()> {\n    // do not inject deps if we have already done so\n    if cargo_toml.contains(RUSTC_PATH_SECTION) {\n        eprintln!(\"warn: dependencies are already setup inside {manifest_path}, skipping file\");\n        return Ok(());\n    }\n\n    let extern_crates = lib_rs\n        .lines()\n        // only take dependencies starting with `rustc_`\n        .filter(|line| line.starts_with(\"extern crate rustc_\"))\n        // we have something like \"extern crate foo;\", we only care about the \"foo\"\n        // extern crate rustc_middle;\n        //              ^^^^^^^^^^^^\n        .map(|s| &s[13..(s.len() - 1)]);\n\n    let new_deps = extern_crates.map(|dep| {\n        // format the dependencies that are going to be put inside the Cargo.toml\n        format!(\"{dep} = {{ path = \\\"{}/{dep}\\\" }}\\n\", rustc_source_dir.display())\n    });\n\n    // format a new [dependencies]-block with the new deps we need to inject\n    let mut all_deps = String::from(\"[target.'cfg(NOT_A_PLATFORM)'.dependencies]\\n\");\n    new_deps.for_each(|dep_line| {\n        all_deps.push_str(&dep_line);\n    });\n    all_deps.push_str(\"\\n[dependencies]\\n\");\n\n    // replace \"[dependencies]\" with\n    // [dependencies]\n    // dep1 = { path = ... }\n    // dep2 = { path = ... }\n    // etc\n    let new_manifest = cargo_toml.replacen(\"[dependencies]\\n\", &all_deps, 1);\n\n    // println!(\"{new_manifest}\");\n    let mut file = File::create(manifest_path)?;\n    file.write_all(new_manifest.as_bytes())?;\n\n    println!(\"info: successfully setup dependencies inside {manifest_path}\");\n\n    Ok(())\n}\n\npub fn remove_rustc_src() {\n    for project in CLIPPY_PROJECTS {\n        remove_rustc_src_from_project(project);\n    }\n}\n\nfn remove_rustc_src_from_project(project: &ClippyProjectInfo) -> bool {\n    let Ok(mut cargo_content) = read_project_file(project.cargo_file) else {\n        return false;\n    };\n    let Some(section_start) = cargo_content.find(RUSTC_PATH_SECTION) else {\n        println!(\n            \"info: dependencies could not be found in `{}` for {}, skipping file\",\n            project.cargo_file, project.name\n        );\n        return true;\n    };\n\n    let Some(end_point) = cargo_content.find(DEPENDENCIES_SECTION) else {\n        eprintln!(\n            \"error: the end of the rustc dependencies section could not be found in `{}`\",\n            project.cargo_file\n        );\n        return false;\n    };\n\n    cargo_content.replace_range(section_start..end_point, \"\");\n\n    match File::create(project.cargo_file) {\n        Ok(mut file) => {\n            file.write_all(cargo_content.as_bytes()).unwrap();\n            println!(\"info: successfully removed dependencies inside {}\", project.cargo_file);\n            true\n        },\n        Err(err) => {\n            eprintln!(\n                \"error: unable to open file `{}` to remove rustc dependencies for {} ({err})\",\n                project.cargo_file, project.name\n            );\n            false\n        },\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/setup/mod.rs",
    "content": "pub mod git_hook;\npub mod intellij;\npub mod toolchain;\npub mod vscode;\n"
  },
  {
    "path": "clippy_dev/src/setup/toolchain.rs",
    "content": "use crate::utils::{cargo_cmd, run_exit_on_err};\nuse std::env::consts::EXE_SUFFIX;\nuse std::env::current_dir;\nuse std::ffi::OsStr;\nuse std::fs;\nuse std::path::{Path, PathBuf};\nuse walkdir::WalkDir;\n\npub fn create(standalone: bool, force: bool, release: bool, name: &str) {\n    let rustup_home = std::env::var(\"RUSTUP_HOME\").unwrap();\n    let toolchain = std::env::var(\"RUSTUP_TOOLCHAIN\").unwrap();\n\n    let src = PathBuf::from_iter([&rustup_home, \"toolchains\", &toolchain]);\n    let dest = PathBuf::from_iter([&rustup_home, \"toolchains\", name]);\n\n    if dest.exists() {\n        if force {\n            fs::remove_dir_all(&dest).unwrap();\n        } else {\n            println!(\"{} already exists, pass `--force` to override it\", dest.display());\n            return;\n        }\n    }\n\n    for entry in WalkDir::new(&src) {\n        let entry = entry.unwrap();\n        let relative = entry.path().strip_prefix(&src).unwrap();\n\n        if relative.starts_with(\"bin\")\n            && matches!(\n                relative.file_stem().and_then(OsStr::to_str),\n                Some(\"cargo-clippy\" | \"clippy-driver\")\n            )\n        {\n            continue;\n        }\n\n        let target = dest.join(relative);\n        if entry.file_type().is_dir() {\n            fs::create_dir(&target).unwrap();\n        } else {\n            fs::hard_link(entry.path(), target).unwrap();\n        }\n    }\n\n    run_exit_on_err(\n        \"cargo build\",\n        cargo_cmd().arg(\"build\").args(release.then_some(\"--release\")),\n    );\n\n    install_bin(\"cargo-clippy\", &dest, standalone, release);\n    install_bin(\"clippy-driver\", &dest, standalone, release);\n\n    println!(\"Created toolchain {name}, use it in other projects with e.g. `cargo +{name} clippy`\");\n    if !standalone {\n        println!(\"Note: This will need to be re-run whenever the Clippy `rust-toolchain.toml` changes\");\n    }\n}\n\nfn install_bin(bin: &str, dest: &Path, standalone: bool, release: bool) {\n    #[cfg(windows)]\n    use std::os::windows::fs::symlink_file as symlink;\n\n    #[cfg(not(windows))]\n    use std::os::unix::fs::symlink;\n\n    let profile = if release { \"release\" } else { \"debug\" };\n    let file_name = format!(\"{bin}{EXE_SUFFIX}\");\n\n    let mut src = current_dir().unwrap();\n    src.extend([\"target\", profile, &file_name]);\n\n    let mut dest = dest.to_path_buf();\n    dest.extend([\"bin\", &file_name]);\n\n    if standalone {\n        fs::copy(src, dest).unwrap();\n    } else {\n        symlink(src, dest).unwrap();\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/setup/vscode.rs",
    "content": "use std::fs;\nuse std::path::Path;\n\nconst VSCODE_DIR: &str = \".vscode\";\nconst TASK_SOURCE_FILE: &str = \"util/etc/vscode-tasks.json\";\nconst TASK_TARGET_FILE: &str = \".vscode/tasks.json\";\n\npub fn install_tasks(force_override: bool) {\n    if !check_install_precondition(force_override) {\n        return;\n    }\n\n    match fs::copy(TASK_SOURCE_FILE, TASK_TARGET_FILE) {\n        Ok(_) => {\n            println!(\"info: the task file can be removed with `cargo dev remove vscode-tasks`\");\n            println!(\"vscode tasks successfully installed\");\n        },\n        Err(err) => eprintln!(\"error: unable to copy `{TASK_SOURCE_FILE}` to `{TASK_TARGET_FILE}` ({err})\"),\n    }\n}\n\nfn check_install_precondition(force_override: bool) -> bool {\n    let vs_dir_path = Path::new(VSCODE_DIR);\n    if vs_dir_path.exists() {\n        // verify the target will be valid\n        if !vs_dir_path.is_dir() {\n            eprintln!(\"error: the `.vscode` path exists but seems to be a file\");\n            return false;\n        }\n\n        // make sure that we don't override any existing tasks by accident\n        let path = Path::new(TASK_TARGET_FILE);\n        if path.exists() {\n            if force_override {\n                return delete_vs_task_file(path);\n            }\n\n            eprintln!(\"error: there is already a `task.json` file inside the `{VSCODE_DIR}` directory\");\n            println!(\"info: use the `--force-override` flag to override the existing `task.json` file\");\n            return false;\n        }\n    } else {\n        match fs::create_dir(vs_dir_path) {\n            Ok(()) => {\n                println!(\"info: created `{VSCODE_DIR}` directory for clippy\");\n            },\n            Err(err) => {\n                eprintln!(\"error: the task target directory `{VSCODE_DIR}` could not be created ({err})\");\n            },\n        }\n    }\n\n    true\n}\n\npub fn remove_tasks() {\n    let path = Path::new(TASK_TARGET_FILE);\n    if path.exists() {\n        if delete_vs_task_file(path) {\n            try_delete_vs_directory_if_empty();\n            println!(\"vscode tasks successfully removed\");\n        }\n    } else {\n        println!(\"no vscode tasks were found\");\n    }\n}\n\nfn delete_vs_task_file(path: &Path) -> bool {\n    if let Err(err) = fs::remove_file(path) {\n        eprintln!(\"error: unable to delete the existing `tasks.json` file ({err})\");\n        return false;\n    }\n\n    true\n}\n\n/// This function will try to delete the `.vscode` directory if it's empty.\n/// It may fail silently.\nfn try_delete_vs_directory_if_empty() {\n    let path = Path::new(VSCODE_DIR);\n    if path.read_dir().is_ok_and(|mut iter| iter.next().is_none()) {\n        // The directory is empty. We just try to delete it but allow a silence\n        // fail as an empty `.vscode` directory is still valid\n        let _silence_result = fs::remove_dir(path);\n    } else {\n        // The directory is not empty or could not be read. Either way don't take\n        // any further actions\n    }\n}\n"
  },
  {
    "path": "clippy_dev/src/sync.rs",
    "content": "use crate::utils::{FileUpdater, update_text_region_fn};\nuse chrono::offset::Utc;\nuse std::fmt::Write;\n\npub fn update_nightly() {\n    let date = Utc::now().format(\"%Y-%m-%d\").to_string();\n    let toolchain_update = &mut update_text_region_fn(\n        \"# begin autogenerated nightly\\n\",\n        \"# end autogenerated nightly\",\n        |dst| {\n            writeln!(dst, \"channel = \\\"nightly-{date}\\\"\").unwrap();\n        },\n    );\n    let readme_update = &mut update_text_region_fn(\n        \"<!-- begin autogenerated nightly -->\\n\",\n        \"<!-- end autogenerated nightly -->\",\n        |dst| {\n            writeln!(dst, \"```\\nnightly-{date}\\n```\").unwrap();\n        },\n    );\n\n    let mut updater = FileUpdater::default();\n    updater.update_file(\"rust-toolchain.toml\", toolchain_update);\n    updater.update_file(\"clippy_utils/README.md\", readme_update);\n}\n"
  },
  {
    "path": "clippy_dev/src/utils.rs",
    "content": "use core::fmt::{self, Display};\nuse core::marker::PhantomData;\nuse core::mem;\nuse core::num::NonZero;\nuse core::ops::{Deref, DerefMut};\nuse core::range::Range;\nuse core::str::FromStr;\nuse std::ffi::OsStr;\nuse std::fs::{self, OpenOptions};\nuse std::io::{self, Read as _, Seek as _, SeekFrom, Write};\nuse std::path::{Path, PathBuf};\nuse std::process::{self, Command, Stdio};\nuse std::{env, thread};\nuse walkdir::WalkDir;\n\npub struct Scoped<'inner, 'outer: 'inner, T>(T, PhantomData<&'inner mut T>, PhantomData<&'outer mut ()>);\nimpl<T> Scoped<'_, '_, T> {\n    pub fn new(value: T) -> Self {\n        Self(value, PhantomData, PhantomData)\n    }\n}\nimpl<T> Deref for Scoped<'_, '_, T> {\n    type Target = T;\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\nimpl<T> DerefMut for Scoped<'_, '_, T> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\n#[derive(Clone, Copy)]\npub enum ErrAction {\n    Open,\n    Read,\n    Write,\n    Create,\n    Rename,\n    Delete,\n    Run,\n}\nimpl ErrAction {\n    fn as_str(self) -> &'static str {\n        match self {\n            Self::Open => \"opening\",\n            Self::Read => \"reading\",\n            Self::Write => \"writing\",\n            Self::Create => \"creating\",\n            Self::Rename => \"renaming\",\n            Self::Delete => \"deleting\",\n            Self::Run => \"running\",\n        }\n    }\n}\n\n#[cold]\n#[track_caller]\npub fn panic_action(err: &impl Display, action: ErrAction, path: &Path) -> ! {\n    panic!(\"error {} `{}`: {}\", action.as_str(), path.display(), *err)\n}\n\n#[track_caller]\npub fn expect_action<T>(res: Result<T, impl Display>, action: ErrAction, path: impl AsRef<Path>) -> T {\n    match res {\n        Ok(x) => x,\n        Err(ref e) => panic_action(e, action, path.as_ref()),\n    }\n}\n\n/// Wrapper around `std::fs::File` which panics with a path on failure.\npub struct File<'a> {\n    pub inner: fs::File,\n    pub path: &'a Path,\n}\nimpl<'a> File<'a> {\n    /// Opens a file panicking on failure.\n    #[track_caller]\n    pub fn open(path: &'a (impl AsRef<Path> + ?Sized), options: &mut OpenOptions) -> Self {\n        let path = path.as_ref();\n        Self {\n            inner: expect_action(options.open(path), ErrAction::Open, path),\n            path,\n        }\n    }\n\n    /// Opens a file if it exists, panicking on any other failure.\n    #[track_caller]\n    pub fn open_if_exists(path: &'a (impl AsRef<Path> + ?Sized), options: &mut OpenOptions) -> Option<Self> {\n        let path = path.as_ref();\n        match options.open(path) {\n            Ok(inner) => Some(Self { inner, path }),\n            Err(e) if e.kind() == io::ErrorKind::NotFound => None,\n            Err(e) => panic_action(&e, ErrAction::Open, path),\n        }\n    }\n\n    /// Opens and reads a file into a string, panicking of failure.\n    #[track_caller]\n    pub fn open_read_to_cleared_string<'dst>(\n        path: &'a (impl AsRef<Path> + ?Sized),\n        dst: &'dst mut String,\n    ) -> &'dst mut String {\n        Self::open(path, OpenOptions::new().read(true)).read_to_cleared_string(dst)\n    }\n\n    /// Read the entire contents of a file to the given buffer.\n    #[track_caller]\n    pub fn read_append_to_string<'dst>(&mut self, dst: &'dst mut String) -> &'dst mut String {\n        expect_action(self.inner.read_to_string(dst), ErrAction::Read, self.path);\n        dst\n    }\n\n    #[track_caller]\n    pub fn read_to_cleared_string<'dst>(&mut self, dst: &'dst mut String) -> &'dst mut String {\n        dst.clear();\n        self.read_append_to_string(dst)\n    }\n\n    /// Replaces the entire contents of a file.\n    #[track_caller]\n    pub fn replace_contents(&mut self, data: &[u8]) {\n        let res = match self.inner.seek(SeekFrom::Start(0)) {\n            Ok(_) => match self.inner.write_all(data) {\n                Ok(()) => self.inner.set_len(data.len() as u64),\n                Err(e) => Err(e),\n            },\n            Err(e) => Err(e),\n        };\n        expect_action(res, ErrAction::Write, self.path);\n    }\n}\n\n/// Creates a `Command` for running cargo.\n#[must_use]\npub fn cargo_cmd() -> Command {\n    if let Some(path) = env::var_os(\"CARGO\") {\n        Command::new(path)\n    } else {\n        Command::new(\"cargo\")\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]\npub struct Version {\n    pub major: u16,\n    pub minor: u16,\n}\nimpl FromStr for Version {\n    type Err = ();\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        if let Some(s) = s.strip_prefix(\"0.\")\n            && let Some((major, minor)) = s.split_once('.')\n            && let Ok(major) = major.parse()\n            && let Ok(minor) = minor.parse()\n        {\n            Ok(Self { major, minor })\n        } else {\n            Err(())\n        }\n    }\n}\nimpl Version {\n    /// Displays the version as a rust version. i.e. `x.y.0`\n    #[must_use]\n    pub fn rust_display(self) -> impl Display {\n        struct X(Version);\n        impl Display for X {\n            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n                write!(f, \"{}.{}.0\", self.0.major, self.0.minor)\n            }\n        }\n        X(self)\n    }\n\n    /// Displays the version as it should appear in clippy's toml files. i.e. `0.x.y`\n    #[must_use]\n    pub fn toml_display(self) -> impl Display {\n        struct X(Version);\n        impl Display for X {\n            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n                write!(f, \"0.{}.{}\", self.0.major, self.0.minor)\n            }\n        }\n        X(self)\n    }\n}\n\nenum TomlPart<'a> {\n    Table(&'a str),\n    Value(&'a str, &'a str),\n}\n\nfn toml_iter(s: &str) -> impl Iterator<Item = (usize, TomlPart<'_>)> {\n    let mut pos = 0;\n    s.split('\\n')\n        .map(move |s| {\n            let x = pos;\n            pos += s.len() + 1;\n            (x, s)\n        })\n        .filter_map(|(pos, s)| {\n            if let Some(s) = s.strip_prefix('[') {\n                s.split_once(']').map(|(name, _)| (pos, TomlPart::Table(name)))\n            } else if matches!(s.bytes().next(), Some(b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'_')) {\n                s.split_once('=').map(|(key, value)| (pos, TomlPart::Value(key, value)))\n            } else {\n                None\n            }\n        })\n}\n\npub struct CargoPackage<'a> {\n    pub name: &'a str,\n    pub version_range: Range<usize>,\n    pub not_a_platform_range: Range<usize>,\n}\n\n#[must_use]\npub fn parse_cargo_package(s: &str) -> CargoPackage<'_> {\n    let mut in_package = false;\n    let mut in_platform_deps = false;\n    let mut name = \"\";\n    let mut version_range = 0..0;\n    let mut not_a_platform_range = 0..0;\n    for (offset, part) in toml_iter(s) {\n        match part {\n            TomlPart::Table(name) => {\n                if in_platform_deps {\n                    not_a_platform_range.end = offset;\n                }\n                in_package = false;\n                in_platform_deps = false;\n\n                match name.trim() {\n                    \"package\" => in_package = true,\n                    \"target.'cfg(NOT_A_PLATFORM)'.dependencies\" => {\n                        in_platform_deps = true;\n                        not_a_platform_range.start = offset;\n                    },\n                    _ => {},\n                }\n            },\n            TomlPart::Value(key, value) if in_package => match key.trim_end() {\n                \"name\" => name = value.trim(),\n                \"version\" => {\n                    version_range.start = offset + (value.len() - value.trim().len()) + key.len() + 1;\n                    version_range.end = offset + key.len() + value.trim_end().len() + 1;\n                },\n                _ => {},\n            },\n            TomlPart::Value(..) => {},\n        }\n    }\n    CargoPackage {\n        name,\n        version_range,\n        not_a_platform_range,\n    }\n}\n\npub struct ClippyInfo {\n    pub path: PathBuf,\n    pub version: Version,\n    pub has_intellij_hook: bool,\n}\nimpl ClippyInfo {\n    #[must_use]\n    pub fn search_for_manifest() -> Self {\n        let mut path = env::current_dir().expect(\"error reading the working directory\");\n        let mut buf = String::new();\n        loop {\n            path.push(\"Cargo.toml\");\n            if let Some(mut file) = File::open_if_exists(&path, OpenOptions::new().read(true)) {\n                file.read_to_cleared_string(&mut buf);\n                let package = parse_cargo_package(&buf);\n                if package.name == \"\\\"clippy\\\"\" {\n                    if let Some(version) = buf[package.version_range].strip_prefix('\"')\n                        && let Some(version) = version.strip_suffix('\"')\n                        && let Ok(version) = version.parse()\n                    {\n                        path.pop();\n                        return ClippyInfo {\n                            path,\n                            version,\n                            has_intellij_hook: !package.not_a_platform_range.is_empty(),\n                        };\n                    }\n                    panic!(\"error reading clippy version from `{}`\", file.path.display());\n                }\n            }\n\n            path.pop();\n            assert!(\n                path.pop(),\n                \"error finding project root, please run from inside the clippy directory\"\n            );\n        }\n    }\n}\n\n#[derive(Clone, Copy)]\npub enum UpdateStatus {\n    Unchanged,\n    Changed,\n}\nimpl UpdateStatus {\n    #[must_use]\n    pub fn from_changed(value: bool) -> Self {\n        if value { Self::Changed } else { Self::Unchanged }\n    }\n\n    #[must_use]\n    pub fn is_changed(self) -> bool {\n        matches!(self, Self::Changed)\n    }\n}\n\n#[derive(Clone, Copy)]\npub enum UpdateMode {\n    Change,\n    Check,\n}\nimpl UpdateMode {\n    #[must_use]\n    pub fn from_check(check: bool) -> Self {\n        if check { Self::Check } else { Self::Change }\n    }\n\n    #[must_use]\n    pub fn is_check(self) -> bool {\n        matches!(self, Self::Check)\n    }\n}\n\n#[derive(Default)]\npub struct FileUpdater {\n    src_buf: String,\n    dst_buf: String,\n}\nimpl FileUpdater {\n    #[track_caller]\n    fn update_file_checked_inner(\n        &mut self,\n        tool: &str,\n        mode: UpdateMode,\n        path: &Path,\n        update: &mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus,\n    ) {\n        let mut file = File::open(path, OpenOptions::new().read(true).write(true));\n        file.read_to_cleared_string(&mut self.src_buf);\n        self.dst_buf.clear();\n        match (mode, update(path, &self.src_buf, &mut self.dst_buf)) {\n            (UpdateMode::Check, UpdateStatus::Changed) => {\n                eprintln!(\n                    \"the contents of `{}` are out of date\\nplease run `{tool}` to update\",\n                    path.display()\n                );\n                process::exit(1);\n            },\n            (UpdateMode::Change, UpdateStatus::Changed) => file.replace_contents(self.dst_buf.as_bytes()),\n            (UpdateMode::Check | UpdateMode::Change, UpdateStatus::Unchanged) => {},\n        }\n    }\n\n    #[track_caller]\n    fn update_file_inner(&mut self, path: &Path, update: &mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus) {\n        let mut file = File::open(path, OpenOptions::new().read(true).write(true));\n        file.read_to_cleared_string(&mut self.src_buf);\n        self.dst_buf.clear();\n        if update(path, &self.src_buf, &mut self.dst_buf).is_changed() {\n            file.replace_contents(self.dst_buf.as_bytes());\n        }\n    }\n\n    #[track_caller]\n    pub fn update_file_checked(\n        &mut self,\n        tool: &str,\n        mode: UpdateMode,\n        path: impl AsRef<Path>,\n        update: &mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus,\n    ) {\n        self.update_file_checked_inner(tool, mode, path.as_ref(), update);\n    }\n\n    #[track_caller]\n    pub fn update_file(\n        &mut self,\n        path: impl AsRef<Path>,\n        update: &mut dyn FnMut(&Path, &str, &mut String) -> UpdateStatus,\n    ) {\n        self.update_file_inner(path.as_ref(), update);\n    }\n}\n\n/// Replaces a region in a text delimited by two strings. Returns the new text if both delimiters\n/// were found, or the missing delimiter if not.\npub fn update_text_region(\n    path: &Path,\n    start: &str,\n    end: &str,\n    src: &str,\n    dst: &mut String,\n    insert: &mut impl FnMut(&mut String),\n) -> UpdateStatus {\n    let Some((src_start, src_end)) = src.split_once(start) else {\n        panic!(\"`{}` does not contain `{start}`\", path.display());\n    };\n    let Some((replaced_text, src_end)) = src_end.split_once(end) else {\n        panic!(\"`{}` does not contain `{end}`\", path.display());\n    };\n    dst.push_str(src_start);\n    dst.push_str(start);\n    let new_start = dst.len();\n    insert(dst);\n    let changed = dst[new_start..] != *replaced_text;\n    dst.push_str(end);\n    dst.push_str(src_end);\n    UpdateStatus::from_changed(changed)\n}\n\npub fn update_text_region_fn(\n    start: &str,\n    end: &str,\n    mut insert: impl FnMut(&mut String),\n) -> impl FnMut(&Path, &str, &mut String) -> UpdateStatus {\n    move |path, src, dst| update_text_region(path, start, end, src, dst, &mut insert)\n}\n\n#[track_caller]\npub fn try_rename_file(old_name: &Path, new_name: &Path) -> bool {\n    match OpenOptions::new().create_new(true).write(true).open(new_name) {\n        Ok(file) => drop(file),\n        Err(e) if matches!(e.kind(), io::ErrorKind::AlreadyExists | io::ErrorKind::NotFound) => return false,\n        Err(ref e) => panic_action(e, ErrAction::Create, new_name),\n    }\n    match fs::rename(old_name, new_name) {\n        Ok(()) => true,\n        Err(ref e) => {\n            drop(fs::remove_file(new_name));\n            // `NotADirectory` happens on posix when renaming a directory to an existing file.\n            // Windows will ignore this and rename anyways.\n            if matches!(e.kind(), io::ErrorKind::NotFound | io::ErrorKind::NotADirectory) {\n                false\n            } else {\n                panic_action(e, ErrAction::Rename, old_name);\n            }\n        },\n    }\n}\n\n#[track_caller]\npub fn try_rename_dir(old_name: &Path, new_name: &Path) -> bool {\n    match fs::create_dir(new_name) {\n        Ok(()) => {},\n        Err(e) if matches!(e.kind(), io::ErrorKind::AlreadyExists | io::ErrorKind::NotFound) => return false,\n        Err(ref e) => panic_action(e, ErrAction::Create, new_name),\n    }\n    // Windows can't reliably rename to an empty directory.\n    #[cfg(windows)]\n    drop(fs::remove_dir(new_name));\n    match fs::rename(old_name, new_name) {\n        Ok(()) => true,\n        Err(ref e) => {\n            // Already dropped earlier on windows.\n            #[cfg(not(windows))]\n            drop(fs::remove_dir(new_name));\n            // `NotADirectory` happens on posix when renaming a file to an existing directory.\n            if matches!(e.kind(), io::ErrorKind::NotFound | io::ErrorKind::NotADirectory) {\n                false\n            } else {\n                panic_action(e, ErrAction::Rename, old_name);\n            }\n        },\n    }\n}\n\n#[track_caller]\npub fn run_exit_on_err(path: &(impl AsRef<Path> + ?Sized), cmd: &mut Command) {\n    match expect_action(cmd.status(), ErrAction::Run, path.as_ref()).code() {\n        Some(0) => {},\n        Some(n) => process::exit(n),\n        None => {\n            eprintln!(\"{} killed by signal\", path.as_ref().display());\n            process::exit(1);\n        },\n    }\n}\n\n#[track_caller]\n#[must_use]\npub fn run_with_output(path: &(impl AsRef<Path> + ?Sized), cmd: &mut Command) -> Vec<u8> {\n    fn f(path: &Path, cmd: &mut Command) -> Vec<u8> {\n        let output = expect_action(\n            cmd.stdin(Stdio::null())\n                .stdout(Stdio::piped())\n                .stderr(Stdio::inherit())\n                .output(),\n            ErrAction::Run,\n            path,\n        );\n        expect_action(output.status.exit_ok(), ErrAction::Run, path);\n        output.stdout\n    }\n    f(path.as_ref(), cmd)\n}\n\n/// Splits an argument list across multiple `Command` invocations.\n///\n/// The argument list will be split into a number of batches based on\n/// `thread::available_parallelism`, with `min_batch_size` setting a lower bound on the size of each\n/// batch.\n///\n/// If the size of the arguments would exceed the system limit additional batches will be created.\npub fn split_args_for_threads(\n    min_batch_size: usize,\n    make_cmd: impl FnMut() -> Command,\n    args: impl ExactSizeIterator<Item: AsRef<OsStr>>,\n) -> impl Iterator<Item = Command> {\n    struct Iter<F, I> {\n        make_cmd: F,\n        args: I,\n        min_batch_size: usize,\n        batch_size: usize,\n        thread_count: usize,\n    }\n    impl<F, I> Iterator for Iter<F, I>\n    where\n        F: FnMut() -> Command,\n        I: ExactSizeIterator<Item: AsRef<OsStr>>,\n    {\n        type Item = Command;\n        fn next(&mut self) -> Option<Self::Item> {\n            if self.thread_count > 1 {\n                self.thread_count -= 1;\n            }\n            let mut cmd = (self.make_cmd)();\n            let mut cmd_len = 0usize;\n            for arg in self.args.by_ref().take(self.batch_size) {\n                cmd.arg(arg.as_ref());\n                // `+ 8` to account for the `argv` pointer on unix.\n                // Windows is complicated since the arguments are first converted to UTF-16ish,\n                // but this needs to account for the space between arguments and whatever additional\n                // is needed to escape within an argument.\n                cmd_len += arg.as_ref().len() + 8;\n                cmd_len += 8;\n\n                // Windows has a command length limit of 32767. For unix systems this is more\n                // complicated since the limit includes environment variables and room needs to be\n                // left to edit them once the program starts, but the total size comes from\n                // `getconf ARG_MAX`.\n                //\n                // For simplicity we use 30000 here under a few assumptions.\n                // * Individual arguments aren't super long (the final argument is still added)\n                // * `ARG_MAX` is set to a reasonable amount. Basically every system will be configured way above\n                //   what windows supports, but POSIX only requires `4096`.\n                if cmd_len > 30000 {\n                    self.batch_size = self.args.len().div_ceil(self.thread_count).max(self.min_batch_size);\n                    break;\n                }\n            }\n            (cmd_len != 0).then_some(cmd)\n        }\n    }\n    let thread_count = thread::available_parallelism().map_or(1, NonZero::get);\n    let batch_size = args.len().div_ceil(thread_count).max(min_batch_size);\n    Iter {\n        make_cmd,\n        args,\n        min_batch_size,\n        batch_size,\n        thread_count,\n    }\n}\n\n#[track_caller]\npub fn delete_file_if_exists(path: &Path) -> bool {\n    match fs::remove_file(path) {\n        Ok(()) => true,\n        Err(e) if matches!(e.kind(), io::ErrorKind::NotFound | io::ErrorKind::IsADirectory) => false,\n        Err(ref e) => panic_action(e, ErrAction::Delete, path),\n    }\n}\n\n#[track_caller]\npub fn delete_dir_if_exists(path: &Path) {\n    match fs::remove_dir_all(path) {\n        Ok(()) => {},\n        Err(e) if matches!(e.kind(), io::ErrorKind::NotFound | io::ErrorKind::NotADirectory) => {},\n        Err(ref e) => panic_action(e, ErrAction::Delete, path),\n    }\n}\n\n/// Walks all items excluding top-level dot files/directories and any target directories.\npub fn walk_dir_no_dot_or_target(p: impl AsRef<Path>) -> impl Iterator<Item = ::walkdir::Result<::walkdir::DirEntry>> {\n    WalkDir::new(p).into_iter().filter_entry(|e| {\n        e.path()\n            .file_name()\n            .is_none_or(|x| x != \"target\" && x.as_encoded_bytes().first().copied() != Some(b'.'))\n    })\n}\n\npub fn slice_groups_mut<T>(\n    slice: &mut [T],\n    split_idx: impl FnMut(&T, &[T]) -> usize,\n) -> impl Iterator<Item = &mut [T]> {\n    struct I<'a, T, F> {\n        slice: &'a mut [T],\n        split_idx: F,\n    }\n    impl<'a, T, F: FnMut(&T, &[T]) -> usize> Iterator for I<'a, T, F> {\n        type Item = &'a mut [T];\n        fn next(&mut self) -> Option<Self::Item> {\n            let (head, tail) = self.slice.split_first()?;\n            let idx = (self.split_idx)(head, tail) + 1;\n            // `mem::take` makes it so `self.slice` isn't reborrowed.\n            if let Some((head, tail)) = mem::take(&mut self.slice).split_at_mut_checked(idx) {\n                self.slice = tail;\n                Some(head)\n            } else {\n                self.slice = &mut [];\n                None\n            }\n        }\n    }\n    I { slice, split_idx }\n}\n"
  },
  {
    "path": "clippy_dummy/Cargo.toml",
    "content": "[package]\nname = \"clippy_dummy\" # rename to clippy before publishing\nversion = \"0.0.303\"\nedition = \"2024\"\nreadme = \"crates-readme.md\"\ndescription = \"A bunch of helpful lints to avoid common pitfalls in Rust.\"\nbuild = 'build.rs'\n\nrepository = \"https://github.com/rust-lang/rust-clippy\"\n\nlicense = \"MIT OR Apache-2.0\"\nkeywords = [\"clippy\", \"lint\", \"plugin\"]\ncategories = [\"development-tools\", \"development-tools::cargo-plugins\"]\n\n[build-dependencies]\nterm = \"0.7\"\n"
  },
  {
    "path": "clippy_dummy/PUBLISH.md",
    "content": "This is a dummy crate to publish to crates.io. It primarily exists to ensure\nthat folks trying to install Clippy from crates.io get redirected to the\n`rustup` technique.\n\nBefore publishing, be sure to rename `clippy_dummy` to `clippy` in `Cargo.toml`,\nit has a different name to avoid workspace issues.\n"
  },
  {
    "path": "clippy_dummy/build.rs",
    "content": "use term::color::{GREEN, RED, WHITE};\nuse term::{Attr, Error, Result};\n\nfn main() {\n    if foo().is_err() {\n        eprintln!(\n            \"error: Clippy is no longer available via crates.io\\n\\n\\\n             help: please run `rustup component add clippy` instead\"\n        );\n    }\n    std::process::exit(1);\n}\n\nfn foo() -> Result<()> {\n    let mut t = term::stderr().ok_or(Error::NotSupported)?;\n\n    t.attr(Attr::Bold)?;\n    t.fg(RED)?;\n    write!(t, \"\\nerror: \")?;\n\n    t.reset()?;\n    t.fg(WHITE)?;\n    writeln!(t, \"Clippy is no longer available via crates.io\\n\")?;\n\n    t.attr(Attr::Bold)?;\n    t.fg(GREEN)?;\n    write!(t, \"help: \")?;\n\n    t.reset()?;\n    t.fg(WHITE)?;\n    write!(t, \"please run `\")?;\n\n    t.attr(Attr::Bold)?;\n    write!(t, \"rustup component add clippy\")?;\n\n    t.reset()?;\n    t.fg(WHITE)?;\n    writeln!(t, \"` instead\")?;\n\n    t.reset()?;\n    Ok(())\n}\n"
  },
  {
    "path": "clippy_dummy/crates-readme.md",
    "content": "Installing Clippy via crates.io is deprecated. Please use the following:\n\n```terminal\nrustup component add clippy\n```\n\non a Rust version 1.29 or later. You may need to run `rustup self update` if it complains about a missing Clippy binary.\n\nSee [the homepage](https://github.com/rust-lang/rust-clippy/#clippy) for more information\n"
  },
  {
    "path": "clippy_dummy/src/main.rs",
    "content": "fn main() {\n    panic!(\"This shouldn't even compile\")\n}\n"
  },
  {
    "path": "clippy_lints/Cargo.toml",
    "content": "[package]\nname = \"clippy_lints\"\nversion = \"0.1.96\"\ndescription = \"A bunch of helpful lints to avoid common pitfalls in Rust\"\nrepository = \"https://github.com/rust-lang/rust-clippy\"\nreadme = \"README.md\"\nlicense = \"MIT OR Apache-2.0\"\nkeywords = [\"clippy\", \"lint\", \"plugin\"]\nedition = \"2024\"\n\n[dependencies]\narrayvec = { version = \"0.7\", default-features = false }\ncargo_metadata = \"0.18\"\nclippy_config = { path = \"../clippy_config\" }\nclippy_utils = { path = \"../clippy_utils\" }\ndeclare_clippy_lint = { path = \"../declare_clippy_lint\" }\nitertools = \"0.12\"\nquine-mc_cluskey = \"0.2\"\nregex-syntax = \"0.8\"\nserde = { version = \"1.0\", features = [\"derive\"] }\nunicode-normalization = \"0.1\"\nunicode-script = { version = \"0.5\", default-features = false }\nsemver = \"1.0\"\nurl = \"2.2\"\n\n[dependencies.toml]\nversion = \"0.9.7\"\ndefault-features = false\n# preserve_order keeps diagnostic output in file order\nfeatures = [\"parse\", \"preserve_order\"]\n\n[dev-dependencies]\nwalkdir = \"2.3\"\n\n[lints.rust.unexpected_cfgs]\nlevel = \"warn\"\ncheck-cfg = ['cfg(bootstrap)']\n\n[package.metadata.rust-analyzer]\n# This crate uses #[feature(rustc_private)]\nrustc_private = true\n"
  },
  {
    "path": "clippy_lints/README.md",
    "content": "This crate contains Clippy lints. For the main crate, check [GitHub](https://github.com/rust-lang/rust-clippy).\n"
  },
  {
    "path": "clippy_lints/src/absolute_paths.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::is_from_proc_macro;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::{CRATE_DEF_INDEX, DefId};\nuse rustc_hir::{HirId, ItemKind, Node, Path};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Symbol;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of items through absolute paths, like `std::env::current_dir`.\n    ///\n    /// ### Why restrict this?\n    /// Many codebases have their own style when it comes to importing, but one that is seldom used\n    /// is using absolute paths *everywhere*. This is generally considered unidiomatic, and you\n    /// should add a `use` statement.\n    ///\n    /// The default maximum segments (2) is pretty strict, you may want to increase this in\n    /// `clippy.toml`.\n    ///\n    /// Note: One exception to this is code from macro expansion - this does not lint such cases, as\n    /// using absolute paths is the proper way of referencing items in one.\n    ///\n    /// ### Known issues\n    ///\n    /// There are currently a few cases which are not caught by this lint:\n    /// * Macro calls. e.g. `path::to::macro!()`\n    /// * Derive macros. e.g. `#[derive(path::to::macro)]`\n    /// * Attribute macros. e.g. `#[path::to::macro]`\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = std::f64::consts::PI;\n    /// ```\n    /// Use any of the below instead, or anything else:\n    /// ```no_run\n    /// use std::f64;\n    /// use std::f64::consts;\n    /// use std::f64::consts::PI;\n    /// let x = f64::consts::PI;\n    /// let x = consts::PI;\n    /// let x = PI;\n    /// use std::f64::consts as f64_consts;\n    /// let x = f64_consts::PI;\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub ABSOLUTE_PATHS,\n    restriction,\n    \"checks for usage of an item without a `use` statement\"\n}\n\nimpl_lint_pass!(AbsolutePaths => [ABSOLUTE_PATHS]);\n\npub struct AbsolutePaths {\n    pub absolute_paths_max_segments: u64,\n    pub absolute_paths_allowed_crates: FxHashSet<Symbol>,\n}\n\nimpl AbsolutePaths {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            absolute_paths_max_segments: conf.absolute_paths_max_segments,\n            absolute_paths_allowed_crates: conf\n                .absolute_paths_allowed_crates\n                .iter()\n                .map(|x| Symbol::intern(x))\n                .collect(),\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for AbsolutePaths {\n    // We should only lint `QPath::Resolved`s, but since `Path` is only used in `Resolved` and `UsePath`\n    // we don't need to use a visitor or anything as we can just check if the `Node` for `hir_id` isn't\n    // a `Use`\n    fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, hir_id: HirId) {\n        let segments = match path.segments {\n            [] | [_] => return,\n            // Don't count enum variants and trait items as part of the length.\n            [rest @ .., _]\n                if let [.., s] = rest\n                    && matches!(s.res, Res::Def(DefKind::Enum | DefKind::Trait | DefKind::TraitAlias, _)) =>\n            {\n                rest\n            },\n            path => path,\n        };\n        if let [s1, s2, ..] = segments\n            && let has_root = s1.ident.name == kw::PathRoot\n            && let first = if has_root { s2 } else { s1 }\n            && let len = segments.len() - usize::from(has_root)\n            && len as u64 > self.absolute_paths_max_segments\n            && let crate_name = if let Res::Def(DefKind::Mod, DefId { index, .. }) = first.res\n                && index == CRATE_DEF_INDEX\n            {\n                // `other_crate::foo` or `::other_crate::foo`\n                first.ident.name\n            } else if first.ident.name == kw::Crate || has_root {\n                // `::foo` or `crate::foo`\n                kw::Crate\n            } else {\n                return;\n            }\n            && !path.span.from_expansion()\n            && let node = cx.tcx.hir_node(hir_id)\n            && !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(..)))\n            && !self.absolute_paths_allowed_crates.contains(&crate_name)\n            && !is_from_proc_macro(cx, path)\n        {\n            span_lint(\n                cx,\n                ABSOLUTE_PATHS,\n                path.span,\n                \"consider bringing this path into scope with the `use` keyword\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/almost_complete_range.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, MsrvStack};\nuse clippy_utils::source::{trim_span, walk_span_to_context};\nuse rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for ranges which almost include the entire range of letters from 'a' to 'z'\n    /// or digits from '0' to '9', but don't because they're a half open range.\n    ///\n    /// ### Why is this bad?\n    /// This (`'a'..'z'`) is almost certainly a typo meant to include all letters.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = 'a'..'z';\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let _ = 'a'..='z';\n    /// ```\n    #[clippy::version = \"1.68.0\"]\n    pub ALMOST_COMPLETE_RANGE,\n    suspicious,\n    \"almost complete range\"\n}\n\nimpl_lint_pass!(AlmostCompleteRange => [ALMOST_COMPLETE_RANGE]);\n\npub struct AlmostCompleteRange {\n    msrv: MsrvStack,\n}\nimpl AlmostCompleteRange {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: MsrvStack::new(conf.msrv),\n        }\n    }\n}\nimpl EarlyLintPass for AlmostCompleteRange {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {\n        if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind\n            && is_incomplete_range(start, end)\n            && !e.span.in_external_macro(cx.sess().source_map())\n        {\n            span_lint_and_then(\n                cx,\n                ALMOST_COMPLETE_RANGE,\n                e.span,\n                \"almost complete ascii range\",\n                |diag| {\n                    let ctxt = e.span.ctxt();\n                    if let Some(start) = walk_span_to_context(start.span, ctxt)\n                        && let Some(end) = walk_span_to_context(end.span, ctxt)\n                        && self.msrv.meets(msrvs::RANGE_INCLUSIVE)\n                    {\n                        diag.span_suggestion(\n                            trim_span(cx.sess().source_map(), start.between(end)),\n                            \"use an inclusive range\",\n                            \"..=\".to_owned(),\n                            Applicability::MaybeIncorrect,\n                        );\n                    }\n                },\n            );\n        }\n    }\n\n    fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &Pat) {\n        if let PatKind::Range(Some(start), Some(end), kind) = &p.kind\n            && matches!(kind.node, RangeEnd::Excluded)\n            && is_incomplete_range(start, end)\n            && !p.span.in_external_macro(cx.sess().source_map())\n        {\n            span_lint_and_then(\n                cx,\n                ALMOST_COMPLETE_RANGE,\n                p.span,\n                \"almost complete ascii range\",\n                |diag| {\n                    diag.span_suggestion(\n                        kind.span,\n                        \"use an inclusive range\",\n                        if self.msrv.meets(msrvs::RANGE_INCLUSIVE) {\n                            \"..=\".to_owned()\n                        } else {\n                            \"...\".to_owned()\n                        },\n                        Applicability::MaybeIncorrect,\n                    );\n                },\n            );\n        }\n    }\n\n    extract_msrv_attr!();\n}\n\nfn is_incomplete_range(start: &Expr, end: &Expr) -> bool {\n    match (&start.peel_parens().kind, &end.peel_parens().kind) {\n        (&ExprKind::Lit(start_lit), &ExprKind::Lit(end_lit)) => {\n            matches!(\n                (LitKind::from_token_lit(start_lit), LitKind::from_token_lit(end_lit),),\n                (\n                    Ok(LitKind::Byte(b'a') | LitKind::Char('a')),\n                    Ok(LitKind::Byte(b'z') | LitKind::Char('z'))\n                ) | (\n                    Ok(LitKind::Byte(b'A') | LitKind::Char('A')),\n                    Ok(LitKind::Byte(b'Z') | LitKind::Char('Z')),\n                ) | (\n                    Ok(LitKind::Byte(b'0') | LitKind::Char('0')),\n                    Ok(LitKind::Byte(b'9') | LitKind::Char('9')),\n                )\n            )\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/approx_const.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::msrvs::{self, Msrv};\nuse rustc_ast::ast::{FloatTy, LitFloatType, LitKind};\nuse rustc_hir::{HirId, Lit, RustcVersion};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, symbol};\nuse std::f64::consts as f64;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for floating point literals that approximate\n    /// constants which are defined in\n    /// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)\n    /// or\n    /// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),\n    /// respectively, suggesting to use the predefined constant.\n    ///\n    /// ### Why is this bad?\n    /// Usually, the definition in the standard library is more\n    /// precise than what people come up with. If you find that your definition is\n    /// actually more precise, please [file a Rust\n    /// issue](https://github.com/rust-lang/rust/issues).\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 3.14;\n    /// let y = 1_f64 / x;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = std::f32::consts::PI;\n    /// let y = std::f64::consts::FRAC_1_PI;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub APPROX_CONSTANT,\n    correctness,\n    \"the approximate of a known float constant (in `std::fXX::consts`)\"\n}\n\nimpl_lint_pass!(ApproxConstant => [APPROX_CONSTANT]);\n\n// Tuples are of the form (constant, name, min_digits, msrv)\nconst KNOWN_CONSTS: [(f64, &str, usize, Option<RustcVersion>); 19] = [\n    (f64::E, \"E\", 4, None),\n    (f64::FRAC_1_PI, \"FRAC_1_PI\", 4, None),\n    (f64::FRAC_1_SQRT_2, \"FRAC_1_SQRT_2\", 5, None),\n    (f64::FRAC_2_PI, \"FRAC_2_PI\", 5, None),\n    (f64::FRAC_2_SQRT_PI, \"FRAC_2_SQRT_PI\", 5, None),\n    (f64::FRAC_PI_2, \"FRAC_PI_2\", 5, None),\n    (f64::FRAC_PI_3, \"FRAC_PI_3\", 5, None),\n    (f64::FRAC_PI_4, \"FRAC_PI_4\", 5, None),\n    (f64::FRAC_PI_6, \"FRAC_PI_6\", 5, None),\n    (f64::FRAC_PI_8, \"FRAC_PI_8\", 5, None),\n    (f64::LN_2, \"LN_2\", 5, None),\n    (f64::LN_10, \"LN_10\", 5, None),\n    (f64::LOG2_10, \"LOG2_10\", 5, Some(msrvs::LOG2_10)),\n    (f64::LOG2_E, \"LOG2_E\", 5, None),\n    (f64::LOG10_2, \"LOG10_2\", 5, Some(msrvs::LOG10_2)),\n    (f64::LOG10_E, \"LOG10_E\", 5, None),\n    (f64::PI, \"PI\", 3, None),\n    (f64::SQRT_2, \"SQRT_2\", 5, None),\n    (f64::TAU, \"TAU\", 3, Some(msrvs::TAU)),\n];\n\npub struct ApproxConstant {\n    msrv: Msrv,\n}\n\nimpl ApproxConstant {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for ApproxConstant {\n    fn check_lit(&mut self, cx: &LateContext<'_>, _hir_id: HirId, lit: Lit, _negated: bool) {\n        match lit.node {\n            LitKind::Float(s, LitFloatType::Suffixed(fty)) => match fty {\n                FloatTy::F16 => self.check_known_consts(cx, lit.span, s, \"f16\"),\n                FloatTy::F32 => self.check_known_consts(cx, lit.span, s, \"f32\"),\n                FloatTy::F64 => self.check_known_consts(cx, lit.span, s, \"f64\"),\n                FloatTy::F128 => self.check_known_consts(cx, lit.span, s, \"f128\"),\n            },\n            // FIXME(f16_f128): add `f16` and `f128` when these types become stable.\n            LitKind::Float(s, LitFloatType::Unsuffixed) => self.check_known_consts(cx, lit.span, s, \"f{32, 64}\"),\n            _ => (),\n        }\n    }\n}\n\nimpl ApproxConstant {\n    fn check_known_consts(&self, cx: &LateContext<'_>, span: Span, s: symbol::Symbol, module: &str) {\n        let s = s.as_str();\n        if let Ok(maybe_constant) = s.parse::<f64>() {\n            for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS {\n                if is_approx_const(constant, s, maybe_constant, min_digits)\n                    && msrv.is_none_or(|msrv| self.msrv.meets(cx, msrv))\n                {\n                    span_lint_and_help(\n                        cx,\n                        APPROX_CONSTANT,\n                        span,\n                        format!(\"approximate value of `{module}::consts::{name}` found\"),\n                        None,\n                        \"consider using the constant directly\",\n                    );\n                    return;\n                }\n            }\n        }\n    }\n}\n\nfn count_digits_after_dot(input: &str) -> usize {\n    input\n        .char_indices()\n        .find(|(_, ch)| *ch == '.')\n        .map_or(0, |(i, _)| input.len() - i - 1)\n}\n\n/// Returns `false` if the number of significant figures in `value` are\n/// less than `min_digits`; otherwise, returns true if `value` is equal\n/// to `constant`, rounded to the number of significant digits present in `value`.\n#[must_use]\nfn is_approx_const(constant: f64, value: &str, f_value: f64, min_digits: usize) -> bool {\n    if value.len() <= min_digits {\n        // The value is not precise enough\n        false\n    } else if f_value.to_string().len() > min_digits && constant.to_string().starts_with(&f_value.to_string()) {\n        // The value represents the same value\n        true\n    } else {\n        // The value is a truncated constant\n\n        // Print constant with numeric formatting (`0`), with the length of `value` as minimum width\n        // (`value_len$`), and with the same precision as `value` (`.value_prec$`).\n        // See https://doc.rust-lang.org/std/fmt/index.html.\n        let round_const = format!(\n            \"{constant:0value_len$.value_prec$}\",\n            value_len = value.len(),\n            value_prec = count_digits_after_dot(value)\n        );\n        value == round_const\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/arbitrary_source_item_ordering.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::{\n    SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind,\n    SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,\n    SourceItemOrderingWithinModuleItemGroupings,\n};\nuse clippy_utils::diagnostics::span_lint_and_note;\nuse clippy_utils::is_cfg_test;\nuse rustc_hir::attrs::AttributeKind;\nuse rustc_hir::{\n    Attribute, FieldDef, HirId, ImplItemId, IsAuto, Item, ItemKind, Mod, OwnerId, QPath, TraitItemId, TyKind, Variant,\n    VariantData,\n};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::AssocKind;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Ident;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Confirms that items are sorted in source files as per configuration.\n    ///\n    /// ### Why restrict this?\n    ///\n    /// Keeping a consistent ordering throughout the codebase helps with working\n    /// as a team, and possibly improves maintainability of the codebase. The\n    /// idea is that by defining a consistent and enforceable rule for how\n    /// source files are structured, less time will be wasted during reviews on\n    /// a topic that is (under most circumstances) not relevant to the logic\n    /// implemented in the code. Sometimes this will be referred to as\n    /// \"bikeshedding\".\n    ///\n    /// The content of items with a representation clause attribute, such as\n    /// `#[repr(C)]` will not be checked, as the order of their fields or\n    /// variants might be dictated by an external API (application binary\n    /// interface).\n    ///\n    /// ### Default Ordering and Configuration\n    ///\n    /// As there is no generally applicable rule, and each project may have\n    /// different requirements, the lint can be configured with high\n    /// granularity. The configuration is split into two stages:\n    ///\n    /// 1. Which item kinds that should have an internal order enforced.\n    /// 2. Individual ordering rules per item kind.\n    ///\n    /// The item kinds that can be linted are:\n    /// - Module (with customized groupings, alphabetical within - configurable)\n    /// - Trait (with customized order of associated items, alphabetical within)\n    /// - Enum, Impl, Struct (purely alphabetical)\n    ///\n    /// #### Module Item Order\n    ///\n    /// Due to the large variation of items within modules, the ordering can be\n    /// configured on a very granular level. Item kinds can be grouped together\n    /// arbitrarily, items within groups will be ordered alphabetically. The\n    /// following table shows the default groupings:\n    ///\n    /// | Group              | Item Kinds           |\n    /// |--------------------|----------------------|\n    /// | `modules`          | \"mod\", \"foreign_mod\" |\n    /// | `use`              | \"use\"                |\n    /// | `macros`           | \"macro\"              |\n    /// | `global_asm`       | \"global_asm\"         |\n    /// | `UPPER_SNAKE_CASE` | \"static\", \"const\"    |\n    /// | `PascalCase`       | \"ty_alias\", \"opaque_ty\", \"enum\", \"struct\", \"union\", \"trait\", \"trait_alias\", \"impl\" |\n    /// | `lower_snake_case` | \"fn\"                 |\n    ///\n    /// The groups' names are arbitrary and can be changed to suit the\n    /// conventions that should be enforced for a specific project.\n    ///\n    /// All item kinds must be accounted for to create an enforceable linting\n    /// rule set. Following are some example configurations that may be useful.\n    ///\n    /// Example: *module inclusions and use statements to be at the top*\n    ///\n    /// ```toml\n    /// module-item-order-groupings = [\n    ///     [ \"modules\", [ \"extern_crate\", \"mod\", \"foreign_mod\" ], ],\n    ///     [ \"use\", [ \"use\", ], ],\n    ///     [ \"everything_else\", [ \"macro\", \"global_asm\", \"static\", \"const\", \"ty_alias\", \"enum\", \"struct\", \"union\", \"trait\", \"trait_alias\", \"impl\", \"fn\", ], ],\n    /// ]\n    /// ```\n    ///\n    /// Example: *only consts and statics should be alphabetically ordered*\n    ///\n    /// It is also possible to configure a selection of module item groups that\n    /// should be ordered alphabetically. This may be useful if for example\n    /// statics and consts should be ordered, but the rest should be left open.\n    ///\n    /// ```toml\n    /// module-items-ordered-within-groupings = [\"UPPER_SNAKE_CASE\"]\n    /// ```\n    ///\n    /// ### Known Problems\n    ///\n    /// #### Performance Impact\n    ///\n    /// Keep in mind, that ordering source code alphabetically can lead to\n    /// reduced performance in cases where the most commonly used enum variant\n    /// isn't the first entry anymore, and similar optimizations that can reduce\n    /// branch misses, cache locality and such. Either don't use this lint if\n    /// that's relevant, or disable the lint in modules or items specifically\n    /// where it matters. Other solutions can be to use profile guided\n    /// optimization (PGO), post-link optimization (e.g. using BOLT for LLVM),\n    /// or other advanced optimization methods. A good starting point to dig\n    /// into optimization is [cargo-pgo][cargo-pgo].\n    ///\n    /// #### Lints on a Contains basis\n    ///\n    /// The lint can be disabled only on a \"contains\" basis, but not per element\n    /// within a \"container\", e.g. the lint works per-module, per-struct,\n    /// per-enum, etc. but not for \"don't order this particular enum variant\".\n    ///\n    /// #### Module documentation\n    ///\n    /// Module level rustdoc comments are not part of the resulting syntax tree\n    /// and as such cannot be linted from within `check_mod`. Instead, the\n    /// `rustdoc::missing_documentation` lint may be used.\n    ///\n    /// #### Module Tests\n    ///\n    /// This lint does not implement detection of module tests (or other feature\n    /// dependent elements for that matter). To lint the location of mod tests,\n    /// the lint `items_after_test_module` can be used instead.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// trait TraitUnordered {\n    ///     const A: bool;\n    ///     const C: bool;\n    ///     const B: bool;\n    ///\n    ///     type SomeType;\n    ///\n    ///     fn a();\n    ///     fn c();\n    ///     fn b();\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// trait TraitOrdered {\n    ///     const A: bool;\n    ///     const B: bool;\n    ///     const C: bool;\n    ///\n    ///     type SomeType;\n    ///\n    ///     fn a();\n    ///     fn b();\n    ///     fn c();\n    /// }\n    /// ```\n    ///\n    /// [cargo-pgo]: https://github.com/Kobzol/cargo-pgo/blob/main/README.md\n    ///\n    #[clippy::version = \"1.84.0\"]\n    pub ARBITRARY_SOURCE_ITEM_ORDERING,\n    restriction,\n    \"arbitrary source item ordering\"\n}\n\nimpl_lint_pass!(ArbitrarySourceItemOrdering => [ARBITRARY_SOURCE_ITEM_ORDERING]);\n\n#[derive(Debug)]\n#[expect(clippy::struct_excessive_bools, reason = \"Bools are cached feature flags\")]\npub struct ArbitrarySourceItemOrdering {\n    assoc_types_order: SourceItemOrderingTraitAssocItemKinds,\n    enable_ordering_for_enum: bool,\n    enable_ordering_for_impl: bool,\n    enable_ordering_for_module: bool,\n    enable_ordering_for_struct: bool,\n    enable_ordering_for_trait: bool,\n    module_item_order_groupings: SourceItemOrderingModuleItemGroupings,\n    module_items_ordered_within_groupings: SourceItemOrderingWithinModuleItemGroupings,\n}\n\nimpl ArbitrarySourceItemOrdering {\n    pub fn new(conf: &'static Conf) -> Self {\n        #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.\n        use SourceItemOrderingCategory::*;\n        Self {\n            assoc_types_order: conf.trait_assoc_item_kinds_order.clone(),\n            enable_ordering_for_enum: conf.source_item_ordering.contains(&Enum),\n            enable_ordering_for_impl: conf.source_item_ordering.contains(&Impl),\n            enable_ordering_for_module: conf.source_item_ordering.contains(&Module),\n            enable_ordering_for_struct: conf.source_item_ordering.contains(&Struct),\n            enable_ordering_for_trait: conf.source_item_ordering.contains(&Trait),\n            module_item_order_groupings: conf.module_item_order_groupings.clone(),\n            module_items_ordered_within_groupings: conf.module_items_ordered_within_groupings.clone(),\n        }\n    }\n\n    /// Produces a linting warning for incorrectly ordered impl items.\n    fn lint_impl_item(&self, cx: &LateContext<'_>, item: ImplItemId, before_item: ImplItemId) {\n        span_lint_and_note(\n            cx,\n            ARBITRARY_SOURCE_ITEM_ORDERING,\n            cx.tcx.def_span(item.owner_id),\n            format!(\n                \"incorrect ordering of impl items (defined order: {:?})\",\n                self.assoc_types_order\n            ),\n            Some(cx.tcx.def_span(before_item.owner_id)),\n            format!(\"should be placed before `{}`\", cx.tcx.item_name(before_item.owner_id)),\n        );\n    }\n\n    /// Produces a linting warning for incorrectly ordered item members.\n    fn lint_member_name<T: LintContext>(cx: &T, ident: Ident, before_ident: Ident) {\n        span_lint_and_note(\n            cx,\n            ARBITRARY_SOURCE_ITEM_ORDERING,\n            ident.span,\n            \"incorrect ordering of items (must be alphabetically ordered)\",\n            Some(before_ident.span),\n            format!(\"should be placed before `{}`\", before_ident.name),\n        );\n    }\n\n    fn lint_member_item(cx: &LateContext<'_>, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) {\n        let span = if let Some(ident) = item.kind.ident() {\n            ident.span\n        } else {\n            item.span\n        };\n\n        let (before_span, note) = if let Some(ident) = before_item.kind.ident() {\n            (ident.span, format!(\"should be placed before `{}`\", ident.name))\n        } else {\n            (\n                before_item.span,\n                \"should be placed before the following item\".to_owned(),\n            )\n        };\n\n        // This catches false positives where generated code gets linted.\n        if span == before_span {\n            return;\n        }\n\n        span_lint_and_note(cx, ARBITRARY_SOURCE_ITEM_ORDERING, span, msg, Some(before_span), note);\n    }\n\n    /// Produces a linting warning for incorrectly ordered trait items.\n    fn lint_trait_item(&self, cx: &LateContext<'_>, item: TraitItemId, before_item: TraitItemId) {\n        span_lint_and_note(\n            cx,\n            ARBITRARY_SOURCE_ITEM_ORDERING,\n            cx.tcx.def_span(item.owner_id),\n            format!(\n                \"incorrect ordering of trait items (defined order: {:?})\",\n                self.assoc_types_order\n            ),\n            Some(cx.tcx.def_span(before_item.owner_id)),\n            format!(\"should be placed before `{}`\", cx.tcx.item_name(before_item.owner_id)),\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if cx\n            .tcx\n            .hir_attrs(item.hir_id())\n            .iter()\n            .any(|attr| matches!(attr, Attribute::Parsed(AttributeKind::Repr { .. })))\n        {\n            // Do not lint items with a `#[repr]` attribute as their layout may be imposed by an external API.\n            return;\n        }\n        match &item.kind {\n            ItemKind::Enum(_, _generics, enum_def) if self.enable_ordering_for_enum => {\n                let mut cur_v: Option<&Variant<'_>> = None;\n                for variant in enum_def.variants {\n                    if variant.span.in_external_macro(cx.sess().source_map()) {\n                        continue;\n                    }\n\n                    if let Some(cur_v) = cur_v\n                        && cur_v.ident.name.as_str() > variant.ident.name.as_str()\n                        && cur_v.span != variant.span\n                    {\n                        Self::lint_member_name(cx, variant.ident, cur_v.ident);\n                    }\n                    cur_v = Some(variant);\n                }\n            },\n            ItemKind::Struct(_, _generics, VariantData::Struct { fields, .. }) if self.enable_ordering_for_struct => {\n                let mut cur_f: Option<&FieldDef<'_>> = None;\n                for field in *fields {\n                    if field.span.in_external_macro(cx.sess().source_map()) {\n                        continue;\n                    }\n\n                    if let Some(cur_f) = cur_f\n                        && cur_f.ident.name.as_str() > field.ident.name.as_str()\n                        && cur_f.span != field.span\n                    {\n                        Self::lint_member_name(cx, field.ident, cur_f.ident);\n                    }\n                    cur_f = Some(field);\n                }\n            },\n            ItemKind::Trait(_constness, is_auto, _safety, _ident, _generics, _generic_bounds, item_ref)\n                if self.enable_ordering_for_trait && *is_auto == IsAuto::No =>\n            {\n                let mut cur_t: Option<(TraitItemId, Ident)> = None;\n\n                for &item in *item_ref {\n                    let span = cx.tcx.def_span(item.owner_id);\n                    let ident = cx.tcx.item_ident(item.owner_id);\n                    if span.in_external_macro(cx.sess().source_map()) {\n                        continue;\n                    }\n\n                    if let Some((cur_t, cur_ident)) = cur_t {\n                        let cur_t_kind = convert_assoc_item_kind(cx, cur_t.owner_id);\n                        let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind);\n                        let item_kind = convert_assoc_item_kind(cx, item.owner_id);\n                        let item_kind_index = self.assoc_types_order.index_of(&item_kind);\n\n                        if cur_t_kind == item_kind && cur_ident.name.as_str() > ident.name.as_str() {\n                            Self::lint_member_name(cx, ident, cur_ident);\n                        } else if cur_t_kind_index > item_kind_index {\n                            self.lint_trait_item(cx, item, cur_t);\n                        }\n                    }\n                    cur_t = Some((item, ident));\n                }\n            },\n            ItemKind::Impl(trait_impl) if self.enable_ordering_for_impl => {\n                let mut cur_t: Option<(ImplItemId, Ident)> = None;\n\n                for &item in trait_impl.items {\n                    let span = cx.tcx.def_span(item.owner_id);\n                    let ident = cx.tcx.item_ident(item.owner_id);\n                    if span.in_external_macro(cx.sess().source_map()) {\n                        continue;\n                    }\n\n                    if let Some((cur_t, cur_ident)) = cur_t {\n                        let cur_t_kind = convert_assoc_item_kind(cx, cur_t.owner_id);\n                        let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind);\n                        let item_kind = convert_assoc_item_kind(cx, item.owner_id);\n                        let item_kind_index = self.assoc_types_order.index_of(&item_kind);\n\n                        if cur_t_kind == item_kind && cur_ident.name.as_str() > ident.name.as_str() {\n                            Self::lint_member_name(cx, ident, cur_ident);\n                        } else if cur_t_kind_index > item_kind_index {\n                            self.lint_impl_item(cx, item, cur_t);\n                        }\n                    }\n                    cur_t = Some((item, ident));\n                }\n            },\n            _ => {}, // Catch-all for `ItemKinds` that don't have fields.\n        }\n    }\n\n    fn check_mod(&mut self, cx: &LateContext<'tcx>, module: &'tcx Mod<'tcx>, _: HirId) {\n        struct CurItem<'a> {\n            item: &'a Item<'a>,\n            order: usize,\n            name: Option<String>,\n        }\n        let mut cur_t: Option<CurItem<'_>> = None;\n\n        if !self.enable_ordering_for_module {\n            return;\n        }\n\n        let items = module.item_ids.iter().map(|&id| cx.tcx.hir_item(id));\n\n        // Iterates over the items within a module.\n        //\n        // As of 2023-05-09, the Rust compiler will hold the entries in the same\n        // order as they appear in the source code, which is convenient for us,\n        // as no sorting by source map/line of code has to be applied.\n        //\n        for item in items {\n            if is_cfg_test(cx.tcx, item.hir_id()) {\n                continue;\n            }\n\n            if item.span.in_external_macro(cx.sess().source_map()) {\n                continue;\n            }\n\n            if let Some(ident) = item.kind.ident() {\n                if ident.name.as_str().starts_with('_') {\n                    // Filters out unnamed macro-like impls for various derives,\n                    // e.g. serde::Serialize or num_derive::FromPrimitive.\n                    continue;\n                }\n\n                if ident.name == rustc_span::sym::std && item.span.is_dummy() {\n                    if let ItemKind::ExternCrate(None, _) = item.kind {\n                        // Filters the auto-included Rust standard library.\n                        continue;\n                    }\n                    if cfg!(debug_assertions) {\n                        rustc_middle::bug!(\"unknown item: {item:?}\");\n                    }\n                }\n            } else if let ItemKind::Impl(_) = item.kind\n                && get_item_name(item).is_some()\n            {\n                // keep going below\n            } else {\n                continue;\n            }\n\n            let item_kind = convert_module_item_kind(&item.kind);\n            let grouping_name = self.module_item_order_groupings.grouping_name_of(&item_kind);\n            let module_level_order = self\n                .module_item_order_groupings\n                .module_level_order_of(&item_kind)\n                .unwrap_or_default();\n\n            if let Some(cur_t) = cur_t.as_ref() {\n                use std::cmp::Ordering; // Better legibility.\n                match module_level_order.cmp(&cur_t.order) {\n                    Ordering::Less => {\n                        Self::lint_member_item(\n                            cx,\n                            item,\n                            cur_t.item,\n                            \"incorrect ordering of items (module item groupings specify another order)\",\n                        );\n                    },\n                    Ordering::Equal if item_kind == SourceItemOrderingModuleItemKind::Use => {\n                        // Skip ordering use statements, as these should be ordered by rustfmt.\n                    },\n                    Ordering::Equal\n                        if (grouping_name.is_some_and(|grouping_name| {\n                            self.module_items_ordered_within_groupings.ordered_within(grouping_name)\n                        }) && cur_t.name > get_item_name(item)) =>\n                    {\n                        Self::lint_member_item(\n                            cx,\n                            item,\n                            cur_t.item,\n                            \"incorrect ordering of items (must be alphabetically ordered)\",\n                        );\n                    },\n                    Ordering::Equal | Ordering::Greater => {\n                        // Nothing to do in this case, they're already in the right order.\n                    },\n                }\n            }\n\n            // Makes a note of the current item for comparison with the next.\n            cur_t = Some(CurItem {\n                item,\n                order: module_level_order,\n                name: get_item_name(item),\n            });\n        }\n    }\n}\n\n/// Converts a [`ty::AssocKind`] to a [`SourceItemOrderingTraitAssocItemKind`].\n///\n/// This is implemented here because `rustc_hir` is not a dependency of\n/// `clippy_config`.\nfn convert_assoc_item_kind(cx: &LateContext<'_>, owner_id: OwnerId) -> SourceItemOrderingTraitAssocItemKind {\n    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.\n    use SourceItemOrderingTraitAssocItemKind::*;\n\n    let kind = cx.tcx.associated_item(owner_id.def_id).kind;\n\n    match kind {\n        AssocKind::Const { .. } => Const,\n        AssocKind::Type { .. } => Type,\n        AssocKind::Fn { .. } => Fn,\n    }\n}\n\n/// Converts a [`rustc_hir::ItemKind`] to a\n/// [`SourceItemOrderingModuleItemKind`].\n///\n/// This is implemented here because `rustc_hir` is not a dependency of\n/// `clippy_config`.\nfn convert_module_item_kind(value: &ItemKind<'_>) -> SourceItemOrderingModuleItemKind {\n    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.\n    use SourceItemOrderingModuleItemKind::*;\n    match value {\n        ItemKind::ExternCrate(..) => ExternCrate,\n        ItemKind::Use(..) => Use,\n        ItemKind::Static(..) => Static,\n        ItemKind::Const(..) => Const,\n        ItemKind::Fn { .. } => Fn,\n        ItemKind::Macro(..) => Macro,\n        ItemKind::Mod(..) => Mod,\n        ItemKind::ForeignMod { .. } => ForeignMod,\n        ItemKind::GlobalAsm { .. } => GlobalAsm,\n        ItemKind::TyAlias(..) => TyAlias,\n        ItemKind::Enum(..) => Enum,\n        ItemKind::Struct(..) => Struct,\n        ItemKind::Union(..) => Union,\n        ItemKind::Trait(..) => Trait,\n        ItemKind::TraitAlias(..) => TraitAlias,\n        ItemKind::Impl(..) => Impl,\n    }\n}\n\n/// Gets the item name for sorting purposes, which in the general case is\n/// `item.ident.name`.\n///\n/// For trait impls, the name used for sorting will be the written path of\n/// `item.self_ty` plus the written path of `item.of_trait`, joined with\n/// exclamation marks. Exclamation marks are used because they are the first\n/// printable ASCII character.\n///\n/// Trait impls generated using a derive-macro will have their path rewritten,\n/// such that for example `Default` is `$crate::default::Default`, and\n/// `std::clone::Clone` is `$crate::clone::Clone`. This behaviour is described\n/// further in the [Rust Reference, Paths Chapter][rust_ref].\n///\n/// [rust_ref]: https://doc.rust-lang.org/reference/paths.html#crate-1\nfn get_item_name(item: &Item<'_>) -> Option<String> {\n    match item.kind {\n        ItemKind::Impl(im) => {\n            if let TyKind::Path(path) = im.self_ty.kind {\n                match path {\n                    QPath::Resolved(_, path) => {\n                        let segs = path.segments.iter();\n                        let mut segs: Vec<String> = segs.map(|s| s.ident.name.as_str().to_owned()).collect();\n\n                        if let Some(of_trait) = im.of_trait {\n                            let mut trait_segs: Vec<String> = of_trait\n                                .trait_ref\n                                .path\n                                .segments\n                                .iter()\n                                .map(|s| s.ident.name.as_str().to_owned())\n                                .collect();\n                            segs.append(&mut trait_segs);\n                        }\n\n                        segs.push(String::new());\n                        Some(segs.join(\"!!\"))\n                    },\n                    QPath::TypeRelative(_, _path_seg) => {\n                        // This case doesn't exist in the clippy tests codebase.\n                        None\n                    },\n                }\n            } else {\n                // Impls for anything that isn't a named type can be skipped.\n                None\n            }\n        },\n        _ => item.kind.ident().map(|name| name.as_str().to_owned()),\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/arc_with_non_send_sync.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_middle::ty::GenericArgKind;\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does.\n    /// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.\n    ///\n    /// ### Why is this bad?\n    /// `Arc<T>` is a thread-safe `Rc<T>` and guarantees that updates to the reference counter\n    /// use atomic operations. To send an `Arc<T>` across thread boundaries and\n    /// share ownership between multiple threads, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#thread-safety),\n    /// so either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::cell::RefCell;\n    /// # use std::sync::Arc;\n    ///\n    /// fn main() {\n    ///     // This is fine, as `i32` implements `Send` and `Sync`.\n    ///     let a = Arc::new(42);\n    ///\n    ///     // `RefCell` is `!Sync`, so either the `Arc` should be replaced with an `Rc`\n    ///     // or the `RefCell` replaced with something like a `RwLock`\n    ///     let b = Arc::new(RefCell::new(42));\n    /// }\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub ARC_WITH_NON_SEND_SYNC,\n    suspicious,\n    \"using `Arc` with a type that does not implement `Send` and `Sync`\"\n}\n\ndeclare_lint_pass!(ArcWithNonSendSync => [ARC_WITH_NON_SEND_SYNC]);\n\nimpl<'tcx> LateLintPass<'tcx> for ArcWithNonSendSync {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Call(func, [arg]) = expr.kind\n            && let ExprKind::Path(QPath::TypeRelative(func_ty, func_name)) = func.kind\n            && func_name.ident.name == sym::new\n            && !expr.span.from_expansion()\n            && cx.typeck_results().node_type(func_ty.hir_id).is_diag_item(cx, sym::Arc)\n            && let arg_ty = cx.typeck_results().expr_ty(arg)\n            // make sure that the type is not and does not contain any type parameters\n            && arg_ty.walk().all(|arg| {\n                !matches!(arg.kind(), GenericArgKind::Type(ty) if matches!(ty.kind(), ty::Param(_)))\n            })\n            && let Some(send) = cx.tcx.get_diagnostic_item(sym::Send)\n            && let Some(sync) = cx.tcx.lang_items().sync_trait()\n            && let [is_send, is_sync] = [send, sync].map(|id| implements_trait(cx, arg_ty, id, &[]))\n            && let reason = match (is_send, is_sync) {\n                (false, false) => \"neither `Send` nor `Sync`\",\n                (false, true) => \"not `Send`\",\n                (true, false) => \"not `Sync`\",\n                _ => return,\n            }\n            && !is_from_proc_macro(cx, expr)\n        {\n            span_lint_and_then(\n                cx,\n                ARC_WITH_NON_SEND_SYNC,\n                expr.span,\n                \"usage of an `Arc` that is not `Send` and `Sync`\",\n                |diag| {\n                    with_forced_trimmed_paths!({\n                        diag.note(format!(\n                            \"`Arc<{arg_ty}>` is not `Send` and `Sync` as `{arg_ty}` is {reason}\"\n                        ));\n                        diag.help(\"if the `Arc` will not be used across threads replace it with an `Rc`\");\n                        diag.help(format!(\n                            \"otherwise make `{arg_ty}` `Send` and `Sync` or consider a wrapper type such as `Mutex`\"\n                        ));\n                    });\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/as_conversions.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `as` conversions.\n    ///\n    /// Note that this lint is specialized in linting *every single* use of `as`\n    /// regardless of whether good alternatives exist or not. If you want more\n    /// precise lints for `as`, please consider using these separate lints:\n    ///\n    /// - `clippy::cast_lossless`\n    /// - `clippy::cast_possible_truncation`\n    /// - `clippy::cast_possible_wrap`\n    /// - `clippy::cast_precision_loss`\n    /// - `clippy::cast_sign_loss`\n    /// - `clippy::char_lit_as_u8`\n    /// - `clippy::fn_to_numeric_cast`\n    /// - `clippy::fn_to_numeric_cast_with_truncation`\n    /// - `clippy::ptr_as_ptr`\n    /// - `clippy::unnecessary_cast`\n    /// - `invalid_reference_casting`\n    ///\n    /// There is a good explanation the reason why this lint should work in this\n    /// way and how it is useful [in this\n    /// issue](https://github.com/rust-lang/rust-clippy/issues/5122).\n    ///\n    /// ### Why restrict this?\n    /// `as` conversions will perform many kinds of\n    /// conversions, including silently lossy conversions and dangerous coercions.\n    /// There are cases when it makes sense to use `as`, so the lint is\n    /// Allow by default.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let a: u32;\n    /// ...\n    /// f(a as u16);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// f(a.try_into()?);\n    ///\n    /// // or\n    ///\n    /// f(a.try_into().expect(\"Unexpected u16 overflow in f\"));\n    /// ```\n    #[clippy::version = \"1.41.0\"]\n    pub AS_CONVERSIONS,\n    restriction,\n    \"using a potentially dangerous silent `as` conversion\"\n}\n\ndeclare_lint_pass!(AsConversions => [AS_CONVERSIONS]);\n\nimpl<'tcx> LateLintPass<'tcx> for AsConversions {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if let ExprKind::Cast(_, _) = expr.kind\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && !is_from_proc_macro(cx, expr)\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                AS_CONVERSIONS,\n                expr.span,\n                \"using a potentially dangerous silent `as` conversion\",\n                |diag| {\n                    diag.help(\"consider using a safe wrapper for this conversion\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/asm_syntax.rs",
    "content": "use std::fmt;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::ast::{Expr, ExprKind, InlineAsmOptions};\nuse rustc_ast::{InlineAsm, Item, ItemKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_target::asm::InlineAsmArch;\n\n#[derive(Clone, Copy, PartialEq, Eq)]\nenum AsmStyle {\n    Intel,\n    Att,\n}\n\nimpl fmt::Display for AsmStyle {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            AsmStyle::Intel => f.write_str(\"Intel\"),\n            AsmStyle::Att => f.write_str(\"AT&T\"),\n        }\n    }\n}\n\nimpl std::ops::Not for AsmStyle {\n    type Output = AsmStyle;\n\n    fn not(self) -> AsmStyle {\n        match self {\n            AsmStyle::Intel => AsmStyle::Att,\n            AsmStyle::Att => AsmStyle::Intel,\n        }\n    }\n}\n\nfn check_asm_syntax(\n    lint: &'static Lint,\n    cx: &EarlyContext<'_>,\n    inline_asm: &InlineAsm,\n    span: Span,\n    check_for: AsmStyle,\n) {\n    if matches!(cx.sess().asm_arch, Some(InlineAsmArch::X86 | InlineAsmArch::X86_64)) {\n        let style = if inline_asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {\n            AsmStyle::Att\n        } else {\n            AsmStyle::Intel\n        };\n\n        if style == check_for {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(cx, lint, span, format!(\"{style} x86 assembly syntax used\"), |diag| {\n                diag.help(format!(\"use {} x86 assembly syntax\", !style));\n            });\n        }\n    }\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of AT&T x86 assembly syntax.\n    ///\n    /// ### Why restrict this?\n    /// To enforce consistent use of Intel x86 assembly syntax.\n    ///\n    /// ### Example\n    ///\n    /// ```rust,no_run\n    /// # #![feature(asm)]\n    /// # #[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n    /// # unsafe { let ptr = \"\".as_ptr();\n    /// # use std::arch::asm;\n    /// asm!(\"lea ({}), {}\", in(reg) ptr, lateout(reg) _, options(att_syntax));\n    /// # }\n    /// ```\n    /// Use instead:\n    /// ```rust,no_run\n    /// # #![feature(asm)]\n    /// # #[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n    /// # unsafe { let ptr = \"\".as_ptr();\n    /// # use std::arch::asm;\n    /// asm!(\"lea {}, [{}]\", lateout(reg) _, in(reg) ptr);\n    /// # }\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub INLINE_ASM_X86_ATT_SYNTAX,\n    restriction,\n    \"prefer Intel x86 assembly syntax\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of Intel x86 assembly syntax.\n    ///\n    /// ### Why restrict this?\n    /// To enforce consistent use of AT&T x86 assembly syntax.\n    ///\n    /// ### Example\n    ///\n    /// ```rust,no_run\n    /// # #![feature(asm)]\n    /// # #[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n    /// # unsafe { let ptr = \"\".as_ptr();\n    /// # use std::arch::asm;\n    /// asm!(\"lea {}, [{}]\", lateout(reg) _, in(reg) ptr);\n    /// # }\n    /// ```\n    /// Use instead:\n    /// ```rust,no_run\n    /// # #![feature(asm)]\n    /// # #[cfg(any(target_arch = \"x86\", target_arch = \"x86_64\"))]\n    /// # unsafe { let ptr = \"\".as_ptr();\n    /// # use std::arch::asm;\n    /// asm!(\"lea ({}), {}\", in(reg) ptr, lateout(reg) _, options(att_syntax));\n    /// # }\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub INLINE_ASM_X86_INTEL_SYNTAX,\n    restriction,\n    \"prefer AT&T x86 assembly syntax\"\n}\n\ndeclare_lint_pass!(InlineAsmX86AttSyntax => [INLINE_ASM_X86_ATT_SYNTAX]);\n\ndeclare_lint_pass!(InlineAsmX86IntelSyntax => [INLINE_ASM_X86_INTEL_SYNTAX]);\n\nimpl EarlyLintPass for InlineAsmX86IntelSyntax {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::InlineAsm(inline_asm) = &expr.kind {\n            check_asm_syntax(INLINE_ASM_X86_INTEL_SYNTAX, cx, inline_asm, expr.span, AsmStyle::Intel);\n        }\n    }\n\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if let ItemKind::GlobalAsm(inline_asm) = &item.kind {\n            check_asm_syntax(INLINE_ASM_X86_INTEL_SYNTAX, cx, inline_asm, item.span, AsmStyle::Intel);\n        }\n    }\n}\n\nimpl EarlyLintPass for InlineAsmX86AttSyntax {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::InlineAsm(inline_asm) = &expr.kind {\n            check_asm_syntax(INLINE_ASM_X86_ATT_SYNTAX, cx, inline_asm, expr.span, AsmStyle::Att);\n        }\n    }\n\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if let ItemKind::GlobalAsm(inline_asm) = &item.kind {\n            check_asm_syntax(INLINE_ASM_X86_ATT_SYNTAX, cx, inline_asm, item.span, AsmStyle::Att);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/assertions_on_constants.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::macros::{find_assert_args, root_macro_call_first_node};\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::visitors::is_const_evaluatable;\nuse clippy_utils::{is_inside_always_const_context, msrvs};\nuse rustc_ast::LitKind;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `assert!(true)` and `assert!(false)` calls.\n    ///\n    /// ### Why is this bad?\n    /// Will be optimized out by the compiler or should probably be replaced by a\n    /// `panic!()` or `unreachable!()`\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// assert!(false)\n    /// assert!(true)\n    /// const B: bool = false;\n    /// assert!(B)\n    /// ```\n    #[clippy::version = \"1.34.0\"]\n    pub ASSERTIONS_ON_CONSTANTS,\n    style,\n    \"`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`\"\n}\n\nimpl_lint_pass!(AssertionsOnConstants => [ASSERTIONS_ON_CONSTANTS]);\n\npub struct AssertionsOnConstants {\n    msrv: Msrv,\n}\nimpl AssertionsOnConstants {\n    pub fn new(conf: &Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let Some(macro_call) = root_macro_call_first_node(cx, e)\n            && let is_debug = match cx.tcx.get_diagnostic_name(macro_call.def_id) {\n                Some(sym::debug_assert_macro) => true,\n                Some(sym::assert_macro) => false,\n                _ => return,\n            }\n            && let Some((condition, _)) = find_assert_args(cx, e, macro_call.expn)\n            && is_const_evaluatable(cx, condition)\n            && let Some((Constant::Bool(assert_val), const_src)) =\n                ConstEvalCtxt::new(cx).eval_with_source(condition, macro_call.span.ctxt())\n            && let in_const_context = is_inside_always_const_context(cx.tcx, e.hir_id)\n            && (const_src.is_local() || !in_const_context)\n            && !(is_debug && as_bool_lit(condition) == Some(false))\n        {\n            let (msg, help) = if !const_src.is_local() {\n                let help = if self.msrv.meets(cx, msrvs::CONST_BLOCKS) {\n                    \"consider moving this into a const block: `const { assert!(..) }`\"\n                } else if self.msrv.meets(cx, msrvs::CONST_PANIC) {\n                    \"consider moving this to an anonymous constant: `const _: () = { assert!(..); }`\"\n                } else {\n                    return;\n                };\n                (\"this assertion has a constant value\", help)\n            } else if assert_val {\n                (\"this assertion is always `true`\", \"remove the assertion\")\n            } else {\n                (\n                    \"this assertion is always `false`\",\n                    \"replace this with `panic!()` or `unreachable!()`\",\n                )\n            };\n\n            span_lint_and_help(cx, ASSERTIONS_ON_CONSTANTS, macro_call.span, msg, None, help);\n        }\n    }\n}\n\nfn as_bool_lit(e: &Expr<'_>) -> Option<bool> {\n    if let ExprKind::Lit(l) = e.kind\n        && let LitKind::Bool(b) = l.node\n    {\n        Some(b)\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/assertions_on_result_states.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{find_assert_args, root_macro_call_first_node};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::sym;\nuse clippy_utils::ty::{has_debug_impl, is_copy};\nuse clippy_utils::usage::local_used_after_expr;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{Expr, ExprKind, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `assert!(r.is_ok())` or `assert!(r.is_err())` calls.\n    ///\n    /// ### Why restrict this?\n    /// This form of assertion does not show any of the information present in the `Result`\n    /// other than which variant it isn’t.\n    ///\n    /// ### Known problems\n    /// The suggested replacement decreases the readability of code and log output.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// # let r = Ok::<_, ()>(());\n    /// assert!(r.is_ok());\n    /// # let r = Err::<(), _>(());\n    /// assert!(r.is_err());\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```rust,no_run\n    /// # let r = Ok::<_, ()>(());\n    /// r.unwrap();\n    /// # let r = Err::<(), _>(());\n    /// r.unwrap_err();\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub ASSERTIONS_ON_RESULT_STATES,\n    restriction,\n    \"`assert!(r.is_ok())` or `assert!(r.is_err())` gives worse panic messages than directly calling `r.unwrap()` or `r.unwrap_err()`\"\n}\n\ndeclare_lint_pass!(AssertionsOnResultStates => [ASSERTIONS_ON_RESULT_STATES]);\n\nimpl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let Some(macro_call) = root_macro_call_first_node(cx, e)\n            && matches!(cx.tcx.get_diagnostic_name(macro_call.def_id), Some(sym::assert_macro))\n            && let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn)\n            && panic_expn.is_default_message()\n            && let ExprKind::MethodCall(method_segment, recv, [], _) = condition.kind\n            && let result_type_with_refs = cx.typeck_results().expr_ty(recv)\n            && let result_type = result_type_with_refs.peel_refs()\n            && result_type.is_diag_item(cx, sym::Result)\n            && let ty::Adt(_, args) = result_type.kind()\n        {\n            if !is_copy(cx, result_type) {\n                if result_type_with_refs != result_type {\n                    return;\n                } else if let Res::Local(binding_id) = *recv.basic_res()\n                    && local_used_after_expr(cx, binding_id, recv)\n                {\n                    return;\n                }\n            }\n            let (message, replacement) = match method_segment.ident.name {\n                sym::is_ok if type_suitable_to_unwrap(cx, args.type_at(1)) => {\n                    (\"called `assert!` with `Result::is_ok`\", \"unwrap\")\n                },\n                sym::is_err if type_suitable_to_unwrap(cx, args.type_at(0)) => {\n                    (\"called `assert!` with `Result::is_err`\", \"unwrap_err\")\n                },\n                _ => return,\n            };\n            span_lint_and_then(cx, ASSERTIONS_ON_RESULT_STATES, macro_call.span, message, |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let recv = snippet_with_context(cx, recv.span, condition.span.ctxt(), \"..\", &mut app).0;\n\n                // `assert!` doesn't return anything, but `Result::unwrap(_err)` does, so we might need to add a\n                // semicolon to the suggestion to avoid leaking the type\n                let sugg = match cx.tcx.parent_hir_node(e.hir_id) {\n                    // trailing expr of a block\n                    Node::Block(..) => format!(\"{recv}.{replacement}();\"),\n                    // already has a trailing semicolon\n                    Node::Stmt(..) => format!(\"{recv}.{replacement}()\"),\n                    // this is the last-resort option, because it's rather verbose\n                    _ => format!(\"{{ {recv}.{replacement}(); }}\"),\n                };\n                diag.span_suggestion(macro_call.span, \"replace with\", sugg, app);\n            });\n        }\n    }\n}\n\nfn type_suitable_to_unwrap<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    has_debug_impl(cx, ty) && !ty.is_unit() && !ty.is_never()\n}\n"
  },
  {
    "path": "clippy_lints/src/assigning_clones.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{is_in_test, last_path_segment, local_is_initialized, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir;\nuse rustc_middle::ty::{self, Instance, Mutability};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, SyntaxContext};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for code like `foo = bar.clone();`\n    ///\n    /// ### Why is this bad?\n    /// Custom `Clone::clone_from()` or `ToOwned::clone_into` implementations allow the objects\n    /// to share resources and therefore avoid allocations.\n    ///\n    /// ### Example\n    /// ```rust\n    /// struct Thing;\n    ///\n    /// impl Clone for Thing {\n    ///     fn clone(&self) -> Self { todo!() }\n    ///     fn clone_from(&mut self, other: &Self) { todo!() }\n    /// }\n    ///\n    /// pub fn assign_to_ref(a: &mut Thing, b: Thing) {\n    ///     *a = b.clone();\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// struct Thing;\n    ///\n    /// impl Clone for Thing {\n    ///     fn clone(&self) -> Self { todo!() }\n    ///     fn clone_from(&mut self, other: &Self) { todo!() }\n    /// }\n    ///\n    /// pub fn assign_to_ref(a: &mut Thing, b: Thing) {\n    ///     a.clone_from(&b);\n    /// }\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub ASSIGNING_CLONES,\n    pedantic,\n    \"assigning the result of cloning may be inefficient\"\n}\n\nimpl_lint_pass!(AssigningClones => [ASSIGNING_CLONES]);\n\npub struct AssigningClones {\n    msrv: Msrv,\n}\n\nimpl AssigningClones {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for AssigningClones {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let ExprKind::Assign(lhs, rhs, _) = e.kind\n            && let typeck = cx.typeck_results()\n            && let (call_kind, fn_name, fn_def, fn_arg, fn_gen_args) = match rhs.kind {\n                ExprKind::Call(f, [arg])\n                    if let ExprKind::Path(fn_path) = &f.kind\n                        && let Some(def) = typeck.qpath_res(fn_path, f.hir_id).opt_def(cx) =>\n                {\n                    (CallKind::Ufcs, last_path_segment(fn_path).ident.name, def, arg, typeck.node_args(f.hir_id))\n                },\n                ExprKind::MethodCall(name, recv, [], _) if let Some(def) = typeck.type_dependent_def(rhs.hir_id) => {\n                    (CallKind::Method, name.ident.name, def, recv, typeck.node_args(rhs.hir_id))\n                },\n                _ => return,\n            }\n            && let ctxt = e.span.ctxt()\n            // Don't lint in macros.\n            && ctxt.is_root()\n            && let which_trait = match fn_name {\n                sym::clone if fn_def.assoc_fn_parent(cx).is_diag_item(cx, sym::Clone) => CloneTrait::Clone,\n                sym::to_owned\n                    if fn_def.assoc_fn_parent(cx).is_diag_item(cx, sym::ToOwned)\n                        && self.msrv.meets(cx, msrvs::CLONE_INTO) =>\n                {\n                    CloneTrait::ToOwned\n                },\n                _ => return,\n            }\n            && let Ok(Some(resolved_fn)) = Instance::try_resolve(cx.tcx, cx.typing_env(), fn_def.1, fn_gen_args)\n            // TODO: This check currently bails if the local variable has no initializer.\n            // That is overly conservative - the lint should fire even if there was no initializer,\n            // but the variable has been initialized before `lhs` was evaluated.\n            && lhs.res_local_id().is_none_or(|lhs| local_is_initialized(cx, lhs))\n            && let Some(resolved_impl) = cx.tcx.impl_of_assoc(resolved_fn.def_id())\n            // Derived forms don't implement `clone_from`/`clone_into`.\n            // See https://github.com/rust-lang/rust/pull/98445#issuecomment-1190681305\n            && !cx.tcx.is_builtin_derived(resolved_impl)\n            // Don't suggest calling a function we're implementing.\n            && resolved_impl.as_local().is_none_or(|block_id| {\n                cx.tcx.hir_parent_owner_iter(e.hir_id).all(|(id, _)| id.def_id != block_id)\n            })\n            && let resolved_assoc_items = cx.tcx.associated_items(resolved_impl)\n            // Only suggest if `clone_from`/`clone_into` is explicitly implemented\n            && resolved_assoc_items.in_definition_order().any(|assoc|\n                match which_trait {\n                    CloneTrait::Clone => assoc.name() == sym::clone_from,\n                    CloneTrait::ToOwned => assoc.name() == sym::clone_into,\n                }\n            )\n            && !clone_source_borrows_from_dest(cx, lhs, rhs.span)\n            && !is_in_test(cx.tcx, e.hir_id)\n        {\n            span_lint_and_then(\n                cx,\n                ASSIGNING_CLONES,\n                e.span,\n                match which_trait {\n                    CloneTrait::Clone => \"assigning the result of `Clone::clone()` may be inefficient\",\n                    CloneTrait::ToOwned => \"assigning the result of `ToOwned::to_owned()` may be inefficient\",\n                },\n                |diag| {\n                    let mut app = Applicability::Unspecified;\n                    diag.span_suggestion(\n                        e.span,\n                        match which_trait {\n                            CloneTrait::Clone => \"use `clone_from()`\",\n                            CloneTrait::ToOwned => \"use `clone_into()`\",\n                        },\n                        build_sugg(cx, ctxt, lhs, fn_arg, which_trait, call_kind, &mut app),\n                        app,\n                    );\n                },\n            );\n        }\n    }\n}\n\n/// Checks if the data being cloned borrows from the place that is being assigned to:\n///\n/// ```\n/// let mut s = String::new();\n/// let s2 = &s;\n/// s = s2.to_owned();\n/// ```\n///\n/// This cannot be written `s2.clone_into(&mut s)` because it has conflicting borrows.\nfn clone_source_borrows_from_dest(cx: &LateContext<'_>, lhs: &Expr<'_>, call_span: Span) -> bool {\n    let Some(mir) = enclosing_mir(cx.tcx, lhs.hir_id) else {\n        return false;\n    };\n    let PossibleBorrowerMap { map: borrow_map, .. } = PossibleBorrowerMap::new(cx, mir);\n\n    // The operation `dest = src.to_owned()` in MIR is split up across 3 blocks *if* the type has `Drop`\n    // code. For types that don't, the second basic block is simply skipped.\n    // For the doc example above that would be roughly:\n    //\n    // bb0:\n    //  s2 = &s\n    //  s_temp = ToOwned::to_owned(move s2) -> bb1\n    //\n    // bb1:\n    //  drop(s) -> bb2  // drop the old string\n    //\n    // bb2:\n    //  s = s_temp\n    if let Some(terminator) = mir.basic_blocks.iter()\n            .map(mir::BasicBlockData::terminator)\n            .find(|term| term.source_info.span == call_span)\n        && let mir::TerminatorKind::Call { ref args, target: Some(assign_bb), .. } = terminator.kind\n        && let [source] = &**args\n        && let mir::Operand::Move(source) = &source.node\n        && let assign_bb = &mir.basic_blocks[assign_bb]\n        && let assign_bb = match assign_bb.terminator().kind {\n            // Skip the drop of the assignment's destination.\n            mir::TerminatorKind::Drop { target, .. } => &mir.basic_blocks[target],\n            _ => assign_bb,\n        }\n        // Skip any storage statements as they are just noise\n        && let Some(assignment) = assign_bb.statements\n            .iter()\n            .find(|stmt| {\n                !matches!(stmt.kind, mir::StatementKind::StorageDead(_) | mir::StatementKind::StorageLive(_))\n            })\n        && let mir::StatementKind::Assign(box (borrowed, _)) = &assignment.kind\n        && let Some(borrowers) = borrow_map.get(&borrowed.local)\n    {\n        borrowers.contains(source.local)\n    } else {\n        false\n    }\n}\n\n#[derive(Clone, Copy)]\nenum CloneTrait {\n    Clone,\n    ToOwned,\n}\n\n#[derive(Copy, Clone)]\nenum CallKind {\n    Ufcs,\n    Method,\n}\n\nfn build_sugg<'tcx>(\n    cx: &LateContext<'tcx>,\n    ctxt: SyntaxContext,\n    lhs: &'tcx Expr<'_>,\n    fn_arg: &'tcx Expr<'_>,\n    which_trait: CloneTrait,\n    call_kind: CallKind,\n    app: &mut Applicability,\n) -> String {\n    match which_trait {\n        CloneTrait::Clone => {\n            match call_kind {\n                CallKind::Method => {\n                    let receiver_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {\n                        // If `ref_expr` is a reference, we can remove the dereference operator (`*`) to make\n                        // the generated code a bit simpler. In other cases, we don't do this special case, to avoid\n                        // having to deal with Deref (https://github.com/rust-lang/rust-clippy/issues/12437).\n\n                        let ty = cx.typeck_results().expr_ty(ref_expr);\n                        if ty.is_ref() {\n                            // Apply special case, remove `*`\n                            // `*lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`\n                            Sugg::hir_with_applicability(cx, ref_expr, \"_\", app)\n                        } else {\n                            // Keep the original lhs\n                            // `*lhs = self_expr.clone();` -> `(*lhs).clone_from(self_expr)`\n                            Sugg::hir_with_applicability(cx, lhs, \"_\", app)\n                        }\n                    } else {\n                        // Keep the original lhs\n                        // `lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`\n                        Sugg::hir_with_applicability(cx, lhs, \"_\", app)\n                    }\n                    .maybe_paren();\n\n                    // Determine whether we need to reference the argument to clone_from().\n                    let clone_receiver_type = cx.typeck_results().expr_ty(fn_arg);\n                    let clone_receiver_adj_type = cx.typeck_results().expr_ty_adjusted(fn_arg);\n                    let mut arg_sugg = Sugg::hir_with_context(cx, fn_arg, ctxt, \"_\", app);\n                    if clone_receiver_type != clone_receiver_adj_type {\n                        // The receiver may have been a value type, so we need to add an `&` to\n                        // be sure the argument to clone_from will be a reference.\n                        arg_sugg = arg_sugg.addr();\n                    }\n\n                    format!(\"{receiver_sugg}.clone_from({arg_sugg})\")\n                },\n                CallKind::Ufcs => {\n                    let self_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {\n                        // See special case of removing `*` in method handling above\n                        let ty = cx.typeck_results().expr_ty(ref_expr);\n                        if ty.is_ref() {\n                            // `*lhs = Clone::clone(self_expr);` -> `Clone::clone_from(lhs, self_expr)`\n                            Sugg::hir_with_applicability(cx, ref_expr, \"_\", app)\n                        } else {\n                            // `*lhs = Clone::clone(self_expr);` -> `Clone::clone_from(&mut *lhs, self_expr)`\n                            // mut_addr_deref is used to avoid unnecessary parentheses around `*lhs`\n                            Sugg::hir_with_applicability(cx, ref_expr, \"_\", app).mut_addr_deref()\n                        }\n                    } else {\n                        // `lhs = Clone::clone(self_expr);` -> `Clone::clone_from(&mut lhs, self_expr)`\n                        Sugg::hir_with_applicability(cx, lhs, \"_\", app).mut_addr()\n                    };\n                    // The RHS had to be exactly correct before the call, there is no auto-deref for function calls.\n                    let rhs_sugg = Sugg::hir_with_context(cx, fn_arg, ctxt, \"_\", app);\n\n                    format!(\"Clone::clone_from({self_sugg}, {rhs_sugg})\")\n                },\n            }\n        },\n        CloneTrait::ToOwned => {\n            let rhs_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {\n                // `*lhs = rhs.to_owned()` -> `rhs.clone_into(lhs)`\n                // `*lhs = ToOwned::to_owned(rhs)` -> `ToOwned::clone_into(rhs, lhs)`\n                let sugg = Sugg::hir_with_applicability(cx, ref_expr, \"_\", app).maybe_paren();\n                let inner_type = cx.typeck_results().expr_ty(ref_expr);\n                // If after unwrapping the dereference, the type is not a mutable reference, we add &mut to make it\n                // deref to a mutable reference.\n                if matches!(inner_type.kind(), ty::Ref(_, _, Mutability::Mut)) {\n                    sugg\n                } else {\n                    sugg.mut_addr()\n                }\n            } else {\n                // `lhs = rhs.to_owned()` -> `rhs.clone_into(&mut lhs)`\n                // `lhs = ToOwned::to_owned(rhs)` -> `ToOwned::clone_into(rhs, &mut lhs)`\n                Sugg::hir_with_applicability(cx, lhs, \"_\", app).maybe_paren().mut_addr()\n            };\n\n            match call_kind {\n                CallKind::Method => {\n                    let receiver_sugg = Sugg::hir_with_context(cx, fn_arg, ctxt, \"_\", app);\n                    format!(\"{receiver_sugg}.clone_into({rhs_sugg})\")\n                },\n                CallKind::Ufcs => {\n                    let self_sugg = Sugg::hir_with_context(cx, fn_arg, ctxt, \"_\", app);\n                    format!(\"ToOwned::clone_into({self_sugg}, {rhs_sugg})\")\n                },\n            }\n        },\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/async_yields_async.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::is_expr_async_block;\nuse clippy_utils::source::walk_span_to_context;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::implements_trait;\nuse rustc_errors::Applicability;\nuse rustc_hir::{\n    Block, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, QPath,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for async blocks that yield values of types\n    /// that can themselves be awaited.\n    ///\n    /// ### Why is this bad?\n    /// An await is likely missing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// async fn foo() {}\n    ///\n    /// fn bar() {\n    ///   let x = async {\n    ///     foo()\n    ///   };\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// async fn foo() {}\n    ///\n    /// fn bar() {\n    ///   let x = async {\n    ///     foo().await\n    ///   };\n    /// }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub ASYNC_YIELDS_ASYNC,\n    correctness,\n    \"async blocks that return a type that can be awaited\"\n}\n\ndeclare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);\n\nimpl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        let ExprKind::Closure(Closure {\n            kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, kind)),\n            body: body_id,\n            ..\n        }) = expr.kind\n        else {\n            return;\n        };\n\n        let body_expr = match kind {\n            CoroutineSource::Fn => {\n                // For functions, with explicitly defined types, don't warn.\n                // XXXkhuey maybe we should?\n                return;\n            },\n            CoroutineSource::Block => cx.tcx.hir_body(*body_id).value,\n            CoroutineSource::Closure => {\n                // Like `async fn`, async closures are wrapped in an additional block\n                // to move all of the closure's arguments into the future.\n\n                let async_closure_body = cx.tcx.hir_body(*body_id).value;\n                let ExprKind::Block(block, _) = async_closure_body.kind else {\n                    return;\n                };\n                let Some(block_expr) = block.expr else {\n                    return;\n                };\n                let ExprKind::DropTemps(body_expr) = block_expr.kind else {\n                    return;\n                };\n                body_expr\n            },\n        };\n\n        let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() else {\n            return;\n        };\n\n        let typeck_results = cx.tcx.typeck_body(*body_id);\n        let expr_ty = typeck_results.expr_ty(body_expr);\n\n        if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {\n            let (return_expr, return_expr_span) = match &body_expr.kind {\n                ExprKind::Block(Block { expr: Some(e), .. }, _) => (*e, e.span),\n                ExprKind::Path(QPath::Resolved(_, path)) => (body_expr, path.span),\n                _ => return,\n            };\n\n            let return_expr_span = walk_span_to_context(return_expr_span, expr.span.ctxt()).unwrap_or(return_expr_span);\n            let mut applicability = Applicability::MaybeIncorrect;\n            let mut return_expr_snip =\n                Sugg::hir_with_context(cx, return_expr, expr.span.ctxt(), \"..\", &mut applicability);\n            if !is_expr_async_block(return_expr) {\n                return_expr_snip = return_expr_snip.maybe_paren();\n            }\n\n            span_lint_hir_and_then(\n                cx,\n                ASYNC_YIELDS_ASYNC,\n                body_expr.hir_id,\n                return_expr_span,\n                \"an async construct yields a type which is itself awaitable\",\n                |db| {\n                    db.span_label(body_expr.span, \"outer async construct\");\n                    db.span_label(return_expr_span, \"awaitable value not awaited\");\n                    db.span_suggestion(\n                        return_expr_span,\n                        \"consider awaiting this value\",\n                        format!(\"{return_expr_snip}.await\"),\n                        applicability,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/allow_attributes.rs",
    "content": "use super::ALLOW_ATTRIBUTES;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse rustc_ast::attr::AttributeExt;\nuse rustc_ast::{AttrStyle, Attribute};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, LintContext};\n\n// Separate each crate's features.\npub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) {\n    if !attr.span.in_external_macro(cx.sess().source_map())\n        && let AttrStyle::Outer = attr.style\n        && let Some(path_span) = attr.path_span()\n        && !is_from_proc_macro(cx, attr)\n    {\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(cx, ALLOW_ATTRIBUTES, path_span, \"#[allow] attribute found\", |diag| {\n            diag.span_suggestion(path_span, \"replace it with\", \"expect\", Applicability::MachineApplicable);\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/allow_attributes_without_reason.rs",
    "content": "use super::{ALLOW_ATTRIBUTES_WITHOUT_REASON, Attribute};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse rustc_ast::{MetaItemInner, MetaItemKind};\nuse rustc_lint::{EarlyContext, LintContext};\nuse rustc_span::sym;\nuse rustc_span::symbol::Symbol;\n\npub(super) fn check<'cx>(cx: &EarlyContext<'cx>, name: Symbol, items: &[MetaItemInner], attr: &'cx Attribute) {\n    // Check if the reason is present\n    if let Some(item) = items.last().and_then(MetaItemInner::meta_item)\n        && let MetaItemKind::NameValue(_) = &item.kind\n        && item.path == sym::reason\n    {\n        return;\n    }\n\n    // Check if the attribute is in an external macro and therefore out of the developer's control\n    if attr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, attr) {\n        return;\n    }\n\n    #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n    span_lint_and_then(\n        cx,\n        ALLOW_ATTRIBUTES_WITHOUT_REASON,\n        attr.span,\n        format!(\"`{name}` attribute without specifying a reason\"),\n        |diag| {\n            diag.help(\"try adding a reason at the end with `, reason = \\\"..\\\"`\");\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs",
    "content": "use super::BLANKET_CLIPPY_RESTRICTION_LINTS;\nuse super::utils::extract_clippy_lint;\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};\nuse clippy_utils::sym;\nuse rustc_ast::MetaItemInner;\nuse rustc_lint::{EarlyContext, Level, LintContext};\nuse rustc_span::DUMMY_SP;\nuse rustc_span::symbol::Symbol;\n\npub(super) fn check(cx: &EarlyContext<'_>, name: Symbol, items: &[MetaItemInner]) {\n    for lint in items {\n        if name != sym::allow && extract_clippy_lint(lint) == Some(sym::restriction) {\n            span_lint_and_help(\n                cx,\n                BLANKET_CLIPPY_RESTRICTION_LINTS,\n                lint.span(),\n                \"`clippy::restriction` is not meant to be enabled as a group\",\n                None,\n                \"enable the restriction lints you need individually\",\n            );\n        }\n    }\n}\n\npub(super) fn check_command_line(cx: &EarlyContext<'_>) {\n    for (name, level) in &cx.sess().opts.lint_opts {\n        if name == \"clippy::restriction\" && *level > Level::Allow {\n            span_lint_and_then(\n                cx,\n                BLANKET_CLIPPY_RESTRICTION_LINTS,\n                DUMMY_SP,\n                \"`clippy::restriction` is not meant to be enabled as a group\",\n                |diag| {\n                    diag.note(format!(\n                        \"because of the command line `--{} clippy::restriction`\",\n                        level.as_str()\n                    ));\n                    diag.help(\"enable the restriction lints you need individually\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/deprecated_cfg_attr.rs",
    "content": "use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, MsrvStack};\nuse clippy_utils::sym;\nuse rustc_ast::AttrStyle;\nuse rustc_errors::Applicability;\nuse rustc_lint::EarlyContext;\n\npub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {\n    // check cfg_attr\n    if attr.has_name(sym::cfg_attr)\n        && let Some(items) = attr.meta_item_list()\n        && items.len() == 2\n        && let Some(feature_item) = items[0].meta_item()\n    {\n        // check for `rustfmt`\n        if feature_item.has_name(sym::rustfmt)\n            && msrv.meets(msrvs::TOOL_ATTRIBUTES)\n            // check for `rustfmt_skip` and `rustfmt::skip`\n            && let Some(skip_item) = &items[1].meta_item()\n            && (skip_item.has_name(sym::rustfmt_skip)\n                || skip_item\n                    .path\n                    .segments\n                    .last()\n                    .expect(\"empty path in attribute\")\n                    .ident\n                    .name\n                    == sym::skip)\n            // Only lint outer attributes, because custom inner attributes are unstable\n            // Tracking issue: https://github.com/rust-lang/rust/issues/54726\n            && attr.style == AttrStyle::Outer\n        {\n            span_lint_and_sugg(\n                cx,\n                DEPRECATED_CFG_ATTR,\n                attr.span,\n                \"`cfg_attr` is deprecated for rustfmt and got replaced by tool attributes\",\n                \"use\",\n                \"#[rustfmt::skip]\".to_string(),\n                Applicability::MachineApplicable,\n            );\n        } else {\n            check_deprecated_cfg_recursively(cx, feature_item);\n            if let Some(behind_cfg_attr) = items[1].meta_item() {\n                unnecessary_clippy_cfg::check(cx, feature_item, behind_cfg_attr, attr);\n            }\n        }\n    }\n}\n\npub(super) fn check_clippy(cx: &EarlyContext<'_>, attr: &Attribute) {\n    if attr.has_name(sym::cfg)\n        && let Some(list) = attr.meta_item_list()\n    {\n        for item in list.iter().filter_map(|item| item.meta_item()) {\n            check_deprecated_cfg_recursively(cx, item);\n        }\n    }\n}\n\nfn check_deprecated_cfg_recursively(cx: &EarlyContext<'_>, attr: &rustc_ast::MetaItem) {\n    if let Some(ident) = attr.ident() {\n        if matches!(ident.name, sym::any | sym::all | sym::not) {\n            let Some(list) = attr.meta_item_list() else { return };\n            for item in list.iter().filter_map(|item| item.meta_item()) {\n                check_deprecated_cfg_recursively(cx, item);\n            }\n        } else {\n            check_cargo_clippy_attr(cx, attr);\n        }\n    }\n}\n\nfn check_cargo_clippy_attr(cx: &EarlyContext<'_>, item: &rustc_ast::MetaItem) {\n    if item.has_name(sym::feature) && item.value_str() == Some(sym::cargo_clippy) {\n        span_lint_and_sugg(\n            cx,\n            DEPRECATED_CLIPPY_CFG_ATTR,\n            item.span,\n            \"`feature = \\\"cargo-clippy\\\"` was replaced by `clippy`\",\n            \"replace with\",\n            \"clippy\".to_string(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/deprecated_semver.rs",
    "content": "use super::DEPRECATED_SEMVER;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::sym;\nuse rustc_ast::{LitKind, MetaItemLit};\nuse rustc_hir::VERSION_PLACEHOLDER;\nuse rustc_lint::EarlyContext;\nuse rustc_span::Span;\nuse semver::Version;\n\npub(super) fn check(cx: &EarlyContext<'_>, span: Span, lit: &MetaItemLit) {\n    if let LitKind::Str(is, _) = lit.kind\n        && (is == sym::TBD || is.as_str() == VERSION_PLACEHOLDER || Version::parse(is.as_str()).is_ok())\n    {\n        return;\n    }\n    span_lint(\n        cx,\n        DEPRECATED_SEMVER,\n        span,\n        \"the since field must contain a semver-compliant version\",\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/duplicated_attributes.rs",
    "content": "use super::DUPLICATED_ATTRIBUTES;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse itertools::Itertools;\nuse rustc_ast::{Attribute, MetaItem};\nuse rustc_ast_pretty::pprust::path_to_string;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_lint::EarlyContext;\nuse rustc_span::{Span, Symbol, sym};\nuse std::collections::hash_map::Entry;\n\nfn emit_if_duplicated(\n    cx: &EarlyContext<'_>,\n    attr: &MetaItem,\n    attr_paths: &mut FxHashMap<String, Span>,\n    complete_path: String,\n) {\n    match attr_paths.entry(complete_path) {\n        Entry::Vacant(v) => {\n            v.insert(attr.span);\n        },\n        Entry::Occupied(o) => {\n            span_lint_and_then(cx, DUPLICATED_ATTRIBUTES, attr.span, \"duplicated attribute\", |diag| {\n                diag.span_note(*o.get(), \"first defined here\");\n                diag.span_help(attr.span, \"remove this attribute\");\n            });\n        },\n    }\n}\n\nfn check_duplicated_attr(\n    cx: &EarlyContext<'_>,\n    attr: &MetaItem,\n    attr_paths: &mut FxHashMap<String, Span>,\n    parent: &mut Vec<Symbol>,\n) {\n    if attr.span.from_expansion() {\n        return;\n    }\n    let attr_path = if let Some(ident) = attr.ident() {\n        ident.name\n    } else {\n        Symbol::intern(&path_to_string(&attr.path))\n    };\n    if let Some(ident) = attr.ident() {\n        let name = ident.name;\n        if name == sym::doc || name == sym::cfg_attr_trace || name == sym::rustc_on_unimplemented || name == sym::reason\n        {\n            // FIXME: Would be nice to handle `cfg_attr` as well. Only problem is to check that cfg\n            // conditions are the same.\n            // `#[rustc_on_unimplemented]` contains duplicated subattributes, that's expected.\n            return;\n        }\n        if let Some(direct_parent) = parent.last()\n            && *direct_parent == sym::cfg_trace\n            && [sym::all, sym::not, sym::any].contains(&name)\n        {\n            // FIXME: We don't correctly check `cfg`s for now, so if it's more complex than just a one\n            // level `cfg`, we leave.\n            return;\n        }\n    }\n    if let Some(value) = attr.value_str() {\n        emit_if_duplicated(\n            cx,\n            attr,\n            attr_paths,\n            format!(\"{}:{attr_path}={value}\", parent.iter().join(\":\")),\n        );\n    } else if let Some(sub_attrs) = attr.meta_item_list() {\n        parent.push(attr_path);\n        for sub_attr in sub_attrs {\n            if let Some(meta) = sub_attr.meta_item() {\n                check_duplicated_attr(cx, meta, attr_paths, parent);\n            }\n        }\n        parent.pop();\n    } else {\n        emit_if_duplicated(cx, attr, attr_paths, format!(\"{}:{attr_path}\", parent.iter().join(\":\")));\n    }\n}\n\npub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) {\n    let mut attr_paths = FxHashMap::default();\n\n    for attr in attrs {\n        if let Some(meta) = attr.meta() {\n            check_duplicated_attr(cx, &meta, &mut attr_paths, &mut Vec::new());\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/inline_always.rs",
    "content": "use super::INLINE_ALWAYS;\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_hir::attrs::InlineAttr;\nuse rustc_hir::{Attribute, find_attr};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\nuse rustc_span::symbol::Symbol;\n\npub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {\n    if span.from_expansion() {\n        return;\n    }\n\n    if let Some(span) = find_attr!(attrs, Inline(InlineAttr::Always, span) => *span) {\n        span_lint(\n            cx,\n            INLINE_ALWAYS,\n            span,\n            format!(\"you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea\"),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/mixed_attributes_style.rs",
    "content": "use super::MIXED_ATTRIBUTES_STYLE;\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_ast::{AttrKind, AttrStyle, Attribute};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_lint::{EarlyContext, LintContext};\nuse rustc_span::source_map::SourceMap;\nuse rustc_span::{SourceFile, Span, Symbol};\nuse std::sync::Arc;\n\n#[derive(Hash, PartialEq, Eq)]\nenum SimpleAttrKind {\n    Doc,\n    /// A normal attribute, with its name symbols.\n    Normal(Vec<Symbol>),\n}\n\nimpl From<&AttrKind> for SimpleAttrKind {\n    fn from(value: &AttrKind) -> Self {\n        match value {\n            AttrKind::Normal(attr) => {\n                let path_symbols = attr\n                    .item\n                    .path\n                    .segments\n                    .iter()\n                    .map(|seg| seg.ident.name)\n                    .collect::<Vec<_>>();\n                Self::Normal(path_symbols)\n            },\n            AttrKind::DocComment(..) => Self::Doc,\n        }\n    }\n}\n\npub(super) fn check(cx: &EarlyContext<'_>, item_span: Span, attrs: &[Attribute]) {\n    let mut inner_attr_kind: FxHashSet<SimpleAttrKind> = FxHashSet::default();\n    let mut outer_attr_kind: FxHashSet<SimpleAttrKind> = FxHashSet::default();\n\n    let source_map = cx.sess().source_map();\n    let item_src = source_map.lookup_source_file(item_span.lo());\n\n    for attr in attrs {\n        if attr.span.from_expansion() || !attr_in_same_src_as_item(source_map, &item_src, attr.span) {\n            continue;\n        }\n\n        let kind: SimpleAttrKind = (&attr.kind).into();\n        match attr.style {\n            AttrStyle::Inner => {\n                if outer_attr_kind.contains(&kind) {\n                    lint_mixed_attrs(cx, attrs);\n                    return;\n                }\n                inner_attr_kind.insert(kind);\n            },\n            AttrStyle::Outer => {\n                if inner_attr_kind.contains(&kind) {\n                    lint_mixed_attrs(cx, attrs);\n                    return;\n                }\n                outer_attr_kind.insert(kind);\n            },\n        }\n    }\n}\n\nfn lint_mixed_attrs(cx: &EarlyContext<'_>, attrs: &[Attribute]) {\n    let mut attrs_iter = attrs.iter().filter(|attr| !attr.span.from_expansion());\n    let span = if let (Some(first), Some(last)) = (attrs_iter.next(), attrs_iter.next_back()) {\n        first.span.with_hi(last.span.hi())\n    } else {\n        return;\n    };\n    span_lint(\n        cx,\n        MIXED_ATTRIBUTES_STYLE,\n        span,\n        \"item has both inner and outer attributes\",\n    );\n}\n\nfn attr_in_same_src_as_item(source_map: &SourceMap, item_src: &Arc<SourceFile>, attr_span: Span) -> bool {\n    let attr_src = source_map.lookup_source_file(attr_span.lo());\n    Arc::ptr_eq(item_src, &attr_src)\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/mod.rs",
    "content": "mod allow_attributes;\nmod allow_attributes_without_reason;\nmod blanket_clippy_restriction_lints;\nmod deprecated_cfg_attr;\nmod deprecated_semver;\nmod duplicated_attributes;\nmod inline_always;\nmod mixed_attributes_style;\nmod non_minimal_cfg;\nmod repr_attributes;\nmod should_panic_without_expect;\nmod unnecessary_clippy_cfg;\nmod useless_attribute;\nmod utils;\n\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::msrvs::{self, Msrv, MsrvStack};\nuse rustc_ast::{self as ast, AttrArgs, AttrItemKind, AttrKind, Attribute, MetaItemInner, MetaItemKind};\nuse rustc_hir::{ImplItem, Item, ItemKind, TraitItem};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::sym;\nuse utils::{is_lint_level, is_relevant_impl, is_relevant_item, is_relevant_trait};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of the `#[allow]` attribute and suggests replacing it with\n    /// the `#[expect]` attribute (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html))\n    ///\n    /// This lint only warns outer attributes (`#[allow]`), as inner attributes\n    /// (`#![allow]`) are usually used to enable or disable lints on a global scale.\n    ///\n    /// ### Why is this bad?\n    /// `#[expect]` attributes suppress the lint emission, but emit a warning, if\n    /// the expectation is unfulfilled. This can be useful to be notified when the\n    /// lint is no longer triggered.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// #[allow(unused_mut)]\n    /// fn foo() -> usize {\n    ///     let mut a = Vec::new();\n    ///     a.len()\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// #[expect(unused_mut)]\n    /// fn foo() -> usize {\n    ///     let mut a = Vec::new();\n    ///     a.len()\n    /// }\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub ALLOW_ATTRIBUTES,\n    restriction,\n    \"`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings.\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for attributes that allow lints without a reason.\n    ///\n    /// ### Why restrict this?\n    /// Justifying each `allow` helps readers understand the reasoning,\n    /// and may allow removing `allow` attributes if their purpose is obsolete.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #![allow(clippy::some_lint)]\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #![allow(clippy::some_lint, reason = \"False positive rust-lang/rust-clippy#1002020\")]\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub ALLOW_ATTRIBUTES_WITHOUT_REASON,\n    restriction,\n    \"ensures that all `allow` and `expect` attributes have a reason\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.\n    ///\n    /// ### Why is this bad?\n    /// Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.\n    /// These lints should only be enabled on a lint-by-lint basis and with careful consideration.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #![deny(clippy::restriction)]\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #![deny(clippy::as_conversions)]\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub BLANKET_CLIPPY_RESTRICTION_LINTS,\n    suspicious,\n    \"enabling the complete restriction group\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it\n    /// with `#[rustfmt::skip]`.\n    ///\n    /// ### Why is this bad?\n    /// Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))\n    /// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.\n    ///\n    /// ### Known problems\n    /// This lint doesn't detect crate level inner attributes, because they get\n    /// processed before the PreExpansionPass lints get executed. See\n    /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[cfg_attr(rustfmt, rustfmt_skip)]\n    /// fn main() { }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #[rustfmt::skip]\n    /// fn main() { }\n    /// ```\n    #[clippy::version = \"1.32.0\"]\n    pub DEPRECATED_CFG_ATTR,\n    complexity,\n    \"usage of `cfg_attr(rustfmt)` instead of tool attributes\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `#[cfg_attr(feature = \"cargo-clippy\", ...)]` and for\n    /// `#[cfg(feature = \"cargo-clippy\")]` and suggests to replace it with\n    /// `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`.\n    ///\n    /// ### Why is this bad?\n    /// This feature has been deprecated for years and shouldn't be used anymore.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[cfg(feature = \"cargo-clippy\")]\n    /// struct Bar;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #[cfg(clippy)]\n    /// struct Bar;\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub DEPRECATED_CLIPPY_CFG_ATTR,\n    suspicious,\n    \"usage of `cfg(feature = \\\"cargo-clippy\\\")` instead of `cfg(clippy)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `#[deprecated]` annotations with a `since`\n    /// field that is not a valid semantic version. Also allows \"TBD\" to signal\n    /// future deprecation.\n    ///\n    /// ### Why is this bad?\n    /// For checking the version of the deprecation, it must be\n    /// a valid semver. Failing that, the contained information is useless.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[deprecated(since = \"forever\")]\n    /// fn something_else() { /* ... */ }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DEPRECATED_SEMVER,\n    correctness,\n    \"use of `#[deprecated(since = \\\"x\\\")]` where x is not semver\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for attributes that appear two or more times.\n    ///\n    /// ### Why is this bad?\n    /// Repeating an attribute on the same item (or globally on the same crate)\n    /// is unnecessary and doesn't have an effect.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[allow(dead_code)]\n    /// #[allow(dead_code)]\n    /// fn foo() {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #[allow(dead_code)]\n    /// fn foo() {}\n    /// ```\n    #[clippy::version = \"1.79.0\"]\n    pub DUPLICATED_ATTRIBUTES,\n    suspicious,\n    \"duplicated attribute\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for ignored tests without messages.\n    ///\n    /// ### Why is this bad?\n    /// The reason for ignoring the test may not be obvious.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[test]\n    /// #[ignore]\n    /// fn test() {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[test]\n    /// #[ignore = \"Some good reason\"]\n    /// fn test() {}\n    /// ```\n    ///\n    /// ### Note\n    /// Clippy can only lint compiled code. For this lint to trigger, you must configure `cargo clippy`\n    /// to include test compilation, for instance, by using flags such as `--tests` or `--all-targets`.\n    #[clippy::version = \"1.88.0\"]\n    pub IGNORE_WITHOUT_REASON,\n    pedantic,\n    \"ignored tests without messages\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for items annotated with `#[inline(always)]`,\n    /// unless the annotated function is empty or simply panics.\n    ///\n    /// ### Why is this bad?\n    /// While there are valid uses of this annotation (and once\n    /// you know when to use it, by all means `allow` this lint), it's a common\n    /// newbie-mistake to pepper one's code with it.\n    ///\n    /// As a rule of thumb, before slapping `#[inline(always)]` on a function,\n    /// measure if that additional function call really affects your runtime profile\n    /// sufficiently to make up for the increase in compile time.\n    ///\n    /// ### Known problems\n    /// False positives, big time. This lint is meant to be\n    /// deactivated by everyone doing serious performance work. This means having\n    /// done the measurement.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// #[inline(always)]\n    /// fn not_quite_hot_code(..) { ... }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INLINE_ALWAYS,\n    pedantic,\n    \"use of `#[inline(always)]`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for items that have the same kind of attributes with mixed styles (inner/outer).\n    ///\n    /// ### Why is this bad?\n    /// Having both style of said attributes makes it more complicated to read code.\n    ///\n    /// ### Known problems\n    /// This lint currently has false-negatives when mixing same attributes\n    /// but they have different path symbols, for example:\n    /// ```ignore\n    /// #[custom_attribute]\n    /// pub fn foo() {\n    ///     #![my_crate::custom_attribute]\n    /// }\n    /// ```\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[cfg(linux)]\n    /// pub fn foo() {\n    ///     #![cfg(windows)]\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[cfg(linux)]\n    /// #[cfg(windows)]\n    /// pub fn foo() {\n    /// }\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub MIXED_ATTRIBUTES_STYLE,\n    style,\n    \"item has both inner and outer attributes\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `any` and `all` combinators in `cfg` with only one condition.\n    ///\n    /// ### Why is this bad?\n    /// If there is only one condition, no need to wrap it into `any` or `all` combinators.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[cfg(any(unix))]\n    /// pub struct Bar;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #[cfg(unix)]\n    /// pub struct Bar;\n    /// ```\n    #[clippy::version = \"1.71.0\"]\n    pub NON_MINIMAL_CFG,\n    style,\n    \"ensure that all `cfg(any())` and `cfg(all())` have more than one condition\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for items with `#[repr(packed)]`-attribute without ABI qualification\n    ///\n    /// ### Why is this bad?\n    /// Without qualification, `repr(packed)` implies `repr(Rust)`. The Rust-ABI is inherently unstable.\n    /// While this is fine as long as the type is accessed correctly within Rust-code, most uses\n    /// of `#[repr(packed)]` involve FFI and/or data structures specified by network-protocols or\n    /// other external specifications. In such situations, the unstable Rust-ABI implied in\n    /// `#[repr(packed)]` may lead to future bugs should the Rust-ABI change.\n    ///\n    /// In case you are relying on a well defined and stable memory layout, qualify the type's\n    /// representation using the `C`-ABI. Otherwise, if the type in question is only ever\n    /// accessed from Rust-code according to Rust's rules, use the `Rust`-ABI explicitly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[repr(packed)]\n    /// struct NetworkPacketHeader {\n    ///     header_length: u8,\n    ///     header_version: u16\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #[repr(C, packed)]\n    /// struct NetworkPacketHeader {\n    ///     header_length: u8,\n    ///     header_version: u16\n    /// }\n    /// ```\n    #[clippy::version = \"1.85.0\"]\n    pub REPR_PACKED_WITHOUT_ABI,\n    suspicious,\n    \"ensures that `repr(packed)` always comes with a qualified ABI\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `#[should_panic]` attributes without specifying the expected panic message.\n    ///\n    /// ### Why is this bad?\n    /// The expected panic message should be specified to ensure that the test is actually\n    /// panicking with the expected message, and not another unrelated panic.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn random() -> i32 { 0 }\n    ///\n    /// #[should_panic]\n    /// #[test]\n    /// fn my_test() {\n    ///     let _ = 1 / random();\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn random() -> i32 { 0 }\n    ///\n    /// #[should_panic = \"attempt to divide by zero\"]\n    /// #[test]\n    /// fn my_test() {\n    ///     let _ = 1 / random();\n    /// }\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub SHOULD_PANIC_WITHOUT_EXPECT,\n    pedantic,\n    \"ensures that all `should_panic` attributes specify its expected panic message\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `#[cfg_attr(clippy, allow(clippy::lint))]`\n    /// and suggests to replace it with `#[allow(clippy::lint)]`.\n    ///\n    /// ### Why is this bad?\n    /// There is no reason to put clippy attributes behind a clippy `cfg` as they are not\n    /// run by anything else than clippy.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #![cfg_attr(clippy, allow(clippy::deprecated_cfg_attr))]\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #![allow(clippy::deprecated_cfg_attr)]\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub UNNECESSARY_CLIPPY_CFG,\n    suspicious,\n    \"usage of `cfg_attr(clippy, allow(clippy::lint))` instead of `allow(clippy::lint)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `extern crate` and `use` items annotated with\n    /// lint attributes.\n    ///\n    /// This lint permits lint attributes for lints emitted on the items themself.\n    /// For `use` items these lints are:\n    /// * ambiguous_glob_reexports\n    /// * dead_code\n    /// * deprecated\n    /// * hidden_glob_reexports\n    /// * unreachable_pub\n    /// * unused\n    /// * unused_braces\n    /// * unused_import_braces\n    /// * clippy::disallowed_types\n    /// * clippy::enum_glob_use\n    /// * clippy::macro_use_imports\n    /// * clippy::module_name_repetitions\n    /// * clippy::redundant_pub_crate\n    /// * clippy::single_component_path_imports\n    /// * clippy::unsafe_removed_from_name\n    /// * clippy::wildcard_imports\n    ///\n    /// For `extern crate` items these lints are:\n    /// * `unused_imports` on items with `#[macro_use]`\n    ///\n    /// ### Why is this bad?\n    /// Lint attributes have no effect on crate imports. Most\n    /// likely a `!` was forgotten.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// #[deny(dead_code)]\n    /// extern crate foo;\n    /// #[forbid(dead_code)]\n    /// use foo::bar;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// #[allow(unused_imports)]\n    /// use foo::baz;\n    /// #[allow(unused_imports)]\n    /// #[macro_use]\n    /// extern crate baz;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USELESS_ATTRIBUTE,\n    correctness,\n    \"use of lint attributes on `extern crate` items\"\n}\n\nimpl_lint_pass!(Attributes => [INLINE_ALWAYS, REPR_PACKED_WITHOUT_ABI]);\n\nimpl_lint_pass!(EarlyAttributes => [\n    DEPRECATED_CFG_ATTR,\n    DEPRECATED_CLIPPY_CFG_ATTR,\n    NON_MINIMAL_CFG,\n    UNNECESSARY_CLIPPY_CFG,\n]);\n\nimpl_lint_pass!(PostExpansionEarlyAttributes => [\n    ALLOW_ATTRIBUTES,\n    ALLOW_ATTRIBUTES_WITHOUT_REASON,\n    BLANKET_CLIPPY_RESTRICTION_LINTS,\n    DEPRECATED_SEMVER,\n    DUPLICATED_ATTRIBUTES,\n    IGNORE_WITHOUT_REASON,\n    MIXED_ATTRIBUTES_STYLE,\n    SHOULD_PANIC_WITHOUT_EXPECT,\n    USELESS_ATTRIBUTE,\n]);\n\npub struct Attributes {\n    msrv: Msrv,\n}\n\nimpl Attributes {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Attributes {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        let attrs = cx.tcx.hir_attrs(item.hir_id());\n        if let ItemKind::Fn { ident, .. } = item.kind\n            && is_relevant_item(cx, item)\n        {\n            inline_always::check(cx, item.span, ident.name, attrs);\n        }\n        repr_attributes::check(cx, item.span, attrs, self.msrv);\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {\n        if is_relevant_impl(cx, item) {\n            inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id()));\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {\n        if is_relevant_trait(cx, item) {\n            inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir_attrs(item.hir_id()));\n        }\n    }\n}\n\npub struct EarlyAttributes {\n    msrv: MsrvStack,\n}\n\nimpl EarlyAttributes {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: MsrvStack::new(conf.msrv),\n        }\n    }\n}\n\nimpl EarlyLintPass for EarlyAttributes {\n    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {\n        deprecated_cfg_attr::check(cx, attr, &self.msrv);\n        deprecated_cfg_attr::check_clippy(cx, attr);\n        non_minimal_cfg::check(cx, attr);\n    }\n\n    extract_msrv_attr!();\n}\n\npub struct PostExpansionEarlyAttributes {\n    msrv: MsrvStack,\n}\n\nimpl PostExpansionEarlyAttributes {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: MsrvStack::new(conf.msrv),\n        }\n    }\n}\n\nimpl EarlyLintPass for PostExpansionEarlyAttributes {\n    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &ast::Crate) {\n        blanket_clippy_restriction_lints::check_command_line(cx);\n        duplicated_attributes::check(cx, &krate.attrs);\n    }\n\n    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {\n        if let Some(items) = &attr.meta_item_list()\n            && let Some(name) = attr.name()\n        {\n            if matches!(name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {\n                allow_attributes::check(cx, attr);\n            }\n            if matches!(name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {\n                allow_attributes_without_reason::check(cx, name, items, attr);\n            }\n            if is_lint_level(name, attr.id) {\n                blanket_clippy_restriction_lints::check(cx, name, items);\n            }\n            if items.is_empty() || !attr.has_name(sym::deprecated) {\n                return;\n            }\n            for item in items {\n                if let MetaItemInner::MetaItem(mi) = &item\n                    && let MetaItemKind::NameValue(lit) = &mi.kind\n                    && mi.has_name(sym::since)\n                {\n                    deprecated_semver::check(cx, item.span(), lit);\n                }\n            }\n        }\n\n        if attr.has_name(sym::should_panic) {\n            should_panic_without_expect::check(cx, attr);\n        }\n\n        if attr.has_name(sym::ignore)\n            && match &attr.kind {\n                AttrKind::Normal(normal_attr) => {\n                    !matches!(normal_attr.item.args, AttrItemKind::Unparsed(AttrArgs::Eq { .. }))\n                },\n                AttrKind::DocComment(..) => true,\n            }\n        {\n            span_lint_and_help(\n                cx,\n                IGNORE_WITHOUT_REASON,\n                attr.span,\n                \"`#[ignore]` without reason\",\n                None,\n                \"add a reason with `= \\\"..\\\"`\",\n            );\n        }\n    }\n\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &'_ ast::Item) {\n        match item.kind {\n            ast::ItemKind::ExternCrate(..) | ast::ItemKind::Use(..) => useless_attribute::check(cx, item, &item.attrs),\n            _ => {},\n        }\n\n        mixed_attributes_style::check(cx, item.span, &item.attrs);\n        duplicated_attributes::check(cx, &item.attrs);\n    }\n\n    extract_msrv_attr!();\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/non_minimal_cfg.rs",
    "content": "use super::{Attribute, NON_MINIMAL_CFG};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_ast::{MetaItemInner, MetaItemKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::EarlyContext;\nuse rustc_span::sym;\n\npub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {\n    if attr.has_name(sym::cfg)\n        && let Some(items) = attr.meta_item_list()\n    {\n        check_nested_cfg(cx, &items);\n    }\n}\n\nfn check_nested_cfg(cx: &EarlyContext<'_>, items: &[MetaItemInner]) {\n    for item in items {\n        if let MetaItemInner::MetaItem(meta) = item {\n            if !meta.has_name(sym::any) && !meta.has_name(sym::all) {\n                continue;\n            }\n            if let MetaItemKind::List(list) = &meta.kind {\n                check_nested_cfg(cx, list);\n                if list.len() == 1 {\n                    span_lint_and_then(\n                        cx,\n                        NON_MINIMAL_CFG,\n                        meta.span,\n                        \"unneeded sub `cfg` when there is only one condition\",\n                        |diag| {\n                            if let Some(snippet) = list[0].span().get_source_text(cx) {\n                                diag.span_suggestion(\n                                    meta.span,\n                                    \"try\",\n                                    snippet.to_owned(),\n                                    Applicability::MaybeIncorrect,\n                                );\n                            }\n                        },\n                    );\n                } else if list.is_empty() && meta.has_name(sym::all) {\n                    span_lint_and_then(\n                        cx,\n                        NON_MINIMAL_CFG,\n                        meta.span,\n                        \"unneeded sub `cfg` when there is no condition\",\n                        |_| {},\n                    );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/repr_attributes.rs",
    "content": "use rustc_hir::attrs::ReprAttr;\nuse rustc_hir::{Attribute, find_attr};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\n\nuse super::REPR_PACKED_WITHOUT_ABI;\n\npub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute], msrv: Msrv) {\n    if let Some(reprs) = find_attr!(attrs, Repr { reprs, .. } => reprs) {\n        let packed_span = reprs\n            .iter()\n            .find(|(r, _)| matches!(r, ReprAttr::ReprPacked(..)))\n            .map(|(_, s)| *s);\n\n        if let Some(packed_span) = packed_span\n            && !reprs\n                .iter()\n                .any(|(x, _)| *x == ReprAttr::ReprC || *x == ReprAttr::ReprRust)\n            && msrv.meets(cx, msrvs::REPR_RUST)\n        {\n            span_lint_and_then(\n                cx,\n                REPR_PACKED_WITHOUT_ABI,\n                item_span,\n                \"item uses `packed` representation without ABI-qualification\",\n                |diag| {\n                    diag.warn(\n                        \"unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI\",\n                    )\n                    .help(\"qualify the desired ABI explicitly via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`\")\n                    .span_label(packed_span, \"`packed` representation set here\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/should_panic_without_expect.rs",
    "content": "use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse rustc_ast::token::{Token, TokenKind};\nuse rustc_ast::tokenstream::TokenTree;\nuse rustc_ast::{AttrArgs, AttrItemKind, AttrKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::EarlyContext;\nuse rustc_span::sym;\n\npub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {\n    if let AttrKind::Normal(normal_attr) = &attr.kind {\n        if let AttrItemKind::Unparsed(AttrArgs::Eq { .. }) = &normal_attr.item.args {\n            // `#[should_panic = \"..\"]` found, good\n            return;\n        }\n\n        if let AttrItemKind::Unparsed(AttrArgs::Delimited(args)) = &normal_attr.item.args\n            && let mut tt_iter = args.tokens.iter()\n            && let Some(TokenTree::Token(\n                Token {\n                    kind: TokenKind::Ident(sym::expected, _),\n                    ..\n                },\n                _,\n            )) = tt_iter.next()\n            && let Some(TokenTree::Token(\n                Token {\n                    kind: TokenKind::Eq, ..\n                },\n                _,\n            )) = tt_iter.next()\n            && let Some(TokenTree::Token(\n                Token {\n                    kind: TokenKind::Literal(_),\n                    ..\n                },\n                _,\n            )) = tt_iter.next()\n        {\n            // `#[should_panic(expected = \"..\")]` found, good\n            return;\n        }\n\n        span_lint_and_sugg(\n            cx,\n            SHOULD_PANIC_WITHOUT_EXPECT,\n            attr.span,\n            \"#[should_panic] attribute without a reason\",\n            \"consider specifying the expected panic\",\n            \"#[should_panic(expected = /* panic message */)]\".into(),\n            Applicability::HasPlaceholders,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/unnecessary_clippy_cfg.rs",
    "content": "use super::{Attribute, UNNECESSARY_CLIPPY_CFG};\nuse clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};\nuse clippy_utils::source::SpanRangeExt;\nuse itertools::Itertools;\nuse rustc_ast::AttrStyle;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, Level};\nuse rustc_span::sym;\n\npub(super) fn check(\n    cx: &EarlyContext<'_>,\n    cfg_attr: &rustc_ast::MetaItem,\n    behind_cfg_attr: &rustc_ast::MetaItem,\n    attr: &Attribute,\n) {\n    if cfg_attr.has_name(sym::clippy)\n        && let Some(ident) = behind_cfg_attr.ident()\n        && Level::from_symbol(ident.name, || Some(attr.id)).is_some()\n        && let Some(items) = behind_cfg_attr.meta_item_list()\n    {\n        let nb_items = items.len();\n        let mut clippy_lints = Vec::with_capacity(items.len());\n        for item in items {\n            if let Some(meta_item) = item.meta_item()\n                && let [part1, _] = meta_item.path.segments.as_slice()\n                && part1.ident.name == sym::clippy\n            {\n                clippy_lints.push(item.span());\n            }\n        }\n        if clippy_lints.is_empty() {\n            return;\n        }\n        if nb_items == clippy_lints.len() {\n            if let Some(snippet) = behind_cfg_attr.span.get_source_text(cx) {\n                span_lint_and_sugg(\n                    cx,\n                    UNNECESSARY_CLIPPY_CFG,\n                    attr.span,\n                    \"no need to put clippy lints behind a `clippy` cfg\",\n                    \"replace with\",\n                    format!(\n                        \"#{}[{}]\",\n                        if attr.style == AttrStyle::Inner { \"!\" } else { \"\" },\n                        snippet\n                    ),\n                    Applicability::MachineApplicable,\n                );\n            }\n        } else {\n            let snippet = clippy_lints.iter().filter_map(|sp| sp.get_source_text(cx)).join(\",\");\n            span_lint_and_note(\n                cx,\n                UNNECESSARY_CLIPPY_CFG,\n                clippy_lints,\n                \"no need to put clippy lints behind a `clippy` cfg\",\n                None,\n                format!(\n                    \"write instead: `#{}[{}({})]`\",\n                    if attr.style == AttrStyle::Inner { \"!\" } else { \"\" },\n                    ident.name,\n                    snippet\n                ),\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/useless_attribute.rs",
    "content": "use super::USELESS_ATTRIBUTE;\nuse super::utils::{is_lint_level, is_word, namespace_and_lint};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{SpanRangeExt, first_line_of_span};\nuse clippy_utils::sym;\nuse rustc_ast::{Attribute, Item, ItemKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, LintContext};\n\npub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {\n    let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));\n\n    for attr in attrs {\n        if attr.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n        if let Some(lint_list) = &attr.meta_item_list()\n            && attr.name().is_some_and(|name| is_lint_level(name, attr.id))\n        {\n            for lint in lint_list {\n                match item.kind {\n                    ItemKind::Use(..) => {\n                        let (namespace @ (Some(sym::clippy) | None), Some(name)) = namespace_and_lint(lint) else {\n                            return;\n                        };\n\n                        if namespace.is_none()\n                            && matches!(\n                                name,\n                                sym::ambiguous_glob_reexports\n                                    | sym::dead_code\n                                    | sym::deprecated\n                                    | sym::deprecated_in_future\n                                    | sym::exported_private_dependencies\n                                    | sym::hidden_glob_reexports\n                                    | sym::unreachable_pub\n                                    | sym::unused\n                                    | sym::unused_braces\n                                    | sym::unused_import_braces\n                                    | sym::unused_imports\n                                    | sym::redundant_imports\n                            )\n                        {\n                            return;\n                        }\n\n                        if namespace == Some(sym::clippy)\n                            && matches!(\n                                name,\n                                sym::wildcard_imports\n                                    | sym::enum_glob_use\n                                    | sym::redundant_pub_crate\n                                    | sym::macro_use_imports\n                                    | sym::unsafe_removed_from_name\n                                    | sym::module_name_repetitions\n                                    | sym::single_component_path_imports\n                                    | sym::disallowed_types\n                                    | sym::unused_trait_names\n                            )\n                        {\n                            return;\n                        }\n                    },\n                    ItemKind::ExternCrate(..) => {\n                        if is_word(lint, sym::unused_imports) && skip_unused_imports {\n                            return;\n                        }\n                        if is_word(lint, sym::unused_extern_crates) {\n                            return;\n                        }\n                    },\n                    _ => {},\n                }\n            }\n            let line_span = first_line_of_span(cx, attr.span);\n\n            if let Some(src) = line_span.get_source_text(cx)\n                && src.contains(\"#[\")\n            {\n                #[expect(clippy::collapsible_span_lint_calls)]\n                span_lint_and_then(cx, USELESS_ATTRIBUTE, line_span, \"useless lint attribute\", |diag| {\n                    diag.span_suggestion(\n                        line_span,\n                        \"if you just forgot a `!`, use\",\n                        src.replacen(\"#[\", \"#![\", 1),\n                        Applicability::MaybeIncorrect,\n                    );\n                });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/attrs/utils.rs",
    "content": "use clippy_utils::macros::{is_panic, macro_backtrace};\nuse rustc_ast::{AttrId, MetaItemInner};\nuse rustc_hir::{\n    Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,\n};\nuse rustc_lint::{LateContext, Level};\nuse rustc_middle::ty;\nuse rustc_span::sym;\nuse rustc_span::symbol::Symbol;\n\npub(super) fn is_word(nmi: &MetaItemInner, expected: Symbol) -> bool {\n    if let MetaItemInner::MetaItem(mi) = &nmi {\n        mi.is_word() && mi.has_name(expected)\n    } else {\n        false\n    }\n}\n\npub(super) fn is_lint_level(symbol: Symbol, attr_id: AttrId) -> bool {\n    Level::from_symbol(symbol, || Some(attr_id)).is_some()\n}\n\npub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {\n    if let ItemKind::Fn { body: eid, .. } = item.kind {\n        is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value)\n    } else {\n        false\n    }\n}\n\npub(super) fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool {\n    match item.kind {\n        ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value),\n        _ => false,\n    }\n}\n\npub(super) fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool {\n    match item.kind {\n        TraitItemKind::Fn(_, TraitFn::Required(_)) => true,\n        TraitItemKind::Fn(_, TraitFn::Provided(eid)) => {\n            is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir_body(eid).value)\n        },\n        _ => false,\n    }\n}\n\nfn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, block: &Block<'_>) -> bool {\n    block.stmts.first().map_or_else(\n        || {\n            block\n                .expr\n                .as_ref()\n                .is_some_and(|e| is_relevant_expr(cx, typeck_results, e))\n        },\n        |stmt| match &stmt.kind {\n            StmtKind::Let(_) => true,\n            StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),\n            StmtKind::Item(_) => false,\n        },\n    )\n}\n\nfn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, expr: &Expr<'_>) -> bool {\n    if macro_backtrace(expr.span).last().is_some_and(|macro_call| {\n        is_panic(cx, macro_call.def_id) || cx.tcx.item_name(macro_call.def_id) == sym::unreachable\n    }) {\n        return false;\n    }\n    match &expr.kind {\n        ExprKind::Block(block, _) => is_relevant_block(cx, typeck_results, block),\n        ExprKind::Ret(Some(e)) => is_relevant_expr(cx, typeck_results, e),\n        ExprKind::Ret(None) | ExprKind::Break(_, None) => false,\n        _ => true,\n    }\n}\n\n/// Returns the lint name if it is clippy lint.\npub(super) fn extract_clippy_lint(lint: &MetaItemInner) -> Option<Symbol> {\n    match namespace_and_lint(lint) {\n        (Some(sym::clippy), name) => name,\n        _ => None,\n    }\n}\n\n/// Returns the lint namespace, if any, as well as the lint name. (`None`, `None`) means\n/// the lint had less than 1 or more than 2 segments.\npub(super) fn namespace_and_lint(lint: &MetaItemInner) -> (Option<Symbol>, Option<Symbol>) {\n    match lint.meta_item().map(|m| m.path.segments.as_slice()).unwrap_or_default() {\n        [name] => (None, Some(name.ident.name)),\n        [namespace, name] => (Some(namespace.ident.name), Some(name.ident.name)),\n        _ => (None, None),\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/await_holding_invalid.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::{DisallowedPathWithoutReplacement, create_disallowed_map};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::paths::{self, PathNS};\nuse clippy_utils::sym;\nuse rustc_hir as hir;\nuse rustc_hir::def_id::{DefId, DefIdMap};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir::CoroutineLayout;\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Allows users to configure types which should not be held across await\n    /// suspension points.\n    ///\n    /// ### Why is this bad?\n    /// There are some types which are perfectly safe to use concurrently from\n    /// a memory access perspective, but that will cause bugs at runtime if\n    /// they are held in such a way.\n    ///\n    /// ### Example\n    ///\n    /// ```toml\n    /// await-holding-invalid-types = [\n    ///   # You can specify a type name\n    ///   \"CustomLockType\",\n    ///   # You can (optionally) specify a reason\n    ///   { path = \"OtherCustomLockType\", reason = \"Relies on a thread local\" }\n    /// ]\n    /// ```\n    ///\n    /// ```no_run\n    /// # async fn baz() {}\n    /// struct CustomLockType;\n    /// struct OtherCustomLockType;\n    /// async fn foo() {\n    ///   let _x = CustomLockType;\n    ///   let _y = OtherCustomLockType;\n    ///   baz().await; // Lint violation\n    /// }\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub AWAIT_HOLDING_INVALID_TYPE,\n    suspicious,\n    \"holding a type across an await point which is not allowed to be held as per the configuration\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `await` while holding a non-async-aware\n    /// `MutexGuard`.\n    ///\n    /// ### Why is this bad?\n    /// The Mutex types found in [`std::sync`](https://doc.rust-lang.org/stable/std/sync/) and\n    /// [`parking_lot`](https://docs.rs/parking_lot/latest/parking_lot/) are\n    /// not designed to operate in an async context across await points.\n    ///\n    /// There are two potential solutions. One is to use an async-aware `Mutex`\n    /// type. Many asynchronous foundation crates provide such a `Mutex` type.\n    /// The other solution is to ensure the mutex is unlocked before calling\n    /// `await`, either by introducing a scope or an explicit call to\n    /// [`Drop::drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html).\n    ///\n    /// ### Known problems\n    /// Will report false positive for explicitly dropped guards\n    /// ([#6446](https://github.com/rust-lang/rust-clippy/issues/6446)). A\n    /// workaround for this is to wrap the `.lock()` call in a block instead of\n    /// explicitly dropping the guard.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::sync::Mutex;\n    /// # async fn baz() {}\n    /// async fn foo(x: &Mutex<u32>) {\n    ///   let mut guard = x.lock().unwrap();\n    ///   *guard += 1;\n    ///   baz().await;\n    /// }\n    ///\n    /// async fn bar(x: &Mutex<u32>) {\n    ///   let mut guard = x.lock().unwrap();\n    ///   *guard += 1;\n    ///   drop(guard); // explicit drop\n    ///   baz().await;\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::sync::Mutex;\n    /// # async fn baz() {}\n    /// async fn foo(x: &Mutex<u32>) {\n    ///   {\n    ///     let mut guard = x.lock().unwrap();\n    ///     *guard += 1;\n    ///   }\n    ///   baz().await;\n    /// }\n    ///\n    /// async fn bar(x: &Mutex<u32>) {\n    ///   {\n    ///     let mut guard = x.lock().unwrap();\n    ///     *guard += 1;\n    ///   } // guard dropped here at end of scope\n    ///   baz().await;\n    /// }\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub AWAIT_HOLDING_LOCK,\n    suspicious,\n    \"inside an async function, holding a `MutexGuard` while calling `await`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `await` while holding a `RefCell`, `Ref`, or `RefMut`.\n    ///\n    /// ### Why is this bad?\n    /// `RefCell` refs only check for exclusive mutable access\n    /// at runtime. Holding a `RefCell` ref across an await suspension point\n    /// risks panics from a mutable ref shared while other refs are outstanding.\n    ///\n    /// ### Known problems\n    /// Will report false positive for explicitly dropped refs\n    /// ([#6353](https://github.com/rust-lang/rust-clippy/issues/6353)). A workaround for this is\n    /// to wrap the `.borrow[_mut]()` call in a block instead of explicitly dropping the ref.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::cell::RefCell;\n    /// # async fn baz() {}\n    /// async fn foo(x: &RefCell<u32>) {\n    ///   let mut y = x.borrow_mut();\n    ///   *y += 1;\n    ///   baz().await;\n    /// }\n    ///\n    /// async fn bar(x: &RefCell<u32>) {\n    ///   let mut y = x.borrow_mut();\n    ///   *y += 1;\n    ///   drop(y); // explicit drop\n    ///   baz().await;\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::cell::RefCell;\n    /// # async fn baz() {}\n    /// async fn foo(x: &RefCell<u32>) {\n    ///   {\n    ///      let mut y = x.borrow_mut();\n    ///      *y += 1;\n    ///   }\n    ///   baz().await;\n    /// }\n    ///\n    /// async fn bar(x: &RefCell<u32>) {\n    ///   {\n    ///     let mut y = x.borrow_mut();\n    ///     *y += 1;\n    ///   } // y dropped here at end of scope\n    ///   baz().await;\n    /// }\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub AWAIT_HOLDING_REFCELL_REF,\n    suspicious,\n    \"inside an async function, holding a `RefCell` ref while calling `await`\"\n}\n\nimpl_lint_pass!(AwaitHolding => [\n    AWAIT_HOLDING_INVALID_TYPE,\n    AWAIT_HOLDING_LOCK,\n    AWAIT_HOLDING_REFCELL_REF,\n]);\n\npub struct AwaitHolding {\n    def_ids: DefIdMap<(&'static str, &'static DisallowedPathWithoutReplacement)>,\n}\n\nimpl AwaitHolding {\n    pub(crate) fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        let (def_ids, _) = create_disallowed_map(\n            tcx,\n            &conf.await_holding_invalid_types,\n            PathNS::Type,\n            crate::disallowed_types::def_kind_predicate,\n            \"type\",\n            false,\n        );\n        Self { def_ids }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for AwaitHolding {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {\n        if let hir::ExprKind::Closure(hir::Closure {\n            kind: hir::ClosureKind::Coroutine(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)),\n            def_id,\n            ..\n        }) = expr.kind\n            && let Some(coroutine_layout) = cx.tcx.mir_coroutine_witnesses(*def_id)\n        {\n            self.check_interior_types(cx, coroutine_layout);\n        }\n    }\n}\n\nimpl AwaitHolding {\n    fn check_interior_types(&self, cx: &LateContext<'_>, coroutine: &CoroutineLayout<'_>) {\n        for (ty_index, ty_cause) in coroutine.field_tys.iter_enumerated() {\n            if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {\n                let await_points = || {\n                    coroutine\n                        .variant_source_info\n                        .iter_enumerated()\n                        .filter_map(|(variant, source_info)| {\n                            coroutine.variant_fields[variant]\n                                .raw\n                                .contains(&ty_index)\n                                .then_some(source_info.span)\n                        })\n                        .collect::<Vec<_>>()\n                };\n                if is_mutex_guard(cx, adt.did()) {\n                    span_lint_and_then(\n                        cx,\n                        AWAIT_HOLDING_LOCK,\n                        ty_cause.source_info.span,\n                        \"this `MutexGuard` is held across an await point\",\n                        |diag| {\n                            diag.help(\n                                \"consider using an async-aware `Mutex` type or ensuring the \\\n                                `MutexGuard` is dropped before calling `await`\",\n                            );\n                            diag.span_note(\n                                await_points(),\n                                \"these are all the await points this lock is held through\",\n                            );\n                        },\n                    );\n                } else if is_refcell_ref(cx, adt.did()) {\n                    span_lint_and_then(\n                        cx,\n                        AWAIT_HOLDING_REFCELL_REF,\n                        ty_cause.source_info.span,\n                        \"this `RefCell` reference is held across an await point\",\n                        |diag| {\n                            diag.help(\"ensure the reference is dropped before calling `await`\");\n                            diag.span_note(\n                                await_points(),\n                                \"these are all the await points this reference is held through\",\n                            );\n                        },\n                    );\n                } else if let Some(&(path, disallowed_path)) = self.def_ids.get(&adt.did()) {\n                    emit_invalid_type(cx, ty_cause.source_info.span, path, disallowed_path);\n                }\n            }\n        }\n    }\n}\n\nfn emit_invalid_type(\n    cx: &LateContext<'_>,\n    span: Span,\n    path: &'static str,\n    disallowed_path: &'static DisallowedPathWithoutReplacement,\n) {\n    span_lint_and_then(\n        cx,\n        AWAIT_HOLDING_INVALID_TYPE,\n        span,\n        format!(\"holding a disallowed type across an await point `{path}`\"),\n        disallowed_path.diag_amendment(span),\n    );\n}\n\nfn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {\n    match cx.tcx.get_diagnostic_name(def_id) {\n        Some(name) => matches!(name, sym::MutexGuard | sym::RwLockReadGuard | sym::RwLockWriteGuard),\n        None => paths::PARKING_LOT_GUARDS.iter().any(|guard| guard.matches(cx, def_id)),\n    }\n}\n\nfn is_refcell_ref(cx: &LateContext<'_>, def_id: DefId) -> bool {\n    matches!(\n        cx.tcx.get_diagnostic_name(def_id),\n        Some(sym::RefCellRef | sym::RefCellRefMut)\n    )\n}\n"
  },
  {
    "path": "clippy_lints/src/blocks_in_conditions.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_block_with_applicability;\nuse clippy_utils::{contains_return, higher, is_from_proc_macro};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `if` and `match` conditions that use blocks containing an\n    /// expression, statements or conditions that use closures with blocks.\n    ///\n    /// ### Why is this bad?\n    /// Style, using blocks in the condition makes it hard to read.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// # fn somefunc() -> bool { true };\n    /// if { true } { /* ... */ }\n    ///\n    /// if { let x = somefunc(); x } { /* ... */ }\n    ///\n    /// match { let e = somefunc(); e } {\n    ///     // ...\n    /// #   _ => {}\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # fn somefunc() -> bool { true };\n    /// if true { /* ... */ }\n    ///\n    /// let res = { let x = somefunc(); x };\n    /// if res { /* ... */ }\n    ///\n    /// let res = { let e = somefunc(); e };\n    /// match res {\n    ///     // ...\n    /// #   _ => {}\n    /// }\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub BLOCKS_IN_CONDITIONS,\n    style,\n    \"useless or complex blocks that can be eliminated in conditions\"\n}\n\ndeclare_lint_pass!(BlocksInConditions => [BLOCKS_IN_CONDITIONS]);\n\nconst BRACED_EXPR_MESSAGE: &str = \"omit braces around single expression condition\";\n\nimpl<'tcx> LateLintPass<'tcx> for BlocksInConditions {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if expr.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        let Some((cond, keyword, desc)) = higher::If::hir(expr)\n            .map(|hif| (hif.cond, \"if\", \"an `if` condition\"))\n            .or(if let ExprKind::Match(match_ex, _, MatchSource::Normal) = expr.kind {\n                Some((match_ex, \"match\", \"a `match` scrutinee\"))\n            } else {\n                None\n            })\n        else {\n            return;\n        };\n        let complex_block_message = format!(\n            \"in {desc}, avoid complex blocks or closures with blocks; \\\n            instead, move the block or closure higher and bind it with a `let`\",\n        );\n\n        if let ExprKind::Block(block, _) = &cond.kind {\n            if !block.span.eq_ctxt(expr.span) {\n                // If the block comes from a macro, or as an argument to a macro,\n                // do not lint.\n                return;\n            }\n            if block.rules == BlockCheckMode::DefaultBlock {\n                if block.stmts.is_empty() {\n                    if let Some(ex) = &block.expr {\n                        // don't dig into the expression here, just suggest that they remove\n                        // the block\n                        if expr.span.from_expansion() || ex.span.from_expansion() {\n                            return;\n                        }\n\n                        // Linting should not be triggered to cases where `return` is included in the condition.\n                        // #9911\n                        if contains_return(block.expr) {\n                            return;\n                        }\n\n                        let mut applicability = Applicability::MachineApplicable;\n                        span_lint_and_sugg(\n                            cx,\n                            BLOCKS_IN_CONDITIONS,\n                            cond.span,\n                            BRACED_EXPR_MESSAGE,\n                            \"try\",\n                            snippet_block_with_applicability(cx, ex.span, \"..\", Some(expr.span), &mut applicability),\n                            applicability,\n                        );\n                    }\n                } else {\n                    let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);\n                    if span.from_expansion() || expr.span.from_expansion() || is_from_proc_macro(cx, cond) {\n                        return;\n                    }\n                    // move block higher\n                    let mut applicability = Applicability::MachineApplicable;\n                    span_lint_and_sugg(\n                        cx,\n                        BLOCKS_IN_CONDITIONS,\n                        expr.span.with_hi(cond.span.hi()),\n                        complex_block_message,\n                        \"try\",\n                        format!(\n                            \"let res = {}; {keyword} res\",\n                            snippet_block_with_applicability(cx, block.span, \"..\", Some(expr.span), &mut applicability),\n                        ),\n                        applicability,\n                    );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/bool_assert_comparison.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node};\nuse clippy_utils::source::walk_span_to_context;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::sym;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Lit};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::Ident;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns about boolean comparisons in assert-like macros.\n    ///\n    /// ### Why is this bad?\n    /// It is shorter to use the equivalent.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// assert_eq!(\"a\".is_empty(), false);\n    /// assert_ne!(\"a\".is_empty(), true);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// assert!(!\"a\".is_empty());\n    /// ```\n    #[clippy::version = \"1.53.0\"]\n    pub BOOL_ASSERT_COMPARISON,\n    style,\n    \"Using a boolean as comparison value in an assert_* macro when there is no need\"\n}\n\ndeclare_lint_pass!(BoolAssertComparison => [BOOL_ASSERT_COMPARISON]);\n\nfn extract_bool_lit(e: &Expr<'_>) -> Option<bool> {\n    if let ExprKind::Lit(Lit {\n        node: LitKind::Bool(b), ..\n    }) = e.kind\n        && !e.span.from_expansion()\n    {\n        Some(b)\n    } else {\n        None\n    }\n}\n\nfn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    cx.tcx\n        .lang_items()\n        .not_trait()\n        .filter(|trait_id| implements_trait(cx, ty, *trait_id, &[]))\n        .and_then(|trait_id| {\n            cx.tcx.associated_items(trait_id).find_by_ident_and_kind(\n                cx.tcx,\n                Ident::with_dummy_span(sym::Output),\n                ty::AssocTag::Type,\n                trait_id,\n            )\n        })\n        .is_some_and(|assoc_item| {\n            let proj = Ty::new_projection(cx.tcx, assoc_item.def_id, cx.tcx.mk_args_trait(ty, []));\n            let nty = cx.tcx.normalize_erasing_regions(cx.typing_env(), proj);\n\n            nty.is_bool()\n        })\n}\n\nimpl<'tcx> LateLintPass<'tcx> for BoolAssertComparison {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {\n            return;\n        };\n        let eq_macro = match cx.tcx.get_diagnostic_name(macro_call.def_id) {\n            Some(sym::assert_eq_macro | sym::debug_assert_eq_macro) => true,\n            Some(sym::assert_ne_macro | sym::debug_assert_ne_macro) => false,\n            _ => return,\n        };\n        let Some((a, b, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else {\n            return;\n        };\n\n        let a_span = a.span.source_callsite();\n        let b_span = b.span.source_callsite();\n\n        let (lit_span, bool_value, non_lit_expr) = match (extract_bool_lit(a), extract_bool_lit(b)) {\n            // assert_eq!(true/false, b)\n            //            ^^^^^^^^^^^^\n            (Some(bool_value), None) => (a_span.until(b_span), bool_value, b),\n            // assert_eq!(a, true/false)\n            //             ^^^^^^^^^^^^\n            (None, Some(bool_value)) => (b_span.with_lo(a_span.hi()), bool_value, a),\n            // If there are two boolean arguments, we definitely don't understand\n            // what's going on, so better leave things as is...\n            //\n            // Or there is simply no boolean and then we can leave things as is!\n            _ => return,\n        };\n\n        let non_lit_ty = cx.typeck_results().expr_ty(non_lit_expr);\n\n        if !is_impl_not_trait_with_bool_out(cx, non_lit_ty) {\n            // At this point the expression which is not a boolean\n            // literal does not implement Not trait with a bool output,\n            // so we cannot suggest to rewrite our code\n            return;\n        }\n\n        if !is_copy(cx, non_lit_ty) {\n            // Only lint with types that are `Copy` because `assert!(x)` takes\n            // ownership of `x` whereas `assert_eq(x, true)` does not\n            return;\n        }\n\n        let macro_name = cx.tcx.item_name(macro_call.def_id);\n        let macro_name = macro_name.as_str();\n        let non_eq_mac = &macro_name[..macro_name.len() - 3];\n        span_lint_and_then(\n            cx,\n            BOOL_ASSERT_COMPARISON,\n            macro_call.span,\n            format!(\"used `{macro_name}!` with a literal bool\"),\n            |diag| {\n                // assert_eq!(...)\n                // ^^^^^^^^^\n                let name_span = cx.sess().source_map().span_until_char(macro_call.span, '!');\n\n                let mut suggestions = vec![(name_span, non_eq_mac.to_string()), (lit_span, String::new())];\n\n                let mut applicability = Applicability::MachineApplicable;\n                let sugg = Sugg::hir_with_context(cx, non_lit_expr, macro_call.span.ctxt(), \"..\", &mut applicability);\n                let sugg = if bool_value ^ eq_macro {\n                    !sugg.maybe_paren()\n                } else if ty::Bool == *non_lit_ty.kind() {\n                    sugg\n                } else {\n                    !!sugg.maybe_paren()\n                };\n                let non_lit_expr_span =\n                    walk_span_to_context(non_lit_expr.span, macro_call.span.ctxt()).unwrap_or(non_lit_expr.span);\n                suggestions.push((non_lit_expr_span, sugg.to_string()));\n\n                diag.multipart_suggestion(\n                    format!(\"replace it with `{non_eq_mac}!(..)`\"),\n                    suggestions,\n                    applicability,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/bool_comparison.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{is_expn_of, peel_blocks, sym};\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::source_map::Spanned;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions of the form `x == true`,\n    /// `x != true` and order comparisons such as `x < true` (or vice versa) and\n    /// suggest using the variable directly.\n    ///\n    /// ### Why is this bad?\n    /// Unnecessary code.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// if x == true {}\n    /// if y == false {}\n    /// ```\n    /// use `x` directly:\n    /// ```rust,ignore\n    /// if x {}\n    /// if !y {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub BOOL_COMPARISON,\n    complexity,\n    \"comparing a variable to a boolean, e.g., `if x == true` or `if x != true`\"\n}\n\ndeclare_lint_pass!(BoolComparison => [BOOL_COMPARISON]);\n\nimpl<'tcx> LateLintPass<'tcx> for BoolComparison {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if e.span.from_expansion() {\n            return;\n        }\n\n        if let ExprKind::Binary(Spanned { node, .. }, left_side, right_side) = e.kind\n            && is_expn_of(left_side.span, sym::cfg).is_none()\n            && is_expn_of(right_side.span, sym::cfg).is_none()\n            && cx.typeck_results().expr_ty(left_side).is_bool()\n            && cx.typeck_results().expr_ty(right_side).is_bool()\n        {\n            let ignore_case = None::<(fn(_) -> _, &str)>;\n            let ignore_no_literal = None::<(fn(_, _) -> _, &str)>;\n            match node {\n                BinOpKind::Eq => {\n                    let true_case = Some((|h| h, \"equality checks against true are unnecessary\"));\n                    let false_case = Some((\n                        |h: Sugg<'tcx>| !h,\n                        \"equality checks against false can be replaced by a negation\",\n                    ));\n                    check_comparison(cx, e, true_case, false_case, true_case, false_case, ignore_no_literal);\n                },\n                BinOpKind::Ne => {\n                    let true_case = Some((\n                        |h: Sugg<'tcx>| !h,\n                        \"inequality checks against true can be replaced by a negation\",\n                    ));\n                    let false_case = Some((|h| h, \"inequality checks against false are unnecessary\"));\n                    check_comparison(cx, e, true_case, false_case, true_case, false_case, ignore_no_literal);\n                },\n                BinOpKind::Lt => check_comparison(\n                    cx,\n                    e,\n                    ignore_case,\n                    Some((|h| h, \"greater than checks against false are unnecessary\")),\n                    Some((\n                        |h: Sugg<'tcx>| !h,\n                        \"less than comparison against true can be replaced by a negation\",\n                    )),\n                    ignore_case,\n                    Some((\n                        |l: Sugg<'tcx>, r: Sugg<'tcx>| (!l).bit_and(&r),\n                        \"order comparisons between booleans can be simplified\",\n                    )),\n                ),\n                BinOpKind::Gt => check_comparison(\n                    cx,\n                    e,\n                    Some((\n                        |h: Sugg<'tcx>| !h,\n                        \"less than comparison against true can be replaced by a negation\",\n                    )),\n                    ignore_case,\n                    ignore_case,\n                    Some((|h| h, \"greater than checks against false are unnecessary\")),\n                    Some((\n                        |l: Sugg<'tcx>, r: Sugg<'tcx>| l.bit_and(&(!r)),\n                        \"order comparisons between booleans can be simplified\",\n                    )),\n                ),\n                _ => (),\n            }\n        }\n    }\n}\n\nfn check_comparison<'a, 'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    left_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,\n    left_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,\n    right_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,\n    right_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,\n    no_literal: Option<(impl FnOnce(Sugg<'a>, Sugg<'a>) -> Sugg<'a>, &'static str)>,\n) {\n    if let ExprKind::Binary(_, left_side, right_side) = e.kind {\n        let mut applicability = Applicability::MachineApplicable;\n        // Eliminate parentheses in `e` by using the lo pos of lhs and hi pos of rhs,\n        // calling `source_callsite` make sure macros are handled correctly, see issue #9907\n        let binop_span = left_side.span.source_callsite().to(right_side.span.source_callsite());\n\n        match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {\n            (Some(true), None) => left_true.map_or((), |(h, m)| {\n                suggest_bool_comparison(cx, binop_span, right_side, applicability, m, h);\n            }),\n            (None, Some(true)) => right_true.map_or((), |(h, m)| {\n                suggest_bool_comparison(cx, binop_span, left_side, applicability, m, h);\n            }),\n            (Some(false), None) => left_false.map_or((), |(h, m)| {\n                suggest_bool_comparison(cx, binop_span, right_side, applicability, m, h);\n            }),\n            (None, Some(false)) => right_false.map_or((), |(h, m)| {\n                suggest_bool_comparison(cx, binop_span, left_side, applicability, m, h);\n            }),\n            (None, None) => no_literal.map_or((), |(h, m)| {\n                let left_side = Sugg::hir_with_context(cx, left_side, binop_span.ctxt(), \"..\", &mut applicability);\n                let right_side = Sugg::hir_with_context(cx, right_side, binop_span.ctxt(), \"..\", &mut applicability);\n                span_lint_and_sugg(\n                    cx,\n                    BOOL_COMPARISON,\n                    binop_span,\n                    m,\n                    \"try\",\n                    h(left_side, right_side).into_string(),\n                    applicability,\n                );\n            }),\n            _ => (),\n        }\n    }\n}\n\nfn suggest_bool_comparison<'a, 'tcx>(\n    cx: &LateContext<'tcx>,\n    span: Span,\n    expr: &Expr<'_>,\n    mut app: Applicability,\n    message: &'static str,\n    conv_hint: impl FnOnce(Sugg<'a>) -> Sugg<'a>,\n) {\n    let hint = Sugg::hir_with_context(cx, expr, span.ctxt(), \"..\", &mut app);\n    span_lint_and_sugg(\n        cx,\n        BOOL_COMPARISON,\n        span,\n        message,\n        \"try\",\n        conv_hint(hint).into_string(),\n        app,\n    );\n}\n\nfn fetch_bool_expr(expr: &Expr<'_>) -> Option<bool> {\n    if let ExprKind::Lit(lit_ptr) = peel_blocks(expr).kind\n        && let LitKind::Bool(value) = lit_ptr.node\n    {\n        return Some(value);\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/bool_to_int_with_if.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{higher, is_else_clause, is_in_const_context, span_contains_comment};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Instead of using an if statement to convert a bool to an int,\n    /// this lint suggests using a `from()` function or an `as` coercion.\n    ///\n    /// ### Why is this bad?\n    /// Coercion or `from()` is another way to convert bool to a number.\n    /// Both methods are guaranteed to return 1 for true, and 0 for false.\n    ///\n    /// See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let condition = false;\n    /// if condition {\n    ///     1_i64\n    /// } else {\n    ///     0\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let condition = false;\n    /// i64::from(condition);\n    /// ```\n    /// or\n    /// ```no_run\n    /// # let condition = false;\n    /// condition as i64;\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub BOOL_TO_INT_WITH_IF,\n    pedantic,\n    \"using if to convert bool to int\"\n}\n\ndeclare_lint_pass!(BoolToIntWithIf => [BOOL_TO_INT_WITH_IF]);\n\nimpl<'tcx> LateLintPass<'tcx> for BoolToIntWithIf {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if !expr.span.from_expansion()\n            && let Some(higher::If {\n                cond,\n                then,\n                r#else: Some(r#else),\n            }) = higher::If::hir(expr)\n            && let Some(then_lit) = as_int_bool_lit(then)\n            && let Some(else_lit) = as_int_bool_lit(r#else)\n            && then_lit != else_lit\n            && !is_in_const_context(cx)\n        {\n            let ty = cx.typeck_results().expr_ty(then);\n            let mut applicability = if span_contains_comment(cx, expr.span) {\n                Applicability::MaybeIncorrect\n            } else {\n                Applicability::MachineApplicable\n            };\n            let snippet = {\n                let mut sugg = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), \"..\", &mut applicability);\n                if !then_lit {\n                    sugg = !sugg;\n                }\n                sugg\n            };\n            let suggestion = {\n                let mut s = Sugg::NonParen(format!(\"{ty}::from({snippet})\").into());\n                // when used in else clause if statement should be wrapped in curly braces\n                if is_else_clause(cx.tcx, expr) {\n                    s = s.blockify();\n                }\n                s\n            };\n\n            let into_snippet = snippet.clone().maybe_paren();\n            let as_snippet = snippet.as_ty(ty);\n\n            span_lint_and_then(\n                cx,\n                BOOL_TO_INT_WITH_IF,\n                expr.span,\n                \"boolean to int conversion using if\",\n                |diag| {\n                    diag.span_suggestion(expr.span, \"replace with from\", suggestion, applicability);\n                    diag.note(format!(\n                        \"`{as_snippet}` or `{into_snippet}.into()` can also be valid options\"\n                    ));\n                },\n            );\n        }\n    }\n}\n\nfn as_int_bool_lit(expr: &Expr<'_>) -> Option<bool> {\n    if let ExprKind::Block(b, _) = expr.kind\n        && b.stmts.is_empty()\n        && let Some(e) = b.expr\n        && !e.span.from_expansion()\n        && let ExprKind::Lit(lit) = e.kind\n        && let LitKind::Int(x, _) = lit.node\n    {\n        match x.get() {\n            0 => Some(false),\n            1 => Some(true),\n            _ => None,\n        }\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/booleans.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};\nuse clippy_utils::higher::has_let_expr;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{SpanRangeExt, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{eq_expr_value, sym};\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{FnKind, Visitor, walk_expr};\nuse rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, RustcVersion, UnOp};\nuse rustc_lint::{LateContext, LateLintPass, Level};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{Span, Symbol, SyntaxContext};\nuse std::fmt::Write as _;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for boolean expressions that can be written more\n    /// concisely.\n    ///\n    /// ### Why is this bad?\n    /// Readability of boolean expressions suffers from\n    /// unnecessary duplication.\n    ///\n    /// ### Known problems\n    /// Ignores short circuiting behavior of `||` and\n    /// `&&`. Ignores `|`, `&` and `^`.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// if a && true {}\n    /// if !(a == b) {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// if a {}\n    /// if a != b {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NONMINIMAL_BOOL,\n    complexity,\n    \"boolean expressions that can be written more concisely\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for boolean expressions that contain terminals that\n    /// can be eliminated.\n    ///\n    /// ### Why is this bad?\n    /// This is most likely a logic bug.\n    ///\n    /// ### Known problems\n    /// Ignores short circuiting behavior.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// // The `b` is unnecessary, the expression is equivalent to `if a`.\n    /// if a && b || a { ... }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// if a {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub OVERLY_COMPLEX_BOOL_EXPR,\n    correctness,\n    \"boolean expressions that contain terminals which can be eliminated\"\n}\n\nimpl_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, OVERLY_COMPLEX_BOOL_EXPR]);\n\n// For each pairs, both orders are considered.\nconst METHODS_WITH_NEGATION: [(Option<RustcVersion>, Symbol, Symbol); 3] = [\n    (None, sym::is_some, sym::is_none),\n    (None, sym::is_err, sym::is_ok),\n    (Some(msrvs::IS_NONE_OR), sym::is_some_and, sym::is_none_or),\n];\n\npub struct NonminimalBool {\n    msrv: Msrv,\n}\n\nimpl NonminimalBool {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NonminimalBool {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        _: FnKind<'tcx>,\n        _: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        _: Span,\n        _: LocalDefId,\n    ) {\n        NonminimalBoolVisitor { cx, msrv: self.msrv }.visit_body(body);\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        match expr.kind {\n            // This check the case where an element in a boolean comparison is inverted, like:\n            //\n            // ```\n            // let a = true;\n            // !a == false;\n            // ```\n            ExprKind::Binary(op, left, right) if matches!(op.node, BinOpKind::Eq | BinOpKind::Ne) => {\n                check_inverted_bool_in_condition(cx, expr.span, op.node, left, right);\n            },\n            _ => {},\n        }\n    }\n}\n\nfn inverted_bin_op_eq_str(op: BinOpKind) -> Option<&'static str> {\n    match op {\n        BinOpKind::Eq => Some(\"!=\"),\n        BinOpKind::Ne => Some(\"==\"),\n        _ => None,\n    }\n}\n\nfn bin_op_eq_str(op: BinOpKind) -> Option<&'static str> {\n    match op {\n        BinOpKind::Eq => Some(\"==\"),\n        BinOpKind::Ne => Some(\"!=\"),\n        _ => None,\n    }\n}\n\nfn check_inverted_bool_in_condition(\n    cx: &LateContext<'_>,\n    expr_span: Span,\n    op: BinOpKind,\n    left: &Expr<'_>,\n    right: &Expr<'_>,\n) {\n    if expr_span.from_expansion()\n        || !cx.typeck_results().node_types()[left.hir_id].is_bool()\n        || !cx.typeck_results().node_types()[right.hir_id].is_bool()\n    {\n        return;\n    }\n\n    let suggestion = match (left.kind, right.kind) {\n        (ExprKind::Unary(UnOp::Not, left_sub), ExprKind::Unary(UnOp::Not, right_sub)) => {\n            let Some(left) = left_sub.span.get_source_text(cx) else {\n                return;\n            };\n            let Some(right) = right_sub.span.get_source_text(cx) else {\n                return;\n            };\n            let Some(op) = bin_op_eq_str(op) else { return };\n            format!(\"{left} {op} {right}\")\n        },\n        (ExprKind::Unary(UnOp::Not, left_sub), _) => {\n            let Some(left) = left_sub.span.get_source_text(cx) else {\n                return;\n            };\n            let Some(right) = right.span.get_source_text(cx) else {\n                return;\n            };\n            let Some(op) = inverted_bin_op_eq_str(op) else { return };\n            format!(\"{left} {op} {right}\")\n        },\n        (_, ExprKind::Unary(UnOp::Not, right_sub)) => {\n            let Some(left) = left.span.get_source_text(cx) else {\n                return;\n            };\n            let Some(right) = right_sub.span.get_source_text(cx) else {\n                return;\n            };\n            let Some(op) = inverted_bin_op_eq_str(op) else { return };\n            format!(\"{left} {op} {right}\")\n        },\n        _ => return,\n    };\n    span_lint_and_sugg(\n        cx,\n        NONMINIMAL_BOOL,\n        expr_span,\n        \"this boolean expression can be simplified\",\n        \"try\",\n        suggestion,\n        Applicability::MachineApplicable,\n    );\n}\n\nfn check_simplify_not(cx: &LateContext<'_>, msrv: Msrv, expr: &Expr<'_>) {\n    if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind\n        && !expr.span.from_expansion()\n        && !inner.span.from_expansion()\n        && let Some(suggestion) = simplify_not(cx, msrv, inner)\n        && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).level != Level::Allow\n    {\n        use clippy_utils::sugg::{Sugg, has_enclosing_paren};\n        let maybe_par = if let Some(sug) = Sugg::hir_opt(cx, inner) {\n            match sug {\n                Sugg::BinOp(..) => true,\n                Sugg::MaybeParen(sug) if !has_enclosing_paren(&sug) => true,\n                _ => false,\n            }\n        } else {\n            false\n        };\n        let suggestion = if maybe_par {\n            format!(\"({suggestion})\")\n        } else {\n            suggestion\n        };\n        span_lint_and_sugg(\n            cx,\n            NONMINIMAL_BOOL,\n            expr.span,\n            \"this boolean expression can be simplified\",\n            \"try\",\n            suggestion,\n            Applicability::MachineApplicable,\n        );\n    }\n}\n\nstruct NonminimalBoolVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    msrv: Msrv,\n}\n\nuse quine_mc_cluskey::Bool;\nstruct Hir2Qmm<'a, 'tcx, 'v> {\n    terminals: Vec<&'v Expr<'v>>,\n    cx: &'a LateContext<'tcx>,\n}\n\nimpl<'v> Hir2Qmm<'_, '_, 'v> {\n    fn extract(&mut self, op: BinOpKind, a: &[&'v Expr<'_>], mut v: Vec<Bool>) -> Result<Vec<Bool>, String> {\n        for a in a {\n            if let ExprKind::Binary(binop, lhs, rhs) = &a.kind\n                && binop.node == op\n            {\n                v = self.extract(op, &[lhs, rhs], v)?;\n                continue;\n            }\n            v.push(self.run(a)?);\n        }\n        Ok(v)\n    }\n\n    fn run(&mut self, e: &'v Expr<'_>) -> Result<Bool, String> {\n        fn negate(bin_op_kind: BinOpKind) -> Option<BinOpKind> {\n            match bin_op_kind {\n                BinOpKind::Eq => Some(BinOpKind::Ne),\n                BinOpKind::Ne => Some(BinOpKind::Eq),\n                BinOpKind::Gt => Some(BinOpKind::Le),\n                BinOpKind::Ge => Some(BinOpKind::Lt),\n                BinOpKind::Lt => Some(BinOpKind::Ge),\n                BinOpKind::Le => Some(BinOpKind::Gt),\n                _ => None,\n            }\n        }\n\n        // prevent folding of `cfg!` macros and the like\n        if !e.span.from_expansion() {\n            match &e.kind {\n                ExprKind::Unary(UnOp::Not, inner) => return Ok(Bool::Not(Box::new(self.run(inner)?))),\n                ExprKind::Binary(binop, lhs, rhs) => match &binop.node {\n                    BinOpKind::Or => {\n                        return Ok(Bool::Or(self.extract(BinOpKind::Or, &[lhs, rhs], Vec::new())?));\n                    },\n                    BinOpKind::And => {\n                        return Ok(Bool::And(self.extract(BinOpKind::And, &[lhs, rhs], Vec::new())?));\n                    },\n                    _ => (),\n                },\n                ExprKind::Lit(lit) => match lit.node {\n                    LitKind::Bool(true) => return Ok(Bool::True),\n                    LitKind::Bool(false) => return Ok(Bool::False),\n                    _ => (),\n                },\n                _ => (),\n            }\n        }\n\n        if self.cx.typeck_results().expr_ty(e).is_never() {\n            return Err(\"contains never type\".to_owned());\n        }\n\n        for (n, expr) in self.terminals.iter().enumerate() {\n            if eq_expr_value(self.cx, e, expr) {\n                #[expect(clippy::cast_possible_truncation)]\n                return Ok(Bool::Term(n as u8));\n            }\n\n            if let ExprKind::Binary(e_binop, e_lhs, e_rhs) = &e.kind\n                && implements_ord(self.cx, e_lhs)\n                && let ExprKind::Binary(expr_binop, expr_lhs, expr_rhs) = &expr.kind\n                && negate(e_binop.node) == Some(expr_binop.node)\n                && eq_expr_value(self.cx, e_lhs, expr_lhs)\n                && eq_expr_value(self.cx, e_rhs, expr_rhs)\n            {\n                #[expect(clippy::cast_possible_truncation)]\n                return Ok(Bool::Not(Box::new(Bool::Term(n as u8))));\n            }\n        }\n        let n = self.terminals.len();\n        self.terminals.push(e);\n        if n < 32 {\n            #[expect(clippy::cast_possible_truncation)]\n            Ok(Bool::Term(n as u8))\n        } else {\n            Err(\"too many literals\".to_owned())\n        }\n    }\n}\n\nstruct SuggestContext<'a, 'tcx, 'v> {\n    terminals: &'v [&'v Expr<'v>],\n    cx: &'a LateContext<'tcx>,\n    msrv: Msrv,\n    output: String,\n}\n\nimpl SuggestContext<'_, '_, '_> {\n    fn recurse(&mut self, suggestion: &Bool) -> Option<()> {\n        use quine_mc_cluskey::Bool::{And, False, Not, Or, Term, True};\n        match suggestion {\n            True => {\n                self.output.push_str(\"true\");\n            },\n            False => {\n                self.output.push_str(\"false\");\n            },\n            Not(inner) => match **inner {\n                And(_) | Or(_) => {\n                    self.output.push('!');\n                    self.output.push('(');\n                    self.recurse(inner);\n                    self.output.push(')');\n                },\n                Term(n) => {\n                    let terminal = self.terminals[n as usize];\n                    if let Some(str) = simplify_not(self.cx, self.msrv, terminal) {\n                        self.output.push_str(&str);\n                    } else {\n                        let mut app = Applicability::MachineApplicable;\n                        let snip = Sugg::hir_with_context(self.cx, terminal, SyntaxContext::root(), \"\", &mut app);\n                        // Ignore the case If the expression is inside a macro expansion, or the default snippet is used\n                        if app != Applicability::MachineApplicable {\n                            return None;\n                        }\n                        let _cannot_fail = write!(&mut self.output, \"{}\", &(!snip));\n                    }\n                },\n                True | False | Not(_) => {\n                    self.output.push('!');\n                    self.recurse(inner)?;\n                },\n            },\n            And(v) => {\n                for (index, inner) in v.iter().enumerate() {\n                    if index > 0 {\n                        self.output.push_str(\" && \");\n                    }\n                    if let Or(_) = *inner {\n                        self.output.push('(');\n                        self.recurse(inner);\n                        self.output.push(')');\n                    } else {\n                        self.recurse(inner);\n                    }\n                }\n            },\n            Or(v) => {\n                for (index, inner) in v.iter().rev().enumerate() {\n                    if index > 0 {\n                        self.output.push_str(\" || \");\n                    }\n                    self.recurse(inner);\n                }\n            },\n            &Term(n) => {\n                self.output.push_str(\n                    &self.terminals[n as usize]\n                        .span\n                        .source_callsite()\n                        .get_source_text(self.cx)?,\n                );\n            },\n        }\n        Some(())\n    }\n}\n\nfn simplify_not(cx: &LateContext<'_>, curr_msrv: Msrv, expr: &Expr<'_>) -> Option<String> {\n    match &expr.kind {\n        ExprKind::Binary(binop, lhs, rhs) => {\n            if !implements_ord(cx, lhs) {\n                return None;\n            }\n\n            match binop.node {\n                BinOpKind::Eq => Some(\" != \"),\n                BinOpKind::Ne => Some(\" == \"),\n                BinOpKind::Lt => Some(\" >= \"),\n                BinOpKind::Gt => Some(\" <= \"),\n                BinOpKind::Le => Some(\" > \"),\n                BinOpKind::Ge => Some(\" < \"),\n                _ => None,\n            }\n            .map(|op| {\n                let mut app = Applicability::MachineApplicable;\n                let (lhs_snippet, _) = snippet_with_context(cx, lhs.span, SyntaxContext::root(), \"\", &mut app);\n                let (rhs_snippet, _) = snippet_with_context(cx, rhs.span, SyntaxContext::root(), \"\", &mut app);\n\n                if !(lhs_snippet.starts_with('(') && lhs_snippet.ends_with(')'))\n                    && let (ExprKind::Cast(..), BinOpKind::Ge) = (&lhs.kind, binop.node)\n                {\n                    // e.g. `(a as u64) < b`. Without the parens the `<` is\n                    // interpreted as a start of generic arguments for `u64`\n                    return format!(\"({lhs_snippet}){op}{rhs_snippet}\");\n                }\n\n                format!(\"{lhs_snippet}{op}{rhs_snippet}\")\n            })\n        },\n        ExprKind::MethodCall(path, receiver, args, _) => {\n            let type_of_receiver = cx.typeck_results().expr_ty(receiver);\n            if !matches!(type_of_receiver.opt_diag_name(cx), Some(sym::Option | sym::Result)) {\n                return None;\n            }\n            METHODS_WITH_NEGATION\n                .iter()\n                .copied()\n                .flat_map(|(msrv, a, b)| vec![(msrv, a, b), (msrv, b, a)])\n                .find(|&(msrv, a, _)| a == path.ident.name && msrv.is_none_or(|msrv| curr_msrv.meets(cx, msrv)))\n                .and_then(|(_, _, neg_method)| {\n                    let negated_args = args\n                        .iter()\n                        .map(|arg| simplify_not(cx, curr_msrv, arg))\n                        .collect::<Option<Vec<_>>>()?\n                        .join(\", \");\n                    Some(format!(\n                        \"{}.{neg_method}({negated_args})\",\n                        receiver.span.get_source_text(cx)?\n                    ))\n                })\n        },\n        ExprKind::Closure(closure) => {\n            let body = cx.tcx.hir_body(closure.body);\n            let params = body\n                .params\n                .iter()\n                .map(|param| param.span.get_source_text(cx).map(|t| t.to_string()))\n                .collect::<Option<Vec<_>>>()?\n                .join(\", \");\n            let negated = simplify_not(cx, curr_msrv, body.value)?;\n            Some(format!(\"|{params}| {negated}\"))\n        },\n        ExprKind::Unary(UnOp::Not, expr) => expr.span.get_source_text(cx).map(|t| t.to_string()),\n        _ => None,\n    }\n}\n\nfn suggest(cx: &LateContext<'_>, msrv: Msrv, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String {\n    let mut suggest_context = SuggestContext {\n        terminals,\n        cx,\n        msrv,\n        output: String::new(),\n    };\n    suggest_context.recurse(suggestion);\n    suggest_context.output\n}\n\nfn simple_negate(b: Bool) -> Bool {\n    use quine_mc_cluskey::Bool::{And, False, Not, Or, Term, True};\n    match b {\n        True => False,\n        False => True,\n        t @ Term(_) => Not(Box::new(t)),\n        And(mut v) => {\n            for el in &mut v {\n                *el = simple_negate(std::mem::replace(el, True));\n            }\n            Or(v)\n        },\n        Or(mut v) => {\n            for el in &mut v {\n                *el = simple_negate(std::mem::replace(el, True));\n            }\n            And(v)\n        },\n        Not(inner) => *inner,\n    }\n}\n\n#[derive(Default)]\nstruct Stats {\n    terminals: [usize; 32],\n    negations: usize,\n    ops: usize,\n}\n\nfn terminal_stats(b: &Bool) -> Stats {\n    fn recurse(b: &Bool, stats: &mut Stats) {\n        match b {\n            True | False => stats.ops += 1,\n            Not(inner) => {\n                match **inner {\n                    And(_) | Or(_) => stats.ops += 1, // brackets are also operations\n                    _ => stats.negations += 1,\n                }\n                recurse(inner, stats);\n            },\n            And(v) | Or(v) => {\n                stats.ops += v.len() - 1;\n                for inner in v {\n                    recurse(inner, stats);\n                }\n            },\n            &Term(n) => stats.terminals[n as usize] += 1,\n        }\n    }\n    use quine_mc_cluskey::Bool::{And, False, Not, Or, Term, True};\n    let mut stats = Stats::default();\n    recurse(b, &mut stats);\n    stats\n}\n\nimpl<'tcx> NonminimalBoolVisitor<'_, 'tcx> {\n    fn bool_expr(&self, e: &'tcx Expr<'_>) {\n        let mut h2q = Hir2Qmm {\n            terminals: Vec::new(),\n            cx: self.cx,\n        };\n        if let Ok(expr) = h2q.run(e) {\n            let stats = terminal_stats(&expr);\n            if stats.ops > 7 {\n                // QMC has exponentially slow behavior as the number of ops increases.\n                // See #825, #13206\n                return;\n            }\n            let mut simplified = expr.simplify();\n            for simple in Bool::Not(Box::new(expr)).simplify() {\n                match simple {\n                    Bool::Not(_) | Bool::True | Bool::False => {},\n                    _ => simplified.push(Bool::Not(Box::new(simple.clone()))),\n                }\n                let simple_negated = simple_negate(simple);\n                if simplified.contains(&simple_negated) {\n                    continue;\n                }\n                simplified.push(simple_negated);\n            }\n            let mut improvements = Vec::with_capacity(simplified.len());\n            'simplified: for suggestion in &simplified {\n                let simplified_stats = terminal_stats(suggestion);\n                let mut improvement = false;\n                for i in 0..32 {\n                    // ignore any \"simplifications\" that end up requiring a terminal more often\n                    // than in the original expression\n                    if stats.terminals[i] < simplified_stats.terminals[i] {\n                        continue 'simplified;\n                    }\n                    if stats.terminals[i] != 0 && simplified_stats.terminals[i] == 0 {\n                        span_lint_hir_and_then(\n                            self.cx,\n                            OVERLY_COMPLEX_BOOL_EXPR,\n                            e.hir_id,\n                            e.span,\n                            \"this boolean expression contains a logic bug\",\n                            |diag| {\n                                diag.span_help(\n                                    h2q.terminals[i].span,\n                                    \"this expression can be optimized out by applying boolean operations to the \\\n                                     outer expression\",\n                                );\n                                diag.span_suggestion(\n                                    e.span,\n                                    \"it would look like the following\",\n                                    suggest(self.cx, self.msrv, suggestion, &h2q.terminals),\n                                    // nonminimal_bool can produce minimal but\n                                    // not human readable expressions (#3141)\n                                    Applicability::Unspecified,\n                                );\n                            },\n                        );\n                        // don't also lint `NONMINIMAL_BOOL`\n                        return;\n                    }\n                    // if the number of occurrences of a terminal decreases or any of the stats\n                    // decreases while none increases\n                    improvement |= (stats.terminals[i] > simplified_stats.terminals[i])\n                        || (stats.negations > simplified_stats.negations && stats.ops == simplified_stats.ops)\n                        || (stats.ops > simplified_stats.ops && stats.negations == simplified_stats.negations);\n                }\n                if improvement {\n                    improvements.push(suggestion);\n                }\n            }\n            let nonminimal_bool_lint = |mut suggestions: Vec<_>| {\n                if self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, e.hir_id).level != Level::Allow {\n                    suggestions.sort();\n                    span_lint_hir_and_then(\n                        self.cx,\n                        NONMINIMAL_BOOL,\n                        e.hir_id,\n                        e.span,\n                        \"this boolean expression can be simplified\",\n                        |diag| {\n                            diag.span_suggestions(\n                                e.span,\n                                \"try\",\n                                suggestions,\n                                // nonminimal_bool can produce minimal but\n                                // not human readable expressions (#3141)\n                                Applicability::Unspecified,\n                            );\n                        },\n                    );\n                }\n            };\n            if improvements.is_empty() {\n                check_simplify_not(self.cx, self.msrv, e);\n            } else {\n                nonminimal_bool_lint(\n                    improvements\n                        .into_iter()\n                        .map(|suggestion| suggest(self.cx, self.msrv, suggestion, &h2q.terminals))\n                        .collect(),\n                );\n            }\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'_, 'tcx> {\n    fn visit_expr(&mut self, e: &'tcx Expr<'_>) {\n        if !e.span.from_expansion() {\n            match &e.kind {\n                ExprKind::Binary(binop, _, _)\n                    if binop.node == BinOpKind::Or || binop.node == BinOpKind::And && !has_let_expr(e) =>\n                {\n                    self.bool_expr(e);\n                },\n                ExprKind::Unary(UnOp::Not, inner) => {\n                    if let ExprKind::Unary(UnOp::Not, ex) = inner.kind\n                        && !self.cx.typeck_results().node_types()[ex.hir_id].is_bool()\n                    {\n                        return;\n                    }\n                    if self.cx.typeck_results().node_types()[inner.hir_id].is_bool() {\n                        self.bool_expr(e);\n                    }\n                },\n                _ => {},\n            }\n        }\n        walk_expr(self, e);\n    }\n}\n\nfn implements_ord(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let ty = cx.typeck_results().expr_ty(expr);\n    cx.tcx\n        .get_diagnostic_item(sym::Ord)\n        .is_some_and(|id| implements_trait(cx, ty, id, &[]))\n}\n"
  },
  {
    "path": "clippy_lints/src/borrow_deref_ref.rs",
    "content": "use crate::reference::DEREF_ADDROF;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{\n    get_enclosing_closure, get_parent_expr, is_expr_temporary_value, is_from_proc_macro, is_lint_allowed, is_mutable,\n    is_upvar_in_closure, path_to_local_with_projections,\n};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, Node, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir::Mutability;\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `&*(&T)`.\n    ///\n    /// ### Why is this bad?\n    /// Dereferencing and then borrowing a reference value has no effect in most cases.\n    ///\n    /// ### Known problems\n    /// False negative on such code:\n    /// ```no_run\n    /// let x = &12;\n    /// let addr_x = &x as *const _ as usize;\n    /// let addr_y = &&*x as *const _ as usize; // assert ok now, and lint triggered.\n    ///                                         // But if we fix it, assert will fail.\n    /// assert_ne!(addr_x, addr_y);\n    /// ```\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let s = &String::new();\n    ///\n    /// let a: &String = &* s;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let s = &String::new();\n    /// let a: &String = s;\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub BORROW_DEREF_REF,\n    complexity,\n    \"deref on an immutable reference returns the same type as itself\"\n}\n\ndeclare_lint_pass!(BorrowDerefRef => [BORROW_DEREF_REF]);\n\nimpl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) {\n        if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, addrof_target) = e.kind\n            && let ExprKind::Unary(UnOp::Deref, deref_target) = addrof_target.kind\n            && !matches!(deref_target.kind, ExprKind::Unary(UnOp::Deref, ..))\n            && !e.span.from_expansion()\n            && !deref_target.span.from_expansion()\n            && !addrof_target.span.from_expansion()\n            && let ref_ty = cx.typeck_results().expr_ty(deref_target)\n            && let ty::Ref(_, inner_ty, Mutability::Not) = ref_ty.kind()\n            && get_parent_expr(cx, e).is_none_or(|parent| {\n                match parent.kind {\n                    // `*&*foo` should lint `deref_addrof` instead.\n                    ExprKind::Unary(UnOp::Deref, _) => is_lint_allowed(cx, DEREF_ADDROF, parent.hir_id),\n                    // `&*foo` creates a distinct temporary from `foo`\n                    ExprKind::AddrOf(_, Mutability::Mut, _) => !matches!(\n                        deref_target.kind,\n                        ExprKind::Path(..)\n                            | ExprKind::Field(..)\n                            | ExprKind::Index(..)\n                            | ExprKind::Unary(UnOp::Deref, ..)\n                    ),\n                    _ => true,\n                }\n            })\n            && !is_from_proc_macro(cx, e)\n            && let e_ty = cx.typeck_results().expr_ty_adjusted(e)\n            // check if the reference is coercing to a mutable reference\n            && (!matches!(e_ty.kind(), ty::Ref(_, _, Mutability::Mut)) || is_mutable(cx, deref_target))\n            // If the new borrow might be itself borrowed mutably and the original reference is not a temporary\n            // value, do not propose to use it directly.\n            && (is_expr_temporary_value(cx, deref_target) || !potentially_bound_to_mutable_ref(cx, e))\n            && let Some(deref_text) = deref_target.span.get_source_text(cx)\n        {\n            // `&*x` can be needed to shorten the borrow of `x`. Replacing it with `x` can be\n            // incorrect when `x` is a closure-captured upvar (e.g. a closure returning another\n            // closure that captures `x`).\n            if let Some(closure) = get_enclosing_closure(cx, e.hir_id)\n                && let Some(local_id) = path_to_local_with_projections(deref_target)\n                && is_upvar_in_closure(cx, closure, local_id)\n            {\n                return;\n            }\n\n            span_lint_and_then(\n                cx,\n                BORROW_DEREF_REF,\n                e.span,\n                \"deref on an immutable reference\",\n                |diag| {\n                    diag.span_suggestion(\n                        e.span,\n                        \"if you would like to reborrow, try removing `&*`\",\n                        deref_text.as_str(),\n                        Applicability::MachineApplicable,\n                    );\n\n                    // has deref trait -> give 2 help\n                    // doesn't have deref trait -> give 1 help\n                    if let Some(deref_trait_id) = cx.tcx.lang_items().deref_trait()\n                        && !implements_trait(cx, *inner_ty, deref_trait_id, &[])\n                    {\n                        return;\n                    }\n\n                    diag.span_suggestion(\n                        e.span,\n                        \"if you would like to deref, try using `&**`\",\n                        format!(\"&**{deref_text}\"),\n                        Applicability::MaybeIncorrect,\n                    );\n                },\n            );\n        }\n    }\n}\n\n/// Checks if `expr` is used as part of a `let` statement containing a `ref mut` binding.\nfn potentially_bound_to_mutable_ref<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {\n    matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::LetStmt(let_stmt)\n             if let_stmt.pat.contains_explicit_ref_binding() == Some(Mutability::Mut))\n}\n"
  },
  {
    "path": "clippy_lints/src/box_default.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::macros::macro_backtrace;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::ty::expr_sig;\nuse clippy_utils::{is_default_equivalent, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};\nuse rustc_hir::{AmbigArg, Block, Expr, ExprKind, HirId, LangItem, LetStmt, Node, QPath, Ty, TyKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// checks for `Box::new(Default::default())`, which can be written as\n    /// `Box::default()`.\n    ///\n    /// ### Why is this bad?\n    /// `Box::default()` is equivalent and more concise.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: Box<String> = Box::new(Default::default());\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x: Box<String> = Box::default();\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub BOX_DEFAULT,\n    style,\n    \"Using Box::new(T::default()) instead of Box::default()\"\n}\n\ndeclare_lint_pass!(BoxDefault => [BOX_DEFAULT]);\n\nimpl LateLintPass<'_> for BoxDefault {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        // If the expression is a call (`Box::new(...)`)\n        if let ExprKind::Call(box_new, [arg]) = expr.kind\n            // And call is of the form `<T>::something`\n            // Here, it would be `<Box>::new`\n            && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_new.kind\n            // And that method is `new`\n            && seg.ident.name == sym::new\n            // And the call is that of a `Box` method\n            && ty.basic_res().is_lang_item(cx, LangItem::OwnedBox)\n            // And the single argument to the call is another function call\n            // This is the `T::default()` (or default equivalent) of `Box::new(T::default())`\n            && let ExprKind::Call(arg_path, _) = arg.kind\n            // And we are not in a foreign crate's macro\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            // And the argument expression has the same context as the outer call expression\n            // or that we are inside a `vec!` macro expansion\n            && (expr.span.eq_ctxt(arg.span) || is_local_vec_expn(cx, arg, expr))\n            // And the argument is `Default::default()` or the type is specified\n            && (is_plain_default(cx, arg_path) || (given_type(cx, expr) && is_default_equivalent(cx, arg)))\n        {\n            span_lint_and_sugg(\n                cx,\n                BOX_DEFAULT,\n                expr.span,\n                \"`Box::new(_)` of default value\",\n                \"try\",\n                \"Box::default()\".into(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n\nfn is_plain_default(cx: &LateContext<'_>, arg_path: &Expr<'_>) -> bool {\n    // we need to match the actual path so we don't match e.g. \"u8::default\"\n    if let ExprKind::Path(QPath::Resolved(None, path)) = &arg_path.kind\n        && let Res::Def(_, def_id) = path.res\n    {\n        // avoid generic parameters\n        cx.tcx.is_diagnostic_item(sym::default_fn, def_id) && path.segments.iter().all(|seg| seg.args.is_none())\n    } else {\n        false\n    }\n}\n\nfn is_local_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>, ref_expr: &Expr<'_>) -> bool {\n    macro_backtrace(expr.span)\n        .next()\n        .is_some_and(|call| cx.tcx.is_diagnostic_item(sym::vec_macro, call.def_id) && call.span.eq_ctxt(ref_expr.span))\n}\n\n#[derive(Default)]\nstruct InferVisitor(bool);\n\nimpl Visitor<'_> for InferVisitor {\n    fn visit_infer(&mut self, inf_id: HirId, _inf_span: Span, _kind: InferKind<'_>) -> Self::Result {\n        self.0 = true;\n        self.visit_id(inf_id);\n    }\n\n    fn visit_ty(&mut self, t: &Ty<'_, AmbigArg>) {\n        self.0 |= matches!(t.kind, TyKind::OpaqueDef(..) | TyKind::TraitObject(..));\n        if !self.0 {\n            walk_ty(self, t);\n        }\n    }\n}\n\nfn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match cx.tcx.parent_hir_node(expr.hir_id) {\n        Node::LetStmt(LetStmt { ty: Some(ty), .. }) => {\n            let mut v = InferVisitor::default();\n            v.visit_ty_unambig(ty);\n            !v.0\n        },\n        Node::Expr(Expr {\n            kind: ExprKind::Call(path, args),\n            ..\n        })\n        | Node::Block(Block {\n            expr: Some(Expr {\n                kind: ExprKind::Call(path, args),\n                ..\n            }),\n            ..\n        }) => {\n            if let Some(index) = args.iter().position(|arg| arg.hir_id == expr.hir_id)\n                && let Some(sig) = expr_sig(cx, path)\n                && let Some(input) = sig.input(index)\n                && let Some(input_ty) = input.no_bound_vars()\n            {\n                input_ty == cx.typeck_results().expr_ty_adjusted(expr)\n            } else {\n                false\n            }\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/byte_char_slices.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse rustc_ast::ast::{BorrowKind, Expr, ExprKind, Mutability};\nuse rustc_ast::token::{Lit, LitKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for hard to read slices of byte characters, that could be more easily expressed as a\n    /// byte string.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Potentially makes the string harder to read.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// &[b'H', b'e', b'l', b'l', b'o'];\n    /// ```\n    /// Use instead:\n    /// ```ignore\n    /// b\"Hello\"\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub BYTE_CHAR_SLICES,\n    style,\n    \"hard to read byte char slice\"\n}\n\ndeclare_lint_pass!(ByteCharSlice => [BYTE_CHAR_SLICES]);\n\nimpl EarlyLintPass for ByteCharSlice {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if !expr.span.from_expansion()\n            && let Some(slice) = is_byte_char_slices(expr)\n        {\n            span_lint_and_sugg(\n                cx,\n                BYTE_CHAR_SLICES,\n                expr.span,\n                \"can be more succinctly written as a byte str\",\n                \"try\",\n                format!(\"b\\\"{slice}\\\"\"),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n\n/// Checks whether the slice is that of byte chars, and if so, builds a byte-string out of it\nfn is_byte_char_slices(expr: &Expr) -> Option<String> {\n    if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, expr) = &expr.kind\n        && let ExprKind::Array(members) = &expr.kind\n        && !members.is_empty()\n    {\n        members\n            .iter()\n            .map(|member| match &member.kind {\n                ExprKind::Lit(Lit {\n                    kind: LitKind::Byte,\n                    symbol,\n                    ..\n                }) => Some(symbol.as_str()),\n                _ => None,\n            })\n            .map(|maybe_quote| match maybe_quote {\n                Some(\"\\\"\") => Some(\"\\\\\\\"\"),\n                Some(\"\\\\'\") => Some(\"'\"),\n                other => other,\n            })\n            .collect::<Option<String>>()\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/cargo/common_metadata.rs",
    "content": "use cargo_metadata::Metadata;\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_lint::LateContext;\nuse rustc_span::DUMMY_SP;\n\nuse super::CARGO_COMMON_METADATA;\n\npub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, ignore_publish: bool) {\n    for package in &metadata.packages {\n        // only run the lint if publish is `None` (`publish = true` or skipped entirely)\n        // or if the vector isn't empty (`publish = [\"something\"]`)\n        if package.publish.as_ref().is_none_or(|publish| !publish.is_empty()) || ignore_publish {\n            if is_empty_str(package.description.as_ref()) {\n                missing_warning(cx, package, \"package.description\");\n            }\n\n            if is_empty_str(package.license.as_ref()) && is_empty_str(package.license_file.as_ref()) {\n                missing_warning(cx, package, \"either package.license or package.license_file\");\n            }\n\n            if is_empty_str(package.repository.as_ref()) {\n                missing_warning(cx, package, \"package.repository\");\n            }\n\n            if is_empty_str(package.readme.as_ref()) {\n                missing_warning(cx, package, \"package.readme\");\n            }\n\n            if is_empty_vec(package.keywords.as_ref()) {\n                missing_warning(cx, package, \"package.keywords\");\n            }\n\n            if is_empty_vec(package.categories.as_ref()) {\n                missing_warning(cx, package, \"package.categories\");\n            }\n        }\n    }\n}\n\nfn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, field: &str) {\n    let message = format!(\"package `{}` is missing `{field}` metadata\", package.name);\n    span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, message);\n}\n\nfn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: Option<&T>) -> bool {\n    value.is_none_or(|s| s.as_ref().is_empty())\n}\n\nfn is_empty_vec(value: &[String]) -> bool {\n    // This works because empty iterators return true\n    value.iter().all(String::is_empty)\n}\n"
  },
  {
    "path": "clippy_lints/src/cargo/feature_name.rs",
    "content": "use cargo_metadata::Metadata;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse rustc_lint::LateContext;\nuse rustc_span::DUMMY_SP;\n\nuse super::{NEGATIVE_FEATURE_NAMES, REDUNDANT_FEATURE_NAMES};\n\nstatic PREFIXES: [&str; 8] = [\"no-\", \"no_\", \"not-\", \"not_\", \"use-\", \"use_\", \"with-\", \"with_\"];\nstatic SUFFIXES: [&str; 2] = [\"-support\", \"_support\"];\n\npub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata) {\n    for package in &metadata.packages {\n        let mut features: Vec<&String> = package.features.keys().collect();\n        features.sort();\n        for feature in features {\n            let prefix_opt = {\n                let i = PREFIXES.partition_point(|prefix| prefix < &feature.as_str());\n                if i > 0 && feature.starts_with(PREFIXES[i - 1]) {\n                    Some(PREFIXES[i - 1])\n                } else {\n                    None\n                }\n            };\n            if let Some(prefix) = prefix_opt {\n                lint(cx, feature, prefix, true);\n            }\n\n            let suffix_opt: Option<&str> = {\n                let i = SUFFIXES.partition_point(|suffix| {\n                    suffix.bytes().rev().cmp(feature.bytes().rev()) == std::cmp::Ordering::Less\n                });\n                if i > 0 && feature.ends_with(SUFFIXES[i - 1]) {\n                    Some(SUFFIXES[i - 1])\n                } else {\n                    None\n                }\n            };\n            if let Some(suffix) = suffix_opt {\n                lint(cx, feature, suffix, false);\n            }\n        }\n    }\n}\n\nfn is_negative_prefix(s: &str) -> bool {\n    s.starts_with(\"no\")\n}\n\nfn lint(cx: &LateContext<'_>, feature: &str, substring: &str, is_prefix: bool) {\n    let is_negative = is_prefix && is_negative_prefix(substring);\n    span_lint_and_help(\n        cx,\n        if is_negative {\n            NEGATIVE_FEATURE_NAMES\n        } else {\n            REDUNDANT_FEATURE_NAMES\n        },\n        DUMMY_SP,\n        format!(\n            \"the \\\"{substring}\\\" {} in the feature name \\\"{feature}\\\" is {}\",\n            if is_prefix { \"prefix\" } else { \"suffix\" },\n            if is_negative { \"negative\" } else { \"redundant\" }\n        ),\n        None,\n        format!(\n            \"consider renaming the feature to \\\"{}\\\"{}\",\n            if is_prefix {\n                feature.strip_prefix(substring)\n            } else {\n                feature.strip_suffix(substring)\n            }\n            .unwrap(),\n            if is_negative {\n                \", but make sure the feature adds functionality\"\n            } else {\n                \"\"\n            }\n        ),\n    );\n}\n\n#[test]\nfn test_prefixes_sorted() {\n    let mut sorted_prefixes = PREFIXES;\n    sorted_prefixes.sort_unstable();\n    assert_eq!(PREFIXES, sorted_prefixes);\n    let mut sorted_suffixes = SUFFIXES;\n    sorted_suffixes.sort_by(|a, b| a.bytes().rev().cmp(b.bytes().rev()));\n    assert_eq!(SUFFIXES, sorted_suffixes);\n}\n"
  },
  {
    "path": "clippy_lints/src/cargo/lint_groups_priority.rs",
    "content": "use super::LINT_GROUPS_PRIORITY;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_lint::{LateContext, unerased_lint_store};\nuse rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};\nuse std::ops::Range;\nuse std::path::Path;\nuse toml::Spanned;\nuse toml::de::{DeTable, DeValue};\n\nfn toml_span(range: Range<usize>, file: &SourceFile) -> Span {\n    Span::new(\n        file.start_pos + BytePos::from_usize(range.start),\n        file.start_pos + BytePos::from_usize(range.end),\n        SyntaxContext::root(),\n        None,\n    )\n}\n\nstruct LintConfig<'a> {\n    sp: Range<usize>,\n    level: &'a str,\n    priority: Option<i64>,\n}\nimpl<'a> LintConfig<'a> {\n    fn priority(&self) -> i64 {\n        self.priority.unwrap_or(0)\n    }\n\n    fn is_implicit(&self) -> bool {\n        self.priority.is_none()\n    }\n\n    fn parse(value: &'a Spanned<DeValue<'a>>) -> Option<Self> {\n        let sp = value.span();\n        let (level, priority) = match value.get_ref() {\n            DeValue::String(level) => (&**level, None),\n            DeValue::Table(tbl) => {\n                let level = tbl.get(\"level\")?.get_ref().as_str()?;\n                let priority = if let Some(priority) = tbl.get(\"priority\") {\n                    let priority = priority.get_ref().as_integer()?;\n                    Some(i64::from_str_radix(priority.as_str(), priority.radix()).ok()?)\n                } else {\n                    None\n                };\n                (level, priority)\n            },\n            _ => return None,\n        };\n        Some(Self { sp, level, priority })\n    }\n}\n\nfn check_table(cx: &LateContext<'_>, table: &DeTable<'_>, known_groups: &FxHashSet<&str>, file: &SourceFile) {\n    let mut lints = Vec::new();\n    let mut groups = Vec::new();\n    for (name, config) in table {\n        if name.get_ref() != \"warnings\"\n            && let Some(config) = LintConfig::parse(config)\n        {\n            if known_groups.contains(&**name.get_ref()) {\n                groups.push((name, config));\n            } else {\n                lints.push((name, config));\n            }\n        }\n    }\n\n    for (group, group_config) in groups {\n        if let Some((conflict, _)) = lints.iter().rfind(|(_, lint_config)| {\n            lint_config.priority() == group_config.priority() && lint_config.level != group_config.level\n        }) {\n            span_lint_and_then(\n                cx,\n                LINT_GROUPS_PRIORITY,\n                toml_span(group.span(), file),\n                format!(\n                    \"lint group `{}` has the same priority ({}) as a lint\",\n                    group.as_ref(),\n                    group_config.priority(),\n                ),\n                |diag| {\n                    let config_span = toml_span(group_config.sp.clone(), file);\n\n                    if group_config.is_implicit() {\n                        diag.span_label(config_span, \"has an implicit priority of 0\");\n                    }\n                    diag.span_label(toml_span(conflict.span(), file), \"has the same priority as this lint\");\n                    diag.note(\"the order of the lints in the table is ignored by Cargo\");\n\n                    let low_priority = lints\n                        .iter()\n                        .map(|(_, lint_config)| lint_config.priority().saturating_sub(1))\n                        .min()\n                        .unwrap_or(-1);\n                    diag.span_suggestion_verbose(\n                        config_span,\n                        format!(\n                            \"to have lints override the group set `{}` to a lower priority\",\n                            group.as_ref()\n                        ),\n                        format!(\"{{ level = {:?}, priority = {low_priority} }}\", group_config.level),\n                        Applicability::MaybeIncorrect,\n                    );\n                },\n            );\n        }\n    }\n}\n\nstruct LintTbls<'a> {\n    rust: Option<&'a DeTable<'a>>,\n    clippy: Option<&'a DeTable<'a>>,\n}\nfn get_lint_tbls<'a>(tbl: &'a DeTable<'a>) -> LintTbls<'a> {\n    if let Some(lints) = tbl.get(\"lints\")\n        && let Some(lints) = lints.get_ref().as_table()\n    {\n        let rust = lints.get(\"rust\").and_then(|x| x.get_ref().as_table());\n        let clippy = lints.get(\"clippy\").and_then(|x| x.get_ref().as_table());\n        LintTbls { rust, clippy }\n    } else {\n        LintTbls {\n            rust: None,\n            clippy: None,\n        }\n    }\n}\n\npub fn check(cx: &LateContext<'_>) {\n    if let Ok(file) = cx.tcx.sess.source_map().load_file(Path::new(\"Cargo.toml\"))\n        && let Some(src) = file.src.as_deref()\n        && let Ok(cargo_toml) = DeTable::parse(src)\n    {\n        let mut rustc_groups = FxHashSet::default();\n        let mut clippy_groups = FxHashSet::default();\n        for group in unerased_lint_store(cx.tcx.sess).get_all_group_names() {\n            match group.split_once(\"::\") {\n                None => {\n                    rustc_groups.insert(group);\n                },\n                Some((\"clippy\", group)) => {\n                    clippy_groups.insert(group);\n                },\n                _ => {},\n            }\n        }\n\n        let lints = get_lint_tbls(cargo_toml.get_ref());\n        if let Some(lints) = lints.rust {\n            check_table(cx, lints, &rustc_groups, &file);\n        }\n        if let Some(lints) = lints.clippy {\n            check_table(cx, lints, &clippy_groups, &file);\n        }\n        if let Some(tbl) = cargo_toml.get_ref().get(\"workspace\")\n            && let Some(tbl) = tbl.get_ref().as_table()\n        {\n            let lints = get_lint_tbls(tbl);\n            if let Some(lints) = lints.rust {\n                check_table(cx, lints, &rustc_groups, &file);\n            }\n            if let Some(lints) = lints.clippy {\n                check_table(cx, lints, &clippy_groups, &file);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/cargo/mod.rs",
    "content": "mod common_metadata;\nmod feature_name;\nmod lint_groups_priority;\nmod multiple_crate_versions;\nmod wildcard_dependencies;\n\nuse cargo_metadata::MetadataCommand;\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::is_lint_allowed;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::hir_id::CRATE_HIR_ID;\nuse rustc_lint::{LateContext, LateLintPass, Lint};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::DUMMY_SP;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks to see if all common metadata is defined in\n    /// `Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata\n    ///\n    /// ### Why is this bad?\n    /// It will be more difficult for users to discover the\n    /// purpose of the crate, and key information related to it.\n    ///\n    /// ### Example\n    /// ```toml\n    /// # This `Cargo.toml` is missing a description field:\n    /// [package]\n    /// name = \"clippy\"\n    /// version = \"0.0.212\"\n    /// repository = \"https://github.com/rust-lang/rust-clippy\"\n    /// readme = \"README.md\"\n    /// license = \"MIT OR Apache-2.0\"\n    /// keywords = [\"clippy\", \"lint\", \"plugin\"]\n    /// categories = [\"development-tools\", \"development-tools::cargo-plugins\"]\n    /// ```\n    ///\n    /// Should include a description field like:\n    ///\n    /// ```toml\n    /// # This `Cargo.toml` includes all common metadata\n    /// [package]\n    /// name = \"clippy\"\n    /// version = \"0.0.212\"\n    /// description = \"A bunch of helpful lints to avoid common pitfalls in Rust\"\n    /// repository = \"https://github.com/rust-lang/rust-clippy\"\n    /// readme = \"README.md\"\n    /// license = \"MIT OR Apache-2.0\"\n    /// keywords = [\"clippy\", \"lint\", \"plugin\"]\n    /// categories = [\"development-tools\", \"development-tools::cargo-plugins\"]\n    /// ```\n    #[clippy::version = \"1.32.0\"]\n    pub CARGO_COMMON_METADATA,\n    cargo,\n    \"common metadata is defined in `Cargo.toml`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for lint groups with the same priority as lints in the `Cargo.toml`\n    /// [`[lints]` table](https://doc.rust-lang.org/cargo/reference/manifest.html#the-lints-section).\n    ///\n    /// This lint will be removed once [cargo#12918](https://github.com/rust-lang/cargo/issues/12918)\n    /// is resolved.\n    ///\n    /// ### Why is this bad?\n    /// The order of lints in the `[lints]` is ignored, to have a lint override a group the\n    /// `priority` field needs to be used, otherwise the sort order is undefined.\n    ///\n    /// ### Known problems\n    /// Does not check lints inherited using `lints.workspace = true`\n    ///\n    /// ### Example\n    /// ```toml\n    /// # Passed as `--allow=clippy::similar_names --warn=clippy::pedantic`\n    /// # which results in `similar_names` being `warn`\n    /// [lints.clippy]\n    /// pedantic = \"warn\"\n    /// similar_names = \"allow\"\n    /// ```\n    /// Use instead:\n    /// ```toml\n    /// # Passed as `--warn=clippy::pedantic --allow=clippy::similar_names`\n    /// # which results in `similar_names` being `allow`\n    /// [lints.clippy]\n    /// pedantic = { level = \"warn\", priority = -1 }\n    /// similar_names = \"allow\"\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub LINT_GROUPS_PRIORITY,\n    correctness,\n    \"a lint group in `Cargo.toml` at the same priority as a lint\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks to see if multiple versions of a crate are being\n    /// used.\n    ///\n    /// ### Why is this bad?\n    /// This bloats the size of targets, and can lead to\n    /// confusing error messages when structs or traits are used interchangeably\n    /// between different versions of a crate.\n    ///\n    /// ### Known problems\n    /// Because this can be caused purely by the dependencies\n    /// themselves, it's not always possible to fix this issue.\n    /// In those cases, you can allow that specific crate using\n    /// the `allowed-duplicate-crates` configuration option.\n    ///\n    /// ### Example\n    /// ```toml\n    /// # This will pull in both winapi v0.3.x and v0.2.x, triggering a warning.\n    /// [dependencies]\n    /// ctrlc = \"=3.1.0\"\n    /// ansi_term = \"=0.11.0\"\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MULTIPLE_CRATE_VERSIONS,\n    cargo,\n    \"multiple versions of the same crate being used\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for negative feature names with prefix `no-` or `not-`\n    ///\n    /// ### Why is this bad?\n    /// Features are supposed to be additive, and negatively-named features violate it.\n    ///\n    /// ### Example\n    /// ```toml\n    /// # The `Cargo.toml` with negative feature names\n    /// [features]\n    /// default = []\n    /// no-abc = []\n    /// not-def = []\n    ///\n    /// ```\n    /// Use instead:\n    /// ```toml\n    /// [features]\n    /// default = [\"abc\", \"def\"]\n    /// abc = []\n    /// def = []\n    ///\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub NEGATIVE_FEATURE_NAMES,\n    cargo,\n    \"usage of a negative feature name\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for feature names with prefix `use-`, `with-` or suffix `-support`\n    ///\n    /// ### Why is this bad?\n    /// These prefixes and suffixes have no significant meaning.\n    ///\n    /// ### Example\n    /// ```toml\n    /// # The `Cargo.toml` with feature name redundancy\n    /// [features]\n    /// default = [\"use-abc\", \"with-def\", \"ghi-support\"]\n    /// use-abc = []  // redundant\n    /// with-def = []   // redundant\n    /// ghi-support = []   // redundant\n    /// ```\n    ///\n    /// Use instead:\n    /// ```toml\n    /// [features]\n    /// default = [\"abc\", \"def\", \"ghi\"]\n    /// abc = []\n    /// def = []\n    /// ghi = []\n    /// ```\n    ///\n    #[clippy::version = \"1.57.0\"]\n    pub REDUNDANT_FEATURE_NAMES,\n    cargo,\n    \"usage of a redundant feature name\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for wildcard dependencies in the `Cargo.toml`.\n    ///\n    /// ### Why is this bad?\n    /// [As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html),\n    /// it is highly unlikely that you work with any possible version of your dependency,\n    /// and wildcard dependencies would cause unnecessary breakage in the ecosystem.\n    ///\n    /// ### Example\n    /// ```toml\n    /// [dependencies]\n    /// regex = \"*\"\n    /// ```\n    /// Use instead:\n    /// ```toml\n    /// [dependencies]\n    /// # allow patch updates, but not minor or major version changes\n    /// some_crate_1 = \"~1.2.3\"\n    ///\n    /// # pin the version to a specific version\n    /// some_crate_2 = \"=1.2.3\"\n    /// ```\n    #[clippy::version = \"1.32.0\"]\n    pub WILDCARD_DEPENDENCIES,\n    cargo,\n    \"wildcard dependencies being used\"\n}\n\nimpl_lint_pass!(Cargo => [\n    CARGO_COMMON_METADATA,\n    LINT_GROUPS_PRIORITY,\n    MULTIPLE_CRATE_VERSIONS,\n    NEGATIVE_FEATURE_NAMES,\n    REDUNDANT_FEATURE_NAMES,\n    WILDCARD_DEPENDENCIES,\n]);\n\npub struct Cargo {\n    allowed_duplicate_crates: FxHashSet<String>,\n    ignore_publish: bool,\n}\n\nimpl Cargo {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            allowed_duplicate_crates: conf.allowed_duplicate_crates.iter().cloned().collect(),\n            ignore_publish: conf.cargo_ignore_publish,\n        }\n    }\n}\n\nimpl LateLintPass<'_> for Cargo {\n    fn check_crate(&mut self, cx: &LateContext<'_>) {\n        static NO_DEPS_LINTS: &[&Lint] = &[\n            CARGO_COMMON_METADATA,\n            REDUNDANT_FEATURE_NAMES,\n            NEGATIVE_FEATURE_NAMES,\n            WILDCARD_DEPENDENCIES,\n        ];\n        static WITH_DEPS_LINTS: &[&Lint] = &[MULTIPLE_CRATE_VERSIONS];\n\n        lint_groups_priority::check(cx);\n\n        if !NO_DEPS_LINTS\n            .iter()\n            .all(|&lint| is_lint_allowed(cx, lint, CRATE_HIR_ID))\n        {\n            match MetadataCommand::new().no_deps().exec() {\n                Ok(metadata) => {\n                    common_metadata::check(cx, &metadata, self.ignore_publish);\n                    feature_name::check(cx, &metadata);\n                    wildcard_dependencies::check(cx, &metadata);\n                },\n                Err(e) => {\n                    for lint in NO_DEPS_LINTS {\n                        span_lint(cx, lint, DUMMY_SP, format!(\"could not read cargo metadata: {e}\"));\n                    }\n                },\n            }\n        }\n\n        if !WITH_DEPS_LINTS\n            .iter()\n            .all(|&lint| is_lint_allowed(cx, lint, CRATE_HIR_ID))\n        {\n            match MetadataCommand::new().exec() {\n                Ok(metadata) => {\n                    multiple_crate_versions::check(cx, &metadata, &self.allowed_duplicate_crates);\n                },\n                Err(e) => {\n                    for lint in WITH_DEPS_LINTS {\n                        span_lint(cx, lint, DUMMY_SP, format!(\"could not read cargo metadata: {e}\"));\n                    }\n                },\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/cargo/multiple_crate_versions.rs",
    "content": "use cargo_metadata::{DependencyKind, Metadata, Node, Package, PackageId};\nuse clippy_utils::diagnostics::span_lint;\nuse itertools::Itertools;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::def_id::LOCAL_CRATE;\nuse rustc_lint::LateContext;\nuse rustc_span::DUMMY_SP;\n\nuse super::MULTIPLE_CRATE_VERSIONS;\n\npub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, allowed_duplicate_crates: &FxHashSet<String>) {\n    let local_name = cx.tcx.crate_name(LOCAL_CRATE);\n    let mut packages = metadata.packages.clone();\n    packages.sort_by(|a, b| a.name.cmp(&b.name));\n\n    if let Some(resolve) = &metadata.resolve\n        && let Some(local_id) = packages.iter().find_map(|p| {\n            // p.name contains the original crate names with dashes intact\n            // local_name contains the crate name as a namespace, with the dashes converted to underscores\n            // the code below temporarily rectifies this discrepancy\n            if p.name\n                .as_bytes()\n                .iter()\n                .map(|b| if b == &b'-' { &b'_' } else { b })\n                .eq(local_name.as_str().as_bytes())\n            {\n                Some(&p.id)\n            } else {\n                None\n            }\n        })\n    {\n        for (name, group) in &packages\n            .iter()\n            .filter(|p| !allowed_duplicate_crates.contains(&p.name))\n            .group_by(|p| &p.name)\n        {\n            let group: Vec<&Package> = group.collect();\n\n            if group.len() <= 1 {\n                continue;\n            }\n\n            if group.iter().all(|p| is_normal_dep(&resolve.nodes, local_id, &p.id)) {\n                let mut versions: Vec<_> = group.into_iter().map(|p| &p.version).collect();\n                versions.sort();\n                let versions = versions.iter().join(\", \");\n\n                span_lint(\n                    cx,\n                    MULTIPLE_CRATE_VERSIONS,\n                    DUMMY_SP,\n                    format!(\"multiple versions for dependency `{name}`: {versions}\"),\n                );\n            }\n        }\n    }\n}\n\nfn is_normal_dep(nodes: &[Node], local_id: &PackageId, dep_id: &PackageId) -> bool {\n    fn depends_on(node: &Node, dep_id: &PackageId) -> bool {\n        node.deps.iter().any(|dep| {\n            dep.pkg == *dep_id\n                && dep\n                    .dep_kinds\n                    .iter()\n                    .any(|info| matches!(info.kind, DependencyKind::Normal))\n        })\n    }\n\n    nodes\n        .iter()\n        .filter(|node| depends_on(node, dep_id))\n        .any(|node| node.id == *local_id || is_normal_dep(nodes, local_id, &node.id))\n}\n"
  },
  {
    "path": "clippy_lints/src/cargo/wildcard_dependencies.rs",
    "content": "use cargo_metadata::Metadata;\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_lint::LateContext;\nuse rustc_span::DUMMY_SP;\n\nuse super::WILDCARD_DEPENDENCIES;\n\npub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata) {\n    for dep in &metadata.packages[0].dependencies {\n        // VersionReq::any() does not work\n        if let Ok(wildcard_ver) = semver::VersionReq::parse(\"*\")\n            && let Some(ref source) = dep.source\n            && !source.starts_with(\"git\")\n            && dep.req == wildcard_ver\n        {\n            span_lint(\n                cx,\n                WILDCARD_DEPENDENCIES,\n                DUMMY_SP,\n                format!(\"wildcard dependency for `{}`\", dep.name),\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/as_pointer_underscore.rs",
    "content": "use rustc_errors::Applicability;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\npub fn check<'tcx>(cx: &LateContext<'tcx>, ty_into: Ty<'_>, cast_to_hir: &'tcx rustc_hir::Ty<'tcx>) {\n    if let rustc_hir::TyKind::Ptr(rustc_hir::MutTy { ty, .. }) = cast_to_hir.kind\n        && matches!(ty.kind, rustc_hir::TyKind::Infer(()))\n    {\n        clippy_utils::diagnostics::span_lint_and_sugg(\n            cx,\n            super::AS_POINTER_UNDERSCORE,\n            cast_to_hir.span,\n            \"using inferred pointer cast\",\n            \"use explicit type\",\n            ty_into.to_string(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/as_ptr_cast_mut.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::Mutability;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::AS_PTR_CAST_MUT;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) {\n    if let ty::RawPtr(ptrty, Mutability::Mut) = cast_to.kind()\n        && let ty::RawPtr(_, Mutability::Not) = cx.typeck_results().node_type(cast_expr.hir_id).kind()\n        && let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind\n        && method_name.ident.name == sym::as_ptr\n        && let Some(as_ptr_did) = cx\n            .typeck_results()\n            .type_dependent_def_id(cast_expr.peel_blocks().hir_id)\n        && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_identity()\n        && let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next()\n        && let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind()\n        && let Some(recv) = receiver.span.get_source_text(cx)\n    {\n        // `as_mut_ptr` might not exist\n        let applicability = Applicability::MaybeIncorrect;\n\n        span_lint_and_sugg(\n            cx,\n            AS_PTR_CAST_MUT,\n            expr.span,\n            format!(\"casting the result of `as_ptr` to *mut {ptrty}\"),\n            \"replace with\",\n            format!(\"{recv}.as_mut_ptr()\"),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/as_underscore.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, Ty, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::IsSuggestable;\n\nuse super::AS_UNDERSCORE;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ty: &'tcx Ty<'_>) {\n    if matches!(ty.kind, TyKind::Infer(())) {\n        span_lint_and_then(cx, AS_UNDERSCORE, expr.span, \"using `as _` conversion\", |diag| {\n            let ty_resolved = cx.typeck_results().expr_ty(expr);\n            if ty_resolved.is_suggestable(cx.tcx, true) {\n                diag.span_suggestion(\n                    ty.span,\n                    \"consider giving the type explicitly\",\n                    ty_resolved,\n                    Applicability::MachineApplicable,\n                );\n            } else {\n                diag.help(\"consider giving the type explicitly\");\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/borrow_as_ptr.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::sugg::has_enclosing_paren;\nuse clippy_utils::{get_parent_expr, is_expr_temporary_value, is_from_proc_macro, is_lint_allowed, msrvs, std_or_core};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::adjustment::{Adjust, AutoBorrow};\nuse rustc_span::BytePos;\n\nuse super::BORROW_AS_PTR;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    cast_expr: &'tcx Expr<'_>,\n    cast_to: &'tcx Ty<'_>,\n    msrv: Msrv,\n) -> bool {\n    if let TyKind::Ptr(target) = cast_to.kind\n        && !matches!(target.ty.kind, TyKind::TraitObject(..))\n        && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind\n        && !is_lint_allowed(cx, BORROW_AS_PTR, expr.hir_id)\n        // Fix #9884\n        && !is_expr_temporary_value(cx, e)\n        && !is_from_proc_macro(cx, expr)\n    {\n        let mut app = Applicability::MachineApplicable;\n        let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), \"..\", &mut app).0;\n\n        let (suggestion, span) = if msrv.meets(cx, msrvs::RAW_REF_OP) {\n            // Make sure that the span to be replaced doesn't include parentheses, that could break the\n            // suggestion.\n            let span = if has_enclosing_paren(snippet_with_applicability(cx, expr.span, \"\", &mut app)) {\n                expr.span\n                    .with_lo(expr.span.lo() + BytePos(1))\n                    .with_hi(expr.span.hi() - BytePos(1))\n            } else {\n                expr.span\n            };\n            (format!(\"&raw {} {snip}\", mutability.ptr_str()), span)\n        } else {\n            let Some(std_or_core) = std_or_core(cx) else {\n                return false;\n            };\n            let macro_name = match mutability {\n                Mutability::Not => \"addr_of\",\n                Mutability::Mut => \"addr_of_mut\",\n            };\n            (format!(\"{std_or_core}::ptr::{macro_name}!({snip})\"), expr.span)\n        };\n\n        span_lint_and_sugg(cx, BORROW_AS_PTR, span, \"borrow as raw pointer\", \"try\", suggestion, app);\n        return true;\n    }\n    false\n}\n\n/// Check for an implicit cast from reference to raw pointer outside an explicit `as`.\npub(super) fn check_implicit_cast(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if !expr.span.from_expansion()\n        && let ExprKind::AddrOf(BorrowKind::Ref, _, pointee) = expr.kind\n        && !matches!(get_parent_expr(cx, expr).map(|e| e.kind), Some(ExprKind::Cast(..)))\n        && let [deref, borrow] = cx.typeck_results().expr_adjustments(expr)\n        && matches!(deref.kind, Adjust::Deref(..))\n        && let Adjust::Borrow(AutoBorrow::RawPtr(mutability)) = borrow.kind\n        // Do not suggest taking a raw pointer to a temporary value\n        && !is_expr_temporary_value(cx, pointee)\n    {\n        span_lint_and_then(cx, BORROW_AS_PTR, expr.span, \"implicit borrow as raw pointer\", |diag| {\n            diag.span_suggestion_verbose(\n                expr.span.until(pointee.span),\n                \"use a raw pointer instead\",\n                format!(\"&raw {} \", mutability.ptr_str()),\n                Applicability::MachineApplicable,\n            );\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_abs_to_unsigned.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::CAST_ABS_TO_UNSIGNED;\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    cast_expr: &Expr<'_>,\n    cast_from: Ty<'_>,\n    cast_to: Ty<'_>,\n    msrv: Msrv,\n) {\n    if let ty::Int(from) = cast_from.kind()\n        && let ty::Uint(to) = cast_to.kind()\n        && let ExprKind::MethodCall(method_path, receiver, [], _) = cast_expr.kind\n        && method_path.ident.name == sym::abs\n        && msrv.meets(cx, msrvs::UNSIGNED_ABS)\n    {\n        let span = if from.bit_width() == to.bit_width() {\n            expr.span\n        } else {\n            // if the result of `.unsigned_abs` would be a different type, keep the cast\n            // e.g. `i64 -> usize`, `i16 -> u8`\n            cast_expr.span\n        };\n\n        span_lint_and_sugg(\n            cx,\n            CAST_ABS_TO_UNSIGNED,\n            span,\n            format!(\"casting the result of `{cast_from}::abs()` to {cast_to}\"),\n            \"replace with\",\n            format!(\"{}.unsigned_abs()\", Sugg::hir(cx, receiver, \"..\").maybe_paren()),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_enum_constructor.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::CAST_ENUM_CONSTRUCTOR;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>) {\n    if matches!(cast_from.kind(), ty::FnDef(..))\n        && let ExprKind::Path(path) = &cast_expr.kind\n        && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) = cx.qpath_res(path, cast_expr.hir_id)\n    {\n        span_lint(\n            cx,\n            CAST_ENUM_CONSTRUCTOR,\n            expr.span,\n            \"cast of an enum tuple constructor to an integer\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_lossless.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_in_const_context;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::is_isize_or_usize;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, QPath, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, FloatTy, Ty};\nuse rustc_span::hygiene;\n\nuse super::{CAST_LOSSLESS, utils};\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    cast_from_expr: &Expr<'_>,\n    cast_from: Ty<'_>,\n    cast_to: Ty<'_>,\n    cast_to_hir: &rustc_hir::Ty<'_>,\n    msrv: Msrv,\n) {\n    if !should_lint(cx, cast_from, cast_to, msrv) {\n        return;\n    }\n\n    // If the `as` is from a macro and the casting type is from macro input, whether it is lossless is\n    // dependent on the input\n    if expr.span.from_expansion() && !cast_to_hir.span.eq_ctxt(expr.span) {\n        return;\n    }\n\n    span_lint_and_then(\n        cx,\n        CAST_LOSSLESS,\n        expr.span,\n        format!(\"casts from `{cast_from}` to `{cast_to}` can be expressed infallibly using `From`\"),\n        |diag| {\n            diag.help(\"an `as` cast can become silently lossy if the types change in the future\");\n            let mut applicability = Applicability::MachineApplicable;\n            let from_sugg = Sugg::hir_with_context(cx, cast_from_expr, expr.span.ctxt(), \"<from>\", &mut applicability);\n            let Some(ty) = hygiene::walk_chain(cast_to_hir.span, expr.span.ctxt()).get_source_text(cx) else {\n                return;\n            };\n            match cast_to_hir.kind {\n                TyKind::Infer(()) => {\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        \"use `Into::into` instead\",\n                        format!(\"{}.into()\", from_sugg.maybe_paren()),\n                        applicability,\n                    );\n                },\n                // Don't suggest `A<_>::B::From(x)` or `macro!()::from(x)`\n                kind if matches!(kind, TyKind::Path(QPath::Resolved(_, path)) if path.segments.iter().any(|s| s.args.is_some()))\n                    || !cast_to_hir.span.eq_ctxt(expr.span) =>\n                {\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        format!(\"use `<{ty}>::from` instead\"),\n                        format!(\"<{ty}>::from({from_sugg})\"),\n                        applicability,\n                    );\n                },\n                _ => {\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        format!(\"use `{ty}::from` instead\"),\n                        format!(\"{ty}::from({from_sugg})\"),\n                        applicability,\n                    );\n                },\n            }\n        },\n    );\n}\n\nfn should_lint(cx: &LateContext<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>, msrv: Msrv) -> bool {\n    // Do not suggest using From in consts/statics until it is valid to do so (see #2267).\n    if is_in_const_context(cx) {\n        return false;\n    }\n\n    match (\n        utils::int_ty_to_nbits(cx.tcx, cast_from),\n        utils::int_ty_to_nbits(cx.tcx, cast_to),\n    ) {\n        (Some(from_nbits), Some(to_nbits)) => {\n            let cast_signed_to_unsigned = cast_from.is_signed() && !cast_to.is_signed();\n            !is_isize_or_usize(cast_from)\n                && !is_isize_or_usize(cast_to)\n                && from_nbits < to_nbits\n                && !cast_signed_to_unsigned\n        },\n\n        (Some(from_nbits), None) => {\n            // FIXME: handle `f16` and `f128`\n            let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() {\n                32\n            } else {\n                64\n            };\n            !is_isize_or_usize(cast_from) && from_nbits < to_nbits\n        },\n        (None, Some(_)) if cast_from.is_bool() && msrv.meets(cx, msrvs::FROM_BOOL) => true,\n        _ => matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64)),\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_nan_to_int.rs",
    "content": "use super::CAST_NAN_TO_INT;\n\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_note;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, from_ty: Ty<'_>, to_ty: Ty<'_>) {\n    if from_ty.is_floating_point() && to_ty.is_integral() && is_known_nan(cx, cast_expr) {\n        span_lint_and_note(\n            cx,\n            CAST_NAN_TO_INT,\n            expr.span,\n            format!(\"casting a known NaN to {to_ty}\"),\n            None,\n            \"this always evaluates to 0\",\n        );\n    }\n}\n\nfn is_known_nan(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    match ConstEvalCtxt::new(cx).eval(e) {\n        // FIXME(f16_f128): add these types when nan checks are available on all platforms\n        Some(Constant::F64(n)) => n.is_nan(),\n        Some(Constant::F32(n)) => n.is_nan(),\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_possible_truncation.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::source::snippet;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};\nuse clippy_utils::{expr_or_init, is_in_const_context, sym};\nuse rustc_abi::IntegerType;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, FloatTy, Ty};\nuse rustc_span::Span;\n\nuse super::{CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION, utils};\n\nfn constant_int(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u128> {\n    if let Some(Constant::Int(c)) = ConstEvalCtxt::new(cx).eval(expr) {\n        Some(c)\n    } else {\n        None\n    }\n}\n\nfn get_constant_bits(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u64> {\n    constant_int(cx, expr).map(|c| u64::from(128 - c.leading_zeros()))\n}\n\nfn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: bool) -> u64 {\n    match expr_or_init(cx, expr).kind {\n        ExprKind::Cast(inner, _) => apply_reductions(cx, nbits, inner, signed),\n        ExprKind::Block(block, _) => block.expr.map_or(nbits, |e| apply_reductions(cx, nbits, e, signed)),\n        ExprKind::Binary(op, left, right) => match op.node {\n            BinOpKind::Div => {\n                apply_reductions(cx, nbits, left, signed).saturating_sub(if signed {\n                    // let's be conservative here\n                    0\n                } else {\n                    // by dividing by 1, we remove 0 bits, etc.\n                    get_constant_bits(cx, right).map_or(0, |b| b.saturating_sub(1))\n                })\n            },\n            BinOpKind::Rem => get_constant_bits(cx, right)\n                .unwrap_or(u64::MAX)\n                .min(apply_reductions(cx, nbits, left, signed)),\n            BinOpKind::BitAnd => get_constant_bits(cx, right)\n                .unwrap_or(u64::MAX)\n                .min(get_constant_bits(cx, left).unwrap_or(u64::MAX))\n                .min(apply_reductions(cx, nbits, right, signed))\n                .min(apply_reductions(cx, nbits, left, signed)),\n            BinOpKind::Shr => apply_reductions(cx, nbits, left, signed)\n                .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).unwrap_or_default())),\n            _ => nbits,\n        },\n        ExprKind::MethodCall(method, left, [right], _) => {\n            if signed {\n                return nbits;\n            }\n            let max_bits = if method.ident.name == sym::min {\n                get_constant_bits(cx, right)\n            } else {\n                None\n            };\n            apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::MAX))\n        },\n        ExprKind::MethodCall(method, _, [lo, hi], _) => {\n            if method.ident.name == sym::clamp\n                //FIXME: make this a diagnostic item\n                && let (Some(lo_bits), Some(hi_bits)) = (get_constant_bits(cx, lo), get_constant_bits(cx, hi))\n            {\n                return lo_bits.max(hi_bits);\n            }\n            nbits\n        },\n        ExprKind::MethodCall(method, _value, [], _) => {\n            if method.ident.name == sym::signum {\n                0 // do not lint if cast comes from a `signum` function\n            } else {\n                nbits\n            }\n        },\n        _ => nbits,\n    }\n}\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    cast_expr: &Expr<'_>,\n    cast_from: Ty<'_>,\n    cast_to: Ty<'_>,\n    cast_to_span: Span,\n) {\n    let msg = match (cast_from.kind(), utils::int_ty_to_nbits(cx.tcx, cast_to)) {\n        (ty::Int(_) | ty::Uint(_), Some(to_nbits)) => {\n            let from_nbits = apply_reductions(\n                cx,\n                utils::int_ty_to_nbits(cx.tcx, cast_from).unwrap(),\n                cast_expr,\n                cast_from.is_signed(),\n            );\n\n            let (should_lint, suffix) = match (is_isize_or_usize(cast_from), is_isize_or_usize(cast_to)) {\n                (true, true) | (false, false) => (to_nbits < from_nbits, \"\"),\n                (true, false) => (\n                    to_nbits <= 32,\n                    if to_nbits == 32 {\n                        \" on targets with 64-bit wide pointers\"\n                    } else {\n                        \"\"\n                    },\n                ),\n                (false, true) => (from_nbits == 64, \" on targets with 32-bit wide pointers\"),\n            };\n\n            if !should_lint {\n                return;\n            }\n\n            format!(\"casting `{cast_from}` to `{cast_to}` may truncate the value{suffix}\")\n        },\n\n        (ty::Adt(def, _), Some(to_nbits)) if def.is_enum() => {\n            let (from_nbits, variant) = if let ExprKind::Path(p) = &cast_expr.kind\n                && let Res::Def(DefKind::Ctor(..), id) = cx.qpath_res(p, cast_expr.hir_id)\n            {\n                let i = def.variant_index_with_ctor_id(id);\n                let variant = def.variant(i);\n                let nbits = utils::enum_value_nbits(get_discriminant_value(cx.tcx, *def, i));\n                (nbits, Some(variant))\n            } else {\n                (utils::enum_ty_to_nbits(*def, cx.tcx), None)\n            };\n\n            let cast_from_ptr_size = def.repr().int.is_none_or(|ty| matches!(ty, IntegerType::Pointer(_),));\n            let suffix = match (cast_from_ptr_size, is_isize_or_usize(cast_to)) {\n                (_, false) if from_nbits > to_nbits => \"\",\n                (false, true) if from_nbits > 64 => \"\",\n                (false, true) if from_nbits > 32 => \" on targets with 32-bit wide pointers\",\n                _ => return,\n            };\n\n            if let Some(variant) = variant {\n                span_lint(\n                    cx,\n                    CAST_ENUM_TRUNCATION,\n                    expr.span,\n                    format!(\n                        \"casting `{cast_from}::{}` to `{cast_to}` will truncate the value{suffix}\",\n                        variant.name,\n                    ),\n                );\n                return;\n            }\n            format!(\"casting `{cast_from}` to `{cast_to}` may truncate the value{suffix}\")\n        },\n\n        (ty::Float(_), Some(_)) => {\n            format!(\"casting `{cast_from}` to `{cast_to}` may truncate the value\")\n        },\n\n        (ty::Float(FloatTy::F64), None) if matches!(cast_to.kind(), &ty::Float(FloatTy::F32)) => {\n            \"casting `f64` to `f32` may truncate the value\".to_string()\n        },\n\n        _ => return,\n    };\n\n    span_lint_and_then(cx, CAST_POSSIBLE_TRUNCATION, expr.span, msg, |diag| {\n        diag.help(\"if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\");\n        // TODO: Remove the condition for const contexts when `try_from` and other commonly used methods\n        // become const fn.\n        if !is_in_const_context(cx) && !cast_from.is_floating_point() {\n            offer_suggestion(cx, expr, cast_expr, cast_to_span, diag);\n        }\n    });\n}\n\nfn offer_suggestion(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    cast_expr: &Expr<'_>,\n    cast_to_span: Span,\n    diag: &mut Diag<'_, ()>,\n) {\n    let cast_to_snip = snippet(cx, cast_to_span, \"..\");\n    let suggestion = if cast_to_snip == \"_\" {\n        format!(\"{}.try_into()\", Sugg::hir(cx, cast_expr, \"..\").maybe_paren())\n    } else {\n        format!(\"{cast_to_snip}::try_from({})\", Sugg::hir(cx, cast_expr, \"..\"))\n    };\n\n    diag.span_suggestion_verbose(\n        expr.span,\n        \"... or use `try_from` and handle the error accordingly\",\n        suggestion,\n        Applicability::Unspecified,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_possible_wrap.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::sugg::Sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\nuse super::{CAST_POSSIBLE_WRAP, utils};\n\n// this should be kept in sync with the allowed bit widths of `usize` and `isize`\nconst ALLOWED_POINTER_SIZES: [u64; 3] = [16, 32, 64];\n\n// whether the lint should be emitted, and the required pointer size, if it matters\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\nenum EmitState {\n    NoLint,\n    LintAlways,\n    LintOnPtrSize(u64),\n}\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    cast_op: &Expr<'_>,\n    cast_from: Ty<'_>,\n    cast_to: Ty<'_>,\n    msrv: Msrv,\n) {\n    let (Some(from_nbits), Some(to_nbits)) = (\n        utils::int_ty_to_nbits(cx.tcx, cast_from),\n        utils::int_ty_to_nbits(cx.tcx, cast_to),\n    ) else {\n        return;\n    };\n\n    // emit a lint if a cast is:\n    // 1. unsigned to signed\n    // and\n    // 2. either:\n    //\n    //    2a. between two types of constant size that are always the same size\n    //    2b. between one target-dependent size and one constant size integer,\n    //        and the constant integer is in the allowed set of target dependent sizes\n    //        (the ptr size could be chosen to be the same as the constant size)\n\n    if cast_from.is_signed() || !cast_to.is_signed() {\n        return;\n    }\n\n    let should_lint = match (cast_from.is_ptr_sized_integral(), cast_to.is_ptr_sized_integral()) {\n        (true, true) => {\n            // casts between two ptr sized integers are trivially always the same size\n            // so do not depend on any specific pointer size to be the same\n            EmitState::LintAlways\n        },\n        (true, false) => {\n            // the first type is `usize` and the second is a constant sized signed integer\n            if ALLOWED_POINTER_SIZES.contains(&to_nbits) {\n                EmitState::LintOnPtrSize(to_nbits)\n            } else {\n                EmitState::NoLint\n            }\n        },\n        (false, true) => {\n            // the first type is a constant sized unsigned integer, and the second is `isize`\n            if ALLOWED_POINTER_SIZES.contains(&from_nbits) {\n                EmitState::LintOnPtrSize(from_nbits)\n            } else {\n                EmitState::NoLint\n            }\n        },\n        (false, false) => {\n            // the types are both a constant known size\n            // and do not depend on any specific pointer size to be the same\n            if from_nbits == to_nbits {\n                EmitState::LintAlways\n            } else {\n                EmitState::NoLint\n            }\n        },\n    };\n\n    let message = match should_lint {\n        EmitState::NoLint => return,\n        EmitState::LintAlways => format!(\"casting `{cast_from}` to `{cast_to}` may wrap around the value\"),\n        EmitState::LintOnPtrSize(ptr_size) => format!(\n            \"casting `{cast_from}` to `{cast_to}` may wrap around the value on targets with {ptr_size}-bit wide pointers\",\n        ),\n    };\n\n    span_lint_and_then(cx, CAST_POSSIBLE_WRAP, expr.span, message, |diag| {\n        if let EmitState::LintOnPtrSize(16) = should_lint {\n            diag\n                .note(\"`usize` and `isize` may be as small as 16 bits on some platforms\")\n                .note(\"for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types\");\n        }\n\n        if msrv.meets(cx, msrvs::INTEGER_SIGN_CAST)\n            && let Some(cast) = utils::is_signedness_cast(cast_from, cast_to)\n        {\n            let method = match cast {\n                utils::CastTo::Signed => \"cast_signed()\",\n                utils::CastTo::Unsigned => \"cast_unsigned()\",\n            };\n            let mut app = Applicability::MaybeIncorrect;\n            let sugg = Sugg::hir_with_context(cx, cast_op, expr.span.ctxt(), \"..\", &mut app);\n\n            diag.span_suggestion(\n                expr.span,\n                format!(\"if this is intentional, use `{method}` instead\"),\n                format!(\"{}.{method}\", sugg.maybe_paren()),\n                app,\n            );\n        }\n    });\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_precision_loss.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::ty::is_isize_or_usize;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, FloatTy, Ty};\n\nuse super::{CAST_PRECISION_LOSS, utils};\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {\n    let Some(from_nbits) = utils::int_ty_to_nbits(cx.tcx, cast_from) else {\n        return;\n    };\n\n    // FIXME: handle `f16` and `f128`\n    let to_nbits = match cast_to.kind() {\n        ty::Float(f @ (FloatTy::F32 | FloatTy::F64)) => f.bit_width(),\n        _ => return,\n    };\n\n    if !(is_isize_or_usize(cast_from) || from_nbits >= to_nbits) {\n        return;\n    }\n\n    let cast_to_f64 = to_nbits == 64;\n    let mantissa_nbits = if cast_to_f64 { 52 } else { 23 };\n\n    let has_width = if is_isize_or_usize(cast_from) {\n        \"can be up to 64 bits wide depending on the target architecture\".to_owned()\n    } else {\n        format!(\"is {from_nbits} bits wide\")\n    };\n\n    span_lint(\n        cx,\n        CAST_PRECISION_LOSS,\n        expr.span,\n        format!(\n            \"casting `{cast_from}` to `{cast_to}` may cause a loss of precision \\\n            (`{cast_from}` {has_width}, \\\n             but `{cast_to}`'s mantissa is only {mantissa_nbits} bits wide)\",\n        ),\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_ptr_alignment.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::ty::is_c_void;\nuse clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, sym};\nuse rustc_hir::{Expr, ExprKind, GenericArg};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::CAST_PTR_ALIGNMENT;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) {\n    lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);\n}\n\npub(super) fn check_cast_method(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let ExprKind::MethodCall(method_path, self_arg, [], _) = &expr.kind\n        && method_path.ident.name == sym::cast\n        && let Some(generic_args) = method_path.args\n        && let [GenericArg::Type(cast_to)] = generic_args.args\n        // There probably is no obvious reason to do this, just to be consistent with `as` cases.\n        && !is_hir_ty_cfg_dependant(cx, cast_to.as_unambig_ty())\n    {\n        let (cast_from, cast_to) = (cx.typeck_results().expr_ty(self_arg), cx.typeck_results().expr_ty(expr));\n        lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);\n    }\n}\n\nfn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) {\n    if let ty::RawPtr(from_ptr_ty, _) = *cast_from.kind()\n        && let ty::RawPtr(to_ptr_ty, _) = *cast_to.kind()\n        && let Ok(from_layout) = cx.layout_of(from_ptr_ty)\n        && let Ok(to_layout) = cx.layout_of(to_ptr_ty)\n        && from_layout.align.abi < to_layout.align.abi\n        // with c_void, we inherently need to trust the user\n        && !is_c_void(cx, from_ptr_ty)\n        // when casting from a ZST, we don't know enough to properly lint\n        && !from_layout.is_zst()\n        && !is_used_as_unaligned(cx, expr)\n    {\n        span_lint(\n            cx,\n            CAST_PTR_ALIGNMENT,\n            expr.span,\n            format!(\n                \"casting from `{cast_from}` to a more-strictly-aligned pointer (`{cast_to}`) ({} < {} bytes)\",\n                from_layout.align.bytes(),\n                to_layout.align.bytes(),\n            ),\n        );\n    }\n}\n\nfn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    let Some(parent) = get_parent_expr(cx, e) else {\n        return false;\n    };\n    match parent.kind {\n        ExprKind::MethodCall(name, self_arg, ..) if self_arg.hir_id == e.hir_id => {\n            if matches!(name.ident.name, sym::read_unaligned | sym::write_unaligned)\n                && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)\n                && let Some(def_id) = cx.tcx.impl_of_assoc(def_id)\n                && cx.tcx.type_of(def_id).instantiate_identity().is_raw_ptr()\n            {\n                true\n            } else {\n                false\n            }\n        },\n        ExprKind::Call(func, [arg, ..]) if arg.hir_id == e.hir_id => {\n            if let ExprKind::Path(path) = &func.kind\n                && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()\n                && let Some(name) = cx.tcx.get_diagnostic_name(def_id)\n                && matches!(\n                    name,\n                    sym::ptr_write_unaligned\n                        | sym::ptr_read_unaligned\n                        | sym::intrinsics_unaligned_volatile_load\n                        | sym::intrinsics_unaligned_volatile_store\n                )\n            {\n                true\n            } else {\n                false\n            }\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_sign_loss.rs",
    "content": "use std::convert::Infallible;\nuse std::ops::ControlFlow;\n\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::visitors::{Descend, for_each_expr_without_closures};\nuse clippy_utils::{method_chain_args, sext, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::Symbol;\n\nuse super::{CAST_SIGN_LOSS, utils};\n\n/// A list of methods that can never return a negative value.\n/// Includes methods that panic rather than returning a negative value.\n///\n/// Methods that can overflow and return a negative value must not be included in this list,\n/// because casting their return values can still result in sign loss.\nconst METHODS_RET_POSITIVE: &[Symbol] = &[\n    sym::checked_abs,\n    sym::saturating_abs,\n    sym::isqrt,\n    sym::checked_isqrt,\n    sym::rem_euclid,\n    sym::checked_rem_euclid,\n    sym::wrapping_rem_euclid,\n];\n\n/// A list of methods that act like `pow()`. See `pow_call_result_sign()` for details.\n///\n/// Methods that can overflow and return a negative value must not be included in this list,\n/// because casting their return values can still result in sign loss.\nconst METHODS_POW: &[Symbol] = &[sym::pow, sym::saturating_pow, sym::checked_pow];\n\n/// A list of methods that act like `unwrap()`, and don't change the sign of the inner value.\nconst METHODS_UNWRAP: &[Symbol] = &[sym::unwrap, sym::unwrap_unchecked, sym::expect, sym::into_ok];\n\npub(super) fn check<'cx>(\n    cx: &LateContext<'cx>,\n    expr: &Expr<'_>,\n    cast_op: &Expr<'_>,\n    cast_from: Ty<'cx>,\n    cast_to: Ty<'_>,\n    msrv: Msrv,\n) {\n    if should_lint(cx, cast_op, cast_from, cast_to) {\n        span_lint_and_then(\n            cx,\n            CAST_SIGN_LOSS,\n            expr.span,\n            format!(\"casting `{cast_from}` to `{cast_to}` may lose the sign of the value\"),\n            |diag| {\n                if msrv.meets(cx, msrvs::INTEGER_SIGN_CAST)\n                    && let Some(cast) = utils::is_signedness_cast(cast_from, cast_to)\n                {\n                    let method = match cast {\n                        utils::CastTo::Signed => \"cast_signed()\",\n                        utils::CastTo::Unsigned => \"cast_unsigned()\",\n                    };\n                    let mut app = Applicability::MaybeIncorrect;\n                    let sugg = Sugg::hir_with_context(cx, cast_op, expr.span.ctxt(), \"..\", &mut app);\n\n                    diag.span_suggestion(\n                        expr.span,\n                        format!(\"if this is intentional, use `{method}` instead\"),\n                        format!(\"{}.{method}\", sugg.maybe_paren()),\n                        app,\n                    );\n                }\n            },\n        );\n    }\n}\n\nfn should_lint<'cx>(cx: &LateContext<'cx>, cast_op: &Expr<'_>, cast_from: Ty<'cx>, cast_to: Ty<'_>) -> bool {\n    match (cast_from.is_integral(), cast_to.is_integral()) {\n        (true, true) => {\n            if !cast_from.is_signed() || cast_to.is_signed() {\n                return false;\n            }\n\n            // Don't lint if `cast_op` is known to be positive, ignoring overflow.\n            if let Sign::ZeroOrPositive = expr_sign(cx, cast_op, cast_from) {\n                return false;\n            }\n\n            if let Sign::ZeroOrPositive = expr_muldiv_sign(cx, cast_op) {\n                return false;\n            }\n\n            if let Sign::ZeroOrPositive = expr_add_sign(cx, cast_op) {\n                return false;\n            }\n\n            true\n        },\n\n        (false, true) => !cast_to.is_signed(),\n\n        (_, _) => false,\n    }\n}\n\nfn get_const_signed_int_eval<'cx>(\n    cx: &LateContext<'cx>,\n    expr: &Expr<'_>,\n    ty: impl Into<Option<Ty<'cx>>>,\n) -> Option<i128> {\n    let ty = ty.into().unwrap_or_else(|| cx.typeck_results().expr_ty(expr));\n\n    if let Constant::Int(n) = ConstEvalCtxt::new(cx).eval(expr)?\n        && let ty::Int(ity) = *ty.kind()\n    {\n        return Some(sext(cx.tcx, n, ity));\n    }\n    None\n}\n\nfn get_const_unsigned_int_eval<'cx>(\n    cx: &LateContext<'cx>,\n    expr: &Expr<'_>,\n    ty: impl Into<Option<Ty<'cx>>>,\n) -> Option<u128> {\n    let ty = ty.into().unwrap_or_else(|| cx.typeck_results().expr_ty(expr));\n\n    if let Constant::Int(n) = ConstEvalCtxt::new(cx).eval(expr)?\n        && let ty::Uint(_ity) = *ty.kind()\n    {\n        return Some(n);\n    }\n    None\n}\n\n#[derive(Copy, Clone, Debug, Eq, PartialEq)]\nenum Sign {\n    ZeroOrPositive,\n    Negative,\n    Uncertain,\n}\n\nfn expr_sign<'cx, 'tcx>(cx: &LateContext<'cx>, mut expr: &'tcx Expr<'tcx>, ty: impl Into<Option<Ty<'cx>>>) -> Sign {\n    // Try evaluate this expr first to see if it's positive\n    if let Some(val) = get_const_signed_int_eval(cx, expr, ty) {\n        return if val >= 0 { Sign::ZeroOrPositive } else { Sign::Negative };\n    }\n    if let Some(_val) = get_const_unsigned_int_eval(cx, expr, None) {\n        return Sign::ZeroOrPositive;\n    }\n\n    // Calling on methods that always return non-negative values.\n    if let ExprKind::MethodCall(path, caller, args, ..) = expr.kind {\n        let mut method_name = path.ident.name;\n\n        // Peel unwrap(), expect(), etc.\n        while let Some(&found_name) = METHODS_UNWRAP.iter().find(|&name| &method_name == name)\n            && let Some(arglist) = method_chain_args(expr, &[found_name])\n            && let ExprKind::MethodCall(inner_path, recv, ..) = &arglist[0].0.kind\n        {\n            // The original type has changed, but we can't use `ty` here anyway, because it has been\n            // moved.\n            method_name = inner_path.ident.name;\n            expr = recv;\n        }\n\n        if METHODS_POW.contains(&method_name)\n            && let [arg] = args\n        {\n            return pow_call_result_sign(cx, caller, arg);\n        } else if METHODS_RET_POSITIVE.contains(&method_name) {\n            return Sign::ZeroOrPositive;\n        }\n    }\n\n    Sign::Uncertain\n}\n\n/// Return the sign of the `pow` call's result, ignoring overflow.\n///\n/// If the base is positive, the result is always positive.\n/// If the exponent is a even number, the result is always positive,\n/// Otherwise, if the base is negative, and the exponent is an odd number, the result is always\n/// negative.\n///\n/// Otherwise, returns [`Sign::Uncertain`].\nfn pow_call_result_sign(cx: &LateContext<'_>, base: &Expr<'_>, exponent: &Expr<'_>) -> Sign {\n    let base_sign = expr_sign(cx, base, None);\n\n    // Rust's integer pow() functions take an unsigned exponent.\n    let exponent_val = get_const_unsigned_int_eval(cx, exponent, None);\n    let exponent_is_even = exponent_val.map(|val| val.is_multiple_of(2));\n\n    match (base_sign, exponent_is_even) {\n        // Non-negative bases always return non-negative results, ignoring overflow.\n        (Sign::ZeroOrPositive, _) |\n        // Any base raised to an even exponent is non-negative.\n        // These both hold even if we don't know the value of the base.\n        (_, Some(true))\n            => Sign::ZeroOrPositive,\n\n        // A negative base raised to an odd exponent is non-negative.\n        (Sign::Negative, Some(false)) => Sign::Negative,\n\n        // Negative/unknown base to an unknown exponent, or unknown base to an odd exponent.\n        // Could be negative or positive depending on the actual values.\n        (Sign::Negative | Sign::Uncertain, None) |\n        (Sign::Uncertain, Some(false)) => Sign::Uncertain,\n    }\n}\n\n/// Peels binary operators such as [`BinOpKind::Mul`] or [`BinOpKind::Rem`],\n/// where the result could always be positive. See [`exprs_with_muldiv_binop_peeled()`] for details.\n///\n/// Returns the sign of the list of peeled expressions.\nfn expr_muldiv_sign(cx: &LateContext<'_>, expr: &Expr<'_>) -> Sign {\n    let mut negative_count = 0;\n\n    // Peel off possible binary expressions, for example:\n    // x * x / y => [x, x, y]\n    // a % b => [a]\n    let exprs = exprs_with_muldiv_binop_peeled(expr);\n    for expr in exprs {\n        match expr_sign(cx, expr, None) {\n            Sign::Negative => negative_count += 1,\n            // A mul/div is:\n            // - uncertain if there are any uncertain values (because they could be negative or positive),\n            Sign::Uncertain => return Sign::Uncertain,\n            Sign::ZeroOrPositive => (),\n        }\n    }\n\n    // A mul/div is:\n    // - negative if there are an odd number of negative values,\n    // - positive or zero otherwise.\n    if negative_count % 2 == 1 {\n        Sign::Negative\n    } else {\n        Sign::ZeroOrPositive\n    }\n}\n\n/// Peels binary operators such as [`BinOpKind::Add`], where the result could always be positive.\n/// See [`exprs_with_add_binop_peeled()`] for details.\n///\n/// Returns the sign of the list of peeled expressions.\nfn expr_add_sign(cx: &LateContext<'_>, expr: &Expr<'_>) -> Sign {\n    let mut negative_count = 0;\n    let mut positive_count = 0;\n\n    // Peel off possible binary expressions, for example:\n    // a + b + c => [a, b, c]\n    let exprs = exprs_with_add_binop_peeled(expr);\n    for expr in exprs {\n        match expr_sign(cx, expr, None) {\n            Sign::Negative => negative_count += 1,\n            // A sum is:\n            // - uncertain if there are any uncertain values (because they could be negative or positive),\n            Sign::Uncertain => return Sign::Uncertain,\n            Sign::ZeroOrPositive => positive_count += 1,\n        }\n    }\n\n    // A sum is:\n    // - positive or zero if there are only positive (or zero) values,\n    // - negative if there are only negative (or zero) values, or\n    // - uncertain if there are both.\n    // We could split Zero out into its own variant, but we don't yet.\n    if negative_count == 0 {\n        Sign::ZeroOrPositive\n    } else if positive_count == 0 {\n        Sign::Negative\n    } else {\n        Sign::Uncertain\n    }\n}\n\n/// Peels binary operators such as [`BinOpKind::Mul`], [`BinOpKind::Div`] or [`BinOpKind::Rem`],\n/// where the result depends on:\n///\n/// - the number of negative values in the entire expression, or\n/// - the number of negative values on the left hand side of the expression.\n///\n/// Ignores overflow.\n///\n///\n/// Expressions using other operators are preserved, so we can try to evaluate them later.\nfn exprs_with_muldiv_binop_peeled<'e>(expr: &'e Expr<'_>) -> Vec<&'e Expr<'e>> {\n    let mut res = vec![];\n\n    for_each_expr_without_closures(expr, |sub_expr| -> ControlFlow<Infallible, Descend> {\n        // We don't check for mul/div/rem methods here, but we could.\n        if let ExprKind::Binary(op, lhs, _rhs) = sub_expr.kind {\n            if matches!(op.node, BinOpKind::Mul | BinOpKind::Div) {\n                // For binary operators where both sides contribute to the sign of the result,\n                // collect all their operands, recursively. This ignores overflow.\n                ControlFlow::Continue(Descend::Yes)\n            } else if matches!(op.node, BinOpKind::Rem | BinOpKind::Shr) {\n                // For binary operators where the left hand side determines the sign of the result,\n                // only collect that side, recursively. Overflow panics, so this always holds.\n                //\n                // Large left shifts turn negatives into zeroes, so we can't use it here.\n                //\n                // > Given remainder = dividend % divisor, the remainder will have the same sign as the dividend\n                // > ...\n                // > Arithmetic right shift on signed integer types\n                // https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators\n\n                // We want to descend into the lhs, but skip the rhs.\n                // That's tricky to do using for_each_expr(), so we just keep the lhs intact.\n                res.push(lhs);\n                ControlFlow::Continue(Descend::No)\n            } else {\n                // The sign of the result of other binary operators depends on the values of the operands,\n                // so try to evaluate the expression.\n                res.push(sub_expr);\n                ControlFlow::Continue(Descend::No)\n            }\n        } else {\n            // For other expressions, including unary operators and constants, try to evaluate the expression.\n            res.push(sub_expr);\n            ControlFlow::Continue(Descend::No)\n        }\n    });\n\n    res\n}\n\n/// Peels binary operators such as [`BinOpKind::Add`], where the result depends on:\n///\n/// - all the expressions being positive, or\n/// - all the expressions being negative.\n///\n/// Ignores overflow.\n///\n/// Expressions using other operators are preserved, so we can try to evaluate them later.\nfn exprs_with_add_binop_peeled<'e>(expr: &'e Expr<'_>) -> Vec<&'e Expr<'e>> {\n    let mut res = vec![];\n\n    for_each_expr_without_closures(expr, |sub_expr| -> ControlFlow<Infallible, Descend> {\n        // We don't check for add methods here, but we could.\n        if let ExprKind::Binary(op, _lhs, _rhs) = sub_expr.kind {\n            if matches!(op.node, BinOpKind::Add) {\n                // For binary operators where both sides contribute to the sign of the result,\n                // collect all their operands, recursively. This ignores overflow.\n                ControlFlow::Continue(Descend::Yes)\n            } else {\n                // The sign of the result of other binary operators depends on the values of the operands,\n                // so try to evaluate the expression.\n                res.push(sub_expr);\n                ControlFlow::Continue(Descend::No)\n            }\n        } else {\n            // For other expressions, including unary operators and constants, try to evaluate the expression.\n            res.push(sub_expr);\n            ControlFlow::Continue(Descend::No)\n        }\n    });\n\n    res\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_slice_different_sizes.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source;\nuse rustc_ast::Mutability;\nuse rustc_hir::{Expr, ExprKind, Node};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_middle::ty::{self, Ty, TypeAndMut};\n\nuse super::CAST_SLICE_DIFFERENT_SIZES;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Msrv) {\n    // if this cast is the child of another cast expression then don't emit something for it, the full\n    // chain will be analyzed\n    if is_child_of_cast(cx, expr) {\n        return;\n    }\n\n    if let Some(CastChainInfo {\n        left_cast,\n        start_ty,\n        end_ty,\n    }) = expr_cast_chain_tys(cx, expr)\n        && let (Ok(from_layout), Ok(to_layout)) = (cx.layout_of(start_ty.ty), cx.layout_of(end_ty.ty))\n    {\n        let from_size = from_layout.size.bytes();\n        let to_size = to_layout.size.bytes();\n        if from_size != to_size && from_size != 0 && to_size != 0 && msrv.meets(cx, msrvs::PTR_SLICE_RAW_PARTS) {\n            span_lint_and_then(\n                cx,\n                CAST_SLICE_DIFFERENT_SIZES,\n                expr.span,\n                format!(\n                    \"casting between raw pointers to `[{}]` (element size {from_size}) and `[{}]` (element size {to_size}) does not adjust the count\",\n                    start_ty.ty, end_ty.ty,\n                ),\n                |diag| {\n                    let ptr_snippet = source::snippet(cx, left_cast.span, \"..\");\n\n                    let (mutbl_fn_str, mutbl_ptr_str) = match end_ty.mutbl {\n                        Mutability::Mut => (\"_mut\", \"mut\"),\n                        Mutability::Not => (\"\", \"const\"),\n                    };\n                    let sugg = format!(\n                        \"core::ptr::slice_from_raw_parts{mutbl_fn_str}({ptr_snippet} as *{mutbl_ptr_str} {}, ..)\",\n                        // get just the ty from the TypeAndMut so that the printed type isn't something like `mut\n                        // T`, extract just the `T`\n                        end_ty.ty\n                    );\n\n                    diag.span_suggestion(\n                        expr.span,\n                        format!(\"replace with `ptr::slice_from_raw_parts{mutbl_fn_str}`\"),\n                        sugg,\n                        rustc_errors::Applicability::HasPlaceholders,\n                    );\n                },\n            );\n        }\n    }\n}\n\nfn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let parent = cx.tcx.parent_hir_node(expr.hir_id);\n    let expr = match parent {\n        Node::Block(block) => {\n            if let Some(parent_expr) = block.expr {\n                parent_expr\n            } else {\n                return false;\n            }\n        },\n        Node::Expr(expr) => expr,\n        _ => return false,\n    };\n\n    matches!(expr.kind, ExprKind::Cast(..))\n}\n\n/// Returns the type T of the pointed to *const [T] or *mut [T] and the mutability of the slice if\n/// the type is one of those slices\nfn get_raw_slice_ty_mut(ty: Ty<'_>) -> Option<TypeAndMut<'_>> {\n    match ty.kind() {\n        ty::RawPtr(slice_ty, mutbl) => match slice_ty.kind() {\n            ty::Slice(ty) => Some(TypeAndMut { ty: *ty, mutbl: *mutbl }),\n            _ => None,\n        },\n        _ => None,\n    }\n}\n\nstruct CastChainInfo<'tcx> {\n    /// The left most part of the cast chain, or in other words, the first cast in the chain\n    /// Used for diagnostics\n    left_cast: &'tcx Expr<'tcx>,\n    /// The starting type of the cast chain\n    start_ty: TypeAndMut<'tcx>,\n    /// The final type of the cast chain\n    end_ty: TypeAndMut<'tcx>,\n}\n\n/// Returns a `CastChainInfo` with the left-most cast in the chain and the original ptr T and final\n/// ptr U if the expression is composed of casts.\n/// Returns None if the expr is not a Cast\nfn expr_cast_chain_tys<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<CastChainInfo<'tcx>> {\n    if let ExprKind::Cast(cast_expr, _cast_to_hir_ty) = expr.peel_blocks().kind {\n        let cast_to = cx.typeck_results().expr_ty(expr);\n        let to_slice_ty = get_raw_slice_ty_mut(cast_to)?;\n\n        // If the expression that makes up the source of this cast is itself a cast, recursively\n        // call `expr_cast_chain_tys` and update the end type with the final target type.\n        // Otherwise, this cast is not immediately nested, just construct the info for this cast\n        if let Some(prev_info) = expr_cast_chain_tys(cx, cast_expr) {\n            Some(CastChainInfo {\n                end_ty: to_slice_ty,\n                ..prev_info\n            })\n        } else {\n            let cast_from = cx.typeck_results().expr_ty(cast_expr);\n            let from_slice_ty = get_raw_slice_ty_mut(cast_from)?;\n            Some(CastChainInfo {\n                left_cast: cast_expr,\n                start_ty: from_slice_ty,\n                end_ty: to_slice_ty,\n            })\n        }\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/cast_slice_from_raw_parts.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{get_parent_expr, is_no_std_crate};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::sym;\n\nuse super::CAST_SLICE_FROM_RAW_PARTS;\n\nenum RawPartsKind {\n    Immutable,\n    Mutable,\n}\n\nfn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option<RawPartsKind> {\n    match cx.tcx.get_diagnostic_name(did)? {\n        sym::slice_from_raw_parts => Some(RawPartsKind::Immutable),\n        sym::slice_from_raw_parts_mut => Some(RawPartsKind::Mutable),\n        _ => None,\n    }\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>, msrv: Msrv) {\n    if let ty::RawPtr(ptrty, _) = cast_to.kind()\n        && let ty::Slice(_) = ptrty.kind()\n        && let ExprKind::Call(fun, [ptr_arg, len_arg]) = cast_expr.peel_blocks().kind\n        && let ExprKind::Path(ref qpath) = fun.kind\n        && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()\n        && let Some(rpk) = raw_parts_kind(cx, fun_def_id)\n        && let ctxt = expr.span.ctxt()\n        && cast_expr.span.ctxt() == ctxt\n        && msrv.meets(cx, msrvs::PTR_SLICE_RAW_PARTS)\n    {\n        let func = match rpk {\n            RawPartsKind::Immutable => \"from_raw_parts\",\n            RawPartsKind::Mutable => \"from_raw_parts_mut\",\n        };\n        let span = expr.span;\n        let mut applicability = Applicability::MachineApplicable;\n        let ptr = snippet_with_context(cx, ptr_arg.span, ctxt, \"ptr\", &mut applicability).0;\n        let len = snippet_with_context(cx, len_arg.span, ctxt, \"len\", &mut applicability).0;\n        let krate = if is_no_std_crate(cx) { \"core\" } else { \"std\" };\n        span_lint_and_sugg(\n            cx,\n            CAST_SLICE_FROM_RAW_PARTS,\n            span,\n            format!(\"casting the result of `{func}` to {cast_to}\"),\n            \"replace with\",\n            format!(\"{krate}::ptr::slice_{func}({ptr}, {len})\"),\n            applicability,\n        );\n    }\n}\n\n/// Checks for implicit cast from slice reference to raw slice pointer.\npub(super) fn check_implicit_cast(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let ExprKind::Call(fun, [ptr_arg, len_arg]) = expr.peel_blocks().kind\n        && let ExprKind::Path(ref qpath) = fun.kind\n        && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()\n        && let Some(rpk) = raw_parts_kind(cx, fun_def_id)\n        && !matches!(get_parent_expr(cx, expr).map(|e| e.kind), Some(ExprKind::Cast(..)))\n        && let [deref, borrow] = cx.typeck_results().expr_adjustments(expr)\n        && matches!(deref.kind, Adjust::Deref(..))\n        && let Adjustment {\n            kind: Adjust::Borrow(AutoBorrow::RawPtr(..)),\n            target,\n        } = borrow\n        && let ty::RawPtr(pointee_ty, _) = target.kind()\n        && pointee_ty.is_slice()\n        && !expr.span.from_expansion()\n    {\n        let func = match rpk {\n            RawPartsKind::Immutable => \"from_raw_parts\",\n            RawPartsKind::Mutable => \"from_raw_parts_mut\",\n        };\n        let mut applicability = Applicability::MachineApplicable;\n        let ctxt = expr.span.ctxt();\n        let ptr = snippet_with_context(cx, ptr_arg.span, ctxt, \"ptr\", &mut applicability).0;\n        let len = snippet_with_context(cx, len_arg.span, ctxt, \"len\", &mut applicability).0;\n        let krate = if is_no_std_crate(cx) { \"core\" } else { \"std\" };\n        span_lint_and_sugg(\n            cx,\n            CAST_SLICE_FROM_RAW_PARTS,\n            expr.span,\n            format!(\"implicitly casting the result of `{func}` to `{target}`\"),\n            \"replace_with\",\n            format!(\"{krate}::ptr::slice_{func}({ptr}, {len})\"),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/char_lit_as_u8.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty, UintTy};\n\nuse super::CHAR_LIT_AS_U8;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from_expr: &Expr<'_>, cast_to: Ty<'_>) {\n    if let ExprKind::Lit(l) = &cast_from_expr.kind\n        && let LitKind::Char(c) = l.node\n        && ty::Uint(UintTy::U8) == *cast_to.kind()\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let snippet = snippet_with_applicability(cx, cast_from_expr.span, \"'x'\", &mut applicability);\n\n        span_lint_and_then(\n            cx,\n            CHAR_LIT_AS_U8,\n            expr.span,\n            \"casting a character literal to `u8` truncates\",\n            |diag| {\n                diag.note(\"`char` is four bytes wide, but `u8` is a single byte\");\n\n                if c.is_ascii() {\n                    diag.span_suggestion(\n                        expr.span,\n                        \"use a byte literal instead\",\n                        format!(\"b{snippet}\"),\n                        applicability,\n                    );\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/confusing_method_to_numeric_cast.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, GenericArg, Ty};\nuse rustc_span::Symbol;\nuse rustc_span::def_id::DefId;\n\nuse super::CONFUSING_METHOD_TO_NUMERIC_CAST;\n\nfn get_primitive_ty_name(ty: Ty<'_>) -> Option<&'static str> {\n    match ty.kind() {\n        ty::Char => Some(\"char\"),\n        ty::Int(int) => Some(int.name_str()),\n        ty::Uint(uint) => Some(uint.name_str()),\n        ty::Float(float) => Some(float.name_str()),\n        _ => None,\n    }\n}\n\nfn get_const_name_and_ty_name(\n    cx: &LateContext<'_>,\n    method_name: Symbol,\n    method_def_id: DefId,\n    generics: &[GenericArg<'_>],\n) -> Option<(&'static str, &'static str)> {\n    let diagnostic_name = cx.tcx.get_diagnostic_name(method_def_id);\n\n    let ty_name = if diagnostic_name.is_some_and(|diag| diag == sym::cmp_ord_min || diag == sym::cmp_ord_max) {\n        // We get the type on which the `min`/`max` method of the `Ord` trait is implemented.\n        if let [ty] = generics\n            && let Some(ty) = ty.as_type()\n        {\n            get_primitive_ty_name(ty)?\n        } else {\n            return None;\n        }\n    } else if let Some(impl_id) = cx.tcx.impl_of_assoc(method_def_id)\n        && let Some(ty_name) = get_primitive_ty_name(cx.tcx.type_of(impl_id).instantiate_identity())\n        && matches!(\n            method_name,\n            sym::min | sym::max | sym::minimum | sym::maximum | sym::min_value | sym::max_value\n        )\n    {\n        ty_name\n    } else {\n        return None;\n    };\n\n    let const_name = if matches!(method_name, sym::max | sym::maximum | sym::max_value) {\n        \"MAX\"\n    } else {\n        \"MIN\"\n    };\n    Some((const_name, ty_name))\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {\n    // We allow casts from any function type to any function type.\n    if cast_to.is_fn() {\n        return;\n    }\n\n    if let ty::FnDef(def_id, generics) = cast_from.kind()\n        && let Some(method_name) = cx.tcx.opt_item_name(*def_id)\n        && let Some((const_name, ty_name)) = get_const_name_and_ty_name(cx, method_name, *def_id, generics.as_slice())\n    {\n        let mut applicability = Applicability::MaybeIncorrect;\n        let from_snippet = snippet_with_applicability(cx, cast_expr.span, \"..\", &mut applicability);\n\n        span_lint_and_then(\n            cx,\n            CONFUSING_METHOD_TO_NUMERIC_CAST,\n            expr.span,\n            format!(\"casting function pointer `{from_snippet}` to `{cast_to}`\"),\n            |diag| {\n                diag.span_suggestion_verbose(\n                    expr.span,\n                    \"did you mean to use the associated constant?\",\n                    format!(\"{ty_name}::{const_name} as {cast_to}\"),\n                    applicability,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/fn_to_numeric_cast.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\nuse super::{FN_TO_NUMERIC_CAST, utils};\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {\n    // We only want to check casts to `ty::Uint` or `ty::Int`\n    let Some(to_nbits) = utils::int_ty_to_nbits(cx.tcx, cast_to) else {\n        return;\n    };\n\n    if cast_from.is_fn() {\n        let mut applicability = Applicability::MaybeIncorrect;\n\n        if to_nbits >= cx.tcx.data_layout.pointer_size().bits() && !cast_to.is_usize() {\n            let from_snippet = snippet_with_applicability(cx, cast_expr.span, \"x\", &mut applicability);\n            span_lint_and_sugg(\n                cx,\n                FN_TO_NUMERIC_CAST,\n                expr.span,\n                format!(\"casting function pointer `{from_snippet}` to `{cast_to}`\"),\n                \"try\",\n                format!(\"{from_snippet} as usize\"),\n                applicability,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/fn_to_numeric_cast_any.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\nuse super::FN_TO_NUMERIC_CAST_ANY;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {\n    // We allow casts from any function type to any function type.\n    if cast_to.is_fn() {\n        return;\n    }\n\n    if cast_from.is_fn() {\n        let mut applicability = Applicability::MaybeIncorrect;\n        let from_snippet = snippet_with_applicability(cx, cast_expr.span, \"..\", &mut applicability);\n\n        span_lint_and_then(\n            cx,\n            FN_TO_NUMERIC_CAST_ANY,\n            expr.span,\n            format!(\"casting function pointer `{from_snippet}` to `{cast_to}`\"),\n            |diag| {\n                diag.span_suggestion_verbose(\n                    expr.span,\n                    \"did you mean to invoke the function?\",\n                    format!(\"{from_snippet}() as {cast_to}\"),\n                    applicability,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\nuse super::{FN_TO_NUMERIC_CAST_WITH_TRUNCATION, utils};\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {\n    // We only want to check casts to `ty::Uint` or `ty::Int`\n    let Some(to_nbits) = utils::int_ty_to_nbits(cx.tcx, cast_to) else {\n        return;\n    };\n    if cast_from.is_fn() {\n        let mut applicability = Applicability::MaybeIncorrect;\n        let from_snippet = snippet_with_applicability(cx, cast_expr.span, \"x\", &mut applicability);\n\n        if to_nbits < cx.tcx.data_layout.pointer_size().bits() {\n            span_lint_and_sugg(\n                cx,\n                FN_TO_NUMERIC_CAST_WITH_TRUNCATION,\n                expr.span,\n                format!(\"casting function pointer `{from_snippet}` to `{cast_to}`, which truncates the value\"),\n                \"try\",\n                format!(\"{from_snippet} as usize\"),\n                applicability,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/manual_dangling_ptr.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{expr_or_init, std_or_core, sym};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, GenericArg, Mutability, QPath, Ty, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::MANUAL_DANGLING_PTR;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) {\n    if let TyKind::Ptr(ref ptr_ty) = to.kind {\n        let init_expr = expr_or_init(cx, from);\n        if is_expr_const_aligned(cx, init_expr, ptr_ty.ty)\n            && let Some(std_or_core) = std_or_core(cx)\n            && let pointee_ty = cx.typeck_results().node_type(ptr_ty.ty.hir_id)\n            && pointee_ty.is_sized(cx.tcx, cx.typing_env())\n        {\n            let sugg_fn = match ptr_ty.mutbl {\n                Mutability::Not => \"ptr::dangling\",\n                Mutability::Mut => \"ptr::dangling_mut\",\n            };\n\n            let sugg = if let TyKind::Infer(()) = ptr_ty.ty.kind {\n                format!(\"{std_or_core}::{sugg_fn}()\")\n            } else if let Some(mut_ty_snip) = ptr_ty.ty.span.get_source_text(cx) {\n                format!(\"{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()\")\n            } else {\n                return;\n            };\n\n            span_lint_and_sugg(\n                cx,\n                MANUAL_DANGLING_PTR,\n                expr.span,\n                \"manual creation of a dangling pointer\",\n                \"use\",\n                sugg,\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n\n// Checks if the given expression is a call to `align_of` whose generic argument matches the target\n// type, or a positive constant literal that matches the target type's alignment.\nfn is_expr_const_aligned(cx: &LateContext<'_>, expr: &Expr<'_>, to: &Ty<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Call(fun, _) => is_align_of_call(cx, fun, to),\n        ExprKind::Lit(lit) => is_literal_aligned(cx, &lit, to),\n        _ => false,\n    }\n}\n\nfn is_align_of_call(cx: &LateContext<'_>, fun: &Expr<'_>, to: &Ty<'_>) -> bool {\n    if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind\n        && fun.basic_res().is_diag_item(cx, sym::mem_align_of)\n        && let Some(args) = path.segments.last().and_then(|seg| seg.args)\n        && let [GenericArg::Type(generic_ty)] = args.args\n    {\n        let typeck = cx.typeck_results();\n        return typeck.node_type(generic_ty.hir_id) == typeck.node_type(to.hir_id);\n    }\n    false\n}\n\nfn is_literal_aligned(cx: &LateContext<'_>, lit: &Spanned<LitKind>, to: &Ty<'_>) -> bool {\n    let LitKind::Int(val, _) = lit.node else { return false };\n    if val == 0 {\n        return false;\n    }\n    let to_mid_ty = cx.typeck_results().node_type(to.hir_id);\n    cx.tcx\n        .layout_of(cx.typing_env().as_query_input(to_mid_ty))\n        .is_ok_and(|layout| {\n            let align = u128::from(layout.align.bytes());\n            u128::from(val) <= align\n        })\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/mod.rs",
    "content": "mod as_pointer_underscore;\nmod as_ptr_cast_mut;\nmod as_underscore;\nmod borrow_as_ptr;\nmod cast_abs_to_unsigned;\nmod cast_enum_constructor;\nmod cast_lossless;\nmod cast_nan_to_int;\nmod cast_possible_truncation;\nmod cast_possible_wrap;\nmod cast_precision_loss;\nmod cast_ptr_alignment;\nmod cast_sign_loss;\nmod cast_slice_different_sizes;\nmod cast_slice_from_raw_parts;\nmod char_lit_as_u8;\nmod confusing_method_to_numeric_cast;\nmod fn_to_numeric_cast;\nmod fn_to_numeric_cast_any;\nmod fn_to_numeric_cast_with_truncation;\nmod manual_dangling_ptr;\nmod needless_type_cast;\nmod ptr_as_ptr;\nmod ptr_cast_constness;\nmod ref_as_ptr;\nmod unnecessary_cast;\nmod utils;\nmod zero_ptr;\n\nuse clippy_config::Conf;\nuse clippy_utils::is_hir_ty_cfg_dependant;\nuse clippy_utils::msrvs::{self, Msrv};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of `as *const _` or `as *mut _` conversion using inferred type.\n    ///\n    /// ### Why restrict this?\n    /// The conversion might include a dangerous cast that might go undetected due to the type being inferred.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn as_usize<T>(t: &T) -> usize {\n    ///     // BUG: `t` is already a reference, so we will here\n    ///     // return a dangling pointer to a temporary value instead\n    ///     &t as *const _ as usize\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn as_usize<T>(t: &T) -> usize {\n    ///     t as *const T as usize\n    /// }\n    /// ```\n    #[clippy::version = \"1.85.0\"]\n    pub AS_POINTER_UNDERSCORE,\n    restriction,\n    \"detects `as *mut _` and `as *const _` conversion\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer.\n    ///\n    /// ### Why is this bad?\n    /// Since `as_ptr` takes a `&self`, the pointer won't have write permissions unless interior\n    /// mutability is used, making it unlikely that having it as a mutable pointer is correct.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut vec = Vec::<u8>::with_capacity(1);\n    /// let ptr = vec.as_ptr() as *mut u8;\n    /// unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut vec = Vec::<u8>::with_capacity(1);\n    /// let ptr = vec.as_mut_ptr();\n    /// unsafe { ptr.write(4) };\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub AS_PTR_CAST_MUT,\n    nursery,\n    \"casting the result of the `&self`-taking `as_ptr` to a mutable pointer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of `as _` conversion using inferred type.\n    ///\n    /// ### Why restrict this?\n    /// The conversion might include lossy conversion or a dangerous cast that might go\n    /// undetected due to the type being inferred.\n    ///\n    /// The lint is allowed by default as using `_` is less wordy than always specifying the type.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(n: usize) {}\n    /// let n: u16 = 256;\n    /// foo(n as _);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo(n: usize) {}\n    /// let n: u16 = 256;\n    /// foo(n as usize);\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub AS_UNDERSCORE,\n    restriction,\n    \"detects `as _` conversion\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of `&expr as *const T` or\n    /// `&mut expr as *mut T`, and suggest using `&raw const` or\n    /// `&raw mut` instead.\n    ///\n    /// ### Why is this bad?\n    /// This would improve readability and avoid creating a reference\n    /// that points to an uninitialized value or unaligned place.\n    /// Read the `&raw` explanation in the Reference for more information.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let val = 1;\n    /// let p = &val as *const i32;\n    ///\n    /// let mut val_mut = 1;\n    /// let p_mut = &mut val_mut as *mut i32;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let val = 1;\n    /// let p = &raw const val;\n    ///\n    /// let mut val_mut = 1;\n    /// let p_mut = &raw mut val_mut;\n    /// ```\n    #[clippy::version = \"1.60.0\"]\n    pub BORROW_AS_PTR,\n    pedantic,\n    \"borrowing just to cast to a raw pointer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of the `abs()` method that cast the result to unsigned.\n    ///\n    /// ### Why is this bad?\n    /// The `unsigned_abs()` method avoids panic when called on the MIN value.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: i32 = -42;\n    /// let y: u32 = x.abs() as u32;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x: i32 = -42;\n    /// let y: u32 = x.unsigned_abs();\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub CAST_ABS_TO_UNSIGNED,\n    suspicious,\n    \"casting the result of `abs()` to an unsigned integer can panic\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts from an enum tuple constructor to an integer.\n    ///\n    /// ### Why is this bad?\n    /// The cast is easily confused with casting a c-like enum value to an integer.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum E { X(i32) };\n    /// let _ = E::X as usize;\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub CAST_ENUM_CONSTRUCTOR,\n    suspicious,\n    \"casts from an enum tuple constructor to an integer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts from an enum type to an integral type that will definitely truncate the\n    /// value.\n    ///\n    /// ### Why is this bad?\n    /// The resulting integral value will not match the value of the variant it came from.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum E { X = 256 };\n    /// let _ = E::X as u8;\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub CAST_ENUM_TRUNCATION,\n    suspicious,\n    \"casts from an enum type to an integral type that will truncate the value\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts between numeric types that can be replaced by safe\n    /// conversion functions.\n    ///\n    /// ### Why is this bad?\n    /// Rust's `as` keyword will perform many kinds of conversions, including\n    /// silently lossy conversions. Conversion functions such as `i32::from`\n    /// will only perform lossless conversions. Using the conversion functions\n    /// prevents conversions from becoming silently lossy if the input types\n    /// ever change, and makes it clear for people reading the code that the\n    /// conversion is lossless.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn as_u64(x: u8) -> u64 {\n    ///     x as u64\n    /// }\n    /// ```\n    ///\n    /// Using `::from` would look like this:\n    ///\n    /// ```no_run\n    /// fn as_u64(x: u8) -> u64 {\n    ///     u64::from(x)\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CAST_LOSSLESS,\n    pedantic,\n    \"casts using `as` that are known to be lossless, e.g., `x as u64` where `x: u8`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for a known NaN float being cast to an integer\n    ///\n    /// ### Why is this bad?\n    /// NaNs are cast into zero, so one could simply use this and make the\n    /// code more readable. The lint could also hint at a programmer error.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let _ = (0.0_f32 / 0.0) as u64;\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// let _ = 0_u64;\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub CAST_NAN_TO_INT,\n    suspicious,\n    \"casting a known floating-point NaN into an integer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts between numeric types that may\n    /// truncate large values. This is expected behavior, so the cast is `Allow` by\n    /// default. It suggests user either explicitly ignore the lint,\n    /// or use `try_from()` and handle the truncation, default, or panic explicitly.\n    ///\n    /// ### Why is this bad?\n    /// In some problem domains, it is good practice to avoid\n    /// truncation. This lint can be activated to help assess where additional\n    /// checks could be beneficial.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn as_u8(x: u64) -> u8 {\n    ///     x as u8\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn as_u8(x: u64) -> u8 {\n    ///     if let Ok(x) = u8::try_from(x) {\n    ///         x\n    ///     } else {\n    ///         todo!();\n    ///     }\n    /// }\n    /// // Or\n    /// #[allow(clippy::cast_possible_truncation)]\n    /// fn as_u16(x: u64) -> u16 {\n    ///     x as u16\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CAST_POSSIBLE_TRUNCATION,\n    pedantic,\n    \"casts that may cause truncation of the value, e.g., `x as u8` where `x: u32`, or `x as i32` where `x: f32`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts from an unsigned type to a signed type of\n    /// the same size, or possibly smaller due to target-dependent integers.\n    /// Performing such a cast is a no-op for the compiler (that is, nothing is\n    /// changed at the bit level), and the binary representation of the value is\n    /// reinterpreted. This can cause wrapping if the value is too big\n    /// for the target signed type. However, the cast works as defined, so this lint\n    /// is `Allow` by default.\n    ///\n    /// ### Why is this bad?\n    /// While such a cast is not bad in itself, the results can\n    /// be surprising when this is not the intended behavior:\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = u32::MAX as i32; // will yield a value of `-1`\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let _ = i32::try_from(u32::MAX).ok();\n    /// ```\n    ///\n    /// If the wrapping is intended, you can use:\n    /// ```no_run\n    /// let _ = u32::MAX.cast_signed();\n    /// let _ = (-1i32).cast_unsigned();\n    /// ```\n    ///\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CAST_POSSIBLE_WRAP,\n    pedantic,\n    \"casts that may cause wrapping around the value, e.g., `x as i32` where `x: u32` and `x > i32::MAX`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts from any numeric type to a float type where\n    /// the receiving type cannot store all values from the original type without\n    /// rounding errors. This possible rounding is to be expected, so this lint is\n    /// `Allow` by default.\n    ///\n    /// Basically, this warns on casting any integer with 32 or more bits to `f32`\n    /// or any 64-bit integer to `f64`.\n    ///\n    /// ### Why is this bad?\n    /// It's not bad at all. But in some applications it can be\n    /// helpful to know where precision loss can take place. This lint can help find\n    /// those places in the code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = u64::MAX;\n    /// x as f64;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CAST_PRECISION_LOSS,\n    pedantic,\n    \"casts that cause loss of precision, e.g., `x as f32` where `x: u64`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts, using `as` or `pointer::cast`, from a\n    /// less strictly aligned pointer to a more strictly aligned pointer.\n    ///\n    /// ### Why is this bad?\n    /// Dereferencing the resulting pointer may be undefined behavior.\n    ///\n    /// ### Known problems\n    /// Using [`std::ptr::read_unaligned`](https://doc.rust-lang.org/std/ptr/fn.read_unaligned.html) and [`std::ptr::write_unaligned`](https://doc.rust-lang.org/std/ptr/fn.write_unaligned.html) or\n    /// similar on the resulting pointer is fine. Is over-zealous: casts with\n    /// manual alignment checks or casts like `u64` -> `u8` -> `u16` can be\n    /// fine. Miri is able to do a more in-depth analysis.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = (&1u8 as *const u8) as *const u16;\n    /// let _ = (&mut 1u8 as *mut u8) as *mut u16;\n    ///\n    /// (&1u8 as *const u8).cast::<u16>();\n    /// (&mut 1u8 as *mut u8).cast::<u16>();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CAST_PTR_ALIGNMENT,\n    pedantic,\n    \"cast from a pointer to a more strictly aligned pointer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts from a signed to an unsigned numeric\n    /// type. In this case, negative values wrap around to large positive values,\n    /// which can be quite surprising in practice. However, since the cast works as\n    /// defined, this lint is `Allow` by default.\n    ///\n    /// ### Why is this bad?\n    /// Possibly surprising results. You can activate this lint\n    /// as a one-time check to see where numeric wrapping can arise.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let y: i8 = -1;\n    /// y as u64; // will return 18446744073709551615\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CAST_SIGN_LOSS,\n    pedantic,\n    \"casts from signed types to unsigned types, e.g., `x as u32` where `x: i32`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `as` casts between raw pointers to slices with differently sized elements.\n    ///\n    /// ### Why is this bad?\n    /// The produced raw pointer to a slice does not update its length metadata. The produced\n    /// pointer will point to a different number of bytes than the original pointer because the\n    /// length metadata of a raw slice pointer is in elements rather than bytes.\n    /// Producing a slice reference from the raw pointer will either create a slice with\n    /// less data (which can be surprising) or create a slice with more data and cause Undefined Behavior.\n    ///\n    /// ### Example\n    /// // Missing data\n    /// ```no_run\n    /// let a = [1_i32, 2, 3, 4];\n    /// let p = &a as *const [i32] as *const [u8];\n    /// unsafe {\n    ///     println!(\"{:?}\", &*p);\n    /// }\n    /// ```\n    /// // Undefined Behavior (note: also potential alignment issues)\n    /// ```no_run\n    /// let a = [1_u8, 2, 3, 4];\n    /// let p = &a as *const [u8] as *const [u32];\n    /// unsafe {\n    ///     println!(\"{:?}\", &*p);\n    /// }\n    /// ```\n    /// Instead use `ptr::slice_from_raw_parts` to construct a slice from a data pointer and the correct length\n    /// ```no_run\n    /// let a = [1_i32, 2, 3, 4];\n    /// let old_ptr = &a as *const [i32];\n    /// // The data pointer is cast to a pointer to the target `u8` not `[u8]`\n    /// // The length comes from the known length of 4 i32s times the 4 bytes per i32\n    /// let new_ptr = core::ptr::slice_from_raw_parts(old_ptr as *const u8, 16);\n    /// unsafe {\n    ///     println!(\"{:?}\", &*new_ptr);\n    /// }\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub CAST_SLICE_DIFFERENT_SIZES,\n    correctness,\n    \"casting using `as` between raw pointers to slices of types with different sizes\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for a raw slice being cast to a slice pointer\n    ///\n    /// ### Why is this bad?\n    /// This can result in multiple `&mut` references to the same location when only a pointer is\n    /// required.\n    /// `ptr::slice_from_raw_parts` is a safe alternative that doesn't require\n    /// the same [safety requirements] to be upheld.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let _: *const [u8] = std::slice::from_raw_parts(ptr, len) as *const _;\n    /// let _: *mut [u8] = std::slice::from_raw_parts_mut(ptr, len) as *mut _;\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, len);\n    /// let _: *mut [u8] = std::ptr::slice_from_raw_parts_mut(ptr, len);\n    /// ```\n    /// [safety requirements]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety\n    #[clippy::version = \"1.65.0\"]\n    pub CAST_SLICE_FROM_RAW_PARTS,\n    suspicious,\n    \"casting a slice created from a pointer and length to a slice pointer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions where a character literal is cast\n    /// to `u8` and suggests using a byte literal instead.\n    ///\n    /// ### Why is this bad?\n    /// In general, casting values to smaller types is\n    /// error-prone and should be avoided where possible. In the particular case of\n    /// converting a character literal to `u8`, it is easy to avoid by just using a\n    /// byte literal instead. As an added bonus, `b'a'` is also slightly shorter\n    /// than `'a' as u8`.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// 'x' as u8\n    /// ```\n    ///\n    /// A better version, using the byte literal:\n    ///\n    /// ```rust,ignore\n    /// b'x'\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CHAR_LIT_AS_U8,\n    complexity,\n    \"casting a character literal to `u8` truncates\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts of a primitive method pointer like `max`/`min` to any integer type.\n    ///\n    /// ### Why restrict this?\n    /// Casting a function pointer to an integer can have surprising results and can occur\n    /// accidentally if parentheses are omitted from a function call. If you aren't doing anything\n    /// low-level with function pointers then you can opt out of casting functions to integers in\n    /// order to avoid mistakes. Alternatively, you can use this lint to audit all uses of function\n    /// pointer casts in your code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = u16::max as usize;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let _ = u16::MAX as usize;\n    /// ```\n    #[clippy::version = \"1.89.0\"]\n    pub CONFUSING_METHOD_TO_NUMERIC_CAST,\n    suspicious,\n    \"casting a primitive method pointer to any integer type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts of function pointers to something other than `usize`.\n    ///\n    /// ### Why is this bad?\n    /// Casting a function pointer to anything other than `usize`/`isize` is\n    /// not portable across architectures. If the target type is too small the\n    /// address would be truncated, and target types larger than `usize` are\n    /// unnecessary.\n    ///\n    /// Casting to `isize` also doesn't make sense, since addresses are never\n    /// signed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn fun() -> i32 { 1 }\n    /// let _ = fun as i64;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # fn fun() -> i32 { 1 }\n    /// let _ = fun as usize;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub FN_TO_NUMERIC_CAST,\n    style,\n    \"casting a function pointer to a numeric type other than `usize`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts of a function pointer to any integer type.\n    ///\n    /// ### Why restrict this?\n    /// Casting a function pointer to an integer can have surprising results and can occur\n    /// accidentally if parentheses are omitted from a function call. If you aren't doing anything\n    /// low-level with function pointers then you can opt out of casting functions to integers in\n    /// order to avoid mistakes. Alternatively, you can use this lint to audit all uses of function\n    /// pointer casts in your code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // fn1 is cast as `usize`\n    /// fn fn1() -> u16 {\n    ///     1\n    /// };\n    /// let _ = fn1 as usize;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// // maybe you intended to call the function?\n    /// fn fn2() -> u16 {\n    ///     1\n    /// };\n    /// let _ = fn2() as usize;\n    ///\n    /// // or\n    ///\n    /// // maybe you intended to cast it to a function type?\n    /// fn fn3() -> u16 {\n    ///     1\n    /// }\n    /// let _ = fn3 as fn() -> u16;\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub FN_TO_NUMERIC_CAST_ANY,\n    restriction,\n    \"casting a function pointer to any integer type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts of a function pointer to a numeric type not wide enough to\n    /// store an address.\n    ///\n    /// ### Why is this bad?\n    /// Such a cast discards some bits of the function's address. If this is intended, it would be more\n    /// clearly expressed by casting to `usize` first, then casting the `usize` to the intended type (with\n    /// a comment) to perform the truncation.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn fn1() -> i16 {\n    ///     1\n    /// };\n    /// let _ = fn1 as i32;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// // Cast to usize first, then comment with the reason for the truncation\n    /// fn fn1() -> i16 {\n    ///     1\n    /// };\n    /// let fn_ptr = fn1 as usize;\n    /// let fn_ptr_truncated = fn_ptr as i32;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub FN_TO_NUMERIC_CAST_WITH_TRUNCATION,\n    style,\n    \"casting a function pointer to a numeric type not wide enough to store the address\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts of small constant literals or `mem::align_of` results to raw pointers.\n    ///\n    /// ### Why is this bad?\n    /// This creates a dangling pointer and is better expressed as\n    /// {`std`, `core`}`::ptr::`{`dangling`, `dangling_mut`}.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let ptr = 4 as *const u32;\n    /// let aligned = std::mem::align_of::<u32>() as *const u32;\n    /// let mut_ptr: *mut i64 = 8 as *mut _;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let ptr = std::ptr::dangling::<u32>();\n    /// let aligned = std::ptr::dangling::<u32>();\n    /// let mut_ptr: *mut i64 = std::ptr::dangling_mut();\n    /// ```\n    #[clippy::version = \"1.88.0\"]\n    pub MANUAL_DANGLING_PTR,\n    style,\n    \"casting small constant literals to pointers to create dangling pointers\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for bindings (constants, statics, or let bindings) that are defined\n    /// with one numeric type but are consistently cast to a different type in all usages.\n    ///\n    /// ### Why is this bad?\n    /// If a binding is always cast to a different type when used, it would be clearer\n    /// and more efficient to define it with the target type from the start.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// const SIZE: u16 = 15;\n    /// let arr: [u8; SIZE as usize] = [0; SIZE as usize];\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// const SIZE: usize = 15;\n    /// let arr: [u8; SIZE] = [0; SIZE];\n    /// ```\n    #[clippy::version = \"1.94.0\"]\n    pub NEEDLESS_TYPE_CAST,\n    nursery,\n    \"binding defined with one type but always cast to another\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `as` casts between raw pointers that don't change their\n    /// constness, namely `*const T` to `*const U` and `*mut T` to `*mut U`.\n    ///\n    /// ### Why is this bad?\n    /// Though `as` casts between raw pointers are not terrible,\n    /// `pointer::cast` is safer because it cannot accidentally change the\n    /// pointer's mutability, nor cast the pointer to other types like `usize`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let ptr: *const u32 = &42_u32;\n    /// let mut_ptr: *mut u32 = &mut 42_u32;\n    /// let _ = ptr as *const i32;\n    /// let _ = mut_ptr as *mut i32;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let ptr: *const u32 = &42_u32;\n    /// let mut_ptr: *mut u32 = &mut 42_u32;\n    /// let _ = ptr.cast::<i32>();\n    /// let _ = mut_ptr.cast::<i32>();\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub PTR_AS_PTR,\n    pedantic,\n    \"casting using `as` between raw pointers that doesn't change their constness, where `pointer::cast` could take the place of `as`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `as` casts between raw pointers that change their constness, namely `*const T` to\n    /// `*mut T` and `*mut T` to `*const T`.\n    ///\n    /// ### Why is this bad?\n    /// Though `as` casts between raw pointers are not terrible, `pointer::cast_mut` and\n    /// `pointer::cast_const` are safer because they cannot accidentally cast the pointer to another\n    /// type. Or, when null pointers are involved, `null()` and `null_mut()` can be used directly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let ptr: *const u32 = &42_u32;\n    /// let mut_ptr = ptr as *mut u32;\n    /// let ptr = mut_ptr as *const u32;\n    /// let ptr1 = std::ptr::null::<u32>() as *mut u32;\n    /// let ptr2 = std::ptr::null_mut::<u32>() as *const u32;\n    /// let ptr3 = std::ptr::null::<u32>().cast_mut();\n    /// let ptr4 = std::ptr::null_mut::<u32>().cast_const();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let ptr: *const u32 = &42_u32;\n    /// let mut_ptr = ptr.cast_mut();\n    /// let ptr = mut_ptr.cast_const();\n    /// let ptr1 = std::ptr::null_mut::<u32>();\n    /// let ptr2 = std::ptr::null::<u32>();\n    /// let ptr3 = std::ptr::null_mut::<u32>();\n    /// let ptr4 = std::ptr::null::<u32>();\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub PTR_CAST_CONSTNESS,\n    pedantic,\n    \"casting using `as` on raw pointers to change constness when specialized methods apply\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts of references to pointer using `as`\n    /// and suggests `std::ptr::from_ref` and `std::ptr::from_mut` instead.\n    ///\n    /// ### Why is this bad?\n    /// Using `as` casts may result in silently changing mutability or type.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a_ref = &1;\n    /// let a_ptr = a_ref as *const _;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let a_ref = &1;\n    /// let a_ptr = std::ptr::from_ref(a_ref);\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub REF_AS_PTR,\n    pedantic,\n    \"using `as` to cast a reference to pointer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for casts to the same type, casts of int literals to integer\n    /// types, casts of float literals to float types, and casts between raw\n    /// pointers that don't change type or constness.\n    ///\n    /// ### Why is this bad?\n    /// It's just unnecessary.\n    ///\n    /// ### Known problems\n    /// When the expression on the left is a function call, the lint considers\n    /// the return type to be a type alias if it's aliased through a `use`\n    /// statement (like `use std::io::Result as IoResult`). It will not lint\n    /// such cases.\n    ///\n    /// This check will only work on primitive types without any intermediate\n    /// references: raw pointers and trait objects may or may not work.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = 2i32 as i32;\n    /// let _ = 0.5 as f32;\n    /// ```\n    ///\n    /// Better:\n    ///\n    /// ```no_run\n    /// let _ = 2_i32;\n    /// let _ = 0.5_f32;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNNECESSARY_CAST,\n    complexity,\n    \"cast to the same type, e.g., `x as i32` where `x: i32`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Catch casts from `0` to some pointer type\n    ///\n    /// ### Why is this bad?\n    /// This generally means `null` and is better expressed as\n    /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = 0 as *const u32;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let a = std::ptr::null::<u32>();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ZERO_PTR,\n    style,\n    \"using `0 as *{const, mut} T`\"\n}\n\nimpl_lint_pass!(Casts => [\n    AS_POINTER_UNDERSCORE,\n    AS_PTR_CAST_MUT,\n    AS_UNDERSCORE,\n    BORROW_AS_PTR,\n    CAST_ABS_TO_UNSIGNED,\n    CAST_ENUM_CONSTRUCTOR,\n    CAST_ENUM_TRUNCATION,\n    CAST_LOSSLESS,\n    CAST_NAN_TO_INT,\n    CAST_POSSIBLE_TRUNCATION,\n    CAST_POSSIBLE_WRAP,\n    CAST_PRECISION_LOSS,\n    CAST_PTR_ALIGNMENT,\n    CAST_SIGN_LOSS,\n    CAST_SLICE_DIFFERENT_SIZES,\n    CAST_SLICE_FROM_RAW_PARTS,\n    CHAR_LIT_AS_U8,\n    CONFUSING_METHOD_TO_NUMERIC_CAST,\n    FN_TO_NUMERIC_CAST,\n    FN_TO_NUMERIC_CAST_ANY,\n    FN_TO_NUMERIC_CAST_WITH_TRUNCATION,\n    MANUAL_DANGLING_PTR,\n    NEEDLESS_TYPE_CAST,\n    PTR_AS_PTR,\n    PTR_CAST_CONSTNESS,\n    REF_AS_PTR,\n    UNNECESSARY_CAST,\n    ZERO_PTR,\n]);\n\npub struct Casts {\n    msrv: Msrv,\n}\n\nimpl Casts {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Casts {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if expr.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if let ExprKind::Cast(cast_from_expr, cast_to_hir) = expr.kind {\n            if is_hir_ty_cfg_dependant(cx, cast_to_hir) {\n                return;\n            }\n            let (cast_from, cast_to) = (\n                cx.typeck_results().expr_ty(cast_from_expr),\n                cx.typeck_results().expr_ty(expr),\n            );\n\n            if !expr.span.from_expansion() && unnecessary_cast::check(cx, expr, cast_from_expr, cast_from, cast_to) {\n                return;\n            }\n            char_lit_as_u8::check(cx, expr, cast_from_expr, cast_to);\n            cast_slice_from_raw_parts::check(cx, expr, cast_from_expr, cast_to, self.msrv);\n            cast_ptr_alignment::check(cx, expr, cast_from, cast_to);\n            ptr_cast_constness::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv);\n            ptr_as_ptr::check(cx, expr, cast_from_expr, cast_from, cast_to_hir, cast_to, self.msrv);\n            as_ptr_cast_mut::check(cx, expr, cast_from_expr, cast_to);\n            fn_to_numeric_cast_any::check(cx, expr, cast_from_expr, cast_from, cast_to);\n            confusing_method_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);\n            fn_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);\n            fn_to_numeric_cast_with_truncation::check(cx, expr, cast_from_expr, cast_from, cast_to);\n            zero_ptr::check(cx, expr, cast_from_expr, cast_to_hir, self.msrv);\n\n            if self.msrv.meets(cx, msrvs::MANUAL_DANGLING_PTR) {\n                manual_dangling_ptr::check(cx, expr, cast_from_expr, cast_to_hir);\n            }\n\n            if cast_to.is_numeric() {\n                cast_possible_truncation::check(cx, expr, cast_from_expr, cast_from, cast_to, cast_to_hir.span);\n                if cast_from.is_numeric() {\n                    cast_possible_wrap::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv);\n                    cast_precision_loss::check(cx, expr, cast_from, cast_to);\n                    cast_sign_loss::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv);\n                    cast_abs_to_unsigned::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv);\n                    cast_nan_to_int::check(cx, expr, cast_from_expr, cast_from, cast_to);\n                }\n                cast_lossless::check(cx, expr, cast_from_expr, cast_from, cast_to, cast_to_hir, self.msrv);\n                cast_enum_constructor::check(cx, expr, cast_from_expr, cast_from);\n            }\n\n            as_underscore::check(cx, expr, cast_to_hir);\n            as_pointer_underscore::check(cx, cast_to, cast_to_hir);\n\n            let was_borrow_as_ptr_emitted = self.msrv.meets(cx, msrvs::BORROW_AS_PTR)\n                && borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir, self.msrv);\n            if !was_borrow_as_ptr_emitted && self.msrv.meets(cx, msrvs::PTR_FROM_REF) {\n                ref_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir);\n            }\n        }\n\n        if self.msrv.meets(cx, msrvs::RAW_REF_OP) {\n            borrow_as_ptr::check_implicit_cast(cx, expr);\n        }\n        if self.msrv.meets(cx, msrvs::PTR_SLICE_RAW_PARTS) {\n            cast_slice_from_raw_parts::check_implicit_cast(cx, expr);\n        }\n        cast_ptr_alignment::check_cast_method(cx, expr);\n        cast_slice_different_sizes::check(cx, expr, self.msrv);\n        ptr_cast_constness::check_null_ptr_cast_method(cx, expr);\n    }\n\n    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &rustc_hir::Body<'tcx>) {\n        needless_type_cast::check(cx, body);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/needless_type_cast.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::visitors::{Descend, for_each_expr, for_each_expr_without_closures};\nuse core::ops::ControlFlow;\nuse rustc_ast::ast::{LitFloatType, LitIntType, LitKind};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{BlockCheckMode, Body, Expr, ExprKind, HirId, LetStmt, PatKind, StmtKind, UnsafeSource};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{Ty, TypeVisitableExt};\nuse rustc_span::Span;\n\nuse super::NEEDLESS_TYPE_CAST;\n\nstruct BindingInfo<'a> {\n    source_ty: Ty<'a>,\n    ty_span: Span,\n    init: Option<&'a Expr<'a>>,\n}\n\nstruct UsageInfo<'a> {\n    cast_to: Option<Ty<'a>>,\n    in_generic_context: bool,\n}\n\npub(super) fn check<'a>(cx: &LateContext<'a>, body: &Body<'a>) {\n    let mut bindings: FxHashMap<HirId, BindingInfo<'a>> = FxHashMap::default();\n\n    for_each_expr_without_closures(body.value, |expr| {\n        match expr.kind {\n            ExprKind::Block(block, _) => {\n                for stmt in block.stmts {\n                    if let StmtKind::Let(let_stmt) = stmt.kind {\n                        collect_binding_from_local(cx, let_stmt, &mut bindings);\n                    }\n                }\n            },\n            ExprKind::Let(let_expr) => {\n                collect_binding_from_let(cx, let_expr, &mut bindings);\n            },\n            _ => {},\n        }\n        ControlFlow::<()>::Continue(())\n    });\n\n    #[allow(rustc::potential_query_instability)]\n    let mut binding_vec: Vec<_> = bindings.into_iter().collect();\n    binding_vec.sort_by_key(|(_, info)| info.ty_span.lo());\n\n    for (hir_id, binding_info) in binding_vec {\n        check_binding_usages(cx, body, hir_id, &binding_info);\n    }\n}\n\nfn collect_binding_from_let<'a>(\n    cx: &LateContext<'a>,\n    let_expr: &rustc_hir::LetExpr<'a>,\n    bindings: &mut FxHashMap<HirId, BindingInfo<'a>>,\n) {\n    if let_expr.ty.is_none()\n        || let_expr.span.from_expansion()\n        || has_generic_return_type(cx, let_expr.init)\n        || contains_unsafe(let_expr.init)\n    {\n        return;\n    }\n\n    if let PatKind::Binding(_, hir_id, _, _) = let_expr.pat.kind\n        && let Some(ty_hir) = let_expr.ty\n    {\n        let ty = cx.typeck_results().pat_ty(let_expr.pat);\n        if ty.is_numeric() {\n            bindings.insert(\n                hir_id,\n                BindingInfo {\n                    source_ty: ty,\n                    ty_span: ty_hir.span,\n                    init: Some(let_expr.init),\n                },\n            );\n        }\n    }\n}\n\nfn collect_binding_from_local<'a>(\n    cx: &LateContext<'a>,\n    let_stmt: &LetStmt<'a>,\n    bindings: &mut FxHashMap<HirId, BindingInfo<'a>>,\n) {\n    if let_stmt.ty.is_none()\n        || let_stmt.span.from_expansion()\n        || let_stmt\n            .init\n            .is_some_and(|init| has_generic_return_type(cx, init) || contains_unsafe(init))\n    {\n        return;\n    }\n\n    if let PatKind::Binding(_, hir_id, _, _) = let_stmt.pat.kind\n        && let Some(ty_hir) = let_stmt.ty\n    {\n        let ty = cx.typeck_results().pat_ty(let_stmt.pat);\n        if ty.is_numeric() {\n            bindings.insert(\n                hir_id,\n                BindingInfo {\n                    source_ty: ty,\n                    ty_span: ty_hir.span,\n                    init: let_stmt.init,\n                },\n            );\n        }\n    }\n}\n\nfn contains_unsafe(expr: &Expr<'_>) -> bool {\n    for_each_expr_without_closures(expr, |e| {\n        if let ExprKind::Block(block, _) = e.kind\n            && let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules\n        {\n            return ControlFlow::Break(());\n        }\n        ControlFlow::Continue(())\n    })\n    .is_some()\n}\n\nfn has_generic_return_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match &expr.kind {\n        ExprKind::Block(block, _) => {\n            if let Some(tail_expr) = block.expr {\n                return has_generic_return_type(cx, tail_expr);\n            }\n            false\n        },\n        ExprKind::If(_, then_block, else_expr) => {\n            has_generic_return_type(cx, then_block) || else_expr.is_some_and(|e| has_generic_return_type(cx, e))\n        },\n        ExprKind::Match(_, arms, _) => arms.iter().any(|arm| has_generic_return_type(cx, arm.body)),\n        ExprKind::Loop(block, label, ..) => for_each_expr_without_closures(*block, |e| {\n            match e.kind {\n                ExprKind::Loop(..) => {\n                    // Unlabeled breaks inside nested loops target the inner loop, not ours\n                    return ControlFlow::Continue(Descend::No);\n                },\n                ExprKind::Break(dest, Some(break_expr)) => {\n                    let targets_this_loop =\n                        dest.label.is_none() || dest.label.map(|l| l.ident) == label.map(|l| l.ident);\n                    if targets_this_loop && has_generic_return_type(cx, break_expr) {\n                        return ControlFlow::Break(());\n                    }\n                },\n                _ => {},\n            }\n            ControlFlow::Continue(Descend::Yes)\n        })\n        .is_some(),\n        ExprKind::MethodCall(..) => {\n            if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {\n                let sig = cx.tcx.fn_sig(def_id).instantiate_identity();\n                let ret_ty = sig.output().skip_binder();\n                return ret_ty.has_param();\n            }\n            false\n        },\n        ExprKind::Call(callee, _) => {\n            if let ExprKind::Path(qpath) = &callee.kind {\n                let res = cx.qpath_res(qpath, callee.hir_id);\n                if let Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) = res {\n                    let sig = cx.tcx.fn_sig(def_id).instantiate_identity();\n                    let ret_ty = sig.output().skip_binder();\n                    return ret_ty.has_param();\n                }\n            }\n            false\n        },\n        _ => false,\n    }\n}\n\nfn is_generic_res(cx: &LateContext<'_>, res: Res) -> bool {\n    let has_type_params = |def_id| {\n        cx.tcx\n            .generics_of(def_id)\n            .own_params\n            .iter()\n            .any(|p| p.kind.is_ty_or_const())\n    };\n    cx.tcx.res_generics_def_id(res).is_some_and(has_type_params)\n}\n\nfn is_cast_in_generic_context<'a>(cx: &LateContext<'a>, cast_expr: &Expr<'a>) -> bool {\n    let mut current_id = cast_expr.hir_id;\n\n    loop {\n        let parent_id = cx.tcx.parent_hir_id(current_id);\n        if parent_id == current_id {\n            return false;\n        }\n\n        let parent = cx.tcx.hir_node(parent_id);\n\n        match parent {\n            rustc_hir::Node::Expr(parent_expr) => {\n                match &parent_expr.kind {\n                    ExprKind::Closure(_) => return false,\n                    ExprKind::Call(callee, _) => {\n                        if let ExprKind::Path(qpath) = &callee.kind {\n                            let res = cx.qpath_res(qpath, callee.hir_id);\n                            if is_generic_res(cx, res) {\n                                return true;\n                            }\n                        }\n                    },\n                    ExprKind::MethodCall(..) => {\n                        if let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent_expr.hir_id)\n                            && cx\n                                .tcx\n                                .generics_of(def_id)\n                                .own_params\n                                .iter()\n                                .any(|p| p.kind.is_ty_or_const())\n                        {\n                            return true;\n                        }\n                    },\n                    _ => {},\n                }\n                current_id = parent_id;\n            },\n            _ => return false,\n        }\n    }\n}\n\nfn can_coerce_to_target_type(expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Lit(lit) => matches!(\n            lit.node,\n            LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed)\n        ),\n        ExprKind::Unary(rustc_hir::UnOp::Neg, inner) => can_coerce_to_target_type(inner),\n        ExprKind::Binary(_, lhs, rhs) => can_coerce_to_target_type(lhs) && can_coerce_to_target_type(rhs),\n        _ => false,\n    }\n}\n\nfn check_binding_usages<'a>(cx: &LateContext<'a>, body: &Body<'a>, hir_id: HirId, binding_info: &BindingInfo<'a>) {\n    let mut usages = Vec::new();\n\n    for_each_expr(cx, body.value, |expr| {\n        if let ExprKind::Path(ref qpath) = expr.kind\n            && !expr.span.from_expansion()\n            && let Res::Local(id) = cx.qpath_res(qpath, expr.hir_id)\n            && id == hir_id\n        {\n            let parent_id = cx.tcx.parent_hir_id(expr.hir_id);\n            let parent = cx.tcx.hir_node(parent_id);\n\n            let usage = if let rustc_hir::Node::Expr(parent_expr) = parent\n                && let ExprKind::Cast(..) = parent_expr.kind\n                && !parent_expr.span.from_expansion()\n            {\n                UsageInfo {\n                    cast_to: Some(cx.typeck_results().expr_ty(parent_expr)),\n                    in_generic_context: is_cast_in_generic_context(cx, parent_expr),\n                }\n            } else {\n                UsageInfo {\n                    cast_to: None,\n                    in_generic_context: false,\n                }\n            };\n            usages.push(usage);\n        }\n        ControlFlow::<()>::Continue(())\n    });\n\n    let Some(first_target) = usages\n        .first()\n        .and_then(|u| u.cast_to)\n        .filter(|&t| t != binding_info.source_ty)\n        .filter(|&t| usages.iter().all(|u| u.cast_to == Some(t) && !u.in_generic_context))\n    else {\n        return;\n    };\n\n    // Don't lint if there's exactly one use and the initializer cannot be coerced to the\n    // target type (i.e., would require an explicit cast). In such cases, the fix would add\n    // a cast to the initializer rather than eliminating one - the cast isn't truly \"needless.\"\n    // See: https://github.com/rust-lang/rust-clippy/issues/16240\n    if usages.len() == 1\n        && binding_info\n            .init\n            .is_some_and(|init| !can_coerce_to_target_type(init) && !init.span.from_expansion())\n    {\n        return;\n    }\n\n    span_lint_and_then(\n        cx,\n        NEEDLESS_TYPE_CAST,\n        binding_info.ty_span,\n        format!(\n            \"this binding is defined as `{}` but is always cast to `{}`\",\n            binding_info.source_ty, first_target\n        ),\n        |diag| {\n            if let Some(init) = binding_info\n                .init\n                .filter(|i| !can_coerce_to_target_type(i) && !i.span.from_expansion())\n            {\n                let sugg = Sugg::hir(cx, init, \"..\").as_ty(first_target);\n                diag.multipart_suggestion(\n                    format!(\"consider defining it as `{first_target}` and casting the initializer\"),\n                    vec![\n                        (binding_info.ty_span, first_target.to_string()),\n                        (init.span, sugg.to_string()),\n                    ],\n                    Applicability::MachineApplicable,\n                );\n            } else {\n                diag.span_suggestion(\n                    binding_info.ty_span,\n                    \"consider defining it as\",\n                    first_target.to_string(),\n                    Applicability::MachineApplicable,\n                );\n            }\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/ptr_as_ptr.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg::Sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, Expr, ExprKind, QPath, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::{Span, sym};\n\nuse super::PTR_AS_PTR;\n\nenum OmitFollowedCastReason<'a> {\n    None,\n    Null(&'a QPath<'a>),\n    NullMut(&'a QPath<'a>),\n}\n\nimpl OmitFollowedCastReason<'_> {\n    fn corresponding_item(&self) -> Option<&QPath<'_>> {\n        match self {\n            OmitFollowedCastReason::None => None,\n            OmitFollowedCastReason::Null(x) | OmitFollowedCastReason::NullMut(x) => Some(*x),\n        }\n    }\n}\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'tcx>,\n    cast_from_expr: &Expr<'_>,\n    cast_from: Ty<'_>,\n    cast_to_hir: &hir::Ty<'_>,\n    cast_to: Ty<'tcx>,\n    msrv: Msrv,\n) {\n    if let ty::RawPtr(_, from_mutbl) = cast_from.kind()\n        && let ty::RawPtr(to_pointee_ty, to_mutbl) = cast_to.kind()\n        && from_mutbl == to_mutbl\n        // The `U` in `pointer::cast` have to be `Sized`\n        // as explained here: https://github.com/rust-lang/rust/issues/60602.\n        && to_pointee_ty.is_sized(cx.tcx, cx.typing_env())\n        && msrv.meets(cx, msrvs::POINTER_CAST)\n        && !is_from_proc_macro(cx, expr)\n    {\n        let mut app = Applicability::MachineApplicable;\n        let turbofish = match &cast_to_hir.kind {\n            TyKind::Infer(()) => String::new(),\n            TyKind::Ptr(mut_ty) => {\n                if matches!(mut_ty.ty.kind, TyKind::Infer(())) {\n                    String::new()\n                } else {\n                    format!(\n                        \"::<{}>\",\n                        snippet_with_applicability(cx, mut_ty.ty.span, \"/* type */\", &mut app)\n                    )\n                }\n            },\n            _ => return,\n        };\n\n        // following `cast` does not compile because it fails to infer what type is expected\n        // as type argument to `std::ptr::ptr_null` or `std::ptr::ptr_null_mut`, so\n        // we omit following `cast`:\n        let omit_cast = if let ExprKind::Call(func, []) = cast_from_expr.kind\n            && let ExprKind::Path(ref qpath @ QPath::Resolved(None, path)) = func.kind\n            && let Some(method_defid) = path.res.opt_def_id()\n        {\n            match cx.tcx.get_diagnostic_name(method_defid) {\n                Some(sym::ptr_null) => OmitFollowedCastReason::Null(qpath),\n                Some(sym::ptr_null_mut) => OmitFollowedCastReason::NullMut(qpath),\n                _ => OmitFollowedCastReason::None,\n            }\n        } else {\n            OmitFollowedCastReason::None\n        };\n\n        let (help, final_suggestion) = if let Some(method) = omit_cast.corresponding_item() {\n            // don't force absolute path\n            let method = snippet_with_applicability(cx, qpath_span_without_turbofish(method), \"..\", &mut app);\n            (\"try call directly\", format!(\"{method}{turbofish}()\"))\n        } else {\n            let cast_expr_sugg = Sugg::hir_with_context(cx, cast_from_expr, expr.span.ctxt(), \"_\", &mut app);\n\n            (\n                \"try `pointer::cast`, a safer alternative\",\n                format!(\"{}.cast{turbofish}()\", cast_expr_sugg.maybe_paren()),\n            )\n        };\n\n        span_lint_and_sugg(\n            cx,\n            PTR_AS_PTR,\n            expr.span,\n            \"`as` casting between raw pointers without changing their constness\",\n            help,\n            final_suggestion,\n            app,\n        );\n    }\n}\n\nfn qpath_span_without_turbofish(qpath: &QPath<'_>) -> Span {\n    if let QPath::Resolved(_, path) = qpath\n        && let [.., last_ident] = path.segments\n        && last_ident.args.is_some()\n    {\n        return qpath.span().shrink_to_lo().to(last_ident.ident.span);\n    }\n\n    qpath.span()\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/ptr_cast_constness.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{std_or_core, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, Expr, ExprKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty, TypeVisitableExt};\n\nuse super::PTR_CAST_CONSTNESS;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    cast_from_expr: &Expr<'_>,\n    cast_from: Ty<'tcx>,\n    cast_to: Ty<'tcx>,\n    msrv: Msrv,\n) {\n    if let ty::RawPtr(from_ty, from_mutbl) = cast_from.kind()\n        && let ty::RawPtr(to_ty, to_mutbl) = cast_to.kind()\n        && from_mutbl != to_mutbl\n        && from_ty == to_ty\n        && !from_ty.has_erased_regions()\n    {\n        if let ExprKind::Call(func, []) = cast_from_expr.kind\n            && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind\n            && let Some(defid) = path.res.opt_def_id()\n            && let Some(prefix) = std_or_core(cx)\n            && let mut app = Applicability::MachineApplicable\n            && let sugg = snippet_with_applicability(cx, cast_from_expr.span, \"_\", &mut app)\n            && let Some((_, after_lt)) = sugg.split_once(\"::<\")\n            && let Some((source, target, target_func)) = match cx.tcx.get_diagnostic_name(defid) {\n                Some(sym::ptr_null) => Some((\"const\", \"mutable\", \"null_mut\")),\n                Some(sym::ptr_null_mut) => Some((\"mutable\", \"const\", \"null\")),\n                _ => None,\n            }\n        {\n            span_lint_and_sugg(\n                cx,\n                PTR_CAST_CONSTNESS,\n                expr.span,\n                format!(\"`as` casting to make a {source} null pointer into a {target} null pointer\"),\n                format!(\"use `{target_func}()` directly instead\"),\n                format!(\"{prefix}::ptr::{target_func}::<{after_lt}\"),\n                app,\n            );\n            return;\n        }\n\n        if msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) {\n            let mut app = Applicability::MachineApplicable;\n            let sugg = if let ExprKind::Cast(nested_from, nested_hir_ty) = cast_from_expr.kind\n                && let hir::TyKind::Ptr(ptr_ty) = nested_hir_ty.kind\n                && let hir::TyKind::Infer(()) = ptr_ty.ty.kind\n            {\n                // `(foo as *const _).cast_mut()` fails method name resolution\n                // avoid this by `as`-ing the full type\n                Sugg::hir_with_context(cx, nested_from, expr.span.ctxt(), \"_\", &mut app).as_ty(cast_from)\n            } else {\n                Sugg::hir_with_context(cx, cast_from_expr, expr.span.ctxt(), \"_\", &mut app)\n            };\n            let constness = to_mutbl.ptr_str();\n\n            span_lint_and_sugg(\n                cx,\n                PTR_CAST_CONSTNESS,\n                expr.span,\n                \"`as` casting between raw pointers while changing only its constness\",\n                format!(\"try `pointer::cast_{constness}`, a safer alternative\"),\n                format!(\"{}.cast_{constness}()\", sugg.maybe_paren()),\n                app,\n            );\n        }\n    }\n}\n\npub(super) fn check_null_ptr_cast_method(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let ExprKind::MethodCall(method, cast_from_expr, [], _) = expr.kind\n        && let ExprKind::Call(func, []) = cast_from_expr.kind\n        && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind\n        && let Some(defid) = path.res.opt_def_id()\n        && let method = match (cx.tcx.get_diagnostic_name(defid), method.ident.name) {\n            (Some(sym::ptr_null), sym::cast_mut) => \"null_mut\",\n            (Some(sym::ptr_null_mut), sym::cast_const) => \"null\",\n            _ => return,\n        }\n        && let Some(prefix) = std_or_core(cx)\n        && let mut app = Applicability::MachineApplicable\n        && let sugg = snippet_with_applicability(cx, cast_from_expr.span, \"_\", &mut app)\n        && let Some((_, after_lt)) = sugg.split_once(\"::<\")\n    {\n        span_lint_and_sugg(\n            cx,\n            PTR_CAST_CONSTNESS,\n            expr.span,\n            \"changing constness of a null pointer\",\n            format!(\"use `{method}()` directly instead\"),\n            format!(\"{prefix}::ptr::{method}::<{after_lt}\"),\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/ref_as_ptr.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{ExprUseNode, expr_use_ctxt, is_expr_temporary_value, std_or_core};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Mutability, Ty, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::REF_AS_PTR;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    cast_expr: &'tcx Expr<'_>,\n    cast_to_hir_ty: &Ty<'_>,\n) {\n    let (cast_from, cast_to) = (\n        cx.typeck_results().expr_ty(cast_expr),\n        cx.typeck_results().expr_ty(expr),\n    );\n\n    if matches!(cast_from.kind(), ty::Ref(..))\n        && let ty::RawPtr(_, to_mutbl) = cast_to.kind()\n        && let use_cx = expr_use_ctxt(cx, expr)\n        && let Some(std_or_core) = std_or_core(cx)\n    {\n        if let ExprKind::AddrOf(_, _, addr_inner) = cast_expr.kind\n            && is_expr_temporary_value(cx, addr_inner)\n            && matches!(\n                use_cx.use_node(cx),\n                ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_)\n            )\n        {\n            return;\n        }\n\n        let fn_name = match to_mutbl {\n            Mutability::Not => \"from_ref\",\n            Mutability::Mut => \"from_mut\",\n        };\n\n        let mut app = Applicability::MachineApplicable;\n        let turbofish = match &cast_to_hir_ty.kind {\n            TyKind::Infer(()) => String::new(),\n            TyKind::Ptr(mut_ty) => {\n                if matches!(mut_ty.ty.kind, TyKind::Infer(())) {\n                    String::new()\n                } else {\n                    format!(\n                        \"::<{}>\",\n                        snippet_with_applicability(cx, mut_ty.ty.span, \"/* type */\", &mut app)\n                    )\n                }\n            },\n            _ => return,\n        };\n\n        let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, \"_\", &mut app);\n\n        span_lint_and_sugg(\n            cx,\n            REF_AS_PTR,\n            expr.span,\n            \"reference as raw pointer\",\n            \"try\",\n            format!(\"{std_or_core}::ptr::{fn_name}{turbofish}({cast_expr_sugg})\"),\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/unnecessary_cast.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::numeric_literal::NumericLiteral;\nuse clippy_utils::res::MaybeResPath as _;\nuse clippy_utils::source::{SpanRangeExt, snippet_opt};\nuse clippy_utils::visitors::{Visitable, for_each_expr_without_closures};\nuse clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, sym};\nuse rustc_ast::{LitFloatType, LitIntType, LitKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Expr, ExprKind, FnRetTy, Lit, Node, Path, QPath, TyKind, UnOp};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::adjustment::Adjust;\nuse rustc_middle::ty::{self, FloatTy, InferTy, Ty};\nuse rustc_span::Symbol;\nuse std::ops::ControlFlow;\n\nuse super::UNNECESSARY_CAST;\n\n#[expect(clippy::too_many_lines)]\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'tcx>,\n    cast_expr: &Expr<'tcx>,\n    cast_from: Ty<'tcx>,\n    cast_to: Ty<'tcx>,\n) -> bool {\n    let cast_str = snippet_opt(cx, cast_expr.span).unwrap_or_default();\n\n    if let ty::RawPtr(..) = cast_from.kind()\n        // check both mutability and type are the same\n        && cast_from.kind() == cast_to.kind()\n        && let ExprKind::Cast(_, cast_to_hir) = expr.kind\n        // Ignore casts to e.g. type aliases and infer types\n        // - p as pointer_alias\n        // - p as _\n        && let TyKind::Ptr(to_pointee) = cast_to_hir.kind\n    {\n        match to_pointee.ty.kind {\n            // Ignore casts to pointers that are aliases or cfg dependant, e.g.\n            // - p as *const std::ffi::c_char (alias)\n            // - p as *const std::os::raw::c_char (cfg dependant)\n            TyKind::Path(qpath) if is_ty_alias(&qpath) || is_hir_ty_cfg_dependant(cx, to_pointee.ty) => {\n                return false;\n            },\n            // Ignore `p as *const _`\n            TyKind::Infer(()) => return false,\n            _ => {},\n        }\n\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_CAST,\n            expr.span,\n            format!(\n                \"casting raw pointers to the same type and constness is unnecessary (`{cast_from}` -> `{cast_to}`)\"\n            ),\n            \"try\",\n            cast_str.clone(),\n            Applicability::MaybeIncorrect,\n        );\n    }\n\n    // skip cast of local that is a type alias\n    if let ExprKind::Cast(inner, ..) = expr.kind\n        && let ExprKind::Path(qpath) = inner.kind\n        && let QPath::Resolved(None, Path { res, .. }) = qpath\n        && let Res::Local(hir_id) = res\n        && let parent = cx.tcx.parent_hir_node(*hir_id)\n        && let Node::LetStmt(local) = parent\n    {\n        if let Some(ty) = local.ty\n            && let TyKind::Path(qpath) = ty.kind\n            && is_ty_alias(&qpath)\n        {\n            return false;\n        }\n\n        if let Some(expr) = local.init\n            && let ExprKind::Cast(.., cast_to) = expr.kind\n            && let TyKind::Path(qpath) = cast_to.kind\n            && is_ty_alias(&qpath)\n        {\n            return false;\n        }\n    }\n\n    // skip cast to non-primitive type\n    if let ExprKind::Cast(_, cast_to) = expr.kind\n        && let TyKind::Path(QPath::Resolved(_, path)) = &cast_to.kind\n        && let Res::PrimTy(_) = path.res\n    {\n    } else {\n        return false;\n    }\n\n    // skip cast of fn call that returns type alias\n    if let ExprKind::Cast(inner, ..) = expr.kind\n        && is_cast_from_ty_alias(cx, inner)\n    {\n        return false;\n    }\n\n    if let Some(lit) = get_numeric_literal(cast_expr) {\n        let literal_str = &cast_str;\n\n        if let LitKind::Int(n, _) = lit.node\n            && let Some(src) = cast_expr.span.get_source_text(cx)\n            && cast_to.is_floating_point()\n            && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node)\n            && let from_nbits = 128 - n.get().leading_zeros()\n            && let to_nbits = fp_ty_mantissa_nbits(cast_to)\n            && from_nbits != 0\n            && to_nbits != 0\n            && from_nbits <= to_nbits\n            && num_lit.is_decimal()\n        {\n            lint_unnecessary_cast(cx, expr, num_lit.integer, cast_from, cast_to);\n            return true;\n        }\n\n        match lit.node {\n            LitKind::Int(_, LitIntType::Unsuffixed) if cast_to.is_integral() => {\n                lint_unnecessary_cast(cx, expr, literal_str, cast_from, cast_to);\n                return false;\n            },\n            LitKind::Float(_, LitFloatType::Unsuffixed) if cast_to.is_floating_point() => {\n                lint_unnecessary_cast(cx, expr, literal_str, cast_from, cast_to);\n                return false;\n            },\n            LitKind::Int(_, LitIntType::Signed(_) | LitIntType::Unsigned(_))\n            | LitKind::Float(_, LitFloatType::Suffixed(_))\n                if cast_from.kind() == cast_to.kind() =>\n            {\n                if let Some(src) = cast_expr.span.get_source_text(cx)\n                    && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node)\n                {\n                    lint_unnecessary_cast(cx, expr, num_lit.integer, cast_from, cast_to);\n                    return true;\n                }\n            },\n            _ => {},\n        }\n    }\n\n    if cast_from.kind() == cast_to.kind() && !expr.span.in_external_macro(cx.sess().source_map()) {\n        enum MaybeParenOrBlock {\n            Paren,\n            Block,\n            Nothing,\n        }\n\n        fn is_borrow_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n            matches!(expr.kind, ExprKind::AddrOf(..))\n                || cx\n                    .typeck_results()\n                    .expr_adjustments(expr)\n                    .first()\n                    .is_some_and(|adj| matches!(adj.kind, Adjust::Borrow(_)))\n        }\n\n        fn is_in_allowed_macro(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n            const ALLOWED_MACROS: &[Symbol] = &[\n                sym::format_args_macro,\n                sym::assert_eq_macro,\n                sym::debug_assert_eq_macro,\n                sym::assert_ne_macro,\n                sym::debug_assert_ne_macro,\n            ];\n            matches!(expr.span.ctxt().outer_expn_data().macro_def_id, Some(def_id) if\n                cx.tcx.get_diagnostic_name(def_id).is_some_and(|sym| ALLOWED_MACROS.contains(&sym)))\n        }\n\n        if let Some(id) = cast_expr.res_local_id()\n            && !cx.tcx.hir_span(id).eq_ctxt(cast_expr.span)\n        {\n            // Binding context is different than the identifiers context.\n            // Weird macro wizardry could be involved here.\n            return false;\n        }\n\n        // Changing `&(x as i32)` to `&x` would change the meaning of the code because the previous creates\n        // a reference to the temporary while the latter creates a reference to the original value.\n        let surrounding = match cx.tcx.parent_hir_node(expr.hir_id) {\n            Node::Expr(parent) if is_borrow_expr(cx, parent) && !is_in_allowed_macro(cx, parent) => {\n                MaybeParenOrBlock::Block\n            },\n            Node::Expr(parent) if cx.precedence(cast_expr) < cx.precedence(parent) => MaybeParenOrBlock::Paren,\n            _ => MaybeParenOrBlock::Nothing,\n        };\n\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_CAST,\n            expr.span,\n            format!(\"casting to the same type is unnecessary (`{cast_from}` -> `{cast_to}`)\"),\n            \"try\",\n            match surrounding {\n                MaybeParenOrBlock::Paren => format!(\"({cast_str})\"),\n                MaybeParenOrBlock::Block => format!(\"{{ {cast_str} }}\"),\n                MaybeParenOrBlock::Nothing => cast_str,\n            },\n            Applicability::MachineApplicable,\n        );\n        return true;\n    }\n\n    false\n}\n\nfn lint_unnecessary_cast(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    raw_literal_str: &str,\n    cast_from: Ty<'_>,\n    cast_to: Ty<'_>,\n) {\n    let literal_kind_name = if cast_from.is_integral() { \"integer\" } else { \"float\" };\n    // first we remove all matches so `-(1)` become `-1`, and remove trailing dots, so `1.` become `1`\n    let literal_str = raw_literal_str\n        .replace(['(', ')'], \"\")\n        .trim_end_matches('.')\n        .to_string();\n    // we know need to check if the parent is a method call, to add parenthesis accordingly (eg:\n    // (-1).foo() instead of -1.foo())\n    let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr)\n        && let ExprKind::MethodCall(..) = parent_expr.kind\n        && literal_str.starts_with('-')\n    {\n        format!(\"({literal_str}_{cast_to})\")\n    } else {\n        format!(\"{literal_str}_{cast_to}\")\n    };\n\n    span_lint_and_sugg(\n        cx,\n        UNNECESSARY_CAST,\n        expr.span,\n        format!(\"casting {literal_kind_name} literal to `{cast_to}` is unnecessary\"),\n        \"try\",\n        sugg,\n        Applicability::MachineApplicable,\n    );\n}\n\nfn get_numeric_literal<'e>(expr: &'e Expr<'e>) -> Option<Lit> {\n    match expr.kind {\n        ExprKind::Lit(lit) => Some(lit),\n        ExprKind::Unary(UnOp::Neg, e) => {\n            if let ExprKind::Lit(lit) = e.kind {\n                Some(lit)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\n/// Returns the mantissa bits wide of a fp type.\n/// Will return 0 if the type is not a fp\nfn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 {\n    match typ.kind() {\n        ty::Float(FloatTy::F32) => 23,\n        ty::Float(FloatTy::F64) | ty::Infer(InferTy::FloatVar(_)) => 52,\n        _ => 0,\n    }\n}\n\n/// Finds whether an `Expr` returns a type alias.\n///\n/// When in doubt, for example because it calls a non-local function that we don't have the\n/// declaration for, assume if might be a type alias.\nfn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx>) -> bool {\n    for_each_expr_without_closures(expr, |expr| {\n        // Calls are a `Path`, and usage of locals are a `Path`. So, this checks\n        // - call() as i32\n        // - local as i32\n        if let ExprKind::Path(qpath) = expr.kind {\n            let res = cx.qpath_res(&qpath, expr.hir_id);\n            if let Res::Def(DefKind::Fn, def_id) = res {\n                let Some(def_id) = def_id.as_local() else {\n                    // External function, we can't know, better be safe\n                    return ControlFlow::Break(());\n                };\n                if let Some(FnRetTy::Return(ty)) = cx.tcx.hir_get_fn_output(def_id)\n                    && let TyKind::Path(qpath) = ty.kind\n                    && is_ty_alias(&qpath)\n                {\n                    // Function call to a local function returning a type alias\n                    return ControlFlow::Break(());\n                }\n            // Local usage\n            } else if let Res::Local(hir_id) = res\n                && let Node::LetStmt(l) = cx.tcx.parent_hir_node(hir_id)\n            {\n                if let Some(e) = l.init\n                    && is_cast_from_ty_alias(cx, e)\n                {\n                    return ControlFlow::Break::<()>(());\n                }\n\n                if let Some(ty) = l.ty\n                    && let TyKind::Path(qpath) = ty.kind\n                    && is_ty_alias(&qpath)\n                {\n                    return ControlFlow::Break::<()>(());\n                }\n            }\n        }\n\n        ControlFlow::Continue(())\n    })\n    .is_some()\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/utils.rs",
    "content": "use clippy_utils::ty::{EnumValue, read_explicit_enum_value};\nuse rustc_middle::ty::{self, AdtDef, IntTy, Ty, TyCtxt, UintTy, VariantDiscr};\n\n/// Returns the size in bits of an integral type, or `None` if `ty` is not an\n/// integral type.\npub(super) fn int_ty_to_nbits(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<u64> {\n    match ty.kind() {\n        ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(tcx.data_layout.pointer_size().bits()),\n        ty::Int(i) => i.bit_width(),\n        ty::Uint(i) => i.bit_width(),\n        _ => None,\n    }\n}\n\npub(super) fn enum_value_nbits(value: EnumValue) -> u64 {\n    match value {\n        EnumValue::Unsigned(x) => 128 - x.leading_zeros(),\n        EnumValue::Signed(x) if x < 0 => 128 - (-(x + 1)).leading_zeros() + 1,\n        EnumValue::Signed(x) => 128 - x.leading_zeros(),\n    }\n    .into()\n}\n\npub(super) fn enum_ty_to_nbits(adt: AdtDef<'_>, tcx: TyCtxt<'_>) -> u64 {\n    let mut explicit = 0i128;\n    let (start, end) = adt\n        .variants()\n        .iter()\n        .fold((0, i128::MIN), |(start, end), variant| match variant.discr {\n            VariantDiscr::Relative(x) => match explicit.checked_add(i128::from(x)) {\n                Some(x) => (start, end.max(x)),\n                None => (i128::MIN, end),\n            },\n            VariantDiscr::Explicit(id) => match read_explicit_enum_value(tcx, id) {\n                Some(EnumValue::Signed(x)) => {\n                    explicit = x;\n                    (start.min(x), end.max(x))\n                },\n                Some(EnumValue::Unsigned(x)) => match i128::try_from(x) {\n                    Ok(x) => {\n                        explicit = x;\n                        (start, end.max(x))\n                    },\n                    Err(_) => (i128::MIN, end),\n                },\n                None => (start, end),\n            },\n        });\n\n    if start > end {\n        // No variants.\n        0\n    } else {\n        let neg_bits = if start < 0 {\n            128 - (-(start + 1)).leading_zeros() + 1\n        } else {\n            0\n        };\n        let pos_bits = if end > 0 { 128 - end.leading_zeros() } else { 0 };\n        neg_bits.max(pos_bits).into()\n    }\n}\n\npub(super) enum CastTo {\n    Signed,\n    Unsigned,\n}\n/// Returns `Some` if the type cast is between 2 integral types that differ\n/// only in signedness, otherwise `None`. The value of `Some` is which\n/// signedness is casted to.\npub(super) fn is_signedness_cast(cast_from: Ty<'_>, cast_to: Ty<'_>) -> Option<CastTo> {\n    match (cast_from.kind(), cast_to.kind()) {\n        (ty::Int(from), ty::Uint(to)) if from.to_unsigned() == *to => Some(CastTo::Unsigned),\n        (ty::Uint(from), ty::Int(to)) if *from == to.to_unsigned() => Some(CastTo::Signed),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/casts/zero_ptr.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{is_in_const_context, is_integer_literal, std_or_core};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, Mutability, Ty, TyKind};\nuse rustc_lint::LateContext;\n\nuse super::ZERO_PTR;\n\npub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>, msrv: Msrv) {\n    if let TyKind::Ptr(ref mut_ty) = to.kind\n        && is_integer_literal(from, 0)\n        && (!is_in_const_context(cx) || msrv.meets(cx, msrvs::PTR_NULL))\n        && let Some(std_or_core) = std_or_core(cx)\n    {\n        let (msg, sugg_fn) = match mut_ty.mutbl {\n            Mutability::Mut => (\"`0 as *mut _` detected\", \"ptr::null_mut\"),\n            Mutability::Not => (\"`0 as *const _` detected\", \"ptr::null\"),\n        };\n\n        let sugg = if let TyKind::Infer(()) = mut_ty.ty.kind {\n            format!(\"{std_or_core}::{sugg_fn}()\")\n        } else if let Some(mut_ty_snip) = mut_ty.ty.span.get_source_text(cx) {\n            format!(\"{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()\")\n        } else {\n            return;\n        };\n\n        span_lint_and_sugg(\n            cx,\n            ZERO_PTR,\n            expr.span,\n            msg,\n            \"try\",\n            sugg,\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/cfg_not_test.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::attr::data_structures::CfgEntry;\nuse rustc_ast::{AttrItemKind, EarlyParsedAttribute};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `cfg` that excludes code from `test` builds. (i.e., `#[cfg(not(test))]`)\n    ///\n    /// ### Why is this bad?\n    /// This may give the false impression that a codebase has 100% coverage, yet actually has untested code.\n    /// Enabling this also guards against excessive mockery as well, which is an anti-pattern.\n    ///\n    /// ### Example\n    /// ```rust\n    /// # fn important_check() {}\n    /// #[cfg(not(test))]\n    /// important_check(); // I'm not actually tested, but not including me will falsely increase coverage!\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// # fn important_check() {}\n    /// important_check();\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub CFG_NOT_TEST,\n    restriction,\n    \"enforce against excluding code from test builds\"\n}\n\ndeclare_lint_pass!(CfgNotTest => [CFG_NOT_TEST]);\n\nimpl EarlyLintPass for CfgNotTest {\n    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &rustc_ast::Attribute) {\n        if attr.has_name(sym::cfg_trace) {\n            let AttrItemKind::Parsed(EarlyParsedAttribute::CfgTrace(cfg)) = &attr.get_normal_item().args else {\n                unreachable!()\n            };\n\n            if contains_not_test(cfg, false) {\n                span_lint_and_then(\n                    cx,\n                    CFG_NOT_TEST,\n                    attr.span,\n                    \"code is excluded from test builds\",\n                    |diag| {\n                        diag.help(\"consider not excluding any code from test builds\");\n                        diag.note_once(\"this could increase code coverage despite not actually being tested\");\n                    },\n                );\n            }\n        }\n    }\n}\n\nfn contains_not_test(cfg: &CfgEntry, not: bool) -> bool {\n    match cfg {\n        CfgEntry::All(subs, _) | CfgEntry::Any(subs, _) => subs.iter().any(|item| contains_not_test(item, not)),\n        CfgEntry::Not(sub, _) => contains_not_test(sub, !not),\n        CfgEntry::NameValue { name: sym::test, .. } => not,\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/checked_conversions.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for explicit bounds checking when casting.\n    ///\n    /// ### Why is this bad?\n    /// Reduces the readability of statements & is error prone.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let foo: u32 = 5;\n    /// foo <= i32::MAX as u32;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let foo = 1;\n    /// # #[allow(unused)]\n    /// i32::try_from(foo).is_ok();\n    /// ```\n    #[clippy::version = \"1.37.0\"]\n    pub CHECKED_CONVERSIONS,\n    pedantic,\n    \"`try_from` could replace manual bounds checking when casting\"\n}\n\nimpl_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);\n\npub struct CheckedConversions {\n    msrv: Msrv,\n}\n\nimpl CheckedConversions {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for CheckedConversions {\n    fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {\n        if let ExprKind::Binary(op, lhs, rhs) = item.kind\n            && let (lt1, gt1, op2) = match op.node {\n                BinOpKind::Le => (lhs, rhs, None),\n                BinOpKind::Ge => (rhs, lhs, None),\n                BinOpKind::And\n                    if let ExprKind::Binary(op1, lhs1, rhs1) = lhs.kind\n                        && let ExprKind::Binary(op2, lhs2, rhs2) = rhs.kind\n                        && let Some((lt1, gt1)) = read_le_ge(op1.node, lhs1, rhs1)\n                        && let Some((lt2, gt2)) = read_le_ge(op2.node, lhs2, rhs2) =>\n                {\n                    (lt1, gt1, Some((lt2, gt2)))\n                },\n                _ => return,\n            }\n            && !item.span.in_external_macro(cx.sess().source_map())\n            && !is_in_const_context(cx)\n            && let Some(cv) = match op2 {\n                // todo: check for case signed -> larger unsigned == only x >= 0\n                None => check_upper_bound(lt1, gt1).filter(|cv| cv.cvt == ConversionType::FromUnsigned),\n                Some((lt2, gt2)) => {\n                    let upper_lower = |lt1, gt1, lt2, gt2| {\n                        check_upper_bound(lt1, gt1)\n                            .zip(check_lower_bound(lt2, gt2))\n                            .and_then(|(l, r)| l.combine(r, cx))\n                    };\n                    upper_lower(lt1, gt1, lt2, gt2).or_else(|| upper_lower(lt2, gt2, lt1, gt1))\n                },\n            }\n            && let Some(to_type) = cv.to_type\n            && self.msrv.meets(cx, msrvs::TRY_FROM)\n        {\n            let mut applicability = Applicability::MachineApplicable;\n            let (snippet, _) =\n                snippet_with_context(cx, cv.expr_to_cast.span, item.span.ctxt(), \"_\", &mut applicability);\n            span_lint_and_sugg(\n                cx,\n                CHECKED_CONVERSIONS,\n                item.span,\n                \"checked cast can be simplified\",\n                \"try\",\n                format!(\"{to_type}::try_from({snippet}).is_ok()\"),\n                applicability,\n            );\n        }\n    }\n}\n\n/// Contains the result of a tried conversion check\n#[derive(Clone, Debug)]\nstruct Conversion<'a> {\n    cvt: ConversionType,\n    expr_to_cast: &'a Expr<'a>,\n    to_type: Option<Symbol>,\n}\n\n/// The kind of conversion that is checked\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\nenum ConversionType {\n    SignedToUnsigned,\n    SignedToSigned,\n    FromUnsigned,\n}\n\n/// Attempts to read either `<=` or `>=` with a normalized operand order.\nfn read_le_ge<'tcx>(\n    op: BinOpKind,\n    lhs: &'tcx Expr<'tcx>,\n    rhs: &'tcx Expr<'tcx>,\n) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {\n    match op {\n        BinOpKind::Le => Some((lhs, rhs)),\n        BinOpKind::Ge => Some((rhs, lhs)),\n        _ => None,\n    }\n}\n\nimpl<'a> Conversion<'a> {\n    /// Combine multiple conversions if the are compatible\n    pub fn combine(self, other: Self, cx: &LateContext<'_>) -> Option<Conversion<'a>> {\n        if self.is_compatible(&other, cx) {\n            // Prefer a Conversion that contains a type-constraint\n            Some(if self.to_type.is_some() { self } else { other })\n        } else {\n            None\n        }\n    }\n\n    /// Checks if two conversions are compatible\n    /// same type of conversion, same 'castee' and same 'to type'\n    pub fn is_compatible(&self, other: &Self, cx: &LateContext<'_>) -> bool {\n        (self.cvt == other.cvt)\n            && (SpanlessEq::new(cx).eq_expr(self.expr_to_cast, other.expr_to_cast))\n            && (self.has_compatible_to_type(other))\n    }\n\n    /// Checks if the to-type is the same (if there is a type constraint)\n    fn has_compatible_to_type(&self, other: &Self) -> bool {\n        match (self.to_type, other.to_type) {\n            (Some(l), Some(r)) => l == r,\n            _ => true,\n        }\n    }\n\n    /// Try to construct a new conversion if the conversion type is valid\n    fn try_new(expr_to_cast: &'a Expr<'_>, from_type: Symbol, to_type: Symbol) -> Option<Conversion<'a>> {\n        ConversionType::try_new(from_type, to_type).map(|cvt| Conversion {\n            cvt,\n            expr_to_cast,\n            to_type: Some(to_type),\n        })\n    }\n\n    /// Construct a new conversion without type constraint\n    fn new_any(expr_to_cast: &'a Expr<'_>) -> Conversion<'a> {\n        Conversion {\n            cvt: ConversionType::SignedToUnsigned,\n            expr_to_cast,\n            to_type: None,\n        }\n    }\n}\n\nimpl ConversionType {\n    /// Creates a conversion type if the type is allowed & conversion is valid\n    #[must_use]\n    fn try_new(from: Symbol, to: Symbol) -> Option<Self> {\n        if UINTS.contains(&from) {\n            Some(Self::FromUnsigned)\n        } else if SINTS.contains(&from) {\n            if UINTS.contains(&to) {\n                Some(Self::SignedToUnsigned)\n            } else if SINTS.contains(&to) {\n                Some(Self::SignedToSigned)\n            } else {\n                None\n            }\n        } else {\n            None\n        }\n    }\n}\n\n/// Check for `expr <= (to_type::MAX as from_type)`\nfn check_upper_bound<'tcx>(lt: &'tcx Expr<'tcx>, gt: &'tcx Expr<'tcx>) -> Option<Conversion<'tcx>> {\n    if let Some((from, to)) = get_types_from_cast(gt, INTS, sym::max_value, sym::MAX) {\n        Conversion::try_new(lt, from, to)\n    } else {\n        None\n    }\n}\n\n/// Check for `expr >= 0|(to_type::MIN as from_type)`\nfn check_lower_bound<'tcx>(lt: &'tcx Expr<'tcx>, gt: &'tcx Expr<'tcx>) -> Option<Conversion<'tcx>> {\n    check_lower_bound_zero(gt, lt).or_else(|| check_lower_bound_min(gt, lt))\n}\n\n/// Check for `expr >= 0`\nfn check_lower_bound_zero<'a>(candidate: &'a Expr<'_>, check: &'a Expr<'_>) -> Option<Conversion<'a>> {\n    is_integer_literal(check, 0).then(|| Conversion::new_any(candidate))\n}\n\n/// Check for `expr >= (to_type::MIN as from_type)`\nfn check_lower_bound_min<'a>(candidate: &'a Expr<'_>, check: &'a Expr<'_>) -> Option<Conversion<'a>> {\n    if let Some((from, to)) = get_types_from_cast(check, SINTS, sym::min_value, sym::MIN) {\n        Conversion::try_new(candidate, from, to)\n    } else {\n        None\n    }\n}\n\n/// Tries to extract the from- and to-type from a cast expression\nfn get_types_from_cast(\n    expr: &Expr<'_>,\n    types: &[Symbol],\n    func: Symbol,\n    assoc_const: Symbol,\n) -> Option<(Symbol, Symbol)> {\n    // `to_type::max_value() as from_type`\n    // or `to_type::MAX as from_type`\n    let call_from_cast: Option<(&Expr<'_>, Symbol)> = if let ExprKind::Cast(limit, from_type) = &expr.kind\n        // to_type::max_value(), from_type\n        && let TyKind::Path(from_type_path) = &from_type.kind\n        && let Some(from_sym) = int_ty_to_sym(from_type_path)\n    {\n        Some((limit, from_sym))\n    } else {\n        None\n    };\n\n    // `from_type::from(to_type::max_value())`\n    let limit_from: Option<(&Expr<'_>, Symbol)> = call_from_cast.or_else(|| {\n        if let ExprKind::Call(from_func, [limit]) = &expr.kind\n            // `from_type::from, to_type::max_value()`\n            // `from_type::from`\n            && let ExprKind::Path(path) = &from_func.kind\n            && let Some(from_sym) = get_implementing_type(path, INTS, sym::from)\n        {\n            Some((limit, from_sym))\n        } else {\n            None\n        }\n    });\n\n    if let Some((limit, from_type)) = limit_from {\n        match limit.kind {\n            // `from_type::from(_)`\n            ExprKind::Call(path, _) => {\n                if let ExprKind::Path(ref path) = path.kind\n                    // `to_type`\n                    && let Some(to_type) = get_implementing_type(path, types, func)\n                {\n                    return Some((from_type, to_type));\n                }\n            },\n            // `to_type::MAX`\n            ExprKind::Path(ref path) => {\n                if let Some(to_type) = get_implementing_type(path, types, assoc_const) {\n                    return Some((from_type, to_type));\n                }\n            },\n            _ => {},\n        }\n    }\n    None\n}\n\n/// Gets the type which implements the called function\nfn get_implementing_type(path: &QPath<'_>, candidates: &[Symbol], function: Symbol) -> Option<Symbol> {\n    if let QPath::TypeRelative(ty, path) = &path\n        && path.ident.name == function\n        && let TyKind::Path(QPath::Resolved(None, tp)) = &ty.kind\n        && let [int] = tp.segments\n    {\n        candidates.iter().find(|c| int.ident.name == **c).copied()\n    } else {\n        None\n    }\n}\n\n/// Gets the type as a string, if it is a supported integer\nfn int_ty_to_sym(path: &QPath<'_>) -> Option<Symbol> {\n    if let QPath::Resolved(_, path) = *path\n        && let [ty] = path.segments\n    {\n        INTS.iter().find(|c| ty.ident.name == **c).copied()\n    } else {\n        None\n    }\n}\n\n// Constants\nconst UINTS: &[Symbol] = &[sym::u8, sym::u16, sym::u32, sym::u64, sym::usize];\nconst SINTS: &[Symbol] = &[sym::i8, sym::i16, sym::i32, sym::i64, sym::isize];\nconst INTS: &[Symbol] = &[\n    sym::u8,\n    sym::u16,\n    sym::u32,\n    sym::u64,\n    sym::usize,\n    sym::i8,\n    sym::i16,\n    sym::i32,\n    sym::i64,\n    sym::isize,\n];\n"
  },
  {
    "path": "clippy_lints/src/cloned_ref_to_slice_refs.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::visitors::is_const_evaluatable;\nuse clippy_utils::{is_in_const_context, is_mutable};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for slice references with cloned references such as `&[f.clone()]`.\n    ///\n    /// ### Why is this bad\n    ///\n    /// A reference does not need to be owned in order to be used as a slice.\n    ///\n    /// ### Known problems\n    ///\n    /// This lint does not know whether or not a clone implementation has side effects.\n    ///\n    /// ### Example\n    ///\n    /// ```ignore\n    /// let data = 10;\n    /// let data_ref = &data;\n    /// take_slice(&[data_ref.clone()]);\n    /// ```\n    /// Use instead:\n    /// ```ignore\n    /// use std::slice;\n    /// let data = 10;\n    /// let data_ref = &data;\n    /// take_slice(slice::from_ref(data_ref));\n    /// ```\n    #[clippy::version = \"1.89.0\"]\n    pub CLONED_REF_TO_SLICE_REFS,\n    perf,\n    \"cloning a reference for slice references\"\n}\n\nimpl_lint_pass!(ClonedRefToSliceRefs<'_> => [CLONED_REF_TO_SLICE_REFS]);\n\npub struct ClonedRefToSliceRefs<'a> {\n    msrv: &'a Msrv,\n}\nimpl<'a> ClonedRefToSliceRefs<'a> {\n    pub fn new(conf: &'a Conf) -> Self {\n        Self { msrv: &conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ClonedRefToSliceRefs<'_> {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if self.msrv.meets(cx, {\n            if is_in_const_context(cx) {\n                msrvs::CONST_SLICE_FROM_REF\n            } else {\n                msrvs::SLICE_FROM_REF\n            }\n        })\n            // `&[foo.clone()]` expressions\n            && let ExprKind::AddrOf(_, mutability, arr) = &expr.kind\n            // mutable references would have a different meaning\n            && mutability.is_not()\n\n            // check for single item arrays\n            && let ExprKind::Array([item]) = &arr.kind\n\n            // check for clones\n            && let ExprKind::MethodCall(_, val, _, _) = item.kind\n            && cx.ty_based_def(item).opt_parent(cx).is_diag_item(cx, sym::Clone)\n\n            // check for immutability or purity\n            && (!is_mutable(cx, val) || is_const_evaluatable(cx, val))\n\n            // get appropriate crate for `slice::from_ref`\n            && let Some(builtin_crate) = clippy_utils::std_or_core(cx)\n        {\n            let mut sugg = Sugg::hir(cx, val, \"_\");\n            if !cx.typeck_results().expr_ty(val).is_ref() {\n                sugg = sugg.addr();\n            }\n\n            span_lint_and_sugg(\n                cx,\n                CLONED_REF_TO_SLICE_REFS,\n                expr.span,\n                format!(\"this call to `clone` can be replaced with `{builtin_crate}::slice::from_ref`\"),\n                \"try\",\n                format!(\"{builtin_crate}::slice::from_ref({sugg})\"),\n                Applicability::MaybeIncorrect,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/coerce_container_to_any.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::{self, Sugg};\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::adjustment::{Adjust, PointerCoercion};\nuse rustc_middle::ty::{self, ExistentialPredicate, Ty, TyCtxt};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Protects against unintended coercion of references to container types to `&dyn Any` when the\n    /// container type dereferences to a `dyn Any` which could be directly referenced instead.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// The intention is usually to get a reference to the `dyn Any` the value dereferences to,\n    /// rather than coercing a reference to the container itself to `&dyn Any`.\n    ///\n    /// ### Example\n    ///\n    /// Because `Box<dyn Any>` itself implements `Any`, `&Box<dyn Any>`\n    /// can be coerced to an `&dyn Any` which refers to *the `Box` itself*, rather than the\n    /// inner `dyn Any`.\n    /// ```no_run\n    /// # use std::any::Any;\n    /// let x: Box<dyn Any> = Box::new(0u32);\n    /// let dyn_any_of_box: &dyn Any = &x;\n    ///\n    /// // Fails as we have a &dyn Any to the Box, not the u32\n    /// assert_eq!(dyn_any_of_box.downcast_ref::<u32>(), None);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::any::Any;\n    /// let x: Box<dyn Any> = Box::new(0u32);\n    /// let dyn_any_of_u32: &dyn Any = &*x;\n    ///\n    /// // Succeeds since we have a &dyn Any to the inner u32!\n    /// assert_eq!(dyn_any_of_u32.downcast_ref::<u32>(), Some(&0u32));\n    /// ```\n    #[clippy::version = \"1.89.0\"]\n    pub COERCE_CONTAINER_TO_ANY,\n    nursery,\n    \"coercing to `&dyn Any` when dereferencing could produce a `dyn Any` without coercion is usually not intended\"\n}\n\ndeclare_lint_pass!(CoerceContainerToAny => [COERCE_CONTAINER_TO_ANY]);\n\nimpl<'tcx> LateLintPass<'tcx> for CoerceContainerToAny {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        // If this expression was coerced to `&dyn Any` ...\n        if !cx.typeck_results().expr_adjustments(e).last().is_some_and(|adj| {\n            matches!(adj.kind, Adjust::Pointer(PointerCoercion::Unsize)) && is_ref_dyn_any(cx.tcx, adj.target)\n        }) {\n            return;\n        }\n\n        let expr_ty = cx.typeck_results().expr_ty(e);\n        let ty::Ref(_, expr_ref_ty, _) = *expr_ty.kind() else {\n            return;\n        };\n        // ... but it's not actually `&dyn Any` ...\n        if is_dyn_any(cx.tcx, expr_ref_ty) {\n            return;\n        }\n        // ... and it also *derefs* to `dyn Any` ...\n        let Some((depth, target)) = clippy_utils::ty::deref_chain(cx, expr_ref_ty).enumerate().last() else {\n            return;\n        };\n        if !is_dyn_any(cx.tcx, target) {\n            return;\n        }\n\n        // ... that's probably not intended.\n        let (target_expr, deref_count) = match e.kind {\n            // If `e` was already an `&` expression, skip `*&` in the suggestion\n            ExprKind::AddrOf(_, _, referent) => (referent, depth),\n            _ => (e, depth + 1),\n        };\n        let ty::Ref(_, _, mutability) = *cx.typeck_results().expr_ty_adjusted(e).kind() else {\n            return;\n        };\n        let sugg = sugg::make_unop(\n            &format!(\"{}{}\", mutability.ref_prefix_str(), str::repeat(\"*\", deref_count)),\n            Sugg::hir(cx, target_expr, \"..\"),\n        );\n        span_lint_and_sugg(\n            cx,\n            COERCE_CONTAINER_TO_ANY,\n            e.span,\n            format!(\"coercing `{expr_ty}` to `{}dyn Any`\", mutability.ref_prefix_str()),\n            \"consider dereferencing\",\n            sugg.to_string(),\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n\nfn is_ref_dyn_any(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool {\n    let ty::Ref(_, ref_ty, _) = *ty.kind() else {\n        return false;\n    };\n    is_dyn_any(tcx, ref_ty)\n}\n\nfn is_dyn_any(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool {\n    let ty::Dynamic(traits, ..) = ty.kind() else {\n        return false;\n    };\n    traits.iter().any(|binder| {\n        let ExistentialPredicate::Trait(t) = binder.skip_binder() else {\n            return false;\n        };\n        tcx.is_diagnostic_item(sym::Any, t.def_id)\n    })\n}\n"
  },
  {
    "path": "clippy_lints/src/cognitive_complexity.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{IntoSpan, SpanRangeExt};\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{LimitStack, get_async_fn_body, sym};\nuse core::ops::ControlFlow;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Attribute, Body, Expr, ExprKind, FnDecl};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// We used to think it measured how hard a method is to understand.\n    ///\n    /// ### Why is this bad?\n    /// Ideally, we would like to be able to measure how hard a function is\n    /// to understand given its context (what we call its Cognitive Complexity).\n    /// But that's not what this lint does. See \"Known problems\"\n    ///\n    /// ### Known problems\n    /// The true Cognitive Complexity of a method is not something we can\n    /// calculate using modern technology. This lint has been left in\n    /// `restriction` so as to not mislead users into using this lint as a\n    /// measurement tool.\n    ///\n    /// For more detailed information, see [rust-clippy#3793](https://github.com/rust-lang/rust-clippy/issues/3793)\n    ///\n    /// ### Lints to consider instead of this\n    ///\n    /// * [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting)\n    /// * [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)\n    #[clippy::version = \"1.35.0\"]\n    pub COGNITIVE_COMPLEXITY,\n    restriction,\n    \"functions that should be split up into multiple functions\",\n    @eval_always = true\n}\n\nimpl_lint_pass!(CognitiveComplexity => [COGNITIVE_COMPLEXITY]);\n\npub struct CognitiveComplexity {\n    limit: LimitStack,\n}\n\nimpl CognitiveComplexity {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            limit: LimitStack::new(conf.cognitive_complexity_threshold),\n        }\n    }\n}\n\nimpl CognitiveComplexity {\n    fn check<'tcx>(\n        &self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        expr: &'tcx Expr<'_>,\n        body_span: Span,\n    ) {\n        if body_span.from_expansion() {\n            return;\n        }\n\n        let mut cc = 1u64;\n        let mut returns = 0u64;\n        let mut prev_expr: Option<&ExprKind<'tcx>> = None;\n        let _: Option<!> = for_each_expr_without_closures(expr, |e| {\n            match e.kind {\n                ExprKind::If(_, _, _) => {\n                    cc += 1;\n                },\n                ExprKind::Match(_, arms, _) => {\n                    if arms.len() > 1 {\n                        cc += 1;\n                    }\n                    cc += arms.iter().filter(|arm| arm.guard.is_some()).count() as u64;\n                },\n                ExprKind::Ret(_) if !matches!(prev_expr, Some(ExprKind::Ret(_))) => {\n                    returns += 1;\n                },\n                _ => {},\n            }\n            prev_expr = Some(&e.kind);\n            ControlFlow::Continue(())\n        });\n\n        let ret_ty = cx.typeck_results().node_type(expr.hir_id);\n        let ret_adjust = if ret_ty.is_diag_item(cx, sym::Result) {\n            returns\n        } else {\n            #[expect(clippy::integer_division)]\n            (returns / 2)\n        };\n\n        // prevent degenerate cases where unreachable code contains `return` statements\n        if cc >= ret_adjust {\n            cc -= ret_adjust;\n        }\n\n        if cc > self.limit.limit() {\n            let fn_span = match kind {\n                FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span,\n                FnKind::Closure => {\n                    let header_span = body_span.with_hi(decl.output.span().lo());\n                    if let Some(range) = header_span.map_range(cx, |_, src, range| {\n                        let mut idxs = src.get(range.clone())?.match_indices('|');\n                        Some(range.start + idxs.next()?.0..range.start + idxs.next()?.0 + 1)\n                    }) {\n                        range.with_ctxt(header_span.ctxt())\n                    } else {\n                        return;\n                    }\n                },\n            };\n\n            span_lint_and_help(\n                cx,\n                COGNITIVE_COMPLEXITY,\n                fn_span,\n                format!(\n                    \"the function has a cognitive complexity of ({cc}/{})\",\n                    self.limit.limit()\n                ),\n                None,\n                \"you could split it up into multiple smaller functions\",\n            );\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for CognitiveComplexity {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        span: Span,\n        def_id: LocalDefId,\n    ) {\n        #[allow(deprecated)]\n        if !cx.tcx.has_attr(def_id, sym::test) {\n            let expr = if kind.asyncness().is_async() {\n                match get_async_fn_body(cx.tcx, body) {\n                    Some(b) => b,\n                    None => {\n                        return;\n                    },\n                }\n            } else {\n                body.value\n            };\n\n            self.check(cx, kind, decl, expr, span);\n        }\n    }\n\n    fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {\n        self.limit.push_attrs(cx.sess(), attrs, sym::cognitive_complexity);\n    }\n    fn check_attributes_post(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {\n        self.limit.pop_attrs(cx.sess(), attrs, sym::cognitive_complexity);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/collapsible_if.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::source::{HasSession, IntoSpan as _, SpanRangeExt, snippet, snippet_block_with_applicability};\nuse clippy_utils::{can_use_if_let_chains, span_contains_non_whitespace, sym, tokenize_with_text};\nuse rustc_ast::{BinOpKind, MetaItemInner};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind, StmtKind};\nuse rustc_lexer::TokenKind;\nuse rustc_lint::{LateContext, LateLintPass, Level};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{BytePos, Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for collapsible `else { if ... }` expressions\n    /// that can be collapsed to `else if ...`.\n    ///\n    /// ### Why is this bad?\n    /// Each `if`-statement adds one level of nesting, which\n    /// makes code look more complex than it really is.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    ///\n    /// if x {\n    ///     …\n    /// } else {\n    ///     if y {\n    ///         …\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Should be written:\n    ///\n    /// ```rust,ignore\n    /// if x {\n    ///     …\n    /// } else if y {\n    ///     …\n    /// }\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub COLLAPSIBLE_ELSE_IF,\n    pedantic,\n    \"nested `else`-`if` expressions that can be collapsed (e.g., `else { if x { ... } }`)\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for nested `if` statements which can be collapsed\n    /// by `&&`-combining their conditions.\n    ///\n    /// ### Why is this bad?\n    /// Each `if`-statement adds one level of nesting, which\n    /// makes code look more complex than it really is.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let (x, y) = (true, true);\n    /// if x {\n    ///     if y {\n    ///         // …\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let (x, y) = (true, true);\n    /// if x && y {\n    ///     // …\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub COLLAPSIBLE_IF,\n    style,\n    \"nested `if`s that can be collapsed (e.g., `if x { if y { ... } }`\"\n}\n\nimpl_lint_pass!(CollapsibleIf => [COLLAPSIBLE_ELSE_IF, COLLAPSIBLE_IF]);\n\npub struct CollapsibleIf {\n    msrv: Msrv,\n    lint_commented_code: bool,\n}\n\nimpl CollapsibleIf {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: conf.msrv,\n            lint_commented_code: conf.lint_commented_code,\n        }\n    }\n\n    fn check_collapsible_else_if(&self, cx: &LateContext<'_>, then_span: Span, else_block: &Block<'_>) {\n        if let Some(else_) = expr_block(else_block)\n            && !else_.span.from_expansion()\n            && let ExprKind::If(else_if_cond, ..) = else_.kind\n            && self.check_significant_tokens_and_expect_attrs(cx, else_block, else_, sym::collapsible_else_if)\n        {\n            span_lint_hir_and_then(\n                cx,\n                COLLAPSIBLE_ELSE_IF,\n                else_.hir_id,\n                else_block.span,\n                \"this `else { if .. }` block can be collapsed\",\n                |diag| {\n                    let up_to_else = then_span.between(else_block.span);\n                    let else_before_if = else_.span.shrink_to_lo().with_hi(else_if_cond.span.lo() - BytePos(1));\n                    if self.lint_commented_code\n                        && let Some(else_keyword_span) = span_extract_keyword(cx, up_to_else, \"else\")\n                        && let Some(else_if_keyword_span) = span_extract_keyword(cx, else_before_if, \"if\")\n                    {\n                        let else_keyword_span = else_keyword_span.with_leading_whitespace(cx).into_span();\n                        let else_open_bracket = else_block.span.split_at(1).0.with_leading_whitespace(cx).into_span();\n                        let else_closing_bracket = {\n                            let end = else_block.span.shrink_to_hi();\n                            end.with_lo(end.lo() - BytePos(1))\n                                .with_leading_whitespace(cx)\n                                .into_span()\n                        };\n                        let sugg = vec![\n                            // Remove the outer else block `else`\n                            (else_keyword_span, String::new()),\n                            // Replace the inner `if` by `else if`\n                            (else_if_keyword_span, String::from(\"else if\")),\n                            // Remove the outer else block `{`\n                            (else_open_bracket, String::new()),\n                            // Remove the outer else block '}'\n                            (else_closing_bracket, String::new()),\n                        ];\n                        diag.multipart_suggestion(\"collapse nested if block\", sugg, Applicability::MachineApplicable);\n                        return;\n                    }\n\n                    // Peel off any parentheses.\n                    let (_, else_block_span, _) = peel_parens(cx, else_.span);\n\n                    // Prevent \"elseif\"\n                    // Check that the \"else\" is followed by whitespace\n                    let requires_space = snippet(cx, up_to_else, \"..\").ends_with(|c: char| !c.is_whitespace());\n                    let mut applicability = Applicability::MachineApplicable;\n                    diag.span_suggestion(\n                        else_block.span,\n                        \"collapse nested if block\",\n                        format!(\n                            \"{}{}\",\n                            if requires_space { \" \" } else { \"\" },\n                            snippet_block_with_applicability(\n                                cx,\n                                else_block_span,\n                                \"..\",\n                                Some(else_block.span),\n                                &mut applicability\n                            )\n                        ),\n                        applicability,\n                    );\n                },\n            );\n        }\n    }\n\n    fn check_collapsible_if_if(&self, cx: &LateContext<'_>, expr: &Expr<'_>, check: &Expr<'_>, then: &Block<'_>) {\n        if let Some(inner) = expr_block(then)\n            && let ExprKind::If(check_inner, _, None) = &inner.kind\n            && self.eligible_condition(cx, check_inner)\n            && expr.span.eq_ctxt(inner.span)\n            && self.check_significant_tokens_and_expect_attrs(cx, then, inner, sym::collapsible_if)\n        {\n            span_lint_hir_and_then(\n                cx,\n                COLLAPSIBLE_IF,\n                inner.hir_id,\n                expr.span,\n                \"this `if` statement can be collapsed\",\n                |diag| {\n                    let then_open_bracket = then.span.split_at(1).0.with_leading_whitespace(cx).into_span();\n                    let then_closing_bracket = {\n                        let end = then.span.shrink_to_hi();\n                        end.with_lo(end.lo() - BytePos(1))\n                            .with_leading_whitespace(cx)\n                            .into_span()\n                    };\n                    let (paren_start, inner_if_span, paren_end) = peel_parens(cx, inner.span);\n                    let inner_if = inner_if_span.split_at(2).0;\n                    let mut sugg = vec![\n                        // Remove the outer then block `{`\n                        (then_open_bracket, String::new()),\n                        // Remove the outer then block '}'\n                        (then_closing_bracket, String::new()),\n                        // Replace inner `if` by `&&`\n                        (inner_if, String::from(\"&&\")),\n                    ];\n\n                    if !paren_start.is_empty() {\n                        // Remove any leading parentheses '('\n                        sugg.push((paren_start, String::new()));\n                    }\n\n                    if !paren_end.is_empty() {\n                        // Remove any trailing parentheses ')'\n                        sugg.push((paren_end, String::new()));\n                    }\n\n                    sugg.extend(parens_around(check));\n                    sugg.extend(parens_around(check_inner));\n\n                    diag.multipart_suggestion(\"collapse nested if block\", sugg, Applicability::MachineApplicable);\n                },\n            );\n        }\n    }\n\n    fn eligible_condition(&self, cx: &LateContext<'_>, cond: &Expr<'_>) -> bool {\n        !matches!(cond.kind, ExprKind::Let(..)) || can_use_if_let_chains(cx, self.msrv)\n    }\n\n    // Check that nothing significant can be found between the initial `{` of `inner_if` and\n    // the beginning of `inner_if_expr`...\n    //\n    // Unless it's only an `#[expect(clippy::collapsible{,_else}_if)]` attribute, in which case we\n    // _do_ need to lint, in order to actually fulfill its expectation (#13365)\n    fn check_significant_tokens_and_expect_attrs(\n        &self,\n        cx: &LateContext<'_>,\n        inner_if: &Block<'_>,\n        inner_if_expr: &Expr<'_>,\n        expected_lint_name: Symbol,\n    ) -> bool {\n        match cx.tcx.hir_attrs(inner_if_expr.hir_id) {\n            [] => {\n                // There aren't any attributes, so just check for significant tokens\n                let span = inner_if.span.split_at(1).1.until(inner_if_expr.span);\n                !span_contains_non_whitespace(cx, span, self.lint_commented_code)\n            },\n\n            [attr]\n                if matches!(Level::from_attr(attr), Some((Level::Expect, _)))\n                    && let Some(metas) = attr.meta_item_list()\n                    && let Some(MetaItemInner::MetaItem(meta_item)) = metas.first()\n                    && let [tool, lint_name] = meta_item.path.segments.as_slice()\n                    && tool.ident.name == sym::clippy\n                    && [expected_lint_name, sym::style, sym::all].contains(&lint_name.ident.name) =>\n            {\n                // There is an `expect` attribute -- check that there is no _other_ significant text\n                let span_before_attr = inner_if.span.split_at(1).1.until(attr.span());\n                let span_after_attr = attr.span().between(inner_if_expr.span);\n                !span_contains_non_whitespace(cx, span_before_attr, self.lint_commented_code)\n                    && !span_contains_non_whitespace(cx, span_after_attr, self.lint_commented_code)\n            },\n\n            // There are other attributes, which are significant tokens -- check failed\n            _ => false,\n        }\n    }\n}\n\nimpl LateLintPass<'_> for CollapsibleIf {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if let ExprKind::If(cond, then, else_) = &expr.kind\n            && !expr.span.from_expansion()\n        {\n            if let Some(else_) = else_\n                // Short circuit if both `if` branches contain only a single `if {..} else {}`, as\n                // collapsing such blocks can lead to less readable code (#4971)\n                && !(single_inner_if_else(then) && single_inner_if_else(else_))\n                && let ExprKind::Block(else_, None) = else_.kind\n            {\n                self.check_collapsible_else_if(cx, then.span, else_);\n            } else if else_.is_none()\n                && self.eligible_condition(cx, cond)\n                && let ExprKind::Block(then, None) = then.kind\n            {\n                self.check_collapsible_if_if(cx, expr, cond, then);\n            }\n        }\n    }\n}\n\n/// Returns true if `expr` is a block that contains only one `if {..} else {}` statement\nfn single_inner_if_else(expr: &Expr<'_>) -> bool {\n    if let ExprKind::Block(block, None) = expr.kind\n        && let Some(inner_expr) = expr_block(block)\n        && let ExprKind::If(_, _, else_) = inner_expr.kind\n        && else_.is_some()\n    {\n        true\n    } else {\n        false\n    }\n}\n\n/// If `block` is a block with either one expression or a statement containing an expression,\n/// return the expression. We don't peel blocks recursively, as extra blocks might be intentional.\nfn expr_block<'tcx>(block: &Block<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    match (block.stmts, block.expr) {\n        ([], expr) => expr,\n        ([stmt], None) if let StmtKind::Semi(expr) = stmt.kind => Some(expr),\n        _ => None,\n    }\n}\n\n/// If the expression is a `||`, suggest parentheses around it.\npub(super) fn parens_around(expr: &Expr<'_>) -> Vec<(Span, String)> {\n    if let ExprKind::Binary(op, _, _) = expr.peel_drop_temps().kind\n        && op.node == BinOpKind::Or\n    {\n        vec![\n            (expr.span.shrink_to_lo(), String::from(\"(\")),\n            (expr.span.shrink_to_hi(), String::from(\")\")),\n        ]\n    } else {\n        vec![]\n    }\n}\n\nfn span_extract_keyword(cx: &impl HasSession, span: Span, keyword: &str) -> Option<Span> {\n    span.with_source_text(cx, |snippet| {\n        tokenize_with_text(snippet)\n            .filter(|(t, s, _)| matches!(t, TokenKind::Ident if *s == keyword))\n            .map(|(_, _, inner)| {\n                span.split_at(u32::try_from(inner.start).unwrap())\n                    .1\n                    .split_at(u32::try_from(inner.end - inner.start).unwrap())\n                    .0\n            })\n            .next()\n    })\n    .flatten()\n}\n\n/// Peel the parentheses from an `if` expression, e.g. `((if true {} else {}))`.\npub(super) fn peel_parens(cx: &impl HasSession, mut span: Span) -> (Span, Span, Span) {\n    use crate::rustc_span::Pos;\n\n    let start = span.shrink_to_lo();\n    let end = span.shrink_to_hi();\n\n    span.with_source_text(cx, |snippet| {\n        if let Some((trim_start, _, trim_end)) = peel_parens_str(snippet) {\n            let mut data = span.data();\n            data.lo = data.lo + BytePos::from_usize(trim_start);\n            data.hi = data.hi - BytePos::from_usize(trim_end);\n            span = data.span();\n        }\n    });\n\n    (start.with_hi(span.lo()), span, end.with_lo(span.hi()))\n}\n\nfn peel_parens_str(snippet: &str) -> Option<(usize, &str, usize)> {\n    let trimmed = snippet.trim();\n    if !(trimmed.starts_with('(') && trimmed.ends_with(')')) {\n        return None;\n    }\n\n    let trim_start = (snippet.len() - snippet.trim_start().len()) + 1;\n    let trim_end = (snippet.len() - snippet.trim_end().len()) + 1;\n\n    let inner = snippet.get(trim_start..snippet.len() - trim_end)?;\n    Some(match peel_parens_str(inner) {\n        None => (trim_start, inner, trim_end),\n        Some((start, inner, end)) => (trim_start + start, inner, trim_end + end),\n    })\n}\n"
  },
  {
    "path": "clippy_lints/src/collection_is_never_read.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::visitors::{Visitable, for_each_expr};\nuse clippy_utils::{get_enclosing_block, sym};\nuse core::ops::ControlFlow;\nuse rustc_hir::{Body, ExprKind, HirId, LangItem, LetStmt, Node, PatKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for collections that are never queried.\n    ///\n    /// ### Why is this bad?\n    /// Putting effort into constructing a collection but then never querying it might indicate that\n    /// the author forgot to do whatever they intended to do with the collection. Example: Clone\n    /// a vector, sort it for iteration, but then mistakenly iterate the original vector\n    /// instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let samples = vec![3, 1, 2];\n    /// let mut sorted_samples = samples.clone();\n    /// sorted_samples.sort();\n    /// for sample in &samples { // Oops, meant to use `sorted_samples`.\n    ///     println!(\"{sample}\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let samples = vec![3, 1, 2];\n    /// let mut sorted_samples = samples.clone();\n    /// sorted_samples.sort();\n    /// for sample in &sorted_samples {\n    ///     println!(\"{sample}\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub COLLECTION_IS_NEVER_READ,\n    nursery,\n    \"a collection is never queried\"\n}\n\ndeclare_lint_pass!(CollectionIsNeverRead => [COLLECTION_IS_NEVER_READ]);\n\nimpl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {\n        // Look for local variables whose type is a container. Search surrounding block for read access.\n        if let PatKind::Binding(_, local_id, _, _) = local.pat.kind\n            && match_acceptable_type(cx, local)\n            && let Some(enclosing_block) = get_enclosing_block(cx, local.hir_id)\n            && has_no_read_access(cx, local_id, enclosing_block)\n        {\n            span_lint(cx, COLLECTION_IS_NEVER_READ, local.span, \"collection is never read\");\n        }\n    }\n}\n\nfn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {\n    let ty = cx.typeck_results().pat_ty(local.pat);\n    matches!(\n        ty.opt_diag_name(cx),\n        Some(\n            sym::BTreeMap\n                | sym::BTreeSet\n                | sym::BinaryHeap\n                | sym::HashMap\n                | sym::HashSet\n                | sym::LinkedList\n                | sym::Option\n                | sym::Vec\n                | sym::VecDeque\n        )\n    ) || ty.is_lang_item(cx, LangItem::String)\n}\n\nfn has_no_read_access<'tcx, T: Visitable<'tcx>>(cx: &LateContext<'tcx>, id: HirId, block: T) -> bool {\n    let mut has_access = false;\n    let mut has_read_access = false;\n\n    // Inspect all expressions and sub-expressions in the block.\n    for_each_expr(cx, block, |expr| {\n        // Ignore expressions that are not simply `id`.\n        if expr.res_local_id() != Some(id) {\n            return ControlFlow::Continue(());\n        }\n\n        // `id` is being accessed. Investigate if it's a read access.\n        has_access = true;\n\n        // `id` appearing in the left-hand side of an assignment is not a read access:\n        //\n        // id = ...; // Not reading `id`.\n        if let Node::Expr(parent) = cx.tcx.parent_hir_node(expr.hir_id)\n            && let ExprKind::Assign(lhs, ..) = parent.kind\n            && lhs.res_local_id() == Some(id)\n        {\n            return ControlFlow::Continue(());\n        }\n\n        // Look for method call with receiver `id`. It might be a non-read access:\n        //\n        // id.foo(args)\n        //\n        // Only assuming this for \"official\" methods defined on the type. For methods defined in extension\n        // traits (identified as local, based on the orphan rule), pessimistically assume that they might\n        // have side effects, so consider them a read.\n        if let Node::Expr(parent) = cx.tcx.parent_hir_node(expr.hir_id)\n            && let ExprKind::MethodCall(_, receiver, args, _) = parent.kind\n            && receiver.res_local_id() == Some(id)\n            && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)\n            && !method_def_id.is_local()\n        {\n            // If this \"official\" method takes closures,\n            // it has read access if one of the closures has read access.\n            //\n            // items.retain(|item| send_item(item).is_ok());\n            let is_read_in_closure_arg = args.iter().any(|arg| {\n                if let ExprKind::Closure(closure) = arg.kind\n                    // To keep things simple, we only check the first param to see if its read.\n                    && let Body { params: [param, ..], value } = cx.tcx.hir_body(closure.body)\n                {\n                    !has_no_read_access(cx, param.hir_id, *value)\n                } else {\n                    false\n                }\n            });\n            if is_read_in_closure_arg {\n                has_read_access = true;\n                return ControlFlow::Break(());\n            }\n\n            // The method call is a statement, so the return value is not used. That's not a read access:\n            //\n            // id.foo(args);\n            if let Node::Stmt(..) = cx.tcx.parent_hir_node(parent.hir_id) {\n                return ControlFlow::Continue(());\n            }\n\n            // The method call is not a statement, so its return value is used somehow but its type is the\n            // unit type, so this is not a real read access. Examples:\n            //\n            // let y = x.clear();\n            // println!(\"{:?}\", x.clear());\n            if cx.typeck_results().expr_ty(parent).is_unit() {\n                return ControlFlow::Continue(());\n            }\n        }\n\n        // Any other access to `id` is a read access. Stop searching.\n        has_read_access = true;\n        ControlFlow::Break(())\n    });\n\n    // Ignore collections that have no access at all. Other lints should catch them.\n    has_access && !has_read_access\n}\n"
  },
  {
    "path": "clippy_lints/src/comparison_chain.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{SpanlessEq, if_sequence, is_else_clause, is_in_const_context};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks comparison chains written with `if` that can be\n    /// rewritten with `match` and `cmp`.\n    ///\n    /// ### Why is this bad?\n    /// `if` is not guaranteed to be exhaustive and conditionals can get\n    /// repetitive\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// # fn a() {}\n    /// # fn b() {}\n    /// # fn c() {}\n    /// fn f(x: u8, y: u8) {\n    ///     if x > y {\n    ///         a()\n    ///     } else if x < y {\n    ///         b()\n    ///     } else {\n    ///         c()\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// use std::cmp::Ordering;\n    /// # fn a() {}\n    /// # fn b() {}\n    /// # fn c() {}\n    /// fn f(x: u8, y: u8) {\n    ///      match x.cmp(&y) {\n    ///          Ordering::Greater => a(),\n    ///          Ordering::Less => b(),\n    ///          Ordering::Equal => c()\n    ///      }\n    /// }\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub COMPARISON_CHAIN,\n    pedantic,\n    \"`if`s that can be rewritten with `match` and `cmp`\"\n}\n\ndeclare_lint_pass!(ComparisonChain => [COMPARISON_CHAIN]);\n\nimpl<'tcx> LateLintPass<'tcx> for ComparisonChain {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        // We only care about the top-most `if` in the chain\n        if is_else_clause(cx.tcx, expr) {\n            return;\n        }\n\n        if is_in_const_context(cx) {\n            return;\n        }\n\n        // Check that there exists at least one explicit else condition\n        let (conds, blocks) = if_sequence(expr);\n        if conds.len() < 2 {\n            return;\n        }\n\n        if blocks.len() < 3 {\n            return;\n        }\n\n        for cond in conds.windows(2) {\n            if let (&ExprKind::Binary(ref kind1, lhs1, rhs1), &ExprKind::Binary(ref kind2, lhs2, rhs2)) =\n                (&cond[0].kind, &cond[1].kind)\n            {\n                if !kind_is_cmp(kind1.node) || !kind_is_cmp(kind2.node) {\n                    return;\n                }\n\n                // Check that both sets of operands are equal\n                let mut spanless_eq = SpanlessEq::new(cx);\n                let same_fixed_operands = spanless_eq.eq_expr(lhs1, lhs2) && spanless_eq.eq_expr(rhs1, rhs2);\n                let same_transposed_operands = spanless_eq.eq_expr(lhs1, rhs2) && spanless_eq.eq_expr(rhs1, lhs2);\n\n                if !same_fixed_operands && !same_transposed_operands {\n                    return;\n                }\n\n                // Check that if the operation is the same, either it's not `==` or the operands are transposed\n                if kind1.node == kind2.node {\n                    if kind1.node == BinOpKind::Eq {\n                        return;\n                    }\n                    if !same_transposed_operands {\n                        return;\n                    }\n                }\n\n                // Check that the type being compared implements `core::cmp::Ord`\n                let ty = cx.typeck_results().expr_ty(lhs1);\n                let is_ord = cx\n                    .tcx\n                    .get_diagnostic_item(sym::Ord)\n                    .is_some_and(|id| implements_trait(cx, ty, id, &[]));\n\n                if !is_ord {\n                    return;\n                }\n            } else {\n                // We only care about comparison chains\n                return;\n            }\n        }\n        let ExprKind::Binary(_, lhs, rhs) = conds[0].kind else {\n            unreachable!();\n        };\n\n        let lhs = Sugg::hir(cx, lhs, \"..\").maybe_paren();\n        let rhs = Sugg::hir(cx, rhs, \"..\").addr();\n        span_lint_and_sugg(\n            cx,\n            COMPARISON_CHAIN,\n            expr.span,\n            \"`if` chain can be rewritten with `match`\",\n            \"consider rewriting the `if` chain with `match`\",\n            format!(\"match {lhs}.cmp({rhs}) {{...}}\"),\n            Applicability::HasPlaceholders,\n        );\n    }\n}\n\nfn kind_is_cmp(kind: BinOpKind) -> bool {\n    matches!(kind, BinOpKind::Lt | BinOpKind::Gt | BinOpKind::Eq)\n}\n"
  },
  {
    "path": "clippy_lints/src/copy_iterator.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_note;\nuse clippy_utils::ty::is_copy;\nuse rustc_hir::{Impl, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for types that implement `Copy` as well as\n    /// `Iterator`.\n    ///\n    /// ### Why is this bad?\n    /// Implicit copies can be confusing when working with\n    /// iterator combinators.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// #[derive(Copy, Clone)]\n    /// struct Countdown(u8);\n    ///\n    /// impl Iterator for Countdown {\n    ///     // ...\n    /// }\n    ///\n    /// let a: Vec<_> = my_iterator.take(1).collect();\n    /// let b: Vec<_> = my_iterator.collect();\n    /// ```\n    #[clippy::version = \"1.30.0\"]\n    pub COPY_ITERATOR,\n    pedantic,\n    \"implementing `Iterator` on a `Copy` type\"\n}\n\ndeclare_lint_pass!(CopyIterator => [COPY_ITERATOR]);\n\nimpl<'tcx> LateLintPass<'tcx> for CopyIterator {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            ..\n        }) = item.kind\n            && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n            && is_copy(cx, ty)\n            && let Some(trait_id) = of_trait.trait_ref.trait_def_id()\n            && cx.tcx.is_diagnostic_item(sym::Iterator, trait_id)\n        {\n            span_lint_and_note(\n                cx,\n                COPY_ITERATOR,\n                item.span,\n                \"you are implementing `Iterator` on a `Copy` type\",\n                None,\n                \"consider implementing `IntoIterator` instead\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/crate_in_macro_def.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse rustc_ast::ast::{AttrKind, Attribute, Item, ItemKind};\nuse rustc_ast::token::{Token, TokenKind};\nuse rustc_ast::tokenstream::{TokenStream, TokenTree};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::sym;\nuse rustc_span::{Span, kw};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `crate` as opposed to `$crate` in a macro definition.\n    ///\n    /// ### Why is this bad?\n    /// `crate` refers to the macro call's crate, whereas `$crate` refers to the macro definition's\n    /// crate. Rarely is the former intended. See:\n    /// https://doc.rust-lang.org/reference/macros-by-example.html#hygiene\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[macro_export]\n    /// macro_rules! print_message {\n    ///     () => {\n    ///         println!(\"{}\", crate::MESSAGE);\n    ///     };\n    /// }\n    /// pub const MESSAGE: &str = \"Hello!\";\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[macro_export]\n    /// macro_rules! print_message {\n    ///     () => {\n    ///         println!(\"{}\", $crate::MESSAGE);\n    ///     };\n    /// }\n    /// pub const MESSAGE: &str = \"Hello!\";\n    /// ```\n    ///\n    /// Note that if the use of `crate` is intentional, an `allow` attribute can be applied to the\n    /// macro definition, e.g.:\n    /// ```rust,ignore\n    /// #[allow(clippy::crate_in_macro_def)]\n    /// macro_rules! ok { ... crate::foo ... }\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub CRATE_IN_MACRO_DEF,\n    suspicious,\n    \"using `crate` in a macro definition\"\n}\n\ndeclare_lint_pass!(CrateInMacroDef => [CRATE_IN_MACRO_DEF]);\n\nimpl EarlyLintPass for CrateInMacroDef {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if let ItemKind::MacroDef(_, macro_def) = &item.kind\n            && item.attrs.iter().any(is_macro_export)\n            && let Some(span) = contains_unhygienic_crate_reference(&macro_def.body.tokens)\n        {\n            span_lint_and_sugg(\n                cx,\n                CRATE_IN_MACRO_DEF,\n                span,\n                \"`crate` references the macro call's crate\",\n                \"to reference the macro definition's crate, use\",\n                String::from(\"$crate\"),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n\nfn is_macro_export(attr: &Attribute) -> bool {\n    if let AttrKind::Normal(normal) = &attr.kind\n        && let [segment] = normal.item.path.segments.as_slice()\n    {\n        segment.ident.name == sym::macro_export\n    } else {\n        false\n    }\n}\n\nfn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option<Span> {\n    let mut prev_is_dollar = false;\n    let mut iter = tts.iter();\n    while let Some(curr) = iter.next() {\n        if !prev_is_dollar\n            && let Some(span) = is_crate_keyword(curr)\n            && let Some(next) = iter.peek()\n            && is_token(next, &TokenKind::PathSep)\n        {\n            return Some(span);\n        }\n        if let TokenTree::Delimited(.., tts) = &curr {\n            let span = contains_unhygienic_crate_reference(tts);\n            if span.is_some() {\n                return span;\n            }\n        }\n        prev_is_dollar = is_token(curr, &TokenKind::Dollar);\n    }\n    None\n}\n\nfn is_crate_keyword(tt: &TokenTree) -> Option<Span> {\n    if let TokenTree::Token(\n        Token {\n            kind: TokenKind::Ident(kw::Crate, _),\n            span,\n        },\n        _,\n    ) = tt\n    {\n        Some(*span)\n    } else {\n        None\n    }\n}\n\nfn is_token(tt: &TokenTree, kind: &TokenKind) -> bool {\n    if let TokenTree::Token(Token { kind: other, .. }, _) = tt {\n        kind == other\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/create_dir.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.\n    ///\n    /// ### Why restrict this?\n    /// Sometimes `std::fs::create_dir` is mistakenly chosen over `std::fs::create_dir_all`,\n    /// resulting in failure when more than one directory needs to be created or when the directory already exists.\n    /// Crates which never need to specifically create a single directory may wish to prevent this mistake.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// std::fs::create_dir(\"foo\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// std::fs::create_dir_all(\"foo\");\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub CREATE_DIR,\n    restriction,\n    \"calling `std::fs::create_dir` instead of `std::fs::create_dir_all`\"\n}\n\ndeclare_lint_pass!(CreateDir => [CREATE_DIR]);\n\nimpl LateLintPass<'_> for CreateDir {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if let ExprKind::Call(func, [_]) = expr.kind\n            && let ExprKind::Path(ref path) = func.kind\n            && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()\n            && cx.tcx.is_diagnostic_item(sym::fs_create_dir, def_id)\n            && let QPath::Resolved(_, path) = path\n            && let Some(last) = path.segments.last()\n        {\n            span_lint_and_then(\n                cx,\n                CREATE_DIR,\n                expr.span,\n                \"calling `std::fs::create_dir` where there may be a better way\",\n                |diag| {\n                    let mut suggestions = vec![(last.ident.span.shrink_to_hi(), \"_all\".to_owned())];\n                    if path.segments.len() == 1 {\n                        suggestions.push((path.span.shrink_to_lo(), \"std::fs::\".to_owned()));\n                    }\n\n                    diag.multipart_suggestion(\n                        \"consider calling `std::fs::create_dir_all` instead\",\n                        suggestions,\n                        Applicability::MaybeIncorrect,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/dbg_macro.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{MacroCall, macro_backtrace};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{is_in_test, sym};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Arm, Closure, ClosureKind, CoroutineKind, Expr, ExprKind, LetStmt, LocalSource, Node, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, SyntaxContext};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of the [`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro.\n    ///\n    /// ### Why restrict this?\n    /// The `dbg!` macro is intended as a debugging tool. It should not be present in released\n    /// software or committed to a version control system.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// dbg!(true)\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// true\n    /// ```\n    #[clippy::version = \"1.34.0\"]\n    pub DBG_MACRO,\n    restriction,\n    \"`dbg!` macro is intended as a debugging tool\"\n}\n\nimpl_lint_pass!(DbgMacro => [DBG_MACRO]);\n\npub struct DbgMacro {\n    allow_dbg_in_tests: bool,\n    /// Tracks the `dbg!` macro callsites that are already checked.\n    checked_dbg_call_site: FxHashSet<Span>,\n    /// Tracks the previous `SyntaxContext`, to avoid walking the same context chain.\n    prev_ctxt: SyntaxContext,\n}\n\nimpl DbgMacro {\n    pub fn new(conf: &'static Conf) -> Self {\n        DbgMacro {\n            allow_dbg_in_tests: conf.allow_dbg_in_tests,\n            checked_dbg_call_site: FxHashSet::default(),\n            prev_ctxt: SyntaxContext::root(),\n        }\n    }\n}\n\nimpl LateLintPass<'_> for DbgMacro {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let cur_syntax_ctxt = expr.span.ctxt();\n\n        if cur_syntax_ctxt != self.prev_ctxt &&\n            let Some(macro_call) = first_dbg_macro_in_expansion(cx, expr.span) &&\n            !macro_call.span.in_external_macro(cx.sess().source_map()) &&\n            // avoids exprs generated by the desugaring of coroutines\n            !is_coroutine_desugar(expr) &&\n            self.checked_dbg_call_site.insert(macro_call.span) &&\n            // allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml\n            !(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))\n        {\n            self.prev_ctxt = cur_syntax_ctxt;\n\n            span_lint_and_then(\n                cx,\n                DBG_MACRO,\n                macro_call.span,\n                \"the `dbg!` macro is intended as a debugging tool\",\n                |diag| {\n                    let mut applicability = Applicability::MachineApplicable;\n                    let (sugg_span, suggestion) = match is_async_move_desugar(expr)\n                        .unwrap_or(expr)\n                        .peel_drop_temps()\n                        .kind\n                    {\n                        // dbg!()\n                        ExprKind::Block(..) => {\n                            // If the `dbg!` macro is a \"free\" statement and not contained within other expressions,\n                            // remove the whole statement.\n                            if let Node::Stmt(_) = cx.tcx.parent_hir_node(expr.hir_id)\n                                && let Some(semi_span) = cx.sess().source_map().mac_call_stmt_semi_span(macro_call.span)\n                            {\n                                (macro_call.span.to(semi_span), String::new())\n                            } else {\n                                (macro_call.span, String::from(\"()\"))\n                            }\n                        },\n                        ExprKind::Match(first, arms, _) => {\n                            let vals = collect_vals(first, arms);\n                            let suggestion = match *vals.as_slice() {\n                                // dbg!(1) => 1\n                                [val] => {\n                                    snippet_with_applicability(cx, val.span.source_callsite(), \"..\", &mut applicability)\n                                        .to_string()\n                                },\n                                // dbg!(2, 3) => (2, 3)\n                                [first, .., last] => {\n                                    let snippet = snippet_with_applicability(\n                                        cx,\n                                        first.span.source_callsite().to(last.span.source_callsite()),\n                                        \"..\",\n                                        &mut applicability,\n                                    );\n                                    format!(\"({snippet})\")\n                                },\n                                _ => unreachable!(),\n                            };\n                            (macro_call.span, suggestion)\n                        },\n                        _ => unreachable!(),\n                    };\n\n                    diag.span_suggestion(\n                        sugg_span,\n                        \"remove the invocation before committing it to a version control system\",\n                        suggestion,\n                        applicability,\n                    );\n                },\n            );\n        }\n    }\n\n    fn check_crate_post(&mut self, _: &LateContext<'_>) {\n        self.checked_dbg_call_site = FxHashSet::default();\n    }\n}\n\nfn is_coroutine_desugar(expr: &Expr<'_>) -> bool {\n    matches!(\n        expr.kind,\n        ExprKind::Closure(Closure {\n            kind: ClosureKind::Coroutine(CoroutineKind::Desugared(..)) | ClosureKind::CoroutineClosure(..),\n            ..\n        })\n    )\n}\n\nfn is_async_move_desugar<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    if let ExprKind::Block(block, _) = expr.kind\n        && let [\n            Stmt {\n                kind:\n                    StmtKind::Let(LetStmt {\n                        source: LocalSource::AsyncFn,\n                        ..\n                    }),\n                ..\n            },\n        ] = block.stmts\n    {\n        return block.expr;\n    }\n\n    None\n}\n\nfn first_dbg_macro_in_expansion(cx: &LateContext<'_>, span: Span) -> Option<MacroCall> {\n    macro_backtrace(span).find(|mc| cx.tcx.is_diagnostic_item(sym::dbg_macro, mc.def_id))\n}\n\n/// Extracts all value expressions from the `match`-tree generated by `dbg!`.\n///\n/// E.g. from\n/// ```rust, ignore\n/// match 1 {\n///     tmp_1 => match 2 {\n///         tmp_2 => {\n///             /* printing */\n///             (tmp_1, tmp_2)\n///         }\n///     }\n/// }\n/// ```\n/// this extracts `1` and `2`.\nfn collect_vals<'hir>(first: &'hir Expr<'hir>, mut arms: &'hir [Arm<'hir>]) -> Vec<&'hir Expr<'hir>> {\n    let mut vals = vec![first];\n    loop {\n        let [arm] = arms else {\n            unreachable!(\"dbg! macro expansion only has single-arm matches\")\n        };\n\n        match is_async_move_desugar(arm.body)\n            .unwrap_or(arm.body)\n            .peel_drop_temps()\n            .kind\n        {\n            ExprKind::Block(..) => return vals,\n            ExprKind::Match(val, a, _) => {\n                vals.push(val);\n                arms = a;\n            },\n            _ => unreachable!(\"dbg! macro expansion only results in block or match expressions\"),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/declared_lints.rs",
    "content": "// This file was generated by `cargo dev update_lints`.\n// Use that command to update this file and do not edit by hand.\n// Manual edits will be overwritten.\n\npub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[\n    crate::absolute_paths::ABSOLUTE_PATHS_INFO,\n    crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO,\n    crate::approx_const::APPROX_CONSTANT_INFO,\n    crate::arbitrary_source_item_ordering::ARBITRARY_SOURCE_ITEM_ORDERING_INFO,\n    crate::arc_with_non_send_sync::ARC_WITH_NON_SEND_SYNC_INFO,\n    crate::as_conversions::AS_CONVERSIONS_INFO,\n    crate::asm_syntax::INLINE_ASM_X86_ATT_SYNTAX_INFO,\n    crate::asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX_INFO,\n    crate::assertions_on_constants::ASSERTIONS_ON_CONSTANTS_INFO,\n    crate::assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES_INFO,\n    crate::assigning_clones::ASSIGNING_CLONES_INFO,\n    crate::async_yields_async::ASYNC_YIELDS_ASYNC_INFO,\n    crate::attrs::ALLOW_ATTRIBUTES_INFO,\n    crate::attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON_INFO,\n    crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO,\n    crate::attrs::DEPRECATED_CFG_ATTR_INFO,\n    crate::attrs::DEPRECATED_CLIPPY_CFG_ATTR_INFO,\n    crate::attrs::DEPRECATED_SEMVER_INFO,\n    crate::attrs::DUPLICATED_ATTRIBUTES_INFO,\n    crate::attrs::IGNORE_WITHOUT_REASON_INFO,\n    crate::attrs::INLINE_ALWAYS_INFO,\n    crate::attrs::MIXED_ATTRIBUTES_STYLE_INFO,\n    crate::attrs::NON_MINIMAL_CFG_INFO,\n    crate::attrs::REPR_PACKED_WITHOUT_ABI_INFO,\n    crate::attrs::SHOULD_PANIC_WITHOUT_EXPECT_INFO,\n    crate::attrs::UNNECESSARY_CLIPPY_CFG_INFO,\n    crate::attrs::USELESS_ATTRIBUTE_INFO,\n    crate::await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE_INFO,\n    crate::await_holding_invalid::AWAIT_HOLDING_LOCK_INFO,\n    crate::await_holding_invalid::AWAIT_HOLDING_REFCELL_REF_INFO,\n    crate::blocks_in_conditions::BLOCKS_IN_CONDITIONS_INFO,\n    crate::bool_assert_comparison::BOOL_ASSERT_COMPARISON_INFO,\n    crate::bool_comparison::BOOL_COMPARISON_INFO,\n    crate::bool_to_int_with_if::BOOL_TO_INT_WITH_IF_INFO,\n    crate::booleans::NONMINIMAL_BOOL_INFO,\n    crate::booleans::OVERLY_COMPLEX_BOOL_EXPR_INFO,\n    crate::borrow_deref_ref::BORROW_DEREF_REF_INFO,\n    crate::box_default::BOX_DEFAULT_INFO,\n    crate::byte_char_slices::BYTE_CHAR_SLICES_INFO,\n    crate::cargo::CARGO_COMMON_METADATA_INFO,\n    crate::cargo::LINT_GROUPS_PRIORITY_INFO,\n    crate::cargo::MULTIPLE_CRATE_VERSIONS_INFO,\n    crate::cargo::NEGATIVE_FEATURE_NAMES_INFO,\n    crate::cargo::REDUNDANT_FEATURE_NAMES_INFO,\n    crate::cargo::WILDCARD_DEPENDENCIES_INFO,\n    crate::casts::AS_POINTER_UNDERSCORE_INFO,\n    crate::casts::AS_PTR_CAST_MUT_INFO,\n    crate::casts::AS_UNDERSCORE_INFO,\n    crate::casts::BORROW_AS_PTR_INFO,\n    crate::casts::CAST_ABS_TO_UNSIGNED_INFO,\n    crate::casts::CAST_ENUM_CONSTRUCTOR_INFO,\n    crate::casts::CAST_ENUM_TRUNCATION_INFO,\n    crate::casts::CAST_LOSSLESS_INFO,\n    crate::casts::CAST_NAN_TO_INT_INFO,\n    crate::casts::CAST_POSSIBLE_TRUNCATION_INFO,\n    crate::casts::CAST_POSSIBLE_WRAP_INFO,\n    crate::casts::CAST_PRECISION_LOSS_INFO,\n    crate::casts::CAST_PTR_ALIGNMENT_INFO,\n    crate::casts::CAST_SIGN_LOSS_INFO,\n    crate::casts::CAST_SLICE_DIFFERENT_SIZES_INFO,\n    crate::casts::CAST_SLICE_FROM_RAW_PARTS_INFO,\n    crate::casts::CHAR_LIT_AS_U8_INFO,\n    crate::casts::CONFUSING_METHOD_TO_NUMERIC_CAST_INFO,\n    crate::casts::FN_TO_NUMERIC_CAST_INFO,\n    crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO,\n    crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,\n    crate::casts::MANUAL_DANGLING_PTR_INFO,\n    crate::casts::NEEDLESS_TYPE_CAST_INFO,\n    crate::casts::PTR_AS_PTR_INFO,\n    crate::casts::PTR_CAST_CONSTNESS_INFO,\n    crate::casts::REF_AS_PTR_INFO,\n    crate::casts::UNNECESSARY_CAST_INFO,\n    crate::casts::ZERO_PTR_INFO,\n    crate::cfg_not_test::CFG_NOT_TEST_INFO,\n    crate::checked_conversions::CHECKED_CONVERSIONS_INFO,\n    crate::cloned_ref_to_slice_refs::CLONED_REF_TO_SLICE_REFS_INFO,\n    crate::coerce_container_to_any::COERCE_CONTAINER_TO_ANY_INFO,\n    crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,\n    crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO,\n    crate::collapsible_if::COLLAPSIBLE_IF_INFO,\n    crate::collection_is_never_read::COLLECTION_IS_NEVER_READ_INFO,\n    crate::comparison_chain::COMPARISON_CHAIN_INFO,\n    crate::copy_iterator::COPY_ITERATOR_INFO,\n    crate::crate_in_macro_def::CRATE_IN_MACRO_DEF_INFO,\n    crate::create_dir::CREATE_DIR_INFO,\n    crate::dbg_macro::DBG_MACRO_INFO,\n    crate::default::DEFAULT_TRAIT_ACCESS_INFO,\n    crate::default::FIELD_REASSIGN_WITH_DEFAULT_INFO,\n    crate::default_constructed_unit_structs::DEFAULT_CONSTRUCTED_UNIT_STRUCTS_INFO,\n    crate::default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY_INFO,\n    crate::default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK_INFO,\n    crate::default_union_representation::DEFAULT_UNION_REPRESENTATION_INFO,\n    crate::dereference::EXPLICIT_AUTO_DEREF_INFO,\n    crate::dereference::EXPLICIT_DEREF_METHODS_INFO,\n    crate::dereference::NEEDLESS_BORROW_INFO,\n    crate::dereference::REF_BINDING_TO_REFERENCE_INFO,\n    crate::derivable_impls::DERIVABLE_IMPLS_INFO,\n    crate::derive::DERIVE_ORD_XOR_PARTIAL_ORD_INFO,\n    crate::derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ_INFO,\n    crate::derive::DERIVED_HASH_WITH_MANUAL_EQ_INFO,\n    crate::derive::EXPL_IMPL_CLONE_ON_COPY_INFO,\n    crate::derive::UNSAFE_DERIVE_DESERIALIZE_INFO,\n    crate::disallowed_fields::DISALLOWED_FIELDS_INFO,\n    crate::disallowed_macros::DISALLOWED_MACROS_INFO,\n    crate::disallowed_methods::DISALLOWED_METHODS_INFO,\n    crate::disallowed_names::DISALLOWED_NAMES_INFO,\n    crate::disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS_INFO,\n    crate::disallowed_types::DISALLOWED_TYPES_INFO,\n    crate::doc::DOC_BROKEN_LINK_INFO,\n    crate::doc::DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS_INFO,\n    crate::doc::DOC_INCLUDE_WITHOUT_CFG_INFO,\n    crate::doc::DOC_LAZY_CONTINUATION_INFO,\n    crate::doc::DOC_LINK_CODE_INFO,\n    crate::doc::DOC_LINK_WITH_QUOTES_INFO,\n    crate::doc::DOC_MARKDOWN_INFO,\n    crate::doc::DOC_NESTED_REFDEFS_INFO,\n    crate::doc::DOC_OVERINDENTED_LIST_ITEMS_INFO,\n    crate::doc::DOC_PARAGRAPHS_MISSING_PUNCTUATION_INFO,\n    crate::doc::DOC_SUSPICIOUS_FOOTNOTES_INFO,\n    crate::doc::EMPTY_DOCS_INFO,\n    crate::doc::MISSING_ERRORS_DOC_INFO,\n    crate::doc::MISSING_PANICS_DOC_INFO,\n    crate::doc::MISSING_SAFETY_DOC_INFO,\n    crate::doc::NEEDLESS_DOCTEST_MAIN_INFO,\n    crate::doc::SUSPICIOUS_DOC_COMMENTS_INFO,\n    crate::doc::TEST_ATTR_IN_DOCTEST_INFO,\n    crate::doc::TOO_LONG_FIRST_DOC_PARAGRAPH_INFO,\n    crate::doc::UNNECESSARY_SAFETY_DOC_INFO,\n    crate::double_parens::DOUBLE_PARENS_INFO,\n    crate::drop_forget_ref::DROP_NON_DROP_INFO,\n    crate::drop_forget_ref::FORGET_NON_DROP_INFO,\n    crate::drop_forget_ref::MEM_FORGET_INFO,\n    crate::duplicate_mod::DUPLICATE_MOD_INFO,\n    crate::duration_suboptimal_units::DURATION_SUBOPTIMAL_UNITS_INFO,\n    crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO,\n    crate::empty_drop::EMPTY_DROP_INFO,\n    crate::empty_enums::EMPTY_ENUMS_INFO,\n    crate::empty_line_after::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,\n    crate::empty_line_after::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,\n    crate::empty_with_brackets::EMPTY_ENUM_VARIANTS_WITH_BRACKETS_INFO,\n    crate::empty_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO,\n    crate::endian_bytes::BIG_ENDIAN_BYTES_INFO,\n    crate::endian_bytes::HOST_ENDIAN_BYTES_INFO,\n    crate::endian_bytes::LITTLE_ENDIAN_BYTES_INFO,\n    crate::entry::MAP_ENTRY_INFO,\n    crate::enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT_INFO,\n    crate::equatable_if_let::EQUATABLE_IF_LET_INFO,\n    crate::error_impl_error::ERROR_IMPL_ERROR_INFO,\n    crate::escape::BOXED_LOCAL_INFO,\n    crate::eta_reduction::REDUNDANT_CLOSURE_INFO,\n    crate::eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS_INFO,\n    crate::excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS_INFO,\n    crate::excessive_bools::STRUCT_EXCESSIVE_BOOLS_INFO,\n    crate::excessive_nesting::EXCESSIVE_NESTING_INFO,\n    crate::exhaustive_items::EXHAUSTIVE_ENUMS_INFO,\n    crate::exhaustive_items::EXHAUSTIVE_STRUCTS_INFO,\n    crate::exit::EXIT_INFO,\n    crate::explicit_write::EXPLICIT_WRITE_INFO,\n    crate::extra_unused_type_parameters::EXTRA_UNUSED_TYPE_PARAMETERS_INFO,\n    crate::fallible_impl_from::FALLIBLE_IMPL_FROM_INFO,\n    crate::field_scoped_visibility_modifiers::FIELD_SCOPED_VISIBILITY_MODIFIERS_INFO,\n    crate::float_literal::EXCESSIVE_PRECISION_INFO,\n    crate::float_literal::LOSSY_FLOAT_LITERAL_INFO,\n    crate::floating_point_arithmetic::IMPRECISE_FLOPS_INFO,\n    crate::floating_point_arithmetic::SUBOPTIMAL_FLOPS_INFO,\n    crate::format::USELESS_FORMAT_INFO,\n    crate::format_args::FORMAT_IN_FORMAT_ARGS_INFO,\n    crate::format_args::POINTER_FORMAT_INFO,\n    crate::format_args::TO_STRING_IN_FORMAT_ARGS_INFO,\n    crate::format_args::UNINLINED_FORMAT_ARGS_INFO,\n    crate::format_args::UNNECESSARY_DEBUG_FORMATTING_INFO,\n    crate::format_args::UNNECESSARY_TRAILING_COMMA_INFO,\n    crate::format_args::UNUSED_FORMAT_SPECS_INFO,\n    crate::format_impl::PRINT_IN_FORMAT_IMPL_INFO,\n    crate::format_impl::RECURSIVE_FORMAT_IMPL_INFO,\n    crate::format_push_string::FORMAT_PUSH_STRING_INFO,\n    crate::formatting::POSSIBLE_MISSING_COMMA_INFO,\n    crate::formatting::POSSIBLE_MISSING_ELSE_INFO,\n    crate::formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING_INFO,\n    crate::formatting::SUSPICIOUS_ELSE_FORMATTING_INFO,\n    crate::formatting::SUSPICIOUS_UNARY_OP_FORMATTING_INFO,\n    crate::four_forward_slashes::FOUR_FORWARD_SLASHES_INFO,\n    crate::from_over_into::FROM_OVER_INTO_INFO,\n    crate::from_raw_with_void_ptr::FROM_RAW_WITH_VOID_PTR_INFO,\n    crate::from_str_radix_10::FROM_STR_RADIX_10_INFO,\n    crate::functions::DOUBLE_MUST_USE_INFO,\n    crate::functions::DUPLICATE_UNDERSCORE_ARGUMENT_INFO,\n    crate::functions::IMPL_TRAIT_IN_PARAMS_INFO,\n    crate::functions::MISNAMED_GETTERS_INFO,\n    crate::functions::MUST_USE_CANDIDATE_INFO,\n    crate::functions::MUST_USE_UNIT_INFO,\n    crate::functions::NOT_UNSAFE_PTR_ARG_DEREF_INFO,\n    crate::functions::REF_OPTION_INFO,\n    crate::functions::RENAMED_FUNCTION_PARAMS_INFO,\n    crate::functions::RESULT_LARGE_ERR_INFO,\n    crate::functions::RESULT_UNIT_ERR_INFO,\n    crate::functions::TOO_MANY_ARGUMENTS_INFO,\n    crate::functions::TOO_MANY_LINES_INFO,\n    crate::future_not_send::FUTURE_NOT_SEND_INFO,\n    crate::if_let_mutex::IF_LET_MUTEX_INFO,\n    crate::if_not_else::IF_NOT_ELSE_INFO,\n    crate::if_then_some_else_none::IF_THEN_SOME_ELSE_NONE_INFO,\n    crate::ifs::BRANCHES_SHARING_CODE_INFO,\n    crate::ifs::IF_SAME_THEN_ELSE_INFO,\n    crate::ifs::IFS_SAME_COND_INFO,\n    crate::ifs::SAME_FUNCTIONS_IN_IF_CONDITION_INFO,\n    crate::ignored_unit_patterns::IGNORED_UNIT_PATTERNS_INFO,\n    crate::impl_hash_with_borrow_str_and_bytes::IMPL_HASH_BORROW_WITH_STR_AND_BYTES_INFO,\n    crate::implicit_hasher::IMPLICIT_HASHER_INFO,\n    crate::implicit_return::IMPLICIT_RETURN_INFO,\n    crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,\n    crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,\n    crate::implicit_saturating_sub::INVERTED_SATURATING_SUB_INFO,\n    crate::implied_bounds_in_impls::IMPLIED_BOUNDS_IN_IMPLS_INFO,\n    crate::incompatible_msrv::INCOMPATIBLE_MSRV_INFO,\n    crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,\n    crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,\n    crate::indexing_slicing::INDEXING_SLICING_INFO,\n    crate::indexing_slicing::OUT_OF_BOUNDS_INDEXING_INFO,\n    crate::ineffective_open_options::INEFFECTIVE_OPEN_OPTIONS_INFO,\n    crate::infallible_try_from::INFALLIBLE_TRY_FROM_INFO,\n    crate::infinite_iter::INFINITE_ITER_INFO,\n    crate::infinite_iter::MAYBE_INFINITE_ITER_INFO,\n    crate::inherent_impl::MULTIPLE_INHERENT_IMPL_INFO,\n    crate::inherent_to_string::INHERENT_TO_STRING_INFO,\n    crate::inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY_INFO,\n    crate::init_numbered_fields::INIT_NUMBERED_FIELDS_INFO,\n    crate::inline_fn_without_body::INLINE_FN_WITHOUT_BODY_INFO,\n    crate::int_plus_one::INT_PLUS_ONE_INFO,\n    crate::item_name_repetitions::ENUM_VARIANT_NAMES_INFO,\n    crate::item_name_repetitions::MODULE_INCEPTION_INFO,\n    crate::item_name_repetitions::MODULE_NAME_REPETITIONS_INFO,\n    crate::item_name_repetitions::STRUCT_FIELD_NAMES_INFO,\n    crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO,\n    crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO,\n    crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO,\n    crate::iter_over_hash_type::ITER_OVER_HASH_TYPE_INFO,\n    crate::iter_without_into_iter::INTO_ITER_WITHOUT_ITER_INFO,\n    crate::iter_without_into_iter::ITER_WITHOUT_INTO_ITER_INFO,\n    crate::large_const_arrays::LARGE_CONST_ARRAYS_INFO,\n    crate::large_enum_variant::LARGE_ENUM_VARIANT_INFO,\n    crate::large_futures::LARGE_FUTURES_INFO,\n    crate::large_include_file::LARGE_INCLUDE_FILE_INFO,\n    crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO,\n    crate::large_stack_frames::LARGE_STACK_FRAMES_INFO,\n    crate::legacy_numeric_constants::LEGACY_NUMERIC_CONSTANTS_INFO,\n    crate::len_without_is_empty::LEN_WITHOUT_IS_EMPTY_INFO,\n    crate::len_zero::COMPARISON_TO_EMPTY_INFO,\n    crate::len_zero::LEN_ZERO_INFO,\n    crate::let_if_seq::USELESS_LET_IF_SEQ_INFO,\n    crate::let_underscore::LET_UNDERSCORE_FUTURE_INFO,\n    crate::let_underscore::LET_UNDERSCORE_LOCK_INFO,\n    crate::let_underscore::LET_UNDERSCORE_MUST_USE_INFO,\n    crate::let_underscore::LET_UNDERSCORE_UNTYPED_INFO,\n    crate::let_with_type_underscore::LET_WITH_TYPE_UNDERSCORE_INFO,\n    crate::lifetimes::ELIDABLE_LIFETIME_NAMES_INFO,\n    crate::lifetimes::EXTRA_UNUSED_LIFETIMES_INFO,\n    crate::lifetimes::NEEDLESS_LIFETIMES_INFO,\n    crate::literal_representation::DECIMAL_LITERAL_REPRESENTATION_INFO,\n    crate::literal_representation::INCONSISTENT_DIGIT_GROUPING_INFO,\n    crate::literal_representation::LARGE_DIGIT_GROUPS_INFO,\n    crate::literal_representation::MISTYPED_LITERAL_SUFFIXES_INFO,\n    crate::literal_representation::UNREADABLE_LITERAL_INFO,\n    crate::literal_representation::UNUSUAL_BYTE_GROUPINGS_INFO,\n    crate::literal_string_with_formatting_args::LITERAL_STRING_WITH_FORMATTING_ARGS_INFO,\n    crate::loops::CHAR_INDICES_AS_BYTE_INDICES_INFO,\n    crate::loops::EMPTY_LOOP_INFO,\n    crate::loops::EXPLICIT_COUNTER_LOOP_INFO,\n    crate::loops::EXPLICIT_INTO_ITER_LOOP_INFO,\n    crate::loops::EXPLICIT_ITER_LOOP_INFO,\n    crate::loops::FOR_KV_MAP_INFO,\n    crate::loops::INFINITE_LOOP_INFO,\n    crate::loops::ITER_NEXT_LOOP_INFO,\n    crate::loops::MANUAL_FIND_INFO,\n    crate::loops::MANUAL_FLATTEN_INFO,\n    crate::loops::MANUAL_MEMCPY_INFO,\n    crate::loops::MANUAL_SLICE_FILL_INFO,\n    crate::loops::MANUAL_WHILE_LET_SOME_INFO,\n    crate::loops::MISSING_SPIN_LOOP_INFO,\n    crate::loops::MUT_RANGE_BOUND_INFO,\n    crate::loops::NEEDLESS_RANGE_LOOP_INFO,\n    crate::loops::NEVER_LOOP_INFO,\n    crate::loops::SAME_ITEM_PUSH_INFO,\n    crate::loops::SINGLE_ELEMENT_LOOP_INFO,\n    crate::loops::UNUSED_ENUMERATE_INDEX_INFO,\n    crate::loops::WHILE_FLOAT_INFO,\n    crate::loops::WHILE_IMMUTABLE_CONDITION_INFO,\n    crate::loops::WHILE_LET_LOOP_INFO,\n    crate::loops::WHILE_LET_ON_ITERATOR_INFO,\n    crate::macro_metavars_in_unsafe::MACRO_METAVARS_IN_UNSAFE_INFO,\n    crate::macro_use::MACRO_USE_IMPORTS_INFO,\n    crate::main_recursion::MAIN_RECURSION_INFO,\n    crate::manual_abs_diff::MANUAL_ABS_DIFF_INFO,\n    crate::manual_assert::MANUAL_ASSERT_INFO,\n    crate::manual_async_fn::MANUAL_ASYNC_FN_INFO,\n    crate::manual_bits::MANUAL_BITS_INFO,\n    crate::manual_checked_ops::MANUAL_CHECKED_OPS_INFO,\n    crate::manual_clamp::MANUAL_CLAMP_INFO,\n    crate::manual_float_methods::MANUAL_IS_FINITE_INFO,\n    crate::manual_float_methods::MANUAL_IS_INFINITE_INFO,\n    crate::manual_hash_one::MANUAL_HASH_ONE_INFO,\n    crate::manual_ignore_case_cmp::MANUAL_IGNORE_CASE_CMP_INFO,\n    crate::manual_ilog2::MANUAL_ILOG2_INFO,\n    crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO,\n    crate::manual_is_power_of_two::MANUAL_IS_POWER_OF_TWO_INFO,\n    crate::manual_let_else::MANUAL_LET_ELSE_INFO,\n    crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO,\n    crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO,\n    crate::manual_option_as_slice::MANUAL_OPTION_AS_SLICE_INFO,\n    crate::manual_pop_if::MANUAL_POP_IF_INFO,\n    crate::manual_range_patterns::MANUAL_RANGE_PATTERNS_INFO,\n    crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO,\n    crate::manual_retain::MANUAL_RETAIN_INFO,\n    crate::manual_rotate::MANUAL_ROTATE_INFO,\n    crate::manual_slice_size_calculation::MANUAL_SLICE_SIZE_CALCULATION_INFO,\n    crate::manual_string_new::MANUAL_STRING_NEW_INFO,\n    crate::manual_strip::MANUAL_STRIP_INFO,\n    crate::manual_take::MANUAL_TAKE_INFO,\n    crate::map_unit_fn::OPTION_MAP_UNIT_FN_INFO,\n    crate::map_unit_fn::RESULT_MAP_UNIT_FN_INFO,\n    crate::match_result_ok::MATCH_RESULT_OK_INFO,\n    crate::matches::COLLAPSIBLE_MATCH_INFO,\n    crate::matches::INFALLIBLE_DESTRUCTURING_MATCH_INFO,\n    crate::matches::MANUAL_FILTER_INFO,\n    crate::matches::MANUAL_MAP_INFO,\n    crate::matches::MANUAL_OK_ERR_INFO,\n    crate::matches::MANUAL_UNWRAP_OR_INFO,\n    crate::matches::MANUAL_UNWRAP_OR_DEFAULT_INFO,\n    crate::matches::MATCH_AS_REF_INFO,\n    crate::matches::MATCH_BOOL_INFO,\n    crate::matches::MATCH_LIKE_MATCHES_MACRO_INFO,\n    crate::matches::MATCH_OVERLAPPING_ARM_INFO,\n    crate::matches::MATCH_REF_PATS_INFO,\n    crate::matches::MATCH_SAME_ARMS_INFO,\n    crate::matches::MATCH_SINGLE_BINDING_INFO,\n    crate::matches::MATCH_STR_CASE_MISMATCH_INFO,\n    crate::matches::MATCH_WILD_ERR_ARM_INFO,\n    crate::matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS_INFO,\n    crate::matches::NEEDLESS_MATCH_INFO,\n    crate::matches::REDUNDANT_GUARDS_INFO,\n    crate::matches::REDUNDANT_PATTERN_MATCHING_INFO,\n    crate::matches::REST_PAT_IN_FULLY_BOUND_STRUCTS_INFO,\n    crate::matches::SIGNIFICANT_DROP_IN_SCRUTINEE_INFO,\n    crate::matches::SINGLE_MATCH_INFO,\n    crate::matches::SINGLE_MATCH_ELSE_INFO,\n    crate::matches::TRY_ERR_INFO,\n    crate::matches::WILDCARD_ENUM_MATCH_ARM_INFO,\n    crate::matches::WILDCARD_IN_OR_PATTERNS_INFO,\n    crate::mem_replace::MEM_REPLACE_OPTION_WITH_NONE_INFO,\n    crate::mem_replace::MEM_REPLACE_OPTION_WITH_SOME_INFO,\n    crate::mem_replace::MEM_REPLACE_WITH_DEFAULT_INFO,\n    crate::mem_replace::MEM_REPLACE_WITH_UNINIT_INFO,\n    crate::methods::BIND_INSTEAD_OF_MAP_INFO,\n    crate::methods::BYTES_COUNT_TO_LEN_INFO,\n    crate::methods::BYTES_NTH_INFO,\n    crate::methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS_INFO,\n    crate::methods::CHARS_LAST_CMP_INFO,\n    crate::methods::CHARS_NEXT_CMP_INFO,\n    crate::methods::CLEAR_WITH_DRAIN_INFO,\n    crate::methods::CLONE_ON_COPY_INFO,\n    crate::methods::CLONE_ON_REF_PTR_INFO,\n    crate::methods::CLONED_INSTEAD_OF_COPIED_INFO,\n    crate::methods::COLLAPSIBLE_STR_REPLACE_INFO,\n    crate::methods::CONST_IS_EMPTY_INFO,\n    crate::methods::DOUBLE_ENDED_ITERATOR_LAST_INFO,\n    crate::methods::DRAIN_COLLECT_INFO,\n    crate::methods::ERR_EXPECT_INFO,\n    crate::methods::EXPECT_FUN_CALL_INFO,\n    crate::methods::EXPECT_USED_INFO,\n    crate::methods::EXTEND_WITH_DRAIN_INFO,\n    crate::methods::FILETYPE_IS_FILE_INFO,\n    crate::methods::FILTER_MAP_BOOL_THEN_INFO,\n    crate::methods::FILTER_MAP_IDENTITY_INFO,\n    crate::methods::FILTER_MAP_NEXT_INFO,\n    crate::methods::FILTER_NEXT_INFO,\n    crate::methods::FLAT_MAP_IDENTITY_INFO,\n    crate::methods::FLAT_MAP_OPTION_INFO,\n    crate::methods::FORMAT_COLLECT_INFO,\n    crate::methods::FROM_ITER_INSTEAD_OF_COLLECT_INFO,\n    crate::methods::GET_FIRST_INFO,\n    crate::methods::GET_LAST_WITH_LEN_INFO,\n    crate::methods::GET_UNWRAP_INFO,\n    crate::methods::IMPLICIT_CLONE_INFO,\n    crate::methods::INEFFICIENT_TO_STRING_INFO,\n    crate::methods::INSPECT_FOR_EACH_INFO,\n    crate::methods::INTO_ITER_ON_REF_INFO,\n    crate::methods::IO_OTHER_ERROR_INFO,\n    crate::methods::IP_CONSTANT_INFO,\n    crate::methods::IS_DIGIT_ASCII_RADIX_INFO,\n    crate::methods::ITER_CLONED_COLLECT_INFO,\n    crate::methods::ITER_COUNT_INFO,\n    crate::methods::ITER_FILTER_IS_OK_INFO,\n    crate::methods::ITER_FILTER_IS_SOME_INFO,\n    crate::methods::ITER_KV_MAP_INFO,\n    crate::methods::ITER_NEXT_SLICE_INFO,\n    crate::methods::ITER_NTH_INFO,\n    crate::methods::ITER_NTH_ZERO_INFO,\n    crate::methods::ITER_ON_EMPTY_COLLECTIONS_INFO,\n    crate::methods::ITER_ON_SINGLE_ITEMS_INFO,\n    crate::methods::ITER_OUT_OF_BOUNDS_INFO,\n    crate::methods::ITER_OVEREAGER_CLONED_INFO,\n    crate::methods::ITER_SKIP_NEXT_INFO,\n    crate::methods::ITER_SKIP_ZERO_INFO,\n    crate::methods::ITER_WITH_DRAIN_INFO,\n    crate::methods::ITERATOR_STEP_BY_ZERO_INFO,\n    crate::methods::JOIN_ABSOLUTE_PATHS_INFO,\n    crate::methods::LINES_FILTER_MAP_OK_INFO,\n    crate::methods::MANUAL_C_STR_LITERALS_INFO,\n    crate::methods::MANUAL_CONTAINS_INFO,\n    crate::methods::MANUAL_FILTER_MAP_INFO,\n    crate::methods::MANUAL_FIND_MAP_INFO,\n    crate::methods::MANUAL_INSPECT_INFO,\n    crate::methods::MANUAL_IS_VARIANT_AND_INFO,\n    crate::methods::MANUAL_NEXT_BACK_INFO,\n    crate::methods::MANUAL_OK_OR_INFO,\n    crate::methods::MANUAL_REPEAT_N_INFO,\n    crate::methods::MANUAL_SATURATING_ARITHMETIC_INFO,\n    crate::methods::MANUAL_SPLIT_ONCE_INFO,\n    crate::methods::MANUAL_STR_REPEAT_INFO,\n    crate::methods::MANUAL_TRY_FOLD_INFO,\n    crate::methods::MAP_ALL_ANY_IDENTITY_INFO,\n    crate::methods::MAP_CLONE_INFO,\n    crate::methods::MAP_COLLECT_RESULT_UNIT_INFO,\n    crate::methods::MAP_ERR_IGNORE_INFO,\n    crate::methods::MAP_FLATTEN_INFO,\n    crate::methods::MAP_IDENTITY_INFO,\n    crate::methods::MAP_UNWRAP_OR_INFO,\n    crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES_INFO,\n    crate::methods::MUT_MUTEX_LOCK_INFO,\n    crate::methods::NAIVE_BYTECOUNT_INFO,\n    crate::methods::NEEDLESS_AS_BYTES_INFO,\n    crate::methods::NEEDLESS_CHARACTER_ITERATION_INFO,\n    crate::methods::NEEDLESS_COLLECT_INFO,\n    crate::methods::NEEDLESS_OPTION_AS_DEREF_INFO,\n    crate::methods::NEEDLESS_OPTION_TAKE_INFO,\n    crate::methods::NEEDLESS_SPLITN_INFO,\n    crate::methods::NEW_RET_NO_SELF_INFO,\n    crate::methods::NO_EFFECT_REPLACE_INFO,\n    crate::methods::NONSENSICAL_OPEN_OPTIONS_INFO,\n    crate::methods::OBFUSCATED_IF_ELSE_INFO,\n    crate::methods::OK_EXPECT_INFO,\n    crate::methods::OPTION_AS_REF_CLONED_INFO,\n    crate::methods::OPTION_AS_REF_DEREF_INFO,\n    crate::methods::OPTION_FILTER_MAP_INFO,\n    crate::methods::OPTION_MAP_OR_NONE_INFO,\n    crate::methods::OR_FUN_CALL_INFO,\n    crate::methods::OR_THEN_UNWRAP_INFO,\n    crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO,\n    crate::methods::PATH_ENDS_WITH_EXT_INFO,\n    crate::methods::PTR_OFFSET_BY_LITERAL_INFO,\n    crate::methods::PTR_OFFSET_WITH_CAST_INFO,\n    crate::methods::RANGE_ZIP_WITH_LEN_INFO,\n    crate::methods::READ_LINE_WITHOUT_TRIM_INFO,\n    crate::methods::READONLY_WRITE_LOCK_INFO,\n    crate::methods::REDUNDANT_AS_STR_INFO,\n    crate::methods::REDUNDANT_ITER_CLONED_INFO,\n    crate::methods::REPEAT_ONCE_INFO,\n    crate::methods::RESULT_FILTER_MAP_INFO,\n    crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,\n    crate::methods::RETURN_AND_THEN_INFO,\n    crate::methods::SEARCH_IS_SOME_INFO,\n    crate::methods::SEEK_FROM_CURRENT_INFO,\n    crate::methods::SEEK_TO_START_INSTEAD_OF_REWIND_INFO,\n    crate::methods::SHOULD_IMPLEMENT_TRAIT_INFO,\n    crate::methods::SINGLE_CHAR_ADD_STR_INFO,\n    crate::methods::SKIP_WHILE_NEXT_INFO,\n    crate::methods::SLICED_STRING_AS_BYTES_INFO,\n    crate::methods::STABLE_SORT_PRIMITIVE_INFO,\n    crate::methods::STR_SPLIT_AT_NEWLINE_INFO,\n    crate::methods::STRING_EXTEND_CHARS_INFO,\n    crate::methods::STRING_LIT_CHARS_ANY_INFO,\n    crate::methods::SUSPICIOUS_COMMAND_ARG_SPACE_INFO,\n    crate::methods::SUSPICIOUS_MAP_INFO,\n    crate::methods::SUSPICIOUS_OPEN_OPTIONS_INFO,\n    crate::methods::SUSPICIOUS_SPLITN_INFO,\n    crate::methods::SUSPICIOUS_TO_OWNED_INFO,\n    crate::methods::SWAP_WITH_TEMPORARY_INFO,\n    crate::methods::TYPE_ID_ON_BOX_INFO,\n    crate::methods::UNBUFFERED_BYTES_INFO,\n    crate::methods::UNINIT_ASSUMED_INIT_INFO,\n    crate::methods::UNIT_HASH_INFO,\n    crate::methods::UNNECESSARY_FALLIBLE_CONVERSIONS_INFO,\n    crate::methods::UNNECESSARY_FILTER_MAP_INFO,\n    crate::methods::UNNECESSARY_FIND_MAP_INFO,\n    crate::methods::UNNECESSARY_FIRST_THEN_CHECK_INFO,\n    crate::methods::UNNECESSARY_FOLD_INFO,\n    crate::methods::UNNECESSARY_GET_THEN_CHECK_INFO,\n    crate::methods::UNNECESSARY_JOIN_INFO,\n    crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO,\n    crate::methods::UNNECESSARY_LITERAL_UNWRAP_INFO,\n    crate::methods::UNNECESSARY_MAP_OR_INFO,\n    crate::methods::UNNECESSARY_MIN_OR_MAX_INFO,\n    crate::methods::UNNECESSARY_OPTION_MAP_OR_ELSE_INFO,\n    crate::methods::UNNECESSARY_RESULT_MAP_OR_ELSE_INFO,\n    crate::methods::UNNECESSARY_SORT_BY_INFO,\n    crate::methods::UNNECESSARY_TO_OWNED_INFO,\n    crate::methods::UNWRAP_OR_DEFAULT_INFO,\n    crate::methods::UNWRAP_USED_INFO,\n    crate::methods::USELESS_ASREF_INFO,\n    crate::methods::USELESS_NONZERO_NEW_UNCHECKED_INFO,\n    crate::methods::VEC_RESIZE_TO_ZERO_INFO,\n    crate::methods::VERBOSE_FILE_READS_INFO,\n    crate::methods::WAKER_CLONE_WAKE_INFO,\n    crate::methods::WRONG_SELF_CONVENTION_INFO,\n    crate::methods::ZST_OFFSET_INFO,\n    crate::min_ident_chars::MIN_IDENT_CHARS_INFO,\n    crate::minmax::MIN_MAX_INFO,\n    crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,\n    crate::misc::USED_UNDERSCORE_BINDING_INFO,\n    crate::misc::USED_UNDERSCORE_ITEMS_INFO,\n    crate::misc_early::BUILTIN_TYPE_SHADOW_INFO,\n    crate::misc_early::MIXED_CASE_HEX_LITERALS_INFO,\n    crate::misc_early::REDUNDANT_AT_REST_PATTERN_INFO,\n    crate::misc_early::REDUNDANT_PATTERN_INFO,\n    crate::misc_early::SEPARATED_LITERAL_SUFFIX_INFO,\n    crate::misc_early::UNNEEDED_FIELD_PATTERN_INFO,\n    crate::misc_early::UNNEEDED_WILDCARD_PATTERN_INFO,\n    crate::misc_early::UNSEPARATED_LITERAL_SUFFIX_INFO,\n    crate::misc_early::ZERO_PREFIXED_LITERAL_INFO,\n    crate::mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER_INFO,\n    crate::missing_assert_message::MISSING_ASSERT_MESSAGE_INFO,\n    crate::missing_asserts_for_indexing::MISSING_ASSERTS_FOR_INDEXING_INFO,\n    crate::missing_const_for_fn::MISSING_CONST_FOR_FN_INFO,\n    crate::missing_const_for_thread_local::MISSING_CONST_FOR_THREAD_LOCAL_INFO,\n    crate::missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS_INFO,\n    crate::missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES_INFO,\n    crate::missing_fields_in_debug::MISSING_FIELDS_IN_DEBUG_INFO,\n    crate::missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS_INFO,\n    crate::missing_trait_methods::MISSING_TRAIT_METHODS_INFO,\n    crate::mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION_INFO,\n    crate::mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION_INFO,\n    crate::module_style::MOD_MODULE_FILES_INFO,\n    crate::module_style::SELF_NAMED_MODULE_FILES_INFO,\n    crate::multi_assignments::MULTI_ASSIGNMENTS_INFO,\n    crate::multiple_bound_locations::MULTIPLE_BOUND_LOCATIONS_INFO,\n    crate::multiple_unsafe_ops_per_block::MULTIPLE_UNSAFE_OPS_PER_BLOCK_INFO,\n    crate::mut_key::MUTABLE_KEY_TYPE_INFO,\n    crate::mut_mut::MUT_MUT_INFO,\n    crate::mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL_INFO,\n    crate::mutex_atomic::MUTEX_ATOMIC_INFO,\n    crate::mutex_atomic::MUTEX_INTEGER_INFO,\n    crate::needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE_INFO,\n    crate::needless_bool::NEEDLESS_BOOL_INFO,\n    crate::needless_bool::NEEDLESS_BOOL_ASSIGN_INFO,\n    crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO,\n    crate::needless_borrows_for_generic_args::NEEDLESS_BORROWS_FOR_GENERIC_ARGS_INFO,\n    crate::needless_continue::NEEDLESS_CONTINUE_INFO,\n    crate::needless_else::NEEDLESS_ELSE_INFO,\n    crate::needless_for_each::NEEDLESS_FOR_EACH_INFO,\n    crate::needless_ifs::NEEDLESS_IFS_INFO,\n    crate::needless_late_init::NEEDLESS_LATE_INIT_INFO,\n    crate::needless_maybe_sized::NEEDLESS_MAYBE_SIZED_INFO,\n    crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO,\n    crate::needless_pass_by_ref_mut::NEEDLESS_PASS_BY_REF_MUT_INFO,\n    crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO,\n    crate::needless_question_mark::NEEDLESS_QUESTION_MARK_INFO,\n    crate::needless_update::NEEDLESS_UPDATE_INFO,\n    crate::neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD_INFO,\n    crate::neg_multiply::NEG_MULTIPLY_INFO,\n    crate::new_without_default::NEW_WITHOUT_DEFAULT_INFO,\n    crate::no_effect::NO_EFFECT_INFO,\n    crate::no_effect::NO_EFFECT_UNDERSCORE_BINDING_INFO,\n    crate::no_effect::UNNECESSARY_OPERATION_INFO,\n    crate::no_mangle_with_rust_abi::NO_MANGLE_WITH_RUST_ABI_INFO,\n    crate::non_canonical_impls::NON_CANONICAL_CLONE_IMPL_INFO,\n    crate::non_canonical_impls::NON_CANONICAL_PARTIAL_ORD_IMPL_INFO,\n    crate::non_copy_const::BORROW_INTERIOR_MUTABLE_CONST_INFO,\n    crate::non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST_INFO,\n    crate::non_expressive_names::JUST_UNDERSCORES_AND_DIGITS_INFO,\n    crate::non_expressive_names::MANY_SINGLE_CHAR_NAMES_INFO,\n    crate::non_expressive_names::SIMILAR_NAMES_INFO,\n    crate::non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS_INFO,\n    crate::non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY_INFO,\n    crate::non_std_lazy_statics::NON_STD_LAZY_STATICS_INFO,\n    crate::non_zero_suggestions::NON_ZERO_SUGGESTIONS_INFO,\n    crate::nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES_INFO,\n    crate::octal_escapes::OCTAL_ESCAPES_INFO,\n    crate::only_used_in_recursion::ONLY_USED_IN_RECURSION_INFO,\n    crate::only_used_in_recursion::SELF_ONLY_USED_IN_RECURSION_INFO,\n    crate::operators::ABSURD_EXTREME_COMPARISONS_INFO,\n    crate::operators::ARITHMETIC_SIDE_EFFECTS_INFO,\n    crate::operators::ASSIGN_OP_PATTERN_INFO,\n    crate::operators::BAD_BIT_MASK_INFO,\n    crate::operators::CMP_OWNED_INFO,\n    crate::operators::DECIMAL_BITWISE_OPERANDS_INFO,\n    crate::operators::DOUBLE_COMPARISONS_INFO,\n    crate::operators::DURATION_SUBSEC_INFO,\n    crate::operators::EQ_OP_INFO,\n    crate::operators::ERASING_OP_INFO,\n    crate::operators::FLOAT_ARITHMETIC_INFO,\n    crate::operators::FLOAT_CMP_INFO,\n    crate::operators::FLOAT_CMP_CONST_INFO,\n    crate::operators::FLOAT_EQUALITY_WITHOUT_ABS_INFO,\n    crate::operators::IDENTITY_OP_INFO,\n    crate::operators::IMPOSSIBLE_COMPARISONS_INFO,\n    crate::operators::INEFFECTIVE_BIT_MASK_INFO,\n    crate::operators::INTEGER_DIVISION_INFO,\n    crate::operators::INTEGER_DIVISION_REMAINDER_USED_INFO,\n    crate::operators::INVALID_UPCAST_COMPARISONS_INFO,\n    crate::operators::MANUAL_DIV_CEIL_INFO,\n    crate::operators::MANUAL_IS_MULTIPLE_OF_INFO,\n    crate::operators::MANUAL_MIDPOINT_INFO,\n    crate::operators::MISREFACTORED_ASSIGN_OP_INFO,\n    crate::operators::MODULO_ARITHMETIC_INFO,\n    crate::operators::MODULO_ONE_INFO,\n    crate::operators::NEEDLESS_BITWISE_BOOL_INFO,\n    crate::operators::OP_REF_INFO,\n    crate::operators::REDUNDANT_COMPARISONS_INFO,\n    crate::operators::SELF_ASSIGNMENT_INFO,\n    crate::operators::VERBOSE_BIT_MASK_INFO,\n    crate::option_env_unwrap::OPTION_ENV_UNWRAP_INFO,\n    crate::option_if_let_else::OPTION_IF_LET_ELSE_INFO,\n    crate::panic_in_result_fn::PANIC_IN_RESULT_FN_INFO,\n    crate::panic_unimplemented::PANIC_INFO,\n    crate::panic_unimplemented::TODO_INFO,\n    crate::panic_unimplemented::UNIMPLEMENTED_INFO,\n    crate::panic_unimplemented::UNREACHABLE_INFO,\n    crate::panicking_overflow_checks::PANICKING_OVERFLOW_CHECKS_INFO,\n    crate::partial_pub_fields::PARTIAL_PUB_FIELDS_INFO,\n    crate::partialeq_ne_impl::PARTIALEQ_NE_IMPL_INFO,\n    crate::partialeq_to_none::PARTIALEQ_TO_NONE_INFO,\n    crate::pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE_INFO,\n    crate::pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF_INFO,\n    crate::pathbuf_init_then_push::PATHBUF_INIT_THEN_PUSH_INFO,\n    crate::pattern_type_mismatch::PATTERN_TYPE_MISMATCH_INFO,\n    crate::permissions_set_readonly_false::PERMISSIONS_SET_READONLY_FALSE_INFO,\n    crate::pointers_in_nomem_asm_block::POINTERS_IN_NOMEM_ASM_BLOCK_INFO,\n    crate::precedence::PRECEDENCE_INFO,\n    crate::precedence::PRECEDENCE_BITS_INFO,\n    crate::ptr::CMP_NULL_INFO,\n    crate::ptr::MUT_FROM_REF_INFO,\n    crate::ptr::PTR_ARG_INFO,\n    crate::ptr::PTR_EQ_INFO,\n    crate::pub_underscore_fields::PUB_UNDERSCORE_FIELDS_INFO,\n    crate::pub_use::PUB_USE_INFO,\n    crate::question_mark::QUESTION_MARK_INFO,\n    crate::question_mark_used::QUESTION_MARK_USED_INFO,\n    crate::ranges::MANUAL_RANGE_CONTAINS_INFO,\n    crate::ranges::RANGE_MINUS_ONE_INFO,\n    crate::ranges::RANGE_PLUS_ONE_INFO,\n    crate::ranges::REVERSED_EMPTY_RANGES_INFO,\n    crate::raw_strings::NEEDLESS_RAW_STRING_HASHES_INFO,\n    crate::raw_strings::NEEDLESS_RAW_STRINGS_INFO,\n    crate::rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT_INFO,\n    crate::read_zero_byte_vec::READ_ZERO_BYTE_VEC_INFO,\n    crate::redundant_async_block::REDUNDANT_ASYNC_BLOCK_INFO,\n    crate::redundant_clone::REDUNDANT_CLONE_INFO,\n    crate::redundant_closure_call::REDUNDANT_CLOSURE_CALL_INFO,\n    crate::redundant_else::REDUNDANT_ELSE_INFO,\n    crate::redundant_field_names::REDUNDANT_FIELD_NAMES_INFO,\n    crate::redundant_locals::REDUNDANT_LOCALS_INFO,\n    crate::redundant_pub_crate::REDUNDANT_PUB_CRATE_INFO,\n    crate::redundant_slicing::DEREF_BY_SLICING_INFO,\n    crate::redundant_slicing::REDUNDANT_SLICING_INFO,\n    crate::redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES_INFO,\n    crate::redundant_test_prefix::REDUNDANT_TEST_PREFIX_INFO,\n    crate::redundant_type_annotations::REDUNDANT_TYPE_ANNOTATIONS_INFO,\n    crate::ref_option_ref::REF_OPTION_REF_INFO,\n    crate::ref_patterns::REF_PATTERNS_INFO,\n    crate::reference::DEREF_ADDROF_INFO,\n    crate::regex::INVALID_REGEX_INFO,\n    crate::regex::REGEX_CREATION_IN_LOOPS_INFO,\n    crate::regex::TRIVIAL_REGEX_INFO,\n    crate::repeat_vec_with_capacity::REPEAT_VEC_WITH_CAPACITY_INFO,\n    crate::replace_box::REPLACE_BOX_INFO,\n    crate::reserve_after_initialization::RESERVE_AFTER_INITIALIZATION_INFO,\n    crate::return_self_not_must_use::RETURN_SELF_NOT_MUST_USE_INFO,\n    crate::returns::LET_AND_RETURN_INFO,\n    crate::returns::NEEDLESS_RETURN_INFO,\n    crate::returns::NEEDLESS_RETURN_WITH_QUESTION_MARK_INFO,\n    crate::same_length_and_capacity::SAME_LENGTH_AND_CAPACITY_INFO,\n    crate::same_name_method::SAME_NAME_METHOD_INFO,\n    crate::self_named_constructors::SELF_NAMED_CONSTRUCTORS_INFO,\n    crate::semicolon_block::SEMICOLON_INSIDE_BLOCK_INFO,\n    crate::semicolon_block::SEMICOLON_OUTSIDE_BLOCK_INFO,\n    crate::semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED_INFO,\n    crate::serde_api::SERDE_API_MISUSE_INFO,\n    crate::set_contains_or_insert::SET_CONTAINS_OR_INSERT_INFO,\n    crate::shadow::SHADOW_REUSE_INFO,\n    crate::shadow::SHADOW_SAME_INFO,\n    crate::shadow::SHADOW_UNRELATED_INFO,\n    crate::significant_drop_tightening::SIGNIFICANT_DROP_TIGHTENING_INFO,\n    crate::single_call_fn::SINGLE_CALL_FN_INFO,\n    crate::single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES_INFO,\n    crate::single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS_INFO,\n    crate::single_option_map::SINGLE_OPTION_MAP_INFO,\n    crate::single_range_in_vec_init::SINGLE_RANGE_IN_VEC_INIT_INFO,\n    crate::size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT_INFO,\n    crate::size_of_ref::SIZE_OF_REF_INFO,\n    crate::slow_vector_initialization::SLOW_VECTOR_INITIALIZATION_INFO,\n    crate::std_instead_of_core::ALLOC_INSTEAD_OF_CORE_INFO,\n    crate::std_instead_of_core::STD_INSTEAD_OF_ALLOC_INFO,\n    crate::std_instead_of_core::STD_INSTEAD_OF_CORE_INFO,\n    crate::string_patterns::MANUAL_PATTERN_CHAR_COMPARISON_INFO,\n    crate::string_patterns::SINGLE_CHAR_PATTERN_INFO,\n    crate::strings::STR_TO_STRING_INFO,\n    crate::strings::STRING_ADD_INFO,\n    crate::strings::STRING_ADD_ASSIGN_INFO,\n    crate::strings::STRING_FROM_UTF8_AS_BYTES_INFO,\n    crate::strings::STRING_LIT_AS_BYTES_INFO,\n    crate::strings::STRING_SLICE_INFO,\n    crate::strings::TRIM_SPLIT_WHITESPACE_INFO,\n    crate::strlen_on_c_strings::STRLEN_ON_C_STRINGS_INFO,\n    crate::suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS_INFO,\n    crate::suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL_INFO,\n    crate::suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL_INFO,\n    crate::suspicious_xor_used_as_pow::SUSPICIOUS_XOR_USED_AS_POW_INFO,\n    crate::swap::ALMOST_SWAPPED_INFO,\n    crate::swap::MANUAL_SWAP_INFO,\n    crate::swap_ptr_to_ref::SWAP_PTR_TO_REF_INFO,\n    crate::tabs_in_doc_comments::TABS_IN_DOC_COMMENTS_INFO,\n    crate::temporary_assignment::TEMPORARY_ASSIGNMENT_INFO,\n    crate::tests_outside_test_module::TESTS_OUTSIDE_TEST_MODULE_INFO,\n    crate::time_subtraction::MANUAL_INSTANT_ELAPSED_INFO,\n    crate::time_subtraction::UNCHECKED_TIME_SUBTRACTION_INFO,\n    crate::to_digit_is_some::TO_DIGIT_IS_SOME_INFO,\n    crate::to_string_trait_impl::TO_STRING_TRAIT_IMPL_INFO,\n    crate::toplevel_ref_arg::TOPLEVEL_REF_ARG_INFO,\n    crate::trailing_empty_array::TRAILING_EMPTY_ARRAY_INFO,\n    crate::trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS_INFO,\n    crate::trait_bounds::TYPE_REPETITION_IN_BOUNDS_INFO,\n    crate::transmute::CROSSPOINTER_TRANSMUTE_INFO,\n    crate::transmute::EAGER_TRANSMUTE_INFO,\n    crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS_INFO,\n    crate::transmute::TRANSMUTE_BYTES_TO_STR_INFO,\n    crate::transmute::TRANSMUTE_INT_TO_BOOL_INFO,\n    crate::transmute::TRANSMUTE_INT_TO_NON_ZERO_INFO,\n    crate::transmute::TRANSMUTE_NULL_TO_FN_INFO,\n    crate::transmute::TRANSMUTE_PTR_TO_PTR_INFO,\n    crate::transmute::TRANSMUTE_PTR_TO_REF_INFO,\n    crate::transmute::TRANSMUTE_UNDEFINED_REPR_INFO,\n    crate::transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS_INFO,\n    crate::transmute::TRANSMUTING_NULL_INFO,\n    crate::transmute::UNSOUND_COLLECTION_TRANSMUTE_INFO,\n    crate::transmute::USELESS_TRANSMUTE_INFO,\n    crate::transmute::WRONG_TRANSMUTE_INFO,\n    crate::tuple_array_conversions::TUPLE_ARRAY_CONVERSIONS_INFO,\n    crate::types::BORROWED_BOX_INFO,\n    crate::types::BOX_COLLECTION_INFO,\n    crate::types::LINKEDLIST_INFO,\n    crate::types::OPTION_OPTION_INFO,\n    crate::types::OWNED_COW_INFO,\n    crate::types::RC_BUFFER_INFO,\n    crate::types::RC_MUTEX_INFO,\n    crate::types::REDUNDANT_ALLOCATION_INFO,\n    crate::types::TYPE_COMPLEXITY_INFO,\n    crate::types::VEC_BOX_INFO,\n    crate::unconditional_recursion::UNCONDITIONAL_RECURSION_INFO,\n    crate::undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS_INFO,\n    crate::undocumented_unsafe_blocks::UNNECESSARY_SAFETY_COMMENT_INFO,\n    crate::unicode::INVISIBLE_CHARACTERS_INFO,\n    crate::unicode::NON_ASCII_LITERAL_INFO,\n    crate::unicode::UNICODE_NOT_NFC_INFO,\n    crate::uninhabited_references::UNINHABITED_REFERENCES_INFO,\n    crate::uninit_vec::UNINIT_VEC_INFO,\n    crate::unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD_INFO,\n    crate::unit_types::LET_UNIT_VALUE_INFO,\n    crate::unit_types::UNIT_ARG_INFO,\n    crate::unit_types::UNIT_CMP_INFO,\n    crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO,\n    crate::unnecessary_literal_bound::UNNECESSARY_LITERAL_BOUND_INFO,\n    crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,\n    crate::unnecessary_mut_passed::UNNECESSARY_MUT_PASSED_INFO,\n    crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,\n    crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,\n    crate::unnecessary_semicolon::UNNECESSARY_SEMICOLON_INFO,\n    crate::unnecessary_struct_initialization::UNNECESSARY_STRUCT_INITIALIZATION_INFO,\n    crate::unnecessary_wraps::UNNECESSARY_WRAPS_INFO,\n    crate::unneeded_struct_pattern::UNNEEDED_STRUCT_PATTERN_INFO,\n    crate::unnested_or_patterns::UNNESTED_OR_PATTERNS_INFO,\n    crate::unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME_INFO,\n    crate::unused_async::UNUSED_ASYNC_INFO,\n    crate::unused_io_amount::UNUSED_IO_AMOUNT_INFO,\n    crate::unused_peekable::UNUSED_PEEKABLE_INFO,\n    crate::unused_result_ok::UNUSED_RESULT_OK_INFO,\n    crate::unused_rounding::UNUSED_ROUNDING_INFO,\n    crate::unused_self::UNUSED_SELF_INFO,\n    crate::unused_trait_names::UNUSED_TRAIT_NAMES_INFO,\n    crate::unused_unit::UNUSED_UNIT_INFO,\n    crate::unwrap::PANICKING_UNWRAP_INFO,\n    crate::unwrap::UNNECESSARY_UNWRAP_INFO,\n    crate::unwrap_in_result::UNWRAP_IN_RESULT_INFO,\n    crate::upper_case_acronyms::UPPER_CASE_ACRONYMS_INFO,\n    crate::use_self::USE_SELF_INFO,\n    crate::useless_concat::USELESS_CONCAT_INFO,\n    crate::useless_conversion::USELESS_CONVERSION_INFO,\n    crate::useless_vec::USELESS_VEC_INFO,\n    crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO,\n    crate::visibility::NEEDLESS_PUB_SELF_INFO,\n    crate::visibility::PUB_WITH_SHORTHAND_INFO,\n    crate::visibility::PUB_WITHOUT_SHORTHAND_INFO,\n    crate::volatile_composites::VOLATILE_COMPOSITES_INFO,\n    crate::wildcard_imports::ENUM_GLOB_USE_INFO,\n    crate::wildcard_imports::WILDCARD_IMPORTS_INFO,\n    crate::write::PRINT_LITERAL_INFO,\n    crate::write::PRINT_STDERR_INFO,\n    crate::write::PRINT_STDOUT_INFO,\n    crate::write::PRINT_WITH_NEWLINE_INFO,\n    crate::write::PRINTLN_EMPTY_STRING_INFO,\n    crate::write::USE_DEBUG_INFO,\n    crate::write::WRITE_LITERAL_INFO,\n    crate::write::WRITE_WITH_NEWLINE_INFO,\n    crate::write::WRITELN_EMPTY_STRING_INFO,\n    crate::zero_div_zero::ZERO_DIVIDED_BY_ZERO_INFO,\n    crate::zero_repeat_side_effects::ZERO_REPEAT_SIDE_EFFECTS_INFO,\n    crate::zero_sized_map_values::ZERO_SIZED_MAP_VALUES_INFO,\n    crate::zombie_processes::ZOMBIE_PROCESSES_INFO,\n];\n"
  },
  {
    "path": "clippy_lints/src/default.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::{has_drop, is_copy};\nuse clippy_utils::{contains_name, get_parent_expr, in_automatically_derived, is_expr_default, is_from_proc_macro};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind, StructTailExpr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::{Ident, Symbol};\nuse rustc_span::{Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for literal calls to `Default::default()`.\n    ///\n    /// ### Why is this bad?\n    /// It's easier for the reader if the name of the type is used, rather than the\n    /// generic `Default`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let s: String = Default::default();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let s = String::default();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DEFAULT_TRAIT_ACCESS,\n    pedantic,\n    \"checks for literal calls to `Default::default()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for immediate reassignment of fields initialized\n    /// with Default::default().\n    ///\n    /// ### Why is this bad?\n    ///It's more idiomatic to use the [functional update syntax](https://doc.rust-lang.org/reference/expressions/struct-expr.html#functional-update-syntax).\n    ///\n    /// ### Known problems\n    /// Assignments to patterns that are of tuple type are not linted.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # #[derive(Default)]\n    /// # struct A { i: i32 }\n    /// let mut a: A = Default::default();\n    /// a.i = 42;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # #[derive(Default)]\n    /// # struct A { i: i32 }\n    /// let a = A {\n    ///     i: 42,\n    ///     .. Default::default()\n    /// };\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub FIELD_REASSIGN_WITH_DEFAULT,\n    style,\n    \"binding initialized with Default should have its fields set in the initializer\"\n}\n\nimpl_lint_pass!(Default => [DEFAULT_TRAIT_ACCESS, FIELD_REASSIGN_WITH_DEFAULT]);\n\n#[derive(Default)]\npub struct Default {\n    // Spans linted by `field_reassign_with_default`.\n    reassigned_linted: FxHashSet<Span>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Default {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if !expr.span.from_expansion()\n            // Avoid cases already linted by `field_reassign_with_default`\n            && !self.reassigned_linted.contains(&expr.span)\n            && let ExprKind::Call(path, []) = expr.kind\n            && !in_automatically_derived(cx.tcx, expr.hir_id)\n            && let ExprKind::Path(ref qpath) = path.kind\n            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()\n            && cx.tcx.is_diagnostic_item(sym::default_fn, def_id)\n            && !is_update_syntax_base(cx, expr)\n            // Detect and ignore <Foo as Default>::default() because these calls do explicitly name the type.\n            && let QPath::Resolved(None, _path) = qpath\n            && let expr_ty = cx.typeck_results().expr_ty(expr)\n            && let ty::Adt(def, ..) = expr_ty.kind()\n            && !is_from_proc_macro(cx, expr)\n        {\n            let replacement = with_forced_trimmed_paths!(format!(\"{}::default()\", cx.tcx.def_path_str(def.did())));\n            span_lint_and_sugg(\n                cx,\n                DEFAULT_TRAIT_ACCESS,\n                expr.span,\n                format!(\"calling `{replacement}` is more clear than this expression\"),\n                \"try\",\n                replacement,\n                Applicability::Unspecified, // First resolve the TODO above\n            );\n        }\n    }\n\n    #[expect(clippy::too_many_lines)]\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {\n        // start from the `let mut _ = _::default();` and look at all the following\n        // statements, see if they re-assign the fields of the binding\n        let stmts_head = match block.stmts {\n            [] | [_] => return,\n            // Skip the last statement since there cannot possibly be any following statements that re-assign fields.\n            [head @ .., _] => head,\n        };\n        for (stmt_idx, stmt) in stmts_head.iter().enumerate() {\n            // find all binding statements like `let mut _ = T::default()` where `T::default()` is the\n            // `default` method of the `Default` trait, and store statement index in current block being\n            // checked and the name of the bound variable\n            let (local, variant, binding_name, binding_type, span) = if let StmtKind::Let(local) = stmt.kind\n                // only take `let ...` statements\n                && let Some(expr) = local.init\n                && !in_automatically_derived(cx.tcx, expr.hir_id)\n                && !expr.span.from_expansion()\n                // only take bindings to identifiers\n                && let PatKind::Binding(_, binding_id, ident, _) = local.pat.kind\n                // only when assigning `... = Default::default()`\n                && is_expr_default(cx, expr)\n                && let binding_type = cx.typeck_results().node_type(binding_id)\n                && let ty::Adt(adt, args) = *binding_type.kind()\n                && adt.is_struct()\n                && let variant = adt.non_enum_variant()\n                && !variant.field_list_has_applicable_non_exhaustive()\n                && let module_did = cx.tcx.parent_module(stmt.hir_id)\n                && variant\n                    .fields\n                    .iter()\n                    .all(|field| field.vis.is_accessible_from(module_did, cx.tcx))\n                && let all_fields_are_copy = variant\n                    .fields\n                    .iter()\n                    .all(|field| {\n                        is_copy(cx, cx.tcx.type_of(field.did).instantiate(cx.tcx, args))\n                    })\n                && (!has_drop(cx, binding_type) || all_fields_are_copy)\n            {\n                (local, variant, ident.name, binding_type, expr.span)\n            } else {\n                continue;\n            };\n\n            let init_ctxt = local.span.ctxt();\n\n            // find all \"later statement\"'s where the fields of the binding set as\n            // Default::default() get reassigned, unless the reassignment refers to the original binding\n            let mut first_assign = None;\n            let mut assigned_fields = Vec::new();\n            let mut cancel_lint = false;\n            for consecutive_statement in &block.stmts[stmt_idx + 1..] {\n                // find out if and which field was set by this `consecutive_statement`\n                if let Some((field_ident, assign_rhs)) = field_reassigned_by_stmt(consecutive_statement, binding_name) {\n                    // interrupt and cancel lint if assign_rhs references the original binding\n                    if contains_name(binding_name, assign_rhs, cx) || init_ctxt != consecutive_statement.span.ctxt() {\n                        cancel_lint = true;\n                        break;\n                    }\n\n                    // if the field was previously assigned, replace the assignment, otherwise insert the assignment\n                    if let Some(prev) = assigned_fields\n                        .iter_mut()\n                        .find(|(field_name, _)| field_name == &field_ident.name)\n                    {\n                        *prev = (field_ident.name, assign_rhs);\n                    } else {\n                        assigned_fields.push((field_ident.name, assign_rhs));\n                    }\n\n                    // also set first instance of error for help message\n                    if first_assign.is_none() {\n                        first_assign = Some(consecutive_statement);\n                    }\n                }\n                // interrupt if no field was assigned, since we only want to look at consecutive statements\n                else {\n                    break;\n                }\n            }\n\n            // if there are incorrectly assigned fields, do a span_lint_and_note to suggest\n            // construction using `Ty { fields, ..Default::default() }`\n            if !assigned_fields.is_empty() && !cancel_lint {\n                // if all fields of the struct are not assigned, add `.. Default::default()` to the suggestion.\n                let ext_with_default = !variant\n                    .fields\n                    .iter()\n                    .all(|field| assigned_fields.iter().any(|(a, _)| a == &field.name));\n\n                let mut app = Applicability::Unspecified;\n                let field_list = assigned_fields\n                    .into_iter()\n                    .map(|(field, rhs)| {\n                        // extract and store the assigned value for help message\n                        let value_snippet = snippet_with_context(cx, rhs.span, init_ctxt, \"..\", &mut app).0;\n                        format!(\"{field}: {value_snippet}\")\n                    })\n                    .collect::<Vec<String>>()\n                    .join(\", \");\n\n                // give correct suggestion if generics are involved (see #6944)\n                let binding_type = if let ty::Adt(adt_def, args) = binding_type.kind()\n                    && !args.is_empty()\n                {\n                    let adt_def_ty_name = cx.tcx.item_name(adt_def.did());\n                    let generic_args = args.iter().collect::<Vec<_>>();\n                    let tys_str = generic_args\n                        .iter()\n                        .map(ToString::to_string)\n                        .collect::<Vec<_>>()\n                        .join(\", \");\n                    format!(\"{adt_def_ty_name}::<{tys_str}>\")\n                } else {\n                    binding_type.to_string()\n                };\n\n                let sugg = if ext_with_default {\n                    if field_list.is_empty() {\n                        format!(\"{binding_type}::default()\")\n                    } else {\n                        format!(\"{binding_type} {{ {field_list}, ..Default::default() }}\")\n                    }\n                } else {\n                    format!(\"{binding_type} {{ {field_list} }}\")\n                };\n\n                // span lint once per statement that binds default\n                span_lint_and_note(\n                    cx,\n                    FIELD_REASSIGN_WITH_DEFAULT,\n                    first_assign.unwrap().span,\n                    \"field assignment outside of initializer for an instance created with Default::default()\",\n                    Some(local.span),\n                    format!(\"consider initializing the variable with `{sugg}` and removing relevant reassignments\"),\n                );\n                self.reassigned_linted.insert(span);\n            }\n        }\n    }\n}\n\n/// Returns the reassigned field and the assigning expression (right-hand side of assign).\nfn field_reassigned_by_stmt<'tcx>(this: &Stmt<'tcx>, binding_name: Symbol) -> Option<(Ident, &'tcx Expr<'tcx>)> {\n    if let StmtKind::Semi(later_expr) = this.kind\n        // only take assignments\n        && let ExprKind::Assign(assign_lhs, assign_rhs, _) = later_expr.kind\n        // only take assignments to fields where the left-hand side field is a field of\n        // the same binding as the previous statement\n        && let ExprKind::Field(binding, field_ident) = assign_lhs.kind\n        && let ExprKind::Path(QPath::Resolved(_, path)) = binding.kind\n        && let Some(second_binding_name) = path.segments.last()\n        && second_binding_name.ident.name == binding_name\n    {\n        Some((field_ident, assign_rhs))\n    } else {\n        None\n    }\n}\n\n/// Returns whether `expr` is the update syntax base: `Foo { a: 1, .. base }`\nfn is_update_syntax_base<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {\n    if let Some(parent) = get_parent_expr(cx, expr)\n        && let ExprKind::Struct(_, _, StructTailExpr::Base(base)) = parent.kind\n    {\n        base.hir_id == expr.hir_id\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/default_constructed_unit_structs.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_ty_alias;\nuse clippy_utils::source::SpanRangeExt as _;\nuse hir::ExprKind;\nuse hir::def::Res;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for construction on unit struct using `default`.\n    ///\n    /// ### Why is this bad?\n    /// This adds code complexity and an unnecessary function call.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::marker::PhantomData;\n    /// #[derive(Default)]\n    /// struct S<T> {\n    ///     _marker: PhantomData<T>\n    /// }\n    ///\n    /// let _: S<i32> = S {\n    ///     _marker: PhantomData::default()\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::marker::PhantomData;\n    /// struct S<T> {\n    ///     _marker: PhantomData<T>\n    /// }\n    ///\n    /// let _: S<i32> = S {\n    ///     _marker: PhantomData\n    /// };\n    /// ```\n    #[clippy::version = \"1.71.0\"]\n    pub DEFAULT_CONSTRUCTED_UNIT_STRUCTS,\n    complexity,\n    \"unit structs can be constructed without calling `default`\"\n}\n\ndeclare_lint_pass!(DefaultConstructedUnitStructs => [\n    DEFAULT_CONSTRUCTED_UNIT_STRUCTS,\n]);\n\nfn is_alias(ty: hir::Ty<'_>) -> bool {\n    if let hir::TyKind::Path(ref qpath) = ty.kind {\n        is_ty_alias(qpath)\n    } else {\n        false\n    }\n}\n\nimpl LateLintPass<'_> for DefaultConstructedUnitStructs {\n    fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {\n        if let ExprKind::Call(fn_expr, &[]) = expr.kind\n            // make sure we have a call to `Default::default`\n            && let ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(base, _)) = fn_expr.kind\n            // make sure this isn't a type alias:\n            // `<Foo as Bar>::Assoc` cannot be used as a constructor\n            && !is_alias(*base)\n            && let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id)\n            && cx.tcx.is_diagnostic_item(sym::default_fn, def_id)\n            // make sure we have a struct with no fields (unit struct)\n            && let ty::Adt(def, ..) = cx.typeck_results().expr_ty(expr).kind()\n            && def.is_struct()\n            && let var @ ty::VariantDef { ctor: Some((hir::def::CtorKind::Const, _)), .. } = def.non_enum_variant()\n            && !var.is_field_list_non_exhaustive()\n            && !expr.span.from_expansion() && !qpath.span().from_expansion()\n            // do not suggest replacing an expression by a type name with placeholders\n            && !base.is_suggestable_infer_ty()\n        {\n            let mut removals = vec![(expr.span.with_lo(qpath.qself_span().hi()), String::new())];\n            if expr.span.check_source_text(cx, |s| s.starts_with('<')) {\n                // Remove `<`, '>` has already been removed by the existing removal expression.\n                removals.push((expr.span.with_hi(qpath.qself_span().lo()), String::new()));\n            }\n            span_lint_and_then(\n                cx,\n                DEFAULT_CONSTRUCTED_UNIT_STRUCTS,\n                expr.span,\n                \"use of `default` to create a unit struct\",\n                |diag| {\n                    diag.multipart_suggestion(\n                        \"remove this call to `default`\",\n                        removals,\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/default_instead_of_iter_empty.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{last_path_segment, std_or_core, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, GenericArg, QPath, TyKind, def};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::SyntaxContext;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// It checks for `std::iter::Empty::default()` and suggests replacing it with\n    /// `std::iter::empty()`.\n    /// ### Why is this bad?\n    /// `std::iter::empty()` is the more idiomatic way.\n    /// ### Example\n    /// ```no_run\n    /// let _ = std::iter::Empty::<usize>::default();\n    /// let iter: std::iter::Empty<usize> = std::iter::Empty::default();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let _ = std::iter::empty::<usize>();\n    /// let iter: std::iter::Empty<usize> = std::iter::empty();\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub DEFAULT_INSTEAD_OF_ITER_EMPTY,\n    style,\n    \"check `std::iter::Empty::default()` and replace with `std::iter::empty()`\"\n}\n\ndeclare_lint_pass!(DefaultIterEmpty => [DEFAULT_INSTEAD_OF_ITER_EMPTY]);\n\nimpl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Call(iter_expr, []) = &expr.kind\n            && let ExprKind::Path(QPath::TypeRelative(ty, _)) = &iter_expr.kind\n            && let TyKind::Path(ty_path) = &ty.kind\n            && let QPath::Resolved(None, path) = ty_path\n            && let def::Res::Def(_, def_id) = &path.res\n            && cx.tcx.is_diagnostic_item(sym::IterEmpty, *def_id)\n            && let ctxt = expr.span.ctxt()\n            && ty.span.ctxt() == ctxt\n        {\n            let mut applicability = Applicability::MachineApplicable;\n            let Some(path) = std_or_core(cx) else { return };\n            let path = format!(\"{path}::iter::empty\");\n            let sugg = make_sugg(cx, ty_path, ctxt, &mut applicability, &path);\n            span_lint_and_sugg(\n                cx,\n                DEFAULT_INSTEAD_OF_ITER_EMPTY,\n                expr.span,\n                format!(\"`{path}()` is the more idiomatic way\"),\n                \"try\",\n                sugg,\n                applicability,\n            );\n        }\n    }\n}\n\nfn make_sugg(\n    cx: &LateContext<'_>,\n    ty_path: &QPath<'_>,\n    ctxt: SyntaxContext,\n    applicability: &mut Applicability,\n    path: &str,\n) -> String {\n    if let Some(last) = last_path_segment(ty_path).args\n        && let Some(iter_ty) = last.args.iter().find_map(|arg| match arg {\n            GenericArg::Type(ty) => Some(ty),\n            _ => None,\n        })\n    {\n        format!(\n            \"{path}::<{}>()\",\n            snippet_with_context(cx, iter_ty.span, ctxt, \"..\", applicability).0\n        )\n    } else {\n        format!(\"{path}()\")\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/default_numeric_fallback.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::numeric_literal;\nuse clippy_utils::source::snippet_opt;\nuse rustc_ast::ast::{LitFloatType, LitIntType, LitKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{Visitor, walk_expr, walk_pat, walk_stmt};\nuse rustc_hir::{\n    Block, Body, ConstContext, Expr, ExprKind, FnRetTy, HirId, Lit, Pat, PatExpr, PatExprKind, PatKind, Stmt, StmtKind,\n    StructTailExpr,\n};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};\nuse rustc_session::declare_lint_pass;\nuse std::iter;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type\n    /// inference.\n    ///\n    /// Default numeric fallback means that if numeric types have not yet been bound to concrete\n    /// types at the end of type inference, then integer type is bound to `i32`, and similarly\n    /// floating type is bound to `f64`.\n    ///\n    /// See [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback.\n    ///\n    /// ### Why restrict this?\n    /// To ensure that every numeric type is chosen explicitly rather than implicitly.\n    ///\n    /// ### Known problems\n    /// This lint is implemented using a custom algorithm independent of rustc's inference,\n    /// which results in many false positives and false negatives.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let i = 10;\n    /// let f = 1.23;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let i = 10_i32;\n    /// let f = 1.23_f64;\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub DEFAULT_NUMERIC_FALLBACK,\n    restriction,\n    \"usage of unconstrained numeric literals which may cause default numeric fallback.\"\n}\n\ndeclare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]);\n\nimpl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback {\n    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {\n        // NOTE: this is different from `clippy_utils::is_inside_always_const_context`.\n        // Inline const supports type inference.\n        let is_parent_const = matches!(\n            cx.tcx.hir_body_const_context(cx.tcx.hir_body_owner_def_id(body.id())),\n            Some(ConstContext::Const { inline: false } | ConstContext::Static(_))\n        );\n        let mut visitor = NumericFallbackVisitor::new(cx, is_parent_const);\n        visitor.visit_body(body);\n    }\n}\n\nstruct NumericFallbackVisitor<'a, 'tcx> {\n    /// Stack manages type bound of exprs. The top element holds current expr type.\n    ty_bounds: Vec<ExplicitTyBound>,\n\n    cx: &'a LateContext<'tcx>,\n}\n\nimpl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>, is_parent_const: bool) -> Self {\n        Self {\n            ty_bounds: vec![if is_parent_const {\n                ExplicitTyBound(true)\n            } else {\n                ExplicitTyBound(false)\n            }],\n            cx,\n        }\n    }\n\n    /// Check whether a passed literal has potential to cause fallback or not.\n    fn check_lit(&self, lit: Lit, lit_ty: Ty<'tcx>, emit_hir_id: HirId) {\n        if !lit.span.in_external_macro(self.cx.sess().source_map())\n            && matches!(self.ty_bounds.last(), Some(ExplicitTyBound(false)))\n            && matches!(\n                lit.node,\n                LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed)\n            )\n        {\n            let (suffix, is_float) = match lit_ty.kind() {\n                ty::Int(IntTy::I32) => (\"i32\", false),\n                ty::Float(FloatTy::F64) => (\"f64\", true),\n                _ => return,\n            };\n            span_lint_hir_and_then(\n                self.cx,\n                DEFAULT_NUMERIC_FALLBACK,\n                emit_hir_id,\n                lit.span,\n                \"default numeric fallback might occur\",\n                |diag| {\n                    let src = if let Some(src) = snippet_opt(self.cx, lit.span) {\n                        src\n                    } else {\n                        match lit.node {\n                            LitKind::Int(src, _) => format!(\"{src}\"),\n                            LitKind::Float(src, _) => format!(\"{src}\"),\n                            _ => unreachable!(\"Default numeric fallback never results in other types\"),\n                        }\n                    };\n\n                    let sugg = numeric_literal::format(&src, Some(suffix), is_float);\n                    diag.span_suggestion(lit.span, \"consider adding suffix\", sugg, Applicability::MaybeIncorrect);\n                },\n            );\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for NumericFallbackVisitor<'_, 'tcx> {\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        match &expr.kind {\n            ExprKind::Block(\n                Block {\n                    stmts, expr: Some(_), ..\n                },\n                _,\n            ) => {\n                if let Some(fn_sig) = self.cx.tcx.parent_hir_node(expr.hir_id).fn_sig()\n                    && let FnRetTy::Return(_ty) = fn_sig.decl.output\n                {\n                    // We cannot check the exact type since it's a `hir::Ty`` which does not implement `is_numeric`\n                    self.ty_bounds.push(ExplicitTyBound(true));\n                    for stmt in *stmts {\n                        self.visit_stmt(stmt);\n                    }\n                    self.ty_bounds.pop();\n                    // Ignore return expr since we know its type was inferred from return ty\n                    return;\n                }\n            },\n\n            // Ignore return expr since we know its type was inferred from return ty\n            ExprKind::Ret(_) => return,\n\n            ExprKind::Call(func, args) => {\n                if let Some(fn_sig) = fn_sig_opt(self.cx, func.hir_id) {\n                    for (expr, bound) in iter::zip(*args, fn_sig.skip_binder().inputs()) {\n                        // If is from macro, try to use last bound type (typically pushed when visiting stmt),\n                        // otherwise push found arg type, then visit arg,\n                        if expr.span.from_expansion() {\n                            self.visit_expr(expr);\n                        } else {\n                            self.ty_bounds.push((*bound).into());\n                            self.visit_expr(expr);\n                            self.ty_bounds.pop();\n                        }\n                    }\n                    return;\n                }\n            },\n\n            ExprKind::MethodCall(_, receiver, args, _) => {\n                if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) {\n                    let fn_sig = self.cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();\n                    for (expr, bound) in iter::zip(iter::once(*receiver).chain(args.iter()), fn_sig.inputs()) {\n                        self.ty_bounds.push((*bound).into());\n                        self.visit_expr(expr);\n                        self.ty_bounds.pop();\n                    }\n                    return;\n                }\n            },\n\n            ExprKind::Struct(_, fields, base) => {\n                let ty = self.cx.typeck_results().expr_ty(expr);\n                if let Some(adt_def) = ty.ty_adt_def()\n                    && adt_def.is_struct()\n                    && let Some(variant) = adt_def.variants().iter().next()\n                {\n                    let fields_def = &variant.fields;\n\n                    // Push field type then visit each field expr.\n                    for field in *fields {\n                        let bound = fields_def.iter().find_map(|f_def| {\n                            if f_def.ident(self.cx.tcx) == field.ident {\n                                Some(self.cx.tcx.type_of(f_def.did).instantiate_identity())\n                            } else {\n                                None\n                            }\n                        });\n                        self.ty_bounds.push(bound.into());\n                        self.visit_expr(field.expr);\n                        self.ty_bounds.pop();\n                    }\n\n                    // Visit base with no bound.\n                    if let StructTailExpr::Base(base) = base {\n                        self.ty_bounds.push(ExplicitTyBound(false));\n                        self.visit_expr(base);\n                        self.ty_bounds.pop();\n                    }\n                    return;\n                }\n            },\n\n            ExprKind::Lit(lit) => {\n                let ty = self.cx.typeck_results().expr_ty(expr);\n                self.check_lit(*lit, ty, expr.hir_id);\n                return;\n            },\n\n            _ => {},\n        }\n\n        walk_expr(self, expr);\n    }\n\n    fn visit_pat(&mut self, pat: &'tcx Pat<'_>) {\n        if let PatKind::Expr(&PatExpr {\n            hir_id,\n            kind: PatExprKind::Lit { lit, .. },\n            ..\n        }) = pat.kind\n        {\n            let ty = self.cx.typeck_results().node_type(hir_id);\n            self.check_lit(lit, ty, hir_id);\n            return;\n        }\n        walk_pat(self, pat);\n    }\n\n    fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {\n        match stmt.kind {\n            // we cannot check the exact type since it's a hir::Ty which does not implement `is_numeric`\n            StmtKind::Let(local) => self.ty_bounds.push(ExplicitTyBound(local.ty.is_some())),\n\n            _ => self.ty_bounds.push(ExplicitTyBound(false)),\n        }\n\n        walk_stmt(self, stmt);\n        self.ty_bounds.pop();\n    }\n}\n\nfn fn_sig_opt<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<PolyFnSig<'tcx>> {\n    let node_ty = cx.typeck_results().node_type_opt(hir_id)?;\n    // We can't use `Ty::fn_sig` because it automatically performs args, this may result in FNs.\n    match node_ty.kind() {\n        ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).instantiate_identity()),\n        ty::FnPtr(sig_tys, hdr) => Some(sig_tys.with(*hdr)),\n        _ => None,\n    }\n}\n\n/// Wrapper around a `bool` to make the meaning of the value clearer\n#[derive(Debug, Clone, Copy)]\nstruct ExplicitTyBound(pub bool);\n\nimpl<'tcx> From<Ty<'tcx>> for ExplicitTyBound {\n    fn from(v: Ty<'tcx>) -> Self {\n        Self(v.is_numeric())\n    }\n}\n\nimpl<'tcx> From<Option<Ty<'tcx>>> for ExplicitTyBound {\n    fn from(v: Option<Ty<'tcx>>) -> Self {\n        Self(v.is_some_and(Ty::is_numeric))\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/default_union_representation.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_hir::attrs::ReprAttr;\nuse rustc_hir::{HirId, Item, ItemKind, find_attr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_middle::ty::{self, FieldDef};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Displays a warning when a union is declared with the default representation (without a `#[repr(C)]` attribute).\n    ///\n    /// ### Why restrict this?\n    /// Unions in Rust have unspecified layout by default, despite many people thinking that they\n    /// lay out each field at the start of the union (like C does). That is, there are no guarantees\n    /// about the offset of the fields for unions with multiple non-ZST fields without an explicitly\n    /// specified layout. These cases may lead to undefined behavior in unsafe blocks.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// union Foo {\n    ///     a: i32,\n    ///     b: u32,\n    /// }\n    ///\n    /// fn main() {\n    ///     let _x: u32 = unsafe {\n    ///         Foo { a: 0_i32 }.b // Undefined behavior: `b` is allowed to be padding\n    ///     };\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[repr(C)]\n    /// union Foo {\n    ///     a: i32,\n    ///     b: u32,\n    /// }\n    ///\n    /// fn main() {\n    ///     let _x: u32 = unsafe {\n    ///         Foo { a: 0_i32 }.b // Now defined behavior, this is just an i32 -> u32 transmute\n    ///     };\n    /// }\n    /// ```\n    #[clippy::version = \"1.60.0\"]\n    pub DEFAULT_UNION_REPRESENTATION,\n    restriction,\n    \"unions without a `#[repr(C)]` attribute\"\n}\n\ndeclare_lint_pass!(DefaultUnionRepresentation => [DEFAULT_UNION_REPRESENTATION]);\n\nimpl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if !item.span.from_expansion()\n            && is_union_with_two_non_zst_fields(cx, item)\n            && !has_c_repr_attr(cx, item.hir_id())\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                DEFAULT_UNION_REPRESENTATION,\n                item.span,\n                \"this union has the default representation\",\n                |diag| {\n                    diag.help(format!(\n                        \"consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout\",\n                        cx.tcx.def_path_str(item.owner_id)\n                    ));\n                },\n            );\n        }\n    }\n}\n\n/// Returns true if the given item is a union with at least two non-ZST fields.\n/// (ZST fields having an arbitrary offset is completely inconsequential, and\n/// if there is only one field left after ignoring ZST fields then the offset\n/// of that field does not matter either.)\nfn is_union_with_two_non_zst_fields<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {\n    if let ItemKind::Union(..) = &item.kind\n        && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()\n    {\n        adt_def.all_fields().filter(|f| !is_zst(cx, f, args)).count() >= 2\n    } else {\n        false\n    }\n}\n\nfn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: ty::GenericArgsRef<'tcx>) -> bool {\n    let ty = field.ty(cx.tcx, args);\n    if let Ok(layout) = cx.layout_of(ty) {\n        layout.is_zst()\n    } else {\n        false\n    }\n}\n\nfn has_c_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {\n    let attrs = cx.tcx.hir_attrs(hir_id);\n\n    find_attr!(attrs, Repr { reprs, .. } if reprs.iter().any(|(x, _)| *x == ReprAttr::ReprC))\n}\n"
  },
  {
    "path": "clippy_lints/src/deprecated_lints.rs",
    "content": "// This file is managed by `cargo dev rename_lint` and `cargo dev deprecate_lint`.\n// Prefer to use those when possible.\n\nmacro_rules! declare_with_version {\n    ($name:ident($name_version:ident) = [$(\n        #[clippy::version = $version:literal]\n        $e:expr,\n    )*]) => {\n        pub static $name: &[(&str, &str)] = &[$($e),*];\n        pub static $name_version: &[&str] = &[$($version),*];\n    };\n}\n\n#[rustfmt::skip]\ndeclare_with_version! { DEPRECATED(DEPRECATED_VERSION) = [\n    #[clippy::version = \"1.30.0\"]\n    (\"clippy::assign_ops\", \"compound operators are harmless and linting on them is not in scope for clippy\"),\n    #[clippy::version = \"pre 1.29.0\"]\n    (\"clippy::extend_from_slice\", \"`Vec::extend_from_slice` is no longer faster than `Vec::extend` due to specialization\"),\n    #[clippy::version = \"1.88.0\"]\n    (\"clippy::match_on_vec_items\", \"`clippy::indexing_slicing` covers indexing and slicing on `Vec<_>`\"),\n    #[clippy::version = \"pre 1.29.0\"]\n    (\"clippy::misaligned_transmute\", \"split into `clippy::cast_ptr_alignment` and `clippy::transmute_ptr_to_ptr`\"),\n    #[clippy::version = \"1.87.0\"]\n    (\"clippy::option_map_or_err_ok\", \"`clippy::manual_ok_or` covers this case\"),\n    #[clippy::version = \"1.54.0\"]\n    (\"clippy::pub_enum_variant_names\", \"`clippy::enum_variant_names` now covers this case via the `avoid-breaking-exported-api` config\"),\n    #[clippy::version = \"pre 1.29.0\"]\n    (\"clippy::range_step_by_zero\", \"`Iterator::step_by(0)` now panics and is no longer an infinite iterator\"),\n    #[clippy::version = \"1.47.0\"]\n    (\"clippy::regex_macro\", \"the `regex!` macro was removed from the regex crate in 2018\"),\n    #[clippy::version = \"1.44.0\"]\n    (\"clippy::replace_consts\", \"`min_value` and `max_value` are now deprecated\"),\n    #[clippy::version = \"pre 1.29.0\"]\n    (\"clippy::should_assert_eq\", \"`assert!(a == b)` can now print the values the same way `assert_eq!(a, b) can\"),\n    #[clippy::version = \"1.91.0\"]\n    (\"clippy::string_to_string\", \"`clippy::implicit_clone` covers those cases\"),\n    #[clippy::version = \"pre 1.29.0\"]\n    (\"clippy::unsafe_vector_initialization\", \"the suggested alternative could be substantially slower\"),\n    #[clippy::version = \"pre 1.29.0\"]\n    (\"clippy::unstable_as_mut_slice\", \"`Vec::as_mut_slice` is now stable\"),\n    #[clippy::version = \"pre 1.29.0\"]\n    (\"clippy::unstable_as_slice\", \"`Vec::as_slice` is now stable\"),\n    #[clippy::version = \"1.39.0\"]\n    (\"clippy::unused_collect\", \"`Iterator::collect` is now marked as `#[must_use]`\"),\n    #[clippy::version = \"1.54.0\"]\n    (\"clippy::wrong_pub_self_convention\", \"`clippy::wrong_self_convention` now covers this case via the `avoid-breaking-exported-api` config\"),\n]}\n\n#[rustfmt::skip]\ndeclare_with_version! { RENAMED(RENAMED_VERSION) = [\n    #[clippy::version = \"\"]\n    (\"clippy::almost_complete_letter_range\", \"clippy::almost_complete_range\"),\n    #[clippy::version = \"\"]\n    (\"clippy::blacklisted_name\", \"clippy::disallowed_names\"),\n    #[clippy::version = \"\"]\n    (\"clippy::block_in_if_condition_expr\", \"clippy::blocks_in_conditions\"),\n    #[clippy::version = \"\"]\n    (\"clippy::block_in_if_condition_stmt\", \"clippy::blocks_in_conditions\"),\n    #[clippy::version = \"\"]\n    (\"clippy::blocks_in_if_conditions\", \"clippy::blocks_in_conditions\"),\n    #[clippy::version = \"\"]\n    (\"clippy::box_vec\", \"clippy::box_collection\"),\n    #[clippy::version = \"\"]\n    (\"clippy::cast_ref_to_mut\", \"invalid_reference_casting\"),\n    #[clippy::version = \"\"]\n    (\"clippy::clone_double_ref\", \"suspicious_double_ref_op\"),\n    #[clippy::version = \"\"]\n    (\"clippy::cmp_nan\", \"invalid_nan_comparisons\"),\n    #[clippy::version = \"\"]\n    (\"clippy::const_static_lifetime\", \"clippy::redundant_static_lifetimes\"),\n    #[clippy::version = \"\"]\n    (\"clippy::cyclomatic_complexity\", \"clippy::cognitive_complexity\"),\n    #[clippy::version = \"\"]\n    (\"clippy::derive_hash_xor_eq\", \"clippy::derived_hash_with_manual_eq\"),\n    #[clippy::version = \"\"]\n    (\"clippy::disallowed_method\", \"clippy::disallowed_methods\"),\n    #[clippy::version = \"\"]\n    (\"clippy::disallowed_type\", \"clippy::disallowed_types\"),\n    #[clippy::version = \"1.86.0\"]\n    (\"clippy::double_neg\", \"double_negations\"),\n    #[clippy::version = \"\"]\n    (\"clippy::drop_bounds\", \"drop_bounds\"),\n    #[clippy::version = \"\"]\n    (\"clippy::drop_copy\", \"dropping_copy_types\"),\n    #[clippy::version = \"\"]\n    (\"clippy::drop_ref\", \"dropping_references\"),\n    #[clippy::version = \"1.92.0\"]\n    (\"clippy::empty_enum\", \"clippy::empty_enums\"),\n    #[clippy::version = \"\"]\n    (\"clippy::eval_order_dependence\", \"clippy::mixed_read_write_in_expression\"),\n    #[clippy::version = \"1.53.0\"]\n    (\"clippy::filter_map\", \"clippy::manual_filter_map\"),\n    #[clippy::version = \"1.51.0\"]\n    (\"clippy::find_map\", \"clippy::manual_find_map\"),\n    #[clippy::version = \"\"]\n    (\"clippy::fn_address_comparisons\", \"unpredictable_function_pointer_comparisons\"),\n    #[clippy::version = \"\"]\n    (\"clippy::fn_null_check\", \"useless_ptr_null_checks\"),\n    #[clippy::version = \"\"]\n    (\"clippy::for_loop_over_option\", \"for_loops_over_fallibles\"),\n    #[clippy::version = \"\"]\n    (\"clippy::for_loop_over_result\", \"for_loops_over_fallibles\"),\n    #[clippy::version = \"\"]\n    (\"clippy::for_loops_over_fallibles\", \"for_loops_over_fallibles\"),\n    #[clippy::version = \"\"]\n    (\"clippy::forget_copy\", \"forgetting_copy_types\"),\n    #[clippy::version = \"\"]\n    (\"clippy::forget_ref\", \"forgetting_references\"),\n    #[clippy::version = \"\"]\n    (\"clippy::identity_conversion\", \"clippy::useless_conversion\"),\n    #[clippy::version = \"pre 1.29.0\"]\n    (\"clippy::if_let_redundant_pattern_matching\", \"clippy::redundant_pattern_matching\"),\n    #[clippy::version = \"\"]\n    (\"clippy::if_let_some_result\", \"clippy::match_result_ok\"),\n    #[clippy::version = \"\"]\n    (\"clippy::incorrect_clone_impl_on_copy_type\", \"clippy::non_canonical_clone_impl\"),\n    #[clippy::version = \"\"]\n    (\"clippy::incorrect_partial_ord_impl_on_ord_type\", \"clippy::non_canonical_partial_ord_impl\"),\n    #[clippy::version = \"\"]\n    (\"clippy::integer_arithmetic\", \"clippy::arithmetic_side_effects\"),\n    #[clippy::version = \"\"]\n    (\"clippy::into_iter_on_array\", \"array_into_iter\"),\n    #[clippy::version = \"\"]\n    (\"clippy::invalid_atomic_ordering\", \"invalid_atomic_ordering\"),\n    #[clippy::version = \"1.88.0\"]\n    (\"clippy::invalid_null_ptr_usage\", \"invalid_null_arguments\"),\n    #[clippy::version = \"\"]\n    (\"clippy::invalid_ref\", \"invalid_value\"),\n    #[clippy::version = \"\"]\n    (\"clippy::invalid_utf8_in_unchecked\", \"invalid_from_utf8_unchecked\"),\n    #[clippy::version = \"\"]\n    (\"clippy::let_underscore_drop\", \"let_underscore_drop\"),\n    #[clippy::version = \"\"]\n    (\"clippy::logic_bug\", \"clippy::overly_complex_bool_expr\"),\n    #[clippy::version = \"1.80.0\"]\n    (\"clippy::maybe_misused_cfg\", \"unexpected_cfgs\"),\n    #[clippy::version = \"\"]\n    (\"clippy::mem_discriminant_non_enum\", \"enum_intrinsics_non_enums\"),\n    #[clippy::version = \"1.80.0\"]\n    (\"clippy::mismatched_target_os\", \"unexpected_cfgs\"),\n    #[clippy::version = \"1.92.0\"]\n    (\"clippy::needless_if\", \"clippy::needless_ifs\"),\n    #[clippy::version = \"\"]\n    (\"clippy::new_without_default_derive\", \"clippy::new_without_default\"),\n    #[clippy::version = \"\"]\n    (\"clippy::option_and_then_some\", \"clippy::bind_instead_of_map\"),\n    #[clippy::version = \"\"]\n    (\"clippy::option_expect_used\", \"clippy::expect_used\"),\n    #[clippy::version = \"\"]\n    (\"clippy::option_map_unwrap_or\", \"clippy::map_unwrap_or\"),\n    #[clippy::version = \"\"]\n    (\"clippy::option_map_unwrap_or_else\", \"clippy::map_unwrap_or\"),\n    #[clippy::version = \"\"]\n    (\"clippy::option_unwrap_used\", \"clippy::unwrap_used\"),\n    #[clippy::version = \"\"]\n    (\"clippy::overflow_check_conditional\", \"clippy::panicking_overflow_checks\"),\n    #[clippy::version = \"\"]\n    (\"clippy::panic_params\", \"non_fmt_panics\"),\n    #[clippy::version = \"\"]\n    (\"clippy::positional_named_format_parameters\", \"named_arguments_used_positionally\"),\n    #[clippy::version = \"\"]\n    (\"clippy::ref_in_deref\", \"clippy::needless_borrow\"),\n    #[clippy::version = \"\"]\n    (\"clippy::result_expect_used\", \"clippy::expect_used\"),\n    #[clippy::version = \"\"]\n    (\"clippy::result_map_unwrap_or_else\", \"clippy::map_unwrap_or\"),\n    #[clippy::version = \"\"]\n    (\"clippy::result_unwrap_used\", \"clippy::unwrap_used\"),\n    #[clippy::version = \"\"]\n    (\"clippy::reverse_range_loop\", \"clippy::reversed_empty_ranges\"),\n    #[clippy::version = \"\"]\n    (\"clippy::single_char_push_str\", \"clippy::single_char_add_str\"),\n    #[clippy::version = \"\"]\n    (\"clippy::stutter\", \"clippy::module_name_repetitions\"),\n    #[clippy::version = \"\"]\n    (\"clippy::temporary_cstring_as_ptr\", \"dangling_pointers_from_temporaries\"),\n    #[clippy::version = \"\"]\n    (\"clippy::thread_local_initializer_can_be_made_const\", \"clippy::missing_const_for_thread_local\"),\n    #[clippy::version = \"\"]\n    (\"clippy::to_string_in_display\", \"clippy::recursive_format_impl\"),\n    #[clippy::version = \"1.88.0\"]\n    (\"clippy::transmute_float_to_int\", \"unnecessary_transmutes\"),\n    #[clippy::version = \"1.88.0\"]\n    (\"clippy::transmute_int_to_char\", \"unnecessary_transmutes\"),\n    #[clippy::version = \"1.88.0\"]\n    (\"clippy::transmute_int_to_float\", \"unnecessary_transmutes\"),\n    #[clippy::version = \"1.88.0\"]\n    (\"clippy::transmute_num_to_bytes\", \"unnecessary_transmutes\"),\n    #[clippy::version = \"1.90.0\"]\n    (\"clippy::unchecked_duration_subtraction\", \"clippy::unchecked_time_subtraction\"),\n    #[clippy::version = \"\"]\n    (\"clippy::undropped_manually_drops\", \"undropped_manually_drops\"),\n    #[clippy::version = \"\"]\n    (\"clippy::unknown_clippy_lints\", \"unknown_lints\"),\n    #[clippy::version = \"\"]\n    (\"clippy::unused_label\", \"unused_labels\"),\n    #[clippy::version = \"\"]\n    (\"clippy::unwrap_or_else_default\", \"clippy::unwrap_or_default\"),\n    #[clippy::version = \"\"]\n    (\"clippy::vtable_address_comparisons\", \"ambiguous_wide_pointer_comparisons\"),\n    #[clippy::version = \"\"]\n    (\"clippy::zero_width_space\", \"clippy::invisible_characters\"),\n]}\n"
  },
  {
    "path": "clippy_lints/src/dereference.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::sugg::has_enclosing_paren;\nuse clippy_utils::ty::{adjust_derefs_manually_drop, implements_trait, is_manually_drop, peel_and_count_ty_refs};\nuse clippy_utils::{\n    DefinedTy, ExprUseNode, expr_use_ctxt, get_parent_expr, is_block_like, is_from_proc_macro, is_lint_allowed, sym,\n};\nuse rustc_ast::util::parser::ExprPrecedence;\nuse rustc_data_structures::fx::FxIndexMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};\nuse rustc_hir::{\n    self as hir, AmbigArg, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, Item, MatchSource, Mutability,\n    Node, OwnerId, Pat, PatKind, Path, QPath, TyKind, UnOp,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};\nuse rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\nuse std::borrow::Cow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for dereferencing expressions which would be covered by auto-deref.\n    ///\n    /// ### Why is this bad?\n    /// This unnecessarily complicates the code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = String::new();\n    /// let y: &str = &*x;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = String::new();\n    /// let y: &str = &x;\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub EXPLICIT_AUTO_DEREF,\n    complexity,\n    \"dereferencing when the compiler would automatically dereference\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for explicit `deref()` or `deref_mut()` method calls.\n    ///\n    /// Doesn't lint inside the implementation of the `Deref` or `DerefMut` traits.\n    ///\n    /// ### Why is this bad?\n    /// Dereferencing by `&*x` or `&mut *x` is clearer and more concise,\n    /// when not part of a method chain.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::ops::Deref;\n    /// let a: &mut String = &mut String::from(\"foo\");\n    /// let b: &str = a.deref();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let a: &mut String = &mut String::from(\"foo\");\n    /// let b = &*a;\n    /// ```\n    ///\n    /// This lint excludes all of:\n    /// ```rust,ignore\n    /// let _ = d.unwrap().deref();\n    /// let _ = Foo::deref(&foo);\n    /// let _ = <Foo as Deref>::deref(&foo);\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub EXPLICIT_DEREF_METHODS,\n    pedantic,\n    \"Explicit use of deref or deref_mut method while not in a method chain.\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for address of operations (`&`) that are going to\n    /// be dereferenced immediately by the compiler.\n    ///\n    /// ### Why is this bad?\n    /// Suggests that the receiver of the expression borrows\n    /// the expression.\n    ///\n    /// ### Known problems\n    /// The lint cannot tell when the implementation of a trait\n    /// for `&T` and `T` do different things. Removing a borrow\n    /// in such a case can change the semantics of the code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn fun(_a: &i32) {}\n    ///\n    /// let x: &i32 = &&&&&&5;\n    /// fun(&x);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # fn fun(_a: &i32) {}\n    /// let x: &i32 = &5;\n    /// fun(x);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_BORROW,\n    style,\n    \"taking a reference that is going to be automatically dereferenced\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `ref` bindings which create a reference to a reference.\n    ///\n    /// ### Why is this bad?\n    /// The address-of operator at the use site is clearer about the need for a reference.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = Some(\"\");\n    /// if let Some(ref x) = x {\n    ///     // use `x` here\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let x = Some(\"\");\n    /// if let Some(x) = x {\n    ///     // use `&x` here\n    /// }\n    /// ```\n    #[clippy::version = \"1.54.0\"]\n    pub REF_BINDING_TO_REFERENCE,\n    pedantic,\n    \"`ref` binding to a reference\"\n}\n\nimpl_lint_pass!(Dereferencing<'_> => [\n    EXPLICIT_AUTO_DEREF,\n    EXPLICIT_DEREF_METHODS,\n    NEEDLESS_BORROW,\n    REF_BINDING_TO_REFERENCE,\n]);\n\n#[derive(Default)]\npub struct Dereferencing<'tcx> {\n    state: Option<(State, StateData<'tcx>)>,\n\n    // While parsing a `deref` method call in ufcs form, the path to the function is itself an\n    // expression. This is to store the id of that expression so it can be skipped when\n    // `check_expr` is called for it.\n    skip_expr: Option<HirId>,\n\n    /// The body the first local was found in. Used to emit lints when the traversal of the body has\n    /// been finished. Note we can't lint at the end of every body as they can be nested within each\n    /// other.\n    current_body: Option<BodyId>,\n\n    /// The list of locals currently being checked by the lint.\n    /// If the value is `None`, then the binding has been seen as a ref pattern, but is not linted.\n    /// This is needed for or patterns where one of the branches can be linted, but another can not\n    /// be.\n    ///\n    /// e.g. `m!(x) | Foo::Bar(ref x)`\n    ref_locals: FxIndexMap<HirId, Option<RefPat>>,\n\n    /// The outermost `impl Deref` we're currently in. While we're in one,\n    /// `explicit_deref_methods` is deactivated\n    outermost_deref_impl: Option<OwnerId>,\n}\n\n#[derive(Debug)]\nstruct StateData<'tcx> {\n    first_expr: &'tcx Expr<'tcx>,\n    adjusted_ty: Ty<'tcx>,\n}\n\n#[derive(Debug)]\nstruct DerefedBorrow {\n    count: usize,\n    msg: &'static str,\n    stability: TyCoercionStability,\n    for_field_access: Option<Symbol>,\n}\n\n#[derive(Debug)]\nenum State {\n    // Any number of deref method calls.\n    DerefMethod {\n        // The number of calls in a sequence which changed the referenced type\n        ty_changed_count: usize,\n        is_ufcs: bool,\n        /// The required mutability\n        mutbl: Mutability,\n    },\n    DerefedBorrow(DerefedBorrow),\n    ExplicitDeref {\n        mutability: Option<Mutability>,\n    },\n    ExplicitDerefField {\n        name: Symbol,\n        derefs_manually_drop: bool,\n    },\n    Reborrow {\n        mutability: Mutability,\n    },\n    Borrow {\n        mutability: Mutability,\n    },\n}\n\n// A reference operation considered by this lint pass\nenum RefOp {\n    Method { mutbl: Mutability, is_ufcs: bool },\n    Deref,\n    AddrOf(Mutability),\n}\n\nstruct RefPat {\n    /// Whether every usage of the binding is dereferenced.\n    always_deref: bool,\n    /// The spans of all the ref bindings for this local.\n    spans: Vec<Span>,\n    /// The applicability of this suggestion.\n    app: Applicability,\n    /// All the replacements which need to be made.\n    replacements: Vec<(Span, String)>,\n    /// The [`HirId`] that the lint should be emitted at.\n    hir_id: HirId,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {\n    #[expect(clippy::too_many_lines)]\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        // Skip path expressions from deref calls. e.g. `Deref::deref(e)`\n        if Some(expr.hir_id) == self.skip_expr.take() {\n            return;\n        }\n\n        if let Some(local) = expr.res_local_id() {\n            self.check_local_usage(cx, expr, local);\n        }\n\n        // Stop processing sub expressions when a macro call is seen\n        if expr.span.from_expansion() {\n            if let Some((state, data)) = self.state.take() {\n                self.report(cx, expr, state, data, cx.typeck_results());\n            }\n            return;\n        }\n\n        let typeck = cx.typeck_results();\n        let Some((kind, sub_expr, skip_expr)) = try_parse_ref_op(cx.tcx, typeck, expr) else {\n            // The whole chain of reference operations has been seen\n            if let Some((state, data)) = self.state.take() {\n                self.report(cx, expr, state, data, typeck);\n            }\n            return;\n        };\n        self.skip_expr = skip_expr;\n\n        if is_from_proc_macro(cx, expr) {\n            if let Some((state, data)) = self.state.take() {\n                self.report(cx, expr, state, data, cx.typeck_results());\n            }\n            return;\n        }\n\n        match (self.state.take(), kind) {\n            (None, kind) => {\n                let expr_ty = typeck.expr_ty(expr);\n                let use_cx = expr_use_ctxt(cx, expr);\n                let adjusted_ty = use_cx.adjustments.last().map_or(expr_ty, |a| a.target);\n\n                match kind {\n                    RefOp::Deref if use_cx.same_ctxt => {\n                        let use_node = use_cx.use_node(cx);\n                        let sub_ty = typeck.expr_ty(sub_expr);\n                        if let ExprUseNode::FieldAccess(name) = use_node\n                            && !use_cx.moved_before_use\n                            && !ty_contains_field(sub_ty, name.name)\n                        {\n                            self.state = Some((\n                                State::ExplicitDerefField {\n                                    name: name.name,\n                                    derefs_manually_drop: is_manually_drop(sub_ty),\n                                },\n                                StateData {\n                                    first_expr: expr,\n                                    adjusted_ty,\n                                },\n                            ));\n                        } else if sub_ty.is_ref()\n                            // Linting method receivers would require verifying that name lookup\n                            // would resolve the same way. This is complicated by trait methods.\n                            && !use_node.is_recv()\n                            && let Some(ty) = use_node.defined_ty(cx)\n                            && TyCoercionStability::for_defined_ty(cx, ty, use_node.is_return()).is_deref_stable()\n                        {\n                            self.state = Some((\n                                State::ExplicitDeref { mutability: None },\n                                StateData {\n                                    first_expr: expr,\n                                    adjusted_ty,\n                                },\n                            ));\n                        }\n                    },\n                    RefOp::Method { mutbl, is_ufcs }\n                        if !is_lint_allowed(cx, EXPLICIT_DEREF_METHODS, expr.hir_id)\n                            // Allow explicit deref in method chains. e.g. `foo.deref().bar()`\n                            && (is_ufcs || !is_in_method_chain(cx, expr)) =>\n                    {\n                        let ty_changed_count = usize::from(!deref_method_same_type(expr_ty, typeck.expr_ty(sub_expr)));\n                        self.state = Some((\n                            State::DerefMethod {\n                                ty_changed_count,\n                                is_ufcs,\n                                mutbl,\n                            },\n                            StateData {\n                                first_expr: expr,\n                                adjusted_ty,\n                            },\n                        ));\n                    },\n                    RefOp::AddrOf(mutability) if use_cx.same_ctxt => {\n                        // Find the number of times the borrow is auto-derefed.\n                        let mut iter = use_cx.adjustments.iter();\n                        let mut deref_count = 0usize;\n                        let next_adjust = loop {\n                            match iter.next() {\n                                Some(adjust) => {\n                                    if !matches!(adjust.kind, Adjust::Deref(_)) {\n                                        break Some(adjust);\n                                    } else if !adjust.target.is_ref() {\n                                        deref_count += 1;\n                                        break iter.next();\n                                    }\n                                    deref_count += 1;\n                                },\n                                None => break None,\n                            }\n                        };\n\n                        let use_node = use_cx.use_node(cx);\n                        let stability = use_node.defined_ty(cx).map_or(TyCoercionStability::None, |ty| {\n                            TyCoercionStability::for_defined_ty(cx, ty, use_node.is_return())\n                        });\n                        let can_auto_borrow = match use_node {\n                            ExprUseNode::FieldAccess(_)\n                                if !use_cx.moved_before_use && matches!(sub_expr.kind, ExprKind::Field(..)) =>\n                            {\n                                // `DerefMut` will not be automatically applied to `ManuallyDrop<_>`\n                                // field expressions when the base type is a union and the parent\n                                // expression is also a field access.\n                                //\n                                // e.g. `&mut x.y.z` where `x` is a union, and accessing `z` requires a\n                                // deref through `ManuallyDrop<_>` will not compile.\n                                !adjust_derefs_manually_drop(use_cx.adjustments, expr_ty)\n                            },\n                            ExprUseNode::Callee | ExprUseNode::FieldAccess(_) if !use_cx.moved_before_use => true,\n                            ExprUseNode::MethodArg(hir_id, _, 0) if !use_cx.moved_before_use => {\n                                // Check for calls to trait methods where the trait is implemented\n                                // on a reference.\n                                // Two cases need to be handled:\n                                // * `self` methods on `&T` will never have auto-borrow\n                                // * `&self` methods on `&T` can have auto-borrow, but `&self` methods on `T` will take\n                                //   priority.\n                                if let Some(fn_id) = typeck.type_dependent_def_id(hir_id)\n                                    && let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id)\n                                    && let arg_ty = cx.tcx.erase_and_anonymize_regions(adjusted_ty)\n                                    && let ty::Ref(_, sub_ty, _) = *arg_ty.kind()\n                                    && let args =\n                                        typeck.node_args_opt(hir_id).map(|args| &args[1..]).unwrap_or_default()\n                                    && let impl_ty =\n                                        if cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder().inputs()[0]\n                                            .is_ref()\n                                        {\n                                            // Trait methods taking `&self`\n                                            sub_ty\n                                        } else {\n                                            // Trait methods taking `self`\n                                            arg_ty\n                                        }\n                                    && impl_ty.is_ref()\n                                    && implements_trait(\n                                        cx,\n                                        impl_ty,\n                                        trait_id,\n                                        &args[..cx.tcx.generics_of(trait_id).own_params.len() - 1],\n                                    )\n                                {\n                                    false\n                                } else {\n                                    true\n                                }\n                            },\n                            _ => false,\n                        };\n\n                        let deref_msg =\n                            \"this expression creates a reference which is immediately dereferenced by the compiler\";\n                        let borrow_msg = \"this expression borrows a value the compiler would automatically borrow\";\n\n                        // Determine the required number of references before any can be removed. In all cases the\n                        // reference made by the current expression will be removed. After that there are four cases to\n                        // handle.\n                        //\n                        // 1. Auto-borrow will trigger in the current position, so no further references are required.\n                        // 2. Auto-deref ends at a reference, or the underlying type, so one extra needs to be left to\n                        //    handle the automatically inserted re-borrow.\n                        // 3. Auto-deref hits a user-defined `Deref` impl, so at least one reference needs to exist to\n                        //    start auto-deref.\n                        // 4. If the chain of non-user-defined derefs ends with a mutable re-borrow, and re-borrow\n                        //    adjustments will not be inserted automatically, then leave one further reference to avoid\n                        //    moving a mutable borrow. e.g.\n                        //\n                        //    ```rust\n                        //    fn foo<T>(x: &mut Option<&mut T>, y: &mut T) {\n                        //        let x = match x {\n                        //            // Removing the borrow will cause `x` to be moved\n                        //            Some(x) => &mut *x,\n                        //            None => y\n                        //        };\n                        //    }\n                        //    ```\n                        let (required_refs, msg) = if can_auto_borrow {\n                            (1, if deref_count == 1 { borrow_msg } else { deref_msg })\n                        } else if let Some(&Adjustment {\n                            kind: Adjust::Borrow(AutoBorrow::Ref(mutability)),\n                            ..\n                        }) = next_adjust\n                            && matches!(mutability, AutoBorrowMutability::Mut { .. })\n                            && !stability.is_reborrow_stable()\n                        {\n                            (3, deref_msg)\n                        } else {\n                            (2, deref_msg)\n                        };\n\n                        if deref_count >= required_refs {\n                            self.state = Some((\n                                State::DerefedBorrow(DerefedBorrow {\n                                    // One of the required refs is for the current borrow expression, the remaining ones\n                                    // can't be removed without breaking the code. See earlier comment.\n                                    count: deref_count - required_refs,\n                                    msg,\n                                    stability,\n                                    for_field_access: if let ExprUseNode::FieldAccess(name) = use_node\n                                        && !use_cx.moved_before_use\n                                    {\n                                        Some(name.name)\n                                    } else {\n                                        None\n                                    },\n                                }),\n                                StateData {\n                                    first_expr: expr,\n                                    adjusted_ty,\n                                },\n                            ));\n                        } else if stability.is_deref_stable()\n                            // Auto-deref doesn't combine with other adjustments\n                            && next_adjust.is_none_or(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))\n                            && iter.all(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))\n                        {\n                            self.state = Some((\n                                State::Borrow { mutability },\n                                StateData {\n                                    first_expr: expr,\n                                    adjusted_ty,\n                                },\n                            ));\n                        }\n                    },\n                    _ => {},\n                }\n            },\n            (\n                Some((\n                    State::DerefMethod {\n                        mutbl,\n                        ty_changed_count,\n                        ..\n                    },\n                    data,\n                )),\n                RefOp::Method { is_ufcs, .. },\n            ) => {\n                self.state = Some((\n                    State::DerefMethod {\n                        ty_changed_count: if deref_method_same_type(typeck.expr_ty(expr), typeck.expr_ty(sub_expr)) {\n                            ty_changed_count\n                        } else {\n                            ty_changed_count + 1\n                        },\n                        is_ufcs,\n                        mutbl,\n                    },\n                    data,\n                ));\n            },\n            (Some((State::DerefedBorrow(state), data)), RefOp::AddrOf(_)) if state.count != 0 => {\n                self.state = Some((\n                    State::DerefedBorrow(DerefedBorrow {\n                        count: state.count - 1,\n                        ..state\n                    }),\n                    data,\n                ));\n            },\n            (Some((State::DerefedBorrow(state), data)), RefOp::AddrOf(mutability)) => {\n                let adjusted_ty = data.adjusted_ty;\n                let stability = state.stability;\n                self.report(cx, expr, State::DerefedBorrow(state), data, typeck);\n                if stability.is_deref_stable() {\n                    self.state = Some((\n                        State::Borrow { mutability },\n                        StateData {\n                            first_expr: expr,\n                            adjusted_ty,\n                        },\n                    ));\n                }\n            },\n            (Some((State::DerefedBorrow(state), data)), RefOp::Deref) => {\n                let adjusted_ty = data.adjusted_ty;\n                let stability = state.stability;\n                let for_field_access = state.for_field_access;\n                self.report(cx, expr, State::DerefedBorrow(state), data, typeck);\n                if let Some(name) = for_field_access\n                    && let sub_expr_ty = typeck.expr_ty(sub_expr)\n                    && !ty_contains_field(sub_expr_ty, name)\n                {\n                    self.state = Some((\n                        State::ExplicitDerefField {\n                            name,\n                            derefs_manually_drop: is_manually_drop(sub_expr_ty),\n                        },\n                        StateData {\n                            first_expr: expr,\n                            adjusted_ty,\n                        },\n                    ));\n                } else if stability.is_deref_stable()\n                    && let Some(parent) = get_parent_expr(cx, expr)\n                {\n                    self.state = Some((\n                        State::ExplicitDeref { mutability: None },\n                        StateData {\n                            first_expr: parent,\n                            adjusted_ty,\n                        },\n                    ));\n                }\n            },\n\n            (Some((State::Borrow { mutability }, data)), RefOp::Deref) => {\n                if typeck.expr_ty(sub_expr).is_ref() {\n                    self.state = Some((State::Reborrow { mutability }, data));\n                } else {\n                    self.state = Some((\n                        State::ExplicitDeref {\n                            mutability: Some(mutability),\n                        },\n                        data,\n                    ));\n                }\n            },\n            (Some((State::Reborrow { mutability }, data)), RefOp::Deref) => {\n                self.state = Some((\n                    State::ExplicitDeref {\n                        mutability: Some(mutability),\n                    },\n                    data,\n                ));\n            },\n            (state @ Some((State::ExplicitDeref { .. }, _)), RefOp::Deref) => {\n                self.state = state;\n            },\n            (\n                Some((\n                    State::ExplicitDerefField {\n                        name,\n                        derefs_manually_drop,\n                    },\n                    data,\n                )),\n                RefOp::Deref,\n            ) if let sub_expr_ty = typeck.expr_ty(sub_expr)\n                && !ty_contains_field(sub_expr_ty, name) =>\n            {\n                self.state = Some((\n                    State::ExplicitDerefField {\n                        name,\n                        derefs_manually_drop: derefs_manually_drop || is_manually_drop(sub_expr_ty),\n                    },\n                    data,\n                ));\n            },\n\n            (Some((state, data)), _) => self.report(cx, expr, state, data, typeck),\n        }\n    }\n\n    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {\n        if let PatKind::Binding(BindingMode::REF, id, name, _) = pat.kind {\n            if let Some(opt_prev_pat) = self.ref_locals.get_mut(&id) {\n                // This binding id has been seen before. Add this pattern to the list of changes.\n                if let Some(prev_pat) = opt_prev_pat {\n                    if pat.span.from_expansion() {\n                        // Doesn't match the context of the previous pattern. Can't lint here.\n                        *opt_prev_pat = None;\n                    } else {\n                        prev_pat.spans.push(pat.span);\n                        prev_pat.replacements.push((\n                            pat.span,\n                            snippet_with_context(cx, name.span, pat.span.ctxt(), \"..\", &mut prev_pat.app)\n                                .0\n                                .into(),\n                        ));\n                    }\n                }\n                return;\n            }\n\n            if !pat.span.from_expansion()\n                && let ty::Ref(_, tam, _) = *cx.typeck_results().pat_ty(pat).kind()\n                // only lint immutable refs, because borrowed `&mut T` cannot be moved out\n                && let ty::Ref(_, _, Mutability::Not) = *tam.kind()\n            {\n                let mut app = Applicability::MachineApplicable;\n                let snip = snippet_with_context(cx, name.span, pat.span.ctxt(), \"..\", &mut app).0;\n                self.current_body = self.current_body.or(cx.enclosing_body);\n                self.ref_locals.insert(\n                    id,\n                    Some(RefPat {\n                        always_deref: true,\n                        spans: vec![pat.span],\n                        app,\n                        replacements: vec![(pat.span, snip.into())],\n                        hir_id: pat.hir_id,\n                    }),\n                );\n            }\n        }\n    }\n\n    fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'_>) {\n        if Some(body.id()) == self.current_body {\n            for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) {\n                let replacements = pat.replacements;\n                let app = pat.app;\n                let lint = if pat.always_deref {\n                    NEEDLESS_BORROW\n                } else {\n                    REF_BINDING_TO_REFERENCE\n                };\n                span_lint_hir_and_then(\n                    cx,\n                    lint,\n                    pat.hir_id,\n                    pat.spans,\n                    \"this pattern creates a reference to a reference\",\n                    |diag| {\n                        diag.multipart_suggestion(\"try\", replacements, app);\n                    },\n                );\n            }\n            self.current_body = None;\n        }\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        // Only check for `impl Deref(Mut)`s if we're not already in one\n        if !self.in_deref_impl() && is_deref_or_derefmut_impl(cx, item) {\n            self.outermost_deref_impl = Some(item.owner_id);\n        }\n    }\n\n    fn check_item_post(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) {\n        // Only clear `self.outermost_deref_impl` if we're escaping the _outermost_ `impl Deref(Mut)`\n        if self.outermost_deref_impl == Some(item.owner_id) {\n            self.outermost_deref_impl = None;\n        }\n    }\n}\n\nfn is_deref_or_derefmut_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool {\n    if let hir::ItemKind::Impl(impl_) = item.kind\n        && let Some(of_trait) = impl_.of_trait\n        && let Some(trait_id) = of_trait.trait_ref.trait_def_id()\n    {\n        cx.tcx.lang_items().deref_trait() == Some(trait_id) || cx.tcx.lang_items().deref_mut_trait() == Some(trait_id)\n    } else {\n        false\n    }\n}\n\nfn try_parse_ref_op<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    typeck: &'tcx TypeckResults<'_>,\n    expr: &'tcx Expr<'_>,\n) -> Option<(RefOp, &'tcx Expr<'tcx>, Option<HirId>)> {\n    let (call_path_id, def_id, arg) = match expr.kind {\n        ExprKind::MethodCall(_, arg, [], _) => (None, typeck.type_dependent_def_id(expr.hir_id)?, arg),\n        ExprKind::Call(\n            &Expr {\n                kind: ExprKind::Path(QPath::Resolved(None, path)),\n                hir_id,\n                ..\n            },\n            [arg],\n        ) => (Some(hir_id), path.res.opt_def_id()?, arg),\n        ExprKind::Unary(UnOp::Deref, sub_expr) if !typeck.expr_ty(sub_expr).is_raw_ptr() => {\n            return Some((RefOp::Deref, sub_expr, None));\n        },\n        ExprKind::AddrOf(BorrowKind::Ref, mutability, sub_expr) => {\n            return Some((RefOp::AddrOf(mutability), sub_expr, None));\n        },\n        _ => return None,\n    };\n    let mutbl = match tcx.get_diagnostic_name(def_id) {\n        Some(sym::deref_method) => Mutability::Not,\n        Some(sym::deref_mut_method) => Mutability::Mut,\n        _ => return None,\n    };\n    Some((\n        RefOp::Method {\n            mutbl,\n            is_ufcs: call_path_id.is_some(),\n        },\n        arg,\n        call_path_id,\n    ))\n}\n\n// Checks whether the type for a deref call actually changed the type, not just the mutability of\n// the reference.\nfn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {\n    match (result_ty.kind(), arg_ty.kind()) {\n        (ty::Ref(_, result_ty, _), ty::Ref(_, arg_ty, _)) => result_ty == arg_ty,\n\n        // The result type for a deref method is always a reference\n        // Not matching the previous pattern means the argument type is not a reference\n        // This means that the type did change\n        _ => false,\n    }\n}\n\nfn is_in_method_chain<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {\n    if let ExprKind::MethodCall(_, recv, _, _) = e.kind\n        && matches!(recv.kind, ExprKind::MethodCall(..))\n    {\n        return true;\n    }\n\n    if let Some(parent) = get_parent_expr(cx, e)\n        && parent.span.eq_ctxt(e.span)\n    {\n        match parent.kind {\n            ExprKind::Call(child, _) | ExprKind::MethodCall(_, child, _, _) | ExprKind::Index(child, _, _)\n                if child.hir_id == e.hir_id =>\n            {\n                true\n            },\n            ExprKind::Match(.., MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar) | ExprKind::Field(_, _) => true,\n            _ => false,\n        }\n    } else {\n        false\n    }\n}\n\n#[derive(Clone, Copy, Debug)]\nenum TyCoercionStability {\n    Deref,\n    Reborrow,\n    None,\n}\nimpl TyCoercionStability {\n    fn is_deref_stable(self) -> bool {\n        matches!(self, Self::Deref)\n    }\n\n    fn is_reborrow_stable(self) -> bool {\n        matches!(self, Self::Deref | Self::Reborrow)\n    }\n\n    fn for_defined_ty<'tcx>(cx: &LateContext<'tcx>, ty: DefinedTy<'tcx>, for_return: bool) -> Self {\n        match ty {\n            DefinedTy::Hir(ty) => Self::for_hir_ty(ty),\n            DefinedTy::Mir { def_site_def_id, ty } => Self::for_mir_ty(\n                cx.tcx,\n                def_site_def_id,\n                cx.tcx.instantiate_bound_regions_with_erased(ty),\n                for_return,\n            ),\n        }\n    }\n\n    // Checks the stability of type coercions when assigned to a binding with the given explicit type.\n    //\n    // e.g.\n    // let x = Box::new(Box::new(0u32));\n    // let y1: &Box<_> = x.deref();\n    // let y2: &Box<_> = &x;\n    //\n    // Here `y1` and `y2` would resolve to different types, so the type `&Box<_>` is not stable when\n    // switching to auto-dereferencing.\n    fn for_hir_ty<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> Self {\n        let TyKind::Ref(_, ty) = &ty.kind else {\n            return Self::None;\n        };\n        let mut ty = ty;\n\n        loop {\n            break match ty.ty.kind {\n                TyKind::Ref(_, ref ref_ty) => {\n                    ty = ref_ty;\n                    continue;\n                },\n                TyKind::Path(\n                    QPath::TypeRelative(_, path)\n                    | QPath::Resolved(\n                        _,\n                        Path {\n                            segments: [.., path], ..\n                        },\n                    ),\n                ) => {\n                    if let Some(args) = path.args\n                        && args.args.iter().any(|arg| match arg {\n                            hir::GenericArg::Infer(_) => true,\n                            hir::GenericArg::Type(ty) => ty_contains_infer(ty.as_unambig_ty()),\n                            _ => false,\n                        })\n                    {\n                        Self::Reborrow\n                    } else {\n                        Self::Deref\n                    }\n                },\n                TyKind::Slice(_)\n                | TyKind::Array(..)\n                | TyKind::Ptr(_)\n                | TyKind::FnPtr(_)\n                | TyKind::Pat(..)\n                | TyKind::FieldOf(..)\n                | TyKind::Never\n                | TyKind::Tup(_)\n                | TyKind::Path(_) => Self::Deref,\n                TyKind::OpaqueDef(..)\n                | TyKind::TraitAscription(..)\n                | TyKind::Infer(())\n                | TyKind::TraitObject(..)\n                | TyKind::InferDelegation(..)\n                | TyKind::Err(_) => Self::Reborrow,\n                TyKind::UnsafeBinder(..) => Self::None,\n            };\n        }\n    }\n\n    fn for_mir_ty<'tcx>(tcx: TyCtxt<'tcx>, def_site_def_id: Option<DefId>, ty: Ty<'tcx>, for_return: bool) -> Self {\n        let ty::Ref(_, mut ty, _) = *ty.kind() else {\n            return Self::None;\n        };\n\n        if let Some(def_id) = def_site_def_id {\n            let typing_env = ty::TypingEnv::non_body_analysis(tcx, def_id);\n            ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);\n        }\n        loop {\n            break match *ty.kind() {\n                ty::Ref(_, ref_ty, _) => {\n                    ty = ref_ty;\n                    continue;\n                },\n                ty::Param(_) if for_return => Self::Deref,\n                ty::Alias(ty::Free | ty::Inherent, _) => unreachable!(\"should have been normalized away above\"),\n                ty::Alias(ty::Projection, _) if !for_return && ty.has_non_region_param() => Self::Reborrow,\n                ty::Infer(_)\n                | ty::Error(_)\n                | ty::Bound(..)\n                | ty::Alias(ty::Opaque, ..)\n                | ty::Placeholder(_)\n                | ty::Dynamic(..)\n                | ty::Param(_) => Self::Reborrow,\n                ty::Adt(_, args)\n                    if ty.has_placeholders()\n                        || ty.has_opaque_types()\n                        || (!for_return && args.has_non_region_param()) =>\n                {\n                    Self::Reborrow\n                },\n                ty::Bool\n                | ty::Char\n                | ty::Int(_)\n                | ty::Uint(_)\n                | ty::Array(..)\n                | ty::Pat(..)\n                | ty::Float(_)\n                | ty::RawPtr(..)\n                | ty::FnPtr(..)\n                | ty::Str\n                | ty::Slice(..)\n                | ty::Adt(..)\n                | ty::Foreign(_)\n                | ty::FnDef(..)\n                | ty::Coroutine(..)\n                | ty::CoroutineWitness(..)\n                | ty::Closure(..)\n                | ty::CoroutineClosure(..)\n                | ty::Never\n                | ty::Tuple(_)\n                | ty::Alias(ty::Projection, _)\n                | ty::UnsafeBinder(_) => Self::Deref,\n            };\n        }\n    }\n}\n\n// Checks whether a type is inferred at some point.\n// e.g. `_`, `Box<_>`, `[_]`\nfn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {\n    struct V(bool);\n    impl Visitor<'_> for V {\n        fn visit_infer(&mut self, inf_id: HirId, _inf_span: Span, kind: InferKind<'_>) -> Self::Result {\n            if let InferKind::Ty(_) | InferKind::Ambig(_) = kind {\n                self.0 = true;\n            }\n            self.visit_id(inf_id);\n        }\n\n        fn visit_ty(&mut self, ty: &hir::Ty<'_, AmbigArg>) {\n            if self.0 || matches!(ty.kind, TyKind::OpaqueDef(..) | TyKind::Err(_)) {\n                self.0 = true;\n            } else {\n                walk_ty(self, ty);\n            }\n        }\n    }\n    let mut v = V(false);\n    v.visit_ty_unambig(ty);\n    v.0\n}\n\nfn ty_contains_field(ty: Ty<'_>, name: Symbol) -> bool {\n    if let ty::Adt(adt, _) = *ty.kind() {\n        adt.is_struct() && adt.all_fields().any(|f| f.name == name)\n    } else {\n        false\n    }\n}\n\nimpl<'tcx> Dereferencing<'tcx> {\n    fn in_deref_impl(&self) -> bool {\n        self.outermost_deref_impl.is_some()\n    }\n\n    fn check_local_usage(&mut self, cx: &LateContext<'tcx>, e: &Expr<'tcx>, local: HirId) {\n        if let Some(outer_pat) = self.ref_locals.get_mut(&local)\n            && let Some(pat) = outer_pat\n            // Check for auto-deref\n            && !matches!(\n                cx.typeck_results().expr_adjustments(e),\n                [\n                    Adjustment {\n                        kind: Adjust::Deref(_),\n                        ..\n                    },\n                    Adjustment {\n                        kind: Adjust::Deref(_),\n                        ..\n                    },\n                    ..\n                ]\n            )\n        {\n            match get_parent_expr(cx, e) {\n                // Field accesses are the same no matter the number of references.\n                Some(Expr {\n                    kind: ExprKind::Field(..),\n                    ..\n                }) => (),\n                Some(&Expr {\n                    span,\n                    kind: ExprKind::Unary(UnOp::Deref, _),\n                    ..\n                }) if !span.from_expansion() => {\n                    // Remove explicit deref.\n                    let snip = snippet_with_context(cx, e.span, span.ctxt(), \"..\", &mut pat.app).0;\n                    pat.replacements.push((span, snip.into()));\n                },\n                Some(parent) if !parent.span.from_expansion() => {\n                    // Double reference might be needed at this point.\n                    if cx.precedence(parent) == ExprPrecedence::Unambiguous {\n                        // Parentheses would be needed here, don't lint.\n                        *outer_pat = None;\n                    } else {\n                        pat.always_deref = false;\n                        let snip = snippet_with_context(cx, e.span, parent.span.ctxt(), \"..\", &mut pat.app).0;\n                        pat.replacements.push((e.span, format!(\"&{snip}\")));\n                    }\n                },\n                _ if !e.span.from_expansion() => {\n                    // Double reference might be needed at this point.\n                    pat.always_deref = false;\n                    let snip = snippet_with_applicability(cx, e.span, \"..\", &mut pat.app);\n                    pat.replacements.push((e.span, format!(\"&{snip}\")));\n                },\n                // Edge case for macros. The span of the identifier will usually match the context of the\n                // binding, but not if the identifier was created in a macro. e.g. `concat_idents` and proc\n                // macros\n                _ => *outer_pat = None,\n            }\n        }\n    }\n\n    #[expect(clippy::needless_pass_by_value, clippy::too_many_lines)]\n    fn report(\n        &self,\n        cx: &LateContext<'tcx>,\n        expr: &'tcx Expr<'_>,\n        state: State,\n        data: StateData<'tcx>,\n        typeck: &'tcx TypeckResults<'tcx>,\n    ) {\n        match state {\n            State::DerefMethod {\n                ty_changed_count,\n                is_ufcs,\n                mutbl,\n            } => {\n                if self.in_deref_impl() {\n                    // `deref(_mut)` is fine in an `impl Deref(Mut)`\n                    return;\n                }\n                let mut app = Applicability::MachineApplicable;\n                let (expr_str, expr_is_macro_call) =\n                    snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), \"..\", &mut app);\n                let ty = typeck.expr_ty(expr);\n                let (_, ref_count, _) = peel_and_count_ty_refs(ty);\n                let deref_str = if ty_changed_count >= ref_count && ref_count != 0 {\n                    // a deref call changing &T -> &U requires two deref operators the first time\n                    // this occurs. One to remove the reference, a second to call the deref impl.\n                    \"*\".repeat(ty_changed_count + 1)\n                } else {\n                    \"*\".repeat(ty_changed_count)\n                };\n                let addr_of_str = if ty_changed_count < ref_count {\n                    // Check if a reborrow from &mut T -> &T is required.\n                    if mutbl == Mutability::Not && matches!(ty.kind(), ty::Ref(_, _, Mutability::Mut)) {\n                        \"&*\"\n                    } else {\n                        \"\"\n                    }\n                } else if mutbl == Mutability::Mut {\n                    \"&mut \"\n                } else {\n                    \"&\"\n                };\n\n                let expr_str = if !expr_is_macro_call && is_ufcs && cx.precedence(expr) < ExprPrecedence::Prefix {\n                    Cow::Owned(format!(\"({expr_str})\"))\n                } else {\n                    expr_str\n                };\n\n                span_lint_and_sugg(\n                    cx,\n                    EXPLICIT_DEREF_METHODS,\n                    data.first_expr.span,\n                    match mutbl {\n                        Mutability::Not => \"explicit `deref` method call\",\n                        Mutability::Mut => \"explicit `deref_mut` method call\",\n                    },\n                    \"try\",\n                    format!(\"{addr_of_str}{deref_str}{expr_str}\"),\n                    app,\n                );\n            },\n            State::DerefedBorrow(state) => {\n                // Do not suggest removing a non-mandatory `&` in `&*rawptr` in an `unsafe` context,\n                // as this may make rustc trigger its `dangerous_implicit_autorefs` lint.\n                if let ExprKind::AddrOf(BorrowKind::Ref, _, subexpr) = data.first_expr.kind\n                    && let ExprKind::Unary(UnOp::Deref, subsubexpr) = subexpr.kind\n                    && cx.typeck_results().expr_ty_adjusted(subsubexpr).is_raw_ptr()\n                {\n                    return;\n                }\n\n                let mut app = Applicability::MachineApplicable;\n                let (snip, snip_is_macro) =\n                    snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), \"..\", &mut app);\n                span_lint_hir_and_then(\n                    cx,\n                    NEEDLESS_BORROW,\n                    data.first_expr.hir_id,\n                    data.first_expr.span,\n                    state.msg,\n                    |diag| {\n                        let needs_paren = match cx.tcx.parent_hir_node(data.first_expr.hir_id) {\n                            Node::Expr(e) => match e.kind {\n                                ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false,\n                                ExprKind::Call(..) => {\n                                    cx.precedence(expr) < ExprPrecedence::Unambiguous\n                                        || matches!(expr.kind, ExprKind::Field(..))\n                                },\n                                _ => cx.precedence(expr) < cx.precedence(e),\n                            },\n                            _ => false,\n                        };\n                        let is_in_tuple = matches!(\n                            get_parent_expr(cx, data.first_expr),\n                            Some(Expr {\n                                kind: ExprKind::Tup(..),\n                                ..\n                            })\n                        );\n\n                        let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) && !is_in_tuple {\n                            format!(\"({snip})\")\n                        } else {\n                            snip.into()\n                        };\n                        diag.span_suggestion(data.first_expr.span, \"change this to\", sugg, app);\n                    },\n                );\n            },\n            State::ExplicitDeref { mutability } => {\n                if is_block_like(expr)\n                    && let ty::Ref(_, ty, _) = data.adjusted_ty.kind()\n                    && ty.is_sized(cx.tcx, cx.typing_env())\n                {\n                    // Rustc bug: auto deref doesn't work on block expression when targeting sized types.\n                    return;\n                }\n\n                let ty = typeck.expr_ty(expr);\n\n                // `&&[T; N]`, or `&&..&[T; N]` (src) cannot coerce to `&[T]` (dst).\n                if let ty::Ref(_, dst, _) = data.adjusted_ty.kind()\n                    && dst.is_slice()\n                {\n                    let (src, n_src_refs, _) = peel_and_count_ty_refs(ty);\n                    if n_src_refs >= 2 && src.is_array() {\n                        return;\n                    }\n                }\n\n                let (prefix, needs_paren) = match mutability {\n                    Some(mutability) if !ty.is_ref() => {\n                        let prefix = match mutability {\n                            Mutability::Not => \"&\",\n                            Mutability::Mut => \"&mut \",\n                        };\n                        (prefix, cx.precedence(expr) < ExprPrecedence::Prefix)\n                    },\n                    None if !ty.is_ref() && data.adjusted_ty.is_ref() => (\"&\", false),\n                    _ => (\"\", false),\n                };\n                span_lint_hir_and_then(\n                    cx,\n                    EXPLICIT_AUTO_DEREF,\n                    data.first_expr.hir_id,\n                    data.first_expr.span,\n                    \"deref which would be done by auto-deref\",\n                    |diag| {\n                        let mut app = Applicability::MachineApplicable;\n                        let (snip, snip_is_macro) =\n                            snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), \"..\", &mut app);\n                        let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) {\n                            format!(\"{prefix}({snip})\")\n                        } else {\n                            format!(\"{prefix}{snip}\")\n                        };\n                        diag.span_suggestion(data.first_expr.span, \"try\", sugg, app);\n                    },\n                );\n            },\n            State::ExplicitDerefField {\n                derefs_manually_drop, ..\n            } => {\n                let (snip_span, needs_parens) = if matches!(expr.kind, ExprKind::Field(..))\n                    && (derefs_manually_drop\n                        || adjust_derefs_manually_drop(\n                            typeck.expr_adjustments(data.first_expr),\n                            typeck.expr_ty(data.first_expr),\n                        )) {\n                    // `DerefMut` will not be automatically applied to `ManuallyDrop<_>`\n                    // field expressions when the base type is a union and the parent\n                    // expression is also a field access.\n                    //\n                    // e.g. `&mut x.y.z` where `x` is a union, and accessing `z` requires a\n                    // deref through `ManuallyDrop<_>` will not compile.\n                    let parent_id = cx.tcx.parent_hir_id(expr.hir_id);\n                    if parent_id == data.first_expr.hir_id {\n                        return;\n                    }\n                    (cx.tcx.hir_node(parent_id).expect_expr().span, true)\n                } else {\n                    (expr.span, false)\n                };\n                span_lint_hir_and_then(\n                    cx,\n                    EXPLICIT_AUTO_DEREF,\n                    data.first_expr.hir_id,\n                    data.first_expr.span,\n                    \"deref which would be done by auto-deref\",\n                    |diag| {\n                        let mut app = Applicability::MachineApplicable;\n                        let snip = snippet_with_context(cx, snip_span, data.first_expr.span.ctxt(), \"..\", &mut app).0;\n                        let sugg = if needs_parens {\n                            format!(\"({snip})\")\n                        } else {\n                            snip.into_owned()\n                        };\n                        diag.span_suggestion(data.first_expr.span, \"try\", sugg, app);\n                    },\n                );\n            },\n            State::Borrow { .. } | State::Reborrow { .. } => (),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/derivable_impls.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::indent_of;\nuse clippy_utils::{is_default_equivalent, peel_blocks};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};\nuse rustc_hir::{\n    self as hir, Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, TyKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::adjustment::{Adjust, PointerCoercion};\nuse rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty, TypeckResults, VariantDef};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects manual `std::default::Default` implementations that are identical to a derived implementation.\n    ///\n    /// ### Why is this bad?\n    /// It is less concise.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo {\n    ///     bar: bool\n    /// }\n    ///\n    /// impl Default for Foo {\n    ///     fn default() -> Self {\n    ///         Self {\n    ///             bar: false\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #[derive(Default)]\n    /// struct Foo {\n    ///     bar: bool\n    /// }\n    /// ```\n    ///\n    /// ### Known problems\n    /// Derive macros [sometimes use incorrect bounds](https://github.com/rust-lang/rust/issues/26925)\n    /// in generic types and the user defined `impl` may be more generalized or\n    /// specialized than what derive will produce. This lint can't detect the manual `impl`\n    /// has exactly equal bounds, and therefore this lint is disabled for types with\n    /// generic parameters.\n    #[clippy::version = \"1.57.0\"]\n    pub DERIVABLE_IMPLS,\n    complexity,\n    \"manual implementation of the `Default` trait which is equal to a derive\"\n}\n\nimpl_lint_pass!(DerivableImpls => [DERIVABLE_IMPLS]);\n\npub struct DerivableImpls {\n    msrv: Msrv,\n}\n\nimpl DerivableImpls {\n    pub fn new(conf: &'static Conf) -> Self {\n        DerivableImpls { msrv: conf.msrv }\n    }\n}\n\nfn is_path_self(e: &Expr<'_>) -> bool {\n    if let ExprKind::Path(QPath::Resolved(_, p)) = e.kind {\n        matches!(p.res, Res::SelfCtor(..) | Res::Def(DefKind::Ctor(..), _))\n    } else {\n        false\n    }\n}\n\nfn contains_trait_object(ty: Ty<'_>) -> bool {\n    match ty.kind() {\n        ty::Ref(_, ty, _) => contains_trait_object(*ty),\n        ty::Adt(def, args) => def.is_box() && args[0].as_type().is_some_and(contains_trait_object),\n        ty::Dynamic(..) => true,\n        _ => false,\n    }\n}\n\nfn determine_derive_macro(cx: &LateContext<'_>, is_const: bool) -> Option<&'static str> {\n    (!is_const)\n        .then_some(\"derive\")\n        .or_else(|| cx.tcx.features().enabled(sym::derive_const).then_some(\"derive_const\"))\n}\n\n#[expect(clippy::too_many_arguments)]\nfn check_struct<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &'tcx Item<'_>,\n    self_ty: &hir::Ty<'_>,\n    func_expr: &Expr<'_>,\n    adt_def: AdtDef<'_>,\n    ty_args: GenericArgsRef<'_>,\n    typeck_results: &'tcx TypeckResults<'tcx>,\n    is_const: bool,\n) {\n    if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind\n        && let Some(PathSegment { args, .. }) = p.segments.last()\n    {\n        let args = args.map(|a| a.args).unwrap_or_default();\n\n        // ty_args contains the generic parameters of the type declaration, while args contains the\n        // arguments used at instantiation time. If both len are not equal, it means that some\n        // parameters were not provided (which means that the default values were used); in this\n        // case we will not risk suggesting too broad a rewrite. We won't either if any argument\n        // is a type or a const.\n        if ty_args.len() != args.len() || args.iter().any(|arg| !matches!(arg, GenericArg::Lifetime(_))) {\n            return;\n        }\n    }\n\n    // the default() call might unsize coerce to a trait object (e.g. Box<T> to Box<dyn Trait>),\n    // which would not be the same if derived (see #10158).\n    // this closure checks both if the expr is equivalent to a `default()` call and does not\n    // have such coercions.\n    let is_default_without_adjusts = |expr| {\n        is_default_equivalent(cx, expr)\n            && typeck_results.expr_adjustments(expr).iter().all(|adj| {\n                !matches!(adj.kind, Adjust::Pointer(PointerCoercion::Unsize)\n                    if contains_trait_object(adj.target))\n            })\n    };\n\n    let should_emit = match peel_blocks(func_expr).kind {\n        ExprKind::Tup(fields) => fields.iter().all(is_default_without_adjusts),\n        ExprKind::Call(callee, args) if is_path_self(callee) => args.iter().all(is_default_without_adjusts),\n        ExprKind::Struct(_, fields, _) => fields.iter().all(|ef| is_default_without_adjusts(ef.expr)),\n        _ => return,\n    };\n\n    if should_emit && let Some(derive_snippet) = determine_derive_macro(cx, is_const) {\n        let struct_span = cx.tcx.def_span(adt_def.did());\n        let indent_enum = indent_of(cx, struct_span).unwrap_or(0);\n        let suggestions = vec![\n            (item.span, String::new()), // Remove the manual implementation\n            (\n                struct_span.shrink_to_lo(),\n                format!(\"#[{derive_snippet}(Default)]\\n{}\", \" \".repeat(indent_enum)),\n            ), // Add the derive attribute\n        ];\n\n        span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, \"this `impl` can be derived\", |diag| {\n            diag.multipart_suggestion(\n                \"replace the manual implementation with a derive attribute\",\n                suggestions,\n                Applicability::MachineApplicable,\n            );\n        });\n    }\n}\n\nfn extract_enum_variant<'tcx>(\n    cx: &LateContext<'tcx>,\n    func_expr: &'tcx Expr<'tcx>,\n    adt_def: AdtDef<'tcx>,\n) -> Option<&'tcx VariantDef> {\n    match &peel_blocks(func_expr).kind {\n        ExprKind::Path(QPath::Resolved(None, p))\n            if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), id) = p.res\n                && let variant_id = cx.tcx.parent(id)\n                && let Some(variant_def) = adt_def.variants().iter().find(|v| v.def_id == variant_id) =>\n        {\n            Some(variant_def)\n        },\n        ExprKind::Path(QPath::TypeRelative(ty, segment))\n            if let TyKind::Path(QPath::Resolved(None, p)) = &ty.kind\n                && let Res::SelfTyAlias {\n                    is_trait_impl: true, ..\n                } = p.res\n                && let variant_ident = segment.ident\n                && let Some(variant_def) = adt_def.variants().iter().find(|v| v.ident(cx.tcx) == variant_ident) =>\n        {\n            Some(variant_def)\n        },\n        _ => None,\n    }\n}\n\nfn check_enum<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &'tcx Item<'tcx>,\n    func_expr: &'tcx Expr<'tcx>,\n    adt_def: AdtDef<'tcx>,\n    is_const: bool,\n) {\n    if let Some(variant_def) = extract_enum_variant(cx, func_expr, adt_def)\n        && variant_def.fields.is_empty()\n        && !variant_def.is_field_list_non_exhaustive()\n    {\n        let enum_span = cx.tcx.def_span(adt_def.did());\n        let indent_enum = indent_of(cx, enum_span).unwrap_or(0);\n        let variant_span = cx.tcx.def_span(variant_def.def_id);\n        let indent_variant = indent_of(cx, variant_span).unwrap_or(0);\n\n        let Some(derive_snippet) = determine_derive_macro(cx, is_const) else {\n            return;\n        };\n\n        let suggestions = vec![\n            (item.span, String::new()), // Remove the manual implementation\n            (\n                enum_span.shrink_to_lo(),\n                format!(\"#[{derive_snippet}(Default)]\\n{}\", \" \".repeat(indent_enum)),\n            ), // Add the derive attribute\n            (\n                variant_span.shrink_to_lo(),\n                format!(\"#[default]\\n{}\", \" \".repeat(indent_variant)),\n            ), // Mark the default variant\n        ];\n\n        span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, \"this `impl` can be derived\", |diag| {\n            diag.multipart_suggestion(\n                \"replace the manual implementation with a derive attribute and mark the default variant\",\n                suggestions,\n                Applicability::MachineApplicable,\n            );\n        });\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for DerivableImpls {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            items: [child],\n            self_ty,\n            constness,\n            ..\n        }) = item.kind\n            && !cx.tcx.is_automatically_derived(item.owner_id.to_def_id())\n            && !item.span.from_expansion()\n            && let Some(def_id) = of_trait.trait_ref.trait_def_id()\n            && cx.tcx.is_diagnostic_item(sym::Default, def_id)\n            && let impl_item_hir = child.hir_id()\n            && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)\n            && let ImplItemKind::Fn(_, b) = &impl_item.kind\n            && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b)\n            && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()\n            && let attrs = cx.tcx.hir_attrs(item.hir_id())\n            && !attrs.iter().any(|attr| attr.doc_str().is_some())\n            && cx.tcx.hir_attrs(impl_item_hir).is_empty()\n        {\n            let is_const = constness == hir::Constness::Const;\n            if adt_def.is_struct() {\n                check_struct(\n                    cx,\n                    item,\n                    self_ty,\n                    func_expr,\n                    adt_def,\n                    args,\n                    cx.tcx.typeck_body(*b),\n                    is_const,\n                );\n            } else if adt_def.is_enum() && self.msrv.meets(cx, msrvs::DEFAULT_ENUM_ATTRIBUTE) {\n                check_enum(cx, item, func_expr, adt_def, is_const);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/derive/derive_ord_xor_partial_ord.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::fulfill_or_allowed;\nuse rustc_hir::{self as hir, HirId};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::sym;\n\nuse super::DERIVE_ORD_XOR_PARTIAL_ORD;\n\n/// Implementation of the `DERIVE_ORD_XOR_PARTIAL_ORD` lint.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &hir::Item<'_>,\n    trait_ref: &hir::TraitRef<'_>,\n    ty: Ty<'tcx>,\n    adt_hir_id: HirId,\n    ord_is_automatically_derived: bool,\n) {\n    if let Some(ord_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Ord)\n        && let Some(partial_ord_trait_def_id) = cx.tcx.lang_items().partial_ord_trait()\n        && let Some(def_id) = &trait_ref.trait_def_id()\n        && *def_id == ord_trait_def_id\n        && let item_hir_id = cx.tcx.local_def_id_to_hir_id(item.owner_id)\n        && !fulfill_or_allowed(cx, DERIVE_ORD_XOR_PARTIAL_ORD, [adt_hir_id])\n    {\n        // Look for the PartialOrd implementations for `ty`\n        cx.tcx.for_each_relevant_impl(partial_ord_trait_def_id, ty, |impl_id| {\n            let partial_ord_is_automatically_derived = cx.tcx.is_automatically_derived(impl_id);\n\n            if partial_ord_is_automatically_derived == ord_is_automatically_derived {\n                return;\n            }\n\n            let trait_ref = cx.tcx.impl_trait_ref(impl_id);\n\n            // Only care about `impl PartialOrd<Foo> for Foo`\n            // For `impl PartialOrd<B> for A, input_types is [A, B]\n            if trait_ref.instantiate_identity().args.type_at(1) == ty {\n                let mess = if partial_ord_is_automatically_derived {\n                    \"you are implementing `Ord` explicitly but have derived `PartialOrd`\"\n                } else {\n                    \"you are deriving `Ord` but have implemented `PartialOrd` explicitly\"\n                };\n\n                span_lint_hir_and_then(cx, DERIVE_ORD_XOR_PARTIAL_ORD, item_hir_id, item.span, mess, |diag| {\n                    if let Some(local_def_id) = impl_id.as_local() {\n                        let hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id);\n                        diag.span_note(cx.tcx.hir_span(hir_id), \"`PartialOrd` implemented here\");\n                    }\n                });\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/derive/derive_partial_eq_without_eq.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::has_non_exhaustive_attr;\nuse clippy_utils::ty::implements_trait_with_env;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{self as hir, HirId};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, ClauseKind, GenericParamDefKind, ParamEnv, TraitPredicate, Ty, TyCtxt, Upcast};\nuse rustc_span::{Span, sym};\n\nuse super::DERIVE_PARTIAL_EQ_WITHOUT_EQ;\n\n/// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    span: Span,\n    trait_ref: &hir::TraitRef<'_>,\n    ty: Ty<'tcx>,\n    adt_hir_id: HirId,\n) {\n    if let ty::Adt(adt, args) = ty.kind()\n        && cx.tcx.visibility(adt.did()).is_public()\n        && let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq)\n        && let Some(def_id) = trait_ref.trait_def_id()\n        && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)\n        && !has_non_exhaustive_attr(cx.tcx, *adt)\n        && !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id)\n        && let typing_env = typing_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)\n        // If all of our fields implement `Eq`, we can implement `Eq` too\n        && adt\n            .all_fields()\n            .map(|f| f.ty(cx.tcx, args))\n            .all(|ty| implements_trait_with_env(cx.tcx, typing_env, ty, eq_trait_def_id, None, &[]))\n    {\n        span_lint_hir_and_then(\n            cx,\n            DERIVE_PARTIAL_EQ_WITHOUT_EQ,\n            adt_hir_id,\n            span.ctxt().outer_expn_data().call_site,\n            \"you are deriving `PartialEq` and can implement `Eq`\",\n            |diag| {\n                diag.span_suggestion(\n                    span.ctxt().outer_expn_data().call_site,\n                    \"consider deriving `Eq` as well\",\n                    \"PartialEq, Eq\",\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n\nfn ty_implements_eq_trait<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, eq_trait_id: DefId) -> bool {\n    tcx.non_blanket_impls_for_ty(eq_trait_id, ty).next().is_some()\n}\n\n/// Creates the `ParamEnv` used for the given type's derived `Eq` impl.\nfn typing_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ty::TypingEnv<'_> {\n    // Initial map from generic index to param def.\n    // Vec<(param_def, needs_eq)>\n    let mut params = tcx\n        .generics_of(did)\n        .own_params\n        .iter()\n        .map(|p| (p, matches!(p.kind, GenericParamDefKind::Type { .. })))\n        .collect::<Vec<_>>();\n\n    let ty_predicates = tcx.predicates_of(did).predicates;\n    for (p, _) in ty_predicates {\n        if let ClauseKind::Trait(p) = p.kind().skip_binder()\n            && p.trait_ref.def_id == eq_trait_id\n            && let ty::Param(self_ty) = p.trait_ref.self_ty().kind()\n        {\n            // Flag types which already have an `Eq` bound.\n            params[self_ty.index as usize].1 = false;\n        }\n    }\n\n    let param_env = ParamEnv::new(tcx.mk_clauses_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain(\n        params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {\n            ClauseKind::Trait(TraitPredicate {\n                trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),\n                polarity: ty::PredicatePolarity::Positive,\n            })\n            .upcast(tcx)\n        }),\n    )));\n    ty::TypingEnv {\n        typing_mode: ty::TypingMode::non_body_analysis(),\n        param_env,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/derive/derived_hash_with_manual_eq.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse rustc_hir::{HirId, TraitRef};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::{Span, sym};\n\nuse super::DERIVED_HASH_WITH_MANUAL_EQ;\n\n/// Implementation of the `DERIVED_HASH_WITH_MANUAL_EQ` lint.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    span: Span,\n    trait_ref: &TraitRef<'_>,\n    ty: Ty<'tcx>,\n    adt_hir_id: HirId,\n    hash_is_automatically_derived: bool,\n) {\n    if let Some(peq_trait_def_id) = cx.tcx.lang_items().eq_trait()\n        && let Some(def_id) = trait_ref.trait_def_id()\n        && cx.tcx.is_diagnostic_item(sym::Hash, def_id)\n    {\n        // Look for the PartialEq implementations for `ty`\n        cx.tcx.for_each_relevant_impl(peq_trait_def_id, ty, |impl_id| {\n            let peq_is_automatically_derived = cx.tcx.is_automatically_derived(impl_id);\n\n            if !hash_is_automatically_derived || peq_is_automatically_derived {\n                return;\n            }\n\n            let trait_ref = cx.tcx.impl_trait_ref(impl_id);\n\n            // Only care about `impl PartialEq<Foo> for Foo`\n            // For `impl PartialEq<B> for A, input_types is [A, B]\n            if trait_ref.instantiate_identity().args.type_at(1) == ty {\n                span_lint_hir_and_then(\n                    cx,\n                    DERIVED_HASH_WITH_MANUAL_EQ,\n                    adt_hir_id,\n                    span,\n                    \"you are deriving `Hash` but have implemented `PartialEq` explicitly\",\n                    |diag| {\n                        if let Some(local_def_id) = impl_id.as_local() {\n                            let hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id);\n                            diag.span_note(cx.tcx.hir_span(hir_id), \"`PartialEq` implemented here\");\n                        }\n                    },\n                );\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/derive/expl_impl_clone_on_copy.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::fulfill_or_allowed;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse rustc_hir::{self as hir, HirId, Item};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, GenericArgKind, Ty};\n\nuse super::EXPL_IMPL_CLONE_ON_COPY;\n\n/// Implementation of the `EXPL_IMPL_CLONE_ON_COPY` lint.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &Item<'_>,\n    trait_ref: &hir::TraitRef<'_>,\n    ty: Ty<'tcx>,\n    adt_hir_id: HirId,\n) {\n    let clone_id = match cx.tcx.lang_items().clone_trait() {\n        Some(id) if trait_ref.trait_def_id() == Some(id) => id,\n        _ => return,\n    };\n    let Some(copy_id) = cx.tcx.lang_items().copy_trait() else {\n        return;\n    };\n    let (ty_adt, ty_subs) = match *ty.kind() {\n        // Unions can't derive clone.\n        ty::Adt(adt, subs) if !adt.is_union() => (adt, subs),\n        _ => return,\n    };\n    // If the current self type doesn't implement Copy (due to generic constraints), search to see if\n    // there's a Copy impl for any instance of the adt.\n    if !is_copy(cx, ty) {\n        if ty_subs.non_erasable_generics().next().is_some() {\n            let has_copy_impl = cx.tcx.local_trait_impls(copy_id).iter().any(|&id| {\n                matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _)\n                                        if ty_adt.did() == adt.did())\n            });\n            if !has_copy_impl {\n                return;\n            }\n        } else {\n            return;\n        }\n    }\n    // Derive constrains all generic types to requiring Clone. Check if any type is not constrained for\n    // this impl.\n    if ty_subs.types().any(|ty| !implements_trait(cx, ty, clone_id, &[])) {\n        return;\n    }\n    // `#[repr(packed)]` structs with type/const parameters can't derive `Clone`.\n    // https://github.com/rust-lang/rust-clippy/issues/10188\n    if ty_adt.repr().packed()\n        && ty_subs\n            .iter()\n            .any(|arg| matches!(arg.kind(), GenericArgKind::Type(_) | GenericArgKind::Const(_)))\n    {\n        return;\n    }\n    // The presence of `unsafe` fields prevents deriving `Clone` automatically\n    if ty_adt.all_fields().any(|f| f.safety.is_unsafe()) {\n        return;\n    }\n\n    if fulfill_or_allowed(cx, EXPL_IMPL_CLONE_ON_COPY, [adt_hir_id]) {\n        return;\n    }\n\n    span_lint_and_help(\n        cx,\n        EXPL_IMPL_CLONE_ON_COPY,\n        item.span,\n        \"you are implementing `Clone` explicitly on a `Copy` type\",\n        None,\n        \"consider deriving `Clone` or removing `Copy`\",\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/derive/mod.rs",
    "content": "use clippy_utils::res::MaybeResPath;\nuse rustc_hir::def::Res;\nuse rustc_hir::{Impl, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\nmod derive_ord_xor_partial_ord;\nmod derive_partial_eq_without_eq;\nmod derived_hash_with_manual_eq;\nmod expl_impl_clone_on_copy;\nmod unsafe_derive_deserialize;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints against manual `PartialOrd` and `Ord` implementations for types with a derived `Ord`\n    /// or `PartialOrd` implementation.\n    ///\n    /// ### Why is this bad?\n    /// The implementation of these traits must agree (for\n    /// example for use with `sort`) so it’s probably a bad idea to use a\n    /// default-generated `Ord` implementation with an explicitly defined\n    /// `PartialOrd`. In particular, the following must hold for any type\n    /// implementing `Ord`:\n    ///\n    /// ```text\n    /// k1.cmp(&k2) == k1.partial_cmp(&k2).unwrap()\n    /// ```\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// #[derive(Ord, PartialEq, Eq)]\n    /// struct Foo;\n    ///\n    /// impl PartialOrd for Foo {\n    ///     ...\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// #[derive(PartialEq, Eq)]\n    /// struct Foo;\n    ///\n    /// impl PartialOrd for Foo {\n    ///     fn partial_cmp(&self, other: &Foo) -> Option<Ordering> {\n    ///        Some(self.cmp(other))\n    ///     }\n    /// }\n    ///\n    /// impl Ord for Foo {\n    ///     ...\n    /// }\n    /// ```\n    /// or, if you don't need a custom ordering:\n    /// ```rust,ignore\n    /// #[derive(Ord, PartialOrd, PartialEq, Eq)]\n    /// struct Foo;\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub DERIVE_ORD_XOR_PARTIAL_ORD,\n    correctness,\n    \"deriving `Ord` but implementing `PartialOrd` explicitly\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for types that derive `PartialEq` and could implement `Eq`.\n    ///\n    /// ### Why is this bad?\n    /// If a type `T` derives `PartialEq` and all of its members implement `Eq`,\n    /// then `T` can always implement `Eq`. Implementing `Eq` allows `T` to be used\n    /// in APIs that require `Eq` types. It also allows structs containing `T` to derive\n    /// `Eq` themselves.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[derive(PartialEq)]\n    /// struct Foo {\n    ///     i_am_eq: i32,\n    ///     i_am_eq_too: Vec<String>,\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[derive(PartialEq, Eq)]\n    /// struct Foo {\n    ///     i_am_eq: i32,\n    ///     i_am_eq_too: Vec<String>,\n    /// }\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub DERIVE_PARTIAL_EQ_WITHOUT_EQ,\n    nursery,\n    \"deriving `PartialEq` on a type that can implement `Eq`, without implementing `Eq`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints against manual `PartialEq` implementations for types with a derived `Hash`\n    /// implementation.\n    ///\n    /// ### Why is this bad?\n    /// The implementation of these traits must agree (for\n    /// example for use with `HashMap`) so it’s probably a bad idea to use a\n    /// default-generated `Hash` implementation with an explicitly defined\n    /// `PartialEq`. In particular, the following must hold for any type:\n    ///\n    /// ```text\n    /// k1 == k2 ⇒ hash(k1) == hash(k2)\n    /// ```\n    ///\n    /// ### Example\n    /// ```ignore\n    /// #[derive(Hash)]\n    /// struct Foo;\n    ///\n    /// impl PartialEq for Foo {\n    ///     ...\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DERIVED_HASH_WITH_MANUAL_EQ,\n    correctness,\n    \"deriving `Hash` but implementing `PartialEq` explicitly\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for explicit `Clone` implementations for `Copy`\n    /// types.\n    ///\n    /// ### Why is this bad?\n    /// To avoid surprising behavior, these traits should\n    /// agree and the behavior of `Copy` cannot be overridden. In almost all\n    /// situations a `Copy` type should have a `Clone` implementation that does\n    /// nothing more than copy the object, which is what `#[derive(Copy, Clone)]`\n    /// gets you.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// #[derive(Copy)]\n    /// struct Foo;\n    ///\n    /// impl Clone for Foo {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EXPL_IMPL_CLONE_ON_COPY,\n    pedantic,\n    \"implementing `Clone` explicitly on `Copy` types\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for deriving `serde::Deserialize` on a type that\n    /// has methods using `unsafe`.\n    ///\n    /// ### Why is this bad?\n    /// Deriving `serde::Deserialize` will create a constructor\n    /// that may violate invariants held by another constructor.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// use serde::Deserialize;\n    ///\n    /// #[derive(Deserialize)]\n    /// pub struct Foo {\n    ///     // ..\n    /// }\n    ///\n    /// impl Foo {\n    ///     pub fn new() -> Self {\n    ///         // setup here ..\n    ///     }\n    ///\n    ///     pub unsafe fn parts() -> (&str, &str) {\n    ///         // assumes invariants hold\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub UNSAFE_DERIVE_DESERIALIZE,\n    pedantic,\n    \"deriving `serde::Deserialize` on a type that has methods using `unsafe`\"\n}\n\ndeclare_lint_pass!(Derive => [\n    DERIVED_HASH_WITH_MANUAL_EQ,\n    DERIVE_ORD_XOR_PARTIAL_ORD,\n    DERIVE_PARTIAL_EQ_WITHOUT_EQ,\n    EXPL_IMPL_CLONE_ON_COPY,\n    UNSAFE_DERIVE_DESERIALIZE,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for Derive {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            self_ty,\n            ..\n        }) = item.kind\n            && let Res::Def(_, def_id) = *self_ty.basic_res()\n            && let Some(local_def_id) = def_id.as_local()\n        {\n            let adt_hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id);\n            let trait_ref = &of_trait.trait_ref;\n            let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();\n            let is_automatically_derived = cx.tcx.is_automatically_derived(item.owner_id.to_def_id());\n\n            derived_hash_with_manual_eq::check(cx, item.span, trait_ref, ty, adt_hir_id, is_automatically_derived);\n            derive_ord_xor_partial_ord::check(cx, item, trait_ref, ty, adt_hir_id, is_automatically_derived);\n\n            if is_automatically_derived {\n                unsafe_derive_deserialize::check(cx, item, trait_ref, ty, adt_hir_id);\n                derive_partial_eq_without_eq::check(cx, item.span, trait_ref, ty, adt_hir_id);\n            } else {\n                expl_impl_clone_on_copy::check(cx, item, trait_ref, ty, adt_hir_id);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/derive/unsafe_derive_deserialize.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::{is_lint_allowed, paths, sym};\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn, walk_item};\nuse rustc_hir::{self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, HirId, Item, UnsafeSource};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::Span;\n\nuse super::UNSAFE_DERIVE_DESERIALIZE;\n\n/// Implementation of the `UNSAFE_DERIVE_DESERIALIZE` lint.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &Item<'_>,\n    trait_ref: &hir::TraitRef<'_>,\n    ty: Ty<'tcx>,\n    adt_hir_id: HirId,\n) {\n    fn has_unsafe<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>) -> bool {\n        let mut visitor = UnsafeVisitor { cx };\n        walk_item(&mut visitor, item).is_break()\n    }\n\n    if let Some(trait_def_id) = trait_ref.trait_def_id()\n        && paths::SERDE_DESERIALIZE.matches(cx, trait_def_id)\n        && let ty::Adt(def, _) = ty.kind()\n        && !is_lint_allowed(cx, UNSAFE_DERIVE_DESERIALIZE, adt_hir_id)\n        && cx\n            .tcx\n            .inherent_impls(def.did())\n            .iter()\n            .map(|imp_did| cx.tcx.hir_expect_item(imp_did.expect_local()))\n            .any(|imp| has_unsafe(cx, imp))\n    {\n        span_lint_hir_and_then(\n            cx,\n            UNSAFE_DERIVE_DESERIALIZE,\n            adt_hir_id,\n            item.span,\n            \"you are deriving `serde::Deserialize` on a type that has methods using `unsafe`\",\n            |diag| {\n                diag.help(\n                    \"consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html\",\n                );\n            },\n        );\n    }\n}\n\nstruct UnsafeVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n}\n\nimpl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {\n    type Result = ControlFlow<()>;\n    type NestedFilter = nested_filter::All;\n\n    fn visit_fn(\n        &mut self,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        body_id: BodyId,\n        _: Span,\n        id: LocalDefId,\n    ) -> Self::Result {\n        if let Some(header) = kind.header()\n            && header.is_unsafe()\n        {\n            ControlFlow::Break(())\n        } else {\n            walk_fn(self, kind, decl, body_id, id)\n        }\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> Self::Result {\n        if let ExprKind::Block(block, _) = expr.kind\n            && block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)\n            && block\n                .span\n                .source_callee()\n                .and_then(|expr| expr.macro_def_id)\n                .is_none_or(|did| !self.cx.tcx.is_diagnostic_item(sym::pin_macro, did))\n        {\n            return ControlFlow::Break(());\n        }\n\n        walk_expr(self, expr)\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/disallowed_fields.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::{DisallowedPath, create_disallowed_map};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::paths::PathNS;\nuse clippy_utils::ty::get_field_def_id_by_name;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefIdMap;\nuse rustc_hir::{Expr, ExprKind, Pat, PatKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Denies the configured fields in clippy.toml\n    ///\n    /// Note: Even though this lint is warn-by-default, it will only trigger if\n    /// fields are defined in the clippy.toml file.\n    ///\n    /// ### Why is this bad?\n    /// Some fields are undesirable in certain contexts, and it's beneficial to\n    /// lint for them as needed.\n    ///\n    /// ### Example\n    /// An example clippy.toml configuration:\n    /// ```toml\n    /// # clippy.toml\n    /// disallowed-fields = [\n    ///     # Can use a string as the path of the disallowed field.\n    ///     \"std::ops::Range::start\",\n    ///     # Can also use an inline table with a `path` key.\n    ///     { path = \"std::ops::Range::start\" },\n    ///     # When using an inline table, can add a `reason` for why the field\n    ///     # is disallowed.\n    ///     { path = \"std::ops::Range::start\", reason = \"The start of the range is not used\" },\n    /// ]\n    /// ```\n    ///\n    /// ```rust\n    /// use std::ops::Range;\n    ///\n    /// let range = Range { start: 0, end: 1 };\n    /// println!(\"{}\", range.start); // `start` is disallowed in the config.\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust\n    /// use std::ops::Range;\n    ///\n    /// let range = Range { start: 0, end: 1 };\n    /// println!(\"{}\", range.end); // `end` is _not_ disallowed in the config.\n    /// ```\n    #[clippy::version = \"1.93.0\"]\n    pub DISALLOWED_FIELDS,\n    style,\n    \"declaration of a disallowed field use\"\n}\n\nimpl_lint_pass!(DisallowedFields => [DISALLOWED_FIELDS]);\n\npub struct DisallowedFields {\n    disallowed: DefIdMap<(&'static str, &'static DisallowedPath)>,\n}\n\nimpl DisallowedFields {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        let (disallowed, _) = create_disallowed_map(\n            tcx,\n            &conf.disallowed_fields,\n            PathNS::Field,\n            |def_kind| matches!(def_kind, DefKind::Field),\n            \"field\",\n            false,\n        );\n        Self { disallowed }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for DisallowedFields {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let (id, span) = match &expr.kind {\n            ExprKind::Path(path) if let Res::Def(_, id) = cx.qpath_res(path, expr.hir_id) => (id, expr.span),\n            ExprKind::Field(e, ident) => {\n                // Very round-about way to get the field `DefId` from the expr: first we get its\n                // parent `Ty`. Then we go through all its fields to find the one with the expected\n                // name and get the `DefId` from it.\n                if let Some(parent_ty) = cx.typeck_results().expr_ty_adjusted_opt(e)\n                    && let Some(field_def_id) = get_field_def_id_by_name(parent_ty, ident.name)\n                {\n                    (field_def_id, ident.span)\n                } else {\n                    return;\n                }\n            },\n            _ => return,\n        };\n        if let Some(&(path, disallowed_path)) = self.disallowed.get(&id) {\n            span_lint_and_then(\n                cx,\n                DISALLOWED_FIELDS,\n                span,\n                format!(\"use of a disallowed field `{path}`\"),\n                disallowed_path.diag_amendment(span),\n            );\n        }\n    }\n\n    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {\n        let PatKind::Struct(struct_path, pat_fields, _) = pat.kind else {\n            return;\n        };\n        match cx.typeck_results().qpath_res(&struct_path, pat.hir_id) {\n            Res::Def(DefKind::Struct, struct_def_id) => {\n                let adt_def = cx.tcx.adt_def(struct_def_id);\n                for field in pat_fields {\n                    if let Some(def_id) = adt_def.all_fields().find_map(|adt_field| {\n                        if field.ident.name == adt_field.name {\n                            Some(adt_field.did)\n                        } else {\n                            None\n                        }\n                    }) && let Some(&(path, disallowed_path)) = self.disallowed.get(&def_id)\n                    {\n                        span_lint_and_then(\n                            cx,\n                            DISALLOWED_FIELDS,\n                            field.span,\n                            format!(\"use of a disallowed field `{path}`\"),\n                            disallowed_path.diag_amendment(field.span),\n                        );\n                    }\n                }\n            },\n            Res::Def(DefKind::Variant, variant_def_id) => {\n                let enum_def_id = cx.tcx.parent(variant_def_id);\n                let variant = cx.tcx.adt_def(enum_def_id).variant_with_id(variant_def_id);\n\n                for field in pat_fields {\n                    if let Some(def_id) = variant.fields.iter().find_map(|adt_field| {\n                        if field.ident.name == adt_field.name {\n                            Some(adt_field.did)\n                        } else {\n                            None\n                        }\n                    }) && let Some(&(path, disallowed_path)) = self.disallowed.get(&def_id)\n                    {\n                        span_lint_and_then(\n                            cx,\n                            DISALLOWED_FIELDS,\n                            field.span,\n                            format!(\"use of a disallowed field `{path}`\"),\n                            disallowed_path.diag_amendment(field.span),\n                        );\n                    }\n                }\n            },\n            _ => {},\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/disallowed_macros.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::{DisallowedPath, create_disallowed_map};\nuse clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};\nuse clippy_utils::macros::macro_backtrace;\nuse clippy_utils::paths::PathNS;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::def::DefKind;\nuse rustc_hir::def_id::DefIdMap;\nuse rustc_hir::{\n    AmbigArg, Expr, ExprKind, ForeignItem, HirId, ImplItem, ImplItemImplKind, Item, ItemKind, OwnerId, Pat, Path, Stmt,\n    TraitItem, Ty,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{ExpnId, MacroKind, Span};\n\nuse crate::utils::attr_collector::AttrStorage;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Denies the configured macros in clippy.toml\n    ///\n    /// Note: Even though this lint is warn-by-default, it will only trigger if\n    /// macros are defined in the clippy.toml file.\n    ///\n    /// ### Why is this bad?\n    /// Some macros are undesirable in certain contexts, and it's beneficial to\n    /// lint for them as needed.\n    ///\n    /// ### Example\n    /// An example clippy.toml configuration:\n    /// ```toml\n    /// # clippy.toml\n    /// disallowed-macros = [\n    ///     # Can use a string as the path of the disallowed macro.\n    ///     \"std::print\",\n    ///     # Can also use an inline table with a `path` key.\n    ///     { path = \"std::println\" },\n    ///     # When using an inline table, can add a `reason` for why the macro\n    ///     # is disallowed.\n    ///     { path = \"serde::Serialize\", reason = \"no serializing\" },\n    ///     # This would normally error if the path is incorrect, but with `allow-invalid` = `true`,\n    ///     # it will be silently ignored\n    ///     { path = \"std::invalid_macro\", reason = \"use alternative instead\", allow-invalid = true }\n    /// ]\n    /// ```\n    /// ```no_run\n    /// use serde::Serialize;\n    ///\n    /// println!(\"warns\");\n    ///\n    /// // The diagnostic will contain the message \"no serializing\"\n    /// #[derive(Serialize)]\n    /// struct Data {\n    ///     name: String,\n    ///     value: usize,\n    /// }\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub DISALLOWED_MACROS,\n    style,\n    \"use of a disallowed macro\"\n}\n\nimpl_lint_pass!(DisallowedMacros => [DISALLOWED_MACROS]);\n\npub struct DisallowedMacros {\n    disallowed: DefIdMap<(&'static str, &'static DisallowedPath)>,\n    seen: FxHashSet<ExpnId>,\n    // Track the most recently seen node that can have a `derive` attribute.\n    // Needed to use the correct lint level.\n    derive_src: Option<OwnerId>,\n\n    // When a macro is disallowed in an early pass, it's stored\n    // and emitted during the late pass. This happens for attributes.\n    early_macro_cache: AttrStorage,\n}\n\nimpl DisallowedMacros {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf, early_macro_cache: AttrStorage) -> Self {\n        let (disallowed, _) = create_disallowed_map(\n            tcx,\n            &conf.disallowed_macros,\n            PathNS::Macro,\n            |def_kind| matches!(def_kind, DefKind::Macro(_)),\n            \"macro\",\n            false,\n        );\n        Self {\n            disallowed,\n            seen: FxHashSet::default(),\n            derive_src: None,\n            early_macro_cache,\n        }\n    }\n\n    fn check(&mut self, cx: &LateContext<'_>, span: Span, derive_src: Option<OwnerId>) {\n        if self.disallowed.is_empty() {\n            return;\n        }\n\n        for mac in macro_backtrace(span) {\n            if !self.seen.insert(mac.expn) {\n                return;\n            }\n\n            if let Some(&(path, disallowed_path)) = self.disallowed.get(&mac.def_id) {\n                let msg = format!(\"use of a disallowed macro `{path}`\");\n                let add_note = disallowed_path.diag_amendment(mac.span);\n                if matches!(mac.kind, MacroKind::Derive)\n                    && let Some(derive_src) = derive_src\n                {\n                    span_lint_hir_and_then(\n                        cx,\n                        DISALLOWED_MACROS,\n                        cx.tcx.local_def_id_to_hir_id(derive_src.def_id),\n                        mac.span,\n                        msg,\n                        add_note,\n                    );\n                } else {\n                    span_lint_and_then(cx, DISALLOWED_MACROS, mac.span, msg, add_note);\n                }\n            }\n        }\n    }\n}\n\nimpl LateLintPass<'_> for DisallowedMacros {\n    fn check_crate(&mut self, cx: &LateContext<'_>) {\n        // once we check a crate in the late pass we can emit the early pass lints\n        if let Some(attr_spans) = self.early_macro_cache.clone().0.get() {\n            for span in attr_spans {\n                self.check(cx, *span, None);\n            }\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        self.check(cx, expr.span, None);\n        // `$t + $t` can have the context of $t, check also the span of the binary operator\n        if let ExprKind::Binary(op, ..) = expr.kind {\n            self.check(cx, op.span, None);\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {\n        self.check(cx, stmt.span, None);\n    }\n\n    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &Ty<'_, AmbigArg>) {\n        self.check(cx, ty.span, None);\n    }\n\n    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {\n        self.check(cx, pat.span, None);\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        self.check(cx, item.span, self.derive_src);\n        self.check(cx, item.vis_span, None);\n\n        if matches!(\n            item.kind,\n            ItemKind::Struct(..) | ItemKind::Enum(..) | ItemKind::Union(..)\n        ) && macro_backtrace(item.span).all(|m| !matches!(m.kind, MacroKind::Derive))\n        {\n            self.derive_src = Some(item.owner_id);\n        }\n    }\n\n    fn check_foreign_item(&mut self, cx: &LateContext<'_>, item: &ForeignItem<'_>) {\n        self.check(cx, item.span, None);\n        self.check(cx, item.vis_span, None);\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &ImplItem<'_>) {\n        self.check(cx, item.span, None);\n        if let ImplItemImplKind::Inherent { vis_span, .. } = item.impl_kind {\n            self.check(cx, vis_span, None);\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {\n        self.check(cx, item.span, None);\n    }\n\n    fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, _: HirId) {\n        self.check(cx, path.span, None);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/disallowed_methods.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::{DisallowedPath, create_disallowed_map};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::paths::PathNS;\nuse rustc_hir::def::{CtorKind, DefKind, Res};\nuse rustc_hir::def_id::DefIdMap;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Denies the configured methods and functions in clippy.toml\n    ///\n    /// Note: Even though this lint is warn-by-default, it will only trigger if\n    /// methods are defined in the clippy.toml file.\n    ///\n    /// ### Why is this bad?\n    /// Some methods are undesirable in certain contexts, and it's beneficial to\n    /// lint for them as needed.\n    ///\n    /// ### Example\n    /// An example clippy.toml configuration:\n    /// ```toml\n    /// # clippy.toml\n    /// disallowed-methods = [\n    ///     # Can use a string as the path of the disallowed method.\n    ///     \"std::boxed::Box::new\",\n    ///     # Can also use an inline table with a `path` key.\n    ///     { path = \"std::time::Instant::now\" },\n    ///     # When using an inline table, can add a `reason` for why the method\n    ///     # is disallowed.\n    ///     { path = \"std::vec::Vec::leak\", reason = \"no leaking memory\" },\n    ///     # Can also add a `replacement` that will be offered as a suggestion.\n    ///     { path = \"std::sync::Mutex::new\", reason = \"prefer faster & simpler non-poisonable mutex\", replacement = \"parking_lot::Mutex::new\" },\n    ///     # This would normally error if the path is incorrect, but with `allow-invalid` = `true`,\n    ///     # it will be silently ignored\n    ///     { path = \"std::fs::InvalidPath\", reason = \"use alternative instead\", allow-invalid = true },\n    /// ]\n    /// ```\n    ///\n    /// ```rust,ignore\n    /// let xs = vec![1, 2, 3, 4];\n    /// xs.leak(); // Vec::leak is disallowed in the config.\n    /// // The diagnostic contains the message \"no leaking memory\".\n    ///\n    /// let _now = Instant::now(); // Instant::now is disallowed in the config.\n    ///\n    /// let _box = Box::new(3); // Box::new is disallowed in the config.\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.\n    /// xs.push(123); // Vec::push is _not_ disallowed in the config.\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub DISALLOWED_METHODS,\n    style,\n    \"use of a disallowed method call\"\n}\n\nimpl_lint_pass!(DisallowedMethods => [DISALLOWED_METHODS]);\n\npub struct DisallowedMethods {\n    disallowed: DefIdMap<(&'static str, &'static DisallowedPath)>,\n}\n\nimpl DisallowedMethods {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        let (disallowed, _) = create_disallowed_map(\n            tcx,\n            &conf.disallowed_methods,\n            PathNS::Value,\n            |def_kind| {\n                matches!(\n                    def_kind,\n                    DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::AssocFn\n                )\n            },\n            \"function\",\n            false,\n        );\n        Self { disallowed }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for DisallowedMethods {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if expr.span.desugaring_kind().is_some() {\n            return;\n        }\n        let (id, span) = match &expr.kind {\n            ExprKind::Path(path) if let Res::Def(_, id) = cx.qpath_res(path, expr.hir_id) => (id, expr.span),\n            ExprKind::MethodCall(name, ..) if let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => {\n                (id, name.ident.span)\n            },\n            _ => return,\n        };\n        if let Some(&(path, disallowed_path)) = self.disallowed.get(&id) {\n            span_lint_and_then(\n                cx,\n                DISALLOWED_METHODS,\n                span,\n                format!(\"use of a disallowed method `{path}`\"),\n                disallowed_path.diag_amendment(span),\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/disallowed_names.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::{is_from_proc_macro, is_in_test};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::{Pat, PatKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of disallowed names for variables, such\n    /// as `foo`.\n    ///\n    /// ### Why is this bad?\n    /// These names are usually placeholder names and should be\n    /// avoided.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let foo = 3.14;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DISALLOWED_NAMES,\n    style,\n    \"usage of a disallowed/placeholder name\"\n}\n\nimpl_lint_pass!(DisallowedNames => [DISALLOWED_NAMES]);\n\npub struct DisallowedNames {\n    disallow: FxHashSet<Symbol>,\n}\n\nimpl DisallowedNames {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            disallow: conf.disallowed_names.iter().map(|x| Symbol::intern(x)).collect(),\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for DisallowedNames {\n    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {\n        if let PatKind::Binding(.., ident, _) = pat.kind\n            && !ident.span.from_expansion()\n            && self.disallow.contains(&ident.name)\n            && !is_in_test(cx.tcx, pat.hir_id)\n            && !is_from_proc_macro(cx, &ident)\n        {\n            span_lint(\n                cx,\n                DISALLOWED_NAMES,\n                ident.span,\n                format!(\"use of a disallowed/placeholder name `{}`\", ident.name),\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/disallowed_script_idents.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_ast::ast;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};\nuse rustc_session::impl_lint_pass;\nuse unicode_script::{Script, UnicodeScript};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of unicode scripts other than those explicitly allowed\n    /// by the lint config.\n    ///\n    /// This lint doesn't take into account non-text scripts such as `Unknown` and `Linear_A`.\n    /// It also ignores the `Common` script type.\n    /// While configuring, be sure to use official script name [aliases] from\n    /// [the list of supported scripts][supported_scripts].\n    ///\n    /// See also: [`non_ascii_idents`].\n    ///\n    /// [aliases]: http://www.unicode.org/reports/tr24/tr24-31.html#Script_Value_Aliases\n    /// [supported_scripts]: https://www.unicode.org/iso15924/iso15924-codes.html\n    ///\n    /// ### Why restrict this?\n    /// It may be not desired to have many different scripts for\n    /// identifiers in the codebase.\n    ///\n    /// Note that if you only want to allow typical English, you might want to use\n    /// built-in [`non_ascii_idents`] lint instead.\n    ///\n    /// [`non_ascii_idents`]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#non-ascii-idents\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // Assuming that `clippy.toml` contains the following line:\n    /// // allowed-scripts = [\"Latin\", \"Cyrillic\"]\n    /// let counter = 10; // OK, latin is allowed.\n    /// let счётчик = 10; // OK, cyrillic is allowed.\n    /// let zähler = 10; // OK, it's still latin.\n    /// let カウンタ = 10; // Will spawn the lint.\n    /// ```\n    #[clippy::version = \"1.55.0\"]\n    pub DISALLOWED_SCRIPT_IDENTS,\n    restriction,\n    \"usage of non-allowed Unicode scripts\"\n}\n\nimpl_lint_pass!(DisallowedScriptIdents => [DISALLOWED_SCRIPT_IDENTS]);\n\npub struct DisallowedScriptIdents {\n    whitelist: FxHashSet<Script>,\n}\n\nimpl DisallowedScriptIdents {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            whitelist: conf\n                .allowed_scripts\n                .iter()\n                .map(String::as_str)\n                .filter_map(Script::from_full_name)\n                .collect(),\n        }\n    }\n}\n\nimpl EarlyLintPass for DisallowedScriptIdents {\n    fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {\n        // Implementation is heavily inspired by the implementation of [`non_ascii_idents`] lint:\n        // https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_lint/src/non_ascii_idents.rs\n\n        let check_disallowed_script_idents = cx.builder.lint_level(DISALLOWED_SCRIPT_IDENTS).level != Level::Allow;\n        if !check_disallowed_script_idents {\n            return;\n        }\n\n        let symbols = cx.sess().psess.symbol_gallery.symbols.lock();\n        // Sort by `Span` so that error messages make sense with respect to the\n        // order of identifier locations in the code.\n        let mut symbols: Vec<_> = symbols.iter().collect();\n        symbols.sort_unstable_by_key(|k| k.1);\n\n        for &(symbol, &span) in &symbols {\n            // Note: `symbol.as_str()` is an expensive operation, thus should not be called\n            // more than once for a single symbol.\n            let symbol_str = symbol.as_str();\n\n            // Check if any character in the symbol is not part of any allowed script.\n            // Fast path for ascii-only idents.\n            if !symbol_str.is_ascii()\n                && let Some(script) = symbol_str.chars().find_map(|c| {\n                    if c.is_ascii() {\n                        return None;\n                    }\n\n                    c.script_extension()\n                        .iter()\n                        .find(|script| !self.whitelist.contains(script))\n                })\n            {\n                span_lint(\n                    cx,\n                    DISALLOWED_SCRIPT_IDENTS,\n                    span,\n                    format!(\n                        \"identifier `{symbol_str}` has a Unicode script that is not allowed by configuration: {}\",\n                        script.full_name()\n                    ),\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/disallowed_types.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::{DisallowedPath, create_disallowed_map};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::paths::PathNS;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefIdMap;\nuse rustc_hir::{AmbigArg, Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Denies the configured types in clippy.toml.\n    ///\n    /// Note: Even though this lint is warn-by-default, it will only trigger if\n    /// types are defined in the clippy.toml file.\n    ///\n    /// ### Why is this bad?\n    /// Some types are undesirable in certain contexts.\n    ///\n    /// ### Example:\n    /// An example clippy.toml configuration:\n    /// ```toml\n    /// # clippy.toml\n    /// disallowed-types = [\n    ///     # Can use a string as the path of the disallowed type.\n    ///     \"std::collections::BTreeMap\",\n    ///     # Can also use an inline table with a `path` key.\n    ///     { path = \"std::net::TcpListener\" },\n    ///     # When using an inline table, can add a `reason` for why the type\n    ///     # is disallowed.\n    ///     { path = \"std::net::Ipv4Addr\", reason = \"no IPv4 allowed\" },\n    ///     # Can also add a `replacement` that will be offered as a suggestion.\n    ///     { path = \"std::sync::Mutex\", reason = \"prefer faster & simpler non-poisonable mutex\", replacement = \"parking_lot::Mutex\" },\n    ///     # This would normally error if the path is incorrect, but with `allow-invalid` = `true`,\n    ///     # it will be silently ignored\n    ///     { path = \"std::invalid::Type\", reason = \"use alternative instead\", allow-invalid = true }\n    /// ]\n    /// ```\n    ///\n    /// ```rust,ignore\n    /// use std::collections::BTreeMap;\n    /// // or its use\n    /// let x = std::collections::BTreeMap::new();\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// // A similar type that is allowed by the config\n    /// use std::collections::HashMap;\n    /// ```\n    #[clippy::version = \"1.55.0\"]\n    pub DISALLOWED_TYPES,\n    style,\n    \"use of disallowed types\"\n}\n\nimpl_lint_pass!(DisallowedTypes => [DISALLOWED_TYPES]);\n\npub struct DisallowedTypes {\n    def_ids: DefIdMap<(&'static str, &'static DisallowedPath)>,\n    prim_tys: FxHashMap<PrimTy, (&'static str, &'static DisallowedPath)>,\n}\n\nimpl DisallowedTypes {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        let (def_ids, prim_tys) = create_disallowed_map(\n            tcx,\n            &conf.disallowed_types,\n            PathNS::Type,\n            def_kind_predicate,\n            \"type\",\n            true,\n        );\n        Self { def_ids, prim_tys }\n    }\n\n    fn check_res_emit(&self, cx: &LateContext<'_>, res: &Res, span: Span) {\n        let (path, disallowed_path) = match res {\n            Res::Def(_, did) if let Some(&x) = self.def_ids.get(did) => x,\n            Res::PrimTy(prim) if let Some(&x) = self.prim_tys.get(prim) => x,\n            _ => return,\n        };\n        span_lint_and_then(\n            cx,\n            DISALLOWED_TYPES,\n            span,\n            format!(\"use of a disallowed type `{path}`\"),\n            disallowed_path.diag_amendment(span),\n        );\n    }\n}\n\npub fn def_kind_predicate(def_kind: DefKind) -> bool {\n    matches!(\n        def_kind,\n        DefKind::Struct\n            | DefKind::Union\n            | DefKind::Enum\n            | DefKind::Trait\n            | DefKind::TyAlias\n            | DefKind::ForeignTy\n            | DefKind::AssocTy\n    )\n}\n\nimpl<'tcx> LateLintPass<'tcx> for DisallowedTypes {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if let ItemKind::Use(path, UseKind::Single(_)) = &item.kind\n            && let Some(res) = path.res.type_ns\n        {\n            self.check_res_emit(cx, &res, item.span);\n        }\n    }\n\n    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx, AmbigArg>) {\n        if let TyKind::Path(path) = &ty.kind {\n            self.check_res_emit(cx, &cx.qpath_res(path, ty.hir_id), ty.span);\n        }\n    }\n\n    fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>) {\n        self.check_res_emit(cx, &poly.trait_ref.path.res, poly.trait_ref.path.span);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/broken_link.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_lint::LateContext;\nuse rustc_resolve::rustdoc::pulldown_cmark::BrokenLink as PullDownBrokenLink;\nuse rustc_resolve::rustdoc::{DocFragment, source_span_for_markdown_range};\nuse rustc_span::{BytePos, Pos, Span};\n\nuse super::DOC_BROKEN_LINK;\n\n/// Scan and report broken link on documents.\n/// It ignores false positives detected by `pulldown_cmark`, and only\n/// warns users when the broken link is consider a URL.\n// NOTE: We don't check these other cases because\n// rustdoc itself will check and warn about it:\n// - When a link url is broken across multiple lines in the URL path part\n// - When a link tag is missing the close parenthesis character at the end.\n// - When a link has whitespace within the url link.\npub fn check(cx: &LateContext<'_>, bl: &PullDownBrokenLink<'_>, doc: &str, fragments: &[DocFragment]) {\n    warn_if_broken_link(cx, bl, doc, fragments);\n}\n\nfn warn_if_broken_link(cx: &LateContext<'_>, bl: &PullDownBrokenLink<'_>, doc: &str, fragments: &[DocFragment]) {\n    let mut len = 0;\n\n    // grab raw link data\n    let (_, raw_link) = doc.split_at(bl.span.start);\n\n    // strip off link text part\n    let raw_link = match raw_link.split_once(']') {\n        None => return,\n        Some((prefix, suffix)) => {\n            len += prefix.len() + 1;\n            suffix\n        },\n    };\n\n    let raw_link = match raw_link.split_once('(') {\n        None => return,\n        Some((prefix, suffix)) => {\n            if !prefix.is_empty() {\n                // there is text between ']' and '(' chars, so it is not a valid link\n                return;\n            }\n            len += prefix.len() + 1;\n            suffix\n        },\n    };\n\n    if raw_link.starts_with(\"(http\") {\n        // reduce chances of false positive reports\n        // by limiting this checking only to http/https links.\n        return;\n    }\n\n    for c in raw_link.chars() {\n        if c == ')' {\n            // it is a valid link\n            return;\n        }\n\n        if c == '\\n'\n            && let Some((span, _)) = source_span_for_markdown_range(cx.tcx, doc, &bl.span, fragments)\n        {\n            report_broken_link(cx, span, len);\n            break;\n        }\n\n        len += 1;\n    }\n}\n\nfn report_broken_link(cx: &LateContext<'_>, frag_span: Span, offset: usize) {\n    let start = frag_span.lo();\n    let end = start + BytePos::from_usize(offset);\n\n    let span = Span::new(start, end, frag_span.ctxt(), frag_span.parent());\n\n    span_lint(\n        cx,\n        DOC_BROKEN_LINK,\n        span,\n        \"possible broken doc link: broken across multiple lines\",\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/doc_comment_double_space_linebreaks.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_errors::Applicability;\nuse rustc_lint::LateContext;\nuse rustc_span::{BytePos, Span};\n\nuse super::DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS;\n\npub fn check(cx: &LateContext<'_>, collected_breaks: &[Span]) {\n    if collected_breaks.is_empty() {\n        return;\n    }\n\n    let breaks: Vec<_> = collected_breaks\n        .iter()\n        .map(|span| span.with_hi(span.lo() + BytePos(2)))\n        .collect();\n\n    span_lint_and_then(\n        cx,\n        DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS,\n        breaks.clone(),\n        \"doc comment uses two spaces for a hard line break\",\n        |diag| {\n            let suggs: Vec<_> = breaks.iter().map(|span| (*span, \"\\\\\".to_string())).collect();\n            diag.tool_only_multipart_suggestion(\n                \"replace this double space with a backslash:\",\n                suggs,\n                Applicability::MachineApplicable,\n            );\n            diag.help(\"replace this double space with a backslash: `\\\\`\");\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/doc_paragraphs_missing_punctuation.rs",
    "content": "use rustc_errors::Applicability;\nuse rustc_lint::LateContext;\nuse rustc_resolve::rustdoc::main_body_opts;\n\nuse rustc_resolve::rustdoc::pulldown_cmark::{Event, Options, Parser, Tag, TagEnd};\n\nuse super::{DOC_PARAGRAPHS_MISSING_PUNCTUATION, Fragments};\n\nconst MSG: &str = \"doc paragraphs should end with a terminal punctuation mark\";\nconst PUNCTUATION_SUGGESTION: char = '.';\n\npub fn check(cx: &LateContext<'_>, doc: &str, fragments: Fragments<'_>) {\n    for missing_punctuation in is_missing_punctuation(doc) {\n        match missing_punctuation {\n            MissingPunctuation::Fixable(offset) => {\n                // This ignores `#[doc]` attributes, which we do not handle.\n                if let Some(span) = fragments.span(cx, offset..offset) {\n                    clippy_utils::diagnostics::span_lint_and_sugg(\n                        cx,\n                        DOC_PARAGRAPHS_MISSING_PUNCTUATION,\n                        span,\n                        MSG,\n                        \"end the paragraph with some punctuation\",\n                        PUNCTUATION_SUGGESTION.to_string(),\n                        Applicability::MaybeIncorrect,\n                    );\n                }\n            },\n            MissingPunctuation::Unfixable(offset) => {\n                // This ignores `#[doc]` attributes, which we do not handle.\n                if let Some(span) = fragments.span(cx, offset..offset) {\n                    clippy_utils::diagnostics::span_lint_and_help(\n                        cx,\n                        DOC_PARAGRAPHS_MISSING_PUNCTUATION,\n                        span,\n                        MSG,\n                        None,\n                        \"end the paragraph with some punctuation\",\n                    );\n                }\n            },\n        }\n    }\n}\n\n#[must_use]\n/// If punctuation is missing, returns the offset where new punctuation should be inserted.\nfn is_missing_punctuation(doc_string: &str) -> Vec<MissingPunctuation> {\n    // The colon is not exactly a terminal punctuation mark, but this is required for paragraphs that\n    // introduce a table or a list for example.\n    const TERMINAL_PUNCTUATION_MARKS: &[char] = &['.', '?', '!', '…', ':'];\n\n    let mut no_report_depth = 0;\n    let mut missing_punctuation = Vec::new();\n    let mut current_paragraph = None;\n    let mut current_event_is_missing_punctuation = false;\n\n    for (event, offset) in\n        Parser::new_ext(doc_string, main_body_opts() - Options::ENABLE_SMART_PUNCTUATION).into_offset_iter()\n    {\n        let last_event_was_missing_punctuation = current_event_is_missing_punctuation;\n        current_event_is_missing_punctuation = false;\n\n        match event {\n            Event::Start(Tag::FootnoteDefinition(_) | Tag::Heading { .. } | Tag::HtmlBlock | Tag::Table(_)) => {\n                no_report_depth += 1;\n            },\n            Event::Start(Tag::CodeBlock(..) | Tag::List(..)) => {\n                no_report_depth += 1;\n                if last_event_was_missing_punctuation {\n                    // Remove the error from the previous paragraph as it is followed by a code\n                    // block or a list.\n                    missing_punctuation.pop();\n                }\n            },\n            Event::End(TagEnd::FootnoteDefinition) => {\n                no_report_depth -= 1;\n            },\n            Event::End(\n                TagEnd::CodeBlock | TagEnd::Heading(_) | TagEnd::HtmlBlock | TagEnd::List(_) | TagEnd::Table,\n            ) => {\n                no_report_depth -= 1;\n                current_paragraph = None;\n            },\n            Event::InlineHtml(_) | Event::Start(Tag::Image { .. }) | Event::End(TagEnd::Image) => {\n                current_paragraph = None;\n            },\n            Event::End(TagEnd::Paragraph) => {\n                if let Some(mp) = current_paragraph {\n                    missing_punctuation.push(mp);\n                    current_event_is_missing_punctuation = true;\n                }\n            },\n            Event::Code(..) | Event::Start(Tag::Link { .. }) | Event::End(TagEnd::Link)\n                if no_report_depth == 0 && !offset.is_empty() =>\n            {\n                if trim_trailing_symbols(&doc_string[..offset.end]).ends_with(TERMINAL_PUNCTUATION_MARKS) {\n                    current_paragraph = None;\n                } else {\n                    current_paragraph = Some(MissingPunctuation::Fixable(offset.end));\n                }\n            },\n            Event::Text(..) if no_report_depth == 0 && !offset.is_empty() => {\n                let trimmed = trim_trailing_symbols(&doc_string[..offset.end]);\n                if trimmed.ends_with(TERMINAL_PUNCTUATION_MARKS) {\n                    current_paragraph = None;\n                } else if let Some(t) = trimmed.strip_suffix(|c| c == ')' || c == '\"') {\n                    if t.ends_with(TERMINAL_PUNCTUATION_MARKS) {\n                        // Avoid false positives.\n                        current_paragraph = None;\n                    } else {\n                        current_paragraph = Some(MissingPunctuation::Unfixable(offset.end));\n                    }\n                } else {\n                    current_paragraph = Some(MissingPunctuation::Fixable(offset.end));\n                }\n            },\n            _ => {},\n        }\n    }\n\n    missing_punctuation\n}\n\nfn trim_trailing_symbols(s: &str) -> &str {\n    s.trim_end_matches(|c: char|\n        // Source: https://unicodeplus.com\n        matches!(c as u32,\n            0x1F300..=0x1F5FF | // Miscellaneous Symbols and Pictographs\n            0x1F600..=0x1F64F | // Emoticons\n            0x1F900..=0x1F9FF | // Supplemental Symbols and Pictographs\n            0x2700..=0x27BF   | // Dingbats\n            0x1FA70..=0x1FAFF | // Symbols and Pictographs Extended-A\n            0x1F680..=0x1F6FF | // Transport and Map Symbols\n            0x2600..=0x26FF | // Miscellaneous Symbols\n            0xFE00..=0xFE0F // Variation selectors\n        ) || c.is_whitespace())\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\nenum MissingPunctuation {\n    Fixable(usize),\n    Unfixable(usize),\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/doc_suspicious_footnotes.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::attr::AttributeExt as _;\nuse rustc_ast::token::{CommentKind, DocFragmentKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::attrs::AttributeKind;\nuse rustc_hir::{AttrStyle, Attribute};\nuse rustc_lint::{LateContext, LintContext};\n\nuse std::ops::Range;\n\nuse super::{DOC_SUSPICIOUS_FOOTNOTES, Fragments};\n\npub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &Fragments<'_>, attrs: &[Attribute]) {\n    for i in doc[range.clone()]\n        .bytes()\n        .enumerate()\n        .filter_map(|(i, c)| if c == b'[' { Some(i) } else { None })\n    {\n        let start = i + range.start;\n        if doc.as_bytes().get(start + 1) == Some(&b'^')\n            && let Some(end) = all_numbers_upto_brace(doc, start + 2)\n            && doc.as_bytes().get(end) != Some(&b':')\n            && doc.as_bytes().get(start - 1) != Some(&b'\\\\')\n            && let Some(this_fragment) = {\n                // the `doc` string contains all fragments concatenated together\n                // figure out which one this suspicious footnote comes from\n                let mut starting_position = 0;\n                let mut found_fragment = fragments.fragments.last();\n                for fragment in fragments.fragments {\n                    if start >= starting_position && start < starting_position + fragment.doc.as_str().len() {\n                        found_fragment = Some(fragment);\n                        break;\n                    }\n                    starting_position += fragment.doc.as_str().len();\n                }\n                found_fragment\n            }\n        {\n            let span = fragments.span(cx, start..end).unwrap_or(this_fragment.span);\n            span_lint_and_then(\n                cx,\n                DOC_SUSPICIOUS_FOOTNOTES,\n                span,\n                \"looks like a footnote ref, but has no matching footnote\",\n                |diag| {\n                    if let DocFragmentKind::Sugared(_) = this_fragment.kind {\n                        let (doc_attr, doc_attr_comment_kind, attr_style) = attrs\n                            .iter()\n                            .filter(|attr| {\n                                matches!(\n                                    attr,\n                                    Attribute::Parsed(AttributeKind::DocComment { span, .. })\n                                    if span.overlaps(this_fragment.span),\n                                )\n                            })\n                            .rev()\n                            .find_map(|attr| {\n                                let (_, fragment) = attr.doc_str_and_fragment_kind()?;\n                                let fragment = match fragment {\n                                    DocFragmentKind::Sugared(kind) => kind,\n                                    DocFragmentKind::Raw(_) => CommentKind::Line,\n                                };\n                                Some((attr, fragment, attr.doc_resolution_scope()?))\n                            })\n                            .unwrap();\n                        let (to_add, terminator) = match (doc_attr_comment_kind, attr_style) {\n                            (CommentKind::Line, AttrStyle::Outer) => (\"\\n///\\n/// \", \"\"),\n                            (CommentKind::Line, AttrStyle::Inner) => (\"\\n//!\\n//! \", \"\"),\n                            (CommentKind::Block, AttrStyle::Outer) => (\"\\n/** \", \" */\"),\n                            (CommentKind::Block, AttrStyle::Inner) => (\"\\n/*! \", \" */\"),\n                        };\n                        diag.span_suggestion_verbose(\n                            doc_attr.span().shrink_to_hi(),\n                            \"add footnote definition\",\n                            format!(\n                                \"{to_add}{label}: <!-- description -->{terminator}\",\n                                label = &doc[start..end]\n                            ),\n                            Applicability::HasPlaceholders,\n                        );\n                    } else {\n                        let is_file_include = cx\n                            .sess()\n                            .source_map()\n                            .span_to_snippet(this_fragment.span)\n                            .as_ref()\n                            .map(|vdoc| vdoc.trim())\n                            == Ok(doc);\n                        if is_file_include {\n                            // if this is a file include, then there's no quote marks\n                            diag.span_suggestion_verbose(\n                                this_fragment.span.shrink_to_hi(),\n                                \"add footnote definition\",\n                                format!(\"\\n\\n{label}: <!-- description -->\", label = &doc[start..end]),\n                                Applicability::HasPlaceholders,\n                            );\n                        } else {\n                            // otherwise, we wrap in a string\n                            diag.span_suggestion_verbose(\n                                this_fragment.span,\n                                \"add footnote definition\",\n                                format!(\n                                    \"r#\\\"{doc}\\n\\n{label}: <!-- description -->\\\"#\",\n                                    doc = this_fragment.doc,\n                                    label = &doc[start..end],\n                                ),\n                                Applicability::HasPlaceholders,\n                            );\n                        }\n                    }\n                },\n            );\n        }\n    }\n}\n\nfn all_numbers_upto_brace(text: &str, i: usize) -> Option<usize> {\n    for (j, c) in text.as_bytes()[i..].iter().copied().enumerate().take(64) {\n        if c == b']' && j != 0 {\n            return Some(i + j + 1);\n        }\n        if !c.is_ascii_digit() || j >= 64 {\n            break;\n        }\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/include_in_doc_without_cfg.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_opt;\nuse rustc_ast::{AttrArgs, AttrItemKind, AttrKind, AttrStyle, Attribute};\nuse rustc_errors::Applicability;\nuse rustc_lint::EarlyContext;\n\nuse super::DOC_INCLUDE_WITHOUT_CFG;\n\npub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) {\n    for attr in attrs {\n        if !attr.span.from_expansion()\n            && let AttrKind::Normal(ref item) = attr.kind\n            && attr.doc_str().is_some()\n            && let AttrItemKind::Unparsed(AttrArgs::Eq { expr: meta, .. }) = &item.item.args\n            && !attr.span.contains(meta.span)\n            // Since the `include_str` is already expanded at this point, we can only take the\n            // whole attribute snippet and then modify for our suggestion.\n            && let Some(snippet) = snippet_opt(cx, attr.span)\n            // We cannot remove this because a `#[doc = include_str!(\"...\")]` attribute can occupy\n            // several lines.\n            && let Some(start) = snippet.find('[')\n            && let Some(end) = snippet.rfind(']')\n            && let snippet = &snippet[start + 1..end]\n            // We check that the expansion actually comes from `include_str!` and not just from\n            // another macro.\n            && let Some(sub_snippet) = snippet.trim().strip_prefix(\"doc\")\n            && let Some(sub_snippet) = sub_snippet.trim().strip_prefix(\"=\")\n            && sub_snippet.trim().starts_with(\"include_str!\")\n        {\n            span_lint_and_sugg(\n                cx,\n                DOC_INCLUDE_WITHOUT_CFG,\n                attr.span,\n                \"included a file in documentation unconditionally\",\n                \"use `cfg_attr(doc, doc = \\\"...\\\")`\",\n                format!(\n                    \"#{}[cfg_attr(doc, {snippet})]\",\n                    if attr.style == AttrStyle::Inner { \"!\" } else { \"\" }\n                ),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/lazy_continuation.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse itertools::Itertools;\nuse rustc_errors::Applicability;\nuse rustc_lint::LateContext;\nuse rustc_span::BytePos;\nuse std::ops::Range;\n\nuse super::{DOC_LAZY_CONTINUATION, DOC_OVERINDENTED_LIST_ITEMS, Fragments};\n\nfn map_container_to_text(c: &super::Container) -> &'static str {\n    match c {\n        super::Container::Blockquote => \"> \",\n        // numbered list can have up to nine digits, plus the dot, plus four spaces on either side\n        super::Container::List(indent) => &\"                  \"[0..*indent],\n    }\n}\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    doc: &str,\n    cooked_range: Range<usize>,\n    fragments: &Fragments<'_>,\n    containers: &[super::Container],\n) {\n    // Get blockquotes\n    let ccount = doc[cooked_range.clone()].chars().filter(|c| *c == '>').count();\n    let blockquote_level = containers\n        .iter()\n        .filter(|c| matches!(c, super::Container::Blockquote))\n        .count();\n\n    if ccount < blockquote_level\n        && let Some(mut span) = fragments.span(cx, cooked_range.clone())\n    {\n        span_lint_and_then(\n            cx,\n            DOC_LAZY_CONTINUATION,\n            span,\n            \"doc quote line without `>` marker\",\n            |diag| {\n                let mut doc_start_range = &doc[cooked_range];\n                let mut suggested = String::new();\n                for c in containers {\n                    let text = map_container_to_text(c);\n                    if doc_start_range.starts_with(text) {\n                        doc_start_range = &doc_start_range[text.len()..];\n                        span = span.with_lo(\n                            span.lo() + BytePos(u32::try_from(text.len()).expect(\"text is not 2**32 or bigger\")),\n                        );\n                    } else if matches!(c, super::Container::Blockquote)\n                        && let Some(i) = doc_start_range.find('>')\n                    {\n                        doc_start_range = &doc_start_range[i + 1..];\n                        span = span\n                            .with_lo(span.lo() + BytePos(u32::try_from(i).expect(\"text is not 2**32 or bigger\") + 1));\n                    } else {\n                        suggested.push_str(text);\n                    }\n                }\n                diag.span_suggestion_verbose(\n                    span,\n                    \"add markers to start of line\",\n                    suggested,\n                    Applicability::MachineApplicable,\n                );\n                diag.help(\"if this not intended to be a quote at all, escape it with `\\\\>`\");\n            },\n        );\n        return;\n    }\n\n    if ccount != 0 && blockquote_level != 0 {\n        // If this doc is a blockquote, we don't go further.\n        return;\n    }\n\n    // List\n    let leading_spaces = doc[cooked_range.clone()].chars().filter(|c| *c == ' ').count();\n    let list_indentation = containers\n        .iter()\n        .map(|c| {\n            if let super::Container::List(indent) = c {\n                *indent\n            } else {\n                0\n            }\n        })\n        .sum();\n\n    if leading_spaces != list_indentation\n        && let Some(span) = fragments.span(cx, cooked_range.clone())\n    {\n        if leading_spaces < list_indentation {\n            span_lint_and_then(\n                cx,\n                DOC_LAZY_CONTINUATION,\n                span,\n                \"doc list item without indentation\",\n                |diag| {\n                    // simpler suggestion style for indentation\n                    let indent = list_indentation - leading_spaces;\n                    diag.span_suggestion_verbose(\n                        span.shrink_to_hi(),\n                        \"indent this line\",\n                        std::iter::repeat_n(\" \", indent).join(\"\"),\n                        Applicability::MaybeIncorrect,\n                    );\n                    diag.help(\"if this is supposed to be its own paragraph, add a blank line\");\n                },\n            );\n\n            return;\n        }\n\n        let sugg = std::iter::repeat_n(\" \", list_indentation).join(\"\");\n        span_lint_and_sugg(\n            cx,\n            DOC_OVERINDENTED_LIST_ITEMS,\n            span,\n            \"doc list item overindented\",\n            format!(\"try using `{sugg}` ({list_indentation} spaces)\"),\n            sugg,\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/link_with_quotes.rs",
    "content": "use std::ops::Range;\n\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_lint::LateContext;\n\nuse super::{DOC_LINK_WITH_QUOTES, Fragments};\n\npub fn check(cx: &LateContext<'_>, trimmed_text: &str, range: Range<usize>, fragments: Fragments<'_>) {\n    if ((trimmed_text.starts_with('\\'') && trimmed_text.ends_with('\\''))\n        || (trimmed_text.starts_with('\"') && trimmed_text.ends_with('\"')))\n        && let Some(span) = fragments.span(cx, range)\n    {\n        span_lint(\n            cx,\n            DOC_LINK_WITH_QUOTES,\n            span,\n            \"possible intra-doc link using quotes instead of backticks\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/markdown.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_lint::LateContext;\nuse rustc_span::{BytePos, Pos, Span};\nuse url::Url;\n\nuse crate::doc::{DOC_MARKDOWN, Fragments};\nuse std::ops::Range;\n\npub fn check(\n    cx: &LateContext<'_>,\n    valid_idents: &FxHashSet<String>,\n    text: &str,\n    fragments: &Fragments<'_>,\n    fragment_range: Range<usize>,\n    code_level: isize,\n    blockquote_level: isize,\n) {\n    for orig_word in text.split(|c: char| c.is_whitespace() || c == '\\'') {\n        // Trim punctuation as in `some comment (see foo::bar).`\n        //                                                   ^^\n        // Or even as in `_foo bar_` which is emphasized. Also preserve `::` as a prefix/suffix.\n        let trim_pattern = |c: char| !c.is_alphanumeric() && c != ':';\n        let mut word = orig_word.trim_end_matches(trim_pattern);\n\n        // If word is immediately followed by `()`, claw it back.\n        if let Some(tmp_word) = orig_word.get(..word.len() + 2)\n            && tmp_word.ends_with(\"()\")\n        {\n            word = tmp_word;\n        }\n\n        let original_len = word.len();\n        word = word.trim_start_matches(trim_pattern);\n\n        // Remove leading or trailing single `:` which may be part of a sentence.\n        if word.starts_with(':') && !word.starts_with(\"::\") {\n            word = word.trim_start_matches(':');\n        }\n        if word.ends_with(':') && !word.ends_with(\"::\") {\n            word = word.trim_end_matches(':');\n        }\n\n        if valid_idents.contains(word) || word.chars().all(|c| c == ':') {\n            continue;\n        }\n\n        // Ensure that all reachable matching closing parens are included as well.\n        let size_diff = original_len - word.len();\n        let mut open_parens = 0;\n        let mut close_parens = 0;\n        for c in word.chars() {\n            if c == '(' {\n                open_parens += 1;\n            } else if c == ')' {\n                close_parens += 1;\n            }\n        }\n        while close_parens < open_parens\n            && let Some(tmp_word) = orig_word.get(size_diff..=(word.len() + size_diff))\n            && tmp_word.ends_with(')')\n        {\n            word = tmp_word;\n            close_parens += 1;\n        }\n\n        // We'll use this offset to calculate the span to lint.\n        let fragment_offset = word.as_ptr() as usize - text.as_ptr() as usize;\n\n        // Adjust for the current word\n        check_word(\n            cx,\n            word,\n            fragments,\n            &fragment_range,\n            fragment_offset,\n            code_level,\n            blockquote_level,\n        );\n    }\n}\n\nfn check_word(\n    cx: &LateContext<'_>,\n    word: &str,\n    fragments: &Fragments<'_>,\n    range: &Range<usize>,\n    fragment_offset: usize,\n    code_level: isize,\n    blockquote_level: isize,\n) {\n    /// Checks if a string is upper-camel-case, i.e., starts with an uppercase and\n    /// contains at least two uppercase letters (`Clippy` is ok) and one lower-case\n    /// letter (`NASA` is ok).\n    /// Plurals are also excluded (`IDs` is ok).\n    fn is_camel_case(s: &str) -> bool {\n        if s.starts_with(|c: char| c.is_ascii_digit() | c.is_ascii_lowercase()) {\n            return false;\n        }\n\n        let s = if let Some(prefix) = s.strip_suffix(\"es\")\n            && prefix.chars().all(|c| c.is_ascii_uppercase())\n            && matches!(prefix.chars().last(), Some('S' | 'X'))\n        {\n            prefix\n        } else if let Some(prefix) = s.strip_suffix(\"ified\")\n            && prefix.chars().all(|c| c.is_ascii_uppercase())\n        {\n            prefix\n        } else {\n            s.strip_suffix('s').unwrap_or(s)\n        };\n\n        s.chars().all(char::is_alphanumeric)\n            && s.chars().filter(|&c| c.is_uppercase()).take(2).count() > 1\n            && s.chars().filter(|&c| c.is_lowercase()).take(1).count() > 0\n    }\n\n    fn has_underscore(s: &str) -> bool {\n        s != \"_\" && !s.contains(\"\\\\_\") && s.contains('_')\n    }\n\n    fn has_hyphen(s: &str) -> bool {\n        s != \"-\" && s.contains('-')\n    }\n\n    if let Ok(url) = Url::parse(word)\n        // try to get around the fact that `foo::bar` parses as a valid URL\n        && !url.cannot_be_a_base()\n    {\n        let Some(fragment_span) = fragments.span(cx, range.clone()) else {\n            return;\n        };\n        let span = Span::new(\n            fragment_span.lo() + BytePos::from_usize(fragment_offset),\n            fragment_span.lo() + BytePos::from_usize(fragment_offset + word.len()),\n            fragment_span.ctxt(),\n            fragment_span.parent(),\n        );\n\n        span_lint_and_sugg(\n            cx,\n            DOC_MARKDOWN,\n            span,\n            \"you should put bare URLs between `<`/`>` or make a proper Markdown link\",\n            \"try\",\n            format!(\"<{word}>\"),\n            Applicability::MachineApplicable,\n        );\n        return;\n    }\n\n    // We assume that mixed-case words are not meant to be put inside backticks. (Issue #2343)\n    //\n    // We also assume that backticks are not necessary if inside a quote. (Issue #10262)\n    if code_level > 0 || blockquote_level > 0 || (has_underscore(word) && has_hyphen(word)) {\n        return;\n    }\n\n    if has_underscore(word) || word.contains(\"::\") || is_camel_case(word) || word.ends_with(\"()\") {\n        let Some(fragment_span) = fragments.span(cx, range.clone()) else {\n            return;\n        };\n\n        let span = Span::new(\n            fragment_span.lo() + BytePos::from_usize(fragment_offset),\n            fragment_span.lo() + BytePos::from_usize(fragment_offset + word.len()),\n            fragment_span.ctxt(),\n            fragment_span.parent(),\n        );\n\n        span_lint_and_then(\n            cx,\n            DOC_MARKDOWN,\n            span,\n            \"item in documentation is missing backticks\",\n            |diag| {\n                let mut applicability = Applicability::MachineApplicable;\n                let snippet = snippet_with_applicability(cx, span, \"..\", &mut applicability);\n                diag.span_suggestion_verbose(span, \"try\", format!(\"`{snippet}`\"), applicability);\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/missing_headers.rs",
    "content": "use super::{DocHeaders, MISSING_ERRORS_DOC, MISSING_PANICS_DOC, MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC};\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_note};\nuse clippy_utils::macros::{is_panic, root_macro_call_first_node};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::implements_trait_with_env;\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{fulfill_or_allowed, is_doc_hidden, is_inside_always_const_context, method_chain_args, return_ty};\nuse rustc_hir::{BodyId, FnSig, OwnerId, Safety};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, sym};\nuse std::ops::ControlFlow;\n\npub fn check(\n    cx: &LateContext<'_>,\n    owner_id: OwnerId,\n    sig: FnSig<'_>,\n    headers: DocHeaders,\n    body_id: Option<BodyId>,\n    check_private_items: bool,\n) {\n    if !check_private_items && !cx.effective_visibilities.is_exported(owner_id.def_id) {\n        return; // Private functions do not require doc comments\n    }\n\n    // do not lint if any parent has `#[doc(hidden)]` attribute (#7347)\n    if !check_private_items\n        && cx\n            .tcx\n            .hir_parent_iter(owner_id.into())\n            .any(|(id, _node)| is_doc_hidden(cx.tcx.hir_attrs(id)))\n    {\n        return;\n    }\n\n    let span = cx.tcx.def_span(owner_id);\n    match (headers.safety, sig.header.safety()) {\n        (false, Safety::Unsafe) => span_lint(\n            cx,\n            MISSING_SAFETY_DOC,\n            span,\n            \"unsafe function's docs are missing a `# Safety` section\",\n        ),\n        (true, Safety::Safe) => span_lint(\n            cx,\n            UNNECESSARY_SAFETY_DOC,\n            span,\n            \"safe function's docs have unnecessary `# Safety` section\",\n        ),\n        _ => (),\n    }\n    if !headers.panics\n        && let Some(body_id) = body_id\n        && let Some(panic_span) = find_panic(cx, body_id)\n    {\n        span_lint_and_note(\n            cx,\n            MISSING_PANICS_DOC,\n            span,\n            \"docs for function which may panic missing `# Panics` section\",\n            Some(panic_span),\n            \"first possible panic found here\",\n        );\n    }\n    if !headers.errors {\n        if return_ty(cx, owner_id).is_diag_item(cx, sym::Result) {\n            span_lint(\n                cx,\n                MISSING_ERRORS_DOC,\n                span,\n                \"docs for function returning `Result` missing `# Errors` section\",\n            );\n        } else if let Some(body_id) = body_id\n            && let Some(future) = cx.tcx.lang_items().future_trait()\n            && let typeck = cx.tcx.typeck_body(body_id)\n            && let body = cx.tcx.hir_body(body_id)\n            && let ret_ty = typeck.expr_ty(body.value)\n            && implements_trait_with_env(\n                cx.tcx,\n                ty::TypingEnv::non_body_analysis(cx.tcx, owner_id.def_id),\n                ret_ty,\n                future,\n                Some(owner_id.def_id.to_def_id()),\n                &[],\n            )\n            && let ty::Coroutine(_, subs) = ret_ty.kind()\n            && subs.as_coroutine().return_ty().is_diag_item(cx, sym::Result)\n        {\n            span_lint(\n                cx,\n                MISSING_ERRORS_DOC,\n                span,\n                \"docs for function returning `Result` missing `# Errors` section\",\n            );\n        }\n    }\n}\n\nfn find_panic(cx: &LateContext<'_>, body_id: BodyId) -> Option<Span> {\n    let mut panic_span = None;\n    let typeck = cx.tcx.typeck_body(body_id);\n    for_each_expr(cx, cx.tcx.hir_body(body_id), |expr| {\n        if is_inside_always_const_context(cx.tcx, expr.hir_id) {\n            return ControlFlow::<!>::Continue(());\n        }\n\n        if let Some(macro_call) = root_macro_call_first_node(cx, expr)\n            && (is_panic(cx, macro_call.def_id)\n                || matches!(\n                    cx.tcx.get_diagnostic_name(macro_call.def_id),\n                    Some(sym::assert_macro | sym::assert_eq_macro | sym::assert_ne_macro)\n                ))\n            && !fulfill_or_allowed(cx, MISSING_PANICS_DOC, [expr.hir_id])\n            && panic_span.is_none()\n        {\n            panic_span = Some(macro_call.span);\n        }\n\n        // check for `unwrap` and `expect` for both `Option` and `Result`\n        if let Some(arglists) =\n            method_chain_args(expr, &[sym::unwrap]).or_else(|| method_chain_args(expr, &[sym::expect]))\n            && let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs()\n            && matches!(receiver_ty.opt_diag_name(cx), Some(sym::Option | sym::Result))\n            && !fulfill_or_allowed(cx, MISSING_PANICS_DOC, [expr.hir_id])\n            && panic_span.is_none()\n        {\n            panic_span = Some(expr.span);\n        }\n\n        // Visit all nodes to fulfill any `#[expect]`s after the first linted panic\n        ControlFlow::<!>::Continue(())\n    });\n    panic_span\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/mod.rs",
    "content": "#![allow(clippy::lint_without_lint_pass)]\n\nuse clippy_config::Conf;\nuse clippy_utils::attrs::is_doc_hidden;\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_then};\nuse clippy_utils::{is_entrypoint_fn, is_trait_impl_item};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Attribute, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};\nuse rustc_resolve::rustdoc::pulldown_cmark::Event::{\n    Code, DisplayMath, End, FootnoteReference, HardBreak, Html, InlineHtml, InlineMath, Rule, SoftBreak, Start,\n    TaskListMarker, Text,\n};\nuse rustc_resolve::rustdoc::pulldown_cmark::Tag::{\n    BlockQuote, CodeBlock, FootnoteDefinition, Heading, Item, Link, Paragraph,\n};\nuse rustc_resolve::rustdoc::pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options, TagEnd};\nuse rustc_resolve::rustdoc::{\n    DocFragment, add_doc_fragment, attrs_to_doc_fragments, main_body_opts, pulldown_cmark,\n    source_span_for_markdown_range, span_of_fragments,\n};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse std::ops::Range;\nuse url::Url;\n\nmod broken_link;\nmod doc_comment_double_space_linebreaks;\nmod doc_paragraphs_missing_punctuation;\nmod doc_suspicious_footnotes;\nmod include_in_doc_without_cfg;\nmod lazy_continuation;\nmod link_with_quotes;\nmod markdown;\nmod missing_headers;\nmod needless_doctest_main;\nmod suspicious_doc_comments;\nmod test_attr_in_doctest;\nmod too_long_first_doc_paragraph;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks the doc comments have unbroken links, mostly caused\n    /// by bad formatted links such as broken across multiple lines.\n    ///\n    /// ### Why is this bad?\n    /// Because documentation generated by rustdoc will be broken\n    /// since expected links won't be links and just text.\n    ///\n    /// ### Examples\n    /// This link is broken:\n    /// ```no_run\n    /// /// [example of a bad link](https://\n    /// /// github.com/rust-lang/rust-clippy/)\n    /// pub fn do_something() {}\n    /// ```\n    ///\n    /// It shouldn't be broken across multiple lines to work:\n    /// ```no_run\n    /// /// [example of a good link](https://github.com/rust-lang/rust-clippy/)\n    /// pub fn do_something() {}\n    /// ```\n    #[clippy::version = \"1.90.0\"]\n    pub DOC_BROKEN_LINK,\n    pedantic,\n    \"broken document link\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects doc comment linebreaks that use double spaces to separate lines, instead of back-slash (`\\`).\n    ///\n    /// ### Why is this bad?\n    /// Double spaces, when used as doc comment linebreaks, can be difficult to see, and may\n    /// accidentally be removed during automatic formatting or manual refactoring. The use of a back-slash (`\\`)\n    /// is clearer in this regard.\n    ///\n    /// ### Example\n    /// The two replacement dots in this example represent a double space.\n    /// ```no_run\n    /// /// This command takes two numbers as inputs and··\n    /// /// adds them together, and then returns the result.\n    /// fn add(l: i32, r: i32) -> i32 {\n    ///     l + r\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// /// This command takes two numbers as inputs and\\\n    /// /// adds them together, and then returns the result.\n    /// fn add(l: i32, r: i32) -> i32 {\n    ///     l + r\n    /// }\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS,\n    pedantic,\n    \"double-space used for doc comment linebreak instead of `\\\\`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if included files in doc comments are included only for `cfg(doc)`.\n    ///\n    /// ### Why restrict this?\n    /// These files are not useful for compilation but will still be included.\n    /// Also, if any of these non-source code file is updated, it will trigger a\n    /// recompilation.\n    ///\n    /// ### Known problems\n    ///\n    /// Excluding this will currently result in the file being left out if\n    /// the item's docs are inlined from another crate. This may be fixed in a\n    /// future version of rustdoc.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// #![doc = include_str!(\"some_file.md\")]\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #![cfg_attr(doc, doc = include_str!(\"some_file.md\"))]\n    /// ```\n    #[clippy::version = \"1.85.0\"]\n    pub DOC_INCLUDE_WITHOUT_CFG,\n    restriction,\n    \"check if files included in documentation are behind `cfg(doc)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// In CommonMark Markdown, the language used to write doc comments, a\n    /// paragraph nested within a list or block quote does not need any line\n    /// after the first one to be indented or marked. The specification calls\n    /// this a \"lazy paragraph continuation.\"\n    ///\n    /// ### Why is this bad?\n    ///\n    /// This is easy to write but hard to read. Lazy continuations makes\n    /// unintended markers hard to see, and make it harder to deduce the\n    /// document's intended structure.\n    ///\n    /// ### Example\n    ///\n    /// This table is probably intended to have two rows,\n    /// but it does not. It has zero rows, and is followed by\n    /// a block quote.\n    /// ```no_run\n    /// /// Range | Description\n    /// /// ----- | -----------\n    /// /// >= 1  | fully opaque\n    /// /// < 1   | partially see-through\n    /// fn set_opacity(opacity: f32) {}\n    /// ```\n    ///\n    /// Fix it by escaping the marker:\n    /// ```no_run\n    /// /// Range | Description\n    /// /// ----- | -----------\n    /// /// \\>= 1 | fully opaque\n    /// /// < 1   | partially see-through\n    /// fn set_opacity(opacity: f32) {}\n    /// ```\n    ///\n    /// This example is actually intended to be a list:\n    /// ```no_run\n    /// /// * Do nothing.\n    /// /// * Then do something. Whatever it is needs done,\n    /// /// it should be done right now.\n    /// # fn do_stuff() {}\n    /// ```\n    ///\n    /// Fix it by indenting the list contents:\n    /// ```no_run\n    /// /// * Do nothing.\n    /// /// * Then do something. Whatever it is needs done,\n    /// ///   it should be done right now.\n    /// # fn do_stuff() {}\n    /// ```\n    #[clippy::version = \"1.80.0\"]\n    pub DOC_LAZY_CONTINUATION,\n    style,\n    \"require every line of a paragraph to be indented and marked\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for links with code directly adjacent to code text:\n    /// `` [`MyItem`]`<`[`u32`]`>` ``.\n    ///\n    /// ### Why is this bad?\n    /// It can be written more simply using HTML-style `<code>` tags.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// //! [`first`](x)`second`\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// //! <code>[first](x)second</code>\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub DOC_LINK_CODE,\n    nursery,\n    \"link with code back-to-back with other code\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects the syntax `['foo']` in documentation comments (notice quotes instead of backticks)\n    /// outside of code blocks\n    /// ### Why is this bad?\n    /// It is likely a typo when defining an intra-doc link\n    ///\n    /// ### Example\n    /// ```no_run\n    /// /// See also: ['foo']\n    /// fn bar() {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// /// See also: [`foo`]\n    /// fn bar() {}\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub DOC_LINK_WITH_QUOTES,\n    pedantic,\n    \"possible typo for an intra-doc link\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the presence of `_`, `::` or camel-case words\n    /// outside ticks in documentation.\n    ///\n    /// ### Why is this bad?\n    /// *Rustdoc* supports markdown formatting, `_`, `::` and\n    /// camel-case probably indicates some code which should be included between\n    /// ticks. `_` can also be used for emphasis in markdown, this lint tries to\n    /// consider that.\n    ///\n    /// ### Known problems\n    /// Lots of bad docs won’t be fixed, what the lint checks\n    /// for is limited, and there are still false positives. HTML elements and their\n    /// content are not linted.\n    ///\n    /// In addition, when writing documentation comments, including `[]` brackets\n    /// inside a link text would trip the parser. Therefore, documenting link with\n    /// `[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec\n    /// would fail.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// /// Do something with the foo_bar parameter. See also\n    /// /// that::other::module::foo.\n    /// // ^ `foo_bar` and `that::other::module::foo` should be ticked.\n    /// fn doit(foo_bar: usize) {}\n    /// ```\n    ///\n    /// ```no_run\n    /// // Link text with `[]` brackets should be written as following:\n    /// /// Consume the array and return the inner\n    /// /// [`SmallVec<[T; INLINE_CAPACITY]>`][SmallVec].\n    /// /// [SmallVec]: SmallVec\n    /// fn main() {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DOC_MARKDOWN,\n    pedantic,\n    \"presence of `_`, `::` or camel-case outside backticks in documentation\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if a link reference definition appears at the start of a\n    /// list item or quote.\n    ///\n    /// ### Why is this bad?\n    /// This is probably intended as an intra-doc link. If it is really\n    /// supposed to be a reference definition, it can be written outside\n    /// of the list item or quote.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// //! - [link]: description\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// //! - [link][]: description (for intra-doc link)\n    /// //!\n    /// //! [link]: destination (for link reference definition)\n    /// ```\n    #[clippy::version = \"1.85.0\"]\n    pub DOC_NESTED_REFDEFS,\n    suspicious,\n    \"link reference defined in list item or quote\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Detects overindented list items in doc comments where the continuation\n    /// lines are indented more than necessary.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Overindented list items in doc comments can lead to inconsistent and\n    /// poorly formatted documentation when rendered. Excessive indentation may\n    /// cause the text to be misinterpreted as a nested list item or code block,\n    /// affecting readability and the overall structure of the documentation.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// /// - This is the first item in a list\n    /// ///      and this line is overindented.\n    /// # fn foo() {}\n    /// ```\n    ///\n    /// Fixes this into:\n    /// ```no_run\n    /// /// - This is the first item in a list\n    /// ///   and this line is overindented.\n    /// # fn foo() {}\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub DOC_OVERINDENTED_LIST_ITEMS,\n    style,\n    \"ensure list items are not overindented\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for doc comments whose paragraphs do not end with a period or another punctuation mark.\n    /// Various Markdowns constructs are taken into account to avoid false positives.\n    ///\n    /// ### Why is this bad?\n    /// A project may wish to enforce consistent doc comments by making sure paragraphs end with a\n    /// punctuation mark.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// /// Returns a random number\n    /// ///\n    /// /// It was chosen by a fair dice roll\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// /// Returns a random number.\n    /// ///\n    /// /// It was chosen by a fair dice roll.\n    /// ```\n    ///\n    /// ### Terminal punctuation marks\n    /// This lint treats these characters as end markers: '.', '?', '!', '…' and ':'.\n    ///\n    /// The colon is not exactly a terminal punctuation mark, but this is required for paragraphs that\n    /// introduce a table or a list for example.\n    #[clippy::version = \"1.93.0\"]\n    pub DOC_PARAGRAPHS_MISSING_PUNCTUATION,\n    restriction,\n    \"missing terminal punctuation in doc comments\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects syntax that looks like a footnote reference.\n    ///\n    /// Rustdoc footnotes are compatible with GitHub-Flavored Markdown (GFM).\n    /// GFM does not parse a footnote reference unless its definition also\n    /// exists. This lint checks for footnote references with missing\n    /// definitions, unless it thinks you're writing a regex.\n    ///\n    /// ### Why is this bad?\n    /// This probably means that a footnote was meant to exist,\n    /// but was not written.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// /// This is not a footnote[^1], because no definition exists.\n    /// fn my_fn() {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// /// This is a footnote[^1].\n    /// ///\n    /// /// [^1]: defined here\n    /// fn my_fn() {}\n    /// ```\n    #[clippy::version = \"1.89.0\"]\n    pub DOC_SUSPICIOUS_FOOTNOTES,\n    suspicious,\n    \"looks like a link or footnote ref, but with no definition\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects documentation that is empty.\n    /// ### Why is this bad?\n    /// Empty docs clutter code without adding value, reducing readability and maintainability.\n    /// ### Example\n    /// ```no_run\n    /// ///\n    /// fn returns_true() -> bool {\n    ///     true\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn returns_true() -> bool {\n    ///     true\n    /// }\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub EMPTY_DOCS,\n    suspicious,\n    \"docstrings exist but documentation is empty\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks the doc comments of publicly visible functions that\n    /// return a `Result` type and warns if there is no `# Errors` section.\n    ///\n    /// ### Why is this bad?\n    /// Documenting the type of errors that can be returned from a\n    /// function can help callers write code to handle the errors appropriately.\n    ///\n    /// ### Examples\n    /// Since the following function returns a `Result` it has an `# Errors` section in\n    /// its doc comment:\n    ///\n    /// ```no_run\n    ///# use std::io;\n    /// /// # Errors\n    /// ///\n    /// /// Will return `Err` if `filename` does not exist or the user does not have\n    /// /// permission to read it.\n    /// pub fn read(filename: String) -> io::Result<String> {\n    ///     unimplemented!();\n    /// }\n    /// ```\n    #[clippy::version = \"1.41.0\"]\n    pub MISSING_ERRORS_DOC,\n    pedantic,\n    \"`pub fn` returns `Result` without `# Errors` in doc comment\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks the doc comments of publicly visible functions that\n    /// may panic and warns if there is no `# Panics` section.\n    ///\n    /// ### Why is this bad?\n    /// Documenting the scenarios in which panicking occurs\n    /// can help callers who do not want to panic to avoid those situations.\n    ///\n    /// ### Examples\n    /// Since the following function may panic it has a `# Panics` section in\n    /// its doc comment:\n    ///\n    /// ```no_run\n    /// /// # Panics\n    /// ///\n    /// /// Will panic if y is 0\n    /// pub fn divide_by(x: i32, y: i32) -> i32 {\n    ///     if y == 0 {\n    ///         panic!(\"Cannot divide by 0\")\n    ///     } else {\n    ///         x / y\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Individual panics within a function can be ignored with `#[expect]` or\n    /// `#[allow]`:\n    ///\n    /// ```no_run\n    /// # use std::num::NonZeroUsize;\n    /// pub fn will_not_panic(x: usize) {\n    ///     #[expect(clippy::missing_panics_doc, reason = \"infallible\")]\n    ///     let y = NonZeroUsize::new(1).unwrap();\n    ///\n    ///     // If any panics are added in the future the lint will still catch them\n    /// }\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub MISSING_PANICS_DOC,\n    pedantic,\n    \"`pub fn` may panic without `# Panics` in doc comment\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the doc comments of publicly visible\n    /// unsafe functions and warns if there is no `# Safety` section.\n    ///\n    /// ### Why is this bad?\n    /// Unsafe functions should document their safety\n    /// preconditions, so that users can be sure they are using them safely.\n    ///\n    /// ### Examples\n    /// ```no_run\n    ///# type Universe = ();\n    /// /// This function should really be documented\n    /// pub unsafe fn start_apocalypse(u: &mut Universe) {\n    ///     unimplemented!();\n    /// }\n    /// ```\n    ///\n    /// At least write a line about safety:\n    ///\n    /// ```no_run\n    ///# type Universe = ();\n    /// /// # Safety\n    /// ///\n    /// /// This function should not be called before the horsemen are ready.\n    /// pub unsafe fn start_apocalypse(u: &mut Universe) {\n    ///     unimplemented!();\n    /// }\n    /// ```\n    #[clippy::version = \"1.39.0\"]\n    pub MISSING_SAFETY_DOC,\n    style,\n    \"`pub unsafe fn` without `# Safety` docs\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `fn main() { .. }` in doctests\n    ///\n    /// ### Why is this bad?\n    /// The test can be shorter (and likely more readable)\n    /// if the `fn main()` is left implicit.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// /// An example of a doctest with a `main()` function\n    /// ///\n    /// /// # Examples\n    /// ///\n    /// /// ```\n    /// /// fn main() {\n    /// ///     // this needs not be in an `fn`\n    /// /// }\n    /// /// ```\n    /// fn needless_main() {\n    ///     unimplemented!();\n    /// }\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub NEEDLESS_DOCTEST_MAIN,\n    style,\n    \"presence of `fn main() {` in code examples\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects the use of outer doc comments (`///`, `/**`) followed by a bang (`!`): `///!`\n    ///\n    /// ### Why is this bad?\n    /// Triple-slash comments (known as \"outer doc comments\") apply to items that follow it.\n    /// An outer doc comment followed by a bang (i.e. `///!`) has no specific meaning.\n    ///\n    /// The user most likely meant to write an inner doc comment (`//!`, `/*!`), which\n    /// applies to the parent item (i.e. the item that the comment is contained in,\n    /// usually a module or crate).\n    ///\n    /// ### Known problems\n    /// Inner doc comments can only appear before items, so there are certain cases where the suggestion\n    /// made by this lint is not valid code. For example:\n    /// ```rust\n    /// fn foo() {}\n    /// ///!\n    /// fn bar() {}\n    /// ```\n    /// This lint detects the doc comment and suggests changing it to `//!`, but an inner doc comment\n    /// is not valid at that position.\n    ///\n    /// ### Example\n    /// In this example, the doc comment is attached to the *function*, rather than the *module*.\n    /// ```no_run\n    /// pub mod util {\n    ///     ///! This module contains utility functions.\n    ///\n    ///     pub fn dummy() {}\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// pub mod util {\n    ///     //! This module contains utility functions.\n    ///\n    ///     pub fn dummy() {}\n    /// }\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub SUSPICIOUS_DOC_COMMENTS,\n    suspicious,\n    \"suspicious usage of (outer) doc comments\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `#[test]` in doctests unless they are marked with\n    /// either `ignore`, `no_run` or `compile_fail`.\n    ///\n    /// ### Why is this bad?\n    /// Code in examples marked as `#[test]` will somewhat\n    /// surprisingly not be run by `cargo test`. If you really want\n    /// to show how to test stuff in an example, mark it `no_run` to\n    /// make the intent clear.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// /// An example of a doctest with a `main()` function\n    /// ///\n    /// /// # Examples\n    /// ///\n    /// /// ```\n    /// /// #[test]\n    /// /// fn equality_works() {\n    /// ///     assert_eq!(1_u8, 1);\n    /// /// }\n    /// /// ```\n    /// fn test_attr_in_doctest() {\n    ///     unimplemented!();\n    /// }\n    /// ```\n    #[clippy::version = \"1.76.0\"]\n    pub TEST_ATTR_IN_DOCTEST,\n    suspicious,\n    \"presence of `#[test]` in code examples\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if the first paragraph in the documentation of items listed in the module page is too long.\n    ///\n    /// ### Why is this bad?\n    /// Documentation will show the first paragraph of the docstring in the summary page of a\n    /// module. Having a nice, short summary in the first paragraph is part of writing good docs.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// /// A very short summary.\n    /// /// A much longer explanation that goes into a lot more detail about\n    /// /// how the thing works, possibly with doclinks and so one,\n    /// /// and probably spanning a many rows.\n    /// struct Foo {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// /// A very short summary.\n    /// ///\n    /// /// A much longer explanation that goes into a lot more detail about\n    /// /// how the thing works, possibly with doclinks and so one,\n    /// /// and probably spanning a many rows.\n    /// struct Foo {}\n    /// ```\n    #[clippy::version = \"1.82.0\"]\n    pub TOO_LONG_FIRST_DOC_PARAGRAPH,\n    nursery,\n    \"ensure the first documentation paragraph is short\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the doc comments of publicly visible\n    /// safe functions and traits and warns if there is a `# Safety` section.\n    ///\n    /// ### Why restrict this?\n    /// Safe functions and traits are safe to implement and therefore do not\n    /// need to describe safety preconditions that users are required to uphold.\n    ///\n    /// ### Examples\n    /// ```no_run\n    ///# type Universe = ();\n    /// /// # Safety\n    /// ///\n    /// /// This function should not be called before the horsemen are ready.\n    /// pub fn start_apocalypse_but_safely(u: &mut Universe) {\n    ///     unimplemented!();\n    /// }\n    /// ```\n    ///\n    /// The function is safe, so there shouldn't be any preconditions\n    /// that have to be explained for safety reasons.\n    ///\n    /// ```no_run\n    ///# type Universe = ();\n    /// /// This function should really be documented\n    /// pub fn start_apocalypse(u: &mut Universe) {\n    ///     unimplemented!();\n    /// }\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub UNNECESSARY_SAFETY_DOC,\n    restriction,\n    \"`pub fn` or `pub trait` with `# Safety` docs\"\n}\n\nimpl_lint_pass!(Documentation => [\n    DOC_BROKEN_LINK,\n    DOC_COMMENT_DOUBLE_SPACE_LINEBREAKS,\n    DOC_INCLUDE_WITHOUT_CFG,\n    DOC_LAZY_CONTINUATION,\n    DOC_LINK_CODE,\n    DOC_LINK_WITH_QUOTES,\n    DOC_MARKDOWN,\n    DOC_NESTED_REFDEFS,\n    DOC_OVERINDENTED_LIST_ITEMS,\n    DOC_PARAGRAPHS_MISSING_PUNCTUATION,\n    DOC_SUSPICIOUS_FOOTNOTES,\n    EMPTY_DOCS,\n    MISSING_ERRORS_DOC,\n    MISSING_PANICS_DOC,\n    MISSING_SAFETY_DOC,\n    NEEDLESS_DOCTEST_MAIN,\n    SUSPICIOUS_DOC_COMMENTS,\n    TEST_ATTR_IN_DOCTEST,\n    TOO_LONG_FIRST_DOC_PARAGRAPH,\n    UNNECESSARY_SAFETY_DOC,\n]);\n\npub struct Documentation {\n    valid_idents: FxHashSet<String>,\n    check_private_items: bool,\n}\n\nimpl Documentation {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            valid_idents: conf.doc_valid_idents.iter().cloned().collect(),\n            check_private_items: conf.check_private_items,\n        }\n    }\n}\n\nimpl EarlyLintPass for Documentation {\n    fn check_attributes(&mut self, cx: &EarlyContext<'_>, attrs: &[rustc_ast::Attribute]) {\n        include_in_doc_without_cfg::check(cx, attrs);\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Documentation {\n    fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {\n        let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else {\n            return;\n        };\n\n        match cx.tcx.hir_node(cx.last_node_with_lint_attrs) {\n            Node::Item(item) => {\n                too_long_first_doc_paragraph::check(\n                    cx,\n                    item,\n                    attrs,\n                    headers.first_paragraph_len,\n                    self.check_private_items,\n                );\n                match item.kind {\n                    ItemKind::Fn { sig, body, .. }\n                        if !(is_entrypoint_fn(cx, item.owner_id.to_def_id())\n                            || item.span.in_external_macro(cx.tcx.sess.source_map())) =>\n                    {\n                        missing_headers::check(cx, item.owner_id, sig, headers, Some(body), self.check_private_items);\n                    },\n                    ItemKind::Trait(_, _, unsafety, ..) => match (headers.safety, unsafety) {\n                        (false, Safety::Unsafe) => span_lint(\n                            cx,\n                            MISSING_SAFETY_DOC,\n                            cx.tcx.def_span(item.owner_id),\n                            \"docs for unsafe trait missing `# Safety` section\",\n                        ),\n                        (true, Safety::Safe) => span_lint(\n                            cx,\n                            UNNECESSARY_SAFETY_DOC,\n                            cx.tcx.def_span(item.owner_id),\n                            \"docs for safe trait have unnecessary `# Safety` section\",\n                        ),\n                        _ => (),\n                    },\n                    _ => (),\n                }\n            },\n            Node::TraitItem(trait_item) => {\n                if let TraitItemKind::Fn(sig, ..) = trait_item.kind\n                    && !trait_item.span.in_external_macro(cx.tcx.sess.source_map())\n                {\n                    missing_headers::check(cx, trait_item.owner_id, sig, headers, None, self.check_private_items);\n                }\n            },\n            Node::ImplItem(impl_item) => {\n                if let ImplItemKind::Fn(sig, body_id) = impl_item.kind\n                    && !impl_item.span.in_external_macro(cx.tcx.sess.source_map())\n                    && !is_trait_impl_item(cx, impl_item.hir_id())\n                {\n                    missing_headers::check(\n                        cx,\n                        impl_item.owner_id,\n                        sig,\n                        headers,\n                        Some(body_id),\n                        self.check_private_items,\n                    );\n                }\n            },\n            _ => {},\n        }\n    }\n}\n\n#[derive(Copy, Clone)]\nstruct Fragments<'a> {\n    doc: &'a str,\n    fragments: &'a [DocFragment],\n}\n\nimpl Fragments<'_> {\n    /// get the span for the markdown range. Note that this function is not cheap, use it with\n    /// caution.\n    #[must_use]\n    fn span(self, cx: &LateContext<'_>, range: Range<usize>) -> Option<Span> {\n        source_span_for_markdown_range(cx.tcx, self.doc, &range, self.fragments).map(|(sp, _)| sp)\n    }\n}\n\n#[derive(Copy, Clone, Default)]\nstruct DocHeaders {\n    safety: bool,\n    errors: bool,\n    panics: bool,\n    first_paragraph_len: usize,\n}\n\n/// Does some pre-processing on raw, desugared `#[doc]` attributes such as parsing them and\n/// then delegates to `check_doc`.\n/// Some lints are already checked here if they can work with attributes directly and don't need\n/// to work with markdown.\n/// Others are checked elsewhere, e.g. in `check_doc` if they need access to markdown, or\n/// back in the various late lint pass methods if they need the final doc headers, like \"Safety\" or\n/// \"Panics\" sections.\nfn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[Attribute]) -> Option<DocHeaders> {\n    // We don't want the parser to choke on intra doc links. Since we don't\n    // actually care about rendering them, just pretend that all broken links\n    // point to a fake address.\n    #[expect(clippy::unnecessary_wraps)] // we're following a type signature\n    fn fake_broken_link_callback<'a>(_: BrokenLink<'_>) -> Option<(CowStr<'a>, CowStr<'a>)> {\n        Some((\"fake\".into(), \"fake\".into()))\n    }\n\n    if suspicious_doc_comments::check(cx, attrs) || is_doc_hidden(attrs) {\n        return None;\n    }\n\n    let (fragments, _) = attrs_to_doc_fragments(\n        attrs.iter().filter_map(|attr| {\n            if attr.doc_str_and_fragment_kind().is_none() || attr.span().in_external_macro(cx.sess().source_map()) {\n                None\n            } else {\n                Some((attr, None))\n            }\n        }),\n        true,\n    );\n\n    let mut doc = String::with_capacity(fragments.iter().map(|frag| frag.doc.as_str().len() + 1).sum());\n\n    for fragment in &fragments {\n        add_doc_fragment(&mut doc, fragment);\n    }\n    doc.pop();\n\n    if doc.trim().is_empty() {\n        if let Some(span) = span_of_fragments(&fragments) {\n            span_lint_and_help(\n                cx,\n                EMPTY_DOCS,\n                span,\n                \"empty doc comment\",\n                None,\n                \"consider removing or filling it\",\n            );\n        }\n        return Some(DocHeaders::default());\n    }\n\n    check_for_code_clusters(\n        cx,\n        pulldown_cmark::Parser::new_with_broken_link_callback(\n            &doc,\n            main_body_opts() - Options::ENABLE_SMART_PUNCTUATION,\n            Some(&mut fake_broken_link_callback),\n        )\n        .into_offset_iter(),\n        &doc,\n        Fragments {\n            doc: &doc,\n            fragments: &fragments,\n        },\n    );\n\n    doc_paragraphs_missing_punctuation::check(\n        cx,\n        &doc,\n        Fragments {\n            doc: &doc,\n            fragments: &fragments,\n        },\n    );\n\n    // NOTE: check_doc uses it own cb function,\n    // to avoid causing duplicated diagnostics for the broken link checker.\n    let mut full_fake_broken_link_callback = |bl: BrokenLink<'_>| -> Option<(CowStr<'_>, CowStr<'_>)> {\n        broken_link::check(cx, &bl, &doc, &fragments);\n        Some((\"fake\".into(), \"fake\".into()))\n    };\n\n    // disable smart punctuation to pick up ['link'] more easily\n    let opts = main_body_opts() - Options::ENABLE_SMART_PUNCTUATION;\n    let parser =\n        pulldown_cmark::Parser::new_with_broken_link_callback(&doc, opts, Some(&mut full_fake_broken_link_callback));\n\n    Some(check_doc(\n        cx,\n        valid_idents,\n        parser.into_offset_iter(),\n        &doc,\n        Fragments {\n            doc: &doc,\n            fragments: &fragments,\n        },\n        attrs,\n    ))\n}\n\nenum Container {\n    Blockquote,\n    List(usize),\n}\n\n/// Scan the documentation for code links that are back-to-back with code spans.\n///\n/// This is done separately from the rest of the docs, because that makes it easier to produce\n/// the correct messages.\nfn check_for_code_clusters<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(\n    cx: &LateContext<'_>,\n    events: Events,\n    doc: &str,\n    fragments: Fragments<'_>,\n) {\n    let mut events = events.peekable();\n    let mut code_starts_at = None;\n    let mut code_ends_at = None;\n    let mut code_includes_link = false;\n    while let Some((event, range)) = events.next() {\n        match event {\n            Start(Link { .. }) if matches!(events.peek(), Some((Code(_), _range))) => {\n                if code_starts_at.is_some() {\n                    code_ends_at = Some(range.end);\n                } else {\n                    code_starts_at = Some(range.start);\n                }\n                code_includes_link = true;\n                // skip the nested \"code\", because we're already handling it here\n                let _ = events.next();\n            },\n            Code(_) => {\n                if code_starts_at.is_some() {\n                    code_ends_at = Some(range.end);\n                } else {\n                    code_starts_at = Some(range.start);\n                }\n            },\n            End(TagEnd::Link) => {},\n            _ => {\n                if let Some(start) = code_starts_at\n                    && let Some(end) = code_ends_at\n                    && code_includes_link\n                    && let Some(span) = fragments.span(cx, start..end)\n                {\n                    span_lint_and_then(cx, DOC_LINK_CODE, span, \"code link adjacent to code text\", |diag| {\n                        let sugg = format!(\"<code>{}</code>\", doc[start..end].replace('`', \"\"));\n                        diag.span_suggestion_verbose(\n                            span,\n                            \"wrap the entire group in `<code>` tags\",\n                            sugg,\n                            Applicability::MaybeIncorrect,\n                        );\n                        diag.help(\"separate code snippets will be shown with a gap\");\n                    });\n                }\n                code_includes_link = false;\n                code_starts_at = None;\n                code_ends_at = None;\n            },\n        }\n    }\n}\n\n#[derive(Clone, Copy)]\n#[expect(clippy::struct_excessive_bools)]\nstruct CodeTags {\n    no_run: bool,\n    ignore: bool,\n    compile_fail: bool,\n    test_harness: bool,\n\n    rust: bool,\n}\n\nimpl Default for CodeTags {\n    fn default() -> Self {\n        Self {\n            no_run: false,\n            ignore: false,\n            compile_fail: false,\n            test_harness: false,\n\n            rust: true,\n        }\n    }\n}\n\nimpl CodeTags {\n    /// Based on <https://github.com/rust-lang/rust/blob/1.90.0/src/librustdoc/html/markdown.rs#L1169>\n    fn parse(lang: &str) -> Self {\n        let mut tags = Self::default();\n\n        let mut seen_rust_tags = false;\n        let mut seen_other_tags = false;\n        for item in lang.split([',', ' ', '\\t']) {\n            match item.trim() {\n                \"\" => {},\n                \"rust\" => {\n                    tags.rust = true;\n                    seen_rust_tags = true;\n                },\n                \"ignore\" => {\n                    tags.ignore = true;\n                    seen_rust_tags = !seen_other_tags;\n                },\n                \"no_run\" => {\n                    tags.no_run = true;\n                    seen_rust_tags = !seen_other_tags;\n                },\n                \"should_panic\" => seen_rust_tags = !seen_other_tags,\n                \"compile_fail\" => {\n                    tags.compile_fail = true;\n                    seen_rust_tags = !seen_other_tags || seen_rust_tags;\n                },\n                \"test_harness\" => {\n                    tags.test_harness = true;\n                    seen_rust_tags = !seen_other_tags || seen_rust_tags;\n                },\n                \"standalone_crate\" => {\n                    seen_rust_tags = !seen_other_tags || seen_rust_tags;\n                },\n                _ if item.starts_with(\"ignore-\") => seen_rust_tags = true,\n                _ if item.starts_with(\"edition\") => {},\n                _ => seen_other_tags = true,\n            }\n        }\n\n        tags.rust &= seen_rust_tags || !seen_other_tags;\n\n        tags\n    }\n}\n\n/// Checks parsed documentation.\n/// This walks the \"events\" (think sections of markdown) produced by `pulldown_cmark`,\n/// so lints here will generally access that information.\n/// Returns documentation headers -- whether a \"Safety\", \"Errors\", \"Panic\" section was found\n#[expect(clippy::too_many_lines, reason = \"big match statement\")]\nfn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(\n    cx: &LateContext<'_>,\n    valid_idents: &FxHashSet<String>,\n    events: Events,\n    doc: &str,\n    fragments: Fragments<'_>,\n    attrs: &[Attribute],\n) -> DocHeaders {\n    // true if a safety header was found\n    let mut headers = DocHeaders::default();\n    let mut code = None;\n    let mut in_link = None;\n    let mut in_heading = false;\n    let mut in_footnote_definition = false;\n    let mut ticks_unbalanced = false;\n    let mut text_to_check: Vec<(CowStr<'_>, Range<usize>, isize)> = Vec::new();\n    let mut paragraph_range = 0..0;\n    let mut code_level = 0;\n    let mut blockquote_level = 0;\n    let mut collected_breaks: Vec<Span> = Vec::new();\n    let mut is_first_paragraph = true;\n\n    let mut containers = Vec::new();\n\n    let mut events = events.peekable();\n\n    while let Some((event, range)) = events.next() {\n        match event {\n            Html(tag) | InlineHtml(tag) => {\n                if tag.starts_with(\"<code\") {\n                    code_level += 1;\n                } else if tag.starts_with(\"</code\") {\n                    code_level -= 1;\n                } else if tag.starts_with(\"<blockquote\") || tag.starts_with(\"<q\") {\n                    blockquote_level += 1;\n                } else if tag.starts_with(\"</blockquote\") || tag.starts_with(\"</q\") {\n                    blockquote_level -= 1;\n                }\n            },\n            Start(BlockQuote(_)) => {\n                blockquote_level += 1;\n                containers.push(Container::Blockquote);\n                if let Some((next_event, next_range)) = events.peek() {\n                    let next_start = match next_event {\n                        End(TagEnd::BlockQuote) => next_range.end,\n                        _ => next_range.start,\n                    };\n                    if let Some(refdefrange) = looks_like_refdef(doc, range.start..next_start) &&\n                        let Some(refdefspan) = fragments.span(cx, refdefrange.clone())\n                    {\n                        span_lint_and_then(\n                            cx,\n                            DOC_NESTED_REFDEFS,\n                            refdefspan,\n                            \"link reference defined in quote\",\n                            |diag| {\n                                diag.span_suggestion_short(\n                                    refdefspan.shrink_to_hi(),\n                                    \"for an intra-doc link, add `[]` between the label and the colon\",\n                                    \"[]\",\n                                    Applicability::MaybeIncorrect,\n                                );\n                                diag.help(\"link definitions are not shown in rendered documentation\");\n                            }\n                        );\n                    }\n                }\n            },\n            End(TagEnd::BlockQuote) => {\n                blockquote_level -= 1;\n                containers.pop();\n            },\n            Start(CodeBlock(ref kind)) => {\n                code = Some(match kind {\n                    CodeBlockKind::Indented => CodeTags::default(),\n                    CodeBlockKind::Fenced(lang) => CodeTags::parse(lang),\n                });\n            },\n            End(TagEnd::CodeBlock) => code = None,\n            Start(Link { dest_url, .. }) => in_link = Some(dest_url),\n            End(TagEnd::Link) => in_link = None,\n            Start(Heading { .. } | Paragraph | Item) => {\n                if let Start(Heading { .. }) = event {\n                    in_heading = true;\n                }\n                if let Start(Item) = event {\n                    let indent = if let Some((next_event, next_range)) = events.peek() {\n                        let next_start = match next_event {\n                            End(TagEnd::Item) => next_range.end,\n                            _ => next_range.start,\n                        };\n                        if let Some(refdefrange) = looks_like_refdef(doc, range.start..next_start) &&\n                            let Some(refdefspan) = fragments.span(cx, refdefrange.clone())\n                        {\n                            span_lint_and_then(\n                                cx,\n                                DOC_NESTED_REFDEFS,\n                                refdefspan,\n                                \"link reference defined in list item\",\n                                |diag| {\n                                    diag.span_suggestion_short(\n                                        refdefspan.shrink_to_hi(),\n                                        \"for an intra-doc link, add `[]` between the label and the colon\",\n                                        \"[]\",\n                                        Applicability::MaybeIncorrect,\n                                    );\n                                    diag.help(\"link definitions are not shown in rendered documentation\");\n                                }\n                            );\n                            refdefrange.start - range.start\n                        } else {\n                            let mut start = next_range.start;\n                            if start > 0 && doc.as_bytes().get(start - 1) == Some(&b'\\\\') {\n                                // backslashes aren't in the event stream...\n                                start -= 1;\n                            }\n\n                            start.saturating_sub(range.start)\n                        }\n                    } else {\n                        0\n                    };\n                    containers.push(Container::List(indent));\n                }\n                ticks_unbalanced = false;\n                paragraph_range = range;\n                if is_first_paragraph {\n                    headers.first_paragraph_len = doc[paragraph_range.clone()].chars().count();\n                    is_first_paragraph = false;\n                }\n            },\n            End(TagEnd::Heading(_) | TagEnd::Paragraph | TagEnd::Item) => {\n                if let End(TagEnd::Heading(_)) = event {\n                    in_heading = false;\n                }\n                if let End(TagEnd::Item) = event {\n                    containers.pop();\n                }\n                if ticks_unbalanced && let Some(span) = fragments.span(cx, paragraph_range.clone()) {\n                    span_lint_and_help(\n                        cx,\n                        DOC_MARKDOWN,\n                        span,\n                        \"backticks are unbalanced\",\n                        None,\n                        \"a backtick may be missing a pair\",\n                    );\n                    text_to_check.clear();\n                } else {\n                    for (text, range, assoc_code_level) in text_to_check.drain(..) {\n                        markdown::check(cx, valid_idents, &text, &fragments, range, assoc_code_level, blockquote_level);\n                    }\n                }\n            },\n            Start(FootnoteDefinition(..)) => in_footnote_definition = true,\n            End(TagEnd::FootnoteDefinition) => in_footnote_definition = false,\n            Start(_) | End(_)  // We don't care about other tags\n            | TaskListMarker(_) | Code(_) | Rule | InlineMath(..) | DisplayMath(..) => (),\n            SoftBreak | HardBreak => {\n                if !containers.is_empty()\n                    && !in_footnote_definition\n                    // Tabs aren't handled correctly vvvv\n                    && !doc[range.clone()].contains('\\t')\n                    && let Some((next_event, next_range)) = events.peek()\n                    && !matches!(next_event, End(_))\n                {\n                    lazy_continuation::check(\n                        cx,\n                        doc,\n                        range.end..next_range.start,\n                        &fragments,\n                        &containers[..],\n                    );\n                }\n\n\n                if event == HardBreak\n                    && !doc[range.clone()].trim().starts_with('\\\\')\n                    && let Some(span) = fragments.span(cx, range.clone())\n                    && !span.from_expansion()\n                    {\n                    collected_breaks.push(span);\n                }\n            },\n            Text(text) => {\n                paragraph_range.end = range.end;\n                let range_ = range.clone();\n                ticks_unbalanced |= text.contains('`')\n                    && code.is_none()\n                    && doc[range.clone()].bytes().enumerate().any(|(i, c)| {\n                        // scan the markdown source code bytes for backquotes that aren't preceded by backslashes\n                        // - use bytes, instead of chars, to avoid utf8 decoding overhead (special chars are ascii)\n                        // - relevant backquotes are within doc[range], but backslashes are not, because they're not\n                        //   actually part of the rendered text (pulldown-cmark doesn't emit any events for escapes)\n                        // - if `range_.start + i == 0`, then `range_.start + i - 1 == -1`, and since we're working in\n                        //   usize, that would underflow and maybe panic\n                        c == b'`' && (range_.start + i == 0 || doc.as_bytes().get(range_.start + i - 1) != Some(&b'\\\\'))\n                    });\n                if Some(&text) == in_link.as_ref() || ticks_unbalanced {\n                    // Probably a link of the form `<http://example.com>`\n                    // Which are represented as a link to \"http://example.com\" with\n                    // text \"http://example.com\" by pulldown-cmark\n                    continue;\n                }\n                let trimmed_text = text.trim();\n                headers.safety |= in_heading && trimmed_text == \"Safety\";\n                headers.safety |= in_heading && trimmed_text == \"SAFETY\";\n                headers.safety |= in_heading && trimmed_text == \"Implementation safety\";\n                headers.safety |= in_heading && trimmed_text == \"Implementation Safety\";\n                headers.errors |= in_heading && trimmed_text == \"Errors\";\n                headers.panics |= in_heading && trimmed_text == \"Panics\";\n\n                if let Some(tags) = code {\n                    if tags.rust && !tags.compile_fail && !tags.ignore {\n                        needless_doctest_main::check(cx, &text, range.start, fragments);\n\n                        if !tags.no_run && !tags.test_harness {\n                            test_attr_in_doctest::check(cx, &text, range.start, fragments);\n                        }\n                    }\n                } else {\n                    if in_link.is_some() {\n                        link_with_quotes::check(cx, trimmed_text, range.clone(), fragments);\n                    }\n                    if let Some(link) = in_link.as_ref()\n                        && let Ok(url) = Url::parse(link)\n                        && (url.scheme() == \"https\" || url.scheme() == \"http\")\n                    {\n                        // Don't check the text associated with external URLs\n                        continue;\n                    }\n                    text_to_check.push((text, range.clone(), code_level));\n                    doc_suspicious_footnotes::check(cx, doc, range, &fragments, attrs);\n                }\n            }\n            FootnoteReference(_) => {}\n        }\n    }\n\n    doc_comment_double_space_linebreaks::check(cx, &collected_breaks);\n\n    headers\n}\n\nfn looks_like_refdef(doc: &str, range: Range<usize>) -> Option<Range<usize>> {\n    if range.end < range.start {\n        return None;\n    }\n\n    let offset = range.start;\n    let mut iterator = doc.as_bytes()[range].iter().copied().enumerate();\n    let mut start = None;\n    while let Some((i, byte)) = iterator.next() {\n        match byte {\n            b'\\\\' => {\n                iterator.next();\n            },\n            b'[' => {\n                start = Some(i + offset);\n            },\n            b']' if let Some(start) = start\n                && doc.as_bytes().get(i + offset + 1) == Some(&b':') =>\n            {\n                return Some(start..i + offset + 1);\n            },\n            _ => {},\n        }\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/needless_doctest_main.rs",
    "content": "use super::Fragments;\nuse crate::doc::NEEDLESS_DOCTEST_MAIN;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::tokenize_with_text;\nuse rustc_lexer::TokenKind;\nuse rustc_lint::LateContext;\nuse rustc_span::InnerSpan;\n\nfn returns_unit<'a>(mut tokens: impl Iterator<Item = (TokenKind, &'a str, InnerSpan)>) -> bool {\n    let mut next = || tokens.next().map_or(TokenKind::Whitespace, |(kind, ..)| kind);\n\n    match next() {\n        // {\n        TokenKind::OpenBrace => true,\n        // - > ( ) {\n        TokenKind::Minus => {\n            next() == TokenKind::Gt\n                && next() == TokenKind::OpenParen\n                && next() == TokenKind::CloseParen\n                && next() == TokenKind::OpenBrace\n        },\n        _ => false,\n    }\n}\n\npub fn check(cx: &LateContext<'_>, text: &str, offset: usize, fragments: Fragments<'_>) {\n    if !text.contains(\"main\") {\n        return;\n    }\n\n    let mut tokens = tokenize_with_text(text).filter(|&(kind, ..)| {\n        !matches!(\n            kind,\n            TokenKind::Whitespace | TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }\n        )\n    });\n    if let Some((TokenKind::Ident, \"fn\", fn_span)) = tokens.next()\n        && let Some((TokenKind::Ident, \"main\", main_span)) = tokens.next()\n        && let Some((TokenKind::OpenParen, ..)) = tokens.next()\n        && let Some((TokenKind::CloseParen, ..)) = tokens.next()\n        && returns_unit(&mut tokens)\n    {\n        let mut depth = 1;\n        for (kind, ..) in &mut tokens {\n            match kind {\n                TokenKind::OpenBrace => depth += 1,\n                TokenKind::CloseBrace => {\n                    depth -= 1;\n                    if depth == 0 {\n                        break;\n                    }\n                },\n                _ => {},\n            }\n        }\n\n        if tokens.next().is_none()\n            && let Some(span) = fragments.span(cx, fn_span.start + offset..main_span.end + offset)\n        {\n            span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, \"needless `fn main` in doctest\");\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/suspicious_doc_comments.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::AttrStyle;\nuse rustc_ast::token::{CommentKind, DocFragmentKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::Attribute;\nuse rustc_hir::attrs::AttributeKind;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::SUSPICIOUS_DOC_COMMENTS;\n\npub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) -> bool {\n    let replacements: Vec<_> = collect_doc_replacements(attrs);\n\n    if let Some((&(lo_span, _), &(hi_span, _))) = replacements.first().zip(replacements.last()) {\n        span_lint_and_then(\n            cx,\n            SUSPICIOUS_DOC_COMMENTS,\n            lo_span.to(hi_span),\n            \"this is an outer doc comment and does not apply to the parent module or crate\",\n            |diag| {\n                diag.multipart_suggestion(\n                    \"use an inner doc comment to document the parent module or crate\",\n                    replacements,\n                    Applicability::MaybeIncorrect,\n                );\n            },\n        );\n\n        true\n    } else {\n        false\n    }\n}\n\nfn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> {\n    attrs\n        .iter()\n        .filter_map(|attr| {\n            if let Attribute::Parsed(AttributeKind::DocComment {\n                style: AttrStyle::Outer,\n                kind: DocFragmentKind::Sugared(comment_kind),\n                comment,\n                ..\n            }) = attr\n                && let Some(com) = comment.as_str().strip_prefix('!')\n            {\n                let sugg = match comment_kind {\n                    CommentKind::Block => format!(\"/*!{com}*/\"),\n                    CommentKind::Line => format!(\"//!{com}\"),\n                };\n                Some((attr.span(), sugg))\n            } else {\n                None\n            }\n        })\n        .collect()\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/test_attr_in_doctest.rs",
    "content": "use super::Fragments;\nuse crate::doc::TEST_ATTR_IN_DOCTEST;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::tokenize_with_text;\nuse rustc_lexer::TokenKind;\nuse rustc_lint::LateContext;\n\npub fn check(cx: &LateContext<'_>, text: &str, offset: usize, fragments: Fragments<'_>) {\n    if !text.contains(\"#[test]\") {\n        return;\n    }\n\n    let mut spans = Vec::new();\n    let mut tokens = tokenize_with_text(text).filter(|&(kind, ..)| kind != TokenKind::Whitespace);\n    while let Some(token) = tokens.next() {\n        if let (TokenKind::Pound, _, pound_span) = token\n            && let Some((TokenKind::OpenBracket, ..)) = tokens.next()\n            && let Some((TokenKind::Ident, \"test\", _)) = tokens.next()\n            && let Some((TokenKind::CloseBracket, _, close_span)) = tokens.next()\n            && let Some(span) = fragments.span(cx, pound_span.start + offset..close_span.end + offset)\n        {\n            spans.push(span);\n        }\n    }\n\n    if !spans.is_empty() {\n        span_lint(\n            cx,\n            TEST_ATTR_IN_DOCTEST,\n            spans,\n            \"unit tests in doctest are not executed\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/doc/too_long_first_doc_paragraph.rs",
    "content": "use rustc_errors::Applicability;\nuse rustc_hir::attrs::AttributeKind;\nuse rustc_hir::{Attribute, Item, ItemKind};\nuse rustc_lint::LateContext;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::source::snippet_opt;\n\nuse super::TOO_LONG_FIRST_DOC_PARAGRAPH;\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    item: &Item<'_>,\n    attrs: &[Attribute],\n    mut first_paragraph_len: usize,\n    check_private_items: bool,\n) {\n    if !check_private_items && !cx.effective_visibilities.is_exported(item.owner_id.def_id) {\n        return;\n    }\n    if first_paragraph_len <= 200\n        || !matches!(\n            item.kind,\n            // This is the list of items which can be documented AND are displayed on the module\n            // page. So associated items or impl blocks are not part of this list.\n            ItemKind::Static(..)\n                | ItemKind::Const(..)\n                | ItemKind::Fn { .. }\n                | ItemKind::Macro(..)\n                | ItemKind::Mod(..)\n                | ItemKind::TyAlias(..)\n                | ItemKind::Enum(..)\n                | ItemKind::Struct(..)\n                | ItemKind::Union(..)\n                | ItemKind::Trait(..)\n                | ItemKind::TraitAlias(..)\n        )\n    {\n        return;\n    }\n\n    let mut spans = Vec::new();\n    let mut should_suggest_empty_doc = false;\n\n    for attr in attrs {\n        if let Attribute::Parsed(AttributeKind::DocComment { span, comment, .. }) = attr {\n            spans.push(span);\n            let doc = comment.as_str();\n            let doc = doc.trim();\n            if spans.len() == 1 {\n                // We make this suggestion only if the first doc line ends with a punctuation\n                // because it might just need to add an empty line with `///`.\n                should_suggest_empty_doc = doc.ends_with('.') || doc.ends_with('!') || doc.ends_with('?');\n            } else if spans.len() == 2 {\n                // We make this suggestion only if the second doc line is not empty.\n                should_suggest_empty_doc &= !doc.is_empty();\n            }\n\n            let len = doc.chars().count();\n            if len >= first_paragraph_len {\n                break;\n            }\n            first_paragraph_len -= len;\n        }\n    }\n\n    let &[first_span, .., last_span] = spans.as_slice() else {\n        return;\n    };\n    if is_from_proc_macro(cx, item) {\n        return;\n    }\n\n    span_lint_and_then(\n        cx,\n        TOO_LONG_FIRST_DOC_PARAGRAPH,\n        first_span.with_hi(last_span.lo()),\n        \"first doc comment paragraph is too long\",\n        |diag| {\n            if should_suggest_empty_doc\n                && let Some(second_span) = spans.get(1)\n                && let new_span = first_span.with_hi(second_span.lo()).with_lo(first_span.hi())\n                && let Some(snippet) = snippet_opt(cx, new_span)\n            {\n                let Some(first) = snippet_opt(cx, *first_span) else {\n                    return;\n                };\n                let Some(comment_form) = first.get(..3) else {\n                    return;\n                };\n\n                diag.span_suggestion(\n                    new_span,\n                    \"add an empty line\",\n                    format!(\"{snippet}{comment_form}{snippet}\"),\n                    Applicability::MachineApplicable,\n                );\n            }\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/double_parens.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{HasSession, SpanRangeExt, snippet_with_applicability, snippet_with_context};\nuse rustc_ast::ast::{Expr, ExprKind, MethodCall};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary double parentheses.\n    ///\n    /// ### Why is this bad?\n    /// This makes code harder to read and might indicate a\n    /// mistake.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn simple_double_parens() -> i32 {\n    ///     ((0))\n    /// }\n    ///\n    /// # fn foo(bar: usize) {}\n    /// foo((0));\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn simple_no_parens() -> i32 {\n    ///     (0)\n    /// }\n    ///\n    /// # fn foo(bar: usize) {}\n    /// foo(0);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DOUBLE_PARENS,\n    complexity,\n    \"Warn on unnecessary double parentheses\"\n}\n\ndeclare_lint_pass!(DoubleParens => [DOUBLE_PARENS]);\n\nimpl EarlyLintPass for DoubleParens {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        match &expr.kind {\n            // ((..))\n            // ^^^^^^ expr\n            //  ^^^^  inner\n            ExprKind::Paren(inner)\n                if matches!(inner.kind, ExprKind::Paren(_) | ExprKind::Tup(_))\n                    && expr.span.eq_ctxt(inner.span)\n                    && !expr.span.in_external_macro(cx.sess().source_map())\n                    && check_source(cx, inner) =>\n            {\n                // suggest removing the outer parens\n\n                let mut applicability = Applicability::MachineApplicable;\n                // We don't need to use `snippet_with_context` here, because:\n                // - if `inner`'s `ctxt` is from macro, we don't lint in the first place (see the check above)\n                // - otherwise, calling `snippet_with_applicability` on a not-from-macro span is fine\n                let sugg = snippet_with_applicability(cx.sess(), inner.span, \"_\", &mut applicability);\n                span_lint_and_sugg(\n                    cx,\n                    DOUBLE_PARENS,\n                    expr.span,\n                    \"unnecessary parentheses\",\n                    \"remove them\",\n                    sugg.to_string(),\n                    applicability,\n                );\n            },\n\n            // func((n))\n            // ^^^^^^^^^ expr\n            //      ^^^  arg\n            //       ^   inner\n            ExprKind::Call(_, args) | ExprKind::MethodCall(box MethodCall { args, .. })\n                if let [arg] = &**args\n                    && let ExprKind::Paren(inner) = &arg.kind\n                    && expr.span.eq_ctxt(arg.span)\n                    && !arg.span.in_external_macro(cx.sess().source_map())\n                    && check_source(cx, arg) =>\n            {\n                // suggest removing the inner parens\n\n                let mut applicability = Applicability::MachineApplicable;\n                let sugg = snippet_with_context(cx.sess(), inner.span, arg.span.ctxt(), \"_\", &mut applicability).0;\n                span_lint_and_sugg(\n                    cx,\n                    DOUBLE_PARENS,\n                    arg.span,\n                    \"unnecessary parentheses\",\n                    \"remove them\",\n                    sugg.to_string(),\n                    applicability,\n                );\n            },\n            _ => {},\n        }\n    }\n}\n\n/// Check that the span does indeed look like `(  (..)  )`\nfn check_source(cx: &EarlyContext<'_>, inner: &Expr) -> bool {\n    if let Some(sfr) = inner.span.get_source_range(cx)\n        // this is the same as `SourceFileRange::as_str`, but doesn't apply the range right away, because\n        // we're interested in the source code outside it\n        && let Some(src) = sfr.sf.src.as_ref().map(|src| src.as_str())\n        && let Some((start, outer_after_inner)) = src.split_at_checked(sfr.range.end)\n        && let Some((outer_before_inner, inner)) = start.split_at_checked(sfr.range.start)\n        && outer_before_inner.trim_end().ends_with('(')\n        && inner.starts_with('(')\n        && inner.ends_with(')')\n        && outer_after_inner.trim_start().starts_with(')')\n        // Don't lint macro repetition patterns like `($($result),*)` where parens are necessary\n        && !inner.trim_start_matches('(').trim_start().starts_with(\"$(\")\n    {\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/drop_forget_ref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_must_use_func_call;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::{is_copy, is_must_use_ty};\nuse rustc_hir::{Arm, Expr, ExprKind, LangItem, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\nuse std::borrow::Cow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `std::mem::drop` with a value that does not implement `Drop`.\n    ///\n    /// ### Why is this bad?\n    /// Calling `std::mem::drop` is no different than dropping such a type. A different value may\n    /// have been intended.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo;\n    /// let x = Foo;\n    /// std::mem::drop(x);\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub DROP_NON_DROP,\n    suspicious,\n    \"call to `std::mem::drop` with a value which does not implement `Drop`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `std::mem::forget` with a value that does not implement `Drop`.\n    ///\n    /// ### Why is this bad?\n    /// Calling `std::mem::forget` is no different than dropping such a type. A different value may\n    /// have been intended.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo;\n    /// let x = Foo;\n    /// std::mem::forget(x);\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub FORGET_NON_DROP,\n    suspicious,\n    \"call to `std::mem::forget` with a value which does not implement `Drop`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `std::mem::forget(t)` where `t` is\n    /// `Drop` or has a field that implements `Drop`.\n    ///\n    /// ### Why restrict this?\n    /// `std::mem::forget(t)` prevents `t` from running its destructor, possibly causing leaks.\n    /// It is not possible to detect all means of creating leaks, but it may be desirable to\n    /// prohibit the simple ones.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::mem;\n    /// # use std::rc::Rc;\n    /// mem::forget(Rc::new(55))\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MEM_FORGET,\n    restriction,\n    \"`mem::forget` usage on `Drop` types, likely to cause memory leaks\"\n}\n\ndeclare_lint_pass!(DropForgetRef => [DROP_NON_DROP, FORGET_NON_DROP, MEM_FORGET]);\n\nconst DROP_NON_DROP_SUMMARY: &str = \"call to `std::mem::drop` with a value that does not implement `Drop`. \\\n                                 Dropping such a type only extends its contained lifetimes\";\nconst FORGET_NON_DROP_SUMMARY: &str = \"call to `std::mem::forget` with a value that does not implement `Drop`. \\\n                                   Forgetting such a type is the same as dropping it\";\n\nimpl<'tcx> LateLintPass<'tcx> for DropForgetRef {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Call(path, [arg]) = expr.kind\n            && let ExprKind::Path(ref qpath) = path.kind\n            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()\n            && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id)\n        {\n            let arg_ty = cx.typeck_results().expr_ty(arg);\n            let is_copy = is_copy(cx, arg_ty);\n            let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);\n            let (lint, msg, note_span) = match fn_name {\n                // early return for uplifted lints: dropping_references, dropping_copy_types, forgetting_references,\n                // forgetting_copy_types\n                sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return,\n                sym::mem_forget if arg_ty.is_ref() => return,\n                sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return,\n                sym::mem_forget if is_copy => return,\n                sym::mem_drop if arg_ty.is_lang_item(cx, LangItem::ManuallyDrop) => return,\n                sym::mem_drop\n                    if !(arg_ty.needs_drop(cx.tcx, cx.typing_env())\n                        || is_must_use_func_call(cx, arg)\n                        || is_must_use_ty(cx, arg_ty)\n                        || drop_is_single_call_in_arm) =>\n                {\n                    (DROP_NON_DROP, DROP_NON_DROP_SUMMARY.into(), Some(arg.span))\n                },\n                sym::mem_forget => {\n                    if arg_ty.needs_drop(cx.tcx, cx.typing_env()) {\n                        (\n                            MEM_FORGET,\n                            Cow::Owned(format!(\n                                \"usage of `mem::forget` on {}\",\n                                if arg_ty.ty_adt_def().is_some_and(|def| def.has_dtor(cx.tcx)) {\n                                    \"`Drop` type\"\n                                } else {\n                                    \"type with `Drop` fields\"\n                                }\n                            )),\n                            None,\n                        )\n                    } else {\n                        (FORGET_NON_DROP, FORGET_NON_DROP_SUMMARY.into(), Some(arg.span))\n                    }\n                },\n                _ => return,\n            };\n            span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n                let note = format!(\"argument has type `{arg_ty}`\");\n                if let Some(span) = note_span {\n                    diag.span_note(span, note);\n                } else {\n                    diag.note(note);\n                }\n            });\n        }\n    }\n}\n\n// dropping returned value of a function like in the following snippet is considered idiomatic, see\n// #9482 for examples match <var> {\n//     <pat> => drop(fn_with_side_effect_and_returning_some_value()),\n//     ..\n// }\nfn is_single_call_in_arm<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'_>, drop_expr: &'tcx Expr<'_>) -> bool {\n    if matches!(arg.kind, ExprKind::Call(..) | ExprKind::MethodCall(..))\n        && let Node::Arm(Arm { body, .. }) = cx.tcx.parent_hir_node(drop_expr.hir_id)\n    {\n        return body.hir_id == drop_expr.hir_id;\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/duplicate_mod.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse rustc_ast::ast::{Crate, Inline, Item, ItemKind, ModKind};\nuse rustc_errors::MultiSpan;\nuse rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};\nuse rustc_middle::lint::LevelAndSource;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{FileName, Span};\nuse std::collections::BTreeMap;\nuse std::path::PathBuf;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for files that are included as modules multiple times.\n    ///\n    /// ### Why is this bad?\n    /// Loading a file as a module more than once causes it to be compiled\n    /// multiple times, taking longer and putting duplicate content into the\n    /// module tree.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// // lib.rs\n    /// mod a;\n    /// mod b;\n    /// ```\n    /// ```rust,ignore\n    /// // a.rs\n    /// #[path = \"./b.rs\"]\n    /// mod b;\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```rust,ignore\n    /// // lib.rs\n    /// mod a;\n    /// mod b;\n    /// ```\n    /// ```rust,ignore\n    /// // a.rs\n    /// use crate::b;\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub DUPLICATE_MOD,\n    suspicious,\n    \"file loaded as module multiple times\"\n}\n\nimpl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]);\n\nstruct Modules {\n    local_path: PathBuf,\n    spans: Vec<Span>,\n    lint_levels: Vec<LevelAndSource>,\n}\n\n#[derive(Default)]\npub struct DuplicateMod {\n    /// map from the canonicalized path to `Modules`, `BTreeMap` to make the\n    /// order deterministic for tests\n    modules: BTreeMap<PathBuf, Modules>,\n}\n\nimpl EarlyLintPass for DuplicateMod {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if let ItemKind::Mod(_, _, ModKind::Loaded(_, Inline::No { .. }, mod_spans)) = &item.kind\n            && let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span)\n            && let Some(local_path) = real.into_local_path()\n            && let Ok(absolute_path) = local_path.canonicalize()\n        {\n            let modules = self.modules.entry(absolute_path).or_insert(Modules {\n                local_path,\n                spans: Vec::new(),\n                lint_levels: Vec::new(),\n            });\n            modules.spans.push(item.span_with_attributes());\n            modules.lint_levels.push(cx.get_lint_level(DUPLICATE_MOD));\n        }\n    }\n\n    fn check_crate_post(&mut self, cx: &EarlyContext<'_>, _: &Crate) {\n        for Modules {\n            local_path,\n            spans,\n            lint_levels,\n        } in self.modules.values()\n        {\n            if spans.len() < 2 {\n                continue;\n            }\n\n            // At this point the lint would be emitted\n            assert_eq!(spans.len(), lint_levels.len());\n            let spans: Vec<_> = spans\n                .iter()\n                .zip(lint_levels)\n                .filter_map(|(span, lvl)| {\n                    if let Some(id) = lvl.lint_id {\n                        cx.fulfill_expectation(id);\n                    }\n\n                    (!matches!(lvl.level, Level::Allow | Level::Expect)).then_some(*span)\n                })\n                .collect();\n\n            if spans.len() < 2 {\n                continue;\n            }\n\n            let mut multi_span = MultiSpan::from_spans(spans.clone());\n            let (&first, duplicates) = spans.split_first().unwrap();\n\n            multi_span.push_span_label(first, \"first loaded here\");\n            for &duplicate in duplicates {\n                multi_span.push_span_label(duplicate, \"loaded again here\");\n            }\n\n            span_lint_and_help(\n                cx,\n                DUPLICATE_MOD,\n                multi_span,\n                format!(\"file is loaded as a module multiple times: `{}`\", local_path.display()),\n                None,\n                \"replace all but one `mod` item with `use` items\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/duration_suboptimal_units.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath, RustcVersion};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{self, TyCtxt, UintTy};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for instances where a `std::time::Duration` is constructed using a smaller time unit\n    /// when the value could be expressed more clearly using a larger unit.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Using a smaller unit for a duration that is evenly divisible by a larger unit reduces\n    /// readability. Readers have to mentally convert values, which can be error-prone and makes\n    /// the code less clear.\n    ///\n    /// ### Example\n    /// ```\n    /// use std::time::Duration;\n    ///\n    /// let dur = Duration::from_millis(5_000);\n    /// let dur = Duration::from_secs(180);\n    /// let dur = Duration::from_mins(10 * 60);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```\n    /// use std::time::Duration;\n    ///\n    /// let dur = Duration::from_secs(5);\n    /// let dur = Duration::from_mins(3);\n    /// let dur = Duration::from_hours(10);\n    /// ```\n    #[clippy::version = \"1.95.0\"]\n    pub DURATION_SUBOPTIMAL_UNITS,\n    pedantic,\n    \"constructing a `Duration` using a smaller unit when a larger unit would be more readable\"\n}\n\nimpl_lint_pass!(DurationSuboptimalUnits => [DURATION_SUBOPTIMAL_UNITS]);\n\npub struct DurationSuboptimalUnits {\n    msrv: Msrv,\n    units: Vec<Unit>,\n}\n\nimpl DurationSuboptimalUnits {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        // The order of the units matters, as they are walked top to bottom\n        let mut units = UNITS.to_vec();\n        if tcx.features().enabled(sym::duration_constructors) {\n            units.extend(EXTENDED_UNITS);\n        }\n        Self { msrv: conf.msrv, units }\n    }\n}\n\nimpl LateLintPass<'_> for DurationSuboptimalUnits {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        if !expr.span.in_external_macro(cx.sess().source_map())\n            // Check if a function on std::time::Duration is called\n            && let ExprKind::Call(func, [arg]) = expr.kind\n            && let ExprKind::Path(QPath::TypeRelative(func_ty, func_name)) = func.kind\n            && cx\n                .typeck_results()\n                .node_type(func_ty.hir_id)\n                .is_diag_item(cx, sym::Duration)\n            && matches!(cx.typeck_results().expr_ty_adjusted(arg).kind(), ty::Uint(UintTy::U64))\n            // We intentionally don't want to evaluate referenced constants, as we don't want to\n            // recommend a literal value over using constants:\n            //\n            // let dur = Duration::from_secs(SIXTY);\n            //           ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::from_mins(1)`\n            && let Some(Constant::Int(value)) = ConstEvalCtxt::new(cx).eval_local(arg, expr.span.ctxt())\n            && let Ok(value) = u64::try_from(value) // Cannot fail\n            // There is no need to promote e.g. 0 seconds to 0 hours\n            && value != 0\n            && let Some((promoted_constructor, promoted_value)) = self.promote(cx, func_name.ident.name, value)\n        {\n            span_lint_and_then(\n                cx,\n                DURATION_SUBOPTIMAL_UNITS,\n                expr.span,\n                \"constructing a `Duration` using a smaller unit when a larger unit would be more readable\",\n                |diag| {\n                    let suggestions = vec![\n                        (func_name.ident.span, promoted_constructor.to_string()),\n                        (arg.span, promoted_value.to_string()),\n                    ];\n                    diag.multipart_suggestion(\n                        format!(\"try using {promoted_constructor}\"),\n                        suggestions,\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n    }\n}\n\nimpl DurationSuboptimalUnits {\n    /// Tries to promote the given constructor and value to a bigger time unit and returns the\n    /// promoted constructor name and value.\n    ///\n    /// Returns [`None`] in case no promotion could be done.\n    fn promote(&self, cx: &LateContext<'_>, constructor_name: Symbol, value: u64) -> Option<(Symbol, u64)> {\n        let (best_unit, best_value) = self\n            .units\n            .iter()\n            .skip_while(|unit| unit.constructor_name != constructor_name)\n            .skip(1)\n            .try_fold(\n                (constructor_name, value),\n                |(current_unit, current_value), bigger_unit| {\n                    if let Some(bigger_value) = current_value.div_exact(u64::from(bigger_unit.factor))\n                        && bigger_unit.stable_since.is_none_or(|v| self.msrv.meets(cx, v))\n                    {\n                        ControlFlow::Continue((bigger_unit.constructor_name, bigger_value))\n                    } else {\n                        // We have to break early, as we can't skip versions, as they are needed to\n                        // correctly calculate the promoted value.\n                        ControlFlow::Break((current_unit, current_value))\n                    }\n                },\n            )\n            .into_value();\n        (best_unit != constructor_name).then_some((best_unit, best_value))\n    }\n}\n\n#[derive(Clone, Copy)]\nstruct Unit {\n    /// Name of the constructor on [`Duration`](std::time::Duration) to construct it from the given\n    /// unit, e.g. [`Duration::from_secs`](std::time::Duration::from_secs)\n    constructor_name: Symbol,\n\n    /// The increase factor over the previous (smaller) unit\n    factor: u16,\n\n    /// In what rustc version stable support for this constructor was added.\n    /// We do not need to track the version stable support in const contexts was added, as the const\n    /// stabilization was done in an ascending order of the time unites, so it's always valid to\n    /// promote a const constructor.\n    stable_since: Option<RustcVersion>,\n}\n\n/// Time unit constructors available on stable. The order matters!\nconst UNITS: [Unit; 6] = [\n    Unit {\n        constructor_name: sym::from_nanos,\n        // The value doesn't matter, as there is no previous unit\n        factor: 0,\n        stable_since: Some(msrvs::DURATION_FROM_NANOS_MICROS),\n    },\n    Unit {\n        constructor_name: sym::from_micros,\n        factor: 1_000,\n        stable_since: Some(msrvs::DURATION_FROM_NANOS_MICROS),\n    },\n    Unit {\n        constructor_name: sym::from_millis,\n        factor: 1_000,\n        stable_since: Some(msrvs::DURATION_FROM_MILLIS_SECS),\n    },\n    Unit {\n        constructor_name: sym::from_secs,\n        factor: 1_000,\n        stable_since: Some(msrvs::DURATION_FROM_MILLIS_SECS),\n    },\n    Unit {\n        constructor_name: sym::from_mins,\n        factor: 60,\n        stable_since: Some(msrvs::DURATION_FROM_MINUTES_HOURS),\n    },\n    Unit {\n        constructor_name: sym::from_hours,\n        factor: 60,\n        stable_since: Some(msrvs::DURATION_FROM_MINUTES_HOURS),\n    },\n];\n\n/// Time unit constructors behind the `duration_constructors` feature. The order matters!\nconst EXTENDED_UNITS: [Unit; 2] = [\n    Unit {\n        constructor_name: sym::from_days,\n        factor: 24,\n        stable_since: None,\n    },\n    Unit {\n        constructor_name: sym::from_weeks,\n        factor: 7,\n        stable_since: None,\n    },\n];\n"
  },
  {
    "path": "clippy_lints/src/else_if_without_else.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::ast::{Expr, ExprKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of if expressions with an `else if` branch,\n    /// but without a final `else` branch.\n    ///\n    /// ### Why restrict this?\n    /// Some coding guidelines require this (e.g., MISRA-C:2004 Rule 14.10).\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn a() {}\n    /// # fn b() {}\n    /// # let x: i32 = 1;\n    /// if x.is_positive() {\n    ///     a();\n    /// } else if x.is_negative() {\n    ///     b();\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```no_run\n    /// # fn a() {}\n    /// # fn b() {}\n    /// # let x: i32 = 1;\n    /// if x.is_positive() {\n    ///     a();\n    /// } else if x.is_negative() {\n    ///     b();\n    /// } else {\n    ///     // We don't care about zero.\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ELSE_IF_WITHOUT_ELSE,\n    restriction,\n    \"`if` expression with an `else if`, but without a final `else` branch\"\n}\n\ndeclare_lint_pass!(ElseIfWithoutElse => [ELSE_IF_WITHOUT_ELSE]);\n\nimpl EarlyLintPass for ElseIfWithoutElse {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) {\n        if let ExprKind::If(_, _, Some(ref els)) = item.kind\n            && let ExprKind::If(_, _, None) = els.kind\n            && !item.span.in_external_macro(cx.sess().source_map())\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                ELSE_IF_WITHOUT_ELSE,\n                els.span,\n                \"`if` expression with an `else if`, but without a final `else`\",\n                |diag| {\n                    diag.help(\"add an `else` block here\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/empty_drop.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::peel_blocks;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Body, ExprKind, Impl, ImplItemKind, Item, ItemKind, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for empty `Drop` implementations.\n    ///\n    /// ### Why restrict this?\n    /// Empty `Drop` implementations have no effect when dropping an instance of the type. They are\n    /// most likely useless. However, an empty `Drop` implementation prevents a type from being\n    /// destructured, which might be the intention behind adding the implementation as a marker.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct S;\n    ///\n    /// impl Drop for S {\n    ///     fn drop(&mut self) {}\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct S;\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub EMPTY_DROP,\n    restriction,\n    \"empty `Drop` implementations\"\n}\n\ndeclare_lint_pass!(EmptyDrop => [EMPTY_DROP]);\n\nimpl LateLintPass<'_> for EmptyDrop {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        if let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            items: [child],\n            ..\n        }) = item.kind\n            && of_trait.trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait()\n            && let impl_item_hir = child.hir_id()\n            && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)\n            && let ImplItemKind::Fn(_, b) = &impl_item.kind\n            && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b)\n            && let func_expr = peel_blocks(func_expr)\n            && let ExprKind::Block(block, _) = func_expr.kind\n            && block.stmts.is_empty()\n            && block.expr.is_none()\n        {\n            span_lint_and_then(cx, EMPTY_DROP, item.span, \"empty drop implementation\", |diag| {\n                diag.span_suggestion_hidden(\n                    item.span,\n                    \"try removing this impl\",\n                    String::new(),\n                    Applicability::MaybeIncorrect,\n                );\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/empty_enums.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::span_contains_cfg;\nuse rustc_hir::{Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `enum`s with no variants, which therefore are uninhabited types\n    /// (cannot be instantiated).\n    ///\n    /// As of this writing, the `never_type` is still a nightly-only experimental API.\n    /// Therefore, this lint is only triggered if `#![feature(never_type)]` is enabled.\n    ///\n    /// ### Why is this bad?\n    /// * If you only want a type which can’t be instantiated, you should use [`!`]\n    ///   (the primitive type \"never\"), because [`!`] has more extensive compiler support\n    ///   (type inference, etc.) and implementations of common traits.\n    ///\n    /// * If you need to introduce a distinct type, consider using a [newtype] `struct`\n    ///   containing [`!`] instead (`struct MyType(pub !)`), because it is more idiomatic\n    ///   to use a `struct` rather than an `enum` when an `enum` is unnecessary.\n    ///\n    ///   If you do this, note that the [visibility] of the [`!`] field determines whether\n    ///   the uninhabitedness is visible in documentation, and whether it can be pattern\n    ///   matched to mark code unreachable. If the field is not visible, then the struct\n    ///   acts like any other struct with private fields.\n    ///\n    /// For further information, visit\n    /// [the never type’s documentation][`!`].\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum CannotExist {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #![feature(never_type)]\n    ///\n    /// /// Use the `!` type directly...\n    /// type CannotExist = !;\n    ///\n    /// /// ...or define a newtype which is distinct.\n    /// struct CannotExist2(pub !);\n    /// ```\n    ///\n    /// [`!`]: https://doc.rust-lang.org/std/primitive.never.html\n    /// [cfg]: https://doc.rust-lang.org/reference/conditional-compilation.html\n    /// [newtype]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction\n    /// [visibility]: https://doc.rust-lang.org/reference/visibility-and-privacy.html\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EMPTY_ENUMS,\n    pedantic,\n    \"enum with no variants\"\n}\n\ndeclare_lint_pass!(EmptyEnums => [EMPTY_ENUMS]);\n\nimpl LateLintPass<'_> for EmptyEnums {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        if let ItemKind::Enum(.., def) = item.kind\n            && def.variants.is_empty()\n            // Only suggest the `never_type` if the feature is enabled\n            && cx.tcx.features().never_type()\n            && !span_contains_cfg(cx, item.span)\n        {\n            span_lint_and_help(\n                cx,\n                EMPTY_ENUMS,\n                item.span,\n                \"enum with no variants\",\n                None,\n                \"consider using the uninhabited type `!` (never type) or a wrapper \\\n                around it to introduce a type which can't be instantiated\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/empty_line_after.rs",
    "content": "use std::borrow::Cow;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{SpanRangeExt, snippet_indent};\nuse clippy_utils::tokenize_with_text;\nuse itertools::Itertools;\nuse rustc_ast::token::CommentKind;\nuse rustc_ast::{AssocItemKind, AttrKind, AttrStyle, Attribute, Crate, Item, ItemKind, ModKind, NodeId};\nuse rustc_errors::{Applicability, Diag, SuggestionStyle};\nuse rustc_lexer::TokenKind;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol, kw, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for empty lines after doc comments.\n    ///\n    /// ### Why is this bad?\n    /// The doc comment may have meant to be an inner doc comment, regular\n    /// comment or applied to some old code that is now commented out. If it was\n    /// intended to be a doc comment, then the empty line should be removed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// /// Some doc comment with a blank line after it.\n    ///\n    /// fn f() {}\n    ///\n    /// /// Docs for `old_code`\n    /// // fn old_code() {}\n    ///\n    /// fn new_code() {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// //! Convert it to an inner doc comment\n    ///\n    /// // Or a regular comment\n    ///\n    /// /// Or remove the empty line\n    /// fn f() {}\n    ///\n    /// // /// Docs for `old_code`\n    /// // fn old_code() {}\n    ///\n    /// fn new_code() {}\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub EMPTY_LINE_AFTER_DOC_COMMENTS,\n    suspicious,\n    \"empty line after doc comments\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for empty lines after outer attributes\n    ///\n    /// ### Why is this bad?\n    /// The attribute may have meant to be an inner attribute (`#![attr]`). If\n    /// it was meant to be an outer attribute (`#[attr]`) then the empty line\n    /// should be removed\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[allow(dead_code)]\n    ///\n    /// fn not_quite_good_code() {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// // Good (as inner attribute)\n    /// #![allow(dead_code)]\n    ///\n    /// fn this_is_fine() {}\n    ///\n    /// // or\n    ///\n    /// // Good (as outer attribute)\n    /// #[allow(dead_code)]\n    /// fn this_is_fine_too() {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EMPTY_LINE_AFTER_OUTER_ATTR,\n    suspicious,\n    \"empty line after outer attribute\"\n}\n\nimpl_lint_pass!(EmptyLineAfter => [\n    EMPTY_LINE_AFTER_DOC_COMMENTS,\n    EMPTY_LINE_AFTER_OUTER_ATTR,\n]);\n\n#[derive(Debug)]\nstruct ItemInfo {\n    kind: &'static str,\n    name: Option<Symbol>,\n    span: Span,\n    mod_items: Option<NodeId>,\n}\n\npub struct EmptyLineAfter {\n    items: Vec<ItemInfo>,\n}\n\nimpl EmptyLineAfter {\n    pub fn new() -> Self {\n        Self { items: Vec::new() }\n    }\n}\n\n#[derive(Debug, PartialEq, Clone, Copy)]\nenum StopKind {\n    Attr,\n    Doc(CommentKind),\n}\n\nimpl StopKind {\n    fn is_doc(self) -> bool {\n        matches!(self, StopKind::Doc(_))\n    }\n}\n\n#[derive(Debug)]\nstruct Stop {\n    span: Span,\n    kind: StopKind,\n    first: usize,\n    last: usize,\n    name: Option<Symbol>,\n}\n\nimpl Stop {\n    fn is_outer_attr_only(&self) -> bool {\n        let Some(name) = self.name else {\n            return false;\n        };\n        // Check if the attribute only has effect when as an outer attribute\n        // The below attributes are collected from the builtin attributes of The Rust Reference\n        // https://doc.rust-lang.org/reference/attributes.html#r-attributes.builtin\n        // And the comments below are from compiler errors and warnings\n        matches!(\n            name,\n            // Cannot be used at crate level\n            sym::repr | sym::test | sym::derive | sym::automatically_derived | sym::path | sym::global_allocator |\n            // Only has an effect on macro definitions\n            sym::macro_export |\n            // Only be applied to trait definitions\n            sym::on_unimplemented |\n            // Only be placed on trait implementations\n            sym::do_not_recommend |\n            // Only has an effect on items\n            sym::ignore | sym::should_panic | sym::proc_macro | sym::proc_macro_derive | sym::proc_macro_attribute |\n            // Has no effect when applied to a module\n            sym::must_use |\n            // Should be applied to a foreign function or static\n            sym::link_name | sym::link_ordinal | sym::link_section |\n            // Should be applied to an `extern crate` item\n            sym::no_link |\n            // Should be applied to a free function, impl method or static\n            sym::export_name | sym::no_mangle |\n            // Should be applied to a `static` variable\n            sym::used |\n            // Should be applied to function or closure\n            sym::inline |\n            // Should be applied to a function definition\n            sym::cold | sym::target_feature | sym::track_caller | sym::instruction_set |\n            // Should be applied to a struct or enum\n            sym::non_exhaustive |\n            // Note: No any warning when it as an inner attribute, but it has no effect\n            sym::panic_handler\n        )\n    }\n\n    fn convert_to_inner(&self) -> Option<(Span, String)> {\n        if self.is_outer_attr_only() {\n            return None;\n        }\n        let inner = match self.kind {\n            // #![...]\n            StopKind::Attr => InnerSpan::new(1, 1),\n            // /// or /**\n            //   ^      ^\n            StopKind::Doc(_) => InnerSpan::new(2, 3),\n        };\n        Some((self.span.from_inner(inner), \"!\".into()))\n    }\n\n    fn comment_out(&self, cx: &EarlyContext<'_>, suggestions: &mut Vec<(Span, String)>) {\n        match self.kind {\n            StopKind::Attr => {\n                if cx.sess().source_map().is_multiline(self.span) {\n                    suggestions.extend([\n                        (self.span.shrink_to_lo(), \"/* \".into()),\n                        (self.span.shrink_to_hi(), \" */\".into()),\n                    ]);\n                } else {\n                    suggestions.push((self.span.shrink_to_lo(), \"// \".into()));\n                }\n            },\n            StopKind::Doc(CommentKind::Line) => suggestions.push((self.span.shrink_to_lo(), \"// \".into())),\n            StopKind::Doc(CommentKind::Block) => {\n                // /** outer */  /*! inner */\n                //  ^             ^\n                let asterisk = self.span.from_inner(InnerSpan::new(1, 2));\n                suggestions.push((asterisk, String::new()));\n            },\n        }\n    }\n\n    fn from_attr(cx: &EarlyContext<'_>, attr: &Attribute) -> Option<Self> {\n        let SpanData { lo, hi, .. } = attr.span.data();\n        let file = cx.sess().source_map().lookup_source_file(lo);\n\n        Some(Self {\n            span: attr.span,\n            kind: match attr.kind {\n                AttrKind::Normal(_) => StopKind::Attr,\n                AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind),\n            },\n            first: file.lookup_line(file.relative_position(lo))?,\n            last: file.lookup_line(file.relative_position(hi))?,\n            name: attr.name(),\n        })\n    }\n}\n\n/// Represents a set of attrs/doc comments separated by 1 or more empty lines\n///\n/// ```ignore\n/// /// chunk 1 docs\n/// // not an empty line so also part of chunk 1\n/// #[chunk_1_attrs] // <-- prev_stop\n///\n/// /* gap */\n///\n/// /// chunk 2 docs // <-- next_stop\n/// #[chunk_2_attrs]\n/// ```\nstruct Gap<'a> {\n    /// The span of individual empty lines including the newline at the end of the line\n    empty_lines: Vec<Span>,\n    has_comment: bool,\n    next_stop: &'a Stop,\n    prev_stop: &'a Stop,\n    /// The chunk that includes [`prev_stop`](Self::prev_stop)\n    prev_chunk: &'a [Stop],\n}\n\nimpl<'a> Gap<'a> {\n    fn new(cx: &EarlyContext<'_>, prev_chunk: &'a [Stop], next_chunk: &'a [Stop]) -> Option<Self> {\n        let prev_stop = prev_chunk.last()?;\n        let next_stop = next_chunk.first()?;\n        let gap_span = prev_stop.span.between(next_stop.span);\n        let gap_snippet = gap_span.get_source_text(cx)?;\n\n        let mut has_comment = false;\n        let mut empty_lines = Vec::new();\n\n        for (token, source, inner_span) in tokenize_with_text(&gap_snippet) {\n            match token {\n                TokenKind::BlockComment {\n                    doc_style: None,\n                    terminated: true,\n                }\n                | TokenKind::LineComment { doc_style: None } => has_comment = true,\n                TokenKind::Whitespace => {\n                    let newlines = source.bytes().positions(|b| b == b'\\n');\n                    empty_lines.extend(\n                        newlines\n                            .tuple_windows()\n                            .map(|(a, b)| InnerSpan::new(inner_span.start + a + 1, inner_span.start + b))\n                            .map(|inner_span| gap_span.from_inner(inner_span)),\n                    );\n                },\n                // Ignore cfg_attr'd out attributes as they may contain empty lines, could also be from macro\n                // shenanigans\n                _ => return None,\n            }\n        }\n\n        (!empty_lines.is_empty()).then_some(Self {\n            empty_lines,\n            has_comment,\n            next_stop,\n            prev_stop,\n            prev_chunk,\n        })\n    }\n\n    fn contiguous_empty_lines(&self) -> impl Iterator<Item = Span> + '_ {\n        self.empty_lines\n            // The `+ BytePos(1)` means \"next line\", because each empty line span is \"N:1-N:1\".\n            .chunk_by(|a, b| a.hi() + BytePos(1) == b.lo())\n            .map(|chunk| {\n                let first = chunk.first().expect(\"at least one empty line\");\n                let last = chunk.last().expect(\"at least one empty line\");\n                // The BytePos subtraction here is safe, as before an empty line, there must be at least one\n                // attribute/comment. The span needs to start at the end of the previous line.\n                first.with_lo(first.lo() - BytePos(1)).with_hi(last.hi())\n            })\n    }\n}\n\nimpl EmptyLineAfter {\n    fn check_gaps(&self, cx: &EarlyContext<'_>, gaps: &[Gap<'_>], id: NodeId) {\n        let Some(first_gap) = gaps.first() else {\n            return;\n        };\n        let empty_lines = || gaps.iter().flat_map(|gap| gap.empty_lines.iter().copied());\n        let contiguous_empty_lines = || gaps.iter().flat_map(Gap::contiguous_empty_lines);\n        let mut has_comment = false;\n        let mut has_attr = false;\n        for gap in gaps {\n            has_comment |= gap.has_comment;\n            if !has_attr {\n                has_attr = gap.prev_chunk.iter().any(|stop| stop.kind == StopKind::Attr);\n            }\n        }\n        let kind = first_gap.prev_stop.kind;\n        let (lint, kind_desc) = match kind {\n            StopKind::Attr => (EMPTY_LINE_AFTER_OUTER_ATTR, \"outer attribute\"),\n            StopKind::Doc(_) => (EMPTY_LINE_AFTER_DOC_COMMENTS, \"doc comment\"),\n        };\n        let (lines, are, them) = if empty_lines().nth(1).is_some() {\n            (\"lines\", \"are\", \"them\")\n        } else {\n            (\"line\", \"is\", \"it\")\n        };\n        span_lint_and_then(\n            cx,\n            lint,\n            first_gap.prev_stop.span.to(empty_lines().last().unwrap()),\n            format!(\"empty {lines} after {kind_desc}\"),\n            |diag| {\n                let info = self.items.last().unwrap();\n                diag.span_label(\n                    info.span,\n                    match kind {\n                        StopKind::Attr => format!(\"the attribute applies to this {}\", info.kind),\n                        StopKind::Doc(_) => format!(\"the comment documents this {}\", info.kind),\n                    },\n                );\n\n                diag.multipart_suggestion_with_style(\n                    format!(\"if the empty {lines} {are} unintentional, remove {them}\"),\n                    contiguous_empty_lines()\n                        .map(|empty_lines| (empty_lines, String::new()))\n                        .collect(),\n                    Applicability::MaybeIncorrect,\n                    SuggestionStyle::HideCodeAlways,\n                );\n\n                if has_comment && kind.is_doc() {\n                    // Likely doc comments that applied to some now commented out code\n                    //\n                    // /// Old docs for Foo\n                    // // struct Foo;\n\n                    let mut suggestions = Vec::new();\n                    for stop in gaps.iter().flat_map(|gap| gap.prev_chunk) {\n                        stop.comment_out(cx, &mut suggestions);\n                    }\n                    let name = match info.name {\n                        Some(name) => format!(\"{} `{name}`\", info.kind).into(),\n                        None => Cow::from(\"the following item\"),\n                    };\n                    diag.multipart_suggestion(\n                        format!(\"if the doc comment should not document {name} then comment it out\"),\n                        suggestions,\n                        Applicability::MaybeIncorrect,\n                    );\n                } else {\n                    self.suggest_inner(diag, kind, gaps, id);\n                }\n\n                if kind == StopKind::Doc(CommentKind::Line)\n                    && gaps\n                        .iter()\n                        .all(|gap| !gap.has_comment && gap.next_stop.kind == StopKind::Doc(CommentKind::Line))\n                {\n                    // Commentless empty gaps between line doc comments, possibly intended to be part of the markdown\n\n                    let indent = snippet_indent(cx, first_gap.prev_stop.span).unwrap_or_default();\n                    diag.multipart_suggestion(\n                        format!(\"if the documentation should include the empty {lines} include {them} in the comment\"),\n                        empty_lines()\n                            .map(|empty_line| (empty_line, format!(\"{indent}///\")))\n                            .collect(),\n                        Applicability::MaybeIncorrect,\n                    );\n                }\n            },\n        );\n    }\n\n    /// If the node the attributes/docs apply to is the first in the module/crate suggest converting\n    /// them to inner attributes/docs\n    fn suggest_inner(&self, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>], id: NodeId) {\n        if let Some(parent) = self.items.iter().rev().nth(1)\n            && (parent.kind == \"module\" || parent.kind == \"crate\")\n            && parent.mod_items == Some(id)\n            && let suggestions = gaps\n                .iter()\n                .flat_map(|gap| gap.prev_chunk)\n                .filter_map(Stop::convert_to_inner)\n                .collect::<Vec<_>>()\n            && !suggestions.is_empty()\n        {\n            let desc = if parent.kind == \"module\" {\n                \"parent module\"\n            } else {\n                parent.kind\n            };\n            diag.multipart_suggestion(\n                match kind {\n                    StopKind::Attr => format!(\"if the attribute should apply to the {desc} use an inner attribute\"),\n                    StopKind::Doc(_) => format!(\"if the comment should document the {desc} use an inner doc comment\"),\n                },\n                suggestions,\n                Applicability::MaybeIncorrect,\n            );\n        }\n    }\n\n    fn check_item_kind(\n        &mut self,\n        cx: &EarlyContext<'_>,\n        kind: &ItemKind,\n        ident: Option<Ident>,\n        span: Span,\n        attrs: &[Attribute],\n        id: NodeId,\n    ) {\n        self.items.push(ItemInfo {\n            kind: kind.descr(),\n            name: ident.map(|ident| ident.name),\n            span: match ident {\n                Some(ident) => span.with_hi(ident.span.hi()),\n                None => span.shrink_to_lo(),\n            },\n            mod_items: match kind {\n                ItemKind::Mod(_, _, ModKind::Loaded(items, _, _)) => items\n                    .iter()\n                    .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))\n                    .map(|i| i.id)\n                    .next(),\n                _ => None,\n            },\n        });\n\n        let mut outer = attrs\n            .iter()\n            .filter(|attr| attr.style == AttrStyle::Outer && !attr.span.from_expansion())\n            .map(|attr| Stop::from_attr(cx, attr))\n            .collect::<Option<Vec<_>>>()\n            .unwrap_or_default();\n\n        if outer.is_empty() {\n            return;\n        }\n\n        // Push a fake attribute Stop for the item itself so we check for gaps between the last outer\n        // attr/doc comment and the item they apply to\n        let span = self.items.last().unwrap().span;\n        if !span.from_expansion()\n            && let Ok(line) = cx.sess().source_map().lookup_line(span.lo())\n        {\n            outer.push(Stop {\n                span,\n                kind: StopKind::Attr,\n                first: line.line,\n                // last doesn't need to be accurate here, we don't compare it with anything\n                last: line.line,\n                name: None,\n            });\n        }\n\n        let mut gaps = Vec::new();\n        let mut last = 0;\n        for pos in outer\n            .array_windows()\n            .positions(|[a, b]| b.first.saturating_sub(a.last) > 1)\n        {\n            // we want to be after the first stop in the window\n            let pos = pos + 1;\n            if let Some(gap) = Gap::new(cx, &outer[last..pos], &outer[pos..]) {\n                last = pos;\n                gaps.push(gap);\n            }\n        }\n\n        self.check_gaps(cx, &gaps, id);\n    }\n}\n\nimpl EarlyLintPass for EmptyLineAfter {\n    fn check_crate(&mut self, _: &EarlyContext<'_>, krate: &Crate) {\n        self.items.push(ItemInfo {\n            kind: \"crate\",\n            name: Some(kw::Crate),\n            span: krate.spans.inner_span.with_hi(krate.spans.inner_span.lo()),\n            mod_items: krate\n                .items\n                .iter()\n                .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))\n                .map(|i| i.id)\n                .next(),\n        });\n    }\n\n    fn check_item_post(&mut self, _: &EarlyContext<'_>, _: &Item) {\n        self.items.pop();\n    }\n    fn check_impl_item_post(&mut self, _: &EarlyContext<'_>, _: &Item<AssocItemKind>) {\n        self.items.pop();\n    }\n    fn check_trait_item_post(&mut self, _: &EarlyContext<'_>, _: &Item<AssocItemKind>) {\n        self.items.pop();\n    }\n\n    fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &Item<AssocItemKind>) {\n        self.check_item_kind(\n            cx,\n            &item.kind.clone().into(),\n            item.kind.ident(),\n            item.span,\n            &item.attrs,\n            item.id,\n        );\n    }\n\n    fn check_trait_item(&mut self, cx: &EarlyContext<'_>, item: &Item<AssocItemKind>) {\n        self.check_item_kind(\n            cx,\n            &item.kind.clone().into(),\n            item.kind.ident(),\n            item.span,\n            &item.attrs,\n            item.id,\n        );\n    }\n\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        self.check_item_kind(cx, &item.kind, item.kind.ident(), item.span, &item.attrs, item.id);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/empty_with_brackets.rs",
    "content": "use clippy_utils::attrs::span_contains_cfg;\nuse clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::span_contains_non_whitespace;\nuse rustc_data_structures::fx::{FxIndexMap, IndexEntry};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::DefKind::Ctor;\nuse rustc_hir::def::Res::Def;\nuse rustc_hir::def::{CtorOf, DefKind};\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::{Expr, ExprKind, Item, ItemKind, Node, Pat, PatKind, Path, QPath, Variant, VariantData};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, TyCtxt};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{BytePos, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds enum variants without fields that are declared with empty brackets.\n    ///\n    /// ### Why restrict this?\n    /// Empty brackets after a enum variant declaration are redundant and can be omitted,\n    /// and it may be desirable to do so consistently for style.\n    ///\n    /// However, removing the brackets also introduces a public constant named after the variant,\n    /// so this is not just a syntactic simplification but an API change, and adding them back\n    /// is a *breaking* API change.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum MyEnum {\n    ///     HasData(u8),\n    ///     HasNoData(),       // redundant parentheses\n    ///     NoneHereEither {}, // redundant braces\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// enum MyEnum {\n    ///     HasData(u8),\n    ///     HasNoData,\n    ///     NoneHereEither,\n    /// }\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub EMPTY_ENUM_VARIANTS_WITH_BRACKETS,\n    restriction,\n    \"finds enum variants with empty brackets\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds structs without fields (a so-called \"empty struct\") that are declared with brackets.\n    ///\n    /// ### Why restrict this?\n    /// Empty brackets after a struct declaration can be omitted,\n    /// and it may be desirable to do so consistently for style.\n    ///\n    /// However, removing the brackets also introduces a public constant named after the struct,\n    /// so this is not just a syntactic simplification but an API change, and adding them back\n    /// is a *breaking* API change.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Cookie {}\n    /// struct Biscuit();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct Cookie;\n    /// struct Biscuit;\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub EMPTY_STRUCTS_WITH_BRACKETS,\n    restriction,\n    \"finds struct declarations with empty brackets\"\n}\n\nimpl_lint_pass!(EmptyWithBrackets => [\n    EMPTY_ENUM_VARIANTS_WITH_BRACKETS,\n    EMPTY_STRUCTS_WITH_BRACKETS,\n]);\n\n#[derive(Debug)]\nenum Usage {\n    Unused { redundant_use_sites: Vec<Span> },\n    Used,\n    NoDefinition { redundant_use_sites: Vec<Span> },\n}\n\n#[derive(Default)]\npub struct EmptyWithBrackets {\n    // Value holds `Usage::Used` if the empty tuple variant was used as a function\n    empty_tuple_enum_variants: FxIndexMap<LocalDefId, Usage>,\n}\n\nimpl LateLintPass<'_> for EmptyWithBrackets {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        // FIXME: handle `struct $name {}`\n        if let ItemKind::Struct(ident, generics, var_data) = &item.kind\n            && !item.span.from_expansion()\n            && !ident.span.from_expansion()\n            && has_brackets(var_data)\n            && let span_after_ident = item.span.with_lo(generics.span.hi())\n            && has_no_fields(cx, var_data, span_after_ident)\n        {\n            span_lint_and_then(\n                cx,\n                EMPTY_STRUCTS_WITH_BRACKETS,\n                span_after_ident,\n                \"found empty brackets on struct declaration\",\n                |diagnostic| {\n                    diagnostic.span_suggestion_hidden(\n                        span_after_ident,\n                        \"remove the brackets\",\n                        \";\",\n                        Applicability::Unspecified,\n                    );\n                },\n            );\n        }\n    }\n\n    fn check_variant(&mut self, cx: &LateContext<'_>, variant: &Variant<'_>) {\n        if !variant.span.from_expansion()\n            && !variant.ident.span.from_expansion()\n            && let span_after_ident = variant.span.with_lo(variant.ident.span.hi())\n            && has_no_fields(cx, &variant.data, span_after_ident)\n        {\n            match variant.data {\n                VariantData::Struct { .. } => {\n                    self.add_enum_variant(variant.def_id);\n                },\n                VariantData::Tuple(.., local_def_id) => {\n                    // Don't lint reachable tuple enums\n                    if cx.effective_visibilities.is_reachable(variant.def_id) {\n                        return;\n                    }\n                    self.add_enum_variant(local_def_id);\n                },\n                VariantData::Unit(..) => {},\n            }\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if let Some((def_id, mut span)) = check_expr_for_enum_as_function(cx, expr) {\n            if span.is_empty()\n                && let Some(parentheses_span) = call_parentheses_span(cx.tcx, expr)\n            {\n                span = parentheses_span;\n            }\n\n            if span.is_empty() {\n                // The parentheses are not redundant.\n                self.empty_tuple_enum_variants.insert(def_id, Usage::Used);\n            } else {\n                // Do not count expressions from macro expansion as a redundant use site.\n                if expr.span.from_expansion() {\n                    return;\n                }\n                self.update_enum_variant_usage(def_id, span);\n            }\n        }\n    }\n\n    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {\n        if !pat.span.from_expansion()\n            && let Some((def_id, span)) = check_pat_for_enum_as_function(cx, pat)\n        {\n            self.update_enum_variant_usage(def_id, span);\n        }\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'_>) {\n        for (&local_def_id, usage) in &self.empty_tuple_enum_variants {\n            // Ignore all variants with Usage::Used or Usage::NoDefinition\n            let Usage::Unused { redundant_use_sites } = usage else {\n                continue;\n            };\n\n            // Attempt to fetch the Variant from LocalDefId.\n            let variant = if let Node::Variant(variant) = cx.tcx.hir_node_by_def_id(local_def_id) {\n                variant\n            } else if let Node::Variant(variant) = cx.tcx.hir_node_by_def_id(cx.tcx.local_parent(local_def_id)) {\n                variant\n            } else {\n                continue;\n            };\n\n            // Span of the parentheses in variant definition\n            let span = variant.span.with_lo(variant.ident.span.hi());\n            let span_inner = span\n                .with_lo(SpanRangeExt::trim_start(span, cx).start + BytePos(1))\n                .with_hi(span.hi() - BytePos(1));\n            if span_contains_non_whitespace(cx, span_inner, false) {\n                continue;\n            }\n            span_lint_hir_and_then(\n                cx,\n                EMPTY_ENUM_VARIANTS_WITH_BRACKETS,\n                variant.hir_id,\n                span,\n                \"enum variant has empty brackets\",\n                |diagnostic| {\n                    if redundant_use_sites.is_empty() {\n                        // If there's no redundant use sites, the definition is the only place to modify.\n                        diagnostic.span_suggestion_hidden(\n                            span,\n                            \"remove the brackets\",\n                            \"\",\n                            Applicability::MaybeIncorrect,\n                        );\n                    } else {\n                        let mut parentheses_spans: Vec<_> =\n                            redundant_use_sites.iter().map(|span| (*span, String::new())).collect();\n                        parentheses_spans.push((span, String::new()));\n                        diagnostic.multipart_suggestion(\n                            \"remove the brackets\",\n                            parentheses_spans,\n                            Applicability::MaybeIncorrect,\n                        );\n                    }\n                },\n            );\n        }\n    }\n}\n\nimpl EmptyWithBrackets {\n    fn add_enum_variant(&mut self, local_def_id: LocalDefId) {\n        self.empty_tuple_enum_variants\n            .entry(local_def_id)\n            .and_modify(|entry| {\n                // empty_tuple_enum_variants contains Usage::NoDefinition if the variant was called before\n                // the definition was encountered. Now that there's a\n                // definition, convert it to Usage::Unused.\n                if let Usage::NoDefinition { redundant_use_sites } = entry {\n                    *entry = Usage::Unused {\n                        redundant_use_sites: redundant_use_sites.clone(),\n                    };\n                }\n            })\n            .or_insert_with(|| Usage::Unused {\n                redundant_use_sites: vec![],\n            });\n    }\n\n    fn update_enum_variant_usage(&mut self, def_id: LocalDefId, parentheses_span: Span) {\n        match self.empty_tuple_enum_variants.entry(def_id) {\n            IndexEntry::Occupied(mut e) => {\n                if let Usage::Unused { redundant_use_sites } | Usage::NoDefinition { redundant_use_sites } = e.get_mut()\n                {\n                    redundant_use_sites.push(parentheses_span);\n                }\n            },\n            IndexEntry::Vacant(e) => {\n                // The variant isn't in the IndexMap which means its definition wasn't encountered yet.\n                e.insert(Usage::NoDefinition {\n                    redundant_use_sites: vec![parentheses_span],\n                });\n            },\n        }\n    }\n}\n\nfn has_brackets(var_data: &VariantData<'_>) -> bool {\n    !matches!(var_data, VariantData::Unit(..))\n}\n\nfn has_no_fields(cx: &LateContext<'_>, var_data: &VariantData<'_>, braces_span: Span) -> bool {\n    var_data.fields().is_empty() &&\n    // there might still be field declarations hidden from the AST\n    // (conditionally compiled code using #[cfg(..)])\n    !span_contains_cfg(cx, braces_span)\n}\n\n// If expression HIR ID and callee HIR ID are same, returns the span of the parentheses, else,\n// returns None.\nfn call_parentheses_span(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> Option<Span> {\n    if let Node::Expr(parent) = tcx.parent_hir_node(expr.hir_id)\n        && let ExprKind::Call(callee, ..) = parent.kind\n        && callee.hir_id == expr.hir_id\n    {\n        Some(parent.span.with_lo(expr.span.hi()))\n    } else {\n        None\n    }\n}\n\n// Returns the LocalDefId of the variant being called as a function if it exists.\nfn check_expr_for_enum_as_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(LocalDefId, Span)> {\n    match expr.kind {\n        ExprKind::Path(QPath::Resolved(\n            _,\n            Path {\n                res: Def(Ctor(CtorOf::Variant, _), def_id),\n                span,\n                ..\n            },\n        )) => def_id.as_local().map(|id| (id, span.with_lo(expr.span.hi()))),\n        ExprKind::Struct(qpath, ..)\n            if let Def(DefKind::Variant, mut def_id) = cx.typeck_results().qpath_res(qpath, expr.hir_id) =>\n        {\n            let ty = cx.tcx.type_of(def_id).instantiate_identity();\n            if let ty::FnDef(ctor_def_id, _) = ty.kind() {\n                def_id = *ctor_def_id;\n            }\n\n            def_id.as_local().map(|id| (id, qpath.span().with_lo(expr.span.hi())))\n        },\n        _ => None,\n    }\n}\n\nfn check_pat_for_enum_as_function(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(LocalDefId, Span)> {\n    match pat.kind {\n        PatKind::TupleStruct(qpath, ..)\n            if let Def(Ctor(CtorOf::Variant, _), def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) =>\n        {\n            def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi())))\n        },\n        PatKind::Struct(qpath, ..)\n            if let Def(DefKind::Variant, mut def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) =>\n        {\n            let ty = cx.tcx.type_of(def_id).instantiate_identity();\n            if let ty::FnDef(ctor_def_id, _) = ty.kind() {\n                def_id = *ctor_def_id;\n            }\n\n            def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi())))\n        },\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/endian_bytes.rs",
    "content": "use crate::Lint;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::{is_lint_allowed, sym};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::Ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Symbol;\nuse std::fmt::Write;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of the `to_be_bytes` method and/or the function `from_be_bytes`.\n    ///\n    /// ### Why restrict this?\n    /// To ensure use of little-endian or the target’s endianness rather than big-endian.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let _x = 2i32.to_be_bytes();\n    /// let _y = 2i64.to_be_bytes();\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub BIG_ENDIAN_BYTES,\n    restriction,\n    \"disallows usage of the `to_be_bytes` method\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of the `to_ne_bytes` method and/or the function `from_ne_bytes`.\n    ///\n    /// ### Why restrict this?\n    /// To ensure use of explicitly chosen endianness rather than the target’s endianness,\n    /// such as when implementing network protocols or file formats rather than FFI.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let _x = 2i32.to_ne_bytes();\n    /// let _y = 2i64.to_ne_bytes();\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub HOST_ENDIAN_BYTES,\n    restriction,\n    \"disallows usage of the `to_ne_bytes` method\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of the `to_le_bytes` method and/or the function `from_le_bytes`.\n    ///\n    /// ### Why restrict this?\n    /// To ensure use of big-endian or the target’s endianness rather than little-endian.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let _x = 2i32.to_le_bytes();\n    /// let _y = 2i64.to_le_bytes();\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub LITTLE_ENDIAN_BYTES,\n    restriction,\n    \"disallows usage of the `to_le_bytes` method\"\n}\n\ndeclare_lint_pass!(EndianBytes => [\n    BIG_ENDIAN_BYTES,\n    HOST_ENDIAN_BYTES,\n    LITTLE_ENDIAN_BYTES,\n]);\n\nconst HOST_NAMES: [Symbol; 2] = [sym::from_ne_bytes, sym::to_ne_bytes];\nconst LITTLE_NAMES: [Symbol; 2] = [sym::from_le_bytes, sym::to_le_bytes];\nconst BIG_NAMES: [Symbol; 2] = [sym::from_be_bytes, sym::to_be_bytes];\n\n#[derive(Clone, Debug)]\nenum LintKind {\n    Host,\n    Little,\n    Big,\n}\n\n#[derive(Clone, Copy, PartialEq)]\nenum Prefix {\n    From,\n    To,\n}\n\nimpl LintKind {\n    fn allowed(&self, cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n        is_lint_allowed(cx, self.as_lint(), expr.hir_id)\n    }\n\n    fn as_lint(&self) -> &'static Lint {\n        match self {\n            LintKind::Host => HOST_ENDIAN_BYTES,\n            LintKind::Little => LITTLE_ENDIAN_BYTES,\n            LintKind::Big => BIG_ENDIAN_BYTES,\n        }\n    }\n\n    fn as_name(&self, prefix: Prefix) -> Symbol {\n        let index = usize::from(prefix == Prefix::To);\n\n        match self {\n            LintKind::Host => HOST_NAMES[index],\n            LintKind::Little => LITTLE_NAMES[index],\n            LintKind::Big => BIG_NAMES[index],\n        }\n    }\n}\n\nimpl LateLintPass<'_> for EndianBytes {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let (prefix, name, ty_expr) = match expr.kind {\n            ExprKind::MethodCall(method_name, receiver, [], ..) => (Prefix::To, method_name.ident.name, receiver),\n            ExprKind::Call(function, ..)\n                if let ExprKind::Path(qpath) = function.kind\n                    && let Some(def_id) = cx.qpath_res(&qpath, function.hir_id).opt_def_id()\n                    && let Some(function_name) = cx.get_def_path(def_id).last() =>\n            {\n                (Prefix::From, *function_name, expr)\n            },\n            _ => return,\n        };\n        if !expr.span.in_external_macro(cx.sess().source_map())\n            && let ty = cx.typeck_results().expr_ty(ty_expr)\n            && ty.is_primitive_ty()\n        {\n            maybe_lint_endian_bytes(cx, expr, prefix, name, ty);\n        }\n    }\n}\n\nfn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: Prefix, name: Symbol, ty: Ty<'_>) {\n    let ne = LintKind::Host.as_name(prefix);\n    let le = LintKind::Little.as_name(prefix);\n    let be = LintKind::Big.as_name(prefix);\n\n    let (lint, other_lints) = match name {\n        name if name == ne => ((&LintKind::Host), [(&LintKind::Little), (&LintKind::Big)]),\n        name if name == le => ((&LintKind::Little), [(&LintKind::Host), (&LintKind::Big)]),\n        name if name == be => ((&LintKind::Big), [(&LintKind::Host), (&LintKind::Little)]),\n        _ => return,\n    };\n\n    span_lint_and_then(\n        cx,\n        lint.as_lint(),\n        expr.span,\n        format!(\n            \"usage of the {}`{ty}::{}`{}\",\n            if prefix == Prefix::From { \"function \" } else { \"\" },\n            lint.as_name(prefix),\n            if prefix == Prefix::To { \" method\" } else { \"\" },\n        ),\n        move |diag| {\n            // all lints disallowed, don't give help here\n            if [&[lint], other_lints.as_slice()]\n                .concat()\n                .iter()\n                .all(|lint| !lint.allowed(cx, expr))\n            {\n                return;\n            }\n\n            // ne_bytes and all other lints allowed\n            if lint.as_name(prefix) == ne && other_lints.iter().all(|lint| lint.allowed(cx, expr)) {\n                diag.help(\"specify the desired endianness explicitly\");\n                return;\n            }\n\n            // le_bytes where ne_bytes allowed but be_bytes is not, or le_bytes where ne_bytes allowed but\n            // le_bytes is not\n            if (lint.as_name(prefix) == le || lint.as_name(prefix) == be) && LintKind::Host.allowed(cx, expr) {\n                diag.help(\"use the native endianness instead\");\n                return;\n            }\n\n            let allowed_lints = other_lints.iter().filter(|lint| lint.allowed(cx, expr));\n            let len = allowed_lints.clone().count();\n\n            let mut help_str = \"use \".to_owned();\n\n            for (i, lint) in allowed_lints.enumerate() {\n                let only_one = len == 1;\n                if !only_one {\n                    help_str.push_str(\"either of \");\n                }\n\n                write!(help_str, \"`{ty}::{}` \", lint.as_name(prefix)).unwrap();\n\n                if i != len && !only_one {\n                    help_str.push_str(\"or \");\n                }\n            }\n            help_str.push_str(\"instead\");\n            diag.help(help_str);\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/entry.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};\nuse clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context};\nuse clippy_utils::ty::is_copy;\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{\n    SpanlessEq, can_move_expr_to_closure_no_visit, desugar_await, higher, is_expr_final_block_expr,\n    is_expr_used_or_unified, paths, peel_hir_expr_while, span_contains_non_whitespace, sym,\n};\nuse core::fmt::{self, Write};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::hir_id::HirIdSet;\nuse rustc_hir::intravisit::{Visitor, walk_body, walk_expr};\nuse rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{DUMMY_SP, Span, SyntaxContext};\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `contains_key` + `insert` on `HashMap`\n    /// or `BTreeMap`.\n    ///\n    /// ### Why is this bad?\n    /// Using `entry` is more efficient.\n    ///\n    /// ### Known problems\n    /// The suggestion may have type inference errors in some cases. e.g.\n    /// ```no_run\n    /// let mut map = std::collections::HashMap::new();\n    /// let _ = if !map.contains_key(&0) {\n    ///     map.insert(0, 0)\n    /// } else {\n    ///     None\n    /// };\n    /// ```\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::collections::HashMap;\n    /// # let mut map = HashMap::new();\n    /// # let k = 1;\n    /// # let v = 1;\n    /// if !map.contains_key(&k) {\n    ///     map.insert(k, v);\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::collections::HashMap;\n    /// # let mut map = HashMap::new();\n    /// # let k = 1;\n    /// # let v = 1;\n    /// map.entry(k).or_insert(v);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MAP_ENTRY,\n    perf,\n    \"use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`\"\n}\n\ndeclare_lint_pass!(HashMapPass => [MAP_ENTRY]);\n\nimpl<'tcx> LateLintPass<'tcx> for HashMapPass {\n    #[expect(clippy::too_many_lines)]\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        let Some(higher::If {\n            cond: cond_expr,\n            then: then_expr,\n            r#else: else_expr,\n        }) = higher::If::hir(expr)\n        else {\n            return;\n        };\n\n        let Some((map_ty, contains_expr)) = try_parse_contains(cx, cond_expr) else {\n            return;\n        };\n\n        let Some(then_search) = find_insert_calls(cx, &contains_expr, then_expr) else {\n            return;\n        };\n\n        let lint_msg = format!(\"usage of `contains_key` followed by `insert` on a `{}`\", map_ty.name());\n        let mut app = Applicability::MachineApplicable;\n        let map_str = snippet_with_context(cx, contains_expr.map.span, contains_expr.call_ctxt, \"..\", &mut app).0;\n        let key_str = snippet_with_context(cx, contains_expr.key.span, contains_expr.call_ctxt, \"..\", &mut app).0;\n\n        let sugg = if let Some(else_expr) = else_expr {\n            let Some(else_search) = find_insert_calls(cx, &contains_expr, else_expr) else {\n                return;\n            };\n\n            if then_search.edits.is_empty() && else_search.edits.is_empty() {\n                // No insertions\n                return;\n            } else if then_search.is_key_used_and_no_copy || else_search.is_key_used_and_no_copy {\n                // If there are other uses of the key, and the key is not copy,\n                // we cannot perform a fix automatically, but continue to emit a lint.\n                None\n            } else if then_search.edits.is_empty() || else_search.edits.is_empty() {\n                // if .. { insert } else { .. } or if .. { .. } else { insert }\n                let ((then_str, entry_kind), else_str) = match (else_search.edits.is_empty(), contains_expr.negated) {\n                    (true, true) => (\n                        then_search.snippet_vacant(cx, then_expr.span, &mut app),\n                        snippet_with_applicability(cx, else_expr.span, \"{ .. }\", &mut app),\n                    ),\n                    (true, false) => (\n                        then_search.snippet_occupied(cx, then_expr.span, &mut app),\n                        snippet_with_applicability(cx, else_expr.span, \"{ .. }\", &mut app),\n                    ),\n                    (false, true) => (\n                        else_search.snippet_occupied(cx, else_expr.span, &mut app),\n                        snippet_with_applicability(cx, then_expr.span, \"{ .. }\", &mut app),\n                    ),\n                    (false, false) => (\n                        else_search.snippet_vacant(cx, else_expr.span, &mut app),\n                        snippet_with_applicability(cx, then_expr.span, \"{ .. }\", &mut app),\n                    ),\n                };\n                Some(format!(\n                    \"if let {}::{entry_kind} = {map_str}.entry({key_str}) {then_str} else {else_str}\",\n                    map_ty.entry_path(),\n                ))\n            } else {\n                // if .. { insert } else { insert }\n                let ((then_str, then_entry), (else_str, else_entry)) = if contains_expr.negated {\n                    (\n                        then_search.snippet_vacant(cx, then_expr.span, &mut app),\n                        else_search.snippet_occupied(cx, else_expr.span, &mut app),\n                    )\n                } else {\n                    (\n                        then_search.snippet_occupied(cx, then_expr.span, &mut app),\n                        else_search.snippet_vacant(cx, else_expr.span, &mut app),\n                    )\n                };\n                let indent_str = snippet_indent(cx, expr.span);\n                let indent_str = indent_str.as_deref().unwrap_or(\"\");\n                Some(format!(\n                    \"match {map_str}.entry({key_str}) {{\\n{indent_str}    {entry}::{then_entry} => {}\\n\\\n                        {indent_str}    {entry}::{else_entry} => {}\\n{indent_str}}}\",\n                    reindent_multiline(&then_str, true, Some(4 + indent_str.len())),\n                    reindent_multiline(&else_str, true, Some(4 + indent_str.len())),\n                    entry = map_ty.entry_path(),\n                ))\n            }\n        } else {\n            if then_search.edits.is_empty() {\n                // no insertions\n                return;\n            }\n\n            // if .. { insert }\n            if !then_search.allow_insert_closure {\n                let (body_str, entry_kind) = if contains_expr.negated {\n                    then_search.snippet_vacant(cx, then_expr.span, &mut app)\n                } else {\n                    then_search.snippet_occupied(cx, then_expr.span, &mut app)\n                };\n                Some(format!(\n                    \"if let {}::{entry_kind} = {map_str}.entry({key_str}) {body_str}\",\n                    map_ty.entry_path(),\n                ))\n            } else if let Some(insertion) = then_search.as_single_insertion()\n                && let span_in_between = then_expr.span.shrink_to_lo().between(insertion.call.span)\n                && let span_in_between = span_in_between.split_at(1).1\n                && !span_contains_non_whitespace(cx, span_in_between, true)\n            {\n                let value_str = snippet_with_context(cx, insertion.value.span, then_expr.span.ctxt(), \"..\", &mut app).0;\n                if contains_expr.negated {\n                    if insertion.value.can_have_side_effects() {\n                        Some(format!(\"{map_str}.entry({key_str}).or_insert_with(|| {value_str});\"))\n                    } else {\n                        Some(format!(\"{map_str}.entry({key_str}).or_insert({value_str});\"))\n                    }\n                } else {\n                    // TODO: suggest using `if let Some(v) = map.get_mut(k) { .. }` here.\n                    // This would need to be a different lint.\n                    return;\n                }\n            } else {\n                let block_str = then_search.snippet_closure(cx, then_expr.span, &mut app);\n                if contains_expr.negated {\n                    Some(format!(\"{map_str}.entry({key_str}).or_insert_with(|| {block_str});\"))\n                } else {\n                    // TODO: suggest using `if let Some(v) = map.get_mut(k) { .. }` here.\n                    // This would need to be a different lint.\n                    return;\n                }\n            }\n        };\n\n        if let Some(sugg) = sugg {\n            span_lint_and_sugg(cx, MAP_ENTRY, expr.span, lint_msg, \"try\", sugg, app);\n        } else {\n            span_lint_and_help(\n                cx,\n                MAP_ENTRY,\n                expr.span,\n                lint_msg,\n                None,\n                format!(\n                    \"consider using the `Entry` API: https://doc.rust-lang.org/std/collections/struct.{}.html#entry-api\",\n                    map_ty.name()\n                ),\n            );\n        }\n    }\n}\n\n#[derive(Clone, Copy)]\nenum MapType {\n    Hash,\n    BTree,\n}\nimpl MapType {\n    fn name(self) -> &'static str {\n        match self {\n            Self::Hash => \"HashMap\",\n            Self::BTree => \"BTreeMap\",\n        }\n    }\n    fn entry_path(self) -> &'static str {\n        match self {\n            Self::Hash => \"std::collections::hash_map::Entry\",\n            Self::BTree => \"std::collections::btree_map::Entry\",\n        }\n    }\n}\n\n/// Details on an expression checking whether a map contains a key.\n///\n/// For instance, with the following:\n/// ```ignore\n/// !!!self.the_map.contains_key(\"the_key\")\n/// ```\n///\n/// - `negated` will be set to `true` (the 3 `!` negate the condition)\n/// - `map` will be the `self.the_map` expression\n/// - `key` will be the `\"the_key\"` expression\nstruct ContainsExpr<'tcx> {\n    /// Whether the check for `contains_key` was negated.\n    negated: bool,\n    /// The map on which the check is performed.\n    map: &'tcx Expr<'tcx>,\n    /// The key that is checked to be contained.\n    key: &'tcx Expr<'tcx>,\n    /// The context of the whole condition expression.\n    call_ctxt: SyntaxContext,\n}\n\n/// Inspect the given expression and return details about the `contains_key` check.\n///\n/// If the given expression is not a `contains_key` check against a `BTreeMap` or a `HashMap`,\n/// return `None`.\nfn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Option<(MapType, ContainsExpr<'tcx>)> {\n    let mut negated = false;\n    let expr = peel_hir_expr_while(expr, |e| match e.kind {\n        ExprKind::Unary(UnOp::Not, e) => {\n            negated = !negated;\n            Some(e)\n        },\n        _ => None,\n    });\n\n    if let ExprKind::MethodCall(_, map, [arg], _) = expr.kind\n        && let Expr {\n            kind: ExprKind::AddrOf(_, _, key),\n            span: key_span,\n            ..\n        } = arg\n        && key_span.eq_ctxt(expr.span)\n    {\n        let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;\n        let expr = ContainsExpr {\n            negated,\n            map,\n            key,\n            call_ctxt: expr.span.ctxt(),\n        };\n        match cx.tcx.get_diagnostic_name(id) {\n            Some(sym::btreemap_contains_key) => Some((MapType::BTree, expr)),\n            Some(sym::hashmap_contains_key) => Some((MapType::Hash, expr)),\n            _ => None,\n        }\n    } else {\n        None\n    }\n}\n\n/// Details on an expression inserting a key into a map.\n///\n/// For instance, on the following:\n/// ```ignore\n/// self.the_map.insert(\"the_key\", 3 + 4);\n/// ```\n///\n/// - `map` will be the `self.the_map` expression\n/// - `key` will be the `\"the_key\"` expression\n/// - `value` will be the `3 + 4` expression\nstruct InsertExpr<'tcx> {\n    /// The map into which the insertion is performed.\n    map: &'tcx Expr<'tcx>,\n    /// The key at which to insert.\n    key: &'tcx Expr<'tcx>,\n    /// The value to insert.\n    value: &'tcx Expr<'tcx>,\n}\n\n/// Inspect the given expression and return details about the `insert` call.\n///\n/// If the given expression is not an `insert` call into a `BTreeMap` or a `HashMap`, return `None`.\nfn try_parse_insert<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<InsertExpr<'tcx>> {\n    if let ExprKind::MethodCall(_, map, [key, value], _) = expr.kind {\n        let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;\n        if let Some(insert) = cx.tcx.get_diagnostic_name(id)\n            && matches!(insert, sym::btreemap_insert | sym::hashmap_insert)\n        {\n            Some(InsertExpr { map, key, value })\n        } else {\n            None\n        }\n    } else {\n        None\n    }\n}\n\n/// An edit that will need to be made to move the expression to use the entry api\n#[derive(Clone, Copy)]\nenum Edit<'tcx> {\n    /// A semicolon that needs to be removed. Used to create a closure for `insert_with`.\n    RemoveSemi(Span),\n    /// An insertion into the map.\n    Insertion(Insertion<'tcx>),\n}\nimpl<'tcx> Edit<'tcx> {\n    fn as_insertion(self) -> Option<Insertion<'tcx>> {\n        if let Self::Insertion(i) = self { Some(i) } else { None }\n    }\n}\n#[derive(Clone, Copy, Debug)]\nstruct Insertion<'tcx> {\n    call: &'tcx Expr<'tcx>,\n    value: &'tcx Expr<'tcx>,\n}\n\n/// This visitor needs to do multiple things:\n/// * Find all usages of the map. An insertion can only be made before any other usages of the map.\n/// * Determine if there's an insertion using the same key. There's no need for the entry api\n///   otherwise.\n/// * Determine if the final statement executed is an insertion. This is needed to use\n///   `or_insert_with`.\n/// * Determine if there's any sub-expression that can't be placed in a closure.\n/// * Determine if there's only a single insert statement. `or_insert` can be used in this case.\n#[expect(clippy::struct_excessive_bools)]\nstruct InsertSearcher<'cx, 'tcx> {\n    cx: &'cx LateContext<'tcx>,\n    /// The map expression used in the contains call.\n    map: &'tcx Expr<'tcx>,\n    /// The key expression used in the contains call.\n    key: &'tcx Expr<'tcx>,\n    /// The context of the top level block. All insert calls must be in the same context.\n    ctxt: SyntaxContext,\n    /// The spanless equality utility used to compare expressions.\n    spanless_eq: SpanlessEq<'cx, 'tcx>,\n    /// Whether this expression can be safely moved into a closure.\n    allow_insert_closure: bool,\n    /// Whether this expression can use the entry api.\n    can_use_entry: bool,\n    /// Whether this expression is the final expression in this code path. This may be a statement.\n    in_tail_pos: bool,\n    /// Is this expression a single insert. A slightly better suggestion can be made in this case.\n    is_single_insert: bool,\n    /// If the visitor has seen the map being used.\n    is_map_used: bool,\n    /// If the visitor has seen the key being used.\n    is_key_used: bool,\n    /// The locations where changes need to be made for the suggestion.\n    edits: Vec<Edit<'tcx>>,\n    /// A stack of loops the visitor is currently in.\n    loops: Vec<HirId>,\n    /// Local variables created in the expression. These don't need to be captured.\n    locals: HirIdSet,\n    /// Whether the map is a non-async-aware `MutexGuard`.\n    map_is_mutex_guard: bool,\n}\nimpl<'tcx> InsertSearcher<'_, 'tcx> {\n    /// Visit the expression as a branch in control flow. Multiple insert calls can be used, but\n    /// only if they are on separate code paths. This will return whether the map was used in the\n    /// given expression.\n    fn visit_cond_arm(&mut self, e: &'tcx Expr<'_>) -> bool {\n        let is_map_used = self.is_map_used;\n        let in_tail_pos = self.in_tail_pos;\n        self.visit_expr(e);\n        let res = self.is_map_used;\n        self.is_map_used = is_map_used;\n        self.in_tail_pos = in_tail_pos;\n        res\n    }\n\n    /// Visit an expression which is not itself in a tail position, but other sibling expressions\n    /// may be. e.g. if conditions\n    fn visit_non_tail_expr(&mut self, e: &'tcx Expr<'_>) {\n        let in_tail_pos = self.in_tail_pos;\n        self.in_tail_pos = false;\n        self.visit_expr(e);\n        self.in_tail_pos = in_tail_pos;\n    }\n\n    /// Visit the key and value expression of an insert expression.\n    /// There may not be uses of the map in either of those two either.\n    fn visit_insert_expr_arguments(&mut self, e: &InsertExpr<'tcx>) {\n        let in_tail_pos = self.in_tail_pos;\n        let allow_insert_closure = self.allow_insert_closure;\n        let is_single_insert = self.is_single_insert;\n        walk_expr(self, e.key);\n        walk_expr(self, e.value);\n        self.in_tail_pos = in_tail_pos;\n        self.allow_insert_closure = allow_insert_closure;\n        self.is_single_insert = is_single_insert;\n    }\n}\nimpl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {\n    fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {\n        match stmt.kind {\n            StmtKind::Semi(e) => {\n                self.visit_expr(e);\n\n                if self.in_tail_pos && self.allow_insert_closure {\n                    // The spans are used to slice the top level expression into multiple parts. This requires that\n                    // they all come from the same part of the source code.\n                    if stmt.span.ctxt() == self.ctxt && e.span.ctxt() == self.ctxt {\n                        self.edits\n                            .push(Edit::RemoveSemi(stmt.span.trim_start(e.span).unwrap_or(DUMMY_SP)));\n                    } else {\n                        self.allow_insert_closure = false;\n                    }\n                }\n            },\n            StmtKind::Expr(e) => self.visit_expr(e),\n            StmtKind::Let(l) => {\n                self.visit_pat(l.pat);\n                if let Some(e) = l.init {\n                    self.allow_insert_closure &= !self.in_tail_pos;\n                    self.in_tail_pos = false;\n                    self.is_single_insert = false;\n                    self.visit_expr(e);\n                }\n                if let Some(els) = &l.els {\n                    self.visit_block(els);\n                }\n            },\n            StmtKind::Item(_) => {\n                self.allow_insert_closure &= !self.in_tail_pos;\n                self.is_single_insert = false;\n            },\n        }\n    }\n\n    fn visit_block(&mut self, block: &'tcx Block<'_>) {\n        // If the block is in a tail position, then the last expression (possibly a statement) is in the\n        // tail position. The rest, however, are not.\n        match (block.stmts, block.expr) {\n            ([], None) => {\n                self.allow_insert_closure &= !self.in_tail_pos;\n            },\n            ([], Some(expr)) => self.visit_expr(expr),\n            (stmts, Some(expr)) => {\n                let in_tail_pos = self.in_tail_pos;\n                self.in_tail_pos = false;\n                for stmt in stmts {\n                    self.visit_stmt(stmt);\n                }\n                self.in_tail_pos = in_tail_pos;\n                self.visit_expr(expr);\n            },\n            ([stmts @ .., stmt], None) => {\n                let in_tail_pos = self.in_tail_pos;\n                self.in_tail_pos = false;\n                for stmt in stmts {\n                    self.visit_stmt(stmt);\n                }\n                self.in_tail_pos = in_tail_pos;\n                self.visit_stmt(stmt);\n            },\n        }\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        if !self.can_use_entry {\n            return;\n        }\n\n        match try_parse_insert(self.cx, expr) {\n            Some(insert_expr) if self.spanless_eq.eq_expr(self.map, insert_expr.map) => {\n                self.visit_insert_expr_arguments(&insert_expr);\n                // Multiple inserts, inserts with a different key, and inserts from a macro can't use the entry api.\n                if self.is_map_used\n                    || !self.spanless_eq.eq_expr(self.key, insert_expr.key)\n                    || expr.span.ctxt() != self.ctxt\n                {\n                    self.can_use_entry = false;\n                    return;\n                }\n\n                self.edits.push(Edit::Insertion(Insertion {\n                    call: expr,\n                    value: insert_expr.value,\n                }));\n                self.is_map_used = true;\n                self.allow_insert_closure &= self.in_tail_pos;\n\n                // The value doesn't affect whether there is only a single insert expression.\n                let is_single_insert = self.is_single_insert;\n                self.visit_non_tail_expr(insert_expr.value);\n                self.is_single_insert = is_single_insert;\n            },\n            _ if is_any_expr_in_map_used(self.cx, &mut self.spanless_eq, self.map, expr) => {\n                self.is_map_used = true;\n            },\n            _ if self.spanless_eq.eq_expr(self.key, expr) => {\n                self.is_key_used = true;\n            },\n            _ => match expr.kind {\n                ExprKind::If(cond_expr, then_expr, Some(else_expr)) => {\n                    self.is_single_insert = false;\n                    self.visit_non_tail_expr(cond_expr);\n                    // Each branch may contain its own insert expression.\n                    let mut is_map_used = self.visit_cond_arm(then_expr);\n                    is_map_used |= self.visit_cond_arm(else_expr);\n                    self.is_map_used = is_map_used;\n                },\n                ExprKind::Match(scrutinee_expr, arms, _) => {\n                    // If the map is a non-async-aware `MutexGuard` and\n                    // `.await` expression appears alongside map insertion in the same `then` or `else` block,\n                    // we cannot suggest using `entry()` because it would hold the lock across the await point,\n                    // triggering `await_holding_lock` and risking deadlock.\n                    if self.map_is_mutex_guard && desugar_await(expr).is_some() {\n                        self.can_use_entry = false;\n                    }\n                    self.is_single_insert = false;\n                    self.visit_non_tail_expr(scrutinee_expr);\n                    // Each branch may contain its own insert expression.\n                    let mut is_map_used = self.is_map_used;\n                    for arm in arms {\n                        self.visit_pat(arm.pat);\n                        if let Some(guard) = arm.guard {\n                            self.visit_non_tail_expr(guard);\n                        }\n                        is_map_used |= self.visit_cond_arm(arm.body);\n                    }\n                    self.is_map_used = is_map_used;\n                },\n                ExprKind::Loop(block, ..) => {\n                    self.loops.push(expr.hir_id);\n                    self.is_single_insert = false;\n                    self.allow_insert_closure &= !self.in_tail_pos;\n                    // Don't allow insertions inside of a loop.\n                    let edit_len = self.edits.len();\n                    self.visit_block(block);\n                    if self.edits.len() != edit_len {\n                        self.can_use_entry = false;\n                    }\n                    self.loops.pop();\n                },\n                ExprKind::Block(block, _) => self.visit_block(block),\n                ExprKind::InlineAsm(_) => {\n                    self.can_use_entry = false;\n                },\n                ExprKind::Closure(closure) => walk_body(self, self.cx.tcx.hir_body(closure.body)),\n                _ => {\n                    self.allow_insert_closure &= !self.in_tail_pos;\n                    self.allow_insert_closure &=\n                        can_move_expr_to_closure_no_visit(self.cx, expr, &self.loops, &self.locals);\n                    // Sub expressions are no longer in the tail position.\n                    self.is_single_insert = false;\n                    self.in_tail_pos = false;\n                    walk_expr(self, expr);\n                },\n            },\n        }\n    }\n\n    fn visit_pat(&mut self, p: &'tcx Pat<'tcx>) {\n        p.each_binding_or_first(&mut |_, id, _, _| {\n            self.locals.insert(id);\n        });\n    }\n}\n\n/// Check if the given expression is used for each sub-expression in the given map.\n/// For example, in map `a.b.c.my_map`, The expression `a.b.c.my_map`, `a.b.c`, `a.b`, and `a` are\n/// all checked.\nfn is_any_expr_in_map_used<'tcx>(\n    cx: &LateContext<'tcx>,\n    spanless_eq: &mut SpanlessEq<'_, 'tcx>,\n    map: &'tcx Expr<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n) -> bool {\n    for_each_expr(cx, map, |e| {\n        if spanless_eq.eq_expr(e, expr) {\n            return ControlFlow::Break(());\n        }\n        ControlFlow::Continue(())\n    })\n    .is_some()\n}\n\nstruct InsertSearchResults<'tcx> {\n    edits: Vec<Edit<'tcx>>,\n    allow_insert_closure: bool,\n    is_single_insert: bool,\n    is_key_used_and_no_copy: bool,\n}\nimpl<'tcx> InsertSearchResults<'tcx> {\n    fn as_single_insertion(&self) -> Option<Insertion<'tcx>> {\n        self.is_single_insert.then(|| self.edits[0].as_insertion().unwrap())\n    }\n\n    fn snippet(\n        &self,\n        cx: &LateContext<'_>,\n        mut span: Span,\n        app: &mut Applicability,\n        write_wrapped: impl Fn(&mut String, Insertion<'_>, SyntaxContext, &mut Applicability),\n    ) -> String {\n        let ctxt = span.ctxt();\n        let mut res = String::new();\n        for insertion in self.edits.iter().filter_map(|e| e.as_insertion()) {\n            res.push_str(&snippet_with_applicability(\n                cx,\n                span.until(insertion.call.span),\n                \"..\",\n                app,\n            ));\n            if is_expr_used_or_unified(cx.tcx, insertion.call) {\n                write_wrapped(&mut res, insertion, ctxt, app);\n            } else {\n                let _: fmt::Result = write!(\n                    res,\n                    \"e.insert({})\",\n                    snippet_with_context(cx, insertion.value.span, ctxt, \"..\", app).0\n                );\n            }\n            span = span.trim_start(insertion.call.span).unwrap_or(DUMMY_SP);\n        }\n        res.push_str(&snippet_with_applicability(cx, span, \"..\", app));\n        res\n    }\n\n    fn snippet_occupied(&self, cx: &LateContext<'_>, span: Span, app: &mut Applicability) -> (String, &'static str) {\n        (\n            self.snippet(cx, span, app, |res, insertion, ctxt, app| {\n                // Insertion into a map would return `Some(&mut value)`, but the entry returns `&mut value`\n                let _: fmt::Result = write!(\n                    res,\n                    \"Some(e.insert({}))\",\n                    snippet_with_context(cx, insertion.value.span, ctxt, \"..\", app).0\n                );\n            }),\n            \"Occupied(mut e)\",\n        )\n    }\n\n    fn snippet_vacant(&self, cx: &LateContext<'_>, span: Span, app: &mut Applicability) -> (String, &'static str) {\n        (\n            self.snippet(cx, span, app, |res, insertion, ctxt, app| {\n                // Insertion into a map would return `None`, but the entry returns a mutable reference.\n                let _: fmt::Result = if is_expr_final_block_expr(cx.tcx, insertion.call) {\n                    write!(\n                        res,\n                        \"e.insert({});\\n{}None\",\n                        snippet_with_context(cx, insertion.value.span, ctxt, \"..\", app).0,\n                        snippet_indent(cx, insertion.call.span).as_deref().unwrap_or(\"\"),\n                    )\n                } else {\n                    write!(\n                        res,\n                        \"{{ e.insert({}); None }}\",\n                        snippet_with_context(cx, insertion.value.span, ctxt, \"..\", app).0,\n                    )\n                };\n            }),\n            \"Vacant(e)\",\n        )\n    }\n\n    fn snippet_closure(&self, cx: &LateContext<'_>, mut span: Span, app: &mut Applicability) -> String {\n        let ctxt = span.ctxt();\n        let mut res = String::new();\n        for edit in &self.edits {\n            match *edit {\n                Edit::Insertion(insertion) => {\n                    // Cut out the value from `map.insert(key, value)`\n                    res.push_str(&snippet_with_applicability(\n                        cx,\n                        span.until(insertion.call.span),\n                        \"..\",\n                        app,\n                    ));\n                    res.push_str(&snippet_with_context(cx, insertion.value.span, ctxt, \"..\", app).0);\n                    span = span.trim_start(insertion.call.span).unwrap_or(DUMMY_SP);\n                },\n                Edit::RemoveSemi(semi_span) => {\n                    // Cut out the semicolon. This allows the value to be returned from the closure.\n                    res.push_str(&snippet_with_applicability(cx, span.until(semi_span), \"..\", app));\n                    span = span.trim_start(semi_span).unwrap_or(DUMMY_SP);\n                },\n            }\n        }\n        res.push_str(&snippet_with_applicability(cx, span, \"..\", app));\n        res\n    }\n}\n\nfn find_insert_calls<'tcx>(\n    cx: &LateContext<'tcx>,\n    contains_expr: &ContainsExpr<'tcx>,\n    expr: &'tcx Expr<'_>,\n) -> Option<InsertSearchResults<'tcx>> {\n    let mut s = InsertSearcher {\n        cx,\n        map: contains_expr.map,\n        key: contains_expr.key,\n        ctxt: expr.span.ctxt(),\n        spanless_eq: SpanlessEq::new(cx),\n        allow_insert_closure: true,\n        can_use_entry: true,\n        in_tail_pos: true,\n        is_single_insert: true,\n        is_map_used: false,\n        is_key_used: false,\n        edits: Vec::new(),\n        loops: Vec::new(),\n        locals: HirIdSet::default(),\n        map_is_mutex_guard: false,\n    };\n    // Check if the map is a non-async-aware `MutexGuard`\n    if let rustc_middle::ty::Adt(adt, _) = cx.typeck_results().expr_ty(contains_expr.map).kind()\n        && is_mutex_guard(cx, adt.did())\n    {\n        s.map_is_mutex_guard = true;\n    }\n\n    s.visit_expr(expr);\n    if !s.can_use_entry {\n        return None;\n    }\n\n    let is_key_used_and_no_copy = s.is_key_used && !is_copy(cx, cx.typeck_results().expr_ty(contains_expr.key));\n    Some(InsertSearchResults {\n        edits: s.edits,\n        allow_insert_closure: s.allow_insert_closure,\n        is_single_insert: s.is_single_insert,\n        is_key_used_and_no_copy,\n    })\n}\n\nfn is_mutex_guard(cx: &LateContext<'_>, def_id: DefId) -> bool {\n    match cx.tcx.get_diagnostic_name(def_id) {\n        Some(name) => matches!(name, sym::MutexGuard | sym::RwLockReadGuard | sym::RwLockWriteGuard),\n        None => paths::PARKING_LOT_GUARDS.iter().any(|guard| guard.matches(cx, def_id)),\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/enum_clike.rs",
    "content": "use clippy_utils::consts::{Constant, mir_to_const};\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_hir::{Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::util::IntTypeExt;\nuse rustc_middle::ty::{self, IntTy, UintTy};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for C-like enumerations that are\n    /// `repr(isize/usize)` and have values that don't fit into an `i32`.\n    ///\n    /// ### Why is this bad?\n    /// This will truncate the variant value on 32 bit\n    /// architectures, but works fine on 64 bit.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # #[cfg(target_pointer_width = \"64\")]\n    /// #[repr(usize)]\n    /// enum NonPortable {\n    ///     X = 0x1_0000_0000,\n    ///     Y = 0,\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ENUM_CLIKE_UNPORTABLE_VARIANT,\n    correctness,\n    \"C-like enums that are `repr(isize/usize)` and have values that don't fit into an `i32`\"\n}\n\ndeclare_lint_pass!(UnportableVariant => [ENUM_CLIKE_UNPORTABLE_VARIANT]);\n\nimpl<'tcx> LateLintPass<'tcx> for UnportableVariant {\n    #[expect(clippy::cast_possible_wrap)]\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if cx.tcx.data_layout.pointer_size().bits() != 64 {\n            return;\n        }\n        if let ItemKind::Enum(_, _, def) = &item.kind {\n            for var in def.variants {\n                if let Some(anon_const) = &var.disr_expr {\n                    let def_id = cx.tcx.hir_body_owner_def_id(anon_const.body);\n                    let mut ty = cx.tcx.type_of(def_id.to_def_id()).instantiate_identity();\n                    let constant = cx.tcx.const_eval_poly(def_id.to_def_id()).ok();\n                    if let Some(Constant::Int(val)) = constant.and_then(|c| mir_to_const(cx.tcx, c, ty)) {\n                        if let ty::Adt(adt, _) = ty.kind()\n                            && adt.is_enum()\n                        {\n                            ty = adt.repr().discr_type().to_ty(cx.tcx);\n                        }\n                        match ty.kind() {\n                            ty::Int(IntTy::Isize) => {\n                                let val = ((val as i128) << 64) >> 64;\n                                if i32::try_from(val).is_ok() {\n                                    continue;\n                                }\n                            },\n                            ty::Uint(UintTy::Usize) if val > u128::from(u32::MAX) => {},\n                            _ => continue,\n                        }\n                        span_lint(\n                            cx,\n                            ENUM_CLIKE_UNPORTABLE_VARIANT,\n                            var.span,\n                            \"C-like enum variant discriminant is not portable to 32-bit targets\",\n                        );\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/equatable_if_let.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_in_const_context;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::implements_trait;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Pat, PatKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::Ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for pattern matchings that can be expressed using equality.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// * It reads better and has less cognitive load because equality won't cause binding.\n    /// * It is a [Yoda condition](https://en.wikipedia.org/wiki/Yoda_conditions). Yoda conditions are widely\n    /// criticized for increasing the cognitive load of reading the code.\n    /// * Equality is a simple bool expression and can be merged with `&&` and `||` and\n    /// reuse if blocks\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// if let Some(2) = x {\n    ///     do_thing();\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// if x == Some(2) {\n    ///     do_thing();\n    /// }\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub EQUATABLE_IF_LET,\n    nursery,\n    \"using pattern matching instead of equality\"\n}\n\ndeclare_lint_pass!(PatternEquality => [EQUATABLE_IF_LET]);\n\n/// detects if pattern matches just one thing\nfn is_unary_pattern(pat: &Pat<'_>) -> bool {\n    fn array_rec(pats: &[Pat<'_>]) -> bool {\n        pats.iter().all(is_unary_pattern)\n    }\n    match &pat.kind {\n        PatKind::Missing => unreachable!(),\n        PatKind::Slice(_, _, _)\n        | PatKind::Range(_, _, _)\n        | PatKind::Binding(..)\n        | PatKind::Wild\n        | PatKind::Never\n        | PatKind::Or(_)\n        | PatKind::Err(_) => false,\n        PatKind::Struct(_, a, etc) => etc.is_none() && a.iter().all(|x| is_unary_pattern(x.pat)),\n        PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a),\n        PatKind::Ref(x, _, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => is_unary_pattern(x),\n        PatKind::Expr(_) => true,\n    }\n}\n\nfn is_structural_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'tcx>) -> bool {\n    if let Some(def_id) = cx.tcx.lang_items().eq_trait() {\n        implements_trait(cx, ty, def_id, &[other.into()])\n    } else {\n        false\n    }\n}\n\n/// Check if the pattern has any type mismatch that would prevent it from being used in an equality\n/// check. This can happen if the expr has a reference type and the corresponding pattern is a\n/// literal.\nfn contains_type_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {\n    let mut result = false;\n    pat.walk(|p| {\n        if result {\n            return false;\n        }\n\n        if p.span.in_external_macro(cx.sess().source_map()) {\n            return true;\n        }\n\n        let adjust_pat = match p.kind {\n            PatKind::Or([p, ..]) => p,\n            _ => p,\n        };\n\n        if let Some(adjustments) = cx.typeck_results().pat_adjustments().get(adjust_pat.hir_id)\n            && adjustments.first().is_some_and(|first| first.source.is_ref())\n        {\n            result = true;\n            return false;\n        }\n\n        true\n    });\n\n    result\n}\n\nimpl<'tcx> LateLintPass<'tcx> for PatternEquality {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Let(let_expr) = expr.kind\n            && is_unary_pattern(let_expr.pat)\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && !let_expr.pat.span.from_expansion()\n            && !let_expr.init.span.from_expansion()\n        {\n            let exp_ty = cx.typeck_results().expr_ty(let_expr.init);\n            let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);\n\n            let mut app = Applicability::MachineApplicable;\n            let ctxt = expr.span.ctxt();\n\n            if is_structural_partial_eq(cx, exp_ty, pat_ty)\n                && !contains_type_mismatch(cx, let_expr.pat)\n                // Calls to trait methods (`PartialEq::eq` in this case) aren't stable yet. We could _technically_\n                // try looking at whether:\n                // 1) features `const_trait_impl` and `const_cmp` are enabled\n                // 2) implementation of `PartialEq<Rhs=PatTy> for ExpTy` has `fn eq` that is `const`\n                //\n                // but that didn't quite work out (see #15482), so we just reject outright in this case\n                && !is_in_const_context(cx)\n            {\n                span_lint_and_then(\n                    cx,\n                    EQUATABLE_IF_LET,\n                    expr.span,\n                    \"this pattern matching can be expressed using equality\",\n                    |diag| {\n                        let pat_str = {\n                            let str = snippet_with_context(cx, let_expr.pat.span, ctxt, \"..\", &mut app).0;\n                            if let PatKind::Struct(..) = let_expr.pat.kind {\n                                format!(\"({str})\").into()\n                            } else {\n                                str\n                            }\n                        };\n\n                        let sugg = format!(\n                            \"{} == {pat_str}\",\n                            snippet_with_context(cx, let_expr.init.span, ctxt, \"..\", &mut app).0,\n                        );\n                        diag.span_suggestion(expr.span, \"try\", sugg, app);\n                    },\n                );\n            } else {\n                span_lint_and_then(\n                    cx,\n                    EQUATABLE_IF_LET,\n                    expr.span,\n                    \"this pattern matching can be expressed using `matches!`\",\n                    |diag| {\n                        let sugg = format!(\n                            \"matches!({}, {})\",\n                            snippet_with_context(cx, let_expr.init.span, ctxt, \"..\", &mut app).0,\n                            snippet_with_context(cx, let_expr.pat.span, ctxt, \"..\", &mut app).0,\n                        );\n                        diag.span_suggestion(expr.span, \"try\", sugg, app);\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/error_impl_error.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_hir_and_then};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::sym;\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir::def_id::{DefId, LocalDefId};\nuse rustc_hir::{Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Visibility;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for types named `Error` that implement `Error`.\n    ///\n    /// ### Why restrict this?\n    /// It can become confusing when a codebase has 20 types all named `Error`, requiring either\n    /// aliasing them in the `use` statement or qualifying them like `my_module::Error`. This\n    /// hinders comprehension, as it requires you to memorize every variation of importing `Error`\n    /// used across a codebase.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// #[derive(Debug)]\n    /// pub enum Error { ... }\n    ///\n    /// impl std::fmt::Display for Error { ... }\n    ///\n    /// impl std::error::Error for Error { ... }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub ERROR_IMPL_ERROR,\n    restriction,\n    \"exported types named `Error` that implement `Error`\"\n}\n\ndeclare_lint_pass!(ErrorImplError => [ERROR_IMPL_ERROR]);\n\nimpl<'tcx> LateLintPass<'tcx> for ErrorImplError {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        match item.kind {\n            ItemKind::TyAlias(ident, ..)\n                if ident.name == sym::Error\n                    && is_visible_outside_module(cx, item.owner_id.def_id)\n                    && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n                    && let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error)\n                    && implements_trait(cx, ty, error_def_id, &[]) =>\n            {\n                span_lint(\n                    cx,\n                    ERROR_IMPL_ERROR,\n                    ident.span,\n                    \"exported type alias named `Error` that implements `Error`\",\n                );\n            },\n            ItemKind::Impl(imp)\n                if let Some(trait_def_id) = imp.of_trait.and_then(|t| t.trait_ref.trait_def_id())\n                    && let Some(error_def_id) = cx.tcx.get_diagnostic_item(sym::Error)\n                    && error_def_id == trait_def_id\n                    && let Some(def_id) = imp.self_ty.basic_res().opt_def_id().and_then(DefId::as_local)\n                    && let Some(ident) = cx.tcx.opt_item_ident(def_id.to_def_id())\n                    && ident.name == sym::Error\n                    && is_visible_outside_module(cx, def_id) =>\n            {\n                span_lint_hir_and_then(\n                    cx,\n                    ERROR_IMPL_ERROR,\n                    cx.tcx.local_def_id_to_hir_id(def_id),\n                    ident.span,\n                    \"exported type named `Error` that implements `Error`\",\n                    |diag| {\n                        diag.span_note(item.span, \"`Error` was implemented here\");\n                    },\n                );\n            },\n            _ => {},\n        }\n    }\n}\n\n/// Do not lint private `Error`s, i.e., ones without any `pub` (minus `pub(self)` of course) and\n/// which aren't reexported\nfn is_visible_outside_module(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {\n    !matches!(\n        cx.tcx.visibility(def_id),\n        Visibility::Restricted(mod_def_id) if cx.tcx.parent_module_from_def_id(def_id).to_def_id() == mod_def_id\n    )\n}\n"
  },
  {
    "path": "clippy_lints/src/escape.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_hir;\nuse rustc_abi::ExternAbi;\nuse rustc_hir::def::DefKind;\nuse rustc_hir::{Body, FnDecl, HirId, HirIdSet, Node, Pat, PatKind, intravisit};\nuse rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir::FakeReadCause;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::symbol::kw;\n\npub struct BoxedLocal {\n    too_large_for_stack: u64,\n}\n\nimpl BoxedLocal {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            too_large_for_stack: conf.too_large_for_stack,\n        }\n    }\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Box<T>` where an unboxed `T` would\n    /// work fine.\n    ///\n    /// ### Why is this bad?\n    /// This is an unnecessary allocation, and bad for\n    /// performance. It is only necessary to allocate if you wish to move the box\n    /// into something.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(x: Box<u32>) {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn foo(x: u32) {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub BOXED_LOCAL,\n    perf,\n    \"using `Box<T>` where unnecessary\"\n}\n\nimpl_lint_pass!(BoxedLocal => [BOXED_LOCAL]);\n\nfn is_non_trait_box(ty: Ty<'_>) -> bool {\n    ty.boxed_ty().is_some_and(|boxed| !boxed.is_trait())\n}\n\nstruct EscapeDelegate<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    set: HirIdSet,\n    trait_self_ty: Option<Ty<'tcx>>,\n    too_large_for_stack: u64,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for BoxedLocal {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        fn_kind: intravisit::FnKind<'tcx>,\n        _: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        _: Span,\n        fn_def_id: LocalDefId,\n    ) {\n        if let Some(header) = fn_kind.header()\n            && header.abi != ExternAbi::Rust\n        {\n            return;\n        }\n\n        let parent_id = cx\n            .tcx\n            .hir_get_parent_item(cx.tcx.local_def_id_to_hir_id(fn_def_id))\n            .def_id;\n\n        let mut trait_self_ty = None;\n        match cx.tcx.def_kind(parent_id) {\n            // If the method is an impl for a trait, don't warn.\n            DefKind::Impl { of_trait: true } => return,\n\n            // find `self` ty for this trait if relevant\n            DefKind::Trait => {\n                trait_self_ty = Some(TraitRef::identity(cx.tcx, parent_id.to_def_id()).self_ty());\n            },\n\n            _ => {},\n        }\n\n        let mut v = EscapeDelegate {\n            cx,\n            set: HirIdSet::default(),\n            trait_self_ty,\n            too_large_for_stack: self.too_large_for_stack,\n        };\n\n        ExprUseVisitor::for_clippy(cx, fn_def_id, &mut v)\n            .consume_body(body)\n            .into_ok();\n\n        for node in v.set {\n            span_lint_hir(\n                cx,\n                BOXED_LOCAL,\n                node,\n                cx.tcx.hir_span(node),\n                \"local variable doesn't need to be boxed here\",\n            );\n        }\n    }\n}\n\n// TODO: Replace with Map::is_argument(..) when it's fixed\nfn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool {\n    match tcx.hir_node(id) {\n        Node::Pat(Pat {\n            kind: PatKind::Binding(..),\n            ..\n        }) => (),\n        _ => return false,\n    }\n\n    matches!(tcx.parent_hir_node(id), Node::Param(_))\n}\n\nimpl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> {\n    fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {\n        if cmt.place.projections.is_empty()\n            && let PlaceBase::Local(lid) = cmt.place.base\n        {\n            // FIXME(rust/#120456) - is `swap_remove` correct?\n            self.set.swap_remove(&lid);\n        }\n    }\n\n    fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {\n        if cmt.place.projections.is_empty()\n            && let PlaceBase::Local(lid) = cmt.place.base\n        {\n            // FIXME(rust/#120456) - is `swap_remove` correct?\n            self.set.swap_remove(&lid);\n        }\n    }\n\n    fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {\n        if cmt.place.projections.is_empty() && is_argument(self.cx.tcx, cmt.hir_id) {\n            // Skip closure arguments\n            let parent_id = self.cx.tcx.parent_hir_id(cmt.hir_id);\n            if let Node::Expr(..) = self.cx.tcx.parent_hir_node(parent_id) {\n                return;\n            }\n\n            // skip if there is a `self` parameter binding to a type\n            // that contains `Self` (i.e.: `self: Box<Self>`), see #4804\n            if let Some(trait_self_ty) = self.trait_self_ty\n                && self.cx.tcx.hir_name(cmt.hir_id) == kw::SelfLower\n                && cmt.place.ty().contains(trait_self_ty)\n            {\n                return;\n            }\n\n            if is_non_trait_box(cmt.place.ty()) && !self.is_large_box(cmt.place.ty()) {\n                self.set.insert(cmt.hir_id);\n            }\n        }\n    }\n\n    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}\n}\n\nimpl<'tcx> EscapeDelegate<'_, 'tcx> {\n    fn is_large_box(&self, ty: Ty<'tcx>) -> bool {\n        // Large types need to be boxed to avoid stack overflows.\n        if let Some(boxed_ty) = ty.boxed_ty() {\n            self.cx.layout_of(boxed_ty).map_or(0, |l| l.size.bytes()) > self.too_large_for_stack\n        } else {\n            false\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/eta_reduction.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::higher::VecArgs;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::{snippet_opt, snippet_with_applicability};\nuse clippy_utils::usage::{local_used_after_expr, local_used_in};\nuse clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate};\nuse rustc_abi::ExternAbi;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind, find_attr};\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};\nuse rustc_middle::ty::{\n    self, Binder, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, Ty, TypeVisitableExt, TypeckResults,\n};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::sym;\nuse rustc_trait_selection::error_reporting::InferCtxtErrorExt as _;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for closures which just call another function where\n    /// the function can be called directly. `unsafe` functions, calls where types\n    /// get adjusted or where the callee is marked `#[track_caller]` are ignored.\n    ///\n    /// ### Why is this bad?\n    /// Needlessly creating a closure adds code for no benefit\n    /// and gives the optimizer more work.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// xs.map(|x| foo(x))\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// // where `foo(_)` is a plain function that takes the exact argument type of `x`.\n    /// xs.map(foo)\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub REDUNDANT_CLOSURE,\n    style,\n    \"redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for closures which only invoke a method on the closure\n    /// argument and can be replaced by referencing the method directly.\n    ///\n    /// ### Why is this bad?\n    /// It's unnecessary to create the closure.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// Some('a').map(|s| s.to_uppercase());\n    /// ```\n    /// may be rewritten as\n    /// ```rust,ignore\n    /// Some('a').map(char::to_uppercase);\n    /// ```\n    #[clippy::version = \"1.35.0\"]\n    pub REDUNDANT_CLOSURE_FOR_METHOD_CALLS,\n    pedantic,\n    \"redundant closures for method calls\"\n}\n\ndeclare_lint_pass!(EtaReduction => [\n    REDUNDANT_CLOSURE,\n    REDUNDANT_CLOSURE_FOR_METHOD_CALLS,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for EtaReduction {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if let ExprKind::MethodCall(_method, receiver, args, _) = expr.kind {\n            for arg in args {\n                check_closure(cx, Some(receiver), arg);\n            }\n        }\n        if let ExprKind::Call(func, args) = expr.kind {\n            check_closure(cx, None, func);\n            for arg in args {\n                check_closure(cx, None, arg);\n            }\n        }\n    }\n}\n\n#[expect(clippy::too_many_lines)]\nfn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx>>, expr: &Expr<'tcx>) {\n    let body = if let ExprKind::Closure(c) = expr.kind\n        && c.fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer(())))\n        && matches!(c.fn_decl.output, FnRetTy::DefaultReturn(_))\n        && !expr.span.from_expansion()\n    {\n        cx.tcx.hir_body(c.body)\n    } else {\n        return;\n    };\n\n    if body.value.span.from_expansion() {\n        if body.params.is_empty()\n            && let Some(VecArgs::Vec(&[])) = VecArgs::hir(cx, body.value)\n        {\n            let vec_crate = if is_no_std_crate(cx) { \"alloc\" } else { \"std\" };\n            // replace `|| vec![]` with `Vec::new`\n            span_lint_hir_and_then(\n                cx,\n                REDUNDANT_CLOSURE,\n                expr.hir_id,\n                expr.span,\n                \"redundant closure\",\n                |diag| {\n                    diag.span_suggestion(\n                        expr.span,\n                        \"replace the closure with `Vec::new`\",\n                        format!(\"{vec_crate}::vec::Vec::new\"),\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n        // skip `foo(|| macro!())`\n        return;\n    }\n\n    if is_adjusted(cx, body.value) {\n        return;\n    }\n\n    let typeck = cx.typeck_results();\n    let closure = if let ty::Closure(_, closure_subs) = typeck.expr_ty(expr).kind() {\n        closure_subs.as_closure()\n    } else {\n        return;\n    };\n    let closure_sig = cx.tcx.signature_unclosure(closure.sig(), Safety::Safe).skip_binder();\n    match body.value.kind {\n        ExprKind::Call(callee, args)\n            if matches!(\n                callee.kind,\n                ExprKind::Path(QPath::Resolved(..) | QPath::TypeRelative(..))\n            ) =>\n        {\n            let callee_ty_raw = typeck.expr_ty(callee);\n            let callee_ty = callee_ty_raw.peel_refs();\n            if matches!(callee_ty.opt_diag_name(cx), Some(sym::Arc | sym::Rc))\n                || !check_inputs(typeck, body.params, None, args)\n            {\n                return;\n            }\n\n            let callee_ty_adjustments = typeck.expr_adjustments(callee);\n            let callee_ty_adjusted = callee_ty_adjustments.last().map_or(callee_ty, |a| a.target);\n\n            let sig = match *callee_ty_adjusted.kind() {\n                ty::FnDef(def, _) => {\n                    // Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location`\n                    if find_attr!(cx.tcx, def, TrackCaller(..)) {\n                        return;\n                    }\n\n                    cx.tcx.fn_sig(def).skip_binder().skip_binder()\n                },\n                ty::FnPtr(sig_tys, hdr) => sig_tys.with(hdr).skip_binder(),\n                ty::Closure(_, subs) => cx\n                    .tcx\n                    .signature_unclosure(subs.as_closure().sig(), Safety::Safe)\n                    .skip_binder(),\n                _ => {\n                    if typeck.type_dependent_def_id(body.value.hir_id).is_some()\n                        && let subs = typeck.node_args(body.value.hir_id)\n                        && let output = typeck.expr_ty(body.value)\n                        && let ty::Tuple(tys) = *subs.type_at(1).kind()\n                    {\n                        cx.tcx.mk_fn_sig(tys, output, false, Safety::Safe, ExternAbi::Rust)\n                    } else {\n                        return;\n                    }\n                },\n            };\n            if let Some(outer) = outer_receiver\n                && ty_has_static(sig.output())\n                && let generic_args = typeck.node_args(outer.hir_id)\n                // HACK: Given a closure in `T.method(|| f())`, where `fn f() -> U where U: 'static`, `T.method(f)`\n                // will succeed iff `T: 'static`. But the region of `T` is always erased by `typeck.expr_ty()` when\n                // T is a generic type. For example, return type of `Option<String>::as_deref()` is a generic.\n                // So we have a hack like this.\n                && !generic_args.is_empty()\n            {\n                return;\n            }\n            if check_sig(closure_sig, sig)\n                && let generic_args = typeck.node_args(callee.hir_id)\n                // Given some trait fn `fn f() -> ()` and some type `T: Trait`, `T::f` is not\n                // `'static` unless `T: 'static`. The cast `T::f as fn()` will, however, result\n                // in a type which is `'static`.\n                // For now ignore all callee types which reference a type parameter.\n                && !generic_args.types().any(|t| matches!(t.kind(), ty::Param(_)))\n                // Rule out `AsyncFn*`s, because while they can be called as `|x| f(x)`,\n                // they can't be passed directly into a place expecting an `Fn*` (#13892)\n                && let Ok((closure_kind, _)) = cx\n                    .tcx\n                    .infer_ctxt()\n                    .build(cx.typing_mode())\n                    .err_ctxt()\n                    .type_implements_fn_trait(\n                        cx.param_env,\n                        Binder::bind_with_vars(callee_ty_adjusted, List::empty()),\n                        ty::PredicatePolarity::Positive,\n                    )\n            {\n                span_lint_hir_and_then(\n                    cx,\n                    REDUNDANT_CLOSURE,\n                    expr.hir_id,\n                    expr.span,\n                    \"redundant closure\",\n                    |diag| {\n                        if let Some(mut snippet) = snippet_opt(cx, callee.span) {\n                            let n_refs = callee_ty_adjustments\n                                .iter()\n                                .rev()\n                                .fold(0, |acc, adjustment| match adjustment.kind {\n                                    Adjust::Deref(DerefAdjustKind::Overloaded(_)) => acc + 1,\n                                    Adjust::Deref(_) if acc > 0 => acc + 1,\n                                    _ => acc,\n                                });\n                            if n_refs > 0 {\n                                snippet = format!(\"{}{snippet}\", \"*\".repeat(n_refs));\n                            }\n\n                            if callee.res_local_id().is_some_and(|l| {\n                                // FIXME: Do we really need this `local_used_in` check?\n                                // Isn't it checking something like... `callee(callee)`?\n                                // If somehow this check is needed, add some test for it,\n                                // 'cuz currently nothing changes after deleting this check.\n                                local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)\n                            }) {\n                                match closure_kind {\n                                    // Mutable closure is used after current expr; we cannot consume it.\n                                    ClosureKind::FnMut => snippet = format!(\"&mut {snippet}\"),\n                                    ClosureKind::Fn if !callee_ty_raw.is_ref() => {\n                                        snippet = format!(\"&{snippet}\");\n                                    },\n                                    _ => (),\n                                }\n                            }\n\n                            let replace_with = match callee_ty_adjusted.kind() {\n                                ty::FnDef(def, _) => cx.tcx.def_descr(*def),\n                                _ => \"function\",\n                            };\n                            diag.span_suggestion(\n                                expr.span,\n                                format!(\"replace the closure with the {replace_with} itself\"),\n                                snippet,\n                                Applicability::MachineApplicable,\n                            );\n                        }\n                    },\n                );\n            }\n        },\n        ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => {\n            if let Some(method_def_id) = typeck.type_dependent_def_id(body.value.hir_id)\n                && !find_attr!(cx.tcx, method_def_id, TrackCaller(..))\n                && check_sig(closure_sig, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder())\n            {\n                let mut app = Applicability::MachineApplicable;\n                let generic_args = match path.args.and_then(GenericArgs::span_ext) {\n                    Some(span) => format!(\"::{}\", snippet_with_applicability(cx, span, \"<..>\", &mut app)),\n                    None => String::new(),\n                };\n                span_lint_hir_and_then(\n                    cx,\n                    REDUNDANT_CLOSURE_FOR_METHOD_CALLS,\n                    expr.hir_id,\n                    expr.span,\n                    \"redundant closure\",\n                    |diag| {\n                        let args = typeck.node_args(body.value.hir_id);\n                        let caller = self_.hir_id.owner.def_id;\n                        let type_name = get_path_from_caller_to_method_type(cx.tcx, caller, method_def_id, args);\n                        diag.span_suggestion(\n                            expr.span,\n                            \"replace the closure with the method itself\",\n                            format!(\"{}::{}{}\", type_name, path.ident.name, generic_args),\n                            app,\n                        );\n                    },\n                );\n            }\n        },\n        _ => (),\n    }\n}\n\nfn check_inputs(\n    typeck: &TypeckResults<'_>,\n    params: &[Param<'_>],\n    self_arg: Option<&Expr<'_>>,\n    args: &[Expr<'_>],\n) -> bool {\n    params.len() == self_arg.map_or(0, |_| 1) + args.len()\n        && params.iter().zip(self_arg.into_iter().chain(args)).all(|(p, arg)| {\n            matches!(\n                p.pat.kind,\n                PatKind::Binding(BindingMode::NONE, id, _, None)\n                if arg.res_local_id() == Some(id)\n            )\n            // Only allow adjustments which change regions (i.e. re-borrowing).\n            && typeck\n                .expr_adjustments(arg)\n                .last()\n                .is_none_or(|a| a.target == typeck.expr_ty(arg))\n        })\n}\n\nfn check_sig<'tcx>(closure_sig: FnSig<'tcx>, call_sig: FnSig<'tcx>) -> bool {\n    call_sig.safety.is_safe() && !has_late_bound_to_non_late_bound_regions(closure_sig, call_sig)\n}\n\n/// This walks through both signatures and checks for any time a late-bound region is expected by an\n/// `impl Fn` type, but the target signature does not have a late-bound region in the same position.\n///\n/// This is needed because rustc is unable to late bind early-bound regions in a function signature.\nfn has_late_bound_to_non_late_bound_regions(from_sig: FnSig<'_>, to_sig: FnSig<'_>) -> bool {\n    fn check_region(from_region: Region<'_>, to_region: Region<'_>) -> bool {\n        from_region.is_bound() && !to_region.is_bound()\n    }\n\n    fn check_subs(from_subs: &[GenericArg<'_>], to_subs: &[GenericArg<'_>]) -> bool {\n        if from_subs.len() != to_subs.len() {\n            return true;\n        }\n        for (from_arg, to_arg) in to_subs.iter().zip(from_subs) {\n            match (from_arg.kind(), to_arg.kind()) {\n                (GenericArgKind::Lifetime(from_region), GenericArgKind::Lifetime(to_region)) => {\n                    if check_region(from_region, to_region) {\n                        return true;\n                    }\n                },\n                (GenericArgKind::Type(from_ty), GenericArgKind::Type(to_ty)) => {\n                    if check_ty(from_ty, to_ty) {\n                        return true;\n                    }\n                },\n                (GenericArgKind::Const(_), GenericArgKind::Const(_)) => (),\n                _ => return true,\n            }\n        }\n        false\n    }\n\n    fn check_ty(from_ty: Ty<'_>, to_ty: Ty<'_>) -> bool {\n        match (from_ty.kind(), to_ty.kind()) {\n            (&ty::Adt(_, from_subs), &ty::Adt(_, to_subs)) => check_subs(from_subs, to_subs),\n            (&ty::Array(from_ty, _), &ty::Array(to_ty, _)) | (&ty::Slice(from_ty), &ty::Slice(to_ty)) => {\n                check_ty(from_ty, to_ty)\n            },\n            (&ty::Ref(from_region, from_ty, _), &ty::Ref(to_region, to_ty, _)) => {\n                check_region(from_region, to_region) || check_ty(from_ty, to_ty)\n            },\n            (&ty::Tuple(from_tys), &ty::Tuple(to_tys)) => {\n                from_tys.len() != to_tys.len()\n                    || from_tys\n                        .iter()\n                        .zip(to_tys)\n                        .any(|(from_ty, to_ty)| check_ty(from_ty, to_ty))\n            },\n            _ => from_ty.has_bound_regions(),\n        }\n    }\n\n    assert!(from_sig.inputs_and_output.len() == to_sig.inputs_and_output.len());\n    from_sig\n        .inputs_and_output\n        .iter()\n        .zip(to_sig.inputs_and_output)\n        .any(|(from_ty, to_ty)| check_ty(from_ty, to_ty))\n}\n\nfn ty_has_static(ty: Ty<'_>) -> bool {\n    ty.walk()\n        .any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(re) if re.is_static()))\n}\n"
  },
  {
    "path": "clippy_lints/src/excessive_bools.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::{get_parent_as_impl, has_repr_attr, is_bool};\nuse rustc_abi::ExternAbi;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, FnDecl, Item, ItemKind, TraitFn, TraitItem, TraitItemKind, Ty};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for excessive use of\n    /// bools in function definitions.\n    ///\n    /// ### Why is this bad?\n    /// Calls to such functions\n    /// are confusing and error prone, because it's\n    /// hard to remember argument order and you have\n    /// no type system support to back you up. Using\n    /// two-variant enums instead of bools often makes\n    /// API easier to use.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// fn f(is_round: bool, is_hot: bool) { ... }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// enum Shape {\n    ///     Round,\n    ///     Spiky,\n    /// }\n    ///\n    /// enum Temperature {\n    ///     Hot,\n    ///     IceCold,\n    /// }\n    ///\n    /// fn f(shape: Shape, temperature: Temperature) { ... }\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub FN_PARAMS_EXCESSIVE_BOOLS,\n    pedantic,\n    \"using too many bools in function parameters\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for excessive\n    /// use of bools in structs.\n    ///\n    /// ### Why is this bad?\n    /// Excessive bools in a struct is often a sign that\n    /// the type is being used to represent a state\n    /// machine, which is much better implemented as an\n    /// enum.\n    ///\n    /// The reason an enum is better for state machines\n    /// over structs is that enums more easily forbid\n    /// invalid states.\n    ///\n    /// Structs with too many booleans may benefit from refactoring\n    /// into multi variant enums for better readability and API.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct S {\n    ///     is_pending: bool,\n    ///     is_processing: bool,\n    ///     is_finished: bool,\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// enum S {\n    ///     Pending,\n    ///     Processing,\n    ///     Finished,\n    /// }\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub STRUCT_EXCESSIVE_BOOLS,\n    pedantic,\n    \"using too many bools in a struct\"\n}\n\nimpl_lint_pass!(ExcessiveBools => [\n    FN_PARAMS_EXCESSIVE_BOOLS,\n    STRUCT_EXCESSIVE_BOOLS,\n]);\n\npub struct ExcessiveBools {\n    max_struct_bools: u64,\n    max_fn_params_bools: u64,\n}\n\nimpl ExcessiveBools {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            max_struct_bools: conf.max_struct_bools,\n            max_fn_params_bools: conf.max_fn_params_bools,\n        }\n    }\n}\n\nfn has_n_bools<'tcx>(iter: impl Iterator<Item = &'tcx Ty<'tcx>>, mut count: u64) -> bool {\n    iter.filter(|ty| is_bool(ty)).any(|_| {\n        let (x, overflow) = count.overflowing_sub(1);\n        count = x;\n        overflow\n    })\n}\n\nfn check_fn_decl(cx: &LateContext<'_>, decl: &FnDecl<'_>, sp: Span, max: u64) {\n    if has_n_bools(decl.inputs.iter(), max) && !sp.from_expansion() {\n        span_lint_and_help(\n            cx,\n            FN_PARAMS_EXCESSIVE_BOOLS,\n            sp,\n            format!(\"more than {max} bools in function parameters\"),\n            None,\n            \"consider refactoring bools into two-variant enums\",\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ExcessiveBools {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if let ItemKind::Struct(_, _, variant_data) = &item.kind\n            && variant_data.fields().len() as u64 > self.max_struct_bools\n            && has_n_bools(\n                variant_data.fields().iter().map(|field| field.ty),\n                self.max_struct_bools,\n            )\n            && !has_repr_attr(cx, item.hir_id())\n            && !item.span.from_expansion()\n        {\n            span_lint_and_help(\n                cx,\n                STRUCT_EXCESSIVE_BOOLS,\n                item.span,\n                format!(\"more than {} bools in a struct\", self.max_struct_bools),\n                None,\n                \"consider using a state machine or refactoring bools into two-variant enums\",\n            );\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'tcx>) {\n        // functions with a body are already checked by `check_fn`\n        if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind\n            && fn_sig.header.abi == ExternAbi::Rust\n            && fn_sig.decl.inputs.len() as u64 > self.max_fn_params_bools\n        {\n            check_fn_decl(cx, fn_sig.decl, fn_sig.span, self.max_fn_params_bools);\n        }\n    }\n\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        fn_kind: FnKind<'tcx>,\n        fn_decl: &'tcx FnDecl<'tcx>,\n        _: &'tcx Body<'tcx>,\n        span: Span,\n        def_id: LocalDefId,\n    ) {\n        if let Some(fn_header) = fn_kind.header()\n            && fn_header.abi == ExternAbi::Rust\n            && fn_decl.inputs.len() as u64 > self.max_fn_params_bools\n            && get_parent_as_impl(cx.tcx, cx.tcx.local_def_id_to_hir_id(def_id))\n                .is_none_or(|impl_item| impl_item.of_trait.is_none())\n        {\n            check_fn_decl(cx, fn_decl, span, self.max_fn_params_bools);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/excessive_nesting.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::source::snippet;\nuse rustc_ast::node_id::NodeSet;\nuse rustc_ast::visit::{Visitor, walk_block, walk_item};\nuse rustc_ast::{Block, Crate, Inline, Item, ItemKind, ModKind, NodeId};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for blocks which are nested beyond a certain threshold.\n    ///\n    /// 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.\n    ///\n    /// ### Why is this bad?\n    /// It can severely hinder readability.\n    ///\n    /// ### Example\n    /// An example clippy.toml configuration:\n    /// ```toml\n    /// # clippy.toml\n    /// excessive-nesting-threshold = 3\n    /// ```\n    /// ```rust,ignore\n    /// // lib.rs\n    /// pub mod a {\n    ///     pub struct X;\n    ///     impl X {\n    ///         pub fn run(&self) {\n    ///             if true {\n    ///                 // etc...\n    ///             }\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// // a.rs\n    /// fn private_run(x: &X) {\n    ///     if true {\n    ///         // etc...\n    ///     }\n    /// }\n    ///\n    /// pub struct X;\n    /// impl X {\n    ///     pub fn run(&self) {\n    ///         private_run(self);\n    ///     }\n    /// }\n    /// ```\n    /// ```rust,ignore\n    /// // lib.rs\n    /// pub mod a;\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub EXCESSIVE_NESTING,\n    complexity,\n    \"checks for blocks nested beyond a certain threshold\"\n}\n\nimpl_lint_pass!(ExcessiveNesting => [EXCESSIVE_NESTING]);\n\npub struct ExcessiveNesting {\n    pub excessive_nesting_threshold: u64,\n    pub nodes: NodeSet,\n}\n\nimpl ExcessiveNesting {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            excessive_nesting_threshold: conf.excessive_nesting_threshold,\n            nodes: NodeSet::default(),\n        }\n    }\n\n    pub fn check_node_id(&self, cx: &EarlyContext<'_>, span: Span, node_id: NodeId) {\n        if self.nodes.contains(&node_id) {\n            span_lint_and_help(\n                cx,\n                EXCESSIVE_NESTING,\n                span,\n                \"this block is too nested\",\n                None,\n                \"try refactoring your code to minimize nesting\",\n            );\n        }\n    }\n}\n\nimpl EarlyLintPass for ExcessiveNesting {\n    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {\n        if self.excessive_nesting_threshold == 0 {\n            return;\n        }\n\n        let mut visitor = NestingVisitor {\n            conf: self,\n            cx,\n            nest_level: 0,\n        };\n\n        for item in &krate.items {\n            visitor.visit_item(item);\n        }\n    }\n\n    fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) {\n        self.check_node_id(cx, block.span, block.id);\n    }\n\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        self.check_node_id(cx, item.span, item.id);\n    }\n}\n\nstruct NestingVisitor<'conf, 'cx> {\n    conf: &'conf mut ExcessiveNesting,\n    cx: &'cx EarlyContext<'cx>,\n    nest_level: u64,\n}\n\nimpl NestingVisitor<'_, '_> {\n    fn check_indent(&mut self, span: Span, id: NodeId) -> bool {\n        if self.nest_level > self.conf.excessive_nesting_threshold\n            && !span.in_external_macro(self.cx.sess().source_map())\n        {\n            self.conf.nodes.insert(id);\n\n            return true;\n        }\n\n        false\n    }\n}\n\nimpl Visitor<'_> for NestingVisitor<'_, '_> {\n    fn visit_block(&mut self, block: &Block) {\n        if block.span.from_expansion() {\n            return;\n        }\n\n        // TODO: This should be rewritten using `LateLintPass` so we can use `is_from_proc_macro` instead,\n        // but for now, this is fine.\n        let snippet = snippet(self.cx, block.span, \"{}\").trim().to_owned();\n        if !snippet.starts_with('{') || !snippet.ends_with('}') {\n            return;\n        }\n\n        self.nest_level += 1;\n\n        if !self.check_indent(block.span, block.id) {\n            walk_block(self, block);\n        }\n\n        self.nest_level -= 1;\n    }\n\n    fn visit_item(&mut self, item: &Item) {\n        if item.span.from_expansion() {\n            return;\n        }\n\n        match &item.kind {\n            ItemKind::Trait(_) | ItemKind::Impl(_) | ItemKind::Mod(.., ModKind::Loaded(_, Inline::Yes, _)) => {\n                self.nest_level += 1;\n\n                if !self.check_indent(item.span, item.id) {\n                    walk_item(self, item);\n                }\n\n                self.nest_level -= 1;\n            },\n            // Reset nesting level for non-inline modules (since these are in another file)\n            ItemKind::Mod(..) => walk_item(\n                &mut NestingVisitor {\n                    conf: self.conf,\n                    cx: self.cx,\n                    nest_level: 0,\n                },\n                item,\n            ),\n            _ => walk_item(self, item),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/exhaustive_items.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::indent_of;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Item, ItemKind, find_attr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`\n    ///\n    /// ### Why restrict this?\n    /// Making an `enum` exhaustive is a stability commitment: adding a variant is a breaking change.\n    /// A project may wish to ensure that there are no exhaustive enums or that every exhaustive\n    /// `enum` is explicitly `#[allow]`ed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum Foo {\n    ///     Bar,\n    ///     Baz\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[non_exhaustive]\n    /// enum Foo {\n    ///     Bar,\n    ///     Baz\n    /// }\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub EXHAUSTIVE_ENUMS,\n    restriction,\n    \"detects exported enums that have not been marked #[non_exhaustive]\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns on any exported `struct`s that are not tagged `#[non_exhaustive]`\n    ///\n    /// ### Why restrict this?\n    /// Making a `struct` exhaustive is a stability commitment: adding a field is a breaking change.\n    /// A project may wish to ensure that there are no exhaustive structs or that every exhaustive\n    /// `struct` is explicitly `#[allow]`ed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo {\n    ///     bar: u8,\n    ///     baz: String,\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[non_exhaustive]\n    /// struct Foo {\n    ///     bar: u8,\n    ///     baz: String,\n    /// }\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub EXHAUSTIVE_STRUCTS,\n    restriction,\n    \"detects exported structs that have not been marked #[non_exhaustive]\"\n}\n\ndeclare_lint_pass!(ExhaustiveItems => [EXHAUSTIVE_ENUMS, EXHAUSTIVE_STRUCTS]);\n\nimpl LateLintPass<'_> for ExhaustiveItems {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        let (lint, msg, fields) = match item.kind {\n            ItemKind::Enum(..) => (\n                EXHAUSTIVE_ENUMS,\n                \"exported enums should not be exhaustive\",\n                [].as_slice(),\n            ),\n            ItemKind::Struct(_, _, v) if v.fields().iter().all(|f| f.default.is_none()) => (\n                EXHAUSTIVE_STRUCTS,\n                \"exported structs should not be exhaustive\",\n                v.fields(),\n            ),\n            _ => return,\n        };\n        if cx.effective_visibilities.is_exported(item.owner_id.def_id)\n            && let attrs = cx.tcx.hir_attrs(item.hir_id())\n            && !find_attr!(attrs, NonExhaustive(..))\n            && fields.iter().all(|f| cx.tcx.visibility(f.def_id).is_public())\n        {\n            span_lint_and_then(cx, lint, item.span, msg, |diag| {\n                let suggestion_span = item.span.shrink_to_lo();\n                let indent = \" \".repeat(indent_of(cx, item.span).unwrap_or(0));\n                let sugg = format!(\"#[non_exhaustive]\\n{indent}\");\n                diag.span_suggestion_verbose(\n                    suggestion_span,\n                    \"try adding #[non_exhaustive]\",\n                    sugg,\n                    Applicability::MaybeIncorrect,\n                );\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/exit.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::sym;\nuse rustc_hir::{Expr, ExprKind, Item, ItemKind, OwnerNode};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects calls to the `exit()` function that are not in the `main` function. Calls to `exit()`\n    /// immediately terminate the program.\n    ///\n    /// ### Why restrict this?\n    /// `exit()` immediately terminates the program with no information other than an exit code.\n    /// This provides no means to troubleshoot a problem, and may be an unexpected side effect.\n    ///\n    /// Codebases may use this lint to require that all exits are performed either by panicking\n    /// (which produces a message, a code location, and optionally a backtrace)\n    /// or by calling `exit()` from `main()` (which is a single place to look).\n    ///\n    /// ### Good example\n    /// ```no_run\n    /// fn main() {\n    ///     std::process::exit(0);\n    /// }\n    /// ```\n    ///\n    /// ### Bad example\n    /// ```no_run\n    /// fn main() {\n    ///     other_function();\n    /// }\n    ///\n    /// fn other_function() {\n    ///     std::process::exit(0);\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```ignore\n    /// // To provide a stacktrace and additional information\n    /// panic!(\"message\");\n    ///\n    /// // or a main method with a return\n    /// fn main() -> Result<(), i32> {\n    ///     Ok(())\n    /// }\n    /// ```\n    #[clippy::version = \"1.41.0\"]\n    pub EXIT,\n    restriction,\n    \"detects `std::process::exit` calls outside of `main`\"\n}\n\ndeclare_lint_pass!(Exit => [EXIT]);\n\nimpl<'tcx> LateLintPass<'tcx> for Exit {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let ExprKind::Call(path_expr, [_]) = e.kind\n            && let ExprKind::Path(ref path) = path_expr.kind\n            && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id()\n            && cx.tcx.is_diagnostic_item(sym::process_exit, def_id)\n            && let parent = cx.tcx.hir_get_parent_item(e.hir_id)\n            && let OwnerNode::Item(Item{kind: ItemKind::Fn{ ident, .. }, ..}) = cx.tcx.hir_owner_node(parent)\n            // If the next item up is a function we check if it isn't named \"main\"\n            // and only then emit a linter warning\n\n            // if you instead check for the parent of the `exit()` call being the entrypoint function, as this worked before,\n            // in compilation contexts like --all-targets (which include --tests), you get false positives\n            // because in a test context, main is not the entrypoint function\n            && ident.name != sym::main\n        {\n            span_lint(cx, EXIT, e.span, \"usage of `process::exit`\");\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/explicit_write.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{is_expn_of, is_in_test, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BindingMode, Block, BlockCheckMode, Expr, ExprKind, Node, PatKind, QPath, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::ExpnId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `write!()` / `writeln()!` which can be\n    /// replaced with `(e)print!()` / `(e)println!()`\n    ///\n    /// ### Why is this bad?\n    /// Using `(e)println!` is clearer and more concise\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::io::Write;\n    /// # let bar = \"furchtbar\";\n    /// writeln!(&mut std::io::stderr(), \"foo: {:?}\", bar).unwrap();\n    /// writeln!(&mut std::io::stdout(), \"foo: {:?}\", bar).unwrap();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::io::Write;\n    /// # let bar = \"furchtbar\";\n    /// eprintln!(\"foo: {:?}\", bar);\n    /// println!(\"foo: {:?}\", bar);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EXPLICIT_WRITE,\n    complexity,\n    \"using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work\"\n}\n\nimpl_lint_pass!(ExplicitWrite => [EXPLICIT_WRITE]);\n\npub struct ExplicitWrite {\n    format_args: FormatArgsStorage,\n}\n\nimpl ExplicitWrite {\n    pub fn new(format_args: FormatArgsStorage) -> Self {\n        Self { format_args }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ExplicitWrite {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        // match call to unwrap\n        if let ExprKind::MethodCall(unwrap_fun, write_call, [], _) = expr.kind\n            && unwrap_fun.ident.name == sym::unwrap\n            // match call to write_fmt\n            && let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind)\n            && let ExprKind::Call(write_recv_path, []) = write_recv.kind\n            && write_fun.ident.name == sym::write_fmt\n            && let Some(def_id) = write_recv_path.basic_res().opt_def_id()\n        {\n            // match calls to std::io::stdout() / std::io::stderr ()\n            let (dest_name, prefix) = match cx.tcx.get_diagnostic_name(def_id) {\n                Some(sym::io_stdout) => (\"stdout\", \"\"),\n                Some(sym::io_stderr) => (\"stderr\", \"e\"),\n                _ => return,\n            };\n            let Some(format_args) = self.format_args.get(cx, write_arg, ExpnId::root()) else {\n                return;\n            };\n\n            // Performing an explicit write in a test circumvent's libtest's capture of stdio and stdout.\n            if is_in_test(cx.tcx, expr.hir_id) {\n                return;\n            }\n\n            // ordering is important here, since `writeln!` uses `write!` internally\n            let calling_macro = if is_expn_of(write_call.span, sym::writeln).is_some() {\n                Some(\"writeln\")\n            } else if is_expn_of(write_call.span, sym::write).is_some() {\n                Some(\"write\")\n            } else {\n                None\n            };\n\n            // We need to remove the last trailing newline from the string because the\n            // underlying `fmt::write` function doesn't know whether `println!` or `print!` was\n            // used.\n            let (used, sugg_mac) = if let Some(macro_name) = calling_macro {\n                (\n                    format!(\"{macro_name}!({dest_name}(), ...)\"),\n                    macro_name.replace(\"write\", \"print\"),\n                )\n            } else {\n                (format!(\"{dest_name}().write_fmt(...)\"), \"print\".into())\n            };\n            let mut applicability = Applicability::MachineApplicable;\n            let inputs_snippet =\n                snippet_with_applicability(cx, format_args_inputs_span(format_args), \"..\", &mut applicability);\n            span_lint_and_sugg(\n                cx,\n                EXPLICIT_WRITE,\n                expr.span,\n                format!(\"use of `{used}.unwrap()`\"),\n                \"try\",\n                format!(\"{prefix}{sugg_mac}!({inputs_snippet})\"),\n                applicability,\n            );\n        }\n    }\n}\n\n/// If `kind` is a block that looks like `{ let result = $expr; result }` then\n/// returns $expr. Otherwise returns `kind`.\nfn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>) -> &'tcx ExprKind<'hir> {\n    if let ExprKind::Block(block, _label @ None) = kind\n        && let Block {\n            stmts: [Stmt { kind: StmtKind::Let(local), .. }],\n            expr: Some(expr_end_of_block),\n            rules: BlockCheckMode::DefaultBlock,\n            ..\n        } = block\n\n        // Find id of the local that expr_end_of_block resolves to\n        && let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind\n        && let Res::Local(expr_res) = expr_path.res\n        && let Node::Pat(res_pat) = cx.tcx.hir_node(expr_res)\n\n        // Find id of the local we found in the block\n        && let PatKind::Binding(BindingMode::NONE, local_hir_id, _ident, None) = local.pat.kind\n\n        // If those two are the same hir id\n        && res_pat.hir_id == local_hir_id\n\n        && let Some(init) = local.init\n    {\n        return &init.kind;\n    }\n    kind\n}\n"
  },
  {
    "path": "clippy_lints/src/extra_unused_type_parameters.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};\nuse clippy_utils::{is_from_proc_macro, trait_ref_of_method};\nuse rustc_data_structures::fx::{FxHashMap, FxHashSet};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty, walk_unambig_ty};\nuse rustc_hir::{\n    AmbigArg, BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item,\n    ItemKind, PredicateOrigin, Ty, WherePredicate, WherePredicateKind,\n};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::hir::nested_filter;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::{DefId, LocalDefId};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for type parameters in generics that are never used anywhere else.\n    ///\n    /// ### Why is this bad?\n    /// Functions cannot infer the value of unused type parameters; therefore, calling them\n    /// requires using a turbofish, which serves no purpose but to satisfy the compiler.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn unused_ty<T>(x: u8) {\n    ///     // ..\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn no_unused_ty(x: u8) {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"1.69.0\"]\n    pub EXTRA_UNUSED_TYPE_PARAMETERS,\n    complexity,\n    \"unused type parameters in function definitions\"\n}\n\nimpl_lint_pass!(ExtraUnusedTypeParameters => [EXTRA_UNUSED_TYPE_PARAMETERS]);\n\npub struct ExtraUnusedTypeParameters {\n    avoid_breaking_exported_api: bool,\n}\n\nimpl ExtraUnusedTypeParameters {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n        }\n    }\n}\n\n/// A visitor struct that walks a given function and gathers generic type parameters, plus any\n/// trait bounds those parameters have.\nstruct TypeWalker<'cx, 'tcx> {\n    cx: &'cx LateContext<'tcx>,\n    /// Collection of the function's type parameters. Once the function has been walked, this will\n    /// contain only unused type parameters.\n    ty_params: FxHashMap<DefId, Span>,\n    /// Collection of any inline trait bounds corresponding to each type parameter.\n    inline_bounds: FxHashMap<DefId, Span>,\n    /// Collection of any type parameters with trait bounds that appear in a where clause.\n    where_bounds: FxHashSet<DefId>,\n    /// The entire `Generics` object of the function, useful for querying purposes.\n    generics: &'tcx Generics<'tcx>,\n}\n\nimpl<'cx, 'tcx> TypeWalker<'cx, 'tcx> {\n    fn new(cx: &'cx LateContext<'tcx>, generics: &'tcx Generics<'tcx>) -> Self {\n        let ty_params = generics\n            .params\n            .iter()\n            .filter_map(|param| match param.kind {\n                GenericParamKind::Type { synthetic, .. } if !synthetic => Some((param.def_id.into(), param.span)),\n                _ => None,\n            })\n            .collect();\n\n        Self {\n            cx,\n            ty_params,\n            inline_bounds: FxHashMap::default(),\n            where_bounds: FxHashSet::default(),\n            generics,\n        }\n    }\n\n    fn get_bound_span(&self, param: &'tcx GenericParam<'tcx>) -> Span {\n        self.inline_bounds\n            .get(&param.def_id.to_def_id())\n            .map_or(param.span, |bound_span| param.span.with_hi(bound_span.hi()))\n    }\n\n    fn emit_help(&self, spans: Vec<Span>, msg: String, help: &'static str) {\n        span_lint_and_help(self.cx, EXTRA_UNUSED_TYPE_PARAMETERS, spans, msg, None, help);\n    }\n\n    fn emit_sugg(&self, spans: Vec<Span>, msg: String, help: &'static str) {\n        let suggestions: Vec<(Span, String)> = spans.iter().copied().zip(std::iter::repeat(String::new())).collect();\n        span_lint_and_then(self.cx, EXTRA_UNUSED_TYPE_PARAMETERS, spans, msg, |diag| {\n            diag.multipart_suggestion(help, suggestions, Applicability::MachineApplicable);\n        });\n    }\n\n    fn emit_lint(&self) {\n        let explicit_params = self\n            .generics\n            .params\n            .iter()\n            .filter(|param| !param.is_elided_lifetime() && !param.is_impl_trait())\n            .collect::<Vec<_>>();\n\n        let extra_params = explicit_params\n            .iter()\n            .enumerate()\n            .filter(|(_, param)| self.ty_params.contains_key(&param.def_id.to_def_id()))\n            .collect::<Vec<_>>();\n\n        let (msg, help) = match extra_params.len() {\n            0 => return,\n            1 => (\n                format!(\n                    \"type parameter `{}` goes unused in function definition\",\n                    extra_params[0].1.name.ident()\n                ),\n                \"consider removing the parameter\",\n            ),\n            _ => (\n                format!(\n                    \"type parameters go unused in function definition: {}\",\n                    extra_params\n                        .iter()\n                        .map(|(_, param)| param.name.ident().to_string())\n                        .collect::<Vec<_>>()\n                        .join(\", \")\n                ),\n                \"consider removing the parameters\",\n            ),\n        };\n\n        // If any parameters are bounded in where clauses, don't try to form a suggestion.\n        // Otherwise, the leftover where bound would produce code that wouldn't compile.\n        if extra_params\n            .iter()\n            .any(|(_, param)| self.where_bounds.contains(&param.def_id.to_def_id()))\n        {\n            let spans = extra_params\n                .iter()\n                .map(|(_, param)| self.get_bound_span(param))\n                .collect::<Vec<_>>();\n            self.emit_help(spans, msg, help);\n        } else {\n            let spans = if explicit_params.len() == extra_params.len() {\n                vec![self.generics.span] // Remove the entire list of generics\n            } else {\n                // 1. Start from the last extra param\n                // 2. While the params preceding it are also extra, construct spans going from the current param to\n                //    the comma before it\n                // 3. Once this chain of extra params stops, switch to constructing spans going from the current\n                //    param to the comma _after_ it\n                let mut end: Option<LocalDefId> = None;\n                extra_params\n                    .iter()\n                    .rev()\n                    .map(|(idx, param)| {\n                        if let Some(next) = explicit_params.get(idx + 1)\n                            && end != Some(next.def_id)\n                        {\n                            // Extend the current span forward, up until the next param in the list.\n                            param.span.until(next.span)\n                        } else {\n                            // Extend the current span back to include the comma following the previous\n                            // param. If the span of the next param in the list has already been\n                            // extended, we continue the chain. This is why we're iterating in reverse.\n                            end = Some(param.def_id);\n\n                            // idx will never be 0, else we'd be removing the entire list of generics\n                            let prev = explicit_params[idx - 1];\n                            let prev_span = self.get_bound_span(prev);\n                            self.get_bound_span(param).with_lo(prev_span.hi())\n                        }\n                    })\n                    .collect()\n            };\n            self.emit_sugg(spans, msg, help);\n        }\n    }\n}\n\n/// Given a generic bound, if the bound is for a trait that's not a `LangItem`, return the\n/// `LocalDefId` for that trait.\nfn bound_to_trait_def_id(bound: &GenericBound<'_>) -> Option<LocalDefId> {\n    bound.trait_ref()?.trait_def_id()?.as_local()\n}\n\nimpl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_ty(&mut self, t: &'tcx Ty<'tcx, AmbigArg>) {\n        if let Some((def_id, _)) = t.peel_refs().as_generic_param() {\n            self.ty_params.remove(&def_id);\n        } else {\n            walk_ty(self, t);\n        }\n    }\n\n    fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {\n        let span = predicate.span;\n        if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind {\n            // Collect spans for any bounds on type parameters.\n            if let Some((def_id, _)) = predicate.bounded_ty.peel_refs().as_generic_param() {\n                match predicate.origin {\n                    PredicateOrigin::GenericParam => {\n                        self.inline_bounds.insert(def_id, span);\n                    },\n                    PredicateOrigin::WhereClause => {\n                        self.where_bounds.insert(def_id);\n                    },\n                    PredicateOrigin::ImplTrait => (),\n                }\n\n                // If the bound contains non-public traits, err on the safe side and don't lint the\n                // corresponding parameter.\n                if !predicate\n                    .bounds\n                    .iter()\n                    .filter_map(bound_to_trait_def_id)\n                    .all(|id| self.cx.effective_visibilities.is_exported(id))\n                {\n                    self.ty_params.remove(&def_id);\n                }\n            } else {\n                // If the bounded type isn't a generic param, but is instead a concrete generic\n                // type, any params we find nested inside of it are being used as concrete types,\n                // and can therefore can be considered used. So, we're fine to walk the left-hand\n                // side of the where bound.\n                walk_unambig_ty(self, predicate.bounded_ty);\n            }\n            for bound in predicate.bounds {\n                walk_param_bound(self, bound);\n            }\n        }\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\nfn is_empty_body(cx: &LateContext<'_>, body: BodyId) -> bool {\n    matches!(cx.tcx.hir_body(body).value.kind, ExprKind::Block(b, _) if b.stmts.is_empty() && b.expr.is_none())\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if let ItemKind::Fn {\n            generics,\n            body: body_id,\n            ..\n        } = item.kind\n            && !generics.params.is_empty()\n            && !is_empty_body(cx, body_id)\n            && (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))\n            && !item.span.in_external_macro(cx.sess().source_map())\n            && !is_from_proc_macro(cx, item)\n        {\n            let mut walker = TypeWalker::new(cx, generics);\n            walk_item(&mut walker, item);\n            walker.emit_lint();\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'tcx>) {\n        // Only lint on inherent methods, not trait methods.\n        if let ImplItemKind::Fn(.., body_id) = item.kind\n            && !item.generics.params.is_empty()\n            && trait_ref_of_method(cx, item.owner_id).is_none()\n            && !is_empty_body(cx, body_id)\n            && (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))\n            && !item.span.in_external_macro(cx.sess().source_map())\n            && !is_from_proc_macro(cx, item)\n        {\n            let mut walker = TypeWalker::new(cx, item.generics);\n            walk_impl_item(&mut walker, item);\n            walker.emit_lint();\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/fallible_impl_from.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{is_panic, root_macro_call_first_node};\nuse clippy_utils::method_chain_args;\nuse clippy_utils::res::MaybeDef;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`\n    ///\n    /// ### Why is this bad?\n    /// `TryFrom` should be used if there's a possibility of failure.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo(i32);\n    ///\n    /// impl From<String> for Foo {\n    ///     fn from(s: String) -> Self {\n    ///         Foo(s.parse().unwrap())\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// struct Foo(i32);\n    ///\n    /// impl TryFrom<String> for Foo {\n    ///     type Error = ();\n    ///     fn try_from(s: String) -> Result<Self, Self::Error> {\n    ///         if let Ok(parsed) = s.parse() {\n    ///             Ok(Foo(parsed))\n    ///         } else {\n    ///             Err(())\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub FALLIBLE_IMPL_FROM,\n    nursery,\n    \"Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`\"\n}\n\ndeclare_lint_pass!(FallibleImplFrom => [FALLIBLE_IMPL_FROM]);\n\nimpl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {\n        // check for `impl From<???> for ..`\n        if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = &item.kind\n            && let impl_trait_id = cx.tcx.impl_trait_id(item.owner_id)\n            && cx.tcx.is_diagnostic_item(sym::From, impl_trait_id)\n        {\n            lint_impl_body(cx, item.owner_id, item.span);\n        }\n    }\n}\n\nfn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Span) {\n    use rustc_hir::Expr;\n    use rustc_hir::intravisit::{self, Visitor};\n\n    struct FindPanicUnwrap<'a, 'tcx> {\n        lcx: &'a LateContext<'tcx>,\n        typeck_results: &'tcx ty::TypeckResults<'tcx>,\n        result: Vec<Span>,\n    }\n\n    impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> {\n        fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n            if let Some(macro_call) = root_macro_call_first_node(self.lcx, expr)\n                && is_panic(self.lcx, macro_call.def_id)\n            {\n                self.result.push(expr.span);\n            }\n\n            // check for `unwrap`\n            if let Some(arglists) = method_chain_args(expr, &[sym::unwrap]) {\n                let receiver_ty = self.typeck_results.expr_ty(arglists[0].0).peel_refs();\n                if matches!(receiver_ty.opt_diag_name(self.lcx), Some(sym::Option | sym::Result)) {\n                    self.result.push(expr.span);\n                }\n            }\n\n            // and check sub-expressions\n            intravisit::walk_expr(self, expr);\n        }\n    }\n\n    for impl_item in cx\n        .tcx\n        .associated_items(item_def_id)\n        .filter_by_name_unhygienic_and_kind(sym::from, ty::AssocTag::Fn)\n    {\n        let impl_item_def_id = impl_item.def_id.expect_local();\n\n        // check the body for `begin_panic` or `unwrap`\n        let body = cx.tcx.hir_body_owned_by(impl_item_def_id);\n        let mut fpu = FindPanicUnwrap {\n            lcx: cx,\n            typeck_results: cx.tcx.typeck(impl_item_def_id),\n            result: Vec::new(),\n        };\n        fpu.visit_expr(body.value);\n\n        // if we've found one, lint\n        if !fpu.result.is_empty() {\n            span_lint_and_then(\n                cx,\n                FALLIBLE_IMPL_FROM,\n                impl_span,\n                \"consider implementing `TryFrom` instead\",\n                move |diag| {\n                    diag.help(\n                        \"`From` is intended for infallible conversions only. \\\n                        Use `TryFrom` if there's a possibility for the conversion to fail\",\n                    );\n                    diag.span_note(fpu.result, \"potential failure(s)\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/field_scoped_visibility_modifiers.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::ast::{Item, ItemKind, VisibilityKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of scoped visibility modifiers, like `pub(crate)`, on fields. These\n    /// make a field visible within a scope between public and private.\n    ///\n    /// ### Why restrict this?\n    /// Scoped visibility modifiers cause a field to be accessible within some scope between\n    /// public and private, potentially within an entire crate. This allows for fields to be\n    /// non-private while upholding internal invariants, but can be a code smell. Scoped visibility\n    /// requires checking a greater area, potentially an entire crate, to verify that an invariant\n    /// is upheld, and global analysis requires a lot of effort.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub mod public_module {\n    ///     struct MyStruct {\n    ///         pub(crate) first_field: bool,\n    ///         pub(super) second_field: bool\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// pub mod public_module {\n    ///     struct MyStruct {\n    ///         first_field: bool,\n    ///         second_field: bool\n    ///     }\n    ///     impl MyStruct {\n    ///         pub(crate) fn get_first_field(&self) -> bool {\n    ///             self.first_field\n    ///         }\n    ///         pub(super) fn get_second_field(&self) -> bool {\n    ///             self.second_field\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub FIELD_SCOPED_VISIBILITY_MODIFIERS,\n    restriction,\n    \"checks for usage of a scoped visibility modifier, like `pub(crate)`, on fields\"\n}\n\ndeclare_lint_pass!(FieldScopedVisibilityModifiers => [\n    FIELD_SCOPED_VISIBILITY_MODIFIERS,\n]);\n\nimpl EarlyLintPass for FieldScopedVisibilityModifiers {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        let ItemKind::Struct(_, _, ref st) = item.kind else {\n            return;\n        };\n        for field in st.fields() {\n            let VisibilityKind::Restricted { path, .. } = &field.vis.kind else {\n                continue;\n            };\n            if !path.segments.is_empty() && path.segments[0].ident.name == rustc_span::symbol::kw::SelfLower {\n                // pub(self) is equivalent to not using pub at all, so we ignore it\n                continue;\n            }\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                FIELD_SCOPED_VISIBILITY_MODIFIERS,\n                field.vis.span,\n                \"scoped visibility modifier on a field\",\n                |diag| {\n                    diag.help(\"consider making the field private and adding a scoped visibility method for it\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/float_literal.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::{ExprUseNode, expr_use_ctxt, numeric_literal};\nuse rustc_ast::ast::{LitFloatType, LitKind};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, FloatTy};\nuse rustc_session::impl_lint_pass;\nuse std::fmt;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for float literals with a precision greater\n    /// than that supported by the underlying type.\n    ///\n    /// The lint is suppressed for literals with over `const_literal_digits_threshold` digits.\n    ///\n    /// ### Why is this bad?\n    /// Rust will truncate the literal silently.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let v: f32 = 0.123_456_789_9;\n    /// println!(\"{}\", v); //  0.123_456_789\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let v: f64 = 0.123_456_789_9;\n    /// println!(\"{}\", v); //  0.123_456_789_9\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EXCESSIVE_PRECISION,\n    style,\n    \"excessive precision for float literal\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for whole number float literals that\n    /// cannot be represented as the underlying type without loss.\n    ///\n    /// ### Why restrict this?\n    /// If the value was intended to be exact, it will not be.\n    /// This may be especially surprising when the lost precision is to the left of the decimal point.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _: f32 = 16_777_217.0; // 16_777_216.0\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let _: f32 = 16_777_216.0;\n    /// let _: f64 = 16_777_217.0;\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub LOSSY_FLOAT_LITERAL,\n    restriction,\n    \"lossy whole number float literals\"\n}\n\nimpl_lint_pass!(FloatLiteral => [EXCESSIVE_PRECISION, LOSSY_FLOAT_LITERAL]);\n\npub struct FloatLiteral {\n    const_literal_digits_threshold: usize,\n}\n\nimpl FloatLiteral {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            const_literal_digits_threshold: conf.const_literal_digits_threshold,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for FloatLiteral {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        if let hir::ExprKind::Lit(lit) = expr.kind\n            && let LitKind::Float(sym, lit_float_ty) = lit.node\n            && let ty::Float(fty) = *cx.typeck_results().expr_ty(expr).kind()\n        {\n            let sym_str = sym.as_str();\n            let formatter = FloatFormat::new(sym_str);\n            // Try to bail out if the float is for sure fine.\n            // If its within the 2 decimal digits of being out of precision we\n            // check if the parsed representation is the same as the string\n            // since we'll need the truncated string anyway.\n            let digits = count_digits(sym_str);\n            let max = max_digits(fty);\n            let type_suffix = match lit_float_ty {\n                LitFloatType::Suffixed(FloatTy::F16) => Some(\"f16\"),\n                LitFloatType::Suffixed(FloatTy::F32) => Some(\"f32\"),\n                LitFloatType::Suffixed(FloatTy::F64) => Some(\"f64\"),\n                LitFloatType::Suffixed(FloatTy::F128) => Some(\"f128\"),\n                LitFloatType::Unsuffixed => None,\n            };\n            let (is_whole, is_inf, mut float_str) = match fty {\n                FloatTy::F16 | FloatTy::F128 => {\n                    // FIXME(f16_f128): do a check like the others when parsing is available\n                    return;\n                },\n                FloatTy::F32 => {\n                    let value = sym_str.parse::<f32>().unwrap();\n\n                    (value.fract() == 0.0, value.is_infinite(), formatter.format(value))\n                },\n                FloatTy::F64 => {\n                    let value = sym_str.parse::<f64>().unwrap();\n\n                    (value.fract() == 0.0, value.is_infinite(), formatter.format(value))\n                },\n            };\n\n            if is_inf {\n                return;\n            }\n\n            if is_whole && !sym_str.contains(['e', 'E']) {\n                // Normalize the literal by stripping the fractional portion\n                if sym_str.split('.').next().unwrap() != float_str {\n                    span_lint_and_then(\n                        cx,\n                        LOSSY_FLOAT_LITERAL,\n                        expr.span,\n                        \"literal cannot be represented as the underlying type without loss of precision\",\n                        |diag| {\n                            // If the type suffix is missing the suggestion would be\n                            // incorrectly interpreted as an integer so adding a `.0`\n                            // suffix to prevent that.\n                            if type_suffix.is_none() {\n                                float_str.push_str(\".0\");\n                            }\n                            diag.span_suggestion_verbose(\n                                expr.span,\n                                \"consider changing the type or replacing it with\",\n                                numeric_literal::format(&float_str, type_suffix, true),\n                                Applicability::MachineApplicable,\n                            );\n                        },\n                    );\n                }\n            } else if digits > max as usize && count_digits(&float_str) < digits {\n                if digits >= self.const_literal_digits_threshold\n                    && matches!(expr_use_ctxt(cx, expr).use_node(cx), ExprUseNode::ConstStatic(_))\n                {\n                    // If a big enough number of digits is specified and it's a constant\n                    // we assume the user is definining a constant, and excessive precision is ok\n                    return;\n                }\n                span_lint_and_then(\n                    cx,\n                    EXCESSIVE_PRECISION,\n                    expr.span,\n                    \"float has excessive precision\",\n                    |diag| {\n                        if digits >= self.const_literal_digits_threshold\n                            && let Some(let_stmt) = maybe_let_stmt(cx, expr)\n                        {\n                            diag.span_note(let_stmt.span, \"consider making it a `const` item\");\n                        }\n                        diag.span_suggestion_verbose(\n                            expr.span,\n                            \"consider changing the type or truncating it to\",\n                            numeric_literal::format(&float_str, type_suffix, true),\n                            Applicability::MachineApplicable,\n                        );\n                    },\n                );\n            }\n        }\n    }\n}\n\n#[must_use]\nfn max_digits(fty: FloatTy) -> u32 {\n    match fty {\n        FloatTy::F16 => f16::DIGITS,\n        FloatTy::F32 => f32::DIGITS,\n        FloatTy::F64 => f64::DIGITS,\n        FloatTy::F128 => f128::DIGITS,\n    }\n}\n\n/// Counts the digits excluding leading zeros\n#[must_use]\nfn count_digits(s: &str) -> usize {\n    // Note that s does not contain the `f{16,32,64,128}` suffix, and underscores have been stripped\n    s.chars()\n        .filter(|c| *c != '-' && *c != '.')\n        .take_while(|c| *c != 'e' && *c != 'E')\n        .fold(0, |count, c| {\n            // leading zeros\n            if c == '0' && count == 0 { count } else { count + 1 }\n        })\n}\n\nenum FloatFormat {\n    LowerExp,\n    UpperExp,\n    Normal,\n}\nimpl FloatFormat {\n    #[must_use]\n    fn new(s: &str) -> Self {\n        s.chars()\n            .find_map(|x| match x {\n                'e' => Some(Self::LowerExp),\n                'E' => Some(Self::UpperExp),\n                _ => None,\n            })\n            .unwrap_or(Self::Normal)\n    }\n    fn format<T>(&self, f: T) -> String\n    where\n        T: fmt::UpperExp + fmt::LowerExp + fmt::Display,\n    {\n        match self {\n            Self::LowerExp => format!(\"{f:e}\"),\n            Self::UpperExp => format!(\"{f:E}\"),\n            Self::Normal => format!(\"{f}\"),\n        }\n    }\n}\n\nfn maybe_let_stmt<'a>(cx: &LateContext<'a>, expr: &hir::Expr<'_>) -> Option<&'a hir::LetStmt<'a>> {\n    let parent = cx.tcx.parent_hir_node(expr.hir_id);\n    match parent {\n        hir::Node::LetStmt(let_stmt) => Some(let_stmt),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/custom_abs.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::consts::Constant::{F32, F64, Int};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{eq_expr_value, higher, peel_blocks};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_span::SyntaxContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::SUBOPTIMAL_FLOPS;\n\n/// Returns true iff expr is an expression which tests whether or not\n/// test is positive or an expression which tests whether or not test\n/// is nonnegative.\n/// Used for check-custom-abs function below\nfn is_testing_positive(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool {\n    if let ExprKind::Binary(Spanned { node: op, .. }, left, right) = expr.kind {\n        match op {\n            BinOpKind::Gt | BinOpKind::Ge => is_zero(cx, right, expr.span.ctxt()) && eq_expr_value(cx, left, test),\n            BinOpKind::Lt | BinOpKind::Le => is_zero(cx, left, expr.span.ctxt()) && eq_expr_value(cx, right, test),\n            _ => false,\n        }\n    } else {\n        false\n    }\n}\n\n/// See [`is_testing_positive`]\nfn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -> bool {\n    if let ExprKind::Binary(Spanned { node: op, .. }, left, right) = expr.kind {\n        match op {\n            BinOpKind::Gt | BinOpKind::Ge => is_zero(cx, left, expr.span.ctxt()) && eq_expr_value(cx, right, test),\n            BinOpKind::Lt | BinOpKind::Le => is_zero(cx, right, expr.span.ctxt()) && eq_expr_value(cx, left, test),\n            _ => false,\n        }\n    } else {\n        false\n    }\n}\n\n/// Returns true iff expr is some zero literal\nfn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> bool {\n    match ConstEvalCtxt::new(cx).eval_local(expr, ctxt) {\n        Some(Int(i)) => i == 0,\n        Some(F32(f)) => f == 0.0,\n        Some(F64(f)) => f == 0.0,\n        _ => false,\n    }\n}\n\n/// If the two expressions are negations of each other, then it returns\n/// a tuple, in which the first element is true iff expr1 is the\n/// positive expressions, and the second element is the positive\n/// one of the two expressions\n/// If the two expressions are not negations of each other, then it\n/// returns None.\nfn are_negated<'a>(cx: &LateContext<'_>, expr1: &'a Expr<'a>, expr2: &'a Expr<'a>) -> Option<(bool, &'a Expr<'a>)> {\n    if let ExprKind::Unary(UnOp::Neg, expr1_negated) = expr1.kind\n        && eq_expr_value(cx, expr1_negated, expr2)\n    {\n        return Some((false, expr2));\n    }\n    if let ExprKind::Unary(UnOp::Neg, expr2_negated) = expr2.kind\n        && eq_expr_value(cx, expr1, expr2_negated)\n    {\n        return Some((true, expr1));\n    }\n    None\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let Some(higher::If {\n        cond,\n        then,\n        r#else: Some(r#else),\n    }) = higher::If::hir(expr)\n        && let if_body_expr = peel_blocks(then)\n        && let else_body_expr = peel_blocks(r#else)\n        && let Some((if_expr_positive, body)) = are_negated(cx, if_body_expr, else_body_expr)\n    {\n        let sugg_positive_abs = if is_testing_positive(cx, cond, body) {\n            if_expr_positive\n        } else if is_testing_negative(cx, cond, body) {\n            !if_expr_positive\n        } else {\n            return;\n        };\n        let mut app = Applicability::MachineApplicable;\n        let body = Sugg::hir_with_applicability(cx, body, \"_\", &mut app).maybe_paren();\n        let sugg = if sugg_positive_abs {\n            (\"manual implementation of `abs` method\", format!(\"{body}.abs()\"))\n        } else {\n            #[rustfmt::skip]\n            (\"manual implementation of negation of `abs` method\", format!(\"-{body}.abs()\"))\n        };\n        span_lint_and_sugg(cx, SUBOPTIMAL_FLOPS, expr.span, sugg.0, \"try\", sugg.1, app);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/expm1.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::consts::Constant::{F32, F64};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::IMPRECISE_FLOPS;\n\n// TODO: Lint expressions of the form `x.exp() - y` where y > 1\n// and suggest usage of `x.exp_m1() - (y - 1)` instead\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let ExprKind::Binary(\n        Spanned {\n            node: BinOpKind::Sub, ..\n        },\n        lhs,\n        rhs,\n    ) = expr.kind\n        && let ExprKind::MethodCall(path, self_arg, [], _) = lhs.kind\n        && path.ident.name == sym::exp\n        && cx.typeck_results().expr_ty(lhs).is_floating_point()\n        && let Some(value) = ConstEvalCtxt::new(cx).eval(rhs)\n        && (F32(1.0) == value || F64(1.0) == value)\n        && cx.typeck_results().expr_ty(self_arg).is_floating_point()\n    {\n        span_lint_and_then(\n            cx,\n            IMPRECISE_FLOPS,\n            expr.span,\n            \"(e.pow(x) - 1) can be computed more accurately\",\n            |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let recv = Sugg::hir_with_applicability(cx, self_arg, \"_\", &mut app).maybe_paren();\n                diag.span_suggestion(expr.span, \"consider using\", format!(\"{recv}.exp_m1()\"), app);\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/hypot.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::consts::Constant::Int;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{eq_expr_value, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::IMPRECISE_FLOPS;\n\npub(super) fn detect(cx: &LateContext<'_>, receiver: &Expr<'_>, app: &mut Applicability) -> Option<String> {\n    if let ExprKind::Binary(\n        Spanned {\n            node: BinOpKind::Add, ..\n        },\n        add_lhs,\n        add_rhs,\n    ) = receiver.kind\n    {\n        // check if expression of the form x * x + y * y\n        if let ExprKind::Binary(\n            Spanned {\n                node: BinOpKind::Mul, ..\n            },\n            lmul_lhs,\n            lmul_rhs,\n        ) = add_lhs.kind\n            && let ExprKind::Binary(\n                Spanned {\n                    node: BinOpKind::Mul, ..\n                },\n                rmul_lhs,\n                rmul_rhs,\n            ) = add_rhs.kind\n            && eq_expr_value(cx, lmul_lhs, lmul_rhs)\n            && eq_expr_value(cx, rmul_lhs, rmul_rhs)\n        {\n            return Some(format!(\n                \"{}.hypot({})\",\n                Sugg::hir_with_applicability(cx, lmul_lhs, \"_\", app).maybe_paren(),\n                Sugg::hir_with_applicability(cx, rmul_lhs, \"_\", app)\n            ));\n        }\n\n        // check if expression of the form x.powi(2) + y.powi(2)\n        if let ExprKind::MethodCall(PathSegment { ident: lmethod, .. }, largs_0, [largs_1, ..], _) = add_lhs.kind\n            && let ExprKind::MethodCall(PathSegment { ident: rmethod, .. }, rargs_0, [rargs_1, ..], _) = add_rhs.kind\n            && lmethod.name == sym::powi\n            && rmethod.name == sym::powi\n            && let ecx = ConstEvalCtxt::new(cx)\n            && let Some(lvalue) = ecx.eval(largs_1)\n            && let Some(rvalue) = ecx.eval(rargs_1)\n            && Int(2) == lvalue\n            && Int(2) == rvalue\n        {\n            return Some(format!(\n                \"{}.hypot({})\",\n                Sugg::hir_with_applicability(cx, largs_0, \"_\", app).maybe_paren(),\n                Sugg::hir_with_applicability(cx, rargs_0, \"_\", app)\n            ));\n        }\n    }\n\n    None\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {\n    let mut app = Applicability::MachineApplicable;\n    if let Some(message) = detect(cx, receiver, &mut app) {\n        span_lint_and_sugg(\n            cx,\n            IMPRECISE_FLOPS,\n            expr.span,\n            \"hypotenuse can be computed more accurately\",\n            \"consider using\",\n            message,\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/lib.rs",
    "content": "use clippy_utils::sugg::Sugg;\nuse rustc_ast::ast;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\n// Adds type suffixes and parenthesis to method receivers if necessary\npub(super) fn prepare_receiver_sugg<'a>(\n    cx: &LateContext<'_>,\n    mut expr: &'a Expr<'a>,\n    app: &mut Applicability,\n) -> Sugg<'a> {\n    let mut suggestion = Sugg::hir_with_applicability(cx, expr, \"_\", app);\n\n    if let ExprKind::Unary(UnOp::Neg, inner_expr) = expr.kind {\n        expr = inner_expr;\n    }\n\n    if let ty::Float(float_ty) = cx.typeck_results().expr_ty(expr).kind()\n        // if the expression is a float literal and it is unsuffixed then\n        // add a suffix so the suggestion is valid and unambiguous\n        && let ExprKind::Lit(lit) = expr.kind\n        && let ast::LitKind::Float(sym, ast::LitFloatType::Unsuffixed) = lit.node\n    {\n        let op = format!(\n            \"{suggestion}{}{}\",\n            // Check for float literals without numbers following the decimal\n            // separator such as `2.` and adds a trailing zero\n            if sym.as_str().ends_with('.') { \"0\" } else { \"\" },\n            float_ty.name_str()\n        )\n        .into();\n\n        suggestion = match suggestion {\n            Sugg::MaybeParen(_) | Sugg::UnOp(UnOp::Neg, _) => Sugg::MaybeParen(op),\n            _ => Sugg::NonParen(op),\n        };\n    }\n\n    suggestion.maybe_paren()\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/ln1p.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::consts::Constant::{F32, F64};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::IMPRECISE_FLOPS;\n\n// TODO: Lint expressions of the form `(x + y).ln()` where y > 1 and\n// suggest usage of `(x + (y - 1)).ln_1p()` instead\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {\n    if let ExprKind::Binary(\n        Spanned {\n            node: BinOpKind::Add, ..\n        },\n        lhs,\n        rhs,\n    ) = receiver.kind\n    {\n        let ecx = ConstEvalCtxt::new(cx);\n        let recv = match (ecx.eval(lhs), ecx.eval(rhs)) {\n            (Some(value), _) if F32(1.0) == value || F64(1.0) == value => rhs,\n            (_, Some(value)) if F32(1.0) == value || F64(1.0) == value => lhs,\n            _ => return,\n        };\n\n        span_lint_and_then(\n            cx,\n            IMPRECISE_FLOPS,\n            expr.span,\n            \"ln(1 + x) can be computed more accurately\",\n            |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let recv = super::lib::prepare_receiver_sugg(cx, recv, &mut app);\n                diag.span_suggestion(expr.span, \"consider using\", format!(\"{recv}.ln_1p()\"), app);\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/log_base.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::consts::Constant::{F32, F64};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::SyntaxContext;\nuse std::f32::consts as f32_consts;\nuse std::f64::consts as f64_consts;\n\nuse super::SUBOPTIMAL_FLOPS;\n\n// Returns the specialized log method for a given base if base is constant\n// and is one of 2, 10 and e\nfn get_specialized_log_method(cx: &LateContext<'_>, base: &Expr<'_>, ctxt: SyntaxContext) -> Option<&'static str> {\n    if let Some(value) = ConstEvalCtxt::new(cx).eval_local(base, ctxt) {\n        if F32(2.0) == value || F64(2.0) == value {\n            return Some(\"log2\");\n        } else if F32(10.0) == value || F64(10.0) == value {\n            return Some(\"log10\");\n        } else if F32(f32_consts::E) == value || F64(f64_consts::E) == value {\n            return Some(\"ln\");\n        }\n    }\n\n    None\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {\n    if let Some(method) = get_specialized_log_method(cx, &args[0], expr.span.ctxt()) {\n        span_lint_and_then(\n            cx,\n            SUBOPTIMAL_FLOPS,\n            expr.span,\n            \"logarithm for bases 2, 10 and e can be computed more accurately\",\n            |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let recv = Sugg::hir_with_applicability(cx, receiver, \"_\", &mut app).maybe_paren();\n                diag.span_suggestion(expr.span, \"consider using\", format!(\"{recv}.{method}()\"), app);\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/log_division.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{eq_expr_value, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::SUBOPTIMAL_FLOPS;\n\nfn are_same_base_logs(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool {\n    if let ExprKind::MethodCall(PathSegment { ident: method_a, .. }, _, args_a, _) = expr_a.kind\n        && let ExprKind::MethodCall(PathSegment { ident: method_b, .. }, _, args_b, _) = expr_b.kind\n    {\n        return method_a.name == method_b.name\n            && args_a.len() == args_b.len()\n            && (matches!(method_a.name, sym::ln | sym::log2 | sym::log10)\n                || method_a.name == sym::log && args_a.len() == 1 && eq_expr_value(cx, &args_a[0], &args_b[0]));\n    }\n\n    false\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    // check if expression of the form x.logN() / y.logN()\n    if let ExprKind::Binary(\n        Spanned {\n            node: BinOpKind::Div, ..\n        },\n        lhs,\n        rhs,\n    ) = expr.kind\n        && are_same_base_logs(cx, lhs, rhs)\n        && let ExprKind::MethodCall(_, largs_self, ..) = lhs.kind\n        && let ExprKind::MethodCall(_, rargs_self, ..) = rhs.kind\n    {\n        let mut app = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            SUBOPTIMAL_FLOPS,\n            expr.span,\n            \"log base can be expressed more clearly\",\n            \"consider using\",\n            format!(\n                \"{}.log({})\",\n                Sugg::hir_with_applicability(cx, largs_self, \"_\", &mut app).maybe_paren(),\n                Sugg::hir_with_applicability(cx, rargs_self, \"_\", &mut app),\n            ),\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/mod.rs",
    "content": "use clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::{is_in_const_context, is_no_std_crate, sym};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\nmod custom_abs;\nmod expm1;\nmod hypot;\nmod lib;\nmod ln1p;\nmod log_base;\nmod log_division;\nmod mul_add;\nmod powf;\nmod powi;\nmod radians;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for floating-point expressions that\n    /// can be expressed using built-in methods to improve accuracy\n    /// at the cost of performance.\n    ///\n    /// ### Why is this bad?\n    /// Negatively impacts accuracy.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = 3f32;\n    /// let _ = a.powf(1.0 / 3.0);\n    /// let _ = (1.0 + a).ln();\n    /// let _ = a.exp() - 1.0;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let a = 3f32;\n    /// let _ = a.cbrt();\n    /// let _ = a.ln_1p();\n    /// let _ = a.exp_m1();\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub IMPRECISE_FLOPS,\n    nursery,\n    \"usage of imprecise floating point operations\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for floating-point expressions that\n    /// can be expressed using built-in methods to improve both\n    /// accuracy and performance.\n    ///\n    /// ### Why is this bad?\n    /// Negatively impacts accuracy and performance.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::f32::consts::E;\n    ///\n    /// let a = 3f32;\n    /// let _ = (2f32).powf(a);\n    /// let _ = E.powf(a);\n    /// let _ = a.powf(1.0 / 2.0);\n    /// let _ = a.log(2.0);\n    /// let _ = a.log(10.0);\n    /// let _ = a.log(E);\n    /// let _ = a.powf(2.0);\n    /// let _ = a * 2.0 + 4.0;\n    /// let _ = if a < 0.0 {\n    ///     -a\n    /// } else {\n    ///     a\n    /// };\n    /// let _ = if a < 0.0 {\n    ///     a\n    /// } else {\n    ///     -a\n    /// };\n    /// ```\n    ///\n    /// is better expressed as\n    ///\n    /// ```no_run\n    /// use std::f32::consts::E;\n    ///\n    /// let a = 3f32;\n    /// let _ = a.exp2();\n    /// let _ = a.exp();\n    /// let _ = a.sqrt();\n    /// let _ = a.log2();\n    /// let _ = a.log10();\n    /// let _ = a.ln();\n    /// let _ = a.powi(2);\n    /// let _ = a.mul_add(2.0, 4.0);\n    /// let _ = a.abs();\n    /// let _ = -a.abs();\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub SUBOPTIMAL_FLOPS,\n    nursery,\n    \"usage of sub-optimal floating point operations\"\n}\n\ndeclare_lint_pass!(FloatingPointArithmetic => [IMPRECISE_FLOPS, SUBOPTIMAL_FLOPS]);\n\nimpl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        // All of these operations are currently not const and are in std.\n        if is_in_const_context(cx) {\n            return;\n        }\n\n        if let ExprKind::MethodCall(path, receiver, args, _) = expr.kind {\n            let recv_ty = cx.typeck_results().expr_ty(receiver);\n\n            if recv_ty.is_floating_point() && !is_no_std_crate(cx) && cx.ty_based_def(expr).opt_parent(cx).is_impl(cx) {\n                match path.ident.name {\n                    sym::ln => ln1p::check(cx, expr, receiver),\n                    sym::log => log_base::check(cx, expr, receiver, args),\n                    sym::powf => powf::check(cx, expr, receiver, args),\n                    sym::powi => powi::check(cx, expr, receiver, args),\n                    sym::sqrt => hypot::check(cx, expr, receiver),\n                    _ => {},\n                }\n            }\n        } else {\n            if !is_no_std_crate(cx) {\n                expm1::check(cx, expr);\n                mul_add::check(cx, expr);\n                custom_abs::check(cx, expr);\n                log_division::check(cx, expr);\n            }\n            radians::check(cx, expr);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/mul_add.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{get_parent_expr, has_ambiguous_literal_in_expr, sym};\nuse rustc_ast::AssignOpKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::SUBOPTIMAL_FLOPS;\n\nfn is_float_mul_expr<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(&'a Expr<'a>, &'a Expr<'a>)> {\n    if let ExprKind::Binary(\n        Spanned {\n            node: BinOpKind::Mul, ..\n        },\n        lhs,\n        rhs,\n    ) = expr.kind\n        && cx.typeck_results().expr_ty(lhs).is_floating_point()\n        && cx.typeck_results().expr_ty(rhs).is_floating_point()\n    {\n        return Some((lhs, rhs));\n    }\n\n    None\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    let (is_assign, op, lhs, rhs) = match &expr.kind {\n        ExprKind::AssignOp(\n            Spanned {\n                node: AssignOpKind::AddAssign,\n                ..\n            },\n            lhs,\n            rhs,\n        ) => (true, BinOpKind::Add, lhs, rhs),\n        ExprKind::AssignOp(\n            Spanned {\n                node: AssignOpKind::SubAssign,\n                ..\n            },\n            lhs,\n            rhs,\n        ) => (true, BinOpKind::Sub, lhs, rhs),\n        ExprKind::Binary(\n            Spanned {\n                node: op @ (BinOpKind::Add | BinOpKind::Sub),\n                ..\n            },\n            lhs,\n            rhs,\n        ) => (false, *op, lhs, rhs),\n        _ => return,\n    };\n\n    if !is_assign\n        && let Some(parent) = get_parent_expr(cx, expr)\n        && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = parent.kind\n        && method.name == sym::sqrt\n        // we don't care about the applicability as this is an early-return condition\n        && super::hypot::detect(cx, receiver, &mut Applicability::Unspecified).is_some()\n    {\n        return;\n    }\n\n    // Check if any variable in the expression has an ambiguous type (could be f32 or f64)\n    // see: https://github.com/rust-lang/rust-clippy/issues/14897\n    let has_ambiguous_type = |expr: &Expr<'_>| {\n        (matches!(expr.kind, ExprKind::Path(_)) || matches!(expr.kind, ExprKind::Call(_, _)))\n            && has_ambiguous_literal_in_expr(cx, expr)\n    };\n\n    let (recv, arg1, arg2, is_from_rhs) = if let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, rhs)\n        && cx.typeck_results().expr_ty(lhs).is_floating_point()\n        && !has_ambiguous_type(inner_lhs)\n    {\n        (inner_lhs, inner_rhs, lhs, true)\n    } else if !is_assign\n        && let Some((inner_lhs, inner_rhs)) = is_float_mul_expr(cx, lhs)\n        && cx.typeck_results().expr_ty(rhs).is_floating_point()\n        && !has_ambiguous_type(inner_lhs)\n    {\n        (inner_lhs, inner_rhs, rhs, false)\n    } else {\n        return;\n    };\n\n    span_lint_and_then(\n        cx,\n        SUBOPTIMAL_FLOPS,\n        expr.span,\n        \"multiply and add expressions can be calculated more efficiently and accurately\",\n        |diag| {\n            let maybe_neg_sugg = |expr, app: &mut _| {\n                let sugg = Sugg::hir_with_applicability(cx, expr, \"_\", app);\n                if let BinOpKind::Sub = op { -sugg } else { sugg }\n            };\n            let mut app = Applicability::MachineApplicable;\n            let recv_sugg = super::lib::prepare_receiver_sugg(cx, recv, &mut app);\n            let (arg1, arg2) = if is_from_rhs {\n                (\n                    maybe_neg_sugg(arg1, &mut app),\n                    Sugg::hir_with_applicability(cx, arg2, \"_\", &mut app),\n                )\n            } else {\n                (\n                    Sugg::hir_with_applicability(cx, arg1, \"_\", &mut app),\n                    maybe_neg_sugg(arg2, &mut app),\n                )\n            };\n            diag.span_suggestion(\n                expr.span,\n                \"consider using\",\n                if is_assign {\n                    format!(\"{arg2} = {recv_sugg}.mul_add({arg1}, {arg2})\")\n                } else {\n                    format!(\"{recv_sugg}.mul_add({arg1}, {arg2})\")\n                },\n                app,\n            );\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/powf.rs",
    "content": "use clippy_utils::consts::Constant::{F32, F64};\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::numeric_literal;\nuse clippy_utils::sugg::Sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse std::f32::consts as f32_consts;\nuse std::f64::consts as f64_consts;\n\nuse super::{IMPRECISE_FLOPS, SUBOPTIMAL_FLOPS};\n\n// Returns an integer if the float constant is a whole number and it can be\n// converted to an integer without loss of precision. For now we only check\n// ranges [-16777215, 16777216) for type f32 as whole number floats outside\n// this range are lossy and ambiguous.\n#[expect(clippy::cast_possible_truncation)]\nfn get_integer_from_float_constant(value: &Constant) -> Option<i32> {\n    match value {\n        F32(num) if num.fract() == 0.0 => {\n            if (-16_777_215.0..16_777_216.0).contains(num) {\n                Some(num.round() as i32)\n            } else {\n                None\n            }\n        },\n        F64(num) if num.fract() == 0.0 => {\n            if (-2_147_483_648.0..2_147_483_648.0).contains(num) {\n                Some(num.round() as i32)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {\n    // Check receiver\n    if let Some(value) = ConstEvalCtxt::new(cx).eval(receiver)\n        && let Some(method) = if F32(f32_consts::E) == value || F64(f64_consts::E) == value {\n            Some(\"exp\")\n        } else if F32(2.0) == value || F64(2.0) == value {\n            Some(\"exp2\")\n        } else {\n            None\n        }\n    {\n        span_lint_and_then(\n            cx,\n            SUBOPTIMAL_FLOPS,\n            expr.span,\n            \"exponent for bases 2 and e can be computed more accurately\",\n            |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let recv = super::lib::prepare_receiver_sugg(cx, &args[0], &mut app);\n                diag.span_suggestion(expr.span, \"consider using\", format!(\"{recv}.{method}()\"), app);\n            },\n        );\n    }\n\n    // Check argument\n    if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0]) {\n        let mut app = Applicability::MachineApplicable;\n        let recv = Sugg::hir_with_applicability(cx, receiver, \"_\", &mut app).maybe_paren();\n        let (lint, help, suggestion) = if F32(1.0 / 2.0) == value || F64(1.0 / 2.0) == value {\n            (\n                SUBOPTIMAL_FLOPS,\n                \"square-root of a number can be computed more efficiently and accurately\",\n                format!(\"{recv}.sqrt()\"),\n            )\n        } else if F32(1.0 / 3.0) == value || F64(1.0 / 3.0) == value {\n            (\n                IMPRECISE_FLOPS,\n                \"cube-root of a number can be computed more accurately\",\n                format!(\"{recv}.cbrt()\"),\n            )\n        } else if let Some(exponent) = get_integer_from_float_constant(&value) {\n            (\n                SUBOPTIMAL_FLOPS,\n                \"exponentiation with integer powers can be computed more efficiently\",\n                format!(\n                    \"{recv}.powi({})\",\n                    numeric_literal::format(&exponent.to_string(), None, false)\n                ),\n            )\n        } else {\n            return;\n        };\n\n        span_lint_and_sugg(cx, lint, expr.span, help, \"consider using\", suggestion, app);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/powi.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::consts::Constant::Int;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{get_parent_expr, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::SUBOPTIMAL_FLOPS;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {\n    if let Some(value) = ConstEvalCtxt::new(cx).eval(&args[0])\n        && value == Int(2)\n        && let Some(parent) = get_parent_expr(cx, expr)\n    {\n        if let Some(grandparent) = get_parent_expr(cx, parent)\n            && let ExprKind::MethodCall(PathSegment { ident: method, .. }, receiver, ..) = grandparent.kind\n            && method.name == sym::sqrt\n            // we don't care about the applicability as this is an early-return condition\n            && super::hypot::detect(cx, receiver, &mut Applicability::Unspecified).is_some()\n        {\n            return;\n        }\n\n        if let ExprKind::Binary(\n            Spanned {\n                node: op @ (BinOpKind::Add | BinOpKind::Sub),\n                ..\n            },\n            lhs,\n            rhs,\n        ) = parent.kind\n        {\n            span_lint_and_then(\n                cx,\n                SUBOPTIMAL_FLOPS,\n                parent.span,\n                \"multiply and add expressions can be calculated more efficiently and accurately\",\n                |diag| {\n                    let other_addend = if lhs.hir_id == expr.hir_id { rhs } else { lhs };\n\n                    // Negate expr if original code has subtraction and expr is on the right side\n                    let maybe_neg_sugg = |expr, hir_id, app: &mut _| {\n                        let sugg = Sugg::hir_with_applicability(cx, expr, \"_\", app);\n                        if matches!(op, BinOpKind::Sub) && hir_id == rhs.hir_id {\n                            -sugg\n                        } else {\n                            sugg\n                        }\n                    };\n\n                    let mut app = Applicability::MachineApplicable;\n                    diag.span_suggestion(\n                        parent.span,\n                        \"consider using\",\n                        format!(\n                            \"{}.mul_add({}, {})\",\n                            Sugg::hir_with_applicability(cx, receiver, \"_\", &mut app).maybe_paren(),\n                            maybe_neg_sugg(receiver, expr.hir_id, &mut app),\n                            maybe_neg_sugg(other_addend, other_addend.hir_id, &mut app),\n                        ),\n                        app,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/floating_point_arithmetic/radians.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::consts::Constant::{F32, F64};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse rustc_ast::ast;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\nuse std::f32::consts as f32_consts;\nuse std::f64::consts as f64_consts;\n\nuse super::SUBOPTIMAL_FLOPS;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let ExprKind::Binary(\n        Spanned {\n            node: BinOpKind::Div, ..\n        },\n        div_lhs,\n        div_rhs,\n    ) = expr.kind\n        && let ExprKind::Binary(\n            Spanned {\n                node: BinOpKind::Mul, ..\n            },\n            mul_lhs,\n            mul_rhs,\n        ) = div_lhs.kind\n        && let ecx = ConstEvalCtxt::new(cx)\n        && let Some(rvalue) = ecx.eval(div_rhs)\n        && let Some(lvalue) = ecx.eval(mul_rhs)\n    {\n        // TODO: also check for constant values near PI/180 or 180/PI\n        if (F32(f32_consts::PI) == rvalue || F64(f64_consts::PI) == rvalue)\n            && (F32(180_f32) == lvalue || F64(180_f64) == lvalue)\n        {\n            span_lint_and_then(\n                cx,\n                SUBOPTIMAL_FLOPS,\n                expr.span,\n                \"conversion to degrees can be done more accurately\",\n                |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let recv = Sugg::hir_with_applicability(cx, mul_lhs, \"num\", &mut app);\n                    let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind\n                        && let ast::LitKind::Float(ref value, float_type) = literal.node\n                        && float_type == ast::LitFloatType::Unsuffixed\n                    {\n                        if value.as_str().ends_with('.') {\n                            format!(\"{recv}0_f64.to_degrees()\")\n                        } else {\n                            format!(\"{recv}_f64.to_degrees()\")\n                        }\n                    } else {\n                        format!(\"{}.to_degrees()\", recv.maybe_paren())\n                    };\n                    diag.span_suggestion(expr.span, \"consider using\", proposal, app);\n                },\n            );\n        } else if (F32(180_f32) == rvalue || F64(180_f64) == rvalue)\n            && (F32(f32_consts::PI) == lvalue || F64(f64_consts::PI) == lvalue)\n        {\n            span_lint_and_then(\n                cx,\n                SUBOPTIMAL_FLOPS,\n                expr.span,\n                \"conversion to radians can be done more accurately\",\n                |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let recv = Sugg::hir_with_applicability(cx, mul_lhs, \"num\", &mut app);\n                    let proposal = if let ExprKind::Lit(literal) = mul_lhs.kind\n                        && let ast::LitKind::Float(ref value, float_type) = literal.node\n                        && float_type == ast::LitFloatType::Unsuffixed\n                    {\n                        if value.as_str().ends_with('.') {\n                            format!(\"{recv}0_f64.to_radians()\")\n                        } else {\n                            format!(\"{recv}_f64.to_radians()\")\n                        }\n                    } else {\n                        format!(\"{}.to_radians()\", recv.maybe_paren())\n                    };\n                    diag.span_suggestion(expr.span, \"consider using\", proposal, app);\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/format.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, root_macro_call_first_node};\nuse clippy_utils::source::{SpanRangeExt, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\nuse rustc_ast::{FormatArgsPiece, FormatOptions, FormatTrait};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of `format!(\"string literal with no\n    /// argument\")` and `format!(\"{}\", foo)` where `foo` is a string.\n    ///\n    /// ### Why is this bad?\n    /// There is no point of doing that. `format!(\"foo\")` can\n    /// be replaced by `\"foo\".to_owned()` if you really need a `String`. The even\n    /// worse `&format!(\"foo\")` is often encountered in the wild. `format!(\"{}\",\n    /// foo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`\n    /// if `foo: &str`.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// let foo = \"foo\";\n    /// format!(\"{}\", foo);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let foo = \"foo\";\n    /// foo.to_owned();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USELESS_FORMAT,\n    complexity,\n    \"useless use of `format!`\"\n}\n\nimpl_lint_pass!(UselessFormat => [USELESS_FORMAT]);\n\npub struct UselessFormat {\n    format_args: FormatArgsStorage,\n}\n\nimpl UselessFormat {\n    pub fn new(format_args: FormatArgsStorage) -> Self {\n        Self { format_args }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UselessFormat {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let Some(macro_call) = root_macro_call_first_node(cx, expr)\n            && cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)\n            && let Some(format_args) = self.format_args.get(cx, expr, macro_call.expn)\n        {\n            let mut applicability = Applicability::MachineApplicable;\n            let call_site = macro_call.span;\n\n            match (format_args.arguments.all_args(), &format_args.template[..]) {\n                ([], []) => span_useless_format_empty(cx, call_site, \"String::new()\".to_owned(), applicability),\n                ([], [_]) => {\n                    // Simulate macro expansion, converting {{ and }} to { and }.\n                    let Some(snippet) = format_args.span.get_source_text(cx) else {\n                        return;\n                    };\n                    let s_expand = snippet.replace(\"{{\", \"{\").replace(\"}}\", \"}\");\n                    let sugg = format!(\"{s_expand}.to_string()\");\n                    span_useless_format(cx, call_site, sugg, applicability);\n                },\n                ([arg], [piece]) => {\n                    if let Some(value) = find_format_arg_expr(expr, arg)\n                        && let FormatArgsPiece::Placeholder(placeholder) = piece\n                        && placeholder.format_trait == FormatTrait::Display\n                        && placeholder.format_options == FormatOptions::default()\n                        && match cx.typeck_results().expr_ty(value).peel_refs().kind() {\n                            ty::Adt(adt, _) => Some(adt.did()) == cx.tcx.lang_items().string(),\n                            ty::Str => true,\n                            _ => false,\n                        }\n                    {\n                        let is_new_string = match value.kind {\n                            ExprKind::Binary(..) => true,\n                            ExprKind::MethodCall(path, ..) => path.ident.name == sym::to_string,\n                            _ => false,\n                        };\n                        let sugg = if is_new_string {\n                            snippet_with_context(cx, value.span, call_site.ctxt(), \"..\", &mut applicability)\n                                .0\n                                .into_owned()\n                        } else {\n                            let sugg = Sugg::hir_with_context(cx, value, call_site.ctxt(), \"<arg>\", &mut applicability);\n                            format!(\"{}.to_string()\", sugg.maybe_paren())\n                        };\n                        span_useless_format(cx, call_site, sugg, applicability);\n                    }\n                },\n                _ => {},\n            }\n        }\n    }\n}\n\nfn span_useless_format_empty(cx: &LateContext<'_>, span: Span, sugg: String, applicability: Applicability) {\n    span_lint_and_sugg(\n        cx,\n        USELESS_FORMAT,\n        span,\n        \"useless use of `format!`\",\n        \"consider using `String::new()`\",\n        sugg,\n        applicability,\n    );\n}\n\nfn span_useless_format(cx: &LateContext<'_>, span: Span, sugg: String, applicability: Applicability) {\n    span_lint_and_sugg(\n        cx,\n        USELESS_FORMAT,\n        span,\n        \"useless use of `format!`\",\n        \"consider using `.to_string()`\",\n        sugg,\n        applicability,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/format_args.rs",
    "content": "use std::collections::hash_map::Entry;\n\nuse arrayvec::ArrayVec;\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::macros::{\n    FormatArgsStorage, FormatParamUsage, MacroCall, find_format_arg_expr, format_arg_removal_span,\n    format_placeholder_format_span, is_assert_macro, is_format_macro, is_panic, matching_root_macro_call,\n    root_macro_call_first_node,\n};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{SpanRangeExt, snippet};\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{is_from_proc_macro, is_in_test, sym, trait_ref_of_method};\nuse itertools::Itertools;\nuse rustc_ast::{\n    FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions,\n    FormatPlaceholder, FormatTrait,\n};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::Applicability;\nuse rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode};\nuse rustc_hir::{Expr, ExprKind, LangItem, RustcVersion, find_attr};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};\nuse rustc_middle::ty::{self, GenericArg, List, TraitRef, Ty, TyCtxt, Upcast};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::edition::Edition::Edition2021;\nuse rustc_span::{BytePos, Pos, Span, Symbol};\nuse rustc_trait_selection::infer::TyCtxtInferExt;\nuse rustc_trait_selection::traits::{Obligation, ObligationCause, Selection, SelectionContext};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects `format!` within the arguments of another macro that does\n    /// formatting such as `format!` itself, `write!` or `println!`. Suggests\n    /// inlining the `format!` call.\n    ///\n    /// ### Why is this bad?\n    /// The recommended code is both shorter and avoids a temporary allocation.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::panic::Location;\n    /// println!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::panic::Location;\n    /// println!(\"error: something failed at {}\", Location::caller());\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub FORMAT_IN_FORMAT_ARGS,\n    perf,\n    \"`format!` used in a macro that does formatting\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects [pointer format] as well as `Debug` formatting of raw pointers or function pointers\n    /// or any types that have a derived `Debug` impl that recursively contains them.\n    ///\n    /// ### Why restrict this?\n    /// The addresses are only useful in very specific contexts, and certain projects may want to keep addresses of\n    /// certain data structures or functions from prying hacker eyes as an additional line of security.\n    ///\n    /// ### Known problems\n    /// The lint currently only looks through derived `Debug` implementations. Checking whether a manual\n    /// implementation prints an address is left as an exercise to the next lint implementer.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let foo = &0_u32;\n    /// fn bar() {}\n    /// println!(\"{:p}\", foo);\n    /// let _ = format!(\"{:?}\", &(bar as fn()));\n    /// ```\n    ///\n    /// [pointer format]: https://doc.rust-lang.org/std/fmt/index.html#formatting-traits\n    #[clippy::version = \"1.89.0\"]\n    pub POINTER_FORMAT,\n    restriction,\n    \"formatting a pointer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for [`ToString::to_string`](https://doc.rust-lang.org/std/string/trait.ToString.html#tymethod.to_string)\n    /// applied to a type that implements [`Display`](https://doc.rust-lang.org/std/fmt/trait.Display.html)\n    /// in a macro that does formatting.\n    ///\n    /// ### Why is this bad?\n    /// Since the type implements `Display`, the use of `to_string` is\n    /// unnecessary.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::panic::Location;\n    /// println!(\"error: something failed at {}\", Location::caller().to_string());\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::panic::Location;\n    /// println!(\"error: something failed at {}\", Location::caller());\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub TO_STRING_IN_FORMAT_ARGS,\n    perf,\n    \"`to_string` applied to a type that implements `Display` in format args\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detect when a variable is not inlined in a format string,\n    /// and suggests to inline it.\n    ///\n    /// ### Why is this bad?\n    /// Non-inlined code is slightly more difficult to read and understand,\n    /// as it requires arguments to be matched against the format string.\n    /// The inlined syntax, where allowed, is simpler.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let var = 42;\n    /// # let width = 1;\n    /// # let prec = 2;\n    /// format!(\"{}\", var);\n    /// format!(\"{:?}\", var);\n    /// format!(\"{v:?}\", v = var);\n    /// format!(\"{0} {0}\", var);\n    /// format!(\"{0:1$}\", var, width);\n    /// format!(\"{:.*}\", prec, var);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let var = 42;\n    /// # let width = 1;\n    /// # let prec = 2;\n    /// format!(\"{var}\");\n    /// format!(\"{var:?}\");\n    /// format!(\"{var:?}\");\n    /// format!(\"{var} {var}\");\n    /// format!(\"{var:width$}\");\n    /// format!(\"{var:.prec$}\");\n    /// ```\n    ///\n    /// If `allow-mixed-uninlined-format-args` is set to `false` in clippy.toml,\n    /// the following code will also trigger the lint:\n    /// ```no_run\n    /// # let var = 42;\n    /// format!(\"{} {}\", var, 1+2);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let var = 42;\n    /// format!(\"{var} {}\", 1+2);\n    /// ```\n    ///\n    /// ### Known Problems\n    ///\n    /// If a format string contains a numbered argument that cannot be inlined\n    /// nothing will be suggested, e.g. `println!(\"{0}={1}\", var, 1+2)`.\n    #[clippy::version = \"1.66.0\"]\n    pub UNINLINED_FORMAT_ARGS,\n    pedantic,\n    \"using non-inlined variables in `format!` calls\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `Debug` formatting (`{:?}`) applied to an `OsStr` or `Path`.\n    ///\n    /// ### Why is this bad?\n    /// Rust doesn't guarantee what `Debug` formatting looks like, and it could\n    /// change in the future. `OsStr`s and `Path`s can be `Display` formatted\n    /// using their `display` methods.\n    ///\n    /// Furthermore, with `Debug` formatting, certain characters are escaped.\n    /// Thus, a `Debug` formatted `Path` is less likely to be clickable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::path::Path;\n    /// let path = Path::new(\"...\");\n    /// println!(\"The path is {:?}\", path);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::path::Path;\n    /// let path = Path::new(\"…\");\n    /// println!(\"The path is {}\", path.display());\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub UNNECESSARY_DEBUG_FORMATTING,\n    pedantic,\n    \"`Debug` formatting applied to an `OsStr` or `Path` when `.display()` is available\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Suggests removing an unnecessary trailing comma before the closing parenthesis in\n    /// single-line macro invocations.\n    ///\n    /// ### Why is this bad?\n    /// The trailing comma is redundant and removing it is more consistent with how\n    /// `rustfmt` formats regular function calls.\n    ///\n    /// ### Known limitations\n    /// This lint currently only runs on format-like macros (e.g. `format!`, `println!`,\n    /// `write!`) because it relies on format-argument parsing; applying it to arbitrary\n    /// user macros could cause incorrect suggestions. It may be extended to other\n    /// macros in the future. Only single-line macro invocations are linted.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// println!(\"Foo={}\", 1,);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// println!(\"Foo={}\", 1);\n    /// ```\n    #[clippy::version = \"1.95.0\"]\n    pub UNNECESSARY_TRAILING_COMMA,\n    pedantic,\n    \"unnecessary trailing comma before closing parenthesis\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects [formatting parameters] that have no effect on the output of\n    /// `format!()`, `println!()` or similar macros.\n    ///\n    /// ### Why is this bad?\n    /// Shorter format specifiers are easier to read, it may also indicate that\n    /// an expected formatting operation such as adding padding isn't happening.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// println!(\"{:.}\", 1.0);\n    ///\n    /// println!(\"not padded: {:5}\", format_args!(\"...\"));\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// println!(\"{}\", 1.0);\n    ///\n    /// println!(\"not padded: {}\", format_args!(\"...\"));\n    /// // OR\n    /// println!(\"padded: {:5}\", format!(\"...\"));\n    /// ```\n    ///\n    /// [formatting parameters]: https://doc.rust-lang.org/std/fmt/index.html#formatting-parameters\n    #[clippy::version = \"1.66.0\"]\n    pub UNUSED_FORMAT_SPECS,\n    complexity,\n    \"use of a format specifier that has no effect\"\n}\n\nimpl_lint_pass!(FormatArgs<'_> => [\n    FORMAT_IN_FORMAT_ARGS,\n    POINTER_FORMAT,\n    TO_STRING_IN_FORMAT_ARGS,\n    UNINLINED_FORMAT_ARGS,\n    UNNECESSARY_DEBUG_FORMATTING,\n    UNNECESSARY_TRAILING_COMMA,\n    UNUSED_FORMAT_SPECS,\n]);\n\n#[expect(clippy::struct_field_names)]\npub struct FormatArgs<'tcx> {\n    format_args: FormatArgsStorage,\n    msrv: Msrv,\n    ignore_mixed: bool,\n    ty_msrv_map: FxHashMap<Ty<'tcx>, Option<RustcVersion>>,\n    has_derived_debug: FxHashMap<Ty<'tcx>, bool>,\n    has_pointer_format: FxHashMap<Ty<'tcx>, bool>,\n}\n\nimpl<'tcx> FormatArgs<'tcx> {\n    pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf, format_args: FormatArgsStorage) -> Self {\n        let ty_msrv_map = make_ty_msrv_map(tcx);\n        Self {\n            format_args,\n            msrv: conf.msrv,\n            ignore_mixed: conf.allow_mixed_uninlined_format_args,\n            ty_msrv_map,\n            has_derived_debug: FxHashMap::default(),\n            has_pointer_format: FxHashMap::default(),\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for FormatArgs<'tcx> {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let Some(macro_call) = root_macro_call_first_node(cx, expr)\n            && is_format_macro(cx, macro_call.def_id)\n            && let Some(format_args) = self.format_args.get(cx, expr, macro_call.expn)\n        {\n            let mut linter = FormatArgsExpr {\n                cx,\n                expr,\n                macro_call: &macro_call,\n                format_args,\n                ignore_mixed: self.ignore_mixed,\n                msrv: &self.msrv,\n                ty_msrv_map: &self.ty_msrv_map,\n                has_derived_debug: &mut self.has_derived_debug,\n                has_pointer_format: &mut self.has_pointer_format,\n            };\n\n            linter.check_trailing_comma();\n            linter.check_templates();\n\n            if self.msrv.meets(cx, msrvs::FORMAT_ARGS_CAPTURE) {\n                linter.check_uninlined_args();\n            }\n        }\n    }\n}\n\nstruct FormatArgsExpr<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    macro_call: &'a MacroCall,\n    format_args: &'a rustc_ast::FormatArgs,\n    ignore_mixed: bool,\n    msrv: &'a Msrv,\n    ty_msrv_map: &'a FxHashMap<Ty<'tcx>, Option<RustcVersion>>,\n    has_derived_debug: &'a mut FxHashMap<Ty<'tcx>, bool>,\n    has_pointer_format: &'a mut FxHashMap<Ty<'tcx>, bool>,\n}\n\nimpl<'tcx> FormatArgsExpr<'_, 'tcx> {\n    /// Check if there is a comma after the last format macro arg.\n    fn check_trailing_comma(&self) {\n        let span = self.macro_call.span;\n        if let Some(src) = span.get_source_text(self.cx)\n            && let Some(src) = src.strip_suffix([')', ']', '}'])\n            && let src = src.trim_end_matches(|c: char| c.is_whitespace() && c != '\\n')\n            && let Some(src) = src.strip_suffix(',')\n            && let src = src.trim_end_matches(|c: char| c.is_whitespace() && c != '\\n')\n            && !src.ends_with('\\n')\n        {\n            span_lint_and_sugg(\n                self.cx,\n                UNNECESSARY_TRAILING_COMMA,\n                span.with_lo(span.lo() + BytePos::from_usize(src.len()))\n                    .with_hi(span.hi() - BytePos(1)),\n                \"unnecessary trailing comma\",\n                \"remove the trailing comma\",\n                String::new(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n\n    fn check_templates(&mut self) {\n        for piece in &self.format_args.template {\n            if let FormatArgsPiece::Placeholder(placeholder) = piece\n                && let Ok(index) = placeholder.argument.index\n                && let Some(arg) = self.format_args.arguments.all_args().get(index)\n                && let Some(arg_expr) = find_format_arg_expr(self.expr, arg)\n            {\n                self.check_unused_format_specifier(placeholder, arg_expr);\n\n                if placeholder.format_trait == FormatTrait::Display\n                    && placeholder.format_options == FormatOptions::default()\n                    && !self.is_aliased(index)\n                {\n                    let name = self.cx.tcx.item_name(self.macro_call.def_id);\n                    self.check_format_in_format_args(name, arg_expr);\n                    self.check_to_string_in_format_args(name, arg_expr);\n                }\n\n                if placeholder.format_trait == FormatTrait::Debug {\n                    let name = self.cx.tcx.item_name(self.macro_call.def_id);\n                    self.check_unnecessary_debug_formatting(name, arg_expr);\n                    if let Some(span) = placeholder.span\n                        && self.has_pointer_debug(self.cx.typeck_results().expr_ty(arg_expr), 0)\n                    {\n                        span_lint(self.cx, POINTER_FORMAT, span, \"pointer formatting detected\");\n                    }\n                }\n\n                if placeholder.format_trait == FormatTrait::Pointer\n                    && let Some(span) = placeholder.span\n                {\n                    span_lint(self.cx, POINTER_FORMAT, span, \"pointer formatting detected\");\n                }\n            }\n        }\n    }\n\n    fn check_unused_format_specifier(&self, placeholder: &FormatPlaceholder, arg: &Expr<'_>) {\n        let options = &placeholder.format_options;\n\n        if let Some(placeholder_span) = placeholder.span\n            && *options != FormatOptions::default()\n            && let ty = self.cx.typeck_results().expr_ty(arg).peel_refs()\n            && ty.is_lang_item(self.cx, LangItem::FormatArguments)\n        {\n            span_lint_and_then(\n                self.cx,\n                UNUSED_FORMAT_SPECS,\n                placeholder_span,\n                \"format specifiers have no effect on `format_args!()`\",\n                |diag| {\n                    let mut suggest_format = |spec| {\n                        let message = format!(\"for the {spec} to apply consider using `format!()`\");\n\n                        if let Some(mac_call) = matching_root_macro_call(self.cx, arg.span, sym::format_args_macro) {\n                            diag.span_suggestion(\n                                self.cx.sess().source_map().span_until_char(mac_call.span, '!'),\n                                message,\n                                \"format\",\n                                Applicability::MaybeIncorrect,\n                            );\n                        } else {\n                            diag.help(message);\n                        }\n                    };\n\n                    if options.width.is_some() {\n                        suggest_format(\"width\");\n                    }\n\n                    if options.precision.is_some() {\n                        suggest_format(\"precision\");\n                    }\n\n                    if let Some(format_span) = format_placeholder_format_span(placeholder) {\n                        diag.span_suggestion_verbose(\n                            format_span,\n                            \"if the current behavior is intentional, remove the format specifiers\",\n                            \"\",\n                            Applicability::MaybeIncorrect,\n                        );\n                    }\n                },\n            );\n        }\n    }\n\n    fn check_uninlined_args(&self) {\n        if self.format_args.span.from_expansion() {\n            return;\n        }\n        if self.macro_call.span.edition() < Edition2021\n            && (is_panic(self.cx, self.macro_call.def_id) || is_assert_macro(self.cx, self.macro_call.def_id))\n        {\n            // panic!, assert!, and debug_assert! before 2021 edition considers a single string argument as\n            // non-format\n            return;\n        }\n\n        let mut fixes = Vec::new();\n        // If any of the arguments are referenced by an index number,\n        // and that argument is not a simple variable and cannot be inlined,\n        // we cannot remove any other arguments in the format string,\n        // because the index numbers might be wrong after inlining.\n        // Example of an un-inlinable format:  print!(\"{}{1}\", foo, 2)\n        for (pos, usage) in self.format_arg_positions() {\n            if !self.check_one_arg(pos, usage, &mut fixes) {\n                return;\n            }\n        }\n\n        if fixes.is_empty() {\n            return;\n        }\n\n        // multiline span display suggestion is sometimes broken: https://github.com/rust-lang/rust/pull/102729#discussion_r988704308\n        // in those cases, make the code suggestion hidden\n        let multiline_fix = fixes\n            .iter()\n            .any(|(span, _)| self.cx.sess().source_map().is_multiline(*span));\n\n        // Suggest removing each argument only once, for example in `format!(\"{0} {0}\", arg)`.\n        fixes.sort_unstable_by_key(|(span, _)| *span);\n        fixes.dedup_by_key(|(span, _)| *span);\n\n        span_lint_and_then(\n            self.cx,\n            UNINLINED_FORMAT_ARGS,\n            self.macro_call.span,\n            \"variables can be used directly in the `format!` string\",\n            |diag| {\n                diag.multipart_suggestion_with_style(\n                    \"change this to\",\n                    fixes,\n                    Applicability::MachineApplicable,\n                    if multiline_fix { CompletelyHidden } else { ShowCode },\n                );\n            },\n        );\n    }\n\n    fn check_one_arg(&self, pos: &FormatArgPosition, usage: FormatParamUsage, fixes: &mut Vec<(Span, String)>) -> bool {\n        let index = pos.index.unwrap();\n        let arg = &self.format_args.arguments.all_args()[index];\n\n        if !matches!(arg.kind, FormatArgumentKind::Captured(_))\n            && let rustc_ast::ExprKind::Path(None, path) = &arg.expr.kind\n            && let [segment] = path.segments.as_slice()\n            && segment.args.is_none()\n            && let Some(arg_span) = format_arg_removal_span(self.format_args, index)\n            && let Some(pos_span) = pos.span\n        {\n            let replacement = match usage {\n                FormatParamUsage::Argument => segment.ident.name.to_string(),\n                FormatParamUsage::Width => format!(\"{}$\", segment.ident.name),\n                FormatParamUsage::Precision => format!(\".{}$\", segment.ident.name),\n            };\n            fixes.push((pos_span, replacement));\n            fixes.push((arg_span, String::new()));\n            true // successful inlining, continue checking\n        } else {\n            // Do not continue inlining (return false) in case\n            // * if we can't inline a numbered argument, e.g. `print!(\"{0} ...\", foo.bar, ...)`\n            // * if allow_mixed_uninlined_format_args is false and this arg hasn't been inlined already\n            pos.kind != FormatArgPositionKind::Number\n                && (!self.ignore_mixed || matches!(arg.kind, FormatArgumentKind::Captured(_)))\n        }\n    }\n\n    fn check_format_in_format_args(&self, name: Symbol, arg: &Expr<'_>) {\n        let expn_data = arg.span.ctxt().outer_expn_data();\n        if expn_data.call_site.from_expansion() {\n            return;\n        }\n        let Some(mac_id) = expn_data.macro_def_id else { return };\n        if !self.cx.tcx.is_diagnostic_item(sym::format_macro, mac_id) {\n            return;\n        }\n        span_lint_and_then(\n            self.cx,\n            FORMAT_IN_FORMAT_ARGS,\n            self.macro_call.span,\n            format!(\"`format!` in `{name}!` args\"),\n            |diag| {\n                diag.help(format!(\n                    \"combine the `format!(..)` arguments with the outer `{name}!(..)` call\"\n                ));\n                diag.help(\"or consider changing `format!` to `format_args!`\");\n            },\n        );\n    }\n\n    fn check_to_string_in_format_args(&self, name: Symbol, value: &Expr<'_>) {\n        let cx = self.cx;\n        if !value.span.from_expansion()\n            && let ExprKind::MethodCall(_, receiver, [], to_string_span) = value.kind\n            && cx\n                .typeck_results()\n                .type_dependent_def_id(value.hir_id)\n                .opt_parent(cx)\n                .is_diag_item(cx, sym::ToString)\n            && let receiver_ty = cx.typeck_results().expr_ty(receiver)\n            && let Some(display_trait_id) = cx.tcx.get_diagnostic_item(sym::Display)\n            && let (n_needed_derefs, target) =\n                count_needed_derefs(receiver_ty, cx.typeck_results().expr_adjustments(receiver).iter())\n            && implements_trait(cx, target, display_trait_id, &[])\n            && let Some(sized_trait_id) = cx.tcx.lang_items().sized_trait()\n            && let Some(receiver_snippet) = receiver.span.source_callsite().get_source_text(cx)\n        {\n            let needs_ref = !implements_trait(cx, receiver_ty, sized_trait_id, &[]);\n            if n_needed_derefs == 0 && !needs_ref {\n                span_lint_and_sugg(\n                    cx,\n                    TO_STRING_IN_FORMAT_ARGS,\n                    to_string_span.with_lo(receiver.span.source_callsite().hi()),\n                    format!(\"`to_string` applied to a type that implements `Display` in `{name}!` args\"),\n                    \"remove this\",\n                    String::new(),\n                    Applicability::MachineApplicable,\n                );\n            } else {\n                span_lint_and_sugg(\n                    cx,\n                    TO_STRING_IN_FORMAT_ARGS,\n                    value.span,\n                    format!(\"`to_string` applied to a type that implements `Display` in `{name}!` args\"),\n                    \"use this\",\n                    format!(\n                        \"{}{:*>n_needed_derefs$}{receiver_snippet}\",\n                        if needs_ref { \"&\" } else { \"\" },\n                        \"\"\n                    ),\n                    Applicability::MachineApplicable,\n                );\n            }\n        }\n    }\n\n    fn check_unnecessary_debug_formatting(&self, name: Symbol, value: &Expr<'tcx>) {\n        let cx = self.cx;\n        if !is_in_test(cx.tcx, value.hir_id)\n            && !value.span.from_expansion()\n            && !is_from_proc_macro(cx, value)\n            && let ty = cx.typeck_results().expr_ty(value)\n            && self.can_display_format(ty)\n        {\n            // If the parent function is a method of `Debug`, we don't want to lint\n            // because it is likely that the user wants to use `Debug` formatting.\n            let parent_fn = cx.tcx.hir_get_parent_item(value.hir_id);\n            if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn)\n                && let Some(trait_def_id) = trait_ref.trait_def_id()\n                && cx.tcx.is_diagnostic_item(sym::Debug, trait_def_id)\n            {\n                return;\n            }\n\n            let snippet = snippet(cx.sess(), value.span, \"..\");\n            span_lint_and_then(\n                cx,\n                UNNECESSARY_DEBUG_FORMATTING,\n                value.span,\n                format!(\"unnecessary `Debug` formatting in `{name}!` args\"),\n                |diag| {\n                    diag.help(format!(\n                        \"use `Display` formatting and change this to `{snippet}.display()`\"\n                    ));\n                    diag.note(\n                        \"switching to `Display` formatting will change how the value is shown; \\\n                         escaped characters will no longer be escaped and surrounding quotes will \\\n                         be removed\",\n                    );\n                },\n            );\n        }\n    }\n\n    fn format_arg_positions(&self) -> impl Iterator<Item = (&FormatArgPosition, FormatParamUsage)> {\n        self.format_args.template.iter().flat_map(|piece| match piece {\n            FormatArgsPiece::Placeholder(placeholder) => {\n                let mut positions = ArrayVec::<_, 3>::new();\n\n                positions.push((&placeholder.argument, FormatParamUsage::Argument));\n                if let Some(FormatCount::Argument(position)) = &placeholder.format_options.width {\n                    positions.push((position, FormatParamUsage::Width));\n                }\n                if let Some(FormatCount::Argument(position)) = &placeholder.format_options.precision {\n                    positions.push((position, FormatParamUsage::Precision));\n                }\n\n                positions\n            },\n            FormatArgsPiece::Literal(_) => ArrayVec::new(),\n        })\n    }\n\n    /// Returns true if the format argument at `index` is referred to by multiple format params\n    fn is_aliased(&self, index: usize) -> bool {\n        self.format_arg_positions()\n            .filter(|(position, _)| position.index == Ok(index))\n            .at_most_one()\n            .is_err()\n    }\n\n    fn can_display_format(&self, ty: Ty<'tcx>) -> bool {\n        let ty = ty.peel_refs();\n\n        if let Some(msrv) = self.ty_msrv_map.get(&ty)\n            && msrv.is_none_or(|msrv| self.msrv.meets(self.cx, msrv))\n        {\n            return true;\n        }\n\n        // Even if `ty` is not in `self.ty_msrv_map`, check whether `ty` implements `Deref` with\n        // a `Target` that is in `self.ty_msrv_map`.\n        if let Some(deref_trait_id) = self.cx.tcx.lang_items().deref_trait()\n            && implements_trait(self.cx, ty, deref_trait_id, &[])\n            && let Some(target_ty) = self.cx.get_associated_type(ty, deref_trait_id, sym::Target)\n            && let Some(msrv) = self.ty_msrv_map.get(&target_ty)\n            && msrv.is_none_or(|msrv| self.msrv.meets(self.cx, msrv))\n        {\n            return true;\n        }\n\n        false\n    }\n\n    fn has_pointer_debug(&mut self, ty: Ty<'tcx>, depth: usize) -> bool {\n        let cx = self.cx;\n        let tcx = cx.tcx;\n        if !tcx.recursion_limit().value_within_limit(depth) {\n            return false;\n        }\n        let depth = depth + 1;\n        let typing_env = cx.typing_env();\n        let ty = tcx.normalize_erasing_regions(typing_env, ty);\n        match ty.kind() {\n            ty::RawPtr(..) | ty::FnPtr(..) | ty::FnDef(..) => true,\n            ty::Ref(_, t, _) | ty::Slice(t) | ty::Array(t, _) => self.has_pointer_debug(*t, depth),\n            ty::Tuple(ts) => ts.iter().any(|t| self.has_pointer_debug(t, depth)),\n            ty::Adt(adt, args) => {\n                match self.has_pointer_format.entry(ty) {\n                    Entry::Occupied(o) => return *o.get(),\n                    Entry::Vacant(v) => v.insert(false),\n                };\n                let derived_debug = if let Some(&known) = self.has_derived_debug.get(&ty) {\n                    known\n                } else {\n                    let Some(trait_id) = tcx.get_diagnostic_item(sym::Debug) else {\n                        return false;\n                    };\n                    let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);\n                    let trait_ref = TraitRef::new(tcx, trait_id, [GenericArg::from(ty)]);\n                    let obligation = Obligation {\n                        cause: ObligationCause::dummy(),\n                        param_env,\n                        recursion_depth: 0,\n                        predicate: trait_ref.upcast(tcx),\n                    };\n                    let selection = SelectionContext::new(&infcx).select(&obligation);\n                    let derived = if let Ok(Some(Selection::UserDefined(data))) = selection {\n                        find_attr!(tcx, data.impl_def_id, AutomaticallyDerived(..))\n                    } else {\n                        false\n                    };\n                    self.has_derived_debug.insert(ty, derived);\n                    derived\n                };\n                let pointer_debug = derived_debug\n                    && adt.all_fields().any(|f| {\n                        self.has_pointer_debug(tcx.normalize_erasing_regions(typing_env, f.ty(tcx, args)), depth)\n                    });\n                self.has_pointer_format.insert(ty, pointer_debug);\n                pointer_debug\n            },\n            _ => false,\n        }\n    }\n}\n\nfn make_ty_msrv_map(tcx: TyCtxt<'_>) -> FxHashMap<Ty<'_>, Option<RustcVersion>> {\n    [(sym::OsStr, Some(msrvs::OS_STR_DISPLAY)), (sym::Path, None)]\n        .into_iter()\n        .filter_map(|(name, feature)| {\n            tcx.get_diagnostic_item(name).map(|def_id| {\n                let ty = Ty::new_adt(tcx, tcx.adt_def(def_id), List::empty());\n                (ty, feature)\n            })\n        })\n        .collect()\n}\n\nfn count_needed_derefs<'tcx, I>(mut ty: Ty<'tcx>, mut iter: I) -> (usize, Ty<'tcx>)\nwhere\n    I: Iterator<Item = &'tcx Adjustment<'tcx>>,\n{\n    let mut n_total = 0;\n    let mut n_needed = 0;\n    loop {\n        if let Some(Adjustment {\n            kind: Adjust::Deref(deref),\n            target,\n        }) = iter.next()\n        {\n            n_total += 1;\n            if let DerefAdjustKind::Overloaded(..) = deref {\n                n_needed = n_total;\n            }\n            ty = *target;\n        } else {\n            return (n_needed, ty);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/format_impl.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};\nuse clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, is_format_macro, root_macro_call_first_node};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::{get_parent_as_impl, peel_ref_operators, sym};\nuse rustc_ast::{FormatArgsPiece, FormatTrait};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Impl, ImplItem, ImplItemKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Symbol;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `println`, `print`, `eprintln` or `eprint` in an\n    /// implementation of a formatting trait.\n    ///\n    /// ### Why is this bad?\n    /// Using a print macro is likely unintentional since formatting traits\n    /// should write to the `Formatter`, not stdout/stderr.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::fmt::{Display, Error, Formatter};\n    ///\n    /// struct S;\n    /// impl Display for S {\n    ///     fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {\n    ///         println!(\"S\");\n    ///\n    ///         Ok(())\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::fmt::{Display, Error, Formatter};\n    ///\n    /// struct S;\n    /// impl Display for S {\n    ///     fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {\n    ///         writeln!(f, \"S\");\n    ///\n    ///         Ok(())\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub PRINT_IN_FORMAT_IMPL,\n    suspicious,\n    \"use of a print macro in a formatting trait impl\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for format trait implementations (e.g. `Display`) with a recursive call to itself\n    /// which uses `self` as a parameter.\n    /// This is typically done indirectly with the `write!` macro or with `to_string()`.\n    ///\n    /// ### Why is this bad?\n    /// This will lead to infinite recursion and a stack overflow.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// use std::fmt;\n    ///\n    /// struct Structure(i32);\n    /// impl fmt::Display for Structure {\n    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n    ///         write!(f, \"{}\", self.to_string())\n    ///     }\n    /// }\n    ///\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::fmt;\n    ///\n    /// struct Structure(i32);\n    /// impl fmt::Display for Structure {\n    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n    ///         write!(f, \"{}\", self.0)\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub RECURSIVE_FORMAT_IMPL,\n    correctness,\n    \"Format trait method called while implementing the same Format trait\"\n}\n\nimpl_lint_pass!(FormatImpl => [PRINT_IN_FORMAT_IMPL, RECURSIVE_FORMAT_IMPL]);\n\n#[derive(Clone, Copy)]\nstruct FormatTraitNames {\n    /// e.g. `sym::Display`\n    name: Symbol,\n    /// `f` in `fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {}`\n    formatter_name: Option<Symbol>,\n}\n\npub struct FormatImpl {\n    format_args: FormatArgsStorage,\n    // Whether we are inside Display or Debug trait impl - None for neither\n    format_trait_impl: Option<FormatTraitNames>,\n}\n\nimpl FormatImpl {\n    pub fn new(format_args: FormatArgsStorage) -> Self {\n        Self {\n            format_args,\n            format_trait_impl: None,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for FormatImpl {\n    fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {\n        self.format_trait_impl = is_format_trait_impl(cx, impl_item);\n    }\n\n    fn check_impl_item_post(&mut self, cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {\n        // Assume no nested Impl of Debug and Display within each other\n        if is_format_trait_impl(cx, impl_item).is_some() {\n            self.format_trait_impl = None;\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let Some(format_trait_impl) = self.format_trait_impl {\n            let linter = FormatImplExpr {\n                cx,\n                format_args: &self.format_args,\n                expr,\n                format_trait_impl,\n            };\n            linter.check_to_string_in_display();\n            linter.check_self_in_format_args();\n            linter.check_print_in_format_impl();\n        }\n    }\n}\n\nstruct FormatImplExpr<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    format_args: &'a FormatArgsStorage,\n    expr: &'tcx Expr<'tcx>,\n    format_trait_impl: FormatTraitNames,\n}\n\nimpl FormatImplExpr<'_, '_> {\n    fn check_to_string_in_display(&self) {\n        if self.format_trait_impl.name == sym::Display\n            && let ExprKind::MethodCall(path, self_arg, [], _) = self.expr.kind\n            // Get the hir_id of the object we are calling the method on\n            // Is the method to_string() ?\n            && path.ident.name == sym::to_string\n            // Is the method a part of the ToString trait? (i.e. not to_string() implemented\n            // separately)\n            && self\n                .cx\n                .typeck_results()\n                .type_dependent_def_id(self.expr.hir_id)\n                .opt_parent(self.cx)\n                .is_diag_item(self.cx, sym::ToString)\n            // Is the method is called on self\n            && let ExprKind::Path(QPath::Resolved(_, path)) = self_arg.kind\n            && let [segment] = path.segments\n            && segment.ident.name == kw::SelfLower\n        {\n            span_lint(\n                self.cx,\n                RECURSIVE_FORMAT_IMPL,\n                self.expr.span,\n                \"using `self.to_string` in `fmt::Display` implementation will cause infinite recursion\",\n            );\n        }\n    }\n\n    fn check_self_in_format_args(&self) {\n        // Check each arg in format calls - do we ever use Display on self (directly or via deref)?\n        if let Some(outer_macro) = root_macro_call_first_node(self.cx, self.expr)\n            && let macro_def_id = outer_macro.def_id\n            && is_format_macro(self.cx, macro_def_id)\n            && let Some(format_args) = self.format_args.get(self.cx, self.expr, outer_macro.expn)\n        {\n            for piece in &format_args.template {\n                if let FormatArgsPiece::Placeholder(placeholder) = piece\n                    && let trait_name = match placeholder.format_trait {\n                        FormatTrait::Display => sym::Display,\n                        FormatTrait::Debug => sym::Debug,\n                        FormatTrait::LowerExp => sym::LowerExp,\n                        FormatTrait::UpperExp => sym::UpperExp,\n                        FormatTrait::Octal => sym::Octal,\n                        FormatTrait::Pointer => sym::Pointer,\n                        FormatTrait::Binary => sym::Binary,\n                        FormatTrait::LowerHex => sym::LowerHex,\n                        FormatTrait::UpperHex => sym::UpperHex,\n                    }\n                    && trait_name == self.format_trait_impl.name\n                    && let Ok(index) = placeholder.argument.index\n                    && let Some(arg) = format_args.arguments.all_args().get(index)\n                    && let Some(arg_expr) = find_format_arg_expr(self.expr, arg)\n                {\n                    self.check_format_arg_self(arg_expr);\n                }\n            }\n        }\n    }\n\n    fn check_format_arg_self(&self, arg: &Expr<'_>) {\n        // Handle multiple dereferencing of references e.g. &&self\n        // Handle dereference of &self -> self that is equivalent (i.e. via *self in fmt() impl)\n        // Since the argument to fmt is itself a reference: &self\n        let reference = peel_ref_operators(self.cx, arg);\n        // Is the reference self?\n        if reference.res_local_id().map(|x| self.cx.tcx.hir_name(x)) == Some(kw::SelfLower) {\n            let FormatTraitNames { name, .. } = self.format_trait_impl;\n            span_lint(\n                self.cx,\n                RECURSIVE_FORMAT_IMPL,\n                self.expr.span,\n                format!(\"using `self` as `{name}` in `impl {name}` will cause infinite recursion\"),\n            );\n        }\n    }\n\n    fn check_print_in_format_impl(&self) {\n        if let Some(macro_call) = root_macro_call_first_node(self.cx, self.expr)\n            && let Some(name) = self.cx.tcx.get_diagnostic_name(macro_call.def_id)\n        {\n            let replacement = match name {\n                sym::print_macro | sym::eprint_macro => \"write\",\n                sym::println_macro | sym::eprintln_macro => \"writeln\",\n                _ => return,\n            };\n\n            let name = name.as_str().strip_suffix(\"_macro\").unwrap();\n\n            span_lint_and_sugg(\n                self.cx,\n                PRINT_IN_FORMAT_IMPL,\n                macro_call.span,\n                format!(\"use of `{name}!` in `{}` impl\", self.format_trait_impl.name),\n                \"replace with\",\n                if let Some(formatter_name) = self.format_trait_impl.formatter_name {\n                    format!(\"{replacement}!({formatter_name}, ..)\")\n                } else {\n                    format!(\"{replacement}!(..)\")\n                },\n                Applicability::HasPlaceholders,\n            );\n        }\n    }\n}\n\nfn is_format_trait_impl(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) -> Option<FormatTraitNames> {\n    if impl_item.ident.name == sym::fmt\n        && let ImplItemKind::Fn(_, body_id) = impl_item.kind\n        && let Some(Impl {\n            of_trait: Some(of_trait),\n            ..\n        }) = get_parent_as_impl(cx.tcx, impl_item.hir_id())\n        && let Some(did) = of_trait.trait_ref.trait_def_id()\n        && let Some(name) = cx.tcx.get_diagnostic_name(did)\n        && matches!(name, sym::Debug | sym::Display)\n    {\n        let body = cx.tcx.hir_body(body_id);\n        let formatter_name = body\n            .params\n            .get(1)\n            .and_then(|param| param.pat.simple_ident())\n            .map(|ident| ident.name);\n\n        Some(FormatTraitNames { name, formatter_name })\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/format_push_string.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::{std_or_core, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{AssignOpKind, Expr, ExprKind, LangItem, MatchSource};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects cases where the result of a `format!` call is\n    /// appended to an existing `String`.\n    ///\n    /// ### Why is this bad?\n    /// Introduces an extra, avoidable heap allocation.\n    ///\n    /// ### Known problems\n    /// `format!` returns a `String` but `write!` returns a `Result`.\n    /// Thus you are forced to ignore the `Err` variant to achieve the same API.\n    ///\n    /// While using `write!` in the suggested way should never fail, this isn't necessarily clear to the programmer.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut s = String::new();\n    /// s += &format!(\"0x{:X}\", 1024);\n    /// s.push_str(&format!(\"0x{:X}\", 1024));\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::fmt::Write as _; // import without risk of name clashing\n    ///\n    /// let mut s = String::new();\n    /// let _ = write!(s, \"0x{:X}\", 1024);\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub FORMAT_PUSH_STRING,\n    pedantic,\n    \"`format!(..)` appended to existing `String`\"\n}\n\nimpl_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]);\n\npub(crate) struct FormatPushString {\n    format_args: FormatArgsStorage,\n}\n\nenum FormatSearchResults {\n    /// The expression is itself a `format!()` invocation -- we can make a suggestion to replace it\n    Direct(Span),\n    /// The expression contains zero or more `format!()`s, e.g.:\n    /// ```ignore\n    /// if true {\n    ///     format!(\"hello\")\n    /// } else {\n    ///     format!(\"world\")\n    /// }\n    /// ```\n    /// or\n    /// ```ignore\n    /// match true {\n    ///     true => format!(\"hello\"),\n    ///     false => format!(\"world\"),\n    /// }\n    Nested(Vec<Span>),\n}\n\nimpl FormatPushString {\n    pub(crate) fn new(format_args: FormatArgsStorage) -> Self {\n        Self { format_args }\n    }\n\n    fn find_formats<'tcx>(&self, cx: &LateContext<'_>, e: &'tcx Expr<'tcx>) -> FormatSearchResults {\n        let expr_as_format = |e| {\n            if let Some(macro_call) = root_macro_call_first_node(cx, e)\n                && cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)\n                && let Some(format_args) = self.format_args.get(cx, e, macro_call.expn)\n            {\n                Some(format_args_inputs_span(format_args))\n            } else {\n                None\n            }\n        };\n\n        let e = e.peel_blocks().peel_borrows();\n        if let Some(fmt) = expr_as_format(e) {\n            FormatSearchResults::Direct(fmt)\n        } else {\n            fn inner<'tcx>(\n                e: &'tcx Expr<'tcx>,\n                expr_as_format: &impl Fn(&'tcx Expr<'tcx>) -> Option<Span>,\n                out: &mut Vec<Span>,\n            ) {\n                let e = e.peel_blocks().peel_borrows();\n\n                match e.kind {\n                    _ if expr_as_format(e).is_some() => out.push(e.span),\n                    ExprKind::Match(_, arms, MatchSource::Normal) => {\n                        for arm in arms {\n                            inner(arm.body, expr_as_format, out);\n                        }\n                    },\n                    ExprKind::If(_, then, els) => {\n                        inner(then, expr_as_format, out);\n                        if let Some(els) = els {\n                            inner(els, expr_as_format, out);\n                        }\n                    },\n                    _ => {},\n                }\n            }\n            let mut spans = vec![];\n            inner(e, &expr_as_format, &mut spans);\n            FormatSearchResults::Nested(spans)\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for FormatPushString {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let (recv, arg) = match expr.kind {\n            ExprKind::MethodCall(_, recv, [arg], _) => {\n                if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n                    && cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id)\n                {\n                    (recv, arg)\n                } else {\n                    return;\n                }\n            },\n            ExprKind::AssignOp(op, recv, arg) if op.node == AssignOpKind::AddAssign && is_string(cx, recv) => {\n                (recv, arg)\n            },\n            _ => return,\n        };\n        let Some(std_or_core) = std_or_core(cx) else {\n            // not even `core` is available, so can't suggest `write!`\n            return;\n        };\n        match self.find_formats(cx, arg) {\n            FormatSearchResults::Direct(format_args) => {\n                span_lint_and_then(\n                    cx,\n                    FORMAT_PUSH_STRING,\n                    expr.span,\n                    \"`format!(..)` appended to existing `String`\",\n                    |diag| {\n                        let mut app = Applicability::MaybeIncorrect;\n                        let msg = \"consider using `write!` to avoid the extra allocation\";\n\n                        let sugg = format!(\n                            \"let _ = write!({recv}, {format_args})\",\n                            recv = snippet_with_context(cx.sess(), recv.span, expr.span.ctxt(), \"_\", &mut app).0,\n                            format_args = snippet_with_applicability(cx.sess(), format_args, \"..\", &mut app),\n                        );\n                        diag.span_suggestion_verbose(expr.span, msg, sugg, app);\n\n                        // TODO: omit the note if the `Write` trait is imported at point\n                        // Tip: `TyCtxt::in_scope_traits` isn't it -- it returns a non-empty list only when called on\n                        // the `HirId` of a `ExprKind::MethodCall` that is a call of a _trait_ method.\n                        diag.note(format!(\"you may need to import the `{std_or_core}::fmt::Write` trait\"));\n                    },\n                );\n            },\n            FormatSearchResults::Nested(spans) => {\n                if !spans.is_empty() {\n                    span_lint_and_then(\n                        cx,\n                        FORMAT_PUSH_STRING,\n                        expr.span,\n                        \"`format!(..)` appended to existing `String`\",\n                        |diag| {\n                            diag.help(\"consider using `write!` to avoid the extra allocation\");\n                            diag.span_labels(spans, \"`format!` used here\");\n\n                            // TODO: omit the note if the `Write` trait is imported at point\n                            // Tip: `TyCtxt::in_scope_traits` isn't it -- it returns a non-empty list only when called\n                            // on the `HirId` of a `ExprKind::MethodCall` that is a call of\n                            // a _trait_ method.\n                            diag.note(format!(\"you may need to import the `{std_or_core}::fmt::Write` trait\"));\n                        },\n                    );\n                }\n            },\n        }\n    }\n}\n\nfn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    cx.typeck_results()\n        .expr_ty(e)\n        .peel_refs()\n        .is_lang_item(cx, LangItem::String)\n}\n"
  },
  {
    "path": "clippy_lints/src/formatting.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};\nuse clippy_utils::is_span_if;\nuse clippy_utils::source::snippet_opt;\nuse rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for possible missing comma in an array. It lints if\n    /// an array element is a binary operator expression and it lies on two lines.\n    ///\n    /// ### Why is this bad?\n    /// This could lead to unexpected results.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let a = &[\n    ///     -1, -2, -3 // <= no comma here\n    ///     -4, -5, -6\n    /// ];\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub POSSIBLE_MISSING_COMMA,\n    correctness,\n    \"possible missing comma in array\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for an `if` expression followed by either a block or another `if` that\n    /// looks like it should have an `else` between them.\n    ///\n    /// ### Why is this bad?\n    /// This is probably some refactoring remnant, even if the code is correct, it\n    /// might look confusing.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// if foo {\n    /// } { // looks like an `else` is missing here\n    /// }\n    ///\n    /// if foo {\n    /// } if bar { // looks like an `else` is missing here\n    /// }\n    /// ```\n    #[clippy::version = \"1.91.0\"]\n    pub POSSIBLE_MISSING_ELSE,\n    suspicious,\n    \"possibly missing `else`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of the non-existent `=*`, `=!` and `=-`\n    /// operators.\n    ///\n    /// ### Why is this bad?\n    /// This is either a typo of `*=`, `!=` or `-=` or\n    /// confusing.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// a =- 42; // confusing, should it be `a -= 42` or `a = -42`?\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SUSPICIOUS_ASSIGNMENT_FORMATTING,\n    suspicious,\n    \"suspicious formatting of `*=`, `-=` or `!=`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for formatting of `else`. It lints if the `else`\n    /// is followed immediately by a newline or the `else` seems to be missing.\n    ///\n    /// ### Why is this bad?\n    /// This is probably some refactoring remnant, even if the\n    /// code is correct, it might look confusing.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// if foo {\n    /// } { // looks like an `else` is missing here\n    /// }\n    ///\n    /// if foo {\n    /// } if bar { // looks like an `else` is missing here\n    /// }\n    ///\n    /// if foo {\n    /// } else\n    ///\n    /// { // this is the `else` block of the previous `if`, but should it be?\n    /// }\n    ///\n    /// if foo {\n    /// } else\n    ///\n    /// if bar { // this is the `else` block of the previous `if`, but should it be?\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SUSPICIOUS_ELSE_FORMATTING,\n    suspicious,\n    \"suspicious formatting of `else`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks the formatting of a unary operator on the right hand side\n    /// of a binary operator. It lints if there is no space between the binary and unary operators,\n    /// but there is a space between the unary and its operand.\n    ///\n    /// ### Why is this bad?\n    /// This is either a typo in the binary operator or confusing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let foo = true;\n    /// # let bar = false;\n    /// // &&! looks like a different operator\n    /// if foo &&! bar {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let foo = true;\n    /// # let bar = false;\n    /// if foo && !bar {}\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub SUSPICIOUS_UNARY_OP_FORMATTING,\n    suspicious,\n    \"suspicious formatting of unary `-` or `!` on the RHS of a BinOp\"\n}\n\ndeclare_lint_pass!(Formatting => [\n    POSSIBLE_MISSING_COMMA,\n    POSSIBLE_MISSING_ELSE,\n    SUSPICIOUS_ASSIGNMENT_FORMATTING,\n    SUSPICIOUS_ELSE_FORMATTING,\n    SUSPICIOUS_UNARY_OP_FORMATTING,\n]);\n\nimpl EarlyLintPass for Formatting {\n    fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) {\n        for w in block.stmts.windows(2) {\n            if let (StmtKind::Expr(first), StmtKind::Expr(second) | StmtKind::Semi(second)) = (&w[0].kind, &w[1].kind) {\n                check_missing_else(cx, first, second);\n            }\n        }\n    }\n\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        check_assign(cx, expr);\n        check_unop(cx, expr);\n        check_else(cx, expr);\n        check_array(cx, expr);\n    }\n}\n\n/// Implementation of the `SUSPICIOUS_ASSIGNMENT_FORMATTING` lint.\nfn check_assign(cx: &EarlyContext<'_>, expr: &Expr) {\n    if let ExprKind::Assign(ref lhs, ref rhs, _) = expr.kind\n        && !lhs.span.from_expansion()\n        && !rhs.span.from_expansion()\n    {\n        let eq_span = lhs.span.between(rhs.span);\n        if let ExprKind::Unary(op, ref sub_rhs) = rhs.kind\n            && let Some(eq_snippet) = snippet_opt(cx, eq_span)\n        {\n            let op = op.as_str();\n            let eqop_span = lhs.span.between(sub_rhs.span);\n            if eq_snippet.ends_with('=') {\n                span_lint_and_note(\n                    cx,\n                    SUSPICIOUS_ASSIGNMENT_FORMATTING,\n                    eqop_span,\n                    format!(\n                        \"this looks like you are trying to use `.. {op}= ..`, but you \\\n                                 really are doing `.. = ({op} ..)`\"\n                    ),\n                    None,\n                    format!(\"to remove this lint, use either `{op}=` or `= {op}`\"),\n                );\n            }\n        }\n    }\n}\n\n/// Implementation of the `SUSPICIOUS_UNARY_OP_FORMATTING` lint.\nfn check_unop(cx: &EarlyContext<'_>, expr: &Expr) {\n    if let ExprKind::Binary(ref binop, ref lhs, ref rhs) = expr.kind\n        && !lhs.span.from_expansion() && !rhs.span.from_expansion()\n        // span between BinOp LHS and RHS\n        && let binop_span = lhs.span.between(rhs.span)\n        // if RHS is an UnOp\n        && let ExprKind::Unary(op, ref un_rhs) = rhs.kind\n        // from UnOp operator to UnOp operand\n        && let unop_operand_span = rhs.span.until(un_rhs.span)\n        && let Some(binop_snippet) = snippet_opt(cx, binop_span)\n        && let Some(unop_operand_snippet) = snippet_opt(cx, unop_operand_span)\n        && let binop_str = binop.node.as_str()\n        // no space after BinOp operator and space after UnOp operator\n        && binop_snippet.ends_with(binop_str) && unop_operand_snippet.ends_with(' ')\n    {\n        let unop_str = op.as_str();\n        let eqop_span = lhs.span.between(un_rhs.span);\n        span_lint_and_help(\n            cx,\n            SUSPICIOUS_UNARY_OP_FORMATTING,\n            eqop_span,\n            format!(\n                \"by not having a space between `{binop_str}` and `{unop_str}` it looks like \\\n                 `{binop_str}{unop_str}` is a single operator\"\n            ),\n            None,\n            format!(\"put a space between `{binop_str}` and `{unop_str}` and remove the space after `{unop_str}`\"),\n        );\n    }\n}\n\n/// Implementation of the `SUSPICIOUS_ELSE_FORMATTING` lint for weird `else`.\nfn check_else(cx: &EarlyContext<'_>, expr: &Expr) {\n    if let ExprKind::If(_, then, Some(else_)) = &expr.kind\n        && (is_block(else_) || is_if(else_))\n        && !then.span.from_expansion() && !else_.span.from_expansion()\n        && !expr.span.in_external_macro(cx.sess().source_map())\n\n        // workaround for rust-lang/rust#43081\n        && expr.span.lo().0 != 0 && expr.span.hi().0 != 0\n\n        // this will be a span from the closing ‘}’ of the “then” block (excluding) to\n        // the “if” of the “else if” block (excluding)\n        && let else_span = then.span.between(else_.span)\n\n        // the snippet should look like \" else \\n    \" with maybe comments anywhere\n        // it’s bad when there is a ‘\\n’ after the “else”\n        && let Some(else_snippet) = snippet_opt(cx, else_span)\n        && let Some((pre_else, post_else)) = else_snippet.split_once(\"else\")\n        && !else_snippet.contains('/')\n        && let Some((_, post_else_post_eol)) = post_else.split_once('\\n')\n    {\n        // Allow allman style braces `} \\n else \\n {`\n        if is_block(else_)\n            && let Some((_, pre_else_post_eol)) = pre_else.split_once('\\n')\n            // Exactly one eol before and after the else\n            && !pre_else_post_eol.contains('\\n')\n            && !post_else_post_eol.contains('\\n')\n        {\n            return;\n        }\n\n        // Don't warn if the only thing inside post_else_post_eol is a comment block.\n        let trimmed_post_else_post_eol = post_else_post_eol.trim();\n        if trimmed_post_else_post_eol.starts_with(\"/*\") && trimmed_post_else_post_eol.ends_with(\"*/\") {\n            return;\n        }\n\n        let else_desc = if is_if(else_) { \"if\" } else { \"{..}\" };\n        span_lint_and_note(\n            cx,\n            SUSPICIOUS_ELSE_FORMATTING,\n            else_span,\n            format!(\"this is an `else {else_desc}` but the formatting might hide it\"),\n            None,\n            format!(\n                \"to remove this lint, remove the `else` or remove the new line between \\\n                 `else` and `{else_desc}`\",\n            ),\n        );\n    }\n}\n\n#[must_use]\nfn has_unary_equivalent(bin_op: BinOpKind) -> bool {\n    // &, *, -\n    bin_op == BinOpKind::And || bin_op == BinOpKind::Mul || bin_op == BinOpKind::Sub\n}\n\nfn indentation(cx: &EarlyContext<'_>, span: Span) -> usize {\n    cx.sess().source_map().lookup_char_pos(span.lo()).col.0\n}\n\n/// Implementation of the `POSSIBLE_MISSING_COMMA` lint for array\nfn check_array(cx: &EarlyContext<'_>, expr: &Expr) {\n    if let ExprKind::Array(ref array) = expr.kind {\n        for element in array {\n            if let ExprKind::Binary(ref op, ref lhs, _) = element.kind\n                && has_unary_equivalent(op.node)\n                && lhs.span.eq_ctxt(op.span)\n                && let space_span = lhs.span.between(op.span)\n                && let Some(space_snippet) = snippet_opt(cx, space_span)\n                && let lint_span = lhs.span.with_lo(lhs.span.hi())\n                && space_snippet.contains('\\n')\n                && indentation(cx, op.span) <= indentation(cx, lhs.span)\n            {\n                span_lint_and_note(\n                    cx,\n                    POSSIBLE_MISSING_COMMA,\n                    lint_span,\n                    \"possibly missing a comma here\",\n                    None,\n                    \"to remove this lint, add a comma or write the expr in a single line\",\n                );\n            }\n        }\n    }\n}\n\nfn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) {\n    if !first.span.from_expansion() && !second.span.from_expansion()\n        && matches!(first.kind, ExprKind::If(..))\n        && (is_block(second) || is_if(second))\n\n        // Proc-macros can give weird spans. Make sure this is actually an `if`.\n        && is_span_if(cx, first.span)\n\n        // If there is a line break between the two expressions, don't lint.\n        // If there is a non-whitespace character, this span came from a proc-macro.\n        && let else_span = first.span.between(second.span)\n        && let Some(else_snippet) = snippet_opt(cx, else_span)\n        && !else_snippet.chars().any(|c| c == '\\n' || !c.is_whitespace())\n    {\n        let (looks_like, next_thing) = if is_if(second) {\n            (\"an `else if`\", \"the second `if`\")\n        } else {\n            (\"an `else {..}`\", \"the next block\")\n        };\n\n        span_lint_and_note(\n            cx,\n            POSSIBLE_MISSING_ELSE,\n            else_span,\n            format!(\"this looks like {looks_like} but the `else` is missing\"),\n            None,\n            format!(\"to remove this lint, add the missing `else` or add a new line before {next_thing}\"),\n        );\n    }\n}\n\nfn is_block(expr: &Expr) -> bool {\n    matches!(expr.kind, ExprKind::Block(..))\n}\n\n/// Check if the expression is an `if` or `if let`\nfn is_if(expr: &Expr) -> bool {\n    matches!(expr.kind, ExprKind::If(..))\n}\n"
  },
  {
    "path": "clippy_lints/src/four_forward_slashes.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt as _;\nuse itertools::Itertools;\nuse rustc_errors::Applicability;\nuse rustc_hir::Item;\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for outer doc comments written with 4 forward slashes (`////`).\n    ///\n    /// ### Why is this bad?\n    /// This is (probably) a typo, and results in it not being a doc comment; just a regular\n    /// comment.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// //// My amazing data structure\n    /// pub struct Foo {\n    ///     // ...\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// /// My amazing data structure\n    /// pub struct Foo {\n    ///     // ...\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub FOUR_FORWARD_SLASHES,\n    suspicious,\n    \"comments with 4 forward slashes (`////`) likely intended to be doc comments (`///`)\"\n}\n\ndeclare_lint_pass!(FourForwardSlashes => [FOUR_FORWARD_SLASHES]);\n\nimpl<'tcx> LateLintPass<'tcx> for FourForwardSlashes {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if item.span.from_expansion() {\n            return;\n        }\n        let sm = cx.sess().source_map();\n        let mut span = cx\n            .tcx\n            .hir_attrs(item.hir_id())\n            .iter()\n            .filter(|i| i.is_doc_comment().is_some())\n            .fold(item.span.shrink_to_lo(), |span, attr| span.to(attr.span()));\n        let (Some(file), _, _, end_line, _) = sm.span_to_location_info(span) else {\n            return;\n        };\n        let mut bad_comments = vec![];\n        for line in (0..end_line.saturating_sub(1)).rev() {\n            let Some(contents) = file.get_line(line).map(|c| c.trim().to_owned()) else {\n                return;\n            };\n            // Keep searching until we find the next item\n            if !contents.is_empty() && !contents.starts_with(\"//\") && !contents.starts_with(\"#[\") {\n                break;\n            }\n\n            if contents.starts_with(\"////\") && !matches!(contents.chars().nth(4), Some('/' | '!')) {\n                let bounds = file.line_bounds(line);\n                let line_span = Span::with_root_ctxt(bounds.start, bounds.end);\n                span = line_span.to(span);\n                bad_comments.push((line_span, contents));\n            }\n        }\n\n        if !bad_comments.is_empty() {\n            span_lint_and_then(\n                cx,\n                FOUR_FORWARD_SLASHES,\n                span,\n                \"this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't\",\n                |diag| {\n                    let msg = if bad_comments.len() == 1 {\n                        \"make this a doc comment by removing one `/`\"\n                    } else {\n                        \"turn these into doc comments by removing one `/`\"\n                    };\n\n                    // If the comment contains a bare CR (not followed by a LF), do not propose an auto-fix\n                    // as bare CR are not allowed in doc comments.\n                    if span.check_source_text(cx, contains_bare_cr) {\n                        diag.help(msg)\n                            .note(\"bare CR characters are not allowed in doc comments\");\n                        return;\n                    }\n\n                    diag.multipart_suggestion(\n                        msg,\n                        bad_comments\n                            .into_iter()\n                            // It's a little unfortunate but the span includes the `\\n` yet the contents\n                            // do not, so we must add it back. If some codebase uses `\\r\\n` instead they\n                            // will need normalization but it should be fine\n                            .map(|(span, c)| (span, c.replacen(\"////\", \"///\", 1) + \"\\n\"))\n                            .collect(),\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n    }\n}\n\n/// Checks if `text` contains any CR not followed by a LF\nfn contains_bare_cr(text: &str) -> bool {\n    text.bytes().tuple_windows().any(|(a, b)| a == b'\\r' && b != b'\\n')\n}\n"
  },
  {
    "path": "clippy_lints/src/from_over_into.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::span_is_local;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{Visitor, walk_path};\nuse rustc_hir::{\n    FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemId, ImplItemKind, Item, ItemKind, PatKind, Path,\n    PathSegment, Ty, TyKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter::OnlyBodies;\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::{kw, sym};\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead.\n    ///\n    /// ### Why is this bad?\n    /// According the std docs implementing `From<..>` is preferred since it gives you `Into<..>` for free where the reverse isn't true.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct StringWrapper(String);\n    ///\n    /// impl Into<StringWrapper> for String {\n    ///     fn into(self) -> StringWrapper {\n    ///         StringWrapper(self)\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct StringWrapper(String);\n    ///\n    /// impl From<String> for StringWrapper {\n    ///     fn from(s: String) -> StringWrapper {\n    ///         StringWrapper(s)\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub FROM_OVER_INTO,\n    style,\n    \"Warns on implementations of `Into<..>` to use `From<..>`\"\n}\n\nimpl_lint_pass!(FromOverInto => [FROM_OVER_INTO]);\n\npub struct FromOverInto {\n    msrv: Msrv,\n}\n\nimpl FromOverInto {\n    pub fn new(conf: &'static Conf) -> Self {\n        FromOverInto { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for FromOverInto {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            self_ty,\n            items: [impl_item_ref],\n            ..\n        }) = item.kind\n            && let Some(into_trait_seg) = of_trait.trait_ref.path.segments.last()\n            // `impl Into<target_ty> for self_ty`\n            && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args\n            && span_is_local(item.span)\n            && let middle_trait_ref = cx.tcx.impl_trait_ref(item.owner_id).instantiate_identity()\n            && cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id)\n            && !matches!(middle_trait_ref.args.type_at(1).kind(), ty::Alias(ty::Opaque, _))\n            && self.msrv.meets(cx, msrvs::RE_REBALANCING_COHERENCE)\n        {\n            span_lint_and_then(\n                cx,\n                FROM_OVER_INTO,\n                cx.tcx.sess.source_map().guess_head_span(item.span),\n                \"an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\",\n                |diag| {\n                    // If the target type is likely foreign mention the orphan rules as it's a common source of\n                    // confusion\n                    if target_ty\n                        .peel_refs()\n                        .basic_res()\n                        .opt_def_id()\n                        .is_none_or(|id| !id.is_local())\n                    {\n                        diag.help(\n                            \"`impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\\n\\\n                            https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence\"\n                        );\n                    }\n\n                    let message = format!(\n                        \"replace the `Into` implementation with `From<{}>`\",\n                        middle_trait_ref.self_ty()\n                    );\n                    if let Some(suggestions) =\n                        convert_to_from(cx, into_trait_seg, target_ty.as_unambig_ty(), self_ty, *impl_item_ref)\n                    {\n                        diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable);\n                    } else {\n                        diag.help(message);\n                    }\n                },\n            );\n        }\n    }\n}\n\n/// Finds the occurrences of `Self` and `self`\n///\n/// Returns `ControlFlow::break` if any of the `self`/`Self` usages were from an expansion, or the\n/// body contained a binding already named `val`.\nstruct SelfFinder<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    /// Occurrences of `Self`\n    upper: Vec<Span>,\n    /// Occurrences of `self`\n    lower: Vec<Span>,\n}\n\nimpl<'tcx> Visitor<'tcx> for SelfFinder<'_, 'tcx> {\n    type Result = ControlFlow<()>;\n    type NestedFilter = OnlyBodies;\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n\n    fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> Self::Result {\n        for segment in path.segments {\n            match segment.ident.name {\n                kw::SelfLower => self.lower.push(segment.ident.span),\n                kw::SelfUpper => self.upper.push(segment.ident.span),\n                _ => continue,\n            }\n\n            if segment.ident.span.from_expansion() {\n                return ControlFlow::Break(());\n            }\n        }\n\n        walk_path(self, path)\n    }\n\n    fn visit_name(&mut self, name: Symbol) -> Self::Result {\n        if name == sym::val {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    }\n}\n\nfn convert_to_from(\n    cx: &LateContext<'_>,\n    into_trait_seg: &PathSegment<'_>,\n    target_ty: &Ty<'_>,\n    self_ty: &Ty<'_>,\n    impl_item_ref: ImplItemId,\n) -> Option<Vec<(Span, String)>> {\n    if !target_ty.find_self_aliases().is_empty() {\n        // It's tricky to expand self-aliases correctly, we'll ignore it to not cause a\n        // bad suggestion/fix.\n        return None;\n    }\n    let impl_item = cx.tcx.hir_impl_item(impl_item_ref);\n    let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else {\n        return None;\n    };\n    let body = cx.tcx.hir_body(body_id);\n    let [self_param] = body.params else { return None };\n    let PatKind::Binding(.., self_ident, None) = self_param.pat.kind else {\n        return None;\n    };\n\n    let from = self_ty.span.get_source_text(cx)?;\n    let into = target_ty.span.get_source_text(cx)?;\n\n    let mut suggestions = vec![\n        // impl Into<T> for U  ->  impl From<T> for U\n        //      ~~~~                    ~~~~\n        (into_trait_seg.ident.span, String::from(\"From\")),\n        // impl Into<T> for U  ->  impl Into<U> for U\n        //           ~                       ~\n        (target_ty.span, from.to_owned()),\n        // impl Into<T> for U  ->  impl Into<T> for T\n        //                  ~                       ~\n        (self_ty.span, into.to_owned()),\n        // fn into(self: U) -> T  ->  fn from(self) -> T\n        //    ~~~~                       ~~~~\n        (impl_item.ident.span, String::from(\"from\")),\n        // fn into([mut] self: U) -> T  ->  fn into([mut] val: T) -> T\n        //               ~~~~~~~                          ~~~~~~\n        (self_ident.span.to(self_param.ty_span), format!(\"val: {from}\")),\n    ];\n\n    if let FnRetTy::Return(_) = sig.decl.output {\n        // fn into(self) -> T  ->  fn into(self) -> Self\n        //                  ~                       ~~~~\n        suggestions.push((sig.decl.output.span(), String::from(\"Self\")));\n    }\n\n    let mut finder = SelfFinder {\n        cx,\n        upper: Vec::new(),\n        lower: Vec::new(),\n    };\n\n    if finder.visit_expr(body.value).is_break() {\n        return None;\n    }\n\n    // don't try to replace e.g. `Self::default()` with `&[T]::default()`\n    if !finder.upper.is_empty() && !matches!(self_ty.kind, TyKind::Path(_)) {\n        return None;\n    }\n\n    for span in finder.upper {\n        suggestions.push((span, from.to_owned()));\n    }\n    for span in finder.lower {\n        suggestions.push((span, String::from(\"val\")));\n    }\n\n    Some(suggestions)\n}\n"
  },
  {
    "path": "clippy_lints/src/from_raw_with_void_ptr.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::sym;\nuse clippy_utils::ty::is_c_void;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if we're passing a `c_void` raw pointer to `{Box,Rc,Arc,Weak}::from_raw(_)`\n    ///\n    /// ### Why is this bad?\n    /// When dealing with `c_void` raw pointers in FFI, it is easy to run into the pitfall of calling `from_raw` with the `c_void` pointer.\n    /// The type signature of `Box::from_raw` is `fn from_raw(raw: *mut T) -> Box<T>`, so if you pass a `*mut c_void` you will get a `Box<c_void>` (and similarly for `Rc`, `Arc` and `Weak`).\n    /// For this to be safe, `c_void` would need to have the same memory layout as the original type, which is often not the case.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::ffi::c_void;\n    /// let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;\n    /// let _ = unsafe { Box::from_raw(ptr) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::ffi::c_void;\n    /// # let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;\n    /// let _ = unsafe { Box::from_raw(ptr as *mut usize) };\n    /// ```\n    ///\n    #[clippy::version = \"1.67.0\"]\n    pub FROM_RAW_WITH_VOID_PTR,\n    suspicious,\n    \"creating a `Box` from a void raw pointer\"\n}\n\ndeclare_lint_pass!(FromRawWithVoidPtr => [FROM_RAW_WITH_VOID_PTR]);\n\nimpl LateLintPass<'_> for FromRawWithVoidPtr {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if let ExprKind::Call(box_from_raw, [arg]) = expr.kind\n            && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind\n            && seg.ident.name == sym::from_raw\n            && let Some(type_str) = ty.basic_res().opt_def_id().and_then(|id| def_id_matches_type(cx, id))\n            && let arg_kind = cx.typeck_results().expr_ty(arg).kind()\n            && let ty::RawPtr(ty, _) = arg_kind\n            && is_c_void(cx, *ty)\n        {\n            let msg = format!(\"creating a `{type_str}` from a void raw pointer\");\n            span_lint_and_help(\n                cx,\n                FROM_RAW_WITH_VOID_PTR,\n                expr.span,\n                msg,\n                Some(arg.span),\n                \"cast this to a pointer of the appropriate type\",\n            );\n        }\n    }\n}\n\n/// Checks whether a `DefId` matches `Box`, `Rc`, `Arc`, or one of the `Weak` types.\n/// Returns a static string slice with the name of the type, if one was found.\nfn def_id_matches_type(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {\n    // Box\n    if Some(def_id) == cx.tcx.lang_items().owned_box() {\n        return Some(\"Box\");\n    }\n\n    if let Some(symbol) = cx.tcx.get_diagnostic_name(def_id) {\n        if symbol == sym::Arc {\n            return Some(\"Arc\");\n        } else if symbol == sym::Rc {\n            return Some(\"Rc\");\n        }\n    }\n\n    if matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::RcWeak | sym::ArcWeak)) {\n        Some(\"Weak\")\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/from_str_radix_10.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{is_in_const_context, is_integer_literal, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem, PrimTy, QPath, TyKind, def};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for function invocations of the form `primitive::from_str_radix(s, 10)`\n    ///\n    /// ### Why is this bad?\n    ///\n    /// This specific common use case can be rewritten as `s.parse::<primitive>()`\n    /// (and in most cases, the turbofish can be removed), which reduces code length\n    /// and complexity.\n    ///\n    /// ### Known problems\n    ///\n    /// This lint may suggest using `(&<expression>).parse()` instead of `<expression>.parse()`\n    /// directly in some cases, which is correct but adds unnecessary complexity to the code.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// let input: &str = get_input();\n    /// let num = u16::from_str_radix(input, 10)?;\n    /// ```\n    /// Use instead:\n    /// ```ignore\n    /// let input: &str = get_input();\n    /// let num: u16 = input.parse()?;\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub FROM_STR_RADIX_10,\n    style,\n    \"from_str_radix with radix 10\"\n}\n\ndeclare_lint_pass!(FromStrRadix10 => [FROM_STR_RADIX_10]);\n\nimpl<'tcx> LateLintPass<'tcx> for FromStrRadix10 {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, exp: &Expr<'tcx>) {\n        if let ExprKind::Call(maybe_path, [src, radix]) = &exp.kind\n            && let ExprKind::Path(QPath::TypeRelative(ty, pathseg)) = &maybe_path.kind\n\n            // check if the second argument is a primitive `10`\n            && is_integer_literal(radix, 10)\n\n            // check if the second part of the path indeed calls the associated\n            // function `from_str_radix`\n            && pathseg.ident.name == sym::from_str_radix\n\n            // check if the first part of the path is some integer primitive\n            && let TyKind::Path(ty_qpath) = &ty.kind\n            && let ty_res = cx.qpath_res(ty_qpath, ty.hir_id)\n            && let def::Res::PrimTy(prim_ty) = ty_res\n            && matches!(prim_ty, PrimTy::Int(_) | PrimTy::Uint(_))\n\n            // do not lint in constant context, because the suggestion won't work.\n            // NB: keep this check until a new `const_trait_impl` is available and stabilized.\n            && !is_in_const_context(cx)\n        {\n            let expr = if let ExprKind::AddrOf(_, _, expr) = &src.kind {\n                let ty = cx.typeck_results().expr_ty(expr);\n                if is_ty_stringish(cx, ty) { expr } else { &src }\n            } else {\n                &src\n            };\n\n            let sugg =\n                Sugg::hir_with_applicability(cx, expr, \"<string>\", &mut Applicability::MachineApplicable).maybe_paren();\n\n            span_lint_and_sugg(\n                cx,\n                FROM_STR_RADIX_10,\n                exp.span,\n                \"this call to `from_str_radix` can be replaced with a call to `str::parse`\",\n                \"try\",\n                format!(\"{sugg}.parse::<{}>()\", prim_ty.name_str()),\n                Applicability::MaybeIncorrect,\n            );\n        }\n    }\n}\n\n/// Checks if a Ty is `String` or `&str`\nfn is_ty_stringish(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    ty.is_lang_item(cx, LangItem::String) || ty.peel_refs().is_str()\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/duplicate_underscore_argument.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_ast::PatKind;\nuse rustc_ast::visit::FnKind;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_lint::EarlyContext;\nuse rustc_span::Span;\n\nuse super::DUPLICATE_UNDERSCORE_ARGUMENT;\n\npub(super) fn check(cx: &EarlyContext<'_>, fn_kind: FnKind<'_>) {\n    let mut registered_names: FxHashMap<String, Span> = FxHashMap::default();\n\n    for arg in &fn_kind.decl().inputs {\n        if let PatKind::Ident(_, ident, None) = arg.pat.kind {\n            let arg_name = ident.to_string();\n\n            if let Some(arg_name) = arg_name.strip_prefix('_') {\n                if let Some(correspondence) = registered_names.get(arg_name) {\n                    span_lint(\n                        cx,\n                        DUPLICATE_UNDERSCORE_ARGUMENT,\n                        *correspondence,\n                        format!(\n                            \"`{arg_name}` already exists, having another argument having almost the same \\\n                                 name makes code comprehension and documentation more difficult\"\n                        ),\n                    );\n                }\n            } else {\n                registered_names.insert(arg_name, arg.pat.span);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/impl_trait_in_params.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_in_test;\n\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, GenericParam, Generics, HirId, ImplItem, ImplItemKind, TraitItem, TraitItemKind};\nuse rustc_lint::LateContext;\n\nuse super::IMPL_TRAIT_IN_PARAMS;\n\nfn report(cx: &LateContext<'_>, param: &GenericParam<'_>, generics: &Generics<'_>) {\n    // No generics with nested generics, and no generics like FnMut(x)\n    span_lint_and_then(\n        cx,\n        IMPL_TRAIT_IN_PARAMS,\n        param.span,\n        \"`impl Trait` used as a function parameter\",\n        |diag| {\n            if let Some(gen_span) = generics.span_for_param_suggestion() {\n                // If there's already a generic param with the same bound, do not lint **this** suggestion.\n                diag.span_suggestion_verbose(\n                    gen_span,\n                    \"add a type parameter\",\n                    format!(\", {{ /* Generic name */ }}: {}\", &param.name.ident().as_str()[5..]),\n                    Applicability::HasPlaceholders,\n                );\n            } else {\n                diag.span_suggestion_verbose(\n                    generics.span,\n                    \"add a type parameter\",\n                    format!(\"<{{ /* Generic name */ }}: {}>\", &param.name.ident().as_str()[5..]),\n                    Applicability::HasPlaceholders,\n                );\n            }\n        },\n    );\n}\n\npub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: &'tcx Body<'_>, hir_id: HirId) {\n    if let FnKind::ItemFn(_, generics, _) = kind\n        && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public()\n        && !is_in_test(cx.tcx, hir_id)\n    {\n        for param in generics.params {\n            if param.is_impl_trait() {\n                report(cx, param, generics);\n            }\n        }\n    }\n}\n\npub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {\n    if let ImplItemKind::Fn(_, body_id) = impl_item.kind\n        && let hir::Node::Item(item) = cx.tcx.parent_hir_node(impl_item.hir_id())\n        && let hir::ItemKind::Impl(impl_) = item.kind\n        && let hir::Impl { of_trait: None, .. } = impl_\n        && let body = cx.tcx.hir_body(body_id)\n        && cx.tcx.visibility(cx.tcx.hir_body_owner_def_id(body.id())).is_public()\n        && !is_in_test(cx.tcx, impl_item.hir_id())\n    {\n        for param in impl_item.generics.params {\n            if param.is_impl_trait() {\n                report(cx, param, impl_item.generics);\n            }\n        }\n    }\n}\n\npub(super) fn check_trait_item(cx: &LateContext<'_>, trait_item: &TraitItem<'_>, avoid_breaking_exported_api: bool) {\n    if !avoid_breaking_exported_api\n        && let TraitItemKind::Fn(_, _) = trait_item.kind\n        && let hir::Node::Item(item) = cx.tcx.parent_hir_node(trait_item.hir_id())\n        // ^^ (Will always be a trait)\n        && !item.vis_span.is_empty() // Is public\n        && !is_in_test(cx.tcx, trait_item.hir_id())\n    {\n        for param in trait_item.generics.params {\n            if param.is_impl_trait() {\n                report(cx, param, trait_item.generics);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/misnamed_getters.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{BlockCheckMode, Body, ExprKind, FnDecl, ImplicitSelfKind, UnsafeSource};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::Span;\n\nuse std::iter;\n\nuse super::MISNAMED_GETTERS;\n\npub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: &Body<'_>, span: Span) {\n    let FnKind::Method(ref ident, sig) = kind else {\n        return;\n    };\n\n    // Takes only &(mut) self\n    if decl.inputs.len() != 1 {\n        return;\n    }\n\n    let name = ident.name.as_str();\n\n    let name = match decl.implicit_self {\n        ImplicitSelfKind::RefMut => {\n            let Some(name) = name.strip_suffix(\"_mut\") else {\n                return;\n            };\n            name\n        },\n        ImplicitSelfKind::Imm | ImplicitSelfKind::Mut | ImplicitSelfKind::RefImm => name,\n        ImplicitSelfKind::None => return,\n    };\n\n    let name = if sig.header.is_unsafe() {\n        name.strip_suffix(\"_unchecked\").unwrap_or(name)\n    } else {\n        name\n    };\n\n    // Body must be `&(mut) <self_data>.name`, potentially in an `unsafe` block\n    // self_data is not necessarily self, to also lint sub-getters, etc…\n\n    let block_expr = if let ExprKind::Block(block, _) = body.value.kind\n        && block.stmts.is_empty()\n        && let Some(block_expr) = block.expr\n    {\n        if let ExprKind::Block(unsafe_block, _) = block_expr.kind\n            && unsafe_block.stmts.is_empty()\n            && matches!(\n                unsafe_block.rules,\n                BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)\n            )\n            && let Some(unsafe_block_expr) = unsafe_block.expr\n        {\n            unsafe_block_expr\n        } else {\n            block_expr\n        }\n    } else {\n        return;\n    };\n    let expr_span = block_expr.span;\n\n    // Accept &<expr>, &mut <expr> and <expr>\n    let expr = if let ExprKind::AddrOf(_, _, tmp) = block_expr.kind {\n        tmp\n    } else {\n        block_expr\n    };\n    let (self_data, used_ident) = if let ExprKind::Field(self_data, ident) = expr.kind\n        && ident.name.as_str() != name\n    {\n        (self_data, ident)\n    } else {\n        return;\n    };\n\n    let mut used_field = None;\n    let mut correct_field = None;\n    let typeck_results = cx.typeck_results();\n    for adjusted_type in iter::once(typeck_results.expr_ty(self_data))\n        .chain(typeck_results.expr_adjustments(self_data).iter().map(|adj| adj.target))\n    {\n        let ty::Adt(def, _) = adjusted_type.kind() else {\n            continue;\n        };\n\n        for f in def.all_fields() {\n            if f.name.as_str() == name {\n                correct_field = Some(f);\n            }\n            if f.name == used_ident.name {\n                used_field = Some(f);\n            }\n        }\n    }\n\n    let Some(used_field) = used_field else {\n        // Can happen if the field access is a tuple. We don't lint those because the getter name could not\n        // start with a number.\n        return;\n    };\n\n    let Some(correct_field) = correct_field else {\n        // There is no field corresponding to the getter name.\n        // FIXME: This can be a false positive if the correct field is reachable through deeper\n        // autodereferences than used_field is\n        return;\n    };\n\n    if cx.tcx.type_of(used_field.did) == cx.tcx.type_of(correct_field.did) {\n        let left_span = block_expr.span.until(used_ident.span);\n        let snippet = snippet(cx, left_span, \"..\");\n        let sugg = format!(\"{snippet}{name}\");\n        span_lint_and_then(\n            cx,\n            MISNAMED_GETTERS,\n            span,\n            \"getter function appears to return the wrong field\",\n            |diag| {\n                diag.span_suggestion(expr_span, \"consider using\", sugg, Applicability::MaybeIncorrect);\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/mod.rs",
    "content": "mod duplicate_underscore_argument;\nmod impl_trait_in_params;\nmod misnamed_getters;\nmod must_use;\nmod not_unsafe_ptr_arg_deref;\nmod ref_option;\nmod renamed_function_params;\nmod result;\nmod too_many_arguments;\nmod too_many_lines;\n\nuse clippy_config::Conf;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::paths::{PathNS, lookup_path_str};\nuse rustc_ast::{self as ast, visit};\nuse rustc_hir as hir;\nuse rustc_hir::intravisit;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::{declare_lint_pass, impl_lint_pass};\nuse rustc_span::Span;\nuse rustc_span::def_id::{DefIdSet, LocalDefId};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for a `#[must_use]` attribute without\n    /// further information on functions and methods that return a type already\n    /// marked as `#[must_use]`.\n    ///\n    /// ### Why is this bad?\n    /// The attribute isn't needed. Not using the result\n    /// will already be reported. Alternatively, one can add some text to the\n    /// attribute to improve the lint message.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// #[must_use]\n    /// fn double_must_use() -> Result<(), ()> {\n    ///     unimplemented!();\n    /// }\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub DOUBLE_MUST_USE,\n    style,\n    \"`#[must_use]` attribute on a `#[must_use]`-returning function / method\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for function arguments having the similar names\n    /// differing by an underscore.\n    ///\n    /// ### Why is this bad?\n    /// It affects code readability.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(a: i32, _a: i32) {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn bar(a: i32, _b: i32) {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DUPLICATE_UNDERSCORE_ARGUMENT,\n    style,\n    \"function arguments having names which only differ by an underscore\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints when `impl Trait` is being used in a function's parameters.\n    ///\n    /// ### Why restrict this?\n    /// Turbofish syntax (`::<>`) cannot be used to specify the type of an `impl Trait` parameter,\n    /// making `impl Trait` less powerful. Readability may also be a factor.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// trait MyTrait {}\n    /// fn foo(a: impl MyTrait) {\n    /// \t// [...]\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// trait MyTrait {}\n    /// fn foo<T: MyTrait>(a: T) {\n    /// \t// [...]\n    /// }\n    /// ```\n    #[clippy::version = \"1.69.0\"]\n    pub IMPL_TRAIT_IN_PARAMS,\n    restriction,\n    \"`impl Trait` is used in the function's parameters\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for getter methods that return a field that doesn't correspond\n    /// to the name of the method, when there is a field's whose name matches that of the method.\n    ///\n    /// ### Why is this bad?\n    /// It is most likely that such a method is a bug caused by a typo or by copy-pasting.\n    ///\n    /// ### Example\n\n    /// ```no_run\n    /// struct A {\n    ///     a: String,\n    ///     b: String,\n    /// }\n    ///\n    /// impl A {\n    ///     fn a(&self) -> &str{\n    ///         &self.b\n    ///     }\n    /// }\n\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct A {\n    ///     a: String,\n    ///     b: String,\n    /// }\n    ///\n    /// impl A {\n    ///     fn a(&self) -> &str{\n    ///         &self.a\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub MISNAMED_GETTERS,\n    suspicious,\n    \"getter method returning the wrong field\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for public functions that have no\n    /// `#[must_use]` attribute, but return something not already marked\n    /// must-use, have no mutable arg and mutate no statics.\n    ///\n    /// ### Why is this bad?\n    /// Not bad at all, this lint just shows places where\n    /// you could add the attribute.\n    ///\n    /// ### Known problems\n    /// The lint only checks the arguments for mutable\n    /// types without looking if they are actually changed. On the other hand,\n    /// it also ignores a broad range of potentially interesting side effects,\n    /// because we cannot decide whether the programmer intends the function to\n    /// be called for the side effect or the result. Expect many false\n    /// positives. At least we don't lint if the result type is unit or already\n    /// `#[must_use]`.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// // this could be annotated with `#[must_use]`.\n    /// pub fn id<T>(t: T) -> T { t }\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub MUST_USE_CANDIDATE,\n    pedantic,\n    \"function or method that could take a `#[must_use]` attribute\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for a `#[must_use]` attribute on\n    /// unit-returning functions and methods.\n    ///\n    /// ### Why is this bad?\n    /// Unit values are useless. The attribute is likely\n    /// a remnant of a refactoring that removed the return type.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// #[must_use]\n    /// fn useless() { }\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub MUST_USE_UNIT,\n    style,\n    \"`#[must_use]` attribute on a unit-returning function / method\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for public functions that dereference raw pointer\n    /// arguments but are not marked `unsafe`.\n    ///\n    /// ### Why is this bad?\n    /// The function should almost definitely be marked `unsafe`, since for an\n    /// arbitrary raw pointer, there is no way of telling for sure if it is valid.\n    ///\n    /// In general, this lint should **never be disabled** unless it is definitely a\n    /// false positive (please submit an issue if so) since it breaks Rust's\n    /// soundness guarantees, directly exposing API users to potentially dangerous\n    /// program behavior. This is also true for internal APIs, as it is easy to leak\n    /// unsoundness.\n    ///\n    /// ### Context\n    /// In Rust, an `unsafe {...}` block is used to indicate that the code in that\n    /// section has been verified in some way that the compiler can not. For a\n    /// function that accepts a raw pointer then accesses the pointer's data, this is\n    /// generally impossible as the incoming pointer could point anywhere, valid or\n    /// not. So, the signature should be marked `unsafe fn`: this indicates that the\n    /// function's caller must provide some verification that the arguments it sends\n    /// are valid (and then call the function within an `unsafe` block).\n    ///\n    /// ### Known problems\n    /// * It does not check functions recursively so if the pointer is passed to a\n    /// private non-`unsafe` function which does the dereferencing, the lint won't\n    /// trigger (false negative).\n    /// * It only checks for arguments whose type are raw pointers, not raw pointers\n    /// got from an argument in some other way (`fn foo(bar: &[*const u8])` or\n    /// `some_argument.get_raw_ptr()`) (false negative).\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// pub fn foo(x: *const u8) {\n    ///     println!(\"{}\", unsafe { *x });\n    /// }\n    ///\n    /// // this call \"looks\" safe but will segfault or worse!\n    /// // foo(invalid_ptr);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// pub unsafe fn foo(x: *const u8) {\n    ///     println!(\"{}\", unsafe { *x });\n    /// }\n    ///\n    /// // this would cause a compiler error for calling without `unsafe`\n    /// // foo(invalid_ptr);\n    ///\n    /// // sound call if the caller knows the pointer is valid\n    /// unsafe { foo(valid_ptr); }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NOT_UNSAFE_PTR_ARG_DEREF,\n    correctness,\n    \"public functions dereferencing raw pointer arguments but not marked `unsafe`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns when a function signature uses `&Option<T>` instead of `Option<&T>`.\n    ///\n    /// ### Why is this bad?\n    /// More flexibility, better memory optimization, and more idiomatic Rust code.\n    ///\n    /// `&Option<T>` in a function signature breaks encapsulation because the caller must own T\n    /// and move it into an Option to call with it. When returned, the owner must internally store\n    /// it as `Option<T>` in order to return it.\n    /// At a lower level, `&Option<T>` points to memory with the `presence` bit flag plus the `T` value,\n    /// whereas `Option<&T>` is usually [optimized](https://doc.rust-lang.org/1.81.0/std/option/index.html#representation)\n    /// to a single pointer, so it may be more optimal.\n    ///\n    /// See this [YouTube video](https://www.youtube.com/watch?v=6c7pZYP_iIE) by\n    /// Logan Smith for an in-depth explanation of why this is important.\n    ///\n    /// ### Known problems\n    /// This lint recommends changing the function signatures, but it cannot\n    /// automatically change the function calls or the function implementations.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // caller uses  foo(&opt)\n    /// fn foo(a: &Option<String>) {}\n    /// # struct Unit {}\n    /// # impl Unit {\n    /// fn bar(&self) -> &Option<String> { &None }\n    /// # }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// // caller should use  `foo1(opt.as_ref())`\n    /// fn foo1(a: Option<&String>) {}\n    /// // better yet, use string slice  `foo2(opt.as_deref())`\n    /// fn foo2(a: Option<&str>) {}\n    /// # struct Unit {}\n    /// # impl Unit {\n    /// fn bar(&self) -> Option<&String> { None }\n    /// # }\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub REF_OPTION,\n    pedantic,\n    \"function signature uses `&Option<T>` instead of `Option<&T>`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints when the name of function parameters from trait impl is\n    /// different than its default implementation.\n    ///\n    /// ### Why restrict this?\n    /// Using the default name for parameters of a trait method is more consistent.\n    ///\n    /// ### Example\n    /// ```rust\n    /// struct A(u32);\n    ///\n    /// impl PartialEq for A {\n    ///     fn eq(&self, b: &Self) -> bool {\n    ///         self.0 == b.0\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// struct A(u32);\n    ///\n    /// impl PartialEq for A {\n    ///     fn eq(&self, other: &Self) -> bool {\n    ///         self.0 == other.0\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.80.0\"]\n    pub RENAMED_FUNCTION_PARAMS,\n    restriction,\n    \"renamed function parameters in trait implementation\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions that return `Result` with an unusually large\n    /// `Err`-variant.\n    ///\n    /// ### Why is this bad?\n    /// A `Result` is at least as large as the `Err`-variant. While we\n    /// expect that variant to be seldom used, the compiler needs to reserve\n    /// and move that much memory every single time.\n    /// Furthermore, errors are often simply passed up the call-stack, making\n    /// use of the `?`-operator and its type-conversion mechanics. If the\n    /// `Err`-variant further up the call-stack stores the `Err`-variant in\n    /// question (as library code often does), it itself needs to be at least\n    /// as large, propagating the problem.\n    ///\n    /// ### Known problems\n    /// The size determined by Clippy is platform-dependent.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// pub enum ParseError {\n    ///     UnparsedBytes([u8; 512]),\n    ///     UnexpectedEof,\n    /// }\n    ///\n    /// // The `Result` has at least 512 bytes, even in the `Ok`-case\n    /// pub fn parse() -> Result<(), ParseError> {\n    ///     Ok(())\n    /// }\n    /// ```\n    /// should be\n    /// ```no_run\n    /// pub enum ParseError {\n    ///     UnparsedBytes(Box<[u8; 512]>),\n    ///     UnexpectedEof,\n    /// }\n    ///\n    /// // The `Result` is slightly larger than a pointer\n    /// pub fn parse() -> Result<(), ParseError> {\n    ///     Ok(())\n    /// }\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub RESULT_LARGE_ERR,\n    perf,\n    \"function returning `Result` with large `Err` type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for public functions that return a `Result`\n    /// with an `Err` type of `()`. It suggests using a custom type that\n    /// implements `std::error::Error`.\n    ///\n    /// ### Why is this bad?\n    /// Unit does not implement `Error` and carries no\n    /// further information about what went wrong.\n    ///\n    /// ### Known problems\n    /// Of course, this lint assumes that `Result` is used\n    /// for a fallible operation (which is after all the intended use). However\n    /// code may opt to (mis)use it as a basic two-variant-enum. In that case,\n    /// the suggestion is misguided, and the code should use a custom enum\n    /// instead.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// pub fn read_u8() -> Result<u8, ()> { Err(()) }\n    /// ```\n    /// should become\n    /// ```rust,should_panic\n    /// use std::fmt;\n    ///\n    /// #[derive(Debug)]\n    /// pub struct EndOfStream;\n    ///\n    /// impl fmt::Display for EndOfStream {\n    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n    ///         write!(f, \"End of Stream\")\n    ///     }\n    /// }\n    ///\n    /// impl std::error::Error for EndOfStream { }\n    ///\n    /// pub fn read_u8() -> Result<u8, EndOfStream> { Err(EndOfStream) }\n    ///# fn main() {\n    ///#     read_u8().unwrap();\n    ///# }\n    /// ```\n    ///\n    /// Note that there are crates that simplify creating the error type, e.g.\n    /// [`thiserror`](https://docs.rs/thiserror).\n    #[clippy::version = \"1.49.0\"]\n    pub RESULT_UNIT_ERR,\n    style,\n    \"public function returning `Result` with an `Err` type of `()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions with too many parameters.\n    ///\n    /// ### Why is this bad?\n    /// Functions with lots of parameters are considered bad\n    /// style and reduce readability (“what does the 5th parameter mean?”). Consider\n    /// grouping some parameters into a new type.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct Color;\n    /// fn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TOO_MANY_ARGUMENTS,\n    complexity,\n    \"functions with too many arguments\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions with a large amount of lines.\n    ///\n    /// ### Why is this bad?\n    /// Functions with a lot of lines are harder to understand\n    /// due to having to look at a larger amount of code to understand what the\n    /// function is doing. Consider splitting the body of the function into\n    /// multiple functions.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn im_too_long() {\n    ///     println!(\"\");\n    ///     // ... 100 more LoC\n    ///     println!(\"\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.34.0\"]\n    pub TOO_MANY_LINES,\n    pedantic,\n    \"functions with too many lines\"\n}\n\ndeclare_lint_pass!(EarlyFunctions => [DUPLICATE_UNDERSCORE_ARGUMENT]);\n\nimpl_lint_pass!(Functions => [\n    DOUBLE_MUST_USE,\n    IMPL_TRAIT_IN_PARAMS,\n    MISNAMED_GETTERS,\n    MUST_USE_CANDIDATE,\n    MUST_USE_UNIT,\n    NOT_UNSAFE_PTR_ARG_DEREF,\n    REF_OPTION,\n    RENAMED_FUNCTION_PARAMS,\n    RESULT_LARGE_ERR,\n    RESULT_UNIT_ERR,\n    TOO_MANY_ARGUMENTS,\n    TOO_MANY_LINES,\n]);\n\nimpl EarlyLintPass for EarlyFunctions {\n    fn check_fn(&mut self, cx: &EarlyContext<'_>, fn_kind: visit::FnKind<'_>, _: Span, _: ast::NodeId) {\n        duplicate_underscore_argument::check(cx, fn_kind);\n    }\n}\n\npub struct Functions {\n    too_many_arguments_threshold: u64,\n    too_many_lines_threshold: u64,\n    large_error_threshold: u64,\n    large_error_ignored: DefIdSet,\n    avoid_breaking_exported_api: bool,\n    /// A set of resolved `def_id` of traits that are configured to allow\n    /// function params renaming.\n    trait_ids: DefIdSet,\n    msrv: Msrv,\n}\n\nimpl Functions {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        Self {\n            too_many_arguments_threshold: conf.too_many_arguments_threshold,\n            too_many_lines_threshold: conf.too_many_lines_threshold,\n            large_error_threshold: conf.large_error_threshold,\n            large_error_ignored: conf\n                .large_error_ignored\n                .iter()\n                .flat_map(|ignored_ty| lookup_path_str(tcx, PathNS::Type, ignored_ty))\n                .collect(),\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n            trait_ids: conf\n                .allow_renamed_params_for\n                .iter()\n                .flat_map(|p| lookup_path_str(tcx, PathNS::Type, p))\n                .collect(),\n            msrv: conf.msrv,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Functions {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: intravisit::FnKind<'tcx>,\n        decl: &'tcx hir::FnDecl<'_>,\n        body: &'tcx hir::Body<'_>,\n        span: Span,\n        def_id: LocalDefId,\n    ) {\n        let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);\n        too_many_arguments::check_fn(cx, kind, decl, hir_id, def_id, self.too_many_arguments_threshold);\n        too_many_lines::check_fn(cx, kind, body, span, def_id, self.too_many_lines_threshold);\n        not_unsafe_ptr_arg_deref::check_fn(cx, kind, decl, body, def_id);\n        misnamed_getters::check_fn(cx, kind, decl, body, span);\n        impl_trait_in_params::check_fn(cx, &kind, body, hir_id);\n        ref_option::check_fn(\n            cx,\n            kind,\n            decl,\n            span,\n            hir_id,\n            def_id,\n            body,\n            self.avoid_breaking_exported_api,\n        );\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {\n        must_use::check_item(cx, item);\n        result::check_item(\n            cx,\n            item,\n            self.large_error_threshold,\n            &self.large_error_ignored,\n            self.msrv,\n        );\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {\n        must_use::check_impl_item(cx, item);\n        result::check_impl_item(\n            cx,\n            item,\n            self.large_error_threshold,\n            &self.large_error_ignored,\n            self.msrv,\n        );\n        impl_trait_in_params::check_impl_item(cx, item);\n        renamed_function_params::check_impl_item(cx, item, &self.trait_ids);\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {\n        too_many_arguments::check_trait_item(cx, item, self.too_many_arguments_threshold);\n        not_unsafe_ptr_arg_deref::check_trait_item(cx, item);\n        must_use::check_trait_item(cx, item);\n        result::check_trait_item(\n            cx,\n            item,\n            self.large_error_threshold,\n            &self.large_error_ignored,\n            self.msrv,\n        );\n        impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api);\n        ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api);\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {\n        result::check_expr(cx, expr, self.large_error_threshold, &self.large_error_ignored);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/must_use.rs",
    "content": "use clippy_utils::res::MaybeDef as _;\nuse hir::FnSig;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::def_id::DefIdSet;\nuse rustc_hir::{self as hir, Attribute, QPath, find_attr};\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::{Span, sym};\n\nuse clippy_utils::attrs::is_proc_macro;\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};\nuse clippy_utils::source::snippet_indent;\nuse clippy_utils::ty::is_must_use_ty;\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{is_entrypoint_fn, return_ty, trait_ref_of_method};\nuse rustc_span::Symbol;\nuse rustc_trait_selection::error_reporting::InferCtxtErrorExt;\n\nuse core::ops::ControlFlow;\n\nuse super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};\n\npub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {\n    let attrs = cx.tcx.hir_attrs(item.hir_id());\n    let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason));\n    if let hir::ItemKind::Fn {\n        ref sig,\n        body: ref body_id,\n        ident,\n        ..\n    } = item.kind\n    {\n        let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);\n        let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());\n        if let Some((attr_span, reason)) = attr {\n            check_needless_must_use(\n                cx,\n                sig.decl,\n                item.owner_id,\n                item.span,\n                fn_header_span,\n                *attr_span,\n                *reason,\n                attrs,\n                sig,\n            );\n        } else if is_public && !is_proc_macro(attrs) && !find_attr!(attrs, NoMangle(..)) {\n            check_must_use_candidate(\n                cx,\n                sig.decl,\n                cx.tcx.hir_body(*body_id),\n                item.span,\n                ident.span,\n                item.owner_id,\n                \"this function could have a `#[must_use]` attribute\",\n            );\n        }\n    }\n}\n\npub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {\n    if let hir::ImplItemKind::Fn(ref sig, ref body_id) = item.kind {\n        let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);\n        let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());\n        let attrs = cx.tcx.hir_attrs(item.hir_id());\n        let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason));\n        if let Some((attr_span, reason)) = attr {\n            check_needless_must_use(\n                cx,\n                sig.decl,\n                item.owner_id,\n                item.span,\n                fn_header_span,\n                *attr_span,\n                *reason,\n                attrs,\n                sig,\n            );\n        } else if is_public && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id).is_none() {\n            check_must_use_candidate(\n                cx,\n                sig.decl,\n                cx.tcx.hir_body(*body_id),\n                item.span,\n                item.ident.span,\n                item.owner_id,\n                \"this method could have a `#[must_use]` attribute\",\n            );\n        }\n    }\n}\n\npub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {\n    if let hir::TraitItemKind::Fn(ref sig, ref eid) = item.kind {\n        let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);\n        let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());\n\n        let attrs = cx.tcx.hir_attrs(item.hir_id());\n        let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), MustUse { span, reason } => (span, reason));\n        if let Some((attr_span, reason)) = attr {\n            check_needless_must_use(\n                cx,\n                sig.decl,\n                item.owner_id,\n                item.span,\n                fn_header_span,\n                *attr_span,\n                *reason,\n                attrs,\n                sig,\n            );\n        } else if let hir::TraitFn::Provided(eid) = *eid {\n            let body = cx.tcx.hir_body(eid);\n            if attr.is_none() && is_public && !is_proc_macro(attrs) {\n                check_must_use_candidate(\n                    cx,\n                    sig.decl,\n                    body,\n                    item.span,\n                    item.ident.span,\n                    item.owner_id,\n                    \"this method could have a `#[must_use]` attribute\",\n                );\n            }\n        }\n    }\n}\n\n// FIXME: needs to be an EARLY LINT. all attribute lints should be\n#[expect(clippy::too_many_arguments)]\nfn check_needless_must_use(\n    cx: &LateContext<'_>,\n    decl: &hir::FnDecl<'_>,\n    item_id: hir::OwnerId,\n    item_span: Span,\n    fn_header_span: Span,\n    attr_span: Span,\n    reason: Option<Symbol>,\n    attrs: &[Attribute],\n    sig: &FnSig<'_>,\n) {\n    if item_span.in_external_macro(cx.sess().source_map()) {\n        return;\n    }\n    if returns_unit(decl) {\n        if attrs.len() == 1 {\n            span_lint_and_then(\n                cx,\n                MUST_USE_UNIT,\n                fn_header_span,\n                \"this unit-returning function has a `#[must_use]` attribute\",\n                |diag| {\n                    diag.span_suggestion(attr_span, \"remove the attribute\", \"\", Applicability::MachineApplicable);\n                },\n            );\n        } else {\n            // When there are multiple attributes, it is not sufficient to simply make `must_use` empty, see\n            // issue #12320.\n            // FIXME(jdonszelmann): this used to give a machine-applicable fix. However, it was super fragile,\n            // honestly looked incorrect, and is a little hard to support for a little bit now. Some day this\n            // could be re-added.\n            span_lint_and_help(\n                cx,\n                MUST_USE_UNIT,\n                fn_header_span,\n                \"this unit-returning function has a `#[must_use]` attribute\",\n                Some(attr_span),\n                \"remove `must_use`\",\n            );\n        }\n    } else if reason.is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {\n        // Ignore async functions unless Future::Output type is a must_use type\n        if sig.header.is_async() {\n            let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());\n            if let Some(future_ty) = infcx.err_ctxt().get_impl_future_output_ty(return_ty(cx, item_id))\n                && !is_must_use_ty(cx, future_ty)\n            {\n                return;\n            }\n        }\n\n        span_lint_and_help(\n            cx,\n            DOUBLE_MUST_USE,\n            fn_header_span,\n            \"this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`\",\n            None,\n            \"either add some descriptive message or remove the attribute\",\n        );\n    }\n}\n\nfn check_must_use_candidate<'tcx>(\n    cx: &LateContext<'tcx>,\n    decl: &'tcx hir::FnDecl<'_>,\n    body: &'tcx hir::Body<'_>,\n    item_span: Span,\n    ident_span: Span,\n    item_id: hir::OwnerId,\n    msg: &'static str,\n) {\n    if has_mutable_arg(cx, body)\n        || mutates_static(cx, body)\n        || item_span.in_external_macro(cx.sess().source_map())\n        || returns_unit(decl)\n        || !cx.effective_visibilities.is_exported(item_id.def_id)\n        || is_must_use_ty(cx, return_ty(cx, item_id))\n        || item_span.from_expansion()\n        || is_entrypoint_fn(cx, item_id.def_id.to_def_id())\n    {\n        return;\n    }\n    span_lint_and_then(cx, MUST_USE_CANDIDATE, ident_span, msg, |diag| {\n        let indent = snippet_indent(cx, item_span).unwrap_or_default();\n        diag.span_suggestion(\n            item_span.shrink_to_lo(),\n            \"add the attribute\",\n            format!(\"#[must_use]\\n{indent}\"),\n            Applicability::MachineApplicable,\n        );\n        if let Some(msg) = match return_ty(cx, item_id).opt_diag_name(cx) {\n            Some(sym::ControlFlow) => Some(\"`ControlFlow<B, C>` as `C` when `B` is uninhabited\"),\n            Some(sym::Result) => Some(\"`Result<T, E>` as `T` when `E` is uninhabited\"),\n            _ => None,\n        } {\n            diag.note(format!(\"a future version of Rust will treat {msg} wrt `#[must_use]`\"));\n        }\n    });\n}\n\nfn returns_unit(decl: &hir::FnDecl<'_>) -> bool {\n    match decl.output {\n        hir::FnRetTy::DefaultReturn(_) => true,\n        hir::FnRetTy::Return(ty) => match ty.kind {\n            hir::TyKind::Tup(tys) => tys.is_empty(),\n            hir::TyKind::Never => true,\n            _ => false,\n        },\n    }\n}\n\nfn has_mutable_arg(cx: &LateContext<'_>, body: &hir::Body<'_>) -> bool {\n    let mut tys = DefIdSet::default();\n    body.params.iter().any(|param| is_mutable_pat(cx, param.pat, &mut tys))\n}\n\nfn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet) -> bool {\n    if let hir::PatKind::Wild = pat.kind {\n        return false; // ignore `_` patterns\n    }\n    if cx.tcx.has_typeck_results(pat.hir_id.owner.def_id) {\n        is_mutable_ty(cx, cx.tcx.typeck(pat.hir_id.owner.def_id).pat_ty(pat), tys)\n    } else {\n        false\n    }\n}\n\nfn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) -> bool {\n    match *ty.kind() {\n        // primitive types are never mutable\n        ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,\n        ty::Adt(adt, args) => {\n            tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.typing_env())\n                || matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::Rc | sym::Arc))\n                    && args.types().any(|ty| is_mutable_ty(cx, ty, tys))\n        },\n        ty::Tuple(args) => args.iter().any(|ty| is_mutable_ty(cx, ty, tys)),\n        ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys),\n        ty::RawPtr(ty, mutbl) | ty::Ref(_, ty, mutbl) => mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys),\n        // calling something constitutes a side effect, so return true on all callables\n        // also never calls need not be used, so return true for them, too\n        _ => true,\n    }\n}\n\nfn is_mutated_static(e: &hir::Expr<'_>) -> bool {\n    use hir::ExprKind::{Field, Index, Path};\n\n    match e.kind {\n        Path(QPath::Resolved(_, path)) => !matches!(path.res, Res::Local(_)),\n        Path(_) => true,\n        Field(inner, _) | Index(inner, _, _) => is_mutated_static(inner),\n        _ => false,\n    }\n}\n\nfn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bool {\n    for_each_expr_without_closures(body.value, |e| {\n        use hir::ExprKind::{AddrOf, Assign, AssignOp, Call, MethodCall};\n\n        match e.kind {\n            Call(_, args) => {\n                let mut tys = DefIdSet::default();\n                for arg in args {\n                    if cx.tcx.has_typeck_results(arg.hir_id.owner.def_id)\n                        && is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys)\n                        && is_mutated_static(arg)\n                    {\n                        return ControlFlow::Break(());\n                    }\n                    tys.clear();\n                }\n                ControlFlow::Continue(())\n            },\n            MethodCall(_, receiver, args, _) => {\n                let mut tys = DefIdSet::default();\n                for arg in std::iter::once(receiver).chain(args.iter()) {\n                    if cx.tcx.has_typeck_results(arg.hir_id.owner.def_id)\n                        && is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys)\n                        && is_mutated_static(arg)\n                    {\n                        return ControlFlow::Break(());\n                    }\n                    tys.clear();\n                }\n                ControlFlow::Continue(())\n            },\n            Assign(target, ..) | AssignOp(_, target, _) | AddrOf(_, hir::Mutability::Mut, target)\n                if is_mutated_static(target) =>\n            {\n                ControlFlow::Break(())\n            },\n            _ => ControlFlow::Continue(()),\n        }\n    })\n    .is_some()\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs",
    "content": "use clippy_utils::res::MaybeResPath;\nuse rustc_hir::{self as hir, HirId, HirIdSet, intravisit};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::def_id::LocalDefId;\n\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::iter_input_pats;\nuse clippy_utils::ty::is_unsafe_fn;\nuse clippy_utils::visitors::for_each_expr;\n\nuse core::ops::ControlFlow;\n\nuse super::NOT_UNSAFE_PTR_ARG_DEREF;\n\npub(super) fn check_fn<'tcx>(\n    cx: &LateContext<'tcx>,\n    kind: intravisit::FnKind<'tcx>,\n    decl: &'tcx hir::FnDecl<'tcx>,\n    body: &'tcx hir::Body<'tcx>,\n    def_id: LocalDefId,\n) {\n    let safety = match kind {\n        intravisit::FnKind::ItemFn(_, _, header) => header.safety(),\n        intravisit::FnKind::Method(_, sig) => sig.header.safety(),\n        intravisit::FnKind::Closure => return,\n    };\n\n    check_raw_ptr(cx, safety, decl, body, def_id);\n}\n\npub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {\n    if let hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(eid)) = item.kind {\n        let body = cx.tcx.hir_body(eid);\n        check_raw_ptr(cx, sig.header.safety(), sig.decl, body, item.owner_id.def_id);\n    }\n}\n\nfn check_raw_ptr<'tcx>(\n    cx: &LateContext<'tcx>,\n    safety: hir::Safety,\n    decl: &'tcx hir::FnDecl<'tcx>,\n    body: &'tcx hir::Body<'tcx>,\n    def_id: LocalDefId,\n) {\n    if safety.is_safe() && cx.effective_visibilities.is_exported(def_id) {\n        let raw_ptrs = iter_input_pats(decl, body)\n            .filter_map(|arg| raw_ptr_arg(cx, arg))\n            .collect::<HirIdSet>();\n\n        if !raw_ptrs.is_empty() {\n            let typeck = cx.tcx.typeck_body(body.id());\n            let _: Option<!> = for_each_expr(cx, body.value, |e| {\n                match e.kind {\n                    hir::ExprKind::Call(f, args) if is_unsafe_fn(cx, typeck.expr_ty(f)) => {\n                        for arg in args {\n                            check_arg(cx, &raw_ptrs, arg);\n                        }\n                    },\n                    hir::ExprKind::MethodCall(_, recv, args, _) => {\n                        let def_id = typeck.type_dependent_def_id(e.hir_id).unwrap();\n                        if cx.tcx.fn_sig(def_id).skip_binder().skip_binder().safety.is_unsafe() {\n                            check_arg(cx, &raw_ptrs, recv);\n                            for arg in args {\n                                check_arg(cx, &raw_ptrs, arg);\n                            }\n                        }\n                    },\n                    hir::ExprKind::Unary(hir::UnOp::Deref, ptr) => check_arg(cx, &raw_ptrs, ptr),\n                    _ => (),\n                }\n                ControlFlow::Continue(())\n            });\n        }\n    }\n}\n\nfn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option<HirId> {\n    if let (&hir::PatKind::Binding(_, id, _, _), Some(&ty::RawPtr(_, _))) = (\n        &arg.pat.kind,\n        cx.maybe_typeck_results()\n            .map(|typeck_results| typeck_results.pat_ty(arg.pat).kind()),\n    ) {\n        Some(id)\n    } else {\n        None\n    }\n}\n\nfn check_arg(cx: &LateContext<'_>, raw_ptrs: &HirIdSet, arg: &hir::Expr<'_>) {\n    if arg.res_local_id().is_some_and(|id| raw_ptrs.contains(&id)) {\n        span_lint(\n            cx,\n            NOT_UNSAFE_PTR_ARG_DEREF,\n            arg.span,\n            \"this public function might dereference a raw pointer but is not marked `unsafe`\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/ref_option.rs",
    "content": "use crate::functions::REF_OPTION;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::option_arg_ty;\nuse clippy_utils::{is_from_proc_macro, is_trait_impl_item};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{self as hir, FnDecl, HirId};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::{self, Mutability, Ty};\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\nfn check_ty<'a>(cx: &LateContext<'a>, param: &hir::Ty<'a>, param_ty: Ty<'a>, fixes: &mut Vec<(Span, String)>) {\n    if !param.span.in_external_macro(cx.sess().source_map())\n        && let ty::Ref(_, opt_ty, Mutability::Not) = param_ty.kind()\n        && let Some(gen_ty) = option_arg_ty(cx, *opt_ty)\n        && !gen_ty.is_ref()\n        // Need to gen the original spans, so first parsing mid, and hir parsing afterward\n        && let hir::TyKind::Ref(lifetime, hir::MutTy { ty, .. }) = param.kind\n        && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind\n        && let (Some(first), Some(last)) = (path.segments.first(), path.segments.last())\n        && let Some(hir::GenericArgs {\n            args: [hir::GenericArg::Type(opt_ty)],\n            ..\n        }) = last.args\n        && !is_from_proc_macro(cx, param)\n    {\n        let lifetime = snippet(cx, lifetime.ident.span, \"..\");\n        fixes.push((\n            param.span,\n            format!(\n                \"{}<&{lifetime}{}{}>\",\n                snippet(cx, first.ident.span.to(last.ident.span), \"..\"),\n                if lifetime.is_empty() { \"\" } else { \" \" },\n                snippet(cx, opt_ty.span, \"..\")\n            ),\n        ));\n    }\n}\n\nfn check_fn_sig<'a>(cx: &LateContext<'a>, decl: &FnDecl<'a>, span: Span, sig: ty::FnSig<'a>) {\n    let mut fixes = Vec::new();\n    // Check function arguments' types\n    for (param, param_ty) in decl.inputs.iter().zip(sig.inputs()) {\n        check_ty(cx, param, *param_ty, &mut fixes);\n    }\n    // Check return type\n    if let hir::FnRetTy::Return(ty) = &decl.output {\n        check_ty(cx, ty, sig.output(), &mut fixes);\n    }\n    if !fixes.is_empty() {\n        span_lint_and_then(\n            cx,\n            REF_OPTION,\n            span,\n            \"it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\",\n            |diag| {\n                diag.multipart_suggestion(\"change this to\", fixes, Applicability::Unspecified);\n            },\n        );\n    }\n}\n\n#[expect(clippy::too_many_arguments)]\npub(crate) fn check_fn<'a>(\n    cx: &LateContext<'a>,\n    kind: FnKind<'a>,\n    decl: &FnDecl<'a>,\n    span: Span,\n    hir_id: HirId,\n    def_id: LocalDefId,\n    body: &hir::Body<'a>,\n    avoid_breaking_exported_api: bool,\n) {\n    if avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {\n        return;\n    }\n    if span.in_external_macro(cx.sess().source_map()) {\n        return;\n    }\n\n    if let FnKind::Closure = kind {\n        // Compute the span of the closure parameters + return type if set\n        let inputs_output_span = if let hir::FnRetTy::Return(out_ty) = &decl.output {\n            if decl.inputs.is_empty() {\n                out_ty.span\n            } else {\n                span.with_hi(out_ty.span.hi())\n            }\n        } else if let (Some(first), Some(last)) = (decl.inputs.first(), decl.inputs.last()) {\n            first.span.to(last.span)\n        } else {\n            // No parameters - no point in checking\n            return;\n        };\n\n        // Figure out the signature of the closure\n        let ty::Closure(_, args) = cx.typeck_results().expr_ty(body.value).kind() else {\n            return;\n        };\n        let sig = args.as_closure().sig().skip_binder();\n\n        if is_from_proc_macro(cx, &(&kind, body, hir_id, span)) {\n            return;\n        }\n\n        check_fn_sig(cx, decl, inputs_output_span, sig);\n    } else if !is_trait_impl_item(cx, hir_id) {\n        let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();\n\n        if is_from_proc_macro(cx, &(&kind, body, hir_id, span)) {\n            return;\n        }\n\n        check_fn_sig(cx, decl, span, sig);\n    }\n}\n\npub(super) fn check_trait_item<'a>(\n    cx: &LateContext<'a>,\n    trait_item: &hir::TraitItem<'a>,\n    avoid_breaking_exported_api: bool,\n) {\n    if !trait_item.span.in_external_macro(cx.sess().source_map())\n        && let hir::TraitItemKind::Fn(ref sig, _) = trait_item.kind\n        && !(avoid_breaking_exported_api && cx.effective_visibilities.is_exported(trait_item.owner_id.def_id))\n        && !is_from_proc_macro(cx, trait_item)\n    {\n        let def_id = trait_item.owner_id.def_id;\n        let ty_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();\n        check_fn_sig(cx, sig.decl, sig.span, ty_sig);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/renamed_function_params.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_errors::{Applicability, MultiSpan};\nuse rustc_hir::def_id::DefIdSet;\nuse rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node, TraitRef};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\nuse rustc_span::symbol::{Ident, kw};\nuse std::iter;\n\nuse super::RENAMED_FUNCTION_PARAMS;\n\npub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored_traits: &DefIdSet) {\n    if !item.span.from_expansion()\n        && let ImplItemKind::Fn(_, body_id) = item.kind\n        && let parent_node = cx.tcx.parent_hir_node(item.hir_id())\n        && let Node::Item(parent_item) = parent_node\n        && let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            ..\n        }) = &parent_item.kind\n        && let Some(did) = cx.tcx.trait_item_of(item.owner_id)\n        && !is_from_ignored_trait(&of_trait.trait_ref, ignored_traits)\n    {\n        let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id);\n        let mut default_param_idents_iter = cx.tcx.fn_arg_idents(did).iter().copied();\n\n        let renames = RenamedFnArgs::new(&mut default_param_idents_iter, &mut param_idents_iter);\n        if !renames.0.is_empty() {\n            let multi_span = renames.multi_span();\n            let plural = if renames.0.len() == 1 { \"\" } else { \"s\" };\n            span_lint_and_then(\n                cx,\n                RENAMED_FUNCTION_PARAMS,\n                multi_span,\n                format!(\"renamed function parameter{plural} of trait impl\"),\n                |diag| {\n                    diag.multipart_suggestion(\n                        format!(\"consider using the default name{plural}\"),\n                        renames.0,\n                        Applicability::Unspecified,\n                    );\n                },\n            );\n        }\n    }\n}\n\nstruct RenamedFnArgs(Vec<(Span, String)>);\n\nimpl RenamedFnArgs {\n    /// Comparing between an iterator of default names and one with current names,\n    /// then collect the ones that got renamed.\n    fn new<I1, I2>(default_idents: &mut I1, current_idents: &mut I2) -> Self\n    where\n        I1: Iterator<Item = Option<Ident>>,\n        I2: Iterator<Item = Option<Ident>>,\n    {\n        let mut renamed: Vec<(Span, String)> = vec![];\n\n        debug_assert!(default_idents.size_hint() == current_idents.size_hint());\n        for (default_ident, current_ident) in iter::zip(default_idents, current_idents) {\n            let has_name_to_check = |ident: Option<Ident>| {\n                ident\n                    .filter(|ident| ident.name != kw::Underscore)\n                    .filter(|ident| !ident.name.as_str().starts_with('_'))\n            };\n\n            if let Some(default_ident) = has_name_to_check(default_ident)\n                && let Some(current_ident) = has_name_to_check(current_ident)\n                && default_ident.name != current_ident.name\n            {\n                renamed.push((current_ident.span, default_ident.to_string()));\n            }\n        }\n\n        Self(renamed)\n    }\n\n    fn multi_span(&self) -> MultiSpan {\n        self.0\n            .iter()\n            .map(|(span, _)| span)\n            .copied()\n            .collect::<Vec<Span>>()\n            .into()\n    }\n}\n\nfn is_from_ignored_trait(of_trait: &TraitRef<'_>, ignored_traits: &DefIdSet) -> bool {\n    of_trait\n        .trait_def_id()\n        .is_some_and(|trait_did| ignored_traits.contains(&trait_did))\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/result.rs",
    "content": "use clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse rustc_errors::Diag;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::def_id::DefIdSet;\nuse rustc_span::{Span, sym};\n\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};\nuse clippy_utils::ty::{AdtVariantInfo, approx_ty_size};\nuse clippy_utils::{is_no_std_crate, trait_ref_of_method};\n\nuse super::{RESULT_LARGE_ERR, RESULT_UNIT_ERR};\n\n/// The type of the `Err`-variant in a `std::result::Result` returned by the\n/// given `FnDecl`\nfn result_err_ty<'tcx>(\n    cx: &LateContext<'tcx>,\n    decl: &hir::FnDecl<'tcx>,\n    id: hir::def_id::LocalDefId,\n    item_span: Span,\n) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {\n    if !item_span.in_external_macro(cx.sess().source_map())\n        && let hir::FnRetTy::Return(hir_ty) = decl.output\n        && let ty = cx\n            .tcx\n            .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().output())\n        && ty.is_diag_item(cx, sym::Result)\n        && let ty::Adt(_, args) = ty.kind()\n    {\n        let err_ty = args.type_at(1);\n        Some((hir_ty, err_ty))\n    } else {\n        None\n    }\n}\n\npub(super) fn check_item<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &hir::Item<'tcx>,\n    large_err_threshold: u64,\n    large_err_ignored: &DefIdSet,\n    msrv: Msrv,\n) {\n    if let hir::ItemKind::Fn { ref sig, .. } = item.kind\n        && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)\n    {\n        if cx.effective_visibilities.is_exported(item.owner_id.def_id) {\n            let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());\n            check_result_unit_err(cx, err_ty, fn_header_span, msrv);\n        }\n        check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false);\n    }\n}\n\npub(super) fn check_impl_item<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &hir::ImplItem<'tcx>,\n    large_err_threshold: u64,\n    large_err_ignored: &DefIdSet,\n    msrv: Msrv,\n) {\n    // Don't lint if method is a trait's implementation, we can't do anything about those\n    if let hir::ImplItemKind::Fn(ref sig, _) = item.kind\n        && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)\n        && trait_ref_of_method(cx, item.owner_id).is_none()\n    {\n        if cx.effective_visibilities.is_exported(item.owner_id.def_id) {\n            let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());\n            check_result_unit_err(cx, err_ty, fn_header_span, msrv);\n        }\n        check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false);\n    }\n}\n\npub(super) fn check_trait_item<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &hir::TraitItem<'tcx>,\n    large_err_threshold: u64,\n    large_err_ignored: &DefIdSet,\n    msrv: Msrv,\n) {\n    if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {\n        let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());\n        if let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span) {\n            if cx.effective_visibilities.is_exported(item.owner_id.def_id) {\n                check_result_unit_err(cx, err_ty, fn_header_span, msrv);\n            }\n            check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold, large_err_ignored, false);\n        }\n    }\n}\n\nfn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: Span, msrv: Msrv) {\n    if err_ty.is_unit() && (!is_no_std_crate(cx) || msrv.meets(cx, msrvs::ERROR_IN_CORE)) {\n        span_lint_and_help(\n            cx,\n            RESULT_UNIT_ERR,\n            fn_header_span,\n            \"this returns a `Result<_, ()>`\",\n            None,\n            \"use a custom `Error` type instead\",\n        );\n    }\n}\n\nfn check_result_large_err<'tcx>(\n    cx: &LateContext<'tcx>,\n    err_ty: Ty<'tcx>,\n    hir_ty_span: Span,\n    large_err_threshold: u64,\n    large_err_ignored: &DefIdSet,\n    is_closure: bool,\n) {\n    if let ty::Adt(adt, _) = err_ty.kind()\n        && large_err_ignored.contains(&adt.did())\n    {\n        return;\n    }\n\n    let subject = if is_closure { \"closure\" } else { \"function\" };\n    if let ty::Adt(adt, subst) = err_ty.kind()\n        && let Some(local_def_id) = adt.did().as_local()\n        && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_def_id)\n        && let hir::ItemKind::Enum(_, _, ref def) = item.kind\n    {\n        let variants_size = AdtVariantInfo::new(cx, *adt, subst);\n        if let Some((first_variant, variants)) = variants_size.split_first()\n            && first_variant.size >= large_err_threshold\n        {\n            span_lint_and_then(\n                cx,\n                RESULT_LARGE_ERR,\n                hir_ty_span,\n                format!(\"the `Err`-variant returned from this {subject} is very large\"),\n                |diag| {\n                    diag.span_label(\n                        def.variants[first_variant.ind].span,\n                        format!(\"the largest variant contains at least {} bytes\", variants_size[0].size),\n                    );\n\n                    for variant in variants {\n                        if variant.size >= large_err_threshold {\n                            let variant_def = &def.variants[variant.ind];\n                            diag.span_label(\n                                variant_def.span,\n                                format!(\n                                    \"the variant `{}` contains at least {} bytes\",\n                                    variant_def.ident, variant.size\n                                ),\n                            );\n                        }\n                    }\n\n                    diag.help(format!(\"try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`\"));\n                },\n            );\n        }\n    } else {\n        let ty_size = approx_ty_size(cx, err_ty);\n        if ty_size >= large_err_threshold {\n            span_lint_and_then(\n                cx,\n                RESULT_LARGE_ERR,\n                hir_ty_span,\n                format!(\"the `Err`-variant returned from this {subject} is very large\"),\n                |diag: &mut Diag<'_, ()>| {\n                    diag.span_label(hir_ty_span, format!(\"the `Err`-variant is at least {ty_size} bytes\"));\n                    diag.help(format!(\"try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`\"));\n                },\n            );\n        }\n    }\n}\n\npub(super) fn check_expr<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'tcx>,\n    large_err_threshold: u64,\n    large_err_ignored: &DefIdSet,\n) {\n    if let hir::ExprKind::Closure(closure) = expr.kind\n        && let ty::Closure(_, args) = cx.typeck_results().expr_ty(expr).kind()\n        && let closure_sig = args.as_closure().sig()\n        && let Ok(err_binder) = closure_sig.output().try_map_bound(|output_ty| {\n            if let ty::Adt(adt, args) = output_ty.kind()\n                && let [_, err_arg] = args.as_slice()\n                && let Some(err_ty) = err_arg.as_type()\n                && adt.is_diag_item(cx, sym::Result)\n            {\n                return Ok(err_ty);\n            }\n\n            Err(())\n        })\n    {\n        let err_ty = cx.tcx.instantiate_bound_regions_with_erased(err_binder);\n        let hir_ty_span = match closure.fn_decl.output {\n            hir::FnRetTy::Return(hir_ty) => hir_ty.span,\n            hir::FnRetTy::DefaultReturn(_) => expr.span,\n        };\n        check_result_large_err(cx, err_ty, hir_ty_span, large_err_threshold, large_err_ignored, true);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/too_many_arguments.rs",
    "content": "use rustc_abi::ExternAbi;\nuse rustc_hir as hir;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::is_trait_impl_item;\n\nuse super::TOO_MANY_ARGUMENTS;\n\npub(super) fn check_fn(\n    cx: &LateContext<'_>,\n    kind: FnKind<'_>,\n    decl: &hir::FnDecl<'_>,\n    hir_id: hir::HirId,\n    def_id: LocalDefId,\n    too_many_arguments_threshold: u64,\n) {\n    // don't warn for implementations, it's not their fault\n    if !is_trait_impl_item(cx, hir_id)\n        // don't lint extern functions decls, it's not their fault either\n        && kind.header().is_some_and(|header| header.abi == ExternAbi::Rust)\n    {\n        check_arg_number(cx, decl, cx.tcx.def_span(def_id), too_many_arguments_threshold);\n    }\n}\n\npub(super) fn check_trait_item(cx: &LateContext<'_>, item: &hir::TraitItem<'_>, too_many_arguments_threshold: u64) {\n    if let hir::TraitItemKind::Fn(ref sig, _) = item.kind\n        // don't lint extern functions decls, it's not their fault\n        && sig.header.abi == ExternAbi::Rust\n    {\n        check_arg_number(\n            cx,\n            sig.decl,\n            item.span.with_hi(sig.decl.output.span().hi()),\n            too_many_arguments_threshold,\n        );\n    }\n}\n\nfn check_arg_number(cx: &LateContext<'_>, decl: &hir::FnDecl<'_>, fn_span: Span, too_many_arguments_threshold: u64) {\n    let args = decl.inputs.len() as u64;\n    if args > too_many_arguments_threshold {\n        span_lint(\n            cx,\n            TOO_MANY_ARGUMENTS,\n            fn_span,\n            format!(\"this function has too many arguments ({args}/{too_many_arguments_threshold})\"),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/functions/too_many_lines.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_hir as hir;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_span::Span;\n\nuse super::TOO_MANY_LINES;\n\npub(super) fn check_fn(\n    cx: &LateContext<'_>,\n    kind: FnKind<'_>,\n    body: &hir::Body<'_>,\n    span: Span,\n    def_id: LocalDefId,\n    too_many_lines_threshold: u64,\n) {\n    // Closures must be contained in a parent body, which will be checked for `too_many_lines`.\n    // Don't check closures for `too_many_lines` to avoid duplicated lints.\n    if matches!(kind, FnKind::Closure) || span.in_external_macro(cx.sess().source_map()) {\n        return;\n    }\n\n    let mut line_count: u64 = 0;\n    let too_many = body.value.span.check_source_text(cx, |src| {\n        let mut in_comment = false;\n        let mut code_in_line;\n\n        let function_lines = if matches!(body.value.kind, hir::ExprKind::Block(..))\n            && src.as_bytes().first().copied() == Some(b'{')\n            && src.as_bytes().last().copied() == Some(b'}')\n        {\n            // Removing the braces from the enclosing block\n            &src[1..src.len() - 1]\n        } else {\n            src\n        }\n        .trim() // Remove leading and trailing blank lines\n        .lines();\n\n        for mut line in function_lines {\n            code_in_line = false;\n            loop {\n                line = line.trim_start();\n                if line.is_empty() {\n                    break;\n                }\n                if in_comment {\n                    if let Some(i) = line.find(\"*/\") {\n                        line = &line[i + 2..];\n                        in_comment = false;\n                        continue;\n                    }\n                } else {\n                    let multi_idx = line.find(\"/*\").unwrap_or(line.len());\n                    let single_idx = line.find(\"//\").unwrap_or(line.len());\n                    code_in_line |= multi_idx > 0 && single_idx > 0;\n                    // Implies multi_idx is below line.len()\n                    if multi_idx < single_idx {\n                        line = &line[multi_idx + 2..];\n                        in_comment = true;\n                        continue;\n                    }\n                }\n                break;\n            }\n            if code_in_line {\n                line_count += 1;\n            }\n        }\n        line_count > too_many_lines_threshold\n    });\n\n    if too_many {\n        span_lint(\n            cx,\n            TOO_MANY_LINES,\n            cx.tcx.def_span(def_id),\n            format!(\"this function has too many lines ({line_count}/{too_many_lines_threshold})\"),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/future_not_send.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::return_ty;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, FnDecl};\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::print::PrintTraitRefExt;\nuse rustc_middle::ty::{\n    self, AliasTy, Binder, ClauseKind, PredicateKind, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor,\n};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{Span, sym};\nuse rustc_trait_selection::error_reporting::InferCtxtErrorExt;\nuse rustc_trait_selection::traits::{self, FulfillmentError, ObligationCtxt};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint requires Future implementations returned from\n    /// functions and methods to implement the `Send` marker trait,\n    /// ignoring type parameters.\n    ///\n    /// If a function is generic and its Future conditionally implements `Send`\n    /// based on a generic parameter then it is considered `Send` and no warning is emitted.\n    ///\n    /// This can be used by library authors (public and internal) to ensure\n    /// their functions are compatible with both multi-threaded runtimes that require `Send` futures,\n    /// as well as single-threaded runtimes where callers may choose `!Send` types\n    /// for generic parameters.\n    ///\n    /// ### Why is this bad?\n    /// A Future implementation captures some state that it\n    /// needs to eventually produce its final value. When targeting a multithreaded\n    /// executor (which is the norm on non-embedded devices) this means that this\n    /// state may need to be transported to other threads, in other words the\n    /// whole Future needs to implement the `Send` marker trait. If it does not,\n    /// then the resulting Future cannot be submitted to a thread pool in the\n    /// end user’s code.\n    ///\n    /// Especially for generic functions it can be confusing to leave the\n    /// discovery of this problem to the end user: the reported error location\n    /// will be far from its cause and can in many cases not even be fixed without\n    /// modifying the library where the offending Future implementation is\n    /// produced.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// async fn not_send(bytes: std::rc::Rc<[u8]>) {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// async fn is_send(bytes: std::sync::Arc<[u8]>) {}\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub FUTURE_NOT_SEND,\n    nursery,\n    \"public Futures must be Send\"\n}\n\ndeclare_lint_pass!(FutureNotSend => [FUTURE_NOT_SEND]);\n\nimpl<'tcx> LateLintPass<'tcx> for FutureNotSend {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'tcx>,\n        _: &'tcx Body<'tcx>,\n        _: Span,\n        fn_def_id: LocalDefId,\n    ) {\n        if let FnKind::Closure = kind {\n            return;\n        }\n        let ret_ty = return_ty(cx, cx.tcx.local_def_id_to_hir_id(fn_def_id).expect_owner());\n        if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind()\n            && let Some(future_trait) = cx.tcx.lang_items().future_trait()\n            && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)\n            && let preds = cx.tcx.explicit_item_self_bounds(def_id)\n            // If is a Future\n            && preds\n                .iter_instantiated_copied(cx.tcx, args)\n                .filter_map(|(p, _)| p.as_trait_clause())\n                .any(|trait_pred| trait_pred.skip_binder().trait_ref.def_id == future_trait)\n        {\n            let span = decl.output.span();\n            let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());\n            let ocx = ObligationCtxt::new_with_diagnostics(&infcx);\n            let cause = traits::ObligationCause::misc(span, fn_def_id);\n            ocx.register_bound(cause, cx.param_env, ret_ty, send_trait);\n            let send_errors = ocx.evaluate_obligations_error_on_ambiguity();\n\n            // Allow errors that try to prove `Send` for types that \"mention\" a generic parameter at the \"top\n            // level\".\n            // For example, allow errors that `T: Send` can't be proven, but reject `Rc<T>: Send` errors,\n            // which is always unconditionally `!Send` for any possible type `T`.\n            //\n            // We also allow associated type projections if the self type is either itself a projection or a\n            // type parameter.\n            // This is to prevent emitting warnings for e.g. holding a `<Fut as Future>::Output` across await\n            // points, where `Fut` is a type parameter.\n\n            let is_send = send_errors.iter().all(|err| {\n                err.obligation\n                    .predicate\n                    .as_trait_clause()\n                    .map(Binder::skip_binder)\n                    .is_some_and(|pred| {\n                        pred.def_id() == send_trait\n                            && pred.self_ty().has_param()\n                            && TyParamAtTopLevelVisitor.visit_ty(pred.self_ty()) == ControlFlow::Break(true)\n                    })\n            });\n\n            if !is_send {\n                span_lint_and_then(\n                    cx,\n                    FUTURE_NOT_SEND,\n                    span,\n                    \"future cannot be sent between threads safely\",\n                    |db| {\n                        for FulfillmentError { obligation, .. } in send_errors {\n                            infcx\n                                .err_ctxt()\n                                .maybe_note_obligation_cause_for_async_await(db, &obligation);\n                            if let PredicateKind::Clause(ClauseKind::Trait(trait_pred)) =\n                                obligation.predicate.kind().skip_binder()\n                            {\n                                db.note(format!(\n                                    \"`{}` doesn't implement `{}`\",\n                                    trait_pred.self_ty(),\n                                    trait_pred.trait_ref.print_only_trait_path(),\n                                ));\n                            }\n                        }\n                    },\n                );\n            }\n        }\n    }\n}\n\nstruct TyParamAtTopLevelVisitor;\nimpl<'tcx> TypeVisitor<TyCtxt<'tcx>> for TyParamAtTopLevelVisitor {\n    type Result = ControlFlow<bool>;\n    fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {\n        match ty.kind() {\n            ty::Param(_) => ControlFlow::Break(true),\n            ty::Alias(ty::AliasTyKind::Projection, ty) => ty.visit_with(self),\n            _ => ControlFlow::Break(false),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/if_let_mutex.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{eq_expr_value, higher, sym};\nuse core::ops::ControlFlow;\nuse rustc_errors::Diag;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::edition::Edition::Edition2024;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `Mutex::lock` calls in `if let` expression\n    /// with lock calls in any of the else blocks.\n    ///\n    /// ### Disabled starting in Edition 2024\n    /// This lint is effectively disabled starting in\n    /// Edition 2024 as `if let ... else` scoping was reworked\n    /// such that this is no longer an issue. See\n    /// [Proposal: stabilize if_let_rescope for Edition 2024](https://github.com/rust-lang/rust/issues/131154)\n    ///\n    /// ### Why is this bad?\n    /// The Mutex lock remains held for the whole\n    /// `if let ... else` block and deadlocks.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// if let Ok(thing) = mutex.lock() {\n    ///     do_thing();\n    /// } else {\n    ///     mutex.lock();\n    /// }\n    /// ```\n    /// Should be written\n    /// ```rust,ignore\n    /// let locked = mutex.lock();\n    /// if let Ok(thing) = locked {\n    ///     do_thing(thing);\n    /// } else {\n    ///     use_locked(locked);\n    /// }\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub IF_LET_MUTEX,\n    correctness,\n    \"locking a `Mutex` in an `if let` block can cause deadlocks\"\n}\n\ndeclare_lint_pass!(IfLetMutex => [IF_LET_MUTEX]);\n\nimpl<'tcx> LateLintPass<'tcx> for IfLetMutex {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if cx.tcx.sess.edition() >= Edition2024 {\n            return;\n        }\n\n        if let Some(higher::IfLet {\n            let_expr,\n            if_then,\n            if_else: Some(if_else),\n            ..\n        }) = higher::IfLet::hir(cx, expr)\n            && let Some(op_mutex) = for_each_expr_without_closures(let_expr, |e| mutex_lock_call(cx, e, None))\n            && let Some(arm_mutex) =\n                for_each_expr_without_closures((if_then, if_else), |e| mutex_lock_call(cx, e, Some(op_mutex)))\n        {\n            let diag = |diag: &mut Diag<'_, ()>| {\n                diag.span_label(\n                    op_mutex.span,\n                    \"this Mutex will remain locked for the entire `if let`-block...\",\n                );\n                diag.span_label(\n                    arm_mutex.span,\n                    \"... and is tried to lock again here, which will always deadlock.\",\n                );\n                diag.help(\"move the lock call outside of the `if let ...` expression\");\n            };\n            span_lint_and_then(\n                cx,\n                IF_LET_MUTEX,\n                expr.span,\n                \"calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock\",\n                diag,\n            );\n        }\n    }\n}\n\nfn mutex_lock_call<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    op_mutex: Option<&'tcx Expr<'_>>,\n) -> ControlFlow<&'tcx Expr<'tcx>> {\n    if let ExprKind::MethodCall(path, self_arg, [], _) = &expr.kind\n        && path.ident.name == sym::lock\n        && let ty = cx.typeck_results().expr_ty(self_arg).peel_refs()\n        && ty.is_diag_item(cx, sym::Mutex)\n        && op_mutex.is_none_or(|op| eq_expr_value(cx, self_arg, op))\n    {\n        ControlFlow::Break(self_arg)\n    } else {\n        ControlFlow::Continue(())\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/if_not_else.rs",
    "content": "use clippy_utils::consts::is_zero_integer_const;\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};\nuse clippy_utils::is_else_clause;\nuse clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet_with_context};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `!` or `!=` in an if condition with an\n    /// else branch.\n    ///\n    /// ### Why is this bad?\n    /// Negations reduce the readability of statements.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let v: Vec<usize> = vec![];\n    /// # fn a() {}\n    /// # fn b() {}\n    /// if !v.is_empty() {\n    ///     a()\n    /// } else {\n    ///     b()\n    /// }\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// # let v: Vec<usize> = vec![];\n    /// # fn a() {}\n    /// # fn b() {}\n    /// if v.is_empty() {\n    ///     b()\n    /// } else {\n    ///     a()\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub IF_NOT_ELSE,\n    pedantic,\n    \"`if` branches that could be swapped so no negation operation is necessary on the condition\"\n}\n\ndeclare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);\n\nimpl LateLintPass<'_> for IfNotElse {\n    fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {\n        if let ExprKind::If(cond, cond_inner, Some(els)) = e.kind\n            && let ExprKind::Block(..) = els.kind\n        {\n            let (msg, help) = match cond.kind {\n                ExprKind::Unary(UnOp::Not, _) => (\n                    \"unnecessary boolean `not` operation\",\n                    \"remove the `!` and swap the blocks of the `if`/`else`\",\n                ),\n                // Don't lint on `… != 0`, as these are likely to be bit tests.\n                // For example, `if foo & 0x0F00 != 0 { … } else { … }` is already in the \"proper\" order.\n                ExprKind::Binary(op, _, rhs)\n                    if op.node == BinOpKind::Ne && !is_zero_integer_const(cx, rhs, e.span.ctxt()) =>\n                {\n                    (\n                        \"unnecessary `!=` operation\",\n                        \"change to `==` and swap the blocks of the `if`/`else`\",\n                    )\n                },\n                _ => return,\n            };\n\n            // `from_expansion` will also catch `while` loops which appear in the HIR as:\n            // ```rust\n            // loop {\n            //     if cond { ... } else { break; }\n            // }\n            // ```\n            if !e.span.from_expansion() && !is_else_clause(cx.tcx, e) {\n                let mut applicability = Applicability::MachineApplicable;\n                match cond.kind {\n                    ExprKind::Unary(UnOp::Not, _) | ExprKind::Binary(_, _, _) => span_lint_and_sugg(\n                        cx,\n                        IF_NOT_ELSE,\n                        e.span,\n                        msg,\n                        \"try\",\n                        make_sugg(\n                            cx,\n                            e.span,\n                            &cond.kind,\n                            cond_inner.span,\n                            els.span,\n                            \"..\",\n                            &mut applicability,\n                        ),\n                        applicability,\n                    ),\n                    _ => span_lint_and_help(cx, IF_NOT_ELSE, e.span, msg, None, help),\n                }\n            }\n        }\n    }\n}\n\nfn make_sugg<'a>(\n    sess: &impl HasSession,\n    expr_span: Span,\n    cond_kind: &'a ExprKind<'a>,\n    cond_inner: Span,\n    els_span: Span,\n    default: &'a str,\n    applicability: &mut Applicability,\n) -> String {\n    let (cond_inner_snip, _) = snippet_with_context(sess, cond_inner, expr_span.ctxt(), default, applicability);\n    let (els_snip, _) = snippet_with_context(sess, els_span, expr_span.ctxt(), default, applicability);\n    let indent = indent_of(sess, expr_span);\n\n    let suggestion = match cond_kind {\n        ExprKind::Unary(UnOp::Not, cond_rest) => {\n            let (cond_rest_snip, _) =\n                snippet_with_context(sess, cond_rest.span, expr_span.ctxt(), default, applicability);\n            format!(\"if {cond_rest_snip} {els_snip} else {cond_inner_snip}\")\n        },\n        ExprKind::Binary(_, lhs, rhs) => {\n            let (lhs_snip, _) = snippet_with_context(sess, lhs.span, expr_span.ctxt(), default, applicability);\n            let (rhs_snip, _) = snippet_with_context(sess, rhs.span, expr_span.ctxt(), default, applicability);\n\n            format!(\"if {lhs_snip} == {rhs_snip} {els_snip} else {cond_inner_snip}\")\n        },\n        _ => String::new(),\n    };\n\n    reindent_multiline(&suggestion, true, indent)\n}\n"
  },
  {
    "path": "clippy_lints/src/if_then_some_else_none.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::eager_or_lazy::switch_to_eager_eval;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{\n    as_some_expr, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, is_none_expr,\n    peel_blocks, sym,\n};\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for if-else that could be written using either `bool::then` or `bool::then_some`.\n    ///\n    /// ### Why restrict this?\n    /// Looks a little redundant. Using `bool::then` is more concise and incurs no loss of clarity.\n    /// For simple calculations and known values, use `bool::then_some`, which is eagerly evaluated\n    /// in comparison to `bool::then`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let v = vec![0];\n    /// let a = if v.is_empty() {\n    ///     println!(\"true!\");\n    ///     Some(42)\n    /// } else {\n    ///     None\n    /// };\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// # let v = vec![0];\n    /// let a = v.is_empty().then(|| {\n    ///     println!(\"true!\");\n    ///     42\n    /// });\n    /// ```\n    #[clippy::version = \"1.53.0\"]\n    pub IF_THEN_SOME_ELSE_NONE,\n    restriction,\n    \"Finds if-else that could be written using either `bool::then` or `bool::then_some`\"\n}\n\nimpl_lint_pass!(IfThenSomeElseNone => [IF_THEN_SOME_ELSE_NONE]);\n\npub struct IfThenSomeElseNone {\n    msrv: Msrv,\n}\n\nimpl IfThenSomeElseNone {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let Some(higher::If {\n            cond,\n            then,\n            r#else: Some(els),\n        }) = higher::If::hir(expr)\n            && let ExprKind::Block(then_block, _) = then.kind\n            && let Some(then_expr) = then_block.expr\n            && let Some(then_arg) = as_some_expr(cx, then_expr)\n            && !expr.span.from_expansion()\n            && !then_expr.span.from_expansion()\n            && is_none_expr(cx, peel_blocks(els))\n            && !is_else_clause(cx.tcx, expr)\n            && !is_in_const_context(cx)\n            && self.msrv.meets(cx, msrvs::BOOL_THEN)\n            && for_each_expr_without_closures(then_block, |e| {\n                if matches!(e.kind, ExprKind::Ret(..) | ExprKind::Yield(..)) {\n                    ControlFlow::Break(())\n                } else {\n                    ControlFlow::Continue(())\n                }\n            })\n            .is_none()\n        {\n            let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) {\n                sym::then_some\n            } else {\n                sym::then\n            };\n            let ctxt = expr.span.ctxt();\n\n            span_lint_and_then(\n                cx,\n                IF_THEN_SOME_ELSE_NONE,\n                expr.span,\n                format!(\"this could be simplified with `bool::{method_name}`\"),\n                |diag| {\n                    if expr_adjustment_requires_coercion(cx, then_arg) {\n                        return;\n                    }\n\n                    let mut app = Applicability::MachineApplicable;\n                    let cond_snip = Sugg::hir_with_context(cx, cond, ctxt, \"[condition]\", &mut app)\n                        .maybe_paren()\n                        .to_string();\n                    let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, \"[body]\", &mut app).0;\n                    let method_body = if let Some(_) = then_block.stmts.first()\n                        && let Some(then_span) = walk_span_to_context(then.span, ctxt)\n                    {\n                        let block_before_snippet =\n                            snippet_with_applicability(cx, then_span.until(then_expr.span), \"..\", &mut app);\n                        let block_after_snippet = snippet_with_applicability(\n                            cx,\n                            then_expr.span.shrink_to_hi().until(then_span.shrink_to_hi()),\n                            \"..\",\n                            &mut app,\n                        );\n                        let closure = if method_name == sym::then { \"|| \" } else { \"\" };\n                        format!(\"{closure}{block_before_snippet}{arg_snip}{block_after_snippet}\")\n                    } else if method_name == sym::then {\n                        (std::borrow::Cow::Borrowed(\"|| \") + arg_snip).into_owned()\n                    } else {\n                        arg_snip.into_owned()\n                    };\n\n                    diag.span_suggestion(\n                        expr.span,\n                        \"try\",\n                        format!(\"{cond_snip}.{method_name}({method_body})\"),\n                        app,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ifs/branches_sharing_code.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::{IntoSpan, SpanRangeExt, first_line_of_span, indent_of, reindent_multiline, snippet};\nuse clippy_utils::ty::needs_ordered_drop;\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{\n    ContainsName, HirEqInterExpr, SpanlessEq, capture_local_usage, get_enclosing_block, hash_expr, hash_stmt,\n};\nuse core::iter;\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, ItemKind, LetStmt, Node, Stmt, StmtKind, UseKind, intravisit};\nuse rustc_lint::LateContext;\nuse rustc_span::hygiene::walk_chain;\nuse rustc_span::source_map::SourceMap;\nuse rustc_span::{Span, Symbol};\n\nuse super::BRANCHES_SHARING_CODE;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    conds: &[&'tcx Expr<'_>],\n    blocks: &[&'tcx Block<'_>],\n    expr: &'tcx Expr<'_>,\n) {\n    // We only lint ifs with multiple blocks\n    let &[first_block, ref blocks @ ..] = blocks else {\n        return;\n    };\n    let &[.., last_block] = blocks else {\n        return;\n    };\n\n    let res = scan_block_for_eq(cx, conds, first_block, blocks);\n    let sm = cx.tcx.sess.source_map();\n    let start_suggestion = res.start_span(first_block, sm).map(|span| {\n        let first_line_span = first_line_of_span(cx, expr.span);\n        let replace_span = first_line_span.with_hi(span.hi());\n        let cond_span = first_line_span.until(first_block.span);\n        let cond_snippet = reindent_multiline(&snippet(cx, cond_span, \"_\"), false, None);\n        let cond_indent = indent_of(cx, cond_span);\n        let moved_snippet = reindent_multiline(&snippet(cx, span, \"_\"), true, None);\n        let suggestion = moved_snippet + \"\\n\" + &cond_snippet + \"{\";\n        let suggestion = reindent_multiline(&suggestion, true, cond_indent);\n        (replace_span, suggestion)\n    });\n    let end_suggestion = res.end_span(last_block, sm).map(|span| {\n        let moved_snipped = reindent_multiline(&snippet(cx, span, \"_\"), true, None);\n        let indent = indent_of(cx, expr.span.shrink_to_hi());\n        let suggestion = \"}\\n\".to_string() + &moved_snipped;\n        let suggestion = reindent_multiline(&suggestion, true, indent);\n\n        let span = span.with_hi(last_block.span.hi());\n        // Improve formatting if the inner block has indentation (i.e. normal Rust formatting)\n        let span = span\n            .map_range(cx, |_, src, range| {\n                (range.start > 4 && src.get(range.start - 4..range.start)? == \"    \")\n                    .then_some(range.start - 4..range.end)\n            })\n            .map_or(span, |range| range.with_ctxt(span.ctxt()));\n        (span, suggestion.clone())\n    });\n\n    let (span, msg, end_span) = match (&start_suggestion, &end_suggestion) {\n        (&Some((span, _)), &Some((end_span, _))) => (\n            span,\n            \"all if blocks contain the same code at both the start and the end\",\n            Some(end_span),\n        ),\n        (&Some((span, _)), None) => (span, \"all if blocks contain the same code at the start\", None),\n        (None, &Some((span, _))) => (span, \"all if blocks contain the same code at the end\", None),\n        (None, None) => return,\n    };\n    span_lint_and_then(cx, BRANCHES_SHARING_CODE, span, msg, |diag| {\n        if let Some(span) = end_span {\n            diag.span_note(span, \"this code is shared at the end\");\n        }\n        if let Some((span, sugg)) = start_suggestion {\n            diag.span_suggestion(\n                span,\n                \"consider moving these statements before the if\",\n                sugg,\n                Applicability::Unspecified,\n            );\n        }\n        if let Some((span, sugg)) = end_suggestion {\n            diag.span_suggestion(\n                span,\n                \"consider moving these statements after the if\",\n                sugg,\n                Applicability::Unspecified,\n            );\n            if is_expr_parent_assignment(cx, expr) || !cx.typeck_results().expr_ty(expr).is_unit() {\n                diag.note(\"the end suggestion probably needs some adjustments to use the expression result correctly\");\n            }\n        }\n        if check_for_warn_of_moved_symbol(cx, &res.moved_locals, expr) {\n            diag.warn(\"some moved values might need to be renamed to avoid wrong references\");\n        }\n    });\n}\n\nstruct BlockEq {\n    /// The end of the range of equal stmts at the start.\n    start_end_eq: usize,\n    /// The start of the range of equal stmts at the end.\n    end_begin_eq: Option<usize>,\n    /// The name and id of every local which can be moved at the beginning and the end.\n    moved_locals: Vec<(HirId, Symbol)>,\n}\n\nimpl BlockEq {\n    fn start_span(&self, b: &Block<'_>, sm: &SourceMap) -> Option<Span> {\n        match &b.stmts[..self.start_end_eq] {\n            [first, .., last] => Some(sm.stmt_span(first.span, b.span).to(sm.stmt_span(last.span, b.span))),\n            [s] => Some(sm.stmt_span(s.span, b.span)),\n            [] => None,\n        }\n    }\n\n    fn end_span(&self, b: &Block<'_>, sm: &SourceMap) -> Option<Span> {\n        match (&b.stmts[b.stmts.len() - self.end_begin_eq?..], b.expr) {\n            ([first, .., last], None) => Some(sm.stmt_span(first.span, b.span).to(sm.stmt_span(last.span, b.span))),\n            ([first, ..], Some(last)) => Some(sm.stmt_span(first.span, b.span).to(sm.stmt_span(last.span, b.span))),\n            ([s], None) => Some(sm.stmt_span(s.span, b.span)),\n            ([], Some(e)) => Some(walk_chain(e.span, b.span.ctxt())),\n            ([], None) => None,\n        }\n    }\n}\n\n/// If the statement is a local, checks if the bound names match the expected list of names.\nfn eq_binding_names(cx: &LateContext<'_>, s: &Stmt<'_>, names: &[(HirId, Symbol)]) -> bool {\n    match s.kind {\n        StmtKind::Let(l) => {\n            let mut i = 0usize;\n            let mut res = true;\n            l.pat.each_binding_or_first(&mut |_, _, _, name| {\n                if names.get(i).is_some_and(|&(_, n)| n == name.name) {\n                    i += 1;\n                } else {\n                    res = false;\n                }\n            });\n            res && i == names.len()\n        },\n        StmtKind::Item(item_id)\n            if let [(_, name)] = names\n                && let item = cx.tcx.hir_item(item_id)\n                && let ItemKind::Static(_, ident, ..)\n                | ItemKind::Const(ident, ..)\n                | ItemKind::Fn { ident, .. }\n                | ItemKind::TyAlias(ident, ..)\n                | ItemKind::Use(_, UseKind::Single(ident))\n                | ItemKind::Mod(ident, _) = item.kind =>\n        {\n            *name == ident.name\n        },\n        _ => false,\n    }\n}\n\n/// Checks if the statement modifies or moves any of the given locals.\nfn modifies_any_local<'tcx>(cx: &LateContext<'tcx>, s: &'tcx Stmt<'_>, locals: &HirIdSet) -> bool {\n    for_each_expr_without_closures(s, |e| {\n        if let Some(id) = e.res_local_id()\n            && locals.contains(&id)\n            && !capture_local_usage(cx, e).is_imm_ref()\n        {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\n/// Checks if the given statement should be considered equal to the statement in the same\n/// position for each block.\nfn eq_stmts(\n    cx: &LateContext<'_>,\n    stmt: &Stmt<'_>,\n    blocks: &[&Block<'_>],\n    get_stmt: impl for<'a> Fn(&'a Block<'a>) -> Option<&'a Stmt<'a>>,\n    eq: &mut HirEqInterExpr<'_, '_, '_>,\n    moved_bindings: &mut Vec<(HirId, Symbol)>,\n) -> bool {\n    (if let StmtKind::Let(l) = stmt.kind {\n        let old_count = moved_bindings.len();\n        l.pat.each_binding_or_first(&mut |_, id, _, name| {\n            moved_bindings.push((id, name.name));\n        });\n        let new_bindings = &moved_bindings[old_count..];\n        blocks\n            .iter()\n            .all(|b| get_stmt(b).is_some_and(|s| eq_binding_names(cx, s, new_bindings)))\n    } else {\n        true\n    }) && blocks.iter().all(|b| get_stmt(b).is_some_and(|s| eq.eq_stmt(s, stmt)))\n}\n\n#[expect(clippy::too_many_lines)]\nfn scan_block_for_eq<'tcx>(\n    cx: &LateContext<'tcx>,\n    conds: &[&'tcx Expr<'_>],\n    block: &'tcx Block<'_>,\n    blocks: &[&'tcx Block<'_>],\n) -> BlockEq {\n    let mut eq = SpanlessEq::new(cx);\n    let mut eq = eq.inter_expr();\n    let mut moved_locals = Vec::new();\n\n    let mut cond_locals = HirIdSet::default();\n    for &cond in conds {\n        let _: Option<!> = for_each_expr_without_closures(cond, |e| {\n            if let Some(id) = e.res_local_id() {\n                cond_locals.insert(id);\n            }\n            ControlFlow::Continue(())\n        });\n    }\n\n    let mut local_needs_ordered_drop = false;\n    let start_end_eq = block\n        .stmts\n        .iter()\n        .enumerate()\n        .find(|&(i, stmt)| {\n            if let StmtKind::Let(l) = stmt.kind\n                && needs_ordered_drop(cx, cx.typeck_results().node_type(l.hir_id))\n            {\n                local_needs_ordered_drop = true;\n                return true;\n            }\n            modifies_any_local(cx, stmt, &cond_locals)\n                || !eq_stmts(cx, stmt, blocks, |b| b.stmts.get(i), &mut eq, &mut moved_locals)\n        })\n        .map_or(block.stmts.len(), |(i, stmt)| {\n            adjust_by_closest_callsite(i, stmt, block.stmts[..i].iter().enumerate().rev())\n        });\n\n    if local_needs_ordered_drop {\n        return BlockEq {\n            start_end_eq,\n            end_begin_eq: None,\n            moved_locals,\n        };\n    }\n\n    // Walk backwards through the final expression/statements so long as their hashes are equal. Note\n    // `SpanlessHash` treats all local references as equal allowing locals declared earlier in the block\n    // to match those in other blocks. e.g. If each block ends with the following the hash value will be\n    // the same even though each `x` binding will have a different `HirId`:\n    //     let x = foo();\n    //     x + 50\n    let expr_hash_eq = if let Some(e) = block.expr {\n        let hash = hash_expr(cx, e);\n        blocks.iter().all(|b| b.expr.is_some_and(|e| hash_expr(cx, e) == hash))\n    } else {\n        blocks.iter().all(|b| b.expr.is_none())\n    };\n    if !expr_hash_eq {\n        return BlockEq {\n            start_end_eq,\n            end_begin_eq: None,\n            moved_locals,\n        };\n    }\n    let end_search_start = block.stmts[start_end_eq..]\n        .iter()\n        .rev()\n        .enumerate()\n        .find(|&(offset, stmt)| {\n            let hash = hash_stmt(cx, stmt);\n            blocks.iter().any(|b| {\n                b.stmts\n                    // the bounds check will catch the underflow\n                    .get(b.stmts.len().wrapping_sub(offset + 1))\n                    .is_none_or(|s| hash != hash_stmt(cx, s))\n            })\n        })\n        .map_or(block.stmts.len() - start_end_eq, |(i, stmt)| {\n            adjust_by_closest_callsite(i, stmt, (0..i).rev().zip(block.stmts[(block.stmts.len() - i)..].iter()))\n        });\n\n    let moved_locals_at_start = moved_locals.len();\n    let mut i = end_search_start;\n    let end_begin_eq = block.stmts[block.stmts.len() - end_search_start..]\n        .iter()\n        .zip(iter::repeat_with(move || {\n            let x = i;\n            i -= 1;\n            x\n        }))\n        .fold(end_search_start, |init, (stmt, offset)| {\n            if eq_stmts(\n                cx,\n                stmt,\n                blocks,\n                |b| b.stmts.get(b.stmts.len() - offset),\n                &mut eq,\n                &mut moved_locals,\n            ) {\n                init\n            } else {\n                // Clear out all locals seen at the end so far. None of them can be moved.\n                let stmts = &blocks[0].stmts;\n                for stmt in &stmts[stmts.len() - init..=stmts.len() - offset] {\n                    match stmt.kind {\n                        StmtKind::Let(l) => {\n                            l.pat.each_binding_or_first(&mut |_, id, _, _| {\n                                // FIXME(rust/#120456) - is `swap_remove` correct?\n                                eq.locals.swap_remove(&id);\n                            });\n                        },\n                        StmtKind::Item(item_id) => {\n                            let item = cx.tcx.hir_item(item_id);\n                            if let ItemKind::Static(..)\n                            | ItemKind::Const(..)\n                            | ItemKind::Fn { .. }\n                            | ItemKind::TyAlias(..)\n                            | ItemKind::Use(..)\n                            | ItemKind::Mod(..) = item.kind\n                            {\n                                eq.local_items.swap_remove(&item.owner_id.to_def_id());\n                            }\n                        },\n                        _ => {},\n                    }\n                }\n                moved_locals.truncate(moved_locals_at_start);\n                offset - 1\n            }\n        });\n    if let Some(e) = block.expr {\n        for block in blocks {\n            if block.expr.is_some_and(|expr| !eq.eq_expr(expr, e)) {\n                moved_locals.truncate(moved_locals_at_start);\n                return BlockEq {\n                    start_end_eq,\n                    end_begin_eq: None,\n                    moved_locals,\n                };\n            }\n        }\n    }\n\n    BlockEq {\n        start_end_eq,\n        end_begin_eq: Some(end_begin_eq),\n        moved_locals,\n    }\n}\n\n/// Adjusts the index for which the statements begin to differ to the closest macro callsite.\n/// This avoids giving suggestions that requires splitting a macro call in half, when only a\n/// part of the macro expansion is equal.\n///\n/// For example, for the following macro:\n/// ```rust,ignore\n/// macro_rules! foo {\n///    ($x:expr) => {\n///        let y = 42;\n///        $x;\n///    };\n/// }\n/// ```\n/// If the macro is called like this:\n/// ```rust,ignore\n/// if false {\n///    let z = 42;\n///    foo!(println!(\"Hello\"));\n/// } else {\n///    let z = 42;\n///    foo!(println!(\"World\"));\n/// }\n/// ```\n/// Although the expanded `let y = 42;` is equal, the macro call should not be included in the\n/// suggestion.\nfn adjust_by_closest_callsite<'tcx>(\n    i: usize,\n    stmt: &'tcx Stmt<'tcx>,\n    mut iter: impl Iterator<Item = (usize, &'tcx Stmt<'tcx>)>,\n) -> usize {\n    let Some((_, first)) = iter.next() else {\n        return 0;\n    };\n\n    // If it is already at the boundary of a macro call, then just return.\n    if first.span.source_callsite() != stmt.span.source_callsite() {\n        return i;\n    }\n\n    iter.find(|(_, stmt)| stmt.span.source_callsite() != first.span.source_callsite())\n        .map_or(0, |(i, _)| i + 1)\n}\n\nfn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbol)], if_expr: &Expr<'_>) -> bool {\n    get_enclosing_block(cx, if_expr.hir_id).is_some_and(|block| {\n        let ignore_span = block.span.shrink_to_lo().to(if_expr.span);\n\n        symbols\n            .iter()\n            .filter(|&&(_, name)| !name.as_str().starts_with('_'))\n            .any(|&(_, name)| {\n                let mut walker = ContainsName { name, cx };\n\n                // Scan block\n                let mut res = block\n                    .stmts\n                    .iter()\n                    .filter(|stmt| !ignore_span.overlaps(stmt.span))\n                    .try_for_each(|stmt| intravisit::walk_stmt(&mut walker, stmt));\n\n                if let Some(expr) = block.expr\n                    && res.is_continue()\n                {\n                    res = intravisit::walk_expr(&mut walker, expr);\n                }\n\n                res.is_break()\n            })\n    })\n}\n\nfn is_expr_parent_assignment(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let parent = cx.tcx.parent_hir_node(expr.hir_id);\n    if let Node::LetStmt(LetStmt { init: Some(e), .. })\n    | Node::Expr(Expr {\n        kind: ExprKind::Assign(_, e, _),\n        ..\n    }) = parent\n    {\n        return e.hir_id == expr.hir_id;\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/ifs/if_same_then_else.rs",
    "content": "use clippy_utils::SpanlessEq;\nuse clippy_utils::diagnostics::span_lint_and_note;\nuse clippy_utils::higher::has_let_expr;\nuse rustc_hir::{Block, Expr};\nuse rustc_lint::LateContext;\n\nuse super::IF_SAME_THEN_ELSE;\n\npub(super) fn check(cx: &LateContext<'_>, conds: &[&Expr<'_>], blocks: &[&Block<'_>]) -> bool {\n    let mut eq = SpanlessEq::new(cx);\n    blocks\n        .array_windows::<2>()\n        .enumerate()\n        .fold(true, |all_eq, (i, &[lhs, rhs])| {\n            if eq.eq_block(lhs, rhs) && !has_let_expr(conds[i]) && conds.get(i + 1).is_none_or(|e| !has_let_expr(e)) {\n                span_lint_and_note(\n                    cx,\n                    IF_SAME_THEN_ELSE,\n                    lhs.span,\n                    \"this `if` has identical blocks\",\n                    Some(rhs.span),\n                    \"same as this\",\n                );\n                all_eq\n            } else {\n                false\n            }\n        })\n}\n"
  },
  {
    "path": "clippy_lints/src/ifs/ifs_same_cond.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::ty::InteriorMut;\nuse clippy_utils::{SpanlessEq, eq_expr_value, find_binding_init, hash_expr, search_same};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\n\nuse super::IFS_SAME_COND;\n\nfn method_caller_is_mutable<'tcx>(\n    cx: &LateContext<'tcx>,\n    caller_expr: &Expr<'_>,\n    interior_mut: &mut InteriorMut<'tcx>,\n) -> bool {\n    let caller_ty = cx.typeck_results().expr_ty(caller_expr);\n\n    interior_mut.is_interior_mut_ty(cx, caller_ty)\n        || caller_ty.is_mutable_ptr()\n        // `find_binding_init` will return the binding iff its not mutable\n        || caller_expr.res_local_id()\n            .and_then(|hid| find_binding_init(cx, hid))\n            .is_none()\n}\n\n/// Implementation of `IFS_SAME_COND`.\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, conds: &[&Expr<'_>], interior_mut: &mut InteriorMut<'tcx>) {\n    for group in search_same(\n        conds,\n        |e| hash_expr(cx, e),\n        |lhs, rhs| {\n            // Ignore eq_expr side effects iff one of the expression kind is a method call\n            // and the caller is not a mutable, including inner mutable type.\n            if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind {\n                if method_caller_is_mutable(cx, caller, interior_mut) {\n                    false\n                } else {\n                    SpanlessEq::new(cx).eq_expr(lhs, rhs)\n                }\n            } else {\n                eq_expr_value(cx, lhs, rhs)\n            }\n        },\n    ) {\n        let spans: Vec<_> = group.into_iter().map(|expr| expr.span).collect();\n        span_lint(cx, IFS_SAME_COND, spans, \"these `if` branches have the same condition\");\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ifs/mod.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::ty::InteriorMut;\nuse clippy_utils::{if_sequence, is_else_clause, is_lint_allowed};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\n\nmod branches_sharing_code;\nmod if_same_then_else;\nmod ifs_same_cond;\nmod same_functions_in_if_cond;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if the `if` and `else` block contain shared code that can be\n    /// moved out of the blocks.\n    ///\n    /// ### Why is this bad?\n    /// Duplicate code is less maintainable.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// let foo = if … {\n    ///     println!(\"Hello World\");\n    ///     13\n    /// } else {\n    ///     println!(\"Hello World\");\n    ///     42\n    /// };\n    /// ```\n    ///\n    /// Use instead:\n    /// ```ignore\n    /// println!(\"Hello World\");\n    /// let foo = if … {\n    ///     13\n    /// } else {\n    ///     42\n    /// };\n    /// ```\n    #[clippy::version = \"1.53.0\"]\n    pub BRANCHES_SHARING_CODE,\n    nursery,\n    \"`if` statement with shared code in all blocks\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `if/else` with the same body as the *then* part\n    /// and the *else* part.\n    ///\n    /// ### Why is this bad?\n    /// This is probably a copy & paste error.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// let foo = if … {\n    ///     42\n    /// } else {\n    ///     42\n    /// };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub IF_SAME_THEN_ELSE,\n    style,\n    \"`if` with the same `then` and `else` blocks\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for consecutive `if`s with the same condition.\n    ///\n    /// ### Why is this bad?\n    /// This is probably a copy & paste error.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// if a == b {\n    ///     …\n    /// } else if a == b {\n    ///     …\n    /// }\n    /// ```\n    ///\n    /// Note that this lint ignores all conditions with a function call as it could\n    /// have side effects:\n    ///\n    /// ```ignore\n    /// if foo() {\n    ///     …\n    /// } else if foo() { // not linted\n    ///     …\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub IFS_SAME_COND,\n    correctness,\n    \"consecutive `if`s with the same condition\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for consecutive `if`s with the same function call.\n    ///\n    /// ### Why is this bad?\n    /// This is probably a copy & paste error.\n    /// Despite the fact that function can have side effects and `if` works as\n    /// intended, such an approach is implicit and can be considered a \"code smell\".\n    ///\n    /// ### Example\n    /// ```ignore\n    /// if foo() == bar {\n    ///     …\n    /// } else if foo() == bar {\n    ///     …\n    /// }\n    /// ```\n    ///\n    /// This probably should be:\n    /// ```ignore\n    /// if foo() == bar {\n    ///     …\n    /// } else if foo() == baz {\n    ///     …\n    /// }\n    /// ```\n    ///\n    /// or if the original code was not a typo and called function mutates a state,\n    /// consider move the mutation out of the `if` condition to avoid similarity to\n    /// a copy & paste error:\n    ///\n    /// ```ignore\n    /// let first = foo();\n    /// if first == bar {\n    ///     …\n    /// } else {\n    ///     let second = foo();\n    ///     if second == bar {\n    ///     …\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.41.0\"]\n    pub SAME_FUNCTIONS_IN_IF_CONDITION,\n    pedantic,\n    \"consecutive `if`s with the same function call\"\n}\n\nimpl_lint_pass!(CopyAndPaste<'_> => [\n    BRANCHES_SHARING_CODE,\n    IFS_SAME_COND,\n    IF_SAME_THEN_ELSE,\n    SAME_FUNCTIONS_IN_IF_CONDITION,\n]);\n\npub struct CopyAndPaste<'tcx> {\n    interior_mut: InteriorMut<'tcx>,\n}\n\nimpl<'tcx> CopyAndPaste<'tcx> {\n    pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf) -> Self {\n        Self {\n            interior_mut: InteriorMut::new(tcx, &conf.ignore_interior_mutability),\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for CopyAndPaste<'tcx> {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if !expr.span.from_expansion() && matches!(expr.kind, ExprKind::If(..)) && !is_else_clause(cx.tcx, expr) {\n            let (conds, blocks) = if_sequence(expr);\n            ifs_same_cond::check(cx, &conds, &mut self.interior_mut);\n            same_functions_in_if_cond::check(cx, &conds);\n            let all_same =\n                !is_lint_allowed(cx, IF_SAME_THEN_ELSE, expr.hir_id) && if_same_then_else::check(cx, &conds, &blocks);\n            if !all_same && conds.len() != blocks.len() {\n                branches_sharing_code::check(cx, &conds, &blocks, expr);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ifs/same_functions_in_if_cond.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::{SpanlessEq, eq_expr_value, hash_expr, search_same};\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\n\nuse super::SAME_FUNCTIONS_IN_IF_CONDITION;\n\n/// Implementation of `SAME_FUNCTIONS_IN_IF_CONDITION`.\npub(super) fn check(cx: &LateContext<'_>, conds: &[&Expr<'_>]) {\n    let eq: &dyn Fn(&&Expr<'_>, &&Expr<'_>) -> bool = &|&lhs, &rhs| -> bool {\n        // Do not lint if any expr originates from a macro\n        if lhs.span.from_expansion() || rhs.span.from_expansion() {\n            return false;\n        }\n        // Do not spawn warning if `IFS_SAME_COND` already produced it.\n        if eq_expr_value(cx, lhs, rhs) {\n            return false;\n        }\n        SpanlessEq::new(cx).eq_expr(lhs, rhs)\n    };\n\n    for group in search_same(conds, |e| hash_expr(cx, e), eq) {\n        let spans: Vec<_> = group.into_iter().map(|expr| expr.span).collect();\n        span_lint(\n            cx,\n            SAME_FUNCTIONS_IN_IF_CONDITION,\n            spans,\n            \"these `if` branches have the same function call\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ignored_unit_patterns.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse hir::{Node, PatKind};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_` in patterns of type `()`.\n    ///\n    /// ### Why is this bad?\n    /// Matching with `()` explicitly instead of `_` outlines\n    /// the fact that the pattern contains no data. Also it\n    /// would detect a type change that `_` would ignore.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// match std::fs::create_dir(\"tmp-work-dir\") {\n    ///     Ok(_) => println!(\"Working directory created\"),\n    ///     Err(s) => eprintln!(\"Could not create directory: {s}\"),\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// match std::fs::create_dir(\"tmp-work-dir\") {\n    ///     Ok(()) => println!(\"Working directory created\"),\n    ///     Err(s) => eprintln!(\"Could not create directory: {s}\"),\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub IGNORED_UNIT_PATTERNS,\n    pedantic,\n    \"suggest replacing `_` by `()` in patterns where appropriate\"\n}\n\ndeclare_lint_pass!(IgnoredUnitPatterns => [IGNORED_UNIT_PATTERNS]);\n\nimpl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns {\n    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx hir::Pat<'tcx>) {\n        if matches!(pat.kind, PatKind::Wild)\n            && !pat.span.from_expansion()\n            && cx.typeck_results().pat_ty(pat).peel_refs().is_unit()\n        {\n            match cx.tcx.parent_hir_node(pat.hir_id) {\n                Node::Param(param) if matches!(cx.tcx.parent_hir_node(param.hir_id), Node::Item(_)) => {\n                    // Ignore function parameters\n                    return;\n                },\n                Node::LetStmt(local) if local.ty.is_some() => {\n                    // Ignore let bindings with explicit type\n                    return;\n                },\n                _ => {},\n            }\n            span_lint_and_sugg(\n                cx,\n                IGNORED_UNIT_PATTERNS,\n                pat.span,\n                \"matching over `()` is more explicit\",\n                \"use `()` instead of `_`\",\n                String::from(\"()\"),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/impl_hash_with_borrow_str_and_bytes.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// This lint is concerned with the semantics of `Borrow` and `Hash` for a\n    /// type that implements all three of `Hash`, `Borrow<str>` and `Borrow<[u8]>`\n    /// as it is impossible to satisfy the semantics of Borrow and `Hash` for\n    /// both `Borrow<str>` and `Borrow<[u8]>`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// When providing implementations for `Borrow<T>`, one should consider whether the different\n    /// implementations should act as facets or representations of the underlying type. Generic code\n    /// typically uses `Borrow<T>` when it relies on the identical behavior of these additional trait\n    /// implementations. These traits will likely appear as additional trait bounds.\n    ///\n    /// In particular `Eq`, `Ord` and `Hash` must be equivalent for borrowed and owned values:\n    /// `x.borrow() == y.borrow()` should give the same result as `x == y`.\n    /// It follows then that the following equivalence must hold:\n    /// `hash(x) == hash((x as Borrow<[u8]>).borrow()) == hash((x as Borrow<str>).borrow())`\n    ///\n    /// Unfortunately it doesn't hold as `hash(\"abc\") != hash(\"abc\".as_bytes())`.\n    /// This happens because the `Hash` impl for str passes an additional `0xFF` byte to\n    /// the hasher to avoid collisions. For example, given the tuples `(\"a\", \"bc\")`, and `(\"ab\", \"c\")`,\n    /// the two tuples would have the same hash value if the `0xFF` byte was not added.\n    ///\n    /// ### Example\n    ///\n    /// ```\n    /// use std::borrow::Borrow;\n    /// use std::hash::{Hash, Hasher};\n    ///\n    /// struct ExampleType {\n    ///     data: String\n    /// }\n    ///\n    /// impl Hash for ExampleType {\n    ///     fn hash<H: Hasher>(&self, state: &mut H) {\n    ///         self.data.hash(state);\n    ///     }\n    /// }\n    ///\n    /// impl Borrow<str> for ExampleType {\n    ///     fn borrow(&self) -> &str {\n    ///         &self.data\n    ///     }\n    /// }\n    ///\n    /// impl Borrow<[u8]> for ExampleType {\n    ///     fn borrow(&self) -> &[u8] {\n    ///         self.data.as_bytes()\n    ///     }\n    /// }\n    /// ```\n    /// As a consequence, hashing a `&ExampleType` and hashing the result of the two\n    /// borrows will result in different values.\n    ///\n    #[clippy::version = \"1.76.0\"]\n    pub IMPL_HASH_BORROW_WITH_STR_AND_BYTES,\n    correctness,\n    \"ensures that the semantics of `Borrow` for `Hash` are satisfied when `Borrow<str>` and `Borrow<[u8]>` are implemented\"\n}\n\ndeclare_lint_pass!(ImplHashWithBorrowStrBytes => [\n    IMPL_HASH_BORROW_WITH_STR_AND_BYTES,\n]);\n\nimpl LateLintPass<'_> for ImplHashWithBorrowStrBytes {\n    /// We are emitting this lint at the Hash impl of a type that implements all\n    /// three of `Hash`, `Borrow<str>` and `Borrow<[u8]>`.\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        if let ItemKind::Impl(imp) = item.kind\n            && let Some(of_trait) = imp.of_trait\n            && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n            && let Some(hash_id) = cx.tcx.get_diagnostic_item(sym::Hash)\n            && Res::Def(DefKind::Trait, hash_id) == of_trait.trait_ref.path.res\n            && let Some(borrow_id) = cx.tcx.get_diagnostic_item(sym::Borrow)\n            // since we are in the `Hash` impl, we don't need to check for that.\n            // we need only to check for `Borrow<str>` and `Borrow<[u8]>`\n            && implements_trait(cx, ty, borrow_id, &[cx.tcx.types.str_.into()])\n            && implements_trait(cx, ty, borrow_id, &[Ty::new_slice(cx.tcx, cx.tcx.types.u8).into()])\n        {\n            span_lint_and_then(\n                cx,\n                IMPL_HASH_BORROW_WITH_STR_AND_BYTES,\n                of_trait.trait_ref.path.span,\n                \"the semantics of `Borrow<T>` around `Hash` can't be satisfied when both `Borrow<str>` and `Borrow<[u8]>` are implemented\",\n                |diag| {\n                    diag.note(\"the `Borrow` semantics require that `Hash` must behave the same for all implementations of Borrow<T>\");\n                    diag.note(\n          \"however, the hash implementations of a string (`str`) and the bytes of a string `[u8]` do not behave the same ...\"\n      );\n                    diag.note(\"... as (`hash(\\\"abc\\\") != hash(\\\"abc\\\".as_bytes())`\");\n                    diag.help(\"consider either removing one of the  `Borrow` implementations (`Borrow<str>` or `Borrow<[u8]>`) ...\");\n                    diag.help(\"... or not implementing `Hash` for this type\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/implicit_hasher.rs",
    "content": "use std::borrow::Cow;\nuse std::collections::BTreeMap;\n\nuse clippy_utils::res::MaybeDef;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::intravisit::{Visitor, VisitorExt, walk_body, walk_expr, walk_ty};\nuse rustc_hir::{self as hir, AmbigArg, Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};\nuse rustc_hir_analysis::lower_ty;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::{Ty, TypeckResults};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{IntoSpan, SpanRangeExt, snippet, snippet_with_context};\nuse clippy_utils::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for public `impl` or `fn` missing generalization\n    /// over different hashers and implicitly defaulting to the default hashing\n    /// algorithm (`SipHash`).\n    ///\n    /// ### Why is this bad?\n    /// `HashMap` or `HashSet` with custom hashers cannot be\n    /// used with them.\n    ///\n    /// ### Known problems\n    /// Suggestions for replacing constructors can contain\n    /// false-positives. Also applying suggestions can require modification of other\n    /// pieces of code, possibly including external crates.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::collections::HashMap;\n    /// # use std::hash::{Hash, BuildHasher};\n    /// # trait Serialize {};\n    /// impl<K: Hash + Eq, V> Serialize for HashMap<K, V> { }\n    ///\n    /// pub fn foo(map: &mut HashMap<i32, i32>) { }\n    /// ```\n    /// could be rewritten as\n    /// ```no_run\n    /// # use std::collections::HashMap;\n    /// # use std::hash::{Hash, BuildHasher};\n    /// # trait Serialize {};\n    /// impl<K: Hash + Eq, V, S: BuildHasher> Serialize for HashMap<K, V, S> { }\n    ///\n    /// pub fn foo<S: BuildHasher>(map: &mut HashMap<i32, i32, S>) { }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub IMPLICIT_HASHER,\n    pedantic,\n    \"missing generalization over different hashers\"\n}\n\ndeclare_lint_pass!(ImplicitHasher => [IMPLICIT_HASHER]);\n\nimpl<'tcx> LateLintPass<'tcx> for ImplicitHasher {\n    #[expect(clippy::too_many_lines)]\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        fn suggestion(\n            cx: &LateContext<'_>,\n            diag: &mut Diag<'_, ()>,\n            generics_span: Span,\n            generics_suggestion_span: Span,\n            target: &ImplicitHasherType<'_>,\n            vis: ImplicitHasherConstructorVisitor<'_, '_, '_>,\n        ) {\n            let generics_snip = snippet(cx, generics_span, \"\");\n            // trim `<` `>`\n            let generics_snip = if generics_snip.is_empty() {\n                \"\"\n            } else {\n                &generics_snip[1..generics_snip.len() - 1]\n            };\n\n            let mut suggestions = vec![\n                (\n                    generics_suggestion_span,\n                    format!(\n                        \"<{generics_snip}{}S: ::std::hash::BuildHasher{}>\",\n                        if generics_snip.is_empty() { \"\" } else { \", \" },\n                        if vis.suggestions.is_empty() {\n                            \"\"\n                        } else {\n                            // request users to add `Default` bound so that generic constructors can be used\n                            \" + Default\"\n                        },\n                    ),\n                ),\n                (\n                    target.span(),\n                    format!(\"{}<{}, S>\", target.type_name(), target.type_arguments()),\n                ),\n            ];\n            suggestions.extend(vis.suggestions);\n\n            diag.multipart_suggestion(\n                \"add a type parameter for `BuildHasher`\",\n                suggestions,\n                Applicability::MaybeIncorrect,\n            );\n        }\n\n        if !cx.effective_visibilities.is_exported(item.owner_id.def_id) {\n            return;\n        }\n\n        match item.kind {\n            ItemKind::Impl(impl_) => {\n                let mut vis = ImplicitHasherTypeVisitor::new(cx);\n                vis.visit_ty_unambig(impl_.self_ty);\n\n                for target in &vis.found {\n                    if !item.span.eq_ctxt(target.span()) {\n                        return;\n                    }\n\n                    let generics_suggestion_span = impl_.generics.span.substitute_dummy({\n                        let range = (item.span.lo()..target.span().lo()).map_range(cx, |_, src, range| {\n                            Some(src.get(range.clone())?.find(\"impl\")? + 4..range.end)\n                        });\n                        if let Some(range) = range {\n                            range.with_ctxt(item.span.ctxt())\n                        } else {\n                            return;\n                        }\n                    });\n\n                    let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);\n                    for item in impl_.items.iter().map(|&item| cx.tcx.hir_impl_item(item)) {\n                        ctr_vis.visit_impl_item(item);\n                    }\n\n                    span_lint_and_then(\n                        cx,\n                        IMPLICIT_HASHER,\n                        target.span(),\n                        format!(\n                            \"impl for `{}` should be generalized over different hashers\",\n                            target.type_name()\n                        ),\n                        move |diag| {\n                            suggestion(cx, diag, impl_.generics.span, generics_suggestion_span, target, ctr_vis);\n                        },\n                    );\n                }\n            },\n            ItemKind::Fn {\n                ref sig,\n                generics,\n                body: body_id,\n                ..\n            } => {\n                let body = cx.tcx.hir_body(body_id);\n\n                for ty in sig.decl.inputs {\n                    let mut vis = ImplicitHasherTypeVisitor::new(cx);\n                    vis.visit_ty_unambig(ty);\n\n                    for target in &vis.found {\n                        if generics.span.from_expansion() {\n                            continue;\n                        }\n                        let generics_suggestion_span = generics.span.substitute_dummy({\n                            let range =\n                                (item.span.lo()..body.params[0].pat.span.lo()).map_range(cx, |_, src, range| {\n                                    let (pre, post) = src.get(range.clone())?.split_once(\"fn\")?;\n                                    let pos = post.find('(')? + pre.len() + 2;\n                                    Some(pos..pos)\n                                });\n                            if let Some(range) = range {\n                                range.with_ctxt(item.span.ctxt())\n                            } else {\n                                return;\n                            }\n                        });\n\n                        let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);\n                        ctr_vis.visit_body(body);\n\n                        span_lint_and_then(\n                            cx,\n                            IMPLICIT_HASHER,\n                            target.span(),\n                            format!(\n                                \"parameter of type `{}` should be generalized over different hashers\",\n                                target.type_name()\n                            ),\n                            move |diag| {\n                                suggestion(cx, diag, generics.span, generics_suggestion_span, target, ctr_vis);\n                            },\n                        );\n                    }\n                }\n            },\n            _ => {},\n        }\n    }\n}\n\nenum ImplicitHasherType<'tcx> {\n    HashMap(Span, Ty<'tcx>, Cow<'static, str>, Cow<'static, str>),\n    HashSet(Span, Ty<'tcx>, Cow<'static, str>),\n}\n\nimpl<'tcx> ImplicitHasherType<'tcx> {\n    /// Checks that `ty` is a target type without a `BuildHasher`.\n    fn new(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Option<Self> {\n        if let TyKind::Path(QPath::Resolved(None, path)) = hir_ty.kind {\n            let params: Vec<_> = path\n                .segments\n                .last()\n                .as_ref()?\n                .args\n                .as_ref()?\n                .args\n                .iter()\n                .filter_map(|arg| match arg {\n                    GenericArg::Type(ty) => Some(ty),\n                    _ => None,\n                })\n                .collect();\n\n            let ty = lower_ty(cx.tcx, hir_ty);\n\n            match (ty.opt_diag_name(cx), &params[..]) {\n                (Some(sym::HashMap), [k, v]) => Some(ImplicitHasherType::HashMap(\n                    hir_ty.span,\n                    ty,\n                    snippet(cx, k.span, \"K\"),\n                    snippet(cx, v.span, \"V\"),\n                )),\n                (Some(sym::HashSet), [t]) => {\n                    Some(ImplicitHasherType::HashSet(hir_ty.span, ty, snippet(cx, t.span, \"T\")))\n                },\n                _ => None,\n            }\n        } else {\n            None\n        }\n    }\n\n    fn type_name(&self) -> &'static str {\n        match *self {\n            ImplicitHasherType::HashMap(..) => \"HashMap\",\n            ImplicitHasherType::HashSet(..) => \"HashSet\",\n        }\n    }\n\n    fn type_arguments(&self) -> String {\n        match *self {\n            ImplicitHasherType::HashMap(.., ref k, ref v) => format!(\"{k}, {v}\"),\n            ImplicitHasherType::HashSet(.., ref t) => format!(\"{t}\"),\n        }\n    }\n\n    fn ty(&self) -> Ty<'tcx> {\n        match *self {\n            ImplicitHasherType::HashMap(_, ty, ..) | ImplicitHasherType::HashSet(_, ty, ..) => ty,\n        }\n    }\n\n    fn span(&self) -> Span {\n        match *self {\n            ImplicitHasherType::HashMap(span, ..) | ImplicitHasherType::HashSet(span, ..) => span,\n        }\n    }\n}\n\nstruct ImplicitHasherTypeVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    found: Vec<ImplicitHasherType<'tcx>>,\n}\n\nimpl<'a, 'tcx> ImplicitHasherTypeVisitor<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>) -> Self {\n        Self { cx, found: vec![] }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'_, 'tcx> {\n    fn visit_ty(&mut self, t: &'tcx hir::Ty<'_, AmbigArg>) {\n        if let Some(target) = ImplicitHasherType::new(self.cx, t.as_unambig_ty()) {\n            self.found.push(target);\n        }\n\n        walk_ty(self, t);\n    }\n}\n\n/// Looks for default-hasher-dependent constructors like `HashMap::new`.\nstruct ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    maybe_typeck_results: Option<&'tcx TypeckResults<'tcx>>,\n    target: &'b ImplicitHasherType<'tcx>,\n    suggestions: BTreeMap<Span, String>,\n}\n\nimpl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>, target: &'b ImplicitHasherType<'tcx>) -> Self {\n        Self {\n            cx,\n            maybe_typeck_results: cx.maybe_typeck_results(),\n            target,\n            suggestions: BTreeMap::new(),\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_body(&mut self, body: &Body<'tcx>) {\n        let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body.id()));\n        walk_body(self, body);\n        self.maybe_typeck_results = old_maybe_typeck_results;\n    }\n\n    fn visit_expr(&mut self, e: &'tcx Expr<'_>) {\n        if let ExprKind::Call(fun, args) = e.kind\n            && let ExprKind::Path(QPath::TypeRelative(ty, method)) = fun.kind\n            && matches!(method.ident.name, sym::new | sym::with_capacity)\n            && let TyKind::Path(QPath::Resolved(None, ty_path)) = ty.kind\n            && let Some(ty_did) = ty_path.res.opt_def_id()\n        {\n            if self.target.ty() != self.maybe_typeck_results.unwrap().expr_ty(e) {\n                return;\n            }\n\n            let container_name = match self.cx.tcx.get_diagnostic_name(ty_did) {\n                Some(sym::HashMap) => \"HashMap\",\n                Some(sym::HashSet) => \"HashSet\",\n                _ => return,\n            };\n\n            match method.ident.name {\n                sym::new => {\n                    self.suggestions.insert(e.span, format!(\"{container_name}::default()\"));\n                },\n                sym::with_capacity => {\n                    let (arg_snippet, _) = snippet_with_context(\n                        self.cx,\n                        args[0].span,\n                        e.span.ctxt(),\n                        \"..\",\n                        // We can throw-away the applicability here since the whole suggestion is\n                        // marked as `MaybeIncorrect` later.\n                        &mut Applicability::MaybeIncorrect,\n                    );\n                    self.suggestions.insert(\n                        e.span,\n                        format!(\"{container_name}::with_capacity_and_hasher({arg_snippet}, Default::default())\"),\n                    );\n                },\n                _ => {},\n            }\n        }\n\n        walk_expr(self, e);\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/implicit_return.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context};\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{desugar_await, get_async_closure_expr, get_async_fn_body, is_from_proc_macro};\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{Span, SyntaxContext};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for missing return statements at the end of a block.\n    ///\n    /// ### Why restrict this?\n    /// Omitting the return keyword whenever possible is idiomatic Rust code, but:\n    ///\n    /// * Programmers coming from other languages might prefer the expressiveness of `return`.\n    /// * It's possible to miss the last returning statement because the only difference is a missing `;`.\n    /// * Especially in bigger code with multiple return paths, having a `return` keyword makes it easier to find the\n    ///   corresponding statements.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(x: usize) -> usize {\n    ///     x\n    /// }\n    /// ```\n    /// add return\n    /// ```no_run\n    /// fn foo(x: usize) -> usize {\n    ///     return x;\n    /// }\n    /// ```\n    #[clippy::version = \"1.33.0\"]\n    pub IMPLICIT_RETURN,\n    restriction,\n    \"use a return statement like `return expr` instead of an expression\"\n}\n\ndeclare_lint_pass!(ImplicitReturn => [IMPLICIT_RETURN]);\n\nfn lint_return(cx: &LateContext<'_>, emission_place: HirId, span: Span) {\n    span_lint_hir_and_then(\n        cx,\n        IMPLICIT_RETURN,\n        emission_place,\n        span,\n        \"missing `return` statement\",\n        |diag| {\n            let mut app = Applicability::MachineApplicable;\n            let snip = snippet_with_applicability(cx, span, \"..\", &mut app);\n            diag.span_suggestion_verbose(span, \"add `return` as shown\", format!(\"return {snip}\"), app);\n        },\n    );\n}\n\nfn lint_break(cx: &LateContext<'_>, emission_place: HirId, break_span: Span, expr_span: Span) {\n    span_lint_hir_and_then(\n        cx,\n        IMPLICIT_RETURN,\n        emission_place,\n        break_span,\n        \"missing `return` statement\",\n        |diag| {\n            let mut app = Applicability::MachineApplicable;\n            let snip = snippet_with_context(cx, expr_span, break_span.ctxt(), \"..\", &mut app).0;\n            diag.span_suggestion_verbose(\n                break_span,\n                \"change `break` to `return` as shown\",\n                format!(\"return {snip}\"),\n                app,\n            );\n        },\n    );\n}\n\n#[derive(Clone, Copy, PartialEq, Eq)]\nenum LintLocation {\n    /// The lint was applied to a parent expression.\n    Parent,\n    /// The lint was applied to this expression, a child, or not applied.\n    Inner,\n}\nimpl LintLocation {\n    fn still_parent(self, b: bool) -> Self {\n        if b { self } else { Self::Inner }\n    }\n\n    fn is_parent(self) -> bool {\n        self == Self::Parent\n    }\n}\n\n// Gets the call site if the span is in a child context. Otherwise returns `None`.\nfn get_call_site(span: Span, ctxt: SyntaxContext) -> Option<Span> {\n    (span.ctxt() != ctxt).then(|| walk_span_to_context(span, ctxt).unwrap_or(span))\n}\n\nfn lint_implicit_returns(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    // The context of the function body.\n    ctxt: SyntaxContext,\n    // Whether the expression is from a macro expansion.\n    call_site_span: Option<Span>,\n) -> LintLocation {\n    match expr.kind {\n        ExprKind::Block(\n            Block {\n                expr: Some(block_expr), ..\n            },\n            _,\n        ) => lint_implicit_returns(\n            cx,\n            block_expr,\n            ctxt,\n            call_site_span.or_else(|| get_call_site(block_expr.span, ctxt)),\n        )\n        .still_parent(call_site_span.is_some()),\n\n        ExprKind::If(_, then_expr, Some(else_expr)) => {\n            // Both `then_expr` or `else_expr` are required to be blocks in the same context as the `if`. Don't\n            // bother checking.\n            let res = lint_implicit_returns(cx, then_expr, ctxt, call_site_span).still_parent(call_site_span.is_some());\n            if res.is_parent() {\n                // The return was added as a parent of this if expression.\n                return res;\n            }\n            lint_implicit_returns(cx, else_expr, ctxt, call_site_span).still_parent(call_site_span.is_some())\n        },\n\n        ExprKind::Match(_, arms, _) => {\n            if let Some(await_expr) = desugar_await(expr) {\n                lint_return(cx, await_expr.hir_id, await_expr.span);\n                return LintLocation::Inner;\n            }\n            for arm in arms {\n                let res = lint_implicit_returns(\n                    cx,\n                    arm.body,\n                    ctxt,\n                    call_site_span.or_else(|| get_call_site(arm.body.span, ctxt)),\n                )\n                .still_parent(call_site_span.is_some());\n                if res.is_parent() {\n                    // The return was added as a parent of this match expression.\n                    return res;\n                }\n            }\n            LintLocation::Inner\n        },\n\n        ExprKind::Loop(block, ..) => {\n            let mut add_return = false;\n            let _: Option<!> = for_each_expr_without_closures(block, |e| {\n                if let ExprKind::Break(dest, sub_expr) = e.kind\n                    && dest.target_id.ok() == Some(expr.hir_id)\n                {\n                    if call_site_span.is_none() && e.span.ctxt() == ctxt {\n                        // At this point sub_expr can be `None` in async functions which either diverge, or return\n                        // the unit type.\n                        if let Some(sub_expr) = sub_expr {\n                            lint_break(cx, e.hir_id, e.span, sub_expr.span);\n                        }\n                    } else {\n                        // the break expression is from a macro call, add a return to the loop\n                        add_return = true;\n                    }\n                }\n                ControlFlow::Continue(())\n            });\n            if add_return {\n                #[expect(clippy::option_if_let_else)]\n                if let Some(span) = call_site_span {\n                    lint_return(cx, expr.hir_id, span);\n                    LintLocation::Parent\n                } else {\n                    lint_return(cx, expr.hir_id, expr.span);\n                    LintLocation::Inner\n                }\n            } else {\n                LintLocation::Inner\n            }\n        },\n\n        // If expressions without an else clause, and blocks without a final expression can only be the final expression\n        // if they are divergent, or return the unit type.\n        ExprKind::If(_, _, None) | ExprKind::Block(Block { expr: None, .. }, _) | ExprKind::Ret(_) => {\n            LintLocation::Inner\n        },\n\n        // Any divergent expression doesn't need a return statement.\n        ExprKind::MethodCall(..)\n        | ExprKind::Call(..)\n        | ExprKind::Binary(..)\n        | ExprKind::Unary(..)\n        | ExprKind::Index(..)\n            if cx.typeck_results().expr_ty(expr).is_never() =>\n        {\n            LintLocation::Inner\n        },\n\n        _ =>\n        {\n            #[expect(clippy::option_if_let_else)]\n            if let Some(span) = call_site_span {\n                lint_return(cx, expr.hir_id, span);\n                LintLocation::Parent\n            } else {\n                lint_return(cx, expr.hir_id, expr.span);\n                LintLocation::Inner\n            }\n        },\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ImplicitReturn {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        span: Span,\n        _: LocalDefId,\n    ) {\n        if (!matches!(kind, FnKind::Closure) && matches!(decl.output, FnRetTy::DefaultReturn(_)))\n            || !span.eq_ctxt(body.value.span)\n            || span.in_external_macro(cx.sess().source_map())\n        {\n            return;\n        }\n\n        let res_ty = cx.typeck_results().expr_ty(body.value);\n        if res_ty.is_unit() || res_ty.is_never() {\n            return;\n        }\n\n        let expr = if kind.asyncness().is_async() {\n            match get_async_fn_body(cx.tcx, body) {\n                Some(e) => e,\n                None => return,\n            }\n        } else if let Some(expr) = get_async_closure_expr(cx.tcx, body.value) {\n            expr\n        } else {\n            body.value\n        };\n\n        if is_from_proc_macro(cx, expr) {\n            return;\n        }\n        lint_implicit_returns(cx, expr, expr.span.ctxt(), None);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/implicit_saturating_add.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::get_parent_expr;\nuse clippy_utils::source::snippet_with_context;\nuse rustc_ast::ast::{LitIntType, LitKind};\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{AssignOpKind, BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{IntTy, Ty, UintTy};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for implicit saturating addition.\n    ///\n    /// ### Why is this bad?\n    /// The built-in function is more readable and may be faster.\n    ///\n    /// ### Example\n    /// ```no_run\n    ///let mut u:u32 = 7000;\n    ///\n    /// if u != u32::MAX {\n    ///     u += 1;\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    ///let mut u:u32 = 7000;\n    ///\n    /// u = u.saturating_add(1);\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub IMPLICIT_SATURATING_ADD,\n    style,\n    \"Perform saturating addition instead of implicitly checking max bound of data type\"\n}\n\ndeclare_lint_pass!(ImplicitSaturatingAdd => [IMPLICIT_SATURATING_ADD]);\n\nimpl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::If(cond, then, None) = expr.kind\n            && let Some((c, op_node, l)) = get_const(cx, cond)\n            && let BinOpKind::Ne | BinOpKind::Lt = op_node\n            && let ExprKind::Block(block, None) = then.kind\n            && let Block {\n                stmts:\n                    [\n                        Stmt {\n                            kind: StmtKind::Expr(ex) | StmtKind::Semi(ex),\n                            ..\n                        },\n                    ],\n                expr: None,\n                ..\n            }\n            | Block {\n                stmts: [],\n                expr: Some(ex),\n                ..\n            } = block\n            && let ExprKind::AssignOp(op1, target, value) = ex.kind\n            && let ty = cx.typeck_results().expr_ty(target)\n            && Some(c) == get_int_max(ty)\n            && let ctxt = expr.span.ctxt()\n            && ex.span.ctxt() == ctxt\n            && cond.span.ctxt() == ctxt\n            && clippy_utils::SpanlessEq::new(cx).eq_expr(l, target)\n            && AssignOpKind::AddAssign == op1.node\n            && let ExprKind::Lit(lit) = value.kind\n            && let LitKind::Int(Pu128(1), LitIntType::Unsuffixed) = lit.node\n            && block.expr.is_none()\n        {\n            let mut app = Applicability::MachineApplicable;\n            let code = snippet_with_context(cx, target.span, ctxt, \"_\", &mut app).0;\n            let sugg = if let Some(parent) = get_parent_expr(cx, expr)\n                && let ExprKind::If(_cond, _then, Some(else_)) = parent.kind\n                && else_.hir_id == expr.hir_id\n            {\n                format!(\"{{{code} = {code}.saturating_add(1); }}\")\n            } else {\n                format!(\"{code} = {code}.saturating_add(1);\")\n            };\n            span_lint_and_sugg(\n                cx,\n                IMPLICIT_SATURATING_ADD,\n                expr.span,\n                \"manual saturating add detected\",\n                \"use instead\",\n                sugg,\n                app,\n            );\n        }\n    }\n}\n\nfn get_int_max(ty: Ty<'_>) -> Option<u128> {\n    use rustc_middle::ty::{Int, Uint};\n    match ty.peel_refs().kind() {\n        Int(IntTy::I8) => i8::MAX.try_into().ok(),\n        Int(IntTy::I16) => i16::MAX.try_into().ok(),\n        Int(IntTy::I32) => i32::MAX.try_into().ok(),\n        Int(IntTy::I64) => i64::MAX.try_into().ok(),\n        Int(IntTy::I128) => i128::MAX.try_into().ok(),\n        Int(IntTy::Isize) => isize::MAX.try_into().ok(),\n        Uint(UintTy::U8) => Some(u8::MAX.into()),\n        Uint(UintTy::U16) => Some(u16::MAX.into()),\n        Uint(UintTy::U32) => Some(u32::MAX.into()),\n        Uint(UintTy::U64) => Some(u64::MAX.into()),\n        Uint(UintTy::U128) => Some(u128::MAX),\n        Uint(UintTy::Usize) => usize::MAX.try_into().ok(),\n        _ => None,\n    }\n}\n\nfn get_const<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<(u128, BinOpKind, &'tcx Expr<'tcx>)> {\n    if let ExprKind::Binary(op, l, r) = expr.kind {\n        let ecx = ConstEvalCtxt::new(cx);\n        let ctxt = expr.span.ctxt();\n        if let Some(Constant::Int(c)) = ecx.eval_local(r, ctxt) {\n            return Some((c, op.node, l));\n        }\n        if let Some(Constant::Int(c)) = ecx.eval_local(l, ctxt) {\n            return Some((c, invert_op(op.node)?, r));\n        }\n    }\n    None\n}\n\nfn invert_op(op: BinOpKind) -> Option<BinOpKind> {\n    use rustc_hir::BinOpKind::{Ge, Gt, Le, Lt, Ne};\n    match op {\n        Lt => Some(Gt),\n        Le => Some(Ge),\n        Ne => Some(Ne),\n        Ge => Some(Le),\n        Gt => Some(Lt),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/implicit_saturating_sub.rs",
    "content": "use std::borrow::Cow;\n\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg::{Sugg, make_binop};\nuse clippy_utils::{\n    SpanlessEq, eq_expr_value, higher, is_in_const_context, is_integer_literal, is_integer_literal_untyped,\n    peel_blocks, peel_blocks_with_stmt, sym,\n};\nuse rustc_ast::ast::LitKind;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{AssignOpKind, BinOp, BinOpKind, Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for implicit saturating subtraction.\n    ///\n    /// ### Why is this bad?\n    /// Simplicity and readability. Instead we can easily use an builtin function.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let end: u32 = 10;\n    /// # let start: u32 = 5;\n    /// let mut i: u32 = end - start;\n    ///\n    /// if i != 0 {\n    ///     i -= 1;\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let end: u32 = 10;\n    /// # let start: u32 = 5;\n    /// let mut i: u32 = end - start;\n    ///\n    /// i = i.saturating_sub(1);\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub IMPLICIT_SATURATING_SUB,\n    style,\n    \"Perform saturating subtraction instead of implicitly checking lower bound of data type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for comparisons between integers, followed by subtracting the greater value from the\n    /// lower one.\n    ///\n    /// ### Why is this bad?\n    /// This could result in an underflow and is most likely not what the user wants. If this was\n    /// intended to be a saturated subtraction, consider using the `saturating_sub` method directly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = 12u32;\n    /// let b = 13u32;\n    ///\n    /// let result = if a > b { b - a } else { 0 };\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let a = 12u32;\n    /// let b = 13u32;\n    ///\n    /// let result = a.saturating_sub(b);\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub INVERTED_SATURATING_SUB,\n    correctness,\n    \"Check if a variable is smaller than another one and still subtract from it even if smaller\"\n}\n\nimpl_lint_pass!(ImplicitSaturatingSub => [\n    IMPLICIT_SATURATING_SUB,\n    INVERTED_SATURATING_SUB,\n]);\n\npub struct ImplicitSaturatingSub {\n    msrv: Msrv,\n}\n\nimpl ImplicitSaturatingSub {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if expr.span.from_expansion() {\n            return;\n        }\n        if let Some(higher::If { cond, then, r#else: None }) = higher::If::hir(expr)\n\n            // Check if the conditional expression is a binary operation\n            && let ExprKind::Binary(ref cond_op, cond_left, cond_right) = cond.kind\n        {\n            check_with_condition(cx, expr, cond_op.node, cond_left, cond_right, then);\n        } else if let Some(higher::If {\n            cond,\n            then: if_block,\n            r#else: Some(else_block),\n        }) = higher::If::hir(expr)\n            && let ExprKind::Binary(ref cond_op, cond_left, cond_right) = cond.kind\n        {\n            check_manual_check(\n                cx, expr, cond_op, cond_left, cond_right, if_block, else_block, self.msrv,\n            );\n        }\n    }\n}\n\n#[expect(clippy::too_many_arguments)]\nfn check_manual_check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'tcx>,\n    condition: &BinOp,\n    left_hand: &Expr<'tcx>,\n    right_hand: &Expr<'tcx>,\n    if_block: &Expr<'tcx>,\n    else_block: &Expr<'tcx>,\n    msrv: Msrv,\n) {\n    let ty = cx.typeck_results().expr_ty(left_hand);\n    if ty.is_numeric() && !ty.is_signed() {\n        match condition.node {\n            BinOpKind::Gt | BinOpKind::Ge => check_gt(\n                cx,\n                condition.span,\n                expr.span,\n                left_hand,\n                right_hand,\n                if_block,\n                else_block,\n                msrv,\n                matches!(\n                    clippy_utils::get_parent_expr(cx, expr),\n                    Some(Expr {\n                        kind: ExprKind::If(..),\n                        ..\n                    })\n                ),\n            ),\n            BinOpKind::Lt | BinOpKind::Le => check_gt(\n                cx,\n                condition.span,\n                expr.span,\n                right_hand,\n                left_hand,\n                if_block,\n                else_block,\n                msrv,\n                matches!(\n                    clippy_utils::get_parent_expr(cx, expr),\n                    Some(Expr {\n                        kind: ExprKind::If(..),\n                        ..\n                    })\n                ),\n            ),\n            _ => {},\n        }\n    }\n}\n\n#[expect(clippy::too_many_arguments)]\nfn check_gt(\n    cx: &LateContext<'_>,\n    condition_span: Span,\n    expr_span: Span,\n    big_expr: &Expr<'_>,\n    little_expr: &Expr<'_>,\n    if_block: &Expr<'_>,\n    else_block: &Expr<'_>,\n    msrv: Msrv,\n    is_composited: bool,\n) {\n    if is_side_effect_free(cx, big_expr) && is_side_effect_free(cx, little_expr) {\n        check_subtraction(\n            cx,\n            condition_span,\n            expr_span,\n            big_expr,\n            little_expr,\n            if_block,\n            else_block,\n            msrv,\n            is_composited,\n        );\n    }\n}\n\nfn is_side_effect_free(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    eq_expr_value(cx, expr, expr)\n}\n\n#[expect(clippy::too_many_arguments)]\nfn check_subtraction(\n    cx: &LateContext<'_>,\n    condition_span: Span,\n    expr_span: Span,\n    big_expr: &Expr<'_>,\n    little_expr: &Expr<'_>,\n    if_block: &Expr<'_>,\n    else_block: &Expr<'_>,\n    msrv: Msrv,\n    is_composited: bool,\n) {\n    let if_block = peel_blocks(if_block);\n    let else_block = peel_blocks(else_block);\n    if is_integer_literal(if_block, 0) {\n        // We need to check this case as well to prevent infinite recursion.\n        if is_integer_literal(else_block, 0) {\n            // Well, seems weird but who knows?\n            return;\n        }\n        // If the subtraction is done in the `else` block, then we need to also revert the two\n        // variables as it means that the check was reverted too.\n        check_subtraction(\n            cx,\n            condition_span,\n            expr_span,\n            little_expr,\n            big_expr,\n            else_block,\n            if_block,\n            msrv,\n            is_composited,\n        );\n        return;\n    }\n    if is_integer_literal(else_block, 0)\n        && let ExprKind::Binary(op, left, right) = if_block.kind\n        && let BinOpKind::Sub = op.node\n    {\n        if eq_expr_value(cx, left, big_expr) && eq_expr_value(cx, right, little_expr) {\n            // This part of the condition is voluntarily split from the one before to ensure that\n            // if `snippet_opt` fails, it won't try the next conditions.\n            if !is_in_const_context(cx) || msrv.meets(cx, msrvs::SATURATING_SUB_CONST) {\n                let mut applicability = Applicability::MachineApplicable;\n                let big_expr_sugg = (if is_integer_literal_untyped(big_expr) {\n                    let get_snippet = |span: Span| {\n                        let snippet = snippet_with_applicability(cx, span, \"..\", &mut applicability);\n                        let big_expr_ty = cx.typeck_results().expr_ty(big_expr);\n                        Cow::Owned(format!(\"{snippet}_{big_expr_ty}\"))\n                    };\n                    Sugg::hir_from_snippet(cx, big_expr, get_snippet)\n                } else {\n                    Sugg::hir_with_applicability(cx, big_expr, \"..\", &mut applicability)\n                })\n                .maybe_paren();\n                let little_expr_sugg = Sugg::hir_with_applicability(cx, little_expr, \"..\", &mut applicability);\n\n                let sugg = format!(\n                    \"{}{big_expr_sugg}.saturating_sub({little_expr_sugg}){}\",\n                    if is_composited { \"{ \" } else { \"\" },\n                    if is_composited { \" }\" } else { \"\" }\n                );\n                span_lint_and_sugg(\n                    cx,\n                    IMPLICIT_SATURATING_SUB,\n                    expr_span,\n                    \"manual arithmetic check found\",\n                    \"replace it with\",\n                    sugg,\n                    applicability,\n                );\n            }\n        } else if eq_expr_value(cx, left, little_expr)\n            && eq_expr_value(cx, right, big_expr)\n            && let Some(big_expr_sugg) = Sugg::hir_opt(cx, big_expr)\n            && let Some(little_expr_sugg) = Sugg::hir_opt(cx, little_expr)\n        {\n            let sugg = make_binop(BinOpKind::Sub, &big_expr_sugg, &little_expr_sugg);\n            span_lint_and_then(\n                cx,\n                INVERTED_SATURATING_SUB,\n                condition_span,\n                \"inverted arithmetic check before subtraction\",\n                |diag| {\n                    diag.span_note(\n                        if_block.span,\n                        format!(\"this subtraction underflows when `{little_expr_sugg} < {big_expr_sugg}`\"),\n                    );\n                    diag.span_suggestion(\n                        if_block.span,\n                        \"try replacing it with\",\n                        format!(\"{sugg}\"),\n                        Applicability::MaybeIncorrect,\n                    );\n                },\n            );\n        }\n    }\n}\n\nfn check_with_condition<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'tcx>,\n    cond_op: BinOpKind,\n    cond_left: &Expr<'tcx>,\n    cond_right: &Expr<'tcx>,\n    then: &Expr<'tcx>,\n) {\n    // Ensure that the binary operator is >, !=, or <\n    if (BinOpKind::Ne == cond_op || BinOpKind::Gt == cond_op || BinOpKind::Lt == cond_op)\n\n        // Check if assign operation is done\n        && let Some(target) = subtracts_one(cx, then)\n\n        // Extracting out the variable name\n        && let ExprKind::Path(QPath::Resolved(_, ares_path)) = target.kind\n    {\n        // Handle symmetric conditions in the if statement\n        let (cond_var, cond_num_val) = if SpanlessEq::new(cx).eq_expr(cond_left, target) {\n            if BinOpKind::Gt == cond_op || BinOpKind::Ne == cond_op {\n                (cond_left, cond_right)\n            } else {\n                return;\n            }\n        } else if SpanlessEq::new(cx).eq_expr(cond_right, target) {\n            if BinOpKind::Lt == cond_op || BinOpKind::Ne == cond_op {\n                (cond_right, cond_left)\n            } else {\n                return;\n            }\n        } else {\n            return;\n        };\n\n        // Check if the variable in the condition statement is an integer\n        if !cx.typeck_results().expr_ty(cond_var).is_integral() {\n            return;\n        }\n\n        // Get the variable name\n        let var_name = ares_path.segments[0].ident.name;\n        match cond_num_val.kind {\n            ExprKind::Lit(cond_lit) => {\n                // Check if the constant is zero\n                if let LitKind::Int(Pu128(0), _) = cond_lit.node {\n                    if cx.typeck_results().expr_ty(cond_left).is_signed() {\n                    } else {\n                        print_lint_and_sugg(cx, var_name, expr);\n                    }\n                }\n            },\n            ExprKind::Path(QPath::TypeRelative(_, name)) => {\n                if name.ident.name == sym::MIN\n                    && let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id)\n                    && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(const_id)\n                    && cx.tcx.type_of(impl_id).instantiate_identity().is_integral()\n                {\n                    print_lint_and_sugg(cx, var_name, expr);\n                }\n            },\n            ExprKind::Call(func, []) => {\n                if let ExprKind::Path(QPath::TypeRelative(_, name)) = func.kind\n                    && name.ident.name == sym::min_value\n                    && let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id)\n                    && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(func_id)\n                    && cx.tcx.type_of(impl_id).instantiate_identity().is_integral()\n                {\n                    print_lint_and_sugg(cx, var_name, expr);\n                }\n            },\n            _ => (),\n        }\n    }\n}\n\nfn subtracts_one<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<&'a Expr<'a>> {\n    match peel_blocks_with_stmt(expr).kind {\n        ExprKind::AssignOp(ref op1, target, value) => {\n            // Check if literal being subtracted is one\n            (AssignOpKind::SubAssign == op1.node && is_integer_literal(value, 1)).then_some(target)\n        },\n        ExprKind::Assign(target, value, _) => {\n            if let ExprKind::Binary(ref op1, left1, right1) = value.kind\n                && BinOpKind::Sub == op1.node\n                && SpanlessEq::new(cx).eq_expr(left1, target)\n                && is_integer_literal(right1, 1)\n            {\n                Some(target)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\nfn print_lint_and_sugg(cx: &LateContext<'_>, var_name: Symbol, expr: &Expr<'_>) {\n    span_lint_and_sugg(\n        cx,\n        IMPLICIT_SATURATING_SUB,\n        expr.span,\n        \"implicitly performing saturating subtraction\",\n        \"try\",\n        format!(\"{var_name} = {var_name}.saturating_sub({});\", '1'),\n        Applicability::MachineApplicable,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/implied_bounds_in_impls.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet;\nuse rustc_errors::{Applicability, SuggestionStyle};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{\n    AmbigArg, AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers,\n    TyKind, WherePredicateKind,\n};\nuse rustc_hir_analysis::lower_ty;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, AssocItem, ClauseKind, Generics, Ty, TyCtxt};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for bounds in `impl Trait` in return position that are implied by other bounds.\n    /// This can happen when a trait is specified that another trait already has as a supertrait\n    /// (e.g. `fn() -> impl Deref + DerefMut<Target = i32>` has an unnecessary `Deref` bound,\n    /// because `Deref` is a supertrait of `DerefMut`)\n    ///\n    /// ### Why is this bad?\n    /// Specifying more bounds than necessary adds needless complexity for the reader.\n    ///\n    /// ### Limitations\n    /// This lint does not check for implied bounds transitively. Meaning that\n    /// it doesn't check for implied bounds from supertraits of supertraits\n    /// (e.g. `trait A {} trait B: A {} trait C: B {}`, then having an `fn() -> impl A + C`)\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::ops::{Deref,DerefMut};\n    /// fn f() -> impl Deref<Target = i32> + DerefMut<Target = i32> {\n    /// //             ^^^^^^^^^^^^^^^^^^^ unnecessary bound, already implied by the `DerefMut` trait bound\n    ///     Box::new(123)\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::ops::{Deref,DerefMut};\n    /// fn f() -> impl DerefMut<Target = i32> {\n    ///     Box::new(123)\n    /// }\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub IMPLIED_BOUNDS_IN_IMPLS,\n    complexity,\n    \"specifying bounds that are implied by other bounds in `impl Trait` type\"\n}\n\ndeclare_lint_pass!(ImpliedBoundsInImpls => [IMPLIED_BOUNDS_IN_IMPLS]);\n\nfn emit_lint(\n    cx: &LateContext<'_>,\n    poly_trait: &rustc_hir::PolyTraitRef<'_>,\n    bounds: GenericBounds<'_>,\n    index: usize,\n    // The constraints that were implied, used for suggestion purposes since removing a bound with\n    // associated types means we might need to then move it to a different bound.\n    implied_constraints: &[AssocItemConstraint<'_>],\n    bound: &ImplTraitBound<'_>,\n) {\n    let implied_by = snippet(cx, bound.span, \"..\");\n\n    span_lint_and_then(\n        cx,\n        IMPLIED_BOUNDS_IN_IMPLS,\n        poly_trait.span,\n        format!(\"this bound is already specified as the supertrait of `{implied_by}`\"),\n        |diag| {\n            // If we suggest removing a bound, we may also need to extend the span\n            // to include the `+` token that is ahead or behind,\n            // so we don't end up with something like `impl + B` or `impl A + `\n\n            let implied_span_extended = if let Some(next_bound) = bounds.get(index + 1) {\n                poly_trait.span.to(next_bound.span().shrink_to_lo())\n            } else if index > 0\n                && let Some(prev_bound) = bounds.get(index - 1)\n            {\n                prev_bound.span().shrink_to_hi().to(poly_trait.span.shrink_to_hi())\n            } else {\n                poly_trait.span\n            };\n\n            let mut sugg = vec![(implied_span_extended, String::new())];\n\n            // We also might need to include associated item constraints that were specified in the implied\n            // bound, but omitted in the implied-by bound:\n            // `fn f() -> impl Deref<Target = u8> + DerefMut`\n            // If we're going to suggest removing `Deref<..>`, we'll need to put `<Target = u8>` on `DerefMut`\n            let omitted_constraints: Vec<_> = implied_constraints\n                .iter()\n                .filter(|constraint| !bound.constraints.iter().any(|c| c.ident == constraint.ident))\n                .collect();\n\n            if !omitted_constraints.is_empty() {\n                // `<>` needs to be added if there aren't yet any generic arguments or constraints\n                let needs_angle_brackets = bound.args.is_empty() && bound.constraints.is_empty();\n                let insert_span = match (bound.args, bound.constraints) {\n                    ([.., arg], [.., constraint]) => arg.span().max(constraint.span).shrink_to_hi(),\n                    ([.., arg], []) => arg.span().shrink_to_hi(),\n                    ([], [.., constraint]) => constraint.span.shrink_to_hi(),\n                    ([], []) => bound.span.shrink_to_hi(),\n                };\n\n                let mut constraints_sugg = if needs_angle_brackets {\n                    \"<\".to_owned()\n                } else {\n                    // If angle brackets aren't needed (i.e., there are already generic arguments or constraints),\n                    // we need to add a comma:\n                    // `impl A<B, C >`\n                    //             ^ if we insert `Assoc=i32` without a comma here, that'd be invalid syntax:\n                    // `impl A<B, C Assoc=i32>`\n                    \", \".to_owned()\n                };\n\n                for (index, constraint) in omitted_constraints.into_iter().enumerate() {\n                    if index > 0 {\n                        constraints_sugg += \", \";\n                    }\n                    constraints_sugg += &snippet(cx, constraint.span, \"..\");\n                }\n                if needs_angle_brackets {\n                    constraints_sugg += \">\";\n                }\n                sugg.push((insert_span, constraints_sugg));\n            }\n\n            diag.multipart_suggestion_with_style(\n                \"try removing this bound\",\n                sugg,\n                Applicability::MachineApplicable,\n                SuggestionStyle::ShowAlways,\n            );\n        },\n    );\n}\n\n/// Tries to \"resolve\" a type.\n/// The index passed to this function must start with `Self=0`, i.e. it must be a valid\n/// type parameter index.\n/// If the index is out of bounds, it means that the generic parameter has a default type.\nfn try_resolve_type<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    args: &'tcx [GenericArg<'tcx>],\n    generics: &'tcx Generics,\n    index: usize,\n) -> Option<Ty<'tcx>> {\n    match args.get(index - 1) {\n        // I don't think we care about `GenericArg::Infer` since this is all for stuff in type signatures\n        // which do not permit inference variables.\n        Some(GenericArg::Type(ty)) => Some(lower_ty(tcx, ty.as_unambig_ty())),\n        Some(_) => None,\n        None => Some(tcx.type_of(generics.own_params[index].def_id).skip_binder()),\n    }\n}\n\n/// This function tries to, for all generic type parameters in a supertrait predicate `trait ...<U>:\n/// GenericTrait<U>`, check if the substituted type in the implied-by bound matches with what's\n/// substituted in the implied bound.\n///\n/// Consider this example.\n/// ```rust,ignore\n/// trait GenericTrait<T> {}\n/// trait GenericSubTrait<T, U, V>: GenericTrait<U> {}\n///                                 ^^^^^^^^^^^^^^^ trait_predicate_args: [Self#0, U#2]\n///                                                 (the Self#0 is implicit: `<Self as GenericTrait<U>>`)\n/// impl GenericTrait<i32> for () {}\n/// impl GenericSubTrait<(), i32, ()> for () {}\n/// impl GenericSubTrait<(), i64, ()> for () {}\n///\n/// fn f() -> impl GenericTrait<i32> + GenericSubTrait<(), i64, ()> {\n///                             ^^^ implied_args       ^^^^^^^^^^^ implied_by_args\n///                                                                (we are interested in `i64` specifically, as that\n///                                                                 is what `U` in `GenericTrait<U>` is substituted with)\n/// }\n/// ```\n/// Here i32 != i64, so this will return false.\nfn is_same_generics<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    trait_predicate_args: &'tcx [ty::GenericArg<'tcx>],\n    implied_by_args: &'tcx [GenericArg<'tcx>],\n    implied_args: &'tcx [GenericArg<'tcx>],\n    implied_by_def_id: DefId,\n    implied_def_id: DefId,\n) -> bool {\n    // Get the generics of the two traits to be able to get default generic parameter.\n    let implied_by_generics = tcx.generics_of(implied_by_def_id);\n    let implied_generics = tcx.generics_of(implied_def_id);\n\n    trait_predicate_args\n        .iter()\n        .enumerate()\n        .skip(1) // skip `Self` implicit arg\n        .all(|(arg_index, arg)| {\n            if let Some(ty) = arg.as_type() {\n                if let &ty::Param(ty::ParamTy { index, .. }) = ty.kind()\n                    // `index == 0` means that it's referring to `Self`,\n                    // in which case we don't try to substitute it\n                    && index != 0\n                    && let Some(ty_a) = try_resolve_type(tcx, implied_by_args, implied_by_generics, index as usize)\n                    && let Some(ty_b) = try_resolve_type(tcx, implied_args, implied_generics, arg_index)\n                {\n                    ty_a == ty_b\n                } else if let Some(ty_b) = try_resolve_type(tcx, implied_args, implied_generics, arg_index) {\n                    ty == ty_b\n                } else {\n                    false\n                }\n            } else {\n                false\n            }\n        })\n}\n\nstruct ImplTraitBound<'tcx> {\n    /// The span of the bound in the `impl Trait` type\n    span: Span,\n    /// The predicates defined in the trait referenced by this bound. This also contains the actual\n    /// supertrait bounds\n    predicates: &'tcx [(ty::Clause<'tcx>, Span)],\n    /// The `DefId` of the trait being referenced by this bound\n    trait_def_id: DefId,\n    /// The generic arguments on the `impl Trait` bound\n    args: &'tcx [GenericArg<'tcx>],\n    /// The associated item constraints of this bound\n    constraints: &'tcx [AssocItemConstraint<'tcx>],\n}\n\n/// Given an `impl Trait` type, gets all the supertraits from each bound (\"implied bounds\").\n///\n/// For `impl Deref + DerefMut + Eq` this returns `[Deref, PartialEq]`.\n/// The `Deref` comes from `DerefMut` because `trait DerefMut: Deref {}`, and `PartialEq` comes from\n/// `Eq`.\nfn collect_supertrait_bounds<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) -> Vec<ImplTraitBound<'tcx>> {\n    bounds\n        .iter()\n        .filter_map(|bound| {\n            if let GenericBound::Trait(poly_trait) = bound\n                && let TraitBoundModifiers::NONE = poly_trait.modifiers\n                && let [.., path] = poly_trait.trait_ref.path.segments\n                && poly_trait.bound_generic_params.is_empty()\n                && let Some(trait_def_id) = path.res.opt_def_id()\n                && let predicates = cx.tcx.explicit_super_predicates_of(trait_def_id).skip_binder()\n                // If the trait has no supertrait, there is no need to collect anything from that bound\n                && !predicates.is_empty()\n            {\n                Some(ImplTraitBound {\n                    span: bound.span(),\n                    predicates,\n                    trait_def_id,\n                    args: path.args.map_or([].as_slice(), |p| p.args),\n                    constraints: path.args.map_or([].as_slice(), |p| p.constraints),\n                })\n            } else {\n                None\n            }\n        })\n        .collect()\n}\n\n/// Given a bound in an `impl Trait` type, looks for a trait in the set of supertraits (previously\n/// collected in [`collect_supertrait_bounds`]) that matches (same trait and generic arguments).\nfn find_bound_in_supertraits<'a, 'tcx>(\n    cx: &LateContext<'tcx>,\n    trait_def_id: DefId,\n    args: &'tcx [GenericArg<'tcx>],\n    bounds: &'a [ImplTraitBound<'tcx>],\n) -> Option<&'a ImplTraitBound<'tcx>> {\n    bounds.iter().find(|bound| {\n        bound.predicates.iter().any(|(clause, _)| {\n            if let ClauseKind::Trait(tr) = clause.kind().skip_binder()\n                && tr.def_id() == trait_def_id\n            {\n                is_same_generics(\n                    cx.tcx,\n                    tr.trait_ref.args,\n                    bound.args,\n                    args,\n                    bound.trait_def_id,\n                    trait_def_id,\n                )\n            } else {\n                false\n            }\n        })\n    })\n}\n\nfn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {\n    if bounds.len() == 1 {\n        // Very often there is only a single bound, e.g. `impl Deref<..>`, in which case\n        // we can avoid doing a bunch of stuff unnecessarily; there will trivially be\n        // no duplicate bounds\n        return;\n    }\n\n    let supertraits = collect_supertrait_bounds(cx, bounds);\n\n    // Lint all bounds in the `impl Trait` type that we've previously also seen in the set of\n    // supertraits of each of the bounds.\n    // This involves some extra logic when generic arguments are present, since\n    // simply comparing trait `DefId`s won't be enough. We also need to compare the generics.\n    for (index, bound) in bounds.iter().enumerate() {\n        if let GenericBound::Trait(poly_trait) = bound\n            && let TraitBoundModifiers::NONE = poly_trait.modifiers\n            && let [.., path] = poly_trait.trait_ref.path.segments\n            && let implied_args = path.args.map_or([].as_slice(), |a| a.args)\n            && let implied_constraints = path.args.map_or([].as_slice(), |a| a.constraints)\n            && let Some(def_id) = poly_trait.trait_ref.path.res.opt_def_id()\n            && let Some(bound) = find_bound_in_supertraits(cx, def_id, implied_args, &supertraits)\n            // If the implied bound has a type binding that also exists in the implied-by trait,\n            // then we shouldn't lint. See #11880 for an example.\n            && let assocs = cx.tcx.associated_items(bound.trait_def_id)\n            && !implied_constraints.iter().any(|constraint| {\n                assocs\n                    .filter_by_name_unhygienic(constraint.ident.name)\n                    .next()\n                    .is_some_and(AssocItem::is_type)\n                })\n        {\n            emit_lint(cx, poly_trait, bounds, index, implied_constraints, bound);\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {\n    fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &rustc_hir::Generics<'tcx>) {\n        for predicate in generics.predicates {\n            if let WherePredicateKind::BoundPredicate(predicate) = predicate.kind\n                // In theory, the origin doesn't really matter,\n                // we *could* also lint on explicit where clauses written out by the user,\n                // not just impl trait desugared ones, but that contradicts with the lint name...\n                && let PredicateOrigin::ImplTrait = predicate.origin\n            {\n                check(cx, predicate.bounds);\n            }\n        }\n    }\n\n    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &rustc_hir::Ty<'tcx, AmbigArg>) {\n        if let TyKind::OpaqueDef(opaque_ty, ..) = ty.kind {\n            check(cx, opaque_ty.bounds);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/incompatible_msrv.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::{is_in_const_context, is_in_test, sym};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, RustcVersion, StabilityLevel, StableSince, find_attr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, TyCtxt};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::def_id::{CrateNum, DefId};\nuse rustc_span::{ExpnKind, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// This lint checks that no function newer than the defined MSRV (minimum\n    /// supported rust version) is used in the crate.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// It would prevent the crate to be actually used with the specified MSRV.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // MSRV of 1.3.0\n    /// use std::thread::sleep;\n    /// use std::time::Duration;\n    ///\n    /// // Sleep was defined in `1.4.0`.\n    /// sleep(Duration::new(1, 0));\n    /// ```\n    ///\n    /// To fix this problem, either increase your MSRV or use another item\n    /// available in your current MSRV.\n    ///\n    /// You can also locally change the MSRV that should be checked by Clippy,\n    /// for example if a feature in your crate (e.g., `modern_compiler`) should\n    /// allow you to use an item:\n    ///\n    /// ```no_run\n    /// //! This crate has a MSRV of 1.3.0, but we also have an optional feature\n    /// //! `sleep_well` which requires at least Rust 1.4.0.\n    ///\n    /// // When the `sleep_well` feature is set, do not warn for functions available\n    /// // in Rust 1.4.0 and below.\n    /// #![cfg_attr(feature = \"sleep_well\", clippy::msrv = \"1.4.0\")]\n    ///\n    /// use std::time::Duration;\n    ///\n    /// #[cfg(feature = \"sleep_well\")]\n    /// fn sleep_for_some_time() {\n    ///     std::thread::sleep(Duration::new(1, 0)); // Will not trigger the lint\n    /// }\n    /// ```\n    ///\n    /// You can also increase the MSRV in tests, by using:\n    ///\n    /// ```no_run\n    /// // Use a much higher MSRV for tests while keeping the main one low\n    /// #![cfg_attr(test, clippy::msrv = \"1.85.0\")]\n    ///\n    /// #[test]\n    /// fn my_test() {\n    ///     // The tests can use items introduced in Rust 1.85.0 and lower\n    ///     // without triggering the `incompatible_msrv` lint.\n    /// }\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub INCOMPATIBLE_MSRV,\n    suspicious,\n    \"ensures that all items used in the crate are available for the current MSRV\"\n}\n\nimpl_lint_pass!(IncompatibleMsrv => [INCOMPATIBLE_MSRV]);\n\n#[derive(Clone, Copy)]\nenum Availability {\n    FeatureEnabled,\n    Since(RustcVersion),\n}\n\n/// All known std crates containing a stability attribute.\nstruct StdCrates([Option<CrateNum>; 6]);\nimpl StdCrates {\n    fn new(tcx: TyCtxt<'_>) -> Self {\n        let mut res = Self([None; _]);\n        for &krate in tcx.crates(()) {\n            // FIXME(@Jarcho): We should have an internal lint to detect when this list is out of date.\n            match tcx.crate_name(krate) {\n                sym::alloc => res.0[0] = Some(krate),\n                sym::core => res.0[1] = Some(krate),\n                sym::core_arch => res.0[2] = Some(krate),\n                sym::proc_macro => res.0[3] = Some(krate),\n                sym::std => res.0[4] = Some(krate),\n                sym::std_detect => res.0[5] = Some(krate),\n                _ => {},\n            }\n        }\n        res\n    }\n\n    fn contains(&self, krate: CrateNum) -> bool {\n        self.0.contains(&Some(krate))\n    }\n}\n\npub struct IncompatibleMsrv {\n    msrv: Msrv,\n    availability_cache: FxHashMap<(DefId, bool), Availability>,\n    check_in_tests: bool,\n    std_crates: StdCrates,\n\n    // The most recently called path. Used to skip checking the path after it's\n    // been checked when visiting the call expression.\n    called_path: Option<HirId>,\n}\n\nimpl IncompatibleMsrv {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        Self {\n            msrv: conf.msrv,\n            availability_cache: FxHashMap::default(),\n            check_in_tests: conf.check_incompatible_msrv_in_tests,\n            std_crates: StdCrates::new(tcx),\n            called_path: None,\n        }\n    }\n\n    /// Returns the availability of `def_id`, whether it is enabled through a feature or\n    /// available since a given version (the default being Rust 1.0.0). `needs_const` requires\n    /// the `const`-stability to be looked up instead of the stability in non-`const` contexts.\n    fn get_def_id_availability(&mut self, tcx: TyCtxt<'_>, def_id: DefId, needs_const: bool) -> Availability {\n        if let Some(availability) = self.availability_cache.get(&(def_id, needs_const)) {\n            return *availability;\n        }\n        let (feature, stability_level) = if needs_const {\n            tcx.lookup_const_stability(def_id)\n                .map(|stability| (stability.feature, stability.level))\n                .unzip()\n        } else {\n            tcx.lookup_stability(def_id)\n                .map(|stability| (stability.feature, stability.level))\n                .unzip()\n        };\n        let version = if feature.is_some_and(|feature| tcx.features().enabled(feature)) {\n            Availability::FeatureEnabled\n        } else if let Some(StableSince::Version(version)) =\n            stability_level.as_ref().and_then(StabilityLevel::stable_since)\n        {\n            Availability::Since(version)\n        } else if needs_const {\n            // Fallback to regular stability\n            self.get_def_id_availability(tcx, def_id, false)\n        } else if let Some(parent_def_id) = tcx.opt_parent(def_id) {\n            self.get_def_id_availability(tcx, parent_def_id, needs_const)\n        } else {\n            Availability::Since(RustcVersion {\n                major: 1,\n                minor: 0,\n                patch: 0,\n            })\n        };\n        self.availability_cache.insert((def_id, needs_const), version);\n        version\n    }\n\n    /// Emit lint if `def_id`, associated with `node` and `span`, is below the current MSRV.\n    fn emit_lint_if_under_msrv(\n        &mut self,\n        cx: &LateContext<'_>,\n        needs_const: bool,\n        def_id: DefId,\n        node: HirId,\n        span: Span,\n    ) {\n        if !self.std_crates.contains(def_id.krate) {\n            // No stability attributes to lookup for these items.\n            return;\n        }\n        // Use `from_expansion` to fast-path the common case.\n        if span.from_expansion() {\n            let expn = span.ctxt().outer_expn_data();\n            match expn.kind {\n                // FIXME(@Jarcho): Check that the actual desugaring or std macro is supported by the\n                // current MSRV. Note that nested expansions need to be handled as well.\n                ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => return,\n                ExpnKind::Macro(..) if expn.macro_def_id.is_some_and(|did| self.std_crates.contains(did.krate)) => {\n                    return;\n                },\n                // All other expansions share the target's MSRV.\n                // FIXME(@Jarcho): What should we do about version dependant macros from external crates?\n                _ => {},\n            }\n        }\n\n        if (self.check_in_tests || !is_in_test(cx.tcx, node))\n            && let Some(current) = self.msrv.current(cx)\n            && let Availability::Since(version) = self.get_def_id_availability(cx.tcx, def_id, needs_const)\n            && version > current\n        {\n            span_lint_and_then(\n                cx,\n                INCOMPATIBLE_MSRV,\n                span,\n                format!(\n                    \"current MSRV (Minimum Supported Rust Version) is `{current}` but this item is stable{} since `{version}`\",\n                    if needs_const { \" in a `const` context\" } else { \"\" },\n                ),\n                |diag| {\n                    if is_under_cfg_attribute(cx, node) {\n                        diag.note_once(\"you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute\");\n                    }\n                },\n            );\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        match expr.kind {\n            ExprKind::MethodCall(_, _, _, span) => {\n                if let Some(method_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {\n                    self.emit_lint_if_under_msrv(cx, is_in_const_context(cx), method_did, expr.hir_id, span);\n                }\n            },\n            ExprKind::Call(callee, _) if let ExprKind::Path(qpath) = callee.kind => {\n                self.called_path = Some(callee.hir_id);\n                let needs_const = is_in_const_context(cx);\n                let def_id = if let Some(def_id) = cx.qpath_res(&qpath, callee.hir_id).opt_def_id() {\n                    def_id\n                } else if needs_const && let ty::FnDef(def_id, _) = *cx.typeck_results().expr_ty(callee).kind() {\n                    // Edge case where a function is first assigned then called.\n                    // We previously would have warned for the non-const MSRV, when\n                    // checking the path, but now that it's called the const MSRV\n                    // must also be met.\n                    def_id\n                } else {\n                    return;\n                };\n                self.emit_lint_if_under_msrv(cx, needs_const, def_id, expr.hir_id, callee.span);\n            },\n            // Desugaring into function calls by the compiler will use `QPath::LangItem` variants. Those should\n            // not be linted as they will not be generated in older compilers if the function is not available,\n            // and the compiler is allowed to call unstable functions.\n            ExprKind::Path(qpath)\n                if let Some(path_def_id) = cx.qpath_res(&qpath, expr.hir_id).opt_def_id()\n                    && self.called_path != Some(expr.hir_id) =>\n            {\n                self.emit_lint_if_under_msrv(cx, false, path_def_id, expr.hir_id, expr.span);\n            },\n            _ => {},\n        }\n    }\n\n    fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &'tcx hir::Ty<'tcx, AmbigArg>) {\n        if let hir::TyKind::Path(qpath) = hir_ty.kind\n            && let Some(ty_def_id) = cx.qpath_res(&qpath, hir_ty.hir_id).opt_def_id()\n            // `CStr` and `CString` have been moved around but have been available since Rust 1.0.0\n            && !matches!(cx.tcx.get_diagnostic_name(ty_def_id), Some(sym::cstr_type | sym::cstring_type))\n        {\n            self.emit_lint_if_under_msrv(cx, false, ty_def_id, hir_ty.hir_id, hir_ty.span);\n        }\n    }\n}\n\n/// Heuristic checking if the node `hir_id` is under a `#[cfg()]` or `#[cfg_attr()]`\n/// attribute.\nfn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool {\n    cx.tcx\n        .hir_parent_id_iter(hir_id)\n        .any(|id| find_attr!(cx.tcx.hir_attrs(id), CfgTrace(..) | CfgAttrTrace))\n}\n"
  },
  {
    "path": "clippy_lints/src/inconsistent_struct_constructor.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::fulfill_or_allowed;\nuse clippy_utils::source::snippet;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for struct constructors where the order of the field\n    /// init in the constructor is inconsistent with the order in the\n    /// struct definition.\n    ///\n    /// ### Why is this bad?\n    /// Since the order of fields in a constructor doesn't affect the\n    /// resulted instance as the below example indicates,\n    ///\n    /// ```no_run\n    /// #[derive(Debug, PartialEq, Eq)]\n    /// struct Foo {\n    ///     x: i32,\n    ///     y: i32,\n    /// }\n    /// let x = 1;\n    /// let y = 2;\n    ///\n    /// // This assertion never fails:\n    /// assert_eq!(Foo { x, y }, Foo { y, x });\n    /// ```\n    ///\n    /// inconsistent order can be confusing and decreases readability and consistency.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo {\n    ///     x: i32,\n    ///     y: i32,\n    /// }\n    /// let x = 1;\n    /// let y = 2;\n    ///\n    /// Foo { y, x };\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # struct Foo {\n    /// #     x: i32,\n    /// #     y: i32,\n    /// # }\n    /// # let x = 1;\n    /// # let y = 2;\n    /// Foo { x, y };\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub INCONSISTENT_STRUCT_CONSTRUCTOR,\n    pedantic,\n    \"the order of the field init is inconsistent with the order in the struct definition\"\n}\n\nimpl_lint_pass!(InconsistentStructConstructor => [\n    INCONSISTENT_STRUCT_CONSTRUCTOR,\n]);\n\npub struct InconsistentStructConstructor {\n    check_inconsistent_struct_field_initializers: bool,\n}\n\nimpl InconsistentStructConstructor {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            check_inconsistent_struct_field_initializers: conf.check_inconsistent_struct_field_initializers,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        let ExprKind::Struct(_, fields, _) = expr.kind else {\n            return;\n        };\n        let all_fields_are_shorthand = fields.iter().all(|f| f.is_shorthand);\n        let applicability = if all_fields_are_shorthand {\n            Applicability::MachineApplicable\n        } else if self.check_inconsistent_struct_field_initializers {\n            Applicability::MaybeIncorrect\n        } else {\n            return;\n        };\n        if !expr.span.from_expansion()\n            && let ty = cx.typeck_results().expr_ty(expr)\n            && let Some(adt_def) = ty.ty_adt_def()\n            && adt_def.is_struct()\n            && let Some(local_def_id) = adt_def.did().as_local()\n            && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id)\n            && let Some(variant) = adt_def.variants().iter().next()\n        {\n            let mut def_order_map = FxHashMap::default();\n            for (idx, field) in variant.fields.iter().enumerate() {\n                def_order_map.insert(field.name, idx);\n            }\n\n            if is_consistent_order(fields, &def_order_map) {\n                return;\n            }\n\n            let span = field_with_attrs_span(cx.tcx, fields.first().unwrap())\n                .with_hi(field_with_attrs_span(cx.tcx, fields.last().unwrap()).hi());\n\n            if !fulfill_or_allowed(cx, INCONSISTENT_STRUCT_CONSTRUCTOR, Some(ty_hir_id)) {\n                span_lint_and_then(\n                    cx,\n                    INCONSISTENT_STRUCT_CONSTRUCTOR,\n                    span,\n                    \"struct constructor field order is inconsistent with struct definition field order\",\n                    |diag| {\n                        let msg = if all_fields_are_shorthand {\n                            \"try\"\n                        } else {\n                            \"if the field evaluation order doesn't matter, try\"\n                        };\n                        let sugg = suggestion(cx, fields, &def_order_map);\n                        diag.span_suggestion(span, msg, sugg, applicability);\n                    },\n                );\n            }\n        }\n    }\n}\n\n// Check whether the order of the fields in the constructor is consistent with the order in the\n// definition.\nfn is_consistent_order<'tcx>(fields: &'tcx [hir::ExprField<'tcx>], def_order_map: &FxHashMap<Symbol, usize>) -> bool {\n    let mut cur_idx = usize::MIN;\n    for f in fields {\n        let next_idx = def_order_map[&f.ident.name];\n        if cur_idx > next_idx {\n            return false;\n        }\n        cur_idx = next_idx;\n    }\n\n    true\n}\n\nfn suggestion<'tcx>(\n    cx: &LateContext<'_>,\n    fields: &'tcx [hir::ExprField<'tcx>],\n    def_order_map: &FxHashMap<Symbol, usize>,\n) -> String {\n    let ws = fields\n        .windows(2)\n        .map(|w| {\n            let w0_span = field_with_attrs_span(cx.tcx, &w[0]);\n            let w1_span = field_with_attrs_span(cx.tcx, &w[1]);\n            let span = w0_span.between(w1_span);\n            snippet(cx, span, \" \")\n        })\n        .collect::<Vec<_>>();\n\n    let mut fields = fields.to_vec();\n    fields.sort_unstable_by_key(|field| def_order_map[&field.ident.name]);\n    let field_snippets = fields\n        .iter()\n        .map(|field| snippet(cx, field_with_attrs_span(cx.tcx, field), \"..\"))\n        .collect::<Vec<_>>();\n\n    assert_eq!(field_snippets.len(), ws.len() + 1);\n\n    let mut sugg = String::new();\n    for i in 0..field_snippets.len() {\n        sugg += &field_snippets[i];\n        if i < ws.len() {\n            sugg += &ws[i];\n        }\n    }\n    sugg\n}\n\nfn field_with_attrs_span(tcx: TyCtxt<'_>, field: &hir::ExprField<'_>) -> Span {\n    if let Some(attr) = tcx.hir_attrs(field.hir_id).first() {\n        field.span.with_lo(attr.span().lo())\n    } else {\n        field.span\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/index_refutable_slice.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::IfLet;\nuse clippy_utils::is_lint_allowed;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::ty::is_copy;\nuse rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::HirId;\nuse rustc_hir::intravisit::{self, Visitor};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::Ident;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// The lint checks for slice bindings in patterns that are only used to\n    /// access individual slice values.\n    ///\n    /// ### Why is this bad?\n    /// Accessing slice values using indices can lead to panics. Using refutable\n    /// patterns can avoid these. Binding to individual values also improves the\n    /// readability as they can be named.\n    ///\n    /// ### Limitations\n    /// This lint currently only checks for immutable access inside `if let`\n    /// patterns.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    ///\n    /// if let Some(slice) = slice {\n    ///     println!(\"{}\", slice[0]);\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    ///\n    /// if let Some(&[first, ..]) = slice {\n    ///     println!(\"{}\", first);\n    /// }\n    /// ```\n    #[clippy::version = \"1.59.0\"]\n    pub INDEX_REFUTABLE_SLICE,\n    pedantic,\n    \"avoid indexing on slices which could be destructed\"\n}\n\nimpl_lint_pass!(IndexRefutableSlice => [INDEX_REFUTABLE_SLICE]);\n\npub struct IndexRefutableSlice {\n    max_suggested_slice: u64,\n    msrv: Msrv,\n}\n\nimpl IndexRefutableSlice {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            max_suggested_slice: conf.max_suggested_slice_pattern_length,\n            msrv: conf.msrv,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        if let Some(IfLet { let_pat, if_then, .. }) = IfLet::hir(cx, expr)\n            && !expr.span.from_expansion()\n            && !is_lint_allowed(cx, INDEX_REFUTABLE_SLICE, expr.hir_id)\n            && let found_slices = find_slice_values(cx, let_pat)\n            && !found_slices.is_empty()\n            && let filtered_slices = filter_lintable_slices(cx, found_slices, self.max_suggested_slice, if_then)\n            && !filtered_slices.is_empty()\n            && self.msrv.meets(cx, msrvs::SLICE_PATTERNS)\n        {\n            for slice in filtered_slices.values() {\n                lint_slice(cx, slice);\n            }\n        }\n    }\n}\n\nfn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<HirId, SliceLintInformation> {\n    let mut removed_pat: FxHashSet<HirId> = FxHashSet::default();\n    let mut slices: FxIndexMap<HirId, SliceLintInformation> = FxIndexMap::default();\n    pat.walk_always(|pat| {\n        // We'll just ignore mut and ref mut for simplicity sake right now\n        if let hir::PatKind::Binding(hir::BindingMode(by_ref, hir::Mutability::Not), value_hir_id, ident, sub_pat) =\n            pat.kind\n            && !matches!(by_ref, hir::ByRef::Yes(_, hir::Mutability::Mut))\n        {\n            // This block catches bindings with sub patterns. It would be hard to build a correct suggestion\n            // for them and it's likely that the user knows what they are doing in such a case.\n            if removed_pat.contains(&value_hir_id) {\n                return;\n            }\n            if sub_pat.is_some() {\n                removed_pat.insert(value_hir_id);\n                // FIXME(rust/#120456) - is `swap_remove` correct?\n                slices.swap_remove(&value_hir_id);\n                return;\n            }\n\n            let bound_ty = cx.typeck_results().node_type(pat.hir_id);\n            if let Some(inner_ty) = bound_ty.peel_refs().builtin_index() {\n                // The values need to use the `ref` keyword if they can't be copied.\n                // This will need to be adjusted if the lint want to support mutable access in the future\n                let src_is_ref = bound_ty.is_ref() && by_ref == hir::ByRef::No;\n                let needs_ref = !(src_is_ref || is_copy(cx, inner_ty));\n\n                let slice_info = slices\n                    .entry(value_hir_id)\n                    .or_insert_with(|| SliceLintInformation::new(ident, needs_ref));\n                slice_info.pattern_spans.push(pat.span);\n            }\n        }\n    });\n\n    slices\n}\n\nfn lint_slice(cx: &LateContext<'_>, slice: &SliceLintInformation) {\n    let used_indices = slice\n        .index_use\n        .iter()\n        .map(|(index, _)| *index)\n        .collect::<FxIndexSet<_>>();\n\n    let value_name = |index| format!(\"{}_{}\", slice.ident.name, index);\n\n    if let Some(max_index) = used_indices.iter().max() {\n        let opt_ref = if slice.needs_ref { \"ref \" } else { \"\" };\n        let pat_sugg_idents = (0..=*max_index)\n            .map(|index| {\n                if used_indices.contains(&index) {\n                    format!(\"{opt_ref}{}\", value_name(index))\n                } else {\n                    \"_\".to_string()\n                }\n            })\n            .collect::<Vec<_>>();\n        let pat_sugg = format!(\"[{}, ..]\", pat_sugg_idents.join(\", \"));\n\n        let mut suggestions = Vec::new();\n\n        // Add the binding pattern suggestion\n        if !slice.pattern_spans.is_empty() {\n            suggestions.extend(slice.pattern_spans.iter().map(|span| (*span, pat_sugg.clone())));\n        }\n\n        // Add the index replacement suggestions\n        if !slice.index_use.is_empty() {\n            suggestions.extend(slice.index_use.iter().map(|(index, span)| (*span, value_name(*index))));\n        }\n\n        span_lint_and_then(\n            cx,\n            INDEX_REFUTABLE_SLICE,\n            slice.ident.span,\n            \"this binding can be a slice pattern to avoid indexing\",\n            |diag| {\n                diag.multipart_suggestion(\n                    \"replace the binding and indexed access with a slice pattern\",\n                    suggestions,\n                    Applicability::MaybeIncorrect,\n                );\n            },\n        );\n    }\n}\n\n#[derive(Debug)]\nstruct SliceLintInformation {\n    ident: Ident,\n    needs_ref: bool,\n    pattern_spans: Vec<Span>,\n    index_use: Vec<(u64, Span)>,\n}\n\nimpl SliceLintInformation {\n    fn new(ident: Ident, needs_ref: bool) -> Self {\n        Self {\n            ident,\n            needs_ref,\n            pattern_spans: Vec::new(),\n            index_use: Vec::new(),\n        }\n    }\n}\n\nfn filter_lintable_slices<'tcx>(\n    cx: &LateContext<'tcx>,\n    slice_lint_info: FxIndexMap<HirId, SliceLintInformation>,\n    max_suggested_slice: u64,\n    scope: &'tcx hir::Expr<'tcx>,\n) -> FxIndexMap<HirId, SliceLintInformation> {\n    let mut visitor = SliceIndexLintingVisitor {\n        cx,\n        slice_lint_info,\n        max_suggested_slice,\n    };\n\n    intravisit::walk_expr(&mut visitor, scope);\n\n    visitor.slice_lint_info\n}\n\nstruct SliceIndexLintingVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    slice_lint_info: FxIndexMap<HirId, SliceLintInformation>,\n    max_suggested_slice: u64,\n}\n\nimpl<'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {\n        if let Some(local_id) = expr.res_local_id() {\n            let Self {\n                cx,\n                ref mut slice_lint_info,\n                max_suggested_slice,\n            } = *self;\n\n            if let Some(use_info) = slice_lint_info.get_mut(&local_id)\n                // Checking for slice indexing\n                && let parent_id = cx.tcx.parent_hir_id(expr.hir_id)\n                && let hir::Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id)\n                && let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind\n                && let Some(Constant::Int(index_value)) = ConstEvalCtxt::new(cx).eval(index_expr)\n                && let Ok(index_value) = index_value.try_into()\n                && index_value < max_suggested_slice\n\n                // Make sure that this slice index is read only\n                && let hir::Node::Expr(maybe_addrof_expr) = cx.tcx.parent_hir_node(parent_id)\n                && let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind\n            {\n                use_info\n                    .index_use\n                    .push((index_value, cx.tcx.hir_span(parent_expr.hir_id)));\n                return;\n            }\n\n            // The slice was used for something other than indexing\n            // FIXME(rust/#120456) - is `swap_remove` correct?\n            self.slice_lint_info.swap_remove(&local_id);\n        }\n        intravisit::walk_expr(self, expr);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/indexing_slicing.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::ty::{deref_chain, get_adt_inherent_method};\nuse clippy_utils::{higher, is_from_proc_macro, is_in_test, sym};\nuse rustc_ast::ast::RangeLimits;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of indexing or slicing that may panic at runtime.\n    ///\n    /// This lint does not report on indexing or slicing operations\n    /// that always panic, [out_of_bounds_indexing](#out_of_bounds_indexing) already\n    /// handles those cases.\n    ///\n    /// ### Why restrict this?\n    /// To avoid implicit panics from indexing and slicing.\n    ///\n    /// There are “checked” alternatives which do not panic, and can be used with `unwrap()` to make\n    /// an explicit panic when it is desired.\n    ///\n    /// ### Limitations\n    /// This lint does not check for the usage of indexing or slicing on strings. These are covered\n    /// by the more specific `string_slice` lint.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// // Vector\n    /// let x = vec![0, 1, 2, 3];\n    ///\n    /// x[2];\n    /// x[100];\n    /// &x[2..100];\n    ///\n    /// // Array\n    /// let y = [0, 1, 2, 3];\n    ///\n    /// let i = 10; // Could be a runtime value\n    /// let j = 20;\n    /// &y[i..j];\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = vec![0, 1, 2, 3];\n    /// x.get(2);\n    /// x.get(100);\n    /// x.get(2..100);\n    ///\n    /// # let y = [0, 1, 2, 3];\n    /// let i = 10;\n    /// let j = 20;\n    /// y.get(i..j);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INDEXING_SLICING,\n    restriction,\n    \"indexing/slicing usage\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for out of bounds array indexing with a constant\n    /// index.\n    ///\n    /// ### Why is this bad?\n    /// This will always panic at runtime.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// let x = [1, 2, 3, 4];\n    ///\n    /// x[9];\n    /// &x[2..9];\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = [1, 2, 3, 4];\n    /// // Index within bounds\n    ///\n    /// x[0];\n    /// x[3];\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub OUT_OF_BOUNDS_INDEXING,\n    correctness,\n    \"out of bounds constant indexing\"\n}\n\nimpl_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING]);\n\npub struct IndexingSlicing {\n    allow_indexing_slicing_in_tests: bool,\n    suppress_restriction_lint_in_const: bool,\n}\n\nimpl IndexingSlicing {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            allow_indexing_slicing_in_tests: conf.allow_indexing_slicing_in_tests,\n            suppress_restriction_lint_in_const: conf.suppress_restriction_lint_in_const,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for IndexingSlicing {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Index(array, index, _) = &expr.kind\n            && (!self.suppress_restriction_lint_in_const || !cx.tcx.hir_is_inside_const_context(expr.hir_id))\n            && let expr_ty = cx.typeck_results().expr_ty(array)\n            && let mut deref = deref_chain(cx, expr_ty)\n            && deref.any(|l| {\n                l.peel_refs().is_slice()\n                    || l.peel_refs().is_array()\n                    || ty_has_applicable_get_function(cx, l.peel_refs(), expr_ty, expr)\n            })\n            && !is_from_proc_macro(cx, expr)\n        {\n            let note = \"the suggestion might not be applicable in constant blocks\";\n            let ty = cx.typeck_results().expr_ty(array).peel_refs();\n            let allowed_in_tests = self.allow_indexing_slicing_in_tests && is_in_test(cx.tcx, expr.hir_id);\n            if let Some(range) = higher::Range::hir(cx, index) {\n                // Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]\n                if let ty::Array(_, s) = ty.kind() {\n                    let size: u128 = if let Some(size) = s.try_to_target_usize(cx.tcx) {\n                        size.into()\n                    } else {\n                        return;\n                    };\n\n                    let const_range = to_const_range(cx, range, size);\n\n                    if let (Some(start), _) = const_range\n                        && start > size\n                    {\n                        span_lint(\n                            cx,\n                            OUT_OF_BOUNDS_INDEXING,\n                            range.start.map_or(expr.span, |start| start.span),\n                            \"range is out of bounds\",\n                        );\n                        return;\n                    }\n\n                    if let (_, Some(end)) = const_range\n                        && end > size\n                    {\n                        span_lint(\n                            cx,\n                            OUT_OF_BOUNDS_INDEXING,\n                            range.end.map_or(expr.span, |end| end.span),\n                            \"range is out of bounds\",\n                        );\n                        return;\n                    }\n\n                    if let (Some(_), Some(_)) = const_range {\n                        // early return because both start and end are constants\n                        // and we have proven above that they are in bounds\n                        return;\n                    }\n                }\n\n                let help_msg = match (range.start, range.end) {\n                    (None, Some(_)) => \"consider using `.get(..n)`or `.get_mut(..n)` instead\",\n                    (Some(_), None) => \"consider using `.get(n..)` or .get_mut(n..)` instead\",\n                    (Some(_), Some(_)) => \"consider using `.get(n..m)` or `.get_mut(n..m)` instead\",\n                    (None, None) => return, // [..] is ok.\n                };\n\n                if allowed_in_tests {\n                    return;\n                }\n\n                span_lint_and_then(cx, INDEXING_SLICING, expr.span, \"slicing may panic\", |diag| {\n                    diag.help(help_msg);\n\n                    if cx.tcx.hir_is_inside_const_context(expr.hir_id) {\n                        diag.note(note);\n                    }\n                });\n            } else {\n                // Catchall non-range index, i.e., [n] or [n << m]\n                if let ty::Array(..) = ty.kind() {\n                    // Index is a const block.\n                    if let ExprKind::ConstBlock(..) = index.kind {\n                        return;\n                    }\n                    // Index is a constant uint.\n                    if let Some(constant) = ConstEvalCtxt::new(cx).eval(index) {\n                        // only `usize` index is legal in rust array index\n                        // leave other type to rustc\n                        if let Constant::Int(off) = constant\n                            && off <= usize::MAX as u128\n                            && let ty::Uint(utype) = cx.typeck_results().expr_ty(index).kind()\n                            && *utype == ty::UintTy::Usize\n                            && let ty::Array(_, s) = ty.kind()\n                            && let Some(size) = s.try_to_target_usize(cx.tcx)\n                        {\n                            // get constant offset and check whether it is in bounds\n                            let off = usize::try_from(off).unwrap();\n                            let size = usize::try_from(size).unwrap();\n\n                            if off >= size {\n                                span_lint(cx, OUT_OF_BOUNDS_INDEXING, expr.span, \"index is out of bounds\");\n                            }\n                        }\n                        // Let rustc's `const_err` lint handle constant `usize` indexing on arrays.\n                        return;\n                    }\n                }\n\n                if allowed_in_tests {\n                    return;\n                }\n\n                span_lint_and_then(cx, INDEXING_SLICING, expr.span, \"indexing may panic\", |diag| {\n                    diag.help(\"consider using `.get(n)` or `.get_mut(n)` instead\");\n\n                    if cx.tcx.hir_is_inside_const_context(expr.hir_id) {\n                        diag.note(note);\n                    }\n                });\n            }\n        }\n    }\n}\n\n/// Returns a tuple of options with the start and end (exclusive) values of\n/// the range. If the start or end is not constant, None is returned.\nfn to_const_range(cx: &LateContext<'_>, range: higher::Range<'_>, array_size: u128) -> (Option<u128>, Option<u128>) {\n    let ecx = ConstEvalCtxt::new(cx);\n    let s = range.start.map(|expr| ecx.eval(expr));\n    let start = match s {\n        Some(Some(Constant::Int(x))) => Some(x),\n        Some(_) => None,\n        None => Some(0),\n    };\n\n    let e = range.end.map(|expr| ecx.eval(expr));\n    let end = match e {\n        Some(Some(Constant::Int(x))) => {\n            if range.limits == RangeLimits::Closed {\n                Some(x + 1)\n            } else {\n                Some(x)\n            }\n        },\n        Some(_) => None,\n        None => Some(array_size),\n    };\n\n    (start, end)\n}\n\n/// Checks if the output Ty of the `get` method on this Ty (if any) matches the Ty returned by the\n/// indexing operation (if any).\nfn ty_has_applicable_get_function<'tcx>(\n    cx: &LateContext<'tcx>,\n    ty: Ty<'tcx>,\n    array_ty: Ty<'tcx>,\n    index_expr: &Expr<'_>,\n) -> bool {\n    if let ty::Adt(_, _) = array_ty.kind()\n        && let Some(get_output_ty) = get_adt_inherent_method(cx, ty, sym::get).map(|m| {\n            cx.tcx\n                .fn_sig(m.def_id)\n                .skip_binder()\n                .output()\n                .skip_binder()\n        })\n        && let ty::Adt(def, args) = get_output_ty.kind()\n        && cx.tcx.is_diagnostic_item(sym::Option, def.0.did)\n        && let Some(option_generic_param) = args.first()\n        && let generic_ty = option_generic_param.expect_ty().peel_refs()\n        // FIXME: ideally this would handle type params and projections properly, for now just assume it's the same type\n        && (cx.typeck_results().expr_ty(index_expr).peel_refs() == generic_ty.peel_refs()\n            || matches!(generic_ty.peel_refs().kind(), ty::Param(_) | ty::Alias(_, _)))\n    {\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ineffective_open_options.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{peel_blocks, peel_hir_expr_while, sym};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if both `.write(true)` and `.append(true)` methods are called\n    /// on a same `OpenOptions`.\n    ///\n    /// ### Why is this bad?\n    /// `.append(true)` already enables `write(true)`, making this one\n    /// superfluous.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::fs::OpenOptions;\n    /// let _ = OpenOptions::new()\n    ///            .write(true)\n    ///            .append(true)\n    ///            .create(true)\n    ///            .open(\"file.json\");\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::fs::OpenOptions;\n    /// let _ = OpenOptions::new()\n    ///            .append(true)\n    ///            .create(true)\n    ///            .open(\"file.json\");\n    /// ```\n    #[clippy::version = \"1.76.0\"]\n    pub INEFFECTIVE_OPEN_OPTIONS,\n    suspicious,\n    \"usage of both `write(true)` and `append(true)` on same `OpenOptions`\"\n}\n\ndeclare_lint_pass!(IneffectiveOpenOptions => [INEFFECTIVE_OPEN_OPTIONS]);\n\nimpl<'tcx> LateLintPass<'tcx> for IneffectiveOpenOptions {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::MethodCall(name, recv, [_], _) = expr.kind\n            && name.ident.name == sym::open\n            && !expr.span.from_expansion()\n            && cx\n                .typeck_results()\n                .expr_ty(recv)\n                .peel_refs()\n                .is_diag_item(cx, sym::FsOpenOptions)\n        {\n            let mut append = false;\n            let mut write = None;\n            peel_hir_expr_while(recv, |e| {\n                if let ExprKind::MethodCall(name, recv, args, call_span) = e.kind\n                    && !e.span.from_expansion()\n                {\n                    if let [arg] = args\n                        && let ExprKind::Lit(lit) = peel_blocks(arg).kind\n                        && matches!(lit.node, LitKind::Bool(true))\n                        && !arg.span.from_expansion()\n                        && !lit.span.from_expansion()\n                    {\n                        match name.ident.name {\n                            sym::append => append = true,\n                            sym::write\n                                if let Some(range) = call_span.map_range(cx, |_, text, range| {\n                                    if text.get(..range.start)?.ends_with('.') {\n                                        Some(range.start - 1..range.end)\n                                    } else {\n                                        None\n                                    }\n                                }) =>\n                            {\n                                write = Some(call_span.with_lo(range.start));\n                            },\n                            _ => {},\n                        }\n                    }\n                    Some(recv)\n                } else {\n                    None\n                }\n            });\n\n            if append && let Some(write_span) = write {\n                span_lint_and_sugg(\n                    cx,\n                    INEFFECTIVE_OPEN_OPTIONS,\n                    write_span,\n                    \"unnecessary use of `.write(true)` because there is `.append(true)`\",\n                    \"remove `.write(true)`\",\n                    String::new(),\n                    Applicability::MachineApplicable,\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/infallible_try_from.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::sym;\nuse rustc_errors::MultiSpan;\nuse rustc_hir::{Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::AssocTag;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Finds manual impls of `TryFrom` with infallible error types.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Infallible conversions should be implemented via `From` with the blanket conversion.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::convert::Infallible;\n    /// struct MyStruct(i16);\n    /// impl TryFrom<i16> for MyStruct {\n    ///     type Error = Infallible;\n    ///     fn try_from(other: i16) -> Result<Self, Infallible> {\n    ///         Ok(Self(other.into()))\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct MyStruct(i16);\n    /// impl From<i16> for MyStruct {\n    ///     fn from(other: i16) -> Self {\n    ///         Self(other)\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.89.0\"]\n    pub INFALLIBLE_TRY_FROM,\n    suspicious,\n    \"TryFrom with infallible Error type\"\n}\n\ndeclare_lint_pass!(InfallibleTryFrom => [INFALLIBLE_TRY_FROM]);\n\nimpl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        let ItemKind::Impl(imp) = item.kind else { return };\n        let Some(of_trait) = imp.of_trait else { return };\n        let Some(trait_def_id) = of_trait.trait_ref.trait_def_id() else {\n            return;\n        };\n        if !cx.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) {\n            return;\n        }\n        for ii in cx\n            .tcx\n            .associated_items(item.owner_id.def_id)\n            .filter_by_name_unhygienic_and_kind(sym::Error, AssocTag::Type)\n        {\n            let ii_ty = cx.tcx.type_of(ii.def_id).instantiate_identity();\n            if !ii_ty.is_inhabited_from(cx.tcx, ii.def_id, cx.typing_env()) {\n                let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id()));\n                let ii_ty_span = cx\n                    .tcx\n                    .hir_node_by_def_id(ii.def_id.expect_local())\n                    .expect_impl_item()\n                    .expect_type()\n                    .span;\n                span.push_span_label(ii_ty_span, \"infallible error type\");\n                span_lint(\n                    cx,\n                    INFALLIBLE_TRY_FROM,\n                    span,\n                    \"infallible TryFrom impl; consider implementing From instead\",\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/infinite_iter.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{higher, sym};\nuse rustc_hir::{BorrowKind, Closure, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for iteration that is guaranteed to be infinite.\n    ///\n    /// ### Why is this bad?\n    /// While there may be places where this is acceptable\n    /// (e.g., in event streams), in most cases this is simply an error.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::iter;\n    ///\n    /// iter::repeat(1_u8).collect::<Vec<_>>();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INFINITE_ITER,\n    correctness,\n    \"infinite iteration\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for iteration that may be infinite.\n    ///\n    /// ### Why is this bad?\n    /// While there may be places where this is acceptable\n    /// (e.g., in event streams), in most cases this is simply an error.\n    ///\n    /// ### Known problems\n    /// The code may have a condition to stop iteration, but\n    /// this lint is not clever enough to analyze it.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let infinite_iter = 0..;\n    /// [0..].iter().zip(infinite_iter.take_while(|x| *x > 5));\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MAYBE_INFINITE_ITER,\n    pedantic,\n    \"possible infinite iteration\"\n}\n\ndeclare_lint_pass!(InfiniteIter => [INFINITE_ITER, MAYBE_INFINITE_ITER]);\n\nimpl<'tcx> LateLintPass<'tcx> for InfiniteIter {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let (lint, msg) = match complete_infinite_iter(cx, expr) {\n            Infinite => (INFINITE_ITER, \"infinite iteration detected\"),\n            MaybeInfinite => (MAYBE_INFINITE_ITER, \"possible infinite iteration detected\"),\n            Finite => {\n                return;\n            },\n        };\n        span_lint(cx, lint, expr.span, msg);\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\nenum Finiteness {\n    Infinite,\n    MaybeInfinite,\n    Finite,\n}\n\nuse self::Finiteness::{Finite, Infinite, MaybeInfinite};\n\nimpl Finiteness {\n    #[must_use]\n    fn and(self, b: Self) -> Self {\n        match (self, b) {\n            (Finite, _) | (_, Finite) => Finite,\n            (MaybeInfinite, _) | (_, MaybeInfinite) => MaybeInfinite,\n            _ => Infinite,\n        }\n    }\n\n    #[must_use]\n    fn or(self, b: Self) -> Self {\n        match (self, b) {\n            (Infinite, _) | (_, Infinite) => Infinite,\n            (MaybeInfinite, _) | (_, MaybeInfinite) => MaybeInfinite,\n            _ => Finite,\n        }\n    }\n}\n\nimpl From<bool> for Finiteness {\n    fn from(b: bool) -> Self {\n        if b { Infinite } else { Finite }\n    }\n}\n\n/// This tells us what to look for to know if the iterator returned by\n/// this method is infinite\n#[derive(Copy, Clone)]\nenum Heuristic {\n    /// infinite no matter what\n    Always,\n    /// infinite if the first argument is\n    First,\n    /// infinite if any of the supplied arguments is\n    Any,\n    /// infinite if all of the supplied arguments are\n    All,\n}\n\nuse self::Heuristic::{All, Always, Any, First};\n\n/// a slice of (method name, number of args, heuristic, bounds) tuples\n/// that will be used to determine whether the method in question\n/// returns an infinite or possibly infinite iterator. The finiteness\n/// is an upper bound, e.g., some methods can return a possibly\n/// infinite iterator at worst, e.g., `take_while`.\nconst HEURISTICS: [(Symbol, usize, Heuristic, Finiteness); 19] = [\n    (sym::zip, 1, All, Infinite),\n    (sym::chain, 1, Any, Infinite),\n    (sym::cycle, 0, Always, Infinite),\n    (sym::map, 1, First, Infinite),\n    (sym::by_ref, 0, First, Infinite),\n    (sym::cloned, 0, First, Infinite),\n    (sym::rev, 0, First, Infinite),\n    (sym::inspect, 0, First, Infinite),\n    (sym::enumerate, 0, First, Infinite),\n    (sym::peekable, 1, First, Infinite),\n    (sym::fuse, 0, First, Infinite),\n    (sym::skip, 1, First, Infinite),\n    (sym::skip_while, 0, First, Infinite),\n    (sym::filter, 1, First, Infinite),\n    (sym::filter_map, 1, First, Infinite),\n    (sym::flat_map, 1, First, Infinite),\n    (sym::unzip, 0, First, Infinite),\n    (sym::take_while, 1, First, MaybeInfinite),\n    (sym::scan, 2, First, MaybeInfinite),\n];\n\nfn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {\n    match expr.kind {\n        ExprKind::MethodCall(method, receiver, args, _) => {\n            for &(name, len, heuristic, cap) in &HEURISTICS {\n                if method.ident.name == name && args.len() == len {\n                    return (match heuristic {\n                        Always => Infinite,\n                        First => is_infinite(cx, receiver),\n                        Any => is_infinite(cx, receiver).or(is_infinite(cx, &args[0])),\n                        All => is_infinite(cx, receiver).and(is_infinite(cx, &args[0])),\n                    })\n                    .and(cap);\n                }\n            }\n            if method.ident.name == sym::flat_map\n                && args.len() == 1\n                && let ExprKind::Closure(&Closure { body, .. }) = args[0].kind\n            {\n                let body = cx.tcx.hir_body(body);\n                return is_infinite(cx, body.value);\n            }\n            Finite\n        },\n        ExprKind::Block(block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)),\n        ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e),\n        ExprKind::Call(path, _) => {\n            if let ExprKind::Path(ref qpath) = path.kind {\n                cx.qpath_res(qpath, path.hir_id)\n                    .opt_def_id()\n                    .is_some_and(|id| cx.tcx.is_diagnostic_item(sym::iter_repeat, id))\n                    .into()\n            } else {\n                Finite\n            }\n        },\n        ExprKind::Struct(..) => higher::Range::hir(cx, expr).is_some_and(|r| r.end.is_none()).into(),\n        _ => Finite,\n    }\n}\n\n/// the names and argument lengths of methods that *may* exhaust their\n/// iterators\nconst POSSIBLY_COMPLETING_METHODS: [(Symbol, usize); 6] = [\n    (sym::find, 1),\n    (sym::rfind, 1),\n    (sym::position, 1),\n    (sym::rposition, 1),\n    (sym::any, 1),\n    (sym::all, 1),\n];\n\n/// the names and argument lengths of methods that *always* exhaust\n/// their iterators\nconst COMPLETING_METHODS: [(Symbol, usize); 12] = [\n    (sym::count, 0),\n    (sym::fold, 2),\n    (sym::for_each, 1),\n    (sym::partition, 1),\n    (sym::max, 0),\n    (sym::max_by, 1),\n    (sym::max_by_key, 1),\n    (sym::min, 0),\n    (sym::min_by, 1),\n    (sym::min_by_key, 1),\n    (sym::sum, 0),\n    (sym::product, 0),\n];\n\nfn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {\n    match expr.kind {\n        ExprKind::MethodCall(method, receiver, args, _) => {\n            let method_str = method.ident.name;\n            for &(name, len) in &COMPLETING_METHODS {\n                if method_str == name && args.len() == len {\n                    return is_infinite(cx, receiver);\n                }\n            }\n            for &(name, len) in &POSSIBLY_COMPLETING_METHODS {\n                if method_str == name && args.len() == len {\n                    return MaybeInfinite.and(is_infinite(cx, receiver));\n                }\n            }\n            if method.ident.name == sym::last && args.is_empty() {\n                let not_double_ended = cx\n                    .tcx\n                    .get_diagnostic_item(sym::DoubleEndedIterator)\n                    .is_some_and(|id| !implements_trait(cx, cx.typeck_results().expr_ty(receiver), id, &[]));\n                if not_double_ended {\n                    return is_infinite(cx, receiver);\n                }\n            } else if method.ident.name == sym::collect {\n                let ty = cx.typeck_results().expr_ty(expr);\n                if matches!(\n                    ty.opt_diag_name(cx),\n                    Some(\n                        sym::BinaryHeap\n                            | sym::BTreeMap\n                            | sym::BTreeSet\n                            | sym::HashMap\n                            | sym::HashSet\n                            | sym::LinkedList\n                            | sym::Vec\n                            | sym::VecDeque,\n                    )\n                ) {\n                    return is_infinite(cx, receiver);\n                }\n            }\n        },\n        ExprKind::Binary(op, l, r) if op.node.is_comparison() => {\n            return is_infinite(cx, l).and(is_infinite(cx, r)).and(MaybeInfinite);\n        }, // TODO: ExprKind::Loop + Match\n        _ => (),\n    }\n    Finite\n}\n"
  },
  {
    "path": "clippy_lints/src/inherent_impl.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::InherentImplLintScope;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::{fulfill_or_allowed, is_cfg_test, is_in_cfg_test};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::def_id::{LocalDefId, LocalModDefId};\nuse rustc_hir::{Item, ItemKind, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{FileName, Span};\nuse std::collections::hash_map::Entry;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for multiple inherent implementations of a struct\n    ///\n    /// The config option controls the scope in which multiple inherent `impl` blocks for the same\n    /// struct are linted, allowing values of `module` (only within the same module), `file`\n    /// (within the same file), or `crate` (anywhere in the crate, default).\n    ///\n    /// ### Why restrict this?\n    /// Splitting the implementation of a type makes the code harder to navigate.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct X;\n    /// impl X {\n    ///     fn one() {}\n    /// }\n    /// impl X {\n    ///     fn other() {}\n    /// }\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// struct X;\n    /// impl X {\n    ///     fn one() {}\n    ///     fn other() {}\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MULTIPLE_INHERENT_IMPL,\n    restriction,\n    \"Multiple inherent impl that could be grouped\"\n}\n\nimpl_lint_pass!(MultipleInherentImpl => [MULTIPLE_INHERENT_IMPL]);\n\npub struct MultipleInherentImpl {\n    scope: InherentImplLintScope,\n}\n\nimpl MultipleInherentImpl {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            scope: conf.inherent_impl_lint_scope,\n        }\n    }\n}\n\n#[derive(Hash, Eq, PartialEq, Clone)]\nenum Criterion {\n    Module(LocalModDefId),\n    File(FileName),\n    Crate,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        // Map from a type to it's first impl block. Needed to distinguish generic arguments.\n        // e.g. `Foo<Bar>` and `Foo<Baz>`\n        let mut type_map = FxHashMap::default();\n        // List of spans to lint. (lint_span, first_span)\n        let mut lint_spans = Vec::new();\n\n        let (impls, _) = cx.tcx.crate_inherent_impls(());\n\n        for (&id, impl_ids) in &impls.inherent_impls {\n            if impl_ids.len() < 2\n            // Check for `#[expect]` or `#[allow]` on the type definition\n            || fulfill_or_allowed(\n                cx,\n                MULTIPLE_INHERENT_IMPL,\n                [cx.tcx.local_def_id_to_hir_id(id)],\n            ) {\n                continue;\n            }\n\n            for impl_id in impl_ids.iter().map(|id| id.expect_local()) {\n                let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity();\n                let hir_id = cx.tcx.local_def_id_to_hir_id(impl_id);\n                let criterion = match self.scope {\n                    InherentImplLintScope::Module => Criterion::Module(cx.tcx.parent_module(hir_id)),\n                    InherentImplLintScope::File => {\n                        let span = cx.tcx.hir_span(hir_id);\n                        Criterion::File(cx.tcx.sess.source_map().lookup_source_file(span.lo()).name.clone())\n                    },\n                    InherentImplLintScope::Crate => Criterion::Crate,\n                };\n                let is_test = is_cfg_test(cx.tcx, hir_id) || is_in_cfg_test(cx.tcx, hir_id);\n                let predicates = {\n                    // Gets the predicates (bounds) for the given impl block,\n                    // sorted for consistent comparison to allow distinguishing between impl blocks\n                    // with different generic bounds.\n                    let mut predicates = cx\n                        .tcx\n                        .predicates_of(impl_id)\n                        .predicates\n                        .iter()\n                        .map(|(clause, _)| *clause)\n                        .collect::<Vec<_>>();\n                    predicates.sort_by_key(|c| format!(\"{c:?}\"));\n                    predicates\n                };\n                match type_map.entry((impl_ty, predicates, criterion, is_test)) {\n                    Entry::Vacant(e) => {\n                        // Store the id for the first impl block of this type. The span is retrieved lazily.\n                        e.insert(IdOrSpan::Id(impl_id));\n                    },\n                    Entry::Occupied(mut e) => {\n                        if let Some(span) = get_impl_span(cx, impl_id) {\n                            let first_span = match *e.get() {\n                                IdOrSpan::Span(s) => s,\n                                IdOrSpan::Id(id) => {\n                                    if let Some(s) = get_impl_span(cx, id) {\n                                        // Remember the span of the first block.\n                                        *e.get_mut() = IdOrSpan::Span(s);\n                                        s\n                                    } else {\n                                        // The first impl block isn't considered by the lint. Replace it with the\n                                        // current one.\n                                        *e.get_mut() = IdOrSpan::Span(span);\n                                        continue;\n                                    }\n                                },\n                            };\n                            lint_spans.push((span, first_span));\n                        }\n                    },\n                }\n            }\n\n            // Switching to the next type definition, no need to keep the current entries around.\n            type_map.clear();\n        }\n        // `TyCtxt::crate_inherent_impls` doesn't have a defined order. Sort the lint output first.\n        lint_spans.sort_by_key(|x| x.0.lo());\n        for (span, first_span) in lint_spans {\n            span_lint_and_then(\n                cx,\n                MULTIPLE_INHERENT_IMPL,\n                span,\n                \"multiple implementations of this structure\",\n                |diag| {\n                    diag.span_note(first_span, \"first implementation here\");\n                },\n            );\n        }\n    }\n}\n\n/// Gets the span for the given impl block unless it's not being considered by the lint.\nfn get_impl_span(cx: &LateContext<'_>, id: LocalDefId) -> Option<Span> {\n    let id = cx.tcx.local_def_id_to_hir_id(id);\n    if let Node::Item(&Item {\n        kind: ItemKind::Impl(_),\n        span,\n        ..\n    }) = cx.tcx.hir_node(id)\n    {\n        (!span.from_expansion() && !fulfill_or_allowed(cx, MULTIPLE_INHERENT_IMPL, [id])).then_some(span)\n    } else {\n        None\n    }\n}\n\nenum IdOrSpan {\n    Id(LocalDefId),\n    Span(Span),\n}\n"
  },
  {
    "path": "clippy_lints/src/inherent_to_string.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{return_ty, trait_ref_of_method};\nuse rustc_abi::ExternAbi;\nuse rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`.\n    ///\n    /// ### Why is this bad?\n    /// This method is also implicitly defined if a type implements the `Display` trait. As the functionality of `Display` is much more versatile, it should be preferred.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub struct A;\n    ///\n    /// impl A {\n    ///     pub fn to_string(&self) -> String {\n    ///         \"I am A\".to_string()\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// use std::fmt;\n    ///\n    /// pub struct A;\n    ///\n    /// impl fmt::Display for A {\n    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n    ///         write!(f, \"I am A\")\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.38.0\"]\n    pub INHERENT_TO_STRING,\n    style,\n    \"type implements inherent method `to_string()`, but should instead implement the `Display` trait\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// 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.\n    ///\n    /// ### Why is this bad?\n    /// This method is also implicitly defined if a type implements the `Display` trait. The less versatile inherent method will then shadow the implementation introduced by `Display`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::fmt;\n    ///\n    /// pub struct A;\n    ///\n    /// impl A {\n    ///     pub fn to_string(&self) -> String {\n    ///         \"I am A\".to_string()\n    ///     }\n    /// }\n    ///\n    /// impl fmt::Display for A {\n    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n    ///         write!(f, \"I am A, too\")\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// use std::fmt;\n    ///\n    /// pub struct A;\n    ///\n    /// impl fmt::Display for A {\n    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n    ///         write!(f, \"I am A\")\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.38.0\"]\n    pub INHERENT_TO_STRING_SHADOW_DISPLAY,\n    correctness,\n    \"type implements inherent method `to_string()`, which gets shadowed by the implementation of the `Display` trait\"\n}\n\ndeclare_lint_pass!(InherentToString => [\n    INHERENT_TO_STRING,\n    INHERENT_TO_STRING_SHADOW_DISPLAY,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for InherentToString {\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {\n        // Check if item is a method called `to_string` and has a parameter 'self'\n        if let ImplItemKind::Fn(ref signature, _) = impl_item.kind\n            // #11201\n            && let header = signature.header\n            && header.is_safe()\n            && header.abi == ExternAbi::Rust\n            && impl_item.ident.name == sym::to_string\n            && let decl = signature.decl\n            && decl.implicit_self.has_implicit_self()\n            && decl.inputs.len() == 1\n            && impl_item.generics.params.iter().all(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))\n            && !impl_item.span.from_expansion()\n            // Check if return type is String\n            && return_ty(cx, impl_item.owner_id).is_lang_item(cx, LangItem::String)\n            // Filters instances of to_string which are required by a trait\n            && trait_ref_of_method(cx, impl_item.owner_id).is_none()\n        {\n            show_lint(cx, impl_item);\n        }\n    }\n}\n\nfn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) {\n    let display_trait_id = cx\n        .tcx\n        .get_diagnostic_item(sym::Display)\n        .expect(\"Failed to get trait ID of `Display`!\");\n\n    // Get the real type of 'self'\n    let self_type = cx.tcx.fn_sig(item.owner_id).skip_binder().input(0);\n    let self_type = self_type.skip_binder().peel_refs();\n\n    // Emit either a warning or an error\n    if implements_trait(cx, self_type, display_trait_id, &[]) {\n        span_lint_and_help(\n            cx,\n            INHERENT_TO_STRING_SHADOW_DISPLAY,\n            item.span,\n            format!(\n                \"type `{self_type}` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display`\"\n            ),\n            None,\n            format!(\"remove the inherent method from type `{self_type}`\"),\n        );\n    } else {\n        span_lint_and_help(\n            cx,\n            INHERENT_TO_STRING,\n            item.span,\n            format!(\"implementation of inherent method `to_string(&self) -> String` for type `{self_type}`\"),\n            None,\n            format!(\"implement trait `Display` for type `{self_type}` instead\"),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/init_numbered_fields.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Expr, ExprKind, StructTailExpr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::SyntaxContext;\nuse std::borrow::Cow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for tuple structs initialized with field syntax.\n    /// It will however not lint if a base initializer is present.\n    /// The lint will also ignore code in macros.\n    ///\n    /// ### Why is this bad?\n    /// This may be confusing to the uninitiated and adds no\n    /// benefit as opposed to tuple initializers\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct TupleStruct(u8, u16);\n    ///\n    /// let _ = TupleStruct {\n    ///     0: 1,\n    ///     1: 23,\n    /// };\n    ///\n    /// // should be written as\n    /// let base = TupleStruct(1, 23);\n    ///\n    /// // This is OK however\n    /// let _ = TupleStruct { 0: 42, ..base };\n    /// ```\n    #[clippy::version = \"1.59.0\"]\n    pub INIT_NUMBERED_FIELDS,\n    style,\n    \"numbered fields in tuple struct initializer\"\n}\n\ndeclare_lint_pass!(NumberedFields => [INIT_NUMBERED_FIELDS]);\n\nimpl<'tcx> LateLintPass<'tcx> for NumberedFields {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let ExprKind::Struct(path, fields @ [field, ..], StructTailExpr::None) = e.kind\n            // If the first character of any field is a digit it has to be a tuple.\n            && field.ident.as_str().as_bytes().first().is_some_and(u8::is_ascii_digit)\n            // Type aliases can't be used as functions.\n            && !matches!(\n                cx.qpath_res(path, e.hir_id),\n                Res::Def(DefKind::TyAlias | DefKind::AssocTy, _)\n            )\n            // This is the only syntax macros can use that works for all struct types.\n            && !e.span.from_expansion()\n            && let mut has_side_effects = false\n            && let Ok(mut expr_spans) = fields\n                .iter()\n                .map(|f| {\n                    has_side_effects |= f.expr.can_have_side_effects();\n                    f.ident.as_str().parse::<usize>().map(|x| (x, f.expr.span))\n                })\n                .collect::<Result<Vec<_>, _>>()\n            // We can only reorder the expressions if there are no side effects.\n            && (!has_side_effects || expr_spans.is_sorted_by_key(|&(idx, _)| idx))\n        {\n            span_lint_and_then(\n                cx,\n                INIT_NUMBERED_FIELDS,\n                e.span,\n                \"used a field initializer for a tuple struct\",\n                |diag| {\n                    if !has_side_effects {\n                        // We already checked the order if there are side effects.\n                        expr_spans.sort_by_key(|&(idx, _)| idx);\n                    }\n                    let mut app = Applicability::MachineApplicable;\n                    diag.span_suggestion(\n                        e.span,\n                        \"use tuple initialization\",\n                        format!(\n                            \"{}({})\",\n                            snippet_with_applicability(cx, path.span(), \"..\", &mut app),\n                            expr_spans\n                                .into_iter()\n                                .map(\n                                    |(_, span)| snippet_with_context(cx, span, SyntaxContext::root(), \"..\", &mut app).0\n                                )\n                                .intersperse(Cow::Borrowed(\", \"))\n                                .collect::<String>()\n                        ),\n                        app,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/inline_fn_without_body.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::DiagExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::{TraitFn, TraitItem, TraitItemKind, find_attr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `#[inline]` on trait methods without bodies\n    ///\n    /// ### Why is this bad?\n    /// Only implementations of trait methods may be inlined.\n    /// The inline attribute is ignored for trait methods without bodies.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// trait Animal {\n    ///     #[inline]\n    ///     fn name(&self) -> &'static str;\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INLINE_FN_WITHOUT_BODY,\n    correctness,\n    \"use of `#[inline]` on trait methods without bodies\"\n}\n\ndeclare_lint_pass!(InlineFnWithoutBody => [INLINE_FN_WITHOUT_BODY]);\n\nimpl<'tcx> LateLintPass<'tcx> for InlineFnWithoutBody {\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {\n        if let TraitItemKind::Fn(_, TraitFn::Required(_)) = item.kind\n            && let Some(attr_span) = find_attr!(cx\n                    .tcx\n                    .hir_attrs(item.hir_id()),\n                    Inline(_, span) => *span\n            )\n        {\n            span_lint_and_then(\n                cx,\n                INLINE_FN_WITHOUT_BODY,\n                attr_span,\n                format!(\"use of `#[inline]` on trait method `{}` which has no body\", item.ident),\n                |diag| {\n                    diag.suggest_remove_item(cx, attr_span, \"remove\", Applicability::MachineApplicable);\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/int_plus_one.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg;\nuse rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind, UnOp};\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block\n    ///\n    /// ### Why is this bad?\n    /// Readability -- better to use `> y` instead of `>= y + 1`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// # let y = 1;\n    /// if x >= y + 1 {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = 1;\n    /// # let y = 1;\n    /// if x > y {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INT_PLUS_ONE,\n    complexity,\n    \"instead of using `x >= y + 1`, use `x > y`\"\n}\n\ndeclare_lint_pass!(IntPlusOne => [INT_PLUS_ONE]);\n\n// cases:\n// LeOrGe::Ge\n// x >= y + 1\n// x - 1 >= y\n//\n// LeOrGe::Le\n// x + 1 <= y\n// x <= y - 1\n\n#[derive(Copy, Clone)]\nenum LeOrGe {\n    Le,\n    Ge,\n}\n\nimpl TryFrom<BinOpKind> for LeOrGe {\n    type Error = ();\n    fn try_from(value: BinOpKind) -> Result<Self, Self::Error> {\n        match value {\n            BinOpKind::Le => Ok(Self::Le),\n            BinOpKind::Ge => Ok(Self::Ge),\n            _ => Err(()),\n        }\n    }\n}\n\nimpl IntPlusOne {\n    fn is_one(expr: &Expr) -> bool {\n        if let ExprKind::Lit(token_lit) = expr.kind\n            && matches!(LitKind::from_token_lit(token_lit), Ok(LitKind::Int(Pu128(1), ..)))\n        {\n            return true;\n        }\n        false\n    }\n\n    fn is_neg_one(expr: &Expr) -> bool {\n        if let ExprKind::Unary(UnOp::Neg, expr) = &expr.kind {\n            Self::is_one(expr)\n        } else {\n            false\n        }\n    }\n\n    /// Checks whether `expr` is `x + 1` or `1 + x`, and if so, returns `x`\n    fn as_x_plus_one(expr: &Expr) -> Option<&Expr> {\n        if let ExprKind::Binary(op, lhs, rhs) = &expr.kind\n            && op.node == BinOpKind::Add\n        {\n            if Self::is_one(rhs) {\n                // x + 1\n                return Some(lhs);\n            } else if Self::is_one(lhs) {\n                // 1 + x\n                return Some(rhs);\n            }\n        }\n        None\n    }\n\n    /// Checks whether `expr` is `x - 1` or `-1 + x`, and if so, returns `x`\n    fn as_x_minus_one(expr: &Expr) -> Option<&Expr> {\n        if let ExprKind::Binary(op, lhs, rhs) = &expr.kind {\n            if op.node == BinOpKind::Sub && Self::is_one(rhs) {\n                // x - 1\n                return Some(lhs);\n            } else if op.node == BinOpKind::Add && Self::is_neg_one(lhs) {\n                // -1 + x\n                return Some(rhs);\n            }\n        }\n        None\n    }\n\n    fn check_binop<'tcx>(le_or_ge: LeOrGe, lhs: &'tcx Expr, rhs: &'tcx Expr) -> Option<(&'tcx Expr, &'tcx Expr)> {\n        match le_or_ge {\n            LeOrGe::Ge => {\n                // case where `x - 1 >= ...` or `-1 + x >= ...`\n                (Self::as_x_minus_one(lhs).map(|new_lhs| (new_lhs, rhs)))\n                    // case where `... >= y + 1` or `... >= 1 + y`\n                    .or_else(|| Self::as_x_plus_one(rhs).map(|new_rhs| (lhs, new_rhs)))\n            },\n            LeOrGe::Le => {\n                // case where `x + 1 <= ...` or `1 + x <= ...`\n                (Self::as_x_plus_one(lhs).map(|new_lhs| (new_lhs, rhs)))\n                    // case where `... <= y - 1` or `... <= -1 + y`\n                    .or_else(|| Self::as_x_minus_one(rhs).map(|new_rhs| (lhs, new_rhs)))\n            },\n        }\n    }\n\n    fn emit_warning(cx: &EarlyContext<'_>, expr: &Expr, new_lhs: &Expr, le_or_ge: LeOrGe, new_rhs: &Expr) {\n        span_lint_and_then(\n            cx,\n            INT_PLUS_ONE,\n            expr.span,\n            \"unnecessary `>= y + 1` or `x - 1 >=`\",\n            |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let ctxt = expr.span.ctxt();\n                let new_lhs = sugg::Sugg::ast(cx, new_lhs, \"_\", ctxt, &mut app);\n                let new_rhs = sugg::Sugg::ast(cx, new_rhs, \"_\", ctxt, &mut app);\n                let new_binop = match le_or_ge {\n                    LeOrGe::Ge => BinOpKind::Gt,\n                    LeOrGe::Le => BinOpKind::Lt,\n                };\n                let rec = sugg::make_binop(new_binop, &new_lhs, &new_rhs);\n                diag.span_suggestion(expr.span, \"change it to\", rec, app);\n            },\n        );\n    }\n}\n\nimpl EarlyLintPass for IntPlusOne {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::Binary(binop, lhs, rhs) = &expr.kind\n            && let Ok(le_or_ge) = LeOrGe::try_from(binop.node)\n            && let Some((new_lhs, new_rhs)) = Self::check_binop(le_or_ge, lhs, rhs)\n        {\n            Self::emit_warning(cx, expr, new_lhs, le_or_ge, new_rhs);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/item_name_repetitions.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir};\nuse clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start, to_camel_case, to_snake_case};\nuse clippy_utils::{is_bool, is_from_proc_macro};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::{Body, EnumDef, FieldDef, Item, ItemKind, QPath, TyKind, UseKind, Variant, VariantData};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects enumeration variants that are prefixed or suffixed\n    /// by the same characters.\n    ///\n    /// ### Why is this bad?\n    /// Enumeration variant names should specify their variant,\n    /// not repeat the enumeration name.\n    ///\n    /// ### Limitations\n    /// Characters with no casing will be considered when comparing prefixes/suffixes\n    /// This applies to numbers and non-ascii characters without casing\n    /// e.g. `Foo1` and `Foo2` is considered to have different prefixes\n    /// (the prefixes are `Foo1` and `Foo2` respectively), as also `Bar螃`, `Bar蟹`\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum Cake {\n    ///     BlackForestCake,\n    ///     HummingbirdCake,\n    ///     BattenbergCake,\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// enum Cake {\n    ///     BlackForest,\n    ///     Hummingbird,\n    ///     Battenberg,\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ENUM_VARIANT_NAMES,\n    style,\n    \"enums where all variants share a prefix/postfix\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for modules that have the same name as their\n    /// parent module\n    ///\n    /// ### Why is this bad?\n    /// A typical beginner mistake is to have `mod foo;` and\n    /// again `mod foo { ..\n    /// }` in `foo.rs`.\n    /// The expectation is that items inside the inner `mod foo { .. }` are then\n    /// available\n    /// through `foo::x`, but they are only available through\n    /// `foo::foo::x`.\n    /// If this is done on purpose, it would be better to choose a more\n    /// representative module name.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// // lib.rs\n    /// mod foo;\n    /// // foo.rs\n    /// mod foo {\n    ///     ...\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MODULE_INCEPTION,\n    style,\n    \"modules that have the same name as their parent module\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects public item names that are prefixed or suffixed by the\n    /// containing public module's name.\n    ///\n    /// ### Why is this bad?\n    /// It requires the user to type the module name twice in each usage,\n    /// especially if they choose to import the module rather than its contents.\n    ///\n    /// Lack of such repetition is also the style used in the Rust standard library;\n    /// e.g. `io::Error` and `fmt::Error` rather than `io::IoError` and `fmt::FmtError`;\n    /// and `array::from_ref` rather than `array::array_from_ref`.\n    ///\n    /// ### Known issues\n    /// Glob re-exports are ignored; e.g. this will not warn even though it should:\n    ///\n    /// ```no_run\n    /// pub mod foo {\n    ///     mod iteration {\n    ///         pub struct FooIter {}\n    ///     }\n    ///     pub use iteration::*; // creates the path `foo::FooIter`\n    /// }\n    /// ```\n    ///\n    /// ### Example\n    /// ```no_run\n    /// mod cake {\n    ///     struct BlackForestCake;\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// mod cake {\n    ///     struct BlackForest;\n    /// }\n    /// ```\n    #[clippy::version = \"1.33.0\"]\n    pub MODULE_NAME_REPETITIONS,\n    restriction,\n    \"type names prefixed/postfixed with their containing module's name\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects struct fields that are prefixed or suffixed\n    /// by the same characters or the name of the struct itself.\n    ///\n    /// ### Why is this bad?\n    /// Information common to all struct fields is better represented in the struct name.\n    ///\n    /// ### Limitations\n    /// Characters with no casing will be considered when comparing prefixes/suffixes\n    /// This applies to numbers and non-ascii characters without casing\n    /// e.g. `foo1` and `foo2` is considered to have different prefixes\n    /// (the prefixes are `foo1` and `foo2` respectively), as also `bar螃`, `bar蟹`\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Cake {\n    ///     cake_sugar: u8,\n    ///     cake_flour: u8,\n    ///     cake_eggs: u8\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct Cake {\n    ///     sugar: u8,\n    ///     flour: u8,\n    ///     eggs: u8\n    /// }\n    /// ```\n    #[clippy::version = \"1.75.0\"]\n    pub STRUCT_FIELD_NAMES,\n    pedantic,\n    \"structs where all fields share a prefix/postfix or contain the name of the struct\"\n}\n\nimpl_lint_pass!(ItemNameRepetitions => [\n    ENUM_VARIANT_NAMES,\n    MODULE_INCEPTION,\n    MODULE_NAME_REPETITIONS,\n    STRUCT_FIELD_NAMES,\n]);\n\npub struct ItemNameRepetitions {\n    /// The module path the lint pass is in.\n    modules: Vec<ModInfo>,\n    enum_threshold: u64,\n    struct_threshold: u64,\n    avoid_breaking_exported_api: bool,\n    allow_exact_repetitions: bool,\n    allow_private_module_inception: bool,\n    allowed_prefixes: FxHashSet<String>,\n}\n\nstruct ModInfo {\n    name: Symbol,\n    name_camel: String,\n    /// Does this module have the `pub` visibility modifier.\n    is_public: bool,\n    /// How many bodies are between this module and the current lint pass position.\n    ///\n    /// Only the most recently seen module is updated when entering/exiting a body.\n    in_body_count: u32,\n}\n\nimpl ItemNameRepetitions {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            modules: Vec::new(),\n            enum_threshold: conf.enum_variant_name_threshold,\n            struct_threshold: conf.struct_field_name_threshold,\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n            allow_exact_repetitions: conf.allow_exact_repetitions,\n            allow_private_module_inception: conf.allow_private_module_inception,\n            allowed_prefixes: conf.allowed_prefixes.iter().map(|s| to_camel_case(s)).collect(),\n        }\n    }\n\n    fn is_allowed_prefix(&self, prefix: &str) -> bool {\n        self.allowed_prefixes.contains(prefix)\n    }\n}\n\n#[must_use]\nfn have_no_extra_prefix(prefixes: &[&str]) -> bool {\n    prefixes.iter().all(|p| p == &\"\" || p == &\"_\")\n}\n\nimpl ItemNameRepetitions {\n    /// Lint the names of enum variants against the name of the enum.\n    fn check_variants(&self, cx: &LateContext<'_>, item: &Item<'_>, def: &EnumDef<'_>) {\n        if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.owner_id.def_id) {\n            return;\n        }\n\n        if (def.variants.len() as u64) < self.enum_threshold {\n            return;\n        }\n\n        let Some(ident) = item.kind.ident() else {\n            return;\n        };\n        let item_name = ident.name.as_str();\n        for var in def.variants {\n            check_enum_start(cx, item_name, var);\n            check_enum_end(cx, item_name, var);\n        }\n\n        Self::check_enum_common_affix(cx, item, def);\n    }\n\n    /// Lint the names of struct fields against the name of the struct.\n    fn check_fields(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {\n        if (fields.len() as u64) < self.struct_threshold {\n            return;\n        }\n\n        self.check_struct_name_repetition(cx, item, fields);\n        self.check_struct_common_affix(cx, item, fields);\n    }\n\n    fn check_enum_common_affix(cx: &LateContext<'_>, item: &Item<'_>, def: &EnumDef<'_>) {\n        let first = match def.variants.first() {\n            Some(variant) => variant.ident.name.as_str(),\n            None => return,\n        };\n        let mut pre = camel_case_split(first);\n        let mut post = pre.clone();\n        post.reverse();\n        for var in def.variants {\n            let name = var.ident.name.as_str();\n\n            let variant_split = camel_case_split(name);\n            if variant_split.len() == 1 {\n                return;\n            }\n\n            pre = pre\n                .iter()\n                .zip(variant_split.iter())\n                .take_while(|(a, b)| a == b)\n                .map(|e| *e.0)\n                .collect();\n            post = post\n                .iter()\n                .zip(variant_split.iter().rev())\n                .take_while(|(a, b)| a == b)\n                .map(|e| *e.0)\n                .collect();\n        }\n        let (what, value) = match (have_no_extra_prefix(&pre), post.is_empty()) {\n            (true, true) => return,\n            (false, _) => (\"pre\", pre.join(\"\")),\n            (true, false) => {\n                post.reverse();\n                (\"post\", post.join(\"\"))\n            },\n        };\n        span_lint_and_help(\n            cx,\n            ENUM_VARIANT_NAMES,\n            item.span,\n            format!(\"all variants have the same {what}fix: `{value}`\"),\n            None,\n            format!(\n                \"remove the {what}fixes and use full paths to \\\n                 the variants instead of glob imports\"\n            ),\n        );\n    }\n\n    fn check_struct_common_affix(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {\n        // if the SyntaxContext of the identifiers of the fields and struct differ dont lint them.\n        // this prevents linting in macros in which the location of the field identifier names differ\n        if !fields\n            .iter()\n            .all(|field| item.kind.ident().is_some_and(|i| i.span.eq_ctxt(field.ident.span)))\n        {\n            return;\n        }\n\n        if self.avoid_breaking_exported_api\n            && fields\n                .iter()\n                .any(|field| cx.effective_visibilities.is_exported(field.def_id))\n        {\n            return;\n        }\n\n        let mut pre: Vec<&str> = match fields.first() {\n            Some(first_field) => first_field.ident.name.as_str().split('_').collect(),\n            None => return,\n        };\n        let mut post = pre.clone();\n        post.reverse();\n        for field in fields {\n            let field_split: Vec<&str> = field.ident.name.as_str().split('_').collect();\n            if field_split.len() == 1 {\n                return;\n            }\n\n            pre = pre\n                .into_iter()\n                .zip(field_split.iter())\n                .take_while(|(a, b)| &a == b)\n                .map(|e| e.0)\n                .collect();\n            post = post\n                .into_iter()\n                .zip(field_split.iter().rev())\n                .take_while(|(a, b)| &a == b)\n                .map(|e| e.0)\n                .collect();\n        }\n        let prefix = pre.join(\"_\");\n        post.reverse();\n        let postfix = match post.last() {\n            Some(&\"\") => post.join(\"_\") + \"_\",\n            Some(_) | None => post.join(\"_\"),\n        };\n        if fields.len() > 1 {\n            let (what, value) = match (\n                prefix.is_empty() || prefix.chars().all(|c| c == '_'),\n                postfix.is_empty(),\n            ) {\n                (true, true) => return,\n                (false, _) => (\"pre\", prefix),\n                (true, false) => (\"post\", postfix),\n            };\n            if fields.iter().all(|field| is_bool(field.ty)) {\n                // If all fields are booleans, we don't want to emit this lint.\n                return;\n            }\n            span_lint_and_help(\n                cx,\n                STRUCT_FIELD_NAMES,\n                item.span,\n                format!(\"all fields have the same {what}fix: `{value}`\"),\n                None,\n                format!(\"remove the {what}fixes\"),\n            );\n        }\n    }\n\n    fn check_struct_name_repetition(&self, cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {\n        let Some(ident) = item.kind.ident() else { return };\n        let snake_name = to_snake_case(ident.name.as_str());\n        let item_name_words: Vec<&str> = snake_name.split('_').collect();\n        for field in fields {\n            if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(field.def_id) {\n                continue;\n            }\n\n            if !field.ident.span.eq_ctxt(ident.span) {\n                // consider linting only if the field identifier has the same SyntaxContext as the item(struct)\n                continue;\n            }\n\n            let field_words: Vec<&str> = field.ident.name.as_str().split('_').collect();\n            if field_words.len() >= item_name_words.len() {\n                // if the field name is shorter than the struct name it cannot contain it\n                if field_words.iter().zip(item_name_words.iter()).all(|(a, b)| a == b) {\n                    span_lint_hir(\n                        cx,\n                        STRUCT_FIELD_NAMES,\n                        field.hir_id,\n                        field.span,\n                        \"field name starts with the struct's name\",\n                    );\n                }\n                if field_words.len() > item_name_words.len()\n                    // lint only if the end is not covered by the start\n                    && field_words\n                        .iter()\n                        .rev()\n                        .zip(item_name_words.iter().rev())\n                        .all(|(a, b)| a == b)\n                {\n                    span_lint_hir(\n                        cx,\n                        STRUCT_FIELD_NAMES,\n                        field.hir_id,\n                        field.span,\n                        \"field name ends with the struct's name\",\n                    );\n                }\n            }\n        }\n    }\n}\n\nfn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>) {\n    let name = variant.ident.name.as_str();\n    let item_name_chars = item_name.chars().count();\n\n    if count_match_start(item_name, name).char_count == item_name_chars\n        && name.chars().nth(item_name_chars).is_some_and(|c| !c.is_lowercase())\n        && name.chars().nth(item_name_chars + 1).is_some_and(|c| !c.is_numeric())\n        && !check_enum_tuple_path_match(name, variant.data)\n    {\n        span_lint_hir(\n            cx,\n            ENUM_VARIANT_NAMES,\n            variant.hir_id,\n            variant.span,\n            \"variant name starts with the enum's name\",\n        );\n    }\n}\n\nfn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>) {\n    let name = variant.ident.name.as_str();\n    let item_name_chars = item_name.chars().count();\n\n    if count_match_end(item_name, name).char_count == item_name_chars\n        && !check_enum_tuple_path_match(name, variant.data)\n    {\n        span_lint_hir(\n            cx,\n            ENUM_VARIANT_NAMES,\n            variant.hir_id,\n            variant.span,\n            \"variant name ends with the enum's name\",\n        );\n    }\n}\n\n/// Checks if an enum tuple variant contains a single field\n/// whose qualified path contains the variant's name.\nfn check_enum_tuple_path_match(variant_name: &str, variant_data: VariantData<'_>) -> bool {\n    // Only check single-field tuple variants\n    let VariantData::Tuple(fields, ..) = variant_data else {\n        return false;\n    };\n    if fields.len() != 1 {\n        return false;\n    }\n    // Check if field type is a path and contains the variant name\n    match fields[0].ty.kind {\n        TyKind::Path(QPath::Resolved(_, path)) => path\n            .segments\n            .iter()\n            .any(|segment| segment.ident.name.as_str() == variant_name),\n        TyKind::Path(QPath::TypeRelative(_, segment)) => segment.ident.name.as_str() == variant_name,\n        _ => false,\n    }\n}\n\nimpl LateLintPass<'_> for ItemNameRepetitions {\n    fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {\n        if matches!(item.kind, ItemKind::Mod(..)) {\n            let prev = self.modules.pop();\n            debug_assert!(prev.is_some());\n        }\n    }\n\n    fn check_body(&mut self, _: &LateContext<'_>, _: &Body<'_>) {\n        if let [.., last] = &mut *self.modules {\n            last.in_body_count += 1;\n        }\n    }\n\n    fn check_body_post(&mut self, _: &LateContext<'_>, _: &Body<'_>) {\n        if let [.., last] = &mut *self.modules {\n            last.in_body_count -= 1;\n        }\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        let ident = match item.kind {\n            ItemKind::Mod(ident, _) => {\n                if let [.., prev] = &*self.modules\n                    && prev.name == ident.name\n                    && prev.in_body_count == 0\n                    && (!self.allow_private_module_inception || prev.is_public)\n                    && !item.span.from_expansion()\n                    && !is_from_proc_macro(cx, item)\n                {\n                    span_lint(\n                        cx,\n                        MODULE_INCEPTION,\n                        item.span,\n                        \"module has the same name as its containing module\",\n                    );\n                }\n                ident\n            },\n\n            ItemKind::Enum(ident, _, def) => {\n                if !ident.span.in_external_macro(cx.tcx.sess.source_map()) {\n                    self.check_variants(cx, item, &def);\n                }\n                ident\n            },\n            ItemKind::Struct(ident, _, data) => {\n                if let VariantData::Struct { fields, .. } = data\n                    && !ident.span.in_external_macro(cx.tcx.sess.source_map())\n                {\n                    self.check_fields(cx, item, fields);\n                }\n                ident\n            },\n\n            ItemKind::Const(ident, ..)\n            | ItemKind::ExternCrate(_, ident)\n            | ItemKind::Fn { ident, .. }\n            | ItemKind::Macro(ident, ..)\n            | ItemKind::Static(_, ident, ..)\n            | ItemKind::Trait(_, _, _, ident, ..)\n            | ItemKind::TraitAlias(_, ident, ..)\n            | ItemKind::TyAlias(ident, ..)\n            | ItemKind::Union(ident, ..)\n            | ItemKind::Use(_, UseKind::Single(ident)) => ident,\n\n            ItemKind::ForeignMod { .. } | ItemKind::GlobalAsm { .. } | ItemKind::Impl(_) | ItemKind::Use(..) => return,\n        };\n\n        let item_name = ident.name.as_str();\n        let item_camel = to_camel_case(item_name);\n\n        if let [.., prev] = &*self.modules\n            && prev.is_public\n            && prev.in_body_count == 0\n            && !item.span.from_expansion()\n            && !matches!(item.kind, ItemKind::Macro(..))\n            && cx.tcx.visibility(item.owner_id).is_public()\n        {\n            if !self.allow_exact_repetitions && item_camel == prev.name_camel {\n                if !is_from_proc_macro(cx, item) {\n                    span_lint(\n                        cx,\n                        MODULE_NAME_REPETITIONS,\n                        ident.span,\n                        \"item name is the same as its containing module's name\",\n                    );\n                }\n            } else if item_camel.len() > prev.name_camel.len() {\n                if let Some(s) = item_camel.strip_prefix(&prev.name_camel)\n                    && let Some(c) = s.chars().next()\n                    && (c == '_' || c.is_uppercase() || c.is_numeric())\n                {\n                    if !is_from_proc_macro(cx, item) {\n                        span_lint(\n                            cx,\n                            MODULE_NAME_REPETITIONS,\n                            ident.span,\n                            \"item name starts with its containing module's name\",\n                        );\n                    }\n                } else if let Some(s) = item_camel.strip_suffix(&prev.name_camel)\n                    && !self.is_allowed_prefix(s)\n                    && !is_from_proc_macro(cx, item)\n                {\n                    span_lint(\n                        cx,\n                        MODULE_NAME_REPETITIONS,\n                        ident.span,\n                        \"item name ends with its containing module's name\",\n                    );\n                }\n            }\n        }\n\n        if matches!(item.kind, ItemKind::Mod(..)) {\n            self.modules.push(ModInfo {\n                name: ident.name,\n                name_camel: item_camel,\n                is_public: cx.tcx.visibility(item.owner_id).is_public(),\n                in_body_count: 0,\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/items_after_statements.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir;\nuse rustc_hir::{Block, ItemKind, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for items declared after some statement in a block.\n    ///\n    /// ### Why is this bad?\n    /// Items live for the entire scope they are declared\n    /// in. But statements are processed in order. This might cause confusion as\n    /// it's hard to figure out which item is meant in a statement.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo() {\n    ///     println!(\"cake\");\n    /// }\n    ///\n    /// fn main() {\n    ///     foo(); // prints \"foo\"\n    ///     fn foo() {\n    ///         println!(\"foo\");\n    ///     }\n    ///     foo(); // prints \"foo\"\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn foo() {\n    ///     println!(\"cake\");\n    /// }\n    ///\n    /// fn main() {\n    ///     fn foo() {\n    ///         println!(\"foo\");\n    ///     }\n    ///     foo(); // prints \"foo\"\n    ///     foo(); // prints \"foo\"\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ITEMS_AFTER_STATEMENTS,\n    pedantic,\n    \"blocks where an item comes after a statement\"\n}\n\ndeclare_lint_pass!(ItemsAfterStatements => [ITEMS_AFTER_STATEMENTS]);\n\nimpl LateLintPass<'_> for ItemsAfterStatements {\n    fn check_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>) {\n        if block.stmts.len() > 1 {\n            let ctxt = block.span.ctxt();\n            let mut in_external = None;\n            block\n                .stmts\n                .iter()\n                .skip_while(|stmt| matches!(stmt.kind, StmtKind::Item(..)))\n                .filter_map(|stmt| match stmt.kind {\n                    StmtKind::Item(id) => Some(cx.tcx.hir_item(id)),\n                    _ => None,\n                })\n                // Ignore macros since they can only see previously defined locals.\n                .filter(|item| !matches!(item.kind, ItemKind::Macro(..)))\n                // Stop linting if macros define items.\n                .take_while(|item| item.span.ctxt() == ctxt)\n                // Don't use `next` due to the complex filter chain.\n                .for_each(|item| {\n                    // Only do the macro check once, but delay it until it's needed.\n                    if !*in_external.get_or_insert_with(|| block.span.in_external_macro(cx.sess().source_map())) {\n                        span_lint_hir(\n                            cx,\n                            ITEMS_AFTER_STATEMENTS,\n                            item.hir_id(),\n                            item.span,\n                            \"adding items after statements is confusing, since items exist from the \\\n                                start of the scope\",\n                        );\n                    }\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/items_after_test_module.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{fulfill_or_allowed, is_cfg_test, is_from_proc_macro};\nuse rustc_errors::{Applicability, SuggestionStyle};\nuse rustc_hir::{HirId, Item, ItemKind, Mod};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::hygiene::AstPass;\nuse rustc_span::{ExpnKind, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Triggers if an item is declared after the testing module marked with `#[cfg(test)]`.\n    /// ### Why is this bad?\n    /// Having items declared after the testing module is confusing and may lead to bad test coverage.\n    /// ### Example\n    /// ```no_run\n    /// #[cfg(test)]\n    /// mod tests {\n    ///     // [...]\n    /// }\n    ///\n    /// fn my_function() {\n    ///     // [...]\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn my_function() {\n    ///     // [...]\n    /// }\n    ///\n    /// #[cfg(test)]\n    /// mod tests {\n    ///     // [...]\n    /// }\n    /// ```\n    #[clippy::version = \"1.71.0\"]\n    pub ITEMS_AFTER_TEST_MODULE,\n    style,\n    \"An item was found after the testing module `tests`\"\n}\n\ndeclare_lint_pass!(ItemsAfterTestModule => [ITEMS_AFTER_TEST_MODULE]);\n\nfn cfg_test_module<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {\n    if let ItemKind::Mod(_, test_mod) = item.kind\n        && item.span.hi() == test_mod.spans.inner_span.hi()\n        && is_cfg_test(cx.tcx, item.hir_id())\n        && !item.span.from_expansion()\n        && !is_from_proc_macro(cx, item)\n    {\n        true\n    } else {\n        false\n    }\n}\n\nimpl LateLintPass<'_> for ItemsAfterTestModule {\n    fn check_mod(&mut self, cx: &LateContext<'_>, module: &Mod<'_>, _: HirId) {\n        let mut items = module.item_ids.iter().map(|&id| cx.tcx.hir_item(id));\n\n        let Some((mod_pos, test_mod)) = items.by_ref().enumerate().find(|(_, item)| cfg_test_module(cx, item)) else {\n            return;\n        };\n\n        let after: Vec<_> = items\n            .filter(|item| {\n                // Ignore the generated test main function\n                if let ItemKind::Fn { ident, .. } = item.kind\n                    && ident.name == sym::main\n                    && item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::TestHarness)\n                {\n                    false\n                } else {\n                    true\n                }\n            })\n            .collect();\n\n        if let Some(last) = after.last()\n            && after.iter().all(|&item| {\n                !matches!(item.kind, ItemKind::Mod(..)) && !item.span.from_expansion() && !is_from_proc_macro(cx, item)\n            })\n            && !fulfill_or_allowed(cx, ITEMS_AFTER_TEST_MODULE, after.iter().map(|item| item.hir_id()))\n        {\n            let def_spans: Vec<_> = std::iter::once(test_mod.owner_id)\n                .chain(after.iter().map(|item| item.owner_id))\n                .map(|id| cx.tcx.def_span(id))\n                .collect();\n\n            span_lint_hir_and_then(\n                cx,\n                ITEMS_AFTER_TEST_MODULE,\n                test_mod.hir_id(),\n                def_spans,\n                \"items after a test module\",\n                |diag| {\n                    if let Some(prev) = mod_pos.checked_sub(1)\n                        && let prev = cx.tcx.hir_item(module.item_ids[prev])\n                        && let items_span = last.span.with_lo(test_mod.span.hi())\n                        && let Some(items) = items_span.get_source_text(cx)\n                    {\n                        diag.multipart_suggestion_with_style(\n                            \"move the items to before the test module was defined\",\n                            vec![\n                                (prev.span.shrink_to_hi(), items.to_owned()),\n                                (items_span, String::new()),\n                            ],\n                            Applicability::MachineApplicable,\n                            SuggestionStyle::HideCodeAlways,\n                        );\n                    }\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/iter_not_returning_iterator.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::{FnSig, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{Symbol, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects methods named `iter` or `iter_mut` that do not have a return type that implements `Iterator`.\n    ///\n    /// ### Why is this bad?\n    /// Methods named `iter` or `iter_mut` conventionally return an `Iterator`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // `String` does not implement `Iterator`\n    /// struct Data {}\n    /// impl Data {\n    ///     fn iter(&self) -> String {\n    ///         todo!()\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::str::Chars;\n    /// struct Data {}\n    /// impl Data {\n    ///     fn iter(&self) -> Chars<'static> {\n    ///         todo!()\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub ITER_NOT_RETURNING_ITERATOR,\n    pedantic,\n    \"methods named `iter` or `iter_mut` that do not return an `Iterator`\"\n}\n\ndeclare_lint_pass!(IterNotReturningIterator => [ITER_NOT_RETURNING_ITERATOR]);\n\nimpl<'tcx> LateLintPass<'tcx> for IterNotReturningIterator {\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {\n        if let TraitItemKind::Fn(fn_sig, _) = &item.kind\n            && matches!(item.ident.name, sym::iter | sym::iter_mut)\n        {\n            check_sig(cx, item.ident.name, fn_sig, item.owner_id.def_id);\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'tcx>) {\n        if let ImplItemKind::Fn(fn_sig, _) = &item.kind\n            && matches!(item.ident.name, sym::iter | sym::iter_mut)\n            && !matches!(\n                cx.tcx.parent_hir_node(item.hir_id()),\n                Node::Item(Item { kind: ItemKind::Impl(i), .. }) if i.of_trait.is_some()\n            )\n        {\n            check_sig(cx, item.ident.name, fn_sig, item.owner_id.def_id);\n        }\n    }\n}\n\nfn check_sig(cx: &LateContext<'_>, name: Symbol, sig: &FnSig<'_>, fn_id: LocalDefId) {\n    if sig.decl.implicit_self.has_implicit_self() {\n        let ret_ty = cx\n            .tcx\n            .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(fn_id).instantiate_identity().output());\n        let ret_ty = cx\n            .tcx\n            .try_normalize_erasing_regions(cx.typing_env(), ret_ty)\n            .unwrap_or(ret_ty);\n        if cx\n            .tcx\n            .get_diagnostic_item(sym::Iterator)\n            .is_some_and(|iter_id| !implements_trait(cx, ret_ty, iter_id, &[]))\n        {\n            span_lint(\n                cx,\n                ITER_NOT_RETURNING_ITERATOR,\n                sig.span,\n                format!(\"this method is named `{name}` but its return type does not implement `Iterator`\"),\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/iter_over_hash_type.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::higher::ForLoop;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This is a restriction lint which prevents the use of hash types (i.e., `HashSet` and `HashMap`) in for loops.\n    ///\n    /// ### Why restrict this?\n    /// Because hash types are unordered, when iterated through such as in a `for` loop, the values are returned in\n    /// an undefined order. As a result, on redundant systems this may cause inconsistencies and anomalies.\n    /// In addition, the unknown order of the elements may reduce readability or introduce other undesired\n    /// side effects.\n    ///\n    /// ### Example\n    /// ```no_run\n    ///     let my_map = std::collections::HashMap::<i32, String>::new();\n    ///     for (key, value) in my_map { /* ... */ }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    ///     let my_map = std::collections::HashMap::<i32, String>::new();\n    ///     let mut keys = my_map.keys().clone().collect::<Vec<_>>();\n    ///     keys.sort();\n    ///     for key in keys {\n    ///         let value = &my_map[key];\n    ///     }\n    /// ```\n    #[clippy::version = \"1.76.0\"]\n    pub ITER_OVER_HASH_TYPE,\n    restriction,\n    \"iterating over unordered hash-based types (`HashMap` and `HashSet`)\"\n}\n\ndeclare_lint_pass!(IterOverHashType => [ITER_OVER_HASH_TYPE]);\n\nimpl LateLintPass<'_> for IterOverHashType {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>) {\n        let hash_iter_tys = [\n            sym::HashMap,\n            sym::HashSet,\n            sym::hashmap_keys_ty,\n            sym::hashmap_values_ty,\n            sym::hashmap_values_mut_ty,\n            sym::hashmap_iter_ty,\n            sym::hashmap_iter_mut_ty,\n            sym::hashmap_drain_ty,\n            sym::hashset_iter_ty,\n            sym::hashset_drain_ty,\n        ];\n\n        if let Some(for_loop) = ForLoop::hir(expr)\n            && !for_loop.body.span.from_expansion()\n            && let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs()\n            && hash_iter_tys.into_iter().any(|sym| ty.is_diag_item(cx, sym))\n        {\n            span_lint(\n                cx,\n                ITER_OVER_HASH_TYPE,\n                expr.span,\n                \"iteration over unordered hash-based type\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/iter_without_into_iter.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::{deref_chain, get_adt_inherent_method, implements_trait, make_normalized_projection};\nuse clippy_utils::{get_parent_as_impl, sym};\nuse rustc_ast::Mutability;\nuse rustc_errors::Applicability;\nuse rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This is the opposite of the `iter_without_into_iter` lint.\n    /// It looks for `IntoIterator for (&|&mut) Type` implementations without an inherent `iter` or `iter_mut` method\n    /// on the type or on any of the types in its `Deref` chain.\n    ///\n    /// ### Why is this bad?\n    /// It's not bad, but having them is idiomatic and allows the type to be used in iterator chains\n    /// by just calling `.iter()`, instead of the more awkward `<&Type>::into_iter` or `(&val).into_iter()` syntax\n    /// in case of ambiguity with another `IntoIterator` impl.\n    ///\n    /// ### Limitations\n    /// This lint focuses on providing an idiomatic API. Therefore, it will only\n    /// lint on types which are accessible outside of the crate. For internal types,\n    /// these methods can be added on demand if they are actually needed. Otherwise,\n    /// it would trigger the [`dead_code`] lint for the unused method.\n    ///\n    /// [`dead_code`]: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#dead-code\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct MySlice<'a>(&'a [u8]);\n    /// impl<'a> IntoIterator for &MySlice<'a> {\n    ///     type Item = &'a u8;\n    ///     type IntoIter = std::slice::Iter<'a, u8>;\n    ///     fn into_iter(self) -> Self::IntoIter {\n    ///         self.0.iter()\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct MySlice<'a>(&'a [u8]);\n    /// impl<'a> MySlice<'a> {\n    ///     pub fn iter(&self) -> std::slice::Iter<'a, u8> {\n    ///         self.into_iter()\n    ///     }\n    /// }\n    /// impl<'a> IntoIterator for &MySlice<'a> {\n    ///     type Item = &'a u8;\n    ///     type IntoIter = std::slice::Iter<'a, u8>;\n    ///     fn into_iter(self) -> Self::IntoIter {\n    ///         self.0.iter()\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.75.0\"]\n    pub INTO_ITER_WITHOUT_ITER,\n    pedantic,\n    \"implementing `IntoIterator for (&|&mut) Type` without an inherent `iter(_mut)` method\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for `iter` and `iter_mut` methods without an associated `IntoIterator for (&|&mut) Type` implementation.\n    ///\n    /// ### Why is this bad?\n    /// It's not bad, but having them is idiomatic and allows the type to be used in for loops directly\n    /// (`for val in &iter {}`), without having to first call `iter()` or `iter_mut()`.\n    ///\n    /// ### Limitations\n    /// This lint focuses on providing an idiomatic API. Therefore, it will only\n    /// lint on types which are accessible outside of the crate. For internal types,\n    /// the `IntoIterator` trait can be implemented on demand if it is actually needed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct MySlice<'a>(&'a [u8]);\n    /// impl<'a> MySlice<'a> {\n    ///     pub fn iter(&self) -> std::slice::Iter<'a, u8> {\n    ///         self.0.iter()\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct MySlice<'a>(&'a [u8]);\n    /// impl<'a> MySlice<'a> {\n    ///     pub fn iter(&self) -> std::slice::Iter<'a, u8> {\n    ///         self.0.iter()\n    ///     }\n    /// }\n    /// impl<'a> IntoIterator for &MySlice<'a> {\n    ///     type Item = &'a u8;\n    ///     type IntoIter = std::slice::Iter<'a, u8>;\n    ///     fn into_iter(self) -> Self::IntoIter {\n    ///         self.iter()\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.75.0\"]\n    pub ITER_WITHOUT_INTO_ITER,\n    pedantic,\n    \"implementing `iter(_mut)` without an associated `IntoIterator for (&|&mut) Type` impl\"\n}\n\ndeclare_lint_pass!(IterWithoutIntoIter => [\n    INTO_ITER_WITHOUT_ITER,\n    ITER_WITHOUT_INTO_ITER,\n]);\n\n/// Checks if a given type is nameable in a trait (impl).\n/// RPIT is stable, but impl Trait in traits is not (yet), so when we have\n/// a function such as `fn iter(&self) -> impl IntoIterator`, we can't\n/// suggest `type IntoIter = impl IntoIterator`.\nfn is_nameable_in_impl_trait(ty: &rustc_hir::Ty<'_>) -> bool {\n    !matches!(ty.kind, TyKind::OpaqueDef(..))\n}\n\nfn is_ty_exported(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    ty.ty_adt_def()\n        .and_then(|adt| adt.did().as_local())\n        .is_some_and(|did| cx.effective_visibilities.is_exported(did))\n}\n\nimpl LateLintPass<'_> for IterWithoutIntoIter {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) {\n        if let ItemKind::Impl(imp) = item.kind\n            && let TyKind::Ref(_, self_ty_without_ref) = &imp.self_ty.kind\n            && let Some(of_trait) = imp.of_trait\n            && of_trait\n                .trait_ref\n                .trait_def_id()\n                .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did))\n            && !item.span.in_external_macro(cx.sess().source_map())\n            && let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()\n            && let expected_method_name = match mtbl {\n                Mutability::Mut => sym::iter_mut,\n                Mutability::Not => sym::iter,\n            }\n            && !deref_chain(cx, ty).any(|ty| {\n                // We can't check inherent impls for slices, but we know that they have an `iter(_mut)` method\n                ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some()\n            })\n            && let Some(iter_assoc_span) = cx\n                .tcx\n                .associated_items(item.owner_id)\n                .filter_by_name_unhygienic_and_kind(sym::IntoIter, ty::AssocTag::Type)\n                .next()\n                .map(|assoc_item| {\n                    cx.tcx\n                        .hir_node_by_def_id(assoc_item.def_id.expect_local())\n                        .expect_impl_item()\n                        .expect_type()\n                        .span\n                })\n            && is_ty_exported(cx, ty)\n        {\n            span_lint_and_then(\n                cx,\n                INTO_ITER_WITHOUT_ITER,\n                item.span,\n                format!(\"`IntoIterator` implemented for a reference type without an `{expected_method_name}` method\"),\n                |diag| {\n                    // The suggestion forwards to the `IntoIterator` impl and uses a form of UFCS\n                    // to avoid name ambiguities, as there might be an inherent into_iter method\n                    // that we don't want to call.\n                    let sugg = format!(\n                        \"\nimpl {self_ty_without_ref} {{\n    fn {expected_method_name}({ref_self}self) -> {iter_ty} {{\n        <{ref_self}Self as IntoIterator>::into_iter(self)\n    }}\n}}\n\",\n                        self_ty_without_ref = snippet(cx, self_ty_without_ref.ty.span, \"..\"),\n                        ref_self = mtbl.ref_prefix_str(),\n                        iter_ty = snippet(cx, iter_assoc_span, \"..\"),\n                    );\n\n                    diag.span_suggestion_verbose(\n                        item.span.shrink_to_lo(),\n                        format!(\"consider implementing `{expected_method_name}`\"),\n                        sugg,\n                        // Just like iter_without_into_iter, this suggestion is on a best effort basis\n                        // and requires potentially adding lifetimes or moving them around.\n                        Applicability::Unspecified,\n                    );\n                },\n            );\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {\n        let item_did = item.owner_id.to_def_id();\n        let (borrow_prefix, expected_implicit_self) = match item.ident.name {\n            sym::iter => (\"&\", ImplicitSelfKind::RefImm),\n            sym::iter_mut => (\"&mut \", ImplicitSelfKind::RefMut),\n            _ => return,\n        };\n\n        if !item.span.in_external_macro(cx.sess().source_map())\n            && let ImplItemKind::Fn(sig, _) = item.kind\n            && let FnRetTy::Return(ret) = sig.decl.output\n            && is_nameable_in_impl_trait(ret)\n            && cx.tcx.generics_of(item_did).is_own_empty()\n            && sig.decl.implicit_self == expected_implicit_self\n            && sig.decl.inputs.len() == 1\n            && let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id())\n            && imp.of_trait.is_none()\n            && let sig = cx.tcx.liberate_late_bound_regions(\n                item_did,\n                cx.tcx.fn_sig(item_did).instantiate_identity()\n            )\n            && let ref_ty = sig.inputs()[0]\n            && let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator)\n            && let Some(iterator_did) = cx.tcx.get_diagnostic_item(sym::Iterator)\n            && let ret_ty = sig.output()\n            // Order is important here, we need to check that the `fn iter` return type actually implements `IntoIterator`\n            // *before* normalizing `<_ as IntoIterator>::Item` (otherwise make_normalized_projection ICEs)\n            && implements_trait(cx, ret_ty, iterator_did, &[])\n            && let Some(iter_ty) = make_normalized_projection(\n                cx.tcx,\n                cx.typing_env(),\n                iterator_did,\n                sym::Item,\n                [ret_ty],\n            )\n            // Only lint if the `IntoIterator` impl doesn't actually exist\n            && !implements_trait(cx, ref_ty, into_iter_did, &[])\n            && is_ty_exported(cx, ref_ty.peel_refs())\n        {\n            let self_ty_snippet = format!(\"{borrow_prefix}{}\", snippet(cx, imp.self_ty.span, \"..\"));\n\n            span_lint_and_then(\n                cx,\n                ITER_WITHOUT_INTO_ITER,\n                item.span,\n                format!(\n                    \"`{}` method without an `IntoIterator` impl for `{self_ty_snippet}`\",\n                    item.ident\n                ),\n                |diag| {\n                    // Get the lower span of the `impl` block, and insert the suggestion right before it:\n                    // impl X {\n                    // ^   fn iter(&self) -> impl IntoIterator { ... }\n                    // }\n                    let span_behind_impl = cx\n                        .tcx\n                        .def_span(cx.tcx.parent_hir_id(item.hir_id()).owner.def_id)\n                        .shrink_to_lo();\n\n                    let sugg = format!(\n                        \"\nimpl IntoIterator for {self_ty_snippet} {{\n    type Item = {iter_ty};\n    type IntoIter = {ret_ty};\n    fn into_iter(self) -> Self::IntoIter {{\n        self.iter()\n    }}\n}}\n\"\n                    );\n                    diag.span_suggestion_verbose(\n                        span_behind_impl,\n                        format!(\"consider implementing `IntoIterator` for `{self_ty_snippet}`\"),\n                        sugg,\n                        // Suggestion is on a best effort basis, might need some adjustments by the user\n                        // such as adding some lifetimes in the associated types, or importing types.\n                        Applicability::Unspecified,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/large_const_arrays.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{BytePos, Pos, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for large `const` arrays that should\n    /// be defined as `static` instead.\n    ///\n    /// ### Why is this bad?\n    /// Performance: const variables are inlined upon use.\n    /// Static items result in only one instance and has a fixed location in memory.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// pub const a = [0u32; 1_000_000];\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// pub static a = [0u32; 1_000_000];\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub LARGE_CONST_ARRAYS,\n    perf,\n    \"large non-scalar const array may cause performance overhead\"\n}\n\nimpl_lint_pass!(LargeConstArrays => [LARGE_CONST_ARRAYS]);\n\npub struct LargeConstArrays {\n    maximum_allowed_size: u64,\n}\n\nimpl LargeConstArrays {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            maximum_allowed_size: conf.array_size_threshold,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for LargeConstArrays {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Const(ident, generics, _, _) = &item.kind\n            // Since static items may not have generics, skip generic const items.\n            // FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it\n            // doesn't account for empty where-clauses that only consist of keyword `where` IINM.\n            && generics.params.is_empty() && !generics.has_where_clause_predicates\n            && !item.span.from_expansion()\n            && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n            && let ty::Array(element_type, cst) = ty.kind()\n            && let Some(element_count) = cx.tcx\n                .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_target_usize(cx.tcx)\n            && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())\n            && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)\n        {\n            let hi_pos = ident.span.lo() - BytePos::from_usize(1);\n            let sugg_span = Span::new(\n                hi_pos - BytePos::from_usize(\"const\".len()),\n                hi_pos,\n                item.span.ctxt(),\n                item.span.parent(),\n            );\n            span_lint_and_then(\n                cx,\n                LARGE_CONST_ARRAYS,\n                item.span,\n                \"large array defined as const\",\n                |diag| {\n                    diag.span_suggestion(\n                        sugg_span,\n                        \"make this a static item\",\n                        \"static\",\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/large_enum_variant.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_no_std_crate;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_copy};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for large size differences between variants on\n    /// `enum`s.\n    ///\n    /// ### Why is this bad?\n    /// Enum size is bounded by the largest variant. Having one\n    /// large variant can penalize the memory layout of that enum.\n    ///\n    /// ### Known problems\n    /// This lint obviously cannot take the distribution of\n    /// variants in your running program into account. It is possible that the\n    /// smaller variants make up less than 1% of all instances, in which case\n    /// the overhead is negligible and the boxing is counter-productive. Always\n    /// measure the change this lint suggests.\n    ///\n    /// For types that implement `Copy`, the suggestion to `Box` a variant's\n    /// data would require removing the trait impl. The types can of course\n    /// still be `Clone`, but that is worse ergonomically. Depending on the\n    /// use case it may be possible to store the large data in an auxiliary\n    /// structure (e.g. Arena or ECS).\n    ///\n    /// The lint will ignore the impact of generic types to the type layout by\n    /// assuming every type parameter is zero-sized. Depending on your use case,\n    /// this may lead to a false positive.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum Test {\n    ///     A(i32),\n    ///     B([i32; 8000]),\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// // Possibly better\n    /// enum Test2 {\n    ///     A(i32),\n    ///     B(Box<[i32; 8000]>),\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub LARGE_ENUM_VARIANT,\n    perf,\n    \"large size difference between variants on an enum\"\n}\n\nimpl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);\n\npub struct LargeEnumVariant {\n    maximum_size_difference_allowed: u64,\n}\n\nimpl LargeEnumVariant {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            maximum_size_difference_allowed: conf.enum_variant_size_threshold,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {\n        if let ItemKind::Enum(ident, _, ref def) = item.kind\n            && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n            && let ty::Adt(adt, subst) = ty.kind()\n            && adt.variants().len() > 1\n            && !item.span.in_external_macro(cx.tcx.sess.source_map())\n        {\n            let variants_size = AdtVariantInfo::new(cx, *adt, subst);\n\n            let mut difference = variants_size[0].size - variants_size[1].size;\n            if difference > self.maximum_size_difference_allowed {\n                let help_text = \"consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\";\n                span_lint_and_then(\n                    cx,\n                    LARGE_ENUM_VARIANT,\n                    item.span,\n                    \"large size difference between variants\",\n                    |diag| {\n                        diag.span_label(\n                            item.span,\n                            format!(\"the entire enum is at least {} bytes\", approx_ty_size(cx, ty)),\n                        );\n                        diag.span_label(\n                            def.variants[variants_size[0].ind].span,\n                            format!(\"the largest variant contains at least {} bytes\", variants_size[0].size),\n                        );\n                        diag.span_label(\n                            def.variants[variants_size[1].ind].span,\n                            if variants_size[1].fields_size.is_empty() {\n                                \"the second-largest variant carries no data at all\".to_owned()\n                            } else {\n                                format!(\n                                    \"the second-largest variant contains at least {} bytes\",\n                                    variants_size[1].size\n                                )\n                            },\n                        );\n\n                        let fields = def.variants[variants_size[0].ind].data.fields();\n                        let mut applicability = Applicability::MaybeIncorrect;\n                        if is_copy(cx, ty) || maybe_copy(cx, ty) {\n                            diag.span_note(\n                                ident.span,\n                                \"boxing a variant would require the type no longer be `Copy`\",\n                            );\n                        } else if !is_no_std_crate(cx) {\n                            let sugg: Vec<(Span, String)> = variants_size[0]\n                                .fields_size\n                                .iter()\n                                .rev()\n                                .map_while(|&(ind, size)| {\n                                    if difference > self.maximum_size_difference_allowed {\n                                        difference = difference.saturating_sub(size);\n                                        Some((\n                                            fields[ind].ty.span,\n                                            format!(\n                                                \"Box<{}>\",\n                                                snippet_with_applicability(\n                                                    cx,\n                                                    fields[ind].ty.span,\n                                                    \"..\",\n                                                    &mut applicability\n                                                )\n                                                .into_owned()\n                                            ),\n                                        ))\n                                    } else {\n                                        None\n                                    }\n                                })\n                                .collect();\n\n                            if !sugg.is_empty() {\n                                diag.multipart_suggestion(help_text, sugg, Applicability::MaybeIncorrect);\n                                return;\n                            }\n                        }\n                        diag.span_help(def.variants[variants_size[0].ind].span, help_text);\n                    },\n                );\n            }\n        }\n    }\n}\n\nfn maybe_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    if let ty::Adt(_def, args) = ty.kind()\n        && args.types().next().is_some()\n        && let Some(copy_trait) = cx.tcx.lang_items().copy_trait()\n    {\n        return cx.tcx.non_blanket_impls_for_ty(copy_trait, ty).next().is_some();\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/large_futures.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::implements_trait;\nuse rustc_abi::Size;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem, MatchSource};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// It checks for the size of a `Future` created by `async fn` or `async {}`.\n    ///\n    /// ### Why is this bad?\n    /// Due to the current [unideal implementation](https://github.com/rust-lang/rust/issues/69826) of `Coroutine`,\n    /// large size of a `Future` may cause stack overflows.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// async fn large_future(_x: [u8; 16 * 1024]) {}\n    ///\n    /// pub async fn trigger() {\n    ///     large_future([0u8; 16 * 1024]).await;\n    /// }\n    /// ```\n    ///\n    /// `Box::pin` the big future instead.\n    ///\n    /// ```no_run\n    /// async fn large_future(_x: [u8; 16 * 1024]) {}\n    ///\n    /// pub async fn trigger() {\n    ///     Box::pin(large_future([0u8; 16 * 1024])).await;\n    /// }\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub LARGE_FUTURES,\n    pedantic,\n    \"large future may lead to unexpected stack overflows\"\n}\n\nimpl_lint_pass!(LargeFuture => [LARGE_FUTURES]);\n\npub struct LargeFuture {\n    future_size_threshold: u64,\n}\n\nimpl LargeFuture {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            future_size_threshold: conf.future_size_threshold,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for LargeFuture {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Match(scrutinee, _, MatchSource::AwaitDesugar) = expr.kind\n            && let ExprKind::Call(func, [arg]) = scrutinee.kind\n            && let ExprKind::Path(qpath) = func.kind\n            && cx.tcx.qpath_is_lang_item(qpath, LangItem::IntoFutureIntoFuture)\n            && !expr.span.from_expansion()\n            && let ty = cx.typeck_results().expr_ty(arg)\n            && let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait()\n            && implements_trait(cx, ty, future_trait_def_id, &[])\n            && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty))\n            && let size = layout.layout.size()\n            && size >= Size::from_bytes(self.future_size_threshold)\n        {\n            span_lint_and_sugg(\n                cx,\n                LARGE_FUTURES,\n                arg.span,\n                format!(\"large future with a size of {} bytes\", size.bytes()),\n                \"consider `Box::pin` on it\",\n                format!(\"Box::pin({})\", snippet(cx, arg.span, \"..\")),\n                Applicability::Unspecified,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/large_include_file.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::root_macro_call_first_node;\nuse clippy_utils::source::snippet_opt;\nuse clippy_utils::sym;\nuse rustc_ast::{AttrArgs, AttrItemKind, AttrKind, Attribute, LitKind};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the inclusion of large files via `include_bytes!()`\n    /// or `include_str!()`.\n    ///\n    /// ### Why restrict this?\n    /// Including large files can undesirably increase the size of the binary produced by the compiler.\n    /// This lint may be used to catch mistakes where an unexpectedly large file is included, or\n    /// temporarily to obtain a list of all large files.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let included_str = include_str!(\"very_large_file.txt\");\n    /// let included_bytes = include_bytes!(\"very_large_file.txt\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// use std::fs;\n    ///\n    /// // You can load the file at runtime\n    /// let string = fs::read_to_string(\"very_large_file.txt\")?;\n    /// let bytes = fs::read(\"very_large_file.txt\")?;\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub LARGE_INCLUDE_FILE,\n    restriction,\n    \"including a large file\"\n}\n\nimpl_lint_pass!(LargeIncludeFile => [LARGE_INCLUDE_FILE]);\n\npub struct LargeIncludeFile {\n    max_file_size: u64,\n}\n\nimpl LargeIncludeFile {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            max_file_size: conf.max_include_file_size,\n        }\n    }\n}\n\nimpl LateLintPass<'_> for LargeIncludeFile {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        if let ExprKind::Lit(lit) = &expr.kind\n            && let len = match &lit.node {\n                // include_bytes\n                LitKind::ByteStr(bstr, _) => bstr.as_byte_str().len(),\n                // include_str\n                LitKind::Str(sym, _) => sym.as_str().len(),\n                _ => return,\n            }\n            && len as u64 > self.max_file_size\n            && let Some(macro_call) = root_macro_call_first_node(cx, expr)\n            && let Some(macro_name) = cx.tcx.get_diagnostic_name(macro_call.def_id)\n            && matches!(macro_name, sym::include_bytes_macro | sym::include_str_macro)\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                LARGE_INCLUDE_FILE,\n                expr.span.source_callsite(),\n                \"attempted to include a large file\",\n                |diag| {\n                    diag.note(format!(\n                        \"the configuration allows a maximum size of {} bytes\",\n                        self.max_file_size\n                    ));\n                },\n            );\n        }\n    }\n}\n\nimpl EarlyLintPass for LargeIncludeFile {\n    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {\n        if !attr.span.from_expansion()\n            // Currently, rustc limits the usage of macro at the top-level of attributes,\n            // so we don't need to recurse into each level.\n            && let AttrKind::Normal(ref item) = attr.kind\n            && let Some(doc) = attr.doc_str()\n            && doc.as_str().len() as u64 > self.max_file_size\n            && let AttrItemKind::Unparsed(AttrArgs::Eq { expr: meta, .. }) = &item.item.args\n            && !attr.span.contains(meta.span)\n            // Since the `include_str` is already expanded at this point, we can only take the\n            // whole attribute snippet and then modify for our suggestion.\n            && let Some(snippet) = snippet_opt(cx, attr.span)\n            // We cannot remove this because a `#[doc = include_str!(\"...\")]` attribute can\n            // occupy several lines.\n            && let Some(start) = snippet.find('[')\n            && let Some(end) = snippet.rfind(']')\n            && let snippet = &snippet[start + 1..end]\n            // We check that the expansion actually comes from `include_str!` and not just from\n            // another macro.\n            && let Some(sub_snippet) = snippet.trim().strip_prefix(\"doc\")\n            && let Some(sub_snippet) = sub_snippet.trim().strip_prefix(\"=\")\n            && let sub_snippet = sub_snippet.trim()\n            && (sub_snippet.starts_with(\"include_str!\") || sub_snippet.starts_with(\"include_bytes!\"))\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                LARGE_INCLUDE_FILE,\n                attr.span,\n                \"attempted to include a large file\",\n                |diag| {\n                    diag.note(format!(\n                        \"the configuration allows a maximum size of {} bytes\",\n                        self.max_file_size\n                    ));\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/large_stack_arrays.rs",
    "content": "use std::num::Saturating;\n\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::macro_backtrace;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{is_from_proc_macro, sym};\nuse rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for local arrays that may be too large.\n    ///\n    /// ### Why is this bad?\n    /// Large local arrays may cause stack overflow.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let a = [0u32; 1_000_000];\n    /// ```\n    #[clippy::version = \"1.41.0\"]\n    pub LARGE_STACK_ARRAYS,\n    pedantic,\n    \"allocating large arrays on stack may cause stack overflow\"\n}\n\nimpl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]);\n\npub struct LargeStackArrays {\n    maximum_allowed_size: u64,\n    prev_vec_macro_callsite: Option<Span>,\n    const_item_counter: Saturating<u16>,\n}\n\nimpl LargeStackArrays {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            maximum_allowed_size: conf.array_size_threshold,\n            prev_vec_macro_callsite: None,\n            const_item_counter: Saturating(0),\n        }\n    }\n\n    /// Check if the given span of an expr is already in a `vec!` call.\n    fn is_from_vec_macro(&mut self, cx: &LateContext<'_>, span: Span) -> bool {\n        // First, we check if this is span is within the last encountered `vec!` macro's root callsite.\n        self.prev_vec_macro_callsite\n            .is_some_and(|vec_mac| vec_mac.contains(span))\n            || {\n                // Then, we try backtracking the macro expansions, to see if there's a `vec!` macro,\n                // and update the `prev_vec_macro_callsite`.\n                let res = macro_backtrace(span).any(|mac| cx.tcx.is_diagnostic_item(sym::vec_macro, mac.def_id));\n                if res {\n                    self.prev_vec_macro_callsite = Some(span.source_callsite());\n                }\n                res\n            }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for LargeStackArrays {\n    fn check_item(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if matches!(item.kind, ItemKind::Static(..) | ItemKind::Const(..)) {\n            self.const_item_counter += 1;\n        }\n    }\n\n    fn check_item_post(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if matches!(item.kind, ItemKind::Static(..) | ItemKind::Const(..)) {\n            self.const_item_counter -= 1;\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if self.const_item_counter.0 == 0\n            && let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind\n            && !self.is_from_vec_macro(cx, expr.span)\n            && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind()\n            && let Some(element_count) = cst.try_to_target_usize(cx.tcx)\n            && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())\n            && !cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, node)| {\n                matches!(\n                    node,\n                    Node::Item(Item {\n                        kind: ItemKind::Static(..),\n                        ..\n                    })\n                )\n            })\n            && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)\n        {\n            // libtest might generate a large array containing the test cases, and no span will be associated\n            // to it. In this case it is better not to complain.\n            //\n            // Note that this condition is not checked explicitly by a unit test. Do not remove it without\n            // ensuring that <https://github.com/rust-lang/rust-clippy/issues/13774> stays fixed.\n            if expr.span.is_dummy() {\n                return;\n            }\n\n            span_lint_and_then(\n                cx,\n                LARGE_STACK_ARRAYS,\n                expr.span,\n                format!(\n                    \"allocating a local array larger than {} bytes\",\n                    self.maximum_allowed_size\n                ),\n                |diag| {\n                    if !might_be_expanded(cx, expr) {\n                        diag.help(format!(\n                            \"consider allocating on the heap with `vec!{}.into_boxed_slice()`\",\n                            snippet(cx, expr.span, \"[...]\")\n                        ));\n                    }\n                },\n            );\n        }\n    }\n}\n\n/// Only giving help messages if the expr does not contains macro expanded codes.\nfn might_be_expanded<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {\n    /// Check if the span of `ConstArg` of a repeat expression is within the expr's span,\n    /// if not, meaning this repeat expr is definitely from some proc-macro.\n    ///\n    /// This is a fail-safe to a case where even the `is_from_proc_macro` is unable to determain the\n    /// correct result.\n    fn repeat_expr_might_be_expanded(expr: &Expr<'_>) -> bool {\n        let ExprKind::Repeat(_, len_ct) = expr.kind else {\n            return false;\n        };\n        !expr.span.contains(len_ct.span)\n    }\n\n    expr.span.from_expansion() || is_from_proc_macro(cx, expr) || repeat_expr_might_be_expanded(expr)\n}\n"
  },
  {
    "path": "clippy_lints/src/large_stack_frames.rs",
    "content": "use std::{fmt, ops};\n\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{HasSession, SpanRangeExt};\nuse clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_in_test};\nuse rustc_errors::Diag;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, FnDecl};\nuse rustc_lexer::is_ident;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, SyntaxContext};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions that use a lot of stack space.\n    ///\n    /// This often happens when constructing a large type, such as an array with a lot of elements,\n    /// or constructing *many* smaller-but-still-large structs, or copying around a lot of large types.\n    ///\n    /// This lint is a more general version of [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/#large_stack_arrays)\n    /// that is intended to look at functions as a whole instead of only individual array expressions inside of a function.\n    ///\n    /// ### Why is this bad?\n    /// The stack region of memory is very limited in size (usually *much* smaller than the heap) and attempting to\n    /// use too much will result in a stack overflow and crash the program.\n    /// To avoid this, you should consider allocating large types on the heap instead (e.g. by boxing them).\n    ///\n    /// Keep in mind that the code path to construction of large types does not even need to be reachable;\n    /// it purely needs to *exist* inside of the function to contribute to the stack size.\n    /// For example, this causes a stack overflow even though the branch is unreachable:\n    /// ```rust,ignore\n    /// fn main() {\n    ///     if false {\n    ///         let x = [0u8; 10000000]; // 10 MB stack array\n    ///         black_box(&x);\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// ### Known issues\n    /// False positives. The stack size that clippy sees is an estimated value and can be vastly different\n    /// from the actual stack usage after optimizations passes have run (especially true in release mode).\n    /// Modern compilers are very smart and are able to optimize away a lot of unnecessary stack allocations.\n    /// In debug mode however, it is usually more accurate.\n    ///\n    /// This lint works by summing up the size of all variables that the user typed, variables that were\n    /// implicitly introduced by the compiler for temporaries, function arguments and the return value,\n    /// and comparing them against a (configurable, but high-by-default).\n    ///\n    /// ### Example\n    /// This function creates four 500 KB arrays on the stack. Quite big but just small enough to not trigger `large_stack_arrays`.\n    /// However, looking at the function as a whole, it's clear that this uses a lot of stack space.\n    /// ```no_run\n    /// struct QuiteLargeType([u8; 500_000]);\n    /// fn foo() {\n    ///     // ... some function that uses a lot of stack space ...\n    ///     let _x1 = QuiteLargeType([0; 500_000]);\n    ///     let _x2 = QuiteLargeType([0; 500_000]);\n    ///     let _x3 = QuiteLargeType([0; 500_000]);\n    ///     let _x4 = QuiteLargeType([0; 500_000]);\n    /// }\n    /// ```\n    ///\n    /// Instead of doing this, allocate the arrays on the heap.\n    /// This currently requires going through a `Vec` first and then converting it to a `Box`:\n    /// ```no_run\n    /// struct NotSoLargeType(Box<[u8]>);\n    ///\n    /// fn foo() {\n    ///     let _x1 = NotSoLargeType(vec![0; 500_000].into_boxed_slice());\n    /// //                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  Now heap allocated.\n    /// //                                                                The size of `NotSoLargeType` is 16 bytes.\n    /// //  ...\n    /// }\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub LARGE_STACK_FRAMES,\n    nursery,\n    \"checks for functions that allocate a lot of stack space\"\n}\n\nimpl_lint_pass!(LargeStackFrames => [LARGE_STACK_FRAMES]);\n\npub struct LargeStackFrames {\n    maximum_allowed_size: u64,\n    allow_large_stack_frames_in_tests: bool,\n}\n\nimpl LargeStackFrames {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            maximum_allowed_size: conf.stack_size_threshold,\n            allow_large_stack_frames_in_tests: conf.allow_large_stack_frames_in_tests,\n        }\n    }\n}\n\n#[derive(Copy, Clone)]\nenum Space {\n    Used(u64),\n    Overflow,\n}\n\nimpl Space {\n    pub fn exceeds_limit(self, limit: u64) -> bool {\n        match self {\n            Self::Used(used) => used > limit,\n            Self::Overflow => true,\n        }\n    }\n}\n\nimpl fmt::Display for Space {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Space::Used(1) => write!(f, \"1 byte\"),\n            Space::Used(n) => write!(f, \"{n} bytes\"),\n            Space::Overflow => write!(f, \"over 2⁶⁴-1 bytes\"),\n        }\n    }\n}\n\nimpl ops::Add<u64> for Space {\n    type Output = Self;\n    fn add(self, rhs: u64) -> Self {\n        match self {\n            Self::Used(lhs) => match lhs.checked_add(rhs) {\n                Some(sum) => Self::Used(sum),\n                None => Self::Overflow,\n            },\n            Self::Overflow => self,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for LargeStackFrames {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        fn_kind: FnKind<'tcx>,\n        _: &'tcx FnDecl<'tcx>,\n        _: &'tcx Body<'tcx>,\n        entire_fn_span: Span,\n        local_def_id: LocalDefId,\n    ) {\n        let def_id = local_def_id.to_def_id();\n        // Building MIR for `fn`s with unsatisfiable preds results in ICE.\n        if fn_has_unsatisfiable_preds(cx, def_id) {\n            return;\n        }\n\n        let mir = cx.tcx.optimized_mir(def_id);\n        let typing_env = mir.typing_env(cx.tcx);\n\n        let sizes_of_locals = mir\n            .local_decls\n            .iter()\n            .filter_map(|local| {\n                let layout = cx.tcx.layout_of(typing_env.as_query_input(local.ty)).ok()?;\n                Some((local, layout.size.bytes()))\n            })\n            .collect::<Vec<_>>();\n\n        let frame_size = sizes_of_locals\n            .iter()\n            .fold(Space::Used(0), |sum, (_, size)| sum + *size);\n\n        let limit = self.maximum_allowed_size;\n        if frame_size.exceeds_limit(limit) {\n            // Point at just the function name if possible, because lints that span\n            // the entire body and don't have to are less legible.\n            let (fn_span, fn_name) = match fn_kind {\n                FnKind::ItemFn(ident, _, _) => (ident.span, format!(\"function `{}`\", ident.name)),\n                FnKind::Method(ident, _) => (ident.span, format!(\"method `{}`\", ident.name)),\n                FnKind::Closure => (entire_fn_span, \"closure\".to_string()),\n            };\n\n            // Don't lint inside tests if configured to not do so.\n            if self.allow_large_stack_frames_in_tests && is_in_test(cx.tcx, cx.tcx.local_def_id_to_hir_id(local_def_id))\n            {\n                return;\n            }\n\n            let explain_lint = |diag: &mut Diag<'_, ()>, ctxt: SyntaxContext| {\n                // Point out the largest individual contribution to this size, because\n                // it is the most likely to be unintentionally large.\n                if let Some((local, size)) = sizes_of_locals.iter().max_by_key(|&(_, size)| size)\n                    && let local_span = local.source_info.span\n                    && local_span.ctxt() == ctxt\n                {\n                    let size = Space::Used(*size); // pluralizes for us\n                    let ty = local.ty;\n\n                    // TODO: Is there a cleaner, robust way to ask this question?\n                    // The obvious `LocalDecl::is_user_variable()` panics on \"unwrapping cross-crate data\",\n                    // and that doesn't get us the true name in scope rather than the span text either.\n                    if let Some(name) = local_span.get_source_text(cx)\n                        && is_ident(&name)\n                    {\n                        // If the local is an ordinary named variable,\n                        // print its name rather than relying solely on the span.\n                        diag.span_label(\n                            local_span,\n                            format!(\"`{name}` is the largest part, at {size} for type `{ty}`\"),\n                        );\n                    } else {\n                        diag.span_label(\n                            local_span,\n                            format!(\"this is the largest part, at {size} for type `{ty}`\"),\n                        );\n                    }\n                }\n\n                // Explain why we are linting this and not other functions.\n                diag.note(format!(\n                    \"{frame_size} is larger than Clippy's configured `stack-size-threshold` of {limit}\"\n                ));\n\n                // Explain why the user should care, briefly.\n                diag.note_once(\n                    \"allocating large amounts of stack space can overflow the stack \\\n                        and cause the program to abort\",\n                );\n            };\n\n            if fn_span.from_expansion() {\n                // Don't lint on the main function generated by `--test` target\n                if cx.sess().is_test_crate() && is_entrypoint_fn(cx, local_def_id.to_def_id()) {\n                    return;\n                }\n\n                let is_from_external_macro = fn_span.in_external_macro(cx.sess().source_map());\n                span_lint_and_then(\n                    cx,\n                    LARGE_STACK_FRAMES,\n                    fn_span.source_callsite(),\n                    format!(\n                        \"{} generated by this macro may allocate a lot of stack space\",\n                        if is_from_external_macro {\n                            cx.tcx.def_descr(local_def_id.into())\n                        } else {\n                            fn_name.as_str()\n                        }\n                    ),\n                    |diag| {\n                        if is_from_external_macro {\n                            return;\n                        }\n\n                        diag.span_label(\n                            fn_span,\n                            format!(\n                                \"this {} has a stack frame size of {frame_size}\",\n                                cx.tcx.def_descr(local_def_id.into())\n                            ),\n                        );\n\n                        explain_lint(diag, fn_span.ctxt());\n                    },\n                );\n                return;\n            }\n\n            span_lint_and_then(\n                cx,\n                LARGE_STACK_FRAMES,\n                fn_span,\n                format!(\"this function may allocate {frame_size} on the stack\"),\n                |diag| {\n                    explain_lint(diag, SyntaxContext::root());\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/legacy_numeric_constants.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{is_from_proc_macro, sym};\nuse hir::def_id::DefId;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Symbol;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `<integer>::max_value()`, `std::<integer>::MAX`,\n    /// `std::<float>::EPSILON`, etc.\n    ///\n    /// ### Why is this bad?\n    /// All of these have been superseded by the associated constants on their respective types,\n    /// such as `i128::MAX`. These legacy items may be deprecated in a future version of rust.\n    ///\n    /// ### Example\n    /// ```rust\n    /// let eps = std::f32::EPSILON;\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// let eps = f32::EPSILON;\n    /// ```\n    #[clippy::version = \"1.79.0\"]\n    pub LEGACY_NUMERIC_CONSTANTS,\n    style,\n    \"checks for usage of legacy std numeric constants and methods\"\n}\n\nimpl_lint_pass!(LegacyNumericConstants => [LEGACY_NUMERIC_CONSTANTS]);\n\npub struct LegacyNumericConstants {\n    msrv: Msrv,\n}\n\nimpl LegacyNumericConstants {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        // Integer modules are \"TBD\" deprecated, and the contents are too,\n        // so lint on the `use` statement directly.\n        if let ItemKind::Use(path, kind @ (UseKind::Single(_) | UseKind::Glob)) = item.kind\n            && !item.span.in_external_macro(cx.sess().source_map())\n            // use `present_items` because it could be in either type_ns or value_ns\n            && let Some(res) = path.res.present_items().next()\n            && let Some(def_id) = res.opt_def_id()\n            && self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS)\n        {\n            let module = if is_integer_module(cx, def_id) {\n                true\n            } else if is_numeric_const(cx, def_id) {\n                false\n            } else {\n                return;\n            };\n\n            span_lint_and_then(\n                cx,\n                LEGACY_NUMERIC_CONSTANTS,\n                path.span,\n                if module {\n                    \"importing legacy numeric constants\"\n                } else {\n                    \"importing a legacy numeric constant\"\n                },\n                |diag| {\n                    if let UseKind::Single(ident) = kind\n                        && ident.name == kw::Underscore\n                    {\n                        diag.help(\"remove this import\");\n                        return;\n                    }\n\n                    let def_path = cx.get_def_path(def_id);\n\n                    if module && let [.., module_name] = &*def_path {\n                        if kind == UseKind::Glob {\n                            diag.help(format!(\"remove this import and use associated constants `{module_name}::<CONST>` from the primitive type instead\"));\n                        } else {\n                            diag.help(\"remove this import\").note(format!(\n                                \"then `{module_name}::<CONST>` will resolve to the respective associated constant\"\n                            ));\n                        }\n                    } else if let [.., module_name, name] = &*def_path {\n                        diag.help(\n                            format!(\"remove this import and use the associated constant `{module_name}::{name}` from the primitive type instead\")\n                        );\n                    }\n                },\n            );\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {\n        // `std::<integer>::<CONST>` check\n        let (sugg, msg) = if let ExprKind::Path(qpath) = &expr.kind\n            && let QPath::Resolved(None, path) = qpath\n            && let Some(def_id) = path.res.opt_def_id()\n            && is_numeric_const(cx, def_id)\n            && let [.., mod_name, name] = &*cx.get_def_path(def_id)\n            // Skip linting if this usage looks identical to the associated constant,\n            // since this would only require removing a `use` import (which is already linted).\n            && !is_numeric_const_path_canonical(path, [*mod_name, *name])\n        {\n            (format!(\"{mod_name}::{name}\"), \"usage of a legacy numeric constant\")\n        // `<integer>::xxx_value` check\n        } else if let ExprKind::Call(func, []) = &expr.kind\n            && let ExprKind::Path(qpath) = &func.kind\n            && let QPath::TypeRelative(ty, last_segment) = qpath\n            && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id()\n            && is_integer_method(cx, def_id)\n            && let Some(mod_name) = ty.span.get_source_text(cx)\n            && ty.span.eq_ctxt(last_segment.ident.span)\n        {\n            let name = last_segment.ident.name.as_str()[..=2].to_ascii_uppercase();\n            (format!(\"{mod_name}::{name}\"), \"usage of a legacy numeric method\")\n        } else {\n            return;\n        };\n\n        if !expr.span.in_external_macro(cx.sess().source_map())\n            && self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS)\n            && !is_from_proc_macro(cx, expr)\n        {\n            span_lint_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.span, msg, |diag| {\n                diag.span_suggestion_verbose(\n                    expr.span,\n                    \"use the associated constant instead\",\n                    sugg,\n                    Applicability::MaybeIncorrect,\n                );\n            });\n        }\n    }\n}\n\nfn is_integer_module(cx: &LateContext<'_>, did: DefId) -> bool {\n    matches!(\n        cx.tcx.get_diagnostic_name(did),\n        Some(\n            sym::isize_legacy_mod\n                | sym::i128_legacy_mod\n                | sym::i64_legacy_mod\n                | sym::i32_legacy_mod\n                | sym::i16_legacy_mod\n                | sym::i8_legacy_mod\n                | sym::usize_legacy_mod\n                | sym::u128_legacy_mod\n                | sym::u64_legacy_mod\n                | sym::u32_legacy_mod\n                | sym::u16_legacy_mod\n                | sym::u8_legacy_mod\n        )\n    )\n}\n\nfn is_numeric_const(cx: &LateContext<'_>, did: DefId) -> bool {\n    matches!(\n        cx.tcx.get_diagnostic_name(did),\n        Some(\n            sym::isize_legacy_const_max\n                | sym::isize_legacy_const_min\n                | sym::i128_legacy_const_max\n                | sym::i128_legacy_const_min\n                | sym::i16_legacy_const_max\n                | sym::i16_legacy_const_min\n                | sym::i32_legacy_const_max\n                | sym::i32_legacy_const_min\n                | sym::i64_legacy_const_max\n                | sym::i64_legacy_const_min\n                | sym::i8_legacy_const_max\n                | sym::i8_legacy_const_min\n                | sym::usize_legacy_const_max\n                | sym::usize_legacy_const_min\n                | sym::u128_legacy_const_max\n                | sym::u128_legacy_const_min\n                | sym::u16_legacy_const_max\n                | sym::u16_legacy_const_min\n                | sym::u32_legacy_const_max\n                | sym::u32_legacy_const_min\n                | sym::u64_legacy_const_max\n                | sym::u64_legacy_const_min\n                | sym::u8_legacy_const_max\n                | sym::u8_legacy_const_min\n                | sym::f32_legacy_const_digits\n                | sym::f32_legacy_const_epsilon\n                | sym::f32_legacy_const_infinity\n                | sym::f32_legacy_const_mantissa_dig\n                | sym::f32_legacy_const_max\n                | sym::f32_legacy_const_max_10_exp\n                | sym::f32_legacy_const_max_exp\n                | sym::f32_legacy_const_min\n                | sym::f32_legacy_const_min_10_exp\n                | sym::f32_legacy_const_min_exp\n                | sym::f32_legacy_const_min_positive\n                | sym::f32_legacy_const_nan\n                | sym::f32_legacy_const_neg_infinity\n                | sym::f32_legacy_const_radix\n                | sym::f64_legacy_const_digits\n                | sym::f64_legacy_const_epsilon\n                | sym::f64_legacy_const_infinity\n                | sym::f64_legacy_const_mantissa_dig\n                | sym::f64_legacy_const_max\n                | sym::f64_legacy_const_max_10_exp\n                | sym::f64_legacy_const_max_exp\n                | sym::f64_legacy_const_min\n                | sym::f64_legacy_const_min_10_exp\n                | sym::f64_legacy_const_min_exp\n                | sym::f64_legacy_const_min_positive\n                | sym::f64_legacy_const_nan\n                | sym::f64_legacy_const_neg_infinity\n                | sym::f64_legacy_const_radix\n        )\n    )\n}\n\n// Whether path expression looks like `i32::MAX`\nfn is_numeric_const_path_canonical(expr_path: &hir::Path<'_>, [mod_name, name]: [Symbol; 2]) -> bool {\n    let [\n        hir::PathSegment {\n            ident: one, args: None, ..\n        },\n        hir::PathSegment {\n            ident: two, args: None, ..\n        },\n    ] = expr_path.segments\n    else {\n        return false;\n    };\n\n    one.name == mod_name && two.name == name\n}\n\nfn is_integer_method(cx: &LateContext<'_>, did: DefId) -> bool {\n    matches!(\n        cx.tcx.get_diagnostic_name(did),\n        Some(\n            sym::isize_legacy_fn_max_value\n                | sym::isize_legacy_fn_min_value\n                | sym::i128_legacy_fn_max_value\n                | sym::i128_legacy_fn_min_value\n                | sym::i16_legacy_fn_max_value\n                | sym::i16_legacy_fn_min_value\n                | sym::i32_legacy_fn_max_value\n                | sym::i32_legacy_fn_min_value\n                | sym::i64_legacy_fn_max_value\n                | sym::i64_legacy_fn_min_value\n                | sym::i8_legacy_fn_max_value\n                | sym::i8_legacy_fn_min_value\n                | sym::usize_legacy_fn_max_value\n                | sym::usize_legacy_fn_min_value\n                | sym::u128_legacy_fn_max_value\n                | sym::u128_legacy_fn_min_value\n                | sym::u16_legacy_fn_max_value\n                | sym::u16_legacy_fn_min_value\n                | sym::u32_legacy_fn_max_value\n                | sym::u32_legacy_fn_min_value\n                | sym::u64_legacy_fn_max_value\n                | sym::u64_legacy_fn_min_value\n                | sym::u8_legacy_fn_max_value\n                | sym::u8_legacy_fn_min_value\n        )\n    )\n}\n"
  },
  {
    "path": "clippy_lints/src/len_without_is_empty.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::{fulfill_or_allowed, get_parent_as_impl, sym};\nuse rustc_hir::def::Res;\nuse rustc_hir::def_id::{DefId, DefIdSet};\nuse rustc_hir::{\n    FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind, ImplicitSelfKind, Item, ItemKind, Mutability,\n    Node, OpaqueTyOrigin, PathSegment, PrimTy, QPath, TraitItemId, TyKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, FnSig, Ty};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::kw;\nuse rustc_span::{Ident, Span, Symbol};\nuse rustc_trait_selection::traits::supertrait_def_ids;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for items that implement `.len()` but not\n    /// `.is_empty()`.\n    ///\n    /// ### Why is this bad?\n    /// It is good custom to have both methods, because for\n    /// some data structures, asking about the length will be a costly operation,\n    /// whereas `.is_empty()` can usually answer in constant time. Also it used to\n    /// lead to false positives on the [`len_zero`](#len_zero) lint – currently that\n    /// lint will ignore such entities.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// impl X {\n    ///     pub fn len(&self) -> usize {\n    ///         ..\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub LEN_WITHOUT_IS_EMPTY,\n    style,\n    \"traits or impls with a public `len` method but no corresponding `is_empty` method\"\n}\n\ndeclare_lint_pass!(LenWithoutIsEmpty => [LEN_WITHOUT_IS_EMPTY]);\n\nimpl<'tcx> LateLintPass<'tcx> for LenWithoutIsEmpty {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Trait(_, _, _, ident, _, _, trait_items) = item.kind\n            && !item.span.from_expansion()\n        {\n            check_trait_items(cx, item, ident, trait_items);\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {\n        if item.ident.name == sym::len\n            && let ImplItemKind::Fn(sig, _) = &item.kind\n            && sig.decl.implicit_self.has_implicit_self()\n            && sig.decl.inputs.len() == 1\n            && cx.effective_visibilities.is_exported(item.owner_id.def_id)\n            && matches!(sig.decl.output, FnRetTy::Return(_))\n            && let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id())\n            && imp.of_trait.is_none()\n            && let TyKind::Path(ty_path) = &imp.self_ty.kind\n            && let Some(ty_id) = cx.qpath_res(ty_path, imp.self_ty.hir_id).opt_def_id()\n            && let Some(local_id) = ty_id.as_local()\n            && let ty_hir_id = cx.tcx.local_def_id_to_hir_id(local_id)\n            && let Some(output) = LenOutput::new(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder())\n        {\n            let (name, kind) = match cx.tcx.hir_node(ty_hir_id) {\n                Node::ForeignItem(x) => (x.ident.name, \"extern type\"),\n                Node::Item(x) => match x.kind {\n                    ItemKind::Struct(ident, ..) => (ident.name, \"struct\"),\n                    ItemKind::Enum(ident, ..) => (ident.name, \"enum\"),\n                    ItemKind::Union(ident, ..) => (ident.name, \"union\"),\n                    _ => (x.kind.ident().unwrap().name, \"type\"),\n                },\n                _ => return,\n            };\n            check_for_is_empty(\n                cx,\n                sig.span,\n                sig.decl.implicit_self,\n                output,\n                ty_id,\n                name,\n                kind,\n                item.hir_id(),\n                ty_hir_id,\n            );\n        }\n    }\n}\n\nfn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) {\n    fn is_named_self(cx: &LateContext<'_>, item: TraitItemId, name: Symbol) -> bool {\n        cx.tcx.item_name(item.owner_id) == name\n            && matches!(\n                cx.tcx.fn_arg_idents(item.owner_id),\n                [Some(Ident {\n                    name: kw::SelfLower,\n                    ..\n                })],\n            )\n    }\n\n    // fill the set with current and super traits\n    fn fill_trait_set(traitt: DefId, set: &mut DefIdSet, cx: &LateContext<'_>) {\n        if set.insert(traitt) {\n            for supertrait in supertrait_def_ids(cx.tcx, traitt) {\n                fill_trait_set(supertrait, set, cx);\n            }\n        }\n    }\n\n    if cx.effective_visibilities.is_exported(visited_trait.owner_id.def_id)\n        && trait_items.iter().any(|&i| is_named_self(cx, i, sym::len))\n    {\n        let mut current_and_super_traits = DefIdSet::default();\n        fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx);\n        let is_empty_method_found = current_and_super_traits\n            .items()\n            .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(sym::is_empty))\n            .any(|i| i.is_method() && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1);\n\n        if !is_empty_method_found {\n            span_lint(\n                cx,\n                LEN_WITHOUT_IS_EMPTY,\n                visited_trait.span,\n                format!(\n                    \"trait `{}` has a `len` method but no (possibly inherited) `is_empty` method\",\n                    ident.name\n                ),\n            );\n        }\n    }\n}\n\nfn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> {\n    if let ty::Alias(_, alias_ty) = ty.kind()\n        && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir_get_if_local(alias_ty.def_id)\n        && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin\n        && let [GenericBound::Trait(trait_ref)] = &opaque.bounds\n        && let Some(segment) = trait_ref.trait_ref.path.segments.last()\n        && let Some(generic_args) = segment.args\n        && let [constraint] = generic_args.constraints\n        && let Some(ty) = constraint.ty()\n        && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind\n        && let [segment] = path.segments\n    {\n        return Some(segment);\n    }\n\n    None\n}\n\nfn is_first_generic_integral<'tcx>(segment: &'tcx PathSegment<'tcx>) -> bool {\n    if let Some(generic_args) = segment.args\n        && let [GenericArg::Type(ty), ..] = &generic_args.args\n        && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind\n        && let [segment, ..] = &path.segments\n        && matches!(segment.res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_)))\n    {\n        true\n    } else {\n        false\n    }\n}\n\n#[derive(Debug, Clone, Copy)]\nenum LenOutput {\n    Integral,\n    Option(DefId),\n    Result(DefId),\n}\n\nimpl LenOutput {\n    fn new<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option<Self> {\n        if let Some(segment) = extract_future_output(cx, sig.output()) {\n            let res = segment.res;\n\n            if matches!(res, Res::PrimTy(PrimTy::Uint(_) | PrimTy::Int(_))) {\n                return Some(Self::Integral);\n            }\n\n            if let Res::Def(_, def_id) = res\n                && let Some(res) = match cx.tcx.get_diagnostic_name(def_id) {\n                    Some(sym::Option) => Some(Self::Option(def_id)),\n                    Some(sym::Result) => Some(Self::Result(def_id)),\n                    _ => None,\n                }\n                && is_first_generic_integral(segment)\n            {\n                return Some(res);\n            }\n\n            return None;\n        }\n\n        match *sig.output().kind() {\n            ty::Int(_) | ty::Uint(_) => Some(Self::Integral),\n            ty::Adt(adt, subs) => match cx.tcx.get_diagnostic_name(adt.did()) {\n                Some(sym::Option) => subs.type_at(0).is_integral().then(|| Self::Option(adt.did())),\n                Some(sym::Result) => subs.type_at(0).is_integral().then(|| Self::Result(adt.did())),\n                _ => None,\n            },\n            _ => None,\n        }\n    }\n\n    fn matches_is_empty_output<'tcx>(self, cx: &LateContext<'tcx>, is_empty_output: Ty<'tcx>) -> bool {\n        if let Some(segment) = extract_future_output(cx, is_empty_output) {\n            return match (self, segment.res) {\n                (_, Res::PrimTy(PrimTy::Bool)) => true,\n                (Self::Option(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Option, def_id) => true,\n                (Self::Result(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Result, def_id) => true,\n                _ => false,\n            };\n        }\n\n        match (self, is_empty_output.kind()) {\n            (_, &ty::Bool) => true,\n            (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(),\n            (Self::Result(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(),\n            _ => false,\n        }\n    }\n}\n\n/// The expected signature of `is_empty`, based on that of `len`\nfn expected_is_empty_sig(len_output: LenOutput, len_self_kind: ImplicitSelfKind) -> String {\n    let self_ref = match len_self_kind {\n        ImplicitSelfKind::RefImm => \"&\",\n        ImplicitSelfKind::RefMut => \"&(mut) \",\n        _ => \"\",\n    };\n    match len_output {\n        LenOutput::Integral => format!(\"expected signature: `({self_ref}self) -> bool`\"),\n        LenOutput::Option(_) => {\n            format!(\"expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Option<bool>\")\n        },\n        LenOutput::Result(..) => {\n            format!(\"expected signature: `({self_ref}self) -> bool` or `({self_ref}self) -> Result<bool>\")\n        },\n    }\n}\n\n/// Checks if the given signature matches the expectations for `is_empty`\nfn check_is_empty_sig<'tcx>(\n    cx: &LateContext<'tcx>,\n    is_empty_sig: FnSig<'tcx>,\n    len_self_kind: ImplicitSelfKind,\n    len_output: LenOutput,\n) -> bool {\n    if let [is_empty_self_arg, is_empty_output] = &**is_empty_sig.inputs_and_output\n        && len_output.matches_is_empty_output(cx, *is_empty_output)\n    {\n        match (is_empty_self_arg.kind(), len_self_kind) {\n            // if `len` takes `&self`, `is_empty` should do so as well\n            (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm)\n            // if `len` takes `&mut self`, `is_empty` may take that _or_ `&self` (#16190)\n            | (ty::Ref(_, _, Mutability::Mut | Mutability::Not), ImplicitSelfKind::RefMut) => true,\n            // if len takes `self`, `is_empty` should do so as well\n            // XXX: we might want to relax this to allow `&self` and `&mut self`\n            (_, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut) if !is_empty_self_arg.is_ref() => true,\n            _ => false,\n        }\n    } else {\n        false\n    }\n}\n\n/// Checks if the given type has an `is_empty` method with the appropriate signature.\n#[expect(clippy::too_many_arguments)]\nfn check_for_is_empty(\n    cx: &LateContext<'_>,\n    len_span: Span,\n    len_self_kind: ImplicitSelfKind,\n    len_output: LenOutput,\n    impl_ty: DefId,\n    item_name: Symbol,\n    item_kind: &str,\n    len_method_hir_id: HirId,\n    ty_decl_hir_id: HirId,\n) {\n    // Implementor may be a type alias, in which case we need to get the `DefId` of the aliased type to\n    // find the correct inherent impls.\n    let impl_ty = if let Some(adt) = cx.tcx.type_of(impl_ty).skip_binder().ty_adt_def() {\n        adt.did()\n    } else {\n        return;\n    };\n\n    let is_empty = cx\n        .tcx\n        .inherent_impls(impl_ty)\n        .iter()\n        .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(sym::is_empty))\n        .find(|item| item.is_fn());\n\n    let (msg, is_empty_span, is_empty_expected_sig) = match is_empty {\n        None => (\n            format!(\"{item_kind} `{item_name}` has a public `len` method, but no `is_empty` method\"),\n            None,\n            None,\n        ),\n        Some(is_empty) if !cx.effective_visibilities.is_exported(is_empty.def_id.expect_local()) => (\n            format!(\"{item_kind} `{item_name}` has a public `len` method, but a private `is_empty` method\"),\n            Some(cx.tcx.def_span(is_empty.def_id)),\n            None,\n        ),\n        Some(is_empty)\n            if !(is_empty.is_method()\n                && check_is_empty_sig(\n                    cx,\n                    cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(),\n                    len_self_kind,\n                    len_output,\n                )) =>\n        {\n            (\n                format!(\n                    \"{item_kind} `{item_name}` has a public `len` method, but the `is_empty` method has an unexpected signature\",\n                ),\n                Some(cx.tcx.def_span(is_empty.def_id)),\n                Some(expected_is_empty_sig(len_output, len_self_kind)),\n            )\n        },\n        Some(_) => return,\n    };\n\n    if !fulfill_or_allowed(cx, LEN_WITHOUT_IS_EMPTY, [len_method_hir_id, ty_decl_hir_id]) {\n        span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, len_span, msg, |db| {\n            if let Some(span) = is_empty_span {\n                db.span_note(span, \"`is_empty` defined here\");\n            }\n            if let Some(expected_sig) = is_empty_expected_sig {\n                db.note(expected_sig);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/len_zero.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::{SpanRangeExt, snippet_with_context};\nuse clippy_utils::sugg::{Sugg, has_enclosing_paren};\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{parent_item_name, peel_ref_operators, sym};\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, PatExprKind, PatKind, RustcVersion, StabilityLevel, StableSince};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for comparing to an empty slice such as `\"\"` or `[]`,\n    /// and suggests using `.is_empty()` where applicable.\n    ///\n    /// ### Why is this bad?\n    /// Some structures can answer `.is_empty()` much faster\n    /// than checking for equality. So it is good to get into the habit of using\n    /// `.is_empty()`, and having it is cheap.\n    /// Besides, it makes the intent clearer than a manual comparison in some contexts.\n    ///\n    /// ### Example\n    ///\n    /// ```ignore\n    /// if s == \"\" {\n    ///     ..\n    /// }\n    ///\n    /// if arr == [] {\n    ///     ..\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```ignore\n    /// if s.is_empty() {\n    ///     ..\n    /// }\n    ///\n    /// if arr.is_empty() {\n    ///     ..\n    /// }\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub COMPARISON_TO_EMPTY,\n    style,\n    \"checking `x == \\\"\\\"` or `x == []` (or similar) when `.is_empty()` could be used instead\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for getting the length of something via `.len()`\n    /// just to compare to zero, and suggests using `.is_empty()` where applicable.\n    ///\n    /// ### Why is this bad?\n    /// Some structures can answer `.is_empty()` much faster\n    /// than calculating their length. So it is good to get into the habit of using\n    /// `.is_empty()`, and having it is cheap.\n    /// Besides, it makes the intent clearer than a manual comparison in some contexts.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// if x.len() == 0 {\n    ///     ..\n    /// }\n    /// if y.len() != 0 {\n    ///     ..\n    /// }\n    /// ```\n    /// instead use\n    /// ```ignore\n    /// if x.is_empty() {\n    ///     ..\n    /// }\n    /// if !y.is_empty() {\n    ///     ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub LEN_ZERO,\n    style,\n    \"checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` could be used instead\"\n}\n\nimpl_lint_pass!(LenZero => [COMPARISON_TO_EMPTY, LEN_ZERO]);\n\npub struct LenZero {\n    msrv: Msrv,\n}\n\nimpl LenZero {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for LenZero {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Let(lt) = expr.kind\n            && match lt.pat.kind {\n                PatKind::Slice([], None, []) => true,\n                PatKind::Expr(lit)\n                    if let PatExprKind::Lit { lit, .. } = lit.kind\n                        && let LitKind::Str(lit, _) = lit.node =>\n                {\n                    lit.as_str().is_empty()\n                },\n                _ => false,\n            }\n            && !expr.span.from_expansion()\n            && has_is_empty(cx, lt.init, self.msrv)\n        {\n            let mut applicability = Applicability::MachineApplicable;\n\n            let lit1 = peel_ref_operators(cx, lt.init);\n            let lit_str = Sugg::hir_with_context(cx, lit1, lt.span.ctxt(), \"_\", &mut applicability).maybe_paren();\n\n            span_lint_and_sugg(\n                cx,\n                COMPARISON_TO_EMPTY,\n                lt.span,\n                \"comparison to empty slice using `if let`\",\n                \"using `is_empty` is clearer and more explicit\",\n                format!(\"{lit_str}.is_empty()\"),\n                applicability,\n            );\n        }\n\n        if let ExprKind::MethodCall(method, lhs_expr, [rhs_expr], _) = expr.kind\n            && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::PartialEq)\n            && !expr.span.from_expansion()\n        {\n            self.check_empty_expr(\n                cx,\n                expr.span,\n                lhs_expr,\n                peel_ref_operators(cx, rhs_expr),\n                if method.ident.name == sym::ne {\n                    \"!\"\n                } else {\n                    Default::default()\n                },\n            );\n        }\n\n        if let ExprKind::Binary(Spanned { node: cmp, .. }, left, right) = expr.kind\n            && !expr.span.from_expansion()\n        {\n            // expr.span might contains parenthesis, see issue #10529\n            let actual_span = span_without_enclosing_paren(cx, expr.span);\n            match cmp {\n                BinOpKind::Eq => {\n                    self.check_cmp(cx, actual_span, left, right, \"\", 0); // len == 0\n                    self.check_cmp(cx, actual_span, right, left, \"\", 0); // 0 == len\n                },\n                BinOpKind::Ne => {\n                    self.check_cmp(cx, actual_span, left, right, \"!\", 0); // len != 0\n                    self.check_cmp(cx, actual_span, right, left, \"!\", 0); // 0 != len\n                },\n                BinOpKind::Gt => {\n                    self.check_cmp(cx, actual_span, left, right, \"!\", 0); // len > 0\n                    self.check_cmp(cx, actual_span, right, left, \"\", 1); // 1 > len\n                },\n                BinOpKind::Lt => {\n                    self.check_cmp(cx, actual_span, left, right, \"\", 1); // len < 1\n                    self.check_cmp(cx, actual_span, right, left, \"!\", 0); // 0 < len\n                },\n                BinOpKind::Ge => self.check_cmp(cx, actual_span, left, right, \"!\", 1), // len >= 1\n                BinOpKind::Le => self.check_cmp(cx, actual_span, right, left, \"!\", 1), // 1 <= len\n                _ => (),\n            }\n        }\n    }\n}\n\nimpl LenZero {\n    fn check_cmp(\n        &self,\n        cx: &LateContext<'_>,\n        span: Span,\n        method: &Expr<'_>,\n        lit: &Expr<'_>,\n        op: &str,\n        compare_to: u32,\n    ) {\n        if method.span.from_expansion() {\n            return;\n        }\n\n        if let (&ExprKind::MethodCall(method_path, receiver, [], _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) {\n            // check if we are in an is_empty() method\n            if parent_item_name(cx, method) == Some(sym::is_empty) {\n                return;\n            }\n\n            self.check_len(cx, span, method_path.ident.name, receiver, &lit.node, op, compare_to);\n        } else {\n            self.check_empty_expr(cx, span, method, lit, op);\n        }\n    }\n\n    #[expect(clippy::too_many_arguments)]\n    fn check_len(\n        &self,\n        cx: &LateContext<'_>,\n        span: Span,\n        method_name: Symbol,\n        receiver: &Expr<'_>,\n        lit: &LitKind,\n        op: &str,\n        compare_to: u32,\n    ) {\n        if let LitKind::Int(lit, _) = *lit {\n            // check if length is compared to the specified number\n            if lit != u128::from(compare_to) {\n                return;\n            }\n\n            if method_name == sym::len && has_is_empty(cx, receiver, self.msrv) {\n                let mut applicability = Applicability::MachineApplicable;\n                span_lint_and_sugg(\n                    cx,\n                    LEN_ZERO,\n                    span,\n                    format!(\"length comparison to {}\", if compare_to == 0 { \"zero\" } else { \"one\" }),\n                    format!(\"using `{op}is_empty` is clearer and more explicit\"),\n                    format!(\n                        \"{op}{}.is_empty()\",\n                        snippet_with_context(cx, receiver.span, span.ctxt(), \"_\", &mut applicability).0,\n                    ),\n                    applicability,\n                );\n            }\n        }\n    }\n\n    fn check_empty_expr(&self, cx: &LateContext<'_>, span: Span, lit1: &Expr<'_>, lit2: &Expr<'_>, op: &str) {\n        if (is_empty_array(lit2) || is_empty_string(lit2)) && has_is_empty(cx, lit1, self.msrv) {\n            let mut applicability = Applicability::MachineApplicable;\n\n            let lit1 = peel_ref_operators(cx, lit1);\n            let lit_str = Sugg::hir_with_context(cx, lit1, span.ctxt(), \"_\", &mut applicability).maybe_paren();\n\n            span_lint_and_sugg(\n                cx,\n                COMPARISON_TO_EMPTY,\n                span,\n                \"comparison to empty slice\",\n                format!(\"using `{op}is_empty` is clearer and more explicit\"),\n                format!(\"{op}{lit_str}.is_empty()\"),\n                applicability,\n            );\n        }\n    }\n}\n\nfn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {\n    let Some(snippet) = span.get_source_text(cx) else {\n        return span;\n    };\n    if has_enclosing_paren(snippet) {\n        let source_map = cx.tcx.sess.source_map();\n        let left_paren = source_map.start_point(span);\n        let right_parent = source_map.end_point(span);\n        left_paren.between(right_parent)\n    } else {\n        span\n    }\n}\n\nfn is_empty_string(expr: &Expr<'_>) -> bool {\n    if let ExprKind::Lit(lit) = expr.kind\n        && let LitKind::Str(lit, _) = lit.node\n    {\n        let lit = lit.as_str();\n        return lit.is_empty();\n    }\n    false\n}\n\nfn is_empty_array(expr: &Expr<'_>) -> bool {\n    if let ExprKind::Array(arr) = expr.kind {\n        return arr.is_empty();\n    }\n    false\n}\n\n/// Checks if this type has an `is_empty` method.\nfn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) -> bool {\n    /// Gets an `AssocItem` and return true if it matches `is_empty(self)`.\n    fn is_is_empty_and_stable(cx: &LateContext<'_>, item: &ty::AssocItem, msrv: Msrv) -> bool {\n        if item.is_fn() {\n            let sig = cx.tcx.fn_sig(item.def_id).skip_binder();\n            let ty = sig.skip_binder();\n            ty.inputs().len() == 1\n                && cx.tcx.lookup_stability(item.def_id).is_none_or(|stability| {\n                    if let StabilityLevel::Stable { since, .. } = stability.level {\n                        let version = match since {\n                            StableSince::Version(version) => version,\n                            StableSince::Current => RustcVersion::CURRENT,\n                            StableSince::Err(_) => return false,\n                        };\n\n                        msrv.meets(cx, version)\n                    } else {\n                        // Unstable fn, check if the feature is enabled.\n                        cx.tcx.features().enabled(stability.feature) && msrv.current(cx).is_none()\n                    }\n                })\n        } else {\n            false\n        }\n    }\n\n    /// Checks the inherent impl's items for an `is_empty(self)` method.\n    fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId, msrv: Msrv) -> bool {\n        cx.tcx.inherent_impls(id).iter().any(|imp| {\n            cx.tcx\n                .associated_items(*imp)\n                .filter_by_name_unhygienic(sym::is_empty)\n                .any(|item| is_is_empty_and_stable(cx, item, msrv))\n        })\n    }\n\n    fn ty_has_is_empty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, depth: usize, msrv: Msrv) -> bool {\n        match ty.kind() {\n            ty::Dynamic(tt, ..) => tt.principal().is_some_and(|principal| {\n                cx.tcx\n                    .associated_items(principal.def_id())\n                    .filter_by_name_unhygienic(sym::is_empty)\n                    .any(|item| is_is_empty_and_stable(cx, item, msrv))\n            }),\n            ty::Alias(ty::Projection, proj) => has_is_empty_impl(cx, proj.def_id, msrv),\n            ty::Adt(id, _) => {\n                has_is_empty_impl(cx, id.did(), msrv)\n                    || (cx.tcx.recursion_limit().value_within_limit(depth)\n                        && cx.tcx.get_diagnostic_item(sym::Deref).is_some_and(|deref_id| {\n                            implements_trait(cx, ty, deref_id, &[])\n                                && cx\n                                    .get_associated_type(ty, deref_id, sym::Target)\n                                    .is_some_and(|deref_ty| ty_has_is_empty(cx, deref_ty, depth + 1, msrv))\n                        }))\n            },\n            ty::Array(..) | ty::Slice(..) | ty::Str => true,\n            _ => false,\n        }\n    }\n\n    ty_has_is_empty(cx, cx.typeck_results().expr_ty(expr).peel_refs(), 0, msrv)\n}\n"
  },
  {
    "path": "clippy_lints/src/let_if_seq.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::visitors::is_local_used;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::{BindingMode, Mutability};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for variable declarations immediately followed by a\n    /// conditional affectation.\n    ///\n    /// ### Why is this bad?\n    /// This is not idiomatic Rust.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let foo;\n    ///\n    /// if bar() {\n    ///     foo = 42;\n    /// } else {\n    ///     foo = 0;\n    /// }\n    ///\n    /// let mut baz = None;\n    ///\n    /// if bar() {\n    ///     baz = Some(42);\n    /// }\n    /// ```\n    ///\n    /// should be written\n    ///\n    /// ```rust,ignore\n    /// let foo = if bar() {\n    ///     42\n    /// } else {\n    ///     0\n    /// };\n    ///\n    /// let baz = if bar() {\n    ///     Some(42)\n    /// } else {\n    ///     None\n    /// };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USELESS_LET_IF_SEQ,\n    nursery,\n    \"unidiomatic `let mut` declaration followed by initialization in `if`\"\n}\n\ndeclare_lint_pass!(LetIfSeq => [USELESS_LET_IF_SEQ]);\n\nimpl<'tcx> LateLintPass<'tcx> for LetIfSeq {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {\n        for [stmt, next] in block.stmts.array_windows::<2>() {\n            if let hir::StmtKind::Expr(if_) = next.kind {\n                check_block_inner(cx, stmt, if_);\n            }\n        }\n\n        if let Some(expr) = block.expr\n            && let Some(stmt) = block.stmts.last()\n        {\n            check_block_inner(cx, stmt, expr);\n        }\n    }\n}\n\nfn check_block_inner<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'tcx>, if_: &'tcx hir::Expr<'tcx>) {\n    if let hir::StmtKind::Let(local) = stmt.kind\n        && let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.kind\n        && let hir::ExprKind::If(cond, then, else_) = if_.kind\n        && !is_local_used(cx, cond, canonical_id)\n        && let hir::ExprKind::Block(then, _) = then.kind\n        && let Some(value) = check_assign(cx, canonical_id, then)\n        && !is_local_used(cx, value, canonical_id)\n    {\n        let span = stmt.span.to(if_.span);\n\n        let has_interior_mutability = !cx\n            .typeck_results()\n            .node_type(canonical_id)\n            .is_freeze(cx.tcx, cx.typing_env());\n        if has_interior_mutability {\n            return;\n        }\n\n        let (default_multi_stmts, default) = if let Some(else_) = else_ {\n            if let hir::ExprKind::Block(else_, _) = else_.kind {\n                if let Some(default) = check_assign(cx, canonical_id, else_) {\n                    (else_.stmts.len() > 1, default)\n                } else if let Some(default) = local.init {\n                    (true, default)\n                } else {\n                    return;\n                }\n            } else {\n                return;\n            }\n        } else if let Some(default) = local.init {\n            (false, default)\n        } else {\n            return;\n        };\n\n        let mutability = match mode {\n            BindingMode(_, Mutability::Mut) => \"<mut> \",\n            _ => \"\",\n        };\n\n        // FIXME: this should not suggest `mut` if we can detect that the variable is not\n        // use mutably after the `if`\n\n        let mut applicability = Applicability::HasPlaceholders;\n        let (cond_snip, _) = snippet_with_context(cx, cond.span, if_.span.ctxt(), \"_\", &mut applicability);\n        let (value_snip, _) = snippet_with_context(cx, value.span, if_.span.ctxt(), \"<value>\", &mut applicability);\n        let (default_snip, _) =\n            snippet_with_context(cx, default.span, if_.span.ctxt(), \"<default>\", &mut applicability);\n        let sug = format!(\n            \"let {mutability}{name} = if {cond_snip} {{{then} {value_snip} }} else {{{else} {default_snip} }};\",\n            name=ident.name,\n            then=if then.stmts.len() > 1 { \" ..;\" } else { \"\" },\n            else=if default_multi_stmts { \" ..;\" } else { \"\" },\n        );\n        span_lint_hir_and_then(\n            cx,\n            USELESS_LET_IF_SEQ,\n            local.hir_id,\n            span,\n            \"`if _ { .. } else { .. }` is an expression\",\n            |diag| {\n                diag.span_suggestion(span, \"it is more idiomatic to write\", sug, applicability);\n                if !mutability.is_empty() {\n                    diag.note(\"you might not need `mut` at all\");\n                }\n            },\n        );\n    }\n}\n\nfn check_assign<'tcx>(\n    cx: &LateContext<'tcx>,\n    decl: hir::HirId,\n    block: &'tcx hir::Block<'_>,\n) -> Option<&'tcx hir::Expr<'tcx>> {\n    if block.expr.is_none()\n        && let Some(expr) = block.stmts.iter().last()\n        && let hir::StmtKind::Semi(expr) = expr.kind\n        && let hir::ExprKind::Assign(var, value, _) = expr.kind\n        && var.res_local_id() == Some(decl)\n    {\n        if block\n            .stmts\n            .iter()\n            .take(block.stmts.len() - 1)\n            .any(|stmt| is_local_used(cx, stmt, decl))\n        {\n            None\n        } else {\n            Some(value)\n        }\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/let_underscore.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::ty::{implements_trait, is_must_use_ty};\nuse clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};\nuse rustc_hir::{LetStmt, LocalSource, PatKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{GenericArgKind, IsSuggestable};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{BytePos, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `let _ = <expr>` where the resulting type of expr implements `Future`\n    ///\n    /// ### Why is this bad?\n    /// Futures must be polled for work to be done. The original intention was most likely to await the future\n    /// and ignore the resulting value.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// async fn foo() -> Result<(), ()> {\n    ///     Ok(())\n    /// }\n    /// let _ = foo();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # async fn context() {\n    /// async fn foo() -> Result<(), ()> {\n    ///     Ok(())\n    /// }\n    /// let _ = foo().await;\n    /// # }\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub LET_UNDERSCORE_FUTURE,\n    suspicious,\n    \"non-binding `let` on a future\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `let _ = sync_lock`. This supports `mutex` and `rwlock` in\n    /// `parking_lot`. For `std` locks see the `rustc` lint\n    /// [`let_underscore_lock`](https://doc.rust-lang.org/nightly/rustc/lints/listing/deny-by-default.html#let-underscore-lock)\n    ///\n    /// ### Why is this bad?\n    /// This statement immediately drops the lock instead of\n    /// extending its lifetime to the end of the scope, which is often not intended.\n    /// To extend lock lifetime to the end of the scope, use an underscore-prefixed\n    /// name instead (i.e. _lock). If you want to explicitly drop the lock,\n    /// `std::mem::drop` conveys your intention better and is less error-prone.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let _ = mutex.lock();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// let _lock = mutex.lock();\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub LET_UNDERSCORE_LOCK,\n    correctness,\n    \"non-binding `let` on a synchronization lock\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `let _ = <expr>` where expr is `#[must_use]`\n    ///\n    /// ### Why restrict this?\n    /// To ensure that all `#[must_use]` types are used rather than ignored.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn f() -> Result<u32, u32> {\n    ///     Ok(0)\n    /// }\n    ///\n    /// let _ = f();\n    /// // is_ok() is marked #[must_use]\n    /// let _ = f().is_ok();\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub LET_UNDERSCORE_MUST_USE,\n    restriction,\n    \"non-binding `let` on a `#[must_use]` expression\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `let _ = <expr>` without a type annotation, and suggests to either provide one,\n    /// or remove the `let` keyword altogether.\n    ///\n    /// ### Why restrict this?\n    /// The `let _ = <expr>` expression ignores the value of `<expr>`, but will continue to do so even\n    /// if the type were to change, thus potentially introducing subtle bugs. By supplying a type\n    /// annotation, one will be forced to re-visit the decision to ignore the value in such cases.\n    ///\n    /// ### Known problems\n    /// The `_ = <expr>` is not properly supported by some tools (e.g. IntelliJ) and may seem odd\n    /// to many developers. This lint also partially overlaps with the other `let_underscore_*`\n    /// lints.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo() -> Result<u32, ()> {\n    ///     Ok(123)\n    /// }\n    /// let _ = foo();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo() -> Result<u32, ()> {\n    ///     Ok(123)\n    /// }\n    /// // Either provide a type annotation:\n    /// let _: Result<u32, ()> = foo();\n    /// // …or drop the let keyword:\n    /// _ = foo();\n    /// ```\n    #[clippy::version = \"1.69.0\"]\n    pub LET_UNDERSCORE_UNTYPED,\n    restriction,\n    \"non-binding `let` without a type annotation\"\n}\n\ndeclare_lint_pass!(LetUnderscore => [\n    LET_UNDERSCORE_FUTURE,\n    LET_UNDERSCORE_LOCK,\n    LET_UNDERSCORE_MUST_USE,\n    LET_UNDERSCORE_UNTYPED,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for LetUnderscore {\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {\n        if matches!(local.source, LocalSource::Normal)\n            && let PatKind::Wild = local.pat.kind\n            && let Some(init) = local.init\n            && !local.span.in_external_macro(cx.tcx.sess.source_map())\n        {\n            let init_ty = cx.typeck_results().expr_ty(init);\n            let contains_sync_guard = init_ty.walk().any(|inner| match inner.kind() {\n                GenericArgKind::Type(inner_ty) => inner_ty\n                    .ty_adt_def()\n                    .is_some_and(|adt| paths::PARKING_LOT_GUARDS.iter().any(|path| path.matches(cx, adt.did()))),\n                GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,\n            });\n            if contains_sync_guard {\n                #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                span_lint_and_then(\n                    cx,\n                    LET_UNDERSCORE_LOCK,\n                    local.span,\n                    \"non-binding `let` on a synchronization lock\",\n                    |diag| {\n                        diag.help(\n                            \"consider using an underscore-prefixed named \\\n                                binding or dropping explicitly with `std::mem::drop`\",\n                        );\n                    },\n                );\n            } else if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait()\n                && implements_trait(cx, cx.typeck_results().expr_ty(init), future_trait_def_id, &[])\n            {\n                #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                span_lint_and_then(\n                    cx,\n                    LET_UNDERSCORE_FUTURE,\n                    local.span,\n                    \"non-binding `let` on a future\",\n                    |diag| {\n                        diag.help(\"consider awaiting the future or dropping explicitly with `std::mem::drop`\");\n                    },\n                );\n            } else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {\n                #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                span_lint_and_then(\n                    cx,\n                    LET_UNDERSCORE_MUST_USE,\n                    local.span,\n                    \"non-binding `let` on an expression with `#[must_use]` type\",\n                    |diag| {\n                        diag.help(\"consider explicitly using expression value\");\n                    },\n                );\n            } else if is_must_use_func_call(cx, init) {\n                #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                span_lint_and_then(\n                    cx,\n                    LET_UNDERSCORE_MUST_USE,\n                    local.span,\n                    \"non-binding `let` on a result of a `#[must_use]` function\",\n                    |diag| {\n                        diag.help(\"consider explicitly using function result\");\n                    },\n                );\n            }\n\n            if local.pat.default_binding_modes && local.ty.is_none() {\n                // When `default_binding_modes` is true, the `let` keyword is present.\n\n                // Ignore unnameable types\n                if let Some(init) = local.init\n                    && !cx.typeck_results().expr_ty(init).is_suggestable(cx.tcx, true)\n                {\n                    return;\n                }\n\n                // Ignore if it is from a procedural macro...\n                if is_from_proc_macro(cx, init) {\n                    return;\n                }\n\n                span_lint_and_then(\n                    cx,\n                    LET_UNDERSCORE_UNTYPED,\n                    local.span,\n                    \"non-binding `let` without a type annotation\",\n                    |diag| {\n                        diag.span_help(\n                            Span::new(\n                                local.pat.span.hi(),\n                                local.pat.span.hi() + BytePos(1),\n                                local.pat.span.ctxt(),\n                                local.pat.span.parent(),\n                            ),\n                            \"consider adding a type annotation\",\n                        );\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/let_with_type_underscore.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::source::{IntoSpan, SpanRangeExt};\nuse rustc_ast::{Local, TyKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects when a variable is declared with an explicit type of `_`.\n    /// ### Why is this bad?\n    /// It adds noise, `: _` provides zero clarity or utility.\n    /// ### Example\n    /// ```rust,ignore\n    /// let my_number: _ = 1;\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// let my_number = 1;\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub LET_WITH_TYPE_UNDERSCORE,\n    complexity,\n    \"unneeded underscore type (`_`) in a variable declaration\"\n}\n\ndeclare_lint_pass!(UnderscoreTyped => [LET_WITH_TYPE_UNDERSCORE]);\n\nimpl EarlyLintPass for UnderscoreTyped {\n    fn check_local(&mut self, cx: &EarlyContext<'_>, local: &Local) {\n        if let Some(ty) = &local.ty // Ensure that it has a type defined\n            && let TyKind::Infer = ty.kind // that type is '_'\n            && local.span.eq_ctxt(ty.span)\n            && let sm = cx.sess().source_map()\n            && !local.span.in_external_macro(sm)\n            && !is_from_proc_macro(cx, &**ty)\n        {\n            let span_to_remove = sm\n                .span_extend_to_prev_char_before(ty.span, ':', true)\n                .with_leading_whitespace(cx)\n                .into_span();\n\n            span_lint_and_then(\n                cx,\n                LET_WITH_TYPE_UNDERSCORE,\n                local.span,\n                \"variable declared with type underscore\",\n                |diag| {\n                    diag.span_suggestion_verbose(\n                        span_to_remove,\n                        \"remove the explicit type `_` declaration\",\n                        \"\",\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/lib.rs",
    "content": "#![cfg_attr(bootstrap, feature(if_let_guard))]\n#![feature(box_patterns)]\n#![feature(control_flow_into_value)]\n#![feature(exact_div)]\n#![feature(f128)]\n#![feature(f16)]\n#![feature(iter_intersperse)]\n#![feature(iter_partition_in_place)]\n#![feature(macro_metavar_expr_concat)]\n#![feature(never_type)]\n#![feature(rustc_private)]\n#![feature(stmt_expr_attributes)]\n#![feature(unwrap_infallible)]\n#![recursion_limit = \"512\"]\n#![allow(\n    clippy::missing_docs_in_private_items,\n    clippy::must_use_candidate,\n    clippy::literal_string_with_formatting_args\n)]\n#![warn(\n    trivial_casts,\n    trivial_numeric_casts,\n    rust_2018_idioms,\n    unused_lifetimes,\n    unused_qualifications,\n    rustc::internal\n)]\n\nextern crate rustc_abi;\nextern crate rustc_arena;\nextern crate rustc_ast;\nextern crate rustc_ast_pretty;\nextern crate rustc_data_structures;\nextern crate rustc_errors;\nextern crate rustc_hir;\nextern crate rustc_hir_analysis;\nextern crate rustc_hir_pretty;\nextern crate rustc_hir_typeck;\nextern crate rustc_index;\nextern crate rustc_infer;\nextern crate rustc_lexer;\nextern crate rustc_lint;\nextern crate rustc_middle;\nextern crate rustc_parse_format;\nextern crate rustc_resolve;\nextern crate rustc_session;\nextern crate rustc_span;\nextern crate rustc_target;\nextern crate rustc_trait_selection;\n\n#[macro_use]\nextern crate clippy_utils;\n\n#[macro_use]\nextern crate declare_clippy_lint;\n\nmod utils;\n\npub mod declared_lints;\npub mod deprecated_lints;\n\n// begin lints modules, do not remove this comment, it's used in `update_lints`\nmod absolute_paths;\nmod almost_complete_range;\nmod approx_const;\nmod arbitrary_source_item_ordering;\nmod arc_with_non_send_sync;\nmod as_conversions;\nmod asm_syntax;\nmod assertions_on_constants;\nmod assertions_on_result_states;\nmod assigning_clones;\nmod async_yields_async;\nmod attrs;\nmod await_holding_invalid;\nmod blocks_in_conditions;\nmod bool_assert_comparison;\nmod bool_comparison;\nmod bool_to_int_with_if;\nmod booleans;\nmod borrow_deref_ref;\nmod box_default;\nmod byte_char_slices;\nmod cargo;\nmod casts;\nmod cfg_not_test;\nmod checked_conversions;\nmod cloned_ref_to_slice_refs;\nmod coerce_container_to_any;\nmod cognitive_complexity;\nmod collapsible_if;\nmod collection_is_never_read;\nmod comparison_chain;\nmod copy_iterator;\nmod crate_in_macro_def;\nmod create_dir;\nmod dbg_macro;\nmod default;\nmod default_constructed_unit_structs;\nmod default_instead_of_iter_empty;\nmod default_numeric_fallback;\nmod default_union_representation;\nmod dereference;\nmod derivable_impls;\nmod derive;\nmod disallowed_fields;\nmod disallowed_macros;\nmod disallowed_methods;\nmod disallowed_names;\nmod disallowed_script_idents;\nmod disallowed_types;\nmod doc;\nmod double_parens;\nmod drop_forget_ref;\nmod duplicate_mod;\nmod duration_suboptimal_units;\nmod else_if_without_else;\nmod empty_drop;\nmod empty_enums;\nmod empty_line_after;\nmod empty_with_brackets;\nmod endian_bytes;\nmod entry;\nmod enum_clike;\nmod equatable_if_let;\nmod error_impl_error;\nmod escape;\nmod eta_reduction;\nmod excessive_bools;\nmod excessive_nesting;\nmod exhaustive_items;\nmod exit;\nmod explicit_write;\nmod extra_unused_type_parameters;\nmod fallible_impl_from;\nmod field_scoped_visibility_modifiers;\nmod float_literal;\nmod floating_point_arithmetic;\nmod format;\nmod format_args;\nmod format_impl;\nmod format_push_string;\nmod formatting;\nmod four_forward_slashes;\nmod from_over_into;\nmod from_raw_with_void_ptr;\nmod from_str_radix_10;\nmod functions;\nmod future_not_send;\nmod if_let_mutex;\nmod if_not_else;\nmod if_then_some_else_none;\nmod ifs;\nmod ignored_unit_patterns;\nmod impl_hash_with_borrow_str_and_bytes;\nmod implicit_hasher;\nmod implicit_return;\nmod implicit_saturating_add;\nmod implicit_saturating_sub;\nmod implied_bounds_in_impls;\nmod incompatible_msrv;\nmod inconsistent_struct_constructor;\nmod index_refutable_slice;\nmod indexing_slicing;\nmod ineffective_open_options;\nmod infallible_try_from;\nmod infinite_iter;\nmod inherent_impl;\nmod inherent_to_string;\nmod init_numbered_fields;\nmod inline_fn_without_body;\nmod int_plus_one;\nmod item_name_repetitions;\nmod items_after_statements;\nmod items_after_test_module;\nmod iter_not_returning_iterator;\nmod iter_over_hash_type;\nmod iter_without_into_iter;\nmod large_const_arrays;\nmod large_enum_variant;\nmod large_futures;\nmod large_include_file;\nmod large_stack_arrays;\nmod large_stack_frames;\nmod legacy_numeric_constants;\nmod len_without_is_empty;\nmod len_zero;\nmod let_if_seq;\nmod let_underscore;\nmod let_with_type_underscore;\nmod lifetimes;\nmod literal_representation;\nmod literal_string_with_formatting_args;\nmod loops;\nmod macro_metavars_in_unsafe;\nmod macro_use;\nmod main_recursion;\nmod manual_abs_diff;\nmod manual_assert;\nmod manual_async_fn;\nmod manual_bits;\nmod manual_checked_ops;\nmod manual_clamp;\nmod manual_float_methods;\nmod manual_hash_one;\nmod manual_ignore_case_cmp;\nmod manual_ilog2;\nmod manual_is_ascii_check;\nmod manual_is_power_of_two;\nmod manual_let_else;\nmod manual_main_separator_str;\nmod manual_non_exhaustive;\nmod manual_option_as_slice;\nmod manual_pop_if;\nmod manual_range_patterns;\nmod manual_rem_euclid;\nmod manual_retain;\nmod manual_rotate;\nmod manual_slice_size_calculation;\nmod manual_string_new;\nmod manual_strip;\nmod manual_take;\nmod map_unit_fn;\nmod match_result_ok;\nmod matches;\nmod mem_replace;\nmod methods;\nmod min_ident_chars;\nmod minmax;\nmod misc;\nmod misc_early;\nmod mismatching_type_param_order;\nmod missing_assert_message;\nmod missing_asserts_for_indexing;\nmod missing_const_for_fn;\nmod missing_const_for_thread_local;\nmod missing_doc;\nmod missing_enforced_import_rename;\nmod missing_fields_in_debug;\nmod missing_inline;\nmod missing_trait_methods;\nmod mixed_read_write_in_expression;\nmod module_style;\nmod multi_assignments;\nmod multiple_bound_locations;\nmod multiple_unsafe_ops_per_block;\nmod mut_key;\nmod mut_mut;\nmod mutable_debug_assertion;\nmod mutex_atomic;\nmod needless_arbitrary_self_type;\nmod needless_bool;\nmod needless_borrowed_ref;\nmod needless_borrows_for_generic_args;\nmod needless_continue;\nmod needless_else;\nmod needless_for_each;\nmod needless_ifs;\nmod needless_late_init;\nmod needless_maybe_sized;\nmod needless_parens_on_range_literals;\nmod needless_pass_by_ref_mut;\nmod needless_pass_by_value;\nmod needless_question_mark;\nmod needless_update;\nmod neg_cmp_op_on_partial_ord;\nmod neg_multiply;\nmod new_without_default;\nmod no_effect;\nmod no_mangle_with_rust_abi;\nmod non_canonical_impls;\nmod non_copy_const;\nmod non_expressive_names;\nmod non_octal_unix_permissions;\nmod non_send_fields_in_send_ty;\nmod non_std_lazy_statics;\nmod non_zero_suggestions;\nmod nonstandard_macro_braces;\nmod octal_escapes;\nmod only_used_in_recursion;\nmod operators;\nmod option_env_unwrap;\nmod option_if_let_else;\nmod panic_in_result_fn;\nmod panic_unimplemented;\nmod panicking_overflow_checks;\nmod partial_pub_fields;\nmod partialeq_ne_impl;\nmod partialeq_to_none;\nmod pass_by_ref_or_value;\nmod pathbuf_init_then_push;\nmod pattern_type_mismatch;\nmod permissions_set_readonly_false;\nmod pointers_in_nomem_asm_block;\nmod precedence;\nmod ptr;\nmod pub_underscore_fields;\nmod pub_use;\nmod question_mark;\nmod question_mark_used;\nmod ranges;\nmod raw_strings;\nmod rc_clone_in_vec_init;\nmod read_zero_byte_vec;\nmod redundant_async_block;\nmod redundant_clone;\nmod redundant_closure_call;\nmod redundant_else;\nmod redundant_field_names;\nmod redundant_locals;\nmod redundant_pub_crate;\nmod redundant_slicing;\nmod redundant_static_lifetimes;\nmod redundant_test_prefix;\nmod redundant_type_annotations;\nmod ref_option_ref;\nmod ref_patterns;\nmod reference;\nmod regex;\nmod repeat_vec_with_capacity;\nmod replace_box;\nmod reserve_after_initialization;\nmod return_self_not_must_use;\nmod returns;\nmod same_length_and_capacity;\nmod same_name_method;\nmod self_named_constructors;\nmod semicolon_block;\nmod semicolon_if_nothing_returned;\nmod serde_api;\nmod set_contains_or_insert;\nmod shadow;\nmod significant_drop_tightening;\nmod single_call_fn;\nmod single_char_lifetime_names;\nmod single_component_path_imports;\nmod single_option_map;\nmod single_range_in_vec_init;\nmod size_of_in_element_count;\nmod size_of_ref;\nmod slow_vector_initialization;\nmod std_instead_of_core;\nmod string_patterns;\nmod strings;\nmod strlen_on_c_strings;\nmod suspicious_operation_groupings;\nmod suspicious_trait_impl;\nmod suspicious_xor_used_as_pow;\nmod swap;\nmod swap_ptr_to_ref;\nmod tabs_in_doc_comments;\nmod temporary_assignment;\nmod tests_outside_test_module;\nmod time_subtraction;\nmod to_digit_is_some;\nmod to_string_trait_impl;\nmod toplevel_ref_arg;\nmod trailing_empty_array;\nmod trait_bounds;\nmod transmute;\nmod tuple_array_conversions;\nmod types;\nmod unconditional_recursion;\nmod undocumented_unsafe_blocks;\nmod unicode;\nmod uninhabited_references;\nmod uninit_vec;\nmod unit_return_expecting_ord;\nmod unit_types;\nmod unnecessary_box_returns;\nmod unnecessary_literal_bound;\nmod unnecessary_map_on_constructor;\nmod unnecessary_mut_passed;\nmod unnecessary_owned_empty_strings;\nmod unnecessary_self_imports;\nmod unnecessary_semicolon;\nmod unnecessary_struct_initialization;\nmod unnecessary_wraps;\nmod unneeded_struct_pattern;\nmod unnested_or_patterns;\nmod unsafe_removed_from_name;\nmod unused_async;\nmod unused_io_amount;\nmod unused_peekable;\nmod unused_result_ok;\nmod unused_rounding;\nmod unused_self;\nmod unused_trait_names;\nmod unused_unit;\nmod unwrap;\nmod unwrap_in_result;\nmod upper_case_acronyms;\nmod use_self;\nmod useless_concat;\nmod useless_conversion;\nmod useless_vec;\nmod vec_init_then_push;\nmod visibility;\nmod volatile_composites;\nmod wildcard_imports;\nmod write;\nmod zero_div_zero;\nmod zero_repeat_side_effects;\nmod zero_sized_map_values;\nmod zombie_processes;\n// end lints modules, do not remove this comment, it's used in `update_lints`\n\nuse clippy_config::{Conf, get_configuration_metadata, sanitize_explanation};\nuse clippy_utils::macros::FormatArgsStorage;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_data_structures::sync;\nuse rustc_lint::{EarlyLintPass, LateLintPass, Lint};\nuse rustc_middle::ty::TyCtxt;\nuse utils::attr_collector::{AttrCollector, AttrStorage};\n\npub fn explain(name: &str) -> i32 {\n    let target = format!(\"clippy::{}\", name.to_ascii_uppercase());\n\n    if let Some(info) = declared_lints::LINTS.iter().find(|info| info.lint.name == target) {\n        println!(\"{}\", sanitize_explanation(info.explanation));\n        // Check if the lint has configuration\n        let mut mdconf = get_configuration_metadata();\n        let name = name.to_ascii_lowercase();\n        mdconf.retain(|cconf| cconf.lints.contains(&&*name));\n        if !mdconf.is_empty() {\n            println!(\"### Configuration for {}:\\n\", info.lint.name_lower());\n            for conf in mdconf {\n                println!(\"{conf}\");\n            }\n        }\n        0\n    } else {\n        println!(\"unknown lint: {name}\");\n        1\n    }\n}\n\n/// Register all lints and lint groups with the rustc lint store\n///\n/// Used in `./src/driver.rs`.\n#[expect(clippy::too_many_lines)]\npub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Conf) {\n    for (old_name, new_name) in deprecated_lints::RENAMED {\n        store.register_renamed(old_name, new_name);\n    }\n    for (name, reason) in deprecated_lints::DEPRECATED {\n        store.register_removed(name, reason);\n    }\n\n    // NOTE: Do not add any more pre-expansion passes. These should be removed eventually.\n    // Due to the architecture of the compiler, currently `cfg_attr` attributes on crate\n    // level (i.e `#![cfg_attr(...)]`) will still be expanded even when using a pre-expansion pass.\n    store.register_pre_expansion_pass(move || Box::new(attrs::EarlyAttributes::new(conf)));\n\n    let format_args_storage = FormatArgsStorage::default();\n    let attr_storage = AttrStorage::default();\n\n    let early_lints: [Box<dyn Fn() -> Box<dyn EarlyLintPass + 'static> + sync::DynSend + sync::DynSync>; _] = [\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move || {\n                Box::new(utils::format_args_collector::FormatArgsCollector::new(\n                    format_args.clone(),\n                ))\n            })\n        },\n        {\n            let attrs = attr_storage.clone();\n            Box::new(move || Box::new(AttrCollector::new(attrs.clone())))\n        },\n        Box::new(move || Box::new(attrs::PostExpansionEarlyAttributes::new(conf))),\n        Box::new(|| Box::new(unnecessary_self_imports::UnnecessarySelfImports)),\n        Box::new(move || Box::new(redundant_static_lifetimes::RedundantStaticLifetimes::new(conf))),\n        Box::new(move || Box::new(redundant_field_names::RedundantFieldNames::new(conf))),\n        Box::new(move || Box::new(unnested_or_patterns::UnnestedOrPatterns::new(conf))),\n        Box::new(|| Box::new(functions::EarlyFunctions)),\n        Box::new(move || Box::new(doc::Documentation::new(conf))),\n        Box::new(|| Box::new(suspicious_operation_groupings::SuspiciousOperationGroupings)),\n        Box::new(|| Box::new(double_parens::DoubleParens)),\n        Box::new(|| Box::new(unsafe_removed_from_name::UnsafeNameRemoval)),\n        Box::new(|| Box::new(else_if_without_else::ElseIfWithoutElse)),\n        Box::new(|| Box::new(int_plus_one::IntPlusOne)),\n        Box::new(|| Box::new(formatting::Formatting)),\n        Box::new(|| Box::new(misc_early::MiscEarlyLints)),\n        Box::new(|| Box::new(unused_unit::UnusedUnit)),\n        Box::new(|| Box::new(precedence::Precedence)),\n        Box::new(|| Box::new(redundant_else::RedundantElse)),\n        Box::new(|| Box::new(needless_arbitrary_self_type::NeedlessArbitrarySelfType)),\n        Box::new(move || Box::new(literal_representation::LiteralDigitGrouping::new(conf))),\n        Box::new(move || Box::new(literal_representation::DecimalLiteralRepresentation::new(conf))),\n        Box::new(|| Box::new(tabs_in_doc_comments::TabsInDocComments)),\n        Box::new(|| Box::<single_component_path_imports::SingleComponentPathImports>::default()),\n        Box::new(|| Box::new(option_env_unwrap::OptionEnvUnwrap)),\n        Box::new(move || Box::new(non_expressive_names::NonExpressiveNames::new(conf))),\n        Box::new(move || Box::new(nonstandard_macro_braces::MacroBraces::new(conf))),\n        Box::new(|| Box::new(asm_syntax::InlineAsmX86AttSyntax)),\n        Box::new(|| Box::new(asm_syntax::InlineAsmX86IntelSyntax)),\n        Box::new(move || Box::new(module_style::ModStyle::default())),\n        Box::new(move || Box::new(disallowed_script_idents::DisallowedScriptIdents::new(conf))),\n        Box::new(|| Box::new(octal_escapes::OctalEscapes)),\n        Box::new(|| Box::new(single_char_lifetime_names::SingleCharLifetimeNames)),\n        Box::new(|| Box::new(crate_in_macro_def::CrateInMacroDef)),\n        Box::new(|| Box::new(pub_use::PubUse)),\n        Box::new(move || Box::new(large_include_file::LargeIncludeFile::new(conf))),\n        Box::new(|| Box::<duplicate_mod::DuplicateMod>::default()),\n        Box::new(|| Box::new(unused_rounding::UnusedRounding)),\n        Box::new(move || Box::new(almost_complete_range::AlmostCompleteRange::new(conf))),\n        Box::new(|| Box::new(multi_assignments::MultiAssignments)),\n        Box::new(|| Box::new(partial_pub_fields::PartialPubFields)),\n        Box::new(|| Box::new(let_with_type_underscore::UnderscoreTyped)),\n        Box::new(move || Box::new(excessive_nesting::ExcessiveNesting::new(conf))),\n        Box::new(|| Box::new(ref_patterns::RefPatterns)),\n        Box::new(|| Box::new(needless_else::NeedlessElse)),\n        Box::new(move || Box::new(raw_strings::RawStrings::new(conf))),\n        Box::new(|| Box::new(visibility::Visibility)),\n        Box::new(|| Box::new(multiple_bound_locations::MultipleBoundLocations)),\n        Box::new(|| Box::new(field_scoped_visibility_modifiers::FieldScopedVisibilityModifiers)),\n        Box::new(|| Box::new(byte_char_slices::ByteCharSlice)),\n        Box::new(|| Box::new(cfg_not_test::CfgNotTest)),\n        Box::new(|| Box::new(empty_line_after::EmptyLineAfter::new())),\n        // add early passes here, used by `cargo dev new_lint`\n    ];\n    store.early_passes.extend(early_lints);\n\n    #[expect(clippy::type_complexity)]\n    let late_lints: [Box<\n        dyn for<'tcx> Fn(TyCtxt<'tcx>) -> Box<dyn LateLintPass<'tcx> + 'tcx> + sync::DynSend + sync::DynSync,\n    >; _] = [\n        Box::new(move |_| Box::new(operators::arithmetic_side_effects::ArithmeticSideEffects::new(conf))),\n        Box::new(|_| Box::new(utils::dump_hir::DumpHir)),\n        Box::new(|_| Box::new(utils::author::Author)),\n        Box::new(move |tcx| Box::new(await_holding_invalid::AwaitHolding::new(tcx, conf))),\n        Box::new(|_| Box::new(serde_api::SerdeApi)),\n        Box::new(move |_| Box::new(types::Types::new(conf))),\n        Box::new(move |_| Box::new(booleans::NonminimalBool::new(conf))),\n        Box::new(|_| Box::new(enum_clike::UnportableVariant)),\n        Box::new(move |_| Box::new(float_literal::FloatLiteral::new(conf))),\n        Box::new(|_| Box::new(ptr::Ptr)),\n        Box::new(|_| Box::new(needless_bool::NeedlessBool)),\n        Box::new(|_| Box::new(bool_comparison::BoolComparison)),\n        Box::new(|_| Box::new(needless_for_each::NeedlessForEach)),\n        Box::new(|_| Box::new(misc::LintPass)),\n        Box::new(|_| Box::new(eta_reduction::EtaReduction)),\n        Box::new(|_| Box::new(mut_mut::MutMut::default())),\n        Box::new(|_| Box::new(unnecessary_mut_passed::UnnecessaryMutPassed)),\n        Box::new(|_| Box::<significant_drop_tightening::SignificantDropTightening<'_>>::default()),\n        Box::new(move |_| Box::new(len_zero::LenZero::new(conf))),\n        Box::new(|_| Box::new(len_without_is_empty::LenWithoutIsEmpty)),\n        Box::new(move |_| Box::new(attrs::Attributes::new(conf))),\n        Box::new(|_| Box::new(blocks_in_conditions::BlocksInConditions)),\n        Box::new(|_| Box::new(unicode::Unicode)),\n        Box::new(|_| Box::new(uninit_vec::UninitVec)),\n        Box::new(|_| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd)),\n        Box::new(|_| Box::new(strings::StringAdd)),\n        Box::new(|_| Box::new(implicit_return::ImplicitReturn)),\n        Box::new(move |_| Box::new(implicit_saturating_sub::ImplicitSaturatingSub::new(conf))),\n        Box::new(|_| Box::new(default_numeric_fallback::DefaultNumericFallback)),\n        Box::new(|_| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions)),\n        Box::new(move |_| Box::new(approx_const::ApproxConstant::new(conf))),\n        Box::new(move |_| Box::new(matches::Matches::new(conf))),\n        Box::new(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustive::new(conf))),\n        Box::new(move |_| Box::new(manual_strip::ManualStrip::new(conf))),\n        Box::new(move |_| Box::new(checked_conversions::CheckedConversions::new(conf))),\n        Box::new(move |_| Box::new(mem_replace::MemReplace::new(conf))),\n        Box::new(move |_| Box::new(ranges::Ranges::new(conf))),\n        Box::new(move |_| Box::new(from_over_into::FromOverInto::new(conf))),\n        Box::new(move |_| Box::new(use_self::UseSelf::new(conf))),\n        Box::new(move |_| Box::new(missing_const_for_fn::MissingConstForFn::new(conf))),\n        Box::new(move |_| Box::new(needless_question_mark::NeedlessQuestionMark)),\n        Box::new(move |_| Box::new(casts::Casts::new(conf))),\n        Box::new(|_| Box::new(size_of_in_element_count::SizeOfInElementCount)),\n        Box::new(|_| Box::new(same_name_method::SameNameMethod)),\n        Box::new(move |_| Box::new(index_refutable_slice::IndexRefutableSlice::new(conf))),\n        Box::new(|_| Box::<shadow::Shadow>::default()),\n        Box::new(move |_| {\n            Box::new(inconsistent_struct_constructor::InconsistentStructConstructor::new(\n                conf,\n            ))\n        }),\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move |_| Box::new(methods::Methods::new(conf, format_args.clone())))\n        },\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move |_| Box::new(unit_types::UnitTypes::new(format_args.clone())))\n        },\n        Box::new(move |_| Box::new(loops::Loops::new(conf))),\n        Box::new(|_| Box::<main_recursion::MainRecursion>::default()),\n        Box::new(move |_| Box::new(lifetimes::Lifetimes::new(conf))),\n        Box::new(|_| Box::new(entry::HashMapPass)),\n        Box::new(|_| Box::new(minmax::MinMaxPass)),\n        Box::new(|_| Box::new(zero_div_zero::ZeroDiv)),\n        Box::new(|_| Box::new(mutex_atomic::Mutex)),\n        Box::new(|_| Box::new(needless_update::NeedlessUpdate)),\n        Box::new(|_| Box::new(needless_borrowed_ref::NeedlessBorrowedRef)),\n        Box::new(|_| Box::new(borrow_deref_ref::BorrowDerefRef)),\n        Box::new(|_| Box::<no_effect::NoEffect>::default()),\n        Box::new(|_| Box::new(temporary_assignment::TemporaryAssignment)),\n        Box::new(move |_| Box::new(transmute::Transmute::new(conf))),\n        Box::new(move |_| Box::new(cognitive_complexity::CognitiveComplexity::new(conf))),\n        Box::new(move |_| Box::new(escape::BoxedLocal::new(conf))),\n        Box::new(move |_| Box::new(useless_vec::UselessVec::new(conf))),\n        Box::new(move |_| Box::new(panic_unimplemented::PanicUnimplemented::new(conf))),\n        Box::new(|_| Box::new(strings::StringLitAsBytes)),\n        Box::new(|_| Box::new(derive::Derive)),\n        Box::new(move |_| Box::new(derivable_impls::DerivableImpls::new(conf))),\n        Box::new(|_| Box::new(drop_forget_ref::DropForgetRef)),\n        Box::new(|_| Box::new(empty_enums::EmptyEnums)),\n        Box::new(|_| Box::<regex::Regex>::default()),\n        Box::new(move |tcx| Box::new(ifs::CopyAndPaste::new(tcx, conf))),\n        Box::new(|_| Box::new(copy_iterator::CopyIterator)),\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move |_| Box::new(format::UselessFormat::new(format_args.clone())))\n        },\n        Box::new(|_| Box::new(swap::Swap)),\n        Box::new(|_| Box::new(panicking_overflow_checks::PanickingOverflowChecks)),\n        Box::new(|_| Box::<new_without_default::NewWithoutDefault>::default()),\n        Box::new(move |_| Box::new(disallowed_names::DisallowedNames::new(conf))),\n        Box::new(move |tcx| Box::new(functions::Functions::new(tcx, conf))),\n        Box::new(move |_| Box::new(doc::Documentation::new(conf))),\n        Box::new(|_| Box::new(neg_multiply::NegMultiply)),\n        Box::new(|_| Box::new(let_if_seq::LetIfSeq)),\n        Box::new(|_| Box::new(mixed_read_write_in_expression::EvalOrderDependence)),\n        Box::new(move |_| Box::new(missing_doc::MissingDoc::new(conf))),\n        Box::new(|_| Box::new(missing_inline::MissingInline)),\n        Box::new(move |_| Box::new(exhaustive_items::ExhaustiveItems)),\n        Box::new(|_| Box::new(unused_result_ok::UnusedResultOk)),\n        Box::new(|_| Box::new(match_result_ok::MatchResultOk)),\n        Box::new(|_| Box::new(partialeq_ne_impl::PartialEqNeImpl)),\n        Box::new(|_| Box::new(unused_io_amount::UnusedIoAmount)),\n        Box::new(move |_| Box::new(large_enum_variant::LargeEnumVariant::new(conf))),\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move |_| Box::new(explicit_write::ExplicitWrite::new(format_args.clone())))\n        },\n        Box::new(|_| Box::new(needless_pass_by_value::NeedlessPassByValue)),\n        Box::new(move |tcx| Box::new(pass_by_ref_or_value::PassByRefOrValue::new(tcx, conf))),\n        Box::new(|_| Box::new(ref_option_ref::RefOptionRef)),\n        Box::new(|_| Box::new(infinite_iter::InfiniteIter)),\n        Box::new(|_| Box::new(inline_fn_without_body::InlineFnWithoutBody)),\n        Box::new(|_| Box::<useless_conversion::UselessConversion>::default()),\n        Box::new(|_| Box::new(implicit_hasher::ImplicitHasher)),\n        Box::new(|_| Box::new(fallible_impl_from::FallibleImplFrom)),\n        Box::new(move |_| Box::new(question_mark::QuestionMark::new(conf))),\n        Box::new(|_| Box::new(question_mark_used::QuestionMarkUsed)),\n        Box::new(|_| Box::new(suspicious_trait_impl::SuspiciousImpl)),\n        Box::new(|_| Box::new(map_unit_fn::MapUnit)),\n        Box::new(move |_| Box::new(inherent_impl::MultipleInherentImpl::new(conf))),\n        Box::new(|_| Box::new(neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd)),\n        Box::new(move |_| Box::new(unwrap::Unwrap::new(conf))),\n        Box::new(move |_| Box::new(indexing_slicing::IndexingSlicing::new(conf))),\n        Box::new(move |tcx| Box::new(non_copy_const::NonCopyConst::new(tcx, conf))),\n        Box::new(|_| Box::new(redundant_clone::RedundantClone)),\n        Box::new(|_| Box::new(slow_vector_initialization::SlowVectorInit)),\n        Box::new(move |_| Box::new(unnecessary_wraps::UnnecessaryWraps::new(conf))),\n        Box::new(|_| Box::new(assertions_on_constants::AssertionsOnConstants::new(conf))),\n        Box::new(|_| Box::new(assertions_on_result_states::AssertionsOnResultStates)),\n        Box::new(|_| Box::new(inherent_to_string::InherentToString)),\n        Box::new(move |_| Box::new(trait_bounds::TraitBounds::new(conf))),\n        Box::new(|_| Box::new(comparison_chain::ComparisonChain)),\n        Box::new(move |tcx| Box::new(mut_key::MutableKeyType::new(tcx, conf))),\n        Box::new(|_| Box::new(reference::DerefAddrOf)),\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move |_| Box::new(format_impl::FormatImpl::new(format_args.clone())))\n        },\n        Box::new(|_| Box::new(redundant_closure_call::RedundantClosureCall)),\n        Box::new(|_| Box::new(unused_unit::UnusedUnit)),\n        Box::new(|_| Box::new(returns::Return)),\n        Box::new(move |_| Box::new(collapsible_if::CollapsibleIf::new(conf))),\n        Box::new(|_| Box::new(items_after_statements::ItemsAfterStatements)),\n        Box::new(|_| Box::new(needless_parens_on_range_literals::NeedlessParensOnRangeLiterals)),\n        Box::new(|_| Box::new(needless_continue::NeedlessContinue)),\n        Box::new(|_| Box::new(create_dir::CreateDir)),\n        Box::new(move |_| Box::new(item_name_repetitions::ItemNameRepetitions::new(conf))),\n        Box::new(move |_| Box::new(upper_case_acronyms::UpperCaseAcronyms::new(conf))),\n        Box::new(|_| Box::<default::Default>::default()),\n        Box::new(move |_| Box::new(unused_self::UnusedSelf::new(conf))),\n        Box::new(|_| Box::new(mutable_debug_assertion::DebugAssertWithMutCall)),\n        Box::new(|_| Box::new(exit::Exit)),\n        Box::new(move |_| Box::new(to_digit_is_some::ToDigitIsSome::new(conf))),\n        Box::new(move |_| Box::new(large_stack_arrays::LargeStackArrays::new(conf))),\n        Box::new(move |_| Box::new(large_const_arrays::LargeConstArrays::new(conf))),\n        Box::new(|_| Box::new(floating_point_arithmetic::FloatingPointArithmetic)),\n        Box::new(|_| Box::new(as_conversions::AsConversions)),\n        Box::new(|_| Box::new(let_underscore::LetUnderscore)),\n        Box::new(move |_| Box::new(excessive_bools::ExcessiveBools::new(conf))),\n        Box::new(move |_| Box::new(wildcard_imports::WildcardImports::new(conf))),\n        Box::new(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default()),\n        Box::new(|_| Box::<dereference::Dereferencing<'_>>::default()),\n        Box::new(|_| Box::new(option_if_let_else::OptionIfLetElse)),\n        Box::new(|_| Box::new(future_not_send::FutureNotSend)),\n        Box::new(move |_| Box::new(large_futures::LargeFuture::new(conf))),\n        Box::new(|_| Box::new(if_let_mutex::IfLetMutex)),\n        Box::new(|_| Box::new(if_not_else::IfNotElse)),\n        Box::new(|_| Box::new(equatable_if_let::PatternEquality)),\n        Box::new(|_| Box::new(manual_async_fn::ManualAsyncFn)),\n        Box::new(|_| Box::new(panic_in_result_fn::PanicInResultFn)),\n        Box::new(|_| Box::<macro_use::MacroUseImports>::default()),\n        Box::new(|_| Box::new(pattern_type_mismatch::PatternTypeMismatch)),\n        Box::new(|_| Box::<unwrap_in_result::UnwrapInResult>::default()),\n        Box::new(|_| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned)),\n        Box::new(|_| Box::new(async_yields_async::AsyncYieldsAsync)),\n        {\n            let attrs = attr_storage.clone();\n            Box::new(move |tcx| Box::new(disallowed_macros::DisallowedMacros::new(tcx, conf, attrs.clone())))\n        },\n        Box::new(move |tcx| Box::new(disallowed_methods::DisallowedMethods::new(tcx, conf))),\n        Box::new(|_| Box::new(empty_drop::EmptyDrop)),\n        Box::new(|_| Box::new(strings::StrToString)),\n        Box::new(|_| Box::new(zero_sized_map_values::ZeroSizedMapValues)),\n        Box::new(|_| Box::<vec_init_then_push::VecInitThenPush>::default()),\n        Box::new(|_| Box::new(redundant_slicing::RedundantSlicing)),\n        Box::new(|_| Box::new(from_str_radix_10::FromStrRadix10)),\n        Box::new(move |_| Box::new(if_then_some_else_none::IfThenSomeElseNone::new(conf))),\n        Box::new(|_| Box::new(bool_assert_comparison::BoolAssertComparison)),\n        Box::new(|_| Box::<unused_async::UnusedAsync>::default()),\n        Box::new(move |tcx| Box::new(disallowed_types::DisallowedTypes::new(tcx, conf))),\n        Box::new(move |tcx| Box::new(missing_enforced_import_rename::ImportRename::new(tcx, conf))),\n        Box::new(move |_| Box::new(strlen_on_c_strings::StrlenOnCStrings::new(conf))),\n        Box::new(move |_| Box::new(self_named_constructors::SelfNamedConstructors)),\n        Box::new(move |_| Box::new(iter_not_returning_iterator::IterNotReturningIterator)),\n        Box::new(move |_| Box::new(manual_assert::ManualAssert)),\n        Box::new(move |_| Box::new(non_send_fields_in_send_ty::NonSendFieldInSendTy::new(conf))),\n        Box::new(move |_| Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks::new(conf))),\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move |tcx| Box::new(format_args::FormatArgs::new(tcx, conf, format_args.clone())))\n        },\n        Box::new(|_| Box::new(trailing_empty_array::TrailingEmptyArray)),\n        Box::new(|_| Box::new(needless_late_init::NeedlessLateInit)),\n        Box::new(|_| Box::new(return_self_not_must_use::ReturnSelfNotMustUse)),\n        Box::new(|_| Box::new(init_numbered_fields::NumberedFields)),\n        Box::new(move |_| Box::new(manual_bits::ManualBits::new(conf))),\n        Box::new(|_| Box::new(default_union_representation::DefaultUnionRepresentation)),\n        Box::new(|_| Box::<only_used_in_recursion::OnlyUsedInRecursion>::default()),\n        Box::new(move |_| Box::new(dbg_macro::DbgMacro::new(conf))),\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move |_| Box::new(write::Write::new(conf, format_args.clone())))\n        },\n        Box::new(move |_| Box::new(cargo::Cargo::new(conf))),\n        Box::new(|_| Box::new(empty_with_brackets::EmptyWithBrackets::default())),\n        Box::new(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings)),\n        {\n            let format_args = format_args_storage.clone();\n            Box::new(move |_| Box::new(format_push_string::FormatPushString::new(format_args.clone())))\n        },\n        Box::new(move |_| Box::new(large_include_file::LargeIncludeFile::new(conf))),\n        Box::new(|_| Box::new(strings::TrimSplitWhitespace)),\n        Box::new(|_| Box::new(rc_clone_in_vec_init::RcCloneInVecInit)),\n        Box::new(|_| Box::new(swap_ptr_to_ref::SwapPtrToRef)),\n        Box::new(|_| Box::new(mismatching_type_param_order::TypeParamMismatch)),\n        Box::new(|_| Box::new(read_zero_byte_vec::ReadZeroByteVec)),\n        Box::new(|_| Box::new(default_instead_of_iter_empty::DefaultIterEmpty)),\n        Box::new(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(conf))),\n        Box::new(move |_| Box::new(manual_retain::ManualRetain::new(conf))),\n        Box::new(move |_| Box::new(manual_rotate::ManualRotate)),\n        Box::new(move |_| Box::new(operators::Operators::new(conf))),\n        Box::new(move |_| Box::new(std_instead_of_core::StdReexports::new(conf))),\n        Box::new(move |_| Box::new(time_subtraction::UncheckedTimeSubtraction::new(conf))),\n        Box::new(|_| Box::new(partialeq_to_none::PartialeqToNone)),\n        Box::new(move |_| Box::new(manual_abs_diff::ManualAbsDiff::new(conf))),\n        Box::new(move |_| Box::new(manual_clamp::ManualClamp::new(conf))),\n        Box::new(|_| Box::new(manual_string_new::ManualStringNew)),\n        Box::new(|_| Box::new(unused_peekable::UnusedPeekable)),\n        Box::new(|_| Box::new(bool_to_int_with_if::BoolToIntWithIf)),\n        Box::new(|_| Box::new(box_default::BoxDefault)),\n        Box::new(|_| Box::new(implicit_saturating_add::ImplicitSaturatingAdd)),\n        Box::new(|_| Box::new(missing_trait_methods::MissingTraitMethods)),\n        Box::new(|_| Box::new(from_raw_with_void_ptr::FromRawWithVoidPtr)),\n        Box::new(|_| Box::new(suspicious_xor_used_as_pow::ConfusingXorAndPow)),\n        Box::new(move |_| Box::new(manual_is_ascii_check::ManualIsAsciiCheck::new(conf))),\n        Box::new(move |_| Box::new(semicolon_block::SemicolonBlock::new(conf))),\n        Box::new(|_| Box::new(permissions_set_readonly_false::PermissionsSetReadonlyFalse)),\n        Box::new(|_| Box::new(size_of_ref::SizeOfRef)),\n        Box::new(|_| Box::new(multiple_unsafe_ops_per_block::MultipleUnsafeOpsPerBlock)),\n        Box::new(move |_| Box::new(extra_unused_type_parameters::ExtraUnusedTypeParameters::new(conf))),\n        Box::new(|_| Box::new(no_mangle_with_rust_abi::NoMangleWithRustAbi)),\n        Box::new(|_| Box::new(collection_is_never_read::CollectionIsNeverRead)),\n        Box::new(|_| Box::new(missing_assert_message::MissingAssertMessage)),\n        Box::new(|_| Box::new(needless_maybe_sized::NeedlessMaybeSized)),\n        Box::new(|_| Box::new(redundant_async_block::RedundantAsyncBlock)),\n        Box::new(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(conf))),\n        Box::new(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct)),\n        Box::new(move |_| Box::new(unnecessary_box_returns::UnnecessaryBoxReturns::new(conf))),\n        Box::new(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule)),\n        Box::new(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation::new(conf))),\n        Box::new(|_| Box::new(items_after_test_module::ItemsAfterTestModule)),\n        Box::new(|_| Box::new(default_constructed_unit_structs::DefaultConstructedUnitStructs)),\n        Box::new(|_| Box::new(missing_fields_in_debug::MissingFieldsInDebug)),\n        Box::new(|_| Box::new(endian_bytes::EndianBytes)),\n        Box::new(|_| Box::new(redundant_type_annotations::RedundantTypeAnnotations)),\n        Box::new(|_| Box::new(arc_with_non_send_sync::ArcWithNonSendSync)),\n        Box::new(|_| Box::new(needless_ifs::NeedlessIfs)),\n        Box::new(move |_| Box::new(min_ident_chars::MinIdentChars::new(conf))),\n        Box::new(move |_| Box::new(large_stack_frames::LargeStackFrames::new(conf))),\n        Box::new(|_| Box::new(single_range_in_vec_init::SingleRangeInVecInit)),\n        Box::new(move |_| Box::new(needless_pass_by_ref_mut::NeedlessPassByRefMut::new(conf))),\n        Box::new(|tcx| Box::new(non_canonical_impls::NonCanonicalImpls::new(tcx))),\n        Box::new(move |_| Box::new(single_call_fn::SingleCallFn::new(conf))),\n        Box::new(move |_| Box::new(legacy_numeric_constants::LegacyNumericConstants::new(conf))),\n        Box::new(|_| Box::new(manual_range_patterns::ManualRangePatterns)),\n        Box::new(move |_| Box::new(tuple_array_conversions::TupleArrayConversions::new(conf))),\n        Box::new(move |_| Box::new(manual_float_methods::ManualFloatMethods::new(conf))),\n        Box::new(|_| Box::new(four_forward_slashes::FourForwardSlashes)),\n        Box::new(|_| Box::new(error_impl_error::ErrorImplError)),\n        Box::new(move |_| Box::new(absolute_paths::AbsolutePaths::new(conf))),\n        Box::new(|_| Box::new(redundant_locals::RedundantLocals)),\n        Box::new(|_| Box::new(ignored_unit_patterns::IgnoredUnitPatterns)),\n        Box::new(|_| Box::<reserve_after_initialization::ReserveAfterInitialization>::default()),\n        Box::new(|_| Box::new(implied_bounds_in_impls::ImpliedBoundsInImpls)),\n        Box::new(|_| Box::new(missing_asserts_for_indexing::MissingAssertsForIndexing)),\n        Box::new(|_| Box::new(unnecessary_map_on_constructor::UnnecessaryMapOnConstructor)),\n        Box::new(move |_| {\n            Box::new(needless_borrows_for_generic_args::NeedlessBorrowsForGenericArgs::new(\n                conf,\n            ))\n        }),\n        Box::new(move |_| Box::new(manual_hash_one::ManualHashOne::new(conf))),\n        Box::new(|_| Box::new(iter_without_into_iter::IterWithoutIntoIter)),\n        Box::new(|_| Box::<pathbuf_init_then_push::PathbufThenPush<'_>>::default()),\n        Box::new(|_| Box::new(iter_over_hash_type::IterOverHashType)),\n        Box::new(|_| Box::new(impl_hash_with_borrow_str_and_bytes::ImplHashWithBorrowStrBytes)),\n        Box::new(move |_| Box::new(repeat_vec_with_capacity::RepeatVecWithCapacity::new(conf))),\n        Box::new(|_| Box::new(uninhabited_references::UninhabitedReferences)),\n        Box::new(|_| Box::new(ineffective_open_options::IneffectiveOpenOptions)),\n        Box::new(|_| Box::<unconditional_recursion::UnconditionalRecursion>::default()),\n        Box::new(move |_| Box::new(pub_underscore_fields::PubUnderscoreFields::new(conf))),\n        Box::new(move |_| Box::new(missing_const_for_thread_local::MissingConstForThreadLocal::new(conf))),\n        Box::new(move |tcx| Box::new(incompatible_msrv::IncompatibleMsrv::new(tcx, conf))),\n        Box::new(|_| Box::new(to_string_trait_impl::ToStringTraitImpl)),\n        Box::new(move |_| Box::new(assigning_clones::AssigningClones::new(conf))),\n        Box::new(|_| Box::new(zero_repeat_side_effects::ZeroRepeatSideEffects)),\n        Box::new(move |_| Box::new(macro_metavars_in_unsafe::ExprMetavarsInUnsafe::new(conf))),\n        Box::new(move |_| Box::new(string_patterns::StringPatterns::new(conf))),\n        Box::new(|_| Box::new(set_contains_or_insert::SetContainsOrInsert)),\n        Box::new(|_| Box::new(zombie_processes::ZombieProcesses)),\n        Box::new(|_| Box::new(pointers_in_nomem_asm_block::PointersInNomemAsmBlock)),\n        Box::new(move |_| Box::new(manual_is_power_of_two::ManualIsPowerOfTwo::new(conf))),\n        Box::new(|_| Box::new(non_zero_suggestions::NonZeroSuggestions)),\n        Box::new(|_| Box::new(literal_string_with_formatting_args::LiteralStringWithFormattingArg)),\n        Box::new(move |_| Box::new(unused_trait_names::UnusedTraitNames::new(conf))),\n        Box::new(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp)),\n        Box::new(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound)),\n        Box::new(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf))),\n        Box::new(|_| Box::new(useless_concat::UselessConcat)),\n        Box::new(|_| Box::new(unneeded_struct_pattern::UnneededStructPattern)),\n        Box::new(|_| Box::<unnecessary_semicolon::UnnecessarySemicolon>::default()),\n        Box::new(move |_| Box::new(non_std_lazy_statics::NonStdLazyStatic::new(conf))),\n        Box::new(|_| Box::new(manual_option_as_slice::ManualOptionAsSlice::new(conf))),\n        Box::new(|_| Box::new(single_option_map::SingleOptionMap)),\n        Box::new(move |_| Box::new(redundant_test_prefix::RedundantTestPrefix)),\n        Box::new(|_| Box::new(cloned_ref_to_slice_refs::ClonedRefToSliceRefs::new(conf))),\n        Box::new(|_| Box::new(infallible_try_from::InfallibleTryFrom)),\n        Box::new(|_| Box::new(coerce_container_to_any::CoerceContainerToAny)),\n        Box::new(|_| Box::new(toplevel_ref_arg::ToplevelRefArg)),\n        Box::new(|_| Box::new(volatile_composites::VolatileComposites)),\n        Box::new(|_| Box::<replace_box::ReplaceBox>::default()),\n        Box::new(move |tcx| Box::new(disallowed_fields::DisallowedFields::new(tcx, conf))),\n        Box::new(move |_| Box::new(manual_ilog2::ManualIlog2::new(conf))),\n        Box::new(|_| Box::new(same_length_and_capacity::SameLengthAndCapacity)),\n        Box::new(move |tcx| Box::new(duration_suboptimal_units::DurationSuboptimalUnits::new(tcx, conf))),\n        Box::new(move |_| Box::new(manual_take::ManualTake::new(conf))),\n        Box::new(|_| Box::new(manual_checked_ops::ManualCheckedOps)),\n        Box::new(move |_| Box::new(manual_pop_if::ManualPopIf::new(conf))),\n        // add late passes here, used by `cargo dev new_lint`\n    ];\n    store.late_passes.extend(late_lints);\n}\n"
  },
  {
    "path": "clippy_lints/src/lifetimes.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::{is_from_proc_macro, trait_ref_of_method};\nuse itertools::Itertools;\nuse rustc_ast::visit::{try_visit, walk_list};\nuse rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};\nuse rustc_errors::Applicability;\nuse rustc_hir::FnRetTy::Return;\nuse rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};\nuse rustc_hir::intravisit::{\n    Visitor, VisitorExt, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_param_bound,\n    walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_unambig_ty, walk_where_predicate,\n};\nuse rustc_hir::{\n    AmbigArg, BodyId, FnDecl, FnPtrTy, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind,\n    Generics, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeKind, LifetimeParamKind, Node,\n    PolyTraitRef, PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate,\n    WherePredicateKind, lang_items,\n};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::hir::nested_filter as middle_nested_filter;\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::symbol::{Ident, kw};\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for lifetime annotations which can be replaced with anonymous lifetimes (`'_`).\n    ///\n    /// ### Why is this bad?\n    /// The additional lifetimes can make the code look more complicated.\n    ///\n    /// ### Known problems\n    /// This lint ignores functions with `where` clauses that reference\n    /// lifetimes to prevent false positives.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::str::Chars;\n    /// fn f<'a>(x: &'a str) -> Chars<'a> {\n    ///     x.chars()\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::str::Chars;\n    /// fn f(x: &str) -> Chars<'_> {\n    ///     x.chars()\n    /// }\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub ELIDABLE_LIFETIME_NAMES,\n    pedantic,\n    \"lifetime name that can be replaced with the anonymous lifetime\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for lifetimes in generics that are never used\n    /// anywhere else.\n    ///\n    /// ### Why is this bad?\n    /// The additional lifetimes make the code look more\n    /// complicated, while there is nothing out of the ordinary going on. Removing\n    /// them leads to more readable code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // unnecessary lifetimes\n    /// fn unused_lifetime<'a>(x: u8) {\n    ///     // ..\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn no_lifetime(x: u8) {\n    ///     // ...\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EXTRA_UNUSED_LIFETIMES,\n    complexity,\n    \"unused lifetimes in function definitions\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for lifetime annotations which can be removed by\n    /// relying on lifetime elision.\n    ///\n    /// ### Why is this bad?\n    /// The additional lifetimes make the code look more\n    /// complicated, while there is nothing out of the ordinary going on. Removing\n    /// them leads to more readable code.\n    ///\n    /// ### Known problems\n    /// This lint ignores functions with `where` clauses that reference\n    /// lifetimes to prevent false positives.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // Unnecessary lifetime annotations\n    /// fn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 {\n    ///     x\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn elided(x: &u8, y: u8) -> &u8 {\n    ///     x\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_LIFETIMES,\n    complexity,\n    \"using explicit lifetimes for references in function arguments when elision rules \\\n     would allow omitting them\"\n}\n\nimpl_lint_pass!(Lifetimes => [\n    ELIDABLE_LIFETIME_NAMES,\n    EXTRA_UNUSED_LIFETIMES,\n    NEEDLESS_LIFETIMES,\n]);\n\npub struct Lifetimes {\n    msrv: Msrv,\n}\n\nimpl Lifetimes {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Lifetimes {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Fn {\n            ref sig,\n            generics,\n            body: id,\n            ..\n        } = item.kind\n        {\n            check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, self.msrv, || {\n                is_from_proc_macro(cx, item)\n            });\n        } else if let ItemKind::Impl(impl_) = &item.kind\n            && !item.span.from_expansion()\n            && !is_from_proc_macro(cx, item)\n        {\n            report_extra_impl_lifetimes(cx, impl_);\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {\n        if let ImplItemKind::Fn(ref sig, id) = item.kind {\n            let report_extra_lifetimes = trait_ref_of_method(cx, item.owner_id).is_none();\n            check_fn_inner(\n                cx,\n                sig,\n                Some(id),\n                None,\n                item.generics,\n                item.span,\n                report_extra_lifetimes,\n                self.msrv,\n                || is_from_proc_macro(cx, item),\n            );\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {\n        if let TraitItemKind::Fn(ref sig, ref body) = item.kind {\n            let (body, trait_sig) = match *body {\n                TraitFn::Required(sig) => (None, Some(sig)),\n                TraitFn::Provided(id) => (Some(id), None),\n            };\n            check_fn_inner(\n                cx,\n                sig,\n                body,\n                trait_sig,\n                item.generics,\n                item.span,\n                true,\n                self.msrv,\n                || is_from_proc_macro(cx, item),\n            );\n        }\n    }\n}\n\n#[expect(clippy::too_many_arguments)]\nfn check_fn_inner<'tcx>(\n    cx: &LateContext<'tcx>,\n    sig: &'tcx FnSig<'_>,\n    body: Option<BodyId>,\n    trait_sig: Option<&[Option<Ident>]>,\n    generics: &'tcx Generics<'_>,\n    span: Span,\n    report_extra_lifetimes: bool,\n    msrv: Msrv,\n    is_from_proc_macro: impl FnOnce() -> bool,\n) {\n    if span.in_external_macro(cx.sess().source_map()) || has_where_lifetimes(cx, generics) {\n        return;\n    }\n\n    let types = generics\n        .params\n        .iter()\n        .filter(|param| matches!(param.kind, GenericParamKind::Type { .. }));\n\n    for typ in types {\n        if !typ.span.eq_ctxt(span) {\n            return;\n        }\n\n        for pred in generics.bounds_for_param(typ.def_id) {\n            if pred.origin == PredicateOrigin::WhereClause {\n                // has_where_lifetimes checked that this predicate contains no lifetime.\n                continue;\n            }\n\n            for bound in pred.bounds {\n                let mut visitor = RefVisitor::new(cx);\n                walk_param_bound(&mut visitor, bound);\n                if visitor.lts.iter().any(|lt| matches!(lt.kind, LifetimeKind::Param(_))) {\n                    return;\n                }\n                if let GenericBound::Trait(ref trait_ref) = *bound {\n                    let params = &trait_ref\n                        .trait_ref\n                        .path\n                        .segments\n                        .last()\n                        .expect(\"a path must have at least one segment\")\n                        .args;\n                    if let Some(params) = *params {\n                        let lifetimes = params.args.iter().filter_map(|arg| match arg {\n                            GenericArg::Lifetime(lt) => Some(lt),\n                            _ => None,\n                        });\n                        for bound in lifetimes {\n                            if bound.kind != LifetimeKind::Static && !bound.is_elided() {\n                                return;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    let elidable = could_use_elision(cx, sig.decl, body, trait_sig, generics.params, msrv);\n    let has_elidable_lts = elidable\n        .as_ref()\n        .is_some_and(|(_, usages)| !usages.iter().any(|usage| !usage.ident.span.eq_ctxt(span)));\n\n    // Only check is_from_proc_macro if we're about to emit a lint (it's an expensive check)\n    if (has_elidable_lts || report_extra_lifetimes) && is_from_proc_macro() {\n        return;\n    }\n\n    if let Some((elidable_lts, usages)) = elidable\n        && has_elidable_lts\n    {\n        // async functions have usages whose spans point at the lifetime declaration which messes up\n        // suggestions\n        let include_suggestions = !sig.header.is_async();\n        report_elidable_lifetimes(cx, generics, &elidable_lts, &usages, include_suggestions);\n    }\n\n    if report_extra_lifetimes {\n        self::report_extra_lifetimes(cx, sig.decl, generics);\n    }\n}\n\nfn could_use_elision<'tcx>(\n    cx: &LateContext<'tcx>,\n    func: &'tcx FnDecl<'_>,\n    body: Option<BodyId>,\n    trait_sig: Option<&[Option<Ident>]>,\n    named_generics: &'tcx [GenericParam<'_>],\n    msrv: Msrv,\n) -> Option<(Vec<LocalDefId>, Vec<Lifetime>)> {\n    // There are two scenarios where elision works:\n    // * no output references, all input references have different LT\n    // * output references, exactly one input reference with same LT\n    // All lifetimes must be unnamed, 'static or defined without bounds on the\n    // level of the current item.\n\n    // check named LTs\n    let allowed_lts = allowed_lts_from(named_generics);\n\n    // these will collect all the lifetimes for references in arg/return types\n    let mut input_visitor = RefVisitor::new(cx);\n    let mut output_visitor = RefVisitor::new(cx);\n\n    // extract lifetimes in input argument types\n    for arg in func.inputs {\n        input_visitor.visit_ty_unambig(arg);\n    }\n    // extract lifetimes in output type\n    if let Return(ty) = func.output {\n        output_visitor.visit_ty_unambig(ty);\n    }\n    for lt in named_generics {\n        input_visitor.visit_generic_param(lt);\n    }\n\n    if input_visitor.abort() || output_visitor.abort() {\n        return None;\n    }\n\n    let input_lts = input_visitor.lts;\n    let output_lts = output_visitor.lts;\n\n    if let Some(&[trait_sig]) = trait_sig\n        && non_elidable_self_type(cx, func, trait_sig, msrv)\n    {\n        return None;\n    }\n\n    if let Some(body_id) = body {\n        let body = cx.tcx.hir_body(body_id);\n\n        let first_ident = body.params.first().and_then(|param| param.pat.simple_ident());\n        if non_elidable_self_type(cx, func, first_ident, msrv) {\n            return None;\n        }\n\n        let mut checker = BodyLifetimeChecker::new(cx);\n        if checker.visit_expr(body.value).is_break() {\n            return None;\n        }\n    }\n\n    // check for lifetimes from higher scopes\n    for lt in input_lts.iter().chain(output_lts.iter()) {\n        if let Some(id) = named_lifetime(lt)\n            && !allowed_lts.contains(&id)\n        {\n            return None;\n        }\n    }\n\n    // check for higher-ranked trait bounds\n    if !input_visitor.nested_elision_site_lts.is_empty() || !output_visitor.nested_elision_site_lts.is_empty() {\n        let allowed_lts: FxHashSet<_> = allowed_lts.iter().map(|id| cx.tcx.item_name(id.to_def_id())).collect();\n        for lt in input_visitor.nested_elision_site_lts {\n            if allowed_lts.contains(&lt.ident.name) {\n                return None;\n            }\n        }\n        for lt in output_visitor.nested_elision_site_lts {\n            if allowed_lts.contains(&lt.ident.name) {\n                return None;\n            }\n        }\n    }\n\n    // A lifetime can be newly elided if:\n    // - It occurs only once among the inputs.\n    // - If there are multiple input lifetimes, then the newly elided lifetime does not occur among the\n    //   outputs (because eliding such an lifetime would create an ambiguity).\n    let elidable_lts = named_lifetime_occurrences(&input_lts)\n        .into_iter()\n        .filter_map(|(def_id, occurrences)| {\n            if occurrences == 1\n                && (input_lts.len() == 1 || !output_lts.iter().any(|lt| named_lifetime(lt) == Some(def_id)))\n            {\n                Some(def_id)\n            } else {\n                None\n            }\n        })\n        .collect::<Vec<_>>();\n\n    if elidable_lts.is_empty() {\n        return None;\n    }\n\n    let usages = itertools::chain(input_lts, output_lts).collect();\n\n    Some((elidable_lts, usages))\n}\n\nfn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxIndexSet<LocalDefId> {\n    named_generics\n        .iter()\n        .filter_map(|par| {\n            if let GenericParamKind::Lifetime { .. } = par.kind {\n                Some(par.def_id)\n            } else {\n                None\n            }\n        })\n        .collect()\n}\n\n// elision doesn't work for explicit self types before Rust 1.81, see rust-lang/rust#69064\nfn non_elidable_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>, msrv: Msrv) -> bool {\n    if let Some(ident) = ident\n        && ident.name == kw::SelfLower\n        && !func.implicit_self.has_implicit_self()\n        && let Some(self_ty) = func.inputs.first()\n        && !msrv.meets(cx, msrvs::EXPLICIT_SELF_TYPE_ELISION)\n    {\n        let mut visitor = RefVisitor::new(cx);\n        visitor.visit_ty_unambig(self_ty);\n\n        !visitor.all_lts().is_empty()\n    } else {\n        false\n    }\n}\n\n/// Number of times each named lifetime occurs in the given slice. Returns a vector to preserve\n/// relative order.\n#[must_use]\nfn named_lifetime_occurrences(lts: &[Lifetime]) -> Vec<(LocalDefId, usize)> {\n    let mut occurrences = Vec::new();\n    for lt in lts {\n        if let Some(curr_def_id) = named_lifetime(lt) {\n            if let Some(pair) = occurrences\n                .iter_mut()\n                .find(|(prev_def_id, _)| *prev_def_id == curr_def_id)\n            {\n                pair.1 += 1;\n            } else {\n                occurrences.push((curr_def_id, 1));\n            }\n        }\n    }\n    occurrences\n}\n\nfn named_lifetime(lt: &Lifetime) -> Option<LocalDefId> {\n    match lt.kind {\n        LifetimeKind::Param(id) if !lt.is_anonymous() => Some(id),\n        _ => None,\n    }\n}\n\nstruct RefVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    lts: Vec<Lifetime>,\n    nested_elision_site_lts: Vec<Lifetime>,\n    unelided_trait_object_lifetime: bool,\n}\n\nimpl<'a, 'tcx> RefVisitor<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>) -> Self {\n        Self {\n            cx,\n            lts: Vec::new(),\n            nested_elision_site_lts: Vec::new(),\n            unelided_trait_object_lifetime: false,\n        }\n    }\n\n    fn all_lts(&self) -> Vec<Lifetime> {\n        self.lts\n            .iter()\n            .chain(self.nested_elision_site_lts.iter())\n            .copied()\n            .collect::<Vec<_>>()\n    }\n\n    fn abort(&self) -> bool {\n        self.unelided_trait_object_lifetime\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {\n    // for lifetimes as parameters of generics\n    fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {\n        self.lts.push(*lifetime);\n    }\n\n    fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>) {\n        let trait_ref = &poly_tref.trait_ref;\n        if let Some(id) = trait_ref.trait_def_id()\n            && lang_items::FN_TRAITS\n                .iter()\n                .any(|&item| self.cx.tcx.lang_items().get(item) == Some(id))\n        {\n            let mut sub_visitor = RefVisitor::new(self.cx);\n            sub_visitor.visit_trait_ref(trait_ref);\n            self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());\n        } else {\n            walk_poly_trait_ref(self, poly_tref);\n        }\n    }\n\n    fn visit_ty(&mut self, ty: &'tcx Ty<'_, AmbigArg>) {\n        match ty.kind {\n            TyKind::FnPtr(&FnPtrTy { decl, .. }) => {\n                let mut sub_visitor = RefVisitor::new(self.cx);\n                sub_visitor.visit_fn_decl(decl);\n                self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());\n            },\n            TyKind::TraitObject(bounds, lt) => {\n                if !lt.is_elided() {\n                    self.unelided_trait_object_lifetime = true;\n                }\n                for bound in bounds {\n                    self.visit_poly_trait_ref(bound);\n                }\n            },\n            _ => walk_ty(self, ty),\n        }\n    }\n}\n\n/// Are any lifetimes mentioned in the `where` clause? If so, we don't try to\n/// reason about elision.\nfn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) -> bool {\n    for predicate in generics.predicates {\n        match *predicate.kind {\n            WherePredicateKind::RegionPredicate(..) => return true,\n            WherePredicateKind::BoundPredicate(ref pred) => {\n                // a predicate like F: Trait or F: for<'a> Trait<'a>\n                let mut visitor = RefVisitor::new(cx);\n                // walk the type F, it may not contain LT refs\n                walk_unambig_ty(&mut visitor, pred.bounded_ty);\n                if !visitor.all_lts().is_empty() {\n                    return true;\n                }\n                // if the bounds define new lifetimes, they are fine to occur\n                let allowed_lts = allowed_lts_from(pred.bound_generic_params);\n                // now walk the bounds\n                for bound in pred.bounds {\n                    walk_param_bound(&mut visitor, bound);\n                }\n                // and check that all lifetimes are allowed\n                for lt in visitor.all_lts() {\n                    if let Some(id) = named_lifetime(&lt)\n                        && !allowed_lts.contains(&id)\n                    {\n                        return true;\n                    }\n                }\n            },\n            WherePredicateKind::EqPredicate(ref pred) => {\n                let mut visitor = RefVisitor::new(cx);\n                walk_unambig_ty(&mut visitor, pred.lhs_ty);\n                walk_unambig_ty(&mut visitor, pred.rhs_ty);\n                if !visitor.lts.is_empty() {\n                    return true;\n                }\n            },\n        }\n    }\n    false\n}\n\n#[expect(clippy::struct_excessive_bools)]\nstruct Usage {\n    lifetime: Lifetime,\n    in_where_predicate: bool,\n    in_bounded_ty: bool,\n    in_generics_arg: bool,\n    lifetime_elision_impossible: bool,\n}\n\nstruct LifetimeChecker<'cx, 'tcx, F> {\n    cx: &'cx LateContext<'tcx>,\n    map: FxIndexMap<LocalDefId, Vec<Usage>>,\n    where_predicate_depth: usize,\n    bounded_ty_depth: usize,\n    generic_args_depth: usize,\n    lifetime_elision_impossible: bool,\n    phantom: std::marker::PhantomData<F>,\n}\n\nimpl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F>\nwhere\n    F: NestedFilter<'tcx>,\n{\n    fn new(cx: &'cx LateContext<'tcx>, generics: &'tcx Generics<'_>) -> LifetimeChecker<'cx, 'tcx, F> {\n        let map = generics\n            .params\n            .iter()\n            .filter_map(|par| match par.kind {\n                GenericParamKind::Lifetime {\n                    kind: LifetimeParamKind::Explicit,\n                } => Some((par.def_id, Vec::new())),\n                _ => None,\n            })\n            .collect();\n        Self {\n            cx,\n            map,\n            where_predicate_depth: 0,\n            bounded_ty_depth: 0,\n            generic_args_depth: 0,\n            lifetime_elision_impossible: false,\n            phantom: std::marker::PhantomData,\n        }\n    }\n\n    // `visit_where_bound_predicate` is based on:\n    // https://github.com/rust-lang/rust/blob/864cee3ea383cc8254ba394ba355e648faa9cfa5/compiler/rustc_hir/src/intravisit.rs#L936-L939\n    fn visit_where_bound_predicate(\n        &mut self,\n        hir_id: HirId,\n        bounded_ty: &'tcx Ty<'tcx>,\n        bounds: &'tcx [GenericBound<'tcx>],\n        bound_generic_params: &'tcx [GenericParam<'tcx>],\n    ) {\n        try_visit!(self.visit_id(hir_id));\n\n        self.bounded_ty_depth += 1;\n        try_visit!(self.visit_ty_unambig(bounded_ty));\n        self.bounded_ty_depth -= 1;\n\n        walk_list!(self, visit_param_bound, bounds);\n        walk_list!(self, visit_generic_param, bound_generic_params);\n    }\n}\n\nimpl<'tcx, F> Visitor<'tcx> for LifetimeChecker<'_, 'tcx, F>\nwhere\n    F: NestedFilter<'tcx>,\n{\n    type MaybeTyCtxt = TyCtxt<'tcx>;\n    type NestedFilter = F;\n\n    // for lifetimes as parameters of generics\n    fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {\n        if let LifetimeKind::Param(def_id) = lifetime.kind\n            && let Some(usages) = self.map.get_mut(&def_id)\n        {\n            usages.push(Usage {\n                lifetime: *lifetime,\n                in_where_predicate: self.where_predicate_depth != 0,\n                in_bounded_ty: self.bounded_ty_depth != 0,\n                in_generics_arg: self.generic_args_depth != 0,\n                lifetime_elision_impossible: self.lifetime_elision_impossible,\n            });\n        }\n    }\n\n    fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {\n        self.where_predicate_depth += 1;\n        if let &WherePredicateKind::BoundPredicate(WhereBoundPredicate {\n            bounded_ty,\n            bounds,\n            bound_generic_params,\n            origin: _,\n        }) = predicate.kind\n        {\n            self.visit_where_bound_predicate(predicate.hir_id, bounded_ty, bounds, bound_generic_params);\n        } else {\n            walk_where_predicate(self, predicate);\n        }\n        self.where_predicate_depth -= 1;\n    }\n\n    fn visit_generic_args(&mut self, generic_args: &'tcx GenericArgs<'tcx>) -> Self::Result {\n        self.generic_args_depth += 1;\n        walk_generic_args(self, generic_args);\n        self.generic_args_depth -= 1;\n    }\n\n    fn visit_fn_decl(&mut self, fd: &'tcx FnDecl<'tcx>) -> Self::Result {\n        self.lifetime_elision_impossible = !is_candidate_for_elision(fd);\n        walk_fn_decl(self, fd);\n        self.lifetime_elision_impossible = false;\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\n/// Check if `fd` supports function elision with an anonymous (or elided) lifetime,\n/// and has a lifetime somewhere in its output type.\nfn is_candidate_for_elision(fd: &FnDecl<'_>) -> bool {\n    struct V;\n\n    impl Visitor<'_> for V {\n        type Result = ControlFlow<bool>;\n\n        fn visit_lifetime(&mut self, lifetime: &Lifetime) -> Self::Result {\n            ControlFlow::Break(lifetime.is_elided() || lifetime.is_anonymous())\n        }\n    }\n\n    if fd.lifetime_elision_allowed\n        && let Return(ret_ty) = fd.output\n        && walk_unambig_ty(&mut V, ret_ty).is_break()\n    {\n        // The first encountered input lifetime will either be one on `self`, or will be the only lifetime.\n        fd.inputs\n            .iter()\n            .find_map(|ty| walk_unambig_ty(&mut V, ty).break_value())\n            .unwrap()\n    } else {\n        false\n    }\n}\n\nfn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>, generics: &'tcx Generics<'_>) {\n    let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, generics);\n\n    walk_generics(&mut checker, generics);\n    walk_fn_decl(&mut checker, func);\n\n    for (def_id, usages) in checker.map {\n        if usages\n            .iter()\n            .all(|usage| usage.in_where_predicate && !usage.in_bounded_ty && !usage.in_generics_arg)\n        {\n            span_lint(\n                cx,\n                EXTRA_UNUSED_LIFETIMES,\n                cx.tcx.def_span(def_id),\n                \"this lifetime isn't used in the function definition\",\n            );\n        }\n    }\n}\n\nfn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'_>) {\n    let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, impl_.generics);\n\n    walk_generics(&mut checker, impl_.generics);\n    if let Some(of_trait) = impl_.of_trait {\n        walk_trait_ref(&mut checker, &of_trait.trait_ref);\n    }\n    walk_unambig_ty(&mut checker, impl_.self_ty);\n    for &item in impl_.items {\n        walk_impl_item_ref(&mut checker, item);\n    }\n\n    for (&def_id, usages) in &checker.map {\n        if usages\n            .iter()\n            .all(|usage| usage.in_where_predicate && !usage.in_bounded_ty && !usage.in_generics_arg)\n        {\n            span_lint(\n                cx,\n                EXTRA_UNUSED_LIFETIMES,\n                cx.tcx.def_span(def_id),\n                \"this lifetime isn't used in the impl\",\n            );\n        }\n    }\n\n    report_elidable_impl_lifetimes(cx, impl_, &checker.map);\n}\n\n// An `impl` lifetime is elidable if it satisfies the following conditions:\n// - It is used exactly once.\n// - That single use is not in a `WherePredicate`.\nfn report_elidable_impl_lifetimes<'tcx>(\n    cx: &LateContext<'tcx>,\n    impl_: &'tcx Impl<'_>,\n    map: &FxIndexMap<LocalDefId, Vec<Usage>>,\n) {\n    let (elidable_lts, usages): (Vec<_>, Vec<_>) = map\n        .iter()\n        .filter_map(|(def_id, usages)| {\n            if let [\n                Usage {\n                    lifetime,\n                    in_where_predicate: false,\n                    lifetime_elision_impossible: false,\n                    ..\n                },\n            ] = usages.as_slice()\n            {\n                Some((def_id, lifetime))\n            } else {\n                None\n            }\n        })\n        .unzip();\n\n    if elidable_lts.is_empty() {\n        return;\n    }\n\n    report_elidable_lifetimes(cx, impl_.generics, &elidable_lts, &usages, true);\n}\n\n#[derive(Copy, Clone)]\nenum ElidableUsage {\n    /// Used in a ref (`&'a T`), can be removed\n    Ref(Span),\n    /// Used as a generic param (`T<'a>`) or an impl lifetime (`impl T + 'a`), can be replaced\n    /// with `'_`\n    Other(Span),\n}\n\n/// Generate diagnostic messages for elidable lifetimes.\nfn report_elidable_lifetimes(\n    cx: &LateContext<'_>,\n    generics: &Generics<'_>,\n    elidable_lts: &[LocalDefId],\n    usages: &[Lifetime],\n    include_suggestions: bool,\n) {\n    let lts = elidable_lts\n        .iter()\n        // In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a\n        // `Node::GenericParam`.\n        .filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident())\n        .format(\", \");\n\n    let elidable_usages: Vec<ElidableUsage> = usages\n        .iter()\n        .filter(|usage| named_lifetime(usage).is_some_and(|id| elidable_lts.contains(&id)))\n        .map(|usage| match cx.tcx.parent_hir_node(usage.hir_id) {\n            Node::Ty(Ty {\n                kind: TyKind::Ref(..), ..\n            }) => ElidableUsage::Ref(usage.ident.span),\n            _ => ElidableUsage::Other(usage.ident.span),\n        })\n        .collect();\n\n    let lint = if elidable_usages\n        .iter()\n        .any(|usage| matches!(usage, ElidableUsage::Other(_)))\n    {\n        ELIDABLE_LIFETIME_NAMES\n    } else {\n        NEEDLESS_LIFETIMES\n    };\n\n    span_lint_and_then(\n        cx,\n        lint,\n        elidable_lts\n            .iter()\n            .map(|&lt| cx.tcx.def_span(lt))\n            .chain(usages.iter().filter_map(|usage| {\n                if let LifetimeKind::Param(def_id) = usage.kind\n                    && elidable_lts.contains(&def_id)\n                {\n                    return Some(usage.ident.span);\n                }\n\n                None\n            }))\n            .collect_vec(),\n        format!(\"the following explicit lifetimes could be elided: {lts}\"),\n        |diag| {\n            if !include_suggestions {\n                return;\n            }\n\n            if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, &elidable_usages) {\n                diag.multipart_suggestion(\"elide the lifetimes\", suggestions, Applicability::MachineApplicable);\n            }\n        },\n    );\n}\n\nfn elision_suggestions(\n    cx: &LateContext<'_>,\n    generics: &Generics<'_>,\n    elidable_lts: &[LocalDefId],\n    usages: &[ElidableUsage],\n) -> Option<Vec<(Span, String)>> {\n    let explicit_params = generics\n        .params\n        .iter()\n        .filter(|param| !param.is_elided_lifetime() && !param.is_impl_trait())\n        .collect::<Vec<_>>();\n\n    let mut suggestions = if elidable_lts.len() == explicit_params.len() {\n        // if all the params are elided remove the whole generic block\n        //\n        // fn x<'a>() {}\n        //     ^^^^\n        vec![(generics.span, String::new())]\n    } else {\n        // 1. Start from the last elidable lifetime\n        // 2. While the lifetimes preceding it are also elidable, construct spans going from the current\n        //    lifetime to the comma before it\n        // 3. Once this chain of elidable lifetimes stops, switch to constructing spans going from the\n        //    current lifetime to the comma _after_ it\n        let mut end: Option<LocalDefId> = None;\n        elidable_lts\n            .iter()\n            .rev()\n            .map(|&id| {\n                let (idx, param) = explicit_params.iter().find_position(|param| param.def_id == id)?;\n\n                let span = if let Some(next) = explicit_params.get(idx + 1)\n                    && end != Some(next.def_id)\n                {\n                    // Extend the current span forward, up until the next param in the list.\n                    // fn x<'prev, 'a, 'next>() {}\n                    //             ^^^^\n                    param.span.until(next.span)\n                } else {\n                    // Extend the current span back to include the comma following the previous\n                    // param. If the span of the next param in the list has already been\n                    // extended, we continue the chain. This is why we're iterating in reverse.\n                    end = Some(param.def_id);\n\n                    // `idx` will never be 0, else we'd be removing the entire list of generics\n                    let prev = explicit_params.get(idx - 1)?;\n\n                    // fn x<'prev, 'a>() {}\n                    //           ^^^^\n                    param.span.with_lo(prev.span.hi())\n                };\n\n                Some((span, String::new()))\n            })\n            .collect::<Option<Vec<_>>>()?\n    };\n\n    suggestions.extend(usages.iter().map(|&usage| {\n        match usage {\n            ElidableUsage::Ref(span) => {\n                // expand `&'a T` to `&'a T`\n                //          ^^         ^^^\n                let span = cx.sess().source_map().span_extend_while_whitespace(span);\n\n                (span, String::new())\n            },\n            ElidableUsage::Other(span) => {\n                // `T<'a>` and `impl Foo + 'a` should be replaced by `'_`\n                (span, String::from(\"'_\"))\n            },\n        }\n    }));\n\n    Some(suggestions)\n}\n\nstruct BodyLifetimeChecker<'tcx> {\n    tcx: TyCtxt<'tcx>,\n}\n\nimpl<'tcx> BodyLifetimeChecker<'tcx> {\n    fn new(cx: &LateContext<'tcx>) -> Self {\n        Self { tcx: cx.tcx }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for BodyLifetimeChecker<'tcx> {\n    type Result = ControlFlow<()>;\n    type NestedFilter = middle_nested_filter::OnlyBodies;\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.tcx\n    }\n    // for lifetimes as parameters of generics\n    fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) -> ControlFlow<()> {\n        if !lifetime.is_anonymous() && lifetime.ident.name != kw::StaticLifetime {\n            return ControlFlow::Break(());\n        }\n        ControlFlow::Continue(())\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/literal_representation.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::numeric_literal::{NumericLiteral, Radix};\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_ast::ast::{Expr, ExprKind, LitKind};\nuse rustc_ast::token;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse std::iter;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if there is a better representation for a numeric literal.\n    ///\n    /// ### Why restrict this?\n    /// Especially for big powers of 2, a hexadecimal representation is usually more\n    /// readable than a decimal representation.\n    ///\n    /// ### Example\n    /// ```text\n    /// `255` => `0xFF`\n    /// `65_535` => `0xFFFF`\n    /// `4_042_322_160` => `0xF0F0_F0F0`\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DECIMAL_LITERAL_REPRESENTATION,\n    restriction,\n    \"using decimal representation when hexadecimal would be better\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if an integral or floating-point constant is\n    /// grouped inconsistently with underscores.\n    ///\n    /// ### Why is this bad?\n    /// Readers may incorrectly interpret inconsistently\n    /// grouped digits.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let _: u64 =\n    /// 618_64_9189_73_511\n    /// # ;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let _: u64 =\n    /// 61_864_918_973_511\n    /// # ;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INCONSISTENT_DIGIT_GROUPING,\n    style,\n    \"integer literals with digits grouped inconsistently\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if the digits of an integral or floating-point\n    /// constant are grouped into groups that\n    /// are too large.\n    ///\n    /// ### Why is this bad?\n    /// Negatively impacts readability.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: u64 = 6186491_8973511;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub LARGE_DIGIT_GROUPS,\n    pedantic,\n    \"grouping digits into groups that are too large\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns for mistyped suffix in literals\n    ///\n    /// ### Why is this bad?\n    /// This is most probably a typo\n    ///\n    /// ### Known problems\n    /// - Does not match on integers too large to fit in the corresponding unsigned type\n    /// - Does not match on `_127` since that is a valid grouping for decimal and octal numbers\n    ///\n    /// ### Example\n    /// ```ignore\n    /// `2_32` => `2_i32`\n    /// `250_8 => `250_u8`\n    /// ```\n    #[clippy::version = \"1.30.0\"]\n    pub MISTYPED_LITERAL_SUFFIXES,\n    correctness,\n    \"mistyped literal suffix\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if a long integral or floating-point constant does\n    /// not contain underscores.\n    ///\n    /// ### Why is this bad?\n    /// Reading long numbers is difficult without separators.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let _: u64 =\n    /// 61864918973511\n    /// # ;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let _: u64 =\n    /// 61_864_918_973_511\n    /// # ;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNREADABLE_LITERAL,\n    pedantic,\n    \"long literal without underscores\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if hexadecimal or binary literals are not grouped\n    /// by nibble or byte.\n    ///\n    /// ### Why is this bad?\n    /// Negatively impacts readability.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: u32 = 0xFFF_FFF;\n    /// let y: u8 = 0b01_011_101;\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub UNUSUAL_BYTE_GROUPINGS,\n    style,\n    \"binary or hex literals that aren't grouped by four\"\n}\n\nimpl_lint_pass!(DecimalLiteralRepresentation => [DECIMAL_LITERAL_REPRESENTATION]);\n\nimpl_lint_pass!(LiteralDigitGrouping => [\n    INCONSISTENT_DIGIT_GROUPING,\n    LARGE_DIGIT_GROUPS,\n    MISTYPED_LITERAL_SUFFIXES,\n    UNREADABLE_LITERAL,\n    UNUSUAL_BYTE_GROUPINGS,\n]);\n\nenum WarningType {\n    UnreadableLiteral,\n    InconsistentDigitGrouping,\n    LargeDigitGroups,\n    DecimalRepresentation,\n    MistypedLiteralSuffix,\n    UnusualByteGroupings,\n}\n\nimpl WarningType {\n    fn lint_and_text(&self) -> (&'static Lint, &'static str, &'static str) {\n        match self {\n            Self::MistypedLiteralSuffix => (\n                MISTYPED_LITERAL_SUFFIXES,\n                \"mistyped literal suffix\",\n                \"did you mean to write\",\n            ),\n            Self::UnreadableLiteral => (UNREADABLE_LITERAL, \"long literal lacking separators\", \"consider\"),\n            Self::LargeDigitGroups => (LARGE_DIGIT_GROUPS, \"digit groups should be smaller\", \"consider\"),\n            Self::InconsistentDigitGrouping => (\n                INCONSISTENT_DIGIT_GROUPING,\n                \"digits grouped inconsistently by underscores\",\n                \"consider\",\n            ),\n            Self::DecimalRepresentation => (\n                DECIMAL_LITERAL_REPRESENTATION,\n                \"integer literal has a better hexadecimal representation\",\n                \"consider\",\n            ),\n            Self::UnusualByteGroupings => (\n                UNUSUAL_BYTE_GROUPINGS,\n                \"digits of hex, binary or octal literal not in groups of equal size\",\n                \"consider\",\n            ),\n        }\n    }\n\n    fn display(&self, num_lit: &NumericLiteral<'_>, cx: &EarlyContext<'_>, span: Span) {\n        let (lint, message, try_msg) = self.lint_and_text();\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(cx, lint, span, message, |diag| {\n            diag.span_suggestion(span, try_msg, num_lit.format(), Applicability::MaybeIncorrect);\n        });\n    }\n}\n\npub struct LiteralDigitGrouping {\n    lint_fraction_readability: bool,\n}\n\nimpl EarlyLintPass for LiteralDigitGrouping {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::Lit(lit) = expr.kind\n            && !expr.span.in_external_macro(cx.sess().source_map())\n        {\n            self.check_lit(cx, lit, expr.span);\n        }\n    }\n}\n\n// Length of each UUID hyphenated group in hex digits.\nconst UUID_GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12];\n\nimpl LiteralDigitGrouping {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            lint_fraction_readability: conf.unreadable_literal_lint_fractions,\n        }\n    }\n\n    fn check_lit(&self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {\n        if let Some(src) = span.get_source_text(cx)\n            && let Ok(lit_kind) = LitKind::from_token_lit(lit)\n            && let Some(mut num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind)\n        {\n            if !Self::check_for_mistyped_suffix(cx, span, &mut num_lit) {\n                return;\n            }\n\n            if Self::is_literal_uuid_formatted(&num_lit) {\n                return;\n            }\n\n            let result = (|| {\n                let integral_group_size = Self::get_group_size(num_lit.integer.split('_'), num_lit.radix, true)?;\n                if let Some(fraction) = num_lit.fraction {\n                    let fractional_group_size =\n                        Self::get_group_size(fraction.rsplit('_'), num_lit.radix, self.lint_fraction_readability)?;\n\n                    let consistent = Self::parts_consistent(\n                        integral_group_size,\n                        fractional_group_size,\n                        num_lit.integer.len(),\n                        fraction.len(),\n                    );\n                    if !consistent {\n                        return Err(WarningType::InconsistentDigitGrouping);\n                    }\n                }\n\n                Ok(())\n            })();\n\n            if let Err(warning_type) = result {\n                let should_warn = match warning_type {\n                    WarningType::UnreadableLiteral\n                    | WarningType::InconsistentDigitGrouping\n                    | WarningType::UnusualByteGroupings\n                    | WarningType::LargeDigitGroups => !span.from_expansion(),\n                    WarningType::DecimalRepresentation | WarningType::MistypedLiteralSuffix => true,\n                };\n                if should_warn {\n                    warning_type.display(&num_lit, cx, span);\n                }\n            }\n        }\n    }\n\n    // Returns `false` if the check fails\n    fn check_for_mistyped_suffix(cx: &EarlyContext<'_>, span: Span, num_lit: &mut NumericLiteral<'_>) -> bool {\n        if num_lit.suffix.is_some() {\n            return true;\n        }\n\n        let (part, mistyped_suffixes, is_float) = if let Some((_, exponent)) = &mut num_lit.exponent {\n            (exponent, &[\"32\", \"64\"][..], true)\n        } else if num_lit.fraction.is_some() {\n            return true;\n        } else {\n            (&mut num_lit.integer, &[\"8\", \"16\", \"32\", \"64\"][..], false)\n        };\n\n        let mut split = part.rsplit('_');\n        let last_group = split.next().expect(\"At least one group\");\n        if split.next().is_some() && mistyped_suffixes.contains(&last_group) {\n            let main_part = &part[..part.len() - last_group.len()];\n            let missing_char;\n            if is_float {\n                missing_char = 'f';\n            } else {\n                let radix = match num_lit.radix {\n                    Radix::Binary => 2,\n                    Radix::Octal => 8,\n                    Radix::Decimal => 10,\n                    Radix::Hexadecimal => 16,\n                };\n                if let Ok(int) = u64::from_str_radix(&main_part.replace('_', \"\"), radix) {\n                    missing_char = match (last_group, int) {\n                        (\"8\", i) if i8::try_from(i).is_ok() => 'i',\n                        (\"16\", i) if i16::try_from(i).is_ok() => 'i',\n                        (\"32\", i) if i32::try_from(i).is_ok() => 'i',\n                        (\"64\", i) if i64::try_from(i).is_ok() => 'i',\n                        (\"8\", u) if u8::try_from(u).is_ok() => 'u',\n                        (\"16\", u) if u16::try_from(u).is_ok() => 'u',\n                        (\"32\", u) if u32::try_from(u).is_ok() => 'u',\n                        (\"64\", _) => 'u',\n                        _ => {\n                            return true;\n                        },\n                    }\n                } else {\n                    return true;\n                }\n            }\n            *part = main_part;\n            let (lint, message, try_msg) = WarningType::MistypedLiteralSuffix.lint_and_text();\n            span_lint_and_then(cx, lint, span, message, |diag| {\n                let mut sugg = num_lit.format();\n                sugg.push('_');\n                sugg.push(missing_char);\n                sugg.push_str(last_group);\n                diag.span_suggestion(span, try_msg, sugg, Applicability::MaybeIncorrect);\n            });\n            false\n        } else {\n            true\n        }\n    }\n\n    /// Checks whether the numeric literal matches the formatting of a UUID.\n    ///\n    /// Returns `true` if the radix is hexadecimal, and the groups match the\n    /// UUID format of 8-4-4-4-12.\n    fn is_literal_uuid_formatted(num_lit: &NumericLiteral<'_>) -> bool {\n        if num_lit.radix != Radix::Hexadecimal {\n            return false;\n        }\n\n        // UUIDs should not have a fraction\n        if num_lit.fraction.is_some() {\n            return false;\n        }\n\n        let group_sizes: Vec<usize> = num_lit.integer.split('_').map(str::len).collect();\n        if UUID_GROUP_LENS.len() == group_sizes.len() {\n            iter::zip(&UUID_GROUP_LENS, &group_sizes).all(|(&a, &b)| a == b)\n        } else {\n            false\n        }\n    }\n\n    /// Given the sizes of the digit groups of both integral and fractional\n    /// parts, and the length\n    /// of both parts, determine if the digits have been grouped consistently.\n    #[must_use]\n    fn parts_consistent(\n        int_group_size: Option<usize>,\n        frac_group_size: Option<usize>,\n        int_size: usize,\n        frac_size: usize,\n    ) -> bool {\n        match (int_group_size, frac_group_size) {\n            // No groups on either side of decimal point - trivially consistent.\n            (None, None) => true,\n            // Integral part has grouped digits, fractional part does not.\n            (Some(int_group_size), None) => frac_size <= int_group_size,\n            // Fractional part has grouped digits, integral part does not.\n            (None, Some(frac_group_size)) => int_size <= frac_group_size,\n            // Both parts have grouped digits. Groups should be the same size.\n            (Some(int_group_size), Some(frac_group_size)) => int_group_size == frac_group_size,\n        }\n    }\n\n    /// Returns the size of the digit groups (or None if ungrouped) if successful,\n    /// otherwise returns a `WarningType` for linting.\n    fn get_group_size<'a>(\n        groups: impl Iterator<Item = &'a str>,\n        radix: Radix,\n        lint_unreadable: bool,\n    ) -> Result<Option<usize>, WarningType> {\n        let mut groups = groups.map(str::len);\n\n        let first = groups.next().expect(\"At least one group\");\n\n        if (radix == Radix::Binary || radix == Radix::Octal || radix == Radix::Hexadecimal)\n            && let Some(second_size) = groups.next()\n            && (!groups.all(|i| i == second_size) || first > second_size)\n        {\n            return Err(WarningType::UnusualByteGroupings);\n        }\n\n        if let Some(second) = groups.next() {\n            if !groups.all(|x| x == second) || first > second {\n                Err(WarningType::InconsistentDigitGrouping)\n            } else if second > 4 {\n                Err(WarningType::LargeDigitGroups)\n            } else {\n                Ok(Some(second))\n            }\n        } else if first > 5 && lint_unreadable {\n            Err(WarningType::UnreadableLiteral)\n        } else {\n            Ok(None)\n        }\n    }\n}\n\npub struct DecimalLiteralRepresentation {\n    threshold: u64,\n}\n\nimpl EarlyLintPass for DecimalLiteralRepresentation {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::Lit(lit) = expr.kind\n            && !expr.span.in_external_macro(cx.sess().source_map())\n        {\n            self.check_lit(cx, lit, expr.span);\n        }\n    }\n}\n\nimpl DecimalLiteralRepresentation {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            threshold: conf.literal_representation_threshold,\n        }\n    }\n    fn check_lit(&self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {\n        // Lint integral literals.\n        if let Ok(lit_kind) = LitKind::from_token_lit(lit)\n            && let LitKind::Int(val, _) = lit_kind\n            && let Some(src) = span.get_source_text(cx)\n            && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind)\n            && num_lit.radix == Radix::Decimal\n            && val >= u128::from(self.threshold)\n        {\n            let hex = format!(\"{val:#X}\");\n            let num_lit = NumericLiteral::new(&hex, num_lit.suffix, false);\n            let _: Result<(), ()> = Self::do_lint(num_lit.integer).map_err(|warning_type| {\n                warning_type.display(&num_lit, cx, span);\n            });\n        }\n    }\n\n    fn do_lint(digits: &str) -> Result<(), WarningType> {\n        if digits.len() == 1 {\n            // Lint for 1 digit literals, if someone really sets the threshold that low\n            if digits == \"1\"\n                || digits == \"2\"\n                || digits == \"4\"\n                || digits == \"8\"\n                || digits == \"3\"\n                || digits == \"7\"\n                || digits == \"F\"\n            {\n                return Err(WarningType::DecimalRepresentation);\n            }\n        } else if digits.len() < 4 {\n            // Lint for Literals with a hex-representation of 2 or 3 digits\n            let f = &digits[0..1]; // first digit\n            let s = &digits[1..]; // suffix\n\n            // Powers of 2\n            if ((f.eq(\"1\") || f.eq(\"2\") || f.eq(\"4\") || f.eq(\"8\")) && s.chars().all(|c| c == '0'))\n                // Powers of 2 minus 1\n                || ((f.eq(\"1\") || f.eq(\"3\") || f.eq(\"7\") || f.eq(\"F\")) && s.chars().all(|c| c == 'F'))\n            {\n                return Err(WarningType::DecimalRepresentation);\n            }\n        } else {\n            // Lint for Literals with a hex-representation of 4 digits or more\n            let f = &digits[0..1]; // first digit\n            let m = &digits[1..digits.len() - 1]; // middle digits, except last\n            let s = &digits[1..]; // suffix\n\n            // Powers of 2 with a margin of +15/-16\n            if ((f.eq(\"1\") || f.eq(\"2\") || f.eq(\"4\") || f.eq(\"8\")) && m.chars().all(|c| c == '0'))\n                || ((f.eq(\"1\") || f.eq(\"3\") || f.eq(\"7\") || f.eq(\"F\")) && m.chars().all(|c| c == 'F'))\n                // Lint for representations with only 0s and Fs, while allowing 7 as the first\n                // digit\n                || ((f.eq(\"7\") || f.eq(\"F\")) && s.chars().all(|c| c == '0' || c == 'F'))\n            {\n                return Err(WarningType::DecimalRepresentation);\n            }\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/literal_string_with_formatting_args.rs",
    "content": "use rustc_ast::{LitKind, StrStyle};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lexer::is_ident;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_parse_format::{ParseMode, Parser, Piece};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{BytePos, Span};\n\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::mir::enclosing_mir;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if string literals have formatting arguments outside of macros\n    /// using them (like `format!`).\n    ///\n    /// ### Why is this bad?\n    /// It will likely not generate the expected content.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: Option<usize> = None;\n    /// let y = \"hello\";\n    /// x.expect(\"{y:?}\");\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x: Option<usize> = None;\n    /// let y = \"hello\";\n    /// x.expect(&format!(\"{y:?}\"));\n    /// ```\n    #[clippy::version = \"1.85.0\"]\n    pub LITERAL_STRING_WITH_FORMATTING_ARGS,\n    nursery,\n    \"Checks if string literals have formatting arguments\"\n}\n\ndeclare_lint_pass!(LiteralStringWithFormattingArg => [\n    LITERAL_STRING_WITH_FORMATTING_ARGS,\n]);\n\nfn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, spans: &[(Span, Option<String>)]) {\n    if !spans.is_empty()\n        && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id)\n    {\n        let spans = spans\n            .iter()\n            .filter_map(|(span, name)| {\n                if let Some(name) = name\n                    // We need to check that the name is a local.\n                    && !mir\n                        .var_debug_info\n                        .iter()\n                        .any(|local| !local.source_info.span.from_expansion() && local.name.as_str() == name)\n                {\n                    return None;\n                }\n                Some(*span)\n            })\n            .collect::<Vec<_>>();\n        match spans.len() {\n            0 => {},\n            1 => {\n                span_lint(\n                    cx,\n                    LITERAL_STRING_WITH_FORMATTING_ARGS,\n                    spans,\n                    \"this looks like a formatting argument but it is not part of a formatting macro\",\n                );\n            },\n            _ => {\n                span_lint(\n                    cx,\n                    LITERAL_STRING_WITH_FORMATTING_ARGS,\n                    spans,\n                    \"these look like formatting arguments but are not part of a formatting macro\",\n                );\n            },\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for LiteralStringWithFormattingArg {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if expr.span.from_expansion() || expr.span.is_dummy() {\n            return;\n        }\n        if let ExprKind::Lit(lit) = expr.kind {\n            let (add, symbol) = match lit.node {\n                LitKind::Str(symbol, style) => {\n                    let add = match style {\n                        StrStyle::Cooked => 1,\n                        StrStyle::Raw(nb) => nb as usize + 2,\n                    };\n                    (add, symbol)\n                },\n                _ => return,\n            };\n            if is_from_proc_macro(cx, expr) {\n                return;\n            }\n            let fmt_str = symbol.as_str();\n            let lo = expr.span.lo();\n            let mut current = fmt_str;\n            let mut diff_len = 0;\n\n            let mut parser = Parser::new(current, None, None, false, ParseMode::Format);\n            let mut spans = Vec::new();\n            while let Some(piece) = parser.next() {\n                if let Some(error) = parser.errors.last() {\n                    // We simply ignore the errors and move after them.\n                    if error.span.end >= current.len() {\n                        break;\n                    }\n                    // We find the closest char to where the error location ends.\n                    let pos = current.floor_char_boundary(error.span.end);\n                    // We get the next character.\n                    current = if let Some((next_char_pos, _)) = current[pos..].char_indices().nth(1) {\n                        // We make the parser start from this new location.\n                        &current[pos + next_char_pos..]\n                    } else {\n                        break;\n                    };\n                    diff_len = fmt_str.len() - current.len();\n                    parser = Parser::new(current, None, None, false, ParseMode::Format);\n                } else if let Piece::NextArgument(arg) = piece {\n                    let mut pos = arg.position_span;\n                    pos.start += diff_len;\n                    pos.end += diff_len;\n\n                    let mut start = pos.start;\n                    while start < fmt_str.len() && !fmt_str.is_char_boundary(start) {\n                        start += 1;\n                    }\n                    let start = fmt_str[..start].rfind('{').unwrap_or(start);\n                    // If this is a unicode character escape, we don't want to lint.\n                    if start > 1 && fmt_str[..start].ends_with(\"\\\\u\") {\n                        continue;\n                    }\n\n                    if fmt_str[start + 1..].trim_start().starts_with('}') {\n                        // We ignore `{}`.\n                        continue;\n                    }\n\n                    let end = fmt_str[start + 1..]\n                        .find('}')\n                        .map_or(pos.end, |found| start + 1 + found)\n                        + 1;\n                    let ident_start = start + 1;\n                    let colon_pos = fmt_str[ident_start..end].find(':');\n                    let ident_end = colon_pos.unwrap_or(end - 1);\n                    let mut name = None;\n                    if ident_start < ident_end\n                        && let arg = &fmt_str[ident_start..ident_end]\n                        && !arg.is_empty()\n                        && is_ident(arg)\n                    {\n                        name = Some(arg.to_string());\n                    } else if colon_pos.is_none() {\n                        // Not a `{:?}`.\n                        continue;\n                    }\n                    spans.push((\n                        expr.span\n                            .with_hi(lo + BytePos((start + add).try_into().unwrap()))\n                            .with_lo(lo + BytePos((end + add).try_into().unwrap())),\n                        name,\n                    ));\n                }\n            }\n            emit_lint(cx, expr, &spans);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/char_indices_as_byte_indices.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{eq_expr_value, higher, sym};\nuse rustc_errors::{Applicability, MultiSpan};\nuse rustc_hir::{Expr, ExprKind, LangItem, Node, Pat, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::{Span, Symbol};\n\nuse super::CHAR_INDICES_AS_BYTE_INDICES;\n\n// The list of `str` methods we want to lint that have a `usize` argument representing a byte index.\n// Note: `String` also has methods that work with byte indices,\n// but they all take `&mut self` and aren't worth considering since the user couldn't have called\n// them while the chars iterator is live anyway.\nconst BYTE_INDEX_METHODS: &[Symbol] = &[\n    sym::ceil_char_boundary,\n    sym::floor_char_boundary,\n    sym::get,\n    sym::get_mut,\n    sym::get_unchecked,\n    sym::get_unchecked_mut,\n    sym::index,\n    sym::index_mut,\n    sym::is_char_boundary,\n    sym::slice_mut_unchecked,\n    sym::slice_unchecked,\n    sym::split_at,\n    sym::split_at_checked,\n    sym::split_at_mut,\n    sym::split_at_mut_checked,\n];\n\nconst CONTINUE: ControlFlow<!, ()> = ControlFlow::Continue(());\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>, iterable: &Expr<'_>, body: &'tcx Expr<'tcx>) {\n    if let ExprKind::MethodCall(_, enumerate_recv, _, enumerate_span) = iterable.kind\n        && let Some(method_id) = cx.typeck_results().type_dependent_def_id(iterable.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::enumerate_method, method_id)\n        && let ExprKind::MethodCall(_, chars_recv, _, chars_span) = enumerate_recv.kind\n        && let Some(method_id) = cx.typeck_results().type_dependent_def_id(enumerate_recv.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::str_chars, method_id)\n    {\n        if let PatKind::Tuple([pat, _], _) = pat.kind\n            && let PatKind::Binding(_, binding_id, ..) = pat.kind\n        {\n            // Destructured iterator element `(idx, _)`, look for uses of the binding\n            for_each_expr(cx, body, |expr| {\n                if expr.res_local_id() == Some(binding_id) {\n                    check_index_usage(cx, expr, pat, enumerate_span, chars_span, chars_recv);\n                }\n                CONTINUE\n            });\n        } else if let PatKind::Binding(_, binding_id, ..) = pat.kind {\n            // Bound as a tuple, look for `tup.0`\n            for_each_expr(cx, body, |expr| {\n                if let ExprKind::Field(e, field) = expr.kind\n                    && e.res_local_id() == Some(binding_id)\n                    && field.name == sym::integer(0)\n                {\n                    check_index_usage(cx, expr, pat, enumerate_span, chars_span, chars_recv);\n                }\n                CONTINUE\n            });\n        }\n    }\n}\n\nfn check_index_usage<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    pat: &Pat<'_>,\n    enumerate_span: Span,\n    chars_span: Span,\n    chars_recv: &Expr<'_>,\n) {\n    let Some(parent_expr) = index_consumed_at(cx, expr) else {\n        return;\n    };\n\n    let is_string_like = |ty: Ty<'_>| ty.is_str() || ty.is_lang_item(cx, LangItem::String);\n    let message = match parent_expr.kind {\n        ExprKind::MethodCall(segment, recv, ..)\n            // We currently only lint `str` methods (which `String` can deref to), so a `.is_str()` check is sufficient here\n            // (contrary to the `ExprKind::Index` case which needs to handle both with `is_string_like` because `String` implements\n            // `Index` directly and no deref to `str` would happen in that case).\n            if cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_str()\n                && BYTE_INDEX_METHODS.contains(&segment.ident.name)\n                && eq_expr_value(cx, chars_recv, recv) =>\n        {\n            \"passing a character position to a method that expects a byte index\"\n        },\n        ExprKind::Index(target, ..)\n            if is_string_like(cx.typeck_results().expr_ty_adjusted(target).peel_refs())\n                && eq_expr_value(cx, chars_recv, target) =>\n        {\n            \"indexing into a string with a character position where a byte index is expected\"\n        },\n        _ => return,\n    };\n\n    span_lint_hir_and_then(\n        cx,\n        CHAR_INDICES_AS_BYTE_INDICES,\n        expr.hir_id,\n        expr.span,\n        message,\n        |diag| {\n            diag.note(\"a character can take up more than one byte, so they are not interchangeable\")\n                .span_note(\n                    MultiSpan::from_spans(vec![pat.span, enumerate_span]),\n                    \"position comes from the enumerate iterator\",\n                )\n                .span_suggestion_verbose(\n                    chars_span.to(enumerate_span),\n                    \"consider using `.char_indices()` instead\",\n                    \"char_indices()\",\n                    Applicability::MaybeIncorrect,\n                );\n        },\n    );\n}\n\n/// Returns the expression which ultimately consumes the index.\n/// This is usually the parent expression, i.e. `.split_at(idx)` for `idx`,\n/// but for `.get(..idx)` we want to consider the method call the consuming expression,\n/// which requires skipping past the range expression.\nfn index_consumed_at<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    for (_, node) in cx.tcx.hir_parent_iter(expr.hir_id) {\n        match node {\n            Node::Expr(expr) if higher::Range::hir(cx, expr).is_some() => {},\n            Node::ExprField(_) => {},\n            Node::Expr(expr) => return Some(expr),\n            _ => break,\n        }\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/empty_loop.rs",
    "content": "use super::EMPTY_LOOP;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::{is_in_panic_handler, is_no_std_crate};\n\nuse rustc_hir::{Block, Expr, ItemKind, Node, find_attr};\nuse rustc_lint::LateContext;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, loop_block: &Block<'_>) {\n    let parent_hir_id = cx.tcx.parent_hir_id(expr.hir_id);\n    if let Node::Item(parent_node) = cx.tcx.hir_node(parent_hir_id)\n        && matches!(parent_node.kind, ItemKind::Fn { .. })\n        && let attrs = cx.tcx.hir_attrs(parent_hir_id)\n        && find_attr!(attrs, RustcIntrinsic)\n    {\n        // Intrinsic functions are expanded into an empty loop when lowering the AST\n        // to simplify the job of later passes which might expect any function to have a body.\n        return;\n    }\n\n    if loop_block.stmts.is_empty() && loop_block.expr.is_none() && !is_in_panic_handler(cx, expr) {\n        let msg = \"empty `loop {}` wastes CPU cycles\";\n        let help = if is_no_std_crate(cx) {\n            \"you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body\"\n        } else {\n            \"you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body\"\n        };\n        span_lint_and_help(cx, EMPTY_LOOP, expr.span, msg, None, help);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/explicit_counter_loop.rs",
    "content": "use std::borrow::Cow;\n\nuse super::{EXPLICIT_COUNTER_LOOP, IncrementVisitor, InitializeVisitor, make_iterator_snippet};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg::{EMPTY, Sugg};\nuse clippy_utils::{get_enclosing_block, is_integer_const, is_integer_literal_untyped};\nuse rustc_ast::{Label, RangeLimits};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{walk_block, walk_expr};\nuse rustc_hir::{Expr, Pat};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty, UintTy};\n\n// To trigger the EXPLICIT_COUNTER_LOOP lint, a variable must be incremented exactly once in the\n// loop body.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    arg: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    expr: &'tcx Expr<'_>,\n    label: Option<Label>,\n) {\n    // Look for variables that are incremented once per loop iteration.\n    let mut increment_visitor = IncrementVisitor::new(cx);\n    walk_expr(&mut increment_visitor, body);\n\n    // For each candidate, check the parent block to see if\n    // it's initialized to zero at the start of the loop.\n    let Some(block) = get_enclosing_block(cx, expr.hir_id) else {\n        return;\n    };\n\n    for id in increment_visitor.into_results() {\n        let mut initialize_visitor = InitializeVisitor::new(cx, expr, id);\n        walk_block(&mut initialize_visitor, block);\n\n        let Some((name, ty, initializer)) = initialize_visitor.get_result() else {\n            continue;\n        };\n        if !cx.typeck_results().expr_ty(initializer).is_integral() {\n            continue;\n        }\n\n        let is_zero = is_integer_const(cx, initializer, 0);\n        let mut applicability = Applicability::MaybeIncorrect;\n        let span = expr.span.with_hi(arg.span.hi());\n        let loop_label = label.map_or(String::new(), |l| format!(\"{}: \", l.ident.name));\n\n        span_lint_and_then(\n            cx,\n            EXPLICIT_COUNTER_LOOP,\n            span,\n            format!(\"the variable `{name}` is used as a loop counter\"),\n            |diag| {\n                let pat_snippet = snippet_with_applicability(cx, pat.span, \"item\", &mut applicability);\n                let iter_snippet = make_iterator_snippet(cx, arg, &mut applicability);\n                let int_name = match ty.map(Ty::kind) {\n                    Some(ty::Uint(UintTy::Usize)) | None => {\n                        if is_zero {\n                            diag.span_suggestion(\n                                span,\n                                \"consider using\",\n                                format!(\"{loop_label}for ({name}, {pat_snippet}) in {iter_snippet}.enumerate()\"),\n                                applicability,\n                            );\n                            return;\n                        }\n                        None\n                    },\n                    Some(ty::Int(int_ty)) => Some(int_ty.name_str()),\n                    Some(ty::Uint(uint_ty)) => Some(uint_ty.name_str()),\n                    _ => None,\n                }\n                .filter(|_| is_integer_literal_untyped(initializer));\n\n                let initializer = Sugg::hir_from_snippet(cx, initializer, |span| {\n                    let snippet = snippet_with_applicability(cx, span, \"..\", &mut applicability);\n                    if let Some(int_name) = int_name {\n                        return Cow::Owned(format!(\"{snippet}_{int_name}\"));\n                    }\n                    snippet\n                });\n\n                diag.span_suggestion(\n                    span,\n                    \"consider using\",\n                    format!(\n                        \"{loop_label}for ({name}, {pat_snippet}) in ({}).zip({iter_snippet})\",\n                        initializer.range(&EMPTY, RangeLimits::HalfOpen)\n                    ),\n                    applicability,\n                );\n\n                if is_zero && let Some(int_name) = int_name {\n                    diag.note(format!(\n                        \"`{name}` is of type `{int_name}`, making it ineligible for `Iterator::enumerate`\"\n                    ));\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/explicit_into_iter_loop.rs",
    "content": "use super::EXPLICIT_INTO_ITER_LOOP;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet_with_context;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};\nuse rustc_span::symbol::sym;\n\n#[derive(Clone, Copy)]\nenum AdjustKind {\n    None,\n    Borrow,\n    BorrowMut,\n    Reborrow,\n    ReborrowMut,\n}\nimpl AdjustKind {\n    fn borrow(mutbl: AutoBorrowMutability) -> Self {\n        match mutbl {\n            AutoBorrowMutability::Not => Self::Borrow,\n            AutoBorrowMutability::Mut { .. } => Self::BorrowMut,\n        }\n    }\n\n    fn reborrow(mutbl: AutoBorrowMutability) -> Self {\n        match mutbl {\n            AutoBorrowMutability::Not => Self::Reborrow,\n            AutoBorrowMutability::Mut { .. } => Self::ReborrowMut,\n        }\n    }\n\n    fn display(self) -> &'static str {\n        match self {\n            Self::None => \"\",\n            Self::Borrow => \"&\",\n            Self::BorrowMut => \"&mut \",\n            Self::Reborrow => \"&*\",\n            Self::ReborrowMut => \"&mut *\",\n        }\n    }\n}\n\npub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<'_>) {\n    if !cx\n        .ty_based_def(call_expr)\n        .opt_parent(cx)\n        .is_diag_item(cx, sym::IntoIterator)\n    {\n        return;\n    }\n\n    let typeck = cx.typeck_results();\n    let self_ty = typeck.expr_ty(self_arg);\n    let adjust = match typeck.expr_adjustments(self_arg) {\n        [] => AdjustKind::None,\n        &[\n            Adjustment {\n                kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),\n                ..\n            },\n        ] => AdjustKind::borrow(mutbl),\n        &[\n            Adjustment {\n                kind: Adjust::Deref(_), ..\n            },\n            Adjustment {\n                kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),\n                target,\n            },\n        ] => {\n            if self_ty == target && matches!(mutbl, AutoBorrowMutability::Not) {\n                AdjustKind::None\n            } else {\n                AdjustKind::reborrow(mutbl)\n            }\n        },\n        _ => return,\n    };\n\n    let mut applicability = Applicability::MachineApplicable;\n    let object = snippet_with_context(cx, self_arg.span, call_expr.span.ctxt(), \"_\", &mut applicability).0;\n    span_lint_and_sugg(\n        cx,\n        EXPLICIT_INTO_ITER_LOOP,\n        call_expr.span,\n        \"it is more concise to loop over containers instead of using explicit \\\n            iteration methods\",\n        \"to write this more concisely, try\",\n        format!(\"{}{object}\", adjust.display()),\n        applicability,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/explicit_iter_loop.rs",
    "content": "use super::EXPLICIT_ITER_LOOP;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::sym;\nuse clippy_utils::ty::{\n    implements_trait, implements_trait_with_env, is_copy, make_normalized_projection,\n    make_normalized_projection_with_regions, normalize_with_regions,\n};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, Mutability};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};\nuse rustc_middle::ty::{self, EarlyBinder, Ty};\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    self_arg: &Expr<'_>,\n    call_expr: &Expr<'_>,\n    msrv: Msrv,\n    enforce_iter_loop_reborrow: bool,\n) {\n    let Some((adjust, ty)) = is_ref_iterable(cx, self_arg, call_expr, enforce_iter_loop_reborrow, msrv) else {\n        return;\n    };\n\n    if let ty::Array(_, count) = *ty.peel_refs().kind() {\n        if !ty.is_ref() {\n            if !msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) {\n                return;\n            }\n        } else if count.try_to_target_usize(cx.tcx).is_none_or(|x| x > 32) && !msrv.meets(cx, msrvs::ARRAY_IMPL_ANY_LEN)\n        {\n            return;\n        }\n    }\n\n    let mut applicability = Applicability::MachineApplicable;\n    let object = snippet_with_context(cx, self_arg.span, call_expr.span.ctxt(), \"_\", &mut applicability).0;\n    span_lint_and_sugg(\n        cx,\n        EXPLICIT_ITER_LOOP,\n        call_expr.span,\n        \"it is more concise to loop over references to containers instead of using explicit \\\n         iteration methods\",\n        \"to write this more concisely, try\",\n        format!(\"{}{object}\", adjust.display()),\n        applicability,\n    );\n}\n\n#[derive(Clone, Copy)]\nenum AdjustKind {\n    None,\n    Borrow,\n    BorrowMut,\n    Deref,\n    Reborrow,\n    ReborrowMut,\n}\nimpl AdjustKind {\n    fn borrow(mutbl: Mutability) -> Self {\n        match mutbl {\n            Mutability::Not => Self::Borrow,\n            Mutability::Mut => Self::BorrowMut,\n        }\n    }\n\n    fn auto_borrow(mutbl: AutoBorrowMutability) -> Self {\n        match mutbl {\n            AutoBorrowMutability::Not => Self::Borrow,\n            AutoBorrowMutability::Mut { .. } => Self::BorrowMut,\n        }\n    }\n\n    fn reborrow(mutbl: Mutability) -> Self {\n        match mutbl {\n            Mutability::Not => Self::Reborrow,\n            Mutability::Mut => Self::ReborrowMut,\n        }\n    }\n\n    fn auto_reborrow(mutbl: AutoBorrowMutability) -> Self {\n        match mutbl {\n            AutoBorrowMutability::Not => Self::Reborrow,\n            AutoBorrowMutability::Mut { .. } => Self::ReborrowMut,\n        }\n    }\n\n    fn display(self) -> &'static str {\n        match self {\n            Self::None => \"\",\n            Self::Borrow => \"&\",\n            Self::BorrowMut => \"&mut \",\n            Self::Deref => \"*\",\n            Self::Reborrow => \"&*\",\n            Self::ReborrowMut => \"&mut *\",\n        }\n    }\n}\n\n/// Checks if an `iter` or `iter_mut` call returns `IntoIterator::IntoIter`. Returns how the\n/// argument needs to be adjusted.\n#[expect(clippy::too_many_lines)]\nfn is_ref_iterable<'tcx>(\n    cx: &LateContext<'tcx>,\n    self_arg: &Expr<'_>,\n    call_expr: &Expr<'_>,\n    enforce_iter_loop_reborrow: bool,\n    msrv: Msrv,\n) -> Option<(AdjustKind, Ty<'tcx>)> {\n    let typeck = cx.typeck_results();\n    if let Some(trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator)\n        && let Some(fn_id) = typeck.type_dependent_def_id(call_expr.hir_id)\n        && let sig = cx\n            .tcx\n            .liberate_late_bound_regions(fn_id, cx.tcx.fn_sig(fn_id).skip_binder())\n        && let &[req_self_ty, req_res_ty] = &**sig.inputs_and_output\n        && let typing_env = ty::TypingEnv::non_body_analysis(cx.tcx, fn_id)\n        && implements_trait_with_env(cx.tcx, typing_env, req_self_ty, trait_id, Some(fn_id), &[])\n        && let Some(into_iter_ty) =\n            make_normalized_projection_with_regions(cx.tcx, typing_env, trait_id, sym::IntoIter, [req_self_ty])\n        && let req_res_ty = normalize_with_regions(cx.tcx, typing_env, req_res_ty)\n        && into_iter_ty == req_res_ty\n    {\n        let adjustments = typeck.expr_adjustments(self_arg);\n        let self_ty = typeck.expr_ty(self_arg);\n        let self_is_copy = is_copy(cx, self_ty);\n\n        if self_ty.peel_refs().is_lang_item(cx, rustc_hir::LangItem::OwnedBox) && !msrv.meets(cx, msrvs::BOX_INTO_ITER)\n        {\n            return None;\n        }\n\n        if adjustments.is_empty() && self_is_copy {\n            // Exact type match, already checked earlier\n            return Some((AdjustKind::None, self_ty));\n        }\n\n        let res_ty = cx.tcx.erase_and_anonymize_regions(\n            EarlyBinder::bind(req_res_ty).instantiate(cx.tcx, typeck.node_args(call_expr.hir_id)),\n        );\n        let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() {\n            Some(mutbl)\n        } else {\n            None\n        };\n\n        if !adjustments.is_empty() {\n            if self_is_copy {\n                // Using by value won't consume anything\n                if implements_trait(cx, self_ty, trait_id, &[])\n                    && let Some(ty) =\n                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [self_ty])\n                    && ty == res_ty\n                {\n                    return Some((AdjustKind::None, self_ty));\n                }\n            } else if enforce_iter_loop_reborrow\n                && let ty::Ref(region, ty, Mutability::Mut) = *self_ty.kind()\n                && let Some(mutbl) = mutbl\n            {\n                // Attempt to reborrow the mutable reference\n                let self_ty = if mutbl.is_mut() {\n                    self_ty\n                } else {\n                    Ty::new_ref(cx.tcx, region, ty, mutbl)\n                };\n                if implements_trait(cx, self_ty, trait_id, &[])\n                    && let Some(ty) =\n                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [self_ty])\n                    && ty == res_ty\n                {\n                    return Some((AdjustKind::reborrow(mutbl), self_ty));\n                }\n            }\n        }\n        if let Some(mutbl) = mutbl\n            && !self_ty.is_ref()\n        {\n            // Attempt to borrow\n            let self_ty = Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, self_ty, mutbl);\n            if implements_trait(cx, self_ty, trait_id, &[])\n                && let Some(ty) =\n                    make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [self_ty])\n                && ty == res_ty\n            {\n                return Some((AdjustKind::borrow(mutbl), self_ty));\n            }\n        }\n\n        match adjustments {\n            [] => Some((AdjustKind::None, self_ty)),\n            &[\n                Adjustment {\n                    kind: Adjust::Deref(_), ..\n                },\n                Adjustment {\n                    kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),\n                    target,\n                },\n                ..,\n            ] => {\n                if enforce_iter_loop_reborrow\n                    && target != self_ty\n                    && implements_trait(cx, target, trait_id, &[])\n                    && let Some(ty) =\n                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [target])\n                    && ty == res_ty\n                {\n                    Some((AdjustKind::auto_reborrow(mutbl), target))\n                } else {\n                    None\n                }\n            },\n            &[\n                Adjustment {\n                    kind: Adjust::Deref(_),\n                    target,\n                },\n                ..,\n            ] => {\n                if is_copy(cx, target)\n                    && implements_trait(cx, target, trait_id, &[])\n                    && let Some(ty) =\n                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [target])\n                    && ty == res_ty\n                {\n                    Some((AdjustKind::Deref, target))\n                } else {\n                    None\n                }\n            },\n            &[\n                Adjustment {\n                    kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),\n                    target,\n                },\n                ..,\n            ] => {\n                if self_ty.is_ref()\n                    && implements_trait(cx, target, trait_id, &[])\n                    && let Some(ty) =\n                        make_normalized_projection(cx.tcx, cx.typing_env(), trait_id, sym::IntoIter, [target])\n                    && ty == res_ty\n                {\n                    Some((AdjustKind::auto_borrow(mutbl), target))\n                } else {\n                    None\n                }\n            },\n            _ => None,\n        }\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/for_kv_map.rs",
    "content": "use super::FOR_KV_MAP;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{snippet_with_applicability, walk_span_to_context};\nuse clippy_utils::{pat_is_wild, sugg};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, sym};\n\n/// Checks for the `FOR_KV_MAP` lint.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    arg: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    span: Span,\n) {\n    let pat_span = pat.span;\n\n    if let PatKind::Tuple(pat, _) = pat.kind\n        && pat.len() == 2\n    {\n        let arg_span = arg.span;\n        let (new_pat_span, kind, ty, mutbl) = match *cx.typeck_results().expr_ty(arg).kind() {\n            ty::Ref(_, ty, mutbl) => match (&pat[0].kind, &pat[1].kind) {\n                (key, _) if pat_is_wild(cx, key, body) => (pat[1].span, \"value\", ty, mutbl),\n                (_, value) if pat_is_wild(cx, value, body) => (pat[0].span, \"key\", ty, Mutability::Not),\n                _ => return,\n            },\n            _ => return,\n        };\n        let mutbl = match mutbl {\n            Mutability::Not => \"\",\n            Mutability::Mut => \"_mut\",\n        };\n        let arg = match arg.kind {\n            ExprKind::AddrOf(BorrowKind::Ref, _, expr) => expr,\n            _ => arg,\n        };\n\n        if matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap))\n            && let Some(arg_span) = walk_span_to_context(arg_span, span.ctxt())\n        {\n            span_lint_and_then(\n                cx,\n                FOR_KV_MAP,\n                arg_span,\n                format!(\"you seem to want to iterate on a map's {kind}s\"),\n                |diag| {\n                    let mut applicability = Applicability::MachineApplicable;\n                    let map = sugg::Sugg::hir_with_context(cx, arg, span.ctxt(), \"map\", &mut applicability);\n                    let pat = snippet_with_applicability(cx, new_pat_span, kind, &mut applicability);\n                    diag.multipart_suggestion(\n                        \"use the corresponding method\",\n                        vec![\n                            (pat_span, pat.to_string()),\n                            (arg_span, format!(\"{}.{kind}s{mutbl}()\", map.maybe_paren())),\n                        ],\n                        applicability,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/infinite_loop.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::{RequiresSemi, fn_def_id, is_from_proc_macro, is_lint_allowed, is_never_expr};\nuse hir::intravisit::{Visitor, walk_expr};\nuse rustc_ast::Label;\nuse rustc_errors::Applicability;\nuse rustc_hir::{\n    self as hir, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnRetTy,\n    FnSig, Node, TyKind,\n};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_span::sym;\n\nuse super::INFINITE_LOOP;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'tcx>,\n    loop_block: &'tcx hir::Block<'_>,\n    label: Option<Label>,\n) {\n    if is_lint_allowed(cx, INFINITE_LOOP, expr.hir_id) {\n        return;\n    }\n\n    // Skip check if this loop is not in a function/method/closure. (In some weird case)\n    let Some(parent_fn_ret) = get_parent_fn_ret_ty(cx, expr) else {\n        return;\n    };\n    // Or, its parent function is already returning `Never`\n    if is_never_return(parent_fn_ret) {\n        return;\n    }\n\n    if is_inside_unawaited_async_block(cx, expr) {\n        return;\n    }\n\n    if expr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, expr) {\n        return;\n    }\n\n    let mut loop_visitor = LoopVisitor {\n        cx,\n        label,\n        inner_labels: label.into_iter().collect(),\n        loop_depth: 0,\n        is_finite: false,\n    };\n    loop_visitor.visit_block(loop_block);\n\n    let is_finite_loop = loop_visitor.is_finite;\n\n    if !is_finite_loop {\n        span_lint_and_then(cx, INFINITE_LOOP, expr.span, \"infinite loop detected\", |diag| {\n            if let FnRetTy::DefaultReturn(ret_span) = parent_fn_ret\n                && cx\n                    .enclosing_body\n                    .is_some_and(|id| matches!(is_never_expr(cx, cx.tcx.hir_body(id).value), Some(RequiresSemi::No)))\n            {\n                diag.span_suggestion(\n                    ret_span,\n                    \"if this is intentional, consider specifying `!` as function return\",\n                    \" -> !\",\n                    Applicability::MaybeIncorrect,\n                );\n            }\n\n            diag.help(\"if this is not intended, try adding a `break` or `return` to the loop\");\n        });\n    }\n}\n\n/// Check if the given expression is inside an async block that is not being awaited.\n/// This helps avoid false positives when async blocks are spawned or assigned to variables.\nfn is_inside_unawaited_async_block(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let current_hir_id = expr.hir_id;\n    for (_, parent_node) in cx.tcx.hir_parent_iter(current_hir_id) {\n        if let Node::Expr(Expr {\n            kind:\n                ExprKind::Closure(Closure {\n                    kind:\n                        ClosureKind::Coroutine(CoroutineKind::Desugared(\n                            CoroutineDesugaring::Async,\n                            CoroutineSource::Block | CoroutineSource::Closure,\n                        )),\n                    ..\n                }),\n            ..\n        }) = parent_node\n        {\n            return !is_async_block_awaited(cx, expr);\n        }\n    }\n    false\n}\n\nfn is_async_block_awaited(cx: &LateContext<'_>, async_expr: &Expr<'_>) -> bool {\n    for (_, parent_node) in cx.tcx.hir_parent_iter(async_expr.hir_id) {\n        if let Node::Expr(Expr {\n            kind: ExprKind::Match(_, _, hir::MatchSource::AwaitDesugar),\n            ..\n        }) = parent_node\n        {\n            return true;\n        }\n    }\n    false\n}\n\nfn get_parent_fn_ret_ty<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<FnRetTy<'tcx>> {\n    for (_, parent_node) in cx.tcx.hir_parent_iter(expr.hir_id) {\n        match parent_node {\n            // Skip `Coroutine` closures, these are the body of `async fn`, not async closures.\n            // This is because we still need to backtrack one parent node to get the `OpaqueDef` ty.\n            Node::Expr(Expr {\n                kind:\n                    ExprKind::Closure(Closure {\n                        kind: ClosureKind::Coroutine(_),\n                        ..\n                    }),\n                ..\n            }) => (),\n            Node::Item(hir::Item {\n                kind:\n                    hir::ItemKind::Fn {\n                        sig: FnSig { decl, .. },\n                        ..\n                    },\n                ..\n            })\n            | Node::TraitItem(hir::TraitItem {\n                kind: hir::TraitItemKind::Fn(FnSig { decl, .. }, _),\n                ..\n            })\n            | Node::ImplItem(hir::ImplItem {\n                kind: hir::ImplItemKind::Fn(FnSig { decl, .. }, _),\n                ..\n            })\n            | Node::Expr(Expr {\n                kind: ExprKind::Closure(Closure { fn_decl: decl, .. }),\n                ..\n            }) => return Some(decl.output),\n            _ => (),\n        }\n    }\n    None\n}\n\nstruct LoopVisitor<'hir, 'tcx> {\n    cx: &'hir LateContext<'tcx>,\n    label: Option<Label>,\n    inner_labels: Vec<Label>,\n    loop_depth: usize,\n    is_finite: bool,\n}\n\nimpl<'hir> Visitor<'hir> for LoopVisitor<'hir, '_> {\n    fn visit_expr(&mut self, ex: &'hir Expr<'_>) {\n        match &ex.kind {\n            ExprKind::Break(hir::Destination { label, .. }, ..) => {\n                // Assuming breaks the loop when `loop_depth` is 0,\n                // as it could only means this `break` breaks current loop or any of its upper loop.\n                // Or, the depth is not zero but the label is matched.\n                if self.loop_depth == 0 || (label.is_some() && *label == self.label) {\n                    self.is_finite = true;\n                }\n            },\n            ExprKind::Continue(hir::Destination { label, .. }) => {\n                // Check whether we are leaving this loop by continuing into an outer loop\n                // whose label we did not encounter.\n                if label.is_some_and(|label| !self.inner_labels.contains(&label)) {\n                    self.is_finite = true;\n                }\n            },\n            ExprKind::Ret(..) => self.is_finite = true,\n            ExprKind::Loop(_, label, _, _) => {\n                if let Some(label) = label {\n                    self.inner_labels.push(*label);\n                }\n                self.loop_depth += 1;\n                walk_expr(self, ex);\n                self.loop_depth -= 1;\n                if label.is_some() {\n                    self.inner_labels.pop();\n                }\n            },\n            _ => {\n                // Calls to a function that never return\n                if let Some(did) = fn_def_id(self.cx, ex) {\n                    let fn_ret_ty = self.cx.tcx.fn_sig(did).skip_binder().output().skip_binder();\n                    if fn_ret_ty.is_never() {\n                        self.is_finite = true;\n                        return;\n                    }\n                }\n                walk_expr(self, ex);\n            },\n        }\n    }\n}\n\n/// Return `true` if the given [`FnRetTy`] is never (!).\n///\n/// Note: This function also take care of return type of async fn,\n/// as the actual type is behind an [`OpaqueDef`](TyKind::OpaqueDef).\nfn is_never_return(ret_ty: FnRetTy<'_>) -> bool {\n    let FnRetTy::Return(hir_ty) = ret_ty else { return false };\n\n    match hir_ty.kind {\n        TyKind::Never => true,\n        TyKind::OpaqueDef(hir::OpaqueTy {\n            origin: hir::OpaqueTyOrigin::AsyncFn { .. },\n            bounds,\n            ..\n        }) => {\n            if let Some(trait_ref) = bounds.iter().find_map(|b| b.trait_ref())\n                && let Some(segment) = trait_ref\n                    .path\n                    .segments\n                    .iter()\n                    .find(|seg| seg.ident.name == sym::future_trait)\n                && let Some(args) = segment.args\n                && let Some(cst_kind) = args\n                    .constraints\n                    .iter()\n                    .find_map(|cst| (cst.ident.name == sym::Output).then_some(cst.kind))\n                && let hir::AssocItemConstraintKind::Equality {\n                    term: hir::Term::Ty(ty),\n                } = cst_kind\n            {\n                matches!(ty.kind, TyKind::Never)\n            } else {\n                false\n            }\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/iter_next_loop.rs",
    "content": "use super::ITER_NEXT_LOOP;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\npub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>) {\n    if cx.ty_based_def(arg).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        span_lint(\n            cx,\n            ITER_NEXT_LOOP,\n            arg.span,\n            \"you are iterating over `Iterator::next()` which is an Option; this will compile but is \\\n            probably not what you want\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/manual_find.rs",
    "content": "use super::MANUAL_FIND;\nuse super::utils::make_iterator_snippet;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::usage::contains_return_break_continue_macro;\nuse clippy_utils::{as_some_expr, higher, peel_blocks_with_stmt};\nuse rustc_errors::Applicability;\nuse rustc_hir::lang_items::LangItem;\nuse rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, Node, Pat, PatKind, Stmt, StmtKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    arg: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    span: Span,\n    expr: &'tcx Expr<'_>,\n) {\n    let inner_expr = peel_blocks_with_stmt(body);\n    // Check for the specific case that the result is returned and optimize suggestion for that (more\n    // cases can be added later)\n    if let Some(higher::If {\n        cond,\n        then,\n        r#else: None,\n    }) = higher::If::hir(inner_expr)\n        && let Some(binding_id) = get_binding(pat)\n        && let ExprKind::Block(block, _) = then.kind\n        && let [stmt] = block.stmts\n        && let StmtKind::Semi(semi) = stmt.kind\n        && let ExprKind::Ret(Some(ret_value)) = semi.kind\n        && let Some(inner_ret) = as_some_expr(cx, ret_value)\n        && inner_ret.res_local_id() == Some(binding_id)\n        && !contains_return_break_continue_macro(cond)\n        && let Some((last_stmt, last_ret)) = last_stmt_and_ret(cx, expr)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let mut snippet = make_iterator_snippet(cx, arg, &mut applicability);\n        // Checks if `pat` is a single reference to a binding (`&x`)\n        let is_ref_to_binding =\n            matches!(pat.kind, PatKind::Ref(inner, _, _) if matches!(inner.kind, PatKind::Binding(..)));\n        // If `pat` is not a binding or a reference to a binding (`x` or `&x`)\n        // we need to map it to the binding returned by the function (i.e. `.map(|(x, _)| x)`)\n        if !(matches!(pat.kind, PatKind::Binding(..)) || is_ref_to_binding) {\n            snippet.push_str(\n                &format!(\n                    \".map(|{}| {})\",\n                    snippet_with_applicability(cx, pat.span, \"..\", &mut applicability),\n                    snippet_with_applicability(cx, inner_ret.span, \"..\", &mut applicability),\n                )[..],\n            );\n        }\n        let ty = cx.typeck_results().expr_ty(inner_ret);\n        if cx\n            .tcx\n            .lang_items()\n            .copy_trait()\n            .is_some_and(|id| implements_trait(cx, ty, id, &[]))\n        {\n            snippet.push_str(\n                &format!(\n                    \".find(|{}{}| {})\",\n                    \"&\".repeat(1 + usize::from(is_ref_to_binding)),\n                    snippet_with_applicability(cx, inner_ret.span, \"..\", &mut applicability),\n                    snippet_with_applicability(cx, cond.span, \"..\", &mut applicability),\n                )[..],\n            );\n            if is_ref_to_binding {\n                snippet.push_str(\".copied()\");\n            }\n        } else {\n            applicability = Applicability::MaybeIncorrect;\n            snippet.push_str(\n                &format!(\n                    \".find(|{}| {})\",\n                    snippet_with_applicability(cx, inner_ret.span, \"..\", &mut applicability),\n                    snippet_with_applicability(cx, cond.span, \"..\", &mut applicability),\n                )[..],\n            );\n        }\n\n        // If the return type requires adjustments, we need to add a `.map` after the iterator\n        let inner_ret_adjust = cx.typeck_results().expr_adjustments(inner_ret);\n        if !inner_ret_adjust.is_empty() {\n            snippet.push_str(\".map(|v| v as _)\");\n        }\n\n        // Extends to `last_stmt` to include semicolon in case of `return None;`\n        let lint_span = span.to(last_stmt.span).to(last_ret.span);\n        span_lint_and_then(\n            cx,\n            MANUAL_FIND,\n            lint_span,\n            \"manual implementation of `Iterator::find`\",\n            |diag| {\n                if applicability == Applicability::MaybeIncorrect {\n                    diag.note(\"you may need to dereference some variables\");\n                }\n                diag.span_suggestion(lint_span, \"replace with an iterator\", snippet, applicability);\n            },\n        );\n    }\n}\n\nfn get_binding(pat: &Pat<'_>) -> Option<HirId> {\n    let mut hir_id = None;\n    let mut count = 0;\n    pat.each_binding(|annotation, id, _, _| {\n        count += 1;\n        if count > 1 {\n            hir_id = None;\n            return;\n        }\n        if let BindingMode::NONE = annotation {\n            hir_id = Some(id);\n        }\n    });\n    hir_id\n}\n\n// Returns the last statement and last return if function fits format for lint\nfn last_stmt_and_ret<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n) -> Option<(&'tcx Stmt<'tcx>, &'tcx Expr<'tcx>)> {\n    // Returns last non-return statement and the last return\n    fn extract<'tcx>(block: &Block<'tcx>) -> Option<(&'tcx Stmt<'tcx>, &'tcx Expr<'tcx>)> {\n        if let [.., last_stmt] = block.stmts {\n            if let Some(ret) = block.expr {\n                return Some((last_stmt, ret));\n            }\n            if let [.., snd_last, _] = block.stmts\n                && let StmtKind::Semi(last_expr) = last_stmt.kind\n                && let ExprKind::Ret(Some(ret)) = last_expr.kind\n            {\n                return Some((snd_last, ret));\n            }\n        }\n        None\n    }\n    let mut parent_iter = cx.tcx.hir_parent_iter(expr.hir_id);\n    if let Some((node_hir, Node::Stmt(..))) = parent_iter.next()\n        // This should be the loop\n        // This should be the function body\n        && let Some((_, Node::Block(block))) = parent_iter.next()\n        && let Some((last_stmt, last_ret)) = extract(block)\n        && last_stmt.hir_id == node_hir\n        && last_ret.res(cx).ctor_parent(cx).is_lang_item(cx, LangItem::OptionNone)\n        && let Some((_, Node::Expr(_block))) = parent_iter.next()\n        // This includes the function header\n        && let Some((_, func)) = parent_iter.next()\n        && func.fn_kind().is_some()\n    {\n        Some((block.stmts.last().unwrap(), last_ret))\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/manual_flatten.rs",
    "content": "use super::MANUAL_FLATTEN;\nuse super::utils::make_iterator_snippet;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};\nuse clippy_utils::visitors::is_local_used;\nuse clippy_utils::{higher, is_refutable, peel_blocks_with_stmt, span_contains_comment};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Expr, Pat, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::Span;\n\n/// Check for unnecessary `if let` usage in a for loop where only the `Some` or `Ok` variant of the\n/// iterator element is used.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    arg: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    span: Span,\n    msrv: Msrv,\n) {\n    let inner_expr = peel_blocks_with_stmt(body);\n    if let Some(higher::IfLet { let_pat, let_expr, if_then, if_else: None, .. })\n            = higher::IfLet::hir(cx, inner_expr)\n        // Ensure match_expr in `if let` statement is the same as the pat from the for-loop\n        && let PatKind::Binding(_, pat_hir_id, _, _) = pat.kind\n        && let_expr.res_local_id() == Some(pat_hir_id)\n        // Ensure the `if let` statement is for the `Some` variant of `Option` or the `Ok` variant of `Result`\n        && let PatKind::TupleStruct(ref qpath, [inner_pat], _) = let_pat.kind\n        && let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(qpath, let_pat.hir_id)\n        && let Some(variant_id) = cx.tcx.opt_parent(ctor_id)\n        && let some_ctor = cx.tcx.lang_items().option_some_variant() == Some(variant_id)\n        && let ok_ctor = cx.tcx.lang_items().result_ok_variant() == Some(variant_id)\n        && (some_ctor || ok_ctor)\n        // Ensure expr in `if let` is not used afterwards\n        && !is_local_used(cx, if_then, pat_hir_id)\n        && msrv.meets(cx, msrvs::ITER_FLATTEN)\n        && !is_refutable(cx, inner_pat)\n    {\n        if arg.span.from_expansion() || if_then.span.from_expansion() {\n            return;\n        }\n        let if_let_type = if some_ctor { \"Some\" } else { \"Ok\" };\n        // Prepare the error message\n        let msg =\n            format!(\"unnecessary `if let` since only the `{if_let_type}` variant of the iterator element is used\");\n\n        // Prepare the help message\n        let mut applicability = if span_contains_comment(cx, body.span) {\n            Applicability::MaybeIncorrect\n        } else {\n            Applicability::MachineApplicable\n        };\n        let arg_snippet = make_iterator_snippet(cx, arg, &mut applicability);\n        let copied = match cx.typeck_results().expr_ty(let_expr).kind() {\n            ty::Ref(_, inner, _) => match inner.kind() {\n                ty::Ref(..) => \".copied()\",\n                _ => \"\",\n            },\n            _ => \"\",\n        };\n\n        let help_msg = \"try `.flatten()` and remove the `if let` statement in the for loop\";\n\n        let pat_snippet =\n            snippet_with_applicability(cx, inner_pat.span.source_callsite(), \"_\", &mut applicability).to_string();\n        let body_snippet =\n            snippet_with_applicability(cx, if_then.span.source_callsite(), \"[body]\", &mut applicability).to_string();\n        let suggestions = vec![\n            // flatten the iterator\n            (arg.span, format!(\"{arg_snippet}{copied}.flatten()\")),\n            (pat.span, pat_snippet),\n            // remove the `if let` statement\n            (\n                body.span,\n                reindent_multiline(&body_snippet, true, indent_of(cx, body.span)),\n            ),\n        ];\n\n        span_lint_and_then(cx, MANUAL_FLATTEN, span, msg, |diag| {\n            diag.span_help(inner_expr.span, help_msg);\n            diag.multipart_suggestion(\"try\", suggestions, applicability);\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/manual_memcpy.rs",
    "content": "use super::{IncrementVisitor, InitializeVisitor, MANUAL_MEMCPY};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::is_copy;\nuse clippy_utils::usage::local_used_in;\nuse clippy_utils::{get_enclosing_block, higher, sugg};\nuse rustc_ast::ast;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::walk_block;\nuse rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Pat, PatKind, StmtKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::symbol::sym;\nuse std::fmt::Display;\n\n/// Checks for `for` loops that sequentially copy items from one slice-like\n/// object to another.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    arg: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    expr: &'tcx Expr<'_>,\n) -> bool {\n    if let Some(higher::Range {\n        start: Some(start),\n        end: Some(end),\n        limits,\n        span: _,\n    }) = higher::Range::hir(cx, arg)\n        // the var must be a single name\n        && let PatKind::Binding(_, canonical_id, _, _) = pat.kind\n    {\n        let mut starts = vec![Start {\n            id: canonical_id,\n            kind: StartKind::Range,\n        }];\n\n        // This is one of few ways to return different iterators\n        // derived from: https://stackoverflow.com/questions/29760668/conditionally-iterate-over-one-of-several-possible-iterators/52064434#52064434\n        let mut iter_a = None;\n        let mut iter_b = None;\n\n        if let ExprKind::Block(block, _) = body.kind {\n            if let Some(loop_counters) = get_loop_counters(cx, block, expr) {\n                starts.extend(loop_counters);\n            }\n            iter_a = Some(get_assignments(block, &starts));\n        } else {\n            iter_b = Some(get_assignment(body));\n        }\n\n        let assignments = iter_a.into_iter().flatten().chain(iter_b);\n\n        let big_sugg = assignments\n            // The only statements in the for loops can be indexed assignments from\n            // indexed retrievals (except increments of loop counters).\n            .map(|o| {\n                o.and_then(|(lhs, rhs)| {\n                    let rhs = fetch_cloned_expr(rhs);\n                    if let ExprKind::Index(base_left, idx_left, _) = lhs.kind\n                            && let ExprKind::Index(base_right, idx_right, _) = rhs.kind\n                            && let Some(ty) = get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_left))\n                            && get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_right)).is_some()\n                            && let Some((start_left, offset_left)) = get_details_from_idx(cx, idx_left, &starts)\n                            && let Some((start_right, offset_right)) = get_details_from_idx(cx, idx_right, &starts)\n                            && !local_used_in(cx, canonical_id, base_left)\n                            && !local_used_in(cx, canonical_id, base_right)\n\t\t\t\t\t\t\t// Source and destination must be different\n                            && base_left.res_local_id() != base_right.res_local_id()\n                    {\n                        Some((\n                            ty,\n                            IndexExpr {\n                                base: base_left,\n                                idx: start_left,\n                                idx_offset: offset_left,\n                            },\n                            IndexExpr {\n                                base: base_right,\n                                idx: start_right,\n                                idx_offset: offset_right,\n                            },\n                        ))\n                    } else {\n                        None\n                    }\n                })\n            })\n            .map(|o| o.map(|(ty, dst, src)| build_manual_memcpy_suggestion(cx, start, end, limits, ty, &dst, &src)))\n            .collect::<Option<Vec<_>>>()\n            .filter(|v| !v.is_empty())\n            .map(|v| v.join(\"\\n    \"));\n\n        if let Some(big_sugg) = big_sugg {\n            span_lint_and_sugg(\n                cx,\n                MANUAL_MEMCPY,\n                expr.span,\n                \"it looks like you're manually copying between slices\",\n                \"try replacing the loop by\",\n                big_sugg,\n                Applicability::Unspecified,\n            );\n            return true;\n        }\n    }\n    false\n}\n\nfn build_manual_memcpy_suggestion<'tcx>(\n    cx: &LateContext<'tcx>,\n    start: &Expr<'_>,\n    end: &Expr<'_>,\n    limits: ast::RangeLimits,\n    elem_ty: Ty<'tcx>,\n    dst: &IndexExpr<'_>,\n    src: &IndexExpr<'_>,\n) -> String {\n    fn print_offset(offset: MinifyingSugg<'static>) -> MinifyingSugg<'static> {\n        if offset.to_string() == \"0\" {\n            sugg::EMPTY.into()\n        } else {\n            offset\n        }\n    }\n\n    let print_limit = |end: &Expr<'_>, end_str: &str, base: &Expr<'_>, sugg: MinifyingSugg<'static>| {\n        if let ExprKind::MethodCall(method, recv, [], _) = end.kind\n            && method.ident.name == sym::len\n            && recv.res_local_id() == base.res_local_id()\n        {\n            if sugg.to_string() == end_str {\n                sugg::EMPTY.into()\n            } else {\n                sugg\n            }\n        } else {\n            match limits {\n                ast::RangeLimits::Closed => sugg + &sugg::ONE.into(),\n                ast::RangeLimits::HalfOpen => sugg,\n            }\n        }\n    };\n\n    let start_str = Sugg::hir(cx, start, \"\").into();\n    let end_str: MinifyingSugg<'_> = Sugg::hir(cx, end, \"\").into();\n\n    let print_offset_and_limit = |idx_expr: &IndexExpr<'_>| match idx_expr.idx {\n        StartKind::Range => (\n            print_offset(apply_offset(&start_str, &idx_expr.idx_offset)).into_sugg(),\n            print_limit(\n                end,\n                end_str.to_string().as_str(),\n                idx_expr.base,\n                apply_offset(&end_str, &idx_expr.idx_offset),\n            )\n            .into_sugg(),\n        ),\n        StartKind::Counter { initializer } => {\n            let counter_start = Sugg::hir(cx, initializer, \"\").into();\n            (\n                print_offset(apply_offset(&counter_start, &idx_expr.idx_offset)).into_sugg(),\n                print_limit(\n                    end,\n                    end_str.to_string().as_str(),\n                    idx_expr.base,\n                    apply_offset(&end_str, &idx_expr.idx_offset) + &counter_start - &start_str,\n                )\n                .into_sugg(),\n            )\n        },\n    };\n\n    let (dst_offset, dst_limit) = print_offset_and_limit(dst);\n    let (src_offset, src_limit) = print_offset_and_limit(src);\n\n    let dst_base_str = snippet(cx, dst.base.span, \"???\");\n    let src_base_str = snippet(cx, src.base.span, \"???\");\n\n    let dst = if (dst_offset == sugg::EMPTY && dst_limit == sugg::EMPTY)\n        || is_array_length_equal_to_range(cx, start, end, dst.base)\n    {\n        dst_base_str\n    } else {\n        format!(\n            \"{dst_base_str}[{}..{}]\",\n            dst_offset.maybe_paren(),\n            dst_limit.maybe_paren()\n        )\n        .into()\n    };\n\n    let method_str = if is_copy(cx, elem_ty) {\n        \"copy_from_slice\"\n    } else {\n        \"clone_from_slice\"\n    };\n\n    let src = if is_array_length_equal_to_range(cx, start, end, src.base) {\n        src_base_str\n    } else {\n        format!(\n            \"{src_base_str}[{}..{}]\",\n            src_offset.maybe_paren(),\n            src_limit.maybe_paren()\n        )\n        .into()\n    };\n\n    format!(\"{dst}.{method_str}(&{src});\")\n}\n\n/// a wrapper of `Sugg`. Besides what `Sugg` do, this removes unnecessary `0`;\n/// and also, it avoids subtracting a variable from the same one by replacing it with `0`.\n/// it exists for the convenience of the overloaded operators while normal functions can do the\n/// same.\n#[derive(Clone)]\nstruct MinifyingSugg<'a>(Sugg<'a>);\n\nimpl Display for MinifyingSugg<'_> {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        self.0.fmt(f)\n    }\n}\n\nimpl<'a> MinifyingSugg<'a> {\n    fn into_sugg(self) -> Sugg<'a> {\n        self.0\n    }\n}\n\nimpl<'a> From<Sugg<'a>> for MinifyingSugg<'a> {\n    fn from(sugg: Sugg<'a>) -> Self {\n        Self(sugg)\n    }\n}\n\nimpl std::ops::Add for &MinifyingSugg<'static> {\n    type Output = MinifyingSugg<'static>;\n    fn add(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> {\n        match (self.to_string().as_str(), rhs.to_string().as_str()) {\n            (\"0\", _) => rhs.clone(),\n            (_, \"0\") => self.clone(),\n            (_, _) => (&self.0 + &rhs.0).into(),\n        }\n    }\n}\n\nimpl std::ops::Sub for &MinifyingSugg<'static> {\n    type Output = MinifyingSugg<'static>;\n    fn sub(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> {\n        match (self.to_string().as_str(), rhs.to_string().as_str()) {\n            (_, \"0\") => self.clone(),\n            (\"0\", _) => (-rhs.0.clone()).into(),\n            (x, y) if x == y => sugg::ZERO.into(),\n            (_, _) => (&self.0 - &rhs.0).into(),\n        }\n    }\n}\n\nimpl std::ops::Add<&MinifyingSugg<'static>> for MinifyingSugg<'static> {\n    type Output = MinifyingSugg<'static>;\n    fn add(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> {\n        match (self.to_string().as_str(), rhs.to_string().as_str()) {\n            (\"0\", _) => rhs.clone(),\n            (_, \"0\") => self,\n            (_, _) => (self.0 + &rhs.0).into(),\n        }\n    }\n}\n\nimpl std::ops::Sub<&MinifyingSugg<'static>> for MinifyingSugg<'static> {\n    type Output = MinifyingSugg<'static>;\n    fn sub(self, rhs: &MinifyingSugg<'static>) -> MinifyingSugg<'static> {\n        match (self.to_string().as_str(), rhs.to_string().as_str()) {\n            (_, \"0\") => self,\n            (\"0\", _) => (-rhs.0.clone()).into(),\n            (x, y) if x == y => sugg::ZERO.into(),\n            (_, _) => (self.0 - &rhs.0).into(),\n        }\n    }\n}\n\n/// a wrapper around `MinifyingSugg`, which carries an operator like currying\n/// so that the suggested code become more efficient (e.g. `foo + -bar` `foo - bar`).\nstruct Offset {\n    value: MinifyingSugg<'static>,\n    sign: OffsetSign,\n}\n\n#[derive(Clone, Copy)]\nenum OffsetSign {\n    Positive,\n    Negative,\n}\n\nimpl Offset {\n    fn negative(value: Sugg<'static>) -> Self {\n        Self {\n            value: value.into(),\n            sign: OffsetSign::Negative,\n        }\n    }\n\n    fn positive(value: Sugg<'static>) -> Self {\n        Self {\n            value: value.into(),\n            sign: OffsetSign::Positive,\n        }\n    }\n\n    fn empty() -> Self {\n        Self::positive(sugg::ZERO)\n    }\n}\n\nfn apply_offset(lhs: &MinifyingSugg<'static>, rhs: &Offset) -> MinifyingSugg<'static> {\n    match rhs.sign {\n        OffsetSign::Positive => lhs + &rhs.value,\n        OffsetSign::Negative => lhs - &rhs.value,\n    }\n}\n\n#[derive(Debug, Clone, Copy)]\nenum StartKind<'hir> {\n    Range,\n    Counter { initializer: &'hir Expr<'hir> },\n}\n\nstruct IndexExpr<'hir> {\n    base: &'hir Expr<'hir>,\n    idx: StartKind<'hir>,\n    idx_offset: Offset,\n}\n\nstruct Start<'hir> {\n    id: HirId,\n    kind: StartKind<'hir>,\n}\n\nfn get_slice_like_element_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {\n    match ty.kind() {\n        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Vec, adt.did()) => Some(subs.type_at(0)),\n        ty::Ref(_, subty, _) => get_slice_like_element_ty(cx, *subty),\n        ty::Slice(ty) | ty::Array(ty, _) => Some(*ty),\n        _ => None,\n    }\n}\n\nfn fetch_cloned_expr<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {\n    if let ExprKind::MethodCall(method, arg, [], _) = expr.kind\n        && method.ident.name == sym::clone\n    {\n        arg\n    } else {\n        expr\n    }\n}\n\nfn get_details_from_idx<'tcx>(\n    cx: &LateContext<'tcx>,\n    idx: &Expr<'_>,\n    starts: &[Start<'tcx>],\n) -> Option<(StartKind<'tcx>, Offset)> {\n    fn get_start<'tcx>(e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option<StartKind<'tcx>> {\n        let id = e.res_local_id()?;\n        starts.iter().find(|start| start.id == id).map(|start| start.kind)\n    }\n\n    fn get_offset<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>, starts: &[Start<'tcx>]) -> Option<Sugg<'static>> {\n        match &e.kind {\n            ExprKind::Lit(l) => match l.node {\n                ast::LitKind::Int(x, _ty) => Some(Sugg::NonParen(x.to_string().into())),\n                _ => None,\n            },\n            ExprKind::Path(..) if get_start(e, starts).is_none() => Some(Sugg::hir(cx, e, \"???\")),\n            _ => None,\n        }\n    }\n\n    match idx.kind {\n        ExprKind::Binary(op, lhs, rhs) => match op.node {\n            BinOpKind::Add => {\n                let offset_opt = get_start(lhs, starts)\n                    .and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, o)))\n                    .or_else(|| get_start(rhs, starts).and_then(|s| get_offset(cx, lhs, starts).map(|o| (s, o))));\n\n                offset_opt.map(|(s, o)| (s, Offset::positive(o)))\n            },\n            BinOpKind::Sub => {\n                get_start(lhs, starts).and_then(|s| get_offset(cx, rhs, starts).map(|o| (s, Offset::negative(o))))\n            },\n            _ => None,\n        },\n        ExprKind::Path(..) => get_start(idx, starts).map(|s| (s, Offset::empty())),\n        _ => None,\n    }\n}\n\nfn get_assignment<'tcx>(e: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {\n    if let ExprKind::Assign(lhs, rhs, _) = e.kind {\n        Some((lhs, rhs))\n    } else {\n        None\n    }\n}\n\n/// Get assignments from the given block.\n/// The returned iterator yields `None` if no assignment expressions are there,\n/// filtering out the increments of the given whitelisted loop counters;\n/// because its job is to make sure there's nothing other than assignments and the increments.\nfn get_assignments<'a, 'tcx>(\n    Block { stmts, expr, .. }: &'tcx Block<'tcx>,\n    loop_counters: &'a [Start<'tcx>],\n) -> impl Iterator<Item = Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)>> + 'a {\n    // As the `filter` and `map` below do different things, I think putting together\n    // just increases complexity. (cc #3188 and #4193)\n    stmts\n        .iter()\n        .filter_map(move |stmt| match stmt.kind {\n            StmtKind::Let(..) | StmtKind::Item(..) => None,\n            StmtKind::Expr(e) | StmtKind::Semi(e) => Some(e),\n        })\n        .chain(*expr)\n        .filter(move |e| {\n            if let ExprKind::AssignOp(_, place, _) = e.kind {\n                place.res_local_id().is_some_and(|id| {\n                    !loop_counters\n                        .iter()\n                        // skip the first item which should be `StartKind::Range`\n                        // this makes it possible to use the slice with `StartKind::Range` in the same iterator loop.\n                        .skip(1)\n                        .any(|counter| counter.id == id)\n                })\n            } else {\n                true\n            }\n        })\n        .map(get_assignment)\n}\n\nfn get_loop_counters<'a, 'tcx>(\n    cx: &'a LateContext<'tcx>,\n    body: &'tcx Block<'tcx>,\n    expr: &'tcx Expr<'_>,\n) -> Option<impl Iterator<Item = Start<'tcx>> + 'a> {\n    // Look for variables that are incremented once per loop iteration.\n    let mut increment_visitor = IncrementVisitor::new(cx);\n    walk_block(&mut increment_visitor, body);\n\n    // For each candidate, check the parent block to see if\n    // it's initialized to zero at the start of the loop.\n    get_enclosing_block(cx, expr.hir_id).and_then(|block| {\n        increment_visitor\n            .into_results()\n            .filter_map(move |var_id| {\n                let mut initialize_visitor = InitializeVisitor::new(cx, expr, var_id);\n                walk_block(&mut initialize_visitor, block);\n\n                initialize_visitor.get_result().map(|(_, _, initializer)| Start {\n                    id: var_id,\n                    kind: StartKind::Counter { initializer },\n                })\n            })\n            .into()\n    })\n}\n\nfn is_array_length_equal_to_range(cx: &LateContext<'_>, start: &Expr<'_>, end: &Expr<'_>, arr: &Expr<'_>) -> bool {\n    fn extract_lit_value(expr: &Expr<'_>) -> Option<u128> {\n        if let ExprKind::Lit(lit) = expr.kind\n            && let ast::LitKind::Int(value, _) = lit.node\n        {\n            Some(value.get())\n        } else {\n            None\n        }\n    }\n\n    let arr_ty = cx.typeck_results().expr_ty(arr).peel_refs();\n\n    if let ty::Array(_, s) = arr_ty.kind() {\n        let size: u128 = if let Some(size) = s.try_to_target_usize(cx.tcx) {\n            size.into()\n        } else {\n            return false;\n        };\n\n        let range = match (extract_lit_value(start), extract_lit_value(end)) {\n            (Some(start_value), Some(end_value)) => end_value - start_value,\n            _ => return false,\n        };\n\n        size == range\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/manual_slice_fill.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::eager_or_lazy::switch_to_eager_eval;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::{implements_trait, is_slice_like};\nuse clippy_utils::visitors::is_local_used;\nuse clippy_utils::{higher, peel_blocks_with_stmt, span_contains_comment};\nuse rustc_ast::ast::LitKind;\nuse rustc_ast::{RangeLimits, UnOp};\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::QPath::Resolved;\nuse rustc_hir::def::Res;\nuse rustc_hir::{Expr, ExprKind, Pat};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::sym;\n\nuse super::MANUAL_SLICE_FILL;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    arg: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    expr: &'tcx Expr<'_>,\n    msrv: Msrv,\n) {\n    // `for _ in 0..slice.len() { slice[_] = value; }`\n    if let Some(higher::Range {\n        start: Some(start),\n        end: Some(end),\n        limits: RangeLimits::HalfOpen,\n        span: _,\n    }) = higher::Range::hir(cx, arg)\n        && let ExprKind::Lit(Spanned {\n            node: LitKind::Int(Pu128(0), _),\n            ..\n        }) = start.kind\n        && let ExprKind::Block(..) = body.kind\n        // Check if the body is an assignment to a slice element.\n        && let ExprKind::Assign(assignee, assignval, _) = peel_blocks_with_stmt(body).kind\n        && let ExprKind::Index(slice, idx, _) = assignee.kind\n        // Check if `len()` is used for the range end.\n        && let ExprKind::MethodCall(path, recv,..) = end.kind\n        && path.ident.name == sym::len\n        // Check if the slice which is being assigned to is the same as the one being iterated over.\n        && let ExprKind::Path(Resolved(_, recv_path)) = recv.kind\n        && let ExprKind::Path(Resolved(_, slice_path)) = slice.kind\n        && recv_path.res == slice_path.res\n        && !assignval.span.from_expansion()\n        // It is generally not equivalent to use the `fill` method if `assignval` can have side effects\n        && switch_to_eager_eval(cx, assignval)\n        // The `fill` method requires that the slice's element type implements the `Clone` trait.\n        && let Some(clone_trait) = cx.tcx.lang_items().clone_trait()\n        && implements_trait(cx, cx.typeck_results().expr_ty(slice), clone_trait, &[])\n        // https://github.com/rust-lang/rust-clippy/issues/14192\n        && let ExprKind::Path(Resolved(_, idx_path)) = idx.kind\n        && let Res::Local(idx_hir) = idx_path.res\n        && !is_local_used(cx, assignval, idx_hir)\n        && msrv.meets(cx, msrvs::SLICE_FILL)\n        && let slice_ty = cx.typeck_results().expr_ty(slice).peel_refs()\n        && is_slice_like(cx, slice_ty)\n    {\n        sugg(cx, body, expr, slice.span, assignval.span);\n    }\n    // `for _ in &mut slice { *_ = value; }`\n    else if let ExprKind::AddrOf(_, _, recv) = arg.kind\n        // Check if the body is an assignment to a slice element.\n        && let ExprKind::Assign(assignee, assignval, _) = peel_blocks_with_stmt(body).kind\n        && let ExprKind::Unary(UnOp::Deref, slice_iter) = assignee.kind\n        && let ExprKind::Path(Resolved(_, recv_path)) = recv.kind\n        // Check if the slice which is being assigned to is the same as the one being iterated over.\n        && let ExprKind::Path(Resolved(_, slice_path)) = slice_iter.kind\n        && let Res::Local(local) = slice_path.res\n        && local == pat.hir_id\n        && !assignval.span.from_expansion()\n        && switch_to_eager_eval(cx, assignval)\n        // `assignval` must not reference the iterator\n        && !is_local_used(cx, assignval, local)\n        // The `fill` method cannot be used if the slice's element type does not implement the `Clone` trait.\n        && let Some(clone_trait) = cx.tcx.lang_items().clone_trait()\n        && implements_trait(cx, cx.typeck_results().expr_ty(recv), clone_trait, &[])\n        && msrv.meets(cx, msrvs::SLICE_FILL)\n    {\n        sugg(cx, body, expr, recv_path.span, assignval.span);\n    }\n}\n\nfn sugg<'tcx>(\n    cx: &LateContext<'tcx>,\n    body: &'tcx Expr<'_>,\n    expr: &'tcx Expr<'_>,\n    slice_span: rustc_span::Span,\n    assignval_span: rustc_span::Span,\n) {\n    let mut app = if span_contains_comment(cx, body.span) {\n        Applicability::MaybeIncorrect // Comments may be informational.\n    } else {\n        Applicability::MachineApplicable\n    };\n\n    span_lint_and_sugg(\n        cx,\n        MANUAL_SLICE_FILL,\n        expr.span,\n        \"manually filling a slice\",\n        \"try\",\n        format!(\n            \"{}.fill({});\",\n            snippet_with_applicability(cx, slice_span, \"..\", &mut app),\n            snippet_with_applicability(cx, assignval_span, \"..\", &mut app),\n        ),\n        app,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/manual_while_let_some.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{SpanlessEq, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Pat, Stmt, StmtKind, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, Symbol};\nuse std::borrow::Cow;\n\nuse super::MANUAL_WHILE_LET_SOME;\n\n/// The kind of statement that the `pop()` call appeared in.\n///\n/// Depending on whether the value was assigned to a variable or not changes what pattern\n/// we use for the suggestion.\n#[derive(Copy, Clone)]\nenum PopStmt<'hir> {\n    /// `x.pop().unwrap()` was and assigned to a variable.\n    /// The pattern of this local variable will be used and the local statement\n    /// is deleted in the suggestion.\n    Local(&'hir Pat<'hir>),\n    /// `x.pop().unwrap()` appeared in an arbitrary expression and was not assigned to a variable.\n    /// The suggestion will use some placeholder identifier and the `x.pop().unwrap()` expression\n    /// is replaced with that identifier.\n    Anonymous,\n}\n\nfn report_lint(cx: &LateContext<'_>, pop_span: Span, pop_stmt_kind: PopStmt<'_>, loop_span: Span, receiver_span: Span) {\n    span_lint_and_then(\n        cx,\n        MANUAL_WHILE_LET_SOME,\n        pop_span,\n        \"you seem to be trying to pop elements from a `Vec` in a loop\",\n        |diag| {\n            let (pat, pop_replacement) = match pop_stmt_kind {\n                PopStmt::Local(pat) => (snippet(cx, pat.span, \"..\"), String::new()),\n                PopStmt::Anonymous => (Cow::Borrowed(\"element\"), \"element\".into()),\n            };\n\n            let loop_replacement = format!(\"while let Some({}) = {}.pop()\", pat, snippet(cx, receiver_span, \"..\"));\n            diag.multipart_suggestion(\n                \"consider using a `while..let` loop\",\n                vec![(loop_span, loop_replacement), (pop_span, pop_replacement)],\n                Applicability::MachineApplicable,\n            );\n        },\n    );\n}\n\nfn match_method_call<const ARGS_COUNT: usize>(cx: &LateContext<'_>, expr: &Expr<'_>, method: Symbol) -> bool {\n    if let ExprKind::MethodCall(_, _, args, _) = expr.kind\n        && args.len() == ARGS_COUNT\n        && let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n    {\n        cx.tcx.is_diagnostic_item(method, id)\n    } else {\n        false\n    }\n}\n\nfn is_vec_pop_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, is_empty_recv: &Expr<'_>) -> bool {\n    if (match_method_call::<0>(cx, expr, sym::option_unwrap) || match_method_call::<1>(cx, expr, sym::option_expect))\n        && let ExprKind::MethodCall(_, unwrap_recv, ..) = expr.kind\n        && match_method_call::<0>(cx, unwrap_recv, sym::vec_pop)\n        && let ExprKind::MethodCall(_, pop_recv, ..) = unwrap_recv.kind\n    {\n        // make sure they're the same `Vec`\n        SpanlessEq::new(cx).eq_expr(pop_recv, is_empty_recv)\n    } else {\n        false\n    }\n}\n\nfn check_local(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &Expr<'_>, loop_span: Span) {\n    if let StmtKind::Let(local) = stmt.kind\n        && let Some(init) = local.init\n        && is_vec_pop_unwrap(cx, init, is_empty_recv)\n    {\n        report_lint(cx, stmt.span, PopStmt::Local(local.pat), loop_span, is_empty_recv.span);\n    }\n}\n\nfn check_call_arguments(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &Expr<'_>, loop_span: Span) {\n    if let StmtKind::Semi(expr) | StmtKind::Expr(expr) = stmt.kind\n        && let ExprKind::MethodCall(.., args, _) | ExprKind::Call(_, args) = expr.kind\n    {\n        let offending_arg = args\n            .iter()\n            .find_map(|arg| is_vec_pop_unwrap(cx, arg, is_empty_recv).then_some(arg.span));\n\n        if let Some(offending_arg) = offending_arg {\n            report_lint(cx, offending_arg, PopStmt::Anonymous, loop_span, is_empty_recv.span);\n        }\n    }\n}\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, full_cond: &'tcx Expr<'_>, body: &'tcx Expr<'_>, loop_span: Span) {\n    if let ExprKind::Unary(UnOp::Not, cond) = full_cond.kind\n        && let ExprKind::MethodCall(_, is_empty_recv, _, _) = cond.kind\n        && match_method_call::<0>(cx, cond, sym::vec_is_empty)\n        && let ExprKind::Block(body, _) = body.kind\n        && let Some(stmt) = body.stmts.first()\n    {\n        check_local(cx, stmt, is_empty_recv, loop_span);\n        check_call_arguments(cx, stmt, is_empty_recv, loop_span);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/missing_spin_loop.rs",
    "content": "use super::MISSING_SPIN_LOOP;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::std_or_core;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nfn unpack_cond<'tcx>(cond: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {\n    match &cond.kind {\n        ExprKind::Block(\n            Block {\n                stmts: [],\n                expr: Some(e),\n                ..\n            },\n            _,\n        )\n        | ExprKind::Unary(_, e) => unpack_cond(e),\n        ExprKind::Binary(_, l, r) => {\n            let l = unpack_cond(l);\n            if let ExprKind::MethodCall(..) = l.kind {\n                l\n            } else {\n                unpack_cond(r)\n            }\n        },\n        _ => cond,\n    }\n}\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'tcx Expr<'_>) {\n    if let ExprKind::Block(\n        Block {\n            stmts: [], expr: None, ..\n        },\n        _,\n    ) = body.kind\n        && let ExprKind::MethodCall(method, callee, ..) = unpack_cond(cond).kind\n        && [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name)\n        && let callee_ty = cx.typeck_results().expr_ty(callee)\n        && callee_ty.is_diag_item(cx, sym::Atomic)\n        && let Some(std_or_core) = std_or_core(cx)\n    {\n        span_lint_and_sugg(\n            cx,\n            MISSING_SPIN_LOOP,\n            body.span,\n            \"busy-waiting loop should at least have a spin loop hint\",\n            \"try\",\n            format!(\"{{ {std_or_core}::hint::spin_loop() }}\"),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/mod.rs",
    "content": "mod char_indices_as_byte_indices;\nmod empty_loop;\nmod explicit_counter_loop;\nmod explicit_into_iter_loop;\nmod explicit_iter_loop;\nmod for_kv_map;\nmod infinite_loop;\nmod iter_next_loop;\nmod manual_find;\nmod manual_flatten;\nmod manual_memcpy;\nmod manual_slice_fill;\nmod manual_while_let_some;\nmod missing_spin_loop;\nmod mut_range_bound;\nmod needless_range_loop;\nmod never_loop;\nmod same_item_push;\nmod single_element_loop;\nmod unused_enumerate_index;\nmod utils;\nmod while_float;\nmod while_immutable_condition;\nmod while_let_loop;\nmod while_let_on_iterator;\n\nuse clippy_config::Conf;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::{higher, sym};\nuse rustc_ast::Label;\nuse rustc_hir::{Expr, ExprKind, LoopSource, Pat};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse utils::{IncrementVisitor, InitializeVisitor, make_iterator_snippet};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of a character position yielded by `.chars().enumerate()` in a context where a **byte index** is expected,\n    /// such as an argument to a specific `str` method or indexing into a `str` or `String`.\n    ///\n    /// ### Why is this bad?\n    /// A character (more specifically, a Unicode scalar value) that is yielded by `str::chars` can take up multiple bytes,\n    /// so a character position does not necessarily have the same byte index at which the character is stored.\n    /// Thus, using the character position where a byte index is expected can unexpectedly return wrong values\n    /// or panic when the string consists of multibyte characters.\n    ///\n    /// For example, the character `a` in `äa` is stored at byte index 2 but has the character position 1.\n    /// Using the character position 1 to index into the string will lead to a panic as it is in the middle of the first character.\n    ///\n    /// Instead of `.chars().enumerate()`, the correct iterator to use is `.char_indices()`, which yields byte indices.\n    ///\n    /// This pattern is technically fine if the strings are known to only use the ASCII subset,\n    /// though in those cases it would be better to use `bytes()` directly to make the intent clearer,\n    /// but there is also no downside to just using `.char_indices()` directly and supporting non-ASCII strings.\n    ///\n    /// You may also want to read the [chapter on strings in the Rust Book](https://doc.rust-lang.org/book/ch08-02-strings.html)\n    /// which goes into this in more detail.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let s = \"...\";\n    /// for (idx, c) in s.chars().enumerate() {\n    ///     let _ = s[idx..]; // ⚠️ Panics for strings consisting of multibyte characters\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let s = \"...\";\n    /// for (idx, c) in s.char_indices() {\n    ///     let _ = s[idx..];\n    /// }\n    /// ```\n    #[clippy::version = \"1.88.0\"]\n    pub CHAR_INDICES_AS_BYTE_INDICES,\n    correctness,\n    \"using the character position yielded by `.chars().enumerate()` in a context where a byte index is expected\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for empty `loop` expressions.\n    ///\n    /// ### Why is this bad?\n    /// These busy loops burn CPU cycles without doing\n    /// anything. It is _almost always_ a better idea to `panic!` than to have\n    /// a busy loop.\n    ///\n    /// If panicking isn't possible, think of the environment and either:\n    ///   - block on something\n    ///   - sleep the thread for some microseconds\n    ///   - yield or pause the thread\n    ///\n    /// For `std` targets, this can be done with\n    /// [`std::thread::sleep`](https://doc.rust-lang.org/std/thread/fn.sleep.html)\n    /// or [`std::thread::yield_now`](https://doc.rust-lang.org/std/thread/fn.yield_now.html).\n    ///\n    /// For `no_std` targets, doing this is more complicated, especially because\n    /// `#[panic_handler]`s can't panic. To stop/pause the thread, you will\n    /// probably need to invoke some target-specific intrinsic. Examples include:\n    ///   - [`x86_64::instructions::hlt`](https://docs.rs/x86_64/0.12.2/x86_64/instructions/fn.hlt.html)\n    ///   - [`cortex_m::asm::wfi`](https://docs.rs/cortex-m/0.6.3/cortex_m/asm/fn.wfi.html)\n    ///\n    /// ### Example\n    /// ```no_run\n    /// loop {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EMPTY_LOOP,\n    suspicious,\n    \"empty `loop {}`, which should block or sleep\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks `for` loops over slices with an explicit counter\n    /// and suggests the use of `.enumerate()`.\n    ///\n    /// ### Why is this bad?\n    /// Using `.enumerate()` makes the intent more clear,\n    /// declutters the code and may be faster in some instances.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let v = vec![1];\n    /// # fn bar(bar: usize, baz: usize) {}\n    /// let mut i = 0;\n    /// for item in &v {\n    ///     bar(i, *item);\n    ///     i += 1;\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let v = vec![1];\n    /// # fn bar(bar: usize, baz: usize) {}\n    /// for (i, item) in v.iter().enumerate() { bar(i, *item); }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EXPLICIT_COUNTER_LOOP,\n    complexity,\n    \"for-looping with an explicit counter when `_.enumerate()` would do\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for loops on `y.into_iter()` where `y` will do, and\n    /// suggests the latter.\n    ///\n    /// ### Why is this bad?\n    /// Readability.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let y = vec![1];\n    /// // with `y` a `Vec` or slice:\n    /// for x in y.into_iter() {\n    ///     // ..\n    /// }\n    /// ```\n    /// can be rewritten to\n    /// ```no_run\n    /// # let y = vec![1];\n    /// for x in y {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EXPLICIT_INTO_ITER_LOOP,\n    pedantic,\n    \"for-looping over `_.into_iter()` when `_` would do\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for loops on `x.iter()` where `&x` will do, and\n    /// suggests the latter.\n    ///\n    /// ### Why is this bad?\n    /// Readability.\n    ///\n    /// ### Known problems\n    /// False negatives. We currently only warn on some known\n    /// types.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // with `y` a `Vec` or slice:\n    /// # let y = vec![1];\n    /// for x in y.iter() {\n    ///     // ..\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let y = vec![1];\n    /// for x in &y {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EXPLICIT_ITER_LOOP,\n    pedantic,\n    \"for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for iterating a map (`HashMap` or `BTreeMap`) and\n    /// ignoring either the keys or values.\n    ///\n    /// ### Why is this bad?\n    /// Readability. There are `keys` and `values` methods that\n    /// can be used to express that don't need the values or keys.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// for (k, _) in &map {\n    ///     ..\n    /// }\n    /// ```\n    ///\n    /// could be replaced by\n    ///\n    /// ```ignore\n    /// for k in map.keys() {\n    ///     ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub FOR_KV_MAP,\n    style,\n    \"looping on a map using `iter` when `keys` or `values` would do\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for infinite loops in a function where the return type is not `!`\n    /// and lint accordingly.\n    ///\n    /// ### Why restrict this?\n    /// Making the return type `!` serves as documentation that the function does not return.\n    /// If the function is not intended to loop infinitely, then this lint may detect a bug.\n    ///\n    /// ### Example\n    /// ```no_run,ignore\n    /// fn run_forever() {\n    ///     loop {\n    ///         // do something\n    ///     }\n    /// }\n    /// ```\n    /// If infinite loops are as intended:\n    /// ```no_run,ignore\n    /// fn run_forever() -> ! {\n    ///     loop {\n    ///         // do something\n    ///     }\n    /// }\n    /// ```\n    /// Otherwise add a `break` or `return` condition:\n    /// ```no_run,ignore\n    /// fn run_forever() {\n    ///     loop {\n    ///         // do something\n    ///         if condition {\n    ///             break;\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.76.0\"]\n    pub INFINITE_LOOP,\n    restriction,\n    \"possibly unintended infinite loop\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for loops on `x.next()`.\n    ///\n    /// ### Why is this bad?\n    /// `next()` returns either `Some(value)` if there was a\n    /// value, or `None` otherwise. The insidious thing is that `Option<_>`\n    /// implements `IntoIterator`, so that possibly one value will be iterated,\n    /// leading to some hard to find bugs. No one will want to write such code\n    /// [except to win an Underhanded Rust\n    /// Contest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr).\n    ///\n    /// ### Example\n    /// ```ignore\n    /// for x in y.next() {\n    ///     ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ITER_NEXT_LOOP,\n    correctness,\n    \"for-looping over `_.next()` which is probably not intended\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual implementations of Iterator::find\n    ///\n    /// ### Why is this bad?\n    /// It doesn't affect performance, but using `find` is shorter and easier to read.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// fn example(arr: Vec<i32>) -> Option<i32> {\n    ///     for el in arr {\n    ///         if el == 1 {\n    ///             return Some(el);\n    ///         }\n    ///     }\n    ///     None\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn example(arr: Vec<i32>) -> Option<i32> {\n    ///     arr.into_iter().find(|&el| el == 1)\n    /// }\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub MANUAL_FIND,\n    complexity,\n    \"manual implementation of `Iterator::find`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary `if let` usage in a for loop\n    /// where only the `Some` or `Ok` variant of the iterator element is used.\n    ///\n    /// ### Why is this bad?\n    /// It is verbose and can be simplified\n    /// by first calling the `flatten` method on the `Iterator`.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// let x = vec![Some(1), Some(2), Some(3)];\n    /// for n in x {\n    ///     if let Some(n) = n {\n    ///         println!(\"{}\", n);\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = vec![Some(1), Some(2), Some(3)];\n    /// for n in x.into_iter().flatten() {\n    ///     println!(\"{}\", n);\n    /// }\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub MANUAL_FLATTEN,\n    complexity,\n    \"for loops over `Option`s or `Result`s with a single expression can be simplified\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for for-loops that manually copy items between\n    /// slices that could be optimized by having a memcpy.\n    ///\n    /// ### Why is this bad?\n    /// It is not as fast as a memcpy.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let src = vec![1];\n    /// # let mut dst = vec![0; 65];\n    /// for i in 0..src.len() {\n    ///     dst[i + 64] = src[i];\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let src = vec![1];\n    /// # let mut dst = vec![0; 65];\n    /// dst[64..(src.len() + 64)].clone_from_slice(&src[..]);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MANUAL_MEMCPY,\n    perf,\n    \"manually copying items between slices\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manually filling a slice with a value.\n    ///\n    /// ### Why is this bad?\n    /// Using the `fill` method is more idiomatic and concise.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut some_slice = [1, 2, 3, 4, 5];\n    /// for i in 0..some_slice.len() {\n    ///     some_slice[i] = 0;\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut some_slice = [1, 2, 3, 4, 5];\n    /// some_slice.fill(0);\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub MANUAL_SLICE_FILL,\n    style,\n    \"manually filling a slice with a value\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for loops that check for emptiness of a `Vec` in the condition and pop an element\n    /// in the body as a separate operation.\n    ///\n    /// ### Why is this bad?\n    /// Such loops can be written in a more idiomatic way by using a while-let loop and directly\n    /// pattern matching on the return value of `Vec::pop()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut numbers = vec![1, 2, 3, 4, 5];\n    /// while !numbers.is_empty() {\n    ///     let number = numbers.pop().unwrap();\n    ///     // use `number`\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut numbers = vec![1, 2, 3, 4, 5];\n    /// while let Some(number) = numbers.pop() {\n    ///     // use `number`\n    /// }\n    /// ```\n    #[clippy::version = \"1.71.0\"]\n    pub MANUAL_WHILE_LET_SOME,\n    style,\n    \"checking for emptiness of a `Vec` in the loop condition and popping an element in the body\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for empty spin loops\n    ///\n    /// ### Why is this bad?\n    /// The loop body should have something like `thread::park()` or at least\n    /// `std::hint::spin_loop()` to avoid needlessly burning cycles and conserve\n    /// energy. Perhaps even better use an actual lock, if possible.\n    ///\n    /// ### Known problems\n    /// This lint doesn't currently trigger on `while let` or\n    /// `loop { match .. { .. } }` loops, which would be considered idiomatic in\n    /// combination with e.g. `AtomicBool::compare_exchange_weak`.\n    ///\n    /// ### Example\n    ///\n    /// ```ignore\n    /// use core::sync::atomic::{AtomicBool, Ordering};\n    /// let b = AtomicBool::new(true);\n    /// // give a ref to `b` to another thread,wait for it to become false\n    /// while b.load(Ordering::Acquire) {};\n    /// ```\n    /// Use instead:\n    /// ```rust,no_run\n    ///# use core::sync::atomic::{AtomicBool, Ordering};\n    ///# let b = AtomicBool::new(true);\n    /// while b.load(Ordering::Acquire) {\n    ///     std::hint::spin_loop()\n    /// }\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub MISSING_SPIN_LOOP,\n    perf,\n    \"An empty busy waiting loop\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for loops with a range bound that is a mutable variable.\n    ///\n    /// ### Why is this bad?\n    /// One might think that modifying the mutable variable changes the loop bounds. It doesn't.\n    ///\n    /// ### Known problems\n    /// False positive when mutation is followed by a `break`, but the `break` is not immediately\n    /// after the mutation:\n    ///\n    /// ```no_run\n    /// let mut x = 5;\n    /// for _ in 0..x {\n    ///     x += 1; // x is a range bound that is mutated\n    ///     ..; // some other expression\n    ///     break; // leaves the loop, so mutation is not an issue\n    /// }\n    /// ```\n    ///\n    /// False positive on nested loops ([#6072](https://github.com/rust-lang/rust-clippy/issues/6072))\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut foo = 42;\n    /// for i in 0..foo {\n    ///     foo -= 1;\n    ///     println!(\"{i}\"); // prints numbers from 0 to 41, not 0 to 21\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MUT_RANGE_BOUND,\n    suspicious,\n    \"for loop over a range where one of the bounds is a mutable variable\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for looping over the range of `0..len` of some\n    /// collection just to get the values by index.\n    ///\n    /// ### Why is this bad?\n    /// Just iterating the collection itself makes the intent\n    /// more clear and is probably faster because it eliminates\n    /// the bounds check that is done when indexing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let vec = vec!['a', 'b', 'c'];\n    /// for i in 0..vec.len() {\n    ///     println!(\"{}\", vec[i]);\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let vec = vec!['a', 'b', 'c'];\n    /// for i in vec {\n    ///     println!(\"{}\", i);\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_RANGE_LOOP,\n    style,\n    \"for-looping over a range of indices where an iterator over items would do\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for loops that will always `break`, `return` or\n    /// `continue` an outer loop.\n    ///\n    /// ### Why is this bad?\n    /// This loop never loops, all it does is obfuscating the\n    /// code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// loop {\n    ///     ..;\n    ///     break;\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEVER_LOOP,\n    correctness,\n    \"any loop that will always `break` or `return`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks whether a for loop is being used to push a constant\n    /// value into a Vec.\n    ///\n    /// ### Why is this bad?\n    /// This kind of operation can be expressed more succinctly with\n    /// `vec![item; SIZE]` or `vec.resize(NEW_SIZE, item)` and using these alternatives may also\n    /// have better performance.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let item1 = 2;\n    /// let item2 = 3;\n    /// let mut vec: Vec<u8> = Vec::new();\n    /// for _ in 0..20 {\n    ///     vec.push(item1);\n    /// }\n    /// for _ in 0..30 {\n    ///     vec.push(item2);\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let item1 = 2;\n    /// let item2 = 3;\n    /// let mut vec: Vec<u8> = vec![item1; 20];\n    /// vec.resize(20 + 30, item2);\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub SAME_ITEM_PUSH,\n    style,\n    \"the same item is pushed inside of a for loop\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks whether a for loop has a single element.\n    ///\n    /// ### Why is this bad?\n    /// There is no reason to have a loop of a\n    /// single element.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let item1 = 2;\n    /// for item in &[item1] {\n    ///     println!(\"{}\", item);\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let item1 = 2;\n    /// let item = &item1;\n    /// println!(\"{}\", item);\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub SINGLE_ELEMENT_LOOP,\n    complexity,\n    \"there is no reason to have a single element loop\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for uses of the `enumerate` method where the index is unused (`_`)\n    ///\n    /// ### Why is this bad?\n    /// The index from `.enumerate()` is immediately dropped.\n    ///\n    /// ### Example\n    /// ```rust\n    /// let v = vec![1, 2, 3, 4];\n    /// for (_, x) in v.iter().enumerate() {\n    ///     println!(\"{x}\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// let v = vec![1, 2, 3, 4];\n    /// for x in v.iter() {\n    ///     println!(\"{x}\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.75.0\"]\n    pub UNUSED_ENUMERATE_INDEX,\n    style,\n    \"using `.enumerate()` and immediately dropping the index\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for while loops comparing floating point values.\n    ///\n    /// ### Why is this bad?\n    /// If you increment floating point values, errors can compound,\n    /// so, use integers instead if possible.\n    ///\n    /// ### Known problems\n    /// The lint will catch all while loops comparing floating point\n    /// values without regarding the increment.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut x = 0.0;\n    /// while x < 42.0 {\n    ///     x += 1.0;\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let mut x = 0;\n    /// while x < 42 {\n    ///     x += 1;\n    /// }\n    /// ```\n    #[clippy::version = \"1.80.0\"]\n    pub WHILE_FLOAT,\n    nursery,\n    \"while loops comparing floating point values\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks whether variables used within while loop condition\n    /// can be (and are) mutated in the body.\n    ///\n    /// ### Why is this bad?\n    /// If the condition is unchanged, entering the body of the loop\n    /// will lead to an infinite loop.\n    ///\n    /// ### Known problems\n    /// If the `while`-loop is in a closure, the check for mutation of the\n    /// condition variables in the body can cause false negatives. For example when only `Upvar` `a` is\n    /// in the condition and only `Upvar` `b` gets mutated in the body, the lint will not trigger.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let i = 0;\n    /// while i > 10 {\n    ///     println!(\"let me loop forever!\");\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub WHILE_IMMUTABLE_CONDITION,\n    correctness,\n    \"variables used within while expression are not mutated in the body\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects `loop + match` combinations that are easier\n    /// written as a `while let` loop.\n    ///\n    /// ### Why is this bad?\n    /// The `while let` loop is usually shorter and more\n    /// readable.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// let y = Some(1);\n    /// loop {\n    ///     let x = match y {\n    ///         Some(x) => x,\n    ///         None => break,\n    ///     };\n    ///     // ..\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,no_run\n    /// let y = Some(1);\n    /// while let Some(x) = y {\n    ///     // ..\n    /// };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub WHILE_LET_LOOP,\n    complexity,\n    \"`loop { if let { ... } else break }`, which can be written as a `while let` loop\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `while let` expressions on iterators.\n    ///\n    /// ### Why is this bad?\n    /// Readability. A simple `for` loop is shorter and conveys\n    /// the intent better.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// while let Some(val) = iter.next() {\n    ///     ..\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```ignore\n    /// for val in &mut iter {\n    ///     ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub WHILE_LET_ON_ITERATOR,\n    style,\n    \"using a `while let` loop instead of a for loop on an iterator\"\n}\n\nimpl_lint_pass!(Loops => [\n    CHAR_INDICES_AS_BYTE_INDICES,\n    EMPTY_LOOP,\n    EXPLICIT_COUNTER_LOOP,\n    EXPLICIT_INTO_ITER_LOOP,\n    EXPLICIT_ITER_LOOP,\n    FOR_KV_MAP,\n    INFINITE_LOOP,\n    ITER_NEXT_LOOP,\n    MANUAL_FIND,\n    MANUAL_FLATTEN,\n    MANUAL_MEMCPY,\n    MANUAL_SLICE_FILL,\n    MANUAL_WHILE_LET_SOME,\n    MISSING_SPIN_LOOP,\n    MUT_RANGE_BOUND,\n    NEEDLESS_RANGE_LOOP,\n    NEVER_LOOP,\n    SAME_ITEM_PUSH,\n    SINGLE_ELEMENT_LOOP,\n    UNUSED_ENUMERATE_INDEX,\n    WHILE_FLOAT,\n    WHILE_IMMUTABLE_CONDITION,\n    WHILE_LET_LOOP,\n    WHILE_LET_ON_ITERATOR,\n]);\n\npub struct Loops {\n    msrv: Msrv,\n    enforce_iter_loop_reborrow: bool,\n}\nimpl Loops {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: conf.msrv,\n            enforce_iter_loop_reborrow: conf.enforce_iter_loop_reborrow,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Loops {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let for_loop = higher::ForLoop::hir(expr);\n        if let Some(higher::ForLoop {\n            pat,\n            arg,\n            body,\n            loop_id,\n            span,\n            label,\n        }) = for_loop\n        {\n            // we don't want to check expanded macros\n            // this check is not at the top of the function\n            // since higher::for_loop expressions are marked as expansions\n            if body.span.from_expansion() {\n                return;\n            }\n            self.check_for_loop(cx, pat, arg, body, expr, span, label);\n            if let ExprKind::Block(block, _) = body.kind {\n                never_loop::check(cx, block, loop_id, span, for_loop.as_ref());\n            }\n        }\n\n        // we don't want to check expanded macros\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        // check for never_loop\n        if let ExprKind::Loop(block, ..) = expr.kind {\n            never_loop::check(cx, block, expr.hir_id, expr.span, None);\n        }\n\n        // check for `loop { if let {} else break }` that could be `while let`\n        // (also matches an explicit \"match\" instead of \"if let\")\n        // (even if the \"match\" or \"if let\" is used for declaration)\n        // (also matches on `let {} else break`)\n        if let ExprKind::Loop(block, label, LoopSource::Loop, _) = expr.kind {\n            // also check for empty `loop {}` statements, skipping those in #[panic_handler]\n            empty_loop::check(cx, expr, block);\n            while_let_loop::check(cx, expr, block);\n            infinite_loop::check(cx, expr, block, label);\n        }\n\n        while_let_on_iterator::check(cx, expr);\n\n        if let Some(higher::While {\n            condition, body, span, ..\n        }) = higher::While::hir(expr)\n        {\n            while_immutable_condition::check(cx, condition, body);\n            while_float::check(cx, condition);\n            missing_spin_loop::check(cx, condition, body);\n            manual_while_let_some::check(cx, condition, body, span);\n        }\n\n        if let ExprKind::MethodCall(path, recv, args, _) = expr.kind {\n            let name = path.ident.name;\n\n            let is_iterator_method = || {\n                cx.ty_based_def(expr)\n                    .assoc_fn_parent(cx)\n                    .is_diag_item(cx, sym::Iterator)\n            };\n\n            // is_iterator_method is a bit expensive, so we call it last in each match arm\n            match (name, args) {\n                (sym::for_each | sym::all | sym::any, [arg]) => {\n                    if let ExprKind::Closure(closure) = arg.kind\n                        && is_iterator_method()\n                    {\n                        unused_enumerate_index::check_method(cx, recv, arg, closure);\n                        never_loop::check_iterator_reduction(cx, expr, recv, closure);\n                    }\n                },\n\n                (sym::filter_map | sym::find_map | sym::flat_map | sym::map, [arg]) => {\n                    if let ExprKind::Closure(closure) = arg.kind\n                        && is_iterator_method()\n                    {\n                        unused_enumerate_index::check_method(cx, recv, arg, closure);\n                    }\n                },\n\n                (sym::try_for_each | sym::reduce, [arg]) | (sym::fold | sym::try_fold, [_, arg]) => {\n                    if let ExprKind::Closure(closure) = arg.kind\n                        && is_iterator_method()\n                    {\n                        never_loop::check_iterator_reduction(cx, expr, recv, closure);\n                    }\n                },\n\n                _ => {},\n            }\n        }\n    }\n}\n\nimpl Loops {\n    #[expect(clippy::too_many_arguments)]\n    fn check_for_loop<'tcx>(\n        &self,\n        cx: &LateContext<'tcx>,\n        pat: &'tcx Pat<'_>,\n        arg: &'tcx Expr<'_>,\n        body: &'tcx Expr<'_>,\n        expr: &'tcx Expr<'_>,\n        span: Span,\n        label: Option<Label>,\n    ) {\n        let is_manual_memcpy_triggered = manual_memcpy::check(cx, pat, arg, body, expr);\n        if !is_manual_memcpy_triggered {\n            manual_slice_fill::check(cx, pat, arg, body, expr, self.msrv);\n            needless_range_loop::check(cx, pat, arg, body, expr);\n            explicit_counter_loop::check(cx, pat, arg, body, expr, label);\n        }\n        self.check_for_loop_arg(cx, pat, arg);\n        for_kv_map::check(cx, pat, arg, body, span);\n        mut_range_bound::check(cx, arg, body);\n        single_element_loop::check(cx, pat, arg, body, expr);\n        same_item_push::check(cx, pat, arg, body, expr, self.msrv);\n        manual_flatten::check(cx, pat, arg, body, span, self.msrv);\n        manual_find::check(cx, pat, arg, body, span, expr);\n        unused_enumerate_index::check(cx, arg, pat, None, body);\n        char_indices_as_byte_indices::check(cx, pat, arg, body);\n    }\n\n    fn check_for_loop_arg(&self, cx: &LateContext<'_>, _: &Pat<'_>, arg: &Expr<'_>) {\n        if !arg.span.from_expansion()\n            && let ExprKind::MethodCall(method, self_arg, [], _) = arg.kind\n        {\n            match method.ident.name {\n                sym::iter | sym::iter_mut => {\n                    explicit_iter_loop::check(cx, self_arg, arg, self.msrv, self.enforce_iter_loop_reborrow);\n                },\n                sym::into_iter => {\n                    explicit_into_iter_loop::check(cx, self_arg, arg);\n                },\n                sym::next => {\n                    iter_next_loop::check(cx, arg);\n                },\n                _ => {},\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/mut_range_bound.rs",
    "content": "use super::MUT_RANGE_BOUND;\nuse clippy_utils::diagnostics::span_lint_and_note;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::{get_enclosing_block, higher};\nuse rustc_hir::intravisit::{self, Visitor};\nuse rustc_hir::{BindingMode, Expr, ExprKind, HirId, Node, PatKind};\nuse rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::FakeReadCause;\nuse rustc_middle::ty;\nuse rustc_span::Span;\nuse std::ops::ControlFlow;\n\npub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) {\n    if let Some(higher::Range {\n        start: Some(start),\n        end: Some(end),\n        ..\n    }) = higher::Range::hir(cx, arg)\n        && let (mut_id_start, mut_id_end) = (check_for_mutability(cx, start), check_for_mutability(cx, end))\n        && (mut_id_start.is_some() || mut_id_end.is_some())\n    {\n        let (span_low, span_high) = check_for_mutation(cx, body, mut_id_start, mut_id_end);\n        mut_warn_with_span(cx, span_low);\n        mut_warn_with_span(cx, span_high);\n    }\n}\n\nfn mut_warn_with_span(cx: &LateContext<'_>, span: Option<Span>) {\n    if let Some(sp) = span {\n        span_lint_and_note(\n            cx,\n            MUT_RANGE_BOUND,\n            sp,\n            \"attempt to mutate range bound within loop\",\n            None,\n            \"the range of the loop is unchanged\",\n        );\n    }\n}\n\nfn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId> {\n    if let Some(hir_id) = bound.res_local_id()\n        && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)\n        && let PatKind::Binding(BindingMode::MUT, ..) = pat.kind\n    {\n        return Some(hir_id);\n    }\n    None\n}\n\nfn check_for_mutation(\n    cx: &LateContext<'_>,\n    body: &Expr<'_>,\n    bound_id_start: Option<HirId>,\n    bound_id_end: Option<HirId>,\n) -> (Option<Span>, Option<Span>) {\n    let mut delegate = MutatePairDelegate {\n        cx,\n        hir_id_low: bound_id_start,\n        hir_id_high: bound_id_end,\n        span_low: None,\n        span_high: None,\n    };\n    ExprUseVisitor::for_clippy(cx, body.hir_id.owner.def_id, &mut delegate)\n        .walk_expr(body)\n        .into_ok();\n\n    delegate.mutation_span()\n}\n\nstruct MutatePairDelegate<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    hir_id_low: Option<HirId>,\n    hir_id_high: Option<HirId>,\n    span_low: Option<Span>,\n    span_high: Option<Span>,\n}\n\nimpl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {\n    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) {\n        if bk == ty::BorrowKind::Mutable\n            && let PlaceBase::Local(id) = cmt.place.base\n        {\n            if Some(id) == self.hir_id_low && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {\n                self.span_low = Some(self.cx.tcx.hir_span(diag_expr_id));\n            }\n            if Some(id) == self.hir_id_high && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {\n                self.span_high = Some(self.cx.tcx.hir_span(diag_expr_id));\n            }\n        }\n    }\n\n    fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {\n        if let PlaceBase::Local(id) = cmt.place.base {\n            if Some(id) == self.hir_id_low && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {\n                self.span_low = Some(self.cx.tcx.hir_span(diag_expr_id));\n            }\n            if Some(id) == self.hir_id_high && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {\n                self.span_high = Some(self.cx.tcx.hir_span(diag_expr_id));\n            }\n        }\n    }\n\n    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}\n}\n\nimpl MutatePairDelegate<'_, '_> {\n    fn mutation_span(&self) -> (Option<Span>, Option<Span>) {\n        (self.span_low, self.span_high)\n    }\n}\n\nstruct BreakAfterExprVisitor {\n    hir_id: HirId,\n    past_expr: bool,\n    break_after_expr: bool,\n}\n\nimpl BreakAfterExprVisitor {\n    pub fn is_found(cx: &LateContext<'_>, hir_id: HirId) -> bool {\n        let mut visitor = BreakAfterExprVisitor {\n            hir_id,\n            past_expr: false,\n            break_after_expr: false,\n        };\n\n        get_enclosing_block(cx, hir_id).is_some_and(|block| {\n            let _ = visitor.visit_block(block);\n            visitor.break_after_expr\n        })\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for BreakAfterExprVisitor {\n    type Result = ControlFlow<()>;\n    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {\n        if expr.hir_id == self.hir_id {\n            self.past_expr = true;\n            ControlFlow::Continue(())\n        } else if self.past_expr {\n            if matches!(&expr.kind, ExprKind::Break(..)) {\n                self.break_after_expr = true;\n            }\n\n            ControlFlow::Break(())\n        } else {\n            intravisit::walk_expr(self, expr)\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/needless_range_loop.rs",
    "content": "use super::NEEDLESS_RANGE_LOOP;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::has_iter_method;\nuse clippy_utils::visitors::is_local_used;\nuse clippy_utils::{SpanlessEq, contains_name, higher, is_integer_const, peel_hir_expr_while, sugg};\nuse rustc_ast::ast;\nuse rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{BinOpKind, BorrowKind, Closure, Expr, ExprKind, HirId, Mutability, Pat, PatKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::middle::region;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::symbol::{Symbol, sym};\nuse std::{iter, mem};\n\n/// Checks for looping over a range and then indexing a sequence with it.\n/// The iteratee must be a range literal.\n#[expect(clippy::too_many_lines)]\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    arg: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    expr: &'tcx Expr<'_>,\n) {\n    if let Some(higher::Range {\n        start: Some(start),\n        ref end,\n        limits,\n        span,\n    }) = higher::Range::hir(cx, arg)\n        // the var must be a single name\n        && let PatKind::Binding(_, canonical_id, ident, _) = pat.kind\n    {\n        let mut visitor = VarVisitor {\n            cx,\n            var: canonical_id,\n            indexed_mut: FxHashSet::default(),\n            indexed_indirectly: FxHashMap::default(),\n            unnamed_indexed_indirectly: false,\n            indexed_directly: FxIndexMap::default(),\n            unnamed_indexed_directly: false,\n            referenced: FxHashSet::default(),\n            nonindex: false,\n            prefer_mutable: false,\n        };\n        walk_expr(&mut visitor, body);\n\n        // linting condition: we only indexed one variable, and indexed it directly\n        if visitor.indexed_indirectly.is_empty()\n            && !visitor.unnamed_indexed_indirectly\n            && !visitor.unnamed_indexed_directly\n            && visitor.indexed_directly.len() == 1\n        {\n            let (indexed, (indexed_extent, indexed_ty)) = visitor\n                .indexed_directly\n                .into_iter()\n                .next()\n                .expect(\"already checked that we have exactly 1 element\");\n\n            // ensure that the indexed variable was declared before the loop, see #601\n            if let Some(indexed_extent) = indexed_extent {\n                let parent_def_id = cx.tcx.hir_get_parent_item(expr.hir_id);\n                let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id);\n                let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id).unwrap();\n                if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) {\n                    return;\n                }\n            }\n\n            // don't lint if the container that is indexed does not have .iter() method\n            let has_iter = has_iter_method(cx, indexed_ty);\n            if has_iter.is_none() {\n                return;\n            }\n\n            // don't lint if the container that is indexed into is also used without\n            // indexing\n            if visitor.referenced.contains(&indexed) {\n                return;\n            }\n\n            let starts_at_zero = is_integer_const(cx, start, 0);\n\n            let skip = if starts_at_zero {\n                String::new()\n            } else if visitor.indexed_mut.contains(&indexed) && contains_name(indexed, start, cx) {\n                return;\n            } else {\n                format!(\".skip({})\", snippet(cx, start.span, \"..\"))\n            };\n\n            let mut end_is_start_plus_val = false;\n\n            let take = if let Some(end) = *end {\n                let mut take_expr = end;\n\n                if let ExprKind::Binary(ref op, left, right) = end.kind\n                    && op.node == BinOpKind::Add\n                {\n                    let start_equal_left = SpanlessEq::new(cx).eq_expr(start, left);\n                    let start_equal_right = SpanlessEq::new(cx).eq_expr(start, right);\n\n                    if start_equal_left {\n                        take_expr = right;\n                    } else if start_equal_right {\n                        take_expr = left;\n                    }\n\n                    end_is_start_plus_val = start_equal_left | start_equal_right;\n                }\n\n                if is_len_call(end, indexed) || is_end_eq_array_len(cx, end, limits, indexed_ty) {\n                    String::new()\n                } else if visitor.indexed_mut.contains(&indexed) && contains_name(indexed, take_expr, cx) {\n                    return;\n                } else {\n                    match limits {\n                        ast::RangeLimits::Closed => {\n                            let take_expr = sugg::Sugg::hir(cx, take_expr, \"<count>\");\n                            format!(\".take({})\", take_expr + sugg::ONE)\n                        },\n                        ast::RangeLimits::HalfOpen => {\n                            format!(\".take({})\", snippet(cx, take_expr.span, \"..\"))\n                        },\n                    }\n                }\n            } else {\n                String::new()\n            };\n\n            let (ref_mut, method) = if visitor.indexed_mut.contains(&indexed) {\n                (\"mut \", \"iter_mut\")\n            } else {\n                (\"\", \"iter\")\n            };\n\n            let take_is_empty = take.is_empty();\n            let mut method_1 = take;\n            let mut method_2 = skip;\n\n            if end_is_start_plus_val {\n                mem::swap(&mut method_1, &mut method_2);\n            }\n\n            if visitor.nonindex {\n                span_lint_and_then(\n                    cx,\n                    NEEDLESS_RANGE_LOOP,\n                    span,\n                    format!(\"the loop variable `{}` is used to index `{indexed}`\", ident.name),\n                    |diag| {\n                        diag.multipart_suggestion(\n                            \"consider using an iterator and enumerate()\",\n                            vec![\n                                (pat.span, format!(\"({}, <item>)\", ident.name)),\n                                (span, format!(\"{indexed}.{method}().enumerate(){method_1}{method_2}\")),\n                            ],\n                            Applicability::HasPlaceholders,\n                        );\n                    },\n                );\n            } else {\n                let repl = if starts_at_zero && take_is_empty {\n                    format!(\"&{ref_mut}{indexed}\")\n                } else {\n                    format!(\"{indexed}.{method}(){method_1}{method_2}\")\n                };\n\n                span_lint_and_then(\n                    cx,\n                    NEEDLESS_RANGE_LOOP,\n                    span,\n                    format!(\"the loop variable `{}` is only used to index `{indexed}`\", ident.name),\n                    |diag| {\n                        diag.multipart_suggestion(\n                            \"consider using an iterator\",\n                            vec![(pat.span, \"<item>\".to_string()), (span, repl)],\n                            Applicability::HasPlaceholders,\n                        );\n                    },\n                );\n            }\n        }\n    }\n}\n\nfn is_len_call(expr: &Expr<'_>, var: Symbol) -> bool {\n    if let ExprKind::MethodCall(method, recv, [], _) = expr.kind\n        && method.ident.name == sym::len\n        && let ExprKind::Path(QPath::Resolved(_, path)) = recv.kind\n        && path.segments.len() == 1\n        && path.segments[0].ident.name == var\n    {\n        return true;\n    }\n\n    false\n}\n\nfn is_end_eq_array_len<'tcx>(\n    cx: &LateContext<'tcx>,\n    end: &Expr<'_>,\n    limits: ast::RangeLimits,\n    indexed_ty: Ty<'tcx>,\n) -> bool {\n    if let ExprKind::Lit(lit) = end.kind\n        && let ast::LitKind::Int(end_int, _) = lit.node\n        && let ty::Array(_, arr_len_const) = indexed_ty.kind()\n        && let Some(arr_len) = arr_len_const.try_to_target_usize(cx.tcx)\n    {\n        return match limits {\n            ast::RangeLimits::Closed => end_int.get() + 1 >= arr_len.into(),\n            ast::RangeLimits::HalfOpen => end_int.get() >= arr_len.into(),\n        };\n    }\n\n    false\n}\n\n#[expect(clippy::struct_excessive_bools)]\nstruct VarVisitor<'a, 'tcx> {\n    /// context reference\n    cx: &'a LateContext<'tcx>,\n    /// var name to look for as index\n    var: HirId,\n    /// indexed variables that are used mutably\n    indexed_mut: FxHashSet<Symbol>,\n    /// indirectly indexed variables (`v[(i + 4) % N]`), the extend is `None` for global\n    indexed_indirectly: FxHashMap<Symbol, Option<region::Scope>>,\n    /// indirectly indexed literals, like `[1, 2, 3][(i + 4) % N]`\n    unnamed_indexed_indirectly: bool,\n    /// subset of `indexed` of vars that are indexed directly: `v[i]`\n    /// this will not contain cases like `v[calc_index(i)]` or `v[(i + 4) % N]`\n    indexed_directly: FxIndexMap<Symbol, (Option<region::Scope>, Ty<'tcx>)>,\n    /// directly indexed literals, like `[1, 2, 3][i]`\n    unnamed_indexed_directly: bool,\n    /// Any names that are used outside an index operation.\n    /// Used to detect things like `&mut vec` used together with `vec[i]`\n    referenced: FxHashSet<Symbol>,\n    /// has the loop variable been used in expressions other than the index of\n    /// an index op?\n    nonindex: bool,\n    /// Whether we are inside the `$` in `&mut $` or `$ = foo` or `$.bar`, where bar\n    /// takes `&mut self`\n    prefer_mutable: bool,\n}\n\nimpl<'tcx> VarVisitor<'_, 'tcx> {\n    fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) -> bool {\n        let mut used_cnt = 0;\n        // It is `true` if all indices are direct\n        let mut index_used_directly = true;\n\n        // Handle initial index\n        if is_local_used(self.cx, idx, self.var) {\n            used_cnt += 1;\n            index_used_directly &= matches!(idx.kind, ExprKind::Path(_));\n        }\n        // Handle nested indices\n        let seqexpr = peel_hir_expr_while(seqexpr, |e| {\n            if let ExprKind::Index(e, idx, _) = e.kind {\n                if is_local_used(self.cx, idx, self.var) {\n                    used_cnt += 1;\n                    index_used_directly &= matches!(idx.kind, ExprKind::Path(_));\n                }\n                Some(e)\n            } else {\n                None\n            }\n        });\n\n        match used_cnt {\n            0 => return true,\n            n if n > 1 => self.nonindex = true, // Optimize code like `a[i][i]`\n            _ => {},\n        }\n\n        if let ExprKind::Path(ref seqpath) = seqexpr.kind\n            // the indexed container is referenced by a name\n            && let QPath::Resolved(None, seqvar) = *seqpath\n            && seqvar.segments.len() == 1\n        {\n            if self.prefer_mutable {\n                self.indexed_mut.insert(seqvar.segments[0].ident.name);\n            }\n            let res = self.cx.qpath_res(seqpath, seqexpr.hir_id);\n            match res {\n                Res::Local(hir_id) => {\n                    let parent_def_id = self.cx.tcx.hir_get_parent_item(expr.hir_id);\n                    let extent = self\n                        .cx\n                        .tcx\n                        .region_scope_tree(parent_def_id)\n                        .var_scope(hir_id.local_id)\n                        .unwrap();\n                    if index_used_directly {\n                        self.indexed_directly.insert(\n                            seqvar.segments[0].ident.name,\n                            (Some(extent), self.cx.typeck_results().node_type(seqexpr.hir_id)),\n                        );\n                    } else {\n                        self.indexed_indirectly\n                            .insert(seqvar.segments[0].ident.name, Some(extent));\n                    }\n                    return false; // no need to walk further *on the variable*\n                },\n                Res::Def(DefKind::Static { .. } | DefKind::Const { .. }, ..) => {\n                    if index_used_directly {\n                        self.indexed_directly.insert(\n                            seqvar.segments[0].ident.name,\n                            (None, self.cx.typeck_results().node_type(seqexpr.hir_id)),\n                        );\n                    } else {\n                        self.indexed_indirectly.insert(seqvar.segments[0].ident.name, None);\n                    }\n                    return false; // no need to walk further *on the variable*\n                },\n                _ => (),\n            }\n        } else if let ExprKind::Repeat(..) | ExprKind::Array(..) = seqexpr.kind {\n            if index_used_directly {\n                self.unnamed_indexed_directly = true;\n            } else {\n                self.unnamed_indexed_indirectly = true;\n            }\n            return false;\n        }\n        true\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for VarVisitor<'_, 'tcx> {\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        if let ExprKind::MethodCall(meth, args_0, [args_1, ..], _) = &expr.kind\n            && let Some(trait_id) = self\n                .cx\n                .typeck_results()\n                .type_dependent_def_id(expr.hir_id)\n                .and_then(|def_id| self.cx.tcx.trait_of_assoc(def_id))\n            && ((meth.ident.name == sym::index && self.cx.tcx.lang_items().index_trait() == Some(trait_id))\n                || (meth.ident.name == sym::index_mut && self.cx.tcx.lang_items().index_mut_trait() == Some(trait_id)))\n            && !self.check(args_1, args_0, expr)\n        {\n            return;\n        }\n\n        if let ExprKind::Index(seqexpr, idx, _) = expr.kind\n            // an index op\n            && !self.check(idx, seqexpr, expr)\n        {\n            return;\n        }\n\n        if let ExprKind::Path(QPath::Resolved(None, path)) = expr.kind\n            // directly using a variable\n            && let Res::Local(local_id) = path.res\n        {\n            if local_id == self.var {\n                self.nonindex = true;\n            } else {\n                // not the correct variable, but still a variable\n                self.referenced.insert(path.segments[0].ident.name);\n            }\n        }\n\n        let old = self.prefer_mutable;\n        match expr.kind {\n            ExprKind::AssignOp(_, lhs, rhs) | ExprKind::Assign(lhs, rhs, _) => {\n                self.prefer_mutable = true;\n                self.visit_expr(lhs);\n                self.prefer_mutable = false;\n                self.visit_expr(rhs);\n            },\n            ExprKind::AddrOf(BorrowKind::Ref, mutbl, expr) => {\n                if mutbl == Mutability::Mut {\n                    self.prefer_mutable = true;\n                }\n                self.visit_expr(expr);\n            },\n            ExprKind::Call(f, args) => {\n                self.visit_expr(f);\n                for expr in args {\n                    let ty = self.cx.typeck_results().expr_ty_adjusted(expr);\n                    self.prefer_mutable = false;\n                    if let ty::Ref(_, _, mutbl) = *ty.kind()\n                        && mutbl == Mutability::Mut\n                    {\n                        self.prefer_mutable = true;\n                    }\n                    self.visit_expr(expr);\n                }\n            },\n            ExprKind::MethodCall(_, receiver, args, _) => {\n                let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();\n                for (ty, expr) in iter::zip(\n                    self.cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder(),\n                    iter::once(receiver).chain(args.iter()),\n                ) {\n                    self.prefer_mutable = false;\n                    if let ty::Ref(_, _, mutbl) = *ty.kind()\n                        && mutbl == Mutability::Mut\n                    {\n                        self.prefer_mutable = true;\n                    }\n                    self.visit_expr(expr);\n                }\n            },\n            ExprKind::Closure(&Closure { body, .. }) => {\n                let body = self.cx.tcx.hir_body(body);\n                self.visit_expr(body.value);\n            },\n            _ => walk_expr(self, expr),\n        }\n        self.prefer_mutable = old;\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/never_loop.rs",
    "content": "use super::NEVER_LOOP;\nuse super::utils::make_iterator_snippet;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::ForLoop;\nuse clippy_utils::macros::root_macro_call_first_node;\nuse clippy_utils::source::{snippet, snippet_with_context};\nuse clippy_utils::visitors::{Descend, for_each_expr_without_closures};\nuse clippy_utils::{contains_return, sym};\nuse rustc_ast::BinOpKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{\n    Block, Closure, Destination, Expr, ExprKind, HirId, InlineAsm, InlineAsmOperand, Node, Pat, Stmt, StmtKind,\n    StructTailExpr,\n};\nuse rustc_lint::LateContext;\nuse rustc_span::{BytePos, Span};\nuse std::iter::once;\nuse std::ops::ControlFlow;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    block: &Block<'tcx>,\n    loop_id: HirId,\n    span: Span,\n    for_loop: Option<&ForLoop<'_>>,\n) {\n    match never_loop_block(cx, block, &mut Vec::new(), loop_id) {\n        NeverLoopResult::Diverging {\n            ref break_spans,\n            ref never_spans,\n        } => {\n            span_lint_and_then(cx, NEVER_LOOP, span, \"this loop never actually loops\", |diag| {\n                if let Some(ForLoop {\n                    arg: iterator,\n                    pat,\n                    span: for_span,\n                    label,\n                    ..\n                }) = for_loop\n                {\n                    // If the block contains a break or continue, or if the loop has a label, `MachineApplicable` is not\n                    // appropriate.\n                    let mut app = if !contains_any_break_or_continue(block) && label.is_none() {\n                        Applicability::MachineApplicable\n                    } else {\n                        Applicability::Unspecified\n                    };\n\n                    if !never_spans.is_empty() {\n                        app = Applicability::HasPlaceholders;\n                    }\n\n                    let mut suggestions = vec![(\n                        for_span.with_hi(iterator.span.hi()),\n                        for_to_if_let_sugg(cx, iterator, pat),\n                    )];\n                    // Make sure to clear up the diverging sites when we remove a loopp.\n                    suggestions.extend(break_spans.iter().map(|span| (*span, String::new())));\n                    diag.multipart_suggestion(\n                        \"if you need the first element of the iterator, try writing\",\n                        suggestions,\n                        app,\n                    );\n\n                    for span in never_spans {\n                        diag.span_help(\n                            *span,\n                            \"this code is unreachable. Consider moving the reachable parts out\",\n                        );\n                    }\n                }\n            });\n        },\n        NeverLoopResult::MayContinueMainLoop | NeverLoopResult::Normal => (),\n    }\n}\n\npub(super) fn check_iterator_reduction<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    recv: &'tcx Expr<'tcx>,\n    closure: &'tcx Closure<'tcx>,\n) {\n    let closure_body = cx.tcx.hir_body(closure.body).value;\n    let body_ty = cx.typeck_results().expr_ty(closure_body);\n    if body_ty.is_never() && !contains_return(closure_body) {\n        span_lint_and_then(\n            cx,\n            NEVER_LOOP,\n            expr.span,\n            \"this iterator reduction never loops (closure always diverges)\",\n            |diag| {\n                let mut app = Applicability::HasPlaceholders;\n                let recv_snip = snippet_with_context(cx, recv.span, expr.span.ctxt(), \"<iter>\", &mut app).0;\n                diag.note(\"if you only need one element, `if let Some(x) = iter.next()` is clearer\");\n                let sugg = format!(\"if let Some(x) = {recv_snip}.next() {{ ... }}\");\n                diag.span_suggestion_verbose(expr.span, \"consider this pattern\", sugg, app);\n            },\n        );\n    }\n}\n\nfn contains_any_break_or_continue(block: &Block<'_>) -> bool {\n    for_each_expr_without_closures(block, |e| match e.kind {\n        ExprKind::Break(..) | ExprKind::Continue(..) => ControlFlow::Break(()),\n        ExprKind::InlineAsm(asm) if contains_label(asm) => ControlFlow::Break(()),\n        ExprKind::Loop(..) => ControlFlow::Continue(Descend::No),\n        _ => ControlFlow::Continue(Descend::Yes),\n    })\n    .is_some()\n}\n\nfn contains_label(asm: &InlineAsm<'_>) -> bool {\n    asm.operands\n        .iter()\n        .any(|(op, _span)| matches!(op, InlineAsmOperand::Label { .. }))\n}\n\n/// The `never_loop` analysis keeps track of three things:\n///\n/// * Has any (reachable) code path hit a `continue` of the main loop?\n/// * Is the current code path diverging (that is, the next expression is not reachable)\n/// * For each block label `'a` inside the main loop, has any (reachable) code path encountered a\n///   `break 'a`?\n///\n/// The first two bits of information are in this enum, and the last part is in the\n/// `local_labels` variable, which contains a list of `(block_id, reachable)` pairs ordered by\n/// scope.\n#[derive(Clone, Debug)]\nenum NeverLoopResult {\n    /// A continue may occur for the main loop.\n    MayContinueMainLoop,\n    /// We have not encountered any main loop continue,\n    /// but we are diverging (subsequent control flow is not reachable)\n    Diverging {\n        break_spans: Vec<Span>,\n        never_spans: Vec<Span>,\n    },\n    /// We have not encountered any main loop continue,\n    /// and subsequent control flow is (possibly) reachable\n    Normal,\n}\n\n#[must_use]\nfn absorb_break(arg: &NeverLoopResult) -> NeverLoopResult {\n    match arg {\n        NeverLoopResult::Diverging { .. } | NeverLoopResult::Normal => NeverLoopResult::Normal,\n        NeverLoopResult::MayContinueMainLoop => NeverLoopResult::MayContinueMainLoop,\n    }\n}\n\n// Combine two results for parts that are called in order.\n#[must_use]\nfn combine_seq(first: NeverLoopResult, second: impl FnOnce() -> NeverLoopResult) -> NeverLoopResult {\n    match first {\n        NeverLoopResult::Diverging { .. } | NeverLoopResult::MayContinueMainLoop => first,\n        NeverLoopResult::Normal => second(),\n    }\n}\n\n// Combine an iterator of results for parts that are called in order.\n#[must_use]\nfn combine_seq_many(iter: impl IntoIterator<Item = NeverLoopResult>) -> NeverLoopResult {\n    for e in iter {\n        if let NeverLoopResult::Diverging { .. } | NeverLoopResult::MayContinueMainLoop = e {\n            return e;\n        }\n    }\n    NeverLoopResult::Normal\n}\n\n// Combine two results where only one of the part may have been executed.\n#[must_use]\nfn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult) -> NeverLoopResult {\n    match (b1, b2) {\n        (NeverLoopResult::MayContinueMainLoop, _) | (_, NeverLoopResult::MayContinueMainLoop) => {\n            NeverLoopResult::MayContinueMainLoop\n        },\n        (NeverLoopResult::Normal, _) | (_, NeverLoopResult::Normal) => NeverLoopResult::Normal,\n        (\n            NeverLoopResult::Diverging {\n                break_spans: mut break_spans1,\n                never_spans: mut never_spans1,\n            },\n            NeverLoopResult::Diverging {\n                break_spans: mut break_spans2,\n                never_spans: mut never_spans2,\n            },\n        ) => {\n            break_spans1.append(&mut break_spans2);\n            never_spans1.append(&mut never_spans2);\n            NeverLoopResult::Diverging {\n                break_spans: break_spans1,\n                never_spans: never_spans1,\n            }\n        },\n    }\n}\n\nfn never_loop_block<'tcx>(\n    cx: &LateContext<'tcx>,\n    block: &Block<'tcx>,\n    local_labels: &mut Vec<(HirId, bool)>,\n    main_loop_id: HirId,\n) -> NeverLoopResult {\n    let iter = block\n        .stmts\n        .iter()\n        .filter_map(stmt_to_expr)\n        .chain(block.expr.map(|expr| (expr, None)));\n    combine_seq_many(iter.map(|(e, els)| {\n        let e = never_loop_expr(cx, e, local_labels, main_loop_id);\n        // els is an else block in a let...else binding\n        els.map_or(e.clone(), |els| {\n            combine_seq(e, || match never_loop_block(cx, els, local_labels, main_loop_id) {\n                // Returning MayContinueMainLoop here means that\n                // we will not evaluate the rest of the body\n                NeverLoopResult::MayContinueMainLoop => NeverLoopResult::MayContinueMainLoop,\n                // An else block always diverges, so the Normal case should not happen,\n                // but the analysis is approximate so it might return Normal anyway.\n                // Returning Normal here says that nothing more happens on the main path\n                NeverLoopResult::Diverging { .. } | NeverLoopResult::Normal => NeverLoopResult::Normal,\n            })\n        })\n    }))\n}\n\nfn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'tcx Block<'tcx>>)> {\n    match stmt.kind {\n        StmtKind::Semi(e) | StmtKind::Expr(e) => Some((e, None)),\n        // add the let...else expression (if present)\n        StmtKind::Let(local) => local.init.map(|init| (init, local.els)),\n        StmtKind::Item(..) => None,\n    }\n}\n\nfn stmt_source_span(stmt: &Stmt<'_>) -> Span {\n    let call_span = stmt.span.source_callsite();\n    // if it is a macro call, the span will be missing the trailing semicolon\n    if stmt.span == call_span {\n        return call_span;\n    }\n\n    // An expression without a trailing semi-colon (must have unit type).\n    if let StmtKind::Expr(..) = stmt.kind {\n        return call_span;\n    }\n\n    call_span.with_hi(call_span.hi() + BytePos(1))\n}\n\n/// Returns a Vec of all the individual spans after the highlighted expression in a block\nfn all_spans_after_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> Vec<Span> {\n    if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id) {\n        if let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id) {\n            return block\n                .stmts\n                .iter()\n                .skip_while(|inner| inner.hir_id != stmt.hir_id)\n                .map(stmt_source_span)\n                .chain(block.expr.map(|e| e.span))\n                .collect();\n        }\n\n        return vec![stmt.span];\n    } else if let Node::Block(_) = cx.tcx.parent_hir_node(expr.hir_id) {\n        return vec![expr.span];\n    }\n\n    vec![]\n}\n\nfn is_label_for_block(cx: &LateContext<'_>, dest: &Destination) -> bool {\n    dest.target_id\n        .is_ok_and(|hir_id| matches!(cx.tcx.hir_node(hir_id), Node::Block(_)))\n}\n\n#[expect(clippy::too_many_lines)]\nfn never_loop_expr<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'tcx>,\n    local_labels: &mut Vec<(HirId, bool)>,\n    main_loop_id: HirId,\n) -> NeverLoopResult {\n    let result = match expr.kind {\n        ExprKind::Unary(_, e)\n        | ExprKind::Cast(e, _)\n        | ExprKind::Type(e, _)\n        | ExprKind::Field(e, _)\n        | ExprKind::AddrOf(_, _, e)\n        | ExprKind::Repeat(e, _)\n        | ExprKind::DropTemps(e)\n        | ExprKind::UnsafeBinderCast(_, e, _) => never_loop_expr(cx, e, local_labels, main_loop_id),\n        ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, local_labels, main_loop_id),\n        ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, es.iter(), local_labels, main_loop_id),\n        ExprKind::Use(expr, _) => never_loop_expr(cx, expr, local_labels, main_loop_id),\n        ExprKind::MethodCall(_, receiver, es, _) => {\n            never_loop_expr_all(cx, once(receiver).chain(es.iter()), local_labels, main_loop_id)\n        },\n        ExprKind::Struct(_, fields, base) => {\n            let fields = never_loop_expr_all(cx, fields.iter().map(|f| f.expr), local_labels, main_loop_id);\n            if let StructTailExpr::Base(base) = base {\n                combine_seq(fields, || never_loop_expr(cx, base, local_labels, main_loop_id))\n            } else {\n                fields\n            }\n        },\n        ExprKind::Call(e, es) => never_loop_expr_all(cx, once(e).chain(es.iter()), local_labels, main_loop_id),\n        ExprKind::Binary(op, e1, _) if matches!(op.node, BinOpKind::And | BinOpKind::Or) => {\n            never_loop_expr(cx, e1, local_labels, main_loop_id)\n        },\n        ExprKind::Binary(_, e1, e2)\n        | ExprKind::Assign(e1, e2, _)\n        | ExprKind::AssignOp(_, e1, e2)\n        | ExprKind::Index(e1, e2, _) => never_loop_expr_all(cx, [e1, e2].iter().copied(), local_labels, main_loop_id),\n        ExprKind::Loop(b, _, _, _) => {\n            // We don't attempt to track reachability after a loop,\n            // just assume there may have been a break somewhere\n            absorb_break(&never_loop_block(cx, b, local_labels, main_loop_id))\n        },\n        ExprKind::If(e, e2, e3) => {\n            let e1 = never_loop_expr(cx, e, local_labels, main_loop_id);\n            combine_seq(e1, || {\n                let e2 = never_loop_expr(cx, e2, local_labels, main_loop_id);\n                let e3 = e3.as_ref().map_or(NeverLoopResult::Normal, |e| {\n                    never_loop_expr(cx, e, local_labels, main_loop_id)\n                });\n                combine_branches(e2, e3)\n            })\n        },\n        ExprKind::Match(e, arms, _) => {\n            let e = never_loop_expr(cx, e, local_labels, main_loop_id);\n            combine_seq(e, || {\n                arms.iter().fold(\n                    NeverLoopResult::Diverging {\n                        break_spans: vec![],\n                        never_spans: vec![],\n                    },\n                    |a, b| combine_branches(a, never_loop_expr(cx, b.body, local_labels, main_loop_id)),\n                )\n            })\n        },\n        ExprKind::Block(b, _) => {\n            if b.targeted_by_break {\n                local_labels.push((b.hir_id, false));\n            }\n            let ret = never_loop_block(cx, b, local_labels, main_loop_id);\n            let jumped_to = b.targeted_by_break && local_labels.pop().unwrap().1;\n            match ret {\n                NeverLoopResult::Diverging { .. } if jumped_to => NeverLoopResult::Normal,\n                _ => ret,\n            }\n        },\n        ExprKind::Continue(d) => {\n            let id = d\n                .target_id\n                .expect(\"target ID can only be missing in the presence of compilation errors\");\n            if id == main_loop_id {\n                NeverLoopResult::MayContinueMainLoop\n            } else {\n                NeverLoopResult::Diverging {\n                    break_spans: all_spans_after_expr(cx, expr),\n                    never_spans: vec![],\n                }\n            }\n        },\n        ExprKind::Ret(e) => {\n            let first = e.as_ref().map_or(NeverLoopResult::Normal, |e| {\n                never_loop_expr(cx, e, local_labels, main_loop_id)\n            });\n            combine_seq(first, || {\n                // checks if break targets a block instead of a loop\n                mark_block_as_reachable(expr, local_labels);\n                NeverLoopResult::Diverging {\n                    break_spans: vec![],\n                    never_spans: vec![],\n                }\n            })\n        },\n        ExprKind::Break(dest, e) => {\n            let first = e.as_ref().map_or(NeverLoopResult::Normal, |e| {\n                never_loop_expr(cx, e, local_labels, main_loop_id)\n            });\n            combine_seq(first, || {\n                // checks if break targets a block instead of a loop\n                mark_block_as_reachable(expr, local_labels);\n                NeverLoopResult::Diverging {\n                    break_spans: if is_label_for_block(cx, &dest) {\n                        vec![]\n                    } else {\n                        all_spans_after_expr(cx, expr)\n                    },\n                    never_spans: vec![],\n                }\n            })\n        },\n        ExprKind::Become(e) => combine_seq(never_loop_expr(cx, e, local_labels, main_loop_id), || {\n            NeverLoopResult::Diverging {\n                break_spans: vec![],\n                never_spans: vec![],\n            }\n        }),\n        ExprKind::InlineAsm(asm) => combine_seq_many(asm.operands.iter().map(|(o, _)| match o {\n            InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {\n                never_loop_expr(cx, expr, local_labels, main_loop_id)\n            },\n            InlineAsmOperand::Out { expr, .. } => {\n                never_loop_expr_all(cx, expr.iter().copied(), local_labels, main_loop_id)\n            },\n            InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => never_loop_expr_all(\n                cx,\n                once(*in_expr).chain(out_expr.iter().copied()),\n                local_labels,\n                main_loop_id,\n            ),\n            InlineAsmOperand::Const { .. } | InlineAsmOperand::SymFn { .. } | InlineAsmOperand::SymStatic { .. } => {\n                NeverLoopResult::Normal\n            },\n            InlineAsmOperand::Label { block } =>\n            // We do not know whether the label will be executed or not, so `Diverging` must be\n            // downgraded to `Normal`.\n            {\n                match never_loop_block(cx, block, local_labels, main_loop_id) {\n                    NeverLoopResult::Diverging { .. } => NeverLoopResult::Normal,\n                    result => result,\n                }\n            },\n        })),\n        ExprKind::OffsetOf(_, _)\n        | ExprKind::Yield(_, _)\n        | ExprKind::Closure { .. }\n        | ExprKind::Path(_)\n        | ExprKind::ConstBlock(_)\n        | ExprKind::Lit(_)\n        | ExprKind::Err(_) => NeverLoopResult::Normal,\n    };\n    let result = combine_seq(result, || {\n        if cx.typeck_results().expr_ty(expr).is_never() {\n            NeverLoopResult::Diverging {\n                break_spans: vec![],\n                never_spans: all_spans_after_expr(cx, expr),\n            }\n        } else {\n            NeverLoopResult::Normal\n        }\n    });\n    if let NeverLoopResult::Diverging { .. } = result\n        && let Some(macro_call) = root_macro_call_first_node(cx, expr)\n        && let Some(sym::todo_macro) = cx.tcx.get_diagnostic_name(macro_call.def_id)\n    {\n        // We return MayContinueMainLoop here because we treat `todo!()`\n        // as potentially containing any code, including a continue of the main loop.\n        // This effectively silences the lint whenever a loop contains this macro anywhere.\n        NeverLoopResult::MayContinueMainLoop\n    } else {\n        result\n    }\n}\n\nfn never_loop_expr_all<'tcx, T: Iterator<Item = &'tcx Expr<'tcx>>>(\n    cx: &LateContext<'tcx>,\n    es: T,\n    local_labels: &mut Vec<(HirId, bool)>,\n    main_loop_id: HirId,\n) -> NeverLoopResult {\n    combine_seq_many(es.map(|e| never_loop_expr(cx, e, local_labels, main_loop_id)))\n}\n\nfn for_to_if_let_sugg(cx: &LateContext<'_>, iterator: &Expr<'_>, pat: &Pat<'_>) -> String {\n    let pat_snippet = snippet(cx, pat.span, \"_\");\n    let iter_snippet = make_iterator_snippet(cx, iterator, &mut Applicability::Unspecified);\n\n    format!(\"if let Some({pat_snippet}) = {iter_snippet}.next()\")\n}\n\nfn mark_block_as_reachable(expr: &Expr<'_>, local_labels: &mut [(HirId, bool)]) {\n    if let ExprKind::Break(Destination { target_id: Ok(t), .. }, _) = expr.kind\n        && let Some((_, reachable)) = local_labels.iter_mut().find(|(label, _)| *label == t)\n    {\n        *reachable = true;\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/same_item_push.rs",
    "content": "use super::SAME_ITEM_PUSH;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{msrvs, std_or_core, sym};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind, Stmt, StmtKind};\nuse rustc_lint::LateContext;\nuse rustc_span::SyntaxContext;\n\n/// Detects for loop pushing the same item into a Vec\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    _: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    _: &'tcx Expr<'_>,\n    msrv: Msrv,\n) {\n    fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>, ctxt: SyntaxContext, msrv: Msrv) {\n        let mut app = Applicability::Unspecified;\n        let vec_str = snippet_with_context(cx, vec.span, ctxt, \"\", &mut app).0;\n        let item_str = snippet_with_context(cx, pushed_item.span, ctxt, \"\", &mut app).0;\n\n        let secondary_help = if msrv.meets(cx, msrvs::REPEAT_N)\n            && let Some(std_or_core) = std_or_core(cx)\n        {\n            format!(\"or `{vec_str}.extend({std_or_core}::iter::repeat_n({item_str}, SIZE))`\")\n        } else {\n            format!(\"or `{vec_str}.resize(NEW_SIZE, {item_str})`\")\n        };\n\n        span_lint_and_then(\n            cx,\n            SAME_ITEM_PUSH,\n            vec.span,\n            \"it looks like the same item is being pushed into this `Vec`\",\n            |diag| {\n                diag.help(format!(\"consider using `vec![{item_str};SIZE]`\"))\n                    .help(secondary_help);\n            },\n        );\n    }\n\n    if !matches!(pat.kind, PatKind::Wild) {\n        return;\n    }\n\n    // Determine whether it is safe to lint the body\n    let mut same_item_push_visitor = SameItemPushVisitor::new(cx);\n    walk_expr(&mut same_item_push_visitor, body);\n    if same_item_push_visitor.should_lint()\n        && let Some((vec, pushed_item, ctxt)) = same_item_push_visitor.vec_push\n        && let vec_ty = cx.typeck_results().expr_ty(vec)\n        && let ty = vec_ty.walk().nth(1).unwrap().expect_ty()\n        && cx\n            .tcx\n            .lang_items()\n            .clone_trait()\n            .is_some_and(|id| implements_trait(cx, ty, id, &[]))\n    {\n        // Make sure that the push does not involve possibly mutating values\n        match pushed_item.kind {\n            ExprKind::Path(ref qpath) => {\n                match cx.qpath_res(qpath, pushed_item.hir_id) {\n                    // immutable bindings that are initialized with literal or constant\n                    Res::Local(hir_id) => {\n                        let node = cx.tcx.hir_node(hir_id);\n                        if let Node::Pat(pat) = node\n                            && let PatKind::Binding(bind_ann, ..) = pat.kind\n                            && !matches!(bind_ann, BindingMode(_, Mutability::Mut))\n                            && let Node::LetStmt(parent_let_expr) = cx.tcx.parent_hir_node(hir_id)\n                            && let Some(init) = parent_let_expr.init\n                        {\n                            match init.kind {\n                                // immutable bindings that are initialized with literal\n                                ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item, ctxt, msrv),\n                                // immutable bindings that are initialized with constant\n                                ExprKind::Path(ref path) => {\n                                    if let Res::Def(DefKind::Const { .. }, ..) = cx.qpath_res(path, init.hir_id) {\n                                        emit_lint(cx, vec, pushed_item, ctxt, msrv);\n                                    }\n                                },\n                                _ => {},\n                            }\n                        }\n                    },\n                    // constant\n                    Res::Def(DefKind::Const { .. }, ..) => emit_lint(cx, vec, pushed_item, ctxt, msrv),\n                    _ => {},\n                }\n            },\n            ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item, ctxt, msrv),\n            _ => {},\n        }\n    }\n}\n\n// Scans the body of the for loop and determines whether lint should be given\nstruct SameItemPushVisitor<'a, 'tcx> {\n    non_deterministic_expr: bool,\n    multiple_pushes: bool,\n    // this field holds the last vec push operation visited, which should be the only push seen\n    vec_push: Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, SyntaxContext)>,\n    cx: &'a LateContext<'tcx>,\n    used_locals: FxHashSet<HirId>,\n}\n\nimpl<'a, 'tcx> SameItemPushVisitor<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>) -> Self {\n        Self {\n            non_deterministic_expr: false,\n            multiple_pushes: false,\n            vec_push: None,\n            cx,\n            used_locals: FxHashSet::default(),\n        }\n    }\n\n    fn should_lint(&self) -> bool {\n        if !self.non_deterministic_expr\n            && !self.multiple_pushes\n            && let Some((vec, _, _)) = self.vec_push\n            && let Some(hir_id) = vec.res_local_id()\n        {\n            !self.used_locals.contains(&hir_id)\n        } else {\n            false\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for SameItemPushVisitor<'_, 'tcx> {\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        match &expr.kind {\n            // Non-determinism may occur ... don't give a lint\n            ExprKind::Loop(..) | ExprKind::Match(..) | ExprKind::If(..) => self.non_deterministic_expr = true,\n            ExprKind::Block(block, _) => self.visit_block(block),\n            _ => {\n                if let Some(hir_id) = expr.res_local_id() {\n                    self.used_locals.insert(hir_id);\n                }\n                walk_expr(self, expr);\n            },\n        }\n    }\n\n    fn visit_block(&mut self, b: &'tcx Block<'_>) {\n        for stmt in b.stmts {\n            self.visit_stmt(stmt);\n        }\n    }\n\n    fn visit_stmt(&mut self, s: &'tcx Stmt<'_>) {\n        let vec_push_option = get_vec_push(self.cx, s);\n        if vec_push_option.is_none() {\n            // Current statement is not a push so visit inside\n            match &s.kind {\n                StmtKind::Expr(expr) | StmtKind::Semi(expr) => self.visit_expr(expr),\n                _ => {},\n            }\n        }\n        // Current statement is a push ...check whether another\n        // push had been previously done\n        else if self.vec_push.is_none() {\n            self.vec_push = vec_push_option;\n        } else {\n            // There are multiple pushes ... don't lint\n            self.multiple_pushes = true;\n        }\n    }\n}\n\n// Given some statement, determine if that statement is a push on a Vec. If it is, return\n// the Vec being pushed into and the item being pushed\nfn get_vec_push<'tcx>(\n    cx: &LateContext<'tcx>,\n    stmt: &'tcx Stmt<'_>,\n) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, SyntaxContext)> {\n    if let StmtKind::Semi(semi_stmt) = &stmt.kind\n            // Extract method being called and figure out the parameters for the method call\n            && let ExprKind::MethodCall(path, self_expr, [pushed_item], _) = &semi_stmt.kind\n            // Check that the method being called is push() on a Vec\n            && path.ident.name == sym::push\n            && cx.typeck_results().expr_ty(self_expr).is_diag_item(cx, sym::Vec)\n    {\n        return Some((self_expr, pushed_item, semi_stmt.span.ctxt()));\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/single_element_loop.rs",
    "content": "use super::SINGLE_ELEMENT_LOOP;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{indent_of, snippet, snippet_with_applicability};\nuse clippy_utils::visitors::contains_break_or_continue;\nuse rustc_ast::Mutability;\nuse rustc_ast::util::parser::ExprPrecedence;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind, is_range_literal};\nuse rustc_lint::LateContext;\nuse rustc_span::edition::Edition;\nuse rustc_span::sym;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    arg: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n    expr: &'tcx Expr<'_>,\n) {\n    let (arg_expression, prefix) = match arg.kind {\n        ExprKind::AddrOf(\n            BorrowKind::Ref,\n            Mutability::Not,\n            Expr {\n                kind: ExprKind::Array([arg]),\n                ..\n            },\n        ) => (arg, \"&\"),\n        ExprKind::AddrOf(\n            BorrowKind::Ref,\n            Mutability::Mut,\n            Expr {\n                kind: ExprKind::Array([arg]),\n                ..\n            },\n        ) => (arg, \"&mut \"),\n        ExprKind::MethodCall(\n            method,\n            Expr {\n                kind: ExprKind::Array([arg]),\n                ..\n            },\n            [],\n            _,\n        ) if method.ident.name == sym::iter => (arg, \"&\"),\n        ExprKind::MethodCall(\n            method,\n            Expr {\n                kind: ExprKind::Array([arg]),\n                ..\n            },\n            [],\n            _,\n        ) if method.ident.name == sym::iter_mut => (arg, \"&mut \"),\n        ExprKind::MethodCall(\n            method,\n            Expr {\n                kind: ExprKind::Array([arg]),\n                ..\n            },\n            [],\n            _,\n        ) if method.ident.name == sym::into_iter => (arg, \"\"),\n        // Only check for arrays edition 2021 or later, as this case will trigger a compiler error otherwise.\n        ExprKind::Array([arg]) if cx.tcx.sess.edition() >= Edition::Edition2021 => (arg, \"\"),\n        _ => return,\n    };\n    if let ExprKind::Block(block, _) = body.kind\n        && !block.stmts.is_empty()\n        && !contains_break_or_continue(body)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let mut pat_snip = snippet_with_applicability(cx, pat.span, \"..\", &mut applicability);\n        if matches!(pat.kind, PatKind::Or(..)) {\n            pat_snip = format!(\"({pat_snip})\").into();\n        }\n        let mut arg_snip = snippet_with_applicability(cx, arg_expression.span, \"..\", &mut applicability);\n        let mut block_str = snippet_with_applicability(cx, block.span, \"..\", &mut applicability).into_owned();\n        block_str.remove(0);\n        block_str.pop();\n        let indent = \" \".repeat(indent_of(cx, block.stmts[0].span).unwrap_or(0));\n\n        // Reference iterator from `&(mut) []` or `[].iter(_mut)()`.\n        if !prefix.is_empty()\n            && (\n                // Precedence of internal expression is less than or equal to precedence of `&expr`.\n                cx.precedence(arg_expression) <= ExprPrecedence::Prefix || is_range_literal(arg_expression)\n            )\n        {\n            arg_snip = format!(\"({arg_snip})\").into();\n        }\n\n        if clippy_utils::higher::Range::hir(cx, arg_expression).is_some() {\n            let range_expr = snippet(cx, arg_expression.span, \"?\").to_string();\n\n            let sugg = snippet(cx, arg_expression.span, \"..\");\n            span_lint_and_sugg(\n                cx,\n                SINGLE_ELEMENT_LOOP,\n                arg.span,\n                format!(\"this loops only once with `{pat_snip}` being `{range_expr}`\"),\n                \"did you mean to iterate over the range instead?\",\n                sugg.to_string(),\n                Applicability::Unspecified,\n            );\n        } else {\n            span_lint_and_sugg(\n                cx,\n                SINGLE_ELEMENT_LOOP,\n                expr.span,\n                \"for loop over a single element\",\n                \"try\",\n                format!(\"{{\\n{indent}let {pat_snip} = {prefix}{arg_snip};{block_str}}}\"),\n                applicability,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/unused_enumerate_index.rs",
    "content": "use super::UNUSED_ENUMERATE_INDEX;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{SpanRangeExt, walk_span_to_context};\nuse clippy_utils::{expr_or_init, pat_is_wild, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Closure, Expr, ExprKind, Pat, PatKind, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, SyntaxContext};\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    iter_expr: &'tcx Expr<'tcx>,\n    pat: &Pat<'tcx>,\n    ty_spans: Option<(Span, Span)>,\n    body: &'tcx Expr<'tcx>,\n) {\n    if let PatKind::Tuple([idx_pat, inner_pat], _) = pat.kind\n        && cx.typeck_results().expr_ty(iter_expr).is_diag_item(cx, sym::Enumerate)\n        && pat_is_wild(cx, &idx_pat.kind, body)\n        && let enumerate_call = expr_or_init(cx, iter_expr)\n        && let ExprKind::MethodCall(_, _, [], enumerate_span) = enumerate_call.kind\n        && let Some(enumerate_id) = cx.typeck_results().type_dependent_def_id(enumerate_call.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::enumerate_method, enumerate_id)\n        && !enumerate_call.span.from_expansion()\n        && !pat.span.from_expansion()\n        && !idx_pat.span.from_expansion()\n        && !inner_pat.span.from_expansion()\n        && let Some(enumerate_range) = enumerate_span.map_range(cx, |_, text, range| {\n            text.get(..range.start)?\n                .ends_with('.')\n                .then_some(range.start - 1..range.end)\n        })\n    {\n        let enumerate_span = Span::new(enumerate_range.start, enumerate_range.end, SyntaxContext::root(), None);\n        span_lint_hir_and_then(\n            cx,\n            UNUSED_ENUMERATE_INDEX,\n            enumerate_call.hir_id,\n            enumerate_span,\n            \"you seem to use `.enumerate()` and immediately discard the index\",\n            |diag| {\n                let mut spans = Vec::with_capacity(5);\n                spans.push((enumerate_span, String::new()));\n                spans.push((pat.span.with_hi(inner_pat.span.lo()), String::new()));\n                spans.push((pat.span.with_lo(inner_pat.span.hi()), String::new()));\n                if let Some((outer, inner)) = ty_spans {\n                    spans.push((outer.with_hi(inner.lo()), String::new()));\n                    spans.push((outer.with_lo(inner.hi()), String::new()));\n                }\n                diag.multipart_suggestion(\n                    \"remove the `.enumerate()` call\",\n                    spans,\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n\npub(super) fn check_method<'tcx>(\n    cx: &LateContext<'tcx>,\n    recv: &'tcx Expr<'tcx>,\n    arg: &'tcx Expr<'tcx>,\n    closure: &'tcx Closure<'tcx>,\n) {\n    let body = cx.tcx.hir_body(closure.body);\n    if let [param] = body.params\n        && let [input] = closure.fn_decl.inputs\n        && !arg.span.from_expansion()\n        && !input.span.from_expansion()\n        && !recv.span.from_expansion()\n        && !param.span.from_expansion()\n    {\n        let ty_spans = if let TyKind::Tup([_, inner]) = input.kind {\n            let Some(inner) = walk_span_to_context(inner.span, SyntaxContext::root()) else {\n                return;\n            };\n            Some((input.span, inner))\n        } else {\n            None\n        };\n        check(cx, recv, param.pat, ty_spans, body.value);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/utils.rs",
    "content": "use clippy_utils::res::MaybeResPath;\nuse clippy_utils::ty::{has_iter_method, implements_trait};\nuse clippy_utils::{get_parent_expr, is_integer_const, sugg};\nuse rustc_ast::ast::{LitIntType, LitKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{Visitor, walk_expr, walk_local};\nuse rustc_hir::{AssignOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, LetStmt, Mutability, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::source_map::Spanned;\nuse rustc_span::symbol::{Symbol, sym};\n\n#[derive(Debug, PartialEq, Eq)]\nenum IncrementVisitorVarState {\n    Initial,  // Not examined yet\n    IncrOnce, // Incremented exactly once, may be a loop counter\n    DontWarn,\n}\n\n/// Scan a for loop for variables that are incremented exactly once and not used after that.\npub(super) struct IncrementVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,                  // context reference\n    states: HirIdMap<IncrementVisitorVarState>, // incremented variables\n    depth: u32,                                 // depth of conditional expressions\n}\n\nimpl<'a, 'tcx> IncrementVisitor<'a, 'tcx> {\n    pub(super) fn new(cx: &'a LateContext<'tcx>) -> Self {\n        Self {\n            cx,\n            states: HirIdMap::default(),\n            depth: 0,\n        }\n    }\n\n    pub(super) fn into_results(self) -> impl Iterator<Item = HirId> {\n        self.states.into_iter().filter_map(|(id, state)| {\n            if state == IncrementVisitorVarState::IncrOnce {\n                Some(id)\n            } else {\n                None\n            }\n        })\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for IncrementVisitor<'_, 'tcx> {\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        // If node is a variable\n        if let Some(def_id) = expr.res_local_id() {\n            if let Some(parent) = get_parent_expr(self.cx, expr) {\n                let state = self.states.entry(def_id).or_insert(IncrementVisitorVarState::Initial);\n                if *state == IncrementVisitorVarState::IncrOnce {\n                    *state = IncrementVisitorVarState::DontWarn;\n                    return;\n                }\n\n                match parent.kind {\n                    ExprKind::AssignOp(op, lhs, rhs) if lhs.hir_id == expr.hir_id => {\n                        *state = if op.node == AssignOpKind::AddAssign\n                            && is_integer_const(self.cx, rhs, 1)\n                            && *state == IncrementVisitorVarState::Initial\n                            && self.depth == 0\n                        {\n                            IncrementVisitorVarState::IncrOnce\n                        } else {\n                            // Assigned some other value or assigned multiple times\n                            IncrementVisitorVarState::DontWarn\n                        };\n                    },\n                    ExprKind::Assign(lhs, _, _) if lhs.hir_id == expr.hir_id => {\n                        *state = IncrementVisitorVarState::DontWarn;\n                    },\n                    ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) => {\n                        *state = IncrementVisitorVarState::DontWarn;\n                    },\n                    _ => (),\n                }\n            }\n\n            walk_expr(self, expr);\n        } else if is_loop(expr) || is_conditional(expr) {\n            self.depth += 1;\n            walk_expr(self, expr);\n            self.depth -= 1;\n        } else if let ExprKind::Continue(_) = expr.kind {\n            // If we see a `continue` block, then we increment depth so that the IncrementVisitor\n            // state will be set to DontWarn if we see the variable being modified anywhere afterwards.\n            self.depth += 1;\n        } else {\n            walk_expr(self, expr);\n        }\n    }\n}\n\nenum InitializeVisitorState<'hir> {\n    Initial,                            // Not examined yet\n    Declared(Symbol, Option<Ty<'hir>>), // Declared but not (yet) initialized\n    Initialized {\n        name: Symbol,\n        ty: Option<Ty<'hir>>,\n        initializer: &'hir Expr<'hir>,\n    },\n    DontWarn,\n}\n\n/// Checks whether a variable is initialized at the start of a loop and not modified\n/// and used after the loop.\npub(super) struct InitializeVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,  // context reference\n    end_expr: &'tcx Expr<'tcx>, // the for loop. Stop scanning here.\n    var_id: HirId,\n    state: InitializeVisitorState<'tcx>,\n    depth: u32, // depth of conditional expressions\n    past_loop: bool,\n}\n\nimpl<'a, 'tcx> InitializeVisitor<'a, 'tcx> {\n    pub(super) fn new(cx: &'a LateContext<'tcx>, end_expr: &'tcx Expr<'tcx>, var_id: HirId) -> Self {\n        Self {\n            cx,\n            end_expr,\n            var_id,\n            state: InitializeVisitorState::Initial,\n            depth: 0,\n            past_loop: false,\n        }\n    }\n\n    pub(super) fn get_result(&self) -> Option<(Symbol, Option<Ty<'tcx>>, &'tcx Expr<'tcx>)> {\n        if let InitializeVisitorState::Initialized { name, ty, initializer } = self.state {\n            Some((name, ty, initializer))\n        } else {\n            None\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for InitializeVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {\n        // Look for declarations of the variable\n        if l.pat.hir_id == self.var_id\n            && let PatKind::Binding(.., ident, _) = l.pat.kind\n        {\n            let ty = l.ty.map(|_| self.cx.typeck_results().pat_ty(l.pat));\n\n            self.state = l.init.map_or(InitializeVisitorState::Declared(ident.name, ty), |init| {\n                InitializeVisitorState::Initialized {\n                    initializer: init,\n                    ty,\n                    name: ident.name,\n                }\n            });\n        }\n\n        walk_local(self, l);\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        if matches!(self.state, InitializeVisitorState::DontWarn) {\n            return;\n        }\n        if expr.hir_id == self.end_expr.hir_id {\n            self.past_loop = true;\n            return;\n        }\n        // No need to visit expressions before the variable is\n        // declared\n        if matches!(self.state, InitializeVisitorState::Initial) {\n            return;\n        }\n\n        // If node is the desired variable, see how it's used\n        if expr.res_local_id() == Some(self.var_id) {\n            if self.past_loop {\n                self.state = InitializeVisitorState::DontWarn;\n                return;\n            }\n\n            if let Some(parent) = get_parent_expr(self.cx, expr) {\n                match parent.kind {\n                    ExprKind::AssignOp(_, lhs, _) if lhs.hir_id == expr.hir_id => {\n                        self.state = InitializeVisitorState::DontWarn;\n                    },\n                    ExprKind::Assign(lhs, rhs, _) if lhs.hir_id == expr.hir_id => {\n                        self.state = if self.depth == 0 {\n                            match self.state {\n                                InitializeVisitorState::Declared(name, mut ty) => {\n                                    if ty.is_none() {\n                                        if let ExprKind::Lit(Spanned {\n                                            node: LitKind::Int(_, LitIntType::Unsuffixed),\n                                            ..\n                                        }) = rhs.kind\n                                        {\n                                            ty = None;\n                                        } else {\n                                            ty = self.cx.typeck_results().expr_ty_opt(rhs);\n                                        }\n                                    }\n\n                                    InitializeVisitorState::Initialized {\n                                        initializer: rhs,\n                                        ty,\n                                        name,\n                                    }\n                                },\n                                InitializeVisitorState::Initialized { ty, name, .. } => {\n                                    InitializeVisitorState::Initialized {\n                                        initializer: rhs,\n                                        ty,\n                                        name,\n                                    }\n                                },\n                                _ => InitializeVisitorState::DontWarn,\n                            }\n                        } else {\n                            InitializeVisitorState::DontWarn\n                        }\n                    },\n                    ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) => {\n                        self.state = InitializeVisitorState::DontWarn;\n                    },\n                    _ => (),\n                }\n            }\n\n            walk_expr(self, expr);\n        } else if !self.past_loop && is_loop(expr) {\n            self.state = InitializeVisitorState::DontWarn;\n        } else if is_conditional(expr) {\n            self.depth += 1;\n            walk_expr(self, expr);\n            self.depth -= 1;\n        } else {\n            walk_expr(self, expr);\n        }\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\nfn is_loop(expr: &Expr<'_>) -> bool {\n    matches!(expr.kind, ExprKind::Loop(..))\n}\n\nfn is_conditional(expr: &Expr<'_>) -> bool {\n    matches!(expr.kind, ExprKind::If(..) | ExprKind::Match(..))\n}\n\n/// If `arg` was the argument to a `for` loop, return the \"cleanest\" way of writing the\n/// actual `Iterator` that the loop uses.\npub(super) fn make_iterator_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, applicability: &mut Applicability) -> String {\n    let impls_iterator = cx\n        .tcx\n        .get_diagnostic_item(sym::Iterator)\n        .is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(arg), id, &[]));\n    if impls_iterator {\n        format!(\n            \"{}\",\n            sugg::Sugg::hir_with_applicability(cx, arg, \"_\", applicability).maybe_paren()\n        )\n    } else {\n        // (&x).into_iter() ==> x.iter()\n        // (&mut x).into_iter() ==> x.iter_mut()\n        let arg_ty = cx.typeck_results().expr_ty_adjusted(arg);\n        match &arg_ty.kind() {\n            ty::Ref(_, inner_ty, mutbl) if has_iter_method(cx, *inner_ty).is_some() => {\n                let method_name = match mutbl {\n                    Mutability::Mut => \"iter_mut\",\n                    Mutability::Not => \"iter\",\n                };\n                let caller = match &arg.kind {\n                    ExprKind::AddrOf(BorrowKind::Ref, _, arg_inner) => arg_inner,\n                    _ => arg,\n                };\n                format!(\n                    \"{}.{method_name}()\",\n                    sugg::Sugg::hir_with_applicability(cx, caller, \"_\", applicability).maybe_paren(),\n                )\n            },\n            _ => format!(\n                \"{}.into_iter()\",\n                sugg::Sugg::hir_with_applicability(cx, arg, \"_\", applicability).maybe_paren()\n            ),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/while_float.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_hir::ExprKind;\n\npub(super) fn check(cx: &rustc_lint::LateContext<'_>, condition: &rustc_hir::Expr<'_>) {\n    if let ExprKind::Binary(_op, left, right) = condition.kind\n        && is_float_type(cx, left)\n        && is_float_type(cx, right)\n    {\n        span_lint(\n            cx,\n            super::WHILE_FLOAT,\n            condition.span,\n            \"while condition comparing floats\",\n        );\n    }\n}\n\nfn is_float_type(cx: &rustc_lint::LateContext<'_>, expr: &rustc_hir::Expr<'_>) -> bool {\n    cx.typeck_results().expr_ty(expr).is_floating_point()\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/while_immutable_condition.rs",
    "content": "use super::WHILE_IMMUTABLE_CONDITION;\nuse clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::usage::mutated_variables;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefIdMap;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{Expr, ExprKind, HirIdSet, QPath};\nuse rustc_lint::LateContext;\nuse std::ops::ControlFlow;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) {\n    if ConstEvalCtxt::new(cx).eval(cond).is_some() {\n        // A pure constant condition (e.g., `while false`) is not linted.\n        return;\n    }\n\n    let mut var_visitor = VarCollectorVisitor {\n        cx,\n        ids: HirIdSet::default(),\n        def_ids: DefIdMap::default(),\n    };\n    if var_visitor.visit_expr(cond).is_break() {\n        return;\n    }\n    let used_in_condition = &var_visitor.ids;\n    let mutated_in_body = mutated_variables(expr, cx);\n    let mutated_in_condition = mutated_variables(cond, cx);\n    let no_cond_variable_mutated =\n        if let (Some(used_mutably_body), Some(used_mutably_cond)) = (mutated_in_body, mutated_in_condition) {\n            used_in_condition.is_disjoint(&used_mutably_body) && used_in_condition.is_disjoint(&used_mutably_cond)\n        } else {\n            return;\n        };\n    let mutable_static_in_cond = var_visitor.def_ids.items().any(|(_, v)| *v);\n\n    let mut has_break_or_return_visitor = HasBreakOrReturnVisitor;\n    let has_break_or_return = has_break_or_return_visitor.visit_expr(expr).is_break();\n\n    if no_cond_variable_mutated && !mutable_static_in_cond {\n        span_lint_and_then(\n            cx,\n            WHILE_IMMUTABLE_CONDITION,\n            cond.span,\n            \"variables in the condition are not mutated in the loop body\",\n            |diag| {\n                diag.note(\"this may lead to an infinite or to a never running loop\");\n\n                if has_break_or_return {\n                    diag.note(\"this loop contains `return`s or `break`s\");\n                    diag.help(\"rewrite it as `if cond { loop { } }`\");\n                }\n            },\n        );\n    }\n}\n\nstruct HasBreakOrReturnVisitor;\n\nimpl<'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor {\n    type Result = ControlFlow<()>;\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> ControlFlow<()> {\n        match expr.kind {\n            ExprKind::Ret(_) | ExprKind::Break(_, _) => {\n                return ControlFlow::Break(());\n            },\n            _ => {},\n        }\n\n        walk_expr(self, expr)\n    }\n}\n\n/// Collects the set of variables in an expression\n/// Stops analysis if a function call is found\n/// Note: In some cases such as `self`, there are no mutable annotation,\n/// All variables definition IDs are collected\nstruct VarCollectorVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    ids: HirIdSet,\n    def_ids: DefIdMap<bool>,\n}\n\nimpl<'tcx> VarCollectorVisitor<'_, 'tcx> {\n    fn insert_def_id(&mut self, ex: &'tcx Expr<'_>) {\n        if let ExprKind::Path(ref qpath) = ex.kind\n            && let QPath::Resolved(None, _) = *qpath\n        {\n            match self.cx.qpath_res(qpath, ex.hir_id) {\n                Res::Local(hir_id) => {\n                    self.ids.insert(hir_id);\n                },\n                Res::Def(DefKind::Static { .. }, def_id) => {\n                    let mutable = self.cx.tcx.is_mutable_static(def_id);\n                    self.def_ids.insert(def_id, mutable);\n                },\n                _ => {},\n            }\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for VarCollectorVisitor<'_, 'tcx> {\n    type Result = ControlFlow<()>;\n    fn visit_expr(&mut self, ex: &'tcx Expr<'_>) -> Self::Result {\n        match ex.kind {\n            ExprKind::Path(_) => {\n                self.insert_def_id(ex);\n                ControlFlow::Continue(())\n            },\n            // If there is any function/method call… we just stop analysis\n            ExprKind::Call(..) | ExprKind::MethodCall(..) => ControlFlow::Break(()),\n\n            _ => walk_expr(self, ex),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/while_let_loop.rs",
    "content": "use super::WHILE_LET_LOOP;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{snippet, snippet_indent, snippet_opt};\nuse clippy_utils::ty::needs_ordered_drop;\nuse clippy_utils::visitors::any_temporaries_need_ordered_drop;\nuse clippy_utils::{higher, peel_blocks};\nuse rustc_ast::BindingMode;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind, Path, QPath, StmtKind, Ty};\nuse rustc_lint::LateContext;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) {\n    let (init, let_info, els) = match (loop_block.stmts, loop_block.expr) {\n        ([stmt, ..], _) => match stmt.kind {\n            StmtKind::Let(LetStmt {\n                init: Some(e),\n                els,\n                pat,\n                ty,\n                ..\n            }) => (*e, Some((*pat, *ty)), *els),\n            StmtKind::Semi(e) | StmtKind::Expr(e) => (e, None, None),\n            _ => return,\n        },\n        ([], Some(e)) => (e, None, None),\n        _ => return,\n    };\n    let has_trailing_exprs = loop_block.stmts.len() + usize::from(loop_block.expr.is_some()) > 1;\n\n    if let Some(if_let) = higher::IfLet::hir(cx, init)\n        && let Some(else_expr) = if_let.if_else\n        && is_simple_break_expr(else_expr)\n    {\n        could_be_while_let(\n            cx,\n            expr,\n            if_let.let_pat,\n            if_let.let_expr,\n            has_trailing_exprs,\n            let_info,\n            Some(if_let.if_then),\n        );\n    } else if els.is_some_and(is_simple_break_block)\n        && let Some((pat, _)) = let_info\n    {\n        could_be_while_let(cx, expr, pat, init, has_trailing_exprs, let_info, None);\n    } else if let ExprKind::Match(scrutinee, [arm1, arm2], MatchSource::Normal) = init.kind\n        && arm1.guard.is_none()\n        && arm2.guard.is_none()\n        && is_simple_break_expr(arm2.body)\n    {\n        could_be_while_let(\n            cx,\n            expr,\n            arm1.pat,\n            scrutinee,\n            has_trailing_exprs,\n            let_info,\n            Some(arm1.body),\n        );\n    }\n}\n\n/// Checks if `block` contains a single unlabeled `break` expression or statement, possibly embedded\n/// inside other blocks.\nfn is_simple_break_block(block: &Block<'_>) -> bool {\n    match (block.stmts, block.expr) {\n        ([s], None) => matches!(s.kind, StmtKind::Expr(e) | StmtKind::Semi(e) if is_simple_break_expr(e)),\n        ([], Some(e)) => is_simple_break_expr(e),\n        _ => false,\n    }\n}\n\n/// Checks if `expr` contains a single unlabeled `break` expression or statement, possibly embedded\n/// inside other blocks.\nfn is_simple_break_expr(expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Block(b, _) => is_simple_break_block(b),\n        ExprKind::Break(dest, None) => dest.label.is_none(),\n        _ => false,\n    }\n}\n\nfn could_be_while_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    let_pat: &'tcx Pat<'_>,\n    let_expr: &'tcx Expr<'_>,\n    has_trailing_exprs: bool,\n    let_info: Option<(&Pat<'_>, Option<&Ty<'_>>)>,\n    inner_expr: Option<&Expr<'_>>,\n) {\n    if has_trailing_exprs\n        && (needs_ordered_drop(cx, cx.typeck_results().expr_ty(let_expr))\n            || any_temporaries_need_ordered_drop(cx, let_expr))\n    {\n        // Switching to a `while let` loop will extend the lifetime of some values.\n        return;\n    }\n\n    // NOTE: we used to build a body here instead of using\n    // ellipsis, this was removed because:\n    // 1) it was ugly with big bodies;\n    // 2) it was not indented properly;\n    // 3) it wasn’t very smart (see #675).\n    let inner_content = if let Some(((pat, ty), inner_expr)) = let_info.zip(inner_expr)\n        // Prevent trivial reassignments such as `let x = x;` or `let _ = …;`, but\n        // keep them if the type has been explicitly specified.\n        && (!is_trivial_assignment(pat, peel_blocks(inner_expr)) || ty.is_some())\n        && let Some(pat_str) = snippet_opt(cx, pat.span)\n        && let Some(init_str) = snippet_opt(cx, peel_blocks(inner_expr).span)\n    {\n        let ty_str = ty\n            .map(|ty| format!(\": {}\", snippet(cx, ty.span, \"_\")))\n            .unwrap_or_default();\n        format!(\n            \"\\n{indent}    let {pat_str}{ty_str} = {init_str};\\n{indent}    ..\\n{indent}\",\n            indent = snippet_indent(cx, expr.span).unwrap_or_default(),\n        )\n    } else {\n        \" .. \".into()\n    };\n\n    span_lint_and_sugg(\n        cx,\n        WHILE_LET_LOOP,\n        expr.span,\n        \"this loop could be written as a `while let` loop\",\n        \"try\",\n        format!(\n            \"while let {} = {} {{{inner_content}}}\",\n            snippet(cx, let_pat.span, \"..\"),\n            snippet(cx, let_expr.span, \"..\"),\n        ),\n        Applicability::HasPlaceholders,\n    );\n}\n\nfn is_trivial_assignment(pat: &Pat<'_>, init: &Expr<'_>) -> bool {\n    match (pat.kind, init.kind) {\n        (PatKind::Wild, _) => true,\n        (\n            PatKind::Binding(BindingMode::NONE, _, pat_ident, None),\n            ExprKind::Path(QPath::Resolved(None, Path { segments: [init], .. })),\n        ) => pat_ident.name == init.ident.name,\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/loops/while_let_on_iterator.rs",
    "content": "use std::ops::ControlFlow;\n\nuse super::WHILE_LET_ON_ITERATOR;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::visitors::is_res_used;\nuse clippy_utils::{as_some_pattern, get_enclosing_loop_or_multi_call_closure, higher, is_refutable};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{Closure, Expr, ExprKind, HirId, LetStmt, Mutability, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter::OnlyBodies;\nuse rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};\nuse rustc_span::Symbol;\nuse rustc_span::symbol::sym;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n    if let Some(higher::WhileLet { if_then, let_pat, let_expr, label, .. }) = higher::WhileLet::hir(expr)\n        // check for `Some(..)` pattern\n        && let Some(some_pat) = as_some_pattern(cx, let_pat)\n        // check for call to `Iterator::next`\n        && let ExprKind::MethodCall(method_name, iter_expr, [], _) = let_expr.kind\n        && method_name.ident.name == sym::next\n        && cx.ty_based_def(let_expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let Some(iter_expr_struct) = try_parse_iter_expr(cx, iter_expr)\n        // get the loop containing the match expression\n        && !uses_iter(cx, &iter_expr_struct, if_then)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n\n        let loop_label = label.map_or(String::new(), |l| format!(\"{}: \", l.ident.name));\n\n        let loop_var = if let Some(some_pat) = some_pat.first() {\n            if is_refutable(cx, some_pat) {\n                // Refutable patterns don't work with for loops.\n                return;\n            }\n            snippet_with_applicability(cx, some_pat.span, \"..\", &mut applicability)\n        } else {\n            \"_\".into()\n        };\n\n        // If the iterator is a field or the iterator is accessed after the loop is complete it needs to be\n        // passed by reference. TODO: If the struct can be partially moved from and the struct isn't used\n        // afterwards a mutable borrow of a field isn't necessary.\n        let iterator = snippet_with_applicability(cx, iter_expr.span, \"_\", &mut applicability);\n        let iterator_by_ref = if cx.typeck_results().expr_ty(iter_expr).ref_mutability() == Some(Mutability::Mut)\n            || !iter_expr_struct.can_move\n            || !iter_expr_struct.fields.is_empty()\n            || needs_mutable_borrow(cx, &iter_expr_struct, expr)\n        {\n            make_iterator_snippet(cx, iter_expr, &iterator)\n        } else {\n            iterator.into_owned()\n        };\n\n        span_lint_and_sugg(\n            cx,\n            WHILE_LET_ON_ITERATOR,\n            expr.span.with_hi(let_expr.span.hi()),\n            \"this loop could be written as a `for` loop\",\n            \"try\",\n            format!(\"{loop_label}for {loop_var} in {iterator_by_ref}\"),\n            applicability,\n        );\n    }\n}\n\n#[derive(Debug)]\nstruct IterExpr {\n    /// The fields used, in order of child to parent.\n    fields: Vec<Symbol>,\n    /// The path being used.\n    path: Res,\n    /// Whether or not the iterator can be moved.\n    can_move: bool,\n}\n\n/// Parses any expression to find out which field of which variable is used. Will return `None` if\n/// the expression might have side effects.\nfn try_parse_iter_expr(cx: &LateContext<'_>, mut e: &Expr<'_>) -> Option<IterExpr> {\n    let mut fields = Vec::new();\n    let mut can_move = true;\n    loop {\n        if cx\n            .typeck_results()\n            .expr_adjustments(e)\n            .iter()\n            .any(|a| matches!(a.kind, Adjust::Deref(DerefAdjustKind::Overloaded(..))))\n        {\n            // Custom deref impls need to borrow the whole value as it's captured by reference\n            can_move = false;\n            fields.clear();\n        }\n        match e.kind {\n            ExprKind::Path(ref path) => {\n                break Some(IterExpr {\n                    fields,\n                    path: cx.qpath_res(path, e.hir_id),\n                    can_move,\n                });\n            },\n            ExprKind::Field(base, name) => {\n                fields.push(name.name);\n                e = base;\n            },\n            // Dereferencing a pointer has no side effects and doesn't affect which field is being used.\n            ExprKind::Unary(UnOp::Deref, base) if cx.typeck_results().expr_ty(base).is_ref() => e = base,\n\n            // Shouldn't have side effects, but there's no way to trace which field is used. So forget which fields have\n            // already been seen.\n            ExprKind::Index(base, idx, _) if !idx.can_have_side_effects() => {\n                can_move = false;\n                fields.clear();\n                e = base;\n            },\n            ExprKind::Unary(UnOp::Deref, base) => {\n                can_move = false;\n                fields.clear();\n                e = base;\n            },\n\n            // No effect and doesn't affect which field is being used.\n            ExprKind::DropTemps(base) | ExprKind::AddrOf(_, _, base) | ExprKind::Type(base, _) => e = base,\n            _ => break None,\n        }\n    }\n}\n\nfn is_expr_same_field(cx: &LateContext<'_>, mut e: &Expr<'_>, mut fields: &[Symbol], path_res: Res) -> bool {\n    loop {\n        match (&e.kind, fields) {\n            (&ExprKind::Field(base, name), [head_field, tail_fields @ ..]) if name.name == *head_field => {\n                e = base;\n                fields = tail_fields;\n            },\n            (ExprKind::Path(path), []) => {\n                break cx.qpath_res(path, e.hir_id) == path_res;\n            },\n            (&(ExprKind::DropTemps(base) | ExprKind::AddrOf(_, _, base) | ExprKind::Type(base, _)), _) => e = base,\n            _ => break false,\n        }\n    }\n}\n\n/// Checks if the given expression is the same field as, is a child of, or is the parent of the\n/// given field. Used to check if the expression can be used while the given field is borrowed\n/// mutably. e.g. if checking for `x.y`, then `x.y`, `x.y.z`, and `x` will all return true, but\n/// `x.z`, and `y` will return false.\nfn is_expr_same_child_or_parent_field(cx: &LateContext<'_>, expr: &Expr<'_>, fields: &[Symbol], path_res: Res) -> bool {\n    match expr.kind {\n        ExprKind::Field(base, name) => {\n            if let Some((head_field, tail_fields)) = fields.split_first() {\n                if name.name == *head_field && is_expr_same_field(cx, base, tail_fields, path_res) {\n                    return true;\n                }\n                // Check if the expression is a parent field\n                let mut fields_iter = tail_fields.iter();\n                while let Some(field) = fields_iter.next() {\n                    if *field == name.name && is_expr_same_field(cx, base, fields_iter.as_slice(), path_res) {\n                        return true;\n                    }\n                }\n            }\n\n            // Check if the expression is a child field.\n            let mut e = base;\n            loop {\n                match e.kind {\n                    ExprKind::Field(..) if is_expr_same_field(cx, e, fields, path_res) => break true,\n                    ExprKind::Field(base, _) | ExprKind::DropTemps(base) | ExprKind::Type(base, _) => e = base,\n                    ExprKind::Path(ref path) if fields.is_empty() => {\n                        break cx.qpath_res(path, e.hir_id) == path_res;\n                    },\n                    _ => break false,\n                }\n            }\n        },\n        // If the path matches, this is either an exact match, or the expression is a parent of the field.\n        ExprKind::Path(ref path) => cx.qpath_res(path, expr.hir_id) == path_res,\n        ExprKind::DropTemps(base) | ExprKind::Type(base, _) | ExprKind::AddrOf(_, _, base) => {\n            is_expr_same_child_or_parent_field(cx, base, fields, path_res)\n        },\n        _ => false,\n    }\n}\n\n/// Strips off all field and path expressions. This will return true if a field or path has been\n/// skipped. Used to skip them after failing to check for equality.\nfn skip_fields_and_path<'tcx>(expr: &'tcx Expr<'_>) -> (Option<&'tcx Expr<'tcx>>, bool) {\n    let mut e = expr;\n    let e = loop {\n        match e.kind {\n            ExprKind::Field(base, _) | ExprKind::DropTemps(base) | ExprKind::Type(base, _) => e = base,\n            ExprKind::Path(_) => return (None, true),\n            _ => break e,\n        }\n    };\n    (Some(e), e.hir_id != expr.hir_id)\n}\n\n/// Checks if the given expression uses the iterator.\nfn uses_iter<'tcx>(cx: &LateContext<'tcx>, iter_expr: &IterExpr, container: &'tcx Expr<'_>) -> bool {\n    struct V<'a, 'b, 'tcx> {\n        cx: &'a LateContext<'tcx>,\n        iter_expr: &'b IterExpr,\n    }\n    impl<'tcx> Visitor<'tcx> for V<'_, '_, 'tcx> {\n        type Result = ControlFlow<()>;\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {\n            if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {\n                ControlFlow::Break(())\n            } else if let (e, true) = skip_fields_and_path(e) {\n                if let Some(e) = e {\n                    self.visit_expr(e)\n                } else {\n                    ControlFlow::Continue(())\n                }\n            } else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {\n                if is_res_used(self.cx, self.iter_expr.path, id) {\n                    ControlFlow::Break(())\n                } else {\n                    ControlFlow::Continue(())\n                }\n            } else {\n                walk_expr(self, e)\n            }\n        }\n    }\n\n    let mut v = V { cx, iter_expr };\n    v.visit_expr(container).is_break()\n}\n\n#[expect(clippy::too_many_lines)]\nfn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &Expr<'_>) -> bool {\n    struct AfterLoopVisitor<'a, 'b, 'tcx> {\n        cx: &'a LateContext<'tcx>,\n        iter_expr: &'b IterExpr,\n        loop_id: HirId,\n        after_loop: bool,\n    }\n    impl<'tcx> Visitor<'tcx> for AfterLoopVisitor<'_, '_, 'tcx> {\n        type NestedFilter = OnlyBodies;\n        type Result = ControlFlow<()>;\n        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n            self.cx.tcx\n        }\n\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {\n            if self.after_loop {\n                if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {\n                    ControlFlow::Break(())\n                } else if let (e, true) = skip_fields_and_path(e) {\n                    if let Some(e) = e {\n                        self.visit_expr(e)\n                    } else {\n                        ControlFlow::Continue(())\n                    }\n                } else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {\n                    if is_res_used(self.cx, self.iter_expr.path, id) {\n                        ControlFlow::Break(())\n                    } else {\n                        ControlFlow::Continue(())\n                    }\n                } else {\n                    walk_expr(self, e)\n                }\n            } else if self.loop_id == e.hir_id {\n                self.after_loop = true;\n                ControlFlow::Continue(())\n            } else {\n                walk_expr(self, e)\n            }\n        }\n    }\n\n    struct NestedLoopVisitor<'a, 'b, 'tcx> {\n        cx: &'a LateContext<'tcx>,\n        iter_expr: &'b IterExpr,\n        local_id: HirId,\n        loop_id: HirId,\n        after_loop: bool,\n        found_local: bool,\n        used_after: bool,\n    }\n    impl<'tcx> Visitor<'tcx> for NestedLoopVisitor<'_, '_, 'tcx> {\n        type NestedFilter = OnlyBodies;\n        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n            self.cx.tcx\n        }\n\n        fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {\n            if !self.after_loop {\n                l.pat.each_binding_or_first(&mut |_, id, _, _| {\n                    if id == self.local_id {\n                        self.found_local = true;\n                    }\n                });\n            }\n            if let Some(e) = l.init {\n                self.visit_expr(e);\n            }\n        }\n\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {\n            if self.used_after {\n                return;\n            }\n            if self.after_loop {\n                if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {\n                    self.used_after = true;\n                } else if let (e, true) = skip_fields_and_path(e) {\n                    if let Some(e) = e {\n                        self.visit_expr(e);\n                    }\n                } else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {\n                    self.used_after = is_res_used(self.cx, self.iter_expr.path, id);\n                } else {\n                    walk_expr(self, e);\n                }\n            } else if e.hir_id == self.loop_id {\n                self.after_loop = true;\n            } else {\n                walk_expr(self, e);\n            }\n        }\n    }\n\n    if let Some(e) = get_enclosing_loop_or_multi_call_closure(cx, loop_expr) {\n        let Res::Local(local_id) = iter_expr.path else {\n            return true;\n        };\n        let mut v = NestedLoopVisitor {\n            cx,\n            iter_expr,\n            local_id,\n            loop_id: loop_expr.hir_id,\n            after_loop: false,\n            found_local: false,\n            used_after: false,\n        };\n        v.visit_expr(e);\n        v.used_after || !v.found_local\n    } else {\n        let mut v = AfterLoopVisitor {\n            cx,\n            iter_expr,\n            loop_id: loop_expr.hir_id,\n            after_loop: false,\n        };\n        v.visit_expr(cx.tcx.hir_body(cx.enclosing_body.unwrap()).value)\n            .is_break()\n    }\n}\n\n/// Constructs the transformed iterator expression for the suggestion.\n/// Returns `iterator.by_ref()` unless the last deref adjustment targets an unsized type,\n/// in which case it applies all derefs (e.g., `&mut **iterator` or `&mut ***iterator`).\nfn make_iterator_snippet<'tcx>(cx: &LateContext<'tcx>, iter_expr: &Expr<'tcx>, iterator: &str) -> String {\n    if let Some((n, adjust)) = cx\n        .typeck_results()\n        .expr_adjustments(iter_expr)\n        .iter()\n        .take_while(|x| matches!(x.kind, Adjust::Deref(_)))\n        .enumerate()\n        .last()\n        && !adjust.target.is_sized(cx.tcx, cx.typing_env())\n    {\n        format!(\"&mut {:*<n$}{iterator}\", '*', n = n + 1)\n    } else {\n        format!(\"{iterator}.by_ref()\")\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/macro_metavars_in_unsafe.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::is_lint_allowed;\nuse itertools::Itertools;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};\nuse rustc_hir::{BlockCheckMode, Expr, ExprKind, HirId, Stmt, UnsafeSource, find_attr};\nuse rustc_lint::{LateContext, LateLintPass, Level, LintContext};\nuse rustc_middle::lint::LevelAndSource;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, SyntaxContext};\nuse std::collections::BTreeMap;\nuse std::collections::btree_map::Entry;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for macros that expand metavariables in an unsafe block.\n    ///\n    /// ### Why is this bad?\n    /// This hides an unsafe block and allows the user of the macro to write unsafe code without an explicit\n    /// unsafe block at callsite, making it possible to perform unsafe operations in seemingly safe code.\n    ///\n    /// The macro should be restructured so that these metavariables are referenced outside of unsafe blocks\n    /// and that the usual unsafety checks apply to the macro argument.\n    ///\n    /// This is usually done by binding it to a variable outside of the unsafe block\n    /// and then using that variable inside of the block as shown in the example, or by referencing it a second time\n    /// in a safe context, e.g. `if false { $expr }`.\n    ///\n    /// ### Known limitations\n    /// Due to how macros are represented in the compiler at the time Clippy runs its lints,\n    /// it's not possible to look for metavariables in macro definitions directly.\n    ///\n    /// Instead, this lint looks at expansions of macros.\n    /// This leads to false negatives for macros that are never actually invoked.\n    ///\n    /// By default, this lint is rather conservative and will only emit warnings on publicly-exported\n    /// macros from the same crate, because oftentimes private internal macros are one-off macros where\n    /// this lint would just be noise (e.g. macros that generate `impl` blocks).\n    /// The default behavior should help with preventing a high number of such false positives,\n    /// however it can be configured to also emit warnings in private macros if desired.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// /// Gets the first element of a slice\n    /// macro_rules! first {\n    ///     ($slice:expr) => {\n    ///         unsafe {\n    ///             let slice = $slice; // ⚠️ expansion inside of `unsafe {}`\n    ///\n    ///             assert!(!slice.is_empty());\n    ///             // SAFETY: slice is checked to have at least one element\n    ///             slice.first().unwrap_unchecked()\n    ///         }\n    ///     }\n    /// }\n    ///\n    /// assert_eq!(*first!(&[1i32]), 1);\n    ///\n    /// // This will compile as a consequence (note the lack of `unsafe {}`)\n    /// assert_eq!(*first!(std::hint::unreachable_unchecked() as &[i32]), 1);\n    /// ```\n    /// Use instead:\n    /// ```compile_fail\n    /// macro_rules! first {\n    ///     ($slice:expr) => {{\n    ///         let slice = $slice; // ✅ outside of `unsafe {}`\n    ///         unsafe {\n    ///             assert!(!slice.is_empty());\n    ///             // SAFETY: slice is checked to have at least one element\n    ///             slice.first().unwrap_unchecked()\n    ///         }\n    ///     }}\n    /// }\n    ///\n    /// assert_eq!(*first!(&[1]), 1);\n    ///\n    /// // This won't compile:\n    /// assert_eq!(*first!(std::hint::unreachable_unchecked() as &[i32]), 1);\n    /// ```\n    #[clippy::version = \"1.80.0\"]\n    pub MACRO_METAVARS_IN_UNSAFE,\n    suspicious,\n    \"expanding macro metavariables in an unsafe block\"\n}\n\nimpl_lint_pass!(ExprMetavarsInUnsafe => [MACRO_METAVARS_IN_UNSAFE]);\n\n#[derive(Clone, Debug)]\npub enum MetavarState {\n    ReferencedInUnsafe { unsafe_blocks: Vec<HirId> },\n    ReferencedInSafe,\n}\n\npub struct ExprMetavarsInUnsafe {\n    warn_unsafe_macro_metavars_in_private_macros: bool,\n    /// A metavariable can be expanded more than once, potentially across multiple bodies, so it\n    /// requires some state kept across HIR nodes to make it possible to delay a warning\n    /// and later undo:\n    ///\n    /// ```ignore\n    /// macro_rules! x {\n    ///     ($v:expr) => {\n    ///         unsafe { $v; } // unsafe context, it might be possible to emit a warning here, so add it to the map\n    ///\n    ///         $v;            // `$v` expanded another time but in a safe context, set to ReferencedInSafe to suppress\n    ///     }\n    /// }\n    /// ```\n    metavar_expns: BTreeMap<Span, MetavarState>,\n}\n\nimpl ExprMetavarsInUnsafe {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            warn_unsafe_macro_metavars_in_private_macros: conf.warn_unsafe_macro_metavars_in_private_macros,\n            metavar_expns: BTreeMap::new(),\n        }\n    }\n}\n\nstruct BodyVisitor<'a, 'tcx> {\n    /// Stack of unsafe blocks -- the top item always represents the last seen unsafe block from\n    /// within a relevant macro.\n    macro_unsafe_blocks: Vec<HirId>,\n    /// When this is >0, it means that the node currently being visited is \"within\" a\n    /// macro definition.\n    /// This is used to detect if an expression represents a metavariable.\n    ///\n    /// For example, the following pre-expansion code that we want to lint\n    /// ```ignore\n    /// macro_rules! m { ($e:expr) => { unsafe { $e; } } }\n    /// m!(1);\n    /// ```\n    /// would look like this post-expansion code:\n    /// ```ignore\n    /// unsafe { /* macro */\n    ///     1 /* root */; /* macro */\n    /// }\n    /// ```\n    /// Visiting the block and the statement will increment the `expn_depth` so that it is >0,\n    /// and visiting the expression with a root context while `expn_depth > 0` tells us\n    /// that it must be a metavariable.\n    expn_depth: u32,\n    cx: &'a LateContext<'tcx>,\n    lint: &'a mut ExprMetavarsInUnsafe,\n}\n\nfn is_public_macro(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {\n    (cx.effective_visibilities.is_exported(def_id) || find_attr!(cx.tcx, def_id, MacroExport { .. }))\n        && !cx.tcx.is_doc_hidden(def_id)\n}\n\nimpl<'tcx> Visitor<'tcx> for BodyVisitor<'_, 'tcx> {\n    fn visit_stmt(&mut self, s: &'tcx Stmt<'tcx>) {\n        let from_expn = s.span.from_expansion();\n        if from_expn {\n            self.expn_depth += 1;\n        }\n        walk_stmt(self, s);\n        if from_expn {\n            self.expn_depth -= 1;\n        }\n    }\n\n    fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) {\n        let ctxt = e.span.ctxt();\n\n        if let ExprKind::Block(block, _) = e.kind\n            && let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules\n            && !ctxt.is_root()\n            && let Some(macro_def_id) = ctxt.outer_expn_data().macro_def_id\n            && let Some(macro_def_id) = macro_def_id.as_local()\n            && (self.lint.warn_unsafe_macro_metavars_in_private_macros || is_public_macro(self.cx, macro_def_id))\n        {\n            self.macro_unsafe_blocks.push(block.hir_id);\n            self.expn_depth += 1;\n            walk_block(self, block);\n            self.expn_depth -= 1;\n            self.macro_unsafe_blocks.pop();\n        } else if ctxt.is_root() && self.expn_depth > 0 {\n            let unsafe_block = self.macro_unsafe_blocks.last().copied();\n\n            match (self.lint.metavar_expns.entry(e.span), unsafe_block) {\n                (Entry::Vacant(e), None) => {\n                    e.insert(MetavarState::ReferencedInSafe);\n                },\n                (Entry::Vacant(e), Some(unsafe_block)) => {\n                    e.insert(MetavarState::ReferencedInUnsafe {\n                        unsafe_blocks: vec![unsafe_block],\n                    });\n                },\n                (Entry::Occupied(mut e), None) => {\n                    if let MetavarState::ReferencedInUnsafe { .. } = *e.get() {\n                        e.insert(MetavarState::ReferencedInSafe);\n                    }\n                },\n                (Entry::Occupied(mut e), Some(unsafe_block)) => {\n                    if let MetavarState::ReferencedInUnsafe { unsafe_blocks } = e.get_mut()\n                        && !unsafe_blocks.contains(&unsafe_block)\n                    {\n                        unsafe_blocks.push(unsafe_block);\n                    }\n                },\n            }\n\n            // NB: No need to visit descendant nodes. They're guaranteed to represent the same\n            // metavariable\n        } else {\n            walk_expr(self, e);\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ExprMetavarsInUnsafe {\n    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &rustc_hir::Body<'tcx>) {\n        if is_lint_allowed(cx, MACRO_METAVARS_IN_UNSAFE, body.value.hir_id) {\n            return;\n        }\n\n        // This BodyVisitor is separate and not part of the lint pass because there is no\n        // `check_stmt_post` on `(Late)LintPass`, which we'd need to detect when we're leaving a macro span\n\n        let mut vis = BodyVisitor {\n            macro_unsafe_blocks: Vec::new(),\n            #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning\n            expn_depth: if body.value.span.from_expansion() { 1 } else { 0 },\n            cx,\n            lint: self\n        };\n        vis.visit_body(body);\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        // Aggregate all unsafe blocks from all spans:\n        // ```\n        // macro_rules! x {\n        //   ($w:expr, $x:expr, $y:expr) => { $w; unsafe { $w; $x; }; unsafe { $x; $y; }; }\n        // }\n        // $w: []  (unsafe#0 is never added because it was referenced in a safe context)\n        // $x: [unsafe#0, unsafe#1]\n        // $y: [unsafe#1]\n        // ```\n        // We want to lint unsafe blocks #0 and #1\n        let bad_unsafe_blocks = self\n            .metavar_expns\n            .values()\n            .filter_map(|state| match state {\n                MetavarState::ReferencedInUnsafe { unsafe_blocks } => Some(unsafe_blocks.as_slice()),\n                MetavarState::ReferencedInSafe => None,\n            })\n            .flatten()\n            .copied()\n            .inspect(|&unsafe_block| {\n                if let LevelAndSource {\n                    level: Level::Expect,\n                    lint_id: Some(id),\n                    ..\n                } = cx.tcx.lint_level_at_node(MACRO_METAVARS_IN_UNSAFE, unsafe_block)\n                {\n                    // Since we're going to deduplicate expanded unsafe blocks by its enclosing macro definition soon,\n                    // which would lead to unfulfilled `#[expect()]`s in all other unsafe blocks that are filtered out\n                    // except for the one we emit the warning at, we must manually fulfill the lint\n                    // for all unsafe blocks here.\n                    cx.fulfill_expectation(id);\n                }\n            })\n            .map(|id| {\n                // Remove the syntax context to hide \"in this macro invocation\" in the diagnostic.\n                // The invocation doesn't matter. Also we want to dedupe by the unsafe block and not by anything\n                // related to the callsite.\n                let span = cx.tcx.hir_span(id);\n\n                (id, Span::new(span.lo(), span.hi(), SyntaxContext::root(), None))\n            })\n            .dedup_by(|&(_, a), &(_, b)| a == b);\n\n        for (id, span) in bad_unsafe_blocks {\n            span_lint_hir_and_then(\n                cx,\n                MACRO_METAVARS_IN_UNSAFE,\n                id,\n                span,\n                \"this macro expands metavariables in an unsafe block\",\n                |diag| {\n                    diag.note(\"this allows the user of the macro to write unsafe code outside of an unsafe block\");\n                    diag.help(\n                            \"consider expanding any metavariables outside of this block, e.g. by storing them in a variable\",\n                        );\n                    diag.help(\n                            \"... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\",\n                        );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/macro_use.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::source::snippet;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{self as hir, AmbigArg, find_attr};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::edition::Edition;\nuse std::collections::BTreeMap;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `#[macro_use] use...`.\n    ///\n    /// ### Why is this bad?\n    /// Since the Rust 2018 edition you can import\n    /// macro's directly, this is considered idiomatic.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// #[macro_use]\n    /// extern crate some_crate;\n    ///\n    /// fn main() {\n    ///     some_macro!();\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```rust,ignore\n    /// use some_crate::some_macro;\n    ///\n    /// fn main() {\n    ///     some_macro!();\n    /// }\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub MACRO_USE_IMPORTS,\n    pedantic,\n    \"#[macro_use] is no longer needed\"\n}\n\nimpl_lint_pass!(MacroUseImports => [MACRO_USE_IMPORTS]);\n\n/// `MacroRefData` includes the name of the macro.\n#[derive(Debug, Clone)]\npub struct MacroRefData {\n    name: String,\n}\n\nimpl MacroRefData {\n    pub fn new(name: String) -> Self {\n        Self { name }\n    }\n}\n\n#[derive(Default)]\npub struct MacroUseImports {\n    /// the actual import path used and the span of the attribute above it. The value is\n    /// the location, where the lint should be emitted.\n    imports: Vec<(String, Span, hir::HirId)>,\n    /// the span of the macro reference, kept to ensure only one reference is used per macro call.\n    collected: FxHashSet<Span>,\n    mac_refs: Vec<MacroRefData>,\n}\n\nimpl MacroUseImports {\n    fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {\n        let call_site = span.source_callsite();\n        let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), \"_\");\n        if span.source_callee().is_some() && !self.collected.contains(&call_site) {\n            let name = if name.contains(\"::\") {\n                name.split(\"::\").last().unwrap().to_string()\n            } else {\n                name.to_string()\n            };\n\n            self.mac_refs.push(MacroRefData::new(name));\n            self.collected.insert(call_site);\n        }\n    }\n\n    fn push_unique_macro_pat_ty(&mut self, cx: &LateContext<'_>, span: Span) {\n        let call_site = span.source_callsite();\n        let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), \"_\");\n        if span.source_callee().is_some() && !self.collected.contains(&call_site) {\n            self.mac_refs.push(MacroRefData::new(name.to_string()));\n            self.collected.insert(call_site);\n        }\n    }\n}\n\nimpl LateLintPass<'_> for MacroUseImports {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {\n        if cx.sess().opts.edition >= Edition::Edition2018\n            && let hir::ItemKind::Use(path, _kind) = &item.kind\n            && let hir_id = item.hir_id()\n            && let attrs = cx.tcx.hir_attrs(hir_id)\n            && let Some(mac_attr_span) = find_attr!(attrs, MacroUse {span, ..} => *span)\n            && let Some(Res::Def(DefKind::Mod, id)) = path.res.type_ns\n            && !id.is_local()\n        {\n            for kid in cx.tcx.module_children(id) {\n                if let Res::Def(DefKind::Macro(_mac_type), mac_id) = kid.res {\n                    let def_path = cx.tcx.def_path_str(mac_id);\n                    self.imports.push((def_path, mac_attr_span, hir_id));\n                }\n            }\n        } else if item.span.from_expansion() {\n            self.push_unique_macro_pat_ty(cx, item.span);\n        }\n    }\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {\n        if expr.span.from_expansion() {\n            self.push_unique_macro(cx, expr.span);\n        }\n    }\n    fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) {\n        if stmt.span.from_expansion() {\n            self.push_unique_macro(cx, stmt.span);\n        }\n    }\n    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &hir::Pat<'_>) {\n        if pat.span.from_expansion() {\n            self.push_unique_macro_pat_ty(cx, pat.span);\n        }\n    }\n    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &hir::Ty<'_, AmbigArg>) {\n        if ty.span.from_expansion() {\n            self.push_unique_macro_pat_ty(cx, ty.span);\n        }\n    }\n    fn check_crate_post(&mut self, cx: &LateContext<'_>) {\n        let mut used = BTreeMap::new();\n        let mut check_dup = vec![];\n        for (import, span, hir_id) in &self.imports {\n            let found_idx = self.mac_refs.iter().position(|mac| import.ends_with(&mac.name));\n\n            if let Some(idx) = found_idx {\n                self.mac_refs.remove(idx);\n                let seg = import.split(\"::\").collect::<Vec<_>>();\n\n                match seg.as_slice() {\n                    // an empty path is impossible\n                    // a path should always consist of 2 or more segments\n                    [] | [_] => return,\n                    [root, item] => {\n                        if !check_dup.contains(&(*item).to_string()) {\n                            used.entry((\n                                (*root).to_string(),\n                                span,\n                                hir_id.local_id,\n                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),\n                            ))\n                            .or_insert_with(|| (vec![], hir_id))\n                            .0\n                            .push((*item).to_string());\n                            check_dup.push((*item).to_string());\n                        }\n                    },\n                    [root, rest @ ..] => {\n                        if rest.iter().all(|item| !check_dup.contains(&(*item).to_string())) {\n                            let filtered = rest\n                                .iter()\n                                .filter_map(|item| {\n                                    if check_dup.contains(&(*item).to_string()) {\n                                        None\n                                    } else {\n                                        Some((*item).to_string())\n                                    }\n                                })\n                                .collect::<Vec<_>>();\n                            used.entry((\n                                (*root).to_string(),\n                                span,\n                                hir_id.local_id,\n                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),\n                            ))\n                            .or_insert_with(|| (vec![], hir_id))\n                            .0\n                            .push(filtered.join(\"::\"));\n                            check_dup.extend(filtered);\n                        } else {\n                            let rest = rest.to_vec();\n                            used.entry((\n                                (*root).to_string(),\n                                span,\n                                hir_id.local_id,\n                                cx.tcx.def_path_hash(hir_id.owner.def_id.into()),\n                            ))\n                            .or_insert_with(|| (vec![], hir_id))\n                            .0\n                            .push(rest.join(\"::\"));\n                            check_dup.extend(rest.iter().map(ToString::to_string));\n                        }\n                    },\n                }\n            }\n        }\n\n        // If mac_refs is not empty we have encountered an import we could not handle\n        // such as `std::prelude::v1::foo` or some other macro that expands to an import.\n        if self.mac_refs.is_empty() {\n            for ((root, span, ..), (path, hir_id)) in used {\n                let import = if let [single] = &path[..] {\n                    format!(\"{root}::{single}\")\n                } else {\n                    format!(\"{root}::{{{}}}\", path.join(\", \"))\n                };\n\n                span_lint_hir_and_then(\n                    cx,\n                    MACRO_USE_IMPORTS,\n                    *hir_id,\n                    *span,\n                    \"`macro_use` attributes are no longer needed in the Rust 2018 edition\",\n                    |diag| {\n                        diag.span_suggestion(\n                            *span,\n                            \"remove the attribute and import the macro directly, try\",\n                            format!(\"use {import};\"),\n                            Applicability::MaybeIncorrect,\n                        );\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/main_recursion.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{is_entrypoint_fn, is_no_std_crate};\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for recursion using the entrypoint.\n    ///\n    /// ### Why is this bad?\n    /// Apart from special setups (which we could detect following attributes like #![no_std]),\n    /// recursing into main() seems like an unintuitive anti-pattern we should be able to detect.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn main() {\n    ///     main();\n    /// }\n    /// ```\n    #[clippy::version = \"1.38.0\"]\n    pub MAIN_RECURSION,\n    style,\n    \"recursion using the entrypoint\"\n}\n\nimpl_lint_pass!(MainRecursion => [MAIN_RECURSION]);\n\n#[derive(Default)]\npub struct MainRecursion {\n    has_no_std_attr: bool,\n}\n\nimpl LateLintPass<'_> for MainRecursion {\n    fn check_crate(&mut self, cx: &LateContext<'_>) {\n        self.has_no_std_attr = is_no_std_crate(cx);\n    }\n\n    fn check_expr_post(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if self.has_no_std_attr {\n            return;\n        }\n\n        if let ExprKind::Call(func, []) = &expr.kind\n            && let ExprKind::Path(QPath::Resolved(_, path)) = &func.kind\n            && let Some(def_id) = path.res.opt_def_id()\n            && is_entrypoint_fn(cx, def_id)\n        {\n            span_lint_and_help(\n                cx,\n                MAIN_RECURSION,\n                func.span,\n                format!(\"recursing into entrypoint `{}`\", snippet(cx, func.span, \"main\")),\n                None,\n                \"consider using another function for this recursion\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_abs_diff.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::If;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::peel_and_count_ty_refs;\nuse clippy_utils::{eq_expr_value, peel_blocks, span_contains_comment, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects patterns like `if a > b { a - b } else { b - a }` and suggests using `a.abs_diff(b)`.\n    ///\n    /// ### Why is this bad?\n    /// Using `abs_diff` is shorter, more readable, and avoids control flow.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// # let (a, b) = (5_usize, 3_usize);\n    /// if a > b {\n    ///     a - b\n    /// } else {\n    ///     b - a\n    /// }\n    /// # ;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let (a, b) = (5_usize, 3_usize);\n    /// a.abs_diff(b)\n    /// # ;\n    /// ```\n    #[clippy::version = \"1.88.0\"]\n    pub MANUAL_ABS_DIFF,\n    complexity,\n    \"using an if-else pattern instead of `abs_diff`\"\n}\n\nimpl_lint_pass!(ManualAbsDiff => [MANUAL_ABS_DIFF]);\n\npub struct ManualAbsDiff {\n    msrv: Msrv,\n}\n\nimpl ManualAbsDiff {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualAbsDiff {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if !expr.span.from_expansion()\n            && let Some(if_expr) = If::hir(expr)\n            && let Some(r#else) = if_expr.r#else\n            && let ExprKind::Binary(op, rhs, lhs) = if_expr.cond.kind\n            && let (BinOpKind::Gt | BinOpKind::Ge, mut a, mut b) | (BinOpKind::Lt | BinOpKind::Le, mut b, mut a) =\n                (op.node, rhs, lhs)\n            && let Some((ty, b_n_refs)) = self.are_ty_eligible(cx, a, b)\n            && is_sub_expr(cx, if_expr.then, a, b, ty)\n            && is_sub_expr(cx, r#else, b, a, ty)\n        {\n            span_lint_and_then(\n                cx,\n                MANUAL_ABS_DIFF,\n                expr.span,\n                \"manual absolute difference pattern without using `abs_diff`\",\n                |diag| {\n                    if is_unsuffixed_numeral_lit(a) && !is_unsuffixed_numeral_lit(b) {\n                        (a, b) = (b, a);\n                    }\n                    let applicability = {\n                        if span_contains_comment(cx, if_expr.then.span) || span_contains_comment(cx, r#else.span) {\n                            Applicability::MaybeIncorrect\n                        } else {\n                            Applicability::MachineApplicable\n                        }\n                    };\n                    let sugg = format!(\n                        \"{}.abs_diff({}{})\",\n                        Sugg::hir(cx, a, \"..\").maybe_paren(),\n                        \"*\".repeat(b_n_refs),\n                        Sugg::hir(cx, b, \"..\")\n                    );\n                    diag.span_suggestion(expr.span, \"replace with `abs_diff`\", sugg, applicability);\n                },\n            );\n        }\n    }\n}\n\nimpl ManualAbsDiff {\n    /// Returns a type if `a` and `b` are both of it, and this lint can be applied to that\n    /// type (currently, any primitive int, or a `Duration`)\n    fn are_ty_eligible<'tcx>(&self, cx: &LateContext<'tcx>, a: &Expr<'_>, b: &Expr<'_>) -> Option<(Ty<'tcx>, usize)> {\n        let is_int = |ty: Ty<'_>| matches!(ty.kind(), ty::Uint(_) | ty::Int(_)) && self.msrv.meets(cx, msrvs::ABS_DIFF);\n        let is_duration =\n            |ty: Ty<'_>| ty.is_diag_item(cx, sym::Duration) && self.msrv.meets(cx, msrvs::DURATION_ABS_DIFF);\n\n        let a_ty = cx.typeck_results().expr_ty(a).peel_refs();\n        let (b_ty, b_n_refs, _) = peel_and_count_ty_refs(cx.typeck_results().expr_ty(b));\n\n        (a_ty == b_ty && (is_int(a_ty) || is_duration(a_ty))).then_some((a_ty, b_n_refs))\n    }\n}\n\n/// Checks if the given expression is a subtraction operation between two expected expressions,\n/// i.e. if `expr` is `{expected_a} - {expected_b}`.\n///\n/// If `expected_ty` is a signed primitive integer, this function will only return `Some` if the\n/// subtraction expr is wrapped in a cast to the equivalent unsigned int.\nfn is_sub_expr(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    expected_a: &Expr<'_>,\n    expected_b: &Expr<'_>,\n    expected_ty: Ty<'_>,\n) -> bool {\n    let expr = peel_blocks(expr).kind;\n\n    if let ty::Int(ty) = expected_ty.kind() {\n        let unsigned = Ty::new_uint(cx.tcx, ty.to_unsigned());\n\n        return if let ExprKind::Cast(expr, cast_ty) = expr\n            && cx.typeck_results().node_type(cast_ty.hir_id) == unsigned\n        {\n            is_sub_expr(cx, expr, expected_a, expected_b, unsigned)\n        } else {\n            false\n        };\n    }\n\n    if let ExprKind::Binary(op, a, b) = expr\n        && let BinOpKind::Sub = op.node\n        && eq_expr_value(cx, a, expected_a)\n        && eq_expr_value(cx, b, expected_b)\n    {\n        true\n    } else {\n        false\n    }\n}\n\nfn is_unsuffixed_numeral_lit(expr: &Expr<'_>) -> bool {\n    matches!(expr.kind, ExprKind::Lit(lit) if lit.node.is_numeric() && lit.node.is_unsuffixed())\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_assert.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{is_panic, root_macro_call};\nuse clippy_utils::source::{indent_of, reindent_multiline};\nuse clippy_utils::{higher, is_else_clause, is_parent_stmt, peel_blocks_with_stmt, span_extract_comment, sugg};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects `if`-then-`panic!` that can be replaced with `assert!`.\n    ///\n    /// ### Why is this bad?\n    /// `assert!` is simpler than `if`-then-`panic!`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let sad_people: Vec<&str> = vec![];\n    /// if !sad_people.is_empty() {\n    ///     panic!(\"there are sad people: {:?}\", sad_people);\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let sad_people: Vec<&str> = vec![];\n    /// assert!(sad_people.is_empty(), \"there are sad people: {:?}\", sad_people);\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub MANUAL_ASSERT,\n    pedantic,\n    \"`panic!` and only a `panic!` in `if`-then statement\"\n}\n\ndeclare_lint_pass!(ManualAssert => [MANUAL_ASSERT]);\n\nimpl<'tcx> LateLintPass<'tcx> for ManualAssert {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if let Some(higher::If { cond, then, r#else: None }) = higher::If::hir(expr)\n            && !matches!(cond.kind, ExprKind::Let(_))\n            && !expr.span.from_expansion()\n            && let then = peel_blocks_with_stmt(then)\n            && let Some(macro_call) = root_macro_call(then.span)\n            && is_panic(cx, macro_call.def_id)\n            && !cx.tcx.sess.source_map().is_multiline(cond.span)\n            && let Ok(panic_snippet) = cx.sess().source_map().span_to_snippet(macro_call.span)\n            && let Some(panic_snippet) = panic_snippet.strip_suffix(')')\n            && let Some((_, format_args_snip)) = panic_snippet.split_once('(')\n            // Don't change `else if foo { panic!(..) }` to `else { assert!(foo, ..) }` as it just\n            // shuffles the condition around.\n            // Should this have a config value?\n            && !is_else_clause(cx.tcx, expr)\n        {\n            span_lint_and_then(\n                cx,\n                MANUAL_ASSERT,\n                expr.span,\n                \"only a `panic!` in `if`-then statement\",\n                |diag| {\n                    let mut applicability = Applicability::MachineApplicable;\n                    let mut comments = span_extract_comment(cx, expr.span);\n                    if !comments.is_empty() {\n                        comments += \"\\n\";\n                    }\n                    let cond_sugg = !sugg::Sugg::hir_with_context(cx, cond, expr.span.ctxt(), \"..\", &mut applicability);\n                    let semicolon = if is_parent_stmt(cx, expr.hir_id) { \";\" } else { \"\" };\n\n                    let indent = indent_of(cx, expr.span);\n                    let full_sugg = reindent_multiline(\n                        format!(\"{comments}assert!({cond_sugg}, {format_args_snip}){semicolon}\").as_str(),\n                        true,\n                        indent,\n                    );\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        \"replace `if`-then-`panic!` with `assert!`\",\n                        full_sugg,\n                        applicability,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_async_fn.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{SpanRangeExt, position_before_rarrow, snippet_block};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{\n    Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,\n    FnRetTy, GenericBound, Node, OpaqueTy, TraitRef, Ty, TyKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::middle::resolve_bound_vars::ResolvedArg;\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// It checks for manual implementations of `async` functions.\n    ///\n    /// ### Why is this bad?\n    /// It's more idiomatic to use the dedicated syntax.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::future::Future;\n    ///\n    /// fn foo() -> impl Future<Output = i32> { async { 42 } }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// async fn foo() -> i32 { 42 }\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub MANUAL_ASYNC_FN,\n    style,\n    \"manual implementations of `async` functions can be simplified using the dedicated syntax\"\n}\n\ndeclare_lint_pass!(ManualAsyncFn => [MANUAL_ASYNC_FN]);\n\nimpl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        span: Span,\n        fn_def_id: LocalDefId,\n    ) {\n        if let Some(header) = kind.header()\n            && !header.asyncness.is_async()\n            // Check that this function returns `impl Future`\n            && let FnRetTy::Return(ret_ty) = decl.output\n            && let TyKind::OpaqueDef(opaque) = ret_ty.kind\n            && let Some(trait_ref) = future_trait_ref(cx, opaque)\n            && let Some(output) = future_output_ty(trait_ref)\n            && captures_all_lifetimes(cx, fn_def_id, opaque.def_id)\n            // Check that the body of the function consists of one async block\n            && let ExprKind::Block(block, _) = body.value.kind\n            && block.stmts.is_empty()\n            && let Some(closure_body) = desugared_async_block(cx, block)\n            && let Some(vis_span_opt) = match cx.tcx.hir_node_by_def_id(fn_def_id) {\n                Node::Item(item) => Some(Some(item.vis_span)),\n                Node::ImplItem(impl_item) => Some(impl_item.vis_span()),\n                _ => None,\n            }\n            && !span.from_expansion()\n        {\n            let header_span = span.with_hi(ret_ty.span.hi());\n\n            span_lint_and_then(\n                cx,\n                MANUAL_ASYNC_FN,\n                header_span,\n                \"this function can be simplified using the `async fn` syntax\",\n                |diag| {\n                    if let Some(vis_span) = vis_span_opt\n                        && let Some(vis_snip) = vis_span.get_source_text(cx)\n                        && let Some(header_snip) = header_span.get_source_text(cx)\n                        && let Some(ret_pos) = position_before_rarrow(&header_snip)\n                        && let Some((_, ret_snip)) = suggested_ret(cx, output)\n                    {\n                        let header_snip = if vis_snip.is_empty() {\n                            format!(\"async {}\", &header_snip[..ret_pos])\n                        } else {\n                            format!(\"{} async {}\", vis_snip, &header_snip[vis_snip.len() + 1..ret_pos])\n                        };\n\n                        let body_snip = snippet_block(cx, closure_body.value.span, \"..\", Some(block.span));\n\n                        diag.multipart_suggestion(\n                            \"make the function `async` and return the output of the future directly\",\n                            vec![\n                                (header_span, format!(\"{header_snip}{ret_snip}\")),\n                                (block.span, body_snip),\n                            ],\n                            Applicability::MachineApplicable,\n                        );\n                    }\n                },\n            );\n        }\n    }\n}\n\nfn future_trait_ref<'tcx>(cx: &LateContext<'tcx>, opaque: &'tcx OpaqueTy<'tcx>) -> Option<&'tcx TraitRef<'tcx>> {\n    if let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {\n        if let GenericBound::Trait(poly) = bound {\n            Some(&poly.trait_ref)\n        } else {\n            None\n        }\n    }) && trait_ref.trait_def_id() == cx.tcx.lang_items().future_trait()\n    {\n        return Some(trait_ref);\n    }\n\n    None\n}\n\nfn future_output_ty<'tcx>(trait_ref: &'tcx TraitRef<'tcx>) -> Option<&'tcx Ty<'tcx>> {\n    if let Some(segment) = trait_ref.path.segments.last()\n        && let Some(args) = segment.args\n        && let [constraint] = args.constraints\n        && constraint.ident.name == sym::Output\n        && let Some(output) = constraint.ty()\n    {\n        return Some(output);\n    }\n\n    None\n}\n\nfn captures_all_lifetimes(cx: &LateContext<'_>, fn_def_id: LocalDefId, opaque_def_id: LocalDefId) -> bool {\n    let early_input_params = ty::GenericArgs::identity_for_item(cx.tcx, fn_def_id);\n    let late_input_params = cx.tcx.late_bound_vars(cx.tcx.local_def_id_to_hir_id(fn_def_id));\n\n    let num_early_lifetimes = early_input_params\n        .iter()\n        .filter(|param| param.as_region().is_some())\n        .count();\n    let num_late_lifetimes = late_input_params\n        .iter()\n        .filter(|param_kind| matches!(param_kind, ty::BoundVariableKind::Region(_)))\n        .count();\n\n    // There is no lifetime, so they are all captured.\n    if num_early_lifetimes == 0 && num_late_lifetimes == 0 {\n        return true;\n    }\n\n    // By construction, each captured lifetime only appears once in `opaque_captured_lifetimes`.\n    let num_captured_lifetimes = cx\n        .tcx\n        .opaque_captured_lifetimes(opaque_def_id)\n        .iter()\n        .filter(|&(lifetime, _)| {\n            matches!(\n                *lifetime,\n                ResolvedArg::EarlyBound(_) | ResolvedArg::LateBound(ty::INNERMOST, _, _)\n            )\n        })\n        .count();\n    num_captured_lifetimes == num_early_lifetimes + num_late_lifetimes\n}\n\nfn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> {\n    if let Some(&Expr {\n        kind: ExprKind::Closure(&Closure { kind, body, .. }),\n        ..\n    }) = block.expr\n        && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Block)) =\n            kind\n    {\n        return Some(cx.tcx.hir_body(body));\n    }\n\n    None\n}\n\nfn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str, String)> {\n    if let TyKind::Tup([]) = output.kind {\n        let sugg = \"remove the return type\";\n        Some((sugg, String::new()))\n    } else {\n        let sugg = \"return the output of the future directly\";\n        output.span.get_source_text(cx).map(|src| (sugg, format!(\" -> {src}\")))\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_bits.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{get_parent_expr, sym};\nuse rustc_ast::ast::LitKind;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `size_of::<T>() * 8` when\n    /// `T::BITS` is available.\n    ///\n    /// ### Why is this bad?\n    /// Can be written as the shorter `T::BITS`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// size_of::<usize>() * 8;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// usize::BITS as usize;\n    /// ```\n    #[clippy::version = \"1.60.0\"]\n    pub MANUAL_BITS,\n    style,\n    \"manual implementation of `size_of::<T>() * 8` can be simplified with `T::BITS`\"\n}\n\nimpl_lint_pass!(ManualBits => [MANUAL_BITS]);\n\npub struct ManualBits {\n    msrv: Msrv,\n}\n\nimpl ManualBits {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualBits {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Binary(bin_op, left_expr, right_expr) = expr.kind\n            && let BinOpKind::Mul = &bin_op.node\n            && !expr.span.from_expansion()\n            && let ctxt = expr.span.ctxt()\n            && left_expr.span.ctxt() == ctxt\n            && right_expr.span.ctxt() == ctxt\n            && let Some((real_ty_span, resolved_ty, other_expr)) = get_one_size_of_ty(cx, left_expr, right_expr)\n            && matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_))\n            && let ExprKind::Lit(lit) = &other_expr.kind\n            && let LitKind::Int(Pu128(8), _) = lit.node\n            && self.msrv.meets(cx, msrvs::INTEGER_BITS)\n        {\n            let mut app = Applicability::MachineApplicable;\n            let ty_snip = snippet_with_context(cx, real_ty_span, ctxt, \"..\", &mut app).0;\n            let sugg = create_sugg(cx, expr, format!(\"{ty_snip}::BITS\"));\n\n            span_lint_and_sugg(\n                cx,\n                MANUAL_BITS,\n                expr.span,\n                \"usage of `size_of::<T>()` to obtain the size of `T` in bits\",\n                \"consider using\",\n                sugg,\n                app,\n            );\n        }\n    }\n}\n\nfn get_one_size_of_ty<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr1: &'tcx Expr<'_>,\n    expr2: &'tcx Expr<'_>,\n) -> Option<(Span, Ty<'tcx>, &'tcx Expr<'tcx>)> {\n    match (get_size_of_ty(cx, expr1), get_size_of_ty(cx, expr2)) {\n        (Some((real_ty_span, resolved_ty)), None) => Some((real_ty_span, resolved_ty, expr2)),\n        (None, Some((real_ty_span, resolved_ty))) => Some((real_ty_span, resolved_ty, expr1)),\n        _ => None,\n    }\n}\n\nfn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<(Span, Ty<'tcx>)> {\n    if let ExprKind::Call(count_func, []) = expr.kind\n        && let ExprKind::Path(ref count_func_qpath) = count_func.kind\n        && let QPath::Resolved(_, count_func_path) = count_func_qpath\n        && let Some(segment_zero) = count_func_path.segments.first()\n        && let Some(args) = segment_zero.args\n        && let Some(real_ty_span) = args.args.first().map(GenericArg::span)\n        && let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id()\n        && cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id)\n    {\n        cx.typeck_results()\n            .node_args(count_func.hir_id)\n            .types()\n            .next()\n            .map(|resolved_ty| (real_ty_span, resolved_ty))\n    } else {\n        None\n    }\n}\n\nfn create_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, base_sugg: String) -> String {\n    if let Some(parent_expr) = get_parent_expr(cx, expr) {\n        if is_ty_conversion(parent_expr) {\n            return base_sugg;\n        }\n\n        // These expressions have precedence over casts, the suggestion therefore\n        // needs to be wrapped into parentheses\n        match parent_expr.kind {\n            ExprKind::Unary(..) | ExprKind::AddrOf(..) | ExprKind::MethodCall(..) => {\n                return format!(\"({base_sugg} as usize)\");\n            },\n            _ => {},\n        }\n    }\n\n    format!(\"{base_sugg} as usize\")\n}\n\nfn is_ty_conversion(expr: &Expr<'_>) -> bool {\n    if let ExprKind::Cast(..) = expr.kind {\n        true\n    } else if let ExprKind::MethodCall(path, _, [], _) = expr.kind\n        && path.ident.name == sym::try_into\n    {\n        // This is only called for `usize` which implements `TryInto`. Therefore,\n        // we don't have to check here if `self` implements the `TryInto` trait.\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_checked_ops.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::visitors::{Descend, for_each_expr_without_closures};\nuse clippy_utils::{SpanlessEq, is_integer_literal};\nuse rustc_hir::{AssignOpKind, BinOpKind, Block, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects manual zero checks before dividing integers, such as `if x != 0 { y / x }`.\n    ///\n    /// ### Why is this bad?\n    /// `checked_div` already handles the zero case and makes the intent clearer while avoiding a\n    /// panic from a manual division.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let (a, b) = (10u32, 5u32);\n    /// if b != 0 {\n    ///     let result = a / b;\n    ///     println!(\"{result}\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let (a, b) = (10u32, 5u32);\n    /// if let Some(result) = a.checked_div(b) {\n    ///     println!(\"{result}\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.95.0\"]\n    pub MANUAL_CHECKED_OPS,\n    complexity,\n    \"manual zero checks before dividing integers\"\n}\n\ndeclare_lint_pass!(ManualCheckedOps => [MANUAL_CHECKED_OPS]);\n\n#[derive(Copy, Clone)]\nenum NonZeroBranch {\n    Then,\n    Else,\n}\n\nimpl LateLintPass<'_> for ManualCheckedOps {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if let ExprKind::If(cond, then, r#else) = expr.kind\n            && !expr.span.from_expansion()\n            && let Some((divisor, branch)) = divisor_from_condition(cond)\n            // This lint is intended for unsigned integers only.\n            //\n            // For signed integers, the most direct refactor to `checked_div` is often not\n            // semantically equivalent to the original guard. For example, `rhs > 0` deliberately\n            // excludes negative divisors, while `checked_div` would return `Some` for `rhs = -2`.\n            // Also, `checked_div` can return `None` for `MIN / -1`, which requires additional\n            // handling beyond the zero check.\n            && is_unsigned_integer(cx, divisor)\n            && let Some(block) = branch_block(then, r#else, branch)\n        {\n            let mut eq = SpanlessEq::new(cx).deny_side_effects().paths_by_resolution();\n            if !eq.eq_expr(divisor, divisor) {\n                return;\n            }\n\n            let mut division_spans = Vec::new();\n            let mut first_use = None;\n\n            let found_early_use = for_each_expr_without_closures(block, |e| {\n                if let ExprKind::Binary(binop, lhs, rhs) = e.kind\n                    && binop.node == BinOpKind::Div\n                    && eq.eq_expr(rhs, divisor)\n                    && is_unsigned_integer(cx, lhs)\n                {\n                    match first_use {\n                        None => first_use = Some(UseKind::Division),\n                        Some(UseKind::Other) => return ControlFlow::Break(()),\n                        Some(UseKind::Division) => {},\n                    }\n\n                    division_spans.push(e.span);\n\n                    ControlFlow::<(), _>::Continue(Descend::No)\n                } else if let ExprKind::AssignOp(op, lhs, rhs) = e.kind\n                    && op.node == AssignOpKind::DivAssign\n                    && eq.eq_expr(rhs, divisor)\n                    && is_unsigned_integer(cx, lhs)\n                {\n                    match first_use {\n                        None => first_use = Some(UseKind::Division),\n                        Some(UseKind::Other) => return ControlFlow::Break(()),\n                        Some(UseKind::Division) => {},\n                    }\n\n                    division_spans.push(e.span);\n\n                    ControlFlow::<(), _>::Continue(Descend::No)\n                } else if eq.eq_expr(e, divisor) {\n                    if first_use.is_none() {\n                        first_use = Some(UseKind::Other);\n                        return ControlFlow::Break(());\n                    }\n                    ControlFlow::<(), _>::Continue(Descend::Yes)\n                } else {\n                    ControlFlow::<(), _>::Continue(Descend::Yes)\n                }\n            });\n\n            if found_early_use.is_some() || first_use != Some(UseKind::Division) || division_spans.is_empty() {\n                return;\n            }\n\n            span_lint_and_then(cx, MANUAL_CHECKED_OPS, cond.span, \"manual checked division\", |diag| {\n                diag.span_label(cond.span, \"check performed here\");\n                if let Some((first, rest)) = division_spans.split_first() {\n                    diag.span_label(*first, \"division performed here\");\n                    if !rest.is_empty() {\n                        diag.span_labels(rest.to_vec(), \"... and here\");\n                    }\n                }\n                diag.help(\"consider using `checked_div`\");\n            });\n        }\n    }\n}\n\n#[derive(Copy, Clone, Eq, PartialEq)]\nenum UseKind {\n    Division,\n    Other,\n}\n\nfn divisor_from_condition<'tcx>(cond: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, NonZeroBranch)> {\n    let ExprKind::Binary(binop, lhs, rhs) = cond.kind else {\n        return None;\n    };\n\n    match binop.node {\n        BinOpKind::Ne | BinOpKind::Lt if is_zero(lhs) => Some((rhs, NonZeroBranch::Then)),\n        BinOpKind::Ne | BinOpKind::Gt if is_zero(rhs) => Some((lhs, NonZeroBranch::Then)),\n        BinOpKind::Eq if is_zero(lhs) => Some((rhs, NonZeroBranch::Else)),\n        BinOpKind::Eq if is_zero(rhs) => Some((lhs, NonZeroBranch::Else)),\n        _ => None,\n    }\n}\n\nfn branch_block<'tcx>(\n    then: &'tcx Expr<'tcx>,\n    r#else: Option<&'tcx Expr<'tcx>>,\n    branch: NonZeroBranch,\n) -> Option<&'tcx Block<'tcx>> {\n    match branch {\n        NonZeroBranch::Then => match then.kind {\n            ExprKind::Block(block, _) => Some(block),\n            _ => None,\n        },\n        NonZeroBranch::Else => match r#else?.kind {\n            ExprKind::Block(block, _) => Some(block),\n            _ => None,\n        },\n    }\n}\n\nfn is_zero(expr: &Expr<'_>) -> bool {\n    is_integer_literal(expr, 0)\n}\n\nfn is_unsigned_integer(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    matches!(cx.typeck_results().expr_ty(expr).peel_refs().kind(), ty::Uint(_))\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_clamp.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};\nuse clippy_utils::higher::If;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::visitors::is_const_evaluatable;\nuse clippy_utils::{eq_expr_value, is_in_const_context, peel_blocks, peel_blocks_with_stmt, sym};\nuse itertools::Itertools;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::def::Res;\nuse rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse std::cmp::Ordering;\nuse std::ops::Deref;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Identifies good opportunities for a clamp function from std or core, and suggests using it.\n    ///\n    /// ### Why is this bad?\n    /// clamp is much shorter, easier to read, and doesn't use any control flow.\n    ///\n    /// ### Limitations\n    ///\n    /// This lint will only trigger if max and min are known at compile time, and max is\n    /// greater than min.\n    ///\n    /// ### Known issue(s)\n    /// If the clamped variable is NaN this suggestion will cause the code to propagate NaN\n    /// rather than returning either `max` or `min`.\n    ///\n    /// `clamp` functions will panic if `max < min`, `max.is_nan()`, or `min.is_nan()`.\n    /// Some may consider panicking in these situations to be desirable, but it also may\n    /// introduce panicking where there wasn't any before.\n    ///\n    /// See also [the discussion in the\n    /// PR](https://github.com/rust-lang/rust-clippy/pull/9484#issuecomment-1278922613).\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// # let (input, min, max) = (0, -2, 1);\n    /// if input > max {\n    ///     max\n    /// } else if input < min {\n    ///     min\n    /// } else {\n    ///     input\n    /// }\n    /// # ;\n    /// ```\n    ///\n    /// ```no_run\n    /// # let (input, min, max) = (0, -2, 1);\n    /// input.max(min).min(max)\n    /// # ;\n    /// ```\n    ///\n    /// ```no_run\n    /// # let (input, min, max) = (0, -2, 1);\n    /// match input {\n    ///     x if x > max => max,\n    ///     x if x < min => min,\n    ///     x => x,\n    /// }\n    /// # ;\n    /// ```\n    ///\n    /// ```no_run\n    /// # let (input, min, max) = (0, -2, 1);\n    /// let mut x = input;\n    /// if x < min { x = min; }\n    /// if x > max { x = max; }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let (input, min, max) = (0, -2, 1);\n    /// input.clamp(min, max)\n    /// # ;\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub MANUAL_CLAMP,\n    complexity,\n    \"using a clamp pattern instead of the clamp function\"\n}\n\nimpl_lint_pass!(ManualClamp => [MANUAL_CLAMP]);\n\npub struct ManualClamp {\n    msrv: Msrv,\n}\n\nimpl ManualClamp {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\n#[derive(Debug)]\nstruct ClampSuggestion<'tcx> {\n    params: InputMinMax<'tcx>,\n    span: Span,\n    make_assignment: Option<&'tcx Expr<'tcx>>,\n    hir_with_ignore_attr: Option<HirId>,\n}\n\nimpl<'tcx> ClampSuggestion<'tcx> {\n    /// This function will return true if and only if you can demonstrate at compile time that min\n    /// is less than max.\n    fn min_less_than_max(&self, cx: &LateContext<'tcx>) -> bool {\n        let max_type = cx.typeck_results().expr_ty(self.params.max);\n        let min_type = cx.typeck_results().expr_ty(self.params.min);\n        if max_type != min_type {\n            return false;\n        }\n        let ecx = ConstEvalCtxt::new(cx);\n        if let Some(max) = ecx.eval(self.params.max)\n            && let Some(min) = ecx.eval(self.params.min)\n            && let Some(ord) = Constant::partial_cmp(cx.tcx, max_type, &min, &max)\n        {\n            ord != Ordering::Greater\n        } else {\n            false\n        }\n    }\n}\n\n#[derive(Debug)]\nstruct InputMinMax<'tcx> {\n    input: &'tcx Expr<'tcx>,\n    min: &'tcx Expr<'tcx>,\n    max: &'tcx Expr<'tcx>,\n    is_float: bool,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualClamp {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if !expr.span.from_expansion() && !is_in_const_context(cx) {\n            let suggestion = is_if_elseif_else_pattern(cx, expr)\n                .or_else(|| is_max_min_pattern(cx, expr))\n                .or_else(|| is_call_max_min_pattern(cx, expr))\n                .or_else(|| is_match_pattern(cx, expr))\n                .or_else(|| is_if_elseif_pattern(cx, expr));\n            if let Some(suggestion) = suggestion\n                && self.msrv.meets(cx, msrvs::CLAMP)\n            {\n                maybe_emit_suggestion(cx, &suggestion);\n            }\n        }\n    }\n\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {\n        if is_in_const_context(cx) || !self.msrv.meets(cx, msrvs::CLAMP) {\n            return;\n        }\n        for suggestion in is_two_if_pattern(cx, block) {\n            maybe_emit_suggestion(cx, &suggestion);\n        }\n    }\n}\n\nfn maybe_emit_suggestion<'tcx>(cx: &LateContext<'tcx>, suggestion: &ClampSuggestion<'tcx>) {\n    if !suggestion.min_less_than_max(cx) {\n        return;\n    }\n    let ClampSuggestion {\n        params: InputMinMax {\n            input,\n            min,\n            max,\n            is_float,\n        },\n        span,\n        make_assignment,\n        hir_with_ignore_attr,\n    } = suggestion;\n    let input = Sugg::hir(cx, input, \"..\").maybe_paren();\n    let min = Sugg::hir(cx, min, \"..\");\n    let max = Sugg::hir(cx, max, \"..\");\n    let semicolon = if make_assignment.is_some() { \";\" } else { \"\" };\n    let assignment = if let Some(assignment) = make_assignment {\n        let assignment = Sugg::hir(cx, assignment, \"..\");\n        format!(\"{assignment} = \")\n    } else {\n        String::new()\n    };\n    let suggestion = format!(\"{assignment}{input}.clamp({min}, {max}){semicolon}\");\n    let msg = \"clamp-like pattern without using clamp function\";\n    let lint_builder = |d: &mut Diag<'_, ()>| {\n        d.span_suggestion(*span, \"replace with clamp\", suggestion, Applicability::MaybeIncorrect);\n        if *is_float {\n            d.note(\"clamp will panic if max < min, min.is_nan(), or max.is_nan()\")\n                .note(\"clamp returns NaN if the input is NaN\");\n        } else {\n            d.note(\"clamp will panic if max < min\");\n        }\n    };\n    if let Some(hir_id) = hir_with_ignore_attr {\n        span_lint_hir_and_then(cx, MANUAL_CLAMP, *hir_id, *span, msg, lint_builder);\n    } else {\n        span_lint_and_then(cx, MANUAL_CLAMP, *span, msg, lint_builder);\n    }\n}\n\n#[derive(Debug, Copy, Clone, Eq, PartialEq)]\nenum TypeClampability {\n    Float,\n    Ord,\n}\n\nimpl TypeClampability {\n    fn is_clampable<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<TypeClampability> {\n        if ty.is_floating_point() {\n            Some(TypeClampability::Float)\n        } else if cx\n            .tcx\n            .get_diagnostic_item(sym::Ord)\n            .is_some_and(|id| implements_trait(cx, ty, id, &[]))\n        {\n            Some(TypeClampability::Ord)\n        } else {\n            None\n        }\n    }\n\n    fn is_float(self) -> bool {\n        matches!(self, TypeClampability::Float)\n    }\n}\n\n/// Targets patterns like\n///\n/// ```no_run\n/// # let (input, min, max) = (0, -3, 12);\n///\n/// if input < min {\n///     min\n/// } else if input > max {\n///     max\n/// } else {\n///     input\n/// }\n/// # ;\n/// ```\nfn is_if_elseif_else_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<ClampSuggestion<'tcx>> {\n    if let Some(If {\n        cond,\n        then,\n        r#else: Some(else_if),\n    }) = If::hir(expr)\n        && let Some(If {\n            cond: else_if_cond,\n            then: else_if_then,\n            r#else: Some(else_body),\n        }) = If::hir(peel_blocks(else_if))\n    {\n        let params = is_clamp_meta_pattern(\n            cx,\n            &BinaryOp::new(peel_blocks(cond))?,\n            &BinaryOp::new(peel_blocks(else_if_cond))?,\n            peel_blocks(then),\n            peel_blocks(else_if_then),\n            None,\n        )?;\n        // Contents of the else should be the resolved input.\n        if !eq_expr_value(cx, params.input, peel_blocks(else_body)) {\n            return None;\n        }\n        Some(ClampSuggestion {\n            params,\n            span: expr.span,\n            make_assignment: None,\n            hir_with_ignore_attr: None,\n        })\n    } else {\n        None\n    }\n}\n\n/// Targets patterns like\n///\n/// ```no_run\n/// # let (input, min_value, max_value) = (0, -3, 12);\n///\n/// input.max(min_value).min(max_value)\n/// # ;\n/// ```\nfn is_max_min_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<ClampSuggestion<'tcx>> {\n    if let ExprKind::MethodCall(seg_second, receiver, [arg_second], _) = expr.kind\n        && (cx.typeck_results().expr_ty_adjusted(receiver).is_floating_point()\n            || cx.ty_based_def(expr).assoc_fn_parent(cx).is_diag_item(cx, sym::Ord))\n        && let ExprKind::MethodCall(seg_first, input, [arg_first], _) = &receiver.kind\n        && (cx.typeck_results().expr_ty_adjusted(input).is_floating_point()\n            || cx.ty_based_def(receiver).assoc_fn_parent(cx).is_diag_item(cx, sym::Ord))\n    {\n        let is_float = cx.typeck_results().expr_ty_adjusted(input).is_floating_point();\n        let (min, max) = match (seg_first.ident.name, seg_second.ident.name) {\n            (sym::min, sym::max) => (arg_second, arg_first),\n            (sym::max, sym::min) => (arg_first, arg_second),\n            _ => return None,\n        };\n        Some(ClampSuggestion {\n            params: InputMinMax {\n                input,\n                min,\n                max,\n                is_float,\n            },\n            span: expr.span,\n            make_assignment: None,\n            hir_with_ignore_attr: None,\n        })\n    } else {\n        None\n    }\n}\n\n/// Targets patterns like\n///\n/// ```no_run\n/// # let (input, min_value, max_value) = (0, -3, 12);\n/// # use std::cmp::{max, min};\n/// min(max(input, min_value), max_value)\n/// # ;\n/// ```\nfn is_call_max_min_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<ClampSuggestion<'tcx>> {\n    fn segment<'tcx>(cx: &LateContext<'_>, func: &Expr<'tcx>) -> Option<FunctionType<'tcx>> {\n        match func.kind {\n            ExprKind::Path(QPath::Resolved(None, path)) => {\n                let def = path.res.opt_def(cx)?;\n                match cx.tcx.get_diagnostic_name(def.1) {\n                    Some(sym::cmp_min) => Some(FunctionType::CmpMin),\n                    Some(sym::cmp_max) => Some(FunctionType::CmpMax),\n                    _ if def.assoc_fn_parent(cx).is_diag_item(cx, sym::Ord) => {\n                        Some(FunctionType::OrdOrFloat(path.segments.last().expect(\"infallible\")))\n                    },\n                    _ => None,\n                }\n            },\n            ExprKind::Path(QPath::TypeRelative(ty, seg)) => {\n                matches!(ty.basic_res(), Res::PrimTy(PrimTy::Float(_))).then(|| FunctionType::OrdOrFloat(seg))\n            },\n            _ => None,\n        }\n    }\n\n    enum FunctionType<'tcx> {\n        CmpMin,\n        CmpMax,\n        OrdOrFloat(&'tcx PathSegment<'tcx>),\n    }\n\n    fn check<'tcx>(\n        cx: &LateContext<'tcx>,\n        outer_fn: &'tcx Expr<'tcx>,\n        inner_call: &'tcx Expr<'tcx>,\n        outer_arg: &'tcx Expr<'tcx>,\n        span: Span,\n    ) -> Option<ClampSuggestion<'tcx>> {\n        if let ExprKind::Call(inner_fn, [first, second]) = &inner_call.kind\n            && let Some(inner_seg) = segment(cx, inner_fn)\n            && let Some(outer_seg) = segment(cx, outer_fn)\n        {\n            let (input, inner_arg) = match (is_const_evaluatable(cx, first), is_const_evaluatable(cx, second)) {\n                (true, false) => (second, first),\n                (false, true) => (first, second),\n                _ => return None,\n            };\n            let is_float = cx.typeck_results().expr_ty_adjusted(input).is_floating_point();\n            let (min, max) = match (inner_seg, outer_seg) {\n                (FunctionType::CmpMin, FunctionType::CmpMax) => (outer_arg, inner_arg),\n                (FunctionType::CmpMax, FunctionType::CmpMin) => (inner_arg, outer_arg),\n                (FunctionType::OrdOrFloat(first_segment), FunctionType::OrdOrFloat(second_segment)) => {\n                    match (first_segment.ident.as_str(), second_segment.ident.as_str()) {\n                        (\"min\", \"max\") => (outer_arg, inner_arg),\n                        (\"max\", \"min\") => (inner_arg, outer_arg),\n                        _ => return None,\n                    }\n                },\n                _ => return None,\n            };\n            Some(ClampSuggestion {\n                params: InputMinMax {\n                    input,\n                    min,\n                    max,\n                    is_float,\n                },\n                span,\n                make_assignment: None,\n                hir_with_ignore_attr: None,\n            })\n        } else {\n            None\n        }\n    }\n\n    if let ExprKind::Call(outer_fn, [first, second]) = &expr.kind {\n        check(cx, outer_fn, first, second, expr.span).or_else(|| check(cx, outer_fn, second, first, expr.span))\n    } else {\n        None\n    }\n}\n\n/// Targets patterns like\n///\n/// ```no_run\n/// # let (input, min, max) = (0, -3, 12);\n///\n/// match input {\n///     input if input > max => max,\n///     input if input < min => min,\n///     input => input,\n/// }\n/// # ;\n/// ```\nfn is_match_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<ClampSuggestion<'tcx>> {\n    if let ExprKind::Match(value, [first_arm, second_arm, last_arm], rustc_hir::MatchSource::Normal) = &expr.kind {\n        // Find possible min/max branches\n        let minmax_values = |a: &'tcx Arm<'tcx>| {\n            if let PatKind::Binding(_, var_hir_id, _, None) = &a.pat.kind\n                && let Some(e) = a.guard\n            {\n                Some((e, var_hir_id, a.body))\n            } else {\n                None\n            }\n        };\n        let (first, first_hir_id, first_expr) = minmax_values(first_arm)?;\n        let (second, second_hir_id, second_expr) = minmax_values(second_arm)?;\n        let first = BinaryOp::new(first)?;\n        let second = BinaryOp::new(second)?;\n        if let PatKind::Binding(_, binding, _, None) = &last_arm.pat.kind\n            && peel_blocks_with_stmt(last_arm.body).res_local_id() == Some(*binding)\n            && last_arm.guard.is_none()\n        {\n            // Proceed as normal\n        } else {\n            return None;\n        }\n        if let Some(params) = is_clamp_meta_pattern(\n            cx,\n            &first,\n            &second,\n            first_expr,\n            second_expr,\n            Some((*first_hir_id, *second_hir_id)),\n        ) {\n            return Some(ClampSuggestion {\n                params: InputMinMax {\n                    input: value,\n                    min: params.min,\n                    max: params.max,\n                    is_float: params.is_float,\n                },\n                span: expr.span,\n                make_assignment: None,\n                hir_with_ignore_attr: None,\n            });\n        }\n    }\n    None\n}\n\n/// Targets patterns like\n///\n/// ```no_run\n/// # let (input, min, max) = (0, -3, 12);\n///\n/// let mut x = input;\n/// if x < min { x = min; }\n/// if x > max { x = max; }\n/// ```\nfn is_two_if_pattern<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Vec<ClampSuggestion<'tcx>> {\n    block_stmt_with_last(block)\n        .tuple_windows()\n        .filter_map(|(maybe_set_first, maybe_set_second)| {\n            if let StmtKind::Expr(first_expr) = *maybe_set_first\n                && let StmtKind::Expr(second_expr) = *maybe_set_second\n                && let Some(If {\n                    cond: first_cond,\n                    then: first_then,\n                    r#else: None,\n                }) = If::hir(first_expr)\n                && let Some(If {\n                    cond: second_cond,\n                    then: second_then,\n                    r#else: None,\n                }) = If::hir(second_expr)\n                && let ExprKind::Assign(maybe_input_first_path, maybe_min_max_first, _) =\n                    peel_blocks_with_stmt(first_then).kind\n                && let ExprKind::Assign(maybe_input_second_path, maybe_min_max_second, _) =\n                    peel_blocks_with_stmt(second_then).kind\n                && eq_expr_value(cx, maybe_input_first_path, maybe_input_second_path)\n                && let Some(first_bin) = BinaryOp::new(first_cond)\n                && let Some(second_bin) = BinaryOp::new(second_cond)\n                && let Some(input_min_max) = is_clamp_meta_pattern(\n                    cx,\n                    &first_bin,\n                    &second_bin,\n                    maybe_min_max_first,\n                    maybe_min_max_second,\n                    None,\n                )\n            {\n                Some(ClampSuggestion {\n                    params: InputMinMax {\n                        input: maybe_input_first_path,\n                        min: input_min_max.min,\n                        max: input_min_max.max,\n                        is_float: input_min_max.is_float,\n                    },\n                    span: first_expr.span.to(second_expr.span),\n                    make_assignment: Some(maybe_input_first_path),\n                    hir_with_ignore_attr: Some(first_expr.hir_id),\n                })\n            } else {\n                None\n            }\n        })\n        .collect()\n}\n\n/// Targets patterns like\n///\n/// ```no_run\n/// # let (mut input, min, max) = (0, -3, 12);\n///\n/// if input < min {\n///     input = min;\n/// } else if input > max {\n///     input = max;\n/// }\n/// ```\nfn is_if_elseif_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<ClampSuggestion<'tcx>> {\n    if let Some(If {\n        cond,\n        then,\n        r#else: Some(else_if),\n    }) = If::hir(expr)\n        && let Some(If {\n            cond: else_if_cond,\n            then: else_if_then,\n            r#else: None,\n        }) = If::hir(peel_blocks(else_if))\n        && let ExprKind::Assign(maybe_input_first_path, maybe_min_max_first, _) = peel_blocks_with_stmt(then).kind\n        && let ExprKind::Assign(maybe_input_second_path, maybe_min_max_second, _) =\n            peel_blocks_with_stmt(else_if_then).kind\n    {\n        let params = is_clamp_meta_pattern(\n            cx,\n            &BinaryOp::new(peel_blocks(cond))?,\n            &BinaryOp::new(peel_blocks(else_if_cond))?,\n            peel_blocks(maybe_min_max_first),\n            peel_blocks(maybe_min_max_second),\n            None,\n        )?;\n        if !eq_expr_value(cx, maybe_input_first_path, maybe_input_second_path) {\n            return None;\n        }\n        Some(ClampSuggestion {\n            params,\n            span: expr.span,\n            make_assignment: Some(maybe_input_first_path),\n            hir_with_ignore_attr: None,\n        })\n    } else {\n        None\n    }\n}\n\n/// `ExprKind::Binary` but more narrowly typed\n#[derive(Debug, Clone, Copy)]\nstruct BinaryOp<'tcx> {\n    op: BinOpKind,\n    left: &'tcx Expr<'tcx>,\n    right: &'tcx Expr<'tcx>,\n}\n\nimpl<'tcx> BinaryOp<'tcx> {\n    fn new(e: &'tcx Expr<'tcx>) -> Option<BinaryOp<'tcx>> {\n        match &e.kind {\n            ExprKind::Binary(op, left, right) => Some(BinaryOp {\n                op: op.node,\n                left,\n                right,\n            }),\n            _ => None,\n        }\n    }\n\n    fn flip(&self) -> Self {\n        Self {\n            op: match self.op {\n                BinOpKind::Le => BinOpKind::Ge,\n                BinOpKind::Lt => BinOpKind::Gt,\n                BinOpKind::Ge => BinOpKind::Le,\n                BinOpKind::Gt => BinOpKind::Lt,\n                other => other,\n            },\n            left: self.right,\n            right: self.left,\n        }\n    }\n}\n\n/// The clamp meta pattern is a pattern shared between many (but not all) patterns.\n/// In summary, this pattern consists of two if statements that meet many criteria,\n///\n/// - binary operators that are one of [`>`, `<`, `>=`, `<=`].\n///\n/// - Both binary statements must have a shared argument\n///\n///     - Which can appear on the left or right side of either statement\n///\n///     - The binary operators must define a finite range for the shared argument. To put this in\n///       the terms of Rust `std` library, the following ranges are acceptable\n///\n///         - `Range`\n///         - `RangeInclusive`\n///\n///       And all other range types are not accepted. For the purposes of `clamp` it's irrelevant\n///       whether the range is inclusive or not, the output is the same.\n///\n/// - The result of each if statement must be equal to the argument unique to that if statement. The\n///   result can not be the shared argument in either case.\nfn is_clamp_meta_pattern<'tcx>(\n    cx: &LateContext<'tcx>,\n    first_bin: &BinaryOp<'tcx>,\n    second_bin: &BinaryOp<'tcx>,\n    first_expr: &'tcx Expr<'tcx>,\n    second_expr: &'tcx Expr<'tcx>,\n    // This parameters is exclusively for the match pattern.\n    // It exists because the variable bindings used in that pattern\n    // refer to the variable bound in the match arm, not the variable\n    // bound outside of it. Fortunately due to context we know this has to\n    // be the input variable, not the min or max.\n    input_hir_ids: Option<(HirId, HirId)>,\n) -> Option<InputMinMax<'tcx>> {\n    fn check<'tcx>(\n        cx: &LateContext<'tcx>,\n        first_bin: &BinaryOp<'tcx>,\n        second_bin: &BinaryOp<'tcx>,\n        first_expr: &'tcx Expr<'tcx>,\n        second_expr: &'tcx Expr<'tcx>,\n        input_hir_ids: Option<(HirId, HirId)>,\n        is_float: bool,\n    ) -> Option<InputMinMax<'tcx>> {\n        match (&first_bin.op, &second_bin.op) {\n            (BinOpKind::Ge | BinOpKind::Gt, BinOpKind::Le | BinOpKind::Lt) => {\n                let (min, max) = (second_expr, first_expr);\n                let refers_to_input = match input_hir_ids {\n                    Some((first_hir_id, second_hir_id)) => {\n                        peel_blocks(first_bin.left).res_local_id() == Some(first_hir_id)\n                            && peel_blocks(second_bin.left).res_local_id() == Some(second_hir_id)\n                    },\n                    None => eq_expr_value(cx, first_bin.left, second_bin.left),\n                };\n                (refers_to_input\n                    && eq_expr_value(cx, first_bin.right, first_expr)\n                    && eq_expr_value(cx, second_bin.right, second_expr))\n                .then_some(InputMinMax {\n                    input: first_bin.left,\n                    min,\n                    max,\n                    is_float,\n                })\n            },\n            _ => None,\n        }\n    }\n    // First filter out any expressions with side effects\n    let exprs = [\n        first_bin.left,\n        first_bin.right,\n        second_bin.left,\n        second_bin.right,\n        first_expr,\n        second_expr,\n    ];\n    let clampability = TypeClampability::is_clampable(cx, cx.typeck_results().expr_ty(first_expr))?;\n    let is_float = clampability.is_float();\n    if exprs.iter().any(|e| peel_blocks(e).can_have_side_effects()) {\n        return None;\n    }\n    if !(is_ord_op(first_bin.op) && is_ord_op(second_bin.op)) {\n        return None;\n    }\n    let cases = [\n        (*first_bin, *second_bin),\n        (first_bin.flip(), second_bin.flip()),\n        (first_bin.flip(), *second_bin),\n        (*first_bin, second_bin.flip()),\n    ];\n\n    cases.into_iter().find_map(|(first, second)| {\n        check(cx, &first, &second, first_expr, second_expr, input_hir_ids, is_float).or_else(|| {\n            check(\n                cx,\n                &second,\n                &first,\n                second_expr,\n                first_expr,\n                input_hir_ids.map(|(l, r)| (r, l)),\n                is_float,\n            )\n        })\n    })\n}\n\nfn block_stmt_with_last<'tcx>(block: &'tcx Block<'tcx>) -> impl Iterator<Item = MaybeBorrowedStmtKind<'tcx>> {\n    block\n        .stmts\n        .iter()\n        .map(|s| MaybeBorrowedStmtKind::Borrowed(&s.kind))\n        .chain(\n            block\n                .expr\n                .as_ref()\n                .map(|e| MaybeBorrowedStmtKind::Owned(StmtKind::Expr(e))),\n        )\n}\n\nfn is_ord_op(op: BinOpKind) -> bool {\n    matches!(op, BinOpKind::Ge | BinOpKind::Gt | BinOpKind::Le | BinOpKind::Lt)\n}\n\n/// Really similar to Cow, but doesn't have a `Clone` requirement.\n#[derive(Debug)]\nenum MaybeBorrowedStmtKind<'a> {\n    Borrowed(&'a StmtKind<'a>),\n    Owned(StmtKind<'a>),\n}\n\nimpl Clone for MaybeBorrowedStmtKind<'_> {\n    fn clone(&self) -> Self {\n        match self {\n            Self::Borrowed(t) => Self::Borrowed(t),\n            Self::Owned(StmtKind::Expr(e)) => Self::Owned(StmtKind::Expr(e)),\n            Self::Owned(_) => unreachable!(\"Owned should only ever contain a StmtKind::Expr.\"),\n        }\n    }\n}\n\nimpl<'a> Deref for MaybeBorrowedStmtKind<'a> {\n    type Target = StmtKind<'a>;\n\n    fn deref(&self) -> &Self::Target {\n        match self {\n            Self::Borrowed(t) => t,\n            Self::Owned(t) => t,\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_float_methods.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::DefKind;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{BinOpKind, Constness, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass, Lint, LintContext};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual `is_finite` reimplementations\n    /// (i.e., `x != <float>::INFINITY && x != <float>::NEG_INFINITY`).\n    ///\n    /// ### Why is this bad?\n    /// The method `is_finite` is shorter and more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1.0f32;\n    /// if x != f32::INFINITY && x != f32::NEG_INFINITY {}\n    /// if x.abs() < f32::INFINITY {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let x = 1.0f32;\n    /// if x.is_finite() {}\n    /// if x.is_finite() {}\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub MANUAL_IS_FINITE,\n    style,\n    \"use dedicated method to check if a float is finite\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual `is_infinite` reimplementations\n    /// (i.e., `x == <float>::INFINITY || x == <float>::NEG_INFINITY`).\n    ///\n    /// ### Why is this bad?\n    /// The method `is_infinite` is shorter and more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1.0f32;\n    /// if x == f32::INFINITY || x == f32::NEG_INFINITY {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let x = 1.0f32;\n    /// if x.is_infinite() {}\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub MANUAL_IS_INFINITE,\n    style,\n    \"use dedicated method to check if a float is infinite\"\n}\n\nimpl_lint_pass!(ManualFloatMethods => [MANUAL_IS_FINITE, MANUAL_IS_INFINITE]);\n\n#[derive(Clone, Copy)]\nenum Variant {\n    ManualIsInfinite,\n    ManualIsFinite,\n}\n\nimpl Variant {\n    pub fn lint(self) -> &'static Lint {\n        match self {\n            Self::ManualIsInfinite => MANUAL_IS_INFINITE,\n            Self::ManualIsFinite => MANUAL_IS_FINITE,\n        }\n    }\n\n    pub fn msg(self) -> &'static str {\n        match self {\n            Self::ManualIsInfinite => \"manually checking if a float is infinite\",\n            Self::ManualIsFinite => \"manually checking if a float is finite\",\n        }\n    }\n}\n\npub struct ManualFloatMethods {\n    msrv: Msrv,\n}\n\nimpl ManualFloatMethods {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nfn is_not_const(tcx: TyCtxt<'_>, def_id: DefId) -> bool {\n    match tcx.def_kind(def_id) {\n        DefKind::Mod\n        | DefKind::Struct\n        | DefKind::Union\n        | DefKind::Enum\n        | DefKind::Variant\n        | DefKind::Trait\n        | DefKind::TyAlias\n        | DefKind::ForeignTy\n        | DefKind::TraitAlias\n        | DefKind::AssocTy\n        | DefKind::Macro(..)\n        | DefKind::Field\n        | DefKind::LifetimeParam\n        | DefKind::ExternCrate\n        | DefKind::Use\n        | DefKind::ForeignMod\n        | DefKind::GlobalAsm\n        | DefKind::Impl { .. }\n        | DefKind::OpaqueTy\n        | DefKind::SyntheticCoroutineBody\n        | DefKind::TyParam => true,\n\n        DefKind::AnonConst\n        | DefKind::InlineConst\n        | DefKind::Const { .. }\n        | DefKind::ConstParam\n        | DefKind::Static { .. }\n        | DefKind::Ctor(..)\n        | DefKind::AssocConst { .. } => false,\n\n        DefKind::Fn | DefKind::AssocFn | DefKind::Closure => tcx.constness(def_id) == Constness::NotConst,\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Binary(kind, lhs, rhs) = expr.kind\n            && let ExprKind::Binary(lhs_kind, lhs_lhs, lhs_rhs) = lhs.kind\n            && let ExprKind::Binary(rhs_kind, rhs_lhs, rhs_rhs) = rhs.kind\n            // Checking all possible scenarios using a function would be a hopeless task, as we have\n            // 16 possible alignments of constants/operands. For now, let's use `partition`.\n            && let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]\n            && exprs.iter_mut().partition_in_place(|i| i.res_local_id().is_some()) == 2\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && (\n                is_not_const(cx.tcx, cx.tcx.hir_enclosing_body_owner(expr.hir_id).into())\n                    || self.msrv.meets(cx, msrvs::CONST_FLOAT_CLASSIFY)\n            )\n            && let [first, second, const_1, const_2] = exprs\n            && let ecx = ConstEvalCtxt::new(cx)\n            && let ctxt = expr.span.ctxt()\n            && let Some(const_1) = ecx.eval_local(const_1, ctxt)\n            && let Some(const_2) = ecx.eval_local(const_2, ctxt)\n            && first.res_local_id().is_some_and(|f| second.res_local_id().is_some_and(|s| f == s))\n            // The actual infinity check, we also allow `NEG_INFINITY` before` INFINITY` just in\n            // case somebody does that for some reason\n            && (const_1.is_pos_infinity() && const_2.is_neg_infinity()\n                || const_1.is_neg_infinity() && const_2.is_pos_infinity())\n            && let Some(local_snippet) = first.span.get_source_text(cx)\n        {\n            let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {\n                (BinOpKind::Or, BinOpKind::Eq, BinOpKind::Eq) => Variant::ManualIsInfinite,\n                (BinOpKind::And, BinOpKind::Ne, BinOpKind::Ne) => Variant::ManualIsFinite,\n                _ => return,\n            };\n            if is_from_proc_macro(cx, expr) {\n                return;\n            }\n\n            span_lint_and_then(cx, variant.lint(), expr.span, variant.msg(), |diag| {\n                match variant {\n                    Variant::ManualIsInfinite => {\n                        diag.span_suggestion(\n                            expr.span,\n                            \"use the dedicated method instead\",\n                            format!(\"{local_snippet}.is_infinite()\"),\n                            Applicability::MachineApplicable,\n                        );\n                    },\n                    Variant::ManualIsFinite => {\n                        // TODO: There's probably some better way to do this, i.e., create\n                        // multiple suggestions with notes between each of them\n                        diag.span_suggestion_verbose(\n                            expr.span,\n                            \"use the dedicated method instead\",\n                            format!(\"{local_snippet}.is_finite()\"),\n                            Applicability::MaybeIncorrect,\n                        )\n                        .span_suggestion_verbose(\n                            expr.span,\n                            \"this will alter how it handles NaN; if that is a problem, use instead\",\n                            format!(\"{local_snippet}.is_finite() || {local_snippet}.is_nan()\"),\n                            Applicability::MaybeIncorrect,\n                        )\n                        .span_suggestion_verbose(\n                            expr.span,\n                            \"or, for conciseness\",\n                            format!(\"!{local_snippet}.is_infinite()\"),\n                            Applicability::MaybeIncorrect,\n                        );\n                    },\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_hash_one.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::sym;\nuse clippy_utils::visitors::{is_local_used, local_used_once};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BindingMode, ExprKind, LetStmt, Node, PatKind, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for cases where [`BuildHasher::hash_one`] can be used.\n    ///\n    /// [`BuildHasher::hash_one`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html#method.hash_one\n    ///\n    /// ### Why is this bad?\n    /// It is more concise to use the `hash_one` method.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::hash::{BuildHasher, Hash, Hasher};\n    /// use std::collections::hash_map::RandomState;\n    ///\n    /// let s = RandomState::new();\n    /// let value = vec![1, 2, 3];\n    ///\n    /// let mut hasher = s.build_hasher();\n    /// value.hash(&mut hasher);\n    /// let hash = hasher.finish();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::hash::BuildHasher;\n    /// use std::collections::hash_map::RandomState;\n    ///\n    /// let s = RandomState::new();\n    /// let value = vec![1, 2, 3];\n    ///\n    /// let hash = s.hash_one(&value);\n    /// ```\n    #[clippy::version = \"1.75.0\"]\n    pub MANUAL_HASH_ONE,\n    complexity,\n    \"manual implementations of `BuildHasher::hash_one`\"\n}\n\nimpl_lint_pass!(ManualHashOne => [MANUAL_HASH_ONE]);\n\npub struct ManualHashOne {\n    msrv: Msrv,\n}\n\nimpl ManualHashOne {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for ManualHashOne {\n    fn check_local(&mut self, cx: &LateContext<'_>, local: &LetStmt<'_>) {\n        // `let mut hasher = seg.build_hasher();`\n        if let PatKind::Binding(BindingMode::MUT, hasher, _, None) = local.pat.kind\n            && let Some(init) = local.init\n            && !init.span.from_expansion()\n            && let ExprKind::MethodCall(seg, build_hasher, [], _) = init.kind\n            && seg.ident.name == sym::build_hasher\n\n            && let Node::Stmt(local_stmt) = cx.tcx.parent_hir_node(local.hir_id)\n            && let Node::Block(block) = cx.tcx.parent_hir_node(local_stmt.hir_id)\n\n            && let mut stmts = block.stmts.iter()\n                .skip_while(|stmt| stmt.hir_id != local_stmt.hir_id)\n                .skip(1)\n                .filter(|&stmt| is_local_used(cx, stmt, hasher))\n\n            // `hashed_value.hash(&mut hasher);`\n            && let Some(hash_stmt) = stmts.next()\n            && let StmtKind::Semi(hash_expr) = hash_stmt.kind\n            && !hash_expr.span.from_expansion()\n            && let ExprKind::MethodCall(seg, hashed_value, [ref_to_hasher], _) = hash_expr.kind\n            && seg.ident.name == sym::hash\n            && cx.ty_based_def(hash_expr).opt_parent(cx).is_diag_item(cx, sym::Hash)\n            && ref_to_hasher.peel_borrows().res_local_id() == Some(hasher)\n\n            && let maybe_finish_stmt = stmts.next()\n            // There should be no more statements referencing `hasher`\n            && stmts.next().is_none()\n\n            // `hasher.finish()`, may be anywhere in a statement or the trailing expr of the block\n            && let Some(path_expr) = local_used_once(cx, (maybe_finish_stmt, block.expr), hasher)\n            && let Node::Expr(finish_expr) = cx.tcx.parent_hir_node(path_expr.hir_id)\n            && !finish_expr.span.from_expansion()\n            && let ExprKind::MethodCall(seg, _, [], _) = finish_expr.kind\n            && seg.ident.name == sym::finish\n\n            && self.msrv.meets(cx, msrvs::BUILD_HASHER_HASH_ONE)\n        {\n            span_lint_hir_and_then(\n                cx,\n                MANUAL_HASH_ONE,\n                finish_expr.hir_id,\n                finish_expr.span,\n                \"manual implementation of `BuildHasher::hash_one`\",\n                |diag| {\n                    if let Some(build_hasher) = build_hasher.span.get_source_text(cx)\n                        && let Some(hashed_value) = hashed_value.span.get_source_text(cx)\n                    {\n                        diag.multipart_suggestion(\n                            \"try\",\n                            vec![\n                                (local_stmt.span, String::new()),\n                                (hash_stmt.span, String::new()),\n                                (\n                                    finish_expr.span,\n                                    // `needless_borrows_for_generic_args` will take care of\n                                    // removing the `&` when it isn't needed\n                                    format!(\"{build_hasher}.hash_one(&{hashed_value})\"),\n                                ),\n                            ],\n                            Applicability::MachineApplicable,\n                        );\n                    }\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_ignore_case_cmp.rs",
    "content": "use crate::manual_ignore_case_cmp::MatchType::{Literal, ToAscii};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::sym;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::ExprKind::{Binary, Lit, MethodCall};\nuse rustc_hir::{BinOpKind, Expr, LangItem};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_middle::ty::{Ty, UintTy};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual case-insensitive ASCII comparison.\n    ///\n    /// ### Why is this bad?\n    /// The `eq_ignore_ascii_case` method is faster because it does not allocate\n    /// memory for the new strings, and it is more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn compare(a: &str, b: &str) -> bool {\n    ///     a.to_ascii_lowercase() == b.to_ascii_lowercase() || a.to_ascii_lowercase() == \"abc\"\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn compare(a: &str, b: &str) -> bool {\n    ///     a.eq_ignore_ascii_case(b) || a.eq_ignore_ascii_case(\"abc\")\n    /// }\n    /// ```\n    #[clippy::version = \"1.84.0\"]\n    pub MANUAL_IGNORE_CASE_CMP,\n    perf,\n    \"manual case-insensitive ASCII comparison\"\n}\n\ndeclare_lint_pass!(ManualIgnoreCaseCmp => [MANUAL_IGNORE_CASE_CMP]);\n\nenum MatchType<'a> {\n    ToAscii(bool, Ty<'a>),\n    Literal(LitKind),\n}\n\nfn get_ascii_type<'a>(cx: &LateContext<'a>, kind: rustc_hir::ExprKind<'_>) -> Option<(Span, MatchType<'a>)> {\n    if let MethodCall(path, expr, _, _) = kind {\n        let is_lower = match path.ident.name {\n            sym::to_ascii_lowercase => true,\n            sym::to_ascii_uppercase => false,\n            _ => return None,\n        };\n        let ty_raw = cx.typeck_results().expr_ty(expr);\n        let ty = ty_raw.peel_refs();\n        if needs_ref_to_cmp(cx, ty)\n            || ty.is_str()\n            || ty.is_slice()\n            || matches!(ty.opt_diag_name(cx), Some(sym::OsStr | sym::OsString))\n        {\n            return Some((expr.span, ToAscii(is_lower, ty_raw)));\n        }\n    } else if let Lit(expr) = kind {\n        return Some((expr.span, Literal(expr.node)));\n    }\n    None\n}\n\n/// Returns true if the type needs to be dereferenced to be compared\nfn needs_ref_to_cmp(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    ty.is_char()\n        || *ty.kind() == ty::Uint(UintTy::U8)\n        || ty.is_diag_item(cx, sym::Vec)\n        || ty.is_lang_item(cx, LangItem::String)\n}\n\nimpl LateLintPass<'_> for ManualIgnoreCaseCmp {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        // check if expression represents a comparison of two strings\n        // using .to_ascii_lowercase() or .to_ascii_uppercase() methods,\n        // or one of the sides is a literal\n        // Offer to replace it with .eq_ignore_ascii_case() method\n        if let Binary(op, left, right) = &expr.kind\n            && (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne)\n            && let Some((left_span, left_val)) = get_ascii_type(cx, left.kind)\n            && let Some((right_span, right_val)) = get_ascii_type(cx, right.kind)\n            && match (&left_val, &right_val) {\n                (ToAscii(l_lower, ..), ToAscii(r_lower, ..)) if l_lower == r_lower => true,\n                (ToAscii(..), Literal(..)) | (Literal(..), ToAscii(..)) => true,\n                _ => false,\n            }\n        {\n            let deref = match right_val {\n                ToAscii(_, ty) if needs_ref_to_cmp(cx, ty) => \"&\",\n                ToAscii(..) => \"\",\n                Literal(ty) => {\n                    if let LitKind::Char(_) | LitKind::Byte(_) = ty {\n                        \"&\"\n                    } else {\n                        \"\"\n                    }\n                },\n            };\n            let neg = if op.node == BinOpKind::Ne { \"!\" } else { \"\" };\n            span_lint_and_then(\n                cx,\n                MANUAL_IGNORE_CASE_CMP,\n                expr.span,\n                \"manual case-insensitive ASCII comparison\",\n                |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let (left_snip, _) = snippet_with_context(cx, left_span, expr.span.ctxt(), \"..\", &mut app);\n                    let (right_snip, _) = snippet_with_context(cx, right_span, expr.span.ctxt(), \"..\", &mut app);\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        \"consider using `.eq_ignore_ascii_case()` instead\",\n                        format!(\"{neg}{left_snip}.eq_ignore_ascii_case({deref}{right_snip})\"),\n                        app,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_ilog2.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{is_from_proc_macro, sym};\nuse rustc_ast::LitKind;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions like `N - x.leading_zeros()` (where `N` is one less than bit width\n    /// of `x`) or `x.ilog(2)`, which are manual reimplementations of `x.ilog2()`\n    ///\n    /// ### Why is this bad?\n    /// Manual reimplementations of `ilog2` increase code complexity for little benefit.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: u32 = 5;\n    /// let log = 31 - x.leading_zeros();\n    /// let log = x.ilog(2);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x: u32 = 5;\n    /// let log = x.ilog2();\n    /// let log = x.ilog2();\n    /// ```\n    #[clippy::version = \"1.94.0\"]\n    pub MANUAL_ILOG2,\n    pedantic,\n    \"manually reimplementing `ilog2`\"\n}\n\nimpl_lint_pass!(ManualIlog2 => [MANUAL_ILOG2]);\n\npub struct ManualIlog2 {\n    msrv: Msrv,\n}\n\nimpl ManualIlog2 {\n    pub fn new(conf: &Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for ManualIlog2 {\n    fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if expr.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        match expr.kind {\n            // `BIT_WIDTH - 1 - n.leading_zeros()`\n            ExprKind::Binary(op, left, right)\n                if left.span.eq_ctxt(right.span)\n                    && op.node == BinOpKind::Sub\n                    && let ExprKind::Lit(lit) = left.kind\n                    && let LitKind::Int(Pu128(val), _) = lit.node\n                    && let ExprKind::MethodCall(leading_zeros, recv, [], _) = right.kind\n                    && leading_zeros.ident.name == sym::leading_zeros\n                    && let ty = cx.typeck_results().expr_ty(recv)\n                    && let Some(bit_width) = match ty.kind() {\n                        ty::Uint(uint_ty) => uint_ty.bit_width(),\n                        ty::Int(_) => {\n                            // On non-positive integers, `ilog2` would panic, which might be a sign that the author does\n                            // in fact want to calculate something different, so stay on the safer side and don't\n                            // suggest anything.\n                            return;\n                        },\n                        _ => return,\n                    }\n                    && val == u128::from(bit_width) - 1\n                    && self.msrv.meets(cx, msrvs::ILOG2)\n                    && !is_from_proc_macro(cx, expr) =>\n            {\n                emit(cx, recv, expr);\n            },\n\n            // `n.ilog(2)`\n            ExprKind::MethodCall(ilog, recv, [two], _)\n                if expr.span.eq_ctxt(two.span)\n                    && ilog.ident.name == sym::ilog\n                    && let ExprKind::Lit(lit) = two.kind\n                    && let LitKind::Int(Pu128(2), _) = lit.node\n                    && cx.typeck_results().expr_ty_adjusted(recv).is_integral()\n                    /* no need to check MSRV here, as `ilog` and `ilog2` were introduced simultaneously */\n                    && !is_from_proc_macro(cx, expr) =>\n            {\n                emit(cx, recv, expr);\n            },\n\n            _ => {},\n        }\n    }\n}\n\nfn emit(cx: &LateContext<'_>, recv: &Expr<'_>, full_expr: &Expr<'_>) {\n    let mut app = Applicability::MachineApplicable;\n    let (recv, _) = snippet_with_context(cx, recv.span, full_expr.span.ctxt(), \"_\", &mut app);\n    span_lint_and_sugg(\n        cx,\n        MANUAL_ILOG2,\n        full_expr.span,\n        \"manually reimplementing `ilog2`\",\n        \"try\",\n        format!(\"{recv}.ilog2()\"),\n        app,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_is_ascii_check.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::matching_root_macro_call;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{higher, is_in_const_context, peel_ref_operators, sym};\nuse rustc_ast::LitKind::{Byte, Char};\nuse rustc_ast::ast::RangeLimits;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Lit, Node, Param, PatExpr, PatExprKind, PatKind, RangeEnd};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Suggests to use dedicated built-in methods,\n    /// `is_ascii_(lowercase|uppercase|digit|hexdigit)` for checking on corresponding\n    /// ascii range\n    ///\n    /// ### Why is this bad?\n    /// Using the built-in functions is more readable and makes it\n    /// clear that it's not a specific subset of characters, but all\n    /// ASCII (lowercase|uppercase|digit|hexdigit) characters.\n    /// ### Example\n    /// ```no_run\n    /// fn main() {\n    ///     assert!(matches!('x', 'a'..='z'));\n    ///     assert!(matches!(b'X', b'A'..=b'Z'));\n    ///     assert!(matches!('2', '0'..='9'));\n    ///     assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\n    ///     assert!(matches!('C', '0'..='9' | 'a'..='f' | 'A'..='F'));\n    ///\n    ///     ('0'..='9').contains(&'0');\n    ///     ('a'..='z').contains(&'a');\n    ///     ('A'..='Z').contains(&'A');\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn main() {\n    ///     assert!('x'.is_ascii_lowercase());\n    ///     assert!(b'X'.is_ascii_uppercase());\n    ///     assert!('2'.is_ascii_digit());\n    ///     assert!('x'.is_ascii_alphabetic());\n    ///     assert!('C'.is_ascii_hexdigit());\n    ///\n    ///     '0'.is_ascii_digit();\n    ///     'a'.is_ascii_lowercase();\n    ///     'A'.is_ascii_uppercase();\n    /// }\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub MANUAL_IS_ASCII_CHECK,\n    style,\n    \"use dedicated method to check ascii range\"\n}\n\nimpl_lint_pass!(ManualIsAsciiCheck => [MANUAL_IS_ASCII_CHECK]);\n\npub struct ManualIsAsciiCheck {\n    msrv: Msrv,\n}\n\nimpl ManualIsAsciiCheck {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\n#[derive(Debug, PartialEq)]\nenum CharRange {\n    /// 'a'..='z' | b'a'..=b'z'\n    LowerChar,\n    /// 'A'..='Z' | b'A'..=b'Z'\n    UpperChar,\n    /// `AsciiLower` | `AsciiUpper`\n    FullChar,\n    /// '0..=9'\n    Digit,\n    /// 'a..=f'\n    LowerHexLetter,\n    /// 'A..=F'\n    UpperHexLetter,\n    /// '0..=9' | 'a..=f' | 'A..=F'\n    HexDigit,\n    Otherwise,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if !self.msrv.meets(cx, msrvs::IS_ASCII_DIGIT) {\n            return;\n        }\n\n        if is_in_const_context(cx) && !self.msrv.meets(cx, msrvs::IS_ASCII_DIGIT_CONST) {\n            return;\n        }\n\n        let (arg, span, range) = if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro)\n            && let ExprKind::Match(recv, [arm, ..], _) = expr.kind\n        {\n            let recv = peel_ref_operators(cx, recv);\n            let range = check_pat(&arm.pat.kind);\n            (recv, macro_call.span, range)\n        } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind\n            && path.ident.name == sym::contains\n            && let Some(higher::Range {\n                start: Some(start),\n                end: Some(end),\n                limits: RangeLimits::Closed,\n                span: _,\n            }) = higher::Range::hir(cx, receiver)\n            && !matches!(cx.typeck_results().expr_ty(arg).peel_refs().kind(), ty::Param(_))\n        {\n            let arg = peel_ref_operators(cx, arg);\n            let range = check_expr_range(start, end);\n            (arg, expr.span, range)\n        } else {\n            return;\n        };\n\n        let ty_sugg = get_ty_sugg(cx, arg);\n        check_is_ascii(cx, span, arg, &range, ty_sugg);\n    }\n}\n\nfn get_ty_sugg<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'_>) -> Option<(Span, Ty<'tcx>)> {\n    let local_hid = arg.res_local_id()?;\n    if let Node::Param(Param { ty_span, span, .. }) = cx.tcx.parent_hir_node(local_hid)\n        // `ty_span` and `span` are the same for inferred type, thus a type suggestion must be given\n        && ty_span == span\n    {\n        let arg_type = cx.typeck_results().expr_ty(arg);\n        return Some((*ty_span, arg_type));\n    }\n    None\n}\n\nfn check_is_ascii(\n    cx: &LateContext<'_>,\n    span: Span,\n    recv: &Expr<'_>,\n    range: &CharRange,\n    ty_sugg: Option<(Span, Ty<'_>)>,\n) {\n    let sugg = match range {\n        CharRange::UpperChar => \"is_ascii_uppercase\",\n        CharRange::LowerChar => \"is_ascii_lowercase\",\n        CharRange::FullChar => \"is_ascii_alphabetic\",\n        CharRange::Digit => \"is_ascii_digit\",\n        CharRange::HexDigit => \"is_ascii_hexdigit\",\n        CharRange::Otherwise | CharRange::LowerHexLetter | CharRange::UpperHexLetter => return,\n    };\n    let mut app = Applicability::MachineApplicable;\n    let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), \"_\", &mut app).maybe_paren();\n    let mut suggestion = vec![(span, format!(\"{recv}.{sugg}()\"))];\n    if let Some((ty_span, ty)) = ty_sugg {\n        suggestion.push((ty_span, format!(\"{recv}: {ty}\")));\n    }\n\n    span_lint_and_then(\n        cx,\n        MANUAL_IS_ASCII_CHECK,\n        span,\n        \"manual check for common ascii range\",\n        |diag| {\n            diag.multipart_suggestion(\"try\", suggestion, app);\n        },\n    );\n}\n\nfn check_pat(pat_kind: &PatKind<'_>) -> CharRange {\n    match pat_kind {\n        PatKind::Or(pats) => {\n            let ranges = pats.iter().map(|p| check_pat(&p.kind)).collect::<Vec<_>>();\n\n            if ranges.len() == 2 && ranges.contains(&CharRange::UpperChar) && ranges.contains(&CharRange::LowerChar) {\n                CharRange::FullChar\n            } else if ranges.len() == 3\n                && ranges.contains(&CharRange::Digit)\n                && ranges.contains(&CharRange::LowerHexLetter)\n                && ranges.contains(&CharRange::UpperHexLetter)\n            {\n                CharRange::HexDigit\n            } else {\n                CharRange::Otherwise\n            }\n        },\n        PatKind::Range(Some(start), Some(end), RangeEnd::Included) => check_range(start, end),\n        _ => CharRange::Otherwise,\n    }\n}\n\nfn check_expr_range(start: &Expr<'_>, end: &Expr<'_>) -> CharRange {\n    if let ExprKind::Lit(start_lit) = &start.kind\n        && let ExprKind::Lit(end_lit) = &end.kind\n    {\n        check_lit_range(start_lit, end_lit)\n    } else {\n        CharRange::Otherwise\n    }\n}\n\nfn check_range(start: &PatExpr<'_>, end: &PatExpr<'_>) -> CharRange {\n    if let PatExprKind::Lit {\n        lit: start_lit,\n        negated: false,\n    } = &start.kind\n        && let PatExprKind::Lit {\n            lit: end_lit,\n            negated: false,\n        } = &end.kind\n    {\n        check_lit_range(start_lit, end_lit)\n    } else {\n        CharRange::Otherwise\n    }\n}\n\nfn check_lit_range(start_lit: &Lit, end_lit: &Lit) -> CharRange {\n    match (&start_lit.node, &end_lit.node) {\n        (Char('a'), Char('z')) | (Byte(b'a'), Byte(b'z')) => CharRange::LowerChar,\n        (Char('A'), Char('Z')) | (Byte(b'A'), Byte(b'Z')) => CharRange::UpperChar,\n        (Char('a'), Char('f')) | (Byte(b'a'), Byte(b'f')) => CharRange::LowerHexLetter,\n        (Char('A'), Char('F')) | (Byte(b'A'), Byte(b'F')) => CharRange::UpperHexLetter,\n        (Char('0'), Char('9')) | (Byte(b'0'), Byte(b'9')) => CharRange::Digit,\n        _ => CharRange::Otherwise,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_is_power_of_two.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::ty_from_hir_ty;\nuse clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions like `x.count_ones() == 1` or `x & (x - 1) == 0`, with x and unsigned integer, which may be manual\n    /// reimplementations of `x.is_power_of_two()`.\n    ///\n    /// ### Why is this bad?\n    /// Manual reimplementations of `is_power_of_two` increase code complexity for little benefit.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a: u32 = 4;\n    /// let result = a.count_ones() == 1;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let a: u32 = 4;\n    /// let result = a.is_power_of_two();\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub MANUAL_IS_POWER_OF_TWO,\n    pedantic,\n    \"manually reimplementing `is_power_of_two`\"\n}\n\nimpl_lint_pass!(ManualIsPowerOfTwo => [MANUAL_IS_POWER_OF_TWO]);\n\npub struct ManualIsPowerOfTwo {\n    msrv: Msrv,\n}\n\nimpl ManualIsPowerOfTwo {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n\n    fn build_sugg(&self, cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {\n        if is_in_const_context(cx) && !self.msrv.meets(cx, msrvs::CONST_IS_POWER_OF_TWO) {\n            return;\n        }\n\n        let mut applicability = Applicability::MachineApplicable;\n        let snippet = Sugg::hir_with_applicability(cx, receiver, \"_\", &mut applicability);\n\n        span_lint_and_sugg(\n            cx,\n            MANUAL_IS_POWER_OF_TWO,\n            expr.span,\n            \"manually reimplementing `is_power_of_two`\",\n            \"consider using `.is_power_of_two()`\",\n            format!(\"{}.is_power_of_two()\", snippet.maybe_paren()),\n            applicability,\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualIsPowerOfTwo {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if !expr.span.from_expansion()\n            && let Some((lhs, rhs)) = unexpanded_binop_operands(expr, BinOpKind::Eq)\n        {\n            if is_integer_literal(rhs, 1)\n                && let Some(a) = count_ones_receiver(cx, lhs)\n            {\n                self.build_sugg(cx, expr, a);\n            } else if is_integer_literal(lhs, 1)\n                && let Some(a) = count_ones_receiver(cx, rhs)\n            {\n                self.build_sugg(cx, expr, a);\n            } else if is_integer_literal(rhs, 0)\n                && let Some(a) = is_and_minus_one(cx, lhs)\n            {\n                self.build_sugg(cx, expr, a);\n            } else if is_integer_literal(lhs, 0)\n                && let Some(a) = is_and_minus_one(cx, rhs)\n            {\n                self.build_sugg(cx, expr, a);\n            }\n        }\n    }\n}\n\n/// Return the unsigned integer receiver of `.count_ones()` or the argument of\n/// `<int-type>::count_ones(…)`.\nfn count_ones_receiver<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    let (method, ty, receiver) = if let ExprKind::MethodCall(method_name, receiver, [], _) = expr.kind {\n        (method_name, cx.typeck_results().expr_ty_adjusted(receiver), receiver)\n    } else if let ExprKind::Call(func, [arg]) = expr.kind\n        && let ExprKind::Path(QPath::TypeRelative(ty, func_name)) = func.kind\n    {\n        (func_name, ty_from_hir_ty(cx, ty), arg)\n    } else {\n        return None;\n    };\n    (method.ident.name == sym::count_ones && matches!(ty.kind(), ty::Uint(_))).then_some(receiver)\n}\n\n/// Return `greater` if `smaller == greater - 1`\nfn is_one_less<'tcx>(\n    cx: &LateContext<'tcx>,\n    greater: &'tcx Expr<'tcx>,\n    smaller: &Expr<'tcx>,\n) -> Option<&'tcx Expr<'tcx>> {\n    if let Some((lhs, rhs)) = unexpanded_binop_operands(smaller, BinOpKind::Sub)\n        && SpanlessEq::new(cx).eq_expr(greater, lhs)\n        && is_integer_literal(rhs, 1)\n        && matches!(cx.typeck_results().expr_ty_adjusted(greater).kind(), ty::Uint(_))\n    {\n        Some(greater)\n    } else {\n        None\n    }\n}\n\n/// Return `v` if `expr` is `v & (v - 1)` or `(v - 1) & v`\nfn is_and_minus_one<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    let (lhs, rhs) = unexpanded_binop_operands(expr, BinOpKind::BitAnd)?;\n    is_one_less(cx, lhs, rhs).or_else(|| is_one_less(cx, rhs, lhs))\n}\n\n/// Return the operands of the `expr` binary operation if the operator is `op` and none of the\n/// operands come from expansion.\nfn unexpanded_binop_operands<'hir>(expr: &Expr<'hir>, op: BinOpKind) -> Option<(&'hir Expr<'hir>, &'hir Expr<'hir>)> {\n    if let ExprKind::Binary(binop, lhs, rhs) = expr.kind\n        && binop.node == op\n        && !lhs.span.from_expansion()\n        && !rhs.span.from_expansion()\n    {\n        Some((lhs, rhs))\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_let_else.rs",
    "content": "use crate::question_mark::{QUESTION_MARK, QuestionMark};\nuse clippy_config::types::MatchLintBehaviour;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::IfLetOrMatch;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{is_lint_allowed, is_never_expr, is_wild, msrvs, pat_and_expr_can_be_question_mark, peel_blocks};\nuse rustc_ast::BindingMode;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{CtorOf, DefKind, Res};\nuse rustc_hir::{\n    Arm, BlockCheckMode, Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind,\n};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_span::Span;\nuse rustc_span::symbol::{Symbol, sym};\nuse std::slice;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Warn of cases where `let...else` could be used\n    ///\n    /// ### Why is this bad?\n    ///\n    /// `let...else` provides a standard construct for this pattern\n    /// that people can easily recognize. It's also more compact.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// # let w = Some(0);\n    /// let v = if let Some(v) = w { v } else { return };\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// # fn main () {\n    /// # let w = Some(0);\n    /// let Some(v) = w else { return };\n    /// # }\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub MANUAL_LET_ELSE,\n    pedantic,\n    \"manual implementation of a let...else statement\"\n}\n\nimpl<'tcx> QuestionMark {\n    pub(crate) fn check_manual_let_else(&self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) {\n        if let StmtKind::Let(local) = stmt.kind\n            && let Some(init) = local.init\n            && local.els.is_none()\n            && local.ty.is_none()\n            && init.span.eq_ctxt(stmt.span)\n            && let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init)\n            && !stmt.span.in_external_macro(cx.sess().source_map())\n            && self.msrv.meets(cx, msrvs::LET_ELSE)\n        {\n            match if_let_or_match {\n                IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else, ..) => {\n                    if let Some(ident_map) = expr_simple_identity_map(local.pat, let_pat, if_then)\n                        && let Some(if_else) = if_else\n                        && is_never_expr(cx, if_else).is_some()\n                        && let qm_allowed = is_lint_allowed(cx, QUESTION_MARK, stmt.hir_id)\n                        && (qm_allowed || pat_and_expr_can_be_question_mark(cx, let_pat, if_else).is_none())\n                    {\n                        emit_manual_let_else(cx, stmt.span, if_let_expr, &ident_map, let_pat, if_else);\n                    }\n                },\n                IfLetOrMatch::Match(match_expr, arms, source) => {\n                    if self.matches_behaviour == MatchLintBehaviour::Never {\n                        return;\n                    }\n                    if source != MatchSource::Normal {\n                        return;\n                    }\n                    // Any other number than two arms doesn't (necessarily)\n                    // have a trivial mapping to let else.\n                    if arms.len() != 2 {\n                        return;\n                    }\n                    // Guards don't give us an easy mapping either\n                    if arms.iter().any(|arm| arm.guard.is_some()) {\n                        return;\n                    }\n                    let check_types = self.matches_behaviour == MatchLintBehaviour::WellKnownTypes;\n                    let diverging_arm_opt = arms.iter().enumerate().find(|(_, arm)| {\n                        is_never_expr(cx, arm.body).is_some() && pat_allowed_for_else(cx, arm.pat, check_types)\n                    });\n                    let Some((idx, diverging_arm)) = diverging_arm_opt else {\n                        return;\n                    };\n\n                    let pat_arm = &arms[1 - idx];\n                    // If the non-diverging arm is the first one, its pattern can be reused in a let/else statement.\n                    // However, if it arrives in second position, its pattern may cover some cases already covered\n                    // by the diverging one.\n                    if idx == 0 && !is_arms_disjointed(cx, diverging_arm, pat_arm) {\n                        return;\n                    }\n\n                    let Some(ident_map) = expr_simple_identity_map(local.pat, pat_arm.pat, pat_arm.body) else {\n                        return;\n                    };\n\n                    emit_manual_let_else(cx, stmt.span, match_expr, &ident_map, pat_arm.pat, diverging_arm.body);\n                },\n            }\n        }\n    }\n}\n\n/// Checks if the patterns of the arms are disjointed. Currently, we only support patterns of simple\n/// enum variants without nested patterns or bindings.\n///\n/// TODO: Support more complex patterns.\nfn is_arms_disjointed(cx: &LateContext<'_>, arm1: &Arm<'_>, arm2: &Arm<'_>) -> bool {\n    if arm1.guard.is_some() || arm2.guard.is_some() {\n        return false;\n    }\n\n    if !is_enum_variant(cx, arm1.pat) || !is_enum_variant(cx, arm2.pat) {\n        return false;\n    }\n\n    true\n}\n\n/// Returns `true` if the given pattern is a variant of an enum.\npub fn is_enum_variant(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {\n    let path = match pat.kind {\n        PatKind::Struct(ref qpath, fields, _)\n            if fields\n                .iter()\n                .all(|field| is_wild(field.pat) || matches!(field.pat.kind, PatKind::Binding(..))) =>\n        {\n            (qpath, pat.hir_id)\n        },\n        PatKind::TupleStruct(ref qpath, pats, _)\n            if pats\n                .iter()\n                .all(|pat| is_wild(pat) || matches!(pat.kind, PatKind::Binding(..))) =>\n        {\n            (qpath, pat.hir_id)\n        },\n        PatKind::Expr(e) if let Some((qpath, id)) = e.opt_qpath() => (qpath, id),\n        _ => return false,\n    };\n    let res = path.res(cx);\n    matches!(\n        res,\n        Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(CtorOf::Variant, _), _)\n    )\n}\n\nfn emit_manual_let_else(\n    cx: &LateContext<'_>,\n    span: Span,\n    expr: &Expr<'_>,\n    ident_map: &FxHashMap<Symbol, (&Pat<'_>, BindingMode)>,\n    pat: &Pat<'_>,\n    else_body: &Expr<'_>,\n) {\n    span_lint_and_then(\n        cx,\n        MANUAL_LET_ELSE,\n        span,\n        \"this could be rewritten as `let...else`\",\n        |diag| {\n            // This is far from perfect, for example there needs to be:\n            // * renamings of the bindings for many `PatKind`s like slices, etc.\n            // * limitations in the existing replacement algorithms\n            // * unused binding collision detection with existing ones\n            // for this to be machine applicable.\n            let mut app = Applicability::HasPlaceholders;\n            let (sn_expr, _) = snippet_with_context(cx, expr.span, span.ctxt(), \"\", &mut app);\n            let (sn_else, else_is_mac_call) = snippet_with_context(cx, else_body.span, span.ctxt(), \"\", &mut app);\n\n            let else_bl = if let ExprKind::Block(block, None) = else_body.kind\n                && matches!(block.rules, BlockCheckMode::DefaultBlock)\n                && !else_is_mac_call\n            {\n                sn_else.into_owned()\n            } else {\n                format!(\"{{ {sn_else} }}\")\n            };\n            let sn_bl = replace_in_pattern(cx, span, ident_map, pat, &mut app, true);\n            let sugg = if sn_expr.ends_with('}') {\n                // let-else statement expressions are not allowed to end with `}`\n                // https://rust-lang.github.io/rfcs/3137-let-else.html#let-pattern--if--else--else-\n                format!(\"let {sn_bl} = ({sn_expr}) else {else_bl};\")\n            } else {\n                format!(\"let {sn_bl} = {sn_expr} else {else_bl};\")\n            };\n            diag.span_suggestion(span, \"consider writing\", sugg, app);\n        },\n    );\n}\n\n/// Replaces the locals in the pattern\n///\n/// For this example:\n///\n/// ```ignore\n/// let (a, FooBar { b, c }) = if let Bar { Some(a_i), b_i } = ex { (a_i, b_i) } else { return };\n/// ```\n///\n/// We have:\n///\n/// ```ignore\n/// pat: Bar { Some(a_i), b_i }\n/// ident_map: (a_i) -> (a), (b_i) -> (FooBar { b, c })\n/// ```\n///\n/// We return:\n///\n/// ```ignore\n/// Bar { Some(a), b_i: FooBar { b, c } }\n/// ```\nfn replace_in_pattern(\n    cx: &LateContext<'_>,\n    span: Span,\n    ident_map: &FxHashMap<Symbol, (&Pat<'_>, BindingMode)>,\n    pat: &Pat<'_>,\n    app: &mut Applicability,\n    top_level: bool,\n) -> String {\n    // We put a labeled block here so that we can implement the fallback in this function.\n    // As the function has multiple call sites, implementing the fallback via an Option<T>\n    // return type and unwrap_or_else would cause repetition. Similarly, the function also\n    // invokes the fall back multiple times.\n    'a: {\n        // If the ident map is empty, there is no replacement to do.\n        // The code following this if assumes a non-empty ident_map.\n        if ident_map.is_empty() {\n            break 'a;\n        }\n\n        match pat.kind {\n            PatKind::Binding(ann, _id, binding_name, opt_subpt) => {\n                match (ident_map.get(&binding_name.name), opt_subpt) {\n                    (Some((pat_to_put, binding_mode)), opt_subpt) => {\n                        let sn_pfx = binding_mode.prefix_str();\n                        let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), \"\", app);\n                        if let Some(subpt) = opt_subpt {\n                            let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);\n                            return format!(\"{sn_pfx}{sn_ptp} @ {subpt}\");\n                        }\n                        return format!(\"{sn_pfx}{sn_ptp}\");\n                    },\n                    (None, Some(subpt)) => {\n                        let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);\n                        // scanning for a value that matches is not sensitive to order\n                        #[expect(rustc::potential_query_instability)]\n                        if ident_map.values().any(|(other_pat, _)| {\n                            if let PatKind::Binding(_, _, other_name, _) = other_pat.kind {\n                                other_name == binding_name\n                            } else {\n                                false\n                            }\n                        }) {\n                            // this name is shadowed, and, therefore, not usable\n                            return subpt;\n                        }\n                        let binding_pfx = ann.prefix_str();\n                        return format!(\"{binding_pfx}{binding_name} @ {subpt}\");\n                    },\n                    (None, None) => break 'a,\n                }\n            },\n            PatKind::Or(pats) => {\n                let patterns = pats\n                    .iter()\n                    .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false))\n                    .collect::<Vec<_>>();\n                let or_pat = patterns.join(\" | \");\n                if top_level {\n                    return format!(\"({or_pat})\");\n                }\n                return or_pat;\n            },\n            PatKind::Struct(path, fields, dot_dot) => {\n                let fields = fields\n                    .iter()\n                    .map(|fld| {\n                        if let PatKind::Binding(_, _, name, None) = fld.pat.kind\n                            && let Some((pat_to_put, binding_mode)) = ident_map.get(&name.name)\n                        {\n                            let sn_pfx = binding_mode.prefix_str();\n                            let (sn_fld_name, _) = snippet_with_context(cx, fld.ident.span, span.ctxt(), \"\", app);\n                            let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), \"\", app);\n                            // TODO: this is a bit of a hack, but it does its job. Ideally, we'd check if pat_to_put is\n                            // a PatKind::Binding but that is also hard to get right.\n                            if sn_fld_name == sn_ptp {\n                                // Field init shorthand\n                                return format!(\"{sn_pfx}{sn_fld_name}\");\n                            }\n                            return format!(\"{sn_fld_name}: {sn_pfx}{sn_ptp}\");\n                        }\n                        let (sn_fld, _) = snippet_with_context(cx, fld.span, span.ctxt(), \"\", app);\n                        sn_fld.into_owned()\n                    })\n                    .collect::<Vec<_>>();\n                let fields_string = fields.join(\", \");\n\n                let dot_dot_str = if dot_dot.is_some() { \", ..\" } else { \"\" };\n                let (sn_pth, _) = snippet_with_context(cx, path.span(), span.ctxt(), \"\", app);\n                return format!(\"{sn_pth} {{ {fields_string}{dot_dot_str} }}\");\n            },\n            // Replace the variable name iff `TupleStruct` has one argument like `Variant(v)`.\n            PatKind::TupleStruct(ref w, args, dot_dot_pos) => {\n                let mut args = args\n                    .iter()\n                    .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false))\n                    .collect::<Vec<_>>();\n                if let Some(pos) = dot_dot_pos.as_opt_usize() {\n                    args.insert(pos, \"..\".to_owned());\n                }\n                let args = args.join(\", \");\n                let sn_wrapper = cx.sess().source_map().span_to_snippet(w.span()).unwrap_or_default();\n                return format!(\"{sn_wrapper}({args})\");\n            },\n            PatKind::Tuple(args, dot_dot_pos) => {\n                let mut args = args\n                    .iter()\n                    .map(|pat| replace_in_pattern(cx, span, ident_map, pat, app, false))\n                    .collect::<Vec<_>>();\n                if let Some(pos) = dot_dot_pos.as_opt_usize() {\n                    args.insert(pos, \"..\".to_owned());\n                }\n                let args = args.join(\", \");\n                return format!(\"({args})\");\n            },\n            _ => {},\n        }\n    }\n    let (sn_pat, _) = snippet_with_context(cx, pat.span, span.ctxt(), \"\", app);\n    sn_pat.into_owned()\n}\n\nfn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: bool) -> bool {\n    // Check whether the pattern contains any bindings, as the\n    // binding might potentially be used in the body.\n    // TODO: only look for *used* bindings.\n    let mut has_bindings = false;\n    pat.each_binding_or_first(&mut |_, _, _, _| has_bindings = true);\n    if has_bindings {\n        return false;\n    }\n\n    // If we shouldn't check the types, exit early.\n    if !check_types {\n        return true;\n    }\n\n    // Check whether any possibly \"unknown\" patterns are included,\n    // because users might not know which values some enum has.\n    // Well-known enums are excepted, as we assume people know them.\n    // We do a deep check, to be able to disallow Err(En::Foo(_))\n    // for usage of the En::Foo variant, as we disallow En::Foo(_),\n    // but we allow Err(_).\n    let typeck_results = cx.typeck_results();\n    let mut has_disallowed = false;\n    pat.walk_always(|pat| {\n        // Only do the check if the type is \"spelled out\" in the pattern\n        if !matches!(\n            pat.kind,\n            PatKind::Struct(..)\n                | PatKind::TupleStruct(..)\n                | PatKind::Expr(PatExpr {\n                    kind: PatExprKind::Path(..),\n                    ..\n                },)\n        ) {\n            return;\n        }\n        let ty = typeck_results.pat_ty(pat);\n        // Option and Result are allowed, everything else isn't.\n        if !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) {\n            has_disallowed = true;\n        }\n    });\n    !has_disallowed\n}\n\n/// Checks if the passed block is a simple identity referring to bindings created by the pattern,\n/// and if yes, returns a mapping between the relevant sub-pattern and the identifier it corresponds\n/// to.\n///\n/// We support patterns with multiple bindings and tuples, e.g.:\n///\n/// ```ignore\n/// let (foo_o, bar_o) = if let (Some(foo), bar) = g() { (foo, bar) } else { ... }\n/// ```\n///\n/// The expected params would be:\n///\n/// ```ignore\n/// local_pat: (foo_o, bar_o)\n/// let_pat: (Some(foo), bar)\n/// expr: (foo, bar)\n/// ```\n///\n/// We build internal `sub_pats` so that it looks like `[foo_o, bar_o]` and `paths` so that it looks\n/// like `[foo, bar]`. Then we turn that into `FxHashMap [(foo) -> (foo_o), (bar) -> (bar_o)]` which\n/// we return.\nfn expr_simple_identity_map<'a, 'hir>(\n    local_pat: &'a Pat<'hir>,\n    let_pat: &'_ Pat<'hir>,\n    expr: &'_ Expr<'hir>,\n) -> Option<FxHashMap<Symbol, (&'a Pat<'hir>, BindingMode)>> {\n    let peeled = peel_blocks(expr);\n    let (sub_pats, paths) = match (local_pat.kind, peeled.kind) {\n        (PatKind::Tuple(pats, _), ExprKind::Tup(exprs)) | (PatKind::Slice(pats, ..), ExprKind::Array(exprs)) => {\n            (pats, exprs)\n        },\n        (_, ExprKind::Path(_)) => (slice::from_ref(local_pat), slice::from_ref(peeled)),\n        _ => return None,\n    };\n\n    // There is some length mismatch, which indicates usage of .. in the patterns above e.g.:\n    // let (a, ..) = if let [a, b, _c] = ex { (a, b) } else { ... };\n    // We bail in these cases as they should be rare.\n    if paths.len() != sub_pats.len() {\n        return None;\n    }\n\n    let mut pat_bindings = FxHashMap::default();\n    let_pat.each_binding_or_first(&mut |binding_mode, _hir_id, _sp, ident| {\n        pat_bindings.insert(ident, binding_mode);\n    });\n    if pat_bindings.len() < paths.len() {\n        // This rebinds some bindings from the outer scope, or it repeats some copy-able bindings multiple\n        // times. We don't support these cases so we bail here. E.g.:\n        // let foo = 0;\n        // let (new_foo, bar, bar_copied) = if let Some(bar) = Some(0) { (foo, bar, bar) } else { .. };\n        return None;\n    }\n    let mut ident_map = FxHashMap::default();\n    for (sub_pat, path) in sub_pats.iter().zip(paths.iter()) {\n        if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind\n            && let [path_seg] = path.segments\n            && let ident = path_seg.ident\n            && let Some(let_binding_mode) = pat_bindings.remove(&ident)\n        {\n            ident_map.insert(ident.name, (sub_pat, let_binding_mode));\n        } else {\n            return None;\n        }\n    }\n    Some(ident_map)\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_main_separator_str.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::{peel_hir_expr_refs, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Expr, ExprKind, Mutability, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for references on `std::path::MAIN_SEPARATOR.to_string()` used\n    /// to build a `&str`.\n    ///\n    /// ### Why is this bad?\n    /// There exists a `std::path::MAIN_SEPARATOR_STR` which does not require\n    /// an extra memory allocation.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let s: &str = &std::path::MAIN_SEPARATOR.to_string();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let s: &str = std::path::MAIN_SEPARATOR_STR;\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub MANUAL_MAIN_SEPARATOR_STR,\n    complexity,\n    \"`&std::path::MAIN_SEPARATOR.to_string()` can be replaced by `std::path::MAIN_SEPARATOR_STR`\"\n}\n\nimpl_lint_pass!(ManualMainSeparatorStr => [MANUAL_MAIN_SEPARATOR_STR]);\n\npub struct ManualMainSeparatorStr {\n    msrv: Msrv,\n}\n\nimpl ManualMainSeparatorStr {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for ManualMainSeparatorStr {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let (target, _) = peel_hir_expr_refs(expr);\n        if let ExprKind::MethodCall(path, receiver, &[], _) = target.kind\n            && path.ident.name == sym::to_string\n            && let ExprKind::Path(QPath::Resolved(None, path)) = receiver.kind\n            && let Res::Def(DefKind::Const { .. }, receiver_def_id) = path.res\n            && cx.ty_based_def(target).opt_parent(cx).is_diag_item(cx, sym::ToString)\n            && cx.tcx.is_diagnostic_item(sym::path_main_separator, receiver_def_id)\n            && let ty::Ref(_, ty, Mutability::Not) = cx.typeck_results().expr_ty_adjusted(expr).kind()\n            && ty.is_str()\n            && self.msrv.meets(cx, msrvs::PATH_MAIN_SEPARATOR_STR)\n        {\n            span_lint_and_sugg(\n                cx,\n                MANUAL_MAIN_SEPARATOR_STR,\n                expr.span,\n                \"taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`\",\n                \"replace with\",\n                \"std::path::MAIN_SEPARATOR_STR\".to_owned(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_non_exhaustive.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};\nuse clippy_utils::is_doc_hidden;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_indent;\nuse itertools::Itertools;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};\nuse rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData, find_attr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual implementations of the non-exhaustive pattern.\n    ///\n    /// ### Why is this bad?\n    /// Using the #[non_exhaustive] attribute expresses better the intent\n    /// and allows possible optimizations when applied to enums.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct S {\n    ///     pub a: i32,\n    ///     pub b: i32,\n    ///     _c: (),\n    /// }\n    ///\n    /// enum E {\n    ///     A,\n    ///     B,\n    ///     #[doc(hidden)]\n    ///     _C,\n    /// }\n    ///\n    /// struct T(pub i32, pub i32, ());\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[non_exhaustive]\n    /// struct S {\n    ///     pub a: i32,\n    ///     pub b: i32,\n    /// }\n    ///\n    /// #[non_exhaustive]\n    /// enum E {\n    ///     A,\n    ///     B,\n    /// }\n    ///\n    /// #[non_exhaustive]\n    /// struct T(pub i32, pub i32);\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub MANUAL_NON_EXHAUSTIVE,\n    style,\n    \"manual implementations of the non-exhaustive pattern can be simplified using #[non_exhaustive]\"\n}\n\nimpl_lint_pass!(ManualNonExhaustive => [MANUAL_NON_EXHAUSTIVE]);\n\npub struct ManualNonExhaustive {\n    msrv: Msrv,\n    constructed_enum_variants: FxHashSet<LocalDefId>,\n    potential_enums: Vec<(LocalDefId, LocalDefId, Span, Span)>,\n}\n\nimpl ManualNonExhaustive {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: conf.msrv,\n            constructed_enum_variants: FxHashSet::default(),\n            potential_enums: Vec::new(),\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if !cx.effective_visibilities.is_exported(item.owner_id.def_id) || !self.msrv.meets(cx, msrvs::NON_EXHAUSTIVE) {\n            return;\n        }\n\n        match item.kind {\n            ItemKind::Enum(_, _, def) if def.variants.len() > 1 => {\n                let iter = def.variants.iter().filter_map(|v| {\n                    (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir_attrs(v.hir_id)))\n                        .then_some((v.def_id, v.span))\n                });\n                if let Ok((id, span)) = iter.exactly_one()\n                    && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), NonExhaustive(..))\n                {\n                    self.potential_enums.push((item.owner_id.def_id, id, item.span, span));\n                }\n            },\n            ItemKind::Struct(_, _, variant_data) => {\n                let fields = variant_data.fields();\n                let private_fields = fields\n                    .iter()\n                    .filter(|field| !cx.effective_visibilities.is_exported(field.def_id));\n                if fields.len() > 1\n                    && let Ok(field) = private_fields.exactly_one()\n                    && let TyKind::Tup([]) = field.ty.kind\n                {\n                    span_lint_and_then(\n                        cx,\n                        MANUAL_NON_EXHAUSTIVE,\n                        item.span,\n                        \"this seems like a manual implementation of the non-exhaustive pattern\",\n                        |diag| {\n                            if let Some(non_exhaustive_span) =\n                                find_attr!(cx.tcx.hir_attrs(item.hir_id()), NonExhaustive(span) => *span)\n                            {\n                                diag.span_note(non_exhaustive_span, \"the struct is already non-exhaustive\");\n                            } else {\n                                let indent = snippet_indent(cx, item.span).unwrap_or_default();\n                                diag.span_suggestion_verbose(\n                                    item.span.shrink_to_lo(),\n                                    \"use the `#[non_exhaustive]` attribute instead\",\n                                    format!(\"#[non_exhaustive]\\n{indent}\"),\n                                    Applicability::MaybeIncorrect,\n                                );\n                            }\n                            diag.span_help(field.span, \"remove this field\");\n                        },\n                    );\n                }\n            },\n            _ => {},\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let ExprKind::Path(QPath::Resolved(None, p)) = &e.kind\n            && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), ctor_id) = p.res\n            && let Some(local_ctor) = ctor_id.as_local()\n        {\n            let variant_id = cx.tcx.local_parent(local_ctor);\n            self.constructed_enum_variants.insert(variant_id);\n        }\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        for &(enum_id, _, enum_span, variant_span) in self\n            .potential_enums\n            .iter()\n            .filter(|(_, variant_id, _, _)| !self.constructed_enum_variants.contains(variant_id))\n        {\n            let hir_id = cx.tcx.local_def_id_to_hir_id(enum_id);\n            span_lint_hir_and_then(\n                cx,\n                MANUAL_NON_EXHAUSTIVE,\n                hir_id,\n                enum_span,\n                \"this seems like a manual implementation of the non-exhaustive pattern\",\n                |diag| {\n                    let indent = snippet_indent(cx, enum_span).unwrap_or_default();\n                    diag.span_suggestion_verbose(\n                        enum_span.shrink_to_lo(),\n                        \"use the `#[non_exhaustive]` attribute instead\",\n                        format!(\"#[non_exhaustive]\\n{indent}\"),\n                        Applicability::MaybeIncorrect,\n                    );\n                    diag.span_help(variant_span, \"remove this variant\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_option_as_slice.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{as_some_pattern, is_none_pattern, msrvs, peel_hir_expr_refs, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Arm, Expr, ExprKind, Pat, PatKind, QPath, is_range_literal};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This detects various manual reimplementations of `Option::as_slice`.\n    ///\n    /// ### Why is this bad?\n    /// Those implementations are both more complex than calling `as_slice`\n    /// and unlike that incur a branch, pessimizing performance and leading\n    /// to more generated code.\n    ///\n    /// ### Example\n    /// ```no_run\n    ///# let opt = Some(1);\n    /// _ = opt.as_ref().map_or(&[][..], std::slice::from_ref);\n    /// _ = match opt.as_ref() {\n    ///     Some(f) => std::slice::from_ref(f),\n    ///     None => &[],\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    ///# let opt = Some(1);\n    /// _ = opt.as_slice();\n    /// _ = opt.as_slice();\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub MANUAL_OPTION_AS_SLICE,\n    complexity,\n    \"manual `Option::as_slice`\"\n}\n\nimpl_lint_pass!(ManualOptionAsSlice => [MANUAL_OPTION_AS_SLICE]);\n\npub struct ManualOptionAsSlice {\n    msrv: Msrv,\n}\n\nimpl ManualOptionAsSlice {\n    pub fn new(conf: &Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for ManualOptionAsSlice {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let span = expr.span;\n        if span.from_expansion() {\n            return;\n        }\n        match expr.kind {\n            ExprKind::Match(scrutinee, [arm1, arm2], _)\n                if is_none_pattern(cx, arm2.pat) && check_arms(cx, arm2, arm1)\n                    || is_none_pattern(cx, arm1.pat) && check_arms(cx, arm1, arm2) =>\n            {\n                check_as_ref(cx, scrutinee, span, self.msrv);\n            },\n            ExprKind::If(cond, then, Some(other)) => {\n                if let ExprKind::Let(let_expr) = cond.kind\n                    && let Some(binding) = extract_ident_from_some_pat(cx, let_expr.pat)\n                    && check_some_body(cx, binding, then)\n                    && is_empty_slice(cx, other.peel_blocks())\n                {\n                    check_as_ref(cx, let_expr.init, span, self.msrv);\n                }\n            },\n            ExprKind::MethodCall(seg, callee, [], _) if seg.ident.name == sym::unwrap_or_default => {\n                check_map(cx, callee, span, self.msrv);\n            },\n            ExprKind::MethodCall(seg, callee, [or], _) => match seg.ident.name {\n                sym::unwrap_or if is_empty_slice(cx, or) => {\n                    check_map(cx, callee, span, self.msrv);\n                },\n                sym::unwrap_or_else if returns_empty_slice(cx, or) => {\n                    check_map(cx, callee, span, self.msrv);\n                },\n                _ => {},\n            },\n            ExprKind::MethodCall(seg, callee, [or_else, map], _) => match seg.ident.name {\n                sym::map_or if is_empty_slice(cx, or_else) && is_slice_from_ref(cx, map) => {\n                    check_as_ref(cx, callee, span, self.msrv);\n                },\n                sym::map_or_else if returns_empty_slice(cx, or_else) && is_slice_from_ref(cx, map) => {\n                    check_as_ref(cx, callee, span, self.msrv);\n                },\n                _ => {},\n            },\n            _ => {},\n        }\n    }\n}\n\nfn check_map(cx: &LateContext<'_>, map: &Expr<'_>, span: Span, msrv: Msrv) {\n    if let ExprKind::MethodCall(seg, callee, [mapping], _) = map.kind\n        && seg.ident.name == sym::map\n        && is_slice_from_ref(cx, mapping)\n    {\n        check_as_ref(cx, callee, span, msrv);\n    }\n}\n\nfn check_as_ref(cx: &LateContext<'_>, expr: &Expr<'_>, span: Span, msrv: Msrv) {\n    if let ExprKind::MethodCall(seg, callee, [], _) = expr.kind\n        && seg.ident.name == sym::as_ref\n        && cx.typeck_results().expr_ty(callee).is_diag_item(cx, sym::Option)\n        && msrv.meets(\n            cx,\n            if clippy_utils::is_in_const_context(cx) {\n                msrvs::CONST_OPTION_AS_SLICE\n            } else {\n                msrvs::OPTION_AS_SLICE\n            },\n        )\n    {\n        span_lint_and_then(\n            cx,\n            MANUAL_OPTION_AS_SLICE,\n            span,\n            \"manual implementation of `Option::as_slice`\",\n            |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let callee = snippet_with_context(cx, callee.span, expr.span.ctxt(), \"_\", &mut app).0;\n                diag.span_suggestion_verbose(\n                    span,\n                    \"use `Option::as_slice` directly\",\n                    format!(\"{callee}.as_slice()\"),\n                    app,\n                );\n            },\n        );\n    }\n}\n\nfn extract_ident_from_some_pat(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<Symbol> {\n    if let Some([binding]) = as_some_pattern(cx, pat)\n        && let PatKind::Binding(_mode, _hir_id, ident, _inner_pat) = binding.kind\n    {\n        Some(ident.name)\n    } else {\n        None\n    }\n}\n\n/// Returns true if `expr` is `std::slice::from_ref(<name>)`. Used in `if let`s.\nfn check_some_body(cx: &LateContext<'_>, name: Symbol, expr: &Expr<'_>) -> bool {\n    if let ExprKind::Call(slice_from_ref, [arg]) = expr.peel_blocks().kind\n        && is_slice_from_ref(cx, slice_from_ref)\n        && let ExprKind::Path(QPath::Resolved(None, path)) = arg.kind\n        && let [seg] = path.segments\n    {\n        seg.ident.name == name\n    } else {\n        false\n    }\n}\n\nfn check_arms(cx: &LateContext<'_>, none_arm: &Arm<'_>, some_arm: &Arm<'_>) -> bool {\n    if none_arm.guard.is_none()\n        && some_arm.guard.is_none()\n        && is_empty_slice(cx, none_arm.body)\n        && let Some(name) = extract_ident_from_some_pat(cx, some_arm.pat)\n    {\n        check_some_body(cx, name, some_arm.body)\n    } else {\n        false\n    }\n}\n\nfn returns_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Path(_) => expr.res(cx).is_diag_item(cx, sym::default_fn),\n        ExprKind::Closure(cl) => is_empty_slice(cx, cx.tcx.hir_body(cl.body).value),\n        _ => false,\n    }\n}\n\n/// Returns if expr returns an empty slice. If:\n/// - An indexing operation to an empty array with a built-in range. `[][..]`\n/// - An indexing operation with a zero-ended range. `expr[..0]`\n/// - A reference to an empty array. `&[]`\n/// - Or a call to `Default::default`.\nfn is_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let expr = peel_hir_expr_refs(expr.peel_blocks()).0;\n    match expr.kind {\n        ExprKind::Index(arr, range, _) => match arr.kind {\n            ExprKind::Array([]) => is_range_literal(range),\n            ExprKind::Array(_) => {\n                let Some(range) = clippy_utils::higher::Range::hir(cx, range) else {\n                    return false;\n                };\n                range.end.is_some_and(|e| clippy_utils::is_integer_const(cx, e, 0))\n            },\n            _ => false,\n        },\n        ExprKind::Array([]) => true,\n        ExprKind::Call(def, []) => def.res(cx).is_diag_item(cx, sym::default_fn),\n        _ => false,\n    }\n}\n\nfn is_slice_from_ref(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    expr.basic_res().is_diag_item(cx, sym::slice_from_ref)\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_pop_if.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::visitors::is_local_used;\nuse clippy_utils::{eq_expr_value, is_else_clause, is_lang_item_or_ctor, peel_blocks_with_stmt, sym};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem, PatKind, RustcVersion, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\nuse std::fmt;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for code to be replaced by `pop_if` methods.\n    ///\n    /// ### Why is this bad?\n    /// Using `pop_if` is more concise and idiomatic.\n    ///\n    /// ### Known issues\n    /// Currently, the lint does not handle the case where the\n    /// `if` condition is part of an `else if` branch.\n    ///\n    /// The lint also does not handle the case where\n    /// the popped value is assigned and used.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// # use std::collections::VecDeque;\n    /// # let mut vec = vec![1, 2, 3, 4, 5];\n    /// # let mut deque: VecDeque<i32> = VecDeque::from([1, 2, 3, 4, 5]);\n    /// if vec.last().is_some_and(|x| *x > 5) {\n    ///     vec.pop().unwrap();\n    /// }\n    /// if deque.back().is_some_and(|x| *x > 5) {\n    ///     deque.pop_back().unwrap();\n    /// }\n    /// if deque.front().is_some_and(|x| *x > 5) {\n    ///     deque.pop_front().unwrap();\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::collections::VecDeque;\n    /// # let mut vec = vec![1, 2, 3, 4, 5];\n    /// # let mut deque: VecDeque<i32> = VecDeque::from([1, 2, 3, 4, 5]);\n    /// vec.pop_if(|x| *x > 5);\n    /// deque.pop_back_if(|x| *x > 5);\n    /// deque.pop_front_if(|x| *x > 5);\n    /// ```\n    #[clippy::version = \"1.95.0\"]\n    pub MANUAL_POP_IF,\n    complexity,\n    \"manual implementation of `pop_if` methods\"\n}\n\nimpl_lint_pass!(ManualPopIf => [MANUAL_POP_IF]);\n\npub struct ManualPopIf {\n    msrv: Msrv,\n}\n\nimpl ManualPopIf {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\n#[allow(clippy::enum_variant_names)]\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\nenum ManualPopIfKind {\n    Vec,\n    VecDequeBack,\n    VecDequeFront,\n}\n\nimpl ManualPopIfKind {\n    fn check_method(self) -> Symbol {\n        match self {\n            ManualPopIfKind::Vec => sym::last,\n            ManualPopIfKind::VecDequeBack => sym::back,\n            ManualPopIfKind::VecDequeFront => sym::front,\n        }\n    }\n\n    fn pop_method(self) -> Symbol {\n        match self {\n            ManualPopIfKind::Vec => sym::pop,\n            ManualPopIfKind::VecDequeBack => sym::pop_back,\n            ManualPopIfKind::VecDequeFront => sym::pop_front,\n        }\n    }\n\n    fn pop_if_method(self) -> Symbol {\n        match self {\n            ManualPopIfKind::Vec => sym::pop_if,\n            ManualPopIfKind::VecDequeBack => sym::pop_back_if,\n            ManualPopIfKind::VecDequeFront => sym::pop_front_if,\n        }\n    }\n\n    fn is_diag_item(self, cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n        let ty = cx.typeck_results().expr_ty(expr).peel_refs();\n        match self {\n            ManualPopIfKind::Vec => ty.is_diag_item(cx, sym::Vec),\n            ManualPopIfKind::VecDequeBack | ManualPopIfKind::VecDequeFront => ty.is_diag_item(cx, sym::VecDeque),\n        }\n    }\n\n    fn msrv(self) -> RustcVersion {\n        match self {\n            ManualPopIfKind::Vec => msrvs::VEC_POP_IF,\n            ManualPopIfKind::VecDequeBack => msrvs::VEC_DEQUE_POP_BACK_IF,\n            ManualPopIfKind::VecDequeFront => msrvs::VEC_DEQUE_POP_FRONT_IF,\n        }\n    }\n}\n\nimpl fmt::Display for ManualPopIfKind {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            ManualPopIfKind::Vec => write!(f, \"`Vec::pop_if`\"),\n            ManualPopIfKind::VecDequeBack => write!(f, \"`VecDeque::pop_back_if`\"),\n            ManualPopIfKind::VecDequeFront => write!(f, \"`VecDeque::pop_front_if`\"),\n        }\n    }\n}\n\nstruct ManualPopIfPattern<'tcx> {\n    kind: ManualPopIfKind,\n\n    /// The collection (`vec` in `vec.last()`)\n    collection_expr: &'tcx Expr<'tcx>,\n\n    /// The closure (`*x > 5` in `|x| *x > 5`)\n    predicate: &'tcx Expr<'tcx>,\n\n    /// Parameter name for the closure (`x` in `|x| *x > 5`)\n    param_name: Symbol,\n\n    /// Span of the if expression (including the `if` keyword)\n    if_span: Span,\n}\n\nimpl ManualPopIfPattern<'_> {\n    fn emit_lint(&self, cx: &LateContext<'_>) {\n        let mut app = Applicability::MachineApplicable;\n        let ctxt = self.if_span.ctxt();\n        let collection_snippet = snippet_with_context(cx, self.collection_expr.span, ctxt, \"..\", &mut app).0;\n        let predicate_snippet = snippet_with_context(cx, self.predicate.span, ctxt, \"..\", &mut app).0;\n        let param_name = self.param_name;\n        let pop_if_method = self.kind.pop_if_method();\n\n        let suggestion = format!(\"{collection_snippet}.{pop_if_method}(|{param_name}| {predicate_snippet});\");\n\n        span_lint_and_sugg(\n            cx,\n            MANUAL_POP_IF,\n            self.if_span,\n            format!(\"manual implementation of {}\", self.kind),\n            \"try\",\n            suggestion,\n            app,\n        );\n    }\n}\n\nfn pop_value_is_used(then_block: &Expr<'_>) -> bool {\n    let ExprKind::Block(block, _) = then_block.kind else {\n        return true;\n    };\n\n    if block.expr.is_some() {\n        return true;\n    }\n\n    match block.stmts {\n        [stmt] => !matches!(stmt.kind, StmtKind::Semi(_) | StmtKind::Item(_)),\n        [.., last] => matches!(last.kind, StmtKind::Expr(_)),\n        [] => false,\n    }\n}\n\n/// Checks for the pattern:\n/// ```ignore\n/// if vec.last().is_some_and(|x| *x > 5) {\n///     vec.pop().unwrap();\n/// }\n/// ```\nfn check_is_some_and_pattern<'tcx>(\n    cx: &LateContext<'tcx>,\n    cond: &'tcx Expr<'_>,\n    then_block: &'tcx Expr<'_>,\n    if_expr_span: Span,\n    kind: ManualPopIfKind,\n) -> Option<ManualPopIfPattern<'tcx>> {\n    if pop_value_is_used(then_block) {\n        return None;\n    }\n\n    let check_method = kind.check_method();\n    let pop_method = kind.pop_method();\n\n    if let ExprKind::MethodCall(path, receiver, [closure_arg], _) = cond.kind\n        && path.ident.name == sym::is_some_and\n        && let ExprKind::MethodCall(check_path, collection_expr, [], _) = receiver.kind\n        && check_path.ident.name == check_method\n        && kind.is_diag_item(cx, collection_expr)\n        && let ExprKind::Closure(closure) = closure_arg.kind\n        && let body = cx.tcx.hir_body(closure.body)\n        && let Some((pop_collection, _pop_span)) = check_pop_unwrap(then_block, pop_method)\n        && eq_expr_value(cx, collection_expr, pop_collection)\n        && let Some(param) = body.params.first()\n        && let Some(ident) = param.pat.simple_ident()\n    {\n        return Some(ManualPopIfPattern {\n            kind,\n            collection_expr,\n            predicate: body.value,\n            param_name: ident.name,\n            if_span: if_expr_span,\n        });\n    }\n\n    None\n}\n\n/// Checks for the pattern:\n/// ```ignore\n/// if let Some(x) = vec.last() {\n///     if *x > 5 {\n///         vec.pop().unwrap();\n///     }\n/// }\n/// ```\nfn check_if_let_pattern<'tcx>(\n    cx: &LateContext<'tcx>,\n    cond: &'tcx Expr<'_>,\n    then_block: &'tcx Expr<'_>,\n    if_expr_span: Span,\n    kind: ManualPopIfKind,\n) -> Option<ManualPopIfPattern<'tcx>> {\n    let check_method = kind.check_method();\n    let pop_method = kind.pop_method();\n\n    if let ExprKind::Let(let_expr) = cond.kind\n        && let PatKind::TupleStruct(qpath, [binding_pat], _) = let_expr.pat.kind\n    {\n        let res = cx.qpath_res(&qpath, let_expr.pat.hir_id);\n\n        if let Some(def_id) = res.opt_def_id()\n            && is_lang_item_or_ctor(cx, def_id, LangItem::OptionSome)\n            && let PatKind::Binding(_, binding_id, binding_name, _) = binding_pat.kind\n            && let ExprKind::MethodCall(path, collection_expr, [], _) = let_expr.init.kind\n            && path.ident.name == check_method\n            && kind.is_diag_item(cx, collection_expr)\n            && let ExprKind::Block(block, _) = then_block.kind\n        {\n            // The inner if can be either a statement or a block expression\n            let inner_if = match (block.stmts, block.expr) {\n                ([stmt], _) => match stmt.kind {\n                    StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr,\n                    _ => return None,\n                },\n                ([], Some(expr)) => expr,\n                _ => return None,\n            };\n\n            if let ExprKind::If(inner_cond, inner_then, None) = inner_if.kind\n                && is_local_used(cx, inner_cond, binding_id)\n                && !pop_value_is_used(inner_then)\n                && let Some((pop_collection, _pop_span)) = check_pop_unwrap(inner_then, pop_method)\n                && eq_expr_value(cx, collection_expr, pop_collection)\n            {\n                return Some(ManualPopIfPattern {\n                    kind,\n                    collection_expr,\n                    predicate: inner_cond,\n                    param_name: binding_name.name,\n                    if_span: if_expr_span,\n                });\n            }\n        }\n    }\n\n    None\n}\n\n/// Checks for the pattern:\n/// ```ignore\n/// if let Some(x) = vec.last() && *x > 5 {\n///     vec.pop().unwrap();\n/// }\n/// ```\nfn check_let_chain_pattern<'tcx>(\n    cx: &LateContext<'tcx>,\n    cond: &'tcx Expr<'_>,\n    then_block: &'tcx Expr<'_>,\n    if_expr_span: Span,\n    kind: ManualPopIfKind,\n) -> Option<ManualPopIfPattern<'tcx>> {\n    if pop_value_is_used(then_block) {\n        return None;\n    }\n\n    let check_method = kind.check_method();\n    let pop_method = kind.pop_method();\n\n    if let ExprKind::Binary(op, left, right) = cond.kind\n        && op.node == rustc_ast::BinOpKind::And\n        && let ExprKind::Let(let_expr) = left.kind\n        && let PatKind::TupleStruct(qpath, [binding_pat], _) = let_expr.pat.kind\n    {\n        let res = cx.qpath_res(&qpath, let_expr.pat.hir_id);\n\n        if let Some(def_id) = res.opt_def_id()\n            && is_lang_item_or_ctor(cx, def_id, LangItem::OptionSome)\n            && let PatKind::Binding(_, binding_id, binding_name, _) = binding_pat.kind\n            && let ExprKind::MethodCall(path, collection_expr, [], _) = let_expr.init.kind\n            && path.ident.name == check_method\n            && kind.is_diag_item(cx, collection_expr)\n            && is_local_used(cx, right, binding_id)\n            && !pop_value_is_used(then_block)\n            && let Some((pop_collection, _pop_span)) = check_pop_unwrap(then_block, pop_method)\n            && eq_expr_value(cx, collection_expr, pop_collection)\n        {\n            return Some(ManualPopIfPattern {\n                kind,\n                collection_expr,\n                predicate: right,\n                param_name: binding_name.name,\n                if_span: if_expr_span,\n            });\n        }\n    }\n\n    None\n}\n\n/// Checks for the pattern:\n/// ```ignore\n/// if vec.last().map(|x| *x > 5).unwrap_or(false) {\n///     vec.pop().unwrap();\n/// }\n/// ```\nfn check_map_unwrap_or_pattern<'tcx>(\n    cx: &LateContext<'tcx>,\n    cond: &'tcx Expr<'_>,\n    then_block: &'tcx Expr<'_>,\n    if_expr_span: Span,\n    kind: ManualPopIfKind,\n) -> Option<ManualPopIfPattern<'tcx>> {\n    if pop_value_is_used(then_block) {\n        return None;\n    }\n\n    let check_method = kind.check_method();\n    let pop_method = kind.pop_method();\n\n    if let ExprKind::MethodCall(unwrap_path, receiver, [default_arg], _) = cond.kind\n        && unwrap_path.ident.name == sym::unwrap_or\n        && matches!(default_arg.kind, ExprKind::Lit(lit) if matches!(lit.node, LitKind::Bool(false)))\n        && let ExprKind::MethodCall(map_path, map_receiver, [closure_arg], _) = receiver.kind\n        && map_path.ident.name == sym::map\n        && let ExprKind::MethodCall(check_path, collection_expr, [], _) = map_receiver.kind\n        && check_path.ident.name == check_method\n        && kind.is_diag_item(cx, collection_expr)\n        && let ExprKind::Closure(closure) = closure_arg.kind\n        && let body = cx.tcx.hir_body(closure.body)\n        && cx.typeck_results().expr_ty(body.value).is_bool()\n        && let Some((pop_collection, _pop_span)) = check_pop_unwrap(then_block, pop_method)\n        && eq_expr_value(cx, collection_expr, pop_collection)\n        && let Some(param) = body.params.first()\n        && let Some(ident) = param.pat.simple_ident()\n    {\n        return Some(ManualPopIfPattern {\n            kind,\n            collection_expr,\n            predicate: body.value,\n            param_name: ident.name,\n            if_span: if_expr_span,\n        });\n    }\n\n    None\n}\n\n/// Checks for `collection.<pop_method>().unwrap()` or `collection.<pop_method>().expect(..)`\n/// and returns the collection and the span of the peeled expr\nfn check_pop_unwrap<'tcx>(expr: &'tcx Expr<'_>, pop_method: Symbol) -> Option<(&'tcx Expr<'tcx>, Span)> {\n    let inner_expr = peel_blocks_with_stmt(expr);\n\n    if let ExprKind::MethodCall(unwrap_path, receiver, _, _) = inner_expr.kind\n        && matches!(unwrap_path.ident.name, sym::unwrap | sym::expect)\n        && let ExprKind::MethodCall(pop_path, collection_expr, [], _) = receiver.kind\n        && pop_path.ident.name == pop_method\n    {\n        return Some((collection_expr, inner_expr.span));\n    }\n\n    None\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualPopIf {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let ExprKind::If(cond, then_block, None) = expr.kind else {\n            return;\n        };\n\n        // Do not lint if we are in an else-if branch.\n        if is_else_clause(cx.tcx, expr) {\n            return;\n        }\n\n        for kind in [\n            ManualPopIfKind::Vec,\n            ManualPopIfKind::VecDequeBack,\n            ManualPopIfKind::VecDequeFront,\n        ] {\n            if let Some(pattern) = check_is_some_and_pattern(cx, cond, then_block, expr.span, kind)\n                .or_else(|| check_if_let_pattern(cx, cond, then_block, expr.span, kind))\n                .or_else(|| check_let_chain_pattern(cx, cond, then_block, expr.span, kind))\n                .or_else(|| check_map_unwrap_or_pattern(cx, cond, then_block, expr.span, kind))\n                && self.msrv.meets(cx, kind.msrv())\n            {\n                pattern.emit_lint(cx);\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_range_patterns.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_ast::LitKind;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{PatExpr, PatExprKind, PatKind, RangeEnd};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{DUMMY_SP, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for combined OR patterns that are all contained in a specific range,\n    /// e.g. `6 | 4 | 5 | 9 | 7 | 8` can be rewritten as `4..=9`.\n    ///\n    /// ### Why is this bad?\n    /// Using an explicit range is more concise and easier to read.\n    ///\n    /// ### Known issues\n    /// This lint intentionally does not handle numbers greater than `i128::MAX` for `u128` literals\n    /// in order to support negative numbers.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 6;\n    /// let foo = matches!(x, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = 6;\n    /// let foo = matches!(x, 1..=10);\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub MANUAL_RANGE_PATTERNS,\n    complexity,\n    \"manually writing range patterns using a combined OR pattern (`|`)\"\n}\n\ndeclare_lint_pass!(ManualRangePatterns => [MANUAL_RANGE_PATTERNS]);\n\nfn expr_as_i128(expr: &PatExpr<'_>) -> Option<i128> {\n    if let PatExprKind::Lit { lit, negated } = expr.kind\n        && let LitKind::Int(num, _) = lit.node\n    {\n        // Intentionally not handling numbers greater than i128::MAX (for u128 literals) for now.\n        let n = i128::try_from(num.get()).ok()?;\n        Some(if negated { -n } else { n })\n    } else {\n        None\n    }\n}\n\n#[derive(Copy, Clone)]\nstruct Num {\n    val: i128,\n    span: Span,\n}\n\nimpl Num {\n    fn new(expr: &PatExpr<'_>) -> Option<Self> {\n        Some(Self {\n            val: expr_as_i128(expr)?,\n            span: expr.span,\n        })\n    }\n\n    fn dummy(val: i128) -> Self {\n        Self { val, span: DUMMY_SP }\n    }\n\n    fn min(self, other: Self) -> Self {\n        if self.val < other.val { self } else { other }\n    }\n}\n\nimpl LateLintPass<'_> for ManualRangePatterns {\n    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &'_ rustc_hir::Pat<'_>) {\n        // a pattern like 1 | 2 seems fine, lint if there are at least 3 alternatives\n        // or more then one range (exclude triggering on stylistic using OR with one element\n        // like described https://github.com/rust-lang/rust-clippy/issues/11825)\n        if let PatKind::Or(pats) = pat.kind\n            && (pats.len() >= 3 || (pats.len() > 1 && pats.iter().any(|p| matches!(p.kind, PatKind::Range(..)))))\n            && !pat.span.in_external_macro(cx.sess().source_map())\n        {\n            let mut min = Num::dummy(i128::MAX);\n            let mut max = Num::dummy(i128::MIN);\n            let mut range_kind = RangeEnd::Included;\n            let mut numbers_found = FxHashSet::default();\n            let mut ranges_found = Vec::new();\n\n            for pat in pats {\n                if let PatKind::Expr(lit) = pat.kind\n                    && let Some(num) = Num::new(lit)\n                {\n                    numbers_found.insert(num.val);\n\n                    min = min.min(num);\n                    if num.val >= max.val {\n                        max = num;\n                        range_kind = RangeEnd::Included;\n                    }\n                } else if let PatKind::Range(Some(left), Some(right), end) = pat.kind\n                    && let Some(left) = Num::new(left)\n                    && let Some(mut right) = Num::new(right)\n                {\n                    if let RangeEnd::Excluded = end {\n                        right.val -= 1;\n                    }\n\n                    min = min.min(left);\n                    if right.val > max.val {\n                        max = right;\n                        range_kind = end;\n                    }\n                    ranges_found.push(left.val..=right.val);\n                } else {\n                    return;\n                }\n            }\n\n            let mut num = min.val;\n            while num <= max.val {\n                if numbers_found.contains(&num) {\n                    num += 1;\n                }\n                // Given a list of (potentially overlapping) ranges like:\n                // 1..=5, 3..=7, 6..=10\n                // We want to find the range with the highest end that still contains the current number\n                else if let Some(range) = ranges_found\n                    .iter()\n                    .filter(|range| range.contains(&num))\n                    .max_by_key(|range| range.end())\n                {\n                    num = range.end() + 1;\n                } else {\n                    return;\n                }\n            }\n\n            span_lint_and_then(\n                cx,\n                MANUAL_RANGE_PATTERNS,\n                pat.span,\n                \"this OR pattern can be rewritten using a range\",\n                |diag| {\n                    if let Some(min) = min.span.get_source_text(cx)\n                        && let Some(max) = max.span.get_source_text(cx)\n                    {\n                        diag.span_suggestion(\n                            pat.span,\n                            \"try\",\n                            format!(\"{min}{range_kind}{max}\"),\n                            Applicability::MachineApplicable,\n                        );\n                    }\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_rem_euclid.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, FullInt};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_in_const_context;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet_with_context;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::SyntaxContext;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for an expression like `((x % 4) + 4) % 4` which is a common manual reimplementation\n    /// of `x.rem_euclid(4)`.\n    ///\n    /// ### Why is this bad?\n    /// It's simpler and more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: i32 = 24;\n    /// let rem = ((x % 4) + 4) % 4;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x: i32 = 24;\n    /// let rem = x.rem_euclid(4);\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub MANUAL_REM_EUCLID,\n    complexity,\n    \"manually reimplementing `rem_euclid`\"\n}\n\nimpl_lint_pass!(ManualRemEuclid => [MANUAL_REM_EUCLID]);\n\npub struct ManualRemEuclid {\n    msrv: Msrv,\n}\n\nimpl ManualRemEuclid {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        // (x % c + c) % c\n        if let ExprKind::Binary(rem_op, rem_lhs, rem_rhs) = expr.kind\n            && rem_op.node == BinOpKind::Rem\n            && let ExprKind::Binary(add_op, add_lhs, add_rhs) = rem_lhs.kind\n            && add_op.node == BinOpKind::Add\n            && let ctxt = expr.span.ctxt()\n            && rem_lhs.span.ctxt() == ctxt\n            && rem_rhs.span.ctxt() == ctxt\n            && add_lhs.span.ctxt() == ctxt\n            && add_rhs.span.ctxt() == ctxt\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && let Some(const1) = check_for_unsigned_int_constant(cx, ctxt, rem_rhs)\n            && let Some((const2, add_other)) = check_for_either_unsigned_int_constant(cx, ctxt, add_lhs, add_rhs)\n            && let ExprKind::Binary(rem2_op, rem2_lhs, rem2_rhs) = add_other.kind\n            && rem2_op.node == BinOpKind::Rem\n            && const1 == const2\n            && let Some(hir_id) = rem2_lhs.res_local_id()\n            && let Some(const3) = check_for_unsigned_int_constant(cx, ctxt, rem2_rhs)\n            // Also ensures the const is nonzero since zero can't be a divisor\n            && const2 == const3\n            && rem2_lhs.span.ctxt() == ctxt\n            && rem2_rhs.span.ctxt() == ctxt\n            && self.msrv.meets(cx, msrvs::REM_EUCLID)\n            && (self.msrv.meets(cx, msrvs::REM_EUCLID_CONST) || !is_in_const_context(cx))\n        {\n            // Apply only to params or locals with annotated types\n            match cx.tcx.parent_hir_node(hir_id) {\n                Node::Param(..) => (),\n                Node::LetStmt(local) => {\n                    let Some(ty) = local.ty else { return };\n                    if matches!(ty.kind, TyKind::Infer(())) {\n                        return;\n                    }\n                },\n                _ => return,\n            }\n\n            let mut app = Applicability::MachineApplicable;\n            let rem_of = snippet_with_context(cx, rem2_lhs.span, ctxt, \"_\", &mut app).0;\n            span_lint_and_sugg(\n                cx,\n                MANUAL_REM_EUCLID,\n                expr.span,\n                \"manual `rem_euclid` implementation\",\n                \"consider using\",\n                format!(\"{rem_of}.rem_euclid({const1})\"),\n                app,\n            );\n        }\n    }\n}\n\n// Checks if either the left or right expressions can be an unsigned int constant and returns that\n// constant along with the other expression unchanged if so\nfn check_for_either_unsigned_int_constant<'a>(\n    cx: &'a LateContext<'_>,\n    ctxt: SyntaxContext,\n    left: &'a Expr<'_>,\n    right: &'a Expr<'_>,\n) -> Option<(u128, &'a Expr<'a>)> {\n    check_for_unsigned_int_constant(cx, ctxt, left)\n        .map(|int_const| (int_const, right))\n        .or_else(|| check_for_unsigned_int_constant(cx, ctxt, right).map(|int_const| (int_const, left)))\n}\n\nfn check_for_unsigned_int_constant<'a>(\n    cx: &'a LateContext<'_>,\n    ctxt: SyntaxContext,\n    expr: &'a Expr<'_>,\n) -> Option<u128> {\n    let int_const = ConstEvalCtxt::new(cx).eval_full_int(expr, ctxt)?;\n    match int_const {\n        FullInt::S(s) => s.try_into().ok(),\n        FullInt::U(u) => Some(u),\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_retain.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{SpanlessEq, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::ExprKind::Assign;\nuse rustc_hir::def_id::DefId;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::Symbol;\n\nconst ACCEPTABLE_METHODS: [Symbol; 5] = [\n    sym::binaryheap_iter,\n    sym::hashset_iter,\n    sym::btreeset_iter,\n    sym::slice_iter,\n    sym::vecdeque_iter,\n];\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for code to be replaced by `.retain()`.\n    /// ### Why is this bad?\n    /// `.retain()` is simpler and avoids needless allocation.\n    /// ### Example\n    /// ```no_run\n    /// let mut vec = vec![0, 1, 2];\n    /// vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();\n    /// vec = vec.into_iter().filter(|x| x % 2 == 0).collect();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut vec = vec![0, 1, 2];\n    /// vec.retain(|x| x % 2 == 0);\n    /// vec.retain(|x| x % 2 == 0);\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub MANUAL_RETAIN,\n    perf,\n    \"`retain()` is simpler and the same functionalities\"\n}\n\nimpl_lint_pass!(ManualRetain => [MANUAL_RETAIN]);\n\npub struct ManualRetain {\n    msrv: Msrv,\n}\n\nimpl ManualRetain {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualRetain {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        if let Assign(left_expr, collect_expr, _) = &expr.kind\n            && let hir::ExprKind::MethodCall(seg, target_expr, [], _) = &collect_expr.kind\n            && seg.args.is_none()\n            && let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id)\n            && cx.tcx.is_diagnostic_item(sym::iterator_collect_fn, collect_def_id)\n        {\n            check_into_iter(cx, left_expr, target_expr, expr.span, self.msrv);\n            check_iter(cx, left_expr, target_expr, expr.span, self.msrv);\n            check_to_owned(cx, left_expr, target_expr, expr.span, self.msrv);\n        }\n    }\n}\n\nfn check_into_iter(\n    cx: &LateContext<'_>,\n    left_expr: &hir::Expr<'_>,\n    target_expr: &hir::Expr<'_>,\n    parent_expr_span: Span,\n    msrv: Msrv,\n) {\n    if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind\n        && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::iter_filter, filter_def_id)\n        && let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &into_iter_expr.kind\n        && let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id)\n        && Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()\n        && match_acceptable_type(cx, left_expr, msrv)\n        && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)\n        && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = target_expr.kind\n        && let hir::ExprKind::Closure(closure) = closure_expr.kind\n        && let filter_body = cx.tcx.hir_body(closure.body)\n        && let [filter_params] = filter_body.params\n    {\n        if match_map_type(cx, left_expr) {\n            if let hir::PatKind::Tuple([key_pat, value_pat], _) = filter_params.pat.kind\n                && let Some(sugg) = make_sugg(cx, key_pat, value_pat, left_expr, filter_body)\n            {\n                make_span_lint_and_sugg(cx, parent_expr_span, sugg);\n            }\n            // Cannot lint other cases because `retain` requires two parameters\n        } else {\n            // Can always move because `retain` and `filter` have the same bound on the predicate\n            // for other types\n            make_span_lint_and_sugg(\n                cx,\n                parent_expr_span,\n                format!(\n                    \"{}.retain({})\",\n                    snippet(cx, left_expr.span, \"..\"),\n                    snippet(cx, closure_expr.span, \"..\")\n                ),\n            );\n        }\n    }\n}\n\nfn check_iter(\n    cx: &LateContext<'_>,\n    left_expr: &hir::Expr<'_>,\n    target_expr: &hir::Expr<'_>,\n    parent_expr_span: Span,\n    msrv: Msrv,\n) {\n    if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind\n        && let Some(copied_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)\n        && let Some(copied_name) = cx.tcx.get_diagnostic_name(copied_def_id)\n        && matches!(copied_name, sym::iter_copied | sym::iter_cloned)\n        && let hir::ExprKind::MethodCall(_, iter_expr, [_], _) = &filter_expr.kind\n        && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::iter_filter, filter_def_id)\n        && let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &iter_expr.kind\n        && let Some(iter_expr_def_id) = cx.typeck_results().type_dependent_def_id(iter_expr.hir_id)\n        && match_acceptable_sym(cx, iter_expr_def_id)\n        && match_acceptable_type(cx, left_expr, msrv)\n        && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)\n        && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind\n        && let hir::ExprKind::Closure(closure) = closure_expr.kind\n        && let filter_body = cx.tcx.hir_body(closure.body)\n        && let [filter_params] = filter_body.params\n    {\n        match filter_params.pat.kind {\n            // hir::PatKind::Binding(_, _, _, None) => {\n            //     // Be conservative now. Do nothing here.\n            //     // TODO: Ideally, we can rewrite the lambda by stripping one level of reference\n            // },\n            hir::PatKind::Tuple([_, _], _) => {\n                // the `&&` reference for the `filter` method will be auto derefed to `ref`\n                // so, we can directly use the lambda\n                // https://doc.rust-lang.org/reference/patterns.html#binding-modes\n                make_span_lint_and_sugg(\n                    cx,\n                    parent_expr_span,\n                    format!(\n                        \"{}.retain({})\",\n                        snippet(cx, left_expr.span, \"..\"),\n                        snippet(cx, closure_expr.span, \"..\")\n                    ),\n                );\n            },\n            hir::PatKind::Ref(pat, _, _) => make_span_lint_and_sugg(\n                cx,\n                parent_expr_span,\n                format!(\n                    \"{}.retain(|{}| {})\",\n                    snippet(cx, left_expr.span, \"..\"),\n                    snippet(cx, pat.span, \"..\"),\n                    snippet(cx, filter_body.value.span, \"..\")\n                ),\n            ),\n            _ => {},\n        }\n    }\n}\n\nfn check_to_owned(\n    cx: &LateContext<'_>,\n    left_expr: &hir::Expr<'_>,\n    target_expr: &hir::Expr<'_>,\n    parent_expr_span: Span,\n    msrv: Msrv,\n) {\n    if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind\n        && let Some(to_owned_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::to_owned_method, to_owned_def_id)\n        && let hir::ExprKind::MethodCall(_, chars_expr, [_], _) = &filter_expr.kind\n        && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::iter_filter, filter_def_id)\n        && let hir::ExprKind::MethodCall(_, str_expr, [], _) = &chars_expr.kind\n        && let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::str_chars, chars_expr_def_id)\n        && let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()\n        && ty.is_lang_item(cx, hir::LangItem::String)\n        && SpanlessEq::new(cx).eq_expr(left_expr, str_expr)\n        && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind\n        && let hir::ExprKind::Closure(closure) = closure_expr.kind\n        && let filter_body = cx.tcx.hir_body(closure.body)\n        && let [filter_params] = filter_body.params\n        && msrv.meets(cx, msrvs::STRING_RETAIN)\n        && let hir::PatKind::Ref(pat, _, _) = filter_params.pat.kind\n    {\n        make_span_lint_and_sugg(\n            cx,\n            parent_expr_span,\n            format!(\n                \"{}.retain(|{}| {})\",\n                snippet(cx, left_expr.span, \"..\"),\n                snippet(cx, pat.span, \"..\"),\n                snippet(cx, filter_body.value.span, \"..\")\n            ),\n        );\n    }\n    // Be conservative now. Do nothing for the `Binding` case.\n    // TODO: Ideally, we can rewrite the lambda by stripping one level of reference\n}\n\nfn make_sugg(\n    cx: &LateContext<'_>,\n    key_pat: &rustc_hir::Pat<'_>,\n    value_pat: &rustc_hir::Pat<'_>,\n    left_expr: &hir::Expr<'_>,\n    filter_body: &hir::Body<'_>,\n) -> Option<String> {\n    match (&key_pat.kind, &value_pat.kind) {\n        (hir::PatKind::Binding(_, _, key_param_ident, None), hir::PatKind::Binding(_, _, value_param_ident, None)) => {\n            Some(format!(\n                \"{}.retain(|{key_param_ident}, &mut {value_param_ident}| {})\",\n                snippet(cx, left_expr.span, \"..\"),\n                snippet(cx, filter_body.value.span, \"..\")\n            ))\n        },\n        (hir::PatKind::Binding(_, _, key_param_ident, None), hir::PatKind::Wild) => Some(format!(\n            \"{}.retain(|{key_param_ident}, _| {})\",\n            snippet(cx, left_expr.span, \"..\"),\n            snippet(cx, filter_body.value.span, \"..\")\n        )),\n        (hir::PatKind::Wild, hir::PatKind::Binding(_, _, value_param_ident, None)) => Some(format!(\n            \"{}.retain(|_, &mut {value_param_ident}| {})\",\n            snippet(cx, left_expr.span, \"..\"),\n            snippet(cx, filter_body.value.span, \"..\")\n        )),\n        _ => None,\n    }\n}\n\nfn match_acceptable_sym(cx: &LateContext<'_>, collect_def_id: DefId) -> bool {\n    cx.tcx\n        .get_diagnostic_name(collect_def_id)\n        .is_some_and(|collect_name| ACCEPTABLE_METHODS.contains(&collect_name))\n}\n\nfn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: Msrv) -> bool {\n    let ty = cx.typeck_results().expr_ty(expr).peel_refs();\n    let required = match ty.opt_diag_name(cx) {\n        Some(sym::BinaryHeap) => msrvs::BINARY_HEAP_RETAIN,\n        Some(sym::BTreeSet) => msrvs::BTREE_SET_RETAIN,\n        Some(sym::BTreeMap) => msrvs::BTREE_MAP_RETAIN,\n        Some(sym::HashSet) => msrvs::HASH_SET_RETAIN,\n        Some(sym::HashMap) => msrvs::HASH_MAP_RETAIN,\n        Some(sym::Vec | sym::VecDeque) => return true,\n        _ => return false,\n    };\n    msrv.meets(cx, required)\n}\n\nfn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {\n    let ty = cx.typeck_results().expr_ty(expr).peel_refs();\n    matches!(ty.opt_diag_name(cx), Some(sym::BTreeMap | sym::HashMap))\n}\n\nfn make_span_lint_and_sugg(cx: &LateContext<'_>, span: Span, sugg: String) {\n    span_lint_and_sugg(\n        cx,\n        MANUAL_RETAIN,\n        span,\n        \"this expression can be written more simply using `.retain()`\",\n        \"consider calling `.retain()` instead\",\n        sugg,\n        Applicability::MachineApplicable,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_rotate.rs",
    "content": "use std::fmt::Display;\n\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// It detects manual bit rotations that could be rewritten using standard\n    /// functions `rotate_left` or `rotate_right`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Calling the function better conveys the intent.\n    ///\n    /// ### Known issues\n    ///\n    /// Currently, the lint only catches shifts by constant amount.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 12345678_u32;\n    /// let _ = (x >> 8) | (x << 24);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = 12345678_u32;\n    /// let _ = x.rotate_right(8);\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub MANUAL_ROTATE,\n    style,\n    \"using bit shifts to rotate integers\"\n}\n\ndeclare_lint_pass!(ManualRotate => [MANUAL_ROTATE]);\n\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\nenum ShiftDirection {\n    Left,\n    Right,\n}\n\nimpl Display for ShiftDirection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.write_str(match self {\n            Self::Left => \"rotate_left\",\n            Self::Right => \"rotate_right\",\n        })\n    }\n}\n\nfn parse_shift<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(ShiftDirection, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {\n    if let ExprKind::Binary(op, l, r) = expr.kind {\n        let dir = match op.node {\n            BinOpKind::Shl => ShiftDirection::Left,\n            BinOpKind::Shr => ShiftDirection::Right,\n            _ => return None,\n        };\n        return Some((dir, l, r));\n    }\n    None\n}\n\nimpl LateLintPass<'_> for ManualRotate {\n    fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if let ExprKind::Binary(op, l, r) = expr.kind\n            && let BinOpKind::Add | BinOpKind::BitOr = op.node\n            && let Some((l_shift_dir, l_expr, l_amount)) = parse_shift(l)\n            && let Some((r_shift_dir, r_expr, r_amount)) = parse_shift(r)\n            && l_shift_dir != r_shift_dir\n            && clippy_utils::eq_expr_value(cx, l_expr, r_expr)\n            && let Some(bit_width) = match cx.typeck_results().expr_ty(expr).kind() {\n                ty::Int(itype) => itype.bit_width(),\n                ty::Uint(itype) => itype.bit_width(),\n                _ => return,\n            }\n        {\n            let const_eval = ConstEvalCtxt::new(cx);\n\n            let ctxt = expr.span.ctxt();\n            let (shift_function, amount) = if let Some(Constant::Int(l_amount_val)) =\n                const_eval.eval_local(l_amount, ctxt)\n                && let Some(Constant::Int(r_amount_val)) = const_eval.eval_local(r_amount, ctxt)\n                && l_amount_val + r_amount_val == u128::from(bit_width)\n            {\n                if l_amount_val < r_amount_val {\n                    (l_shift_dir, l_amount)\n                } else {\n                    (r_shift_dir, r_amount)\n                }\n            } else {\n                let (amount1, binop, minuend, amount2, shift_direction) = match (l_amount.kind, r_amount.kind) {\n                    (_, ExprKind::Binary(binop, minuend, other)) => (l_amount, binop, minuend, other, l_shift_dir),\n                    (ExprKind::Binary(binop, minuend, other), _) => (r_amount, binop, minuend, other, r_shift_dir),\n                    _ => return,\n                };\n\n                if let Some(Constant::Int(minuend)) = const_eval.eval_local(minuend, ctxt)\n                    && clippy_utils::eq_expr_value(cx, amount1, amount2)\n                    // (x << s) | (x >> bit_width - s)\n                    && ((binop.node == BinOpKind::Sub && u128::from(bit_width) == minuend)\n                        // (x << s) | (x >> (bit_width - 1) ^ s)\n                        || (binop.node == BinOpKind::BitXor && u128::from(bit_width).checked_sub(minuend) == Some(1)))\n                {\n                    // NOTE: we take these from the side that _doesn't_ have the binop, since it's probably simpler\n                    (shift_direction, amount1)\n                } else {\n                    return;\n                }\n            };\n\n            let mut applicability = Applicability::MachineApplicable;\n            let expr_sugg = sugg::Sugg::hir_with_applicability(cx, l_expr, \"_\", &mut applicability).maybe_paren();\n            let amount = sugg::Sugg::hir_with_applicability(cx, amount, \"_\", &mut applicability);\n            span_lint_and_sugg(\n                cx,\n                MANUAL_ROTATE,\n                expr.span,\n                \"there is no need to manually implement bit rotation\",\n                \"this expression can be rewritten as\",\n                format!(\"{expr_sugg}.{shift_function}({amount})\"),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_slice_size_calculation.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::peel_and_count_ty_refs;\nuse clippy_utils::{expr_or_init, is_in_const_context, std_or_core, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// When `a` is `&[T]`, detect `a.len() * size_of::<T>()` and suggest `size_of_val(a)`\n    /// instead.\n    ///\n    /// ### Why is this better?\n    /// * Shorter to write\n    /// * Removes the need for the human and the compiler to worry about overflow in the\n    ///   multiplication\n    /// * Potentially faster at runtime as rust emits special no-wrapping flags when it\n    ///   calculates the byte length\n    /// * Less turbofishing\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let data : &[i32] = &[1, 2, 3];\n    /// let newlen = data.len() * size_of::<i32>();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let data : &[i32] = &[1, 2, 3];\n    /// let newlen = size_of_val(data);\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub MANUAL_SLICE_SIZE_CALCULATION,\n    complexity,\n    \"manual slice size calculation\"\n}\n\nimpl_lint_pass!(ManualSliceSizeCalculation => [MANUAL_SLICE_SIZE_CALCULATION]);\n\npub struct ManualSliceSizeCalculation {\n    msrv: Msrv,\n}\n\nimpl ManualSliceSizeCalculation {\n    pub fn new(conf: &Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualSliceSizeCalculation {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Binary(ref op, left, right) = expr.kind\n            && BinOpKind::Mul == op.node\n            && !expr.span.from_expansion()\n            && let Some((receiver, refs_count)) = simplify(cx, left, right)\n            && (!is_in_const_context(cx) || self.msrv.meets(cx, msrvs::CONST_SIZE_OF_VAL))\n        {\n            let ctxt = expr.span.ctxt();\n            let mut app = Applicability::MachineApplicable;\n            let deref = if refs_count > 0 {\n                \"*\".repeat(refs_count - 1)\n            } else {\n                \"&\".into()\n            };\n            let val_name = snippet_with_context(cx, receiver.span, ctxt, \"slice\", &mut app).0;\n            let Some(sugg) = std_or_core(cx) else { return };\n\n            span_lint_and_sugg(\n                cx,\n                MANUAL_SLICE_SIZE_CALCULATION,\n                expr.span,\n                \"manual slice size calculation\",\n                \"try\",\n                format!(\"{sugg}::mem::size_of_val({deref}{val_name})\"),\n                app,\n            );\n        }\n    }\n}\n\nfn simplify<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr1: &'tcx Expr<'tcx>,\n    expr2: &'tcx Expr<'tcx>,\n) -> Option<(&'tcx Expr<'tcx>, usize)> {\n    let expr1 = expr_or_init(cx, expr1);\n    let expr2 = expr_or_init(cx, expr2);\n\n    simplify_half(cx, expr1, expr2).or_else(|| simplify_half(cx, expr2, expr1))\n}\n\nfn simplify_half<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr1: &'tcx Expr<'tcx>,\n    expr2: &'tcx Expr<'tcx>,\n) -> Option<(&'tcx Expr<'tcx>, usize)> {\n    if !expr1.span.from_expansion()\n        // expr1 is `[T1].len()`?\n        && let ExprKind::MethodCall(method_path, receiver, [], _) = expr1.kind\n        && method_path.ident.name == sym::len\n        && let receiver_ty = cx.typeck_results().expr_ty(receiver)\n        && let (receiver_ty, refs_count, _) = peel_and_count_ty_refs(receiver_ty)\n        && let ty::Slice(ty1) = receiver_ty.kind()\n        // expr2 is `size_of::<T2>()`?\n        && let ExprKind::Call(func, []) = expr2.kind\n        && let ExprKind::Path(ref func_qpath) = func.kind\n        && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id()\n        && cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id)\n        && let Some(ty2) = cx.typeck_results().node_args(func.hir_id).types().next()\n        // T1 == T2?\n        && *ty1 == ty2\n    {\n        Some((receiver, refs_count))\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_string_new.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sym;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability::MachineApplicable;\nuse rustc_hir::{Expr, ExprKind, PathSegment, QPath, TyKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for usage of `\"\"` to create a `String`, such as `\"\".to_string()`, `\"\".to_owned()`,\n    /// `String::from(\"\")` and others.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Different ways of creating an empty string makes your code less standardized, which can\n    /// be confusing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = \"\".to_string();\n    /// let b: String = \"\".into();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let a = String::new();\n    /// let b = String::new();\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub MANUAL_STRING_NEW,\n    pedantic,\n    \"empty String is being created manually\"\n}\n\ndeclare_lint_pass!(ManualStringNew => [MANUAL_STRING_NEW]);\n\nimpl LateLintPass<'_> for ManualStringNew {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        let ty = cx.typeck_results().expr_ty(expr);\n        match ty.kind() {\n            ty::Adt(adt_def, _) if adt_def.is_struct() => {\n                if cx.tcx.lang_items().string() != Some(adt_def.did()) {\n                    return;\n                }\n            },\n            _ => return,\n        }\n\n        match expr.kind {\n            ExprKind::Call(func, [arg]) => {\n                parse_call(cx, expr.span, func, arg);\n            },\n            ExprKind::MethodCall(path_segment, receiver, ..) => {\n                parse_method_call(cx, expr.span, path_segment, receiver);\n            },\n            _ => (),\n        }\n    }\n}\n\n/// Checks if an expression's kind corresponds to an empty &str.\nfn is_expr_kind_empty_str(expr_kind: &ExprKind<'_>) -> bool {\n    if let ExprKind::Lit(lit) = expr_kind\n        && let LitKind::Str(value, _) = lit.node\n        && value == sym::empty\n    {\n        return true;\n    }\n\n    false\n}\n\nfn warn_then_suggest(cx: &LateContext<'_>, span: Span) {\n    span_lint_and_sugg(\n        cx,\n        MANUAL_STRING_NEW,\n        span,\n        \"empty String is being created manually\",\n        \"consider using\",\n        \"String::new()\".into(),\n        MachineApplicable,\n    );\n}\n\n/// Tries to parse an expression as a method call, emitting the warning if necessary.\nfn parse_method_call(cx: &LateContext<'_>, span: Span, path_segment: &PathSegment<'_>, receiver: &Expr<'_>) {\n    let method_arg_kind = &receiver.kind;\n    if matches!(path_segment.ident.name, sym::to_string | sym::to_owned | sym::into)\n        && is_expr_kind_empty_str(method_arg_kind)\n    {\n        warn_then_suggest(cx, span);\n    } else if let ExprKind::Call(func, [arg]) = method_arg_kind {\n        // If our first argument is a function call itself, it could be an `unwrap`-like function.\n        // E.g. String::try_from(\"hello\").unwrap(), TryFrom::try_from(\"\").expect(\"hello\"), etc.\n        parse_call(cx, span, func, arg);\n    }\n}\n\n/// Tries to parse an expression as a function call, emitting the warning if necessary.\nfn parse_call(cx: &LateContext<'_>, span: Span, func: &Expr<'_>, arg: &Expr<'_>) {\n    if let ExprKind::Path(qpath) = &func.kind {\n        // String::from(...) or String::try_from(...)\n        if let QPath::TypeRelative(ty, path_seg) = qpath\n            && [sym::from, sym::try_from].contains(&path_seg.ident.name)\n            && let TyKind::Path(qpath) = &ty.kind\n            && let QPath::Resolved(_, path) = qpath\n            && let [path_seg] = path.segments\n            && path_seg.ident.name == sym::String\n            && is_expr_kind_empty_str(&arg.kind)\n        {\n            warn_then_suggest(cx, span);\n        } else if let QPath::Resolved(_, path) = qpath\n            // From::from(...) or TryFrom::try_from(...)\n            && let [path_seg1, path_seg2] = path.segments\n            && is_expr_kind_empty_str(&arg.kind)\n            && ((path_seg1.ident.name == sym::From && path_seg2.ident.name == sym::from)\n                || (path_seg1.ident.name == sym::TryFrom && path_seg2.ident.name == sym::try_from))\n        {\n            warn_then_suggest(cx, span);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_strip.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::usage::mutated_variables;\nuse clippy_utils::{eq_expr_value, higher, sym};\nuse rustc_ast::BindingMode;\nuse rustc_ast::ast::LitKind;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::intravisit::{Visitor, walk_expr, walk_pat};\nuse rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, Node, PatKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext as _};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::{Symbol, SyntaxContext};\nuse std::iter;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using\n    /// the pattern's length.\n    ///\n    /// ### Why is this bad?\n    /// Using `str:strip_{prefix,suffix}` is safer and may have better performance as there is no\n    /// slicing which may panic and the compiler does not need to insert this panic code. It is\n    /// also sometimes more readable as it removes the need for duplicating or storing the pattern\n    /// used by `str::{starts,ends}_with` and in the slicing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let s = \"hello, world!\";\n    /// if s.starts_with(\"hello, \") {\n    ///     assert_eq!(s[\"hello, \".len()..].to_uppercase(), \"WORLD!\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let s = \"hello, world!\";\n    /// if let Some(end) = s.strip_prefix(\"hello, \") {\n    ///     assert_eq!(end.to_uppercase(), \"WORLD!\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub MANUAL_STRIP,\n    complexity,\n    \"suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing\"\n}\n\nimpl_lint_pass!(ManualStrip => [MANUAL_STRIP]);\n\npub struct ManualStrip {\n    msrv: Msrv,\n}\n\nimpl ManualStrip {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\nenum StripKind {\n    Prefix,\n    Suffix,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ManualStrip {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let Some(higher::If { cond, then, .. }) = higher::If::hir(expr)\n            && let ExprKind::MethodCall(_, target_arg, [pattern], _) = cond.kind\n            && let ExprKind::Path(target_path) = &target_arg.kind\n            && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(cond.hir_id)\n        {\n            let strip_kind = match cx.tcx.get_diagnostic_name(method_def_id) {\n                Some(sym::str_starts_with) => StripKind::Prefix,\n                Some(sym::str_ends_with) => StripKind::Suffix,\n                _ => return,\n            };\n            let target_res = cx.qpath_res(target_path, target_arg.hir_id);\n            if target_res == Res::Err {\n                return;\n            }\n\n            if let Res::Local(hir_id) = target_res\n                && let Some(used_mutably) = mutated_variables(then, cx)\n                && used_mutably.contains(&hir_id)\n            {\n                return;\n            }\n\n            let (strippings, bindings) = find_stripping(cx, strip_kind, target_res, pattern, then, expr.span.ctxt());\n            if !strippings.is_empty() && self.msrv.meets(cx, msrvs::STR_STRIP_PREFIX) {\n                let kind_word = match strip_kind {\n                    StripKind::Prefix => \"prefix\",\n                    StripKind::Suffix => \"suffix\",\n                };\n\n                let test_span = expr.span.until(then.span);\n\n                // If the first use is a simple `let` statement, reuse its identifier in the `if let Some(…)` and\n                // remove the `let` statement as long as the identifier is never bound again within the lexical\n                // scope of interest.\n                let (ident_name, let_stmt_span, skip, mut app) = if let Node::LetStmt(let_stmt) =\n                    cx.tcx.parent_hir_node(strippings[0].hir_id)\n                    && let PatKind::Binding(BindingMode::NONE, _, ident, None) = &let_stmt.pat.kind\n                    && bindings.get(&ident.name) == Some(&1)\n                {\n                    (\n                        ident.name.as_str(),\n                        Some(cx.sess().source_map().span_extend_while_whitespace(let_stmt.span)),\n                        1,\n                        Applicability::MachineApplicable,\n                    )\n                } else {\n                    (\"<stripped>\", None, 0, Applicability::HasPlaceholders)\n                };\n\n                span_lint_and_then(\n                    cx,\n                    MANUAL_STRIP,\n                    strippings[0].span,\n                    format!(\"stripping a {kind_word} manually\"),\n                    |diag| {\n                        diag.span_note(test_span, format!(\"the {kind_word} was tested here\"));\n                        diag.multipart_suggestion(\n                            format!(\"try using the `strip_{kind_word}` method\"),\n                            iter::once((\n                                test_span,\n                                format!(\n                                    \"if let Some({ident_name}) = {}.strip_{kind_word}({}) \",\n                                    snippet_with_applicability(cx, target_arg.span, \"_\", &mut app),\n                                    snippet_with_applicability(cx, pattern.span, \"_\", &mut app)\n                                ),\n                            ))\n                            .chain(let_stmt_span.map(|span| (span, String::new())))\n                            .chain(\n                                strippings\n                                    .into_iter()\n                                    .skip(skip)\n                                    .map(|expr| (expr.span, ident_name.into())),\n                            )\n                            .collect(),\n                            app,\n                        );\n                    },\n                );\n            }\n        }\n    }\n}\n\n// Returns `Some(arg)` if `expr` matches `arg.len()` and `None` otherwise.\nfn len_arg<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {\n    if let ExprKind::MethodCall(_, arg, [], _) = expr.kind\n        && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::str_len, method_def_id)\n    {\n        Some(arg)\n    } else {\n        None\n    }\n}\n\n// Returns the length of the `expr` if it's a constant string or char.\nfn constant_length(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> Option<u128> {\n    let value = ConstEvalCtxt::new(cx).eval_local(expr, ctxt)?;\n    match value {\n        Constant::Str(value) => Some(value.len() as u128),\n        Constant::Char(value) => Some(value.len_utf8() as u128),\n        _ => None,\n    }\n}\n\n// Tests if `expr` equals the length of the pattern.\nfn eq_pattern_length<'tcx>(\n    cx: &LateContext<'tcx>,\n    pattern: &Expr<'_>,\n    expr: &'tcx Expr<'_>,\n    ctxt: SyntaxContext,\n) -> bool {\n    if let ExprKind::Lit(Spanned {\n        node: LitKind::Int(n, _),\n        ..\n    }) = expr.kind\n    {\n        constant_length(cx, pattern, ctxt).is_some_and(|length| n == length)\n    } else {\n        len_arg(cx, expr).is_some_and(|arg| eq_expr_value(cx, pattern, arg))\n    }\n}\n\n// Tests if `expr` is a `&str`.\nfn is_ref_str(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match cx.typeck_results().expr_ty_adjusted(expr).kind() {\n        ty::Ref(_, ty, _) => ty.is_str(),\n        _ => false,\n    }\n}\n\n// Removes the outer `AddrOf` expression if needed.\nfn peel_ref<'a>(expr: &'a Expr<'_>) -> &'a Expr<'a> {\n    if let ExprKind::AddrOf(BorrowKind::Ref, _, unref) = &expr.kind {\n        unref\n    } else {\n        expr\n    }\n}\n\n/// Find expressions where `target` is stripped using the length of `pattern`.\n/// We'll suggest replacing these expressions with the result of the `strip_{prefix,suffix}`\n/// method.\n/// Also, all bindings found during the visit are counted and returned.\nfn find_stripping<'tcx>(\n    cx: &LateContext<'tcx>,\n    strip_kind: StripKind,\n    target: Res,\n    pattern: &'tcx Expr<'_>,\n    expr: &'tcx Expr<'tcx>,\n    ctxt: SyntaxContext,\n) -> (Vec<&'tcx Expr<'tcx>>, FxHashMap<Symbol, usize>) {\n    struct StrippingFinder<'a, 'tcx> {\n        cx: &'a LateContext<'tcx>,\n        strip_kind: StripKind,\n        target: Res,\n        pattern: &'tcx Expr<'tcx>,\n        results: Vec<&'tcx Expr<'tcx>>,\n        bindings: FxHashMap<Symbol, usize>,\n        ctxt: SyntaxContext,\n    }\n\n    impl<'tcx> Visitor<'tcx> for StrippingFinder<'_, 'tcx> {\n        fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {\n            if is_ref_str(self.cx, ex)\n                && let unref = peel_ref(ex)\n                && let ExprKind::Index(indexed, index, _) = &unref.kind\n                && let Some(higher::Range { start, end, .. }) = higher::Range::hir(self.cx, index)\n                && let ExprKind::Path(path) = &indexed.kind\n                && self.cx.qpath_res(path, ex.hir_id) == self.target\n            {\n                match (self.strip_kind, start, end) {\n                    (StripKind::Prefix, Some(start), None)\n                        if eq_pattern_length(self.cx, self.pattern, start, self.ctxt) =>\n                    {\n                        self.results.push(ex);\n                        return;\n                    },\n                    (StripKind::Suffix, None, Some(end))\n                        if let ExprKind::Binary(\n                            Spanned {\n                                node: BinOpKind::Sub, ..\n                            },\n                            left,\n                            right,\n                        ) = end.kind\n                            && let Some(left_arg) = len_arg(self.cx, left)\n                            && let ExprKind::Path(left_path) = &left_arg.kind\n                            && self.cx.qpath_res(left_path, left_arg.hir_id) == self.target\n                            && eq_pattern_length(self.cx, self.pattern, right, self.ctxt) =>\n                    {\n                        self.results.push(ex);\n                        return;\n                    },\n                    _ => {},\n                }\n            }\n\n            walk_expr(self, ex);\n        }\n\n        fn visit_pat(&mut self, pat: &'tcx rustc_hir::Pat<'tcx>) -> Self::Result {\n            if let PatKind::Binding(_, _, ident, _) = pat.kind {\n                *self.bindings.entry(ident.name).or_default() += 1;\n            }\n            walk_pat(self, pat);\n        }\n    }\n\n    let mut finder = StrippingFinder {\n        cx,\n        strip_kind,\n        target,\n        pattern,\n        results: vec![],\n        bindings: FxHashMap::default(),\n        ctxt,\n    };\n    walk_expr(&mut finder, expr);\n    (finder.results, finder.bindings)\n}\n"
  },
  {
    "path": "clippy_lints/src/manual_take.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{MEM_TAKE, Msrv};\nuse clippy_utils::source::snippet_with_context;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects manual re-implementations of `std::mem::take`.\n    ///\n    /// ### Why is this bad?\n    /// Because the function call is shorter and easier to read.\n    ///\n    /// ### Known issues\n    /// Currently the lint only detects cases involving `bool`s.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut x = true;\n    /// let _ = if x {\n    ///     x = false;\n    ///     true\n    /// } else {\n    ///     false\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut x = true;\n    /// let _ = std::mem::take(&mut x);\n    /// ```\n    #[clippy::version = \"1.94.0\"]\n    pub MANUAL_TAKE,\n    complexity,\n    \"manual `mem::take` implementation\"\n}\n\nimpl_lint_pass!(ManualTake => [MANUAL_TAKE]);\n\npub struct ManualTake {\n    msrv: Msrv,\n}\n\nimpl ManualTake {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for ManualTake {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if let ExprKind::If(cond, then, Some(otherwise)) = expr.kind\n            && let ExprKind::Path(_) = cond.kind\n            && let ExprKind::Block(\n                Block {\n                    stmts: [stmt],\n                    expr: Some(then_expr),\n                    ..\n                },\n                ..,\n            ) = then.kind\n            && let ExprKind::Block(\n                Block {\n                    stmts: [],\n                    expr: Some(else_expr),\n                    ..\n                },\n                ..,\n            ) = otherwise.kind\n            && let StmtKind::Semi(assignment) = stmt.kind\n            && let ExprKind::Assign(mut_c, possible_false, _) = assignment.kind\n            && let ExprKind::Path(_) = mut_c.kind\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && let Some(std_or_core) = clippy_utils::std_or_core(cx)\n            && self.msrv.meets(cx, MEM_TAKE)\n            && clippy_utils::SpanlessEq::new(cx).eq_expr(cond, mut_c)\n            && Some(false) == as_const_bool(possible_false)\n            && let Some(then_bool) = as_const_bool(then_expr)\n            && let Some(else_bool) = as_const_bool(else_expr)\n            && then_bool != else_bool\n        {\n            span_lint_and_then(\n                cx,\n                MANUAL_TAKE,\n                expr.span,\n                \"manual implementation of `mem::take`\",\n                |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let negate = if then_bool { \"\" } else { \"!\" };\n                    let taken = snippet_with_context(cx, cond.span, expr.span.ctxt(), \"_\", &mut app).0;\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        \"use\",\n                        format!(\"{negate}{std_or_core}::mem::take(&mut {taken})\"),\n                        app,\n                    );\n                },\n            );\n        }\n    }\n}\n\nfn as_const_bool(e: &Expr<'_>) -> Option<bool> {\n    if let ExprKind::Lit(lit) = e.kind\n        && let LitKind::Bool(b) = lit.node\n    {\n        Some(b)\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/map_unit_fn.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context};\nuse clippy_utils::{iter_input_pats, method_chain_args};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `option.map(f)` where f is a function\n    /// or closure that returns the unit type `()`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more clearly with\n    /// an if let statement\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn do_stuff() -> Option<String> { Some(String::new()) }\n    /// # fn log_err_msg(foo: String) -> Option<String> { Some(foo) }\n    /// # fn format_msg(foo: String) -> String { String::new() }\n    /// let x: Option<String> = do_stuff();\n    /// x.map(log_err_msg);\n    /// # let x: Option<String> = do_stuff();\n    /// x.map(|msg| log_err_msg(format_msg(msg)));\n    /// ```\n    ///\n    /// The correct use would be:\n    ///\n    /// ```no_run\n    /// # fn do_stuff() -> Option<String> { Some(String::new()) }\n    /// # fn log_err_msg(foo: String) -> Option<String> { Some(foo) }\n    /// # fn format_msg(foo: String) -> String { String::new() }\n    /// let x: Option<String> = do_stuff();\n    /// if let Some(msg) = x {\n    ///     log_err_msg(msg);\n    /// }\n    ///\n    /// # let x: Option<String> = do_stuff();\n    /// if let Some(msg) = x {\n    ///     log_err_msg(format_msg(msg));\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub OPTION_MAP_UNIT_FN,\n    complexity,\n    \"using `option.map(f)`, where `f` is a function or closure that returns `()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `result.map(f)` where f is a function\n    /// or closure that returns the unit type `()`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more clearly with\n    /// an if let statement\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn do_stuff() -> Result<String, String> { Ok(String::new()) }\n    /// # fn log_err_msg(foo: String) -> Result<String, String> { Ok(foo) }\n    /// # fn format_msg(foo: String) -> String { String::new() }\n    /// let x: Result<String, String> = do_stuff();\n    /// x.map(log_err_msg);\n    /// # let x: Result<String, String> = do_stuff();\n    /// x.map(|msg| log_err_msg(format_msg(msg)));\n    /// ```\n    ///\n    /// The correct use would be:\n    ///\n    /// ```no_run\n    /// # fn do_stuff() -> Result<String, String> { Ok(String::new()) }\n    /// # fn log_err_msg(foo: String) -> Result<String, String> { Ok(foo) }\n    /// # fn format_msg(foo: String) -> String { String::new() }\n    /// let x: Result<String, String> = do_stuff();\n    /// if let Ok(msg) = x {\n    ///     log_err_msg(msg);\n    /// };\n    /// # let x: Result<String, String> = do_stuff();\n    /// if let Ok(msg) = x {\n    ///     log_err_msg(format_msg(msg));\n    /// };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub RESULT_MAP_UNIT_FN,\n    complexity,\n    \"using `result.map(f)`, where `f` is a function or closure that returns `()`\"\n}\n\ndeclare_lint_pass!(MapUnit => [OPTION_MAP_UNIT_FN, RESULT_MAP_UNIT_FN]);\n\nfn is_unit_type(ty: Ty<'_>) -> bool {\n    ty.is_unit() || ty.is_never()\n}\n\nfn is_unit_function(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {\n    let ty = cx.typeck_results().expr_ty(expr);\n\n    if let ty::FnDef(id, _) = *ty.kind()\n        && let Some(fn_type) = cx.tcx.fn_sig(id).instantiate_identity().no_bound_vars()\n    {\n        return is_unit_type(fn_type.output());\n    }\n    false\n}\n\nfn is_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {\n    is_unit_type(cx.typeck_results().expr_ty(expr))\n}\n\n/// The expression inside a closure may or may not have surrounding braces and\n/// semicolons, which causes problems when generating a suggestion. Given an\n/// expression that evaluates to '()' or '!', recursively remove useless braces\n/// and semi-colons until is suitable for including in the suggestion template.\n/// The `bool` is `true` when the resulting `span` needs to be enclosed in an\n/// `unsafe` block.\nfn reduce_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<(Span, bool)> {\n    if !is_unit_expression(cx, expr) {\n        return None;\n    }\n\n    match expr.kind {\n        hir::ExprKind::Call(_, _) | hir::ExprKind::MethodCall(..) => {\n            // Calls can't be reduced any more\n            Some((expr.span, false))\n        },\n        hir::ExprKind::Block(block, _) => {\n            let is_unsafe = matches!(block.rules, hir::BlockCheckMode::UnsafeBlock(_));\n            match (block.stmts, block.expr.as_ref()) {\n                ([], Some(inner_expr)) => {\n                    // If block only contains an expression,\n                    // reduce `{ X }` to `X`\n                    reduce_unit_expression(cx, inner_expr)\n                        .map(|(span, inner_is_unsafe)| (span, inner_is_unsafe || is_unsafe))\n                },\n                ([inner_stmt], None) => {\n                    // If block only contains statements,\n                    // reduce `{ X; }` to `X` or `X;`\n                    match inner_stmt.kind {\n                        hir::StmtKind::Let(local) => Some((local.span, is_unsafe)),\n                        hir::StmtKind::Expr(e) => Some((e.span, is_unsafe)),\n                        hir::StmtKind::Semi(..) => Some((inner_stmt.span, is_unsafe)),\n                        hir::StmtKind::Item(..) => None,\n                    }\n                },\n                _ => {\n                    // For closures that contain multiple statements\n                    // it's difficult to get a correct suggestion span\n                    // for all cases (multi-line closures specifically)\n                    //\n                    // We do not attempt to build a suggestion for those right now.\n                    None\n                },\n            }\n        },\n        _ => None,\n    }\n}\n\nfn unit_closure<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &hir::Expr<'_>,\n) -> Option<(&'tcx hir::Param<'tcx>, &'tcx hir::Expr<'tcx>)> {\n    if let hir::ExprKind::Closure(&hir::Closure { fn_decl, body, .. }) = expr.kind\n        && let body = cx.tcx.hir_body(body)\n        && let body_expr = &body.value\n        && fn_decl.inputs.len() == 1\n        && is_unit_expression(cx, body_expr)\n        && let Some(binding) = iter_input_pats(fn_decl, body).next()\n    {\n        return Some((binding, body_expr));\n    }\n    None\n}\n\n/// Builds a name for the let binding variable (`var_arg`)\n///\n/// `x.field` => `x_field`\n/// `y` => `_y`\n///\n/// Anything else will return `a`.\nfn let_binding_name(cx: &LateContext<'_>, var_arg: &hir::Expr<'_>) -> String {\n    match &var_arg.kind {\n        hir::ExprKind::Field(_, _) => snippet(cx, var_arg.span, \"_\").replace('.', \"_\"),\n        hir::ExprKind::Path(_) => format!(\"_{}\", snippet(cx, var_arg.span, \"\")),\n        _ => \"a\".to_string(),\n    }\n}\n\n#[must_use]\nfn suggestion_msg(function_type: &str, article: &str, map_type: &str) -> String {\n    format!(\n        \"called `map(f)` on {article} `{map_type}` value where `f` is a {function_type} that returns the unit type `()`\"\n    )\n}\n\nfn lint_map_unit_fn(\n    cx: &LateContext<'_>,\n    stmt: &hir::Stmt<'_>,\n    expr: &hir::Expr<'_>,\n    map_args: (&hir::Expr<'_>, &[hir::Expr<'_>]),\n) {\n    let var_arg = &map_args.0;\n\n    let (article, map_type, variant, lint) = if cx.typeck_results().expr_ty(var_arg).is_diag_item(cx, sym::Option) {\n        (\"an\", \"Option\", \"Some\", OPTION_MAP_UNIT_FN)\n    } else if cx.typeck_results().expr_ty(var_arg).is_diag_item(cx, sym::Result) {\n        (\"a\", \"Result\", \"Ok\", RESULT_MAP_UNIT_FN)\n    } else {\n        return;\n    };\n    let fn_arg = &map_args.1[0];\n\n    #[expect(clippy::items_after_statements, reason = \"the const is only used below\")]\n    const SUGG_MSG: &str = \"use `if let` instead\";\n\n    if is_unit_function(cx, fn_arg) {\n        let mut applicability = Applicability::MachineApplicable;\n        let msg = suggestion_msg(\"function\", article, map_type);\n        let suggestion = format!(\n            \"if let {0}({binding}) = {1} {{ {2}({binding}) }}\",\n            variant,\n            snippet_with_applicability(cx, var_arg.span, \"_\", &mut applicability),\n            snippet_with_applicability(cx, fn_arg.span, \"_\", &mut applicability),\n            binding = let_binding_name(cx, var_arg)\n        );\n\n        span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n            diag.span_suggestion_verbose(stmt.span, SUGG_MSG, suggestion, applicability);\n        });\n    } else if let Some((binding, closure_expr)) = unit_closure(cx, fn_arg) {\n        let msg = suggestion_msg(\"closure\", article, map_type);\n\n        span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n            if let Some((reduced_expr_span, is_unsafe)) = reduce_unit_expression(cx, closure_expr) {\n                let mut applicability = Applicability::MachineApplicable;\n                let (prefix_is_unsafe, suffix_is_unsafe) = if is_unsafe { (\"unsafe { \", \" }\") } else { (\"\", \"\") };\n                let suggestion = format!(\n                    \"if let {0}({1}) = {2} {{ {prefix_is_unsafe}{3}{suffix_is_unsafe} }}\",\n                    variant,\n                    snippet_with_applicability(cx, binding.pat.span, \"_\", &mut applicability),\n                    snippet_with_applicability(cx, var_arg.span, \"_\", &mut applicability),\n                    snippet_with_context(cx, reduced_expr_span, var_arg.span.ctxt(), \"_\", &mut applicability).0,\n                );\n                diag.span_suggestion_verbose(stmt.span, SUGG_MSG, suggestion, applicability);\n            } else {\n                let suggestion = format!(\n                    \"if let {0}({1}) = {2} {{ ... }}\",\n                    variant,\n                    snippet(cx, binding.pat.span, \"_\"),\n                    snippet(cx, var_arg.span, \"_\"),\n                );\n                diag.span_suggestion_verbose(stmt.span, SUGG_MSG, suggestion, Applicability::HasPlaceholders);\n            }\n        });\n    }\n}\n\nimpl LateLintPass<'_> for MapUnit {\n    fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) {\n        if let hir::StmtKind::Semi(expr) = stmt.kind\n            && !stmt.span.from_expansion()\n            && let Some(arglists) = method_chain_args(expr, &[sym::map])\n        {\n            lint_map_unit_fn(cx, stmt, expr, arglists[0]);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/match_result_ok.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{as_some_pattern, higher, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary `ok()` in `while let`.\n    ///\n    /// ### Why is this bad?\n    /// Calling `ok()` in `while let` is unnecessary, instead match\n    /// on `Ok(pat)`\n    ///\n    /// ### Example\n    /// ```ignore\n    /// while let Some(value) = iter.next().ok() {\n    ///     vec.push(value)\n    /// }\n    ///\n    /// if let Some(value) = iter.next().ok() {\n    ///     vec.push(value)\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```ignore\n    /// while let Ok(value) = iter.next() {\n    ///     vec.push(value)\n    /// }\n    ///\n    /// if let Ok(value) = iter.next() {\n    ///        vec.push(value)\n    /// }\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub MATCH_RESULT_OK,\n    style,\n    \"usage of `ok()` in `let Some(pat)` statements is unnecessary, match on `Ok(pat)` instead\"\n}\n\ndeclare_lint_pass!(MatchResultOk => [MATCH_RESULT_OK]);\n\nimpl<'tcx> LateLintPass<'tcx> for MatchResultOk {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let (let_pat, let_expr, ifwhile) =\n            if let Some(higher::IfLet { let_pat, let_expr, .. }) = higher::IfLet::hir(cx, expr) {\n                (let_pat, let_expr, \"if\")\n            } else if let Some(higher::WhileLet { let_pat, let_expr, .. }) = higher::WhileLet::hir(expr) {\n                (let_pat, let_expr, \"while\")\n            } else {\n                return;\n            };\n\n        if let ExprKind::MethodCall(ok_path, recv, [], ..) = let_expr.kind //check is expr.ok() has type Result<T,E>.ok(, _)\n            && ok_path.ident.name == sym::ok\n            && cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result)\n            && let Some([ok_pat]) = as_some_pattern(cx, let_pat) //get operation\n            && let ctxt = expr.span.ctxt()\n            && let_expr.span.ctxt() == ctxt\n            && let_pat.span.ctxt() == ctxt\n        {\n            let mut applicability = Applicability::MachineApplicable;\n            let some_expr_string = snippet_with_context(cx, ok_pat.span, ctxt, \"\", &mut applicability).0;\n            let trimmed_ok = snippet_with_context(cx, recv.span, ctxt, \"\", &mut applicability).0;\n            let sugg = format!(\n                \"{ifwhile} let Ok({some_expr_string}) = {}\",\n                trimmed_ok.trim().trim_end_matches('.'),\n            );\n            span_lint_and_sugg(\n                cx,\n                MATCH_RESULT_OK,\n                expr.span.with_hi(let_expr.span.hi()),\n                \"matching on `Some` with `ok()` is redundant\",\n                format!(\"consider matching on `Ok({some_expr_string})` and removing the call to `ok` instead\"),\n                sugg,\n                applicability,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/collapsible_match.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::higher::{If, IfLetOrMatch};\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::{IntoSpan, SpanRangeExt, snippet};\nuse clippy_utils::visitors::is_local_used;\nuse clippy_utils::{SpanlessEq, get_ref_operators, is_unit_expr, peel_blocks_with_stmt, peel_ref_operators};\nuse rustc_ast::BorrowKind;\nuse rustc_errors::{Applicability, MultiSpan};\nuse rustc_hir::LangItem::OptionNone;\nuse rustc_hir::{Arm, Expr, ExprKind, HirId, Pat, PatExpr, PatExprKind, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::Ident;\nuse rustc_span::{BytePos, Span};\n\nuse crate::collapsible_if::{parens_around, peel_parens};\n\nuse super::{COLLAPSIBLE_MATCH, pat_contains_disallowed_or};\n\npub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>], msrv: Msrv) {\n    if let Some(els_arm) = arms.iter().rfind(|arm| arm_is_wild_like(cx, arm)) {\n        for arm in arms {\n            check_arm(cx, true, arm.pat, expr, arm.body, arm.guard, Some(els_arm.body), msrv);\n        }\n    }\n}\n\npub(super) fn check_if_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    body: &'tcx Expr<'_>,\n    else_expr: Option<&'tcx Expr<'_>>,\n    let_expr: &'tcx Expr<'_>,\n    msrv: Msrv,\n) {\n    check_arm(cx, false, pat, let_expr, body, None, else_expr, msrv);\n}\n\n#[expect(clippy::too_many_arguments, clippy::too_many_lines)]\nfn check_arm<'tcx>(\n    cx: &LateContext<'tcx>,\n    outer_is_match: bool,\n    outer_pat: &'tcx Pat<'tcx>,\n    outer_cond: &'tcx Expr<'tcx>,\n    outer_then_body: &'tcx Expr<'tcx>,\n    outer_guard: Option<&'tcx Expr<'tcx>>,\n    outer_else_body: Option<&'tcx Expr<'tcx>>,\n    msrv: Msrv,\n) {\n    let inner_expr = peel_blocks_with_stmt(outer_then_body);\n    if let Some(inner) = IfLetOrMatch::parse(cx, inner_expr)\n        && let Some((inner_scrutinee, inner_then_pat, inner_else_body)) = match inner {\n            IfLetOrMatch::IfLet(scrutinee, pat, _, els, _) => Some((scrutinee, pat, els)),\n            IfLetOrMatch::Match(scrutinee, arms, ..) => {\n                if arms.len() == 2 && arms.iter().all(|a| a.guard.is_none())\n                    // if there are more than two arms, collapsing would be non-trivial\n                    // one of the arms must be \"wild-like\"\n                    && let Some(wild_idx) = arms.iter().rposition(|a| arm_is_wild_like(cx, a))\n                {\n                    let (then, els) = (&arms[1 - wild_idx], &arms[wild_idx]);\n                    Some((scrutinee, then.pat, Some(els.body)))\n                } else {\n                    None\n                }\n            },\n        }\n        && outer_pat.span.eq_ctxt(inner_scrutinee.span)\n        // match expression must be a local binding\n        // match <local> { .. }\n        && let Some(binding_id) = peel_ref_operators(cx, inner_scrutinee).res_local_id()\n        && !pat_contains_disallowed_or(cx, inner_then_pat, msrv)\n        // the binding must come from the pattern of the containing match arm\n        // ..<local>.. => match <local> { .. }\n        && let (Some((binding_ident, binding_span)), is_innermost_parent_pat_struct) =\n            find_pat_binding_and_is_innermost_parent_pat_struct(outer_pat, binding_id)\n        // the \"else\" branches must be equal\n        && match (outer_else_body, inner_else_body) {\n            (None, None) => true,\n            (None, Some(e)) | (Some(e), None) => is_unit_expr(e),\n            (Some(a), Some(b)) => SpanlessEq::new(cx).eq_expr(a, b),\n        }\n        // the binding must not be used in the if guard\n        && outer_guard.is_none_or(|e| !is_local_used(cx, e, binding_id))\n        // ...or anywhere in the inner expression\n        && match inner {\n            IfLetOrMatch::IfLet(_, _, body, els, _) => {\n                !is_local_used(cx, body, binding_id) && els.is_none_or(|e| !is_local_used(cx, e, binding_id))\n            },\n            IfLetOrMatch::Match(_, arms, ..) => !arms.iter().any(|arm| is_local_used(cx, arm, binding_id)),\n        }\n        // Check if the inner expression contains any borrows/dereferences\n        && let ref_types = get_ref_operators(cx, inner_scrutinee)\n        && let Some(method) = build_ref_method_chain(ref_types)\n    {\n        let msg = format!(\n            \"this `{}` can be collapsed into the outer `{}`\",\n            if matches!(inner, IfLetOrMatch::Match(..)) {\n                \"match\"\n            } else {\n                \"if let\"\n            },\n            if outer_is_match { \"match\" } else { \"if let\" },\n        );\n        // collapsing patterns need an explicit field name in struct pattern matching\n        // ex: Struct {x: Some(1)}\n        let replace_msg = if is_innermost_parent_pat_struct {\n            format!(\", prefixed by `{binding_ident}: `\")\n        } else {\n            String::new()\n        };\n        span_lint_hir_and_then(cx, COLLAPSIBLE_MATCH, inner_expr.hir_id, inner_expr.span, msg, |diag| {\n            let mut help_span = MultiSpan::from_spans(vec![binding_span, inner_then_pat.span]);\n            help_span.push_span_label(binding_span, \"replace this binding\");\n            help_span.push_span_label(inner_then_pat.span, format!(\"with this pattern{replace_msg}\"));\n            if !method.is_empty() {\n                let outer_cond_msg = format!(\"use: `{}{}`\", snippet(cx, outer_cond.span, \"..\"), method);\n                help_span.push_span_label(outer_cond.span, outer_cond_msg);\n            }\n            diag.span_help(\n                help_span,\n                \"the outer pattern can be modified to include the inner pattern\",\n            );\n        });\n    } else if outer_is_match // Leave if-let to the `collapsible_if` lint\n        && let Some(inner) = If::hir(inner_expr)\n        && outer_pat.span.eq_ctxt(inner.cond.span)\n        && match (outer_else_body, inner.r#else) {\n            (None, None) => true,\n            (None, Some(e)) | (Some(e), None) => is_unit_expr(e),\n            (Some(a), Some(b)) => SpanlessEq::new(cx).eq_expr(a, b),\n        }\n    {\n        span_lint_hir_and_then(\n            cx,\n            COLLAPSIBLE_MATCH,\n            inner_expr.hir_id,\n            inner_expr.span,\n            \"this `if` can be collapsed into the outer `match`\",\n            |diag| {\n                let outer_then_open_bracket = outer_then_body\n                    .span\n                    .split_at(1)\n                    .0\n                    .with_leading_whitespace(cx)\n                    .into_span();\n                let outer_then_closing_bracket = {\n                    let end = outer_then_body.span.shrink_to_hi();\n                    end.with_lo(end.lo() - BytePos(1))\n                        .with_leading_whitespace(cx)\n                        .into_span()\n                };\n                let outer_arrow_end = if let Some(outer_guard) = outer_guard {\n                    outer_guard.span.shrink_to_hi()\n                } else {\n                    outer_pat.span.shrink_to_hi()\n                };\n                let (paren_start, inner_if_span, paren_end) = peel_parens(cx, inner_expr.span);\n                let inner_if = inner_if_span.split_at(2).0;\n                let mut sugg = vec![\n                    (inner.then.span.shrink_to_lo(), \"=> \".to_string()),\n                    (outer_arrow_end.to(outer_then_open_bracket), String::new()),\n                    (outer_then_closing_bracket, String::new()),\n                ];\n\n                if let Some(outer_guard) = outer_guard {\n                    sugg.extend(parens_around(outer_guard));\n                    sugg.push((inner_if, \"&&\".to_string()));\n                }\n\n                if !paren_start.is_empty() {\n                    sugg.push((paren_start, String::new()));\n                }\n\n                if !paren_end.is_empty() {\n                    sugg.push((paren_end, String::new()));\n                }\n\n                sugg.extend(parens_around(inner.cond));\n\n                if let Some(else_inner) = inner.r#else {\n                    let else_inner_span = inner.then.span.shrink_to_hi().to(else_inner.span);\n                    sugg.push((else_inner_span, String::new()));\n                }\n\n                diag.multipart_suggestion(\"collapse nested if block\", sugg, Applicability::MachineApplicable);\n            },\n        );\n    }\n}\n\n/// A \"wild-like\" arm has a wild (`_`) or `None` pattern and no guard. Such arms can be \"collapsed\"\n/// into a single wild arm without any significant loss in semantics or readability.\nfn arm_is_wild_like(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {\n    if arm.guard.is_some() {\n        return false;\n    }\n    match arm.pat.kind {\n        PatKind::Binding(..) | PatKind::Wild => true,\n        PatKind::Expr(PatExpr {\n            kind: PatExprKind::Path(qpath),\n            hir_id,\n            ..\n        }) => cx\n            .qpath_res(qpath, *hir_id)\n            .ctor_parent(cx)\n            .is_lang_item(cx, OptionNone),\n        _ => false,\n    }\n}\n\nfn find_pat_binding_and_is_innermost_parent_pat_struct(pat: &Pat<'_>, hir_id: HirId) -> (Option<(Ident, Span)>, bool) {\n    let mut binding = None;\n    let mut is_innermost_parent_pat_struct = false;\n    pat.walk_short(|p| match p.kind {\n        // ignore OR patterns\n        PatKind::Or(_) => false,\n        PatKind::Binding(_bm, _, ident, _) => {\n            let found = p.hir_id == hir_id;\n            if found {\n                binding = Some((ident, p.span));\n            }\n            !found\n        },\n        _ => {\n            is_innermost_parent_pat_struct = matches!(p.kind, PatKind::Struct(..));\n            true\n        },\n    });\n    (binding, is_innermost_parent_pat_struct)\n}\n\n/// Builds a chain of reference-manipulation method calls (e.g., `.as_ref()`, `.as_mut()`,\n/// `.copied()`) based on reference operators\nfn build_ref_method_chain(expr: Vec<&Expr<'_>>) -> Option<String> {\n    let mut req_method_calls = String::new();\n\n    for ref_operator in expr {\n        match ref_operator.kind {\n            ExprKind::AddrOf(BorrowKind::Raw, _, _) => {\n                return None;\n            },\n            ExprKind::AddrOf(_, m, _) if m.is_mut() => {\n                req_method_calls.push_str(\".as_mut()\");\n            },\n            ExprKind::AddrOf(_, _, _) => {\n                req_method_calls.push_str(\".as_ref()\");\n            },\n            // Deref operator is the only operator that this function should have received\n            ExprKind::Unary(_, _) => {\n                req_method_calls.push_str(\".copied()\");\n            },\n            _ => (),\n        }\n    }\n\n    Some(req_method_calls)\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/infallible_destructuring_match.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{peel_blocks, strip_pat_refs};\nuse rustc_errors::Applicability;\nuse rustc_hir::{ExprKind, LetStmt, MatchSource, PatKind, QPath};\nuse rustc_lint::LateContext;\n\nuse super::INFALLIBLE_DESTRUCTURING_MATCH;\n\npub(crate) fn check(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {\n    if !local.span.from_expansion()\n        && let Some(expr) = local.init\n        && let ExprKind::Match(target, arms, MatchSource::Normal) = expr.kind\n        && arms.len() == 1\n        && arms[0].guard.is_none()\n        && let PatKind::TupleStruct(QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind\n        && args.len() == 1\n        && let PatKind::Binding(binding, arg, ..) = strip_pat_refs(&args[0]).kind\n        && let body = peel_blocks(arms[0].body)\n        && body.res_local_id() == Some(arg)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            INFALLIBLE_DESTRUCTURING_MATCH,\n            local.span,\n            \"you seem to be trying to use `match` to destructure a single infallible pattern. \\\n            Consider using `let`\",\n            \"try\",\n            format!(\n                \"let {}({}{}) = {};\",\n                snippet_with_applicability(cx, variant_name.span, \"..\", &mut applicability),\n                binding.prefix_str(),\n                snippet_with_applicability(cx, local.pat.span, \"..\", &mut applicability),\n                snippet_with_applicability(cx, target.span, \"..\", &mut applicability),\n            ),\n            applicability,\n        );\n        return true;\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/manual_filter.rs",
    "content": "use clippy_utils::as_some_expr;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse clippy_utils::visitors::contains_unsafe_block;\n\nuse rustc_hir::LangItem::OptionNone;\nuse rustc_hir::{Arm, Expr, ExprKind, HirId, Pat, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::{SyntaxContext, sym};\n\nuse super::MANUAL_FILTER;\nuse super::manual_utils::{SomeExpr, check_with};\n\n// Function called on the <expr> of `[&+]Some((ref | ref mut) x) => <expr>`\n// Need to check if it's of the form `<expr>=if <cond> {<then_expr>} else {<else_expr>}`\n// AND that only one `then/else_expr` resolves to `Some(x)` while the other resolves to `None`\n// return the `cond` expression if so.\nfn get_cond_expr<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &Pat<'_>,\n    expr: &'tcx Expr<'_>,\n    ctxt: SyntaxContext,\n) -> Option<SomeExpr<'tcx>> {\n    if let Some(block_expr) = peels_blocks_incl_unsafe_opt(expr)\n        && let ExprKind::If(cond, then_expr, Some(else_expr)) = block_expr.kind\n        && let PatKind::Binding(_, target, ..) = pat.kind\n        && (is_some_expr(cx, target, ctxt, then_expr) && is_none_expr(cx, else_expr)\n            || is_none_expr(cx, then_expr) && is_some_expr(cx, target, ctxt, else_expr))\n    // check that one expr resolves to `Some(x)`, the other to `None`\n    {\n        return Some(SomeExpr {\n            expr: peels_blocks_incl_unsafe(cond.peel_drop_temps()),\n            needs_unsafe_block: contains_unsafe_block(cx, expr),\n            needs_negated: is_none_expr(cx, then_expr), /* if the `then_expr` resolves to `None`, need to negate the\n                                                         * cond */\n        });\n    }\n    None\n}\n\nfn peels_blocks_incl_unsafe_opt<'a>(expr: &'a Expr<'a>) -> Option<&'a Expr<'a>> {\n    // we don't want to use `peel_blocks` here because we don't care if the block is unsafe, it's\n    // checked by `contains_unsafe_block`\n    if let ExprKind::Block(block, None) = expr.kind\n        && block.stmts.is_empty()\n    {\n        return block.expr;\n    }\n    None\n}\n\nfn peels_blocks_incl_unsafe<'a>(expr: &'a Expr<'a>) -> &'a Expr<'a> {\n    peels_blocks_incl_unsafe_opt(expr).unwrap_or(expr)\n}\n\n/// Checks whether <expr> resolves to `Some(target)`\n// NOTE: called for each <expr> expression:\n// Some(x) => if <cond> {\n//    <expr>\n// } else {\n//    <expr>\n// }\nfn is_some_expr(cx: &LateContext<'_>, target: HirId, ctxt: SyntaxContext, expr: &Expr<'_>) -> bool {\n    if let Some(inner_expr) = peels_blocks_incl_unsafe_opt(expr)\n        // there can be not statements in the block as they would be removed when switching to `.filter`\n        && let Some(arg) = as_some_expr(cx, inner_expr)\n    {\n        return ctxt == expr.span.ctxt() && arg.res_local_id() == Some(target);\n    }\n    false\n}\n\nfn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let Some(inner_expr) = peels_blocks_incl_unsafe_opt(expr) {\n        return inner_expr.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone);\n    }\n    false\n}\n\n// given the closure: `|<pattern>| <expr>`\n// returns `|&<pattern>| <expr>`\nfn add_ampersand_if_copy(body_str: String, has_copy_trait: bool) -> String {\n    if has_copy_trait {\n        let mut with_ampersand = body_str;\n        with_ampersand.insert(1, '&');\n        with_ampersand\n    } else {\n        body_str\n    }\n}\n\npub(super) fn check_match<'tcx>(\n    cx: &LateContext<'tcx>,\n    scrutinee: &'tcx Expr<'_>,\n    arms: &'tcx [Arm<'_>],\n    expr: &'tcx Expr<'_>,\n) {\n    let ty = cx.typeck_results().expr_ty(expr);\n    if ty.is_diag_item(cx, sym::Option)\n        && let [first_arm, second_arm] = arms\n        && first_arm.guard.is_none()\n        && second_arm.guard.is_none()\n    {\n        check(\n            cx,\n            expr,\n            scrutinee,\n            first_arm.pat,\n            first_arm.body,\n            Some(second_arm.pat),\n            second_arm.body,\n        );\n    }\n}\n\npub(super) fn check_if_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    let_pat: &'tcx Pat<'_>,\n    let_expr: &'tcx Expr<'_>,\n    then_expr: &'tcx Expr<'_>,\n    else_expr: &'tcx Expr<'_>,\n) {\n    check(cx, expr, let_expr, let_pat, then_expr, None, else_expr);\n}\n\nfn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    scrutinee: &'tcx Expr<'_>,\n    then_pat: &'tcx Pat<'_>,\n    then_body: &'tcx Expr<'_>,\n    else_pat: Option<&'tcx Pat<'_>>,\n    else_body: &'tcx Expr<'_>,\n) {\n    if let Some(sugg_info) = check_with(\n        cx,\n        expr,\n        scrutinee,\n        then_pat,\n        then_body,\n        else_pat,\n        else_body,\n        get_cond_expr,\n    ) {\n        let body_str = add_ampersand_if_copy(sugg_info.body_str, sugg_info.scrutinee_impl_copy);\n        span_lint_and_sugg(\n            cx,\n            MANUAL_FILTER,\n            expr.span,\n            \"manual implementation of `Option::filter`\",\n            \"try\",\n            if sugg_info.needs_brackets {\n                format!(\n                    \"{{ {}{}.filter({body_str}) }}\",\n                    sugg_info.scrutinee_str, sugg_info.as_ref_str\n                )\n            } else {\n                format!(\"{}{}.filter({body_str})\", sugg_info.scrutinee_str, sugg_info.as_ref_str)\n            },\n            sugg_info.app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/manual_map.rs",
    "content": "use super::MANUAL_MAP;\nuse super::manual_utils::{SomeExpr, check_with};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\n\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse rustc_hir::LangItem::OptionSome;\nuse rustc_hir::{Arm, Block, BlockCheckMode, Expr, ExprKind, Pat, UnsafeSource};\nuse rustc_lint::LateContext;\nuse rustc_span::SyntaxContext;\n\npub(super) fn check_match<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    scrutinee: &'tcx Expr<'_>,\n    arms: &'tcx [Arm<'_>],\n) {\n    if let [arm1, arm2] = arms\n        && arm1.guard.is_none()\n        && arm2.guard.is_none()\n    {\n        check(cx, expr, scrutinee, arm1.pat, arm1.body, Some(arm2.pat), arm2.body);\n    }\n}\n\npub(super) fn check_if_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    let_pat: &'tcx Pat<'_>,\n    let_expr: &'tcx Expr<'_>,\n    then_expr: &'tcx Expr<'_>,\n    else_expr: &'tcx Expr<'_>,\n) {\n    check(cx, expr, let_expr, let_pat, then_expr, None, else_expr);\n}\n\nfn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    scrutinee: &'tcx Expr<'_>,\n    then_pat: &'tcx Pat<'_>,\n    then_body: &'tcx Expr<'_>,\n    else_pat: Option<&'tcx Pat<'_>>,\n    else_body: &'tcx Expr<'_>,\n) {\n    if let Some(sugg_info) = check_with(\n        cx,\n        expr,\n        scrutinee,\n        then_pat,\n        then_body,\n        else_pat,\n        else_body,\n        get_some_expr,\n    ) {\n        span_lint_and_sugg(\n            cx,\n            MANUAL_MAP,\n            expr.span,\n            \"manual implementation of `Option::map`\",\n            \"try\",\n            if sugg_info.needs_brackets {\n                format!(\n                    \"{{ {}{}.map({}) }}\",\n                    sugg_info.scrutinee_str, sugg_info.as_ref_str, sugg_info.body_str\n                )\n            } else {\n                format!(\n                    \"{}{}.map({})\",\n                    sugg_info.scrutinee_str, sugg_info.as_ref_str, sugg_info.body_str\n                )\n            },\n            sugg_info.app,\n        );\n    }\n}\n\n// Checks for an expression wrapped by the `Some` constructor. Returns the contained expression.\nfn get_some_expr<'tcx>(\n    cx: &LateContext<'tcx>,\n    _: &'tcx Pat<'_>,\n    expr: &'tcx Expr<'_>,\n    ctxt: SyntaxContext,\n) -> Option<SomeExpr<'tcx>> {\n    fn get_some_expr_internal<'tcx>(\n        cx: &LateContext<'tcx>,\n        expr: &'tcx Expr<'_>,\n        needs_unsafe_block: bool,\n        ctxt: SyntaxContext,\n    ) -> Option<SomeExpr<'tcx>> {\n        // TODO: Allow more complex expressions.\n        match expr.kind {\n            ExprKind::Call(callee, [arg])\n                if ctxt == expr.span.ctxt() && callee.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome) =>\n            {\n                Some(SomeExpr::new_no_negated(arg, needs_unsafe_block))\n            },\n            ExprKind::Block(\n                Block {\n                    stmts: [],\n                    expr: Some(expr),\n                    rules,\n                    ..\n                },\n                _,\n            ) => get_some_expr_internal(\n                cx,\n                expr,\n                needs_unsafe_block || *rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),\n                ctxt,\n            ),\n            _ => None,\n        }\n    }\n    get_some_expr_internal(cx, expr, false, ctxt)\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/manual_ok_err.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{indent_of, reindent_multiline};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::{option_arg_ty, peel_and_count_ty_refs};\nuse clippy_utils::{as_some_expr, get_parent_expr, is_none_expr, peel_blocks, span_contains_comment};\nuse rustc_ast::{BindingMode, Mutability};\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::ResultErr;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Arm, Expr, ExprKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::symbol::Ident;\n\nuse super::MANUAL_OK_ERR;\n\npub(crate) fn check_if_let(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    let_pat: &Pat<'_>,\n    let_expr: &Expr<'_>,\n    if_then: &Expr<'_>,\n    else_expr: &Expr<'_>,\n) {\n    if let Some(inner_expr_ty) = option_arg_ty(cx, cx.typeck_results().expr_ty(expr))\n        && let Some((is_ok, ident)) = is_ok_or_err(cx, let_pat)\n        && is_some_ident(cx, if_then, ident, inner_expr_ty)\n        && is_none(cx, else_expr)\n    {\n        apply_lint(cx, expr, let_expr, is_ok);\n    }\n}\n\npub(crate) fn check_match(cx: &LateContext<'_>, expr: &Expr<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>]) {\n    if let Some(inner_expr_ty) = option_arg_ty(cx, cx.typeck_results().expr_ty(expr))\n        && arms.len() == 2\n        && arms.iter().all(|arm| arm.guard.is_none())\n        && let Some((idx, is_ok)) = arms.iter().enumerate().find_map(|(arm_idx, arm)| {\n            // Check if the arm is a `Ok(x) => x` or `Err(x) => x` alternative.\n            // In this case, return its index and whether it uses `Ok` or `Err`.\n             if let Some((is_ok, ident)) = is_ok_or_err(cx, arm.pat)\n                && is_some_ident(cx, arm.body, ident, inner_expr_ty)\n            {\n                Some((arm_idx, is_ok))\n            } else {\n                None\n            }\n        })\n        // Accept wildcard only as the second arm\n        && is_variant_or_wildcard(cx, arms[1-idx].pat, idx == 0, is_ok)\n        // Check that the body of the non `Ok`/`Err` arm is `None`\n        && is_none(cx, arms[1 - idx].body)\n    {\n        apply_lint(cx, expr, scrutinee, is_ok);\n    }\n}\n\n/// Check that `pat` applied to a `Result` only matches `Ok(_)`, `Err(_)`, not a subset or a\n/// superset of it. If `can_be_wild` is `true`, wildcards are also accepted. In the case of\n/// a non-wildcard, `must_match_err` indicates whether the `Err` or the `Ok` variant should be\n/// accepted.\nfn is_variant_or_wildcard(cx: &LateContext<'_>, pat: &Pat<'_>, can_be_wild: bool, must_match_err: bool) -> bool {\n    match pat.kind {\n        PatKind::Wild\n        | PatKind::Expr(PatExpr {\n            kind: PatExprKind::Path(_),\n            ..\n        })\n        | PatKind::Binding(_, _, _, None)\n            if can_be_wild =>\n        {\n            true\n        },\n        PatKind::TupleStruct(qpath, ..) => {\n            cx.qpath_res(&qpath, pat.hir_id)\n                .ctor_parent(cx)\n                .is_lang_item(cx, ResultErr)\n                == must_match_err\n        },\n        PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _, _) => {\n            is_variant_or_wildcard(cx, pat, can_be_wild, must_match_err)\n        },\n        _ => false,\n    }\n}\n\n/// Return `Some((true, IDENT))` if `pat` contains `Ok(IDENT)`, `Some((false, IDENT))` if it\n/// contains `Err(IDENT)`, `None` otherwise.\nfn is_ok_or_err<'hir>(cx: &LateContext<'_>, pat: &Pat<'hir>) -> Option<(bool, &'hir Ident)> {\n    if let PatKind::TupleStruct(qpath, [arg], _) = &pat.kind\n        && let PatKind::Binding(BindingMode::NONE, _, ident, None) = &arg.kind\n        && let res = cx.qpath_res(qpath, pat.hir_id)\n        && let Res::Def(DefKind::Ctor(..), id) = res\n        && let id @ Some(_) = cx.tcx.opt_parent(id)\n    {\n        let lang_items = cx.tcx.lang_items();\n        if id == lang_items.result_ok_variant() {\n            return Some((true, ident));\n        } else if id == lang_items.result_err_variant() {\n            return Some((false, ident));\n        }\n    }\n    None\n}\n\n/// Check if `expr` contains `Some(ident)`, possibly as a block\nfn is_some_ident<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, ident: &Ident, ty: Ty<'tcx>) -> bool {\n    if let Some(body_arg) = as_some_expr(cx, peel_blocks(expr))\n        && cx.typeck_results().expr_ty(body_arg) == ty\n        && let ExprKind::Path(QPath::Resolved(\n            _,\n            Path {\n                segments: [segment], ..\n            },\n        )) = body_arg.kind\n    {\n        segment.ident.name == ident.name\n    } else {\n        false\n    }\n}\n\n/// Check if `expr` is `None`, possibly as a block\nfn is_none(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    is_none_expr(cx, peel_blocks(expr))\n}\n\n/// Suggest replacing `expr` by `scrutinee.METHOD()`, where `METHOD` is either `ok` or\n/// `err`, depending on `is_ok`.\nfn apply_lint(cx: &LateContext<'_>, expr: &Expr<'_>, scrutinee: &Expr<'_>, is_ok: bool) {\n    let method = if is_ok { \"ok\" } else { \"err\" };\n    let mut app = if span_contains_comment(cx, expr.span) {\n        Applicability::MaybeIncorrect\n    } else {\n        Applicability::MachineApplicable\n    };\n    let scrut = Sugg::hir_with_context(cx, scrutinee, expr.span.ctxt(), \"..\", &mut app).maybe_paren();\n\n    let scrutinee_ty = cx.typeck_results().expr_ty(scrutinee);\n    let (_, _, mutability) = peel_and_count_ty_refs(scrutinee_ty);\n    let prefix = match mutability {\n        Some(Mutability::Mut) => \".as_mut()\",\n        Some(Mutability::Not) => \".as_ref()\",\n        None => \"\",\n    };\n\n    let sugg = format!(\"{scrut}{prefix}.{method}()\");\n\n    // If the expression being expanded is the `if …` part of an `else if …`, it must be blockified.\n    let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr)\n        && let ExprKind::If(_, _, Some(else_part)) = parent_expr.kind\n        && else_part.hir_id == expr.hir_id\n    {\n        reindent_multiline(&format!(\"{{\\n    {sugg}\\n}}\"), true, indent_of(cx, parent_expr.span))\n    } else {\n        sugg\n    };\n    span_lint_and_sugg(\n        cx,\n        MANUAL_OK_ERR,\n        expr.span,\n        format!(\"manual implementation of `{method}`\"),\n        \"replace with\",\n        sugg,\n        app,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/manual_unwrap_or.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse clippy_utils::source::{SpanRangeExt as _, indent_of, reindent_multiline};\nuse rustc_ast::{BindingMode, ByRef};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{Arm, Expr, ExprKind, HirId, LangItem, Pat, PatExpr, PatExprKind, PatKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{GenericArgKind, Ty};\nuse rustc_span::sym;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::{expr_type_is_certain, implements_trait, is_copy};\nuse clippy_utils::usage::local_used_after_expr;\nuse clippy_utils::{is_default_equivalent, is_lint_allowed, peel_blocks, span_contains_comment};\n\nuse super::{MANUAL_UNWRAP_OR, MANUAL_UNWRAP_OR_DEFAULT};\n\nfn get_some(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<HirId> {\n    if let PatKind::TupleStruct(QPath::Resolved(_, path), &[pat], _) = pat.kind\n        && let PatKind::Binding(BindingMode(ByRef::No, _), pat_id, _, _) = pat.kind\n        && let Some(def_id) = path.res.opt_def_id()\n        // Since it comes from a pattern binding, we need to get the parent to actually match\n        // against it.\n        && let Some(def_id) = cx.tcx.opt_parent(def_id)\n        && let Some(lang_item) = cx.tcx.lang_items().from_def_id(def_id)\n        && matches!(lang_item, LangItem::OptionSome | LangItem::ResultOk)\n    {\n        Some(pat_id)\n    } else {\n        None\n    }\n}\n\nfn get_none<'tcx>(cx: &LateContext<'_>, arm: &Arm<'tcx>, allow_wildcard: bool) -> Option<&'tcx Expr<'tcx>> {\n    if let PatKind::Expr(PatExpr { kind: PatExprKind::Path(QPath::Resolved(_, path)), .. }) = arm.pat.kind\n        && let Some(def_id) = path.res.opt_def_id()\n        // Since it comes from a pattern binding, we need to get the parent to actually match\n        // against it.\n        && let Some(def_id) = cx.tcx.opt_parent(def_id)\n        && cx.tcx.lang_items().get(LangItem::OptionNone) == Some(def_id)\n    {\n        Some(arm.body)\n    } else if let PatKind::TupleStruct(QPath::Resolved(_, path), _, _)= arm.pat.kind\n        && let Some(def_id) = path.res.opt_def_id()\n        // Since it comes from a pattern binding, we need to get the parent to actually match\n        // against it.\n        && let Some(def_id) = cx.tcx.opt_parent(def_id)\n        && cx.tcx.lang_items().get(LangItem::ResultErr) == Some(def_id)\n    {\n        Some(arm.body)\n    } else if let PatKind::Wild = arm.pat.kind\n        && allow_wildcard\n    {\n        // We consider that the `Some` check will filter it out if it's not right.\n        Some(arm.body)\n    } else {\n        None\n    }\n}\n\nfn get_some_and_none_bodies<'tcx>(\n    cx: &LateContext<'tcx>,\n    arm1: &'tcx Arm<'tcx>,\n    arm2: &'tcx Arm<'tcx>,\n) -> Option<((&'tcx Expr<'tcx>, HirId), &'tcx Expr<'tcx>)> {\n    if let Some(binding_id) = get_some(cx, arm1.pat)\n        && let Some(body_none) = get_none(cx, arm2, true)\n    {\n        Some(((arm1.body, binding_id), body_none))\n    } else if let Some(body_none) = get_none(cx, arm1, false)\n        && let Some(binding_id) = get_some(cx, arm2.pat)\n    {\n        Some(((arm2.body, binding_id), body_none))\n    } else {\n        None\n    }\n}\n\nfn handle(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    expr_name: &'static str,\n    condition: &Expr<'_>,\n    body_some: &Expr<'_>,\n    body_none: &Expr<'_>,\n    binding_id: HirId,\n) {\n    // Only deal with situations where both alternatives return the same non-adjusted type.\n    if cx.typeck_results().expr_ty(body_some) != cx.typeck_results().expr_ty(body_none)\n        || !safe_to_move_scrutinee(cx, expr, condition)\n    {\n        return;\n    }\n\n    let expr_type = cx.typeck_results().expr_ty(expr);\n    // We check that the `Some(x) => x` doesn't do anything apart \"returning\" the value in `Some`.\n    if let ExprKind::Path(QPath::Resolved(_, path)) = peel_blocks(body_some).kind\n        && let Res::Local(local_id) = path.res\n        && local_id == binding_id\n    {\n        // Machine applicable only if there are no comments present\n        let mut applicability = if span_contains_comment(cx, expr.span) {\n            Applicability::MaybeIncorrect\n        } else {\n            Applicability::MachineApplicable\n        };\n        let receiver = Sugg::hir_with_applicability(cx, condition, \"_\", &mut applicability).maybe_paren();\n\n        // We now check the `None` arm is calling a method equivalent to `Default::default`.\n        if !is_lint_allowed(cx, MANUAL_UNWRAP_OR_DEFAULT, expr.hir_id)\n            // We check if the return type of the expression implements Default.\n            && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)\n            && implements_trait(cx, expr_type, default_trait_id, &[])\n            // We check if the initial condition implements Default.\n            && let Some(condition_ty) = cx.typeck_results().expr_ty(condition).walk().nth(1)\n            && let GenericArgKind::Type(condition_ty) = condition_ty.kind()\n            && implements_trait(cx, condition_ty, default_trait_id, &[])\n            && is_default_equivalent(cx, peel_blocks(body_none))\n        {\n            // We now check if the condition is a None variant, in which case we need to specify the type\n            if condition\n                .res(cx)\n                .opt_def_id()\n                .is_some_and(|id| Some(cx.tcx.parent(id)) == cx.tcx.lang_items().option_none_variant())\n            {\n                return span_lint_and_sugg(\n                    cx,\n                    MANUAL_UNWRAP_OR_DEFAULT,\n                    expr.span,\n                    format!(\"{expr_name} can be simplified with `.unwrap_or_default()`\"),\n                    \"replace it with\",\n                    format!(\"{receiver}::<{expr_type}>.unwrap_or_default()\"),\n                    applicability,\n                );\n            }\n\n            // We check if the expression type is still uncertain, in which case we ask the user to specify it\n            if !expr_type_is_certain(cx, condition) {\n                return span_lint_and_sugg(\n                    cx,\n                    MANUAL_UNWRAP_OR_DEFAULT,\n                    expr.span,\n                    format!(\"{expr_name} can be simplified with `.unwrap_or_default()`\"),\n                    format!(\"ascribe the type {expr_type} and replace your expression with\"),\n                    format!(\"{receiver}.unwrap_or_default()\"),\n                    Applicability::Unspecified,\n                );\n            }\n\n            span_lint_and_sugg(\n                cx,\n                MANUAL_UNWRAP_OR_DEFAULT,\n                expr.span,\n                format!(\"{expr_name} can be simplified with `.unwrap_or_default()`\"),\n                \"replace it with\",\n                format!(\"{receiver}.unwrap_or_default()\"),\n                applicability,\n            );\n        } else if let Some(ty_name) = find_type_name(cx, cx.typeck_results().expr_ty(condition))\n            && cx.typeck_results().expr_adjustments(body_some).is_empty()\n            && let Some(or_body_snippet) = peel_blocks(body_none).span.get_source_text(cx)\n            && let Some(indent) = indent_of(cx, expr.span)\n            && ConstEvalCtxt::new(cx).eval_local(body_none, expr.span.ctxt()).is_some()\n        {\n            let reindented_or_body = reindent_multiline(&or_body_snippet, true, Some(indent));\n            let mut app = Applicability::MachineApplicable;\n            let suggestion = Sugg::hir_with_context(cx, condition, expr.span.ctxt(), \"..\", &mut app).maybe_paren();\n            span_lint_and_sugg(\n                cx,\n                MANUAL_UNWRAP_OR,\n                expr.span,\n                format!(\"this pattern reimplements `{ty_name}::unwrap_or`\"),\n                \"replace with\",\n                format!(\"{suggestion}.unwrap_or({reindented_or_body})\"),\n                app,\n            );\n        }\n    }\n}\n\nfn find_type_name<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'static str> {\n    match ty.opt_diag_name(cx)? {\n        sym::Option => Some(\"Option\"),\n        sym::Result => Some(\"Result\"),\n        _ => None,\n    }\n}\n\n/// Checks whether it is safe to move scrutinee.\n/// It is not safe to move if:\n///     1. `scrutinee` is a `Result` that doesn't implemenet `Copy`, mainly because the `Err`\n///        variant is not copyable.\n///     2. `expr` is a local variable that is used after the if-let-else expression.\n/// ```rust,ignore\n/// let foo: Result<usize, String> = Ok(0);\n/// let v = if let Ok(v) = foo { v } else { 1 };\n/// let bar = foo;\n/// ```\nfn safe_to_move_scrutinee(cx: &LateContext<'_>, expr: &Expr<'_>, scrutinee: &Expr<'_>) -> bool {\n    if let Some(hir_id) = scrutinee.res_local_id()\n        && let scrutinee_ty = cx.typeck_results().expr_ty(scrutinee)\n        && scrutinee_ty.is_diag_item(cx, sym::Result)\n        && !is_copy(cx, scrutinee_ty)\n        && local_used_after_expr(cx, hir_id, expr)\n    {\n        false\n    } else {\n        true\n    }\n}\n\npub fn check_match<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    scrutinee: &'tcx Expr<'tcx>,\n    arms: &'tcx [Arm<'tcx>],\n) {\n    if let [arm1, arm2] = arms\n        // Make sure there are no guards to keep things simple\n        && arm1.guard.is_none()\n        && arm2.guard.is_none()\n        // Get the some and none bodies and the binding id of the some arm\n        && let Some(((body_some, binding_id), body_none)) = get_some_and_none_bodies(cx, arm1, arm2)\n    {\n        handle(cx, expr, \"match\", scrutinee, body_some, body_none, binding_id);\n    }\n}\n\npub fn check_if_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    pat: &'tcx Pat<'tcx>,\n    scrutinee: &'tcx Expr<'tcx>,\n    then_expr: &'tcx Expr<'tcx>,\n    else_expr: &'tcx Expr<'tcx>,\n) {\n    if let Some(binding_id) = get_some(cx, pat) {\n        handle(\n            cx,\n            expr,\n            \"if let\",\n            scrutinee,\n            peel_blocks(then_expr),\n            peel_blocks(else_expr),\n            binding_id,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/manual_utils.rs",
    "content": "use crate::map_unit_fn::OPTION_MAP_UNIT_FN;\nuse crate::matches::MATCH_AS_REF;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::{is_copy, is_unsafe_fn, peel_and_count_ty_refs};\nuse clippy_utils::{\n    CaptureKind, as_some_pattern, can_move_expr_to_closure, expr_requires_coercion, is_else_clause, is_lint_allowed,\n    is_none_expr, is_none_pattern, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while,\n};\nuse rustc_ast::util::parser::ExprPrecedence;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BindingMode, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Path, QPath};\nuse rustc_lint::LateContext;\nuse rustc_span::{SyntaxContext, sym};\n\n#[expect(clippy::too_many_arguments)]\n#[expect(clippy::too_many_lines)]\npub(super) fn check_with<'tcx, F>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    scrutinee: &'tcx Expr<'_>,\n    then_pat: &'tcx Pat<'_>,\n    then_body: &'tcx Expr<'_>,\n    else_pat: Option<&'tcx Pat<'_>>,\n    else_body: &'tcx Expr<'_>,\n    get_some_expr_fn: F,\n) -> Option<SuggInfo<'tcx>>\nwhere\n    F: Fn(&LateContext<'tcx>, &'tcx Pat<'_>, &'tcx Expr<'_>, SyntaxContext) -> Option<SomeExpr<'tcx>>,\n{\n    let (scrutinee_ty, ty_ref_count, ty_mutability) = peel_and_count_ty_refs(cx.typeck_results().expr_ty(scrutinee));\n    let ty_mutability = ty_mutability.unwrap_or(Mutability::Mut);\n\n    if !(scrutinee_ty.is_diag_item(cx, sym::Option) && cx.typeck_results().expr_ty(expr).is_diag_item(cx, sym::Option))\n    {\n        return None;\n    }\n\n    let expr_ctxt = expr.span.ctxt();\n    let (some_expr, some_pat, pat_ref_count, is_wild_none) = match (\n        try_parse_pattern(cx, then_pat, expr_ctxt),\n        else_pat.map_or(Some(OptionPat::Wild), |p| try_parse_pattern(cx, p, expr_ctxt)),\n    ) {\n        (Some(OptionPat::Wild), Some(OptionPat::Some { pattern, ref_count })) if is_none_arm_body(cx, then_body) => {\n            (else_body, pattern, ref_count, true)\n        },\n        (Some(OptionPat::None), Some(OptionPat::Some { pattern, ref_count })) if is_none_arm_body(cx, then_body) => {\n            (else_body, pattern, ref_count, false)\n        },\n        (Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::Wild)) if is_none_arm_body(cx, else_body) => {\n            (then_body, pattern, ref_count, true)\n        },\n        (Some(OptionPat::Some { pattern, ref_count }), Some(OptionPat::None)) if is_none_arm_body(cx, else_body) => {\n            (then_body, pattern, ref_count, false)\n        },\n        _ => return None,\n    };\n\n    // Top level or patterns aren't allowed in closures.\n    if matches!(some_pat.kind, PatKind::Or(_)) {\n        return None;\n    }\n\n    let some_expr = get_some_expr_fn(cx, some_pat, some_expr, expr_ctxt)?;\n\n    // These two lints will go back and forth with each other.\n    if cx.typeck_results().expr_ty(some_expr.expr) == cx.tcx.types.unit\n        && !is_lint_allowed(cx, OPTION_MAP_UNIT_FN, expr.hir_id)\n    {\n        return None;\n    }\n\n    // `map` won't perform any adjustments.\n    if expr_requires_coercion(cx, expr) {\n        return None;\n    }\n\n    // Determine which binding mode to use.\n    let explicit_ref = some_pat.contains_explicit_ref_binding();\n    let binding_ref = explicit_ref.or_else(|| (ty_ref_count != pat_ref_count).then_some(ty_mutability));\n\n    let as_ref_str = match binding_ref {\n        Some(Mutability::Mut) => \".as_mut()\",\n        Some(Mutability::Not) => \".as_ref()\",\n        None => \"\",\n    };\n\n    match can_move_expr_to_closure(cx, some_expr.expr) {\n        Some(captures) => {\n            // Check if captures the closure will need conflict with borrows made in the scrutinee.\n            // TODO: check all the references made in the scrutinee expression. This will require interacting\n            // with the borrow checker. Currently only `<local>[.<field>]*` is checked for.\n            if let Some(binding_ref_mutability) = binding_ref {\n                let e = peel_hir_expr_while(scrutinee, |e| match e.kind {\n                    ExprKind::Field(e, _) | ExprKind::AddrOf(_, _, e) => Some(e),\n                    _ => None,\n                });\n                if let ExprKind::Path(QPath::Resolved(None, Path { res: Res::Local(l), .. })) = e.kind {\n                    match captures.get(l) {\n                        Some(CaptureKind::Value | CaptureKind::Use | CaptureKind::Ref(Mutability::Mut)) => return None,\n                        Some(CaptureKind::Ref(Mutability::Not)) if binding_ref_mutability == Mutability::Mut => {\n                            return None;\n                        },\n                        Some(CaptureKind::Ref(Mutability::Not)) | None => (),\n                    }\n                }\n            }\n        },\n        None => return None,\n    }\n\n    let mut app = Applicability::MachineApplicable;\n\n    // Remove address-of expressions from the scrutinee. Either `as_ref` will be called, or\n    // it's being passed by value.\n    let scrutinee = peel_hir_expr_refs(scrutinee).0;\n    let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, \"..\", &mut app);\n    let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && cx.precedence(scrutinee) < ExprPrecedence::Unambiguous {\n        format!(\"({scrutinee_str})\")\n    } else {\n        scrutinee_str.into()\n    };\n\n    let closure_expr_snip = some_expr.to_snippet_with_context(cx, expr_ctxt, &mut app);\n    let closure_body = if some_expr.needs_unsafe_block {\n        format!(\"unsafe {}\", closure_expr_snip.blockify())\n    } else {\n        closure_expr_snip.to_string()\n    };\n\n    let body_str = if let PatKind::Binding(annotation, id, some_binding, None) = some_pat.kind {\n        if !some_expr.needs_unsafe_block\n            && let Some(func) = can_pass_as_func(cx, id, some_expr.expr)\n            && func.span.eq_ctxt(some_expr.expr.span)\n        {\n            snippet_with_applicability(cx, func.span, \"..\", &mut app).into_owned()\n        } else {\n            if some_expr.expr.res_local_id() == Some(id)\n                && !is_lint_allowed(cx, MATCH_AS_REF, expr.hir_id)\n                && binding_ref.is_some()\n            {\n                return None;\n            }\n\n            // `ref` and `ref mut` annotations were handled earlier.\n            let annotation = if matches!(annotation, BindingMode::MUT) {\n                \"mut \"\n            } else {\n                \"\"\n            };\n\n            format!(\"|{annotation}{some_binding}| {closure_body}\")\n        }\n    } else if !is_wild_none && explicit_ref.is_none() {\n        // TODO: handle explicit reference annotations.\n        let pat_snip = snippet_with_context(cx, some_pat.span, expr_ctxt, \"..\", &mut app).0;\n        format!(\"|{pat_snip}| {closure_body}\")\n    } else {\n        // Refutable bindings and mixed reference annotations can't be handled by `map`.\n        return None;\n    };\n\n    // relies on the fact that Option<T>: Copy where T: copy\n    let scrutinee_impl_copy = is_copy(cx, scrutinee_ty);\n\n    Some(SuggInfo {\n        needs_brackets: else_pat.is_none() && is_else_clause(cx.tcx, expr),\n        scrutinee_impl_copy,\n        scrutinee_str,\n        as_ref_str,\n        body_str,\n        app,\n    })\n}\n\npub struct SuggInfo<'a> {\n    pub needs_brackets: bool,\n    pub scrutinee_impl_copy: bool,\n    pub scrutinee_str: String,\n    pub as_ref_str: &'a str,\n    pub body_str: String,\n    pub app: Applicability,\n}\n\n// Checks whether the expression could be passed as a function, or whether a closure is needed.\n// Returns the function to be passed to `map` if it exists.\nfn can_pass_as_func<'tcx>(cx: &LateContext<'tcx>, binding: HirId, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {\n    match expr.kind {\n        ExprKind::Call(func, [arg])\n            if arg.res_local_id() == Some(binding)\n                && cx.typeck_results().expr_adjustments(arg).is_empty()\n                && !is_unsafe_fn(cx, cx.typeck_results().expr_ty(func).peel_refs()) =>\n        {\n            Some(func)\n        },\n        _ => None,\n    }\n}\n\n#[derive(Debug)]\npub(super) enum OptionPat<'a> {\n    Wild,\n    None,\n    Some {\n        // The pattern contained in the `Some` tuple.\n        pattern: &'a Pat<'a>,\n        // The number of references before the `Some` tuple.\n        // e.g. `&&Some(_)` has a ref count of 2.\n        ref_count: usize,\n    },\n}\n\npub(super) struct SomeExpr<'tcx> {\n    pub expr: &'tcx Expr<'tcx>,\n    pub needs_unsafe_block: bool,\n    pub needs_negated: bool, // for `manual_filter` lint\n}\n\nimpl<'tcx> SomeExpr<'tcx> {\n    pub fn new_no_negated(expr: &'tcx Expr<'tcx>, needs_unsafe_block: bool) -> Self {\n        Self {\n            expr,\n            needs_unsafe_block,\n            needs_negated: false,\n        }\n    }\n\n    pub fn to_snippet_with_context(\n        &self,\n        cx: &LateContext<'tcx>,\n        ctxt: SyntaxContext,\n        app: &mut Applicability,\n    ) -> Sugg<'tcx> {\n        let sugg = Sugg::hir_with_context(cx, self.expr, ctxt, \"..\", app);\n        if self.needs_negated { !sugg } else { sugg }\n    }\n}\n\n// Try to parse into a recognized `Option` pattern.\n// i.e. `_`, `None`, `Some(..)`, or a reference to any of those.\npub(super) fn try_parse_pattern<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    ctxt: SyntaxContext,\n) -> Option<OptionPat<'tcx>> {\n    fn f<'tcx>(\n        cx: &LateContext<'tcx>,\n        pat: &'tcx Pat<'_>,\n        ref_count: usize,\n        ctxt: SyntaxContext,\n    ) -> Option<OptionPat<'tcx>> {\n        match pat.kind {\n            PatKind::Wild => Some(OptionPat::Wild),\n            PatKind::Ref(pat, _, _) => f(cx, pat, ref_count + 1, ctxt),\n            _ if is_none_pattern(cx, pat) => Some(OptionPat::None),\n            _ if let Some([pattern]) = as_some_pattern(cx, pat)\n                && pat.span.ctxt() == ctxt =>\n            {\n                Some(OptionPat::Some { pattern, ref_count })\n            },\n            _ => None,\n        }\n    }\n    f(cx, pat, 0, ctxt)\n}\n\n/// Checks for the `None` value, possibly in a block.\nfn is_none_arm_body(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    is_none_expr(cx, peel_blocks(expr))\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_as_ref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::option_arg_ty;\nuse clippy_utils::{as_some_expr, as_some_pattern, is_none_arm, peel_blocks};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, Mutability, PatKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::MATCH_AS_REF;\n\npub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {\n    if let [arm1, arm2] = arms\n        && arm1.guard.is_none()\n        && arm2.guard.is_none()\n        && let Some(arm_ref_mutbl) = if is_none_arm(cx, arm1) {\n            as_ref_some_arm(cx, arm2)\n        } else if is_none_arm(cx, arm2) {\n            as_ref_some_arm(cx, arm1)\n        } else {\n            None\n        }\n        && let output_ty = cx.typeck_results().expr_ty(expr)\n        && let input_ty = cx.typeck_results().expr_ty(ex)\n        && let Some(input_ty) = option_arg_ty(cx, input_ty)\n        && let Some(output_ty) = option_arg_ty(cx, output_ty)\n        && let ty::Ref(_, output_ty, output_mutbl) = *output_ty.kind()\n    {\n        let method = match arm_ref_mutbl {\n            Mutability::Not => \"as_ref\",\n            Mutability::Mut => \"as_mut\",\n        };\n\n        // ```\n        // let _: Option<&T> = match opt {\n        //     Some(ref mut t) => Some(t),\n        //     None => None,\n        // };\n        // ```\n        // We need to suggest `t.as_ref()` in order downcast the reference from `&mut` to `&`.\n        // We may or may not need to cast the type as well, for which we'd need `.map()`, and that could\n        // theoretically take care of the reference downcasting as well, but we chose to keep these two\n        // operations separate\n        let need_as_ref = arm_ref_mutbl == Mutability::Mut && output_mutbl == Mutability::Not;\n\n        let cast = if input_ty == output_ty { \"\" } else { \".map(|x| x as _)\" };\n\n        let mut applicability = Applicability::MachineApplicable;\n        let ctxt = expr.span.ctxt();\n        span_lint_and_then(\n            cx,\n            MATCH_AS_REF,\n            expr.span,\n            format!(\"manual implementation of `Option::{method}`\"),\n            |diag| {\n                if need_as_ref {\n                    diag.note(\"but the type is coerced to a non-mutable reference, and so `as_ref` can used instead\");\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        \"use `Option::as_ref()`\",\n                        format!(\n                            \"{}.as_ref(){cast}\",\n                            Sugg::hir_with_context(cx, ex, ctxt, \"_\", &mut applicability).maybe_paren(),\n                        ),\n                        applicability,\n                    );\n                } else {\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        format!(\"use `Option::{method}()` directly\"),\n                        format!(\n                            \"{}.{method}(){cast}\",\n                            Sugg::hir_with_context(cx, ex, ctxt, \"_\", &mut applicability).maybe_paren(),\n                        ),\n                        applicability,\n                    );\n                }\n            },\n        );\n    }\n}\n\n// Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)\nfn as_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<Mutability> {\n    if let Some([first_pat, ..]) = as_some_pattern(cx, arm.pat)\n        && let PatKind::Binding(BindingMode(ByRef::Yes(_, mutabl), _), .., ident, _) = first_pat.kind\n        && let Some(arg) = as_some_expr(cx, peel_blocks(arm.body))\n        && let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind\n        && path2.segments.len() == 1\n        && ident.name == path2.segments[0].ident.name\n    {\n        return Some(mutabl);\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_bool.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_unit_expr;\nuse clippy_utils::source::expr_block;\nuse clippy_utils::sugg::Sugg;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Arm, Expr, PatExprKind, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::MATCH_BOOL;\n\npub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {\n    // Type of expression is `bool`.\n    if *cx.typeck_results().expr_ty(scrutinee).kind() == ty::Bool\n        && arms\n            .iter()\n            .all(|arm| arm.pat.walk_short(|p| !matches!(p.kind, PatKind::Binding(..))))\n        && arms.len() == 2\n    {\n        span_lint_and_then(\n            cx,\n            MATCH_BOOL,\n            expr.span,\n            \"`match` on a boolean expression\",\n            move |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let ctxt = expr.span.ctxt();\n                let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind {\n                    let test = Sugg::hir_with_context(cx, scrutinee, ctxt, \"_\", &mut app);\n                    if let PatExprKind::Lit { lit, .. } = arm_bool.kind {\n                        match &lit.node {\n                            LitKind::Bool(true) => Some(test),\n                            LitKind::Bool(false) => Some(!test),\n                            _ => None,\n                        }\n                        .map(|test| {\n                            if let Some(guard) = &arms[0]\n                                .guard\n                                .map(|g| Sugg::hir_with_context(cx, g, ctxt, \"_\", &mut app))\n                            {\n                                test.and(guard)\n                            } else {\n                                test\n                            }\n                        })\n                    } else {\n                        None\n                    }\n                } else {\n                    None\n                };\n\n                if let Some(test_sugg) = test_sugg {\n                    let ctxt = expr.span.ctxt();\n                    let (true_expr, false_expr) = (arms[0].body, arms[1].body);\n                    let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {\n                        (false, false) => Some(format!(\n                            \"if {} {} else {}\",\n                            test_sugg,\n                            expr_block(cx, true_expr, ctxt, \"..\", Some(expr.span), &mut app),\n                            expr_block(cx, false_expr, ctxt, \"..\", Some(expr.span), &mut app)\n                        )),\n                        (false, true) => Some(format!(\n                            \"if {} {}\",\n                            test_sugg,\n                            expr_block(cx, true_expr, ctxt, \"..\", Some(expr.span), &mut app)\n                        )),\n                        (true, false) => Some(format!(\n                            \"if {} {}\",\n                            !test_sugg,\n                            expr_block(cx, false_expr, ctxt, \"..\", Some(expr.span), &mut app)\n                        )),\n                        (true, true) => None,\n                    };\n\n                    if let Some(sugg) = sugg {\n                        diag.span_suggestion(expr.span, \"consider using an `if`/`else` expression\", sugg, app);\n                    }\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_like_matches.rs",
    "content": "//! Lint a `match` or `if let .. { .. } else { .. }` expr that could be replaced by `matches!`\n\nuse super::REDUNDANT_PATTERN_MATCHING;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::has_let_expr;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::{is_lint_allowed, is_wild, span_contains_comment};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Pat, PatKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::source_map::Spanned;\n\nuse super::MATCH_LIKE_MATCHES_MACRO;\n\npub(crate) fn check_if_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    let_pat: &'tcx Pat<'_>,\n    let_expr: &'tcx Expr<'_>,\n    then_expr: &'tcx Expr<'_>,\n    else_expr: &'tcx Expr<'_>,\n) {\n    if !span_contains_comment(cx, expr.span)\n        && cx.typeck_results().expr_ty(expr).is_bool()\n        && let Some(b0) = find_bool_lit(then_expr)\n        && let Some(b1) = find_bool_lit(else_expr)\n        && b0 != b1\n    {\n        if !is_lint_allowed(cx, REDUNDANT_PATTERN_MATCHING, let_pat.hir_id) && is_some_wild(let_pat.kind) {\n            return;\n        }\n\n        // The suggestion may be incorrect, because some arms can have `cfg` attributes\n        // evaluated into `false` and so such arms will be stripped before.\n        let mut applicability = Applicability::MaybeIncorrect;\n        let pat = snippet_with_applicability(cx, let_pat.span, \"..\", &mut applicability);\n\n        // strip potential borrows (#6503), but only if the type is a reference\n        let mut ex_new = let_expr;\n        if let ExprKind::AddrOf(BorrowKind::Ref, .., ex_inner) = let_expr.kind\n            && let ty::Ref(..) = cx.typeck_results().expr_ty(ex_inner).kind()\n        {\n            ex_new = ex_inner;\n        }\n\n        let (snippet, _) = snippet_with_context(cx, ex_new.span, expr.span.ctxt(), \"..\", &mut applicability);\n        span_lint_and_then(\n            cx,\n            MATCH_LIKE_MATCHES_MACRO,\n            expr.span,\n            \"`if let .. else` expression looks like `matches!` macro\",\n            |diag| {\n                diag.span_suggestion_verbose(\n                    expr.span,\n                    \"use `matches!` directly\",\n                    format!(\"{}matches!({snippet}, {pat})\", if b0 { \"\" } else { \"!\" }),\n                    applicability,\n                );\n            },\n        );\n    }\n}\n\npub(super) fn check_match<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    scrutinee: &'tcx Expr<'_>,\n    arms: &'tcx [Arm<'tcx>],\n) -> bool {\n    if let Some((last_arm, arms_without_last)) = arms.split_last()\n        && let Some((first_arm, middle_arms)) = arms_without_last.split_first()\n        && !span_contains_comment(cx, e.span)\n        && cx.typeck_results().expr_ty(e).is_bool()\n        && let Some(b0) = find_bool_lit(first_arm.body)\n        && let Some(b1) = find_bool_lit(last_arm.body)\n        && b0 != b1\n        // We handle two cases:\n        && (\n            // - There are no middle arms, i.e., 2 arms in total\n            //\n            // In that case, the first arm may or may not have a guard, because this:\n            // ```rs\n            // match e {\n            //     Either::Left $(if $guard)|+ => true, // or `false`, but then we'll need `!matches!(..)`\n            //     _ => false,\n            // }\n            // ```\n            // can always become this:\n            // ```rs\n            // matches!(e, Either::Left $(if $guard)|+)\n            // ```\n            //\n            // But if the guard _is_ present, it may not be an `if-let` guard, as `matches!` doesn't\n            // support these (currently?)\n            (middle_arms.is_empty() && first_arm.guard.is_none_or(|g| !has_let_expr(g)))\n\n            // - (added in #6216) There are middle arms\n            //\n            // In that case, neither they nor the first arm may have guards\n            // -- otherwise, they couldn't be combined into an or-pattern in `matches!`\n            //\n            // This:\n            // ```rs\n            // match e {\n            //     Either3::First => true,\n            //     Either3::Second => true,\n            //     _ /* matches `Either3::Third` */ => false,\n            // }\n            // ```\n            // can become this:\n            // ```rs\n            // matches!(e, Either3::First | Either3::Second)\n            // ```\n            //\n            // But this:\n            // ```rs\n            // match e {\n            //     Either3::First if X => true,\n            //     Either3::Second => true,\n            //     _ => false,\n            // }\n            // ```\n            // cannot be transformed.\n            //\n            // We set an additional constraint of all of them needing to return the same bool,\n            // so we don't lint things like:\n            // ```rs\n            // match e {\n            //     Either3::First => true,\n            //     Either3::Second => false,\n            //     _ => false,\n            // }\n            // ```\n            // This is not *strictly* necessary, but it simplifies the logic a bit\n            || arms_without_last.iter().all(|arm| {\n                cx.tcx.hir_attrs(arm.hir_id).is_empty() && arm.guard.is_none() && find_bool_lit(arm.body) == Some(b0)\n            })\n        )\n    {\n        if !is_wild(last_arm.pat) {\n            return false;\n        }\n\n        for arm in arms_without_last {\n            let pat = arm.pat;\n            if !is_lint_allowed(cx, REDUNDANT_PATTERN_MATCHING, pat.hir_id) && is_some_wild(pat.kind) {\n                return false;\n            }\n        }\n\n        // The suggestion may be incorrect, because some arms can have `cfg` attributes\n        // evaluated into `false` and so such arms will be stripped before.\n        let mut applicability = Applicability::MaybeIncorrect;\n        let pat = {\n            use itertools::Itertools as _;\n            arms_without_last\n                .iter()\n                .map(|arm| snippet_with_applicability(cx, arm.pat.span, \"..\", &mut applicability))\n                .join(\" | \")\n        };\n        let pat_and_guard = if let Some(g) = first_arm.guard {\n            format!(\n                \"{pat} if {}\",\n                snippet_with_applicability(cx, g.span, \"..\", &mut applicability)\n            )\n        } else {\n            pat\n        };\n\n        // strip potential borrows (#6503), but only if the type is a reference\n        let mut ex_new = scrutinee;\n        if let ExprKind::AddrOf(BorrowKind::Ref, .., ex_inner) = scrutinee.kind\n            && let ty::Ref(..) = cx.typeck_results().expr_ty(ex_inner).kind()\n        {\n            ex_new = ex_inner;\n        }\n\n        let (snippet, _) = snippet_with_context(cx, ex_new.span, e.span.ctxt(), \"..\", &mut applicability);\n        span_lint_and_then(\n            cx,\n            MATCH_LIKE_MATCHES_MACRO,\n            e.span,\n            \"match expression looks like `matches!` macro\",\n            |diag| {\n                diag.span_suggestion_verbose(\n                    e.span,\n                    \"use `matches!` directly\",\n                    format!(\"{}matches!({snippet}, {pat_and_guard})\", if b0 { \"\" } else { \"!\" }),\n                    applicability,\n                );\n            },\n        );\n        true\n    } else {\n        false\n    }\n}\n\n/// Extract a `bool` or `{ bool }`\nfn find_bool_lit(ex: &Expr<'_>) -> Option<bool> {\n    match ex.kind {\n        ExprKind::Lit(Spanned {\n            node: LitKind::Bool(b), ..\n        }) => Some(b),\n        ExprKind::Block(\n            rustc_hir::Block {\n                stmts: [],\n                expr: Some(exp),\n                ..\n            },\n            _,\n        ) => {\n            if let ExprKind::Lit(Spanned {\n                node: LitKind::Bool(b), ..\n            }) = exp.kind\n            {\n                Some(b)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\n/// Checks whether a pattern is `Some(_)`\nfn is_some_wild(pat_kind: PatKind<'_>) -> bool {\n    match pat_kind {\n        PatKind::TupleStruct(QPath::Resolved(_, path), [first, ..], _) if is_wild(first) => {\n            let name = path.segments[0].ident;\n            name.name == rustc_span::sym::Some\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_ref_pats.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{snippet, walk_span_to_context};\nuse clippy_utils::sugg::Sugg;\nuse core::iter::once;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind};\nuse rustc_lint::LateContext;\n\nuse super::MATCH_REF_PATS;\n\npub(crate) fn check<'a, 'b, I>(cx: &LateContext<'_>, scrutinee: &Expr<'_>, pats: I, expr: &Expr<'_>)\nwhere\n    'b: 'a,\n    I: Clone + Iterator<Item = &'a Pat<'b>>,\n{\n    if !has_multiple_ref_pats(pats.clone()) {\n        return;\n    }\n\n    // `!` cannot be deref-ed\n    if cx.typeck_results().expr_ty(scrutinee).is_never() {\n        return;\n    }\n\n    let (first_sugg, msg, title);\n    let ctxt = expr.span.ctxt();\n    let mut app = Applicability::Unspecified;\n    if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = scrutinee.kind {\n        if scrutinee.span.ctxt() != ctxt {\n            return;\n        }\n        first_sugg = once((\n            scrutinee.span,\n            Sugg::hir_with_context(cx, inner, ctxt, \"..\", &mut app).to_string(),\n        ));\n        msg = \"try\";\n        title = \"you don't need to add `&` to both the expression and the patterns\";\n    } else {\n        let Some(span) = walk_span_to_context(scrutinee.span, ctxt) else {\n            return;\n        };\n        first_sugg = once((\n            span,\n            Sugg::hir_with_context(cx, scrutinee, ctxt, \"..\", &mut app)\n                .deref()\n                .to_string(),\n        ));\n        msg = \"instead of prefixing all patterns with `&`, you can dereference the expression\";\n        title = \"you don't need to add `&` to all patterns\";\n    }\n\n    let remaining_suggs = pats.filter_map(|pat| {\n        if let PatKind::Ref(refp, _, _) = pat.kind {\n            Some((pat.span, snippet(cx, refp.span, \"..\").to_string()))\n        } else {\n            None\n        }\n    });\n\n    span_lint_and_then(cx, MATCH_REF_PATS, expr.span, title, |diag| {\n        if !expr.span.from_expansion() {\n            diag.multipart_suggestion(\n                msg,\n                first_sugg.chain(remaining_suggs).collect(),\n                Applicability::MachineApplicable,\n            );\n        }\n    });\n}\n\nfn has_multiple_ref_pats<'a, 'b, I>(pats: I) -> bool\nwhere\n    'b: 'a,\n    I: Iterator<Item = &'a Pat<'b>>,\n{\n    let mut ref_count = 0;\n    for opt in pats.map(|pat| match pat.kind {\n        PatKind::Ref(..) => Some(true), // &-patterns\n        PatKind::Wild => Some(false),   // an \"anything\" wildcard is also fine\n        _ => None,                      // any other pattern is not fine\n    }) {\n        if let Some(inner) = opt {\n            if inner {\n                ref_count += 1;\n            }\n        } else {\n            return false;\n        }\n    }\n    ref_count > 1\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_same_arms.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{SpanlessEq, fulfill_or_allowed, hash_expr, is_lint_allowed, search_same};\nuse core::cmp::Ordering;\nuse core::{iter, slice};\nuse itertools::Itertools;\nuse rustc_arena::DroplessArena;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{Arm, Expr, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatExpr, PatExprKind, PatKind, RangeEnd};\nuse rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::{self, TypeckResults};\nuse rustc_span::{ByteSymbol, ErrorGuaranteed, Span, Symbol};\n\nuse super::MATCH_SAME_ARMS;\n\n#[expect(clippy::too_many_lines)]\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {\n    let hash = |&(_, arm): &(_, &Arm<'_>)| hash_expr(cx, arm.body);\n\n    let arena = DroplessArena::default();\n    let normalized_pats: Vec<_> = arms\n        .iter()\n        .map(|a| NormalizedPat::from_pat(cx, &arena, a.pat))\n        .collect();\n\n    // The furthest forwards a pattern can move without semantic changes\n    let forwards_blocking_idxs: Vec<_> = normalized_pats\n        .iter()\n        .enumerate()\n        .map(|(i, pat)| {\n            (normalized_pats[i + 1..].iter().enumerate())\n                .find_map(|(j, other)| pat.has_overlapping_values(other).then_some(i + 1 + j))\n                .unwrap_or(normalized_pats.len())\n        })\n        .collect();\n\n    // The furthest backwards a pattern can move without semantic changes\n    let backwards_blocking_idxs: Vec<_> = normalized_pats\n        .iter()\n        .enumerate()\n        .map(|(i, pat)| {\n            iter::zip(\n                normalized_pats[..i].iter().enumerate().rev(),\n                forwards_blocking_idxs[..i].iter().copied().rev(),\n            )\n            .skip_while(|&(_, forward_block)| forward_block > i)\n            .find_map(|((j, other), forward_block)| {\n                (forward_block == i || pat.has_overlapping_values(other)).then_some(j)\n            })\n            .unwrap_or(0)\n        })\n        .collect();\n\n    let eq = |&(lindex, lhs): &(usize, &Arm<'_>), &(rindex, rhs): &(usize, &Arm<'_>)| -> bool {\n        let min_index = usize::min(lindex, rindex);\n        let max_index = usize::max(lindex, rindex);\n\n        let check_eq_with_pat = |expr_a: &Expr<'_>, expr_b: &Expr<'_>| {\n            let mut local_map: HirIdMap<HirId> = HirIdMap::default();\n            let eq_fallback = |a_typeck_results: &TypeckResults<'tcx>,\n                               a: &Expr<'_>,\n                               b_typeck_results: &TypeckResults<'tcx>,\n                               b: &Expr<'_>| {\n                if let Some(a_id) = a.res_local_id()\n                    && let Some(b_id) = b.res_local_id()\n                    && let entry = match local_map.entry(a_id) {\n                        HirIdMapEntry::Vacant(entry) => entry,\n                        // check if using the same bindings as before\n                        HirIdMapEntry::Occupied(entry) => return *entry.get() == b_id,\n                    }\n                    // the names technically don't have to match; this makes the lint more conservative\n                    && cx.tcx.hir_name(a_id) == cx.tcx.hir_name(b_id)\n                    && a_typeck_results.expr_ty(a) == b_typeck_results.expr_ty(b)\n                    && pat_contains_local(lhs.pat, a_id)\n                    && pat_contains_local(rhs.pat, b_id)\n                {\n                    entry.insert(b_id);\n                    true\n                } else {\n                    false\n                }\n            };\n\n            SpanlessEq::new(cx)\n                .expr_fallback(eq_fallback)\n                .eq_expr(expr_a, expr_b)\n                // these checks could be removed to allow unused bindings\n                && bindings_eq(lhs.pat, local_map.keys().copied().collect())\n                && bindings_eq(rhs.pat, local_map.values().copied().collect())\n        };\n\n        let check_same_guard = || match (&lhs.guard, &rhs.guard) {\n            (None, None) => true,\n            (Some(lhs_guard), Some(rhs_guard)) => check_eq_with_pat(lhs_guard, rhs_guard),\n            _ => false,\n        };\n\n        let check_same_body = || check_eq_with_pat(lhs.body, rhs.body);\n\n        // Arms with different guard are ignored, those can’t always be merged together\n        // If both arms overlap with an arm in between then these can't be merged either.\n        !(backwards_blocking_idxs[max_index] > min_index && forwards_blocking_idxs[min_index] < max_index)\n            && check_same_guard()\n            && check_same_body()\n    };\n\n    let indexed_arms: Vec<(usize, &Arm<'_>)> = arms.iter().enumerate().collect();\n    for mut group in search_same(&indexed_arms, hash, eq) {\n        // Filter out (and fulfill) `#[allow]`ed and `#[expect]`ed arms\n        group.retain(|(_, arm)| !fulfill_or_allowed(cx, MATCH_SAME_ARMS, [arm.hir_id]));\n\n        if group.len() < 2 {\n            continue;\n        }\n\n        span_lint_and_then(\n            cx,\n            MATCH_SAME_ARMS,\n            group.iter().map(|(_, arm)| arm.span).collect_vec(),\n            \"these match arms have identical bodies\",\n            |diag| {\n                diag.help(\"if this is unintentional make the arms return different values\");\n\n                if let [prev @ .., (_, last)] = group.as_slice()\n                    && is_wildcard_arm(last.pat)\n                    && is_lint_allowed(cx, NON_EXHAUSTIVE_OMITTED_PATTERNS, last.hir_id)\n                {\n                    diag.span_label(last.span, \"the wildcard arm\");\n\n                    let s = if prev.len() > 1 { \"s\" } else { \"\" };\n                    diag.multipart_suggestion(\n                        format!(\"otherwise remove the non-wildcard arm{s}\"),\n                        prev.iter()\n                            .map(|(_, arm)| (adjusted_arm_span(cx, arm.span), String::new()))\n                            .collect(),\n                        Applicability::MaybeIncorrect,\n                    );\n                } else if let &[&(first_idx, _), .., &(last_idx, _)] = group.as_slice() {\n                    let back_block = backwards_blocking_idxs[last_idx];\n                    let split = if back_block < first_idx\n                        || (back_block == 0 && forwards_blocking_idxs[first_idx] <= last_idx)\n                    {\n                        group.split_first()\n                    } else {\n                        group.split_last()\n                    };\n\n                    if let Some(((_, dest), src)) = split\n                        && let Some(pat_snippets) = group\n                            .iter()\n                            .map(|(_, arm)| arm.pat.span.get_source_text(cx))\n                            .collect::<Option<Vec<_>>>()\n                    {\n                        let suggs = src\n                            .iter()\n                            .map(|(_, arm)| (adjusted_arm_span(cx, arm.span), String::new()))\n                            .chain([(dest.pat.span, pat_snippets.iter().join(\" | \"))])\n                            .collect_vec();\n\n                        diag.multipart_suggestion(\n                            \"otherwise merge the patterns into a single arm\",\n                            suggs,\n                            Applicability::MaybeIncorrect,\n                        );\n                    }\n                }\n            },\n        );\n    }\n}\n\n/// Extend arm's span to include the comma and whitespaces after it.\nfn adjusted_arm_span(cx: &LateContext<'_>, span: Span) -> Span {\n    let source_map = cx.sess().source_map();\n    source_map\n        .span_extend_while(span, |c| c == ',' || c.is_ascii_whitespace())\n        .unwrap_or(span)\n}\n\n#[derive(Clone, Copy)]\nenum NormalizedPat<'a> {\n    Wild,\n    Never,\n    Struct(Option<DefId>, &'a [(Symbol, Self)]),\n    Tuple(Option<DefId>, &'a [Self]),\n    Or(&'a [Self]),\n    Path(Option<DefId>),\n    LitStr(Symbol),\n    LitBytes(ByteSymbol),\n    LitInt(u128),\n    LitBool(bool),\n    Range(PatRange),\n    /// A slice pattern. If the second value is `None`, then this matches an exact size. Otherwise\n    /// the first value contains everything before the `..` wildcard pattern, and the second value\n    /// contains everything afterwards. Note that either side, or both sides, may contain zero\n    /// patterns.\n    Slice(&'a [Self], Option<&'a [Self]>),\n    /// A placeholder for a pattern that wasn't well formed in some way.\n    Err(ErrorGuaranteed),\n}\n\n#[derive(Clone, Copy)]\nstruct PatRange {\n    start: u128,\n    end: u128,\n    bounds: RangeEnd,\n}\nimpl PatRange {\n    fn contains(&self, x: u128) -> bool {\n        x >= self.start\n            && match self.bounds {\n                RangeEnd::Included => x <= self.end,\n                RangeEnd::Excluded => x < self.end,\n            }\n    }\n\n    fn overlaps(&self, other: &Self) -> bool {\n        // Note: Empty ranges are impossible, so this is correct even though it would return true if an\n        // empty exclusive range were to reside within an inclusive range.\n        (match self.bounds {\n            RangeEnd::Included => self.end >= other.start,\n            RangeEnd::Excluded => self.end > other.start,\n        } && match other.bounds {\n            RangeEnd::Included => self.start <= other.end,\n            RangeEnd::Excluded => self.start < other.end,\n        })\n    }\n}\n\n/// Iterates over the pairs of fields with matching names.\nfn iter_matching_struct_fields<'a>(\n    left: &'a [(Symbol, NormalizedPat<'a>)],\n    right: &'a [(Symbol, NormalizedPat<'a>)],\n) -> impl Iterator<Item = (&'a NormalizedPat<'a>, &'a NormalizedPat<'a>)> + 'a {\n    struct Iter<'a>(\n        slice::Iter<'a, (Symbol, NormalizedPat<'a>)>,\n        slice::Iter<'a, (Symbol, NormalizedPat<'a>)>,\n    );\n    impl<'a> Iterator for Iter<'a> {\n        type Item = (&'a NormalizedPat<'a>, &'a NormalizedPat<'a>);\n        fn next(&mut self) -> Option<Self::Item> {\n            // Note: all the fields in each slice are sorted by symbol value.\n            let mut left = self.0.next()?;\n            let mut right = self.1.next()?;\n            loop {\n                match left.0.cmp(&right.0) {\n                    Ordering::Equal => return Some((&left.1, &right.1)),\n                    Ordering::Less => left = self.0.next()?,\n                    Ordering::Greater => right = self.1.next()?,\n                }\n            }\n        }\n    }\n    Iter(left.iter(), right.iter())\n}\n\n#[expect(clippy::similar_names, clippy::too_many_lines)]\nimpl<'a> NormalizedPat<'a> {\n    fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) -> Self {\n        match pat.kind {\n            PatKind::Missing => unreachable!(),\n            PatKind::Wild | PatKind::Binding(.., None) => Self::Wild,\n            PatKind::Binding(.., Some(pat))\n            | PatKind::Box(pat)\n            | PatKind::Deref(pat)\n            | PatKind::Ref(pat, _, _)\n            | PatKind::Guard(pat, _) => Self::from_pat(cx, arena, pat),\n            PatKind::Never => Self::Never,\n            PatKind::Struct(ref path, fields, _) => {\n                let fields =\n                    arena.alloc_from_iter(fields.iter().map(|f| (f.ident.name, Self::from_pat(cx, arena, f.pat))));\n                fields.sort_by_key(|&(name, _)| name);\n                Self::Struct(cx.qpath_res(path, pat.hir_id).opt_def_id(), fields)\n            },\n            PatKind::TupleStruct(ref path, pats, wild_idx) => {\n                let Some(adt) = cx.typeck_results().pat_ty(pat).ty_adt_def() else {\n                    return Self::Wild;\n                };\n                let (var_id, variant) = if adt.is_enum() {\n                    match cx.qpath_res(path, pat.hir_id).opt_def_id() {\n                        Some(x) => (Some(x), adt.variant_with_ctor_id(x)),\n                        None => return Self::Wild,\n                    }\n                } else {\n                    (None, adt.non_enum_variant())\n                };\n                let (front, back) = match wild_idx.as_opt_usize() {\n                    Some(i) => pats.split_at(i),\n                    None => (pats, [].as_slice()),\n                };\n                let pats = arena.alloc_from_iter(\n                    front\n                        .iter()\n                        .map(|pat| Self::from_pat(cx, arena, pat))\n                        .chain(iter::repeat_with(|| Self::Wild).take(variant.fields.len() - pats.len()))\n                        .chain(back.iter().map(|pat| Self::from_pat(cx, arena, pat))),\n                );\n                Self::Tuple(var_id, pats)\n            },\n            PatKind::Or(pats) => Self::Or(arena.alloc_from_iter(pats.iter().map(|pat| Self::from_pat(cx, arena, pat)))),\n            PatKind::Expr(PatExpr {\n                kind: PatExprKind::Path(path),\n                hir_id,\n                ..\n            }) => Self::Path(cx.qpath_res(path, *hir_id).opt_def_id()),\n            PatKind::Tuple(pats, wild_idx) => {\n                let field_count = match cx.typeck_results().pat_ty(pat).kind() {\n                    ty::Tuple(subs) => subs.len(),\n                    _ => return Self::Wild,\n                };\n                let (front, back) = match wild_idx.as_opt_usize() {\n                    Some(i) => pats.split_at(i),\n                    None => (pats, [].as_slice()),\n                };\n                let pats = arena.alloc_from_iter(\n                    front\n                        .iter()\n                        .map(|pat| Self::from_pat(cx, arena, pat))\n                        .chain(iter::repeat_with(|| Self::Wild).take(field_count - pats.len()))\n                        .chain(back.iter().map(|pat| Self::from_pat(cx, arena, pat))),\n                );\n                Self::Tuple(None, pats)\n            },\n            PatKind::Expr(e) => match &e.kind {\n                // TODO: Handle negative integers. They're currently treated as a wild match.\n                PatExprKind::Lit { lit, negated: false } => match lit.node {\n                    LitKind::Str(sym, _) => Self::LitStr(sym),\n                    LitKind::ByteStr(byte_sym, _) | LitKind::CStr(byte_sym, _) => Self::LitBytes(byte_sym),\n                    LitKind::Byte(val) => Self::LitInt(val.into()),\n                    LitKind::Char(val) => Self::LitInt(val.into()),\n                    LitKind::Int(val, _) => Self::LitInt(val.get()),\n                    LitKind::Bool(val) => Self::LitBool(val),\n                    LitKind::Float(..) => Self::Wild,\n                    LitKind::Err(guar) => Self::Err(guar),\n                },\n                _ => Self::Wild,\n            },\n            PatKind::Range(start, end, bounds) => {\n                // TODO: Handle negative integers. They're currently treated as a wild match.\n                let start = match start {\n                    None => 0,\n                    Some(e) => match &e.kind {\n                        PatExprKind::Lit { lit, negated: false } => match lit.node {\n                            LitKind::Int(val, _) => val.get(),\n                            LitKind::Char(val) => val.into(),\n                            LitKind::Byte(val) => val.into(),\n                            _ => return Self::Wild,\n                        },\n                        _ => return Self::Wild,\n                    },\n                };\n                let (end, bounds) = match end {\n                    None => (u128::MAX, RangeEnd::Included),\n                    Some(e) => match &e.kind {\n                        PatExprKind::Lit { lit, negated: false } => match lit.node {\n                            LitKind::Int(val, _) => (val.get(), bounds),\n                            LitKind::Char(val) => (val.into(), bounds),\n                            LitKind::Byte(val) => (val.into(), bounds),\n                            _ => return Self::Wild,\n                        },\n                        _ => return Self::Wild,\n                    },\n                };\n                Self::Range(PatRange { start, end, bounds })\n            },\n            PatKind::Slice(front, wild_pat, back) => Self::Slice(\n                arena.alloc_from_iter(front.iter().map(|pat| Self::from_pat(cx, arena, pat))),\n                wild_pat.map(|_| &*arena.alloc_from_iter(back.iter().map(|pat| Self::from_pat(cx, arena, pat)))),\n            ),\n            PatKind::Err(guar) => Self::Err(guar),\n        }\n    }\n\n    /// Checks if two patterns overlap in the values they can match assuming they are for the same\n    /// type.\n    fn has_overlapping_values(&self, other: &Self) -> bool {\n        match (*self, *other) {\n            (Self::Wild, _) | (_, Self::Wild) | (Self::Never, Self::Never) => true,\n            (Self::Or(pats), ref other) | (ref other, Self::Or(pats)) => {\n                pats.iter().any(|pat| pat.has_overlapping_values(other))\n            },\n            (Self::Struct(lpath, lfields), Self::Struct(rpath, rfields)) => {\n                if lpath != rpath {\n                    return false;\n                }\n                iter_matching_struct_fields(lfields, rfields).all(|(lpat, rpat)| lpat.has_overlapping_values(rpat))\n            },\n            (Self::Tuple(lpath, lpats), Self::Tuple(rpath, rpats)) => {\n                if lpath != rpath {\n                    return false;\n                }\n                iter::zip(lpats, rpats).all(|(lpat, rpat)| lpat.has_overlapping_values(rpat))\n            },\n            (Self::Path(x), Self::Path(y)) => x == y,\n            (Self::LitStr(x), Self::LitStr(y)) => x == y,\n            (Self::LitBytes(x), Self::LitBytes(y)) => x == y,\n            (Self::LitInt(x), Self::LitInt(y)) => x == y,\n            (Self::LitBool(x), Self::LitBool(y)) => x == y,\n            (Self::Range(ref x), Self::Range(ref y)) => x.overlaps(y),\n            (Self::Range(ref range), Self::LitInt(x)) | (Self::LitInt(x), Self::Range(ref range)) => range.contains(x),\n            (Self::Slice(lpats, None), Self::Slice(rpats, None)) => {\n                lpats.len() == rpats.len() && iter::zip(lpats, rpats).all(|(x, y)| x.has_overlapping_values(y))\n            },\n            (Self::Slice(pats, None), Self::Slice(front, Some(back)))\n            | (Self::Slice(front, Some(back)), Self::Slice(pats, None)) => {\n                // Here `pats` is an exact size match. If the combined lengths of `front` and `back` are greater\n                // then the minimum length required will be greater than the length of `pats`.\n                if pats.len() < front.len() + back.len() {\n                    return false;\n                }\n                iter::zip(&pats[..front.len()], front)\n                    .chain(iter::zip(&pats[pats.len() - back.len()..], back))\n                    .all(|(x, y)| x.has_overlapping_values(y))\n            },\n            (Self::Slice(lfront, Some(lback)), Self::Slice(rfront, Some(rback))) => iter::zip(lfront, rfront)\n                .chain(iter::zip(lback.iter().rev(), rback.iter().rev()))\n                .all(|(x, y)| x.has_overlapping_values(y)),\n\n            // Enums can mix unit variants with tuple/struct variants. These can never overlap.\n            (Self::Path(_), Self::Tuple(..) | Self::Struct(..))\n            | (Self::Tuple(..) | Self::Struct(..), Self::Path(_)) => false,\n\n            // Tuples can be matched like a struct.\n            (Self::Tuple(x, _), Self::Struct(y, _)) | (Self::Struct(x, _), Self::Tuple(y, _)) => {\n                // TODO: check fields here.\n                x == y\n            },\n\n            // TODO: Lit* with Path, Range with Path, LitBytes with Slice\n            _ => true,\n        }\n    }\n}\n\nfn pat_contains_local(pat: &Pat<'_>, id: HirId) -> bool {\n    let mut result = false;\n    pat.walk_short(|p| {\n        result |= matches!(p.kind, PatKind::Binding(_, binding_id, ..) if binding_id == id);\n        !result\n    });\n    result\n}\n\n/// Returns true if all the bindings in the `Pat` are in `ids` and vice versa\nfn bindings_eq(pat: &Pat<'_>, mut ids: HirIdSet) -> bool {\n    let mut result = true;\n    // FIXME(rust/#120456) - is `swap_remove` correct?\n    pat.each_binding_or_first(&mut |_, id, _, _| result &= ids.swap_remove(&id));\n    result && ids.is_empty()\n}\n\nfn is_wildcard_arm(pat: &Pat<'_>) -> bool {\n    match pat.kind {\n        PatKind::Wild => true,\n        PatKind::Or([.., last]) => matches!(last.kind, PatKind::Wild),\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_single_binding.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::macros::HirNode;\nuse clippy_utils::source::{indent_of, reindent_multiline, snippet, snippet_block_with_context, snippet_with_context};\nuse clippy_utils::{is_expr_identity_of_pat, is_refutable, peel_blocks};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_path, walk_stmt};\nuse rustc_hir::{Arm, Block, Expr, ExprKind, HirId, Item, ItemKind, Node, PatKind, Path, Stmt, StmtKind};\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, Symbol};\n\nuse super::MATCH_SINGLE_BINDING;\n\n#[derive(Debug)]\nenum AssignmentExpr {\n    Assign { span: Span, match_span: Span },\n    Local { span: Span, pat_span: Span },\n}\n\n#[expect(clippy::too_many_lines)]\npub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'a>) {\n    if expr.span.from_expansion() || arms.len() != 1 || is_refutable(cx, arms[0].pat) {\n        return;\n    }\n\n    let matched_vars = ex.span;\n    let bind_names = arms[0].pat.span;\n    let match_body = peel_blocks(arms[0].body);\n    let mut app = Applicability::MaybeIncorrect;\n    let ctxt = expr.span.ctxt();\n    let mut snippet_body = snippet_block_with_context(cx, match_body.span, ctxt, \"..\", Some(expr.span), &mut app).0;\n\n    // Do we need to add ';' to suggestion ?\n    if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id)\n        && let StmtKind::Expr(_) = stmt.kind\n        && match match_body.kind {\n            // We don't need to add a ; to blocks, unless that block is from a macro expansion\n            ExprKind::Block(block, _) => block.span.from_expansion(),\n            _ => true,\n        }\n    {\n        snippet_body.push(';');\n    }\n\n    match arms[0].pat.kind {\n        PatKind::Binding(..) | PatKind::Tuple(_, _) | PatKind::Struct(..) => {\n            let (target_span, sugg) = match opt_parent_assign_span(cx, ex) {\n                Some(AssignmentExpr::Assign { span, match_span }) => {\n                    let sugg = sugg_with_curlies(\n                        cx,\n                        (ex, expr),\n                        (bind_names, matched_vars),\n                        snippet_body,\n                        &mut app,\n                        Some(span),\n                        true,\n                        is_var_binding_used_later(cx, expr, &arms[0]),\n                    );\n\n                    span_lint_and_sugg(\n                        cx,\n                        MATCH_SINGLE_BINDING,\n                        span.to(match_span),\n                        \"this assignment could be simplified\",\n                        \"consider removing the `match` expression\",\n                        sugg,\n                        app,\n                    );\n\n                    return;\n                },\n                Some(AssignmentExpr::Local { span, pat_span }) => (\n                    span,\n                    format!(\n                        \"let {} = {};\\n{}let {} = {snippet_body};\",\n                        snippet_with_context(cx, bind_names, ctxt, \"..\", &mut app).0,\n                        snippet_with_context(cx, matched_vars, ctxt, \"..\", &mut app).0,\n                        \" \".repeat(indent_of(cx, expr.span).unwrap_or(0)),\n                        snippet_with_context(cx, pat_span, ctxt, \"..\", &mut app).0\n                    ),\n                ),\n                None if is_expr_identity_of_pat(cx, arms[0].pat, ex, false) => {\n                    span_lint_and_sugg(\n                        cx,\n                        MATCH_SINGLE_BINDING,\n                        expr.span,\n                        \"this match could be replaced by its body itself\",\n                        \"consider using the match body instead\",\n                        snippet_body,\n                        Applicability::MachineApplicable,\n                    );\n                    return;\n                },\n                None => {\n                    let sugg = sugg_with_curlies(\n                        cx,\n                        (ex, expr),\n                        (bind_names, matched_vars),\n                        snippet_body,\n                        &mut app,\n                        None,\n                        true,\n                        is_var_binding_used_later(cx, expr, &arms[0]),\n                    );\n                    (expr.span, sugg)\n                },\n            };\n\n            span_lint_and_sugg(\n                cx,\n                MATCH_SINGLE_BINDING,\n                target_span,\n                \"this match could be written as a `let` statement\",\n                \"consider using a `let` statement\",\n                sugg,\n                app,\n            );\n        },\n        PatKind::Wild => {\n            if ex.can_have_side_effects() {\n                let sugg = sugg_with_curlies(\n                    cx,\n                    (ex, expr),\n                    (bind_names, matched_vars),\n                    snippet_body,\n                    &mut app,\n                    None,\n                    false,\n                    true,\n                );\n\n                span_lint_and_sugg(\n                    cx,\n                    MATCH_SINGLE_BINDING,\n                    expr.span,\n                    \"this match could be replaced by its scrutinee and body\",\n                    \"consider using the scrutinee and body instead\",\n                    sugg,\n                    app,\n                );\n            } else {\n                span_lint_and_sugg(\n                    cx,\n                    MATCH_SINGLE_BINDING,\n                    expr.span,\n                    \"this match could be replaced by its body itself\",\n                    \"consider using the match body instead\",\n                    snippet_body,\n                    Applicability::MachineApplicable,\n                );\n            }\n        },\n        _ => (),\n    }\n}\n\nstruct VarBindingVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    identifiers: FxHashSet<Symbol>,\n}\n\nimpl<'tcx> Visitor<'tcx> for VarBindingVisitor<'_, 'tcx> {\n    type Result = ControlFlow<()>;\n\n    fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) -> Self::Result {\n        if let Res::Local(_) = path.res\n            && let [segment] = path.segments\n            && self.identifiers.contains(&segment.ident.name)\n        {\n            return ControlFlow::Break(());\n        }\n\n        walk_path(self, path)\n    }\n\n    fn visit_block(&mut self, block: &'tcx Block<'tcx>) -> Self::Result {\n        let before = self.identifiers.clone();\n        walk_block(self, block)?;\n        self.identifiers = before;\n        ControlFlow::Continue(())\n    }\n\n    fn visit_stmt(&mut self, stmt: &'tcx Stmt<'tcx>) -> Self::Result {\n        if let StmtKind::Let(let_stmt) = stmt.kind {\n            if let Some(init) = let_stmt.init {\n                self.visit_expr(init)?;\n            }\n\n            let_stmt.pat.each_binding(|_, _, _, ident| {\n                self.identifiers.remove(&ident.name);\n            });\n        }\n        walk_stmt(self, stmt)\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> Self::Result {\n        match expr.kind {\n            ExprKind::If(\n                Expr {\n                    kind: ExprKind::Let(let_expr),\n                    ..\n                },\n                then,\n                else_,\n            ) => {\n                self.visit_expr(let_expr.init)?;\n                let before = self.identifiers.clone();\n                let_expr.pat.each_binding(|_, _, _, ident| {\n                    self.identifiers.remove(&ident.name);\n                });\n\n                self.visit_expr(then)?;\n                self.identifiers = before;\n                if let Some(else_) = else_ {\n                    self.visit_expr(else_)?;\n                }\n                ControlFlow::Continue(())\n            },\n            ExprKind::Closure(closure) => {\n                let body = self.cx.tcx.hir_body(closure.body);\n                let before = self.identifiers.clone();\n                for param in body.params {\n                    param.pat.each_binding(|_, _, _, ident| {\n                        self.identifiers.remove(&ident.name);\n                    });\n                }\n                self.visit_expr(body.value)?;\n                self.identifiers = before;\n                ControlFlow::Continue(())\n            },\n            ExprKind::Match(expr, arms, _) => {\n                self.visit_expr(expr)?;\n                for arm in arms {\n                    let before = self.identifiers.clone();\n                    arm.pat.each_binding(|_, _, _, ident| {\n                        self.identifiers.remove(&ident.name);\n                    });\n                    if let Some(guard) = arm.guard {\n                        self.visit_expr(guard)?;\n                    }\n                    self.visit_expr(arm.body)?;\n                    self.identifiers = before;\n                }\n                ControlFlow::Continue(())\n            },\n            _ => walk_expr(self, expr),\n        }\n    }\n}\n\nfn is_var_binding_used_later(cx: &LateContext<'_>, expr: &Expr<'_>, arm: &Arm<'_>) -> bool {\n    let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id) else {\n        return false;\n    };\n    let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id) else {\n        return false;\n    };\n\n    let mut identifiers = FxHashSet::default();\n    arm.pat.each_binding(|_, _, _, ident| {\n        identifiers.insert(ident.name);\n    });\n\n    let mut visitor = VarBindingVisitor { cx, identifiers };\n    block\n        .stmts\n        .iter()\n        .skip_while(|s| s.hir_id != stmt.hir_id)\n        .skip(1)\n        .any(|stmt| matches!(visitor.visit_stmt(stmt), ControlFlow::Break(())))\n        || block\n            .expr\n            .is_some_and(|expr| matches!(visitor.visit_expr(expr), ControlFlow::Break(())))\n}\n\n/// Returns true if the `ex` match expression is in a local (`let`) or assign expression\nfn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<AssignmentExpr> {\n    if let Node::Expr(parent_arm_expr) = cx.tcx.parent_hir_node(ex.hir_id) {\n        return match cx.tcx.parent_hir_node(parent_arm_expr.hir_id) {\n            Node::LetStmt(parent_let_expr) => Some(AssignmentExpr::Local {\n                span: parent_let_expr.span,\n                pat_span: parent_let_expr.pat.span(),\n            }),\n            Node::Expr(Expr {\n                kind: ExprKind::Assign(parent_assign_expr, match_expr, _),\n                ..\n            }) => Some(AssignmentExpr::Assign {\n                span: parent_assign_expr.span,\n                match_span: match_expr.span,\n            }),\n            _ => None,\n        };\n    }\n\n    None\n}\n\nfn expr_in_nested_block(cx: &LateContext<'_>, match_expr: &Expr<'_>) -> bool {\n    if let Node::Block(block) = cx.tcx.parent_hir_node(match_expr.hir_id) {\n        return block\n            .expr\n            .map_or_else(|| matches!(block.stmts, [_]), |_| block.stmts.is_empty());\n    }\n    false\n}\n\nfn indent_of_nth_line(snippet: &str, nth: usize) -> Option<usize> {\n    snippet\n        .lines()\n        .nth(nth)\n        .and_then(|s| s.find(|c: char| !c.is_whitespace()))\n}\n\nfn reindent_snippet_if_in_block(snippet_body: &str, has_assignment: bool) -> String {\n    if has_assignment || !snippet_body.starts_with('{') {\n        return reindent_multiline(snippet_body, true, indent_of_nth_line(snippet_body, 1));\n    }\n\n    let snippet_body = snippet_body.trim_start_matches('{').trim_end_matches('}').trim();\n    reindent_multiline(\n        snippet_body,\n        false,\n        indent_of_nth_line(snippet_body, 0).map(|indent| indent.saturating_sub(4)),\n    )\n}\n\n#[expect(clippy::too_many_arguments)]\nfn sugg_with_curlies<'a>(\n    cx: &LateContext<'a>,\n    (ex, match_expr): (&Expr<'a>, &Expr<'a>),\n    (bind_names, matched_vars): (Span, Span),\n    mut snippet_body: String,\n    applicability: &mut Applicability,\n    assignment: Option<Span>,\n    needs_var_binding: bool,\n    is_var_binding_used_later: bool,\n) -> String {\n    let assignment_str = assignment.map_or_else(String::new, |span| {\n        let mut s = snippet(cx, span, \"..\").to_string();\n        s.push_str(\" = \");\n        s\n    });\n\n    let ctxt = match_expr.span.ctxt();\n    let scrutinee = if needs_var_binding {\n        format!(\n            \"let {} = {}\",\n            snippet_with_context(cx, bind_names, ctxt, \"..\", applicability).0,\n            snippet_with_context(cx, matched_vars, ctxt, \"..\", applicability).0\n        )\n    } else {\n        snippet_with_context(cx, matched_vars, ctxt, \"..\", applicability)\n            .0\n            .to_string()\n    };\n\n    let mut indent = \" \".repeat(indent_of(cx, ex.span).unwrap_or(0));\n    let (mut cbrace_start, mut cbrace_end) = (String::new(), String::new());\n    let mut add_curlies = || {\n        cbrace_end = format!(\"\\n{indent}}}\");\n        // Fix body indent due to the closure\n        indent = \" \".repeat(indent_of(cx, bind_names).unwrap_or(0));\n        cbrace_start = format!(\"{{\\n{indent}\");\n        snippet_body = reindent_snippet_if_in_block(&snippet_body, !assignment_str.is_empty());\n    };\n\n    if !expr_in_nested_block(cx, match_expr) {\n        let mut parent = cx.tcx.parent_hir_node(match_expr.hir_id);\n        if let Node::Expr(Expr {\n            kind: ExprKind::Assign(..),\n            hir_id,\n            ..\n        }) = parent\n        {\n            parent = cx.tcx.parent_hir_node(*hir_id);\n        }\n        if let Node::Stmt(stmt) = parent {\n            parent = cx.tcx.parent_hir_node(stmt.hir_id);\n        }\n\n        match parent {\n            Node::Block(..)\n            | Node::Expr(Expr {\n                kind: ExprKind::Block(..) | ExprKind::ConstBlock(..),\n                ..\n            }) if needs_var_binding && is_var_binding_used_later => {\n                add_curlies();\n            },\n            Node::Expr(..)\n            | Node::AnonConst(..)\n            | Node::Item(Item {\n                kind: ItemKind::Const(..),\n                ..\n            }) => add_curlies(),\n            Node::Arm(arm) if let ExprKind::Match(..) = arm.body.kind => add_curlies(),\n            _ => {},\n        }\n    }\n\n    format!(\"{cbrace_start}{scrutinee};\\n{indent}{assignment_str}{snippet_body}{cbrace_end}\")\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_str_case_mismatch.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{Arm, Expr, ExprKind, LangItem, PatExpr, PatExprKind, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::Span;\nuse rustc_span::symbol::Symbol;\n\nuse super::MATCH_STR_CASE_MISMATCH;\n\n#[derive(Debug)]\nenum CaseMethod {\n    LowerCase,\n    AsciiLowerCase,\n    UpperCase,\n    AsciiUppercase,\n}\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) {\n    if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty(scrutinee).kind()\n        && let ty::Str = ty.kind()\n    {\n        let mut visitor = MatchExprVisitor { cx };\n        if let ControlFlow::Break(case_method) = visitor.visit_expr(scrutinee)\n            && let Some((bad_case_span, bad_case_sym)) = verify_case(&case_method, arms)\n        {\n            lint(cx, &case_method, bad_case_span, bad_case_sym.as_str());\n        }\n    }\n}\n\nstruct MatchExprVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n}\n\nimpl<'tcx> Visitor<'tcx> for MatchExprVisitor<'_, 'tcx> {\n    type Result = ControlFlow<CaseMethod>;\n    fn visit_expr(&mut self, ex: &'tcx Expr<'_>) -> Self::Result {\n        if let ExprKind::MethodCall(segment, receiver, [], _) = ex.kind {\n            let result = self.case_altered(segment.ident.name, receiver);\n            if result.is_break() {\n                return result;\n            }\n        }\n\n        walk_expr(self, ex)\n    }\n}\n\nimpl MatchExprVisitor<'_, '_> {\n    fn case_altered(&self, segment_ident: Symbol, receiver: &Expr<'_>) -> ControlFlow<CaseMethod> {\n        if let Some(case_method) = get_case_method(segment_ident) {\n            let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();\n\n            if ty.is_lang_item(self.cx, LangItem::String) || ty.kind() == &ty::Str {\n                return ControlFlow::Break(case_method);\n            }\n        }\n\n        ControlFlow::Continue(())\n    }\n}\n\nfn get_case_method(segment_ident: Symbol) -> Option<CaseMethod> {\n    match segment_ident {\n        sym::to_lowercase => Some(CaseMethod::LowerCase),\n        sym::to_ascii_lowercase => Some(CaseMethod::AsciiLowerCase),\n        sym::to_uppercase => Some(CaseMethod::UpperCase),\n        sym::to_ascii_uppercase => Some(CaseMethod::AsciiUppercase),\n        _ => None,\n    }\n}\n\nfn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(Span, Symbol)> {\n    let case_check = match case_method {\n        CaseMethod::LowerCase => |input: &str| -> bool { input.chars().all(|c| c.to_lowercase().next() == Some(c)) },\n        CaseMethod::AsciiLowerCase => |input: &str| -> bool { !input.chars().any(|c| c.is_ascii_uppercase()) },\n        CaseMethod::UpperCase => |input: &str| -> bool { input.chars().all(|c| c.to_uppercase().next() == Some(c)) },\n        CaseMethod::AsciiUppercase => |input: &str| -> bool { !input.chars().any(|c| c.is_ascii_lowercase()) },\n    };\n\n    for arm in arms {\n        if let PatKind::Expr(PatExpr {\n            kind: PatExprKind::Lit { lit, negated: false },\n            ..\n        }) = arm.pat.kind\n            && let LitKind::Str(symbol, _) = lit.node\n            && let input = symbol.as_str()\n            && !case_check(input)\n        {\n            return Some((lit.span, symbol));\n        }\n    }\n\n    None\n}\n\nfn lint(cx: &LateContext<'_>, case_method: &CaseMethod, bad_case_span: Span, bad_case_str: &str) {\n    let (method_str, suggestion) = match case_method {\n        CaseMethod::LowerCase => (\"to_lowercase\", bad_case_str.to_lowercase()),\n        CaseMethod::AsciiLowerCase => (\"to_ascii_lowercase\", bad_case_str.to_ascii_lowercase()),\n        CaseMethod::UpperCase => (\"to_uppercase\", bad_case_str.to_uppercase()),\n        CaseMethod::AsciiUppercase => (\"to_ascii_uppercase\", bad_case_str.to_ascii_uppercase()),\n    };\n\n    span_lint_and_sugg(\n        cx,\n        MATCH_STR_CASE_MISMATCH,\n        bad_case_span,\n        \"this `match` arm has a differing case than its expression\",\n        format!(\"consider changing the case of this arm to respect `{method_str}`\"),\n        format!(\"\\\"{suggestion}\\\"\"),\n        Applicability::MachineApplicable,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_wild_enum.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{is_refutable, peel_hir_pat_refs, recurse_or_patterns};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{CtorKind, DefKind, Res};\nuse rustc_hir::{Arm, Expr, PatExpr, PatExprKind, PatKind, PathSegment, QPath, Ty, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, VariantDef};\nuse rustc_span::sym;\n\nuse super::{MATCH_WILDCARD_FOR_SINGLE_VARIANTS, WILDCARD_ENUM_MATCH_ARM};\n\n#[expect(clippy::too_many_lines)]\npub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {\n    let ty = cx.typeck_results().expr_ty(ex).peel_refs();\n    let adt_def = match ty.kind() {\n        ty::Adt(adt_def, _)\n            if adt_def.is_enum() && !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) =>\n        {\n            adt_def\n        },\n        _ => return,\n    };\n\n    // First pass - check for violation, but don't do much book-keeping because this is hopefully\n    // the uncommon case, and the book-keeping is slightly expensive.\n    let mut wildcard_span = None;\n    let mut wildcard_ident = None;\n    let mut has_non_wild = false;\n    for arm in arms {\n        match peel_hir_pat_refs(arm.pat).0.kind {\n            PatKind::Wild if arm.guard.is_none() => wildcard_span = Some(arm.pat.span),\n            PatKind::Binding(_, _, ident, None) => {\n                wildcard_span = Some(arm.pat.span);\n                wildcard_ident = Some(ident);\n            },\n            _ => has_non_wild = true,\n        }\n    }\n    let wildcard_span = match wildcard_span {\n        Some(x) if has_non_wild => x,\n        _ => return,\n    };\n\n    // Accumulate the variants which should be put in place of the wildcard because they're not\n    // already covered.\n    let is_external = adt_def.did().as_local().is_none();\n    let has_external_hidden = is_external && adt_def.variants().iter().any(|x| is_hidden(cx, x));\n    let mut missing_variants: Vec<_> = adt_def\n        .variants()\n        .iter()\n        .filter(|x| !(is_external && is_hidden(cx, x)))\n        .collect();\n\n    let mut path_prefix = CommonPrefixSearcher::None;\n    for arm in arms {\n        // Guards mean that this case probably isn't exhaustively covered. Technically\n        // this is incorrect, as we should really check whether each variant is exhaustively\n        // covered by the set of guards that cover it, but that's really hard to do.\n        recurse_or_patterns(arm.pat, |pat| {\n            let path = match &peel_hir_pat_refs(pat).0.kind {\n                PatKind::Expr(PatExpr {\n                    hir_id,\n                    kind: PatExprKind::Path(path),\n                    ..\n                }) => {\n                    // FIXME(clippy): don't you want to use the hir id of the peeled pat?\n                    let id = match cx.qpath_res(path, *hir_id) {\n                        Res::Def(\n                            DefKind::Const { .. } | DefKind::ConstParam | DefKind::AnonConst | DefKind::InlineConst,\n                            _,\n                        ) => return,\n                        Res::Def(_, id) => id,\n                        _ => return,\n                    };\n                    if arm.guard.is_none() {\n                        missing_variants.retain(|e| e.ctor_def_id() != Some(id));\n                    }\n                    path\n                },\n                PatKind::TupleStruct(path, patterns, ..) => {\n                    if let Some(id) = cx.qpath_res(path, pat.hir_id).opt_def_id()\n                        && arm.guard.is_none()\n                        && patterns.iter().all(|p| !is_refutable(cx, p))\n                    {\n                        missing_variants.retain(|e| e.ctor_def_id() != Some(id));\n                    }\n                    path\n                },\n                PatKind::Struct(path, patterns, ..) => {\n                    if let Some(id) = cx.qpath_res(path, pat.hir_id).opt_def_id()\n                        && arm.guard.is_none()\n                        && patterns.iter().all(|p| !is_refutable(cx, p.pat))\n                    {\n                        missing_variants.retain(|e| e.def_id != id);\n                    }\n                    path\n                },\n                _ => return,\n            };\n            match path {\n                QPath::Resolved(_, path) => path_prefix.with_path(path.segments),\n                QPath::TypeRelative(\n                    Ty {\n                        kind: TyKind::Path(QPath::Resolved(_, path)),\n                        ..\n                    },\n                    _,\n                ) => path_prefix.with_prefix(path.segments),\n                QPath::TypeRelative(..) => (),\n            }\n        });\n    }\n\n    let format_suggestion = |variant: &VariantDef| {\n        format!(\n            \"{}{}{}{}\",\n            wildcard_ident.map_or(String::new(), |ident| {\n                ident\n                    .span\n                    .get_source_text(cx)\n                    .map_or_else(|| format!(\"{} @ \", ident.name), |s| format!(\"{s} @ \"))\n            }),\n            if let CommonPrefixSearcher::Path(path_prefix) = path_prefix {\n                let mut s = String::new();\n                for seg in path_prefix {\n                    s.push_str(seg.ident.as_str());\n                    s.push_str(\"::\");\n                }\n                s\n            } else {\n                let mut s = cx.tcx.def_path_str(adt_def.did());\n                s.push_str(\"::\");\n                s\n            },\n            variant.name,\n            match variant.ctor_kind() {\n                Some(CtorKind::Fn) if variant.fields.len() == 1 => \"(_)\",\n                Some(CtorKind::Fn) => \"(..)\",\n                Some(CtorKind::Const) => \"\",\n                None => \" { .. }\",\n            }\n        )\n    };\n\n    match missing_variants.as_slice() {\n        [] => (),\n        [x] if !adt_def.is_variant_list_non_exhaustive() && !has_external_hidden => span_lint_and_sugg(\n            cx,\n            MATCH_WILDCARD_FOR_SINGLE_VARIANTS,\n            wildcard_span,\n            \"wildcard matches only a single variant and will also match any future added variants\",\n            \"try\",\n            format_suggestion(x),\n            Applicability::MaybeIncorrect,\n        ),\n        variants => {\n            let (message, add_wildcard) = if adt_def.is_variant_list_non_exhaustive() || has_external_hidden {\n                (\n                    \"wildcard matches known variants and will also match future added variants\",\n                    true,\n                )\n            } else {\n                (\"wildcard match will also match any future added variants\", false)\n            };\n\n            span_lint_and_then(cx, WILDCARD_ENUM_MATCH_ARM, wildcard_span, message, |diag| {\n                let mut suggestions: Vec<_> = variants.iter().copied().map(format_suggestion).collect();\n                if add_wildcard {\n                    suggestions.push(\"_\".into());\n                }\n                diag.span_suggestion(\n                    wildcard_span,\n                    \"try\",\n                    suggestions.join(\" | \"),\n                    Applicability::MaybeIncorrect,\n                );\n            });\n        },\n    }\n}\n\nenum CommonPrefixSearcher<'a> {\n    None,\n    Path(&'a [PathSegment<'a>]),\n    Mixed,\n}\nimpl<'a> CommonPrefixSearcher<'a> {\n    fn with_path(&mut self, path: &'a [PathSegment<'a>]) {\n        if let [path @ .., _] = path {\n            self.with_prefix(path);\n        }\n    }\n\n    fn with_prefix(&mut self, path: &'a [PathSegment<'a>]) {\n        match self {\n            Self::None => *self = Self::Path(path),\n            Self::Path(self_path)\n                if path\n                    .iter()\n                    .map(|p| p.ident.name)\n                    .eq(self_path.iter().map(|p| p.ident.name)) => {},\n            Self::Path(_) => *self = Self::Mixed,\n            Self::Mixed => (),\n        }\n    }\n}\n\nfn is_hidden(cx: &LateContext<'_>, variant_def: &VariantDef) -> bool {\n    cx.tcx.is_doc_hidden(variant_def.def_id)\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/match_wild_err_arm.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_note;\nuse clippy_utils::macros::{is_panic, root_macro_call};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::visitors::is_local_used;\nuse clippy_utils::{is_in_const_context, is_wild, peel_blocks_with_stmt};\nuse rustc_hir::{Arm, Expr, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::{kw, sym};\n\nuse super::MATCH_WILD_ERR_ARM;\n\npub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<'tcx>]) {\n    // `unwrap`/`expect` is not (yet) const, so we want to allow this in const contexts for now\n    if is_in_const_context(cx) {\n        return;\n    }\n\n    let ex_ty = cx.typeck_results().expr_ty(ex).peel_refs();\n    if ex_ty.is_diag_item(cx, sym::Result) {\n        for arm in arms {\n            if let PatKind::TupleStruct(ref path, inner, _) = arm.pat.kind {\n                let path_str = rustc_hir_pretty::qpath_to_string(&cx.tcx, path);\n                if path_str == \"Err\" {\n                    let mut matching_wild = inner.iter().any(is_wild);\n                    let mut ident_bind_name = kw::Underscore;\n                    if !matching_wild {\n                        // Looking for unused bindings (i.e.: `_e`)\n                        for pat in inner {\n                            if let PatKind::Binding(_, id, ident, None) = pat.kind\n                                && ident.as_str().starts_with('_')\n                                && !is_local_used(cx, arm.body, id)\n                            {\n                                ident_bind_name = ident.name;\n                                matching_wild = true;\n                            }\n                        }\n                    }\n                    if matching_wild\n                        && let Some(macro_call) = root_macro_call(peel_blocks_with_stmt(arm.body).span)\n                        && is_panic(cx, macro_call.def_id)\n                    {\n                        // `Err(_)` or `Err(_e)` arm with `panic!` found\n                        span_lint_and_note(\n                            cx,\n                            MATCH_WILD_ERR_ARM,\n                            arm.pat.span,\n                            format!(\"`Err({ident_bind_name})` matches all errors\"),\n                            None,\n                            \"match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable\",\n                        );\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/mod.rs",
    "content": "mod collapsible_match;\nmod infallible_destructuring_match;\nmod manual_filter;\nmod manual_map;\nmod manual_ok_err;\nmod manual_unwrap_or;\nmod manual_utils;\nmod match_as_ref;\nmod match_bool;\nmod match_like_matches;\nmod match_ref_pats;\nmod match_same_arms;\nmod match_single_binding;\nmod match_str_case_mismatch;\nmod match_wild_enum;\nmod match_wild_err_arm;\nmod needless_match;\nmod overlapping_arms;\nmod redundant_guards;\nmod redundant_pattern_match;\nmod rest_pat_in_fully_bound_struct;\nmod significant_drop_in_scrutinee;\nmod single_match;\nmod try_err;\nmod wild_in_or_pats;\n\nuse clippy_config::Conf;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::walk_span_to_context;\nuse clippy_utils::{\n    higher, is_direct_expn_of, is_in_const_context, is_span_match, span_contains_cfg, span_extract_comments, sym,\n};\nuse rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{SpanData, SyntaxContext};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds nested `match` or `if let` expressions where the patterns may be \"collapsed\" together\n    /// without adding any branches.\n    ///\n    /// Note that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only\n    /// cases where merging would most likely make the code more readable.\n    ///\n    /// ### Why is this bad?\n    /// It is unnecessarily verbose and complex.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn func(opt: Option<Result<u64, String>>) {\n    ///     let n = match opt {\n    ///         Some(n) => match n {\n    ///             Ok(n) => n,\n    ///             _ => return,\n    ///         }\n    ///         None => return,\n    ///     };\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn func(opt: Option<Result<u64, String>>) {\n    ///     let n = match opt {\n    ///         Some(Ok(n)) => n,\n    ///         _ => return,\n    ///     };\n    /// }\n    /// ```\n    #[clippy::version = \"1.50.0\"]\n    pub COLLAPSIBLE_MATCH,\n    style,\n    \"Nested `match` or `if let` expressions where the patterns may be \\\"collapsed\\\" together.\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for matches being used to destructure a single-variant enum\n    /// or tuple struct where a `let` will suffice.\n    ///\n    /// ### Why is this bad?\n    /// Just readability – `let` doesn't nest, whereas a `match` does.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum Wrapper {\n    ///     Data(i32),\n    /// }\n    ///\n    /// let wrapper = Wrapper::Data(42);\n    ///\n    /// let data = match wrapper {\n    ///     Wrapper::Data(i) => i,\n    /// };\n    /// ```\n    ///\n    /// The correct use would be:\n    /// ```no_run\n    /// enum Wrapper {\n    ///     Data(i32),\n    /// }\n    ///\n    /// let wrapper = Wrapper::Data(42);\n    /// let Wrapper::Data(data) = wrapper;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INFALLIBLE_DESTRUCTURING_MATCH,\n    style,\n    \"a `match` statement with a single infallible arm instead of a `let`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `match` which could be implemented using `filter`\n    ///\n    /// ### Why is this bad?\n    /// Using the `filter` method is clearer and more concise.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// match Some(0) {\n    ///     Some(x) => if x % 2 == 0 {\n    ///                     Some(x)\n    ///                } else {\n    ///                     None\n    ///                 },\n    ///     None => None,\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// Some(0).filter(|&x| x % 2 == 0);\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub MANUAL_FILTER,\n    complexity,\n    \"reimplementation of `filter`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `match` which could be implemented using `map`\n    ///\n    /// ### Why is this bad?\n    /// Using the `map` method is clearer and more concise.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// match Some(0) {\n    ///     Some(x) => Some(x + 1),\n    ///     None => None,\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// Some(0).map(|x| x + 1);\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub MANUAL_MAP,\n    style,\n    \"reimplementation of `map`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual implementation of `.ok()` or `.err()`\n    /// on `Result` values.\n    ///\n    /// ### Why is this bad?\n    /// Using `.ok()` or `.err()` rather than a `match` or\n    /// `if let` is less complex and more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn func() -> Result<u32, &'static str> { Ok(0) }\n    /// let a = match func() {\n    ///     Ok(v) => Some(v),\n    ///     Err(_) => None,\n    /// };\n    /// let b = if let Err(v) = func() {\n    ///     Some(v)\n    /// } else {\n    ///     None\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # fn func() -> Result<u32, &'static str> { Ok(0) }\n    /// let a = func().ok();\n    /// let b = func().err();\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub MANUAL_OK_ERR,\n    complexity,\n    \"find manual implementations of `.ok()` or `.err()` on `Result`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`.\n    ///\n    /// ### Why is this bad?\n    /// Concise code helps focusing on behavior instead of boilerplate.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let foo: Option<i32> = None;\n    /// match foo {\n    ///     Some(v) => v,\n    ///     None => 1,\n    /// };\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let foo: Option<i32> = None;\n    /// foo.unwrap_or(1);\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub MANUAL_UNWRAP_OR,\n    complexity,\n    \"finds patterns that can be encoded more concisely with `Option::unwrap_or` or `Result::unwrap_or`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if a `match` or `if let` expression can be simplified using\n    /// `.unwrap_or_default()`.\n    ///\n    /// ### Why is this bad?\n    /// It can be done in one call with `.unwrap_or_default()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: Option<String> = Some(String::new());\n    /// let y: String = match x {\n    ///     Some(v) => v,\n    ///     None => String::new(),\n    /// };\n    ///\n    /// let x: Option<Vec<String>> = Some(Vec::new());\n    /// let y: Vec<String> = if let Some(v) = x {\n    ///     v\n    /// } else {\n    ///     Vec::new()\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x: Option<String> = Some(String::new());\n    /// let y: String = x.unwrap_or_default();\n    ///\n    /// let x: Option<Vec<String>> = Some(Vec::new());\n    /// let y: Vec<String> = x.unwrap_or_default();\n    /// ```\n    #[clippy::version = \"1.79.0\"]\n    pub MANUAL_UNWRAP_OR_DEFAULT,\n    suspicious,\n    \"check if a `match` or `if let` can be simplified with `unwrap_or_default`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for match which is used to add a reference to an\n    /// `Option` value.\n    ///\n    /// ### Why is this bad?\n    /// Using `as_ref()` or `as_mut()` instead is shorter.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: Option<()> = None;\n    ///\n    /// let r: Option<&()> = match x {\n    ///     None => None,\n    ///     Some(ref v) => Some(v),\n    /// };\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let x: Option<()> = None;\n    ///\n    /// let r: Option<&()> = x.as_ref();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MATCH_AS_REF,\n    complexity,\n    \"a `match` on an Option value instead of using `as_ref()` or `as_mut`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for matches where match expression is a `bool`. It\n    /// suggests to replace the expression with an `if...else` block.\n    ///\n    /// ### Why is this bad?\n    /// It makes the code less readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn foo() {}\n    /// # fn bar() {}\n    /// let condition: bool = true;\n    /// match condition {\n    ///     true => foo(),\n    ///     false => bar(),\n    /// }\n    /// ```\n    /// Use if/else instead:\n    /// ```no_run\n    /// # fn foo() {}\n    /// # fn bar() {}\n    /// let condition: bool = true;\n    /// if condition {\n    ///     foo();\n    /// } else {\n    ///     bar();\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MATCH_BOOL,\n    pedantic,\n    \"a `match` on a boolean expression instead of an `if..else` block\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `match`  or `if let` expressions producing a\n    /// `bool` that could be written using `matches!`\n    ///\n    /// ### Why is this bad?\n    /// Readability and needless complexity.\n    ///\n    /// ### Known problems\n    /// This lint falsely triggers, if there are arms with\n    /// `cfg` attributes that remove an arm evaluating to `false`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = Some(5);\n    ///\n    /// let a = match x {\n    ///     Some(0) => true,\n    ///     _ => false,\n    /// };\n    ///\n    /// let a = if let Some(0) = x {\n    ///     true\n    /// } else {\n    ///     false\n    /// };\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let x = Some(5);\n    /// let a = matches!(x, Some(0));\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub MATCH_LIKE_MATCHES_MACRO,\n    style,\n    \"a match that could be written with the matches! macro\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for overlapping match arms.\n    ///\n    /// ### Why is this bad?\n    /// It is likely to be an error and if not, makes the code\n    /// less obvious.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 5;\n    /// match x {\n    ///     1..=10 => println!(\"1 ... 10\"),\n    ///     5..=15 => println!(\"5 ... 15\"),\n    ///     _ => (),\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MATCH_OVERLAPPING_ARM,\n    style,\n    \"a `match` with overlapping arms\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for matches where all arms match a reference,\n    /// suggesting to remove the reference and deref the matched expression\n    /// instead. It also checks for `if let &foo = bar` blocks.\n    ///\n    /// ### Why is this bad?\n    /// It just makes the code less readable. That reference\n    /// destructuring adds nothing to the code.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// match x {\n    ///     &A(ref y) => foo(y),\n    ///     &B => bar(),\n    ///     _ => frob(&x),\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// match *x {\n    ///     A(ref y) => foo(y),\n    ///     B => bar(),\n    ///     _ => frob(x),\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MATCH_REF_PATS,\n    style,\n    \"a `match` or `if let` with all arms prefixed with `&` instead of deref-ing the match expression\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `match` with identical arm bodies.\n    ///\n    /// Note: Does not lint on wildcards if the `non_exhaustive_omitted_patterns_lint` feature is\n    /// enabled and disallowed.\n    ///\n    /// ### Why is this bad?\n    /// This is probably a copy & paste error. If arm bodies\n    /// are the same on purpose, you can factor them\n    /// [using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// match foo {\n    ///     Bar => bar(),\n    ///     Quz => quz(),\n    ///     Baz => bar(), // <= oops\n    /// }\n    /// ```\n    ///\n    /// This should probably be\n    /// ```rust,ignore\n    /// match foo {\n    ///     Bar => bar(),\n    ///     Quz => quz(),\n    ///     Baz => baz(), // <= fixed\n    /// }\n    /// ```\n    ///\n    /// or if the original code was not a typo:\n    /// ```rust,ignore\n    /// match foo {\n    ///     Bar | Baz => bar(), // <= shows the intent better\n    ///     Quz => quz(),\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MATCH_SAME_ARMS,\n    pedantic,\n    \"`match` with identical arm bodies\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for useless match that binds to only one value.\n    ///\n    /// ### Why is this bad?\n    /// Readability and needless complexity.\n    ///\n    /// ### Known problems\n    ///  Suggested replacements may be incorrect when `match`\n    /// is actually binding temporary value, bringing a 'dropped while borrowed' error.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let a = 1;\n    /// # let b = 2;\n    /// match (a, b) {\n    ///     (c, d) => {\n    ///         // useless match\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let a = 1;\n    /// # let b = 2;\n    /// let (c, d) = (a, b);\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub MATCH_SINGLE_BINDING,\n    complexity,\n    \"a match with a single binding instead of using `let` statement\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `match` expressions modifying the case of a string with non-compliant arms\n    ///\n    /// ### Why is this bad?\n    /// The arm is unreachable, which is likely a mistake\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let text = \"Foo\";\n    /// match &*text.to_ascii_lowercase() {\n    ///     \"foo\" => {},\n    ///     \"Bar\" => {},\n    ///     _ => {},\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let text = \"Foo\";\n    /// match &*text.to_ascii_lowercase() {\n    ///     \"foo\" => {},\n    ///     \"bar\" => {},\n    ///     _ => {},\n    /// }\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub MATCH_STR_CASE_MISMATCH,\n    correctness,\n    \"creation of a case altering match expression with non-compliant arms\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for arm which matches all errors with `Err(_)`\n    /// and take drastic actions like `panic!`.\n    ///\n    /// ### Why is this bad?\n    /// It is generally a bad practice, similar to\n    /// catching all exceptions in java with `catch(Exception)`\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: Result<i32, &str> = Ok(3);\n    /// match x {\n    ///     Ok(_) => println!(\"ok\"),\n    ///     Err(_) => panic!(\"err\"),\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MATCH_WILD_ERR_ARM,\n    pedantic,\n    \"a `match` with `Err(_)` arm and take drastic actions\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for wildcard enum matches for a single variant.\n    ///\n    /// ### Why is this bad?\n    /// New enum variants added by library updates can be missed.\n    ///\n    /// ### Known problems\n    /// Suggested replacements may not use correct path to enum\n    /// if it's not present in the current scope.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # enum Foo { A, B, C }\n    /// # let x = Foo::B;\n    /// match x {\n    ///     Foo::A => {},\n    ///     Foo::B => {},\n    ///     _ => {},\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # enum Foo { A, B, C }\n    /// # let x = Foo::B;\n    /// match x {\n    ///     Foo::A => {},\n    ///     Foo::B => {},\n    ///     Foo::C => {},\n    /// }\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub MATCH_WILDCARD_FOR_SINGLE_VARIANTS,\n    pedantic,\n    \"a wildcard enum match for a single variant\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary `match` or match-like `if let` returns for `Option` and `Result`\n    /// when function signatures are the same.\n    ///\n    /// ### Why is this bad?\n    /// This `match` block does nothing and might not be what the coder intended.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// fn foo() -> Result<(), i32> {\n    ///     match result {\n    ///         Ok(val) => Ok(val),\n    ///         Err(err) => Err(err),\n    ///     }\n    /// }\n    ///\n    /// fn bar() -> Option<i32> {\n    ///     if let Some(val) = option {\n    ///         Some(val)\n    ///     } else {\n    ///         None\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Could be replaced as\n    ///\n    /// ```rust,ignore\n    /// fn foo() -> Result<(), i32> {\n    ///     result\n    /// }\n    ///\n    /// fn bar() -> Option<i32> {\n    ///     option\n    /// }\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub NEEDLESS_MATCH,\n    complexity,\n    \"`match` or match-like `if let` that are unnecessary\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary guards in match expressions.\n    ///\n    /// ### Why is this bad?\n    /// It's more complex and much less readable. Making it part of the pattern can improve\n    /// exhaustiveness checking as well.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// match x {\n    ///     Some(x) if matches!(x, Some(1)) => ..,\n    ///     Some(x) if x == Some(2) => ..,\n    ///     _ => todo!(),\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// match x {\n    ///     Some(Some(1)) => ..,\n    ///     Some(Some(2)) => ..,\n    ///     _ => todo!(),\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub REDUNDANT_GUARDS,\n    complexity,\n    \"checks for unnecessary guards in match expressions\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lint for redundant pattern matching over `Result`, `Option`,\n    /// `std::task::Poll`, `std::net::IpAddr` or `bool`s\n    ///\n    /// ### Why is this bad?\n    /// It's more concise and clear to just use the proper\n    /// utility function or using the condition directly\n    ///\n    /// ### Known problems\n    /// For suggestions involving bindings in patterns, this will change the drop order for the matched type.\n    /// Both `if let` and `while let` will drop the value at the end of the block, both `if` and `while` will drop the\n    /// value before entering the block. For most types this change will not matter, but for a few\n    /// types this will not be an acceptable change (e.g. locks). See the\n    /// [reference](https://doc.rust-lang.org/reference/destructors.html#drop-scopes) for more about\n    /// drop order.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::task::Poll;\n    /// # use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};\n    /// if let Ok(_) = Ok::<i32, i32>(42) {}\n    /// if let Err(_) = Err::<i32, i32>(42) {}\n    /// if let None = None::<()> {}\n    /// if let Some(_) = Some(42) {}\n    /// if let Poll::Pending = Poll::Pending::<()> {}\n    /// if let Poll::Ready(_) = Poll::Ready(42) {}\n    /// if let IpAddr::V4(_) = IpAddr::V4(Ipv4Addr::LOCALHOST) {}\n    /// if let IpAddr::V6(_) = IpAddr::V6(Ipv6Addr::LOCALHOST) {}\n    /// match Ok::<i32, i32>(42) {\n    ///     Ok(_) => true,\n    ///     Err(_) => false,\n    /// };\n    ///\n    /// let cond = true;\n    /// if let true = cond {}\n    /// matches!(cond, true);\n    /// ```\n    ///\n    /// The more idiomatic use would be:\n    ///\n    /// ```no_run\n    /// # use std::task::Poll;\n    /// # use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};\n    /// if Ok::<i32, i32>(42).is_ok() {}\n    /// if Err::<i32, i32>(42).is_err() {}\n    /// if None::<()>.is_none() {}\n    /// if Some(42).is_some() {}\n    /// if Poll::Pending::<()>.is_pending() {}\n    /// if Poll::Ready(42).is_ready() {}\n    /// if IpAddr::V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\n    /// if IpAddr::V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\n    /// Ok::<i32, i32>(42).is_ok();\n    ///\n    /// let cond = true;\n    /// if cond {}\n    /// cond;\n    /// ```\n    #[clippy::version = \"1.31.0\"]\n    pub REDUNDANT_PATTERN_MATCHING,\n    style,\n    \"use the proper utility function avoiding an `if let`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched.\n    ///\n    /// ### Why restrict this?\n    /// Correctness and readability. It's like having a wildcard pattern after\n    /// matching all enum variants explicitly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct A { a: i32 }\n    /// let a = A { a: 5 };\n    ///\n    /// match a {\n    ///     A { a: 5, .. } => {},\n    ///     _ => {},\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # struct A { a: i32 }\n    /// # let a = A { a: 5 };\n    /// match a {\n    ///     A { a: 5 } => {},\n    ///     _ => {},\n    /// }\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub REST_PAT_IN_FULLY_BOUND_STRUCTS,\n    restriction,\n    \"a match on a struct that binds all fields but still uses the wildcard pattern\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for temporaries returned from function calls in a match scrutinee that have the\n    /// `clippy::has_significant_drop` attribute.\n    ///\n    /// ### Why is this bad?\n    /// The `clippy::has_significant_drop` attribute can be added to types whose Drop impls have\n    /// an important side-effect, such as unlocking a mutex, making it important for users to be\n    /// able to accurately understand their lifetimes. When a temporary is returned in a function\n    /// call in a match scrutinee, its lifetime lasts until the end of the match block, which may\n    /// be surprising.\n    ///\n    /// For `Mutex`es this can lead to a deadlock. This happens when the match scrutinee uses a\n    /// function call that returns a `MutexGuard` and then tries to lock again in one of the match\n    /// arms. In that case the `MutexGuard` in the scrutinee will not be dropped until the end of\n    /// the match block and thus will not unlock.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// # use std::sync::Mutex;\n    /// # struct State {}\n    /// # impl State {\n    /// #     fn foo(&self) -> bool {\n    /// #         true\n    /// #     }\n    /// #     fn bar(&self) {}\n    /// # }\n    /// let mutex = Mutex::new(State {});\n    ///\n    /// match mutex.lock().unwrap().foo() {\n    ///     true => {\n    ///         mutex.lock().unwrap().bar(); // Deadlock!\n    ///     }\n    ///     false => {}\n    /// };\n    ///\n    /// println!(\"All done!\");\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::sync::Mutex;\n    /// # struct State {}\n    /// # impl State {\n    /// #     fn foo(&self) -> bool {\n    /// #         true\n    /// #     }\n    /// #     fn bar(&self) {}\n    /// # }\n    /// let mutex = Mutex::new(State {});\n    ///\n    /// let is_foo = mutex.lock().unwrap().foo();\n    /// match is_foo {\n    ///     true => {\n    ///         mutex.lock().unwrap().bar();\n    ///     }\n    ///     false => {}\n    /// };\n    ///\n    /// println!(\"All done!\");\n    /// ```\n    #[clippy::version = \"1.60.0\"]\n    pub SIGNIFICANT_DROP_IN_SCRUTINEE,\n    nursery,\n    \"warns when a temporary of a type with a drop with a significant side-effect might have a surprising lifetime\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for matches with a single arm where an `if let`\n    /// will usually suffice.\n    ///\n    /// This intentionally does not lint if there are comments\n    /// inside of the other arm, so as to allow the user to document\n    /// why having another explicit pattern with an empty body is necessary,\n    /// or because the comments need to be preserved for other reasons.\n    ///\n    /// ### Why is this bad?\n    /// Just readability – `if let` nests less than a `match`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn bar(stool: &str) {}\n    /// # let x = Some(\"abc\");\n    /// match x {\n    ///     Some(ref foo) => bar(foo),\n    ///     _ => (),\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # fn bar(stool: &str) {}\n    /// # let x = Some(\"abc\");\n    /// if let Some(ref foo) = x {\n    ///     bar(foo);\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SINGLE_MATCH,\n    style,\n    \"a `match` statement with a single nontrivial arm (i.e., where the other arm is `_ => {}`) instead of `if let`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for matches with two arms where an `if let else` will\n    /// usually suffice.\n    ///\n    /// ### Why is this bad?\n    /// Just readability – `if let` nests less than a `match`.\n    ///\n    /// ### Known problems\n    /// Personal style preferences may differ.\n    ///\n    /// ### Example\n    /// Using `match`:\n    ///\n    /// ```no_run\n    /// # fn bar(foo: &usize) {}\n    /// # let other_ref: usize = 1;\n    /// # let x: Option<&usize> = Some(&1);\n    /// match x {\n    ///     Some(ref foo) => bar(foo),\n    ///     _ => bar(&other_ref),\n    /// }\n    /// ```\n    ///\n    /// Using `if let` with `else`:\n    ///\n    /// ```no_run\n    /// # fn bar(foo: &usize) {}\n    /// # let other_ref: usize = 1;\n    /// # let x: Option<&usize> = Some(&1);\n    /// if let Some(ref foo) = x {\n    ///     bar(foo);\n    /// } else {\n    ///     bar(&other_ref);\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SINGLE_MATCH_ELSE,\n    pedantic,\n    \"a `match` statement with two arms where the second arm's pattern is a placeholder instead of a specific match pattern\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Err(x)?`.\n    ///\n    /// ### Why restrict this?\n    /// The `?` operator is designed to allow calls that\n    /// can fail to be easily chained. For example, `foo()?.bar()` or\n    /// `foo(bar()?)`. Because `Err(x)?` can't be used that way (it will\n    /// always return), it is more clear to write `return Err(x)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(fail: bool) -> Result<i32, String> {\n    ///     if fail {\n    ///       Err(\"failed\")?;\n    ///     }\n    ///     Ok(0)\n    /// }\n    /// ```\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// fn foo(fail: bool) -> Result<i32, String> {\n    ///     if fail {\n    ///       return Err(\"failed\".into());\n    ///     }\n    ///     Ok(0)\n    /// }\n    /// ```\n    #[clippy::version = \"1.38.0\"]\n    pub TRY_ERR,\n    restriction,\n    \"return errors explicitly rather than hiding them behind a `?`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for wildcard enum matches using `_`.\n    ///\n    /// ### Why restrict this?\n    /// New enum variants added by library updates can be missed.\n    ///\n    /// ### Known problems\n    /// Suggested replacements may be incorrect if guards exhaustively cover some\n    /// variants, and also may not use correct path to enum if it's not present in the current scope.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # enum Foo { A(usize), B(usize) }\n    /// # let x = Foo::B(1);\n    /// match x {\n    ///     Foo::A(_) => {},\n    ///     _ => {},\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # enum Foo { A(usize), B(usize) }\n    /// # let x = Foo::B(1);\n    /// match x {\n    ///     Foo::A(_) => {},\n    ///     Foo::B(_) => {},\n    /// }\n    /// ```\n    #[clippy::version = \"1.34.0\"]\n    pub WILDCARD_ENUM_MATCH_ARM,\n    restriction,\n    \"a wildcard enum match arm using `_`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for wildcard pattern used with others patterns in same match arm.\n    ///\n    /// ### Why is this bad?\n    /// Wildcard pattern already covers any other pattern as it will match anyway.\n    /// It makes the code less readable, especially to spot wildcard pattern use in match arm.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let s = \"foo\";\n    /// match s {\n    ///     \"a\" => {},\n    ///     \"bar\" | _ => {},\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let s = \"foo\";\n    /// match s {\n    ///     \"a\" => {},\n    ///     _ => {},\n    /// }\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub WILDCARD_IN_OR_PATTERNS,\n    complexity,\n    \"a wildcard pattern used with others patterns in same match arm\"\n}\n\nimpl_lint_pass!(Matches => [\n    COLLAPSIBLE_MATCH,\n    INFALLIBLE_DESTRUCTURING_MATCH,\n    MANUAL_FILTER,\n    MANUAL_MAP,\n    MANUAL_OK_ERR,\n    MANUAL_UNWRAP_OR,\n    MANUAL_UNWRAP_OR_DEFAULT,\n    MATCH_AS_REF,\n    MATCH_BOOL,\n    MATCH_LIKE_MATCHES_MACRO,\n    MATCH_OVERLAPPING_ARM,\n    MATCH_REF_PATS,\n    MATCH_SAME_ARMS,\n    MATCH_SINGLE_BINDING,\n    MATCH_STR_CASE_MISMATCH,\n    MATCH_WILDCARD_FOR_SINGLE_VARIANTS,\n    MATCH_WILD_ERR_ARM,\n    NEEDLESS_MATCH,\n    REDUNDANT_GUARDS,\n    REDUNDANT_PATTERN_MATCHING,\n    REST_PAT_IN_FULLY_BOUND_STRUCTS,\n    SIGNIFICANT_DROP_IN_SCRUTINEE,\n    SINGLE_MATCH,\n    SINGLE_MATCH_ELSE,\n    TRY_ERR,\n    WILDCARD_ENUM_MATCH_ARM,\n    WILDCARD_IN_OR_PATTERNS,\n]);\n\npub struct Matches {\n    msrv: Msrv,\n    infallible_destructuring_match_linted: bool,\n}\n\nimpl Matches {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: conf.msrv,\n            infallible_destructuring_match_linted: false,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Matches {\n    #[expect(clippy::too_many_lines)]\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if is_direct_expn_of(expr.span, sym::matches).is_none() && expr.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n        let from_expansion = expr.span.from_expansion();\n\n        if let ExprKind::Match(ex, arms, source) = expr.kind {\n            if is_direct_expn_of(expr.span, sym::matches).is_some()\n                && let [arm, _] = arms\n            {\n                redundant_pattern_match::check_match(cx, expr, ex, arms);\n                redundant_pattern_match::check_matches_true(cx, expr, arm, ex);\n            }\n\n            if source == MatchSource::Normal && !is_span_match(cx, expr.span) {\n                return;\n            }\n            if matches!(source, MatchSource::Normal | MatchSource::ForLoopDesugar) {\n                significant_drop_in_scrutinee::check_match(cx, expr, ex, arms, source);\n            }\n\n            collapsible_match::check_match(cx, ex, arms, self.msrv);\n            if !from_expansion {\n                // These don't depend on a relationship between multiple arms\n                match_wild_err_arm::check(cx, ex, arms);\n                wild_in_or_pats::check(cx, ex, arms);\n            }\n\n            if let MatchSource::TryDesugar(_) = source {\n                try_err::check(cx, expr, ex);\n            }\n\n            if !from_expansion && !contains_cfg_arm(cx, expr, ex, arms) {\n                if source == MatchSource::Normal {\n                    if !(self.msrv.meets(cx, msrvs::MATCHES_MACRO)\n                        && match_like_matches::check_match(cx, expr, ex, arms))\n                    {\n                        match_same_arms::check(cx, arms);\n                    }\n\n                    redundant_pattern_match::check_match(cx, expr, ex, arms);\n                    let mut match_comments = span_extract_comments(cx, expr.span);\n                    // We remove comments from inside arms block.\n                    if !match_comments.is_empty() {\n                        for arm in arms {\n                            for comment in span_extract_comments(cx, arm.body.span) {\n                                if let Some(index) = match_comments\n                                    .iter()\n                                    .enumerate()\n                                    .find(|(_, cm)| **cm == comment)\n                                    .map(|(index, _)| index)\n                                {\n                                    match_comments.remove(index);\n                                }\n                            }\n                        }\n                    }\n                    // If there are still comments, it means they are outside of the arms. Tell the lint\n                    // code about it.\n                    single_match::check(cx, ex, arms, expr, !match_comments.is_empty());\n                    match_bool::check(cx, ex, arms, expr);\n                    overlapping_arms::check(cx, ex, arms);\n                    match_wild_enum::check(cx, ex, arms);\n                    match_as_ref::check(cx, ex, arms, expr);\n                    needless_match::check_match(cx, ex, arms, expr);\n                    match_str_case_mismatch::check(cx, ex, arms);\n                    redundant_guards::check(cx, arms, self.msrv);\n\n                    if !is_in_const_context(cx) {\n                        manual_unwrap_or::check_match(cx, expr, ex, arms);\n                        manual_map::check_match(cx, expr, ex, arms);\n                        manual_filter::check_match(cx, ex, arms, expr);\n                        manual_ok_err::check_match(cx, expr, ex, arms);\n                    }\n\n                    if self.infallible_destructuring_match_linted {\n                        self.infallible_destructuring_match_linted = false;\n                    } else {\n                        match_single_binding::check(cx, ex, arms, expr);\n                    }\n                }\n                match_ref_pats::check(cx, ex, arms.iter().map(|el| el.pat), expr);\n            }\n        } else if let Some(if_let) = higher::IfLet::hir(cx, expr) {\n            collapsible_match::check_if_let(\n                cx,\n                if_let.let_pat,\n                if_let.if_then,\n                if_let.if_else,\n                if_let.let_expr,\n                self.msrv,\n            );\n            significant_drop_in_scrutinee::check_if_let(cx, expr, if_let.let_expr, if_let.if_then, if_let.if_else);\n            if !from_expansion {\n                if let Some(else_expr) = if_let.if_else {\n                    if self.msrv.meets(cx, msrvs::MATCHES_MACRO) {\n                        match_like_matches::check_if_let(\n                            cx,\n                            expr,\n                            if_let.let_pat,\n                            if_let.let_expr,\n                            if_let.if_then,\n                            else_expr,\n                        );\n                    }\n                    if !is_in_const_context(cx) {\n                        manual_unwrap_or::check_if_let(\n                            cx,\n                            expr,\n                            if_let.let_pat,\n                            if_let.let_expr,\n                            if_let.if_then,\n                            else_expr,\n                        );\n                        manual_map::check_if_let(cx, expr, if_let.let_pat, if_let.let_expr, if_let.if_then, else_expr);\n                        manual_filter::check_if_let(\n                            cx,\n                            expr,\n                            if_let.let_pat,\n                            if_let.let_expr,\n                            if_let.if_then,\n                            else_expr,\n                        );\n                        manual_ok_err::check_if_let(\n                            cx,\n                            expr,\n                            if_let.let_pat,\n                            if_let.let_expr,\n                            if_let.if_then,\n                            else_expr,\n                        );\n                    }\n                }\n                redundant_pattern_match::check_if_let(\n                    cx,\n                    expr,\n                    if_let.let_pat,\n                    if_let.let_expr,\n                    if_let.if_else.is_some(),\n                    if_let.let_span,\n                );\n                needless_match::check_if_let(cx, expr, &if_let);\n            }\n        } else {\n            if let Some(while_let) = higher::WhileLet::hir(expr) {\n                significant_drop_in_scrutinee::check_while_let(cx, expr, while_let.let_expr, while_let.if_then);\n            }\n            if !from_expansion {\n                redundant_pattern_match::check(cx, expr);\n            }\n        }\n    }\n\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {\n        self.infallible_destructuring_match_linted |=\n            local.els.is_none() && infallible_destructuring_match::check(cx, local);\n    }\n\n    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {\n        rest_pat_in_fully_bound_struct::check(cx, pat);\n    }\n}\n\n/// Checks if there are any arms with a `#[cfg(..)]` attribute.\nfn contains_cfg_arm(cx: &LateContext<'_>, e: &Expr<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>]) -> bool {\n    let Some(scrutinee_span) = walk_span_to_context(scrutinee.span, SyntaxContext::root()) else {\n        // Shouldn't happen, but treat this as though a `cfg` attribute were found\n        return true;\n    };\n\n    let start = scrutinee_span.hi();\n    let mut arm_spans = arms.iter().map(|arm| {\n        let data = arm.span.data();\n        (data.ctxt == SyntaxContext::root()).then_some((data.lo, data.hi))\n    });\n    let end = e.span.hi();\n\n    // Walk through all the non-code space before each match arm. The space trailing the final arm is\n    // handled after the `try_fold` e.g.\n    //\n    // match foo {\n    // _________^-                      everything between the scrutinee and arm1\n    //|    arm1 => (),\n    //|---^___________^                 everything before arm2\n    //|    #[cfg(feature = \"enabled\")]\n    //|    arm2 => some_code(),\n    //|---^____________________^        everything before arm3\n    //|    // some comment about arm3\n    //|    arm3 => some_code(),\n    //|---^____________________^        everything after arm3\n    //|    #[cfg(feature = \"disabled\")]\n    //|    arm4 = some_code(),\n    //|};\n    //|^\n    let found = arm_spans.try_fold(start, |start, range| {\n        let Some((end, next_start)) = range else {\n            // Shouldn't happen as macros can't expand to match arms, but treat this as though a `cfg` attribute\n            // were found.\n            return Err(());\n        };\n        let span = SpanData {\n            lo: start,\n            hi: end,\n            ctxt: SyntaxContext::root(),\n            parent: None,\n        }\n        .span();\n        (!span_contains_cfg(cx, span)).then_some(next_start).ok_or(())\n    });\n    match found {\n        Ok(start) => {\n            let span = SpanData {\n                lo: start,\n                hi: end,\n                ctxt: SyntaxContext::root(),\n                parent: None,\n            }\n            .span();\n            span_contains_cfg(cx, span)\n        },\n        Err(()) => true,\n    }\n}\n\n/// Checks if `pat` contains OR patterns that cannot be nested due to a too low MSRV.\nfn pat_contains_disallowed_or(cx: &LateContext<'_>, pat: &Pat<'_>, msrv: Msrv) -> bool {\n    let mut contains_or = false;\n    pat.walk(|p| {\n        let is_or = matches!(p.kind, PatKind::Or(_));\n        contains_or |= is_or;\n        !is_or\n    });\n    contains_or && !msrv.meets(cx, msrvs::OR_PATTERNS)\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/needless_match.rs",
    "content": "use super::NEEDLESS_MATCH;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::same_type_modulo_regions;\nuse clippy_utils::{\n    SpanlessEq, eq_expr_value, get_parent_expr_for_hir, higher, is_else_clause, over, peel_blocks_with_stmt,\n};\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::OptionNone;\nuse rustc_hir::{\n    Arm, BindingMode, ByRef, Expr, ExprKind, ItemKind, Node, Pat, PatExpr, PatExprKind, PatKind, Path, QPath,\n};\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\npub(crate) fn check_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {\n    if arms.len() > 1 && expr_ty_matches_p_ty(cx, ex, expr) && check_all_arms(cx, ex, arms) {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            NEEDLESS_MATCH,\n            expr.span,\n            \"this match expression is unnecessary\",\n            \"replace it with\",\n            snippet_with_applicability(cx, ex.span, \"..\", &mut applicability).to_string(),\n            applicability,\n        );\n    }\n}\n\n/// Check for nop `if let` expression that assembled as unnecessary match\n///\n/// ```rust,ignore\n/// if let Some(a) = option {\n///     Some(a)\n/// } else {\n///     None\n/// }\n/// ```\n/// OR\n/// ```rust,ignore\n/// if let SomeEnum::A = some_enum {\n///     SomeEnum::A\n/// } else if let SomeEnum::B = some_enum {\n///     SomeEnum::B\n/// } else {\n///     some_enum\n/// }\n/// ```\npub(crate) fn check_if_let<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'_>, if_let: &higher::IfLet<'tcx>) {\n    if !is_else_clause(cx.tcx, ex) && expr_ty_matches_p_ty(cx, if_let.let_expr, ex) && check_if_let_inner(cx, if_let) {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            NEEDLESS_MATCH,\n            ex.span,\n            \"this if-let expression is unnecessary\",\n            \"replace it with\",\n            snippet_with_applicability(cx, if_let.let_expr.span, \"..\", &mut applicability).to_string(),\n            applicability,\n        );\n    }\n}\n\nfn check_all_arms(cx: &LateContext<'_>, match_expr: &Expr<'_>, arms: &[Arm<'_>]) -> bool {\n    for arm in arms {\n        let arm_expr = peel_blocks_with_stmt(arm.body);\n\n        if let Some(guard_expr) = &arm.guard\n            && guard_expr.can_have_side_effects()\n        {\n            return false;\n        }\n\n        if let PatKind::Wild = arm.pat.kind {\n            if !eq_expr_value(cx, match_expr, arm_expr) {\n                return false;\n            }\n        } else if !pat_same_as_expr(arm.pat, arm_expr) {\n            return false;\n        }\n    }\n\n    true\n}\n\nfn check_if_let_inner(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool {\n    if let Some(if_else) = if_let.if_else {\n        if !pat_same_as_expr(if_let.let_pat, peel_blocks_with_stmt(if_let.if_then)) {\n            return false;\n        }\n\n        // Recursively check for each `else if let` phrase,\n        if let Some(ref nested_if_let) = higher::IfLet::hir(cx, if_else)\n            && SpanlessEq::new(cx).eq_expr(nested_if_let.let_expr, if_let.let_expr)\n        {\n            return check_if_let_inner(cx, nested_if_let);\n        }\n\n        if matches!(if_else.kind, ExprKind::Block(..)) {\n            let else_expr = peel_blocks_with_stmt(if_else);\n            if matches!(else_expr.kind, ExprKind::Block(..)) {\n                return false;\n            }\n            let let_expr_ty = cx.typeck_results().expr_ty(if_let.let_expr);\n            if let_expr_ty.is_diag_item(cx, sym::Option) {\n                return else_expr.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)\n                    || eq_expr_value(cx, if_let.let_expr, else_expr);\n            }\n            return eq_expr_value(cx, if_let.let_expr, else_expr);\n        }\n    }\n\n    false\n}\n\n/// Manually check for coercion casting by checking if the type of the match operand or let expr\n/// differs with the assigned local variable or the function return type.\nfn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>) -> bool {\n    match cx.tcx.parent_hir_node(p_expr.hir_id) {\n        // Compare match_expr ty with local in `let local = match match_expr {..}`\n        Node::LetStmt(local) => {\n            let results = cx.typeck_results();\n            return same_type_modulo_regions(results.node_type(local.hir_id), results.expr_ty(expr));\n        },\n        // compare match_expr ty with RetTy in `fn foo() -> RetTy`\n        Node::Item(item) => {\n            if let ItemKind::Fn { .. } = item.kind {\n                let output = cx\n                    .tcx\n                    .fn_sig(item.owner_id)\n                    .instantiate_identity()\n                    .output()\n                    .skip_binder();\n                return same_type_modulo_regions(output, cx.typeck_results().expr_ty(expr));\n            }\n        },\n        // check the parent expr for this whole block `{ match match_expr {..} }`\n        Node::Block(block) => {\n            if let Some(block_parent_expr) = get_parent_expr_for_hir(cx, block.hir_id) {\n                return expr_ty_matches_p_ty(cx, expr, block_parent_expr);\n            }\n        },\n        // recursively call on `if xxx {..}` etc.\n        Node::Expr(p_expr) => {\n            return expr_ty_matches_p_ty(cx, expr, p_expr);\n        },\n        _ => {},\n    }\n    false\n}\n\nfn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {\n    match (&pat.kind, &expr.kind) {\n        // Example: `Some(val) => Some(val)`\n        (PatKind::TupleStruct(QPath::Resolved(_, path), tuple_params, _), ExprKind::Call(call_expr, call_params)) => {\n            if let ExprKind::Path(QPath::Resolved(_, call_path)) = call_expr.kind {\n                return over(path.segments, call_path.segments, |pat_seg, call_seg| {\n                    pat_seg.ident.name == call_seg.ident.name\n                }) && same_non_ref_symbols(tuple_params, call_params);\n            }\n        },\n        // Example: `val => val`\n        (\n            PatKind::Binding(annot, _, pat_ident, _),\n            ExprKind::Path(QPath::Resolved(\n                _,\n                Path {\n                    segments: [first_seg, ..],\n                    ..\n                },\n            )),\n        ) => {\n            return !matches!(annot, BindingMode(ByRef::Yes(..), _)) && pat_ident.name == first_seg.ident.name;\n        },\n        // Example: `Custom::TypeA => Custom::TypeB`, or `None => None`\n        (\n            PatKind::Expr(PatExpr {\n                kind: PatExprKind::Path(QPath::Resolved(_, p_path)),\n                ..\n            }),\n            ExprKind::Path(QPath::Resolved(_, e_path)),\n        ) => {\n            return over(p_path.segments, e_path.segments, |p_seg, e_seg| {\n                p_seg.ident.name == e_seg.ident.name\n            });\n        },\n        // Example: `5 => 5`\n        (PatKind::Expr(pat_expr_expr), ExprKind::Lit(expr_spanned)) => {\n            if let PatExprKind::Lit {\n                lit: pat_spanned,\n                negated: false,\n            } = &pat_expr_expr.kind\n            {\n                return pat_spanned.node == expr_spanned.node;\n            }\n        },\n        _ => {},\n    }\n\n    false\n}\n\nfn same_non_ref_symbols(pats: &[Pat<'_>], exprs: &[Expr<'_>]) -> bool {\n    if pats.len() != exprs.len() {\n        return false;\n    }\n\n    for i in 0..pats.len() {\n        if !pat_same_as_expr(&pats[i], &exprs[i]) {\n            return false;\n        }\n    }\n\n    true\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/overlapping_arms.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant, FullInt};\nuse clippy_utils::diagnostics::span_lint_and_note;\nuse core::cmp::Ordering;\nuse rustc_hir::{Arm, Expr, PatKind, RangeEnd};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::Span;\n\nuse super::MATCH_OVERLAPPING_ARM;\n\npub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) {\n    if arms.len() >= 2 && cx.typeck_results().expr_ty(ex).is_integral() {\n        let ranges = all_ranges(cx, arms, cx.typeck_results().expr_ty(ex));\n        if !ranges.is_empty()\n            && let Some((start, end)) = overlapping(&ranges)\n        {\n            span_lint_and_note(\n                cx,\n                MATCH_OVERLAPPING_ARM,\n                start.span,\n                \"some ranges overlap\",\n                Some(end.span),\n                \"overlaps with this\",\n            );\n        }\n    }\n}\n\n/// Gets the ranges for each range pattern arm. Applies `ty` bounds for open ranges.\nfn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>) -> Vec<SpannedRange<FullInt>> {\n    arms.iter()\n        .filter_map(|arm| {\n            if let Arm { pat, guard: None, .. } = *arm {\n                if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind {\n                    let lhs_const = if let Some(lhs) = lhs {\n                        ConstEvalCtxt::new(cx).eval_pat_expr(lhs)?\n                    } else {\n                        Constant::new_numeric_min(cx.tcx, ty)?\n                    };\n                    let rhs_const = if let Some(rhs) = rhs {\n                        ConstEvalCtxt::new(cx).eval_pat_expr(rhs)?\n                    } else {\n                        Constant::new_numeric_max(cx.tcx, ty)?\n                    };\n                    let lhs_val = lhs_const.int_value(cx.tcx, ty)?;\n                    let rhs_val = rhs_const.int_value(cx.tcx, ty)?;\n                    let rhs_bound = match range_end {\n                        RangeEnd::Included => EndBound::Included(rhs_val),\n                        RangeEnd::Excluded => EndBound::Excluded(rhs_val),\n                    };\n                    return Some(SpannedRange {\n                        span: pat.span,\n                        node: (lhs_val, rhs_bound),\n                    });\n                }\n\n                if let PatKind::Expr(value) = pat.kind {\n                    let value = ConstEvalCtxt::new(cx)\n                        .eval_pat_expr(value)?\n                        .int_value(cx.tcx, cx.typeck_results().node_type(pat.hir_id))?;\n                    return Some(SpannedRange {\n                        span: pat.span,\n                        node: (value, EndBound::Included(value)),\n                    });\n                }\n            }\n            None\n        })\n        .collect()\n}\n\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\npub enum EndBound<T> {\n    Included(T),\n    Excluded(T),\n}\n\n#[derive(Debug, Eq, PartialEq)]\nstruct SpannedRange<T> {\n    pub span: Span,\n    pub node: (T, EndBound<T>),\n}\n\nfn overlapping<T>(ranges: &[SpannedRange<T>]) -> Option<(&SpannedRange<T>, &SpannedRange<T>)>\nwhere\n    T: Copy + Ord,\n{\n    #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]\n    enum BoundKind {\n        EndExcluded,\n        Start,\n        EndIncluded,\n    }\n\n    #[derive(Copy, Clone, Debug, Eq, PartialEq)]\n    struct RangeBound<'a, T>(T, BoundKind, &'a SpannedRange<T>);\n\n    impl<T: Copy + Ord> PartialOrd for RangeBound<'_, T> {\n        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n            Some(self.cmp(other))\n        }\n    }\n\n    impl<T: Copy + Ord> Ord for RangeBound<'_, T> {\n        fn cmp(&self, RangeBound(other_value, other_kind, _): &Self) -> Ordering {\n            let RangeBound(self_value, self_kind, _) = *self;\n            (self_value, self_kind).cmp(&(*other_value, *other_kind))\n        }\n    }\n\n    let mut values = Vec::with_capacity(2 * ranges.len());\n\n    for r @ SpannedRange { node: (start, end), .. } in ranges {\n        values.push(RangeBound(*start, BoundKind::Start, r));\n        values.push(match end {\n            EndBound::Excluded(val) => RangeBound(*val, BoundKind::EndExcluded, r),\n            EndBound::Included(val) => RangeBound(*val, BoundKind::EndIncluded, r),\n        });\n    }\n\n    values.sort();\n\n    let mut started = vec![];\n\n    for RangeBound(_, kind, range) in values {\n        match kind {\n            BoundKind::Start => started.push(range),\n            BoundKind::EndExcluded | BoundKind::EndIncluded => {\n                let mut overlap = None;\n\n                while let Some(last_started) = started.pop() {\n                    if last_started == range {\n                        break;\n                    }\n                    overlap = Some(last_started);\n                }\n\n                if let Some(first_overlapping) = overlap {\n                    return Some((range, first_overlapping));\n                }\n            },\n        }\n    }\n\n    None\n}\n\n#[test]\nfn test_overlapping() {\n    use rustc_span::DUMMY_SP;\n\n    let sp = |s, e| SpannedRange {\n        span: DUMMY_SP,\n        node: (s, e),\n    };\n\n    assert_eq!(None, overlapping::<u8>(&[]));\n    assert_eq!(None, overlapping(&[sp(1, EndBound::Included(4))]));\n    assert_eq!(\n        None,\n        overlapping(&[sp(1, EndBound::Included(4)), sp(5, EndBound::Included(6))])\n    );\n    assert_eq!(\n        None,\n        overlapping(&[\n            sp(1, EndBound::Included(4)),\n            sp(5, EndBound::Included(6)),\n            sp(10, EndBound::Included(11))\n        ],)\n    );\n    assert_eq!(\n        Some((&sp(1, EndBound::Included(4)), &sp(3, EndBound::Included(6)))),\n        overlapping(&[sp(1, EndBound::Included(4)), sp(3, EndBound::Included(6))])\n    );\n    assert_eq!(\n        Some((&sp(5, EndBound::Included(6)), &sp(6, EndBound::Included(11)))),\n        overlapping(&[\n            sp(1, EndBound::Included(4)),\n            sp(5, EndBound::Included(6)),\n            sp(6, EndBound::Included(11))\n        ],)\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/redundant_guards.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::matching_root_macro_call;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet;\nuse clippy_utils::visitors::{for_each_expr_without_closures, is_local_used};\nuse clippy_utils::{is_in_const_context, sym};\nuse rustc_ast::{BorrowKind, LitKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, PatKind, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::Ident;\nuse rustc_span::{Span, Symbol};\nuse std::borrow::Cow;\nuse std::ops::ControlFlow;\n\nuse super::{REDUNDANT_GUARDS, pat_contains_disallowed_or};\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: Msrv) {\n    for outer_arm in arms {\n        let Some(guard) = outer_arm.guard else {\n            continue;\n        };\n\n        // `Some(x) if matches!(x, y)`\n        if let ExprKind::Match(scrutinee, [arm, _], MatchSource::Normal) = guard.kind\n            && matching_root_macro_call(cx, guard.span, sym::matches_macro).is_some()\n            && let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm)\n            && !pat_contains_disallowed_or(cx, arm.pat, msrv)\n        {\n            let pat_span = match (arm.pat.kind, binding.byref_ident) {\n                (PatKind::Ref(pat, _, _), Some(_)) => pat.span,\n                (PatKind::Ref(..), None) | (_, Some(_)) => continue,\n                _ => arm.pat.span,\n            };\n            emit_redundant_guards(\n                cx,\n                outer_arm,\n                guard.span,\n                snippet(cx, pat_span, \"<binding>\"),\n                &binding,\n                arm.guard,\n            );\n        }\n        // `Some(x) if let Some(2) = x`\n        else if let ExprKind::Let(let_expr) = guard.kind\n            && let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm)\n            && !pat_contains_disallowed_or(cx, let_expr.pat, msrv)\n        {\n            let pat_span = match (let_expr.pat.kind, binding.byref_ident) {\n                (PatKind::Ref(pat, _, _), Some(_)) => pat.span,\n                (PatKind::Ref(..), None) | (_, Some(_)) => continue,\n                _ => let_expr.pat.span,\n            };\n            emit_redundant_guards(\n                cx,\n                outer_arm,\n                let_expr.span,\n                snippet(cx, pat_span, \"<binding>\"),\n                &binding,\n                None,\n            );\n        }\n        // `Some(x) if x == Some(2)`\n        // `Some(x) if Some(2) == x`\n        else if let ExprKind::Binary(bin_op, local, pat) = guard.kind\n            && matches!(bin_op.node, BinOpKind::Eq)\n            // Ensure they have the same type. If they don't, we'd need deref coercion which isn't\n            // possible (currently) in a pattern. In some cases, you can use something like\n            // `as_deref` or similar but in general, we shouldn't lint this as it'd create an\n            // extraordinary amount of FPs.\n            //\n            // This isn't necessary in the other two checks, as they must be a pattern already.\n            && cx.typeck_results().expr_ty(local) == cx.typeck_results().expr_ty(pat)\n            // Since we want to lint on both `x == Some(2)` and `Some(2) == x`, we might have to \"swap\"\n            // `local` and `pat`, depending on which side they are.\n            && let Some((binding, pat)) = get_pat_binding(cx, local, outer_arm)\n                .map(|binding| (binding, pat))\n                .or_else(|| get_pat_binding(cx, pat, outer_arm).map(|binding| (binding, local)))\n            && expr_can_be_pat(cx, pat)\n        {\n            let pat_span = match (pat.kind, binding.byref_ident) {\n                (ExprKind::AddrOf(BorrowKind::Ref, _, expr), Some(_)) => expr.span,\n                (ExprKind::AddrOf(..), None) | (_, Some(_)) => continue,\n                _ => pat.span,\n            };\n            emit_redundant_guards(\n                cx,\n                outer_arm,\n                guard.span,\n                snippet(cx, pat_span, \"<binding>\"),\n                &binding,\n                None,\n            );\n        } else if let ExprKind::MethodCall(path, recv, args, ..) = guard.kind\n            && let Some(binding) = get_pat_binding(cx, recv, outer_arm)\n        {\n            check_method_calls(cx, outer_arm, path.ident.name, recv, args, guard, &binding);\n        }\n    }\n}\n\nfn check_method_calls<'tcx>(\n    cx: &LateContext<'tcx>,\n    arm: &Arm<'tcx>,\n    method: Symbol,\n    recv: &Expr<'_>,\n    args: &[Expr<'_>],\n    if_expr: &Expr<'_>,\n    binding: &PatBindingInfo,\n) {\n    let ty = cx.typeck_results().expr_ty(recv).peel_refs();\n    let slice_like = ty.is_slice() || ty.is_array();\n\n    let sugg = if method == sym::is_empty {\n        // `s if s.is_empty()` becomes \"\"\n        // `arr if arr.is_empty()` becomes []\n\n        if ty.is_str() && !is_in_const_context(cx) {\n            r#\"\"\"\"#.into()\n        } else if slice_like {\n            \"[]\".into()\n        } else {\n            return;\n        }\n    } else if slice_like\n        && let Some(needle) = args.first()\n        && let ExprKind::AddrOf(.., needle) = needle.kind\n        && let ExprKind::Array(needles) = needle.kind\n        && needles.iter().all(|needle| expr_can_be_pat(cx, needle))\n    {\n        // `arr if arr.starts_with(&[123])` becomes [123, ..]\n        // `arr if arr.ends_with(&[123])` becomes [.., 123]\n        // `arr if arr.starts_with(&[])` becomes [..]  (why would anyone write this?)\n\n        let mut sugg = snippet(cx, needle.span, \"<needle>\").into_owned();\n\n        if needles.is_empty() {\n            sugg.insert_str(1, \"..\");\n        } else if method == sym::starts_with {\n            sugg.insert_str(sugg.len() - 1, \", ..\");\n        } else if method == sym::ends_with {\n            sugg.insert_str(1, \".., \");\n        } else {\n            return;\n        }\n\n        sugg.into()\n    } else {\n        return;\n    };\n\n    emit_redundant_guards(cx, arm, if_expr.span, sugg, binding, None);\n}\n\nstruct PatBindingInfo {\n    span: Span,\n    byref_ident: Option<Ident>,\n    is_field: bool,\n}\n\nfn get_pat_binding<'tcx>(\n    cx: &LateContext<'tcx>,\n    guard_expr: &Expr<'_>,\n    outer_arm: &Arm<'tcx>,\n) -> Option<PatBindingInfo> {\n    if let Some(local) = guard_expr.res_local_id()\n        && !is_local_used(cx, outer_arm.body, local)\n    {\n        let mut span = None;\n        let mut byref_ident = None;\n        let mut multiple_bindings = false;\n        // `each_binding` gives the `HirId` of the `Pat` itself, not the binding\n        outer_arm.pat.walk(|pat| {\n            if let PatKind::Binding(bind_annot, hir_id, ident, _) = pat.kind\n                && hir_id == local\n            {\n                if matches!(bind_annot.0, rustc_ast::ByRef::Yes(..)) {\n                    let _ = byref_ident.insert(ident);\n                }\n                // the second call of `replace()` returns a `Some(span)`, meaning a multi-binding pattern\n                if span.replace(pat.span).is_some() {\n                    multiple_bindings = true;\n                    return false;\n                }\n            }\n            true\n        });\n\n        // Ignore bindings from or patterns, like `First(x) | Second(x, _) | Third(x, _, _)`\n        if !multiple_bindings {\n            return span.map(|span| PatBindingInfo {\n                span,\n                byref_ident,\n                is_field: matches!(cx.tcx.parent_hir_node(local), Node::PatField(_)),\n            });\n        }\n    }\n\n    None\n}\n\nfn emit_redundant_guards<'tcx>(\n    cx: &LateContext<'tcx>,\n    outer_arm: &Arm<'tcx>,\n    guard_span: Span,\n    binding_replacement: Cow<'static, str>,\n    pat_binding: &PatBindingInfo,\n    inner_guard: Option<&Expr<'_>>,\n) {\n    span_lint_and_then(\n        cx,\n        REDUNDANT_GUARDS,\n        guard_span.source_callsite(),\n        \"redundant guard\",\n        |diag| {\n            let suggestion_span = match *pat_binding {\n                PatBindingInfo {\n                    span,\n                    byref_ident: Some(ident),\n                    is_field: true,\n                } => (span, format!(\"{ident}: {binding_replacement}\")),\n                PatBindingInfo {\n                    span, is_field: true, ..\n                } => (span.shrink_to_hi(), format!(\": {binding_replacement}\")),\n                PatBindingInfo { span, .. } => (span, binding_replacement.into_owned()),\n            };\n            diag.multipart_suggestion(\n                \"try\",\n                vec![\n                    suggestion_span,\n                    (\n                        guard_span.source_callsite().with_lo(outer_arm.pat.span.hi()),\n                        inner_guard.map_or_else(String::new, |guard| {\n                            format!(\" if {}\", snippet(cx, guard.span, \"<guard>\"))\n                        }),\n                    ),\n                ],\n                Applicability::MaybeIncorrect,\n            );\n        },\n    );\n}\n\n/// Checks if the given `Expr` can also be represented as a `Pat`.\nfn expr_can_be_pat(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    for_each_expr_without_closures(expr, |expr| {\n        if match expr.kind {\n            ExprKind::Call(c, ..) if let ExprKind::Path(qpath) = c.kind => {\n                // Allow ctors\n                matches!(cx.qpath_res(&qpath, c.hir_id), Res::Def(DefKind::Ctor(..), ..))\n            },\n            ExprKind::Path(qpath) => {\n                matches!(\n                    cx.qpath_res(&qpath, expr.hir_id),\n                    Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Ctor(..), ..),\n                )\n            },\n            ExprKind::AddrOf(..)\n            | ExprKind::Array(..)\n            | ExprKind::Tup(..)\n            | ExprKind::Struct(..)\n            | ExprKind::Unary(UnOp::Neg, _) => true,\n            ExprKind::Lit(lit) if !matches!(lit.node, LitKind::CStr(..)) => true,\n            _ => false,\n        } {\n            return ControlFlow::Continue(());\n        }\n\n        ControlFlow::Break(())\n    })\n    .is_none()\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/redundant_pattern_match.rs",
    "content": "use super::REDUNDANT_PATTERN_MATCHING;\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::sugg::{Sugg, make_unop};\nuse clippy_utils::ty::needs_ordered_drop;\nuse clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures};\nuse clippy_utils::{higher, is_expn_of, sym};\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk};\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatExpr, PatExprKind, PatKind, QPath, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, GenericArgKind, Ty};\nuse rustc_span::{Span, Symbol};\nuse std::fmt::Write;\nuse std::ops::ControlFlow;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n    if let Some(higher::WhileLet {\n        let_pat,\n        let_expr,\n        let_span,\n        ..\n    }) = higher::WhileLet::hir(expr)\n    {\n        find_method_sugg_for_if_let(cx, expr, let_pat, let_expr, \"while\", false, let_span);\n        find_if_let_true(cx, let_pat, let_expr, let_span);\n    }\n}\n\npub(super) fn check_if_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    pat: &'tcx Pat<'_>,\n    scrutinee: &'tcx Expr<'_>,\n    has_else: bool,\n    let_span: Span,\n) {\n    find_if_let_true(cx, pat, scrutinee, let_span);\n    find_method_sugg_for_if_let(cx, expr, pat, scrutinee, \"if\", has_else, let_span);\n}\n\n/// Looks for:\n/// * `matches!(expr, true)`\npub fn check_matches_true<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    arm: &'tcx Arm<'_>,\n    scrutinee: &'tcx Expr<'_>,\n) {\n    find_match_true(\n        cx,\n        arm.pat,\n        scrutinee,\n        expr.span.source_callsite(),\n        \"using `matches!` to pattern match a bool\",\n    );\n}\n\n/// Looks for any of:\n/// * `if let true = ...`\n/// * `if let false = ...`\n/// * `while let true = ...`\nfn find_if_let_true<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, scrutinee: &'tcx Expr<'_>, let_span: Span) {\n    find_match_true(cx, pat, scrutinee, let_span, \"using `if let` to pattern match a bool\");\n}\n\n/// Common logic between `find_if_let_true` and `check_matches_true`\nfn find_match_true<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &'tcx Pat<'_>,\n    scrutinee: &'tcx Expr<'_>,\n    span: Span,\n    message: &'static str,\n) {\n    if let PatKind::Expr(lit) = pat.kind\n        && let PatExprKind::Lit { lit, negated: false } = lit.kind\n        && let LitKind::Bool(pat_is_true) = lit.node\n    {\n        let mut applicability = Applicability::MachineApplicable;\n\n        let mut sugg = Sugg::hir_with_context(\n            cx,\n            scrutinee,\n            scrutinee.span.source_callsite().ctxt(),\n            \"..\",\n            &mut applicability,\n        );\n\n        if !pat_is_true {\n            sugg = make_unop(\"!\", sugg);\n        }\n\n        span_lint_and_sugg(\n            cx,\n            REDUNDANT_PATTERN_MATCHING,\n            span,\n            message,\n            \"consider using the condition directly\",\n            sugg.into_string(),\n            applicability,\n        );\n    }\n}\n\n// Extract the generic arguments out of a type\nfn try_get_generic_ty(ty: Ty<'_>, index: usize) -> Option<Ty<'_>> {\n    if let ty::Adt(_, subs) = ty.kind()\n        && let Some(sub) = subs.get(index)\n        && let GenericArgKind::Type(sub_ty) = sub.kind()\n    {\n        Some(sub_ty)\n    } else {\n        None\n    }\n}\n\nfn find_method_and_type<'tcx>(\n    cx: &LateContext<'tcx>,\n    check_pat: &Pat<'_>,\n    op_ty: Ty<'tcx>,\n) -> Option<(&'static str, Ty<'tcx>)> {\n    match check_pat.kind {\n        PatKind::TupleStruct(ref qpath, args, rest) => {\n            let is_wildcard = matches!(args.first().map(|p| &p.kind), Some(PatKind::Wild));\n            let is_rest = matches!((args, rest.as_opt_usize()), ([], Some(_)));\n\n            if is_wildcard || is_rest {\n                let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id);\n                let id = res.opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id))?;\n                let lang_items = cx.tcx.lang_items();\n                if Some(id) == lang_items.result_ok_variant() {\n                    Some((\"is_ok()\", try_get_generic_ty(op_ty, 0).unwrap_or(op_ty)))\n                } else if Some(id) == lang_items.result_err_variant() {\n                    Some((\"is_err()\", try_get_generic_ty(op_ty, 1).unwrap_or(op_ty)))\n                } else if Some(id) == lang_items.option_some_variant() {\n                    Some((\"is_some()\", op_ty))\n                } else if Some(id) == lang_items.poll_ready_variant() {\n                    Some((\"is_ready()\", op_ty))\n                } else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym::V4)) {\n                    Some((\"is_ipv4()\", op_ty))\n                } else if is_pat_variant(cx, check_pat, qpath, Item::Diag(sym::IpAddr, sym::V6)) {\n                    Some((\"is_ipv6()\", op_ty))\n                } else {\n                    None\n                }\n            } else {\n                None\n            }\n        },\n        PatKind::Expr(PatExpr {\n            kind: PatExprKind::Path(path),\n            hir_id,\n            ..\n        }) => {\n            if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(path, *hir_id)\n                && let Some(variant_id) = cx.tcx.opt_parent(ctor_id)\n            {\n                let method = if cx.tcx.lang_items().option_none_variant() == Some(variant_id) {\n                    \"is_none()\"\n                } else if cx.tcx.lang_items().poll_pending_variant() == Some(variant_id) {\n                    \"is_pending()\"\n                } else {\n                    return None;\n                };\n                // `None` and `Pending` don't have an inner type.\n                Some((method, cx.tcx.types.unit))\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\nfn find_method_sugg_for_if_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    let_pat: &Pat<'_>,\n    let_expr: &'tcx Expr<'_>,\n    keyword: &'static str,\n    has_else: bool,\n    let_span: Span,\n) {\n    // also look inside refs\n    // if we have &None for example, peel it so we can detect \"if let None = x\"\n    let check_pat = match let_pat.kind {\n        PatKind::Ref(inner, _pinnedness, _mutability) => inner,\n        _ => let_pat,\n    };\n    let op_ty = cx.typeck_results().expr_ty(let_expr);\n    // Determine which function should be used, and the type contained by the corresponding\n    // variant.\n    let Some((good_method, inner_ty)) = find_method_and_type(cx, check_pat, op_ty) else {\n        return;\n    };\n\n    // If this is the last expression in a block or there is an else clause then the whole\n    // type needs to be considered, not just the inner type of the branch being matched on.\n    // Note the last expression in a block is dropped after all local bindings.\n    let check_ty = if has_else\n        || (keyword == \"if\" && matches!(cx.tcx.hir_parent_iter(expr.hir_id).next(), Some((_, Node::Block(..)))))\n    {\n        op_ty\n    } else {\n        inner_ty\n    };\n\n    // All temporaries created in the scrutinee expression are dropped at the same time as the\n    // scrutinee would be, so they have to be considered as well.\n    // e.g. in `if let Some(x) = foo.lock().unwrap().baz.as_ref() { .. }` the lock will be held\n    // for the duration if body.\n    let needs_drop = needs_ordered_drop(cx, check_ty) || any_temporaries_need_ordered_drop(cx, let_expr);\n\n    // check that `while_let_on_iterator` lint does not trigger\n    if keyword == \"while\"\n        && let ExprKind::MethodCall(method_path, _, [], _) = let_expr.kind\n        && method_path.ident.name == sym::next\n        && cx.ty_based_def(let_expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n    {\n        return;\n    }\n\n    let result_expr = match &let_expr.kind {\n        ExprKind::AddrOf(_, _, borrowed) => borrowed,\n        ExprKind::Unary(UnOp::Deref, deref) => deref,\n        _ => let_expr,\n    };\n\n    span_lint_and_then(\n        cx,\n        REDUNDANT_PATTERN_MATCHING,\n        let_pat.span,\n        format!(\"redundant pattern matching, consider using `{good_method}`\"),\n        |diag| {\n            // if/while let ... = ... { ... }\n            // ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n            let expr_span = expr.span;\n            let ctxt = expr.span.ctxt();\n\n            // if/while let ... = ... { ... }\n            // ^^^^^^^^^^^^^^^^^^^^^^\n            let span = expr_span.until(let_span.shrink_to_hi());\n\n            let mut app = if needs_drop {\n                Applicability::MaybeIncorrect\n            } else {\n                Applicability::MachineApplicable\n            };\n\n            let sugg = Sugg::hir_with_context(cx, result_expr, ctxt, \"_\", &mut app)\n                .maybe_paren()\n                .to_string();\n\n            diag.span_suggestion(span, \"try\", format!(\"{keyword} {sugg}.{good_method}\"), app);\n\n            if needs_drop {\n                diag.note(\"this will change drop order of the result, as well as all temporaries\");\n                diag.note(\"add `#[allow(clippy::redundant_pattern_matching)]` if this is important\");\n            }\n        },\n    );\n}\n\npub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) {\n    if let Ok(arms) = arms.try_into() // TODO: use `slice::as_array` once stabilized\n        && let Some((good_method, maybe_guard)) = found_good_method(cx, arms)\n    {\n        let expr_span = is_expn_of(expr.span, sym::matches).unwrap_or(expr.span);\n\n        let result_expr = match &op.kind {\n            ExprKind::AddrOf(_, _, borrowed) => borrowed,\n            _ => op,\n        };\n        let mut app = Applicability::MachineApplicable;\n        let receiver_sugg = Sugg::hir_with_context(cx, result_expr, expr_span.ctxt(), \"_\", &mut app).maybe_paren();\n        let mut sugg = format!(\"{receiver_sugg}.{good_method}\");\n\n        if let Some(guard) = maybe_guard {\n            // wow, the HIR for match guards in `PAT if let PAT = expr && expr => ...` is annoying!\n            // `guard` here is `Guard::If` with the let expression somewhere deep in the tree of exprs,\n            // counter to the intuition that it should be `Guard::IfLet`, so we need another check\n            // to see that there aren't any let chains anywhere in the guard, as that would break\n            // if we suggest `t.is_none() && (let X = y && z)` for:\n            // `match t { None if let X = y && z => true, _ => false }`\n            let has_nested_let_chain = for_each_expr_without_closures(guard, |expr| {\n                if matches!(expr.kind, ExprKind::Let(..)) {\n                    ControlFlow::Break(())\n                } else {\n                    ControlFlow::Continue(())\n                }\n            })\n            .is_some();\n\n            if has_nested_let_chain {\n                return;\n            }\n\n            let guard = Sugg::hir_with_context(cx, guard, expr_span.ctxt(), \"..\", &mut app);\n            let _ = write!(sugg, \" && {}\", guard.maybe_paren());\n        }\n\n        span_lint_and_sugg(\n            cx,\n            REDUNDANT_PATTERN_MATCHING,\n            expr_span,\n            format!(\"redundant pattern matching, consider using `{good_method}`\"),\n            \"try\",\n            sugg,\n            app,\n        );\n    }\n}\n\nfn found_good_method<'tcx>(\n    cx: &LateContext<'_>,\n    arms: &'tcx [Arm<'tcx>; 2],\n) -> Option<(&'static str, Option<&'tcx Expr<'tcx>>)> {\n    match (&arms[0].pat.kind, &arms[1].pat.kind) {\n        (PatKind::TupleStruct(path_left, [pattern_left], _), PatKind::TupleStruct(path_right, [pattern_right], _)) => {\n            if let (PatKind::Wild, PatKind::Wild) = (&pattern_left.kind, &pattern_right.kind) {\n                find_good_method_for_match(\n                    cx,\n                    arms,\n                    path_left,\n                    path_right,\n                    Item::Lang(ResultOk),\n                    Item::Lang(ResultErr),\n                    \"is_ok()\",\n                    \"is_err()\",\n                )\n                .or_else(|| {\n                    find_good_method_for_match(\n                        cx,\n                        arms,\n                        path_left,\n                        path_right,\n                        Item::Diag(sym::IpAddr, sym::V4),\n                        Item::Diag(sym::IpAddr, sym::V6),\n                        \"is_ipv4()\",\n                        \"is_ipv6()\",\n                    )\n                })\n            } else {\n                None\n            }\n        },\n        (\n            PatKind::TupleStruct(path_left, [pattern], _),\n            PatKind::Expr(PatExpr {\n                kind: PatExprKind::Path(path_right),\n                ..\n            }),\n        )\n        | (\n            PatKind::Expr(PatExpr {\n                kind: PatExprKind::Path(path_left),\n                ..\n            }),\n            PatKind::TupleStruct(path_right, [pattern], _),\n        ) => {\n            if let PatKind::Wild = pattern.kind {\n                find_good_method_for_match(\n                    cx,\n                    arms,\n                    path_left,\n                    path_right,\n                    Item::Lang(OptionSome),\n                    Item::Lang(OptionNone),\n                    \"is_some()\",\n                    \"is_none()\",\n                )\n                .or_else(|| {\n                    find_good_method_for_match(\n                        cx,\n                        arms,\n                        path_left,\n                        path_right,\n                        Item::Lang(PollReady),\n                        Item::Lang(PollPending),\n                        \"is_ready()\",\n                        \"is_pending()\",\n                    )\n                })\n            } else {\n                None\n            }\n        },\n        (PatKind::TupleStruct(path_left, [pattern], _), PatKind::Wild) => {\n            if let PatKind::Wild = pattern.kind {\n                get_good_method(cx, arms, path_left)\n            } else {\n                None\n            }\n        },\n        (\n            PatKind::Expr(PatExpr {\n                kind: PatExprKind::Path(path_left),\n                ..\n            }),\n            PatKind::Wild,\n        ) => get_good_method(cx, arms, path_left),\n        _ => None,\n    }\n}\n\nfn get_ident(path: &QPath<'_>) -> Option<rustc_span::symbol::Ident> {\n    match path {\n        QPath::Resolved(_, path) => {\n            let name = path.segments[0].ident;\n            Some(name)\n        },\n        QPath::TypeRelative(..) => None,\n    }\n}\n\nfn get_good_method<'tcx>(\n    cx: &LateContext<'_>,\n    arms: &'tcx [Arm<'tcx>; 2],\n    path_left: &QPath<'_>,\n) -> Option<(&'static str, Option<&'tcx Expr<'tcx>>)> {\n    let ident = get_ident(path_left)?;\n\n    let (expected_item_left, should_be_left, should_be_right) = match ident.name {\n        sym::Ok => (Item::Lang(ResultOk), \"is_ok()\", \"is_err()\"),\n        sym::Err => (Item::Lang(ResultErr), \"is_err()\", \"is_ok()\"),\n        sym::Some => (Item::Lang(OptionSome), \"is_some()\", \"is_none()\"),\n        sym::None => (Item::Lang(OptionNone), \"is_none()\", \"is_some()\"),\n        sym::Ready => (Item::Lang(PollReady), \"is_ready()\", \"is_pending()\"),\n        sym::Pending => (Item::Lang(PollPending), \"is_pending()\", \"is_ready()\"),\n        sym::V4 => (Item::Diag(sym::IpAddr, sym::V4), \"is_ipv4()\", \"is_ipv6()\"),\n        sym::V6 => (Item::Diag(sym::IpAddr, sym::V6), \"is_ipv6()\", \"is_ipv4()\"),\n        _ => return None,\n    };\n    find_good_method_for_matches_macro(cx, arms, path_left, expected_item_left, should_be_left, should_be_right)\n}\n\n#[derive(Clone, Copy)]\nenum Item {\n    Lang(LangItem),\n    Diag(Symbol, Symbol),\n}\n\nfn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expected_item: Item) -> bool {\n    let Some(id) = cx.typeck_results().qpath_res(path, pat.hir_id).opt_def_id() else {\n        return false;\n    };\n\n    match expected_item {\n        Item::Lang(expected_lang_item) => cx\n            .tcx\n            .lang_items()\n            .get(expected_lang_item)\n            .is_some_and(|expected_id| cx.tcx.parent(id) == expected_id),\n        Item::Diag(expected_ty, expected_variant) => {\n            let ty = cx.typeck_results().pat_ty(pat);\n\n            if ty.is_diag_item(cx, expected_ty) {\n                let variant = ty\n                    .ty_adt_def()\n                    .expect(\"struct pattern type is not an ADT\")\n                    .variant_of_res(cx.qpath_res(path, pat.hir_id));\n\n                return variant.name == expected_variant;\n            }\n\n            false\n        },\n    }\n}\n\n#[expect(clippy::too_many_arguments)]\nfn find_good_method_for_match<'a, 'tcx>(\n    cx: &LateContext<'_>,\n    arms: &'tcx [Arm<'tcx>; 2],\n    path_left: &QPath<'_>,\n    path_right: &QPath<'_>,\n    expected_item_left: Item,\n    expected_item_right: Item,\n    should_be_left: &'a str,\n    should_be_right: &'a str,\n) -> Option<(&'a str, Option<&'tcx Expr<'tcx>>)> {\n    let first_pat = arms[0].pat;\n    let second_pat = arms[1].pat;\n\n    let body_node_pair = if (is_pat_variant(cx, first_pat, path_left, expected_item_left))\n        && (is_pat_variant(cx, second_pat, path_right, expected_item_right))\n    {\n        (&arms[0].body.kind, &arms[1].body.kind)\n    } else if (is_pat_variant(cx, first_pat, path_left, expected_item_right))\n        && (is_pat_variant(cx, second_pat, path_right, expected_item_left))\n    {\n        (&arms[1].body.kind, &arms[0].body.kind)\n    } else {\n        return None;\n    };\n\n    match body_node_pair {\n        (ExprKind::Lit(lit_left), ExprKind::Lit(lit_right)) => match (&lit_left.node, &lit_right.node) {\n            (LitKind::Bool(true), LitKind::Bool(false)) => Some((should_be_left, arms[0].guard)),\n            (LitKind::Bool(false), LitKind::Bool(true)) => Some((should_be_right, arms[1].guard)),\n            _ => None,\n        },\n        _ => None,\n    }\n}\n\nfn find_good_method_for_matches_macro<'a, 'tcx>(\n    cx: &LateContext<'_>,\n    arms: &'tcx [Arm<'tcx>; 2],\n    path_left: &QPath<'_>,\n    expected_item_left: Item,\n    should_be_left: &'a str,\n    should_be_right: &'a str,\n) -> Option<(&'a str, Option<&'tcx Expr<'tcx>>)> {\n    let first_pat = arms[0].pat;\n\n    let body_node_pair = if is_pat_variant(cx, first_pat, path_left, expected_item_left) {\n        (&arms[0].body.kind, &arms[1].body.kind)\n    } else {\n        return None;\n    };\n\n    match body_node_pair {\n        (ExprKind::Lit(lit_left), ExprKind::Lit(lit_right)) => match (&lit_left.node, &lit_right.node) {\n            (LitKind::Bool(true), LitKind::Bool(false)) => Some((should_be_left, arms[0].guard)),\n            (LitKind::Bool(false), LitKind::Bool(true)) => Some((should_be_right, arms[1].guard)),\n            _ => None,\n        },\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_hir::{Pat, PatKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::REST_PAT_IN_FULLY_BOUND_STRUCTS;\n\npub(crate) fn check(cx: &LateContext<'_>, pat: &Pat<'_>) {\n    if !pat.span.from_expansion()\n        && let PatKind::Struct(QPath::Resolved(_, path), fields, Some(dotdot)) = pat.kind\n        && let Some(def_id) = path.res.opt_def_id()\n        && let ty = cx.tcx.type_of(def_id).instantiate_identity()\n        && let ty::Adt(def, _) = ty.kind()\n        && (def.is_struct() || def.is_union())\n        && fields.len() == def.non_enum_variant().fields.len()\n        && !def.non_enum_variant().is_field_list_non_exhaustive()\n    {\n        span_lint_and_then(\n            cx,\n            REST_PAT_IN_FULLY_BOUND_STRUCTS,\n            pat.span,\n            \"unnecessary use of `..` pattern in struct binding. All fields were already bound\",\n            |diag| {\n                diag.span_suggestion_verbose(\n                    dotdot,\n                    \"consider removing `..` from this binding\",\n                    \"\",\n                    rustc_errors::Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/significant_drop_in_scrutinee.rs",
    "content": "use std::ops::ControlFlow;\n\nuse crate::FxHashSet;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{first_line_of_span, indent_of, snippet};\nuse clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy};\nuse clippy_utils::{get_builtin_attr, is_lint_allowed, sym};\nuse itertools::Itertools;\nuse rustc_ast::Mutability;\nuse rustc_data_structures::fx::FxIndexSet;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{Arm, Expr, ExprKind, MatchSource};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::{GenericArgKind, RegionKind, Ty, TypeVisitableExt};\nuse rustc_span::Span;\n\nuse super::SIGNIFICANT_DROP_IN_SCRUTINEE;\n\npub(super) fn check_match<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    scrutinee: &'tcx Expr<'_>,\n    arms: &'tcx [Arm<'_>],\n    source: MatchSource,\n) {\n    if is_lint_allowed(cx, SIGNIFICANT_DROP_IN_SCRUTINEE, expr.hir_id) {\n        return;\n    }\n\n    let scrutinee = match (source, &scrutinee.kind) {\n        (MatchSource::ForLoopDesugar, ExprKind::Call(_, [e])) => e,\n        _ => scrutinee,\n    };\n\n    let message = if source == MatchSource::Normal {\n        \"temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\"\n    } else {\n        \"temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression\"\n    };\n\n    let arms = arms.iter().map(|arm| arm.body).collect::<Vec<_>>();\n\n    check(cx, expr, scrutinee, &arms, message, Suggestion::Emit);\n}\n\npub(super) fn check_if_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    scrutinee: &'tcx Expr<'_>,\n    if_then: &'tcx Expr<'_>,\n    if_else: Option<&'tcx Expr<'_>>,\n) {\n    if is_lint_allowed(cx, SIGNIFICANT_DROP_IN_SCRUTINEE, expr.hir_id) {\n        return;\n    }\n\n    let message =\n        \"temporary with significant `Drop` in `if let` scrutinee will live until the end of the `if let` expression\";\n\n    if let Some(if_else) = if_else {\n        check(cx, expr, scrutinee, &[if_then, if_else], message, Suggestion::Emit);\n    } else {\n        check(cx, expr, scrutinee, &[if_then], message, Suggestion::Emit);\n    }\n}\n\npub(super) fn check_while_let<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    scrutinee: &'tcx Expr<'_>,\n    body: &'tcx Expr<'_>,\n) {\n    if is_lint_allowed(cx, SIGNIFICANT_DROP_IN_SCRUTINEE, expr.hir_id) {\n        return;\n    }\n\n    check(\n        cx,\n        expr,\n        scrutinee,\n        &[body],\n        \"temporary with significant `Drop` in `while let` scrutinee will live until the end of the `while let` expression\",\n        // Don't emit wrong suggestions: We cannot fix the significant drop in the `while let` scrutinee by simply\n        // moving it out. We need to change the `while` to a `loop` instead.\n        Suggestion::DontEmit,\n    );\n}\n\n#[derive(Copy, Clone, Debug)]\nenum Suggestion {\n    Emit,\n    DontEmit,\n}\n\nfn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    scrutinee: &'tcx Expr<'_>,\n    arms: &[&'tcx Expr<'_>],\n    message: &'static str,\n    sugg: Suggestion,\n) {\n    let mut helper = SigDropHelper::new(cx);\n    let suggestions = helper.find_sig_drop(scrutinee);\n\n    for found in suggestions {\n        span_lint_and_then(cx, SIGNIFICANT_DROP_IN_SCRUTINEE, found.found_span, message, |diag| {\n            match sugg {\n                Suggestion::Emit => set_suggestion(diag, cx, expr, found),\n                Suggestion::DontEmit => (),\n            }\n\n            let s = Span::new(expr.span.hi(), expr.span.hi(), expr.span.ctxt(), None);\n            diag.span_label(s, \"temporary lives until here\");\n            for span in has_significant_drop_in_arms(cx, arms) {\n                diag.span_label(span, \"another value with significant `Drop` created here\");\n            }\n            diag.note(\"this might lead to deadlocks or other unexpected behavior\");\n        });\n    }\n}\n\nfn set_suggestion<'tcx>(diag: &mut Diag<'_, ()>, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, found: FoundSigDrop) {\n    let original = snippet(cx, found.found_span, \"..\");\n    let trailing_indent = \" \".repeat(indent_of(cx, found.found_span).unwrap_or(0));\n\n    let replacement = {\n        let (def_part, deref_part) = if found.is_unit_return_val {\n            (\"\", String::new())\n        } else {\n            (\"let value = \", \"*\".repeat(found.peel_ref_times))\n        };\n        format!(\"{def_part}{deref_part}{original};\\n{trailing_indent}\")\n    };\n\n    let suggestion_message = if found.peel_ref_times == 0 {\n        \"try moving the temporary above the match\"\n    } else {\n        \"try moving the temporary above the match and create a copy\"\n    };\n\n    let scrutinee_replacement = if found.is_unit_return_val {\n        \"()\".to_owned()\n    } else if found.peel_ref_times == 0 {\n        \"value\".to_owned()\n    } else {\n        let ref_part = \"&\".repeat(found.peel_ref_times);\n        format!(\"({ref_part}value)\")\n    };\n\n    diag.multipart_suggestion(\n        suggestion_message,\n        vec![\n            (first_line_of_span(cx, expr.span).shrink_to_lo(), replacement),\n            (found.found_span, scrutinee_replacement),\n        ],\n        Applicability::MaybeIncorrect,\n    );\n}\n\nstruct SigDropChecker<'a, 'tcx> {\n    seen_types: FxHashSet<Ty<'tcx>>,\n    cx: &'a LateContext<'tcx>,\n}\n\nimpl<'a, 'tcx> SigDropChecker<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>) -> SigDropChecker<'a, 'tcx> {\n        SigDropChecker {\n            seen_types: FxHashSet::default(),\n            cx,\n        }\n    }\n\n    fn is_sig_drop_expr(&mut self, ex: &'tcx Expr<'_>) -> bool {\n        !ex.is_syntactic_place_expr() && self.has_sig_drop_attr(self.cx.typeck_results().expr_ty(ex))\n    }\n\n    fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool {\n        self.seen_types.clear();\n        self.has_sig_drop_attr_impl(ty)\n    }\n\n    fn has_sig_drop_attr_impl(&mut self, ty: Ty<'tcx>) -> bool {\n        if let Some(adt) = ty.ty_adt_def()\n            && get_builtin_attr(\n                self.cx.sess(),\n                #[allow(deprecated)]\n                self.cx.tcx.get_all_attrs(adt.did()),\n                sym::has_significant_drop,\n            )\n            .count()\n                > 0\n        {\n            return true;\n        }\n\n        if !self.seen_types.insert(ty) {\n            return false;\n        }\n\n        match ty.kind() {\n            rustc_middle::ty::Adt(adt, args) => {\n                // if some field has significant drop,\n                adt.all_fields()\n                    .map(|field| field.ty(self.cx.tcx, args))\n                    .any(|ty| self.has_sig_drop_attr_impl(ty))\n                    // or if there is no generic lifetime and..\n                    // (to avoid false positive on `Ref<'a, MutexGuard<Foo>>`)\n                    || (args\n                        .iter()\n                        .all(|arg| !matches!(arg.kind(), GenericArgKind::Lifetime(_)))\n                        // some generic parameter has significant drop\n                        // (to avoid false negative on `Box<MutexGuard<Foo>>`)\n                        && args\n                            .iter()\n                            .filter_map(|arg| match arg.kind() {\n                                GenericArgKind::Type(ty) => Some(ty),\n                                _ => None,\n                            })\n                            .any(|ty| self.has_sig_drop_attr_impl(ty)))\n            },\n            rustc_middle::ty::Tuple(tys) => tys.iter().any(|ty| self.has_sig_drop_attr_impl(ty)),\n            rustc_middle::ty::Array(ty, _) | rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr_impl(*ty),\n            _ => false,\n        }\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]\nenum SigDropHolder {\n    /// No values with significant drop present in this expression.\n    ///\n    /// Expressions that we've emitted lints do not count.\n    #[default]\n    None,\n    /// Some field in this expression references to values with significant drop.\n    ///\n    /// Example: `(1, &data.lock().field)`.\n    PackedRef,\n    /// The value of this expression references to values with significant drop.\n    ///\n    /// Example: `data.lock().field`.\n    DirectRef,\n    /// This expression should be moved out to avoid significant drop in scrutinee.\n    Moved,\n}\n\nstruct SigDropHelper<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    parent_expr: Option<&'tcx Expr<'tcx>>,\n    sig_drop_holder: SigDropHolder,\n    sig_drop_spans: Vec<FoundSigDrop>,\n    sig_drop_checker: SigDropChecker<'a, 'tcx>,\n}\n\n#[derive(Clone, Copy, Debug)]\nstruct FoundSigDrop {\n    found_span: Span,\n    is_unit_return_val: bool,\n    peel_ref_times: usize,\n}\n\nimpl<'a, 'tcx> SigDropHelper<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>) -> SigDropHelper<'a, 'tcx> {\n        SigDropHelper {\n            cx,\n            parent_expr: None,\n            sig_drop_holder: SigDropHolder::None,\n            sig_drop_spans: Vec::new(),\n            sig_drop_checker: SigDropChecker::new(cx),\n        }\n    }\n\n    fn find_sig_drop(&mut self, match_expr: &'tcx Expr<'_>) -> Vec<FoundSigDrop> {\n        self.visit_expr(match_expr);\n\n        core::mem::take(&mut self.sig_drop_spans)\n    }\n\n    fn replace_current_sig_drop(&mut self, found_span: Span, is_unit_return_val: bool, peel_ref_times: usize) {\n        self.sig_drop_spans.clear();\n        self.sig_drop_spans.push(FoundSigDrop {\n            found_span,\n            is_unit_return_val,\n            peel_ref_times,\n        });\n    }\n\n    fn try_move_sig_drop(&mut self, expr: &'tcx Expr<'_>, parent_expr: &'tcx Expr<'_>) {\n        if self.sig_drop_holder == SigDropHolder::Moved {\n            self.sig_drop_holder = SigDropHolder::None;\n        }\n\n        if self.sig_drop_holder == SigDropHolder::DirectRef {\n            self.sig_drop_holder = SigDropHolder::PackedRef;\n            self.try_move_sig_drop_direct_ref(expr, parent_expr);\n        } else if self.sig_drop_checker.is_sig_drop_expr(expr) {\n            // The values with significant drop can be moved to some other functions. For example, consider\n            // `drop(data.lock())`. We use `SigDropHolder::None` here to avoid emitting lints in such scenarios.\n            self.sig_drop_holder = SigDropHolder::None;\n            self.try_move_sig_drop_direct_ref(expr, parent_expr);\n        }\n\n        if self.sig_drop_holder != SigDropHolder::None {\n            let parent_ty = self.cx.typeck_results().expr_ty(parent_expr);\n            if !parent_ty.has_erased_regions() && !parent_expr.is_syntactic_place_expr() {\n                self.replace_current_sig_drop(parent_expr.span, parent_ty.is_unit(), 0);\n                self.sig_drop_holder = SigDropHolder::Moved;\n            }\n\n            let (peel_ref_ty, peel_ref_times) = ty_peel_refs(parent_ty);\n            if !peel_ref_ty.has_erased_regions() && is_copy(self.cx, peel_ref_ty) {\n                self.replace_current_sig_drop(parent_expr.span, peel_ref_ty.is_unit(), peel_ref_times);\n                self.sig_drop_holder = SigDropHolder::Moved;\n            }\n        }\n    }\n\n    fn try_move_sig_drop_direct_ref(&mut self, expr: &'tcx Expr<'_>, parent_expr: &'tcx Expr<'_>) {\n        let arg_idx = match parent_expr.kind {\n            ExprKind::MethodCall(_, receiver, exprs, _) => std::iter::once(receiver)\n                .chain(exprs.iter())\n                .find_position(|ex| ex.hir_id == expr.hir_id)\n                .map(|(idx, _)| idx),\n            ExprKind::Call(_, exprs) => exprs\n                .iter()\n                .find_position(|ex| ex.hir_id == expr.hir_id)\n                .map(|(idx, _)| idx),\n            ExprKind::Binary(_, lhs, rhs) | ExprKind::AssignOp(_, lhs, rhs) => [lhs, rhs]\n                .iter()\n                .find_position(|ex| ex.hir_id == expr.hir_id)\n                .map(|(idx, _)| idx),\n            ExprKind::Unary(_, ex) => (ex.hir_id == expr.hir_id).then_some(0),\n            _ => {\n                // Here we assume that all other expressions create or propagate the reference to the value with\n                // significant drop.\n                self.sig_drop_holder = SigDropHolder::DirectRef;\n                return;\n            },\n        };\n        let Some(arg_idx) = arg_idx else {\n            return;\n        };\n\n        let fn_sig = if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(parent_expr.hir_id) {\n            self.cx.tcx.fn_sig(def_id).instantiate_identity()\n        } else {\n            return;\n        };\n\n        let input_re = if let Some(input_ty) = fn_sig.skip_binder().inputs().get(arg_idx)\n            && let rustc_middle::ty::Ref(input_re, _, _) = input_ty.kind()\n        {\n            input_re\n        } else {\n            return;\n        };\n\n        // Late bound lifetime parameters are not related to any constraints, so we can track them in a very\n        // simple manner. For other lifetime parameters, we give up and update the state to `PackedRef`.\n        let RegionKind::ReBound(_, input_re_bound) = input_re.kind() else {\n            self.sig_drop_holder = SigDropHolder::PackedRef;\n            return;\n        };\n        let contains_input_re = |re_bound| {\n            if re_bound == input_re_bound {\n                ControlFlow::Break(())\n            } else {\n                ControlFlow::Continue(())\n            }\n        };\n\n        let output_ty = fn_sig.skip_binder().output();\n        if let rustc_middle::ty::Ref(output_re, peel_ref_ty, _) = output_ty.kind()\n            && input_re == output_re\n            && for_each_top_level_late_bound_region(*peel_ref_ty, contains_input_re).is_continue()\n        {\n            // We're lucky! The output type is still a direct reference to the value with significant drop.\n            self.sig_drop_holder = SigDropHolder::DirectRef;\n        } else if for_each_top_level_late_bound_region(output_ty, contains_input_re).is_continue() {\n            // The lifetime to the value with significant drop goes away. So we can emit a lint that suggests to\n            // move the expression out.\n            self.replace_current_sig_drop(parent_expr.span, output_ty.is_unit(), 0);\n            self.sig_drop_holder = SigDropHolder::Moved;\n        } else {\n            // TODO: The lifetime is still there but it's for a inner type. For instance, consider\n            // `Some(&mutex.lock().field)`, which has a type of `Option<&u32>`. How to address this scenario?\n            self.sig_drop_holder = SigDropHolder::PackedRef;\n        }\n    }\n}\n\nfn ty_peel_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize) {\n    let mut n = 0;\n    while let rustc_middle::ty::Ref(_, new_ty, Mutability::Not) = ty.kind() {\n        ty = *new_ty;\n        n += 1;\n    }\n    (ty, n)\n}\n\nimpl<'tcx> Visitor<'tcx> for SigDropHelper<'_, 'tcx> {\n    fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {\n        // We've emitted a lint on some neighborhood expression. That lint will suggest to move out the\n        // _parent_ expression (not the expression itself). Since we decide to move out the parent\n        // expression, it is pointless to continue to process the current expression.\n        if self.sig_drop_holder == SigDropHolder::Moved {\n            return;\n        }\n\n        // These states are of neighborhood expressions. We save and clear them here, and we'll later merge\n        // the states of the current expression with them at the end of the method.\n        let sig_drop_holder_before = core::mem::take(&mut self.sig_drop_holder);\n        let sig_drop_spans_before = core::mem::take(&mut self.sig_drop_spans);\n        let parent_expr_before = self.parent_expr.replace(ex);\n\n        match ex.kind {\n            // Skip blocks because values in blocks will be dropped as usual, and await\n            // desugaring because temporary insides the future will have been dropped.\n            ExprKind::Block(..) | ExprKind::Match(_, _, MatchSource::AwaitDesugar) => (),\n            _ => walk_expr(self, ex),\n        }\n\n        if let Some(parent_ex) = parent_expr_before {\n            match parent_ex.kind {\n                ExprKind::Assign(lhs, _, _) | ExprKind::AssignOp(_, lhs, _)\n                    if lhs.hir_id == ex.hir_id && self.sig_drop_holder == SigDropHolder::Moved =>\n                {\n                    // Never move out only the assignee. Instead, we should always move out the whole assignment.\n                    self.replace_current_sig_drop(parent_ex.span, true, 0);\n                },\n                _ => {\n                    self.try_move_sig_drop(ex, parent_ex);\n                },\n            }\n        }\n\n        self.sig_drop_holder = std::cmp::max(self.sig_drop_holder, sig_drop_holder_before);\n\n        // We do not need those old spans in neighborhood expressions if we emit a lint that suggests to\n        // move out the _parent_ expression (i.e., `self.sig_drop_holder == SigDropHolder::Moved`).\n        if self.sig_drop_holder != SigDropHolder::Moved {\n            let mut sig_drop_spans = sig_drop_spans_before;\n            sig_drop_spans.append(&mut self.sig_drop_spans);\n            self.sig_drop_spans = sig_drop_spans;\n        }\n\n        self.parent_expr = parent_expr_before;\n    }\n}\n\nstruct ArmSigDropHelper<'a, 'tcx> {\n    sig_drop_checker: SigDropChecker<'a, 'tcx>,\n    found_sig_drop_spans: FxIndexSet<Span>,\n}\n\nimpl<'a, 'tcx> ArmSigDropHelper<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>) -> ArmSigDropHelper<'a, 'tcx> {\n        ArmSigDropHelper {\n            sig_drop_checker: SigDropChecker::new(cx),\n            found_sig_drop_spans: FxIndexSet::<Span>::default(),\n        }\n    }\n}\n\nfn has_significant_drop_in_arms<'tcx>(cx: &LateContext<'tcx>, arms: &[&'tcx Expr<'_>]) -> FxIndexSet<Span> {\n    let mut helper = ArmSigDropHelper::new(cx);\n    for arm in arms {\n        helper.visit_expr(arm);\n    }\n    helper.found_sig_drop_spans\n}\n\nimpl<'tcx> Visitor<'tcx> for ArmSigDropHelper<'_, 'tcx> {\n    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {\n        if self.sig_drop_checker.is_sig_drop_expr(ex) {\n            self.found_sig_drop_spans.insert(ex.span);\n            return;\n        }\n        walk_expr(self, ex);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/single_match.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{\n    SpanRangeExt, expr_block, snippet, snippet_block_with_context, snippet_with_applicability, snippet_with_context,\n};\nuse clippy_utils::ty::{implements_trait, peel_and_count_ty_refs};\nuse clippy_utils::{is_lint_allowed, is_unit_expr, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs, sym};\nuse core::ops::ControlFlow;\nuse rustc_arena::DroplessArena;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::intravisit::{Visitor, walk_pat};\nuse rustc_hir::{Arm, Expr, ExprKind, HirId, Node, Pat, PatExpr, PatExprKind, PatKind, QPath, StmtKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, AdtDef, TyCtxt, TypeckResults, VariantDef};\nuse rustc_span::Span;\n\nuse super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE};\n\n/// Checks if there are comments contained within a span.\n/// This is a very \"naive\" check, as it just looks for the literal characters // and /* in the\n/// source text. This won't be accurate if there are potentially expressions contained within the\n/// span, e.g. a string literal `\"//\"`, but we know that this isn't the case for empty\n/// match arms.\nfn empty_arm_has_comment(cx: &LateContext<'_>, span: Span) -> bool {\n    span.check_source_text(cx, |text| text.as_bytes().windows(2).any(|w| w == b\"//\" || w == b\"/*\"))\n}\n\npub(crate) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    ex: &'tcx Expr<'_>,\n    arms: &'tcx [Arm<'_>],\n    expr: &'tcx Expr<'_>,\n    contains_comments: bool,\n) {\n    if let [arm1, arm2] = arms\n        && !arms.iter().any(|arm| arm.guard.is_some() || arm.pat.span.from_expansion())\n        && !expr.span.from_expansion()\n        // don't lint for or patterns for now, this makes\n        // the lint noisy in unnecessary situations\n        && !matches!(arm1.pat.kind, PatKind::Or(..))\n    {\n        let els = if is_unit_expr(peel_blocks(arm2.body)) && !empty_arm_has_comment(cx, arm2.body.span) {\n            None\n        } else if let ExprKind::Block(block, _) = arm2.body.kind {\n            if matches!((block.stmts, block.expr), ([], Some(_)) | ([_], None)) {\n                // single statement/expr \"else\" block, don't lint\n                return;\n            }\n            // block with 2+ statements or 1 expr and 1+ statement\n            Some(arm2.body)\n        } else {\n            // not a block or an empty block w/ comments, don't lint\n            return;\n        };\n\n        let typeck = cx.typeck_results();\n        if *typeck.expr_ty(ex).peel_refs().kind() != ty::Bool || is_lint_allowed(cx, MATCH_BOOL, ex.hir_id) {\n            let mut v = PatVisitor {\n                typeck,\n                has_enum: false,\n            };\n            if v.visit_pat(arm2.pat).is_break() {\n                return;\n            }\n            if v.has_enum {\n                let cx = PatCtxt {\n                    tcx: cx.tcx,\n                    typeck,\n                    arena: DroplessArena::default(),\n                };\n                let mut state = PatState::Other;\n                if !(state.add_pat(&cx, arm2.pat) || state.add_pat(&cx, arm1.pat)) {\n                    // Don't lint if the pattern contains an enum which doesn't have a wild match.\n                    return;\n                }\n            }\n\n            report_single_pattern(cx, ex, arm1, expr, els, contains_comments);\n        }\n    }\n}\n\nfn report_single_pattern(\n    cx: &LateContext<'_>,\n    ex: &Expr<'_>,\n    arm: &Arm<'_>,\n    expr: &Expr<'_>,\n    els: Option<&Expr<'_>>,\n    contains_comments: bool,\n) {\n    let lint = if els.is_some() { SINGLE_MATCH_ELSE } else { SINGLE_MATCH };\n    let ctxt = expr.span.ctxt();\n    let note = |diag: &mut Diag<'_, ()>| {\n        if contains_comments {\n            diag.note(\"you might want to preserve the comments from inside the `match`\");\n        }\n    };\n    let mut app = if contains_comments {\n        Applicability::MaybeIncorrect\n    } else {\n        Applicability::MachineApplicable\n    };\n    let els_str = els.map_or(String::new(), |els| {\n        format!(\" else {}\", expr_block(cx, els, ctxt, \"..\", Some(expr.span), &mut app))\n    });\n\n    if ex.span.eq_ctxt(expr.span) && snippet(cx, ex.span, \"..\") == snippet(cx, arm.pat.span, \"..\") {\n        let msg = \"this pattern is irrefutable, `match` is useless\";\n        let (sugg, help) = if is_unit_expr(arm.body) {\n            (String::new(), \"`match` expression can be removed\")\n        } else {\n            let mut sugg = snippet_block_with_context(cx, arm.body.span, ctxt, \"..\", Some(expr.span), &mut app).0;\n            if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id)\n                && let StmtKind::Expr(_) = stmt.kind\n                && match arm.body.kind {\n                    ExprKind::Block(block, _) => block.span.from_expansion(),\n                    _ => true,\n                }\n            {\n                sugg.push(';');\n            }\n            (sugg, \"try\")\n        };\n        span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n            diag.span_suggestion(expr.span, help, sugg, app);\n            note(diag);\n        });\n        return;\n    }\n\n    let (pat, pat_ref_count) = peel_hir_pat_refs(arm.pat);\n    let (msg, sugg) = if let PatKind::Expr(_) = pat.kind\n        && let (ty, ty_ref_count, _) = peel_and_count_ty_refs(cx.typeck_results().expr_ty(ex))\n        && let Some(spe_trait_id) = cx.tcx.lang_items().structural_peq_trait()\n        && let Some(pe_trait_id) = cx.tcx.lang_items().eq_trait()\n        && (ty.is_integral()\n            || ty.is_char()\n            || ty.is_str()\n            || (implements_trait(cx, ty, spe_trait_id, &[]) && implements_trait(cx, ty, pe_trait_id, &[ty.into()])))\n    {\n        // scrutinee derives PartialEq and the pattern is a constant.\n        let pat_ref_count = match pat.kind {\n            // string literals are already a reference.\n            PatKind::Expr(PatExpr {\n                kind: PatExprKind::Lit { lit, negated: false },\n                ..\n            }) if lit.node.is_str() || lit.node.is_bytestr() => pat_ref_count + 1,\n            _ => pat_ref_count,\n        };\n\n        // References are implicitly removed when `deref_patterns` are used.\n        // They are implicitly added when match ergonomics are used.\n        let (ex, ref_or_deref_adjust) = if ty_ref_count > pat_ref_count {\n            let ref_count_diff = ty_ref_count - pat_ref_count;\n\n            // Try to remove address of expressions first.\n            let (ex, removed) = peel_n_hir_expr_refs(ex, ref_count_diff);\n\n            (ex, String::from(if ref_count_diff == removed { \"\" } else { \"&\" }))\n        } else {\n            (ex, \"*\".repeat(pat_ref_count - ty_ref_count))\n        };\n\n        let msg = \"you seem to be trying to use `match` for an equality check. Consider using `if`\";\n        let sugg = format!(\n            \"if {} == {}{} {}{els_str}\",\n            snippet_with_context(cx, ex.span, ctxt, \"..\", &mut app).0,\n            // PartialEq for different reference counts may not exist.\n            ref_or_deref_adjust,\n            snippet_with_applicability(cx, arm.pat.span, \"..\", &mut app),\n            expr_block(cx, arm.body, ctxt, \"..\", Some(expr.span), &mut app),\n        );\n        (msg, sugg)\n    } else {\n        let msg = \"you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\";\n        let sugg = format!(\n            \"if let {} = {} {}{els_str}\",\n            snippet_with_applicability(cx, arm.pat.span, \"..\", &mut app),\n            snippet_with_context(cx, ex.span, ctxt, \"..\", &mut app).0,\n            expr_block(cx, arm.body, ctxt, \"..\", Some(expr.span), &mut app),\n        );\n        (msg, sugg)\n    };\n\n    span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n        diag.span_suggestion(expr.span, \"try\", sugg, app);\n        note(diag);\n    });\n}\n\nstruct PatVisitor<'tcx> {\n    typeck: &'tcx TypeckResults<'tcx>,\n    has_enum: bool,\n}\nimpl<'tcx> Visitor<'tcx> for PatVisitor<'tcx> {\n    type Result = ControlFlow<()>;\n    fn visit_pat(&mut self, pat: &'tcx Pat<'_>) -> Self::Result {\n        if matches!(pat.kind, PatKind::Binding(..)) {\n            ControlFlow::Break(())\n        } else {\n            self.has_enum |= self.typeck.pat_ty(pat).ty_adt_def().is_some_and(AdtDef::is_enum);\n            walk_pat(self, pat)\n        }\n    }\n}\n\n/// The context needed to manipulate a `PatState`.\nstruct PatCtxt<'tcx> {\n    tcx: TyCtxt<'tcx>,\n    typeck: &'tcx TypeckResults<'tcx>,\n    arena: DroplessArena,\n}\n\n/// State for tracking whether a match can become non-exhaustive by adding a variant to a contained\n/// enum.\n///\n/// This treats certain std enums as if they will never be extended.\nenum PatState<'a> {\n    /// Either a wild match or an uninteresting type. Uninteresting types include:\n    /// * builtin types (e.g. `i32` or `!`)\n    /// * A struct/tuple/array containing only uninteresting types.\n    /// * A std enum containing only uninteresting types.\n    Wild,\n    /// A std enum we know won't be extended. Tracks the states of each variant separately.\n    ///\n    /// This is not used for `Option` since it uses the current pattern to track its state.\n    StdEnum(&'a mut [Self]),\n    /// Either the initial state for a pattern or a non-std enum. There is currently no need to\n    /// distinguish these cases.\n    ///\n    /// For non-std enums there's no need to track the state of sub-patterns as the state of just\n    /// this pattern on its own is enough for linting. Consider two cases:\n    /// * This enum has no wild match. This case alone is enough to determine we can lint.\n    /// * This enum has a wild match and therefore all sub-patterns also have a wild match.\n    ///\n    /// In both cases the sub patterns are not needed to determine whether to lint.\n    Other,\n}\nimpl<'a> PatState<'a> {\n    /// Adds a set of patterns as a product type to the current state. Returns whether or not the\n    /// current state is a wild match after the merge.\n    fn add_product_pat<'tcx>(\n        &mut self,\n        cx: &'a PatCtxt<'tcx>,\n        pats: impl IntoIterator<Item = &'tcx Pat<'tcx>>,\n    ) -> bool {\n        // Ideally this would actually keep track of the state separately for each pattern. Doing so would\n        // require implementing something similar to exhaustiveness checking which is a significant increase\n        // in complexity.\n        //\n        // For now treat this as a wild match only if all the sub-patterns are wild\n        let is_wild = pats.into_iter().all(|p| {\n            let mut state = Self::Other;\n            state.add_pat(cx, p)\n        });\n        if is_wild {\n            *self = Self::Wild;\n        }\n        is_wild\n    }\n\n    /// Attempts to get the state for the enum variant, initializing the current state if necessary.\n    fn get_std_enum_variant<'tcx>(\n        &mut self,\n        cx: &'a PatCtxt<'tcx>,\n        adt: AdtDef<'tcx>,\n        path: &'tcx QPath<'_>,\n        hir_id: HirId,\n    ) -> Option<(&mut Self, &'tcx VariantDef)> {\n        let states = match self {\n            Self::Wild => return None,\n            Self::Other => {\n                *self = Self::StdEnum(\n                    cx.arena\n                        .alloc_from_iter(std::iter::repeat_with(|| Self::Other).take(adt.variants().len())),\n                );\n                let Self::StdEnum(x) = self else {\n                    unreachable!();\n                };\n                x\n            },\n            Self::StdEnum(x) => x,\n        };\n        let i = match cx.typeck.qpath_res(path, hir_id) {\n            Res::Def(DefKind::Ctor(..), id) => adt.variant_index_with_ctor_id(id),\n            Res::Def(DefKind::Variant, id) => adt.variant_index_with_id(id),\n            _ => return None,\n        };\n        Some((&mut states[i.as_usize()], adt.variant(i)))\n    }\n\n    fn check_all_wild_enum(&mut self) -> bool {\n        if let Self::StdEnum(states) = self\n            && states.iter().all(|s| matches!(s, Self::Wild))\n        {\n            *self = Self::Wild;\n            true\n        } else {\n            false\n        }\n    }\n\n    #[expect(clippy::similar_names)]\n    fn add_struct_pats<'tcx>(\n        &mut self,\n        cx: &'a PatCtxt<'tcx>,\n        pat: &'tcx Pat<'tcx>,\n        path: &'tcx QPath<'tcx>,\n        single_pat: Option<&'tcx Pat<'tcx>>,\n        pats: impl IntoIterator<Item = &'tcx Pat<'tcx>>,\n    ) -> bool {\n        let ty::Adt(adt, _) = *cx.typeck.pat_ty(pat).kind() else {\n            // Should never happen\n            *self = Self::Wild;\n            return true;\n        };\n        if adt.is_struct() {\n            return if let Some(pat) = single_pat\n                && adt.non_enum_variant().fields.len() == 1\n            {\n                self.add_pat(cx, pat)\n            } else {\n                self.add_product_pat(cx, pats)\n            };\n        }\n        match cx.tcx.get_diagnostic_name(adt.did()) {\n            Some(sym::Option) => {\n                if let Some(pat) = single_pat {\n                    self.add_pat(cx, pat)\n                } else {\n                    *self = Self::Wild;\n                    true\n                }\n            },\n            Some(sym::Result | sym::Cow) => {\n                let Some((state, variant)) = self.get_std_enum_variant(cx, adt, path, pat.hir_id) else {\n                    return matches!(self, Self::Wild);\n                };\n                let is_wild = if let Some(pat) = single_pat\n                    && variant.fields.len() == 1\n                {\n                    state.add_pat(cx, pat)\n                } else {\n                    state.add_product_pat(cx, pats)\n                };\n                is_wild && self.check_all_wild_enum()\n            },\n            _ => matches!(self, Self::Wild),\n        }\n    }\n\n    /// Adds the pattern into the current state. Returns whether or not the current state is a wild\n    /// match after the merge.\n    #[expect(clippy::similar_names)]\n    fn add_pat<'tcx>(&mut self, cx: &'a PatCtxt<'tcx>, pat: &'tcx Pat<'_>) -> bool {\n        match pat.kind {\n            PatKind::Expr(PatExpr {\n                kind: PatExprKind::Path(_),\n                ..\n            }) if match *cx.typeck.pat_ty(pat).peel_refs().kind() {\n                ty::Adt(adt, _) => adt.is_enum() || (adt.is_struct() && !adt.non_enum_variant().fields.is_empty()),\n                ty::Tuple(tys) => !tys.is_empty(),\n                ty::Array(_, len) => len.try_to_target_usize(cx.tcx) != Some(1),\n                ty::Slice(..) => true,\n                _ => false,\n            } =>\n            {\n                matches!(self, Self::Wild)\n            },\n\n            PatKind::Guard(..) => {\n                matches!(self, Self::Wild)\n            },\n\n            // Patterns for things which can only contain a single sub-pattern.\n            PatKind::Binding(_, _, _, Some(pat))\n            | PatKind::Ref(pat, _, _)\n            | PatKind::Box(pat)\n            | PatKind::Deref(pat) => {\n                self.add_pat(cx, pat)\n            },\n            PatKind::Tuple([sub_pat], pos)\n                // `pat` looks like `(sub_pat)`, without a `..` -- has only one sub-pattern\n                if pos.as_opt_usize().is_none()\n                    // `pat` looks like `(sub_pat, ..)` or `(.., sub_pat)`, but its type is a unary tuple,\n                    // so it still only has one sub-pattern\n                    || cx.typeck.pat_ty(pat).tuple_fields().len() == 1 =>\n            {\n                self.add_pat(cx, sub_pat)\n            },\n            PatKind::Slice([sub_pat], _, []) | PatKind::Slice([], _, [sub_pat])\n                if let ty::Array(_, len) = *cx.typeck.pat_ty(pat).kind()\n                    && len.try_to_target_usize(cx.tcx) == Some(1) =>\n            {\n                self.add_pat(cx, sub_pat)\n            },\n\n            PatKind::Or(pats) => pats.iter().any(|p| self.add_pat(cx, p)),\n            PatKind::Tuple(pats, _) => self.add_product_pat(cx, pats),\n            PatKind::Slice(head, _, tail) => self.add_product_pat(cx, head.iter().chain(tail)),\n\n            PatKind::TupleStruct(ref path, pats, _) => self.add_struct_pats(\n                cx,\n                pat,\n                path,\n                if let [pat] = pats { Some(pat) } else { None },\n                pats.iter(),\n            ),\n            PatKind::Struct(ref path, pats, _) => self.add_struct_pats(\n                cx,\n                pat,\n                path,\n                if let [pat] = pats { Some(pat.pat) } else { None },\n                pats.iter().map(|p| p.pat),\n            ),\n\n            PatKind::Missing => unreachable!(),\n            PatKind::Wild\n            | PatKind::Binding(_, _, _, None)\n            | PatKind::Expr(_)\n            | PatKind::Range(..)\n            | PatKind::Never\n            | PatKind::Err(_) => {\n                *self = PatState::Wild;\n                true\n            },\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/try_err.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::get_parent_expr;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::option_arg_ty;\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::ResultErr;\nuse rustc_hir::{Expr, ExprKind, LangItem, MatchSource};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::{hygiene, sym};\n\nuse super::TRY_ERR;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutinee: &'tcx Expr<'_>) {\n    // Looks for a structure like this:\n    // match ::std::ops::Try::into_result(Err(5)) {\n    //     ::std::result::Result::Err(err) =>\n    //         #[allow(unreachable_code)]\n    //         return ::std::ops::Try::from_error(::std::convert::From::from(err)),\n    //     ::std::result::Result::Ok(val) =>\n    //         #[allow(unreachable_code)]\n    //         val,\n    // };\n    if let ExprKind::Call(match_fun, [try_arg]) = scrutinee.kind\n        && let ExprKind::Path(match_fun_path) = match_fun.kind\n        && cx.tcx.qpath_is_lang_item(match_fun_path, LangItem::TryTraitBranch)\n        && let ExprKind::Call(err_fun, [err_arg]) = try_arg.kind\n        && err_fun.res(cx).ctor_parent(cx).is_lang_item(cx, ResultErr)\n        && let Some(return_ty) = find_return_type(cx, &expr.kind)\n    {\n        let (prefix, suffix, err_ty) = if let Some(ty) = result_error_type(cx, return_ty) {\n            (\"Err(\", \")\", ty)\n        } else if let Some(ty) = poll_result_error_type(cx, return_ty) {\n            (\"Poll::Ready(Err(\", \"))\", ty)\n        } else if let Some(ty) = poll_option_result_error_type(cx, return_ty) {\n            (\"Poll::Ready(Some(Err(\", \")))\", ty)\n        } else {\n            return;\n        };\n\n        span_lint_and_then(\n            cx,\n            TRY_ERR,\n            expr.span,\n            \"returning an `Err(_)` with the `?` operator\",\n            |diag| {\n                let expr_err_ty = cx.typeck_results().expr_ty(err_arg);\n                let span = hygiene::walk_chain(err_arg.span, try_arg.span.ctxt());\n                let mut applicability = Applicability::MachineApplicable;\n                let origin_snippet = snippet_with_applicability(cx, span, \"_\", &mut applicability);\n                let ret_prefix = if get_parent_expr(cx, expr).is_some_and(|e| matches!(e.kind, ExprKind::Ret(_))) {\n                    \"\" // already returns\n                } else {\n                    \"return \"\n                };\n                let suggestion = if err_ty == expr_err_ty {\n                    format!(\"{ret_prefix}{prefix}{origin_snippet}{suffix}\")\n                } else {\n                    format!(\"{ret_prefix}{prefix}{origin_snippet}.into(){suffix}\")\n                };\n                diag.span_suggestion(expr.span, \"try\", suggestion, applicability);\n            },\n        );\n    }\n}\n\n/// Finds function return type by examining return expressions in match arms.\nfn find_return_type<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx ExprKind<'_>) -> Option<Ty<'tcx>> {\n    if let ExprKind::Match(_, arms, MatchSource::TryDesugar(_)) = expr {\n        for arm in *arms {\n            if let ExprKind::Ret(Some(ret)) = arm.body.kind {\n                return Some(cx.typeck_results().expr_ty(ret));\n            }\n        }\n    }\n    None\n}\n\n/// Extracts the error type from Result<T, E>.\nfn result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {\n    if let ty::Adt(def, subst) = ty.kind()\n        && cx.tcx.is_diagnostic_item(sym::Result, def.did())\n    {\n        Some(subst.type_at(1))\n    } else {\n        None\n    }\n}\n\n/// Extracts the error type from Poll<Result<T, E>>.\nfn poll_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {\n    if let ty::Adt(def, subst) = ty.kind()\n        && cx.tcx.lang_items().get(LangItem::Poll) == Some(def.did())\n    {\n        let ready_ty = subst.type_at(0);\n        result_error_type(cx, ready_ty)\n    } else {\n        None\n    }\n}\n\n/// Extracts the error type from Poll<Option<Result<T, E>>>.\nfn poll_option_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {\n    if let ty::Adt(def, subst) = ty.kind()\n        && cx.tcx.lang_items().get(LangItem::Poll) == Some(def.did())\n        && let ready_ty = subst.type_at(0)\n        && let Some(some_ty) = option_arg_ty(cx, ready_ty)\n    {\n        result_error_type(cx, some_ty)\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/matches/wild_in_or_pats.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::{has_non_exhaustive_attr, is_wild};\nuse rustc_hir::{Arm, Expr, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::WILDCARD_IN_OR_PATTERNS;\n\npub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arms: &[Arm<'_>]) {\n    // first check if we are matching on an enum that has the non_exhaustive attribute\n    let ty = cx.typeck_results().expr_ty(expr).peel_refs();\n    if let ty::Adt(adt_def, _) = ty.kind()\n        && has_non_exhaustive_attr(cx.tcx, *adt_def)\n    {\n        return;\n    }\n    for arm in arms {\n        if let PatKind::Or(fields) = arm.pat.kind\n            // look for multiple fields in this arm that contains at least one Wild pattern\n            && fields.len() > 1 && fields.iter().any(is_wild)\n        {\n            span_lint_and_help(\n                cx,\n                WILDCARD_IN_OR_PATTERNS,\n                arm.pat.span,\n                \"wildcard pattern covers any other pattern as it will match anyway\",\n                None,\n                \"consider handling `_` separately\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/mem_replace.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::is_non_aggregate_primitive_type;\nuse clippy_utils::{\n    as_some_expr, is_default_equivalent, is_expr_used_or_unified, is_none_expr, peel_ref_operators, std_or_core, sym,\n};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `mem::replace()` on an `Option` with\n    /// `None`.\n    ///\n    /// ### Why is this bad?\n    /// `Option` already has the method `take()` for\n    /// taking its current value (Some(..) or None) and replacing it with\n    /// `None`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::mem;\n    ///\n    /// let mut an_option = Some(0);\n    /// let replaced = mem::replace(&mut an_option, None);\n    /// ```\n    /// Is better expressed with:\n    /// ```no_run\n    /// let mut an_option = Some(0);\n    /// let taken = an_option.take();\n    /// ```\n    #[clippy::version = \"1.31.0\"]\n    pub MEM_REPLACE_OPTION_WITH_NONE,\n    style,\n    \"replacing an `Option` with `None` instead of `take()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `mem::replace()` on an `Option` with `Some(…)`.\n    ///\n    /// ### Why is this bad?\n    /// `Option` already has the method `replace()` for\n    /// taking its current value (Some(…) or None) and replacing it with\n    /// `Some(…)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut an_option = Some(0);\n    /// let replaced = std::mem::replace(&mut an_option, Some(1));\n    /// ```\n    /// Is better expressed with:\n    /// ```no_run\n    /// let mut an_option = Some(0);\n    /// let taken = an_option.replace(1);\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub MEM_REPLACE_OPTION_WITH_SOME,\n    style,\n    \"replacing an `Option` with `Some` instead of `replace()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `std::mem::replace` on a value of type\n    /// `T` with `T::default()`.\n    ///\n    /// ### Why is this bad?\n    /// `std::mem` module already has the method `take` to\n    /// take the current value and replace it with the default value of that type.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut text = String::from(\"foo\");\n    /// let replaced = std::mem::replace(&mut text, String::default());\n    /// ```\n    /// Is better expressed with:\n    /// ```no_run\n    /// let mut text = String::from(\"foo\");\n    /// let taken = std::mem::take(&mut text);\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub MEM_REPLACE_WITH_DEFAULT,\n    style,\n    \"replacing a value of type `T` with `T::default()` instead of using `std::mem::take`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `mem::replace(&mut _, mem::uninitialized())`\n    /// and `mem::replace(&mut _, mem::zeroed())`.\n    ///\n    /// ### Why is this bad?\n    /// This will lead to undefined behavior even if the\n    /// value is overwritten later, because the uninitialized value may be\n    /// observed in the case of a panic.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::mem;\n    ///# fn may_panic(v: Vec<i32>) -> Vec<i32> { v }\n    ///\n    /// #[allow(deprecated, invalid_value)]\n    /// fn myfunc (v: &mut Vec<i32>) {\n    ///     let taken_v = unsafe { mem::replace(v, mem::uninitialized()) };\n    ///     let new_v = may_panic(taken_v); // undefined behavior on panic\n    ///     mem::forget(mem::replace(v, new_v));\n    /// }\n    /// ```\n    ///\n    /// The [take_mut](https://docs.rs/take_mut) crate offers a sound solution,\n    /// at the cost of either lazily creating a replacement value or aborting\n    /// on panic, to ensure that the uninitialized value cannot be observed.\n    #[clippy::version = \"1.39.0\"]\n    pub MEM_REPLACE_WITH_UNINIT,\n    correctness,\n    \"`mem::replace(&mut _, mem::uninitialized())` or `mem::replace(&mut _, mem::zeroed())`\"\n}\n\nimpl_lint_pass!(MemReplace => [\n    MEM_REPLACE_OPTION_WITH_NONE,\n    MEM_REPLACE_OPTION_WITH_SOME,\n    MEM_REPLACE_WITH_DEFAULT,\n    MEM_REPLACE_WITH_UNINIT,\n]);\n\nfn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) -> bool {\n    if is_none_expr(cx, src) {\n        // Since this is a late pass (already type-checked),\n        // and we already know that the second argument is an\n        // `Option`, we do not need to check the first\n        // argument's type. All that's left is to get\n        // the replacee's expr after peeling off the `&mut`\n        let sugg_expr = peel_ref_operators(cx, dest);\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            MEM_REPLACE_OPTION_WITH_NONE,\n            expr_span,\n            \"replacing an `Option` with `None`\",\n            \"consider `Option::take()` instead\",\n            format!(\n                \"{}.take()\",\n                Sugg::hir_with_context(cx, sugg_expr, expr_span.ctxt(), \"\", &mut applicability).maybe_paren()\n            ),\n            applicability,\n        );\n        true\n    } else {\n        false\n    }\n}\n\nfn check_replace_option_with_some(\n    cx: &LateContext<'_>,\n    src: &Expr<'_>,\n    dest: &Expr<'_>,\n    expr_span: Span,\n    msrv: Msrv,\n) -> bool {\n    if let Some(src_arg) = as_some_expr(cx, src)\n        && msrv.meets(cx, msrvs::OPTION_REPLACE)\n    {\n        // We do not have to check for a `const` context here, because `core::mem::replace()` and\n        // `Option::replace()` have been const-stabilized simultaneously in version 1.83.0.\n        let sugg_expr = peel_ref_operators(cx, dest);\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            MEM_REPLACE_OPTION_WITH_SOME,\n            expr_span,\n            \"replacing an `Option` with `Some(..)`\",\n            \"consider `Option::replace()` instead\",\n            format!(\n                \"{}.replace({})\",\n                Sugg::hir_with_context(cx, sugg_expr, expr_span.ctxt(), \"_\", &mut applicability).maybe_paren(),\n                snippet_with_applicability(cx, src_arg.span, \"_\", &mut applicability)\n            ),\n            applicability,\n        );\n        true\n    } else {\n        false\n    }\n}\n\nfn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) {\n    if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(src.hir_id)\n        // check if replacement is mem::MaybeUninit::uninit().assume_init()\n        && cx.tcx.is_diagnostic_item(sym::assume_init, method_def_id)\n    {\n        let Some(top_crate) = std_or_core(cx) else { return };\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            MEM_REPLACE_WITH_UNINIT,\n            expr_span,\n            \"replacing with `mem::MaybeUninit::uninit().assume_init()`\",\n            \"consider using\",\n            format!(\n                \"{top_crate}::ptr::read({})\",\n                snippet_with_applicability(cx, dest.span, \"\", &mut applicability)\n            ),\n            applicability,\n        );\n        return;\n    }\n\n    if let ExprKind::Call(repl_func, []) = src.kind\n        && let ExprKind::Path(ref repl_func_qpath) = repl_func.kind\n        && let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id()\n    {\n        let repl_name = cx.tcx.get_diagnostic_name(repl_def_id);\n        if repl_name == Some(sym::mem_uninitialized) {\n            let Some(top_crate) = std_or_core(cx) else { return };\n            let mut applicability = Applicability::MachineApplicable;\n            span_lint_and_sugg(\n                cx,\n                MEM_REPLACE_WITH_UNINIT,\n                expr_span,\n                \"replacing with `mem::uninitialized()`\",\n                \"consider using\",\n                format!(\n                    \"{top_crate}::ptr::read({})\",\n                    snippet_with_applicability(cx, dest.span, \"\", &mut applicability)\n                ),\n                applicability,\n            );\n        } else if repl_name == Some(sym::mem_zeroed) && !cx.typeck_results().expr_ty(src).is_primitive() {\n            span_lint_and_help(\n                cx,\n                MEM_REPLACE_WITH_UNINIT,\n                expr_span,\n                \"replacing with `mem::zeroed()`\",\n                None,\n                \"consider using a default value or the `take_mut` crate instead\",\n            );\n        }\n    }\n}\n\nfn check_replace_with_default(\n    cx: &LateContext<'_>,\n    src: &Expr<'_>,\n    dest: &Expr<'_>,\n    expr: &Expr<'_>,\n    msrv: Msrv,\n) -> bool {\n    if is_expr_used_or_unified(cx.tcx, expr)\n        // disable lint for primitives\n        && let expr_type = cx.typeck_results().expr_ty_adjusted(src)\n        && !is_non_aggregate_primitive_type(expr_type)\n        && is_default_equivalent(cx, src)\n        && !expr.span.in_external_macro(cx.tcx.sess.source_map())\n        && let Some(top_crate) = std_or_core(cx)\n        && msrv.meets(cx, msrvs::MEM_TAKE)\n    {\n        span_lint_and_then(\n            cx,\n            MEM_REPLACE_WITH_DEFAULT,\n            expr.span,\n            format!(\n                \"replacing a value of type `T` with `T::default()` is better expressed using `{top_crate}::mem::take`\"\n            ),\n            |diag| {\n                if !expr.span.from_expansion() {\n                    let mut applicability = Applicability::MachineApplicable;\n                    let (dest_snip, _) = snippet_with_context(cx, dest.span, expr.span.ctxt(), \"\", &mut applicability);\n                    let suggestion = format!(\"{top_crate}::mem::take({dest_snip})\");\n\n                    diag.span_suggestion(expr.span, \"consider using\", suggestion, applicability);\n                }\n            },\n        );\n        true\n    } else {\n        false\n    }\n}\n\npub struct MemReplace {\n    msrv: Msrv,\n}\n\nimpl MemReplace {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MemReplace {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Call(func, [dest, src]) = expr.kind\n            // Check that `expr` is a call to `mem::replace()`\n            && let ExprKind::Path(ref func_qpath) = func.kind\n            && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id()\n            && cx.tcx.is_diagnostic_item(sym::mem_replace, def_id)\n            // Check that second argument is `Option::None`\n            && !check_replace_option_with_none(cx, src, dest, expr.span)\n            && !check_replace_option_with_some(cx, src, dest, expr.span, self.msrv)\n            && !check_replace_with_default(cx, src, dest, expr, self.msrv)\n        {\n            check_replace_with_uninit(cx, src, dest, expr.span);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/bind_instead_of_map.rs",
    "content": "use super::{BIND_INSTEAD_OF_MAP, contains_return};\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::peel_blocks;\nuse clippy_utils::source::{snippet, snippet_with_context};\nuse clippy_utils::visitors::find_all_ret_expressions;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};\nuse rustc_hir::{LangItem, QPath};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\npub(super) fn check_and_then_some(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    recv: &hir::Expr<'_>,\n    arg: &hir::Expr<'_>,\n) -> bool {\n    BindInsteadOfMap {\n        variant_lang_item: LangItem::OptionSome,\n        bad_method_name: \"and_then\",\n        good_method_name: \"map\",\n    }\n    .check(cx, expr, recv, arg)\n}\n\npub(super) fn check_and_then_ok(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    recv: &hir::Expr<'_>,\n    arg: &hir::Expr<'_>,\n) -> bool {\n    BindInsteadOfMap {\n        variant_lang_item: LangItem::ResultOk,\n        bad_method_name: \"and_then\",\n        good_method_name: \"map\",\n    }\n    .check(cx, expr, recv, arg)\n}\n\npub(super) fn check_or_else_err(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    recv: &hir::Expr<'_>,\n    arg: &hir::Expr<'_>,\n) -> bool {\n    BindInsteadOfMap {\n        variant_lang_item: LangItem::ResultErr,\n        bad_method_name: \"or_else\",\n        good_method_name: \"map_err\",\n    }\n    .check(cx, expr, recv, arg)\n}\n\nstruct BindInsteadOfMap {\n    variant_lang_item: LangItem,\n    bad_method_name: &'static str,\n    good_method_name: &'static str,\n}\n\nimpl BindInsteadOfMap {\n    fn no_op_msg(&self, cx: &LateContext<'_>) -> Option<String> {\n        let variant_id = cx.tcx.lang_items().get(self.variant_lang_item)?;\n        let item_id = cx.tcx.parent(variant_id);\n        Some(format!(\n            \"using `{}.{}({})`, which is a no-op\",\n            cx.tcx.item_name(item_id),\n            self.bad_method_name,\n            cx.tcx.item_name(variant_id),\n        ))\n    }\n\n    fn lint_msg(&self, cx: &LateContext<'_>) -> Option<String> {\n        let variant_id = cx.tcx.lang_items().get(self.variant_lang_item)?;\n        let item_id = cx.tcx.parent(variant_id);\n        Some(format!(\n            \"using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`\",\n            cx.tcx.item_name(item_id),\n            self.bad_method_name,\n            cx.tcx.item_name(variant_id),\n            self.good_method_name,\n        ))\n    }\n\n    fn lint_closure_autofixable(\n        &self,\n        cx: &LateContext<'_>,\n        expr: &hir::Expr<'_>,\n        recv: &hir::Expr<'_>,\n        closure_expr: &hir::Expr<'_>,\n        closure_args_span: Span,\n    ) -> bool {\n        if let hir::ExprKind::Call(some_expr, [inner_expr]) = closure_expr.kind\n            && let hir::ExprKind::Path(QPath::Resolved(_, path)) = some_expr.kind\n            && self.is_variant(cx, path.res)\n            && !contains_return(inner_expr)\n            && let Some(msg) = self.lint_msg(cx)\n        {\n            let mut app = Applicability::MachineApplicable;\n            let some_inner_snip = snippet_with_context(cx, inner_expr.span, closure_expr.span.ctxt(), \"_\", &mut app).0;\n\n            let closure_args_snip = snippet(cx, closure_args_span, \"..\");\n            let option_snip = snippet(cx, recv.span, \"..\");\n            let note = format!(\n                \"{option_snip}.{}({closure_args_snip} {some_inner_snip})\",\n                self.good_method_name\n            );\n            span_lint_and_sugg(cx, BIND_INSTEAD_OF_MAP, expr.span, msg, \"try\", note, app);\n            true\n        } else {\n            false\n        }\n    }\n\n    fn lint_closure(&self, cx: &LateContext<'_>, expr: &hir::Expr<'_>, closure_expr: &hir::Expr<'_>) -> bool {\n        let mut suggs = Vec::new();\n        let can_sugg: bool = find_all_ret_expressions(cx, closure_expr, |ret_expr| {\n            if !ret_expr.span.from_expansion()\n                && let hir::ExprKind::Call(func_path, [arg]) = ret_expr.kind\n                && let hir::ExprKind::Path(QPath::Resolved(_, path)) = func_path.kind\n                && self.is_variant(cx, path.res)\n                && !contains_return(arg)\n            {\n                suggs.push((ret_expr.span, arg.span.source_callsite()));\n                true\n            } else {\n                false\n            }\n        });\n        let (span, msg) = if can_sugg\n            && let hir::ExprKind::MethodCall(segment, ..) = expr.kind\n            && let Some(msg) = self.lint_msg(cx)\n        {\n            (segment.ident.span, msg)\n        } else {\n            return false;\n        };\n        span_lint_and_then(cx, BIND_INSTEAD_OF_MAP, expr.span, msg, |diag| {\n            diag.multipart_suggestion(\n                format!(\"use `{}` instead\", self.good_method_name),\n                std::iter::once((span, self.good_method_name.into()))\n                    .chain(\n                        suggs\n                            .into_iter()\n                            .map(|(span1, span2)| (span1, snippet(cx, span2, \"_\").into())),\n                    )\n                    .collect(),\n                Applicability::MachineApplicable,\n            );\n        });\n        true\n    }\n\n    /// Lint use of `_.and_then(|x| Some(y))` for `Option`s\n    fn check(&self, cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) -> bool {\n        if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def()\n            && let Some(vid) = cx.tcx.lang_items().get(self.variant_lang_item)\n            && adt.did() == cx.tcx.parent(vid)\n        {\n        } else {\n            return false;\n        }\n\n        match arg.kind {\n            hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) => {\n                let closure_body = cx.tcx.hir_body(body);\n                let closure_expr = peel_blocks(closure_body.value);\n\n                if self.lint_closure_autofixable(cx, expr, recv, closure_expr, fn_decl_span) {\n                    true\n                } else {\n                    self.lint_closure(cx, expr, closure_expr)\n                }\n            },\n            // `_.and_then(Some)` case, which is no-op.\n            hir::ExprKind::Path(QPath::Resolved(_, path)) if self.is_variant(cx, path.res) => {\n                if let Some(msg) = self.no_op_msg(cx) {\n                    span_lint_and_sugg(\n                        cx,\n                        BIND_INSTEAD_OF_MAP,\n                        expr.span,\n                        msg,\n                        \"use the expression directly\",\n                        snippet(cx, recv.span, \"..\").into(),\n                        Applicability::MachineApplicable,\n                    );\n                }\n                true\n            },\n            _ => false,\n        }\n    }\n\n    fn is_variant(&self, cx: &LateContext<'_>, res: Res) -> bool {\n        if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res\n            && let Some(variant_id) = cx.tcx.lang_items().get(self.variant_lang_item)\n        {\n            return cx.tcx.parent(id) == variant_id;\n        }\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/bytecount.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::visitors::is_local_used;\nuse clippy_utils::{peel_blocks, peel_ref_operators, strip_pat_refs, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Closure, Expr, ExprKind, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, UintTy};\n\nuse super::NAIVE_BYTECOUNT;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    filter_recv: &'tcx Expr<'_>,\n    filter_arg: &'tcx Expr<'_>,\n) {\n    if let ExprKind::Closure(&Closure { body, .. }) = filter_arg.kind\n        && let body = cx.tcx.hir_body(body)\n        && let [param] = body.params\n        && let PatKind::Binding(_, arg_id, _, _) = strip_pat_refs(param.pat).kind\n        && let ExprKind::Binary(ref op, l, r) = body.value.kind\n        && op.node == BinOpKind::Eq\n        && cx\n            .typeck_results()\n            .expr_ty(filter_recv)\n            .peel_refs()\n            .is_diag_item(cx, sym::SliceIter)\n        && let operand_is_arg = (|expr| {\n            let expr = peel_ref_operators(cx, peel_blocks(expr));\n            expr.res_local_id() == Some(arg_id)\n        })\n        && let needle = if operand_is_arg(l) {\n            r\n        } else if operand_is_arg(r) {\n            l\n        } else {\n            return;\n        }\n        && ty::Uint(UintTy::U8) == *cx.typeck_results().expr_ty(needle).peel_refs().kind()\n        && !is_local_used(cx, needle, arg_id)\n    {\n        let haystack = if let ExprKind::MethodCall(path, receiver, [], _) = filter_recv.kind {\n            let p = path.ident.name;\n            if p == sym::iter || p == sym::iter_mut {\n                receiver\n            } else {\n                filter_recv\n            }\n        } else {\n            filter_recv\n        };\n        let mut applicability = Applicability::MaybeIncorrect;\n        span_lint_and_sugg(\n            cx,\n            NAIVE_BYTECOUNT,\n            expr.span,\n            \"you appear to be counting bytes the naive way\",\n            \"consider using the bytecount crate\",\n            format!(\n                \"bytecount::count({}, {})\",\n                snippet_with_applicability(cx, haystack.span, \"..\", &mut applicability),\n                snippet_with_applicability(cx, needle.span, \"..\", &mut applicability)\n            ),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/bytes_count_to_len.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\n\nuse super::BYTES_COUNT_TO_LEN;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    count_recv: &'tcx hir::Expr<'_>,\n    bytes_recv: &'tcx hir::Expr<'_>,\n) {\n    if let Some(bytes_id) = cx.typeck_results().type_dependent_def_id(count_recv.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(bytes_id)\n        && cx.tcx.type_of(impl_id).instantiate_identity().is_str()\n        && let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs()\n        && (ty.is_str() || ty.is_lang_item(cx, hir::LangItem::String))\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            BYTES_COUNT_TO_LEN,\n            expr.span,\n            \"using long and hard to read `.bytes().count()`\",\n            \"consider calling `.len()` instead\",\n            format!(\n                \"{}.len()\",\n                snippet_with_applicability(cx, bytes_recv.span, \"..\", &mut applicability)\n            ),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/bytes_nth.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, LangItem};\nuse rustc_lint::LateContext;\n\nuse crate::methods::method_call;\n\nuse super::BYTES_NTH;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, n_arg: &'tcx Expr<'tcx>) {\n    let ty = cx.typeck_results().expr_ty(recv).peel_refs();\n    let caller_type = if ty.is_str() {\n        \"str\"\n    } else if ty.is_lang_item(cx, LangItem::String) {\n        \"String\"\n    } else {\n        return;\n    };\n\n    let mut applicability = Applicability::MachineApplicable;\n    let receiver = snippet_with_applicability(cx, recv.span, \"..\", &mut applicability);\n    let n = snippet_with_applicability(cx, n_arg.span, \"..\", &mut applicability);\n\n    if let Some(parent) = clippy_utils::get_parent_expr(cx, expr)\n        && let Some((name, _, _, _, _)) = method_call(parent)\n        && name == sym::unwrap\n    {\n        span_lint_and_sugg(\n            cx,\n            BYTES_NTH,\n            parent.span,\n            format!(\"called `.bytes().nth().unwrap()` on a `{caller_type}`\"),\n            \"try\",\n            format!(\"{receiver}.as_bytes()[{n}]\"),\n            applicability,\n        );\n    } else {\n        span_lint_and_sugg(\n            cx,\n            BYTES_NTH,\n            expr.span,\n            format!(\"called `.bytes().nth()` on a `{caller_type}`\"),\n            \"try\",\n            format!(\"{receiver}.as_bytes().get({n}).copied()\"),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{SpanRangeExt, indent_of, reindent_multiline};\nuse clippy_utils::sym;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\nuse rustc_span::source_map::Spanned;\n\nuse super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    call_span: Span,\n    recv: &'tcx Expr<'_>,\n    arg: &'tcx Expr<'_>,\n    msrv: Msrv,\n) {\n    if let ExprKind::MethodCall(path_segment, ..) = recv.kind\n        && matches!(\n            path_segment.ident.name,\n            sym::to_lowercase | sym::to_uppercase | sym::to_ascii_lowercase | sym::to_ascii_uppercase\n        )\n    {\n        return;\n    }\n\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && cx.tcx.type_of(impl_id).instantiate_identity().is_str()\n        && let ExprKind::Lit(Spanned {\n            node: LitKind::Str(ext_literal, ..),\n            ..\n        }) = arg.kind\n        && (2..=6).contains(&ext_literal.as_str().len())\n        && let ext_str = ext_literal.as_str()\n        && ext_str.starts_with('.')\n        && (ext_str.chars().skip(1).all(|c| c.is_uppercase() || c.is_ascii_digit())\n            || ext_str.chars().skip(1).all(|c| c.is_lowercase() || c.is_ascii_digit()))\n        && !ext_str.chars().skip(1).all(|c| c.is_ascii_digit())\n        && let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs()\n        && (recv_ty.is_str() || recv_ty.is_lang_item(cx, LangItem::String))\n    {\n        span_lint_and_then(\n            cx,\n            CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,\n            recv.span.to(call_span),\n            \"case-sensitive file extension comparison\",\n            |diag| {\n                diag.help(\"consider using a case-insensitive comparison instead\");\n                if let Some(recv_source) = recv.span.get_source_text(cx) {\n                    let recv_source = if cx.typeck_results().expr_ty(recv).is_ref() {\n                        recv_source.to_owned()\n                    } else {\n                        format!(\"&{recv_source}\")\n                    };\n\n                    let suggestion_source = reindent_multiline(\n                        &format!(\n                            \"std::path::Path::new({recv_source})\n                                .extension()\n                                .{}|ext| ext.eq_ignore_ascii_case(\\\"{}\\\"))\",\n                            if msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) {\n                                \"is_some_and(\"\n                            } else {\n                                \"map_or(false, \"\n                            },\n                            ext_str.strip_prefix('.').unwrap(),\n                        ),\n                        true,\n                        Some(indent_of(cx, call_span).unwrap_or(0) + 4),\n                    );\n\n                    diag.span_suggestion(\n                        recv.span.to(call_span),\n                        \"use std::path::Path\",\n                        suggestion_source,\n                        Applicability::MaybeIncorrect,\n                    );\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/chars_cmp.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::method_chain_args;\nuse clippy_utils::res::MaybeQPath;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, Lint};\nuse rustc_middle::ty;\nuse rustc_span::Symbol;\n\n/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints.\npub(super) fn check(\n    cx: &LateContext<'_>,\n    info: &crate::methods::BinaryExprInfo<'_>,\n    chain_methods: &[Symbol],\n    lint: &'static Lint,\n    suggest: &str,\n) -> bool {\n    if let Some(args) = method_chain_args(info.chain, chain_methods)\n        && let hir::ExprKind::Call(fun, [arg_char]) = info.other.kind\n        && let Some(id) = fun.res(cx).opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id))\n        && Some(id) == cx.tcx.lang_items().option_some_variant()\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let self_ty = cx.typeck_results().expr_ty_adjusted(args[0].0).peel_refs();\n\n        if *self_ty.kind() != ty::Str {\n            return false;\n        }\n\n        span_lint_and_sugg(\n            cx,\n            lint,\n            info.expr.span,\n            format!(\"you should use the `{suggest}` method\"),\n            \"like this\",\n            format!(\n                \"{}{}.{suggest}({})\",\n                if info.eq { \"\" } else { \"!\" },\n                snippet_with_applicability(cx, args[0].0.span, \"..\", &mut applicability),\n                snippet_with_applicability(cx, arg_char.span, \"..\", &mut applicability)\n            ),\n            applicability,\n        );\n\n        return true;\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/chars_cmp_with_unwrap.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::method_chain_args;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_ast::ast;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, Lint};\nuse rustc_span::Symbol;\n\n/// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`.\npub(super) fn check(\n    cx: &LateContext<'_>,\n    info: &crate::methods::BinaryExprInfo<'_>,\n    chain_methods: &[Symbol],\n    lint: &'static Lint,\n    suggest: &str,\n) -> bool {\n    if let Some(args) = method_chain_args(info.chain, chain_methods)\n        && let hir::ExprKind::Lit(lit) = info.other.kind\n        && let ast::LitKind::Char(c) = lit.node\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            lint,\n            info.expr.span,\n            format!(\"you should use the `{suggest}` method\"),\n            \"like this\",\n            format!(\n                \"{}{}.{suggest}('{}')\",\n                if info.eq { \"\" } else { \"!\" },\n                snippet_with_applicability(cx, args[0].0.span, \"..\", &mut applicability),\n                c.escape_default()\n            ),\n            applicability,\n        );\n\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/chars_last_cmp.rs",
    "content": "use crate::methods::chars_cmp;\nuse clippy_utils::sym;\nuse rustc_lint::LateContext;\n\nuse super::CHARS_LAST_CMP;\n\n/// Checks for the `CHARS_LAST_CMP` lint.\npub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {\n    if chars_cmp::check(cx, info, &[sym::chars, sym::last], CHARS_LAST_CMP, \"ends_with\") {\n        true\n    } else {\n        chars_cmp::check(cx, info, &[sym::chars, sym::next_back], CHARS_LAST_CMP, \"ends_with\")\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs",
    "content": "use crate::methods::chars_cmp_with_unwrap;\nuse clippy_utils::sym;\nuse rustc_lint::LateContext;\n\nuse super::CHARS_LAST_CMP;\n\n/// Checks for the `CHARS_LAST_CMP` lint with `unwrap()`.\npub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {\n    if chars_cmp_with_unwrap::check(\n        cx,\n        info,\n        &[sym::chars, sym::last, sym::unwrap],\n        CHARS_LAST_CMP,\n        \"ends_with\",\n    ) {\n        true\n    } else {\n        chars_cmp_with_unwrap::check(\n            cx,\n            info,\n            &[sym::chars, sym::next_back, sym::unwrap],\n            CHARS_LAST_CMP,\n            \"ends_with\",\n        )\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/chars_next_cmp.rs",
    "content": "use clippy_utils::sym;\nuse rustc_lint::LateContext;\n\nuse super::CHARS_NEXT_CMP;\n\n/// Checks for the `CHARS_NEXT_CMP` lint.\npub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {\n    crate::methods::chars_cmp::check(cx, info, &[sym::chars, sym::next], CHARS_NEXT_CMP, \"starts_with\")\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs",
    "content": "use clippy_utils::sym;\nuse rustc_lint::LateContext;\n\nuse super::CHARS_NEXT_CMP;\n\n/// Checks for the `CHARS_NEXT_CMP` lint with `unwrap()`.\npub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {\n    crate::methods::chars_cmp_with_unwrap::check(\n        cx,\n        info,\n        &[sym::chars, sym::next, sym::unwrap],\n        CHARS_NEXT_CMP,\n        \"starts_with\",\n    )\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/clear_with_drain.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::{is_range_full, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem, QPath};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::CLEAR_WITH_DRAIN;\n\n// Add `String` here when it is added to diagnostic items\nconst ACCEPTABLE_TYPES_WITH_ARG: [rustc_span::Symbol; 2] = [sym::Vec, sym::VecDeque];\n\nconst ACCEPTABLE_TYPES_WITHOUT_ARG: [rustc_span::Symbol; 3] = [sym::BinaryHeap, sym::HashMap, sym::HashSet];\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, arg: Option<&Expr<'_>>) {\n    if let Some(arg) = arg {\n        if match_acceptable_type(cx, recv, &ACCEPTABLE_TYPES_WITH_ARG)\n            && let ExprKind::Path(QPath::Resolved(None, container_path)) = recv.kind\n            && is_range_full(cx, arg, Some(container_path))\n        {\n            suggest(cx, expr, recv, span);\n        }\n    } else if match_acceptable_type(cx, recv, &ACCEPTABLE_TYPES_WITHOUT_ARG) {\n        suggest(cx, expr, recv, span);\n    }\n}\n\nfn match_acceptable_type(cx: &LateContext<'_>, expr: &Expr<'_>, types: &[rustc_span::Symbol]) -> bool {\n    let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();\n    types.iter().any(|&ty| expr_ty.is_diag_item(cx, ty))\n    // String type is a lang item but not a diagnostic item for now so we need a separate check\n        || expr_ty.is_lang_item(cx, LangItem::String)\n}\n\nfn suggest(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span) {\n    if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def()\n    // Use `opt_item_name` while `String` is not a diagnostic item\n        && let Some(ty_name) = cx.tcx.opt_item_name(adt.did())\n    {\n        span_lint_and_sugg(\n            cx,\n            CLEAR_WITH_DRAIN,\n            span.with_hi(expr.span.hi()),\n            format!(\"`drain` used to clear a `{ty_name}`\"),\n            \"try\",\n            \"clear()\".to_string(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/clone_on_copy.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::is_copy;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BindingMode, ByRef, Expr, ExprKind, MatchSource, Node, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_middle::ty::adjustment::Adjust;\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\n\nuse super::CLONE_ON_COPY;\n\n/// Checks for the `CLONE_ON_COPY` lint.\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>) {\n    if cx\n        .typeck_results()\n        .type_dependent_def_id(expr.hir_id)\n        .and_then(|id| cx.tcx.trait_of_assoc(id))\n        .zip(cx.tcx.lang_items().clone_trait())\n        .is_none_or(|(x, y)| x != y)\n    {\n        return;\n    }\n    let arg_adjustments = cx.typeck_results().expr_adjustments(receiver);\n    let arg_ty = arg_adjustments\n        .last()\n        .map_or_else(|| cx.typeck_results().expr_ty(receiver), |a| a.target);\n\n    let ty = cx.typeck_results().expr_ty(expr);\n    if let ty::Ref(_, inner, _) = arg_ty.kind()\n        && let ty::Ref(..) = inner.kind()\n    {\n        return; // don't report clone_on_copy\n    }\n\n    if is_copy(cx, ty) {\n        let parent_is_suffix_expr = match cx.tcx.parent_hir_node(expr.hir_id) {\n            Node::Expr(parent) => match parent.kind {\n                // &*x is a nop, &x.clone() is not\n                ExprKind::AddrOf(..) => return,\n                // (*x).func() is useless, x.clone().func() can work in case func borrows self\n                ExprKind::MethodCall(_, self_arg, ..)\n                    if expr.hir_id == self_arg.hir_id && ty != cx.typeck_results().expr_ty_adjusted(expr) =>\n                {\n                    return;\n                },\n                // ? is a Call, makes sure not to rec *x?, but rather (*x)?\n                ExprKind::Call(hir_callee, [_]) => matches!(\n                    hir_callee.kind,\n                    ExprKind::Path(qpath)\n                    if cx.tcx.qpath_is_lang_item(qpath, rustc_hir::LangItem::TryTraitBranch)\n                ),\n                ExprKind::MethodCall(_, self_arg, ..) if expr.hir_id == self_arg.hir_id => true,\n                ExprKind::Match(_, _, MatchSource::TryDesugar(_) | MatchSource::AwaitDesugar)\n                | ExprKind::Field(..)\n                | ExprKind::Index(..) => true,\n                _ => false,\n            },\n            // local binding capturing a reference\n            Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingMode(ByRef::Yes(..), _), ..)) => {\n                return;\n            },\n            _ => false,\n        };\n\n        let mut app = Applicability::MachineApplicable;\n        let snip = snippet_with_context(cx, receiver.span, expr.span.ctxt(), \"_\", &mut app).0;\n\n        let deref_count = arg_adjustments\n            .iter()\n            .take_while(|adj| matches!(adj.kind, Adjust::Deref(_)))\n            .count();\n        let (help, sugg) = if deref_count == 0 {\n            (\"try removing the `clone` call\", snip.into())\n        } else if parent_is_suffix_expr {\n            (\"try dereferencing it\", format!(\"({}{snip})\", \"*\".repeat(deref_count)))\n        } else {\n            (\"try dereferencing it\", format!(\"{}{snip}\", \"*\".repeat(deref_count)))\n        };\n\n        span_lint_and_sugg(\n            cx,\n            CLONE_ON_COPY,\n            expr.span,\n            with_forced_trimmed_paths!(format!(\n                \"using `clone` on type `{ty}` which implements the `Copy` trait\"\n            )),\n            help,\n            sugg,\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/clone_on_ref_ptr.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::peel_and_count_ty_refs;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, IsSuggestable};\nuse rustc_span::symbol::sym;\n\nuse super::CLONE_ON_REF_PTR;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>) {\n    let receiver_ty = cx.typeck_results().expr_ty(receiver);\n    let (receiver_ty_peeled, n_refs, _) = peel_and_count_ty_refs(receiver_ty);\n\n    if let ty::Adt(adt, subst) = receiver_ty_peeled.kind()\n        && let Some(name) = cx.tcx.get_diagnostic_name(adt.did())\n    {\n        let caller_type = match name {\n            sym::Rc => \"std::rc::Rc\",\n            sym::Arc => \"std::sync::Arc\",\n            sym::RcWeak => \"std::rc::Weak\",\n            sym::ArcWeak => \"std::sync::Weak\",\n            _ => return,\n        };\n        span_lint_and_then(\n            cx,\n            CLONE_ON_REF_PTR,\n            expr.span,\n            \"using `.clone()` on a ref-counted pointer\",\n            |diag| {\n                // Sometimes unnecessary ::<_> after Rc/Arc/Weak\n                let mut app = Applicability::Unspecified;\n                let mut sugg = Sugg::hir_with_context(cx, receiver, expr.span.ctxt(), \"..\", &mut app);\n                if n_refs == 0 {\n                    sugg = sugg.addr();\n                }\n                // References on argument position don't need to preserve parentheses\n                // even if they were present in the original expression.\n                sugg = sugg.strip_paren();\n                let generic = subst.type_at(0);\n                if generic.is_suggestable(cx.tcx, true) {\n                    diag.span_suggestion(\n                        expr.span,\n                        \"try\",\n                        format!(\"{caller_type}::<{generic}>::clone({sugg})\"),\n                        app,\n                    );\n                } else {\n                    diag.span_suggestion(\n                        expr.span,\n                        \"try\",\n                        format!(\"{caller_type}::</* generic */>::clone({sugg})\"),\n                        Applicability::HasPlaceholders,\n                    );\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/cloned_instead_of_copied.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::ty::{get_iterator_item_ty, is_copy};\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, sym};\n\nuse super::CLONED_INSTEAD_OF_COPIED;\n\npub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Msrv) {\n    let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);\n    let inner_ty = match recv_ty.kind() {\n        // `Option<T>` -> `T`\n        ty::Adt(adt, subst)\n            if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && msrv.meets(cx, msrvs::OPTION_COPIED) =>\n        {\n            subst.type_at(0)\n        },\n        _ if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n            && msrv.meets(cx, msrvs::ITERATOR_COPIED) =>\n        {\n            match get_iterator_item_ty(cx, recv_ty) {\n                // <T as Iterator>::Item\n                Some(ty) => ty,\n                _ => return,\n            }\n        },\n        _ => return,\n    };\n    match inner_ty.kind() {\n        // &T where T: Copy\n        ty::Ref(_, ty, _) if is_copy(cx, *ty) => {},\n        _ => return,\n    }\n    span_lint_and_sugg(\n        cx,\n        CLONED_INSTEAD_OF_COPIED,\n        span,\n        \"used `cloned` where `copied` could be used instead\",\n        \"try\",\n        \"copied\".into(),\n        Applicability::MachineApplicable,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/collapsible_str_replace.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{eq_expr_value, get_parent_expr, sym};\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse std::collections::VecDeque;\n\nuse super::{COLLAPSIBLE_STR_REPLACE, method_call};\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'tcx>,\n    from: &'tcx hir::Expr<'tcx>,\n    to: &'tcx hir::Expr<'tcx>,\n) {\n    let replace_methods = collect_replace_calls(cx, expr, to);\n    if replace_methods.methods.len() > 1 {\n        let from_kind = cx.typeck_results().expr_ty(from).peel_refs().kind();\n        // If the parent node's `to` argument is the same as the `to` argument\n        // of the last replace call in the current chain, don't lint as it was already linted\n        if let Some(parent) = get_parent_expr(cx, expr)\n            && let Some((sym::replace, _, [current_from, current_to], _, _)) = method_call(parent)\n            && eq_expr_value(cx, to, current_to)\n            && from_kind == cx.typeck_results().expr_ty(current_from).peel_refs().kind()\n        {\n            return;\n        }\n\n        check_consecutive_replace_calls(cx, expr, &replace_methods, to);\n    }\n}\n\nstruct ReplaceMethods<'tcx> {\n    methods: VecDeque<&'tcx hir::Expr<'tcx>>,\n    from_args: VecDeque<&'tcx hir::Expr<'tcx>>,\n}\n\nfn collect_replace_calls<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'tcx>,\n    to_arg: &'tcx hir::Expr<'tcx>,\n) -> ReplaceMethods<'tcx> {\n    let mut methods = VecDeque::new();\n    let mut from_args = VecDeque::new();\n\n    let _: Option<()> = for_each_expr_without_closures(expr, |e| {\n        if let Some((sym::replace, _, [from, to], _, _)) = method_call(e) {\n            if eq_expr_value(cx, to_arg, to) && cx.typeck_results().expr_ty(from).peel_refs().is_char() {\n                methods.push_front(e);\n                from_args.push_front(from);\n                ControlFlow::Continue(())\n            } else {\n                ControlFlow::Break(())\n            }\n        } else {\n            ControlFlow::Continue(())\n        }\n    });\n\n    ReplaceMethods { methods, from_args }\n}\n\n/// Check a chain of `str::replace` calls for `collapsible_str_replace` lint.\nfn check_consecutive_replace_calls<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'tcx>,\n    replace_methods: &ReplaceMethods<'tcx>,\n    to_arg: &'tcx hir::Expr<'tcx>,\n) {\n    let from_args = &replace_methods.from_args;\n    let from_arg_reprs: Vec<String> = from_args\n        .iter()\n        .map(|from_arg| snippet(cx, from_arg.span, \"..\").to_string())\n        .collect();\n    let app = Applicability::MachineApplicable;\n    let earliest_replace_call = replace_methods.methods.front().unwrap();\n    if let Some((_, _, [..], span_lo, _)) = method_call(earliest_replace_call) {\n        span_lint_and_sugg(\n            cx,\n            COLLAPSIBLE_STR_REPLACE,\n            expr.span.with_lo(span_lo.lo()),\n            \"used consecutive `str::replace` call\",\n            \"replace with\",\n            format!(\n                \"replace([{}], {})\",\n                from_arg_reprs.join(\", \"),\n                snippet(cx, to_arg.span, \"..\"),\n            ),\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/double_ended_iterator_last.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::ty::{has_non_owning_mutable_access, implements_trait};\nuse clippy_utils::{is_mutable, path_to_local_with_projections, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, Node, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Instance;\nuse rustc_span::Span;\n\nuse super::DOUBLE_ENDED_ITERATOR_LAST;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Expr<'_>, call_span: Span) {\n    let typeck = cx.typeck_results();\n\n    // if the \"last\" method is that of Iterator\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        // if self implements DoubleEndedIterator\n        && let Some(deiter_id) = cx.tcx.get_diagnostic_item(sym::DoubleEndedIterator)\n        && let self_type = cx.typeck_results().expr_ty(self_expr)\n        && implements_trait(cx, self_type.peel_refs(), deiter_id, &[])\n        // resolve the method definition\n        && let id = typeck.type_dependent_def_id(expr.hir_id).unwrap()\n        && let args = typeck.node_args(expr.hir_id)\n        && let Ok(Some(fn_def)) = Instance::try_resolve(cx.tcx, cx.typing_env(), id, args)\n        // find the provided definition of Iterator::last\n        && let Some(item) = cx.tcx.get_diagnostic_item(sym::Iterator)\n        && let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name() == sym::last)\n        // if the resolved method is the same as the provided definition\n        && fn_def.def_id() == last_def.def_id\n        && let self_ty = cx.typeck_results().expr_ty(self_expr)\n        && !has_non_owning_mutable_access(cx, self_ty)\n    {\n        let mut sugg = vec![(call_span, String::from(\"next_back()\"))];\n        let mut dont_apply = false;\n\n        // if `self_expr` is a reference, it is mutable because it is used for `.last()`\n        // TODO: Change this to lint only when the referred iterator is not used later. If it is used later,\n        // changing to `next_back()` may change its behavior.\n        if !(is_mutable(cx, self_expr) || self_type.is_ref()) {\n            if let Some(hir_id) = path_to_local_with_projections(self_expr)\n                && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)\n                && let PatKind::Binding(_, _, ident, _) = pat.kind\n            {\n                sugg.push((ident.span.shrink_to_lo(), String::from(\"mut \")));\n            } else {\n                // If we can't make the binding mutable, make the suggestion `Unspecified` to prevent it from being\n                // automatically applied, and add a complementary help message.\n                dont_apply = true;\n            }\n        }\n        span_lint_and_then(\n            cx,\n            DOUBLE_ENDED_ITERATOR_LAST,\n            expr.span,\n            \"called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator\",\n            |diag| {\n                let expr_ty = cx.typeck_results().expr_ty(expr);\n                let droppable_elements = expr_ty.has_significant_drop(cx.tcx, cx.typing_env());\n                diag.multipart_suggestion(\n                    \"try\",\n                    sugg,\n                    if dont_apply {\n                        Applicability::Unspecified\n                    } else if droppable_elements {\n                        Applicability::MaybeIncorrect\n                    } else {\n                        Applicability::MachineApplicable\n                    },\n                );\n                if droppable_elements {\n                    diag.note(\"this change will alter drop order which may be undesirable\");\n                }\n                if dont_apply {\n                    diag.span_note(self_expr.span, \"this must be made mutable to use `.next_back()`\");\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/drain_collect.rs",
    "content": "use crate::methods::DRAIN_COLLECT;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{is_range_full, std_or_core, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem, Path, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_middle::ty::Ty;\nuse rustc_span::Symbol;\n\n/// Checks if both types match the given diagnostic item, e.g.:\n///\n/// `vec![1,2].drain(..).collect::<Vec<_>>()`\n///  ^^^^^^^^^                     ^^^^^^   true\n/// `vec![1,2].drain(..).collect::<HashSet<_>>()`\n///  ^^^^^^^^^                     ^^^^^^^^^^  false\nfn types_match_diagnostic_item(cx: &LateContext<'_>, expr: Ty<'_>, recv: Ty<'_>, sym: Symbol) -> bool {\n    if let Some(expr_adt) = expr.ty_adt_def()\n        && let Some(recv_adt) = recv.ty_adt_def()\n    {\n        cx.tcx.is_diagnostic_item(sym, expr_adt.did()) && cx.tcx.is_diagnostic_item(sym, recv_adt.did())\n    } else {\n        false\n    }\n}\n\n/// Checks `std::{vec::Vec, collections::VecDeque}`.\nfn check_vec(cx: &LateContext<'_>, args: &[Expr<'_>], expr: Ty<'_>, recv: Ty<'_>, recv_path: &Path<'_>) -> bool {\n    (types_match_diagnostic_item(cx, expr, recv, sym::Vec)\n        || types_match_diagnostic_item(cx, expr, recv, sym::VecDeque))\n        && matches!(args, [arg] if is_range_full(cx, arg, Some(recv_path)))\n}\n\n/// Checks `std::string::String`\nfn check_string(cx: &LateContext<'_>, args: &[Expr<'_>], expr: Ty<'_>, recv: Ty<'_>, recv_path: &Path<'_>) -> bool {\n    expr.is_lang_item(cx, LangItem::String)\n        && recv.is_lang_item(cx, LangItem::String)\n        && matches!(args, [arg] if is_range_full(cx, arg, Some(recv_path)))\n}\n\n/// Checks `std::collections::{HashSet, HashMap, BinaryHeap}`.\nfn check_collections(cx: &LateContext<'_>, expr: Ty<'_>, recv: Ty<'_>) -> Option<&'static str> {\n    types_match_diagnostic_item(cx, expr, recv, sym::HashSet)\n        .then_some(\"HashSet\")\n        .or_else(|| types_match_diagnostic_item(cx, expr, recv, sym::HashMap).then_some(\"HashMap\"))\n        .or_else(|| types_match_diagnostic_item(cx, expr, recv, sym::BinaryHeap).then_some(\"BinaryHeap\"))\n}\n\npub(super) fn check(cx: &LateContext<'_>, args: &[Expr<'_>], expr: &Expr<'_>, recv: &Expr<'_>) {\n    let expr_ty = cx.typeck_results().expr_ty(expr);\n    let recv_ty = cx.typeck_results().expr_ty(recv);\n    let recv_ty_no_refs = recv_ty.peel_refs();\n\n    if let ExprKind::Path(QPath::Resolved(_, recv_path)) = recv.kind\n        && let Some(typename) = check_vec(cx, args, expr_ty, recv_ty_no_refs, recv_path)\n            .then_some(\"Vec\")\n            .or_else(|| check_string(cx, args, expr_ty, recv_ty_no_refs, recv_path).then_some(\"String\"))\n            .or_else(|| check_collections(cx, expr_ty, recv_ty_no_refs))\n        && let Some(exec_context) = std_or_core(cx)\n    {\n        let recv = snippet(cx, recv.span, \"<expr>\");\n        let sugg = if let ty::Ref(..) = recv_ty.kind() {\n            format!(\"{exec_context}::mem::take({recv})\")\n        } else {\n            format!(\"{exec_context}::mem::take(&mut {recv})\")\n        };\n\n        span_lint_and_sugg(\n            cx,\n            DRAIN_COLLECT,\n            expr.span,\n            format!(\"you seem to be trying to move all elements into a new `{typename}`\"),\n            \"consider using `mem::take`\",\n            sugg,\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/err_expect.rs",
    "content": "use super::ERR_EXPECT;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::ty::has_debug_impl;\nuse rustc_errors::Applicability;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_middle::ty::Ty;\nuse rustc_span::{Span, sym};\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    _expr: &rustc_hir::Expr<'_>,\n    recv: &rustc_hir::Expr<'_>,\n    expect_span: Span,\n    err_span: Span,\n    msrv: Msrv,\n) {\n    let result_ty = cx.typeck_results().expr_ty(recv);\n    // Grabs the `Result<T, E>` type\n    if let Some(data_type) = get_data_type(cx, result_ty)\n        // Tests if the T type in a `Result<T, E>` implements Debug\n        && has_debug_impl(cx, data_type)\n        && msrv.meets(cx, msrvs::EXPECT_ERR)\n    {\n        span_lint_and_sugg(\n            cx,\n            ERR_EXPECT,\n            err_span.to(expect_span),\n            \"called `.err().expect()` on a `Result` value\",\n            \"try\",\n            \"expect_err\".to_string(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n\n/// Given a `Result<T, E>` type, return its data (`T`).\nfn get_data_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> {\n    match ty.kind() {\n        ty::Adt(adt, args) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => args.types().next(),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/expect_fun_call.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{contains_return, is_inside_always_const_context, peel_blocks, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\nuse std::borrow::Cow;\nuse std::ops::ControlFlow;\n\nuse super::EXPECT_FUN_CALL;\n\n/// Checks for the `EXPECT_FUN_CALL` lint.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    format_args_storage: &FormatArgsStorage,\n    expr: &hir::Expr<'_>,\n    method_span: Span,\n    receiver: &'tcx hir::Expr<'tcx>,\n    arg: &'tcx hir::Expr<'tcx>,\n) {\n    let arg_root = get_arg_root(cx, arg);\n    if contains_call(cx, arg_root) && !contains_return(arg_root) {\n        let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver);\n        let closure_args = match receiver_type.opt_diag_name(cx) {\n            Some(sym::Option) => \"||\",\n            Some(sym::Result) => \"|_|\",\n            _ => return,\n        };\n\n        let span_replace_word = method_span.with_hi(expr.span.hi());\n\n        let mut applicability = Applicability::MachineApplicable;\n\n        // Special handling for `format!` as arg_root\n        if let Some(macro_call) = root_macro_call_first_node(cx, arg_root) {\n            if cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)\n                && let Some(format_args) = format_args_storage.get(cx, arg_root, macro_call.expn)\n            {\n                let span = format_args_inputs_span(format_args);\n                let sugg = snippet_with_applicability(cx, span, \"..\", &mut applicability);\n                span_lint_and_sugg(\n                    cx,\n                    EXPECT_FUN_CALL,\n                    span_replace_word,\n                    \"function call inside of `expect`\",\n                    \"try\",\n                    format!(\"unwrap_or_else({closure_args} panic!({sugg}))\"),\n                    applicability,\n                );\n            }\n            return;\n        }\n\n        let arg_root_snippet: Cow<'_, _> = snippet_with_applicability(cx, arg_root.span, \"..\", &mut applicability);\n\n        span_lint_and_sugg(\n            cx,\n            EXPECT_FUN_CALL,\n            span_replace_word,\n            \"function call inside of `expect`\",\n            \"try\",\n            format!(\"unwrap_or_else({closure_args} panic!(\\\"{{}}\\\", {arg_root_snippet}))\"),\n            applicability,\n        );\n    }\n}\n\n/// Strip `{}`, `&`, `as_ref()` and `as_str()` off `arg` until we're left with either a `String` or\n/// `&str`\nfn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {\n    let mut arg_root = peel_blocks(arg);\n    loop {\n        arg_root = match &arg_root.kind {\n            hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => expr,\n            hir::ExprKind::MethodCall(method_name, receiver, [], ..) => {\n                if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && {\n                    let arg_type = cx.typeck_results().expr_ty(receiver);\n                    let base_type = arg_type.peel_refs();\n                    base_type.is_str() || base_type.is_lang_item(cx, hir::LangItem::String)\n                } {\n                    receiver\n                } else {\n                    break;\n                }\n            },\n            _ => break,\n        };\n    }\n    arg_root\n}\n\nfn contains_call<'a>(cx: &LateContext<'a>, arg: &'a hir::Expr<'a>) -> bool {\n    for_each_expr(cx, arg, |expr| {\n        if matches!(expr.kind, hir::ExprKind::MethodCall { .. } | hir::ExprKind::Call { .. })\n            && !is_inside_always_const_context(cx.tcx, expr.hir_id)\n        {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/extend_with_drain.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem};\nuse rustc_lint::LateContext;\n\nuse super::EXTEND_WITH_DRAIN;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) {\n    let ty = cx.typeck_results().expr_ty(recv).peel_refs();\n    if ty.is_diag_item(cx, sym::Vec)\n        //check source object\n        && let ExprKind::MethodCall(src_method, drain_vec, [drain_arg], _) = &arg.kind\n        && src_method.ident.name == sym::drain\n        && let src_ty = cx.typeck_results().expr_ty(drain_vec)\n        //check if actual src type is mutable for code suggestion\n        && let immutable = src_ty.is_mutable_ptr()\n        && let src_ty = src_ty.peel_refs()\n        && src_ty.is_diag_item(cx, sym::Vec)\n        //check drain range\n        && let src_ty_range = cx.typeck_results().expr_ty(drain_arg).peel_refs()\n        && src_ty_range.is_lang_item(cx, LangItem::RangeFull)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            EXTEND_WITH_DRAIN,\n            expr.span,\n            \"use of `extend` instead of `append` for adding the full range of a second vector\",\n            \"try\",\n            format!(\n                \"{}.append({}{})\",\n                snippet_with_applicability(cx, recv.span, \"..\", &mut applicability),\n                if immutable { \"\" } else { \"&mut \" },\n                snippet_with_applicability(cx, drain_vec.span, \"..\", &mut applicability)\n            ),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/filetype_is_file.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::{get_parent_expr, sym};\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::FILETYPE_IS_FILE;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {\n    let ty = cx.typeck_results().expr_ty(recv);\n\n    if !ty.is_diag_item(cx, sym::FileType) {\n        return;\n    }\n\n    let span: Span;\n    let verb: &str;\n    let lint_unary: &str;\n    let help_unary: &str;\n    if let Some(parent) = get_parent_expr(cx, expr)\n        && let hir::ExprKind::Unary(op, _) = parent.kind\n        && op == hir::UnOp::Not\n    {\n        lint_unary = \"!\";\n        verb = \"denies\";\n        help_unary = \"\";\n        span = parent.span;\n    } else {\n        lint_unary = \"\";\n        verb = \"covers\";\n        help_unary = \"!\";\n        span = expr.span;\n    }\n    let lint_msg = format!(\"`{lint_unary}FileType::is_file()` only {verb} regular files\");\n\n    #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n    span_lint_and_then(cx, FILETYPE_IS_FILE, span, lint_msg, |diag| {\n        diag.help(format!(\"use `{help_unary}FileType::is_dir()` instead\"));\n    });\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/filter_map.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::macros::{is_panic, matching_root_macro_call, root_macro_call};\nuse clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::source::{indent_of, reindent_multiline, snippet};\nuse clippy_utils::{SpanlessEq, higher, peel_blocks, sym};\nuse hir::{Body, HirId, MatchSource, Pat};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::def::Res;\nuse rustc_hir::{Closure, Expr, ExprKind, PatKind, PathSegment, QPath, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::TypeckResults;\nuse rustc_middle::ty::adjustment::Adjust;\nuse rustc_span::Span;\nuse rustc_span::symbol::{Ident, Symbol};\n\nuse super::{MANUAL_FILTER_MAP, MANUAL_FIND_MAP, OPTION_FILTER_MAP, RESULT_FILTER_MAP};\n\nfn is_method(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol) -> bool {\n    match &expr.kind {\n        ExprKind::Path(QPath::TypeRelative(_, mname)) => mname.ident.name == method_name,\n        ExprKind::Path(QPath::Resolved(_, segments)) => segments.segments.last().unwrap().ident.name == method_name,\n        ExprKind::MethodCall(segment, _, _, _) => segment.ident.name == method_name,\n        ExprKind::Closure(Closure { body, .. }) => {\n            let body = cx.tcx.hir_body(*body);\n            let closure_expr = peel_blocks(body.value);\n            match closure_expr.kind {\n                ExprKind::MethodCall(PathSegment { ident, .. }, receiver, ..) => {\n                    if ident.name == method_name\n                        && let ExprKind::Path(path) = &receiver.kind\n                        && let Res::Local(ref local) = cx.qpath_res(path, receiver.hir_id)\n                        && !body.params.is_empty()\n                    {\n                        let arg_id = body.params[0].pat.hir_id;\n                        return arg_id == *local;\n                    }\n                    false\n                },\n                _ => false,\n            }\n        },\n        _ => false,\n    }\n}\n\nfn is_option_filter_map(cx: &LateContext<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {\n    is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym::is_some)\n}\nfn is_ok_filter_map(cx: &LateContext<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {\n    is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym::is_ok)\n}\n\n#[derive(Debug, Copy, Clone)]\nenum OffendingFilterExpr<'tcx> {\n    /// `.filter(|opt| opt.is_some())`\n    IsSome {\n        /// The receiver expression\n        receiver: &'tcx Expr<'tcx>,\n        /// If `Some`, then this contains the span of an expression that possibly contains side\n        /// effects: `.filter(|opt| side_effect(opt).is_some())`\n        ///                         ^^^^^^^^^^^^^^^^\n        ///\n        /// We will use this later for warning the user that the suggested fix may change\n        /// the behavior.\n        side_effect_expr_span: Option<Span>,\n    },\n    /// `.filter(|res| res.is_ok())`\n    IsOk {\n        /// The receiver expression\n        receiver: &'tcx Expr<'tcx>,\n        /// See `IsSome`\n        side_effect_expr_span: Option<Span>,\n    },\n    /// `.filter(|enum| matches!(enum, Enum::A(_)))`\n    Matches {\n        /// The `DefId` of the variant being matched\n        variant_def_id: hir::def_id::DefId,\n    },\n}\n\n#[derive(Debug)]\nenum CalledMethod {\n    OptionIsSome,\n    ResultIsOk,\n}\n\n/// The result of checking a `map` call, returned by `OffendingFilterExpr::check_map_call`\n#[derive(Debug)]\nenum CheckResult<'tcx> {\n    Method {\n        map_arg: &'tcx Expr<'tcx>,\n        /// The method that was called inside of `filter`\n        method: CalledMethod,\n        /// See `OffendingFilterExpr::IsSome`\n        side_effect_expr_span: Option<Span>,\n    },\n    PatternMatching {\n        /// The span of the variant being matched\n        /// if let Some(s) = enum\n        ///        ^^^^^^^\n        variant_span: Span,\n        /// if let Some(s) = enum\n        ///             ^\n        variant_ident: Ident,\n    },\n}\n\nimpl<'tcx> OffendingFilterExpr<'tcx> {\n    pub fn check_map_call(\n        &self,\n        cx: &LateContext<'tcx>,\n        map_body: &'tcx Body<'tcx>,\n        map_param_id: HirId,\n        filter_param_id: HirId,\n        is_filter_param_ref: bool,\n    ) -> Option<CheckResult<'tcx>> {\n        match *self {\n            OffendingFilterExpr::IsSome {\n                receiver,\n                side_effect_expr_span,\n            }\n            | OffendingFilterExpr::IsOk {\n                receiver,\n                side_effect_expr_span,\n            } => {\n                // check if closure ends with expect() or unwrap()\n                if let ExprKind::MethodCall(seg, map_arg, ..) = map_body.value.kind\n                    && matches!(seg.ident.name, sym::expect | sym::unwrap | sym::unwrap_or)\n                    // .map(|y| f(y).copied().unwrap())\n                    //          ~~~~\n                    && let map_arg_peeled = match map_arg.kind {\n                        ExprKind::MethodCall(method, original_arg, [], _) if acceptable_methods(method) => {\n                            original_arg\n                        },\n                        _ => map_arg,\n                    }\n                    // .map(|y| y[.acceptable_method()].unwrap())\n                    && let simple_equal = (receiver.res_local_id() == Some(filter_param_id)\n                        && map_arg_peeled.res_local_id() == Some(map_param_id))\n                    && let eq_fallback =\n                    (|a_typeck_results: &TypeckResults<'tcx>, a: &Expr<'_>,\n                     b_typeck_results: &TypeckResults<'tcx>, b: &Expr<'_>| {\n                        // in `filter(|x| ..)`, replace `*x` with `x`\n                        let a_path = if !is_filter_param_ref\n                            && let ExprKind::Unary(UnOp::Deref, expr_path) = a.kind\n                        { expr_path } else { a };\n                        // let the filter closure arg and the map closure arg be equal\n                        a_path.res_local_id() == Some(filter_param_id)\n                            && b.res_local_id() == Some(map_param_id)\n                            && a_typeck_results.expr_ty_adjusted(a) == b_typeck_results.expr_ty_adjusted(b)\n                    })\n                    && (simple_equal\n                        || SpanlessEq::new(cx).expr_fallback(eq_fallback).eq_expr(receiver, map_arg_peeled))\n                {\n                    Some(CheckResult::Method {\n                        map_arg,\n                        side_effect_expr_span,\n                        method: match self {\n                            OffendingFilterExpr::IsSome { .. } => CalledMethod::OptionIsSome,\n                            OffendingFilterExpr::IsOk { .. } => CalledMethod::ResultIsOk,\n                            OffendingFilterExpr::Matches { .. } => unreachable!(\"only IsSome and IsOk can get here\"),\n                        },\n                    })\n                } else {\n                    None\n                }\n            },\n            OffendingFilterExpr::Matches { variant_def_id } => {\n                let expr_uses_local = |pat: &Pat<'_>, expr: &Expr<'_>| {\n                    if let PatKind::TupleStruct(QPath::Resolved(_, path), [subpat], _) = pat.kind\n                        && let PatKind::Binding(_, local_id, ident, _) = subpat.kind\n                        && expr.peel_blocks().res_local_id() == Some(local_id)\n                        && let Some(local_variant_def_id) = path.res.opt_def_id()\n                        && local_variant_def_id == variant_def_id\n                    {\n                        Some((ident, pat.span))\n                    } else {\n                        None\n                    }\n                };\n\n                // look for:\n                // `if let Variant   (v) =         enum { v } else { unreachable!() }`\n                //         ^^^^^^^    ^            ^^^^            ^^^^^^^^^^^^^^^^^^\n                //    variant_span  variant_ident  scrutinee       else_ (blocks peeled later)\n                // OR\n                // `match enum {   Variant       (v) => v,      _ => unreachable!() }`\n                //        ^^^^     ^^^^^^^        ^                  ^^^^^^^^^^^^^^\n                //     scrutinee  variant_span  variant_ident        else_\n                let (scrutinee, else_, variant_ident, variant_span) =\n                    match higher::IfLetOrMatch::parse(cx, map_body.value) {\n                        // For `if let` we want to check that the variant matching arm references the local created by\n                        // its pattern\n                        Some(higher::IfLetOrMatch::IfLet(sc, pat, then, Some(else_), ..))\n                            if let Some((ident, span)) = expr_uses_local(pat, then) =>\n                        {\n                            (sc, else_, ident, span)\n                        },\n                        // For `match` we want to check that the \"else\" arm is the wildcard (`_`) pattern\n                        // and that the variant matching arm references the local created by its pattern\n                        Some(higher::IfLetOrMatch::Match(sc, [arm, wild_arm], MatchSource::Normal))\n                            if let PatKind::Wild = wild_arm.pat.kind\n                                && let Some((ident, span)) = expr_uses_local(arm.pat, arm.body.peel_blocks()) =>\n                        {\n                            (sc, wild_arm.body, ident, span)\n                        },\n                        _ => return None,\n                    };\n\n                if scrutinee.res_local_id() == Some(map_param_id)\n                    // else branch should be a `panic!` or `unreachable!` macro call\n                    && let Some(mac) = root_macro_call(else_.peel_blocks().span)\n                    && (is_panic(cx, mac.def_id) || cx.tcx.opt_item_name(mac.def_id) == Some(sym::unreachable))\n                {\n                    Some(CheckResult::PatternMatching {\n                        variant_span,\n                        variant_ident,\n                    })\n                } else {\n                    None\n                }\n            },\n        }\n    }\n\n    fn hir(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, filter_param_id: HirId) -> Option<Self> {\n        if let ExprKind::MethodCall(path, receiver, [], _) = expr.kind\n            && let Some(recv_ty) = cx.typeck_results().expr_ty(receiver).peel_refs().ty_adt_def()\n        {\n            // we still want to lint if the expression possibly contains side effects,\n            // *but* it can't be machine-applicable then, because that can change the behavior of the program:\n            // .filter(|x| effect(x).is_some()).map(|x| effect(x).unwrap())\n            // vs.\n            // .filter_map(|x| effect(x))\n            //\n            // the latter only calls `effect` once\n            let side_effect_expr_span = receiver.can_have_side_effects().then_some(receiver.span);\n\n            match (cx.tcx.get_diagnostic_name(recv_ty.did()), path.ident.name) {\n                (Some(sym::Option), sym::is_some) => Some(Self::IsSome {\n                    receiver,\n                    side_effect_expr_span,\n                }),\n                (Some(sym::Result), sym::is_ok) => Some(Self::IsOk {\n                    receiver,\n                    side_effect_expr_span,\n                }),\n                _ => None,\n            }\n        } else if matching_root_macro_call(cx, expr.span, sym::matches_macro).is_some()\n            // we know for a fact that the wildcard pattern is the second arm\n            && let ExprKind::Match(scrutinee, [arm, _], _) = expr.kind\n            && scrutinee.res_local_id() == Some(filter_param_id)\n            && let PatKind::TupleStruct(QPath::Resolved(_, path), ..) = arm.pat.kind\n            && let Some(variant_def_id) = path.res.opt_def_id()\n        {\n            Some(OffendingFilterExpr::Matches { variant_def_id })\n        } else {\n            None\n        }\n    }\n}\n\n/// is `filter(|x| x.is_some()).map(|x| x.unwrap())`\nfn is_filter_some_map_unwrap(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    filter_recv: &Expr<'_>,\n    filter_arg: &Expr<'_>,\n    map_arg: &Expr<'_>,\n) -> bool {\n    let iterator = cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator);\n    let option = cx.typeck_results().expr_ty(filter_recv).is_diag_item(cx, sym::Option);\n\n    (iterator || option) && is_option_filter_map(cx, filter_arg, map_arg)\n}\n\n/// is `filter(|x| x.is_ok()).map(|x| x.unwrap())`\nfn is_filter_ok_map_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {\n    // result has no filter, so we only check for iterators\n    let iterator = cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator);\n    iterator && is_ok_filter_map(cx, filter_arg, map_arg)\n}\n\n/// lint use of `filter().map()` or `find().map()` for `Iterators`\n#[expect(clippy::too_many_arguments)]\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    filter_recv: &Expr<'_>,\n    filter_arg: &Expr<'_>,\n    filter_span: Span,\n    map_recv: &Expr<'_>,\n    map_arg: &Expr<'_>,\n    map_span: Span,\n    is_find: bool,\n) {\n    if is_filter_some_map_unwrap(cx, expr, filter_recv, filter_arg, map_arg) {\n        span_lint_and_sugg(\n            cx,\n            OPTION_FILTER_MAP,\n            filter_span.with_hi(expr.span.hi()),\n            \"`filter` for `Some` followed by `unwrap`\",\n            \"consider using `flatten` instead\",\n            reindent_multiline(\"flatten()\", true, indent_of(cx, map_span)),\n            Applicability::MachineApplicable,\n        );\n\n        return;\n    }\n\n    if is_filter_ok_map_unwrap(cx, expr, filter_arg, map_arg) {\n        span_lint_and_sugg(\n            cx,\n            RESULT_FILTER_MAP,\n            filter_span.with_hi(expr.span.hi()),\n            \"`filter` for `Ok` followed by `unwrap`\",\n            \"consider using `flatten` instead\",\n            reindent_multiline(\"flatten()\", true, indent_of(cx, map_span)),\n            Applicability::MachineApplicable,\n        );\n\n        return;\n    }\n\n    if let Some((map_param_ident, check_result)) = is_find_or_filter(cx, map_recv, filter_arg, map_arg) {\n        let span = filter_span.with_hi(expr.span.hi());\n        let (filter_name, lint) = if is_find {\n            (\"find\", MANUAL_FIND_MAP)\n        } else {\n            (\"filter\", MANUAL_FILTER_MAP)\n        };\n        let msg = format!(\"`{filter_name}(..).map(..)` can be simplified as `{filter_name}_map(..)`\");\n\n        let (sugg, note_and_span, applicability) = match check_result {\n            CheckResult::Method {\n                map_arg,\n                method,\n                side_effect_expr_span,\n            } => {\n                let (to_opt, deref) = match method {\n                    CalledMethod::ResultIsOk => (\".ok()\", String::new()),\n                    CalledMethod::OptionIsSome => {\n                        let derefs = cx\n                            .typeck_results()\n                            .expr_adjustments(map_arg)\n                            .iter()\n                            .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))\n                            .count();\n\n                        (\"\", \"*\".repeat(derefs))\n                    },\n                };\n\n                let sugg = format!(\n                    \"{filter_name}_map(|{map_param_ident}| {deref}{}{to_opt})\",\n                    snippet(cx, map_arg.span, \"..\"),\n                );\n                let (note_and_span, applicability) = if let Some(span) = side_effect_expr_span {\n                    let note = \"the suggestion might change the behavior of the program when merging `filter` and `map`, \\\n                        because this expression potentially contains side effects and will only execute once\";\n\n                    (Some((note, span)), Applicability::MaybeIncorrect)\n                } else {\n                    (None, Applicability::MachineApplicable)\n                };\n\n                (sugg, note_and_span, applicability)\n            },\n            CheckResult::PatternMatching {\n                variant_span,\n                variant_ident,\n            } => {\n                let pat = snippet(cx, variant_span, \"<pattern>\");\n\n                (\n                    format!(\n                        \"{filter_name}_map(|{map_param_ident}| match {map_param_ident} {{ \\\n                    {pat} => Some({variant_ident}), \\\n                    _ => None \\\n                }})\"\n                    ),\n                    None,\n                    Applicability::MachineApplicable,\n                )\n            },\n        };\n        span_lint_and_then(cx, lint, span, msg, |diag| {\n            diag.span_suggestion(span, \"try\", sugg, applicability);\n\n            if let Some((note, span)) = note_and_span {\n                diag.span_note(span, note);\n            }\n        });\n    }\n}\n\nfn is_find_or_filter<'a>(\n    cx: &LateContext<'a>,\n    map_recv: &Expr<'_>,\n    filter_arg: &Expr<'_>,\n    map_arg: &Expr<'_>,\n) -> Option<(Ident, CheckResult<'a>)> {\n    if cx.ty_based_def(map_recv).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        // filter(|x| ...is_some())...\n        && let ExprKind::Closure(&Closure { body: filter_body_id, .. }) = filter_arg.kind\n        && let filter_body = cx.tcx.hir_body(filter_body_id)\n        && let [filter_param] = filter_body.params\n        // optional ref pattern: `filter(|&x| ..)`\n        && let (filter_pat, is_filter_param_ref) = if let PatKind::Ref(ref_pat, _, _) = filter_param.pat.kind {\n            (ref_pat, true)\n        } else {\n            (filter_param.pat, false)\n        }\n\n        && let PatKind::Binding(_, filter_param_id, _, None) = filter_pat.kind\n        && let Some(offending_expr) = OffendingFilterExpr::hir(cx, filter_body.value, filter_param_id)\n\n        && let ExprKind::Closure(&Closure { body: map_body_id, .. }) = map_arg.kind\n        && let map_body = cx.tcx.hir_body(map_body_id)\n        && let [map_param] = map_body.params\n        && let PatKind::Binding(_, map_param_id, map_param_ident, None) = map_param.pat.kind\n\n        && let Some(check_result) =\n            offending_expr.check_map_call(cx, map_body, map_param_id, filter_param_id, is_filter_param_ref)\n    {\n        return Some((map_param_ident, check_result));\n    }\n    None\n}\n\nfn acceptable_methods(method: &PathSegment<'_>) -> bool {\n    matches!(\n        method.ident.name,\n        sym::clone\n            | sym::as_ref\n            | sym::copied\n            | sym::cloned\n            | sym::as_deref\n            | sym::as_mut\n            | sym::as_deref_mut\n            | sym::to_owned\n    )\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/filter_map_bool_then.rs",
    "content": "use super::FILTER_MAP_BOOL_THEN;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::{SpanRangeExt, snippet_with_context};\nuse clippy_utils::ty::is_copy;\nuse clippy_utils::{CaptureKind, can_move_expr_to_closure, contains_return, is_from_proc_macro, peel_blocks, sym};\nuse rustc_ast::Mutability;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, HirId, Param, Pat};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::Binder;\nuse rustc_middle::ty::adjustment::Adjust;\nuse rustc_span::Span;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &Expr<'_>, call_span: Span) {\n    if !expr.span.in_external_macro(cx.sess().source_map())\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let ExprKind::Closure(closure) = arg.kind\n        && let body = cx.tcx.hir_body(closure.body)\n        && let value = peel_blocks(body.value)\n        // Indexing should be fine as `filter_map` always has 1 input, we unfortunately need both\n        // `inputs` and `params` here as we need both the type and the span\n        && let param_ty = closure.fn_decl.inputs[0]\n        && let param = body.params[0]\n        // Issue #11309\n        && let param_ty = cx.tcx.liberate_late_bound_regions(\n            closure.def_id.to_def_id(),\n            Binder::bind_with_vars(\n                cx.typeck_results().node_type(param_ty.hir_id),\n                cx.tcx.late_bound_vars(cx.tcx.local_def_id_to_hir_id(closure.def_id)),\n            ),\n        )\n        && is_copy(cx, param_ty)\n        && let ExprKind::MethodCall(_, recv, [then_arg], _) = value.kind\n        && let ExprKind::Closure(then_closure) = then_arg.kind\n        && let then_body = peel_blocks(cx.tcx.hir_body(then_closure.body).value)\n        && let Some(def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::bool_then, def_id)\n        && !is_from_proc_macro(cx, expr)\n        // Count the number of derefs needed to get to the bool because we need those in the suggestion\n        && let needed_derefs = cx.typeck_results().expr_adjustments(recv)\n            .iter()\n            .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))\n            .count()\n        && let Some(param_snippet) = param.span.get_source_text(cx)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let (filter, _) = snippet_with_context(cx, recv.span, expr.span.ctxt(), \"..\", &mut applicability);\n        let (map, _) = snippet_with_context(cx, then_body.span, expr.span.ctxt(), \"..\", &mut applicability);\n\n        span_lint_and_then(\n            cx,\n            FILTER_MAP_BOOL_THEN,\n            call_span,\n            \"usage of `bool::then` in `filter_map`\",\n            |diag| {\n                if can_filter_and_then_move_to_closure(cx, &param, recv, then_body) {\n                    diag.span_suggestion(\n                        call_span,\n                        \"use `filter` then `map` instead\",\n                        format!(\n                            \"filter(|&{param_snippet}| {derefs}{filter}).map(|{param_snippet}| {map})\",\n                            derefs = \"*\".repeat(needed_derefs)\n                        ),\n                        applicability,\n                    );\n                } else {\n                    diag.help(\"consider using `filter` then `map` instead\");\n                }\n            },\n        );\n    }\n}\n\n/// Returns a set of all bindings found in the given pattern.\nfn find_bindings_from_pat(pat: &Pat<'_>) -> FxHashSet<HirId> {\n    let mut bindings = FxHashSet::default();\n    pat.walk(|p| {\n        if let rustc_hir::PatKind::Binding(_, hir_id, _, _) = p.kind {\n            bindings.insert(hir_id);\n        }\n        true\n    });\n    bindings\n}\n\n/// Returns true if we can take a closure parameter and have it in both the `filter` function and\n/// the`map` function. This is not the case if:\n///\n/// - The `filter` would contain an early return,\n/// - `filter` and `then` contain captures, and any of those are &mut\nfn can_filter_and_then_move_to_closure<'tcx>(\n    cx: &LateContext<'tcx>,\n    param: &Param<'tcx>,\n    filter: &'tcx Expr<'tcx>,\n    then: &'tcx Expr<'tcx>,\n) -> bool {\n    if contains_return(filter) {\n        return false;\n    }\n\n    let Some(filter_captures) = can_move_expr_to_closure(cx, filter) else {\n        return true;\n    };\n    let Some(then_captures) = can_move_expr_to_closure(cx, then) else {\n        return true;\n    };\n\n    let param_bindings = find_bindings_from_pat(param.pat);\n    filter_captures.iter().all(|(hir_id, filter_cap)| {\n        param_bindings.contains(hir_id)\n            || !then_captures\n                .get(hir_id)\n                .is_some_and(|then_cap| matches!(*filter_cap | *then_cap, CaptureKind::Ref(Mutability::Mut)))\n    })\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/filter_map_identity.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::{is_expr_identity_function, is_expr_untyped_identity_function};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::ExprKind;\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, sym};\n\nuse super::FILTER_MAP_IDENTITY;\n\nfn is_identity(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Applicability> {\n    if is_expr_untyped_identity_function(cx, expr) {\n        return Some(Applicability::MachineApplicable);\n    }\n    if is_expr_identity_function(cx, expr) {\n        return Some(Applicability::Unspecified);\n    }\n    None\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg: &hir::Expr<'_>, filter_map_span: Span) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let Some(applicability) = is_identity(cx, filter_map_arg)\n    {\n        // check if the iterator is from an empty array, see issue #12653\n        if let ExprKind::MethodCall(_, recv, ..) = expr.kind\n            && let ExprKind::MethodCall(_, recv2, ..) = recv.kind\n            && let ExprKind::Array(arr) = recv2.kind\n            && arr.is_empty()\n        {\n            return;\n        }\n\n        span_lint_and_sugg(\n            cx,\n            FILTER_MAP_IDENTITY,\n            filter_map_span.with_hi(expr.span.hi()),\n            \"use of `filter_map` with an identity function\",\n            \"try\",\n            \"flatten()\".to_string(),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/filter_map_next.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::FILTER_MAP_NEXT;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'_>,\n    arg: &'tcx hir::Expr<'_>,\n    msrv: Msrv,\n) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        if !msrv.meets(cx, msrvs::ITERATOR_FIND_MAP) {\n            return;\n        }\n\n        let msg = \"called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \\\n                   `.find_map(..)` instead\";\n        let filter_snippet = snippet(cx, arg.span, \"..\");\n        if filter_snippet.lines().count() <= 1 {\n            let iter_snippet = snippet(cx, recv.span, \"..\");\n            span_lint_and_sugg(\n                cx,\n                FILTER_MAP_NEXT,\n                expr.span,\n                msg,\n                \"try\",\n                format!(\"{iter_snippet}.find_map({filter_snippet})\"),\n                Applicability::MachineApplicable,\n            );\n        } else {\n            span_lint(cx, FILTER_MAP_NEXT, expr.span, msg);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/filter_next.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{path_to_local_with_projections, sym};\nuse rustc_ast::{BindingMode, Mutability};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\n\nuse super::FILTER_NEXT;\n\n#[derive(Copy, Clone)]\npub(super) enum Direction {\n    Forward,\n    Backward,\n}\n\n/// lint use of `filter().next()` for `Iterator` and `filter().next_back()` for\n/// `DoubleEndedIterator`\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'_>,\n    filter_arg: &'tcx hir::Expr<'_>,\n    direction: Direction,\n) {\n    // lint if caller of `.filter().next()` is an Iterator or `.filter().next_back()` is a\n    // DoubleEndedIterator\n    let (required_trait, next_method, find_method) = match direction {\n        Direction::Forward => (sym::Iterator, \"next\", \"find\"),\n        Direction::Backward => (sym::DoubleEndedIterator, \"next_back\", \"rfind\"),\n    };\n    if !cx\n        .tcx\n        .get_diagnostic_item(required_trait)\n        .is_some_and(|id| implements_trait(cx, cx.typeck_results().expr_ty(recv), id, &[]))\n    {\n        return;\n    }\n    let msg = format!(\n        \"called `filter(..).{next_method}()` on an `{}`. This is more succinctly expressed by calling \\\n                   `.{find_method}(..)` instead\",\n        required_trait.as_str()\n    );\n    let filter_snippet = snippet(cx, filter_arg.span, \"..\");\n    if filter_snippet.lines().count() <= 1 {\n        let iter_snippet = snippet(cx, recv.span, \"..\");\n        // add note if not multi-line\n        span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| {\n            let (applicability, pat) = if let Some(id) = path_to_local_with_projections(recv)\n                && let hir::Node::Pat(pat) = cx.tcx.hir_node(id)\n                && let hir::PatKind::Binding(BindingMode(_, Mutability::Not), _, ident, _) = pat.kind\n            {\n                (Applicability::Unspecified, Some((pat.span, ident)))\n            } else {\n                (Applicability::MachineApplicable, None)\n            };\n\n            diag.span_suggestion(\n                expr.span,\n                \"try\",\n                format!(\"{iter_snippet}.{find_method}({filter_snippet})\"),\n                applicability,\n            );\n\n            if let Some((pat_span, ident)) = pat {\n                diag.span_help(\n                    pat_span,\n                    format!(\"you will also need to make `{ident}` mutable, because `{find_method}` takes `&mut self`\"),\n                );\n            }\n        });\n    } else {\n        span_lint(cx, FILTER_NEXT, expr.span, msg);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/flat_map_identity.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_expr_untyped_identity_function;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, sym};\n\nuse super::FLAT_MAP_IDENTITY;\n\n/// lint use of `flat_map` for `Iterators` where `flatten` would be sufficient\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    flat_map_arg: &'tcx hir::Expr<'_>,\n    flat_map_span: Span,\n) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && is_expr_untyped_identity_function(cx, flat_map_arg)\n    {\n        span_lint_and_sugg(\n            cx,\n            FLAT_MAP_IDENTITY,\n            flat_map_span.with_hi(expr.span.hi()),\n            \"use of `flat_map` with an identity function\",\n            \"try\",\n            \"flatten()\".to_string(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/flat_map_option.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, sym};\n\nuse super::FLAT_MAP_OPTION;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>, span: Span) {\n    if !cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        return;\n    }\n    let arg_ty = cx.typeck_results().expr_ty_adjusted(arg);\n    let sig = match arg_ty.kind() {\n        ty::Closure(_, args) => args.as_closure().sig(),\n        _ if arg_ty.is_fn() => arg_ty.fn_sig(cx.tcx),\n        _ => return,\n    };\n    if !sig.output().skip_binder().is_diag_item(cx, sym::Option) {\n        return;\n    }\n    span_lint_and_sugg(\n        cx,\n        FLAT_MAP_OPTION,\n        span,\n        \"used `flat_map` where `filter_map` could be used instead\",\n        \"try\",\n        \"filter_map\".into(),\n        Applicability::MachineApplicable,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/format_collect.rs",
    "content": "use super::FORMAT_COLLECT;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{is_format_macro, root_macro_call_first_node};\nuse clippy_utils::res::MaybeDef;\nuse rustc_hir::{Expr, ExprKind, LangItem};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\n/// Same as `peel_blocks` but only actually considers blocks that are not from an expansion.\n/// This is needed because always calling `peel_blocks` would otherwise remove parts of the\n/// `format!` macro, which would cause `root_macro_call_first_node` to return `None`.\nfn peel_non_expn_blocks<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    match expr.kind {\n        ExprKind::Block(block, _) if !expr.span.from_expansion() => peel_non_expn_blocks(block.expr?),\n        _ => Some(expr),\n    }\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, map_arg: &Expr<'_>, map_span: Span) {\n    if cx.typeck_results().expr_ty(expr).is_lang_item(cx, LangItem::String)\n        && let ExprKind::Closure(closure) = map_arg.kind\n        && let body = cx.tcx.hir_body(closure.body)\n        && let Some(value) = peel_non_expn_blocks(body.value)\n        && let Some(mac) = root_macro_call_first_node(cx, value)\n        && is_format_macro(cx, mac.def_id)\n    {\n        span_lint_and_then(\n            cx,\n            FORMAT_COLLECT,\n            expr.span,\n            \"use of `format!` to build up a string from an iterator\",\n            |diag| {\n                diag.span_help(map_span, \"call `fold` instead\")\n                    .span_help(value.span.source_callsite(), \"... and use the `write!` macro here\")\n                    .note(\"this can be written more efficiently by appending to a `String` directly\");\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/from_iter_instead_of_collect.rs",
    "content": "use std::fmt::Write as _;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{sugg, sym};\nuse rustc_ast::join_path_idents;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{self as hir, Expr, ExprKind, GenericArg, QPath, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::GenericParamDefKind;\n\nuse super::FROM_ITER_INSTEAD_OF_COLLECT;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>], func: &Expr<'_>) {\n    if func.res(cx).is_diag_item(cx, sym::from_iter_fn)\n        && let arg_ty = cx.typeck_results().expr_ty(&args[0])\n        && let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator)\n        && implements_trait(cx, arg_ty, iter_id, &[])\n    {\n        let mut app = Applicability::MaybeIncorrect;\n        let turbofish = match func.kind {\n            ExprKind::Path(QPath::TypeRelative(hir_ty, _)) => build_full_type(cx, hir_ty, &mut app),\n            ExprKind::Path(QPath::Resolved(Some(self_ty), _)) => build_full_type(cx, self_ty, &mut app),\n            _ => return,\n        };\n        let iter_expr = sugg::Sugg::hir(cx, &args[0], \"..\").maybe_paren();\n        let sugg = format!(\"{iter_expr}.collect::<{turbofish}>()\");\n        span_lint_and_sugg(\n            cx,\n            FROM_ITER_INSTEAD_OF_COLLECT,\n            expr.span,\n            \"usage of `FromIterator::from_iter`\",\n            \"use `.collect()` instead of `::from_iter()`\",\n            sugg,\n            app,\n        );\n    }\n}\n\n/// Build a type which can be used in a turbofish syntax from `hir_ty`, either by copying the\n/// existing generic arguments with the exception of elided lifetimes, or by inserting placeholders\n/// for types and consts without default values.\nfn build_full_type(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, app: &mut Applicability) -> String {\n    if let TyKind::Path(ty_qpath) = hir_ty.kind\n        && let QPath::Resolved(None, ty_path) = &ty_qpath\n        && let Res::Def(_, ty_did) = ty_path.res\n    {\n        let mut ty_str = join_path_idents(ty_path.segments.iter().map(|seg| seg.ident));\n        let mut first = true;\n        let mut append = |arg: &str| {\n            write!(&mut ty_str, \"{}{arg}\", [\", \", \"<\"][usize::from(first)]).unwrap();\n            first = false;\n        };\n        if let Some(args) = ty_path.segments.last().and_then(|segment| segment.args) {\n            args.args\n                .iter()\n                .filter(|arg| !matches!(arg, GenericArg::Lifetime(lt) if lt.is_elided()))\n                .for_each(|arg| append(&snippet_with_applicability(cx, arg.span().source_callsite(), \"_\", app)));\n        } else {\n            cx.tcx\n                .generics_of(ty_did)\n                .own_params\n                .iter()\n                .filter(|param| {\n                    matches!(\n                        param.kind,\n                        GenericParamDefKind::Type { has_default: false, .. }\n                            | GenericParamDefKind::Const { has_default: false, .. }\n                    )\n                })\n                .for_each(|_| append(\"_\"));\n        }\n        ty_str.push_str([\">\", \"\"][usize::from(first)]);\n        ty_str\n    } else {\n        snippet_with_applicability(cx, hir_ty.span.source_callsite(), \"_\", app).into()\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/get_first.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse rustc_ast::LitKind;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\n\nuse super::GET_FIRST;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'_>,\n    arg: &'tcx hir::Expr<'_>,\n) {\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && let identity = cx.tcx.type_of(impl_id).instantiate_identity()\n        && let hir::ExprKind::Lit(Spanned {\n            node: LitKind::Int(Pu128(0), _),\n            ..\n        }) = arg.kind\n    {\n        if identity.is_slice() {\n            let mut app = Applicability::MachineApplicable;\n            let slice_name = snippet_with_applicability(cx, recv.span, \"..\", &mut app);\n            span_lint_and_sugg(\n                cx,\n                GET_FIRST,\n                expr.span,\n                format!(\"accessing first element with `{slice_name}.get(0)`\"),\n                \"try\",\n                format!(\"{slice_name}.first()\"),\n                app,\n            );\n        } else if identity.is_diag_item(cx, sym::VecDeque) {\n            let mut app = Applicability::MachineApplicable;\n            let slice_name = snippet_with_applicability(cx, recv.span, \"..\", &mut app);\n            span_lint_and_sugg(\n                cx,\n                GET_FIRST,\n                expr.span,\n                format!(\"accessing first element with `{slice_name}.get(0)`\"),\n                \"try\",\n                format!(\"{slice_name}.front()\"),\n                app,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/get_last_with_len.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{SpanlessEq, is_integer_literal, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::source_map::Spanned;\n\nuse super::GET_LAST_WITH_LEN;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) {\n    // Argument to \"get\" is a subtraction\n    if let ExprKind::Binary(\n        Spanned {\n            node: BinOpKind::Sub, ..\n        },\n        lhs,\n        rhs,\n    ) = arg.kind\n\n        // LHS of subtraction is \"x.len()\"\n        && let ExprKind::MethodCall(lhs_path, lhs_recv, [], _) = &lhs.kind\n        && lhs_path.ident.name == sym::len\n\n        // RHS of subtraction is 1\n        && is_integer_literal(rhs, 1)\n\n        // check that recv == lhs_recv `recv.get(lhs_recv.len() - 1)`\n        && SpanlessEq::new(cx).eq_expr(recv, lhs_recv)\n        && !recv.can_have_side_effects()\n    {\n        let method = match cx.typeck_results().expr_ty_adjusted(recv).peel_refs().kind() {\n            ty::Adt(def, _) if cx.tcx.is_diagnostic_item(sym::VecDeque, def.did()) => \"back\",\n            ty::Slice(_) => \"last\",\n            _ => return,\n        };\n\n        let mut applicability = Applicability::MachineApplicable;\n        let recv_snippet = snippet_with_applicability(cx, recv.span, \"_\", &mut applicability);\n\n        span_lint_and_sugg(\n            cx,\n            GET_LAST_WITH_LEN,\n            expr.span,\n            format!(\"accessing last element with `{recv_snippet}.get({recv_snippet}.len() - 1)`\"),\n            \"try\",\n            format!(\"{recv_snippet}.{method}()\"),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/get_unwrap.rs",
    "content": "use super::utils::derefs_to_slice;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{get_parent_expr, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\n\nuse super::GET_UNWRAP;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'tcx>,\n    get_arg: &'tcx hir::Expr<'_>,\n    is_mut: bool,\n) {\n    // Note: we don't want to lint `get_mut().unwrap` for `HashMap` or `BTreeMap`,\n    // because they do not implement `IndexMut`\n    let expr_ty = cx.typeck_results().expr_ty(recv);\n    let caller_type = if derefs_to_slice(cx, recv, expr_ty).is_some() {\n        \"slice\"\n    } else {\n        match expr_ty\n            .ty_adt_def()\n            .and_then(|def| cx.tcx.get_diagnostic_name(def.did()))\n        {\n            Some(sym::Vec) => \"Vec\",\n            Some(sym::VecDeque) => \"VecDeque\",\n            Some(sym::HashMap) if !is_mut => \"HashMap\",\n            Some(sym::BTreeMap) if !is_mut => \"BTreeMap\",\n            _ => return, // caller is not a type that we want to lint\n        }\n    };\n\n    let mut span = expr.span;\n\n    // Handle the case where the result is immediately dereferenced,\n    // either directly be the user, or as a result of a method call or the like\n    // by not requiring an explicit reference\n    let needs_ref = if let Some(parent) = get_parent_expr(cx, expr)\n        && let hir::ExprKind::Unary(hir::UnOp::Deref, _)\n        | hir::ExprKind::MethodCall(..)\n        | hir::ExprKind::Field(..)\n        | hir::ExprKind::Index(..) = parent.kind\n    {\n        if let hir::ExprKind::Unary(hir::UnOp::Deref, _) = parent.kind {\n            // if the user explicitly dereferences the result, we can adjust\n            // the span to also include the deref part\n            span = parent.span;\n        }\n        false\n    } else {\n        true\n    };\n\n    let mut_str = if is_mut { \"_mut\" } else { \"\" };\n\n    span_lint_and_then(\n        cx,\n        GET_UNWRAP,\n        span,\n        format!(\"called `.get{mut_str}().unwrap()` on a {caller_type}\"),\n        |diag| {\n            let mut applicability = Applicability::MachineApplicable;\n            let get_args_str = snippet_with_applicability(cx, get_arg.span, \"..\", &mut applicability);\n\n            let borrow_str = if !needs_ref {\n                \"\"\n            } else if is_mut {\n                \"&mut \"\n            } else {\n                \"&\"\n            };\n\n            diag.span_suggestion_verbose(\n                span,\n                \"using `[]` is clearer and more concise\",\n                format!(\n                    \"{borrow_str}{}[{get_args_str}]\",\n                    snippet_with_applicability(cx, recv.span, \"..\", &mut applicability)\n                ),\n                applicability,\n            );\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/implicit_clone.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::sym;\nuse clippy_utils::ty::{implements_trait, peel_and_count_ty_refs};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::Symbol;\n\nuse super::IMPLICIT_CLONE;\n\npub fn check(cx: &LateContext<'_>, method_name: Symbol, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {\n    if let Some(method_parent_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id).opt_parent(cx)\n        && is_clone_like(cx, method_name, method_parent_id)\n        && let return_type = cx.typeck_results().expr_ty(expr)\n        && let input_type = cx.typeck_results().expr_ty(recv)\n        && let (input_type, ref_count, _) = peel_and_count_ty_refs(input_type)\n        && !(ref_count > 0 && method_parent_id.is_diag_item(cx, sym::ToOwned))\n        && let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did()))\n        && return_type == input_type\n        && let Some(clone_trait) = cx.tcx.lang_items().clone_trait()\n        && implements_trait(cx, return_type, clone_trait, &[])\n    {\n        let mut app = Applicability::MachineApplicable;\n        let recv_snip = snippet_with_context(cx, recv.span, expr.span.ctxt(), \"..\", &mut app).0;\n        span_lint_and_sugg(\n            cx,\n            IMPLICIT_CLONE,\n            expr.span,\n            format!(\"implicitly cloning a `{ty_name}` by calling `{method_name}` on its dereferenced type\"),\n            \"consider using\",\n            if ref_count > 1 {\n                format!(\"({}{recv_snip}).clone()\", \"*\".repeat(ref_count - 1))\n            } else {\n                format!(\"{recv_snip}.clone()\")\n            },\n            app,\n        );\n    }\n}\n\n/// Returns true if the named method can be used to clone the receiver.\npub fn is_clone_like(cx: &LateContext<'_>, method_name: Symbol, method_parent_id: hir::def_id::DefId) -> bool {\n    match method_name {\n        sym::to_os_string => method_parent_id.opt_impl_ty(cx).is_diag_item(cx, sym::OsStr),\n        sym::to_owned => method_parent_id.is_diag_item(cx, sym::ToOwned),\n        sym::to_path_buf => method_parent_id.opt_impl_ty(cx).is_diag_item(cx, sym::Path),\n        sym::to_string => method_parent_id.is_diag_item(cx, sym::ToString),\n        sym::to_vec => method_parent_id\n            .opt_impl_ty(cx)\n            .is_some_and(|ty| ty.instantiate_identity().is_slice()),\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/inefficient_to_string.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse clippy_utils::ty::peel_and_count_ty_refs;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::INEFFICIENT_TO_STRING;\n\npub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, msrv: Msrv) {\n    if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && cx.tcx.is_diagnostic_item(sym::to_string_method, to_string_meth_did)\n        && let Some(args) = cx.typeck_results().node_args_opt(expr.hir_id)\n        && let arg_ty = cx.typeck_results().expr_ty_adjusted(receiver)\n        && let self_ty = args.type_at(0)\n        && let (deref_self_ty, deref_count, _) = peel_and_count_ty_refs(self_ty)\n        && deref_count >= 1\n        // Since Rust 1.82, the specialized `ToString` is properly called\n        && !msrv.meets(cx, msrvs::SPECIALIZED_TO_STRING_FOR_REFS)\n        && specializes_tostring(cx, deref_self_ty)\n    {\n        span_lint_and_then(\n            cx,\n            INEFFICIENT_TO_STRING,\n            expr.span,\n            format!(\"calling `to_string` on `{arg_ty}`\"),\n            |diag| {\n                diag.help(format!(\n                    \"`{self_ty}` implements `ToString` through a slower blanket impl, but `{deref_self_ty}` has a fast specialization of `ToString`\"\n                ));\n                let mut applicability = Applicability::MachineApplicable;\n                let arg_snippet = snippet_with_applicability(cx, receiver.span, \"..\", &mut applicability);\n                diag.span_suggestion(\n                    expr.span,\n                    \"try dereferencing the receiver\",\n                    format!(\"({}{arg_snippet}).to_string()\", \"*\".repeat(deref_count)),\n                    applicability,\n                );\n            },\n        );\n    }\n}\n\n/// Returns whether `ty` specializes `ToString`.\n/// Currently, these are `str`, `String`, and `Cow<'_, str>`.\nfn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    if let ty::Str = ty.kind() {\n        return true;\n    }\n\n    if ty.is_lang_item(cx, hir::LangItem::String) {\n        return true;\n    }\n\n    if let ty::Adt(adt, args) = ty.kind() {\n        cx.tcx.is_diagnostic_item(sym::Cow, adt.did()) && args.type_at(1).is_str()\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/inspect_for_each.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, sym};\n\nuse super::INSPECT_FOR_EACH;\n\n/// lint use of `inspect().for_each()` for `Iterators`\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, inspect_span: Span) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        let msg = \"called `inspect(..).for_each(..)` on an `Iterator`\";\n        let hint = \"move the code from `inspect(..)` to `for_each(..)` and remove the `inspect(..)`\";\n        span_lint_and_help(\n            cx,\n            INSPECT_FOR_EACH,\n            inspect_span.with_hi(expr.span.hi()),\n            msg,\n            None,\n            hint,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/into_iter_on_ref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::ty::has_iter_method;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::Span;\nuse rustc_span::symbol::{Symbol, sym};\n\nuse super::INTO_ITER_ON_REF;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_span: Span, receiver: &hir::Expr<'_>) {\n    let self_ty = cx.typeck_results().expr_ty_adjusted(receiver);\n    if let ty::Ref(..) = self_ty.kind()\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::IntoIterator)\n        && let Some((kind, method_name)) = ty_has_iter_method(cx, self_ty)\n    {\n        span_lint_and_sugg(\n            cx,\n            INTO_ITER_ON_REF,\n            method_span,\n            format!(\"this `.into_iter()` call is equivalent to `.{method_name}()` and will not consume the `{kind}`\"),\n            \"call directly\",\n            method_name.to_string(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n\nfn ty_has_iter_method(cx: &LateContext<'_>, self_ref_ty: Ty<'_>) -> Option<(Symbol, &'static str)> {\n    has_iter_method(cx, self_ref_ty).map(|ty_name| {\n        let ty::Ref(_, _, mutbl) = self_ref_ty.kind() else {\n            unreachable!()\n        };\n        let method_name = match mutbl {\n            hir::Mutability::Not => \"iter\",\n            hir::Mutability::Mut => \"iter_mut\",\n        };\n        (ty_name, method_name)\n    })\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/io_other_error.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::{expr_or_init, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::LateContext;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, path: &Expr<'_>, args: &[Expr<'_>], msrv: Msrv) {\n    if let [error_kind, error] = args\n        && !expr.span.from_expansion()\n        && !error_kind.span.from_expansion()\n        && let ExprKind::Path(QPath::TypeRelative(_, new_segment)) = path.kind\n        && path.ty_rel_def(cx).is_diag_item(cx, sym::io_error_new)\n        && let ExprKind::Path(QPath::Resolved(_, init_path)) = &expr_or_init(cx, error_kind).kind\n        && let [.., error_kind_ty, error_kind_variant] = init_path.segments\n        && cx.tcx.is_diagnostic_item(sym::io_errorkind, error_kind_ty.res.def_id())\n        && error_kind_variant.ident.name == sym::Other\n        && msrv.meets(cx, msrvs::IO_ERROR_OTHER)\n    {\n        span_lint_and_then(\n            cx,\n            super::IO_OTHER_ERROR,\n            expr.span,\n            \"this can be `std::io::Error::other(_)`\",\n            |diag| {\n                diag.multipart_suggestion(\n                    \"use `std::io::Error::other`\",\n                    vec![\n                        (new_segment.ident.span, \"other\".to_owned()),\n                        (error_kind.span.until(error.span.source_callsite()), String::new()),\n                    ],\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/ip_constant.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sym;\nuse rustc_data_structures::smallvec::SmallVec;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath, TyKind};\nuse rustc_lint::LateContext;\n\nuse super::IP_CONSTANT;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>]) {\n    if let ExprKind::Path(QPath::TypeRelative(ty, p)) = func.kind\n        && let TyKind::Path(QPath::Resolved(_, func_path)) = ty.kind\n        && p.ident.name == sym::new\n        && let Some(func_def_id) = func_path.res.opt_def_id()\n        && matches!(\n            cx.tcx.get_diagnostic_name(func_def_id),\n            Some(sym::Ipv4Addr | sym::Ipv6Addr)\n        )\n        && let ecx = ConstEvalCtxt::new(cx)\n        && let ctxt = expr.span.ctxt()\n        && let Some(args) = args\n            .iter()\n            .map(|arg| {\n                if let Some(Constant::Int(constant @ (0 | 1 | 127 | 255))) = ecx.eval_local(arg, ctxt) {\n                    u8::try_from(constant).ok()\n                } else {\n                    None\n                }\n            })\n            .collect::<Option<SmallVec<[u8; 8]>>>()\n    {\n        let constant_name = match args.as_slice() {\n            [0, 0, 0, 0] | [0, 0, 0, 0, 0, 0, 0, 0] => \"UNSPECIFIED\",\n            [127, 0, 0, 1] | [0, 0, 0, 0, 0, 0, 0, 1] => \"LOCALHOST\",\n            [255, 255, 255, 255] => \"BROADCAST\",\n            _ => return,\n        };\n\n        let mut sugg = vec![(expr.span.with_lo(p.ident.span.lo()), constant_name.to_owned())];\n        let before_span = expr.span.shrink_to_lo().until(ty.span);\n        if !before_span.is_empty() {\n            // Remove everything before the type name\n            sugg.push((before_span, String::new()));\n        }\n\n        span_lint_and_then(cx, IP_CONSTANT, expr.span, \"hand-coded well-known IP address\", |diag| {\n            diag.multipart_suggestion(\"use\", sugg, Applicability::MachineApplicable);\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/is_digit_ascii_radix.rs",
    "content": "use super::IS_DIGIT_ASCII_RADIX;\nuse clippy_utils::consts::{ConstEvalCtxt, FullInt};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    self_arg: &'tcx Expr<'_>,\n    radix: &'tcx Expr<'_>,\n    msrv: Msrv,\n) {\n    if !cx.typeck_results().expr_ty_adjusted(self_arg).peel_refs().is_char() {\n        return;\n    }\n\n    if let Some(radix_val) = ConstEvalCtxt::new(cx).eval_full_int(radix, expr.span.ctxt()) {\n        let (num, replacement) = match radix_val {\n            FullInt::S(10) | FullInt::U(10) => (10, \"is_ascii_digit\"),\n            FullInt::S(16) | FullInt::U(16) => (16, \"is_ascii_hexdigit\"),\n            _ => return,\n        };\n        let mut applicability = Applicability::MachineApplicable;\n\n        if !msrv.meets(cx, msrvs::IS_ASCII_DIGIT) {\n            return;\n        }\n\n        span_lint_and_sugg(\n            cx,\n            IS_DIGIT_ASCII_RADIX,\n            expr.span,\n            format!(\"use of `char::is_digit` with literal radix of {num}\"),\n            \"try\",\n            format!(\n                \"{}.{replacement}()\",\n                snippet_with_applicability(cx, self_arg.span, \"..\", &mut applicability)\n            ),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/is_empty.rs",
    "content": "use clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::macros::{is_assert_macro, root_macro_call};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context};\nuse rustc_hir::{Expr, HirId, find_attr};\nuse rustc_lint::{LateContext, LintContext};\n\nuse super::CONST_IS_EMPTY;\n\n/// Expression whose initialization depend on a constant conditioned by a `#[cfg(…)]` directive will\n/// not trigger the lint.\npub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_>) {\n    if expr.span.in_external_macro(cx.sess().source_map()) || !receiver.span.eq_ctxt(expr.span) {\n        return;\n    }\n    if let Some(parent) = get_parent_expr(cx, expr)\n        && let Some(parent) = get_parent_expr(cx, parent)\n        && is_inside_always_const_context(cx.tcx, expr.hir_id)\n        && let Some(macro_call) = root_macro_call(parent.span)\n        && is_assert_macro(cx, macro_call.def_id)\n    {\n        return;\n    }\n    let init_expr = expr_or_init(cx, receiver);\n    if !receiver.span.eq_ctxt(init_expr.span) {\n        return;\n    }\n    if let Some(init_is_empty) = ConstEvalCtxt::new(cx).eval_is_empty(init_expr) {\n        span_lint(\n            cx,\n            CONST_IS_EMPTY,\n            expr.span,\n            format!(\"this expression always evaluates to {init_is_empty:?}\"),\n        );\n    }\n}\n\nfn is_under_cfg(cx: &LateContext<'_>, id: HirId) -> bool {\n    cx.tcx\n        .hir_parent_id_iter(id)\n        .any(|id| find_attr!(cx.tcx.hir_attrs(id), CfgTrace(..)))\n}\n\n/// Similar to [`clippy_utils::expr_or_init`], but does not go up the chain if the initialization\n/// value depends on a `#[cfg(…)]` directive.\nfn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr<'b>) -> &'a Expr<'b> {\n    while let Some(init) = expr\n        .res_local_id()\n        .and_then(|id| find_binding_init(cx, id))\n        .filter(|init| cx.typeck_results().expr_adjustments(init).is_empty())\n        .filter(|init| !is_under_cfg(cx, init.hir_id))\n    {\n        expr = init;\n    }\n    expr\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_cloned_collect.rs",
    "content": "use crate::methods::utils::derefs_to_slice;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::get_iterator_item_ty;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Symbol, sym};\n\nuse super::ITER_CLONED_COLLECT;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    method_name: Symbol,\n    expr: &hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'_>,\n) {\n    let expr_ty = cx.typeck_results().expr_ty(expr);\n    if expr_ty.is_diag_item(cx, sym::Vec)\n        && let Some(slice) = derefs_to_slice(cx, recv, cx.typeck_results().expr_ty(recv))\n        && let ty::Adt(_, args) = expr_ty.kind()\n        && let Some(iter_item_ty) = get_iterator_item_ty(cx, cx.typeck_results().expr_ty(recv))\n        && let ty::Ref(_, iter_item_ty, _) = iter_item_ty.kind()\n        && *iter_item_ty == args.type_at(0)\n        && let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite())\n    {\n        span_lint_and_sugg(\n            cx,\n            ITER_CLONED_COLLECT,\n            to_replace,\n            format!(\n                \"called `iter().{method_name}().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \\\n            more readable\"\n            ),\n            \"try\",\n            \".to_vec()\".to_string(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_count.rs",
    "content": "use super::utils::derefs_to_slice;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::Symbol;\n\nuse super::ITER_COUNT;\n\npub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx Expr<'tcx>, iter_method: Symbol) {\n    let ty = cx.typeck_results().expr_ty(recv);\n    let caller_type = match ty.opt_diag_name(cx) {\n        _ if derefs_to_slice(cx, recv, ty).is_some() => \"slice\",\n        Some(sym::Vec) => \"Vec\",\n        Some(sym::VecDeque) => \"VecDeque\",\n        Some(sym::HashSet) => \"HashSet\",\n        Some(sym::HashMap) => \"HashMap\",\n        Some(sym::BTreeMap) => \"BTreeMap\",\n        Some(sym::BTreeSet) => \"BTreeSet\",\n        Some(sym::LinkedList) => \"LinkedList\",\n        Some(sym::BinaryHeap) => \"BinaryHeap\",\n        _ => return,\n    };\n    let mut applicability = Applicability::MachineApplicable;\n    span_lint_and_sugg(\n        cx,\n        ITER_COUNT,\n        expr.span,\n        format!(\"called `.{iter_method}().count()` on a `{caller_type}`\"),\n        \"try\",\n        format!(\n            \"{}.len()\",\n            snippet_with_applicability(cx, recv.span, \"..\", &mut applicability),\n        ),\n        applicability,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_filter.rs",
    "content": "use clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::ty::get_iterator_item_ty;\nuse hir::ExprKind;\nuse rustc_lint::LateContext;\n\nuse super::{ITER_FILTER_IS_OK, ITER_FILTER_IS_SOME};\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{indent_of, reindent_multiline};\nuse clippy_utils::{get_parent_expr, peel_blocks, span_contains_comment, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::QPath;\nuse rustc_span::Span;\nuse rustc_span::symbol::{Ident, Symbol};\n\n///\n/// Returns true if the expression is a method call to `method_name`\n/// e.g. `a.method_name()` or `Option::method_name`.\n///\n/// The type-checker verifies for us that the method accepts the right kind of items\n/// (e.g. `Option::is_some` accepts `Option<_>`), so we don't need to check that.\n///\n/// How to capture each case:\n///\n/// `.filter(|a| { std::option::Option::is_some(a) })`\n///          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- this is a closure, getting unwrapped and\n/// recursively checked.\n/// `std::option::Option::is_some(a)`\n///  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- this is a call. It unwraps to a path with\n/// `QPath::TypeRelative`. Since this is a type relative path, we need to check the method name, the\n/// type, and that the parameter of the closure is passed in the call. This part is the dual of\n/// `receiver.method_name()` below.\n///\n/// `filter(std::option::Option::is_some);`\n///          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ <- this is a type relative path, like above, we check the\n/// type and the method name.\n///\n/// `filter(|a| a.is_some());`\n///         ^^^^^^^^^^^^^^^ <- this is a method call inside a closure,\n/// we check that the parameter of the closure is the receiver of the method call and don't allow\n/// any other parameters.\nfn is_method(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    type_symbol: Symbol,\n    method_name: Symbol,\n    params: &[&hir::Pat<'_>],\n) -> bool {\n    fn pat_is_recv(ident: Ident, param: &hir::Pat<'_>) -> bool {\n        match param.kind {\n            hir::PatKind::Binding(_, _, other, _) => ident == other,\n            hir::PatKind::Ref(pat, _, _) => pat_is_recv(ident, pat),\n            _ => false,\n        }\n    }\n    match expr.kind {\n        ExprKind::MethodCall(hir::PathSegment { ident, .. }, recv, ..) => {\n            // compare the identifier of the receiver to the parameter\n            // we are in a filter => closure has a single parameter and a single, non-block\n            // expression, this means that the parameter shadows all outside variables with\n            // the same name => avoid FPs. If the parameter is not the receiver, then this hits\n            // outside variables => avoid FP\n            if ident.name == method_name\n                && let ExprKind::Path(QPath::Resolved(None, path)) = recv.kind\n                && let &[seg] = path.segments\n                && params.iter().any(|p| pat_is_recv(seg.ident, p))\n            {\n                return true;\n            }\n            false\n        },\n        // This is used to check for complete paths via `|a| std::option::Option::is_some(a)`\n        // this then unwraps to a path with `QPath::TypeRelative`\n        // we pass the params as they've been passed to the current call through the closure\n        ExprKind::Call(expr, [param]) => {\n            // this will hit the `QPath::TypeRelative` case and check that the method name is correct\n            if is_method(cx, expr, type_symbol, method_name, params)\n                // we then check that this is indeed passing the parameter of the closure\n                && let ExprKind::Path(QPath::Resolved(None, path)) = param.kind\n                && let &[seg] = path.segments\n                && params.iter().any(|p| pat_is_recv(seg.ident, p))\n            {\n                return true;\n            }\n            false\n        },\n        ExprKind::Path(QPath::TypeRelative(ty, mname)) => {\n            let ty = cx.typeck_results().node_type(ty.hir_id);\n            if let Some(did) = cx.tcx.get_diagnostic_item(type_symbol)\n                && ty.ty_adt_def() == cx.tcx.type_of(did).skip_binder().ty_adt_def()\n            {\n                return mname.ident.name == method_name;\n            }\n            false\n        },\n        ExprKind::Closure(&hir::Closure { body, .. }) => {\n            let body = cx.tcx.hir_body(body);\n            let closure_expr = peel_blocks(body.value);\n            let params = body.params.iter().map(|param| param.pat).collect::<Vec<_>>();\n            is_method(cx, closure_expr, type_symbol, method_name, params.as_slice())\n        },\n        _ => false,\n    }\n}\n\nfn parent_is_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {\n    if let Some(expr) = get_parent_expr(cx, expr)\n        && let ExprKind::MethodCall(path, _, [_], _) = expr.kind\n        && path.ident.name == sym::map\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n    {\n        return true;\n    }\n    false\n}\n\nenum FilterType {\n    IsSome,\n    IsOk,\n}\n\n/// Returns the `FilterType` of the expression if it is a filter over an Iter<Option> or\n/// Iter<Result> with the parent expression not being a map, and not having a comment in the span of\n/// the filter. If it is not a filter over an Iter<Option> or Iter<Result> then it returns None\n///\n/// How this is done:\n/// 1. we know that this is invoked in a method call with `filter` as the method name via `mod.rs`\n/// 2. we check that we are in a trait method. Therefore we are in an `(x as\n///    Iterator).filter({filter_arg})` method call.\n/// 3. we check that the parent expression is not a map. This is because we don't want to lint\n///    twice, and we already have a specialized lint for that.\n/// 4. we check that the span of the filter does not contain a comment.\n/// 5. we get the type of the `Item` in the `Iterator`, and compare against the type of Option and\n///    Result.\n/// 6. we finally check the contents of the filter argument to see if it is a call to `is_some` or\n///    `is_ok`.\n/// 7. if all of the above are true, then we return the `FilterType`\nfn expression_type(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    filter_arg: &hir::Expr<'_>,\n    filter_span: Span,\n) -> Option<FilterType> {\n    if !cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        || parent_is_map(cx, expr)\n        || span_contains_comment(cx, filter_span.with_hi(expr.span.hi()))\n    {\n        return None;\n    }\n    if let ExprKind::MethodCall(_, receiver, _, _) = expr.kind\n        && let receiver_ty = cx.typeck_results().expr_ty(receiver)\n        && let Some(iter_item_ty) = get_iterator_item_ty(cx, receiver_ty)\n    {\n        if let Some(opt_defid) = cx.tcx.get_diagnostic_item(sym::Option)\n            && let opt_ty = cx.tcx.type_of(opt_defid).skip_binder()\n            && iter_item_ty.ty_adt_def() == opt_ty.ty_adt_def()\n            && is_method(cx, filter_arg, sym::Option, sym::is_some, &[])\n        {\n            return Some(FilterType::IsSome);\n        }\n\n        if let Some(opt_defid) = cx.tcx.get_diagnostic_item(sym::Result)\n            && let opt_ty = cx.tcx.type_of(opt_defid).skip_binder()\n            && iter_item_ty.ty_adt_def() == opt_ty.ty_adt_def()\n            && is_method(cx, filter_arg, sym::Result, sym::is_ok, &[])\n        {\n            return Some(FilterType::IsOk);\n        }\n    }\n    None\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_arg: &hir::Expr<'_>, filter_span: Span) {\n    // we are in a filter inside an iterator\n    match expression_type(cx, expr, filter_arg, filter_span) {\n        None => (),\n        Some(FilterType::IsOk) => span_lint_and_sugg(\n            cx,\n            ITER_FILTER_IS_OK,\n            filter_span.with_hi(expr.span.hi()),\n            \"`filter` for `is_ok` on iterator over `Result`s\",\n            \"consider using `flatten` instead\",\n            reindent_multiline(\"flatten()\", true, indent_of(cx, filter_span)),\n            Applicability::HasPlaceholders,\n        ),\n        Some(FilterType::IsSome) => span_lint_and_sugg(\n            cx,\n            ITER_FILTER_IS_SOME,\n            filter_span.with_hi(expr.span.hi()),\n            \"`filter` for `is_some` on iterator over `Option`\",\n            \"consider using `flatten` instead\",\n            reindent_multiline(\"flatten()\", true, indent_of(cx, filter_span)),\n            Applicability::HasPlaceholders,\n        ),\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_kv_map.rs",
    "content": "use super::ITER_KV_MAP;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::{pat_is_wild, sym};\nuse rustc_hir::{Body, Expr, ExprKind, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Symbol;\n\n/// lint use of:\n///\n/// - `hashmap.iter().map(|(_, v)| v)`\n/// - `hashmap.into_iter().map(|(_, v)| v)`\n///\n/// on `HashMaps` and `BTreeMaps` in std\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    map_type: Symbol,        // iter / into_iter\n    expr: &'tcx Expr<'tcx>,  // .iter().map(|(_, v_| v))\n    recv: &'tcx Expr<'tcx>,  // hashmap\n    m_arg: &'tcx Expr<'tcx>, // |(_, v)| v\n    msrv: Msrv,\n    method_name: Symbol,\n) {\n    if map_type == sym::into_iter && !msrv.meets(cx, msrvs::INTO_KEYS) {\n        return;\n    }\n    if !expr.span.from_expansion()\n        && let ExprKind::Closure(c) = m_arg.kind\n        && let Body {\n            params: [p],\n            value: body_expr,\n        } = cx.tcx.hir_body(c.body)\n        && let PatKind::Tuple([key_pat, val_pat], _) = p.pat.kind\n        && let (replacement_kind, annotation, bound_ident) = match (&key_pat.kind, &val_pat.kind) {\n            (key, PatKind::Binding(ann, _, value, _)) if pat_is_wild(cx, key, m_arg) => (\"value\", ann, value),\n            (PatKind::Binding(ann, _, key, _), value) if pat_is_wild(cx, value, m_arg) => (\"key\", ann, key),\n            _ => return,\n        }\n        && let ty = cx.typeck_results().expr_ty_adjusted(recv).peel_refs()\n        && matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap))\n    {\n        let mut applicability = rustc_errors::Applicability::MachineApplicable;\n        let recv_snippet = snippet_with_applicability(cx, recv.span, \"map\", &mut applicability);\n        let into_prefix = if map_type == sym::into_iter { \"into_\" } else { \"\" };\n\n        if let ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) = body_expr.kind\n            && let [local_ident] = path.segments\n            && local_ident.ident.name == bound_ident.name\n        {\n            span_lint_and_sugg(\n                cx,\n                ITER_KV_MAP,\n                expr.span,\n                format!(\"iterating on a map's {replacement_kind}s\"),\n                \"try\",\n                format!(\"{recv_snippet}.{into_prefix}{replacement_kind}s()\"),\n                applicability,\n            );\n        } else {\n            let (body_snippet, _) =\n                snippet_with_context(cx, body_expr.span, expr.span.ctxt(), \"..\", &mut applicability);\n            span_lint_and_sugg(\n                cx,\n                ITER_KV_MAP,\n                expr.span,\n                format!(\"iterating on a map's {replacement_kind}s\"),\n                \"try\",\n                format!(\n                    \"{recv_snippet}.{into_prefix}{replacement_kind}s().{method_name}(|{}{bound_ident}| {body_snippet})\",\n                    annotation.prefix_str(),\n                ),\n                applicability,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_next_slice.rs",
    "content": "use super::utils::derefs_to_slice;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{get_parent_expr, higher};\nuse rustc_ast::ast;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::symbol::sym;\n\nuse super::ITER_NEXT_SLICE;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, caller_expr: &'tcx hir::Expr<'_>) {\n    // Skip lint if the `iter().next()` expression is a for loop argument,\n    // since it is already covered by `&loops::ITER_NEXT_LOOP`\n    let mut parent_expr_opt = get_parent_expr(cx, expr);\n    while let Some(parent_expr) = parent_expr_opt {\n        if higher::ForLoop::hir(parent_expr).is_some() {\n            return;\n        }\n        parent_expr_opt = get_parent_expr(cx, parent_expr);\n    }\n\n    if derefs_to_slice(cx, caller_expr, cx.typeck_results().expr_ty(caller_expr)).is_some() {\n        // caller is a Slice\n        if let hir::ExprKind::Index(caller_var, index_expr, _) = &caller_expr.kind\n            && let Some(higher::Range {\n                start: Some(start_expr),\n                end: None,\n                limits: ast::RangeLimits::HalfOpen,\n                span: _,\n            }) = higher::Range::hir(cx, index_expr)\n            && let hir::ExprKind::Lit(start_lit) = &start_expr.kind\n            && let ast::LitKind::Int(start_idx, _) = start_lit.node\n        {\n            let mut applicability = Applicability::MachineApplicable;\n            let suggest = if start_idx == 0 {\n                format!(\n                    \"{}.first()\",\n                    snippet_with_applicability(cx, caller_var.span, \"..\", &mut applicability)\n                )\n            } else {\n                format!(\n                    \"{}.get({start_idx})\",\n                    snippet_with_applicability(cx, caller_var.span, \"..\", &mut applicability)\n                )\n            };\n            span_lint_and_sugg(\n                cx,\n                ITER_NEXT_SLICE,\n                expr.span,\n                \"using `.iter().next()` on a Slice without end index\",\n                \"try calling\",\n                suggest,\n                applicability,\n            );\n        }\n    } else if is_vec_or_array(cx, caller_expr) {\n        // caller is a Vec or an Array\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            ITER_NEXT_SLICE,\n            expr.span,\n            \"using `.iter().next()` on an array\",\n            \"try calling\",\n            format!(\n                \"{}.first()\",\n                snippet_with_applicability(cx, caller_expr.span, \"..\", &mut applicability)\n            ),\n            applicability,\n        );\n    }\n}\n\nfn is_vec_or_array<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) -> bool {\n    cx.typeck_results().expr_ty(expr).is_diag_item(cx, sym::Vec)\n        || matches!(&cx.typeck_results().expr_ty(expr).peel_refs().kind(), ty::Array(_, _))\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_nth.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, Symbol};\n\nuse super::ITER_NTH;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &hir::Expr<'_>,\n    iter_recv: &'tcx hir::Expr<'tcx>,\n    iter_method: Symbol,\n    iter_span: Span,\n    nth_span: Span,\n) -> bool {\n    let caller_type = match cx.typeck_results().expr_ty(iter_recv).peel_refs().opt_diag_name(cx) {\n        Some(sym::Vec) => \"`Vec`\",\n        Some(sym::VecDeque) => \"`VecDeque`\",\n        _ if cx.typeck_results().expr_ty_adjusted(iter_recv).peel_refs().is_slice() => \"slice\",\n        // caller is not a type that we want to lint\n        _ => return false,\n    };\n\n    span_lint_and_then(\n        cx,\n        ITER_NTH,\n        expr.span,\n        format!(\"called `.{iter_method}().nth()` on a {caller_type}\"),\n        |diag| {\n            let get_method = if iter_method == sym::iter_mut { \"get_mut\" } else { \"get\" };\n            diag.span_suggestion_verbose(\n                iter_span.to(nth_span),\n                format!(\"`{get_method}` is equivalent but more concise\"),\n                get_method,\n                Applicability::MachineApplicable,\n            );\n        },\n    );\n\n    true\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_nth_zero.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_lang_item_or_ctor;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet_with_applicability;\nuse hir::{LangItem, OwnerNode};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::ITER_NTH_ZERO;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {\n    if let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir_get_parent_item(expr.hir_id))\n        && let def_id = item.owner_id.to_def_id()\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let Some(Constant::Int(0)) = ConstEvalCtxt::new(cx).eval_local(arg, expr.span.ctxt())\n        && !is_lang_item_or_ctor(cx, def_id, LangItem::IteratorNext)\n    {\n        let mut app = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            ITER_NTH_ZERO,\n            expr.span,\n            \"called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent\",\n            \"try calling `.next()` instead of `.nth(0)`\",\n            format!(\"{}.next()\", snippet_with_applicability(cx, recv.span, \"..\", &mut app)),\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_on_single_or_empty_collections.rs",
    "content": "use std::iter::once;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::{ExprFnSig, expr_sig, ty_sig};\nuse clippy_utils::{as_some_expr, get_expr_use_or_unification_node, is_none_expr, std_or_core, sym};\n\nuse rustc_errors::Applicability;\nuse rustc_hir::hir_id::HirId;\nuse rustc_hir::{Expr, ExprKind, Node};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Binder;\nuse rustc_span::Symbol;\n\nuse super::{ITER_ON_EMPTY_COLLECTIONS, ITER_ON_SINGLE_ITEMS};\n\nenum IterType {\n    Iter,\n    IterMut,\n    IntoIter,\n}\n\nimpl IterType {\n    fn ref_prefix(&self) -> &'static str {\n        match self {\n            Self::Iter => \"&\",\n            Self::IterMut => \"&mut \",\n            Self::IntoIter => \"\",\n        }\n    }\n}\n\nfn is_arg_ty_unified_in_fn<'tcx>(\n    cx: &LateContext<'tcx>,\n    fn_sig: ExprFnSig<'tcx>,\n    arg_id: HirId,\n    args: impl IntoIterator<Item = &'tcx Expr<'tcx>>,\n    is_method: bool,\n) -> bool {\n    let arg_id_in_args = args.into_iter().position(|e| e.hir_id == arg_id).unwrap();\n    let Some(arg_ty_in_args) = fn_sig.input(arg_id_in_args).map(Binder::skip_binder) else {\n        return false;\n    };\n\n    fn_sig\n        .predicates_id()\n        .map(|def_id| cx.tcx.predicates_of(def_id))\n        .is_some_and(|generics| {\n            generics.predicates.iter().any(|(clause, _)| {\n                clause\n                    .as_projection_clause()\n                    .and_then(|p| p.map_bound(|p| p.term.as_type()).transpose())\n                    .is_some_and(|ty| ty.skip_binder() == arg_ty_in_args)\n            })\n        })\n        || (!is_method\n            && fn_sig.input(arg_id_in_args).is_some_and(|binder| {\n                binder\n                    .skip_binder()\n                    .walk()\n                    .any(|arg| arg.as_type() == Some(arg_ty_in_args))\n            }))\n}\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method_name: Symbol, recv: &'tcx Expr<'tcx>) {\n    let item = match recv.kind {\n        ExprKind::Array([]) => None,\n        ExprKind::Array([e]) => Some(e),\n        _ if is_none_expr(cx, recv) => None,\n        _ if let Some(arg) = as_some_expr(cx, recv) => Some(arg),\n        _ => return,\n    };\n    let iter_type = match method_name {\n        sym::iter => IterType::Iter,\n        sym::iter_mut => IterType::IterMut,\n        sym::into_iter => IterType::IntoIter,\n        _ => return,\n    };\n\n    let is_unified = match get_expr_use_or_unification_node(cx.tcx, expr) {\n        Some((Node::Expr(parent), child_id)) => match parent.kind {\n            ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id == child_id => false,\n            ExprKind::Call(recv, args) => {\n                expr_sig(cx, recv).is_some_and(|fn_sig| is_arg_ty_unified_in_fn(cx, fn_sig, child_id, args, false))\n            },\n            ExprKind::MethodCall(_name, recv, args, _span) => cx\n                .typeck_results()\n                .type_dependent_def_id(parent.hir_id)\n                .and_then(|def_id| ty_sig(cx, cx.tcx.type_of(def_id).instantiate_identity()))\n                .is_some_and(|fn_sig| {\n                    is_arg_ty_unified_in_fn(cx, fn_sig, child_id, once(recv).chain(args.iter()), true)\n                }),\n            ExprKind::If(_, _, _)\n            | ExprKind::Match(_, _, _)\n            | ExprKind::Closure(_)\n            | ExprKind::Ret(_)\n            | ExprKind::Break(_, _) => true,\n            _ => false,\n        },\n        Some((Node::LetStmt(let_stmt), _)) => let_stmt.ty.is_some(),\n        Some((Node::Stmt(_), _)) => false,\n        _ => true,\n    };\n\n    if is_unified {\n        return;\n    }\n\n    let Some(top_crate) = std_or_core(cx) else { return };\n    if let Some(i) = item {\n        let sugg = format!(\n            \"{top_crate}::iter::once({}{})\",\n            iter_type.ref_prefix(),\n            snippet(cx, i.span, \"...\")\n        );\n        span_lint_and_sugg(\n            cx,\n            ITER_ON_SINGLE_ITEMS,\n            expr.span,\n            format!(\"`{method_name}` call on a collection with only one item\"),\n            \"try\",\n            sugg,\n            Applicability::MaybeIncorrect,\n        );\n    } else {\n        span_lint_and_sugg(\n            cx,\n            ITER_ON_EMPTY_COLLECTIONS,\n            expr.span,\n            format!(\"`{method_name}` call on an empty collection\"),\n            \"try\",\n            format!(\"{top_crate}::iter::empty()\"),\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_out_of_bounds.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_note;\nuse clippy_utils::higher::VecArgs;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::{expr_or_init, sym};\nuse rustc_ast::LitKind;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::ITER_OUT_OF_BOUNDS;\n\nfn expr_as_u128(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<u128> {\n    if let ExprKind::Lit(lit) = expr_or_init(cx, e).kind\n        && let LitKind::Int(n, _) = lit.node\n    {\n        Some(n.get())\n    } else {\n        None\n    }\n}\n\n/// Attempts to extract the length out of an iterator expression.\nfn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) -> Option<u128> {\n    let ty::Adt(adt, substs) = cx.typeck_results().expr_ty(iter).kind() else {\n        return None;\n    };\n\n    match cx.tcx.get_diagnostic_name(adt.did()) {\n        Some(sym::ArrayIntoIter) => {\n            // For array::IntoIter<T, const N: usize>, the length is the second generic\n            // parameter.\n            substs.const_at(1).try_to_target_usize(cx.tcx).map(u128::from)\n        },\n        Some(sym::SliceIter) if let ExprKind::MethodCall(_, recv, ..) = iter.kind => {\n            if let ty::Array(_, len) = cx.typeck_results().expr_ty(recv).peel_refs().kind() {\n                // For slice::Iter<'_, T>, the receiver might be an array literal: [1,2,3].iter().skip(..)\n                len.try_to_target_usize(cx.tcx).map(u128::from)\n            } else if let Some(args) = VecArgs::hir(cx, expr_or_init(cx, recv)) {\n                match args {\n                    VecArgs::Vec(vec) => vec.len().try_into().ok(),\n                    VecArgs::Repeat(_, len) => expr_as_u128(cx, len),\n                }\n            } else {\n                None\n            }\n        },\n        Some(sym::IterEmpty) => Some(0),\n        Some(sym::IterOnce) => Some(1),\n        _ => None,\n    }\n}\n\nfn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    recv: &'tcx Expr<'tcx>,\n    arg: &'tcx Expr<'tcx>,\n    message: &'static str,\n    note: &'static str,\n) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let Some(len) = get_iterator_length(cx, recv)\n        && let Some(skipped) = expr_as_u128(cx, arg)\n        && skipped > len\n    {\n        span_lint_and_note(cx, ITER_OUT_OF_BOUNDS, expr.span, message, None, note);\n    }\n}\n\npub(super) fn check_skip<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    recv: &'tcx Expr<'tcx>,\n    arg: &'tcx Expr<'tcx>,\n) {\n    check(\n        cx,\n        expr,\n        recv,\n        arg,\n        \"this `.skip()` call skips more items than the iterator will produce\",\n        \"this operation is useless and will create an empty iterator\",\n    );\n}\n\npub(super) fn check_take<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    recv: &'tcx Expr<'tcx>,\n    arg: &'tcx Expr<'tcx>,\n) {\n    check(\n        cx,\n        expr,\n        recv,\n        arg,\n        \"this `.take()` call takes more items than the iterator will produce\",\n        \"this operation is useless and the returned iterator will simply yield the same items\",\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_overeager_cloned.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet_opt;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse core::ops::ControlFlow;\nuse rustc_ast::BindingMode;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Body, CaptureBy, Closure, Expr, ExprKind, HirId, HirIdSet, Param, PatKind};\nuse rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::{FakeReadCause, Mutability};\nuse rustc_middle::ty::{self, BorrowKind, UpvarCapture};\nuse rustc_span::{Symbol, sym};\n\nuse super::{ITER_OVEREAGER_CLONED, REDUNDANT_ITER_CLONED};\n\n#[derive(Clone, Copy)]\npub(super) enum Op<'a> {\n    // rm `.cloned()`\n    // e.g. `count`\n    RmCloned,\n\n    // rm `.cloned()`\n    // e.g. `map` `for_each` `all` `any`\n    NeedlessMove(&'a Expr<'a>),\n\n    // later `.cloned()`\n    // and add `&` to the parameter of closure parameter\n    // e.g. `find` `filter`\n    FixClosure(Symbol, &'a Expr<'a>),\n\n    // later `.cloned()`\n    // e.g. `skip` `take`\n    LaterCloned,\n}\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    cloned_call: &'tcx Expr<'_>,\n    cloned_recv: &'tcx Expr<'_>,\n    op: Op<'tcx>,\n    needs_into_iter: bool,\n) {\n    let typeck = cx.typeck_results();\n    if let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator)\n        && let Some(method_id) = typeck.type_dependent_def_id(expr.hir_id)\n        && cx.tcx.trait_of_assoc(method_id) == Some(iter_id)\n        && let Some(method_id) = typeck.type_dependent_def_id(cloned_call.hir_id)\n        && cx.tcx.trait_of_assoc(method_id) == Some(iter_id)\n        && let cloned_recv_ty = typeck.expr_ty_adjusted(cloned_recv)\n        && let Some(iter_assoc_ty) = cx.get_associated_type(cloned_recv_ty, iter_id, sym::Item)\n        && matches!(*iter_assoc_ty.kind(), ty::Ref(_, ty, _) if !is_copy(cx, ty))\n    {\n        if needs_into_iter\n            && let Some(into_iter_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator)\n            && !implements_trait(cx, iter_assoc_ty, into_iter_id, &[])\n        {\n            return;\n        }\n\n        if let Op::NeedlessMove(expr) = op {\n            let ExprKind::Closure(closure) = expr.kind else {\n                return;\n            };\n            let body @ Body { params: [p], .. } = cx.tcx.hir_body(closure.body) else {\n                return;\n            };\n\n            if param_captured_by_move_block(cx, body.value, p) {\n                return;\n            }\n\n            let mut delegate = MoveDelegate {\n                used_move: HirIdSet::default(),\n            };\n\n            ExprUseVisitor::for_clippy(cx, closure.def_id, &mut delegate)\n                .consume_body(body)\n                .into_ok();\n\n            let mut to_be_discarded = false;\n\n            p.pat.walk(|it| {\n                if delegate.used_move.contains(&it.hir_id) {\n                    to_be_discarded = true;\n                    return false;\n                }\n\n                match it.kind {\n                    PatKind::Binding(BindingMode(_, Mutability::Mut), _, _, _)\n                    | PatKind::Ref(_, _, Mutability::Mut) => {\n                        to_be_discarded = true;\n                        false\n                    },\n                    _ => true,\n                }\n            });\n\n            if to_be_discarded {\n                return;\n            }\n        }\n\n        let (lint, msg, trailing_clone) = match op {\n            Op::RmCloned | Op::NeedlessMove(_) => (REDUNDANT_ITER_CLONED, \"unneeded cloning of iterator items\", \"\"),\n            Op::LaterCloned | Op::FixClosure(_, _) => (\n                ITER_OVEREAGER_CLONED,\n                \"unnecessarily eager cloning of iterator items\",\n                \".cloned()\",\n            ),\n        };\n\n        span_lint_and_then(cx, lint, expr.span, msg, |diag| match op {\n            Op::RmCloned | Op::LaterCloned => {\n                let method_span = expr.span.with_lo(cloned_call.span.hi());\n                if let Some(mut snip) = snippet_opt(cx, method_span) {\n                    snip.push_str(trailing_clone);\n                    let replace_span = expr.span.with_lo(cloned_recv.span.hi());\n                    diag.span_suggestion(replace_span, \"try\", snip, Applicability::MachineApplicable);\n                }\n            },\n            Op::FixClosure(name, predicate_expr) => {\n                if let Some(predicate) = snippet_opt(cx, predicate_expr.span) {\n                    let new_closure = if let ExprKind::Closure(_) = predicate_expr.kind {\n                        predicate.replacen('|', \"|&\", 1)\n                    } else {\n                        format!(\"|&x| {predicate}(x)\")\n                    };\n                    let snip = format!(\".{name}({new_closure}).cloned()\");\n                    let replace_span = expr.span.with_lo(cloned_recv.span.hi());\n                    diag.span_suggestion(replace_span, \"try\", snip, Applicability::MachineApplicable);\n                }\n            },\n            Op::NeedlessMove(_) => {\n                let method_span = expr.span.with_lo(cloned_call.span.hi());\n                if let Some(snip) = snippet_opt(cx, method_span) {\n                    let replace_span = expr.span.with_lo(cloned_recv.span.hi());\n                    diag.span_suggestion(replace_span, \"try\", snip, Applicability::MaybeIncorrect);\n                }\n            },\n        });\n    }\n}\n\nstruct MoveDelegate {\n    used_move: HirIdSet,\n}\n\n/// Checks if the expression contains a closure or coroutine with `move` capture semantics that\n/// captures the given parameter.\nfn param_captured_by_move_block(cx: &LateContext<'_>, expr: &Expr<'_>, param: &Param<'_>) -> bool {\n    let mut param_hir_ids = HirIdSet::default();\n    param.pat.walk(|pat| {\n        param_hir_ids.insert(pat.hir_id);\n        true\n    });\n\n    for_each_expr_without_closures(expr, |e| {\n        if let ExprKind::Closure(Closure {\n            capture_clause: CaptureBy::Value { .. },\n            def_id,\n            ..\n        }) = e.kind\n            && cx.tcx.closure_captures(*def_id).iter().any(|capture| {\n                matches!(capture.info.capture_kind, UpvarCapture::ByValue)\n                    && matches!(capture.place.base, PlaceBase::Upvar(upvar) if param_hir_ids.contains(&upvar.var_path.hir_id))\n            })\n        {\n            return ControlFlow::Break(());\n        }\n\n        ControlFlow::Continue(())\n    })\n    .is_some()\n}\n\nimpl<'tcx> Delegate<'tcx> for MoveDelegate {\n    fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, _: HirId) {\n        if let PlaceBase::Local(l) = place_with_id.place.base {\n            self.used_move.insert(l);\n        }\n    }\n\n    fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn borrow(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: BorrowKind) {}\n\n    fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_skip_next.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::{BindingMode, Node, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::ITER_SKIP_NEXT;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {\n    // lint if caller of skip is an Iterator\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_then(\n            cx,\n            ITER_SKIP_NEXT,\n            expr.span.trim_start(recv.span).unwrap(),\n            \"called `skip(..).next()` on an iterator\",\n            |diag| {\n                if let Some(id) = recv.res_local_id()\n                    && let Node::Pat(pat) = cx.tcx.hir_node(id)\n                    && let PatKind::Binding(ann, _, _, _) = pat.kind\n                    && ann != BindingMode::MUT\n                {\n                    applicability = Applicability::Unspecified;\n                    diag.span_help(\n                        pat.span,\n                        format!(\"for this change `{}` has to be mutable\", snippet(cx, pat.span, \"..\")),\n                    );\n                }\n\n                diag.span_suggestion(\n                    expr.span.trim_start(recv.span).unwrap(),\n                    \"use `nth` instead\",\n                    format!(\".nth({})\", snippet(cx, arg.span, \"..\")),\n                    applicability,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_skip_zero.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::ITER_SKIP_ZERO;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg_expr: &Expr<'_>) {\n    if !expr.span.from_expansion()\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let Some(arg) = ConstEvalCtxt::new(cx)\n            .eval_local(arg_expr, expr.span.ctxt())\n            .and_then(|constant| {\n                if let Constant::Int(arg) = constant {\n                    Some(arg)\n                } else {\n                    None\n                }\n            })\n        && arg == 0\n        && !is_from_proc_macro(cx, expr)\n    {\n        span_lint_and_then(cx, ITER_SKIP_ZERO, arg_expr.span, \"usage of `.skip(0)`\", |diag| {\n            diag.span_suggestion(\n                arg_expr.span,\n                \"if you meant to skip the first element, use\",\n                \"1\",\n                Applicability::MaybeIncorrect,\n            )\n            .note(\"this call to `skip` does nothing and is useless; remove it\");\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iter_with_drain.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::{is_range_full, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::ITER_WITH_DRAIN;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, arg: &Expr<'_>) {\n    if !matches!(recv.kind, ExprKind::Field(..))\n        && let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def()\n        && let Some(ty_name) = cx.tcx.get_diagnostic_name(adt.did())\n        && matches!(ty_name, sym::Vec | sym::VecDeque)\n        && let ExprKind::Path(QPath::Resolved(None, container_path)) = recv.kind\n        && is_range_full(cx, arg, Some(container_path))\n    {\n        span_lint_and_sugg(\n            cx,\n            ITER_WITH_DRAIN,\n            span.with_hi(expr.span.hi()),\n            format!(\"`drain(..)` used on a `{ty_name}`\"),\n            \"try\",\n            \"into_iter()\".to_string(),\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/iterator_step_by_zero.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::ITERATOR_STEP_BY_ZERO;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, arg: &'tcx hir::Expr<'_>) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let Some(Constant::Int(0)) = ConstEvalCtxt::new(cx).eval(arg)\n    {\n        span_lint(\n            cx,\n            ITERATOR_STEP_BY_ZERO,\n            expr.span,\n            \"`Iterator::step_by(0)` will panic at runtime\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/join_absolute_paths.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{expr_or_init, sym};\nuse rustc_ast::ast::{LitKind, StrStyle};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::JOIN_ABSOLUTE_PATHS;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx Expr<'tcx>, join_arg: &'tcx Expr<'tcx>, expr_span: Span) {\n    let ty = cx.typeck_results().expr_ty(recv).peel_refs();\n    if matches!(ty.opt_diag_name(cx), Some(sym::Path | sym::PathBuf))\n        && let ExprKind::Lit(spanned) = expr_or_init(cx, join_arg).kind\n        && let LitKind::Str(symbol, style) = spanned.node\n        && let sym_str = symbol.as_str()\n        && sym_str.starts_with(['/', '\\\\'])\n    {\n        span_lint_and_then(\n            cx,\n            JOIN_ABSOLUTE_PATHS,\n            join_arg.span,\n            \"argument to `Path::join` starts with a path separator\",\n            |diag| {\n                let arg_str = snippet(cx, spanned.span, \"..\");\n\n                let no_separator = if sym_str.starts_with('/') {\n                    arg_str.replacen('/', \"\", 1)\n                } else if let StrStyle::Raw(_) = style {\n                    arg_str.replacen('\\\\', \"\", 1)\n                } else {\n                    arg_str.replacen(\"\\\\\\\\\", \"\", 1)\n                };\n\n                diag.note(\"joining a path starting with separator will replace the path instead\")\n                    .span_suggestion(\n                        spanned.span,\n                        \"if this is unintentional, try removing the starting separator\",\n                        no_separator,\n                        Applicability::Unspecified,\n                    )\n                    .span_suggestion(\n                        expr_span,\n                        \"if this is intentional, consider using `Path::new`\",\n                        format!(\"PathBuf::from({arg_str})\"),\n                        Applicability::Unspecified,\n                    );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/lib.rs",
    "content": "use clippy_utils::sym;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse rustc_hir::Mutability;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\n#[derive(Clone, Copy, PartialEq, Eq, Debug)]\npub(super) enum SelfKind {\n    Value,\n    Ref,\n    RefMut,\n    No, // When we want the first argument type to be different than `Self`\n}\n\nimpl SelfKind {\n    pub(super) fn matches<'a>(self, cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {\n        fn matches_value<'a>(cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {\n            if ty == parent_ty {\n                true\n            } else if let Some(boxed_ty) = ty.boxed_ty() {\n                boxed_ty == parent_ty\n            } else if let ty::Adt(adt_def, args) = ty.kind()\n                && matches!(cx.tcx.get_diagnostic_name(adt_def.did()), Some(sym::Rc | sym::Arc))\n            {\n                args.types().next() == Some(parent_ty)\n            } else {\n                false\n            }\n        }\n\n        fn matches_ref<'a>(cx: &LateContext<'a>, mutability: Mutability, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {\n            if let ty::Ref(_, t, m) = *ty.kind() {\n                return m == mutability && t == parent_ty;\n            }\n\n            let trait_sym = match mutability {\n                Mutability::Not => sym::AsRef,\n                Mutability::Mut => sym::AsMut,\n            };\n\n            let Some(trait_def_id) = cx.tcx.get_diagnostic_item(trait_sym) else {\n                return false;\n            };\n            implements_trait(cx, ty, trait_def_id, &[parent_ty.into()])\n        }\n\n        fn matches_none<'a>(cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {\n            !matches_value(cx, parent_ty, ty)\n                && !matches_ref(cx, Mutability::Not, parent_ty, ty)\n                && !matches_ref(cx, Mutability::Mut, parent_ty, ty)\n        }\n\n        match self {\n            Self::Value => matches_value(cx, parent_ty, ty),\n            Self::Ref => matches_ref(cx, Mutability::Not, parent_ty, ty) || ty == parent_ty && is_copy(cx, ty),\n            Self::RefMut => matches_ref(cx, Mutability::Mut, parent_ty, ty),\n            Self::No => matches_none(cx, parent_ty, ty),\n        }\n    }\n\n    #[must_use]\n    pub(super) fn description(self) -> &'static str {\n        match self {\n            Self::Value => \"`self` by value\",\n            Self::Ref => \"`self` by reference\",\n            Self::RefMut => \"`self` by mutable reference\",\n            Self::No => \"no `self`\",\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/lines_filter_map_ok.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Body, Closure, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::LINES_FILTER_MAP_OK;\n\npub(super) fn check_flatten(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, call_span: Span, msrv: Msrv) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && cx\n            .typeck_results()\n            .expr_ty_adjusted(recv)\n            .is_diag_item(cx, sym::IoLines)\n        && msrv.meets(cx, msrvs::MAP_WHILE)\n    {\n        emit(cx, recv, \"flatten\", call_span);\n    }\n}\n\npub(super) fn check_filter_or_flat_map(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    recv: &Expr<'_>,\n    method_name: &'static str,\n    method_arg: &Expr<'_>,\n    call_span: Span,\n    msrv: Msrv,\n) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && cx\n            .typeck_results()\n            .expr_ty_adjusted(recv)\n            .is_diag_item(cx, sym::IoLines)\n        && match method_arg.kind {\n            // Detect `Result::ok`\n            ExprKind::Path(ref qpath) => cx\n                .qpath_res(qpath, method_arg.hir_id)\n                .is_diag_item(cx, sym::result_ok_method),\n            // Detect `|x| x.ok()`\n            ExprKind::Closure(&Closure { body, .. }) => {\n                if let Body {\n                    params: [param], value, ..\n                } = cx.tcx.hir_body(body)\n                    && let ExprKind::MethodCall(method, receiver, [], _) = value.kind\n                {\n                    method.ident.name == sym::ok\n                        && receiver.res_local_id() == Some(param.pat.hir_id)\n                        && cx.ty_based_def(*value).is_diag_item(cx, sym::result_ok_method)\n                } else {\n                    false\n                }\n            },\n            _ => false,\n        }\n        && msrv.meets(cx, msrvs::MAP_WHILE)\n    {\n        emit(cx, recv, method_name, call_span);\n    }\n}\n\nfn emit(cx: &LateContext<'_>, recv: &Expr<'_>, method_name: &'static str, call_span: Span) {\n    span_lint_and_then(\n        cx,\n        LINES_FILTER_MAP_OK,\n        call_span,\n        format!(\"`{method_name}()` will run forever if the iterator repeatedly produces an `Err`\"),\n        |diag| {\n            diag.span_note(\n                recv.span,\n                \"this expression returning a `std::io::Lines` may produce \\\n                        an infinite number of `Err` in case of a read error\",\n            );\n            diag.span_suggestion(\n                call_span,\n                \"replace with\",\n                \"map_while(Result::ok)\",\n                Applicability::MaybeIncorrect,\n            );\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_c_str_literals.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet;\nuse clippy_utils::{get_parent_expr, sym};\nuse rustc_ast::{LitKind, StrStyle};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Node, QPath, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_span::edition::Edition::Edition2021;\nuse rustc_span::{Span, Symbol};\n\nuse super::MANUAL_C_STR_LITERALS;\n\n/// Checks:\n/// - `b\"...\".as_ptr()`\n/// - `b\"...\".as_ptr().cast()`\n/// - `\"...\".as_ptr()`\n/// - `\"...\".as_ptr().cast()`\n///\n/// Iff the parent call of `.cast()` isn't `CStr::from_ptr`, to avoid linting twice.\npub(super) fn check_as_ptr<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    receiver: &'tcx Expr<'tcx>,\n    msrv: Msrv,\n) {\n    if let ExprKind::Lit(lit) = receiver.kind\n        && let LitKind::ByteStr(_, StrStyle::Cooked) | LitKind::Str(_, StrStyle::Cooked) = lit.node\n        && cx.tcx.sess.edition() >= Edition2021\n        && let casts_removed = peel_ptr_cast_ancestors(cx, expr)\n        && !get_parent_expr(cx, casts_removed).is_some_and(\n            |parent| matches!(parent.kind, ExprKind::Call(func, _) if is_c_str_function(cx, func).is_some()),\n        )\n        && let Some(sugg) = rewrite_as_cstr(cx, lit.span)\n        && msrv.meets(cx, msrvs::C_STR_LITERALS)\n    {\n        span_lint_and_sugg(\n            cx,\n            MANUAL_C_STR_LITERALS,\n            receiver.span,\n            \"manually constructing a nul-terminated string\",\n            r#\"use a `c\"\"` literal\"#,\n            sugg,\n            // an additional cast may be needed, since the type of `CStr::as_ptr` and\n            // `\"\".as_ptr()` can differ and is platform dependent\n            Applicability::HasPlaceholders,\n        );\n    }\n}\n\n/// Checks if the callee is a \"relevant\" `CStr` function considered by this lint.\n/// Returns the function name.\nfn is_c_str_function(cx: &LateContext<'_>, func: &Expr<'_>) -> Option<Symbol> {\n    if let ExprKind::Path(QPath::TypeRelative(cstr, fn_name)) = &func.kind\n        && let TyKind::Path(QPath::Resolved(_, ty_path)) = &cstr.kind\n        && cx.tcx.lang_items().c_str() == ty_path.res.opt_def_id()\n    {\n        Some(fn_name.ident.name)\n    } else {\n        None\n    }\n}\n\n/// Checks calls to the `CStr` constructor functions:\n/// - `CStr::from_bytes_with_nul(..)`\n/// - `CStr::from_bytes_with_nul_unchecked(..)`\n/// - `CStr::from_ptr(..)`\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>], msrv: Msrv) {\n    if let Some(fn_name) = is_c_str_function(cx, func)\n        && let [arg] = args\n        && cx.tcx.sess.edition() >= Edition2021\n        && msrv.meets(cx, msrvs::C_STR_LITERALS)\n    {\n        match fn_name {\n            sym::from_bytes_with_nul | sym::from_bytes_with_nul_unchecked\n                if !arg.span.from_expansion()\n                    && let ExprKind::Lit(lit) = arg.kind\n                    && let LitKind::ByteStr(_, StrStyle::Cooked) | LitKind::Str(_, StrStyle::Cooked) = lit.node =>\n            {\n                check_from_bytes(cx, expr, arg, fn_name);\n            },\n            sym::from_ptr => check_from_ptr(cx, expr, arg),\n            _ => {},\n        }\n    }\n}\n\n/// Checks `CStr::from_ptr(b\"foo\\0\".as_ptr().cast())`\nfn check_from_ptr(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>) {\n    if let ExprKind::MethodCall(method, lit, [], _) = peel_ptr_cast(arg).kind\n        && method.ident.name == sym::as_ptr\n        && !lit.span.from_expansion()\n        && let ExprKind::Lit(lit) = lit.kind\n        && let LitKind::ByteStr(_, StrStyle::Cooked) = lit.node\n        && let Some(sugg) = rewrite_as_cstr(cx, lit.span)\n    {\n        span_lint_and_sugg(\n            cx,\n            MANUAL_C_STR_LITERALS,\n            expr.span,\n            \"calling `CStr::from_ptr` with a byte string literal\",\n            r#\"use a `c\"\"` literal\"#,\n            sugg,\n            Applicability::MachineApplicable,\n        );\n    }\n}\n/// Checks `CStr::from_bytes_with_nul(b\"foo\\0\")`\nfn check_from_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, method: Symbol) {\n    let (span, applicability) = if let Some(parent) = get_parent_expr(cx, expr)\n        && let ExprKind::MethodCall(method, ..) = parent.kind\n        && [sym::unwrap, sym::expect].contains(&method.ident.name)\n    {\n        (parent.span, Applicability::MachineApplicable)\n    } else if method == sym::from_bytes_with_nul_unchecked {\n        // `*_unchecked` returns `&CStr` directly, nothing needs to be changed\n        (expr.span, Applicability::MachineApplicable)\n    } else {\n        // User needs to remove error handling, can't be machine applicable\n        (expr.span, Applicability::HasPlaceholders)\n    };\n\n    let Some(sugg) = rewrite_as_cstr(cx, arg.span) else {\n        return;\n    };\n\n    span_lint_and_sugg(\n        cx,\n        MANUAL_C_STR_LITERALS,\n        span,\n        \"calling `CStr::new` with a byte string literal\",\n        r#\"use a `c\"\"` literal\"#,\n        sugg,\n        applicability,\n    );\n}\n\n/// Rewrites a byte string literal to a c-str literal.\n/// `b\"foo\\0\"` -> `c\"foo\"`\n///\n/// Returns `None` if it doesn't end in a NUL byte.\nfn rewrite_as_cstr(cx: &LateContext<'_>, span: Span) -> Option<String> {\n    let mut sugg = String::from(\"c\") + snippet(cx, span.source_callsite(), \"..\").trim_start_matches('b');\n\n    // NUL byte should always be right before the closing quote.\n    if let Some(quote_pos) = sugg.rfind('\"') {\n        // Possible values right before the quote:\n        // - literal NUL value\n        if sugg.as_bytes()[quote_pos - 1] == b'\\0' {\n            sugg.remove(quote_pos - 1);\n        }\n        // - \\x00\n        else if sugg[..quote_pos].ends_with(\"\\\\x00\") {\n            sugg.replace_range(quote_pos - 4..quote_pos, \"\");\n        }\n        // - \\0\n        else if sugg[..quote_pos].ends_with(\"\\\\0\") {\n            sugg.replace_range(quote_pos - 2..quote_pos, \"\");\n        }\n        // No known suffix, so assume it's not a C-string.\n        else {\n            return None;\n        }\n    }\n\n    Some(sugg)\n}\n\nfn get_cast_target<'tcx>(e: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    match &e.kind {\n        ExprKind::MethodCall(method, receiver, [], _) if method.ident.name == sym::cast => Some(receiver),\n        ExprKind::Cast(expr, _) => Some(expr),\n        _ => None,\n    }\n}\n\n/// `x.cast()` -> `x`\n/// `x as *const _` -> `x`\n/// `x` -> `x` (returns the same expression for non-cast exprs)\nfn peel_ptr_cast<'tcx>(e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {\n    get_cast_target(e).map_or(e, peel_ptr_cast)\n}\n\n/// Same as `peel_ptr_cast`, but the other way around, by walking up the ancestor cast expressions:\n///\n/// `foo(x.cast() as *const _)`\n///      ^ given this `x` expression, returns the `foo(...)` expression\nfn peel_ptr_cast_ancestors<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {\n    let mut prev = e;\n    for (_, node) in cx.tcx.hir_parent_iter(e.hir_id) {\n        if let Node::Expr(e) = node\n            && get_cast_target(e).is_some()\n        {\n            prev = e;\n        } else {\n            break;\n        }\n    }\n    prev\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_contains.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::eager_or_lazy::switch_to_eager_eval;\nuse clippy_utils::peel_hir_pat_refs;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg::Sugg;\nuse rustc_ast::UnOp;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BinOpKind, Body, Expr, ExprKind, HirId, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::source_map::Spanned;\n\nuse super::MANUAL_CONTAINS;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, closure_arg: &Expr<'_>) {\n    let mut app = Applicability::MachineApplicable;\n\n    if !expr.span.from_expansion()\n        // check if `iter().any()` can be replaced with `contains()`\n        && let ExprKind::Closure(closure) = closure_arg.kind\n        && let Body{params: [param],value} = cx.tcx.hir_body(closure.body)\n        && let ExprKind::Binary(op, lhs, rhs) = value.kind\n        && let (peeled_ref_pat, _) = peel_hir_pat_refs(param.pat)\n        && let Some((snip,snip_expr)) = can_replace_with_contains(cx, op, lhs, rhs, peeled_ref_pat.hir_id, &mut app)\n        && let ref_type = cx.typeck_results().expr_ty_adjusted(recv)\n        && let ty::Ref(_, inner_type, _) = ref_type.kind()\n        && let ty::Slice(slice_type) = inner_type.kind()\n        && *slice_type == cx.typeck_results().expr_ty(snip_expr)\n    {\n        span_lint_and_sugg(\n            cx,\n            MANUAL_CONTAINS,\n            expr.span,\n            \"using `contains()` instead of `iter().any()` is more efficient\",\n            \"try\",\n            format!(\n                \"{}.contains({})\",\n                snippet_with_applicability(cx, recv.span, \"_\", &mut app),\n                snip\n            ),\n            app,\n        );\n    }\n}\n\nenum EligibleArg {\n    IsClosureArg,\n    ContainsArg(String),\n}\n\nfn try_get_eligible_arg<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    closure_arg_id: HirId,\n    applicability: &mut Applicability,\n) -> Option<(EligibleArg, &'tcx Expr<'tcx>)> {\n    let mut get_snippet = |expr: &Expr<'_>, needs_borrow: bool| {\n        let sugg = Sugg::hir_with_applicability(cx, expr, \"_\", applicability);\n        EligibleArg::ContainsArg((if needs_borrow { sugg.addr() } else { sugg }).to_string())\n    };\n\n    match expr.kind {\n        ExprKind::Path(QPath::Resolved(_, path)) => {\n            if path.res == Res::Local(closure_arg_id) {\n                Some((EligibleArg::IsClosureArg, expr))\n            } else {\n                Some((get_snippet(expr, true), expr))\n            }\n        },\n        ExprKind::Unary(UnOp::Deref, inner) => {\n            if let ExprKind::Path(QPath::Resolved(_, path)) = inner.kind {\n                if path.res == Res::Local(closure_arg_id) {\n                    Some((EligibleArg::IsClosureArg, expr))\n                } else {\n                    Some((get_snippet(inner, false), expr))\n                }\n            } else {\n                None\n            }\n        },\n        _ => {\n            if switch_to_eager_eval(cx, expr) {\n                Some((get_snippet(expr, true), expr))\n            } else {\n                None\n            }\n        },\n    }\n}\n\nfn can_replace_with_contains<'tcx>(\n    cx: &LateContext<'tcx>,\n    bin_op: Spanned<BinOpKind>,\n    left_expr: &'tcx Expr<'tcx>,\n    right_expr: &'tcx Expr<'tcx>,\n    closure_arg_id: HirId,\n    applicability: &mut Applicability,\n) -> Option<(String, &'tcx Expr<'tcx>)> {\n    if bin_op.node != BinOpKind::Eq {\n        return None;\n    }\n\n    let left_candidate = try_get_eligible_arg(cx, left_expr, closure_arg_id, applicability)?;\n    let right_candidate = try_get_eligible_arg(cx, right_expr, closure_arg_id, applicability)?;\n    match (left_candidate, right_candidate) {\n        ((EligibleArg::IsClosureArg, _), (EligibleArg::ContainsArg(snip), candidate_expr))\n        | ((EligibleArg::ContainsArg(snip), candidate_expr), (EligibleArg::IsClosureArg, _)) => {\n            Some((snip, candidate_expr))\n        },\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_inspect.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::{IntoSpan, SpanRangeExt};\nuse clippy_utils::ty::get_field_by_name;\nuse clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures};\nuse clippy_utils::{ExprUseNode, expr_use_ctxt, sym};\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BindingMode, BorrowKind, ByRef, ClosureKind, Expr, ExprKind, Mutability, Node, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};\nuse rustc_span::{DUMMY_SP, Span, Symbol};\n\nuse super::MANUAL_INSPECT;\n\n#[expect(clippy::too_many_lines)]\npub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name: Symbol, name_span: Span, msrv: Msrv) {\n    if let ExprKind::Closure(c) = arg.kind\n        && matches!(c.kind, ClosureKind::Closure)\n        && let typeck = cx.typeck_results()\n        && let Some(fn_def) = typeck.type_dependent_def(expr.hir_id)\n        && (fn_def.opt_parent(cx).is_diag_item(cx, sym::Iterator)\n            || ((fn_def.opt_parent(cx).opt_impl_ty(cx).is_diag_item(cx, sym::Option)\n                || fn_def.opt_parent(cx).opt_impl_ty(cx).is_diag_item(cx, sym::Result))\n                && msrv.meets(cx, msrvs::OPTION_RESULT_INSPECT)))\n        && let body = cx.tcx.hir_body(c.body)\n        && let [param] = body.params\n        && let PatKind::Binding(BindingMode(ByRef::No, Mutability::Not), arg_id, _, None) = param.pat.kind\n        && let arg_ty = typeck.node_type(arg_id)\n        && let ExprKind::Block(block, _) = body.value.kind\n        && let Some(final_expr) = block.expr\n        && !block.stmts.is_empty()\n        && final_expr.res_local_id() == Some(arg_id)\n        && typeck.expr_adjustments(final_expr).is_empty()\n    {\n        let mut requires_copy = false;\n        let mut requires_deref = false;\n\n        // The number of unprocessed return expressions.\n        let mut ret_count = 0u32;\n\n        // The uses for which processing is delayed until after the visitor.\n        let mut delayed = vec![];\n\n        let ctxt = arg.span.ctxt();\n        let can_lint = for_each_expr_without_closures(block.stmts, |e| {\n            if let ExprKind::Closure(c) = e.kind {\n                // Nested closures don't need to treat returns specially.\n                let _: Option<!> = for_each_expr(cx, cx.tcx.hir_body(c.body).value, |e| {\n                    if e.res_local_id() == Some(arg_id) {\n                        let (kind, same_ctxt) = check_use(cx, e);\n                        match (kind, same_ctxt && e.span.ctxt() == ctxt) {\n                            (_, false) | (UseKind::Deref | UseKind::Return(..), true) => {\n                                requires_copy = true;\n                                requires_deref = true;\n                            },\n                            (UseKind::AutoBorrowed, true) => {},\n                            (UseKind::WillAutoDeref, true) => {\n                                requires_copy = true;\n                            },\n                            (kind, true) => delayed.push(kind),\n                        }\n                    }\n                    ControlFlow::Continue(())\n                });\n            } else if matches!(e.kind, ExprKind::Ret(_)) {\n                ret_count += 1;\n            } else if e.res_local_id() == Some(arg_id) {\n                let (kind, same_ctxt) = check_use(cx, e);\n                match (kind, same_ctxt && e.span.ctxt() == ctxt) {\n                    (UseKind::Return(..), false) => {\n                        return ControlFlow::Break(());\n                    },\n                    (_, false) | (UseKind::Deref, true) => {\n                        requires_copy = true;\n                        requires_deref = true;\n                    },\n                    (UseKind::AutoBorrowed, true) => {},\n                    (UseKind::WillAutoDeref, true) => {\n                        requires_copy = true;\n                    },\n                    (kind @ UseKind::Return(_), true) => {\n                        ret_count -= 1;\n                        delayed.push(kind);\n                    },\n                    (kind, true) => delayed.push(kind),\n                }\n            }\n            ControlFlow::Continue(())\n        })\n        .is_none();\n\n        if ret_count != 0 {\n            // A return expression that didn't return the original value was found.\n            return;\n        }\n\n        let mut edits = Vec::with_capacity(delayed.len() + 3);\n        let mut addr_of_edits = Vec::with_capacity(delayed.len());\n        for x in delayed {\n            match x {\n                UseKind::Return(s) => edits.push((s.with_leading_whitespace(cx).with_ctxt(s.ctxt()), String::new())),\n                UseKind::Borrowed(s) => {\n                    let range = s.map_range(cx, |_, src, range| {\n                        let src = src.get(range.clone())?;\n                        let trimmed = src.trim_start_matches([' ', '\\t', '\\n', '\\r', '(']);\n                        trimmed.starts_with('&').then(|| {\n                            let pos = range.start + src.len() - trimmed.len();\n                            pos..pos + 1\n                        })\n                    });\n                    if let Some(range) = range {\n                        addr_of_edits.push((range.with_ctxt(s.ctxt()), String::new()));\n                    } else {\n                        requires_copy = true;\n                        requires_deref = true;\n                    }\n                },\n                UseKind::FieldAccess(name, e) => {\n                    let Some(mut ty) = get_field_by_name(cx.tcx, arg_ty.peel_refs(), name) else {\n                        requires_copy = true;\n                        continue;\n                    };\n                    let mut prev_expr = e;\n\n                    for (_, parent) in cx.tcx.hir_parent_iter(e.hir_id) {\n                        if let Node::Expr(e) = parent {\n                            match e.kind {\n                                ExprKind::Field(_, name)\n                                    if let Some(fty) = get_field_by_name(cx.tcx, ty.peel_refs(), name.name) =>\n                                {\n                                    ty = fty;\n                                    prev_expr = e;\n                                    continue;\n                                },\n                                ExprKind::AddrOf(BorrowKind::Ref, ..) => break,\n                                _ if matches!(\n                                    typeck.expr_adjustments(prev_expr).first(),\n                                    Some(Adjustment {\n                                        kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not))\n                                            | Adjust::Deref(_),\n                                        ..\n                                    })\n                                ) =>\n                                {\n                                    break;\n                                },\n                                _ => {},\n                            }\n                        }\n                        requires_copy |= !cx.type_is_copy_modulo_regions(ty);\n                        break;\n                    }\n                },\n                // Already processed uses.\n                UseKind::AutoBorrowed | UseKind::WillAutoDeref | UseKind::Deref => {},\n            }\n        }\n\n        if can_lint\n            && (!requires_copy || cx.type_is_copy_modulo_regions(arg_ty))\n            // This case could be handled, but a fair bit of care would need to be taken.\n            && (!requires_deref || arg_ty.is_freeze(cx.tcx, cx.typing_env()))\n        {\n            if requires_deref {\n                edits.push((param.span.shrink_to_lo(), \"&\".into()));\n            } else {\n                edits.extend(addr_of_edits);\n            }\n            let edit = match name {\n                sym::map => \"inspect\",\n                sym::map_err => \"inspect_err\",\n                _ => return,\n            };\n            edits.push((name_span, edit.to_string()));\n            edits.push((\n                final_expr\n                    .span\n                    .with_leading_whitespace(cx)\n                    .with_ctxt(final_expr.span.ctxt()),\n                String::new(),\n            ));\n            let app = if edits.iter().any(|(s, _)| s.from_expansion()) {\n                Applicability::MaybeIncorrect\n            } else {\n                Applicability::MachineApplicable\n            };\n            span_lint_and_then(\n                cx,\n                MANUAL_INSPECT,\n                name_span,\n                format!(\"using `{name}` over `{edit}`\"),\n                |diag| {\n                    diag.multipart_suggestion(\"try\", edits, app);\n                },\n            );\n        }\n    }\n}\n\nenum UseKind<'tcx> {\n    AutoBorrowed,\n    WillAutoDeref,\n    Deref,\n    Return(Span),\n    Borrowed(Span),\n    FieldAccess(Symbol, &'tcx Expr<'tcx>),\n}\n\n/// Checks how the value is used, and whether it was used in the same `SyntaxContext`.\nfn check_use<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (UseKind<'tcx>, bool) {\n    let use_cx = expr_use_ctxt(cx, e);\n    if use_cx\n        .adjustments\n        .first()\n        .is_some_and(|a| matches!(a.kind, Adjust::Deref(_)))\n    {\n        return (UseKind::AutoBorrowed, use_cx.same_ctxt);\n    }\n    let res = match use_cx.use_node(cx) {\n        ExprUseNode::Return(_) => {\n            if let ExprKind::Ret(Some(e)) = use_cx.node.expect_expr().kind {\n                UseKind::Return(e.span)\n            } else {\n                return (UseKind::Return(DUMMY_SP), false);\n            }\n        },\n        ExprUseNode::FieldAccess(name) => UseKind::FieldAccess(name.name, use_cx.node.expect_expr()),\n        ExprUseNode::Callee | ExprUseNode::MethodArg(_, _, 0)\n            if use_cx\n                .adjustments\n                .first()\n                .is_some_and(|a| matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)))) =>\n        {\n            UseKind::AutoBorrowed\n        },\n        ExprUseNode::Callee | ExprUseNode::MethodArg(_, _, 0) => UseKind::WillAutoDeref,\n        ExprUseNode::AddrOf(BorrowKind::Ref, _) => UseKind::Borrowed(use_cx.node.expect_expr().span),\n        _ => UseKind::Deref,\n    };\n    (res, use_cx.same_ctxt)\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_is_variant_and.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{SpanlessEq, get_parent_expr, sym};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{BinOpKind, Closure, Expr, ExprKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, Symbol};\n\nuse super::MANUAL_IS_VARIANT_AND;\n\n#[derive(Clone, Copy, PartialEq)]\nenum Flavor {\n    Option,\n    Result,\n}\n\nimpl Flavor {\n    fn new(cx: &LateContext<'_>, def_id: DefId) -> Option<Self> {\n        match cx.tcx.get_diagnostic_name(def_id)? {\n            sym::Option => Some(Self::Option),\n            sym::Result => Some(Self::Result),\n            _ => None,\n        }\n    }\n\n    const fn diag_sym(self) -> Symbol {\n        match self {\n            Self::Option => sym::Option,\n            Self::Result => sym::Result,\n        }\n    }\n\n    const fn positive_variant_name(self) -> Symbol {\n        match self {\n            Self::Option => sym::Some,\n            Self::Result => sym::Ok,\n        }\n    }\n}\n\npub(super) fn check_map_unwrap_or_default(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    map_recv: &Expr<'_>,\n    map_arg: &Expr<'_>,\n    map_span: Span,\n    msrv: Msrv,\n) {\n    // Don't lint if:\n\n    // 1. the `expr` is generated by a macro\n    if expr.span.from_expansion() {\n        return;\n    }\n\n    // 2. the caller of `map()` is neither `Option` nor `Result`\n    let Some(flavor) = (cx.typeck_results())\n        .expr_ty(map_recv)\n        .opt_def_id()\n        .and_then(|did| Flavor::new(cx, did))\n    else {\n        return;\n    };\n\n    // 3. the caller of `unwrap_or_default` is neither `Option<bool>` nor `Result<bool, _>`\n    if !cx.typeck_results().expr_ty(expr).is_bool() {\n        return;\n    }\n\n    // 4. msrv doesn't meet `OPTION_RESULT_IS_VARIANT_AND`\n    if !msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) {\n        return;\n    }\n\n    let lint_span = expr.span.with_lo(map_span.lo());\n    let lint_msg = match flavor {\n        Flavor::Option => \"called `map(<f>).unwrap_or_default()` on an `Option` value\",\n        Flavor::Result => \"called `map(<f>).unwrap_or_default()` on a `Result` value\",\n    };\n\n    span_lint_and_then(cx, MANUAL_IS_VARIANT_AND, lint_span, lint_msg, |diag| {\n        let method = match flavor {\n            Flavor::Option => \"is_some_and\",\n            Flavor::Result => \"is_ok_and\",\n        };\n\n        let mut app = Applicability::MachineApplicable;\n        let map_arg_snippet = snippet_with_applicability(cx, map_arg.span, \"_\", &mut app);\n\n        diag.span_suggestion(lint_span, \"use\", format!(\"{method}({map_arg_snippet})\"), app);\n    });\n}\n\n#[derive(Clone, Copy, PartialEq)]\nenum Op {\n    Eq,\n    Ne,\n}\n\nimpl std::fmt::Display for Op {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::Eq => write!(f, \"==\"),\n            Self::Ne => write!(f, \"!=\"),\n        }\n    }\n}\n\nimpl TryFrom<BinOpKind> for Op {\n    type Error = ();\n    fn try_from(op: BinOpKind) -> Result<Self, Self::Error> {\n        match op {\n            BinOpKind::Eq => Ok(Self::Eq),\n            BinOpKind::Ne => Ok(Self::Ne),\n            _ => Err(()),\n        }\n    }\n}\n\n/// Represents the argument of the `.map()` function, as a closure or as a path\n/// in case η-reduction is used.\nenum MapFunc<'hir> {\n    Closure(&'hir Closure<'hir>),\n    Path(&'hir Expr<'hir>),\n}\n\nimpl<'hir> TryFrom<&'hir Expr<'hir>> for MapFunc<'hir> {\n    type Error = ();\n\n    fn try_from(expr: &'hir Expr<'hir>) -> Result<Self, Self::Error> {\n        match expr.kind {\n            ExprKind::Closure(closure) => Ok(Self::Closure(closure)),\n            ExprKind::Path(_) => Ok(Self::Path(expr)),\n            _ => Err(()),\n        }\n    }\n}\n\nimpl<'hir> MapFunc<'hir> {\n    /// Build a suggestion suitable for use in a `.map()`-like function. η-expansion will be applied\n    /// as needed.\n    fn sugg(self, cx: &LateContext<'hir>, invert: bool, app: &mut Applicability) -> String {\n        match self {\n            Self::Closure(closure) => {\n                let body = Sugg::hir_with_applicability(cx, cx.tcx.hir_body(closure.body).value, \"..\", app);\n                format!(\n                    \"{} {}\",\n                    snippet_with_applicability(cx, closure.fn_decl_span, \"|..|\", app),\n                    if invert { !body } else { body }\n                )\n            },\n            Self::Path(expr) => {\n                let path = snippet_with_applicability(cx, expr.span, \"_\", app);\n                if invert {\n                    format!(\"|x| !{path}(x)\")\n                } else {\n                    path.to_string()\n                }\n            },\n        }\n    }\n}\n\nfn emit_lint<'tcx>(\n    cx: &LateContext<'tcx>,\n    span: Span,\n    op: Op,\n    flavor: Flavor,\n    in_some_or_ok: bool,\n    map_func: MapFunc<'tcx>,\n    recv: &Expr<'_>,\n) {\n    let mut app = Applicability::MachineApplicable;\n    let recv = snippet_with_applicability(cx, recv.span, \"_\", &mut app);\n\n    let (invert_expr, method, invert_body) = match (flavor, op) {\n        (Flavor::Option, Op::Eq) => (false, \"is_some_and\", !in_some_or_ok),\n        (Flavor::Option, Op::Ne) => (false, \"is_none_or\", in_some_or_ok),\n        (Flavor::Result, Op::Eq) => (false, \"is_ok_and\", !in_some_or_ok),\n        (Flavor::Result, Op::Ne) => (true, \"is_ok_and\", !in_some_or_ok),\n    };\n    span_lint_and_sugg(\n        cx,\n        MANUAL_IS_VARIANT_AND,\n        span,\n        format!(\"called `.map() {op} {pos}()`\", pos = flavor.positive_variant_name()),\n        \"use\",\n        format!(\n            \"{inversion}{recv}.{method}({body})\",\n            inversion = if invert_expr { \"!\" } else { \"\" },\n            body = map_func.sugg(cx, invert_body, &mut app),\n        ),\n        app,\n    );\n}\n\npub(super) fn check_map(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let Some(parent_expr) = get_parent_expr(cx, expr)\n        && let ExprKind::Binary(op, left, right) = parent_expr.kind\n        && op.span.eq_ctxt(expr.span)\n        && let Ok(op) = Op::try_from(op.node)\n    {\n        // Check `left` and `right` expression in any order\n        for (expr1, expr2) in [(left, right), (right, left)] {\n            if let ExprKind::Call(call, [arg]) = expr1.kind\n                && let ExprKind::Lit(lit) = arg.kind\n                && let LitKind::Bool(bool_cst) = lit.node\n                && let ExprKind::Path(QPath::Resolved(_, path)) = call.kind\n                && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) = path.res\n                && let ExprKind::MethodCall(_, recv, [map_expr], _) = expr2.kind\n                && let ty = cx.typeck_results().expr_ty(expr1)\n                && let ty::Adt(adt, args) = ty.kind()\n                && let Some(flavor) = Flavor::new(cx, adt.did())\n                && args.type_at(0).is_bool()\n                && cx.typeck_results().expr_ty(recv).is_diag_item(cx, flavor.diag_sym())\n                && let Ok(map_func) = MapFunc::try_from(map_expr)\n            {\n                emit_lint(cx, parent_expr.span, op, flavor, bool_cst, map_func, recv);\n                return;\n            }\n        }\n    }\n}\n\npub(super) fn check_or<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    lhs: &'tcx Expr<'tcx>,\n    rhs: &'tcx Expr<'tcx>,\n    msrv: Msrv,\n) {\n    let (some_recv, some_arg) = if let (\n        ExprKind::MethodCall(none_path, none_recv, [], _),\n        ExprKind::MethodCall(some_path, some_recv, [some_arg], _),\n    )\n    | (\n        ExprKind::MethodCall(some_path, some_recv, [some_arg], _),\n        ExprKind::MethodCall(none_path, none_recv, [], _),\n    ) = (lhs.kind, rhs.kind)\n        && none_path.ident.name == sym::is_none\n        && some_path.ident.name == sym::is_some_and\n        && cx\n            .typeck_results()\n            .expr_ty_adjusted(none_recv)\n            .peel_refs()\n            .is_diag_item(cx, sym::Option)\n        && cx\n            .typeck_results()\n            .expr_ty_adjusted(some_recv)\n            .peel_refs()\n            .is_diag_item(cx, sym::Option)\n        && SpanlessEq::new(cx).eq_expr(none_recv, some_recv)\n    {\n        (some_recv, some_arg)\n    } else {\n        return;\n    };\n\n    if !msrv.meets(cx, msrvs::IS_NONE_OR) {\n        return;\n    }\n\n    let Ok(map_func) = MapFunc::try_from(some_arg) else {\n        return;\n    };\n\n    span_lint_and_then(\n        cx,\n        MANUAL_IS_VARIANT_AND,\n        expr.span,\n        \"manual implementation of `Option::is_none_or`\",\n        |diag| {\n            let mut app = Applicability::MachineApplicable;\n            let (recv_snip, _) = snippet_with_context(cx, some_recv.span, expr.span.ctxt(), \"_\", &mut app);\n            let map_func_snip = map_func.sugg(cx, false, &mut app);\n\n            diag.span_suggestion(\n                expr.span,\n                \"use\",\n                format!(\"{recv_snip}.is_none_or({map_func_snip})\"),\n                app,\n            );\n        },\n    );\n}\n\npub(super) fn check_is_some_is_none<'tcx>(\n    cx: &LateContext<'tcx>,\n    call_span: Span,\n    recv: &'tcx Expr<'tcx>,\n    arg: &'tcx Expr<'tcx>,\n    is_some: bool,\n    msrv: Msrv,\n) {\n    if cx\n        .typeck_results()\n        .expr_ty_adjusted(recv)\n        .peel_refs()\n        .is_diag_item(cx, sym::Option)\n        && (is_some || msrv.meets(cx, msrvs::IS_NONE_OR))\n        && let Ok(map_func) = MapFunc::try_from(arg)\n    {\n        let method = if is_some { \"is_some_and\" } else { \"is_none_or\" };\n        let lint_span = recv.span.to(call_span);\n        span_lint_and_then(\n            cx,\n            MANUAL_IS_VARIANT_AND,\n            lint_span,\n            format!(\"manual implementation of `Option::{method}`\"),\n            |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let (recv_snip, _) = snippet_with_context(cx, recv.span, lint_span.ctxt(), \"_\", &mut app);\n                let map_func_snip = map_func.sugg(cx, !is_some, &mut app);\n\n                // We need to use `as_ref()` because `filter` takes a reference\n                diag.span_suggestion(\n                    lint_span,\n                    \"use\",\n                    format!(\"{recv_snip}.as_ref().{method}({map_func_snip})\"),\n                    app,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_next_back.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::sym;\nuse clippy_utils::ty::implements_trait;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    rev_call: &'tcx Expr<'_>,\n    rev_recv: &'tcx Expr<'_>,\n) {\n    let rev_recv_ty = cx.typeck_results().expr_ty(rev_recv);\n\n    // check that the receiver of `rev` implements `DoubleEndedIterator` and\n    // that `rev` and `next` come from `Iterator`\n    if cx\n        .tcx\n        .get_diagnostic_item(sym::DoubleEndedIterator)\n        .is_some_and(|double_ended_iterator| implements_trait(cx, rev_recv_ty, double_ended_iterator, &[]))\n        && cx.ty_based_def(rev_call).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n    {\n        span_lint_and_sugg(\n            cx,\n            super::MANUAL_NEXT_BACK,\n            expr.span.with_lo(rev_recv.span.hi()),\n            \"manual backwards iteration\",\n            \"use\",\n            String::from(\".next_back()\"),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_ok_or.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse clippy_utils::source::{SpanRangeExt, indent_of, reindent_multiline};\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::{ResultErr, ResultOk};\nuse rustc_hir::{Expr, ExprKind, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::sym;\n\nuse super::MANUAL_OK_OR;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    recv: &'tcx Expr<'_>,\n    or_expr: &'tcx Expr<'_>,\n    map_expr: &'tcx Expr<'_>,\n) {\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && cx\n            .tcx\n            .type_of(impl_id)\n            .instantiate_identity()\n            .is_diag_item(cx, sym::Option)\n        && let ExprKind::Call(err_path, [err_arg]) = or_expr.kind\n        && err_path.res(cx).ctor_parent(cx).is_lang_item(cx, ResultErr)\n        && is_ok_wrapping(cx, map_expr)\n        && let Some(recv_snippet) = recv.span.get_source_text(cx)\n        && let Some(err_arg_snippet) = err_arg.span.get_source_text(cx)\n        && let Some(indent) = indent_of(cx, expr.span)\n    {\n        let reindented_err_arg_snippet = reindent_multiline(err_arg_snippet.as_str(), true, Some(indent + 4));\n        span_lint_and_sugg(\n            cx,\n            MANUAL_OK_OR,\n            expr.span,\n            \"this pattern reimplements `Option::ok_or`\",\n            \"replace with\",\n            format!(\"{recv_snippet}.ok_or({reindented_err_arg_snippet})\"),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n\nfn is_ok_wrapping(cx: &LateContext<'_>, map_expr: &Expr<'_>) -> bool {\n    match map_expr.kind {\n        ExprKind::Path(ref qpath)\n            if cx\n                .qpath_res(qpath, map_expr.hir_id)\n                .ctor_parent(cx)\n                .is_lang_item(cx, ResultOk) =>\n        {\n            true\n        },\n        ExprKind::Closure(closure) => {\n            let body = cx.tcx.hir_body(closure.body);\n            if let PatKind::Binding(_, param_id, ..) = body.params[0].pat.kind\n                && let ExprKind::Call(callee, [ok_arg]) = body.value.kind\n                && callee.res(cx).ctor_parent(cx).is_lang_item(cx, ResultOk)\n            {\n                ok_arg.res_local_id() == Some(param_id)\n            } else {\n                false\n            }\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_repeat_n.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::{snippet, snippet_with_context};\nuse clippy_utils::{expr_use_ctxt, fn_def_id, std_or_core, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\n\nuse super::MANUAL_REPEAT_N;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    repeat_expr: &Expr<'_>,\n    take_arg: &Expr<'_>,\n    msrv: Msrv,\n) {\n    if !expr.span.from_expansion()\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let ExprKind::Call(_, [repeat_arg]) = repeat_expr.kind\n        && let Some(def_id) = fn_def_id(cx, repeat_expr)\n        && cx.tcx.is_diagnostic_item(sym::iter_repeat, def_id)\n        && !expr_use_ctxt(cx, expr).is_ty_unified\n        && let Some(std_or_core) = std_or_core(cx)\n        && msrv.meets(cx, msrvs::REPEAT_N)\n    {\n        let mut app = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            MANUAL_REPEAT_N,\n            expr.span,\n            \"this `repeat().take()` can be written more concisely\",\n            \"consider using `repeat_n()` instead\",\n            format!(\n                \"{std_or_core}::iter::repeat_n({}, {})\",\n                snippet_with_context(cx, repeat_arg.span, expr.span.ctxt(), \"..\", &mut app).0,\n                snippet(cx, take_arg.span, \"..\")\n            ),\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_saturating_arithmetic.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse rustc_ast::ast;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{self as hir, Expr};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_span::Symbol;\n\npub fn check_unwrap_or(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    arith_lhs: &Expr<'_>,\n    arith_rhs: &Expr<'_>,\n    unwrap_arg: &Expr<'_>,\n    arith: Symbol,\n) {\n    let ty = cx.typeck_results().expr_ty(arith_lhs);\n    if !ty.is_integral() {\n        return;\n    }\n\n    let Some(mm) = is_min_or_max(cx, unwrap_arg) else {\n        return;\n    };\n\n    let Some(checked_arith) = CheckedArith::new(arith) else {\n        return;\n    };\n\n    check(cx, expr, arith_lhs, arith_rhs, ty, mm, checked_arith);\n}\n\npub(super) fn check_sub_unwrap_or_default(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    arith_lhs: &Expr<'_>,\n    arith_rhs: &Expr<'_>,\n) {\n    let ty = cx.typeck_results().expr_ty(arith_lhs);\n    if !ty.is_integral() {\n        return;\n    }\n\n    let mm = if ty.is_signed() {\n        return; // iN::default() is 0, which is neither MIN nor MAX\n    } else {\n        MinMax::Min // uN::default() is 0, which is also the MIN\n    };\n\n    let checked_arith = CheckedArith::Sub;\n\n    check(cx, expr, arith_lhs, arith_rhs, ty, mm, checked_arith);\n}\n\nfn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    arith_lhs: &Expr<'_>,\n    arith_rhs: &Expr<'_>,\n    ty: Ty<'_>,\n    mm: MinMax,\n    checked_arith: CheckedArith,\n) {\n    use self::MinMax::{Max, Min};\n    use self::Sign::{Neg, Pos};\n    use CheckedArith::{Add, Mul, Sub};\n\n    if ty.is_signed() {\n        let Some(sign) = lit_sign(arith_rhs) else {\n            return;\n        };\n\n        match (checked_arith, sign, mm) {\n            (Add, Pos, Max) | (Add, Neg, Min) | (Sub, Neg, Max) | (Sub, Pos, Min) => (),\n            // \"mul\" is omitted because lhs can be negative.\n            _ => return,\n        }\n    } else {\n        match (mm, checked_arith) {\n            (Max, Add | Mul) | (Min, Sub) => (),\n            _ => return,\n        }\n    }\n\n    let mut applicability = Applicability::MachineApplicable;\n    let saturating_arith = checked_arith.as_saturating();\n    span_lint_and_sugg(\n        cx,\n        super::MANUAL_SATURATING_ARITHMETIC,\n        expr.span,\n        \"manual saturating arithmetic\",\n        format!(\"consider using `{saturating_arith}`\"),\n        format!(\n            \"{}.{saturating_arith}({})\",\n            snippet_with_applicability(cx, arith_lhs.span, \"..\", &mut applicability),\n            snippet_with_applicability(cx, arith_rhs.span, \"..\", &mut applicability),\n        ),\n        applicability,\n    );\n}\n\n#[derive(Clone, Copy)]\nenum CheckedArith {\n    Add,\n    Sub,\n    Mul,\n}\n\nimpl CheckedArith {\n    fn new(sym: Symbol) -> Option<Self> {\n        let res = match sym {\n            sym::checked_add => Self::Add,\n            sym::checked_sub => Self::Sub,\n            sym::checked_mul => Self::Mul,\n            _ => return None,\n        };\n        Some(res)\n    }\n\n    fn as_saturating(self) -> &'static str {\n        match self {\n            Self::Add => \"saturating_add\",\n            Self::Sub => \"saturating_sub\",\n            Self::Mul => \"saturating_mul\",\n        }\n    }\n}\n\n#[derive(PartialEq, Eq)]\nenum MinMax {\n    Min,\n    Max,\n}\n\nfn is_min_or_max(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<MinMax> {\n    // `T::max_value()` `T::min_value()` inherent methods\n    if let hir::ExprKind::Call(func, []) = &expr.kind\n        && let hir::ExprKind::Path(hir::QPath::TypeRelative(_, segment)) = &func.kind\n    {\n        match segment.ident.name {\n            sym::max_value => return Some(MinMax::Max),\n            sym::min_value => return Some(MinMax::Min),\n            _ => {},\n        }\n    }\n\n    let ty = cx.typeck_results().expr_ty(expr);\n\n    // `T::MAX` and `T::MIN` constants\n    if let hir::ExprKind::Path(hir::QPath::TypeRelative(base, seg)) = expr.kind\n        && matches!(base.basic_res(), Res::PrimTy(_))\n    {\n        match seg.ident.name {\n            sym::MAX => return Some(MinMax::Max),\n            sym::MIN => return Some(MinMax::Min),\n            _ => {},\n        }\n    }\n\n    // Literals\n    let bits = cx.layout_of(ty).unwrap().size.bits();\n    let (minval, maxval): (u128, u128) = if ty.is_signed() {\n        let minval = 1 << (bits - 1);\n        let mut maxval = !(1 << (bits - 1));\n        if bits != 128 {\n            maxval &= (1 << bits) - 1;\n        }\n        (minval, maxval)\n    } else {\n        (0, if bits == 128 { !0 } else { (1 << bits) - 1 })\n    };\n\n    let check_lit = |expr: &Expr<'_>, check_min: bool| {\n        if let hir::ExprKind::Lit(lit) = &expr.kind\n            && let ast::LitKind::Int(value, _) = lit.node\n        {\n            if value == maxval {\n                return Some(MinMax::Max);\n            }\n\n            if check_min && value == minval {\n                return Some(MinMax::Min);\n            }\n        }\n\n        None\n    };\n\n    if let r @ Some(_) = check_lit(expr, !ty.is_signed()) {\n        return r;\n    }\n\n    if ty.is_signed()\n        && let hir::ExprKind::Unary(hir::UnOp::Neg, val) = &expr.kind\n    {\n        return check_lit(val, true);\n    }\n\n    None\n}\n\n#[derive(PartialEq, Eq)]\nenum Sign {\n    Pos,\n    Neg,\n}\n\nfn lit_sign(expr: &Expr<'_>) -> Option<Sign> {\n    if let hir::ExprKind::Unary(hir::UnOp::Neg, inner) = &expr.kind {\n        if let hir::ExprKind::Lit(..) = &inner.kind {\n            return Some(Sign::Neg);\n        }\n    } else if let hir::ExprKind::Lit(..) = &expr.kind {\n        return Some(Sign::Pos);\n    }\n\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_str_repeat.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::sym;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse std::borrow::Cow;\n\nuse super::MANUAL_STR_REPEAT;\n\nenum RepeatKind {\n    String,\n    Char(char),\n}\n\nfn get_ty_param(ty: Ty<'_>) -> Option<Ty<'_>> {\n    if let ty::Adt(_, subs) = ty.kind() {\n        subs.types().next()\n    } else {\n        None\n    }\n}\n\nfn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {\n    if let ExprKind::Lit(lit) = &e.kind {\n        match lit.node {\n            LitKind::Str(..) => Some(RepeatKind::String),\n            LitKind::Char(c) => Some(RepeatKind::Char(c)),\n            _ => None,\n        }\n    } else {\n        let ty = cx.typeck_results().expr_ty(e);\n        if ty.is_lang_item(cx, LangItem::String)\n            || (ty.is_lang_item(cx, LangItem::OwnedBox) && get_ty_param(ty).is_some_and(Ty::is_str))\n            || (ty.is_diag_item(cx, sym::Cow) && get_ty_param(ty).is_some_and(Ty::is_str))\n        {\n            Some(RepeatKind::String)\n        } else {\n            let ty = ty.peel_refs();\n            (ty.is_str() || ty.is_lang_item(cx, LangItem::String)).then_some(RepeatKind::String)\n        }\n    }\n}\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    collect_expr: &Expr<'_>,\n    take_expr: &Expr<'_>,\n    take_self_arg: &Expr<'_>,\n    take_arg: &Expr<'_>,\n) {\n    if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind\n        && repeat_fn.basic_res().is_diag_item(cx, sym::iter_repeat)\n        && cx\n            .typeck_results()\n            .expr_ty(collect_expr)\n            .is_lang_item(cx, LangItem::String)\n        && let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id)\n        && let Some(iter_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator)\n        && cx.tcx.trait_of_assoc(take_id) == Some(iter_trait_id)\n        && let Some(repeat_kind) = parse_repeat_arg(cx, repeat_arg)\n        && let ctxt = collect_expr.span.ctxt()\n        && ctxt == take_expr.span.ctxt()\n        && ctxt == take_self_arg.span.ctxt()\n    {\n        let mut app = Applicability::MachineApplicable;\n        let count_snip = snippet_with_context(cx, take_arg.span, ctxt, \"..\", &mut app).0;\n\n        let val_str = match repeat_kind {\n            RepeatKind::Char(_) if repeat_arg.span.ctxt() != ctxt => return,\n            RepeatKind::Char('\\'') => r#\"\"'\"\"#.into(),\n            RepeatKind::Char('\"') => r#\"\"\\\"\"\"#.into(),\n            RepeatKind::Char(_) => match snippet_with_applicability(cx, repeat_arg.span, \"..\", &mut app) {\n                Cow::Owned(s) => Cow::Owned(format!(\"\\\"{}\\\"\", &s[1..s.len() - 1])),\n                s @ Cow::Borrowed(_) => s,\n            },\n            RepeatKind::String => Sugg::hir_with_context(cx, repeat_arg, ctxt, \"..\", &mut app)\n                .maybe_paren()\n                .to_string()\n                .into(),\n        };\n\n        span_lint_and_sugg(\n            cx,\n            MANUAL_STR_REPEAT,\n            collect_expr.span,\n            \"manual implementation of `str::repeat` using iterators\",\n            \"try\",\n            format!(\"{val_str}.repeat({count_snip})\"),\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/manual_try_fold.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::ty::implements_trait;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_span::{Span, sym};\n\nuse super::MANUAL_TRY_FOLD;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'tcx>,\n    init: &Expr<'_>,\n    acc: &Expr<'_>,\n    fold_span: Span,\n    msrv: Msrv,\n) {\n    if !fold_span.in_external_macro(cx.sess().source_map())\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let init_ty = cx.typeck_results().expr_ty(init)\n        && let Some(try_trait) = cx.tcx.lang_items().try_trait()\n        && implements_trait(cx, init_ty, try_trait, &[])\n        && let ExprKind::Call(path, [first, rest @ ..]) = init.kind\n        && let ExprKind::Path(qpath) = path.kind\n        && let Res::Def(DefKind::Ctor(_, _), _) = cx.qpath_res(&qpath, path.hir_id)\n        && let ExprKind::Closure(closure) = acc.kind\n        && msrv.meets(cx, msrvs::ITERATOR_TRY_FOLD)\n        && !is_from_proc_macro(cx, expr)\n        && let Some(args_snip) = closure\n            .fn_arg_span\n            .and_then(|fn_arg_span| fn_arg_span.get_source_text(cx))\n    {\n        let init_snip = rest\n            .is_empty()\n            .then_some(first.span)\n            .and_then(|span| span.get_source_text(cx))\n            .map_or_else(|| \"...\".to_owned(), |src| src.to_owned());\n\n        span_lint_and_sugg(\n            cx,\n            MANUAL_TRY_FOLD,\n            fold_span,\n            \"usage of `Iterator::fold` on a type that implements `Try`\",\n            \"use `try_fold` instead\",\n            format!(\"try_fold({init_snip}, {args_snip} ...)\"),\n            Applicability::HasPlaceholders,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_all_any_identity.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_expr_identity_function;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, sym};\n\nuse super::MAP_ALL_ANY_IDENTITY;\n\n#[expect(clippy::too_many_arguments)]\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    recv: &Expr<'_>,\n    map_call_span: Span,\n    map_arg: &Expr<'_>,\n    any_call_span: Span,\n    any_arg: &Expr<'_>,\n    method: &str,\n) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && cx.ty_based_def(recv).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && is_expr_identity_function(cx, any_arg)\n        && let map_any_call_span = map_call_span.with_hi(any_call_span.hi())\n        && let Some(map_arg) = map_arg.span.get_source_text(cx)\n    {\n        span_lint_and_then(\n            cx,\n            MAP_ALL_ANY_IDENTITY,\n            map_any_call_span,\n            format!(\"usage of `.map(...).{method}(identity)`\"),\n            |diag| {\n                diag.span_suggestion_verbose(\n                    map_any_call_span,\n                    format!(\"use `.{method}(...)` instead\"),\n                    format!(\"{method}({map_arg})\"),\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_clone.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::peel_blocks;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::{is_copy, should_call_clone_as_function};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{self as hir, LangItem};\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::{Mutability, Pinnedness};\nuse rustc_middle::ty;\nuse rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};\nuse rustc_span::symbol::Ident;\nuse rustc_span::{Span, sym};\n\nuse super::MAP_CLONE;\n\n// If this `map` is called on an `Option` or a `Result` and the previous call is `as_ref`, we don't\n// run this lint because it would overlap with `useless_asref` which provides a better suggestion\n// in this case.\nfn should_run_lint(cx: &LateContext<'_>, e: &hir::Expr<'_>, method_parent_id: DefId) -> bool {\n    if method_parent_id.is_diag_item(cx, sym::Iterator) {\n        return true;\n    }\n    // We check if it's an `Option` or a `Result`.\n    if let Some(ty) = method_parent_id.opt_impl_ty(cx) {\n        if !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result)) {\n            return false;\n        }\n    } else {\n        return false;\n    }\n    // We check if the previous method call is `as_ref`.\n    if let hir::ExprKind::MethodCall(path1, receiver, _, _) = &e.kind\n        && let hir::ExprKind::MethodCall(path2, _, _, _) = &receiver.kind\n    {\n        return path2.ident.name != sym::as_ref || path1.ident.name != sym::map;\n    }\n\n    true\n}\n\npub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>, msrv: Msrv) {\n    if let Some(parent_id) = cx.typeck_results().type_dependent_def_id(e.hir_id).opt_parent(cx)\n        && should_run_lint(cx, e, parent_id)\n    {\n        match arg.kind {\n            hir::ExprKind::Closure(&hir::Closure { body, .. }) => {\n                let closure_body = cx.tcx.hir_body(body);\n                let closure_expr = peel_blocks(closure_body.value);\n                match closure_body.params[0].pat.kind {\n                    hir::PatKind::Ref(inner, Pinnedness::Not, Mutability::Not) => {\n                        if let hir::PatKind::Binding(hir::BindingMode::NONE, .., name, None) = inner.kind\n                            && ident_eq(name, closure_expr)\n                        {\n                            lint_explicit_closure(cx, e.span, recv.span, true, msrv);\n                        }\n                    },\n                    hir::PatKind::Binding(hir::BindingMode::NONE, .., name, None) => {\n                        match closure_expr.kind {\n                            hir::ExprKind::Unary(hir::UnOp::Deref, inner) => {\n                                if ident_eq(name, inner)\n                                    && let ty::Ref(.., Mutability::Not) = cx.typeck_results().expr_ty(inner).kind()\n                                {\n                                    lint_explicit_closure(cx, e.span, recv.span, true, msrv);\n                                }\n                            },\n                            hir::ExprKind::MethodCall(method, obj, [], _) => {\n                                if ident_eq(name, obj) && method.ident.name == sym::clone\n                                && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id)\n                                && let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id)\n                                && cx.tcx.lang_items().clone_trait() == Some(trait_id)\n                                // no autoderefs\n                                && !cx.typeck_results().expr_adjustments(obj).iter()\n                                    .any(|a| matches!(a.kind, Adjust::Deref(DerefAdjustKind::Overloaded(..))))\n                                {\n                                    let obj_ty = cx.typeck_results().expr_ty(obj);\n                                    if let ty::Ref(_, ty, mutability) = obj_ty.kind() {\n                                        if matches!(mutability, Mutability::Not) {\n                                            let copy = is_copy(cx, *ty);\n                                            lint_explicit_closure(cx, e.span, recv.span, copy, msrv);\n                                        }\n                                    } else {\n                                        lint_needless_cloning(cx, e.span, recv.span);\n                                    }\n                                }\n                            },\n                            hir::ExprKind::Call(call, [arg]) => {\n                                if let hir::ExprKind::Path(qpath) = call.kind\n                                    && ident_eq(name, arg)\n                                {\n                                    handle_path(cx, call, &qpath, e, recv);\n                                }\n                            },\n                            _ => {},\n                        }\n                    },\n                    _ => {},\n                }\n            },\n            hir::ExprKind::Path(qpath) => handle_path(cx, arg, &qpath, e, recv),\n            _ => {},\n        }\n    }\n}\n\nfn handle_path(\n    cx: &LateContext<'_>,\n    arg: &hir::Expr<'_>,\n    qpath: &hir::QPath<'_>,\n    e: &hir::Expr<'_>,\n    recv: &hir::Expr<'_>,\n) {\n    if let Some(path_def_id) = cx.qpath_res(qpath, arg.hir_id).opt_def_id()\n        && cx.tcx.lang_items().get(LangItem::CloneFn) == Some(path_def_id)\n        // The `copied` and `cloned` methods are only available on `&T` and `&mut T` in `Option`\n        // and `Result`.\n        && let ty::Adt(_, args) = cx.typeck_results().expr_ty(recv).kind()\n        && let args = args.as_slice()\n        && let Some(ty) = args.iter().find_map(|generic_arg| generic_arg.as_type())\n        && let ty::Ref(_, ty, Mutability::Not) = ty.kind()\n        && let ty::FnDef(_, lst) = cx.typeck_results().expr_ty(arg).kind()\n        && lst.iter().all(|l| l.as_type() == Some(*ty))\n        && !should_call_clone_as_function(cx, *ty)\n    {\n        lint_path(cx, e.span, recv.span, is_copy(cx, ty.peel_refs()));\n    }\n}\n\nfn ident_eq(name: Ident, path: &hir::Expr<'_>) -> bool {\n    if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = path.kind {\n        path.segments.len() == 1 && path.segments[0].ident == name\n    } else {\n        false\n    }\n}\n\nfn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) {\n    span_lint_and_sugg(\n        cx,\n        MAP_CLONE,\n        root.trim_start(receiver).unwrap(),\n        \"you are needlessly cloning iterator elements\",\n        \"remove the `map` call\",\n        String::new(),\n        Applicability::MachineApplicable,\n    );\n}\n\nfn lint_path(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool) {\n    let mut applicability = Applicability::MachineApplicable;\n\n    let replacement = if is_copy { \"copied\" } else { \"cloned\" };\n\n    span_lint_and_sugg(\n        cx,\n        MAP_CLONE,\n        replace,\n        \"you are explicitly cloning with `.map()`\",\n        format!(\"consider calling the dedicated `{replacement}` method\"),\n        format!(\n            \"{}.{replacement}()\",\n            snippet_with_applicability(cx, root, \"..\", &mut applicability),\n        ),\n        applicability,\n    );\n}\n\nfn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool, msrv: Msrv) {\n    let mut applicability = Applicability::MachineApplicable;\n\n    let (message, sugg_method) = if is_copy && msrv.meets(cx, msrvs::ITERATOR_COPIED) {\n        (\"you are using an explicit closure for copying elements\", \"copied\")\n    } else {\n        (\"you are using an explicit closure for cloning elements\", \"cloned\")\n    };\n\n    span_lint_and_sugg(\n        cx,\n        MAP_CLONE,\n        replace,\n        message,\n        format!(\"consider calling the dedicated `{sugg_method}` method\"),\n        format!(\n            \"{}.{sugg_method}()\",\n            snippet_with_applicability(cx, root, \"..\", &mut applicability),\n        ),\n        applicability,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_collect_result_unit.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::symbol::sym;\n\nuse super::MAP_COLLECT_RESULT_UNIT;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, iter: &hir::Expr<'_>, map_fn: &hir::Expr<'_>) {\n    // return of collect `Result<(),_>`\n    let collect_ret_ty = cx.typeck_results().expr_ty(expr);\n    if collect_ret_ty.is_diag_item(cx, sym::Result)\n        && let ty::Adt(_, args) = collect_ret_ty.kind()\n        && let Some(result_t) = args.types().next()\n        && result_t.is_unit()\n    // get parts for snippet\n    {\n        span_lint_and_sugg(\n            cx,\n            MAP_COLLECT_RESULT_UNIT,\n            expr.span,\n            \"`.map().collect()` can be replaced with `.try_for_each()`\",\n            \"try\",\n            format!(\n                \"{}.try_for_each({})\",\n                snippet(cx, iter.span, \"..\"),\n                snippet(cx, map_fn.span, \"..\")\n            ),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_err_ignore.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse rustc_hir::{CaptureBy, Closure, Expr, ExprKind, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::MAP_ERR_IGNORE;\n\npub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) {\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && cx\n            .tcx\n            .type_of(impl_id)\n            .instantiate_identity()\n            .is_diag_item(cx, sym::Result)\n        && let ExprKind::Closure(&Closure {\n            capture_clause: CaptureBy::Ref,\n            body,\n            fn_decl_span,\n            ..\n        }) = arg.kind\n        && let closure_body = cx.tcx.hir_body(body)\n        && let [param] = closure_body.params\n        && let PatKind::Wild = param.pat.kind\n    {\n        // span the area of the closure capture and warn that the\n        // original error will be thrown away\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(\n            cx,\n            MAP_ERR_IGNORE,\n            fn_decl_span,\n            \"`map_err(|_|...` wildcard pattern discards the original error\",\n            |diag| {\n                diag.help(\n                    \"consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)\",\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_flatten.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::span_contains_comment;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::Span;\nuse rustc_span::symbol::sym;\n\nuse super::MAP_FLATTEN;\n\n/// lint use of `map().flatten()` for `Iterators` and 'Options'\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, map_arg: &Expr<'_>, map_span: Span) {\n    if let Some((caller_ty_name, method_to_use)) = try_get_caller_ty_name_and_method_name(cx, expr, recv, map_arg) {\n        let mut applicability = Applicability::MachineApplicable;\n\n        let closure_snippet = snippet_with_applicability(cx, map_arg.span, \"..\", &mut applicability);\n        let span = expr.span.with_lo(map_span.lo());\n        // If the methods are separated with comments, we don't apply suggestion automatically.\n        if span_contains_comment(cx, span) {\n            applicability = Applicability::Unspecified;\n        }\n        span_lint_and_sugg(\n            cx,\n            MAP_FLATTEN,\n            span,\n            format!(\"called `map(..).flatten()` on `{caller_ty_name}`\"),\n            format!(\"try replacing `map` with `{method_to_use}` and remove the `.flatten()`\"),\n            format!(\"{method_to_use}({closure_snippet})\"),\n            applicability,\n        );\n    }\n}\n\nfn try_get_caller_ty_name_and_method_name(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    caller_expr: &Expr<'_>,\n    map_arg: &Expr<'_>,\n) -> Option<(&'static str, &'static str)> {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        if is_map_to_option(cx, map_arg) {\n            // `(...).map(...)` has type `impl Iterator<Item=Option<...>>\n            Some((\"Iterator\", \"filter_map\"))\n        } else {\n            // `(...).map(...)` has type `impl Iterator<Item=impl Iterator<...>>\n            Some((\"Iterator\", \"flat_map\"))\n        }\n    } else {\n        if let ty::Adt(adt, _) = cx.typeck_results().expr_ty(caller_expr).kind() {\n            match cx.tcx.get_diagnostic_name(adt.did()) {\n                Some(sym::Option) => return Some((\"Option\", \"and_then\")),\n                Some(sym::Result) => return Some((\"Result\", \"and_then\")),\n                _ => {},\n            }\n        }\n        None\n    }\n}\n\nfn is_map_to_option(cx: &LateContext<'_>, map_arg: &Expr<'_>) -> bool {\n    let map_closure_ty = cx.typeck_results().expr_ty(map_arg);\n    match map_closure_ty.kind() {\n        ty::Closure(_, _) | ty::FnDef(_, _) | ty::FnPtr(..) => {\n            let map_closure_sig = match map_closure_ty.kind() {\n                ty::Closure(_, args) => args.as_closure().sig(),\n                _ => map_closure_ty.fn_sig(cx.tcx),\n            };\n            let map_closure_return_ty = cx.tcx.instantiate_bound_regions_with_erased(map_closure_sig.output());\n            map_closure_return_ty.is_diag_item(cx, sym::Option)\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_identity.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::is_copy;\nuse clippy_utils::{is_expr_untyped_identity_function, is_mutable, path_to_local_with_projections};\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, ExprKind, Node, PatKind};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_span::{Span, Symbol, sym};\n\nuse super::MAP_IDENTITY;\n\nconst MSG: &str = \"unnecessary map of the identity function\";\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    caller: &hir::Expr<'_>,\n    map_arg: &hir::Expr<'_>,\n    name: Symbol,\n    _map_span: Span,\n) {\n    let caller_ty = cx.typeck_results().expr_ty(caller);\n\n    if (cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        || caller_ty.is_diag_item(cx, sym::Result)\n        || caller_ty.is_diag_item(cx, sym::Option))\n        && is_expr_untyped_identity_function(cx, map_arg)\n        && let Some(call_span) = expr.span.trim_start(caller.span)\n    {\n        span_lint_and_then(cx, MAP_IDENTITY, call_span, MSG, |diag| {\n            let main_sugg = (call_span, String::new());\n            let mut app = if is_copy(cx, caller_ty) {\n                // there is technically a behavioral change here for `Copy` iterators, where\n                // `iter.map(|x| x).next()` would mutate a temporary copy of the iterator and\n                // changing it to `iter.next()` mutates iter directly\n                Applicability::Unspecified\n            } else {\n                Applicability::MachineApplicable\n            };\n\n            let needs_to_be_mutable = cx.typeck_results().expr_ty_adjusted(expr).is_mutable_ptr();\n            if needs_to_be_mutable && !is_mutable(cx, caller) {\n                if let Some(hir_id) = path_to_local_with_projections(caller)\n                    && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)\n                    && let PatKind::Binding(_, _, ident, _) = pat.kind\n                {\n                    // We can reach the binding -- suggest making it mutable\n                    let suggs = vec![main_sugg, (ident.span.shrink_to_lo(), String::from(\"mut \"))];\n\n                    let ident = snippet_with_applicability(cx.sess(), ident.span, \"_\", &mut app);\n\n                    diag.multipart_suggestion(\n                        format!(\"remove the call to `{name}`, and make `{ident}` mutable\"),\n                        suggs,\n                        app,\n                    );\n                } else {\n                    // If we can't make the binding mutable, prevent the suggestion from being automatically applied,\n                    // and add a complementary help message.\n                    app = Applicability::Unspecified;\n\n                    let method_requiring_mut = if let Node::Expr(expr) = cx.tcx.parent_hir_node(expr.hir_id)\n                        && let ExprKind::MethodCall(method, ..) = expr.kind\n                    {\n                        Some(method.ident)\n                    } else {\n                        None\n                    };\n\n                    diag.span_suggestion(main_sugg.0, format!(\"remove the call to `{name}`\"), main_sugg.1, app);\n\n                    let note = if let Some(method_requiring_mut) = method_requiring_mut {\n                        format!(\"this must be made mutable to use `{method_requiring_mut}`\")\n                    } else {\n                        \"this must be made mutable\".to_string()\n                    };\n                    diag.span_note(caller.span, note);\n                }\n            } else {\n                diag.span_suggestion(main_sugg.0, format!(\"remove the call to `{name}`\"), main_sugg.1, app);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_unwrap_or.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef as _, MaybeResPath as _};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::is_copy;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::intravisit::{Visitor, walk_expr, walk_path};\nuse rustc_hir::{ExprKind, HirId, LangItem, Node, PatKind, Path, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter;\nuse rustc_span::{Span, sym};\nuse std::ops::ControlFlow;\n\nuse super::MAP_UNWRAP_OR;\n\n/// lint use of `map().unwrap_or()` for `Option`s and `Result`s\n#[expect(clippy::too_many_arguments)]\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &rustc_hir::Expr<'_>,\n    recv: &rustc_hir::Expr<'_>,\n    map_arg: &'tcx rustc_hir::Expr<'_>,\n    unwrap_recv: &rustc_hir::Expr<'_>,\n    unwrap_arg: &'tcx rustc_hir::Expr<'_>,\n    map_span: Span,\n    msrv: Msrv,\n) {\n    let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();\n    let recv_ty_kind = match recv_ty.opt_diag_name(cx) {\n        Some(sym::Option) => sym::Option,\n        Some(sym::Result) if msrv.meets(cx, msrvs::RESULT_MAP_OR) => sym::Result,\n        _ => return,\n    };\n\n    let unwrap_arg_ty = cx.typeck_results().expr_ty(unwrap_arg);\n    if !is_copy(cx, unwrap_arg_ty) {\n        // Replacing `.map(<f>).unwrap_or(<a>)` with `.map_or(<a>, <f>)` can sometimes lead to\n        // borrowck errors, see #10579 for one such instance.\n        // In particular, if `a` causes a move and `f` references that moved binding, then we cannot lint:\n        // ```\n        // let x = vec![1, 2];\n        // x.get(0..1).map(|s| s.to_vec()).unwrap_or(x);\n        // ```\n        // This compiles, but changing it to `map_or` will produce a compile error:\n        // ```\n        // let x = vec![1, 2];\n        // x.get(0..1).map_or(x, |s| s.to_vec())\n        //                    ^ moving `x` here\n        // ^^^^^^^^^^^ while it is borrowed here (and later used in the closure)\n        // ```\n        // So, we have to check that `a` is not referenced anywhere (even outside of the `.map` closure!)\n        // before the call to `unwrap_or`.\n\n        let mut unwrap_visitor = UnwrapVisitor {\n            cx,\n            identifiers: FxHashSet::default(),\n        };\n        unwrap_visitor.visit_expr(unwrap_arg);\n\n        let mut reference_visitor = ReferenceVisitor {\n            cx,\n            identifiers: unwrap_visitor.identifiers,\n            unwrap_or_span: unwrap_arg.span,\n        };\n\n        let body = cx.tcx.hir_body_owned_by(cx.tcx.hir_enclosing_body_owner(expr.hir_id));\n\n        // Visit the body, and return if we've found a reference\n        if reference_visitor.visit_body(body).is_break() {\n            return;\n        }\n    }\n\n    if !unwrap_arg.span.eq_ctxt(map_span) {\n        return;\n    }\n\n    let mut applicability = Applicability::MachineApplicable;\n    // get snippet for unwrap_or()\n    let unwrap_snippet = snippet_with_applicability(cx, unwrap_arg.span, \"..\", &mut applicability);\n    // lint message\n\n    let suggest_kind = if recv_ty_kind == sym::Option\n        && unwrap_arg\n            .basic_res()\n            .ctor_parent(cx)\n            .is_lang_item(cx, LangItem::OptionNone)\n    {\n        SuggestedKind::AndThen\n    }\n    // is_some_and is stabilised && `unwrap_or` argument is false; suggest `is_some_and` instead\n    else if matches!(&unwrap_arg.kind, ExprKind::Lit(lit)\n            if matches!(lit.node, rustc_ast::LitKind::Bool(false)))\n        && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND)\n    {\n        SuggestedKind::IsVariantAnd\n    } else {\n        SuggestedKind::Other\n    };\n\n    let arg = match suggest_kind {\n        SuggestedKind::AndThen => \"None\",\n        SuggestedKind::IsVariantAnd => \"false\",\n        SuggestedKind::Other => \"<a>\",\n    };\n\n    let suggest = match (suggest_kind, recv_ty_kind) {\n        (SuggestedKind::AndThen, _) => \"and_then(<f>)\",\n        (SuggestedKind::IsVariantAnd, sym::Result) => \"is_ok_and(<f>)\",\n        (SuggestedKind::IsVariantAnd, sym::Option) => \"is_some_and(<f>)\",\n        _ => \"map_or(<a>, <f>)\",\n    };\n\n    let msg = format!(\n        \"called `map(<f>).unwrap_or({arg})` on {} `{recv_ty_kind}` value\",\n        if recv_ty_kind == sym::Option { \"an\" } else { \"a\" }\n    );\n\n    span_lint_and_then(cx, MAP_UNWRAP_OR, expr.span, msg, |diag| {\n        let map_arg_span = map_arg.span;\n\n        let mut suggestion = vec![\n            (\n                map_span,\n                String::from(match (suggest_kind, recv_ty_kind) {\n                    (SuggestedKind::AndThen, _) => \"and_then\",\n                    (SuggestedKind::IsVariantAnd, sym::Result) => \"is_ok_and\",\n                    (SuggestedKind::IsVariantAnd, sym::Option) => \"is_some_and\",\n                    (SuggestedKind::Other, _)\n                        if unwrap_arg_ty.peel_refs().is_array()\n                            && cx.typeck_results().expr_ty_adjusted(unwrap_arg).peel_refs().is_slice() =>\n                    {\n                        return;\n                    },\n                    _ => \"map_or\",\n                }),\n            ),\n            (expr.span.with_lo(unwrap_recv.span.hi()), String::new()),\n        ];\n\n        if matches!(suggest_kind, SuggestedKind::Other) {\n            suggestion.push((map_arg_span.with_hi(map_arg_span.lo()), format!(\"{unwrap_snippet}, \")));\n        }\n\n        diag.multipart_suggestion(format!(\"use `{suggest}` instead\"), suggestion, applicability);\n    });\n}\n\n#[derive(Clone, Copy, PartialEq, Eq)]\nenum SuggestedKind {\n    AndThen,\n    IsVariantAnd,\n    Other,\n}\n\nstruct UnwrapVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    identifiers: FxHashSet<HirId>,\n}\n\nimpl<'tcx> Visitor<'tcx> for UnwrapVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::All;\n\n    fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {\n        if let Res::Local(local_id) = path.res\n            && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)\n            && let PatKind::Binding(_, local_id, ..) = pat.kind\n        {\n            self.identifiers.insert(local_id);\n        }\n        walk_path(self, path);\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\nstruct ReferenceVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    identifiers: FxHashSet<HirId>,\n    unwrap_or_span: Span,\n}\n\nimpl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::All;\n    type Result = ControlFlow<()>;\n    fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) -> ControlFlow<()> {\n        // If we haven't found a reference yet, check if this references\n        // one of the locals that was moved in the `unwrap_or` argument.\n        // We are only interested in exprs that appear before the `unwrap_or` call.\n        if expr.span < self.unwrap_or_span\n            && let ExprKind::Path(ref path) = expr.kind\n            && let QPath::Resolved(_, path) = path\n            && let Res::Local(local_id) = path.res\n            && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)\n            && let PatKind::Binding(_, local_id, ..) = pat.kind\n            && self.identifiers.contains(&local_id)\n        {\n            return ControlFlow::Break(());\n        }\n        walk_expr(self, expr)\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_unwrap_or_else.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef as _;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sym;\nuse clippy_utils::usage::mutated_variables;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\n\nuse super::MAP_UNWRAP_OR;\n\n/// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s\n///\n/// Is part of the `map_unwrap_or` lint, split into separate files for readability.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'_>,\n    map_arg: &'tcx hir::Expr<'_>,\n    unwrap_arg: &'tcx hir::Expr<'_>,\n    msrv: Msrv,\n) -> bool {\n    let recv_ty = cx.typeck_results().expr_ty(recv).peel_refs();\n    let recv_ty_kind = match recv_ty.opt_diag_name(cx) {\n        Some(sym::Option) => sym::Option,\n        Some(sym::Result) if msrv.meets(cx, msrvs::RESULT_MAP_OR_ELSE) => sym::Result,\n        _ => return false,\n    };\n\n    // Don't make a suggestion that may fail to compile due to mutably borrowing\n    // the same variable twice.\n    let Some(map_mutated_vars) = mutated_variables(recv, cx) else {\n        return false;\n    };\n    let Some(unwrap_mutated_vars) = mutated_variables(unwrap_arg, cx) else {\n        return false;\n    };\n    if map_mutated_vars.intersection(&unwrap_mutated_vars).next().is_some() {\n        return false;\n    }\n\n    // lint message\n    let msg = if recv_ty_kind == sym::Option {\n        \"called `map(<f>).unwrap_or_else(<g>)` on an `Option` value\"\n    } else {\n        \"called `map(<f>).unwrap_or_else(<g>)` on a `Result` value\"\n    };\n    // get snippets for args to map() and unwrap_or_else()\n    let map_snippet = snippet(cx, map_arg.span, \"..\");\n    let unwrap_snippet = snippet(cx, unwrap_arg.span, \"..\");\n    // lint, with note if both map() and unwrap_or_else() have the same span\n    if map_arg.span.eq_ctxt(unwrap_arg.span) {\n        let var_snippet = snippet(cx, recv.span, \"..\");\n        span_lint_and_sugg(\n            cx,\n            MAP_UNWRAP_OR,\n            expr.span,\n            msg,\n            \"try\",\n            format!(\"{var_snippet}.map_or_else({unwrap_snippet}, {map_snippet})\"),\n            Applicability::MachineApplicable,\n        );\n        return true;\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs",
    "content": "use crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{eager_or_lazy, higher, std_or_core, usage};\nuse rustc_ast::LitKind;\nuse rustc_ast::ast::RangeLimits;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Body, Closure, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nfn extract_count_with_applicability(\n    cx: &LateContext<'_>,\n    range: higher::Range<'_>,\n    applicability: &mut Applicability,\n) -> Option<String> {\n    let start = range.start?;\n    let end = range.end?;\n    // TODO: This doesn't handle if either the start or end are negative literals, or if the start is\n    // not a literal. In the first case, we need to be careful about how we handle computing the\n    // count to avoid overflows. In the second, we may need to add parenthesis to make the\n    // suggestion correct.\n    if let ExprKind::Lit(lit) = start.kind\n        && let LitKind::Int(Pu128(lower_bound), _) = lit.node\n    {\n        if let ExprKind::Lit(lit) = end.kind\n            && let LitKind::Int(Pu128(upper_bound), _) = lit.node\n        {\n            // Here we can explicitly calculate the number of iterations\n            let count = if upper_bound >= lower_bound {\n                match range.limits {\n                    RangeLimits::HalfOpen => upper_bound - lower_bound,\n                    RangeLimits::Closed => (upper_bound - lower_bound).checked_add(1)?,\n                }\n            } else {\n                0\n            };\n            return Some(format!(\"{count}\"));\n        }\n        let end_snippet = Sugg::hir_with_applicability(cx, end, \"...\", applicability)\n            .maybe_paren()\n            .into_string();\n        if lower_bound == 0 {\n            if range.limits == RangeLimits::Closed {\n                return Some(format!(\"{end_snippet} + 1\"));\n            }\n            return Some(end_snippet);\n        }\n        if range.limits == RangeLimits::Closed {\n            return Some(format!(\"{end_snippet} - {}\", lower_bound - 1));\n        }\n        return Some(format!(\"{end_snippet} - {lower_bound}\"));\n    }\n    None\n}\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    ex: &Expr<'_>,\n    receiver: &Expr<'_>,\n    arg: &Expr<'_>,\n    msrv: Msrv,\n    method_name_span: Span,\n) {\n    let mut applicability = Applicability::MaybeIncorrect;\n    if let Some(range) = higher::Range::hir(cx, receiver)\n        && let ExprKind::Closure(Closure { body, .. }) = arg.kind\n        && let body_hir = cx.tcx.hir_body(*body)\n        && let Body {\n            params: [param],\n            value: body_expr,\n        } = body_hir\n        && !usage::BindingUsageFinder::are_params_used(cx, body_hir)\n        && let Some(count) = extract_count_with_applicability(cx, range, &mut applicability)\n        && let Some(exec_context) = std_or_core(cx)\n    {\n        let method_to_use_name;\n        let new_span;\n        let use_take;\n\n        if eager_or_lazy::switch_to_eager_eval(cx, body_expr) {\n            if msrv.meets(cx, msrvs::REPEAT_N) {\n                method_to_use_name = \"repeat_n\";\n                let body_snippet = snippet_with_applicability(cx, body_expr.span, \"..\", &mut applicability);\n                new_span = (arg.span, format!(\"{body_snippet}, {count}\"));\n                use_take = false;\n            } else {\n                method_to_use_name = \"repeat\";\n                let body_snippet = snippet_with_applicability(cx, body_expr.span, \"..\", &mut applicability);\n                new_span = (arg.span, body_snippet.to_string());\n                use_take = true;\n            }\n        } else if msrv.meets(cx, msrvs::REPEAT_WITH) {\n            method_to_use_name = \"repeat_with\";\n            new_span = (param.span, String::new());\n            use_take = true;\n        } else {\n            return;\n        }\n\n        // We need to provide nonempty parts to diag.multipart_suggestion so we\n        // collate all our parts here and then remove those that are empty.\n        let mut parts = vec![\n            (\n                ex.span.with_hi(method_name_span.hi()),\n                format!(\"{exec_context}::iter::{method_to_use_name}\"),\n            ),\n            new_span,\n        ];\n        if use_take {\n            parts.push((ex.span.shrink_to_hi(), format!(\".take({count})\")));\n        }\n\n        span_lint_and_then(\n            cx,\n            MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,\n            ex.span,\n            \"map of a closure that does not depend on its parameter over a range\",\n            |diag| {\n                diag.multipart_suggestion(\n                    if use_take {\n                        format!(\"remove the explicit range and use `{method_to_use_name}` and `take`\")\n                    } else {\n                        format!(\"remove the explicit range and use `{method_to_use_name}`\")\n                    },\n                    parts,\n                    applicability,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/mod.rs",
    "content": "mod bind_instead_of_map;\nmod bytecount;\nmod bytes_count_to_len;\nmod bytes_nth;\nmod case_sensitive_file_extension_comparisons;\nmod chars_cmp;\nmod chars_cmp_with_unwrap;\nmod chars_last_cmp;\nmod chars_last_cmp_with_unwrap;\nmod chars_next_cmp;\nmod chars_next_cmp_with_unwrap;\nmod clear_with_drain;\nmod clone_on_copy;\nmod clone_on_ref_ptr;\nmod cloned_instead_of_copied;\nmod collapsible_str_replace;\nmod double_ended_iterator_last;\nmod drain_collect;\nmod err_expect;\nmod expect_fun_call;\nmod extend_with_drain;\nmod filetype_is_file;\nmod filter_map;\nmod filter_map_bool_then;\nmod filter_map_identity;\nmod filter_map_next;\nmod filter_next;\nmod flat_map_identity;\nmod flat_map_option;\nmod format_collect;\nmod from_iter_instead_of_collect;\nmod get_first;\nmod get_last_with_len;\nmod get_unwrap;\nmod implicit_clone;\nmod inefficient_to_string;\nmod inspect_for_each;\nmod into_iter_on_ref;\nmod io_other_error;\nmod ip_constant;\nmod is_digit_ascii_radix;\nmod is_empty;\nmod iter_cloned_collect;\nmod iter_count;\nmod iter_filter;\nmod iter_kv_map;\nmod iter_next_slice;\nmod iter_nth;\nmod iter_nth_zero;\nmod iter_on_single_or_empty_collections;\nmod iter_out_of_bounds;\nmod iter_overeager_cloned;\nmod iter_skip_next;\nmod iter_skip_zero;\nmod iter_with_drain;\nmod iterator_step_by_zero;\nmod join_absolute_paths;\nmod lib;\nmod lines_filter_map_ok;\nmod manual_c_str_literals;\nmod manual_contains;\nmod manual_inspect;\nmod manual_is_variant_and;\nmod manual_next_back;\nmod manual_ok_or;\nmod manual_repeat_n;\nmod manual_saturating_arithmetic;\nmod manual_str_repeat;\nmod manual_try_fold;\nmod map_all_any_identity;\nmod map_clone;\nmod map_collect_result_unit;\nmod map_err_ignore;\nmod map_flatten;\nmod map_identity;\nmod map_unwrap_or;\nmod map_unwrap_or_else;\nmod map_with_unused_argument_over_ranges;\nmod mut_mutex_lock;\nmod needless_as_bytes;\nmod needless_character_iteration;\nmod needless_collect;\nmod needless_option_as_deref;\nmod needless_option_take;\nmod new_ret_no_self;\nmod no_effect_replace;\nmod obfuscated_if_else;\nmod ok_expect;\nmod open_options;\nmod option_as_ref_cloned;\nmod option_as_ref_deref;\nmod option_map_or_none;\nmod or_fun_call;\nmod or_then_unwrap;\nmod path_buf_push_overwrite;\nmod path_ends_with_ext;\nmod ptr_offset_by_literal;\nmod ptr_offset_with_cast;\nmod range_zip_with_len;\nmod read_line_without_trim;\nmod readonly_write_lock;\nmod redundant_as_str;\nmod repeat_once;\nmod result_map_or_else_none;\nmod return_and_then;\nmod search_is_some;\nmod seek_from_current;\nmod seek_to_start_instead_of_rewind;\nmod should_implement_trait;\nmod single_char_add_str;\nmod skip_while_next;\nmod sliced_string_as_bytes;\nmod stable_sort_primitive;\nmod str_split;\nmod str_splitn;\nmod string_extend_chars;\nmod string_lit_chars_any;\nmod suspicious_command_arg_space;\nmod suspicious_map;\nmod suspicious_splitn;\nmod suspicious_to_owned;\nmod swap_with_temporary;\nmod type_id_on_box;\nmod unbuffered_bytes;\nmod uninit_assumed_init;\nmod unit_hash;\nmod unnecessary_fallible_conversions;\nmod unnecessary_filter_map;\nmod unnecessary_first_then_check;\nmod unnecessary_fold;\nmod unnecessary_get_then_check;\nmod unnecessary_iter_cloned;\nmod unnecessary_join;\nmod unnecessary_lazy_eval;\nmod unnecessary_literal_unwrap;\nmod unnecessary_map_or;\nmod unnecessary_map_or_else;\nmod unnecessary_min_or_max;\nmod unnecessary_sort_by;\nmod unnecessary_to_owned;\nmod unwrap_expect_used;\nmod useless_asref;\nmod useless_nonzero_new_unchecked;\nmod utils;\nmod vec_resize_to_zero;\nmod verbose_file_reads;\nmod waker_clone_wake;\nmod wrong_self_convention;\nmod zst_offset;\n\nuse clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::macros::FormatArgsStorage;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::{contains_return, iter_input_pats, peel_blocks, sym};\npub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::{self as hir, Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::TraitRef;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))`\n    /// or `_.or_else(|x| Err(y))`.\n    ///\n    /// ### Why is this bad?\n    /// This can be written more concisely as `_.map(|x| y)` or `_.map_err(|x| y)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn opt() -> Option<&'static str> { Some(\"42\") }\n    /// # fn res() -> Result<&'static str, &'static str> { Ok(\"42\") }\n    /// let _ = opt().and_then(|s| Some(s.len()));\n    /// let _ = res().and_then(|s| if s.len() == 42 { Ok(10) } else { Ok(20) });\n    /// let _ = res().or_else(|s| if s.len() == 42 { Err(10) } else { Err(20) });\n    /// ```\n    ///\n    /// The correct use would be:\n    ///\n    /// ```no_run\n    /// # fn opt() -> Option<&'static str> { Some(\"42\") }\n    /// # fn res() -> Result<&'static str, &'static str> { Ok(\"42\") }\n    /// let _ = opt().map(|s| s.len());\n    /// let _ = res().map(|s| if s.len() == 42 { 10 } else { 20 });\n    /// let _ = res().map_err(|s| if s.len() == 42 { 10 } else { 20 });\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub BIND_INSTEAD_OF_MAP,\n    complexity,\n    \"using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// It checks for `str::bytes().count()` and suggests replacing it with\n    /// `str::len()`.\n    ///\n    /// ### Why is this bad?\n    /// `str::bytes().count()` is longer and may not be as performant as using\n    /// `str::len()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// \"hello\".bytes().count();\n    /// String::from(\"hello\").bytes().count();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// \"hello\".len();\n    /// String::from(\"hello\").len();\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub BYTES_COUNT_TO_LEN,\n    complexity,\n    \"Using `bytes().count()` when `len()` performs the same functionality\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of `.bytes().nth()`.\n    ///\n    /// ### Why is this bad?\n    /// `.as_bytes().get()` is more efficient and more\n    /// readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// \"Hello\".bytes().nth(3);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// \"Hello\".as_bytes().get(3);\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub BYTES_NTH,\n    style,\n    \"replace `.bytes().nth()` with `.as_bytes().get()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `ends_with` with possible file extensions\n    /// and suggests to use a case-insensitive approach instead.\n    ///\n    /// ### Why is this bad?\n    /// `ends_with` is case-sensitive and may not detect files with a valid extension.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn is_rust_file(filename: &str) -> bool {\n    ///     filename.ends_with(\".rs\")\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn is_rust_file(filename: &str) -> bool {\n    ///     let filename = std::path::Path::new(filename);\n    ///     filename.extension()\n    ///         .map_or(false, |ext| ext.eq_ignore_ascii_case(\"rs\"))\n    /// }\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,\n    pedantic,\n    \"Checks for calls to ends_with with case-sensitive file extensions\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.chars().last()` or\n    /// `_.chars().next_back()` on a `str` to check if it ends with a given char.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.ends_with(_)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let name = \"_\";\n    /// name.chars().last() == Some('_') || name.chars().next_back() == Some('-');\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let name = \"_\";\n    /// name.ends_with('_') || name.ends_with('-');\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CHARS_LAST_CMP,\n    style,\n    \"using `.chars().last()` or `.chars().next_back()` to check if a string ends with a char\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.chars().next()` on a `str` to check\n    /// if it starts with a given char.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.starts_with(_)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let name = \"foo\";\n    /// if name.chars().next() == Some('_') {};\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let name = \"foo\";\n    /// if name.starts_with('_') {};\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CHARS_NEXT_CMP,\n    style,\n    \"using `.chars().next()` to check if a string starts with a char\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.drain(..)` for the sole purpose of clearing a container.\n    ///\n    /// ### Why is this bad?\n    /// This creates an unnecessary iterator that is dropped immediately.\n    ///\n    /// Calling `.clear()` also makes the intent clearer.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut v = vec![1, 2, 3];\n    /// v.drain(..);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut v = vec![1, 2, 3];\n    /// v.clear();\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub CLEAR_WITH_DRAIN,\n    nursery,\n    \"calling `drain` in order to `clear` a container\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.clone()` on a `Copy` type.\n    ///\n    /// ### Why is this bad?\n    /// The only reason `Copy` types implement `Clone` is for\n    /// generics, not for using the `clone` method on a concrete type.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// 42u64.clone();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CLONE_ON_COPY,\n    complexity,\n    \"using `clone` on a `Copy` type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.clone()` on a ref-counted pointer,\n    /// (`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified\n    /// function syntax instead (e.g., `Rc::clone(foo)`).\n    ///\n    /// ### Why restrict this?\n    /// Calling `.clone()` on an `Rc`, `Arc`, or `Weak`\n    /// can obscure the fact that only the pointer is being cloned, not the underlying\n    /// data.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::rc::Rc;\n    /// let x = Rc::new(1);\n    ///\n    /// x.clone();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::rc::Rc;\n    /// # let x = Rc::new(1);\n    /// Rc::clone(&x);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CLONE_ON_REF_PTR,\n    restriction,\n    \"using `clone` on a ref-counted pointer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `cloned()` on an `Iterator` or `Option` where\n    /// `copied()` could be used instead.\n    ///\n    /// ### Why is this bad?\n    /// `copied()` is better because it guarantees that the type being cloned\n    /// implements `Copy`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// [1, 2, 3].iter().cloned();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// [1, 2, 3].iter().copied();\n    /// ```\n    #[clippy::version = \"1.53.0\"]\n    pub CLONED_INSTEAD_OF_COPIED,\n    pedantic,\n    \"used `cloned` where `copied` could be used instead\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for consecutive calls to `str::replace` (2 or more)\n    /// that can be collapsed into a single call.\n    ///\n    /// ### Why is this bad?\n    /// Consecutive `str::replace` calls scan the string multiple times\n    /// with repetitive code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let hello = \"hesuo worpd\"\n    ///     .replace('s', \"l\")\n    ///     .replace(\"u\", \"l\")\n    ///     .replace('p', \"l\");\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let hello = \"hesuo worpd\".replace(['s', 'u', 'p'], \"l\");\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub COLLAPSIBLE_STR_REPLACE,\n    perf,\n    \"collapse consecutive calls to str::replace (2 or more) into a single call\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// It identifies calls to `.is_empty()` on constant values.\n    ///\n    /// ### Why is this bad?\n    /// String literals and constant values are known at compile time. Checking if they\n    /// are empty will always return the same value. This might not be the intention of\n    /// the expression.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let value = \"\";\n    /// if value.is_empty() {\n    ///     println!(\"the string is empty\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// println!(\"the string is empty\");\n    /// ```\n    #[clippy::version = \"1.79.0\"]\n    pub CONST_IS_EMPTY,\n    suspicious,\n    \"is_empty() called on strings known at compile time\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for `Iterator::last` being called on a  `DoubleEndedIterator`, which can be replaced\n    /// with `DoubleEndedIterator::next_back`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// `Iterator::last` is implemented by consuming the iterator, which is unnecessary if\n    /// the iterator is a `DoubleEndedIterator`. Since Rust traits do not allow specialization,\n    /// `Iterator::last` cannot be optimized for `DoubleEndedIterator`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let last_arg = \"echo hello world\".split(' ').last();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let last_arg = \"echo hello world\".split(' ').next_back();\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub DOUBLE_ENDED_ITERATOR_LAST,\n    perf,\n    \"using `Iterator::last` on a `DoubleEndedIterator`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `.drain()` that clear the collection, immediately followed by a call to `.collect()`.\n    ///\n    /// > \"Collection\" in this context refers to any type with a `drain` method:\n    /// > `Vec`, `VecDeque`, `BinaryHeap`, `HashSet`,`HashMap`, `String`\n    ///\n    /// ### Why is this bad?\n    /// Using `mem::take` is faster as it avoids the allocation.\n    /// When using `mem::take`, the old collection is replaced with an empty one and ownership of\n    /// the old collection is returned.\n    ///\n    /// ### Known issues\n    /// `mem::take(&mut vec)` is almost equivalent to `vec.drain(..).collect()`, except that\n    /// it also moves the **capacity**. The user might have explicitly written it this way\n    /// to keep the capacity on the original `Vec`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn remove_all(v: &mut Vec<i32>) -> Vec<i32> {\n    ///     v.drain(..).collect()\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::mem;\n    /// fn remove_all(v: &mut Vec<i32>) -> Vec<i32> {\n    ///     mem::take(v)\n    /// }\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub DRAIN_COLLECT,\n    perf,\n    \"calling `.drain(..).collect()` to move all elements into a new collection\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `.err().expect()` calls on the `Result` type.\n    ///\n    /// ### Why is this bad?\n    /// `.expect_err()` can be called directly to avoid the extra type conversion from `err()`.\n    ///\n    /// ### Example\n    /// ```should_panic\n    /// let x: Result<u32, &str> = Ok(10);\n    /// x.err().expect(\"Testing err().expect()\");\n    /// ```\n    /// Use instead:\n    /// ```should_panic\n    /// let x: Result<u32, &str> = Ok(10);\n    /// x.expect_err(\"Testing expect_err\");\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub ERR_EXPECT,\n    style,\n    r#\"using `.err().expect(\"\")` when `.expect_err(\"\")` can be used\"#\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,\n    /// etc., and suggests to use `unwrap_or_else` instead\n    ///\n    /// ### Why is this bad?\n    /// The function will always be called.\n    ///\n    /// ### Known problems\n    /// If the function has side-effects, not calling it will\n    /// change the semantics of the program, but you shouldn't rely on that anyway.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let foo = Some(String::new());\n    /// # let err_code = \"418\";\n    /// # let err_msg = \"I'm a teapot\";\n    /// foo.expect(&format!(\"Err {}: {}\", err_code, err_msg));\n    ///\n    /// // or\n    ///\n    /// # let foo = Some(String::new());\n    /// foo.expect(format!(\"Err {}: {}\", err_code, err_msg).as_str());\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let foo = Some(String::new());\n    /// # let err_code = \"418\";\n    /// # let err_msg = \"I'm a teapot\";\n    /// foo.unwrap_or_else(|| panic!(\"Err {}: {}\", err_code, err_msg));\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EXPECT_FUN_CALL,\n    perf,\n    \"using any `expect` method with a function call\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `.expect()` or `.expect_err()` calls on `Result`s and `.expect()` call on `Option`s.\n    ///\n    /// ### Why restrict this?\n    /// Usually it is better to handle the `None` or `Err` case.\n    /// Still, for a lot of quick-and-dirty code, `expect` is a good choice, which is why\n    /// this lint is `Allow` by default.\n    ///\n    /// `result.expect()` will let the thread panic on `Err`\n    /// values. Normally, you want to implement more sophisticated error handling,\n    /// and propagate errors upwards with `?` operator.\n    ///\n    /// ### Examples\n    /// ```rust,ignore\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// option.expect(\"one\");\n    /// result.expect(\"one\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// option?;\n    ///\n    /// // or\n    ///\n    /// result?;\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub EXPECT_USED,\n    restriction,\n    \"using `.expect()` on `Result` or `Option`, which might be better handled\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for occurrences where one vector gets extended instead of append\n    ///\n    /// ### Why is this bad?\n    /// Using `append` instead of `extend` is more concise and faster\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut a = vec![1, 2, 3];\n    /// let mut b = vec![4, 5, 6];\n    ///\n    /// a.extend(b.drain(..));\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let mut a = vec![1, 2, 3];\n    /// let mut b = vec![4, 5, 6];\n    ///\n    /// a.append(&mut b);\n    /// ```\n    #[clippy::version = \"1.55.0\"]\n    pub EXTEND_WITH_DRAIN,\n    perf,\n    \"using vec.append(&mut vec) to move the full range of a vector to another\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `FileType::is_file()`.\n    ///\n    /// ### Why restrict this?\n    /// When people testing a file type with `FileType::is_file`\n    /// they are testing whether a path is something they can get bytes from. But\n    /// `is_file` doesn't cover special file types in unix-like systems, and doesn't cover\n    /// symlink in windows. Using `!FileType::is_dir()` is a better way to that intention.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # || {\n    /// let metadata = std::fs::metadata(\"foo.txt\")?;\n    /// let filetype = metadata.file_type();\n    ///\n    /// if filetype.is_file() {\n    ///     // read file\n    /// }\n    /// # Ok::<_, std::io::Error>(())\n    /// # };\n    /// ```\n    ///\n    /// should be written as:\n    ///\n    /// ```no_run\n    /// # || {\n    /// let metadata = std::fs::metadata(\"foo.txt\")?;\n    /// let filetype = metadata.file_type();\n    ///\n    /// if !filetype.is_dir() {\n    ///     // read file\n    /// }\n    /// # Ok::<_, std::io::Error>(())\n    /// # };\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub FILETYPE_IS_FILE,\n    restriction,\n    \"`FileType::is_file` is not recommended to test for readable file type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `bool::then` in `Iterator::filter_map`.\n    ///\n    /// ### Why is this bad?\n    /// This can be written with `filter` then `map` instead, which would reduce nesting and\n    /// separates the filtering from the transformation phase. This comes with no cost to\n    /// performance and is just cleaner.\n    ///\n    /// ### Limitations\n    /// Does not lint `bool::then_some`, as it eagerly evaluates its arguments rather than lazily.\n    /// This can create differing behavior, so better safe than sorry.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn really_expensive_fn(i: i32) -> i32 { i }\n    /// # let v = vec![];\n    /// _ = v.into_iter().filter_map(|i| (i % 2 == 0).then(|| really_expensive_fn(i)));\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # fn really_expensive_fn(i: i32) -> i32 { i }\n    /// # let v = vec![];\n    /// _ = v.into_iter().filter(|i| i % 2 == 0).map(|i| really_expensive_fn(i));\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub FILTER_MAP_BOOL_THEN,\n    style,\n    \"checks for usage of `bool::then` in `Iterator::filter_map`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `filter_map(|x| x)`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely by using `flatten`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let iter = vec![Some(1)].into_iter();\n    /// iter.filter_map(|x| x);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let iter = vec![Some(1)].into_iter();\n    /// iter.flatten();\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub FILTER_MAP_IDENTITY,\n    complexity,\n    \"call to `filter_map` where `flatten` is sufficient\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.filter_map(_).next()`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.find_map(_)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    ///  (0..3).filter_map(|x| if x == 2 { Some(x) } else { None }).next();\n    /// ```\n    /// Can be written as\n    ///\n    /// ```no_run\n    ///  (0..3).find_map(|x| if x == 2 { Some(x) } else { None });\n    /// ```\n    #[clippy::version = \"1.36.0\"]\n    pub FILTER_MAP_NEXT,\n    pedantic,\n    \"using combination of `filter_map` and `next` which can usually be written as a single method call\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.filter(_).next()`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.find(_)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let vec = vec![1];\n    /// vec.iter().filter(|x| **x == 0).next();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let vec = vec![1];\n    /// vec.iter().find(|x| **x == 0);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub FILTER_NEXT,\n    complexity,\n    \"using `filter(p).next()`, which is more succinctly expressed as `.find(p)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `flat_map(|x| x)`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely by using `flatten`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let iter = vec![vec![0]].into_iter();\n    /// iter.flat_map(|x| x);\n    /// ```\n    /// Can be written as\n    /// ```no_run\n    /// # let iter = vec![vec![0]].into_iter();\n    /// iter.flatten();\n    /// ```\n    #[clippy::version = \"1.39.0\"]\n    pub FLAT_MAP_IDENTITY,\n    complexity,\n    \"call to `flat_map` where `flatten` is sufficient\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Iterator::flat_map()` where `filter_map()` could be\n    /// used instead.\n    ///\n    /// ### Why is this bad?\n    /// `filter_map()` is known to always produce 0 or 1 output items per input item,\n    /// rather than however many the inner iterator type produces.\n    /// Therefore, it maintains the upper bound in `Iterator::size_hint()`,\n    /// and communicates to the reader that the input items are not being expanded into\n    /// multiple output items without their having to notice that the mapping function\n    /// returns an `Option`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let nums: Vec<i32> = [\"1\", \"2\", \"whee!\"].iter().flat_map(|x| x.parse().ok()).collect();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let nums: Vec<i32> = [\"1\", \"2\", \"whee!\"].iter().filter_map(|x| x.parse().ok()).collect();\n    /// ```\n    #[clippy::version = \"1.53.0\"]\n    pub FLAT_MAP_OPTION,\n    pedantic,\n    \"used `flat_map` where `filter_map` could be used instead\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.map(|_| format!(..)).collect::<String>()`.\n    ///\n    /// ### Why is this bad?\n    /// This allocates a new string for every element in the iterator.\n    /// This can be done more efficiently by creating the `String` once and appending to it in `Iterator::fold`,\n    /// using either the `write!` macro which supports exactly the same syntax as the `format!` macro,\n    /// or concatenating with `+` in case the iterator yields `&str`/`String`.\n    ///\n    /// Note also that `write!`-ing into a `String` can never fail, despite the return type of `write!` being `std::fmt::Result`,\n    /// so it can be safely ignored or unwrapped.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn hex_encode(bytes: &[u8]) -> String {\n    ///     bytes.iter().map(|b| format!(\"{b:02X}\")).collect()\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::fmt::Write;\n    /// fn hex_encode(bytes: &[u8]) -> String {\n    ///     bytes.iter().fold(String::new(), |mut output, b| {\n    ///         let _ = write!(output, \"{b:02X}\");\n    ///         output\n    ///     })\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub FORMAT_COLLECT,\n    pedantic,\n    \"`format!`ing every element in a collection, then collecting the strings into a new `String`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `from_iter()` function calls on types that implement the `FromIterator`\n    /// trait.\n    ///\n    /// ### Why is this bad?\n    /// If it's needed to create a collection from the contents of an iterator, the `Iterator::collect(_)`\n    /// method is preferred. However, when it's needed to specify the container type,\n    /// `Vec::from_iter(_)` can be more readable than using a turbofish (e.g. `_.collect::<Vec<_>>()`). See\n    /// [FromIterator documentation](https://doc.rust-lang.org/std/iter/trait.FromIterator.html)\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let five_fives = std::iter::repeat(5).take(5);\n    ///\n    /// let v = Vec::from_iter(five_fives);\n    ///\n    /// assert_eq!(v, vec![5, 5, 5, 5, 5]);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let five_fives = std::iter::repeat(5).take(5);\n    ///\n    /// let v: Vec<i32> = five_fives.collect();\n    ///\n    /// assert_eq!(v, vec![5, 5, 5, 5, 5]);\n    /// ```\n    /// but prefer to use\n    /// ```no_run\n    /// let numbers: Vec<i32> = FromIterator::from_iter(1..=5);\n    /// ```\n    /// instead of\n    /// ```no_run\n    /// let numbers = (1..=5).collect::<Vec<_>>();\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub FROM_ITER_INSTEAD_OF_COLLECT,\n    pedantic,\n    \"use `.collect()` instead of `::from_iter()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `x.get(0)` instead of\n    /// `x.first()` or `x.front()`.\n    ///\n    /// ### Why is this bad?\n    /// Using `x.first()` for `Vec`s and slices or `x.front()`\n    /// for `VecDeque`s is easier to read and has the same result.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = vec![2, 3, 5];\n    /// let first_element = x.get(0);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let x = vec![2, 3, 5];\n    /// let first_element = x.first();\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub GET_FIRST,\n    style,\n    \"Using `x.get(0)` when `x.first()` or `x.front()` is simpler\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `x.get(x.len() - 1)` instead of\n    /// `x.last()`.\n    ///\n    /// ### Why is this bad?\n    /// Using `x.last()` is easier to read and has the same\n    /// result.\n    ///\n    /// Note that using `x[x.len() - 1]` is semantically different from\n    /// `x.last()`.  Indexing into the array will panic on out-of-bounds\n    /// accesses, while `x.get()` and `x.last()` will return `None`.\n    ///\n    /// There is another lint (get_unwrap) that covers the case of using\n    /// `x.get(index).unwrap()` instead of `x[index]`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = vec![2, 3, 5];\n    /// let last_element = x.get(x.len() - 1);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let x = vec![2, 3, 5];\n    /// let last_element = x.last();\n    /// ```\n    #[clippy::version = \"1.37.0\"]\n    pub GET_LAST_WITH_LEN,\n    complexity,\n    \"Using `x.get(x.len() - 1)` when `x.last()` is correct and simpler\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.get().unwrap()` (or\n    /// `.get_mut().unwrap`) on a standard library type which implements `Index`\n    ///\n    /// ### Why restrict this?\n    /// Using the Index trait (`[]`) is more clear and more\n    /// concise.\n    ///\n    /// ### Known problems\n    /// Not a replacement for error handling: Using either\n    /// `.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic`\n    /// if the value being accessed is `None`. If the use of `.get().unwrap()` is a\n    /// temporary placeholder for dealing with the `Option` type, then this does\n    /// not mitigate the need for error handling. If there is a chance that `.get()`\n    /// will be `None` in your program, then it is advisable that the `None` case\n    /// is handled in a future refactor instead of using `.unwrap()` or the Index\n    /// trait.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut some_vec = vec![0, 1, 2, 3];\n    /// let last = some_vec.get(3).unwrap();\n    /// *some_vec.get_mut(0).unwrap() = 1;\n    /// ```\n    /// The correct use would be:\n    /// ```no_run\n    /// let mut some_vec = vec![0, 1, 2, 3];\n    /// let last = some_vec[3];\n    /// some_vec[0] = 1;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub GET_UNWRAP,\n    restriction,\n    \"using `.get().unwrap()` or `.get_mut().unwrap()` when using `[]` would work instead\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer.\n    ///\n    /// ### Why is this bad?\n    /// These methods do the same thing as `_.clone()` but may be confusing as\n    /// to why we are calling `to_vec` on something that is already a `Vec` or calling `to_owned` on something that is already owned.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = vec![1, 2, 3];\n    /// let b = a.to_vec();\n    /// let c = a.to_owned();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let a = vec![1, 2, 3];\n    /// let b = a.clone();\n    /// let c = a.clone();\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub IMPLICIT_CLONE,\n    pedantic,\n    \"implicitly cloning a value by invoking a function on its dereferenced type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.to_string()` on an `&&T` where\n    /// `T` implements `ToString` directly (like `&&str` or `&&String`).\n    ///\n    /// ### Why is this bad?\n    /// In versions of the compiler before Rust 1.82.0, this bypasses the specialized\n    /// implementation of `ToString` and instead goes through the more expensive string\n    /// formatting facilities.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // Generic implementation for `T: Display` is used (slow)\n    /// [\"foo\", \"bar\"].iter().map(|s| s.to_string());\n    ///\n    /// // OK, the specialized impl is used\n    /// [\"foo\", \"bar\"].iter().map(|&s| s.to_string());\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub INEFFICIENT_TO_STRING,\n    pedantic,\n    \"using `to_string` on `&&T` where `T: ToString`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `inspect().for_each()`.\n    ///\n    /// ### Why is this bad?\n    /// It is the same as performing the computation\n    /// inside `inspect` at the beginning of the closure in `for_each`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// [1,2,3,4,5].iter()\n    /// .inspect(|&x| println!(\"inspect the number: {}\", x))\n    /// .for_each(|&x| {\n    ///     assert!(x >= 0);\n    /// });\n    /// ```\n    /// Can be written as\n    /// ```no_run\n    /// [1,2,3,4,5].iter()\n    /// .for_each(|&x| {\n    ///     println!(\"inspect the number: {}\", x);\n    ///     assert!(x >= 0);\n    /// });\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub INSPECT_FOR_EACH,\n    complexity,\n    \"using `.inspect().for_each()`, which can be replaced with `.for_each()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `into_iter` calls on references which should be replaced by `iter`\n    /// or `iter_mut`.\n    ///\n    /// ### Why is this bad?\n    /// Readability. Calling `into_iter` on a reference will not move out its\n    /// content into the resulting iterator, which is confusing. It is better just call `iter` or\n    /// `iter_mut` directly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let vec = vec![3, 4, 5];\n    /// (&vec).into_iter();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let vec = vec![3, 4, 5];\n    /// (&vec).iter();\n    /// ```\n    #[clippy::version = \"1.32.0\"]\n    pub INTO_ITER_ON_REF,\n    style,\n    \"using `.into_iter()` on a reference\"\n}\n\ndeclare_clippy_lint! {\n    /// This lint warns on calling `io::Error::new(..)` with a kind of\n    /// `io::ErrorKind::Other`.\n    ///\n    /// ### Why is this bad?\n    /// Since Rust 1.74, there's the `io::Error::other(_)` shortcut.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::io;\n    /// let _ = io::Error::new(io::ErrorKind::Other, \"bad\".to_string());\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let _ = std::io::Error::other(\"bad\".to_string());\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub IO_OTHER_ERROR,\n    style,\n    \"calling `std::io::Error::new(std::io::ErrorKind::Other, _)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for IP addresses that could be replaced with predefined constants such as\n    /// `Ipv4Addr::new(127, 0, 0, 1)` instead of using the appropriate constants.\n    ///\n    /// ### Why is this bad?\n    /// Using specific IP addresses like `127.0.0.1` or `::1` is less clear and less maintainable than using the\n    /// predefined constants `Ipv4Addr::LOCALHOST` or `Ipv6Addr::LOCALHOST`. These constants improve code\n    /// readability, make the intent explicit, and are less error-prone.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::net::{Ipv4Addr, Ipv6Addr};\n    ///\n    /// // IPv4 loopback\n    /// let addr_v4 = Ipv4Addr::new(127, 0, 0, 1);\n    ///\n    /// // IPv6 loopback\n    /// let addr_v6 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::net::{Ipv4Addr, Ipv6Addr};\n    ///\n    /// // IPv4 loopback\n    /// let addr_v4 = Ipv4Addr::LOCALHOST;\n    ///\n    /// // IPv6 loopback\n    /// let addr_v6 = Ipv6Addr::LOCALHOST;\n    /// ```\n    #[clippy::version = \"1.89.0\"]\n    pub IP_CONSTANT,\n    pedantic,\n    \"hardcoded localhost IP address\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds usages of [`char::is_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_digit) that\n    /// can be replaced with [`is_ascii_digit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_digit) or\n    /// [`is_ascii_hexdigit`](https://doc.rust-lang.org/stable/std/primitive.char.html#method.is_ascii_hexdigit).\n    ///\n    /// ### Why is this bad?\n    /// `is_digit(..)` is slower and requires specifying the radix.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let c: char = '6';\n    /// c.is_digit(10);\n    /// c.is_digit(16);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let c: char = '6';\n    /// c.is_ascii_digit();\n    /// c.is_ascii_hexdigit();\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub IS_DIGIT_ASCII_RADIX,\n    style,\n    \"use of `char::is_digit(..)` with literal radix of 10 or 16\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of `.cloned().collect()` on slice to\n    /// create a `Vec`.\n    ///\n    /// ### Why is this bad?\n    /// `.to_vec()` is clearer\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let s = [1, 2, 3, 4, 5];\n    /// let s2: Vec<isize> = s[..].iter().cloned().collect();\n    /// ```\n    /// The better use would be:\n    /// ```no_run\n    /// let s = [1, 2, 3, 4, 5];\n    /// let s2: Vec<isize> = s.to_vec();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ITER_CLONED_COLLECT,\n    style,\n    \"using `.cloned().collect()` on slice to create a `Vec`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of `.iter().count()`.\n    ///\n    /// ### Why is this bad?\n    /// `.len()` is more efficient and more\n    /// readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let some_vec = vec![0, 1, 2, 3];\n    ///\n    /// some_vec.iter().count();\n    /// &some_vec[..].iter().count();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let some_vec = vec![0, 1, 2, 3];\n    ///\n    /// some_vec.len();\n    /// &some_vec[..].len();\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub ITER_COUNT,\n    complexity,\n    \"replace `.iter().count()` with `.len()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.filter(Result::is_ok)` that may be replaced with a `.flatten()` call.\n    /// This lint will require additional changes to the follow-up calls as it affects the type.\n    ///\n    /// ### Why is this bad?\n    /// This pattern is often followed by manual unwrapping of `Result`. The simplification\n    /// results in more readable and succinct code without the need for manual unwrapping.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// vec![Ok::<i32, String>(1)].into_iter().filter(Result::is_ok);\n    ///\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// vec![Ok::<i32, String>(1)].into_iter().flatten();\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub ITER_FILTER_IS_OK,\n    pedantic,\n    \"filtering an iterator over `Result`s for `Ok` can be achieved with `flatten`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.filter(Option::is_some)` that may be replaced with a `.flatten()` call.\n    /// This lint will require additional changes to the follow-up calls as it affects the type.\n    ///\n    /// ### Why is this bad?\n    /// This pattern is often followed by manual unwrapping of the `Option`. The simplification\n    /// results in more readable and succinct code without the need for manual unwrapping.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// vec![Some(1)].into_iter().filter(Option::is_some);\n    ///\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// vec![Some(1)].into_iter().flatten();\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub ITER_FILTER_IS_SOME,\n    pedantic,\n    \"filtering an iterator over `Option`s for `Some` can be achieved with `flatten`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for iterating a map (`HashMap` or `BTreeMap`) and\n    /// ignoring either the keys or values.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Readability. There are `keys` and `values` methods that\n    /// can be used to express that we only need the keys or the values.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// # use std::collections::HashMap;\n    /// let map: HashMap<u32, u32> = HashMap::new();\n    /// let values = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::collections::HashMap;\n    /// let map: HashMap<u32, u32> = HashMap::new();\n    /// let values = map.values().collect::<Vec<_>>();\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub ITER_KV_MAP,\n    complexity,\n    \"iterating on map using `iter` when `keys` or `values` would do\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `iter().next()` on a Slice or an Array\n    ///\n    /// ### Why is this bad?\n    /// These can be shortened into `.get()`\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let a = [1, 2, 3];\n    /// # let b = vec![1, 2, 3];\n    /// a[2..].iter().next();\n    /// b.iter().next();\n    /// ```\n    /// should be written as:\n    /// ```no_run\n    /// # let a = [1, 2, 3];\n    /// # let b = vec![1, 2, 3];\n    /// a.get(2);\n    /// b.get(0);\n    /// ```\n    #[clippy::version = \"1.46.0\"]\n    pub ITER_NEXT_SLICE,\n    style,\n    \"using `.iter().next()` on a sliced array, which can be shortened to just `.get()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.iter().nth()`/`.iter_mut().nth()` on standard library types that have\n    /// equivalent `.get()`/`.get_mut()` methods.\n    ///\n    /// ### Why is this bad?\n    /// `.get()` and `.get_mut()` are equivalent but more concise.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let some_vec = vec![0, 1, 2, 3];\n    /// let bad_vec = some_vec.iter().nth(3);\n    /// let bad_slice = &some_vec[..].iter().nth(3);\n    /// ```\n    /// The correct use would be:\n    /// ```no_run\n    /// let some_vec = vec![0, 1, 2, 3];\n    /// let bad_vec = some_vec.get(3);\n    /// let bad_slice = &some_vec[..].get(3);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ITER_NTH,\n    style,\n    \"using `.iter().nth()` on a standard library type with O(1) element access\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of `iter.nth(0)`.\n    ///\n    /// ### Why is this bad?\n    /// `iter.next()` is equivalent to\n    /// `iter.nth(0)`, as they both consume the next element,\n    ///  but is more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::collections::HashSet;\n    /// # let mut s = HashSet::new();\n    /// # s.insert(1);\n    /// let x = s.iter().nth(0);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::collections::HashSet;\n    /// # let mut s = HashSet::new();\n    /// # s.insert(1);\n    /// let x = s.iter().next();\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub ITER_NTH_ZERO,\n    style,\n    \"replace `iter.nth(0)` with `iter.next()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for calls to `iter`, `iter_mut` or `into_iter` on empty collections\n    ///\n    /// ### Why is this bad?\n    ///\n    /// It is simpler to use the empty function from the standard library:\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// use std::{slice, option};\n    /// let a: slice::Iter<i32> = [].iter();\n    /// let f: option::IntoIter<i32> = None.into_iter();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::iter;\n    /// let a: iter::Empty<i32> = iter::empty();\n    /// let b: iter::Empty<i32> = iter::empty();\n    /// ```\n    ///\n    /// ### Known problems\n    ///\n    /// The type of the resulting iterator might become incompatible with its usage\n    #[clippy::version = \"1.65.0\"]\n    pub ITER_ON_EMPTY_COLLECTIONS,\n    nursery,\n    \"Iterator for empty array\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for calls to `iter`, `iter_mut` or `into_iter` on collections containing a single item\n    ///\n    /// ### Why is this bad?\n    ///\n    /// It is simpler to use the once function from the standard library:\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// let a = [123].iter();\n    /// let b = Some(123).into_iter();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::iter;\n    /// let a = iter::once(&123);\n    /// let b = iter::once(123);\n    /// ```\n    ///\n    /// ### Known problems\n    ///\n    /// The type of the resulting iterator might become incompatible with its usage\n    #[clippy::version = \"1.65.0\"]\n    pub ITER_ON_SINGLE_ITEMS,\n    nursery,\n    \"Iterator for array of length 1\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for iterator combinator calls such as `.take(x)` or `.skip(x)`\n    /// where `x` is greater than the amount of items that an iterator will produce.\n    ///\n    /// ### Why is this bad?\n    /// Taking or skipping more items than there are in an iterator either creates an iterator\n    /// with all items from the original iterator or an iterator with no items at all.\n    /// This is most likely not what the user intended to do.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// for _ in [1, 2, 3].iter().take(4) {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// for _ in [1, 2, 3].iter() {}\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub ITER_OUT_OF_BOUNDS,\n    suspicious,\n    \"calls to `.take()` or `.skip()` that are out of bounds\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.cloned().<func>()` where call to `.cloned()` can be postponed.\n    ///\n    /// ### Why is this bad?\n    /// It's often inefficient to clone all elements of an iterator, when eventually, only some\n    /// of them will be consumed.\n    ///\n    /// ### Known Problems\n    /// This `lint` removes the side of effect of cloning items in the iterator.\n    /// A code that relies on that side-effect could fail.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// # let vec = vec![\"string\".to_string()];\n    /// vec.iter().cloned().take(10);\n    /// vec.iter().cloned().last();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let vec = vec![\"string\".to_string()];\n    /// vec.iter().take(10).cloned();\n    /// vec.iter().last().cloned();\n    /// ```\n    #[clippy::version = \"1.60.0\"]\n    pub ITER_OVEREAGER_CLONED,\n    perf,\n    \"using `cloned()` early with `Iterator::iter()` can lead to some performance inefficiencies\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.skip(x).next()` on iterators.\n    ///\n    /// ### Why is this bad?\n    /// `.nth(x)` is cleaner\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let some_vec = vec![0, 1, 2, 3];\n    /// let bad_vec = some_vec.iter().skip(3).next();\n    /// let bad_slice = &some_vec[..].iter().skip(3).next();\n    /// ```\n    /// The correct use would be:\n    /// ```no_run\n    /// let some_vec = vec![0, 1, 2, 3];\n    /// let bad_vec = some_vec.iter().nth(3);\n    /// let bad_slice = &some_vec[..].iter().nth(3);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ITER_SKIP_NEXT,\n    style,\n    \"using `.skip(x).next()` on an iterator\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.skip(0)` on iterators.\n    ///\n    /// ### Why is this bad?\n    /// This was likely intended to be `.skip(1)` to skip the first element, as `.skip(0)` does\n    /// nothing. If not, the call should be removed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let v = vec![1, 2, 3];\n    /// let x = v.iter().skip(0).collect::<Vec<_>>();\n    /// let y = v.iter().collect::<Vec<_>>();\n    /// assert_eq!(x, y);\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub ITER_SKIP_ZERO,\n    correctness,\n    \"disallows `.skip(0)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.drain(..)` on `Vec` and `VecDeque` for iteration.\n    ///\n    /// ### Why is this bad?\n    /// `.into_iter()` is simpler with better performance.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::collections::HashSet;\n    /// let mut foo = vec![0, 1, 2, 3];\n    /// let bar: HashSet<usize> = foo.drain(..).collect();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::collections::HashSet;\n    /// let foo = vec![0, 1, 2, 3];\n    /// let bar: HashSet<usize> = foo.into_iter().collect();\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub ITER_WITH_DRAIN,\n    nursery,\n    \"replace `.drain(..)` with `.into_iter()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calling `.step_by(0)` on iterators which panics.\n    ///\n    /// ### Why is this bad?\n    /// This very much looks like an oversight. Use `panic!()` instead if you\n    /// actually intend to panic.\n    ///\n    /// ### Example\n    /// ```rust,should_panic\n    /// for x in (0..100).step_by(0) {\n    ///     //..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ITERATOR_STEP_BY_ZERO,\n    correctness,\n    \"using `Iterator::step_by(0)`, which will panic at runtime\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `Path::join` that start with a path separator (`\\\\` or `/`).\n    ///\n    /// ### Why is this bad?\n    /// If the argument to `Path::join` starts with a separator, it will overwrite\n    /// the original path. If this is intentional, prefer using `Path::new` instead.\n    ///\n    /// Note the behavior is platform dependent. A leading `\\\\` will be accepted\n    /// on unix systems as part of the file name\n    ///\n    /// See [`Path::join`](https://doc.rust-lang.org/std/path/struct.Path.html#method.join)\n    ///\n    /// ### Example\n    /// ```rust\n    /// # use std::path::{Path, PathBuf};\n    /// let path = Path::new(\"/bin\");\n    /// let joined_path = path.join(\"/sh\");\n    /// assert_eq!(joined_path, PathBuf::from(\"/sh\"));\n    /// ```\n    ///\n    /// Use instead;\n    /// ```rust\n    /// # use std::path::{Path, PathBuf};\n    /// let path = Path::new(\"/bin\");\n    ///\n    /// // If this was unintentional, remove the leading separator\n    /// let joined_path = path.join(\"sh\");\n    /// assert_eq!(joined_path, PathBuf::from(\"/bin/sh\"));\n    ///\n    /// // If this was intentional, create a new path instead\n    /// let new = Path::new(\"/sh\");\n    /// assert_eq!(new, PathBuf::from(\"/sh\"));\n    /// ```\n    #[clippy::version = \"1.76.0\"]\n    pub JOIN_ABSOLUTE_PATHS,\n    suspicious,\n    \"calls to `Path::join` which will overwrite the original path\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `lines.filter_map(Result::ok)` or `lines.flat_map(Result::ok)`\n    /// when `lines` has type `std::io::Lines`.\n    ///\n    /// ### Why is this bad?\n    /// `Lines` instances might produce a never-ending stream of `Err`, in which case\n    /// `filter_map(Result::ok)` will enter an infinite loop while waiting for an\n    /// `Ok` variant. Calling `next()` once is sufficient to enter the infinite loop,\n    /// even in the absence of explicit loops in the user code.\n    ///\n    /// This situation can arise when working with user-provided paths. On some platforms,\n    /// `std::fs::File::open(path)` might return `Ok(fs)` even when `path` is a directory,\n    /// but any later attempt to read from `fs` will return an error.\n    ///\n    /// ### Known problems\n    /// This lint suggests replacing `filter_map()` or `flat_map()` applied to a `Lines`\n    /// instance in all cases. There are two cases where the suggestion might not be\n    /// appropriate or necessary:\n    ///\n    /// - If the `Lines` instance can never produce any error, or if an error is produced\n    ///   only once just before terminating the iterator, using `map_while()` is not\n    ///   necessary but will not do any harm.\n    /// - If the `Lines` instance can produce intermittent errors then recover and produce\n    ///   successful results, using `map_while()` would stop at the first error.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::{fs::File, io::{self, BufRead, BufReader}};\n    /// # let _ = || -> io::Result<()> {\n    /// let mut lines = BufReader::new(File::open(\"some-path\")?).lines().filter_map(Result::ok);\n    /// // If \"some-path\" points to a directory, the next statement never terminates:\n    /// let first_line: Option<String> = lines.next();\n    /// # Ok(()) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::{fs::File, io::{self, BufRead, BufReader}};\n    /// # let _ = || -> io::Result<()> {\n    /// let mut lines = BufReader::new(File::open(\"some-path\")?).lines().map_while(Result::ok);\n    /// let first_line: Option<String> = lines.next();\n    /// # Ok(()) };\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub LINES_FILTER_MAP_OK,\n    suspicious,\n    \"filtering `std::io::Lines` with `filter_map()`, `flat_map()`, or `flatten()` might cause an infinite loop\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the manual creation of C strings (a string with a `NUL` byte at the end), either\n    /// through one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()`\n    /// on a (byte) string literal with a hardcoded `\\0` byte at the end.\n    ///\n    /// ### Why is this bad?\n    /// This can be written more concisely using `c\"str\"` literals and is also less error-prone,\n    /// because the compiler checks for interior `NUL` bytes and the terminating `NUL` byte is inserted automatically.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::ffi::CStr;\n    /// # mod libc { pub unsafe fn puts(_: *const i8) {} }\n    /// fn needs_cstr(_: &CStr) {}\n    ///\n    /// needs_cstr(CStr::from_bytes_with_nul(b\"Hello\\0\").unwrap());\n    /// unsafe { libc::puts(\"World\\0\".as_ptr().cast()) }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::ffi::CStr;\n    /// # mod libc { pub unsafe fn puts(_: *const i8) {} }\n    /// fn needs_cstr(_: &CStr) {}\n    ///\n    /// needs_cstr(c\"Hello\");\n    /// unsafe { libc::puts(c\"World\".as_ptr()) }\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub MANUAL_C_STR_LITERALS,\n    complexity,\n    r#\"creating a `CStr` through functions when `c\"\"` literals can be used\"#\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `iter().any()` on slices when it can be replaced with `contains()` and suggests doing so.\n    ///\n    /// ### Why is this bad?\n    /// `contains()` is more concise and idiomatic, while also being faster in some cases.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(values: &[u8]) -> bool {\n    ///     values.iter().any(|&v| v == 10)\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo(values: &[u8]) -> bool {\n    ///     values.contains(&10)\n    /// }\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub MANUAL_CONTAINS,\n    perf,\n    \"unnecessary `iter().any()` on slices that can be replaced with `contains()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.filter(_).map(_)` that can be written more simply\n    /// as `filter_map(_)`.\n    ///\n    /// ### Why is this bad?\n    /// Redundant code in the `filter` and `map` operations is poor style and\n    /// less performant.\n    ///\n     /// ### Example\n    /// ```no_run\n    /// (0_i32..10)\n    ///     .filter(|n| n.checked_add(1).is_some())\n    ///     .map(|n| n.checked_add(1).unwrap());\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// (0_i32..10).filter_map(|n| n.checked_add(1));\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub MANUAL_FILTER_MAP,\n    complexity,\n    \"using `_.filter(_).map(_)` in a way that can be written more simply as `filter_map(_)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.find(_).map(_)` that can be written more simply\n    /// as `find_map(_)`.\n    ///\n    /// ### Why is this bad?\n    /// Redundant code in the `find` and `map` operations is poor style and\n    /// less performant.\n    ///\n     /// ### Example\n    /// ```no_run\n    /// (0_i32..10)\n    ///     .find(|n| n.checked_add(1).is_some())\n    ///     .map(|n| n.checked_add(1).unwrap());\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// (0_i32..10).find_map(|n| n.checked_add(1));\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub MANUAL_FIND_MAP,\n    complexity,\n    \"using `_.find(_).map(_)` in a way that can be written more simply as `find_map(_)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for uses of `map` which return the original item.\n    ///\n    /// ### Why is this bad?\n    /// `inspect` is both clearer in intent and shorter.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = Some(0).map(|x| { println!(\"{x}\"); x });\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = Some(0).inspect(|x| println!(\"{x}\"));\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub MANUAL_INSPECT,\n    complexity,\n    \"use of `map` returning the original item\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// 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.\n    ///\n    /// Also checks for equality comparisons like `option.map(f) == Some(true)` and `result.map(f) == Ok(true)`.\n    ///\n    /// ### Why is this bad?\n    /// Readability. These can be written more concisely as `option.is_some_and(f)` and `result.is_ok_and(f)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// option.map(|a| a > 10).unwrap_or_default();\n    /// result.map(|a| a > 10).unwrap_or_default();\n    ///\n    /// option.map(|a| a > 10) == Some(true);\n    /// result.map(|a| a > 10) == Ok(true);\n    /// option.map(|a| a > 10) != Some(true);\n    /// result.map(|a| a > 10) != Ok(true);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// option.is_some_and(|a| a > 10);\n    /// result.is_ok_and(|a| a > 10);\n    ///\n    /// option.is_some_and(|a| a > 10);\n    /// result.is_ok_and(|a| a > 10);\n    /// option.is_none_or(|a| a > 10);\n    /// !result.is_ok_and(|a| a > 10);\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub MANUAL_IS_VARIANT_AND,\n    pedantic,\n    \"using `.map(f).unwrap_or_default()` or `.map(f) == Some/Ok(true)`, which are more succinctly expressed as `is_some_and(f)` or `is_ok_and(f)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `.rev().next()` on a `DoubleEndedIterator`\n    ///\n    /// ### Why is this bad?\n    /// `.next_back()` is cleaner.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let foo = [0; 10];\n    /// foo.iter().rev().next();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let foo = [0; 10];\n    /// foo.iter().next_back();\n    /// ```\n    #[clippy::version = \"1.71.0\"]\n    pub MANUAL_NEXT_BACK,\n    style,\n    \"manual reverse iteration of `DoubleEndedIterator`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Finds patterns that reimplement `Option::ok_or`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Concise code helps focusing on behavior instead of boilerplate.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// let foo: Option<i32> = None;\n    /// foo.map_or(Err(\"error\"), |v| Ok(v));\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let foo: Option<i32> = None;\n    /// foo.ok_or(\"error\");\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub MANUAL_OK_OR,\n    style,\n    \"finds patterns that can be encoded more concisely with `Option::ok_or`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for `repeat().take()` that can be replaced with `repeat_n()`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Using `repeat_n()` is more concise and clearer. Also, `repeat_n()` is sometimes faster than `repeat().take()` when the type of the element is non-trivial to clone because the original value can be reused for the last `.next()` call rather than always cloning.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = std::iter::repeat(10).take(3);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let _ = std::iter::repeat_n(10, 3);\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub MANUAL_REPEAT_N,\n    style,\n    \"detect `repeat().take()` that can be replaced with `repeat_n()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`.\n    ///\n    /// ### Why is this bad?\n    /// These can be written simply with `saturating_add/sub` methods.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let y: u32 = 0;\n    /// # let x: u32 = 100;\n    /// let add = x.checked_add(y).unwrap_or(u32::MAX);\n    /// let sub = x.checked_sub(y).unwrap_or(u32::MIN);\n    /// ```\n    ///\n    /// can be written using dedicated methods for saturating addition/subtraction as:\n    ///\n    /// ```no_run\n    /// # let y: u32 = 0;\n    /// # let x: u32 = 100;\n    /// let add = x.saturating_add(y);\n    /// let sub = x.saturating_sub(y);\n    /// ```\n    #[clippy::version = \"1.39.0\"]\n    pub MANUAL_SATURATING_ARITHMETIC,\n    style,\n    \"`.checked_add/sub(x).unwrap_or(MAX/MIN)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `str::splitn(2, _)`\n    ///\n    /// ### Why is this bad?\n    /// `split_once` is both clearer in intent and slightly more efficient.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let s = \"key=value=add\";\n    /// let (key, value) = s.splitn(2, '=').next_tuple()?;\n    /// let value = s.splitn(2, '=').nth(1)?;\n    ///\n    /// let mut parts = s.splitn(2, '=');\n    /// let key = parts.next()?;\n    /// let value = parts.next()?;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// let s = \"key=value=add\";\n    /// let (key, value) = s.split_once('=')?;\n    /// let value = s.split_once('=')?.1;\n    ///\n    /// let (key, value) = s.split_once('=')?;\n    /// ```\n    ///\n    /// ### Limitations\n    /// The multiple statement variant currently only detects `iter.next()?`/`iter.next().unwrap()`\n    /// in two separate `let` statements that immediately follow the `splitn()`\n    #[clippy::version = \"1.57.0\"]\n    pub MANUAL_SPLIT_ONCE,\n    complexity,\n    \"replace `.splitn(2, pat)` with `.split_once(pat)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual implementations of `str::repeat`\n    ///\n    /// ### Why is this bad?\n    /// These are both harder to read, as well as less performant.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: String = std::iter::repeat('x').take(10).collect();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let x: String = \"x\".repeat(10);\n    /// ```\n    #[clippy::version = \"1.54.0\"]\n    pub MANUAL_STR_REPEAT,\n    perf,\n    \"manual implementation of `str::repeat`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Iterator::fold` with a type that implements `Try`.\n    ///\n    /// ### Why is this bad?\n    /// The code should use `try_fold` instead, which short-circuits on failure, thus opening the\n    /// door for additional optimizations not possible with `fold` as rustc can guarantee the\n    /// function is never called on `None`, `Err`, etc., alleviating otherwise necessary checks. It's\n    /// also slightly more idiomatic.\n    ///\n    /// ### Known issues\n    /// This lint doesn't take into account whether a function does something on the failure case,\n    /// i.e., whether short-circuiting will affect behavior. Refactoring to `try_fold` is not\n    /// desirable in those cases.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// vec![1, 2, 3].iter().fold(Some(0i32), |sum, i| sum?.checked_add(*i));\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// vec![1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i));\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub MANUAL_TRY_FOLD,\n    perf,\n    \"checks for usage of `Iterator::fold` with a type that implements `Try`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.map(…)`, followed by `.all(identity)` or `.any(identity)`.\n    ///\n    /// ### Why is this bad?\n    /// The `.all(…)` or `.any(…)` methods can be called directly in place of `.map(…)`.\n    ///\n    /// ### Example\n    /// ```\n    /// # let mut v = [\"\"];\n    /// let e1 = v.iter().map(|s| s.is_empty()).all(|a| a);\n    /// let e2 = v.iter().map(|s| s.is_empty()).any(std::convert::identity);\n    /// ```\n    /// Use instead:\n    /// ```\n    /// # let mut v = [\"\"];\n    /// let e1 = v.iter().all(|s| s.is_empty());\n    /// let e2 = v.iter().any(|s| s.is_empty());\n    /// ```\n    #[clippy::version = \"1.84.0\"]\n    pub MAP_ALL_ANY_IDENTITY,\n    complexity,\n    \"combine `.map(_)` followed by `.all(identity)`/`.any(identity)` into a single call\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `map(|x| x.clone())` or\n    /// dereferencing closures for `Copy` types, on `Iterator` or `Option`,\n    /// and suggests `cloned()` or `copied()` instead\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = vec![42, 43];\n    /// let y = x.iter();\n    /// let z = y.map(|i| *i);\n    /// ```\n    ///\n    /// The correct use would be:\n    ///\n    /// ```no_run\n    /// let x = vec![42, 43];\n    /// let y = x.iter();\n    /// let z = y.cloned();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MAP_CLONE,\n    style,\n    \"using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.map(_).collect::<Result<(), _>()`.\n    ///\n    /// ### Why is this bad?\n    /// Using `try_for_each` instead is more readable and idiomatic.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// (0..3).map(|t| Err(t)).collect::<Result<(), _>>();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// (0..3).try_for_each(|t| Err(t));\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub MAP_COLLECT_RESULT_UNIT,\n    style,\n    \"using `.map(_).collect::<Result<(),_>()`, which can be replaced with `try_for_each`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for instances of `map_err(|_| Some::Enum)`\n    ///\n    /// ### Why restrict this?\n    /// This `map_err` throws away the original error rather than allowing the enum to\n    /// contain and report the cause of the error.\n    ///\n    /// ### Example\n    /// Before:\n    /// ```no_run\n    /// use std::fmt;\n    ///\n    /// #[derive(Debug)]\n    /// enum Error {\n    ///     Indivisible,\n    ///     Remainder(u8),\n    /// }\n    ///\n    /// impl fmt::Display for Error {\n    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n    ///         match self {\n    ///             Error::Indivisible => write!(f, \"could not divide input by three\"),\n    ///             Error::Remainder(remainder) => write!(\n    ///                 f,\n    ///                 \"input is not divisible by three, remainder = {}\",\n    ///                 remainder\n    ///             ),\n    ///         }\n    ///     }\n    /// }\n    ///\n    /// impl std::error::Error for Error {}\n    ///\n    /// fn divisible_by_3(input: &str) -> Result<(), Error> {\n    ///     input\n    ///         .parse::<i32>()\n    ///         .map_err(|_| Error::Indivisible)\n    ///         .map(|v| v % 3)\n    ///         .and_then(|remainder| {\n    ///             if remainder == 0 {\n    ///                 Ok(())\n    ///             } else {\n    ///                 Err(Error::Remainder(remainder as u8))\n    ///             }\n    ///         })\n    /// }\n    /// ```\n    ///\n    /// After:\n    /// ```rust\n    /// use std::{fmt, num::ParseIntError};\n    ///\n    /// #[derive(Debug)]\n    /// enum Error {\n    ///     Indivisible(ParseIntError),\n    ///     Remainder(u8),\n    /// }\n    ///\n    /// impl fmt::Display for Error {\n    ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n    ///         match self {\n    ///             Error::Indivisible(_) => write!(f, \"could not divide input by three\"),\n    ///             Error::Remainder(remainder) => write!(\n    ///                 f,\n    ///                 \"input is not divisible by three, remainder = {}\",\n    ///                 remainder\n    ///             ),\n    ///         }\n    ///     }\n    /// }\n    ///\n    /// impl std::error::Error for Error {\n    ///     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {\n    ///         match self {\n    ///             Error::Indivisible(source) => Some(source),\n    ///             _ => None,\n    ///         }\n    ///     }\n    /// }\n    ///\n    /// fn divisible_by_3(input: &str) -> Result<(), Error> {\n    ///     input\n    ///         .parse::<i32>()\n    ///         .map_err(Error::Indivisible)\n    ///         .map(|v| v % 3)\n    ///         .and_then(|remainder| {\n    ///             if remainder == 0 {\n    ///                 Ok(())\n    ///             } else {\n    ///                 Err(Error::Remainder(remainder as u8))\n    ///             }\n    ///         })\n    /// }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub MAP_ERR_IGNORE,\n    restriction,\n    \"`map_err` should not ignore the original error\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.flat_map(_)` for `Iterator` or `_.and_then(_)` for `Option`\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let vec = vec![vec![1]];\n    /// let opt = Some(5);\n    ///\n    /// vec.iter().map(|x| x.iter()).flatten();\n    /// opt.map(|x| Some(x * 2)).flatten();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let vec = vec![vec![1]];\n    /// # let opt = Some(5);\n    /// vec.iter().flat_map(|x| x.iter());\n    /// opt.and_then(|x| Some(x * 2));\n    /// ```\n    #[clippy::version = \"1.31.0\"]\n    pub MAP_FLATTEN,\n    complexity,\n    \"using combinations of `flatten` and `map` which can usually be written as a single method call\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for instances of `map(f)` where `f` is the identity function.\n    ///\n    /// ### Why is this bad?\n    /// It can be written more concisely without the call to `map`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = [1, 2, 3];\n    /// let y: Vec<_> = x.iter().map(|x| x).map(|x| 2*x).collect();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = [1, 2, 3];\n    /// let y: Vec<_> = x.iter().map(|x| 2*x).collect();\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub MAP_IDENTITY,\n    complexity,\n    \"using iterator.map(|x| x)\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or\n    /// `result.map(_).unwrap_or_else(_)`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, these can be written more concisely (resp.) as\n    /// `option.map_or(_, _)`, `option.map_or_else(_, _)` and `result.map_or_else(_, _)`.\n    ///\n    /// ### Known problems\n    /// The order of the arguments is not in execution order\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// # fn some_function(foo: ()) -> usize { 1 }\n    /// option.map(|a| a + 1).unwrap_or(0);\n    /// option.map(|a| a > 10).unwrap_or(false);\n    /// result.map(|a| a + 1).unwrap_or_else(some_function);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// # fn some_function(foo: ()) -> usize { 1 }\n    /// option.map_or(0, |a| a + 1);\n    /// option.is_some_and(|a| a > 10);\n    /// result.map_or_else(some_function, |a| a + 1);\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub MAP_UNWRAP_OR,\n    pedantic,\n    \"using `.map(f).unwrap_or(a)` or `.map(f).unwrap_or_else(func)`, which are more succinctly expressed as `map_or(a, f)` or `map_or_else(a, f)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for `Iterator::map` over ranges without using the parameter which\n    /// could be more clearly expressed using `std::iter::repeat(...).take(...)`\n    /// or `std::iter::repeat_n`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// It expresses the intent more clearly to `take` the correct number of times\n    /// from a generating function than to apply a closure to each number in a\n    /// range only to discard them.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// let random_numbers : Vec<_> = (0..10).map(|_| { 3 + 1 }).collect();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let f : Vec<_> = std::iter::repeat( 3 + 1 ).take(10).collect();\n    /// ```\n    ///\n    /// ### Known Issues\n    ///\n    /// This lint may suggest replacing a `Map<Range>` with a `Take<RepeatWith>`.\n    /// The former implements some traits that the latter does not, such as\n    /// `DoubleEndedIterator`.\n    #[clippy::version = \"1.84.0\"]\n    pub MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,\n    restriction,\n    \"map of a trivial closure (not dependent on parameter) over a range\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `&mut Mutex::lock` calls\n    ///\n    /// ### Why is this bad?\n    /// `Mutex::lock` is less efficient than\n    /// calling `Mutex::get_mut`. In addition you also have a statically\n    /// guarantee that the mutex isn't locked, instead of just a runtime\n    /// guarantee.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::sync::{Arc, Mutex};\n    ///\n    /// let mut value_rc = Arc::new(Mutex::new(42_u8));\n    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();\n    ///\n    /// let mut value = value_mutex.lock().unwrap();\n    /// *value += 1;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::sync::{Arc, Mutex};\n    ///\n    /// let mut value_rc = Arc::new(Mutex::new(42_u8));\n    /// let value_mutex = Arc::get_mut(&mut value_rc).unwrap();\n    ///\n    /// let value = value_mutex.get_mut().unwrap();\n    /// *value += 1;\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub MUT_MUTEX_LOCK,\n    style,\n    \"`&mut Mutex::lock` does unnecessary locking\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for naive byte counts\n    ///\n    /// ### Why is this bad?\n    /// The [`bytecount`](https://crates.io/crates/bytecount)\n    /// crate has methods to count your bytes faster, especially for large slices.\n    ///\n    /// ### Known problems\n    /// If you have predominantly small slices, the\n    /// `bytecount::count(..)` method may actually be slower. However, if you can\n    /// ensure that less than 2³²-1 matches arise, the `naive_count_32(..)` can be\n    /// faster in those cases.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let vec = vec![1_u8];\n    /// let count = vec.iter().filter(|x| **x == 0u8).count();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// # let vec = vec![1_u8];\n    /// let count = bytecount::count(&vec, 0u8);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NAIVE_BYTECOUNT,\n    pedantic,\n    \"use of naive `<slice>.filter(|&x| x == y).count()` to count byte values\"\n}\n\ndeclare_clippy_lint! {\n   /// ### What it does\n   /// It detects useless calls to `str::as_bytes()` before calling `len()` or `is_empty()`.\n   ///\n   /// ### Why is this bad?\n   /// The `len()` and `is_empty()` methods are also directly available on strings, and they\n   /// return identical results. In particular, `len()` on a string returns the number of\n   /// bytes.\n   ///\n   /// ### Example\n   /// ```\n   /// let len = \"some string\".as_bytes().len();\n   /// let b = \"some string\".as_bytes().is_empty();\n   /// ```\n   /// Use instead:\n   /// ```\n   /// let len = \"some string\".len();\n   /// let b = \"some string\".is_empty();\n   /// ```\n   #[clippy::version = \"1.84.0\"]\n   pub NEEDLESS_AS_BYTES,\n   complexity,\n   \"detect useless calls to `as_bytes()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if an iterator is used to check if a string is ascii.\n    ///\n    /// ### Why is this bad?\n    /// The `str` type already implements the `is_ascii` method.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// \"foo\".chars().all(|c| c.is_ascii());\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// \"foo\".is_ascii();\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub NEEDLESS_CHARACTER_ITERATION,\n    suspicious,\n    \"is_ascii() called on a char iterator\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions collecting an iterator when collect\n    /// is not needed.\n    ///\n    /// ### Why is this bad?\n    /// `collect` causes the allocation of a new data structure,\n    /// when this allocation may not be needed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let iterator = vec![1].into_iter();\n    /// let len = iterator.collect::<Vec<_>>().len();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let iterator = vec![1].into_iter();\n    /// let len = iterator.count();\n    /// ```\n    #[clippy::version = \"1.30.0\"]\n    pub NEEDLESS_COLLECT,\n    nursery,\n    \"collecting an iterator when collect is not needed\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for no-op uses of `Option::{as_deref, as_deref_mut}`,\n    /// for example, `Option<&T>::as_deref()` returns the same type.\n    ///\n    /// ### Why is this bad?\n    /// Redundant code and improving readability.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = Some(&1);\n    /// let b = a.as_deref(); // goes from Option<&i32> to Option<&i32>\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let a = Some(&1);\n    /// let b = a;\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub NEEDLESS_OPTION_AS_DEREF,\n    complexity,\n    \"no-op use of `deref` or `deref_mut` method to `Option`.\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calling `take` function after `as_ref`.\n    ///\n    /// ### Why is this bad?\n    /// Redundant code. `take` writes `None` to its argument.\n    /// In this case the modification is useless as it's a temporary that cannot be read from afterwards.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = Some(3);\n    /// x.as_ref().take();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = Some(3);\n    /// x.as_ref();\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub NEEDLESS_OPTION_TAKE,\n    complexity,\n    \"using `.as_ref().take()` on a temporary value\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `str::splitn` (or `str::rsplitn`) where using `str::split` would be the same.\n    /// ### Why is this bad?\n    /// The function `split` is simpler and there is no performance difference in these cases, considering\n    /// that both functions return a lazy iterator.\n    /// ### Example\n    /// ```no_run\n    /// let str = \"key=value=add\";\n    /// let _ = str.splitn(3, '=').next().unwrap();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let str = \"key=value=add\";\n    /// let _ = str.split('=').next().unwrap();\n    /// ```\n    #[clippy::version = \"1.59.0\"]\n    pub NEEDLESS_SPLITN,\n    complexity,\n    \"usages of `str::splitn` that can be replaced with `str::split`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `new` not returning a type that contains `Self`.\n    ///\n    /// ### Why is this bad?\n    /// As a convention, `new` methods are used to make a new\n    /// instance of a type.\n    ///\n    /// ### Example\n    /// In an impl block:\n    /// ```no_run\n    /// # struct Foo;\n    /// # struct NotAFoo;\n    /// impl Foo {\n    ///     fn new() -> NotAFoo {\n    /// # NotAFoo\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// ```no_run\n    /// # struct Foo;\n    /// struct Bar(Foo);\n    /// impl Foo {\n    ///     // Bad. The type name must contain `Self`\n    ///     fn new() -> Bar {\n    /// # Bar(Foo)\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// ```no_run\n    /// # struct Foo;\n    /// # struct FooError;\n    /// impl Foo {\n    ///     // Good. Return type contains `Self`\n    ///     fn new() -> Result<Foo, FooError> {\n    /// # Ok(Foo)\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Or in a trait definition:\n    /// ```no_run\n    /// pub trait Trait {\n    ///     // Bad. The type name must contain `Self`\n    ///     fn new();\n    /// }\n    /// ```\n    ///\n    /// ```no_run\n    /// pub trait Trait {\n    ///     // Good. Return type contains `Self`\n    ///     fn new() -> Self;\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEW_RET_NO_SELF,\n    style,\n    \"not returning type containing `Self` in a `new` method\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `replace` statements which have no effect.\n    ///\n    /// ### Why is this bad?\n    /// It's either a mistake or confusing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// \"1234\".replace(\"12\", \"12\");\n    /// \"1234\".replacen(\"12\", \"12\", 1);\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub NO_EFFECT_REPLACE,\n    suspicious,\n    \"replace with no effect\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for duplicate open options as well as combinations\n    /// that make no sense.\n    ///\n    /// ### Why is this bad?\n    /// In the best case, the code will be harder to read than\n    /// necessary. I don't know the worst case.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::fs::OpenOptions;\n    ///\n    /// OpenOptions::new().read(true).truncate(true);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NONSENSICAL_OPEN_OPTIONS,\n    correctness,\n    \"nonsensical combination of options for opening a file\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary method chains that can be simplified into `if .. else ..`.\n    ///\n    /// ### Why is this bad?\n    /// This can be written more clearly with `if .. else ..`\n    ///\n    /// ### Limitations\n    /// This lint currently only looks for usages of\n    /// `.{then, then_some}(..).{unwrap_or, unwrap_or_else, unwrap_or_default}(..)`, but will be expanded\n    /// to account for similar patterns.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = true;\n    /// x.then_some(\"a\").unwrap_or(\"b\");\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = true;\n    /// if x { \"a\" } else { \"b\" };\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub OBFUSCATED_IF_ELSE,\n    style,\n    \"use of `.then_some(..).unwrap_or(..)` can be written \\\n    more clearly with `if .. else ..`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `ok().expect(..)`.\n    ///\n    /// Note: This lint only triggers for code marked compatible\n    /// with versions of the compiler older than Rust 1.82.0.\n    ///\n    /// ### Why is this bad?\n    /// Because you usually call `expect()` on the `Result`\n    /// directly to get a better error message.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = Ok::<_, ()>(());\n    /// x.ok().expect(\"why did I do this again?\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = Ok::<_, ()>(());\n    /// x.expect(\"why did I do this again?\");\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub OK_EXPECT,\n    style,\n    \"using `ok().expect()`, which gives worse error messages than calling `expect` directly on the Result\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.as_ref().cloned()` and `.as_mut().cloned()` on `Option`s\n    ///\n    /// ### Why is this bad?\n    /// This can be written more concisely by cloning the `Option` directly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(bar: &Option<Vec<u8>>) -> Option<Vec<u8>> {\n    ///     bar.as_ref().cloned()\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo(bar: &Option<Vec<u8>>) -> Option<Vec<u8>> {\n    ///     bar.clone()\n    /// }\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub OPTION_AS_REF_CLONED,\n    pedantic,\n    \"cloning an `Option` via `as_ref().cloned()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.as_ref().map(Deref::deref)` or its aliases (such as String::as_str).\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.as_deref()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let opt = Some(\"\".to_string());\n    /// opt.as_ref().map(String::as_str)\n    /// # ;\n    /// ```\n    /// Can be written as\n    /// ```no_run\n    /// # let opt = Some(\"\".to_string());\n    /// opt.as_deref()\n    /// # ;\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub OPTION_AS_REF_DEREF,\n    complexity,\n    \"using `as_ref().map(Deref::deref)`, which is more succinctly expressed as `as_deref()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for iterators of `Option`s using `.filter(Option::is_some).map(Option::unwrap)` that may\n    /// be replaced with a `.flatten()` call.\n    ///\n    /// ### Why is this bad?\n    /// `Option` is like a collection of 0-1 things, so `flatten`\n    /// automatically does this without suspicious-looking `unwrap` calls.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = std::iter::empty::<Option<i32>>().filter(Option::is_some).map(Option::unwrap);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let _ = std::iter::empty::<Option<i32>>().flatten();\n    /// ```\n    #[clippy::version = \"1.53.0\"]\n    pub OPTION_FILTER_MAP,\n    complexity,\n    \"filtering `Option` for `Some` then force-unwrapping, which can be one type-safe operation\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.map_or(None, _)`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.and_then(_)`.\n    ///\n    /// ### Known problems\n    /// The order of the arguments is not in execution order.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let opt = Some(1);\n    /// opt.map_or(None, |a| Some(a + 1));\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let opt = Some(1);\n    /// opt.and_then(|a| Some(a + 1));\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub OPTION_MAP_OR_NONE,\n    style,\n    \"using `Option.map_or(None, f)`, which is more succinctly expressed as `and_then(f)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,\n    /// `.or_insert(foo(..))` etc., and suggests to use `.or_else(|| foo(..))`,\n    /// `.unwrap_or_else(|| foo(..))`, `.unwrap_or_default()` or `.or_default()`\n    /// etc. instead.\n    ///\n    /// ### Why is this bad?\n    /// The function will always be called. This is only bad if it allocates or\n    /// does some non-trivial amount of work.\n    ///\n    /// ### Known problems\n    /// If the function has side-effects, not calling it will change the\n    /// semantic of the program, but you shouldn't rely on that.\n    ///\n    /// The lint also cannot figure out whether the function you call is\n    /// actually expensive to call or not.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let foo = Some(String::new());\n    /// foo.unwrap_or(String::from(\"empty\"));\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let foo = Some(String::new());\n    /// foo.unwrap_or_else(|| String::from(\"empty\"));\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub OR_FUN_CALL,\n    nursery,\n    \"using any `*or` method with a function call, which suggests `*or_else`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `.or(…).unwrap()` calls to Options and Results.\n    ///\n    /// ### Why is this bad?\n    /// You should use `.unwrap_or(…)` instead for clarity.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let fallback = \"fallback\";\n    /// // Result\n    /// # type Error = &'static str;\n    /// # let result: Result<&str, Error> = Err(\"error\");\n    /// let value = result.or::<Error>(Ok(fallback)).unwrap();\n    ///\n    /// // Option\n    /// # let option: Option<&str> = None;\n    /// let value = option.or(Some(fallback)).unwrap();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let fallback = \"fallback\";\n    /// // Result\n    /// # let result: Result<&str, &str> = Err(\"error\");\n    /// let value = result.unwrap_or(fallback);\n    ///\n    /// // Option\n    /// # let option: Option<&str> = None;\n    /// let value = option.unwrap_or(fallback);\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub OR_THEN_UNWRAP,\n    complexity,\n    \"checks for `.or(…).unwrap()` calls to Options and Results.\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)\n    /// calls on `PathBuf` that can cause overwrites.\n    ///\n    /// ### Why is this bad?\n    /// Calling `push` with a root path at the start can overwrite the\n    /// previous defined path.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::path::PathBuf;\n    ///\n    /// let mut x = PathBuf::from(\"/foo\");\n    /// x.push(\"/bar\");\n    /// assert_eq!(x, PathBuf::from(\"/bar\"));\n    /// ```\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// use std::path::PathBuf;\n    ///\n    /// let mut x = PathBuf::from(\"/foo\");\n    /// x.push(\"bar\");\n    /// assert_eq!(x, PathBuf::from(\"/foo/bar\"));\n    /// ```\n    #[clippy::version = \"1.36.0\"]\n    pub PATH_BUF_PUSH_OVERWRITE,\n    nursery,\n    \"calling `push` with file system root on `PathBuf` can overwrite it\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for calls to `Path::ends_with` calls where the argument looks like a file extension.\n    ///\n    /// By default, Clippy has a short list of known filenames that start with a dot\n    /// but aren't necessarily file extensions (e.g. the `.git` folder), which are allowed by default.\n    /// The `allowed-dotfiles` configuration can be used to allow additional\n    /// file extensions that Clippy should not lint.\n    ///\n    /// ### Why is this bad?\n    /// This doesn't actually compare file extensions. Rather, `ends_with` compares the given argument\n    /// to the last **component** of the path and checks if it matches exactly.\n    ///\n    /// ### Known issues\n    /// File extensions are often at most three characters long, so this only lints in those cases\n    /// in an attempt to avoid false positives.\n    /// Any extension names longer than that are assumed to likely be real path components and are\n    /// therefore ignored.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::path::Path;\n    /// fn is_markdown(path: &Path) -> bool {\n    ///     path.ends_with(\".md\")\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::path::Path;\n    /// fn is_markdown(path: &Path) -> bool {\n    ///     path.extension().is_some_and(|ext| ext == \"md\")\n    /// }\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub PATH_ENDS_WITH_EXT,\n    suspicious,\n    \"attempting to compare file extensions using `Path::ends_with`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of the `offset` pointer method with an integer\n    /// literal.\n    ///\n    /// ### Why is this bad?\n    /// The `add` and `sub` methods more accurately express the intent.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let vec = vec![b'a', b'b', b'c'];\n    /// let ptr = vec.as_ptr();\n    ///\n    /// unsafe {\n    ///     ptr.offset(-8);\n    /// }\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// let vec = vec![b'a', b'b', b'c'];\n    /// let ptr = vec.as_ptr();\n    ///\n    /// unsafe {\n    ///     ptr.sub(8);\n    /// }\n    /// ```\n    #[clippy::version = \"1.94.0\"]\n    pub PTR_OFFSET_BY_LITERAL,\n    pedantic,\n    \"unneeded pointer offset\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of the `offset` pointer method with a `usize` casted to an\n    /// `isize`.\n    ///\n    /// ### Why is this bad?\n    /// If we’re always increasing the pointer address, we can avoid the numeric\n    /// cast by using the `add` method instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let vec = vec![b'a', b'b', b'c'];\n    /// let ptr = vec.as_ptr();\n    /// let offset = 1_usize;\n    ///\n    /// unsafe {\n    ///     ptr.offset(offset as isize);\n    /// }\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// let vec = vec![b'a', b'b', b'c'];\n    /// let ptr = vec.as_ptr();\n    /// let offset = 1_usize;\n    ///\n    /// unsafe {\n    ///     ptr.add(offset);\n    /// }\n    /// ```\n    #[clippy::version = \"1.30.0\"]\n    pub PTR_OFFSET_WITH_CAST,\n    complexity,\n    \"unneeded pointer offset cast\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for zipping a collection with the range of\n    /// `0.._.len()`.\n    ///\n    /// ### Why is this bad?\n    /// The code is better expressed with `.enumerate()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = vec![1];\n    /// let _ = x.iter().zip(0..x.len());\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = vec![1];\n    /// let _ = x.iter().enumerate();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub RANGE_ZIP_WITH_LEN,\n    complexity,\n    \"zipping iterator with a range when `enumerate()` would do\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for calls to [`Stdin::read_line`] to read a line from the standard input\n    /// into a string, then later attempting to use that string for an operation that will never\n    /// work for strings with a trailing newline character in it (e.g. parsing into a `i32`).\n    ///\n    /// ### Why is this bad?\n    /// The operation will always fail at runtime no matter what the user enters, thus\n    /// making it a useless operation.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let mut input = String::new();\n    /// std::io::stdin().read_line(&mut input).expect(\"Failed to read a line\");\n    /// let num: i32 = input.parse().expect(\"Not a number!\");\n    /// assert_eq!(num, 42); // we never even get here!\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// let mut input = String::new();\n    /// std::io::stdin().read_line(&mut input).expect(\"Failed to read a line\");\n    /// let num: i32 = input.trim_end().parse().expect(\"Not a number!\");\n    /// //                  ^^^^^^^^^^^ remove the trailing newline\n    /// assert_eq!(num, 42);\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub READ_LINE_WITHOUT_TRIM,\n    correctness,\n    \"calling `Stdin::read_line`, then trying to parse it without first trimming\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for calls to `RwLock::write` where the lock is only used for reading.\n    ///\n    /// ### Why is this bad?\n    /// The write portion of `RwLock` is exclusive, meaning that no other thread\n    /// can access the lock while this writer is active.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::sync::RwLock;\n    /// fn assert_is_zero(lock: &RwLock<i32>) {\n    ///     let num = lock.write().unwrap();\n    ///     assert_eq!(*num, 0);\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// use std::sync::RwLock;\n    /// fn assert_is_zero(lock: &RwLock<i32>) {\n    ///     let num = lock.read().unwrap();\n    ///     assert_eq!(*num, 0);\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub READONLY_WRITE_LOCK,\n    perf,\n    \"acquiring a write lock when a read lock would work\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `as_str()` on a `String` chained with a method available on the `String` itself.\n    ///\n    /// ### Why is this bad?\n    /// The `as_str()` conversion is pointless and can be removed for simplicity and cleanliness.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let owned_string = \"This is a string\".to_owned();\n    /// owned_string.as_str().as_bytes()\n    /// # ;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let owned_string = \"This is a string\".to_owned();\n    /// owned_string.as_bytes()\n    /// # ;\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub REDUNDANT_AS_STR,\n    complexity,\n    \"`as_str` used to call a method on `str` that is also available on `String`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `Iterator::cloned` where the original value could be used\n    /// instead.\n    ///\n    /// ### Why is this bad?\n    /// It is not always possible for the compiler to eliminate useless allocations and\n    /// deallocations generated by redundant `clone()`s.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = vec![String::new()];\n    /// let _ = x.iter().cloned().map(|x| x.len());\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = vec![String::new()];\n    /// let _ = x.iter().map(|x| x.len());\n    /// ```\n    #[clippy::version = \"1.92.0\"]\n    pub REDUNDANT_ITER_CLONED,\n    perf,\n    \"detects redundant calls to `Iterator::cloned`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.repeat(1)` and suggest the following method for each types.\n    /// - `.to_string()` for `str`\n    /// - `.clone()` for `String`\n    /// - `.to_vec()` for `slice`\n    ///\n    /// The lint will evaluate constant expressions and values as arguments of `.repeat(..)` and emit a message if\n    /// they are equivalent to `1`. (Related discussion in [rust-clippy#7306](https://github.com/rust-lang/rust-clippy/issues/7306))\n    ///\n    /// ### Why is this bad?\n    /// For example, `String.repeat(1)` is equivalent to `.clone()`. If cloning\n    /// the string is the intention behind this, `clone()` should be used.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn main() {\n    ///     let x = String::from(\"hello world\").repeat(1);\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn main() {\n    ///     let x = String::from(\"hello world\").clone();\n    /// }\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub REPEAT_ONCE,\n    complexity,\n    \"using `.repeat(1)` instead of `String.clone()`, `str.to_string()` or `slice.to_vec()` \"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for iterators of `Result`s using `.filter(Result::is_ok).map(Result::unwrap)` that may\n    /// be replaced with a `.flatten()` call.\n    ///\n    /// ### Why is this bad?\n    /// `Result` implements `IntoIterator<Item = T>`. This means that `Result` can be flattened\n    /// automatically without suspicious-looking `unwrap` calls.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = std::iter::empty::<Result<i32, ()>>().filter(Result::is_ok).map(Result::unwrap);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let _ = std::iter::empty::<Result<i32, ()>>().flatten();\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub RESULT_FILTER_MAP,\n    complexity,\n    \"filtering `Result` for `Ok` then force-unwrapping, which can be one type-safe operation\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.map_or(None, Some)`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.ok()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let r: Result<u32, &str> = Ok(1);\n    /// assert_eq!(Some(1), r.map_or(None, Some));\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let r: Result<u32, &str> = Ok(1);\n    /// assert_eq!(Some(1), r.ok());\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub RESULT_MAP_OR_INTO_OPTION,\n    style,\n    \"using `Result.map_or(None, Some)`, which is more succinctly expressed as `ok()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detect functions that end with `Option::and_then` or `Result::and_then`, and suggest using\n    /// the `?` operator instead.\n    ///\n    /// ### Why is this bad?\n    /// The `and_then` method is used to chain a computation that returns an `Option` or a `Result`.\n    /// This can be replaced with the `?` operator, which is more concise and idiomatic.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// fn test(opt: Option<i32>) -> Option<i32> {\n    ///     opt.and_then(|n| {\n    ///         if n > 1 {\n    ///             Some(n + 1)\n    ///         } else {\n    ///             None\n    ///        }\n    ///     })\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn test(opt: Option<i32>) -> Option<i32> {\n    ///     let n = opt?;\n    ///     if n > 1 {\n    ///         Some(n + 1)\n    ///     } else {\n    ///         None\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub RETURN_AND_THEN,\n    restriction,\n    \"using `Option::and_then` or `Result::and_then` to chain a computation that returns an `Option` or a `Result`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for an iterator or string search (such as `find()`,\n    /// `position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as:\n    /// * `_.any(_)`, or `_.contains(_)` for `is_some()`,\n    /// * `!_.any(_)`, or `!_.contains(_)` for `is_none()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let vec = vec![1];\n    /// vec.iter().find(|x| **x == 0).is_some();\n    ///\n    /// \"hello world\".find(\"world\").is_none();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let vec = vec![1];\n    /// vec.iter().any(|x| *x == 0);\n    ///\n    /// !\"hello world\".contains(\"world\");\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SEARCH_IS_SOME,\n    nursery,\n    \"using an iterator or string search followed by `is_some()` or `is_none()`, which is more succinctly expressed as a call to `any()` or `contains()` (with negation in case of `is_none()`)\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks if the `seek` method of the `Seek` trait is called with `SeekFrom::Current(0)`,\n    /// and if it is, suggests using `stream_position` instead.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Readability. Use dedicated method.\n    ///\n    /// ### Example\n    ///\n    /// ```rust,no_run\n    /// use std::fs::File;\n    /// use std::io::{self, Write, Seek, SeekFrom};\n    ///\n    /// fn main() -> io::Result<()> {\n    ///     let mut f = File::create(\"foo.txt\")?;\n    ///     f.write_all(b\"Hello\")?;\n    ///     eprintln!(\"Written {} bytes\", f.seek(SeekFrom::Current(0))?);\n    ///\n    ///     Ok(())\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,no_run\n    /// use std::fs::File;\n    /// use std::io::{self, Write, Seek, SeekFrom};\n    ///\n    /// fn main() -> io::Result<()> {\n    ///     let mut f = File::create(\"foo.txt\")?;\n    ///     f.write_all(b\"Hello\")?;\n    ///     eprintln!(\"Written {} bytes\", f.stream_position()?);\n    ///\n    ///     Ok(())\n    /// }\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub SEEK_FROM_CURRENT,\n    complexity,\n    \"use dedicated method for seek from current position\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for jumps to the start of a stream that implements `Seek`\n    /// and uses the `seek` method providing `Start` as parameter.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Readability. There is a specific method that was implemented for\n    /// this exact scenario.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::io;\n    /// fn foo<T: io::Seek>(t: &mut T) {\n    ///     t.seek(io::SeekFrom::Start(0));\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::io;\n    /// fn foo<T: io::Seek>(t: &mut T) {\n    ///     t.rewind();\n    /// }\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub SEEK_TO_START_INSTEAD_OF_REWIND,\n    complexity,\n    \"jumping to the start of stream using `seek` method\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for methods that should live in a trait\n    /// implementation of a `std` trait (see [llogiq's blog\n    /// post](http://llogiq.github.io/2015/07/30/traits.html) for further\n    /// information) instead of an inherent implementation.\n    ///\n    /// ### Why is this bad?\n    /// Implementing the traits improve ergonomics for users of\n    /// the code, often with very little cost. Also people seeing a `mul(...)`\n    /// method\n    /// may expect `*` to work equally, so you should have good reason to disappoint\n    /// them.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct X;\n    /// impl X {\n    ///     fn add(&self, other: &X) -> X {\n    ///         // ..\n    /// # X\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SHOULD_IMPLEMENT_TRAIT,\n    style,\n    \"defining a method that should be implementing a std trait\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns when using `push_str`/`insert_str` with a single-character string literal\n    /// where `push`/`insert` with a `char` would work fine.\n    ///\n    /// ### Why is this bad?\n    /// It's less clear that we are pushing a single character.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let mut string = String::new();\n    /// string.insert_str(0, \"R\");\n    /// string.push_str(\"R\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let mut string = String::new();\n    /// string.insert(0, 'R');\n    /// string.push('R');\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub SINGLE_CHAR_ADD_STR,\n    style,\n    \"`push_str()` or `insert_str()` used with a single-character string literal as parameter\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `_.skip_while(condition).next()`.\n    ///\n    /// ### Why is this bad?\n    /// Readability, this can be written more concisely as\n    /// `_.find(!condition)`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let vec = vec![1];\n    /// vec.iter().skip_while(|x| **x == 0).next();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let vec = vec![1];\n    /// vec.iter().find(|x| **x != 0);\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub SKIP_WHILE_NEXT,\n    complexity,\n    \"using `skip_while(p).next()`, which is more succinctly expressed as `.find(!p)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for string slices immediately followed by `as_bytes`.\n    ///\n    /// ### Why is this bad?\n    /// It involves doing an unnecessary UTF-8 alignment check which is less efficient, and can cause a panic.\n    ///\n    /// ### Known problems\n    /// In some cases, the UTF-8 validation and potential panic from string slicing may be required for\n    /// the code's correctness. If you need to ensure the slice boundaries fall on valid UTF-8 character\n    /// boundaries, the original form (`s[1..5].as_bytes()`) should be preferred.\n    ///\n    /// ### Example\n    /// ```rust\n    /// let s = \"Lorem ipsum\";\n    /// s[1..5].as_bytes();\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// let s = \"Lorem ipsum\";\n    /// &s.as_bytes()[1..5];\n    /// ```\n     #[clippy::version = \"1.86.0\"]\n     pub SLICED_STRING_AS_BYTES,\n     perf,\n     \"slicing a string and immediately calling as_bytes is less efficient and can lead to panics\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// When sorting primitive values (integers, bools, chars, as well\n    /// as arrays, slices, and tuples of such items), it is typically better to\n    /// use an unstable sort than a stable sort.\n    ///\n    /// ### Why is this bad?\n    /// Typically, using a stable sort consumes more memory and cpu cycles.\n    /// Because values which compare equal are identical, preserving their\n    /// relative order (the guarantee that a stable sort provides) means\n    /// nothing, while the extra costs still apply.\n    ///\n    /// ### Known problems\n    ///\n    /// As pointed out in\n    /// [issue #8241](https://github.com/rust-lang/rust-clippy/issues/8241),\n    /// a stable sort can instead be significantly faster for certain scenarios\n    /// (eg. when a sorted vector is extended with new data and resorted).\n    ///\n    /// For more information and benchmarking results, please refer to the\n    /// issue linked above.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut vec = vec![2, 1, 3];\n    /// vec.sort();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut vec = vec![2, 1, 3];\n    /// vec.sort_unstable();\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub STABLE_SORT_PRIMITIVE,\n    pedantic,\n    \"use of sort() when sort_unstable() is equivalent\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for usages of `str.trim().split(\"\\n\")` and `str.trim().split(\"\\r\\n\")`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Hard-coding the line endings makes the code less compatible. `str.lines` should be used instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// \"some\\ntext\\nwith\\nnewlines\\n\".trim().split('\\n');\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// \"some\\ntext\\nwith\\nnewlines\\n\".lines();\n    /// ```\n    ///\n    /// ### Known Problems\n    ///\n    /// This lint cannot detect if the split is intentionally restricted to a single type of newline (`\"\\n\"` or\n    /// `\"\\r\\n\"`), for example during the parsing of a specific file format in which precisely one newline type is\n    /// valid.\n    #[clippy::version = \"1.77.0\"]\n    pub STR_SPLIT_AT_NEWLINE,\n    pedantic,\n    \"splitting a trimmed string at hard-coded newlines\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of `.extend(s.chars())` where s is a\n    /// `&str` or `String`.\n    ///\n    /// ### Why is this bad?\n    /// `.push_str(s)` is clearer\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let abc = \"abc\";\n    /// let def = String::from(\"def\");\n    /// let mut s = String::new();\n    /// s.extend(abc.chars());\n    /// s.extend(def.chars());\n    /// ```\n    /// The correct use would be:\n    /// ```no_run\n    /// let abc = \"abc\";\n    /// let def = String::from(\"def\");\n    /// let mut s = String::new();\n    /// s.push_str(abc);\n    /// s.push_str(&def);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub STRING_EXTEND_CHARS,\n    style,\n    \"using `x.extend(s.chars())` where s is a `&str` or `String`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `<string_lit>.chars().any(|i| i == c)`.\n    ///\n    /// ### Why is this bad?\n    /// It's significantly slower than using a pattern instead, like\n    /// `matches!(c, '\\\\' | '.' | '+')`.\n    ///\n    /// Despite this being faster, this is not `perf` as this is pretty common, and is a rather nice\n    /// way to check if a `char` is any in a set. In any case, this `restriction` lint is available\n    /// for situations where that additional performance is absolutely necessary.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let c = 'c';\n    /// \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let c = 'c';\n    /// matches!(c, '\\\\' | '.' | '+' | '*' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub STRING_LIT_CHARS_ANY,\n    restriction,\n    \"checks for `<string_lit>.chars().any(|i| i == c)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for `Command::arg()` invocations that look like they\n    /// should be multiple arguments instead, such as `arg(\"-t ext2\")`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// `Command::arg()` does not split arguments by space. An argument like `arg(\"-t ext2\")`\n    /// will be passed as a single argument to the command,\n    /// which is likely not what was intended.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// std::process::Command::new(\"echo\").arg(\"-n hello\").spawn().unwrap();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// std::process::Command::new(\"echo\").args([\"-n\", \"hello\"]).spawn().unwrap();\n    /// ```\n    #[clippy::version = \"1.69.0\"]\n    pub SUSPICIOUS_COMMAND_ARG_SPACE,\n    suspicious,\n    \"single command line argument that looks like it should be multiple arguments\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `map` followed by a `count`.\n    ///\n    /// ### Why is this bad?\n    /// It looks suspicious. Maybe `map` was confused with `filter`.\n    /// If the `map` call is intentional, this should be rewritten\n    /// using `inspect`. Or, if you intend to drive the iterator to\n    /// completion, you can just use `for_each` instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = (0..3).map(|x| x + 2).count();\n    /// ```\n    #[clippy::version = \"1.39.0\"]\n    pub SUSPICIOUS_MAP,\n    suspicious,\n    \"suspicious usage of map\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the suspicious use of `OpenOptions::create()`\n    /// without an explicit `OpenOptions::truncate()`.\n    ///\n    /// ### Why is this bad?\n    /// `create()` alone will either create a new file or open an\n    /// existing file. If the file already exists, it will be\n    /// overwritten when written to, but the file will not be\n    /// truncated by default.\n    /// If less data is written to the file\n    /// than it already contains, the remainder of the file will\n    /// remain unchanged, and the end of the file will contain old\n    /// data.\n    /// In most cases, one should either use `create_new` to ensure\n    /// the file is created from scratch, or ensure `truncate` is\n    /// called so that the truncation behaviour is explicit. `truncate(true)`\n    /// will ensure the file is entirely overwritten with new data, whereas\n    /// `truncate(false)` will explicitly keep the default behavior.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// use std::fs::OpenOptions;\n    ///\n    /// OpenOptions::new().create(true);\n    /// ```\n    /// Use instead:\n    /// ```rust,no_run\n    /// use std::fs::OpenOptions;\n    ///\n    /// OpenOptions::new().create(true).truncate(true);\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub SUSPICIOUS_OPEN_OPTIONS,\n    suspicious,\n    \"suspicious combination of options for opening a file\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to [`splitn`]\n    /// (https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and\n    /// related functions with either zero or one splits.\n    ///\n    /// ### Why is this bad?\n    /// These calls don't actually split the value and are\n    /// likely to be intended as a different number.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let s = \"\";\n    /// for x in s.splitn(1, \":\") {\n    ///     // ..\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let s = \"\";\n    /// for x in s.splitn(2, \":\") {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"1.54.0\"]\n    pub SUSPICIOUS_SPLITN,\n    correctness,\n    \"checks for `.splitn(0, ..)` and `.splitn(1, ..)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of `_.to_owned()`, on a `Cow<'_, _>`.\n    ///\n    /// ### Why is this bad?\n    /// Calling `to_owned()` on a `Cow` creates a clone of the `Cow`\n    /// itself, without taking ownership of the `Cow` contents (i.e.\n    /// it's equivalent to calling `Cow::clone`).\n    /// The similarly named `into_owned` method, on the other hand,\n    /// clones the `Cow` contents, effectively turning any `Cow::Borrowed`\n    /// into a `Cow::Owned`.\n    ///\n    /// Given the potential ambiguity, consider replacing `to_owned`\n    /// with `clone` for better readability or, if getting a `Cow::Owned`\n    /// was the original intent, using `into_owned` instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::borrow::Cow;\n    /// let s = \"Hello world!\";\n    /// let cow = Cow::Borrowed(s);\n    ///\n    /// let data = cow.to_owned();\n    /// assert!(matches!(data, Cow::Borrowed(_)))\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::borrow::Cow;\n    /// let s = \"Hello world!\";\n    /// let cow = Cow::Borrowed(s);\n    ///\n    /// let data = cow.clone();\n    /// assert!(matches!(data, Cow::Borrowed(_)))\n    /// ```\n    /// or\n    /// ```no_run\n    /// # use std::borrow::Cow;\n    /// let s = \"Hello world!\";\n    /// let cow = Cow::Borrowed(s);\n    ///\n    /// let _data: String = cow.into_owned();\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub SUSPICIOUS_TO_OWNED,\n    suspicious,\n    \"calls to `to_owned` on a `Cow<'_, _>` might not do what they are expected\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `std::mem::swap` with temporary values.\n    ///\n    /// ### Why is this bad?\n    /// Storing a new value in place of a temporary value which will\n    /// be dropped right after the `swap` is an inefficient way of performing\n    /// an assignment. The same result can be achieved by using a regular\n    /// assignment.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// fn replace_string(s: &mut String) {\n    ///     std::mem::swap(s, &mut String::from(\"replaced\"));\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn replace_string(s: &mut String) {\n    ///     *s = String::from(\"replaced\");\n    /// }\n    /// ```\n    ///\n    /// Also, swapping two temporary values has no effect, as they will\n    /// both be dropped right after swapping them. This is likely an indication\n    /// of a bug. For example, the following code swaps the references to\n    /// the last element of the vectors, instead of swapping the elements\n    /// themselves:\n    ///\n    /// ```no_run\n    /// fn bug(v1: &mut [i32], v2: &mut [i32]) {\n    ///     // Incorrect: swapping temporary references (`&mut &mut` passed to swap)\n    ///     std::mem::swap(&mut v1.last_mut().unwrap(), &mut v2.last_mut().unwrap());\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn correct(v1: &mut [i32], v2: &mut [i32]) {\n    ///     std::mem::swap(v1.last_mut().unwrap(), v2.last_mut().unwrap());\n    /// }\n    /// ```\n    #[clippy::version = \"1.88.0\"]\n    pub SWAP_WITH_TEMPORARY,\n    complexity,\n    \"detect swap with a temporary value\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for calls to `.type_id()` on a `Box<dyn _>`.\n    ///\n    /// ### Why is this bad?\n    /// This almost certainly does not do what the user expects and can lead to subtle bugs.\n    /// Calling `.type_id()` on a `Box<dyn Trait>` returns a fixed `TypeId` of the `Box` itself,\n    /// rather than returning the `TypeId` of the underlying type behind the trait object.\n    ///\n    /// For `Box<dyn Any>` specifically (and trait objects that have `Any` as its supertrait),\n    /// this lint will provide a suggestion, which is to dereference the receiver explicitly\n    /// to go from `Box<dyn Any>` to `dyn Any`.\n    /// This makes sure that `.type_id()` resolves to a dynamic call on the trait object\n    /// and not on the box.\n    ///\n    /// If the fixed `TypeId` of the `Box` is the intended behavior, it's better to be explicit about it\n    /// and write `TypeId::of::<Box<dyn Trait>>()`:\n    /// this makes it clear that a fixed `TypeId` is returned and not the `TypeId` of the implementor.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// use std::any::{Any, TypeId};\n    ///\n    /// let any_box: Box<dyn Any> = Box::new(42_i32);\n    /// assert_eq!(any_box.type_id(), TypeId::of::<i32>()); // ⚠️ this fails!\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::any::{Any, TypeId};\n    ///\n    /// let any_box: Box<dyn Any> = Box::new(42_i32);\n    /// assert_eq!((*any_box).type_id(), TypeId::of::<i32>());\n    /// //          ^ dereference first, to call `type_id` on `dyn Any`\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub TYPE_ID_ON_BOX,\n    suspicious,\n    \"calling `.type_id()` on a boxed trait object\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `Read::bytes` on types which don't implement `BufRead`.\n    ///\n    /// ### Why is this bad?\n    /// The default implementation calls `read` for each byte, which can be very inefficient for data that's not in memory, such as `File`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::io::Read;\n    /// use std::fs::File;\n    /// let file = File::open(\"./bytes.txt\").unwrap();\n    /// file.bytes();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::io::{BufReader, Read};\n    /// use std::fs::File;\n    /// let file = BufReader::new(File::open(\"./bytes.txt\").unwrap());\n    /// file.bytes();\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub UNBUFFERED_BYTES,\n    perf,\n    \"calling .bytes() is very inefficient when data is not in memory\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `MaybeUninit::uninit().assume_init()`.\n    ///\n    /// ### Why is this bad?\n    /// For most types, this is undefined behavior.\n    ///\n    /// ### Known problems\n    /// For now, we accept empty tuples and tuples / arrays\n    /// of `MaybeUninit`. There may be other types that allow uninitialized\n    /// data, but those are not yet rigorously defined.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // Beware the UB\n    /// use std::mem::MaybeUninit;\n    ///\n    /// let _: usize = unsafe { MaybeUninit::uninit().assume_init() };\n    /// ```\n    ///\n    /// Note that the following is OK:\n    ///\n    /// ```no_run\n    /// use std::mem::MaybeUninit;\n    ///\n    /// let _: [MaybeUninit<bool>; 5] = unsafe {\n    ///     MaybeUninit::uninit().assume_init()\n    /// };\n    /// ```\n    #[clippy::version = \"1.39.0\"]\n    pub UNINIT_ASSUMED_INIT,\n    correctness,\n    \"`MaybeUninit::uninit().assume_init()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects `().hash(_)`.\n    ///\n    /// ### Why is this bad?\n    /// Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::hash::Hash;\n    /// # use std::collections::hash_map::DefaultHasher;\n    /// # enum Foo { Empty, WithValue(u8) }\n    /// # use Foo::*;\n    /// # let mut state = DefaultHasher::new();\n    /// # let my_enum = Foo::Empty;\n    /// match my_enum {\n    /// \tEmpty => ().hash(&mut state),\n    /// \tWithValue(x) => x.hash(&mut state),\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::hash::Hash;\n    /// # use std::collections::hash_map::DefaultHasher;\n    /// # enum Foo { Empty, WithValue(u8) }\n    /// # use Foo::*;\n    /// # let mut state = DefaultHasher::new();\n    /// # let my_enum = Foo::Empty;\n    /// match my_enum {\n    /// \tEmpty => 0_u8.hash(&mut state),\n    /// \tWithValue(x) => x.hash(&mut state),\n    /// }\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub UNIT_HASH,\n    correctness,\n    \"hashing a unit value, which does nothing\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `TryInto::try_into` and `TryFrom::try_from` when their infallible counterparts\n    /// could be used.\n    ///\n    /// ### Why is this bad?\n    /// In those cases, the `TryInto` and `TryFrom` trait implementation is a blanket impl that forwards\n    /// to `Into` or `From`, which always succeeds.\n    /// The returned `Result<_, Infallible>` requires error handling to get the contained value\n    /// even though the conversion can never fail.\n    ///\n    /// ### Example\n    /// ```rust\n    /// let _: Result<i64, _> = 1i32.try_into();\n    /// let _: Result<i64, _> = <_>::try_from(1i32);\n    /// ```\n    /// Use `from`/`into` instead:\n    /// ```rust\n    /// let _: i64 = 1i32.into();\n    /// let _: i64 = <_>::from(1i32);\n    /// ```\n    #[clippy::version = \"1.75.0\"]\n    pub UNNECESSARY_FALLIBLE_CONVERSIONS,\n    style,\n    \"calling the `try_from` and `try_into` trait methods when `From`/`Into` is implemented\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `filter_map` calls that could be replaced by `filter` or `map`.\n    /// More specifically it checks if the closure provided is only performing one of the\n    /// filter or map operations and suggests the appropriate option.\n    ///\n    /// ### Why is this bad?\n    /// Complexity. The intent is also clearer if only a single\n    /// operation is being performed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = (0..3).filter_map(|x| if x > 2 { Some(x) } else { None });\n    ///\n    /// // As there is no transformation of the argument this could be written as:\n    /// let _ = (0..3).filter(|&x| x > 2);\n    /// ```\n    ///\n    /// ```no_run\n    /// let _ = (0..4).filter_map(|x| Some(x + 1));\n    ///\n    /// // As there is no conditional check on the argument this could be written as:\n    /// let _ = (0..4).map(|x| x + 1);\n    /// ```\n    #[clippy::version = \"1.31.0\"]\n    pub UNNECESSARY_FILTER_MAP,\n    complexity,\n    \"using `filter_map` when a more succinct alternative exists\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `find_map` calls that could be replaced by `find` or `map`. More\n    /// specifically it checks if the closure provided is only performing one of the\n    /// find or map operations and suggests the appropriate option.\n    ///\n    /// ### Why is this bad?\n    /// Complexity. The intent is also clearer if only a single\n    /// operation is being performed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = (0..3).find_map(|x| if x > 2 { Some(x) } else { None });\n    ///\n    /// // As there is no transformation of the argument this could be written as:\n    /// let _ = (0..3).find(|&x| x > 2);\n    /// ```\n    ///\n    /// ```no_run\n    /// let _ = (0..4).find_map(|x| Some(x + 1));\n    ///\n    /// // As there is no conditional check on the argument this could be written as:\n    /// let _ = (0..4).map(|x| x + 1).next();\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub UNNECESSARY_FIND_MAP,\n    complexity,\n    \"using `find_map` when a more succinct alternative exists\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks the usage of `.first().is_some()` or `.first().is_none()` to check if a slice is\n    /// empty.\n    ///\n    /// ### Why is this bad?\n    /// Using `.is_empty()` is shorter and better communicates the intention.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let v = vec![1, 2, 3];\n    /// if v.first().is_none() {\n    ///     // The vector is empty...\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let v = vec![1, 2, 3];\n    /// if v.is_empty() {\n    ///     // The vector is empty...\n    /// }\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub UNNECESSARY_FIRST_THEN_CHECK,\n    complexity,\n    \"calling `.first().is_some()` or `.first().is_none()` instead of `.is_empty()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `fold` when a more succinct alternative exists.\n    /// Specifically, this checks for `fold`s which could be replaced by `any`, `all`,\n    /// `sum` or `product`.\n    ///\n    /// ### Why is this bad?\n    /// Readability.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// (0..3).fold(false, |acc, x| acc || x > 2);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// (0..3).any(|x| x > 2);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNNECESSARY_FOLD,\n    style,\n    \"using `fold` when a more succinct alternative exists\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks the usage of `.get().is_some()` or `.get().is_none()` on std map types.\n    ///\n    /// ### Why is this bad?\n    /// It can be done in one call with `.contains()`/`.contains_key()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::collections::HashSet;\n    /// let s: HashSet<String> = HashSet::new();\n    /// if s.get(\"a\").is_some() {\n    ///     // code\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::collections::HashSet;\n    /// let s: HashSet<String> = HashSet::new();\n    /// if s.contains(\"a\") {\n    ///     // code\n    /// }\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub UNNECESSARY_GET_THEN_CHECK,\n    suspicious,\n    \"calling `.get().is_some()` or `.get().is_none()` instead of `.contains()` or `.contains_key()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.collect::<Vec<String>>().join(\"\")` on iterators.\n    ///\n    /// ### Why is this bad?\n    /// `.collect::<String>()` is more concise and might be more performant\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let vector = vec![\"hello\",  \"world\"];\n    /// let output = vector.iter().map(|item| item.to_uppercase()).collect::<Vec<String>>().join(\"\");\n    /// println!(\"{}\", output);\n    /// ```\n    /// The correct use would be:\n    /// ```no_run\n    /// let vector = vec![\"hello\",  \"world\"];\n    /// let output = vector.iter().map(|item| item.to_uppercase()).collect::<String>();\n    /// println!(\"{}\", output);\n    /// ```\n    /// ### Known problems\n    /// While `.collect::<String>()` is sometimes more performant, there are cases where\n    /// using `.collect::<String>()` over `.collect::<Vec<String>>().join(\"\")`\n    /// will prevent loop unrolling and will result in a negative performance impact.\n    ///\n    /// Additionally, differences have been observed between aarch64 and x86_64 assembly output,\n    /// with aarch64 tending to producing faster assembly in more cases when using `.collect::<String>()`\n    #[clippy::version = \"1.61.0\"]\n    pub UNNECESSARY_JOIN,\n    pedantic,\n    \"using `.collect::<Vec<String>>().join(\\\"\\\")` on an iterator\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// As the counterpart to `or_fun_call`, this lint looks for unnecessary\n    /// lazily evaluated closures on `Option` and `Result`.\n    ///\n    /// This lint suggests changing the following functions, when eager evaluation results in\n    /// simpler code:\n    ///  - `unwrap_or_else` to `unwrap_or`\n    ///  - `and_then` to `and`\n    ///  - `or_else` to `or`\n    ///  - `get_or_insert_with` to `get_or_insert`\n    ///  - `ok_or_else` to `ok_or`\n    ///  - `then` to `then_some` (for msrv >= 1.62.0)\n    ///\n    /// ### Why is this bad?\n    /// Using eager evaluation is shorter and simpler in some cases.\n    ///\n    /// ### Known problems\n    /// It is possible, but not recommended for `Deref` and `Index` to have\n    /// side effects. Eagerly evaluating them can change the semantics of the program.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let opt: Option<u32> = None;\n    ///\n    /// opt.unwrap_or_else(|| 42);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let opt: Option<u32> = None;\n    ///\n    /// opt.unwrap_or(42);\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub UNNECESSARY_LAZY_EVALUATIONS,\n    style,\n    \"using unnecessary lazy evaluation, which can be replaced with simpler eager evaluation\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `.unwrap()` related calls on `Result`s and `Option`s that are constructed.\n    ///\n    /// ### Why is this bad?\n    /// It is better to write the value directly without the indirection.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// let val1 = Some(1).unwrap();\n    /// let val2 = Ok::<_, ()>(1).unwrap();\n    /// let val3 = Err::<(), _>(1).unwrap_err();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let val1 = 1;\n    /// let val2 = 1;\n    /// let val3 = 1;\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub UNNECESSARY_LITERAL_UNWRAP,\n    complexity,\n    \"using `unwrap()` related calls on `Result` and `Option` constructors\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Converts some constructs mapping an Enum value for equality comparison.\n    ///\n    /// ### Why is this bad?\n    /// Calls such as `opt.map_or(false, |val| val == 5)` are needlessly long and cumbersome,\n    /// and can be reduced to, for example, `opt == Some(5)` assuming `opt` implements `PartialEq`.\n    /// Also, calls such as `opt.map_or(true, |val| val == 5)` can be reduced to\n    /// `opt.is_none_or(|val| val == 5)`.\n    /// This lint offers readability and conciseness improvements.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub fn a(x: Option<i32>) -> (bool, bool) {\n    ///     (\n    ///         x.map_or(false, |n| n == 5),\n    ///         x.map_or(true, |n| n > 5),\n    ///     )\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// pub fn a(x: Option<i32>) -> (bool, bool) {\n    ///     (\n    ///         x == Some(5),\n    ///         x.is_none_or(|n| n > 5),\n    ///     )\n    /// }\n    /// ```\n    #[clippy::version = \"1.84.0\"]\n    pub UNNECESSARY_MAP_OR,\n    style,\n    \"reduce unnecessary calls to `.map_or(bool, …)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary calls to `min()` or `max()` in the following cases\n    /// - Either both side is constant\n    /// - One side is clearly larger than the other, like i32::MIN and an i32 variable\n    ///\n    /// ### Why is this bad?\n    ///\n    /// In the aforementioned cases it is not necessary to call `min()` or `max()`\n    /// to compare values, it may even cause confusion.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = 0.min(7_u32);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let _ = 0;\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub UNNECESSARY_MIN_OR_MAX,\n    complexity,\n    \"using 'min()/max()' when there is no need for it\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.map_or_else()` \"map closure\" for `Option` type.\n    ///\n    /// ### Why is this bad?\n    /// This can be written more concisely by using `unwrap_or_else()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let k = 10;\n    /// let x: Option<u32> = Some(4);\n    /// let y = x.map_or_else(|| 2 * k, |n| n);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let k = 10;\n    /// let x: Option<u32> = Some(4);\n    /// let y = x.unwrap_or_else(|| 2 * k);\n    /// ```\n    #[clippy::version = \"1.92.0\"]\n    pub UNNECESSARY_OPTION_MAP_OR_ELSE,\n    suspicious,\n    \"making no use of the \\\"map closure\\\" when calling `.map_or_else(|| 2 * k, |n| n)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.map_or_else()` \"map closure\" for `Result` type.\n    ///\n    /// ### Why is this bad?\n    /// This can be written more concisely by using `unwrap_or_else()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn handle_error(_: ()) -> u32 { 0 }\n    /// let x: Result<u32, ()> = Ok(0);\n    /// let y = x.map_or_else(|err| handle_error(err), |n| n);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # fn handle_error(_: ()) -> u32 { 0 }\n    /// let x: Result<u32, ()> = Ok(0);\n    /// let y = x.unwrap_or_else(|err| handle_error(err));\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub UNNECESSARY_RESULT_MAP_OR_ELSE,\n    suspicious,\n    \"making no use of the \\\"map closure\\\" when calling `.map_or_else(|err| handle_error(err), |n| n)`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Vec::sort_by` passing in a closure\n    /// which compares the two arguments, either directly or indirectly.\n    ///\n    /// ### Why is this bad?\n    /// It is more clear to use `Vec::sort_by_key` (or `Vec::sort` if\n    /// possible) than to use `Vec::sort_by` and a more complicated\n    /// closure.\n    ///\n    /// ### Known problems\n    /// If the suggested `Vec::sort_by_key` uses Reverse and it isn't already\n    /// imported by a use statement, then it will need to be added manually.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct A;\n    /// # impl A { fn foo(&self) {} }\n    /// # let mut vec: Vec<A> = Vec::new();\n    /// vec.sort_by(|a, b| a.foo().cmp(&b.foo()));\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # struct A;\n    /// # impl A { fn foo(&self) {} }\n    /// # let mut vec: Vec<A> = Vec::new();\n    /// vec.sort_by_key(|a| a.foo());\n    /// ```\n    #[clippy::version = \"1.46.0\"]\n    pub UNNECESSARY_SORT_BY,\n    complexity,\n    \"Use of `Vec::sort_by` when `Vec::sort_by_key` or `Vec::sort` would be clearer\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary calls to [`ToOwned::to_owned`](https://doc.rust-lang.org/std/borrow/trait.ToOwned.html#tymethod.to_owned)\n    /// and other `to_owned`-like functions.\n    ///\n    /// ### Why is this bad?\n    /// The unnecessary calls result in useless allocations.\n    ///\n    /// ### Known problems\n    /// `unnecessary_to_owned` can falsely trigger if `IntoIterator::into_iter` is applied to an\n    /// owned copy of a resource and the resource is later used mutably. See\n    /// [#8148](https://github.com/rust-lang/rust-clippy/issues/8148).\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let path = std::path::Path::new(\"x\");\n    /// foo(&path.to_string_lossy().to_string());\n    /// fn foo(s: &str) {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let path = std::path::Path::new(\"x\");\n    /// foo(&path.to_string_lossy());\n    /// fn foo(s: &str) {}\n    /// ```\n    #[clippy::version = \"1.59.0\"]\n    pub UNNECESSARY_TO_OWNED,\n    perf,\n    \"unnecessary calls to `to_owned`-like functions\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usages of the following functions with an argument that constructs a default value\n    /// (e.g., `Default::default` or `String::new`):\n    /// - `unwrap_or`\n    /// - `unwrap_or_else`\n    /// - `or_insert`\n    /// - `or_insert_with`\n    ///\n    /// ### Why is this bad?\n    /// Readability. Using `unwrap_or_default` in place of `unwrap_or`/`unwrap_or_else`, or `or_default`\n    /// in place of `or_insert`/`or_insert_with`, is simpler and more concise.\n    ///\n    /// ### Known problems\n    /// In some cases, the argument of `unwrap_or`, etc. is needed for type inference. The lint uses a\n    /// heuristic to try to identify such cases. However, the heuristic can produce false negatives.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// # let x = Some(1);\n    /// # let mut map = std::collections::HashMap::<u64, String>::new();\n    /// x.unwrap_or(Default::default());\n    /// map.entry(42).or_insert_with(String::new);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = Some(1);\n    /// # let mut map = std::collections::HashMap::<u64, String>::new();\n    /// x.unwrap_or_default();\n    /// map.entry(42).or_default();\n    /// ```\n    #[clippy::version = \"1.56.0\"]\n    pub UNWRAP_OR_DEFAULT,\n    style,\n    \"using `.unwrap_or`, etc. with an argument that constructs a default value\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `.unwrap()` or `.unwrap_err()` calls on `Result`s and `.unwrap()` call on `Option`s.\n    ///\n    /// ### Why restrict this?\n    /// It is better to handle the `None` or `Err` case,\n    /// or at least call `.expect(_)` with a more helpful message. Still, for a lot of\n    /// quick-and-dirty code, `unwrap` is a good choice, which is why this lint is\n    /// `Allow` by default.\n    ///\n    /// `result.unwrap()` will let the thread panic on `Err` values.\n    /// Normally, you want to implement more sophisticated error handling,\n    /// and propagate errors upwards with `?` operator.\n    ///\n    /// Even if you want to panic on errors, not all `Error`s implement good\n    /// messages on display. Therefore, it may be beneficial to look at the places\n    /// where they may get displayed. Activate this lint to do just that.\n    ///\n    /// ### Examples\n    /// ```no_run\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// option.unwrap();\n    /// result.unwrap();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// option.expect(\"more helpful message\");\n    /// result.expect(\"more helpful message\");\n    /// ```\n    ///\n    /// If [expect_used](#expect_used) is enabled, instead:\n    /// ```rust,ignore\n    /// # let option = Some(1);\n    /// # let result: Result<usize, ()> = Ok(1);\n    /// option?;\n    ///\n    /// // or\n    ///\n    /// result?;\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub UNWRAP_USED,\n    restriction,\n    \"using `.unwrap()` on `Result` or `Option`, which should at least get a better message using `expect()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `.as_ref()` or `.as_mut()` where the\n    /// types before and after the call are the same.\n    ///\n    /// ### Why is this bad?\n    /// The call is unnecessary.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn do_stuff(x: &[i32]) {}\n    /// let x: &[i32] = &[1, 2, 3, 4, 5];\n    /// do_stuff(x.as_ref());\n    /// ```\n    /// The correct use would be:\n    /// ```no_run\n    /// # fn do_stuff(x: &[i32]) {}\n    /// let x: &[i32] = &[1, 2, 3, 4, 5];\n    /// do_stuff(x);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USELESS_ASREF,\n    complexity,\n    \"using `as_ref` where the types before and after the call are the same\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for `NonZero*::new_unchecked()` being used in a `const` context.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Using `NonZero*::new_unchecked()` is an `unsafe` function and requires an `unsafe` context. When used in a\n    /// context evaluated at compilation time, `NonZero*::new().unwrap()` will provide the same result with identical\n    /// runtime performances while not requiring `unsafe`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::num::NonZeroUsize;\n    /// const PLAYERS: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::num::NonZeroUsize;\n    /// const PLAYERS: NonZeroUsize = NonZeroUsize::new(3).unwrap();\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub USELESS_NONZERO_NEW_UNCHECKED,\n    complexity,\n    \"using `NonZero::new_unchecked()` in a `const` context\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds occurrences of `Vec::resize(0, an_int)`\n    ///\n    /// ### Why is this bad?\n    /// This is probably an argument inversion mistake.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// vec![1, 2, 3, 4, 5].resize(0, 5)\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// vec![1, 2, 3, 4, 5].clear()\n    /// ```\n    #[clippy::version = \"1.46.0\"]\n    pub VEC_RESIZE_TO_ZERO,\n    correctness,\n    \"emptying a vector with `resize(0, an_int)` instead of `clear()` is probably an argument inversion mistake\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of File::read_to_end and File::read_to_string.\n    ///\n    /// ### Why restrict this?\n    /// `fs::{read, read_to_string}` provide the same functionality when `buf` is empty with fewer imports and no intermediate values.\n    /// See also: [fs::read docs](https://doc.rust-lang.org/std/fs/fn.read.html), [fs::read_to_string docs](https://doc.rust-lang.org/std/fs/fn.read_to_string.html)\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// # use std::io::Read;\n    /// # use std::fs::File;\n    /// let mut f = File::open(\"foo.txt\").unwrap();\n    /// let mut bytes = Vec::new();\n    /// f.read_to_end(&mut bytes).unwrap();\n    /// ```\n    /// Can be written more concisely as\n    /// ```rust,no_run\n    /// # use std::fs;\n    /// let mut bytes = fs::read(\"foo.txt\").unwrap();\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub VERBOSE_FILE_READS,\n    restriction,\n    \"use of `File::read_to_end` or `File::read_to_string`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `waker.clone().wake()`\n    ///\n    /// ### Why is this bad?\n    /// Cloning the waker is not necessary, `wake_by_ref()` enables the same operation\n    /// without extra cloning/dropping.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// waker.clone().wake();\n    /// ```\n    /// Should be written\n    /// ```rust,ignore\n    /// waker.wake_by_ref();\n    /// ```\n    #[clippy::version = \"1.75.0\"]\n    pub WAKER_CLONE_WAKE,\n    perf,\n    \"cloning a `Waker` only to wake it\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for methods with certain name prefixes or suffixes, and which\n    /// do not adhere to standard conventions regarding how `self` is taken.\n    /// The actual rules are:\n    ///\n    /// |Prefix |Postfix     |`self` taken                   | `self` type  |\n    /// |-------|------------|-------------------------------|--------------|\n    /// |`as_`  | none       |`&self` or `&mut self`         | any          |\n    /// |`from_`| none       | none                          | any          |\n    /// |`into_`| none       |`self`                         | any          |\n    /// |`is_`  | none       |`&mut self` or `&self` or none | any          |\n    /// |`to_`  | `_mut`     |`&mut self`                    | any          |\n    /// |`to_`  | not `_mut` |`self`                         | `Copy`       |\n    /// |`to_`  | not `_mut` |`&self`                        | not `Copy`   |\n    ///\n    /// Note: Clippy doesn't trigger methods with `to_` prefix in:\n    /// - Traits definition.\n    /// Clippy can not tell if a type that implements a trait is `Copy` or not.\n    /// - Traits implementation, when `&self` is taken.\n    /// The method signature is controlled by the trait and often `&self` is required for all types that implement the trait\n    /// (see e.g. the `std::string::ToString` trait).\n    ///\n    /// Clippy allows `Pin<&Self>` and `Pin<&mut Self>` if `&self` and `&mut self` is required.\n    ///\n    /// Please find more info here:\n    /// https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv\n    ///\n    /// ### Why is this bad?\n    /// Consistency breeds readability. If you follow the\n    /// conventions, your users won't be surprised that they, e.g., need to supply a\n    /// mutable reference to a `as_..` function.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct X;\n    /// impl X {\n    ///     fn as_str(self) -> &'static str {\n    ///         // ..\n    /// # \"\"\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # struct X;\n    /// impl X {\n    ///     fn as_str(&self) -> &'static str {\n    ///         // ..\n    /// # \"\"\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub WRONG_SELF_CONVENTION,\n    style,\n    \"defining a method named with an established prefix (like \\\"into_\\\") that takes `self` with the wrong convention\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to\n    /// zero-sized types\n    ///\n    /// ### Why is this bad?\n    /// This is a no-op, and likely unintended\n    ///\n    /// ### Example\n    /// ```no_run\n    /// unsafe { (&() as *const ()).offset(1) };\n    /// ```\n    #[clippy::version = \"1.41.0\"]\n    pub ZST_OFFSET,\n    correctness,\n    \"Check for offset calculations on raw pointers to zero-sized types\"\n}\n\nimpl_lint_pass!(Methods => [\n    BIND_INSTEAD_OF_MAP,\n    BYTES_COUNT_TO_LEN,\n    BYTES_NTH,\n    CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,\n    CHARS_LAST_CMP,\n    CHARS_NEXT_CMP,\n    CLEAR_WITH_DRAIN,\n    CLONED_INSTEAD_OF_COPIED,\n    CLONE_ON_COPY,\n    CLONE_ON_REF_PTR,\n    COLLAPSIBLE_STR_REPLACE,\n    CONST_IS_EMPTY,\n    DOUBLE_ENDED_ITERATOR_LAST,\n    DRAIN_COLLECT,\n    ERR_EXPECT,\n    EXPECT_FUN_CALL,\n    EXPECT_USED,\n    EXTEND_WITH_DRAIN,\n    FILETYPE_IS_FILE,\n    FILTER_MAP_BOOL_THEN,\n    FILTER_MAP_IDENTITY,\n    FILTER_MAP_NEXT,\n    FILTER_NEXT,\n    FLAT_MAP_IDENTITY,\n    FLAT_MAP_OPTION,\n    FORMAT_COLLECT,\n    FROM_ITER_INSTEAD_OF_COLLECT,\n    GET_FIRST,\n    GET_LAST_WITH_LEN,\n    GET_UNWRAP,\n    IMPLICIT_CLONE,\n    INEFFICIENT_TO_STRING,\n    INSPECT_FOR_EACH,\n    INTO_ITER_ON_REF,\n    IO_OTHER_ERROR,\n    IP_CONSTANT,\n    IS_DIGIT_ASCII_RADIX,\n    ITERATOR_STEP_BY_ZERO,\n    ITER_CLONED_COLLECT,\n    ITER_COUNT,\n    ITER_FILTER_IS_OK,\n    ITER_FILTER_IS_SOME,\n    ITER_KV_MAP,\n    ITER_NEXT_SLICE,\n    ITER_NTH,\n    ITER_NTH_ZERO,\n    ITER_ON_EMPTY_COLLECTIONS,\n    ITER_ON_SINGLE_ITEMS,\n    ITER_OUT_OF_BOUNDS,\n    ITER_OVEREAGER_CLONED,\n    ITER_SKIP_NEXT,\n    ITER_SKIP_ZERO,\n    ITER_WITH_DRAIN,\n    JOIN_ABSOLUTE_PATHS,\n    LINES_FILTER_MAP_OK,\n    MANUAL_CONTAINS,\n    MANUAL_C_STR_LITERALS,\n    MANUAL_FILTER_MAP,\n    MANUAL_FIND_MAP,\n    MANUAL_INSPECT,\n    MANUAL_IS_VARIANT_AND,\n    MANUAL_NEXT_BACK,\n    MANUAL_OK_OR,\n    MANUAL_REPEAT_N,\n    MANUAL_SATURATING_ARITHMETIC,\n    MANUAL_SPLIT_ONCE,\n    MANUAL_STR_REPEAT,\n    MANUAL_TRY_FOLD,\n    MAP_ALL_ANY_IDENTITY,\n    MAP_CLONE,\n    MAP_COLLECT_RESULT_UNIT,\n    MAP_ERR_IGNORE,\n    MAP_FLATTEN,\n    MAP_IDENTITY,\n    MAP_UNWRAP_OR,\n    MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,\n    MUT_MUTEX_LOCK,\n    NAIVE_BYTECOUNT,\n    NEEDLESS_AS_BYTES,\n    NEEDLESS_CHARACTER_ITERATION,\n    NEEDLESS_COLLECT,\n    NEEDLESS_OPTION_AS_DEREF,\n    NEEDLESS_OPTION_TAKE,\n    NEEDLESS_SPLITN,\n    NEW_RET_NO_SELF,\n    NONSENSICAL_OPEN_OPTIONS,\n    NO_EFFECT_REPLACE,\n    OBFUSCATED_IF_ELSE,\n    OK_EXPECT,\n    OPTION_AS_REF_CLONED,\n    OPTION_AS_REF_DEREF,\n    OPTION_FILTER_MAP,\n    OPTION_MAP_OR_NONE,\n    OR_FUN_CALL,\n    OR_THEN_UNWRAP,\n    PATH_BUF_PUSH_OVERWRITE,\n    PATH_ENDS_WITH_EXT,\n    PTR_OFFSET_BY_LITERAL,\n    PTR_OFFSET_WITH_CAST,\n    RANGE_ZIP_WITH_LEN,\n    READONLY_WRITE_LOCK,\n    READ_LINE_WITHOUT_TRIM,\n    REDUNDANT_AS_STR,\n    REDUNDANT_ITER_CLONED,\n    REPEAT_ONCE,\n    RESULT_FILTER_MAP,\n    RESULT_MAP_OR_INTO_OPTION,\n    RETURN_AND_THEN,\n    SEARCH_IS_SOME,\n    SEEK_FROM_CURRENT,\n    SEEK_TO_START_INSTEAD_OF_REWIND,\n    SHOULD_IMPLEMENT_TRAIT,\n    SINGLE_CHAR_ADD_STR,\n    SKIP_WHILE_NEXT,\n    SLICED_STRING_AS_BYTES,\n    STABLE_SORT_PRIMITIVE,\n    STRING_EXTEND_CHARS,\n    STRING_LIT_CHARS_ANY,\n    STR_SPLIT_AT_NEWLINE,\n    SUSPICIOUS_COMMAND_ARG_SPACE,\n    SUSPICIOUS_MAP,\n    SUSPICIOUS_OPEN_OPTIONS,\n    SUSPICIOUS_SPLITN,\n    SUSPICIOUS_TO_OWNED,\n    SWAP_WITH_TEMPORARY,\n    TYPE_ID_ON_BOX,\n    UNBUFFERED_BYTES,\n    UNINIT_ASSUMED_INIT,\n    UNIT_HASH,\n    UNNECESSARY_FALLIBLE_CONVERSIONS,\n    UNNECESSARY_FILTER_MAP,\n    UNNECESSARY_FIND_MAP,\n    UNNECESSARY_FIRST_THEN_CHECK,\n    UNNECESSARY_FOLD,\n    UNNECESSARY_GET_THEN_CHECK,\n    UNNECESSARY_JOIN,\n    UNNECESSARY_LAZY_EVALUATIONS,\n    UNNECESSARY_LITERAL_UNWRAP,\n    UNNECESSARY_MAP_OR,\n    UNNECESSARY_MIN_OR_MAX,\n    UNNECESSARY_OPTION_MAP_OR_ELSE,\n    UNNECESSARY_RESULT_MAP_OR_ELSE,\n    UNNECESSARY_SORT_BY,\n    UNNECESSARY_TO_OWNED,\n    UNWRAP_OR_DEFAULT,\n    UNWRAP_USED,\n    USELESS_ASREF,\n    USELESS_NONZERO_NEW_UNCHECKED,\n    VEC_RESIZE_TO_ZERO,\n    VERBOSE_FILE_READS,\n    WAKER_CLONE_WAKE,\n    WRONG_SELF_CONVENTION,\n    ZST_OFFSET,\n]);\n\n#[expect(clippy::struct_excessive_bools)]\npub struct Methods {\n    avoid_breaking_exported_api: bool,\n    msrv: Msrv,\n    allow_expect_in_tests: bool,\n    allow_unwrap_in_tests: bool,\n    allow_expect_in_consts: bool,\n    allow_unwrap_in_consts: bool,\n    allowed_dotfiles: FxHashSet<&'static str>,\n    format_args: FormatArgsStorage,\n    allow_unwrap_types: Vec<String>,\n    unwrap_allowed_ids: FxHashSet<rustc_hir::def_id::DefId>,\n    unwrap_allowed_aliases: Vec<rustc_hir::def_id::DefId>,\n}\n\nimpl Methods {\n    pub fn new(conf: &'static Conf, format_args: FormatArgsStorage) -> Self {\n        let mut allowed_dotfiles: FxHashSet<_> = conf.allowed_dotfiles.iter().map(|s| &**s).collect();\n        allowed_dotfiles.extend(DEFAULT_ALLOWED_DOTFILES);\n\n        Self {\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n            msrv: conf.msrv,\n            allow_expect_in_tests: conf.allow_expect_in_tests,\n            allow_unwrap_in_tests: conf.allow_unwrap_in_tests,\n            allow_expect_in_consts: conf.allow_expect_in_consts,\n            allow_unwrap_in_consts: conf.allow_unwrap_in_consts,\n            allowed_dotfiles,\n            format_args,\n            allow_unwrap_types: conf.allow_unwrap_types.clone(),\n            unwrap_allowed_ids: FxHashSet::default(),\n            unwrap_allowed_aliases: Vec::new(),\n        }\n    }\n}\n\n/// Extracts a method call name, args, and `Span` of the method name.\n/// This ensures that neither the receiver nor any of the arguments\n/// come from expansion.\npub fn method_call<'tcx>(recv: &'tcx Expr<'tcx>) -> Option<(Symbol, &'tcx Expr<'tcx>, &'tcx [Expr<'tcx>], Span, Span)> {\n    if let ExprKind::MethodCall(path, receiver, args, call_span) = recv.kind\n        && !args.iter().any(|e| e.range_span().unwrap_or(e.span).from_expansion())\n        && !receiver.range_span().unwrap_or(receiver.span).from_expansion()\n    {\n        Some((path.ident.name, receiver, args, path.ident.span, call_span))\n    } else {\n        None\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Methods {\n    fn check_crate(&mut self, cx: &LateContext<'tcx>) {\n        for s in &self.allow_unwrap_types {\n            let def_ids = clippy_utils::paths::lookup_path_str(cx.tcx, clippy_utils::paths::PathNS::Type, s);\n            for def_id in def_ids {\n                if cx.tcx.def_kind(def_id) == rustc_hir::def::DefKind::TyAlias {\n                    self.unwrap_allowed_aliases.push(def_id);\n                } else {\n                    self.unwrap_allowed_ids.insert(def_id);\n                }\n            }\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        match expr.kind {\n            ExprKind::Call(func, args) => {\n                from_iter_instead_of_collect::check(cx, expr, args, func);\n                unnecessary_fallible_conversions::check_function(cx, expr, func);\n                manual_c_str_literals::check(cx, expr, func, args, self.msrv);\n                useless_nonzero_new_unchecked::check(cx, expr, func, args, self.msrv);\n                io_other_error::check(cx, expr, func, args, self.msrv);\n                swap_with_temporary::check(cx, expr, func, args);\n                ip_constant::check(cx, expr, func, args);\n                unwrap_expect_used::check_call(\n                    cx,\n                    expr,\n                    func,\n                    args,\n                    self.allow_unwrap_in_tests,\n                    self.allow_expect_in_tests,\n                    self.allow_unwrap_in_consts,\n                    self.allow_expect_in_consts,\n                    &self.unwrap_allowed_ids,\n                    &self.unwrap_allowed_aliases,\n                );\n            },\n            ExprKind::MethodCall(..) => {\n                self.check_methods(cx, expr);\n            },\n            ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {\n                let mut info = BinaryExprInfo {\n                    expr,\n                    chain: lhs,\n                    other: rhs,\n                    eq: op.node == hir::BinOpKind::Eq,\n                };\n                lint_binary_expr_with_method_call(cx, &mut info);\n            },\n            ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Or => {\n                manual_is_variant_and::check_or(cx, expr, lhs, rhs, self.msrv);\n            },\n            _ => (),\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {\n        if impl_item.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind {\n            let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id;\n            let item = cx.tcx.hir_expect_item(parent);\n            let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity();\n            let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }));\n\n            let method_sig = cx.tcx.fn_sig(impl_item.owner_id).instantiate_identity();\n            let method_sig = cx.tcx.instantiate_bound_regions_with_erased(method_sig);\n            let first_arg_ty_opt = method_sig.inputs().iter().next().copied();\n            should_implement_trait::check_impl_item(cx, impl_item, self_ty, implements_trait, first_arg_ty_opt, sig);\n\n            if sig.decl.implicit_self.has_implicit_self()\n                && !(self.avoid_breaking_exported_api\n                    && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id))\n                && let Some(first_arg) = iter_input_pats(sig.decl, cx.tcx.hir_body(id)).next()\n                && let Some(first_arg_ty) = first_arg_ty_opt\n            {\n                wrong_self_convention::check(\n                    cx,\n                    impl_item.ident.name,\n                    self_ty,\n                    first_arg_ty,\n                    first_arg.pat.span,\n                    implements_trait,\n                    false,\n                );\n            }\n\n            new_ret_no_self::check_impl_item(cx, impl_item, self_ty, implements_trait);\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {\n        if item.span.in_external_macro(cx.tcx.sess.source_map()) {\n            return;\n        }\n\n        if let TraitItemKind::Fn(ref sig, _) = item.kind {\n            if sig.decl.implicit_self.has_implicit_self()\n                && let Some(first_arg_hir_ty) = sig.decl.inputs.first()\n                && let Some(&first_arg_ty) = cx\n                    .tcx\n                    .fn_sig(item.owner_id)\n                    .instantiate_identity()\n                    .inputs()\n                    .skip_binder()\n                    .first()\n            {\n                let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()).self_ty();\n                wrong_self_convention::check(\n                    cx,\n                    item.ident.name,\n                    self_ty,\n                    first_arg_ty,\n                    first_arg_hir_ty.span,\n                    false,\n                    true,\n                );\n            }\n\n            new_ret_no_self::check_trait_item(cx, item);\n        }\n    }\n}\n\nimpl Methods {\n    #[expect(clippy::too_many_lines)]\n    fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        // Handle method calls whose receiver and arguments may not come from expansion\n        if let Some((name, recv, args, span, call_span)) = method_call(expr) {\n            match (name, args) {\n                (sym::add | sym::sub | sym::wrapping_add | sym::wrapping_sub, [_arg]) => {\n                    zst_offset::check(cx, expr, recv);\n                },\n                (sym::all, [arg]) => {\n                    needless_character_iteration::check(cx, expr, recv, arg, true);\n                    match method_call(recv) {\n                        Some((sym::cloned, recv2, [], _, _)) => {\n                            iter_overeager_cloned::check(\n                                cx,\n                                expr,\n                                recv,\n                                recv2,\n                                iter_overeager_cloned::Op::NeedlessMove(arg),\n                                false,\n                            );\n                        },\n                        Some((sym::map, _, [map_arg], _, map_call_span)) => {\n                            map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, \"all\");\n                        },\n                        _ => {},\n                    }\n                },\n                (sym::and_then, [arg]) => {\n                    let biom_option_linted = bind_instead_of_map::check_and_then_some(cx, expr, recv, arg);\n                    let biom_result_linted = bind_instead_of_map::check_and_then_ok(cx, expr, recv, arg);\n                    if !biom_option_linted && !biom_result_linted {\n                        let ule_and_linted = unnecessary_lazy_eval::check(cx, expr, recv, arg, \"and\");\n                        if !ule_and_linted {\n                            return_and_then::check(cx, expr, recv, arg);\n                        }\n                    }\n                },\n                (sym::any, [arg]) => {\n                    needless_character_iteration::check(cx, expr, recv, arg, false);\n                    match method_call(recv) {\n                        Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check(\n                            cx,\n                            expr,\n                            recv,\n                            recv2,\n                            iter_overeager_cloned::Op::NeedlessMove(arg),\n                            false,\n                        ),\n                        Some((sym::chars, recv, _, _, _))\n                            if let ExprKind::Closure(arg) = arg.kind\n                                && let body = cx.tcx.hir_body(arg.body)\n                                && let [param] = body.params =>\n                        {\n                            string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), self.msrv);\n                        },\n                        Some((sym::map, _, [map_arg], _, map_call_span)) => {\n                            map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, \"any\");\n                        },\n                        Some((sym::iter, iter_recv, ..)) => {\n                            manual_contains::check(cx, expr, iter_recv, arg);\n                        },\n                        _ => {},\n                    }\n                },\n                (sym::arg, [arg]) => {\n                    suspicious_command_arg_space::check(cx, recv, arg, span);\n                },\n                (sym::as_deref | sym::as_deref_mut, []) => {\n                    needless_option_as_deref::check(cx, expr, recv, name);\n                },\n                (sym::as_bytes, []) => {\n                    if let Some((sym::as_str, recv, [], as_str_span, _)) = method_call(recv) {\n                        redundant_as_str::check(cx, expr, recv, as_str_span, span);\n                    }\n                    sliced_string_as_bytes::check(cx, expr, recv);\n                },\n                (sym::as_mut | sym::as_ref, []) => useless_asref::check(cx, expr, name, recv),\n                (sym::as_ptr, []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, self.msrv),\n                (sym::assume_init, []) => uninit_assumed_init::check(cx, expr, recv),\n                (sym::bytes, []) => unbuffered_bytes::check(cx, expr, recv),\n                (sym::cloned, []) => {\n                    cloned_instead_of_copied::check(cx, expr, recv, span, self.msrv);\n                    if let Some((method @ (sym::as_ref | sym::as_mut), as_ref_recv, [], as_ref_ident_span, _)) =\n                        method_call(recv)\n                    {\n                        option_as_ref_cloned::check(cx, span, method, as_ref_recv, as_ref_ident_span);\n                    }\n                },\n                (sym::collect, []) if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) => {\n                    needless_collect::check(cx, span, expr, recv, call_span);\n                    match method_call(recv) {\n                        Some((name @ (sym::cloned | sym::copied), recv2, [], _, _)) => {\n                            iter_cloned_collect::check(cx, name, expr, recv2);\n                        },\n                        Some((sym::map, m_recv, [m_arg], m_ident_span, _)) => {\n                            map_collect_result_unit::check(cx, expr, m_recv, m_arg);\n                            format_collect::check(cx, expr, m_arg, m_ident_span);\n                        },\n                        Some((sym::take, take_self_arg, [take_arg], _, _)) => {\n                            #[expect(clippy::collapsible_match)]\n                            if self.msrv.meets(cx, msrvs::STR_REPEAT) {\n                                manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);\n                            }\n                        },\n                        Some((sym::drain, recv, args, ..)) => {\n                            drain_collect::check(cx, args, expr, recv);\n                        },\n                        _ => {},\n                    }\n                },\n                (sym::count, []) if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) => {\n                    match method_call(recv) {\n                        Some((sym::cloned, recv2, [], _, _)) => {\n                            iter_overeager_cloned::check(\n                                cx,\n                                expr,\n                                recv,\n                                recv2,\n                                iter_overeager_cloned::Op::RmCloned,\n                                false,\n                            );\n                        },\n                        Some((name2 @ (sym::into_iter | sym::iter | sym::iter_mut), recv2, [], _, _)) => {\n                            iter_count::check(cx, expr, recv2, name2);\n                        },\n                        Some((sym::map, _, [arg], _, _)) => suspicious_map::check(cx, expr, recv, arg),\n                        Some((sym::filter, recv2, [arg], _, _)) => bytecount::check(cx, expr, recv2, arg),\n                        Some((sym::bytes, recv2, [], _, _)) => bytes_count_to_len::check(cx, expr, recv, recv2),\n                        _ => {},\n                    }\n                },\n                (sym::min | sym::max, [arg]) => {\n                    unnecessary_min_or_max::check(cx, expr, name, recv, arg);\n                },\n                (sym::drain, ..) => {\n                    if let Node::Stmt(Stmt { hir_id: _, kind, .. }) = cx.tcx.parent_hir_node(expr.hir_id)\n                        && matches!(kind, StmtKind::Semi(_))\n                        && args.len() <= 1\n                    {\n                        clear_with_drain::check(cx, expr, recv, span, args.first());\n                    } else if let [arg] = args {\n                        iter_with_drain::check(cx, expr, recv, span, arg);\n                    }\n                },\n                (sym::ends_with, [arg]) => {\n                    if let ExprKind::MethodCall(.., span) = expr.kind {\n                        case_sensitive_file_extension_comparisons::check(cx, expr, span, recv, arg, self.msrv);\n                    }\n                    path_ends_with_ext::check(cx, recv, arg, expr, self.msrv, &self.allowed_dotfiles);\n                },\n                (sym::expect, [_]) => {\n                    match method_call(recv) {\n                        Some((sym::ok, recv_inner, [], _, _)) => ok_expect::check(cx, expr, recv, recv_inner),\n                        Some((sym::err, recv, [], err_span, _)) => {\n                            err_expect::check(cx, expr, recv, span, err_span, self.msrv);\n                        },\n                        _ => {},\n                    }\n                    unnecessary_literal_unwrap::check(cx, expr, recv, name, args);\n                },\n                (sym::expect_err, [_]) | (sym::unwrap_err | sym::unwrap_unchecked | sym::unwrap_err_unchecked, []) => {\n                    unnecessary_literal_unwrap::check(cx, expr, recv, name, args);\n                },\n                (sym::extend, [arg]) => {\n                    string_extend_chars::check(cx, expr, recv, arg);\n                    extend_with_drain::check(cx, expr, recv, arg);\n                },\n                (sym::filter, [arg]) => {\n                    if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) {\n                        // if `arg` has side-effect, the semantic will change\n                        iter_overeager_cloned::check(\n                            cx,\n                            expr,\n                            recv,\n                            recv2,\n                            iter_overeager_cloned::Op::FixClosure(name, arg),\n                            false,\n                        );\n                    }\n                    if self.msrv.meets(cx, msrvs::ITER_FLATTEN) {\n                        // use the sourcemap to get the span of the closure\n                        iter_filter::check(cx, expr, arg, span);\n                    }\n                },\n                (sym::find, [arg]) => {\n                    if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) {\n                        // if `arg` has side-effect, the semantic will change\n                        iter_overeager_cloned::check(\n                            cx,\n                            expr,\n                            recv,\n                            recv2,\n                            iter_overeager_cloned::Op::FixClosure(name, arg),\n                            false,\n                        );\n                    }\n                },\n                (sym::filter_map, [arg]) => {\n                    unnecessary_filter_map::check(cx, expr, arg, call_span, unnecessary_filter_map::Kind::FilterMap);\n                    filter_map_bool_then::check(cx, expr, arg, call_span);\n                    filter_map_identity::check(cx, expr, arg, span);\n                    lines_filter_map_ok::check_filter_or_flat_map(\n                        cx,\n                        expr,\n                        recv,\n                        \"filter_map\",\n                        arg,\n                        call_span,\n                        self.msrv,\n                    );\n                    if let Some((map_name @ (sym::iter | sym::into_iter), recv2, _, _, _)) = method_call(recv) {\n                        iter_kv_map::check(cx, map_name, expr, recv2, arg, self.msrv, sym::filter_map);\n                    }\n                },\n                (sym::find_map, [arg]) => {\n                    unnecessary_filter_map::check(cx, expr, arg, call_span, unnecessary_filter_map::Kind::FindMap);\n                },\n                (sym::flat_map, [arg]) => {\n                    flat_map_identity::check(cx, expr, arg, span);\n                    flat_map_option::check(cx, expr, arg, span);\n                    lines_filter_map_ok::check_filter_or_flat_map(\n                        cx, expr, recv, \"flat_map\", arg, call_span, self.msrv,\n                    );\n                    if let Some((map_name @ (sym::iter | sym::into_iter), recv2, _, _, _)) = method_call(recv) {\n                        iter_kv_map::check(cx, map_name, expr, recv2, arg, self.msrv, sym::flat_map);\n                    }\n                },\n                (sym::flatten, []) => {\n                    match method_call(recv) {\n                        Some((sym::map, recv, [map_arg], map_span, _)) => {\n                            map_flatten::check(cx, expr, recv, map_arg, map_span);\n                        },\n                        Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check(\n                            cx,\n                            expr,\n                            recv,\n                            recv2,\n                            iter_overeager_cloned::Op::LaterCloned,\n                            true,\n                        ),\n                        _ => {},\n                    }\n                    lines_filter_map_ok::check_flatten(cx, expr, recv, call_span, self.msrv);\n                },\n                (sym::fold, [init, acc]) => {\n                    manual_try_fold::check(cx, expr, init, acc, call_span, self.msrv);\n                    unnecessary_fold::check(cx, expr, init, acc, span);\n                },\n                (sym::for_each, [arg]) => match method_call(recv) {\n                    Some((sym::inspect, _, [_], span2, _)) => inspect_for_each::check(cx, expr, span2),\n                    Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check(\n                        cx,\n                        expr,\n                        recv,\n                        recv2,\n                        iter_overeager_cloned::Op::NeedlessMove(arg),\n                        false,\n                    ),\n                    _ => {},\n                },\n                (sym::get, [arg]) => {\n                    get_first::check(cx, expr, recv, arg);\n                    get_last_with_len::check(cx, expr, recv, arg);\n                },\n                (sym::get_or_insert_with, [arg]) => {\n                    unnecessary_lazy_eval::check(cx, expr, recv, arg, \"get_or_insert\");\n                },\n                (sym::hash, [arg]) => {\n                    unit_hash::check(cx, expr, recv, arg);\n                },\n                (sym::is_empty, []) => {\n                    match method_call(recv) {\n                        Some((prev_method @ (sym::as_bytes | sym::bytes), prev_recv, [], _, _)) => {\n                            needless_as_bytes::check(cx, prev_method, name, prev_recv, expr.span);\n                        },\n                        Some((sym::as_str, recv, [], as_str_span, _)) => {\n                            redundant_as_str::check(cx, expr, recv, as_str_span, span);\n                        },\n                        _ => {},\n                    }\n                    is_empty::check(cx, expr, recv);\n                },\n                (sym::is_file, []) => filetype_is_file::check(cx, expr, recv),\n                (sym::is_digit, [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv),\n                (sym::is_none, []) => check_is_some_is_none(cx, expr, recv, call_span, false, self.msrv),\n                (sym::is_some, []) => check_is_some_is_none(cx, expr, recv, call_span, true, self.msrv),\n                (sym::iter | sym::iter_mut | sym::into_iter, []) => {\n                    iter_on_single_or_empty_collections::check(cx, expr, name, recv);\n                },\n                (sym::join, [join_arg]) => {\n                    if let Some((sym::collect, _, _, span, _)) = method_call(recv) {\n                        unnecessary_join::check(cx, expr, recv, join_arg, span);\n                    } else {\n                        join_absolute_paths::check(cx, recv, join_arg, expr.span);\n                    }\n                },\n                (sym::last, []) => {\n                    if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) {\n                        iter_overeager_cloned::check(\n                            cx,\n                            expr,\n                            recv,\n                            recv2,\n                            iter_overeager_cloned::Op::LaterCloned,\n                            false,\n                        );\n                    }\n                    double_ended_iterator_last::check(cx, expr, recv, call_span);\n                },\n                (sym::len, []) => {\n                    if let Some((prev_method @ (sym::as_bytes | sym::bytes), prev_recv, [], _, _)) = method_call(recv) {\n                        needless_as_bytes::check(cx, prev_method, sym::len, prev_recv, expr.span);\n                    }\n                },\n                (sym::lock, []) => {\n                    mut_mutex_lock::check(cx, expr, recv, span);\n                },\n                (name @ (sym::map | sym::map_err), [m_arg]) => {\n                    if name == sym::map {\n                        map_clone::check(cx, expr, recv, m_arg, self.msrv);\n                        map_with_unused_argument_over_ranges::check(cx, expr, recv, m_arg, self.msrv, span);\n                        manual_is_variant_and::check_map(cx, expr);\n                        match method_call(recv) {\n                            Some((map_name @ (sym::iter | sym::into_iter), recv2, _, _, _)) => {\n                                iter_kv_map::check(cx, map_name, expr, recv2, m_arg, self.msrv, sym::map);\n                            },\n                            Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check(\n                                cx,\n                                expr,\n                                recv,\n                                recv2,\n                                iter_overeager_cloned::Op::NeedlessMove(m_arg),\n                                false,\n                            ),\n                            _ => {},\n                        }\n                    } else {\n                        map_err_ignore::check(cx, expr, m_arg);\n                    }\n                    if let Some((name, recv2, args, span2, _)) = method_call(recv) {\n                        match (name, args) {\n                            (sym::as_mut, []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv),\n                            (sym::as_ref, []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv),\n                            (sym::filter, [f_arg]) => {\n                                filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false);\n                            },\n                            (sym::find, [f_arg]) => {\n                                filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, true);\n                            },\n                            _ => {},\n                        }\n                    }\n                    map_identity::check(cx, expr, recv, m_arg, name, span);\n                    manual_inspect::check(cx, expr, m_arg, name, span, self.msrv);\n                },\n                (sym::map_or, [def, map]) => {\n                    option_map_or_none::check(cx, expr, recv, def, map);\n                    manual_ok_or::check(cx, expr, recv, def, map);\n                    unnecessary_map_or::check(cx, expr, recv, def, map, span, self.msrv);\n                },\n                (sym::map_or_else, [def, map]) => {\n                    result_map_or_else_none::check(cx, expr, recv, def, map);\n                    unnecessary_map_or_else::check(cx, expr, recv, def, map, call_span);\n                },\n                (sym::next, []) => {\n                    if let Some((name2, recv2, args2, _, _)) = method_call(recv) {\n                        match (name2, args2) {\n                            (sym::cloned, []) => iter_overeager_cloned::check(\n                                cx,\n                                expr,\n                                recv,\n                                recv2,\n                                iter_overeager_cloned::Op::LaterCloned,\n                                false,\n                            ),\n                            (sym::filter, [arg]) => {\n                                filter_next::check(cx, expr, recv2, arg, filter_next::Direction::Forward);\n                            },\n                            (sym::filter_map, [arg]) => filter_map_next::check(cx, expr, recv2, arg, self.msrv),\n                            (sym::iter, []) => iter_next_slice::check(cx, expr, recv2),\n                            (sym::skip, [arg]) => iter_skip_next::check(cx, expr, recv2, arg),\n                            (sym::skip_while, [_]) => skip_while_next::check(cx, expr),\n                            (sym::rev, []) => manual_next_back::check(cx, expr, recv, recv2),\n                            _ => {},\n                        }\n                    }\n                },\n                (sym::next_back, []) => {\n                    if let Some((name2, recv2, args2, _, _)) = method_call(recv)\n                        && let (sym::filter, [arg]) = (name2, args2)\n                        && self.msrv.meets(cx, msrvs::DOUBLE_ENDED_ITERATOR_RFIND)\n                    {\n                        filter_next::check(cx, expr, recv2, arg, filter_next::Direction::Backward);\n                    }\n                },\n                (sym::nth, [n_arg]) => match method_call(recv) {\n                    Some((sym::bytes, recv2, [], _, _)) => bytes_nth::check(cx, expr, recv2, n_arg),\n                    Some((sym::cloned, recv2, [], _, _)) => iter_overeager_cloned::check(\n                        cx,\n                        expr,\n                        recv,\n                        recv2,\n                        iter_overeager_cloned::Op::LaterCloned,\n                        false,\n                    ),\n                    Some((iter_method @ (sym::iter | sym::iter_mut), iter_recv, [], iter_span, _)) => {\n                        if !iter_nth::check(cx, expr, iter_recv, iter_method, iter_span, span) {\n                            iter_nth_zero::check(cx, expr, recv, n_arg);\n                        }\n                    },\n                    _ => iter_nth_zero::check(cx, expr, recv, n_arg),\n                },\n                (sym::offset | sym::wrapping_offset, [arg]) => {\n                    zst_offset::check(cx, expr, recv);\n\n                    ptr_offset_with_cast::check(cx, name, expr, recv, arg, self.msrv);\n                    ptr_offset_by_literal::check(cx, expr, self.msrv);\n                },\n                (sym::ok_or_else, [arg]) => {\n                    unnecessary_lazy_eval::check(cx, expr, recv, arg, \"ok_or\");\n                },\n                (sym::open, [_]) => {\n                    open_options::check(cx, expr, recv);\n                },\n                (sym::or_else, [arg]) =>\n                {\n                    #[expect(clippy::collapsible_match)]\n                    if !bind_instead_of_map::check_or_else_err(cx, expr, recv, arg) {\n                        unnecessary_lazy_eval::check(cx, expr, recv, arg, \"or\");\n                    }\n                },\n                (sym::push, [arg]) => {\n                    path_buf_push_overwrite::check(cx, expr, arg);\n                },\n                (sym::read_to_end, [_]) => {\n                    verbose_file_reads::check(cx, expr, recv, verbose_file_reads::READ_TO_END_MSG);\n                },\n                (sym::read_to_string, [_]) => {\n                    verbose_file_reads::check(cx, expr, recv, verbose_file_reads::READ_TO_STRING_MSG);\n                },\n                (sym::read_line, [arg]) => {\n                    read_line_without_trim::check(cx, expr, recv, arg);\n                },\n                (sym::repeat, [arg]) => {\n                    repeat_once::check(cx, expr, recv, arg);\n                },\n                (name @ (sym::replace | sym::replacen), [arg1, arg2] | [arg1, arg2, _]) => {\n                    no_effect_replace::check(cx, expr, arg1, arg2);\n\n                    // Check for repeated `str::replace` calls to perform `collapsible_str_replace` lint\n                    if self.msrv.meets(cx, msrvs::PATTERN_TRAIT_CHAR_ARRAY)\n                        && name == sym::replace\n                        && let Some((sym::replace, ..)) = method_call(recv)\n                    {\n                        collapsible_str_replace::check(cx, expr, arg1, arg2);\n                    }\n                },\n                (sym::resize, [count_arg, default_arg]) => {\n                    vec_resize_to_zero::check(cx, expr, count_arg, default_arg, span);\n                },\n                (sym::seek, [arg]) => {\n                    if self.msrv.meets(cx, msrvs::SEEK_FROM_CURRENT) {\n                        seek_from_current::check(cx, expr, recv, arg);\n                    }\n                    if self.msrv.meets(cx, msrvs::SEEK_REWIND) {\n                        seek_to_start_instead_of_rewind::check(cx, expr, recv, arg, span);\n                    }\n                },\n                (sym::skip, [arg]) => {\n                    iter_skip_zero::check(cx, expr, arg);\n                    iter_out_of_bounds::check_skip(cx, expr, recv, arg);\n\n                    if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) {\n                        iter_overeager_cloned::check(\n                            cx,\n                            expr,\n                            recv,\n                            recv2,\n                            iter_overeager_cloned::Op::LaterCloned,\n                            false,\n                        );\n                    }\n                },\n                (sym::sort, []) => {\n                    stable_sort_primitive::check(cx, expr, recv);\n                },\n                (sym::sort_by, [arg]) => {\n                    unnecessary_sort_by::check(cx, expr, call_span, arg, false);\n                },\n                (sym::sort_unstable_by, [arg]) => {\n                    unnecessary_sort_by::check(cx, expr, call_span, arg, true);\n                },\n                (sym::split, [arg]) => {\n                    str_split::check(cx, expr, recv, call_span, arg);\n                },\n                (sym::splitn | sym::rsplitn, [count_arg, pat_arg]) => {\n                    if let Some(Constant::Int(count)) = ConstEvalCtxt::new(cx).eval(count_arg) {\n                        suspicious_splitn::check(cx, name, expr, recv, count);\n                        str_splitn::check(cx, name, expr, recv, pat_arg, count, self.msrv);\n                    }\n                },\n                (sym::splitn_mut | sym::rsplitn_mut, [count_arg, _]) => {\n                    if let Some(Constant::Int(count)) = ConstEvalCtxt::new(cx).eval(count_arg) {\n                        suspicious_splitn::check(cx, name, expr, recv, count);\n                    }\n                },\n                (sym::step_by, [arg]) => iterator_step_by_zero::check(cx, expr, arg),\n                (sym::take, [arg]) => {\n                    iter_out_of_bounds::check_take(cx, expr, recv, arg);\n                    manual_repeat_n::check(cx, expr, recv, arg, self.msrv);\n                    if let Some((sym::cloned, recv2, [], _span2, _)) = method_call(recv) {\n                        iter_overeager_cloned::check(\n                            cx,\n                            expr,\n                            recv,\n                            recv2,\n                            iter_overeager_cloned::Op::LaterCloned,\n                            false,\n                        );\n                    }\n                },\n                (sym::take, []) => needless_option_take::check(cx, expr, recv),\n                (sym::then, [arg]) => {\n                    if !self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) {\n                        return;\n                    }\n                    unnecessary_lazy_eval::check(cx, expr, recv, arg, \"then_some\");\n                },\n                (sym::try_into, []) if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::TryInto) => {\n                    unnecessary_fallible_conversions::check_method(cx, expr);\n                },\n                (sym::to_owned, []) =>\n                {\n                    #[expect(clippy::collapsible_match)]\n                    if !suspicious_to_owned::check(cx, expr, span) {\n                        implicit_clone::check(cx, name, expr, recv);\n                    }\n                },\n                (sym::to_os_string | sym::to_path_buf | sym::to_string | sym::to_vec, []) => {\n                    implicit_clone::check(cx, name, expr, recv);\n                },\n                (sym::type_id, []) => {\n                    type_id_on_box::check(cx, recv, expr.span);\n                },\n                (sym::unwrap, []) => {\n                    match method_call(recv) {\n                        Some((sym::get, recv, [get_arg], _, _)) => {\n                            get_unwrap::check(cx, expr, recv, get_arg, false);\n                        },\n                        Some((sym::get_mut, recv, [get_arg], _, _)) => {\n                            get_unwrap::check(cx, expr, recv, get_arg, true);\n                        },\n                        Some((sym::or, recv, [or_arg], or_span, _)) => {\n                            or_then_unwrap::check(cx, expr, recv, or_arg, or_span);\n                        },\n                        _ => {},\n                    }\n                    unnecessary_literal_unwrap::check(cx, expr, recv, name, args);\n                },\n                (sym::unwrap_or, [u_arg]) => {\n                    match method_call(recv) {\n                        Some((arith @ (sym::checked_add | sym::checked_sub | sym::checked_mul), lhs, [rhs], _, _)) => {\n                            manual_saturating_arithmetic::check_unwrap_or(cx, expr, lhs, rhs, u_arg, arith);\n                        },\n                        Some((sym::map, m_recv, [m_arg], span, _)) => {\n                            map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, self.msrv);\n                        },\n                        Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => {\n                            obfuscated_if_else::check(\n                                cx,\n                                expr,\n                                t_recv,\n                                t_arg,\n                                then_method,\n                                obfuscated_if_else::Unwrap::Or(u_arg),\n                            );\n                        },\n                        _ => {},\n                    }\n                    unnecessary_literal_unwrap::check(cx, expr, recv, name, args);\n                },\n                (sym::unwrap_or_default, []) => {\n                    match method_call(recv) {\n                        Some((sym::checked_sub, lhs, [rhs], _, _)) => {\n                            manual_saturating_arithmetic::check_sub_unwrap_or_default(cx, expr, lhs, rhs);\n                        },\n                        Some((sym::map, m_recv, [arg], span, _)) => {\n                            manual_is_variant_and::check_map_unwrap_or_default(cx, expr, m_recv, arg, span, self.msrv);\n                        },\n                        Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => {\n                            obfuscated_if_else::check(\n                                cx,\n                                expr,\n                                t_recv,\n                                t_arg,\n                                then_method,\n                                obfuscated_if_else::Unwrap::OrDefault,\n                            );\n                        },\n                        _ => {},\n                    }\n                    unnecessary_literal_unwrap::check(cx, expr, recv, name, args);\n                },\n                (sym::unwrap_or_else, [u_arg]) => {\n                    match method_call(recv) {\n                        Some((sym::map, recv, [map_arg], _, _))\n                            if map_unwrap_or_else::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {},\n                        Some((then_method @ (sym::then | sym::then_some), t_recv, [t_arg], _, _)) => {\n                            obfuscated_if_else::check(\n                                cx,\n                                expr,\n                                t_recv,\n                                t_arg,\n                                then_method,\n                                obfuscated_if_else::Unwrap::OrElse(u_arg),\n                            );\n                        },\n                        _ => {\n                            unnecessary_lazy_eval::check(cx, expr, recv, u_arg, \"unwrap_or\");\n                        },\n                    }\n                    unnecessary_literal_unwrap::check(cx, expr, recv, name, args);\n                },\n                (sym::wake, []) => {\n                    waker_clone_wake::check(cx, expr, recv);\n                },\n                (sym::write, []) => {\n                    readonly_write_lock::check(cx, expr, recv);\n                },\n                (sym::zip, [arg]) => {\n                    if let ExprKind::MethodCall(name, iter_recv, [], _) = recv.kind\n                        && name.ident.name == sym::iter\n                    {\n                        range_zip_with_len::check(cx, expr, iter_recv, arg);\n                    }\n                },\n                _ => {},\n            }\n        }\n        // Handle method calls whose receiver and arguments may come from expansion\n        if let ExprKind::MethodCall(path, recv, args, _call_span) = expr.kind {\n            let method_span = path.ident.span;\n\n            // Those methods do their own method name checking as they deal with multiple methods.\n            or_fun_call::check(cx, expr, method_span, path.ident.name, recv, args, self.msrv);\n            unnecessary_to_owned::check(cx, expr, path.ident.name, recv, args, self.msrv);\n\n            match (path.ident.name, args) {\n                (sym::clone, []) => {\n                    clone_on_ref_ptr::check(cx, expr, recv);\n                    clone_on_copy::check(cx, expr, recv);\n                },\n                (sym::expect, [arg]) => {\n                    unwrap_expect_used::check(\n                        cx,\n                        expr,\n                        recv,\n                        false,\n                        self.allow_expect_in_consts,\n                        self.allow_expect_in_tests,\n                        &self.unwrap_allowed_ids,\n                        &self.unwrap_allowed_aliases,\n                        unwrap_expect_used::Variant::Expect,\n                    );\n                    expect_fun_call::check(cx, &self.format_args, expr, method_span, recv, arg);\n                },\n                (sym::expect_err, [_]) => {\n                    unwrap_expect_used::check(\n                        cx,\n                        expr,\n                        recv,\n                        true,\n                        self.allow_expect_in_consts,\n                        self.allow_expect_in_tests,\n                        &self.unwrap_allowed_ids,\n                        &self.unwrap_allowed_aliases,\n                        unwrap_expect_used::Variant::Expect,\n                    );\n                },\n                (sym::insert_str | sym::push_str, _) => {\n                    single_char_add_str::check(cx, expr, recv, args);\n                },\n                (sym::into_iter, []) => {\n                    into_iter_on_ref::check(cx, expr, method_span, recv);\n                },\n                (sym::to_string, []) => {\n                    inefficient_to_string::check(cx, expr, recv, self.msrv);\n                },\n                (sym::unwrap, []) => {\n                    unwrap_expect_used::check(\n                        cx,\n                        expr,\n                        recv,\n                        false,\n                        self.allow_unwrap_in_consts,\n                        self.allow_unwrap_in_tests,\n                        &self.unwrap_allowed_ids,\n                        &self.unwrap_allowed_aliases,\n                        unwrap_expect_used::Variant::Unwrap,\n                    );\n                },\n                (sym::unwrap_err, []) => {\n                    unwrap_expect_used::check(\n                        cx,\n                        expr,\n                        recv,\n                        true,\n                        self.allow_unwrap_in_consts,\n                        self.allow_unwrap_in_tests,\n                        &self.unwrap_allowed_ids,\n                        &self.unwrap_allowed_aliases,\n                        unwrap_expect_used::Variant::Unwrap,\n                    );\n                },\n                _ => {},\n            }\n        }\n    }\n}\n\nfn check_is_some_is_none<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    recv: &'tcx Expr<'tcx>,\n    call_span: Span,\n    is_some: bool,\n    msrv: Msrv,\n) {\n    match method_call(recv) {\n        Some((name @ (sym::find | sym::position | sym::rposition), f_recv, [arg], span, _)) => {\n            search_is_some::check(cx, expr, name, is_some, f_recv, arg, recv, span);\n        },\n        Some((sym::get, f_recv, [arg], _, _)) => {\n            unnecessary_get_then_check::check(cx, call_span, recv, f_recv, arg, is_some);\n        },\n        Some((sym::first, f_recv, [], _, _)) => {\n            unnecessary_first_then_check::check(cx, call_span, recv, f_recv, is_some);\n        },\n        Some((sym::filter, f_recv, [arg], _, _)) => {\n            manual_is_variant_and::check_is_some_is_none(cx, call_span, f_recv, arg, is_some, msrv);\n        },\n        _ => {},\n    }\n}\n\n/// Used for `lint_binary_expr_with_method_call`.\n#[derive(Copy, Clone)]\nstruct BinaryExprInfo<'a> {\n    expr: &'a Expr<'a>,\n    chain: &'a Expr<'a>,\n    other: &'a Expr<'a>,\n    eq: bool,\n}\n\n/// Checks for the `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints.\nfn lint_binary_expr_with_method_call(cx: &LateContext<'_>, info: &mut BinaryExprInfo<'_>) {\n    macro_rules! lint_with_both_lhs_and_rhs {\n        ($func:expr, $cx:expr, $info:ident) => {\n            if !$func($cx, $info) {\n                ::std::mem::swap(&mut $info.chain, &mut $info.other);\n                if $func($cx, $info) {\n                    return;\n                }\n            }\n        };\n    }\n\n    lint_with_both_lhs_and_rhs!(chars_next_cmp::check, cx, info);\n    lint_with_both_lhs_and_rhs!(chars_last_cmp::check, cx, info);\n    lint_with_both_lhs_and_rhs!(chars_next_cmp_with_unwrap::check, cx, info);\n    lint_with_both_lhs_and_rhs!(chars_last_cmp_with_unwrap::check, cx, info);\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/mut_mutex_lock.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::expr_custom_deref_adjustment;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::peel_and_count_ty_refs;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, Mutability};\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, sym};\n\nuse super::MUT_MUTEX_LOCK;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>, recv: &'tcx Expr<'tcx>, name_span: Span) {\n    if matches!(expr_custom_deref_adjustment(cx, recv), None | Some(Mutability::Mut))\n        && let (_, _, Some(Mutability::Mut)) = peel_and_count_ty_refs(cx.typeck_results().expr_ty(recv))\n        && let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && cx.tcx.type_of(impl_id).is_diag_item(cx, sym::Mutex)\n    {\n        span_lint_and_sugg(\n            cx,\n            MUT_MUTEX_LOCK,\n            name_span,\n            \"calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference\",\n            \"change this to\",\n            \"get_mut\".to_owned(),\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/needless_as_bytes.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sugg::Sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, LangItem};\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, Symbol};\n\nuse super::NEEDLESS_AS_BYTES;\n\npub fn check(cx: &LateContext<'_>, prev_method: Symbol, method: Symbol, prev_recv: &Expr<'_>, span: Span) {\n    let ty1 = cx.typeck_results().expr_ty_adjusted(prev_recv).peel_refs();\n    if ty1.is_lang_item(cx, LangItem::String) || ty1.is_str() {\n        let mut app = Applicability::MachineApplicable;\n        let sugg = Sugg::hir_with_context(cx, prev_recv, span.ctxt(), \"..\", &mut app);\n        span_lint_and_sugg(\n            cx,\n            NEEDLESS_AS_BYTES,\n            span,\n            format!(\"needless call to `{prev_method}`\"),\n            format!(\"`{method}()` can be called directly on strings\"),\n            format!(\"{sugg}.{method}()\"),\n            app,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/needless_character_iteration.rs",
    "content": "use clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Closure, Expr, ExprKind, HirId, StmtKind, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::Span;\n\nuse super::NEEDLESS_CHARACTER_ITERATION;\nuse super::utils::get_last_chain_binding_hir_id;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{peel_blocks, sym};\n\nfn peels_expr_ref<'a, 'tcx>(mut expr: &'a Expr<'tcx>) -> &'a Expr<'tcx> {\n    while let ExprKind::AddrOf(_, _, e) = expr.kind {\n        expr = e;\n    }\n    expr\n}\n\nfn handle_expr(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    first_param: HirId,\n    span: Span,\n    before_chars: Span,\n    revert: bool,\n    is_all: bool,\n) {\n    match expr.kind {\n        ExprKind::MethodCall(method, receiver, [], _) => {\n            // If we have `!is_ascii`, then only `.any()` should warn. And if the condition is\n            // `is_ascii`, then only `.all()` should warn.\n            if revert != is_all\n                && method.ident.name == sym::is_ascii\n                && receiver.res_local_id() == Some(first_param)\n                && let char_arg_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs()\n                && *char_arg_ty.kind() == ty::Char\n                && let Some(snippet) = before_chars.get_source_text(cx)\n            {\n                span_lint_and_sugg(\n                    cx,\n                    NEEDLESS_CHARACTER_ITERATION,\n                    span,\n                    \"checking if a string is ascii using iterators\",\n                    \"try\",\n                    format!(\"{}{snippet}.is_ascii()\", if revert { \"!\" } else { \"\" }),\n                    Applicability::MachineApplicable,\n                );\n            }\n        },\n        ExprKind::Block(block, _) => {\n            if block.stmts.iter().any(|stmt| !matches!(stmt.kind, StmtKind::Let(_))) {\n                // If there is something else than let bindings, then better not emit the lint.\n                return;\n            }\n            if let Some(block_expr) = block.expr\n                // First we ensure that this is a \"binding chain\" (each statement is a binding\n                // of the previous one) and that it is a binding of the closure argument.\n                && let Some(last_chain_binding_id) =\n                    get_last_chain_binding_hir_id(first_param, block.stmts)\n            {\n                handle_expr(\n                    cx,\n                    block_expr,\n                    last_chain_binding_id,\n                    span,\n                    before_chars,\n                    revert,\n                    is_all,\n                );\n            }\n        },\n        ExprKind::Unary(UnOp::Not, expr) => handle_expr(cx, expr, first_param, span, before_chars, !revert, is_all),\n        ExprKind::Call(fn_path, [arg]) => {\n            // If we have `!is_ascii`, then only `.any()` should warn. And if the condition is\n            // `is_ascii`, then only `.all()` should warn.\n            if revert != is_all\n                && fn_path.ty_rel_def(cx).is_diag_item(cx, sym::char_is_ascii)\n                && peels_expr_ref(arg).res_local_id() == Some(first_param)\n                && let Some(snippet) = before_chars.get_source_text(cx)\n            {\n                span_lint_and_sugg(\n                    cx,\n                    NEEDLESS_CHARACTER_ITERATION,\n                    span,\n                    \"checking if a string is ascii using iterators\",\n                    \"try\",\n                    format!(\"{}{snippet}.is_ascii()\", if revert { \"!\" } else { \"\" }),\n                    Applicability::MachineApplicable,\n                );\n            }\n        },\n        _ => {},\n    }\n}\n\npub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>, closure_arg: &Expr<'_>, is_all: bool) {\n    if let ExprKind::Closure(&Closure { body, .. }) = closure_arg.kind\n        && let body = cx.tcx.hir_body(body)\n        && let Some(first_param) = body.params.first()\n        && let ExprKind::MethodCall(method, mut recv, [], _) = recv.kind\n        && method.ident.name == sym::chars\n        && let str_ty = cx.typeck_results().expr_ty_adjusted(recv).peel_refs()\n        && *str_ty.kind() == ty::Str\n    {\n        let expr_start = recv.span;\n        while let ExprKind::MethodCall(_, new_recv, _, _) = recv.kind {\n            recv = new_recv;\n        }\n        let body_expr = peel_blocks(body.value);\n\n        handle_expr(\n            cx,\n            body_expr,\n            first_param.pat.hir_id,\n            recv.span.with_hi(call_expr.span.hi()),\n            recv.span.with_hi(expr_start.hi()),\n            false,\n            is_all,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/needless_collect.rs",
    "content": "use std::borrow::Cow;\nuse std::ops::ControlFlow;\n\nuse super::NEEDLESS_COLLECT;\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};\nuse clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::source::{snippet, snippet_with_applicability};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::{has_non_owning_mutable_access, make_normalized_projection, make_projection};\nuse clippy_utils::{CaptureKind, can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, sym};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::{Applicability, MultiSpan};\nuse rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};\nuse rustc_hir::{\n    BindingMode, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Mutability, Node, Pat, PatKind, Stmt, StmtKind,\n};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::{self, AssocTag, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty};\nuse rustc_span::symbol::Ident;\nuse rustc_span::{Span, Symbol};\n\nconst NEEDLESS_COLLECT_MSG: &str = \"avoid using `collect()` when not needed\";\n\n#[expect(clippy::too_many_lines)]\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    name_span: Span,\n    collect_expr: &'tcx Expr<'_>,\n    iter_expr: &'tcx Expr<'tcx>,\n    call_span: Span,\n) {\n    let iter_ty = cx.typeck_results().expr_ty(iter_expr);\n    if has_non_owning_mutable_access(cx, iter_ty) {\n        return; // don't lint if the iterator has side effects\n    }\n\n    match cx.tcx.parent_hir_node(collect_expr.hir_id) {\n        Node::Expr(parent) => {\n            check_collect_into_intoiterator(cx, parent, collect_expr, call_span, iter_expr);\n\n            let sugg: String;\n            let mut app;\n\n            if let ExprKind::MethodCall(name, _, args @ ([] | [_]), _) = parent.kind {\n                app = Applicability::MachineApplicable;\n                let collect_ty = cx.typeck_results().expr_ty(collect_expr);\n\n                sugg = match name.ident.name {\n                    sym::len => {\n                        if let Some(adt) = collect_ty.ty_adt_def()\n                            && matches!(\n                                cx.tcx.get_diagnostic_name(adt.did()),\n                                Some(sym::Vec | sym::VecDeque | sym::LinkedList | sym::BinaryHeap)\n                            )\n                        {\n                            \"count()\".into()\n                        } else {\n                            return;\n                        }\n                    },\n                    sym::is_empty\n                        if is_is_empty_sig(cx, parent.hir_id)\n                            && iterates_same_ty(cx, cx.typeck_results().expr_ty(iter_expr), collect_ty) =>\n                    {\n                        \"next().is_none()\".into()\n                    },\n                    sym::contains => {\n                        if is_contains_sig(cx, parent.hir_id, iter_expr)\n                            && let Some(arg) = args.first()\n                        {\n                            let (span, prefix) = if let ExprKind::AddrOf(_, _, arg) = arg.kind {\n                                (arg.span, \"\")\n                            } else {\n                                (arg.span, \"*\")\n                            };\n                            let snip = snippet_with_applicability(cx, span, \"??\", &mut app);\n                            format!(\"any(|x| x == {prefix}{snip})\")\n                        } else {\n                            return;\n                        }\n                    },\n                    _ => return,\n                };\n            } else if let ExprKind::Index(_, index, _) = parent.kind\n                && cx.typeck_results().expr_ty(index).is_usize()\n            {\n                app = Applicability::MaybeIncorrect;\n                let snip = snippet_with_applicability(cx, index.span, \"_\", &mut app);\n                sugg = format!(\"nth({snip}).unwrap()\");\n            } else {\n                return;\n            }\n\n            span_lint_and_sugg(\n                cx,\n                NEEDLESS_COLLECT,\n                call_span.with_hi(parent.span.hi()),\n                NEEDLESS_COLLECT_MSG,\n                \"replace with\",\n                sugg,\n                app,\n            );\n        },\n        Node::LetStmt(l) => {\n            if let PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None) = l.pat.kind\n                && let ty = cx.typeck_results().expr_ty(collect_expr)\n                && let Some(extra_spec) = ty.opt_diag_name(cx).and_then(ExtraFunctionSpec::new)\n                && let iter_ty = cx.typeck_results().expr_ty(iter_expr)\n                && let Some(block) = get_enclosing_block(cx, l.hir_id)\n                && let Some((iter_calls, extra_calls)) =\n                    detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty), extra_spec)\n                && let [iter_call] = &*iter_calls\n            {\n                let mut used_count_visitor = UsedCountVisitor {\n                    cx,\n                    id,\n                    extra_spec,\n                    count: 0,\n                };\n                walk_block(&mut used_count_visitor, block);\n                if used_count_visitor.count > 1 {\n                    return;\n                }\n\n                if let IterFunctionKind::IntoIter(hir_id) = iter_call.func\n                    && !check_iter_expr_used_only_as_iterator(cx, hir_id, block)\n                {\n                    return;\n                }\n\n                // Suggest replacing iter_call with iter_replacement, and removing stmt\n                let mut span = MultiSpan::from_span(name_span);\n                span.push_span_label(iter_call.span, \"the iterator could be used here instead\");\n                span_lint_hir_and_then(\n                    cx,\n                    NEEDLESS_COLLECT,\n                    collect_expr.hir_id,\n                    span,\n                    NEEDLESS_COLLECT_MSG,\n                    |diag| {\n                        let iter_snippet = Sugg::hir(cx, iter_expr, \"..\");\n                        let mut iter_replacement = iter_snippet.to_string();\n                        for extra in &extra_calls {\n                            iter_replacement = extra.apply_iter_method(cx, &iter_replacement);\n                        }\n                        iter_replacement.push_str(&iter_call.get_iter_method(cx));\n\n                        let mut remove_suggestions = vec![(l.span, String::new())];\n                        remove_suggestions.extend(\n                            extra_calls\n                                .iter()\n                                .flat_map(|extra| extra.span().map(|s| (s, String::new()))),\n                        );\n                        remove_suggestions.push((iter_call.span, iter_replacement));\n\n                        diag.multipart_suggestion(\n                            iter_call.get_suggestion_text(),\n                            remove_suggestions,\n                            Applicability::MaybeIncorrect,\n                        );\n                    },\n                );\n            }\n        },\n        _ => (),\n    }\n}\n\n/// checks for collecting into a (generic) method or function argument\n/// taking an `IntoIterator`\nfn check_collect_into_intoiterator<'tcx>(\n    cx: &LateContext<'tcx>,\n    parent: &'tcx Expr<'tcx>,\n    collect_expr: &'tcx Expr<'tcx>,\n    call_span: Span,\n    iter_expr: &'tcx Expr<'tcx>,\n) {\n    if let Some(id) = fn_def_id(cx, parent) {\n        let args = match parent.kind {\n            ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) => args,\n            _ => &[],\n        };\n        // find the argument index of the `collect_expr` in the\n        // function / method call\n        if let Some(arg_idx) = args.iter().position(|e| e.hir_id == collect_expr.hir_id).map(|i| {\n            if matches!(parent.kind, ExprKind::MethodCall(_, _, _, _)) {\n                i + 1\n            } else {\n                i\n            }\n        }) {\n            // extract the input types of the function/method call\n            // that contains `collect_expr`\n            let inputs = cx\n                .tcx\n                .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity())\n                .inputs();\n\n            // map IntoIterator generic bounds to their signature\n            // types and check whether the argument type is an\n            // `IntoIterator`\n            if cx\n                .tcx\n                .param_env(id)\n                .caller_bounds()\n                .into_iter()\n                .filter_map(|p| {\n                    if let ClauseKind::Trait(t) = p.kind().skip_binder()\n                        && cx.tcx.is_diagnostic_item(sym::IntoIterator, t.trait_ref.def_id)\n                    {\n                        Some(t.self_ty())\n                    } else {\n                        None\n                    }\n                })\n                .any(|ty| ty == inputs[arg_idx])\n            {\n                span_lint_and_sugg(\n                    cx,\n                    NEEDLESS_COLLECT,\n                    call_span.with_lo(iter_expr.span.hi()),\n                    NEEDLESS_COLLECT_MSG,\n                    \"remove this call\",\n                    String::new(),\n                    Applicability::MachineApplicable,\n                );\n            }\n        }\n    }\n}\n\n/// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool`\nfn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool {\n    cx.typeck_results().type_dependent_def_id(call_id).is_some_and(|id| {\n        let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_binder();\n        sig.inputs().len() == 1 && sig.output().is_bool()\n    })\n}\n\n/// Checks if `<iter_ty as Iterator>::Item` is the same as `<collect_ty as IntoIter>::Item`\nfn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: Ty<'tcx>) -> bool {\n    if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)\n        && let Some(into_iter_trait) = cx.tcx.get_diagnostic_item(sym::IntoIterator)\n        && let Some(iter_item_ty) =\n            make_normalized_projection(cx.tcx, cx.typing_env(), iter_trait, sym::Item, [iter_ty])\n        && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, sym::Item, [collect_ty])\n        && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(\n            cx.typing_env(),\n            Ty::new_projection_from_args(cx.tcx, into_iter_item_proj.def_id, into_iter_item_proj.args),\n        )\n    {\n        iter_item_ty == into_iter_item_ty\n    } else {\n        false\n    }\n}\n\n/// Checks if the given method call matches the expected signature of\n/// `([&[mut]] self, &<iter_ty as Iterator>::Item) -> bool`\nfn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -> bool {\n    let typeck = cx.typeck_results();\n    if let Some(id) = typeck.type_dependent_def_id(call_id)\n        && let sig = cx.tcx.fn_sig(id).instantiate_identity()\n        && sig.skip_binder().output().is_bool()\n        && let [_, search_ty] = *sig.skip_binder().inputs()\n        && let ty::Ref(_, search_ty, Mutability::Not) = *cx\n            .tcx\n            .instantiate_bound_regions_with_erased(sig.rebind(search_ty))\n            .kind()\n        && let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)\n        && let Some(iter_item) = cx.tcx.associated_items(iter_trait).find_by_ident_and_kind(\n            cx.tcx,\n            Ident::with_dummy_span(sym::Item),\n            AssocTag::Type,\n            iter_trait,\n        )\n        && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))])\n        && let proj_ty = Ty::new_projection_from_args(cx.tcx, iter_item.def_id, args)\n        && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), proj_ty)\n    {\n        item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id))\n    } else {\n        false\n    }\n}\n\nstruct IterFunction {\n    func: IterFunctionKind,\n    span: Span,\n}\n\nimpl IterFunction {\n    fn get_iter_method(&self, cx: &LateContext<'_>) -> String {\n        match &self.func {\n            IterFunctionKind::IntoIter(_) => String::new(),\n            IterFunctionKind::Len => String::from(\".count()\"),\n            IterFunctionKind::IsEmpty => String::from(\".next().is_none()\"),\n            IterFunctionKind::Contains(span) => {\n                let s = snippet(cx, *span, \"..\");\n                if let Some(stripped) = s.strip_prefix('&') {\n                    format!(\".any(|x| x == {stripped})\")\n                } else {\n                    format!(\".any(|x| x == *{s})\")\n                }\n            },\n        }\n    }\n\n    fn get_suggestion_text(&self) -> &'static str {\n        match &self.func {\n            IterFunctionKind::IntoIter(_) => {\n                \"use the original Iterator instead of collecting it and then producing a new one\"\n            },\n            IterFunctionKind::Len => {\n                \"take the original Iterator's count instead of collecting it and finding the length\"\n            },\n            IterFunctionKind::IsEmpty => {\n                \"check if the original Iterator has anything instead of collecting it and seeing if it's empty\"\n            },\n            IterFunctionKind::Contains(_) => {\n                \"check if the original Iterator contains an element instead of collecting then checking\"\n            },\n        }\n    }\n}\n\nenum IterFunctionKind {\n    IntoIter(HirId),\n    Len,\n    IsEmpty,\n    Contains(Span),\n}\n\nstruct ExtraFunctionSpan {\n    /// Span of the function call\n    func_span: Span,\n    /// Span of the argument\n    arg_span: Span,\n}\n\nenum ExtraFunction {\n    Push {\n        back: Vec<ExtraFunctionSpan>,\n        front: Vec<ExtraFunctionSpan>,\n    },\n    Extend(ExtraFunctionSpan),\n}\n\nimpl ExtraFunction {\n    fn apply_iter_method(&self, cx: &LateContext<'_>, inner: &str) -> String {\n        match &self {\n            ExtraFunction::Push { back, front } => {\n                let back_sugg = back\n                    .iter()\n                    .map(|span| snippet(cx, span.arg_span, \"..\"))\n                    .intersperse(Cow::Borrowed(\", \"))\n                    .collect::<String>();\n                let front = front\n                    .iter()\n                    .map(|span| snippet(cx, span.arg_span, \"..\"))\n                    .intersperse(Cow::Borrowed(\", \"))\n                    .collect::<String>();\n                match (front.is_empty(), back_sugg.is_empty()) {\n                    (true, true) => inner.to_string(),\n                    (true, false) => format!(\"{inner}.chain([{back_sugg}])\"),\n                    (false, true) => format!(\"[{front}].into_iter().chain({inner})\"),\n                    (false, false) => format!(\"[{front}].into_iter().chain({inner}).chain([{back_sugg}])\"),\n                }\n            },\n            ExtraFunction::Extend(span) => {\n                let s = snippet(cx, span.arg_span, \"..\");\n                format!(\"{inner}.chain({s})\")\n            },\n        }\n    }\n\n    fn span(&self) -> Box<dyn Iterator<Item = Span> + '_> {\n        match &self {\n            ExtraFunction::Push { back, front } => Box::new(\n                back.iter()\n                    .map(|s| s.func_span)\n                    .chain(front.iter().map(|s| s.func_span)),\n            ),\n            ExtraFunction::Extend(span) => Box::new(std::iter::once(span.func_span)),\n        }\n    }\n}\n\n#[derive(Clone, Copy)]\nstruct ExtraFunctionPushSpec {\n    back: Option<Symbol>,\n    front: Option<Symbol>,\n}\n\n#[derive(Clone, Copy)]\nstruct ExtraFunctionSpec {\n    push_symbol: ExtraFunctionPushSpec,\n    extend_symbol: Option<Symbol>,\n}\n\nimpl ExtraFunctionSpec {\n    fn new(target: Symbol) -> Option<Self> {\n        match target {\n            sym::Vec => Some(ExtraFunctionSpec {\n                push_symbol: ExtraFunctionPushSpec {\n                    back: Some(sym::push),\n                    front: None,\n                },\n                extend_symbol: Some(sym::extend),\n            }),\n            sym::VecDeque | sym::LinkedList => Some(ExtraFunctionSpec {\n                push_symbol: ExtraFunctionPushSpec {\n                    back: Some(sym::push_back),\n                    front: Some(sym::push_front),\n                },\n                extend_symbol: Some(sym::extend),\n            }),\n            sym::BinaryHeap => Some(ExtraFunctionSpec {\n                push_symbol: ExtraFunctionPushSpec {\n                    back: None,\n                    front: None,\n                },\n                extend_symbol: None,\n            }),\n            _ => None,\n        }\n    }\n\n    fn is_extra_function(self, name: Symbol) -> bool {\n        self.push_symbol.back == Some(name) || self.push_symbol.front == Some(name) || self.extend_symbol == Some(name)\n    }\n}\n\nstruct IterFunctionVisitor<'a, 'tcx> {\n    illegal_mutable_capture_ids: HirIdSet,\n    current_mutably_captured_ids: HirIdSet,\n    cx: &'a LateContext<'tcx>,\n    uses: Vec<Option<IterFunction>>,\n    extras: Vec<ExtraFunction>,\n    extra_spec: ExtraFunctionSpec,\n    hir_id_uses_map: FxHashMap<HirId, usize>,\n    current_statement_hir_id: Option<HirId>,\n    seen_other: bool,\n    target: HirId,\n}\n\nimpl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> {\n    fn visit_block(&mut self, block: &'tcx Block<'tcx>) {\n        for (expr, hir_id) in block.stmts.iter().filter_map(get_expr_and_hir_id_from_stmt) {\n            if check_loop_kind(expr).is_some() {\n                continue;\n            }\n            self.visit_block_expr(expr, hir_id);\n        }\n        if let Some(expr) = block.expr {\n            if let Some(loop_kind) = check_loop_kind(expr) {\n                if let LoopKind::Conditional(block_expr) = loop_kind {\n                    self.visit_block_expr(block_expr, None);\n                }\n            } else {\n                self.visit_block_expr(expr, None);\n            }\n        }\n    }\n\n    #[expect(clippy::too_many_lines)]\n    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {\n        // Check function calls on our collection\n        if let ExprKind::MethodCall(method_name, recv, args, _) = &expr.kind {\n            if args.is_empty()\n                && method_name.ident.name == sym::collect\n                && self\n                    .cx\n                    .ty_based_def(expr)\n                    .opt_parent(self.cx)\n                    .is_diag_item(self.cx, sym::Iterator)\n            {\n                self.current_mutably_captured_ids = get_captured_ids(self.cx, self.cx.typeck_results().expr_ty(recv));\n                self.visit_expr(recv);\n                return;\n            }\n\n            if recv.res_local_id() == Some(self.target) {\n                if self\n                    .illegal_mutable_capture_ids\n                    .intersection(&self.current_mutably_captured_ids)\n                    .next()\n                    .is_none()\n                {\n                    if let Some(hir_id) = self.current_statement_hir_id {\n                        self.hir_id_uses_map.insert(hir_id, self.uses.len());\n                    }\n                    match method_name.ident.name {\n                        sym::into_iter => self.uses.push(Some(IterFunction {\n                            func: IterFunctionKind::IntoIter(expr.hir_id),\n                            span: expr.span,\n                        })),\n                        sym::len => self.uses.push(Some(IterFunction {\n                            func: IterFunctionKind::Len,\n                            span: expr.span,\n                        })),\n                        sym::is_empty => self.uses.push(Some(IterFunction {\n                            func: IterFunctionKind::IsEmpty,\n                            span: expr.span,\n                        })),\n                        sym::contains => self.uses.push(Some(IterFunction {\n                            func: IterFunctionKind::Contains(args[0].span),\n                            span: expr.span,\n                        })),\n                        name if let is_push_back = self.extra_spec.push_symbol.back.is_some_and(|sym| name == sym)\n                            && (is_push_back || self.extra_spec.push_symbol.front.is_some_and(|sym| name == sym))\n                            && self.uses.is_empty() =>\n                        {\n                            let span = get_span_of_expr_or_parent_stmt(self.cx, expr);\n                            match self.extras.last_mut() {\n                                Some(ExtraFunction::Push { back, .. }) if is_push_back => {\n                                    back.push(ExtraFunctionSpan {\n                                        func_span: span,\n                                        arg_span: args[0].span,\n                                    });\n                                },\n                                Some(ExtraFunction::Push { front, .. }) => {\n                                    front.push(ExtraFunctionSpan {\n                                        func_span: span,\n                                        arg_span: args[0].span,\n                                    });\n                                },\n                                _ if is_push_back => {\n                                    self.extras.push(ExtraFunction::Push {\n                                        back: vec![ExtraFunctionSpan {\n                                            func_span: span,\n                                            arg_span: args[0].span,\n                                        }],\n                                        front: Vec::new(),\n                                    });\n                                },\n                                _ => {\n                                    self.extras.push(ExtraFunction::Push {\n                                        back: Vec::new(),\n                                        front: vec![ExtraFunctionSpan {\n                                            func_span: span,\n                                            arg_span: args[0].span,\n                                        }],\n                                    });\n                                },\n                            }\n                        },\n                        name if self.extra_spec.extend_symbol.is_some_and(|sym| name == sym)\n                            && self.uses.is_empty() =>\n                        {\n                            let span = get_span_of_expr_or_parent_stmt(self.cx, expr);\n                            self.extras.push(ExtraFunction::Extend(ExtraFunctionSpan {\n                                func_span: span,\n                                arg_span: args[0].span,\n                            }));\n                        },\n                        _ => {\n                            self.seen_other = true;\n                            if let Some(hir_id) = self.current_statement_hir_id {\n                                self.hir_id_uses_map.remove(&hir_id);\n                            }\n                        },\n                    }\n                }\n                return;\n            }\n\n            if let Some(hir_id) = recv.res_local_id()\n                && let Some(index) = self.hir_id_uses_map.remove(&hir_id)\n            {\n                if self\n                    .illegal_mutable_capture_ids\n                    .intersection(&self.current_mutably_captured_ids)\n                    .next()\n                    .is_none()\n                {\n                    if let Some(hir_id) = self.current_statement_hir_id {\n                        self.hir_id_uses_map.insert(hir_id, index);\n                    }\n                } else {\n                    self.uses[index] = None;\n                }\n            }\n        }\n        // Check if the collection is used for anything else\n        if expr.res_local_id() == Some(self.target) {\n            self.seen_other = true;\n        } else {\n            walk_expr(self, expr);\n        }\n    }\n}\n\n/// If parent of the `expr` is a statement, return the span of the statement, otherwise return the\n/// span of the expression.\nfn get_span_of_expr_or_parent_stmt<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Span {\n    if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id) {\n        stmt.span\n    } else {\n        expr.span\n    }\n}\n\nenum LoopKind<'tcx> {\n    Conditional(&'tcx Expr<'tcx>),\n    Loop,\n}\n\nfn check_loop_kind<'tcx>(expr: &Expr<'tcx>) -> Option<LoopKind<'tcx>> {\n    if let Some(higher::WhileLet { let_expr, .. }) = higher::WhileLet::hir(expr) {\n        return Some(LoopKind::Conditional(let_expr));\n    }\n    if let Some(higher::While { condition, .. }) = higher::While::hir(expr) {\n        return Some(LoopKind::Conditional(condition));\n    }\n    if let Some(higher::ForLoop { arg, .. }) = higher::ForLoop::hir(expr) {\n        return Some(LoopKind::Conditional(arg));\n    }\n    if let ExprKind::Loop { .. } = expr.kind {\n        return Some(LoopKind::Loop);\n    }\n\n    None\n}\n\nimpl<'tcx> IterFunctionVisitor<'_, 'tcx> {\n    fn visit_block_expr(&mut self, expr: &'tcx Expr<'tcx>, hir_id: Option<HirId>) {\n        self.current_statement_hir_id = hir_id;\n        self.current_mutably_captured_ids = get_captured_ids(self.cx, self.cx.typeck_results().expr_ty(expr));\n        self.visit_expr(expr);\n    }\n}\n\nfn get_expr_and_hir_id_from_stmt<'v>(stmt: &'v Stmt<'v>) -> Option<(&'v Expr<'v>, Option<HirId>)> {\n    match stmt.kind {\n        StmtKind::Expr(expr) | StmtKind::Semi(expr) => Some((expr, None)),\n        StmtKind::Item(..) => None,\n        StmtKind::Let(LetStmt { init, pat, .. }) => {\n            if let PatKind::Binding(_, hir_id, ..) = pat.kind {\n                init.map(|init_expr| (init_expr, Some(hir_id)))\n            } else {\n                init.map(|init_expr| (init_expr, None))\n            }\n        },\n    }\n}\n\nstruct UsedCountVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    id: HirId,\n    extra_spec: ExtraFunctionSpec,\n    count: usize,\n}\n\nimpl<'tcx> Visitor<'tcx> for UsedCountVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        if expr.res_local_id() != Some(self.id) {\n            walk_expr(self, expr);\n            return;\n        }\n\n        let parent = self.cx.tcx.parent_hir_node(expr.hir_id);\n        if let Node::Expr(expr) = parent\n            && let ExprKind::MethodCall(method_name, _, _, _) = &expr.kind\n            && self.extra_spec.is_extra_function(method_name.ident.name)\n        {\n            return;\n        }\n\n        self.count += 1;\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\n/// Detect the occurrences of calls to `iter` or `into_iter` for the\n/// given identifier\nfn detect_iter_and_into_iters<'tcx: 'a, 'a>(\n    block: &'tcx Block<'tcx>,\n    id: HirId,\n    cx: &'a LateContext<'tcx>,\n    captured_ids: HirIdSet,\n    extra_spec: ExtraFunctionSpec,\n) -> Option<(Vec<IterFunction>, Vec<ExtraFunction>)> {\n    let mut visitor = IterFunctionVisitor {\n        illegal_mutable_capture_ids: captured_ids,\n        current_mutably_captured_ids: HirIdSet::default(),\n        cx,\n        uses: Vec::new(),\n        extras: Vec::new(),\n        extra_spec,\n        hir_id_uses_map: FxHashMap::default(),\n        current_statement_hir_id: None,\n        seen_other: false,\n        target: id,\n    };\n    visitor.visit_block(block);\n    if visitor.seen_other {\n        None\n    } else {\n        Some((visitor.uses.into_iter().flatten().collect(), visitor.extras))\n    }\n}\n\nfn get_captured_ids(cx: &LateContext<'_>, ty: Ty<'_>) -> HirIdSet {\n    fn get_captured_ids_recursive(cx: &LateContext<'_>, ty: Ty<'_>, set: &mut HirIdSet) {\n        match ty.kind() {\n            ty::Adt(_, generics) => {\n                for generic in *generics {\n                    if let GenericArgKind::Type(ty) = generic.kind() {\n                        get_captured_ids_recursive(cx, ty, set);\n                    }\n                }\n            },\n            ty::Closure(def_id, _) => {\n                let closure_hir_node = cx.tcx.hir_get_if_local(*def_id).unwrap();\n                if let Node::Expr(closure_expr) = closure_hir_node {\n                    can_move_expr_to_closure(cx, closure_expr)\n                        .unwrap()\n                        .into_iter()\n                        .for_each(|(hir_id, capture_kind)| {\n                            if matches!(capture_kind, CaptureKind::Ref(Mutability::Mut)) {\n                                set.insert(hir_id);\n                            }\n                        });\n                }\n            },\n            _ => (),\n        }\n    }\n\n    let mut set = HirIdSet::default();\n\n    get_captured_ids_recursive(cx, ty, &mut set);\n\n    set\n}\n\nstruct IteratorMethodCheckVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    hir_id_of_expr: HirId,\n    hir_id_of_let_binding: Option<HirId>,\n}\n\nimpl<'tcx> Visitor<'tcx> for IteratorMethodCheckVisitor<'_, 'tcx> {\n    type Result = ControlFlow<()>;\n    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {\n        if let ExprKind::MethodCall(_method_name, recv, _args, _) = &expr.kind\n            && (recv.hir_id == self.hir_id_of_expr\n                || self\n                    .hir_id_of_let_binding\n                    .is_some_and(|hid| recv.res_local_id() == Some(hid)))\n            && !self\n                .cx\n                .ty_based_def(expr)\n                .opt_parent(self.cx)\n                .is_diag_item(self.cx, sym::Iterator)\n        {\n            return ControlFlow::Break(());\n        } else if let ExprKind::Assign(place, value, _span) = &expr.kind\n            && value.hir_id == self.hir_id_of_expr\n            && let Some(id) = place.res_local_id()\n        {\n            // our iterator was directly assigned to a variable\n            self.hir_id_of_let_binding = Some(id);\n        }\n        walk_expr(self, expr)\n    }\n    fn visit_stmt(&mut self, stmt: &'tcx Stmt<'tcx>) -> ControlFlow<()> {\n        if let StmtKind::Let(LetStmt {\n            init: Some(expr),\n            pat:\n                Pat {\n                    kind: PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None),\n                    ..\n                },\n            ..\n        }) = &stmt.kind\n            && expr.hir_id == self.hir_id_of_expr\n        {\n            // our iterator was directly assigned to a variable\n            self.hir_id_of_let_binding = Some(*id);\n        }\n        walk_stmt(self, stmt)\n    }\n}\n\nfn check_iter_expr_used_only_as_iterator<'tcx>(\n    cx: &LateContext<'tcx>,\n    hir_id_of_expr: HirId,\n    block: &'tcx Block<'tcx>,\n) -> bool {\n    let mut visitor = IteratorMethodCheckVisitor {\n        cx,\n        hir_id_of_expr,\n        hir_id_of_let_binding: None,\n    };\n    visitor.visit_block(block).is_continue()\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/needless_option_as_deref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::sym;\nuse clippy_utils::usage::local_used_after_expr;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_hir::def::Res;\nuse rustc_lint::LateContext;\nuse rustc_span::Symbol;\n\nuse super::NEEDLESS_OPTION_AS_DEREF;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, name: Symbol) {\n    let typeck = cx.typeck_results();\n    let outer_ty = typeck.expr_ty(expr);\n\n    if outer_ty.is_diag_item(cx, sym::Option) && outer_ty == typeck.expr_ty(recv) {\n        if name == sym::as_deref_mut && recv.is_syntactic_place_expr() {\n            let Res::Local(binding_id) = *recv.basic_res() else {\n                return;\n            };\n\n            if local_used_after_expr(cx, binding_id, recv) {\n                return;\n            }\n        }\n\n        span_lint_and_sugg(\n            cx,\n            NEEDLESS_OPTION_AS_DEREF,\n            expr.span,\n            \"derefed type is same as origin\",\n            \"try\",\n            recv.span.get_source_text(cx).unwrap().to_owned(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/needless_option_take.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_span::{Symbol, sym};\n\nuse super::NEEDLESS_OPTION_TAKE;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {\n    // Checks if expression type is equal to sym::Option and if the expr is not a syntactic place\n    if !recv.is_syntactic_place_expr()\n        && is_expr_option(cx, recv)\n        && let Some(function_name) = source_of_temporary_value(recv)\n    {\n        span_lint_and_then(\n            cx,\n            NEEDLESS_OPTION_TAKE,\n            expr.span,\n            \"called `Option::take()` on a temporary value\",\n            |diag| {\n                diag.note(format!(\n                    \"`{function_name}` creates a temporary value, so calling take() has no effect\"\n                ));\n                diag.span_suggestion(\n                    expr.span.with_lo(recv.span.hi()),\n                    \"remove\",\n                    \"\",\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n\nfn is_expr_option(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let expr_type = cx.typeck_results().expr_ty(expr);\n    expr_type.is_diag_item(cx, sym::Option)\n}\n\n/// Returns the string of the function call that creates the temporary.\n/// When this function is called, we are reasonably certain that the `ExprKind` is either\n/// `Call` or `MethodCall` because we already checked that the expression is not\n/// `is_syntactic_place_expr()`.\nfn source_of_temporary_value(expr: &Expr<'_>) -> Option<Symbol> {\n    match expr.peel_borrows().kind {\n        ExprKind::Call(function, _) => {\n            if let ExprKind::Path(QPath::Resolved(_, func_path)) = function.kind\n                && !func_path.segments.is_empty()\n            {\n                return Some(func_path.segments[0].ident.name);\n            }\n            if let ExprKind::Path(QPath::TypeRelative(_, func_path_segment)) = function.kind {\n                return Some(func_path_segment.ident.name);\n            }\n            None\n        },\n        ExprKind::MethodCall(path_segment, ..) => Some(path_segment.ident.name),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/new_ret_no_self.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::return_ty;\nuse clippy_utils::ty::contains_ty_adt_constructor_opaque;\nuse rustc_hir::{ImplItem, TraitItem};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::sym;\n\nuse super::NEW_RET_NO_SELF;\n\npub(super) fn check_impl_item<'tcx>(\n    cx: &LateContext<'tcx>,\n    impl_item: &'tcx ImplItem<'_>,\n    self_ty: Ty<'tcx>,\n    implements_trait: bool,\n) {\n    // if this impl block implements a trait, lint in trait definition instead\n    if !implements_trait\n        && impl_item.ident.name == sym::new\n        && let ret_ty = return_ty(cx, impl_item.owner_id)\n        && ret_ty != self_ty\n        && !contains_ty_adt_constructor_opaque(cx, ret_ty, self_ty)\n    {\n        span_lint(\n            cx,\n            NEW_RET_NO_SELF,\n            impl_item.span,\n            \"methods called `new` usually return `Self`\",\n        );\n    }\n}\n\npub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'tcx>) {\n    if trait_item.ident.name == sym::new\n        && let ret_ty = return_ty(cx, trait_item.owner_id)\n        && let self_ty = ty::TraitRef::identity(cx.tcx, trait_item.owner_id.to_def_id()).self_ty()\n        && !ret_ty.contains(self_ty)\n    {\n        span_lint(\n            cx,\n            NEW_RET_NO_SELF,\n            trait_item.span,\n            \"methods called `new` usually return `Self`\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/no_effect_replace.rs",
    "content": "use clippy_utils::SpanlessEq;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::MaybeDef;\nuse rustc_ast::LitKind;\nuse rustc_hir::{ExprKind, LangItem};\nuse rustc_lint::LateContext;\n\nuse super::NO_EFFECT_REPLACE;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx rustc_hir::Expr<'_>,\n    arg1: &'tcx rustc_hir::Expr<'_>,\n    arg2: &'tcx rustc_hir::Expr<'_>,\n) {\n    let ty = cx.typeck_results().expr_ty(expr).peel_refs();\n    if !(ty.is_str() || ty.is_lang_item(cx, LangItem::String)) {\n        return;\n    }\n\n    if let ExprKind::Lit(spanned) = &arg1.kind\n        && let Some(param1) = lit_string_value(&spanned.node)\n        && let ExprKind::Lit(spanned) = &arg2.kind\n        && let LitKind::Str(param2, _) = &spanned.node\n        && param1 == param2.as_str()\n    {\n        span_lint(cx, NO_EFFECT_REPLACE, expr.span, \"replacing text with itself\");\n        return;\n    }\n\n    if SpanlessEq::new(cx).eq_expr(arg1, arg2) {\n        span_lint(cx, NO_EFFECT_REPLACE, expr.span, \"replacing text with itself\");\n    }\n}\n\nfn lit_string_value(node: &LitKind) -> Option<String> {\n    match node {\n        LitKind::Char(value) => Some(value.to_string()),\n        LitKind::Str(value, _) => Some(value.as_str().to_owned()),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/obfuscated_if_else.rs",
    "content": "use super::OBFUSCATED_IF_ELSE;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::eager_or_lazy::switch_to_eager_eval;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{get_parent_expr, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Symbol;\n\n#[expect(clippy::needless_pass_by_value)]\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    then_recv: &'tcx Expr<'_>,\n    then_arg: &'tcx Expr<'_>,\n    then_method_name: Symbol,\n    unwrap: Unwrap<'tcx>,\n) {\n    let recv_ty = cx.typeck_results().expr_ty(then_recv);\n\n    if recv_ty.is_bool() {\n        let then_eager = switch_to_eager_eval(cx, then_arg);\n        let unwrap_eager = unwrap.arg().is_none_or(|arg| switch_to_eager_eval(cx, arg));\n\n        let mut applicability = if then_eager && unwrap_eager {\n            Applicability::MachineApplicable\n        } else {\n            Applicability::MaybeIncorrect\n        };\n\n        let if_then = match then_method_name {\n            sym::then if let ExprKind::Closure(closure) = then_arg.kind => {\n                let body = cx.tcx.hir_body(closure.body);\n                snippet_with_context(cx, body.value.span, expr.span.ctxt(), \"..\", &mut applicability).0\n            },\n            sym::then_some => snippet_with_context(cx, then_arg.span, expr.span.ctxt(), \"..\", &mut applicability).0,\n            _ => return,\n        };\n\n        let els = match unwrap {\n            Unwrap::Or(arg) => snippet_with_context(cx, arg.span, expr.span.ctxt(), \"..\", &mut applicability).0,\n            Unwrap::OrElse(arg) => match arg.kind {\n                ExprKind::Closure(closure) => {\n                    let body = cx.tcx.hir_body(closure.body);\n                    snippet_with_context(cx, body.value.span, expr.span.ctxt(), \"..\", &mut applicability).0\n                },\n                ExprKind::Path(_) => {\n                    snippet_with_context(cx, arg.span, expr.span.ctxt(), \"_\", &mut applicability).0 + \"()\"\n                },\n                _ => return,\n            },\n            Unwrap::OrDefault => \"Default::default()\".into(),\n        };\n\n        let sugg = format!(\n            \"if {} {{ {} }} else {{ {} }}\",\n            Sugg::hir_with_context(cx, then_recv, expr.span.ctxt(), \"..\", &mut applicability),\n            if_then,\n            els\n        );\n\n        // To be parsed as an expression, the `if { … } else { … }` as the left operand of a binary operator\n        // requires parentheses.\n        let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr)\n            && let ExprKind::Binary(_, left, _) = parent_expr.kind\n            && left.hir_id == expr.hir_id\n        {\n            format!(\"({sugg})\")\n        } else {\n            sugg\n        };\n\n        span_lint_and_sugg(\n            cx,\n            OBFUSCATED_IF_ELSE,\n            expr.span,\n            \"this method chain can be written more clearly with `if .. else ..`\",\n            \"try\",\n            sugg,\n            applicability,\n        );\n    }\n}\n\npub(super) enum Unwrap<'tcx> {\n    Or(&'tcx Expr<'tcx>),\n    OrElse(&'tcx Expr<'tcx>),\n    OrDefault,\n}\n\nimpl<'tcx> Unwrap<'tcx> {\n    fn arg(&self) -> Option<&'tcx Expr<'tcx>> {\n        match self {\n            Self::Or(a) | Self::OrElse(a) => Some(a),\n            Self::OrDefault => None,\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/ok_expect.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::ty::has_debug_impl;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::sym;\n\nuse super::OK_EXPECT;\n\n/// lint use of `ok().expect()` for `Result`s\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, recv_inner: &hir::Expr<'_>) {\n    let result_ty = cx.typeck_results().expr_ty(recv_inner);\n    // lint if the caller of `ok()` is a `Result`\n    if let Some(error_type) = get_error_type(cx, result_ty)\n        && has_debug_impl(cx, error_type)\n        && let Some(span) = recv.span.trim_start(recv_inner.span)\n    {\n        span_lint_and_then(\n            cx,\n            OK_EXPECT,\n            expr.span,\n            \"called `ok().expect()` on a `Result` value\",\n            |diag| {\n                let span = cx.sess().source_map().span_extend_while_whitespace(span);\n                diag.span_suggestion_verbose(\n                    span,\n                    \"call `expect()` directly on the `Result`\",\n                    String::new(),\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n\n/// Given a `Result<T, E>` type, return its error type (`E`).\nfn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> {\n    match ty.kind() {\n        ty::Adt(adt, args) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => args.types().nth(1),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/open_options.rs",
    "content": "use clippy_utils::res::MaybeDef;\nuse rustc_data_structures::fx::FxHashMap;\n\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::{paths, sym};\nuse rustc_ast::ast::LitKind;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::Span;\nuse rustc_span::source_map::Spanned;\n\nuse super::{NONSENSICAL_OPEN_OPTIONS, SUSPICIOUS_OPEN_OPTIONS};\n\nfn is_open_options(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    ty.is_diag_item(cx, sym::FsOpenOptions) || paths::TOKIO_IO_OPEN_OPTIONS.matches_ty(cx, ty)\n}\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && is_open_options(cx, cx.tcx.type_of(impl_id).instantiate_identity())\n    {\n        let mut options = Vec::new();\n        if get_open_options(cx, recv, &mut options) {\n            check_open_options(cx, &options, e.span);\n        }\n    }\n}\n\n#[derive(Eq, PartialEq, Clone, Debug)]\nenum Argument {\n    Set(bool),\n    Unknown,\n}\n\n#[derive(Debug, Eq, PartialEq, Hash, Clone)]\nenum OpenOption {\n    Append,\n    Create,\n    CreateNew,\n    Read,\n    Truncate,\n    Write,\n}\nimpl std::fmt::Display for OpenOption {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            OpenOption::Append => write!(f, \"append\"),\n            OpenOption::Create => write!(f, \"create\"),\n            OpenOption::CreateNew => write!(f, \"create_new\"),\n            OpenOption::Read => write!(f, \"read\"),\n            OpenOption::Truncate => write!(f, \"truncate\"),\n            OpenOption::Write => write!(f, \"write\"),\n        }\n    }\n}\n\n/// Collects information about a method call chain on `OpenOptions`.\n/// Returns false if an unexpected expression kind was found \"on the way\",\n/// and linting should then be avoided.\nfn get_open_options(\n    cx: &LateContext<'_>,\n    argument: &Expr<'_>,\n    options: &mut Vec<(OpenOption, Argument, Span)>,\n) -> bool {\n    if let ExprKind::MethodCall(path, receiver, arguments, span) = argument.kind {\n        let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs();\n\n        // Only proceed if this is a call on some object of type std::fs::OpenOptions\n        if !arguments.is_empty() && is_open_options(cx, obj_ty) {\n            let argument_option = match arguments[0].kind {\n                ExprKind::Lit(span) => {\n                    if let Spanned {\n                        node: LitKind::Bool(lit),\n                        ..\n                    } = span\n                    {\n                        Argument::Set(lit)\n                    } else {\n                        // The function is called with a literal which is not a boolean literal.\n                        // This is theoretically possible, but not very likely.\n                        // We'll ignore it for now\n                        return get_open_options(cx, receiver, options);\n                    }\n                },\n                _ => Argument::Unknown,\n            };\n\n            match path.ident.name {\n                sym::create => {\n                    options.push((OpenOption::Create, argument_option, span));\n                },\n                sym::create_new => {\n                    options.push((OpenOption::CreateNew, argument_option, span));\n                },\n                sym::append => {\n                    options.push((OpenOption::Append, argument_option, span));\n                },\n                sym::truncate => {\n                    options.push((OpenOption::Truncate, argument_option, span));\n                },\n                sym::read => {\n                    options.push((OpenOption::Read, argument_option, span));\n                },\n                sym::write => {\n                    options.push((OpenOption::Write, argument_option, span));\n                },\n                _ => {\n                    // Avoid linting altogether if this method is from a trait.\n                    // This might be a user defined extension trait with a method like `truncate_write`\n                    // which would be a false positive\n                    if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(argument.hir_id)\n                        && cx.tcx.trait_of_assoc(method_def_id).is_some()\n                    {\n                        return false;\n                    }\n                },\n            }\n\n            get_open_options(cx, receiver, options)\n        } else {\n            false\n        }\n    } else if let ExprKind::Call(callee, _) = argument.kind\n        && let ExprKind::Path(path) = callee.kind\n        && let Some(did) = cx.qpath_res(&path, callee.hir_id).opt_def_id()\n    {\n        let is_std_options = matches!(\n            cx.tcx.get_diagnostic_name(did),\n            Some(sym::file_options | sym::open_options_new)\n        );\n\n        is_std_options\n            || paths::TOKIO_IO_OPEN_OPTIONS_NEW.matches(cx, did)\n            || paths::TOKIO_FILE_OPTIONS.matches(cx, did)\n    } else {\n        false\n    }\n}\n\nfn check_open_options(cx: &LateContext<'_>, settings: &[(OpenOption, Argument, Span)], span: Span) {\n    // The args passed to these methods, if they have been called\n    let mut options = FxHashMap::default();\n    for (option, arg, sp) in settings {\n        if let Some((_, prev_span)) = options.insert(option.clone(), (arg.clone(), *sp)) {\n            span_lint(\n                cx,\n                NONSENSICAL_OPEN_OPTIONS,\n                prev_span,\n                format!(\"the method `{option}` is called more than once\"),\n            );\n        }\n    }\n\n    if let Some((Argument::Set(true), _)) = options.get(&OpenOption::Read)\n        && let Some((Argument::Set(true), _)) = options.get(&OpenOption::Truncate)\n        && let None | Some((Argument::Set(false), _)) = options.get(&OpenOption::Write)\n    {\n        span_lint(\n            cx,\n            NONSENSICAL_OPEN_OPTIONS,\n            span,\n            \"file opened with `truncate` and `read`\",\n        );\n    }\n\n    if let Some((Argument::Set(true), _)) = options.get(&OpenOption::Append)\n        && let Some((Argument::Set(true), _)) = options.get(&OpenOption::Truncate)\n    {\n        span_lint(\n            cx,\n            NONSENSICAL_OPEN_OPTIONS,\n            span,\n            \"file opened with `append` and `truncate`\",\n        );\n    }\n\n    if let Some((Argument::Set(true), create_span)) = options.get(&OpenOption::Create)\n        && let None = options.get(&OpenOption::Truncate)\n        && let None | Some((Argument::Set(false), _)) = options.get(&OpenOption::Append)\n    {\n        span_lint_and_then(\n            cx,\n            SUSPICIOUS_OPEN_OPTIONS,\n            *create_span,\n            \"file opened with `create`, but `truncate` behavior not defined\",\n            |diag| {\n                diag.span_suggestion(\n                    create_span.shrink_to_hi(),\n                    \"add\",\n                    \".truncate(true)\".to_string(),\n                    rustc_errors::Applicability::MaybeIncorrect,\n                )\n                .help(\"if you intend to overwrite an existing file entirely, call `.truncate(true)`\")\n                .help(\n                    \"if you instead know that you may want to keep some parts of the old file, call `.truncate(false)`\",\n                )\n                .help(\"alternatively, use `.append(true)` to append to the file instead of overwriting it\");\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/option_as_ref_cloned.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, Symbol};\n\nuse super::OPTION_AS_REF_CLONED;\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    cloned_ident_span: Span,\n    as_ref_method: Symbol,\n    as_ref_recv: &Expr<'_>,\n    as_ref_ident_span: Span,\n) {\n    if cx\n        .typeck_results()\n        .expr_ty(as_ref_recv)\n        .peel_refs()\n        .is_diag_item(cx, sym::Option)\n    {\n        span_lint_and_sugg(\n            cx,\n            OPTION_AS_REF_CLONED,\n            as_ref_ident_span.to(cloned_ident_span),\n            format!(\"cloning an `Option<_>` using `.{as_ref_method}().cloned()`\"),\n            \"this can be written more concisely by cloning the `Option<_>` directly\",\n            \"clone\".into(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/option_as_ref_deref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet;\nuse clippy_utils::{peel_blocks, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::Symbol;\n\nuse super::OPTION_AS_REF_DEREF;\n\n/// lint use of `_.as_ref().map(Deref::deref)` for `Option`s\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    as_ref_recv: &hir::Expr<'_>,\n    map_arg: &hir::Expr<'_>,\n    is_mut: bool,\n    msrv: Msrv,\n) {\n    let same_mutability = |m| (is_mut && m == &hir::Mutability::Mut) || (!is_mut && m == &hir::Mutability::Not);\n\n    let option_ty = cx.typeck_results().expr_ty(as_ref_recv);\n    if !option_ty.is_diag_item(cx, sym::Option) {\n        return;\n    }\n\n    let deref_aliases: [Symbol; 7] = [\n        sym::cstring_as_c_str,\n        sym::os_string_as_os_str,\n        sym::pathbuf_as_path,\n        sym::string_as_str,\n        sym::string_as_mut_str,\n        sym::vec_as_slice,\n        sym::vec_as_mut_slice,\n    ];\n\n    let is_deref = match map_arg.kind {\n        hir::ExprKind::Path(ref expr_qpath) => cx\n            .qpath_res(expr_qpath, map_arg.hir_id)\n            .opt_def_id()\n            .and_then(|fun_def_id| cx.tcx.get_diagnostic_name(fun_def_id))\n            .is_some_and(|fun_name| {\n                matches!(fun_name, sym::deref_method | sym::deref_mut_method) || deref_aliases.contains(&fun_name)\n            }),\n        hir::ExprKind::Closure(&hir::Closure { body, .. }) => {\n            let closure_body = cx.tcx.hir_body(body);\n            let closure_expr = peel_blocks(closure_body.value);\n\n            match &closure_expr.kind {\n                hir::ExprKind::MethodCall(_, receiver, [], _) => {\n                    if receiver.res_local_id() == Some(closure_body.params[0].pat.hir_id)\n                        && let adj = cx\n                            .typeck_results()\n                            .expr_adjustments(receiver)\n                            .iter()\n                            .map(|x| &x.kind)\n                            .collect::<Box<[_]>>()\n                        && let [\n                            ty::adjustment::Adjust::Deref(ty::adjustment::DerefAdjustKind::Builtin),\n                            ty::adjustment::Adjust::Borrow(_),\n                        ] = *adj\n                        && let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap()\n                        && let Some(method_name) = cx.tcx.get_diagnostic_name(method_did)\n                    {\n                        matches!(method_name, sym::deref_method | sym::deref_mut_method)\n                            || deref_aliases.contains(&method_name)\n                    } else {\n                        false\n                    }\n                },\n                hir::ExprKind::AddrOf(hir::BorrowKind::Ref, m, inner) if same_mutability(m) => {\n                    if let hir::ExprKind::Unary(hir::UnOp::Deref, inner1) = inner.kind\n                        && let hir::ExprKind::Unary(hir::UnOp::Deref, inner2) = inner1.kind\n                    {\n                        inner2.res_local_id() == Some(closure_body.params[0].pat.hir_id)\n                    } else {\n                        false\n                    }\n                },\n                _ => false,\n            }\n        },\n        _ => false,\n    };\n\n    if is_deref && msrv.meets(cx, msrvs::OPTION_AS_DEREF) {\n        let current_method = if is_mut {\n            format!(\".as_mut().map({})\", snippet(cx, map_arg.span, \"..\"))\n        } else {\n            format!(\".as_ref().map({})\", snippet(cx, map_arg.span, \"..\"))\n        };\n        let method_hint = if is_mut { \"as_deref_mut\" } else { \"as_deref\" };\n        let hint = format!(\"{}.{method_hint}()\", snippet(cx, as_ref_recv.span, \"..\"));\n        let suggestion = format!(\"consider using {method_hint}\");\n\n        let msg = format!(\"called `{current_method}` on an `Option` value\");\n        span_lint_and_sugg(\n            cx,\n            OPTION_AS_REF_DEREF,\n            expr.span,\n            msg,\n            suggestion,\n            hint,\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/option_map_or_none.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_none_expr;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::LangItem::OptionSome;\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::sym;\n\nuse super::{OPTION_MAP_OR_NONE, RESULT_MAP_OR_INTO_OPTION};\n\n// The expression inside a closure may or may not have surrounding braces\n// which causes problems when generating a suggestion.\nfn reduce_unit_expression<'a>(expr: &'a hir::Expr<'_>) -> Option<(&'a hir::Expr<'a>, &'a [hir::Expr<'a>])> {\n    match expr.kind {\n        hir::ExprKind::Call(func, arg_char) => Some((func, arg_char)),\n        hir::ExprKind::Block(block, _) => {\n            match (block.stmts, block.expr) {\n                (&[], Some(inner_expr)) => {\n                    // If block only contains an expression,\n                    // reduce `|x| { x + 1 }` to `|x| x + 1`\n                    reduce_unit_expression(inner_expr)\n                },\n                _ => None,\n            }\n        },\n        _ => None,\n    }\n}\n\n/// lint use of `_.map_or(None, _)` for `Option`s and `Result`s\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'_>,\n    def_arg: &'tcx hir::Expr<'_>,\n    map_arg: &'tcx hir::Expr<'_>,\n) {\n    let is_option = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Option);\n    let is_result = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result);\n\n    // There are two variants of this `map_or` lint:\n    // (1) using `map_or` as an adapter from `Result<T,E>` to `Option<T>`\n    // (2) using `map_or` as a combinator instead of `and_then`\n    //\n    // (For this lint) we don't care if any other type calls `map_or`\n    if !is_option && !is_result {\n        return;\n    }\n\n    if !is_none_expr(cx, def_arg) {\n        // nothing to lint!\n        return;\n    }\n\n    let f_arg_is_some = map_arg.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome);\n\n    if is_option {\n        let self_snippet = snippet(cx, recv.span, \"..\");\n        if let hir::ExprKind::Closure(&hir::Closure { body, fn_decl_span, .. }) = map_arg.kind\n            && let arg_snippet = snippet(cx, fn_decl_span, \"..\")\n            && let body = cx.tcx.hir_body(body)\n            && let Some((func, [arg_char])) = reduce_unit_expression(body.value)\n            && let Some(id) = func.res(cx).opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id))\n            && Some(id) == cx.tcx.lang_items().option_some_variant()\n        {\n            let func_snippet = snippet(cx, arg_char.span, \"..\");\n            let msg = \"called `map_or(None, ..)` on an `Option` value\";\n            return span_lint_and_sugg(\n                cx,\n                OPTION_MAP_OR_NONE,\n                expr.span,\n                msg,\n                \"consider using `map`\",\n                format!(\"{self_snippet}.map({arg_snippet} {func_snippet})\"),\n                Applicability::MachineApplicable,\n            );\n        }\n\n        let func_snippet = snippet(cx, map_arg.span, \"..\");\n        let msg = \"called `map_or(None, ..)` on an `Option` value\";\n        span_lint_and_sugg(\n            cx,\n            OPTION_MAP_OR_NONE,\n            expr.span,\n            msg,\n            \"consider using `and_then`\",\n            format!(\"{self_snippet}.and_then({func_snippet})\"),\n            Applicability::MachineApplicable,\n        );\n    } else if f_arg_is_some {\n        let msg = \"called `map_or(None, Some)` on a `Result` value\";\n        let self_snippet = snippet(cx, recv.span, \"..\");\n        span_lint_and_sugg(\n            cx,\n            RESULT_MAP_OR_INTO_OPTION,\n            expr.span,\n            msg,\n            \"consider using `ok`\",\n            format!(\"{self_snippet}.ok()\"),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/or_fun_call.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::eager_or_lazy::switch_to_lazy_eval;\nuse clippy_utils::higher::VecArgs;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::{expr_type_is_certain, implements_trait};\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{\n    contains_return, is_default_equivalent, is_default_equivalent_call, last_path_segment, peel_blocks, sym,\n};\nuse rustc_ast as ast;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, Symbol};\n\nuse super::{OR_FUN_CALL, UNWRAP_OR_DEFAULT};\n\n/// Checks for the `OR_FUN_CALL` lint.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &hir::Expr<'_>,\n    method_span: Span,\n    name: Symbol,\n    receiver: &'tcx hir::Expr<'_>,\n    args: &'tcx [hir::Expr<'_>],\n    msrv: Msrv,\n) {\n    if let [arg] = args {\n        let inner_arg = peel_blocks(arg);\n        for_each_expr(cx, inner_arg, |ex| {\n            // `or_fun_call` lint needs to take nested expr into account,\n            // but `unwrap_or_default` lint doesn't, we don't want something like:\n            // `opt.unwrap_or(Foo { inner: String::default(), other: 1 })` to get replaced by\n            // `opt.unwrap_or_default()`.\n            let is_nested_expr = ex.hir_id != inner_arg.hir_id;\n\n            let is_triggered = match ex.kind {\n                hir::ExprKind::Call(fun, fun_args) => {\n                    let inner_fun_has_args = !fun_args.is_empty();\n                    let fun_span = if inner_fun_has_args || is_nested_expr {\n                        None\n                    } else {\n                        Some(fun.span)\n                    };\n                    (!inner_fun_has_args\n                        && !is_nested_expr\n                        && check_unwrap_or_default(cx, name, receiver, fun, Some(ex), expr.span, method_span, msrv))\n                        || check_or_fn_call(cx, name, method_span, receiver, arg, None, expr.span, fun_span)\n                },\n                hir::ExprKind::Path(..) | hir::ExprKind::Closure(..) if !is_nested_expr => {\n                    check_unwrap_or_default(cx, name, receiver, ex, None, expr.span, method_span, msrv)\n                },\n                hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {\n                    check_or_fn_call(cx, name, method_span, receiver, arg, None, expr.span, None)\n                },\n                _ => false,\n            };\n\n            if is_triggered {\n                ControlFlow::Break(())\n            } else {\n                ControlFlow::Continue(())\n            }\n        });\n    }\n\n    // `map_or` takes two arguments\n    if let [arg, lambda] = args {\n        let inner_arg = peel_blocks(arg);\n        for_each_expr(cx, inner_arg, |ex| {\n            let is_top_most_expr = ex.hir_id == inner_arg.hir_id;\n            match ex.kind {\n                hir::ExprKind::Call(fun, fun_args) => {\n                    let fun_span = if fun_args.is_empty() && is_top_most_expr {\n                        Some(fun.span)\n                    } else {\n                        None\n                    };\n                    if check_or_fn_call(cx, name, method_span, receiver, arg, Some(lambda), expr.span, fun_span) {\n                        return ControlFlow::Break(());\n                    }\n                },\n                hir::ExprKind::MethodCall(..)\n                    if check_or_fn_call(cx, name, method_span, receiver, arg, Some(lambda), expr.span, None) =>\n                {\n                    return ControlFlow::Break(());\n                },\n                _ => {},\n            }\n            ControlFlow::Continue(())\n        });\n    }\n}\n\n/// Checks for `unwrap_or(T::new())`, `unwrap_or(T::default())`,\n/// `or_insert(T::new())` or `or_insert(T::default())`.\n/// Similarly checks for `unwrap_or_else(T::new)`, `unwrap_or_else(T::default)`,\n/// `or_insert_with(T::new)` or `or_insert_with(T::default)`.\n#[expect(clippy::too_many_arguments)]\nfn check_unwrap_or_default(\n    cx: &LateContext<'_>,\n    name: Symbol,\n    receiver: &hir::Expr<'_>,\n    fun: &hir::Expr<'_>,\n    call_expr: Option<&hir::Expr<'_>>,\n    span: Span,\n    method_span: Span,\n    msrv: Msrv,\n) -> bool {\n    let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver).peel_refs();\n\n    // Check MSRV, but only for `Result::unwrap_or_default`\n    if receiver_ty.is_diag_item(cx, sym::Result) && !msrv.meets(cx, msrvs::RESULT_UNWRAP_OR_DEFAULT) {\n        return false;\n    }\n\n    if !expr_type_is_certain(cx, receiver) {\n        return false;\n    }\n\n    let is_new = |fun: &hir::Expr<'_>| {\n        if let hir::ExprKind::Path(ref qpath) = fun.kind {\n            let path = last_path_segment(qpath).ident.name;\n            matches!(path, sym::new)\n        } else {\n            false\n        }\n    };\n\n    let output_type_implements_default = |fun| {\n        let fun_ty = cx.typeck_results().expr_ty(fun);\n        if let ty::FnDef(def_id, args) = *fun_ty.kind() {\n            let output_ty = cx.tcx.fn_sig(def_id).instantiate(cx.tcx, args).skip_binder().output();\n            cx.tcx\n                .get_diagnostic_item(sym::Default)\n                .is_some_and(|default_trait_id| implements_trait(cx, output_ty, default_trait_id, &[]))\n        } else {\n            false\n        }\n    };\n\n    let sugg = match (name, call_expr.is_some()) {\n        (sym::unwrap_or, true) | (sym::unwrap_or_else, false) => sym::unwrap_or_default,\n        (sym::or_insert, true) | (sym::or_insert_with, false) => sym::or_default,\n        _ => return false,\n    };\n\n    let Some(suggested_method_def_id) = receiver_ty.ty_adt_def().and_then(|adt_def| {\n        cx.tcx\n            .inherent_impls(adt_def.did())\n            .iter()\n            .flat_map(|&impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))\n            .find_map(|assoc| {\n                if assoc.is_method() && cx.tcx.fn_sig(assoc.def_id).skip_binder().inputs().skip_binder().len() == 1 {\n                    Some(assoc.def_id)\n                } else {\n                    None\n                }\n            })\n    }) else {\n        return false;\n    };\n    let in_sugg_method_implementation = {\n        matches!(\n            suggested_method_def_id.as_local(),\n            Some(local_def_id) if local_def_id == cx.tcx.hir_get_parent_item(receiver.hir_id).def_id\n        )\n    };\n    if in_sugg_method_implementation {\n        return false;\n    }\n\n    // `.unwrap_or(vec![])` is as readable as `.unwrap_or_default()`. And if the expression is a\n    // non-empty `Vec`, then it will not be a default value anyway. Bail out in all cases.\n    if call_expr.and_then(|call_expr| VecArgs::hir(cx, call_expr)).is_some() {\n        return false;\n    }\n\n    // needs to target Default::default in particular or be *::new and have a Default impl\n    // available\n    if (is_new(fun) && output_type_implements_default(fun))\n        || match call_expr {\n            Some(call_expr) => is_default_equivalent(cx, call_expr),\n            None => is_default_equivalent_call(cx, fun, None) || closure_body_returns_empty_to_string(cx, fun),\n        }\n    {\n        span_lint_and_sugg(\n            cx,\n            UNWRAP_OR_DEFAULT,\n            method_span.with_hi(span.hi()),\n            format!(\"use of `{name}` to construct default value\"),\n            \"try\",\n            format!(\"{sugg}()\"),\n            Applicability::MachineApplicable,\n        );\n\n        true\n    } else {\n        false\n    }\n}\n\n/// Checks for `*or(foo())`.\n#[expect(clippy::too_many_arguments)]\nfn check_or_fn_call<'tcx>(\n    cx: &LateContext<'tcx>,\n    name: Symbol,\n    method_span: Span,\n    self_expr: &hir::Expr<'_>,\n    arg: &'tcx hir::Expr<'_>,\n    // `Some` if fn has second argument\n    second_arg: Option<&hir::Expr<'_>>,\n    span: Span,\n    // None if lambda is required\n    fun_span: Option<Span>,\n) -> bool {\n    // (path, fn_has_argument, methods, suffix)\n    const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 7] = [\n        (sym::BTreeEntry, false, &[sym::or_insert], \"with\"),\n        (sym::HashMapEntry, false, &[sym::or_insert], \"with\"),\n        (\n            sym::Option,\n            false,\n            &[sym::map_or, sym::ok_or, sym::or, sym::unwrap_or],\n            \"else\",\n        ),\n        (sym::Option, false, &[sym::get_or_insert], \"with\"),\n        (sym::Option, true, &[sym::and], \"then\"),\n        (sym::Result, true, &[sym::map_or, sym::or, sym::unwrap_or], \"else\"),\n        (sym::Result, true, &[sym::and], \"then\"),\n    ];\n\n    if KNOW_TYPES.iter().any(|k| k.2.contains(&name))\n        && switch_to_lazy_eval(cx, arg)\n        && !contains_return(arg)\n        && let self_ty = cx.typeck_results().expr_ty(self_expr)\n        && let Some(&(_, fn_has_arguments, _, suffix)) = KNOW_TYPES\n            .iter()\n            .find(|&&i| self_ty.is_diag_item(cx, i.0) && i.2.contains(&name))\n    {\n        let ctxt = span.ctxt();\n        let mut app = Applicability::HasPlaceholders;\n        let sugg = {\n            let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) {\n                (false, Some(fun_span)) => (fun_span, false),\n                _ => (arg.span, true),\n            };\n\n            let snip = snippet_with_context(cx, snippet_span, ctxt, \"..\", &mut app).0;\n            let snip = if use_lambda {\n                let l_arg = if fn_has_arguments { \"_\" } else { \"\" };\n                format!(\"|{l_arg}| {snip}\")\n            } else {\n                snip.into_owned()\n            };\n\n            if let Some(f) = second_arg {\n                let f = snippet_with_context(cx, f.span, ctxt, \"..\", &mut app).0;\n                format!(\"{snip}, {f}\")\n            } else {\n                snip\n            }\n        };\n        let span_replace_word = method_span.with_hi(span.hi());\n        span_lint_and_sugg(\n            cx,\n            OR_FUN_CALL,\n            span_replace_word,\n            format!(\"function call inside of `{name}`\"),\n            \"try\",\n            format!(\"{name}_{suffix}({sugg})\"),\n            app,\n        );\n        true\n    } else {\n        false\n    }\n}\n\nfn closure_body_returns_empty_to_string(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> bool {\n    if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = e.kind {\n        let body = cx.tcx.hir_body(body);\n\n        if body.params.is_empty()\n            && let hir::Expr { kind, .. } = &body.value\n            && let hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, self_arg, [], _) = kind\n            && ident.name == sym::to_string\n            && let hir::Expr { kind, .. } = self_arg\n            && let hir::ExprKind::Lit(lit) = kind\n            && let ast::LitKind::Str(rustc_span::sym::empty, _) = lit.node\n        {\n            return true;\n        }\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/or_then_unwrap.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::lang_items::LangItem;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, sym};\n\nuse super::OR_THEN_UNWRAP;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    unwrap_expr: &Expr<'_>,\n    recv: &'tcx Expr<'tcx>,\n    or_arg: &'tcx Expr<'_>,\n    or_span: Span,\n) {\n    let ty = cx.typeck_results().expr_ty(recv); // get type of x (we later check if it's Option or Result)\n    let title;\n    let or_arg_content: Span;\n\n    match ty.opt_diag_name(cx) {\n        Some(sym::Option) => {\n            title = \"found `.or(Some(…)).unwrap()`\";\n            if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::OptionSome) {\n                or_arg_content = content;\n            } else {\n                return;\n            }\n        },\n        Some(sym::Result) => {\n            title = \"found `.or(Ok(…)).unwrap()`\";\n            if let Some(content) = get_content_if_ctor_matches(cx, or_arg, LangItem::ResultOk) {\n                or_arg_content = content;\n            } else {\n                return;\n            }\n        },\n        _ => {\n            // Someone has implemented a struct with .or(...).unwrap() chaining,\n            // but it's not an Option or a Result, so bail\n            return;\n        },\n    }\n\n    let mut applicability = Applicability::MachineApplicable;\n    let suggestion = format!(\n        \"unwrap_or({})\",\n        snippet_with_applicability(cx, or_arg_content, \"..\", &mut applicability)\n    );\n\n    span_lint_and_sugg(\n        cx,\n        OR_THEN_UNWRAP,\n        unwrap_expr.span.with_lo(or_span.lo()),\n        title,\n        \"try\",\n        suggestion,\n        applicability,\n    );\n}\n\nfn get_content_if_ctor_matches(cx: &LateContext<'_>, expr: &Expr<'_>, item: LangItem) -> Option<Span> {\n    if let ExprKind::Call(some_expr, [arg]) = expr.kind\n        && some_expr.res(cx).ctor_parent(cx).is_lang_item(cx, item)\n    {\n        Some(arg.span.source_callsite())\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/path_buf_push_overwrite.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse std::path::{Component, Path};\n\nuse super::PATH_BUF_PUSH_OVERWRITE;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && cx\n            .tcx\n            .type_of(impl_id)\n            .instantiate_identity()\n            .is_diag_item(cx, sym::PathBuf)\n        && let ExprKind::Lit(lit) = arg.kind\n        && let LitKind::Str(ref path_lit, _) = lit.node\n        && let pushed_path = Path::new(path_lit.as_str())\n        && let Some(pushed_path_lit) = pushed_path.to_str()\n        && pushed_path.has_root()\n        && let Some(root) = pushed_path.components().next()\n        && root == Component::RootDir\n    {\n        span_lint_and_sugg(\n            cx,\n            PATH_BUF_PUSH_OVERWRITE,\n            lit.span,\n            \"calling `push` with '/' or '\\\\' (file system root) will overwrite the previous path definition\",\n            \"try\",\n            format!(\"\\\"{}\\\"\", pushed_path_lit.trim_start_matches(['/', '\\\\'])),\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/path_ends_with_ext.rs",
    "content": "use super::PATH_ENDS_WITH_EXT;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sym;\nuse rustc_ast::{LitKind, StrStyle};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse std::fmt::Write;\n\npub const DEFAULT_ALLOWED_DOTFILES: &[&str] = &[\n    \"git\", \"svn\", \"gem\", \"npm\", \"vim\", \"env\", \"rnd\", \"ssh\", \"vnc\", \"smb\", \"nvm\", \"bin\",\n];\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    recv: &Expr<'_>,\n    path: &Expr<'_>,\n    expr: &Expr<'_>,\n    msrv: Msrv,\n    allowed_dotfiles: &FxHashSet<&'static str>,\n) {\n    if cx\n        .typeck_results()\n        .expr_ty(recv)\n        .peel_refs()\n        .is_diag_item(cx, sym::Path)\n        && !path.span.from_expansion()\n        && let ExprKind::Lit(lit) = path.kind\n        && let LitKind::Str(path, StrStyle::Cooked) = lit.node\n        && let Some(path) = path.as_str().strip_prefix('.')\n        && (1..=3).contains(&path.len())\n        && !allowed_dotfiles.contains(path)\n        && path.chars().all(char::is_alphanumeric)\n    {\n        let mut sugg = snippet(cx, recv.span, \"..\").into_owned();\n        if msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) {\n            let _ = write!(sugg, r#\".extension().is_some_and(|ext| ext == \"{path}\")\"#);\n        } else {\n            let _ = write!(sugg, r#\".extension().map_or(false, |ext| ext == \"{path}\")\"#);\n        }\n\n        span_lint_and_sugg(\n            cx,\n            PATH_ENDS_WITH_EXT,\n            expr.span,\n            \"this looks like a failed attempt at checking for the file extension\",\n            \"try\",\n            sugg,\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/ptr_offset_by_literal.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::sym;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Lit, UnOp};\nuse rustc_lint::LateContext;\nuse std::cmp::Ordering;\nuse std::fmt;\n\nuse super::PTR_OFFSET_BY_LITERAL;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Msrv) {\n    // `pointer::add` and `pointer::wrapping_add` are only stable since 1.26.0. These functions\n    // became const-stable in 1.61.0, the same version that `pointer::offset` became const-stable.\n    if !msrv.meets(cx, msrvs::POINTER_ADD_SUB_METHODS) {\n        return;\n    }\n\n    let ExprKind::MethodCall(method_name, recv, [arg_expr], _) = expr.kind else {\n        return;\n    };\n\n    let method = match method_name.ident.name {\n        sym::offset => Method::Offset,\n        sym::wrapping_offset => Method::WrappingOffset,\n        _ => return,\n    };\n\n    if !cx.typeck_results().expr_ty_adjusted(recv).is_raw_ptr() {\n        return;\n    }\n\n    // Check if the argument to the method call is a (negated) literal.\n    let Some((literal, literal_text)) = expr_as_literal(cx, arg_expr) else {\n        return;\n    };\n\n    match method.suggestion(literal) {\n        None => {\n            let msg = format!(\"use of `{method}` with zero\");\n            span_lint_and_then(cx, PTR_OFFSET_BY_LITERAL, expr.span, msg, |diag| {\n                diag.span_suggestion(\n                    expr.span.with_lo(recv.span.hi()),\n                    format!(\"remove the call to `{method}`\"),\n                    String::new(),\n                    Applicability::MachineApplicable,\n                );\n            });\n        },\n        Some(method_suggestion) => {\n            let msg = format!(\"use of `{method}` with a literal\");\n            span_lint_and_then(cx, PTR_OFFSET_BY_LITERAL, expr.span, msg, |diag| {\n                diag.multipart_suggestion(\n                    format!(\"use `{method_suggestion}` instead\"),\n                    vec![\n                        (method_name.ident.span, method_suggestion.to_string()),\n                        (arg_expr.span, literal_text),\n                    ],\n                    Applicability::MachineApplicable,\n                );\n            });\n        },\n    }\n}\n\nfn get_literal_bits<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<u128> {\n    match expr.kind {\n        ExprKind::Lit(Lit {\n            node: LitKind::Int(packed_u128, _),\n            ..\n        }) => Some(packed_u128.get()),\n        _ => None,\n    }\n}\n\n// If the given expression is a (negated) literal, return its value.\nfn expr_as_literal<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<(i128, String)> {\n    if let Some(literal_bits) = get_literal_bits(expr) {\n        // The value must fit in a isize, so we can't have overflow here.\n        return Some((literal_bits.cast_signed(), format_isize_literal(cx, expr)?));\n    }\n\n    if let ExprKind::Unary(UnOp::Neg, inner) = expr.kind\n        && let Some(literal_bits) = get_literal_bits(inner)\n    {\n        return Some((-(literal_bits.cast_signed()), format_isize_literal(cx, inner)?));\n    }\n\n    None\n}\n\nfn format_isize_literal<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<String> {\n    let text = expr.span.get_source_text(cx)?;\n    let text = peel_parens_str(&text);\n    Some(text.trim_end_matches(\"isize\").trim_end_matches('_').to_string())\n}\n\nfn peel_parens_str(snippet: &str) -> &str {\n    let mut s = snippet.trim();\n    while let Some(next) = s.strip_prefix(\"(\").and_then(|suf| suf.strip_suffix(\")\")) {\n        s = next.trim();\n    }\n    s\n}\n\n#[derive(Copy, Clone)]\nenum Method {\n    Offset,\n    WrappingOffset,\n}\n\nimpl Method {\n    fn suggestion(self, literal: i128) -> Option<&'static str> {\n        match Ord::cmp(&literal, &0) {\n            Ordering::Greater => match self {\n                Method::Offset => Some(\"add\"),\n                Method::WrappingOffset => Some(\"wrapping_add\"),\n            },\n            // `ptr.offset(0)` is equivalent to `ptr`, so no adjustment is needed\n            Ordering::Equal => None,\n            Ordering::Less => match self {\n                Method::Offset => Some(\"sub\"),\n                Method::WrappingOffset => Some(\"wrapping_sub\"),\n            },\n        }\n    }\n}\n\nimpl fmt::Display for Method {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::Offset => write!(f, \"offset\"),\n            Self::WrappingOffset => write!(f, \"wrapping_offset\"),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/ptr_offset_with_cast.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Symbol;\nuse std::fmt;\n\nuse super::PTR_OFFSET_WITH_CAST;\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    method: Symbol,\n    expr: &Expr<'_>,\n    recv: &Expr<'_>,\n    arg: &Expr<'_>,\n    msrv: Msrv,\n) {\n    // `pointer::add` and `pointer::wrapping_add` are only stable since 1.26.0. These functions\n    // became const-stable in 1.61.0, the same version that `pointer::offset` became const-stable.\n    if !msrv.meets(cx, msrvs::POINTER_ADD_SUB_METHODS) {\n        return;\n    }\n\n    let method = match method {\n        sym::offset => Method::Offset,\n        sym::wrapping_offset => Method::WrappingOffset,\n        _ => return,\n    };\n\n    if !cx.typeck_results().expr_ty_adjusted(recv).is_raw_ptr() {\n        return;\n    }\n\n    // Check if the argument to the method call is a cast from usize.\n    let cast_lhs_expr = match arg.kind {\n        ExprKind::Cast(lhs, _) if cx.typeck_results().expr_ty(lhs).is_usize() => lhs,\n        _ => return,\n    };\n\n    let ExprKind::MethodCall(method_name, _, _, _) = expr.kind else {\n        return;\n    };\n\n    let msg = format!(\"use of `{method}` with a `usize` casted to an `isize`\");\n    span_lint_and_then(cx, PTR_OFFSET_WITH_CAST, expr.span, msg, |diag| {\n        diag.multipart_suggestion(\n            format!(\"use `{}` instead\", method.suggestion()),\n            vec![\n                (method_name.ident.span, method.suggestion().to_string()),\n                (arg.span.with_lo(cast_lhs_expr.span.hi()), String::new()),\n            ],\n            Applicability::MachineApplicable,\n        );\n    });\n}\n\n#[derive(Copy, Clone)]\nenum Method {\n    Offset,\n    WrappingOffset,\n}\n\nimpl Method {\n    #[must_use]\n    fn suggestion(self) -> &'static str {\n        match self {\n            Self::Offset => \"add\",\n            Self::WrappingOffset => \"wrapping_add\",\n        }\n    }\n}\n\nimpl fmt::Display for Method {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Self::Offset => write!(f, \"offset\"),\n            Self::WrappingOffset => write!(f, \"wrapping_offset\"),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/range_zip_with_len.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::{SpanRangeExt as _, snippet_with_applicability};\nuse clippy_utils::{SpanlessEq, get_parent_expr, higher, is_integer_const, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Node, Pat, PatKind, QPath};\nuse rustc_lint::LateContext;\n\nuse super::RANGE_ZIP_WITH_LEN;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, zip_arg: &'tcx Expr<'_>) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        // range expression in `.zip()` call: `0..x.len()`\n        && let Some(higher::Range { start: Some(start), end: Some(end), .. }) = higher::Range::hir(cx, zip_arg)\n        && is_integer_const(cx, start, 0)\n        // `.len()` call\n        && let ExprKind::MethodCall(len_path, len_recv, [], _) = end.kind\n        && len_path.ident.name == sym::len\n        // `.iter()` and `.len()` called on same `Path`\n        && let ExprKind::Path(QPath::Resolved(_, iter_path)) = recv.kind\n        && let ExprKind::Path(QPath::Resolved(_, len_path)) = len_recv.kind\n        && SpanlessEq::new(cx).eq_path_segments(iter_path.segments, len_path.segments)\n    {\n        span_lint_and_then(\n            cx,\n            RANGE_ZIP_WITH_LEN,\n            expr.span,\n            \"using `.zip()` with a range and `.len()`\",\n            |diag| {\n                // If the iterator content is consumed by a pattern with exactly two elements, swap\n                // the order of those elements. Otherwise, the suggestion will be marked as\n                // `Applicability::MaybeIncorrect` (because it will be), and a note will be added\n                // to the diagnostic to underline the swapping of the index and the content.\n                let pat = methods_pattern(cx, expr).or_else(|| for_loop_pattern(cx, expr));\n                let invert_bindings = if let Some(pat) = pat\n                    && pat.span.eq_ctxt(expr.span)\n                    && let PatKind::Tuple([first, second], _) = pat.kind\n                {\n                    Some((first.span, second.span))\n                } else {\n                    None\n                };\n                let mut app = Applicability::MachineApplicable;\n                let mut suggestions = vec![(\n                    expr.span,\n                    format!(\n                        \"{}.iter().enumerate()\",\n                        snippet_with_applicability(cx, recv.span, \"_\", &mut app)\n                    ),\n                )];\n                if let Some((left, right)) = invert_bindings\n                    && let Some(snip_left) = left.get_source_text(cx)\n                    && let Some(snip_right) = right.get_source_text(cx)\n                {\n                    suggestions.extend([(left, snip_right.to_string()), (right, snip_left.to_string())]);\n                } else {\n                    app = Applicability::MaybeIncorrect;\n                }\n                diag.multipart_suggestion(\"use\", suggestions, app);\n                if app != Applicability::MachineApplicable {\n                    diag.note(\"the order of the element and the index will be swapped\");\n                }\n            },\n        );\n    }\n}\n\n/// If `expr` is the argument of a `for` loop, return the loop pattern.\nfn for_loop_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Pat<'tcx>> {\n    cx.tcx.hir_parent_iter(expr.hir_id).find_map(|(_, node)| {\n        if let Node::Expr(ancestor_expr) = node\n            && let Some(for_loop) = higher::ForLoop::hir(ancestor_expr)\n            && for_loop.arg.hir_id == expr.hir_id\n        {\n            Some(for_loop.pat)\n        } else {\n            None\n        }\n    })\n}\n\n/// If `expr` is the receiver of an `Iterator` method which consumes the iterator elements and feed\n/// them to a closure, return the pattern of the closure.\nfn methods_pattern<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Pat<'tcx>> {\n    if let Some(parent_expr) = get_parent_expr(cx, expr)\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let ExprKind::MethodCall(method, recv, [arg], _) = parent_expr.kind\n        && recv.hir_id == expr.hir_id\n        && matches!(\n            method.ident.name,\n            sym::all\n                | sym::any\n                | sym::filter_map\n                | sym::find_map\n                | sym::flat_map\n                | sym::for_each\n                | sym::is_partitioned\n                | sym::is_sorted_by_key\n                | sym::map\n                | sym::map_while\n                | sym::position\n                | sym::rposition\n                | sym::try_for_each\n        )\n        && let ExprKind::Closure(closure) = arg.kind\n        && let body = cx.tcx.hir_body(closure.body)\n        && let [param] = body.params\n    {\n        Some(param.pat)\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/read_line_without_trim.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse clippy_utils::visitors::for_each_local_use_after_expr;\nuse clippy_utils::{get_parent_expr, sym};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::READ_LINE_WITHOUT_TRIM;\n\nfn expr_is_string_literal_without_trailing_newline(expr: &Expr<'_>) -> bool {\n    if let ExprKind::Lit(lit) = expr.kind\n        && let LitKind::Str(sym, _) = lit.node\n    {\n        !sym.as_str().ends_with('\\n')\n    } else {\n        false\n    }\n}\n\n/// Will a `.parse::<ty>()` call fail if the input has a trailing newline?\nfn parse_fails_on_trailing_newline(ty: Ty<'_>) -> bool {\n    // only allow a very limited set of types for now, for which we 100% know parsing will fail\n    matches!(ty.kind(), ty::Float(_) | ty::Bool | ty::Int(_) | ty::Uint(_))\n}\n\npub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) {\n    let recv_ty = cx.typeck_results().expr_ty(recv);\n    if recv_ty.is_diag_item(cx, sym::Stdin)\n        && let ExprKind::Path(QPath::Resolved(_, path)) = arg.peel_borrows().kind\n        && let Res::Local(local_id) = path.res\n    {\n        // We've checked that `call` is a call to `Stdin::read_line()` with the right receiver,\n        // now let's check if the first use of the string passed to `::read_line()`\n        // is used for operations that will always fail (e.g. parsing \"6\\n\" into a number)\n        let _ = for_each_local_use_after_expr(cx, local_id, call.hir_id, |expr| {\n            if let Some(parent) = get_parent_expr(cx, expr) {\n                let data = if let ExprKind::MethodCall(segment, recv, args, span) = parent.kind {\n                    if args.is_empty()\n                        && segment.ident.name == sym::parse\n                        && let parse_result_ty = cx.typeck_results().expr_ty(parent)\n                        && parse_result_ty.is_diag_item(cx, sym::Result)\n                        && let ty::Adt(_, substs) = parse_result_ty.kind()\n                        && let Some(ok_ty) = substs[0].as_type()\n                        && parse_fails_on_trailing_newline(ok_ty)\n                    {\n                        // Called `s.parse::<T>()` where `T` is a type we know for certain will fail\n                        // if the input has a trailing newline\n                        Some((\n                            span,\n                            \"calling `.parse()` on a string without trimming the trailing newline character\",\n                            \"checking\",\n                        ))\n                    } else if segment.ident.name == sym::ends_with\n                        && recv.span == expr.span\n                        && let [arg] = args\n                        && expr_is_string_literal_without_trailing_newline(arg)\n                    {\n                        // Called `s.ends_with(<some string literal>)` where the argument is a string literal that does\n                        // not end with a newline, thus always evaluating to false\n                        Some((\n                            parent.span,\n                            \"checking the end of a string without trimming the trailing newline character\",\n                            \"parsing\",\n                        ))\n                    } else {\n                        None\n                    }\n                } else if let ExprKind::Binary(binop, left, right) = parent.kind\n                    && let BinOpKind::Eq = binop.node\n                    && (expr_is_string_literal_without_trailing_newline(left)\n                        || expr_is_string_literal_without_trailing_newline(right))\n                {\n                    // `s == <some string literal>` where the string literal does not end with a newline\n                    Some((\n                        parent.span,\n                        \"comparing a string literal without trimming the trailing newline character\",\n                        \"comparison\",\n                    ))\n                } else {\n                    None\n                };\n\n                if let Some((primary_span, lint_message, operation)) = data {\n                    span_lint_and_then(cx, READ_LINE_WITHOUT_TRIM, primary_span, lint_message, |diag| {\n                        let local_snippet = snippet(cx, expr.span, \"<expr>\");\n\n                        diag.span_note(\n                            call.span,\n                            format!(\n                                \"call to `.read_line()` here, \\\n                                which leaves a trailing newline character in the buffer, \\\n                                which in turn will cause the {operation} to always fail\"\n                            ),\n                        );\n\n                        diag.span_suggestion(\n                            expr.span,\n                            \"try\",\n                            format!(\"{local_snippet}.trim_end()\"),\n                            Applicability::MachineApplicable,\n                        );\n                    });\n                }\n            }\n\n            // only consider the first use to prevent this scenario:\n            // ```\n            // let mut s = String::new();\n            // std::io::stdin().read_line(&mut s);\n            // s.pop();\n            // let _x: i32 = s.parse().unwrap();\n            // ```\n            // this is actually fine, because the pop call removes the trailing newline.\n            ControlFlow::<(), ()>::Break(())\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/readonly_write_lock.rs",
    "content": "use super::READONLY_WRITE_LOCK;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::mir::{enclosing_mir, visit_local_usage};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Node, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::{Location, START_BLOCK};\nuse rustc_span::sym;\n\nfn is_unwrap_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let ExprKind::MethodCall(path, receiver, [], _) = expr.kind\n        && path.ident.name == sym::unwrap\n    {\n        cx.typeck_results()\n            .expr_ty(receiver)\n            .peel_refs()\n            .is_diag_item(cx, sym::Result)\n    } else {\n        false\n    }\n}\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver: &Expr<'_>) {\n    if cx.typeck_results().expr_ty(receiver).peel_refs().is_diag_item(cx, sym::RwLock)\n        && let Node::Expr(unwrap_call_expr) = cx.tcx.parent_hir_node(expr.hir_id)\n        && is_unwrap_call(cx, unwrap_call_expr)\n        && let parent = cx.tcx.parent_hir_node(unwrap_call_expr.hir_id)\n        && let Node::LetStmt(local) = parent\n        && let PatKind::Binding(.., ident, _) = local.pat.kind\n        // if the binding is prefixed with `_`, it typically means\n        // that this guard only exists to protect a section of code\n        // rather than the contained data\n        && !ident.as_str().starts_with('_')\n        && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id)\n        && let Some((local, _)) = mir\n            .local_decls\n            .iter_enumerated()\n            .find(|(_, decl)| local.span.contains(decl.source_info.span))\n        && let Some([usage]) = visit_local_usage(\n            [local],\n            mir,\n            Location {\n                block: START_BLOCK,\n                statement_index: 0,\n            },\n        )\n    {\n        let writer_never_mutated = usage.local_consume_or_mutate_locs.is_empty();\n\n        if writer_never_mutated {\n            span_lint_and_sugg(\n                cx,\n                READONLY_WRITE_LOCK,\n                expr.span,\n                \"this write lock is used only for reading\",\n                \"consider using a read lock instead\",\n                format!(\"{}.read()\", snippet(cx, receiver.span, \"<receiver>\")),\n                Applicability::MaybeIncorrect, // write lock might be intentional for enforcing exclusiveness\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/redundant_as_str.rs",
    "content": "use super::REDUNDANT_AS_STR;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    _expr: &Expr<'_>,\n    recv: &Expr<'_>,\n    as_str_span: Span,\n    other_method_span: Span,\n) {\n    if cx\n        .typeck_results()\n        .expr_ty(recv)\n        .ty_adt_def()\n        .is_some_and(|adt| Some(adt.did()) == cx.tcx.lang_items().string())\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            REDUNDANT_AS_STR,\n            as_str_span.to(other_method_span),\n            \"this `as_str` is redundant and can be removed as the method immediately following exists on `String` too\",\n            \"try\",\n            snippet_with_applicability(cx, other_method_span, \"..\", &mut applicability).into_owned(),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/repeat_once.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, LangItem};\nuse rustc_lint::LateContext;\n\nuse super::REPEAT_ONCE;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    recv: &'tcx Expr<'_>,\n    repeat_arg: &'tcx Expr<'_>,\n) {\n    if ConstEvalCtxt::new(cx).eval_local(repeat_arg, expr.span.ctxt()) == Some(Constant::Int(1)) {\n        let ty = cx.typeck_results().expr_ty(recv).peel_refs();\n        if ty.is_str() {\n            span_lint_and_sugg(\n                cx,\n                REPEAT_ONCE,\n                expr.span,\n                \"calling `repeat(1)` on str\",\n                \"consider using `.to_string()` instead\",\n                format!(\"{}.to_string()\", snippet(cx, recv.span, r#\"\"...\"\"#)),\n                Applicability::MachineApplicable,\n            );\n        } else if ty.builtin_index().is_some() {\n            span_lint_and_sugg(\n                cx,\n                REPEAT_ONCE,\n                expr.span,\n                \"calling `repeat(1)` on slice\",\n                \"consider using `.to_vec()` instead\",\n                format!(\"{}.to_vec()\", snippet(cx, recv.span, r#\"\"...\"\"#)),\n                Applicability::MachineApplicable,\n            );\n        } else if ty.is_lang_item(cx, LangItem::String) {\n            span_lint_and_sugg(\n                cx,\n                REPEAT_ONCE,\n                expr.span,\n                \"calling `repeat(1)` on a string literal\",\n                \"consider using `.clone()` instead\",\n                format!(\"{}.clone()\", snippet(cx, recv.span, r#\"\"...\"\"#)),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/result_map_or_else_none.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet;\nuse clippy_utils::{is_none_expr, peel_blocks};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::LangItem::OptionSome;\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::sym;\n\nuse super::RESULT_MAP_OR_INTO_OPTION;\n\n/// lint use of `_.map_or_else(|_| None, Some)` for `Result`s\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'_>,\n    def_arg: &'tcx hir::Expr<'_>,\n    map_arg: &'tcx hir::Expr<'_>,\n) {\n    // lint if the caller of `map_or_else()` is a `Result`\n    if cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result)\n        // We check that it is mapped as `Some`.\n        && map_arg.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)\n        && let hir::ExprKind::Closure(&hir::Closure { body, .. }) = def_arg.kind\n        && let body = cx.tcx.hir_body(body)\n        // And finally we check that we return a `None` in the \"else case\".\n        && is_none_expr(cx, peel_blocks(body.value))\n    {\n        let msg = \"called `map_or_else(|_| None, Some)` on a `Result` value\";\n        let self_snippet = snippet(cx, recv.span, \"..\");\n        span_lint_and_sugg(\n            cx,\n            RESULT_MAP_OR_INTO_OPTION,\n            expr.span,\n            msg,\n            \"consider using `ok`\",\n            format!(\"{self_snippet}.ok()\"),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/return_and_then.rs",
    "content": "use clippy_utils::res::MaybeDef;\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, Node};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, GenericArg, Ty};\nuse rustc_span::sym;\nuse std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};\nuse clippy_utils::visitors::for_each_unconsumed_temporary;\nuse clippy_utils::{peel_blocks, potential_return_of_enclosing_body};\n\nuse super::RETURN_AND_THEN;\n\n/// lint if `and_then` is the last expression in a block, and\n/// there are no references or temporaries in the receiver\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'tcx>,\n    arg: &'tcx hir::Expr<'_>,\n) {\n    if !potential_return_of_enclosing_body(cx, expr) {\n        return;\n    }\n\n    let recv_type = cx.typeck_results().expr_ty(recv);\n    if !matches!(recv_type.opt_diag_name(cx), Some(sym::Option | sym::Result)) {\n        return;\n    }\n\n    let has_ref_type = matches!(recv_type.kind(), ty::Adt(_, args) if args\n        .first()\n        .and_then(|arg0: &GenericArg<'tcx>| GenericArg::as_type(*arg0))\n        .is_some_and(Ty::is_ref));\n    let has_temporaries = for_each_unconsumed_temporary(cx, recv, |_| ControlFlow::Break(())).is_break();\n    if has_ref_type && has_temporaries {\n        return;\n    }\n\n    let hir::ExprKind::Closure(&hir::Closure { body, fn_decl, .. }) = arg.kind else {\n        return;\n    };\n\n    let closure_arg = fn_decl.inputs[0];\n    let closure_expr = peel_blocks(cx.tcx.hir_body(body).value);\n\n    let mut applicability = Applicability::MachineApplicable;\n    let arg_snip = snippet_with_applicability(cx, closure_arg.span, \"_\", &mut applicability);\n    let recv_snip = snippet_with_applicability(cx, recv.span, \"_\", &mut applicability);\n    let body_snip = snippet_with_applicability(cx, closure_expr.span, \"..\", &mut applicability);\n    let inner = match body_snip.strip_prefix('{').and_then(|s| s.strip_suffix('}')) {\n        Some(s) => s.trim_start_matches('\\n').trim_end(),\n        None => &body_snip,\n    };\n\n    // If suggestion is going to get inserted as part of a `return` expression or as a match expression\n    // arm, it must be blockified.\n    let (parent_span_for_indent, opening_paren, closing_paren) = match cx.tcx.parent_hir_node(expr.hir_id) {\n        Node::Expr(parent_expr) if matches!(parent_expr.kind, hir::ExprKind::Break(..)) => {\n            (Some(parent_expr.span), \"(\", \")\")\n        },\n        Node::Expr(parent_expr) => (Some(parent_expr.span), \"\", \"\"),\n        Node::Arm(match_arm) => (Some(match_arm.span), \"\", \"\"),\n        _ => (None, \"\", \"\"),\n    };\n    let sugg = if let Some(span) = parent_span_for_indent {\n        let base_indent = indent_of(cx, span);\n        let inner_indent = base_indent.map(|i| i + 4);\n        format!(\n            \"{}\\n{}\\n{}\",\n            reindent_multiline(\n                &format!(\"{opening_paren}{{\\nlet {arg_snip} = {recv_snip}?;\"),\n                true,\n                inner_indent\n            ),\n            reindent_multiline(inner, false, inner_indent),\n            reindent_multiline(&format!(\"}}{closing_paren}\"), false, base_indent),\n        )\n    } else {\n        format!(\n            \"let {} = {}?;\\n{}\",\n            arg_snip,\n            recv_snip,\n            reindent_multiline(inner, false, indent_of(cx, expr.span))\n        )\n    };\n\n    span_lint_and_sugg(\n        cx,\n        RETURN_AND_THEN,\n        expr.span,\n        \"use the `?` operator instead of an `and_then` call\",\n        \"try\",\n        sugg,\n        applicability,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/search_is_some.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::{snippet, snippet_with_applicability};\nuse clippy_utils::sugg::deref_closure_args;\nuse clippy_utils::{is_receiver_of_method_call, strip_pat_refs, sym};\nuse hir::ExprKind;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::PatKind;\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, Symbol};\n\nuse super::SEARCH_IS_SOME;\n\n/// lint searching an Iterator followed by `is_some()`\n/// or calling `find()` on a string followed by `is_some()` or `is_none()`\n#[expect(clippy::too_many_arguments, clippy::too_many_lines)]\npub(super) fn check<'tcx>(\n    cx: &LateContext<'_>,\n    expr: &'tcx hir::Expr<'_>,\n    search_method: Symbol,\n    is_some: bool,\n    search_recv: &hir::Expr<'_>,\n    search_arg: &'tcx hir::Expr<'_>,\n    is_some_recv: &hir::Expr<'_>,\n    method_span: Span,\n) {\n    let option_check_method = if is_some { \"is_some\" } else { \"is_none\" };\n    // lint if caller of search is an Iterator\n    if cx\n        .ty_based_def(is_some_recv)\n        .opt_parent(cx)\n        .is_diag_item(cx, sym::Iterator)\n    {\n        let msg = format!(\"called `{option_check_method}()` after searching an `Iterator` with `{search_method}`\");\n        let search_snippet = snippet(cx, search_arg.span, \"..\");\n        // suggest `any(|x| ..)` instead of `any(|&x| ..)` for `find(|&x| ..).is_some()`\n        // suggest `any(|..| *..)` instead of `any(|..| **..)` for `find(|..| **..).is_some()`\n        let mut applicability = Applicability::MachineApplicable;\n        let any_search_snippet = if search_method == sym::find\n            && let ExprKind::Closure(&hir::Closure { body, .. }) = search_arg.kind\n            && let closure_body = cx.tcx.hir_body(body)\n            && let Some(closure_arg) = closure_body.params.first()\n        {\n            if let PatKind::Ref(..) = closure_arg.pat.kind {\n                Some(search_snippet.replacen('&', \"\", 1))\n            } else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind {\n                // `find()` provides a reference to the item, but `any` does not,\n                // so we should fix item usages for suggestion\n                if let Some(closure_sugg) = deref_closure_args(cx, search_arg) {\n                    applicability = closure_sugg.applicability;\n                    Some(closure_sugg.suggestion)\n                } else {\n                    Some(search_snippet.to_string())\n                }\n            } else {\n                None\n            }\n        } else {\n            None\n        };\n        // add note if not multi-line\n        if is_some {\n            span_lint_and_sugg(\n                cx,\n                SEARCH_IS_SOME,\n                method_span.with_hi(expr.span.hi()),\n                msg,\n                \"consider using\",\n                format!(\n                    \"any({})\",\n                    any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)\n                ),\n                applicability,\n            );\n        } else {\n            let iter = snippet(cx, search_recv.span, \"..\");\n            let sugg = if is_receiver_of_method_call(cx, expr) {\n                format!(\n                    \"(!{iter}.any({}))\",\n                    any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)\n                )\n            } else {\n                format!(\n                    \"!{iter}.any({})\",\n                    any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)\n                )\n            };\n            span_lint_and_sugg(\n                cx,\n                SEARCH_IS_SOME,\n                expr.span,\n                msg,\n                \"consider using\",\n                sugg,\n                applicability,\n            );\n        }\n    }\n    // lint if `find()` is called by `String` or `&str`\n    else if search_method == sym::find {\n        let is_string_or_str_slice = |e| {\n            let self_ty = cx.typeck_results().expr_ty(e).peel_refs();\n            if self_ty.is_lang_item(cx, hir::LangItem::String) {\n                true\n            } else {\n                self_ty.is_str()\n            }\n        };\n        if is_string_or_str_slice(search_recv) && is_string_or_str_slice(search_arg) {\n            let msg = format!(\"called `{option_check_method}()` after calling `find()` on a string\");\n            match option_check_method {\n                \"is_some\" => {\n                    let mut applicability = Applicability::MachineApplicable;\n                    let find_arg = snippet_with_applicability(cx, search_arg.span, \"..\", &mut applicability);\n                    span_lint_and_sugg(\n                        cx,\n                        SEARCH_IS_SOME,\n                        method_span.with_hi(expr.span.hi()),\n                        msg,\n                        \"consider using\",\n                        format!(\"contains({find_arg})\"),\n                        applicability,\n                    );\n                },\n                \"is_none\" => {\n                    let string = snippet(cx, search_recv.span, \"..\");\n                    let mut applicability = Applicability::MachineApplicable;\n                    let find_arg = snippet_with_applicability(cx, search_arg.span, \"..\", &mut applicability);\n                    let sugg = if is_receiver_of_method_call(cx, expr) {\n                        format!(\"(!{string}.contains({find_arg}))\")\n                    } else {\n                        format!(\"!{string}.contains({find_arg})\")\n                    };\n                    span_lint_and_sugg(\n                        cx,\n                        SEARCH_IS_SOME,\n                        expr.span,\n                        msg,\n                        \"consider using\",\n                        sugg,\n                        applicability,\n                    );\n                },\n                _ => (),\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/seek_from_current.rs",
    "content": "use rustc_ast::ast::{LitIntType, LitKind};\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{is_enum_variant_ctor, sym};\n\nuse super::SEEK_FROM_CURRENT;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {\n    let ty = cx.typeck_results().expr_ty(recv);\n\n    if let Some(def_id) = cx.tcx.get_diagnostic_item(sym::IoSeek)\n        && implements_trait(cx, ty, def_id, &[])\n        && arg_is_seek_from_current(cx, arg)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let snip = snippet_with_applicability(cx, recv.span, \"..\", &mut applicability);\n\n        span_lint_and_sugg(\n            cx,\n            SEEK_FROM_CURRENT,\n            expr.span,\n            \"using `SeekFrom::Current` to start from current position\",\n            \"replace with\",\n            format!(\"{snip}.stream_position()\"),\n            applicability,\n        );\n    }\n}\n\nfn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {\n    if let ExprKind::Call(f, [arg]) = expr.kind\n        && let ExprKind::Path(ref path) = f.kind\n        && let Some(ctor_call_id) = cx.qpath_res(path, f.hir_id).opt_def_id()\n        && is_enum_variant_ctor(cx, sym::SeekFrom, sym::Current, ctor_call_id)\n        // check if argument of `SeekFrom::Current` is `0`\n        && let ExprKind::Lit(lit) = arg.kind\n        && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node\n    {\n        return true;\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{is_enum_variant_ctor, is_expr_used_or_unified, sym};\nuse rustc_ast::ast::{LitIntType, LitKind};\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::SEEK_TO_START_INSTEAD_OF_REWIND;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    recv: &'tcx Expr<'_>,\n    arg: &'tcx Expr<'_>,\n    name_span: Span,\n) {\n    // Get receiver type\n    let ty = cx.typeck_results().expr_ty(recv).peel_refs();\n\n    if is_expr_used_or_unified(cx.tcx, expr) {\n        return;\n    }\n\n    if let Some(seek_trait_id) = cx.tcx.get_diagnostic_item(sym::IoSeek)\n        && implements_trait(cx, ty, seek_trait_id, &[])\n        && let ExprKind::Call(func, [arg]) = arg.kind\n        && let ExprKind::Path(ref path) = func.kind\n        && let Some(ctor_call_id) = cx.qpath_res(path, func.hir_id).opt_def_id()\n        && is_enum_variant_ctor(cx, sym::SeekFrom, sym::Start, ctor_call_id)\n        && let ExprKind::Lit(lit) = arg.kind\n        && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node\n    {\n        let method_call_span = expr.span.with_lo(name_span.lo());\n        span_lint_and_then(\n            cx,\n            SEEK_TO_START_INSTEAD_OF_REWIND,\n            method_call_span,\n            \"used `seek` to go to the start of the stream\",\n            |diag| {\n                let app = Applicability::MachineApplicable;\n\n                diag.span_suggestion(method_call_span, \"replace with\", \"rewind()\", app);\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/should_implement_trait.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::{is_bool, sym};\nuse rustc_abi::ExternAbi;\nuse rustc_hir::{self as hir, FnRetTy, FnSig, GenericParamKind, ImplItem, LifetimeParamKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::edition::Edition::{self, Edition2015, Edition2021};\nuse rustc_span::{Symbol, kw};\n\nuse super::SHOULD_IMPLEMENT_TRAIT;\nuse super::lib::SelfKind;\n\npub(super) fn check_impl_item<'tcx>(\n    cx: &LateContext<'tcx>,\n    impl_item: &'tcx ImplItem<'_>,\n    self_ty: Ty<'tcx>,\n    impl_implements_trait: bool,\n    first_arg_ty_opt: Option<Ty<'tcx>>,\n    sig: &FnSig<'_>,\n) {\n    // if this impl block implements a trait, lint in trait definition instead\n    if !impl_implements_trait && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)\n        // check missing trait implementations\n        && let Some(method_config) = TRAIT_METHODS.iter().find(|case| case.method_name == impl_item.ident.name)\n        && sig.decl.inputs.len() == method_config.param_count\n        && method_config.output_type.matches(&sig.decl.output)\n        // in case there is no first arg, since we already have checked the number of arguments\n        // it's should be always true\n        && first_arg_ty_opt\n            .is_none_or(|first_arg_ty| method_config.self_kind.matches(cx, self_ty, first_arg_ty))\n        && sig.header.is_safe()\n        && !sig.header.is_const()\n        && !sig.header.is_async()\n        && sig.header.abi == ExternAbi::Rust\n        && method_config.lifetime_param_cond(impl_item)\n        && method_config.in_prelude_since <= cx.tcx.sess.edition()\n    {\n        span_lint_and_help(\n            cx,\n            SHOULD_IMPLEMENT_TRAIT,\n            impl_item.span,\n            format!(\n                \"method `{}` can be confused for the standard trait method `{}::{}`\",\n                method_config.method_name, method_config.trait_name, method_config.method_name\n            ),\n            None,\n            format!(\n                \"consider implementing the trait `{}` or choosing a less ambiguous method name\",\n                method_config.trait_name\n            ),\n        );\n    }\n}\n\nstruct ShouldImplTraitCase {\n    trait_name: &'static str,\n    method_name: Symbol,\n    param_count: usize,\n    // implicit self kind expected (none, self, &self, ...)\n    self_kind: SelfKind,\n    // checks against the output type\n    output_type: OutType,\n    // certain methods with explicit lifetimes can't implement the equivalent trait method\n    lint_explicit_lifetime: bool,\n    in_prelude_since: Edition,\n}\n\nimpl ShouldImplTraitCase {\n    const fn new(\n        trait_name: &'static str,\n        method_name: Symbol,\n        param_count: usize,\n        self_kind: SelfKind,\n        output_type: OutType,\n        lint_explicit_lifetime: bool,\n        in_prelude_since: Edition,\n    ) -> ShouldImplTraitCase {\n        ShouldImplTraitCase {\n            trait_name,\n            method_name,\n            param_count,\n            self_kind,\n            output_type,\n            lint_explicit_lifetime,\n            in_prelude_since,\n        }\n    }\n\n    fn lifetime_param_cond(&self, impl_item: &ImplItem<'_>) -> bool {\n        self.lint_explicit_lifetime\n            || !impl_item.generics.params.iter().any(|p| {\n                matches!(\n                    p.kind,\n                    GenericParamKind::Lifetime {\n                        kind: LifetimeParamKind::Explicit\n                    }\n                )\n            })\n    }\n}\n\n#[rustfmt::skip]\nconst TRAIT_METHODS: [ShouldImplTraitCase; 30] = [\n    ShouldImplTraitCase::new(\"std::ops::Add\",           sym::add,        2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::convert::AsMut\",     sym::as_mut,     1,  SelfKind::RefMut, OutType::Ref,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::convert::AsRef\",     sym::as_ref,     1,  SelfKind::Ref,    OutType::Ref,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::BitAnd\",        sym::bitand,     2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::BitOr\",         sym::bitor,      2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::BitXor\",        sym::bitxor,     2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::borrow::Borrow\",     sym::borrow,     1,  SelfKind::Ref,    OutType::Ref,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::borrow::BorrowMut\",  sym::borrow_mut, 1,  SelfKind::RefMut, OutType::Ref,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::clone::Clone\",       sym::clone,      1,  SelfKind::Ref,    OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::cmp::Ord\",           sym::cmp,        2,  SelfKind::Ref,    OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::default::Default\",   kw::Default,     0,  SelfKind::No,     OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Deref\",         sym::deref,      1,  SelfKind::Ref,    OutType::Ref,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::DerefMut\",      sym::deref_mut,  1,  SelfKind::RefMut, OutType::Ref,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Div\",           sym::div,        2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Drop\",          sym::drop,       1,  SelfKind::RefMut, OutType::Unit, true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::cmp::PartialEq\",     sym::eq,         2,  SelfKind::Ref,    OutType::Bool, true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::iter::FromIterator\", sym::from_iter,  1,  SelfKind::No,     OutType::Any,  true,  Edition2021),\n    ShouldImplTraitCase::new(\"std::str::FromStr\",       sym::from_str,   1,  SelfKind::No,     OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::hash::Hash\",         sym::hash,       2,  SelfKind::Ref,    OutType::Unit, true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Index\",         sym::index,      2,  SelfKind::Ref,    OutType::Ref,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::IndexMut\",      sym::index_mut,  2,  SelfKind::RefMut, OutType::Ref,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::iter::IntoIterator\", sym::into_iter,  1,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Mul\",           sym::mul,        2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Neg\",           sym::neg,        1,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::iter::Iterator\",     sym::next,       1,  SelfKind::RefMut, OutType::Any,  false, Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Not\",           sym::not,        1,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Rem\",           sym::rem,        2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Shl\",           sym::shl,        2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Shr\",           sym::shr,        2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n    ShouldImplTraitCase::new(\"std::ops::Sub\",           sym::sub,        2,  SelfKind::Value,  OutType::Any,  true,  Edition2015),\n];\n\n#[derive(Clone, Copy)]\nenum OutType {\n    Unit,\n    Bool,\n    Any,\n    Ref,\n}\n\nimpl OutType {\n    fn matches(self, ty: &FnRetTy<'_>) -> bool {\n        let is_unit = |ty: &hir::Ty<'_>| matches!(ty.kind, hir::TyKind::Tup(&[]));\n        match (self, ty) {\n            (Self::Unit, &FnRetTy::DefaultReturn(_)) => true,\n            (Self::Unit, &FnRetTy::Return(ty)) if is_unit(ty) => true,\n            (Self::Bool, &FnRetTy::Return(ty)) if is_bool(ty) => true,\n            (Self::Any, &FnRetTy::Return(ty)) if !is_unit(ty) => true,\n            (Self::Ref, &FnRetTy::Return(ty)) => matches!(ty.kind, hir::TyKind::Ref(_, _)),\n            _ => false,\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/single_char_add_str.rs",
    "content": "use super::SINGLE_CHAR_ADD_STR;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{snippet_with_applicability, str_literal_to_char_literal};\nuse clippy_utils::sym;\nuse rustc_ast::BorrowKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, args: &[Expr<'_>]) {\n    if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {\n        let mut applicability = Applicability::MachineApplicable;\n        let (short_name, arg, extra) = match cx.tcx.get_diagnostic_name(fn_def_id) {\n            Some(sym::string_insert_str) => (\n                \"insert\",\n                &args[1],\n                Some(|applicability| {\n                    format!(\n                        \"{}, \",\n                        snippet_with_applicability(cx, args[0].span, \"..\", applicability)\n                    )\n                }),\n            ),\n            Some(sym::string_push_str) => (\"push\", &args[0], None),\n            _ => return,\n        };\n\n        if let Some(extension_string) = str_literal_to_char_literal(cx, arg, &mut applicability, false) {\n            let base_string_snippet =\n                snippet_with_applicability(cx, receiver.span.source_callsite(), \"_\", &mut applicability);\n            span_lint_and_sugg(\n                cx,\n                SINGLE_CHAR_ADD_STR,\n                expr.span,\n                format!(\"calling `{short_name}_str()` using a single-character string literal\"),\n                format!(\"consider using `{short_name}` with a character literal\"),\n                format!(\n                    \"{base_string_snippet}.{short_name}({}{extension_string})\",\n                    extra.map_or(String::new(), |f| f(&mut applicability))\n                ),\n                applicability,\n            );\n        } else if let ExprKind::AddrOf(BorrowKind::Ref, _, inner) = arg.kind\n            && let ExprKind::MethodCall(path_segment, method_arg, [], _) = inner.kind\n            && path_segment.ident.name == sym::to_string\n            && (is_ref_char(cx, method_arg) || is_char(cx, method_arg))\n        {\n            let base_string_snippet =\n                snippet_with_applicability(cx, receiver.span.source_callsite(), \"_\", &mut applicability);\n            let extension_string = match (\n                snippet_with_applicability(cx, method_arg.span.source_callsite(), \"_\", &mut applicability),\n                is_ref_char(cx, method_arg),\n            ) {\n                (snippet, false) => snippet,\n                (snippet, true) => format!(\"*{snippet}\").into(),\n            };\n            span_lint_and_sugg(\n                cx,\n                SINGLE_CHAR_ADD_STR,\n                expr.span,\n                format!(\"calling `{short_name}_str()` using a single-character converted to string\"),\n                format!(\"consider using `{short_name}` without `to_string()`\"),\n                format!(\n                    \"{base_string_snippet}.{short_name}({}{extension_string})\",\n                    extra.map_or(String::new(), |f| f(&mut applicability))\n                ),\n                applicability,\n            );\n        }\n    }\n}\n\nfn is_ref_char(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    matches!(cx.typeck_results().expr_ty(expr).kind(), ty::Ref(_, ty, _) if ty.is_char())\n}\n\nfn is_char(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    cx.typeck_results().expr_ty(expr).is_char()\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/skip_while_next.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::SKIP_WHILE_NEXT;\n\n/// lint use of `skip_while().next()` for `Iterators`\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n    // lint if caller of `.skip_while().next()` is an Iterator\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        span_lint_and_help(\n            cx,\n            SKIP_WHILE_NEXT,\n            expr.span,\n            \"called `skip_while(<p>).next()` on an `Iterator`\",\n            None,\n            \"this is more succinctly expressed by calling `.find(!<p>)` instead\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/sliced_string_as_bytes.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::higher;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem};\nuse rustc_lint::LateContext;\n\nuse super::SLICED_STRING_AS_BYTES;\n\n/// Checks if `index` is any type of range except `RangeFull` (i.e. `..`)\nfn is_bounded_range_literal(cx: &LateContext<'_>, index: &Expr<'_>) -> bool {\n    higher::Range::hir(cx, index).is_some_and(|range| Option::or(range.start, range.end).is_some())\n}\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>) {\n    if let ExprKind::Index(indexed, index, _) = recv.kind\n        && is_bounded_range_literal(cx, index)\n        && let ty = cx.typeck_results().expr_ty(indexed).peel_refs()\n        && (ty.is_str() || ty.is_lang_item(cx, LangItem::String))\n    {\n        let mut applicability = Applicability::MaybeIncorrect;\n        let stringish = snippet_with_applicability(cx, indexed.span, \"_\", &mut applicability);\n        let range = snippet_with_applicability(cx, index.span, \"_\", &mut applicability);\n        span_lint_and_sugg(\n            cx,\n            SLICED_STRING_AS_BYTES,\n            expr.span,\n            \"calling `as_bytes` after slicing a string\",\n            \"try\",\n            format!(\"&{stringish}.as_bytes()[{range}]\"),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/stable_sort_primitive.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_slice_of_primitives;\nuse clippy_utils::source::snippet_with_context;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\n\nuse super::STABLE_SORT_PRIMITIVE;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && cx.tcx.type_of(impl_id).instantiate_identity().is_slice()\n        && let Some(slice_type) = is_slice_of_primitives(cx, recv)\n    {\n        span_lint_and_then(\n            cx,\n            STABLE_SORT_PRIMITIVE,\n            e.span,\n            format!(\"used `sort` on primitive type `{slice_type}`\"),\n            |diag| {\n                let mut app = Applicability::MachineApplicable;\n                let recv_snip = snippet_with_context(cx, recv.span, e.span.ctxt(), \"..\", &mut app).0;\n                diag.span_suggestion(e.span, \"try\", format!(\"{recv_snip}.sort_unstable()\"), app);\n                diag.note(\n                    \"an unstable sort typically performs faster without any observable difference for this data type\",\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/str_split.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sym;\nuse clippy_utils::visitors::is_const_evaluatable;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::STR_SPLIT_AT_NEWLINE;\n\npub(super) fn check<'a>(\n    cx: &LateContext<'a>,\n    expr: &'_ Expr<'_>,\n    split_recv: &'a Expr<'_>,\n    split_span: Span,\n    split_arg: &'_ Expr<'_>,\n) {\n    // We're looking for `A.trim().split(B)`, where the adjusted type of `A` is `&str` (e.g. an\n    // expression returning `String`), and `B` is a `Pattern` that hard-codes a newline (either `\"\\n\"`\n    // or `\"\\r\\n\"`). There are a lot of ways to specify a pattern, and this lint only checks the most\n    // basic ones: a `'\\n'`, `\"\\n\"`, and `\"\\r\\n\"`.\n    if let ExprKind::MethodCall(trim_method_name, trim_recv, [], trim_span) = split_recv.kind\n        && trim_method_name.ident.name == sym::trim\n        && cx.typeck_results().expr_ty_adjusted(trim_recv).peel_refs().is_str()\n        && !is_const_evaluatable(cx, trim_recv)\n        && let ExprKind::Lit(split_lit) = split_arg.kind\n        && matches!(\n            split_lit.node,\n            LitKind::Char('\\n') | LitKind::Str(sym::LF | sym::CRLF, _)\n        )\n    {\n        span_lint_and_then(\n            cx,\n            STR_SPLIT_AT_NEWLINE,\n            expr.span,\n            \"using `str.trim().split()` with hard-coded newlines\",\n            |diag| {\n                diag.span_suggestion_verbose(\n                    trim_span.to(split_span), // combine the call spans of the two methods\n                    \"use `str.lines()` instead\",\n                    \"lines()\",\n                    Applicability::MaybeIncorrect,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/str_splitn.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::usage::local_used_after_expr;\nuse clippy_utils::visitors::{Descend, for_each_expr};\nuse clippy_utils::{paths, sym};\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir::{\n    BindingMode, Expr, ExprKind, HirId, LangItem, LetStmt, MatchSource, Node, Pat, PatKind, Stmt, StmtKind,\n};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, Symbol, SyntaxContext};\n\nuse super::{MANUAL_SPLIT_ONCE, NEEDLESS_SPLITN};\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    method_name: Symbol,\n    expr: &Expr<'_>,\n    self_arg: &Expr<'_>,\n    pat_arg: &Expr<'_>,\n    count: u128,\n    msrv: Msrv,\n) {\n    if count < 2 || !cx.typeck_results().expr_ty_adjusted(self_arg).peel_refs().is_str() {\n        return;\n    }\n\n    let needless = |usage_kind| match usage_kind {\n        IterUsageKind::Nth(n) => count > n + 1,\n        IterUsageKind::NextTuple => count > 2,\n    };\n    let manual = count == 2 && msrv.meets(cx, msrvs::STR_SPLIT_ONCE);\n\n    match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir_parent_iter(expr.hir_id)) {\n        Some(usage) if needless(usage.kind) => lint_needless(cx, method_name, expr, self_arg, pat_arg),\n        Some(usage) if manual => check_manual_split_once(cx, method_name, expr, self_arg, pat_arg, &usage),\n        None if manual => {\n            check_manual_split_once_indirect(cx, method_name, expr, self_arg, pat_arg);\n        },\n        _ => {},\n    }\n}\n\nfn lint_needless(cx: &LateContext<'_>, method_name: Symbol, expr: &Expr<'_>, self_arg: &Expr<'_>, pat_arg: &Expr<'_>) {\n    let mut app = Applicability::MachineApplicable;\n    let r = if method_name == sym::splitn { \"\" } else { \"r\" };\n\n    span_lint_and_sugg(\n        cx,\n        NEEDLESS_SPLITN,\n        expr.span,\n        format!(\"unnecessary use of `{r}splitn`\"),\n        \"try\",\n        format!(\n            \"{}.{r}split({})\",\n            snippet_with_context(cx, self_arg.span, expr.span.ctxt(), \"..\", &mut app).0,\n            snippet_with_context(cx, pat_arg.span, expr.span.ctxt(), \"..\", &mut app).0,\n        ),\n        app,\n    );\n}\n\nfn check_manual_split_once(\n    cx: &LateContext<'_>,\n    method_name: Symbol,\n    expr: &Expr<'_>,\n    self_arg: &Expr<'_>,\n    pat_arg: &Expr<'_>,\n    usage: &IterUsage,\n) {\n    let ctxt = expr.span.ctxt();\n    let (msg, reverse) = if method_name == sym::splitn {\n        (\"manual implementation of `split_once`\", false)\n    } else {\n        (\"manual implementation of `rsplit_once`\", true)\n    };\n\n    let mut app = Applicability::MachineApplicable;\n    let self_snip = snippet_with_context(cx, self_arg.span, ctxt, \"..\", &mut app).0;\n    let pat_snip = snippet_with_context(cx, pat_arg.span, ctxt, \"..\", &mut app).0;\n\n    let sugg = match usage.kind {\n        IterUsageKind::NextTuple => {\n            if reverse {\n                format!(\"{self_snip}.rsplit_once({pat_snip}).map(|(x, y)| (y, x))\")\n            } else {\n                format!(\"{self_snip}.split_once({pat_snip})\")\n            }\n        },\n        IterUsageKind::Nth(1) => {\n            let (r, field) = if reverse { (\"r\", 0) } else { (\"\", 1) };\n\n            match usage.unwrap_kind {\n                Some(UnwrapKind::Unwrap) => {\n                    format!(\"{self_snip}.{r}split_once({pat_snip}).unwrap().{field}\")\n                },\n                Some(UnwrapKind::QuestionMark) => {\n                    format!(\"{self_snip}.{r}split_once({pat_snip})?.{field}\")\n                },\n                None => {\n                    format!(\"{self_snip}.{r}split_once({pat_snip}).map(|x| x.{field})\")\n                },\n            }\n        },\n        IterUsageKind::Nth(_) => return,\n    };\n\n    span_lint_and_sugg(cx, MANUAL_SPLIT_ONCE, usage.span, msg, \"try\", sugg, app);\n}\n\n/// checks for\n///\n/// ```no_run\n/// let mut iter = \"a.b.c\".splitn(2, '.');\n/// let a = iter.next();\n/// let b = iter.next();\n/// ```\nfn check_manual_split_once_indirect(\n    cx: &LateContext<'_>,\n    method_name: Symbol,\n    expr: &Expr<'_>,\n    self_arg: &Expr<'_>,\n    pat_arg: &Expr<'_>,\n) -> Option<()> {\n    let ctxt = expr.span.ctxt();\n    let mut parents = cx.tcx.hir_parent_iter(expr.hir_id);\n    if let (_, Node::LetStmt(local)) = parents.next()?\n        && let PatKind::Binding(BindingMode::MUT, iter_binding_id, _, None) = local.pat.kind\n        && let (iter_stmt_id, Node::Stmt(_)) = parents.next()?\n        && let (_, Node::Block(enclosing_block)) = parents.next()?\n        && let mut stmts = enclosing_block\n            .stmts\n            .iter()\n            .skip_while(|stmt| stmt.hir_id != iter_stmt_id)\n            .skip(1)\n        && let first = indirect_usage(cx, stmts.next()?, iter_binding_id, ctxt)?\n        && let second = indirect_usage(cx, stmts.next()?, iter_binding_id, ctxt)?\n        && first.unwrap_kind == second.unwrap_kind\n        && first.name != second.name\n        && !local_used_after_expr(cx, iter_binding_id, second.init_expr)\n    {\n        let (r, lhs, rhs) = if method_name == sym::splitn {\n            (\"\", first.name, second.name)\n        } else {\n            (\"r\", second.name, first.name)\n        };\n        let msg = format!(\"manual implementation of `{r}split_once`\");\n\n        let mut app = Applicability::MachineApplicable;\n        let self_snip = snippet_with_context(cx, self_arg.span, ctxt, \"..\", &mut app).0;\n        let pat_snip = snippet_with_context(cx, pat_arg.span, ctxt, \"..\", &mut app).0;\n\n        span_lint_and_then(cx, MANUAL_SPLIT_ONCE, local.span, msg, |diag| {\n            diag.span_label(first.span, \"first usage here\");\n            diag.span_label(second.span, \"second usage here\");\n\n            let unwrap = match first.unwrap_kind {\n                UnwrapKind::Unwrap => \".unwrap()\",\n                UnwrapKind::QuestionMark => \"?\",\n            };\n\n            // Add a multipart suggestion\n            diag.multipart_suggestion(\n                format!(\"replace with `{r}split_once`\"),\n                vec![\n                    (\n                        local.span,\n                        format!(\"let ({lhs}, {rhs}) = {self_snip}.{r}split_once({pat_snip}){unwrap};\"),\n                    ),\n                    (first.span, String::new()),  // Remove the first usage\n                    (second.span, String::new()), // Remove the second usage\n                ],\n                app,\n            );\n        });\n    }\n\n    Some(())\n}\n\n#[derive(Debug)]\nstruct IndirectUsage<'a> {\n    name: Symbol,\n    span: Span,\n    init_expr: &'a Expr<'a>,\n    unwrap_kind: UnwrapKind,\n}\n\n/// returns `Some(IndirectUsage)` for e.g.\n///\n/// ```ignore\n/// let name = binding.next()?;\n/// let name = binding.next().unwrap();\n/// ```\nfn indirect_usage<'tcx>(\n    cx: &LateContext<'tcx>,\n    stmt: &Stmt<'tcx>,\n    binding: HirId,\n    ctxt: SyntaxContext,\n) -> Option<IndirectUsage<'tcx>> {\n    if let StmtKind::Let(&LetStmt {\n        pat: Pat {\n            kind: PatKind::Binding(BindingMode::NONE, _, ident, None),\n            ..\n        },\n        init: Some(init_expr),\n        hir_id: local_hir_id,\n        ..\n    }) = stmt.kind\n    {\n        let mut path_to_binding = None;\n        let _: Option<!> = for_each_expr(cx, init_expr, |e| {\n            if e.res_local_id() == Some(binding) {\n                path_to_binding = Some(e);\n            }\n            ControlFlow::Continue(Descend::from(path_to_binding.is_none()))\n        });\n\n        let mut parents = cx.tcx.hir_parent_iter(path_to_binding?.hir_id);\n        let iter_usage = parse_iter_usage(cx, ctxt, &mut parents)?;\n\n        let (parent_id, _) = parents.find(|(_, node)| {\n            !matches!(\n                node,\n                Node::Expr(Expr {\n                    kind: ExprKind::Match(.., MatchSource::TryDesugar(_)),\n                    ..\n                })\n            )\n        })?;\n\n        if let IterUsage {\n            kind: IterUsageKind::Nth(0),\n            unwrap_kind: Some(unwrap_kind),\n            ..\n        } = iter_usage\n            && parent_id == local_hir_id\n        {\n            return Some(IndirectUsage {\n                name: ident.name,\n                span: stmt.span,\n                init_expr,\n                unwrap_kind,\n            });\n        }\n    }\n\n    None\n}\n\n#[derive(Debug, Clone, Copy)]\nenum IterUsageKind {\n    Nth(u128),\n    NextTuple,\n}\n\n#[derive(Debug, PartialEq, Eq)]\nenum UnwrapKind {\n    Unwrap,\n    QuestionMark,\n}\n\n#[derive(Debug)]\nstruct IterUsage {\n    kind: IterUsageKind,\n    unwrap_kind: Option<UnwrapKind>,\n    span: Span,\n}\n\nfn parse_iter_usage<'tcx>(\n    cx: &LateContext<'tcx>,\n    ctxt: SyntaxContext,\n    mut iter: impl Iterator<Item = (HirId, Node<'tcx>)>,\n) -> Option<IterUsage> {\n    let (kind, span) = match iter.next() {\n        Some((_, Node::Expr(e))) if e.span.ctxt() == ctxt => {\n            let ExprKind::MethodCall(name, _, args, _) = e.kind else {\n                return None;\n            };\n            let did = cx.typeck_results().type_dependent_def_id(e.hir_id)?;\n            let iter_id = cx.tcx.get_diagnostic_item(sym::Iterator)?;\n\n            match (name.ident.name, args) {\n                (sym::next, []) if cx.tcx.trait_of_assoc(did) == Some(iter_id) => (IterUsageKind::Nth(0), e.span),\n                (sym::next_tuple, []) => {\n                    return if paths::ITERTOOLS_NEXT_TUPLE.matches(cx, did)\n                        && let ty::Adt(adt_def, subs) = cx.typeck_results().expr_ty(e).kind()\n                        && cx.tcx.is_diagnostic_item(sym::Option, adt_def.did())\n                        && let ty::Tuple(subs) = subs.type_at(0).kind()\n                        && subs.len() == 2\n                    {\n                        Some(IterUsage {\n                            kind: IterUsageKind::NextTuple,\n                            unwrap_kind: None,\n                            span: e.span,\n                        })\n                    } else {\n                        None\n                    };\n                },\n                (sym::nth | sym::skip, [idx_expr]) if cx.tcx.trait_of_assoc(did) == Some(iter_id) => {\n                    if let Some(Constant::Int(idx)) = ConstEvalCtxt::new(cx).eval_local(idx_expr, ctxt) {\n                        let span = if name.ident.as_str() == \"nth\" {\n                            e.span\n                        } else if let Some((_, Node::Expr(next_expr))) = iter.next()\n                            && let ExprKind::MethodCall(next_name, _, [], _) = next_expr.kind\n                            && next_name.ident.name == sym::next\n                            && next_expr.span.ctxt() == ctxt\n                            && let Some(next_id) = cx.typeck_results().type_dependent_def_id(next_expr.hir_id)\n                            && cx.tcx.trait_of_assoc(next_id) == Some(iter_id)\n                        {\n                            next_expr.span\n                        } else {\n                            return None;\n                        };\n                        (IterUsageKind::Nth(idx), span)\n                    } else {\n                        return None;\n                    }\n                },\n                _ => return None,\n            }\n        },\n        _ => return None,\n    };\n\n    let (unwrap_kind, span) = if let Some((_, Node::Expr(e))) = iter.next() {\n        match e.kind {\n            ExprKind::Call(\n                &Expr {\n                    kind: ExprKind::Path(qpath),\n                    ..\n                },\n                [_],\n            ) if cx.tcx.qpath_is_lang_item(qpath, LangItem::TryTraitBranch) => {\n                let parent_span = e.span.parent_callsite().unwrap();\n                if parent_span.ctxt() == ctxt {\n                    (Some(UnwrapKind::QuestionMark), parent_span)\n                } else {\n                    (None, span)\n                }\n            },\n            _ if e.span.ctxt() != ctxt => (None, span),\n            ExprKind::MethodCall(name, _, [], _)\n                if name.ident.name == sym::unwrap\n                    && cx\n                        .typeck_results()\n                        .type_dependent_def_id(e.hir_id)\n                        .opt_parent(cx)\n                        .opt_impl_ty(cx)\n                        .is_diag_item(cx, sym::Option) =>\n            {\n                (Some(UnwrapKind::Unwrap), e.span)\n            },\n            _ => (None, span),\n        }\n    } else {\n        (None, span)\n    };\n\n    Some(IterUsage {\n        kind,\n        unwrap_kind,\n        span,\n    })\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/string_extend_chars.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{method_chain_args, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\n\nuse super::STRING_EXTEND_CHARS;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {\n    let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();\n    if !obj_ty.is_lang_item(cx, hir::LangItem::String) {\n        return;\n    }\n    if let Some(arglists) = method_chain_args(arg, &[sym::chars]) {\n        let target = &arglists[0].0;\n        let self_ty = cx.typeck_results().expr_ty(target).peel_refs();\n        let ref_str = if self_ty.is_str() {\n            if matches!(target.kind, hir::ExprKind::Index(..)) {\n                \"&\"\n            } else {\n                \"\"\n            }\n        } else if self_ty.is_lang_item(cx, hir::LangItem::String) {\n            \"&\"\n        } else {\n            return;\n        };\n\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            STRING_EXTEND_CHARS,\n            expr.span,\n            \"calling `.extend(_.chars())`\",\n            \"try\",\n            format!(\n                \"{}.push_str({ref_str}{})\",\n                snippet_with_applicability(cx, recv.span, \"..\", &mut applicability),\n                snippet_with_applicability(cx, target.span, \"..\", &mut applicability)\n            ),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/string_lit_chars_any.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::source::SpanRangeExt;\nuse itertools::Itertools;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, Param, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::STRING_LIT_CHARS_ANY;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    recv: &Expr<'_>,\n    param: &'tcx Param<'tcx>,\n    body: &Expr<'_>,\n    msrv: Msrv,\n) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n        && let PatKind::Binding(_, arg, _, _) = param.pat.kind\n        && let ExprKind::Lit(lit_kind) = recv.kind\n        && let LitKind::Str(val, _) = lit_kind.node\n        && let ExprKind::Binary(kind, lhs, rhs) = body.kind\n        && let BinOpKind::Eq = kind.node\n        && let Some(lhs_path) = lhs.res_local_id()\n        && let Some(rhs_path) = rhs.res_local_id()\n        && let scrutinee = match (lhs_path == arg, rhs_path == arg) {\n            (true, false) => rhs,\n            (false, true) => lhs,\n            _ => return,\n        }\n        && msrv.meets(cx, msrvs::MATCHES_MACRO)\n        && !is_from_proc_macro(cx, expr)\n        && let Some(scrutinee_snip) = scrutinee.span.get_source_text(cx)\n    {\n        // Normalize the char using `map` so `join` doesn't use `Display`, if we don't then\n        // something like `r\"\\\"` will become `'\\'`, which is of course invalid\n        let pat_snip = val.as_str().chars().map(|c| format!(\"{c:?}\")).join(\" | \");\n\n        span_lint_and_then(\n            cx,\n            STRING_LIT_CHARS_ANY,\n            expr.span,\n            \"usage of `.chars().any(...)` to check if a char matches any from a string literal\",\n            |diag| {\n                diag.span_suggestion_verbose(\n                    expr.span,\n                    \"use `matches!(...)` instead\",\n                    format!(\"matches!({scrutinee_snip}, {pat_snip})\"),\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/suspicious_command_arg_space.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_ast as ast;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::SUSPICIOUS_COMMAND_ARG_SPACE;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>, span: Span) {\n    let ty = cx.typeck_results().expr_ty(recv).peel_refs();\n\n    if ty.is_diag_item(cx, sym::Command)\n        && let hir::ExprKind::Lit(lit) = &arg.kind\n        && let ast::LitKind::Str(s, _) = &lit.node\n        && let Some((arg1, arg2)) = s.as_str().split_once(' ')\n        && arg1.starts_with('-')\n        && arg1.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')\n    {\n        span_lint_and_then(\n            cx,\n            SUSPICIOUS_COMMAND_ARG_SPACE,\n            arg.span,\n            \"single argument that looks like it should be multiple arguments\",\n            |diag: &mut Diag<'_, ()>| {\n                diag.multipart_suggestion(\n                    \"consider splitting the argument\",\n                    vec![(span, \"args\".to_string()), (arg.span, format!(\"[{arg1:?}, {arg2:?}]\"))],\n                    Applicability::MaybeIncorrect,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/suspicious_map.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::expr_or_init;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::usage::mutated_variables;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::SUSPICIOUS_MAP;\n\npub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) {\n    if cx\n        .ty_based_def(count_recv)\n        .opt_parent(cx)\n        .is_diag_item(cx, sym::Iterator)\n        && let hir::ExprKind::Closure(closure) = expr_or_init(cx, map_arg).kind\n        && let closure_body = cx.tcx.hir_body(closure.body)\n        && !cx.typeck_results().expr_ty(closure_body.value).is_unit()\n    {\n        if let Some(map_mutated_vars) = mutated_variables(closure_body.value, cx)\n            // A variable is used mutably inside of the closure. Suppress the lint.\n            && !map_mutated_vars.is_empty()\n        {\n            return;\n        }\n        span_lint_and_help(\n            cx,\n            SUSPICIOUS_MAP,\n            expr.span,\n            \"this call to `map()` won't have an effect on the call to `count()`\",\n            None,\n            \"make sure you did not confuse `map` with `filter`, `for_each` or `inspect`\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/suspicious_splitn.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_note;\nuse rustc_ast::LitKind;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Symbol;\nuse rustc_span::source_map::Spanned;\n\nuse super::SUSPICIOUS_SPLITN;\n\npub(super) fn check(cx: &LateContext<'_>, method_name: Symbol, expr: &Expr<'_>, self_arg: &Expr<'_>, count: u128) {\n    if count <= 1\n        && let Some(call_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && let Some(impl_id) = cx.tcx.inherent_impl_of_assoc(call_id)\n        && let self_ty = cx.tcx.type_of(impl_id).instantiate_identity()\n        && (self_ty.is_slice() || self_ty.is_str())\n    {\n        // Ignore empty slice and string literals when used with a literal count.\n        if matches!(self_arg.kind, ExprKind::Array([]))\n            || matches!(self_arg.kind, ExprKind::Lit(Spanned { node: LitKind::Str(s, _), .. }) if s.is_empty())\n        {\n            return;\n        }\n\n        let (msg, note_msg) = if count == 0 {\n            (\n                format!(\"`{method_name}` called with `0` splits\"),\n                \"the resulting iterator will always return `None`\",\n            )\n        } else {\n            (\n                format!(\"`{method_name}` called with `1` split\"),\n                if self_ty.is_slice() {\n                    \"the resulting iterator will always return the entire slice followed by `None`\"\n                } else {\n                    \"the resulting iterator will always return the entire string followed by `None`\"\n                },\n            )\n        };\n\n        span_lint_and_note(cx, SUSPICIOUS_SPLITN, expr.span, msg, None, note_msg);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/suspicious_to_owned.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\nuse rustc_span::Span;\n\nuse super::SUSPICIOUS_TO_OWNED;\n\npub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_span: Span) -> bool {\n    if cx\n        .typeck_results()\n        .type_dependent_def_id(expr.hir_id)\n        .opt_parent(cx)\n        .is_diag_item(cx, sym::ToOwned)\n        && let input_type = cx.typeck_results().expr_ty(expr)\n        && input_type.is_diag_item(cx, sym::Cow)\n    {\n        let app = Applicability::MaybeIncorrect;\n        span_lint_and_then(\n            cx,\n            SUSPICIOUS_TO_OWNED,\n            expr.span,\n            with_forced_trimmed_paths!(format!(\n                \"this `to_owned` call clones the `{input_type}` itself and does not cause its contents to become owned\"\n            )),\n            |diag| {\n                diag.span_suggestion(\n                    method_span,\n                    \"depending on intent, either make the `Cow` an `Owned` variant\",\n                    \"into_owned\".to_string(),\n                    app,\n                );\n                diag.span_suggestion(method_span, \"or clone the `Cow` itself\", \"clone\".to_string(), app);\n            },\n        );\n        return true;\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/swap_with_temporary.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse rustc_ast::BorrowKind;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::{Expr, ExprKind, Node, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};\nuse rustc_span::sym;\n\nuse super::SWAP_WITH_TEMPORARY;\n\nconst MSG_TEMPORARY: &str = \"this expression returns a temporary value\";\nconst MSG_TEMPORARY_REFMUT: &str = \"this is a mutable reference to a temporary value\";\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, func: &Expr<'_>, args: &'tcx [Expr<'_>]) {\n    if let ExprKind::Path(QPath::Resolved(_, func_path)) = func.kind\n        && let Some(func_def_id) = func_path.res.opt_def_id()\n        && cx.tcx.is_diagnostic_item(sym::mem_swap, func_def_id)\n    {\n        match (ArgKind::new(cx, &args[0]), ArgKind::new(cx, &args[1])) {\n            (ArgKind::RefMutToTemp(left_temp), ArgKind::RefMutToTemp(right_temp)) => {\n                emit_lint_useless(cx, expr, &args[0], &args[1], left_temp, right_temp);\n            },\n            (ArgKind::RefMutToTemp(left_temp), right) => emit_lint_assign(cx, expr, &right, &args[0], left_temp),\n            (left, ArgKind::RefMutToTemp(right_temp)) => emit_lint_assign(cx, expr, &left, &args[1], right_temp),\n            _ => {},\n        }\n    }\n}\n\nenum ArgKind<'tcx> {\n    // Mutable reference to a place, coming from a macro, and number of dereferences to use\n    RefMutToPlaceAsMacro(&'tcx Expr<'tcx>, usize),\n    // Place behind a mutable reference, and number of dereferences to use\n    RefMutToPlace(&'tcx Expr<'tcx>, usize),\n    // Temporary value behind a mutable reference\n    RefMutToTemp(&'tcx Expr<'tcx>),\n    // Any other case\n    Expr(&'tcx Expr<'tcx>),\n}\n\nimpl<'tcx> ArgKind<'tcx> {\n    /// Build a new `ArgKind` from `arg`. There must be no false positive when returning a\n    /// `ArgKind::RefMutToTemp` variant, as this may cause a spurious lint to be emitted.\n    fn new(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Self {\n        if let ExprKind::AddrOf(BorrowKind::Ref, _, target) = arg.kind\n            && let adjustments = cx.typeck_results().expr_adjustments(arg)\n            && adjustments\n                .first()\n                .is_some_and(|adj| matches!(adj.kind, Adjust::Deref(DerefAdjustKind::Builtin)))\n            && adjustments\n                .last()\n                .is_some_and(|adj| matches!(adj.kind, Adjust::Borrow(_)))\n        {\n            let extra_derefs = adjustments[1..adjustments.len() - 1]\n                .iter()\n                .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))\n                .count();\n            // If a deref is used, `arg` might be a place expression. For example, a mutex guard\n            // would dereference into the mutex content which is probably not temporary.\n            if target.is_syntactic_place_expr() || extra_derefs > 0 {\n                if arg.span.from_expansion() {\n                    ArgKind::RefMutToPlaceAsMacro(arg, extra_derefs)\n                } else {\n                    ArgKind::RefMutToPlace(target, extra_derefs)\n                }\n            } else {\n                ArgKind::RefMutToTemp(target)\n            }\n        } else {\n            ArgKind::Expr(arg)\n        }\n    }\n}\n\n// Emits a note either on the temporary expression if it can be found in the same context as the\n// base and returns `true`, or on the mutable reference to the temporary expression otherwise and\n// returns `false`.\nfn emit_note(diag: &mut Diag<'_, ()>, base: &Expr<'_>, expr: &Expr<'_>, expr_temp: &Expr<'_>) -> bool {\n    if base.span.eq_ctxt(expr.span) {\n        diag.span_note(expr_temp.span.source_callsite(), MSG_TEMPORARY);\n        true\n    } else {\n        diag.span_note(expr.span.source_callsite(), MSG_TEMPORARY_REFMUT);\n        false\n    }\n}\n\nfn emit_lint_useless(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    left: &Expr<'_>,\n    right: &Expr<'_>,\n    left_temp: &Expr<'_>,\n    right_temp: &Expr<'_>,\n) {\n    span_lint_and_then(\n        cx,\n        SWAP_WITH_TEMPORARY,\n        expr.span,\n        \"swapping temporary values has no effect\",\n        |diag| {\n            emit_note(diag, expr, left, left_temp);\n            emit_note(diag, expr, right, right_temp);\n        },\n    );\n}\n\nfn emit_lint_assign(cx: &LateContext<'_>, expr: &Expr<'_>, target: &ArgKind<'_>, reftemp: &Expr<'_>, temp: &Expr<'_>) {\n    span_lint_and_then(\n        cx,\n        SWAP_WITH_TEMPORARY,\n        expr.span,\n        \"swapping with a temporary value is inefficient\",\n        |diag| {\n            if !emit_note(diag, expr, reftemp, temp) {\n                return;\n            }\n\n            // Make the suggestion only when the original `swap()` call is a statement\n            // or the last expression in a block.\n            if matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::Stmt(..) | Node::Block(..)) {\n                let mut applicability = Applicability::MachineApplicable;\n                let ctxt = expr.span.ctxt();\n                let assign_target = match target {\n                    ArgKind::Expr(target) => Sugg::hir_with_context(cx, target, ctxt, \"_\", &mut applicability).deref(),\n                    ArgKind::RefMutToPlaceAsMacro(arg, derefs) => (0..*derefs).fold(\n                        Sugg::hir_with_context(cx, arg, ctxt, \"_\", &mut applicability).deref(),\n                        |sugg, _| sugg.deref(),\n                    ),\n                    ArgKind::RefMutToPlace(target, derefs) => (0..*derefs).fold(\n                        Sugg::hir_with_context(cx, target, ctxt, \"_\", &mut applicability),\n                        |sugg, _| sugg.deref(),\n                    ),\n                    ArgKind::RefMutToTemp(_) => unreachable!(),\n                };\n                let assign_source = Sugg::hir_with_context(cx, temp, ctxt, \"_\", &mut applicability);\n                diag.span_suggestion(\n                    expr.span,\n                    \"use assignment instead\",\n                    format!(\"{assign_target} = {assign_source}\"),\n                    applicability,\n                );\n            }\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/type_id_on_box.rs",
    "content": "use crate::methods::TYPE_ID_ON_BOX;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\nuse rustc_middle::ty::{self, ExistentialPredicate, Ty};\nuse rustc_span::Span;\n\n/// Checks if the given type is `dyn Any`, or a trait object that has `Any` as a supertrait.\n/// Only in those cases will its vtable have a `type_id` method that returns the implementor's\n/// `TypeId`, and only in those cases can we give a proper suggestion to dereference the box.\n///\n/// If this returns false, then `.type_id()` likely (this may have FNs) will not be what the user\n/// expects in any case and dereferencing it won't help either. It will likely require some\n/// other changes, but it is still worth emitting a lint.\n/// See <https://github.com/rust-lang/rust-clippy/pull/11350#discussion_r1544863005> for more details.\nfn is_subtrait_of_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    if let ty::Dynamic(preds, ..) = ty.kind() {\n        preds.iter().any(|p| match p.skip_binder() {\n            ExistentialPredicate::Trait(tr) => {\n                cx.tcx.is_diagnostic_item(sym::Any, tr.def_id)\n                    || cx\n                        .tcx\n                        .explicit_super_predicates_of(tr.def_id)\n                        .iter_identity_copied()\n                        .any(|(clause, _)| {\n                            matches!(clause.kind().skip_binder(), ty::ClauseKind::Trait(super_tr)\n                            if cx.tcx.is_diagnostic_item(sym::Any, super_tr.def_id()))\n                        })\n            },\n            _ => false,\n        })\n    } else {\n        false\n    }\n}\n\npub(super) fn check(cx: &LateContext<'_>, receiver: &Expr<'_>, call_span: Span) {\n    let recv_adjusts = cx.typeck_results().expr_adjustments(receiver);\n\n    if let Some(Adjustment { target: recv_ty, .. }) = recv_adjusts.last()\n        && let ty::Ref(_, ty, _) = recv_ty.kind()\n        && let ty::Adt(adt, args) = ty.kind()\n        && adt.is_box()\n        && let inner_box_ty = args.type_at(0)\n        && let ty::Dynamic(..) = inner_box_ty.kind()\n    {\n        let ty_name = with_forced_trimmed_paths!(ty.to_string());\n\n        span_lint_and_then(\n            cx,\n            TYPE_ID_ON_BOX,\n            call_span,\n            format!(\"calling `.type_id()` on `{ty_name}`\"),\n            |diag| {\n                let derefs = recv_adjusts\n                    .iter()\n                    .filter(|adj| matches!(adj.kind, Adjust::Deref(DerefAdjustKind::Builtin)))\n                    .count();\n\n                diag.note(\n                    \"this returns the type id of the literal type `Box<_>` instead of the \\\n                    type id of the boxed value, which is most likely not what you want\",\n                )\n                .note(format!(\n                    \"if this is intentional, use `TypeId::of::<{ty_name}>()` instead, \\\n                    which makes it more clear\"\n                ));\n\n                if is_subtrait_of_any(cx, inner_box_ty) {\n                    let mut sugg = \"*\".repeat(derefs + 1);\n                    sugg += &snippet(cx, receiver.span, \"<expr>\");\n\n                    diag.span_suggestion(\n                        receiver.span,\n                        \"consider dereferencing first\",\n                        format!(\"({sugg})\"),\n                        Applicability::MaybeIncorrect,\n                    );\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unbuffered_bytes.rs",
    "content": "use super::UNBUFFERED_BYTES;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::sym;\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {\n    // Lint if the `.bytes()` call is from the `Read` trait and the implementor is not buffered.\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::IoRead)\n        && let Some(buf_read) = cx.tcx.get_diagnostic_item(sym::IoBufRead)\n        && let ty = cx.typeck_results().expr_ty_adjusted(recv)\n        && !implements_trait(cx, ty, buf_read, &[])\n    {\n        span_lint_and_help(\n            cx,\n            UNBUFFERED_BYTES,\n            expr.span,\n            \"calling .bytes() is very inefficient when data is not in memory\",\n            None,\n            \"consider using `BufReader`\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/uninit_assumed_init.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::ty::is_uninit_value_valid_for_ty;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::UNINIT_ASSUMED_INIT;\n\n/// lint for `MaybeUninit::uninit().assume_init()` (we already have the latter)\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {\n    if let hir::ExprKind::Call(callee, []) = recv.kind\n        && callee.ty_rel_def(cx).is_diag_item(cx, sym::maybe_uninit_uninit)\n        && !is_uninit_value_valid_for_ty(cx, cx.typeck_results().expr_ty_adjusted(expr))\n    {\n        span_lint(\n            cx,\n            UNINIT_ASSUMED_INIT,\n            expr.span,\n            \"this call for this type may be undefined behavior\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unit_hash.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::UNIT_HASH;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Hash) && cx.typeck_results().expr_ty(recv).is_unit() {\n        span_lint_and_then(\n            cx,\n            UNIT_HASH,\n            expr.span,\n            \"this call to `hash` on the unit type will do nothing\",\n            |diag| {\n                diag.span_suggestion(\n                    expr.span,\n                    \"remove the call to `hash` or consider using\",\n                    format!(\"0_u8.hash({})\", snippet(cx, arg.span, \"..\")),\n                    Applicability::MaybeIncorrect,\n                );\n                diag.note(\"the implementation of `Hash` for `()` is a no-op\");\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_fallible_conversions.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::get_parent_expr;\nuse clippy_utils::ty::implements_trait;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\nuse rustc_span::{Span, sym};\n\nuse super::UNNECESSARY_FALLIBLE_CONVERSIONS;\n\n#[derive(Copy, Clone)]\nenum SpansKind {\n    TraitFn { trait_span: Span, fn_span: Span },\n    Fn { fn_span: Span },\n}\n\n/// What function is being called and whether that call is written as a method call or a function\n/// call\n#[derive(Copy, Clone)]\n#[expect(clippy::enum_variant_names)]\nenum FunctionKind {\n    /// `T::try_from(U)`\n    TryFromFunction(Option<SpansKind>),\n    /// `t.try_into()`\n    TryIntoMethod,\n    /// `U::try_into(t)`\n    TryIntoFunction(Option<SpansKind>),\n}\n\nimpl FunctionKind {\n    fn appl_sugg(&self, parent_unwrap_call: Option<Span>, primary_span: Span) -> (Applicability, Vec<(Span, String)>) {\n        let Some(unwrap_span) = parent_unwrap_call else {\n            return (Applicability::Unspecified, self.default_sugg(primary_span));\n        };\n\n        match &self {\n            FunctionKind::TryFromFunction(None) | FunctionKind::TryIntoFunction(None) => {\n                (Applicability::Unspecified, self.default_sugg(primary_span))\n            },\n            _ => (\n                Applicability::MachineApplicable,\n                self.machine_applicable_sugg(primary_span, unwrap_span),\n            ),\n        }\n    }\n\n    fn default_sugg(&self, primary_span: Span) -> Vec<(Span, String)> {\n        let replacement = match *self {\n            FunctionKind::TryFromFunction(_) => \"From::from\",\n            FunctionKind::TryIntoFunction(_) => \"Into::into\",\n            FunctionKind::TryIntoMethod => \"into\",\n        };\n\n        vec![(primary_span, String::from(replacement))]\n    }\n\n    fn machine_applicable_sugg(&self, primary_span: Span, unwrap_span: Span) -> Vec<(Span, String)> {\n        let (trait_name, fn_name) = match self {\n            FunctionKind::TryFromFunction(_) => (\"From\".to_owned(), \"from\".to_owned()),\n            FunctionKind::TryIntoFunction(_) | FunctionKind::TryIntoMethod => (\"Into\".to_owned(), \"into\".to_owned()),\n        };\n\n        let mut sugg = match *self {\n            FunctionKind::TryFromFunction(Some(spans)) | FunctionKind::TryIntoFunction(Some(spans)) => match spans {\n                SpansKind::TraitFn { trait_span, fn_span } => vec![(trait_span, trait_name), (fn_span, fn_name)],\n                SpansKind::Fn { fn_span } => vec![(fn_span, fn_name)],\n            },\n            FunctionKind::TryIntoMethod => vec![(primary_span, fn_name)],\n            // Or the suggestion is not machine-applicable\n            _ => unreachable!(),\n        };\n\n        sugg.push((unwrap_span, String::new()));\n        sugg\n    }\n}\n\nfn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'_>,\n    node_args: ty::GenericArgsRef<'tcx>,\n    kind: FunctionKind,\n    primary_span: Span,\n) {\n    if let &[self_ty, other_ty] = node_args.as_slice()\n        // useless_conversion already warns `T::try_from(T)`, so ignore it here\n        && self_ty != other_ty\n        && let Some(self_ty) = self_ty.as_type()\n        && let Some(from_into_trait) = cx.tcx.get_diagnostic_item(match kind {\n            FunctionKind::TryFromFunction(_) => sym::From,\n            FunctionKind::TryIntoMethod | FunctionKind::TryIntoFunction(_) => sym::Into,\n        })\n        // If `T: TryFrom<U>` and `T: From<U>` both exist, then that means that the `TryFrom`\n        // _must_ be from the blanket impl and cannot have been manually implemented\n        // (else there would be conflicting impls, even with #![feature(spec)]), so we don't even need to check\n        // what `<T as TryFrom<U>>::Error` is: it's always `Infallible`\n        && implements_trait(cx, self_ty, from_into_trait, &[other_ty])\n        && let Some(other_ty) = other_ty.as_type()\n    {\n        // Extend the span to include the unwrap/expect call:\n        // `foo.try_into().expect(\"..\")`\n        //      ^^^^^^^^^^^^^^^^^^^^^^^\n        //\n        // `try_into().unwrap()` specifically can be trivially replaced with just `into()`,\n        // so that can be machine-applicable\n        let parent_unwrap_call = get_parent_expr(cx, expr).and_then(|parent| {\n            if let ExprKind::MethodCall(path, .., span) = parent.kind\n                && let sym::unwrap | sym::expect = path.ident.name\n            {\n                // include `.` before `unwrap`/`expect`\n                Some(span.with_lo(expr.span.hi()))\n            } else {\n                None\n            }\n        });\n\n        // If there is an unwrap/expect call, extend the span to include the call\n        let span = if let Some(unwrap_call) = parent_unwrap_call {\n            primary_span.with_hi(unwrap_call.hi())\n        } else {\n            primary_span\n        };\n\n        let (source_ty, target_ty) = match kind {\n            FunctionKind::TryIntoMethod | FunctionKind::TryIntoFunction(_) => (self_ty, other_ty),\n            FunctionKind::TryFromFunction(_) => (other_ty, self_ty),\n        };\n\n        let (applicability, sugg) = kind.appl_sugg(parent_unwrap_call, primary_span);\n\n        span_lint_and_then(\n            cx,\n            UNNECESSARY_FALLIBLE_CONVERSIONS,\n            span,\n            \"use of a fallible conversion when an infallible one could be used\",\n            |diag| {\n                with_forced_trimmed_paths!({\n                    diag.note(format!(\"converting `{source_ty}` to `{target_ty}` cannot fail\"));\n                });\n                diag.multipart_suggestion(\"use\", sugg, applicability);\n            },\n        );\n    }\n}\n\n/// Checks method call exprs:\n/// - `0i32.try_into()`\npub(super) fn check_method(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let ExprKind::MethodCall(path, ..) = expr.kind {\n        check(\n            cx,\n            expr,\n            cx.typeck_results().node_args(expr.hir_id),\n            FunctionKind::TryIntoMethod,\n            path.ident.span,\n        );\n    }\n}\n\n/// Checks function call exprs:\n/// - `<i64 as TryFrom<_>>::try_from(0i32)`\n/// - `<_ as TryInto<i64>>::try_into(0i32)`\npub(super) fn check_function(cx: &LateContext<'_>, expr: &Expr<'_>, callee: &Expr<'_>) {\n    if let ExprKind::Path(ref qpath) = callee.kind\n        && let Some(item_def_id) = cx.qpath_res(qpath, callee.hir_id).opt_def_id()\n        && let Some(trait_def_id) = cx.tcx.trait_of_assoc(item_def_id)\n    {\n        let qpath_spans = match qpath {\n            QPath::Resolved(_, path) => {\n                if let [trait_seg, fn_seg] = path.segments {\n                    Some(SpansKind::TraitFn {\n                        trait_span: trait_seg.ident.span,\n                        fn_span: fn_seg.ident.span,\n                    })\n                } else {\n                    None\n                }\n            },\n            QPath::TypeRelative(_, seg) => Some(SpansKind::Fn {\n                fn_span: seg.ident.span,\n            }),\n        };\n\n        check(\n            cx,\n            expr,\n            cx.typeck_results().node_args(callee.hir_id),\n            match cx.tcx.get_diagnostic_name(trait_def_id) {\n                Some(sym::TryFrom) => FunctionKind::TryFromFunction(qpath_spans),\n                Some(sym::TryInto) => FunctionKind::TryIntoFunction(qpath_spans),\n                _ => return,\n            },\n            callee.span,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_filter_map.rs",
    "content": "use super::utils::clone_or_copy_needed;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::ty::{is_copy, option_arg_ty};\nuse clippy_utils::usage::mutated_variables;\nuse clippy_utils::visitors::{Descend, for_each_expr_without_closures};\nuse clippy_utils::{as_some_expr, sym};\nuse core::ops::ControlFlow;\nuse rustc_hir as hir;\nuse rustc_hir::LangItem::{OptionNone, OptionSome};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\nuse std::fmt::Display;\n\nuse super::{UNNECESSARY_FILTER_MAP, UNNECESSARY_FIND_MAP};\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'tcx>,\n    arg: &'tcx hir::Expr<'tcx>,\n    call_span: Span,\n    kind: Kind,\n) {\n    if !cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        return;\n    }\n\n    if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = arg.kind {\n        let body = cx.tcx.hir_body(body);\n        let arg_id = body.params[0].pat.hir_id;\n        let mutates_arg = mutated_variables(body.value, cx).is_none_or(|used_mutably| used_mutably.contains(&arg_id));\n        let (clone_or_copy_needed, _) = clone_or_copy_needed(cx, body.params[0].pat, body.value);\n\n        let (mut found_mapping, mut found_filtering) = check_expression(cx, arg_id, body.value);\n\n        let _: Option<!> = for_each_expr_without_closures(body.value, |e| {\n            if let hir::ExprKind::Ret(Some(e)) = &e.kind {\n                let (found_mapping_res, found_filtering_res) = check_expression(cx, arg_id, e);\n                found_mapping |= found_mapping_res;\n                found_filtering |= found_filtering_res;\n                ControlFlow::Continue(Descend::No)\n            } else {\n                ControlFlow::Continue(Descend::Yes)\n            }\n        });\n        let in_ty = cx.typeck_results().node_type(body.params[0].hir_id);\n        let sugg = if !found_filtering {\n            // Check if the closure is .filter_map(|x| Some(x))\n            if kind.is_filter_map()\n                && let Some(arg) = as_some_expr(cx, body.value)\n                && let hir::ExprKind::Path(_) = arg.kind\n            {\n                span_lint(\n                    cx,\n                    UNNECESSARY_FILTER_MAP,\n                    call_span,\n                    String::from(\"this call to `.filter_map(..)` is unnecessary\"),\n                );\n                return;\n            }\n            match kind {\n                Kind::FilterMap => \"map(..)\",\n                Kind::FindMap => \"map(..).next()\",\n            }\n        } else if !found_mapping && !mutates_arg && (!clone_or_copy_needed || is_copy(cx, in_ty)) {\n            let ty = cx.typeck_results().expr_ty(body.value);\n            if option_arg_ty(cx, ty).is_some_and(|t| t == in_ty) {\n                match kind {\n                    Kind::FilterMap => \"filter(..)\",\n                    Kind::FindMap => \"find(..)\",\n                }\n            } else {\n                return;\n            }\n        } else {\n            return;\n        };\n        span_lint(\n            cx,\n            match kind {\n                Kind::FilterMap => UNNECESSARY_FILTER_MAP,\n                Kind::FindMap => UNNECESSARY_FIND_MAP,\n            },\n            call_span,\n            format!(\"this `.{kind}(..)` can be written more simply using `.{sugg}`\"),\n        );\n    }\n}\n\n#[derive(Clone, Copy)]\npub(super) enum Kind {\n    FilterMap,\n    FindMap,\n}\n\nimpl Kind {\n    fn is_filter_map(self) -> bool {\n        matches!(self, Self::FilterMap)\n    }\n}\n\nimpl Display for Kind {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::FilterMap => f.write_str(\"filter_map\"),\n            Self::FindMap => f.write_str(\"find_map\"),\n        }\n    }\n}\n\n// returns (found_mapping, found_filtering)\nfn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tcx hir::Expr<'_>) -> (bool, bool) {\n    match expr.kind {\n        hir::ExprKind::Path(ref path)\n            if cx\n                .qpath_res(path, expr.hir_id)\n                .ctor_parent(cx)\n                .is_lang_item(cx, OptionNone) =>\n        {\n            // None\n            (false, true)\n        },\n        hir::ExprKind::Call(func, args) => {\n            if func.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome) {\n                if args[0].res_local_id() == Some(arg_id) {\n                    // Some(arg_id)\n                    return (false, false);\n                }\n                // Some(not arg_id)\n                return (true, false);\n            }\n            (true, true)\n        },\n        hir::ExprKind::MethodCall(segment, recv, [arg], _)\n            if segment.ident.name == sym::then_some\n                && cx.typeck_results().expr_ty(recv).is_bool()\n                && arg.res_local_id() == Some(arg_id) =>\n        {\n            // bool.then_some(arg_id)\n            (false, true)\n        },\n        hir::ExprKind::Block(block, _) => block\n            .expr\n            .as_ref()\n            .map_or((false, false), |expr| check_expression(cx, arg_id, expr)),\n        hir::ExprKind::Match(_, arms, _) => {\n            let mut found_mapping = false;\n            let mut found_filtering = false;\n            for arm in arms {\n                let (m, f) = check_expression(cx, arg_id, arm.body);\n                found_mapping |= m;\n                found_filtering |= f;\n            }\n            (found_mapping, found_filtering)\n        },\n        // There must be an else_arm or there will be a type error\n        hir::ExprKind::If(_, if_arm, Some(else_arm)) => {\n            let if_check = check_expression(cx, arg_id, if_arm);\n            let else_check = check_expression(cx, arg_id, else_arm);\n            (if_check.0 | else_check.0, if_check.1 | else_check.1)\n        },\n        _ => (true, true),\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_first_then_check.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::SpanRangeExt;\n\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::UNNECESSARY_FIRST_THEN_CHECK;\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    call_span: Span,\n    first_call: &Expr<'_>,\n    first_caller: &Expr<'_>,\n    is_some: bool,\n) {\n    if !cx\n        .typeck_results()\n        .expr_ty_adjusted(first_caller)\n        .peel_refs()\n        .is_slice()\n    {\n        return;\n    }\n\n    let ExprKind::MethodCall(_, _, _, first_call_span) = first_call.kind else {\n        return;\n    };\n\n    let both_calls_span = first_call_span.with_hi(call_span.hi());\n    if let Some(both_calls_snippet) = both_calls_span.get_source_text(cx)\n        && let Some(first_caller_snippet) = first_caller.span.get_source_text(cx)\n    {\n        let (sugg_span, suggestion) = if is_some {\n            (\n                first_caller.span.with_hi(call_span.hi()),\n                format!(\"!{first_caller_snippet}.is_empty()\"),\n            )\n        } else {\n            (both_calls_span, \"is_empty()\".to_owned())\n        };\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_FIRST_THEN_CHECK,\n            sugg_span,\n            format!(\n                \"unnecessary use of `{both_calls_snippet}` to check if slice {}\",\n                if is_some { \"is not empty\" } else { \"is empty\" }\n            ),\n            \"replace this with\",\n            suggestion,\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_fold.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_blocks, strip_pat_refs};\nuse rustc_ast::ast;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir as hir;\nuse rustc_hir::PatKind;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::{Span, Symbol, sym};\n\nuse super::UNNECESSARY_FOLD;\n\n/// Do we need to suggest turbofish when suggesting a replacement method?\n/// Changing `fold` to `sum` needs it sometimes when the return type can't be\n/// inferred. This checks for some common cases where it can be safely omitted\nfn needs_turbofish<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool {\n    let use_cx = expr_use_ctxt(cx, expr);\n    if use_cx.same_ctxt\n        && let use_node = use_cx.use_node(cx)\n        && let Some(ty) = use_node.defined_ty(cx)\n    {\n        // some common cases where turbofish isn't needed:\n        match (use_node, ty) {\n            // - assigned to a local variable with a type annotation\n            (ExprUseNode::LetStmt(_), _) => return false,\n\n            // - part of a function call argument, can be inferred from the function signature (provided that the\n            //   parameter is not a generic type parameter)\n            (ExprUseNode::FnArg(..), DefinedTy::Mir { ty: arg_ty, .. })\n                if !matches!(arg_ty.skip_binder().kind(), ty::Param(_)) =>\n            {\n                return false;\n            },\n\n            // - the final expression in the body of a function with a simple return type\n            (ExprUseNode::Return(_), DefinedTy::Mir { ty: fn_return_ty, .. })\n                if !fn_return_ty\n                    .skip_binder()\n                    .walk()\n                    .any(|generic| generic.as_type().is_some_and(Ty::is_impl_trait)) =>\n            {\n                return false;\n            },\n            _ => {},\n        }\n    }\n\n    // if it's neither of those, stay on the safe side and suggest turbofish,\n    // even if it could work!\n    true\n}\n\n#[derive(Copy, Clone)]\nstruct Replacement {\n    method_name: &'static str,\n    has_args: bool,\n    has_generic_return: bool,\n    is_short_circuiting: bool,\n}\n\nimpl Replacement {\n    fn default_applicability(&self) -> Applicability {\n        if self.is_short_circuiting {\n            Applicability::MaybeIncorrect\n        } else {\n            Applicability::MachineApplicable\n        }\n    }\n\n    fn maybe_add_note(&self, diag: &mut Diag<'_, ()>) {\n        if self.is_short_circuiting {\n            diag.note(format!(\n                \"the `{}` method is short circuiting and may change the program semantics if the iterator has side effects\",\n                self.method_name\n            ));\n        }\n    }\n\n    fn maybe_turbofish(&self, ty: Ty<'_>) -> String {\n        if self.has_generic_return {\n            format!(\"::<{ty}>\")\n        } else {\n            String::new()\n        }\n    }\n}\n\nfn get_triggered_expr_span(\n    left_expr: &hir::Expr<'_>,\n    right_expr: &hir::Expr<'_>,\n    first_arg_id: hir::HirId,\n    second_arg_id: hir::HirId,\n    replacement: Replacement,\n) -> Option<Span> {\n    if left_expr.res_local_id() == Some(first_arg_id)\n        && (replacement.has_args || right_expr.res_local_id() == Some(second_arg_id))\n    {\n        right_expr.span.into()\n    }\n    // https://github.com/rust-lang/rust-clippy/issues/16581\n    else if right_expr.res_local_id() == Some(first_arg_id)\n        && (replacement.has_args || left_expr.res_local_id() == Some(second_arg_id))\n    {\n        left_expr.span.into()\n    } else {\n        None\n    }\n}\n\nfn check_fold_with_op(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    acc: &hir::Expr<'_>,\n    fold_span: Span,\n    op: hir::BinOpKind,\n    replacement: Replacement,\n) -> bool {\n    if let hir::ExprKind::Closure(&hir::Closure { body, .. }) = acc.kind\n        // Extract the body of the closure passed to fold\n        && let closure_body = cx.tcx.hir_body(body)\n        && let closure_expr = peel_blocks(closure_body.value)\n\n        // Check if the closure body is of the form `acc <op> some_expr(x)`\n        && let hir::ExprKind::Binary(ref bin_op, left_expr, right_expr) = closure_expr.kind\n        && bin_op.node == op\n\n        // Extract the names of the two arguments to the closure\n        && let [param_a, param_b] = closure_body.params\n        && let PatKind::Binding(_, first_arg_id, ..) = strip_pat_refs(param_a.pat).kind\n        && let PatKind::Binding(_, second_arg_id, second_arg_ident, _) = strip_pat_refs(param_b.pat).kind\n\n        && let Some(triggered_expr_span) = get_triggered_expr_span(\n            left_expr,\n            right_expr,\n            first_arg_id,\n            second_arg_id,\n            replacement\n        )\n    {\n        let span = fold_span.with_hi(expr.span.hi());\n        span_lint_and_then(\n            cx,\n            UNNECESSARY_FOLD,\n            span,\n            \"this `.fold` can be written more succinctly using another method\",\n            |diag| {\n                let mut applicability = replacement.default_applicability();\n                let turbofish =\n                    replacement.maybe_turbofish(cx.typeck_results().expr_ty_adjusted(right_expr).peel_refs());\n                let (r_snippet, _) =\n                    snippet_with_context(cx, triggered_expr_span, expr.span.ctxt(), \"EXPR\", &mut applicability);\n                let sugg = if replacement.has_args {\n                    format!(\n                        \"{method}{turbofish}(|{second_arg_ident}| {r_snippet})\",\n                        method = replacement.method_name,\n                    )\n                } else {\n                    format!(\"{method}{turbofish}()\", method = replacement.method_name)\n                };\n\n                diag.span_suggestion(span, \"try\", sugg, applicability);\n                replacement.maybe_add_note(diag);\n            },\n        );\n        return true;\n    }\n    false\n}\n\nfn check_fold_with_method(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    acc: &hir::Expr<'_>,\n    fold_span: Span,\n    method: Symbol,\n    replacement: Replacement,\n) {\n    // Extract the name of the function passed to `fold`\n    if let Res::Def(DefKind::AssocFn, fn_did) = acc.res_if_named(cx, method)\n        // Check if the function belongs to the operator\n        && cx.tcx.is_diagnostic_item(method, fn_did)\n    {\n        let span = fold_span.with_hi(expr.span.hi());\n        span_lint_and_then(\n            cx,\n            UNNECESSARY_FOLD,\n            span,\n            \"this `.fold` can be written more succinctly using another method\",\n            |diag| {\n                diag.span_suggestion(\n                    span,\n                    \"try\",\n                    format!(\n                        \"{method}{turbofish}()\",\n                        method = replacement.method_name,\n                        turbofish = replacement.maybe_turbofish(cx.typeck_results().expr_ty(expr))\n                    ),\n                    replacement.default_applicability(),\n                );\n                replacement.maybe_add_note(diag);\n            },\n        );\n    }\n}\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &hir::Expr<'tcx>,\n    init: &hir::Expr<'_>,\n    acc: &hir::Expr<'_>,\n    fold_span: Span,\n) {\n    // Check that this is a call to Iterator::fold rather than just some function called fold\n    if !cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator) {\n        return;\n    }\n\n    // Check if the first argument to .fold is a suitable literal\n    if let hir::ExprKind::Lit(lit) = init.kind {\n        match lit.node {\n            ast::LitKind::Bool(false) => {\n                let replacement = Replacement {\n                    method_name: \"any\",\n                    has_args: true,\n                    has_generic_return: false,\n                    is_short_circuiting: true,\n                };\n                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, replacement);\n            },\n            ast::LitKind::Bool(true) => {\n                let replacement = Replacement {\n                    method_name: \"all\",\n                    has_args: true,\n                    has_generic_return: false,\n                    is_short_circuiting: true,\n                };\n                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, replacement);\n            },\n            ast::LitKind::Int(Pu128(0), _) => {\n                let replacement = Replacement {\n                    method_name: \"sum\",\n                    has_args: false,\n                    has_generic_return: needs_turbofish(cx, expr),\n                    is_short_circuiting: false,\n                };\n                if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, replacement) {\n                    check_fold_with_method(cx, expr, acc, fold_span, sym::add, replacement);\n                }\n            },\n            ast::LitKind::Int(Pu128(1), _) => {\n                let replacement = Replacement {\n                    method_name: \"product\",\n                    has_args: false,\n                    has_generic_return: needs_turbofish(cx, expr),\n                    is_short_circuiting: false,\n                };\n                if !check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, replacement) {\n                    check_fold_with_method(cx, expr, acc, fold_span, sym::mul, replacement);\n                }\n            },\n            _ => (),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_get_then_check.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::sym;\n\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::Span;\n\nuse super::UNNECESSARY_GET_THEN_CHECK;\n\nfn is_a_std_set_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    matches!(ty.opt_diag_name(cx), Some(sym::HashSet | sym::BTreeSet))\n}\n\nfn is_a_std_map_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap))\n}\n\npub(super) fn check(\n    cx: &LateContext<'_>,\n    call_span: Span,\n    get_call: &Expr<'_>,\n    get_caller: &Expr<'_>,\n    arg: &Expr<'_>,\n    is_some: bool,\n) {\n    let caller_ty = cx.typeck_results().expr_ty(get_caller);\n\n    let is_set = is_a_std_set_type(cx, caller_ty);\n    let is_map = is_a_std_map_type(cx, caller_ty);\n\n    if !is_set && !is_map {\n        return;\n    }\n    let ExprKind::MethodCall(path, _, _, get_call_span) = get_call.kind else {\n        return;\n    };\n    let both_calls_span = get_call_span.with_hi(call_span.hi());\n    if let Some(snippet) = both_calls_span.get_source_text(cx)\n        && let Some(arg_snippet) = arg.span.get_source_text(cx)\n    {\n        let generics_snippet = if let Some(generics) = path.args\n            && let Some(generics_snippet) = generics.span_ext.get_source_text(cx)\n        {\n            format!(\"::{generics_snippet}\")\n        } else {\n            String::new()\n        };\n        let suggestion = if is_set {\n            format!(\"contains{generics_snippet}({arg_snippet})\")\n        } else {\n            format!(\"contains_key{generics_snippet}({arg_snippet})\")\n        };\n        if is_some {\n            span_lint_and_sugg(\n                cx,\n                UNNECESSARY_GET_THEN_CHECK,\n                both_calls_span,\n                format!(\"unnecessary use of `{snippet}`\"),\n                \"replace it with\",\n                suggestion,\n                Applicability::MaybeIncorrect,\n            );\n        } else if let Some(caller_snippet) = get_caller.span.get_source_text(cx) {\n            let full_span = get_caller.span.with_hi(call_span.hi());\n\n            span_lint_and_then(\n                cx,\n                UNNECESSARY_GET_THEN_CHECK,\n                both_calls_span,\n                format!(\"unnecessary use of `{snippet}`\"),\n                |diag| {\n                    diag.span_suggestion(\n                        full_span,\n                        \"replace it with\",\n                        format!(\"{}{caller_snippet}.{suggestion}\", if is_some { \"\" } else { \"!\" }),\n                        Applicability::MaybeIncorrect,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_iter_cloned.rs",
    "content": "use super::utils::clone_or_copy_needed;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::ForLoop;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::ty::{get_iterator_item_ty, implements_trait};\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr};\nuse core::ops::ControlFlow;\nuse itertools::Itertools;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{BindingMode, Expr, ExprKind, Node, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::{Symbol, sym};\n\nuse super::UNNECESSARY_TO_OWNED;\n\npub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol, receiver: &Expr<'_>) -> bool {\n    if let Some(parent) = get_parent_expr(cx, expr)\n        && let Some(callee_def_id) = fn_def_id(cx, parent)\n        && is_into_iter(cx, callee_def_id)\n    {\n        check_for_loop_iter(cx, parent, method_name, receiver, false)\n    } else {\n        false\n    }\n}\n\n/// Checks whether `expr` is an iterator in a `for` loop and, if so, determines whether the\n/// iterated-over items could be iterated over by reference. The reason why `check` above does not\n/// include this code directly is so that it can be called from\n/// `unnecessary_into_owned::check_into_iter_call_arg`.\npub fn check_for_loop_iter(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    method_name: Symbol,\n    receiver: &Expr<'_>,\n    cloned_before_iter: bool,\n) -> bool {\n    if let Some(grandparent) = get_parent_expr(cx, expr).and_then(|parent| get_parent_expr(cx, parent))\n        && let Some(ForLoop { pat, body, .. }) = ForLoop::hir(grandparent)\n        && let (clone_or_copy_needed, references_to_binding) = clone_or_copy_needed(cx, pat, body)\n        && !clone_or_copy_needed\n        && let Some(receiver_snippet) = receiver.span.get_source_text(cx)\n    {\n        // Issue 12098\n        // https://github.com/rust-lang/rust-clippy/issues/12098\n        // if the assignee have `mut borrow` conflict with the iteratee\n        // the lint should not execute, former didn't consider the mut case\n\n        // check whether `expr` is mutable\n        fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n            if let Some(hir_id) = expr.res_local_id()\n                && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)\n            {\n                matches!(pat.kind, PatKind::Binding(BindingMode::MUT, ..))\n            } else {\n                true\n            }\n        }\n\n        fn is_caller_or_fields_change(cx: &LateContext<'_>, body: &Expr<'_>, caller: &Expr<'_>) -> bool {\n            let mut change = false;\n            if let ExprKind::Block(block, ..) = body.kind {\n                for_each_expr_without_closures(block, |e| {\n                    match e.kind {\n                        ExprKind::Assign(assignee, _, _) | ExprKind::AssignOp(_, assignee, _) => {\n                            change |= !can_mut_borrow_both(cx, caller, assignee);\n                        },\n                        _ => {},\n                    }\n                    // the return value has no effect but the function need one return value\n                    ControlFlow::<()>::Continue(())\n                });\n            }\n            change\n        }\n\n        if let ExprKind::Call(_, [child, ..]) = expr.kind {\n            // filter first layer of iterator\n            let mut child = child;\n            // get inner real caller requests for clone\n            while let ExprKind::MethodCall(_, caller, _, _) = child.kind {\n                child = caller;\n            }\n            if is_mutable(cx, child) && is_caller_or_fields_change(cx, body, child) {\n                // skip lint\n                return true;\n            }\n        }\n\n        // the lint should not be executed if no violation happens\n        let snippet = if let ExprKind::MethodCall(maybe_iter_method_name, collection, [], _) = receiver.kind\n            && maybe_iter_method_name.ident.name == sym::iter\n            && let Some(iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator)\n            && let receiver_ty = cx.typeck_results().expr_ty(receiver)\n            && implements_trait(cx, receiver_ty, iterator_trait_id, &[])\n            && let Some(iter_item_ty) = get_iterator_item_ty(cx, receiver_ty)\n            && let Some(into_iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::IntoIterator)\n            && let collection_ty = cx.typeck_results().expr_ty(collection)\n            && implements_trait(cx, collection_ty, into_iterator_trait_id, &[])\n            && let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, sym::Item)\n            && iter_item_ty == into_iter_item_ty\n            && let Some(collection_snippet) = collection.span.get_source_text(cx)\n        {\n            collection_snippet\n        } else {\n            receiver_snippet\n        };\n        span_lint_and_then(\n            cx,\n            UNNECESSARY_TO_OWNED,\n            expr.span,\n            format!(\"unnecessary use of `{method_name}`\"),\n            |diag| {\n                // If `check_into_iter_call_arg` called `check_for_loop_iter` because a call to\n                // a `to_owned`-like function was removed, then the next suggestion may be\n                // incorrect. This is because the iterator that results from the call's removal\n                // could hold a reference to a resource that is used mutably. See\n                // https://github.com/rust-lang/rust-clippy/issues/8148.\n                let applicability = if cloned_before_iter {\n                    Applicability::MaybeIncorrect\n                } else {\n                    Applicability::MachineApplicable\n                };\n\n                let combined = references_to_binding\n                    .into_iter()\n                    .chain(vec![(expr.span, snippet.to_owned())])\n                    .collect_vec();\n\n                diag.multipart_suggestion(\"remove any references to the binding\", combined, applicability);\n            },\n        );\n        return true;\n    }\n    false\n}\n\n/// Returns true if the named method is `IntoIterator::into_iter`.\npub fn is_into_iter(cx: &LateContext<'_>, callee_def_id: DefId) -> bool {\n    Some(callee_def_id) == cx.tcx.lang_items().into_iter_fn()\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_join.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, LangItem};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::Span;\n\nuse super::UNNECESSARY_JOIN;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    join_self_arg: &'tcx Expr<'tcx>,\n    join_arg: &'tcx Expr<'tcx>,\n    span: Span,\n) {\n    let applicability = Applicability::MachineApplicable;\n    let collect_output_adjusted_type = cx.typeck_results().expr_ty_adjusted(join_self_arg);\n    if let ty::Ref(_, ref_type, _) = collect_output_adjusted_type.kind()\n        // the turbofish for collect is ::<Vec<String>>\n        && let ty::Slice(slice) = *ref_type.kind()\n        && slice.is_lang_item(cx, LangItem::String)\n        // the argument for join is \"\"\n        && let ExprKind::Lit(spanned) = &join_arg.kind\n        && let LitKind::Str(symbol, _) = spanned.node\n        && symbol.is_empty()\n    {\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_JOIN,\n            span.with_hi(expr.span.hi()),\n            r#\"called `.collect::<Vec<String>>().join(\"\")` on an iterator\"#,\n            \"consider using\",\n            \"collect::<String>()\".to_owned(),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_lazy_eval.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{eager_or_lazy, is_from_proc_macro, usage};\nuse hir::FnRetTy;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::UNNECESSARY_LAZY_EVALUATIONS;\n\n/// lint use of `<fn>_else(simple closure)` for `Option`s and `Result`s that can be\n/// replaced with `<fn>(return value of simple closure)`\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    recv: &'tcx hir::Expr<'_>,\n    arg: &'tcx hir::Expr<'_>,\n    simplify_using: &str,\n) -> bool {\n    let is_option = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Option);\n    let is_result = cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result);\n    let is_bool = cx.typeck_results().expr_ty(recv).is_bool();\n\n    if (is_option || is_result || is_bool)\n        && let hir::ExprKind::Closure(&hir::Closure {\n            body,\n            fn_decl,\n            kind: hir::ClosureKind::Closure,\n            ..\n        }) = arg.kind\n    {\n        let body = cx.tcx.hir_body(body);\n        let body_expr = &body.value;\n\n        if usage::BindingUsageFinder::are_params_used(cx, body) || is_from_proc_macro(cx, expr) {\n            return false;\n        }\n\n        if eager_or_lazy::switch_to_eager_eval(cx, body_expr) {\n            let msg = if is_option {\n                \"unnecessary closure used to substitute value for `Option::None`\"\n            } else if is_result {\n                \"unnecessary closure used to substitute value for `Result::Err`\"\n            } else {\n                \"unnecessary closure used with `bool::then`\"\n            };\n            let applicability = if body\n                .params\n                .iter()\n                // bindings are checked to be unused above\n                .all(|param| matches!(param.pat.kind, hir::PatKind::Binding(..) | hir::PatKind::Wild))\n                && matches!(\n                    fn_decl.output,\n                    FnRetTy::DefaultReturn(_)\n                        | FnRetTy::Return(hir::Ty {\n                            kind: hir::TyKind::Infer(()),\n                            ..\n                        })\n                ) {\n                Applicability::MachineApplicable\n            } else {\n                // replacing the lambda may break type inference\n                Applicability::MaybeIncorrect\n            };\n\n            // This is a duplicate of what's happening in clippy_lints::methods::method_call,\n            // which isn't ideal, We want to get the method call span,\n            // but prefer to avoid changing the signature of the function itself.\n            if let hir::ExprKind::MethodCall(.., span) = expr.kind {\n                span_lint_and_then(cx, UNNECESSARY_LAZY_EVALUATIONS, expr.span, msg, |diag| {\n                    diag.span_suggestion_verbose(\n                        span,\n                        format!(\"use `{simplify_using}` instead\"),\n                        format!(\"{simplify_using}({})\", snippet(cx, body_expr.span, \"..\")),\n                        applicability,\n                    );\n                });\n                return true;\n            }\n        }\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_literal_unwrap.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::{is_none_expr, last_path_segment, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, AmbigArg};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\nuse rustc_span::Symbol;\n\nuse super::UNNECESSARY_LITERAL_UNWRAP;\n\nfn get_ty_from_args<'a>(args: Option<&'a [hir::GenericArg<'a>]>, index: usize) -> Option<&'a hir::Ty<'a, AmbigArg>> {\n    let args = args?;\n\n    if args.len() <= index {\n        return None;\n    }\n\n    match args[index] {\n        hir::GenericArg::Type(ty) => Some(ty),\n        _ => None,\n    }\n}\n\n#[expect(clippy::too_many_lines)]\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    recv: &hir::Expr<'_>,\n    method: Symbol,\n    args: &[hir::Expr<'_>],\n) {\n    let init = clippy_utils::expr_or_init(cx, recv);\n    if init.span.from_expansion() {\n        // don't lint if the receiver or binding initializer comes from a macro\n        // (e.g. `let x = option_env!(..); x.unwrap()`)\n        return;\n    }\n\n    let (constructor, call_args, ty) = if let hir::ExprKind::Call(call, call_args) = init.kind {\n        if let Some((qpath, hir_id)) = call.opt_qpath()\n            && let args = last_path_segment(qpath).args.map(|args| args.args)\n            && let Some(did) = cx.qpath_res(qpath, hir_id).ctor_parent(cx).opt_def_id()\n        {\n            let lang_items = cx.tcx.lang_items();\n            if Some(did) == lang_items.option_some_variant() {\n                (sym::Some, call_args, get_ty_from_args(args, 0))\n            } else if Some(did) == lang_items.result_ok_variant() {\n                (sym::Ok, call_args, get_ty_from_args(args, 0))\n            } else if Some(did) == lang_items.result_err_variant() {\n                (sym::Err, call_args, get_ty_from_args(args, 1))\n            } else {\n                return;\n            }\n        } else {\n            return;\n        }\n    } else if is_none_expr(cx, init) {\n        let call_args: &[hir::Expr<'_>] = &[];\n        (sym::None, call_args, None)\n    } else {\n        return;\n    };\n\n    let help_message = format!(\"used `{method}()` on `{constructor}` value\");\n    let suggestion_message = format!(\"remove the `{constructor}` and `{method}()`\");\n\n    span_lint_and_then(cx, UNNECESSARY_LITERAL_UNWRAP, expr.span, help_message, |diag| {\n        let suggestions = match (constructor, method, ty) {\n            (sym::None, sym::unwrap, _) => Some(vec![(expr.span, \"panic!()\".to_string())]),\n            (sym::None, sym::expect, _) => Some(vec![\n                (expr.span.with_hi(args[0].span.lo()), \"panic!(\".to_string()),\n                (expr.span.with_lo(args[0].span.hi()), \")\".to_string()),\n            ]),\n            (sym::Some | sym::Ok, sym::unwrap_unchecked, _) | (sym::Err, sym::unwrap_err_unchecked, _) => {\n                let mut suggs = vec![\n                    (recv.span.with_hi(call_args[0].span.lo()), String::new()),\n                    (expr.span.with_lo(call_args[0].span.hi()), String::new()),\n                ];\n                // try to also remove the unsafe block if present\n                if let hir::Node::Block(block) = cx.tcx.parent_hir_node(expr.hir_id)\n                    && let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules\n                {\n                    suggs.extend([\n                        (block.span.shrink_to_lo().to(expr.span.shrink_to_lo()), String::new()),\n                        (expr.span.shrink_to_hi().to(block.span.shrink_to_hi()), String::new()),\n                    ]);\n                }\n                Some(suggs)\n            },\n            (sym::None, sym::unwrap_or_default, _) => {\n                let ty = cx.typeck_results().expr_ty(expr);\n                let default_ty_string = if let ty::Adt(def, ..) = ty.kind() {\n                    with_forced_trimmed_paths!(format!(\"{}\", cx.tcx.def_path_str(def.did())))\n                } else {\n                    \"Default\".to_string()\n                };\n                Some(vec![(expr.span, format!(\"{default_ty_string}::default()\"))])\n            },\n            (sym::None, sym::unwrap_or, _) => Some(vec![\n                (expr.span.with_hi(args[0].span.lo()), String::new()),\n                (expr.span.with_lo(args[0].span.hi()), String::new()),\n            ]),\n            (sym::None, sym::unwrap_or_else, _) => match args[0].kind {\n                hir::ExprKind::Closure(hir::Closure { body, .. }) => Some(vec![\n                    (expr.span.with_hi(cx.tcx.hir_body(*body).value.span.lo()), String::new()),\n                    (expr.span.with_lo(args[0].span.hi()), String::new()),\n                ]),\n                _ => None,\n            },\n            _ if call_args.is_empty() => None,\n            (_, _, Some(_)) => None,\n            (sym::Ok, sym::unwrap_err, None) | (sym::Err, sym::unwrap, None) => Some(vec![\n                (\n                    recv.span.with_hi(call_args[0].span.lo()),\n                    \"panic!(\\\"{:?}\\\", \".to_string(),\n                ),\n                (expr.span.with_lo(call_args[0].span.hi()), \")\".to_string()),\n            ]),\n            (sym::Ok, sym::expect_err, None) | (sym::Err, sym::expect, None) => Some(vec![\n                (\n                    recv.span.with_hi(call_args[0].span.lo()),\n                    \"panic!(\\\"{1}: {:?}\\\", \".to_string(),\n                ),\n                (call_args[0].span.with_lo(args[0].span.lo()), \", \".to_string()),\n            ]),\n            (_, _, None) => Some(vec![\n                (recv.span.with_hi(call_args[0].span.lo()), String::new()),\n                (expr.span.with_lo(call_args[0].span.hi()), String::new()),\n            ]),\n        };\n\n        match (init.span == recv.span, suggestions) {\n            (true, Some(suggestions)) => {\n                diag.multipart_suggestion(suggestion_message, suggestions, Applicability::MachineApplicable);\n            },\n            _ => {\n                diag.span_help(init.span, suggestion_message);\n            },\n        }\n    });\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_map_or.rs",
    "content": "use std::borrow::Cow;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::eager_or_lazy::switch_to_eager_eval;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::sugg::{Sugg, make_binop};\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse clippy_utils::visitors::is_local_used;\nuse clippy_utils::{get_parent_expr, is_from_proc_macro};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, PatKind};\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, sym};\n\nuse super::UNNECESSARY_MAP_OR;\n\npub(super) enum Variant {\n    Ok,\n    Some,\n}\nimpl Variant {\n    pub fn variant_name(&self) -> &'static str {\n        match self {\n            Variant::Ok => \"Ok\",\n            Variant::Some => \"Some\",\n        }\n    }\n\n    pub fn method_name(&self) -> &'static str {\n        match self {\n            Variant::Ok => \"is_ok_and\",\n            Variant::Some => \"is_some_and\",\n        }\n    }\n}\n\npub(super) fn check<'a>(\n    cx: &LateContext<'a>,\n    expr: &Expr<'a>,\n    recv: &Expr<'_>,\n    def: &Expr<'_>,\n    map: &Expr<'_>,\n    method_span: Span,\n    msrv: Msrv,\n) {\n    let ExprKind::Lit(def_kind) = def.kind else {\n        return;\n    };\n    let LitKind::Bool(def_bool) = def_kind.node else {\n        return;\n    };\n\n    let typeck = cx.typeck_results();\n\n    let recv_ty = typeck.expr_ty_adjusted(recv);\n\n    let variant = match recv_ty.opt_diag_name(cx) {\n        Some(sym::Option) => Variant::Some,\n        Some(sym::Result) => Variant::Ok,\n        Some(_) | None => return,\n    };\n\n    let ext_def_span = def.span.until(map.span);\n\n    let (sugg, method, applicability): (_, Cow<'_, _>, _) = if typeck.expr_adjustments(recv).is_empty()\n            && let ExprKind::Closure(map_closure) = map.kind\n            && let closure_body = cx.tcx.hir_body(map_closure.body)\n            && let closure_body_value = closure_body.value.peel_blocks()\n            && let ExprKind::Binary(op, l, r) = closure_body_value.kind\n            && let [param] = closure_body.params\n            && let PatKind::Binding(_, hir_id, _, _) = param.pat.kind\n            // checking that map_or is one of the following:\n            // .map_or(false, |x| x == y)\n            // .map_or(false, |x| y == x) - swapped comparison\n            // .map_or(true, |x| x != y)\n            // .map_or(true, |x| y != x) - swapped comparison\n            && ((BinOpKind::Eq == op.node && !def_bool) || (BinOpKind::Ne == op.node && def_bool))\n            && let non_binding_location = if l.res_local_id() == Some(hir_id) { r } else { l }\n            && switch_to_eager_eval(cx, non_binding_location)\n            // if it's both then that's a strange edge case and\n            // we can just ignore it, since by default clippy will error on this\n            && (l.res_local_id() == Some(hir_id)) != (r.res_local_id() == Some(hir_id))\n            && !is_local_used(cx, non_binding_location, hir_id)\n            && let l_ty = typeck.expr_ty(l)\n            && l_ty == typeck.expr_ty(r)\n            && let Some(partial_eq) = cx.tcx.lang_items().eq_trait()\n            && implements_trait(cx, recv_ty, partial_eq, &[recv_ty.into()])\n            && is_copy(cx, l_ty)\n    {\n        let wrap = variant.variant_name();\n\n        // we may need to add parens around the suggestion\n        // in case the parent expression has additional method calls,\n        // since for example `Some(5).map_or(false, |x| x == 5).then(|| 1)`\n        // being converted to `Some(5) == Some(5).then(|| 1)` isn't\n        // the same thing\n\n        let mut app = Applicability::MachineApplicable;\n        let inner_non_binding = Sugg::NonParen(Cow::Owned(format!(\n            \"{wrap}({})\",\n            Sugg::hir_with_applicability(cx, non_binding_location, \"\", &mut app)\n        )));\n\n        let binop = make_binop(\n            op.node,\n            &Sugg::hir_with_applicability(cx, recv, \"..\", &mut app),\n            &inner_non_binding,\n        );\n\n        let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr) {\n            if parent_expr.span.eq_ctxt(expr.span) {\n                match parent_expr.kind {\n                    ExprKind::Binary(..) | ExprKind::Unary(..) | ExprKind::Cast(..) => binop.maybe_paren(),\n                    ExprKind::MethodCall(_, receiver, _, _) if receiver.hir_id == expr.hir_id => binop.maybe_paren(),\n                    _ => binop,\n                }\n            } else {\n                // if our parent expr is created by a macro, then it should be the one taking care of\n                // parenthesising us if necessary\n                binop\n            }\n        } else {\n            binop\n        }\n        .into_string();\n\n        (vec![(expr.span, sugg)], \"a standard comparison\".into(), app)\n    } else if !def_bool && msrv.meets(cx, msrvs::OPTION_RESULT_IS_VARIANT_AND) {\n        let suggested_name = variant.method_name();\n        (\n            vec![(method_span, suggested_name.into()), (ext_def_span, String::new())],\n            format!(\"`{suggested_name}`\").into(),\n            Applicability::MachineApplicable,\n        )\n    } else if def_bool && matches!(variant, Variant::Some) && msrv.meets(cx, msrvs::IS_NONE_OR) {\n        (\n            vec![(method_span, \"is_none_or\".into()), (ext_def_span, String::new())],\n            \"`is_none_or`\".into(),\n            Applicability::MachineApplicable,\n        )\n    } else {\n        return;\n    };\n\n    if is_from_proc_macro(cx, expr) {\n        return;\n    }\n\n    span_lint_and_then(\n        cx,\n        UNNECESSARY_MAP_OR,\n        expr.span,\n        \"this `map_or` can be simplified\",\n        |diag| {\n            diag.multipart_suggestion(format!(\"use {method} instead\"), sugg, applicability);\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_map_or_else.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_expr_identity_function;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\nuse rustc_span::symbol::sym;\n\nuse super::{UNNECESSARY_OPTION_MAP_OR_ELSE, UNNECESSARY_RESULT_MAP_OR_ELSE};\n\n/// lint use of `_.map_or_else(|err| err, |n| n)` for `Result`s and `Option`s.\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    recv: &Expr<'_>,\n    def_arg: &Expr<'_>,\n    map_arg: &Expr<'_>,\n    call_span: Span,\n) {\n    let (symbol, lint) = match cx.typeck_results().expr_ty(recv).opt_diag_name(cx) {\n        Some(x @ sym::Result) => (x, UNNECESSARY_RESULT_MAP_OR_ELSE),\n        Some(x @ sym::Option) => (x, UNNECESSARY_OPTION_MAP_OR_ELSE),\n        _ => return,\n    };\n\n    if is_expr_identity_function(cx, map_arg) {\n        let msg = format!(\"unused \\\"map closure\\\" when calling `{symbol}::map_or_else` value\");\n\n        span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n            let mut applicability = Applicability::MachineApplicable;\n            let err_snippet = snippet_with_applicability(cx, def_arg.span, \"..\", &mut applicability);\n            let sugg = format!(\"unwrap_or_else({err_snippet})\");\n\n            diag.span_suggestion_verbose(call_span, \"consider using `unwrap_or_else`\", sugg, applicability);\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_min_or_max.rs",
    "content": "use std::cmp::Ordering;\n\nuse super::UNNECESSARY_MIN_OR_MAX;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant, FullInt};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\n\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, Symbol};\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    name: Symbol,\n    recv: &'tcx Expr<'_>,\n    arg: &'tcx Expr<'_>,\n) {\n    let typeck_results = cx.typeck_results();\n    let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), typeck_results);\n    if let Some(id) = typeck_results.type_dependent_def_id(expr.hir_id)\n        && let Some(fn_name) = cx.tcx.get_diagnostic_name(id)\n        && matches!(fn_name, sym::cmp_ord_min | sym::cmp_ord_max)\n    {\n        let ctxt = expr.span.ctxt();\n        if let Some(left) = ecx.eval_local(recv, ctxt)\n            && let Some(right) = ecx.eval_local(arg, ctxt)\n        {\n            let Some(ord) = Constant::partial_cmp(cx.tcx, typeck_results.expr_ty(recv), &left, &right) else {\n                return;\n            };\n\n            lint(cx, expr, name, recv.span, arg.span, ord);\n        } else if let Some(extrema) = detect_extrema(cx, recv) {\n            let ord = match extrema {\n                Extrema::Minimum => Ordering::Less,\n                Extrema::Maximum => Ordering::Greater,\n            };\n            lint(cx, expr, name, recv.span, arg.span, ord);\n        } else if let Some(extrema) = detect_extrema(cx, arg) {\n            let ord = match extrema {\n                Extrema::Minimum => Ordering::Greater,\n                Extrema::Maximum => Ordering::Less,\n            };\n            lint(cx, expr, name, recv.span, arg.span, ord);\n        }\n    }\n}\n\nfn lint(cx: &LateContext<'_>, expr: &Expr<'_>, name: Symbol, lhs: Span, rhs: Span, order: Ordering) {\n    let cmp_str = if order.is_ge() { \"smaller\" } else { \"greater\" };\n\n    let suggested_value = if (name == sym::min && order.is_ge()) || (name == sym::max && order.is_le()) {\n        snippet(cx, rhs, \"..\")\n    } else {\n        snippet(cx, lhs, \"..\")\n    };\n\n    span_lint_and_sugg(\n        cx,\n        UNNECESSARY_MIN_OR_MAX,\n        expr.span,\n        format!(\n            \"`{}` is never {} than `{}` and has therefore no effect\",\n            snippet(cx, lhs, \"..\"),\n            cmp_str,\n            snippet(cx, rhs, \"..\")\n        ),\n        \"try\",\n        suggested_value.to_string(),\n        Applicability::MachineApplicable,\n    );\n}\n\n#[derive(Debug)]\nenum Extrema {\n    Minimum,\n    Maximum,\n}\nfn detect_extrema<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<Extrema> {\n    let ty = cx.typeck_results().expr_ty(expr);\n\n    let cv = ConstEvalCtxt::new(cx).eval(expr)?;\n\n    match (cv.int_value(cx.tcx, ty)?, ty.kind()) {\n        (FullInt::S(i), &ty::Int(ity)) if i == i128::MIN >> (128 - ity.bit_width()?) => Some(Extrema::Minimum),\n        (FullInt::S(i), &ty::Int(ity)) if i == i128::MAX >> (128 - ity.bit_width()?) => Some(Extrema::Maximum),\n        (FullInt::U(i), &ty::Uint(uty))\n            if {\n                let bits = match uty {\n                    ty::UintTy::Usize => u32::try_from(cx.tcx.data_layout.pointer_size().bits()).ok()?,\n                    _ => u32::try_from(uty.bit_width()?).ok()?,\n                };\n                i == u128::MAX >> (128 - bits)\n            } =>\n        {\n            Some(Extrema::Maximum)\n        },\n        (FullInt::U(0), &ty::Uint(_)) => Some(Extrema::Minimum),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_sort_by.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::std_or_core;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::{implements_trait, is_copy, peel_n_ty_refs};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, GenericArgKind, Ty};\nuse rustc_span::symbol::Ident;\nuse rustc_span::{Span, sym};\nuse std::iter;\nuse std::ops::Not;\n\nuse super::UNNECESSARY_SORT_BY;\n\nenum LintTrigger {\n    Sort,\n    SortByKey(SortByKeyDetection),\n}\n\nstruct SortByKeyDetection {\n    closure_arg: Span,\n    closure_body: String,\n    reverse: bool,\n    applicability: Applicability,\n}\n\n/// Detect if the two expressions are mirrored (identical, except one\n/// contains a and the other replaces it with b)\nfn mirrored_exprs(\n    a_expr: &Expr<'_>,\n    b_expr: &Expr<'_>,\n    binding_map: &BindingMap,\n    binding_source: BindingSource,\n) -> bool {\n    match (a_expr.kind, b_expr.kind) {\n        // Two arrays with mirrored contents\n        (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => iter::zip(left_exprs, right_exprs)\n            .all(|(left, right)| mirrored_exprs(left, right, binding_map, binding_source)),\n        // The two exprs are function calls.\n        // Check to see that the function itself and its arguments are mirrored\n        (ExprKind::Call(left_expr, left_args), ExprKind::Call(right_expr, right_args)) => {\n            mirrored_exprs(left_expr, right_expr, binding_map, binding_source)\n                && iter::zip(left_args, right_args)\n                    .all(|(left, right)| mirrored_exprs(left, right, binding_map, binding_source))\n        },\n        // The two exprs are method calls.\n        // Check to see that the function is the same and the arguments and receivers are mirrored\n        (\n            ExprKind::MethodCall(left_segment, left_receiver, left_args, _),\n            ExprKind::MethodCall(right_segment, right_receiver, right_args, _),\n        ) => {\n            left_segment.ident == right_segment.ident\n                && iter::zip(left_args, right_args)\n                    .all(|(left, right)| mirrored_exprs(left, right, binding_map, binding_source))\n                && mirrored_exprs(left_receiver, right_receiver, binding_map, binding_source)\n        },\n        // Two tuples with mirrored contents\n        (ExprKind::Tup(left_exprs), ExprKind::Tup(right_exprs)) => iter::zip(left_exprs, right_exprs)\n            .all(|(left, right)| mirrored_exprs(left, right, binding_map, binding_source)),\n        // Two binary ops, which are the same operation and which have mirrored arguments\n        (ExprKind::Binary(left_op, left_left, left_right), ExprKind::Binary(right_op, right_left, right_right)) => {\n            left_op.node == right_op.node\n                && mirrored_exprs(left_left, right_left, binding_map, binding_source)\n                && mirrored_exprs(left_right, right_right, binding_map, binding_source)\n        },\n        // Two unary ops, which are the same operation and which have the same argument\n        (ExprKind::Unary(left_op, left_expr), ExprKind::Unary(right_op, right_expr)) => {\n            left_op == right_op && mirrored_exprs(left_expr, right_expr, binding_map, binding_source)\n        },\n        // The two exprs are literals of some kind\n        (ExprKind::Lit(left_lit), ExprKind::Lit(right_lit)) => left_lit.node == right_lit.node,\n        (ExprKind::Cast(left, _), ExprKind::Cast(right, _)) => mirrored_exprs(left, right, binding_map, binding_source),\n        (ExprKind::DropTemps(left_block), ExprKind::DropTemps(right_block)) => {\n            mirrored_exprs(left_block, right_block, binding_map, binding_source)\n        },\n        (ExprKind::Field(left_expr, left_ident), ExprKind::Field(right_expr, right_ident)) => {\n            left_ident.name == right_ident.name && mirrored_exprs(left_expr, right_expr, binding_map, binding_source)\n        },\n        // Two paths: either one is a and the other is b, or they're identical to each other\n        (\n            ExprKind::Path(QPath::Resolved(\n                _,\n                &Path {\n                    segments: left_segments,\n                    ..\n                },\n            )),\n            ExprKind::Path(QPath::Resolved(\n                _,\n                &Path {\n                    segments: right_segments,\n                    ..\n                },\n            )),\n        ) => {\n            (iter::zip(left_segments, right_segments).all(|(left, right)| left.ident == right.ident)\n                && left_segments.iter().all(|seg| {\n                    !binding_map.contains_key(&BindingKey {\n                        ident: seg.ident,\n                        source: BindingSource::Left,\n                    }) && !binding_map.contains_key(&BindingKey {\n                        ident: seg.ident,\n                        source: BindingSource::Right,\n                    })\n                }))\n                || (left_segments.len() == 1\n                    && right_segments.len() == 1\n                    && binding_map\n                        .get(&BindingKey {\n                            ident: left_segments[0].ident,\n                            source: binding_source,\n                        })\n                        .is_some_and(|value| value.mirrored.ident == right_segments[0].ident))\n        },\n        // Matching expressions, but one or both is borrowed\n        (\n            ExprKind::AddrOf(left_kind, Mutability::Not, left_expr),\n            ExprKind::AddrOf(right_kind, Mutability::Not, right_expr),\n        ) => left_kind == right_kind && mirrored_exprs(left_expr, right_expr, binding_map, binding_source),\n        (_, ExprKind::AddrOf(_, Mutability::Not, right_expr)) => {\n            mirrored_exprs(a_expr, right_expr, binding_map, binding_source)\n        },\n        (ExprKind::AddrOf(_, Mutability::Not, left_expr), _) => {\n            mirrored_exprs(left_expr, b_expr, binding_map, binding_source)\n        },\n        _ => false,\n    }\n}\n\n#[derive(Copy, Clone, PartialEq, Eq, Hash)]\nenum BindingSource {\n    Left,\n    Right,\n}\n\nimpl Not for BindingSource {\n    type Output = BindingSource;\n\n    fn not(self) -> Self::Output {\n        match self {\n            BindingSource::Left => BindingSource::Right,\n            BindingSource::Right => BindingSource::Left,\n        }\n    }\n}\n\n#[derive(Copy, Clone, PartialEq, Eq, Hash)]\nstruct BindingKey {\n    /// The identifier of the binding.\n    ident: Ident,\n    /// The source of the binding.\n    source: BindingSource,\n}\n\nstruct BindingValue {\n    /// The mirrored binding.\n    mirrored: BindingKey,\n    /// The number of refs the binding is wrapped in.\n    n_refs: usize,\n}\n\n/// A map from binding info to the number of refs the binding is wrapped in.\ntype BindingMap = FxHashMap<BindingKey, BindingValue>;\n/// Extract the binding pairs, if the two patterns are mirrored. The pats are assumed to be used in\n/// closure inputs and thus irrefutable.\nfn mapping_of_mirrored_pats(a_pat: &Pat<'_>, b_pat: &Pat<'_>) -> Option<BindingMap> {\n    fn mapping_of_mirrored_pats_inner(\n        a_pat: &Pat<'_>,\n        b_pat: &Pat<'_>,\n        mapping: &mut BindingMap,\n        n_refs: usize,\n    ) -> bool {\n        match (&a_pat.kind, &b_pat.kind) {\n            (PatKind::Tuple(a_pats, a_dots), PatKind::Tuple(b_pats, b_dots)) => {\n                a_dots == b_dots\n                    && a_pats.len() == b_pats.len()\n                    && iter::zip(a_pats.iter(), b_pats.iter())\n                        .all(|(a, b)| mapping_of_mirrored_pats_inner(a, b, mapping, n_refs))\n            },\n            (PatKind::Binding(_, _, a_ident, _), PatKind::Binding(_, _, b_ident, _)) => {\n                let a_key = BindingKey {\n                    ident: *a_ident,\n                    source: BindingSource::Left,\n                };\n                let b_key = BindingKey {\n                    ident: *b_ident,\n                    source: BindingSource::Right,\n                };\n                let a_value = BindingValue {\n                    mirrored: b_key,\n                    n_refs,\n                };\n                let b_value = BindingValue {\n                    mirrored: a_key,\n                    n_refs,\n                };\n                mapping.insert(a_key, a_value);\n                mapping.insert(b_key, b_value);\n                true\n            },\n            (PatKind::Wild, PatKind::Wild) => true,\n            (PatKind::TupleStruct(_, a_pats, a_dots), PatKind::TupleStruct(_, b_pats, b_dots)) => {\n                a_dots == b_dots\n                    && a_pats.len() == b_pats.len()\n                    && iter::zip(a_pats.iter(), b_pats.iter())\n                        .all(|(a, b)| mapping_of_mirrored_pats_inner(a, b, mapping, n_refs))\n            },\n            (PatKind::Struct(_, a_fields, a_rest), PatKind::Struct(_, b_fields, b_rest)) => {\n                a_rest == b_rest\n                    && a_fields.len() == b_fields.len()\n                    && iter::zip(a_fields.iter(), b_fields.iter()).all(|(a_field, b_field)| {\n                        a_field.ident == b_field.ident\n                            && mapping_of_mirrored_pats_inner(a_field.pat, b_field.pat, mapping, n_refs)\n                    })\n            },\n            (PatKind::Ref(a_inner, _, _), PatKind::Ref(b_inner, _, _)) => {\n                mapping_of_mirrored_pats_inner(a_inner, b_inner, mapping, n_refs + 1)\n            },\n            (PatKind::Slice(a_elems, None, a_rest), PatKind::Slice(b_elems, None, b_rest)) => {\n                a_elems.len() == b_elems.len()\n                    && iter::zip(a_elems.iter(), b_elems.iter())\n                        .all(|(a, b)| mapping_of_mirrored_pats_inner(a, b, mapping, n_refs))\n                    && a_rest.len() == b_rest.len()\n                    && iter::zip(a_rest.iter(), b_rest.iter())\n                        .all(|(a, b)| mapping_of_mirrored_pats_inner(a, b, mapping, n_refs))\n            },\n            _ => false,\n        }\n    }\n\n    let mut mapping = FxHashMap::default();\n    if mapping_of_mirrored_pats_inner(a_pat, b_pat, &mut mapping, 0) {\n        return Some(mapping);\n    }\n\n    None\n}\n\nfn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>) -> Option<LintTrigger> {\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && cx.tcx.type_of(impl_id).instantiate_identity().is_slice()\n        && let ExprKind::Closure(&Closure { body, .. }) = arg.kind\n        && let closure_body = cx.tcx.hir_body(body)\n        && let &[Param { pat: l_pat, .. }, Param { pat: r_pat, .. }] = closure_body.params\n        && let Some(binding_map) = mapping_of_mirrored_pats(l_pat, r_pat)\n        && let ExprKind::MethodCall(method_path, left_expr, [right_expr], _) = closure_body.value.kind\n        && method_path.ident.name == sym::cmp\n        && let Some(ord_trait) = cx.tcx.get_diagnostic_item(sym::Ord)\n        && cx.ty_based_def(closure_body.value).opt_parent(cx).opt_def_id() == Some(ord_trait)\n    {\n        let (closure_body, closure_arg, reverse) =\n            if mirrored_exprs(left_expr, right_expr, &binding_map, BindingSource::Left) {\n                (left_expr, l_pat.span, false)\n            } else if mirrored_exprs(left_expr, right_expr, &binding_map, BindingSource::Right) {\n                (left_expr, r_pat.span, true)\n            } else {\n                return None;\n            };\n\n        let mut applicability = if reverse {\n            Applicability::MaybeIncorrect\n        } else {\n            Applicability::MachineApplicable\n        };\n\n        if let ExprKind::Path(QPath::Resolved(\n            _,\n            Path {\n                segments: [PathSegment { ident: left_name, .. }],\n                ..\n            },\n        )) = left_expr.kind\n        {\n            if let PatKind::Binding(_, _, left_ident, _) = l_pat.kind\n                && *left_name == left_ident\n                && implements_trait(cx, cx.typeck_results().expr_ty(left_expr), ord_trait, &[])\n            {\n                return Some(LintTrigger::Sort);\n            }\n\n            let mut left_expr_ty = cx.typeck_results().expr_ty(left_expr);\n            let left_ident_n_refs = binding_map\n                .get(&BindingKey {\n                    ident: *left_name,\n                    source: BindingSource::Left,\n                })\n                .map_or(0, |value| value.n_refs);\n            // Peel off the outer-most ref which is introduced by the closure, if it is not already peeled\n            // by the pattern\n            if left_ident_n_refs == 0 {\n                (left_expr_ty, _) = peel_n_ty_refs(left_expr_ty, 1);\n            }\n            if !reverse && is_copy(cx, left_expr_ty) {\n                let mut closure_body =\n                    snippet_with_applicability(cx, closure_body.span, \"_\", &mut applicability).to_string();\n                if left_ident_n_refs == 0 {\n                    closure_body = format!(\"*{closure_body}\");\n                }\n                return Some(LintTrigger::SortByKey(SortByKeyDetection {\n                    closure_arg,\n                    closure_body,\n                    reverse,\n                    applicability,\n                }));\n            }\n        }\n\n        let left_expr_ty = cx.typeck_results().expr_ty(left_expr);\n        if !expr_borrows(left_expr_ty)\n            // Don't lint if the closure is accessing non-Copy fields\n            && (!expr_is_field_access(left_expr) || is_copy(cx, left_expr_ty))\n        {\n            let closure_body = Sugg::hir_with_applicability(cx, closure_body, \"_\", &mut applicability).to_string();\n            return Some(LintTrigger::SortByKey(SortByKeyDetection {\n                closure_arg,\n                closure_body,\n                reverse,\n                applicability,\n            }));\n        }\n    }\n\n    None\n}\n\nfn expr_borrows(ty: Ty<'_>) -> bool {\n    matches!(ty.kind(), ty::Ref(..)) || ty.walk().any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(_)))\n}\n\nfn expr_is_field_access(expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Field(_, _) => true,\n        ExprKind::AddrOf(_, Mutability::Not, inner) => expr_is_field_access(inner),\n        _ => false,\n    }\n}\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    call_span: Span,\n    arg: &'tcx Expr<'_>,\n    is_unstable: bool,\n) {\n    match detect_lint(cx, expr, arg) {\n        Some(LintTrigger::SortByKey(trigger)) => {\n            let method = if is_unstable {\n                \"sort_unstable_by_key\"\n            } else {\n                \"sort_by_key\"\n            };\n            let Some(std_or_core) = std_or_core(cx) else {\n                // To make it this far the crate has to reference diagnostic items defined in core. Either this is\n                // the `core` crate, there's an `extern crate core` somewhere, or another crate is defining the\n                // diagnostic items. It's fine to not lint in all those cases even if we might be able to.\n                return;\n            };\n            span_lint_and_then(\n                cx,\n                UNNECESSARY_SORT_BY,\n                expr.span,\n                format!(\"consider using `{method}`\"),\n                |diag| {\n                    let mut app = trigger.applicability;\n                    let closure_body = if trigger.reverse {\n                        format!(\"{std_or_core}::cmp::Reverse({})\", trigger.closure_body)\n                    } else {\n                        trigger.closure_body\n                    };\n                    let closure_arg = snippet_with_applicability(cx, trigger.closure_arg, \"_\", &mut app);\n                    diag.span_suggestion_verbose(\n                        call_span,\n                        \"try\",\n                        format!(\"{method}(|{closure_arg}| {closure_body})\"),\n                        app,\n                    );\n                },\n            );\n        },\n        Some(LintTrigger::Sort) => {\n            let method = if is_unstable { \"sort_unstable\" } else { \"sort\" };\n            span_lint_and_then(\n                cx,\n                UNNECESSARY_SORT_BY,\n                expr.span,\n                format!(\"consider using `{method}`\"),\n                |diag| {\n                    diag.span_suggestion_verbose(\n                        call_span,\n                        \"try\",\n                        format!(\"{method}()\"),\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        },\n        None => {},\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unnecessary_to_owned.rs",
    "content": "use super::implicit_clone::is_clone_like;\nuse super::unnecessary_iter_cloned::{self, is_into_iter};\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{SpanRangeExt, snippet, snippet_with_context};\nuse clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, peel_and_count_ty_refs};\nuse clippy_utils::visitors::find_all_ret_expressions;\nuse clippy_utils::{fn_def_id, get_parent_expr, is_expr_temporary_value, return_ty, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::Mutability;\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind, OverloadedDeref};\nuse rustc_middle::ty::{\n    self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty,\n};\nuse rustc_span::Symbol;\nuse rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;\nuse rustc_trait_selection::traits::{Obligation, ObligationCause};\n\nuse super::UNNECESSARY_TO_OWNED;\n\npub fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    method_name: Symbol,\n    receiver: &'tcx Expr<'_>,\n    args: &'tcx [Expr<'_>],\n    msrv: Msrv,\n) {\n    if let Some(method_parent_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id).opt_parent(cx)\n        && args.is_empty()\n    {\n        if is_cloned_or_copied(cx, method_name, method_parent_id) {\n            unnecessary_iter_cloned::check(cx, expr, method_name, receiver);\n        } else if is_to_owned_like(cx, expr, method_name, method_parent_id) {\n            if check_split_call_arg(cx, expr, method_name, receiver) {\n                return;\n            }\n            // At this point, we know the call is of a `to_owned`-like function. The functions\n            // `check_addr_of_expr` and `check_into_iter_call_arg` determine whether the call is unnecessary\n            // based on its context, that is, whether it is a referent in an `AddrOf` expression, an\n            // argument in a `into_iter` call, or an argument in the call of some other function.\n            if check_addr_of_expr(cx, expr, method_name, method_parent_id, receiver) {\n                return;\n            }\n            if check_into_iter_call_arg(cx, expr, method_name, receiver, msrv) {\n                return;\n            }\n            if check_string_from_utf8(cx, expr, receiver) {\n                return;\n            }\n            check_other_call_arg(cx, expr, method_name, receiver);\n        }\n    } else {\n        check_borrow_predicate(cx, expr);\n    }\n}\n\n/// Checks whether `expr` is a referent in an `AddrOf` expression and, if so, determines whether its\n/// call of a `to_owned`-like function is unnecessary.\n#[expect(clippy::too_many_lines)]\nfn check_addr_of_expr(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    method_name: Symbol,\n    method_parent_id: DefId,\n    receiver: &Expr<'_>,\n) -> bool {\n    if let Some(parent) = get_parent_expr(cx, expr)\n        && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, _) = parent.kind\n        && let adjustments = cx.typeck_results().expr_adjustments(parent).iter().collect::<Vec<_>>()\n        && let\n            // For matching uses of `Cow::from`\n            [\n                Adjustment {\n                    kind: Adjust::Deref(DerefAdjustKind::Builtin),\n                    target: referent_ty,\n                },\n                Adjustment {\n                    kind: Adjust::Borrow(_),\n                    target: target_ty,\n                },\n            ]\n            // For matching uses of arrays\n            | [\n                Adjustment {\n                    kind: Adjust::Deref(DerefAdjustKind::Builtin),\n                    target: referent_ty,\n                },\n                Adjustment {\n                    kind: Adjust::Borrow(_),\n                    ..\n                },\n                Adjustment {\n                    kind: Adjust::Pointer(_),\n                    target: target_ty,\n                },\n            ]\n            // For matching everything else\n            | [\n                Adjustment {\n                    kind: Adjust::Deref(DerefAdjustKind::Builtin),\n                    target: referent_ty,\n                },\n                Adjustment {\n                    kind: Adjust::Deref(DerefAdjustKind::Overloaded(OverloadedDeref { .. })),\n                    ..\n                },\n                Adjustment {\n                    kind: Adjust::Borrow(_),\n                    target: target_ty,\n                },\n            ] = adjustments[..]\n        && let receiver_ty = cx.typeck_results().expr_ty(receiver)\n        && let (target_ty, n_target_refs, _) = peel_and_count_ty_refs(*target_ty)\n        && let (receiver_ty, n_receiver_refs, _) = peel_and_count_ty_refs(receiver_ty)\n        // Only flag cases satisfying at least one of the following three conditions:\n        // * the referent and receiver types are distinct\n        // * the referent/receiver type is a copyable array\n        // * the method is `Cow::into_owned`\n        // This restriction is to ensure there is no overlap between `redundant_clone` and this\n        // lint. It also avoids the following false positive:\n        //  https://github.com/rust-lang/rust-clippy/issues/8759\n        //   Arrays are a bit of a corner case. Non-copyable arrays are handled by\n        // `redundant_clone`, but copyable arrays are not.\n        && (*referent_ty != receiver_ty\n            || (matches!(referent_ty.kind(), ty::Array(..)) && is_copy(cx, *referent_ty))\n            || is_cow_into_owned(cx, method_name, method_parent_id))\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let (receiver_snippet, _) = snippet_with_context(cx, receiver.span, expr.span.ctxt(), \"..\", &mut applicability);\n\n        if receiver_ty == target_ty && n_target_refs >= n_receiver_refs {\n            span_lint_and_sugg(\n                cx,\n                UNNECESSARY_TO_OWNED,\n                parent.span,\n                format!(\"unnecessary use of `{method_name}`\"),\n                \"use\",\n                format!(\n                    \"{:&>width$}{receiver_snippet}\",\n                    \"\",\n                    width = n_target_refs - n_receiver_refs\n                ),\n                applicability,\n            );\n            return true;\n        }\n        if let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)\n            && implements_trait(cx, receiver_ty, deref_trait_id, &[])\n            && cx.get_associated_type(receiver_ty, deref_trait_id, sym::Target) == Some(target_ty)\n            // Make sure that it's actually calling the right `.to_string()`, (#10033)\n            // *or* this is a `Cow::into_owned()` call (which would be the wrong into_owned receiver (str != Cow)\n            // but that's ok for Cow::into_owned specifically)\n            && (cx.typeck_results().expr_ty_adjusted(receiver).peel_refs() == target_ty\n                || is_cow_into_owned(cx, method_name, method_parent_id))\n        {\n            if n_receiver_refs > 0 {\n                span_lint_and_sugg(\n                    cx,\n                    UNNECESSARY_TO_OWNED,\n                    parent.span,\n                    format!(\"unnecessary use of `{method_name}`\"),\n                    \"use\",\n                    receiver_snippet.to_string(),\n                    applicability,\n                );\n            } else {\n                span_lint_and_sugg(\n                    cx,\n                    UNNECESSARY_TO_OWNED,\n                    expr.span.with_lo(receiver.span.hi()),\n                    format!(\"unnecessary use of `{method_name}`\"),\n                    \"remove this\",\n                    String::new(),\n                    applicability,\n                );\n            }\n            return true;\n        }\n        if let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)\n            && implements_trait(cx, receiver_ty, as_ref_trait_id, &[GenericArg::from(target_ty)])\n        {\n            span_lint_and_sugg(\n                cx,\n                UNNECESSARY_TO_OWNED,\n                parent.span,\n                format!(\"unnecessary use of `{method_name}`\"),\n                \"use\",\n                format!(\"{receiver_snippet}.as_ref()\"),\n                applicability,\n            );\n            return true;\n        }\n    }\n    false\n}\n\n/// Checks whether `expr` is an argument in an `into_iter` call and, if so, determines whether its\n/// call of a `to_owned`-like function is unnecessary.\nfn check_into_iter_call_arg(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    method_name: Symbol,\n    receiver: &Expr<'_>,\n    msrv: Msrv,\n) -> bool {\n    if let Some(parent) = get_parent_expr(cx, expr)\n        && let Some(callee_def_id) = fn_def_id(cx, parent)\n        && is_into_iter(cx, callee_def_id)\n        && let Some(iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator)\n        && let parent_ty = cx.typeck_results().expr_ty(parent)\n        && implements_trait(cx, parent_ty, iterator_trait_id, &[])\n        && let Some(item_ty) = get_iterator_item_ty(cx, parent_ty)\n        && let Some(receiver_snippet) = receiver.span.get_source_text(cx)\n        // If the receiver is a `Cow`, we can't remove the `into_owned` generally, see https://github.com/rust-lang/rust-clippy/issues/13624.\n        && !cx.typeck_results().expr_ty(receiver).is_diag_item(cx, sym::Cow)\n        // Calling `iter()` on a temporary object can lead to false positives. #14242\n        && !is_expr_temporary_value(cx, receiver)\n    {\n        if unnecessary_iter_cloned::check_for_loop_iter(cx, parent, method_name, receiver, true) {\n            return true;\n        }\n\n        let cloned_or_copied = if is_copy(cx, item_ty) && msrv.meets(cx, msrvs::ITERATOR_COPIED) {\n            \"copied\"\n        } else {\n            \"cloned\"\n        };\n        // The next suggestion may be incorrect because the removal of the `to_owned`-like\n        // function could cause the iterator to hold a reference to a resource that is used\n        // mutably. See https://github.com/rust-lang/rust-clippy/issues/8148.\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_TO_OWNED,\n            parent.span,\n            format!(\"unnecessary use of `{method_name}`\"),\n            \"use\",\n            format!(\"{receiver_snippet}.iter().{cloned_or_copied}()\"),\n            Applicability::MaybeIncorrect,\n        );\n        return true;\n    }\n    false\n}\n\n/// Checks for `&String::from_utf8(bytes.{to_vec,to_owned,...}()).unwrap()` coercing to `&str`,\n/// which can be written as just `std::str::from_utf8(bytes).unwrap()`.\nfn check_string_from_utf8<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, receiver: &'tcx Expr<'tcx>) -> bool {\n    if let Some((call, arg)) = skip_addr_of_ancestors(cx, expr)\n        && !arg.span.from_expansion()\n        && let ExprKind::Call(callee, _) = call.kind\n        && fn_def_id(cx, call).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::string_from_utf8, did))\n        && let Some(unwrap_call) = get_parent_expr(cx, call)\n        && let ExprKind::MethodCall(unwrap_method_name, ..) = unwrap_call.kind\n        && matches!(unwrap_method_name.ident.name, sym::unwrap | sym::expect)\n        && let Some(ref_string) = get_parent_expr(cx, unwrap_call)\n        && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, _) = ref_string.kind\n        && let adjusted_ty = cx.typeck_results().expr_ty_adjusted(ref_string)\n        // `&...` creates a `&String`, so only actually lint if this coerces to a `&str`\n        && matches!(adjusted_ty.kind(), ty::Ref(_, ty, _) if ty.is_str())\n    {\n        span_lint_and_then(\n            cx,\n            UNNECESSARY_TO_OWNED,\n            ref_string.span,\n            \"allocating a new `String` only to create a temporary `&str` from it\",\n            |diag| {\n                let arg_suggestion = format!(\n                    \"{borrow}{recv_snippet}\",\n                    recv_snippet = snippet(cx, receiver.span.source_callsite(), \"..\"),\n                    borrow = if cx.typeck_results().expr_ty(receiver).is_ref() {\n                        \"\"\n                    } else {\n                        // If not already a reference, prefix with a borrow so that it can coerce to one\n                        \"&\"\n                    }\n                );\n\n                diag.multipart_suggestion(\n                    \"convert from `&[u8]` to `&str` directly\",\n                    vec![\n                        // `&String::from_utf8(bytes.to_vec()).unwrap()`\n                        //   ^^^^^^^^^^^^^^^^^\n                        (callee.span, \"core::str::from_utf8\".into()),\n                        // `&String::from_utf8(bytes.to_vec()).unwrap()`\n                        //  ^\n                        (\n                            ref_string.span.shrink_to_lo().to(unwrap_call.span.shrink_to_lo()),\n                            String::new(),\n                        ),\n                        // `&String::from_utf8(bytes.to_vec()).unwrap()`\n                        //                     ^^^^^^^^^^^^^^\n                        (arg.span, arg_suggestion),\n                    ],\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n        true\n    } else {\n        false\n    }\n}\n\n/// Checks whether `expr` is an argument in an `into_iter` call and, if so, determines whether its\n/// call of a `to_owned`-like function is unnecessary.\nfn check_split_call_arg(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol, receiver: &Expr<'_>) -> bool {\n    if let Some(parent) = get_parent_expr(cx, expr)\n        && let Some((sym::split, argument_expr)) = get_fn_name_and_arg(cx, parent)\n        && let Some(receiver_snippet) = receiver.span.get_source_text(cx)\n        && let Some(arg_snippet) = argument_expr.span.get_source_text(cx)\n    {\n        // We may end-up here because of an expression like `x.to_string().split(…)` where the type of `x`\n        // implements `AsRef<str>` but does not implement `Deref<Target = str>`. In this case, we have to\n        // add `.as_ref()` to the suggestion.\n        let as_ref = if cx.typeck_results().expr_ty(expr).is_lang_item(cx, LangItem::String)\n            && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)\n            && cx.get_associated_type(cx.typeck_results().expr_ty(receiver), deref_trait_id, sym::Target)\n                != Some(cx.tcx.types.str_)\n        {\n            \".as_ref()\"\n        } else {\n            \"\"\n        };\n\n        // The next suggestion may be incorrect because the removal of the `to_owned`-like\n        // function could cause the iterator to hold a reference to a resource that is used\n        // mutably. See https://github.com/rust-lang/rust-clippy/issues/8148.\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_TO_OWNED,\n            parent.span,\n            format!(\"unnecessary use of `{method_name}`\"),\n            \"use\",\n            format!(\"{receiver_snippet}{as_ref}.split({arg_snippet})\"),\n            Applicability::MaybeIncorrect,\n        );\n        return true;\n    }\n    false\n}\n\nfn get_fn_name_and_arg<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<(Symbol, Expr<'tcx>)> {\n    match &expr.kind {\n        ExprKind::MethodCall(path, _, [arg_expr], ..) => Some((path.ident.name, *arg_expr)),\n        ExprKind::Call(\n            Expr {\n                kind: ExprKind::Path(qpath),\n                hir_id: path_hir_id,\n                ..\n            },\n            [arg_expr],\n        ) => {\n            // Only return Fn-like DefIds, not the DefIds of statics/consts/etc that contain or\n            // deref to fn pointers, dyn Fn, impl Fn - #8850\n            if let Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, def_id) =\n                cx.typeck_results().qpath_res(qpath, *path_hir_id)\n                && let Some(fn_name) = cx.tcx.opt_item_name(def_id)\n            {\n                Some((fn_name, *arg_expr))\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\n/// Checks whether `expr` is an argument in a function call and, if so, determines whether its call\n/// of a `to_owned`-like function is unnecessary.\nfn check_other_call_arg<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    method_name: Symbol,\n    receiver: &'tcx Expr<'tcx>,\n) -> bool {\n    if let Some((maybe_call, maybe_arg)) = skip_addr_of_ancestors(cx, expr)\n        && let Some((callee_def_id, _, recv, call_args)) = get_callee_generic_args_and_args(cx, maybe_call)\n        && let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder()\n        && let Some(i) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == maybe_arg.hir_id)\n        && let Some(input) = fn_sig.inputs().get(i)\n        && let (input, n_refs, _) = peel_and_count_ty_refs(*input)\n        && let (trait_predicates, _) = get_input_traits_and_projections(cx, callee_def_id, input)\n        && let Some(sized_def_id) = cx.tcx.lang_items().sized_trait()\n        && let Some(meta_sized_def_id) = cx.tcx.lang_items().meta_sized_trait()\n        && let [trait_predicate] = trait_predicates\n            .iter()\n            .filter(|trait_predicate| trait_predicate.def_id() != sized_def_id)\n            .filter(|trait_predicate| trait_predicate.def_id() != meta_sized_def_id)\n            .collect::<Vec<_>>()[..]\n        && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)\n        && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)\n        && (trait_predicate.def_id() == deref_trait_id || trait_predicate.def_id() == as_ref_trait_id)\n        && let receiver_ty = cx.typeck_results().expr_ty(receiver)\n        // We can't add an `&` when the trait is `Deref` because `Target = &T` won't match\n        // `Target = T`.\n        && let Some((n_refs, receiver_ty)) = if n_refs > 0 || is_copy(cx, receiver_ty) {\n            Some((n_refs, receiver_ty))\n        } else if trait_predicate.def_id() != deref_trait_id {\n            Some((1, Ty::new_imm_ref(cx.tcx,\n                cx.tcx.lifetimes.re_erased,\n                receiver_ty,\n            )))\n        } else {\n            None\n        }\n        && can_change_type(cx, maybe_arg, receiver_ty)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let (receiver_snippet, _) = snippet_with_context(cx, receiver.span, expr.span.ctxt(), \"..\", &mut applicability);\n\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_TO_OWNED,\n            maybe_arg.span,\n            format!(\"unnecessary use of `{method_name}`\"),\n            \"use\",\n            format!(\"{:&>n_refs$}{receiver_snippet}\", \"\"),\n            applicability,\n        );\n        return true;\n    }\n    false\n}\n\n/// Walks an expression's ancestors until it finds a non-`AddrOf` expression. Returns the first such\n/// expression found (if any) along with the immediately prior expression.\nfn skip_addr_of_ancestors<'tcx>(\n    cx: &LateContext<'tcx>,\n    mut expr: &'tcx Expr<'tcx>,\n) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {\n    while let Some(parent) = get_parent_expr(cx, expr) {\n        if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, _) = parent.kind {\n            expr = parent;\n        } else {\n            return Some((parent, expr));\n        }\n    }\n    None\n}\n\n/// Checks whether an expression is a function or method call and, if so, returns its `DefId`,\n/// `GenericArgs`, and arguments.\nfn get_callee_generic_args_and_args<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n) -> Option<(\n    DefId,\n    GenericArgsRef<'tcx>,\n    Option<&'tcx Expr<'tcx>>,\n    &'tcx [Expr<'tcx>],\n)> {\n    if let ExprKind::Call(callee, args) = expr.kind\n        && let callee_ty = cx.typeck_results().expr_ty(callee)\n        && let ty::FnDef(callee_def_id, _) = callee_ty.kind()\n    {\n        let generic_args = cx.typeck_results().node_args(callee.hir_id);\n        return Some((*callee_def_id, generic_args, None, args));\n    }\n    if let ExprKind::MethodCall(_, recv, args, _) = expr.kind\n        && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n    {\n        let generic_args = cx.typeck_results().node_args(expr.hir_id);\n        return Some((method_def_id, generic_args, Some(recv), args));\n    }\n    None\n}\n\n/// Returns the `TraitPredicate`s and `ProjectionPredicate`s for a function's input type.\nfn get_input_traits_and_projections<'tcx>(\n    cx: &LateContext<'tcx>,\n    callee_def_id: DefId,\n    input: Ty<'tcx>,\n) -> (Vec<TraitPredicate<'tcx>>, Vec<ProjectionPredicate<'tcx>>) {\n    let mut trait_predicates = Vec::new();\n    let mut projection_predicates = Vec::new();\n    for predicate in cx.tcx.param_env(callee_def_id).caller_bounds() {\n        match predicate.kind().skip_binder() {\n            ClauseKind::Trait(trait_predicate) if trait_predicate.trait_ref.self_ty() == input => {\n                trait_predicates.push(trait_predicate);\n            },\n            ClauseKind::Projection(projection_predicate) if projection_predicate.projection_term.self_ty() == input => {\n                projection_predicates.push(projection_predicate);\n            },\n            _ => {},\n        }\n    }\n    (trait_predicates, projection_predicates)\n}\n\n#[expect(clippy::too_many_lines)]\nfn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<'a>) -> bool {\n    for (_, node) in cx.tcx.hir_parent_iter(expr.hir_id) {\n        match node {\n            Node::Stmt(_) => return true,\n            Node::Block(..) => {},\n            Node::Item(item) => {\n                if let ItemKind::Fn { body: body_id, .. } = &item.kind\n                    && let output_ty = return_ty(cx, item.owner_id)\n                    && rustc_hir_typeck::can_coerce(cx.tcx, cx.param_env, item.owner_id.def_id, ty, output_ty)\n                {\n                    if has_lifetime(output_ty) && has_lifetime(ty) {\n                        return false;\n                    }\n                    let body = cx.tcx.hir_body(*body_id);\n                    let body_expr = &body.value;\n                    let mut count = 0;\n                    return find_all_ret_expressions(cx, body_expr, |_| {\n                        count += 1;\n                        count <= 1\n                    });\n                }\n            },\n            Node::Expr(parent_expr) => {\n                if let Some((callee_def_id, call_generic_args, recv, call_args)) =\n                    get_callee_generic_args_and_args(cx, parent_expr)\n                {\n                    let bound_fn_sig = cx.tcx.fn_sig(callee_def_id);\n                    let fn_sig = bound_fn_sig.skip_binder();\n                    if let Some(arg_index) = recv\n                        .into_iter()\n                        .chain(call_args)\n                        .position(|arg| arg.hir_id == expr.hir_id)\n                        && let param_ty = fn_sig.input(arg_index).skip_binder()\n                        && let ty::Param(ParamTy { index: param_index , ..}) = *param_ty.kind()\n                        // https://github.com/rust-lang/rust-clippy/issues/9504 and https://github.com/rust-lang/rust-clippy/issues/10021\n                        && (param_index as usize) < call_generic_args.len()\n                    {\n                        if fn_sig\n                            .skip_binder()\n                            .inputs()\n                            .iter()\n                            .enumerate()\n                            .filter(|(i, _)| *i != arg_index)\n                            .any(|(_, ty)| ty.contains(param_ty))\n                        {\n                            return false;\n                        }\n\n                        let mut trait_predicates =\n                            cx.tcx\n                                .param_env(callee_def_id)\n                                .caller_bounds()\n                                .iter()\n                                .filter(|predicate| {\n                                    if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()\n                                        && trait_predicate.trait_ref.self_ty() == param_ty\n                                    {\n                                        true\n                                    } else {\n                                        false\n                                    }\n                                });\n\n                        let new_subst = cx\n                            .tcx\n                            .mk_args_from_iter(call_generic_args.iter().enumerate().map(|(i, t)| {\n                                if i == param_index as usize {\n                                    GenericArg::from(ty)\n                                } else {\n                                    t\n                                }\n                            }));\n\n                        if trait_predicates.any(|predicate| {\n                            let predicate = bound_fn_sig.rebind(predicate).instantiate(cx.tcx, new_subst);\n                            let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);\n                            !cx.tcx\n                                .infer_ctxt()\n                                .build(cx.typing_mode())\n                                .predicate_must_hold_modulo_regions(&obligation)\n                        }) {\n                            return false;\n                        }\n\n                        let output_ty = cx.tcx.instantiate_bound_regions_with_erased(fn_sig.output());\n                        if output_ty.contains(param_ty) {\n                            if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions(\n                                new_subst,\n                                cx.typing_env(),\n                                bound_fn_sig.rebind(output_ty),\n                            ) {\n                                expr = parent_expr;\n                                ty = new_ty;\n                                continue;\n                            }\n                            return false;\n                        }\n\n                        return true;\n                    }\n                } else if let ExprKind::Block(..) = parent_expr.kind {\n                    continue;\n                }\n                return false;\n            },\n            _ => return false,\n        }\n    }\n\n    false\n}\n\nfn has_lifetime(ty: Ty<'_>) -> bool {\n    ty.walk().any(|t| matches!(t.kind(), GenericArgKind::Lifetime(_)))\n}\n\n/// Returns true if the named method is `Iterator::cloned` or `Iterator::copied`.\nfn is_cloned_or_copied(cx: &LateContext<'_>, method_name: Symbol, method_parent_id: DefId) -> bool {\n    matches!(method_name, sym::cloned | sym::copied) && method_parent_id.is_diag_item(cx, sym::Iterator)\n}\n\n/// Returns true if the named method can be used to convert the receiver to its \"owned\"\n/// representation.\nfn is_to_owned_like<'a>(\n    cx: &LateContext<'a>,\n    call_expr: &Expr<'a>,\n    method_name: Symbol,\n    method_parent_id: DefId,\n) -> bool {\n    is_cow_into_owned(cx, method_name, method_parent_id)\n        || (method_name != sym::to_string && is_clone_like(cx, method_name, method_parent_id))\n        || is_to_string_on_string_like(cx, call_expr, method_name, method_parent_id)\n}\n\n/// Returns true if the named method is `Cow::into_owned`.\nfn is_cow_into_owned(cx: &LateContext<'_>, method_name: Symbol, method_parent_id: DefId) -> bool {\n    method_name == sym::into_owned && method_parent_id.opt_impl_ty(cx).is_diag_item(cx, sym::Cow)\n}\n\n/// Returns true if the named method is `ToString::to_string` and it's called on a type that\n/// is string-like i.e. implements `AsRef<str>` or `Deref<Target = str>`.\nfn is_to_string_on_string_like<'a>(\n    cx: &LateContext<'_>,\n    call_expr: &'a Expr<'a>,\n    method_name: Symbol,\n    method_parent_id: DefId,\n) -> bool {\n    if method_name != sym::to_string || !method_parent_id.is_diag_item(cx, sym::ToString) {\n        return false;\n    }\n\n    if let Some(args) = cx.typeck_results().node_args_opt(call_expr.hir_id)\n        && let [generic_arg] = args.as_slice()\n        && let GenericArgKind::Type(ty) = generic_arg.kind()\n        && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref)\n        && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef)\n        && (cx.get_associated_type(ty, deref_trait_id, sym::Target) == Some(cx.tcx.types.str_)\n            || implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()]))\n    {\n        true\n    } else {\n        false\n    }\n}\n\nfn std_map_key<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {\n    match ty.kind() {\n        ty::Adt(adt, args)\n            if matches!(\n                cx.tcx.get_diagnostic_name(adt.did()),\n                Some(sym::BTreeMap | sym::BTreeSet | sym::HashMap | sym::HashSet)\n            ) =>\n        {\n            Some(args.type_at(0))\n        },\n        _ => None,\n    }\n}\n\nfn is_str_and_string(cx: &LateContext<'_>, arg_ty: Ty<'_>, original_arg_ty: Ty<'_>) -> bool {\n    original_arg_ty.is_str() && arg_ty.is_lang_item(cx, LangItem::String)\n}\n\nfn is_slice_and_vec(cx: &LateContext<'_>, arg_ty: Ty<'_>, original_arg_ty: Ty<'_>) -> bool {\n    (original_arg_ty.is_slice() || original_arg_ty.is_array() || original_arg_ty.is_array_slice())\n        && arg_ty.is_diag_item(cx, sym::Vec)\n}\n\n// This function will check the following:\n// 1. The argument is a non-mutable reference.\n// 2. It calls `to_owned()`, `to_string()` or `to_vec()`.\n// 3. That the method is called on `String` or on `Vec` (only types supported for the moment).\nfn check_if_applicable_to_argument<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'tcx>) {\n    if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, expr) = arg.kind\n        && let ExprKind::MethodCall(method_path, caller, &[], _) = expr.kind\n        && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && let method_name = method_path.ident.name\n        && match method_name {\n            sym::to_owned => cx.tcx.is_diagnostic_item(sym::to_owned_method, method_def_id),\n            sym::to_string => cx.tcx.is_diagnostic_item(sym::to_string_method, method_def_id),\n            sym::to_vec => cx\n                .tcx\n                .impl_of_assoc(method_def_id)\n                .is_some_and(|impl_did| cx.tcx.type_of(impl_did).instantiate_identity().is_slice()),\n            _ => false,\n        }\n        && let original_arg_ty = cx.typeck_results().node_type(caller.hir_id).peel_refs()\n        && let arg_ty = cx.typeck_results().expr_ty(arg)\n        && let ty::Ref(_, arg_ty, Mutability::Not) = arg_ty.kind()\n        // FIXME: try to fix `can_change_type` to make it work in this case.\n        // && can_change_type(cx, caller, *arg_ty)\n        && let arg_ty = arg_ty.peel_refs()\n        // For now we limit this lint to `String` and `Vec`.\n        && (is_str_and_string(cx, arg_ty, original_arg_ty) || is_slice_and_vec(cx, arg_ty, original_arg_ty))\n        && let Some(snippet) = caller.span.get_source_text(cx)\n    {\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_TO_OWNED,\n            arg.span,\n            format!(\"unnecessary use of `{method_name}`\"),\n            \"replace it with\",\n            if original_arg_ty.is_array() {\n                format!(\"{snippet}.as_slice()\")\n            } else {\n                snippet.to_owned()\n            },\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n\n// In std \"map types\", the getters all expect a `Borrow<Key>` generic argument. So in here, we\n// check that:\n// 1. This is a method with only one argument that doesn't come from a trait.\n// 2. That it has `Borrow` in its generic predicates.\n// 3. `Self` is a std \"map type\" (ie `HashSet`, `HashMap`, `BTreeSet`, `BTreeMap`).\n// 4. The key to the \"map type\" is not a reference.\nfn check_borrow_predicate<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n    if let ExprKind::MethodCall(_, caller, &[arg], _) = expr.kind\n        && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && cx.tcx.trait_of_assoc(method_def_id).is_none()\n        && let Some(borrow_id) = cx.tcx.get_diagnostic_item(sym::Borrow)\n        && cx.tcx.predicates_of(method_def_id).predicates.iter().any(|(pred, _)| {\n            if let ClauseKind::Trait(trait_pred) = pred.kind().skip_binder()\n                && trait_pred.polarity == ty::PredicatePolarity::Positive\n                && trait_pred.trait_ref.def_id == borrow_id\n            {\n                true\n            } else {\n                false\n            }\n        })\n        && let caller_ty = cx.typeck_results().expr_ty(caller)\n        // For now we limit it to \"map types\".\n        && let Some(key_ty) = std_map_key(cx, caller_ty)\n        // We need to check that the key type is not a reference.\n        && !key_ty.is_ref()\n    {\n        check_if_applicable_to_argument(cx, &arg);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/unwrap_expect_used.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::is_never_like;\nuse clippy_utils::{is_in_test, is_inside_always_const_context, is_lint_allowed};\nuse rustc_hir::Expr;\nuse rustc_hir::def::DefKind;\nuse rustc_lint::{LateContext, Lint};\nuse rustc_middle::ty;\nuse rustc_span::sym;\n\nuse super::{EXPECT_USED, UNWRAP_USED};\n\n#[derive(Clone, Copy, Eq, PartialEq)]\npub(super) enum Variant {\n    Unwrap,\n    Expect,\n}\n\nimpl Variant {\n    fn method_name(self, is_err: bool) -> &'static str {\n        match (self, is_err) {\n            (Variant::Unwrap, true) => \"unwrap_err\",\n            (Variant::Unwrap, false) => \"unwrap\",\n            (Variant::Expect, true) => \"expect_err\",\n            (Variant::Expect, false) => \"expect\",\n        }\n    }\n\n    fn lint(self) -> &'static Lint {\n        match self {\n            Variant::Unwrap => UNWRAP_USED,\n            Variant::Expect => EXPECT_USED,\n        }\n    }\n}\n\n/// Lint usage of `unwrap` or `unwrap_err` for `Result` and `unwrap()` for `Option` (and their\n/// `expect` counterparts).\n#[allow(clippy::too_many_arguments)]\npub(super) fn check(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    recv: &Expr<'_>,\n    is_err: bool,\n    allow_unwrap_in_consts: bool,\n    allow_unwrap_in_tests: bool,\n    unwrap_allowed_ids: &rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::DefId>,\n    unwrap_allowed_aliases: &[rustc_hir::def_id::DefId],\n    variant: Variant,\n) {\n    let ty = cx.typeck_results().expr_ty(recv).peel_refs();\n\n    let (kind, none_value, none_prefix) = match ty.opt_diag_name(cx) {\n        Some(sym::Option) if !is_err => (\"an `Option`\", \"None\", \"\"),\n        Some(sym::Result)\n            if let ty::Adt(_, substs) = ty.kind()\n                && let Some(t_or_e_ty) = substs[usize::from(!is_err)].as_type() =>\n        {\n            if is_never_like(t_or_e_ty) {\n                return;\n            }\n\n            (\"a `Result`\", if is_err { \"Ok\" } else { \"Err\" }, \"an \")\n        },\n        _ => return,\n    };\n\n    let method_suffix = if is_err { \"_err\" } else { \"\" };\n\n    if let ty::Adt(adt, _) = ty.kind()\n        && unwrap_allowed_ids.contains(&adt.did())\n    {\n        return;\n    }\n\n    for &def_id in unwrap_allowed_aliases {\n        let alias_ty = cx.tcx.type_of(def_id).instantiate_identity();\n        if let (ty::Adt(adt, substs), ty::Adt(alias_adt, alias_substs)) = (ty.kind(), alias_ty.kind())\n            && adt.did() == alias_adt.did()\n        {\n            let mut all_match = true;\n            for (arg, alias_arg) in substs.iter().zip(alias_substs.iter()) {\n                if let (Some(arg_ty), Some(alias_arg_ty)) = (arg.as_type(), alias_arg.as_type()) {\n                    if matches!(alias_arg_ty.kind(), ty::Param(_)) {\n                        continue;\n                    }\n                    if let (ty::Adt(arg_adt, _), ty::Adt(alias_arg_adt, _)) =\n                        (arg_ty.peel_refs().kind(), alias_arg_ty.peel_refs().kind())\n                    {\n                        if arg_adt.did() != alias_arg_adt.did() {\n                            all_match = false;\n                            break;\n                        }\n                    } else if arg_ty != alias_arg_ty {\n                        all_match = false;\n                        break;\n                    }\n                }\n            }\n            if all_match {\n                return;\n            }\n        }\n    }\n\n    if allow_unwrap_in_tests && is_in_test(cx.tcx, expr.hir_id) {\n        return;\n    }\n\n    if allow_unwrap_in_consts && is_inside_always_const_context(cx.tcx, expr.hir_id) {\n        return;\n    }\n\n    span_lint_and_then(\n        cx,\n        variant.lint(),\n        expr.span,\n        format!(\"used `{}()` on {kind} value\", variant.method_name(is_err)),\n        |diag| {\n            diag.note(format!(\"if this value is {none_prefix}`{none_value}`, it will panic\"));\n\n            if variant == Variant::Unwrap && is_lint_allowed(cx, EXPECT_USED, expr.hir_id) {\n                diag.help(format!(\n                    \"consider using `expect{method_suffix}()` to provide a better panic message\"\n                ));\n            }\n        },\n    );\n}\n\n#[expect(clippy::too_many_arguments, clippy::fn_params_excessive_bools)]\npub(super) fn check_call(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    func: &Expr<'_>,\n    args: &[Expr<'_>],\n    allow_unwrap_in_consts: bool,\n    allow_unwrap_in_tests: bool,\n    allow_expect_in_consts: bool,\n    allow_expect_in_tests: bool,\n    unwrap_allowed_ids: &rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::DefId>,\n    unwrap_allowed_aliases: &[rustc_hir::def_id::DefId],\n) {\n    let Some(recv) = args.first() else {\n        return;\n    };\n    let Some((DefKind::AssocFn, def_id)) = cx.typeck_results().type_dependent_def(func.hir_id) else {\n        return;\n    };\n\n    match cx.tcx.item_name(def_id) {\n        sym::unwrap => {\n            check(\n                cx,\n                expr,\n                recv,\n                false,\n                allow_unwrap_in_consts,\n                allow_unwrap_in_tests,\n                unwrap_allowed_ids,\n                unwrap_allowed_aliases,\n                Variant::Unwrap,\n            );\n        },\n        sym::expect => {\n            check(\n                cx,\n                expr,\n                recv,\n                false,\n                allow_expect_in_consts,\n                allow_expect_in_tests,\n                unwrap_allowed_ids,\n                unwrap_allowed_aliases,\n                Variant::Expect,\n            );\n        },\n        clippy_utils::sym::unwrap_err => {\n            check(\n                cx,\n                expr,\n                recv,\n                true,\n                allow_unwrap_in_consts,\n                allow_unwrap_in_tests,\n                unwrap_allowed_ids,\n                unwrap_allowed_aliases,\n                Variant::Unwrap,\n            );\n        },\n        clippy_utils::sym::expect_err => {\n            check(\n                cx,\n                expr,\n                recv,\n                true,\n                allow_expect_in_consts,\n                allow_expect_in_tests,\n                unwrap_allowed_ids,\n                unwrap_allowed_aliases,\n                Variant::Expect,\n            );\n        },\n        _ => (),\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/useless_asref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::ty::{implements_trait, peel_and_count_ty_refs, should_call_clone_as_function};\nuse clippy_utils::{get_parent_expr, peel_blocks, strip_pat_refs};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{self as hir, LangItem, Node};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};\nuse rustc_middle::ty::{Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};\nuse rustc_span::{Span, Symbol, sym};\n\nuse core::ops::ControlFlow;\n\nuse super::USELESS_ASREF;\n\n/// Returns the first type inside the `Option`/`Result` type passed as argument.\nfn get_enum_ty(enum_ty: Ty<'_>) -> Option<Ty<'_>> {\n    struct ContainsTyVisitor {\n        level: usize,\n    }\n\n    impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTyVisitor {\n        type Result = ControlFlow<Ty<'tcx>>;\n\n        fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {\n            self.level += 1;\n            if self.level == 1 {\n                t.super_visit_with(self)\n            } else {\n                ControlFlow::Break(t)\n            }\n        }\n    }\n\n    match enum_ty.visit_with(&mut ContainsTyVisitor { level: 0 }) {\n        ControlFlow::Break(ty) => Some(ty),\n        ControlFlow::Continue(()) => None,\n    }\n}\n\n/// Checks for the `USELESS_ASREF` lint.\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: Symbol, recvr: &hir::Expr<'_>) {\n    // when we get here, we've already checked that the call name is \"as_ref\" or \"as_mut\"\n    // check if the call is to the actual `AsRef` or `AsMut` trait\n    let Some(def) = cx.typeck_results().type_dependent_def_id(expr.hir_id) else {\n        return;\n    };\n\n    if def.opt_parent(cx).is_diag_item(cx, sym::AsRef) || def.opt_parent(cx).is_diag_item(cx, sym::AsMut) {\n        // check if the type after `as_ref` or `as_mut` is the same as before\n        let rcv_ty = cx.typeck_results().expr_ty(recvr);\n        let res_ty = cx.typeck_results().expr_ty(expr);\n        let (base_res_ty, res_depth, _) = peel_and_count_ty_refs(res_ty);\n        let (base_rcv_ty, rcv_depth, _) = peel_and_count_ty_refs(rcv_ty);\n        if base_rcv_ty == base_res_ty && rcv_depth >= res_depth {\n            if let Some(parent) = get_parent_expr(cx, expr) {\n                // allow the `as_ref` or `as_mut` if it is followed by another method call\n                if let hir::ExprKind::MethodCall(segment, ..) = parent.kind\n                    && segment.ident.span != expr.span\n                {\n                    return;\n                }\n\n                // allow the `as_ref` or `as_mut` if they belong to a closure that changes\n                // the number of references\n                if matches!(parent.kind, hir::ExprKind::Closure(..)) && rcv_depth != res_depth {\n                    return;\n                }\n            }\n\n            // Add `*` derefs if the expr is used in a ctor, because automatic derefs don't apply in that case.\n            let deref = if rcv_depth > res_depth {\n                let parent = cx.tcx.parent_hir_node(expr.hir_id);\n                match parent {\n                    Node::ExprField(_) => \"*\".repeat(rcv_depth - res_depth),\n                    Node::Expr(parent)\n                        if let hir::ExprKind::Call(func, _) = parent.kind\n                            && let (_, Some(path)) = func.opt_res_path()\n                            && matches!(path.res, Res::Def(DefKind::Ctor(_, _), _) | Res::SelfCtor(_)) =>\n                    {\n                        \"*\".repeat(rcv_depth - res_depth)\n                    },\n                    _ => String::new(),\n                }\n            } else {\n                String::new()\n            };\n\n            let mut applicability = Applicability::MachineApplicable;\n            let suggestion = format!(\n                \"{deref}{}\",\n                snippet_with_applicability(cx, recvr.span, \"..\", &mut applicability)\n            );\n\n            span_lint_and_sugg(\n                cx,\n                USELESS_ASREF,\n                expr.span,\n                format!(\"this call to `{call_name}` does nothing\"),\n                \"try\",\n                suggestion,\n                applicability,\n            );\n        }\n    } else if matches!(\n        def.opt_parent(cx).opt_impl_ty(cx).opt_diag_name(cx),\n        Some(sym::Option | sym::Result)\n    ) {\n        let rcv_ty = cx.typeck_results().expr_ty(recvr).peel_refs();\n        let res_ty = cx.typeck_results().expr_ty(expr).peel_refs();\n\n        if let Some(rcv_ty) = get_enum_ty(rcv_ty)\n            && let Some(res_ty) = get_enum_ty(res_ty)\n            // If the only thing the `as_mut`/`as_ref` call is doing is adding references and not\n            // changing the type, then we can move forward.\n            && rcv_ty.peel_refs() == res_ty.peel_refs()\n            && let Some(parent) = get_parent_expr(cx, expr)\n            // Check that it only has one argument.\n            && let hir::ExprKind::MethodCall(segment, _, [arg], _) = parent.kind\n            && segment.ident.span != expr.span\n            // We check that the called method name is `map`.\n            && segment.ident.name == sym::map\n            && is_calling_clone(cx, arg)\n            // And that we are not recommending recv.clone() over Arc::clone() or similar\n            && !should_call_clone_as_function(cx, rcv_ty)\n            // https://github.com/rust-lang/rust-clippy/issues/12357\n            && let Some(clone_trait) = cx.tcx.lang_items().clone_trait()\n            && implements_trait(cx, cx.typeck_results().expr_ty(recvr), clone_trait, &[])\n        {\n            lint_as_ref_clone(cx, expr.span.with_hi(parent.span.hi()), recvr, call_name);\n        }\n    }\n}\n\nfn check_qpath(cx: &LateContext<'_>, qpath: hir::QPath<'_>, hir_id: hir::HirId) -> bool {\n    // We check it's calling the `clone` method of the `Clone` trait.\n    if let Some(path_def_id) = cx.qpath_res(&qpath, hir_id).opt_def_id() {\n        cx.tcx.lang_items().get(LangItem::CloneFn) == Some(path_def_id)\n    } else {\n        false\n    }\n}\n\nfn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {\n    match arg.kind {\n        hir::ExprKind::Closure(&hir::Closure { body, .. })\n            // If it's a closure, we need to check what is called.\n            if let closure_body = cx.tcx.hir_body(body)\n                && let [param] = closure_body.params\n                && let hir::PatKind::Binding(_, local_id, ..) = strip_pat_refs(param.pat).kind =>\n        {\n            let closure_expr = peel_blocks(closure_body.value);\n            match closure_expr.kind {\n                hir::ExprKind::MethodCall(method, obj, [], _) => {\n                    if method.ident.name == sym::clone\n                        && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id)\n                        && let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id)\n                        // We check it's the `Clone` trait.\n                        && cx.tcx.lang_items().clone_trait().is_some_and(|id| id == trait_id)\n                        // no autoderefs\n                        && !cx.typeck_results().expr_adjustments(obj).iter()\n                            .any(|a| matches!(a.kind, Adjust::Deref(DerefAdjustKind::Overloaded(..))))\n                        && obj.res_local_id() == Some(local_id)\n                    {\n                        true\n                    } else {\n                        false\n                    }\n                },\n                hir::ExprKind::Call(call, [recv]) => {\n                    if let hir::ExprKind::Path(qpath) = call.kind\n                        && recv.res_local_id() == Some(local_id)\n                    {\n                        check_qpath(cx, qpath, call.hir_id)\n                    } else {\n                        false\n                    }\n                },\n                _ => false,\n            }\n        },\n        hir::ExprKind::Path(qpath) => check_qpath(cx, qpath, arg.hir_id),\n        _ => false,\n    }\n}\n\nfn lint_as_ref_clone(cx: &LateContext<'_>, span: Span, recvr: &hir::Expr<'_>, call_name: Symbol) {\n    let mut applicability = Applicability::MachineApplicable;\n    span_lint_and_sugg(\n        cx,\n        USELESS_ASREF,\n        span,\n        format!(\"this call to `{call_name}.map(...)` does nothing\"),\n        \"try\",\n        format!(\n            \"{}.clone()\",\n            snippet_with_applicability(cx, recvr.span, \"..\", &mut applicability)\n        ),\n        applicability,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/useless_nonzero_new_unchecked.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::is_inside_always_const_context;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, Node, QPath, UnsafeSource};\nuse rustc_lint::LateContext;\nuse rustc_span::sym;\n\nuse super::USELESS_NONZERO_NEW_UNCHECKED;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, func: &Expr<'tcx>, args: &[Expr<'_>], msrv: Msrv) {\n    if let ExprKind::Path(QPath::TypeRelative(ty, segment)) = func.kind\n        && segment.ident.name == sym::new_unchecked\n        && let [init_arg] = args\n        && is_inside_always_const_context(cx.tcx, expr.hir_id)\n        && cx.typeck_results().node_type(ty.hir_id).is_diag_item(cx, sym::NonZero)\n        && msrv.meets(cx, msrvs::CONST_UNWRAP)\n    {\n        let mut app = Applicability::MachineApplicable;\n        let ty_str = snippet_with_applicability(cx, ty.span, \"_\", &mut app);\n        let msg = format!(\"`{ty_str}::new()` and `Option::unwrap()` can be safely used in a `const` context\");\n        let sugg = format!(\n            \"{ty_str}::new({}).unwrap()\",\n            snippet_with_applicability(cx, init_arg.span, \"_\", &mut app)\n        );\n\n        if let Node::Block(Block {\n            stmts: [],\n            span: block_span,\n            rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),\n            ..\n        }) = cx.tcx.parent_hir_node(expr.hir_id)\n        {\n            if !block_span.from_expansion() {\n                // The expression is the only component of an `unsafe` block. Propose\n                // to replace the block altogether.\n                span_lint_and_sugg(\n                    cx,\n                    USELESS_NONZERO_NEW_UNCHECKED,\n                    *block_span,\n                    msg,\n                    \"use instead\",\n                    sugg,\n                    app,\n                );\n            }\n        } else {\n            // The expression is enclosed in a larger `unsafe` context. Indicate that\n            // this may no longer be needed for the fixed expression.\n            span_lint_and_then(cx, USELESS_NONZERO_NEW_UNCHECKED, expr.span, msg, |diagnostic| {\n                diagnostic\n                    .span_suggestion(expr.span, \"use instead\", sugg, app)\n                    .note(\"the fixed expression does not require an `unsafe` context\");\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/utils.rs",
    "content": "use clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::{get_parent_expr, usage};\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, QPath, Stmt, StmtKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::Span;\nuse rustc_span::symbol::sym;\n\n/// Checks if `expr`, of type `ty`, corresponds to a slice or can be dereferenced to a slice, or if\n/// `expr` is a method call to `.iter()` on such a type. In these cases, return the slice-like\n/// expression.\npub(super) fn derefs_to_slice<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    ty: Ty<'tcx>,\n) -> Option<&'tcx Expr<'tcx>> {\n    fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {\n        match ty.kind() {\n            ty::Slice(_) => true,\n            ty::Adt(..) if let Some(boxed) = ty.boxed_ty() => may_slice(cx, boxed),\n            ty::Adt(..) => ty.is_diag_item(cx, sym::Vec),\n            ty::Array(_, size) => size.try_to_target_usize(cx.tcx).is_some(),\n            ty::Ref(_, inner, _) => may_slice(cx, *inner),\n            _ => false,\n        }\n    }\n\n    if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind {\n        if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(self_arg)) {\n            Some(self_arg)\n        } else {\n            None\n        }\n    } else {\n        match ty.kind() {\n            ty::Slice(_) => Some(expr),\n            _ if ty.boxed_ty().is_some_and(|boxed| may_slice(cx, boxed)) => Some(expr),\n            ty::Ref(_, inner, _) => {\n                if may_slice(cx, *inner) {\n                    Some(expr)\n                } else {\n                    None\n                }\n            },\n            _ => None,\n        }\n    }\n}\n\n/// The core logic of `check_for_loop_iter` in `unnecessary_iter_cloned.rs`, this function wraps a\n/// use of `CloneOrCopyVisitor`.\npub(super) fn clone_or_copy_needed<'tcx>(\n    cx: &LateContext<'tcx>,\n    pat: &Pat<'tcx>,\n    body: &'tcx Expr<'tcx>,\n) -> (bool, Vec<(Span, String)>) {\n    let mut visitor = CloneOrCopyVisitor {\n        cx,\n        binding_hir_ids: pat_bindings(pat),\n        clone_or_copy_needed: false,\n        references_to_binding: Vec::new(),\n    };\n    visitor.visit_expr(body);\n    (visitor.clone_or_copy_needed, visitor.references_to_binding)\n}\n\n/// Returns a vector of all `HirId`s bound by the pattern.\nfn pat_bindings(pat: &Pat<'_>) -> Vec<HirId> {\n    let mut collector = usage::ParamBindingIdCollector {\n        binding_hir_ids: Vec::new(),\n    };\n    collector.visit_pat(pat);\n    collector.binding_hir_ids\n}\n\n/// `clone_or_copy_needed` will be false when `CloneOrCopyVisitor` is done visiting if the only\n/// operations performed on `binding_hir_ids` are:\n/// * to take non-mutable references to them\n/// * to use them as non-mutable `&self` in method calls\n///\n/// If any of `binding_hir_ids` is used in any other way, then `clone_or_copy_needed` will be true\n/// when `CloneOrCopyVisitor` is done visiting.\nstruct CloneOrCopyVisitor<'cx, 'tcx> {\n    cx: &'cx LateContext<'tcx>,\n    binding_hir_ids: Vec<HirId>,\n    clone_or_copy_needed: bool,\n    references_to_binding: Vec<(Span, String)>,\n}\n\nimpl<'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {\n        walk_expr(self, expr);\n        if self.is_binding(expr) {\n            if let Some(parent) = get_parent_expr(self.cx, expr) {\n                match parent.kind {\n                    ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, referent) => {\n                        if !parent.span.from_expansion() {\n                            self.references_to_binding\n                                .push((parent.span.until(referent.span), String::new()));\n                        }\n                        return;\n                    },\n                    ExprKind::MethodCall(.., args, _) => {\n                        if args.iter().all(|arg| !self.is_binding(arg))\n                            && let Some(method_def_id) = self.cx.typeck_results().type_dependent_def_id(parent.hir_id)\n                            && let method_ty = self.cx.tcx.type_of(method_def_id).instantiate_identity()\n                            && let self_ty = method_ty.fn_sig(self.cx.tcx).input(0).skip_binder()\n                            && matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Not))\n                        {\n                            return;\n                        }\n                    },\n                    _ => {},\n                }\n            }\n            self.clone_or_copy_needed = true;\n        }\n    }\n}\n\nimpl<'tcx> CloneOrCopyVisitor<'_, 'tcx> {\n    fn is_binding(&self, expr: &Expr<'tcx>) -> bool {\n        self.binding_hir_ids\n            .iter()\n            .any(|&hir_id| expr.res_local_id() == Some(hir_id))\n    }\n}\n\npub(super) fn get_last_chain_binding_hir_id(mut hir_id: HirId, statements: &[Stmt<'_>]) -> Option<HirId> {\n    for stmt in statements {\n        if let StmtKind::Let(local) = stmt.kind\n            && let Some(init) = local.init\n            && let ExprKind::Path(QPath::Resolved(_, path)) = init.kind\n            && let rustc_hir::def::Res::Local(local_hir_id) = path.res\n            && local_hir_id == hir_id\n        {\n            hir_id = local.pat.hir_id;\n        } else {\n            return None;\n        }\n    }\n    Some(hir_id)\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/vec_resize_to_zero.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse rustc_ast::LitKind;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::{Span, sym};\n\nuse super::VEC_RESIZE_TO_ZERO;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    count_arg: &'tcx Expr<'_>,\n    default_arg: &'tcx Expr<'_>,\n    name_span: Span,\n) {\n    if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && let Some(impl_id) = cx.tcx.impl_of_assoc(method_id)\n        && cx\n            .tcx\n            .type_of(impl_id)\n            .instantiate_identity()\n            .is_diag_item(cx, sym::Vec)\n        && let ExprKind::Lit(Spanned {\n            node: LitKind::Int(Pu128(0), _),\n            ..\n        }) = count_arg.kind\n        && let ExprKind::Lit(Spanned {\n            node: LitKind::Int(..), ..\n        }) = default_arg.kind\n    {\n        let method_call_span = expr.span.with_lo(name_span.lo());\n        span_lint_and_then(\n            cx,\n            VEC_RESIZE_TO_ZERO,\n            expr.span,\n            \"emptying a vector with `resize`\",\n            |db| {\n                db.help(\"the arguments may be inverted...\");\n                db.span_suggestion(\n                    method_call_span,\n                    \"...or you can empty the vector with\",\n                    \"clear()\".to_string(),\n                    Applicability::MaybeIncorrect,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/verbose_file_reads.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::sym;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::LateContext;\n\nuse super::VERBOSE_FILE_READS;\n\npub(super) const READ_TO_END_MSG: (&str, &str) = (\"use of `File::read_to_end`\", \"consider using `fs::read` instead\");\npub(super) const READ_TO_STRING_MSG: (&str, &str) = (\n    \"use of `File::read_to_string`\",\n    \"consider using `fs::read_to_string` instead\",\n);\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    recv: &'tcx Expr<'_>,\n    (msg, help): (&'static str, &'static str),\n) {\n    if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::IoRead)\n        && matches!(recv.kind, ExprKind::Path(QPath::Resolved(None, _)))\n        && cx\n            .typeck_results()\n            .expr_ty_adjusted(recv)\n            .peel_refs()\n            .is_diag_item(cx, sym::File)\n    {\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(cx, VERBOSE_FILE_READS, expr.span, msg, |diag| {\n            diag.help(help);\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/waker_clone_wake.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\n\nuse super::WAKER_CLONE_WAKE;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {\n    let ty = cx.typeck_results().expr_ty(recv);\n\n    if let Some(did) = ty.ty_adt_def()\n        && cx.tcx.is_diagnostic_item(sym::Waker, did.did())\n        && let ExprKind::MethodCall(_, waker_ref, &[], _) = recv.kind\n        && cx.ty_based_def(recv).opt_parent(cx).is_diag_item(cx, sym::Clone)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let snippet = snippet_with_applicability(cx, waker_ref.span.source_callsite(), \"..\", &mut applicability);\n\n        span_lint_and_sugg(\n            cx,\n            WAKER_CLONE_WAKE,\n            expr.span,\n            \"cloning a `Waker` only to wake it\",\n            \"replace with\",\n            format!(\"{snippet}.wake_by_ref()\"),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/wrong_self_convention.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::ty::is_copy;\nuse itertools::Itertools;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::{Span, Symbol};\nuse std::fmt;\n\nuse super::WRONG_SELF_CONVENTION;\nuse super::lib::SelfKind;\n\n#[rustfmt::skip]\nconst CONVENTIONS: [(&[Convention], &[SelfKind]); 9] = [\n    (&[Convention::Eq(\"new\")], &[SelfKind::No]),\n    (&[Convention::StartsWith(\"as_\")], &[SelfKind::Ref, SelfKind::RefMut]),\n    (&[Convention::StartsWith(\"from_\")], &[SelfKind::No]),\n    (&[Convention::StartsWith(\"into_\")], &[SelfKind::Value]),\n    (&[Convention::StartsWith(\"is_\")], &[SelfKind::RefMut, SelfKind::Ref, SelfKind::No]),\n    (&[Convention::Eq(\"to_mut\")], &[SelfKind::RefMut]),\n    (&[Convention::StartsWith(\"to_\"), Convention::EndsWith(\"_mut\")], &[SelfKind::RefMut]),\n\n    // Conversion using `to_` can use borrowed (non-Copy types) or owned (Copy types).\n    // Source: https://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv\n    (&[Convention::StartsWith(\"to_\"), Convention::NotEndsWith(\"_mut\"), Convention::IsSelfTypeCopy(false),\n    Convention::IsTraitItem(false), Convention::ImplementsTrait(false)], &[SelfKind::Ref]),\n    (&[Convention::StartsWith(\"to_\"), Convention::NotEndsWith(\"_mut\"), Convention::IsSelfTypeCopy(true),\n    Convention::IsTraitItem(false), Convention::ImplementsTrait(false)], &[SelfKind::Value]),\n];\n\nenum Convention {\n    Eq(&'static str),\n    StartsWith(&'static str),\n    EndsWith(&'static str),\n    NotEndsWith(&'static str),\n    IsSelfTypeCopy(bool),\n    ImplementsTrait(bool),\n    IsTraitItem(bool),\n}\n\nimpl Convention {\n    #[must_use]\n    fn check<'tcx>(\n        &self,\n        cx: &LateContext<'tcx>,\n        self_ty: Ty<'tcx>,\n        other: &str,\n        implements_trait: bool,\n        is_trait_item: bool,\n    ) -> bool {\n        match *self {\n            Self::Eq(this) => this == other,\n            Self::StartsWith(this) => other.starts_with(this) && this != other,\n            Self::EndsWith(this) => other.ends_with(this) && this != other,\n            Self::NotEndsWith(this) => !Self::EndsWith(this).check(cx, self_ty, other, implements_trait, is_trait_item),\n            Self::IsSelfTypeCopy(is_true) => is_true == is_copy(cx, self_ty),\n            Self::ImplementsTrait(is_true) => is_true == implements_trait,\n            Self::IsTraitItem(is_true) => is_true == is_trait_item,\n        }\n    }\n}\n\nimpl fmt::Display for Convention {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {\n        match *self {\n            Self::Eq(this) => write!(f, \"`{this}`\"),\n            Self::StartsWith(this) => write!(f, \"`{this}*`\"),\n            Self::EndsWith(this) => write!(f, \"`*{this}`\"),\n            Self::NotEndsWith(this) => write!(f, \"`~{this}`\"),\n            Self::IsSelfTypeCopy(is_true) => {\n                write!(f, \"`self` type is{} `Copy`\", if is_true { \"\" } else { \" not\" })\n            },\n            Self::ImplementsTrait(is_true) => {\n                let (negation, s_suffix) = if is_true { (\"\", \"s\") } else { (\" does not\", \"\") };\n                write!(f, \"method{negation} implement{s_suffix} a trait\")\n            },\n            Self::IsTraitItem(is_true) => {\n                let suffix = if is_true { \" is\" } else { \" is not\" };\n                write!(f, \"method{suffix} a trait item\")\n            },\n        }\n    }\n}\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    item_name: Symbol,\n    self_ty: Ty<'tcx>,\n    first_arg_ty: Ty<'tcx>,\n    first_arg_span: Span,\n    implements_trait: bool,\n    is_trait_item: bool,\n) {\n    let item_name_str = item_name.as_str();\n    if let Some((conventions, self_kinds)) = &CONVENTIONS.iter().find(|(convs, _)| {\n        convs\n            .iter()\n            .all(|conv| conv.check(cx, self_ty, item_name_str, implements_trait, is_trait_item))\n    }) {\n        // don't lint if it implements a trait but not willing to check `Copy` types conventions (see #7032)\n        if implements_trait\n            && !conventions\n                .iter()\n                .any(|conv| matches!(conv, Convention::IsSelfTypeCopy(_)))\n        {\n            return;\n        }\n        if !self_kinds.iter().any(|k| k.matches(cx, self_ty, first_arg_ty)) {\n            let suggestion = {\n                if conventions.len() > 1 {\n                    // Don't mention `NotEndsWith` when there is also `StartsWith` convention present\n                    let cut_ends_with_conv = conventions.iter().any(|conv| matches!(conv, Convention::StartsWith(_)))\n                        && conventions\n                            .iter()\n                            .any(|conv| matches!(conv, Convention::NotEndsWith(_)));\n\n                    let s = conventions\n                        .iter()\n                        .filter(|conv| !(cut_ends_with_conv && matches!(conv, Convention::NotEndsWith(_))))\n                        .filter(|conv| !matches!(conv, Convention::ImplementsTrait(_) | Convention::IsTraitItem(_)))\n                        .format(\" and \");\n\n                    format!(\"methods with the following characteristics: ({s})\")\n                } else {\n                    format!(\"methods called {}\", &conventions[0])\n                }\n            };\n\n            span_lint_and_help(\n                cx,\n                WRONG_SELF_CONVENTION,\n                first_arg_span,\n                format!(\n                    \"{suggestion} usually take {}\",\n                    self_kinds.iter().map(|k| k.description()).format(\" or \")\n                ),\n                None,\n                \"consider choosing a less ambiguous name\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/methods/zst_offset.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::ZST_OFFSET;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {\n    if let ty::RawPtr(ty, _) = cx.typeck_results().expr_ty(recv).kind()\n        && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(*ty))\n        && layout.is_zst()\n    {\n        span_lint(cx, ZST_OFFSET, expr.span, \"offset calculation on zero-sized value\");\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/min_ident_chars.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::is_from_proc_macro;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::intravisit::{Visitor, walk_item, walk_trait_item};\nuse rustc_hir::{\n    GenericParamKind, HirId, Impl, ImplItem, ImplItemImplKind, ImplItemKind, Item, ItemKind, ItemLocalId, Node, Pat,\n    PatKind, TraitItem, UsePath,\n};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::Ident;\nuse rustc_span::{Span, Symbol};\nuse std::borrow::Cow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for identifiers which consist of a single character (or fewer than the configured threshold).\n    ///\n    /// Note: This lint can be very noisy when enabled; it may be desirable to only enable it\n    /// temporarily.\n    ///\n    /// ### Why restrict this?\n    /// To improve readability by requiring that every variable has a name more specific than a single letter can be.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// for m in movies {\n    ///     let title = m.t;\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// for movie in movies {\n    ///     let title = movie.title;\n    /// }\n    /// ```\n    ///\n    /// ### Limitations\n    /// Trait implementations which use the same function or parameter name as the trait declaration will\n    /// not be warned about, even if the name is below the configured limit.\n    #[clippy::version = \"1.72.0\"]\n    pub MIN_IDENT_CHARS,\n    restriction,\n    \"disallows idents that are too short\"\n}\n\nimpl_lint_pass!(MinIdentChars => [MIN_IDENT_CHARS]);\n\npub struct MinIdentChars {\n    allowed_idents_below_min_chars: FxHashSet<String>,\n    min_ident_chars_threshold: u64,\n}\n\nimpl MinIdentChars {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            allowed_idents_below_min_chars: conf.allowed_idents_below_min_chars.iter().cloned().collect(),\n            min_ident_chars_threshold: conf.min_ident_chars_threshold,\n        }\n    }\n\n    #[expect(clippy::cast_possible_truncation)]\n    fn is_ident_too_short(&self, cx: &LateContext<'_>, str: &str, span: Span) -> bool {\n        !span.in_external_macro(cx.sess().source_map())\n            && str.len() <= self.min_ident_chars_threshold as usize\n            && !str.starts_with('_')\n            && !str.is_empty()\n            && !self.allowed_idents_below_min_chars.contains(str)\n    }\n}\n\nimpl LateLintPass<'_> for MinIdentChars {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        if self.min_ident_chars_threshold == 0 {\n            return;\n        }\n\n        walk_item(&mut IdentVisitor { conf: self, cx }, item);\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {\n        if self.min_ident_chars_threshold == 0 {\n            return;\n        }\n\n        // If the function is declared but not defined in a trait, check_pat isn't called so we need to\n        // check this explicitly\n        if matches!(&item.kind, rustc_hir::TraitItemKind::Fn(_, _)) {\n            let param_names = cx.tcx.fn_arg_idents(item.owner_id.to_def_id());\n            for ident in param_names.iter().flatten() {\n                let str = ident.as_str();\n                if self.is_ident_too_short(cx, str, ident.span) {\n                    emit_min_ident_chars(self, cx, str, ident.span);\n                }\n            }\n        }\n\n        walk_trait_item(&mut IdentVisitor { conf: self, cx }, item);\n    }\n\n    // This is necessary as `Node::Pat`s are not visited in `visit_id`. :/\n    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {\n        if let PatKind::Binding(_, _, ident, ..) = pat.kind\n            && let str = ident.as_str()\n            && self.is_ident_too_short(cx, str, ident.span)\n            && is_not_in_trait_impl(cx, pat, ident)\n        {\n            emit_min_ident_chars(self, cx, str, ident.span);\n        }\n    }\n}\n\nstruct IdentVisitor<'cx, 'tcx> {\n    conf: &'cx MinIdentChars,\n    cx: &'cx LateContext<'tcx>,\n}\n\nimpl Visitor<'_> for IdentVisitor<'_, '_> {\n    fn visit_id(&mut self, hir_id: HirId) {\n        let Self { conf, cx } = *self;\n        // FIXME(#112534) Reimplementation of `find`, as it uses indexing, which can (and will in\n        // async functions, or really anything async) panic. This should probably be fixed on the\n        // rustc side, this is just a temporary workaround.\n        let node = if hir_id.local_id == ItemLocalId::from_u32(0) {\n            // In this case, we can just use `find`, `Owner`'s `node` field is private anyway so we can't\n            // reimplement it even if we wanted to\n            Some(cx.tcx.hir_node(hir_id))\n        } else {\n            let owner = cx.tcx.hir_owner_nodes(hir_id.owner);\n            owner.nodes.get(hir_id.local_id).copied().map(|p| p.node)\n        };\n        let Some(node) = node else {\n            return;\n        };\n        let Some(ident) = node.ident() else {\n            return;\n        };\n\n        let str = ident.as_str();\n        if conf.is_ident_too_short(cx, str, ident.span) {\n            // Check whether the node is part of a `impl` for a trait.\n            if matches!(cx.tcx.parent_hir_node(hir_id), Node::TraitRef(_)) {\n                return;\n            }\n\n            // Check whether the node is part of a `use` statement. We don't want to emit a warning if the user\n            // has no control over the type.\n            let usenode = opt_as_use_node(node).or_else(|| {\n                cx.tcx\n                    .hir_parent_iter(hir_id)\n                    .find_map(|(_, node)| opt_as_use_node(node))\n            });\n\n            // If the name of the identifier is the same as the one of the imported item, this means that we\n            // found a `use foo::bar`. We can early-return to not emit the warning.\n            // If however the identifier is different, this means it is an alias (`use foo::bar as baz`). In\n            // this case, we need to emit the warning for `baz`.\n            if let Some(imported_item_path) = usenode\n                // use `present_items` because it could be in any of type_ns, value_ns, macro_ns\n                && let Some(Res::Def(_, imported_item_defid)) = imported_item_path.res.value_ns\n                && cx.tcx.item_name(imported_item_defid).as_str() == str\n            {\n                return;\n            }\n\n            // `struct Array<T, const N: usize>([T; N])`\n            //                                   ^  ^\n            if let Node::PathSegment(path) = node {\n                if let Res::Def(def_kind, ..) = path.res\n                    && let DefKind::TyParam | DefKind::ConstParam = def_kind\n                {\n                    return;\n                }\n                if matches!(path.res, Res::PrimTy(..)) || path.res.opt_def_id().is_some_and(|def_id| !def_id.is_local())\n                {\n                    return;\n                }\n            }\n            // `struct Awa<T>(T)`\n            //             ^\n            if let Node::GenericParam(generic_param) = node\n                && let GenericParamKind::Type { .. } = generic_param.kind\n            {\n                return;\n            }\n\n            // `struct Array<T, const N: usize>([T; N])`\n            //                        ^\n            if let Node::GenericParam(generic_param) = node\n                && let GenericParamKind::Const { .. } = generic_param.kind\n            {\n                return;\n            }\n\n            if is_from_proc_macro(cx, &ident) {\n                return;\n            }\n\n            emit_min_ident_chars(conf, cx, str, ident.span);\n        }\n    }\n}\n\nfn emit_min_ident_chars(conf: &MinIdentChars, cx: &impl LintContext, ident: &str, span: Span) {\n    let help = if conf.min_ident_chars_threshold == 1 {\n        Cow::Borrowed(\"this ident consists of a single char\")\n    } else {\n        Cow::Owned(format!(\n            \"this ident is too short ({} <= {})\",\n            ident.len(),\n            conf.min_ident_chars_threshold,\n        ))\n    };\n    span_lint(cx, MIN_IDENT_CHARS, span, help);\n}\n\n/// Attempt to convert the node to an [`ItemKind::Use`] node.\n///\n/// If it is, return the [`UsePath`] contained within.\nfn opt_as_use_node(node: Node<'_>) -> Option<&'_ UsePath<'_>> {\n    if let Node::Item(item) = node\n        && let ItemKind::Use(path, _) = item.kind\n    {\n        Some(path)\n    } else {\n        None\n    }\n}\n\n/// Check if a pattern is a function param in an impl block for a trait and that the param name is\n/// the same than in the trait definition.\nfn is_not_in_trait_impl(cx: &LateContext<'_>, pat: &Pat<'_>, ident: Ident) -> bool {\n    let parent_node = cx.tcx.parent_hir_node(pat.hir_id);\n    if !matches!(parent_node, Node::Param(_)) {\n        return true;\n    }\n\n    for (_, parent_node) in cx.tcx.hir_parent_iter(pat.hir_id) {\n        if let Node::ImplItem(impl_item) = parent_node\n            && matches!(impl_item.kind, ImplItemKind::Fn(_, _))\n        {\n            let impl_parent_node = cx.tcx.parent_hir_node(impl_item.hir_id());\n            if let Node::Item(parent_item) = impl_parent_node\n                && let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = &parent_item.kind\n                && let Some(name) = get_param_name(impl_item, cx, ident)\n            {\n                return name != ident.name;\n            }\n\n            return true;\n        }\n    }\n\n    true\n}\n\nfn get_param_name(impl_item: &ImplItem<'_>, cx: &LateContext<'_>, ident: Ident) -> Option<Symbol> {\n    if let ImplItemImplKind::Trait {\n        trait_item_def_id: Ok(trait_item_def_id),\n        ..\n    } = impl_item.impl_kind\n    {\n        let trait_param_names = cx.tcx.fn_arg_idents(trait_item_def_id);\n\n        let ImplItemKind::Fn(_, body_id) = impl_item.kind else {\n            return None;\n        };\n\n        if let Some(param_index) = cx\n            .tcx\n            .hir_body_param_idents(body_id)\n            .position(|param_ident| param_ident.is_some_and(|param_ident| param_ident.span == ident.span))\n            && let Some(trait_param_name) = trait_param_names.get(param_index)\n            && let Some(trait_param_ident) = trait_param_name\n        {\n            return Some(trait_param_ident.name);\n        }\n    }\n\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/minmax.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::sym;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::SyntaxContext;\nuse std::cmp::Ordering::{Equal, Greater, Less};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions where `std::cmp::min` and `max` are\n    /// used to clamp values, but switched so that the result is constant.\n    ///\n    /// ### Why is this bad?\n    /// This is in all probability not the intended outcome. At\n    /// the least it hurts readability of the code.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// min(0, max(100, x))\n    ///\n    /// // or\n    ///\n    /// x.max(100).min(0)\n    /// ```\n    /// It will always be equal to `0`. Probably the author meant to clamp the value\n    /// between 0 and 100, but has erroneously swapped `min` and `max`.\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MIN_MAX,\n    correctness,\n    \"`min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant\"\n}\n\ndeclare_lint_pass!(MinMaxPass => [MIN_MAX]);\n\nimpl<'tcx> LateLintPass<'tcx> for MinMaxPass {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let Some((outer_max, outer_c, oe)) = min_max(cx, expr)\n            && let Some((inner_max, inner_c, ie)) = min_max(cx, oe)\n            && outer_max != inner_max\n            && let Some(ord) = Constant::partial_cmp(cx.tcx, cx.typeck_results().expr_ty(ie), &outer_c, &inner_c)\n            && matches!(\n                (outer_max, ord),\n                (MinMax::Max, Equal | Greater) | (MinMax::Min, Equal | Less)\n            )\n        {\n            span_lint(\n                cx,\n                MIN_MAX,\n                expr.span,\n                \"this `min`/`max` combination leads to constant result\",\n            );\n        }\n    }\n}\n\n#[derive(PartialEq, Eq, Debug, Clone, Copy)]\nenum MinMax {\n    Min,\n    Max,\n}\n\nfn min_max<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(MinMax, Constant, &'a Expr<'a>)> {\n    match expr.kind {\n        ExprKind::Call(path, args) => {\n            if let ExprKind::Path(ref qpath) = path.kind {\n                cx.typeck_results()\n                    .qpath_res(qpath, path.hir_id)\n                    .opt_def_id()\n                    .and_then(|def_id| match cx.tcx.get_diagnostic_name(def_id) {\n                        Some(sym::cmp_min) => fetch_const(cx, expr.span.ctxt(), None, args, MinMax::Min),\n                        Some(sym::cmp_max) => fetch_const(cx, expr.span.ctxt(), None, args, MinMax::Max),\n                        _ => None,\n                    })\n            } else {\n                None\n            }\n        },\n        ExprKind::MethodCall(path, receiver, args @ [_], _) => {\n            if cx.typeck_results().expr_ty(receiver).is_floating_point()\n                || cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Ord)\n            {\n                match path.ident.name {\n                    sym::max => fetch_const(cx, expr.span.ctxt(), Some(receiver), args, MinMax::Max),\n                    sym::min => fetch_const(cx, expr.span.ctxt(), Some(receiver), args, MinMax::Min),\n                    _ => None,\n                }\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\nfn fetch_const<'a>(\n    cx: &LateContext<'_>,\n    ctxt: SyntaxContext,\n    receiver: Option<&'a Expr<'a>>,\n    args: &'a [Expr<'a>],\n    m: MinMax,\n) -> Option<(MinMax, Constant, &'a Expr<'a>)> {\n    let mut args = receiver.into_iter().chain(args);\n    let first_arg = args.next()?;\n    let second_arg = args.next()?;\n    if args.next().is_some() {\n        return None;\n    }\n    let ecx = ConstEvalCtxt::new(cx);\n    match (ecx.eval_local(first_arg, ctxt), ecx.eval_local(second_arg, ctxt)) {\n        (Some(c), None) => Some((m, c, second_arg)),\n        (None, Some(c)) => Some((m, c, first_arg)),\n        // otherwise ignore\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/misc.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{SpanlessEq, fulfill_or_allowed, get_parent_expr, in_automatically_derived, last_path_segment};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, QPath, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of short circuit boolean conditions as\n    /// a\n    /// statement.\n    ///\n    /// ### Why is this bad?\n    /// Using a short circuit boolean condition as a statement\n    /// may hide the fact that the second part is executed or not depending on the\n    /// outcome of the first part.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// f() && g(); // We should write `if f() { g(); }`.\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SHORT_CIRCUIT_STATEMENT,\n    complexity,\n    \"using a short circuit boolean condition as a statement\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of bindings with a single leading\n    /// underscore.\n    ///\n    /// ### Why is this bad?\n    /// A single leading underscore is usually used to indicate\n    /// that a binding will not be used. Using such a binding breaks this\n    /// expectation.\n    ///\n    /// ### Known problems\n    /// The lint does not work properly with desugaring and\n    /// macro, it has been allowed in the meantime.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _x = 0;\n    /// let y = _x + 1; // Here we are using `_x`, even though it has a leading\n    ///                 // underscore. We should rename `_x` to `x`\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USED_UNDERSCORE_BINDING,\n    pedantic,\n    \"using a binding which is prefixed with an underscore\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the use of item with a single leading\n    /// underscore.\n    ///\n    /// ### Why is this bad?\n    /// A single leading underscore is usually used to indicate\n    /// that a item will not be used. Using such a item breaks this\n    /// expectation.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn _foo() {}\n    ///\n    /// struct _FooStruct {}\n    ///\n    /// fn main() {\n    ///     _foo();\n    ///     let _ = _FooStruct{};\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn foo() {}\n    ///\n    /// struct FooStruct {}\n    ///\n    /// fn main() {\n    ///     foo();\n    ///     let _ = FooStruct{};\n    /// }\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub USED_UNDERSCORE_ITEMS,\n    pedantic,\n    \"using a item which is prefixed with an underscore\"\n}\n\ndeclare_lint_pass!(LintPass => [\n    SHORT_CIRCUIT_STATEMENT,\n    USED_UNDERSCORE_BINDING,\n    USED_UNDERSCORE_ITEMS,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for LintPass {\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if let StmtKind::Semi(expr) = stmt.kind\n            && let ExprKind::Binary(binop, a, b) = &expr.kind\n            && matches!(binop.node, BinOpKind::And | BinOpKind::Or)\n            && !stmt.span.from_expansion()\n            && expr.span.eq_ctxt(stmt.span)\n        {\n            span_lint_hir_and_then(\n                cx,\n                SHORT_CIRCUIT_STATEMENT,\n                expr.hir_id,\n                stmt.span,\n                \"boolean short circuit operator in statement may be clearer using an explicit test\",\n                |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let test = Sugg::hir_with_context(cx, a, expr.span.ctxt(), \"_\", &mut app);\n                    let test = if binop.node == BinOpKind::Or { !test } else { test };\n                    let then = Sugg::hir_with_context(cx, b, expr.span.ctxt(), \"_\", &mut app);\n                    diag.span_suggestion(stmt.span, \"replace it with\", format!(\"if {test} {{ {then}; }}\"), app);\n                },\n            );\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if expr.span.in_external_macro(cx.sess().source_map())\n            || expr.span.desugaring_kind().is_some()\n            || in_automatically_derived(cx.tcx, expr.hir_id)\n        {\n            return;\n        }\n\n        used_underscore_binding(cx, expr);\n        used_underscore_items(cx, expr);\n    }\n}\n\nfn used_underscore_items<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n    let (def_id, ident) = match expr.kind {\n        ExprKind::Call(func, ..) => {\n            if let ExprKind::Path(QPath::Resolved(.., path)) = func.kind\n                && let Some(last_segment) = path.segments.last()\n                && let Res::Def(_, def_id) = last_segment.res\n            {\n                (def_id, last_segment.ident)\n            } else {\n                return;\n            }\n        },\n        ExprKind::MethodCall(path, ..) => {\n            if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {\n                (def_id, path.ident)\n            } else {\n                return;\n            }\n        },\n        ExprKind::Struct(QPath::Resolved(_, path), ..) => {\n            if let Some(last_segment) = path.segments.last()\n                && let Res::Def(_, def_id) = last_segment.res\n            {\n                (def_id, last_segment.ident)\n            } else {\n                return;\n            }\n        },\n        _ => return,\n    };\n\n    let name = ident.name.as_str();\n    let definition_span = cx.tcx.def_span(def_id);\n    if name.starts_with('_')\n        && !name.starts_with(\"__\")\n        && !definition_span.from_expansion()\n        && def_id.is_local()\n        && !cx.tcx.is_foreign_item(def_id)\n    {\n        span_lint_and_then(\n            cx,\n            USED_UNDERSCORE_ITEMS,\n            expr.span,\n            \"used underscore-prefixed item\".to_string(),\n            |diag| {\n                diag.span_note(definition_span, \"item is defined here\".to_string());\n            },\n        );\n    }\n}\n\nfn used_underscore_binding<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n    let (definition_hir_id, ident) = match expr.kind {\n        ExprKind::Path(ref qpath) => {\n            if let QPath::Resolved(None, path) = qpath\n                && let Res::Local(id) = path.res\n                && is_used(cx, expr)\n            {\n                (id, last_path_segment(qpath).ident)\n            } else {\n                return;\n            }\n        },\n        ExprKind::Field(recv, ident) => {\n            if let Some(adt_def) = cx.typeck_results().expr_ty_adjusted(recv).ty_adt_def()\n                && let Some(field) = adt_def.all_fields().find(|field| field.name == ident.name)\n                && let Some(local_did) = field.did.as_local()\n                && !cx.tcx.type_of(field.did).skip_binder().is_phantom_data()\n            {\n                (cx.tcx.local_def_id_to_hir_id(local_did), ident)\n            } else {\n                return;\n            }\n        },\n        _ => return,\n    };\n\n    let name = ident.name.as_str();\n    if name.starts_with('_')\n        && !name.starts_with(\"__\")\n        && let definition_span = cx.tcx.hir_span(definition_hir_id)\n        && !definition_span.from_expansion()\n        && !fulfill_or_allowed(cx, USED_UNDERSCORE_BINDING, [expr.hir_id, definition_hir_id])\n    {\n        span_lint_and_then(\n            cx,\n            USED_UNDERSCORE_BINDING,\n            expr.span,\n            \"used underscore-prefixed binding\".to_string(),\n            |diag| {\n                diag.span_note(definition_span, \"binding is defined here\".to_string());\n            },\n        );\n    }\n}\n\n/// Heuristic to see if an expression is used. Should be compatible with\n/// `unused_variables`'s idea\n/// of what it means for an expression to be \"used\".\nfn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    get_parent_expr(cx, expr).is_none_or(|parent| match parent.kind {\n        ExprKind::Assign(_, rhs, _) | ExprKind::AssignOp(_, _, rhs) => SpanlessEq::new(cx).eq_expr(rhs, expr),\n        _ => is_used(cx, parent),\n    })\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/builtin_type_shadow.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_ast::ast::{GenericParam, GenericParamKind};\nuse rustc_hir::PrimTy;\nuse rustc_lint::EarlyContext;\n\nuse super::BUILTIN_TYPE_SHADOW;\n\npub(super) fn check(cx: &EarlyContext<'_>, param: &GenericParam) {\n    if let GenericParamKind::Type { .. } = param.kind\n        && let Some(prim_ty) = PrimTy::from_name(param.ident.name)\n    {\n        span_lint(\n            cx,\n            BUILTIN_TYPE_SHADOW,\n            param.ident.span,\n            format!(\"this generic shadows the built-in type `{}`\", prim_ty.name()),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/literal_suffix.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_errors::Applicability;\nuse rustc_lint::EarlyContext;\nuse rustc_span::Span;\n\nuse super::{SEPARATED_LITERAL_SUFFIX, UNSEPARATED_LITERAL_SUFFIX};\n\npub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str, suffix: &str, sugg_type: &str) {\n    let Some(maybe_last_sep_idx) = lit_snip.len().checked_sub(suffix.len() + 1) else {\n        return; // It's useless so shouldn't lint.\n    };\n    // Do not lint when literal is unsuffixed.\n    if !suffix.is_empty() {\n        if lit_snip.as_bytes()[maybe_last_sep_idx] == b'_' {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                SEPARATED_LITERAL_SUFFIX,\n                lit_span,\n                format!(\"{sugg_type} type suffix should not be separated by an underscore\"),\n                |diag| {\n                    diag.span_suggestion(\n                        lit_span,\n                        \"remove the underscore\",\n                        format!(\"{}{suffix}\", &lit_snip[..maybe_last_sep_idx]),\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        } else {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                UNSEPARATED_LITERAL_SUFFIX,\n                lit_span,\n                format!(\"{sugg_type} type suffix should be separated by an underscore\"),\n                |diag| {\n                    diag.span_suggestion(\n                        lit_span,\n                        \"add an underscore\",\n                        format!(\"{}_{suffix}\", &lit_snip[..=maybe_last_sep_idx]),\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/mixed_case_hex_literals.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse rustc_lint::EarlyContext;\nuse rustc_span::Span;\n\nuse super::MIXED_CASE_HEX_LITERALS;\n\npub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, suffix: &str, lit_snip: &str) {\n    let num_end_idx = match lit_snip.strip_suffix(suffix) {\n        Some(p) if p.ends_with('_') => lit_snip.len() - (suffix.len() + 1),\n        Some(_) => lit_snip.len() - suffix.len(),\n        None => lit_snip.len(),\n    };\n\n    if num_end_idx <= 2 {\n        // It's meaningless or causes range error.\n        return;\n    }\n\n    let mut seen = (false, false);\n    for ch in &lit_snip.as_bytes()[2..num_end_idx] {\n        match ch {\n            b'a'..=b'f' => seen.0 = true,\n            b'A'..=b'F' => seen.1 = true,\n            _ => {},\n        }\n        if seen.0 && seen.1 {\n            let raw_digits = &lit_snip[2..num_end_idx];\n            let (sugg_lower, sugg_upper) = if suffix.is_empty() {\n                (\n                    format!(\"0x{}\", raw_digits.to_lowercase()),\n                    format!(\"0x{}\", raw_digits.to_uppercase()),\n                )\n            } else {\n                (\n                    format!(\"0x{}_{}\", raw_digits.to_lowercase(), suffix),\n                    format!(\"0x{}_{}\", raw_digits.to_uppercase(), suffix),\n                )\n            };\n\n            span_lint_and_help(\n                cx,\n                MIXED_CASE_HEX_LITERALS,\n                lit_span,\n                \"inconsistent casing in hexadecimal literal\",\n                None,\n                format!(\"consider using `{sugg_lower}` or `{sugg_upper}`\"),\n            );\n            return;\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/mod.rs",
    "content": "mod builtin_type_shadow;\nmod literal_suffix;\nmod mixed_case_hex_literals;\nmod redundant_at_rest_pattern;\nmod redundant_pattern;\nmod unneeded_field_pattern;\nmod unneeded_wildcard_pattern;\nmod zero_prefixed_literal;\n\nuse clippy_utils::source::snippet_opt;\nuse rustc_ast::ast::{Expr, ExprKind, Generics, LitFloatType, LitIntType, LitKind, Pat};\nuse rustc_ast::token;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if a generic shadows a built-in type.\n    ///\n    /// ### Why is this bad?\n    /// This gives surprising type errors.\n    ///\n    /// ### Example\n    ///\n    /// ```ignore\n    /// impl<u32> Foo<u32> {\n    ///     fn impl_func(&self) -> u32 {\n    ///         42\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub BUILTIN_TYPE_SHADOW,\n    style,\n    \"shadowing a builtin type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns on hexadecimal literals with mixed-case letter\n    /// digits.\n    ///\n    /// ### Why is this bad?\n    /// It looks confusing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let _ =\n    /// 0x1a9BAcD\n    /// # ;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let _ =\n    /// 0x1A9BACD\n    /// # ;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MIXED_CASE_HEX_LITERALS,\n    style,\n    \"hex literals whose letter digits are not consistently upper- or lowercased\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `[all @ ..]` patterns.\n    ///\n    /// ### Why is this bad?\n    /// In all cases, `all` works fine and can often make code simpler, as you possibly won't need\n    /// to convert from say a `Vec` to a slice by dereferencing.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// if let [all @ ..] = &*v {\n    ///     // NOTE: Type is a slice here\n    ///     println!(\"all elements: {all:#?}\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// if let all = v {\n    ///     // NOTE: Type is a `Vec` here\n    ///     println!(\"all elements: {all:#?}\");\n    /// }\n    /// // or\n    /// println!(\"all elements: {v:#?}\");\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub REDUNDANT_AT_REST_PATTERN,\n    complexity,\n    \"checks for `[all @ ..]` where `all` would suffice\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for patterns in the form `name @ _`.\n    ///\n    /// ### Why is this bad?\n    /// It's almost always more readable to just use direct\n    /// bindings.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let v = Some(\"abc\");\n    /// match v {\n    ///     Some(x) => (),\n    ///     y @ _ => (),\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let v = Some(\"abc\");\n    /// match v {\n    ///     Some(x) => (),\n    ///     y => (),\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub REDUNDANT_PATTERN,\n    style,\n    \"using `name @ _` in a pattern\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if literal suffixes are separated by an underscore.\n    /// To enforce separated literal suffix style,\n    /// see the `unseparated_literal_suffix` lint.\n    ///\n    /// ### Why restrict this?\n    /// Suffix style should be consistent.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let _ =\n    /// 123832_i32\n    /// # ;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let _ =\n    /// 123832i32\n    /// # ;\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub SEPARATED_LITERAL_SUFFIX,\n    restriction,\n    \"literals whose suffix is separated by an underscore\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for structure field patterns bound to wildcards.\n    ///\n    /// ### Why restrict this?\n    /// Using `..` instead is shorter and leaves the focus on\n    /// the fields that are actually bound.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct Foo {\n    /// #     a: i32,\n    /// #     b: i32,\n    /// #     c: i32,\n    /// # }\n    /// let f = Foo { a: 0, b: 0, c: 0 };\n    ///\n    /// match f {\n    ///     Foo { a: _, b: 0, .. } => {},\n    ///     Foo { a: _, b: _, c: _ } => {},\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # struct Foo {\n    /// #     a: i32,\n    /// #     b: i32,\n    /// #     c: i32,\n    /// # }\n    /// let f = Foo { a: 0, b: 0, c: 0 };\n    ///\n    /// match f {\n    ///     Foo { b: 0, .. } => {},\n    ///     Foo { .. } => {},\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNNEEDED_FIELD_PATTERN,\n    restriction,\n    \"struct fields bound to a wildcard instead of using `..`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for tuple patterns with a wildcard\n    /// pattern (`_`) is next to a rest pattern (`..`).\n    ///\n    /// _NOTE_: While `_, ..` means there is at least one element left, `..`\n    /// means there are 0 or more elements left. This can make a difference\n    /// when refactoring, but shouldn't result in errors in the refactored code,\n    /// since the wildcard pattern isn't used anyway.\n    ///\n    /// ### Why is this bad?\n    /// The wildcard pattern is unneeded as the rest pattern\n    /// can match that element as well.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct TupleStruct(u32, u32, u32);\n    /// # let t = TupleStruct(1, 2, 3);\n    /// match t {\n    ///     TupleStruct(0, .., _) => (),\n    ///     _ => (),\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # struct TupleStruct(u32, u32, u32);\n    /// # let t = TupleStruct(1, 2, 3);\n    /// match t {\n    ///     TupleStruct(0, ..) => (),\n    ///     _ => (),\n    /// }\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub UNNEEDED_WILDCARD_PATTERN,\n    complexity,\n    \"tuple patterns with a wildcard pattern (`_`) is next to a rest pattern (`..`)\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if literal suffixes are not separated by an\n    /// underscore.\n    /// To enforce unseparated literal suffix style,\n    /// see the `separated_literal_suffix` lint.\n    ///\n    /// ### Why restrict this?\n    /// Suffix style should be consistent.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let _ =\n    /// 123832i32\n    /// # ;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let _ =\n    /// 123832_i32\n    /// # ;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNSEPARATED_LITERAL_SUFFIX,\n    restriction,\n    \"literals whose suffix is not separated by an underscore\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if an integral constant literal starts with `0`.\n    ///\n    /// ### Why is this bad?\n    /// In some languages (including the infamous C language\n    /// and most of its\n    /// family), this marks an octal constant. In Rust however, this is a decimal\n    /// constant. This could\n    /// be confusing for both the writer and a reader of the constant.\n    ///\n    /// ### Example\n    ///\n    /// In Rust:\n    /// ```no_run\n    /// fn main() {\n    ///     let a = 0123;\n    ///     println!(\"{}\", a);\n    /// }\n    /// ```\n    ///\n    /// prints `123`, while in C:\n    ///\n    /// ```c\n    /// #include <stdio.h>\n    ///\n    /// int main() {\n    ///     int a = 0123;\n    ///     printf(\"%d\\n\", a);\n    /// }\n    /// ```\n    ///\n    /// prints `83` (as `83 == 0o123` while `123 == 0o173`).\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ZERO_PREFIXED_LITERAL,\n    complexity,\n    \"integer literals starting with `0`\"\n}\n\ndeclare_lint_pass!(MiscEarlyLints => [\n    BUILTIN_TYPE_SHADOW,\n    MIXED_CASE_HEX_LITERALS,\n    REDUNDANT_AT_REST_PATTERN,\n    REDUNDANT_PATTERN,\n    SEPARATED_LITERAL_SUFFIX,\n    UNNEEDED_FIELD_PATTERN,\n    UNNEEDED_WILDCARD_PATTERN,\n    UNSEPARATED_LITERAL_SUFFIX,\n    ZERO_PREFIXED_LITERAL,\n]);\n\nimpl EarlyLintPass for MiscEarlyLints {\n    fn check_generics(&mut self, cx: &EarlyContext<'_>, generics: &Generics) {\n        for param in &generics.params {\n            builtin_type_shadow::check(cx, param);\n        }\n    }\n\n    fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) {\n        if pat.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        unneeded_field_pattern::check(cx, pat);\n        redundant_pattern::check(cx, pat);\n        redundant_at_rest_pattern::check(cx, pat);\n        unneeded_wildcard_pattern::check(cx, pat);\n    }\n\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if expr.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if let ExprKind::Lit(lit) = expr.kind {\n            MiscEarlyLints::check_lit(cx, lit, expr.span);\n        }\n    }\n}\n\nimpl MiscEarlyLints {\n    fn check_lit(cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {\n        // We test if first character in snippet is a number, because the snippet could be an expansion\n        // from a built-in macro like `line!()` or a proc-macro like `#[wasm_bindgen]`.\n        // Note that this check also covers special case that `line!()` is eagerly expanded by compiler.\n        // See <https://github.com/rust-lang/rust-clippy/issues/4507> for a regression.\n        // FIXME: Find a better way to detect those cases.\n        let lit_snip = match snippet_opt(cx, span) {\n            Some(snip) if snip.starts_with(|c: char| c.is_ascii_digit()) => snip,\n            _ => return,\n        };\n\n        let lit_kind = LitKind::from_token_lit(lit);\n        if let Ok(LitKind::Int(value, lit_int_type)) = lit_kind {\n            let suffix = match lit_int_type {\n                LitIntType::Signed(ty) => ty.name_str(),\n                LitIntType::Unsigned(ty) => ty.name_str(),\n                LitIntType::Unsuffixed => \"\",\n            };\n            literal_suffix::check(cx, span, &lit_snip, suffix, \"integer\");\n            if lit_snip.starts_with(\"0x\") {\n                mixed_case_hex_literals::check(cx, span, suffix, &lit_snip);\n            } else if lit_snip.starts_with(\"0b\") || lit_snip.starts_with(\"0o\") {\n                // nothing to do\n            } else if value != 0 && lit_snip.starts_with('0') {\n                zero_prefixed_literal::check(cx, span, &lit_snip);\n            }\n        } else if let Ok(LitKind::Float(_, LitFloatType::Suffixed(float_ty))) = lit_kind {\n            let suffix = float_ty.name_str();\n            literal_suffix::check(cx, span, &lit_snip, suffix, \"float\");\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/redundant_at_rest_pattern.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse rustc_ast::{Pat, PatKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, LintContext};\n\nuse super::REDUNDANT_AT_REST_PATTERN;\n\npub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {\n    if !pat.span.in_external_macro(cx.sess().source_map())\n        && let PatKind::Slice(slice) = &pat.kind\n        && let [one] = &**slice\n        && let PatKind::Ident(annotation, ident, Some(rest)) = &one.kind\n        && let PatKind::Rest = rest.kind\n    {\n        span_lint_and_sugg(\n            cx,\n            REDUNDANT_AT_REST_PATTERN,\n            pat.span,\n            \"using a rest pattern to bind an entire slice to a local\",\n            \"this is better represented with just the binding\",\n            format!(\"{}{ident}\", annotation.prefix_str()),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/redundant_pattern.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse rustc_ast::ast::{Pat, PatKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::EarlyContext;\n\nuse super::REDUNDANT_PATTERN;\n\npub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {\n    if let PatKind::Ident(ann, ident, Some(ref right)) = pat.kind\n        && let PatKind::Wild = right.kind\n    {\n        span_lint_and_sugg(\n            cx,\n            REDUNDANT_PATTERN,\n            pat.span,\n            format!(\n                \"the `{} @ _` pattern can be written as just `{}`\",\n                ident.name, ident.name,\n            ),\n            \"try\",\n            format!(\"{}{}\", ann.prefix_str(), ident.name),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/unneeded_field_pattern.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::source::SpanRangeExt;\nuse itertools::Itertools;\nuse rustc_ast::ast::{Pat, PatKind};\nuse rustc_lint::EarlyContext;\n\nuse super::UNNEEDED_FIELD_PATTERN;\n\npub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {\n    if let PatKind::Struct(_, ref npat, ref pfields, _) = pat.kind {\n        let mut wilds = 0;\n        let type_name = npat\n            .segments\n            .last()\n            .expect(\"A path must have at least one segment\")\n            .ident\n            .name;\n\n        for field in pfields {\n            if let PatKind::Wild = field.pat.kind {\n                wilds += 1;\n            }\n        }\n        if !pfields.is_empty() && wilds == pfields.len() {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                UNNEEDED_FIELD_PATTERN,\n                pat.span,\n                \"all the struct fields are matched to a wildcard pattern, consider using `..`\",\n                |diag| {\n                    diag.help(format!(\"try with `{type_name} {{ .. }}` instead\"));\n                },\n            );\n            return;\n        }\n        if wilds > 0 {\n            for field in pfields {\n                if let PatKind::Wild = field.pat.kind {\n                    wilds -= 1;\n                    if wilds > 0 {\n                        span_lint(\n                            cx,\n                            UNNEEDED_FIELD_PATTERN,\n                            field.span,\n                            \"you matched a field with a wildcard pattern, consider using `..` instead\",\n                        );\n                    } else {\n                        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                        span_lint_and_then(\n                            cx,\n                            UNNEEDED_FIELD_PATTERN,\n                            field.span,\n                            \"you matched a field with a wildcard pattern, consider using `..` instead\",\n                            |diag| {\n                                diag.help(format!(\n                                    \"try with `{type_name} {{ {}, .. }}`\",\n                                    pfields\n                                        .iter()\n                                        .filter_map(|f| match f.pat.kind {\n                                            PatKind::Wild => None,\n                                            _ => f.span.get_source_text(cx),\n                                        })\n                                        .format(\", \"),\n                                ));\n                            },\n                        );\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse rustc_ast::ast::{Pat, PatKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::EarlyContext;\nuse rustc_span::Span;\n\nuse super::UNNEEDED_WILDCARD_PATTERN;\n\npub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {\n    if let PatKind::TupleStruct(_, _, ref patterns) | PatKind::Tuple(ref patterns) = pat.kind\n        && let Some(rest_index) = patterns.iter().position(Pat::is_rest)\n    {\n        if let Some((left_index, left_pat)) = patterns[..rest_index]\n            .iter()\n            .rev()\n            .take_while(|pat| matches!(pat.kind, PatKind::Wild))\n            .enumerate()\n            .last()\n        {\n            span_lint(cx, left_pat.span.until(patterns[rest_index].span), left_index == 0);\n        }\n\n        if let Some((right_index, right_pat)) = patterns[rest_index + 1..]\n            .iter()\n            .take_while(|pat| matches!(pat.kind, PatKind::Wild))\n            .enumerate()\n            .last()\n        {\n            span_lint(\n                cx,\n                patterns[rest_index].span.shrink_to_hi().to(right_pat.span),\n                right_index == 0,\n            );\n        }\n    }\n}\n\nfn span_lint(cx: &EarlyContext<'_>, span: Span, only_one: bool) {\n    span_lint_and_sugg(\n        cx,\n        UNNEEDED_WILDCARD_PATTERN,\n        span,\n        if only_one {\n            \"this pattern is unneeded as the `..` pattern can match that element\"\n        } else {\n            \"these patterns are unneeded as the `..` pattern can match those elements\"\n        },\n        if only_one { \"remove it\" } else { \"remove them\" },\n        String::new(),\n        Applicability::MachineApplicable,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/misc_early/zero_prefixed_literal.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_errors::Applicability;\nuse rustc_lint::EarlyContext;\nuse rustc_span::Span;\n\nuse super::ZERO_PREFIXED_LITERAL;\n\npub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str) {\n    let trimmed_lit_snip = lit_snip.trim_start_matches(['_', '0']);\n    span_lint_and_then(\n        cx,\n        ZERO_PREFIXED_LITERAL,\n        lit_span,\n        \"this is a decimal constant\",\n        |diag| {\n            diag.span_suggestion(\n                lit_span,\n                \"if you mean to use a decimal constant, remove the `0` to avoid confusion\",\n                trimmed_lit_snip.to_string(),\n                Applicability::MaybeIncorrect,\n            );\n            // do not advise to use octal form if the literal cannot be expressed in base 8.\n            if !lit_snip.contains(['8', '9']) {\n                diag.span_suggestion(\n                    lit_span,\n                    \"if you mean to use an octal constant, use `0o`\",\n                    format!(\"0o{trimmed_lit_snip}\"),\n                    Applicability::MaybeIncorrect,\n                );\n            }\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/mismatching_type_param_order.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{GenericArg, Item, ItemKind, QPath, Ty, TyKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::GenericParamDefKind;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for type parameters which are positioned inconsistently between\n    /// a type definition and impl block. Specifically, a parameter in an impl\n    /// block which has the same name as a parameter in the type def, but is in\n    /// a different place.\n    ///\n    /// ### Why is this bad?\n    /// Type parameters are determined by their position rather than name.\n    /// Naming type parameters inconsistently may cause you to refer to the\n    /// wrong type parameter.\n    ///\n    /// ### Limitations\n    /// This lint only applies to impl blocks with simple generic params, e.g.\n    /// `A`. If there is anything more complicated, such as a tuple, it will be\n    /// ignored.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo<A, B> {\n    ///     x: A,\n    ///     y: B,\n    /// }\n    /// // inside the impl, B refers to Foo::A\n    /// impl<B, A> Foo<B, A> {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct Foo<A, B> {\n    ///     x: A,\n    ///     y: B,\n    /// }\n    /// impl<A, B> Foo<A, B> {}\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub MISMATCHING_TYPE_PARAM_ORDER,\n    pedantic,\n    \"type parameter positioned inconsistently between type def and impl block\"\n}\n\ndeclare_lint_pass!(TypeParamMismatch => [MISMATCHING_TYPE_PARAM_ORDER]);\n\nimpl<'tcx> LateLintPass<'tcx> for TypeParamMismatch {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if let ItemKind::Impl(imp) = &item.kind\n            && let TyKind::Path(QPath::Resolved(_, path)) = &imp.self_ty.kind\n            && let [segment, ..] = path.segments\n            && let Some(generic_args) = segment.args\n            && !generic_args.args.is_empty()\n            && !item.span.from_expansion()\n        {\n            // get the name and span of the generic parameters in the Impl\n            let mut impl_params = Vec::new();\n            for p in generic_args.args {\n                match p {\n                    GenericArg::Type(Ty {\n                        kind: TyKind::Path(QPath::Resolved(_, path)),\n                        ..\n                    }) => impl_params.push((path.segments[0].ident.to_string(), path.span)),\n                    GenericArg::Type(_) => return,\n                    _ => (),\n                }\n            }\n\n            // find the type that the Impl is for\n            // only lint on struct/enum/union for now\n            let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, defid) = path.res else {\n                return;\n            };\n\n            // get the names of the generic parameters in the type\n            let type_params = &cx.tcx.generics_of(defid).own_params;\n            let type_param_names: Vec<_> = type_params\n                .iter()\n                .filter_map(|p| match p.kind {\n                    GenericParamDefKind::Type { .. } => Some(p.name.to_string()),\n                    _ => None,\n                })\n                .collect();\n            // hashmap of name -> index for mismatch_param_name\n            let type_param_names_hashmap: FxHashMap<&String, usize> = type_param_names\n                .iter()\n                .enumerate()\n                .map(|(i, param)| (param, i))\n                .collect();\n\n            let type_name = segment.ident;\n            for (i, (impl_param_name, impl_param_span)) in impl_params.iter().enumerate() {\n                if mismatch_param_name(i, impl_param_name, &type_param_names_hashmap) {\n                    let msg = format!(\n                        \"`{type_name}` has a similarly named generic type parameter `{impl_param_name}` in its declaration, but in a different order\"\n                    );\n                    let help = format!(\n                        \"try `{}`, or a name that does not conflict with `{type_name}`'s generic params\",\n                        type_param_names[i]\n                    );\n                    span_lint_and_help(cx, MISMATCHING_TYPE_PARAM_ORDER, *impl_param_span, msg, None, help);\n                }\n            }\n        }\n    }\n}\n\n// Checks if impl_param_name is the same as one of type_param_names,\n// and is in a different position\nfn mismatch_param_name(i: usize, impl_param_name: &String, type_param_names: &FxHashMap<&String, usize>) -> bool {\n    if let Some(j) = type_param_names.get(impl_param_name)\n        && i != *j\n    {\n        return true;\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_assert_message.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_in_test;\nuse clippy_utils::macros::{find_assert_args, find_assert_eq_args, root_macro_call_first_node};\nuse rustc_hir::Expr;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks assertions without a custom panic message.\n    ///\n    /// ### Why restrict this?\n    /// Without a good custom message, it'd be hard to understand what went wrong when the assertion fails.\n    /// A good custom message should be more about why the failure of the assertion is problematic\n    /// and not what is failed because the assertion already conveys that.\n    ///\n    /// Although the same reasoning applies to testing functions, this lint ignores them as they would be too noisy.\n    /// Also, in most cases understanding the test failure would be easier\n    /// compared to understanding a complex invariant distributed around the codebase.\n    ///\n    /// ### Known problems\n    /// This lint cannot check the quality of the custom panic messages.\n    /// Hence, you can suppress this lint simply by adding placeholder messages\n    /// like \"assertion failed\". However, we recommend coming up with good messages\n    /// that provide useful information instead of placeholder messages that\n    /// don't provide any extra information.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct Service { ready: bool }\n    /// fn call(service: Service) {\n    ///     assert!(service.ready);\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # struct Service { ready: bool }\n    /// fn call(service: Service) {\n    ///     assert!(service.ready, \"`service.poll_ready()` must be called first to ensure that service is ready to receive requests\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub MISSING_ASSERT_MESSAGE,\n    restriction,\n    \"checks assertions without a custom panic message\"\n}\n\ndeclare_lint_pass!(MissingAssertMessage => [MISSING_ASSERT_MESSAGE]);\n\nimpl<'tcx> LateLintPass<'tcx> for MissingAssertMessage {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {\n            return;\n        };\n        let single_argument = match cx.tcx.get_diagnostic_name(macro_call.def_id) {\n            Some(sym::assert_macro | sym::debug_assert_macro) => true,\n            Some(\n                sym::assert_eq_macro | sym::assert_ne_macro | sym::debug_assert_eq_macro | sym::debug_assert_ne_macro,\n            ) => false,\n            _ => return,\n        };\n\n        // This lint would be very noisy in tests, so just ignore if we're in test context\n        if is_in_test(cx.tcx, expr.hir_id) {\n            return;\n        }\n\n        let panic_expn = if single_argument {\n            let Some((_, panic_expn)) = find_assert_args(cx, expr, macro_call.expn) else {\n                return;\n            };\n            panic_expn\n        } else {\n            let Some((_, _, panic_expn)) = find_assert_eq_args(cx, expr, macro_call.expn) else {\n                return;\n            };\n            panic_expn\n        };\n\n        if panic_expn.is_default_message() {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                MISSING_ASSERT_MESSAGE,\n                macro_call.span,\n                \"assert without any message\",\n                |diag| {\n                    diag.help(\"consider describing why the failing assert is problematic\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_asserts_for_indexing.rs",
    "content": "use std::mem;\nuse std::ops::ControlFlow;\n\nuse clippy_utils::comparisons::{Rel, normalize_comparison};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::{If, Range};\nuse clippy_utils::macros::{find_assert_eq_args, first_node_macro_backtrace, root_macro_call};\nuse clippy_utils::source::{snippet, snippet_with_applicability};\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{eq_expr_value, hash_expr};\nuse rustc_ast::{BinOpKind, LitKind, RangeLimits};\nuse rustc_data_structures::packed::Pu128;\nuse rustc_data_structures::unhash::UnindexMap;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::{Block, Body, Expr, ExprKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::{Span, Symbol, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for repeated slice indexing without asserting beforehand that the length\n    /// is greater than the largest index used to index into the slice.\n    ///\n    /// ### Why restrict this?\n    /// In the general case where the compiler does not have a lot of information\n    /// about the length of a slice, indexing it repeatedly will generate a bounds check\n    /// for every single index.\n    ///\n    /// Asserting that the length of the slice is at least as large as the largest value\n    /// to index beforehand gives the compiler enough information to elide the bounds checks,\n    /// effectively reducing the number of bounds checks from however many times\n    /// the slice was indexed to just one (the assert).\n    ///\n    /// ### Drawbacks\n    /// False positives. It is, in general, very difficult to predict how well\n    /// the optimizer will be able to elide bounds checks and it very much depends on\n    /// the surrounding code. For example, indexing into the slice yielded by the\n    /// [`slice::chunks_exact`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.chunks_exact)\n    /// iterator will likely have all of the bounds checks elided even without an assert\n    /// if the `chunk_size` is a constant.\n    ///\n    /// Asserts are not tracked across function calls. Asserting the length of a slice\n    /// in a different function likely gives the optimizer enough information\n    /// about the length of a slice, but this lint will not detect that.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn sum(v: &[u8]) -> u8 {\n    ///     // 4 bounds checks\n    ///     v[0] + v[1] + v[2] + v[3]\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn sum(v: &[u8]) -> u8 {\n    ///     assert!(v.len() > 3);\n    ///     // no bounds checks\n    ///     v[0] + v[1] + v[2] + v[3]\n    /// }\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub MISSING_ASSERTS_FOR_INDEXING,\n    restriction,\n    \"indexing into a slice multiple times without an `assert`\"\n}\n\ndeclare_lint_pass!(MissingAssertsForIndexing => [MISSING_ASSERTS_FOR_INDEXING]);\n\nfn report_lint<F>(cx: &LateContext<'_>, index_spans: Vec<Span>, msg: &'static str, f: F)\nwhere\n    F: FnOnce(&mut Diag<'_, ()>),\n{\n    span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, index_spans, msg, |diag| {\n        f(diag);\n        diag.note_once(\"asserting the length before indexing will elide bounds checks\");\n    });\n}\n\n#[derive(Copy, Clone, Debug)]\nenum LengthComparison {\n    /// `v.len() < 5`\n    LengthLessThanInt,\n    /// `5 < v.len()`\n    IntLessThanLength,\n    /// `v.len() <= 5`\n    LengthLessThanOrEqualInt,\n    /// `5 <= v.len()`\n    IntLessThanOrEqualLength,\n    /// `5 == v.len()`\n    /// `v.len() == 5`\n    LengthEqualInt,\n}\n\n/// Extracts parts out of a length comparison expression.\n///\n/// E.g. for `v.len() > 5` this returns `Some((LengthComparison::IntLessThanLength, 5, v.len()))`\nfn len_comparison<'hir>(\n    bin_op: BinOpKind,\n    left: &'hir Expr<'hir>,\n    right: &'hir Expr<'hir>,\n) -> Option<(LengthComparison, usize, &'hir Expr<'hir>)> {\n    macro_rules! int_lit_pat {\n        ($id:ident) => {\n            ExprKind::Lit(Spanned {\n                node: LitKind::Int(Pu128($id), _),\n                ..\n            })\n        };\n    }\n\n    // normalize comparison, `v.len() > 4` becomes `4 < v.len()`\n    // this simplifies the logic a bit\n    let (op, left, right) = normalize_comparison(bin_op, left, right)?;\n    match (op, left.kind, right.kind) {\n        (Rel::Lt, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanLength, left as usize, right)),\n        (Rel::Lt, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanInt, right as usize, left)),\n        (Rel::Le, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanOrEqualLength, left as usize, right)),\n        (Rel::Le, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanOrEqualInt, right as usize, left)),\n        (Rel::Eq, int_lit_pat!(left), _) => Some((LengthComparison::LengthEqualInt, left as usize, right)),\n        (Rel::Eq, _, int_lit_pat!(right)) => Some((LengthComparison::LengthEqualInt, right as usize, left)),\n        _ => None,\n    }\n}\n\n/// Attempts to extract parts out of an `assert!`-like expression\n/// in the form `assert!(some_slice.len() > 5)`.\n///\n/// `assert!` has expanded to an if expression at the HIR, so this\n/// actually works not just with `assert!` specifically, but anything\n/// that has a never type expression in the `then` block (e.g. `panic!`).\nfn assert_len_expr<'hir>(\n    cx: &LateContext<'_>,\n    expr: &'hir Expr<'hir>,\n) -> Option<(LengthComparison, usize, &'hir Expr<'hir>, Symbol)> {\n    let ((cmp, asserted_len, slice_len), macro_call) = if let Some(If { cond, then, .. }) = If::hir(expr)\n        && let ExprKind::Unary(UnOp::Not, condition) = &cond.kind\n        && let ExprKind::Binary(bin_op, left, right) = &condition.kind\n        // check if `then` block has a never type expression\n        && let ExprKind::Block(Block { expr: Some(then_expr), .. }, _) = then.kind\n        && cx.typeck_results().expr_ty(then_expr).is_never()\n    {\n        (len_comparison(bin_op.node, left, right)?, sym::assert_macro)\n    } else if let Some((macro_call, bin_op)) = first_node_macro_backtrace(cx, expr).find_map(|macro_call| {\n        match cx.tcx.get_diagnostic_name(macro_call.def_id) {\n            Some(sym::assert_eq_macro) => Some((macro_call, BinOpKind::Eq)),\n            Some(sym::assert_ne_macro) => Some((macro_call, BinOpKind::Ne)),\n            _ => None,\n        }\n    }) && let Some((left, right, _)) = find_assert_eq_args(cx, expr, macro_call.expn)\n    {\n        (\n            len_comparison(bin_op, left, right)?,\n            root_macro_call(expr.span)\n                .and_then(|macro_call| cx.tcx.get_diagnostic_name(macro_call.def_id))\n                .unwrap_or(sym::assert_macro),\n        )\n    } else {\n        return None;\n    };\n\n    if let ExprKind::MethodCall(method, recv, [], _) = &slice_len.kind\n        && cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice()\n        && method.ident.name == sym::len\n    {\n        Some((cmp, asserted_len, recv, macro_call))\n    } else {\n        None\n    }\n}\n\n#[derive(Debug)]\nenum IndexEntry<'hir> {\n    /// `assert!` without any indexing (so far)\n    StrayAssert {\n        asserted_len: usize,\n        comparison: LengthComparison,\n        assert_span: Span,\n        slice: &'hir Expr<'hir>,\n        macro_call: Symbol,\n    },\n    /// `assert!` with indexing\n    ///\n    /// We also store the highest index to be able to check\n    /// if the `assert!` asserts the right length.\n    AssertWithIndex {\n        highest_index: usize,\n        is_first_highest: bool,\n        asserted_len: usize,\n        assert_span: Span,\n        slice: &'hir Expr<'hir>,\n        indexes: Vec<Span>,\n        comparison: LengthComparison,\n        macro_call: Symbol,\n    },\n    /// Indexing without an `assert!`\n    IndexWithoutAssert {\n        highest_index: usize,\n        is_first_highest: bool,\n        indexes: Vec<Span>,\n        slice: &'hir Expr<'hir>,\n    },\n}\n\nimpl<'hir> IndexEntry<'hir> {\n    pub fn slice(&self) -> &'hir Expr<'hir> {\n        match self {\n            IndexEntry::StrayAssert { slice, .. }\n            | IndexEntry::AssertWithIndex { slice, .. }\n            | IndexEntry::IndexWithoutAssert { slice, .. } => slice,\n        }\n    }\n}\n\n/// Extracts the upper index of a slice indexing expression.\n///\n/// E.g. for `5` this returns `Some(5)`, for `..5` this returns `Some(4)`,\n/// for `..=5` this returns `Some(5)`\nfn upper_index_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<usize> {\n    if let ExprKind::Lit(lit) = &expr.kind\n        && let LitKind::Int(Pu128(index), _) = lit.node\n    {\n        Some(index as usize)\n    } else if let Some(Range {\n        end: Some(end), limits, ..\n    }) = Range::hir(cx, expr)\n        && let ExprKind::Lit(lit) = &end.kind\n        && let LitKind::Int(Pu128(index @ 1..), _) = lit.node\n    {\n        match limits {\n            RangeLimits::HalfOpen => Some(index as usize - 1),\n            RangeLimits::Closed => Some(index as usize),\n        }\n    } else {\n        None\n    }\n}\n\n/// Checks if the expression is an index into a slice and adds it to `indexes`\nfn check_index<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut UnindexMap<u64, Vec<IndexEntry<'hir>>>) {\n    if let ExprKind::Index(slice, index_lit, _) = expr.kind\n        && cx.typeck_results().expr_ty_adjusted(slice).peel_refs().is_slice()\n        && let Some(index) = upper_index_expr(cx, index_lit)\n    {\n        let hash = hash_expr(cx, slice);\n\n        let indexes = map.entry(hash).or_default();\n        let entry = indexes.iter_mut().find(|entry| eq_expr_value(cx, entry.slice(), slice));\n\n        if let Some(entry) = entry {\n            match entry {\n                IndexEntry::StrayAssert {\n                    asserted_len,\n                    comparison,\n                    assert_span,\n                    slice,\n                    macro_call,\n                } => {\n                    if slice.span.lo() > assert_span.lo() {\n                        *entry = IndexEntry::AssertWithIndex {\n                            highest_index: index,\n                            is_first_highest: true,\n                            asserted_len: *asserted_len,\n                            assert_span: *assert_span,\n                            slice,\n                            indexes: vec![expr.span],\n                            comparison: *comparison,\n                            macro_call: *macro_call,\n                        };\n                    }\n                },\n                IndexEntry::IndexWithoutAssert {\n                    highest_index,\n                    indexes,\n                    is_first_highest,\n                    ..\n                }\n                | IndexEntry::AssertWithIndex {\n                    highest_index,\n                    indexes,\n                    is_first_highest,\n                    ..\n                } => {\n                    indexes.push(expr.span);\n                    if *is_first_highest {\n                        (*is_first_highest) = *highest_index >= index;\n                    }\n                    *highest_index = (*highest_index).max(index);\n                },\n            }\n        } else {\n            indexes.push(IndexEntry::IndexWithoutAssert {\n                highest_index: index,\n                is_first_highest: true,\n                indexes: vec![expr.span],\n                slice,\n            });\n        }\n    }\n}\n\n/// Checks if the expression is an `assert!` expression and adds it to `asserts`\nfn check_assert<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>, map: &mut UnindexMap<u64, Vec<IndexEntry<'hir>>>) {\n    if let Some((comparison, asserted_len, slice, macro_call)) = assert_len_expr(cx, expr) {\n        let hash = hash_expr(cx, slice);\n        let indexes = map.entry(hash).or_default();\n\n        let entry = indexes.iter_mut().find(|entry| eq_expr_value(cx, entry.slice(), slice));\n\n        if let Some(entry) = entry {\n            if let IndexEntry::IndexWithoutAssert {\n                highest_index,\n                is_first_highest,\n                indexes,\n                slice,\n            } = entry\n                && expr.span.lo() <= slice.span.lo()\n            {\n                *entry = IndexEntry::AssertWithIndex {\n                    highest_index: *highest_index,\n                    indexes: mem::take(indexes),\n                    is_first_highest: *is_first_highest,\n                    slice,\n                    assert_span: expr.span.source_callsite(),\n                    comparison,\n                    asserted_len,\n                    macro_call,\n                };\n            }\n        } else {\n            indexes.push(IndexEntry::StrayAssert {\n                asserted_len,\n                comparison,\n                assert_span: expr.span.source_callsite(),\n                slice,\n                macro_call,\n            });\n        }\n    }\n}\n\n/// Inspects indexes and reports lints.\n///\n/// Called at the end of this lint after all indexing and `assert!` expressions have been collected.\nfn report_indexes(cx: &LateContext<'_>, map: UnindexMap<u64, Vec<IndexEntry<'_>>>) {\n    for bucket in map.into_values() {\n        for entry in bucket {\n            match entry {\n                IndexEntry::AssertWithIndex {\n                    highest_index,\n                    is_first_highest,\n                    asserted_len,\n                    indexes,\n                    comparison,\n                    assert_span,\n                    slice,\n                    macro_call,\n                } if indexes.len() > 1 && !is_first_highest => {\n                    let mut app = Applicability::MachineApplicable;\n                    let slice_str = snippet_with_applicability(cx, slice.span, \"_\", &mut app);\n                    // if we have found an `assert!`, let's also check that it's actually right\n                    // and if it covers the highest index and if not, suggest the correct length\n                    let sugg = match comparison {\n                        // `v.len() < 5` and `v.len() <= 5` does nothing in terms of bounds checks.\n                        // The user probably meant `v.len() > 5`\n                        LengthComparison::LengthLessThanInt | LengthComparison::LengthLessThanOrEqualInt => {\n                            Some(format!(\"assert!({slice_str}.len() > {highest_index})\"))\n                        },\n                        // `5 < v.len()` == `v.len() > 5`\n                        LengthComparison::IntLessThanLength if asserted_len < highest_index => {\n                            Some(format!(\"assert!({slice_str}.len() > {highest_index})\"))\n                        },\n                        // `5 <= v.len() == `v.len() >= 5`\n                        LengthComparison::IntLessThanOrEqualLength if asserted_len <= highest_index => {\n                            Some(format!(\"assert!({slice_str}.len() > {highest_index})\"))\n                        },\n                        // `highest_index` here is rather a length, so we need to add 1 to it\n                        LengthComparison::LengthEqualInt if asserted_len < highest_index + 1 => match macro_call {\n                            sym::assert_eq_macro => {\n                                Some(format!(\"assert_eq!({slice_str}.len(), {})\", highest_index + 1))\n                            },\n                            sym::debug_assert_eq_macro => {\n                                Some(format!(\"debug_assert_eq!({slice_str}.len(), {})\", highest_index + 1))\n                            },\n                            _ => Some(format!(\"assert!({slice_str}.len() == {})\", highest_index + 1)),\n                        },\n                        _ => None,\n                    };\n\n                    if let Some(sugg) = sugg {\n                        report_lint(\n                            cx,\n                            indexes,\n                            \"indexing into a slice multiple times with an `assert` that does not cover the highest index\",\n                            |diag| {\n                                diag.span_suggestion_verbose(\n                                    assert_span,\n                                    \"provide the highest index that is indexed with\",\n                                    sugg,\n                                    app,\n                                );\n                            },\n                        );\n                    }\n                },\n                IndexEntry::IndexWithoutAssert {\n                    indexes,\n                    highest_index,\n                    is_first_highest,\n                    slice,\n                } if indexes.len() > 1 && !is_first_highest => {\n                    // if there was no `assert!` but more than one index, suggest\n                    // adding an `assert!` that covers the highest index\n                    report_lint(\n                        cx,\n                        indexes,\n                        \"indexing into a slice multiple times without an `assert`\",\n                        |diag| {\n                            diag.help(format!(\n                                \"consider asserting the length before indexing: `assert!({}.len() > {highest_index});`\",\n                                snippet(cx, slice.span, \"..\")\n                            ));\n                        },\n                    );\n                },\n                _ => {},\n            }\n        }\n    }\n}\n\nimpl LateLintPass<'_> for MissingAssertsForIndexing {\n    fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {\n        let mut map = UnindexMap::default();\n\n        for_each_expr_without_closures(body.value, |expr| {\n            check_index(cx, expr, &mut map);\n            check_assert(cx, expr, &mut map);\n            ControlFlow::<!, ()>::Continue(())\n        });\n\n        report_indexes(cx, map);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_const_for_fn.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::qualify_min_const_fn::is_min_const_fn;\nuse clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, is_in_test, trait_ref_of_method};\nuse rustc_abi::ExternAbi;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::CRATE_DEF_ID;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind, OwnerId};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Suggests the use of `const` in functions and methods where possible.\n    ///\n    /// ### Why is this bad?\n    /// Not having the function const prevents callers of the function from being const as well.\n    ///\n    /// ### Known problems\n    /// Const functions are currently still being worked on, with some features only being available\n    /// on nightly. This lint does not consider all edge cases currently and the suggestions may be\n    /// incorrect if you are using this lint on stable.\n    ///\n    /// Also, the lint only runs one pass over the code. Consider these two non-const functions:\n    ///\n    /// ```no_run\n    /// fn a() -> i32 {\n    ///     0\n    /// }\n    /// fn b() -> i32 {\n    ///     a()\n    /// }\n    /// ```\n    ///\n    /// When running Clippy, the lint will only suggest to make `a` const, because `b` at this time\n    /// can't be const as it calls a non-const function. Making `a` const and running Clippy again,\n    /// will suggest to make `b` const, too.\n    ///\n    /// If you are marking a public function with `const`, removing it again will break API compatibility.\n    /// ### Example\n    /// ```no_run\n    /// # struct Foo {\n    /// #     random_number: usize,\n    /// # }\n    /// # impl Foo {\n    /// fn new() -> Self {\n    ///     Self { random_number: 42 }\n    /// }\n    /// # }\n    /// ```\n    ///\n    /// Could be a const fn:\n    ///\n    /// ```no_run\n    /// # struct Foo {\n    /// #     random_number: usize,\n    /// # }\n    /// # impl Foo {\n    /// const fn new() -> Self {\n    ///     Self { random_number: 42 }\n    /// }\n    /// # }\n    /// ```\n    #[clippy::version = \"1.34.0\"]\n    pub MISSING_CONST_FOR_FN,\n    nursery,\n    \"Lint functions definitions that could be made `const fn`\"\n}\n\nimpl_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]);\n\npub struct MissingConstForFn {\n    msrv: Msrv,\n}\n\nimpl MissingConstForFn {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MissingConstForFn {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        _: &FnDecl<'_>,\n        body: &Body<'tcx>,\n        span: Span,\n        def_id: LocalDefId,\n    ) {\n        let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);\n        if is_in_test(cx.tcx, hir_id) {\n            return;\n        }\n\n        if span.in_external_macro(cx.tcx.sess.source_map()) || is_entrypoint_fn(cx, def_id.to_def_id()) {\n            return;\n        }\n\n        // Building MIR for `fn`s with unsatisfiable preds results in ICE.\n        if fn_has_unsatisfiable_preds(cx, def_id.to_def_id()) {\n            return;\n        }\n\n        // Perform some preliminary checks that rule out constness on the Clippy side. This way we\n        // can skip the actual const check and return early.\n        match kind {\n            FnKind::ItemFn(_, generics, header, ..) => {\n                let has_const_generic_params = generics\n                    .params\n                    .iter()\n                    .any(|param| matches!(param.kind, GenericParamKind::Const { .. }));\n\n                if already_const(header)\n                    || has_const_generic_params\n                    || !could_be_const_with_abi(cx, self.msrv, header.abi)\n                {\n                    return;\n                }\n            },\n            FnKind::Method(_, sig, ..) => {\n                if already_const(sig.header) || trait_ref_of_method(cx, OwnerId { def_id }).is_some() {\n                    return;\n                }\n            },\n            FnKind::Closure => return,\n        }\n\n        if fn_inputs_has_impl_trait_ty(cx, def_id) {\n            return;\n        }\n\n        // Const fns are not allowed as methods in a trait.\n        {\n            let parent = cx.tcx.hir_get_parent_item(hir_id).def_id;\n            if parent != CRATE_DEF_ID\n                && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)\n                && let hir::ItemKind::Trait(..) = &item.kind\n            {\n                return;\n            }\n        }\n\n        if !self.msrv.meets(cx, msrvs::CONST_IF_MATCH) {\n            return;\n        }\n\n        if is_from_proc_macro(cx, &(&kind, body, hir_id, span)) {\n            return;\n        }\n\n        let mir = cx.tcx.optimized_mir(def_id);\n\n        if let Ok(()) = is_min_const_fn(cx, mir, self.msrv)\n            && let node = cx.tcx.hir_node_by_def_id(def_id)\n            && let Some((item_span, vis_span_opt)) = match node {\n                hir::Node::Item(item) => Some((item.span, Some(item.vis_span))),\n                hir::Node::ImplItem(impl_item) => Some((impl_item.span, impl_item.vis_span())),\n                _ => None,\n            }\n        {\n            let (sugg_span, suggestion) = if let Some(vis_span) = vis_span_opt\n                && !vis_span.is_empty()\n            {\n                (vis_span.shrink_to_hi(), \" const\")\n            } else {\n                (item_span.shrink_to_lo(), \"const \")\n            };\n            span_lint_and_then(cx, MISSING_CONST_FOR_FN, span, \"this could be a `const fn`\", |diag| {\n                diag.span_suggestion_verbose(\n                    sugg_span,\n                    \"make the function `const`\",\n                    suggestion,\n                    Applicability::MachineApplicable,\n                );\n            });\n        }\n    }\n}\n\n// We don't have to lint on something that's already `const`\n#[must_use]\nfn already_const(header: hir::FnHeader) -> bool {\n    header.constness == Constness::Const\n}\n\nfn could_be_const_with_abi(cx: &LateContext<'_>, msrv: Msrv, abi: ExternAbi) -> bool {\n    match abi {\n        ExternAbi::Rust => true,\n        // `const extern \"C\"` was stabilized after 1.62.0\n        ExternAbi::C { unwind: false } => msrv.meets(cx, msrvs::CONST_EXTERN_C_FN),\n        // Rest ABIs are still unstable and need the `const_extern_fn` feature enabled.\n        _ => msrv.meets(cx, msrvs::CONST_EXTERN_FN),\n    }\n}\n\n/// Return `true` when the given `def_id` is a function that has `impl Trait` ty as one of\n/// its parameter types.\nfn fn_inputs_has_impl_trait_ty(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {\n    let inputs = cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder();\n    inputs.iter().any(|input| {\n        matches!(\n            input.kind(),\n            ty::Alias(ty::AliasTyKind::Free, alias_ty) if cx.tcx.type_of(alias_ty.def_id).skip_binder().is_impl_trait()\n        )\n    })\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_const_for_thread_local.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::macros::macro_backtrace;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::qualify_min_const_fn::is_min_const_fn;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{fn_has_unsatisfiable_preds, peel_blocks, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, intravisit};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Suggests to use `const` in `thread_local!` macro if possible.\n    /// ### Why is this bad?\n    ///\n    /// The `thread_local!` macro wraps static declarations and makes them thread-local.\n    /// It supports using a `const` keyword that may be used for declarations that can\n    /// be evaluated as a constant expression. This can enable a more efficient thread\n    /// local implementation that can avoid lazy initialization. For types that do not\n    /// need to be dropped, this can enable an even more efficient implementation that\n    /// does not need to track any additional state.\n    ///\n    /// https://doc.rust-lang.org/std/macro.thread_local.html\n    ///\n    /// ### Example\n    /// ```no_run\n    /// thread_local! {\n    ///     static BUF: String = String::new();\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// thread_local! {\n    ///     static BUF: String = const { String::new() };\n    /// }\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub MISSING_CONST_FOR_THREAD_LOCAL,\n    perf,\n    \"suggest using `const` in `thread_local!` macro\"\n}\n\nimpl_lint_pass!(MissingConstForThreadLocal => [MISSING_CONST_FOR_THREAD_LOCAL]);\n\npub struct MissingConstForThreadLocal {\n    msrv: Msrv,\n}\n\nimpl MissingConstForThreadLocal {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\n#[inline]\nfn is_thread_local_initializer(\n    cx: &LateContext<'_>,\n    fn_kind: intravisit::FnKind<'_>,\n    span: rustc_span::Span,\n) -> Option<bool> {\n    let macro_def_id = span.source_callee()?.macro_def_id?;\n    Some(\n        cx.tcx.is_diagnostic_item(sym::thread_local_macro, macro_def_id)\n            && matches!(fn_kind, intravisit::FnKind::ItemFn(..)),\n    )\n}\n\nfn is_unreachable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let Some(macro_call) = macro_backtrace(expr.span).next()\n        && let Some(diag_name) = cx.tcx.get_diagnostic_name(macro_call.def_id)\n    {\n        return (matches!(\n            diag_name,\n            sym::core_panic_macro\n                | sym::std_panic_macro\n                | sym::core_panic_2015_macro\n                | sym::std_panic_2015_macro\n                | sym::core_panic_2021_macro\n        ) && !cx.tcx.hir_is_inside_const_context(expr.hir_id))\n            || matches!(\n                diag_name,\n                sym::unimplemented_macro | sym::todo_macro | sym::unreachable_macro | sym::unreachable_2015_macro\n            );\n    }\n    false\n}\n\n#[inline]\nfn initializer_can_be_made_const(cx: &LateContext<'_>, defid: rustc_span::def_id::DefId, msrv: Msrv) -> bool {\n    // Building MIR for `fn`s with unsatisfiable preds results in ICE.\n    if !fn_has_unsatisfiable_preds(cx, defid)\n        && let mir = cx.tcx.optimized_mir(defid)\n        && let Ok(()) = is_min_const_fn(cx, mir, msrv)\n    {\n        return true;\n    }\n    false\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MissingConstForThreadLocal {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        fn_kind: intravisit::FnKind<'tcx>,\n        _: &'tcx rustc_hir::FnDecl<'tcx>,\n        body: &'tcx rustc_hir::Body<'tcx>,\n        span: rustc_span::Span,\n        local_defid: rustc_span::def_id::LocalDefId,\n    ) {\n        let defid = local_defid.to_def_id();\n        if is_thread_local_initializer(cx, fn_kind, span).unwrap_or(false)\n            // Some implementations of `thread_local!` include an initializer fn.\n            // In the case of a const initializer, the init fn is also const,\n            // so we can skip the lint in that case. This occurs only on some\n            // backends due to conditional compilation:\n            // https://doc.rust-lang.org/src/std/sys/common/thread_local/mod.rs.html\n            // for details on this issue, see:\n            // https://github.com/rust-lang/rust-clippy/pull/12276\n            && !cx.tcx.is_const_fn(defid)\n            && let ExprKind::Block(block, _) = body.value.kind\n            && let Some(unpeeled) = block.expr\n            && let ret_expr = peel_blocks(unpeeled)\n            // A common pattern around threadlocal! is to make the value unreachable\n            // to force an initialization before usage\n            // https://github.com/rust-lang/rust-clippy/issues/12637\n            // we ensure that this is reachable before we check in mir\n            && !is_unreachable(cx, ret_expr)\n            && initializer_can_be_made_const(cx, defid, self.msrv)\n            // we know that the function is const-qualifiable, so now\n            // we need only to get the initializer expression to span-lint it.\n            && let initializer_snippet = snippet(cx, ret_expr.span, \"thread_local! { ... }\")\n            && initializer_snippet != \"thread_local! { ... }\"\n            && self.msrv.meets(cx, msrvs::THREAD_LOCAL_CONST_INIT)\n        {\n            span_lint_and_sugg(\n                cx,\n                MISSING_CONST_FOR_THREAD_LOCAL,\n                unpeeled.span,\n                \"initializer for `thread_local` value can be made `const`\",\n                \"replace with\",\n                format!(\"const {{ {initializer_snippet} }}\"),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_doc.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::{is_doc_hidden, is_from_proc_macro};\nuse rustc_hir::attrs::AttributeKind;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::{\n    AttrArgs, Attribute, Body, BodyId, FieldDef, HirId, ImplItem, Item, ItemKind, Node, TraitItem, Variant,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::middle::privacy::Level;\nuse rustc_middle::ty::Visibility;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::def_id::CRATE_DEF_ID;\nuse rustc_span::sym;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns if there is missing documentation for any private documentable item.\n    ///\n    /// ### Why restrict this?\n    /// Doc is good. *rustc* has a `MISSING_DOCS`\n    /// allowed-by-default lint for\n    /// public members, but has no way to enforce documentation of private items.\n    /// This lint fixes that.\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MISSING_DOCS_IN_PRIVATE_ITEMS,\n    restriction,\n    \"detects missing documentation for private members\"\n}\n\nimpl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]);\n\npub struct MissingDoc {\n    /// Whether to **only** check for missing documentation in items visible within the current\n    /// crate. For example, `pub(crate)` items.\n    crate_items_only: bool,\n    /// Whether to allow fields starting with an underscore to skip documentation requirements\n    allow_unused: bool,\n    /// The current number of modules since the crate root.\n    module_depth: u32,\n    macro_module_depth: u32,\n    /// The current level of the attribute stack.\n    attr_depth: u32,\n    /// What `attr_depth` level the first `doc(hidden)` attribute was seen. This is zero if the\n    /// attribute hasn't been seen.\n    doc_hidden_depth: u32,\n    /// What `attr_depth` level the first `automatically_derived` attribute was seen. This is zero\n    /// if the attribute hasn't been seen.\n    automatically_derived_depth: u32,\n    /// The id of the first body we've seen.\n    in_body: Option<BodyId>,\n    /// The module/crate id an item must be visible at to be linted.\n    require_visibility_at: Option<LocalDefId>,\n}\n\nimpl MissingDoc {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            crate_items_only: conf.missing_docs_in_crate_items,\n            allow_unused: conf.missing_docs_allow_unused,\n            module_depth: 0,\n            macro_module_depth: 0,\n            attr_depth: 0,\n            doc_hidden_depth: 0,\n            automatically_derived_depth: 0,\n            in_body: None,\n            require_visibility_at: None,\n        }\n    }\n\n    fn is_missing_docs(&self, cx: &LateContext<'_>, def_id: LocalDefId, hir_id: HirId) -> bool {\n        if cx.tcx.sess.opts.test {\n            return false;\n        }\n\n        match cx.effective_visibilities.effective_vis(def_id) {\n            None if self.require_visibility_at.is_some() => return false,\n            None if self.crate_items_only && self.module_depth != 0 => return false,\n            // `missing_docs` lint uses `Reexported` because rustdoc doesn't render documentation\n            // for items without a reachable path.\n            Some(vis) if vis.is_public_at_level(Level::Reexported) => return false,\n            Some(vis) => {\n                if self.crate_items_only {\n                    // Use the `Reachable` level since rustdoc will be able to render the documentation\n                    // when building private docs.\n                    let vis = vis.at_level(Level::Reachable);\n                    if !(vis.is_public() || matches!(vis, Visibility::Restricted(id) if id.is_top_level_module())) {\n                        return false;\n                    }\n                } else if let Some(id) = self.require_visibility_at\n                    && !vis.at_level(Level::Reexported).is_accessible_from(id, cx.tcx)\n                {\n                    return false;\n                }\n            },\n            None => {},\n        }\n\n        !cx.tcx.hir_attrs(hir_id).iter().any(is_doc_attr)\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MissingDoc {\n    fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {\n        self.attr_depth += 1;\n        if self.doc_hidden_depth == 0 && is_doc_hidden(attrs) {\n            self.doc_hidden_depth = self.attr_depth;\n        }\n    }\n\n    fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [Attribute]) {\n        self.attr_depth -= 1;\n        if self.attr_depth < self.doc_hidden_depth {\n            self.doc_hidden_depth = 0;\n        }\n        if self.attr_depth < self.automatically_derived_depth {\n            self.automatically_derived_depth = 0;\n        }\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if self.doc_hidden_depth != 0 || self.automatically_derived_depth != 0 || self.in_body.is_some() {\n            return;\n        }\n\n        let span = match item.kind {\n            // ignore main()\n            ItemKind::Fn { ident, .. }\n                if ident.name == sym::main && cx.tcx.local_parent(item.owner_id.def_id) == CRATE_DEF_ID =>\n            {\n                return;\n            },\n            ItemKind::Const(ident, ..) if ident.name == kw::Underscore => return,\n            ItemKind::Impl { .. } => {\n                if cx.tcx.is_automatically_derived(item.owner_id.def_id.to_def_id()) {\n                    self.automatically_derived_depth = self.attr_depth;\n                }\n                return;\n            },\n            ItemKind::ExternCrate(..)\n            | ItemKind::ForeignMod { .. }\n            | ItemKind::GlobalAsm { .. }\n            | ItemKind::Use(..) => return,\n\n            ItemKind::Mod(ident, ..) => {\n                if item.span.from_expansion() && item.span.eq_ctxt(ident.span) {\n                    self.module_depth += 1;\n                    self.require_visibility_at = cx.tcx.opt_local_parent(item.owner_id.def_id);\n                    self.macro_module_depth = self.module_depth;\n                    return;\n                }\n                ident.span\n            },\n\n            ItemKind::Const(ident, ..)\n            | ItemKind::Enum(ident, ..)\n            | ItemKind::Fn { ident, .. }\n            | ItemKind::Macro(ident, ..)\n            | ItemKind::Static(_, ident, ..)\n            | ItemKind::Struct(ident, ..)\n            | ItemKind::Trait(_, _, _, ident, ..)\n            | ItemKind::TraitAlias(_, ident, ..)\n            | ItemKind::TyAlias(ident, ..)\n            | ItemKind::Union(ident, ..) => ident.span,\n        };\n\n        if !item.span.from_expansion()\n            && self.is_missing_docs(cx, item.owner_id.def_id, item.hir_id())\n            && !is_from_proc_macro(cx, item)\n        {\n            let (article, desc) = cx.tcx.article_and_description(item.owner_id.to_def_id());\n            span_lint(\n                cx,\n                MISSING_DOCS_IN_PRIVATE_ITEMS,\n                span,\n                format!(\"missing documentation for {article} {desc}\"),\n            );\n        }\n        if matches!(item.kind, ItemKind::Mod(..)) {\n            self.module_depth += 1;\n        }\n    }\n\n    fn check_item_post(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if matches!(item.kind, ItemKind::Mod(..))\n            && self.doc_hidden_depth == 0\n            && self.automatically_derived_depth == 0\n            && self.in_body.is_none()\n        {\n            self.module_depth -= 1;\n            if self.module_depth < self.macro_module_depth {\n                self.require_visibility_at = None;\n            }\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {\n        if self.doc_hidden_depth == 0\n            && self.automatically_derived_depth == 0\n            && self.in_body.is_none()\n            && !item.span.from_expansion()\n            && self.is_missing_docs(cx, item.owner_id.def_id, item.hir_id())\n            && !is_from_proc_macro(cx, item)\n        {\n            let (article, desc) = cx.tcx.article_and_description(item.owner_id.to_def_id());\n            span_lint(\n                cx,\n                MISSING_DOCS_IN_PRIVATE_ITEMS,\n                item.ident.span,\n                format!(\"missing documentation for {article} {desc}\"),\n            );\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {\n        if self.doc_hidden_depth == 0\n            && self.automatically_derived_depth == 0\n            && self.in_body.is_none()\n            && let Node::Item(parent) = cx.tcx.parent_hir_node(item.hir_id())\n            && let ItemKind::Impl(impl_) = parent.kind\n            && impl_.of_trait.is_none()\n            && !item.span.from_expansion()\n            && self.is_missing_docs(cx, item.owner_id.def_id, item.hir_id())\n            && !is_from_proc_macro(cx, item)\n        {\n            let (article, desc) = cx.tcx.article_and_description(item.owner_id.to_def_id());\n            span_lint(\n                cx,\n                MISSING_DOCS_IN_PRIVATE_ITEMS,\n                item.ident.span,\n                format!(\"missing documentation for {article} {desc}\"),\n            );\n        }\n    }\n\n    fn check_body(&mut self, _: &LateContext<'tcx>, body: &Body<'tcx>) {\n        if self.doc_hidden_depth == 0 && self.automatically_derived_depth == 0 && self.in_body.is_none() {\n            self.in_body = Some(body.id());\n        }\n    }\n\n    fn check_body_post(&mut self, _: &LateContext<'tcx>, body: &Body<'tcx>) {\n        if self.in_body == Some(body.id()) {\n            self.in_body = None;\n        }\n    }\n\n    fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &'tcx FieldDef<'_>) {\n        if self.doc_hidden_depth == 0\n            && self.automatically_derived_depth == 0\n            && self.in_body.is_none()\n            && !field.is_positional()\n            && !field.span.from_expansion()\n            && !(self.allow_unused && field.ident.name.as_str().starts_with('_'))\n            && self.is_missing_docs(cx, field.def_id, field.hir_id)\n            && !is_from_proc_macro(cx, field)\n        {\n            span_lint(\n                cx,\n                MISSING_DOCS_IN_PRIVATE_ITEMS,\n                field.ident.span,\n                \"missing documentation for a field\",\n            );\n        }\n    }\n\n    fn check_variant(&mut self, cx: &LateContext<'tcx>, variant: &'tcx Variant<'_>) {\n        if self.doc_hidden_depth == 0\n            && self.automatically_derived_depth == 0\n            && self.in_body.is_none()\n            && !variant.span.from_expansion()\n            && self.is_missing_docs(cx, variant.def_id, variant.hir_id)\n            && !is_from_proc_macro(cx, variant)\n        {\n            span_lint(\n                cx,\n                MISSING_DOCS_IN_PRIVATE_ITEMS,\n                variant.ident.span,\n                \"missing documentation for a variant\",\n            );\n        }\n    }\n}\n\nfn is_doc_attr(attr: &Attribute) -> bool {\n    match attr {\n        Attribute::Parsed(AttributeKind::DocComment { .. }) => true,\n        Attribute::Unparsed(attr)\n            if let [name] = &*attr.path.segments\n                && *name == sym::doc =>\n        {\n            matches!(attr.args, AttrArgs::Eq { .. })\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_enforced_import_rename.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::paths::{PathNS, lookup_path_str};\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::def_id::DefIdMap;\nuse rustc_hir::{Item, ItemKind, UseKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for imports that do not rename the item as specified\n    /// in the `enforced-import-renames` config option.\n    ///\n    /// Note: Even though this lint is warn-by-default, it will only trigger if\n    /// import renames are defined in the `clippy.toml` file.\n    ///\n    /// ### Why is this bad?\n    /// Consistency is important; if a project has defined import renames, then they should be\n    /// followed. More practically, some item names are too vague outside of their defining scope,\n    /// in which case this can enforce a more meaningful naming.\n    ///\n    /// ### Example\n    /// An example clippy.toml configuration:\n    /// ```toml\n    /// # clippy.toml\n    /// enforced-import-renames = [\n    ///     { path = \"serde_json::Value\", rename = \"JsonValue\" },\n    /// ]\n    /// ```\n    ///\n    /// ```rust,ignore\n    /// use serde_json::Value;\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// use serde_json::Value as JsonValue;\n    /// ```\n    #[clippy::version = \"1.55.0\"]\n    pub MISSING_ENFORCED_IMPORT_RENAMES,\n    style,\n    \"enforce import renames\"\n}\n\nimpl_lint_pass!(ImportRename => [MISSING_ENFORCED_IMPORT_RENAMES]);\n\npub struct ImportRename {\n    renames: DefIdMap<Symbol>,\n}\n\nimpl ImportRename {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        Self {\n            renames: conf\n                .enforced_import_renames\n                .iter()\n                .map(|x| (&x.path, Symbol::intern(&x.rename)))\n                .flat_map(|(path, rename)| {\n                    lookup_path_str(tcx, PathNS::Arbitrary, path)\n                        .into_iter()\n                        .map(move |id| (id, rename))\n                })\n                .collect(),\n        }\n    }\n}\n\nimpl LateLintPass<'_> for ImportRename {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        if let ItemKind::Use(path, UseKind::Single(_)) = &item.kind {\n            // use `present_items` because it could be in any of type_ns, value_ns, macro_ns\n            for res in path.res.present_items() {\n                if let Res::Def(_, id) = res\n                    && let Some(name) = self.renames.get(&id)\n                    // Remove semicolon since it is not present for nested imports\n                    && let span_without_semi = cx.sess().source_map().span_until_char(item.span, ';')\n                    && let Some(snip) = span_without_semi.get_source_text(cx)\n                    && let Some(import) = match snip.split_once(\" as \") {\n                        None => Some(snip.as_str()),\n                        Some((import, rename)) => {\n                            let trimmed_rename = rename.trim();\n                            if trimmed_rename == \"_\" || trimmed_rename == name.as_str() {\n                                None\n                            } else {\n                                Some(import.trim())\n                            }\n                        },\n                    }\n                {\n                    span_lint_and_sugg(\n                        cx,\n                        MISSING_ENFORCED_IMPORT_RENAMES,\n                        span_without_semi,\n                        \"this import should be renamed\",\n                        \"try\",\n                        format!(\"{import} as {name}\"),\n                        Applicability::MachineApplicable,\n                    );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_fields_in_debug.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::sym;\nuse clippy_utils::visitors::{Visitable, for_each_expr};\nuse rustc_ast::LitKind;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Block, Expr, ExprKind, Impl, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{Ty, TypeckResults};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual [`core::fmt::Debug`](https://doc.rust-lang.org/core/fmt/trait.Debug.html) implementations that do not use all fields.\n    ///\n    /// ### Why is this bad?\n    /// A common mistake is to forget to update manual `Debug` implementations when adding a new field\n    /// to a struct or a new variant to an enum.\n    ///\n    /// At the same time, it also acts as a style lint to suggest using [`core::fmt::DebugStruct::finish_non_exhaustive`](https://doc.rust-lang.org/core/fmt/struct.DebugStruct.html#method.finish_non_exhaustive)\n    /// for the times when the user intentionally wants to leave out certain fields (e.g. to hide implementation details).\n    ///\n    /// ### Known problems\n    /// This lint works based on the `DebugStruct` helper types provided by the `Formatter`,\n    /// so this won't detect `Debug` impls that use the `write!` macro.\n    /// Oftentimes there is more logic to a `Debug` impl if it uses `write!` macro, so it tries\n    /// to be on the conservative side and not lint in those cases in an attempt to prevent false positives.\n    ///\n    /// This lint also does not look through function calls, so calling a function does not consider fields\n    /// used inside of that function as used by the `Debug` impl.\n    ///\n    /// Lastly, it also ignores tuple structs as their `DebugTuple` formatter does not have a `finish_non_exhaustive`\n    /// method, as well as enums because their exhaustiveness is already checked by the compiler when matching on the enum,\n    /// making it much less likely to accidentally forget to update the `Debug` impl when adding a new variant.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::fmt;\n    /// struct Foo {\n    ///     data: String,\n    ///     // implementation detail\n    ///     hidden_data: i32\n    /// }\n    /// impl fmt::Debug for Foo {\n    ///     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n    ///         formatter\n    ///             .debug_struct(\"Foo\")\n    ///             .field(\"data\", &self.data)\n    ///             .finish()\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::fmt;\n    /// struct Foo {\n    ///     data: String,\n    ///     // implementation detail\n    ///     hidden_data: i32\n    /// }\n    /// impl fmt::Debug for Foo {\n    ///     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n    ///         formatter\n    ///             .debug_struct(\"Foo\")\n    ///             .field(\"data\", &self.data)\n    ///             .finish_non_exhaustive()\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub MISSING_FIELDS_IN_DEBUG,\n    pedantic,\n    \"missing fields in manual `Debug` implementation\"\n}\n\ndeclare_lint_pass!(MissingFieldsInDebug => [MISSING_FIELDS_IN_DEBUG]);\n\nfn report_lints(cx: &LateContext<'_>, span: Span, span_notes: Vec<(Span, &'static str)>) {\n    span_lint_and_then(\n        cx,\n        MISSING_FIELDS_IN_DEBUG,\n        span,\n        \"manual `Debug` impl does not include all fields\",\n        |diag| {\n            for (span, note) in span_notes {\n                diag.span_note(span, note);\n            }\n            diag.help(\"consider including all fields in this `Debug` impl\")\n                .help(\"consider calling `.finish_non_exhaustive()` if you intend to ignore fields\");\n        },\n    );\n}\n\n/// Checks if we should lint in a block of code\n///\n/// The way we check for this condition is by checking if there is\n/// a call to `Formatter::debug_struct` but no call to `.finish_non_exhaustive()`.\nfn should_lint<'tcx>(\n    cx: &LateContext<'tcx>,\n    typeck_results: &TypeckResults<'tcx>,\n    block: impl Visitable<'tcx>,\n) -> bool {\n    // Is there a call to `DebugStruct::finish_non_exhaustive`? Don't lint if there is.\n    let mut has_finish_non_exhaustive = false;\n    // Is there a call to `DebugStruct::debug_struct`? Do lint if there is.\n    let mut has_debug_struct = false;\n\n    for_each_expr(cx, block, |expr| {\n        if let ExprKind::MethodCall(path, recv, ..) = &expr.kind {\n            let recv_ty = typeck_results.expr_ty(recv).peel_refs();\n\n            match (path.ident.name, recv_ty.opt_diag_name(cx)) {\n                (sym::debug_struct, Some(sym::Formatter)) => {\n                    has_debug_struct = true;\n                },\n                (sym::finish_non_exhaustive, Some(sym::DebugStruct)) => {\n                    has_finish_non_exhaustive = true;\n                },\n                _ => {},\n            }\n        }\n        ControlFlow::<!, _>::Continue(())\n    });\n\n    !has_finish_non_exhaustive && has_debug_struct\n}\n\n/// Checks if the given expression is a call to `DebugStruct::field`\n/// and the first argument to it is a string literal and if so, returns it\n///\n/// Example: `.field(\"foo\", ....)` returns `Some(\"foo\")`\nfn as_field_call<'tcx>(\n    cx: &LateContext<'tcx>,\n    typeck_results: &TypeckResults<'tcx>,\n    expr: &Expr<'_>,\n) -> Option<Symbol> {\n    if let ExprKind::MethodCall(path, recv, [debug_field, _], _) = &expr.kind\n        && let recv_ty = typeck_results.expr_ty(recv).peel_refs()\n        && recv_ty.is_diag_item(cx, sym::DebugStruct)\n        && path.ident.name == sym::field\n        && let ExprKind::Lit(lit) = &debug_field.kind\n        && let LitKind::Str(sym, ..) = lit.node\n    {\n        Some(sym)\n    } else {\n        None\n    }\n}\n\n/// Attempts to find unused fields assuming that the item is a struct\nfn check_struct<'tcx>(\n    cx: &LateContext<'tcx>,\n    typeck_results: &TypeckResults<'tcx>,\n    block: &'tcx Block<'tcx>,\n    self_ty: Ty<'tcx>,\n    item: &'tcx Item<'tcx>,\n    data: &VariantData<'_>,\n) {\n    // Is there a \"direct\" field access anywhere (i.e. self.foo)?\n    // We don't want to lint if there is not, because the user might have\n    // a newtype struct and use fields from the wrapped type only.\n    let mut has_direct_field_access = false;\n    let mut field_accesses = FxHashSet::default();\n\n    for_each_expr(cx, block, |expr| {\n        if let ExprKind::Field(target, ident) = expr.kind\n            && let target_ty = typeck_results.expr_ty_adjusted(target).peel_refs()\n            && target_ty == self_ty\n        {\n            field_accesses.insert(ident.name);\n            has_direct_field_access = true;\n        } else if let Some(sym) = as_field_call(cx, typeck_results, expr) {\n            field_accesses.insert(sym);\n        }\n        ControlFlow::<!, _>::Continue(())\n    });\n\n    let span_notes = data\n        .fields()\n        .iter()\n        .filter_map(|field| {\n            if field_accesses.contains(&field.ident.name)\n                || field.ty.basic_res().is_lang_item(cx, LangItem::PhantomData)\n            {\n                None\n            } else {\n                Some((field.span, \"this field is unused\"))\n            }\n        })\n        .collect::<Vec<_>>();\n\n    // only lint if there's also at least one direct field access to allow patterns\n    // where one might have a newtype struct and uses fields from the wrapped type\n    if !span_notes.is_empty() && has_direct_field_access {\n        report_lints(cx, item.span, span_notes);\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        // is this an `impl Debug for X` block?\n        if let ItemKind::Impl(Impl { of_trait: Some(of_trait), self_ty, .. }) = item.kind\n            && let Res::Def(DefKind::Trait, trait_def_id) = of_trait.trait_ref.path.res\n            && let TyKind::Path(QPath::Resolved(_, self_path)) = &self_ty.kind\n            // make sure that the self type is either a struct, an enum or a union\n            // this prevents ICEs such as when self is a type parameter or a primitive type\n            // (see #10887, #11063)\n            && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, self_path_did) = self_path.res\n            && cx.tcx.is_diagnostic_item(sym::Debug, trait_def_id)\n            // don't trigger if this impl was derived\n            && !cx.tcx.is_automatically_derived(item.owner_id.to_def_id())\n            && !item.span.from_expansion()\n            // find `Debug::fmt` function\n            && let Some(fmt_item) = cx.tcx.associated_items(item.owner_id).filter_by_name_unhygienic(sym::fmt).next()\n            && let body = cx.tcx.hir_body_owned_by(fmt_item.def_id.expect_local())\n            && let ExprKind::Block(block, _) = body.value.kind\n            // inspect `self`\n            && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs()\n            && let Some(self_adt) = self_ty.ty_adt_def()\n            && let Some(self_def_id) = self_adt.did().as_local()\n            && let Node::Item(self_item) = cx.tcx.hir_node_by_def_id(self_def_id)\n            // NB: can't call cx.typeck_results() as we are not in a body\n            && let typeck_results = cx.tcx.typeck_body(body.id())\n            && should_lint(cx, typeck_results, block)\n            // we intentionally only lint structs, see lint description\n            && let ItemKind::Struct(_, _, data) = &self_item.kind\n        {\n            check_struct(cx, typeck_results, block, self_ty, item, data);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_inline.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_hir};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{self as hir, Attribute, find_attr};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::AssocContainer;\nuse rustc_session::config::CrateType;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// It lints if an exported function, method, trait method with default impl,\n    /// or trait method impl is not `#[inline]`.\n    ///\n    /// ### Why restrict this?\n    /// When a function is not marked `#[inline]`, it is not\n    /// [a “small” candidate for automatic inlining][small], and LTO is not in use, then it is not\n    /// possible for the function to be inlined into the code of any crate other than the one in\n    /// which it is defined.  Depending on the role of the function and the relationship of the crates,\n    /// this could significantly reduce performance.\n    ///\n    /// Certain types of crates might intend for most of the methods in their public API to be able\n    /// to be inlined across crates even when LTO is disabled.\n    /// This lint allows those crates to require all exported methods to be `#[inline]` by default, and\n    /// then opt out for specific methods where this might not make sense.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub fn foo() {} // missing #[inline]\n    /// fn ok() {} // ok\n    /// #[inline] pub fn bar() {} // ok\n    /// #[inline(always)] pub fn baz() {} // ok\n    ///\n    /// pub trait Bar {\n    ///   fn bar(); // ok\n    ///   fn def_bar() {} // missing #[inline]\n    /// }\n    ///\n    /// struct Baz;\n    /// impl Baz {\n    ///     fn private() {} // ok\n    /// }\n    ///\n    /// impl Bar for Baz {\n    ///   fn bar() {} // ok - Baz is not exported\n    /// }\n    ///\n    /// pub struct PubBaz;\n    /// impl PubBaz {\n    ///     fn private() {} // ok\n    ///     pub fn not_private() {} // missing #[inline]\n    /// }\n    ///\n    /// impl Bar for PubBaz {\n    ///     fn bar() {} // missing #[inline]\n    ///     fn def_bar() {} // missing #[inline]\n    /// }\n    /// ```\n    ///\n    /// [small]: https://github.com/rust-lang/rust/pull/116505\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MISSING_INLINE_IN_PUBLIC_ITEMS,\n    restriction,\n    \"detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)\"\n}\n\ndeclare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);\n\nfn check_missing_inline_attrs(\n    cx: &LateContext<'_>,\n    attrs: &[Attribute],\n    sp: Span,\n    desc: &'static str,\n    hir_id: Option<hir::HirId>,\n) {\n    if !find_attr!(attrs, Inline(..)) {\n        let msg = format!(\"missing `#[inline]` for {desc}\");\n        if let Some(hir_id) = hir_id {\n            span_lint_hir(cx, MISSING_INLINE_IN_PUBLIC_ITEMS, hir_id, sp, msg);\n        } else {\n            span_lint(cx, MISSING_INLINE_IN_PUBLIC_ITEMS, sp, msg);\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MissingInline {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {\n        if it.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if cx\n            .tcx\n            .crate_types()\n            .iter()\n            .any(|t: &CrateType| matches!(t, CrateType::ProcMacro))\n        {\n            return;\n        }\n\n        if !cx.effective_visibilities.is_exported(it.owner_id.def_id) {\n            return;\n        }\n        match it.kind {\n            hir::ItemKind::Fn { .. } => {\n                if fn_is_externally_exported(cx, it.owner_id.to_def_id()) {\n                    return;\n                }\n\n                let desc = \"a function\";\n                let attrs = cx.tcx.hir_attrs(it.hir_id());\n                check_missing_inline_attrs(cx, attrs, it.span, desc, None);\n            },\n            hir::ItemKind::Trait(.., trait_items) => {\n                // note: we need to check if the trait is exported so we can't use\n                // `LateLintPass::check_trait_item` here.\n                for &tit in trait_items {\n                    let tit_ = cx.tcx.hir_trait_item(tit);\n                    match tit_.kind {\n                        hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},\n                        hir::TraitItemKind::Fn(..) => {\n                            if cx.tcx.defaultness(tit.owner_id).has_value() {\n                                // trait method with default body needs inline in case\n                                // an impl is not provided\n                                let desc = \"a default trait method\";\n                                let item = cx.tcx.hir_trait_item(tit);\n                                let attrs = cx.tcx.hir_attrs(item.hir_id());\n                                check_missing_inline_attrs(cx, attrs, item.span, desc, Some(tit.hir_id()));\n                            }\n                        },\n                    }\n                }\n            },\n            hir::ItemKind::Const(..)\n            | hir::ItemKind::Enum(..)\n            | hir::ItemKind::Macro(..)\n            | hir::ItemKind::Mod(..)\n            | hir::ItemKind::Static(..)\n            | hir::ItemKind::Struct(..)\n            | hir::ItemKind::TraitAlias(..)\n            | hir::ItemKind::GlobalAsm { .. }\n            | hir::ItemKind::TyAlias(..)\n            | hir::ItemKind::Union(..)\n            | hir::ItemKind::ExternCrate(..)\n            | hir::ItemKind::ForeignMod { .. }\n            | hir::ItemKind::Impl { .. }\n            | hir::ItemKind::Use(..) => {},\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {\n        if impl_item.span.in_external_macro(cx.sess().source_map())\n            || cx\n                .tcx\n                .crate_types()\n                .iter()\n                .any(|t: &CrateType| matches!(t, CrateType::ProcMacro))\n        {\n            return;\n        }\n\n        // If the item being implemented is not exported, then we don't need #[inline]\n        if !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) {\n            return;\n        }\n\n        let desc = match impl_item.kind {\n            hir::ImplItemKind::Fn(..) => \"a method\",\n            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(_) => return,\n        };\n\n        let assoc_item = cx.tcx.associated_item(impl_item.owner_id);\n        let container_id = assoc_item.container_id(cx.tcx);\n        let trait_def_id = match assoc_item.container {\n            AssocContainer::Trait => Some(container_id),\n            AssocContainer::TraitImpl(_) => Some(cx.tcx.impl_trait_id(container_id)),\n            AssocContainer::InherentImpl => None,\n        };\n\n        if let Some(trait_def_id) = trait_def_id\n            && trait_def_id.is_local()\n            && !cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)\n        {\n            // If a trait is being implemented for an item, and the\n            // trait is not exported, we don't need #[inline]\n            return;\n        }\n\n        let attrs = cx.tcx.hir_attrs(impl_item.hir_id());\n        check_missing_inline_attrs(cx, attrs, impl_item.span, desc, None);\n    }\n}\n\n/// Checks if this function is externally exported, where #[inline] wouldn't have the desired effect\n/// and a rustc warning would be triggered, see #15301\nfn fn_is_externally_exported(cx: &LateContext<'_>, def_id: DefId) -> bool {\n    let attrs = cx.tcx.codegen_fn_attrs(def_id);\n    attrs.contains_extern_indicator()\n}\n"
  },
  {
    "path": "clippy_lints/src/missing_trait_methods.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_lint_allowed;\nuse clippy_utils::macros::span_is_local;\nuse clippy_utils::source::snippet_opt;\nuse rustc_hir::def_id::DefIdSet;\nuse rustc_hir::{Impl, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if a provided method is used implicitly by a trait\n    /// implementation.\n    ///\n    /// ### Why restrict this?\n    /// To ensure that a certain implementation implements every method; for example,\n    /// a wrapper type where every method should delegate to the corresponding method of\n    /// the inner type's implementation.\n    ///\n    /// This lint should typically be enabled on a specific trait `impl` item\n    /// rather than globally.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// trait Trait {\n    ///     fn required();\n    ///\n    ///     fn provided() {}\n    /// }\n    ///\n    /// # struct Type;\n    /// #[warn(clippy::missing_trait_methods)]\n    /// impl Trait for Type {\n    ///     fn required() { /* ... */ }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// trait Trait {\n    ///     fn required();\n    ///\n    ///     fn provided() {}\n    /// }\n    ///\n    /// # struct Type;\n    /// #[warn(clippy::missing_trait_methods)]\n    /// impl Trait for Type {\n    ///     fn required() { /* ... */ }\n    ///\n    ///     fn provided() { /* ... */ }\n    /// }\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub MISSING_TRAIT_METHODS,\n    restriction,\n    \"trait implementation uses default provided method\"\n}\n\ndeclare_lint_pass!(MissingTraitMethods => [MISSING_TRAIT_METHODS]);\n\nimpl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if !is_lint_allowed(cx, MISSING_TRAIT_METHODS, item.hir_id())\n            && span_is_local(item.span)\n            && let ItemKind::Impl(Impl {\n                of_trait: Some(of_trait),\n                ..\n            }) = item.kind\n            && let Some(trait_id) = of_trait.trait_ref.trait_def_id()\n        {\n            let trait_item_ids: DefIdSet = cx\n                .tcx\n                .associated_items(item.owner_id)\n                .in_definition_order()\n                .filter_map(|assoc_item| assoc_item.expect_trait_impl().ok())\n                .collect();\n\n            for assoc in cx\n                .tcx\n                .provided_trait_methods(trait_id)\n                .filter(|assoc| !trait_item_ids.contains(&assoc.def_id))\n            {\n                span_lint_and_then(\n                    cx,\n                    MISSING_TRAIT_METHODS,\n                    cx.tcx.def_span(item.owner_id),\n                    format!(\"missing trait method provided by default: `{}`\", assoc.name()),\n                    |diag| {\n                        if assoc.def_id.is_local() {\n                            diag.span_help(cx.tcx.def_span(assoc.def_id), \"implement the method\");\n                        } else if let Some(snippet) = snippet_opt(cx, of_trait.trait_ref.path.span) {\n                            diag.help(format!(\n                                \"implement the missing `{}` method of the `{snippet}` trait\",\n                                assoc.name(),\n                            ));\n                        }\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/mixed_read_write_in_expression.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::macros::root_macro_call_first_node;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::{get_parent_expr, sym};\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, LetStmt, Node, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for diverging calls that are not match arms or\n    /// statements.\n    ///\n    /// ### Why is this bad?\n    /// It is often confusing to read. In addition, the\n    /// sub-expression evaluation order for Rust is not well documented.\n    ///\n    /// ### Known problems\n    /// Someone might want to use `some_bool || panic!()` as a\n    /// shorthand.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// # fn b() -> bool { true }\n    /// # fn c() -> bool { true }\n    /// let a = b() || panic!() || c();\n    /// // `c()` is dead, `panic!()` is only called if `b()` returns `false`\n    /// let x = (a, b, c, panic!());\n    /// // can simply be replaced by `panic!()`\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DIVERGING_SUB_EXPRESSION,\n    complexity,\n    \"whether an expression contains a diverging sub expression\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for a read and a write to the same variable where\n    /// whether the read occurs before or after the write depends on the evaluation\n    /// order of sub-expressions.\n    ///\n    /// ### Why restrict this?\n    /// While [the evaluation order of sub-expressions] is fully specified in Rust,\n    /// it still may be confusing to read an expression where the evaluation order\n    /// affects its behavior.\n    ///\n    /// ### Known problems\n    /// Code which intentionally depends on the evaluation\n    /// order, or which is correct for any evaluation order.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut x = 0;\n    ///\n    /// let a = {\n    ///     x = 1;\n    ///     1\n    /// } + x;\n    /// // Unclear whether a is 1 or 2.\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let mut x = 0;\n    /// let tmp = {\n    ///     x = 1;\n    ///     1\n    /// };\n    /// let a = tmp + x;\n    /// ```\n    ///\n    /// [order]: (https://doc.rust-lang.org/reference/expressions.html?highlight=subexpression#evaluation-order-of-operands)\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MIXED_READ_WRITE_IN_EXPRESSION,\n    restriction,\n    \"whether a variable read occurs before a write depends on sub-expression evaluation order\"\n}\n\ndeclare_lint_pass!(EvalOrderDependence => [\n    DIVERGING_SUB_EXPRESSION,\n    MIXED_READ_WRITE_IN_EXPRESSION,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for EvalOrderDependence {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        // Find a write to a local variable.\n        let var = if let ExprKind::Assign(lhs, ..) | ExprKind::AssignOp(_, lhs, _) = expr.kind\n            && let Some(var) = lhs.res_local_id()\n            && expr.span.desugaring_kind().is_none()\n        {\n            var\n        } else {\n            return;\n        };\n        let mut visitor = ReadVisitor {\n            cx,\n            var,\n            write_expr: expr,\n            last_expr: expr,\n        };\n        check_for_unsequenced_reads(&mut visitor);\n    }\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        match stmt.kind {\n            StmtKind::Let(local) => {\n                if let LetStmt { init: Some(e), .. } = local {\n                    DivergenceVisitor { cx }.visit_expr(e);\n                }\n            },\n            StmtKind::Expr(e) | StmtKind::Semi(e) => DivergenceVisitor { cx }.maybe_walk_expr(e),\n            StmtKind::Item(..) => {},\n        }\n    }\n}\n\nstruct DivergenceVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n}\n\nimpl<'tcx> DivergenceVisitor<'_, 'tcx> {\n    fn maybe_walk_expr(&mut self, e: &'tcx Expr<'_>) {\n        match e.kind {\n            ExprKind::Closure(..) | ExprKind::If(..) | ExprKind::Loop(..) => {},\n            ExprKind::Match(e, arms, _) => {\n                self.visit_expr(e);\n                for arm in arms {\n                    if let Some(if_expr) = arm.guard {\n                        self.visit_expr(if_expr);\n                    }\n                    // make sure top level arm expressions aren't linted\n                    self.maybe_walk_expr(arm.body);\n                }\n            },\n            _ => walk_expr(self, e),\n        }\n    }\n\n    fn report_diverging_sub_expr(&self, e: &Expr<'_>) {\n        if let Some(macro_call) = root_macro_call_first_node(self.cx, e)\n            && self.cx.tcx.is_diagnostic_item(sym::todo_macro, macro_call.def_id)\n        {\n            return;\n        }\n        span_lint(self.cx, DIVERGING_SUB_EXPRESSION, e.span, \"sub-expression diverges\");\n    }\n}\n\nfn stmt_might_diverge(stmt: &Stmt<'_>) -> bool {\n    !matches!(stmt.kind, StmtKind::Item(..))\n}\n\nimpl<'tcx> Visitor<'tcx> for DivergenceVisitor<'_, 'tcx> {\n    fn visit_expr(&mut self, e: &'tcx Expr<'_>) {\n        match e.kind {\n            // fix #10776\n            ExprKind::Block(block, ..) => match (block.stmts, block.expr) {\n                (stmts, Some(e)) if stmts.iter().all(|stmt| !stmt_might_diverge(stmt)) => {\n                    self.visit_expr(e);\n                },\n                ([first @ .., stmt], None)\n                    if first.iter().all(|stmt| !stmt_might_diverge(stmt))\n                        && let StmtKind::Expr(e) | StmtKind::Semi(e) = stmt.kind =>\n                {\n                    self.visit_expr(e);\n                },\n                _ => {},\n            },\n            ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => self.report_diverging_sub_expr(e),\n            ExprKind::Call(func, _) => {\n                let typ = self.cx.typeck_results().expr_ty(func);\n                if typ.is_fn() {\n                    let sig = typ.fn_sig(self.cx.tcx);\n                    if self.cx.tcx.instantiate_bound_regions_with_erased(sig).output().kind() == &ty::Never {\n                        self.report_diverging_sub_expr(e);\n                    }\n                }\n            },\n            ExprKind::MethodCall(..) => {\n                let borrowed_table = self.cx.typeck_results();\n                if borrowed_table.expr_ty(e).is_never() {\n                    self.report_diverging_sub_expr(e);\n                }\n            },\n            _ => {\n                // do not lint expressions referencing objects of type `!`, as that required a\n                // diverging expression\n                // to begin with\n            },\n        }\n        self.maybe_walk_expr(e);\n    }\n    fn visit_block(&mut self, _: &'tcx Block<'_>) {\n        // don't continue over blocks, LateLintPass already does that\n    }\n}\n\n/// Walks up the AST from the given write expression (`vis.write_expr`) looking\n/// for reads to the same variable that are unsequenced relative to the write.\n///\n/// This means reads for which there is a common ancestor between the read and\n/// the write such that\n///\n/// * evaluating the ancestor necessarily evaluates both the read and the write (for example, `&x`\n///   and `|| x = 1` don't necessarily evaluate `x`), and\n///\n/// * which one is evaluated first depends on the order of sub-expression evaluation. Blocks, `if`s,\n///   loops, `match`es, and the short-circuiting logical operators are considered to have a defined\n///   evaluation order.\n///\n/// When such a read is found, the lint is triggered.\nfn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) {\n    let mut cur_id = vis.write_expr.hir_id;\n    loop {\n        let parent_id = vis.cx.tcx.parent_hir_id(cur_id);\n        if parent_id == cur_id {\n            break;\n        }\n\n        let stop_early = match vis.cx.tcx.hir_node(parent_id) {\n            Node::Expr(expr) => check_expr(vis, expr),\n            Node::Stmt(stmt) => check_stmt(vis, stmt),\n            Node::Item(_) => {\n                // We reached the top of the function, stop.\n                break;\n            },\n            _ => StopEarly::KeepGoing,\n        };\n        match stop_early {\n            StopEarly::Stop => break,\n            StopEarly::KeepGoing => {},\n        }\n\n        cur_id = parent_id;\n    }\n}\n\n/// Whether to stop early for the loop in `check_for_unsequenced_reads`. (If\n/// `check_expr` weren't an independent function, this would be unnecessary and\n/// we could just use `break`).\nenum StopEarly {\n    KeepGoing,\n    Stop,\n}\n\nfn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> StopEarly {\n    if expr.hir_id == vis.last_expr.hir_id {\n        return StopEarly::KeepGoing;\n    }\n\n    match expr.kind {\n        ExprKind::Array(_)\n        | ExprKind::Tup(_)\n        | ExprKind::MethodCall(..)\n        | ExprKind::Call(_, _)\n        | ExprKind::Assign(..)\n        | ExprKind::Index(..)\n        | ExprKind::Repeat(_, _)\n        | ExprKind::Struct(_, _, _)\n        | ExprKind::AssignOp(_, _, _) => {\n            walk_expr(vis, expr);\n        },\n        ExprKind::Binary(op, _, _) => {\n            if op.node == BinOpKind::And || op.node == BinOpKind::Or {\n                // x && y and x || y always evaluate x first, so these are\n                // strictly sequenced.\n            } else {\n                walk_expr(vis, expr);\n            }\n        },\n        ExprKind::Closure { .. } => {\n            // Either\n            //\n            // * `var` is defined in the closure body, in which case we've reached the top of the enclosing\n            //   function and can stop, or\n            //\n            // * `var` is captured by the closure, in which case, because evaluating a closure does not evaluate\n            //   its body, we don't necessarily have a write, so we need to stop to avoid generating false\n            //   positives.\n            //\n            // This is also the only place we need to stop early (grrr).\n            return StopEarly::Stop;\n        },\n        // All other expressions either have only one child or strictly\n        // sequence the evaluation order of their sub-expressions.\n        _ => {},\n    }\n\n    vis.last_expr = expr;\n\n    StopEarly::KeepGoing\n}\n\nfn check_stmt<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, stmt: &'tcx Stmt<'_>) -> StopEarly {\n    match stmt.kind {\n        StmtKind::Expr(expr) | StmtKind::Semi(expr) => check_expr(vis, expr),\n        // If the declaration is of a local variable, check its initializer\n        // expression if it has one. Otherwise, keep going.\n        StmtKind::Let(local) => local\n            .init\n            .as_ref()\n            .map_or(StopEarly::KeepGoing, |expr| check_expr(vis, expr)),\n        StmtKind::Item(..) => StopEarly::KeepGoing,\n    }\n}\n\n/// A visitor that looks for reads from a variable.\nstruct ReadVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    /// The ID of the variable we're looking for.\n    var: HirId,\n    /// The expressions where the write to the variable occurred (for reporting\n    /// in the lint).\n    write_expr: &'tcx Expr<'tcx>,\n    /// The last (highest in the AST) expression we've checked, so we know not\n    /// to recheck it.\n    last_expr: &'tcx Expr<'tcx>,\n}\n\nimpl<'tcx> Visitor<'tcx> for ReadVisitor<'_, 'tcx> {\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        if expr.hir_id == self.last_expr.hir_id {\n            return;\n        }\n\n        if expr.res_local_id() == Some(self.var)\n            // Check that this is a read, not a write.\n            && !is_in_assignment_position(self.cx, expr)\n        {\n            span_lint_and_then(\n                self.cx,\n                MIXED_READ_WRITE_IN_EXPRESSION,\n                expr.span,\n                format!(\"unsequenced read of `{}`\", self.cx.tcx.hir_name(self.var)),\n                |diag| {\n                    diag.span_note(\n                        self.write_expr.span,\n                        \"whether read occurs before this write depends on evaluation order\",\n                    );\n                },\n            );\n        }\n        match expr.kind {\n            // We're about to descend a closure. Since we don't know when (or\n            // if) the closure will be evaluated, any reads in it might not\n            // occur here (or ever). Like above, bail to avoid false positives.\n            ExprKind::Closure{..} |\n\n            // We want to avoid a false positive when a variable name occurs\n            // only to have its address taken, so we stop here. Technically,\n            // this misses some weird cases, eg.\n            //\n            // ```rust\n            // let mut x = 0;\n            // let a = foo(&{x = 1; x}, x);\n            // ```\n            //\n            // TODO: fix this\n            ExprKind::AddrOf(_, _, _) => {\n                return;\n            }\n            _ => {}\n        }\n\n        walk_expr(self, expr);\n    }\n}\n\n/// Returns `true` if `expr` is the LHS of an assignment, like `expr = ...`.\nfn is_in_assignment_position(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let Some(parent) = get_parent_expr(cx, expr)\n        && let ExprKind::Assign(lhs, ..) = parent.kind\n    {\n        return lhs.hir_id == expr.hir_id;\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/module_style.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::ast::{self, Inline, ItemKind, ModKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::def_id::LOCAL_CRATE;\nuse rustc_span::{FileName, SourceFile, Span, SyntaxContext, sym};\nuse std::path::{Component, Path, PathBuf};\nuse std::sync::Arc;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks that module layout uses only self named module files; bans `mod.rs` files.\n    ///\n    /// ### Why restrict this?\n    /// Having multiple module layout styles in a project can be confusing.\n    ///\n    /// ### Example\n    /// ```text\n    /// src/\n    ///   stuff/\n    ///     stuff_files.rs\n    ///     mod.rs\n    ///   lib.rs\n    /// ```\n    /// Use instead:\n    /// ```text\n    /// src/\n    ///   stuff/\n    ///     stuff_files.rs\n    ///   stuff.rs\n    ///   lib.rs\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub MOD_MODULE_FILES,\n    restriction,\n    \"checks that module layout is consistent\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks that module layout uses only `mod.rs` files.\n    ///\n    /// ### Why restrict this?\n    /// Having multiple module layout styles in a project can be confusing.\n    ///\n    /// ### Example\n    /// ```text\n    /// src/\n    ///   stuff/\n    ///     stuff_files.rs\n    ///   stuff.rs\n    ///   lib.rs\n    /// ```\n    /// Use instead:\n    /// ```text\n    /// src/\n    ///   stuff/\n    ///     stuff_files.rs\n    ///     mod.rs\n    ///   lib.rs\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub SELF_NAMED_MODULE_FILES,\n    restriction,\n    \"checks that module layout is consistent\"\n}\n\nimpl_lint_pass!(ModStyle => [MOD_MODULE_FILES, SELF_NAMED_MODULE_FILES]);\n\npub struct ModState {\n    contains_external: bool,\n    has_path_attr: bool,\n    mod_file: Arc<SourceFile>,\n}\n\n#[derive(Default)]\npub struct ModStyle {\n    working_dir: Option<PathBuf>,\n    module_stack: Vec<ModState>,\n}\n\nimpl EarlyLintPass for ModStyle {\n    fn check_crate(&mut self, cx: &EarlyContext<'_>, _: &ast::Crate) {\n        self.working_dir = cx.sess().source_map().working_dir().local_path().map(Path::to_path_buf);\n    }\n\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {\n        if cx.builder.lint_level(MOD_MODULE_FILES).level == Level::Allow\n            && cx.builder.lint_level(SELF_NAMED_MODULE_FILES).level == Level::Allow\n        {\n            return;\n        }\n        if let ItemKind::Mod(.., ModKind::Loaded(_, Inline::No { .. }, mod_spans, ..)) = &item.kind {\n            let has_path_attr = item.attrs.iter().any(|attr| attr.has_name(sym::path));\n            if !has_path_attr && let Some(current) = self.module_stack.last_mut() {\n                current.contains_external = true;\n            }\n            let mod_file = cx.sess().source_map().lookup_source_file(mod_spans.inner_span.lo());\n            self.module_stack.push(ModState {\n                contains_external: false,\n                has_path_attr,\n                mod_file,\n            });\n        }\n    }\n\n    fn check_item_post(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {\n        if cx.builder.lint_level(MOD_MODULE_FILES).level == Level::Allow\n            && cx.builder.lint_level(SELF_NAMED_MODULE_FILES).level == Level::Allow\n        {\n            return;\n        }\n\n        if let ItemKind::Mod(.., ModKind::Loaded(_, Inline::No { .. }, ..)) = &item.kind\n            && let Some(current) = self.module_stack.pop()\n            && !current.has_path_attr\n        {\n            let Some(path) = self\n                .working_dir\n                .as_ref()\n                .and_then(|src| try_trim_file_path_prefix(&current.mod_file, src))\n            else {\n                return;\n            };\n            if current.contains_external {\n                check_self_named_module(cx, path, &current.mod_file);\n            }\n            check_mod_module(cx, path, &current.mod_file);\n        }\n    }\n}\n\nfn check_self_named_module(cx: &EarlyContext<'_>, path: &Path, file: &SourceFile) {\n    if !path.ends_with(\"mod.rs\") {\n        let mut mod_folder = path.with_extension(\"\");\n        span_lint_and_then(\n            cx,\n            SELF_NAMED_MODULE_FILES,\n            Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),\n            format!(\"`mod.rs` files are required, found `{}`\", path.display()),\n            |diag| {\n                mod_folder.push(\"mod.rs\");\n                diag.help(format!(\"move `{}` to `{}`\", path.display(), mod_folder.display()));\n            },\n        );\n    }\n}\n\n/// We should not emit a lint for test modules in the presence of `mod.rs`.\n/// Using `mod.rs` in integration tests is a [common pattern](https://doc.rust-lang.org/book/ch11-03-test-organization.html#submodules-in-integration-test)\n/// for code-sharing between tests.\nfn check_mod_module(cx: &EarlyContext<'_>, path: &Path, file: &SourceFile) {\n    if path.ends_with(\"mod.rs\")\n        && !path\n            .components()\n            .filter_map(|c| if let Component::Normal(d) = c { Some(d) } else { None })\n            .take_while(|&c| c != \"src\")\n            .any(|c| c == \"tests\")\n    {\n        span_lint_and_then(\n            cx,\n            MOD_MODULE_FILES,\n            Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),\n            format!(\"`mod.rs` files are not allowed, found `{}`\", path.display()),\n            |diag| {\n                let mut mod_file = path.to_path_buf();\n                mod_file.pop();\n                mod_file.set_extension(\"rs\");\n\n                diag.help(format!(\"move `{}` to `{}`\", path.display(), mod_file.display()));\n            },\n        );\n    }\n}\n\nfn try_trim_file_path_prefix<'a>(file: &'a SourceFile, prefix: &'a Path) -> Option<&'a Path> {\n    if let FileName::Real(name) = &file.name\n        && let Some(mut path) = name.local_path()\n        && file.cnum == LOCAL_CRATE\n    {\n        if !path.is_relative() {\n            path = path.strip_prefix(prefix).ok()?;\n        }\n        Some(path)\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/multi_assignments.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_ast::ast::{Expr, ExprKind, Stmt, StmtKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for nested assignments.\n    ///\n    /// ### Why is this bad?\n    /// While this is in most cases already a type mismatch,\n    /// the result of an assignment being `()` can throw off people coming from languages like python or C,\n    /// where such assignments return a copy of the assigned value.\n    ///\n    /// ### Example\n    /// ```no_run\n    ///# let (a, b);\n    /// a = b = 42;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    ///# let (a, b);\n    /// b = 42;\n    /// a = b;\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub MULTI_ASSIGNMENTS,\n    suspicious,\n    \"instead of using `a = b = c;` use `a = c; b = c;`\"\n}\n\ndeclare_lint_pass!(MultiAssignments => [MULTI_ASSIGNMENTS]);\n\nfn strip_paren_blocks(expr: &Expr) -> &Expr {\n    match &expr.kind {\n        ExprKind::Paren(e) => strip_paren_blocks(e),\n        ExprKind::Block(b, _) => {\n            if let [\n                Stmt {\n                    kind: StmtKind::Expr(e),\n                    ..\n                },\n            ] = &b.stmts[..]\n            {\n                strip_paren_blocks(e)\n            } else {\n                expr\n            }\n        },\n        _ => expr,\n    }\n}\n\nimpl EarlyLintPass for MultiAssignments {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::Assign(target, source, _) = &expr.kind {\n            if let ExprKind::Assign(_target, _source, _) = &strip_paren_blocks(target).kind {\n                span_lint(cx, MULTI_ASSIGNMENTS, expr.span, \"assignments don't nest intuitively\");\n            }\n            if let ExprKind::Assign(_target, _source, _) = &strip_paren_blocks(source).kind {\n                span_lint(cx, MULTI_ASSIGNMENTS, expr.span, \"assignments don't nest intuitively\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/multiple_bound_locations.rs",
    "content": "use rustc_ast::visit::FnKind;\nuse rustc_ast::{Fn, NodeId, WherePredicateKind};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::source::SpanRangeExt;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Check if a generic is defined both in the bound predicate and in the `where` clause.\n    ///\n    /// ### Why is this bad?\n    /// It can be confusing for developers when seeing bounds for a generic in multiple places.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn ty<F: std::fmt::Debug>(a: F)\n    /// where\n    ///     F: Sized,\n    /// {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn ty<F>(a: F)\n    /// where\n    ///     F: Sized + std::fmt::Debug,\n    /// {}\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub MULTIPLE_BOUND_LOCATIONS,\n    style,\n    \"defining generic bounds in multiple locations\"\n}\n\ndeclare_lint_pass!(MultipleBoundLocations => [MULTIPLE_BOUND_LOCATIONS]);\n\nimpl EarlyLintPass for MultipleBoundLocations {\n    fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, _: Span, _: NodeId) {\n        if let FnKind::Fn(_, _, Fn { generics, .. }) = kind\n            && !generics.params.is_empty()\n            && !generics.where_clause.predicates.is_empty()\n        {\n            let mut generic_params_with_bounds = FxHashMap::default();\n\n            for param in &generics.params {\n                if !param.bounds.is_empty() {\n                    generic_params_with_bounds.insert(param.ident.as_str(), param.ident.span);\n                }\n            }\n            for clause in &generics.where_clause.predicates {\n                match &clause.kind {\n                    WherePredicateKind::BoundPredicate(pred) => {\n                        if (!pred.bound_generic_params.is_empty() || !pred.bounds.is_empty())\n                            && let Some(Some(bound_span)) = pred\n                                .bounded_ty\n                                .span\n                                .with_source_text(cx, |src| generic_params_with_bounds.get(src))\n                        {\n                            emit_lint(cx, *bound_span, pred.bounded_ty.span);\n                        }\n                    },\n                    WherePredicateKind::RegionPredicate(pred) => {\n                        if !pred.bounds.is_empty()\n                            && let Some(bound_span) = generic_params_with_bounds.get(&pred.lifetime.ident.as_str())\n                        {\n                            emit_lint(cx, *bound_span, pred.lifetime.ident.span);\n                        }\n                    },\n                    WherePredicateKind::EqPredicate(_) => {},\n                }\n            }\n        }\n    }\n}\n\nfn emit_lint(cx: &EarlyContext<'_>, bound_span: Span, where_span: Span) {\n    span_lint(\n        cx,\n        MULTIPLE_BOUND_LOCATIONS,\n        vec![bound_span, where_span],\n        \"bound is defined in more than one place\",\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/multiple_unsafe_ops_per_block.rs",
    "content": "use clippy_utils::desugar_await;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse hir::def::{DefKind, Res};\nuse hir::{BlockCheckMode, ExprKind, QPath, UnOp};\nuse rustc_ast::{BorrowKind, Mutability};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir as hir;\nuse rustc_hir::intravisit::{Visitor, walk_body, walk_expr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::{self, TyCtxt, TypeckResults};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `unsafe` blocks that contain more than one unsafe operation.\n    ///\n    /// ### Why restrict this?\n    /// Combined with `undocumented_unsafe_blocks`,\n    /// this lint ensures that each unsafe operation must be independently justified.\n    /// Combined with `unused_unsafe`, this lint also ensures\n    /// elimination of unnecessary unsafe blocks through refactoring.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// /// Reads a `char` from the given pointer.\n    /// ///\n    /// /// # Safety\n    /// ///\n    /// /// `ptr` must point to four consecutive, initialized bytes which\n    /// /// form a valid `char` when interpreted in the native byte order.\n    /// fn read_char(ptr: *const u8) -> char {\n    ///     // SAFETY: The caller has guaranteed that the value pointed\n    ///     // to by `bytes` is a valid `char`.\n    ///     unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// /// Reads a `char` from the given pointer.\n    /// ///\n    /// /// # Safety\n    /// ///\n    /// /// - `ptr` must be 4-byte aligned, point to four consecutive\n    /// ///   initialized bytes, and be valid for reads of 4 bytes.\n    /// /// - The bytes pointed to by `ptr` must represent a valid\n    /// ///   `char` when interpreted in the native byte order.\n    /// fn read_char(ptr: *const u8) -> char {\n    ///     // SAFETY: `ptr` is 4-byte aligned, points to four consecutive\n    ///     // initialized bytes, and is valid for reads of 4 bytes.\n    ///     let int_value = unsafe { *ptr.cast::<u32>() };\n    ///\n    ///     // SAFETY: The caller has guaranteed that the four bytes\n    ///     // pointed to by `bytes` represent a valid `char`.\n    ///     unsafe { char::from_u32_unchecked(int_value) }\n    /// }\n    /// ```\n    ///\n    /// ### Notes\n    ///\n    /// - Unsafe operations only count towards the total for the innermost\n    ///   enclosing `unsafe` block.\n    /// - Each call to a macro expanding to unsafe operations count for one\n    ///   unsafe operation.\n    /// - Taking a raw pointer to a union field is always safe and will\n    ///   not be considered unsafe by this lint, even when linting code written\n    ///   with a specified Rust version of 1.91 or earlier (which required\n    ///   using an `unsafe` block).\n    #[clippy::version = \"1.69.0\"]\n    pub MULTIPLE_UNSAFE_OPS_PER_BLOCK,\n    restriction,\n    \"more than one unsafe operation per `unsafe` block\"\n}\n\ndeclare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK]);\n\nimpl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {\n        if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) || block.span.from_expansion() {\n            return;\n        }\n        let unsafe_ops = UnsafeExprCollector::collect_unsafe_exprs(cx, block);\n        if unsafe_ops.len() > 1 {\n            span_lint_and_then(\n                cx,\n                MULTIPLE_UNSAFE_OPS_PER_BLOCK,\n                block.span,\n                format!(\n                    \"this `unsafe` block contains {} unsafe operations, expected only one\",\n                    unsafe_ops.len()\n                ),\n                |diag| {\n                    for (msg, span) in unsafe_ops {\n                        diag.span_note(span, msg);\n                    }\n                },\n            );\n        }\n    }\n}\n\nstruct UnsafeExprCollector<'tcx> {\n    tcx: TyCtxt<'tcx>,\n    typeck_results: &'tcx TypeckResults<'tcx>,\n    unsafe_ops: FxHashMap<Span, &'static str>,\n}\n\nimpl<'tcx> UnsafeExprCollector<'tcx> {\n    fn collect_unsafe_exprs(cx: &LateContext<'tcx>, block: &'tcx hir::Block<'tcx>) -> Vec<(&'static str, Span)> {\n        let mut collector = Self {\n            tcx: cx.tcx,\n            typeck_results: cx.typeck_results(),\n            unsafe_ops: FxHashMap::default(),\n        };\n        collector.visit_block(block);\n        #[allow(\n            rustc::potential_query_instability,\n            reason = \"span ordering only needed inside the one expression being walked\"\n        )]\n        let mut unsafe_ops = collector\n            .unsafe_ops\n            .into_iter()\n            .map(|(span, msg)| (msg, span))\n            .collect::<Vec<_>>();\n        unsafe_ops.sort_unstable();\n        unsafe_ops\n    }\n}\n\nimpl UnsafeExprCollector<'_> {\n    fn insert_span(&mut self, span: Span, message: &'static str) {\n        if span.from_expansion() {\n            self.unsafe_ops.insert(\n                span.source_callsite(),\n                \"this macro call expands into one or more unsafe operations\",\n            );\n        } else {\n            self.unsafe_ops.insert(span, message);\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {\n        match expr.kind {\n            // The `await` itself will desugar to two unsafe calls, but we should ignore those.\n            // Instead, check the expression that is `await`ed\n            _ if let Some(e) = desugar_await(expr) => {\n                return self.visit_expr(e);\n            },\n\n            // Do not recurse inside an inner `unsafe` block, it will be checked on its own\n            ExprKind::Block(block, _) if matches!(block.rules, BlockCheckMode::UnsafeBlock(_)) => return,\n\n            ExprKind::InlineAsm(_) => self.insert_span(expr.span, \"inline assembly used here\"),\n\n            ExprKind::AddrOf(BorrowKind::Raw, _, mut inner) => {\n                while let ExprKind::Field(prefix, _) = inner.kind\n                    && self.typeck_results.expr_adjustments(prefix).is_empty()\n                {\n                    inner = prefix;\n                }\n                return self.visit_expr(inner);\n            },\n\n            ExprKind::Field(e, _) if self.typeck_results.expr_ty(e).is_union() => {\n                self.insert_span(expr.span, \"union field access occurs here\");\n            },\n\n            ExprKind::Path(QPath::Resolved(\n                _,\n                hir::Path {\n                    res:\n                        Res::Def(\n                            DefKind::Static {\n                                mutability: Mutability::Mut,\n                                ..\n                            },\n                            _,\n                        ),\n                    ..\n                },\n            )) => {\n                self.insert_span(expr.span, \"access of a mutable static occurs here\");\n            },\n\n            ExprKind::Unary(UnOp::Deref, e) if self.typeck_results.expr_ty(e).is_raw_ptr() => {\n                self.insert_span(expr.span, \"raw pointer dereference occurs here\");\n            },\n\n            ExprKind::Call(path_expr, _) => {\n                let opt_sig = match *self.typeck_results.expr_ty_adjusted(path_expr).kind() {\n                    ty::FnDef(id, _) => Some(self.tcx.fn_sig(id).skip_binder()),\n                    ty::FnPtr(sig_tys, hdr) => Some(sig_tys.with(hdr)),\n                    _ => None,\n                };\n                if opt_sig.is_some_and(|sig| sig.safety().is_unsafe()) {\n                    self.insert_span(expr.span, \"unsafe function call occurs here\");\n                }\n            },\n\n            ExprKind::MethodCall(..) => {\n                let opt_sig = self\n                    .typeck_results\n                    .type_dependent_def_id(expr.hir_id)\n                    .map(|def_id| self.tcx.fn_sig(def_id));\n                if opt_sig.is_some_and(|sig| sig.skip_binder().safety().is_unsafe()) {\n                    self.insert_span(expr.span, \"unsafe method call occurs here\");\n                }\n            },\n\n            ExprKind::AssignOp(_, lhs, rhs) | ExprKind::Assign(lhs, rhs, _) => {\n                if matches!(\n                    lhs.kind,\n                    ExprKind::Path(QPath::Resolved(\n                        _,\n                        hir::Path {\n                            res: Res::Def(\n                                DefKind::Static {\n                                    mutability: Mutability::Mut,\n                                    ..\n                                },\n                                _\n                            ),\n                            ..\n                        }\n                    ))\n                ) {\n                    self.insert_span(expr.span, \"modification of a mutable static occurs here\");\n                    return self.visit_expr(rhs);\n                }\n            },\n\n            _ => {},\n        }\n\n        walk_expr(self, expr);\n    }\n\n    fn visit_body(&mut self, body: &hir::Body<'tcx>) {\n        let saved_typeck_results = self.typeck_results;\n        self.typeck_results = self.tcx.typeck_body(body.id());\n        walk_body(self, body);\n        self.typeck_results = saved_typeck_results;\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.tcx\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/mut_key.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::ty::InteriorMut;\nuse clippy_utils::{sym, trait_ref_of_method};\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\nuse rustc_middle::ty::{self, Ty, TyCtxt};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\nuse std::iter;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for sets/maps with mutable key types.\n    ///\n    /// ### Why is this bad?\n    /// All of `HashMap`, `HashSet`, `BTreeMap` and\n    /// `BtreeSet` rely on either the hash or the order of keys be unchanging,\n    /// so having types with interior mutability is a bad idea.\n    ///\n    /// ### Known problems\n    ///\n    /// #### False Positives\n    /// It's correct to use a struct that contains interior mutability as a key when its\n    /// implementation of `Hash` or `Ord` doesn't access any of the interior mutable types.\n    /// However, this lint is unable to recognize this, so it will often cause false positives in\n    /// these cases.\n    ///\n    /// #### False Negatives\n    /// This lint does not follow raw pointers (`*const T` or `*mut T`) as `Hash` and `Ord`\n    /// apply only to the **address** of the contained value. This can cause false negatives for\n    /// custom collections that use raw pointers internally.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::cmp::{PartialEq, Eq};\n    /// use std::collections::HashSet;\n    /// use std::hash::{Hash, Hasher};\n    /// use std::sync::atomic::AtomicUsize;\n    ///\n    /// struct Bad(AtomicUsize);\n    /// impl PartialEq for Bad {\n    ///     fn eq(&self, rhs: &Self) -> bool {\n    ///          ..\n    /// # ; true\n    ///     }\n    /// }\n    ///\n    /// impl Eq for Bad {}\n    ///\n    /// impl Hash for Bad {\n    ///     fn hash<H: Hasher>(&self, h: &mut H) {\n    ///         ..\n    /// # ;\n    ///     }\n    /// }\n    ///\n    /// fn main() {\n    ///     let _: HashSet<Bad> = HashSet::new();\n    /// }\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub MUTABLE_KEY_TYPE,\n    suspicious,\n    \"Check for mutable `Map`/`Set` key type\"\n}\n\nimpl_lint_pass!(MutableKeyType<'_> => [MUTABLE_KEY_TYPE]);\n\npub struct MutableKeyType<'tcx> {\n    interior_mut: InteriorMut<'tcx>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MutableKeyType<'tcx> {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {\n        if let hir::ItemKind::Fn { ref sig, .. } = item.kind {\n            self.check_sig(cx, item.owner_id.def_id, sig.decl);\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'tcx>) {\n        if let hir::ImplItemKind::Fn(ref sig, ..) = item.kind\n            && trait_ref_of_method(cx, item.owner_id).is_none()\n        {\n            self.check_sig(cx, item.owner_id.def_id, sig.decl);\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'tcx>) {\n        if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {\n            self.check_sig(cx, item.owner_id.def_id, sig.decl);\n        }\n    }\n\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &hir::LetStmt<'tcx>) {\n        if let hir::PatKind::Wild = local.pat.kind {\n            return;\n        }\n        self.check_ty_(cx, local.span, cx.typeck_results().pat_ty(local.pat));\n    }\n}\n\nimpl<'tcx> MutableKeyType<'tcx> {\n    pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf) -> Self {\n        Self {\n            interior_mut: InteriorMut::without_pointers(tcx, &conf.ignore_interior_mutability),\n        }\n    }\n\n    fn check_sig(&mut self, cx: &LateContext<'tcx>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'tcx>) {\n        let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity();\n        for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {\n            self.check_ty_(cx, hir_ty.span, *ty);\n        }\n        self.check_ty_(\n            cx,\n            decl.output.span(),\n            cx.tcx.instantiate_bound_regions_with_erased(fn_sig.output()),\n        );\n    }\n\n    // We want to lint 1. sets or maps with 2. not immutable key types and 3. no unerased\n    // generics (because the compiler cannot ensure immutability for unknown types).\n    fn check_ty_(&mut self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {\n        let ty = ty.peel_refs();\n        if let ty::Adt(def, args) = ty.kind()\n            && matches!(\n                cx.tcx.get_diagnostic_name(def.did()),\n                Some(sym::HashMap | sym::BTreeMap | sym::HashSet | sym::BTreeSet)\n            )\n        {\n            let subst_ty = args.type_at(0);\n            if let Some(chain) = self.interior_mut.interior_mut_ty_chain(cx, subst_ty) {\n                span_lint_and_then(cx, MUTABLE_KEY_TYPE, span, \"mutable key type\", |diag| {\n                    for ty in chain.iter().rev() {\n                        diag.note(with_forced_trimmed_paths!(format!(\n                            \"... because it contains `{ty}`, which has interior mutability\"\n                        )));\n                    }\n                });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/mut_mut.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};\nuse clippy_utils::higher;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg::Sugg;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, AmbigArg, BorrowKind, Expr, ExprKind, HirId, Mutability, TyKind, intravisit};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for instances of `mut mut` references.\n    ///\n    /// ### Why is this bad?\n    /// This is usually just a typo or a misunderstanding of how references work.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = &mut &mut 1;\n    ///\n    /// let mut x = &mut 1;\n    /// let y = &mut x;\n    ///\n    /// fn foo(x: &mut &mut u32) {}\n    /// ```\n    /// Use instead\n    /// ```no_run\n    /// let x = &mut 1;\n    ///\n    /// let mut x = &mut 1;\n    /// let y = &mut *x; // reborrow\n    ///\n    /// fn foo(x: &mut u32) {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MUT_MUT,\n    pedantic,\n    \"usage of double mut-refs, e.g., `&mut &mut ...`\"\n}\n\nimpl_lint_pass!(MutMut => [MUT_MUT]);\n\n#[derive(Default)]\npub(crate) struct MutMut {\n    seen_tys: FxHashSet<HirId>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for MutMut {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {\n        intravisit::walk_block(&mut MutVisitor { cx }, block);\n    }\n\n    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'_, AmbigArg>) {\n        if let TyKind::Ref(_, mty) = ty.kind\n            && mty.mutbl == Mutability::Mut\n            && let TyKind::Ref(_, mty2) = mty.ty.kind\n            && mty2.mutbl == Mutability::Mut\n            && !ty.span.in_external_macro(cx.sess().source_map())\n        {\n            if self.seen_tys.contains(&ty.hir_id) {\n                // we have 2+ `&mut`s, e.g., `&mut &mut &mut x`\n                // and we have already flagged on the outermost `&mut &mut (&mut x)`,\n                // so don't flag the inner `&mut &mut (x)`\n                return;\n            }\n\n            // if there is an even longer chain, like `&mut &mut &mut x`, suggest peeling off\n            // all extra ones at once\n            let (mut t, mut t2) = (mty.ty, mty2.ty);\n            let mut many_muts = false;\n            loop {\n                // this should allow us to remember all the nested types, so that the `contains`\n                // above fails faster\n                self.seen_tys.insert(t.hir_id);\n                if let TyKind::Ref(_, next) = t2.kind\n                    && next.mutbl == Mutability::Mut\n                {\n                    (t, t2) = (t2, next.ty);\n                    many_muts = true;\n                } else {\n                    break;\n                }\n            }\n\n            let mut applicability = Applicability::MaybeIncorrect;\n            let sugg = snippet_with_applicability(cx.sess(), t.span, \"..\", &mut applicability);\n            let suffix = if many_muts { \"s\" } else { \"\" };\n            span_lint_and_sugg(\n                cx,\n                MUT_MUT,\n                ty.span,\n                \"a type of form `&mut &mut _`\",\n                format!(\"remove the extra `&mut`{suffix}\"),\n                sugg.to_string(),\n                applicability,\n            );\n        }\n    }\n}\n\npub struct MutVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n}\n\nimpl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        if expr.span.in_external_macro(self.cx.sess().source_map()) {\n            return;\n        }\n\n        if let Some(higher::ForLoop { arg, body, .. }) = higher::ForLoop::hir(expr) {\n            // A `for` loop lowers to:\n            // ```rust\n            // match ::std::iter::Iterator::next(&mut iter) {\n            // //                                ^^^^\n            // ```\n            // Let's ignore the generated code.\n            intravisit::walk_expr(self, arg);\n            intravisit::walk_expr(self, body);\n        } else if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, e) = expr.kind {\n            if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, e2) = e.kind {\n                if !expr.span.eq_ctxt(e.span) {\n                    return;\n                }\n\n                // if there is an even longer chain, like `&mut &mut &mut x`, suggest peeling off\n                // all extra ones at once\n                let (mut e, mut e2) = (e, e2);\n                let mut many_muts = false;\n                loop {\n                    if !e.span.eq_ctxt(e2.span) {\n                        return;\n                    }\n                    if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, next) = e2.kind {\n                        (e, e2) = (e2, next);\n                        many_muts = true;\n                    } else {\n                        break;\n                    }\n                }\n\n                let mut applicability = Applicability::MaybeIncorrect;\n                let sugg = Sugg::hir_with_applicability(self.cx, e, \"..\", &mut applicability);\n                let suffix = if many_muts { \"s\" } else { \"\" };\n                span_lint_hir_and_then(\n                    self.cx,\n                    MUT_MUT,\n                    expr.hir_id,\n                    expr.span,\n                    \"an expression of form `&mut &mut _`\",\n                    |diag| {\n                        diag.span_suggestion(\n                            expr.span,\n                            format!(\"remove the extra `&mut`{suffix}\"),\n                            sugg,\n                            applicability,\n                        );\n                    },\n                );\n            } else if let ty::Ref(_, ty, Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind()\n                && ty.peel_refs().is_sized(self.cx.tcx, self.cx.typing_env())\n            {\n                let mut applicability = Applicability::MaybeIncorrect;\n                let sugg = Sugg::hir_with_applicability(self.cx, e, \"..\", &mut applicability).mut_addr_deref();\n                span_lint_hir_and_then(\n                    self.cx,\n                    MUT_MUT,\n                    expr.hir_id,\n                    expr.span,\n                    \"this expression mutably borrows a mutable reference\",\n                    |diag| {\n                        diag.span_suggestion(expr.span, \"reborrow instead\", sugg, applicability);\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/mutable_debug_assertion.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::macros::{MacroCall, find_assert_args, find_assert_eq_args, root_macro_call_first_node};\nuse clippy_utils::sym;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{BorrowKind, Expr, ExprKind, MatchSource, Mutability};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for function/method calls with a mutable\n    /// parameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros.\n    ///\n    /// ### Why is this bad?\n    /// In release builds `debug_assert!` macros are optimized out by the\n    /// compiler.\n    /// Therefore mutating something in a `debug_assert!` macro results in different behavior\n    /// between a release and debug build.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// debug_assert_eq!(vec![3].pop(), Some(3));\n    ///\n    /// // or\n    ///\n    /// # let mut x = 5;\n    /// # fn takes_a_mut_parameter(_: &mut u32) -> bool { unimplemented!() }\n    /// debug_assert!(takes_a_mut_parameter(&mut x));\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub DEBUG_ASSERT_WITH_MUT_CALL,\n    nursery,\n    \"mutable arguments in `debug_assert{,_ne,_eq}!`\"\n}\n\ndeclare_lint_pass!(DebugAssertWithMutCall => [DEBUG_ASSERT_WITH_MUT_CALL]);\n\nimpl<'tcx> LateLintPass<'tcx> for DebugAssertWithMutCall {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        let Some(macro_call) = root_macro_call_first_node(cx, e) else {\n            return;\n        };\n        match cx.tcx.get_diagnostic_name(macro_call.def_id) {\n            Some(sym::debug_assert_macro) => {\n                if let Some((arg, _)) = find_assert_args(cx, e, macro_call.expn) {\n                    check_arg(cx, arg, &macro_call);\n                }\n            },\n            Some(sym::debug_assert_ne_macro | sym::debug_assert_eq_macro) => {\n                if let Some((lhs, rhs, _)) = find_assert_eq_args(cx, e, macro_call.expn) {\n                    check_arg(cx, lhs, &macro_call);\n                    check_arg(cx, rhs, &macro_call);\n                }\n            },\n            _ => {},\n        }\n    }\n}\n\nfn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>, macro_call: &MacroCall) {\n    let mut visitor = MutArgVisitor::new(cx);\n    visitor.visit_expr(arg);\n    if let Some(span) = visitor.expr_span() {\n        span_lint(\n            cx,\n            DEBUG_ASSERT_WITH_MUT_CALL,\n            span,\n            format!(\n                \"do not call a function with mutable arguments inside of `{}!`\",\n                cx.tcx.item_name(macro_call.def_id)\n            ),\n        );\n    }\n}\n\nstruct MutArgVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    expr_span: Option<Span>,\n    found: bool,\n}\n\nimpl<'a, 'tcx> MutArgVisitor<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>) -> Self {\n        Self {\n            cx,\n            expr_span: None,\n            found: false,\n        }\n    }\n\n    fn expr_span(&self) -> Option<Span> {\n        if self.found { self.expr_span } else { None }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for MutArgVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        match expr.kind {\n            ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) => {\n                self.found = true;\n                return;\n            },\n            ExprKind::Path(_) => {\n                if let Some(adj) = self.cx.typeck_results().adjustments().get(expr.hir_id)\n                    && adj\n                        .iter()\n                        .any(|a| matches!(a.target.kind(), ty::Ref(_, _, Mutability::Mut)))\n                {\n                    self.found = true;\n                    return;\n                }\n            },\n            // Don't check await desugars\n            ExprKind::Match(_, _, MatchSource::AwaitDesugar) => return,\n            _ if !self.found => self.expr_span = Some(expr.span),\n            _ => return,\n        }\n        walk_expr(self, expr);\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/mutex_atomic.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::{IntoSpan, SpanRangeExt};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::ty_from_hir_ty;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::{self as hir, Expr, ExprKind, Item, ItemKind, LetStmt, QPath};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::mir::Mutability;\nuse rustc_middle::ty::{self, IntTy, Ty, UintTy};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Mutex<X>` where an atomic will do.\n    ///\n    /// ### Why restrict this?\n    /// Using a mutex just to make access to a plain bool or\n    /// reference sequential is shooting flies with cannons.\n    /// `std::sync::atomic::AtomicBool` and `std::sync::atomic::AtomicPtr` are leaner and\n    /// faster.\n    ///\n    /// On the other hand, `Mutex`es are, in general, easier to\n    /// verify correctness. An atomic does not behave the same as\n    /// an equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s\n    /// commentary for more details.\n    ///\n    /// ### Known problems\n    /// * This lint cannot detect if the mutex is actually used\n    ///   for waiting before a critical section.\n    /// * This lint has a false positive that warns without considering the case\n    ///   where `Mutex` is used together with `Condvar`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let y = true;\n    /// # use std::sync::Mutex;\n    /// let x = Mutex::new(&y);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let y = true;\n    /// # use std::sync::atomic::AtomicBool;\n    /// let x = AtomicBool::new(y);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MUTEX_ATOMIC,\n    restriction,\n    \"using a mutex where an atomic value could be used instead.\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Mutex<X>` where `X` is an integral\n    /// type.\n    ///\n    /// ### Why restrict this?\n    /// Using a mutex just to make access to a plain integer\n    /// sequential is\n    /// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster.\n    ///\n    /// On the other hand, `Mutex`es are, in general, easier to\n    /// verify correctness. An atomic does not behave the same as\n    /// an equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s\n    /// commentary for more details.\n    ///\n    /// ### Known problems\n    /// * This lint cannot detect if the mutex is actually used\n    ///   for waiting before a critical section.\n    /// * This lint has a false positive that warns without considering the case\n    ///   where `Mutex` is used together with `Condvar`.\n    /// * This lint suggest using `AtomicU64` instead of `Mutex<u64>`, but\n    ///   `AtomicU64` is not available on some 32-bit platforms.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::sync::Mutex;\n    /// let x = Mutex::new(0usize);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::sync::atomic::AtomicUsize;\n    /// let x = AtomicUsize::new(0usize);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MUTEX_INTEGER,\n    restriction,\n    \"using a mutex for an integer type\"\n}\n\ndeclare_lint_pass!(Mutex => [MUTEX_ATOMIC, MUTEX_INTEGER]);\n\n// NOTE: we don't use `check_expr` because that would make us lint every _use_ of such mutexes, not\n// just their definitions\nimpl<'tcx> LateLintPass<'tcx> for Mutex {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if !item.span.from_expansion()\n            && let ItemKind::Static(_, _, ty, body_id) = item.kind\n        {\n            let body = cx.tcx.hir_body(body_id);\n            let mid_ty = ty_from_hir_ty(cx, ty);\n            check_expr(cx, body.value.peel_blocks(), &TypeAscriptionKind::Required(ty), mid_ty);\n        }\n    }\n    fn check_local(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx LetStmt<'_>) {\n        if !stmt.span.from_expansion()\n            && let Some(init) = stmt.init\n        {\n            let mid_ty = cx.typeck_results().expr_ty(init);\n            check_expr(cx, init.peel_blocks(), &TypeAscriptionKind::Optional(stmt.ty), mid_ty);\n        }\n    }\n}\n\n/// Whether the type ascription `: Mutex<X>` (which we'll suggest replacing with `AtomicX`) is\n/// required\nenum TypeAscriptionKind<'tcx> {\n    /// Yes; for us, this is the case for statics\n    Required(&'tcx hir::Ty<'tcx>),\n    /// No; the ascription might've been necessary in an expression like:\n    /// ```ignore\n    /// let mutex: Mutex<u64> = Mutex::new(0);\n    /// ```\n    /// to specify the type of `0`, but since `AtomicX` already refers to a concrete type, we won't\n    /// need this ascription anymore.\n    Optional(Option<&'tcx hir::Ty<'tcx>>),\n}\n\nfn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, ty_ascription: &TypeAscriptionKind<'tcx>, ty: Ty<'tcx>) {\n    if let ty::Adt(_, subst) = ty.kind()\n        && ty.is_diag_item(cx, sym::Mutex)\n        && let mutex_param = subst.type_at(0)\n        && let Some(atomic_name) = get_atomic_name(mutex_param)\n    {\n        let msg = \"using a `Mutex` where an atomic would do\";\n        let diag = |diag: &mut Diag<'_, _>| {\n            // if `expr = Mutex::new(arg)`, we can try emitting a suggestion\n            if let ExprKind::Call(qpath, [arg]) = expr.kind\n                && let ExprKind::Path(QPath::TypeRelative(_mutex, new)) = qpath.kind\n                && new.ident.name == sym::new\n            {\n                let mut applicability = Applicability::MaybeIncorrect;\n                let arg = Sugg::hir_with_context(cx, arg, expr.span.ctxt(), \"_\", &mut applicability);\n                let mut suggs = vec![(expr.span, format!(\"std::sync::atomic::{atomic_name}::new({arg})\"))];\n                match ty_ascription {\n                    TypeAscriptionKind::Required(ty_ascription) => {\n                        suggs.push((ty_ascription.span, format!(\"std::sync::atomic::{atomic_name}\")));\n                    },\n                    TypeAscriptionKind::Optional(Some(ty_ascription)) => {\n                        // See https://github.com/rust-lang/rust-clippy/pull/15386 for why this is\n                        // required\n                        let colon_ascription = (cx.sess().source_map())\n                            .span_extend_to_prev_char_before(ty_ascription.span, ':', true)\n                            .with_leading_whitespace(cx)\n                            .into_span();\n                        suggs.push((colon_ascription, String::new()));\n                    },\n                    TypeAscriptionKind::Optional(None) => {}, // nothing to remove/replace\n                }\n                diag.multipart_suggestion(\"try\", suggs, applicability);\n            } else {\n                diag.help(format!(\"consider using an `{atomic_name}` instead\"));\n            }\n            diag.help(\"if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\");\n        };\n        match *mutex_param.kind() {\n            ty::Uint(t) if t != UintTy::Usize => span_lint_and_then(cx, MUTEX_INTEGER, expr.span, msg, diag),\n            ty::Int(t) if t != IntTy::Isize => span_lint_and_then(cx, MUTEX_INTEGER, expr.span, msg, diag),\n            _ => span_lint_and_then(cx, MUTEX_ATOMIC, expr.span, msg, diag),\n        }\n    }\n}\n\nfn get_atomic_name(ty: Ty<'_>) -> Option<&'static str> {\n    match ty.kind() {\n        ty::Bool => Some(\"AtomicBool\"),\n        ty::Uint(uint_ty) => {\n            match uint_ty {\n                UintTy::U8 => Some(\"AtomicU8\"),\n                UintTy::U16 => Some(\"AtomicU16\"),\n                UintTy::U32 => Some(\"AtomicU32\"),\n                UintTy::U64 => Some(\"AtomicU64\"),\n                UintTy::Usize => Some(\"AtomicUsize\"),\n                // `AtomicU128` is unstable and only available on a few platforms: https://github.com/rust-lang/rust/issues/99069\n                UintTy::U128 => None,\n            }\n        },\n        ty::Int(int_ty) => {\n            match int_ty {\n                IntTy::I8 => Some(\"AtomicI8\"),\n                IntTy::I16 => Some(\"AtomicI16\"),\n                IntTy::I32 => Some(\"AtomicI32\"),\n                IntTy::I64 => Some(\"AtomicI64\"),\n                IntTy::Isize => Some(\"AtomicIsize\"),\n                // `AtomicU128` is unstable and only available on a few platforms: https://github.com/rust-lang/rust/issues/99069\n                IntTy::I128 => None,\n            }\n        },\n        // `AtomicPtr` only accepts `*mut T`\n        ty::RawPtr(_, Mutability::Mut) => Some(\"AtomicPtr\"),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_arbitrary_self_type.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_ast::ast::{BindingMode, ByRef, Lifetime, Param, PatKind, TyKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// The lint checks for `self` in fn parameters that\n    /// specify the `Self`-type explicitly\n    /// ### Why is this bad?\n    /// Increases the amount and decreases the readability of code\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum ValType {\n    ///     I32,\n    ///     I64,\n    ///     F32,\n    ///     F64,\n    /// }\n    ///\n    /// impl ValType {\n    ///     pub fn bytes(self: Self) -> usize {\n    ///         match self {\n    ///             Self::I32 | Self::F32 => 4,\n    ///             Self::I64 | Self::F64 => 8,\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Could be rewritten as\n    ///\n    /// ```no_run\n    /// enum ValType {\n    ///     I32,\n    ///     I64,\n    ///     F32,\n    ///     F64,\n    /// }\n    ///\n    /// impl ValType {\n    ///     pub fn bytes(self) -> usize {\n    ///         match self {\n    ///             Self::I32 | Self::F32 => 4,\n    ///             Self::I64 | Self::F64 => 8,\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub NEEDLESS_ARBITRARY_SELF_TYPE,\n    complexity,\n    \"type of `self` parameter is already by default `Self`\"\n}\n\ndeclare_lint_pass!(NeedlessArbitrarySelfType => [NEEDLESS_ARBITRARY_SELF_TYPE]);\n\nenum Mode {\n    Ref(Option<Lifetime>),\n    Value,\n}\n\nimpl EarlyLintPass for NeedlessArbitrarySelfType {\n    fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {\n        // Bail out if the parameter it's not a receiver or was not written by the user\n        if !p.is_self() || p.span.from_expansion() {\n            return;\n        }\n\n        let (path, binding_mode, mutbl) = match &p.ty.kind {\n            TyKind::Path(None, path) if let PatKind::Ident(BindingMode(ByRef::No, mutbl), _, _) = p.pat.kind => {\n                (path, Mode::Value, mutbl)\n            },\n            TyKind::Ref(lifetime, mut_ty)\n                if let TyKind::Path(None, path) = &mut_ty.ty.kind\n                    && let PatKind::Ident(BindingMode::NONE, _, _) = p.pat.kind =>\n            {\n                (path, Mode::Ref(*lifetime), mut_ty.mutbl)\n            },\n            _ => return,\n        };\n\n        let span = p.span.to(p.ty.span);\n        if let [segment] = &path.segments[..]\n            && segment.ident.name == kw::SelfUpper\n        {\n            span_lint_and_then(\n                cx,\n                NEEDLESS_ARBITRARY_SELF_TYPE,\n                span,\n                \"the type of the `self` parameter does not need to be arbitrary\",\n                |diag| {\n                    let mut applicability = Applicability::MachineApplicable;\n                    let add = match binding_mode {\n                        Mode::Value => String::new(),\n                        Mode::Ref(None) => mutbl.ref_prefix_str().to_string(),\n                        Mode::Ref(Some(lifetime)) => {\n                            // In case we have a named lifetime, we check if the name comes from expansion.\n                            // If it does, at this point we know the rest of the parameter was written by the user,\n                            // so let them decide what the name of the lifetime should be.\n                            // See #6089 for more details.\n                            let lt_name = if lifetime.ident.span.from_expansion() {\n                                applicability = Applicability::HasPlaceholders;\n                                \"'_\".into()\n                            } else {\n                                snippet_with_applicability(cx, lifetime.ident.span, \"'_\", &mut applicability)\n                            };\n                            format!(\"&{lt_name} {mut_}\", mut_ = mutbl.prefix_str())\n                        },\n                    };\n\n                    let mut sugg = vec![(p.ty.span.with_lo(p.span.hi()), String::new())];\n                    if !add.is_empty() {\n                        sugg.push((p.span.shrink_to_lo(), add));\n                    }\n                    diag.multipart_suggestion(\"remove the type\", sugg, applicability);\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_bool.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{\n    SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_parent_stmt, is_receiver_of_method_call,\n    peel_blocks, peel_blocks_with_stmt, span_contains_comment,\n};\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions of the form `if c { true } else {\n    /// false }` (or vice versa) and suggests using the condition directly.\n    ///\n    /// ### Why is this bad?\n    /// Redundant code.\n    ///\n    /// ### Known problems\n    /// Maybe false positives: Sometimes, the two branches are\n    /// painstakingly documented (which we, of course, do not detect), so they *may*\n    /// have some value. Even then, the documentation can be rewritten to match the\n    /// shorter code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = true;\n    /// if x {\n    ///     false\n    /// } else {\n    ///     true\n    /// }\n    /// # ;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = true;\n    /// !x\n    /// # ;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_BOOL,\n    complexity,\n    \"if-statements with plain booleans in the then- and else-clause, e.g., `if p { true } else { false }`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions of the form `if c { x = true } else { x = false }`\n    /// (or vice versa) and suggest assigning the variable directly from the\n    /// condition.\n    ///\n    /// ### Why is this bad?\n    /// Redundant code.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// # fn must_keep(x: i32, y: i32) -> bool { x == y }\n    /// # let x = 32; let y = 10;\n    /// # let mut skip: bool;\n    /// if must_keep(x, y) {\n    ///     skip = false;\n    /// } else {\n    ///     skip = true;\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// # fn must_keep(x: i32, y: i32) -> bool { x == y }\n    /// # let x = 32; let y = 10;\n    /// # let mut skip: bool;\n    /// skip = !must_keep(x, y);\n    /// ```\n    #[clippy::version = \"1.71.0\"]\n    pub NEEDLESS_BOOL_ASSIGN,\n    complexity,\n    \"setting the same boolean variable in both branches of an if-statement\"\n}\n\ndeclare_lint_pass!(NeedlessBool => [NEEDLESS_BOOL, NEEDLESS_BOOL_ASSIGN]);\n\nfn condition_needs_parentheses(e: &Expr<'_>) -> bool {\n    let mut inner = e;\n    while let ExprKind::Binary(_, i, _)\n    | ExprKind::Call(i, _)\n    | ExprKind::Cast(i, _)\n    | ExprKind::Type(i, _)\n    | ExprKind::Index(i, _, _) = inner.kind\n    {\n        if is_block_like(i) {\n            return true;\n        }\n        inner = i;\n    }\n    false\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessBool {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        use self::Expression::{Bool, RetBool};\n        if !e.span.from_expansion()\n            && let Some(higher::If {\n                cond,\n                then,\n                r#else: Some(else_expr),\n            }) = higher::If::hir(e)\n            && !span_contains_comment(cx, e.span)\n        {\n            let reduce = |ret, not| {\n                let mut applicability = Applicability::MachineApplicable;\n                let snip = Sugg::hir_with_applicability(cx, cond, \"<predicate>\", &mut applicability);\n                let mut snip = if not { !snip } else { snip };\n\n                if ret {\n                    snip = snip.make_return();\n                }\n\n                if is_else_clause(cx.tcx, e) {\n                    snip = snip.blockify();\n                }\n\n                if (condition_needs_parentheses(cond) && is_parent_stmt(cx, e.hir_id))\n                    || is_receiver_of_method_call(cx, e)\n                    || is_as_argument(cx, e)\n                {\n                    snip = snip.maybe_paren();\n                }\n\n                span_lint_and_sugg(\n                    cx,\n                    NEEDLESS_BOOL,\n                    e.span,\n                    \"this if-then-else expression returns a bool literal\",\n                    \"you can reduce it to\",\n                    snip.to_string(),\n                    applicability,\n                );\n            };\n            if let Some(a) = fetch_bool_block(then)\n                && let Some(b) = fetch_bool_block(else_expr)\n            {\n                match (a, b) {\n                    (RetBool(true), RetBool(true)) | (Bool(true), Bool(true)) => {\n                        span_lint(\n                            cx,\n                            NEEDLESS_BOOL,\n                            e.span,\n                            \"this if-then-else expression will always return true\",\n                        );\n                    },\n                    (RetBool(false), RetBool(false)) | (Bool(false), Bool(false)) => {\n                        span_lint(\n                            cx,\n                            NEEDLESS_BOOL,\n                            e.span,\n                            \"this if-then-else expression will always return false\",\n                        );\n                    },\n                    (RetBool(true), RetBool(false)) => reduce(true, false),\n                    (Bool(true), Bool(false)) => reduce(false, false),\n                    (RetBool(false), RetBool(true)) => reduce(true, true),\n                    (Bool(false), Bool(true)) => reduce(false, true),\n                    _ => (),\n                }\n            }\n            if let Some((lhs_a, a)) = fetch_assign(then)\n                && let Some((lhs_b, b)) = fetch_assign(else_expr)\n                && SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b)\n            {\n                let mut applicability = Applicability::MachineApplicable;\n                let cond = Sugg::hir_with_context(cx, cond, e.span.ctxt(), \"..\", &mut applicability);\n                let (lhs, _) = snippet_with_context(cx, lhs_a.span, e.span.ctxt(), \"..\", &mut applicability);\n                let mut sugg = if a == b {\n                    format!(\"{cond}; {lhs} = {a:?};\")\n                } else {\n                    format!(\"{lhs} = {};\", if a { cond } else { !cond })\n                };\n\n                if is_else_clause(cx.tcx, e) {\n                    sugg = format!(\"{{ {sugg} }}\");\n                }\n\n                span_lint_and_sugg(\n                    cx,\n                    NEEDLESS_BOOL_ASSIGN,\n                    e.span,\n                    \"this if-then-else expression assigns a bool literal\",\n                    \"you can reduce it to\",\n                    sugg,\n                    applicability,\n                );\n            }\n        }\n    }\n}\n\nenum Expression {\n    Bool(bool),\n    RetBool(bool),\n}\n\nfn fetch_bool_block(expr: &Expr<'_>) -> Option<Expression> {\n    match peel_blocks_with_stmt(expr).kind {\n        ExprKind::Ret(Some(ret)) => Some(Expression::RetBool(fetch_bool_expr(ret)?)),\n        _ => Some(Expression::Bool(fetch_bool_expr(expr)?)),\n    }\n}\n\nfn fetch_bool_expr(expr: &Expr<'_>) -> Option<bool> {\n    if let ExprKind::Lit(lit_ptr) = peel_blocks(expr).kind\n        && let LitKind::Bool(value) = lit_ptr.node\n    {\n        return Some(value);\n    }\n    None\n}\n\nfn fetch_assign<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<(&'tcx Expr<'tcx>, bool)> {\n    if let ExprKind::Assign(lhs, rhs, _) = peel_blocks_with_stmt(expr).kind {\n        fetch_bool_expr(rhs).map(|b| (lhs, b))\n    } else {\n        None\n    }\n}\n\nfn is_as_argument(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    matches!(get_parent_expr(cx, e).map(|e| e.kind), Some(ExprKind::Cast(_, _)))\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_borrowed_ref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BindingMode, Mutability, Node, Pat, PatKind, Pinnedness};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for bindings that needlessly destructure a reference and borrow the inner\n    /// value with `&ref`.\n    ///\n    /// ### Why is this bad?\n    /// This pattern has no effect in almost all cases.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut v = Vec::<String>::new();\n    /// v.iter_mut().filter(|&ref a| a.is_empty());\n    ///\n    /// if let &[ref first, ref second] = v.as_slice() {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let mut v = Vec::<String>::new();\n    /// v.iter_mut().filter(|a| a.is_empty());\n    ///\n    /// if let [first, second] = v.as_slice() {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_BORROWED_REFERENCE,\n    complexity,\n    \"destructuring a reference and borrowing the inner value\"\n}\n\ndeclare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]);\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {\n    fn check_pat(&mut self, cx: &LateContext<'tcx>, ref_pat: &'tcx Pat<'_>) {\n        if let PatKind::Ref(pat, Pinnedness::Not, Mutability::Not) = ref_pat.kind\n            && !ref_pat.span.from_expansion()\n            && cx\n                .tcx\n                .hir_parent_iter(ref_pat.hir_id)\n                .map_while(|(_, parent)| if let Node::Pat(pat) = parent { Some(pat) } else { None })\n                // Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms\n                .all(|pat| !matches!(pat.kind, PatKind::Or(_)))\n        {\n            match pat.kind {\n                // Check sub_pat got a `ref` keyword (excluding `ref mut`).\n                PatKind::Binding(BindingMode::REF, _, ident, None) => {\n                    span_lint_and_then(\n                        cx,\n                        NEEDLESS_BORROWED_REFERENCE,\n                        ref_pat.span,\n                        \"this pattern takes a reference on something that is being dereferenced\",\n                        |diag| {\n                            // `&ref ident`\n                            //  ^^^^^\n                            let span = ref_pat.span.until(ident.span);\n                            diag.span_suggestion_verbose(\n                                span,\n                                \"try removing the `&ref` part\",\n                                String::new(),\n                                Applicability::MachineApplicable,\n                            );\n                        },\n                    );\n                },\n                // Slices where each element is `ref`: `&[ref a, ref b, ..., ref z]`\n                PatKind::Slice(\n                    before,\n                    None\n                    | Some(Pat {\n                        kind: PatKind::Wild, ..\n                    }),\n                    after,\n                ) => {\n                    check_subpatterns(\n                        cx,\n                        \"dereferencing a slice pattern where every element takes a reference\",\n                        ref_pat,\n                        pat,\n                        itertools::chain(before, after),\n                    );\n                },\n                PatKind::Tuple(subpatterns, _) | PatKind::TupleStruct(_, subpatterns, _) => {\n                    check_subpatterns(\n                        cx,\n                        \"dereferencing a tuple pattern where every element takes a reference\",\n                        ref_pat,\n                        pat,\n                        subpatterns,\n                    );\n                },\n                PatKind::Struct(_, fields, _) => {\n                    check_subpatterns(\n                        cx,\n                        \"dereferencing a struct pattern where every field's pattern takes a reference\",\n                        ref_pat,\n                        pat,\n                        fields.iter().map(|field| field.pat),\n                    );\n                },\n                _ => {},\n            }\n        }\n    }\n}\n\nfn check_subpatterns<'tcx>(\n    cx: &LateContext<'tcx>,\n    message: &'static str,\n    ref_pat: &Pat<'_>,\n    pat: &Pat<'_>,\n    subpatterns: impl IntoIterator<Item = &'tcx Pat<'tcx>>,\n) {\n    let mut suggestions = Vec::new();\n\n    for subpattern in subpatterns {\n        match subpattern.kind {\n            PatKind::Binding(BindingMode::REF, _, ident, None) => {\n                // `ref ident`\n                //  ^^^^\n                let span = subpattern.span.until(ident.span);\n                suggestions.push((span, String::new()));\n            },\n            PatKind::Wild => {},\n            _ => return,\n        }\n    }\n\n    if !suggestions.is_empty() {\n        span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, ref_pat.span, message, |diag| {\n            // `&pat`\n            //  ^\n            let span = ref_pat.span.until(pat.span);\n            suggestions.push((span, String::new()));\n\n            diag.multipart_suggestion(\n                \"try removing the `&` and `ref` parts\",\n                suggestions,\n                Applicability::MachineApplicable,\n            );\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_borrows_for_generic_args.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir, expr_local, local_assignments, used_exactly_once};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_n_hir_expr_refs, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::{DefId, LocalDefId};\nuse rustc_hir::{Body, Expr, ExprKind, Mutability, Path, QPath};\nuse rustc_index::bit_set::DenseBitSet;\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir::{Rvalue, StatementKind};\nuse rustc_middle::ty::{\n    self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, ParamTy, ProjectionPredicate, Ty,\n};\nuse rustc_session::impl_lint_pass;\nuse rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;\nuse rustc_trait_selection::traits::{Obligation, ObligationCause};\nuse std::collections::VecDeque;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for borrow operations (`&`) that are used as a generic argument to a\n    /// function when the borrowed value could be used.\n    ///\n    /// ### Why is this bad?\n    /// Suggests that the receiver of the expression borrows\n    /// the expression.\n    ///\n    /// ### Known problems\n    /// The lint cannot tell when the implementation of a trait\n    /// for `&T` and `T` do different things. Removing a borrow\n    /// in such a case can change the semantics of the code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn f(_: impl AsRef<str>) {}\n    ///\n    /// let x = \"foo\";\n    /// f(&x);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn f(_: impl AsRef<str>) {}\n    ///\n    /// let x = \"foo\";\n    /// f(x);\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub NEEDLESS_BORROWS_FOR_GENERIC_ARGS,\n    style,\n    \"taking a reference that is going to be automatically dereferenced\"\n}\n\nimpl_lint_pass!(NeedlessBorrowsForGenericArgs<'_> => [\n    NEEDLESS_BORROWS_FOR_GENERIC_ARGS,\n]);\n\npub struct NeedlessBorrowsForGenericArgs<'tcx> {\n    /// Stack of (body owner, `PossibleBorrowerMap`) pairs. Used by\n    /// [`needless_borrow_count`] to determine when a borrowed expression can instead\n    /// be moved.\n    possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,\n\n    // `IntoIterator` for arrays requires Rust 1.53.\n    msrv: Msrv,\n}\nimpl NeedlessBorrowsForGenericArgs<'_> {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            possible_borrowers: Vec::new(),\n            msrv: conf.msrv,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if matches!(expr.kind, ExprKind::AddrOf(..))\n            && !expr.span.from_expansion()\n            && let use_cx = expr_use_ctxt(cx, expr)\n            && use_cx.same_ctxt\n            && !use_cx.is_ty_unified\n            && let use_node = use_cx.use_node(cx)\n            && let Some(DefinedTy::Mir { def_site_def_id: _, ty }) = use_node.defined_ty(cx)\n            && let ty::Param(param_ty) = *ty.skip_binder().kind()\n            && let Some((hir_id, fn_id, i)) = match use_node {\n                ExprUseNode::MethodArg(_, _, 0) => None,\n                ExprUseNode::MethodArg(hir_id, None, i) => cx\n                    .typeck_results()\n                    .type_dependent_def_id(hir_id)\n                    .map(|id| (hir_id, id, i)),\n                ExprUseNode::FnArg(\n                    &Expr {\n                        kind: ExprKind::Path(ref p),\n                        hir_id,\n                        ..\n                    },\n                    i,\n                ) if !path_has_args(p) => match cx.typeck_results().qpath_res(p, hir_id) {\n                    Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => Some((hir_id, id, i)),\n                    _ => None,\n                },\n                _ => None,\n            }\n            && let count = needless_borrow_count(\n                cx,\n                &mut self.possible_borrowers,\n                fn_id,\n                cx.typeck_results().node_args(hir_id),\n                i,\n                param_ty,\n                expr,\n                self.msrv,\n            )\n            && count != 0\n        {\n            span_lint_and_then(\n                cx,\n                NEEDLESS_BORROWS_FOR_GENERIC_ARGS,\n                expr.span,\n                \"the borrowed expression implements the required traits\",\n                |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let snip_span = peel_n_hir_expr_refs(expr, count).0.span;\n                    let snip = snippet_with_context(cx, snip_span, expr.span.ctxt(), \"..\", &mut app).0;\n                    diag.span_suggestion(expr.span, \"change this to\", snip.into_owned(), app);\n                },\n            );\n        }\n    }\n\n    fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'_>) {\n        if self\n            .possible_borrowers\n            .last()\n            .is_some_and(|&(local_def_id, _)| local_def_id == cx.tcx.hir_body_owner_def_id(body.id()))\n        {\n            self.possible_borrowers.pop();\n        }\n    }\n}\n\nfn path_has_args(p: &QPath<'_>) -> bool {\n    match *p {\n        QPath::Resolved(_, Path { segments: [.., s], .. }) | QPath::TypeRelative(_, s) => s.args.is_some(),\n        QPath::Resolved(..) => false,\n    }\n}\n\n/// Checks for the number of borrow expressions which can be removed from the given expression\n/// where the expression is used as an argument to a function expecting a generic type.\n///\n/// The following constraints will be checked:\n/// * The borrowed expression meets all the generic type's constraints.\n/// * The generic type appears only once in the functions signature.\n/// * The borrowed value is:\n///   - `Copy` itself, or\n///   - the only use of a mutable reference, or\n///   - not a variable (created by a function call)\n#[expect(clippy::too_many_arguments, clippy::too_many_lines)]\nfn needless_borrow_count<'tcx>(\n    cx: &LateContext<'tcx>,\n    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,\n    fn_id: DefId,\n    callee_args: ty::GenericArgsRef<'tcx>,\n    arg_index: usize,\n    param_ty: ParamTy,\n    mut expr: &Expr<'tcx>,\n    msrv: Msrv,\n) -> usize {\n    let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();\n    let sized_trait_def_id = cx.tcx.lang_items().sized_trait();\n    let meta_sized_trait_def_id = cx.tcx.lang_items().meta_sized_trait();\n    let drop_trait_def_id = cx.tcx.lang_items().drop_trait();\n\n    let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();\n    let predicates = cx.tcx.param_env(fn_id).caller_bounds();\n    let projection_predicates = predicates\n        .iter()\n        .filter_map(|predicate| {\n            if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() {\n                Some(projection_predicate)\n            } else {\n                None\n            }\n        })\n        .collect::<Vec<_>>();\n\n    let mut trait_with_ref_mut_self_method = false;\n\n    // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return.\n    if predicates\n        .iter()\n        .filter_map(|predicate| {\n            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()\n                && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)\n            {\n                Some(trait_predicate.trait_ref.def_id)\n            } else {\n                None\n            }\n        })\n        .inspect(|trait_def_id| {\n            trait_with_ref_mut_self_method |= has_ref_mut_self_method(cx, *trait_def_id);\n        })\n        .all(|trait_def_id| {\n            Some(trait_def_id) == destruct_trait_def_id\n                || Some(trait_def_id) == sized_trait_def_id\n                || Some(trait_def_id) == meta_sized_trait_def_id\n                || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)\n        })\n    {\n        return 0;\n    }\n\n    // See:\n    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201\n    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232\n    if projection_predicates\n        .iter()\n        .any(|projection_predicate| is_mixed_projection_predicate(cx, fn_id, projection_predicate))\n    {\n        return 0;\n    }\n\n    // `args_with_referent_ty` can be constructed outside of `check_referent` because the same\n    // elements are modified each time `check_referent` is called.\n    let mut args_with_referent_ty = callee_args.to_vec();\n\n    let mut check_reference_and_referent = |reference: &Expr<'tcx>, referent: &Expr<'tcx>| {\n        if let ExprKind::Field(base, _) = &referent.kind\n            && let base_ty = cx.typeck_results().expr_ty(base)\n            && drop_trait_def_id.is_some_and(|id| implements_trait(cx, base_ty, id, &[]))\n        {\n            return false;\n        }\n\n        let referent_ty = cx.typeck_results().expr_ty(referent);\n\n        if !(is_copy(cx, referent_ty)\n            || referent_ty.is_ref() && referent_used_exactly_once(cx, possible_borrowers, reference)\n            || matches!(referent.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)))\n        {\n            return false;\n        }\n\n        // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321\n        if trait_with_ref_mut_self_method && !matches!(referent_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {\n            return false;\n        }\n\n        if !replace_types(\n            cx,\n            param_ty,\n            referent_ty,\n            fn_sig,\n            arg_index,\n            &projection_predicates,\n            &mut args_with_referent_ty,\n        ) {\n            return false;\n        }\n\n        predicates.iter().all(|predicate| {\n            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()\n                && cx\n                    .tcx\n                    .is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)\n                && let ty::Param(param_ty) = trait_predicate.self_ty().kind()\n                && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].kind()\n                && ty.is_array()\n                && !msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR)\n            {\n                return false;\n            }\n\n            let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty[..]);\n            let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);\n            let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());\n            infcx.predicate_must_hold_modulo_regions(&obligation)\n        })\n    };\n\n    let mut count = 0;\n    while let ExprKind::AddrOf(_, _, referent) = expr.kind {\n        if !check_reference_and_referent(expr, referent) {\n            break;\n        }\n        expr = referent;\n        count += 1;\n    }\n    count\n}\n\nfn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {\n    cx.tcx\n        .associated_items(trait_def_id)\n        .in_definition_order()\n        .any(|assoc_item| {\n            if assoc_item.is_method() {\n                let self_ty = cx\n                    .tcx\n                    .fn_sig(assoc_item.def_id)\n                    .instantiate_identity()\n                    .skip_binder()\n                    .inputs()[0];\n                matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))\n            } else {\n                false\n            }\n        })\n}\n\nfn is_mixed_projection_predicate<'tcx>(\n    cx: &LateContext<'tcx>,\n    callee_def_id: DefId,\n    projection_predicate: &ProjectionPredicate<'tcx>,\n) -> bool {\n    let generics = cx.tcx.generics_of(callee_def_id);\n    // The predicate requires the projected type to equal a type parameter from the parent context.\n    if let Some(term_ty) = projection_predicate.term.as_type()\n        && let ty::Param(term_param_ty) = term_ty.kind()\n        && (term_param_ty.index as usize) < generics.parent_count\n    {\n        // The inner-most self type is a type parameter from the current function.\n        let mut projection_term = projection_predicate.projection_term;\n        loop {\n            match *projection_term.self_ty().kind() {\n                ty::Alias(ty::Projection, inner_projection_ty) => {\n                    projection_term = inner_projection_ty.into();\n                },\n                ty::Param(param_ty) => {\n                    return (param_ty.index as usize) >= generics.parent_count;\n                },\n                _ => {\n                    return false;\n                },\n            }\n        }\n    } else {\n        false\n    }\n}\n\nfn referent_used_exactly_once<'tcx>(\n    cx: &LateContext<'tcx>,\n    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,\n    reference: &Expr<'tcx>,\n) -> bool {\n    if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id)\n        && let Some(local) = expr_local(cx.tcx, reference)\n        && let [location] = *local_assignments(mir, local).as_slice()\n        && let block_data = &mir.basic_blocks[location.block]\n        && let Some(statement) = block_data.statements.get(location.statement_index)\n        && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind\n        && !place.is_indirect_first_projection()\n    {\n        let body_owner_local_def_id = cx.tcx.hir_enclosing_body_owner(reference.hir_id);\n        if possible_borrowers\n            .last()\n            .is_none_or(|&(local_def_id, _)| local_def_id != body_owner_local_def_id)\n        {\n            possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir)));\n        }\n        let possible_borrower = &mut possible_borrowers.last_mut().unwrap().1;\n        // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is\n        // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of\n        // itself. See the comment in that method for an explanation as to why.\n        possible_borrower.bounded_borrowers(&[local], &[local, place.local], place.local, location)\n            && used_exactly_once(mir, place.local).unwrap_or(false)\n    } else {\n        false\n    }\n}\n\n// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting\n// projected type that is a type parameter. Returns `false` if replacing the types would have an\n// effect on the function signature beyond substituting `new_ty` for `param_ty`.\n// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757\nfn replace_types<'tcx>(\n    cx: &LateContext<'tcx>,\n    param_ty: ParamTy,\n    new_ty: Ty<'tcx>,\n    fn_sig: FnSig<'tcx>,\n    arg_index: usize,\n    projection_predicates: &[ProjectionPredicate<'tcx>],\n    args: &mut [GenericArg<'tcx>],\n) -> bool {\n    let mut replaced = DenseBitSet::new_empty(args.len());\n\n    let mut deque = VecDeque::with_capacity(args.len());\n    deque.push_back((param_ty, new_ty));\n\n    while let Some((param_ty, new_ty)) = deque.pop_front() {\n        // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.\n        if !fn_sig\n            .inputs_and_output\n            .iter()\n            .enumerate()\n            .all(|(i, ty)| (replaced.is_empty() && i == arg_index) || !ty.contains(param_ty.to_ty(cx.tcx)))\n        {\n            return false;\n        }\n\n        args[param_ty.index as usize] = GenericArg::from(new_ty);\n\n        // The `replaced.insert(...)` check provides some protection against infinite loops.\n        if replaced.insert(param_ty.index) {\n            for projection_predicate in projection_predicates {\n                if projection_predicate.projection_term.self_ty() == param_ty.to_ty(cx.tcx)\n                    && let Some(term_ty) = projection_predicate.term.as_type()\n                    && let ty::Param(term_param_ty) = term_ty.kind()\n                {\n                    let projection = projection_predicate\n                        .projection_term\n                        .with_replaced_self_ty(cx.tcx, new_ty)\n                        .expect_ty(cx.tcx)\n                        .to_ty(cx.tcx);\n\n                    if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), projection)\n                        && args[term_param_ty.index as usize] != GenericArg::from(projected_ty)\n                    {\n                        deque.push_back((*term_param_ty, projected_ty));\n                    }\n                }\n            }\n        }\n    }\n\n    true\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_continue.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::higher;\nuse clippy_utils::source::{indent_of, snippet_block, snippet_with_context};\nuse rustc_ast::Label;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind, HirId, LoopSource, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{ExpnKind, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// The lint checks for `if`-statements appearing in loops\n    /// that contain a `continue` statement in either their main blocks or their\n    /// `else`-blocks, when omitting the `else`-block possibly with some\n    /// rearrangement of code can make the code easier to understand.\n    /// The lint also checks if the last statement in the loop is a `continue`\n    ///\n    /// ### Why is this bad?\n    /// Having explicit `else` blocks for `if` statements\n    /// containing `continue` in their THEN branch adds unnecessary branching and\n    /// nesting to the code. Having an else block containing just `continue` can\n    /// also be better written by grouping the statements following the whole `if`\n    /// statement within the THEN block and omitting the else block completely.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn condition() -> bool { false }\n    /// # fn update_condition() {}\n    /// # let x = false;\n    /// while condition() {\n    ///     update_condition();\n    ///     if x {\n    ///         // ...\n    ///     } else {\n    ///         continue;\n    ///     }\n    ///     println!(\"Hello, world\");\n    /// }\n    /// ```\n    ///\n    /// Could be rewritten as\n    ///\n    /// ```no_run\n    /// # fn condition() -> bool { false }\n    /// # fn update_condition() {}\n    /// # let x = false;\n    /// while condition() {\n    ///     update_condition();\n    ///     if x {\n    ///         // ...\n    ///         println!(\"Hello, world\");\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// As another example, the following code\n    ///\n    /// ```no_run\n    /// # fn waiting() -> bool { false }\n    /// loop {\n    ///     if waiting() {\n    ///         continue;\n    ///     } else {\n    ///         // Do something useful\n    ///     }\n    ///     # break;\n    /// }\n    /// ```\n    /// Could be rewritten as\n    ///\n    /// ```no_run\n    /// # fn waiting() -> bool { false }\n    /// loop {\n    ///     if waiting() {\n    ///         continue;\n    ///     }\n    ///     // Do something useful\n    ///     # break;\n    /// }\n    /// ```\n    ///\n    /// ```rust\n    /// # use std::io::ErrorKind;\n    ///\n    /// fn foo() -> ErrorKind { ErrorKind::NotFound }\n    /// for _ in 0..10 {\n    ///     match foo() {\n    ///         ErrorKind::NotFound => {\n    ///             eprintln!(\"not found\");\n    ///             continue\n    ///         }\n    ///         ErrorKind::TimedOut => {\n    ///             eprintln!(\"timeout\");\n    ///             continue\n    ///         }\n    ///         _ => {\n    ///             eprintln!(\"other error\");\n    ///             continue\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    /// Could be rewritten as\n    ///\n    ///\n    /// ```rust\n    /// # use std::io::ErrorKind;\n    ///\n    /// fn foo() -> ErrorKind { ErrorKind::NotFound }\n    /// for _ in 0..10 {\n    ///     match foo() {\n    ///         ErrorKind::NotFound => {\n    ///             eprintln!(\"not found\");\n    ///         }\n    ///         ErrorKind::TimedOut => {\n    ///             eprintln!(\"timeout\");\n    ///         }\n    ///         _ => {\n    ///             eprintln!(\"other error\");\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_CONTINUE,\n    pedantic,\n    \"`continue` statements that can be replaced by a rearrangement of code\"\n}\n\ndeclare_lint_pass!(NeedlessContinue => [NEEDLESS_CONTINUE]);\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessContinue {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        // We cannot use `from_expansion` because for loops, while loops and while let loops are desugared\n        // into `loop` expressions.\n        if !matches!(expr.span.ctxt().outer_expn_data().kind, ExpnKind::Macro(..)) {\n            check_and_warn(cx, expr);\n        }\n    }\n}\n\n/* This lint has to mainly deal with two cases of needless continue\n * statements. */\n// Case 1 [Continue inside else block]:\n//\n//     loop {\n//         // region A\n//         if cond {\n//             // region B\n//         } else {\n//             continue;\n//         }\n//         // region C\n//     }\n//\n// This code can better be written as follows:\n//\n//     loop {\n//         // region A\n//         if cond {\n//             // region B\n//             // region C\n//         }\n//     }\n//\n// Case 2 [Continue inside then block]:\n//\n//     loop {\n//       // region A\n//       if cond {\n//           continue;\n//           // potentially more code here.\n//       } else {\n//           // region B\n//       }\n//       // region C\n//     }\n//\n//\n// This snippet can be refactored to:\n//\n//     loop {\n//       // region A\n//       if !cond {\n//           // region B\n//           // region C\n//       }\n//     }\n//\n\n/// Given an expression, returns true if either of the following is true\n///\n/// - The expression is a `continue` node.\n/// - The expression node is a block with the first statement being a `continue`.\nfn needless_continue_in_else(else_expr: &Expr<'_>, label: Option<&Label>) -> bool {\n    match else_expr.kind {\n        ExprKind::Block(else_block, _) => is_first_block_stmt_continue(else_block, label),\n        ExprKind::Continue(l) => compare_labels(label, l.label.as_ref()),\n        _ => false,\n    }\n}\n\nfn is_first_block_stmt_continue(block: &Block<'_>, label: Option<&Label>) -> bool {\n    block.stmts.first().is_some_and(|stmt| match stmt.kind {\n        StmtKind::Semi(e) | StmtKind::Expr(e) => {\n            if let ExprKind::Continue(l) = e.kind {\n                compare_labels(label, l.label.as_ref())\n            } else {\n                false\n            }\n        },\n        _ => false,\n    })\n}\n\n/// If the `continue` has a label, check it matches the label of the loop.\nfn compare_labels(loop_label: Option<&Label>, continue_label: Option<&Label>) -> bool {\n    match (loop_label, continue_label) {\n        // `loop { continue; }` or `'a loop { continue; }`\n        (_, None) => true,\n        // `loop { continue 'a; }`\n        (None, _) => false,\n        // `'a loop { continue 'a; }` or `'a loop { continue 'b; }`\n        (Some(x), Some(y)) => x.ident == y.ident,\n    }\n}\n\n/// If `expr` is a loop expression (while/while let/for/loop), calls `func` with\n/// the HIR object representing the loop block of `expr`.\nfn with_loop_block<F>(expr: &Expr<'_>, mut func: F)\nwhere\n    F: FnMut(&Block<'_>, Option<&Label>),\n{\n    if let Some(higher::ForLoop { body, label, .. }) = higher::ForLoop::hir(expr)\n        && let ExprKind::Block(block, _) = &body.kind\n    {\n        func(block, label.as_ref());\n        return;\n    }\n\n    if let Some(higher::While { body, label, .. }) = higher::While::hir(expr)\n        && let ExprKind::Block(block, _) = &body.kind\n    {\n        func(block, label.as_ref());\n        return;\n    }\n\n    if let Some(higher::WhileLet { if_then, label, .. }) = higher::WhileLet::hir(expr)\n        && let ExprKind::Block(block, _) = &if_then.kind\n    {\n        func(block, label.as_ref());\n        return;\n    }\n\n    if let ExprKind::Loop(block, label, LoopSource::Loop, ..) = expr.kind {\n        func(block, label.as_ref());\n    }\n}\n\n/// If `stmt` is an if expression node with an `else` branch, calls func with\n/// the\n/// following:\n///\n/// - The `if` expression itself,\n/// - The `if` condition expression,\n/// - The `then` block, and\n/// - The `else` expression.\nfn with_if_expr<F>(expr: &Expr<'_>, mut func: F)\nwhere\n    F: FnMut(&Expr<'_>, &Expr<'_>, &Block<'_>, &Expr<'_>),\n{\n    if let Some(higher::If {\n        cond,\n        then,\n        r#else: Some(r#else),\n    }) = higher::If::hir(expr)\n        && let ExprKind::Block(then, _) = then.kind\n    {\n        func(expr, cond, then, r#else);\n    }\n}\n\n/// A type to distinguish between the two distinct cases this lint handles.\n#[derive(Copy, Clone, Debug)]\nenum LintType {\n    ContinueInsideElseBlock,\n    ContinueInsideThenBlock,\n}\n\n/// Data we pass around for construction of help messages.\n#[derive(Debug)]\nstruct LintData<'hir> {\n    /// The `if` expression encountered in the above loop.\n    if_expr: &'hir Expr<'hir>,\n    /// The condition expression for the above `if`.\n    if_cond: &'hir Expr<'hir>,\n    /// The `then` block of the `if` statement.\n    if_block: &'hir Block<'hir>,\n    /// The `else` block of the `if` statement.\n    /// Note that we only work with `if` exprs that have an `else` branch.\n    else_expr: &'hir Expr<'hir>,\n    /// The 0-based index of the `if` statement in the containing loop block.\n    stmt_idx: Option<usize>,\n    /// The statements of the loop block.\n    loop_block: &'hir Block<'hir>,\n}\n\nconst MSG_REDUNDANT_CONTINUE_EXPRESSION: &str = \"this `continue` expression is redundant\";\n\nconst MSG_REDUNDANT_ELSE_BLOCK: &str = \"this `else` block is redundant\";\n\nconst MSG_ELSE_BLOCK_NOT_NEEDED: &str = \"there is no need for an explicit `else` block for this `if` \\\n                                         expression\";\n\nconst DROP_ELSE_BLOCK_AND_MERGE_MSG: &str = \"consider dropping the `else` clause and merging the code that \\\n                                             follows (in the loop) with the `if` block\";\n\nconst DROP_ELSE_BLOCK_MSG: &str = \"consider dropping the `else` clause\";\n\nconst DROP_CONTINUE_EXPRESSION_MSG: &str = \"consider dropping the `continue` expression\";\n\nfn emit_warning(cx: &LateContext<'_>, data: &LintData<'_>, header: &str, typ: LintType) {\n    // snip    is the whole *help* message that appears after the warning.\n    // message is the warning message.\n    // expr    is the expression which the lint warning message refers to.\n    let (snip, message, expr) = match typ {\n        LintType::ContinueInsideElseBlock => (\n            suggestion_snippet_for_continue_inside_else(cx, data),\n            MSG_REDUNDANT_ELSE_BLOCK,\n            data.else_expr,\n        ),\n        LintType::ContinueInsideThenBlock => (\n            suggestion_snippet_for_continue_inside_if(cx, data),\n            MSG_ELSE_BLOCK_NOT_NEEDED,\n            data.if_expr,\n        ),\n    };\n    span_lint_hir_and_then(cx, NEEDLESS_CONTINUE, expr.hir_id, expr.span, message, |diag| {\n        diag.help(format!(\"{header}\\n{snip}\"));\n    });\n}\n\nfn suggestion_snippet_for_continue_inside_if(cx: &LateContext<'_>, data: &LintData<'_>) -> String {\n    let mut applicability = Applicability::MachineApplicable;\n    let (cond_code, _) = snippet_with_context(\n        cx,\n        data.if_cond.span,\n        data.if_expr.span.ctxt(),\n        \"..\",\n        &mut applicability,\n    );\n\n    let continue_code = snippet_block(cx, data.if_block.span, \"..\", Some(data.if_expr.span));\n\n    let else_code = snippet_block(cx, data.else_expr.span, \"..\", Some(data.if_expr.span));\n\n    let indent_if = indent_of(cx, data.if_expr.span).unwrap_or(0);\n    format!(\n        \"{indent}if {cond_code} {continue_code}\\n{indent}{else_code}\",\n        indent = \" \".repeat(indent_if),\n    )\n}\n\nfn suggestion_snippet_for_continue_inside_else(cx: &LateContext<'_>, data: &LintData<'_>) -> String {\n    let mut applicability = Applicability::MachineApplicable;\n    let (cond_code, _) = snippet_with_context(\n        cx,\n        data.if_cond.span,\n        data.if_expr.span.ctxt(),\n        \"..\",\n        &mut applicability,\n    );\n\n    // Region B\n    let block_code = erode_from_back(&snippet_block(cx, data.if_block.span, \"..\", Some(data.if_expr.span)));\n\n    // Region C\n    // These is the code in the loop block that follows the if/else construction\n    // we are complaining about. We want to pull all of this code into the\n    // `then` block of the `if` statement.\n    let indent = span_of_first_expr_in_block(data.if_block)\n        .and_then(|span| indent_of(cx, span))\n        .unwrap_or(0);\n    let to_annex = if let Some(stmt_idx) = data.stmt_idx {\n        let mut lines = data.loop_block.stmts[stmt_idx + 1..]\n            .iter()\n            .map(|stmt| {\n                let span = cx.sess().source_map().stmt_span(stmt.span, data.loop_block.span);\n                let snip = snippet_block(cx, span, \"..\", None);\n                snip.lines()\n                    .map(|line| format!(\"{}{line}\", \" \".repeat(indent)))\n                    .collect::<Vec<_>>()\n                    .join(\"\\n\")\n            })\n            .collect::<Vec<_>>();\n        if let Some(expr) = data.loop_block.expr {\n            let span = expr.span;\n            let snip = snippet_block(cx, span, \"..\", None);\n            let expr_lines = snip\n                .lines()\n                .map(|line| format!(\"{}{line}\", \" \".repeat(indent)))\n                .collect::<Vec<_>>()\n                .join(\"\\n\");\n            lines.push(expr_lines);\n        }\n        lines.join(\"\\n\")\n    } else {\n        String::new()\n    };\n\n    let indent_if = indent_of(cx, data.if_expr.span).unwrap_or(0);\n    format!(\n        \"{indent_if}if {cond_code} {block_code}\\n{indent}// merged code follows:\\n{to_annex}\\n{indent_if}}}\",\n        indent = \" \".repeat(indent),\n        indent_if = \" \".repeat(indent_if),\n    )\n}\n\nfn check_last_stmt_in_expr<F>(cx: &LateContext<'_>, inner_expr: &Expr<'_>, func: &F)\nwhere\n    F: Fn(HirId, Option<&Label>, Span),\n{\n    match inner_expr.kind {\n        ExprKind::Continue(continue_label) => {\n            func(inner_expr.hir_id, continue_label.label.as_ref(), inner_expr.span);\n        },\n        ExprKind::If(_, then_block, else_block) if let ExprKind::Block(then_block, _) = then_block.kind => {\n            check_last_stmt_in_block(cx, then_block, func);\n            if let Some(else_block) = else_block {\n                check_last_stmt_in_expr(cx, else_block, func);\n            }\n        },\n        ExprKind::Match(_, arms, _) => {\n            let match_ty = cx.typeck_results().expr_ty(inner_expr);\n            if !match_ty.is_unit() && !match_ty.is_never() {\n                return;\n            }\n            for arm in arms {\n                check_last_stmt_in_expr(cx, arm.body, func);\n            }\n        },\n        ExprKind::Block(b, _) => {\n            check_last_stmt_in_block(cx, b, func);\n        },\n        _ => {},\n    }\n}\n\nfn check_last_stmt_in_block<F>(cx: &LateContext<'_>, b: &Block<'_>, func: &F)\nwhere\n    F: Fn(HirId, Option<&Label>, Span),\n{\n    if let Some(expr) = b.expr {\n        check_last_stmt_in_expr(cx, expr, func);\n        return;\n    }\n\n    if let Some(last_stmt) = b.stmts.last()\n        && let StmtKind::Expr(inner_expr) | StmtKind::Semi(inner_expr) = last_stmt.kind\n    {\n        check_last_stmt_in_expr(cx, inner_expr, func);\n    }\n}\n\nfn check_and_warn(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    with_loop_block(expr, |loop_block, label| {\n        let p = |continue_hir_id, continue_label: Option<&Label>, span: Span| {\n            if compare_labels(label, continue_label) {\n                span_lint_hir_and_then(\n                    cx,\n                    NEEDLESS_CONTINUE,\n                    continue_hir_id,\n                    span,\n                    MSG_REDUNDANT_CONTINUE_EXPRESSION,\n                    |diag| {\n                        diag.help(DROP_CONTINUE_EXPRESSION_MSG);\n                    },\n                );\n            }\n        };\n\n        let stmts = loop_block.stmts;\n        for (i, stmt) in stmts.iter().enumerate() {\n            let mut maybe_emitted_in_if = false;\n            if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind {\n                with_if_expr(expr, |if_expr, cond, then_block, else_expr| {\n                    let data = &LintData {\n                        if_expr,\n                        if_cond: cond,\n                        if_block: then_block,\n                        else_expr,\n                        stmt_idx: Some(i),\n                        loop_block,\n                    };\n\n                    maybe_emitted_in_if = true;\n                    if needless_continue_in_else(else_expr, label) {\n                        emit_warning(\n                            cx,\n                            data,\n                            DROP_ELSE_BLOCK_AND_MERGE_MSG,\n                            LintType::ContinueInsideElseBlock,\n                        );\n                    } else if is_first_block_stmt_continue(then_block, label) {\n                        emit_warning(cx, data, DROP_ELSE_BLOCK_MSG, LintType::ContinueInsideThenBlock);\n                    } else {\n                        maybe_emitted_in_if = false;\n                    }\n                });\n            }\n\n            if i == stmts.len() - 1 && loop_block.expr.is_none() && !maybe_emitted_in_if {\n                check_last_stmt_in_block(cx, loop_block, &p);\n            }\n        }\n\n        if let Some(expr) = loop_block.expr {\n            let mut maybe_emitted_in_if = false;\n\n            with_if_expr(expr, |if_expr, cond, then_block, else_expr| {\n                let data = &LintData {\n                    if_expr,\n                    if_cond: cond,\n                    if_block: then_block,\n                    else_expr,\n                    stmt_idx: None,\n                    loop_block,\n                };\n\n                maybe_emitted_in_if = true;\n                if needless_continue_in_else(else_expr, label) {\n                    emit_warning(\n                        cx,\n                        data,\n                        DROP_ELSE_BLOCK_AND_MERGE_MSG,\n                        LintType::ContinueInsideElseBlock,\n                    );\n                } else if is_first_block_stmt_continue(then_block, label) {\n                    emit_warning(cx, data, DROP_ELSE_BLOCK_MSG, LintType::ContinueInsideThenBlock);\n                } else {\n                    maybe_emitted_in_if = false;\n                }\n            });\n\n            if !maybe_emitted_in_if {\n                check_last_stmt_in_block(cx, loop_block, &p);\n            }\n        }\n    });\n}\n\n/// Eats at `s` from the end till a closing brace `}` is encountered, and then continues eating\n/// till a non-whitespace character is found.  e.g., the string. If no closing `}` is present, the\n/// string will be preserved.\n///\n/// ```no_run\n/// {\n///     let x = 5;\n/// }\n/// ```\n///\n/// is transformed to\n///\n/// ```text\n///     {\n///         let x = 5;\n/// ```\n#[must_use]\nfn erode_from_back(s: &str) -> String {\n    let mut ret = s.to_string();\n    while ret.pop().is_some_and(|c| c != '}') {}\n    while let Some(c) = ret.pop() {\n        if !c.is_whitespace() {\n            ret.push(c);\n            break;\n        }\n    }\n    if ret.is_empty() { s.to_string() } else { ret }\n}\n\nfn span_of_first_expr_in_block(block: &Block<'_>) -> Option<Span> {\n    block\n        .stmts\n        .first()\n        .map(|stmt| stmt.span)\n        .or(block.expr.map(|expr| expr.span))\n}\n\n#[cfg(test)]\nmod test {\n    use super::erode_from_back;\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_erode_from_back() {\n        let input = \"\\\n{\n    let x = 5;\n    let y = format!(\\\"{}\\\", 42);\n}\";\n\n        let expected = \"\\\n{\n    let x = 5;\n    let y = format!(\\\"{}\\\", 42);\";\n\n        let got = erode_from_back(input);\n        assert_eq!(expected, got);\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_erode_from_back_no_brace() {\n        let input = \"\\\nlet x = 5;\nlet y = something();\n\";\n        let expected = input;\n        let got = erode_from_back(input);\n        assert_eq!(expected, got);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_else.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{IntoSpan, SpanRangeExt};\nuse rustc_ast::ast::{Expr, ExprKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for empty `else` branches.\n    ///\n    /// ### Why is this bad?\n    /// An empty else branch does nothing and can be removed.\n    ///\n    /// ### Example\n    /// ```no_run\n    ///# fn check() -> bool { true }\n    /// if check() {\n    ///     println!(\"Check successful!\");\n    /// } else {\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    ///# fn check() -> bool { true }\n    /// if check() {\n    ///     println!(\"Check successful!\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub NEEDLESS_ELSE,\n    style,\n    \"empty else branch\"\n}\n\ndeclare_lint_pass!(NeedlessElse => [NEEDLESS_ELSE]);\n\nimpl EarlyLintPass for NeedlessElse {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::If(_, then_block, Some(else_clause)) = &expr.kind\n            && let ExprKind::Block(block, _) = &else_clause.kind\n            && !expr.span.from_expansion()\n            && !else_clause.span.from_expansion()\n            && block.stmts.is_empty()\n            && let range = (then_block.span.hi()..expr.span.hi()).trim_start(cx)\n            && range.clone().check_source_text(cx, |src| {\n                // Ignore else blocks that contain comments or #[cfg]s\n                !src.contains(['/', '#'])\n            })\n        {\n            span_lint_and_sugg(\n                cx,\n                NEEDLESS_ELSE,\n                range.with_ctxt(expr.span.ctxt()),\n                \"this `else` branch is empty\",\n                \"you can remove it\",\n                String::new(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_for_each.rs",
    "content": "use clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{Block, BlockCheckMode, Closure, Expr, ExprKind, Stmt, StmtKind, TyKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::sym;\nuse clippy_utils::ty::has_iter_method;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `for_each` that would be more simply written as a\n    /// `for` loop.\n    ///\n    /// ### Why is this bad?\n    /// `for_each` may be used after applying iterator transformers like\n    /// `filter` for better readability and performance. It may also be used to fit a simple\n    /// operation on one line.\n    /// But when none of these apply, a simple `for` loop is more idiomatic.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let v = vec![0, 1, 2];\n    /// v.iter().for_each(|elem| {\n    ///     println!(\"{elem}\");\n    /// })\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let v = vec![0, 1, 2];\n    /// for elem in &v {\n    ///     println!(\"{elem}\");\n    /// }\n    /// ```\n    ///\n    /// ### Known Problems\n    /// When doing things such as:\n    /// ```ignore\n    /// let v = vec![0, 1, 2];\n    /// v.iter().for_each(|elem| unsafe {\n    ///     libc::printf(c\"%d\\n\".as_ptr(), elem);\n    /// });\n    /// ```\n    /// This lint will not trigger.\n    #[clippy::version = \"1.53.0\"]\n    pub NEEDLESS_FOR_EACH,\n    pedantic,\n    \"using `for_each` where a `for` loop would be simpler\"\n}\n\ndeclare_lint_pass!(NeedlessForEach => [NEEDLESS_FOR_EACH]);\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessForEach {\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind {\n            check_expr(cx, expr, stmt.span);\n        }\n    }\n\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {\n        if let Some(expr) = block.expr {\n            check_expr(cx, expr, expr.span);\n        }\n    }\n}\n\nfn check_expr(cx: &LateContext<'_>, expr: &Expr<'_>, outer_span: Span) {\n    if let ExprKind::MethodCall(method_name, for_each_recv, [for_each_arg], _) = expr.kind\n            && let ExprKind::MethodCall(_, iter_recv, [], _) = for_each_recv.kind\n            // Skip the lint if the call chain is too long. e.g. `v.field.iter().for_each()` or\n            // `v.foo().iter().for_each()` must be skipped.\n            && matches!(\n                iter_recv.kind,\n                ExprKind::Array(..) | ExprKind::Call(..) | ExprKind::Path(..)\n            )\n            && method_name.ident.name == sym::for_each\n            && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n            // Checks the type of the `iter` method receiver is NOT a user defined type.\n            && has_iter_method(cx, cx.typeck_results().expr_ty(iter_recv)).is_some()\n            // Skip the lint if the body is not block because this is simpler than `for` loop.\n            // e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop.\n            && let ExprKind::Closure(&Closure { body, fn_decl, .. }) = for_each_arg.kind\n            && let body = cx.tcx.hir_body(body)\n            // Skip the lint if the body is not safe, so as not to suggest `for … in … unsafe {}`\n            // and suggesting `for … in … { unsafe { } }` is a little ugly.\n            && !matches!(body.value.kind, ExprKind::Block(Block { rules: BlockCheckMode::UnsafeBlock(_), .. }, ..))\n    {\n        let mut applicability = Applicability::MachineApplicable;\n\n        // If any closure parameter has an explicit type specified, applying the lint would necessarily\n        // remove that specification, possibly breaking type inference\n        if fn_decl\n            .inputs\n            .iter()\n            .any(|input| matches!(input.kind, TyKind::Infer(..)))\n        {\n            applicability = Applicability::MaybeIncorrect;\n        }\n\n        let mut ret_collector = RetCollector::default();\n        ret_collector.visit_expr(body.value);\n\n        // Skip the lint if `return` is used in `Loop` in order not to suggest using `'label`.\n        if ret_collector.ret_in_loop {\n            return;\n        }\n\n        let ret_suggs = if ret_collector.spans.is_empty() {\n            None\n        } else {\n            applicability = Applicability::MaybeIncorrect;\n            Some(\n                ret_collector\n                    .spans\n                    .into_iter()\n                    .map(|span| (span, \"continue\".to_string()))\n                    .collect(),\n            )\n        };\n\n        let body_param_sugg = snippet_with_applicability(cx, body.params[0].pat.span, \"..\", &mut applicability);\n        let for_each_rev_sugg = snippet_with_applicability(cx, for_each_recv.span, \"..\", &mut applicability);\n        let (body_value_sugg, is_macro_call) =\n            snippet_with_context(cx, body.value.span, for_each_recv.span.ctxt(), \"..\", &mut applicability);\n\n        let sugg = format!(\n            \"for {} in {} {}\",\n            body_param_sugg,\n            for_each_rev_sugg,\n            if is_macro_call {\n                format!(\"{{ {body_value_sugg}; }}\")\n            } else {\n                match body.value.kind {\n                    ExprKind::Block(block, _) if is_let_desugar(block) => {\n                        format!(\"{{ {body_value_sugg} }}\")\n                    },\n                    ExprKind::Block(_, _) => body_value_sugg.to_string(),\n                    _ => format!(\"{{ {body_value_sugg}; }}\"),\n                }\n            }\n        );\n\n        span_lint_and_then(\n            cx,\n            NEEDLESS_FOR_EACH,\n            outer_span,\n            \"needless use of `for_each`\",\n            |diag| {\n                diag.span_suggestion(outer_span, \"try\", sugg, applicability);\n                if let Some(ret_suggs) = ret_suggs {\n                    diag.multipart_suggestion(\"...and replace `return` with `continue`\", ret_suggs, applicability);\n                }\n            },\n        );\n    }\n}\n\n/// Check if the block is a desugared `_ = expr` statement.\nfn is_let_desugar(block: &Block<'_>) -> bool {\n    matches!(\n        block,\n        Block {\n            stmts: [Stmt {\n                kind: StmtKind::Let(_),\n                ..\n            },],\n            ..\n        }\n    )\n}\n\n/// This type plays two roles.\n/// 1. Collect spans of `return` in the closure body.\n/// 2. Detect use of `return` in `Loop` in the closure body.\n///\n/// NOTE: The functionality of this type is similar to\n/// [`clippy_utils::visitors::find_all_ret_expressions`], but we can't use\n/// `find_all_ret_expressions` instead of this type. The reasons are:\n/// 1. `find_all_ret_expressions` passes the argument of `ExprKind::Ret` to a callback, but what we\n///    need here is `ExprKind::Ret` itself.\n/// 2. We can't trace current loop depth with `find_all_ret_expressions`.\n#[derive(Default)]\nstruct RetCollector {\n    spans: Vec<Span>,\n    ret_in_loop: bool,\n    loop_depth: u16,\n}\n\nimpl Visitor<'_> for RetCollector {\n    fn visit_expr(&mut self, expr: &Expr<'_>) {\n        match expr.kind {\n            ExprKind::Ret(..) => {\n                if self.loop_depth > 0 && !self.ret_in_loop {\n                    self.ret_in_loop = true;\n                }\n\n                self.spans.push(expr.span);\n            },\n\n            ExprKind::Loop(..) => {\n                self.loop_depth += 1;\n                walk_expr(self, expr);\n                self.loop_depth -= 1;\n                return;\n            },\n\n            _ => {},\n        }\n\n        walk_expr(self, expr);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_ifs.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::higher::If;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::source::{SpanRangeExt, walk_span_to_context};\nuse rustc_errors::Applicability;\nuse rustc_hir::{ExprKind, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for empty `if` branches with no else branch.\n    ///\n    /// ### Why is this bad?\n    /// It can be entirely omitted, and often the condition too.\n    ///\n    /// ### Known issues\n    /// This will usually only suggest to remove the `if` statement, not the condition. Other lints\n    /// such as `no_effect` will take care of removing the condition if it's unnecessary.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// if really_expensive_condition(&i) {}\n    /// if really_expensive_condition_with_side_effects(&mut i) {}\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// // <omitted>\n    /// really_expensive_condition_with_side_effects(&mut i);\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub NEEDLESS_IFS,\n    complexity,\n    \"checks for empty if branches\"\n}\n\ndeclare_lint_pass!(NeedlessIfs => [NEEDLESS_IFS]);\n\nimpl LateLintPass<'_> for NeedlessIfs {\n    fn check_stmt<'tcx>(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'tcx>) {\n        if let StmtKind::Expr(expr) = stmt.kind\n            && let Some(If {\n                cond,\n                then,\n                r#else: None,\n            }) = If::hir(expr)\n            && let ExprKind::Block(block, ..) = then.kind\n            && block.stmts.is_empty()\n            && block.expr.is_none()\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && then.span.check_source_text(cx, |src| {\n                // Ignore\n                // - empty macro expansions\n                // - empty reptitions in macro expansions\n                // - comments\n                // - #[cfg]'d out code\n                src.bytes()\n                    .all(|ch| matches!(ch, b'{' | b'}') || ch.is_ascii_whitespace())\n            })\n            && let Some(cond_span) = walk_span_to_context(cond.span, expr.span.ctxt())\n            && let Some(cond_snippet) = cond_span.get_source_text(cx)\n            && !is_from_proc_macro(cx, expr)\n        {\n            span_lint_and_sugg(\n                cx,\n                NEEDLESS_IFS,\n                stmt.span,\n                \"this `if` branch is empty\",\n                \"you can remove it\",\n                if cond.can_have_side_effects() || !cx.tcx.hir_attrs(stmt.hir_id).is_empty() {\n                    // `{ foo }` or `{ foo } && bar` placed into a statement position would be\n                    // interpreted as a block statement, force it to be an expression\n                    if cond_snippet.starts_with('{') {\n                        format!(\"({cond_snippet});\")\n                    } else {\n                        format!(\"{cond_snippet};\")\n                    }\n                } else {\n                    String::new()\n                },\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_late_init.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::{SourceText, SpanRangeExt, snippet};\nuse clippy_utils::ty::needs_ordered_drop;\nuse clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures, is_local_used};\nuse core::ops::ControlFlow;\nuse rustc_errors::{Applicability, MultiSpan};\nuse rustc_hir::{\n    BindingMode, Block, Expr, ExprKind, HirId, LetStmt, LocalSource, MatchSource, Node, Pat, PatKind, Stmt, StmtKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for late initializations that can be replaced by a `let` statement\n    /// with an initializer.\n    ///\n    /// ### Why is this bad?\n    /// Assigning in the `let` statement is less repetitive.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a;\n    /// a = 1;\n    ///\n    /// let b;\n    /// match 3 {\n    ///     0 => b = \"zero\",\n    ///     1 => b = \"one\",\n    ///     _ => b = \"many\",\n    /// }\n    ///\n    /// let c;\n    /// if true {\n    ///     c = 1;\n    /// } else {\n    ///     c = -1;\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let a = 1;\n    ///\n    /// let b = match 3 {\n    ///     0 => \"zero\",\n    ///     1 => \"one\",\n    ///     _ => \"many\",\n    /// };\n    ///\n    /// let c = if true {\n    ///     1\n    /// } else {\n    ///     -1\n    /// };\n    /// ```\n    #[clippy::version = \"1.59.0\"]\n    pub NEEDLESS_LATE_INIT,\n    style,\n    \"late initializations that can be replaced by a `let` statement with an initializer\"\n}\n\ndeclare_lint_pass!(NeedlessLateInit => [NEEDLESS_LATE_INIT]);\n\nfn contains_assign_expr<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) -> bool {\n    for_each_expr(cx, stmt, |e| {\n        if matches!(e.kind, ExprKind::Assign(..)) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\nfn contains_let(cond: &Expr<'_>) -> bool {\n    for_each_expr_without_closures(cond, |e| {\n        if matches!(e.kind, ExprKind::Let(_)) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\nfn stmt_needs_ordered_drop(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {\n    let StmtKind::Let(local) = stmt.kind else {\n        return false;\n    };\n    !local.pat.walk_short(|pat| {\n        if let PatKind::Binding(.., None) = pat.kind {\n            !needs_ordered_drop(cx, cx.typeck_results().pat_ty(pat))\n        } else {\n            true\n        }\n    })\n}\n\n#[derive(Debug)]\nstruct LocalAssign {\n    lhs_id: HirId,\n    rhs_span: Span,\n    span: Span,\n}\n\nimpl LocalAssign {\n    fn from_expr(expr: &Expr<'_>, span: Span) -> Option<Self> {\n        if expr.span.from_expansion() {\n            return None;\n        }\n\n        if let ExprKind::Assign(lhs, rhs, _) = expr.kind {\n            if lhs.span.from_expansion() {\n                return None;\n            }\n\n            Some(Self {\n                lhs_id: lhs.res_local_id()?,\n                rhs_span: rhs.span.source_callsite(),\n                span,\n            })\n        } else {\n            None\n        }\n    }\n\n    fn new<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, binding_id: HirId) -> Option<LocalAssign> {\n        let assign = match expr.kind {\n            ExprKind::Block(Block { expr: Some(expr), .. }, _) => Self::from_expr(expr, expr.span),\n            ExprKind::Block(block, _) => {\n                if let Some((last, other_stmts)) = block.stmts.split_last()\n                    && let StmtKind::Expr(expr) | StmtKind::Semi(expr) = last.kind\n\n                    && let assign = Self::from_expr(expr, last.span)?\n\n                    // avoid visiting if not needed\n                    && assign.lhs_id == binding_id\n                    && other_stmts.iter().all(|stmt| !contains_assign_expr(cx, stmt))\n                {\n                    Some(assign)\n                } else {\n                    None\n                }\n            },\n            ExprKind::Assign(..) => Self::from_expr(expr, expr.span),\n            _ => None,\n        }?;\n\n        if assign.lhs_id == binding_id {\n            Some(assign)\n        } else {\n            None\n        }\n    }\n}\n\nfn assignment_suggestions<'tcx>(\n    cx: &LateContext<'tcx>,\n    binding_id: HirId,\n    exprs: impl IntoIterator<Item = &'tcx Expr<'tcx>>,\n) -> Option<(Applicability, Vec<(Span, String)>)> {\n    let mut assignments = Vec::new();\n\n    for expr in exprs {\n        let ty = cx.typeck_results().expr_ty(expr);\n\n        if ty.is_never() {\n            continue;\n        }\n        if !ty.is_unit() {\n            return None;\n        }\n\n        let assign = LocalAssign::new(cx, expr, binding_id)?;\n\n        assignments.push(assign);\n    }\n\n    let suggestions = assignments\n        .iter()\n        .flat_map(|assignment| {\n            let mut spans = vec![assignment.span.until(assignment.rhs_span)];\n\n            if assignment.rhs_span.hi() != assignment.span.hi() {\n                spans.push(assignment.rhs_span.shrink_to_hi().with_hi(assignment.span.hi()));\n            }\n\n            spans\n        })\n        .map(|span| (span, String::new()))\n        .collect::<Vec<(Span, String)>>();\n\n    match suggestions.len() {\n        // All of `exprs` are never types\n        // https://github.com/rust-lang/rust-clippy/issues/8911\n        0 => None,\n        1 => Some((Applicability::MachineApplicable, suggestions)),\n        // multiple suggestions don't work with rustfix in multipart_suggest\n        // https://github.com/rust-lang/rustfix/issues/141\n        _ => Some((Applicability::Unspecified, suggestions)),\n    }\n}\n\nstruct Usage<'tcx> {\n    stmt: &'tcx Stmt<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    needs_semi: bool,\n}\n\nfn first_usage<'tcx>(\n    cx: &LateContext<'tcx>,\n    binding_id: HirId,\n    local_stmt_id: HirId,\n    block: &'tcx Block<'tcx>,\n) -> Option<Usage<'tcx>> {\n    let significant_drop = needs_ordered_drop(cx, cx.typeck_results().node_type(binding_id));\n\n    block\n        .stmts\n        .iter()\n        .skip_while(|stmt| stmt.hir_id != local_stmt_id)\n        .skip(1)\n        .take_while(|stmt| !significant_drop || !stmt_needs_ordered_drop(cx, stmt))\n        .find(|&stmt| is_local_used(cx, stmt, binding_id))\n        .and_then(|stmt| match stmt.kind {\n            StmtKind::Expr(expr) => Some(Usage {\n                stmt,\n                expr,\n                needs_semi: true,\n            }),\n            StmtKind::Semi(expr) => Some(Usage {\n                stmt,\n                expr,\n                needs_semi: false,\n            }),\n            _ => None,\n        })\n}\n\nfn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) -> Option<SourceText> {\n    let span = local.span.with_hi(match local.ty {\n        // let <pat>: <ty>;\n        // ~~~~~~~~~~~~~~~\n        Some(ty) => ty.span.hi(),\n        // let <pat>;\n        // ~~~~~~~~~\n        None => local.pat.span.hi(),\n    });\n\n    span.get_source_text(cx)\n}\n\nfn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    local: &'tcx LetStmt<'tcx>,\n    local_stmt: &'tcx Stmt<'tcx>,\n    block: &'tcx Block<'tcx>,\n    binding_id: HirId,\n) -> Option<()> {\n    let usage = first_usage(cx, binding_id, local_stmt.hir_id, block)?;\n    let binding_name = cx.tcx.hir_opt_name(binding_id)?;\n    let let_snippet = local_snippet_without_semicolon(cx, local)?;\n\n    match usage.expr.kind {\n        ExprKind::Assign(..) => {\n            let assign = LocalAssign::new(cx, usage.expr, binding_id)?;\n            let mut msg_span = MultiSpan::from_spans(vec![local_stmt.span, assign.span]);\n            msg_span.push_span_label(local_stmt.span, \"created here\");\n            msg_span.push_span_label(assign.span, \"initialised here\");\n\n            span_lint_and_then(\n                cx,\n                NEEDLESS_LATE_INIT,\n                msg_span,\n                \"unneeded late initialization\",\n                |diag| {\n                    diag.multipart_suggestion(\n                        format!(\"move the declaration `{binding_name}` here\"),\n                        vec![\n                            (local_stmt.span, String::new()),\n                            (\n                                assign.span,\n                                let_snippet.to_owned() + \" = \" + &snippet(cx, assign.rhs_span, \"..\"),\n                            ),\n                        ],\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        },\n        ExprKind::If(cond, then_expr, Some(else_expr)) if !contains_let(cond) => {\n            let (applicability, mut suggestions) = assignment_suggestions(cx, binding_id, [then_expr, else_expr])?;\n\n            span_lint_and_then(\n                cx,\n                NEEDLESS_LATE_INIT,\n                local_stmt.span,\n                \"unneeded late initialization\",\n                |diag| {\n                    suggestions.push((local_stmt.span, String::new()));\n                    suggestions.push((usage.stmt.span.shrink_to_lo(), format!(\"{let_snippet} = \")));\n\n                    if usage.needs_semi {\n                        suggestions.push((usage.stmt.span.shrink_to_hi(), \";\".to_owned()));\n                    }\n\n                    diag.multipart_suggestion(\n                        format!(\n                            \"move the declaration `{binding_name}` here and remove the assignments from the branches\"\n                        ),\n                        suggestions,\n                        applicability,\n                    );\n                },\n            );\n        },\n        ExprKind::Match(_, arms, MatchSource::Normal) => {\n            let (applicability, mut suggestions) =\n                assignment_suggestions(cx, binding_id, arms.iter().map(|arm| arm.body))?;\n\n            span_lint_and_then(\n                cx,\n                NEEDLESS_LATE_INIT,\n                local_stmt.span,\n                \"unneeded late initialization\",\n                |diag| {\n                    suggestions.push((local_stmt.span, String::new()));\n                    suggestions.push((usage.stmt.span.shrink_to_lo(), format!(\"{let_snippet} = \")));\n\n                    if usage.needs_semi {\n                        suggestions.push((usage.stmt.span.shrink_to_hi(), \";\".to_owned()));\n                    }\n\n                    diag.multipart_suggestion(\n                        format!(\"move the declaration `{binding_name}` here and remove the assignments from the `match` arms\"),\n                        suggestions,\n                        applicability,\n                    );\n                },\n            );\n        },\n        _ => {},\n    }\n\n    Some(())\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessLateInit {\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {\n        let mut parents = cx.tcx.hir_parent_iter(local.hir_id);\n        if let LetStmt {\n            init: None,\n            pat:\n                Pat {\n                    kind: PatKind::Binding(BindingMode::NONE, binding_id, _, None),\n                    ..\n                },\n            source: LocalSource::Normal,\n            ..\n        } = local\n            && let Some((_, Node::Stmt(local_stmt))) = parents.next()\n            && let Some((_, Node::Block(block))) = parents.next()\n        {\n            check(cx, local, local_stmt, block, *binding_id);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_maybe_sized.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_from_proc_macro;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::{DefId, DefIdMap};\nuse rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicateKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{ClauseKind, PredicatePolarity};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::Ident;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints `?Sized` bounds applied to type parameters that cannot be unsized\n    ///\n    /// ### Why is this bad?\n    /// The `?Sized` bound is misleading because it cannot be satisfied by an\n    /// unsized type\n    ///\n    /// ### Example\n    /// ```rust\n    /// // `T` cannot be unsized because `Clone` requires it to be `Sized`\n    /// fn f<T: Clone + ?Sized>(t: &T) {}\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// fn f<T: Clone>(t: &T) {}\n    ///\n    /// // or choose alternative bounds for `T` so that it can be unsized\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub NEEDLESS_MAYBE_SIZED,\n    suspicious,\n    \"a `?Sized` bound that is unusable due to a `Sized` requirement\"\n}\n\ndeclare_lint_pass!(NeedlessMaybeSized => [NEEDLESS_MAYBE_SIZED]);\n\n#[expect(clippy::struct_field_names)]\n#[derive(Debug)]\nstruct Bound<'tcx> {\n    /// The [`DefId`] of the type parameter the bound refers to\n    param: DefId,\n    ident: Ident,\n\n    trait_bound: &'tcx PolyTraitRef<'tcx>,\n\n    predicate_pos: usize,\n    bound_pos: usize,\n}\n\n/// Finds all of the [`Bound`]s that refer to a type parameter and are not from a macro expansion\nfn type_param_bounds<'tcx>(generics: &'tcx Generics<'tcx>) -> impl Iterator<Item = Bound<'tcx>> {\n    generics\n        .predicates\n        .iter()\n        .enumerate()\n        .filter_map(|(predicate_pos, predicate)| {\n            let WherePredicateKind::BoundPredicate(bound_predicate) = &predicate.kind else {\n                return None;\n            };\n\n            let (param, ident) = bound_predicate.bounded_ty.as_generic_param()?;\n\n            Some(\n                bound_predicate\n                    .bounds\n                    .iter()\n                    .enumerate()\n                    .filter_map(move |(bound_pos, bound)| match bound {\n                        GenericBound::Trait(trait_bound) => Some(Bound {\n                            param,\n                            ident,\n                            trait_bound,\n                            predicate_pos,\n                            bound_pos,\n                        }),\n                        GenericBound::Outlives(_) | GenericBound::Use(..) => None,\n                    })\n                    .filter(|bound| !bound.trait_bound.span.from_expansion()),\n            )\n        })\n        .flatten()\n}\n\n/// Searches the supertraits of the trait referred to by `trait_bound` recursively, returning the\n/// path taken to find a `Sized` bound if one is found\nfn path_to_sized_bound(cx: &LateContext<'_>, trait_bound: &PolyTraitRef<'_>) -> Option<Vec<DefId>> {\n    fn search(cx: &LateContext<'_>, path: &mut Vec<DefId>) -> bool {\n        let trait_def_id = *path.last().unwrap();\n\n        if Some(trait_def_id) == cx.tcx.lang_items().sized_trait() {\n            return true;\n        }\n\n        for (predicate, _) in cx.tcx.explicit_super_predicates_of(trait_def_id).iter_identity_copied() {\n            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()\n                && trait_predicate.polarity == PredicatePolarity::Positive\n                && !path.contains(&trait_predicate.def_id())\n            {\n                path.push(trait_predicate.def_id());\n                if search(cx, path) {\n                    return true;\n                }\n                path.pop();\n            }\n        }\n\n        false\n    }\n\n    let mut path = vec![trait_bound.trait_ref.trait_def_id()?];\n    search(cx, &mut path).then_some(path)\n}\n\nimpl LateLintPass<'_> for NeedlessMaybeSized {\n    fn check_generics(&mut self, cx: &LateContext<'_>, generics: &Generics<'_>) {\n        let Some(sized_trait) = cx.tcx.lang_items().sized_trait() else {\n            return;\n        };\n\n        let maybe_sized_params: DefIdMap<_> = type_param_bounds(generics)\n            .filter(|bound| {\n                bound.trait_bound.trait_ref.trait_def_id() == Some(sized_trait)\n                    && matches!(bound.trait_bound.modifiers.polarity, BoundPolarity::Maybe(_))\n            })\n            .map(|bound| (bound.param, bound))\n            .collect();\n\n        for bound in type_param_bounds(generics) {\n            if bound.trait_bound.modifiers == TraitBoundModifiers::NONE\n                && let Some(sized_bound) = maybe_sized_params.get(&bound.param)\n                && let Some(path) = path_to_sized_bound(cx, bound.trait_bound)\n                && !is_from_proc_macro(cx, bound.trait_bound)\n            {\n                span_lint_and_then(\n                    cx,\n                    NEEDLESS_MAYBE_SIZED,\n                    sized_bound.trait_bound.span,\n                    \"`?Sized` bound is ignored because of a `Sized` requirement\",\n                    |diag| {\n                        let ty_param = sized_bound.ident;\n                        diag.span_note(\n                            bound.trait_bound.span,\n                            format!(\"`{ty_param}` cannot be unsized because of the bound\"),\n                        );\n\n                        for &[current_id, next_id] in path.array_windows() {\n                            let current = cx.tcx.item_name(current_id);\n                            let next = cx.tcx.item_name(next_id);\n                            diag.note(format!(\"...because `{current}` has the bound `{next}`\"));\n                        }\n\n                        diag.span_suggestion_verbose(\n                            generics.span_for_bound_removal(sized_bound.predicate_pos, sized_bound.bound_pos),\n                            \"change the bounds that require `Sized`, or remove the `?Sized` bound\",\n                            \"\",\n                            Applicability::MaybeIncorrect,\n                        );\n                    },\n                );\n\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_parens_on_range_literals.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher;\nuse clippy_utils::source::{snippet, snippet_with_applicability};\n\nuse rustc_ast::ast;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n  /// ### What it does\n  /// The lint checks for parenthesis on literals in range statements that are\n  /// superfluous.\n  ///\n  /// ### Why is this bad?\n  /// Having superfluous parenthesis makes the code less readable\n  /// overhead when reading.\n  ///\n  /// ### Example\n  ///\n  /// ```no_run\n  /// for i in (0)..10 {\n  ///   println!(\"{i}\");\n  /// }\n  /// ```\n  ///\n  /// Use instead:\n  ///\n  /// ```no_run\n  /// for i in 0..10 {\n  ///   println!(\"{i}\");\n  /// }\n  /// ```\n  #[clippy::version = \"1.63.0\"]\n  pub NEEDLESS_PARENS_ON_RANGE_LITERALS,\n  style,\n  \"needless parenthesis on range literals can be removed\"\n}\n\ndeclare_lint_pass!(NeedlessParensOnRangeLiterals => [\n    NEEDLESS_PARENS_ON_RANGE_LITERALS,\n]);\n\nfn snippet_enclosed_in_parenthesis(snippet: &str) -> bool {\n    snippet.starts_with('(') && snippet.ends_with(')')\n}\n\nfn check_for_parens(cx: &LateContext<'_>, e: &Expr<'_>, is_start: bool) {\n    if is_start\n        && let ExprKind::Lit(literal) = e.kind\n        && let ast::LitKind::Float(_sym, ast::LitFloatType::Unsuffixed) = literal.node\n    {\n        // don't check floating point literals on the start expression of a range\n        return;\n    }\n    if let ExprKind::Lit(literal) = e.kind\n        // the indicator that parenthesis surround the literal is that the span of the expression and the literal differ\n        && (literal.span.data().hi - literal.span.data().lo) != (e.span.data().hi - e.span.data().lo)\n        // inspect the source code of the expression for parenthesis\n        && snippet_enclosed_in_parenthesis(&snippet(cx, e.span, \"\"))\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_then(\n            cx,\n            NEEDLESS_PARENS_ON_RANGE_LITERALS,\n            e.span,\n            \"needless parenthesis on range literals can be removed\",\n            |diag| {\n                let suggestion = snippet_with_applicability(cx, literal.span, \"_\", &mut applicability);\n                diag.span_suggestion(e.span, \"try\", suggestion, applicability);\n            },\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessParensOnRangeLiterals {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let Some(higher::Range { start, end, .. }) = higher::Range::hir(cx, expr) {\n            if let Some(start) = start {\n                check_for_parens(cx, start, true);\n            }\n            if let Some(end) = end {\n                check_for_parens(cx, end, false);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_pass_by_ref_mut.rs",
    "content": "use super::needless_pass_by_value::requires_exact_signature;\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::source::HasSession as _;\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{inherits_cfg, is_from_proc_macro, is_self};\nuse core::ops::ControlFlow;\nuse rustc_abi::ExternAbi;\nuse rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{\n    BlockCheckMode, Body, Closure, Expr, ExprKind, FnDecl, HirId, HirIdMap, HirIdSet, Impl, ItemKind, Mutability, Node,\n    PatKind,\n};\nuse rustc_hir_typeck::expr_use_visitor as euv;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir::FakeReadCause;\nuse rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::symbol::kw;\nuse rustc_span::{BytePos, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Check if a `&mut` function argument is actually used mutably.\n    ///\n    /// Be careful if the function is publicly reexported as it would break compatibility with\n    /// users of this function, when the users pass this function as an argument.\n    ///\n    /// ### Why is this bad?\n    /// Less `mut` means less fights with the borrow checker. It can also lead to more\n    /// opportunities for parallelization.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(y: &mut i32) -> i32 {\n    ///     12 + *y\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo(y: &i32) -> i32 {\n    ///     12 + *y\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub NEEDLESS_PASS_BY_REF_MUT,\n    nursery,\n    \"using a `&mut` argument when it's not mutated\"\n}\n\nimpl_lint_pass!(NeedlessPassByRefMut<'_> => [NEEDLESS_PASS_BY_REF_MUT]);\n\npub struct NeedlessPassByRefMut<'tcx> {\n    avoid_breaking_exported_api: bool,\n    used_fn_def_ids: FxHashSet<LocalDefId>,\n    fn_def_ids_to_maybe_unused_mut: FxIndexMap<LocalDefId, Vec<rustc_hir::Ty<'tcx>>>,\n}\n\nimpl NeedlessPassByRefMut<'_> {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n            used_fn_def_ids: FxHashSet::default(),\n            fn_def_ids_to_maybe_unused_mut: FxIndexMap::default(),\n        }\n    }\n}\n\nfn should_skip<'tcx>(\n    cx: &LateContext<'tcx>,\n    input: rustc_hir::Ty<'tcx>,\n    ty: Ty<'_>,\n    arg: &rustc_hir::Param<'_>,\n) -> bool {\n    // We check if this a `&mut`. `ref_mutability` returns `None` if it's not a reference.\n    if !matches!(ty.ref_mutability(), Some(Mutability::Mut)) {\n        return true;\n    }\n\n    if is_self(arg) {\n        // Interestingly enough, `self` arguments make `is_from_proc_macro` return `true`, hence why\n        // we return early here.\n        return false;\n    }\n\n    if let PatKind::Binding(.., name, _) = arg.pat.kind\n        // If it's a potentially unused variable, we don't check it.\n        && (name.name == kw::Underscore || name.as_str().starts_with('_'))\n    {\n        return true;\n    }\n\n    // All spans generated from a proc-macro invocation are the same...\n    is_from_proc_macro(cx, &input)\n}\n\nfn check_closures<'tcx>(\n    ctx: &mut MutablyUsedVariablesCtxt<'tcx>,\n    cx: &LateContext<'tcx>,\n    checked_closures: &mut FxHashSet<LocalDefId>,\n    closures: FxIndexSet<LocalDefId>,\n) {\n    for closure in closures {\n        if !checked_closures.insert(closure) {\n            continue;\n        }\n        ctx.prev_bind = None;\n        ctx.prev_move_to_closure.clear();\n        if let Some(body) = cx\n            .tcx\n            .hir_node_by_def_id(closure)\n            .associated_body()\n            .map(|(_, body_id)| cx.tcx.hir_body(body_id))\n        {\n            euv::ExprUseVisitor::for_clippy(cx, closure, &mut *ctx)\n                .consume_body(body)\n                .into_ok();\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'tcx>,\n        body: &'tcx Body<'_>,\n        span: Span,\n        fn_def_id: LocalDefId,\n    ) {\n        if span.from_expansion() {\n            return;\n        }\n\n        if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(fn_def_id) {\n            return;\n        }\n\n        let hir_id = cx.tcx.local_def_id_to_hir_id(fn_def_id);\n        let is_async = match kind {\n            FnKind::ItemFn(.., header) => {\n                if header.is_unsafe() {\n                    // We don't check unsafe functions.\n                    return;\n                }\n                let attrs = cx.tcx.hir_attrs(hir_id);\n                if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) {\n                    return;\n                }\n                header.is_async()\n            },\n            FnKind::Method(.., sig) => {\n                if sig.header.is_unsafe() {\n                    // We don't check unsafe functions.\n                    return;\n                }\n                sig.header.is_async()\n            },\n            FnKind::Closure => return,\n        };\n\n        // Exclude non-inherent impls\n        if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id)\n            && matches!(\n                item.kind,\n                ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)\n            )\n        {\n            return;\n        }\n\n        let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity();\n        let fn_sig = cx.tcx.liberate_late_bound_regions(fn_def_id.to_def_id(), fn_sig);\n\n        // If there are no `&mut` argument, no need to go any further.\n        let mut it = decl\n            .inputs\n            .iter()\n            .zip(fn_sig.inputs())\n            .zip(body.params)\n            .filter(|&((&input, &ty), arg)| !should_skip(cx, input, ty, arg))\n            .peekable();\n        if it.peek().is_none() {\n            return;\n        }\n        // Collect variables mutably used and spans which will need dereferencings from the\n        // function body.\n        let mutably_used_vars = {\n            let mut ctx = MutablyUsedVariablesCtxt {\n                mutably_used_vars: HirIdSet::default(),\n                prev_bind: None,\n                prev_move_to_closure: HirIdSet::default(),\n                aliases: HirIdMap::default(),\n                async_closures: FxIndexSet::default(),\n                tcx: cx.tcx,\n            };\n            euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx)\n                .consume_body(body)\n                .into_ok();\n\n            let mut checked_closures = FxHashSet::default();\n\n            // We retrieve all the closures declared in the function because they will not be found\n            // by `euv::Delegate`.\n            let mut closures: FxIndexSet<LocalDefId> = FxIndexSet::default();\n            for_each_expr(cx, body, |expr| {\n                if let ExprKind::Closure(closure) = expr.kind {\n                    closures.insert(closure.def_id);\n                }\n                ControlFlow::<()>::Continue(())\n            });\n            check_closures(&mut ctx, cx, &mut checked_closures, closures);\n\n            if is_async {\n                while !ctx.async_closures.is_empty() {\n                    let async_closures = ctx.async_closures.clone();\n                    ctx.async_closures.clear();\n                    check_closures(&mut ctx, cx, &mut checked_closures, async_closures);\n                }\n            }\n            ctx.generate_mutably_used_ids_from_aliases()\n        };\n        for ((&input, &_), arg) in it {\n            // Only take `&mut` arguments.\n            if let PatKind::Binding(_, canonical_id, ..) = arg.pat.kind\n                && !mutably_used_vars.contains(&canonical_id)\n            {\n                self.fn_def_ids_to_maybe_unused_mut\n                    .entry(fn_def_id)\n                    .or_default()\n                    .push(input);\n            }\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        // #11182; do not lint if mutability is required elsewhere\n        if let ExprKind::Path(..) = expr.kind\n            && let ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(expr).kind()\n            && let Some(def_id) = def_id.as_local()\n        {\n            if let Node::Expr(e) = cx.tcx.parent_hir_node(expr.hir_id)\n                && let ExprKind::Call(call, _) = e.kind\n                && call.hir_id == expr.hir_id\n            {\n                return;\n            }\n\n            // We don't need to check each argument individually as you cannot coerce a function\n            // taking `&mut` -> `&`, for some reason, so if we've gotten this far we know it's\n            // passed as a `fn`-like argument (or is unified) and should ignore every \"unused\"\n            // argument entirely\n            self.used_fn_def_ids.insert(def_id);\n        }\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        for (fn_def_id, unused) in self\n            .fn_def_ids_to_maybe_unused_mut\n            .iter()\n            .filter(|(def_id, _)| !self.used_fn_def_ids.contains(def_id))\n        {\n            let mut is_cfged = None;\n            for input in unused {\n                // If the argument is never used mutably, we emit the warning.\n                let sp = input.span;\n                if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind {\n                    let Some(after_mut_span) = cx.sess().source_map().span_extend_to_prev_str(\n                        inner_ty.ty.span.shrink_to_lo(),\n                        \"mut\",\n                        true,\n                        true,\n                    ) else {\n                        return;\n                    };\n                    let mut_span = after_mut_span.with_lo(after_mut_span.lo() - BytePos(3));\n                    let is_cfged = is_cfged.get_or_insert_with(|| inherits_cfg(cx.tcx, *fn_def_id));\n                    span_lint_hir_and_then(\n                        cx,\n                        NEEDLESS_PASS_BY_REF_MUT,\n                        cx.tcx.local_def_id_to_hir_id(*fn_def_id),\n                        sp,\n                        \"this parameter is a mutable reference but is not used mutably\",\n                        |diag| {\n                            diag.span_suggestion(\n                                mut_span,\n                                \"consider removing this `mut`\",\n                                \"\",\n                                Applicability::Unspecified,\n                            );\n                            if cx.effective_visibilities.is_exported(*fn_def_id) {\n                                diag.warn(\"changing this function will impact semver compatibility\");\n                            }\n                            if *is_cfged {\n                                diag.note(\"this is cfg-gated and may require further changes\");\n                            }\n                        },\n                    );\n                }\n            }\n        }\n    }\n}\n\nstruct MutablyUsedVariablesCtxt<'tcx> {\n    mutably_used_vars: HirIdSet,\n    prev_bind: Option<HirId>,\n    /// In async functions, the inner AST is composed of multiple layers until we reach the code\n    /// defined by the user. Because of that, some variables are marked as mutably borrowed even\n    /// though they're not. This field lists the `HirId` that should not be considered as mutable\n    /// use of a variable.\n    prev_move_to_closure: HirIdSet,\n    aliases: HirIdMap<HirId>,\n    async_closures: FxIndexSet<LocalDefId>,\n    tcx: TyCtxt<'tcx>,\n}\n\nimpl MutablyUsedVariablesCtxt<'_> {\n    fn add_mutably_used_var(&mut self, used_id: HirId) {\n        self.mutably_used_vars.insert(used_id);\n    }\n\n    // Because the alias may come after the mutable use of a variable, we need to fill the map at\n    // the end.\n    fn generate_mutably_used_ids_from_aliases(mut self) -> HirIdSet {\n        let all_ids = self.mutably_used_vars.iter().copied().collect::<Vec<_>>();\n        for mut used_id in all_ids {\n            while let Some(id) = self.aliases.get(&used_id) {\n                self.mutably_used_vars.insert(used_id);\n                used_id = *id;\n            }\n            self.mutably_used_vars.insert(used_id);\n        }\n        self.mutably_used_vars\n    }\n\n    fn would_be_alias_cycle(&self, alias: HirId, mut target: HirId) -> bool {\n        while let Some(id) = self.aliases.get(&target) {\n            if *id == alias {\n                return true;\n            }\n            target = *id;\n        }\n        false\n    }\n\n    fn add_alias(&mut self, alias: HirId, target: HirId) {\n        // This is to prevent alias loop.\n        if alias == target || self.would_be_alias_cycle(alias, target) {\n            return;\n        }\n        self.aliases.insert(alias, target);\n    }\n\n    // The goal here is to find if the current scope is unsafe or not. It stops when it finds\n    // a function or an unsafe block.\n    fn is_in_unsafe_block(&self, item: HirId) -> bool {\n        for (parent, node) in self.tcx.hir_parent_iter(item) {\n            if let Some(fn_sig) = self.tcx.hir_fn_sig_by_hir_id(parent) {\n                return fn_sig.header.is_unsafe();\n            } else if let Node::Block(block) = node\n                && matches!(block.rules, BlockCheckMode::UnsafeBlock(_))\n            {\n                return true;\n            }\n        }\n        false\n    }\n}\n\nimpl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {\n    fn consume(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, id: HirId) {\n        if let euv::Place {\n            base:\n                euv::PlaceBase::Local(vid)\n                | euv::PlaceBase::Upvar(UpvarId {\n                    var_path: UpvarPath { hir_id: vid },\n                    ..\n                }),\n            base_ty,\n            ..\n        } = &cmt.place\n        {\n            if let Some(bind_id) = self.prev_bind.take() {\n                if bind_id != *vid {\n                    self.add_alias(bind_id, *vid);\n                }\n            } else if !self.prev_move_to_closure.contains(vid)\n                && matches!(base_ty.ref_mutability(), Some(Mutability::Mut))\n            {\n                self.add_mutably_used_var(*vid);\n            } else if self.is_in_unsafe_block(id) {\n                // If we are in an unsafe block, any operation on this variable must not be warned\n                // upon!\n                self.add_mutably_used_var(*vid);\n            }\n            self.prev_bind = None;\n            // FIXME(rust/#120456) - is `swap_remove` correct?\n            self.prev_move_to_closure.swap_remove(vid);\n        }\n    }\n\n    fn use_cloned(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, id: HirId, borrow: ty::BorrowKind) {\n        self.prev_bind = None;\n        if let euv::Place {\n            base:\n                euv::PlaceBase::Local(vid)\n                | euv::PlaceBase::Upvar(UpvarId {\n                    var_path: UpvarPath { hir_id: vid },\n                    ..\n                }),\n            base_ty,\n            ..\n        } = &cmt.place\n        {\n            // If this is a mutable borrow, it was obviously used mutably so we add it. However\n            // for `UniqueImmBorrow`, it's interesting because if you do: `array[0] = value` inside\n            // a closure, it'll return this variant whereas if you have just an index access, it'll\n            // return `ImmBorrow`. So if there is \"Unique\" and it's a mutable reference, we add it\n            // to the mutably used variables set.\n            if borrow == ty::BorrowKind::Mutable\n                || (borrow == ty::BorrowKind::UniqueImmutable && base_ty.ref_mutability() == Some(Mutability::Mut))\n            {\n                self.add_mutably_used_var(*vid);\n            } else if self.is_in_unsafe_block(id) {\n                // If we are in an unsafe block, any operation on this variable must not be warned\n                // upon!\n                self.add_mutably_used_var(*vid);\n            }\n        } else if borrow == ty::BorrowKind::Immutable\n            // If there is an `async block`, it'll contain a call to a closure which we need to\n            // go into to ensure all \"mutate\" checks are found.\n            && let Node::Expr(Expr {\n                kind:\n                    ExprKind::Call(\n                        _,\n                        [\n                            Expr {\n                                kind: ExprKind::Closure(Closure { def_id, .. }),\n                                ..\n                            },\n                        ],\n                    ),\n                ..\n            }) = self.tcx.hir_node(cmt.hir_id)\n        {\n            self.async_closures.insert(*def_id);\n        }\n    }\n\n    fn mutate(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId) {\n        self.prev_bind = None;\n        if let euv::Place {\n            projections,\n            base:\n                euv::PlaceBase::Local(vid)\n                | euv::PlaceBase::Upvar(UpvarId {\n                    var_path: UpvarPath { hir_id: vid },\n                    ..\n                }),\n            ..\n        } = &cmt.place\n            && !projections.is_empty()\n        {\n            self.add_mutably_used_var(*vid);\n        }\n    }\n\n    fn copy(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, id: HirId) {\n        if let euv::Place {\n            base:\n                euv::PlaceBase::Local(vid)\n                | euv::PlaceBase::Upvar(UpvarId {\n                    var_path: UpvarPath { hir_id: vid },\n                    ..\n                }),\n            ..\n        } = &cmt.place\n            && self.is_in_unsafe_block(id)\n        {\n            self.add_mutably_used_var(*vid);\n        }\n        self.prev_bind = None;\n    }\n\n    fn fake_read(\n        &mut self,\n        cmt: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>,\n        cause: FakeReadCause,\n        _id: HirId,\n    ) {\n        if let euv::Place {\n            base:\n                euv::PlaceBase::Upvar(UpvarId {\n                    var_path: UpvarPath { hir_id: vid },\n                    ..\n                }),\n            ..\n        } = &cmt.place\n            && let FakeReadCause::ForLet(Some(inner)) = cause\n        {\n            // Seems like we are inside an async function. We need to store the closure `DefId`\n            // to go through it afterwards.\n            self.async_closures.insert(inner);\n            self.add_alias(cmt.hir_id, *vid);\n            self.prev_move_to_closure.insert(*vid);\n            self.prev_bind = None;\n        }\n    }\n\n    fn bind(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, id: HirId) {\n        self.prev_bind = Some(id);\n        if let euv::Place {\n            base:\n                euv::PlaceBase::Local(vid)\n                | euv::PlaceBase::Upvar(UpvarId {\n                    var_path: UpvarPath { hir_id: vid },\n                    ..\n                }),\n            ..\n        } = &cmt.place\n            && self.is_in_unsafe_block(id)\n        {\n            self.add_mutably_used_var(*vid);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_pass_by_value.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::{SpanRangeExt, snippet};\nuse clippy_utils::ty::{implements_trait, implements_trait_with_env_from_iter, is_copy};\nuse clippy_utils::visitors::{Descend, for_each_expr_without_closures};\nuse clippy_utils::{is_self, peel_hir_ty_options, strip_pat_refs, sym};\nuse rustc_abi::ExternAbi;\nuse rustc_errors::{Applicability, Diag};\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{\n    Attribute, BindingMode, Body, ExprKind, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability,\n    Node, PatKind, QPath, TyKind,\n};\nuse rustc_hir_typeck::expr_use_visitor as euv;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir::FakeReadCause;\nuse rustc_middle::ty::{self, Ty, TypeVisitableExt};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::symbol::kw;\nuse rustc_span::{Span, Symbol};\nuse rustc_trait_selection::traits;\nuse rustc_trait_selection::traits::misc::type_allowed_to_implement_copy;\n\nuse std::borrow::Cow;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions taking arguments by value, but not\n    /// consuming them in its\n    /// body.\n    ///\n    /// ### Why is this bad?\n    /// Taking arguments by reference is more flexible and can\n    /// sometimes avoid\n    /// unnecessary allocations.\n    ///\n    /// ### Known problems\n    /// * This lint suggests taking an argument by reference,\n    /// however sometimes it is better to let users decide the argument type\n    /// (by using `Borrow` trait, for example), depending on how the function is used.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(v: Vec<i32>) {\n    ///     assert_eq!(v.len(), 42);\n    /// }\n    /// ```\n    /// should be\n    /// ```no_run\n    /// fn foo(v: &[i32]) {\n    ///     assert_eq!(v.len(), 42);\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_PASS_BY_VALUE,\n    pedantic,\n    \"functions taking arguments by value, but not consuming them in its body\"\n}\n\ndeclare_lint_pass!(NeedlessPassByValue => [NEEDLESS_PASS_BY_VALUE]);\n\nmacro_rules! need {\n    ($e: expr) => {\n        if let Some(x) = $e {\n            x\n        } else {\n            return;\n        }\n    };\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {\n    #[expect(clippy::too_many_lines)]\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        span: Span,\n        fn_def_id: LocalDefId,\n    ) {\n        if span.from_expansion() {\n            return;\n        }\n\n        let hir_id = cx.tcx.local_def_id_to_hir_id(fn_def_id);\n\n        match kind {\n            FnKind::ItemFn(.., header) => {\n                let attrs = cx.tcx.hir_attrs(hir_id);\n                if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) {\n                    return;\n                }\n            },\n            FnKind::Method(..) => (),\n            FnKind::Closure => return,\n        }\n\n        // Exclude non-inherent impls\n        if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id)\n            && matches!(\n                item.kind,\n                ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)\n            )\n        {\n            return;\n        }\n\n        // Allow `Borrow` or functions to be taken by value\n        let allowed_traits = [\n            need!(cx.tcx.lang_items().fn_trait()),\n            need!(cx.tcx.lang_items().fn_once_trait()),\n            need!(cx.tcx.lang_items().fn_mut_trait()),\n            need!(cx.tcx.get_diagnostic_item(sym::RangeBounds)),\n        ];\n\n        let sized_trait = need!(cx.tcx.lang_items().sized_trait());\n        let meta_sized_trait = need!(cx.tcx.lang_items().meta_sized_trait());\n\n        let preds = traits::elaborate(cx.tcx, cx.param_env.caller_bounds().iter())\n            .filter(|p| !p.is_global())\n            .filter_map(|pred| {\n                // Note that we do not want to deal with qualified predicates here.\n                match pred.kind().no_bound_vars() {\n                    Some(ty::ClauseKind::Trait(pred))\n                        if pred.def_id() != sized_trait && pred.def_id() != meta_sized_trait =>\n                    {\n                        Some(pred)\n                    },\n                    _ => None,\n                }\n            })\n            .collect::<Vec<_>>();\n\n        // Collect moved variables and spans which will need dereferencing from the\n        // function body.\n        let MovedVariablesCtxt { moved_vars } = {\n            let mut ctx = MovedVariablesCtxt::default();\n            euv::ExprUseVisitor::for_clippy(cx, fn_def_id, &mut ctx)\n                .consume_body(body)\n                .into_ok();\n            ctx\n        };\n\n        let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity();\n        let fn_sig = cx.tcx.liberate_late_bound_regions(fn_def_id.to_def_id(), fn_sig);\n\n        for (idx, ((input, &ty), arg)) in decl.inputs.iter().zip(fn_sig.inputs()).zip(body.params).enumerate() {\n            // All spans generated from a proc-macro invocation are the same...\n            if span == input.span {\n                return;\n            }\n\n            // Ignore `self`s and params whose variable name starts with an underscore\n            if let PatKind::Binding(.., ident, _) = arg.pat.kind {\n                if idx == 0 && ident.name == kw::SelfLower {\n                    continue;\n                }\n                if ident.name.as_str().starts_with('_') {\n                    continue;\n                }\n            }\n\n            //\n            // * Exclude a type that is specifically bounded by `Borrow`.\n            // * Exclude a type whose reference also fulfills its bound. (e.g., `std::convert::AsRef`,\n            //   `serde::Serialize`)\n            let (implements_borrow_trait, all_borrowable_trait) = {\n                let preds = preds.iter().filter(|t| t.self_ty() == ty).collect::<Vec<_>>();\n\n                (\n                    preds.iter().any(|t| cx.tcx.is_diagnostic_item(sym::Borrow, t.def_id())),\n                    !preds.is_empty() && {\n                        let ty_empty_region = Ty::new_imm_ref(cx.tcx, cx.tcx.lifetimes.re_erased, ty);\n                        preds.iter().all(|t| {\n                            let ty_params = t.trait_ref.args.iter().skip(1).collect::<Vec<_>>();\n                            implements_trait(cx, ty_empty_region, t.def_id(), &ty_params)\n                        })\n                    },\n                )\n            };\n\n            if !is_self(arg)\n                && !ty.is_mutable_ptr()\n                && !is_copy(cx, ty)\n                && ty.is_sized(cx.tcx, cx.typing_env())\n                && !allowed_traits.iter().any(|&t| {\n                    implements_trait_with_env_from_iter(\n                        cx.tcx,\n                        cx.typing_env(),\n                        ty,\n                        t,\n                        None,\n                        [None::<ty::GenericArg<'tcx>>],\n                    )\n                })\n                && !implements_borrow_trait\n                && !all_borrowable_trait\n                && let PatKind::Binding(BindingMode(_, Mutability::Not), canonical_id, ..) = arg.pat.kind\n                && !moved_vars.contains(&canonical_id)\n            {\n                // Dereference suggestion\n                let sugg = |diag: &mut Diag<'_, ()>| {\n                    if let ty::Adt(def, ..) = ty.kind()\n                        && let Some(span) = cx.tcx.hir_span_if_local(def.did())\n                        && type_allowed_to_implement_copy(\n                            cx.tcx,\n                            cx.param_env,\n                            ty,\n                            traits::ObligationCause::dummy_with_span(span),\n                            rustc_hir::Safety::Safe,\n                        )\n                        .is_ok()\n                    {\n                        diag.span_help(span, \"or consider marking this type as `Copy`\");\n                    }\n\n                    if ty.is_diag_item(cx, sym::Vec)\n                        && let Some(clone_spans) = get_spans(cx, body, idx, &[(sym::clone, \".to_owned()\")])\n                        && let TyKind::Path(QPath::Resolved(_, path)) = input.kind\n                        && let Some(elem_ty) = path\n                            .segments\n                            .iter()\n                            .find(|seg| seg.ident.name == sym::Vec)\n                            .and_then(|ps| ps.args.as_ref())\n                            .map(|params| {\n                                params\n                                    .args\n                                    .iter()\n                                    .find_map(|arg| match arg {\n                                        GenericArg::Type(ty) => Some(ty),\n                                        _ => None,\n                                    })\n                                    .unwrap()\n                            })\n                    {\n                        let slice_ty = format!(\"&[{}]\", snippet(cx, elem_ty.span, \"_\"));\n                        diag.span_suggestion(\n                            input.span,\n                            \"consider changing the type to\",\n                            slice_ty,\n                            Applicability::Unspecified,\n                        );\n\n                        for (span, suggestion) in clone_spans {\n                            diag.span_suggestion(\n                                span,\n                                span.get_source_text(cx).map_or_else(\n                                    || \"change the call to\".to_owned(),\n                                    |src| format!(\"change `{src}` to\"),\n                                ),\n                                suggestion,\n                                Applicability::Unspecified,\n                            );\n                        }\n\n                        // cannot be destructured, no need for `*` suggestion\n                        return;\n                    }\n\n                    if ty.is_lang_item(cx, LangItem::String)\n                        && let Some(clone_spans) =\n                            get_spans(cx, body, idx, &[(sym::clone, \".to_string()\"), (sym::as_str, \"\")])\n                    {\n                        diag.span_suggestion(\n                            input.span,\n                            \"consider changing the type to\",\n                            \"&str\",\n                            Applicability::Unspecified,\n                        );\n\n                        for (span, suggestion) in clone_spans {\n                            diag.span_suggestion(\n                                span,\n                                span.get_source_text(cx).map_or_else(\n                                    || \"change the call to\".to_owned(),\n                                    |src| format!(\"change `{src}` to\"),\n                                ),\n                                suggestion,\n                                Applicability::Unspecified,\n                            );\n                        }\n\n                        return;\n                    }\n\n                    diag.span_suggestion_verbose(\n                        peel_hir_ty_options(cx, input).span.shrink_to_lo(),\n                        \"consider taking a reference instead\",\n                        '&',\n                        Applicability::MaybeIncorrect,\n                    );\n                };\n\n                span_lint_and_then(\n                    cx,\n                    NEEDLESS_PASS_BY_VALUE,\n                    input.span,\n                    \"this argument is passed by value, but not consumed in the function body\",\n                    sugg,\n                );\n            }\n        }\n    }\n}\n\n/// Functions marked with these attributes must have the exact signature.\npub(crate) fn requires_exact_signature(attrs: &[Attribute]) -> bool {\n    attrs.iter().any(Attribute::is_proc_macro_attr)\n}\n\n#[derive(Default)]\nstruct MovedVariablesCtxt {\n    moved_vars: HirIdSet,\n}\n\nimpl MovedVariablesCtxt {\n    fn move_common(&mut self, cmt: &euv::PlaceWithHirId<'_>) {\n        if let euv::PlaceBase::Local(vid) = cmt.place.base {\n            self.moved_vars.insert(vid);\n        }\n    }\n}\n\nimpl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {\n    fn consume(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _: HirId) {\n        self.move_common(cmt);\n    }\n\n    fn use_cloned(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {}\n\n    fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}\n}\n\nfn get_spans<'tcx>(\n    cx: &LateContext<'tcx>,\n    body: &'tcx Body<'_>,\n    idx: usize,\n    replacements: &[(Symbol, &'static str)],\n) -> Option<Vec<(Span, Cow<'static, str>)>> {\n    if let PatKind::Binding(_, binding_id, _, _) = strip_pat_refs(body.params[idx].pat).kind {\n        extract_clone_suggestions(cx, binding_id, replacements, body)\n    } else {\n        Some(vec![])\n    }\n}\n\nfn extract_clone_suggestions<'tcx>(\n    cx: &LateContext<'tcx>,\n    id: HirId,\n    replace: &[(Symbol, &'static str)],\n    body: &'tcx Body<'_>,\n) -> Option<Vec<(Span, Cow<'static, str>)>> {\n    let mut spans = Vec::new();\n    for_each_expr_without_closures(body, |e| {\n        if let ExprKind::MethodCall(seg, recv, [], _) = e.kind\n            && recv.res_local_id() == Some(id)\n        {\n            if seg.ident.name == sym::capacity {\n                return ControlFlow::Break(());\n            }\n            for &(fn_name, suffix) in replace {\n                if seg.ident.name == fn_name {\n                    spans.push((e.span, snippet(cx, recv.span, \"_\") + suffix));\n                    return ControlFlow::Continue(Descend::No);\n                }\n            }\n        }\n        ControlFlow::Continue(Descend::Yes)\n    })\n    .is_none()\n    .then_some(spans)\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_question_mark.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::res::MaybeQPath;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Block, Body, Expr, ExprKind, LangItem, MatchSource};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Suggests replacing `Ok(x?)` or `Some(x?)` with `x` in return positions where the `?` operator\n    /// is not needed to convert the type of `x`.\n    ///\n    /// ### Why is this bad?\n    /// There's no reason to use `?` to short-circuit when execution of the body will end there anyway.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::num::ParseIntError;\n    /// fn f(s: &str) -> Option<usize> {\n    ///     Some(s.find('x')?)\n    /// }\n    ///\n    /// fn g(s: &str) -> Result<usize, ParseIntError> {\n    ///     Ok(s.parse()?)\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::num::ParseIntError;\n    /// fn f(s: &str) -> Option<usize> {\n    ///     s.find('x')\n    /// }\n    ///\n    /// fn g(s: &str) -> Result<usize, ParseIntError> {\n    ///     s.parse()\n    /// }\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub NEEDLESS_QUESTION_MARK,\n    complexity,\n    \"using `Ok(x?)` or `Some(x?)` where `x` would be equivalent\"\n}\n\ndeclare_lint_pass!(NeedlessQuestionMark => [NEEDLESS_QUESTION_MARK]);\n\nimpl LateLintPass<'_> for NeedlessQuestionMark {\n    /*\n     * The question mark operator is compatible with both Result<T, E> and Option<T>,\n     * from Rust 1.13 and 1.22 respectively.\n     */\n\n    /*\n     * What do we match:\n     * Expressions that look like this:\n     * Some(option?), Ok(result?)\n     *\n     * Where do we match:\n     *      Last expression of a body\n     *      Return statement\n     *      A body's value (single line closure)\n     *\n     * What do we not match:\n     *      Implicit calls to `from(..)` on the error value\n     */\n\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        if let ExprKind::Ret(Some(e)) = expr.kind {\n            check(cx, e);\n        }\n    }\n\n    fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {\n        if let ExprKind::Block(\n            Block {\n                expr:\n                    Some(Expr {\n                        kind: ExprKind::DropTemps(async_body),\n                        ..\n                    }),\n                ..\n            },\n            _,\n        ) = body.value.kind\n        {\n            if let ExprKind::Block(Block { expr: Some(expr), .. }, ..) = async_body.kind {\n                check(cx, expr.peel_blocks());\n            }\n        } else {\n            check(cx, body.value.peel_blocks());\n        }\n    }\n}\n\nfn check(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if let ExprKind::Call(path, [arg]) = expr.kind\n        && let Res::Def(DefKind::Ctor(..), ctor_id) = path.res(cx)\n        && let Some(variant_id) = cx.tcx.opt_parent(ctor_id)\n        && let variant = if cx.tcx.lang_items().option_some_variant() == Some(variant_id) {\n            \"Some\"\n        } else if cx.tcx.lang_items().result_ok_variant() == Some(variant_id) {\n            \"Ok\"\n        } else {\n            return;\n        }\n        && let ExprKind::Match(inner_expr_with_q, _, MatchSource::TryDesugar(_)) = &arg.kind\n        && let ExprKind::Call(called, [inner_expr]) = &inner_expr_with_q.kind\n        && let ExprKind::Path(qpath) = called.kind\n        && cx.tcx.qpath_is_lang_item(qpath, LangItem::TryTraitBranch)\n        && expr.span.eq_ctxt(inner_expr.span)\n        && let expr_ty = cx.typeck_results().expr_ty(expr)\n        && let inner_ty = cx.typeck_results().expr_ty(inner_expr)\n        && expr_ty == inner_ty\n    {\n        span_lint_hir_and_then(\n            cx,\n            NEEDLESS_QUESTION_MARK,\n            expr.hir_id,\n            expr.span,\n            format!(\"enclosing `{variant}` and `?` operator are unneeded\"),\n            |diag| {\n                diag.multipart_suggestion(\n                    format!(\"remove the enclosing `{variant}` and `?` operator\"),\n                    vec![\n                        (expr.span.until(inner_expr.span), String::new()),\n                        (\n                            inner_expr.span.shrink_to_hi().to(expr.span.shrink_to_hi()),\n                            String::new(),\n                        ),\n                    ],\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/needless_update.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_hir::{Expr, ExprKind, StructTailExpr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for needlessly including a base struct on update\n    /// when all fields are changed anyway.\n    ///\n    /// This lint is not applied to structs marked with\n    /// [non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html).\n    ///\n    /// ### Why is this bad?\n    /// This will cost resources (because the base has to be\n    /// somewhere), and make the code less readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct Point {\n    /// #     x: i32,\n    /// #     y: i32,\n    /// #     z: i32,\n    /// # }\n    /// # let zero_point = Point { x: 0, y: 0, z: 0 };\n    /// Point {\n    ///     x: 1,\n    ///     y: 1,\n    ///     z: 1,\n    ///     ..zero_point\n    /// };\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// // Missing field `z`\n    /// Point {\n    ///     x: 1,\n    ///     y: 1,\n    ///     ..zero_point\n    /// };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_UPDATE,\n    complexity,\n    \"using `Foo { ..base }` when there are no missing fields\"\n}\n\ndeclare_lint_pass!(NeedlessUpdate => [NEEDLESS_UPDATE]);\n\nimpl<'tcx> LateLintPass<'tcx> for NeedlessUpdate {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Struct(_, fields, StructTailExpr::Base(base)) = expr.kind {\n            let ty = cx.typeck_results().expr_ty(expr);\n            if let ty::Adt(def, _) = ty.kind()\n                && fields.len() == def.non_enum_variant().fields.len()\n                && !def.variant(0_usize.into()).is_field_list_non_exhaustive()\n            {\n                span_lint(\n                    cx,\n                    NEEDLESS_UPDATE,\n                    base.span,\n                    \"struct update has no effect, all the fields in the struct have already been specified\",\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/neg_cmp_op_on_partial_ord.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::ty::implements_trait;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of negated comparison operators on types which only implement\n    /// `PartialOrd` (e.g., `f64`).\n    ///\n    /// ### Why is this bad?\n    /// These operators make it easy to forget that the underlying types actually allow not only three\n    /// potential Orderings (Less, Equal, Greater) but also a fourth one (Uncomparable). This is\n    /// especially easy to miss if the operator based comparison result is negated.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = 1.0;\n    /// let b = f64::NAN;\n    ///\n    /// let not_less_or_equal = !(a <= b);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// use std::cmp::Ordering;\n    /// # let a = 1.0;\n    /// # let b = f64::NAN;\n    ///\n    /// let _not_less_or_equal = match a.partial_cmp(&b) {\n    ///     None | Some(Ordering::Greater) => true,\n    ///     _ => false,\n    /// };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEG_CMP_OP_ON_PARTIAL_ORD,\n    complexity,\n    \"The use of negated comparison operators on partially ordered types may produce confusing code.\"\n}\n\ndeclare_lint_pass!(NoNegCompOpForPartialOrd => [NEG_CMP_OP_ON_PARTIAL_ORD]);\n\nimpl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Unary(UnOp::Not, inner) = expr.kind\n            && let ExprKind::Binary(ref op, left, _) = inner.kind\n            && let BinOpKind::Le | BinOpKind::Ge | BinOpKind::Lt | BinOpKind::Gt = op.node\n            && !expr.span.in_external_macro(cx.sess().source_map())\n        {\n            let ty = cx.typeck_results().expr_ty(left);\n\n            let implements_ord = {\n                if let Some(id) = cx.tcx.get_diagnostic_item(sym::Ord) {\n                    implements_trait(cx, ty, id, &[])\n                } else {\n                    return;\n                }\n            };\n\n            let implements_partial_ord = {\n                if let Some(id) = cx.tcx.lang_items().partial_ord_trait() {\n                    implements_trait(cx, ty, id, &[ty.into()])\n                } else {\n                    return;\n                }\n            };\n\n            if implements_partial_ord && !implements_ord {\n                span_lint(\n                    cx,\n                    NEG_CMP_OP_ON_PARTIAL_ORD,\n                    expr.span,\n                    \"the use of negated comparison operators on partially ordered \\\n                    types produces code that is hard to read and refactor, please \\\n                    consider using the `partial_cmp` method instead, to make it \\\n                    clear that the two values could be incomparable\",\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/neg_multiply.rs",
    "content": "use clippy_utils::consts::{self, Constant};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::get_parent_expr;\nuse clippy_utils::source::{snippet, snippet_with_context};\nuse clippy_utils::sugg::has_enclosing_paren;\nuse rustc_ast::util::parser::ExprPrecedence;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for multiplication by -1 as a form of negation.\n    ///\n    /// ### Why is this bad?\n    /// It's more readable to just negate.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let a = x * -1;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// let a = -x;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEG_MULTIPLY,\n    style,\n    \"multiplying integers by `-1`\"\n}\n\ndeclare_lint_pass!(NegMultiply => [NEG_MULTIPLY]);\n\nfn is_in_parens_with_postfix(cx: &LateContext<'_>, mul_expr: &Expr<'_>) -> bool {\n    if let Some(parent) = get_parent_expr(cx, mul_expr) {\n        let mult_snippet = snippet(cx, mul_expr.span, \"\");\n        if has_enclosing_paren(&mult_snippet)\n            && let ExprKind::MethodCall(_, _, _, _) = parent.kind\n        {\n            return true;\n        }\n    }\n\n    false\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NegMultiply {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let ExprKind::Binary(ref op, left, right) = e.kind\n            && BinOpKind::Mul == op.node\n        {\n            match (&left.kind, &right.kind) {\n                (&ExprKind::Unary(..), &ExprKind::Unary(..)) => {},\n                (&ExprKind::Unary(UnOp::Neg, lit), _) => check_mul(cx, e, lit, right),\n                (_, &ExprKind::Unary(UnOp::Neg, lit)) => check_mul(cx, e, lit, left),\n                _ => {},\n            }\n        }\n    }\n}\n\nfn check_mul(cx: &LateContext<'_>, mul_expr: &Expr<'_>, lit: &Expr<'_>, exp: &Expr<'_>) {\n    const F16_ONE: u16 = 1.0_f16.to_bits();\n    const F128_ONE: u128 = 1.0_f128.to_bits();\n    if let ExprKind::Lit(l) = lit.kind\n        && matches!(\n            consts::lit_to_mir_constant(&l.node, cx.typeck_results().expr_ty_opt(lit)),\n            Constant::Int(1)\n                | Constant::F16(F16_ONE)\n                | Constant::F32(1.0)\n                | Constant::F64(1.0)\n                | Constant::F128(F128_ONE)\n        )\n        && cx.typeck_results().expr_ty(exp).is_numeric()\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let (snip, from_macro) = snippet_with_context(cx, exp.span, mul_expr.span.ctxt(), \"..\", &mut applicability);\n\n        let needs_parens_for_postfix = is_in_parens_with_postfix(cx, mul_expr);\n\n        let suggestion = if needs_parens_for_postfix {\n            // Special case: when the multiplication is in parentheses followed by a method call\n            // we need to preserve the grouping but negate the inner expression.\n            // Consider this expression: `((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0)`\n            // We need to end up with: `(-(a.delta - 0.5).abs()).total_cmp(&1.0)`\n            // Otherwise, without the parentheses we would try to negate an Ordering:\n            // `-(a.delta - 0.5).abs().total_cmp(&1.0)`\n            format!(\"(-{snip})\")\n        } else if !from_macro && cx.precedence(exp) < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {\n            format!(\"-({snip})\")\n        } else {\n            format!(\"-{snip}\")\n        };\n        span_lint_and_sugg(\n            cx,\n            NEG_MULTIPLY,\n            mul_expr.span,\n            \"this multiplication by -1 can be written more succinctly\",\n            \"consider using\",\n            suggestion,\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/new_without_default.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::return_ty;\nuse clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};\nuse clippy_utils::sugg::DiagExt;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::attrs::AttributeKind;\nuse rustc_hir::{Attribute, HirIdSet};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::AssocKind;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for public types with a `pub fn new() -> Self` method and no\n    /// implementation of\n    /// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html).\n    ///\n    /// ### Why is this bad?\n    /// The user might expect to be able to use\n    /// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the\n    /// type can be constructed without arguments.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// pub struct Foo(Bar);\n    ///\n    /// impl Foo {\n    ///     pub fn new() -> Self {\n    ///         Foo(Bar::new())\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// To fix the lint, add a `Default` implementation that delegates to `new`:\n    ///\n    /// ```ignore\n    /// pub struct Foo(Bar);\n    ///\n    /// impl Default for Foo {\n    ///     fn default() -> Self {\n    ///         Foo::new()\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEW_WITHOUT_DEFAULT,\n    style,\n    \"`pub fn new() -> Self` method without `Default` implementation\"\n}\n\nimpl_lint_pass!(NewWithoutDefault => [NEW_WITHOUT_DEFAULT]);\n\n#[derive(Clone, Default)]\npub struct NewWithoutDefault {\n    impling_types: Option<HirIdSet>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {\n    #[expect(clippy::too_many_lines)]\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {\n        let hir::ItemKind::Impl(hir::Impl {\n            of_trait: None,\n            generics,\n            self_ty: impl_self_ty,\n            ..\n        }) = item.kind\n        else {\n            return;\n        };\n\n        for assoc_item in cx\n            .tcx\n            .associated_items(item.owner_id.def_id)\n            .filter_by_name_unhygienic(sym::new)\n        {\n            if let AssocKind::Fn { has_self: false, .. } = assoc_item.kind\n                && let assoc_item_hir_id = cx.tcx.local_def_id_to_hir_id(assoc_item.def_id.expect_local())\n                && let impl_item = cx.tcx.hir_node(assoc_item_hir_id).expect_impl_item()\n                && !impl_item.span.in_external_macro(cx.sess().source_map())\n                && let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind\n                && let id = impl_item.owner_id\n                // can't be implemented for unsafe new\n                && !sig.header.is_unsafe()\n                // shouldn't be implemented when it is hidden in docs\n                && !cx.tcx.is_doc_hidden(impl_item.owner_id.def_id)\n                // when the result of `new()` depends on a parameter we should not require\n                // an impl of `Default`\n                && impl_item.generics.params.is_empty()\n                && sig.decl.inputs.is_empty()\n                && cx.effective_visibilities.is_exported(impl_item.owner_id.def_id)\n                && let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n                && self_ty == return_ty(cx, impl_item.owner_id)\n                && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)\n            {\n                if self.impling_types.is_none() {\n                    let mut impls = HirIdSet::default();\n                    for &d in cx.tcx.local_trait_impls(default_trait_id) {\n                        let ty = cx.tcx.type_of(d).instantiate_identity();\n                        if let Some(ty_def) = ty.ty_adt_def()\n                            && let Some(local_def_id) = ty_def.did().as_local()\n                        {\n                            impls.insert(cx.tcx.local_def_id_to_hir_id(local_def_id));\n                        }\n                    }\n                    self.impling_types = Some(impls);\n                }\n\n                // Check if a Default implementation exists for the Self type, regardless of\n                // generics\n                if let Some(ref impling_types) = self.impling_types\n                    && let self_def = cx.tcx.type_of(item.owner_id).instantiate_identity()\n                    && let Some(self_def) = self_def.ty_adt_def()\n                    && let Some(self_local_did) = self_def.did().as_local()\n                    && let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did)\n                    && impling_types.contains(&self_id)\n                {\n                    return;\n                }\n\n                let mut app = Applicability::MachineApplicable;\n                let attrs_sugg = {\n                    let mut sugg = String::new();\n                    for attr in cx.tcx.hir_attrs(assoc_item_hir_id) {\n                        let Attribute::Parsed(AttributeKind::CfgTrace(attrs)) = attr else {\n                            // This might be some other attribute that the `impl Default` ought to inherit.\n                            // But it could also be one of the many attributes that:\n                            // - can't be put on an impl block -- like `#[inline]`\n                            // - we can't even build a suggestion for, since `Attribute::span` may panic.\n                            //\n                            // Because of all that, remain on the safer side -- don't inherit this attr, and just\n                            // reduce the applicability\n                            app = Applicability::MaybeIncorrect;\n                            continue;\n                        };\n\n                        for (_, attr_span) in attrs {\n                            sugg.push_str(&snippet_with_applicability(cx.sess(), *attr_span, \"_\", &mut app));\n                            sugg.push('\\n');\n                        }\n                    }\n                    sugg\n                };\n                let generics_sugg = snippet_with_applicability(cx, generics.span, \"\", &mut app);\n                let where_clause_sugg = if generics.has_where_clause_predicates {\n                    let where_clause_sugg =\n                        snippet_with_applicability(cx, generics.where_clause_span, \"\", &mut app).to_string();\n                    let mut where_clause_sugg = reindent_multiline(&where_clause_sugg, true, Some(4));\n                    if impl_item.generics.has_where_clause_predicates {\n                        if !where_clause_sugg.ends_with(',') {\n                            where_clause_sugg.push(',');\n                        }\n\n                        let additional_where_preds =\n                            snippet_with_applicability(cx, impl_item.generics.where_clause_span, \"\", &mut app);\n                        let ident = indent_of(cx, generics.where_clause_span).unwrap_or(0);\n                        // Remove the leading `where ` keyword\n                        let additional_where_preds = additional_where_preds.trim_start_matches(\"where\").trim_start();\n                        where_clause_sugg.push('\\n');\n                        where_clause_sugg.extend(std::iter::repeat_n(' ', ident));\n                        where_clause_sugg.push_str(additional_where_preds);\n                    }\n                    format!(\"\\n{where_clause_sugg}\\n\")\n                } else if impl_item.generics.has_where_clause_predicates {\n                    let where_clause_sugg =\n                        snippet_with_applicability(cx, impl_item.generics.where_clause_span, \"\", &mut app);\n                    let where_clause_sugg = reindent_multiline(&where_clause_sugg, true, Some(4));\n                    format!(\"\\n{}\\n\", where_clause_sugg.trim_start())\n                } else {\n                    String::new()\n                };\n                let self_ty_fmt = self_ty.to_string();\n                let self_type_snip = snippet_with_applicability(cx, impl_self_ty.span, &self_ty_fmt, &mut app);\n                span_lint_hir_and_then(\n                    cx,\n                    NEW_WITHOUT_DEFAULT,\n                    id.into(),\n                    impl_item.span,\n                    format!(\"you should consider adding a `Default` implementation for `{self_type_snip}`\"),\n                    |diag| {\n                        diag.suggest_prepend_item(\n                            cx,\n                            item.span,\n                            \"try adding this\",\n                            &create_new_without_default_suggest_msg(\n                                &attrs_sugg,\n                                &self_type_snip,\n                                &generics_sugg,\n                                &where_clause_sugg,\n                            ),\n                            app,\n                        );\n                    },\n                );\n            }\n        }\n    }\n}\n\nfn create_new_without_default_suggest_msg(\n    attrs_sugg: &str,\n    self_type_snip: &str,\n    generics_sugg: &str,\n    where_clause_sugg: &str,\n) -> String {\n    #[rustfmt::skip]\n    format!(\n\"{attrs_sugg}impl{generics_sugg} Default for {self_type_snip}{where_clause_sugg} {{\n    fn default() -> Self {{\n        Self::new()\n    }}\n}}\")\n}\n"
  },
  {
    "path": "clippy_lints/src/no_effect.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::ty::{expr_type_is_certain, has_drop};\nuse clippy_utils::{in_automatically_derived, is_inside_always_const_context, is_lint_allowed, peel_blocks};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{\n    BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, LocalSource, Node, PatKind, Stmt, StmtKind,\n    StructTailExpr, UnsafeSource, is_range_literal,\n};\nuse rustc_infer::infer::TyCtxtInferExt as _;\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_trait_selection::error_reporting::InferCtxtErrorExt;\nuse std::ops::Deref;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for statements which have no effect.\n    ///\n    /// ### Why is this bad?\n    /// Unlike dead code, these statements are actually\n    /// executed. However, as they have no effect, all they do is make the code less\n    /// readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// 0;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NO_EFFECT,\n    complexity,\n    \"statements with no effect\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for binding to underscore prefixed variable without side-effects.\n    ///\n    /// ### Why is this bad?\n    /// Unlike dead code, these bindings are actually\n    /// executed. However, as they have no effect and shouldn't be used further on, all they\n    /// do is make the code less readable.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let _i_serve_no_purpose = 1;\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub NO_EFFECT_UNDERSCORE_BINDING,\n    pedantic,\n    \"binding to `_` prefixed variable with no side-effect\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expression statements that can be reduced to a\n    /// sub-expression.\n    ///\n    /// ### Why is this bad?\n    /// Expressions by themselves often have no side-effects.\n    /// Having such expressions reduces readability.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// compute_array()[0];\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNNECESSARY_OPERATION,\n    complexity,\n    \"outer expressions with no effect\"\n}\n\nimpl_lint_pass!(NoEffect => [\n    NO_EFFECT,\n    NO_EFFECT_UNDERSCORE_BINDING,\n    UNNECESSARY_OPERATION,\n]);\n\n#[derive(Default)]\npub struct NoEffect {\n    underscore_bindings: HirIdMap<Span>,\n    local_bindings: Vec<Vec<HirId>>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NoEffect {\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if self.check_no_effect(cx, stmt) {\n            return;\n        }\n        check_unnecessary_operation(cx, stmt);\n    }\n\n    fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Block<'tcx>) {\n        self.local_bindings.push(Vec::default());\n    }\n\n    fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx rustc_hir::Block<'tcx>) {\n        for hir_id in self.local_bindings.pop().unwrap() {\n            if let Some(span) = self.underscore_bindings.swap_remove(&hir_id) {\n                span_lint_hir(\n                    cx,\n                    NO_EFFECT_UNDERSCORE_BINDING,\n                    hir_id,\n                    span,\n                    \"binding to `_` prefixed variable with no side-effect\",\n                );\n            }\n        }\n    }\n\n    fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let Some(def_id) = expr.res_local_id() {\n            self.underscore_bindings.swap_remove(&def_id);\n        }\n    }\n}\n\nimpl NoEffect {\n    fn check_no_effect(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {\n        if let StmtKind::Semi(expr) = stmt.kind {\n            // Covered by rustc `path_statements` lint\n            if matches!(expr.kind, ExprKind::Path(_)) {\n                return true;\n            }\n\n            if expr.range_span().unwrap_or(expr.span).from_expansion() {\n                return false;\n            }\n            let expr = peel_blocks(expr);\n\n            if is_operator_overridden(cx, expr) {\n                // Return `true`, to prevent `check_unnecessary_operation` from\n                // linting on this statement as well.\n                return true;\n            }\n            if has_no_effect(cx, expr) {\n                span_lint_hir_and_then(\n                    cx,\n                    NO_EFFECT,\n                    expr.hir_id,\n                    stmt.span,\n                    \"statement with no effect\",\n                    |diag| {\n                        for parent in cx.tcx.hir_parent_iter(stmt.hir_id) {\n                            if let Node::Item(item) = parent.1\n                                && let ItemKind::Fn { .. } = item.kind\n                                && let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id)\n                                && let [.., final_stmt] = block.stmts\n                                && final_stmt.hir_id == stmt.hir_id\n                            {\n                                let expr_ty = cx.typeck_results().expr_ty(expr);\n                                let mut ret_ty = cx\n                                    .tcx\n                                    .fn_sig(item.owner_id)\n                                    .instantiate_identity()\n                                    .output()\n                                    .skip_binder();\n\n                                // Remove `impl Future<Output = T>` to get `T`\n                                if cx.tcx.ty_is_opaque_future(ret_ty)\n                                    && let Some(true_ret_ty) = cx\n                                        .tcx\n                                        .infer_ctxt()\n                                        .build(cx.typing_mode())\n                                        .err_ctxt()\n                                        .get_impl_future_output_ty(ret_ty)\n                                {\n                                    ret_ty = true_ret_ty;\n                                }\n\n                                if !ret_ty.is_unit() && ret_ty == expr_ty {\n                                    diag.span_suggestion(\n                                        stmt.span.shrink_to_lo(),\n                                        \"did you mean to return it?\",\n                                        \"return \",\n                                        Applicability::MaybeIncorrect,\n                                    );\n                                }\n                            }\n                        }\n                    },\n                );\n                return true;\n            }\n        } else if let StmtKind::Let(local) = stmt.kind\n            && !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id)\n            && !matches!(local.source, LocalSource::AsyncFn)\n            && let Some(init) = local.init\n            && local.els.is_none()\n            && !local.pat.span.from_expansion()\n            && has_no_effect(cx, init)\n            && let PatKind::Binding(_, hir_id, ident, _) = local.pat.kind\n            && ident.name.to_ident_string().starts_with('_')\n            && !in_automatically_derived(cx.tcx, local.hir_id)\n        {\n            if let Some(l) = self.local_bindings.last_mut() {\n                l.push(hir_id);\n                self.underscore_bindings.insert(hir_id, ident.span);\n            }\n            return true;\n        }\n        false\n    }\n}\n\nfn is_operator_overridden(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    // It's very hard or impossible to check whether overridden operator have side-effect this lint.\n    // So, this function assume user-defined operator is overridden with an side-effect.\n    // The definition of user-defined structure here is ADT-type,\n    // Althrough this will weaken the ability of this lint, less error lint-fix happen.\n    match expr.kind {\n        ExprKind::Binary(..) | ExprKind::Unary(..) => {\n            // No need to check type of `lhs` and `rhs`\n            // because if the operator is overridden, at least one operand is ADT type\n\n            // reference: rust/compiler/rustc_middle/src/ty/typeck_results.rs: `is_method_call`.\n            // use this function to check whether operator is overridden in `ExprKind::{Binary, Unary}`.\n            cx.typeck_results().is_method_call(expr)\n        },\n        _ => false,\n    }\n}\n\n/// Checks if dropping `expr` might have a visible side effect.\nfn expr_ty_has_significant_drop(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let ty = cx.typeck_results().expr_ty(expr);\n    ty.has_significant_drop(cx.tcx, cx.typing_env())\n}\n\nfn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Lit(..) | ExprKind::Closure { .. } => true,\n        ExprKind::Path(..) => !expr_ty_has_significant_drop(cx, expr),\n        ExprKind::Index(a, b, _) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b),\n        ExprKind::Array(v) | ExprKind::Tup(v) => v.iter().all(|val| has_no_effect(cx, val)),\n        ExprKind::Repeat(inner, _)\n        | ExprKind::Cast(inner, _)\n        | ExprKind::Type(inner, _)\n        | ExprKind::Unary(_, inner)\n        | ExprKind::Field(inner, _)\n        | ExprKind::AddrOf(_, _, inner) => has_no_effect(cx, inner),\n        ExprKind::Struct(_, fields, base) => {\n            !expr_ty_has_significant_drop(cx, expr)\n                && fields.iter().all(|field| has_no_effect(cx, field.expr))\n                && match &base {\n                    StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => true,\n                    StructTailExpr::Base(base) => has_no_effect(cx, base),\n                }\n        },\n        ExprKind::Call(callee, args) => {\n            if let ExprKind::Path(ref qpath) = callee.kind {\n                if cx.typeck_results().type_dependent_def(expr.hir_id).is_some() {\n                    // type-dependent function call like `impl FnOnce for X`\n                    return false;\n                }\n                let def_matched = matches!(\n                    cx.qpath_res(qpath, callee.hir_id),\n                    Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..)\n                );\n                if def_matched || is_range_literal(expr) {\n                    !expr_ty_has_significant_drop(cx, expr) && args.iter().all(|arg| has_no_effect(cx, arg))\n                } else {\n                    false\n                }\n            } else {\n                false\n            }\n        },\n        _ => false,\n    }\n}\n\nfn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {\n    if let StmtKind::Semi(expr) = stmt.kind\n        && !stmt.span.in_external_macro(cx.sess().source_map())\n        && let ctxt = stmt.span.ctxt()\n        && expr.range_span().unwrap_or(expr.span).ctxt() == ctxt\n        && let Some(reduced) = reduce_expression(cx, expr)\n        && reduced.iter().all(|e| e.span.ctxt() == ctxt)\n    {\n        if let ExprKind::Index(..) = &expr.kind {\n            if !is_inside_always_const_context(cx.tcx, expr.hir_id)\n                && let [arr, func] = &*reduced\n                && let Some(arr) = arr.span.get_source_text(cx)\n                && let Some(func) = func.span.get_source_text(cx)\n            {\n                span_lint_hir_and_then(\n                    cx,\n                    UNNECESSARY_OPERATION,\n                    expr.hir_id,\n                    stmt.span,\n                    \"unnecessary operation\",\n                    |diag| {\n                        diag.span_suggestion(\n                            stmt.span,\n                            \"statement can be written as\",\n                            format!(\"assert!({arr}.len() > {func});\"),\n                            Applicability::MaybeIncorrect,\n                        );\n                    },\n                );\n            }\n        } else {\n            let mut snippet = String::new();\n            for e in reduced {\n                if let Some(snip) = e.span.get_source_text(cx) {\n                    snippet.push_str(&snip);\n                    snippet.push_str(\"; \");\n                } else {\n                    return;\n                }\n            }\n            snippet.pop(); // remove the last space\n            span_lint_hir_and_then(\n                cx,\n                UNNECESSARY_OPERATION,\n                expr.hir_id,\n                stmt.span,\n                \"unnecessary operation\",\n                |diag| {\n                    diag.span_suggestion(\n                        stmt.span,\n                        \"statement can be reduced to\",\n                        snippet,\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n    }\n}\n\nfn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec<&'a Expr<'a>>> {\n    if expr.range_span().unwrap_or(expr.span).from_expansion() {\n        return None;\n    }\n    match expr.kind {\n        ExprKind::Index(a, b, _) => Some(vec![a, b]),\n        ExprKind::Binary(ref binop, a, b) if binop.node != BinOpKind::And && binop.node != BinOpKind::Or => {\n            Some(vec![a, b])\n        },\n        ExprKind::Array(v) | ExprKind::Tup(v) => Some(v.iter().collect()),\n        ExprKind::Repeat(inner, _)\n        | ExprKind::Type(inner, _)\n        | ExprKind::Unary(_, inner)\n        | ExprKind::Field(inner, _)\n        | ExprKind::AddrOf(_, _, inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),\n        ExprKind::Cast(inner, _) if expr_type_is_certain(cx, inner) => {\n            reduce_expression(cx, inner).or_else(|| Some(vec![inner]))\n        },\n        ExprKind::Struct(_, fields, ref base) => {\n            if has_drop(cx, cx.typeck_results().expr_ty(expr)) {\n                None\n            } else {\n                let base = match base {\n                    StructTailExpr::Base(base) => Some(base),\n                    StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => None,\n                };\n                Some(fields.iter().map(|f| &f.expr).chain(base).map(Deref::deref).collect())\n            }\n        },\n        ExprKind::Call(callee, args) => {\n            if let ExprKind::Path(ref qpath) = callee.kind {\n                if cx.typeck_results().type_dependent_def(expr.hir_id).is_some() {\n                    // type-dependent function call like `impl FnOnce for X`\n                    return None;\n                }\n                let res = cx.qpath_res(qpath, callee.hir_id);\n                match res {\n                    Res::Def(DefKind::Struct | DefKind::Variant | DefKind::Ctor(..), ..)\n                        if !has_drop(cx, cx.typeck_results().expr_ty(expr)) =>\n                    {\n                        Some(args.iter().collect())\n                    },\n                    _ => None,\n                }\n            } else {\n                None\n            }\n        },\n        ExprKind::Block(block, _) => {\n            if block.stmts.is_empty() && !block.targeted_by_break {\n                block.expr.as_ref().and_then(|e| {\n                    match block.rules {\n                        BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) => None,\n                        BlockCheckMode::DefaultBlock => Some(vec![&**e]),\n                        // in case of compiler-inserted signaling blocks\n                        BlockCheckMode::UnsafeBlock(_) => reduce_expression(cx, e),\n                    }\n                })\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/no_mangle_with_rust_abi.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{snippet, snippet_with_applicability};\nuse rustc_abi::ExternAbi;\nuse rustc_errors::Applicability;\nuse rustc_hir::attrs::AttributeKind;\nuse rustc_hir::{Attribute, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{BytePos, Pos};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for Rust ABI functions with the `#[no_mangle]` attribute.\n    ///\n    /// ### Why is this bad?\n    /// The Rust ABI is not stable, but in many simple cases matches\n    /// enough with the C ABI that it is possible to forget to add\n    /// `extern \"C\"` to a function called from C. Changes to the\n    /// Rust ABI can break this at any point.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    ///  #[no_mangle]\n    ///  fn example(arg_one: u32, arg_two: usize) {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    ///  #[no_mangle]\n    ///  extern \"C\" fn example(arg_one: u32, arg_two: usize) {}\n    /// ```\n    #[clippy::version = \"1.69.0\"]\n    pub NO_MANGLE_WITH_RUST_ABI,\n    pedantic,\n    \"convert Rust ABI functions to C ABI\"\n}\n\ndeclare_lint_pass!(NoMangleWithRustAbi => [NO_MANGLE_WITH_RUST_ABI]);\n\nimpl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if let ItemKind::Fn { ident, sig: fn_sig, .. } = &item.kind\n            && !item.span.from_expansion()\n        {\n            let attrs = cx.tcx.hir_attrs(item.hir_id());\n            let mut app = Applicability::MaybeIncorrect;\n            let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(ident.span.lo()), \"..\", &mut app);\n            for attr in attrs {\n                if let Attribute::Parsed(AttributeKind::NoMangle(attr_span)) = attr\n                    && fn_sig.header.abi == ExternAbi::Rust\n                    && let Some((fn_attrs, _)) = fn_snippet.rsplit_once(\"fn\")\n                    && !fn_attrs.contains(\"extern\")\n                {\n                    let sugg_span = fn_sig\n                        .span\n                        .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len()))\n                        .shrink_to_lo();\n                    let attr_snippet = snippet(cx, *attr_span, \"..\");\n\n                    span_lint_and_then(\n                        cx,\n                        NO_MANGLE_WITH_RUST_ABI,\n                        fn_sig.span,\n                        format!(\"`{attr_snippet}` set on a function with the default (`Rust`) ABI\"),\n                        |diag| {\n                            diag.span_suggestion(sugg_span, \"set an ABI\", \"extern \\\"C\\\" \", app)\n                                .span_suggestion(sugg_span, \"or explicitly set the default\", \"extern \\\"Rust\\\" \", app);\n                        },\n                    );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/non_canonical_impls.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{is_from_proc_macro, last_path_segment, std_or_core};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{Block, Body, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, LangItem, UnOp};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{TyCtxt, TypeckResults};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::sym;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for non-canonical implementations of `Clone` when `Copy` is already implemented.\n    ///\n    /// ### Why is this bad?\n    /// If both `Clone` and `Copy` are implemented, they must agree. This can done by dereferencing\n    /// `self` in `Clone`'s implementation, which will avoid any possibility of the implementations\n    /// becoming out of sync.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// #[derive(Eq, PartialEq)]\n    /// struct A(u32);\n    ///\n    /// impl Clone for A {\n    ///     fn clone(&self) -> Self {\n    ///         Self(self.0)\n    ///     }\n    /// }\n    ///\n    /// impl Copy for A {}\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// #[derive(Eq, PartialEq)]\n    /// struct A(u32);\n    ///\n    /// impl Clone for A {\n    ///     fn clone(&self) -> Self {\n    ///         *self\n    ///     }\n    /// }\n    ///\n    /// impl Copy for A {}\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub NON_CANONICAL_CLONE_IMPL,\n    suspicious,\n    \"non-canonical implementation of `Clone` on a `Copy` type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for non-canonical implementations of `PartialOrd` when `Ord` is already implemented.\n    ///\n    /// ### Why is this bad?\n    /// If both `PartialOrd` and `Ord` are implemented, they must agree. This is commonly done by\n    /// wrapping the result of `cmp` in `Some` for `partial_cmp`. Not doing this may silently\n    /// introduce an error upon refactoring.\n    ///\n    /// ### Known issues\n    /// Code that calls the `.into()` method instead will be flagged, despite `.into()` wrapping it\n    /// in `Some`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::cmp::Ordering;\n    /// #[derive(Eq, PartialEq)]\n    /// struct A(u32);\n    ///\n    /// impl Ord for A {\n    ///     fn cmp(&self, other: &Self) -> Ordering {\n    ///         // ...\n    /// #       todo!();\n    ///     }\n    /// }\n    ///\n    /// impl PartialOrd for A {\n    ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n    ///         // ...\n    /// #       todo!();\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::cmp::Ordering;\n    /// #[derive(Eq, PartialEq)]\n    /// struct A(u32);\n    ///\n    /// impl Ord for A {\n    ///     fn cmp(&self, other: &Self) -> Ordering {\n    ///         // ...\n    /// #       todo!();\n    ///     }\n    /// }\n    ///\n    /// impl PartialOrd for A {\n    ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n    ///         Some(self.cmp(other))   // or self.cmp(other).into()\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub NON_CANONICAL_PARTIAL_ORD_IMPL,\n    suspicious,\n    \"non-canonical implementation of `PartialOrd` on an `Ord` type\"\n}\n\nimpl_lint_pass!(NonCanonicalImpls => [\n    NON_CANONICAL_CLONE_IMPL,\n    NON_CANONICAL_PARTIAL_ORD_IMPL,\n]);\n\n#[expect(\n    clippy::struct_field_names,\n    reason = \"`_trait` suffix is meaningful on its own, \\\n              and creating an inner `StoredTraits` struct would just add a level of indirection\"\n)]\npub(crate) struct NonCanonicalImpls {\n    partial_ord_trait: Option<DefId>,\n    ord_trait: Option<DefId>,\n    clone_trait: Option<DefId>,\n    copy_trait: Option<DefId>,\n}\n\nimpl NonCanonicalImpls {\n    pub(crate) fn new(tcx: TyCtxt<'_>) -> Self {\n        let lang_items = tcx.lang_items();\n        Self {\n            partial_ord_trait: lang_items.partial_ord_trait(),\n            ord_trait: tcx.get_diagnostic_item(sym::Ord),\n            clone_trait: lang_items.clone_trait(),\n            copy_trait: lang_items.copy_trait(),\n        }\n    }\n}\n\n/// The traits that this lint looks at\nenum Trait {\n    Clone,\n    PartialOrd,\n}\n\nimpl LateLintPass<'_> for NonCanonicalImpls {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        if let ItemKind::Impl(impl_) = item.kind\n            // Both `PartialOrd` and `Clone` have one required method, and `PartialOrd` can have 5 methods in total\n            && (1..=5).contains(&impl_.items.len())\n            && let Some(of_trait) = impl_.of_trait\n            && let Some(trait_did) = of_trait.trait_ref.trait_def_id()\n            // Check this early to hopefully bail out as soon as possible\n            && let trait_ = if Some(trait_did) == self.clone_trait {\n                Trait::Clone\n            } else if Some(trait_did) == self.partial_ord_trait {\n                Trait::PartialOrd\n            } else {\n                return;\n            }\n            && !cx.tcx.is_automatically_derived(item.owner_id.to_def_id())\n        {\n            let mut assoc_fns = impl_\n                .items\n                .iter()\n                .map(|id| cx.tcx.hir_impl_item(*id))\n                .filter_map(|assoc| {\n                    if let ImplItemKind::Fn(_, body_id) = assoc.kind\n                        && let body = cx.tcx.hir_body(body_id)\n                        && let ExprKind::Block(block, ..) = body.value.kind\n                        && !block.span.in_external_macro(cx.sess().source_map())\n                    {\n                        Some((assoc, body, block))\n                    } else {\n                        None\n                    }\n                });\n\n            let trait_impl = cx.tcx.impl_trait_ref(item.owner_id).skip_binder();\n\n            match trait_ {\n                Trait::Clone => {\n                    if let Some(copy_trait) = self.copy_trait\n                        && implements_trait(cx, trait_impl.self_ty(), copy_trait, &[])\n                    {\n                        for (assoc, _, block) in assoc_fns {\n                            check_clone_on_copy(cx, assoc, block);\n                        }\n                    }\n                },\n                Trait::PartialOrd => {\n                    // If `Self` and `Rhs` are not the same type, then a corresponding `Ord` impl is not possible,\n                    // since it doesn't have an `Rhs`\n                    if let [lhs, rhs] = trait_impl.args.as_slice()\n                        && lhs == rhs\n                        && let Some(ord_trait) = self.ord_trait\n                        && implements_trait(cx, trait_impl.self_ty(), ord_trait, &[])\n                        && let Some((assoc, body, block)) =\n                            assoc_fns.find(|(assoc, _, _)| assoc.ident.name == sym::partial_cmp)\n                    {\n                        check_partial_ord_on_ord(cx, assoc, item, body, block);\n                    }\n                },\n            }\n        }\n    }\n}\n\nfn check_clone_on_copy(cx: &LateContext<'_>, impl_item: &ImplItem<'_>, block: &Block<'_>) {\n    if impl_item.ident.name == sym::clone {\n        if block.stmts.is_empty()\n            && let Some(expr) = block.expr\n            && let ExprKind::Unary(UnOp::Deref, deref) = expr.kind\n            && let ExprKind::Path(qpath) = deref.kind\n            && last_path_segment(&qpath).ident.name == kw::SelfLower\n        {\n            // this is the canonical implementation, `fn clone(&self) -> Self { *self }`\n            return;\n        }\n\n        if is_from_proc_macro(cx, impl_item) {\n            return;\n        }\n\n        span_lint_and_sugg(\n            cx,\n            NON_CANONICAL_CLONE_IMPL,\n            block.span,\n            \"non-canonical implementation of `clone` on a `Copy` type\",\n            \"change this to\",\n            \"{ *self }\".to_owned(),\n            Applicability::MaybeIncorrect,\n        );\n    }\n\n    if impl_item.ident.name == sym::clone_from && !is_from_proc_macro(cx, impl_item) {\n        span_lint_and_sugg(\n            cx,\n            NON_CANONICAL_CLONE_IMPL,\n            impl_item.span,\n            \"unnecessary implementation of `clone_from` on a `Copy` type\",\n            \"remove it\",\n            String::new(),\n            Applicability::MaybeIncorrect,\n        );\n    }\n}\n\nfn check_partial_ord_on_ord<'tcx>(\n    cx: &LateContext<'tcx>,\n    impl_item: &ImplItem<'_>,\n    item: &Item<'_>,\n    body: &Body<'_>,\n    block: &Block<'tcx>,\n) {\n    // If the `cmp` call likely needs to be fully qualified in the suggestion\n    // (like `std::cmp::Ord::cmp`). It's unfortunate we must put this here but we can't\n    // access `cmp_expr` in the suggestion without major changes, as we lint in `else`.\n\n    let mut needs_fully_qualified = false;\n    if block.stmts.is_empty()\n        && let Some(expr) = block.expr\n        && expr_is_cmp(cx, expr, impl_item, &mut needs_fully_qualified)\n    {\n        return;\n    }\n    // Fix #12683, allow [`needless_return`] here\n    else if block.expr.is_none()\n        && let Some(stmt) = block.stmts.first()\n        && let rustc_hir::StmtKind::Semi(Expr {\n            kind: ExprKind::Ret(Some(ret)),\n            ..\n        }) = stmt.kind\n        && expr_is_cmp(cx, ret, impl_item, &mut needs_fully_qualified)\n    {\n        return;\n    } else if is_from_proc_macro(cx, impl_item) {\n        return;\n    }\n\n    span_lint_and_then(\n        cx,\n        NON_CANONICAL_PARTIAL_ORD_IMPL,\n        item.span,\n        \"non-canonical implementation of `partial_cmp` on an `Ord` type\",\n        |diag| {\n            let [_, other] = body.params else {\n                return;\n            };\n            let Some(std_or_core) = std_or_core(cx) else {\n                return;\n            };\n\n            let suggs = match (other.pat.simple_ident(), needs_fully_qualified) {\n                (Some(other_ident), true) => vec![(\n                    block.span,\n                    format!(\"{{ Some({std_or_core}::cmp::Ord::cmp(self, {})) }}\", other_ident.name),\n                )],\n                (Some(other_ident), false) => {\n                    vec![(block.span, format!(\"{{ Some(self.cmp({})) }}\", other_ident.name))]\n                },\n                (None, true) => vec![\n                    (\n                        block.span,\n                        format!(\"{{ Some({std_or_core}::cmp::Ord::cmp(self, other)) }}\"),\n                    ),\n                    (other.pat.span, \"other\".to_owned()),\n                ],\n                (None, false) => vec![\n                    (block.span, \"{ Some(self.cmp(other)) }\".to_owned()),\n                    (other.pat.span, \"other\".to_owned()),\n                ],\n            };\n\n            diag.multipart_suggestion(\"change this to\", suggs, Applicability::Unspecified);\n        },\n    );\n}\n\n/// Return true if `expr_kind` is a `cmp` call.\nfn expr_is_cmp<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    impl_item: &ImplItem<'_>,\n    needs_fully_qualified: &mut bool,\n) -> bool {\n    let typeck = cx.tcx.typeck(impl_item.owner_id.def_id);\n    match expr.kind {\n        ExprKind::Call(\n            Expr {\n                kind: ExprKind::Path(some_path),\n                hir_id: some_hir_id,\n                ..\n            },\n            [cmp_expr],\n        ) => {\n            typeck.qpath_res(some_path, *some_hir_id).ctor_parent(cx).is_lang_item(cx, LangItem::OptionSome)\n                // Fix #11178, allow `Self::cmp(self, ..)`\n                && self_cmp_call(cx, typeck, cmp_expr, needs_fully_qualified)\n        },\n        ExprKind::MethodCall(_, recv, [], _) => {\n            typeck\n                .type_dependent_def(expr.hir_id)\n                .assoc_parent(cx)\n                .is_diag_item(cx, sym::Into)\n                && self_cmp_call(cx, typeck, recv, needs_fully_qualified)\n        },\n        _ => false,\n    }\n}\n\n/// Returns whether this is any of `self.cmp(..)`, `Self::cmp(self, ..)` or `Ord::cmp(self, ..)`.\nfn self_cmp_call<'tcx>(\n    cx: &LateContext<'tcx>,\n    typeck: &TypeckResults<'tcx>,\n    cmp_expr: &'tcx Expr<'tcx>,\n    needs_fully_qualified: &mut bool,\n) -> bool {\n    match cmp_expr.kind {\n        ExprKind::Call(path, [_, _]) => path.res(typeck).is_diag_item(cx, sym::ord_cmp_method),\n        ExprKind::MethodCall(_, recv, [_], ..) => {\n            let ExprKind::Path(path) = recv.kind else {\n                return false;\n            };\n            if last_path_segment(&path).ident.name != kw::SelfLower {\n                return false;\n            }\n\n            // We can set this to true here no matter what as if it's a `MethodCall` and goes to the\n            // `else` branch, it must be a method named `cmp` that isn't `Ord::cmp`\n            *needs_fully_qualified = true;\n\n            typeck\n                .type_dependent_def_id(cmp_expr.hir_id)\n                .is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::ord_cmp_method, def_id))\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/non_copy_const.rs",
    "content": "// Implementation for lints detecting interior mutability in constants.\n//\n// For `declare_interior_mutable_const` there are three strategies used to\n// determine if a value has interior mutability:\n// * A type-based check. This is the least accurate, but can always run.\n// * A const-eval based check. This is the most accurate, but this requires that the value is\n//   defined and does not work with generics.\n// * A HIR-tree based check. This is less accurate than const-eval, but it can be applied to generic\n//   values.\n//\n// For `borrow_interior_mutable_const` the same three strategies are applied\n// when checking a constant's value, but field and array index projections at\n// the borrow site are taken into account as well. As an example: `FOO.bar` may\n// have interior mutability, but `FOO.baz` may not. When borrowing `FOO.baz` no\n// warning will be issued.\n//\n// No matter the lint or strategy, a warning should only be issued if a value\n// definitely contains interior mutability.\n\nuse clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant, const_item_rhs_to_expr};\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::macros::macro_backtrace;\nuse clippy_utils::paths::{PathNS, lookup_path_str};\nuse clippy_utils::ty::{get_field_idx_by_name, implements_trait};\nuse clippy_utils::{is_in_const_context, sym};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::{DefId, DefIdSet};\nuse rustc_hir::{\n    ConstArgKind, ConstItemRhs, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, Node, StructTailExpr,\n    TraitItem, TraitItemKind, UnOp,\n};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::mir::{ConstValue, UnevaluatedConst};\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};\nuse rustc_middle::ty::{\n    self, AliasTyKind, EarlyBinder, GenericArgs, GenericArgsRef, Instance, Ty, TyCtxt, TypeFolder, TypeSuperFoldable,\n    TypeckResults, TypingEnv,\n};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::DUMMY_SP;\nuse std::collections::hash_map::Entry;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for a borrow of a named constant with interior mutability.\n    ///\n    /// ### Why is this bad?\n    /// Named constants are copied at every use site which means any change to their value\n    /// will be lost after the newly created value is dropped. e.g.\n    ///\n    /// ```rust\n    /// use core::sync::atomic::{AtomicUsize, Ordering};\n    /// const ATOMIC: AtomicUsize = AtomicUsize::new(0);\n    /// fn add_one() -> usize {\n    ///     // This will always return `0` since `ATOMIC` is copied before it's borrowed\n    ///     // for use by `fetch_add`.\n    ///     ATOMIC.fetch_add(1, Ordering::AcqRel)\n    /// }\n    /// ```\n    ///\n    /// ### Known problems\n    /// This lint does not, and cannot in general, determine if the borrow of the constant\n    /// is used in a way which causes a mutation. e.g.\n    ///\n    /// ```rust\n    /// use core::cell::Cell;\n    /// const CELL: Cell<usize> = Cell::new(0);\n    /// fn get_cell() -> Cell<usize> {\n    ///     // This is fine. It borrows a copy of `CELL`, but never mutates it through the\n    ///     // borrow.\n    ///     CELL.clone()\n    /// }\n    /// ```\n    ///\n    /// There also exists types which contain private fields with interior mutability, but\n    /// no way to both create a value as a constant and modify any mutable field using the\n    /// type's public interface (e.g. `bytes::Bytes`). As there is no reasonable way to\n    /// scan a crate's interface to see if this is the case, all such types will be linted.\n    /// If this happens use the `ignore-interior-mutability` configuration option to allow\n    /// the type.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};\n    /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);\n    ///\n    /// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged\n    /// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};\n    /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);\n    ///\n    /// static STATIC_ATOM: AtomicUsize = CONST_ATOM;\n    /// STATIC_ATOM.store(9, SeqCst);\n    /// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub BORROW_INTERIOR_MUTABLE_CONST,\n    style,\n    \"referencing `const` with interior mutability\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the declaration of named constant which contain interior mutability.\n    ///\n    /// ### Why is this bad?\n    /// Named constants are copied at every use site which means any change to their value\n    /// will be lost after the newly created value is dropped. e.g.\n    ///\n    /// ```rust\n    /// use core::sync::atomic::{AtomicUsize, Ordering};\n    /// const ATOMIC: AtomicUsize = AtomicUsize::new(0);\n    /// fn add_one() -> usize {\n    ///     // This will always return `0` since `ATOMIC` is copied before it's used.\n    ///     ATOMIC.fetch_add(1, Ordering::AcqRel)\n    /// }\n    /// ```\n    ///\n    /// If shared modification of the value is desired, a `static` item is needed instead.\n    /// If that is not desired, a `const fn` constructor should be used to make it obvious\n    /// at the use site that a new value is created.\n    ///\n    /// ### Known problems\n    /// Prior to `const fn` stabilization this was the only way to provide a value which\n    /// could initialize a `static` item (e.g. the `std::sync::ONCE_INIT` constant). In\n    /// this case the use of `const` is required and this lint should be suppressed.\n    ///\n    /// There also exists types which contain private fields with interior mutability, but\n    /// no way to both create a value as a constant and modify any mutable field using the\n    /// type's public interface (e.g. `bytes::Bytes`). As there is no reasonable way to\n    /// scan a crate's interface to see if this is the case, all such types will be linted.\n    /// If this happens use the `ignore-interior-mutability` configuration option to allow\n    /// the type.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};\n    ///\n    /// const CONST_ATOM: AtomicUsize = AtomicUsize::new(12);\n    /// CONST_ATOM.store(6, SeqCst); // the content of the atomic is unchanged\n    /// assert_eq!(CONST_ATOM.load(SeqCst), 12); // because the CONST_ATOM in these lines are distinct\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};\n    /// static STATIC_ATOM: AtomicUsize = AtomicUsize::new(15);\n    /// STATIC_ATOM.store(9, SeqCst);\n    /// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DECLARE_INTERIOR_MUTABLE_CONST,\n    suspicious,\n    \"declaring `const` with interior mutability\"\n}\n\nimpl_lint_pass!(NonCopyConst<'_> => [\n    BORROW_INTERIOR_MUTABLE_CONST,\n    DECLARE_INTERIOR_MUTABLE_CONST,\n]);\n\n#[derive(Clone, Copy)]\nenum IsFreeze {\n    /// The type and all possible values are `Freeze`\n    Yes,\n    /// The type itself is non-`Freeze`, but not all values are.\n    Maybe,\n    /// The type and all possible values are non-`Freeze`\n    No,\n}\nimpl IsFreeze {\n    /// Merges the variants of a sum type (i.e. an enum).\n    fn from_variants(iter: impl Iterator<Item = Self>) -> Self {\n        iter.fold(Self::Yes, |x, y| match (x, y) {\n            (Self::Maybe, _) | (_, Self::Maybe) | (Self::No, Self::Yes) | (Self::Yes, Self::No) => Self::Maybe,\n            (Self::No, Self::No) => Self::No,\n            (Self::Yes, Self::Yes) => Self::Yes,\n        })\n    }\n\n    /// Merges the fields of a product type (e.g. a struct or tuple).\n    fn from_fields(mut iter: impl Iterator<Item = Self>) -> Self {\n        iter.try_fold(Self::Yes, |x, y| match (x, y) {\n            (Self::No, _) | (_, Self::No) => None,\n            (Self::Maybe, _) | (_, Self::Maybe) => Some(Self::Maybe),\n            (Self::Yes, Self::Yes) => Some(Self::Yes),\n        })\n        .unwrap_or(Self::No)\n    }\n\n    /// Checks if this is definitely `Freeze`.\n    fn is_freeze(self) -> bool {\n        matches!(self, Self::Yes)\n    }\n\n    /// Checks if this is definitely not `Freeze`.\n    fn is_not_freeze(self) -> bool {\n        matches!(self, Self::No)\n    }\n}\n\n/// What operation caused a borrow to occur.\n#[derive(Clone, Copy)]\nenum BorrowCause {\n    Borrow,\n    Deref,\n    Index,\n    AutoDeref,\n    AutoBorrow,\n    AutoDerefField,\n}\nimpl BorrowCause {\n    fn note(self) -> Option<&'static str> {\n        match self {\n            Self::Borrow => None,\n            Self::Deref => Some(\"this deref expression is a call to `Deref::deref`\"),\n            Self::Index => Some(\"this index expression is a call to `Index::index`\"),\n            Self::AutoDeref => Some(\"there is a compiler inserted call to `Deref::deref` here\"),\n            Self::AutoBorrow => Some(\"there is a compiler inserted borrow here\"),\n            Self::AutoDerefField => {\n                Some(\"there is a compiler inserted call to `Deref::deref` when accessing this field\")\n            },\n        }\n    }\n}\n\n/// The source of a borrow. Both what caused it and where.\nstruct BorrowSource<'tcx> {\n    expr: &'tcx Expr<'tcx>,\n    cause: BorrowCause,\n}\nimpl<'tcx> BorrowSource<'tcx> {\n    fn new(tcx: TyCtxt<'tcx>, expr: &'tcx Expr<'tcx>, cause: BorrowCause) -> Self {\n        // Custom deref and index impls will always have an auto-borrow inserted since we\n        // never work with reference types.\n        let (expr, cause) = if matches!(cause, BorrowCause::AutoBorrow)\n            && let Node::Expr(parent) = tcx.parent_hir_node(expr.hir_id)\n        {\n            match parent.kind {\n                ExprKind::Unary(UnOp::Deref, _) => (parent, BorrowCause::Deref),\n                ExprKind::Index(..) => (parent, BorrowCause::Index),\n                ExprKind::Field(..) => (parent, BorrowCause::AutoDerefField),\n                _ => (expr, cause),\n            }\n        } else {\n            (expr, cause)\n        };\n        Self { expr, cause }\n    }\n}\n\npub struct NonCopyConst<'tcx> {\n    ignore_tys: DefIdSet,\n    // Cache checked types. We can recurse through a type multiple times so this\n    // can be hit quite frequently.\n    freeze_tys: FxHashMap<Ty<'tcx>, IsFreeze>,\n}\n\nimpl<'tcx> NonCopyConst<'tcx> {\n    pub fn new(tcx: TyCtxt<'tcx>, conf: &'static Conf) -> Self {\n        Self {\n            ignore_tys: conf\n                .ignore_interior_mutability\n                .iter()\n                .flat_map(|ignored_ty| lookup_path_str(tcx, PathNS::Type, ignored_ty))\n                .collect(),\n            freeze_tys: FxHashMap::default(),\n        }\n    }\n\n    /// Checks if a value of the given type is `Freeze`, or may be depending on the value.\n    fn is_ty_freeze(&mut self, tcx: TyCtxt<'tcx>, typing_env: TypingEnv<'tcx>, ty: Ty<'tcx>) -> IsFreeze {\n        // FIXME: this should probably be using the trait solver\n        let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);\n        match self.freeze_tys.entry(ty) {\n            Entry::Occupied(e) => *e.get(),\n            Entry::Vacant(e) => {\n                let e = e.insert(IsFreeze::Yes);\n                if ty.is_freeze(tcx, typing_env) {\n                    return IsFreeze::Yes;\n                }\n                let is_freeze = match *ty.kind() {\n                    ty::Adt(adt, _) if adt.is_unsafe_cell() => {\n                        *e = IsFreeze::No;\n                        return IsFreeze::No;\n                    },\n                    ty::Adt(adt, _) if self.ignore_tys.contains(&adt.did()) => return IsFreeze::Yes,\n                    ty::Adt(adt, args) if adt.is_enum() => IsFreeze::from_variants(adt.variants().iter().map(|v| {\n                        IsFreeze::from_fields(\n                            v.fields\n                                .iter()\n                                .map(|f| self.is_ty_freeze(tcx, typing_env, f.ty(tcx, args))),\n                        )\n                    })),\n                    // Workaround for `ManuallyDrop`-like unions.\n                    ty::Adt(adt, args)\n                        if adt.is_union()\n                            && adt.non_enum_variant().fields.iter().any(|f| {\n                                tcx.layout_of(typing_env.as_query_input(f.ty(tcx, args)))\n                                    .is_ok_and(|l| l.layout.size().bytes() == 0)\n                            }) =>\n                    {\n                        return IsFreeze::Yes;\n                    },\n                    // Rust doesn't have the concept of an active union field so we have\n                    // to treat all fields as active.\n                    ty::Adt(adt, args) => IsFreeze::from_fields(\n                        adt.non_enum_variant()\n                            .fields\n                            .iter()\n                            .map(|f| self.is_ty_freeze(tcx, typing_env, f.ty(tcx, args))),\n                    ),\n                    ty::Array(ty, _) | ty::Pat(ty, _) => self.is_ty_freeze(tcx, typing_env, ty),\n                    ty::Tuple(tys) => {\n                        IsFreeze::from_fields(tys.iter().map(|ty| self.is_ty_freeze(tcx, typing_env, ty)))\n                    },\n                    // Treat type parameters as though they were `Freeze`.\n                    ty::Param(_) | ty::Alias(..) => return IsFreeze::Yes,\n                    // TODO: check other types.\n                    _ => {\n                        *e = IsFreeze::No;\n                        return IsFreeze::No;\n                    },\n                };\n                if !is_freeze.is_freeze() {\n                    self.freeze_tys.insert(ty, is_freeze);\n                }\n                is_freeze\n            },\n        }\n    }\n\n    /// Checks if the given constant value is `Freeze`. Returns `Err` if the constant\n    /// cannot be read, but the result depends on the value.\n    fn is_value_freeze(\n        &mut self,\n        tcx: TyCtxt<'tcx>,\n        typing_env: TypingEnv<'tcx>,\n        ty: Ty<'tcx>,\n        val: ConstValue,\n    ) -> Result<bool, ()> {\n        let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);\n        match self.is_ty_freeze(tcx, typing_env, ty) {\n            IsFreeze::Yes => Ok(true),\n            IsFreeze::Maybe if matches!(ty.kind(), ty::Adt(..) | ty::Array(..) | ty::Tuple(..)) => {\n                for &(val, ty) in tcx\n                    .try_destructure_mir_constant_for_user_output(val, ty)\n                    .ok_or(())?\n                    .fields\n                {\n                    if !self.is_value_freeze(tcx, typing_env, ty, val)? {\n                        return Ok(false);\n                    }\n                }\n                Ok(true)\n            },\n            IsFreeze::Maybe | IsFreeze::No => Ok(false),\n        }\n    }\n\n    /// Checks if the given expression creates a value which is `Freeze`.\n    ///\n    /// This will return `true` if the type is maybe `Freeze`, but it cannot be\n    /// determined for certain from the value.\n    ///\n    /// `typing_env` and `gen_args` are from the constant's use site.\n    /// `typeck` and `e` are from the constant's definition site.\n    fn is_init_expr_freeze(\n        &mut self,\n        tcx: TyCtxt<'tcx>,\n        typing_env: TypingEnv<'tcx>,\n        typeck: &'tcx TypeckResults<'tcx>,\n        gen_args: GenericArgsRef<'tcx>,\n        e: &'tcx Expr<'tcx>,\n    ) -> bool {\n        // Make sure to instantiate all types coming from `typeck` with `gen_args`.\n        let ty = EarlyBinder::bind(typeck.expr_ty(e)).instantiate(tcx, gen_args);\n        let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);\n        match self.is_ty_freeze(tcx, typing_env, ty) {\n            IsFreeze::Yes => true,\n            IsFreeze::No => false,\n            IsFreeze::Maybe => match e.kind {\n                ExprKind::Block(b, _)\n                    if !b.targeted_by_break\n                        && b.stmts.is_empty()\n                        && let Some(e) = b.expr =>\n                {\n                    self.is_init_expr_freeze(tcx, typing_env, typeck, gen_args, e)\n                },\n                ExprKind::Path(ref p) => {\n                    let res = typeck.qpath_res(p, e.hir_id);\n                    let gen_args = EarlyBinder::bind(typeck.node_args(e.hir_id)).instantiate(tcx, gen_args);\n                    match res {\n                        Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did)\n                            if let Ok(val) =\n                                tcx.const_eval_resolve(typing_env, UnevaluatedConst::new(did, gen_args), DUMMY_SP)\n                                && let Ok(is_freeze) = self.is_value_freeze(tcx, typing_env, ty, val) =>\n                        {\n                            is_freeze\n                        },\n                        Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did)\n                            if let Some((typeck, init)) = get_const_hir_value(tcx, typing_env, did, gen_args) =>\n                        {\n                            self.is_init_expr_freeze(tcx, typing_env, typeck, gen_args, init)\n                        },\n                        // Either this is a unit constructor, or some unknown value.\n                        // In either case we consider the value to be `Freeze`.\n                        _ => true,\n                    }\n                },\n                ExprKind::Call(callee, args)\n                    if let ExprKind::Path(p) = &callee.kind\n                        && let res = typeck.qpath_res(p, callee.hir_id)\n                        && matches!(res, Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(_)) =>\n                {\n                    args.iter()\n                        .all(|e| self.is_init_expr_freeze(tcx, typing_env, typeck, gen_args, e))\n                },\n                ExprKind::Struct(_, fields, StructTailExpr::None) => fields\n                    .iter()\n                    .all(|f| self.is_init_expr_freeze(tcx, typing_env, typeck, gen_args, f.expr)),\n                ExprKind::Tup(exprs) | ExprKind::Array(exprs) => exprs\n                    .iter()\n                    .all(|e| self.is_init_expr_freeze(tcx, typing_env, typeck, gen_args, e)),\n                ExprKind::Repeat(e, _) => self.is_init_expr_freeze(tcx, typing_env, typeck, gen_args, e),\n                _ => true,\n            },\n        }\n    }\n\n    /// Checks if the given expression (or a local projection of it) is both borrowed and\n    /// definitely a non-`Freeze` type.\n    fn is_non_freeze_expr_borrowed(\n        &mut self,\n        tcx: TyCtxt<'tcx>,\n        typing_env: TypingEnv<'tcx>,\n        typeck: &'tcx TypeckResults<'tcx>,\n        mut src_expr: &'tcx Expr<'tcx>,\n    ) -> Option<BorrowSource<'tcx>> {\n        let mut parents = tcx.hir_parent_iter(src_expr.hir_id);\n        loop {\n            let ty = typeck.expr_ty(src_expr);\n            // Normalized as we need to check if this is an array later.\n            let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);\n            let is_freeze = self.is_ty_freeze(tcx, typing_env, ty);\n            if is_freeze.is_freeze() {\n                return None;\n            }\n            if let [adjust, ..] = typeck.expr_adjustments(src_expr) {\n                return does_adjust_borrow(adjust)\n                    .filter(|_| is_freeze.is_not_freeze())\n                    .map(|cause| BorrowSource::new(tcx, src_expr, cause));\n            }\n            let Some((_, Node::Expr(use_expr))) = parents.next() else {\n                return None;\n            };\n            match use_expr.kind {\n                ExprKind::Field(..) => {},\n                ExprKind::Index(..) if ty.is_array() => {},\n                ExprKind::AddrOf(..) if is_freeze.is_not_freeze() => {\n                    return Some(BorrowSource::new(tcx, use_expr, BorrowCause::Borrow));\n                },\n                // All other expressions use the value.\n                _ => return None,\n            }\n            src_expr = use_expr;\n        }\n    }\n\n    /// Checks if the given value (or a local projection of it) is both borrowed and\n    /// definitely non-`Freeze`. Returns `Err` if the constant cannot be read, but the\n    /// result depends on the value.\n    fn is_non_freeze_val_borrowed(\n        &mut self,\n        tcx: TyCtxt<'tcx>,\n        typing_env: TypingEnv<'tcx>,\n        typeck: &'tcx TypeckResults<'tcx>,\n        mut src_expr: &'tcx Expr<'tcx>,\n        mut val: ConstValue,\n    ) -> Result<Option<BorrowSource<'tcx>>, ()> {\n        let mut parents = tcx.hir_parent_iter(src_expr.hir_id);\n        let mut ty = typeck.expr_ty(src_expr);\n        loop {\n            // Normalized as we need to check if this is an array later.\n            ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);\n            if let [adjust, ..] = typeck.expr_adjustments(src_expr) {\n                let res = if let Some(cause) = does_adjust_borrow(adjust)\n                    && !self.is_value_freeze(tcx, typing_env, ty, val)?\n                {\n                    Some(BorrowSource::new(tcx, src_expr, cause))\n                } else {\n                    None\n                };\n                return Ok(res);\n            }\n            // Check only the type here as the result gets cached for each type.\n            if self.is_ty_freeze(tcx, typing_env, ty).is_freeze() {\n                return Ok(None);\n            }\n            let Some((_, Node::Expr(use_expr))) = parents.next() else {\n                return Ok(None);\n            };\n            let next_val = match use_expr.kind {\n                ExprKind::Field(_, name) => {\n                    if let Some(idx) = get_field_idx_by_name(ty, name.name) {\n                        tcx.try_destructure_mir_constant_for_user_output(val, ty)\n                            .ok_or(())?\n                            .fields\n                            .get(idx)\n                    } else {\n                        return Ok(None);\n                    }\n                },\n                ExprKind::Index(_, idx, _) if ty.is_array() => {\n                    let val = tcx.try_destructure_mir_constant_for_user_output(val, ty).ok_or(())?;\n                    if let Some(Constant::Int(idx)) = ConstEvalCtxt::with_env(tcx, typing_env, typeck).eval(idx) {\n                        val.fields.get(idx as usize)\n                    } else {\n                        // It's some value in the array so check all of them.\n                        for &(val, _) in val.fields {\n                            if let Some(src) =\n                                self.is_non_freeze_val_borrowed(tcx, typing_env, typeck, use_expr, val)?\n                            {\n                                return Ok(Some(src));\n                            }\n                        }\n                        return Ok(None);\n                    }\n                },\n                ExprKind::AddrOf(..) if !self.is_value_freeze(tcx, typing_env, ty, val)? => {\n                    return Ok(Some(BorrowSource::new(tcx, use_expr, BorrowCause::Borrow)));\n                },\n                // All other expressions use the value.\n                _ => return Ok(None),\n            };\n            src_expr = use_expr;\n            if let Some(&(next_val, next_ty)) = next_val {\n                ty = next_ty;\n                val = next_val;\n            } else {\n                return Ok(None);\n            }\n        }\n    }\n\n    /// Checks if the given value (or a local projection of it) is both borrowed and\n    /// definitely non-`Freeze`.\n    ///\n    /// `typing_env` and `init_args` are from the constant's use site.\n    /// `init_typeck` and `init_expr` are from the constant's definition site.\n    #[expect(clippy::too_many_arguments, clippy::too_many_lines)]\n    fn is_non_freeze_init_borrowed(\n        &mut self,\n        tcx: TyCtxt<'tcx>,\n        typing_env: TypingEnv<'tcx>,\n        typeck: &'tcx TypeckResults<'tcx>,\n        mut src_expr: &'tcx Expr<'tcx>,\n        mut init_typeck: &'tcx TypeckResults<'tcx>,\n        mut init_args: GenericArgsRef<'tcx>,\n        mut init_expr: &'tcx Expr<'tcx>,\n    ) -> Option<BorrowSource<'tcx>> {\n        // Make sure to instantiate all types coming from `init_typeck` with `init_args`.\n        let mut parents = tcx.hir_parent_iter(src_expr.hir_id);\n        loop {\n            // First handle any adjustments since they are cheap to check.\n            if let [adjust, ..] = typeck.expr_adjustments(src_expr) {\n                return does_adjust_borrow(adjust)\n                    .filter(|_| !self.is_init_expr_freeze(tcx, typing_env, init_typeck, init_args, init_expr))\n                    .map(|cause| BorrowSource::new(tcx, src_expr, cause));\n            }\n\n            // Then read through constants and blocks on the init expression before\n            // applying the next use expression.\n            loop {\n                match init_expr.kind {\n                    ExprKind::Block(b, _)\n                        if !b.targeted_by_break\n                            && b.stmts.is_empty()\n                            && let Some(next_init) = b.expr =>\n                    {\n                        init_expr = next_init;\n                    },\n                    ExprKind::Path(ref init_path) => {\n                        let next_init_args =\n                            EarlyBinder::bind(init_typeck.node_args(init_expr.hir_id)).instantiate(tcx, init_args);\n                        match init_typeck.qpath_res(init_path, init_expr.hir_id) {\n                            Res::Def(DefKind::Ctor(..), _) => return None,\n                            Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did)\n                                if let Ok(val) = tcx.const_eval_resolve(\n                                    typing_env,\n                                    UnevaluatedConst::new(did, next_init_args),\n                                    DUMMY_SP,\n                                ) && let Ok(res) =\n                                    self.is_non_freeze_val_borrowed(tcx, typing_env, init_typeck, src_expr, val) =>\n                            {\n                                return res;\n                            },\n                            Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did)\n                                if let Some((next_typeck, value)) =\n                                    get_const_hir_value(tcx, typing_env, did, next_init_args) =>\n                            {\n                                init_typeck = next_typeck;\n                                init_args = next_init_args;\n                                init_expr = value;\n                            },\n                            // There's no more that we can read from the init expression. Switch to a\n                            // type based check.\n                            _ => {\n                                return self.is_non_freeze_expr_borrowed(tcx, typing_env, typeck, src_expr);\n                            },\n                        }\n                    },\n                    _ => break,\n                }\n            }\n\n            // Then a type check. Note we only check the type here as the result\n            // gets cached.\n            let ty = typeck.expr_ty(src_expr);\n            // Normalized as we need to check if this is an array later.\n            let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty);\n            if self.is_ty_freeze(tcx, typing_env, ty).is_freeze() {\n                return None;\n            }\n\n            // Finally reduce the init expression using the next use expression.\n            let Some((_, Node::Expr(use_expr))) = parents.next() else {\n                return None;\n            };\n            init_expr = match &use_expr.kind {\n                ExprKind::Field(_, name) => match init_expr.kind {\n                    ExprKind::Struct(_, fields, _)\n                        if let Some(field) = fields.iter().find(|f| f.ident.name == name.name) =>\n                    {\n                        field.expr\n                    },\n                    ExprKind::Tup(fields)\n                        if let Ok(idx) = name.as_str().parse::<usize>()\n                            && let Some(field) = fields.get(idx) =>\n                    {\n                        field\n                    },\n                    ExprKind::Call(callee, args)\n                        if let ExprKind::Path(callee_path) = &callee.kind\n                            && matches!(\n                                init_typeck.qpath_res(callee_path, callee.hir_id),\n                                Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(_)\n                            )\n                            && let Ok(idx) = name.as_str().parse::<usize>()\n                            && let Some(arg) = args.get(idx) =>\n                    {\n                        arg\n                    },\n                    // Revert to a type based check as we don't know the field's value.\n                    _ => return self.is_non_freeze_expr_borrowed(tcx, typing_env, typeck, use_expr),\n                },\n                ExprKind::Index(_, idx, _) if ty.is_array() => match init_expr.kind {\n                    ExprKind::Array(fields) => {\n                        if let Some(Constant::Int(idx)) = ConstEvalCtxt::with_env(tcx, typing_env, typeck).eval(idx) {\n                            // If the index is out of bounds it means the code\n                            // unconditionally panics. In that case there is no borrow.\n                            fields.get(idx as usize)?\n                        } else {\n                            // Unknown index, just run the check for all values.\n                            return fields.iter().find_map(|f| {\n                                self.is_non_freeze_init_borrowed(\n                                    tcx,\n                                    typing_env,\n                                    typeck,\n                                    use_expr,\n                                    init_typeck,\n                                    init_args,\n                                    f,\n                                )\n                            });\n                        }\n                    },\n                    // Just assume the index expression doesn't panic here.\n                    ExprKind::Repeat(field, _) => field,\n                    _ => return self.is_non_freeze_expr_borrowed(tcx, typing_env, typeck, use_expr),\n                },\n                ExprKind::AddrOf(..)\n                    if !self.is_init_expr_freeze(tcx, typing_env, init_typeck, init_args, init_expr) =>\n                {\n                    return Some(BorrowSource::new(tcx, use_expr, BorrowCause::Borrow));\n                },\n                // All other expressions use the value.\n                _ => return None,\n            };\n            src_expr = use_expr;\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NonCopyConst<'tcx> {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Const(ident, .., ct_rhs) = item.kind\n            && !ident.is_special()\n            && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n            && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) {\n                IsFreeze::No => true,\n                IsFreeze::Yes => false,\n                IsFreeze::Maybe => match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) {\n                    Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => !is_freeze,\n                    // FIXME: we just assume mgca rhs's are freeze\n                    _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).is_some_and(|e| !self.is_init_expr_freeze(\n                        cx.tcx,\n                        cx.typing_env(),\n                        cx.tcx.typeck(item.owner_id),\n                        GenericArgs::identity_for_item(cx.tcx, item.owner_id),\n                        e\n                    )),\n                },\n            }\n            && !item.span.in_external_macro(cx.sess().source_map())\n            // Only needed when compiling `std`\n            && !is_thread_local(cx, item)\n        {\n            span_lint_and_then(\n                cx,\n                DECLARE_INTERIOR_MUTABLE_CONST,\n                ident.span,\n                \"named constant with interior mutability\",\n                |diag| {\n                    let Some(sync_trait) = cx.tcx.lang_items().sync_trait() else {\n                        return;\n                    };\n                    if implements_trait(cx, ty, sync_trait, &[]) {\n                        diag.help(\"did you mean to make this a `static` item\");\n                    } else {\n                        diag.help(\"did you mean to make this a `thread_local!` item\");\n                    }\n                },\n            );\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {\n        if let TraitItemKind::Const(_, ct_rhs_opt, _) = item.kind\n            && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n            && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) {\n                IsFreeze::No => true,\n                IsFreeze::Maybe if let Some(ct_rhs) = ct_rhs_opt => {\n                    match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) {\n                        Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => {\n                            !is_freeze\n                        },\n                        // FIXME: we just assume mgca rhs's are freeze\n                        _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).is_some_and(|e| {\n                            !self.is_init_expr_freeze(\n                                cx.tcx,\n                                cx.typing_env(),\n                                cx.tcx.typeck(item.owner_id),\n                                GenericArgs::identity_for_item(cx.tcx, item.owner_id),\n                                e,\n                            )\n                        }),\n                    }\n                },\n                IsFreeze::Yes | IsFreeze::Maybe => false,\n            }\n            && !item.span.in_external_macro(cx.sess().source_map())\n        {\n            span_lint(\n                cx,\n                DECLARE_INTERIOR_MUTABLE_CONST,\n                item.ident.span,\n                \"named constant with interior mutability\",\n            );\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {\n        if let ImplItemKind::Const(_, ct_rhs) = item.kind\n            && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()\n            && match self.is_ty_freeze(cx.tcx, cx.typing_env(), ty) {\n                IsFreeze::Yes => false,\n                IsFreeze::No => {\n                    // If this is a trait impl, check if the trait definition is the source\n                    // of the cell.\n                    if let Node::Item(parent_item) = cx.tcx.parent_hir_node(item.hir_id())\n                        && let ItemKind::Impl(impl_block) = parent_item.kind\n                        && let Some(of_trait) = impl_block.of_trait\n                        && let Some(trait_id) = of_trait.trait_ref.trait_def_id()\n                    {\n                        // Replace all instances of `<Self as Trait>::AssocType` with the\n                        // unit type and check again. If the result is the same then the\n                        // trait definition is the cause.\n                        let ty = (ReplaceAssocFolder {\n                            tcx: cx.tcx,\n                            trait_id,\n                            self_ty: cx.tcx.type_of(parent_item.owner_id).instantiate_identity(),\n                        })\n                        .fold_ty(cx.tcx.type_of(item.owner_id).instantiate_identity());\n                        // `ty` may not be normalizable, but that should be fine.\n                        !self.is_ty_freeze(cx.tcx, cx.typing_env(), ty).is_not_freeze()\n                    } else {\n                        true\n                    }\n                },\n                // Even if this is from a trait, there are values which don't have\n                // interior mutability.\n                IsFreeze::Maybe => match cx.tcx.const_eval_poly(item.owner_id.to_def_id()) {\n                    Ok(val) if let Ok(is_freeze) = self.is_value_freeze(cx.tcx, cx.typing_env(), ty, val) => !is_freeze,\n                    // FIXME: we just assume mgca rhs's are freeze\n                    _ => const_item_rhs_to_expr(cx.tcx, ct_rhs).is_some_and(|e| {\n                        !self.is_init_expr_freeze(\n                            cx.tcx,\n                            cx.typing_env(),\n                            cx.tcx.typeck(item.owner_id),\n                            GenericArgs::identity_for_item(cx.tcx, item.owner_id),\n                            e,\n                        )\n                    }),\n                },\n            }\n            && !item.span.in_external_macro(cx.sess().source_map())\n        {\n            span_lint(\n                cx,\n                DECLARE_INTERIOR_MUTABLE_CONST,\n                item.ident.span,\n                \"named constant with interior mutability\",\n            );\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let ExprKind::Path(qpath) = &e.kind\n            && let typeck = cx.typeck_results()\n            && let Res::Def(DefKind::Const { .. } | DefKind::AssocConst { .. }, did) = typeck.qpath_res(qpath, e.hir_id)\n            // As of `1.80` constant contexts can't borrow any type with interior mutability\n            && !is_in_const_context(cx)\n            && !self.is_ty_freeze(cx.tcx, cx.typing_env(), typeck.expr_ty(e)).is_freeze()\n            && let Some(borrow_src) = {\n                // The extra block helps formatting a lot.\n                if let Ok(val) = cx.tcx.const_eval_resolve(\n                    cx.typing_env(),\n                    UnevaluatedConst::new(did, typeck.node_args(e.hir_id)),\n                    DUMMY_SP,\n                ) && let Ok(src) = self.is_non_freeze_val_borrowed(cx.tcx, cx.typing_env(), typeck, e, val)\n                {\n                    src\n                } else if let init_args = typeck.node_args(e.hir_id)\n                    && let Some((init_typeck, init)) = get_const_hir_value(cx.tcx, cx.typing_env(), did, init_args)\n                {\n                    self.is_non_freeze_init_borrowed(cx.tcx, cx.typing_env(), typeck, e, init_typeck, init_args, init)\n                } else {\n                    self.is_non_freeze_expr_borrowed(cx.tcx, cx.typing_env(), typeck, e)\n                }\n            }\n            && !borrow_src.expr.span.in_external_macro(cx.sess().source_map())\n        {\n            span_lint_and_then(\n                cx,\n                BORROW_INTERIOR_MUTABLE_CONST,\n                borrow_src.expr.span,\n                \"borrow of a named constant with interior mutability\",\n                |diag| {\n                    if let Some(note) = borrow_src.cause.note() {\n                        diag.note(note);\n                    }\n                    diag.help(\"this lint can be silenced by assigning the value to a local variable before borrowing\");\n                },\n            );\n        }\n    }\n}\n\nstruct ReplaceAssocFolder<'tcx> {\n    tcx: TyCtxt<'tcx>,\n    trait_id: DefId,\n    self_ty: Ty<'tcx>,\n}\nimpl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceAssocFolder<'tcx> {\n    fn cx(&self) -> TyCtxt<'tcx> {\n        self.tcx\n    }\n\n    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {\n        if let ty::Alias(AliasTyKind::Projection, ty) = ty.kind()\n            && ty.trait_def_id(self.tcx) == self.trait_id\n            && ty.self_ty() == self.self_ty\n        {\n            self.tcx.types.unit\n        } else {\n            ty.super_fold_with(self)\n        }\n    }\n}\n\nfn is_thread_local(cx: &LateContext<'_>, it: &Item<'_>) -> bool {\n    macro_backtrace(it.span).any(|macro_call| {\n        matches!(\n            cx.tcx.get_diagnostic_name(macro_call.def_id),\n            Some(sym::thread_local_macro)\n        )\n    })\n}\n\n/// Checks if the adjustment causes a borrow of the original value. Returns\n/// `None` if the value is consumed instead of borrowed.\nfn does_adjust_borrow(adjust: &Adjustment<'_>) -> Option<BorrowCause> {\n    match adjust.kind {\n        Adjust::Borrow(_) => Some(BorrowCause::AutoBorrow),\n        // Custom deref calls `<T as Deref>::deref(&x)` resulting in a borrow.\n        Adjust::Deref(DerefAdjustKind::Overloaded(_)) => Some(BorrowCause::AutoDeref),\n        // All other adjustments read the value.\n        _ => None,\n    }\n}\n\n/// Attempts to get the value of a constant as a HIR expression. Also gets the\n/// `TypeckResults` associated with the constant's body.\nfn get_const_hir_value<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    typing_env: TypingEnv<'tcx>,\n    did: DefId,\n    args: GenericArgsRef<'tcx>,\n) -> Option<(&'tcx TypeckResults<'tcx>, &'tcx Expr<'tcx>)> {\n    let did = did.as_local()?;\n    let (did, ct_rhs) = match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) {\n        Node::Item(item) if let ItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs),\n        Node::ImplItem(item) if let ImplItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs),\n        Node::TraitItem(_)\n            if let Ok(Some(inst)) = Instance::try_resolve(tcx, typing_env, did.into(), args)\n                && let Some(did) = inst.def_id().as_local() =>\n        {\n            match tcx.hir_node(tcx.local_def_id_to_hir_id(did)) {\n                Node::ImplItem(item) if let ImplItemKind::Const(.., ct_rhs) = item.kind => (did, ct_rhs),\n                Node::TraitItem(item) if let TraitItemKind::Const(_, Some(ct_rhs), _) = item.kind => (did, ct_rhs),\n                _ => return None,\n            }\n        },\n        _ => return None,\n    };\n    match ct_rhs {\n        ConstItemRhs::Body(body_id) => Some((tcx.typeck(did), tcx.hir_body(body_id).value)),\n        ConstItemRhs::TypeConst(ct_arg) => match ct_arg.kind {\n            ConstArgKind::Anon(anon_const) => Some((tcx.typeck(did), tcx.hir_body(anon_const.body).value)),\n            _ => None,\n        },\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/non_expressive_names.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse rustc_ast::ast::{\n    self, Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, Pat, PatKind,\n};\nuse rustc_ast::visit::{Visitor, walk_block, walk_expr, walk_pat};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::{Ident, Symbol};\nuse rustc_span::{Span, sym};\nuse std::cmp::Ordering;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if you have variables whose name consists of just\n    /// underscores and digits.\n    ///\n    /// ### Why is this bad?\n    /// It's hard to memorize what a variable means without a\n    /// descriptive name.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _1 = 1;\n    /// let ___1 = 1;\n    /// let __1___2 = 11;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub JUST_UNDERSCORES_AND_DIGITS,\n    style,\n    \"unclear name\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for too many variables whose name consists of a\n    /// single character.\n    ///\n    /// ### Why is this bad?\n    /// It's hard to memorize what a variable means without a\n    /// descriptive name.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// let (a, b, c, d, e, f, g) = (...);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MANY_SINGLE_CHAR_NAMES,\n    pedantic,\n    \"too many single character bindings\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for names that are very similar and thus confusing.\n    ///\n    /// Note: this lint looks for similar names throughout each\n    /// scope. To allow it, you need to allow it on the scope\n    /// level, not on the name that is reported.\n    ///\n    /// ### Why is this bad?\n    /// It's hard to distinguish between names that differ only\n    /// by a single character.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// let checked_exp = something;\n    /// let checked_expr = something_else;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SIMILAR_NAMES,\n    pedantic,\n    \"similarly named items and bindings\"\n}\n\nimpl_lint_pass!(NonExpressiveNames => [\n    JUST_UNDERSCORES_AND_DIGITS,\n    MANY_SINGLE_CHAR_NAMES,\n    SIMILAR_NAMES,\n]);\n\npub struct NonExpressiveNames {\n    pub single_char_binding_names_threshold: u64,\n}\n\nimpl NonExpressiveNames {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            single_char_binding_names_threshold: conf.single_char_binding_names_threshold,\n        }\n    }\n}\n\nstruct ExistingName {\n    interned: Symbol,\n    span: Span,\n    len: usize,\n    exemptions: &'static [&'static str],\n}\n\nstruct SimilarNamesLocalVisitor<'a, 'tcx> {\n    names: Vec<ExistingName>,\n    cx: &'a EarlyContext<'tcx>,\n    threshold: u64,\n\n    /// A stack of scopes containing the single-character bindings in each scope.\n    single_char_names: Vec<Vec<Ident>>,\n}\n\nimpl SimilarNamesLocalVisitor<'_, '_> {\n    fn check_single_char_names(&self) {\n        if self.single_char_names.last().map(Vec::len) == Some(0) {\n            return;\n        }\n\n        let num_single_char_names = self.single_char_names.iter().flatten().count();\n        if num_single_char_names as u64 > self.threshold {\n            let span = self\n                .single_char_names\n                .iter()\n                .flatten()\n                .map(|ident| ident.span)\n                .collect::<Vec<_>>();\n            span_lint(\n                self.cx,\n                MANY_SINGLE_CHAR_NAMES,\n                span,\n                format!(\"{num_single_char_names} bindings with single-character names in scope\"),\n            );\n        }\n    }\n}\n\n// this list contains lists of names that are allowed to be similar\n// the assumption is that no name is ever contained in multiple lists.\nconst ALLOWED_TO_BE_SIMILAR: &[&[&str]] = &[\n    &[\"parsed\", \"parser\"],\n    &[\"lhs\", \"rhs\"],\n    &[\"tx\", \"rx\"],\n    &[\"set\", \"get\"],\n    &[\"args\", \"arms\"],\n    &[\"qpath\", \"path\"],\n    &[\"lit\", \"lint\"],\n    &[\"wparam\", \"lparam\"],\n    &[\"iter\", \"item\"],\n];\n\n/// Characters that look visually similar\nconst SIMILAR_CHARS: &[(char, char)] = &[('l', 'i'), ('l', '1'), ('i', '1'), ('u', 'v')];\n\n/// Return true if two characters are visually similar\nfn chars_are_similar(a: char, b: char) -> bool {\n    a == b || SIMILAR_CHARS.contains(&(a, b)) || SIMILAR_CHARS.contains(&(b, a))\n}\n\nstruct SimilarNamesNameVisitor<'a, 'tcx, 'b>(&'b mut SimilarNamesLocalVisitor<'a, 'tcx>);\n\nimpl<'tcx> Visitor<'tcx> for SimilarNamesNameVisitor<'_, 'tcx, '_> {\n    fn visit_pat(&mut self, pat: &'tcx Pat) {\n        match pat.kind {\n            PatKind::Ident(_, ident, _) => {\n                if !pat.span.from_expansion() {\n                    self.check_ident(ident);\n                }\n            },\n            PatKind::Struct(_, _, ref fields, _) => {\n                for field in fields {\n                    if !field.is_shorthand {\n                        self.visit_pat(&field.pat);\n                    }\n                }\n            },\n            // just go through the first pattern, as either all patterns\n            // bind the same bindings or rustc would have errored much earlier\n            PatKind::Or(ref pats) => self.visit_pat(&pats[0]),\n            _ => walk_pat(self, pat),\n        }\n    }\n}\n\n#[must_use]\nfn get_exemptions(interned_name: &str) -> Option<&'static [&'static str]> {\n    ALLOWED_TO_BE_SIMILAR\n        .iter()\n        .find(|&&list| allowed_to_be_similar(interned_name, list))\n        .copied()\n}\n\n#[must_use]\nfn allowed_to_be_similar(interned_name: &str, list: &[&str]) -> bool {\n    list.iter()\n        .any(|&name| interned_name.starts_with(name) || interned_name.ends_with(name))\n}\n\nimpl SimilarNamesNameVisitor<'_, '_, '_> {\n    fn check_short_ident(&mut self, ident: Ident) {\n        // Ignore shadowing\n        if self\n            .0\n            .single_char_names\n            .iter()\n            .flatten()\n            .any(|id| id.name == ident.name)\n        {\n            return;\n        }\n\n        if let Some(scope) = &mut self.0.single_char_names.last_mut() {\n            scope.push(ident);\n        }\n    }\n\n    fn check_ident(&mut self, ident: Ident) {\n        let interned_name = ident.name.as_str();\n        // name can be empty if it comes from recovery\n        if interned_name.chars().any(char::is_uppercase) || interned_name.is_empty() {\n            return;\n        }\n        if interned_name.chars().all(|c| c.is_ascii_digit() || c == '_') {\n            span_lint(\n                self.0.cx,\n                JUST_UNDERSCORES_AND_DIGITS,\n                ident.span,\n                \"consider choosing a more descriptive name\",\n            );\n            return;\n        }\n        if interned_name.starts_with('_') {\n            // these bindings are typically unused or represent an ignored portion of a destructuring pattern\n            return;\n        }\n        let count = interned_name.chars().count();\n        if count < 3 {\n            if count == 1 {\n                self.check_short_ident(ident);\n            }\n            return;\n        }\n        for existing_name in &self.0.names {\n            if allowed_to_be_similar(interned_name, existing_name.exemptions) {\n                continue;\n            }\n\n            let existing_str = existing_name.interned.as_str();\n\n            // The first char being different is usually enough to set identifiers apart, as long\n            // as the characters aren't too similar.\n            if !chars_are_similar(\n                interned_name.chars().next().expect(\"len >= 1\"),\n                existing_str.chars().next().expect(\"len >= 1\"),\n            ) {\n                continue;\n            }\n\n            // Skip similarity check if both names are exactly 3 characters\n            if count == 3 && existing_name.len == 3 {\n                continue;\n            }\n\n            let dissimilar = match existing_name.len.cmp(&count) {\n                Ordering::Greater => existing_name.len - count != 1 || levenstein_not_1(interned_name, existing_str),\n                Ordering::Less => count - existing_name.len != 1 || levenstein_not_1(existing_str, interned_name),\n                Ordering::Equal => Self::equal_length_strs_not_similar(interned_name, existing_str),\n            };\n\n            if dissimilar {\n                continue;\n            }\n\n            span_lint_and_then(\n                self.0.cx,\n                SIMILAR_NAMES,\n                ident.span,\n                \"binding's name is too similar to existing binding\",\n                |diag| {\n                    diag.span_note(existing_name.span, \"existing binding defined here\");\n                },\n            );\n            return;\n        }\n        self.0.names.push(ExistingName {\n            interned: ident.name,\n            span: ident.span,\n            len: count,\n            exemptions: get_exemptions(interned_name).unwrap_or(&[]),\n        });\n    }\n\n    fn equal_length_strs_not_similar(interned_name: &str, existing_name: &str) -> bool {\n        let mut interned_chars = interned_name.chars();\n        let mut existing_chars = existing_name.chars();\n        let first_i = interned_chars.next().expect(\"we know we have at least one char\");\n        let first_e = existing_chars.next().expect(\"we know we have at least one char\");\n        let eq_or_numeric = |(a, b): (char, char)| a == b || a.is_numeric() && b.is_numeric();\n\n        if eq_or_numeric((first_i, first_e)) {\n            let last_i = interned_chars.next_back().expect(\"we know we have at least two chars\");\n            let last_e = existing_chars.next_back().expect(\"we know we have at least two chars\");\n            if eq_or_numeric((last_i, last_e)) {\n                if interned_chars\n                    .zip(existing_chars)\n                    .filter(|&ie| !eq_or_numeric(ie))\n                    .count()\n                    != 1\n                {\n                    return true;\n                }\n            } else {\n                let second_last_i = interned_chars\n                    .next_back()\n                    .expect(\"we know we have at least three chars\");\n                let second_last_e = existing_chars\n                    .next_back()\n                    .expect(\"we know we have at least three chars\");\n                if !eq_or_numeric((second_last_i, second_last_e))\n                    || second_last_i == '_'\n                    || !interned_chars.zip(existing_chars).all(eq_or_numeric)\n                {\n                    // allowed similarity foo_x, foo_y\n                    // or too many chars differ (foo_x, boo_y) or (foox, booy)\n                    return true;\n                }\n            }\n        } else {\n            let second_i = interned_chars.next().expect(\"we know we have at least two chars\");\n            let second_e = existing_chars.next().expect(\"we know we have at least two chars\");\n            if !eq_or_numeric((second_i, second_e))\n                || second_i == '_'\n                || !interned_chars.zip(existing_chars).all(eq_or_numeric)\n            {\n                // allowed similarity x_foo, y_foo\n                // or too many chars differ (x_foo, y_boo) or (xfoo, yboo)\n                return true;\n            }\n        }\n\n        false\n    }\n}\n\nimpl SimilarNamesLocalVisitor<'_, '_> {\n    /// ensure scoping rules work\n    fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {\n        let n = self.names.len();\n        let single_char_count = self.single_char_names.len();\n        f(self);\n        self.names.truncate(n);\n        self.single_char_names.truncate(single_char_count);\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'_, 'tcx> {\n    fn visit_local(&mut self, local: &'tcx Local) {\n        if let Some((init, els)) = &local.kind.init_else_opt() {\n            self.apply(|this| walk_expr(this, init));\n            if let Some(els) = els {\n                self.apply(|this| walk_block(this, els));\n            }\n        }\n        // add the pattern after the expression because the bindings aren't available\n        // yet in the init\n        // expression\n        SimilarNamesNameVisitor(self).visit_pat(&local.pat);\n    }\n    fn visit_block(&mut self, blk: &'tcx Block) {\n        self.single_char_names.push(vec![]);\n\n        self.apply(|this| walk_block(this, blk));\n\n        self.check_single_char_names();\n        self.single_char_names.pop();\n    }\n    fn visit_arm(&mut self, arm: &'tcx Arm) {\n        self.single_char_names.push(vec![]);\n\n        self.apply(|this| {\n            SimilarNamesNameVisitor(this).visit_pat(&arm.pat);\n            if let Some(body) = &arm.body {\n                this.apply(|this| walk_expr(this, body));\n            }\n        });\n\n        self.check_single_char_names();\n        self.single_char_names.pop();\n    }\n    fn visit_item(&mut self, _: &Item) {\n        // do not recurse into inner items\n    }\n}\n\nimpl EarlyLintPass for NonExpressiveNames {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if item.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if let ItemKind::Fn(box ast::Fn {\n            ref sig,\n            body: Some(ref blk),\n            ..\n        }) = item.kind\n        {\n            do_check(self, cx, &item.attrs, &sig.decl, blk);\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &AssocItem) {\n        if item.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if let AssocItemKind::Fn(box ast::Fn {\n            ref sig,\n            body: Some(ref blk),\n            ..\n        }) = item.kind\n        {\n            do_check(self, cx, &item.attrs, &sig.decl, blk);\n        }\n    }\n}\n\nfn do_check(lint: &NonExpressiveNames, cx: &EarlyContext<'_>, attrs: &[Attribute], decl: &FnDecl, blk: &Block) {\n    if !attrs.iter().any(|attr| attr.has_name(sym::test)) {\n        let mut visitor = SimilarNamesLocalVisitor {\n            names: Vec::new(),\n            cx,\n            threshold: lint.single_char_binding_names_threshold,\n            single_char_names: vec![vec![]],\n        };\n\n        // initialize with function arguments\n        for arg in &decl.inputs {\n            SimilarNamesNameVisitor(&mut visitor).visit_pat(&arg.pat);\n        }\n        // walk all other bindings\n        walk_block(&mut visitor, blk);\n\n        visitor.check_single_char_names();\n    }\n}\n\n/// Precondition: `a_name.chars().count() < b_name.chars().count()`.\n#[must_use]\nfn levenstein_not_1(a_name: &str, b_name: &str) -> bool {\n    debug_assert!(a_name.chars().count() < b_name.chars().count());\n    let mut a_chars = a_name.chars();\n    let mut b_chars = b_name.chars();\n    while let (Some(a), Some(b)) = (a_chars.next(), b_chars.next()) {\n        if a == b {\n            continue;\n        }\n        if let Some(b2) = b_chars.next() {\n            // check if there's just one character inserted\n            return a != b2 || a_chars.ne(b_chars);\n        }\n        // tuple\n        // ntuple\n        return true;\n    }\n    // for item in items\n    true\n}\n"
  },
  {
    "path": "clippy_lints/src/non_octal_unix_permissions.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{SpanRangeExt, snippet_with_applicability};\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for non-octal values used to set Unix file permissions.\n    ///\n    /// ### Why is this bad?\n    /// They will be converted into octal, creating potentially\n    /// unintended file permissions.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// use std::fs::OpenOptions;\n    /// use std::os::unix::fs::OpenOptionsExt;\n    ///\n    /// let mut options = OpenOptions::new();\n    /// options.mode(644);\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// use std::fs::OpenOptions;\n    /// use std::os::unix::fs::OpenOptionsExt;\n    ///\n    /// let mut options = OpenOptions::new();\n    /// options.mode(0o644);\n    /// ```\n    #[clippy::version = \"1.53.0\"]\n    pub NON_OCTAL_UNIX_PERMISSIONS,\n    correctness,\n    \"use of non-octal value to set unix file permissions, which will be translated into octal\"\n}\n\ndeclare_lint_pass!(NonOctalUnixPermissions => [NON_OCTAL_UNIX_PERMISSIONS]);\n\nimpl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        match &expr.kind {\n            ExprKind::MethodCall(path, func, [param], _) => {\n                if let Some(adt) = cx.typeck_results().expr_ty(func).peel_refs().ty_adt_def()\n                    && matches!(\n                        (cx.tcx.get_diagnostic_name(adt.did()), path.ident.name),\n                        (Some(sym::FsOpenOptions | sym::DirBuilder), sym::mode)\n                            | (Some(sym::FsPermissions), sym::set_mode)\n                    )\n                    && let ExprKind::Lit(_) = param.kind\n                    && param.span.eq_ctxt(expr.span)\n                    && param\n                        .span\n                        .check_source_text(cx, |src| !matches!(src.as_bytes(), [b'0', b'o' | b'b', ..]))\n                {\n                    show_error(cx, param);\n                }\n            },\n            ExprKind::Call(func, [param]) => {\n                if let ExprKind::Path(ref path) = func.kind\n                    && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()\n                    && cx.tcx.is_diagnostic_item(sym::permissions_from_mode, def_id)\n                    && let ExprKind::Lit(_) = param.kind\n                    && param.span.eq_ctxt(expr.span)\n                    && param\n                        .span\n                        .check_source_text(cx, |src| !matches!(src.as_bytes(), [b'0', b'o' | b'b', ..]))\n                {\n                    show_error(cx, param);\n                }\n            },\n            _ => {},\n        }\n    }\n}\n\nfn show_error(cx: &LateContext<'_>, param: &Expr<'_>) {\n    let mut applicability = Applicability::MachineApplicable;\n    span_lint_and_sugg(\n        cx,\n        NON_OCTAL_UNIX_PERMISSIONS,\n        param.span,\n        \"using a non-octal value to set unix file permissions\",\n        \"consider using an octal literal instead\",\n        format!(\n            \"0o{}\",\n            snippet_with_applicability(cx, param.span, \"0o..\", &mut applicability,),\n        ),\n        applicability,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/non_send_fields_in_send_ty.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_lint_allowed;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse rustc_ast::ImplPolarity;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{FieldDef, Item, ItemKind, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, GenericArgKind, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns about a `Send` implementation for a type that\n    /// contains fields that are not safe to be sent across threads.\n    /// It tries to detect fields that can cause a soundness issue\n    /// when sent to another thread (e.g., `Rc`) while allowing `!Send` fields\n    /// that are expected to exist in a `Send` type, such as raw pointers.\n    ///\n    /// ### Why is this bad?\n    /// Sending the struct to another thread effectively sends all of its fields,\n    /// and the fields that do not implement `Send` can lead to soundness bugs\n    /// such as data races when accessed in a thread\n    /// that is different from the thread that created it.\n    ///\n    /// See:\n    /// * [*The Rustonomicon* about *Send and Sync*](https://doc.rust-lang.org/nomicon/send-and-sync.html)\n    /// * [The documentation of `Send`](https://doc.rust-lang.org/std/marker/trait.Send.html)\n    ///\n    /// ### Known Problems\n    /// This lint relies on heuristics to distinguish types that are actually\n    /// unsafe to be sent across threads and `!Send` types that are expected to\n    /// exist in  `Send` type. Its rule can filter out basic cases such as\n    /// `Vec<*const T>`, but it's not perfect. Feel free to create an issue if\n    /// you have a suggestion on how this heuristic can be improved.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// struct ExampleStruct<T> {\n    ///     rc_is_not_send: Rc<String>,\n    ///     unbounded_generic_field: T,\n    /// }\n    ///\n    /// // This impl is unsound because it allows sending `!Send` types through `ExampleStruct`\n    /// unsafe impl<T> Send for ExampleStruct<T> {}\n    /// ```\n    /// Use thread-safe types like [`std::sync::Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html)\n    /// or specify correct bounds on generic type parameters (`T: Send`).\n    #[clippy::version = \"1.57.0\"]\n    pub NON_SEND_FIELDS_IN_SEND_TY,\n    nursery,\n    \"there is a field that is not safe to be sent to another thread in a `Send` struct\"\n}\n\nimpl_lint_pass!(NonSendFieldInSendTy => [NON_SEND_FIELDS_IN_SEND_TY]);\n\npub struct NonSendFieldInSendTy {\n    enable_raw_pointer_heuristic: bool,\n}\n\nimpl NonSendFieldInSendTy {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            enable_raw_pointer_heuristic: conf.enable_raw_pointer_heuristic_for_send,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        let ty_allowed_in_send = if self.enable_raw_pointer_heuristic {\n            ty_allowed_with_raw_pointer_heuristic\n        } else {\n            ty_allowed_without_raw_pointer_heuristic\n        };\n\n        // Checks if we are in `Send` impl item.\n        // We start from `Send` impl instead of `check_field_def()` because\n        // single `AdtDef` may have multiple `Send` impls due to generic\n        // parameters, and the lint is much easier to implement in this way.\n        if !item.span.in_external_macro(cx.tcx.sess.source_map())\n            && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)\n            && let ItemKind::Impl(hir_impl) = &item.kind\n            && let Some(of_trait) = &hir_impl.of_trait\n            && let Some(trait_id) = of_trait.trait_ref.trait_def_id()\n            && send_trait == trait_id\n            && of_trait.polarity == ImplPolarity::Positive\n            && let ty_trait_ref = cx.tcx.impl_trait_ref(item.owner_id)\n            && let self_ty = ty_trait_ref.instantiate_identity().self_ty()\n            && let ty::Adt(adt_def, impl_trait_args) = self_ty.kind()\n        {\n            let mut non_send_fields = Vec::new();\n\n            for variant in adt_def.variants() {\n                for field in &variant.fields {\n                    if let Some(field_hir_id) = field\n                        .did\n                        .as_local()\n                        .map(|local_def_id| cx.tcx.local_def_id_to_hir_id(local_def_id))\n                        && !is_lint_allowed(cx, NON_SEND_FIELDS_IN_SEND_TY, field_hir_id)\n                        && let field_ty = field.ty(cx.tcx, impl_trait_args)\n                        && !ty_allowed_in_send(cx, field_ty, send_trait)\n                        && let Node::Field(field_def) = cx.tcx.hir_node(field_hir_id)\n                    {\n                        non_send_fields.push(NonSendField {\n                            def: field_def,\n                            ty: field_ty,\n                            generic_params: collect_generic_params(field_ty),\n                        });\n                    }\n                }\n            }\n\n            if !non_send_fields.is_empty() {\n                span_lint_and_then(\n                    cx,\n                    NON_SEND_FIELDS_IN_SEND_TY,\n                    item.span,\n                    format!(\n                        \"some fields in `{}` are not safe to be sent to another thread\",\n                        snippet(cx, hir_impl.self_ty.span, \"Unknown\")\n                    ),\n                    |diag| {\n                        for field in non_send_fields {\n                            diag.span_note(\n                                field.def.span,\n                                format!(\n                                    \"it is not safe to send field `{}` to another thread\",\n                                    field.def.ident.name\n                                ),\n                            );\n\n                            match field.generic_params.len() {\n                                0 => diag.help(\"use a thread-safe type that implements `Send`\"),\n                                1 if is_ty_param(field.ty) => {\n                                    diag.help(format!(\"add `{}: Send` bound in `Send` impl\", field.ty))\n                                },\n                                _ => diag.help(format!(\n                                    \"add bounds on type parameter{} `{}` that satisfy `{}: Send`\",\n                                    if field.generic_params.len() > 1 { \"s\" } else { \"\" },\n                                    field.generic_params_string(),\n                                    snippet(cx, field.def.ty.span, \"Unknown\"),\n                                )),\n                            };\n                        }\n                    },\n                );\n            }\n        }\n    }\n}\n\nstruct NonSendField<'tcx> {\n    def: &'tcx FieldDef<'tcx>,\n    ty: Ty<'tcx>,\n    generic_params: Vec<Ty<'tcx>>,\n}\n\nimpl NonSendField<'_> {\n    fn generic_params_string(&self) -> String {\n        self.generic_params\n            .iter()\n            .map(ToString::to_string)\n            .collect::<Vec<_>>()\n            .join(\", \")\n    }\n}\n\n/// Given a type, collect all of its generic parameters.\n/// Example: `MyStruct<P, Box<Q, R>>` => `vec![P, Q, R]`\nfn collect_generic_params(ty: Ty<'_>) -> Vec<Ty<'_>> {\n    ty.walk()\n        .filter_map(|inner| match inner.kind() {\n            GenericArgKind::Type(inner_ty) => Some(inner_ty),\n            _ => None,\n        })\n        .filter(|&inner_ty| is_ty_param(inner_ty))\n        .collect()\n}\n\n/// Be more strict when the heuristic is disabled\nfn ty_allowed_without_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, send_trait: DefId) -> bool {\n    if implements_trait(cx, ty, send_trait, &[]) {\n        return true;\n    }\n\n    if is_copy(cx, ty) && !contains_pointer_like(cx, ty) {\n        return true;\n    }\n\n    false\n}\n\n/// Heuristic to allow cases like `Vec<*const u8>`\nfn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, send_trait: DefId) -> bool {\n    if implements_trait(cx, ty, send_trait, &[]) || is_copy(cx, ty) {\n        return true;\n    }\n\n    // The type is known to be `!Send` and `!Copy`\n    match ty.kind() {\n        ty::Tuple(fields) => fields\n            .iter()\n            .all(|ty| ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait)),\n        ty::Array(ty, _) | ty::Slice(ty) => ty_allowed_with_raw_pointer_heuristic(cx, *ty, send_trait),\n        ty::Adt(_, args) if contains_pointer_like(cx, ty) => {\n            // descends only if ADT contains any raw pointers\n            args.iter().all(|generic_arg| match generic_arg.kind() {\n                GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait),\n                // Lifetimes and const generics are not solid part of ADT and ignored\n                GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true,\n            })\n        },\n        // Raw pointers are `!Send` but allowed by the heuristic\n        ty::RawPtr(_, _) => true,\n        _ => false,\n    }\n}\n\n/// Checks if the type contains any pointer-like types in args (including nested ones)\nfn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> bool {\n    for ty_node in target_ty.walk() {\n        if let GenericArgKind::Type(inner_ty) = ty_node.kind() {\n            match inner_ty.kind() {\n                ty::RawPtr(_, _) => {\n                    return true;\n                },\n                ty::Adt(adt_def, _) if cx.tcx.is_diagnostic_item(sym::NonNull, adt_def.did()) => {\n                    return true;\n                },\n                _ => (),\n            }\n        }\n    }\n\n    false\n}\n\n/// Returns `true` if the type is a type parameter such as `T`.\nfn is_ty_param(target_ty: Ty<'_>) -> bool {\n    matches!(target_ty.kind(), ty::Param(_))\n}\n"
  },
  {
    "path": "clippy_lints/src/non_std_lazy_statics.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint, span_lint_hir_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::paths::{self, PathNS, find_crates, lookup_path_str};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{fn_def_id, is_no_std_crate, sym};\nuse rustc_data_structures::fx::FxIndexMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::{CrateNum, DefId};\nuse rustc_hir::{self as hir, BodyId, Expr, ExprKind, HirId, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints when `once_cell::sync::Lazy` or `lazy_static!` are used to define a static variable,\n    /// and suggests replacing such cases with `std::sync::LazyLock` instead.\n    ///\n    /// Note: This lint will not trigger in crate with `no_std` context, or with MSRV < 1.80.0. It\n    /// also will not trigger on `once_cell::sync::Lazy` usage in crates which use other types\n    /// from `once_cell`, such as `once_cell::race::OnceBox`.\n    ///\n    /// ### Why restrict this?\n    /// - Reduces the need for an extra dependency\n    /// - Enforce convention of using standard library types when possible\n    ///\n    /// ### Example\n    /// ```ignore\n    /// lazy_static! {\n    ///     static ref FOO: String = \"foo\".to_uppercase();\n    /// }\n    /// static BAR: once_cell::sync::Lazy<String> = once_cell::sync::Lazy::new(|| \"BAR\".to_lowercase());\n    /// ```\n    /// Use instead:\n    /// ```ignore\n    /// static FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"FOO\".to_lowercase());\n    /// static BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"BAR\".to_lowercase());\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub NON_STD_LAZY_STATICS,\n    pedantic,\n    \"lazy static that could be replaced by `std::sync::LazyLock`\"\n}\n\nimpl_lint_pass!(NonStdLazyStatic => [NON_STD_LAZY_STATICS]);\n\n/// A list containing functions with corresponding replacements in `LazyLock`.\n///\n/// Some functions could be replaced as well if we have replaced `Lazy` to `LazyLock`,\n/// therefore after suggesting replace the type, we need to make sure the function calls can be\n/// replaced, otherwise the suggestions cannot be applied thus the applicability should be\n/// [`Applicability::Unspecified`] or [`Applicability::MaybeIncorrect`].\nstatic FUNCTION_REPLACEMENTS: &[(&str, Option<&str>)] = &[\n    (\"once_cell::sync::Lazy::force\", Some(\"std::sync::LazyLock::force\")),\n    (\"once_cell::sync::Lazy::get\", None), // `std::sync::LazyLock::get` is experimental\n    (\"once_cell::sync::Lazy::new\", Some(\"std::sync::LazyLock::new\")),\n    // Note: `Lazy::{into_value, get_mut, force_mut}` are not in the list.\n    // Because the lint only checks for `static`s, and using these functions with statics\n    // will either be a hard error or triggers `static_mut_ref` that will be hard errors.\n    // But keep in mind that if somehow we decide to expand this lint to catch non-statics,\n    // add those functions into the list.\n];\n\npub struct NonStdLazyStatic {\n    msrv: Msrv,\n    once_cell_crates: Vec<CrateNum>,\n    sugg_map: FxIndexMap<DefId, Option<String>>,\n    lazy_type_defs: FxIndexMap<DefId, LazyInfo>,\n    uses_other_once_cell_types: bool,\n}\n\nimpl NonStdLazyStatic {\n    #[must_use]\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: conf.msrv,\n            once_cell_crates: Vec::new(),\n            sugg_map: FxIndexMap::default(),\n            lazy_type_defs: FxIndexMap::default(),\n            uses_other_once_cell_types: false,\n        }\n    }\n}\n\nfn can_use_lazy_cell(cx: &LateContext<'_>, msrv: Msrv) -> bool {\n    msrv.meets(cx, msrvs::LAZY_CELL) && !is_no_std_crate(cx)\n}\n\nimpl<'hir> LateLintPass<'hir> for NonStdLazyStatic {\n    fn check_crate(&mut self, cx: &LateContext<'hir>) {\n        // Add CrateNums for `once_cell` crate\n        self.once_cell_crates = find_crates(cx.tcx, sym::once_cell)\n            .iter()\n            .map(|def_id| def_id.krate)\n            .collect();\n\n        // Convert hardcoded fn replacement list into a map with def_id\n        for (path, sugg) in FUNCTION_REPLACEMENTS {\n            for did in lookup_path_str(cx.tcx, PathNS::Value, path) {\n                self.sugg_map.insert(did, sugg.map(ToOwned::to_owned));\n            }\n        }\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'hir>, item: &Item<'hir>) {\n        if let ItemKind::Static(..) = item.kind\n            && let Some(macro_call) = clippy_utils::macros::root_macro_call(item.span)\n            && paths::LAZY_STATIC.matches(cx, macro_call.def_id)\n            && can_use_lazy_cell(cx, self.msrv)\n        {\n            span_lint(\n                cx,\n                NON_STD_LAZY_STATICS,\n                macro_call.span,\n                \"this macro has been superseded by `std::sync::LazyLock`\",\n            );\n            return;\n        }\n\n        if item.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if let Some(lazy_info) = LazyInfo::from_item(cx, item)\n            && can_use_lazy_cell(cx, self.msrv)\n        {\n            self.lazy_type_defs.insert(item.owner_id.to_def_id(), lazy_info);\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'hir>, expr: &Expr<'hir>) {\n        // All functions in the `FUNCTION_REPLACEMENTS` have only one args\n        if let ExprKind::Call(callee, [arg]) = expr.kind\n            && let Some(call_def_id) = fn_def_id(cx, expr)\n            && self.sugg_map.contains_key(&call_def_id)\n            && let ExprKind::Path(qpath) = arg.peel_borrows().kind\n            && let Some(arg_def_id) = cx.typeck_results().qpath_res(&qpath, arg.hir_id).opt_def_id()\n            && let Some(lazy_info) = self.lazy_type_defs.get_mut(&arg_def_id)\n        {\n            lazy_info.calls_span_and_id.insert(callee.span, call_def_id);\n        }\n    }\n\n    fn check_ty(&mut self, cx: &LateContext<'hir>, ty: &'hir rustc_hir::Ty<'hir, rustc_hir::AmbigArg>) {\n        // Record if types from `once_cell` besides `sync::Lazy` are used.\n        if let rustc_hir::TyKind::Path(qpath) = ty.peel_refs().kind\n            && let Some(ty_def_id) = cx.qpath_res(&qpath, ty.hir_id).opt_def_id()\n            // Is from `once_cell` crate\n            && self.once_cell_crates.contains(&ty_def_id.krate)\n            // And is NOT `once_cell::sync::Lazy`\n            && !paths::ONCE_CELL_SYNC_LAZY.matches(cx, ty_def_id)\n        {\n            self.uses_other_once_cell_types = true;\n        }\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'hir>) {\n        if !self.uses_other_once_cell_types {\n            for (_, lazy_info) in &self.lazy_type_defs {\n                lazy_info.lint(cx, &self.sugg_map);\n            }\n        }\n    }\n}\n\nstruct LazyInfo {\n    /// Span of the [`hir::Ty`] without including args.\n    /// i.e.:\n    /// ```ignore\n    /// static FOO: Lazy<String> = Lazy::new(...);\n    /// //          ^^^^\n    /// ```\n    ty_span_no_args: Span,\n    /// Item on which the lint must be generated.\n    item_hir_id: HirId,\n    /// `Span` and `DefId` of calls on `Lazy` type.\n    /// i.e.:\n    /// ```ignore\n    /// static FOO: Lazy<String> = Lazy::new(...);\n    /// //                         ^^^^^^^^^\n    /// ```\n    calls_span_and_id: FxIndexMap<Span, DefId>,\n}\n\nimpl LazyInfo {\n    fn from_item(cx: &LateContext<'_>, item: &Item<'_>) -> Option<Self> {\n        // Check if item is a `once_cell:sync::Lazy` static.\n        if let ItemKind::Static(_, _, ty, body_id) = item.kind\n            && let Some(path_def_id) = ty.basic_res().opt_def_id()\n            && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind\n            && paths::ONCE_CELL_SYNC_LAZY.matches(cx, path_def_id)\n        {\n            let ty_span_no_args = path_span_without_args(path);\n            let body = cx.tcx.hir_body(body_id);\n\n            // visit body to collect `Lazy::new` calls\n            let mut new_fn_calls = FxIndexMap::default();\n            for_each_expr::<(), ()>(cx, body, |ex| {\n                if let Some((fn_did, call_span)) = fn_def_id_and_span_from_body(cx, ex, body_id)\n                    && paths::ONCE_CELL_SYNC_LAZY_NEW.matches(cx, fn_did)\n                {\n                    new_fn_calls.insert(call_span, fn_did);\n                }\n                std::ops::ControlFlow::Continue(())\n            });\n\n            Some(LazyInfo {\n                ty_span_no_args,\n                item_hir_id: item.hir_id(),\n                calls_span_and_id: new_fn_calls,\n            })\n        } else {\n            None\n        }\n    }\n\n    fn lint(&self, cx: &LateContext<'_>, sugg_map: &FxIndexMap<DefId, Option<String>>) {\n        // Applicability might get adjusted to `Unspecified` later if any calls\n        // in `calls_span_and_id` are not replaceable judging by the `sugg_map`.\n        let mut app = Applicability::MachineApplicable;\n        let mut suggs = vec![(self.ty_span_no_args, \"std::sync::LazyLock\".to_string())];\n\n        for (span, def_id) in &self.calls_span_and_id {\n            let maybe_sugg = sugg_map.get(def_id).cloned().flatten();\n            if let Some(sugg) = maybe_sugg {\n                suggs.push((*span, sugg));\n            } else {\n                // If NO suggested replacement, not machine applicable\n                app = Applicability::Unspecified;\n            }\n        }\n\n        span_lint_hir_and_then(\n            cx,\n            NON_STD_LAZY_STATICS,\n            self.item_hir_id,\n            self.ty_span_no_args,\n            \"this type has been superseded by `LazyLock` in the standard library\",\n            |diag| {\n                diag.multipart_suggestion(\"use `std::sync::LazyLock` instead\", suggs, app);\n            },\n        );\n    }\n}\n\n/// Return the span of a given `Path` without including any of its args.\n///\n/// NB: Re-write of a private function `rustc_lint::non_local_def::path_span_without_args`.\nfn path_span_without_args(path: &hir::Path<'_>) -> Span {\n    path.segments\n        .last()\n        .and_then(|seg| seg.args)\n        .map_or(path.span, |args| path.span.until(args.span_ext))\n}\n\n/// Returns the `DefId` and `Span` of the callee if the given expression is a function call.\n///\n/// NB: Modified from [`clippy_utils::fn_def_id`], to support calling in an static `Item`'s body.\nfn fn_def_id_and_span_from_body(cx: &LateContext<'_>, expr: &Expr<'_>, body_id: BodyId) -> Option<(DefId, Span)> {\n    // FIXME: find a way to cache the result.\n    let typeck = cx.tcx.typeck_body(body_id);\n    match &expr.kind {\n        ExprKind::Call(\n            Expr {\n                kind: ExprKind::Path(qpath),\n                hir_id: path_hir_id,\n                span,\n                ..\n            },\n            ..,\n        ) => {\n            // Only return Fn-like DefIds, not the DefIds of statics/consts/etc that contain or\n            // deref to fn pointers, dyn Fn, impl Fn - #8850\n            if let Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) =\n                typeck.qpath_res(qpath, *path_hir_id)\n            {\n                Some((id, *span))\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/non_zero_suggestions.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sym;\nuse rustc_ast::ast::BinOpKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for conversions from `NonZero` types to regular integer types,\n    /// and suggests using `NonZero` types for the target as well.\n    ///\n    /// ### Why is this bad?\n    /// Converting from `NonZero` types to regular integer types and then back to `NonZero`\n    /// types is less efficient and loses the type-safety guarantees provided by `NonZero` types.\n    /// Using `NonZero` types consistently can lead to more optimized code and prevent\n    /// certain classes of errors related to zero values.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::num::{NonZeroU32, NonZeroU64};\n    ///\n    /// fn example(x: u64, y: NonZeroU32) {\n    ///     // Bad: Converting NonZeroU32 to u64 unnecessarily\n    ///     let r1 = x / u64::from(y.get());\n    ///     let r2 = x % u64::from(y.get());\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::num::{NonZeroU32, NonZeroU64};\n    ///\n    /// fn example(x: u64, y: NonZeroU32) {\n    ///     // Good: Preserving the NonZero property\n    ///     let r1 = x / NonZeroU64::from(y);\n    ///     let r2 = x % NonZeroU64::from(y);\n    /// }\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub NON_ZERO_SUGGESTIONS,\n    restriction,\n    \"suggests using `NonZero#` from `u#` or `i#` for more efficient and type-safe conversions\"\n}\n\ndeclare_lint_pass!(NonZeroSuggestions => [NON_ZERO_SUGGESTIONS]);\n\nimpl<'tcx> LateLintPass<'tcx> for NonZeroSuggestions {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Binary(op, _, rhs) = expr.kind\n            && matches!(op.node, BinOpKind::Div | BinOpKind::Rem)\n        {\n            check_non_zero_conversion(cx, rhs, Applicability::MachineApplicable);\n        } else {\n            // Check if the parent expression is a binary operation\n            let parent_is_binary = cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, node)| {\n                matches!(node, rustc_hir::Node::Expr(parent_expr) if matches!(parent_expr.kind, ExprKind::Binary(..)))\n            });\n\n            if !parent_is_binary {\n                check_non_zero_conversion(cx, expr, Applicability::MaybeIncorrect);\n            }\n        }\n    }\n}\n\nfn check_non_zero_conversion(cx: &LateContext<'_>, expr: &Expr<'_>, applicability: Applicability) {\n    // Check if the expression is a function call with one argument\n    if let ExprKind::Call(func, [arg]) = expr.kind\n        && let ExprKind::Path(qpath) = &func.kind\n        && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id()\n        && let ExprKind::MethodCall(rcv_path, receiver, [], _) = &arg.kind\n        && rcv_path.ident.name == sym::get\n    {\n        let fn_name = cx.tcx.item_name(def_id);\n        let target_ty = cx.typeck_results().expr_ty(expr);\n        let receiver_ty = cx.typeck_results().expr_ty(receiver);\n\n        // Check if the receiver type is a NonZero type\n        if let ty::Adt(adt_def, _) = receiver_ty.kind()\n            && adt_def.is_struct()\n            && cx.tcx.get_diagnostic_name(adt_def.did()) == Some(sym::NonZero)\n            && let Some(target_non_zero_type) = get_target_non_zero_type(target_ty)\n        {\n            let arg_snippet = get_arg_snippet(cx, arg, rcv_path);\n            suggest_non_zero_conversion(cx, expr, fn_name, target_non_zero_type, &arg_snippet, applicability);\n        }\n    }\n}\n\nfn get_arg_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, rcv_path: &rustc_hir::PathSegment<'_>) -> String {\n    let arg_snippet = snippet(cx, arg.span, \"..\");\n    if let Some(index) = arg_snippet.rfind(&format!(\".{}\", rcv_path.ident.name)) {\n        arg_snippet[..index].trim().to_string()\n    } else {\n        arg_snippet.to_string()\n    }\n}\n\nfn suggest_non_zero_conversion(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    fn_name: rustc_span::Symbol,\n    target_non_zero_type: &str,\n    arg_snippet: &str,\n    applicability: Applicability,\n) {\n    let suggestion = format!(\"{target_non_zero_type}::{fn_name}({arg_snippet})\");\n    span_lint_and_sugg(\n        cx,\n        NON_ZERO_SUGGESTIONS,\n        expr.span,\n        format!(\"consider using `{target_non_zero_type}::{fn_name}()` for more efficient and type-safe conversion\"),\n        \"replace with\",\n        suggestion,\n        applicability,\n    );\n}\n\nfn get_target_non_zero_type(ty: Ty<'_>) -> Option<&'static str> {\n    match ty.kind() {\n        ty::Uint(uint_ty) => Some(match uint_ty {\n            ty::UintTy::U8 => \"NonZeroU8\",\n            ty::UintTy::U16 => \"NonZeroU16\",\n            ty::UintTy::U32 => \"NonZeroU32\",\n            ty::UintTy::U64 => \"NonZeroU64\",\n            ty::UintTy::U128 => \"NonZeroU128\",\n            ty::UintTy::Usize => \"NonZeroUsize\",\n        }),\n        ty::Int(int_ty) => Some(match int_ty {\n            ty::IntTy::I8 => \"NonZeroI8\",\n            ty::IntTy::I16 => \"NonZeroI16\",\n            ty::IntTy::I32 => \"NonZeroI32\",\n            ty::IntTy::I64 => \"NonZeroI64\",\n            ty::IntTy::I128 => \"NonZeroI128\",\n            ty::IntTy::Isize => \"NonZeroIsize\",\n        }),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/nonstandard_macro_braces.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::MacroMatcher;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{SourceText, SpanRangeExt};\nuse rustc_ast::ast;\nuse rustc_data_structures::fx::{FxHashMap, FxHashSet};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::hygiene::{ExpnKind, MacroKind};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks that common macros are used with consistent bracing.\n    ///\n    /// ### Why is this bad?\n    /// Having non-conventional braces on well-stablished macros can be confusing\n    /// when debugging, and they bring incosistencies with the rest of the ecosystem.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// vec!{1, 2, 3};\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// vec![1, 2, 3];\n    /// ```\n    #[clippy::version = \"1.55.0\"]\n    pub NONSTANDARD_MACRO_BRACES,\n    nursery,\n    \"check consistent use of braces in macro\"\n}\n\nimpl_lint_pass!(MacroBraces => [NONSTANDARD_MACRO_BRACES]);\n\nstruct MacroInfo {\n    callsite_span: Span,\n    callsite_snippet: SourceText,\n    old_open_brace: char,\n    braces: (char, char),\n}\n\npub struct MacroBraces {\n    macro_braces: FxHashMap<String, (char, char)>,\n    done: FxHashSet<Span>,\n}\n\nimpl MacroBraces {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            macro_braces: macro_braces(&conf.standard_macro_braces),\n            done: FxHashSet::default(),\n        }\n    }\n}\n\nimpl EarlyLintPass for MacroBraces {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {\n        if let Some(MacroInfo {\n            callsite_span,\n            callsite_snippet,\n            braces,\n            ..\n        }) = is_offending_macro(cx, item.span, self)\n        {\n            emit_help(cx, &callsite_snippet, braces, callsite_span, false);\n            self.done.insert(callsite_span);\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &ast::Stmt) {\n        if let Some(MacroInfo {\n            callsite_span,\n            callsite_snippet,\n            braces,\n            old_open_brace,\n        }) = is_offending_macro(cx, stmt.span, self)\n        {\n            // if we turn `macro!{}` into `macro!()`/`macro![]`, we'll no longer get the implicit\n            // trailing semicolon, see #9913\n            // NOTE: `stmt.kind != StmtKind::MacCall` because `EarlyLintPass` happens after macro expansion\n            let add_semi = matches!(stmt.kind, ast::StmtKind::Expr(..)) && old_open_brace == '{';\n            emit_help(cx, &callsite_snippet, braces, callsite_span, add_semi);\n            self.done.insert(callsite_span);\n        }\n    }\n\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {\n        if let Some(MacroInfo {\n            callsite_span,\n            callsite_snippet,\n            braces,\n            ..\n        }) = is_offending_macro(cx, expr.span, self)\n        {\n            emit_help(cx, &callsite_snippet, braces, callsite_span, false);\n            self.done.insert(callsite_span);\n        }\n    }\n\n    fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {\n        if let Some(MacroInfo {\n            callsite_span,\n            braces,\n            callsite_snippet,\n            ..\n        }) = is_offending_macro(cx, ty.span, self)\n        {\n            emit_help(cx, &callsite_snippet, braces, callsite_span, false);\n            self.done.insert(callsite_span);\n        }\n    }\n}\n\nfn is_offending_macro(cx: &EarlyContext<'_>, span: Span, mac_braces: &MacroBraces) -> Option<MacroInfo> {\n    let unnested_or_local = |span: Span| {\n        !span.from_expansion()\n            || span\n                .macro_backtrace()\n                .last()\n                .is_some_and(|e| e.macro_def_id.is_some_and(DefId::is_local))\n    };\n\n    let mut ctxt = span.ctxt();\n    while !ctxt.is_root() {\n        let expn_data = ctxt.outer_expn_data();\n        if let ExpnKind::Macro(MacroKind::Bang, mac_name) = expn_data.kind\n        && let name = mac_name.as_str()\n        && let Some(&braces) = mac_braces.macro_braces.get(name)\n        && let Some(snip) = expn_data.call_site.get_source_text(cx)\n        // we must check only invocation sites\n        // https://github.com/rust-lang/rust-clippy/issues/7422\n        && let Some(macro_args_str) = snip.strip_prefix(name).and_then(|snip| snip.strip_prefix('!'))\n        && let Some(old_open_brace @ ('{' | '(' | '[')) = macro_args_str.trim_start().chars().next()\n        && old_open_brace != braces.0\n        && unnested_or_local(expn_data.call_site)\n        && !mac_braces.done.contains(&expn_data.call_site)\n        {\n            return Some(MacroInfo {\n                callsite_span: expn_data.call_site,\n                callsite_snippet: snip,\n                old_open_brace,\n                braces,\n            });\n        }\n\n        ctxt = expn_data.call_site.ctxt();\n    }\n\n    None\n}\n\nfn emit_help(cx: &EarlyContext<'_>, snip: &str, (open, close): (char, char), span: Span, add_semi: bool) {\n    let semi = if add_semi { \";\" } else { \"\" };\n    if let Some((macro_name, macro_args_str)) = snip.split_once('!') {\n        let mut macro_args = macro_args_str.trim().to_string();\n        // now remove the wrong braces\n        macro_args.pop();\n        macro_args.remove(0);\n        span_lint_and_sugg(\n            cx,\n            NONSTANDARD_MACRO_BRACES,\n            span,\n            format!(\"use of irregular braces for `{macro_name}!` macro\"),\n            \"consider writing\",\n            format!(\"{macro_name}!{open}{macro_args}{close}{semi}\"),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n\nfn macro_braces(conf: &[MacroMatcher]) -> FxHashMap<String, (char, char)> {\n    let mut braces = FxHashMap::from_iter(\n        [\n            (\"print\", ('(', ')')),\n            (\"println\", ('(', ')')),\n            (\"eprint\", ('(', ')')),\n            (\"eprintln\", ('(', ')')),\n            (\"write\", ('(', ')')),\n            (\"writeln\", ('(', ')')),\n            (\"format\", ('(', ')')),\n            (\"format_args\", ('(', ')')),\n            (\"vec\", ('[', ']')),\n            (\"matches\", ('(', ')')),\n        ]\n        .map(|(k, v)| (k.to_string(), v)),\n    );\n    // We want users items to override any existing items\n    for it in conf {\n        braces.insert(it.name.clone(), it.braces);\n    }\n    braces\n}\n"
  },
  {
    "path": "clippy_lints/src/octal_escapes.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_ast::token::LitKind;\nuse rustc_ast::{Expr, ExprKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{BytePos, Pos, SpanData};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `\\0` escapes in string and byte literals that look like octal\n    /// character escapes in C.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// C and other languages support octal character escapes in strings, where\n    /// a backslash is followed by up to three octal digits. For example, `\\033`\n    /// stands for the ASCII character 27 (ESC). Rust does not support this\n    /// notation, but has the escape code `\\0` which stands for a null\n    /// byte/character, and any following digits do not form part of the escape\n    /// sequence. Therefore, `\\033` is not a compiler error but the result may\n    /// be surprising.\n    ///\n    /// ### Known problems\n    /// The actual meaning can be the intended one. `\\x00` can be used in these\n    /// cases to be unambiguous.\n    ///\n    /// The lint does not trigger for format strings in `print!()`, `write!()`\n    /// and friends since the string is already preprocessed when Clippy lints\n    /// can see it.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let one = \"\\033[1m Bold? \\033[0m\";  // \\033 intended as escape\n    /// let two = \"\\033\\0\";                 // \\033 intended as null-3-3\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let one = \"\\x1b[1mWill this be bold?\\x1b[0m\";\n    /// let two = \"\\x0033\\x00\";\n    /// ```\n    #[clippy::version = \"1.59.0\"]\n    pub OCTAL_ESCAPES,\n    suspicious,\n    \"string escape sequences looking like octal characters\"\n}\n\ndeclare_lint_pass!(OctalEscapes => [OCTAL_ESCAPES]);\n\nimpl EarlyLintPass for OctalEscapes {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::Lit(lit) = &expr.kind\n            // The number of bytes from the start of the token to the start of literal's text.\n            && let start_offset = BytePos::from_u32(match lit.kind {\n                LitKind::Str => 1,\n                LitKind::ByteStr | LitKind::CStr => 2,\n                _ => return,\n            })\n            && !expr.span.in_external_macro(cx.sess().source_map())\n        {\n            let s = lit.symbol.as_str();\n            let mut iter = s.as_bytes().iter();\n            while let Some(&c) = iter.next() {\n                if c == b'\\\\'\n                    // Always move the iterator to read the escape char.\n                    && let Some(b'0') = iter.next()\n                {\n                    // C-style octal escapes read from one to three characters.\n                    // The first character (`0`) has already been read.\n                    let (tail, len, c_hi, c_lo) = match *iter.as_slice() {\n                        [c_hi @ b'0'..=b'7', c_lo @ b'0'..=b'7', ref tail @ ..] => (tail, 4, c_hi, c_lo),\n                        [c_lo @ b'0'..=b'7', ref tail @ ..] => (tail, 3, b'0', c_lo),\n                        _ => continue,\n                    };\n                    iter = tail.iter();\n                    let offset = start_offset + BytePos::from_usize(s.len() - tail.len());\n                    let data = expr.span.data();\n                    let span = SpanData {\n                        lo: data.lo + offset - BytePos::from_u32(len),\n                        hi: data.lo + offset,\n                        ..data\n                    }\n                    .span();\n\n                    // Last check to make sure the source text matches what we read from the string.\n                    // Macros are involved somehow if this doesn't match.\n                    if span.check_source_text(cx, |src| match *src.as_bytes() {\n                        [b'\\\\', b'0', lo] => lo == c_lo,\n                        [b'\\\\', b'0', hi, lo] => hi == c_hi && lo == c_lo,\n                        _ => false,\n                    }) {\n                        span_lint_and_then(cx, OCTAL_ESCAPES, span, \"octal-looking escape in a literal\", |diag| {\n                            diag.help_once(\"octal escapes are not supported, `\\\\0` is always null\")\n                                .span_suggestion(\n                                    span,\n                                    \"if an octal escape is intended, use a hex escape instead\",\n                                    format!(\"\\\\x{:02x}\", (((c_hi - b'0') << 3) | (c_lo - b'0'))),\n                                    Applicability::MaybeIncorrect,\n                                )\n                                .span_suggestion(\n                                    span,\n                                    \"if a null escape is intended, disambiguate using\",\n                                    format!(\"\\\\x00{}{}\", c_hi as char, c_lo as char),\n                                    Applicability::MaybeIncorrect,\n                                );\n                        });\n                    } else {\n                        break;\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/only_used_in_recursion.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::get_expr_use_or_unification_node;\nuse clippy_utils::res::{MaybeQPath, MaybeResPath};\nuse core::cell::Cell;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::hir_id::HirIdMap;\nuse rustc_hir::{\n    Body, Expr, ExprKind, HirId, ImplItem, ImplItemImplKind, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, ConstKind, GenericArgKind, GenericArgsRef};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::{Ident, kw};\nuse std::iter;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for arguments that are only used in recursion with no side-effects.\n    ///\n    /// ### Why is this bad?\n    /// It could contain a useless calculation and can make function simpler.\n    ///\n    /// The arguments can be involved in calculations and assignments but as long as\n    /// the calculations have no side-effects (function calls or mutating dereference)\n    /// and the assigned variables are also only in recursion, it is useless.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn f(a: usize, b: usize) -> usize {\n    ///     if a == 0 {\n    ///         1\n    ///     } else {\n    ///         f(a - 1, b + 1)\n    ///     }\n    /// }\n    /// # fn main() {\n    /// #     print!(\"{}\", f(1, 1));\n    /// # }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn f(a: usize) -> usize {\n    ///     if a == 0 {\n    ///         1\n    ///     } else {\n    ///         f(a - 1)\n    ///     }\n    /// }\n    /// # fn main() {\n    /// #     print!(\"{}\", f(1));\n    /// # }\n    /// ```\n    ///\n    /// ### Known problems\n    /// Too many code paths in the linting code are currently untested and prone to produce false\n    /// positives or are prone to have performance implications.\n    ///\n    /// In some cases, this would not catch all useless arguments.\n    ///\n    /// ```no_run\n    /// fn foo(a: usize, b: usize) -> usize {\n    ///     let f = |x| x + 1;\n    ///\n    ///     if a == 0 {\n    ///         1\n    ///     } else {\n    ///         foo(a - 1, f(b))\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// For example, the argument `b` is only used in recursion, but the lint would not catch it.\n    ///\n    /// List of some examples that can not be caught:\n    /// - binary operation of non-primitive types\n    /// - closure usage\n    /// - some `break` relative operations\n    /// - struct pattern binding\n    ///\n    /// Also, when you recurse the function name with path segments, it is not possible to detect.\n    #[clippy::version = \"1.61.0\"]\n    pub ONLY_USED_IN_RECURSION,\n    complexity,\n    \"arguments that is only used in recursion can be removed\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `self` receiver that is only used in recursion with no side-effects.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// It may be possible to remove the `self` argument, allowing the function to be\n    /// used without an object of type `Self`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo;\n    /// impl Foo {\n    ///     fn f(&self, n: u32) -> u32 {\n    ///         if n == 0 {\n    ///             1\n    ///         } else {\n    ///             n * self.f(n - 1)\n    ///         }\n    ///     }\n    /// }\n    /// # fn main() {\n    /// #     print!(\"{}\", Foo.f(10));\n    /// # }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct Foo;\n    /// impl Foo {\n    ///     fn f(n: u32) -> u32 {\n    ///         if n == 0 {\n    ///             1\n    ///         } else {\n    ///             n * Self::f(n - 1)\n    ///         }\n    ///     }\n    /// }\n    /// # fn main() {\n    /// #     print!(\"{}\", Foo::f(10));\n    /// # }\n    /// ```\n    ///\n    /// ### Known problems\n    /// Too many code paths in the linting code are currently untested and prone to produce false\n    /// positives or are prone to have performance implications.\n    ///\n    /// In some cases, this would not catch all useless arguments.\n    ///\n    /// ```no_run\n    /// struct Foo;\n    /// impl Foo {\n    ///     fn foo(&self, a: usize) -> usize {\n    ///         let f = |x| x;\n    ///\n    ///         if a == 0 {\n    ///             1\n    ///         } else {\n    ///             f(self).foo(a)\n    ///         }\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// For example, here `self` is only used in recursion, but the lint would not catch it.\n    ///\n    /// List of some examples that can not be caught:\n    /// - binary operation of non-primitive types\n    /// - closure usage\n    /// - some `break` relative operations\n    /// - struct pattern binding\n    ///\n    /// Also, when you recurse the function name with path segments, it is not possible to detect.\n    #[clippy::version = \"1.92.0\"]\n    pub SELF_ONLY_USED_IN_RECURSION,\n    pedantic,\n    \"self receiver only used to recursively call method can be removed\"\n}\n\nimpl_lint_pass!(OnlyUsedInRecursion => [\n    ONLY_USED_IN_RECURSION,\n    SELF_ONLY_USED_IN_RECURSION,\n]);\n\n#[derive(Clone, Copy)]\nenum FnKind {\n    Fn,\n    TraitFn,\n    // This is a hack. Ideally we would store a `GenericArgsRef<'tcx>` type here, but a lint pass must be `'static`.\n    // Substitutions are, however, interned. This allows us to store the pointer as a `usize` when comparing for\n    // equality.\n    ImplTraitFn(usize),\n}\n\nstruct Param {\n    /// The function this is a parameter for.\n    fn_id: DefId,\n    fn_kind: FnKind,\n    /// The index of this parameter.\n    idx: usize,\n    ident: Ident,\n    /// Whether this parameter should be linted. Set by `Params::flag_for_linting`.\n    apply_lint: Cell<bool>,\n    /// All the uses of this parameter.\n    uses: Vec<Usage>,\n}\nimpl Param {\n    fn new(fn_id: DefId, fn_kind: FnKind, idx: usize, ident: Ident) -> Self {\n        Self {\n            fn_id,\n            fn_kind,\n            idx,\n            ident,\n            apply_lint: Cell::new(true),\n            uses: Vec::new(),\n        }\n    }\n}\n\n#[derive(Debug)]\nstruct Usage {\n    span: Span,\n    idx: usize,\n}\nimpl Usage {\n    fn new(span: Span, idx: usize) -> Self {\n        Self { span, idx }\n    }\n}\n\n/// The parameters being checked by the lint, indexed by both the parameter's `HirId` and the\n/// `DefId` of the function paired with the parameter's index.\n#[derive(Default)]\n#[expect(clippy::struct_field_names)]\nstruct Params {\n    params: Vec<Param>,\n    by_id: HirIdMap<usize>,\n    by_fn: FxHashMap<(DefId, usize), usize>,\n}\nimpl Params {\n    fn insert(&mut self, param: Param, id: HirId) {\n        let idx = self.params.len();\n        self.by_id.insert(id, idx);\n        self.by_fn.insert((param.fn_id, param.idx), idx);\n        self.params.push(param);\n    }\n\n    fn remove_by_id(&mut self, id: HirId) {\n        if let Some(param) = self.get_by_id_mut(id) {\n            param.uses = Vec::new();\n            let key = (param.fn_id, param.idx);\n            self.by_fn.remove(&key);\n            // FIXME(rust/#120456) - is `swap_remove` correct?\n            self.by_id.swap_remove(&id);\n        }\n    }\n\n    fn get_by_id_mut(&mut self, id: HirId) -> Option<&mut Param> {\n        self.params.get_mut(*self.by_id.get(&id)?)\n    }\n\n    fn get_by_fn(&self, id: DefId, idx: usize) -> Option<&Param> {\n        self.params.get(*self.by_fn.get(&(id, idx))?)\n    }\n\n    fn clear(&mut self) {\n        self.params.clear();\n        self.by_id.clear();\n        self.by_fn.clear();\n    }\n\n    /// Sets the `apply_lint` flag on each parameter.\n    fn flag_for_linting(&self) {\n        // Stores the list of parameters currently being resolved. Needed to avoid cycles.\n        let mut eval_stack = Vec::new();\n        for param in &self.params {\n            self.try_disable_lint_for_param(param, &mut eval_stack);\n        }\n    }\n\n    // Use by calling `flag_for_linting`.\n    fn try_disable_lint_for_param(&self, param: &Param, eval_stack: &mut Vec<usize>) -> bool {\n        if !param.apply_lint.get() {\n            true\n        } else if param.uses.is_empty() {\n            // Don't lint on unused parameters.\n            param.apply_lint.set(false);\n            true\n        } else if eval_stack.contains(&param.idx) {\n            // Already on the evaluation stack. Returning false will continue to evaluate other dependencies.\n            false\n        } else {\n            eval_stack.push(param.idx);\n            // Check all cases when used at a different parameter index.\n            // Needed to catch cases like: `fn f(x: u32, y: u32) { f(y, x) }`\n            for usage in param.uses.iter().filter(|u| u.idx != param.idx) {\n                if self\n                    .get_by_fn(param.fn_id, usage.idx)\n                    // If the parameter can't be found, then it's used for more than just recursion.\n                    .is_none_or(|p| self.try_disable_lint_for_param(p, eval_stack))\n                {\n                    param.apply_lint.set(false);\n                    eval_stack.pop();\n                    return true;\n                }\n            }\n            eval_stack.pop();\n            false\n        }\n    }\n}\n\n#[derive(Default)]\npub struct OnlyUsedInRecursion {\n    /// Track the top-level body entered. Needed to delay reporting when entering nested bodies.\n    entered_body: Option<HirId>,\n    params: Params,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {\n    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {\n        if body.value.span.from_expansion() {\n            return;\n        }\n        // `skip_params` is either `0` or `1` to skip the `self` parameter in trait functions.\n        // It can't be renamed, and it can't be removed without removing it from multiple functions.\n        let (fn_id, fn_kind, skip_params) = match cx.tcx.parent_hir_node(body.value.hir_id) {\n            Node::Item(i) => (i.owner_id.to_def_id(), FnKind::Fn, 0),\n            Node::TraitItem(&TraitItem {\n                kind: TraitItemKind::Fn(ref sig, _),\n                owner_id,\n                ..\n            }) => (\n                owner_id.to_def_id(),\n                FnKind::TraitFn,\n                usize::from(sig.decl.implicit_self.has_implicit_self()),\n            ),\n            Node::ImplItem(&ImplItem {\n                kind: ImplItemKind::Fn(ref sig, _),\n                owner_id,\n                impl_kind,\n                ..\n            }) => {\n                if let ImplItemImplKind::Trait { trait_item_def_id, .. } = impl_kind\n                    && let Ok(trait_item_id) = trait_item_def_id\n                {\n                    let impl_id = cx.tcx.parent(owner_id.into());\n                    let trait_ref = cx.tcx.impl_trait_ref(impl_id).instantiate_identity();\n                    (\n                        trait_item_id,\n                        FnKind::ImplTraitFn(\n                            std::ptr::from_ref(cx.tcx.erase_and_anonymize_regions(trait_ref.args)) as usize\n                        ),\n                        usize::from(sig.decl.implicit_self.has_implicit_self()),\n                    )\n                } else {\n                    (owner_id.to_def_id(), FnKind::Fn, 0)\n                }\n            },\n            _ => return,\n        };\n        body.params\n            .iter()\n            .enumerate()\n            .skip(skip_params)\n            .filter_map(|(idx, p)| match p.pat.kind {\n                PatKind::Binding(_, id, ident, None) if !ident.as_str().starts_with('_') => {\n                    Some((id, Param::new(fn_id, fn_kind, idx, ident)))\n                },\n                _ => None,\n            })\n            .for_each(|(id, param)| self.params.insert(param, id));\n        if self.entered_body.is_none() {\n            self.entered_body = Some(body.value.hir_id);\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) {\n        if let Some(id) = e.res_local_id()\n            && let Some(param) = self.params.get_by_id_mut(id)\n        {\n            let typeck = cx.typeck_results();\n            let span = e.span;\n            let mut e = e;\n            loop {\n                match get_expr_use_or_unification_node(cx.tcx, e) {\n                    None | Some((Node::Stmt(_), _)) => return,\n                    Some((Node::Expr(parent), child_id)) => match parent.kind {\n                        // Recursive call. Track which index the parameter is used in.\n                        ExprKind::Call(callee, args)\n                            if callee.res(cx).opt_def_id().is_some_and(|id| {\n                                id == param.fn_id && has_matching_args(param.fn_kind, typeck.node_args(callee.hir_id))\n                            }) =>\n                        {\n                            if let Some(idx) = args.iter().position(|arg| arg.hir_id == child_id) {\n                                param.uses.push(Usage::new(span, idx));\n                            }\n                            return;\n                        },\n                        ExprKind::MethodCall(_, receiver, args, _)\n                            if typeck.type_dependent_def_id(parent.hir_id).is_some_and(|id| {\n                                id == param.fn_id && has_matching_args(param.fn_kind, typeck.node_args(parent.hir_id))\n                            }) =>\n                        {\n                            if let Some(idx) = iter::once(receiver).chain(args).position(|arg| arg.hir_id == child_id) {\n                                param.uses.push(Usage::new(span, idx));\n                            }\n                            return;\n                        },\n                        // Assignment to a parameter is fine.\n                        ExprKind::Assign(lhs, _, _) | ExprKind::AssignOp(_, lhs, _) if lhs.hir_id == child_id => {\n                            return;\n                        },\n                        // Parameter update e.g. `x = x + 1`\n                        ExprKind::Assign(lhs, rhs, _) | ExprKind::AssignOp(_, lhs, rhs)\n                            if rhs.hir_id == child_id && lhs.res_local_id() == Some(id) =>\n                        {\n                            return;\n                        },\n                        // Side-effect free expressions. Walk to the parent expression.\n                        ExprKind::Binary(_, lhs, rhs)\n                            if typeck.expr_ty(lhs).is_primitive() && typeck.expr_ty(rhs).is_primitive() =>\n                        {\n                            e = parent;\n                            continue;\n                        },\n                        ExprKind::Unary(_, arg) if typeck.expr_ty(arg).is_primitive() => {\n                            e = parent;\n                            continue;\n                        },\n                        ExprKind::AddrOf(..) | ExprKind::Cast(..) => {\n                            e = parent;\n                            continue;\n                        },\n                        // Only allow field accesses without auto-deref\n                        ExprKind::Field(..) if typeck.adjustments().get(child_id).is_none() => {\n                            e = parent;\n                            continue;\n                        },\n                        _ => (),\n                    },\n                    _ => (),\n                }\n                self.params.remove_by_id(id);\n                return;\n            }\n        }\n    }\n\n    fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {\n        if self.entered_body == Some(body.value.hir_id) {\n            self.entered_body = None;\n            self.params.flag_for_linting();\n            for param in &self.params.params {\n                if param.apply_lint.get() {\n                    if param.ident.name == kw::SelfLower {\n                        span_lint_and_then(\n                            cx,\n                            SELF_ONLY_USED_IN_RECURSION,\n                            param.ident.span,\n                            \"`self` is only used in recursion\",\n                            |diag| {\n                                diag.span_note(\n                                    param.uses.iter().map(|x| x.span).collect::<Vec<_>>(),\n                                    \"`self` used here\",\n                                );\n                            },\n                        );\n                    } else {\n                        span_lint_and_then(\n                            cx,\n                            ONLY_USED_IN_RECURSION,\n                            param.ident.span,\n                            \"parameter is only used in recursion\",\n                            |diag| {\n                                diag.span_suggestion(\n                                    param.ident.span,\n                                    \"if this is intentional, prefix it with an underscore\",\n                                    format!(\"_{}\", param.ident.name),\n                                    Applicability::MaybeIncorrect,\n                                );\n                                diag.span_note(\n                                    param.uses.iter().map(|x| x.span).collect::<Vec<_>>(),\n                                    \"parameter used here\",\n                                );\n                            },\n                        );\n                    }\n                }\n            }\n            self.params.clear();\n        }\n    }\n}\n\nfn has_matching_args(kind: FnKind, args: GenericArgsRef<'_>) -> bool {\n    match kind {\n        FnKind::Fn => true,\n        FnKind::TraitFn => args.iter().enumerate().all(|(idx, subst)| match subst.kind() {\n            GenericArgKind::Lifetime(_) => true,\n            GenericArgKind::Type(ty) => matches!(*ty.kind(), ty::Param(ty) if ty.index as usize == idx),\n            GenericArgKind::Const(c) => matches!(c.kind(), ConstKind::Param(c) if c.index as usize == idx),\n        }),\n        FnKind::ImplTraitFn(expected_args) => std::ptr::from_ref(args) as usize == expected_args,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/absurd_extreme_comparisons.rs",
    "content": "use rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse clippy_utils::comparisons::{Rel, normalize_comparison};\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::is_isize_or_usize;\nuse clippy_utils::{clip, int_bits, unsext};\n\nuse super::ABSURD_EXTREME_COMPARISONS;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    op: BinOpKind,\n    lhs: &'tcx Expr<'_>,\n    rhs: &'tcx Expr<'_>,\n) {\n    if let Some((culprit, result)) = detect_absurd_comparison(cx, op, lhs, rhs) {\n        let msg = \"this comparison involving the minimum or maximum element for this \\\n                           type contains a case that is always true or always false\";\n\n        let conclusion = match result {\n            AbsurdComparisonResult::AlwaysFalse => \"this comparison is always false\".to_owned(),\n            AbsurdComparisonResult::AlwaysTrue => \"this comparison is always true\".to_owned(),\n            AbsurdComparisonResult::InequalityImpossible => format!(\n                \"the case where the two sides are not equal never occurs, consider using `{} == {}` \\\n                         instead\",\n                snippet(cx, lhs.span, \"lhs\"),\n                snippet(cx, rhs.span, \"rhs\")\n            ),\n        };\n\n        let help = format!(\n            \"because `{}` is the {} value for this type, {conclusion}\",\n            snippet(cx, culprit.expr.span, \"x\"),\n            match culprit.which {\n                ExtremeType::Minimum => \"minimum\",\n                ExtremeType::Maximum => \"maximum\",\n            }\n        );\n\n        span_lint_and_help(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, None, help);\n    }\n}\n\nenum ExtremeType {\n    Minimum,\n    Maximum,\n}\n\nstruct ExtremeExpr<'a> {\n    which: ExtremeType,\n    expr: &'a Expr<'a>,\n}\n\nenum AbsurdComparisonResult {\n    AlwaysFalse,\n    AlwaysTrue,\n    InequalityImpossible,\n}\n\nfn is_cast_between_fixed_and_target<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {\n    if let ExprKind::Cast(cast_exp, _) = expr.kind {\n        let precast_ty = cx.typeck_results().expr_ty(cast_exp);\n        let cast_ty = cx.typeck_results().expr_ty(expr);\n\n        return is_isize_or_usize(precast_ty) != is_isize_or_usize(cast_ty);\n    }\n\n    false\n}\n\nfn detect_absurd_comparison<'tcx>(\n    cx: &LateContext<'tcx>,\n    op: BinOpKind,\n    lhs: &'tcx Expr<'_>,\n    rhs: &'tcx Expr<'_>,\n) -> Option<(ExtremeExpr<'tcx>, AbsurdComparisonResult)> {\n    use AbsurdComparisonResult::{AlwaysFalse, AlwaysTrue, InequalityImpossible};\n    use ExtremeType::{Maximum, Minimum};\n    // absurd comparison only makes sense on primitive types\n    // primitive types don't implement comparison operators with each other\n    if cx.typeck_results().expr_ty(lhs) != cx.typeck_results().expr_ty(rhs) {\n        return None;\n    }\n\n    // comparisons between fix sized types and target sized types are considered unanalyzable\n    if is_cast_between_fixed_and_target(cx, lhs) || is_cast_between_fixed_and_target(cx, rhs) {\n        return None;\n    }\n\n    let (rel, normalized_lhs, normalized_rhs) = normalize_comparison(op, lhs, rhs)?;\n\n    let lx = detect_extreme_expr(cx, normalized_lhs);\n    let rx = detect_extreme_expr(cx, normalized_rhs);\n\n    Some(match rel {\n        Rel::Lt => {\n            match (lx, rx) {\n                (Some(l @ ExtremeExpr { which: Maximum, .. }), _) => (l, AlwaysFalse), // max < x\n                (_, Some(r @ ExtremeExpr { which: Minimum, .. })) => (r, AlwaysFalse), // x < min\n                _ => return None,\n            }\n        },\n        Rel::Le => {\n            match (lx, rx) {\n                (Some(l @ ExtremeExpr { which: Minimum, .. }), _) => (l, AlwaysTrue), // min <= x\n                (Some(l @ ExtremeExpr { which: Maximum, .. }), _) => (l, InequalityImpossible), // max <= x\n                (_, Some(r @ ExtremeExpr { which: Minimum, .. })) => (r, InequalityImpossible), // x <= min\n                (_, Some(r @ ExtremeExpr { which: Maximum, .. })) => (r, AlwaysTrue), // x <= max\n                _ => return None,\n            }\n        },\n        Rel::Ne | Rel::Eq => return None,\n    })\n}\n\nfn detect_extreme_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<ExtremeExpr<'tcx>> {\n    let ty = cx.typeck_results().expr_ty(expr);\n\n    let cv = ConstEvalCtxt::new(cx).eval(expr)?;\n\n    let which = match (ty.kind(), cv) {\n        (&ty::Bool, Constant::Bool(false)) | (&ty::Uint(_), Constant::Int(0)) => ExtremeType::Minimum,\n        (&ty::Int(ity), Constant::Int(i)) if i == unsext(cx.tcx, i128::MIN >> (128 - int_bits(cx.tcx, ity)), ity) => {\n            ExtremeType::Minimum\n        },\n\n        (&ty::Bool, Constant::Bool(true)) => ExtremeType::Maximum,\n        (&ty::Int(ity), Constant::Int(i)) if i == unsext(cx.tcx, i128::MAX >> (128 - int_bits(cx.tcx, ity)), ity) => {\n            ExtremeType::Maximum\n        },\n        (&ty::Uint(uty), Constant::Int(i)) if clip(cx.tcx, u128::MAX, uty) == i => ExtremeType::Maximum,\n\n        _ => return None,\n    };\n    Some(ExtremeExpr { which, expr })\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/arithmetic_side_effects.rs",
    "content": "use super::ARITHMETIC_SIDE_EFFECTS;\nuse crate::clippy_utils::res::MaybeQPath as _;\nuse clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary, sym};\nuse rustc_ast as ast;\nuse rustc_data_structures::fx::{FxHashMap, FxHashSet};\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty, UintTy};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\n\npub struct ArithmeticSideEffects {\n    allowed_binary: FxHashMap<&'static str, FxHashSet<&'static str>>,\n    allowed_unary: FxHashSet<&'static str>,\n    // Used to check whether expressions are constants, such as in enum discriminants and consts\n    const_span: Option<Span>,\n    disallowed_int_methods: FxHashSet<Symbol>,\n    expr_span: Option<Span>,\n}\n\nimpl_lint_pass!(ArithmeticSideEffects => [ARITHMETIC_SIDE_EFFECTS]);\n\nimpl ArithmeticSideEffects {\n    pub fn new(conf: &'static Conf) -> Self {\n        let mut allowed_binary = FxHashMap::<&'static str, FxHashSet<&'static str>>::default();\n        let mut allowed_unary = FxHashSet::<&'static str>::default();\n\n        allowed_unary.extend([\"f32\", \"f64\", \"std::num::Saturating\", \"std::num::Wrapping\"]);\n        allowed_unary.extend(conf.arithmetic_side_effects_allowed_unary.iter().map(|x| &**x));\n        allowed_binary.extend([\n            (\"f32\", FxHashSet::from_iter([\"f32\"])),\n            (\"f64\", FxHashSet::from_iter([\"f64\"])),\n            (\n                \"std::string::String\",\n                FxHashSet::from_iter([\"str\", \"std::string::String\"]),\n            ),\n        ]);\n        for (lhs, rhs) in &conf.arithmetic_side_effects_allowed_binary {\n            allowed_binary.entry(lhs).or_default().insert(rhs);\n        }\n        for s in &conf.arithmetic_side_effects_allowed {\n            allowed_binary.entry(s).or_default().insert(\"*\");\n            allowed_binary.entry(\"*\").or_default().insert(s);\n            allowed_unary.insert(s);\n        }\n\n        Self {\n            allowed_binary,\n            allowed_unary,\n            const_span: None,\n            disallowed_int_methods: [\n                sym::saturating_div,\n                sym::wrapping_div,\n                sym::wrapping_rem,\n                sym::wrapping_rem_euclid,\n            ]\n            .into_iter()\n            .collect(),\n            expr_span: None,\n        }\n    }\n\n    /// Checks if the lhs and the rhs types of a binary operation like \"addition\" or\n    /// \"multiplication\" are present in the inner set of allowed types.\n    fn has_allowed_binary(&self, lhs_ty: Ty<'_>, rhs_ty: Ty<'_>) -> bool {\n        let lhs_ty_string = lhs_ty.to_string();\n        let lhs_ty_string_elem = lhs_ty_string.split('<').next().unwrap_or_default();\n        let rhs_ty_string = rhs_ty.to_string();\n        let rhs_ty_string_elem = rhs_ty_string.split('<').next().unwrap_or_default();\n        if let Some(rhs_from_specific) = self.allowed_binary.get(lhs_ty_string_elem)\n            && {\n                let rhs_has_allowed_ty = rhs_from_specific.contains(rhs_ty_string_elem);\n                rhs_has_allowed_ty || rhs_from_specific.contains(\"*\")\n            }\n        {\n            true\n        } else if let Some(rhs_from_glob) = self.allowed_binary.get(\"*\") {\n            rhs_from_glob.contains(rhs_ty_string_elem)\n        } else {\n            false\n        }\n    }\n\n    /// Checks if the type of an unary operation like \"negation\" is present in the inner set of\n    /// allowed types.\n    fn has_allowed_unary(&self, ty: Ty<'_>) -> bool {\n        let ty_string = ty.to_string();\n        let ty_string_elem = ty_string.split('<').next().unwrap_or_default();\n        self.allowed_unary.contains(ty_string_elem)\n    }\n\n    // Common entry-point to avoid code duplication.\n    fn issue_lint<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        if is_from_proc_macro(cx, expr) {\n            return;\n        }\n        let msg = \"arithmetic operation that can potentially result in unexpected side-effects\";\n        span_lint(cx, ARITHMETIC_SIDE_EFFECTS, expr.span, msg);\n        self.expr_span = Some(expr.span);\n    }\n\n    /// Methods like `add_assign` are send to their `BinOps` references.\n    fn manage_sugar_methods<'tcx>(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        expr: &'tcx hir::Expr<'_>,\n        lhs: &'tcx hir::Expr<'_>,\n        ps: &hir::PathSegment<'_>,\n        rhs: &'tcx hir::Expr<'_>,\n    ) {\n        if ps.ident.name == sym::add || ps.ident.name == sym::add_assign {\n            self.manage_bin_ops(cx, expr, hir::BinOpKind::Add, lhs, rhs);\n        } else if ps.ident.name == sym::div || ps.ident.name == sym::div_assign {\n            self.manage_bin_ops(cx, expr, hir::BinOpKind::Div, lhs, rhs);\n        } else if ps.ident.name == sym::mul || ps.ident.name == sym::mul_assign {\n            self.manage_bin_ops(cx, expr, hir::BinOpKind::Mul, lhs, rhs);\n        } else if ps.ident.name == sym::rem || ps.ident.name == sym::rem_assign {\n            self.manage_bin_ops(cx, expr, hir::BinOpKind::Rem, lhs, rhs);\n        } else if ps.ident.name == sym::sub || ps.ident.name == sym::sub_assign {\n            self.manage_bin_ops(cx, expr, hir::BinOpKind::Sub, lhs, rhs);\n        }\n    }\n\n    /// Manages when the lint should be triggered. Operations in constant environments, hard coded\n    /// types, custom allowed types and non-constant operations that don't overflow are ignored.\n    fn manage_bin_ops<'tcx>(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        expr: &'tcx hir::Expr<'_>,\n        op: hir::BinOpKind,\n        lhs: &'tcx hir::Expr<'_>,\n        rhs: &'tcx hir::Expr<'_>,\n    ) {\n        if ConstEvalCtxt::new(cx).eval_local(expr, expr.span.ctxt()).is_some() {\n            return;\n        }\n        if !matches!(\n            op,\n            hir::BinOpKind::Add\n                | hir::BinOpKind::Div\n                | hir::BinOpKind::Mul\n                | hir::BinOpKind::Rem\n                | hir::BinOpKind::Shl\n                | hir::BinOpKind::Shr\n                | hir::BinOpKind::Sub\n        ) {\n            return;\n        }\n        let (mut actual_lhs, lhs_ref_counter) = peel_hir_expr_refs(lhs);\n        let (mut actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs);\n        actual_lhs = expr_or_init(cx, actual_lhs);\n        actual_rhs = expr_or_init(cx, actual_rhs);\n\n        // `NonZeroU*.get() - 1`, will never overflow\n        if let hir::BinOpKind::Sub = op\n            && let hir::ExprKind::MethodCall(method, receiver, [], _) = actual_lhs.kind\n            && method.ident.name == sym::get\n            && let receiver_ty = cx.typeck_results().expr_ty(receiver).peel_refs()\n            && is_non_zero_u(cx, receiver_ty)\n            && literal_integer(cx, actual_rhs) == Some(1)\n        {\n            return;\n        }\n\n        let lhs_ty = cx.typeck_results().expr_ty(actual_lhs).peel_refs();\n        let rhs_ty = cx.typeck_results().expr_ty_adjusted(actual_rhs).peel_refs();\n        if self.has_allowed_binary(lhs_ty, rhs_ty)\n            | has_specific_allowed_type_and_operation(cx, lhs_ty, op, rhs_ty)\n            | is_safe_due_to_smaller_source_type(cx, op, (actual_lhs, lhs_ty), actual_rhs)\n            | is_safe_due_to_smaller_source_type(cx, op, (actual_rhs, rhs_ty), actual_lhs)\n        {\n            return;\n        }\n        if is_integer(lhs_ty) && is_integer(rhs_ty) {\n            if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op {\n                // At least for integers, shifts are already handled by the CTFE\n                return;\n            }\n            match (literal_integer(cx, actual_lhs), literal_integer(cx, actual_rhs)) {\n                (None, Some(n)) => match (&op, n) {\n                    // Division and module are always valid if applied to non-zero integers\n                    (hir::BinOpKind::Div | hir::BinOpKind::Rem, local_n) if local_n != 0 => return,\n                    // Adding or subtracting zeros is always a no-op\n                    (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0)\n                    // Multiplication by 1 or 0 will never overflow\n                    | (hir::BinOpKind::Mul, 0 | 1)\n                    => return,\n                    _ => {},\n                },\n                (Some(n), None)\n                    if matches!(\n                        (&op, n),\n                        // Adding or subtracting zeros is always a no-op\n                        (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0)\n                        // Multiplication by 1 or 0 will never overflow\n                        | (hir::BinOpKind::Mul, 0 | 1)\n                    ) =>\n                {\n                    return;\n                },\n                (Some(_), Some(_)) if matches!((lhs_ref_counter, rhs_ref_counter), (0, 0)) => return,\n                _ => {},\n            }\n        }\n        self.issue_lint(cx, expr);\n    }\n\n    /// There are some integer methods like `wrapping_div` that will panic depending on the\n    /// provided input.\n    fn manage_method_call<'tcx>(\n        &mut self,\n        args: &'tcx [hir::Expr<'_>],\n        cx: &LateContext<'tcx>,\n        expr: &'tcx hir::Expr<'_>,\n        ps: &'tcx hir::PathSegment<'_>,\n        receiver: &'tcx hir::Expr<'_>,\n    ) {\n        let Some(arg) = args.first() else {\n            return;\n        };\n        if ConstEvalCtxt::new(cx).eval_local(receiver, expr.span.ctxt()).is_some() {\n            return;\n        }\n        let instance_ty = cx.typeck_results().expr_ty_adjusted(receiver);\n        if !is_integer(instance_ty) {\n            return;\n        }\n        self.manage_sugar_methods(cx, expr, receiver, ps, arg);\n        if !self.disallowed_int_methods.contains(&ps.ident.name) {\n            return;\n        }\n        let (actual_arg, _) = peel_hir_expr_refs(arg);\n        match literal_integer(cx, actual_arg) {\n            None | Some(0) => self.issue_lint(cx, arg),\n            Some(_) => {},\n        }\n    }\n\n    fn manage_unary_ops<'tcx>(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        expr: &'tcx hir::Expr<'_>,\n        un_expr: &'tcx hir::Expr<'_>,\n        un_op: hir::UnOp,\n    ) {\n        let hir::UnOp::Neg = un_op else {\n            return;\n        };\n        if ConstEvalCtxt::new(cx).eval(un_expr).is_some() {\n            return;\n        }\n        let ty = cx.typeck_results().expr_ty_adjusted(expr).peel_refs();\n        if self.has_allowed_unary(ty) {\n            return;\n        }\n        let actual_un_expr = peel_hir_expr_refs(un_expr).0;\n        if literal_integer(cx, actual_un_expr).is_some() {\n            return;\n        }\n        self.issue_lint(cx, expr);\n    }\n\n    fn should_skip_expr<'tcx>(&self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool {\n        is_lint_allowed(cx, ARITHMETIC_SIDE_EFFECTS, expr.hir_id)\n            || self.expr_span.is_some()\n            || self.const_span.is_some_and(|sp| sp.contains(expr.span))\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {\n        if self.should_skip_expr(cx, expr) {\n            return;\n        }\n        match &expr.kind {\n            hir::ExprKind::Binary(op, lhs, rhs) => {\n                self.manage_bin_ops(cx, expr, op.node, lhs, rhs);\n            },\n            hir::ExprKind::AssignOp(op, lhs, rhs) => {\n                self.manage_bin_ops(cx, expr, op.node.into(), lhs, rhs);\n            },\n            hir::ExprKind::MethodCall(ps, receiver, args, _) => {\n                self.manage_method_call(args, cx, expr, ps, receiver);\n            },\n            hir::ExprKind::Unary(un_op, un_expr) => {\n                self.manage_unary_ops(cx, expr, un_expr, *un_op);\n            },\n            _ => {},\n        }\n    }\n\n    fn check_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {\n        let body_owner = cx.tcx.hir_body_owner(body.id());\n        let body_owner_def_id = cx.tcx.hir_body_owner_def_id(body.id());\n\n        let body_owner_kind = cx.tcx.hir_body_owner_kind(body_owner_def_id);\n        if let hir::BodyOwnerKind::Const { .. } | hir::BodyOwnerKind::Static(_) = body_owner_kind {\n            let body_span = cx.tcx.hir_span_with_body(body_owner);\n            if let Some(span) = self.const_span\n                && span.contains(body_span)\n            {\n                return;\n            }\n            self.const_span = Some(body_span);\n        }\n    }\n\n    fn check_body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {\n        let body_owner = cx.tcx.hir_body_owner(body.id());\n        let body_span = cx.tcx.hir_span(body_owner);\n        if let Some(span) = self.const_span\n            && span.contains(body_span)\n        {\n            return;\n        }\n        self.const_span = None;\n    }\n\n    fn check_expr_post(&mut self, _: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        if Some(expr.span) == self.expr_span {\n            self.expr_span = None;\n        }\n    }\n}\n\n/// Detects a type-casting conversion and returns the type of the original expression. For\n/// example, `let foo = u64::from(bar)`.\nfn find_original_primitive_ty<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) -> Option<Ty<'tcx>> {\n    if let hir::ExprKind::Call(path, [arg]) = &expr.kind\n        && path.res(cx).opt_def_id().is_diag_item(&cx.tcx, sym::from_fn)\n    {\n        Some(cx.typeck_results().expr_ty(arg))\n    } else {\n        None\n    }\n}\n\n/// Verifies built-in types that have specific allowed operations\nfn has_specific_allowed_type_and_operation<'tcx>(\n    cx: &LateContext<'tcx>,\n    lhs_ty: Ty<'tcx>,\n    op: hir::BinOpKind,\n    rhs_ty: Ty<'tcx>,\n) -> bool {\n    let is_div_or_rem = matches!(op, hir::BinOpKind::Div | hir::BinOpKind::Rem);\n    let is_sat_or_wrap = |ty: Ty<'_>| matches!(ty.opt_diag_name(cx), Some(sym::Saturating | sym::Wrapping));\n\n    // If the RHS is `NonZero<u*>`, then division or module by zero will never occur.\n    if is_non_zero_u(cx, rhs_ty) && is_div_or_rem {\n        return true;\n    }\n\n    // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module.\n    if is_sat_or_wrap(lhs_ty) {\n        return !is_div_or_rem;\n    }\n\n    false\n}\n\n// For example, `i8` or `u128` and possible associated references like `&&u16`.\nfn is_integer(ty: Ty<'_>) -> bool {\n    ty.peel_refs().is_integral()\n}\n\nfn is_non_zero_u(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    if let ty::Adt(adt, substs) = ty.kind()\n        && cx.tcx.is_diagnostic_item(sym::NonZero, adt.did())\n        && let int_type = substs.type_at(0)\n        && matches!(int_type.kind(), ty::Uint(_))\n    {\n        true\n    } else {\n        false\n    }\n}\n\n/// If one side is a literal it is possible to evaluate overflows as long as the other side has a\n/// smaller type. `0` and `1` suffixes indicate different sides.\n///\n/// For example, `1000u64 + u64::from(some_runtime_variable_of_type_u8)`.\nfn is_safe_due_to_smaller_source_type(\n    cx: &LateContext<'_>,\n    op: hir::BinOpKind,\n    (expr0, ty0): (&hir::Expr<'_>, Ty<'_>),\n    expr1: &hir::Expr<'_>,\n) -> bool {\n    let Some(num0) = literal_integer(cx, expr0) else {\n        return false;\n    };\n    let Some(orig_ty1) = find_original_primitive_ty(cx, expr1) else {\n        return false;\n    };\n    let Some(num1) = max_int_num(orig_ty1) else {\n        return false;\n    };\n    let Some(rslt) = (match op {\n        hir::BinOpKind::Add => num0.checked_add(num1),\n        hir::BinOpKind::Mul => num0.checked_mul(num1),\n        _ => None,\n    }) else {\n        return false;\n    };\n    match ty0.peel_refs().kind() {\n        ty::Uint(UintTy::U16) => u16::try_from(rslt).is_ok(),\n        ty::Uint(UintTy::U32) => u32::try_from(rslt).is_ok(),\n        ty::Uint(UintTy::U64) => u64::try_from(rslt).is_ok(),\n        ty::Uint(UintTy::U128) => true,\n        ty::Uint(UintTy::Usize) => usize::try_from(rslt).is_ok(),\n        _ => false,\n    }\n}\n\n/// Returns the numeric value of a literal integer originated from `expr`, if any.\n///\n/// Literal integers can be originated from adhoc declarations like `1`, associated constants\n/// like `i32::MAX` or constant references like `N` from `const N: i32 = 1;`,\nfn literal_integer(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<u128> {\n    let actual = peel_hir_expr_unary(expr).0;\n    if let hir::ExprKind::Lit(lit) = actual.kind\n        && let ast::LitKind::Int(n, _) = lit.node\n    {\n        return Some(n.get());\n    }\n    if let Some(Constant::Int(n)) = ConstEvalCtxt::new(cx).eval(expr) {\n        return Some(n);\n    }\n    None\n}\n\nfn max_int_num(ty: Ty<'_>) -> Option<u128> {\n    match ty.peel_refs().kind() {\n        ty::Uint(UintTy::U8) => Some(u8::MAX.into()),\n        ty::Uint(UintTy::U16) => Some(u16::MAX.into()),\n        ty::Uint(UintTy::U32) => Some(u32::MAX.into()),\n        ty::Uint(UintTy::U64) => Some(u64::MAX.into()),\n        ty::Uint(UintTy::U128) => Some(u128::MAX),\n        ty::Uint(UintTy::Usize) => usize::MAX.try_into().ok(),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/assign_op_pattern.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::qualify_min_const_fn::is_stable_const_fn;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{binop_traits, eq_expr_value, is_in_const_context, trait_ref_of_method};\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::{HirId, HirIdSet};\nuse rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::FakeReadCause;\nuse rustc_middle::ty::BorrowKind;\n\nuse super::ASSIGN_OP_PATTERN;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    assignee: &'tcx hir::Expr<'_>,\n    e: &'tcx hir::Expr<'_>,\n    msrv: Msrv,\n) {\n    if let hir::ExprKind::Binary(op, l, r) = &e.kind {\n        let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| {\n            let ty = cx.typeck_results().expr_ty(assignee);\n            let rty = cx.typeck_results().expr_ty(rhs);\n            if let Some((_, lang_item)) = binop_traits(op.node)\n                && let Some(trait_id) = cx.tcx.lang_items().get(lang_item)\n                && let parent_fn = cx.tcx.hir_get_parent_item(e.hir_id)\n                && trait_ref_of_method(cx, parent_fn).is_none_or(|t| t.path.res.def_id() != trait_id)\n                && implements_trait(cx, ty, trait_id, &[rty.into()])\n            {\n                // Primitive types execute assign-ops right-to-left. Every other type is left-to-right.\n                if !(ty.is_primitive() && rty.is_primitive()) {\n                    // TODO: This will have false negatives as it doesn't check if the borrows are\n                    // actually live at the end of their respective expressions.\n                    let mut_borrows = mut_borrows_in_expr(cx, assignee);\n                    let imm_borrows = imm_borrows_in_expr(cx, rhs);\n                    if mut_borrows.iter().any(|id| imm_borrows.contains(id)) {\n                        return;\n                    }\n                }\n\n                // Skip if the trait or the implementation is not stable in const contexts\n                if is_in_const_context(cx) {\n                    if cx\n                        .tcx\n                        .associated_item_def_ids(trait_id)\n                        .first()\n                        .is_none_or(|binop_id| !is_stable_const_fn(cx, *binop_id, msrv))\n                    {\n                        return;\n                    }\n\n                    let impls = cx.tcx.non_blanket_impls_for_ty(trait_id, rty).collect::<Vec<_>>();\n                    if impls.is_empty()\n                        || impls.into_iter().any(|impl_id| {\n                            cx.tcx\n                                .associated_item_def_ids(impl_id)\n                                .first()\n                                .is_none_or(|fn_id| !is_stable_const_fn(cx, *fn_id, msrv))\n                        })\n                    {\n                        return;\n                    }\n                }\n\n                span_lint_and_then(\n                    cx,\n                    ASSIGN_OP_PATTERN,\n                    expr.span,\n                    \"manual implementation of an assign operation\",\n                    |diag| {\n                        if let Some(snip_a) = assignee.span.get_source_text(cx)\n                            && let Some(snip_r) = rhs.span.get_source_text(cx)\n                        {\n                            diag.span_suggestion(\n                                expr.span,\n                                \"replace it with\",\n                                format!(\"{snip_a} {}= {snip_r}\", op.node.as_str()),\n                                Applicability::MachineApplicable,\n                            );\n                        }\n                    },\n                );\n            }\n        };\n\n        let mut found = false;\n        let found_multiple = for_each_expr_without_closures(e, |e| {\n            if eq_expr_value(cx, assignee, e) {\n                if found {\n                    return ControlFlow::Break(());\n                }\n                found = true;\n            }\n            ControlFlow::Continue(())\n        })\n        .is_some();\n\n        if found && !found_multiple {\n            // a = a op b\n            if eq_expr_value(cx, assignee, l) {\n                lint(assignee, r);\n            }\n            // a = b commutative_op a\n            // Limited to primitive type as these ops are know to be commutative\n            if eq_expr_value(cx, assignee, r) && cx.typeck_results().expr_ty(assignee).is_primitive_ty() {\n                match op.node {\n                    hir::BinOpKind::Add\n                    | hir::BinOpKind::Mul\n                    | hir::BinOpKind::And\n                    | hir::BinOpKind::Or\n                    | hir::BinOpKind::BitXor\n                    | hir::BinOpKind::BitAnd\n                    | hir::BinOpKind::BitOr => {\n                        lint(assignee, l);\n                    },\n                    _ => {},\n                }\n            }\n        }\n    }\n}\n\nfn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet {\n    struct S(HirIdSet);\n    impl Delegate<'_> for S {\n        fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: HirId, kind: BorrowKind) {\n            if matches!(kind, BorrowKind::Immutable | BorrowKind::UniqueImmutable) {\n                self.0.insert(match place.place.base {\n                    PlaceBase::Local(id) => id,\n                    PlaceBase::Upvar(id) => id.var_path.hir_id,\n                    _ => return,\n                });\n            }\n        }\n\n        fn consume(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {}\n        fn use_cloned(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {}\n        fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {}\n        fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: HirId) {}\n        fn copy(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {}\n    }\n\n    let mut s = S(HirIdSet::default());\n    let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s);\n    v.consume_expr(e).into_ok();\n    s.0\n}\n\nfn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet {\n    struct S(HirIdSet);\n    impl Delegate<'_> for S {\n        fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: HirId, kind: BorrowKind) {\n            if matches!(kind, BorrowKind::Mutable) {\n                self.0.insert(match place.place.base {\n                    PlaceBase::Local(id) => id,\n                    PlaceBase::Upvar(id) => id.var_path.hir_id,\n                    _ => return,\n                });\n            }\n        }\n\n        fn consume(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {}\n        fn use_cloned(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {}\n        fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {}\n        fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: HirId) {}\n        fn copy(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {}\n    }\n\n    let mut s = S(HirIdSet::default());\n    let v = ExprUseVisitor::for_clippy(cx, e.hir_id.owner.def_id, &mut s);\n    v.consume_expr(e).into_ok();\n    s.0\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/bit_mask.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::is_from_proc_macro;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::{BAD_BIT_MASK, INEFFECTIVE_BIT_MASK};\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n) {\n    if op.is_comparison() {\n        if let Some(cmp_opt) = fetch_int_literal(cx, right) {\n            check_compare(cx, left, op, cmp_opt, e.span);\n        } else if let Some(cmp_val) = fetch_int_literal(cx, left) {\n            check_compare(cx, right, invert_cmp(op), cmp_val, e.span);\n        }\n    }\n}\n\n#[must_use]\nfn invert_cmp(cmp: BinOpKind) -> BinOpKind {\n    match cmp {\n        BinOpKind::Eq => BinOpKind::Eq,\n        BinOpKind::Ne => BinOpKind::Ne,\n        BinOpKind::Lt => BinOpKind::Gt,\n        BinOpKind::Gt => BinOpKind::Lt,\n        BinOpKind::Le => BinOpKind::Ge,\n        BinOpKind::Ge => BinOpKind::Le,\n        _ => BinOpKind::Or, // Dummy\n    }\n}\n\nfn check_compare<'a>(cx: &LateContext<'a>, bit_op: &Expr<'a>, cmp_op: BinOpKind, cmp_value: u128, span: Span) {\n    if let ExprKind::Binary(op, left, right) = &bit_op.kind {\n        if op.node != BinOpKind::BitAnd && op.node != BinOpKind::BitOr || is_from_proc_macro(cx, bit_op) {\n            return;\n        }\n        if let Some(mask) = fetch_int_literal(cx, right).or_else(|| fetch_int_literal(cx, left)) {\n            check_bit_mask(cx, op.node, cmp_op, mask, cmp_value, span);\n        }\n    }\n}\n\nfn check_bit_mask(\n    cx: &LateContext<'_>,\n    bit_op: BinOpKind,\n    cmp_op: BinOpKind,\n    mask_value: u128,\n    cmp_value: u128,\n    span: Span,\n) {\n    match cmp_op {\n        BinOpKind::Eq | BinOpKind::Ne => match bit_op {\n            BinOpKind::BitAnd => {\n                if mask_value & cmp_value != cmp_value {\n                    if cmp_value != 0 {\n                        span_lint(\n                            cx,\n                            BAD_BIT_MASK,\n                            span,\n                            format!(\"incompatible bit mask: `_ & {mask_value}` can never be equal to `{cmp_value}`\"),\n                        );\n                    }\n                } else if mask_value == 0 {\n                    span_lint(cx, BAD_BIT_MASK, span, \"&-masking with zero\");\n                }\n            },\n            BinOpKind::BitOr if mask_value | cmp_value != cmp_value => {\n                span_lint(\n                    cx,\n                    BAD_BIT_MASK,\n                    span,\n                    format!(\"incompatible bit mask: `_ | {mask_value}` can never be equal to `{cmp_value}`\"),\n                );\n            },\n            _ => (),\n        },\n        BinOpKind::Lt | BinOpKind::Ge => match bit_op {\n            BinOpKind::BitAnd => {\n                if mask_value < cmp_value {\n                    span_lint(\n                        cx,\n                        BAD_BIT_MASK,\n                        span,\n                        format!(\"incompatible bit mask: `_ & {mask_value}` will always be lower than `{cmp_value}`\"),\n                    );\n                } else if mask_value == 0 {\n                    span_lint(cx, BAD_BIT_MASK, span, \"&-masking with zero\");\n                }\n            },\n            BinOpKind::BitOr => {\n                if mask_value >= cmp_value {\n                    span_lint(\n                        cx,\n                        BAD_BIT_MASK,\n                        span,\n                        format!(\"incompatible bit mask: `_ | {mask_value}` will never be lower than `{cmp_value}`\"),\n                    );\n                } else {\n                    check_ineffective_lt(cx, span, mask_value, cmp_value, \"|\");\n                }\n            },\n            BinOpKind::BitXor => check_ineffective_lt(cx, span, mask_value, cmp_value, \"^\"),\n            _ => (),\n        },\n        BinOpKind::Le | BinOpKind::Gt => match bit_op {\n            BinOpKind::BitAnd => {\n                if mask_value <= cmp_value {\n                    span_lint(\n                        cx,\n                        BAD_BIT_MASK,\n                        span,\n                        format!(\"incompatible bit mask: `_ & {mask_value}` will never be higher than `{cmp_value}`\"),\n                    );\n                } else if mask_value == 0 {\n                    span_lint(cx, BAD_BIT_MASK, span, \"&-masking with zero\");\n                }\n            },\n            BinOpKind::BitOr => {\n                if mask_value > cmp_value {\n                    span_lint(\n                        cx,\n                        BAD_BIT_MASK,\n                        span,\n                        format!(\"incompatible bit mask: `_ | {mask_value}` will always be higher than `{cmp_value}`\"),\n                    );\n                } else {\n                    check_ineffective_gt(cx, span, mask_value, cmp_value, \"|\");\n                }\n            },\n            BinOpKind::BitXor => check_ineffective_gt(cx, span, mask_value, cmp_value, \"^\"),\n            _ => (),\n        },\n        _ => (),\n    }\n}\n\nfn check_ineffective_lt(cx: &LateContext<'_>, span: Span, m: u128, c: u128, op: &str) {\n    if c.is_power_of_two() && m < c {\n        span_lint(\n            cx,\n            INEFFECTIVE_BIT_MASK,\n            span,\n            format!(\"ineffective bit mask: `x {op} {m}` compared to `{c}`, is the same as x compared directly\"),\n        );\n    }\n}\n\nfn check_ineffective_gt(cx: &LateContext<'_>, span: Span, m: u128, c: u128, op: &str) {\n    if (c + 1).is_power_of_two() && m <= c {\n        span_lint(\n            cx,\n            INEFFECTIVE_BIT_MASK,\n            span,\n            format!(\"ineffective bit mask: `x {op} {m}` compared to `{c}`, is the same as x compared directly\"),\n        );\n    }\n}\n\nfn fetch_int_literal(cx: &LateContext<'_>, lit: &Expr<'_>) -> Option<u128> {\n    match ConstEvalCtxt::new(cx).eval(lit)? {\n        Constant::Int(n) => Some(n),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/cmp_owned.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeQPath;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::sym;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\nuse super::CMP_OWNED;\n\npub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>) {\n    if op.is_comparison() {\n        check_op(cx, e, lhs, rhs, true);\n        check_op(cx, e, rhs, lhs, false);\n    }\n}\n\n#[derive(Default)]\nstruct EqImpl {\n    ty_eq_other: bool,\n    other_eq_ty: bool,\n}\nimpl EqImpl {\n    fn is_implemented(&self) -> bool {\n        self.ty_eq_other || self.other_eq_ty\n    }\n}\n\nfn symmetric_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'tcx>) -> Option<EqImpl> {\n    cx.tcx.lang_items().eq_trait().map(|def_id| EqImpl {\n        ty_eq_other: implements_trait(cx, ty, def_id, &[other.into()]),\n        other_eq_ty: implements_trait(cx, other, def_id, &[ty.into()]),\n    })\n}\n\nfn check_op(cx: &LateContext<'_>, outer: &Expr<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) {\n    if !outer.span.eq_ctxt(expr.span) {\n        return;\n    }\n\n    let typeck = cx.typeck_results();\n    let (arg, arg_span) = match expr.kind {\n        ExprKind::MethodCall(_, arg, [], _)\n            if typeck\n                .type_dependent_def_id(expr.hir_id)\n                .and_then(|id| cx.tcx.trait_of_assoc(id))\n                .is_some_and(|id| matches!(cx.tcx.get_diagnostic_name(id), Some(sym::ToString | sym::ToOwned))) =>\n        {\n            (arg, arg.span)\n        },\n        ExprKind::Call(path, [arg])\n            if path\n                .res(cx)\n                .opt_def_id()\n                .is_some_and(|did| match cx.tcx.get_diagnostic_name(did) {\n                    Some(sym::from_str_method) => true,\n                    Some(sym::from_fn) => !is_copy(cx, typeck.expr_ty(expr)),\n                    _ => false,\n                }) =>\n        {\n            (arg, arg.span)\n        },\n        _ => return,\n    };\n\n    let arg_ty = typeck.expr_ty(arg);\n    let other_ty = typeck.expr_ty(other);\n\n    let without_deref = symmetric_partial_eq(cx, arg_ty, other_ty).unwrap_or_default();\n    let with_deref = arg_ty\n        .builtin_deref(true)\n        .and_then(|ty| symmetric_partial_eq(cx, ty, other_ty))\n        .unwrap_or_default();\n\n    if !with_deref.is_implemented() && !without_deref.is_implemented() {\n        return;\n    }\n\n    let other_gets_derefed = matches!(other.kind, ExprKind::Unary(UnOp::Deref, _));\n\n    let lint_span = if other_gets_derefed {\n        expr.span.to(other.span)\n    } else {\n        expr.span\n    };\n\n    span_lint_and_then(\n        cx,\n        CMP_OWNED,\n        lint_span,\n        \"this creates an owned instance just for comparison\",\n        |diag| {\n            // This also catches `PartialEq` implementations that call `to_owned`.\n            if other_gets_derefed {\n                diag.span_label(lint_span, \"try implementing the comparison without allocating\");\n                return;\n            }\n\n            let mut applicability = Applicability::MachineApplicable;\n            let (arg_snip, _) = snippet_with_context(cx, arg_span, expr.span.ctxt(), \"..\", &mut applicability);\n            let (expr_snip, eq_impl) = if without_deref.is_implemented() {\n                (arg_snip.to_string(), without_deref)\n            } else {\n                (format!(\"*{arg_snip}\"), with_deref)\n            };\n\n            let (span, hint) = if (eq_impl.ty_eq_other && left) || (eq_impl.other_eq_ty && !left) {\n                (expr.span, expr_snip)\n            } else {\n                let span = expr.span.to(other.span);\n\n                let cmp_span = if other.span < expr.span {\n                    other.span.between(expr.span)\n                } else {\n                    expr.span.between(other.span)\n                };\n\n                let (cmp_snippet, _) = snippet_with_context(cx, cmp_span, expr.span.ctxt(), \"..\", &mut applicability);\n                let (other_snippet, _) =\n                    snippet_with_context(cx, other.span, expr.span.ctxt(), \"..\", &mut applicability);\n\n                if eq_impl.ty_eq_other {\n                    (span, format!(\"{expr_snip}{cmp_snippet}{other_snippet}\"))\n                } else {\n                    (span, format!(\"{other_snippet}{cmp_snippet}{expr_snip}\"))\n                }\n            };\n\n            diag.span_suggestion(span, \"try\", hint, applicability);\n        },\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/const_comparisons.rs",
    "content": "#![allow(clippy::match_same_arms)]\n\nuse std::cmp::Ordering;\n\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::layout::HasTyCtxt;\nuse rustc_middle::ty::{Ty, TypeckResults};\nuse rustc_span::Span;\nuse rustc_span::source_map::Spanned;\n\nuse clippy_utils::SpanlessEq;\nuse clippy_utils::diagnostics::span_lint_and_note;\nuse clippy_utils::source::snippet;\n\nuse super::{IMPOSSIBLE_COMPARISONS, REDUNDANT_COMPARISONS};\n\n// Extract a comparison between a const and non-const\n// Flip yoda conditionals, turnings expressions like `42 < x` into `x > 42`\nfn comparison_to_const<'tcx>(\n    cx: &LateContext<'tcx>,\n    typeck: &'tcx TypeckResults<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n) -> Option<(CmpOp, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>, Constant, Ty<'tcx>)> {\n    if let ExprKind::Binary(operator, left, right) = expr.kind\n        && let Ok(cmp_op) = CmpOp::try_from(operator.node)\n    {\n        let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), typeck);\n        match (ecx.eval(left), ecx.eval(right)) {\n            (Some(_), Some(_)) => None,\n            (_, Some(con)) => Some((cmp_op, left, right, con, typeck.expr_ty(right))),\n            (Some(con), _) => Some((cmp_op.reverse(), right, left, con, typeck.expr_ty(left))),\n            _ => None,\n        }\n    } else {\n        None\n    }\n}\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    and_op: Spanned<BinOpKind>,\n    left_cond: &'tcx Expr<'tcx>,\n    right_cond: &'tcx Expr<'tcx>,\n    span: Span,\n) {\n    if and_op.node == BinOpKind::And\n        // Ensure that the binary operator is &&\n\n        // Check that both operands to '&&' are themselves a binary operation\n        // The `comparison_to_const` step also checks this, so this step is just an optimization\n        && let ExprKind::Binary(_, _, _) = left_cond.kind\n        && let ExprKind::Binary(_, _, _) = right_cond.kind\n\n        && let typeck = cx.typeck_results()\n\n        // Check that both operands to '&&' compare a non-literal to a literal\n        && let Some((left_cmp_op, left_expr, left_const_expr, left_const, left_type)) =\n            comparison_to_const(cx, typeck, left_cond)\n        && let Some((right_cmp_op, right_expr, right_const_expr, right_const, right_type)) =\n            comparison_to_const(cx, typeck, right_cond)\n\n        && left_type == right_type\n\n        // Check that the same expression is compared in both comparisons\n        && SpanlessEq::new(cx).eq_expr(left_expr, right_expr)\n\n        && !left_expr.can_have_side_effects()\n\n        // Compare the two constant expressions\n        && let Some(ordering) = Constant::partial_cmp(cx.tcx(), left_type, &left_const, &right_const)\n\n        // Rule out the `x >= 42 && x <= 42` corner case immediately\n        // Mostly to simplify the implementation, but it is also covered by `clippy::double_comparisons`\n        && !matches!(\n            (&left_cmp_op, &right_cmp_op, ordering),\n            (CmpOp::Le | CmpOp::Ge, CmpOp::Le | CmpOp::Ge, Ordering::Equal)\n        )\n    {\n        if left_cmp_op.direction() == right_cmp_op.direction() {\n            let lhs_str = snippet(cx, left_cond.span, \"<lhs>\");\n            let rhs_str = snippet(cx, right_cond.span, \"<rhs>\");\n            // We already know that either side of `&&` has no effect,\n            // but emit a different error message depending on which side it is\n            if left_side_is_useless(left_cmp_op, ordering) {\n                span_lint_and_note(\n                    cx,\n                    REDUNDANT_COMPARISONS,\n                    span,\n                    \"left-hand side of `&&` operator has no effect\",\n                    Some(left_cond.span.until(right_cond.span)),\n                    format!(\"`if `{rhs_str}` evaluates to true, {lhs_str}` will always evaluate to true as well\"),\n                );\n            } else {\n                span_lint_and_note(\n                    cx,\n                    REDUNDANT_COMPARISONS,\n                    span,\n                    \"right-hand side of `&&` operator has no effect\",\n                    Some(and_op.span.to(right_cond.span)),\n                    format!(\"`if `{lhs_str}` evaluates to true, {rhs_str}` will always evaluate to true as well\"),\n                );\n            }\n            // We could autofix this error but choose not to,\n            // because code triggering this lint probably not behaving correctly in the first place\n        } else if !comparison_is_possible(left_cmp_op.direction(), ordering) {\n            let expr_str = snippet(cx, left_expr.span, \"..\");\n            let lhs_str = snippet(cx, left_const_expr.span, \"<lhs>\");\n            let rhs_str = snippet(cx, right_const_expr.span, \"<rhs>\");\n            let note = match ordering {\n                Ordering::Less => format!(\n                    \"since `{lhs_str}` < `{rhs_str}`, the expression evaluates to false for any value of `{expr_str}`\"\n                ),\n                Ordering::Equal => {\n                    format!(\"`{expr_str}` cannot simultaneously be greater than and less than `{lhs_str}`\")\n                },\n                Ordering::Greater => format!(\n                    \"since `{lhs_str}` > `{rhs_str}`, the expression evaluates to false for any value of `{expr_str}`\"\n                ),\n            };\n            span_lint_and_note(\n                cx,\n                IMPOSSIBLE_COMPARISONS,\n                span,\n                \"boolean expression will never evaluate to 'true'\",\n                None,\n                note,\n            );\n        }\n    }\n}\n\nfn left_side_is_useless(left_cmp_op: CmpOp, ordering: Ordering) -> bool {\n    // Special-case for equal constants with an inclusive comparison\n    if ordering == Ordering::Equal {\n        match left_cmp_op {\n            CmpOp::Lt | CmpOp::Gt => false,\n            CmpOp::Le | CmpOp::Ge => true,\n        }\n    } else {\n        match (left_cmp_op.direction(), ordering) {\n            (CmpOpDirection::Lesser, Ordering::Less) => false,\n            (CmpOpDirection::Lesser, Ordering::Equal) => false,\n            (CmpOpDirection::Lesser, Ordering::Greater) => true,\n            (CmpOpDirection::Greater, Ordering::Less) => true,\n            (CmpOpDirection::Greater, Ordering::Equal) => false,\n            (CmpOpDirection::Greater, Ordering::Greater) => false,\n        }\n    }\n}\n\nfn comparison_is_possible(left_cmp_direction: CmpOpDirection, ordering: Ordering) -> bool {\n    match (left_cmp_direction, ordering) {\n        (CmpOpDirection::Lesser, Ordering::Less | Ordering::Equal) => false,\n        (CmpOpDirection::Lesser, Ordering::Greater) => true,\n        (CmpOpDirection::Greater, Ordering::Greater | Ordering::Equal) => false,\n        (CmpOpDirection::Greater, Ordering::Less) => true,\n    }\n}\n\n#[derive(PartialEq, Eq, Clone, Copy)]\nenum CmpOpDirection {\n    Lesser,\n    Greater,\n}\n\n#[derive(Clone, Copy)]\nenum CmpOp {\n    Lt,\n    Le,\n    Ge,\n    Gt,\n}\n\nimpl CmpOp {\n    fn reverse(self) -> Self {\n        match self {\n            CmpOp::Lt => CmpOp::Gt,\n            CmpOp::Le => CmpOp::Ge,\n            CmpOp::Ge => CmpOp::Le,\n            CmpOp::Gt => CmpOp::Lt,\n        }\n    }\n\n    fn direction(self) -> CmpOpDirection {\n        match self {\n            CmpOp::Lt => CmpOpDirection::Lesser,\n            CmpOp::Le => CmpOpDirection::Lesser,\n            CmpOp::Ge => CmpOpDirection::Greater,\n            CmpOp::Gt => CmpOpDirection::Greater,\n        }\n    }\n}\n\nimpl TryFrom<BinOpKind> for CmpOp {\n    type Error = ();\n\n    fn try_from(bin_op: BinOpKind) -> Result<Self, Self::Error> {\n        match bin_op {\n            BinOpKind::Lt => Ok(CmpOp::Lt),\n            BinOpKind::Le => Ok(CmpOp::Le),\n            BinOpKind::Ge => Ok(CmpOp::Ge),\n            BinOpKind::Gt => Ok(CmpOp::Gt),\n            _ => Err(()),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/decimal_bitwise_operands.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::numeric_literal;\nuse clippy_utils::numeric_literal::NumericLiteral;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_ast::LitKind;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::DECIMAL_BITWISE_OPERANDS;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, op: BinOpKind, left: &'tcx Expr<'_>, right: &'tcx Expr<'_>) {\n    if !matches!(op, BinOpKind::BitAnd | BinOpKind::BitOr | BinOpKind::BitXor) {\n        return;\n    }\n\n    for expr in [left, right] {\n        check_expr(cx, expr);\n    }\n}\n\nfn check_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    match &expr.kind {\n        ExprKind::Block(block, _) => {\n            if let Some(block_expr) = block.expr {\n                check_expr(cx, block_expr);\n            }\n        },\n        ExprKind::Cast(cast_expr, _) => {\n            check_expr(cx, cast_expr);\n        },\n        ExprKind::Unary(_, unary_expr) => {\n            check_expr(cx, unary_expr);\n        },\n        ExprKind::AddrOf(_, _, addr_of_expr) => {\n            check_expr(cx, addr_of_expr);\n        },\n        ExprKind::Lit(lit) => {\n            if let LitKind::Int(Pu128(val), _) = lit.node\n                && !is_single_digit(val)\n                && !is_power_of_twoish(val)\n                && let Some(src) = lit.span.get_source_text(cx)\n                && let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node)\n                && num_lit.is_decimal()\n            {\n                emit_lint(cx, lit.span, num_lit.suffix, val);\n            }\n        },\n        _ => (),\n    }\n}\n\nfn is_power_of_twoish(val: u128) -> bool {\n    val.is_power_of_two() || val.wrapping_add(1).is_power_of_two()\n}\n\nfn is_single_digit(val: u128) -> bool {\n    val <= 9\n}\n\nfn emit_lint(cx: &LateContext<'_>, span: Span, suffix: Option<&str>, val: u128) {\n    span_lint_and_help(\n        cx,\n        DECIMAL_BITWISE_OPERANDS,\n        span,\n        \"using decimal literal for bitwise operation\",\n        None,\n        format!(\n            \"use binary ({}), hex ({}), or octal ({}) notation for better readability\",\n            numeric_literal::format(&format!(\"{val:#b}\"), suffix, false),\n            numeric_literal::format(&format!(\"{val:#x}\"), suffix, false),\n            numeric_literal::format(&format!(\"{val:#o}\"), suffix, false),\n        ),\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/double_comparison.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::eq_expr_value;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::DOUBLE_COMPARISONS;\n\npub(super) fn check(cx: &LateContext<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>, span: Span) {\n    if let ExprKind::Binary(lop, llhs, lrhs) = lhs.kind\n        && let ExprKind::Binary(rop, rlhs, rrhs) = rhs.kind\n        && eq_expr_value(cx, llhs, rlhs)\n        && eq_expr_value(cx, lrhs, rrhs)\n    {\n        let op = match (op, lop.node, rop.node) {\n            // x == y || x < y => x <= y\n            (BinOpKind::Or, BinOpKind::Eq, BinOpKind::Lt)\n            // x < y || x == y => x <= y\n            | (BinOpKind::Or, BinOpKind::Lt, BinOpKind::Eq) => {\n                \"<=\"\n            },\n            // x == y || x > y => x >= y\n            (BinOpKind::Or, BinOpKind::Eq, BinOpKind::Gt)\n            // x > y || x == y => x >= y\n            | (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Eq) => {\n                \">=\"\n            },\n            // x < y || x > y => x != y\n            (BinOpKind::Or, BinOpKind::Lt, BinOpKind::Gt)\n            // x > y || x < y => x != y\n            | (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Lt) => {\n                \"!=\"\n            },\n            // x <= y && x >= y => x == y\n            (BinOpKind::And, BinOpKind::Le, BinOpKind::Ge)\n            // x >= y && x <= y => x == y\n            | (BinOpKind::And, BinOpKind::Ge, BinOpKind::Le) => {\n                \"==\"\n            },\n            // x != y && x >= y => x > y\n            (BinOpKind::And, BinOpKind::Ne, BinOpKind::Ge)\n            // x >= y && x != y => x > y\n            | (BinOpKind::And, BinOpKind::Ge, BinOpKind::Ne) => {\n                \">\"\n            },\n            // x != y && x <= y => x < y\n            (BinOpKind::And, BinOpKind::Ne, BinOpKind::Le)\n            // x <= y && x != y => x < y\n            | (BinOpKind::And, BinOpKind::Le, BinOpKind::Ne) => {\n                \"<\"\n            },\n            _ => return,\n        };\n\n        let mut applicability = Applicability::MachineApplicable;\n        let lhs_str = snippet_with_applicability(cx, llhs.span, \"\", &mut applicability);\n        let rhs_str = snippet_with_applicability(cx, lrhs.span, \"\", &mut applicability);\n        let sugg = format!(\"{lhs_str} {op} {rhs_str}\");\n        span_lint_and_sugg(\n            cx,\n            DOUBLE_COMPARISONS,\n            span,\n            \"this binary expression can be simplified\",\n            \"try\",\n            sugg,\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/duration_subsec.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\n\nuse super::DURATION_SUBSEC;\n\npub(crate) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n) {\n    if op == BinOpKind::Div\n        && let ExprKind::MethodCall(method_path, self_arg, [], _) = left.kind\n        && cx\n            .typeck_results()\n            .expr_ty(self_arg)\n            .peel_refs()\n            .is_diag_item(cx, sym::Duration)\n        && let Some(Constant::Int(divisor)) = ConstEvalCtxt::new(cx).eval_local(right, expr.span.ctxt())\n    {\n        let suggested_fn = match (method_path.ident.name, divisor) {\n            (sym::subsec_micros, 1_000) | (sym::subsec_nanos, 1_000_000) => \"subsec_millis\",\n            (sym::subsec_nanos, 1_000) => \"subsec_micros\",\n            _ => return,\n        };\n        let mut applicability = Applicability::MachineApplicable;\n        span_lint_and_sugg(\n            cx,\n            DURATION_SUBSEC,\n            expr.span,\n            format!(\"calling `{suggested_fn}()` is more concise than this calculation\"),\n            \"try\",\n            format!(\n                \"{}.{suggested_fn}()\",\n                snippet_with_applicability(cx, self_arg.span, \"_\", &mut applicability)\n            ),\n            applicability,\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/eq_op.rs",
    "content": "use clippy_utils::ast_utils::is_useless_with_eq_exprs;\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::macros::{find_assert_eq_args, first_node_macro_backtrace};\nuse clippy_utils::{eq_expr_value, is_in_test_function, sym};\nuse rustc_hir::{BinOpKind, Expr};\nuse rustc_lint::LateContext;\n\nuse super::EQ_OP;\n\npub(crate) fn check_assert<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n    if let Some(macro_call) = first_node_macro_backtrace(cx, e).find(|macro_call| {\n        matches!(\n            cx.tcx.get_diagnostic_name(macro_call.def_id),\n            Some(sym::assert_eq_macro | sym::assert_ne_macro | sym::debug_assert_eq_macro | sym::debug_assert_ne_macro)\n        )\n    }) && let Some((lhs, rhs, _)) = find_assert_eq_args(cx, e, macro_call.expn)\n        && eq_expr_value(cx, lhs, rhs)\n        && macro_call.is_local()\n        && !is_in_test_function(cx.tcx, e.hir_id)\n    {\n        span_lint(\n            cx,\n            EQ_OP,\n            lhs.span.to(rhs.span),\n            format!(\n                \"identical args used in this `{}!` macro call\",\n                cx.tcx.item_name(macro_call.def_id)\n            ),\n        );\n    }\n}\n\npub(crate) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n) {\n    if is_useless_with_eq_exprs(op) && eq_expr_value(cx, left, right) && !is_in_test_function(cx.tcx, e.hir_id) {\n        span_lint_and_then(\n            cx,\n            EQ_OP,\n            e.span,\n            format!(\"equal expressions as operands to `{}`\", op.as_str()),\n            |diag| {\n                if let BinOpKind::Ne = op\n                    && cx.typeck_results().expr_ty(left).is_floating_point()\n                {\n                    diag.note(\"if you intended to check if the operand is NaN, use `.is_nan()` instead\");\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/erasing_op.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::ty::same_type_modulo_regions;\n\nuse rustc_hir::{BinOpKind, Expr};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::TypeckResults;\n\nuse super::ERASING_OP;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n) {\n    let tck = cx.typeck_results();\n    match op {\n        BinOpKind::Mul | BinOpKind::BitAnd => {\n            check_op(cx, tck, left, right, e);\n            check_op(cx, tck, right, left, e);\n        },\n        BinOpKind::Div => check_op(cx, tck, left, right, e),\n        _ => (),\n    }\n}\n\nfn different_types(tck: &TypeckResults<'_>, input: &Expr<'_>, output: &Expr<'_>) -> bool {\n    let input_ty = tck.expr_ty(input).peel_refs();\n    let output_ty = tck.expr_ty(output).peel_refs();\n    !same_type_modulo_regions(input_ty, output_ty)\n}\n\nfn check_op<'tcx>(\n    cx: &LateContext<'tcx>,\n    tck: &'tcx TypeckResults<'tcx>,\n    op: &Expr<'tcx>,\n    other: &Expr<'tcx>,\n    parent: &Expr<'tcx>,\n) {\n    if ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), tck).eval_local(op, parent.span.ctxt())\n        == Some(Constant::Int(0))\n    {\n        if different_types(tck, other, parent) {\n            return;\n        }\n        span_lint(\n            cx,\n            ERASING_OP,\n            parent.span,\n            \"this operation will always return zero. This is likely not the intended outcome\",\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/float_cmp.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{parent_item_name, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::{FLOAT_CMP, FLOAT_CMP_CONST};\n\npub(crate) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n) {\n    if (op == BinOpKind::Eq || op == BinOpKind::Ne) && is_float(cx, left) {\n        let ecx = ConstEvalCtxt::new(cx);\n        let ctxt = expr.span.ctxt();\n        let left_is_local = match ecx.eval_with_source(left, ctxt) {\n            Some((c, s)) if !is_allowed(&c) => s.is_local(),\n            Some(_) => return,\n            None => true,\n        };\n        let right_is_local = match ecx.eval_with_source(right, ctxt) {\n            Some((c, s)) if !is_allowed(&c) => s.is_local(),\n            Some(_) => return,\n            None => true,\n        };\n\n        // Allow comparing the results of signum()\n        if is_signum(cx, left) && is_signum(cx, right) {\n            return;\n        }\n\n        if let Some(name) = parent_item_name(cx, expr) {\n            let name = name.as_str();\n            if name == \"eq\" || name == \"ne\" || name == \"is_nan\" || name.starts_with(\"eq_\") || name.ends_with(\"_eq\") {\n                return;\n            }\n        }\n        let is_comparing_arrays = is_array(cx, left) || is_array(cx, right);\n        let (lint, msg) = get_lint_and_message(left_is_local && right_is_local, is_comparing_arrays);\n        span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n            let lhs = Sugg::hir(cx, left, \"..\");\n            let rhs = Sugg::hir(cx, right, \"..\");\n\n            if !is_comparing_arrays {\n                diag.span_suggestion(\n                    expr.span,\n                    \"consider comparing them within some margin of error\",\n                    format!(\n                        \"({}).abs() {} error_margin\",\n                        lhs - rhs,\n                        if op == BinOpKind::Eq { '<' } else { '>' }\n                    ),\n                    Applicability::HasPlaceholders, // snippet\n                );\n            }\n        });\n    }\n}\n\nfn get_lint_and_message(is_local: bool, is_comparing_arrays: bool) -> (&'static rustc_lint::Lint, &'static str) {\n    if is_local {\n        (\n            FLOAT_CMP,\n            if is_comparing_arrays {\n                \"strict comparison of `f32` or `f64` arrays\"\n            } else {\n                \"strict comparison of `f32` or `f64`\"\n            },\n        )\n    } else {\n        (\n            FLOAT_CMP_CONST,\n            if is_comparing_arrays {\n                \"strict comparison of `f32` or `f64` constant arrays\"\n            } else {\n                \"strict comparison of `f32` or `f64` constant\"\n            },\n        )\n    }\n}\n\nfn is_allowed(val: &Constant) -> bool {\n    match val {\n        // FIXME(f16_f128): add when equality check is available on all platforms\n        &Constant::F32(f) => f == 0.0 || f.is_infinite(),\n        &Constant::F64(f) => f == 0.0 || f.is_infinite(),\n        Constant::Vec(vec) => vec.iter().all(|f| match f {\n            Constant::F32(f) => *f == 0.0 || (*f).is_infinite(),\n            Constant::F64(f) => *f == 0.0 || (*f).is_infinite(),\n            _ => false,\n        }),\n        _ => false,\n    }\n}\n\n// Return true if `expr` is the result of `signum()` invoked on a float value.\nfn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    // The negation of a signum is still a signum\n    if let ExprKind::Unary(UnOp::Neg, child_expr) = expr.kind {\n        return is_signum(cx, child_expr);\n    }\n\n    if let ExprKind::MethodCall(method_name, self_arg, [], _) = expr.kind\n        && method_name.ident.name == sym::signum\n    // Check that the receiver of the signum() is a float (expressions[0] is the receiver of\n    // the method call)\n    {\n        return is_float(cx, self_arg);\n    }\n    false\n}\n\nfn is_float(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let value = &cx.typeck_results().expr_ty(expr).peel_refs().kind();\n\n    if let ty::Array(arr_ty, _) = value {\n        return matches!(arr_ty.kind(), ty::Float(_));\n    }\n\n    matches!(value, ty::Float(_))\n}\n\nfn is_array(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    matches!(&cx.typeck_results().expr_ty(expr).peel_refs().kind(), ty::Array(_, _))\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/float_equality_without_abs.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::{sugg, sym};\nuse rustc_ast::util::parser::AssocOp;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::source_map::Spanned;\n\nuse super::FLOAT_EQUALITY_WITHOUT_ABS;\n\npub(crate) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    op: BinOpKind,\n    lhs: &'tcx Expr<'_>,\n    rhs: &'tcx Expr<'_>,\n) {\n    let (lhs, rhs) = match op {\n        BinOpKind::Lt => (lhs, rhs),\n        BinOpKind::Gt => (rhs, lhs),\n        _ => return,\n    };\n\n    if let ExprKind::Binary(\n        // left hand side is a subtraction\n            Spanned {\n                node: BinOpKind::Sub,\n                ..\n            },\n            val_l,\n            val_r,\n        ) = lhs.kind\n\n        // right hand side matches _::EPSILON\n        && let ExprKind::Path(ref epsilon_path) = rhs.kind\n        && let Res::Def(DefKind::AssocConst { .. }, def_id) = cx.qpath_res(epsilon_path, rhs.hir_id)\n        && let Some(sym) = cx.tcx.get_diagnostic_name(def_id)\n        && matches!(sym, sym::f16_epsilon | sym::f32_epsilon | sym::f64_epsilon | sym::f128_epsilon)\n\n        // values of the subtractions on the left hand side are of the type float\n        && let t_val_l = cx.typeck_results().expr_ty(val_l)\n        && let t_val_r = cx.typeck_results().expr_ty(val_r)\n        && let ty::Float(_) = t_val_l.kind()\n        && let ty::Float(_) = t_val_r.kind()\n    {\n        let sug_l = sugg::Sugg::hir(cx, val_l, \"..\");\n        let sug_r = sugg::Sugg::hir(cx, val_r, \"..\");\n        // format the suggestion\n        let suggestion = format!(\n            \"{}.abs()\",\n            sugg::make_assoc(AssocOp::Binary(BinOpKind::Sub), &sug_l, &sug_r).maybe_paren()\n        );\n        // spans the lint\n        span_lint_and_then(\n            cx,\n            FLOAT_EQUALITY_WITHOUT_ABS,\n            expr.span,\n            \"float equality check without `.abs()`\",\n            |diag| {\n                diag.span_suggestion(lhs.span, \"add `.abs()`\", suggestion, Applicability::MaybeIncorrect);\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/identity_op.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant, FullInt, integer_const, is_zero_integer_const};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{ExprUseNode, clip, expr_use_ctxt, peel_hir_expr_refs, unsext};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{BinOpKind, Expr, ExprKind, Node, Path, QPath};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::{Span, SyntaxContext, kw};\n\nuse super::IDENTITY_OP;\n\npub(crate) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n) {\n    if !is_allowed(cx, expr, op, left, right) {\n        return;\n    }\n\n    // we need to know whether a ref is coerced to a value\n    // if a ref is coerced, then the suggested lint must deref it\n    // e.g. `let _: i32 = x+0` with `x: &i32` should be replaced with `let _: i32 = *x`.\n    // we do this by checking the _kind_ of the type of the expression\n    // if it's a ref, we then check whether it is erased, and that's it.\n    let (peeled_left_span, left_is_coerced_to_value) = {\n        let expr = peel_hir_expr_refs(left).0;\n        let span = expr.span;\n        let is_coerced = expr_is_erased_ref(cx, expr);\n        (span, is_coerced)\n    };\n\n    let (peeled_right_span, right_is_coerced_to_value) = {\n        let expr = peel_hir_expr_refs(right).0;\n        let span = expr.span;\n        let is_coerced = expr_is_erased_ref(cx, expr);\n        (span, is_coerced)\n    };\n\n    let ctxt = expr.span.ctxt();\n    match op {\n        BinOpKind::Add | BinOpKind::BitOr | BinOpKind::BitXor => {\n            if is_redundant_op(cx, left, 0, ctxt) {\n                let paren = needs_parenthesis(cx, expr, right);\n                span_ineffective_operation(cx, expr.span, peeled_right_span, paren, right_is_coerced_to_value);\n            } else if is_redundant_op(cx, right, 0, ctxt) {\n                let paren = needs_parenthesis(cx, expr, left);\n                span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);\n            }\n        },\n        BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Sub if is_redundant_op(cx, right, 0, ctxt) => {\n            let paren = needs_parenthesis(cx, expr, left);\n            span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);\n        },\n        BinOpKind::Mul => {\n            if is_redundant_op(cx, left, 1, ctxt) {\n                let paren = needs_parenthesis(cx, expr, right);\n                span_ineffective_operation(cx, expr.span, peeled_right_span, paren, right_is_coerced_to_value);\n            } else if is_redundant_op(cx, right, 1, ctxt) {\n                let paren = needs_parenthesis(cx, expr, left);\n                span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);\n            }\n        },\n        BinOpKind::Div if is_redundant_op(cx, right, 1, ctxt) => {\n            let paren = needs_parenthesis(cx, expr, left);\n            span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);\n        },\n        BinOpKind::BitAnd => {\n            if is_redundant_op(cx, left, -1, ctxt) {\n                let paren = needs_parenthesis(cx, expr, right);\n                span_ineffective_operation(cx, expr.span, peeled_right_span, paren, right_is_coerced_to_value);\n            } else if is_redundant_op(cx, right, -1, ctxt) {\n                let paren = needs_parenthesis(cx, expr, left);\n                span_ineffective_operation(cx, expr.span, peeled_left_span, paren, left_is_coerced_to_value);\n            }\n        },\n        BinOpKind::Rem => check_remainder(cx, left, right, expr.span, left.span),\n        _ => (),\n    }\n}\n\nfn expr_is_erased_ref(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match cx.typeck_results().expr_ty(expr).kind() {\n        ty::Ref(r, ..) => r.is_erased(),\n        _ => false,\n    }\n}\n\n#[derive(Copy, Clone)]\nenum Parens {\n    Needed,\n    Unneeded,\n}\n\n/// Checks if a binary expression needs parenthesis when reduced to just its\n/// right or left child.\n///\n/// e.g. `-(x + y + 0)` cannot be reduced to `-x + y`, as the behavior changes silently.\n/// e.g. `1u64 + ((x + y + 0i32) as u64)` cannot be reduced to `1u64 + x + y as u64`, since\n/// the cast expression will not apply to the same expression.\n/// e.g. `0 + if b { 1 } else { 2 } + if b { 3 } else { 4 }` cannot be reduced\n/// to `if b { 1 } else { 2 } + if b { 3 } else { 4 }` where the `if` could be\n/// interpreted as a statement. The same behavior happens for `match`, `loop`,\n/// and blocks.\n/// e.g.  `2 * (0 + { a })` can be reduced to `2 * { a }` without the need for parenthesis,\n/// but `1 * ({ a } + 4)` cannot be reduced to `{ a } + 4`, as a block at the start of a line\n/// will be interpreted as a statement instead of an expression.\n///\n/// See #8724, #13470\nfn needs_parenthesis(cx: &LateContext<'_>, binary: &Expr<'_>, child: &Expr<'_>) -> Parens {\n    match child.kind {\n        ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) => {\n            // For casts and binary expressions, we want to add parenthesis if\n            // the parent HIR node is an expression, or if the parent HIR node\n            // is a Block or Stmt, and the new left hand side would need\n            // parenthesis be treated as a statement rather than an expression.\n            if let Some((_, parent)) = cx.tcx.hir_parent_iter(binary.hir_id).next() {\n                match parent {\n                    Node::Expr(_) => return Parens::Needed,\n                    Node::Block(_) | Node::Stmt(_) => {\n                        // ensure we're checking against the leftmost expression of `child`\n                        //\n                        // ~~~~~~~~~~~ `binary`\n                        //     ~~~ `lhs`\n                        // 0 + {4} * 2\n                        //     ~~~~~~~ `child`\n                        return needs_parenthesis(cx, binary, lhs);\n                    },\n                    _ => return Parens::Unneeded,\n                }\n            }\n        },\n        ExprKind::If(..) | ExprKind::Match(..) | ExprKind::Block(..) | ExprKind::Loop(..) => {\n            // For if, match, block, and loop expressions, we want to add parenthesis if\n            // the closest ancestor node that is not an expression is a block or statement.\n            // This would mean that the rustfix suggestion will appear at the start of a line, which causes\n            // these expressions to be interpreted as statements if they do not have parenthesis.\n            let mut prev_id = binary.hir_id;\n            for (_, parent) in cx.tcx.hir_parent_iter(binary.hir_id) {\n                if let Node::Expr(expr) = parent\n                    && let ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) | ExprKind::Unary(_, lhs) = expr.kind\n                    && lhs.hir_id == prev_id\n                {\n                    // keep going until we find a node that encompasses left of `binary`\n                    prev_id = expr.hir_id;\n                    continue;\n                }\n\n                match parent {\n                    Node::Block(_) | Node::Stmt(_) => return Parens::Needed,\n                    _ => return Parens::Unneeded,\n                };\n            }\n        },\n        _ => {\n            return Parens::Unneeded;\n        },\n    }\n    Parens::Needed\n}\n\nfn is_allowed<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    cmp: BinOpKind,\n    left: &Expr<'tcx>,\n    right: &Expr<'tcx>,\n) -> bool {\n    // Exclude case where the left or right side is associated function call returns a type which is\n    // `Self` that is not given explicitly, and the expression is not a let binding's init\n    // expression and the let binding has a type annotation, or a function's return value.\n    if (is_assoc_fn_without_type_instance(cx, left) || is_assoc_fn_without_type_instance(cx, right))\n        && !is_expr_used_with_type_annotation(cx, expr)\n    {\n        return false;\n    }\n\n    // This lint applies to integers and their references\n    cx.typeck_results().expr_ty(left).peel_refs().is_integral()\n    && cx.typeck_results().expr_ty(right).peel_refs().is_integral()\n        // `1 << 0` is a common pattern in bit manipulation code\n        && !(cmp == BinOpKind::Shl\n            && is_zero_integer_const(cx, right, expr.span.ctxt())\n            && integer_const(cx, left, expr.span.ctxt()) == Some(1))\n}\n\nfn check_remainder(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>, span: Span, arg: Span) {\n    let ecx = ConstEvalCtxt::new(cx);\n    let ctxt = span.ctxt();\n    if match (ecx.eval_full_int(left, ctxt), ecx.eval_full_int(right, ctxt)) {\n        (Some(FullInt::S(lv)), Some(FullInt::S(rv))) => lv.abs() < rv.abs(),\n        (Some(FullInt::U(lv)), Some(FullInt::U(rv))) => lv < rv,\n        _ => return,\n    } {\n        span_ineffective_operation(cx, span, arg, Parens::Unneeded, false);\n    }\n}\n\nfn is_redundant_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, ctxt: SyntaxContext) -> bool {\n    if let Some(Constant::Int(v)) = ConstEvalCtxt::new(cx).eval_local(e, ctxt).map(Constant::peel_refs) {\n        let check = match *cx.typeck_results().expr_ty(e).peel_refs().kind() {\n            ty::Int(ity) => unsext(cx.tcx, -1_i128, ity),\n            ty::Uint(uty) => clip(cx.tcx, !0, uty),\n            _ => return false,\n        };\n        if match m {\n            0 => v == 0,\n            -1 => v == check,\n            1 => v == 1,\n            _ => unreachable!(),\n        } {\n            return true;\n        }\n    }\n    false\n}\n\nfn span_ineffective_operation(\n    cx: &LateContext<'_>,\n    span: Span,\n    arg: Span,\n    parens: Parens,\n    is_ref_coerced_to_val: bool,\n) {\n    let mut applicability = Applicability::MachineApplicable;\n    let expr_snippet = snippet_with_applicability(cx, arg, \"..\", &mut applicability);\n    let expr_snippet = if is_ref_coerced_to_val {\n        format!(\"*{expr_snippet}\")\n    } else {\n        expr_snippet.into_owned()\n    };\n    let suggestion = match parens {\n        Parens::Needed => format!(\"({expr_snippet})\"),\n        Parens::Unneeded => expr_snippet,\n    };\n\n    span_lint_and_sugg(\n        cx,\n        IDENTITY_OP,\n        span,\n        \"this operation has no effect\",\n        \"consider reducing it to\",\n        suggestion,\n        applicability,\n    );\n}\n\nfn is_expr_used_with_type_annotation<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {\n    match expr_use_ctxt(cx, expr).use_node(cx) {\n        ExprUseNode::LetStmt(letstmt) => letstmt.ty.is_some(),\n        ExprUseNode::Return(_) => true,\n        _ => false,\n    }\n}\n\n/// Check if the expression is an associated function without a type instance.\n/// Example:\n/// ```\n/// trait Def {\n///     fn def() -> Self;\n/// }\n/// impl Def for usize {\n///     fn def() -> Self {\n///         0\n///     }\n/// }\n/// fn test() {\n///     let _ = 0usize + &Default::default();\n///     let _ = 0usize + &Def::def();\n/// }\n/// ```\nfn is_assoc_fn_without_type_instance<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {\n    if let ExprKind::Call(func, _) = peel_hir_expr_refs(expr).0.kind\n        && let ExprKind::Path(QPath::Resolved(\n            // If it's not None, don't need to go further.\n            None,\n            Path {\n                res: Res::Def(DefKind::AssocFn, def_id),\n                ..\n            },\n        )) = func.kind\n        && let output_ty = cx.tcx.fn_sig(*def_id).instantiate_identity().skip_binder().output()\n        && let ty::Param(ty::ParamTy {\n            name: kw::SelfUpper, ..\n        }) = output_ty.kind()\n    {\n        return true;\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/integer_division.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::sym;\n\nuse super::INTEGER_DIVISION;\n\npub(crate) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    op: hir::BinOpKind,\n    left: &'tcx hir::Expr<'_>,\n    right: &'tcx hir::Expr<'_>,\n) {\n    if op == hir::BinOpKind::Div\n        && cx.typeck_results().expr_ty(left).is_integral()\n        && let right_ty = cx.typeck_results().expr_ty(right)\n        && (right_ty.is_integral() || right_ty.is_diag_item(cx, sym::NonZero))\n    {\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(cx, INTEGER_DIVISION, expr.span, \"integer division\", |diag| {\n            diag.help(\"division of integers may cause loss of precision. consider using floats\");\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/integer_division_remainder_used.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_ast::BinOpKind;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_span::Span;\n\nuse super::INTEGER_DIVISION_REMAINDER_USED;\n\npub(super) fn check(cx: &LateContext<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>, span: Span) {\n    if let BinOpKind::Div | BinOpKind::Rem = op\n        && let lhs_ty = cx.typeck_results().expr_ty(lhs)\n        && let rhs_ty = cx.typeck_results().expr_ty(rhs)\n        && let ty::Int(_) | ty::Uint(_) = lhs_ty.peel_refs().kind()\n        && let ty::Int(_) | ty::Uint(_) = rhs_ty.peel_refs().kind()\n    {\n        span_lint(\n            cx,\n            INTEGER_DIVISION_REMAINDER_USED,\n            span.source_callsite(),\n            format!(\"use of `{}` has been disallowed in this context\", op.as_str()),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/invalid_upcast_comparisons.rs",
    "content": "use rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_middle::ty::{self, IntTy, UintTy};\nuse rustc_span::Span;\n\nuse clippy_utils::comparisons;\nuse clippy_utils::comparisons::Rel;\nuse clippy_utils::consts::{ConstEvalCtxt, FullInt};\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::source::snippet_with_context;\n\nuse super::INVALID_UPCAST_COMPARISONS;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    cmp: BinOpKind,\n    lhs: &'tcx Expr<'_>,\n    rhs: &'tcx Expr<'_>,\n    span: Span,\n) {\n    let normalized = comparisons::normalize_comparison(cmp, lhs, rhs);\n    let Some((rel, normalized_lhs, normalized_rhs)) = normalized else {\n        return;\n    };\n\n    let lhs_bounds = numeric_cast_precast_bounds(cx, normalized_lhs);\n    let rhs_bounds = numeric_cast_precast_bounds(cx, normalized_rhs);\n\n    upcast_comparison_bounds_err(cx, span, rel, lhs_bounds, normalized_lhs, normalized_rhs, false);\n    upcast_comparison_bounds_err(cx, span, rel, rhs_bounds, normalized_rhs, normalized_lhs, true);\n}\n\nfn numeric_cast_precast_bounds(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(FullInt, FullInt)> {\n    if let ExprKind::Cast(cast_exp, _) = expr.kind {\n        let pre_cast_ty = cx.typeck_results().expr_ty(cast_exp);\n        let cast_ty = cx.typeck_results().expr_ty(expr);\n        // if it's a cast from i32 to u32 wrapping will invalidate all these checks\n        if cx.layout_of(pre_cast_ty).ok().map(|l| l.size) == cx.layout_of(cast_ty).ok().map(|l| l.size) {\n            return None;\n        }\n        match pre_cast_ty.kind() {\n            ty::Int(int_ty) => Some(match int_ty {\n                IntTy::I8 => (FullInt::S(i128::from(i8::MIN)), FullInt::S(i128::from(i8::MAX))),\n                IntTy::I16 => (FullInt::S(i128::from(i16::MIN)), FullInt::S(i128::from(i16::MAX))),\n                IntTy::I32 => (FullInt::S(i128::from(i32::MIN)), FullInt::S(i128::from(i32::MAX))),\n                IntTy::I64 => (FullInt::S(i128::from(i64::MIN)), FullInt::S(i128::from(i64::MAX))),\n                IntTy::I128 => (FullInt::S(i128::MIN), FullInt::S(i128::MAX)),\n                IntTy::Isize => (FullInt::S(isize::MIN as i128), FullInt::S(isize::MAX as i128)),\n            }),\n            ty::Uint(uint_ty) => Some(match uint_ty {\n                UintTy::U8 => (FullInt::U(u128::from(u8::MIN)), FullInt::U(u128::from(u8::MAX))),\n                UintTy::U16 => (FullInt::U(u128::from(u16::MIN)), FullInt::U(u128::from(u16::MAX))),\n                UintTy::U32 => (FullInt::U(u128::from(u32::MIN)), FullInt::U(u128::from(u32::MAX))),\n                UintTy::U64 => (FullInt::U(u128::from(u64::MIN)), FullInt::U(u128::from(u64::MAX))),\n                UintTy::U128 => (FullInt::U(u128::MIN), FullInt::U(u128::MAX)),\n                UintTy::Usize => (FullInt::U(usize::MIN as u128), FullInt::U(usize::MAX as u128)),\n            }),\n            _ => None,\n        }\n    } else {\n        None\n    }\n}\n\nfn upcast_comparison_bounds_err<'tcx>(\n    cx: &LateContext<'tcx>,\n    span: Span,\n    rel: Rel,\n    lhs_bounds: Option<(FullInt, FullInt)>,\n    lhs: &'tcx Expr<'_>,\n    rhs: &'tcx Expr<'_>,\n    invert: bool,\n) {\n    if let Some((lb, ub)) = lhs_bounds\n        && let Some(norm_rhs_val) = ConstEvalCtxt::new(cx).eval_full_int(rhs, span.ctxt())\n    {\n        match rel {\n            Rel::Eq => {\n                if norm_rhs_val < lb || ub < norm_rhs_val {\n                    err_upcast_comparison(cx, span, lhs, false);\n                }\n            },\n            Rel::Ne => {\n                if norm_rhs_val < lb || ub < norm_rhs_val {\n                    err_upcast_comparison(cx, span, lhs, true);\n                }\n            },\n            Rel::Lt => {\n                if (invert && norm_rhs_val < lb) || (!invert && ub < norm_rhs_val) {\n                    err_upcast_comparison(cx, span, lhs, true);\n                } else if (!invert && norm_rhs_val <= lb) || (invert && ub <= norm_rhs_val) {\n                    err_upcast_comparison(cx, span, lhs, false);\n                }\n            },\n            Rel::Le => {\n                if (invert && norm_rhs_val <= lb) || (!invert && ub <= norm_rhs_val) {\n                    err_upcast_comparison(cx, span, lhs, true);\n                } else if (!invert && norm_rhs_val < lb) || (invert && ub < norm_rhs_val) {\n                    err_upcast_comparison(cx, span, lhs, false);\n                }\n            },\n        }\n    }\n}\n\nfn err_upcast_comparison(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, always: bool) {\n    if let ExprKind::Cast(cast_val, _) = expr.kind {\n        let mut applicability = Applicability::MachineApplicable;\n        let (cast_val_snip, _) = snippet_with_context(\n            cx,\n            cast_val.span,\n            expr.span.ctxt(),\n            \"the expression\",\n            &mut applicability,\n        );\n        span_lint(\n            cx,\n            INVALID_UPCAST_COMPARISONS,\n            span,\n            format!(\n                \"because of the numeric bounds on `{}` prior to casting, this expression is always {}\",\n                cast_val_snip,\n                if always { \"true\" } else { \"false\" },\n            ),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/manual_div_ceil.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::sugg::{Sugg, has_enclosing_paren};\nuse clippy_utils::{SpanlessEq, sym};\nuse rustc_ast::{BinOpKind, LitIntType, LitKind, UnOp};\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::source_map::Spanned;\n\nuse super::MANUAL_DIV_CEIL;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>, msrv: Msrv) {\n    let mut applicability = Applicability::MachineApplicable;\n\n    if op == BinOpKind::Div\n        && check_int_ty_and_feature(cx, cx.typeck_results().expr_ty(lhs))\n        && check_int_ty_and_feature(cx, cx.typeck_results().expr_ty(rhs))\n        && msrv.meets(cx, msrvs::DIV_CEIL)\n    {\n        match lhs.kind {\n            ExprKind::Binary(inner_op, inner_lhs, inner_rhs) => {\n                // (x + (y - 1)) / y\n                if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind\n                    && inner_op.node == BinOpKind::Add\n                    && sub_op.node == BinOpKind::Sub\n                    && check_literal(sub_rhs)\n                    && check_eq_expr(cx, sub_lhs, rhs)\n                {\n                    build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability);\n                    return;\n                }\n\n                // ((y - 1) + x) / y\n                if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_lhs.kind\n                    && inner_op.node == BinOpKind::Add\n                    && sub_op.node == BinOpKind::Sub\n                    && check_literal(sub_rhs)\n                    && check_eq_expr(cx, sub_lhs, rhs)\n                {\n                    build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability);\n                    return;\n                }\n\n                // (x + y - 1) / y\n                if let ExprKind::Binary(add_op, add_lhs, add_rhs) = inner_lhs.kind\n                    && inner_op.node == BinOpKind::Sub\n                    && add_op.node == BinOpKind::Add\n                    && check_literal(inner_rhs)\n                    && check_eq_expr(cx, add_rhs, rhs)\n                {\n                    build_suggestion(cx, expr, add_lhs, rhs, &mut applicability);\n                }\n\n                // (x + (Y - 1)) / Y\n                if inner_op.node == BinOpKind::Add && differ_by_one(inner_rhs, rhs) {\n                    build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability);\n                }\n\n                // ((Y - 1) + x) / Y\n                if inner_op.node == BinOpKind::Add && differ_by_one(inner_lhs, rhs) {\n                    build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability);\n                }\n\n                // (x - (-Y - 1)) / Y\n                if inner_op.node == BinOpKind::Sub\n                    && let ExprKind::Unary(UnOp::Neg, abs_div_rhs) = rhs.kind\n                    && differ_by_one(abs_div_rhs, inner_rhs)\n                {\n                    build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability);\n                }\n            },\n            ExprKind::MethodCall(method, receiver, [next_multiple_of_arg], _)\n                if method.ident.name == sym::next_multiple_of\n                    && check_int_ty(cx.typeck_results().expr_ty(receiver))\n                    && check_eq_expr(cx, next_multiple_of_arg, rhs) =>\n            {\n                // x.next_multiple_of(Y) / Y\n                build_suggestion(cx, expr, receiver, rhs, &mut applicability);\n            },\n            ExprKind::Call(callee, [receiver, next_multiple_of_arg]) => {\n                // int_type::next_multiple_of(x, Y) / Y\n                if let Some(impl_ty_binder) = callee\n                    .ty_rel_def_if_named(cx, sym::next_multiple_of)\n                    .assoc_fn_parent(cx)\n                    .opt_impl_ty(cx)\n                    && check_int_ty(impl_ty_binder.skip_binder())\n                    && check_eq_expr(cx, next_multiple_of_arg, rhs)\n                {\n                    build_suggestion(cx, expr, receiver, rhs, &mut applicability);\n                }\n            },\n            _ => (),\n        }\n    }\n}\n\n/// Checks if two expressions represent non-zero integer literals such that `small_expr + 1 ==\n/// large_expr`.\nfn differ_by_one(small_expr: &Expr<'_>, large_expr: &Expr<'_>) -> bool {\n    if let ExprKind::Lit(small) = small_expr.kind\n        && let ExprKind::Lit(large) = large_expr.kind\n        && let LitKind::Int(s, _) = small.node\n        && let LitKind::Int(l, _) = large.node\n    {\n        Some(l.get()) == s.get().checked_add(1)\n    } else if let ExprKind::Unary(UnOp::Neg, small_inner_expr) = small_expr.kind\n        && let ExprKind::Unary(UnOp::Neg, large_inner_expr) = large_expr.kind\n    {\n        differ_by_one(large_inner_expr, small_inner_expr)\n    } else {\n        false\n    }\n}\n\nfn check_int_ty(expr_ty: Ty<'_>) -> bool {\n    matches!(expr_ty.peel_refs().kind(), ty::Int(_) | ty::Uint(_))\n}\n\nfn check_int_ty_and_feature(cx: &LateContext<'_>, expr_ty: Ty<'_>) -> bool {\n    match expr_ty.peel_refs().kind() {\n        ty::Uint(_) => true,\n        ty::Int(_) => cx.tcx.features().enabled(sym::int_roundings),\n        _ => false,\n    }\n}\n\nfn check_literal(expr: &Expr<'_>) -> bool {\n    if let ExprKind::Lit(lit) = expr.kind\n        && let LitKind::Int(Pu128(1), _) = lit.node\n    {\n        return true;\n    }\n    false\n}\n\nfn check_eq_expr(cx: &LateContext<'_>, lhs: &Expr<'_>, rhs: &Expr<'_>) -> bool {\n    SpanlessEq::new(cx).eq_expr(lhs, rhs)\n}\n\nfn build_suggestion(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    lhs: &Expr<'_>,\n    rhs: &Expr<'_>,\n    applicability: &mut Applicability,\n) {\n    let dividend_sugg = Sugg::hir_with_applicability(cx, lhs, \"..\", applicability).maybe_paren();\n    let rhs_ty = cx.typeck_results().expr_ty(rhs);\n    let type_suffix = if cx.typeck_results().expr_ty(lhs).is_numeric()\n        && matches!(\n            lhs.kind,\n            ExprKind::Lit(Spanned {\n                node: LitKind::Int(_, LitIntType::Unsuffixed),\n                ..\n            }) | ExprKind::Unary(\n                UnOp::Neg,\n                Expr {\n                    kind: ExprKind::Lit(Spanned {\n                        node: LitKind::Int(_, LitIntType::Unsuffixed),\n                        ..\n                    }),\n                    ..\n                }\n            )\n        ) {\n        format!(\"_{rhs_ty}\")\n    } else {\n        String::new()\n    };\n    let dividend_sugg_str = dividend_sugg.into_string();\n    // If `dividend_sugg` has enclosing paren like `(-2048)` and we need to add type suffix in the\n    // suggestion message, we want to make a suggestion string before `div_ceil` like\n    // `(-2048_{type_suffix})`.\n    let suggestion_before_div_ceil = if has_enclosing_paren(&dividend_sugg_str) {\n        format!(\n            \"{}{})\",\n            &dividend_sugg_str[..dividend_sugg_str.len() - 1].to_string(),\n            type_suffix\n        )\n    } else {\n        format!(\"{dividend_sugg_str}{type_suffix}\")\n    };\n\n    // Dereference the RHS if it is a reference type\n    let divisor_snippet = match Sugg::hir_with_context(cx, rhs, expr.span.ctxt(), \"_\", applicability) {\n        sugg if rhs_ty.is_ref() => sugg.deref(),\n        sugg => sugg,\n    };\n\n    span_lint_and_sugg(\n        cx,\n        MANUAL_DIV_CEIL,\n        expr.span,\n        \"manually reimplementing `div_ceil`\",\n        \"consider using `.div_ceil()`\",\n        format!(\"{suggestion_before_div_ceil}.div_ceil({divisor_snippet})\"),\n        *applicability,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/manual_is_multiple_of.rs",
    "content": "use clippy_utils::consts::is_zero_integer_const;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::expr_type_is_certain;\nuse rustc_ast::BinOpKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::MANUAL_IS_MULTIPLE_OF;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    op: BinOpKind,\n    lhs: &'tcx Expr<'tcx>,\n    rhs: &'tcx Expr<'tcx>,\n    msrv: Msrv,\n) {\n    if msrv.meets(cx, msrvs::UNSIGNED_IS_MULTIPLE_OF)\n        && let Some(operand) = uint_compare_to_zero(cx, expr, op, lhs, rhs)\n        && let ExprKind::Binary(operand_op, operand_left, operand_right) = operand.kind\n        && operand_op.node == BinOpKind::Rem\n        && matches!(\n            cx.typeck_results().expr_ty_adjusted(operand_left).peel_refs().kind(),\n            ty::Uint(_)\n        )\n        && matches!(\n            cx.typeck_results().expr_ty_adjusted(operand_right).peel_refs().kind(),\n            ty::Uint(_)\n        )\n        && expr_type_is_certain(cx, operand_left)\n    {\n        let mut app = Applicability::MachineApplicable;\n        let divisor = deref_sugg(\n            Sugg::hir_with_context(cx, operand_right, expr.span.ctxt(), \"_\", &mut app),\n            cx.typeck_results().expr_ty_adjusted(operand_right),\n        );\n        span_lint_and_sugg(\n            cx,\n            MANUAL_IS_MULTIPLE_OF,\n            expr.span,\n            \"manual implementation of `.is_multiple_of()`\",\n            \"replace with\",\n            format!(\n                \"{}{}.is_multiple_of({divisor})\",\n                if op == BinOpKind::Eq { \"\" } else { \"!\" },\n                Sugg::hir_with_context(cx, operand_left, expr.span.ctxt(), \"_\", &mut app).maybe_paren()\n            ),\n            app,\n        );\n    }\n}\n\n// If we have a `x == 0`, `x != 0` or `x > 0` (or the reverted ones), return the non-zero operand\nfn uint_compare_to_zero<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'tcx>,\n    op: BinOpKind,\n    lhs: &'tcx Expr<'tcx>,\n    rhs: &'tcx Expr<'tcx>,\n) -> Option<&'tcx Expr<'tcx>> {\n    let operand = if matches!(lhs.kind, ExprKind::Binary(..))\n        && matches!(op, BinOpKind::Eq | BinOpKind::Ne | BinOpKind::Gt)\n        && is_zero_integer_const(cx, rhs, e.span.ctxt())\n    {\n        lhs\n    } else if matches!(rhs.kind, ExprKind::Binary(..))\n        && matches!(op, BinOpKind::Eq | BinOpKind::Ne | BinOpKind::Lt)\n        && is_zero_integer_const(cx, lhs, e.span.ctxt())\n    {\n        rhs\n    } else {\n        return None;\n    };\n\n    matches!(cx.typeck_results().expr_ty_adjusted(operand).kind(), ty::Uint(_)).then_some(operand)\n}\n\nfn deref_sugg<'a>(sugg: Sugg<'a>, ty: Ty<'_>) -> Sugg<'a> {\n    if let ty::Ref(_, target_ty, _) = ty.kind() {\n        deref_sugg(sugg.deref(), *target_ty)\n    } else {\n        sugg\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/manual_midpoint.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{is_float_literal, is_integer_literal};\nuse rustc_ast::BinOpKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::MANUAL_MIDPOINT;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n    msrv: Msrv,\n) {\n    if !left.span.from_expansion()\n        && !right.span.from_expansion()\n        && op == BinOpKind::Div\n        && (is_integer_literal(right, 2) || is_float_literal(right, 2.0))\n        && let Some((ll_expr, lr_expr)) = add_operands(left)\n        && add_operands(ll_expr).is_none() && add_operands(lr_expr).is_none()\n        && let left_ty = cx.typeck_results().expr_ty_adjusted(ll_expr)\n        && let right_ty = cx.typeck_results().expr_ty_adjusted(lr_expr)\n        && left_ty == right_ty\n        // Do not lint on `(_+1)/2` and `(1+_)/2`, it is likely a `div_ceil()` operation\n        && !is_integer_literal(ll_expr, 1) && !is_integer_literal(lr_expr, 1)\n        && is_midpoint_implemented(cx, left_ty, msrv)\n    {\n        let mut app = Applicability::MachineApplicable;\n        let left_sugg = Sugg::hir_with_context(cx, ll_expr, expr.span.ctxt(), \"..\", &mut app);\n        let right_sugg = Sugg::hir_with_context(cx, lr_expr, expr.span.ctxt(), \"..\", &mut app);\n        let sugg = format!(\"{left_ty}::midpoint({left_sugg}, {right_sugg})\");\n        span_lint_and_sugg(\n            cx,\n            MANUAL_MIDPOINT,\n            expr.span,\n            \"manual implementation of `midpoint` which can overflow\",\n            format!(\"use `{left_ty}::midpoint` instead\"),\n            sugg,\n            app,\n        );\n    }\n}\n\n/// Return the left and right operands if `expr` represents an addition\nfn add_operands<'e, 'tcx>(expr: &'e Expr<'tcx>) -> Option<(&'e Expr<'tcx>, &'e Expr<'tcx>)> {\n    match expr.kind {\n        ExprKind::Binary(op, left, right) if op.node == BinOpKind::Add => Some((left, right)),\n        _ => None,\n    }\n}\n\nfn is_midpoint_implemented(cx: &LateContext<'_>, ty: Ty<'_>, msrv: Msrv) -> bool {\n    match ty.kind() {\n        ty::Uint(_) | ty::Float(_) => msrv.meets(cx, msrvs::UINT_FLOAT_MIDPOINT),\n        ty::Int(_) => msrv.meets(cx, msrvs::INT_MIDPOINT),\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/misrefactored_assign_op.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{eq_expr_value, sugg};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\n\nuse super::MISREFACTORED_ASSIGN_OP;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'_>,\n    op: hir::BinOpKind,\n    lhs: &'tcx hir::Expr<'_>,\n    rhs: &'tcx hir::Expr<'_>,\n) {\n    if let hir::ExprKind::Binary(binop, l, r) = &rhs.kind {\n        if op != binop.node {\n            return;\n        }\n        // lhs op= l op r\n        if eq_expr_value(cx, lhs, l) {\n            lint_misrefactored_assign_op(cx, expr, op, rhs, lhs, r);\n        } else if is_commutative(op) && eq_expr_value(cx, lhs, r) {\n            // lhs op= l commutative_op r\n            lint_misrefactored_assign_op(cx, expr, op, rhs, lhs, l);\n        }\n    }\n}\n\nfn lint_misrefactored_assign_op(\n    cx: &LateContext<'_>,\n    expr: &hir::Expr<'_>,\n    op: hir::BinOpKind,\n    rhs: &hir::Expr<'_>,\n    assignee: &hir::Expr<'_>,\n    rhs_other: &hir::Expr<'_>,\n) {\n    span_lint_and_then(\n        cx,\n        MISREFACTORED_ASSIGN_OP,\n        expr.span,\n        \"variable appears on both sides of an assignment operation\",\n        |diag| {\n            if let Some(snip_a) = assignee.span.get_source_text(cx)\n                && let Some(snip_r) = rhs_other.span.get_source_text(cx)\n            {\n                let a = &sugg::Sugg::hir(cx, assignee, \"..\");\n                let r = &sugg::Sugg::hir(cx, rhs, \"..\");\n                let long = format!(\"{snip_a} = {}\", sugg::make_binop(op, a, r));\n                diag.span_suggestion(\n                    expr.span,\n                    format!(\n                        \"did you mean `{snip_a} = {snip_a} {} {snip_r}` or `{long}`? Consider replacing it with\",\n                        op.as_str()\n                    ),\n                    format!(\"{snip_a} {}= {snip_r}\", op.as_str()),\n                    Applicability::MaybeIncorrect,\n                );\n                diag.span_suggestion(\n                    expr.span,\n                    \"or\",\n                    long,\n                    Applicability::MaybeIncorrect, // snippet\n                );\n            }\n        },\n    );\n}\n\n#[must_use]\nfn is_commutative(op: hir::BinOpKind) -> bool {\n    use rustc_hir::BinOpKind::{\n        Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub,\n    };\n    match op {\n        Add | Mul | And | Or | BitXor | BitAnd | BitOr | Eq | Ne => true,\n        Sub | Div | Rem | Shl | Shr | Lt | Le | Ge | Gt => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/mod.rs",
    "content": "mod absurd_extreme_comparisons;\nmod assign_op_pattern;\nmod bit_mask;\nmod cmp_owned;\nmod const_comparisons;\nmod decimal_bitwise_operands;\nmod double_comparison;\nmod duration_subsec;\nmod eq_op;\nmod erasing_op;\nmod float_cmp;\nmod float_equality_without_abs;\nmod identity_op;\nmod integer_division;\nmod integer_division_remainder_used;\nmod invalid_upcast_comparisons;\nmod manual_div_ceil;\nmod manual_is_multiple_of;\nmod manual_midpoint;\nmod misrefactored_assign_op;\nmod modulo_arithmetic;\nmod modulo_one;\nmod needless_bitwise_bool;\nmod numeric_arithmetic;\nmod op_ref;\nmod self_assignment;\nmod verbose_bit_mask;\n\npub(crate) mod arithmetic_side_effects;\n\nuse clippy_config::Conf;\nuse clippy_utils::msrvs::Msrv;\nuse rustc_hir::{Body, Expr, ExprKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for comparisons where one side of the relation is\n    /// either the minimum or maximum value for its type and warns if it involves a\n    /// case that is always true or always false. Only integer and boolean types are\n    /// checked.\n    ///\n    /// ### Why is this bad?\n    /// An expression like `min <= x` may misleadingly imply\n    /// that it is possible for `x` to be less than the minimum. Expressions like\n    /// `max < x` are probably mistakes.\n    ///\n    /// ### Known problems\n    /// For `usize` the size of the current compile target will\n    /// be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such\n    /// a comparison to detect target pointer width will trigger this lint. One can\n    /// use `mem::sizeof` and compare its value or conditional compilation\n    /// attributes\n    /// like `#[cfg(target_pointer_width = \"64\")] ..` instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let vec: Vec<isize> = Vec::new();\n    /// if vec.len() <= 0 {}\n    /// if 100 > i32::MAX {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ABSURD_EXTREME_COMPARISONS,\n    correctness,\n    \"a comparison with a maximum or minimum value that is always true or false\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks any kind of arithmetic operation of any type.\n    ///\n    /// Operators like `+`, `-`, `*` or `<<` are usually capable of overflowing according to the [Rust\n    /// Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),\n    /// or can panic (`/`, `%`).\n    ///\n    /// Known safe built-in types like `Wrapping` or `Saturating`, floats, operations in constant\n    /// environments, allowed types and non-constant operations that won't overflow are ignored.\n    ///\n    /// ### Why restrict this?\n    /// For integers, overflow will trigger a panic in debug builds or wrap the result in\n    /// release mode; division by zero will cause a panic in either mode. As a result, it is\n    /// desirable to explicitly call checked, wrapping or saturating arithmetic methods.\n    ///\n    /// #### Example\n    /// ```no_run\n    /// // `n` can be any number, including `i32::MAX`.\n    /// fn foo(n: i32) -> i32 {\n    ///     n + 1\n    /// }\n    /// ```\n    ///\n    /// Third-party types can also overflow or present unwanted side-effects.\n    ///\n    /// #### Example\n    /// ```ignore,rust\n    /// use rust_decimal::Decimal;\n    /// let _n = Decimal::MAX + Decimal::MAX;\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub ARITHMETIC_SIDE_EFFECTS,\n    restriction,\n    \"any arithmetic expression that can cause side effects like overflows or panics\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `a = a op b` or `a = b commutative_op a`\n    /// patterns.\n    ///\n    /// ### Why is this bad?\n    /// These can be written as the shorter `a op= b`.\n    ///\n    /// ### Known problems\n    /// While forbidden by the spec, `OpAssign` traits may have\n    /// implementations that differ from the regular `Op` impl.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut a = 5;\n    /// let b = 0;\n    /// // ...\n    ///\n    /// a = a + b;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let mut a = 5;\n    /// let b = 0;\n    /// // ...\n    ///\n    /// a += b;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ASSIGN_OP_PATTERN,\n    style,\n    \"assigning the result of an operation on a variable to that same variable\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for incompatible bit masks in comparisons.\n    ///\n    /// The formula for detecting if an expression of the type `_ <bit_op> m\n    /// <cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of\n    /// {`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following\n    /// table:\n    ///\n    /// |Comparison  |Bit Op|Example      |is always|Formula               |\n    /// |------------|------|-------------|---------|----------------------|\n    /// |`==` or `!=`| `&`  |`x & 2 == 3` |`false`  |`c & m != c`          |\n    /// |`<`  or `>=`| `&`  |`x & 2 < 3`  |`true`   |`m < c`               |\n    /// |`>`  or `<=`| `&`  |`x & 1 > 1`  |`false`  |`m <= c`              |\n    /// |`==` or `!=`| `\\|` |`x \\| 1 == 0`|`false`  |`c \\| m != c`         |\n    /// |`<`  or `>=`| `\\|` |`x \\| 1 < 1` |`false`  |`m >= c`              |\n    /// |`<=` or `>` | `\\|` |`x \\| 1 > 0` |`true`   |`m > c`               |\n    ///\n    /// ### Why is this bad?\n    /// If the bits that the comparison cares about are always\n    /// set to zero or one by the bit mask, the comparison is constant `true` or\n    /// `false` (depending on mask, compared value, and operators).\n    ///\n    /// So the code is actively misleading, and the only reason someone would write\n    /// this intentionally is to win an underhanded Rust contest or create a\n    /// test-case for this lint.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// if (x & 1 == 2) { }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub BAD_BIT_MASK,\n    correctness,\n    \"expressions of the form `_ & mask == select` that will only ever return `true` or `false`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for conversions to owned values just for the sake\n    /// of a comparison.\n    ///\n    /// ### Why is this bad?\n    /// The comparison can operate on a reference, so creating\n    /// an owned value effectively throws it away directly afterwards, which is\n    /// needlessly consuming code and heap space.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = \"foo\";\n    /// # let y = String::from(\"foo\");\n    /// if x.to_owned() == y {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = \"foo\";\n    /// # let y = String::from(\"foo\");\n    /// if x == y {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CMP_OWNED,\n    perf,\n    \"creating owned instances for comparing with others, e.g., `x == \\\"foo\\\".to_string()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for decimal literals used as bit masks in bitwise operations.\n    ///\n    /// ### Why is this bad?\n    /// Using decimal literals for bit masks can make the code less readable and obscure the intended bit pattern.\n    /// Binary, hexadecimal, or octal literals make the bit pattern more explicit and easier to understand at a glance.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// let a = 14 & 6; // Bit pattern is not immediately clear\n    /// ```\n    /// Use instead:\n    /// ```rust,no_run\n    /// let a = 0b1110 & 0b0110;\n    /// ```\n    #[clippy::version = \"1.94.0\"]\n    pub DECIMAL_BITWISE_OPERANDS,\n    pedantic,\n    \"use binary, hex, or octal literals for bitwise operations\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for double comparisons that could be simplified to a single expression.\n    ///\n    ///\n    /// ### Why is this bad?\n    /// Readability.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// # let y = 2;\n    /// if x == y || x < y {}\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```no_run\n    /// # let x = 1;\n    /// # let y = 2;\n    /// if x <= y {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DOUBLE_COMPARISONS,\n    complexity,\n    \"unnecessary double comparisons that can be simplified\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calculation of subsecond microseconds or milliseconds\n    /// from other `Duration` methods.\n    ///\n    /// ### Why is this bad?\n    /// It's more concise to call `Duration::subsec_micros()` or\n    /// `Duration::subsec_millis()` than to calculate them.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::time::Duration;\n    /// # let duration = Duration::new(5, 0);\n    /// let micros = duration.subsec_nanos() / 1_000;\n    /// let millis = duration.subsec_nanos() / 1_000_000;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::time::Duration;\n    /// # let duration = Duration::new(5, 0);\n    /// let micros = duration.subsec_micros();\n    /// let millis = duration.subsec_millis();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DURATION_SUBSEC,\n    complexity,\n    \"checks for calculation of subsecond microseconds or milliseconds\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for equal operands to comparison, logical and\n    /// bitwise, difference and division binary operators (`==`, `>`, etc., `&&`,\n    /// `||`, `&`, `|`, `^`, `-` and `/`).\n    ///\n    /// ### Why is this bad?\n    /// This is usually just a typo or a copy and paste error.\n    ///\n    /// ### Known problems\n    /// False negatives: We had some false positives regarding\n    /// calls (notably [racer](https://github.com/phildawes/racer) had one instance\n    /// of `x.pop() && x.pop()`), so we removed matching any function or method\n    /// calls. We may introduce a list of known pure functions in the future.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// if x + 1 == x + 1 {}\n    ///\n    /// // or\n    ///\n    /// # let a = 3;\n    /// # let b = 4;\n    /// assert_eq!(a, a);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub EQ_OP,\n    correctness,\n    \"equal operands on both sides of a comparison or bitwise combination (e.g., `x == x`)\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for erasing operations, e.g., `x * 0`.\n    ///\n    /// ### Why is this bad?\n    /// The whole expression can be replaced by zero.\n    /// This is most likely not the intended outcome and should probably be\n    /// corrected\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 1;\n    /// 0 / x;\n    /// 0 * x;\n    /// x & 0;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ERASING_OP,\n    correctness,\n    \"using erasing operations, e.g., `x * 0` or `y & 0`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for float arithmetic.\n    ///\n    /// ### Why restrict this?\n    /// For some embedded systems or kernel development, it\n    /// can be useful to rule out floating-point numbers.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let a = 0.0;\n    /// a + 1.0;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub FLOAT_ARITHMETIC,\n    restriction,\n    \"any floating-point arithmetic statement\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for (in-)equality comparisons on floating-point\n    /// values (apart from zero), except in functions called `*eq*` (which probably\n    /// implement equality for a type involving floats).\n    ///\n    /// ### Why is this bad?\n    /// Floating point calculations are usually imprecise, so asking if two values are *exactly*\n    /// equal is asking for trouble because arriving at the same logical result via different\n    /// routes (e.g. calculation versus constant) may yield different values.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// let a: f64 = 1000.1;\n    /// let b: f64 = 0.2;\n    /// let x = a + b;\n    /// let y = 1000.3; // Expected value.\n    ///\n    /// // Actual value: 1000.3000000000001\n    /// println!(\"{x}\");\n    ///\n    /// let are_equal = x == y;\n    /// println!(\"{are_equal}\"); // false\n    /// ```\n    ///\n    /// The correct way to compare floating point numbers is to define an allowed error margin. This\n    /// may be challenging if there is no \"natural\" error margin to permit. Broadly speaking, there\n    /// are two cases:\n    ///\n    /// 1. If your values are in a known range and you can define a threshold for \"close enough to\n    ///    be equal\", it may be appropriate to define an absolute error margin. For example, if your\n    ///    data is \"length of vehicle in centimeters\", you may consider 0.1 cm to be \"close enough\".\n    /// 1. If your code is more general and you do not know the range of values, you should use a\n    ///    relative error margin, accepting e.g. 0.1% of error regardless of specific values.\n    ///\n    /// For the scenario where you can define a meaningful absolute error margin, consider using:\n    ///\n    /// ```no_run\n    /// let a: f64 = 1000.1;\n    /// let b: f64 = 0.2;\n    /// let x = a + b;\n    /// let y = 1000.3; // Expected value.\n    ///\n    /// const ALLOWED_ERROR_VEHICLE_LENGTH_CM: f64 = 0.1;\n    /// let within_tolerance = (x - y).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM;\n    /// println!(\"{within_tolerance}\"); // true\n    /// ```\n    ///\n    /// NOTE: Do not use `f64::EPSILON` - while the error margin is often called \"epsilon\", this is\n    /// a different use of the term that is not suitable for floating point equality comparison.\n    /// Indeed, for the example above using `f64::EPSILON` as the allowed error would return `false`.\n    ///\n    /// For the scenario where no meaningful absolute error can be defined, refer to\n    /// [the floating point guide](https://www.floating-point-gui.de/errors/comparison)\n    /// for a reference implementation of relative error based comparison of floating point values.\n    /// `MIN_NORMAL` in the reference implementation is equivalent to `MIN_POSITIVE` in Rust.\n    #[clippy::version = \"pre 1.29.0\"]\n    pub FLOAT_CMP,\n    pedantic,\n    \"using `==` or `!=` on float values instead of comparing difference with an allowed error\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for (in-)equality comparisons on constant floating-point\n    /// values (apart from zero), except in functions called `*eq*` (which probably\n    /// implement equality for a type involving floats).\n    ///\n    /// ### Why restrict this?\n    /// Floating point calculations are usually imprecise, so asking if two values are *exactly*\n    /// equal is asking for trouble because arriving at the same logical result via different\n    /// routes (e.g. calculation versus constant) may yield different values.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// let a: f64 = 1000.1;\n    /// let b: f64 = 0.2;\n    /// let x = a + b;\n    /// const Y: f64 = 1000.3; // Expected value.\n    ///\n    /// // Actual value: 1000.3000000000001\n    /// println!(\"{x}\");\n    ///\n    /// let are_equal = x == Y;\n    /// println!(\"{are_equal}\"); // false\n    /// ```\n    ///\n    /// The correct way to compare floating point numbers is to define an allowed error margin. This\n    /// may be challenging if there is no \"natural\" error margin to permit. Broadly speaking, there\n    /// are two cases:\n    ///\n    /// 1. If your values are in a known range and you can define a threshold for \"close enough to\n    ///    be equal\", it may be appropriate to define an absolute error margin. For example, if your\n    ///    data is \"length of vehicle in centimeters\", you may consider 0.1 cm to be \"close enough\".\n    /// 1. If your code is more general and you do not know the range of values, you should use a\n    ///    relative error margin, accepting e.g. 0.1% of error regardless of specific values.\n    ///\n    /// For the scenario where you can define a meaningful absolute error margin, consider using:\n    ///\n    /// ```no_run\n    /// let a: f64 = 1000.1;\n    /// let b: f64 = 0.2;\n    /// let x = a + b;\n    /// const Y: f64 = 1000.3; // Expected value.\n    ///\n    /// const ALLOWED_ERROR_VEHICLE_LENGTH_CM: f64 = 0.1;\n    /// let within_tolerance = (x - Y).abs() < ALLOWED_ERROR_VEHICLE_LENGTH_CM;\n    /// println!(\"{within_tolerance}\"); // true\n    /// ```\n    ///\n    /// NOTE: Do not use `f64::EPSILON` - while the error margin is often called \"epsilon\", this is\n    /// a different use of the term that is not suitable for floating point equality comparison.\n    /// Indeed, for the example above using `f64::EPSILON` as the allowed error would return `false`.\n    ///\n    /// For the scenario where no meaningful absolute error can be defined, refer to\n    /// [the floating point guide](https://www.floating-point-gui.de/errors/comparison)\n    /// for a reference implementation of relative error based comparison of floating point values.\n    /// `MIN_NORMAL` in the reference implementation is equivalent to `MIN_POSITIVE` in Rust.\n    #[clippy::version = \"pre 1.29.0\"]\n    pub FLOAT_CMP_CONST,\n    restriction,\n    \"using `==` or `!=` on float constants instead of comparing difference with an allowed error\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for statements of the form `(a - b) < f32::EPSILON` or\n    /// `(a - b) < f64::EPSILON`. Note the missing `.abs()`.\n    ///\n    /// ### Why is this bad?\n    /// The code without `.abs()` is more likely to have a bug.\n    ///\n    /// ### Known problems\n    /// If the user can ensure that b is larger than a, the `.abs()` is\n    /// technically unnecessary. However, it will make the code more robust and doesn't have any\n    /// large performance implications. If the abs call was deliberately left out for performance\n    /// reasons, it is probably better to state this explicitly in the code, which then can be done\n    /// with an allow.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub fn is_roughly_equal(a: f32, b: f32) -> bool {\n    ///     (a - b) < f32::EPSILON\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// pub fn is_roughly_equal(a: f32, b: f32) -> bool {\n    ///     (a - b).abs() < f32::EPSILON\n    /// }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub FLOAT_EQUALITY_WITHOUT_ABS,\n    suspicious,\n    \"float equality check without `.abs()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for identity operations, e.g., `x + 0`.\n    ///\n    /// ### Why is this bad?\n    /// This code can be removed without changing the\n    /// meaning. So it just obscures what's going on. Delete it mercilessly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// x / 1 + 0 * 1 - 0 | 0;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub IDENTITY_OP,\n    complexity,\n    \"using identity operations, e.g., `x + 0` or `y / 1`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for double comparisons that can never succeed\n    ///\n    /// ### Why is this bad?\n    /// The whole expression can be replaced by `false`,\n    /// which is probably not the programmer's intention\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let status_code = 200;\n    /// if status_code <= 400 && status_code > 500 {}\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub IMPOSSIBLE_COMPARISONS,\n    correctness,\n    \"double comparisons that will never evaluate to `true`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for bit masks in comparisons which can be removed\n    /// without changing the outcome. The basic structure can be seen in the\n    /// following table:\n    ///\n    /// |Comparison| Bit Op   |Example     |equals |\n    /// |----------|----------|------------|-------|\n    /// |`>` / `<=`|`\\|` / `^`|`x \\| 2 > 3`|`x > 3`|\n    /// |`<` / `>=`|`\\|` / `^`|`x ^ 1 < 4` |`x < 4`|\n    ///\n    /// ### Why is this bad?\n    /// Not equally evil as [`bad_bit_mask`](#bad_bit_mask),\n    /// but still a bit misleading, because the bit mask is ineffective.\n    ///\n    /// ### Known problems\n    /// False negatives: This lint will only match instances\n    /// where we have figured out the math (which is for a power-of-two compared\n    /// value). This means things like `x | 1 >= 7` (which would be better written\n    /// as `x >= 6`) will not be reported (but bit masks like this are fairly\n    /// uncommon).\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// if (x | 1 > 3) {  }\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```no_run\n    /// # let x = 1;\n    /// if (x >= 2) {  }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INEFFECTIVE_BIT_MASK,\n    correctness,\n    \"expressions where a bit mask will be rendered useless by a comparison, e.g., `(x | 1) > 2`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for division of integers\n    ///\n    /// ### Why restrict this?\n    /// When outside of some very specific algorithms,\n    /// integer division is very often a mistake because it discards the\n    /// remainder.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 3 / 2;\n    /// println!(\"{}\", x);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let x = 3f32 / 2f32;\n    /// println!(\"{}\", x);\n    /// ```\n    #[clippy::version = \"1.37.0\"]\n    pub INTEGER_DIVISION,\n    restriction,\n    \"integer division may cause loss of precision\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the usage of division (`/`) and remainder (`%`) operations\n    /// when performed on any integer types using the default `Div` and `Rem` trait implementations.\n    ///\n    /// ### Why restrict this?\n    /// In cryptographic contexts, division can result in timing sidechannel vulnerabilities,\n    /// and needs to be replaced with constant-time code instead (e.g. Barrett reduction).\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let my_div = 10 / 2;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let my_div = 10 >> 1;\n    /// ```\n    #[clippy::version = \"1.79.0\"]\n    pub INTEGER_DIVISION_REMAINDER_USED,\n    restriction,\n    \"use of disallowed default division and remainder operations\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for comparisons where the relation is always either\n    /// true or false, but where one side has been upcast so that the comparison is\n    /// necessary. Only integer types are checked.\n    ///\n    /// ### Why is this bad?\n    /// An expression like `let x : u8 = ...; (x as u32) > 300`\n    /// will mistakenly imply that it is possible for `x` to be outside the range of\n    /// `u8`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: u8 = 1;\n    /// (x as u32) > 300;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INVALID_UPCAST_COMPARISONS,\n    pedantic,\n    \"a comparison involving an upcast which is always true or false\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for an expression like `(x + (y - 1)) / y` which is a common manual reimplementation\n    /// of `x.div_ceil(y)`.\n    ///\n    /// ### Why is this bad?\n    /// It's simpler, clearer and more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x: i32 = 7;\n    /// let y: i32 = 4;\n    /// let div = (x + (y - 1)) / y;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #![feature(int_roundings)]\n    /// let x: i32 = 7;\n    /// let y: i32 = 4;\n    /// let div = x.div_ceil(y);\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub MANUAL_DIV_CEIL,\n    complexity,\n    \"manually reimplementing `div_ceil`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual implementation of `.is_multiple_of()` on\n    /// unsigned integer types.\n    ///\n    /// ### Why is this bad?\n    /// `a.is_multiple_of(b)` is a clearer way to check for divisibility\n    /// of `a` by `b`. This expression can never panic.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let (a, b) = (3u64, 4u64);\n    /// if a % b == 0 {\n    ///     println!(\"{a} is divisible by {b}\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let (a, b) = (3u64, 4u64);\n    /// if a.is_multiple_of(b) {\n    ///     println!(\"{a} is divisible by {b}\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.90.0\"]\n    pub MANUAL_IS_MULTIPLE_OF,\n    complexity,\n    \"manual implementation of `.is_multiple_of()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual implementation of `midpoint`.\n    ///\n    /// ### Why is this bad?\n    /// Using `(x + y) / 2` might cause an overflow on the intermediate\n    /// addition result.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let a: u32 = 0;\n    /// let c = (a + 10) / 2;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let a: u32 = 0;\n    /// let c = u32::midpoint(a, 10);\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub MANUAL_MIDPOINT,\n    pedantic,\n    \"manual implementation of `midpoint` which can overflow\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `a op= a op b` or `a op= b op a` patterns.\n    ///\n    /// ### Why is this bad?\n    /// Most likely these are bugs where one meant to write `a\n    /// op= b`.\n    ///\n    /// ### Known problems\n    /// Clippy cannot know for sure if `a op= a op b` should have\n    /// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both.\n    /// If `a op= a op b` is really the correct behavior it should be\n    /// written as `a = a op a op b` as it's less confusing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut a = 5;\n    /// let b = 2;\n    /// // ...\n    /// a += a + b;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MISREFACTORED_ASSIGN_OP,\n    suspicious,\n    \"having a variable on both sides of an assign op\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for modulo arithmetic.\n    ///\n    /// ### Why restrict this?\n    /// The results of modulo (`%`) operation might differ\n    /// depending on the language, when negative numbers are involved.\n    /// If you interop with different languages it might be beneficial\n    /// to double check all places that use modulo arithmetic.\n    ///\n    /// For example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = -17 % 3;\n    /// ```\n    #[clippy::version = \"1.42.0\"]\n    pub MODULO_ARITHMETIC,\n    restriction,\n    \"any modulo arithmetic statement\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for getting the remainder of integer division by one or minus\n    /// one.\n    ///\n    /// ### Why is this bad?\n    /// The result for a divisor of one can only ever be zero; for\n    /// minus one it can cause panic/overflow (if the left operand is the minimal value of\n    /// the respective integer type) or results in zero. No one will write such code\n    /// deliberately, unless trying to win an Underhanded Rust Contest. Even for that\n    /// contest, it's probably a bad idea. Use something more underhanded.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// let a = x % 1;\n    /// let a = x % -1;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MODULO_ONE,\n    correctness,\n    \"taking an integer modulo +/-1, which can either panic/overflow or always returns 0\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of bitwise and/or operators between booleans, where performance may be improved by using\n    /// a lazy and.\n    ///\n    /// ### Why is this bad?\n    /// The bitwise operators do not support short-circuiting, so it may hinder code performance.\n    /// Additionally, boolean logic \"masked\" as bitwise logic is not caught by lints like `unnecessary_fold`\n    ///\n    /// ### Known problems\n    /// This lint evaluates only when the right side is determined to have no side effects. At this time, that\n    /// determination is quite conservative.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let (x,y) = (true, false);\n    /// if x & !y {} // where both x and y are booleans\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let (x,y) = (true, false);\n    /// if x && !y {}\n    /// ```\n    #[clippy::version = \"1.54.0\"]\n    pub NEEDLESS_BITWISE_BOOL,\n    pedantic,\n    \"Boolean expressions that use bitwise rather than lazy operators\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for arguments to `==` which have their address\n    /// taken to satisfy a bound\n    /// and suggests to dereference the other argument instead\n    ///\n    /// ### Why is this bad?\n    /// It is more idiomatic to dereference the other argument.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// &x == y\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// x == *y\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub OP_REF,\n    style,\n    \"taking a reference to satisfy the type constraints on `==`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for ineffective double comparisons against constants.\n    ///\n    /// ### Why is this bad?\n    /// Only one of the comparisons has any effect on the result, the programmer\n    /// probably intended to flip one of the comparison operators, or compare a\n    /// different value entirely.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let status_code = 200;\n    /// if status_code <= 400 && status_code < 500 {}\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub REDUNDANT_COMPARISONS,\n    correctness,\n    \"double comparisons where one of them can be removed\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for explicit self-assignments.\n    ///\n    /// ### Why is this bad?\n    /// Self-assignments are redundant and unlikely to be\n    /// intentional.\n    ///\n    /// ### Known problems\n    /// If expression contains any deref coercions or\n    /// indexing operations they are assumed not to have any side effects.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Event {\n    ///     x: i32,\n    /// }\n    ///\n    /// fn copy_position(a: &mut Event, b: &Event) {\n    ///     a.x = a.x;\n    /// }\n    /// ```\n    ///\n    /// Should be:\n    /// ```no_run\n    /// struct Event {\n    ///     x: i32,\n    /// }\n    ///\n    /// fn copy_position(a: &mut Event, b: &Event) {\n    ///     a.x = b.x;\n    /// }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub SELF_ASSIGNMENT,\n    correctness,\n    \"explicit self-assignment\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for bit masks that can be replaced by a call\n    /// to `trailing_zeros`\n    ///\n    /// ### Why is this bad?\n    /// `x.trailing_zeros() >= 4` is much clearer than `x & 15\n    /// == 0`\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// if x & 0b1111 == 0 { }\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```no_run\n    /// # let x: i32 = 1;\n    /// if x.trailing_zeros() >= 4 { }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub VERBOSE_BIT_MASK,\n    pedantic,\n    \"expressions where a bit mask is less readable than the corresponding method call\"\n}\n\nimpl_lint_pass!(Operators => [\n    ABSURD_EXTREME_COMPARISONS,\n    ARITHMETIC_SIDE_EFFECTS,\n    ASSIGN_OP_PATTERN,\n    BAD_BIT_MASK,\n    CMP_OWNED,\n    DECIMAL_BITWISE_OPERANDS,\n    DOUBLE_COMPARISONS,\n    DURATION_SUBSEC,\n    EQ_OP,\n    ERASING_OP,\n    FLOAT_ARITHMETIC,\n    FLOAT_CMP,\n    FLOAT_CMP_CONST,\n    FLOAT_EQUALITY_WITHOUT_ABS,\n    IDENTITY_OP,\n    IMPOSSIBLE_COMPARISONS,\n    INEFFECTIVE_BIT_MASK,\n    INTEGER_DIVISION,\n    INTEGER_DIVISION_REMAINDER_USED,\n    INVALID_UPCAST_COMPARISONS,\n    MANUAL_DIV_CEIL,\n    MANUAL_IS_MULTIPLE_OF,\n    MANUAL_MIDPOINT,\n    MISREFACTORED_ASSIGN_OP,\n    MODULO_ARITHMETIC,\n    MODULO_ONE,\n    NEEDLESS_BITWISE_BOOL,\n    OP_REF,\n    REDUNDANT_COMPARISONS,\n    SELF_ASSIGNMENT,\n    VERBOSE_BIT_MASK,\n]);\n\npub struct Operators {\n    arithmetic_context: numeric_arithmetic::Context,\n    verbose_bit_mask_threshold: u64,\n    modulo_arithmetic_allow_comparison_to_zero: bool,\n    msrv: Msrv,\n}\n\nimpl Operators {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            arithmetic_context: numeric_arithmetic::Context::default(),\n            verbose_bit_mask_threshold: conf.verbose_bit_mask_threshold,\n            modulo_arithmetic_allow_comparison_to_zero: conf.allow_comparison_to_zero,\n            msrv: conf.msrv,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Operators {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        eq_op::check_assert(cx, e);\n        match e.kind {\n            ExprKind::Binary(op, lhs, rhs) => {\n                if !e.span.from_expansion() {\n                    absurd_extreme_comparisons::check(cx, e, op.node, lhs, rhs);\n                    if !(macro_with_not_op(lhs) || macro_with_not_op(rhs)) {\n                        eq_op::check(cx, e, op.node, lhs, rhs);\n                        op_ref::check(cx, e, op.node, lhs, rhs);\n                    }\n                    erasing_op::check(cx, e, op.node, lhs, rhs);\n                    identity_op::check(cx, e, op.node, lhs, rhs);\n                    invalid_upcast_comparisons::check(cx, op.node, lhs, rhs, e.span);\n                    needless_bitwise_bool::check(cx, e, op.node, lhs, rhs);\n                    manual_midpoint::check(cx, e, op.node, lhs, rhs, self.msrv);\n                    manual_is_multiple_of::check(cx, e, op.node, lhs, rhs, self.msrv);\n                    decimal_bitwise_operands::check(cx, op.node, lhs, rhs);\n                }\n                self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);\n                bit_mask::check(cx, e, op.node, lhs, rhs);\n                verbose_bit_mask::check(cx, e, op.node, lhs, rhs, self.verbose_bit_mask_threshold);\n                double_comparison::check(cx, op.node, lhs, rhs, e.span);\n                const_comparisons::check(cx, op, lhs, rhs, e.span);\n                duration_subsec::check(cx, e, op.node, lhs, rhs);\n                float_equality_without_abs::check(cx, e, op.node, lhs, rhs);\n                integer_division::check(cx, e, op.node, lhs, rhs);\n                integer_division_remainder_used::check(cx, op.node, lhs, rhs, e.span);\n                cmp_owned::check(cx, e, op.node, lhs, rhs);\n                float_cmp::check(cx, e, op.node, lhs, rhs);\n                modulo_one::check(cx, e, op.node, rhs);\n                modulo_arithmetic::check(\n                    cx,\n                    e,\n                    op.node,\n                    lhs,\n                    rhs,\n                    self.modulo_arithmetic_allow_comparison_to_zero,\n                );\n                manual_div_ceil::check(cx, e, op.node, lhs, rhs, self.msrv);\n            },\n            ExprKind::AssignOp(op, lhs, rhs) => {\n                let bin_op = op.node.into();\n                if !e.span.from_expansion() {\n                    decimal_bitwise_operands::check(cx, bin_op, lhs, rhs);\n                }\n                self.arithmetic_context.check_binary(cx, e, bin_op, lhs, rhs);\n                misrefactored_assign_op::check(cx, e, bin_op, lhs, rhs);\n                modulo_arithmetic::check(cx, e, bin_op, lhs, rhs, false);\n            },\n            ExprKind::Assign(lhs, rhs, _) => {\n                assign_op_pattern::check(cx, e, lhs, rhs, self.msrv);\n                self_assignment::check(cx, e, lhs, rhs);\n            },\n            ExprKind::Unary(op, arg) =>\n            {\n                #[expect(clippy::collapsible_match)]\n                if op == UnOp::Neg {\n                    self.arithmetic_context.check_negate(cx, e, arg);\n                }\n            },\n            _ => (),\n        }\n    }\n\n    fn check_expr_post(&mut self, _: &LateContext<'_>, e: &Expr<'_>) {\n        self.arithmetic_context.expr_post(e.hir_id);\n    }\n\n    fn check_body(&mut self, cx: &LateContext<'tcx>, b: &Body<'_>) {\n        self.arithmetic_context.enter_body(cx, b);\n    }\n\n    fn check_body_post(&mut self, cx: &LateContext<'tcx>, b: &Body<'_>) {\n        self.arithmetic_context.body_post(cx, b);\n    }\n}\n\nfn macro_with_not_op(e: &Expr<'_>) -> bool {\n    if let ExprKind::Unary(_, e) = e.kind {\n        e.span.from_expansion()\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/modulo_arithmetic.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sext;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, Node};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse std::fmt::Display;\n\nuse super::MODULO_ARITHMETIC;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    op: BinOpKind,\n    lhs: &'tcx Expr<'_>,\n    rhs: &'tcx Expr<'_>,\n    allow_comparison_to_zero: bool,\n) {\n    if op == BinOpKind::Rem {\n        if allow_comparison_to_zero && used_in_comparison_with_zero(cx, e) {\n            return;\n        }\n\n        let lhs_operand = analyze_operand(lhs, cx, e);\n        let rhs_operand = analyze_operand(rhs, cx, e);\n        if let Some(lhs_operand) = lhs_operand\n            && let Some(rhs_operand) = rhs_operand\n        {\n            check_const_operands(cx, e, &lhs_operand, &rhs_operand);\n        } else {\n            check_non_const_operands(cx, e, lhs);\n        }\n    }\n}\n\nfn used_in_comparison_with_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id)\n        && let ExprKind::Binary(op, lhs, rhs) = parent_expr.kind\n        && let BinOpKind::Eq | BinOpKind::Ne = op.node\n    {\n        let ecx = ConstEvalCtxt::new(cx);\n        let ctxt = expr.span.ctxt();\n        matches!(ecx.eval_local(lhs, ctxt), Some(Constant::Int(0)))\n            || matches!(ecx.eval_local(rhs, ctxt), Some(Constant::Int(0)))\n    } else {\n        false\n    }\n}\n\nstruct OperandInfo {\n    string_representation: Option<String>,\n    is_negative: bool,\n    is_integral: bool,\n}\n\nfn analyze_operand(operand: &Expr<'_>, cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<OperandInfo> {\n    match ConstEvalCtxt::new(cx).eval(operand)? {\n        Constant::Int(v) => match *cx.typeck_results().expr_ty(expr).kind() {\n            ty::Int(ity) => {\n                let value: i128 = sext(cx.tcx, v, ity);\n                Some(OperandInfo {\n                    string_representation: Some(value.to_string()),\n                    is_negative: value < 0,\n                    is_integral: true,\n                })\n            },\n            ty::Uint(_) => Some(OperandInfo {\n                string_representation: None,\n                is_negative: false,\n                is_integral: true,\n            }),\n            _ => None,\n        },\n        // FIXME(f16_f128): add when casting is available on all platforms\n        Constant::F32(f) => Some(floating_point_operand_info(&f)),\n        Constant::F64(f) => Some(floating_point_operand_info(&f)),\n        _ => None,\n    }\n}\n\nfn floating_point_operand_info<T: Display + PartialOrd + From<f32>>(f: &T) -> OperandInfo {\n    OperandInfo {\n        string_representation: Some(format!(\"{:.3}\", *f)),\n        is_negative: *f < 0.0.into(),\n        is_integral: false,\n    }\n}\n\nfn might_have_negative_value(t: Ty<'_>) -> bool {\n    t.is_signed() || t.is_floating_point()\n}\n\nfn check_const_operands<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    lhs_operand: &OperandInfo,\n    rhs_operand: &OperandInfo,\n) {\n    if lhs_operand.is_negative ^ rhs_operand.is_negative {\n        span_lint_and_then(\n            cx,\n            MODULO_ARITHMETIC,\n            expr.span,\n            format!(\n                \"you are using modulo operator on constants with different signs: `{} % {}`\",\n                lhs_operand.string_representation.as_ref().unwrap(),\n                rhs_operand.string_representation.as_ref().unwrap()\n            ),\n            |diag| {\n                diag.note(\"double check for expected result especially when interoperating with different languages\");\n                if lhs_operand.is_integral {\n                    diag.note(\"or consider using `rem_euclid` or similar function\");\n                }\n            },\n        );\n    }\n}\n\nfn check_non_const_operands<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, operand: &Expr<'_>) {\n    let operand_type = cx.typeck_results().expr_ty(operand);\n    if might_have_negative_value(operand_type) {\n        span_lint_and_then(\n            cx,\n            MODULO_ARITHMETIC,\n            expr.span,\n            \"you are using modulo operator on types that might have different signs\",\n            |diag| {\n                diag.note(\"double check for expected result especially when interoperating with different languages\");\n                if operand_type.is_integral() {\n                    diag.note(\"or consider using `rem_euclid` or similar function\");\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/modulo_one.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::{is_integer_const, unsext};\nuse rustc_hir::{BinOpKind, Expr};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\n\nuse super::MODULO_ONE;\n\npub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, op: BinOpKind, right: &Expr<'_>) {\n    if op == BinOpKind::Rem {\n        if is_integer_const(cx, right, 1) {\n            span_lint(cx, MODULO_ONE, expr.span, \"any number modulo 1 will be 0\");\n        }\n\n        if let ty::Int(ity) = cx.typeck_results().expr_ty(right).kind()\n            && is_integer_const(cx, right, unsext(cx.tcx, -1, *ity))\n        {\n            span_lint(\n                cx,\n                MODULO_ONE,\n                expr.span,\n                \"any number modulo -1 will panic/overflow or result in 0\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/needless_bitwise_bool.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\n\nuse super::NEEDLESS_BITWISE_BOOL;\n\npub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>) {\n    let op_str = match op {\n        BinOpKind::BitAnd => \"&&\",\n        BinOpKind::BitOr => \"||\",\n        _ => return,\n    };\n    if matches!(\n        rhs.kind,\n        ExprKind::Call(..) | ExprKind::MethodCall(..) | ExprKind::Binary(..) | ExprKind::Unary(..)\n    ) && cx.typeck_results().expr_ty(e).is_bool()\n        && !rhs.can_have_side_effects()\n    {\n        span_lint_and_then(\n            cx,\n            NEEDLESS_BITWISE_BOOL,\n            e.span,\n            \"use of bitwise operator instead of lazy operator between booleans\",\n            |diag| {\n                if let Some(lhs_snip) = lhs.span.get_source_text(cx)\n                    && let Some(rhs_snip) = rhs.span.get_source_text(cx)\n                {\n                    let sugg = format!(\"{lhs_snip} {op_str} {rhs_snip}\");\n                    diag.span_suggestion(e.span, \"try\", sugg, Applicability::MachineApplicable);\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/numeric_arithmetic.rs",
    "content": "use super::FLOAT_ARITHMETIC;\nuse clippy_utils::consts::ConstEvalCtxt;\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_hir as hir;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\n#[derive(Default)]\npub struct Context {\n    expr_id: Option<hir::HirId>,\n    /// This field is used to check whether expressions are constants, such as in enum discriminants\n    /// and consts\n    const_span: Option<Span>,\n}\nimpl Context {\n    fn skip_expr(&self, e: &hir::Expr<'_>) -> bool {\n        self.expr_id.is_some() || self.const_span.is_some_and(|span| span.contains(e.span))\n    }\n\n    pub fn check_binary<'tcx>(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        expr: &'tcx hir::Expr<'_>,\n        op: hir::BinOpKind,\n        l: &'tcx hir::Expr<'_>,\n        r: &'tcx hir::Expr<'_>,\n    ) {\n        if self.skip_expr(expr) {\n            return;\n        }\n        match op {\n            hir::BinOpKind::And\n            | hir::BinOpKind::Or\n            | hir::BinOpKind::BitAnd\n            | hir::BinOpKind::BitOr\n            | hir::BinOpKind::BitXor\n            | hir::BinOpKind::Eq\n            | hir::BinOpKind::Lt\n            | hir::BinOpKind::Le\n            | hir::BinOpKind::Ne\n            | hir::BinOpKind::Ge\n            | hir::BinOpKind::Gt => return,\n            _ => (),\n        }\n\n        let (l_ty, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r));\n        if l_ty.peel_refs().is_floating_point() && r_ty.peel_refs().is_floating_point() {\n            span_lint(cx, FLOAT_ARITHMETIC, expr.span, \"floating-point arithmetic detected\");\n            self.expr_id = Some(expr.hir_id);\n        }\n    }\n\n    pub fn check_negate<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, arg: &'tcx hir::Expr<'_>) {\n        if self.skip_expr(expr) {\n            return;\n        }\n        let ty = cx.typeck_results().expr_ty(arg);\n        if ConstEvalCtxt::new(cx).eval_local(expr, expr.span.ctxt()).is_none() && ty.is_floating_point() {\n            span_lint(cx, FLOAT_ARITHMETIC, expr.span, \"floating-point arithmetic detected\");\n            self.expr_id = Some(expr.hir_id);\n        }\n    }\n\n    pub fn expr_post(&mut self, id: hir::HirId) {\n        if Some(id) == self.expr_id {\n            self.expr_id = None;\n        }\n    }\n\n    pub fn enter_body(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {\n        let body_owner = cx.tcx.hir_body_owner(body.id());\n        let body_owner_def_id = cx.tcx.hir_body_owner_def_id(body.id());\n\n        match cx.tcx.hir_body_owner_kind(body_owner_def_id) {\n            hir::BodyOwnerKind::Static(_) | hir::BodyOwnerKind::Const { .. } => {\n                let body_span = cx.tcx.hir_span_with_body(body_owner);\n\n                if let Some(span) = self.const_span\n                    && span.contains(body_span)\n                {\n                    return;\n                }\n                self.const_span = Some(body_span);\n            },\n            hir::BodyOwnerKind::Fn | hir::BodyOwnerKind::Closure | hir::BodyOwnerKind::GlobalAsm => (),\n        }\n    }\n\n    pub fn body_post(&mut self, cx: &LateContext<'_>, body: &hir::Body<'_>) {\n        let body_owner = cx.tcx.hir_body_owner(body.id());\n        let body_span = cx.tcx.hir_span_with_body(body_owner);\n\n        if let Some(span) = self.const_span\n            && span.contains(body_span)\n        {\n            return;\n        }\n        self.const_span = None;\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/op_ref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::get_enclosing_block;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, GenericArg, ItemKind, QPath, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\nuse super::OP_REF;\n\n#[expect(clippy::too_many_lines)]\npub(crate) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n) {\n    let (trait_id, requires_ref) = match op {\n        BinOpKind::Add => (cx.tcx.lang_items().add_trait(), false),\n        BinOpKind::Sub => (cx.tcx.lang_items().sub_trait(), false),\n        BinOpKind::Mul => (cx.tcx.lang_items().mul_trait(), false),\n        BinOpKind::Div => (cx.tcx.lang_items().div_trait(), false),\n        BinOpKind::Rem => (cx.tcx.lang_items().rem_trait(), false),\n        // don't lint short circuiting ops\n        BinOpKind::And | BinOpKind::Or => return,\n        BinOpKind::BitXor => (cx.tcx.lang_items().bitxor_trait(), false),\n        BinOpKind::BitAnd => (cx.tcx.lang_items().bitand_trait(), false),\n        BinOpKind::BitOr => (cx.tcx.lang_items().bitor_trait(), false),\n        BinOpKind::Shl => (cx.tcx.lang_items().shl_trait(), false),\n        BinOpKind::Shr => (cx.tcx.lang_items().shr_trait(), false),\n        BinOpKind::Ne | BinOpKind::Eq => (cx.tcx.lang_items().eq_trait(), true),\n        BinOpKind::Lt | BinOpKind::Le | BinOpKind::Ge | BinOpKind::Gt => {\n            (cx.tcx.lang_items().partial_ord_trait(), true)\n        },\n    };\n    if let Some(trait_id) = trait_id {\n        match (&left.kind, &right.kind) {\n            // do not suggest to dereference literals\n            (&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {},\n            // &foo == &bar\n            (&ExprKind::AddrOf(BorrowKind::Ref, _, l), &ExprKind::AddrOf(BorrowKind::Ref, _, r)) => {\n                let lty = cx.typeck_results().expr_ty(l);\n                let rty = cx.typeck_results().expr_ty(r);\n                let lcpy = is_copy(cx, lty);\n                let rcpy = is_copy(cx, rty);\n                if let Some((self_ty, other_ty)) = in_impl(cx, e, trait_id)\n                    && ((are_equal(cx, rty, self_ty) && are_equal(cx, lty, other_ty))\n                        || (are_equal(cx, rty, other_ty) && are_equal(cx, lty, self_ty)))\n                {\n                    return; // Don't lint\n                }\n                // either operator autorefs or both args are copyable\n                if (requires_ref || (lcpy && rcpy)) && implements_trait(cx, lty, trait_id, &[rty.into()]) {\n                    span_lint_and_then(\n                        cx,\n                        OP_REF,\n                        e.span,\n                        \"needlessly taken reference of both operands\",\n                        |diag| {\n                            let mut applicability = Applicability::MachineApplicable;\n                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), \"...\", &mut applicability);\n                            let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), \"...\", &mut applicability);\n                            diag.multipart_suggestion(\n                                \"use the values directly\",\n                                vec![(left.span, lsnip.to_string()), (right.span, rsnip.to_string())],\n                                applicability,\n                            );\n                        },\n                    );\n                } else if lcpy\n                    && !rcpy\n                    && implements_trait(cx, lty, trait_id, &[cx.typeck_results().expr_ty(right).into()])\n                {\n                    span_lint_and_then(\n                        cx,\n                        OP_REF,\n                        e.span,\n                        \"needlessly taken reference of left operand\",\n                        |diag| {\n                            let mut applicability = Applicability::MachineApplicable;\n                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), \"...\", &mut applicability);\n                            diag.span_suggestion(left.span, \"use the left value directly\", lsnip, applicability);\n                        },\n                    );\n                } else if !lcpy\n                    && rcpy\n                    && implements_trait(cx, cx.typeck_results().expr_ty(left), trait_id, &[rty.into()])\n                {\n                    span_lint_and_then(\n                        cx,\n                        OP_REF,\n                        e.span,\n                        \"needlessly taken reference of right operand\",\n                        |diag| {\n                            let mut applicability = Applicability::MachineApplicable;\n                            let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), \"...\", &mut applicability);\n                            diag.span_suggestion(\n                                right.span,\n                                \"use the right value directly\",\n                                rsnip,\n                                Applicability::MachineApplicable,\n                            );\n                        },\n                    );\n                }\n            },\n            // &foo == bar\n            (&ExprKind::AddrOf(BorrowKind::Ref, _, l), _) => {\n                let lty = cx.typeck_results().expr_ty(l);\n                if let Some((self_ty, other_ty)) = in_impl(cx, e, trait_id) {\n                    let rty = cx.typeck_results().expr_ty(right);\n                    if (are_equal(cx, rty, self_ty) && are_equal(cx, lty, other_ty))\n                        || (are_equal(cx, rty, other_ty) && are_equal(cx, lty, self_ty))\n                    {\n                        return; // Don't lint\n                    }\n                }\n                let lcpy = is_copy(cx, lty);\n                if (requires_ref || lcpy)\n                    && implements_trait(cx, lty, trait_id, &[cx.typeck_results().expr_ty(right).into()])\n                {\n                    span_lint_and_then(\n                        cx,\n                        OP_REF,\n                        e.span,\n                        \"needlessly taken reference of left operand\",\n                        |diag| {\n                            let mut applicability = Applicability::MachineApplicable;\n                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), \"...\", &mut applicability);\n                            diag.span_suggestion(\n                                left.span,\n                                \"use the left value directly\",\n                                lsnip,\n                                Applicability::MachineApplicable,\n                            );\n                        },\n                    );\n                }\n            },\n            // foo == &bar\n            (_, &ExprKind::AddrOf(BorrowKind::Ref, _, r)) => {\n                let rty = cx.typeck_results().expr_ty(r);\n                if let Some((self_ty, other_ty)) = in_impl(cx, e, trait_id) {\n                    let lty = cx.typeck_results().expr_ty(left);\n                    if (are_equal(cx, rty, self_ty) && are_equal(cx, lty, other_ty))\n                        || (are_equal(cx, rty, other_ty) && are_equal(cx, lty, self_ty))\n                    {\n                        return; // Don't lint\n                    }\n                }\n                let rcpy = is_copy(cx, rty);\n                if (requires_ref || rcpy)\n                    && implements_trait(cx, cx.typeck_results().expr_ty(left), trait_id, &[rty.into()])\n                {\n                    span_lint_and_then(cx, OP_REF, e.span, \"taken reference of right operand\", |diag| {\n                        let mut applicability = Applicability::MachineApplicable;\n                        let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), \"...\", &mut applicability);\n                        diag.span_suggestion(\n                            right.span,\n                            \"use the right value directly\",\n                            rsnip,\n                            Applicability::MachineApplicable,\n                        );\n                    });\n                }\n            },\n            _ => {},\n        }\n    }\n}\n\nfn in_impl<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    bin_op: DefId,\n) -> Option<(&'tcx rustc_hir::Ty<'tcx>, &'tcx rustc_hir::Ty<'tcx>)> {\n    if let Some(block) = get_enclosing_block(cx, e.hir_id)\n        && let Some(impl_def_id) = cx.tcx.impl_of_assoc(block.hir_id.owner.to_def_id())\n        && let item = cx.tcx.hir_expect_item(impl_def_id.expect_local())\n        && let ItemKind::Impl(item) = &item.kind\n        && let Some(of_trait) = &item.of_trait\n        && let Some(seg) = of_trait.trait_ref.path.segments.last()\n        && let Res::Def(_, trait_id) = seg.res\n        && trait_id == bin_op\n        && let Some(generic_args) = seg.args\n        && let Some(GenericArg::Type(other_ty)) = generic_args.args.last()\n    {\n        // `_` is not permitted in impl headers\n        Some((item.self_ty, other_ty.as_unambig_ty()))\n    } else {\n        None\n    }\n}\n\nfn are_equal(cx: &LateContext<'_>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool {\n    if let ty::Adt(adt_def, _) = middle_ty.kind()\n        && let Some(local_did) = adt_def.did().as_local()\n        && let item = cx.tcx.hir_expect_item(local_did)\n        && let middle_ty_id = item.owner_id.to_def_id()\n        && let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind\n        && let Res::Def(_, hir_ty_id) = path.res\n    {\n        hir_ty_id == middle_ty_id\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/self_assignment.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::eq_expr_value;\nuse clippy_utils::source::snippet;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\n\nuse super::SELF_ASSIGNMENT;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, lhs: &'tcx Expr<'_>, rhs: &'tcx Expr<'_>) {\n    if eq_expr_value(cx, lhs, rhs) {\n        let lhs = snippet(cx, lhs.span, \"<lhs>\");\n        let rhs = snippet(cx, rhs.span, \"<rhs>\");\n        span_lint(\n            cx,\n            SELF_ASSIGNMENT,\n            e.span,\n            format!(\"self-assignment of `{rhs}` to `{lhs}`\"),\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/operators/verbose_bit_mask.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg::Sugg;\nuse rustc_ast::ast::LitKind;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\n\nuse super::VERBOSE_BIT_MASK;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n    threshold: u64,\n) {\n    if BinOpKind::Eq == op\n        && let ExprKind::Binary(op1, left1, right1) = &left.kind\n        && BinOpKind::BitAnd == op1.node\n        && let ExprKind::Lit(lit) = &right1.kind\n        && let LitKind::Int(Pu128(n), _) = lit.node\n        && let ExprKind::Lit(lit1) = &right.kind\n        && let LitKind::Int(Pu128(0), _) = lit1.node\n        && n.leading_zeros() == n.count_zeros()\n        && n > u128::from(threshold)\n    {\n        span_lint_and_then(\n            cx,\n            VERBOSE_BIT_MASK,\n            e.span,\n            \"bit mask could be simplified with a call to `trailing_zeros`\",\n            |diag| {\n                let sugg = Sugg::hir(cx, left1, \"...\").maybe_paren();\n                diag.span_suggestion(\n                    e.span,\n                    \"try\",\n                    format!(\"{sugg}.trailing_zeros() >= {}\", n.count_ones()),\n                    Applicability::MaybeIncorrect,\n                );\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/option_env_unwrap.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::is_direct_expn_of;\nuse rustc_ast::ast::{Expr, ExprKind, MethodCall};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `option_env!(...).unwrap()` and\n    /// suggests usage of the `env!` macro.\n    ///\n    /// ### Why is this bad?\n    /// Unwrapping the result of `option_env!` will panic\n    /// at run-time if the environment variable doesn't exist, whereas `env!`\n    /// catches it at compile-time.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// let _ = option_env!(\"HOME\").unwrap();\n    /// ```\n    ///\n    /// Is better expressed as:\n    ///\n    /// ```rust,no_run\n    /// let _ = env!(\"HOME\");\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub OPTION_ENV_UNWRAP,\n    correctness,\n    \"using `option_env!(...).unwrap()` to get environment variable\"\n}\n\ndeclare_lint_pass!(OptionEnvUnwrap => [OPTION_ENV_UNWRAP]);\n\nimpl EarlyLintPass for OptionEnvUnwrap {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind\n            && matches!(seg.ident.name, sym::expect | sym::unwrap)\n            && is_direct_expn_of(receiver.span, sym::option_env).is_some()\n        {\n            span_lint_and_help(\n                cx,\n                OPTION_ENV_UNWRAP,\n                expr.span,\n                \"this will panic at run-time if the environment variable doesn't exist at compile-time\",\n                None,\n                \"consider using the `env!` macro instead\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/option_if_let_else.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::is_copy;\nuse clippy_utils::{\n    CaptureKind, can_move_expr_to_closure, eager_or_lazy, expr_requires_coercion, higher, is_else_clause,\n    is_in_const_context, is_none_pattern, peel_blocks, peel_hir_expr_while,\n};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::ResultErr;\nuse rustc_hir::def::Res;\nuse rustc_hir::intravisit::{Visitor, walk_expr, walk_path};\nuse rustc_hir::{\n    Arm, BindingMode, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat, PatKind, Path, QPath, UnOp,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::SyntaxContext;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints usage of `if let Some(v) = ... { y } else { x }` and\n    /// `match .. { Some(v) => y, None/_ => x }` which are more\n    /// idiomatically done with `Option::map_or` (if the else bit is a pure\n    /// expression) or `Option::map_or_else` (if the else bit is an impure\n    /// expression).\n    ///\n    /// ### Why is this bad?\n    /// Using the dedicated functions of the `Option` type is clearer and\n    /// more concise than an `if let` expression.\n    ///\n    /// ### Notes\n    /// This lint uses a deliberately conservative metric for checking if the\n    /// inside of either body contains loop control expressions `break` or\n    /// `continue` (which cannot be used within closures). If these are found,\n    /// this lint will not be raised.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let optional: Option<u32> = Some(0);\n    /// # fn do_complicated_function() -> u32 { 5 };\n    /// let _ = if let Some(foo) = optional {\n    ///     foo\n    /// } else {\n    ///     5\n    /// };\n    /// let _ = match optional {\n    ///     Some(val) => val + 1,\n    ///     None => 5\n    /// };\n    /// let _ = if let Some(foo) = optional {\n    ///     foo\n    /// } else {\n    ///     let y = do_complicated_function();\n    ///     y*y\n    /// };\n    /// ```\n    ///\n    /// should be\n    ///\n    /// ```no_run\n    /// # let optional: Option<u32> = Some(0);\n    /// # fn do_complicated_function() -> u32 { 5 };\n    /// let _ = optional.map_or(5, |foo| foo);\n    /// let _ = optional.map_or(5, |val| val + 1);\n    /// let _ = optional.map_or_else(||{\n    ///     let y = do_complicated_function();\n    ///     y*y\n    /// }, |foo| foo);\n    /// ```\n    // FIXME: Before moving this lint out of nursery, the lint name needs to be updated. It now also\n    // covers matches and `Result`.\n    #[clippy::version = \"1.47.0\"]\n    pub OPTION_IF_LET_ELSE,\n    nursery,\n    \"reimplementation of Option::map_or\"\n}\n\ndeclare_lint_pass!(OptionIfLetElse => [OPTION_IF_LET_ELSE]);\n\n/// A struct containing information about occurrences of construct that this lint detects\n///\n/// Such as:\n///\n/// ```ignore\n/// if let Some(..) = {..} else {..}\n/// ```\n/// or\n/// ```ignore\n/// match x {\n///     Some(..) => {..},\n///     None/_ => {..}\n/// }\n/// ```\nstruct OptionOccurrence {\n    option: String,\n    method_sugg: String,\n    some_expr: String,\n    none_expr: String,\n}\n\nfn format_option_in_sugg(cond_sugg: Sugg<'_>, as_ref: bool, as_mut: bool) -> String {\n    format!(\n        \"{}{}\",\n        cond_sugg.maybe_paren(),\n        if as_mut {\n            \".as_mut()\"\n        } else if as_ref {\n            \".as_ref()\"\n        } else {\n            \"\"\n        }\n    )\n}\n\n#[expect(clippy::too_many_lines)]\nfn try_get_option_occurrence<'tcx>(\n    cx: &LateContext<'tcx>,\n    ctxt: SyntaxContext,\n    pat: &Pat<'tcx>,\n    expr: &'tcx Expr<'_>,\n    if_then: &'tcx Expr<'_>,\n    if_else: &'tcx Expr<'_>,\n) -> Option<OptionOccurrence> {\n    let cond_expr = match expr.kind {\n        ExprKind::AddrOf(_, _, inner_expr) => inner_expr,\n        ExprKind::Unary(UnOp::Deref, inner_expr) if !cx.typeck_results().expr_ty(inner_expr).is_raw_ptr() => inner_expr,\n        _ => expr,\n    };\n    let (inner_pat, is_result) = try_get_inner_pat_and_is_result(cx, pat)?;\n    if let PatKind::Binding(bind_annotation, _, id, None) = inner_pat.kind\n        && let Some(some_captures) = can_move_expr_to_closure(cx, if_then)\n        && let Some(none_captures) = can_move_expr_to_closure(cx, if_else)\n        && some_captures\n            .iter()\n            .filter_map(|(id, &c)| none_captures.get(id).map(|&c2| (c, c2)))\n            .all(|(x, y)| x.is_imm_ref() && y.is_imm_ref())\n    {\n        let capture_mut = if bind_annotation == BindingMode::MUT {\n            \"mut \"\n        } else {\n            \"\"\n        };\n        let some_body = peel_blocks(if_then);\n        let none_body = peel_blocks(if_else);\n        let method_sugg = if eager_or_lazy::switch_to_eager_eval(cx, none_body) {\n            \"map_or\"\n        } else {\n            \"map_or_else\"\n        };\n        let capture_name = id.name.to_ident_string();\n        let (as_ref, as_mut) = match &expr.kind {\n            ExprKind::AddrOf(_, Mutability::Not, _) => (true, false),\n            ExprKind::AddrOf(_, Mutability::Mut, _) => (false, true),\n            _ if let Some(mutb) = cx.typeck_results().expr_ty(expr).ref_mutability() => {\n                (mutb == Mutability::Not, mutb == Mutability::Mut)\n            },\n            _ => (\n                bind_annotation == BindingMode::REF,\n                bind_annotation == BindingMode::REF_MUT,\n            ),\n        };\n\n        // Check if captures the closure will need conflict with borrows made in the scrutinee.\n        // TODO: check all the references made in the scrutinee expression. This will require interacting\n        // with the borrow checker. Currently only `<local>[.<field>]*` is checked for.\n        if as_ref || as_mut {\n            let e = peel_hir_expr_while(cond_expr, |e| match e.kind {\n                ExprKind::Field(e, _) | ExprKind::AddrOf(_, _, e) => Some(e),\n                _ => None,\n            });\n            if let ExprKind::Path(QPath::Resolved(\n                None,\n                Path {\n                    res: Res::Local(local_id),\n                    ..\n                },\n            )) = e.kind\n            {\n                match some_captures.get(local_id).or_else(|| {\n                    (method_sugg == \"map_or_else\")\n                        .then_some(())\n                        .and_then(|()| none_captures.get(local_id))\n                }) {\n                    Some(CaptureKind::Value | CaptureKind::Use | CaptureKind::Ref(Mutability::Mut)) => return None,\n                    Some(CaptureKind::Ref(Mutability::Not)) if as_mut => return None,\n                    Some(CaptureKind::Ref(Mutability::Not)) | None => (),\n                }\n            }\n        } else if !is_copy(cx, cx.typeck_results().expr_ty(expr))\n        // TODO: Cover more match cases\n            && matches!(\n                expr.kind,\n                ExprKind::Field(_, _) | ExprKind::Path(_) | ExprKind::Index(_, _, _)\n            )\n        {\n            let mut condition_visitor = ConditionVisitor {\n                cx,\n                identifiers: FxHashSet::default(),\n            };\n            condition_visitor.visit_expr(cond_expr);\n\n            let mut reference_visitor = ReferenceVisitor {\n                cx,\n                identifiers: condition_visitor.identifiers,\n            };\n            if reference_visitor.visit_expr(none_body).is_break() {\n                return None;\n            }\n        }\n\n        let some_body_ty = cx.typeck_results().expr_ty(some_body);\n        let none_body_ty = cx.typeck_results().expr_ty(none_body);\n        // Check if coercion is needed for the `None` arm. If so, we cannot suggest because it will\n        // introduce a type mismatch. A special case is when both arms have the same type, then\n        // coercion is fine.\n        if some_body_ty != none_body_ty && expr_requires_coercion(cx, none_body) {\n            return None;\n        }\n\n        let mut app = Applicability::Unspecified;\n\n        let (none_body, can_omit_arg) = match none_body.kind {\n            ExprKind::Call(call_expr, []) if !none_body.span.from_expansion() && !is_result => (call_expr, true),\n            _ => (none_body, false),\n        };\n\n        return Some(OptionOccurrence {\n            option: format_option_in_sugg(\n                Sugg::hir_with_context(cx, cond_expr, ctxt, \"..\", &mut app),\n                as_ref,\n                as_mut,\n            ),\n            method_sugg: method_sugg.to_string(),\n            some_expr: format!(\n                \"|{capture_mut}{capture_name}| {}\",\n                Sugg::hir_with_context(cx, some_body, ctxt, \"..\", &mut app),\n            ),\n            none_expr: format!(\n                \"{}{}\",\n                if method_sugg == \"map_or\" || can_omit_arg {\n                    \"\"\n                } else if is_result {\n                    \"|_| \"\n                } else {\n                    \"|| \"\n                },\n                Sugg::hir_with_context(cx, none_body, ctxt, \"..\", &mut app),\n            ),\n        });\n    }\n\n    None\n}\n\n/// This visitor looks for bindings in the <then> block that mention a local variable. Then gets the\n/// identifiers. The list of identifiers will then be used to check if the <none> block mentions the\n/// same local. See [`ReferenceVisitor`] for more.\nstruct ConditionVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    identifiers: FxHashSet<HirId>,\n}\n\nimpl<'tcx> Visitor<'tcx> for ConditionVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::All;\n\n    fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {\n        if let Res::Local(local_id) = path.res\n            && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)\n            && let PatKind::Binding(_, local_id, ..) = pat.kind\n        {\n            self.identifiers.insert(local_id);\n        }\n        walk_path(self, path);\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\n/// This visitor checks if the <none> block contains references to the local variables that are\n/// used in the <then> block. See [`ConditionVisitor`] for more.\nstruct ReferenceVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    identifiers: FxHashSet<HirId>,\n}\n\nimpl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::All;\n    type Result = ControlFlow<()>;\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> ControlFlow<()> {\n        if let ExprKind::Path(ref path) = expr.kind\n            && let QPath::Resolved(_, path) = path\n            && let Res::Local(local_id) = path.res\n            && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)\n            && let PatKind::Binding(_, local_id, ..) = pat.kind\n            && self.identifiers.contains(&local_id)\n        {\n            return ControlFlow::Break(());\n        }\n        walk_expr(self, expr)\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\nfn try_get_inner_pat_and_is_result<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<(&'tcx Pat<'tcx>, bool)> {\n    if let PatKind::TupleStruct(ref qpath, [inner_pat], ..) = pat.kind\n        && let res = cx.qpath_res(qpath, pat.hir_id)\n        && let Some(did) = res.ctor_parent(cx).opt_def_id()\n    {\n        let lang_items = cx.tcx.lang_items();\n        if Some(did) == lang_items.option_some_variant() {\n            return Some((inner_pat, false));\n        } else if Some(did) == lang_items.result_ok_variant() {\n            return Some((inner_pat, true));\n        }\n    }\n    None\n}\n\n/// If this expression is the option if let/else construct we're detecting, then\n/// this function returns an `OptionOccurrence` struct with details if\n/// this construct is found, or None if this construct is not found.\nfn detect_option_if_let_else<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<OptionOccurrence> {\n    if let Some(higher::IfLet {\n        let_pat,\n        let_expr,\n        if_then,\n        if_else: Some(if_else),\n        ..\n    }) = higher::IfLet::hir(cx, expr)\n        && !cx.typeck_results().expr_ty(expr).is_unit()\n        && !is_else_clause(cx.tcx, expr)\n    {\n        try_get_option_occurrence(cx, expr.span.ctxt(), let_pat, let_expr, if_then, if_else)\n    } else {\n        None\n    }\n}\n\nfn detect_option_match<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<OptionOccurrence> {\n    if let ExprKind::Match(ex, arms, MatchSource::Normal) = expr.kind\n        && !cx.typeck_results().expr_ty(expr).is_unit()\n        && let Some((let_pat, if_then, if_else)) = try_convert_match(cx, arms)\n    {\n        try_get_option_occurrence(cx, expr.span.ctxt(), let_pat, ex, if_then, if_else)\n    } else {\n        None\n    }\n}\n\nfn try_convert_match<'tcx>(\n    cx: &LateContext<'tcx>,\n    arms: &[Arm<'tcx>],\n) -> Option<(&'tcx Pat<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {\n    if let [first_arm, second_arm] = arms\n        && first_arm.guard.is_none()\n        && second_arm.guard.is_none()\n    {\n        return if is_none_or_err_arm(cx, second_arm) {\n            Some((first_arm.pat, first_arm.body, second_arm.body))\n        } else if is_none_or_err_arm(cx, first_arm) {\n            Some((second_arm.pat, second_arm.body, first_arm.body))\n        } else {\n            None\n        };\n    }\n    None\n}\n\nfn is_none_or_err_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {\n    match arm.pat.kind {\n        _ if is_none_pattern(cx, arm.pat) => true,\n        PatKind::TupleStruct(ref qpath, [first_pat], _) => {\n            cx.qpath_res(qpath, arm.pat.hir_id)\n                .ctor_parent(cx)\n                .is_lang_item(cx, ResultErr)\n                && matches!(first_pat.kind, PatKind::Wild)\n        },\n        PatKind::Wild => true,\n        _ => false,\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for OptionIfLetElse {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        // Don't lint macros and constants\n        if expr.span.from_expansion() || is_in_const_context(cx) {\n            return;\n        }\n\n        let detection = detect_option_if_let_else(cx, expr).or_else(|| detect_option_match(cx, expr));\n        if let Some(det) = detection {\n            span_lint_and_sugg(\n                cx,\n                OPTION_IF_LET_ELSE,\n                expr.span,\n                format!(\"use Option::{} instead of an if let/else\", det.method_sugg),\n                \"try\",\n                format!(\n                    \"{}.{}({}, {})\",\n                    det.option, det.method_sugg, det.none_expr, det.some_expr\n                ),\n                Applicability::MaybeIncorrect,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/panic_in_result_fn.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{is_panic, root_macro_call_first_node};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::visitors::{Descend, for_each_expr};\nuse clippy_utils::{is_inside_always_const_context, return_ty};\nuse core::ops::ControlFlow;\nuse rustc_hir as hir;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `panic!` or assertions in a function whose return type is `Result`.\n    ///\n    /// ### Why restrict this?\n    /// For some codebases, it is desirable for functions of type result to return an error instead of crashing. Hence panicking macros should be avoided.\n    ///\n    /// ### Known problems\n    /// Functions called from a function returning a `Result` may invoke a panicking macro. This is not checked.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn result_with_panic() -> Result<bool, String>\n    /// {\n    ///     panic!(\"error\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn result_without_panic() -> Result<bool, String> {\n    ///     Err(String::from(\"error\"))\n    /// }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub PANIC_IN_RESULT_FN,\n    restriction,\n    \"functions of type `Result<..>` that contain `panic!()` or assertion\"\n}\n\ndeclare_lint_pass!(PanicInResultFn => [PANIC_IN_RESULT_FN]);\n\nimpl<'tcx> LateLintPass<'tcx> for PanicInResultFn {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        fn_kind: FnKind<'tcx>,\n        _: &'tcx hir::FnDecl<'tcx>,\n        body: &'tcx hir::Body<'tcx>,\n        span: Span,\n        def_id: LocalDefId,\n    ) {\n        if matches!(fn_kind, FnKind::Closure) {\n            return;\n        }\n        let owner = cx.tcx.local_def_id_to_hir_id(def_id).expect_owner();\n        if return_ty(cx, owner).is_diag_item(cx, sym::Result) {\n            lint_impl_body(cx, span, body);\n        }\n    }\n}\n\nfn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, body: &'tcx hir::Body<'tcx>) {\n    let mut panics = Vec::new();\n    let _: Option<!> = for_each_expr(cx, body.value, |e| {\n        let Some(macro_call) = root_macro_call_first_node(cx, e) else {\n            return ControlFlow::Continue(Descend::Yes);\n        };\n        if !is_inside_always_const_context(cx.tcx, e.hir_id)\n            && (is_panic(cx, macro_call.def_id)\n                || matches!(\n                    cx.tcx.get_diagnostic_name(macro_call.def_id),\n                    Some(sym::assert_macro | sym::assert_eq_macro | sym::assert_ne_macro)\n                ))\n        {\n            panics.push(macro_call.span);\n            ControlFlow::Continue(Descend::No)\n        } else {\n            ControlFlow::Continue(Descend::Yes)\n        }\n    });\n    if !panics.is_empty() {\n        span_lint_and_then(\n            cx,\n            PANIC_IN_RESULT_FN,\n            impl_span,\n            \"used `panic!()` or assertion in a function that returns `Result`\",\n            move |diag| {\n                diag.help(\n                    \"`panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing\",\n                );\n                diag.span_note(panics, \"return Err() instead of panicking\");\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/panic_unimplemented.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::macros::{is_panic, root_macro_call_first_node};\nuse clippy_utils::{is_in_test, is_inside_always_const_context, sym};\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\npub struct PanicUnimplemented {\n    allow_panic_in_tests: bool,\n}\n\nimpl PanicUnimplemented {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            allow_panic_in_tests: conf.allow_panic_in_tests,\n        }\n    }\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `panic!`.\n    ///\n    /// ### Why restrict this?\n    /// This macro, or panics in general, may be unwanted in production code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// panic!(\"even with a good reason\");\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub PANIC,\n    restriction,\n    \"usage of the `panic!` macro\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `todo!`.\n    ///\n    /// ### Why restrict this?\n    /// The `todo!` macro indicates the presence of unfinished code,\n    /// so it should not be present in production code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// todo!();\n    /// ```\n    /// Finish the implementation, or consider marking it as explicitly unimplemented.\n    /// ```no_run\n    /// unimplemented!();\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub TODO,\n    restriction,\n    \"`todo!` should not be present in production code\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `unimplemented!`.\n    ///\n    /// ### Why restrict this?\n    /// This macro, or panics in general, may be unwanted in production code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// unimplemented!();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNIMPLEMENTED,\n    restriction,\n    \"`unimplemented!` should not be present in production code\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `unreachable!`.\n    ///\n    /// ### Why restrict this?\n    /// This macro, or panics in general, may be unwanted in production code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// unreachable!();\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub UNREACHABLE,\n    restriction,\n    \"usage of the `unreachable!` macro\"\n}\n\nimpl_lint_pass!(PanicUnimplemented => [PANIC, TODO, UNIMPLEMENTED, UNREACHABLE]);\n\nimpl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let Some(macro_call) = root_macro_call_first_node(cx, expr) {\n            if is_panic(cx, macro_call.def_id) {\n                if is_inside_always_const_context(cx.tcx, expr.hir_id)\n                    || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id)\n                {\n                    return;\n                }\n\n                span_lint(\n                    cx,\n                    PANIC,\n                    macro_call.span,\n                    \"`panic` should not be present in production code\",\n                );\n                return;\n            }\n            match cx.tcx.get_diagnostic_name(macro_call.def_id) {\n                Some(sym::todo_macro) => {\n                    span_lint(\n                        cx,\n                        TODO,\n                        macro_call.span,\n                        \"`todo` should not be present in production code\",\n                    );\n                },\n                Some(sym::unimplemented_macro) => {\n                    span_lint(\n                        cx,\n                        UNIMPLEMENTED,\n                        macro_call.span,\n                        \"`unimplemented` should not be present in production code\",\n                    );\n                },\n                Some(sym::unreachable_macro) => {\n                    span_lint(cx, UNREACHABLE, macro_call.span, \"usage of the `unreachable!` macro\");\n                },\n                _ => {},\n            }\n        } else if let ExprKind::Call(func, [_]) = expr.kind\n            && let ExprKind::Path(QPath::Resolved(None, expr_path)) = func.kind\n            && let Res::Def(DefKind::Fn, def_id) = expr_path.res\n            && cx.tcx.is_diagnostic_item(sym::panic_any, def_id)\n        {\n            if is_inside_always_const_context(cx.tcx, expr.hir_id)\n                || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id)\n            {\n                return;\n            }\n\n            span_lint(\n                cx,\n                PANIC,\n                expr.span,\n                \"`panic_any` should not be present in production code\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/panicking_overflow_checks.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::eq_expr_value;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects C-style underflow/overflow checks.\n    ///\n    /// ### Why is this bad?\n    /// These checks will, by default, panic in debug builds rather than check\n    /// whether the operation caused an overflow.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let a = 1i32;\n    /// # let b = 2i32;\n    /// if a + b < a {\n    ///     // handle overflow\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let a = 1i32;\n    /// # let b = 2i32;\n    /// if a.checked_add(b).is_none() {\n    ///     // handle overflow\n    /// }\n    /// ```\n    ///\n    /// Or:\n    /// ```no_run\n    /// # let a = 1i32;\n    /// # let b = 2i32;\n    /// if a.overflowing_add(b).1 {\n    ///     // handle overflow\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PANICKING_OVERFLOW_CHECKS,\n    correctness,\n    \"overflow checks which will panic in debug mode\"\n}\n\ndeclare_lint_pass!(PanickingOverflowChecks => [PANICKING_OVERFLOW_CHECKS]);\n\nimpl<'tcx> LateLintPass<'tcx> for PanickingOverflowChecks {\n    // a + b < a, a > a + b, a < a - b, a - b > a\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Binary(op, lhs, rhs) = expr.kind\n            && let (lt, gt) = match op.node {\n                BinOpKind::Lt => (lhs, rhs),\n                BinOpKind::Gt => (rhs, lhs),\n                _ => return,\n            }\n            && let ctxt = expr.span.ctxt()\n            && let (op_lhs, op_rhs, other, commutative) = match (&lt.kind, &gt.kind) {\n                (&ExprKind::Binary(op, lhs, rhs), _) if op.node == BinOpKind::Add && ctxt == lt.span.ctxt() => {\n                    (lhs, rhs, gt, true)\n                },\n                (_, &ExprKind::Binary(op, lhs, rhs)) if op.node == BinOpKind::Sub && ctxt == gt.span.ctxt() => {\n                    (lhs, rhs, lt, false)\n                },\n                _ => return,\n            }\n            && let typeck = cx.typeck_results()\n            && let ty = typeck.expr_ty(op_lhs)\n            && matches!(ty.kind(), ty::Uint(_))\n            && ty == typeck.expr_ty(op_rhs)\n            && ty == typeck.expr_ty(other)\n            && !expr.span.in_external_macro(cx.tcx.sess.source_map())\n            && (eq_expr_value(cx, op_lhs, other) || (commutative && eq_expr_value(cx, op_rhs, other)))\n        {\n            span_lint(\n                cx,\n                PANICKING_OVERFLOW_CHECKS,\n                expr.span,\n                \"you are trying to use classic C overflow conditions that will fail in Rust\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/partial_pub_fields.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::ast::{Item, ItemKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks whether some but not all fields of a `struct` are public.\n    ///\n    /// Either make all fields of a type public, or make none of them public\n    ///\n    /// ### Why restrict this?\n    /// Most types should either be:\n    /// * Abstract data types: complex objects with opaque implementation which guard\n    ///   interior invariants and expose intentionally limited API to the outside world.\n    /// * Data: relatively simple objects which group a bunch of related attributes together,\n    ///   but have no invariants.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub struct Color {\n    ///     pub r: u8,\n    ///     pub g: u8,\n    ///     b: u8,\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// pub struct Color {\n    ///     pub r: u8,\n    ///     pub g: u8,\n    ///     pub b: u8,\n    /// }\n    /// ```\n    #[clippy::version = \"1.66.0\"]\n    pub PARTIAL_PUB_FIELDS,\n    restriction,\n    \"partial fields of a struct are public\"\n}\n\ndeclare_lint_pass!(PartialPubFields => [PARTIAL_PUB_FIELDS]);\n\nimpl EarlyLintPass for PartialPubFields {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        let ItemKind::Struct(_, _, ref st) = item.kind else {\n            return;\n        };\n\n        let mut fields = st.fields().iter();\n        let Some(first_field) = fields.next() else {\n            // Empty struct.\n            return;\n        };\n        let all_pub = first_field.vis.kind.is_pub();\n        let all_priv = !all_pub;\n\n        let msg = \"mixed usage of pub and non-pub fields\";\n\n        for field in fields {\n            if all_priv && field.vis.kind.is_pub() {\n                #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                span_lint_and_then(cx, PARTIAL_PUB_FIELDS, field.vis.span, msg, |diag| {\n                    diag.help(\"consider using private field here\");\n                });\n                return;\n            } else if all_pub && !field.vis.kind.is_pub() {\n                #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                span_lint_and_then(cx, PARTIAL_PUB_FIELDS, field.vis.span, msg, |diag| {\n                    diag.help(\"consider using public field here\");\n                });\n                return;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/partialeq_ne_impl.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir;\nuse rustc_hir::{Impl, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual re-implementations of `PartialEq::ne`.\n    ///\n    /// ### Why is this bad?\n    /// `PartialEq::ne` is required to always return the\n    /// negated result of `PartialEq::eq`, which is exactly what the default\n    /// implementation does. Therefore, there should never be any need to\n    /// re-implement it.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo;\n    ///\n    /// impl PartialEq for Foo {\n    ///     fn eq(&self, other: &Foo) -> bool { true }\n    ///     fn ne(&self, other: &Foo) -> bool { !(self == other) }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PARTIALEQ_NE_IMPL,\n    complexity,\n    \"re-implementing `PartialEq::ne`\"\n}\n\ndeclare_lint_pass!(PartialEqNeImpl => [PARTIALEQ_NE_IMPL]);\n\nimpl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            items: impl_items,\n            ..\n        }) = item.kind\n            && !cx.tcx.is_automatically_derived(item.owner_id.to_def_id())\n            && let Some(eq_trait) = cx.tcx.lang_items().eq_trait()\n            && of_trait.trait_ref.path.res.def_id() == eq_trait\n        {\n            for impl_item in impl_items {\n                if cx.tcx.item_name(impl_item.owner_id) == sym::ne {\n                    span_lint_hir(\n                        cx,\n                        PARTIALEQ_NE_IMPL,\n                        impl_item.hir_id(),\n                        cx.tcx.def_span(impl_item.owner_id),\n                        \"re-implementing `PartialEq::ne` is unnecessary\",\n                    );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/partialeq_to_none.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::{peel_hir_expr_refs, peel_ref_operators, sugg};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, LangItem};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for binary comparisons to a literal `Option::None`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// A programmer checking if some `foo` is `None` via a comparison `foo == None`\n    /// is usually inspired from other programming languages (e.g. `foo is None`\n    /// in Python).\n    /// Checking if a value of type `Option<T>` is (not) equal to `None` in that\n    /// way relies on `T: PartialEq` to do the comparison, which is unneeded.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(f: Option<u32>) -> &'static str {\n    ///     if f != None { \"yay\" } else { \"nay\" }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo(f: Option<u32>) -> &'static str {\n    ///     if f.is_some() { \"yay\" } else { \"nay\" }\n    /// }\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub PARTIALEQ_TO_NONE,\n    style,\n    \"Binary comparison to `Option<T>::None` relies on `T: PartialEq`, which is unneeded\"\n}\n\ndeclare_lint_pass!(PartialeqToNone => [PARTIALEQ_TO_NONE]);\n\nimpl<'tcx> LateLintPass<'tcx> for PartialeqToNone {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        // Skip expanded code, as we have no control over it anyway...\n        if e.span.from_expansion() {\n            return;\n        }\n\n        // If the expression is of type `Option`\n        let is_ty_option = |expr: &Expr<'_>| {\n            cx.typeck_results()\n                .expr_ty(expr)\n                .peel_refs()\n                .is_diag_item(cx, sym::Option)\n        };\n\n        // If the expression is a literal `Option::None`\n        let is_none_ctor = |expr: &Expr<'_>| {\n            !expr.span.from_expansion()\n                && peel_hir_expr_refs(expr)\n                    .0\n                    .res(cx)\n                    .ctor_parent(cx)\n                    .is_lang_item(cx, LangItem::OptionNone)\n        };\n\n        let mut applicability = Applicability::MachineApplicable;\n\n        if let ExprKind::Binary(op, left_side, right_side) = e.kind {\n            // All other comparisons (e.g. `>= None`) have special meaning wrt T\n            let is_eq = match op.node {\n                BinOpKind::Eq => true,\n                BinOpKind::Ne => false,\n                _ => return,\n            };\n\n            // We are only interested in comparisons between `Option` and a literal `Option::None`\n            let scrutinee = match (\n                is_none_ctor(left_side) && is_ty_option(right_side),\n                is_none_ctor(right_side) && is_ty_option(left_side),\n            ) {\n                (true, false) => right_side,\n                (false, true) => left_side,\n                _ => return,\n            };\n\n            // Peel away refs/derefs (as long as we don't cross manual deref impls), as\n            // autoref/autoderef will take care of those\n            let sugg = format!(\n                \"{}.{}\",\n                sugg::Sugg::hir_with_applicability(cx, peel_ref_operators(cx, scrutinee), \"..\", &mut applicability)\n                    .maybe_paren(),\n                if is_eq { \"is_none()\" } else { \"is_some()\" }\n            );\n\n            span_lint_and_sugg(\n                cx,\n                PARTIALEQ_TO_NONE,\n                e.span,\n                \"binary comparison to literal `Option::None`\",\n                if is_eq {\n                    \"use `Option::is_none()` instead\"\n                } else {\n                    \"use `Option::is_some()` instead\"\n                },\n                sugg,\n                applicability,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/pass_by_ref_or_value.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy};\nuse clippy_utils::{is_self, is_self_ty};\nuse core::ops::ControlFlow;\nuse rustc_abi::ExternAbi;\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::attrs::InlineAttr;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{BindingMode, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind, find_attr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::adjustment::{Adjust, PointerCoercion};\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_middle::ty::{self, BoundVarIndexKind, RegionKind, TyCtxt};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{Span, sym};\nuse std::iter;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions taking arguments by value, where\n    /// the argument type is `Copy` and large enough to be worth considering\n    /// passing by reference. Does not trigger if the function is being exported,\n    /// because that might induce API breakage, if the parameter is declared as mutable,\n    /// or if the argument is a `self`.\n    ///\n    /// ### Why is this bad?\n    /// Arguments passed by value might result in an unnecessary\n    /// shallow copy, taking up more space in the stack and requiring a call to\n    /// `memcpy`, which can be expensive.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[derive(Clone, Copy)]\n    /// struct TooLarge([u8; 2048]);\n    ///\n    /// fn foo(v: TooLarge) {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # #[derive(Clone, Copy)]\n    /// # struct TooLarge([u8; 2048]);\n    /// fn foo(v: &TooLarge) {}\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub LARGE_TYPES_PASSED_BY_VALUE,\n    pedantic,\n    \"functions taking large arguments by value\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions taking arguments by reference, where\n    /// the argument type is `Copy` and small enough to be more efficient to always\n    /// pass by value.\n    ///\n    /// ### Why is this bad?\n    /// In many calling conventions instances of structs will\n    /// be passed through registers if they fit into two or less general purpose\n    /// registers.\n    ///\n    /// ### Known problems\n    /// This lint is target dependent, some cases will lint on 64-bit targets but\n    /// not 32-bit or lower targets.\n    ///\n    /// The configuration option `trivial_copy_size_limit` can be set to override\n    /// this limit for a project.\n    ///\n    /// This lint attempts to allow passing arguments by reference if a reference\n    /// to that argument is returned. This is implemented by comparing the lifetime\n    /// of the argument and return value for equality. However, this can cause\n    /// false positives in cases involving multiple lifetimes that are bounded by\n    /// each other.\n    ///\n    /// Also, it does not take account of other similar cases where getting memory addresses\n    /// matters; namely, returning the pointer to the argument in question,\n    /// and passing the argument, as both references and pointers,\n    /// to a function that needs the memory address. For further details, refer to\n    /// [this issue](https://github.com/rust-lang/rust-clippy/issues/5953)\n    /// that explains a real case in which this false positive\n    /// led to an **undefined behavior** introduced with unsafe code.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// fn foo(v: &u32) {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn foo(v: u32) {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TRIVIALLY_COPY_PASS_BY_REF,\n    pedantic,\n    \"functions taking small copyable arguments by reference\"\n}\n\nimpl_lint_pass!(PassByRefOrValue => [\n    LARGE_TYPES_PASSED_BY_VALUE,\n    TRIVIALLY_COPY_PASS_BY_REF,\n]);\n\npub struct PassByRefOrValue {\n    ref_min_size: u64,\n    value_max_size: u64,\n    avoid_breaking_exported_api: bool,\n}\n\nimpl PassByRefOrValue {\n    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {\n        let ref_min_size = conf\n            .trivial_copy_size_limit\n            .unwrap_or_else(|| u64::from(tcx.sess.target.pointer_width / 8));\n\n        Self {\n            ref_min_size,\n            value_max_size: conf.pass_by_value_size_limit,\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n        }\n    }\n\n    fn check_poly_fn(&self, cx: &LateContext<'_>, def_id: LocalDefId, decl: &FnDecl<'_>, span: Option<Span>) {\n        if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {\n            return;\n        }\n\n        let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity();\n        let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir_body(id));\n\n        // Gather all the lifetimes found in the output type which may affect whether\n        // `TRIVIALLY_COPY_PASS_BY_REF` should be linted.\n        let mut output_regions = FxHashSet::default();\n        let _ = for_each_top_level_late_bound_region(fn_sig.skip_binder().output(), |region| -> ControlFlow<!> {\n            output_regions.insert(region);\n            ControlFlow::Continue(())\n        });\n\n        for (index, (input, ty)) in iter::zip(\n            decl.inputs,\n            fn_sig.skip_binder().inputs().iter().map(|&ty| fn_sig.rebind(ty)),\n        )\n        .enumerate()\n        {\n            // All spans generated from a proc-macro invocation are the same...\n            match span {\n                Some(s) if s == input.span => continue,\n                _ => (),\n            }\n\n            match *ty.skip_binder().kind() {\n                ty::Ref(lt, ty, Mutability::Not) => {\n                    match lt.kind() {\n                        RegionKind::ReBound(BoundVarIndexKind::Bound(index), region)\n                            if index.as_u32() == 0 && output_regions.contains(&region) =>\n                        {\n                            continue;\n                        },\n                        // Early bound regions on functions are either from the containing item, are bounded by another\n                        // lifetime, or are used as a bound for a type or lifetime.\n                        RegionKind::ReEarlyParam(..) => continue,\n                        _ => (),\n                    }\n\n                    let ty = cx.tcx.instantiate_bound_regions_with_erased(fn_sig.rebind(ty));\n                    if is_copy(cx, ty)\n                        && let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes())\n                        && size <= self.ref_min_size\n                        && let hir::TyKind::Ref(_, MutTy { ty: decl_ty, .. }) = input.kind\n                    {\n                        if let Some(typeck) = cx.maybe_typeck_results()\n                            // Don't lint if a raw pointer is created.\n                            // TODO: Limit the check only to raw pointers to the argument (or part of the argument)\n                            //       which escape the current function.\n                            && (typeck.node_types().items().any(|(_, &ty)| ty.is_raw_ptr())\n                                || typeck\n                                    .adjustments()\n                                    .items()\n                                    .flat_map(|(_, a)| a)\n                                    .any(|a| matches!(a.kind, Adjust::Pointer(PointerCoercion::UnsafeFnPointer))))\n                        {\n                            continue;\n                        }\n                        let value_type = if fn_body.and_then(|body| body.params.get(index)).is_some_and(is_self) {\n                            \"self\".into()\n                        } else {\n                            snippet(cx, decl_ty.span, \"_\").into()\n                        };\n                        span_lint_and_sugg(\n                            cx,\n                            TRIVIALLY_COPY_PASS_BY_REF,\n                            input.span,\n                            format!(\n                                \"this argument ({size} byte) is passed by reference, but would be more efficient if passed by value (limit: {} byte)\",\n                                self.ref_min_size\n                            ),\n                            \"consider passing by value instead\",\n                            value_type,\n                            Applicability::Unspecified,\n                        );\n                    }\n                },\n\n                ty::Adt(_, _) | ty::Array(_, _) | ty::Tuple(_) => {\n                    // if function has a body and parameter is annotated with mut, ignore\n                    if let Some(param) = fn_body.and_then(|body| body.params.get(index)) {\n                        match param.pat.kind {\n                            PatKind::Binding(BindingMode::NONE, _, _, _) => {},\n                            _ => continue,\n                        }\n                    }\n                    let ty = cx.tcx.instantiate_bound_regions_with_erased(ty);\n\n                    if is_copy(cx, ty)\n                        && !is_self_ty(input)\n                        && let Some(size) = cx.layout_of(ty).ok().map(|l| l.size.bytes())\n                        && size > self.value_max_size\n                    {\n                        span_lint_and_sugg(\n                            cx,\n                            LARGE_TYPES_PASSED_BY_VALUE,\n                            input.span,\n                            format!(\n                                \"this argument ({size} byte) is passed by value, but might be more efficient if passed by reference (limit: {} byte)\",\n                                self.value_max_size\n                            ),\n                            \"consider passing by reference instead\",\n                            format!(\"&{}\", snippet(cx, input.span, \"_\")),\n                            Applicability::MaybeIncorrect,\n                        );\n                    }\n                },\n\n                _ => {},\n            }\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {\n        if item.span.from_expansion() {\n            return;\n        }\n\n        if let hir::TraitItemKind::Fn(method_sig, _) = &item.kind {\n            self.check_poly_fn(cx, item.owner_id.def_id, method_sig.decl, None);\n        }\n    }\n\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        _body: &'tcx Body<'_>,\n        span: Span,\n        def_id: LocalDefId,\n    ) {\n        if span.from_expansion() {\n            return;\n        }\n\n        let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);\n        match kind {\n            FnKind::ItemFn(.., header) => {\n                if header.abi != ExternAbi::Rust {\n                    return;\n                }\n                let attrs = cx.tcx.hir_attrs(hir_id);\n                if find_attr!(attrs, Inline(InlineAttr::Always, _)) {\n                    return;\n                }\n\n                for a in attrs {\n                    // FIXME(jdonszelmann): make part of the find_attr above\n                    if a.has_name(sym::proc_macro_derive) {\n                        return;\n                    }\n                }\n            },\n            FnKind::Method(..) => (),\n            FnKind::Closure => return,\n        }\n\n        // Exclude non-inherent impls\n        if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id)\n            && matches!(\n                item.kind,\n                ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)\n            )\n        {\n            return;\n        }\n\n        self.check_poly_fn(cx, def_id, decl, Some(span));\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/pathbuf_init_then_push.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::{SpanRangeExt, snippet};\nuse clippy_utils::sym;\nuse rustc_ast::{LitKind, StrStyle};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind, TyKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `push` immediately after creating a new `PathBuf`.\n    ///\n    /// ### Why is this bad?\n    /// Multiple `.join()` calls are usually easier to read than multiple `.push`\n    /// calls across multiple statements. It might also be possible to use\n    /// `PathBuf::from` instead.\n    ///\n    /// ### Known problems\n    /// `.join()` introduces an implicit `clone()`. `PathBuf::from` can alternatively be\n    /// used when the `PathBuf` is newly constructed. This will avoid the implicit clone.\n    ///\n    /// ### Example\n    /// ```rust\n    /// # use std::path::PathBuf;\n    /// let mut path_buf = PathBuf::new();\n    /// path_buf.push(\"foo\");\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// # use std::path::PathBuf;\n    /// let path_buf = PathBuf::from(\"foo\");\n    /// // or\n    /// let path_buf = PathBuf::new().join(\"foo\");\n    /// ```\n    #[clippy::version = \"1.82.0\"]\n    pub PATHBUF_INIT_THEN_PUSH,\n    restriction,\n    \"`push` immediately after `PathBuf` creation\"\n}\n\nimpl_lint_pass!(PathbufThenPush<'_> => [PATHBUF_INIT_THEN_PUSH]);\n\n#[derive(Default)]\npub struct PathbufThenPush<'tcx> {\n    searcher: Option<PathbufPushSearcher<'tcx>>,\n}\n\nstruct PathbufPushSearcher<'tcx> {\n    local_id: HirId,\n    lhs_is_let: bool,\n    let_ty_span: Option<Span>,\n    init_val: Expr<'tcx>,\n    arg: Option<Expr<'tcx>>,\n    name: Symbol,\n    err_span: Span,\n}\n\nimpl PathbufPushSearcher<'_> {\n    /// Try to generate a suggestion with `PathBuf::from`.\n    /// Returns `None` if the suggestion would be invalid.\n    fn gen_pathbuf_from(&self, cx: &LateContext<'_>) -> Option<String> {\n        if let ExprKind::Call(iter_expr, []) = &self.init_val.kind\n            && let ExprKind::Path(QPath::TypeRelative(ty, segment)) = &iter_expr.kind\n            && let TyKind::Path(ty_path) = &ty.kind\n            && let QPath::Resolved(None, path) = ty_path\n            && let Res::Def(_, def_id) = &path.res\n            && cx.tcx.is_diagnostic_item(sym::PathBuf, *def_id)\n            && segment.ident.name == sym::new\n            && let Some(arg) = self.arg\n            && let ExprKind::Lit(x) = arg.kind\n            && let LitKind::Str(_, StrStyle::Cooked) = x.node\n            && let Some(s) = arg.span.get_source_text(cx)\n        {\n            Some(format!(\" = PathBuf::from({s});\"))\n        } else {\n            None\n        }\n    }\n\n    fn gen_pathbuf_join(&self, cx: &LateContext<'_>) -> Option<String> {\n        let arg = self.arg?;\n        let arg_str = arg.span.get_source_text(cx)?;\n        let init_val = self.init_val.span.get_source_text(cx)?;\n        Some(format!(\" = {init_val}.join({arg_str});\"))\n    }\n\n    fn display_err(&self, cx: &LateContext<'_>) {\n        if clippy_utils::attrs::span_contains_cfg(cx, self.err_span) {\n            return;\n        }\n        let mut sugg = if self.lhs_is_let {\n            String::from(\"let mut \")\n        } else {\n            String::new()\n        };\n        sugg.push_str(self.name.as_str());\n        if let Some(span) = self.let_ty_span {\n            sugg.push_str(\": \");\n            sugg.push_str(&snippet(cx, span, \"_\"));\n        }\n        match self.gen_pathbuf_from(cx) {\n            Some(value) => {\n                sugg.push_str(&value);\n            },\n            None => {\n                if let Some(value) = self.gen_pathbuf_join(cx) {\n                    sugg.push_str(&value);\n                } else {\n                    return;\n                }\n            },\n        }\n\n        span_lint_and_sugg(\n            cx,\n            PATHBUF_INIT_THEN_PUSH,\n            self.err_span,\n            \"calls to `push` immediately after creation\",\n            \"consider using the `.join()`\",\n            sugg,\n            Applicability::HasPlaceholders,\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for PathbufThenPush<'tcx> {\n    fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {\n        self.searcher = None;\n    }\n\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {\n        if let Some(init_expr) = local.init\n            && let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind\n            && !local.span.in_external_macro(cx.sess().source_map())\n            && let ty = cx.typeck_results().pat_ty(local.pat)\n            && ty.is_diag_item(cx, sym::PathBuf)\n        {\n            self.searcher = Some(PathbufPushSearcher {\n                local_id: id,\n                lhs_is_let: true,\n                let_ty_span: local.ty.map(|ty| ty.span),\n                init_val: *init_expr,\n                arg: None,\n                name: name.name,\n                err_span: local.span,\n            });\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Assign(left, right, _) = expr.kind\n            && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind\n            && let [name] = &path.segments\n            && let Res::Local(id) = path.res\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && let ty = cx.typeck_results().expr_ty(left)\n            && ty.is_diag_item(cx, sym::PathBuf)\n        {\n            self.searcher = Some(PathbufPushSearcher {\n                local_id: id,\n                lhs_is_let: false,\n                let_ty_span: None,\n                init_val: *right,\n                arg: None,\n                name: name.ident.name,\n                err_span: expr.span,\n            });\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if let Some(mut searcher) = self.searcher.take()\n            && let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind\n            && let ExprKind::MethodCall(name, self_arg, [arg_expr], _) = expr.kind\n            && self_arg.res_local_id() == Some(searcher.local_id)\n            && name.ident.name == sym::push\n        {\n            searcher.err_span = searcher.err_span.to(stmt.span);\n            searcher.arg = Some(*arg_expr);\n            searcher.display_err(cx);\n        }\n    }\n\n    fn check_block_post(&mut self, _: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {\n        self.searcher = None;\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/pattern_type_mismatch.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_hir::{\n    Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind, intravisit,\n};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for patterns that aren't exact representations of the types\n    /// they are applied to.\n    ///\n    /// To satisfy this lint, you will have to adjust either the expression that is matched\n    /// against or the pattern itself, as well as the bindings that are introduced by the\n    /// adjusted patterns. For matching you will have to either dereference the expression\n    /// with the `*` operator, or amend the patterns to explicitly match against `&<pattern>`\n    /// or `&mut <pattern>` depending on the reference mutability. For the bindings you need\n    /// to use the inverse. You can leave them as plain bindings if you wish for the value\n    /// to be copied, but you must use `ref mut <variable>` or `ref <variable>` to construct\n    /// a reference into the matched structure.\n    ///\n    /// If you are looking for a way to learn about ownership semantics in more detail, it\n    /// is recommended to look at IDE options available to you to highlight types, lifetimes\n    /// and reference semantics in your code. The available tooling would expose these things\n    /// in a general way even outside of the various pattern matching mechanics. Of course\n    /// this lint can still be used to highlight areas of interest and ensure a good understanding\n    /// of ownership semantics.\n    ///\n    /// ### Why restrict this?\n    /// It increases ownership hints in the code, and will guard against some changes\n    /// in ownership.\n    ///\n    /// ### Example\n    /// This example shows the basic adjustments necessary to satisfy the lint. Note how\n    /// the matched expression is explicitly dereferenced with `*` and the `inner` variable\n    /// is bound to a shared borrow via `ref inner`.\n    ///\n    /// ```rust,ignore\n    /// // Bad\n    /// let value = &Some(Box::new(23));\n    /// match value {\n    ///     Some(inner) => println!(\"{}\", inner),\n    ///     None => println!(\"none\"),\n    /// }\n    ///\n    /// // Good\n    /// let value = &Some(Box::new(23));\n    /// match *value {\n    ///     Some(ref inner) => println!(\"{}\", inner),\n    ///     None => println!(\"none\"),\n    /// }\n    /// ```\n    ///\n    /// The following example demonstrates one of the advantages of the more verbose style.\n    /// Note how the second version uses `ref mut a` to explicitly declare `a` a shared mutable\n    /// borrow, while `b` is simply taken by value. This ensures that the loop body cannot\n    /// accidentally modify the wrong part of the structure.\n    ///\n    /// ```rust,ignore\n    /// // Bad\n    /// let mut values = vec![(2, 3), (3, 4)];\n    /// for (a, b) in &mut values {\n    ///     *a += *b;\n    /// }\n    ///\n    /// // Good\n    /// let mut values = vec![(2, 3), (3, 4)];\n    /// for &mut (ref mut a, b) in &mut values {\n    ///     *a += b;\n    /// }\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub PATTERN_TYPE_MISMATCH,\n    restriction,\n    \"type of pattern does not match the expression type\"\n}\n\ndeclare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]);\n\nimpl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if let StmtKind::Let(local) = stmt.kind {\n            if local.pat.span.in_external_macro(cx.sess().source_map()) {\n                return;\n            }\n            let deref_possible = match local.source {\n                LocalSource::Normal => DerefPossible::Possible,\n                _ => DerefPossible::Impossible,\n            };\n            apply_lint(cx, local.pat, deref_possible);\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Match(_, arms, _) = expr.kind {\n            // if the match is generated by an external macro, the writer does not control\n            // how the scrutinee (`match &scrutiny { ... }`) is matched\n            if expr.span.in_external_macro(cx.sess().source_map()) {\n                return;\n            }\n\n            for arm in arms {\n                let pat = &arm.pat;\n                if apply_lint(cx, pat, DerefPossible::Possible) {\n                    break;\n                }\n            }\n        }\n        if let ExprKind::Let(LetExpr { pat, .. }) = expr.kind {\n            apply_lint(cx, pat, DerefPossible::Possible);\n        }\n    }\n\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        _: intravisit::FnKind<'tcx>,\n        _: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        _: Span,\n        _: LocalDefId,\n    ) {\n        for param in body.params {\n            apply_lint(cx, param.pat, DerefPossible::Impossible);\n        }\n    }\n}\n\n#[derive(Debug, Clone, Copy)]\nenum DerefPossible {\n    Possible,\n    Impossible,\n}\n\nfn apply_lint(cx: &LateContext<'_>, pat: &Pat<'_>, deref_possible: DerefPossible) -> bool {\n    let maybe_mismatch = find_first_mismatch(cx, pat);\n    if let Some((span, mutability, level)) = maybe_mismatch {\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(\n            cx,\n            PATTERN_TYPE_MISMATCH,\n            span,\n            \"type of pattern does not match the expression type\",\n            |diag| {\n                diag.help(format!(\n                    \"{}explicitly match against a `{}` pattern and adjust the enclosed variable bindings\",\n                    match (deref_possible, level) {\n                        (DerefPossible::Possible, Level::Top) => \"use `*` to dereference the match expression or \",\n                        _ => \"\",\n                    },\n                    match mutability {\n                        Mutability::Mut => \"&mut _\",\n                        Mutability::Not => \"&_\",\n                    },\n                ));\n            },\n        );\n        true\n    } else {\n        false\n    }\n}\n\n#[derive(Debug, Copy, Clone)]\nenum Level {\n    Top,\n    Lower,\n}\n\nfn find_first_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(Span, Mutability, Level)> {\n    let mut result = None;\n    pat.walk(|p| {\n        if result.is_some() {\n            return false;\n        }\n        if p.span.in_external_macro(cx.sess().source_map()) {\n            return true;\n        }\n        let adjust_pat = match p.kind {\n            PatKind::Or([p, ..]) => p,\n            _ => p,\n        };\n        if let Some(adjustments) = cx.typeck_results().pat_adjustments().get(adjust_pat.hir_id)\n            && let [first, ..] = **adjustments\n            && let ty::Ref(.., mutability) = *first.source.kind()\n        {\n            let level = if p.hir_id == pat.hir_id {\n                Level::Top\n            } else {\n                Level::Lower\n            };\n            result = Some((p.span, mutability, level));\n        }\n        result.is_none()\n    });\n    result\n}\n"
  },
  {
    "path": "clippy_lints/src/permissions_set_readonly_false.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_ast::ast::LitKind;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `std::fs::Permissions.set_readonly` with argument `false`.\n    ///\n    /// ### Why is this bad?\n    /// On Unix platforms this results in the file being world writable,\n    /// equivalent to `chmod a+w <file>`.\n    /// ### Example\n    /// ```no_run\n    /// use std::fs::File;\n    /// let f = File::create(\"foo.txt\").unwrap();\n    /// let metadata = f.metadata().unwrap();\n    /// let mut permissions = metadata.permissions();\n    /// permissions.set_readonly(false);\n    /// ```\n    #[clippy::version = \"1.68.0\"]\n    pub PERMISSIONS_SET_READONLY_FALSE,\n    suspicious,\n    \"Checks for calls to `std::fs::Permissions.set_readonly` with argument `false`\"\n}\n\ndeclare_lint_pass!(PermissionsSetReadonlyFalse => [\n    PERMISSIONS_SET_READONLY_FALSE,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for PermissionsSetReadonlyFalse {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::MethodCall(path, receiver, [arg], _) = &expr.kind\n            && let ExprKind::Lit(lit) = &arg.kind\n            && LitKind::Bool(false) == lit.node\n            && path.ident.name == sym::set_readonly\n            && cx\n                .typeck_results()\n                .expr_ty(receiver)\n                .is_diag_item(cx, sym::FsPermissions)\n        {\n            span_lint_and_then(\n                cx,\n                PERMISSIONS_SET_READONLY_FALSE,\n                expr.span,\n                \"call to `set_readonly` with argument `false`\",\n                |diag| {\n                    diag.note(\"on Unix platforms this results in the file being world writable\");\n                    diag.help(\n                        \"you can set the desired permissions using `PermissionsExt`. For more information, see\\n\\\n                        https://doc.rust-lang.org/std/os/unix/fs/trait.PermissionsExt.html\",\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/pointers_in_nomem_asm_block.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::InlineAsmOptions;\nuse rustc_hir::{Expr, ExprKind, InlineAsm, InlineAsmOperand};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if any pointer is being passed to an asm! block with `nomem` option.\n    ///\n    /// ### Why is this bad?\n    /// `nomem` forbids any reads or writes to memory and passing a pointer suggests\n    /// that either of those will happen.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn f(p: *mut u32) {\n    ///     unsafe { core::arch::asm!(\"mov [{p}], 42\", p = in(reg) p, options(nomem, nostack)); }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn f(p: *mut u32) {\n    ///     unsafe { core::arch::asm!(\"mov [{p}], 42\", p = in(reg) p, options(nostack)); }\n    /// }\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub POINTERS_IN_NOMEM_ASM_BLOCK,\n    suspicious,\n    \"pointers in nomem asm block\"\n}\n\ndeclare_lint_pass!(PointersInNomemAsmBlock => [POINTERS_IN_NOMEM_ASM_BLOCK]);\n\nimpl<'tcx> LateLintPass<'tcx> for PointersInNomemAsmBlock {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        if let ExprKind::InlineAsm(asm) = &expr.kind {\n            check_asm(cx, asm);\n        }\n    }\n}\n\nfn check_asm(cx: &LateContext<'_>, asm: &InlineAsm<'_>) {\n    if !asm.options.contains(InlineAsmOptions::NOMEM) {\n        return;\n    }\n\n    let spans = asm\n        .operands\n        .iter()\n        .filter(|(op, _span)| has_in_operand_pointer(cx, op))\n        .map(|(_op, span)| *span)\n        .collect::<Vec<Span>>();\n\n    if spans.is_empty() {\n        return;\n    }\n\n    span_lint_and_then(\n        cx,\n        POINTERS_IN_NOMEM_ASM_BLOCK,\n        spans,\n        \"passing pointers to nomem asm block\",\n        additional_notes,\n    );\n}\n\nfn has_in_operand_pointer(cx: &LateContext<'_>, asm_op: &InlineAsmOperand<'_>) -> bool {\n    let asm_in_expr = match asm_op {\n        InlineAsmOperand::SymStatic { .. }\n        | InlineAsmOperand::Out { .. }\n        | InlineAsmOperand::Const { .. }\n        | InlineAsmOperand::SymFn { .. }\n        | InlineAsmOperand::Label { .. } => return false,\n        InlineAsmOperand::SplitInOut { in_expr, .. } => in_expr,\n        InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => expr,\n    };\n\n    // This checks for raw ptrs, refs and function pointers - the last one\n    // also technically counts as reading memory.\n    cx.typeck_results().expr_ty(asm_in_expr).is_any_ptr()\n}\n\nfn additional_notes(diag: &mut rustc_errors::Diag<'_, ()>) {\n    diag.note(\"`nomem` means that no memory write or read happens inside the asm! block\");\n    diag.note(\"if this is intentional and no pointers are read or written to, consider allowing the lint\");\n}\n"
  },
  {
    "path": "clippy_lints/src/precedence.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_ast::ast::BinOpKind::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};\nuse rustc_ast::ast::{BinOpKind, Expr, ExprKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, Lint};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::source_map::Spanned;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for operations where precedence may be unclear and suggests to add parentheses.\n    /// It catches a mixed usage of arithmetic and bit shifting/combining operators,\n    /// as well as method calls applied to closures.\n    ///\n    /// ### Why is this bad?\n    /// Not everyone knows the precedence of those operators by\n    /// heart, so expressions like these may trip others trying to reason about the\n    /// code.\n    ///\n    /// ### Example\n    /// `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PRECEDENCE,\n    complexity,\n    \"operations where precedence may be unclear\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for bit shifting operations combined with bit masking/combining operators\n    /// and suggest using parentheses.\n    ///\n    /// ### Why restrict this?\n    /// Not everyone knows the precedence of those operators by\n    /// heart, so expressions like these may trip others trying to reason about the\n    /// code.\n    ///\n    /// ### Example\n    /// `0x2345 & 0xF000 >> 12` equals 5, while `(0x2345 & 0xF000) >> 12` equals 2\n    #[clippy::version = \"1.86.0\"]\n    pub PRECEDENCE_BITS,\n    restriction,\n    \"operations mixing bit shifting with bit combining/masking\"\n}\n\ndeclare_lint_pass!(Precedence => [PRECEDENCE, PRECEDENCE_BITS]);\n\nimpl EarlyLintPass for Precedence {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.kind {\n            let span_sugg = |lint: &'static Lint, expr: &Expr, sugg, appl| {\n                span_lint_and_sugg(\n                    cx,\n                    lint,\n                    expr.span,\n                    \"operator precedence might not be obvious\",\n                    \"consider parenthesizing your expression\",\n                    sugg,\n                    appl,\n                );\n            };\n\n            if !is_bit_op(op) {\n                return;\n            }\n            let mut applicability = Applicability::MachineApplicable;\n            match (op, get_bin_opt(left), get_bin_opt(right)) {\n                (\n                    BitAnd | BitOr | BitXor,\n                    Some(left_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)),\n                    Some(right_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)),\n                )\n                | (\n                    Shl | Shr,\n                    Some(left_op @ (Add | Div | Mul | Rem | Sub)),\n                    Some(right_op @ (Add | Div | Mul | Rem | Sub)),\n                ) => {\n                    let sugg = format!(\n                        \"({}) {} ({})\",\n                        snippet_with_applicability(cx, left.span, \"..\", &mut applicability),\n                        op.as_str(),\n                        snippet_with_applicability(cx, right.span, \"..\", &mut applicability)\n                    );\n                    span_sugg(lint_for(&[op, left_op, right_op]), expr, sugg, applicability);\n                },\n                (BitAnd | BitOr | BitXor, Some(side_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)), _)\n                | (Shl | Shr, Some(side_op @ (Add | Div | Mul | Rem | Sub)), _) => {\n                    let sugg = format!(\n                        \"({}) {} {}\",\n                        snippet_with_applicability(cx, left.span, \"..\", &mut applicability),\n                        op.as_str(),\n                        snippet_with_applicability(cx, right.span, \"..\", &mut applicability)\n                    );\n                    span_sugg(lint_for(&[op, side_op]), expr, sugg, applicability);\n                },\n                (BitAnd | BitOr | BitXor, _, Some(side_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)))\n                | (Shl | Shr, _, Some(side_op @ (Add | Div | Mul | Rem | Sub))) => {\n                    let sugg = format!(\n                        \"{} {} ({})\",\n                        snippet_with_applicability(cx, left.span, \"..\", &mut applicability),\n                        op.as_str(),\n                        snippet_with_applicability(cx, right.span, \"..\", &mut applicability)\n                    );\n                    span_sugg(lint_for(&[op, side_op]), expr, sugg, applicability);\n                },\n                _ => (),\n            }\n        } else if let ExprKind::MethodCall(method_call) = &expr.kind\n            && let ExprKind::Closure(closure) = &method_call.receiver.kind\n        {\n            span_lint_and_then(cx, PRECEDENCE, expr.span, \"precedence might not be obvious\", |diag| {\n                diag.multipart_suggestion(\n                    \"consider parenthesizing the closure\",\n                    vec![\n                        (closure.fn_decl_span.shrink_to_lo(), String::from(\"(\")),\n                        (closure.body.span.shrink_to_hi(), String::from(\")\")),\n                    ],\n                    Applicability::MachineApplicable,\n                );\n            });\n        }\n    }\n}\n\nfn get_bin_opt(expr: &Expr) -> Option<BinOpKind> {\n    match expr.kind {\n        ExprKind::Binary(Spanned { node: op, .. }, _, _) => Some(op),\n        _ => None,\n    }\n}\n\n#[must_use]\nfn is_bit_op(op: BinOpKind) -> bool {\n    matches!(op, BitXor | BitAnd | BitOr | Shl | Shr)\n}\n\nfn lint_for(ops: &[BinOpKind]) -> &'static Lint {\n    if ops.iter().all(|op| is_bit_op(*op)) {\n        PRECEDENCE_BITS\n    } else {\n        PRECEDENCE\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ptr/cmp_null.rs",
    "content": "use super::CMP_NULL;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{is_lint_allowed, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    op: BinOpKind,\n    l: &Expr<'_>,\n    r: &Expr<'_>,\n) -> bool {\n    let mut applicability = Applicability::MachineApplicable;\n    let non_null_path_snippet = match (\n        is_lint_allowed(cx, CMP_NULL, expr.hir_id),\n        is_null_path(cx, l),\n        is_null_path(cx, r),\n    ) {\n        (false, true, false) => Sugg::hir_with_context(cx, r, expr.span.ctxt(), \"..\", &mut applicability).maybe_paren(),\n        (false, false, true) => Sugg::hir_with_context(cx, l, expr.span.ctxt(), \"..\", &mut applicability).maybe_paren(),\n        _ => return false,\n    };\n    let invert = if op == BinOpKind::Eq { \"\" } else { \"!\" };\n\n    span_lint_and_sugg(\n        cx,\n        CMP_NULL,\n        expr.span,\n        \"comparing with null is better expressed by the `.is_null()` method\",\n        \"try\",\n        format!(\"{invert}{non_null_path_snippet}.is_null()\"),\n        applicability,\n    );\n    true\n}\n\nfn is_null_path(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let ExprKind::Call(pathexp, []) = expr.kind {\n        matches!(\n            pathexp.basic_res().opt_diag_name(cx),\n            Some(sym::ptr_null | sym::ptr_null_mut)\n        )\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ptr/mod.rs",
    "content": "use rustc_hir::{BinOpKind, Body, Expr, ExprKind, ImplItemKind, ItemKind, Node, TraitFn, TraitItem, TraitItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\nmod cmp_null;\nmod mut_from_ref;\nmod ptr_arg;\nmod ptr_eq;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint checks for equality comparisons with `ptr::null` or `ptr::null_mut`\n    ///\n    /// ### Why is this bad?\n    /// It's easier and more readable to use the inherent\n    /// `.is_null()`\n    /// method instead\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// use std::ptr;\n    ///\n    /// if x == ptr::null() {\n    ///     // ..\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// if x.is_null() {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CMP_NULL,\n    style,\n    \"comparing a pointer to a null pointer, suggesting to use `.is_null()` instead\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint checks for functions that take immutable references and return\n    /// mutable ones. This will not trigger if no unsafe code exists as there\n    /// are multiple safe functions which will do this transformation\n    ///\n    /// To be on the conservative side, if there's at least one mutable\n    /// reference with the output lifetime, this lint will not trigger.\n    ///\n    /// ### Why is this bad?\n    /// Creating a mutable reference which can be repeatably derived from an\n    /// immutable reference is unsound as it allows creating multiple live\n    /// mutable references to the same object.\n    ///\n    /// This [error](https://github.com/rust-lang/rust/issues/39465) actually\n    /// lead to an interim Rust release 1.15.1.\n    ///\n    /// ### Known problems\n    /// This pattern is used by memory allocators to allow allocating multiple\n    /// objects while returning mutable references to each one. So long as\n    /// different mutable references are returned each time such a function may\n    /// be safe.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// fn foo(&Foo) -> &mut Bar { .. }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MUT_FROM_REF,\n    correctness,\n    \"fns that create mutable refs from immutable ref args\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint checks for function arguments of type `&String`, `&Vec`,\n    /// `&PathBuf`, and `Cow<_>`. It will also suggest you replace `.clone()` calls\n    /// with the appropriate `.to_owned()`/`to_string()` calls.\n    ///\n    /// ### Why is this bad?\n    /// Requiring the argument to be of the specific type\n    /// makes the function less useful for no benefit; slices in the form of `&[T]`\n    /// or `&str` usually suffice and can be obtained from other types, too.\n    ///\n    /// ### Known problems\n    /// There may be `fn(&Vec)`-typed references pointing to your function.\n    /// If you have them, you will get a compiler error after applying this lint's\n    /// suggestions. You then have the choice to undo your changes or change the\n    /// type of the reference.\n    ///\n    /// Note that if the function is part of your public interface, there may be\n    /// other crates referencing it, of which you may not be aware. Carefully\n    /// deprecate the function before applying the lint suggestions in this case.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// fn foo(&Vec<u32>) { .. }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```ignore\n    /// fn foo(&[u32]) { .. }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PTR_ARG,\n    style,\n    \"fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Use `std::ptr::eq` when applicable\n    ///\n    /// ### Why is this bad?\n    /// `ptr::eq` can be used to compare `&T` references\n    /// (which coerce to `*const T` implicitly) by their address rather than\n    /// comparing the values they point to.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = &[1, 2, 3];\n    /// let b = &[1, 2, 3];\n    ///\n    /// assert!(a as *const _ as usize == b as *const _ as usize);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let a = &[1, 2, 3];\n    /// let b = &[1, 2, 3];\n    ///\n    /// assert!(std::ptr::eq(a, b));\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub PTR_EQ,\n    style,\n    \"use `std::ptr::eq` when comparing raw pointers\"\n}\n\ndeclare_lint_pass!(Ptr => [CMP_NULL, MUT_FROM_REF, PTR_ARG, PTR_EQ]);\n\nimpl<'tcx> LateLintPass<'tcx> for Ptr {\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {\n        if let TraitItemKind::Fn(sig, trait_method) = &item.kind {\n            if matches!(trait_method, TraitFn::Provided(_)) {\n                // Handled by `check_body`.\n                return;\n            }\n\n            mut_from_ref::check(cx, sig, None);\n            ptr_arg::check_trait_item(cx, item.owner_id, sig);\n        }\n    }\n\n    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {\n        let mut parents = cx.tcx.hir_parent_iter(body.value.hir_id);\n        let (item_id, sig, is_trait_item) = match parents.next() {\n            Some((_, Node::Item(i))) => {\n                if let ItemKind::Fn { sig, .. } = &i.kind {\n                    (i.owner_id, sig, false)\n                } else {\n                    return;\n                }\n            },\n            Some((_, Node::ImplItem(i))) => {\n                if !matches!(parents.next(),\n                    Some((_, Node::Item(i))) if matches!(&i.kind, ItemKind::Impl(i) if i.of_trait.is_none())\n                ) {\n                    return;\n                }\n                if let ImplItemKind::Fn(sig, _) = &i.kind {\n                    (i.owner_id, sig, false)\n                } else {\n                    return;\n                }\n            },\n            Some((_, Node::TraitItem(i))) => {\n                if let TraitItemKind::Fn(sig, _) = &i.kind {\n                    (i.owner_id, sig, true)\n                } else {\n                    return;\n                }\n            },\n            _ => return,\n        };\n\n        mut_from_ref::check(cx, sig, Some(body));\n        ptr_arg::check_body(cx, body, item_id, sig, is_trait_item);\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Binary(op, l, r) = expr.kind\n            && (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne)\n        {\n            #[expect(\n                clippy::collapsible_if,\n                reason = \"the outer `if`s check the HIR, the inner ones run lints\"\n            )]\n            if !cmp_null::check(cx, expr, op.node, l, r) {\n                ptr_eq::check(cx, op.node, l, r, expr.span);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ptr/mut_from_ref.rs",
    "content": "use super::MUT_FROM_REF;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::visitors::contains_unsafe_block;\nuse rustc_errors::MultiSpan;\nuse rustc_hir::intravisit::Visitor;\nuse rustc_hir::{self as hir, Body, FnRetTy, FnSig, GenericArg, Lifetime, Mutability, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Option<&Body<'tcx>>) {\n    let FnRetTy::Return(ty) = sig.decl.output else { return };\n    for (out, mutability, out_span) in get_lifetimes(ty) {\n        if mutability != Some(Mutability::Mut) {\n            continue;\n        }\n        let out_region = cx.tcx.named_bound_var(out.hir_id);\n        // `None` if one of the types contains `&'a mut T` or `T<'a>`.\n        // Else, contains all the locations of `&'a T` types.\n        let args_immut_refs: Option<Vec<Span>> = sig\n            .decl\n            .inputs\n            .iter()\n            .flat_map(get_lifetimes)\n            .filter(|&(lt, _, _)| cx.tcx.named_bound_var(lt.hir_id) == out_region)\n            .map(|(_, mutability, span)| (mutability == Some(Mutability::Not)).then_some(span))\n            .collect();\n        if let Some(args_immut_refs) = args_immut_refs\n            && !args_immut_refs.is_empty()\n            && body.is_none_or(|body| sig.header.is_unsafe() || contains_unsafe_block(cx, body.value))\n        {\n            span_lint_and_then(\n                cx,\n                MUT_FROM_REF,\n                out_span,\n                \"mutable borrow from immutable input(s)\",\n                |diag| {\n                    let ms = MultiSpan::from_spans(args_immut_refs);\n                    diag.span_note(ms, \"immutable borrow here\");\n                },\n            );\n        }\n    }\n}\n\nstruct LifetimeVisitor<'tcx> {\n    result: Vec<(&'tcx Lifetime, Option<Mutability>, Span)>,\n}\n\nimpl<'tcx> Visitor<'tcx> for LifetimeVisitor<'tcx> {\n    fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx, hir::AmbigArg>) {\n        if let TyKind::Ref(lt, ref m) = ty.kind {\n            self.result.push((lt, Some(m.mutbl), ty.span));\n        }\n        hir::intravisit::walk_ty(self, ty);\n    }\n\n    fn visit_generic_arg(&mut self, generic_arg: &'tcx GenericArg<'tcx>) {\n        if let GenericArg::Lifetime(lt) = generic_arg {\n            self.result.push((lt, None, generic_arg.span()));\n        }\n        hir::intravisit::walk_generic_arg(self, generic_arg);\n    }\n}\n\n/// Visit `ty` and collect the all the lifetimes appearing in it, implicit or not.\n///\n/// The second field of the vector's elements indicate if the lifetime is attached to a\n/// shared reference, a mutable reference, or neither.\nfn get_lifetimes<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> Vec<(&'tcx Lifetime, Option<Mutability>, Span)> {\n    use hir::intravisit::VisitorExt as _;\n\n    let mut visitor = LifetimeVisitor { result: Vec::new() };\n    visitor.visit_ty_unambig(ty);\n    visitor.result\n}\n"
  },
  {
    "path": "clippy_lints/src/ptr/ptr_arg.rs",
    "content": "use super::PTR_ARG;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::{VEC_METHODS_SHADOWING_SLICE_METHODS, get_expr_use_or_unification_node, is_lint_allowed, sym};\nuse hir::LifetimeKind;\nuse rustc_abi::ExternAbi;\nuse rustc_errors::Applicability;\nuse rustc_hir::hir_id::{HirId, HirIdMap};\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{\n    self as hir, AnonConst, BindingMode, Body, Expr, ExprKind, FnSig, GenericArg, Lifetime, Mutability, Node, OwnerId,\n    Param, PatKind, QPath, TyKind,\n};\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_infer::traits::{Obligation, ObligationCause};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::{self, Binder, ClauseKind, ExistentialPredicate, List, PredicateKind, Ty};\nuse rustc_span::Span;\nuse rustc_span::symbol::Symbol;\nuse rustc_trait_selection::infer::InferCtxtExt as _;\nuse rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;\nuse std::{fmt, iter};\n\npub(super) fn check_body<'tcx>(\n    cx: &LateContext<'tcx>,\n    body: &Body<'tcx>,\n    item_id: OwnerId,\n    sig: &FnSig<'tcx>,\n    is_trait_item: bool,\n) {\n    if !matches!(sig.header.abi, ExternAbi::Rust) {\n        // Ignore `extern` functions with non-Rust calling conventions\n        return;\n    }\n\n    let decl = sig.decl;\n    let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder();\n    let lint_args: Vec<_> = check_fn_args(cx, sig, decl.inputs, body.params)\n        .filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not)\n        .collect();\n    let results = check_ptr_arg_usage(cx, body, &lint_args);\n\n    for (result, args) in iter::zip(&results, &lint_args).filter(|(r, _)| !r.skip) {\n        span_lint_hir_and_then(cx, PTR_ARG, args.emission_id, args.span, args.build_msg(), |diag| {\n            diag.multipart_suggestion(\n                \"change this to\",\n                iter::once((args.span, format!(\"{}{}\", args.ref_prefix, args.deref_ty.display(cx))))\n                    .chain(result.replacements.iter().map(|r| {\n                        (\n                            r.expr_span,\n                            format!(\"{}{}\", r.self_span.get_source_text(cx).unwrap(), r.replacement),\n                        )\n                    }))\n                    .collect(),\n                Applicability::Unspecified,\n            );\n        });\n    }\n}\n\npub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item_id: OwnerId, sig: &FnSig<'tcx>) {\n    if !matches!(sig.header.abi, ExternAbi::Rust) {\n        // Ignore `extern` functions with non-Rust calling conventions\n        return;\n    }\n\n    for arg in check_fn_args(\n        cx,\n        cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder(),\n        sig.decl.inputs,\n        &[],\n    )\n    .filter(|arg| arg.mutability() == Mutability::Not)\n    {\n        span_lint_hir_and_then(cx, PTR_ARG, arg.emission_id, arg.span, arg.build_msg(), |diag| {\n            diag.span_suggestion(\n                arg.span,\n                \"change this to\",\n                format!(\"{}{}\", arg.ref_prefix, arg.deref_ty.display(cx)),\n                Applicability::Unspecified,\n            );\n        });\n    }\n}\n\n#[derive(Default)]\nstruct PtrArgResult {\n    skip: bool,\n    replacements: Vec<PtrArgReplacement>,\n}\n\nstruct PtrArgReplacement {\n    expr_span: Span,\n    self_span: Span,\n    replacement: &'static str,\n}\n\nstruct PtrArg<'tcx> {\n    idx: usize,\n    emission_id: HirId,\n    span: Span,\n    ty_name: Symbol,\n    method_renames: &'static [(Symbol, &'static str)],\n    ref_prefix: RefPrefix,\n    deref_ty: DerefTy<'tcx>,\n}\nimpl PtrArg<'_> {\n    fn build_msg(&self) -> String {\n        format!(\n            \"writing `&{}{}` instead of `&{}{}` involves a new object where a slice will do\",\n            self.ref_prefix.mutability.prefix_str(),\n            self.ty_name,\n            self.ref_prefix.mutability.prefix_str(),\n            self.deref_ty.argless_str(),\n        )\n    }\n\n    fn mutability(&self) -> Mutability {\n        self.ref_prefix.mutability\n    }\n}\n\nstruct RefPrefix {\n    lt: Lifetime,\n    mutability: Mutability,\n}\nimpl fmt::Display for RefPrefix {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        use fmt::Write;\n        f.write_char('&')?;\n        if !self.lt.is_anonymous() {\n            self.lt.ident.fmt(f)?;\n            f.write_char(' ')?;\n        }\n        f.write_str(self.mutability.prefix_str())\n    }\n}\n\nstruct DerefTyDisplay<'a, 'tcx>(&'a LateContext<'tcx>, &'a DerefTy<'tcx>);\nimpl fmt::Display for DerefTyDisplay<'_, '_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        use std::fmt::Write;\n        match self.1 {\n            DerefTy::Str => f.write_str(\"str\"),\n            DerefTy::Path => f.write_str(\"Path\"),\n            DerefTy::Slice(hir_ty, ty) => {\n                f.write_char('[')?;\n                match hir_ty.and_then(|s| s.get_source_text(self.0)) {\n                    Some(s) => f.write_str(&s)?,\n                    None => ty.fmt(f)?,\n                }\n                f.write_char(']')\n            },\n        }\n    }\n}\n\nenum DerefTy<'tcx> {\n    Str,\n    Path,\n    Slice(Option<Span>, Ty<'tcx>),\n}\nimpl<'tcx> DerefTy<'tcx> {\n    fn ty(&self, cx: &LateContext<'tcx>) -> Ty<'tcx> {\n        match *self {\n            Self::Str => cx.tcx.types.str_,\n            Self::Path => Ty::new_adt(\n                cx.tcx,\n                cx.tcx.adt_def(cx.tcx.get_diagnostic_item(sym::Path).unwrap()),\n                List::empty(),\n            ),\n            Self::Slice(_, ty) => Ty::new_slice(cx.tcx, ty),\n        }\n    }\n\n    fn argless_str(&self) -> &'static str {\n        match *self {\n            Self::Str => \"str\",\n            Self::Path => \"Path\",\n            Self::Slice(..) => \"[_]\",\n        }\n    }\n\n    fn display<'a>(&'a self, cx: &'a LateContext<'tcx>) -> DerefTyDisplay<'a, 'tcx> {\n        DerefTyDisplay(cx, self)\n    }\n}\n\nfn check_fn_args<'cx, 'tcx: 'cx>(\n    cx: &'cx LateContext<'tcx>,\n    fn_sig: ty::FnSig<'tcx>,\n    hir_tys: &'tcx [hir::Ty<'tcx>],\n    params: &'tcx [Param<'tcx>],\n) -> impl Iterator<Item = PtrArg<'tcx>> + 'cx {\n    iter::zip(fn_sig.inputs(), hir_tys)\n        .enumerate()\n        .filter_map(move |(i, (ty, hir_ty))| {\n            if let ty::Ref(_, ty, mutability) = *ty.kind()\n                && let  ty::Adt(adt, args) = *ty.kind()\n                && let TyKind::Ref(lt, ref ty) = hir_ty.kind\n                && let TyKind::Path(QPath::Resolved(None, path)) = ty.ty.kind\n                // Check that the name as typed matches the actual name of the type.\n                // e.g. `fn foo(_: &Foo)` shouldn't trigger the lint when `Foo` is an alias for `Vec`\n                && let [.., name] = path.segments\n                && cx.tcx.item_name(adt.did()) == name.ident.name\n            {\n                let emission_id = params.get(i).map_or(hir_ty.hir_id, |param| param.hir_id);\n                let (method_renames, deref_ty) = match cx.tcx.get_diagnostic_name(adt.did()) {\n                    Some(sym::Vec) => (\n                        [(sym::clone, \".to_owned()\")].as_slice(),\n                        DerefTy::Slice(\n                            if let Some(name_args) = name.args\n                                && let [GenericArg::Type(ty), ..] = name_args.args\n                            {\n                                Some(ty.span)\n                            } else {\n                                None\n                            },\n                            args.type_at(0),\n                        ),\n                    ),\n                    _ if Some(adt.did()) == cx.tcx.lang_items().string() => (\n                        [(sym::clone, \".to_owned()\"), (sym::as_str, \"\")].as_slice(),\n                        DerefTy::Str,\n                    ),\n                    Some(sym::PathBuf) => (\n                        [(sym::clone, \".to_path_buf()\"), (sym::as_path, \"\")].as_slice(),\n                        DerefTy::Path,\n                    ),\n                    Some(sym::Cow) if mutability == Mutability::Not => {\n                        if let Some(name_args) = name.args\n                            && let [GenericArg::Lifetime(lifetime), ty] = name_args.args\n                        {\n                            if let LifetimeKind::Param(param_def_id) = lifetime.kind\n                                && !lifetime.is_anonymous()\n                                && fn_sig\n                                    .output()\n                                    .walk()\n                                    .filter_map(ty::GenericArg::as_region)\n                                    .filter_map(|lifetime| match lifetime.kind() {\n                                        ty::ReEarlyParam(r) => Some(\n                                            cx.tcx\n                                                .generics_of(cx.tcx.parent(param_def_id.to_def_id()))\n                                                .region_param(r, cx.tcx)\n                                                .def_id,\n                                        ),\n                                        ty::ReBound(_, r) => r.kind.get_id(),\n                                        ty::ReLateParam(r) => r.kind.get_id(),\n                                        ty::ReStatic\n                                        | ty::ReVar(_)\n                                        | ty::RePlaceholder(_)\n                                        | ty::ReErased\n                                        | ty::ReError(_) => None,\n                                    })\n                                    .any(|def_id| def_id.as_local().is_some_and(|def_id| def_id == param_def_id))\n                            {\n                                // `&Cow<'a, T>` when the return type uses 'a is okay\n                                return None;\n                            }\n\n                            span_lint_hir_and_then(\n                                cx,\n                                PTR_ARG,\n                                emission_id,\n                                hir_ty.span,\n                                \"using a reference to `Cow` is not recommended\",\n                                |diag| {\n                                    diag.span_suggestion(\n                                        hir_ty.span,\n                                        \"change this to\",\n                                        match ty.span().get_source_text(cx) {\n                                            Some(s) => format!(\"&{}{s}\", mutability.prefix_str()),\n                                            None => format!(\"&{}{}\", mutability.prefix_str(), args.type_at(1)),\n                                        },\n                                        Applicability::Unspecified,\n                                    );\n                                },\n                            );\n                        }\n                        return None;\n                    },\n                    _ => return None,\n                };\n                return Some(PtrArg {\n                    idx: i,\n                    emission_id,\n                    span: hir_ty.span,\n                    ty_name: name.ident.name,\n                    method_renames,\n                    ref_prefix: RefPrefix { lt: *lt, mutability },\n                    deref_ty,\n                });\n            }\n            None\n        })\n}\n\n#[expect(clippy::too_many_lines)]\nfn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[PtrArg<'tcx>]) -> Vec<PtrArgResult> {\n    struct V<'cx, 'tcx> {\n        cx: &'cx LateContext<'tcx>,\n        /// Map from a local id to which argument it came from (index into `Self::args` and\n        /// `Self::results`)\n        bindings: HirIdMap<usize>,\n        /// The arguments being checked.\n        args: &'cx [PtrArg<'tcx>],\n        /// The results for each argument (len should match args.len)\n        results: Vec<PtrArgResult>,\n        /// The number of arguments which can't be linted. Used to return early.\n        skip_count: usize,\n    }\n    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {\n        type NestedFilter = nested_filter::OnlyBodies;\n        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n            self.cx.tcx\n        }\n\n        fn visit_anon_const(&mut self, _: &'tcx AnonConst) {}\n\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {\n            if self.skip_count == self.args.len() {\n                return;\n            }\n\n            // Check if this is local we care about\n            let Some(&args_idx) = e.res_local_id().and_then(|id| self.bindings.get(&id)) else {\n                return walk_expr(self, e);\n            };\n            let args = &self.args[args_idx];\n            let result = &mut self.results[args_idx];\n\n            // Helper function to handle early returns.\n            let mut set_skip_flag = || {\n                if !result.skip {\n                    self.skip_count += 1;\n                }\n                result.skip = true;\n            };\n\n            match get_expr_use_or_unification_node(self.cx.tcx, e) {\n                Some((Node::Stmt(_), _)) => (),\n                Some((Node::LetStmt(l), _)) => {\n                    // Only trace simple bindings. e.g `let x = y;`\n                    if let PatKind::Binding(BindingMode::NONE, id, ident, None) = l.pat.kind\n                        // Let's not lint for the current parameter. The user may still intend to mutate\n                        // (or, if not mutate, then perhaps call a method that's not otherwise available\n                        // for) the referenced value behind the parameter through this local let binding\n                        // with the underscore being only temporary.\n                        && !ident.name.as_str().starts_with('_')\n                    {\n                        self.bindings.insert(id, args_idx);\n                    } else {\n                        set_skip_flag();\n                    }\n                },\n                Some((Node::Expr(use_expr), child_id)) => {\n                    if let ExprKind::Index(e, ..) = use_expr.kind\n                        && e.hir_id == child_id\n                    {\n                        // Indexing works with both owned and its dereferenced type\n                        return;\n                    }\n\n                    if let ExprKind::MethodCall(name, receiver, ..) = use_expr.kind\n                        && receiver.hir_id == child_id\n                    {\n                        let name = name.ident.name;\n\n                        // Check if the method can be renamed.\n                        if let Some((_, replacement)) = args.method_renames.iter().find(|&&(x, _)| x == name) {\n                            result.replacements.push(PtrArgReplacement {\n                                expr_span: use_expr.span,\n                                self_span: receiver.span,\n                                replacement,\n                            });\n                            return;\n                        }\n\n                        // Some methods exist on both `[T]` and `Vec<T>`, such as `len`, where the receiver type\n                        // doesn't coerce to a slice and our adjusted type check below isn't enough,\n                        // but it would still be valid to call with a slice\n                        if VEC_METHODS_SHADOWING_SLICE_METHODS.contains(&name) {\n                            return;\n                        }\n                    }\n\n                    // If the expression's type gets adjusted down to the deref type, we might as\n                    // well have started with that deref type -- the lint should fire\n                    let deref_ty = args.deref_ty.ty(self.cx);\n                    let adjusted_ty = self.cx.typeck_results().expr_ty_adjusted(e).peel_refs();\n                    if adjusted_ty == deref_ty {\n                        return;\n                    }\n\n                    // If the expression's type is constrained by `dyn Trait`, see if the deref\n                    // type implements the trait(s) as well, and if so, the lint should fire\n                    if let ty::Dynamic(preds, ..) = adjusted_ty.kind()\n                        && matches_preds(self.cx, deref_ty, preds)\n                    {\n                        return;\n                    }\n\n                    set_skip_flag();\n                },\n                _ => set_skip_flag(),\n            }\n        }\n    }\n\n    let mut skip_count = 0;\n    let mut results = args.iter().map(|_| PtrArgResult::default()).collect::<Vec<_>>();\n    let mut v = V {\n        cx,\n        bindings: args\n            .iter()\n            .enumerate()\n            .filter_map(|(i, arg)| {\n                let param = &body.params[arg.idx];\n                match param.pat.kind {\n                    PatKind::Binding(BindingMode::NONE, id, ident, None)\n                        if !is_lint_allowed(cx, PTR_ARG, param.hir_id)\n                            // Let's not lint for the current parameter. The user may still intend to mutate\n                            // (or, if not mutate, then perhaps call a method that's not otherwise available\n                            // for) the referenced value behind the parameter with the underscore being only\n                            // temporary.\n                            && !ident.name.as_str().starts_with('_') =>\n                    {\n                        Some((id, i))\n                    },\n                    _ => {\n                        skip_count += 1;\n                        results[i].skip = true;\n                        None\n                    },\n                }\n            })\n            .collect(),\n        args,\n        results,\n        skip_count,\n    };\n    v.visit_expr(body.value);\n    v.results\n}\n\nfn matches_preds<'tcx>(\n    cx: &LateContext<'tcx>,\n    ty: Ty<'tcx>,\n    preds: &'tcx [ty::PolyExistentialPredicate<'tcx>],\n) -> bool {\n    let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());\n    preds\n        .iter()\n        .all(|&p| match cx.tcx.instantiate_bound_regions_with_erased(p) {\n            ExistentialPredicate::Trait(p) => infcx\n                .type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.args.iter()), cx.param_env)\n                .must_apply_modulo_regions(),\n            ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(\n                cx.tcx,\n                ObligationCause::dummy(),\n                cx.param_env,\n                cx.tcx\n                    .mk_predicate(Binder::dummy(PredicateKind::Clause(ClauseKind::Projection(\n                        p.with_self_ty(cx.tcx, ty),\n                    )))),\n            )),\n            ExistentialPredicate::AutoTrait(p) => infcx\n                .type_implements_trait(p, [ty], cx.param_env)\n                .must_apply_modulo_regions(),\n        })\n}\n"
  },
  {
    "path": "clippy_lints/src/ptr/ptr_eq.rs",
    "content": "use super::PTR_EQ;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::std_or_core;\nuse clippy_utils::sugg::Sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::Span;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    op: BinOpKind,\n    left: &'tcx Expr<'_>,\n    right: &'tcx Expr<'_>,\n    span: Span,\n) {\n    if span.from_expansion() {\n        return;\n    }\n\n    // Remove one level of usize conversion if any\n    let (left, right, usize_peeled) = match (expr_as_cast_to_usize(cx, left), expr_as_cast_to_usize(cx, right)) {\n        (Some(lhs), Some(rhs)) => (lhs, rhs, true),\n        _ => (left, right, false),\n    };\n\n    // This lint concerns raw pointers\n    let (left_ty, right_ty) = (cx.typeck_results().expr_ty(left), cx.typeck_results().expr_ty(right));\n    if !left_ty.is_raw_ptr() || !right_ty.is_raw_ptr() {\n        return;\n    }\n\n    let ((left_var, left_casts_peeled), (right_var, right_casts_peeled)) =\n        (peel_raw_casts(cx, left, left_ty), peel_raw_casts(cx, right, right_ty));\n\n    if !(usize_peeled || left_casts_peeled || right_casts_peeled) {\n        return;\n    }\n\n    let mut app = Applicability::MachineApplicable;\n    let ctxt = span.ctxt();\n    let left_snip = Sugg::hir_with_context(cx, left_var, ctxt, \"_\", &mut app);\n    let right_snip = Sugg::hir_with_context(cx, right_var, ctxt, \"_\", &mut app);\n    {\n        let Some(top_crate) = std_or_core(cx) else { return };\n        let invert = if op == BinOpKind::Eq { \"\" } else { \"!\" };\n        span_lint_and_sugg(\n            cx,\n            PTR_EQ,\n            span,\n            format!(\"use `{top_crate}::ptr::eq` when comparing raw pointers\"),\n            \"try\",\n            format!(\"{invert}{top_crate}::ptr::eq({left_snip}, {right_snip})\"),\n            app,\n        );\n    }\n}\n\n// If the given expression is a cast to a usize, return the lhs of the cast\n// E.g., `foo as *const _ as usize` returns `foo as *const _`.\nfn expr_as_cast_to_usize<'tcx>(cx: &LateContext<'tcx>, cast_expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {\n    if !cast_expr.span.from_expansion()\n        && cx.typeck_results().expr_ty(cast_expr) == cx.tcx.types.usize\n        && let ExprKind::Cast(expr, _) = cast_expr.kind\n    {\n        Some(expr)\n    } else {\n        None\n    }\n}\n\n// Peel raw casts if the remaining expression can be coerced to it, and whether casts have been\n// peeled or not.\nfn peel_raw_casts<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, expr_ty: Ty<'tcx>) -> (&'tcx Expr<'tcx>, bool) {\n    if !expr.span.from_expansion()\n        && let ExprKind::Cast(inner, _) = expr.kind\n        && let ty::RawPtr(target_ty, _) = expr_ty.kind()\n        && let inner_ty = cx.typeck_results().expr_ty(inner)\n        && let ty::RawPtr(inner_target_ty, _) | ty::Ref(_, inner_target_ty, _) = inner_ty.kind()\n        && target_ty == inner_target_ty\n    {\n        (peel_raw_casts(cx, inner, inner_ty).0, true)\n    } else {\n        (expr, false)\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/pub_underscore_fields.rs",
    "content": "use clippy_config::Conf;\nuse clippy_config::types::PubUnderscoreFieldsBehaviour;\nuse clippy_utils::attrs::is_doc_hidden;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse rustc_hir::{FieldDef, Item, ItemKind, LangItem};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks whether any field of the struct is prefixed with an `_` (underscore) and also marked\n    /// `pub` (public)\n    ///\n    /// ### Why is this bad?\n    /// Fields prefixed with an `_` are inferred as unused, which suggests it should not be marked\n    /// as `pub`, because marking it as `pub` infers it will be used.\n    ///\n    /// ### Example\n    /// ```rust\n    /// struct FileHandle {\n    ///     pub _descriptor: usize,\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// struct FileHandle {\n    ///     _descriptor: usize,\n    /// }\n    /// ```\n    ///\n    /// OR\n    ///\n    /// ```rust\n    /// struct FileHandle {\n    ///     pub descriptor: usize,\n    /// }\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub PUB_UNDERSCORE_FIELDS,\n    pedantic,\n    \"struct field prefixed with underscore and marked public\"\n}\n\nimpl_lint_pass!(PubUnderscoreFields => [PUB_UNDERSCORE_FIELDS]);\n\npub struct PubUnderscoreFields {\n    behavior: PubUnderscoreFieldsBehaviour,\n}\nimpl PubUnderscoreFields {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            behavior: conf.pub_underscore_fields_behavior,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        // This lint only pertains to structs.\n        let ItemKind::Struct(_, _, variant_data) = &item.kind else {\n            return;\n        };\n\n        let is_visible = |field: &FieldDef<'_>| match self.behavior {\n            PubUnderscoreFieldsBehaviour::PubliclyExported => cx.effective_visibilities.is_reachable(field.def_id),\n            PubUnderscoreFieldsBehaviour::AllPubFields => {\n                // If there is a visibility span then the field is marked pub in some way.\n                !field.vis_span.is_empty()\n            },\n        };\n\n        for field in variant_data.fields() {\n            // Only pertains to fields that start with an underscore, and are public.\n            if field.ident.as_str().starts_with('_') && is_visible(field)\n                // We ignore fields that have `#[doc(hidden)]`.\n                && !is_doc_hidden(cx.tcx.hir_attrs(field.hir_id))\n                // We ignore fields that are `PhantomData`.\n                && !field.ty.basic_res().is_lang_item(cx, LangItem::PhantomData)\n            {\n                span_lint_hir_and_then(\n                    cx,\n                    PUB_UNDERSCORE_FIELDS,\n                    field.hir_id,\n                    field.vis_span.to(field.ident.span),\n                    \"field marked as public but also inferred as unused because it's prefixed with `_`\",\n                    |diag| {\n                        diag.help(\"consider removing the underscore, or making the field private\");\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/pub_use.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::ast::{Item, ItemKind, VisibilityKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Restricts the usage of `pub use ...`\n    ///\n    /// ### Why restrict this?\n    /// A project may wish to limit `pub use` instances to prevent\n    /// unintentional exports, or to encourage placing exported items directly in public modules.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub mod outer {\n    ///     mod inner {\n    ///         pub struct Test {}\n    ///     }\n    ///     pub use inner::Test;\n    /// }\n    ///\n    /// use outer::Test;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// pub mod outer {\n    ///     pub struct Test {}\n    /// }\n    ///\n    /// use outer::Test;\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub PUB_USE,\n    restriction,\n    \"restricts the usage of `pub use`\"\n}\n\ndeclare_lint_pass!(PubUse => [PUB_USE]);\n\nimpl EarlyLintPass for PubUse {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if let ItemKind::Use(_) = item.kind\n            && let VisibilityKind::Public = item.vis.kind\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(cx, PUB_USE, item.span, \"using `pub use`\", |diag| {\n                diag.help(\"move the exported item to a public module instead\");\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/question_mark.rs",
    "content": "use crate::manual_let_else::MANUAL_LET_ELSE;\nuse crate::question_mark_used::QUESTION_MARK_USED;\nuse clippy_config::Conf;\nuse clippy_config::types::MatchLintBehaviour;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::{implements_trait, is_copy};\nuse clippy_utils::usage::local_used_after_expr;\nuse clippy_utils::{\n    eq_expr_value, fn_def_id_with_node_args, higher, is_else_clause, is_in_const_context, is_lint_allowed,\n    pat_and_expr_can_be_question_mark, peel_blocks, peel_blocks_with_stmt, span_contains_cfg, span_contains_comment,\n    sym,\n};\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};\nuse rustc_hir::def::Res;\nuse rustc_hir::{\n    Arm, BindingMode, Block, Body, ByRef, Expr, ExprKind, FnRetTy, HirId, LetStmt, MatchSource, Mutability, Node, Pat,\n    PatKind, PathSegment, QPath, Stmt, StmtKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions that could be replaced by the `?` operator.\n    ///\n    /// ### Why is this bad?\n    /// Using the `?` operator is shorter and more idiomatic.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// if option.is_none() {\n    ///     return None;\n    /// }\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```ignore\n    /// option?;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub QUESTION_MARK,\n    style,\n    \"checks for expressions that could be replaced by the `?` operator\"\n}\n\nimpl_lint_pass!(QuestionMark => [MANUAL_LET_ELSE, QUESTION_MARK]);\n\npub struct QuestionMark {\n    pub(crate) msrv: Msrv,\n    pub(crate) matches_behaviour: MatchLintBehaviour,\n    /// Keeps track of how many try blocks we are in at any point during linting.\n    /// This allows us to answer the question \"are we inside of a try block\"\n    /// very quickly, without having to walk up the parent chain, by simply checking\n    /// if it is greater than zero.\n    /// As for why we need this in the first place: <https://github.com/rust-lang/rust-clippy/issues/8628>\n    try_block_depth_stack: Vec<u32>,\n    /// Keeps track of the number of inferred return type closures we are inside, to avoid problems\n    /// with the `Err(x.into())` expansion being ambiguous.\n    inferred_ret_closure_stack: u16,\n}\n\nimpl QuestionMark {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: conf.msrv,\n            matches_behaviour: conf.matches_for_let_else,\n            try_block_depth_stack: Vec::new(),\n            inferred_ret_closure_stack: 0,\n        }\n    }\n}\n\nenum IfBlockType<'hir> {\n    /// An `if x.is_xxx() { a } else { b } ` expression.\n    ///\n    /// Contains: `caller (x), caller_type, call_sym (is_xxx), if_then (a), if_else (b)`\n    IfIs(&'hir Expr<'hir>, Ty<'hir>, Symbol, &'hir Expr<'hir>),\n    /// An `if let Xxx(a) = b { c } else { d }` expression.\n    ///\n    /// Contains: `let_pat_qpath (Xxx), let_pat_type, let_pat_sym (a), let_expr (b), if_then (c),\n    /// if_else (d)`\n    IfLet(\n        Res,\n        Ty<'hir>,\n        Symbol,\n        &'hir Expr<'hir>,\n        &'hir Expr<'hir>,\n        Option<&'hir Expr<'hir>>,\n    ),\n}\n\nfn find_let_else_ret_expression<'hir>(block: &'hir Block<'hir>) -> Option<&'hir Expr<'hir>> {\n    if let Block {\n        stmts: [],\n        expr: Some(els),\n        ..\n    } = block\n    {\n        Some(els)\n    } else if let [stmt] = block.stmts\n        && let StmtKind::Semi(expr) = stmt.kind\n        && let ExprKind::Ret(..) = expr.kind\n    {\n        Some(expr)\n    } else {\n        None\n    }\n}\n\nfn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {\n    /// Make sure the init expr implements try trait so a valid suggestion could be given.\n    ///\n    /// Because the init expr could have the type of `&Option<T>` which does not implements `Try`.\n    ///\n    /// NB: This conveniently prevents the cause of\n    /// issue [#12412](https://github.com/rust-lang/rust-clippy/issues/12412),\n    /// since accessing an `Option` field from a borrowed struct requires borrow, such as\n    /// `&some_struct.opt`, which is type of `&Option`. And we can't suggest `&some_struct.opt?`\n    /// or `(&some_struct.opt)?` since the first one has different semantics and the later does\n    /// not implements `Try`.\n    fn init_expr_can_use_question_mark(cx: &LateContext<'_>, init_expr: &Expr<'_>) -> bool {\n        let init_ty = cx.typeck_results().expr_ty_adjusted(init_expr);\n        cx.tcx\n            .lang_items()\n            .try_trait()\n            .is_some_and(|did| implements_trait(cx, init_ty, did, &[]))\n    }\n\n    if let StmtKind::Let(LetStmt {\n        pat,\n        init: Some(init_expr),\n        els: Some(els),\n        ..\n    }) = stmt.kind\n        && init_expr_can_use_question_mark(cx, init_expr)\n        && let Some(ret) = find_let_else_ret_expression(els)\n        && let Some(inner_pat) = pat_and_expr_can_be_question_mark(cx, pat, ret)\n        && !span_contains_comment(cx, els.span)\n        && !span_contains_cfg(cx, els.span)\n    {\n        let mut applicability = Applicability::MaybeIncorrect;\n        let init_expr_str =\n            Sugg::hir_with_context(cx, init_expr, stmt.span.ctxt(), \"..\", &mut applicability).maybe_paren();\n        // Take care when binding is `ref`\n        let sugg = if let PatKind::Binding(\n            BindingMode(ByRef::Yes(_, ref_mutability), binding_mutability),\n            _hir_id,\n            ident,\n            subpattern,\n        ) = inner_pat.kind\n        {\n            let (from_method, replace_to) = match ref_mutability {\n                Mutability::Mut => (\".as_mut()\", \"&mut \"),\n                Mutability::Not => (\".as_ref()\", \"&\"),\n            };\n\n            let mutability_str = match binding_mutability {\n                Mutability::Mut => \"mut \",\n                Mutability::Not => \"\",\n            };\n\n            // Handle subpattern (@ subpattern)\n            let maybe_subpattern = match subpattern {\n                Some(Pat {\n                    kind: PatKind::Binding(BindingMode(ByRef::Yes(..), _), _, subident, None),\n                    ..\n                }) => {\n                    // avoid `&ref`\n                    // note that, because you can't have aliased, mutable references, we don't have to worry about\n                    // the outer and inner mutability being different\n                    format!(\" @ {subident}\")\n                },\n                Some(subpattern) => {\n                    let substr = snippet_with_applicability(cx, subpattern.span, \"..\", &mut applicability);\n                    format!(\" @ {replace_to}{substr}\")\n                },\n                None => String::new(),\n            };\n\n            format!(\"let {mutability_str}{ident}{maybe_subpattern} = {init_expr_str}{from_method}?;\")\n        } else {\n            let receiver_str = snippet_with_applicability(cx, inner_pat.span, \"..\", &mut applicability);\n            format!(\"let {receiver_str} = {init_expr_str}?;\")\n        };\n        span_lint_and_sugg(\n            cx,\n            QUESTION_MARK,\n            stmt.span,\n            \"this `let...else` may be rewritten with the `?` operator\",\n            \"replace it with\",\n            sugg,\n            applicability,\n        );\n    }\n}\n\nfn is_early_return(smbl: Symbol, cx: &LateContext<'_>, if_block: &IfBlockType<'_>) -> bool {\n    match *if_block {\n        IfBlockType::IfIs(caller, caller_ty, call_sym, if_then) => {\n            // If the block could be identified as `if x.is_none()/is_err()`,\n            // we then only need to check the if_then return to see if it is none/err.\n            caller_ty.is_diag_item(cx, smbl)\n                && expr_return_none_or_err(smbl, cx, if_then, caller, None)\n                && match smbl {\n                    sym::Option => call_sym == sym::is_none,\n                    sym::Result => call_sym == sym::is_err,\n                    _ => false,\n                }\n        },\n        IfBlockType::IfLet(res, let_expr_ty, let_pat_sym, let_expr, if_then, if_else) => {\n            let_expr_ty.is_diag_item(cx, smbl)\n                && match smbl {\n                    sym::Option => {\n                        // We only need to check `if let Some(x) = option` not `if let None = option`,\n                        // because the later one will be suggested as `if option.is_none()` thus causing conflict.\n                        res.ctor_parent(cx).is_lang_item(cx, OptionSome)\n                            && if_else.is_some()\n                            && expr_return_none_or_err(smbl, cx, if_else.unwrap(), let_expr, None)\n                    },\n                    sym::Result => {\n                        (res.ctor_parent(cx).is_lang_item(cx, ResultOk)\n                            && if_else.is_some()\n                            && expr_return_none_or_err(smbl, cx, if_else.unwrap(), let_expr, Some(let_pat_sym)))\n                            || res.ctor_parent(cx).is_lang_item(cx, ResultErr)\n                                && expr_return_none_or_err(smbl, cx, if_then, let_expr, Some(let_pat_sym))\n                                && if_else.is_none()\n                    },\n                    _ => false,\n                }\n        },\n    }\n}\n\nfn expr_return_none_or_err(\n    smbl: Symbol,\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    cond_expr: &Expr<'_>,\n    err_sym: Option<Symbol>,\n) -> bool {\n    match peel_blocks_with_stmt(expr).kind {\n        ExprKind::Ret(Some(ret_expr)) => expr_return_none_or_err(smbl, cx, ret_expr, cond_expr, err_sym),\n        ExprKind::Path(ref qpath) => match smbl {\n            sym::Option => cx\n                .qpath_res(qpath, expr.hir_id)\n                .ctor_parent(cx)\n                .is_lang_item(cx, OptionNone),\n            sym::Result => expr.res_local_id().is_some() && expr.res_local_id() == cond_expr.res_local_id(),\n            _ => false,\n        },\n        ExprKind::Call(call_expr, [arg]) => {\n            if smbl == sym::Result\n                && let ExprKind::Path(QPath::Resolved(_, path)) = &call_expr.kind\n                && let Some(segment) = path.segments.first()\n                && let Some(err_sym) = err_sym\n                && let ExprKind::Path(QPath::Resolved(_, arg_path)) = &arg.kind\n                && let Some(PathSegment { ident, .. }) = arg_path.segments.first()\n            {\n                return segment.ident.name == sym::Err && err_sym == ident.name;\n            }\n            false\n        },\n        _ => false,\n    }\n}\n\n/// Checks if the given expression on the given context matches the following structure:\n///\n/// ```ignore\n/// if option.is_none() {\n///     return None;\n/// }\n/// ```\n///\n/// ```ignore\n/// if result.is_err() {\n///     return result;\n/// }\n/// ```\n///\n/// If it matches, it will suggest to use the `?` operator instead\nfn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n    if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr)\n        && !is_else_clause(cx.tcx, expr)\n        && let ExprKind::MethodCall(segment, caller, [], _) = &cond.kind\n        && let caller_ty = cx.typeck_results().expr_ty(caller)\n        && let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then)\n        && (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block))\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let receiver_str = snippet_with_context(cx, caller.span, expr.span.ctxt(), \"..\", &mut applicability).0;\n        let by_ref = !cx.type_is_copy_modulo_regions(caller_ty)\n            && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));\n        let sugg = if let Some(else_inner) = r#else {\n            if eq_expr_value(cx, caller, peel_blocks(else_inner)) {\n                format!(\"Some({receiver_str}?)\")\n            } else {\n                return;\n            }\n        } else {\n            format!(\"{receiver_str}{}?;\", if by_ref { \".as_ref()\" } else { \"\" })\n        };\n\n        span_lint_and_sugg(\n            cx,\n            QUESTION_MARK,\n            expr.span,\n            \"this block may be rewritten with the `?` operator\",\n            \"replace it with\",\n            sugg,\n            applicability,\n        );\n    }\n}\n\n#[derive(Clone, Copy, Debug)]\nenum TryMode {\n    Result,\n    Option,\n}\n\nfn find_try_mode<'tcx>(cx: &LateContext<'tcx>, scrutinee: &Expr<'tcx>) -> Option<TryMode> {\n    let scrutinee_ty = cx.typeck_results().expr_ty_adjusted(scrutinee);\n    let ty::Adt(scrutinee_adt_def, _) = scrutinee_ty.kind() else {\n        return None;\n    };\n\n    match cx.tcx.get_diagnostic_name(scrutinee_adt_def.did())? {\n        sym::Result => Some(TryMode::Result),\n        sym::Option => Some(TryMode::Option),\n        _ => None,\n    }\n}\n\n// Check that `pat` is `{ctor_lang_item}(val)`, returning `val`.\nfn extract_ctor_call<'a, 'tcx>(\n    cx: &LateContext<'tcx>,\n    expected_ctor: LangItem,\n    pat: &'a Pat<'tcx>,\n) -> Option<&'a Pat<'tcx>> {\n    if let PatKind::TupleStruct(variant_path, [val_binding], _) = &pat.kind\n        && cx\n            .qpath_res(variant_path, pat.hir_id)\n            .ctor_parent(cx)\n            .is_lang_item(cx, expected_ctor)\n    {\n        Some(val_binding)\n    } else {\n        None\n    }\n}\n\n// Extracts the local ID of a plain `val` pattern.\nfn extract_binding_pat(pat: &Pat<'_>) -> Option<HirId> {\n    if let PatKind::Binding(BindingMode::NONE, binding, _, None) = pat.kind {\n        Some(binding)\n    } else {\n        None\n    }\n}\n\nfn check_arm_is_some_or_ok<'tcx>(cx: &LateContext<'tcx>, mode: TryMode, arm: &Arm<'tcx>) -> bool {\n    let happy_ctor = match mode {\n        TryMode::Result => ResultOk,\n        TryMode::Option => OptionSome,\n    };\n\n    // Check for `Ok(val)` or `Some(val)`\n    if arm.guard.is_none()\n        && let Some(val_binding) = extract_ctor_call(cx, happy_ctor, arm.pat)\n        // Extract out `val`\n        && let Some(binding) = extract_binding_pat(val_binding)\n        // Check body is just `=> val`\n        && peel_blocks(arm.body).res_local_id() == Some(binding)\n    {\n        true\n    } else {\n        false\n    }\n}\n\nfn check_arm_is_none_or_err<'tcx>(cx: &LateContext<'tcx>, mode: TryMode, arm: &Arm<'tcx>) -> bool {\n    if arm.guard.is_some() {\n        return false;\n    }\n\n    let arm_body = peel_blocks(arm.body);\n    match mode {\n        TryMode::Result => {\n            // Check that pat is Err(val)\n            if let Some(ok_pat) = extract_ctor_call(cx, ResultErr, arm.pat)\n                && let Some(ok_val) = extract_binding_pat(ok_pat)\n                // check `=> return Err(...)`\n                && let ExprKind::Ret(Some(wrapped_ret_expr)) = arm_body.kind\n                && let ExprKind::Call(ok_ctor, [ret_expr]) = wrapped_ret_expr.kind\n                && ok_ctor.res(cx).ctor_parent(cx).is_lang_item(cx, ResultErr)\n                // check if `...` is `val` from binding or `val.into()`\n                && is_local_or_local_into(cx, ret_expr, ok_val)\n            {\n                true\n            } else {\n                false\n            }\n        },\n        TryMode::Option => {\n            // Check the pat is `None`\n            if arm.pat.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)\n                // Check `=> return None`\n                && let ExprKind::Ret(Some(ret_expr)) = arm_body.kind\n                && ret_expr.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)\n                && !ret_expr.span.from_expansion()\n            {\n                true\n            } else {\n                false\n            }\n        },\n    }\n}\n\n/// Check if `expr` is `val` or `val.into()`\nfn is_local_or_local_into(cx: &LateContext<'_>, expr: &Expr<'_>, val: HirId) -> bool {\n    let is_into_call = fn_def_id_with_node_args(cx, expr)\n        .and_then(|(fn_def_id, _)| cx.tcx.trait_of_assoc(fn_def_id))\n        .is_some_and(|trait_def_id| cx.tcx.is_diagnostic_item(sym::Into, trait_def_id));\n    match expr.kind {\n        ExprKind::MethodCall(_, recv, [], _) | ExprKind::Call(_, [recv]) => {\n            is_into_call && recv.res_local_id() == Some(val)\n        },\n        _ => expr.res_local_id() == Some(val),\n    }\n}\n\nfn check_arms_are_try<'tcx>(cx: &LateContext<'tcx>, mode: TryMode, arm1: &Arm<'tcx>, arm2: &Arm<'tcx>) -> bool {\n    (check_arm_is_some_or_ok(cx, mode, arm1) && check_arm_is_none_or_err(cx, mode, arm2))\n        || (check_arm_is_some_or_ok(cx, mode, arm2) && check_arm_is_none_or_err(cx, mode, arm1))\n}\n\nfn check_if_try_match<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n    if let ExprKind::Match(scrutinee, [arm1, arm2], MatchSource::Normal | MatchSource::Postfix) = expr.kind\n        && !expr.span.from_expansion()\n        && let Some(mode) = find_try_mode(cx, scrutinee)\n        && !span_contains_cfg(cx, expr.span)\n        && check_arms_are_try(cx, mode, arm1, arm2)\n    {\n        let mut applicability = Applicability::MachineApplicable;\n        let snippet = snippet_with_applicability(cx, scrutinee.span.source_callsite(), \"..\", &mut applicability);\n\n        span_lint_and_sugg(\n            cx,\n            QUESTION_MARK,\n            expr.span,\n            \"this `match` expression can be replaced with `?`\",\n            \"try instead\",\n            snippet.into_owned() + \"?\",\n            applicability,\n        );\n    }\n}\n\nfn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n    if let Some(higher::IfLet {\n        let_pat,\n        let_expr,\n        if_then,\n        if_else,\n        ..\n    }) = higher::IfLet::hir(cx, expr)\n        && let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind\n        && ddpos.as_opt_usize().is_none()\n        && let PatKind::Binding(BindingMode(by_ref, _), bind_id, ident, None) = field.kind\n        && let caller_ty = cx.typeck_results().expr_ty(let_expr)\n        && let if_block = IfBlockType::IfLet(\n            cx.qpath_res(path1, let_pat.hir_id),\n            caller_ty,\n            ident.name,\n            let_expr,\n            if_then,\n            if_else,\n        )\n        && ((is_early_return(sym::Option, cx, &if_block) && peel_blocks(if_then).res_local_id() == Some(bind_id))\n            || is_early_return(sym::Result, cx, &if_block))\n        && if_else\n            .map(|e| eq_expr_value(cx, let_expr, peel_blocks(e)))\n            .is_none_or(|e| !e)\n    {\n        if !is_copy(cx, caller_ty)\n            && let Some(hir_id) = let_expr.res_local_id()\n            && local_used_after_expr(cx, hir_id, expr)\n        {\n            return;\n        }\n\n        let mut applicability = Applicability::MachineApplicable;\n        let receiver_str = snippet_with_applicability(cx, let_expr.span, \"..\", &mut applicability);\n        let parent = cx.tcx.parent_hir_node(expr.hir_id);\n        let requires_semi = matches!(parent, Node::Stmt(_)) || cx.typeck_results().expr_ty(expr).is_unit();\n        let method_call_str = match by_ref {\n            ByRef::Yes(_, Mutability::Mut) => \".as_mut()\",\n            ByRef::Yes(_, Mutability::Not) => \".as_ref()\",\n            ByRef::No => \"\",\n        };\n\n        let mut sugg = format!(\n            \"{receiver_str}{method_call_str}?{}\",\n            if requires_semi { \";\" } else { \"\" }\n        );\n        if is_else_clause(cx.tcx, expr) || (requires_semi && !matches!(parent, Node::Stmt(_) | Node::Block(_))) {\n            sugg = format!(\"{{ {sugg} }}\");\n        }\n\n        span_lint_and_sugg(\n            cx,\n            QUESTION_MARK,\n            expr.span,\n            \"this block may be rewritten with the `?` operator\",\n            \"replace it with\",\n            sugg,\n            applicability,\n        );\n    }\n}\n\nimpl QuestionMark {\n    fn inside_try_block(&self) -> bool {\n        self.try_block_depth_stack.last() > Some(&0)\n    }\n}\n\nfn is_try_block(cx: &LateContext<'_>, bl: &Block<'_>) -> bool {\n    if let Some(expr) = bl.expr\n        && let ExprKind::Call(callee, [_]) = expr.kind\n        && let ExprKind::Path(qpath) = callee.kind\n        && cx.tcx.qpath_is_lang_item(qpath, LangItem::TryTraitFromOutput)\n    {\n        true\n    } else {\n        false\n    }\n}\n\nfn is_inferred_ret_closure(expr: &Expr<'_>) -> bool {\n    let ExprKind::Closure(closure) = expr.kind else {\n        return false;\n    };\n\n    match closure.fn_decl.output {\n        FnRetTy::Return(ret_ty) => ret_ty.is_suggestable_infer_ty(),\n        FnRetTy::DefaultReturn(_) => true,\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for QuestionMark {\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if !is_lint_allowed(cx, QUESTION_MARK_USED, stmt.hir_id) || !self.msrv.meets(cx, msrvs::QUESTION_MARK_OPERATOR)\n        {\n            return;\n        }\n\n        if !self.inside_try_block() && !is_in_const_context(cx) {\n            check_let_some_else_return_none(cx, stmt);\n        }\n        self.check_manual_let_else(cx, stmt);\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if is_inferred_ret_closure(expr) {\n            self.inferred_ret_closure_stack += 1;\n            return;\n        }\n\n        if !self.inside_try_block()\n            && !is_in_const_context(cx)\n            && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id)\n            && self.msrv.meets(cx, msrvs::QUESTION_MARK_OPERATOR)\n        {\n            check_is_none_or_err_and_early_return(cx, expr);\n            check_if_let_some_or_err_and_early_return(cx, expr);\n\n            if self.inferred_ret_closure_stack == 0 {\n                check_if_try_match(cx, expr);\n            }\n        }\n    }\n\n    fn check_expr_post(&mut self, _: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if is_inferred_ret_closure(expr) {\n            self.inferred_ret_closure_stack -= 1;\n        }\n    }\n\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {\n        if is_try_block(cx, block) {\n            *self\n                .try_block_depth_stack\n                .last_mut()\n                .expect(\"blocks are always part of bodies and must have a depth\") += 1;\n        }\n    }\n\n    fn check_body(&mut self, _: &LateContext<'tcx>, _: &Body<'tcx>) {\n        self.try_block_depth_stack.push(0);\n    }\n\n    fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &Body<'tcx>) {\n        self.try_block_depth_stack.pop();\n    }\n\n    fn check_block_post(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {\n        if is_try_block(cx, block) {\n            *self\n                .try_block_depth_stack\n                .last_mut()\n                .expect(\"blocks are always part of bodies and must have a depth\") -= 1;\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/question_mark_used.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::span_is_local;\nuse rustc_hir::{Expr, ExprKind, MatchSource};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions that use the `?` operator and rejects them.\n    ///\n    /// ### Why restrict this?\n    /// Sometimes code wants to avoid the `?` operator because for instance a local\n    /// block requires a macro to re-throw errors to attach additional information to the\n    /// error.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// let result = expr?;\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```ignore\n    /// utility_macro!(expr);\n    /// ```\n    #[clippy::version = \"1.69.0\"]\n    pub QUESTION_MARK_USED,\n    restriction,\n    \"checks if the `?` operator is used\"\n}\n\ndeclare_lint_pass!(QuestionMarkUsed => [QUESTION_MARK_USED]);\n\nimpl<'tcx> LateLintPass<'tcx> for QuestionMarkUsed {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Match(_, _, MatchSource::TryDesugar(_)) = expr.kind {\n            if !span_is_local(expr.span) {\n                return;\n            }\n\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(cx, QUESTION_MARK_USED, expr.span, \"the `?` operator was used\", |diag| {\n                diag.help(\"consider using a custom macro or match expression\");\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ranges.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{expr_use_ctxt, fn_def_id, get_parent_expr, higher, is_in_const_context, is_integer_const, sym};\nuse rustc_ast::Mutability;\nuse rustc_ast::ast::RangeLimits;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, HirId, LangItem, Node};\nuse rustc_lint::{LateContext, LateLintPass, Lint};\nuse rustc_middle::ty::{self, ClauseKind, GenericArgKind, PredicatePolarity, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::{DesugaringKind, Span};\nuse std::cmp::Ordering;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for expressions like `x >= 3 && x < 8` that could\n    /// be more readably expressed as `(3..8).contains(x)`.\n    ///\n    /// ### Why is this bad?\n    /// `contains` expresses the intent better and has less\n    /// failure modes (such as fencepost errors or using `||` instead of `&&`).\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // given\n    /// let x = 6;\n    ///\n    /// assert!(x >= 3 && x < 8);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    ///# let x = 6;\n    /// assert!((3..8).contains(&x));\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub MANUAL_RANGE_CONTAINS,\n    style,\n    \"manually reimplementing {`Range`, `RangeInclusive`}`::contains`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for inclusive ranges where 1 is subtracted from\n    /// the upper bound, e.g., `x..=(y-1)`.\n    ///\n    /// ### Why is this bad?\n    /// The code is more readable with an exclusive range\n    /// like `x..y`.\n    ///\n    /// ### Limitations\n    /// The lint is conservative and will trigger only when switching\n    /// from an inclusive to an exclusive range is provably safe from\n    /// a typing point of view. This corresponds to situations where\n    /// the range is used as an iterator, or for indexing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 0;\n    /// # let y = 1;\n    /// for i in x..=(y-1) {\n    ///     // ..\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = 0;\n    /// # let y = 1;\n    /// for i in x..y {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub RANGE_MINUS_ONE,\n    pedantic,\n    \"`x..=(y-1)` reads better as `x..y`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for exclusive ranges where 1 is added to the\n    /// upper bound, e.g., `x..(y+1)`.\n    ///\n    /// ### Why is this bad?\n    /// The code is more readable with an inclusive range\n    /// like `x..=y`.\n    ///\n    /// ### Limitations\n    /// The lint is conservative and will trigger only when switching\n    /// from an exclusive to an inclusive range is provably safe from\n    /// a typing point of view. This corresponds to situations where\n    /// the range is used as an iterator, or for indexing.\n    ///\n    /// ### Known problems\n    /// Will add unnecessary pair of parentheses when the\n    /// expression is not wrapped in a pair but starts with an opening parenthesis\n    /// and ends with a closing one.\n    /// I.e., `let _ = (f()+1)..(f()+1)` results in `let _ = ((f()+1)..=f())`.\n    ///\n    /// Also in many cases, inclusive ranges are still slower to run than\n    /// exclusive ranges, because they essentially add an extra branch that\n    /// LLVM may fail to hoist out of the loop.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 0;\n    /// # let y = 1;\n    /// for i in x..(y+1) {\n    ///     // ..\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = 0;\n    /// # let y = 1;\n    /// for i in x..=y {\n    ///     // ..\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub RANGE_PLUS_ONE,\n    pedantic,\n    \"`x..(y+1)` reads better as `x..=y`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for range expressions `x..y` where both `x` and `y`\n    /// are constant and `x` is greater to `y`. Also triggers if `x` is equal to `y` when they are conditions to a `for` loop.\n    ///\n    /// ### Why is this bad?\n    /// Empty ranges yield no values so iterating them is a no-op.\n    /// Moreover, trying to use a reversed range to index a slice will panic at run-time.\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// fn main() {\n    ///     (10..=0).for_each(|x| println!(\"{}\", x));\n    ///\n    ///     let arr = [1, 2, 3, 4, 5];\n    ///     let sub = &arr[3..1];\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn main() {\n    ///     (0..=10).rev().for_each(|x| println!(\"{}\", x));\n    ///\n    ///     let arr = [1, 2, 3, 4, 5];\n    ///     let sub = &arr[1..3];\n    /// }\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub REVERSED_EMPTY_RANGES,\n    correctness,\n    \"reversing the limits of range expressions, resulting in empty ranges\"\n}\n\nimpl_lint_pass!(Ranges => [\n    MANUAL_RANGE_CONTAINS,\n    RANGE_MINUS_ONE,\n    RANGE_PLUS_ONE,\n    REVERSED_EMPTY_RANGES,\n]);\n\npub struct Ranges {\n    msrv: Msrv,\n}\n\nimpl Ranges {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Ranges {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Binary(ref op, l, r) = expr.kind\n            && self.msrv.meets(cx, msrvs::RANGE_CONTAINS)\n        {\n            check_possible_range_contains(cx, op.node, l, r, expr, expr.span);\n        }\n\n        check_exclusive_range_plus_one(cx, expr);\n        check_inclusive_range_minus_one(cx, expr);\n        check_reversed_empty_range(cx, expr);\n    }\n}\n\nfn check_possible_range_contains(\n    cx: &LateContext<'_>,\n    op: BinOpKind,\n    left: &Expr<'_>,\n    right: &Expr<'_>,\n    expr: &Expr<'_>,\n    span: Span,\n) {\n    if is_in_const_context(cx) {\n        return;\n    }\n\n    let combine_and = match op {\n        BinOpKind::And | BinOpKind::BitAnd => true,\n        BinOpKind::Or | BinOpKind::BitOr => false,\n        _ => return,\n    };\n    // value, name, order (higher/lower), inclusiveness\n    if let (Some(l), Some(r)) = (check_range_bounds(cx, left), check_range_bounds(cx, right)) {\n        // we only lint comparisons on the same name and with different\n        // direction\n        if l.id != r.id || l.ord == r.ord {\n            return;\n        }\n        let ord = Constant::partial_cmp(cx.tcx, cx.typeck_results().expr_ty(l.expr), &l.val, &r.val);\n        if combine_and && ord == Some(r.ord) {\n            // order lower bound and upper bound\n            let (l_span, u_span, l_inc, u_inc) = if r.ord == Ordering::Less {\n                (l.val_span, r.val_span, l.inc, r.inc)\n            } else {\n                (r.val_span, l.val_span, r.inc, l.inc)\n            };\n            // we only lint inclusive lower bounds\n            if !l_inc {\n                return;\n            }\n            let (range_type, range_op) = if u_inc {\n                (\"RangeInclusive\", \"..=\")\n            } else {\n                (\"Range\", \"..\")\n            };\n            let mut applicability = Applicability::MachineApplicable;\n            let name = snippet_with_applicability(cx, l.name_span, \"_\", &mut applicability);\n            let lo = snippet_with_applicability(cx, l_span, \"_\", &mut applicability);\n            let hi = snippet_with_applicability(cx, u_span, \"_\", &mut applicability);\n            let space = if lo.ends_with('.') { \" \" } else { \"\" };\n            span_lint_and_sugg(\n                cx,\n                MANUAL_RANGE_CONTAINS,\n                span,\n                format!(\"manual `{range_type}::contains` implementation\"),\n                \"use\",\n                format!(\"({lo}{space}{range_op}{hi}).contains(&{name})\"),\n                applicability,\n            );\n        } else if !combine_and && ord == Some(l.ord) {\n            // `!_.contains(_)`\n            // order lower bound and upper bound\n            let (l_span, u_span, l_inc, u_inc) = if l.ord == Ordering::Less {\n                (l.val_span, r.val_span, l.inc, r.inc)\n            } else {\n                (r.val_span, l.val_span, r.inc, l.inc)\n            };\n            if l_inc {\n                return;\n            }\n            let (range_type, range_op) = if u_inc {\n                (\"Range\", \"..\")\n            } else {\n                (\"RangeInclusive\", \"..=\")\n            };\n            let mut applicability = Applicability::MachineApplicable;\n            let name = snippet_with_applicability(cx, l.name_span, \"_\", &mut applicability);\n            let lo = snippet_with_applicability(cx, l_span, \"_\", &mut applicability);\n            let hi = snippet_with_applicability(cx, u_span, \"_\", &mut applicability);\n            let space = if lo.ends_with('.') { \" \" } else { \"\" };\n            span_lint_and_sugg(\n                cx,\n                MANUAL_RANGE_CONTAINS,\n                span,\n                format!(\"manual `!{range_type}::contains` implementation\"),\n                \"use\",\n                format!(\"!({lo}{space}{range_op}{hi}).contains(&{name})\"),\n                applicability,\n            );\n        }\n    }\n\n    // If the LHS is the same operator, we have to recurse to get the \"real\" RHS, since they have\n    // the same operator precedence\n    if let ExprKind::Binary(ref lhs_op, _left, new_lhs) = left.kind\n        && op == lhs_op.node\n        && let new_span = Span::new(new_lhs.span.lo(), right.span.hi(), expr.span.ctxt(), expr.span.parent())\n        && new_span.check_source_text(cx, |src| {\n            // Do not continue if we have mismatched number of parens, otherwise the suggestion is wrong\n            src.matches('(').count() == src.matches(')').count()\n        })\n    {\n        check_possible_range_contains(cx, op, new_lhs, right, expr, new_span);\n    }\n}\n\nstruct RangeBounds<'a> {\n    val: Constant,\n    expr: &'a Expr<'a>,\n    id: HirId,\n    name_span: Span,\n    val_span: Span,\n    ord: Ordering,\n    inc: bool,\n}\n\n// Takes a binary expression such as x <= 2 as input\n// Breaks apart into various pieces, such as the value of the number,\n// hir id of the variable, and direction/inclusiveness of the operator\nfn check_range_bounds<'a>(cx: &'a LateContext<'_>, ex: &'a Expr<'_>) -> Option<RangeBounds<'a>> {\n    if let ExprKind::Binary(ref op, l, r) = ex.kind {\n        let (inclusive, ordering) = match op.node {\n            BinOpKind::Gt => (false, Ordering::Greater),\n            BinOpKind::Ge => (true, Ordering::Greater),\n            BinOpKind::Lt => (false, Ordering::Less),\n            BinOpKind::Le => (true, Ordering::Less),\n            _ => return None,\n        };\n        if let Some(id) = l.res_local_id() {\n            if let Some(c) = ConstEvalCtxt::new(cx).eval(r) {\n                return Some(RangeBounds {\n                    val: c,\n                    expr: r,\n                    id,\n                    name_span: l.span,\n                    val_span: r.span,\n                    ord: ordering,\n                    inc: inclusive,\n                });\n            }\n        } else if let Some(id) = r.res_local_id()\n            && let Some(c) = ConstEvalCtxt::new(cx).eval(l)\n        {\n            return Some(RangeBounds {\n                val: c,\n                expr: l,\n                id,\n                name_span: r.span,\n                val_span: l.span,\n                ord: ordering.reverse(),\n                inc: inclusive,\n            });\n        }\n    }\n    None\n}\n\n/// Check whether `expr` could switch range types without breaking the typing requirements. This is\n/// generally the case when `expr` is used as an iterator for example, or as a slice or `&str`\n/// index.\n///\n/// FIXME: Note that the current implementation may still return false positives. A proper fix would\n/// check that the obligations are still satisfied after switching the range type.\nfn can_switch_ranges<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    original: RangeLimits,\n    inner_ty: Ty<'tcx>,\n) -> bool {\n    let use_ctxt = expr_use_ctxt(cx, expr);\n    let (Node::Expr(parent_expr), false) = (use_ctxt.node, use_ctxt.is_ty_unified) else {\n        return false;\n    };\n\n    // Check if `expr` is the argument of a compiler-generated `IntoIter::into_iter(expr)`\n    if let ExprKind::Call(func, [arg]) = parent_expr.kind\n        && arg.hir_id == use_ctxt.child_id\n        && let ExprKind::Path(qpath) = func.kind\n        && cx.tcx.qpath_is_lang_item(qpath, LangItem::IntoIterIntoIter)\n        && parent_expr.span.is_desugaring(DesugaringKind::ForLoop)\n    {\n        return true;\n    }\n\n    // Check if `expr` is used as the receiver of a method of the `Iterator`, `IntoIterator`,\n    // or `RangeBounds` traits.\n    if let ExprKind::MethodCall(_, receiver, _, _) = parent_expr.kind\n        && receiver.hir_id == use_ctxt.child_id\n        && let Some(method_did) = cx.typeck_results().type_dependent_def_id(parent_expr.hir_id)\n        && let Some(trait_did) = cx.tcx.trait_of_assoc(method_did)\n        && matches!(\n            cx.tcx.get_diagnostic_name(trait_did),\n            Some(sym::Iterator | sym::IntoIterator | sym::RangeBounds)\n        )\n    {\n        return true;\n    }\n\n    // Check if `expr` is an argument of a call which requires an `Iterator`, `IntoIterator`,\n    // or `RangeBounds` trait.\n    if let ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) = parent_expr.kind\n        && let Some(id) = fn_def_id(cx, parent_expr)\n        && let Some(arg_idx) = args.iter().position(|e| e.hir_id == use_ctxt.child_id)\n    {\n        let input_idx = if matches!(parent_expr.kind, ExprKind::MethodCall(..)) {\n            arg_idx + 1\n        } else {\n            arg_idx\n        };\n        let inputs = cx\n            .tcx\n            .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity())\n            .inputs();\n        let expr_ty = inputs[input_idx];\n        // Check that the `expr` type is present only once, otherwise modifying just one of them might be\n        // risky if they are referenced using the same generic type for example.\n        if inputs.iter().enumerate().all(|(n, ty)|\n                                         n == input_idx\n                                         || !ty.walk().any(|arg| matches!(arg.kind(),\n                                                                          GenericArgKind::Type(ty) if ty == expr_ty)))\n            // Look for a clause requiring `Iterator`, `IntoIterator`, or `RangeBounds`, and resolving to `expr_type`.\n            && cx\n                .tcx\n                .param_env(id)\n                .caller_bounds()\n                .into_iter()\n                .any(|p| {\n                    if let ClauseKind::Trait(t) = p.kind().skip_binder()\n                        && t.polarity == PredicatePolarity::Positive\n                        && matches!(\n                            cx.tcx.get_diagnostic_name(t.trait_ref.def_id),\n                            Some(sym::Iterator | sym::IntoIterator | sym::RangeBounds)\n                        )\n                    {\n                        t.self_ty() == expr_ty\n                    } else {\n                        false\n                    }\n                })\n        {\n            return true;\n        }\n    }\n\n    // Check if `expr` is used for indexing, and if the switched range type could be used\n    // as well.\n    if let ExprKind::Index(outer_expr, index, _) = parent_expr.kind\n        && index.hir_id == expr.hir_id\n        // Build the switched range type (for example `RangeInclusive<usize>`).\n        && let Some(switched_range_def_id) = match original {\n            RangeLimits::HalfOpen => cx.tcx.lang_items().range_inclusive_struct(),\n            RangeLimits::Closed => cx.tcx.lang_items().range_struct(),\n        }\n        && let switched_range_ty = cx\n            .tcx\n            .type_of(switched_range_def_id)\n            .instantiate(cx.tcx, &[inner_ty.into()])\n        // Check that the switched range type can be used for indexing the original expression\n        // through the `Index` or `IndexMut` trait.\n        && let ty::Ref(_, outer_ty, mutability) = cx.typeck_results().expr_ty_adjusted(outer_expr).kind()\n        && let Some(index_def_id) = match mutability {\n            Mutability::Not => cx.tcx.lang_items().index_trait(),\n            Mutability::Mut => cx.tcx.lang_items().index_mut_trait(),\n        }\n       && implements_trait(cx, *outer_ty, index_def_id, &[switched_range_ty.into()])\n    // We could also check that the associated item of the `index_def_id` trait with the switched range type\n    // return the same type, but it is reasonable to expect so. We can't check that the result is identical\n    // in both `Index<Range<…>>` and `Index<RangeInclusive<…>>` anyway.\n    {\n        return true;\n    }\n\n    false\n}\n\n// exclusive range plus one: `x..(y+1)`\nfn check_exclusive_range_plus_one<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n    check_range_switch(\n        cx,\n        expr,\n        RangeLimits::HalfOpen,\n        y_plus_one,\n        RANGE_PLUS_ONE,\n        \"an inclusive range would be more readable\",\n        \"..=\",\n    );\n}\n\n// inclusive range minus one: `x..=(y-1)`\nfn check_inclusive_range_minus_one<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n    check_range_switch(\n        cx,\n        expr,\n        RangeLimits::Closed,\n        y_minus_one,\n        RANGE_MINUS_ONE,\n        \"an exclusive range would be more readable\",\n        \"..\",\n    );\n}\n\n/// Check for a `kind` of range in `expr`, check for `predicate` on the end,\n/// and emit the `lint` with `msg` and the `operator`.\nfn check_range_switch<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    kind: RangeLimits,\n    predicate: impl for<'hir> FnOnce(&LateContext<'_>, &Expr<'hir>) -> Option<&'hir Expr<'hir>>,\n    lint: &'static Lint,\n    msg: &'static str,\n    operator: &str,\n) {\n    if let Some(range) = higher::Range::hir(cx, expr)\n        && let higher::Range {\n            start,\n            end: Some(end),\n            limits,\n            span,\n        } = range\n        && span.can_be_used_for_suggestions()\n        && limits == kind\n        && let Some(y) = predicate(cx, end)\n        && can_switch_ranges(cx, expr, kind, cx.typeck_results().expr_ty(y))\n    {\n        span_lint_and_then(cx, lint, span, msg, |diag| {\n            let mut app = Applicability::MachineApplicable;\n            let start = start.map_or(String::new(), |x| {\n                Sugg::hir_with_applicability(cx, x, \"<x>\", &mut app)\n                    .maybe_paren()\n                    .to_string()\n            });\n            let end = Sugg::hir_with_applicability(cx, y, \"<y>\", &mut app).maybe_paren();\n            match span.with_source_text(cx, |src| src.starts_with('(') && src.ends_with(')')) {\n                Some(true) => {\n                    diag.span_suggestion(span, \"use\", format!(\"({start}{operator}{end})\"), app);\n                },\n                Some(false) => {\n                    diag.span_suggestion(span, \"use\", format!(\"{start}{operator}{end}\"), app);\n                },\n                None => {},\n            }\n        });\n    }\n}\n\nfn check_reversed_empty_range(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    fn inside_indexing_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n        matches!(\n            get_parent_expr(cx, expr),\n            Some(Expr {\n                kind: ExprKind::Index(..),\n                ..\n            })\n        )\n    }\n\n    fn is_for_loop_arg(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n        let mut cur_expr = expr;\n        while let Some(parent_expr) = get_parent_expr(cx, cur_expr) {\n            match higher::ForLoop::hir(parent_expr) {\n                Some(higher::ForLoop { arg, .. }) if arg.hir_id == expr.hir_id => return true,\n                _ => cur_expr = parent_expr,\n            }\n        }\n\n        false\n    }\n\n    fn is_empty_range(limits: RangeLimits, ordering: Ordering) -> bool {\n        match limits {\n            RangeLimits::HalfOpen => ordering != Ordering::Less,\n            RangeLimits::Closed => ordering == Ordering::Greater,\n        }\n    }\n\n    if let Some(higher::Range {\n        start: Some(start),\n        end: Some(end),\n        limits,\n        span,\n    }) = higher::Range::hir(cx, expr)\n        && let ty = cx.typeck_results().expr_ty(start)\n        && let ty::Int(_) | ty::Uint(_) = ty.kind()\n        && let ecx = ConstEvalCtxt::new(cx)\n        && let Some(start_idx) = ecx.eval(start)\n        && let Some(end_idx) = ecx.eval(end)\n        && let Some(ordering) = Constant::partial_cmp(cx.tcx, ty, &start_idx, &end_idx)\n        && is_empty_range(limits, ordering)\n    {\n        if inside_indexing_expr(cx, expr) {\n            // Avoid linting `N..N` as it has proven to be useful, see #5689 and #5628 ...\n            if ordering != Ordering::Equal {\n                span_lint(\n                    cx,\n                    REVERSED_EMPTY_RANGES,\n                    span,\n                    \"this range is reversed and using it to index a slice will panic at run-time\",\n                );\n            }\n        // ... except in for loop arguments for backwards compatibility with `reverse_range_loop`\n        } else if ordering != Ordering::Equal || is_for_loop_arg(cx, expr) {\n            span_lint_and_then(\n                cx,\n                REVERSED_EMPTY_RANGES,\n                span,\n                \"this range is empty so it will yield no values\",\n                |diag| {\n                    if ordering != Ordering::Equal {\n                        let start_snippet = snippet(cx, start.span, \"_\");\n                        let end_snippet = snippet(cx, end.span, \"_\");\n                        let dots = match limits {\n                            RangeLimits::HalfOpen => \"..\",\n                            RangeLimits::Closed => \"..=\",\n                        };\n\n                        diag.span_suggestion(\n                            span,\n                            \"consider using the following if you are attempting to iterate over this \\\n                             range in reverse\",\n                            format!(\"({end_snippet}{dots}{start_snippet}).rev()\"),\n                            Applicability::MaybeIncorrect,\n                        );\n                    }\n                },\n            );\n        }\n    }\n}\n\nfn y_plus_one<'tcx>(cx: &LateContext<'_>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    match expr.kind {\n        ExprKind::Binary(\n            Spanned {\n                node: BinOpKind::Add, ..\n            },\n            lhs,\n            rhs,\n        ) => {\n            if is_integer_const(cx, lhs, 1) {\n                Some(rhs)\n            } else if is_integer_const(cx, rhs, 1) {\n                Some(lhs)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\nfn y_minus_one<'tcx>(cx: &LateContext<'_>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    match expr.kind {\n        ExprKind::Binary(\n            Spanned {\n                node: BinOpKind::Sub, ..\n            },\n            lhs,\n            rhs,\n        ) if is_integer_const(cx, rhs, 1) => Some(lhs),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/raw_strings.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{SpanRangeExt, snippet_opt};\nuse rustc_ast::ast::{Expr, ExprKind};\nuse rustc_ast::token::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{BytePos, Pos, Span};\nuse std::iter::once;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for raw string literals with an unnecessary amount of hashes around them.\n    ///\n    /// ### Why is this bad?\n    /// It's just unnecessary, and makes it look like there's more escaping needed than is actually\n    /// necessary.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let r = r###\"Hello, \"world\"!\"###;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let r = r#\"Hello, \"world\"!\"#;\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub NEEDLESS_RAW_STRING_HASHES,\n    pedantic,\n    \"suggests reducing the number of hashes around a raw string literal\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for raw string literals where a string literal can be used instead.\n    ///\n    /// ### Why restrict this?\n    /// For consistent style by using simpler string literals whenever possible.\n    ///\n    /// However, there are many cases where using a raw string literal is more\n    /// idiomatic than a string literal, so it's opt-in.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let r = r\"Hello, world!\";\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let r = \"Hello, world!\";\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub NEEDLESS_RAW_STRINGS,\n    restriction,\n    \"suggests using a string literal when a raw string literal is unnecessary\"\n}\n\nimpl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRINGS, NEEDLESS_RAW_STRING_HASHES]);\n\npub struct RawStrings {\n    pub allow_one_hash_in_raw_strings: bool,\n}\n\nimpl RawStrings {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            allow_one_hash_in_raw_strings: conf.allow_one_hash_in_raw_strings,\n        }\n    }\n}\n\nimpl EarlyLintPass for RawStrings {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::FormatArgs(format_args) = &expr.kind\n            && !format_args.span.in_external_macro(cx.sess().source_map())\n            && format_args.span.check_source_text(cx, |src| src.starts_with('r'))\n            && let Some(str) = snippet_opt(cx.sess(), format_args.span)\n            && let count_hash = str.bytes().skip(1).take_while(|b| *b == b'#').count()\n            && let Some(str) = str.get(count_hash + 2..str.len() - count_hash - 1)\n        {\n            self.check_raw_string(\n                cx,\n                str,\n                format_args.span,\n                \"r\",\n                u8::try_from(count_hash).unwrap(),\n                \"string\",\n            );\n        }\n\n        if let ExprKind::Lit(lit) = expr.kind\n            && let (prefix, max) = match lit.kind {\n                LitKind::StrRaw(max) => (\"r\", max),\n                LitKind::ByteStrRaw(max) => (\"br\", max),\n                LitKind::CStrRaw(max) => (\"cr\", max),\n                _ => return,\n            }\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && expr.span.check_source_text(cx, |src| src.starts_with(prefix))\n        {\n            self.check_raw_string(cx, lit.symbol.as_str(), expr.span, prefix, max, lit.kind.descr());\n        }\n    }\n}\n\nimpl RawStrings {\n    fn check_raw_string(&self, cx: &EarlyContext<'_>, str: &str, lit_span: Span, prefix: &str, max: u8, descr: &str) {\n        if !str.contains(['\\\\', '\"']) {\n            span_lint_and_then(\n                cx,\n                NEEDLESS_RAW_STRINGS,\n                lit_span,\n                \"unnecessary raw string literal\",\n                |diag| {\n                    let (start, end) = hash_spans(lit_span, prefix.len(), 0, max);\n\n                    // BytePos: skip over the `b` in `br`, we checked the prefix appears in the source text\n                    let r_pos = lit_span.lo() + BytePos::from_usize(prefix.len() - 1);\n                    let start = start.with_lo(r_pos);\n\n                    let mut remove = vec![(start, String::new())];\n                    // avoid debug ICE from empty suggestions\n                    if !end.is_empty() {\n                        remove.push((end, String::new()));\n                    }\n\n                    diag.multipart_suggestion(\n                        format!(\"use a plain {descr} literal instead\"),\n                        remove,\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n            if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS).level, rustc_lint::Allow) {\n                return;\n            }\n        }\n\n        let mut req = {\n            let mut following_quote = false;\n            let mut req = 0;\n            // `once` so a raw string ending in hashes is still checked\n            let num = str.as_bytes().iter().chain(once(&0)).try_fold(0u8, |acc, &b| {\n                match b {\n                    b'\"' if !following_quote => (following_quote, req) = (true, 1),\n                    b'#' => req += u8::from(following_quote),\n                    _ => {\n                        if following_quote {\n                            following_quote = false;\n\n                            if req == max {\n                                return ControlFlow::Break(req);\n                            }\n\n                            return ControlFlow::Continue(acc.max(req));\n                        }\n                    },\n                }\n\n                ControlFlow::Continue(acc)\n            });\n\n            match num {\n                ControlFlow::Continue(num) | ControlFlow::Break(num) => num,\n            }\n        };\n        if self.allow_one_hash_in_raw_strings {\n            req = req.max(1);\n        }\n        if req < max {\n            span_lint_and_then(\n                cx,\n                NEEDLESS_RAW_STRING_HASHES,\n                lit_span,\n                \"unnecessary hashes around raw string literal\",\n                |diag| {\n                    let (start, end) = hash_spans(lit_span, prefix.len(), req, max);\n\n                    let message = match max - req {\n                        _ if req == 0 => format!(\"remove all the hashes around the {descr} literal\"),\n                        1 => format!(\"remove one hash from both sides of the {descr} literal\"),\n                        n => format!(\"remove {n} hashes from both sides of the {descr} literal\"),\n                    };\n\n                    diag.multipart_suggestion(\n                        message,\n                        vec![(start, String::new()), (end, String::new())],\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n    }\n}\n\n/// Returns spans pointing at the unneeded hashes, e.g. for a `req` of `1` and `max` of `3`:\n///\n/// ```ignore\n/// r###\"..\"###\n///   ^^    ^^\n/// ```\nfn hash_spans(literal_span: Span, prefix_len: usize, req: u8, max: u8) -> (Span, Span) {\n    let literal_span = literal_span.data();\n\n    // BytePos: we checked prefix appears literally in the source text\n    let hash_start = literal_span.lo + BytePos::from_usize(prefix_len);\n    let hash_end = literal_span.hi;\n\n    // BytePos: req/max are counts of the ASCII character #\n    let start = Span::new(\n        hash_start + BytePos(req.into()),\n        hash_start + BytePos(max.into()),\n        literal_span.ctxt,\n        None,\n    );\n    let end = Span::new(\n        hash_end - BytePos(req.into()),\n        hash_end - BytePos(max.into()),\n        literal_span.ctxt,\n        None,\n    );\n\n    (start, end)\n}\n"
  },
  {
    "path": "clippy_lints/src/rc_clone_in_vec_init.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::VecArgs;\nuse clippy_utils::macros::root_macro_call_first_node;\nuse clippy_utils::source::{indent_of, snippet};\nuse clippy_utils::{last_path_segment, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath, TyKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for reference-counted pointers (`Arc`, `Rc`, `rc::Weak`, and `sync::Weak`)\n    /// in `vec![elem; len]`\n    ///\n    /// ### Why is this bad?\n    /// This will create `elem` once and clone it `len` times - doing so with `Arc`/`Rc`/`Weak`\n    /// is a bit misleading, as it will create references to the same pointer, rather\n    /// than different instances.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let v = vec![std::sync::Arc::new(\"some data\".to_string()); 100];\n    /// // or\n    /// let v = vec![std::rc::Rc::new(\"some data\".to_string()); 100];\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// // Initialize each value separately:\n    /// let mut data = Vec::with_capacity(100);\n    /// for _ in 0..100 {\n    ///     data.push(std::rc::Rc::new(\"some data\".to_string()));\n    /// }\n    ///\n    /// // Or if you want clones of the same reference,\n    /// // Create the reference beforehand to clarify that\n    /// // it should be cloned for each value\n    /// let data = std::rc::Rc::new(\"some data\".to_string());\n    /// let v = vec![data; 100];\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub RC_CLONE_IN_VEC_INIT,\n    suspicious,\n    \"initializing reference-counted pointer in `vec![elem; len]`\"\n}\n\ndeclare_lint_pass!(RcCloneInVecInit => [RC_CLONE_IN_VEC_INIT]);\n\nimpl LateLintPass<'_> for RcCloneInVecInit {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {\n            return;\n        };\n        let Some(VecArgs::Repeat(elem, len)) = VecArgs::hir(cx, expr) else {\n            return;\n        };\n        let Some((symbol, func_span)) = ref_init(cx, elem) else {\n            return;\n        };\n\n        emit_lint(cx, symbol, macro_call.span, elem, len, func_span);\n    }\n}\n\nfn loop_init_suggestion(elem: &str, len: &str, indent: &str) -> String {\n    format!(\n        r\"{{\n{indent}    let mut v = Vec::with_capacity({len});\n{indent}    (0..{len}).for_each(|_| v.push({elem}));\n{indent}    v\n{indent}}}\"\n    )\n}\n\nfn extract_suggestion(elem: &str, len: &str, indent: &str) -> String {\n    format!(\n        \"{{\n{indent}    let data = {elem};\n{indent}    vec![data; {len}]\n{indent}}}\"\n    )\n}\n\nfn emit_lint(cx: &LateContext<'_>, symbol: Symbol, lint_span: Span, elem: &Expr<'_>, len: &Expr<'_>, func_span: Span) {\n    let symbol_name = symbol.as_str();\n\n    span_lint_and_then(\n        cx,\n        RC_CLONE_IN_VEC_INIT,\n        lint_span,\n        \"initializing a reference-counted pointer in `vec![elem; len]`\",\n        |diag| {\n            let len_snippet = snippet(cx, len.span, \"..\");\n            let elem_snippet = format!(\"{}(..)\", snippet(cx, elem.span.with_hi(func_span.hi()), \"..\"));\n            let indentation = \" \".repeat(indent_of(cx, lint_span).unwrap_or(0));\n            let loop_init_suggestion = loop_init_suggestion(&elem_snippet, len_snippet.as_ref(), &indentation);\n            let extract_suggestion = extract_suggestion(&elem_snippet, len_snippet.as_ref(), &indentation);\n\n            diag.note(format!(\"each element will point to the same `{symbol_name}` instance\"));\n            diag.span_suggestion(\n                lint_span,\n                format!(\"consider initializing each `{symbol_name}` element individually\"),\n                loop_init_suggestion,\n                Applicability::HasPlaceholders,\n            );\n            diag.span_suggestion(\n                lint_span,\n                format!(\n                    \"or if this is intentional, consider extracting the `{symbol_name}` initialization to a variable\"\n                ),\n                extract_suggestion,\n                Applicability::HasPlaceholders,\n            );\n        },\n    );\n}\n\n/// Checks whether the given `expr` is a call to `Arc::new`, `Rc::new`, or evaluates to a `Weak`\nfn ref_init(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(Symbol, Span)> {\n    if let ExprKind::Call(func, _args) = expr.kind\n        && let ExprKind::Path(ref func_path @ QPath::TypeRelative(ty, _)) = func.kind\n        && let TyKind::Path(ref ty_path) = ty.kind\n        && let Some(def_id) = cx.qpath_res(ty_path, ty.hir_id).opt_def_id()\n    {\n        if last_path_segment(func_path).ident.name == sym::new\n            && let Some(symbol) = cx\n                .tcx\n                .get_diagnostic_name(def_id)\n                .filter(|symbol| symbol == &sym::Arc || symbol == &sym::Rc)\n        {\n            return Some((symbol, func.span));\n        }\n\n        if let ty::Adt(adt, _) = *cx.typeck_results().expr_ty(expr).kind()\n            && matches!(cx.tcx.get_diagnostic_name(adt.did()), Some(sym::RcWeak | sym::ArcWeak))\n        {\n            return Some((sym::Weak, func.span));\n        }\n    }\n\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/read_zero_byte_vec.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};\nuse clippy_utils::higher::{VecInitKind, get_vec_init_kind};\nuse clippy_utils::source::{indent_of, snippet};\nuse clippy_utils::{get_enclosing_block, sym};\n\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{self as hir, Expr, ExprKind, HirId, LetStmt, PatKind, PathSegment, QPath, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint catches reads into a zero-length `Vec`.\n    /// Especially in the case of a call to `with_capacity`, this lint warns that read\n    /// gets the number of bytes from the `Vec`'s length, not its capacity.\n    ///\n    /// ### Why is this bad?\n    /// Reading zero bytes is almost certainly not the intended behavior.\n    ///\n    /// ### Known problems\n    /// In theory, a very unusual read implementation could assign some semantic meaning\n    /// to zero-byte reads. But it seems exceptionally unlikely that code intending to do\n    /// a zero-byte read would allocate a `Vec` for it.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::io;\n    /// fn foo<F: io::Read>(mut f: F) {\n    ///     let mut data = Vec::with_capacity(100);\n    ///     f.read(&mut data).unwrap();\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::io;\n    /// fn foo<F: io::Read>(mut f: F) {\n    ///     let mut data = Vec::with_capacity(100);\n    ///     data.resize(100, 0);\n    ///     f.read(&mut data).unwrap();\n    /// }\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub READ_ZERO_BYTE_VEC,\n    nursery,\n    \"checks for reads into a zero-length `Vec`\"\n}\n\ndeclare_lint_pass!(ReadZeroByteVec => [READ_ZERO_BYTE_VEC]);\n\nimpl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &hir::Block<'tcx>) {\n        for stmt in block.stmts {\n            if stmt.span.from_expansion() {\n                return;\n            }\n\n            if let StmtKind::Let(local) = stmt.kind\n                && let LetStmt {\n                    pat, init: Some(init), ..\n                } = local\n                && let PatKind::Binding(_, id, ident, _) = pat.kind\n                && let Some(vec_init_kind) = get_vec_init_kind(cx, init)\n            {\n                let mut visitor = ReadVecVisitor {\n                    local_id: id,\n                    read_zero_expr: None,\n                    has_resize: false,\n                };\n\n                let Some(enclosing_block) = get_enclosing_block(cx, id) else {\n                    return;\n                };\n                visitor.visit_block(enclosing_block);\n\n                if let Some(expr) = visitor.read_zero_expr {\n                    let applicability = Applicability::MaybeIncorrect;\n                    match vec_init_kind {\n                        VecInitKind::WithConstCapacity(len) => span_lint_hir_and_then(\n                            cx,\n                            READ_ZERO_BYTE_VEC,\n                            expr.hir_id,\n                            expr.span,\n                            \"reading zero byte data to `Vec`\",\n                            |diag| {\n                                let span = first_stmt_containing_expr(cx, expr).map_or(expr.span, |stmt| stmt.span);\n                                let indent = indent_of(cx, span).unwrap_or(0);\n                                diag.span_suggestion(\n                                    span.shrink_to_lo(),\n                                    \"try\",\n                                    format!(\"{ident}.resize({len}, 0);\\n{}\", \" \".repeat(indent)),\n                                    applicability,\n                                );\n                            },\n                        ),\n                        VecInitKind::WithExprCapacity(hir_id) => {\n                            let e = cx.tcx.hir_expect_expr(hir_id);\n                            span_lint_hir_and_then(\n                                cx,\n                                READ_ZERO_BYTE_VEC,\n                                expr.hir_id,\n                                expr.span,\n                                \"reading zero byte data to `Vec`\",\n                                |diag| {\n                                    let span = first_stmt_containing_expr(cx, expr).map_or(expr.span, |stmt| stmt.span);\n                                    let indent = indent_of(cx, span).unwrap_or(0);\n                                    diag.span_suggestion(\n                                        span.shrink_to_lo(),\n                                        \"try\",\n                                        format!(\n                                            \"{ident}.resize({}, 0);\\n{}\",\n                                            snippet(cx, e.span, \"..\"),\n                                            \" \".repeat(indent)\n                                        ),\n                                        applicability,\n                                    );\n                                },\n                            );\n                        },\n                        _ => {\n                            span_lint_hir(\n                                cx,\n                                READ_ZERO_BYTE_VEC,\n                                expr.hir_id,\n                                expr.span,\n                                \"reading zero byte data to `Vec`\",\n                            );\n                        },\n                    }\n                }\n            }\n        }\n    }\n}\n\nfn first_stmt_containing_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx hir::Stmt<'tcx>> {\n    cx.tcx.hir_parent_iter(expr.hir_id).find_map(|(_, node)| {\n        if let hir::Node::Stmt(stmt) = node {\n            Some(stmt)\n        } else {\n            None\n        }\n    })\n}\n\nstruct ReadVecVisitor<'tcx> {\n    local_id: HirId,\n    read_zero_expr: Option<&'tcx Expr<'tcx>>,\n    has_resize: bool,\n}\n\nimpl<'tcx> Visitor<'tcx> for ReadVecVisitor<'tcx> {\n    fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) {\n        if let ExprKind::MethodCall(path, receiver, args, _) = e.kind {\n            let PathSegment { ident, .. } = *path;\n\n            match ident.name {\n                sym::read | sym::read_exact => {\n                    let [arg] = args else { return };\n                    if let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind\n                        && let ExprKind::Path(QPath::Resolved(None, inner_path)) = inner.kind\n                        && let [inner_seg] = inner_path.segments\n                        && let Res::Local(res_id) = inner_seg.res\n                        && self.local_id == res_id\n                    {\n                        self.read_zero_expr = Some(e);\n                        return;\n                    }\n                },\n                sym::resize => {\n                    // If the Vec is resized, then it's a valid read\n                    if let ExprKind::Path(QPath::Resolved(_, inner_path)) = receiver.kind\n                        && let Res::Local(res_id) = inner_path.res\n                        && self.local_id == res_id\n                    {\n                        self.has_resize = true;\n                        return;\n                    }\n                },\n                _ => {},\n            }\n        }\n\n        if !self.has_resize && self.read_zero_expr.is_none() {\n            walk_expr(self, e);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_async_block.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{snippet, walk_span_to_context};\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{desugar_await, peel_blocks};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::UpvarCapture;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `async` block that only returns `await` on a future.\n    ///\n    /// ### Why is this bad?\n    /// It is simpler and more efficient to use the future directly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let f = async {\n    ///     1 + 2\n    /// };\n    /// let fut = async {\n    ///     f.await\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let f = async {\n    ///     1 + 2\n    /// };\n    /// let fut = f;\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub REDUNDANT_ASYNC_BLOCK,\n    complexity,\n    \"`async { future.await }` can be replaced by `future`\"\n}\n\ndeclare_lint_pass!(RedundantAsyncBlock => [REDUNDANT_ASYNC_BLOCK]);\n\nimpl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let span = expr.span;\n        if !span.in_external_macro(cx.tcx.sess.source_map()) &&\n            let Some(body_expr) = desugar_async_block(cx, expr) &&\n            let Some(expr) = desugar_await(peel_blocks(body_expr)) &&\n            // The await prefix must not come from a macro as its content could change in the future.\n            expr.span.eq_ctxt(body_expr.span) &&\n            // The await prefix must implement Future, as implementing IntoFuture is not enough.\n            let Some(future_trait) = cx.tcx.lang_items().future_trait() &&\n            implements_trait(cx, cx.typeck_results().expr_ty(expr), future_trait, &[]) &&\n            // An async block does not have immediate side-effects from a `.await` point-of-view.\n            (!expr.can_have_side_effects() || desugar_async_block(cx, expr).is_some()) &&\n            let Some(shortened_span) = walk_span_to_context(expr.span, span.ctxt())\n        {\n            span_lint_and_sugg(\n                cx,\n                REDUNDANT_ASYNC_BLOCK,\n                span,\n                \"this async expression only awaits a single future\",\n                \"you can reduce it to\",\n                snippet(cx, shortened_span, \"..\").into_owned(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n\n/// If `expr` is a desugared `async` block, return the original expression if it does not capture\n/// any variable by ref.\nfn desugar_async_block<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {\n    if let ExprKind::Closure(Closure { body, def_id, kind, .. }) = expr.kind\n        && let body = cx.tcx.hir_body(*body)\n        && matches!(\n            kind,\n            ClosureKind::Coroutine(CoroutineKind::Desugared(\n                CoroutineDesugaring::Async,\n                CoroutineSource::Block\n            ))\n        )\n    {\n        cx.typeck_results()\n            .closure_min_captures\n            .get(def_id)\n            .is_none_or(|m| {\n                m.values().all(|places| {\n                    places\n                        .iter()\n                        .all(|place| matches!(place.info.capture_kind, UpvarCapture::ByValue))\n                })\n            })\n            .then_some(body.value)\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_clone.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};\nuse clippy_utils::mir::{LocalUsage, PossibleBorrowerMap, visit_local_usage};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::ty::{has_drop, is_copy, peel_and_count_ty_refs};\nuse clippy_utils::{fn_has_unsatisfiable_preds, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, FnDecl, LangItem, def_id};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{BytePos, Span};\n\nmacro_rules! unwrap_or_continue {\n    ($x:expr) => {\n        match $x {\n            Some(x) => x,\n            None => continue,\n        }\n    };\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for a redundant `clone()` (and its relatives) which clones an owned\n    /// value that is going to be dropped without further use.\n    ///\n    /// ### Why is this bad?\n    /// It is not always possible for the compiler to eliminate useless\n    /// allocations and deallocations generated by redundant `clone()`s.\n    ///\n    /// ### Known problems\n    /// False-negatives: analysis performed by this lint is conservative and limited.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::path::Path;\n    /// # #[derive(Clone)]\n    /// # struct Foo;\n    /// # impl Foo {\n    /// #     fn new() -> Self { Foo {} }\n    /// # }\n    /// # fn call(x: Foo) {}\n    /// {\n    ///     let x = Foo::new();\n    ///     call(x.clone());\n    ///     call(x.clone()); // this can just pass `x`\n    /// }\n    ///\n    /// [\"lorem\", \"ipsum\"].join(\" \").to_string();\n    ///\n    /// Path::new(\"/a/b\").join(\"c\").to_path_buf();\n    /// ```\n    #[clippy::version = \"1.32.0\"]\n    pub REDUNDANT_CLONE,\n    nursery,\n    \"`clone()` of an owned value that is going to be dropped immediately\"\n}\n\ndeclare_lint_pass!(RedundantClone => [REDUNDANT_CLONE]);\n\nimpl<'tcx> LateLintPass<'tcx> for RedundantClone {\n    #[expect(clippy::too_many_lines)]\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        _: FnKind<'tcx>,\n        _: &'tcx FnDecl<'_>,\n        _: &'tcx Body<'_>,\n        _: Span,\n        def_id: LocalDefId,\n    ) {\n        // Building MIR for `fn`s with unsatisfiable preds results in ICE.\n        if fn_has_unsatisfiable_preds(cx, def_id.to_def_id()) {\n            return;\n        }\n\n        let mir = cx.tcx.optimized_mir(def_id.to_def_id());\n\n        let mut possible_borrower = PossibleBorrowerMap::new(cx, mir);\n\n        for (bb, bbdata) in mir.basic_blocks.iter_enumerated() {\n            let terminator = bbdata.terminator();\n\n            if terminator.source_info.span.from_expansion() {\n                continue;\n            }\n\n            // Give up on loops\n            if terminator.successors().any(|s| s == bb) {\n                continue;\n            }\n\n            let (fn_def_id, arg, arg_ty, clone_ret) =\n                unwrap_or_continue!(is_call_with_ref_arg(cx, mir, &terminator.kind));\n\n            let fn_name = cx.tcx.get_diagnostic_name(fn_def_id);\n\n            let from_borrow = cx.tcx.lang_items().get(LangItem::CloneFn) == Some(fn_def_id)\n                || fn_name == Some(sym::to_owned_method)\n                || (fn_name == Some(sym::to_string_method) && arg_ty.is_lang_item(cx, LangItem::String));\n\n            let from_deref = !from_borrow && matches!(fn_name, Some(sym::path_to_pathbuf | sym::os_str_to_os_string));\n\n            if !from_borrow && !from_deref {\n                continue;\n            }\n\n            if let ty::Adt(def, _) = arg_ty.kind()\n                && def.is_manually_drop()\n            {\n                continue;\n            }\n\n            // `{ arg = &cloned; clone(move arg); }` or `{ arg = &cloned; to_path_buf(arg); }`\n            let (cloned, cannot_move_out) = unwrap_or_continue!(find_stmt_assigns_to(cx, mir, arg, from_borrow, bb));\n\n            let loc = mir::Location {\n                block: bb,\n                statement_index: bbdata.statements.len(),\n            };\n\n            // `Local` to be cloned, and a local of `clone` call's destination\n            let (local, ret_local) = if from_borrow {\n                // `res = clone(arg)` can be turned into `res = move arg;`\n                // if `arg` is the only borrow of `cloned` at this point.\n\n                if cannot_move_out || !possible_borrower.only_borrowers(&[arg], cloned, loc) {\n                    continue;\n                }\n\n                (cloned, clone_ret)\n            } else {\n                // `arg` is a reference as it is `.deref()`ed in the previous block.\n                // Look into the predecessor block and find out the source of deref.\n\n                let ps = &mir.basic_blocks.predecessors()[bb];\n                if ps.len() != 1 {\n                    continue;\n                }\n                let pred_terminator = mir[ps[0]].terminator();\n\n                // receiver of the `deref()` call\n                let (pred_arg, deref_clone_ret) = if let Some((pred_fn_def_id, pred_arg, pred_arg_ty, res)) =\n                    is_call_with_ref_arg(cx, mir, &pred_terminator.kind)\n                    && res == cloned\n                    && cx.tcx.is_diagnostic_item(sym::deref_method, pred_fn_def_id)\n                    && let ty::Adt(pred_arg_def, _) = pred_arg_ty.kind()\n                    && let Some(pred_arg_name) = cx.tcx.get_diagnostic_name(pred_arg_def.did())\n                    && matches!(pred_arg_name, sym::PathBuf | sym::OsString)\n                {\n                    (pred_arg, res)\n                } else {\n                    continue;\n                };\n\n                let (local, cannot_move_out) =\n                    unwrap_or_continue!(find_stmt_assigns_to(cx, mir, pred_arg, true, ps[0]));\n                let loc = mir::Location {\n                    block: bb,\n                    statement_index: mir.basic_blocks[bb].statements.len(),\n                };\n\n                // This can be turned into `res = move local` if `arg` and `cloned` are not borrowed\n                // at the last statement:\n                //\n                // ```\n                // pred_arg = &local;\n                // cloned = deref(pred_arg);\n                // arg = &cloned;\n                // StorageDead(pred_arg);\n                // res = to_path_buf(cloned);\n                // ```\n                if cannot_move_out || !possible_borrower.only_borrowers(&[arg, cloned], local, loc) {\n                    continue;\n                }\n\n                (local, deref_clone_ret)\n            };\n\n            let clone_usage = if local == ret_local {\n                CloneUsage {\n                    cloned_use_loc: None.into(),\n                    cloned_consume_or_mutate_loc: None,\n                    clone_consumed_or_mutated: true,\n                }\n            } else {\n                let clone_usage = visit_clone_usage(local, ret_local, mir, bb);\n                if clone_usage.cloned_use_loc.maybe_used() && clone_usage.clone_consumed_or_mutated {\n                    // cloned value is used, and the clone is modified or moved\n                    continue;\n                } else if let MirLocalUsage::Used(loc) = clone_usage.cloned_use_loc\n                    && possible_borrower.local_is_alive_at(ret_local, loc)\n                {\n                    // cloned value is used, and the clone is alive.\n                    continue;\n                } else if let Some(loc) = clone_usage.cloned_consume_or_mutate_loc\n                    // cloned value is mutated, and the clone is alive.\n                    && possible_borrower.local_is_alive_at(ret_local, loc)\n                {\n                    continue;\n                }\n                clone_usage\n            };\n\n            let span = terminator.source_info.span;\n            let scope = terminator.source_info.scope;\n            let node = mir.source_scopes[scope]\n                .local_data\n                .as_ref()\n                .unwrap_crate_local()\n                .lint_root;\n\n            if let Some(snip) = span.get_source_text(cx)\n                && let Some(dot) = snip.rfind('.')\n            {\n                let sugg_span = span.with_lo(span.lo() + BytePos(u32::try_from(dot).unwrap()));\n                let mut app = Applicability::MaybeIncorrect;\n\n                let call_snip = &snip[dot + 1..];\n                // Machine applicable when `call_snip` looks like `foobar()`\n                if let Some(call_snip) = call_snip.strip_suffix(\"()\").map(str::trim)\n                    && call_snip\n                        .as_bytes()\n                        .iter()\n                        .all(|b| b.is_ascii_alphabetic() || *b == b'_')\n                {\n                    app = Applicability::MachineApplicable;\n                }\n\n                span_lint_hir_and_then(cx, REDUNDANT_CLONE, node, sugg_span, \"redundant clone\", |diag| {\n                    diag.span_suggestion(sugg_span, \"remove this\", \"\", app);\n                    if clone_usage.cloned_use_loc.maybe_used() {\n                        diag.span_note(span, \"cloned value is neither consumed nor mutated\");\n                    } else {\n                        diag.span_note(\n                            span.with_hi(span.lo() + BytePos(u32::try_from(dot).unwrap())),\n                            \"this value is dropped without further use\",\n                        );\n                    }\n                });\n            } else {\n                span_lint_hir(cx, REDUNDANT_CLONE, node, span, \"redundant clone\");\n            }\n        }\n    }\n}\n\n/// If `kind` is `y = func(x: &T)` where `T: !Copy`, returns `(DefId of func, x, T, y)`.\nfn is_call_with_ref_arg<'tcx>(\n    cx: &LateContext<'tcx>,\n    mir: &'tcx mir::Body<'tcx>,\n    kind: &'tcx mir::TerminatorKind<'tcx>,\n) -> Option<(def_id::DefId, mir::Local, Ty<'tcx>, mir::Local)> {\n    if let mir::TerminatorKind::Call {\n        func,\n        args,\n        destination,\n        ..\n    } = kind\n        && args.len() == 1\n        && let mir::Operand::Move(mir::Place { local, .. }) = &args[0].node\n        && let ty::FnDef(def_id, _) = *func.ty(mir, cx.tcx).kind()\n        && let (inner_ty, 1, _) = peel_and_count_ty_refs(args[0].node.ty(mir, cx.tcx))\n        && !is_copy(cx, inner_ty)\n    {\n        Some((def_id, *local, inner_ty, destination.as_local()?))\n    } else {\n        None\n    }\n}\n\ntype CannotMoveOut = bool;\n\n/// Finds the first `to = (&)from`, and returns\n/// ``Some((from, whether `from` cannot be moved out))``.\nfn find_stmt_assigns_to<'tcx>(\n    cx: &LateContext<'tcx>,\n    mir: &mir::Body<'tcx>,\n    to_local: mir::Local,\n    by_ref: bool,\n    bb: mir::BasicBlock,\n) -> Option<(mir::Local, CannotMoveOut)> {\n    let rvalue = mir.basic_blocks[bb].statements.iter().rev().find_map(|stmt| {\n        if let mir::StatementKind::Assign(box (mir::Place { local, .. }, v)) = &stmt.kind {\n            return if *local == to_local { Some(v) } else { None };\n        }\n\n        None\n    })?;\n\n    match (by_ref, rvalue) {\n        (true, mir::Rvalue::Ref(_, _, place)) | (false, mir::Rvalue::Use(mir::Operand::Copy(place))) => {\n            Some(base_local_and_movability(cx, mir, *place))\n        },\n        (false, mir::Rvalue::Ref(_, _, place)) => {\n            if let [mir::ProjectionElem::Deref] = place.as_ref().projection {\n                Some(base_local_and_movability(cx, mir, *place))\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\n/// Extracts and returns the undermost base `Local` of given `place`. Returns `place` itself\n/// if it is already a `Local`.\n///\n/// Also reports whether given `place` cannot be moved out.\nfn base_local_and_movability<'tcx>(\n    cx: &LateContext<'tcx>,\n    mir: &mir::Body<'tcx>,\n    place: mir::Place<'tcx>,\n) -> (mir::Local, CannotMoveOut) {\n    // Dereference. You cannot move things out from a borrowed value.\n    let mut deref = false;\n    // Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.\n    let mut field = false;\n    // If projection is a slice index then clone can be removed only if the\n    // underlying type implements Copy\n    let mut slice = false;\n\n    for (base, elem) in place.as_ref().iter_projections() {\n        let base_ty = base.ty(&mir.local_decls, cx.tcx).ty;\n        deref |= matches!(elem, mir::ProjectionElem::Deref);\n        field |= matches!(elem, mir::ProjectionElem::Field(..)) && has_drop(cx, base_ty);\n        slice |= matches!(elem, mir::ProjectionElem::Index(..)) && !is_copy(cx, base_ty);\n    }\n\n    (place.local, deref || field || slice)\n}\n\n#[derive(Debug, Default)]\nenum MirLocalUsage {\n    /// The local maybe used, but we are not sure how.\n    Unknown,\n    /// The local is not used.\n    #[default]\n    Unused,\n    /// The local is used at a specific location.\n    Used(mir::Location),\n}\n\nimpl MirLocalUsage {\n    fn maybe_used(&self) -> bool {\n        matches!(self, MirLocalUsage::Unknown | MirLocalUsage::Used(_))\n    }\n}\n\nimpl From<Option<mir::Location>> for MirLocalUsage {\n    fn from(loc: Option<mir::Location>) -> Self {\n        loc.map_or(MirLocalUsage::Unused, MirLocalUsage::Used)\n    }\n}\n\n#[derive(Debug, Default)]\nstruct CloneUsage {\n    /// The first location where the cloned value is used, if any.\n    cloned_use_loc: MirLocalUsage,\n    /// The first location where the cloned value is consumed or mutated, if any.\n    cloned_consume_or_mutate_loc: Option<mir::Location>,\n    /// Whether the clone value is mutated.\n    clone_consumed_or_mutated: bool,\n}\n\nfn visit_clone_usage(cloned: mir::Local, clone: mir::Local, mir: &mir::Body<'_>, bb: mir::BasicBlock) -> CloneUsage {\n    if let Some(\n        [\n            LocalUsage {\n                local_use_locs: cloned_use_locs,\n                local_consume_or_mutate_locs: cloned_consume_or_mutate_locs,\n            },\n            LocalUsage {\n                local_use_locs: _,\n                local_consume_or_mutate_locs: clone_consume_or_mutate_locs,\n            },\n        ],\n    ) = visit_local_usage(\n        [cloned, clone],\n        mir,\n        mir::Location {\n            block: bb,\n            statement_index: mir.basic_blocks[bb].statements.len(),\n        },\n    ) {\n        CloneUsage {\n            cloned_use_loc: cloned_use_locs.first().copied().into(),\n            cloned_consume_or_mutate_loc: cloned_consume_or_mutate_locs.first().copied(),\n            // Consider non-temporary clones consumed.\n            // TODO: Actually check for mutation of non-temporaries.\n            clone_consumed_or_mutated: mir.local_kind(clone) != mir::LocalKind::Temp\n                || !clone_consume_or_mutate_locs.is_empty(),\n        }\n    } else {\n        CloneUsage {\n            cloned_use_loc: MirLocalUsage::Unknown,\n            cloned_consume_or_mutate_loc: None,\n            clone_consumed_or_mutated: true,\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_closure_call.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir};\nuse clippy_utils::get_parent_expr;\nuse clippy_utils::sugg::Sugg;\nuse hir::Param;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};\nuse rustc_hir::{ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, intravisit as hir_visit};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::ExpnKind;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects closures called in the same expression where they\n    /// are defined.\n    ///\n    /// ### Why is this bad?\n    /// It is unnecessarily adding to the expression's\n    /// complexity.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = (|| 42)();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let a = 42;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub REDUNDANT_CLOSURE_CALL,\n    complexity,\n    \"throwaway closures called in the expression they are defined\"\n}\n\ndeclare_lint_pass!(RedundantClosureCall => [REDUNDANT_CLOSURE_CALL]);\n\n// Used to find `return` statements or equivalents e.g., `?`\nstruct ReturnVisitor;\n\nimpl<'tcx> Visitor<'tcx> for ReturnVisitor {\n    type Result = ControlFlow<()>;\n    fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> ControlFlow<()> {\n        if let ExprKind::Ret(_) | ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind {\n            return ControlFlow::Break(());\n        }\n        hir_visit::walk_expr(self, ex)\n    }\n}\n\n/// Checks if the body is owned by an async closure.\n/// Returns true for `async || whatever_expression`, but false for `|| async { whatever_expression\n/// }`.\nfn is_async_closure(body: &hir::Body<'_>) -> bool {\n    if let ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind\n        // checks whether it is `async || whatever_expression`\n        && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure))\n            = innermost_closure_generated_by_desugar.kind\n    {\n        true\n    } else {\n        false\n    }\n}\n\n/// Tries to find the innermost closure:\n/// ```rust,ignore\n/// (|| || || || 42)()()()()\n///  ^^^^^^^^^^^^^^          given this nested closure expression\n///           ^^^^^          we want to return this closure\n/// ```\n/// It also has a parameter for how many steps to go in at most, so as to\n/// not take more closures than there are calls.\nfn find_innermost_closure<'tcx>(\n    cx: &LateContext<'tcx>,\n    mut expr: &'tcx hir::Expr<'tcx>,\n    mut steps: usize,\n) -> Option<(\n    &'tcx hir::Expr<'tcx>,\n    &'tcx hir::FnDecl<'tcx>,\n    ty::Asyncness,\n    &'tcx [Param<'tcx>],\n)> {\n    let mut data = None;\n\n    while let ExprKind::Closure(closure) = expr.kind\n        && let body = cx.tcx.hir_body(closure.body)\n        && {\n            let mut visitor = ReturnVisitor;\n            !visitor.visit_expr(body.value).is_break()\n        }\n        && steps > 0\n    {\n        expr = body.value;\n        data = Some((\n            body.value,\n            closure.fn_decl,\n            if is_async_closure(body) {\n                ty::Asyncness::Yes\n            } else {\n                ty::Asyncness::No\n            },\n            body.params,\n        ));\n        steps -= 1;\n    }\n\n    data\n}\n\n/// \"Walks up\" the chain of calls to find the outermost call expression, and returns the depth:\n/// ```rust,ignore\n/// (|| || || 3)()()()\n///             ^^      this is the call expression we were given\n///                 ^^  this is what we want to return (and the depth is 3)\n/// ```\nfn get_parent_call_exprs<'tcx>(\n    cx: &LateContext<'tcx>,\n    mut expr: &'tcx hir::Expr<'tcx>,\n) -> (&'tcx hir::Expr<'tcx>, usize) {\n    let mut depth = 1;\n    while let Some(parent) = get_parent_expr(cx, expr)\n        && let ExprKind::Call(recv, _) = parent.kind\n        && expr.span == recv.span\n    {\n        expr = parent;\n        depth += 1;\n    }\n    (expr, depth)\n}\n\nimpl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {\n        if expr.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if let ExprKind::Call(recv, _) = expr.kind\n            // don't lint if the receiver is a call, too.\n            // we do this in order to prevent linting multiple times; consider:\n            // `(|| || 1)()()`\n            //           ^^  we only want to lint for this call (but we walk up the calls to consider both calls).\n            // without this check, we'd end up linting twice.\n            && !matches!(recv.kind, ExprKind::Call(..))\n            // Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is\n            // the same as the one the call is in.\n            // For instance, let's assume `x!()` returns a closure:\n            //    B ---v\n            //      x!()()\n            //          ^- A\n            // The call happens in the expansion `A`, while the closure originates from the expansion `B`.\n            // We don't want to suggest replacing `x!()()` with `x!()`.\n            && recv.span.ctxt().outer_expn() == expr.span.ctxt().outer_expn()\n            && let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)\n            && let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)\n            // outside macros we lint properly. Inside macros, we lint only ||() style closures.\n            && (!matches!(expr.span.ctxt().outer_expn_data().kind, ExpnKind::Macro(_, _)) || params.is_empty())\n        {\n            span_lint_and_then(\n                cx,\n                REDUNDANT_CLOSURE_CALL,\n                full_expr.span,\n                \"try not to call a closure in the expression where it is declared\",\n                |diag| {\n                    if fn_decl.inputs.is_empty() {\n                        let mut applicability = Applicability::MachineApplicable;\n                        let mut hint =\n                            Sugg::hir_with_context(cx, body, full_expr.span.ctxt(), \"..\", &mut applicability);\n\n                        if coroutine_kind.is_async()\n                            && let ExprKind::Closure(closure) = body.kind\n                        {\n                            // Like `async fn`, async closures are wrapped in an additional block\n                            // to move all of the closure's arguments into the future.\n\n                            let async_closure_body = cx.tcx.hir_body(closure.body).value;\n                            let ExprKind::Block(block, _) = async_closure_body.kind else {\n                                return;\n                            };\n                            let Some(block_expr) = block.expr else {\n                                return;\n                            };\n                            let ExprKind::DropTemps(body_expr) = block_expr.kind else {\n                                return;\n                            };\n\n                            // `async x` is a syntax error, so it becomes `async { x }`\n                            if !matches!(body_expr.kind, ExprKind::Block(_, _)) {\n                                hint = hint.blockify();\n                            }\n\n                            hint = hint.asyncify();\n                        }\n\n                        // If the closure body is a block with a single expression, suggest just the inner expression,\n                        // not the block. Example: `(|| { Some(true) })()` should suggest\n                        // `Some(true)`\n                        if let ExprKind::Block(block, _) = body.kind\n                            && block.stmts.is_empty()\n                            && let Some(expr) = block.expr\n                        {\n                            hint = Sugg::hir_with_context(cx, expr, full_expr.span.ctxt(), \"..\", &mut applicability)\n                                .maybe_paren();\n                        }\n\n                        diag.span_suggestion(full_expr.span, \"try doing something like\", hint, applicability);\n                    }\n                },\n            );\n        }\n    }\n\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {\n        fn count_closure_usage<'tcx>(\n            cx: &LateContext<'tcx>,\n            block: &'tcx hir::Block<'_>,\n            path: &'tcx hir::Path<'tcx>,\n        ) -> usize {\n            struct ClosureUsageCount<'a, 'tcx> {\n                cx: &'a LateContext<'tcx>,\n                path: &'tcx hir::Path<'tcx>,\n                count: usize,\n            }\n            impl<'tcx> Visitor<'tcx> for ClosureUsageCount<'_, 'tcx> {\n                type NestedFilter = nested_filter::OnlyBodies;\n\n                fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {\n                    if let ExprKind::Call(closure, _) = expr.kind\n                        && let ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind\n                        && self.path.segments[0].ident == path.segments[0].ident\n                        && self.path.res == path.res\n                    {\n                        self.count += 1;\n                    }\n                    hir_visit::walk_expr(self, expr);\n                }\n\n                fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n                    self.cx.tcx\n                }\n            }\n            let mut closure_usage_count = ClosureUsageCount { cx, path, count: 0 };\n            closure_usage_count.visit_block(block);\n            closure_usage_count.count\n        }\n\n        for w in block.stmts.windows(2) {\n            if let hir::StmtKind::Let(local) = w[0].kind\n                && let Some(t) = local.init\n                && let ExprKind::Closure { .. } = t.kind\n                && let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind\n                && let hir::StmtKind::Semi(second) = w[1].kind\n                && let ExprKind::Assign(_, call, _) = second.kind\n                && let ExprKind::Call(closure, _) = call.kind\n                && let ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind\n                && ident == path.segments[0].ident\n                && count_closure_usage(cx, block, path) == 1\n            {\n                span_lint_hir(\n                    cx,\n                    REDUNDANT_CLOSURE_CALL,\n                    second.hir_id,\n                    second.span,\n                    \"closure called just once immediately after it was declared\",\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_else.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{indent_of, reindent_multiline, snippet};\nuse rustc_ast::ast::{Block, Expr, ExprKind, Stmt, StmtKind};\nuse rustc_ast::visit::{Visitor, walk_expr};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `else` blocks that can be removed without changing semantics.\n    ///\n    /// ### Why is this bad?\n    /// The `else` block adds unnecessary indentation and verbosity.\n    ///\n    /// ### Known problems\n    /// Some may prefer to keep the `else` block for clarity.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn my_func(count: u32) {\n    ///     if count == 0 {\n    ///         print!(\"Nothing to do\");\n    ///         return;\n    ///     } else {\n    ///         print!(\"Moving on...\");\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn my_func(count: u32) {\n    ///     if count == 0 {\n    ///         print!(\"Nothing to do\");\n    ///         return;\n    ///     }\n    ///     print!(\"Moving on...\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.50.0\"]\n    pub REDUNDANT_ELSE,\n    pedantic,\n    \"`else` branch that can be removed without changing semantics\"\n}\n\ndeclare_lint_pass!(RedundantElse => [REDUNDANT_ELSE]);\n\nimpl EarlyLintPass for RedundantElse {\n    fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) {\n        if stmt.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n        // Only look at expressions that are a whole statement\n        let expr: &Expr = match &stmt.kind {\n            StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr,\n            _ => return,\n        };\n        // if else\n        let (mut then, mut els): (&Block, &Expr) = match &expr.kind {\n            ExprKind::If(_, then, Some(els)) => (then, els),\n            _ => return,\n        };\n        loop {\n            if !BreakVisitor::default().check_block(then) {\n                // then block does not always break\n                return;\n            }\n            match &els.kind {\n                // else if else\n                ExprKind::If(_, next_then, Some(next_els)) => {\n                    then = next_then;\n                    els = next_els;\n                },\n                // else if without else\n                ExprKind::If(..) => return,\n                // done\n                _ => break,\n            }\n        }\n\n        let mut app = Applicability::MachineApplicable;\n        if let ExprKind::Block(block, _) = &els.kind {\n            for stmt in &block.stmts {\n                // If the `else` block contains a local binding or a macro invocation, Clippy shouldn't auto-fix it\n                if matches!(&stmt.kind, StmtKind::Let(_) | StmtKind::MacCall(_)) {\n                    app = Applicability::Unspecified;\n                    break;\n                }\n            }\n        }\n\n        // FIXME: The indentation of the suggestion would be the same as the one of the macro invocation in this implementation, see https://github.com/rust-lang/rust-clippy/pull/13936#issuecomment-2569548202\n        span_lint_and_sugg(\n            cx,\n            REDUNDANT_ELSE,\n            els.span.with_lo(then.span.hi()),\n            \"redundant else block\",\n            \"remove the `else` block and move the contents out\",\n            make_sugg(cx, els.span, \"..\", Some(expr.span)),\n            app,\n        );\n    }\n}\n\n/// Call `check` functions to check if an expression always breaks control flow\n#[derive(Default)]\nstruct BreakVisitor {\n    is_break: bool,\n}\n\nimpl<'ast> Visitor<'ast> for BreakVisitor {\n    fn visit_block(&mut self, block: &'ast Block) {\n        self.is_break = match block.stmts.as_slice() {\n            [.., last] => self.check_stmt(last),\n            _ => false,\n        };\n    }\n\n    fn visit_expr(&mut self, expr: &'ast Expr) {\n        self.is_break = match expr.kind {\n            ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) => true,\n            ExprKind::Match(_, ref arms, _) => arms.iter().all(|arm|\n                arm.body.is_none() || arm.body.as_deref().is_some_and(|body| self.check_expr(body))\n            ),\n            ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els),\n            ExprKind::If(_, _, None)\n            // ignore loops for simplicity\n            | ExprKind::While(..) | ExprKind::ForLoop { .. } | ExprKind::Loop(..) => false,\n            _ => {\n                walk_expr(self, expr);\n                return;\n            },\n        };\n    }\n}\n\nimpl BreakVisitor {\n    fn check<T>(&mut self, item: T, visit: fn(&mut Self, T)) -> bool {\n        visit(self, item);\n        std::mem::replace(&mut self.is_break, false)\n    }\n\n    fn check_block(&mut self, block: &Block) -> bool {\n        self.check(block, Self::visit_block)\n    }\n\n    fn check_expr(&mut self, expr: &Expr) -> bool {\n        self.check(expr, Self::visit_expr)\n    }\n\n    fn check_stmt(&mut self, stmt: &Stmt) -> bool {\n        self.check(stmt, Self::visit_stmt)\n    }\n}\n\n// Extract the inner contents of an `else` block str\n// e.g. `{ foo(); bar(); }` -> `foo(); bar();`\nfn extract_else_block(mut block: &str) -> String {\n    block = block.strip_prefix(\"{\").unwrap_or(block);\n    block = block.strip_suffix(\"}\").unwrap_or(block);\n    block.trim_end().to_string()\n}\n\nfn make_sugg(cx: &EarlyContext<'_>, els_span: Span, default: &str, indent_relative_to: Option<Span>) -> String {\n    let extracted = extract_else_block(&snippet(cx, els_span, default));\n    let indent = indent_relative_to.and_then(|s| indent_of(cx, s));\n\n    reindent_multiline(&extracted, false, indent)\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_field_names.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, MsrvStack};\nuse rustc_ast::ast::{Expr, ExprKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for fields in struct literals where shorthands\n    /// could be used.\n    ///\n    /// ### Why is this bad?\n    /// If the field and variable names are the same,\n    /// the field name is redundant.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let bar: u8 = 123;\n    ///\n    /// struct Foo {\n    ///     bar: u8,\n    /// }\n    ///\n    /// let foo = Foo { bar: bar };\n    /// ```\n    /// the last line can be simplified to\n    /// ```ignore\n    /// let foo = Foo { bar };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub REDUNDANT_FIELD_NAMES,\n    style,\n    \"checks for fields in struct literals where shorthands could be used\"\n}\n\nimpl_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]);\n\npub struct RedundantFieldNames {\n    msrv: MsrvStack,\n}\n\nimpl RedundantFieldNames {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: MsrvStack::new(conf.msrv),\n        }\n    }\n}\n\nimpl EarlyLintPass for RedundantFieldNames {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if !self.msrv.meets(msrvs::FIELD_INIT_SHORTHAND) {\n            return;\n        }\n\n        if expr.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n        if let ExprKind::Struct(ref se) = expr.kind {\n            for field in &se.fields {\n                if !field.is_shorthand\n                    && let ExprKind::Path(None, path) = &field.expr.kind\n                    && let [segment] = path.segments.as_slice()\n                    && segment.args.is_none()\n                    && segment.ident == field.ident\n                    && field.span.eq_ctxt(field.ident.span)\n                {\n                    span_lint_and_sugg(\n                        cx,\n                        REDUNDANT_FIELD_NAMES,\n                        field.span,\n                        \"redundant field names in struct initialization\",\n                        \"replace it with\",\n                        field.ident.to_string(),\n                        Applicability::MachineApplicable,\n                    );\n                }\n            }\n        }\n    }\n\n    extract_msrv_attr!();\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_locals.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::ty::needs_ordered_drop;\nuse rustc_ast::Mutability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BindingMode, ByRef, ExprKind, HirId, LetStmt, Node, Pat, PatKind, QPath};\nuse rustc_hir_typeck::expr_use_visitor::PlaceBase;\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::UpvarCapture;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::DesugaringKind;\nuse rustc_span::symbol::Ident;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for redundant redefinitions of local bindings.\n    ///\n    /// ### Why is this bad?\n    /// Redundant redefinitions of local bindings do not change behavior other than variable's lifetimes and are likely to be unintended.\n    ///\n    /// These rebindings can be intentional to shorten the lifetimes of variables because they affect when the `Drop` implementation is called. Other than that, they do not affect your code's meaning but they _may_ affect `rustc`'s stack allocation.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let a = 0;\n    /// let a = a;\n    ///\n    /// fn foo(b: i32) {\n    ///     let b = b;\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let a = 0;\n    /// // no redefinition with the same name\n    ///\n    /// fn foo(b: i32) {\n    ///   // no redefinition with the same name\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub REDUNDANT_LOCALS,\n    suspicious,\n    \"redundant redefinition of a local binding\"\n}\n\ndeclare_lint_pass!(RedundantLocals => [REDUNDANT_LOCALS]);\n\nimpl<'tcx> LateLintPass<'tcx> for RedundantLocals {\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {\n        if !local.span.is_desugaring(DesugaringKind::Async)\n            // the pattern is a single by-value binding\n            && let PatKind::Binding(BindingMode(ByRef::No, mutability), _, ident, None) = local.pat.kind\n            // the binding is not type-ascribed\n            && local.ty.is_none()\n            // the expression is a resolved path\n            && let Some(expr) = local.init\n            && let ExprKind::Path(qpath @ QPath::Resolved(None, path)) = expr.kind\n            // the path is a single segment equal to the local's name\n            && let [last_segment] = path.segments\n            && last_segment.ident == ident\n            // resolve the path to its defining binding pattern\n            && let Res::Local(binding_id) = cx.qpath_res(&qpath, expr.hir_id)\n            && let Node::Pat(binding_pat) = cx.tcx.hir_node(binding_id)\n            // the previous binding has the same mutability\n            && find_binding(binding_pat, ident).is_some_and(|bind| bind.1 == mutability)\n            // the local does not change the effect of assignments to the binding. see #11290\n            && !affects_assignments(cx, mutability, binding_id, local.hir_id)\n            // the local does not affect the code's drop behavior\n            && !needs_ordered_drop(cx, cx.typeck_results().expr_ty(expr))\n            // the local is user-controlled\n            && !local.span.in_external_macro(cx.sess().source_map())\n            && !is_from_proc_macro(cx, expr)\n            && !is_by_value_closure_capture(cx, local.hir_id, binding_id)\n        {\n            span_lint_and_help(\n                cx,\n                REDUNDANT_LOCALS,\n                local.span,\n                format!(\"redundant redefinition of a binding `{ident}`\"),\n                Some(binding_pat.span),\n                format!(\"`{ident}` is initially defined here\"),\n            );\n        }\n    }\n}\n\n/// Checks if the enclosing body is a closure and if the given local is captured by value.\n///\n/// In those cases, the redefinition may be necessary to force a move:\n/// ```\n/// fn assert_static<T: 'static>(_: T) {}\n///\n/// let v = String::new();\n/// let closure = || {\n///   let v = v; // <- removing this redefinition makes `closure` no longer `'static`\n///   dbg!(&v);\n/// };\n/// assert_static(closure);\n/// ```\nfn is_by_value_closure_capture(cx: &LateContext<'_>, redefinition: HirId, root_variable: HirId) -> bool {\n    let closure_def_id = cx.tcx.hir_enclosing_body_owner(redefinition);\n\n    cx.tcx.is_closure_like(closure_def_id.to_def_id())\n        && cx.tcx.closure_captures(closure_def_id).iter().any(|c| {\n            matches!(c.info.capture_kind, UpvarCapture::ByValue)\n                && matches!(c.place.base, PlaceBase::Upvar(upvar) if upvar.var_path.hir_id == root_variable)\n        })\n}\n\n/// Find the annotation of a binding introduced by a pattern, or `None` if it's not introduced.\nfn find_binding(pat: &Pat<'_>, name: Ident) -> Option<BindingMode> {\n    let mut ret = None;\n\n    pat.each_binding_or_first(&mut |annotation, _, _, ident| {\n        if ident == name {\n            ret = Some(annotation);\n        }\n    });\n\n    ret\n}\n\n/// Check if a rebinding of a local changes the effect of assignments to the binding.\nfn affects_assignments(cx: &LateContext<'_>, mutability: Mutability, bind: HirId, rebind: HirId) -> bool {\n    // the binding is mutable and the rebinding is in a different scope than the original binding\n    mutability == Mutability::Mut && cx.tcx.hir_get_enclosing_scope(bind) != cx.tcx.hir_get_enclosing_scope(rebind)\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_pub_crate.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::HasSession;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Item, ItemKind, UseKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::def_id::CRATE_DEF_ID;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for items declared `pub(crate)` that are not crate visible because they\n    /// are inside a private module.\n    ///\n    /// ### Why is this bad?\n    /// Writing `pub(crate)` is misleading when it's redundant due to the parent\n    /// module's visibility.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// mod internal {\n    ///     pub(crate) fn internal_fn() { }\n    /// }\n    /// ```\n    /// This function is not visible outside the module and it can be declared with `pub` or\n    /// private visibility\n    /// ```no_run\n    /// mod internal {\n    ///     pub fn internal_fn() { }\n    /// }\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub REDUNDANT_PUB_CRATE,\n    nursery,\n    \"Using `pub(crate)` visibility on items that are not crate visible due to the visibility of the module that contains them.\"\n}\n\nimpl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]);\n\n#[derive(Default)]\npub struct RedundantPubCrate {\n    is_exported: Vec<bool>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if cx.tcx.visibility(item.owner_id.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())\n            && !cx.effective_visibilities.is_exported(item.owner_id.def_id)\n            && self.is_exported.last() == Some(&false)\n            && !is_ignorable_export(item)\n            && !item.span.in_external_macro(cx.sess().source_map())\n        {\n            let span = item\n                .kind\n                .ident()\n                .map_or(item.span, |ident| item.span.with_hi(ident.span.hi()));\n            let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id());\n            span_lint_and_then(\n                cx,\n                REDUNDANT_PUB_CRATE,\n                span,\n                format!(\"pub(crate) {descr} inside private module\"),\n                |diag| {\n                    diag.span_suggestion(\n                        item.vis_span,\n                        \"consider using\",\n                        \"pub\".to_string(),\n                        Applicability::MachineApplicable,\n                    );\n                },\n            );\n        }\n\n        if let ItemKind::Mod { .. } = item.kind {\n            self.is_exported\n                .push(cx.effective_visibilities.is_exported(item.owner_id.def_id));\n        }\n    }\n\n    fn check_item_post(&mut self, _cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if let ItemKind::Mod { .. } = item.kind {\n            self.is_exported.pop().expect(\"unbalanced check_item/check_item_post\");\n        }\n    }\n}\n\n// We ignore macro exports. And `ListStem` uses, which aren't interesting.\nfn is_ignorable_export<'tcx>(item: &'tcx Item<'tcx>) -> bool {\n    if let ItemKind::Use(path, kind) = item.kind {\n        let ignore = matches!(path.res.macro_ns, Some(Res::Def(DefKind::Macro(_), _))) || kind == UseKind::ListStem;\n        if ignore {\n            return true;\n        }\n    } else if let ItemKind::Macro(..) = item.kind {\n        return true;\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_slicing.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::get_parent_expr;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::ty::peel_and_count_ty_refs;\nuse rustc_ast::util::parser::ExprPrecedence;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};\nuse rustc_lint::{LateContext, LateLintPass, Lint};\nuse rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};\nuse rustc_middle::ty::{GenericArg, Ty};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for slicing expressions which are equivalent to dereferencing the\n    /// value.\n    ///\n    /// ### Why restrict this?\n    /// Some people may prefer to dereference rather than slice.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let vec = vec![1, 2, 3];\n    /// let slice = &vec[..];\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let vec = vec![1, 2, 3];\n    /// let slice = &*vec;\n    /// ```\n    #[clippy::version = \"1.61.0\"]\n    pub DEREF_BY_SLICING,\n    restriction,\n    \"slicing instead of dereferencing\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for redundant slicing expressions which use the full range, and\n    /// do not change the type.\n    ///\n    /// ### Why is this bad?\n    /// It unnecessarily adds complexity to the expression.\n    ///\n    /// ### Known problems\n    /// If the type being sliced has an implementation of `Index<RangeFull>`\n    /// that actually changes anything then it can't be removed. However, this would be surprising\n    /// to people reading the code and should have a note with it.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// fn get_slice(x: &[u32]) -> &[u32] {\n    ///     &x[..]\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```ignore\n    /// fn get_slice(x: &[u32]) -> &[u32] {\n    ///     x\n    /// }\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub REDUNDANT_SLICING,\n    complexity,\n    \"redundant slicing of the whole range of a type\"\n}\n\ndeclare_lint_pass!(RedundantSlicing => [DEREF_BY_SLICING, REDUNDANT_SLICING]);\n\nstatic REDUNDANT_SLICING_LINT: (&Lint, &str) = (REDUNDANT_SLICING, \"redundant slicing of the whole range\");\nstatic DEREF_BY_SLICING_LINT: (&Lint, &str) = (DEREF_BY_SLICING, \"slicing when dereferencing would work\");\n\nimpl<'tcx> LateLintPass<'tcx> for RedundantSlicing {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        let ctxt = expr.span.ctxt();\n        if let ExprKind::AddrOf(BorrowKind::Ref, mutability, addressee) = expr.kind\n            && addressee.span.ctxt() == ctxt\n            && let ExprKind::Index(indexed, range, _) = addressee.kind\n            && cx\n                .typeck_results()\n                .expr_ty_adjusted(range)\n                .is_lang_item(cx, LangItem::RangeFull)\n        {\n            let (expr_ty, expr_ref_count, _) = peel_and_count_ty_refs(cx.typeck_results().expr_ty(expr));\n            let (indexed_ty, indexed_ref_count, _) = peel_and_count_ty_refs(cx.typeck_results().expr_ty(indexed));\n            let parent_expr = get_parent_expr(cx, expr);\n            let needs_parens_for_prefix =\n                parent_expr.is_some_and(|parent| cx.precedence(parent) > ExprPrecedence::Prefix);\n\n            if expr_ty == indexed_ty {\n                if expr_ref_count > indexed_ref_count {\n                    // Indexing takes self by reference and can't return a reference to that\n                    // reference as it's a local variable. The only way this could happen is if\n                    // `self` contains a reference to the `Self` type. If this occurs then the\n                    // lint no longer applies as it's essentially a field access, which is not\n                    // redundant.\n                    return;\n                }\n                let deref_count = indexed_ref_count - expr_ref_count;\n\n                let ((lint, msg), reborrow_str, help_msg) = if mutability == Mutability::Mut {\n                    // The slice was used to reborrow the mutable reference.\n                    (DEREF_BY_SLICING_LINT, \"&mut *\", \"reborrow the original value instead\")\n                } else if matches!(\n                    parent_expr,\n                    Some(Expr {\n                        kind: ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _),\n                        ..\n                    })\n                ) || cx.typeck_results().expr_adjustments(expr).first().is_some_and(|a| {\n                    matches!(\n                        a.kind,\n                        Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. }))\n                    )\n                }) || (matches!(\n                    cx.typeck_results().expr_ty(indexed).ref_mutability(),\n                    Some(Mutability::Mut)\n                ) && mutability == Mutability::Not)\n                {\n                    (DEREF_BY_SLICING_LINT, \"&*\", \"reborrow the original value instead\")\n                } else if deref_count != 0 {\n                    (DEREF_BY_SLICING_LINT, \"\", \"dereference the original value instead\")\n                } else {\n                    (REDUNDANT_SLICING_LINT, \"\", \"use the original value instead\")\n                };\n\n                span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let snip = snippet_with_context(cx, indexed.span, ctxt, \"..\", &mut app).0;\n                    let sugg = if (deref_count != 0 || !reborrow_str.is_empty()) && needs_parens_for_prefix {\n                        format!(\"({reborrow_str}{}{snip})\", \"*\".repeat(deref_count))\n                    } else {\n                        format!(\"{reborrow_str}{}{snip}\", \"*\".repeat(deref_count))\n                    };\n                    diag.span_suggestion(expr.span, help_msg, sugg, app);\n                });\n            } else if let Some(target_id) = cx.tcx.lang_items().deref_target()\n                && let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions(\n                    cx.typing_env(),\n                    Ty::new_projection_from_args(cx.tcx, target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])),\n                )\n                && deref_ty == expr_ty\n            {\n                let (lint, msg) = DEREF_BY_SLICING_LINT;\n                span_lint_and_then(cx, lint, expr.span, msg, |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let snip = snippet_with_context(cx, indexed.span, ctxt, \"..\", &mut app).0;\n                    let sugg = if needs_parens_for_prefix {\n                        format!(\"(&{}{}*{snip})\", mutability.prefix_str(), \"*\".repeat(indexed_ref_count))\n                    } else {\n                        format!(\"&{}{}*{snip}\", mutability.prefix_str(), \"*\".repeat(indexed_ref_count))\n                    };\n                    diag.span_suggestion(expr.span, \"dereference the original value instead\", sugg, app);\n                });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_static_lifetimes.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, MsrvStack};\nuse clippy_utils::source::snippet;\nuse rustc_ast::ast::{ConstItem, Item, ItemKind, StaticItem, Ty, TyKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for constants and statics with an explicit `'static` lifetime.\n    ///\n    /// ### Why is this bad?\n    /// Adding `'static` to every reference can create very\n    /// complicated types.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// const FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =\n    /// &[...]\n    /// static FOO: &'static [(&'static str, &'static str, fn(&Bar) -> bool)] =\n    /// &[...]\n    /// ```\n    /// This code can be rewritten as\n    /// ```ignore\n    ///  const FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]\n    ///  static FOO: &[(&str, &str, fn(&Bar) -> bool)] = &[...]\n    /// ```\n    #[clippy::version = \"1.37.0\"]\n    pub REDUNDANT_STATIC_LIFETIMES,\n    style,\n    \"Using explicit `'static` lifetime for constants or statics when elision rules would allow omitting them.\"\n}\n\nimpl_lint_pass!(RedundantStaticLifetimes => [REDUNDANT_STATIC_LIFETIMES]);\n\npub struct RedundantStaticLifetimes {\n    msrv: MsrvStack,\n}\n\nimpl RedundantStaticLifetimes {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: MsrvStack::new(conf.msrv),\n        }\n    }\n}\n\nimpl RedundantStaticLifetimes {\n    // Recursively visit types\n    fn visit_type(ty: &Ty, cx: &EarlyContext<'_>, reason: &'static str) {\n        match ty.kind {\n            // Be careful of nested structures (arrays and tuples)\n            TyKind::Array(ref ty, _) | TyKind::Slice(ref ty) => {\n                Self::visit_type(ty, cx, reason);\n            },\n            TyKind::Tup(ref tup) => {\n                for tup_ty in tup {\n                    Self::visit_type(tup_ty, cx, reason);\n                }\n            },\n            // This is what we are looking for !\n            TyKind::Ref(ref optional_lifetime, ref borrow_type) => {\n                // Match the 'static lifetime\n                if let Some(lifetime) = *optional_lifetime {\n                    match borrow_type.ty.kind {\n                        TyKind::Path(..) | TyKind::Slice(..) | TyKind::Array(..) | TyKind::Tup(..)\n                            if lifetime.ident.name == kw::StaticLifetime =>\n                        {\n                            let snip = snippet(cx, borrow_type.ty.span, \"<type>\");\n                            let sugg = format!(\"&{}{snip}\", borrow_type.mutbl.prefix_str());\n                            span_lint_and_then(cx, REDUNDANT_STATIC_LIFETIMES, lifetime.ident.span, reason, |diag| {\n                                diag.span_suggestion(\n                                    ty.span,\n                                    \"consider removing `'static`\",\n                                    sugg,\n                                    Applicability::MachineApplicable, //snippet\n                                );\n                            });\n                        },\n                        _ => {},\n                    }\n                }\n                Self::visit_type(&borrow_type.ty, cx, reason);\n            },\n            _ => {},\n        }\n    }\n}\n\nimpl EarlyLintPass for RedundantStaticLifetimes {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if !self.msrv.meets(msrvs::STATIC_IN_CONST) {\n            return;\n        }\n\n        if !item.span.from_expansion() {\n            if let ItemKind::Const(box ConstItem { ty: ref var_type, .. }) = item.kind {\n                Self::visit_type(var_type, cx, \"constants have by default a `'static` lifetime\");\n                // Don't check associated consts because `'static` cannot be elided on those (issue\n                // #2438)\n            }\n\n            if let ItemKind::Static(box StaticItem { ty: ref var_type, .. }) = item.kind {\n                Self::visit_type(var_type, cx, \"statics have by default a `'static` lifetime\");\n            }\n        }\n    }\n\n    extract_msrv_attr!();\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_test_prefix.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_test_function;\nuse clippy_utils::visitors::for_each_expr;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{self as hir, Body, ExprKind, FnDecl};\nuse rustc_lexer::is_ident;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{Span, Symbol, edition};\nuse std::borrow::Cow;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for test functions (functions annotated with `#[test]`) that are prefixed\n    /// with `test_` which is redundant.\n    ///\n    /// ### Why is this bad?\n    /// This is redundant because test functions are already annotated with `#[test]`.\n    /// Moreover, it clutters the output of `cargo test` since test functions are expanded as\n    /// `module::tests::test_use_case` in the output. Without the redundant prefix, the output\n    /// becomes `module::tests::use_case`, which is more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[cfg(test)]\n    /// mod tests {\n    ///   use super::*;\n    ///\n    ///   #[test]\n    ///   fn test_use_case() {\n    ///       // test code\n    ///   }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[cfg(test)]\n    /// mod tests {\n    ///   use super::*;\n    ///\n    ///   #[test]\n    ///   fn use_case() {\n    ///       // test code\n    ///   }\n    /// }\n    /// ```\n    ///\n    /// ### Note\n    /// Clippy can only lint compiled code. For this lint to trigger, you must configure `cargo clippy`\n    /// to include test compilation, for instance, by using flags such as `--tests` or `--all-targets`.\n    #[clippy::version = \"1.88.0\"]\n    pub REDUNDANT_TEST_PREFIX,\n    restriction,\n    \"redundant `test_` prefix in test function name\"\n}\n\ndeclare_lint_pass!(RedundantTestPrefix => [REDUNDANT_TEST_PREFIX]);\n\nimpl<'tcx> LateLintPass<'tcx> for RedundantTestPrefix {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'_>,\n        _decl: &FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        _span: Span,\n        fn_def_id: LocalDefId,\n    ) {\n        // Ignore methods and closures.\n        let FnKind::ItemFn(ref ident, ..) = kind else {\n            return;\n        };\n\n        // Skip the lint if the function is within a macro expansion.\n        if ident.span.from_expansion() {\n            return;\n        }\n\n        // Skip if the function name does not start with `test_`.\n        if !ident.as_str().starts_with(\"test_\") {\n            return;\n        }\n\n        // If the function is not a test function, skip the lint.\n        if !is_test_function(cx.tcx, fn_def_id) {\n            return;\n        }\n\n        span_lint_and_then(\n            cx,\n            REDUNDANT_TEST_PREFIX,\n            ident.span,\n            \"redundant `test_` prefix in test function name\",\n            |diag| {\n                let non_prefixed = Symbol::intern(ident.as_str().trim_start_matches(\"test_\"));\n                if is_invalid_ident(non_prefixed) {\n                    // If the prefix-trimmed name is not a valid function name, do not provide an\n                    // automatic fix, just suggest renaming the function.\n                    diag.help(\n                        \"consider function renaming (just removing `test_` prefix will produce invalid function name)\",\n                    );\n                } else {\n                    let (sugg, msg): (Cow<'_, str>, _) = if name_conflicts(cx, body, non_prefixed) {\n                        // If `non_prefixed` conflicts with another function in the same module/scope,\n                        // do not provide an automatic fix, but still emit a fix suggestion.\n                        (\n                            format!(\"{non_prefixed}_works\").into(),\n                            \"consider function renaming (just removing `test_` prefix will cause a name conflict)\",\n                        )\n                    } else {\n                        // If `non_prefixed` is a valid identifier and does not conflict with another function,\n                        // so we can suggest an auto-fix.\n                        (non_prefixed.as_str().into(), \"consider removing the `test_` prefix\")\n                    };\n                    diag.span_suggestion(ident.span, msg, sugg, Applicability::MaybeIncorrect);\n                }\n            },\n        );\n    }\n}\n\n/// Checks whether removal of the `_test` prefix from the function name will cause a name conflict.\n///\n/// There should be no other function with the same name in the same module/scope. Also, there\n/// should not be any function call with the same name within the body of the function, to avoid\n/// recursion.\nfn name_conflicts<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, fn_name: Symbol) -> bool {\n    let tcx = cx.tcx;\n    let id = body.id().hir_id;\n\n    // Iterate over items in the same module/scope\n    let (module, _module_span, _module_hir) = tcx.hir_get_module(tcx.parent_module(id));\n    if module\n        .item_ids\n        .iter()\n        .any(|item| matches!(tcx.hir_item(*item).kind, hir::ItemKind::Fn { ident, .. } if ident.name == fn_name))\n    {\n        // Name conflict found\n        return true;\n    }\n\n    // Also check that within the body of the function there is also no function call\n    // with the same name (since it will result in recursion)\n    for_each_expr(cx, body, |expr| {\n        if let ExprKind::Path(qpath) = &expr.kind\n            && let Some(def_id) = cx.qpath_res(qpath, expr.hir_id).opt_def_id()\n            && let Some(name) = tcx.opt_item_name(def_id)\n            && name == fn_name\n        {\n            // Function call with the same name found\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\nfn is_invalid_ident(ident: Symbol) -> bool {\n    // The identifier is either a reserved keyword, or starts with an invalid sequence.\n    ident.is_reserved(|| edition::LATEST_STABLE_EDITION) || !is_ident(ident.as_str())\n}\n"
  },
  {
    "path": "clippy_lints/src/redundant_type_annotations.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::is_lint_allowed;\nuse rustc_ast::LitKind;\nuse rustc_hir as hir;\nuse rustc_hir::def::DefKind;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns about needless / redundant type annotations.\n    ///\n    /// ### Why restrict this?\n    /// Code without type annotations is shorter and in most cases\n    /// more idiomatic and easier to modify.\n    ///\n    /// ### Limitations\n    /// This lint doesn't support:\n    ///\n    /// - Generics\n    /// - Refs returned from anything else than a `MethodCall`\n    /// - Complex types (tuples, arrays, etc...)\n    /// - `Path` to anything else than a primitive type.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let foo: String = String::new();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let foo = String::new();\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub REDUNDANT_TYPE_ANNOTATIONS,\n    restriction,\n    \"warns about needless / redundant type annotations.\"\n}\n\ndeclare_lint_pass!(RedundantTypeAnnotations => [REDUNDANT_TYPE_ANNOTATIONS]);\n\nfn is_same_type<'tcx>(cx: &LateContext<'tcx>, ty_resolved_path: hir::def::Res, func_return_type: Ty<'tcx>) -> bool {\n    // type annotation is primitive\n    if let hir::def::Res::PrimTy(primty) = ty_resolved_path\n        && func_return_type.is_primitive()\n        && let Some(func_return_type_sym) = func_return_type.primitive_symbol()\n    {\n        return primty.name() == func_return_type_sym;\n    }\n\n    // type annotation is a non generic type\n    if let hir::def::Res::Def(DefKind::Struct | DefKind::Union | DefKind::Enum, defid) = ty_resolved_path\n        && let Some(annotation_ty) = cx.tcx.type_of(defid).no_bound_vars()\n    {\n        return annotation_ty == func_return_type;\n    }\n\n    false\n}\n\nfn func_hir_id_to_func_ty<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::hir_id::HirId) -> Option<Ty<'tcx>> {\n    if let Some((defkind, func_defid)) = cx.typeck_results().type_dependent_def(hir_id)\n        && defkind == DefKind::AssocFn\n        && let Some(init_ty) = cx.tcx.type_of(func_defid).no_bound_vars()\n    {\n        Some(init_ty)\n    } else {\n        None\n    }\n}\n\nfn func_ty_to_return_type<'tcx>(cx: &LateContext<'tcx>, func_ty: Ty<'tcx>) -> Option<Ty<'tcx>> {\n    if func_ty.is_fn() {\n        Some(func_ty.fn_sig(cx.tcx).output().skip_binder())\n    } else {\n        None\n    }\n}\n\n/// Extracts the fn Ty, e.g. `fn() -> std::string::String {f}`\nfn extract_fn_ty<'tcx>(\n    cx: &LateContext<'tcx>,\n    call: &hir::Expr<'tcx>,\n    func_return_path: &hir::QPath<'tcx>,\n) -> Option<Ty<'tcx>> {\n    match func_return_path {\n        // let a: String = f(); where f: fn f() -> String\n        hir::QPath::Resolved(_, resolved_path) => {\n            if let hir::def::Res::Def(_, defid) = resolved_path.res\n                && let Some(middle_ty_init) = cx.tcx.type_of(defid).no_bound_vars()\n            {\n                Some(middle_ty_init)\n            } else {\n                None\n            }\n        },\n        // Associated functions like\n        // let a: String = String::new();\n        // let a: String = String::get_string();\n        hir::QPath::TypeRelative(..) => func_hir_id_to_func_ty(cx, call.hir_id),\n    }\n}\n\nfn is_redundant_in_func_call<'tcx>(\n    cx: &LateContext<'tcx>,\n    ty_resolved_path: hir::def::Res,\n    call: &hir::Expr<'tcx>,\n) -> bool {\n    if let hir::ExprKind::Path(init_path) = &call.kind {\n        let func_type = extract_fn_ty(cx, call, init_path);\n\n        if let Some(func_type) = func_type\n            && let Some(init_return_type) = func_ty_to_return_type(cx, func_type)\n        {\n            return is_same_type(cx, ty_resolved_path, init_return_type);\n        }\n    }\n\n    false\n}\n\nfn extract_primty(ty_kind: &hir::TyKind<'_>) -> Option<hir::PrimTy> {\n    if let hir::TyKind::Path(ty_path) = ty_kind\n        && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path\n        && let hir::def::Res::PrimTy(primty) = resolved_path_ty.res\n    {\n        Some(primty)\n    } else {\n        None\n    }\n}\n\nimpl LateLintPass<'_> for RedundantTypeAnnotations {\n    fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx rustc_hir::LetStmt<'tcx>) {\n        if !is_lint_allowed(cx, REDUNDANT_TYPE_ANNOTATIONS, local.hir_id)\n            // type annotation part\n            && !local.span.from_expansion()\n            && let Some(ty) = &local.ty\n\n            // initialization part\n            && let Some(init) = local.init\n        {\n            match &init.kind {\n                // When the initialization is a call to a function\n                hir::ExprKind::Call(init_call, _) => {\n                    if let hir::TyKind::Path(ty_path) = &ty.kind\n                        && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path\n                        && is_redundant_in_func_call(cx, resolved_path_ty.res, init_call)\n                    {\n                        span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, \"redundant type annotation\");\n                    }\n                },\n                hir::ExprKind::MethodCall(_, _, _, _) => {\n                    let mut is_ref = false;\n                    let mut ty_kind = &ty.kind;\n\n                    // If the annotation is a ref we \"peel\" it\n                    if let hir::TyKind::Ref(_, mut_ty) = &ty.kind {\n                        is_ref = true;\n                        ty_kind = &mut_ty.ty.kind;\n                    }\n\n                    if let hir::TyKind::Path(ty_path) = ty_kind\n                        && let hir::QPath::Resolved(_, resolved_path_ty) = ty_path\n                        && let Some(func_ty) = func_hir_id_to_func_ty(cx, init.hir_id)\n                        && let Some(return_type) = func_ty_to_return_type(cx, func_ty)\n                        && is_same_type(\n                            cx,\n                            resolved_path_ty.res,\n                            if is_ref { return_type.peel_refs() } else { return_type },\n                        )\n                    {\n                        span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, \"redundant type annotation\");\n                    }\n                },\n                // When the initialization is a path for example u32::MAX\n                hir::ExprKind::Path(init_path) => {\n                    // TODO: check for non primty\n                    if let Some(primty) = extract_primty(&ty.kind)\n                        && let hir::QPath::TypeRelative(init_ty, _) = init_path\n                        && let Some(primty_init) = extract_primty(&init_ty.kind)\n                        && primty == primty_init\n                    {\n                        span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, \"redundant type annotation\");\n                    }\n                },\n                hir::ExprKind::Lit(init_lit) => {\n                    match init_lit.node {\n                        // In these cases the annotation is redundant\n                        LitKind::Str(..)\n                        | LitKind::Byte(..)\n                        | LitKind::Char(..)\n                        | LitKind::Bool(..)\n                        | LitKind::CStr(..) => {\n                            span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, \"redundant type annotation\");\n                        },\n                        LitKind::Int(..) | LitKind::Float(..) => {\n                            // If the initialization value is a suffixed literal we lint\n                            if init_lit.node.is_suffixed() {\n                                span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, \"redundant type annotation\");\n                            }\n                        },\n                        LitKind::Err(_) => (),\n                        LitKind::ByteStr(..) => {\n                            // We only lint if the type annotation is an array type (e.g. &[u8; 4]).\n                            // If instead it is a slice (e.g. &[u8]) it may not be redundant, so we\n                            // don't lint.\n                            if let hir::TyKind::Ref(_, mut_ty) = ty.kind\n                                && matches!(mut_ty.ty.kind, hir::TyKind::Array(..))\n                            {\n                                span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, \"redundant type annotation\");\n                            }\n                        },\n                    }\n                },\n                _ => (),\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ref_option_ref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::last_path_segment;\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{AmbigArg, GenericArg, GenericArgsParentheses, Mutability, Ty, TyKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `&Option<&T>`.\n    ///\n    /// ### Why is this bad?\n    /// Since `&` is Copy, it's useless to have a\n    /// reference on `Option<&T>`.\n    ///\n    /// ### Known problems\n    /// It may be irrelevant to use this lint on\n    /// public API code as it will make a breaking change to apply it.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let x: &Option<&u32> = &Some(&0u32);\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// let x: Option<&u32> = Some(&0u32);\n    /// ```\n    #[clippy::version = \"1.49.0\"]\n    pub REF_OPTION_REF,\n    pedantic,\n    \"use `Option<&T>` instead of `&Option<&T>`\"\n}\n\ndeclare_lint_pass!(RefOptionRef => [REF_OPTION_REF]);\n\nimpl<'tcx> LateLintPass<'tcx> for RefOptionRef {\n    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx, AmbigArg>) {\n        if let TyKind::Ref(_, ref mut_ty) = ty.kind\n            && mut_ty.mutbl == Mutability::Not\n            && let TyKind::Path(qpath) = &mut_ty.ty.kind\n            && let last = last_path_segment(qpath)\n            && let Some(def_id) = last.res.opt_def_id()\n            && cx.tcx.is_diagnostic_item(sym::Option, def_id)\n            && let Some(params) = last_path_segment(qpath).args\n            && params.parenthesized == GenericArgsParentheses::No\n            && let Some(inner_ty) = params.args.iter().find_map(|arg| match arg {\n                GenericArg::Type(inner_ty) => Some(inner_ty),\n                _ => None,\n            })\n            && let TyKind::Ref(_, ref inner_mut_ty) = inner_ty.kind\n            && inner_mut_ty.mutbl == Mutability::Not\n        {\n            span_lint_and_sugg(\n                cx,\n                REF_OPTION_REF,\n                ty.span,\n                \"since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\",\n                \"try\",\n                format!(\"Option<{}>\", &snippet(cx, inner_ty.span, \"..\")),\n                Applicability::MaybeIncorrect,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/ref_patterns.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::ast::{BindingMode, Pat, PatKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usages of the `ref` keyword.\n    ///\n    /// ### Why restrict this?\n    /// The `ref` keyword can be confusing for people unfamiliar with it, and often\n    /// it is more concise to use `&` instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let opt = Some(5);\n    /// if let Some(ref foo) = opt {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let opt = Some(5);\n    /// if let Some(foo) = &opt {}\n    /// ```\n    #[clippy::version = \"1.71.0\"]\n    pub REF_PATTERNS,\n    restriction,\n    \"use of a ref pattern, e.g. Some(ref value)\"\n}\n\ndeclare_lint_pass!(RefPatterns => [REF_PATTERNS]);\n\nimpl EarlyLintPass for RefPatterns {\n    fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) {\n        if let PatKind::Ident(BindingMode::REF, _, _) = pat.kind\n            && !pat.span.from_expansion()\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(cx, REF_PATTERNS, pat.span, \"usage of ref pattern\", |diag| {\n                diag.help(\"consider using `&` for clarity instead\");\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/reference.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sugg::{Sugg, has_enclosing_paren};\nuse clippy_utils::ty::adjust_derefs_manually_drop;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, HirId, Node, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `*&` and `*&mut` in expressions.\n    ///\n    /// ### Why is this bad?\n    /// Immediately dereferencing a reference is no-op and\n    /// makes the code less clear.\n    ///\n    /// ### Known problems\n    /// Multiple dereference/addrof pairs are not handled so\n    /// the suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let a = f(*&mut b);\n    /// let c = *&d;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// let a = f(b);\n    /// let c = d;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub DEREF_ADDROF,\n    complexity,\n    \"use of `*&` or `*&mut` in an expression\"\n}\n\ndeclare_lint_pass!(DerefAddrOf => [DEREF_ADDROF]);\n\nimpl LateLintPass<'_> for DerefAddrOf {\n    fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {\n        if !e.span.from_expansion()\n            && let ExprKind::Unary(UnOp::Deref, deref_target) = e.kind\n            && !deref_target.span.from_expansion()\n            && let ExprKind::AddrOf(_, _, addrof_target) = deref_target.kind\n            // NOTE(tesuji): `*&` forces rustc to const-promote the array to `.rodata` section.\n            // See #12854 for details.\n            && !matches!(addrof_target.kind, ExprKind::Array(_))\n            && deref_target.span.eq_ctxt(e.span)\n            && !addrof_target.span.from_expansion()\n        {\n            let mut applicability = Applicability::MachineApplicable;\n            let mut sugg = || Sugg::hir_with_applicability(cx, addrof_target, \"_\", &mut applicability);\n\n            // If this expression is an explicit `DerefMut` of a `ManuallyDrop` reached through a\n            // union, we may remove the reference if we are at the point where the implicit\n            // dereference would take place. Otherwise, we should not lint.\n            let sugg = match is_manually_drop_through_union(cx, e.hir_id, addrof_target) {\n                ManuallyDropThroughUnion::Directly => sugg().deref(),\n                ManuallyDropThroughUnion::Indirect => return,\n                ManuallyDropThroughUnion::No => sugg(),\n            };\n\n            let sugg = if has_enclosing_paren(snippet(cx, e.span, \"\")) {\n                sugg.maybe_paren()\n            } else {\n                sugg\n            };\n\n            span_lint_and_sugg(\n                cx,\n                DEREF_ADDROF,\n                e.span,\n                \"immediately dereferencing a reference\",\n                \"try\",\n                sugg.to_string(),\n                applicability,\n            );\n        }\n    }\n}\n\n/// Is this a `ManuallyDrop` reached through a union, and when is `DerefMut` called on it?\nenum ManuallyDropThroughUnion {\n    /// `ManuallyDrop` reached through a union and immediately explicitely dereferenced\n    Directly,\n    /// `ManuallyDrop` reached through a union, and dereferenced later on\n    Indirect,\n    /// Any other situation\n    No,\n}\n\n/// Check if `addrof_target` is part of an access to a `ManuallyDrop` entity reached through a\n/// union, and when it is dereferenced using `DerefMut` starting from `expr_id` and going up.\nfn is_manually_drop_through_union(\n    cx: &LateContext<'_>,\n    expr_id: HirId,\n    addrof_target: &Expr<'_>,\n) -> ManuallyDropThroughUnion {\n    if is_reached_through_union(cx, addrof_target) {\n        let typeck = cx.typeck_results();\n        for (idx, id) in std::iter::once(expr_id)\n            .chain(cx.tcx.hir_parent_id_iter(expr_id))\n            .enumerate()\n        {\n            if let Node::Expr(expr) = cx.tcx.hir_node(id) {\n                if adjust_derefs_manually_drop(typeck.expr_adjustments(expr), typeck.expr_ty(expr)) {\n                    return if idx == 0 {\n                        ManuallyDropThroughUnion::Directly\n                    } else {\n                        ManuallyDropThroughUnion::Indirect\n                    };\n                }\n            } else {\n                break;\n            }\n        }\n    }\n    ManuallyDropThroughUnion::No\n}\n\n/// Checks whether `expr` denotes an object reached through a union\nfn is_reached_through_union(cx: &LateContext<'_>, mut expr: &Expr<'_>) -> bool {\n    while let ExprKind::Field(parent, _) | ExprKind::Index(parent, _, _) = expr.kind {\n        if cx.typeck_results().expr_ty_adjusted(parent).is_union() {\n            return true;\n        }\n        expr = parent;\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/regex.rs",
    "content": "use std::fmt::Display;\n\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_help};\nuse clippy_utils::paths;\nuse clippy_utils::paths::PathLookup;\nuse clippy_utils::res::MaybeQPath;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_ast::ast::{LitKind, StrStyle};\nuse rustc_hir::def_id::DefIdMap;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, OwnerId};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{BytePos, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks [regex](https://crates.io/crates/regex) creation\n    /// (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct\n    /// regex syntax.\n    ///\n    /// ### Why is this bad?\n    /// This will lead to a runtime panic.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// Regex::new(\"(\")\n    /// ```\n    ///\n    /// Use instead:\n    /// ```ignore\n    /// Regex::new(\"\\(\")\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub INVALID_REGEX,\n    correctness,\n    \"invalid regular expressions\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for [regex](https://crates.io/crates/regex) compilation inside a loop with a literal.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Compiling a regex is a much more expensive operation than using one, and a compiled regex can be used multiple times.\n    /// This is documented as an antipattern [on the regex documentation](https://docs.rs/regex/latest/regex/#avoid-re-compiling-regexes-especially-in-a-loop)\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// # let haystacks = [\"\"];\n    /// # const MY_REGEX: &str = \"a.b\";\n    /// for haystack in haystacks {\n    ///     let regex = regex::Regex::new(MY_REGEX).unwrap();\n    ///     if regex.is_match(haystack) {\n    ///         // Perform operation\n    ///     }\n    /// }\n    /// ```\n    /// can be replaced with\n    /// ```rust,ignore\n    /// # let haystacks = [\"\"];\n    /// # const MY_REGEX: &str = \"a.b\";\n    /// let regex = regex::Regex::new(MY_REGEX).unwrap();\n    /// for haystack in haystacks {\n    ///     if regex.is_match(haystack) {\n    ///         // Perform operation\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.84.0\"]\n    pub REGEX_CREATION_IN_LOOPS,\n    perf,\n    \"regular expression compilation performed in a loop\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for trivial [regex](https://crates.io/crates/regex)\n    /// creation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`).\n    ///\n    /// ### Why is this bad?\n    /// Matching the regex can likely be replaced by `==` or\n    /// `str::starts_with`, `str::ends_with` or `std::contains` or other `str`\n    /// methods.\n    ///\n    /// ### Known problems\n    /// If the same regex is going to be applied to multiple\n    /// inputs, the precomputations done by `Regex` construction can give\n    /// significantly better performance than any of the `str`-based methods.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// Regex::new(\"^foobar\")\n    /// ```\n    ///\n    /// Use instead:\n    /// ```ignore\n    /// str::starts_with(\"foobar\")\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TRIVIAL_REGEX,\n    nursery,\n    \"trivial regular expressions\"\n}\n\nimpl_lint_pass!(Regex => [INVALID_REGEX, REGEX_CREATION_IN_LOOPS, TRIVIAL_REGEX]);\n\n#[derive(Copy, Clone)]\nenum RegexKind {\n    Unicode,\n    UnicodeSet,\n    Bytes,\n    BytesSet,\n}\n\n#[derive(Default)]\npub struct Regex {\n    definitions: DefIdMap<RegexKind>,\n    loop_stack: Vec<(OwnerId, Span)>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Regex {\n    fn check_crate(&mut self, cx: &LateContext<'tcx>) {\n        let mut resolve = |path: &PathLookup, kind: RegexKind| {\n            for &id in path.get(cx) {\n                self.definitions.insert(id, kind);\n            }\n        };\n\n        resolve(&paths::REGEX_NEW, RegexKind::Unicode);\n        resolve(&paths::REGEX_BUILDER_NEW, RegexKind::Unicode);\n        resolve(&paths::REGEX_SET_NEW, RegexKind::UnicodeSet);\n        resolve(&paths::REGEX_BYTES_NEW, RegexKind::Bytes);\n        resolve(&paths::REGEX_BYTES_BUILDER_NEW, RegexKind::Bytes);\n        resolve(&paths::REGEX_BYTES_SET_NEW, RegexKind::BytesSet);\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Call(fun, [arg]) = expr.kind\n            && let Some(def_id) = fun.res(cx).opt_def_id()\n            && let Some(regex_kind) = self.definitions.get(&def_id)\n        {\n            if let Some(&(loop_item_id, loop_span)) = self.loop_stack.last()\n                && loop_item_id == fun.hir_id.owner\n                && (matches!(arg.kind, ExprKind::Lit(_)) || const_str(cx, arg).is_some())\n            {\n                span_lint_and_help(\n                    cx,\n                    REGEX_CREATION_IN_LOOPS,\n                    fun.span,\n                    \"compiling a regex in a loop\",\n                    Some(loop_span),\n                    \"move the regex construction outside this loop\",\n                );\n            }\n\n            match regex_kind {\n                RegexKind::Unicode => check_regex(cx, arg, true),\n                RegexKind::UnicodeSet => check_set(cx, arg, true),\n                RegexKind::Bytes => check_regex(cx, arg, false),\n                RegexKind::BytesSet => check_set(cx, arg, false),\n            }\n        } else if let ExprKind::Loop(block, _, _, span) = expr.kind {\n            self.loop_stack.push((block.hir_id.owner, span));\n        }\n    }\n\n    fn check_expr_post(&mut self, _: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if matches!(expr.kind, ExprKind::Loop(..)) {\n            self.loop_stack.pop();\n        }\n    }\n}\n\nfn lint_syntax_error(cx: &LateContext<'_>, error: &regex_syntax::Error, unescaped: &str, base: Span, offset: u8) {\n    let parts: Option<(_, _, &dyn Display)> = match &error {\n        regex_syntax::Error::Parse(e) => Some((e.span(), e.auxiliary_span(), e.kind())),\n        regex_syntax::Error::Translate(e) => Some((e.span(), None, e.kind())),\n        _ => None,\n    };\n\n    let convert_span = |regex_span: &regex_syntax::ast::Span| {\n        let offset = u32::from(offset);\n        let start = base.lo() + BytePos(u32::try_from(regex_span.start.offset).expect(\"offset too large\") + offset);\n        let end = base.lo() + BytePos(u32::try_from(regex_span.end.offset).expect(\"offset too large\") + offset);\n\n        Span::new(start, end, base.ctxt(), base.parent())\n    };\n\n    if let Some((primary, auxiliary, kind)) = parts\n        && let Some(literal_snippet) = base.get_source_text(cx)\n        && let Some(inner) = literal_snippet.get(offset as usize..)\n        // Only convert to native rustc spans if the parsed regex matches the\n        // source snippet exactly, to ensure the span offsets are correct\n        && inner.get(..unescaped.len()) == Some(unescaped)\n    {\n        let spans = if let Some(auxiliary) = auxiliary {\n            vec![convert_span(primary), convert_span(auxiliary)]\n        } else {\n            vec![convert_span(primary)]\n        };\n\n        span_lint(cx, INVALID_REGEX, spans, format!(\"regex syntax error: {kind}\"));\n    } else {\n        span_lint_and_help(\n            cx,\n            INVALID_REGEX,\n            base,\n            error.to_string(),\n            None,\n            \"consider using a raw string literal: `r\\\"..\\\"`\",\n        );\n    }\n}\n\nfn const_str<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<String> {\n    ConstEvalCtxt::new(cx).eval(e).and_then(|c| match c {\n        Constant::Str(s) => Some(s),\n        _ => None,\n    })\n}\n\nfn is_trivial_regex(s: &regex_syntax::hir::Hir) -> Option<&'static str> {\n    use regex_syntax::hir::HirKind::{Alternation, Concat, Empty, Literal, Look};\n    use regex_syntax::hir::Look as HirLook;\n\n    let is_literal = |e: &[regex_syntax::hir::Hir]| e.iter().all(|e| matches!(*e.kind(), Literal(_)));\n\n    match *s.kind() {\n        Empty | Look(_) => Some(\"the regex is unlikely to be useful as it is\"),\n        Literal(_) => Some(\"consider using `str::contains`\"),\n        Alternation(ref exprs) => {\n            if exprs.iter().all(|e| matches!(e.kind(), Empty)) {\n                Some(\"the regex is unlikely to be useful as it is\")\n            } else {\n                None\n            }\n        },\n        Concat(ref exprs) => match (exprs[0].kind(), exprs[exprs.len() - 1].kind()) {\n            (&Look(HirLook::Start), &Look(HirLook::End)) if exprs[1..(exprs.len() - 1)].is_empty() => {\n                Some(\"consider using `str::is_empty`\")\n            },\n            (&Look(HirLook::Start), &Look(HirLook::End)) if is_literal(&exprs[1..(exprs.len() - 1)]) => {\n                Some(\"consider using `==` on `str`s\")\n            },\n            (&Look(HirLook::Start), &Literal(_)) if is_literal(&exprs[1..]) => {\n                Some(\"consider using `str::starts_with`\")\n            },\n            (&Literal(_), &Look(HirLook::End)) if is_literal(&exprs[1..(exprs.len() - 1)]) => {\n                Some(\"consider using `str::ends_with`\")\n            },\n            _ if is_literal(exprs) => Some(\"consider using `str::contains`\"),\n            _ => None,\n        },\n        _ => None,\n    }\n}\n\nfn check_set<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) {\n    if let ExprKind::AddrOf(BorrowKind::Ref, _, expr) = expr.kind\n        && let ExprKind::Array(exprs) = expr.kind\n    {\n        for expr in exprs {\n            check_regex(cx, expr, utf8);\n        }\n    }\n}\n\nfn check_regex<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) {\n    let mut parser = regex_syntax::ParserBuilder::new().unicode(true).utf8(utf8).build();\n\n    if let ExprKind::Lit(lit) = expr.kind {\n        if let LitKind::Str(ref r, style) = lit.node {\n            let r = r.as_str();\n            let offset = if let StrStyle::Raw(n) = style { 2 + n } else { 1 };\n            match parser.parse(r) {\n                Ok(r) => {\n                    if let Some(repl) = is_trivial_regex(&r) {\n                        span_lint_and_help(cx, TRIVIAL_REGEX, expr.span, \"trivial regex\", None, repl);\n                    }\n                },\n                Err(e) => lint_syntax_error(cx, &e, r, expr.span, offset),\n            }\n        }\n    } else if let Some(r) = const_str(cx, expr) {\n        match parser.parse(&r) {\n            Ok(r) => {\n                if let Some(repl) = is_trivial_regex(&r) {\n                    span_lint_and_help(cx, TRIVIAL_REGEX, expr.span, \"trivial regex\", None, repl);\n                }\n            },\n            Err(e) => span_lint(cx, INVALID_REGEX, expr.span, e.to_string()),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/repeat_vec_with_capacity.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::VecArgs;\nuse clippy_utils::macros::matching_root_macro_call;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet;\nuse clippy_utils::{expr_or_init, fn_def_id, std_or_core, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\npub struct RepeatVecWithCapacity {\n    msrv: Msrv,\n}\n\nimpl RepeatVecWithCapacity {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for patterns such as `vec![Vec::with_capacity(x); n]` or `iter::repeat(Vec::with_capacity(x))`.\n    ///\n    /// ### Why is this bad?\n    /// These constructs work by cloning the element, but cloning a `Vec<_>` does not\n    /// respect the old vector's capacity and effectively discards it.\n    ///\n    /// This makes `iter::repeat(Vec::with_capacity(x))` especially suspicious because the user most certainly\n    /// expected that the yielded `Vec<_>` will have the requested capacity, otherwise one can simply write\n    /// `iter::repeat(Vec::new())` instead and it will have the same effect.\n    ///\n    /// Similarly for `vec![x; n]`, the element `x` is cloned to fill the vec.\n    /// Unlike `iter::repeat` however, the vec repeat macro does not have to clone the value `n` times\n    /// but just `n - 1` times, because it can reuse the passed value for the last slot.\n    /// That means that the last `Vec<_>` gets the requested capacity but all other ones do not.\n    ///\n    /// ### Example\n    /// ```rust\n    /// # use std::iter;\n    ///\n    /// let _: Vec<Vec<u8>> = vec![Vec::with_capacity(42); 123];\n    /// let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// # use std::iter;\n    ///\n    /// let _: Vec<Vec<u8>> = iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect();\n    /// //                                      ^^^ this closure executes 123 times\n    /// //                                          and the vecs will have the expected capacity\n    /// ```\n    #[clippy::version = \"1.76.0\"]\n    pub REPEAT_VEC_WITH_CAPACITY,\n    suspicious,\n    \"repeating a `Vec::with_capacity` expression which does not retain capacity\"\n}\n\nimpl_lint_pass!(RepeatVecWithCapacity => [REPEAT_VEC_WITH_CAPACITY]);\n\nfn emit_lint(cx: &LateContext<'_>, span: Span, kind: &str, note: &'static str, sugg_msg: &'static str, sugg: String) {\n    span_lint_and_then(\n        cx,\n        REPEAT_VEC_WITH_CAPACITY,\n        span,\n        format!(\"repeating `Vec::with_capacity` using `{kind}`, which does not retain capacity\"),\n        |diag| {\n            diag.note(note);\n            diag.span_suggestion_verbose(span, sugg_msg, sugg, Applicability::MaybeIncorrect);\n        },\n    );\n}\n\n/// Checks `vec![Vec::with_capacity(x); n]`\nfn check_vec_macro(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if matching_root_macro_call(cx, expr.span, sym::vec_macro).is_some()\n        && let Some(VecArgs::Repeat(repeat_expr, len_expr)) = VecArgs::hir(cx, expr)\n        && fn_def_id(cx, repeat_expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::vec_with_capacity, did))\n        && !len_expr.span.from_expansion()\n        && let Some(Constant::Int(2..)) = ConstEvalCtxt::new(cx).eval(expr_or_init(cx, len_expr))\n    {\n        emit_lint(\n            cx,\n            expr.span.source_callsite(),\n            \"vec![x; n]\",\n            \"only the last `Vec` will have the capacity\",\n            \"if you intended to initialize multiple `Vec`s with an initial capacity, try\",\n            format!(\n                \"(0..{}).map(|_| {}).collect::<Vec<_>>()\",\n                snippet(cx, len_expr.span, \"\"),\n                snippet(cx, repeat_expr.span, \"..\")\n            ),\n        );\n    }\n}\n\n/// Checks `iter::repeat(Vec::with_capacity(x))`\nfn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) {\n    if !expr.span.from_expansion()\n        && fn_def_id(cx, expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::iter_repeat, did))\n        && let ExprKind::Call(_, [repeat_expr]) = expr.kind\n        && fn_def_id(cx, repeat_expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::vec_with_capacity, did))\n        && !repeat_expr.span.from_expansion()\n        && let Some(exec_context) = std_or_core(cx)\n        && msrv.meets(cx, msrvs::REPEAT_WITH)\n    {\n        emit_lint(\n            cx,\n            expr.span,\n            \"iter::repeat\",\n            \"none of the yielded `Vec`s will have the requested capacity\",\n            \"if you intended to create an iterator that yields `Vec`s with an initial capacity, try\",\n            format!(\n                \"{exec_context}::iter::repeat_with(|| {})\",\n                snippet(cx, repeat_expr.span, \"..\")\n            ),\n        );\n    }\n}\n\nimpl LateLintPass<'_> for RepeatVecWithCapacity {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        check_vec_macro(cx, expr);\n        check_repeat_fn(cx, expr, self.msrv);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/replace_box.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{is_default_equivalent_call, local_is_initialized};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_data_structures::smallvec::SmallVec;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Body, BodyId, Expr, ExprKind, HirId, LangItem, QPath};\nuse rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::place::ProjectionKind;\nuse rustc_middle::mir::FakeReadCause;\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Symbol, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects assignments of `Default::default()` or `Box::new(value)`\n    /// to a place of type `Box<T>`.\n    ///\n    /// ### Why is this bad?\n    /// This incurs an extra heap allocation compared to assigning the boxed\n    /// storage.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut b = Box::new(1u32);\n    /// b = Default::default();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut b = Box::new(1u32);\n    /// *b = Default::default();\n    /// ```\n    #[clippy::version = \"1.92.0\"]\n    pub REPLACE_BOX,\n    perf,\n    \"assigning a newly created box to `Box<T>` is inefficient\"\n}\n\nimpl_lint_pass!(ReplaceBox => [REPLACE_BOX]);\n\n#[derive(Default)]\npub struct ReplaceBox {\n    consumed_locals: FxHashSet<HirId>,\n    loaded_bodies: SmallVec<[BodyId; 2]>,\n}\n\nimpl ReplaceBox {\n    fn get_consumed_locals(&mut self, cx: &LateContext<'_>) -> &FxHashSet<HirId> {\n        if let Some(body_id) = cx.enclosing_body\n            && !self.loaded_bodies.contains(&body_id)\n        {\n            self.loaded_bodies.push(body_id);\n            ExprUseVisitor::for_clippy(\n                cx,\n                cx.tcx.hir_body_owner_def_id(body_id),\n                MovedVariablesCtxt {\n                    consumed_locals: &mut self.consumed_locals,\n                },\n            )\n            .consume_body(cx.tcx.hir_body(body_id))\n            .into_ok();\n        }\n\n        &self.consumed_locals\n    }\n}\n\nimpl LateLintPass<'_> for ReplaceBox {\n    fn check_body_post(&mut self, _: &LateContext<'_>, body: &Body<'_>) {\n        if self.loaded_bodies.first().is_some_and(|&x| x == body.id()) {\n            self.consumed_locals.clear();\n            self.loaded_bodies.clear();\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        if let ExprKind::Assign(lhs, rhs, _) = &expr.kind\n            && !lhs.span.from_expansion()\n            && !rhs.span.from_expansion()\n            && let lhs_ty = cx.typeck_results().expr_ty(lhs)\n            && let Some(inner_ty) = lhs_ty.boxed_ty()\n            // No diagnostic for late-initialized locals\n            && lhs.res_local_id().is_none_or(|local| local_is_initialized(cx, local))\n            // No diagnostic if this is a local that has been moved, or the field\n            // of a local that has been moved, or several chained field accesses of a local\n            && local_base(lhs).is_none_or(|(base_id, _)| {\n                !self.get_consumed_locals(cx).contains(&base_id)\n            })\n        {\n            if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)\n                && implements_trait(cx, inner_ty, default_trait_id, &[])\n                && is_default_call(cx, rhs)\n            {\n                span_lint_and_then(\n                    cx,\n                    REPLACE_BOX,\n                    expr.span,\n                    \"creating a new box with default content\",\n                    |diag| {\n                        let mut app = Applicability::MachineApplicable;\n                        let suggestion = format!(\n                            \"{} = Default::default()\",\n                            Sugg::hir_with_applicability(cx, lhs, \"_\", &mut app).deref()\n                        );\n\n                        diag.note(\"this creates a needless allocation\").span_suggestion(\n                            expr.span,\n                            \"replace existing content with default instead\",\n                            suggestion,\n                            app,\n                        );\n                    },\n                );\n            }\n\n            if inner_ty.is_sized(cx.tcx, cx.typing_env())\n                && let Some(rhs_inner) = get_box_new_payload(cx, rhs)\n            {\n                span_lint_and_then(cx, REPLACE_BOX, expr.span, \"creating a new box\", |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let suggestion = format!(\n                        \"{} = {}\",\n                        Sugg::hir_with_applicability(cx, lhs, \"_\", &mut app).deref(),\n                        Sugg::hir_with_context(cx, rhs_inner, expr.span.ctxt(), \"_\", &mut app),\n                    );\n\n                    diag.note(\"this creates a needless allocation\").span_suggestion(\n                        expr.span,\n                        \"replace existing content with inner value instead\",\n                        suggestion,\n                        app,\n                    );\n                });\n            }\n        }\n    }\n}\n\nfn is_default_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    matches!(expr.kind, ExprKind::Call(func, _args) if is_default_equivalent_call(cx, func, Some(expr)))\n}\n\nfn get_box_new_payload<'tcx>(cx: &LateContext<'_>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    if let ExprKind::Call(box_new, [arg]) = expr.kind\n        && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_new.kind\n        && seg.ident.name == sym::new\n        && ty.basic_res().is_lang_item(cx, LangItem::OwnedBox)\n    {\n        Some(arg)\n    } else {\n        None\n    }\n}\n\nstruct MovedVariablesCtxt<'a> {\n    consumed_locals: &'a mut FxHashSet<HirId>,\n}\n\nimpl<'tcx> Delegate<'tcx> for MovedVariablesCtxt<'_> {\n    fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {\n        if let PlaceBase::Local(id) = cmt.place.base\n            && let mut projections = cmt\n                .place\n                .projections\n                .iter()\n                .filter(|x| matches!(x.kind, ProjectionKind::Deref))\n            // Either no deref or multiple derefs\n            && (projections.next().is_none() || projections.next().is_some())\n        {\n            self.consumed_locals.insert(id);\n        }\n    }\n\n    fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn borrow(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {}\n\n    fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}\n}\n\n/// A local place followed by optional fields\ntype IdFields = (HirId, Vec<Symbol>);\n\n/// If `expr` is a local variable with optional field accesses, return it.\nfn local_base(expr: &Expr<'_>) -> Option<IdFields> {\n    match expr.kind {\n        ExprKind::Path(qpath) => qpath.res_local_id().map(|id| (id, Vec::new())),\n        ExprKind::Field(expr, field) => local_base(expr).map(|(id, mut fields)| {\n            fields.push(field.name);\n            (id, fields)\n        }),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/reserve_after_initialization.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::higher::{VecInitKind, get_vec_init_kind};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet;\nuse clippy_utils::{is_from_proc_macro, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Informs the user about a more concise way to create a vector with a known capacity.\n    ///\n    /// ### Why is this bad?\n    /// The `Vec::with_capacity` constructor is less complex.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut v: Vec<usize> = vec![];\n    /// v.reserve(10);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let mut v: Vec<usize> = Vec::with_capacity(10);\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub RESERVE_AFTER_INITIALIZATION,\n    complexity,\n    \"`reserve` called immediately after `Vec` creation\"\n}\n\nimpl_lint_pass!(ReserveAfterInitialization => [RESERVE_AFTER_INITIALIZATION]);\n\n#[derive(Default)]\npub struct ReserveAfterInitialization {\n    searcher: Option<VecReserveSearcher>,\n}\n\nstruct VecReserveSearcher {\n    local_id: HirId,\n    err_span: Span,\n    init_part: String,\n    space_hint: String,\n}\nimpl VecReserveSearcher {\n    fn display_err(&self, cx: &LateContext<'_>) {\n        if self.space_hint.is_empty() {\n            return;\n        }\n\n        let s = format!(\"{}Vec::with_capacity({});\", self.init_part, self.space_hint);\n\n        span_lint_and_sugg(\n            cx,\n            RESERVE_AFTER_INITIALIZATION,\n            self.err_span,\n            \"call to `reserve` immediately after creation\",\n            \"consider using `Vec::with_capacity(/* Space hint */)`\",\n            s,\n            Applicability::HasPlaceholders,\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {\n    fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {\n        self.searcher = None;\n    }\n\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {\n        if let Some(init_expr) = local.init\n            && let PatKind::Binding(BindingMode::MUT, id, _, None) = local.pat.kind\n            && !local.span.in_external_macro(cx.sess().source_map())\n            && let Some(init) = get_vec_init_kind(cx, init_expr)\n            && !matches!(\n                init,\n                VecInitKind::WithExprCapacity(_) | VecInitKind::WithConstCapacity(_)\n            )\n        {\n            self.searcher = Some(VecReserveSearcher {\n                local_id: id,\n                err_span: local.span,\n                init_part: snippet(\n                    cx,\n                    local\n                        .span\n                        .shrink_to_lo()\n                        .to(init_expr.span.source_callsite().shrink_to_lo()),\n                    \"..\",\n                )\n                .into_owned(),\n                space_hint: String::new(),\n            });\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if self.searcher.is_none()\n            && let ExprKind::Assign(left, right, _) = expr.kind\n            && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind\n            && let Res::Local(id) = path.res\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && let Some(init) = get_vec_init_kind(cx, right)\n            && !matches!(\n                init,\n                VecInitKind::WithExprCapacity(_) | VecInitKind::WithConstCapacity(_)\n            )\n        {\n            self.searcher = Some(VecReserveSearcher {\n                local_id: id,\n                err_span: expr.span,\n                init_part: snippet(\n                    cx,\n                    left.span.shrink_to_lo().to(right.span.source_callsite().shrink_to_lo()),\n                    \"..\",\n                )\n                .into_owned(), // see `assign_expression` test\n                space_hint: String::new(),\n            });\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if let Some(searcher) = self.searcher.take() {\n            if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind\n                && let ExprKind::MethodCall(name, self_arg, [space_hint], _) = expr.kind\n                && self_arg.res_local_id() == Some(searcher.local_id)\n                && name.ident.name == sym::reserve\n                && !is_from_proc_macro(cx, expr)\n            {\n                self.searcher = Some(VecReserveSearcher {\n                    err_span: searcher.err_span.to(stmt.span),\n                    space_hint: snippet(cx, space_hint.span, \"..\").into_owned(),\n                    ..searcher\n                });\n            } else {\n                searcher.display_err(cx);\n            }\n        }\n    }\n\n    fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {\n        if let Some(searcher) = self.searcher.take() {\n            searcher.display_err(cx);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/return_self_not_must_use.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::ty::is_must_use_ty;\nuse clippy_utils::{nth_arg, return_ty};\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind, find_attr};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns when a method returning `Self` doesn't have the `#[must_use]` attribute.\n    ///\n    /// ### Why is this bad?\n    /// Methods returning `Self` often create new values, having the `#[must_use]` attribute\n    /// prevents users from \"forgetting\" to use the newly created value.\n    ///\n    /// The `#[must_use]` attribute can be added to the type itself to ensure that instances\n    /// are never forgotten. Functions returning a type marked with `#[must_use]` will not be\n    /// linted, as the usage is already enforced by the type attribute.\n    ///\n    /// ### Limitations\n    /// This lint is only applied on methods taking a `self` argument. It would be mostly noise\n    /// if it was added on constructors for example.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub struct Bar;\n    /// impl Bar {\n    ///     // Missing attribute\n    ///     pub fn bar(&self) -> Self {\n    ///         Self\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # {\n    /// // It's better to have the `#[must_use]` attribute on the method like this:\n    /// pub struct Bar;\n    /// impl Bar {\n    ///     #[must_use]\n    ///     pub fn bar(&self) -> Self {\n    ///         Self\n    ///     }\n    /// }\n    /// # }\n    ///\n    /// # {\n    /// // Or on the type definition like this:\n    /// #[must_use]\n    /// pub struct Bar;\n    /// impl Bar {\n    ///     pub fn bar(&self) -> Self {\n    ///         Self\n    ///     }\n    /// }\n    /// # }\n    /// ```\n    #[clippy::version = \"1.59.0\"]\n    pub RETURN_SELF_NOT_MUST_USE,\n    pedantic,\n    \"missing `#[must_use]` annotation on a method returning `Self`\"\n}\n\ndeclare_lint_pass!(ReturnSelfNotMustUse => [RETURN_SELF_NOT_MUST_USE]);\n\nfn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, span: Span, owner_id: OwnerId) {\n    if !span.in_external_macro(cx.sess().source_map())\n        // If it comes from an external macro, better ignore it.\n        && decl.implicit_self.has_implicit_self()\n        // We only show this warning for public exported methods.\n        && cx.effective_visibilities.is_exported(fn_def)\n        // We don't want to emit this lint if the `#[must_use]` attribute is already there.\n        && !find_attr!(\n            cx.tcx.hir_attrs(owner_id.into()),\n            MustUse { .. }\n        )\n        && cx.tcx.visibility(fn_def.to_def_id()).is_public()\n        && let ret_ty = return_ty(cx, owner_id)\n        && let self_arg = nth_arg(cx, owner_id, 0)\n        // If `Self` has the same type as the returned type, then we want to warn.\n        //\n        // For this check, we don't want to remove the reference on the returned type because if\n        // there is one, we shouldn't emit a warning!\n        && self_arg.peel_refs() == ret_ty\n        // If `Self` is already marked as `#[must_use]`, no need for the attribute here.\n        && !is_must_use_ty(cx, ret_ty)\n    {\n        span_lint_and_help(\n            cx,\n            RETURN_SELF_NOT_MUST_USE,\n            span,\n            \"missing `#[must_use]` attribute on a method returning `Self`\",\n            None,\n            \"consider adding the `#[must_use]` attribute to the method or directly to the `Self` type\",\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'tcx>,\n        _: &'tcx Body<'tcx>,\n        span: Span,\n        fn_def: LocalDefId,\n    ) {\n        if matches!(kind, FnKind::Method(_, _))\n            // We are only interested in methods, not in functions or associated functions.\n            // We don't want this method to be te implementation of a trait because the\n            // `#[must_use]` should be put on the trait definition directly.\n            && cx.tcx.inherent_impl_of_assoc(fn_def.to_def_id()).is_some()\n        {\n            let hir_id = cx.tcx.local_def_id_to_hir_id(fn_def);\n            check_method(cx, decl, fn_def, span, hir_id.expect_owner());\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) {\n        if let TraitItemKind::Fn(ref sig, _) = item.kind {\n            check_method(cx, sig.decl, item.owner_id.def_id, item.span, item.owner_id);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/returns/let_and_return.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::sugg::has_enclosing_paren;\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{binary_expr_needs_parentheses, fn_def_id, span_contains_non_whitespace};\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, PatKind, StmtKind};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::GenericArgKind;\nuse rustc_span::edition::Edition;\n\nuse super::LET_AND_RETURN;\n\npub(super) fn check_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {\n    // we need both a let-binding stmt and an expr\n    if let Some(retexpr) = block.expr\n        && let Some(stmt) = block.stmts.last()\n        && let StmtKind::Let(local) = &stmt.kind\n        && local.ty.is_none()\n        && cx.tcx.hir_attrs(local.hir_id).is_empty()\n        && let Some(initexpr) = &local.init\n        && let PatKind::Binding(_, local_id, _, _) = local.pat.kind\n        && retexpr.res_local_id() == Some(local_id)\n        && (cx.sess().edition() >= Edition::Edition2024 || !last_statement_borrows(cx, initexpr))\n        && !initexpr.span.in_external_macro(cx.sess().source_map())\n        && !retexpr.span.in_external_macro(cx.sess().source_map())\n        && !local.span.from_expansion()\n        && !span_contains_non_whitespace(cx, stmt.span.between(retexpr.span), false)\n    {\n        span_lint_hir_and_then(\n            cx,\n            LET_AND_RETURN,\n            retexpr.hir_id,\n            retexpr.span,\n            \"returning the result of a `let` binding from a block\",\n            |err| {\n                err.span_label(local.span, \"unnecessary `let` binding\");\n\n                if let Some(src) = initexpr.span.get_source_text(cx) {\n                    let sugg = if binary_expr_needs_parentheses(initexpr) {\n                        if has_enclosing_paren(&src) {\n                            src.to_owned()\n                        } else {\n                            format!(\"({src})\")\n                        }\n                    } else if !cx.typeck_results().expr_adjustments(retexpr).is_empty() {\n                        if has_enclosing_paren(&src) {\n                            format!(\"{src} as _\")\n                        } else {\n                            format!(\"({src}) as _\")\n                        }\n                    } else {\n                        src.to_owned()\n                    };\n                    err.multipart_suggestion(\n                        \"return the expression directly\",\n                        vec![(local.span, String::new()), (retexpr.span, sugg)],\n                        Applicability::MachineApplicable,\n                    );\n                } else {\n                    err.span_help(initexpr.span, \"this expression can be directly returned\");\n                }\n            },\n        );\n    }\n}\nfn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {\n    for_each_expr(cx, expr, |e| {\n        if let Some(def_id) = fn_def_id(cx, e)\n            && cx\n                .tcx\n                .fn_sig(def_id)\n                .instantiate_identity()\n                .skip_binder()\n                .output()\n                .walk()\n                .any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(re) if !re.is_static()))\n        {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n"
  },
  {
    "path": "clippy_lints/src/returns/mod.rs",
    "content": "use rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Block, Body, FnDecl, Stmt};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\nmod let_and_return;\nmod needless_return;\nmod needless_return_with_question_mark;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `let`-bindings, which are subsequently\n    /// returned.\n    ///\n    /// ### Why is this bad?\n    /// It is just extraneous code. Remove it to make your code\n    /// more rusty.\n    ///\n    /// ### Known problems\n    /// In the case of some temporaries, e.g. locks, eliding the variable binding could lead\n    /// to deadlocks. See [this issue](https://github.com/rust-lang/rust/issues/37612).\n    /// This could become relevant if the code is later changed to use the code that would have been\n    /// bound without first assigning it to a let-binding.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo() -> String {\n    ///     let x = String::new();\n    ///     x\n    /// }\n    /// ```\n    /// instead, use\n    /// ```no_run\n    /// fn foo() -> String {\n    ///     String::new()\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub LET_AND_RETURN,\n    style,\n    \"creating a let-binding and then immediately returning it like `let x = expr; x` at the end of a block\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for return statements at the end of a block.\n    ///\n    /// ### Why is this bad?\n    /// Removing the `return` and semicolon will make the code\n    /// more rusty.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(x: usize) -> usize {\n    ///     return x;\n    /// }\n    /// ```\n    /// simplify to\n    /// ```no_run\n    /// fn foo(x: usize) -> usize {\n    ///     x\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NEEDLESS_RETURN,\n    // This lint requires some special handling in `check_final_expr` for `#[expect]`.\n    // This handling needs to be updated if the group gets changed. This should also\n    // be caught by tests.\n    style,\n    \"using a return statement like `return expr;` where an expression would suffice\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for return statements on `Err` paired with the `?` operator.\n    ///\n    /// ### Why is this bad?\n    /// The `return` is unnecessary.\n    ///\n    /// Returns may be used to add attributes to the return expression. Return\n    /// statements with attributes are therefore be accepted by this lint.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// fn foo(x: usize) -> Result<(), Box<dyn Error>> {\n    ///     if x == 0 {\n    ///         return Err(...)?;\n    ///     }\n    ///     Ok(())\n    /// }\n    /// ```\n    /// simplify to\n    /// ```rust,ignore\n    /// fn foo(x: usize) -> Result<(), Box<dyn Error>> {\n    ///     if x == 0 {\n    ///         Err(...)?;\n    ///     }\n    ///     Ok(())\n    /// }\n    /// ```\n    /// if paired with `try_err`, use instead:\n    /// ```rust,ignore\n    /// fn foo(x: usize) -> Result<(), Box<dyn Error>> {\n    ///     if x == 0 {\n    ///         return Err(...);\n    ///     }\n    ///     Ok(())\n    /// }\n    /// ```\n    #[clippy::version = \"1.73.0\"]\n    pub NEEDLESS_RETURN_WITH_QUESTION_MARK,\n    style,\n    \"using a return statement like `return Err(expr)?;` where removing it would suffice\"\n}\n\ndeclare_lint_pass!(Return => [\n    LET_AND_RETURN,\n    NEEDLESS_RETURN,\n    NEEDLESS_RETURN_WITH_QUESTION_MARK,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for Return {\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        needless_return_with_question_mark::check_stmt(cx, stmt);\n    }\n\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {\n        let_and_return::check_block(cx, block);\n    }\n\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        _: &'tcx FnDecl<'tcx>,\n        body: &'tcx Body<'tcx>,\n        sp: Span,\n        _: LocalDefId,\n    ) {\n        needless_return::check_fn(cx, kind, body, sp);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/returns/needless_return.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::{\n    binary_expr_needs_parentheses, is_from_proc_macro, leaks_droppable_temporary_with_limited_lifetime,\n    span_contains_cfg, span_find_starting_semi, sym,\n};\nuse rustc_ast::MetaItemInner;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, Expr, ExprKind, HirId, LangItem, MatchSource, StmtKind};\nuse rustc_lint::{LateContext, Level, LintContext};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::{BytePos, Pos, Span};\nuse std::borrow::Cow;\nuse std::fmt::Display;\n\nuse super::NEEDLESS_RETURN;\n\n#[derive(PartialEq, Eq)]\nenum RetReplacement<'tcx> {\n    Empty,\n    Block,\n    Unit,\n    NeedsPar(Cow<'tcx, str>, Applicability),\n    Expr(Cow<'tcx, str>, Applicability),\n}\n\nimpl RetReplacement<'_> {\n    fn sugg_help(&self) -> &'static str {\n        match self {\n            Self::Empty | Self::Expr(..) => \"remove `return`\",\n            Self::Block => \"replace `return` with an empty block\",\n            Self::Unit => \"replace `return` with a unit value\",\n            Self::NeedsPar(..) => \"remove `return` and wrap the sequence with parentheses\",\n        }\n    }\n\n    fn applicability(&self) -> Applicability {\n        match self {\n            Self::Expr(_, ap) | Self::NeedsPar(_, ap) => *ap,\n            _ => Applicability::MachineApplicable,\n        }\n    }\n}\n\nimpl Display for RetReplacement<'_> {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            Self::Empty => f.write_str(\"\"),\n            Self::Block => f.write_str(\"{}\"),\n            Self::Unit => f.write_str(\"()\"),\n            Self::NeedsPar(inner, _) => write!(f, \"({inner})\"),\n            Self::Expr(inner, _) => write!(f, \"{inner}\"),\n        }\n    }\n}\n\npub(super) fn check_fn<'tcx>(cx: &LateContext<'tcx>, kind: FnKind<'tcx>, body: &'tcx Body<'tcx>, sp: Span) {\n    if sp.from_expansion() {\n        return;\n    }\n\n    match kind {\n        FnKind::Closure => {\n            // when returning without value in closure, replace this `return`\n            // with an empty block to prevent invalid suggestion (see #6501)\n            let replacement = if let ExprKind::Ret(None) = &body.value.kind {\n                RetReplacement::Block\n            } else {\n                RetReplacement::Empty\n            };\n            check_final_expr(cx, body.value, vec![], replacement, None);\n        },\n        FnKind::ItemFn(..) | FnKind::Method(..) => {\n            check_block_return(cx, &body.value.kind, sp, vec![]);\n        },\n    }\n}\n\n// if `expr` is a block, check if there are needless returns in it\nfn check_block_return<'tcx>(cx: &LateContext<'tcx>, expr_kind: &ExprKind<'tcx>, sp: Span, mut semi_spans: Vec<Span>) {\n    if let ExprKind::Block(block, _) = expr_kind {\n        if let Some(block_expr) = block.expr {\n            check_final_expr(cx, block_expr, semi_spans, RetReplacement::Empty, None);\n        } else if let Some(stmt) = block.stmts.last() {\n            if span_contains_cfg(\n                cx,\n                Span::between(\n                    stmt.span,\n                    cx.sess().source_map().end_point(block.span), // the closing brace of the block\n                ),\n            ) {\n                return;\n            }\n            match stmt.kind {\n                StmtKind::Expr(expr) => {\n                    check_final_expr(cx, expr, semi_spans, RetReplacement::Empty, None);\n                },\n                StmtKind::Semi(semi_expr) => {\n                    // Remove ending semicolons and any whitespace ' ' in between.\n                    // Without `return`, the suggestion might not compile if the semicolon is retained\n                    if let Some(semi_span) = stmt.span.trim_start(semi_expr.span) {\n                        let semi_span_to_remove =\n                            span_find_starting_semi(cx.sess().source_map(), semi_span.with_hi(sp.hi()));\n                        semi_spans.push(semi_span_to_remove);\n                    }\n                    check_final_expr(cx, semi_expr, semi_spans, RetReplacement::Empty, None);\n                },\n                _ => (),\n            }\n        }\n    }\n}\n\nfn check_final_expr<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    semi_spans: Vec<Span>, /* containing all the places where we would need to remove semicolons if finding an\n                            * needless return */\n    replacement: RetReplacement<'tcx>,\n    match_ty_opt: Option<Ty<'_>>,\n) {\n    let peeled_drop_expr = expr.peel_drop_temps();\n    match &peeled_drop_expr.kind {\n        // simple return is always \"bad\"\n        ExprKind::Ret(inner) => {\n            // check if expr return nothing\n            let ret_span = if inner.is_none() && replacement == RetReplacement::Empty {\n                extend_span_to_previous_non_ws(cx, peeled_drop_expr.span)\n            } else {\n                peeled_drop_expr.span\n            };\n\n            let replacement = if let Some(inner_expr) = inner {\n                // if desugar of `do yeet`, don't lint\n                if let ExprKind::Call(path_expr, [_]) = inner_expr.kind\n                    && let ExprKind::Path(qpath) = path_expr.kind\n                    && cx.tcx.qpath_is_lang_item(qpath, LangItem::TryTraitFromYeet)\n                {\n                    return;\n                }\n\n                let mut applicability = Applicability::MachineApplicable;\n                let (snippet, _) = snippet_with_context(cx, inner_expr.span, ret_span.ctxt(), \"..\", &mut applicability);\n                if binary_expr_needs_parentheses(inner_expr) {\n                    RetReplacement::NeedsPar(snippet, applicability)\n                } else {\n                    RetReplacement::Expr(snippet, applicability)\n                }\n            } else {\n                match match_ty_opt {\n                    Some(match_ty) => {\n                        match match_ty.kind() {\n                            // If the code got till here with\n                            // tuple not getting detected before it,\n                            // then we are sure it's going to be Unit\n                            // type\n                            ty::Tuple(_) => RetReplacement::Unit,\n                            // We don't want to anything in this case\n                            // cause we can't predict what the user would\n                            // want here\n                            _ => return,\n                        }\n                    },\n                    None => replacement,\n                }\n            };\n\n            if inner.is_some_and(|inner| leaks_droppable_temporary_with_limited_lifetime(cx, inner)) {\n                return;\n            }\n\n            if ret_span.from_expansion() || is_from_proc_macro(cx, expr) {\n                return;\n            }\n\n            // Returns may be used to turn an expression into a statement in rustc's AST.\n            // This allows the addition of attributes, like `#[allow]` (See: clippy#9361)\n            // `#[expect(clippy::needless_return)]` needs to be handled separately to\n            // actually fulfill the expectation (clippy::#12998)\n            match cx.tcx.hir_attrs(expr.hir_id) {\n                [] => {},\n                [attr] => {\n                    if matches!(Level::from_attr(attr), Some((Level::Expect, _)))\n                        && let metas = attr.meta_item_list()\n                        && let Some(lst) = metas\n                        && let [MetaItemInner::MetaItem(meta_item), ..] = lst.as_slice()\n                        && let [tool, lint_name] = meta_item.path.segments.as_slice()\n                        && tool.ident.name == sym::clippy\n                        && matches!(\n                            lint_name.ident.name,\n                            sym::needless_return | sym::style | sym::all | sym::warnings\n                        )\n                    {\n                        // This is an expectation of the `needless_return` lint\n                    } else {\n                        return;\n                    }\n                },\n                _ => return,\n            }\n\n            emit_return_lint(\n                cx,\n                peeled_drop_expr.span,\n                ret_span,\n                semi_spans,\n                &replacement,\n                expr.hir_id,\n            );\n        },\n        ExprKind::If(_, then, else_clause_opt) => {\n            check_block_return(cx, &then.kind, peeled_drop_expr.span, semi_spans.clone());\n            if let Some(else_clause) = else_clause_opt {\n                // The `RetReplacement` won't be used there as `else_clause` will be either a block or\n                // a `if` expression.\n                check_final_expr(cx, else_clause, semi_spans, RetReplacement::Empty, match_ty_opt);\n            }\n        },\n        // a match expr, check all arms\n        // an if/if let expr, check both exprs\n        // note, if without else is going to be a type checking error anyways\n        // (except for unit type functions) so we don't match it\n        ExprKind::Match(_, arms, MatchSource::Normal) => {\n            let match_ty = cx.typeck_results().expr_ty(peeled_drop_expr);\n            for arm in *arms {\n                check_final_expr(cx, arm.body, semi_spans.clone(), RetReplacement::Unit, Some(match_ty));\n            }\n        },\n        // if it's a whole block, check it\n        other_expr_kind => check_block_return(cx, other_expr_kind, peeled_drop_expr.span, semi_spans),\n    }\n}\n\nfn emit_return_lint(\n    cx: &LateContext<'_>,\n    lint_span: Span,\n    ret_span: Span,\n    semi_spans: Vec<Span>,\n    replacement: &RetReplacement<'_>,\n    at: HirId,\n) {\n    span_lint_hir_and_then(\n        cx,\n        NEEDLESS_RETURN,\n        at,\n        lint_span,\n        \"unneeded `return` statement\",\n        |diag| {\n            let suggestions = std::iter::once((ret_span, replacement.to_string()))\n                .chain(semi_spans.into_iter().map(|span| (span, String::new())))\n                .collect();\n\n            diag.multipart_suggestion(replacement.sugg_help(), suggestions, replacement.applicability());\n        },\n    );\n}\n\n// Go backwards while encountering whitespace and extend the given Span to that point.\nfn extend_span_to_previous_non_ws(cx: &LateContext<'_>, sp: Span) -> Span {\n    if let Ok(prev_source) = cx.sess().source_map().span_to_prev_source(sp) {\n        let ws = [b' ', b'\\t', b'\\n'];\n        if let Some(non_ws_pos) = prev_source.bytes().rposition(|c| !ws.contains(&c)) {\n            let len = prev_source.len() - non_ws_pos - 1;\n            return sp.with_lo(sp.lo() - BytePos::from_usize(len));\n        }\n    }\n\n    sp\n}\n"
  },
  {
    "path": "clippy_lints/src/returns/needless_return_with_question_mark.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::{is_from_proc_macro, is_inside_let_else};\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::ResultErr;\nuse rustc_hir::{ExprKind, HirId, ItemKind, MatchSource, Node, OwnerNode, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty::adjustment::Adjust;\n\nuse super::NEEDLESS_RETURN_WITH_QUESTION_MARK;\n\npub(super) fn check_stmt<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n    if !stmt.span.in_external_macro(cx.sess().source_map())\n        && let StmtKind::Semi(expr) = stmt.kind\n        && let ExprKind::Ret(Some(ret)) = expr.kind\n        // return Err(...)? desugars to a match\n        // over a Err(...).branch()\n        // which breaks down to a branch call, with the callee being\n        // the constructor of the Err variant\n        && let ExprKind::Match(maybe_cons, _, MatchSource::TryDesugar(_)) = ret.kind\n        && let ExprKind::Call(_, [maybe_result_err]) = maybe_cons.kind\n        && let ExprKind::Call(maybe_constr, _) = maybe_result_err.kind\n        && maybe_constr.res(cx).ctor_parent(cx).is_lang_item(cx, ResultErr)\n\n        // Ensure this is not the final stmt, otherwise removing it would cause a compile error\n        && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir_get_parent_item(expr.hir_id))\n        && let ItemKind::Fn { body, .. } = item.kind\n        && let block = cx.tcx.hir_body(body).value\n        && let ExprKind::Block(block, _) = block.kind\n        && !is_inside_let_else(cx.tcx, expr)\n        && let [.., final_stmt] = block.stmts\n        && final_stmt.hir_id != stmt.hir_id\n        && !is_from_proc_macro(cx, expr)\n        && !stmt_needs_never_type(cx, stmt.hir_id)\n    {\n        span_lint_and_sugg(\n            cx,\n            NEEDLESS_RETURN_WITH_QUESTION_MARK,\n            expr.span.until(ret.span),\n            \"unneeded `return` statement with `?` operator\",\n            \"remove it\",\n            String::new(),\n            Applicability::MachineApplicable,\n        );\n    }\n}\n\n/// Checks if a return statement is \"needed\" in the middle of a block, or if it can be removed.\n/// This is the case when the enclosing block expression is coerced to some other type,\n/// which only works because of the never-ness of `return` expressions\nfn stmt_needs_never_type(cx: &LateContext<'_>, stmt_hir_id: HirId) -> bool {\n    cx.tcx\n        .hir_parent_iter(stmt_hir_id)\n        .find_map(|(_, node)| if let Node::Expr(expr) = node { Some(expr) } else { None })\n        .is_some_and(|e| {\n            cx.typeck_results()\n                .expr_adjustments(e)\n                .iter()\n                .any(|adjust| adjust.target != cx.tcx.types.unit && matches!(adjust.kind, Adjust::NeverToAny))\n        })\n}\n"
  },
  {
    "path": "clippy_lints/src/same_length_and_capacity.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::{eq_expr_value, sym};\nuse rustc_hir::{Expr, ExprKind, LangItem, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::sym as rustc_sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for usages of `Vec::from_raw_parts` and `String::from_raw_parts`\n    /// where the same expression is used for the length and the capacity.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// If the same expression is being passed for the length and\n    /// capacity, it is most likely a semantic error. In the case of a\n    /// Vec, for example, the only way to end up with one that has\n    /// the same length and capacity is by going through a boxed slice,\n    /// e.g. `Box::from(some_vec)`, which shrinks the capacity to match\n    /// the length.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// #![feature(vec_into_raw_parts)]\n    /// let mut original: Vec::<i32> = Vec::with_capacity(20);\n    /// original.extend([1, 2, 3, 4, 5]);\n    ///\n    /// let (ptr, mut len, cap) = original.into_raw_parts();\n    ///\n    /// // I will add three more integers:\n    /// unsafe {\n    ///    let ptr = ptr as *mut i32;\n    ///\n    ///    for i in 6..9 {\n    ///        *ptr.add(i - 1) = i as i32;\n    ///        len += 1;\n    ///    }\n    /// }\n    ///\n    /// // But I forgot the capacity was separate from the length:\n    /// let reconstructed = unsafe { Vec::from_raw_parts(ptr, len, len) };\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #![feature(vec_into_raw_parts)]\n    /// let mut original: Vec::<i32> = Vec::with_capacity(20);\n    /// original.extend([1, 2, 3, 4, 5]);\n    ///\n    /// let (ptr, mut len, cap) = original.into_raw_parts();\n    ///\n    /// // I will add three more integers:\n    /// unsafe {\n    ///    let ptr = ptr as *mut i32;\n    ///\n    ///    for i in 6..9 {\n    ///        *ptr.add(i - 1) = i as i32;\n    ///        len += 1;\n    ///    }\n    /// }\n    ///\n    /// // This time, leverage the previously saved capacity:\n    /// let reconstructed = unsafe { Vec::from_raw_parts(ptr, len, cap) };\n    /// ```\n    #[clippy::version = \"1.94.0\"]\n    pub SAME_LENGTH_AND_CAPACITY,\n    pedantic,\n    \"`from_raw_parts` with same length and capacity\"\n}\n\ndeclare_lint_pass!(SameLengthAndCapacity => [SAME_LENGTH_AND_CAPACITY]);\n\nimpl<'tcx> LateLintPass<'tcx> for SameLengthAndCapacity {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Call(path_expr, args) = expr.kind\n            && let ExprKind::Path(QPath::TypeRelative(ty, fn_path)) = path_expr.kind\n            && fn_path.ident.name == sym::from_raw_parts\n            && args.len() >= 3\n            && eq_expr_value(cx, &args[1], &args[2])\n        {\n            let middle_ty = cx.typeck_results().node_type(ty.hir_id);\n            if middle_ty.is_diag_item(cx, rustc_sym::Vec) {\n                span_lint_and_help(\n                    cx,\n                    SAME_LENGTH_AND_CAPACITY,\n                    expr.span,\n                    \"usage of `Vec::from_raw_parts` with the same expression for length and capacity\",\n                    None,\n                    \"try `Box::from(slice::from_raw_parts(...)).into::<Vec<_>>()`\",\n                );\n            } else if middle_ty.is_lang_item(cx, LangItem::String) {\n                span_lint_and_help(\n                    cx,\n                    SAME_LENGTH_AND_CAPACITY,\n                    expr.span,\n                    \"usage of `String::from_raw_parts` with the same expression for length and capacity\",\n                    None,\n                    \"try `String::from(str::from_utf8_unchecked(slice::from_raw_parts(...)))`\",\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/same_name_method.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{AssocItem, AssocKind};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::Symbol;\nuse std::collections::{BTreeMap, BTreeSet};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// It lints if a struct has two methods with the same name:\n    /// one from a trait, another not from a trait.\n    ///\n    /// ### Why restrict this?\n    /// Confusing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// trait T {\n    ///     fn foo(&self) {}\n    /// }\n    ///\n    /// struct S;\n    ///\n    /// impl T for S {\n    ///     fn foo(&self) {}\n    /// }\n    ///\n    /// impl S {\n    ///     fn foo(&self) {}\n    /// }\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub SAME_NAME_METHOD,\n    restriction,\n    \"two method with same name\"\n}\n\ndeclare_lint_pass!(SameNameMethod => [SAME_NAME_METHOD]);\n\nstruct ExistingName {\n    impl_methods: BTreeMap<Symbol, (Span, HirId)>,\n    trait_methods: BTreeMap<Symbol, Vec<Span>>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for SameNameMethod {\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        let mut map = FxHashMap::<Res, ExistingName>::default();\n\n        for id in cx.tcx.hir_free_items() {\n            if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. })\n                && let item = cx.tcx.hir_item(id)\n                && let ItemKind::Impl(Impl { of_trait, self_ty, .. }) = &item.kind\n                && let TyKind::Path(QPath::Resolved(_, Path { res, .. })) = self_ty.kind\n            {\n                if !map.contains_key(res) {\n                    map.insert(\n                        *res,\n                        ExistingName {\n                            impl_methods: BTreeMap::new(),\n                            trait_methods: BTreeMap::new(),\n                        },\n                    );\n                }\n                let existing_name = map.get_mut(res).unwrap();\n\n                match of_trait {\n                    Some(of_trait) => {\n                        let mut methods_in_trait: BTreeSet<Symbol> = if let Node::TraitRef(TraitRef { path, .. }) =\n                            cx.tcx.hir_node(of_trait.trait_ref.hir_ref_id)\n                            && let Res::Def(DefKind::Trait, did) = path.res\n                        {\n                            // FIXME: if\n                            // `rustc_middle::ty::assoc::AssocItems::items` is public,\n                            // we can iterate its keys instead of `in_definition_order`,\n                            // which's more efficient\n                            cx.tcx\n                                .associated_items(did)\n                                .in_definition_order()\n                                .filter(|assoc_item| assoc_item.is_fn())\n                                .map(AssocItem::name)\n                                .collect()\n                        } else {\n                            BTreeSet::new()\n                        };\n\n                        let mut check_trait_method = |method_name: Symbol, trait_method_span: Span| {\n                            if let Some((impl_span, hir_id)) = existing_name.impl_methods.get(&method_name) {\n                                span_lint_hir_and_then(\n                                    cx,\n                                    SAME_NAME_METHOD,\n                                    *hir_id,\n                                    *impl_span,\n                                    \"method's name is the same as an existing method in a trait\",\n                                    |diag| {\n                                        diag.span_note(\n                                            trait_method_span,\n                                            format!(\"existing `{method_name}` defined here\"),\n                                        );\n                                    },\n                                );\n                            }\n                            if let Some(v) = existing_name.trait_methods.get_mut(&method_name) {\n                                v.push(trait_method_span);\n                            } else {\n                                existing_name.trait_methods.insert(method_name, vec![trait_method_span]);\n                            }\n                        };\n\n                        for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() {\n                            if let AssocKind::Fn { name, .. } = assoc_item.kind {\n                                methods_in_trait.remove(&name);\n                                check_trait_method(name, cx.tcx.def_span(assoc_item.def_id));\n                            }\n                        }\n\n                        for method_name in methods_in_trait {\n                            check_trait_method(method_name, item.span);\n                        }\n                    },\n                    None => {\n                        for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() {\n                            let AssocKind::Fn { name, .. } = assoc_item.kind else {\n                                continue;\n                            };\n                            let impl_span = cx.tcx.def_span(assoc_item.def_id);\n                            let hir_id = cx.tcx.local_def_id_to_hir_id(assoc_item.def_id.expect_local());\n                            if let Some(trait_spans) = existing_name.trait_methods.get(&name) {\n                                span_lint_hir_and_then(\n                                    cx,\n                                    SAME_NAME_METHOD,\n                                    hir_id,\n                                    impl_span,\n                                    \"method's name is the same as an existing method in a trait\",\n                                    |diag| {\n                                        // TODO should we `span_note` on every trait?\n                                        // iterate on trait_spans?\n                                        diag.span_note(trait_spans[0], format!(\"existing `{name}` defined here\"));\n                                    },\n                                );\n                            }\n                            existing_name.impl_methods.insert(name, (impl_span, hir_id));\n                        }\n                    },\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/self_named_constructors.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::return_ty;\nuse clippy_utils::ty::contains_adt_constructor;\nuse rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns when constructors have the same name as their types.\n    ///\n    /// ### Why is this bad?\n    /// Repeating the name of the type is redundant.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// struct Foo {}\n    ///\n    /// impl Foo {\n    ///     pub fn foo() -> Foo {\n    ///         Foo {}\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// struct Foo {}\n    ///\n    /// impl Foo {\n    ///     pub fn new() -> Foo {\n    ///         Foo {}\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.55.0\"]\n    pub SELF_NAMED_CONSTRUCTORS,\n    style,\n    \"method should not have the same name as the type it is implemented for\"\n}\n\ndeclare_lint_pass!(SelfNamedConstructors => [SELF_NAMED_CONSTRUCTORS]);\n\nimpl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {\n        match impl_item.kind {\n            ImplItemKind::Fn(ref sig, _) => {\n                if sig.decl.implicit_self.has_implicit_self() {\n                    return;\n                }\n            },\n            _ => return,\n        }\n\n        let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id;\n        let item = cx.tcx.hir_expect_item(parent);\n        let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity();\n        let ret_ty = return_ty(cx, impl_item.owner_id);\n\n        // Do not check trait impls\n        if matches!(item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. })) {\n            return;\n        }\n\n        // Ensure method is constructor-like\n        if let Some(self_adt) = self_ty.ty_adt_def() {\n            if !contains_adt_constructor(ret_ty, self_adt) {\n                return;\n            }\n        } else if !ret_ty.contains(self_ty) {\n            return;\n        }\n\n        if let Some(self_def) = self_ty.ty_adt_def()\n            && let Some(self_local_did) = self_def.did().as_local()\n            && let Node::Item(x) = cx.tcx.hir_node_by_def_id(self_local_did)\n            && let Some(type_ident) = x.kind.ident()\n            && let type_name = type_ident.name.as_str().to_lowercase()\n            && (impl_item.ident.name.as_str() == type_name\n                || impl_item.ident.name.as_str().replace('_', \"\") == type_name)\n        {\n            span_lint(\n                cx,\n                SELF_NAMED_CONSTRUCTORS,\n                impl_item.span,\n                format!(\"constructor `{}` has the same name as the type\", impl_item.ident.name),\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/semicolon_block.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Suggests moving the semicolon after a block to the inside of the block, after its last\n    /// expression.\n    ///\n    /// ### Why restrict this?\n    /// For consistency it's best to have the semicolon inside/outside the block. Either way is fine\n    /// and this lint suggests inside the block.\n    /// Take a look at `semicolon_outside_block` for the other alternative.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// # fn f(_: u32) {}\n    /// # let x = 0;\n    /// unsafe { f(x) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # fn f(_: u32) {}\n    /// # let x = 0;\n    /// unsafe { f(x); }\n    /// ```\n    #[clippy::version = \"1.68.0\"]\n    pub SEMICOLON_INSIDE_BLOCK,\n    restriction,\n    \"add a semicolon inside the block\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Suggests moving the semicolon from a block's final expression outside of the block.\n    ///\n    /// ### Why restrict this?\n    /// For consistency it's best to have the semicolon inside/outside the block. Either way is fine\n    /// and this lint suggests outside the block.\n    /// Take a look at `semicolon_inside_block` for the other alternative.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// # fn f(_: u32) {}\n    /// # let x = 0;\n    /// unsafe { f(x); }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # fn f(_: u32) {}\n    /// # let x = 0;\n    /// unsafe { f(x) };\n    /// ```\n    #[clippy::version = \"1.68.0\"]\n    pub SEMICOLON_OUTSIDE_BLOCK,\n    restriction,\n    \"add a semicolon outside the block\"\n}\n\nimpl_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK]);\n\npub struct SemicolonBlock {\n    semicolon_inside_block_ignore_singleline: bool,\n    semicolon_outside_block_ignore_multiline: bool,\n}\n\nimpl SemicolonBlock {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            semicolon_inside_block_ignore_singleline: conf.semicolon_inside_block_ignore_singleline,\n            semicolon_outside_block_ignore_multiline: conf.semicolon_outside_block_ignore_multiline,\n        }\n    }\n\n    fn semicolon_inside_block(&self, cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<'_>, semi_span: Span) {\n        let insert_span = tail.span.source_callsite().shrink_to_hi();\n        let remove_span = semi_span.with_lo(block.span.hi());\n\n        // If the block is surrounded by parens (`({ 0 });`), the author probably knows what\n        // they're doing and why, so don't get in their way.\n        //\n        // This has the additional benefit of stopping the block being parsed as a function call:\n        // ```\n        // fn foo() {\n        //     ({ 0 }); // if we remove this `;`, this will parse as a `({ 0 })(5);` function call\n        //     (5);\n        // }\n        if remove_span.check_source_text(cx, |src| src.contains(')')) {\n            return;\n        }\n\n        if self.semicolon_inside_block_ignore_singleline && get_line(cx, remove_span) == get_line(cx, insert_span) {\n            return;\n        }\n\n        span_lint_and_then(\n            cx,\n            SEMICOLON_INSIDE_BLOCK,\n            semi_span,\n            \"consider moving the `;` inside the block for consistent formatting\",\n            |diag| {\n                diag.multipart_suggestion(\n                    \"put the `;` here\",\n                    vec![(remove_span, String::new()), (insert_span, \";\".to_owned())],\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n\n    fn semicolon_outside_block(&self, cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_expr: &Expr<'_>) {\n        let insert_span = block.span.shrink_to_hi();\n\n        // For macro call semicolon statements (`mac!();`), the statement's span does not actually\n        // include the semicolon itself, so use `mac_call_stmt_semi_span`, which finds the semicolon\n        // based on a source snippet.\n        // (Does not use `stmt_span` as that requires `.from_expansion()` to return true,\n        // which is not the case for e.g. `line!();` and `asm!();`)\n        let Some(remove_span) = cx\n            .sess()\n            .source_map()\n            .mac_call_stmt_semi_span(tail_stmt_expr.span.source_callsite())\n        else {\n            return;\n        };\n\n        if self.semicolon_outside_block_ignore_multiline && get_line(cx, remove_span) != get_line(cx, insert_span) {\n            return;\n        }\n\n        span_lint_and_then(\n            cx,\n            SEMICOLON_OUTSIDE_BLOCK,\n            block.span,\n            \"consider moving the `;` outside the block for consistent formatting\",\n            |diag| {\n                diag.multipart_suggestion(\n                    \"put the `;` here\",\n                    vec![(remove_span, String::new()), (insert_span, \";\".to_owned())],\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n}\n\nimpl LateLintPass<'_> for SemicolonBlock {\n    fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {\n        match stmt.kind {\n            StmtKind::Expr(Expr {\n                kind: ExprKind::Block(block, _),\n                ..\n            }) if !block.span.from_expansion() && stmt.span.contains(block.span) => {\n                if block.expr.is_none()\n                    && let [.., stmt] = block.stmts\n                    && let StmtKind::Semi(expr) = stmt.kind\n                {\n                    self.semicolon_outside_block(cx, block, expr);\n                }\n            },\n            StmtKind::Semi(Expr {\n                kind: ExprKind::Block(block, _),\n                ..\n            }) if !block.span.from_expansion() && !block.targeted_by_break => {\n                let attrs = cx.tcx.hir_attrs(stmt.hir_id);\n                if !attrs.is_empty() && !cx.tcx.features().stmt_expr_attributes() {\n                    return;\n                }\n\n                if let Some(tail) = block.expr {\n                    self.semicolon_inside_block(cx, block, tail, stmt.span);\n                }\n            },\n            _ => (),\n        }\n    }\n}\n\nfn get_line(cx: &LateContext<'_>, span: Span) -> Option<usize> {\n    cx.sess().source_map().lookup_line(span.lo()).ok().map(|line| line.line)\n}\n"
  },
  {
    "path": "clippy_lints/src/semicolon_if_nothing_returned.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_context;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{ExpnKind, MacroKind, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for blocks of expressions and fires if the last expression returns\n    /// `()` but is not followed by a semicolon.\n    ///\n    /// ### Why is this bad?\n    /// The semicolon might be optional but when extending the block with new\n    /// code, it doesn't require a change in previous last line.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn main() {\n    ///     println!(\"Hello world\")\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn main() {\n    ///     println!(\"Hello world\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.52.0\"]\n    pub SEMICOLON_IF_NOTHING_RETURNED,\n    pedantic,\n    \"add a semicolon if nothing is returned\"\n}\n\ndeclare_lint_pass!(SemicolonIfNothingReturned => [SEMICOLON_IF_NOTHING_RETURNED]);\n\nimpl<'tcx> LateLintPass<'tcx> for SemicolonIfNothingReturned {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {\n        if !block.span.from_expansion()\n            && let Some(expr) = block.expr\n            && !from_attr_macro(expr.span)\n            && let t_expr = cx.typeck_results().expr_ty(expr)\n            && t_expr.is_unit()\n            && let mut app = Applicability::MachineApplicable\n            && let snippet = snippet_with_context(cx, expr.span, block.span.ctxt(), \"}\", &mut app).0\n            && !snippet.ends_with('}')\n            && !snippet.ends_with(';')\n            && cx.sess().source_map().is_multiline(block.span)\n        {\n            // filter out the desugared `for` loop\n            if let ExprKind::DropTemps(..) = &expr.kind {\n                return;\n            }\n            span_lint_and_sugg(\n                cx,\n                SEMICOLON_IF_NOTHING_RETURNED,\n                expr.span.source_callsite(),\n                \"consider adding a `;` to the last statement for consistent formatting\",\n                \"add a `;` here\",\n                format!(\"{snippet};\"),\n                app,\n            );\n        }\n    }\n}\n\nfn from_attr_macro(span: Span) -> bool {\n    matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Attr, _))\n}\n"
  },
  {
    "path": "clippy_lints/src/serde_api.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::{paths, sym};\nuse rustc_hir::{Impl, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for misuses of the serde API.\n    ///\n    /// ### Why is this bad?\n    /// Serde is very finicky about how its API should be\n    /// used, but the type system can't be used to enforce it (yet?).\n    ///\n    /// ### Example\n    /// Implementing `Visitor::visit_string` but not\n    /// `Visitor::visit_str`.\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SERDE_API_MISUSE,\n    correctness,\n    \"various things that will negatively affect your serde experience\"\n}\n\ndeclare_lint_pass!(SerdeApi => [SERDE_API_MISUSE]);\n\nimpl<'tcx> LateLintPass<'tcx> for SerdeApi {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            items,\n            ..\n        }) = item.kind\n        {\n            let did = of_trait.trait_ref.path.res.def_id();\n            if paths::SERDE_DE_VISITOR.matches(cx, did) {\n                let mut seen_str = None;\n                let mut seen_string = None;\n                for item in items {\n                    match cx.tcx.item_name(item.owner_id) {\n                        sym::visit_str => seen_str = Some(cx.tcx.def_span(item.owner_id)),\n                        sym::visit_string => seen_string = Some(cx.tcx.def_span(item.owner_id)),\n                        _ => {},\n                    }\n                }\n                if let Some(span) = seen_string\n                    && seen_str.is_none()\n                {\n                    span_lint(\n                        cx,\n                        SERDE_API_MISUSE,\n                        span,\n                        \"you should not implement `visit_string` without also implementing `visit_str`\",\n                    );\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/set_contains_or_insert.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{SpanlessEq, higher, peel_hir_expr_while, sym};\nuse rustc_hir::{Expr, ExprKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `contains` to see if a value is not present\n    /// in a set like `HashSet` or `BTreeSet`, followed by an `insert`.\n    ///\n    /// ### Why is this bad?\n    /// Using just `insert` and checking the returned `bool` is more efficient.\n    ///\n    /// ### Known problems\n    /// In case the value that wants to be inserted is borrowed and also expensive or impossible\n    /// to clone. In such a scenario, the developer might want to check with `contains` before inserting,\n    /// to avoid the clone. In this case, it will report a false positive.\n    ///\n    /// ### Example\n    /// ```rust\n    /// use std::collections::HashSet;\n    /// let mut set = HashSet::new();\n    /// let value = 5;\n    /// if !set.contains(&value) {\n    ///     set.insert(value);\n    ///     println!(\"inserted {value:?}\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// use std::collections::HashSet;\n    /// let mut set = HashSet::new();\n    /// let value = 5;\n    /// if set.insert(&value) {\n    ///     println!(\"inserted {value:?}\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub SET_CONTAINS_OR_INSERT,\n    nursery,\n    \"call to `<set>::contains` followed by `<set>::insert`\"\n}\n\ndeclare_lint_pass!(SetContainsOrInsert => [SET_CONTAINS_OR_INSERT]);\n\nimpl<'tcx> LateLintPass<'tcx> for SetContainsOrInsert {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if !expr.span.from_expansion()\n            && let Some(higher::If {\n                cond: cond_expr,\n                then: then_expr,\n                ..\n            }) = higher::If::hir(expr)\n            && let Some((contains_expr, sym)) = try_parse_op_call(cx, cond_expr, sym::contains)//try_parse_contains(cx, cond_expr)\n            && let Some(insert_expr) = find_insert_calls(cx, &contains_expr, then_expr)\n        {\n            span_lint(\n                cx,\n                SET_CONTAINS_OR_INSERT,\n                vec![contains_expr.span, insert_expr.span],\n                format!(\"usage of `{sym}::insert` after `{sym}::contains`\"),\n            );\n        }\n    }\n}\n\nstruct OpExpr<'tcx> {\n    receiver: &'tcx Expr<'tcx>,\n    value: &'tcx Expr<'tcx>,\n    span: Span,\n}\n\nfn try_parse_op_call<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    symbol: Symbol,\n) -> Option<(OpExpr<'tcx>, Symbol)> {\n    let expr = peel_hir_expr_while(expr, |e| {\n        if let ExprKind::Unary(UnOp::Not, e) = e.kind {\n            Some(e)\n        } else {\n            None\n        }\n    });\n\n    if let ExprKind::MethodCall(path, receiver, [value], span) = expr.kind {\n        let value = value.peel_borrows();\n        let value = peel_hir_expr_while(value, |e| {\n            if let ExprKind::Unary(UnOp::Deref, e) = e.kind {\n                Some(e)\n            } else {\n                None\n            }\n        });\n        let receiver = receiver.peel_borrows();\n        let receiver_ty = cx.typeck_results().expr_ty(receiver).peel_refs();\n        if value.span.eq_ctxt(expr.span) && path.ident.name == symbol {\n            for sym in &[sym::HashSet, sym::BTreeSet] {\n                if receiver_ty.is_diag_item(cx, *sym) {\n                    return Some((OpExpr { receiver, value, span }, *sym));\n                }\n            }\n        }\n    }\n    None\n}\n\nfn is_set_mutated<'tcx>(cx: &LateContext<'tcx>, contains_expr: &OpExpr<'tcx>, expr: &'tcx Expr<'_>) -> bool {\n    // Guard on type to avoid useless potentially expansive `SpanlessEq` checks\n    cx.typeck_results().expr_ty_adjusted(expr).is_mutable_ptr()\n        && matches!(\n            cx.typeck_results().expr_ty(expr).peel_refs().opt_diag_name(cx),\n            Some(sym::HashSet | sym::BTreeSet)\n        )\n        && SpanlessEq::new(cx).eq_expr(contains_expr.receiver, expr.peel_borrows())\n}\n\nfn find_insert_calls<'tcx>(\n    cx: &LateContext<'tcx>,\n    contains_expr: &OpExpr<'tcx>,\n    expr: &'tcx Expr<'_>,\n) -> Option<OpExpr<'tcx>> {\n    for_each_expr(cx, expr, |e| {\n        if let Some((insert_expr, _)) = try_parse_op_call(cx, e, sym::insert)\n            && SpanlessEq::new(cx).eq_expr(contains_expr.receiver, insert_expr.receiver)\n            && SpanlessEq::new(cx).eq_expr(contains_expr.value, insert_expr.value)\n        {\n            return ControlFlow::Break(Some(insert_expr));\n        }\n\n        if is_set_mutated(cx, contains_expr, e) {\n            return ControlFlow::Break(None);\n        }\n\n        ControlFlow::Continue(())\n    })\n    .flatten()\n}\n"
  },
  {
    "path": "clippy_lints/src/shadow.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet;\nuse clippy_utils::visitors::{Descend, Visitable, for_each_expr};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::def::Res;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::hir_id::ItemLocalId;\nuse rustc_hir::{\n    Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, LetExpr, LocalSource, Node, Pat, PatKind, QPath, UnOp,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for bindings that shadow other bindings already in\n    /// scope, while reusing the original value.\n    ///\n    /// ### Why restrict this?\n    /// Some argue that name shadowing like this hurts readability,\n    /// because a value may be bound to different things depending on position in\n    /// the code.\n    ///\n    /// See also `shadow_same` and `shadow_unrelated` for other restrictions on shadowing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 2;\n    /// let x = x + 1;\n    /// ```\n    /// use different variable name:\n    /// ```no_run\n    /// let x = 2;\n    /// let y = x + 1;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SHADOW_REUSE,\n    restriction,\n    \"rebinding a name to an expression that reuses the original value, e.g., `let x = x + 1`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for bindings that shadow other bindings already in\n    /// scope, while just changing reference level or mutability.\n    ///\n    /// ### Why restrict this?\n    /// To require that what are formally distinct variables be given distinct names.\n    ///\n    /// See also `shadow_reuse` and `shadow_unrelated` for other restrictions on shadowing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let x = 1;\n    /// let x = &x;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let x = 1;\n    /// let y = &x; // use different variable name\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SHADOW_SAME,\n    restriction,\n    \"rebinding a name to itself, e.g., `let mut x = &mut x`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for bindings that shadow other bindings already in\n    /// scope, either without an initialization or with one that does not even use\n    /// the original value.\n    ///\n    /// ### Why restrict this?\n    /// Shadowing a binding with a closely related one is part of idiomatic Rust,\n    /// but shadowing a binding by accident with an unrelated one may indicate a mistake.\n    ///\n    /// Additionally, name shadowing in general can hurt readability, especially in\n    /// large code bases, because it is easy to lose track of the active binding at\n    /// any place in the code. If linting against all shadowing is desired, you may wish\n    /// to use the `shadow_same` and `shadow_reuse` lints as well.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let y = 1;\n    /// # let z = 2;\n    /// let x = y;\n    /// let x = z; // shadows the earlier binding\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let y = 1;\n    /// # let z = 2;\n    /// let x = y;\n    /// let w = z; // use different variable name\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SHADOW_UNRELATED,\n    restriction,\n    \"rebinding a name without even using the original value\"\n}\n\nimpl_lint_pass!(Shadow => [SHADOW_REUSE, SHADOW_SAME, SHADOW_UNRELATED]);\n\n#[derive(Default)]\npub(crate) struct Shadow {\n    bindings: Vec<(FxHashMap<Symbol, Vec<ItemLocalId>>, LocalDefId)>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Shadow {\n    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {\n        let PatKind::Binding(_, id, ident, _) = pat.kind else {\n            return;\n        };\n\n        if pat.span.desugaring_kind().is_some() || pat.span.from_expansion() {\n            return;\n        }\n\n        if ident.span.from_expansion() || ident.span.is_dummy() {\n            return;\n        }\n\n        // Desugaring of a destructuring assignment may reuse the same identifier internally.\n        // Peel `Pat` and `PatField` nodes and check if we reach a desugared `Let` assignment.\n        if let Some((_, Node::LetStmt(let_stmt))) = cx\n            .tcx\n            .hir_parent_iter(pat.hir_id)\n            .find(|(_, node)| !matches!(node, Node::Pat(_) | Node::PatField(_)))\n            && let LocalSource::AssignDesugar = let_stmt.source\n        {\n            return;\n        }\n\n        let HirId { owner, local_id } = id;\n        // get (or insert) the list of items for this owner and symbol\n        let (ref mut data, scope_owner) = *self.bindings.last_mut().unwrap();\n        let items_with_name = data.entry(ident.name).or_default();\n\n        // check other bindings with the same name, most recently seen first\n        for &prev in items_with_name.iter().rev() {\n            if prev == local_id {\n                // repeated binding in an `Or` pattern\n                return;\n            }\n\n            if is_shadow(cx, scope_owner, prev, local_id) {\n                let prev_hir_id = HirId { owner, local_id: prev };\n                lint_shadow(cx, pat, prev_hir_id, ident.span);\n                // only lint against the \"nearest\" shadowed binding\n                break;\n            }\n        }\n        // store the binding\n        items_with_name.push(local_id);\n    }\n\n    fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {\n        let owner_id = cx.tcx.hir_body_owner_def_id(body.id());\n        if !matches!(cx.tcx.hir_body_owner_kind(owner_id), BodyOwnerKind::Closure) {\n            self.bindings.push((FxHashMap::default(), owner_id));\n        }\n    }\n\n    fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {\n        if !matches!(\n            cx.tcx.hir_body_owner_kind(cx.tcx.hir_body_owner_def_id(body.id())),\n            BodyOwnerKind::Closure\n        ) {\n            self.bindings.pop();\n        }\n    }\n}\n\nfn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {\n    let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id());\n    if let Some(first_scope) = scope_tree.var_scope(first)\n        && let Some(second_scope) = scope_tree.var_scope(second)\n    {\n        return scope_tree.is_subscope_of(second_scope, first_scope);\n    }\n\n    false\n}\n\n/// Checks if the given local is used, except for in child expression of `except`.\n///\n/// This is a version of [`is_local_used`](clippy_utils::visitors::is_local_used), used to\n/// implement the fix for <https://github.com/rust-lang/rust-clippy/issues/10780>.\npub fn is_local_used_except<'tcx>(\n    cx: &LateContext<'tcx>,\n    visitable: impl Visitable<'tcx>,\n    id: HirId,\n    except: Option<HirId>,\n) -> bool {\n    for_each_expr(cx, visitable, |e| {\n        if except.is_some_and(|it| it == e.hir_id) {\n            ControlFlow::Continue(Descend::No)\n        } else if e.res_local_id() == Some(id) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(Descend::Yes)\n        }\n    })\n    .is_some()\n}\n\nfn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span) {\n    let (lint, msg) = match find_init(cx, pat.hir_id) {\n        Some((expr, _)) if is_self_shadow(cx, pat, expr, shadowed) => {\n            let msg = format!(\n                \"`{}` is shadowed by itself in `{}`\",\n                snippet(cx, pat.span, \"_\"),\n                snippet(cx, expr.span, \"..\")\n            );\n            (SHADOW_SAME, msg)\n        },\n        Some((expr, except)) if is_local_used_except(cx, expr, shadowed, except) => {\n            let msg = format!(\"`{}` is shadowed\", snippet(cx, pat.span, \"_\"));\n            (SHADOW_REUSE, msg)\n        },\n        _ => {\n            let msg = format!(\"`{}` shadows a previous, unrelated binding\", snippet(cx, pat.span, \"_\"));\n            (SHADOW_UNRELATED, msg)\n        },\n    };\n    span_lint_and_then(cx, lint, span, msg, |diag| {\n        diag.span_note(cx.tcx.hir_span(shadowed), \"previous binding is here\");\n    });\n}\n\n/// Returns true if the expression is a simple transformation of a local binding such as `&x`\nfn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_id: HirId) -> bool {\n    let is_direct_binding = cx\n        .tcx\n        .hir_parent_iter(pat.hir_id)\n        .map_while(|(_id, node)| match node {\n            Node::Pat(pat) => Some(pat),\n            _ => None,\n        })\n        .all(|pat| matches!(pat.kind, PatKind::Ref(..) | PatKind::Or(_)));\n    if !is_direct_binding {\n        return false;\n    }\n    loop {\n        expr = match expr.kind {\n            ExprKind::AddrOf(_, _, e)\n            | ExprKind::Block(\n                &Block {\n                    stmts: [],\n                    expr: Some(e),\n                    ..\n                },\n                _,\n            )\n            | ExprKind::Unary(UnOp::Deref, e) => e,\n            ExprKind::Path(QPath::Resolved(None, path)) => break path.res == Res::Local(hir_id),\n            _ => break false,\n        }\n    }\n}\n\n/// Finds the \"init\" expression for a pattern: `let <pat> = <init>;` (or `if let`) or\n/// `match <init> { .., <pat> => .., .. }`\n///\n/// For closure arguments passed to a method call, returns the method call, and the `HirId` of the\n/// closure (which will later be skipped). This is for <https://github.com/rust-lang/rust-clippy/issues/10780>\nfn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<(&'tcx Expr<'tcx>, Option<HirId>)> {\n    for (hir_id, node) in cx.tcx.hir_parent_iter(hir_id) {\n        let init = match node {\n            Node::Arm(_) | Node::Pat(_) | Node::PatField(_) | Node::Param(_) => continue,\n            Node::Expr(expr) => match expr.kind {\n                ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some((e, None)),\n                // If we're a closure argument, then a parent call is also an associated item.\n                ExprKind::Closure(_) => {\n                    if let Some((_, node)) = cx.tcx.hir_parent_iter(hir_id).next() {\n                        match node {\n                            Node::Expr(expr) => match expr.kind {\n                                ExprKind::MethodCall(_, _, _, _) | ExprKind::Call(_, _) => Some((expr, Some(hir_id))),\n                                _ => None,\n                            },\n                            _ => None,\n                        }\n                    } else {\n                        None\n                    }\n                },\n                _ => None,\n            },\n            Node::LetStmt(local) => local.init.map(|init| (init, None)),\n            _ => None,\n        };\n        return init;\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/significant_drop_tightening.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::{indent_of, snippet};\nuse clippy_utils::{expr_or_init, get_builtin_attr, peel_hir_expr_unary, sym};\nuse rustc_ast::BindingMode;\nuse rustc_data_structures::fx::{FxHashMap, FxIndexMap};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{self as hir, HirId};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{GenericArgKind, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::Ident;\nuse rustc_span::{DUMMY_SP, Span};\nuse std::borrow::Cow;\nuse std::collections::hash_map::Entry;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Searches for elements marked with `#[clippy::has_significant_drop]` that could be early\n    /// dropped but are in fact dropped at the end of their scopes. In other words, enforces the\n    /// \"tightening\" of their possible lifetimes.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Elements marked with `#[clippy::has_significant_drop]` are generally synchronizing\n    /// primitives that manage shared resources, as such, it is desired to release them as soon as\n    /// possible to avoid unnecessary resource contention.\n    ///\n    /// ### Example\n    ///\n    /// ```rust,ignore\n    /// fn main() {\n    ///   let lock = some_sync_resource.lock();\n    ///   let owned_rslt = lock.do_stuff_with_resource();\n    ///   // Only `owned_rslt` is needed but `lock` is still held.\n    ///   do_heavy_computation_that_takes_time(owned_rslt);\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```rust,ignore\n    /// fn main() {\n    ///     let owned_rslt = some_sync_resource.lock().do_stuff_with_resource();\n    ///     do_heavy_computation_that_takes_time(owned_rslt);\n    /// }\n    /// ```\n    #[clippy::version = \"1.69.0\"]\n    pub SIGNIFICANT_DROP_TIGHTENING,\n    nursery,\n    \"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\"\n}\n\nimpl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]);\n\n#[derive(Default)]\npub struct SignificantDropTightening<'tcx> {\n    apas: FxIndexMap<HirId, AuxParamsAttr>,\n    /// Auxiliary structure used to avoid having to verify the same type multiple times.\n    type_cache: FxHashMap<Ty<'tcx>, bool>,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        _: hir::intravisit::FnKind<'_>,\n        _: &hir::FnDecl<'_>,\n        body: &'tcx hir::Body<'_>,\n        _: Span,\n        _: hir::def_id::LocalDefId,\n    ) {\n        self.apas.clear();\n        let initial_dummy_stmt = dummy_stmt_expr(body.value);\n        let mut ap = AuxParams::new(&mut self.apas, &initial_dummy_stmt);\n        StmtsChecker::new(&mut ap, cx, &mut self.type_cache).visit_body(body);\n        for apa in ap.apas.values() {\n            if apa.counter <= 1 || !apa.has_expensive_expr_after_last_attr {\n                continue;\n            }\n            let first_bind_ident = apa.first_bind_ident.unwrap();\n            span_lint_and_then(\n                cx,\n                SIGNIFICANT_DROP_TIGHTENING,\n                first_bind_ident.span,\n                \"temporary with significant `Drop` can be early dropped\",\n                |diag| {\n                    match apa.counter {\n                        0 | 1 => {},\n                        2 if let Some(last_method_span) = apa.last_method_span => {\n                            let indent = \" \".repeat(indent_of(cx, apa.last_stmt_span).unwrap_or(0));\n                            let init_method = snippet(cx, apa.first_method_span, \"..\");\n                            let usage_method = snippet(cx, last_method_span, \"..\");\n                            let stmt = if let Some((binding_mode, last_bind_ident)) = apa.last_bind_ident {\n                                format!(\n                                    \"\\n{indent}let {}{} = {init_method}.{usage_method};\",\n                                    binding_mode.prefix_str(),\n                                    snippet(cx, last_bind_ident.span, \"..\"),\n                                )\n                            } else {\n                                format!(\"\\n{indent}{init_method}.{usage_method};\")\n                            };\n\n                            diag.multipart_suggestion(\n                                \"merge the temporary construction with its single usage\",\n                                vec![(apa.first_stmt_span, stmt), (apa.last_stmt_span, String::new())],\n                                Applicability::MaybeIncorrect,\n                            );\n                        },\n                        _ => {\n                            diag.span_suggestion(\n                                apa.last_stmt_span.shrink_to_hi(),\n                                \"drop the temporary after the end of its last usage\",\n                                format!(\n                                    \"\\n{}drop({});\",\n                                    \" \".repeat(indent_of(cx, apa.last_stmt_span).unwrap_or(0)),\n                                    first_bind_ident\n                                ),\n                                Applicability::MaybeIncorrect,\n                            );\n                        },\n                    }\n                    diag.note(\"this might lead to unnecessary resource contention\");\n                    diag.span_label(\n                        apa.first_block_span,\n                        format!(\n                            \"temporary `{first_bind_ident}` is currently being dropped at the end of its contained scope\"\n                        ),\n                    );\n                },\n            );\n        }\n    }\n}\n\n/// Checks the existence of the `#[has_significant_drop]` attribute.\nstruct AttrChecker<'cx, 'others, 'tcx> {\n    cx: &'cx LateContext<'tcx>,\n    type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>,\n}\n\nimpl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {\n    pub(crate) fn new(cx: &'cx LateContext<'tcx>, type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>) -> Self {\n        Self { cx, type_cache }\n    }\n\n    fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>, depth: usize) -> bool {\n        if !self.cx.tcx.recursion_limit().value_within_limit(depth) {\n            return false;\n        }\n        let ty = self\n            .cx\n            .tcx\n            .try_normalize_erasing_regions(self.cx.typing_env(), ty)\n            .unwrap_or(ty);\n        match self.type_cache.entry(ty) {\n            Entry::Occupied(e) => return *e.get(),\n            Entry::Vacant(e) => {\n                e.insert(false);\n            },\n        }\n        let value = self.has_sig_drop_attr_uncached(ty, depth + 1);\n        self.type_cache.insert(ty, value);\n        value\n    }\n\n    fn has_sig_drop_attr_uncached(&mut self, ty: Ty<'tcx>, depth: usize) -> bool {\n        if let Some(adt) = ty.ty_adt_def() {\n            let mut iter = get_builtin_attr(\n                self.cx.sess(),\n                #[allow(deprecated)]\n                self.cx.tcx.get_all_attrs(adt.did()),\n                sym::has_significant_drop,\n            );\n            if iter.next().is_some() {\n                return true;\n            }\n        }\n        match ty.kind() {\n            rustc_middle::ty::Adt(a, b) => {\n                for f in a.all_fields() {\n                    let ty = f.ty(self.cx.tcx, b);\n                    if self.has_sig_drop_attr(ty, depth) {\n                        return true;\n                    }\n                }\n                for generic_arg in *b {\n                    if let GenericArgKind::Type(ty) = generic_arg.kind()\n                        && self.has_sig_drop_attr(ty, depth)\n                    {\n                        return true;\n                    }\n                }\n                false\n            },\n            rustc_middle::ty::Array(ty, _)\n            | rustc_middle::ty::RawPtr(ty, _)\n            | rustc_middle::ty::Ref(_, ty, _)\n            | rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr(*ty, depth),\n            _ => false,\n        }\n    }\n}\n\nstruct StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> {\n    ap: &'ap mut AuxParams<'others, 'stmt, 'tcx>,\n    cx: &'lc LateContext<'tcx>,\n    type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>,\n}\n\nimpl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> {\n    fn new(\n        ap: &'ap mut AuxParams<'others, 'stmt, 'tcx>,\n        cx: &'lc LateContext<'tcx>,\n        type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>,\n    ) -> Self {\n        Self { ap, cx, type_cache }\n    }\n\n    fn manage_has_expensive_expr_after_last_attr(&mut self) {\n        let has_expensive_stmt = match self.ap.curr_stmt.kind {\n            hir::StmtKind::Expr(expr) if is_inexpensive_expr(expr) => false,\n            hir::StmtKind::Let(local)\n                if let Some(expr) = local.init\n                    && let hir::ExprKind::Path(_) = expr.kind =>\n            {\n                false\n            },\n            _ => true,\n        };\n        if has_expensive_stmt {\n            for apa in self.ap.apas.values_mut() {\n                let last_stmt_is_not_dummy = apa.last_stmt_span != DUMMY_SP;\n                let last_stmt_is_not_curr = self.ap.curr_stmt.span != apa.last_stmt_span;\n                let block_equals_curr = self.ap.curr_block_hir_id == apa.first_block_hir_id;\n                let block_is_ancestor = self\n                    .cx\n                    .tcx\n                    .hir_parent_iter(self.ap.curr_block_hir_id)\n                    .any(|(id, _)| id == apa.first_block_hir_id);\n                if last_stmt_is_not_dummy && last_stmt_is_not_curr && (block_equals_curr || block_is_ancestor) {\n                    apa.has_expensive_expr_after_last_attr = true;\n                }\n            }\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {\n    fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {\n        self.ap.curr_block_hir_id = block.hir_id;\n        self.ap.curr_block_span = block.span;\n        for stmt in block.stmts {\n            self.ap.curr_stmt = Cow::Borrowed(stmt);\n            self.visit_stmt(stmt);\n            self.ap.curr_block_hir_id = block.hir_id;\n            self.ap.curr_block_span = block.span;\n            self.manage_has_expensive_expr_after_last_attr();\n        }\n        if let Some(expr) = block.expr {\n            self.ap.curr_stmt = Cow::Owned(dummy_stmt_expr(expr));\n            self.visit_expr(expr);\n            self.ap.curr_block_hir_id = block.hir_id;\n            self.ap.curr_block_span = block.span;\n            self.manage_has_expensive_expr_after_last_attr();\n        }\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {\n        let modify_apa_params = |apa: &mut AuxParamsAttr| {\n            apa.counter = apa.counter.wrapping_add(1);\n            apa.has_expensive_expr_after_last_attr = false;\n        };\n        let mut ac = AttrChecker::new(self.cx, self.type_cache);\n        if ac.has_sig_drop_attr(self.cx.typeck_results().expr_ty(expr), 0) {\n            if let hir::StmtKind::Let(local) = self.ap.curr_stmt.kind\n                && let hir::PatKind::Binding(_, hir_id, ident, _) = local.pat.kind\n                && !self.ap.apas.contains_key(&hir_id)\n                && {\n                    if let Some(local_hir_id) = expr.res_local_id() {\n                        local_hir_id == hir_id\n                    } else {\n                        true\n                    }\n                }\n            {\n                let mut apa = AuxParamsAttr {\n                    first_block_hir_id: self.ap.curr_block_hir_id,\n                    first_block_span: self.ap.curr_block_span,\n                    first_bind_ident: Some(ident),\n                    first_method_span: {\n                        let expr_or_init = expr_or_init(self.cx, expr);\n                        if let hir::ExprKind::MethodCall(_, local_expr, _, span) = expr_or_init.kind {\n                            local_expr.span.to(span)\n                        } else {\n                            expr_or_init.span\n                        }\n                    },\n                    first_stmt_span: self.ap.curr_stmt.span,\n                    ..Default::default()\n                };\n                modify_apa_params(&mut apa);\n                let _ = self.ap.apas.insert(hir_id, apa);\n            } else {\n                let Some(hir_id) = expr.res_local_id() else {\n                    return;\n                };\n                let Some(apa) = self.ap.apas.get_mut(&hir_id) else {\n                    return;\n                };\n                match self.ap.curr_stmt.kind {\n                    hir::StmtKind::Let(local) => {\n                        if let hir::PatKind::Binding(binding_mode, _, ident, _) = local.pat.kind {\n                            apa.last_bind_ident = Some((binding_mode, ident));\n                        }\n                        if let Some(local_init) = local.init\n                            && let hir::ExprKind::MethodCall(_, _, _, span) = local_init.kind\n                        {\n                            apa.last_method_span = Some(span);\n                        }\n                    },\n                    hir::StmtKind::Semi(semi_expr) => {\n                        if has_drop(self.cx, semi_expr, apa.first_bind_ident) {\n                            apa.has_expensive_expr_after_last_attr = false;\n                            apa.last_stmt_span = DUMMY_SP;\n                            return;\n                        }\n                        if let hir::ExprKind::MethodCall(_, _, _, span) = semi_expr.kind {\n                            apa.last_method_span = Some(span);\n                        }\n                    },\n                    _ => {},\n                }\n                apa.last_stmt_span = self.ap.curr_stmt.span;\n                modify_apa_params(apa);\n            }\n        }\n        walk_expr(self, expr);\n    }\n}\n\n/// Auxiliary parameters used on each block check of an item\nstruct AuxParams<'others, 'stmt, 'tcx> {\n    //// See [AuxParamsAttr].\n    apas: &'others mut FxIndexMap<HirId, AuxParamsAttr>,\n    /// The current block identifier that is being visited.\n    curr_block_hir_id: HirId,\n    /// The current block span that is being visited.\n    curr_block_span: Span,\n    /// The current statement that is being visited.\n    curr_stmt: Cow<'stmt, hir::Stmt<'tcx>>,\n}\n\nimpl<'others, 'stmt, 'tcx> AuxParams<'others, 'stmt, 'tcx> {\n    fn new(apas: &'others mut FxIndexMap<HirId, AuxParamsAttr>, curr_stmt: &'stmt hir::Stmt<'tcx>) -> Self {\n        Self {\n            apas,\n            curr_block_hir_id: HirId::INVALID,\n            curr_block_span: DUMMY_SP,\n            curr_stmt: Cow::Borrowed(curr_stmt),\n        }\n    }\n}\n\n/// Auxiliary parameters used on expression created with `#[has_significant_drop]`.\n#[derive(Debug)]\nstruct AuxParamsAttr {\n    /// The number of times `#[has_significant_drop]` was referenced.\n    counter: usize,\n    /// If an expensive expression follows the last use of anything marked with\n    /// `#[has_significant_drop]`.\n    has_expensive_expr_after_last_attr: bool,\n\n    /// The identifier of the block that involves the first `#[has_significant_drop]`.\n    first_block_hir_id: HirId,\n    /// The span of the block that involves the first `#[has_significant_drop]`.\n    first_block_span: Span,\n    /// The binding or variable that references the initial construction of the type marked with\n    /// `#[has_significant_drop]`.\n    first_bind_ident: Option<Ident>,\n    /// Similar to `init_bind_ident` but encompasses the right-hand method call.\n    first_method_span: Span,\n    /// Similar to `init_bind_ident` but encompasses the whole contained statement.\n    first_stmt_span: Span,\n\n    /// The last visited binding or variable span within a block that had any referenced inner type\n    /// marked with `#[has_significant_drop]`.\n    last_bind_ident: Option<(BindingMode, Ident)>,\n    /// Similar to `last_bind_span` but encompasses the right-hand method call.\n    last_method_span: Option<Span>,\n    /// Similar to `last_bind_span` but encompasses the whole contained statement.\n    last_stmt_span: Span,\n}\n\nimpl Default for AuxParamsAttr {\n    fn default() -> Self {\n        Self {\n            counter: 0,\n            has_expensive_expr_after_last_attr: false,\n            first_block_hir_id: HirId::INVALID,\n            first_block_span: DUMMY_SP,\n            first_bind_ident: None,\n            first_method_span: DUMMY_SP,\n            first_stmt_span: DUMMY_SP,\n            last_bind_ident: None,\n            last_method_span: None,\n            last_stmt_span: DUMMY_SP,\n        }\n    }\n}\n\nfn dummy_stmt_expr<'any>(expr: &'any hir::Expr<'any>) -> hir::Stmt<'any> {\n    hir::Stmt {\n        hir_id: HirId::INVALID,\n        kind: hir::StmtKind::Expr(expr),\n        span: DUMMY_SP,\n    }\n}\n\nfn has_drop(cx: &LateContext<'_>, expr: &hir::Expr<'_>, first_bind_ident: Option<Ident>) -> bool {\n    if let hir::ExprKind::Call(fun, [first_arg]) = expr.kind\n        && let hir::ExprKind::Path(hir::QPath::Resolved(_, fun_path)) = &fun.kind\n        && let Res::Def(DefKind::Fn, did) = fun_path.res\n        && cx.tcx.is_diagnostic_item(sym::mem_drop, did)\n    {\n        let has_ident = |local_expr: &hir::Expr<'_>| {\n            if let hir::ExprKind::Path(hir::QPath::Resolved(_, arg_path)) = &local_expr.kind\n                && let [first_arg_ps, ..] = arg_path.segments\n                && let Some(first_bind_ident) = first_bind_ident\n                && first_arg_ps.ident == first_bind_ident\n            {\n                true\n            } else {\n                false\n            }\n        };\n        if has_ident(first_arg) {\n            return true;\n        }\n        if let hir::ExprKind::Tup(value) = &first_arg.kind\n            && value.iter().any(has_ident)\n        {\n            return true;\n        }\n    }\n    false\n}\n\nfn is_inexpensive_expr(expr: &hir::Expr<'_>) -> bool {\n    let actual = peel_hir_expr_unary(expr).0;\n    let is_path = matches!(actual.kind, hir::ExprKind::Path(_));\n    let is_lit = matches!(actual.kind, hir::ExprKind::Lit(_));\n    is_path || is_lit\n}\n"
  },
  {
    "path": "clippy_lints/src/single_call_fn.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::{is_from_proc_macro, is_in_test_function};\nuse rustc_data_structures::fx::{FxIndexMap, IndexEntry};\nuse rustc_hir::def::DefKind;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::{Expr, ExprKind, HirId, Node};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions that are only used once. Does not lint tests.\n    ///\n    /// ### Why restrict this?\n    /// If a function is only used once (perhaps because it used to be used more widely),\n    /// then the code could be simplified by moving that function's code into its caller.\n    ///\n    /// However, there are reasons not to do this everywhere:\n    ///\n    /// * Splitting a large function into multiple parts often improves readability\n    ///   by giving names to its parts.\n    /// * A function’s signature might serve a necessary purpose, such as constraining\n    ///   the type of a closure passed to it.\n    /// * Generic functions might call non-generic functions to reduce duplication\n    ///   in the produced machine code.\n    ///\n    /// If this lint is used, prepare to `#[allow]` it a lot.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub fn a<T>(t: &T)\n    /// where\n    ///     T: AsRef<str>,\n    /// {\n    ///     a_inner(t.as_ref())\n    /// }\n    ///\n    /// fn a_inner(t: &str) {\n    ///     /* snip */\n    /// }\n    ///\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// pub fn a<T>(t: &T)\n    /// where\n    ///     T: AsRef<str>,\n    /// {\n    ///     let t = t.as_ref();\n    ///     /* snip */\n    /// }\n    ///\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub SINGLE_CALL_FN,\n    restriction,\n    \"checks for functions that are only used once\"\n}\n\nimpl_lint_pass!(SingleCallFn => [SINGLE_CALL_FN]);\n\n#[derive(Debug, Clone)]\npub enum CallState {\n    Once { call_site: Span },\n    Multiple,\n}\n\npub struct SingleCallFn {\n    avoid_breaking_exported_api: bool,\n    def_id_to_usage: FxIndexMap<LocalDefId, CallState>,\n}\n\nimpl SingleCallFn {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n            def_id_to_usage: FxIndexMap::default(),\n        }\n    }\n\n    fn is_function_allowed(\n        &self,\n        cx: &LateContext<'_>,\n        fn_def_id: LocalDefId,\n        fn_hir_id: HirId,\n        fn_span: Span,\n    ) -> bool {\n        (self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(fn_def_id))\n            || fn_span.in_external_macro(cx.sess().source_map())\n            || cx\n                .tcx\n                .hir_maybe_body_owned_by(fn_def_id)\n                .is_none_or(|body| is_in_test_function(cx.tcx, body.value.hir_id))\n            || match cx.tcx.hir_node(fn_hir_id) {\n                Node::Item(item) => is_from_proc_macro(cx, item),\n                Node::ImplItem(item) => is_from_proc_macro(cx, item),\n                Node::TraitItem(item) => is_from_proc_macro(cx, item),\n                _ => true,\n            }\n    }\n}\n\n/// Whether a called function is a kind of item that the lint cares about.\n/// For example, calling an `extern \"C\" { fn fun(); }` only once is totally fine and does not\n/// to be considered.\nfn is_valid_item_kind(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {\n    matches!(\n        cx.tcx.hir_node_by_def_id(def_id),\n        Node::Item(_) | Node::ImplItem(_) | Node::TraitItem(_)\n    )\n}\n\nimpl<'tcx> LateLintPass<'tcx> for SingleCallFn {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Path(qpath) = expr.kind\n            && let res = cx.qpath_res(&qpath, expr.hir_id)\n            && let Some(call_def_id) = res.opt_def_id()\n            && let Some(def_id) = call_def_id.as_local()\n            && let DefKind::Fn | DefKind::AssocFn = cx.tcx.def_kind(def_id)\n            && is_valid_item_kind(cx, def_id)\n        {\n            match self.def_id_to_usage.entry(def_id) {\n                IndexEntry::Occupied(mut entry) => {\n                    if let CallState::Once { .. } = entry.get() {\n                        entry.insert(CallState::Multiple);\n                    }\n                },\n                IndexEntry::Vacant(entry) => {\n                    entry.insert(CallState::Once { call_site: expr.span });\n                },\n            }\n        }\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        for (&def_id, usage) in &self.def_id_to_usage {\n            if let CallState::Once { call_site } = *usage\n                && let fn_hir_id = cx.tcx.local_def_id_to_hir_id(def_id)\n                && let fn_span = cx.tcx.hir_span_with_body(fn_hir_id)\n                && !self.is_function_allowed(cx, def_id, fn_hir_id, fn_span)\n            {\n                span_lint_hir_and_then(\n                    cx,\n                    SINGLE_CALL_FN,\n                    fn_hir_id,\n                    fn_span,\n                    \"this function is only used once\",\n                    |diag| {\n                        diag.span_note(call_site, \"used here\");\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/single_char_lifetime_names.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::ast::{GenericParam, GenericParamKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for lifetimes with names which are one character\n    /// long.\n    ///\n    /// ### Why restrict this?\n    /// A single character is likely not enough to express the\n    /// purpose of a lifetime. Using a longer name can make code\n    /// easier to understand.\n    ///\n    /// ### Known problems\n    /// Rust programmers and learning resources tend to use single\n    /// character lifetimes, so this lint is at odds with the\n    /// ecosystem at large. In addition, the lifetime's purpose may\n    /// be obvious or, rarely, expressible in one character.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct DiagnosticCtx<'a> {\n    ///     source: &'a str,\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct DiagnosticCtx<'src> {\n    ///     source: &'src str,\n    /// }\n    /// ```\n    #[clippy::version = \"1.60.0\"]\n    pub SINGLE_CHAR_LIFETIME_NAMES,\n    restriction,\n    \"warns against single-character lifetime names\"\n}\n\ndeclare_lint_pass!(SingleCharLifetimeNames => [SINGLE_CHAR_LIFETIME_NAMES]);\n\nimpl EarlyLintPass for SingleCharLifetimeNames {\n    fn check_generic_param(&mut self, cx: &EarlyContext<'_>, param: &GenericParam) {\n        if param.ident.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        if let GenericParamKind::Lifetime = param.kind\n            && !param.is_placeholder\n            && param.ident.as_str().len() <= 2\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                SINGLE_CHAR_LIFETIME_NAMES,\n                param.ident.span,\n                \"single-character lifetime names are likely uninformative\",\n                |diag| {\n                    diag.help(\"use a more informative name\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/single_component_path_imports.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};\nuse rustc_ast::node_id::{NodeId, NodeMap};\nuse rustc_ast::visit::{Visitor, walk_expr};\nuse rustc_ast::{Crate, Expr, ExprKind, Item, ItemKind, MacroDef, ModKind, Ty, TyKind, UseTreeKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::edition::Edition;\nuse rustc_span::symbol::kw;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checking for imports with single component use path.\n    ///\n    /// ### Why is this bad?\n    /// Import with single component use path such as `use cratename;`\n    /// is not necessary, and thus should be removed.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// use regex;\n    ///\n    /// fn main() {\n    ///     regex::Regex::new(r\"^\\d{4}-\\d{2}-\\d{2}$\").unwrap();\n    /// }\n    /// ```\n    /// Better as\n    /// ```rust,ignore\n    /// fn main() {\n    ///     regex::Regex::new(r\"^\\d{4}-\\d{2}-\\d{2}$\").unwrap();\n    /// }\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub SINGLE_COMPONENT_PATH_IMPORTS,\n    style,\n    \"imports with single component path are redundant\"\n}\n\nimpl_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]);\n\n#[derive(Default)]\npub struct SingleComponentPathImports {\n    /// Buffer found usages to emit when visiting that item so that `#[allow]` works as expected\n    found: NodeMap<Vec<SingleUse>>,\n}\n\nstruct SingleUse {\n    name: Symbol,\n    span: Span,\n    item_id: NodeId,\n    can_suggest: bool,\n}\n\nimpl EarlyLintPass for SingleComponentPathImports {\n    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {\n        if cx.sess().opts.edition < Edition::Edition2018 {\n            return;\n        }\n\n        self.check_mod(&krate.items);\n    }\n\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        for SingleUse { span, can_suggest, .. } in self.found.remove(&item.id).into_iter().flatten() {\n            if can_suggest {\n                span_lint_and_sugg(\n                    cx,\n                    SINGLE_COMPONENT_PATH_IMPORTS,\n                    span,\n                    \"this import is redundant\",\n                    \"remove it entirely\",\n                    String::new(),\n                    Applicability::MachineApplicable,\n                );\n            } else {\n                span_lint_and_help(\n                    cx,\n                    SINGLE_COMPONENT_PATH_IMPORTS,\n                    span,\n                    \"this import is redundant\",\n                    None,\n                    \"remove this import\",\n                );\n            }\n        }\n    }\n}\n\n#[derive(Default)]\nstruct ImportUsageVisitor {\n    // keep track of imports reused with `self` keyword, such as `self::std` in the example below.\n    // Removing the `use std;` would make this a compile error (#10549)\n    // ```\n    // use std;\n    //\n    // fn main() {\n    //     let _ = self::std::io::stdout();\n    // }\n    // ```\n    imports_referenced_with_self: Vec<Symbol>,\n}\n\nimpl Visitor<'_> for ImportUsageVisitor {\n    fn visit_expr(&mut self, expr: &Expr) {\n        if let ExprKind::Path(_, path) = &expr.kind\n            && path.segments.len() > 1\n            && path.segments[0].ident.name == kw::SelfLower\n        {\n            self.imports_referenced_with_self.push(path.segments[1].ident.name);\n        }\n        walk_expr(self, expr);\n    }\n\n    fn visit_ty(&mut self, ty: &Ty) {\n        if let TyKind::Path(_, path) = &ty.kind\n            && path.segments.len() > 1\n            && path.segments[0].ident.name == kw::SelfLower\n        {\n            self.imports_referenced_with_self.push(path.segments[1].ident.name);\n        }\n    }\n}\n\nimpl SingleComponentPathImports {\n    fn check_mod(&mut self, items: &[Box<Item>]) {\n        // keep track of imports reused with `self` keyword, such as `self::crypto_hash` in the example\n        // below. Removing the `use crypto_hash;` would make this a compile error\n        // ```\n        // use crypto_hash;\n        //\n        // use self::crypto_hash::{Algorithm, Hasher};\n        // ```\n        let mut imports_reused_with_self = Vec::new();\n\n        // keep track of single use statements such as `crypto_hash` in the example below\n        // ```\n        // use crypto_hash;\n        // ```\n        let mut single_use_usages = Vec::new();\n\n        // keep track of macros defined in the module as we don't want it to trigger on this (#7106)\n        // ```\n        // macro_rules! foo { () => {} };\n        // pub(crate) use foo;\n        // ```\n        let mut macros = Vec::new();\n\n        let mut import_usage_visitor = ImportUsageVisitor::default();\n        for item in items {\n            self.track_uses(item, &mut imports_reused_with_self, &mut single_use_usages, &mut macros);\n            import_usage_visitor.visit_item(item);\n        }\n\n        for usage in single_use_usages {\n            if !imports_reused_with_self.contains(&usage.name)\n                && !import_usage_visitor.imports_referenced_with_self.contains(&usage.name)\n            {\n                self.found.entry(usage.item_id).or_default().push(usage);\n            }\n        }\n    }\n\n    fn track_uses(\n        &mut self,\n        item: &Item,\n        imports_reused_with_self: &mut Vec<Symbol>,\n        single_use_usages: &mut Vec<SingleUse>,\n        macros: &mut Vec<Symbol>,\n    ) {\n        if item.span.from_expansion() || item.vis.kind.is_pub() {\n            return;\n        }\n\n        match &item.kind {\n            ItemKind::Mod(_, _, ModKind::Loaded(items, ..)) => {\n                self.check_mod(items);\n            },\n            ItemKind::MacroDef(ident, MacroDef { macro_rules: true, .. }) => {\n                macros.push(ident.name);\n            },\n            ItemKind::Use(use_tree) => {\n                let segments = &use_tree.prefix.segments;\n\n                // keep track of `use some_module;` usages\n                if segments.len() == 1 {\n                    if let UseTreeKind::Simple(None) = use_tree.kind {\n                        let name = segments[0].ident.name;\n                        if !macros.contains(&name) {\n                            single_use_usages.push(SingleUse {\n                                name,\n                                span: item.span,\n                                item_id: item.id,\n                                can_suggest: true,\n                            });\n                        }\n                    }\n                    return;\n                }\n\n                if segments.is_empty() {\n                    // keep track of `use {some_module, some_other_module};` usages\n                    if let UseTreeKind::Nested { items, .. } = &use_tree.kind {\n                        for tree in items {\n                            let segments = &tree.0.prefix.segments;\n                            if segments.len() == 1\n                                && let UseTreeKind::Simple(None) = tree.0.kind\n                            {\n                                let name = segments[0].ident.name;\n                                if !macros.contains(&name) {\n                                    single_use_usages.push(SingleUse {\n                                        name,\n                                        span: tree.0.span,\n                                        item_id: item.id,\n                                        can_suggest: false,\n                                    });\n                                }\n                            }\n                        }\n                    }\n                }\n                // keep track of `use self::some_module` usages\n                else if segments[0].ident.name == kw::SelfLower {\n                    // simple case such as `use self::module::SomeStruct`\n                    if segments.len() > 1 {\n                        imports_reused_with_self.push(segments[1].ident.name);\n                        return;\n                    }\n\n                    // nested case such as `use self::{module1::Struct1, module2::Struct2}`\n                    if let UseTreeKind::Nested { items, .. } = &use_tree.kind {\n                        for tree in items {\n                            let segments = &tree.0.prefix.segments;\n                            if !segments.is_empty() {\n                                imports_reused_with_self.push(segments[0].ident.name);\n                            }\n                        }\n                    }\n                }\n            },\n            _ => {},\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/single_option_map.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::peel_blocks;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse rustc_hir::def::Res;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, ExprKind, FnDecl, FnRetTy};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions with method calls to `.map(_)` on an arg\n    /// of type `Option` as the outermost expression.\n    ///\n    /// ### Why is this bad?\n    /// Taking and returning an `Option<T>` may require additional\n    /// `Some(_)` and `unwrap` if all you have is a `T`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn double(param: Option<u32>) -> Option<u32> {\n    ///     param.map(|x| x * 2)\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn double(param: u32) -> u32 {\n    ///     param * 2\n    /// }\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub SINGLE_OPTION_MAP,\n    nursery,\n    \"Checks for functions with method calls to `.map(_)` on an arg of type `Option` as the outermost expression.\"\n}\n\ndeclare_lint_pass!(SingleOptionMap => [SINGLE_OPTION_MAP]);\n\nimpl<'tcx> LateLintPass<'tcx> for SingleOptionMap {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'tcx>,\n        body: &'tcx Body<'tcx>,\n        span: Span,\n        _fn_def: LocalDefId,\n    ) {\n        if let FnRetTy::Return(_ret) = decl.output\n            && matches!(kind, FnKind::ItemFn(_, _, _) | FnKind::Method(_, _))\n        {\n            let func_body = peel_blocks(body.value);\n            if let ExprKind::MethodCall(method_name, callee, args, _span) = func_body.kind\n                && method_name.ident.name == sym::map\n                && let callee_type = cx.typeck_results().expr_ty(callee)\n                && callee_type.is_diag_item(cx, sym::Option)\n                && let ExprKind::Path(_path) = callee.kind\n                && matches!(callee.basic_res(), Res::Local(_))\n                && !matches!(args[0].kind, ExprKind::Path(_))\n            {\n                if let ExprKind::Closure(closure) = args[0].kind {\n                    let Body { params: [..], value } = cx.tcx.hir_body(closure.body);\n                    if let ExprKind::Call(func, f_args) = value.kind\n                        && matches!(func.kind, ExprKind::Path(_))\n                        && f_args.iter().all(|arg| matches!(arg.kind, ExprKind::Path(_)))\n                    {\n                        return;\n                    } else if let ExprKind::MethodCall(_segment, receiver, method_args, _span) = value.kind\n                        && matches!(receiver.kind, ExprKind::Path(_))\n                        && method_args.iter().all(|arg| matches!(arg.kind, ExprKind::Path(_)))\n                        && method_args.iter().all(|arg| matches!(arg.basic_res(), Res::Local(_)))\n                    {\n                        return;\n                    }\n                }\n\n                span_lint_and_help(\n                    cx,\n                    SINGLE_OPTION_MAP,\n                    span,\n                    \"`fn` that only maps over argument\",\n                    None,\n                    \"move the `.map` to the caller or to an `_opt` function\",\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/single_range_in_vec_init.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::VecArgs;\nuse clippy_utils::macros::root_macro_call_first_node;\nuse clippy_utils::source::{SpanRangeExt, snippet_with_context};\nuse clippy_utils::ty::implements_trait;\nuse clippy_utils::{is_no_std_crate, sym};\nuse rustc_ast::{LitIntType, LitKind, UintTy};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, StructTailExpr};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::DesugaringKind;\nuse std::fmt::{self, Display, Formatter};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `Vec` or array initializations that contain only one range.\n    ///\n    /// ### Why is this bad?\n    /// This is almost always incorrect, as it will result in a `Vec` that has only one element.\n    /// Almost always, the programmer intended for it to include all elements in the range or for\n    /// the end of the range to be the length instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = [0..200];\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// // If it was intended to include every element in the range...\n    /// let x = (0..200).collect::<Vec<i32>>();\n    /// // ...Or if 200 was meant to be the len\n    /// let x = [0; 200];\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub SINGLE_RANGE_IN_VEC_INIT,\n    suspicious,\n    \"checks for initialization of `Vec` or arrays which consist of a single range\"\n}\n\ndeclare_lint_pass!(SingleRangeInVecInit => [SINGLE_RANGE_IN_VEC_INIT]);\n\nenum SuggestedType {\n    Vec,\n    Array,\n}\n\nimpl SuggestedType {\n    fn starts_with(&self) -> &'static str {\n        if matches!(self, SuggestedType::Vec) {\n            \"vec!\"\n        } else {\n            \"[\"\n        }\n    }\n\n    fn ends_with(&self) -> &'static str {\n        if matches!(self, SuggestedType::Vec) { \"\" } else { \"]\" }\n    }\n}\n\nimpl Display for SuggestedType {\n    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {\n        if matches!(&self, SuggestedType::Vec) {\n            write!(f, \"a `Vec`\")\n        } else {\n            write!(f, \"an array\")\n        }\n    }\n}\n\nimpl LateLintPass<'_> for SingleRangeInVecInit {\n    fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        // inner_expr: `vec![0..200]` or `[0..200]`\n        //                   ^^^^^^       ^^^^^^^\n        // span: `vec![0..200]` or `[0..200]`\n        //        ^^^^^^^^^^^^      ^^^^^^^^\n        // suggested_type: What to print, \"an array\" or \"a `Vec`\"\n        let (inner_expr, span, suggested_type) = if let ExprKind::Array([inner_expr]) = expr.kind\n            && !expr.span.from_expansion()\n        {\n            (inner_expr, expr.span, SuggestedType::Array)\n        } else if let Some(macro_call) = root_macro_call_first_node(cx, expr)\n            && let Some(VecArgs::Vec([expr])) = VecArgs::hir(cx, expr)\n        {\n            (expr, macro_call.span, SuggestedType::Vec)\n        } else {\n            return;\n        };\n\n        let ExprKind::Struct(_, [start, end], StructTailExpr::None) = inner_expr.kind else {\n            return;\n        };\n\n        if inner_expr.span.is_desugaring(DesugaringKind::RangeExpr)\n            && let ty = cx.typeck_results().expr_ty(start.expr)\n            && let Some(snippet) = span.get_source_text(cx)\n            // `is_from_proc_macro` will skip any `vec![]`. Let's not!\n            && snippet.starts_with(suggested_type.starts_with())\n            && snippet.ends_with(suggested_type.ends_with())\n        {\n            let mut applicability = Applicability::MaybeIncorrect;\n            let (start_snippet, _) = snippet_with_context(cx, start.expr.span, span.ctxt(), \"..\", &mut applicability);\n            let (end_snippet, _) = snippet_with_context(cx, end.expr.span, span.ctxt(), \"..\", &mut applicability);\n\n            let should_emit_every_value = if let Some(step_def_id) = cx.tcx.get_diagnostic_item(sym::range_step)\n                && implements_trait(cx, ty, step_def_id, &[])\n            {\n                true\n            } else {\n                false\n            };\n            let should_emit_of_len = if let Some(copy_def_id) = cx.tcx.lang_items().copy_trait()\n                && implements_trait(cx, ty, copy_def_id, &[])\n                && let ExprKind::Lit(lit_kind) = end.expr.kind\n                && let LitKind::Int(.., suffix_type) = lit_kind.node\n                && let LitIntType::Unsigned(UintTy::Usize) | LitIntType::Unsuffixed = suffix_type\n            {\n                true\n            } else {\n                false\n            };\n\n            if should_emit_every_value || should_emit_of_len {\n                span_lint_and_then(\n                    cx,\n                    SINGLE_RANGE_IN_VEC_INIT,\n                    span,\n                    format!(\"{suggested_type} of `Range` that is only one element\"),\n                    |diag| {\n                        if should_emit_every_value && !is_no_std_crate(cx) {\n                            diag.span_suggestion(\n                                span,\n                                \"if you wanted a `Vec` that contains the entire range, try\",\n                                format!(\"({start_snippet}..{end_snippet}).collect::<std::vec::Vec<{ty}>>()\"),\n                                applicability,\n                            );\n                        }\n\n                        if should_emit_of_len {\n                            diag.span_suggestion(\n                                inner_expr.span,\n                                format!(\"if you wanted {suggested_type} of len {end_snippet}, try\"),\n                                format!(\"{start_snippet}; {end_snippet}\"),\n                                applicability,\n                            );\n                        }\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/size_of_in_element_count.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::sym;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects expressions where\n    /// `size_of::<T>` or `size_of_val::<T>` is used as a\n    /// count of elements of type `T`\n    ///\n    /// ### Why is this bad?\n    /// These functions expect a count\n    /// of `T` and not a number of bytes\n    ///\n    /// ### Example\n    /// ```rust,no_run\n    /// # use std::ptr::copy_nonoverlapping;\n    /// const SIZE: usize = 128;\n    /// let x = [2u8; SIZE];\n    /// let mut y = [2u8; SIZE];\n    /// unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };\n    /// ```\n    #[clippy::version = \"1.50.0\"]\n    pub SIZE_OF_IN_ELEMENT_COUNT,\n    correctness,\n    \"using `size_of::<T>` or `size_of_val::<T>` where a count of elements of `T` is expected\"\n}\n\ndeclare_lint_pass!(SizeOfInElementCount => [SIZE_OF_IN_ELEMENT_COUNT]);\n\nfn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, inverted: bool) -> Option<Ty<'tcx>> {\n    match expr.kind {\n        ExprKind::Call(count_func, _) => {\n            if !inverted\n                && let ExprKind::Path(ref count_func_qpath) = count_func.kind\n                && let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id()\n                && matches!(\n                    cx.tcx.get_diagnostic_name(def_id),\n                    Some(sym::mem_size_of | sym::mem_size_of_val)\n                )\n            {\n                cx.typeck_results().node_args(count_func.hir_id).types().next()\n            } else {\n                None\n            }\n        },\n        ExprKind::Binary(op, left, right) if BinOpKind::Mul == op.node => {\n            get_size_of_ty(cx, left, inverted).or_else(|| get_size_of_ty(cx, right, inverted))\n        },\n        ExprKind::Binary(op, left, right) if BinOpKind::Div == op.node => {\n            get_size_of_ty(cx, left, inverted).or_else(|| get_size_of_ty(cx, right, !inverted))\n        },\n        ExprKind::Cast(expr, _) => get_size_of_ty(cx, expr, inverted),\n        _ => None,\n    }\n}\n\nfn get_pointee_ty_and_count_expr<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n) -> Option<(Ty<'tcx>, &'tcx Expr<'tcx>)> {\n    const METHODS: [Symbol; 10] = [\n        sym::copy_to,\n        sym::copy_from,\n        sym::copy_to_nonoverlapping,\n        sym::copy_from_nonoverlapping,\n        sym::add,\n        sym::wrapping_add,\n        sym::sub,\n        sym::wrapping_sub,\n        sym::offset,\n        sym::wrapping_offset,\n    ];\n\n    if let ExprKind::Call(func, [.., count]) = expr.kind\n        // Find calls to ptr::{copy, copy_nonoverlapping}\n        // and ptr::swap_nonoverlapping,\n        && let ExprKind::Path(ref func_qpath) = func.kind\n        && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id()\n        && matches!(cx.tcx.get_diagnostic_name(def_id), Some(\n            sym::ptr_copy\n            | sym::ptr_copy_nonoverlapping\n            | sym::ptr_slice_from_raw_parts\n            | sym::ptr_slice_from_raw_parts_mut\n            | sym::ptr_swap_nonoverlapping\n            | sym::slice_from_raw_parts\n            | sym::slice_from_raw_parts_mut\n        ))\n\n        // Get the pointee type\n        && let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).types().next()\n    {\n        return Some((pointee_ty, count));\n    }\n    if let ExprKind::MethodCall(method_path, ptr_self, [.., count], _) = expr.kind\n        // Find calls to copy_{from,to}{,_nonoverlapping}\n        && let method_ident = method_path.ident.name\n        && METHODS.contains(&method_ident)\n\n        // Get the pointee type\n        && let ty::RawPtr(pointee_ty, _) =\n            cx.typeck_results().expr_ty(ptr_self).kind()\n    {\n        return Some((*pointee_ty, count));\n    }\n    None\n}\n\nimpl<'tcx> LateLintPass<'tcx> for SizeOfInElementCount {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        const HELP_MSG: &str = \"use a count of elements instead of a count of bytes\\\n            , it already gets multiplied by the size of the type\";\n\n        const LINT_MSG: &str = \"found a count of bytes \\\n             instead of a count of elements of `T`\";\n\n        if let Some((pointee_ty, count_expr)) = get_pointee_ty_and_count_expr(cx, expr)\n            // Using a number of bytes for a byte type isn't suspicious\n            && pointee_ty != cx.tcx.types.u8\n            // Find calls to functions with an element count parameter and get\n            // the pointee type and count parameter expression\n\n            // Find a size_of call in the count parameter expression and\n            // check that it's the same type\n            && let Some(ty_used_for_size_of) = get_size_of_ty(cx, count_expr, false)\n            && pointee_ty == ty_used_for_size_of\n        {\n            span_lint_and_help(cx, SIZE_OF_IN_ELEMENT_COUNT, count_expr.span, LINT_MSG, None, HELP_MSG);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/size_of_ref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::sym;\nuse clippy_utils::ty::peel_and_count_ty_refs;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for calls to `size_of_val()` where the argument is\n    /// a reference to a reference.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Calling `size_of_val()` with a reference to a reference as the argument\n    /// yields the size of the reference-type, not the size of the value behind\n    /// the reference.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo {\n    ///     buffer: [u8],\n    /// }\n    ///\n    /// impl Foo {\n    ///     fn size(&self) -> usize {\n    ///         // Note that `&self` as an argument is a `&&Foo`: Because `self`\n    ///         // is already a reference, `&self` is a double-reference.\n    ///         // The return value of `size_of_val()` therefore is the\n    ///         // size of the reference-type, not the size of `self`.\n    ///         size_of_val(&self)\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct Foo {\n    ///     buffer: [u8],\n    /// }\n    ///\n    /// impl Foo {\n    ///     fn size(&self) -> usize {\n    ///         // Correct\n    ///         size_of_val(self)\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.68.0\"]\n    pub SIZE_OF_REF,\n    suspicious,\n    \"Argument to `size_of_val()` is a double-reference, which is almost certainly unintended\"\n}\n\ndeclare_lint_pass!(SizeOfRef => [SIZE_OF_REF]);\n\nimpl LateLintPass<'_> for SizeOfRef {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        if let ExprKind::Call(path, [arg]) = expr.kind\n            && path.basic_res().is_diag_item(cx, sym::mem_size_of_val)\n            && let arg_ty = cx.typeck_results().expr_ty(arg)\n            && peel_and_count_ty_refs(arg_ty).1 > 1\n        {\n            span_lint_and_help(\n                cx,\n                SIZE_OF_REF,\n                expr.span,\n                \"argument to `size_of_val()` is a reference to a reference\",\n                None,\n                \"dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/slow_vector_initialization.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::macros::matching_root_macro_call;\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{SpanlessEq, get_enclosing_block, is_integer_literal, span_contains_comment, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};\nuse rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, PatKind, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks slow zero-filled vector initialization\n    ///\n    /// ### Why is this bad?\n    /// These structures are non-idiomatic and less efficient than simply using\n    /// `vec![0; len]`.\n    ///\n    /// Specifically, for `vec![0; len]`, the compiler can use a specialized type of allocation\n    /// that also zero-initializes the allocated memory in the same call\n    /// (see: [alloc_zeroed](https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#method.alloc_zeroed)).\n    ///\n    /// Writing `Vec::new()` followed by `vec.resize(len, 0)` is suboptimal because,\n    /// while it does do the same number of allocations,\n    /// it involves two operations for allocating and initializing.\n    /// The `resize` call first allocates memory (since `Vec::new()` did not), and only *then* zero-initializes it.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use core::iter::repeat;\n    /// # let len = 4;\n    /// let mut vec1 = Vec::new();\n    /// vec1.resize(len, 0);\n    ///\n    /// let mut vec2 = Vec::with_capacity(len);\n    /// vec2.resize(len, 0);\n    ///\n    /// let mut vec3 = Vec::with_capacity(len);\n    /// vec3.extend(repeat(0).take(len));\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let len = 4;\n    /// let mut vec1 = vec![0; len];\n    /// let mut vec2 = vec![0; len];\n    /// let mut vec3 = vec![0; len];\n    /// ```\n    #[clippy::version = \"1.32.0\"]\n    pub SLOW_VECTOR_INITIALIZATION,\n    perf,\n    \"slow vector initialization\"\n}\n\ndeclare_lint_pass!(SlowVectorInit => [SLOW_VECTOR_INITIALIZATION]);\n\n/// `VecAllocation` contains data regarding a vector allocated with `with_capacity` and then\n/// assigned to a variable. For example, `let mut vec = Vec::with_capacity(0)` or\n/// `vec = Vec::with_capacity(0)`\nstruct VecAllocation<'tcx> {\n    /// `HirId` of the variable\n    local_id: HirId,\n\n    /// Reference to the expression which allocates the vector\n    allocation_expr: &'tcx Expr<'tcx>,\n\n    /// Reference to the expression used as argument on `with_capacity` call. This is used\n    /// to only match slow zero-filling idioms of the same length than vector initialization.\n    size_expr: InitializedSize<'tcx>,\n}\n\n/// Initializer for the creation of the vector.\n///\n/// When `Vec::with_capacity(size)` is found, the `size` expression will be in\n/// `InitializedSize::Initialized`.\n///\n/// Otherwise, for `Vec::new()` calls, there is no allocation initializer yet, so\n/// `InitializedSize::Uninitialized` is used.\n/// Later, when a call to `.resize(size, 0)` or similar is found, it's set\n/// to `InitializedSize::Initialized(size)`.\n///\n/// Since it will be set to `InitializedSize::Initialized(size)` when a slow initialization is\n/// found, it is always safe to \"unwrap\" it at lint time.\nenum InitializedSize<'tcx> {\n    Initialized(&'tcx Expr<'tcx>),\n    Uninitialized,\n}\n\n/// Type of slow initialization\nenum InitializationType<'tcx> {\n    /// Extend is a slow initialization with the form `vec.extend(repeat(0).take(..))`\n    Extend(&'tcx Expr<'tcx>),\n\n    /// Resize is a slow initialization with the form `vec.resize(.., 0)`\n    Resize(&'tcx Expr<'tcx>),\n}\n\nimpl<'tcx> LateLintPass<'tcx> for SlowVectorInit {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        // Matches initialization on reassignments. For example: `vec = Vec::with_capacity(100)`\n        if let ExprKind::Assign(left, right, _) = expr.kind\n            && let Some(local_id) = left.res_local_id()\n            && let Some(size_expr) = Self::as_vec_initializer(cx, right)\n        {\n            let vi = VecAllocation {\n                local_id,\n                allocation_expr: right,\n                size_expr,\n            };\n\n            Self::search_initialization(cx, vi, expr.hir_id);\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        // Matches statements which initializes vectors. For example: `let mut vec = Vec::with_capacity(10)`\n        // or `Vec::new()`\n        if let StmtKind::Let(local) = stmt.kind\n            && let PatKind::Binding(BindingMode::MUT, local_id, _, None) = local.pat.kind\n            && let Some(init) = local.init\n            && let Some(size_expr) = Self::as_vec_initializer(cx, init)\n        {\n            let vi = VecAllocation {\n                local_id,\n                allocation_expr: init,\n                size_expr,\n            };\n\n            Self::search_initialization(cx, vi, stmt.hir_id);\n        }\n    }\n}\n\nimpl SlowVectorInit {\n    /// Looks for `Vec::with_capacity(size)` or `Vec::new()` calls and returns the initialized size,\n    /// if any. More specifically, it returns:\n    /// - `Some(InitializedSize::Initialized(size))` for `Vec::with_capacity(size)`\n    /// - `Some(InitializedSize::Uninitialized)` for `Vec::new()`\n    /// - `None` for other, unrelated kinds of expressions\n    fn as_vec_initializer<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<InitializedSize<'tcx>> {\n        // Generally don't warn if the vec initializer comes from an expansion, except for the vec! macro.\n        // This lets us still warn on `vec![]`, while ignoring other kinds of macros that may output an\n        // empty vec\n        if expr.span.from_expansion() && matching_root_macro_call(cx, expr.span, sym::vec_macro).is_none() {\n            return None;\n        }\n\n        if let ExprKind::Call(func, [len_expr]) = expr.kind\n            && func.ty_rel_def(cx).is_diag_item(cx, sym::vec_with_capacity)\n        {\n            Some(InitializedSize::Initialized(len_expr))\n        } else if let ExprKind::Call(func, []) = expr.kind\n            && func.ty_rel_def(cx).is_diag_item(cx, sym::vec_new)\n        {\n            Some(InitializedSize::Uninitialized)\n        } else {\n            None\n        }\n    }\n\n    /// Search initialization for the given vector\n    fn search_initialization<'tcx>(cx: &LateContext<'tcx>, vec_alloc: VecAllocation<'tcx>, parent_node: HirId) {\n        let enclosing_body = get_enclosing_block(cx, parent_node);\n\n        if enclosing_body.is_none() {\n            return;\n        }\n\n        let mut v = VectorInitializationVisitor {\n            cx,\n            vec_alloc,\n            slow_expression: None,\n            initialization_found: false,\n        };\n\n        v.visit_block(enclosing_body.unwrap());\n\n        if let Some(ref allocation_expr) = v.slow_expression {\n            Self::lint_initialization(cx, allocation_expr, &v.vec_alloc);\n        }\n    }\n\n    fn lint_initialization<'tcx>(\n        cx: &LateContext<'tcx>,\n        initialization: &InitializationType<'tcx>,\n        vec_alloc: &VecAllocation<'_>,\n    ) {\n        match initialization {\n            InitializationType::Extend(e) | InitializationType::Resize(e) => {\n                Self::emit_lint(cx, e, vec_alloc, \"slow zero-filling initialization\");\n            },\n        }\n    }\n\n    fn emit_lint(cx: &LateContext<'_>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &'static str) {\n        let len_expr = Sugg::hir(\n            cx,\n            match vec_alloc.size_expr {\n                InitializedSize::Initialized(expr) => expr,\n                InitializedSize::Uninitialized => unreachable!(\"size expression must be set by this point\"),\n            },\n            \"len\",\n        );\n\n        let span_to_replace = slow_fill\n            .span\n            .with_lo(vec_alloc.allocation_expr.span.source_callsite().lo());\n\n        // If there is no comment in `span_to_replace`, Clippy can automatically fix the code.\n        let app = if span_contains_comment(cx, span_to_replace) {\n            Applicability::Unspecified\n        } else {\n            Applicability::MachineApplicable\n        };\n\n        span_lint_and_sugg(\n            cx,\n            SLOW_VECTOR_INITIALIZATION,\n            span_to_replace,\n            msg,\n            \"consider replacing this with\",\n            format!(\"vec![0; {len_expr}]\"),\n            app,\n        );\n    }\n}\n\n/// `VectorInitializationVisitor` searches for unsafe or slow vector initializations for the given\n/// vector.\nstruct VectorInitializationVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n\n    /// Contains the information.\n    vec_alloc: VecAllocation<'tcx>,\n\n    /// Contains the slow initialization expression, if one was found.\n    slow_expression: Option<InitializationType<'tcx>>,\n\n    /// `true` if the initialization of the vector has been found on the visited block.\n    initialization_found: bool,\n}\n\nimpl<'tcx> VectorInitializationVisitor<'_, 'tcx> {\n    /// Checks if the given expression is extending a vector with `repeat(0).take(..)`\n    fn search_slow_extend_filling(&mut self, expr: &'tcx Expr<'_>) {\n        if self.initialization_found\n            && let ExprKind::MethodCall(path, self_arg, [extend_arg], _) = expr.kind\n            && self_arg.res_local_id() == Some(self.vec_alloc.local_id)\n            && path.ident.name == sym::extend\n            && self.is_repeat_take(extend_arg)\n        {\n            self.slow_expression = Some(InitializationType::Extend(expr));\n        }\n    }\n\n    /// Checks if the given expression is resizing a vector with 0\n    fn search_slow_resize_filling(&mut self, expr: &'tcx Expr<'tcx>) {\n        if self.initialization_found\n            && let ExprKind::MethodCall(path, self_arg, [len_arg, fill_arg], _) = expr.kind\n            && self_arg.res_local_id() == Some(self.vec_alloc.local_id)\n            && path.ident.name == sym::resize\n            // Check that is filled with 0\n            && is_integer_literal(fill_arg, 0)\n        {\n            let is_matching_resize = if let InitializedSize::Initialized(size_expr) = self.vec_alloc.size_expr {\n                // If we have a size expression, check that it is equal to what's passed to `resize`\n                SpanlessEq::new(self.cx).eq_expr(len_arg, size_expr)\n                    || matches!(len_arg.kind, ExprKind::MethodCall(path, ..) if path.ident.name == sym::capacity)\n            } else {\n                self.vec_alloc.size_expr = InitializedSize::Initialized(len_arg);\n                true\n            };\n\n            if is_matching_resize {\n                self.slow_expression = Some(InitializationType::Resize(expr));\n            }\n        }\n    }\n\n    /// Returns `true` if give expression is `repeat(0).take(...)`\n    fn is_repeat_take(&mut self, expr: &'tcx Expr<'tcx>) -> bool {\n        if let ExprKind::MethodCall(take_path, recv, [len_arg], _) = expr.kind\n            && take_path.ident.name == sym::take\n            // Check that take is applied to `repeat(0)`\n            && self.is_repeat_zero(recv)\n        {\n            if let InitializedSize::Initialized(size_expr) = self.vec_alloc.size_expr {\n                // Check that len expression is equals to `with_capacity` expression\n                return SpanlessEq::new(self.cx).eq_expr(len_arg, size_expr)\n                    || matches!(len_arg.kind, ExprKind::MethodCall(path, ..) if path.ident.name == sym::capacity);\n            }\n\n            self.vec_alloc.size_expr = InitializedSize::Initialized(len_arg);\n            return true;\n        }\n\n        false\n    }\n\n    /// Returns `true` if given expression is `repeat(0)`\n    fn is_repeat_zero(&self, expr: &Expr<'_>) -> bool {\n        if let ExprKind::Call(fn_expr, [repeat_arg]) = expr.kind\n            && fn_expr.basic_res().is_diag_item(self.cx, sym::iter_repeat)\n            && is_integer_literal(repeat_arg, 0)\n        {\n            true\n        } else {\n            false\n        }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for VectorInitializationVisitor<'_, 'tcx> {\n    fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {\n        if self.initialization_found {\n            match stmt.kind {\n                StmtKind::Expr(expr) | StmtKind::Semi(expr) => {\n                    self.search_slow_extend_filling(expr);\n                    self.search_slow_resize_filling(expr);\n                },\n                _ => (),\n            }\n\n            self.initialization_found = false;\n        } else {\n            walk_stmt(self, stmt);\n        }\n    }\n\n    fn visit_block(&mut self, block: &'tcx Block<'_>) {\n        if self.initialization_found {\n            if let Some(s) = block.stmts.first() {\n                self.visit_stmt(s);\n            }\n\n            self.initialization_found = false;\n        } else {\n            walk_block(self, block);\n        }\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        // Skip all the expressions previous to the vector initialization\n        if self.vec_alloc.allocation_expr.hir_id == expr.hir_id {\n            self.initialization_found = true;\n        }\n\n        walk_expr(self, expr);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/std_instead_of_core.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::msrvs::Msrv;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{Block, Body, HirId, Path, PathSegment, StabilityLevel, StableSince};\nuse rustc_lint::{LateContext, LateLintPass, Lint, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::kw;\nuse rustc_span::{Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds items imported through `alloc` when available through `core`.\n    ///\n    /// ### Why restrict this?\n    /// Crates which have `no_std` compatibility and may optionally require alloc may wish to ensure types are\n    /// imported from core to ensure disabling `alloc` does not cause the crate to fail to compile. This lint\n    /// is also useful for crates migrating to become `no_std` compatible.\n    ///\n    /// ### Known problems\n    /// The lint is only partially aware of the required MSRV for items that were originally in `std` but moved\n    /// to `core`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # extern crate alloc;\n    /// use alloc::slice::from_ref;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use core::slice::from_ref;\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub ALLOC_INSTEAD_OF_CORE,\n    restriction,\n    \"type is imported from alloc when available in core\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds items imported through `std` when available through `alloc`.\n    ///\n    /// ### Why restrict this?\n    /// Crates which have `no_std` compatibility and require alloc may wish to ensure types are imported from\n    /// alloc to ensure disabling `std` does not cause the crate to fail to compile. This lint is also useful\n    /// for crates migrating to become `no_std` compatible.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::vec::Vec;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # extern crate alloc;\n    /// use alloc::vec::Vec;\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub STD_INSTEAD_OF_ALLOC,\n    restriction,\n    \"type is imported from std when available in alloc\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Finds items imported through `std` when available through `core`.\n    ///\n    /// ### Why restrict this?\n    /// Crates which have `no_std` compatibility may wish to ensure types are imported from core to ensure\n    /// disabling `std` does not cause the crate to fail to compile. This lint is also useful for crates\n    /// migrating to become `no_std` compatible.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::hash::Hasher;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use core::hash::Hasher;\n    /// ```\n    #[clippy::version = \"1.64.0\"]\n    pub STD_INSTEAD_OF_CORE,\n    restriction,\n    \"type is imported from std when available in core\"\n}\n\nimpl_lint_pass!(StdReexports => [\n    ALLOC_INSTEAD_OF_CORE,\n    STD_INSTEAD_OF_ALLOC,\n    STD_INSTEAD_OF_CORE,\n]);\n\npub struct StdReexports {\n    lint_points: Option<(Span, Vec<LintPoint>)>,\n    msrv: Msrv,\n}\n\nimpl StdReexports {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            lint_points: Option::default(),\n            msrv: conf.msrv,\n        }\n    }\n\n    fn lint_if_finish(&mut self, cx: &LateContext<'_>, krate: Span, lint_point: LintPoint) {\n        match &mut self.lint_points {\n            Some((prev_krate, prev_lints)) if prev_krate.overlaps(krate) => {\n                prev_lints.push(lint_point);\n            },\n            _ => emit_lints(cx, self.lint_points.replace((krate, vec![lint_point]))),\n        }\n    }\n}\n\n#[derive(Debug)]\nenum LintPoint {\n    Available(Span, &'static Lint, &'static str, &'static str),\n    Conflict,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for StdReexports {\n    fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, _: HirId) {\n        if let Res::Def(def_kind, def_id) = path.res\n            && let Some(first_segment) = get_first_segment(path)\n            && is_stable(cx, def_id, self.msrv)\n            && !path.span.in_external_macro(cx.sess().source_map())\n            && !is_from_proc_macro(cx, &first_segment.ident)\n            && !matches!(def_kind, DefKind::Macro(_))\n            && let Some(last_segment) = path.segments.last()\n            && let Res::Def(DefKind::Mod, crate_def_id) = first_segment.res\n            && crate_def_id.is_crate_root()\n        {\n            let (lint, used_mod, replace_with) = match first_segment.ident.name {\n                sym::std => match cx.tcx.crate_name(def_id.krate) {\n                    sym::core => (STD_INSTEAD_OF_CORE, \"std\", \"core\"),\n                    sym::alloc => (STD_INSTEAD_OF_ALLOC, \"std\", \"alloc\"),\n                    _ => {\n                        self.lint_if_finish(cx, first_segment.ident.span, LintPoint::Conflict);\n                        return;\n                    },\n                },\n                sym::alloc if cx.tcx.crate_name(def_id.krate) == sym::core => (ALLOC_INSTEAD_OF_CORE, \"alloc\", \"core\"),\n                _ => {\n                    self.lint_if_finish(cx, first_segment.ident.span, LintPoint::Conflict);\n                    return;\n                },\n            };\n\n            self.lint_if_finish(\n                cx,\n                first_segment.ident.span,\n                LintPoint::Available(last_segment.ident.span, lint, used_mod, replace_with),\n            );\n        }\n    }\n\n    fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &Block<'tcx>) {\n        emit_lints(cx, self.lint_points.take());\n    }\n\n    fn check_body_post(&mut self, cx: &LateContext<'tcx>, _: &Body<'tcx>) {\n        emit_lints(cx, self.lint_points.take());\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        emit_lints(cx, self.lint_points.take());\n    }\n}\n\nfn emit_lints(cx: &LateContext<'_>, lint_points: Option<(Span, Vec<LintPoint>)>) {\n    let Some((krate_span, lint_points)) = lint_points else {\n        return;\n    };\n\n    let mut lint: Option<(&'static Lint, &'static str, &'static str)> = None;\n    let mut has_conflict = false;\n    for lint_point in &lint_points {\n        match lint_point {\n            LintPoint::Available(_, l, used_mod, replace_with)\n                if lint.is_none_or(|(prev_l, ..)| l.name == prev_l.name) =>\n            {\n                lint = Some((l, used_mod, replace_with));\n            },\n            _ => {\n                has_conflict = true;\n                break;\n            },\n        }\n    }\n\n    if !has_conflict && let Some((lint, used_mod, replace_with)) = lint {\n        span_lint_and_sugg(\n            cx,\n            lint,\n            krate_span,\n            format!(\"used import from `{used_mod}` instead of `{replace_with}`\"),\n            format!(\"consider importing the item from `{replace_with}`\"),\n            (*replace_with).to_string(),\n            Applicability::MachineApplicable,\n        );\n        return;\n    }\n\n    for lint_point in lint_points {\n        let LintPoint::Available(span, lint, used_mod, replace_with) = lint_point else {\n            continue;\n        };\n        span_lint_and_help(\n            cx,\n            lint,\n            span,\n            format!(\"used import from `{used_mod}` instead of `{replace_with}`\"),\n            None,\n            format!(\"consider importing the item from `{replace_with}`\"),\n        );\n    }\n}\n\n/// Returns the first named segment of a [`Path`].\n///\n/// If this is a global path (such as `::std::fmt::Debug`), then the segment after [`kw::PathRoot`]\n/// is returned.\nfn get_first_segment<'tcx>(path: &Path<'tcx>) -> Option<&'tcx PathSegment<'tcx>> {\n    match path.segments {\n        // A global path will have PathRoot as the first segment. In this case, return the segment after.\n        [x, y, ..] if x.ident.name == kw::PathRoot => Some(y),\n        [x, ..] => Some(x),\n        _ => None,\n    }\n}\n\n/// Checks if all ancestors of `def_id` meet `msrv` to avoid linting [unstable moves](https://github.com/rust-lang/rust/pull/95956)\n/// or now stable moves that were once unstable.\n///\n/// Does not catch individually moved items\nfn is_stable(cx: &LateContext<'_>, mut def_id: DefId, msrv: Msrv) -> bool {\n    loop {\n        if let Some(stability) = cx.tcx.lookup_stability(def_id)\n            && let StabilityLevel::Stable {\n                since,\n                allowed_through_unstable_modules: None,\n            } = stability.level\n        {\n            let stable = match since {\n                StableSince::Version(v) => msrv.meets(cx, v),\n                StableSince::Current => msrv.current(cx).is_none(),\n                StableSince::Err(_) => false,\n            };\n\n            if !stable {\n                return false;\n            }\n        }\n\n        match cx.tcx.opt_parent(def_id) {\n            Some(parent) => def_id = parent,\n            None => return true,\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/string_patterns.rs",
    "content": "use std::ops::ControlFlow;\n\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::eager_or_lazy::switch_to_eager_eval;\nuse clippy_utils::macros::matching_root_macro_call;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::{snippet, str_literal_to_char_literal};\nuse clippy_utils::sym;\nuse clippy_utils::visitors::{Descend, for_each_expr};\nuse itertools::Itertools;\nuse rustc_ast::{BinOpKind, LitKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, PatExprKind, PatKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual `char` comparison in string patterns\n    ///\n    /// ### Why is this bad?\n    /// This can be written more concisely using a `char` or an array of `char`.\n    /// This is more readable and more optimized when comparing to only one `char`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// \"Hello World!\".trim_end_matches(|c| c == '.' || c == ',' || c == '!' || c == '?');\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// \"Hello World!\".trim_end_matches(['.', ',', '!', '?']);\n    /// ```\n    #[clippy::version = \"1.81.0\"]\n    pub MANUAL_PATTERN_CHAR_COMPARISON,\n    style,\n    \"manual char comparison in string patterns\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for string methods that receive a single-character\n    /// `str` as an argument, e.g., `_.split(\"x\")`.\n    ///\n    /// ### Why is this bad?\n    /// While this can make a perf difference on some systems,\n    /// benchmarks have proven inconclusive. But at least using a\n    /// char literal makes it clear that we are looking at a single\n    /// character.\n    ///\n    /// ### Known problems\n    /// Does not catch multi-byte unicode characters. This is by\n    /// design, on many machines, splitting by a non-ascii char is\n    /// actually slower. Please do your own measurements instead of\n    /// relying solely on the results of this lint.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// _.split(\"x\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// _.split('x');\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SINGLE_CHAR_PATTERN,\n    pedantic,\n    \"using a single-character str where a char could be used, e.g., `_.split(\\\"x\\\")`\"\n}\n\nimpl_lint_pass!(StringPatterns => [\n    MANUAL_PATTERN_CHAR_COMPARISON,\n    SINGLE_CHAR_PATTERN,\n]);\n\npub struct StringPatterns {\n    msrv: Msrv,\n}\n\nimpl StringPatterns {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nconst PATTERN_METHODS: [(Symbol, usize); 22] = [\n    (sym::contains, 0),\n    (sym::starts_with, 0),\n    (sym::ends_with, 0),\n    (sym::find, 0),\n    (sym::rfind, 0),\n    (sym::split, 0),\n    (sym::split_inclusive, 0),\n    (sym::rsplit, 0),\n    (sym::split_terminator, 0),\n    (sym::rsplit_terminator, 0),\n    (sym::splitn, 1),\n    (sym::rsplitn, 1),\n    (sym::split_once, 0),\n    (sym::rsplit_once, 0),\n    (sym::matches, 0),\n    (sym::rmatches, 0),\n    (sym::match_indices, 0),\n    (sym::rmatch_indices, 0),\n    (sym::trim_start_matches, 0),\n    (sym::trim_end_matches, 0),\n    (sym::replace, 0),\n    (sym::replacen, 0),\n];\n\nfn check_single_char_pattern_lint(cx: &LateContext<'_>, arg: &Expr<'_>) {\n    let mut applicability = Applicability::MachineApplicable;\n    if let Some(hint) = str_literal_to_char_literal(cx, arg, &mut applicability, true) {\n        span_lint_and_sugg(\n            cx,\n            SINGLE_CHAR_PATTERN,\n            arg.span,\n            \"single-character string constant used as pattern\",\n            \"consider using a `char`\",\n            hint,\n            applicability,\n        );\n    }\n}\n\nfn get_char_span<'tcx>(cx: &'_ LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<Span> {\n    if cx.typeck_results().expr_ty_adjusted(expr).is_char()\n        && !expr.span.from_expansion()\n        && switch_to_eager_eval(cx, expr)\n    {\n        Some(expr.span)\n    } else {\n        None\n    }\n}\n\nfn check_manual_pattern_char_comparison(cx: &LateContext<'_>, method_arg: &Expr<'_>, msrv: Msrv) {\n    if let ExprKind::Closure(closure) = method_arg.kind\n        && let body = cx.tcx.hir_body(closure.body)\n        && let Some(PatKind::Binding(_, binding, ..)) = body.params.first().map(|p| p.pat.kind)\n    {\n        let mut set_char_spans: Vec<Span> = Vec::new();\n\n        // We want to retrieve all the comparisons done.\n        // They are ordered in a nested way and so we need to traverse the AST to collect them all.\n        if for_each_expr(cx, body.value, |sub_expr| -> ControlFlow<(), Descend> {\n            match sub_expr.kind {\n                ExprKind::Binary(op, left, right) if op.node == BinOpKind::Eq => {\n                    if left.res_local_id() == Some(binding)\n                        && let Some(span) = get_char_span(cx, right)\n                    {\n                        set_char_spans.push(span);\n                        ControlFlow::Continue(Descend::No)\n                    } else if right.res_local_id() == Some(binding)\n                        && let Some(span) = get_char_span(cx, left)\n                    {\n                        set_char_spans.push(span);\n                        ControlFlow::Continue(Descend::No)\n                    } else {\n                        ControlFlow::Break(())\n                    }\n                },\n                ExprKind::Binary(op, _, _) if op.node == BinOpKind::Or => ControlFlow::Continue(Descend::Yes),\n                ExprKind::Match(match_value, [arm, _], _) => {\n                    if matching_root_macro_call(cx, sub_expr.span, sym::matches_macro).is_none()\n                        || arm.guard.is_some()\n                        || match_value.res_local_id() != Some(binding)\n                    {\n                        return ControlFlow::Break(());\n                    }\n                    if arm.pat.walk_short(|pat| match pat.kind {\n                        PatKind::Expr(expr) if let PatExprKind::Lit { lit, negated: false } = expr.kind => {\n                            if let LitKind::Char(_) = lit.node {\n                                set_char_spans.push(lit.span);\n                            }\n                            true\n                        },\n                        PatKind::Or(_) => true,\n                        _ => false,\n                    }) {\n                        ControlFlow::Continue(Descend::No)\n                    } else {\n                        ControlFlow::Break(())\n                    }\n                },\n                _ => ControlFlow::Break(()),\n            }\n        })\n        .is_some()\n        {\n            return;\n        }\n        if set_char_spans.len() > 1 && !msrv.meets(cx, msrvs::PATTERN_TRAIT_CHAR_ARRAY) {\n            return;\n        }\n        span_lint_and_then(\n            cx,\n            MANUAL_PATTERN_CHAR_COMPARISON,\n            method_arg.span,\n            \"this manual char comparison can be written more succinctly\",\n            |diag| {\n                if let [set_char_span] = set_char_spans[..] {\n                    diag.span_suggestion(\n                        method_arg.span,\n                        \"consider using a `char`\",\n                        snippet(cx, set_char_span, \"c\"),\n                        Applicability::MachineApplicable,\n                    );\n                } else {\n                    diag.span_suggestion(\n                        method_arg.span,\n                        \"consider using an array of `char`\",\n                        format!(\n                            \"[{}]\",\n                            set_char_spans.into_iter().map(|span| snippet(cx, span, \"c\")).join(\", \")\n                        ),\n                        Applicability::MachineApplicable,\n                    );\n                }\n            },\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for StringPatterns {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if !expr.span.from_expansion()\n            && let ExprKind::MethodCall(method, receiver, args, _) = expr.kind\n            && let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(receiver).kind()\n            && ty.is_str()\n            && let method_name = method.ident.name\n            && let Some(&(_, pos)) = PATTERN_METHODS\n                .iter()\n                .find(|(array_method_name, _)| *array_method_name == method_name)\n            && let Some(arg) = args.get(pos)\n        {\n            check_single_char_pattern_lint(cx, arg);\n\n            check_manual_pattern_char_comparison(cx, arg, self.msrv);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/strings.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context};\nuse clippy_utils::{\n    SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, method_calls, peel_blocks, sym,\n};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, LangItem, Node};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::source_map::Spanned;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint checks for `.to_string()` method calls on values of type `&str`.\n    ///\n    /// ### Why restrict this?\n    /// The `to_string` method is also used on other types to convert them to a string.\n    /// When called on a `&str` it turns the `&str` into the owned variant `String`, which can be\n    /// more specifically expressed with `.to_owned()`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let _ = \"str\".to_string();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let _ = \"str\".to_owned();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub STR_TO_STRING,\n    restriction,\n    \"using `to_string()` on a `&str`, which should be `to_owned()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for all instances of `x + _` where `x` is of type\n    /// `String`, but only if [`string_add_assign`](#string_add_assign) does *not*\n    /// match.\n    ///\n    /// ### Why restrict this?\n    /// This particular\n    /// `Add` implementation is asymmetric (the other operand need not be `String`,\n    /// but `x` does), while addition as mathematically defined is symmetric, and\n    /// the `String::push_str(_)` function is a perfectly good replacement.\n    /// Therefore, some dislike it and wish not to have it in their code.\n    ///\n    /// That said, other people think that string addition, having a long tradition\n    /// in other languages is actually fine, which is why we decided to make this\n    /// particular lint `allow` by default.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = \"Hello\".to_owned();\n    /// x + \", World\";\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let mut x = \"Hello\".to_owned();\n    /// x.push_str(\", World\");\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub STRING_ADD,\n    restriction,\n    \"using `x + ..` where x is a `String` instead of `push_str()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for string appends of the form `x = x + y` (without\n    /// `let`!).\n    ///\n    /// ### Why is this bad?\n    /// It's not really bad, but some people think that the\n    /// `.push_str(_)` method is more readable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut x = \"Hello\".to_owned();\n    /// x = x + \", World\";\n    ///\n    /// // More readable\n    /// x += \", World\";\n    /// x.push_str(\", World\");\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub STRING_ADD_ASSIGN,\n    pedantic,\n    \"using `x = x + ..` where x is a `String` instead of `push_str()`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Check if the string is transformed to byte array and casted back to string.\n    ///\n    /// ### Why is this bad?\n    /// It's unnecessary, the string can be used directly.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// std::str::from_utf8(&\"Hello World!\".as_bytes()[6..11]).unwrap();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// &\"Hello World!\"[6..11];\n    /// ```\n    #[clippy::version = \"1.50.0\"]\n    pub STRING_FROM_UTF8_AS_BYTES,\n    complexity,\n    \"casting string slices to byte slices and back\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the `as_bytes` method called on string literals\n    /// that contain only ASCII characters.\n    ///\n    /// ### Why is this bad?\n    /// Byte string literals (e.g., `b\"foo\"`) can be used\n    /// instead. They are shorter but less discoverable than `as_bytes()`.\n    ///\n    /// ### Known problems\n    /// `\"str\".as_bytes()` and the suggested replacement of `b\"str\"` are not\n    /// equivalent because they have different types. The former is `&[u8]`\n    /// while the latter is `&[u8; 3]`. That means in general they will have a\n    /// different set of methods and different trait implementations.\n    ///\n    /// ```compile_fail\n    /// fn f(v: Vec<u8>) {}\n    ///\n    /// f(\"...\".as_bytes().to_owned()); // works\n    /// f(b\"...\".to_owned()); // does not work, because arg is [u8; 3] not Vec<u8>\n    ///\n    /// fn g(r: impl std::io::Read) {}\n    ///\n    /// g(\"...\".as_bytes()); // works\n    /// g(b\"...\"); // does not work\n    /// ```\n    ///\n    /// The actual equivalent of `\"str\".as_bytes()` with the same type is not\n    /// `b\"str\"` but `&b\"str\"[..]`, which is a great deal of punctuation and not\n    /// more readable than a function call.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let bstr = \"a byte string\".as_bytes();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let bstr = b\"a byte string\";\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub STRING_LIT_AS_BYTES,\n    nursery,\n    \"calling `as_bytes` on a string literal instead of using a byte string literal\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for slice operations on strings\n    ///\n    /// ### Why restrict this?\n    /// UTF-8 characters span multiple bytes, and it is easy to inadvertently confuse character\n    /// counts and string indices. This may lead to panics, and should warrant some test cases\n    /// containing wide UTF-8 characters. This lint is most useful in code that should avoid\n    /// panics at all costs.\n    ///\n    /// ### Known problems\n    /// Probably lots of false positives. If an index comes from a known valid position (e.g.\n    /// obtained via `char_indices` over the same string), it is totally OK.\n    ///\n    /// ### Example\n    /// ```rust,should_panic\n    /// &\"Ölkanne\"[1..];\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub STRING_SLICE,\n    restriction,\n    \"slicing a string\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Warns about calling `str::trim` (or variants) before `str::split_whitespace`.\n    ///\n    /// ### Why is this bad?\n    /// `split_whitespace` already ignores leading and trailing whitespace.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// \" A B C \".trim().split_whitespace();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// \" A B C \".split_whitespace();\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub TRIM_SPLIT_WHITESPACE,\n    style,\n    \"using `str::trim()` or alike before `str::split_whitespace`\"\n}\n\ndeclare_lint_pass!(StrToString => [STR_TO_STRING]);\n\ndeclare_lint_pass!(StringAdd => [STRING_ADD, STRING_ADD_ASSIGN, STRING_SLICE]);\n\ndeclare_lint_pass!(StringLitAsBytes => [\n    STRING_FROM_UTF8_AS_BYTES,\n    STRING_LIT_AS_BYTES,\n]);\n\ndeclare_lint_pass!(TrimSplitWhitespace => [TRIM_SPLIT_WHITESPACE]);\n\nimpl<'tcx> LateLintPass<'tcx> for StringAdd {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if e.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n        match e.kind {\n            ExprKind::Binary(\n                Spanned {\n                    node: BinOpKind::Add, ..\n                },\n                left,\n                _,\n            ) if is_string(cx, left) => {\n                if !is_lint_allowed(cx, STRING_ADD_ASSIGN, e.hir_id) {\n                    let parent = get_parent_expr(cx, e);\n                    if let Some(p) = parent\n                            && let ExprKind::Assign(target, _, _) = p.kind\n                                // avoid duplicate matches\n                                && SpanlessEq::new(cx).eq_expr(target, left)\n                    {\n                        return;\n                    }\n                }\n                span_lint(\n                    cx,\n                    STRING_ADD,\n                    e.span,\n                    \"you added something to a string. Consider using `String::push_str()` instead\",\n                );\n            },\n            ExprKind::Assign(target, src, _) if is_string(cx, target) && is_add(cx, src, target) => {\n                span_lint(\n                    cx,\n                    STRING_ADD_ASSIGN,\n                    e.span,\n                    \"you assigned the result of adding something to this string. Consider using \\\n                         `String::push_str()` instead\",\n                );\n            },\n            ExprKind::Index(target, _idx, _) => {\n                let e_ty = cx.typeck_results().expr_ty_adjusted(target).peel_refs();\n                if e_ty.is_str() || e_ty.is_lang_item(cx, LangItem::String) {\n                    span_lint(\n                        cx,\n                        STRING_SLICE,\n                        e.span,\n                        \"indexing into a string may panic if the index is within a UTF-8 character\",\n                    );\n                }\n            },\n            _ => {},\n        }\n    }\n}\n\nfn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    cx.typeck_results()\n        .expr_ty(e)\n        .peel_refs()\n        .is_lang_item(cx, LangItem::String)\n}\n\nfn is_add(cx: &LateContext<'_>, src: &Expr<'_>, target: &Expr<'_>) -> bool {\n    match peel_blocks(src).kind {\n        ExprKind::Binary(\n            Spanned {\n                node: BinOpKind::Add, ..\n            },\n            left,\n            _,\n        ) => SpanlessEq::new(cx).eq_expr(target, left),\n        _ => false,\n    }\n}\n\n// Max length a b\"foo\" string can take\nconst MAX_LENGTH_BYTE_STRING_LIT: usize = 32;\n\nimpl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        use rustc_ast::LitKind;\n\n        if let ExprKind::Call(fun, [bytes_arg]) = e.kind\n            // Find `std::str::converts::from_utf8` or `std::primitive::str::from_utf8`\n            && let Some(sym::str_from_utf8 | sym::str_inherent_from_utf8) =\n                fun.res(cx).opt_diag_name(cx)\n\n            // Find string::as_bytes\n            && let ExprKind::AddrOf(BorrowKind::Ref, _, args) = bytes_arg.kind\n            && let ExprKind::Index(left, right, _) = args.kind\n            && let (method_names, expressions, _) = method_calls(left, 1)\n            && method_names == [sym::as_bytes]\n            && expressions.len() == 1\n            && expressions[0].1.is_empty()\n\n            // Check for slicer\n            && let ExprKind::Struct(&qpath, _, _) = right.kind\n            && cx.tcx.qpath_is_lang_item(qpath, LangItem::Range)\n        {\n            let mut applicability = Applicability::MachineApplicable;\n            let string_expression = &expressions[0].0;\n\n            let snippet_app = snippet_with_applicability(cx, string_expression.span, \"..\", &mut applicability);\n            let (right_snip, _) = snippet_with_context(cx, right.span, e.span.ctxt(), \"..\", &mut applicability);\n\n            span_lint_and_sugg(\n                cx,\n                STRING_FROM_UTF8_AS_BYTES,\n                e.span,\n                \"calling a slice of `as_bytes()` with `from_utf8` should be not necessary\",\n                \"try\",\n                format!(\"Some(&{snippet_app}[{right_snip}])\"),\n                applicability,\n            );\n        }\n\n        if !e.span.in_external_macro(cx.sess().source_map())\n            && let ExprKind::MethodCall(path, receiver, ..) = &e.kind\n            && path.ident.name == sym::as_bytes\n            && let ExprKind::Lit(lit) = &receiver.kind\n            && let LitKind::Str(lit_content, _) = &lit.node\n        {\n            let callsite = snippet(cx, receiver.span.source_callsite(), r#\"\"foo\"\"#);\n            let mut applicability = Applicability::MachineApplicable;\n            if callsite.starts_with(\"include_str!\") {\n                span_lint_and_sugg(\n                    cx,\n                    STRING_LIT_AS_BYTES,\n                    e.span,\n                    \"calling `as_bytes()` on `include_str!(..)`\",\n                    \"consider using `include_bytes!(..)` instead\",\n                    snippet_with_applicability(cx, receiver.span.source_callsite(), r#\"\"foo\"\"#, &mut applicability)\n                        .replacen(\"include_str\", \"include_bytes\", 1),\n                    applicability,\n                );\n            } else if lit_content.as_str().is_ascii()\n                && lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT\n                && !receiver.span.from_expansion()\n            {\n                if let Some((parent, id)) = get_expr_use_or_unification_node(cx.tcx, e)\n                    && let Node::Expr(parent) = parent\n                    && let ExprKind::Match(scrutinee, ..) = parent.kind\n                    && scrutinee.hir_id == id\n                {\n                    // Don't lint. Byte strings produce `&[u8; N]` whereas `as_bytes()` produces\n                    // `&[u8]`. This change would prevent matching with different sized slices.\n                } else if !callsite.starts_with(\"env!\") {\n                    span_lint_and_sugg(\n                        cx,\n                        STRING_LIT_AS_BYTES,\n                        e.span,\n                        \"calling `as_bytes()` on a string literal\",\n                        \"consider using a byte string literal instead\",\n                        format!(\n                            \"b{}\",\n                            snippet_with_applicability(cx, receiver.span, r#\"\"foo\"\"#, &mut applicability)\n                        ),\n                        applicability,\n                    );\n                }\n            }\n        }\n\n        if let ExprKind::MethodCall(path, recv, [], _) = &e.kind\n            && path.ident.name == sym::into_bytes\n            && let ExprKind::MethodCall(path, recv, [], _) = &recv.kind\n            && matches!(path.ident.name, sym::to_owned | sym::to_string)\n            && let ExprKind::Lit(lit) = &recv.kind\n            && let LitKind::Str(lit_content, _) = &lit.node\n            && lit_content.as_str().is_ascii()\n            && lit_content.as_str().len() <= MAX_LENGTH_BYTE_STRING_LIT\n            && !recv.span.from_expansion()\n        {\n            let mut applicability = Applicability::MachineApplicable;\n\n            span_lint_and_sugg(\n                cx,\n                STRING_LIT_AS_BYTES,\n                e.span,\n                \"calling `into_bytes()` on a string literal\",\n                \"consider using a byte string literal instead\",\n                format!(\n                    \"b{}.to_vec()\",\n                    snippet_with_applicability(cx, recv.span, r#\"\"..\"\"#, &mut applicability)\n                ),\n                applicability,\n            );\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for StrToString {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        if let ExprKind::MethodCall(path, self_arg, [], _) = &expr.kind\n            && path.ident.name == sym::to_string\n            && let ty = cx.typeck_results().expr_ty(self_arg)\n            && let ty::Ref(_, ty, ..) = ty.kind()\n            && ty.is_str()\n        {\n            span_lint_and_then(\n                cx,\n                STR_TO_STRING,\n                expr.span,\n                \"`to_string()` called on a `&str`\",\n                |diag| {\n                    let mut applicability = Applicability::MachineApplicable;\n                    let (snippet, _) =\n                        snippet_with_context(cx, self_arg.span, expr.span.ctxt(), \"..\", &mut applicability);\n                    diag.span_suggestion(expr.span, \"try\", format!(\"{snippet}.to_owned()\"), applicability);\n                },\n            );\n        } else if let ExprKind::Path(_) = expr.kind\n            && let Some(parent) = get_parent_expr(cx, expr)\n            && let ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) = &parent.kind\n            && args.iter().any(|a| a.hir_id == expr.hir_id)\n            && let Res::Def(DefKind::AssocFn, def_id) = expr.res(cx)\n            && cx.tcx.is_diagnostic_item(sym::to_string_method, def_id)\n            && let Some(args) = cx.typeck_results().node_args_opt(expr.hir_id)\n            && args.type_at(0).is_str()\n        {\n            // Detected `ToString::to_string` passed as an argument (generic: any call or method call)\n            span_lint_and_sugg(\n                cx,\n                STR_TO_STRING,\n                expr.span,\n                \"`ToString::to_string` used as `&str` to `String` converter\",\n                \"try\",\n                \"str::to_owned\".to_string(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for TrimSplitWhitespace {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {\n        let tyckres = cx.typeck_results();\n        if let ExprKind::MethodCall(path, split_recv, [], split_ws_span) = expr.kind\n            && path.ident.name == sym::split_whitespace\n            && let Some(split_ws_def_id) = tyckres.type_dependent_def_id(expr.hir_id)\n            && cx.tcx.is_diagnostic_item(sym::str_split_whitespace, split_ws_def_id)\n            && let ExprKind::MethodCall(path, _trim_recv, [], trim_span) = split_recv.kind\n            && let trim_fn_name @ (sym::trim | sym::trim_start | sym::trim_end) = path.ident.name\n            && let Some(trim_def_id) = tyckres.type_dependent_def_id(split_recv.hir_id)\n            && is_one_of_trim_diagnostic_items(cx, trim_def_id)\n        {\n            span_lint_and_sugg(\n                cx,\n                TRIM_SPLIT_WHITESPACE,\n                trim_span.with_hi(split_ws_span.lo()),\n                format!(\"found call to `str::{trim_fn_name}` before `str::split_whitespace`\"),\n                format!(\"remove `{trim_fn_name}()`\"),\n                String::new(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n\nfn is_one_of_trim_diagnostic_items(cx: &LateContext<'_>, trim_def_id: DefId) -> bool {\n    matches!(\n        cx.tcx.get_diagnostic_name(trim_def_id),\n        Some(sym::str_trim | sym::str_trim_start | sym::str_trim_end)\n    )\n}\n"
  },
  {
    "path": "clippy_lints/src/strlen_on_c_strings.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::visitors::is_expr_unsafe;\nuse clippy_utils::{match_libc_symbol, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, LangItem, Node, UnsafeSource};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `libc::strlen` on a `CString` or `CStr` value,\n    /// and suggest calling `count_bytes()` instead.\n    ///\n    /// ### Why is this bad?\n    /// libc::strlen is an unsafe function, which we don't need to call\n    /// if all we want to know is the length of the c-string.\n    ///\n    /// ### Example\n    /// ```rust, ignore\n    /// use std::ffi::CString;\n    /// let cstring = CString::new(\"foo\").expect(\"CString::new failed\");\n    /// let len = unsafe { libc::strlen(cstring.as_ptr()) };\n    /// ```\n    /// Use instead:\n    /// ```rust, no_run\n    /// use std::ffi::CString;\n    /// let cstring = CString::new(\"foo\").expect(\"CString::new failed\");\n    /// let len = cstring.count_bytes();\n    /// ```\n    #[clippy::version = \"1.55.0\"]\n    pub STRLEN_ON_C_STRINGS,\n    complexity,\n    \"using `libc::strlen` on a `CString` or `CStr` value, while `count_bytes()` can be used instead\"\n}\n\nimpl_lint_pass!(StrlenOnCStrings => [STRLEN_ON_C_STRINGS]);\n\npub struct StrlenOnCStrings {\n    msrv: Msrv,\n}\n\nimpl StrlenOnCStrings {\n    pub fn new(conf: &Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for StrlenOnCStrings {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if !expr.span.from_expansion()\n            && let ExprKind::Call(func, [recv]) = expr.kind\n            && let ExprKind::Path(path) = &func.kind\n            && let Some(did) = cx.qpath_res(path, func.hir_id).opt_def_id()\n            && match_libc_symbol(cx, did, sym::strlen)\n            && let ExprKind::MethodCall(path, self_arg, [], _) = recv.kind\n            && !recv.span.from_expansion()\n            && path.ident.name == sym::as_ptr\n            && let typeck = cx.typeck_results()\n            && typeck\n                .expr_ty_adjusted(self_arg)\n                .peel_refs()\n                .is_lang_item(cx, LangItem::CStr)\n        {\n            let ty = typeck.expr_ty(self_arg).peel_refs();\n            let ty_kind = if ty.is_diag_item(cx, sym::cstring_type) {\n                \"`CString` value\"\n            } else if ty.is_lang_item(cx, LangItem::CStr) {\n                \"`CStr` value\"\n            } else {\n                \"type that dereferences to `CStr`\"\n            };\n\n            let ctxt = expr.span.ctxt();\n            let span = match cx.tcx.parent_hir_node(expr.hir_id) {\n                Node::Block(&Block {\n                    rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),\n                    span,\n                    ..\n                }) if span.ctxt() == ctxt && !is_expr_unsafe(cx, self_arg) => span,\n                _ => expr.span,\n            };\n\n            span_lint_and_then(\n                cx,\n                STRLEN_ON_C_STRINGS,\n                span,\n                format!(\"using `libc::strlen` on a {ty_kind}\"),\n                |diag| {\n                    let mut app = Applicability::MachineApplicable;\n                    let val_name = snippet_with_context(cx, self_arg.span, ctxt, \"_\", &mut app).0;\n\n                    let suggestion = if self.msrv.meets(cx, msrvs::CSTR_COUNT_BYTES) {\n                        format!(\"{val_name}.count_bytes()\")\n                    } else {\n                        format!(\"{val_name}.to_bytes().len()\")\n                    };\n\n                    diag.span_suggestion(span, \"use\", suggestion, app);\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/suspicious_operation_groupings.rs",
    "content": "use clippy_utils::ast_utils::{IdentIter, eq_id, is_useless_with_eq_exprs};\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet_with_applicability;\nuse core::ops::{Add, AddAssign};\nuse rustc_ast::ast::{BinOpKind, Expr, ExprKind, StmtKind};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::symbol::Ident;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unlikely usages of binary operators that are almost\n    /// certainly typos and/or copy/paste errors, given the other usages\n    /// of binary operators nearby.\n    ///\n    /// ### Why is this bad?\n    /// They are probably bugs and if they aren't then they look like bugs\n    /// and you should add a comment explaining why you are doing such an\n    /// odd set of operations.\n    ///\n    /// ### Known problems\n    /// There may be some false positives if you are trying to do something\n    /// unusual that happens to look like a typo.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Vec3 {\n    ///     x: f64,\n    ///     y: f64,\n    ///     z: f64,\n    /// }\n    ///\n    /// impl Eq for Vec3 {}\n    ///\n    /// impl PartialEq for Vec3 {\n    ///     fn eq(&self, other: &Self) -> bool {\n    ///         // This should trigger the lint because `self.x` is compared to `other.y`\n    ///         self.x == other.y && self.y == other.y && self.z == other.z\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # struct Vec3 {\n    /// #     x: f64,\n    /// #     y: f64,\n    /// #     z: f64,\n    /// # }\n    /// // same as above except:\n    /// impl PartialEq for Vec3 {\n    ///     fn eq(&self, other: &Self) -> bool {\n    ///         // Note we now compare other.x to self.x\n    ///         self.x == other.x && self.y == other.y && self.z == other.z\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.50.0\"]\n    pub SUSPICIOUS_OPERATION_GROUPINGS,\n    nursery,\n    \"groupings of binary operations that look suspiciously like typos\"\n}\n\ndeclare_lint_pass!(SuspiciousOperationGroupings => [\n    SUSPICIOUS_OPERATION_GROUPINGS,\n]);\n\nimpl EarlyLintPass for SuspiciousOperationGroupings {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        if let Some(binops) = extract_related_binops(&expr.kind) {\n            check_binops(cx, &binops.iter().collect::<Vec<_>>());\n\n            let mut op_types = Vec::with_capacity(binops.len());\n            // We could use a hashmap, etc. to avoid being O(n*m) here, but\n            // we want the lints to be emitted in a consistent order. Besides,\n            // m, (the number of distinct `BinOpKind`s in `binops`)\n            // will often be small, and does have an upper limit.\n            binops.iter().map(|b| b.op).for_each(|op| {\n                if !op_types.contains(&op) {\n                    op_types.push(op);\n                }\n            });\n\n            for op_type in op_types {\n                let ops: Vec<_> = binops.iter().filter(|b| b.op == op_type).collect();\n\n                check_binops(cx, &ops);\n            }\n        }\n    }\n}\n\nfn check_binops(cx: &EarlyContext<'_>, binops: &[&BinaryOp<'_>]) {\n    let binop_count = binops.len();\n    if binop_count < 2 {\n        // Single binary operation expressions would likely be false\n        // positives.\n        return;\n    }\n\n    let mut one_ident_difference_count = 0;\n    let mut no_difference_info = None;\n    let mut double_difference_info = None;\n    let mut expected_ident_loc = None;\n\n    let mut paired_identifiers = FxHashSet::default();\n\n    for (i, BinaryOp { left, right, op, .. }) in binops.iter().enumerate() {\n        match ident_difference_expr(left, right) {\n            IdentDifference::NoDifference => {\n                if is_useless_with_eq_exprs(*op) {\n                    // The `eq_op` lint should catch this in this case.\n                    return;\n                }\n\n                no_difference_info = Some(i);\n            },\n            IdentDifference::Single(ident_loc) => {\n                one_ident_difference_count += 1;\n                if let Some(previous_expected) = expected_ident_loc {\n                    if previous_expected != ident_loc {\n                        // This expression doesn't match the form we're\n                        // looking for.\n                        return;\n                    }\n                } else {\n                    expected_ident_loc = Some(ident_loc);\n                }\n\n                // If there was only a single difference, all other idents\n                // must have been the same, and thus were paired.\n                for id in skip_index(IdentIter::from(*left), ident_loc.index) {\n                    paired_identifiers.insert(id);\n                }\n            },\n            IdentDifference::Double(ident_loc1, ident_loc2) => {\n                double_difference_info = Some((i, ident_loc1, ident_loc2));\n            },\n            IdentDifference::Multiple | IdentDifference::NonIdent => {\n                // It's too hard to know whether this is a bug or not.\n                return;\n            },\n        }\n    }\n\n    let mut applicability = Applicability::MachineApplicable;\n\n    if let Some(expected_loc) = expected_ident_loc {\n        match (no_difference_info, double_difference_info) {\n            (Some(i), None) => attempt_to_emit_no_difference_lint(cx, binops, i, expected_loc),\n            (None, Some((double_difference_index, ident_loc1, ident_loc2))) => {\n                if one_ident_difference_count == binop_count - 1\n                    && let Some(binop) = binops.get(double_difference_index)\n                {\n                    let changed_loc = if ident_loc1 == expected_loc {\n                        ident_loc2\n                    } else if ident_loc2 == expected_loc {\n                        ident_loc1\n                    } else {\n                        // This expression doesn't match the form we're\n                        // looking for.\n                        return;\n                    };\n\n                    if let Some(sugg) = ident_swap_sugg(cx, &paired_identifiers, binop, changed_loc, &mut applicability)\n                    {\n                        emit_suggestion(cx, binop.span, sugg, applicability);\n                    }\n                }\n            },\n            _ => {},\n        }\n    }\n}\n\nfn attempt_to_emit_no_difference_lint(\n    cx: &EarlyContext<'_>,\n    binops: &[&BinaryOp<'_>],\n    i: usize,\n    expected_loc: IdentLocation,\n) {\n    if let Some(binop) = binops.get(i).copied() {\n        // We need to try and figure out which identifier we should\n        // suggest using instead. Since there could be multiple\n        // replacement candidates in a given expression, and we're\n        // just taking the first one, we may get some bad lint\n        // messages.\n        let mut applicability = Applicability::MaybeIncorrect;\n\n        // We assume that the correct ident is one used elsewhere in\n        // the other binops, in a place that there was a single\n        // difference between idents before.\n        let old_left_ident = get_ident(binop.left, expected_loc);\n        let old_right_ident = get_ident(binop.right, expected_loc);\n\n        for b in skip_index(binops.iter(), i) {\n            if let (Some(old_ident), Some(new_ident)) = (old_left_ident, get_ident(b.left, expected_loc))\n                && old_ident != new_ident\n                && let Some(sugg) =\n                    suggestion_with_swapped_ident(cx, binop.left, expected_loc, new_ident, &mut applicability)\n            {\n                emit_suggestion(\n                    cx,\n                    binop.span,\n                    replace_left_sugg(cx, binop, &sugg, &mut applicability),\n                    applicability,\n                );\n                return;\n            }\n\n            if let (Some(old_ident), Some(new_ident)) = (old_right_ident, get_ident(b.right, expected_loc))\n                && old_ident != new_ident\n                && let Some(sugg) =\n                    suggestion_with_swapped_ident(cx, binop.right, expected_loc, new_ident, &mut applicability)\n            {\n                emit_suggestion(\n                    cx,\n                    binop.span,\n                    replace_right_sugg(cx, binop, &sugg, &mut applicability),\n                    applicability,\n                );\n                return;\n            }\n        }\n    }\n}\n\nfn emit_suggestion(cx: &EarlyContext<'_>, span: Span, sugg: String, applicability: Applicability) {\n    span_lint_and_sugg(\n        cx,\n        SUSPICIOUS_OPERATION_GROUPINGS,\n        span,\n        \"this sequence of operators looks suspiciously like a bug\",\n        \"did you mean\",\n        sugg,\n        applicability,\n    );\n}\n\nfn ident_swap_sugg(\n    cx: &EarlyContext<'_>,\n    paired_identifiers: &FxHashSet<Ident>,\n    binop: &BinaryOp<'_>,\n    location: IdentLocation,\n    applicability: &mut Applicability,\n) -> Option<String> {\n    let left_ident = get_ident(binop.left, location)?;\n    let right_ident = get_ident(binop.right, location)?;\n\n    let sugg = match (\n        paired_identifiers.contains(&left_ident),\n        paired_identifiers.contains(&right_ident),\n    ) {\n        (true, true) | (false, false) => {\n            // We don't have a good guess of what ident should be\n            // used instead, in these cases.\n            *applicability = Applicability::MaybeIncorrect;\n\n            // We arbitrarily choose one side to suggest changing,\n            // since we don't have a better guess. If the user\n            // ends up duplicating a clause, the `logic_bug` lint\n            // should catch it.\n\n            let right_suggestion = suggestion_with_swapped_ident(cx, binop.right, location, left_ident, applicability)?;\n\n            replace_right_sugg(cx, binop, &right_suggestion, applicability)\n        },\n        (false, true) => {\n            // We haven't seen a pair involving the left one, so\n            // it's probably what is wanted.\n\n            let right_suggestion = suggestion_with_swapped_ident(cx, binop.right, location, left_ident, applicability)?;\n\n            replace_right_sugg(cx, binop, &right_suggestion, applicability)\n        },\n        (true, false) => {\n            // We haven't seen a pair involving the right one, so\n            // it's probably what is wanted.\n            let left_suggestion = suggestion_with_swapped_ident(cx, binop.left, location, right_ident, applicability)?;\n\n            replace_left_sugg(cx, binop, &left_suggestion, applicability)\n        },\n    };\n\n    Some(sugg)\n}\n\nfn replace_left_sugg(\n    cx: &EarlyContext<'_>,\n    binop: &BinaryOp<'_>,\n    left_suggestion: &str,\n    applicability: &mut Applicability,\n) -> String {\n    format!(\n        \"{left_suggestion} {} {}\",\n        binop.op.as_str(),\n        snippet_with_applicability(cx, binop.right.span, \"..\", applicability),\n    )\n}\n\nfn replace_right_sugg(\n    cx: &EarlyContext<'_>,\n    binop: &BinaryOp<'_>,\n    right_suggestion: &str,\n    applicability: &mut Applicability,\n) -> String {\n    format!(\n        \"{} {} {right_suggestion}\",\n        snippet_with_applicability(cx, binop.left.span, \"..\", applicability),\n        binop.op.as_str(),\n    )\n}\n\n#[derive(Clone, Debug)]\nstruct BinaryOp<'exprs> {\n    op: BinOpKind,\n    span: Span,\n    left: &'exprs Expr,\n    right: &'exprs Expr,\n}\n\nimpl<'exprs> BinaryOp<'exprs> {\n    fn new(op: BinOpKind, span: Span, (left, right): (&'exprs Expr, &'exprs Expr)) -> Self {\n        Self { op, span, left, right }\n    }\n}\n\nfn strip_non_ident_wrappers(expr: &Expr) -> &Expr {\n    let mut output = expr;\n    loop {\n        output = match &output.kind {\n            ExprKind::Paren(inner) | ExprKind::Unary(_, inner) => inner,\n            _ => {\n                return output;\n            },\n        };\n    }\n}\n\nfn extract_related_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {\n    append_opt_vecs(chained_binops(kind), if_statement_binops(kind))\n}\n\nfn if_statement_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {\n    match kind {\n        ExprKind::If(condition, _, _) => chained_binops(&condition.kind),\n        ExprKind::Paren(e) => if_statement_binops(&e.kind),\n        ExprKind::Block(block, _) => {\n            let mut output = None;\n            for stmt in &block.stmts {\n                match &stmt.kind {\n                    StmtKind::Expr(e) | StmtKind::Semi(e) => {\n                        output = append_opt_vecs(output, if_statement_binops(&e.kind));\n                    },\n                    _ => {},\n                }\n            }\n            output\n        },\n        _ => None,\n    }\n}\n\nfn append_opt_vecs<A>(target_opt: Option<Vec<A>>, source_opt: Option<Vec<A>>) -> Option<Vec<A>> {\n    match (target_opt, source_opt) {\n        (Some(mut target), Some(source)) => {\n            target.reserve(source.len());\n            for op in source {\n                target.push(op);\n            }\n            Some(target)\n        },\n        (Some(v), None) | (None, Some(v)) => Some(v),\n        (None, None) => None,\n    }\n}\n\nfn chained_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {\n    match kind {\n        ExprKind::Binary(_, left_outer, right_outer) => chained_binops_helper(left_outer, right_outer),\n        ExprKind::Paren(e) | ExprKind::Unary(_, e) => chained_binops(&e.kind),\n        _ => None,\n    }\n}\n\nfn chained_binops_helper<'expr>(left_outer: &'expr Expr, right_outer: &'expr Expr) -> Option<Vec<BinaryOp<'expr>>> {\n    match (&left_outer.kind, &right_outer.kind) {\n        (\n            ExprKind::Paren(left_e) | ExprKind::Unary(_, left_e),\n            ExprKind::Paren(right_e) | ExprKind::Unary(_, right_e),\n        ) => chained_binops_helper(left_e, right_e),\n        (ExprKind::Paren(left_e) | ExprKind::Unary(_, left_e), _) => chained_binops_helper(left_e, right_outer),\n        (_, ExprKind::Paren(right_e) | ExprKind::Unary(_, right_e)) => chained_binops_helper(left_outer, right_e),\n        (\n            ExprKind::Binary(Spanned { node: left_op, .. }, left_left, left_right),\n            ExprKind::Binary(Spanned { node: right_op, .. }, right_left, right_right),\n        ) => match (\n            chained_binops_helper(left_left, left_right),\n            chained_binops_helper(right_left, right_right),\n        ) {\n            (Some(mut left_ops), Some(right_ops)) => {\n                left_ops.reserve(right_ops.len());\n                for op in right_ops {\n                    left_ops.push(op);\n                }\n                Some(left_ops)\n            },\n            (Some(mut left_ops), _) => {\n                left_ops.push(BinaryOp::new(*right_op, right_outer.span, (right_left, right_right)));\n                Some(left_ops)\n            },\n            (_, Some(mut right_ops)) => {\n                right_ops.insert(0, BinaryOp::new(*left_op, left_outer.span, (left_left, left_right)));\n                Some(right_ops)\n            },\n            (None, None) => Some(vec![\n                BinaryOp::new(*left_op, left_outer.span, (left_left, left_right)),\n                BinaryOp::new(*right_op, right_outer.span, (right_left, right_right)),\n            ]),\n        },\n        _ => None,\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Eq, Default, Debug)]\nstruct IdentLocation {\n    index: usize,\n}\n\nimpl Add for IdentLocation {\n    type Output = IdentLocation;\n\n    fn add(self, other: Self) -> Self::Output {\n        Self {\n            index: self.index + other.index,\n        }\n    }\n}\n\nimpl AddAssign for IdentLocation {\n    fn add_assign(&mut self, other: Self) {\n        *self = *self + other;\n    }\n}\n\n#[derive(Clone, Copy, Debug)]\nenum IdentDifference {\n    NoDifference,\n    Single(IdentLocation),\n    Double(IdentLocation, IdentLocation),\n    Multiple,\n    NonIdent,\n}\n\nimpl Add for IdentDifference {\n    type Output = IdentDifference;\n\n    fn add(self, other: Self) -> Self::Output {\n        match (self, other) {\n            (Self::NoDifference, output) | (output, Self::NoDifference) => output,\n            (Self::Multiple, _)\n            | (_, Self::Multiple)\n            | (Self::Double(_, _), Self::Single(_))\n            | (Self::Single(_) | Self::Double(_, _), Self::Double(_, _)) => Self::Multiple,\n            (Self::NonIdent, _) | (_, Self::NonIdent) => Self::NonIdent,\n            (Self::Single(il1), Self::Single(il2)) => Self::Double(il1, il2),\n        }\n    }\n}\n\nimpl AddAssign for IdentDifference {\n    fn add_assign(&mut self, other: Self) {\n        *self = *self + other;\n    }\n}\n\nimpl IdentDifference {\n    /// Returns true if learning about more differences will not change the value\n    /// of this `IdentDifference`, and false otherwise.\n    fn is_complete(&self) -> bool {\n        match self {\n            Self::NoDifference | Self::Single(_) | Self::Double(_, _) => false,\n            Self::Multiple | Self::NonIdent => true,\n        }\n    }\n}\n\nfn ident_difference_expr(left: &Expr, right: &Expr) -> IdentDifference {\n    ident_difference_expr_with_base_location(left, right, IdentLocation::default()).0\n}\n\nfn ident_difference_expr_with_base_location(\n    left: &Expr,\n    right: &Expr,\n    mut base: IdentLocation,\n) -> (IdentDifference, IdentLocation) {\n    // Ideally, this function should not use IdentIter because it should return\n    // early if the expressions have any non-ident differences. We want that early\n    // return because if without that restriction the lint would lead to false\n    // positives.\n    //\n    // But, we cannot (easily?) use a `rustc_ast::visit::Visitor`, since we need\n    // the two expressions to be walked in lockstep. And without a `Visitor`, we'd\n    // have to do all the AST traversal ourselves, which is a lot of work, since to\n    // do it properly we'd need to be able to handle more or less every possible\n    // AST node since `Item`s can be written inside `Expr`s.\n    //\n    // In practice, it seems likely that expressions, above a certain size, that\n    // happen to use the exact same idents in the exact same order, and which are\n    // not structured the same, would be rare. Therefore it seems likely that if\n    // we do only the first layer of matching ourselves and eventually fallback on\n    // IdentIter, then the output of this function will be almost always be correct\n    // in practice.\n    //\n    // If it turns out that problematic cases are more prevalent than we assume,\n    // then we should be able to change this function to do the correct traversal,\n    // without needing to change the rest of the code.\n\n    #![allow(clippy::enum_glob_use)]\n    use ExprKind::*;\n\n    match (\n        &strip_non_ident_wrappers(left).kind,\n        &strip_non_ident_wrappers(right).kind,\n    ) {\n        (Yield(_), Yield(_))\n        | (Try(_), Try(_))\n        | (Paren(_), Paren(_))\n        | (Repeat(_, _), Repeat(_, _))\n        | (Struct(_), Struct(_))\n        | (MacCall(_), MacCall(_))\n        | (InlineAsm(_), InlineAsm(_))\n        | (Ret(_), Ret(_))\n        | (Continue(_), Continue(_))\n        | (Break(_, _), Break(_, _))\n        | (AddrOf(_, _, _), AddrOf(_, _, _))\n        | (Path(_, _), Path(_, _))\n        | (Range(_, _, _), Range(_, _, _))\n        | (Index(_, _, _), Index(_, _, _))\n        | (Field(_, _), Field(_, _))\n        | (AssignOp(_, _, _), AssignOp(_, _, _))\n        | (Assign(_, _, _), Assign(_, _, _))\n        | (TryBlock(_, _), TryBlock(_, _))\n        | (Await(_, _), Await(_, _))\n        | (Gen(_, _, _, _), Gen(_, _, _, _))\n        | (Block(_, _), Block(_, _))\n        | (Closure(_), Closure(_))\n        | (Match(_, _, _), Match(_, _, _))\n        | (Loop(_, _, _), Loop(_, _, _))\n        | (ForLoop { .. }, ForLoop { .. })\n        | (While(_, _, _), While(_, _, _))\n        | (If(_, _, _), If(_, _, _))\n        | (Let(_, _, _, _), Let(_, _, _, _))\n        | (Type(_, _), Type(_, _))\n        | (Cast(_, _), Cast(_, _))\n        | (Lit(_), Lit(_))\n        | (Unary(_, _), Unary(_, _))\n        | (Binary(_, _, _), Binary(_, _, _))\n        | (Tup(_), Tup(_))\n        | (MethodCall(_), MethodCall(_))\n        | (Call(_, _), Call(_, _))\n        | (ConstBlock(_), ConstBlock(_))\n        | (Array(_), Array(_)) => {\n            // keep going\n        },\n        _ => {\n            return (IdentDifference::NonIdent, base);\n        },\n    }\n\n    let mut difference = IdentDifference::NoDifference;\n\n    for (left_attr, right_attr) in left.attrs.iter().zip(right.attrs.iter()) {\n        let (new_difference, new_base) =\n            ident_difference_via_ident_iter_with_base_location(left_attr, right_attr, base);\n        base = new_base;\n        difference += new_difference;\n        if difference.is_complete() {\n            return (difference, base);\n        }\n    }\n\n    let (new_difference, new_base) = ident_difference_via_ident_iter_with_base_location(left, right, base);\n    base = new_base;\n    difference += new_difference;\n\n    (difference, base)\n}\n\nfn ident_difference_via_ident_iter_with_base_location<Iterable: Into<IdentIter>>(\n    left: Iterable,\n    right: Iterable,\n    mut base: IdentLocation,\n) -> (IdentDifference, IdentLocation) {\n    // See the note in `ident_difference_expr_with_base_location` about `IdentIter`\n    let mut difference = IdentDifference::NoDifference;\n\n    let mut left_iterator = left.into();\n    let mut right_iterator = right.into();\n\n    loop {\n        match (left_iterator.next(), right_iterator.next()) {\n            (Some(left_ident), Some(right_ident)) => {\n                if !eq_id(left_ident, right_ident) {\n                    difference += IdentDifference::Single(base);\n                    if difference.is_complete() {\n                        return (difference, base);\n                    }\n                }\n            },\n            (Some(_), None) | (None, Some(_)) => {\n                return (IdentDifference::NonIdent, base);\n            },\n            (None, None) => {\n                return (difference, base);\n            },\n        }\n        base += IdentLocation { index: 1 };\n    }\n}\n\nfn get_ident(expr: &Expr, location: IdentLocation) -> Option<Ident> {\n    IdentIter::from(expr).nth(location.index)\n}\n\nfn suggestion_with_swapped_ident(\n    cx: &EarlyContext<'_>,\n    expr: &Expr,\n    location: IdentLocation,\n    new_ident: Ident,\n    applicability: &mut Applicability,\n) -> Option<String> {\n    get_ident(expr, location).and_then(|current_ident| {\n        if eq_id(current_ident, new_ident) {\n            // We never want to suggest a non-change\n            return None;\n        }\n\n        Some(format!(\n            \"{}{new_ident}{}\",\n            snippet_with_applicability(cx, expr.span.with_hi(current_ident.span.lo()), \"..\", applicability),\n            snippet_with_applicability(cx, expr.span.with_lo(current_ident.span.hi()), \"..\", applicability),\n        ))\n    })\n}\n\nfn skip_index<A, Iter>(iter: Iter, index: usize) -> impl Iterator<Item = A>\nwhere\n    Iter: Iterator<Item = A>,\n{\n    iter.enumerate()\n        .filter_map(move |(i, a)| if i == index { None } else { Some(a) })\n}\n"
  },
  {
    "path": "clippy_lints/src/suspicious_trait_impl.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::visitors::for_each_expr_without_closures;\nuse clippy_utils::{BINOP_TRAITS, OP_ASSIGN_TRAITS, binop_traits, trait_ref_of_method};\nuse core::ops::ControlFlow;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints for suspicious operations in impls of arithmetic operators, e.g.\n    /// subtracting elements in an Add impl.\n    ///\n    /// ### Why is this bad?\n    /// This is probably a typo or copy-and-paste error and not intended.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// impl Add for Foo {\n    ///     type Output = Foo;\n    ///\n    ///     fn add(self, other: Foo) -> Foo {\n    ///         Foo(self.0 - other.0)\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SUSPICIOUS_ARITHMETIC_IMPL,\n    suspicious,\n    \"suspicious use of operators in impl of arithmetic trait\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints for suspicious operations in impls of OpAssign, e.g.\n    /// subtracting elements in an AddAssign impl.\n    ///\n    /// ### Why is this bad?\n    /// This is probably a typo or copy-and-paste error and not intended.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// impl AddAssign for Foo {\n    ///     fn add_assign(&mut self, other: Foo) {\n    ///         *self = *self - other;\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub SUSPICIOUS_OP_ASSIGN_IMPL,\n    suspicious,\n    \"suspicious use of operators in impl of OpAssign trait\"\n}\n\ndeclare_lint_pass!(SuspiciousImpl => [\n    SUSPICIOUS_ARITHMETIC_IMPL,\n    SUSPICIOUS_OP_ASSIGN_IMPL,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        match expr.kind {\n            hir::ExprKind::Binary(op, _, _) => {\n                check_expr_inner(cx, expr, op.node, op.span);\n            },\n            hir::ExprKind::AssignOp(op, _, _) => {\n                check_expr_inner(cx, expr, op.node.into(), op.span);\n            },\n            _ => {},\n        }\n    }\n}\n\nfn check_expr_inner<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, binop: hir::BinOpKind, span: Span) {\n    if let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop)\n            && let Some(binop_trait_id) = cx.tcx.lang_items().get(binop_trait_lang)\n            && let Some(op_assign_trait_id) = cx.tcx.lang_items().get(op_assign_trait_lang)\n\n            // Check for more than one binary operation in the implemented function\n            // Linting when multiple operations are involved can result in false positives\n            && let parent_fn = cx.tcx.hir_get_parent_item(expr.hir_id).def_id\n            && let hir::Node::ImplItem(impl_item) = cx.tcx.hir_node_by_def_id(parent_fn)\n            && let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind\n            && let body = cx.tcx.hir_body(body_id)\n            && let parent_fn = cx.tcx.hir_get_parent_item(expr.hir_id)\n            && let Some(trait_ref) = trait_ref_of_method(cx, parent_fn)\n            && let trait_id = trait_ref.path.res.def_id()\n            && ![binop_trait_id, op_assign_trait_id].contains(&trait_id)\n            && let Some(&(_, lint)) = [\n                (&BINOP_TRAITS, SUSPICIOUS_ARITHMETIC_IMPL),\n                (&OP_ASSIGN_TRAITS, SUSPICIOUS_OP_ASSIGN_IMPL),\n            ]\n                .iter()\n                .find(|&(ts, _)| ts.iter().any(|&t| Some(trait_id) == cx.tcx.lang_items().get(t)))\n            && count_binops(body.value) == 1\n    {\n        span_lint(\n            cx,\n            lint,\n            span,\n            format!(\n                \"suspicious use of `{}` in `{}` impl\",\n                binop.as_str(),\n                cx.tcx.item_name(trait_id)\n            ),\n        );\n    }\n}\n\nfn count_binops(expr: &hir::Expr<'_>) -> u32 {\n    let mut count = 0u32;\n    let _: Option<!> = for_each_expr_without_closures(expr, |e| {\n        if matches!(\n            e.kind,\n            hir::ExprKind::Binary(..)\n                | hir::ExprKind::Unary(hir::UnOp::Not | hir::UnOp::Neg, _)\n                | hir::ExprKind::AssignOp(..)\n        ) {\n            count += 1;\n        }\n        ControlFlow::Continue(())\n    });\n    count\n}\n"
  },
  {
    "path": "clippy_lints/src/suspicious_xor_used_as_pow.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::numeric_literal::NumericLiteral;\nuse clippy_utils::source::snippet;\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// 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.\n    ///\n    /// ### Why restrict this?\n    /// It's most probably a typo and may lead to unexpected behaviours.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 3_i32 ^ 4_i32;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = 3_i32.pow(4);\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub SUSPICIOUS_XOR_USED_AS_POW,\n    restriction,\n    \"XOR (`^`) operator possibly used as exponentiation operator\"\n}\n\ndeclare_lint_pass!(ConfusingXorAndPow => [SUSPICIOUS_XOR_USED_AS_POW]);\n\nimpl LateLintPass<'_> for ConfusingXorAndPow {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if !expr.span.in_external_macro(cx.sess().source_map())\n            && let ExprKind::Binary(op, left, right) = &expr.kind\n            && op.node == BinOpKind::BitXor\n            && left.span.eq_ctxt(right.span)\n            && let ExprKind::Lit(lit_left) = &left.kind\n            && let ExprKind::Lit(lit_right) = &right.kind\n            && matches!(lit_right.node, LitKind::Int(..) | LitKind::Float(..))\n            && matches!(lit_left.node, LitKind::Int(..) | LitKind::Float(..))\n            && NumericLiteral::from_lit_kind(&snippet(cx, lit_right.span, \"..\"), &lit_right.node)\n                .is_some_and(|x| x.is_decimal())\n        {\n            span_lint_and_then(\n                cx,\n                SUSPICIOUS_XOR_USED_AS_POW,\n                expr.span,\n                \"`^` is not the exponentiation operator\",\n                |diag| {\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        \"did you mean to write\",\n                        format!(\"{}.pow({})\", lit_left.node, lit_right.node),\n                        Applicability::MaybeIncorrect,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/swap.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::{snippet_indent, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\n\nuse clippy_utils::{can_mut_borrow_both, eq_expr_value, is_in_const_context, std_or_core, sym};\nuse itertools::Itertools;\n\nuse rustc_data_structures::fx::FxIndexSet;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\n\nuse rustc_errors::Applicability;\nuse rustc_hir::{AssignOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::symbol::Ident;\nuse rustc_span::{Span, SyntaxContext};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `foo = bar; bar = foo` sequences.\n    ///\n    /// ### Why is this bad?\n    /// This looks like a failed attempt to swap.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let mut a = 1;\n    /// # let mut b = 2;\n    /// a = b;\n    /// b = a;\n    /// ```\n    /// If swapping is intended, use `swap()` instead:\n    /// ```no_run\n    /// # let mut a = 1;\n    /// # let mut b = 2;\n    /// std::mem::swap(&mut a, &mut b);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ALMOST_SWAPPED,\n    correctness,\n    \"`foo = bar; bar = foo` sequence\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for manual swapping.\n    ///\n    /// Note that the lint will not be emitted in const blocks, as the suggestion would not be applicable.\n    ///\n    /// ### Why is this bad?\n    /// The `std::mem::swap` function exposes the intent better\n    /// without deinitializing or copying either variable.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut a = 42;\n    /// let mut b = 1337;\n    ///\n    /// let t = b;\n    /// b = a;\n    /// a = t;\n    /// ```\n    /// Use std::mem::swap():\n    /// ```no_run\n    /// let mut a = 1;\n    /// let mut b = 2;\n    /// std::mem::swap(&mut a, &mut b);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub MANUAL_SWAP,\n    complexity,\n    \"manual swap of two variables\"\n}\n\ndeclare_lint_pass!(Swap => [ALMOST_SWAPPED, MANUAL_SWAP]);\n\nimpl<'tcx> LateLintPass<'tcx> for Swap {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {\n        check_manual_swap(cx, block);\n        check_suspicious_swap(cx, block);\n        check_xor_swap(cx, block);\n    }\n}\n\n#[expect(clippy::too_many_arguments)]\nfn generate_swap_warning<'tcx>(\n    block: &'tcx Block<'tcx>,\n    cx: &LateContext<'tcx>,\n    e1: &'tcx Expr<'tcx>,\n    e2: &'tcx Expr<'tcx>,\n    rhs1: &'tcx Expr<'tcx>,\n    rhs2: &'tcx Expr<'tcx>,\n    span: Span,\n    is_xor_based: bool,\n) {\n    let ctxt = span.ctxt();\n    let mut applicability = Applicability::MachineApplicable;\n\n    if !can_mut_borrow_both(cx, e1, e2) {\n        if let ExprKind::Index(lhs1, idx1, _) = e1.kind\n            && let ExprKind::Index(lhs2, idx2, _) = e2.kind\n            && eq_expr_value(cx, lhs1, lhs2)\n            && e1.span.ctxt() == ctxt\n            && e2.span.ctxt() == ctxt\n        {\n            let ty = cx.typeck_results().expr_ty(lhs1).peel_refs();\n\n            if matches!(ty.kind(), ty::Slice(_))\n                || matches!(ty.kind(), ty::Array(_, _))\n                || ty.is_diag_item(cx, sym::Vec)\n                || ty.is_diag_item(cx, sym::VecDeque)\n            {\n                let slice = Sugg::hir_with_applicability(cx, lhs1, \"<slice>\", &mut applicability);\n\n                span_lint_and_sugg(\n                    cx,\n                    MANUAL_SWAP,\n                    span,\n                    format!(\"this looks like you are swapping elements of `{slice}` manually\"),\n                    \"try\",\n                    format!(\n                        \"{}{}.swap({}, {});\",\n                        IndexBinding {\n                            block,\n                            swap1_idx: idx1,\n                            swap2_idx: idx2,\n                            suggest_span: span,\n                            cx,\n                            ctxt,\n                            applicability: &mut applicability,\n                        }\n                        .snippet_index_bindings(&[idx1, idx2, rhs1, rhs2]),\n                        slice.maybe_paren(),\n                        snippet_with_context(cx, idx1.span, ctxt, \"..\", &mut applicability).0,\n                        snippet_with_context(cx, idx2.span, ctxt, \"..\", &mut applicability).0,\n                    ),\n                    applicability,\n                );\n            }\n        }\n        return;\n    }\n\n    let first = Sugg::hir_with_context(cx, e1, ctxt, \"..\", &mut applicability);\n    let second = Sugg::hir_with_context(cx, e2, ctxt, \"..\", &mut applicability);\n    let Some(sugg) = std_or_core(cx) else { return };\n\n    span_lint_and_then(\n        cx,\n        MANUAL_SWAP,\n        span,\n        format!(\"this looks like you are swapping `{first}` and `{second}` manually\"),\n        |diag| {\n            diag.span_suggestion(\n                span,\n                \"try\",\n                format!(\"{sugg}::mem::swap({}, {});\", first.mut_addr(), second.mut_addr()),\n                applicability,\n            );\n            if !is_xor_based {\n                diag.note(format!(\"or maybe you should use `{sugg}::mem::replace`?\"));\n            }\n        },\n    );\n}\n\n/// Implementation of the `MANUAL_SWAP` lint.\nfn check_manual_swap<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {\n    if is_in_const_context(cx) {\n        return;\n    }\n\n    for [s1, s2, s3] in block.stmts.array_windows::<3>() {\n        if let StmtKind::Let(tmp) = s1.kind\n            // let t = foo();\n            && let Some(tmp_init) = tmp.init\n            && let PatKind::Binding(.., ident, None) = tmp.pat.kind\n\n            // foo() = bar();\n            && let StmtKind::Semi(first) = s2.kind\n            && let ExprKind::Assign(lhs1, rhs1, _) = first.kind\n\n            // bar() = t;\n            && let StmtKind::Semi(second) = s3.kind\n            && let ExprKind::Assign(lhs2, rhs2, _) = second.kind\n            && let ExprKind::Path(QPath::Resolved(None, rhs2_path)) = rhs2.kind\n            && rhs2_path.segments.len() == 1\n\n            && ident.name == rhs2_path.segments[0].ident.name\n            && eq_expr_value(cx, tmp_init, lhs1)\n            && eq_expr_value(cx, rhs1, lhs2)\n\n            && let ctxt = s1.span.ctxt()\n            && s2.span.ctxt() == ctxt\n            && s3.span.ctxt() == ctxt\n            && first.span.ctxt() == ctxt\n            && second.span.ctxt() == ctxt\n        {\n            let span = s1.span.to(s3.span);\n            generate_swap_warning(block, cx, lhs1, lhs2, rhs1, rhs2, span, false);\n        }\n    }\n}\n\n/// Implementation of the `ALMOST_SWAPPED` lint.\nfn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) {\n    for [first, second] in block.stmts.array_windows() {\n        if let Some((lhs0, rhs0)) = parse(first)\n            && let Some((lhs1, rhs1)) = parse(second)\n            && first.span.eq_ctxt(second.span)\n\t\t\t&& !first.span.in_external_macro(cx.sess().source_map())\n            && is_same(cx, lhs0, rhs1)\n            && is_same(cx, lhs1, rhs0)\n\t\t\t&& !is_same(cx, lhs1, rhs1) // Ignore a = b; a = a (#10421)\n            && let Some(lhs_sugg) = match &lhs0 {\n                ExprOrIdent::Expr(expr) => Sugg::hir_opt(cx, expr),\n                ExprOrIdent::Ident(ident) => Some(Sugg::NonParen(ident.as_str().into())),\n            }\n            && let Some(rhs_sugg) = Sugg::hir_opt(cx, rhs0)\n        {\n            let span = first.span.to(rhs1.span);\n            let Some(sugg) = std_or_core(cx) else { return };\n            span_lint_and_then(\n                cx,\n                ALMOST_SWAPPED,\n                span,\n                format!(\"this looks like you are trying to swap `{lhs_sugg}` and `{rhs_sugg}`\"),\n                |diag| {\n                    diag.span_suggestion(\n                        span,\n                        \"try\",\n                        format!(\"{sugg}::mem::swap({}, {})\", lhs_sugg.mut_addr(), rhs_sugg.mut_addr()),\n                        Applicability::MaybeIncorrect,\n                    );\n                    diag.note(format!(\"or maybe you should use `{sugg}::mem::replace`?\"));\n                },\n            );\n        }\n    }\n}\n\nfn is_same(cx: &LateContext<'_>, lhs: ExprOrIdent<'_>, rhs: &Expr<'_>) -> bool {\n    match lhs {\n        ExprOrIdent::Expr(expr) => eq_expr_value(cx, expr, rhs),\n        ExprOrIdent::Ident(ident) => {\n            if let ExprKind::Path(QPath::Resolved(None, path)) = rhs.kind\n                && let [segment] = &path.segments\n                && segment.ident == ident\n            {\n                true\n            } else {\n                false\n            }\n        },\n    }\n}\n\n#[derive(Debug, Clone, Copy)]\nenum ExprOrIdent<'a> {\n    Expr(&'a Expr<'a>),\n    Ident(Ident),\n}\n\nfn parse<'a, 'hir>(stmt: &'a Stmt<'hir>) -> Option<(ExprOrIdent<'hir>, &'a Expr<'hir>)> {\n    if let StmtKind::Semi(expr) = stmt.kind {\n        if let ExprKind::Assign(lhs, rhs, _) = expr.kind {\n            return Some((ExprOrIdent::Expr(lhs), rhs));\n        }\n    } else if let StmtKind::Let(expr) = stmt.kind\n        && let Some(rhs) = expr.init\n        && let PatKind::Binding(_, _, ident_l, _) = expr.pat.kind\n    {\n        return Some((ExprOrIdent::Ident(ident_l), rhs));\n    }\n    None\n}\n\n/// Implementation of the xor case for `MANUAL_SWAP` lint.\nfn check_xor_swap<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {\n    for [s1, s2, s3] in block.stmts.array_windows::<3>() {\n        let ctxt = s1.span.ctxt();\n        if let Some((lhs0, rhs0)) = extract_sides_of_xor_assign(s1, ctxt)\n            && let Some((lhs1, rhs1)) = extract_sides_of_xor_assign(s2, ctxt)\n            && let Some((lhs2, rhs2)) = extract_sides_of_xor_assign(s3, ctxt)\n            && eq_expr_value(cx, lhs0, rhs1)\n            && eq_expr_value(cx, lhs2, rhs1)\n            && eq_expr_value(cx, lhs1, rhs0)\n            && eq_expr_value(cx, lhs1, rhs2)\n            && s2.span.ctxt() == ctxt\n            && s3.span.ctxt() == ctxt\n        {\n            let span = s1.span.to(s3.span);\n            generate_swap_warning(block, cx, lhs0, rhs0, rhs1, rhs2, span, true);\n        }\n    }\n}\n\n/// Returns the lhs and rhs of an xor assignment statement.\nfn extract_sides_of_xor_assign<'a, 'hir>(\n    stmt: &'a Stmt<'hir>,\n    ctxt: SyntaxContext,\n) -> Option<(&'a Expr<'hir>, &'a Expr<'hir>)> {\n    if let StmtKind::Semi(expr) = stmt.kind\n        && let ExprKind::AssignOp(\n            Spanned {\n                node: AssignOpKind::BitXorAssign,\n                ..\n            },\n            lhs,\n            rhs,\n        ) = expr.kind\n        && expr.span.ctxt() == ctxt\n    {\n        Some((lhs, rhs))\n    } else {\n        None\n    }\n}\n\nstruct IndexBinding<'a, 'tcx> {\n    block: &'a Block<'a>,\n    swap1_idx: &'a Expr<'a>,\n    swap2_idx: &'a Expr<'a>,\n    suggest_span: Span,\n    cx: &'a LateContext<'tcx>,\n    ctxt: SyntaxContext,\n    applicability: &'a mut Applicability,\n}\n\nimpl<'tcx> IndexBinding<'_, 'tcx> {\n    fn snippet_index_bindings(&mut self, exprs: &[&'tcx Expr<'tcx>]) -> String {\n        let mut bindings = FxIndexSet::default();\n        for expr in exprs {\n            bindings.insert(self.snippet_index_binding(expr));\n        }\n        bindings.into_iter().join(\"\")\n    }\n\n    fn snippet_index_binding(&mut self, expr: &'tcx Expr<'tcx>) -> String {\n        match expr.kind {\n            ExprKind::Binary(_, lhs, rhs) => {\n                if matches!(lhs.kind, ExprKind::Lit(_)) && matches!(rhs.kind, ExprKind::Lit(_)) {\n                    return String::new();\n                }\n                let lhs_snippet = self.snippet_index_binding(lhs);\n                let rhs_snippet = self.snippet_index_binding(rhs);\n                format!(\"{lhs_snippet}{rhs_snippet}\")\n            },\n            ExprKind::Path(QPath::Resolved(_, path)) => {\n                let Some(first_segment) = path.segments.first() else {\n                    return String::new();\n                };\n\n                let init = self.cx.expr_or_init(expr);\n\n                // We skip suggesting a variable binding in any of these cases:\n                // - Variable initialization is outside the suggestion span\n                // - Variable declaration is outside the suggestion span\n                // - Variable is not used as an index or elsewhere later\n                if !self.suggest_span.contains(init.span)\n                    || expr\n                        .res_local_id()\n                        .is_some_and(|hir_id| !self.suggest_span.contains(self.cx.tcx.hir_span(hir_id)))\n                    || !self.is_used_other_than_swapping(first_segment.ident)\n                {\n                    return String::new();\n                }\n\n                let init_str = snippet_with_context(self.cx, init.span, self.ctxt, \"\", self.applicability)\n                    .0\n                    .to_string();\n                let indent_str = snippet_indent(self.cx, init.span);\n                let indent_str = indent_str.as_deref().unwrap_or(\"\");\n\n                format!(\"let {} = {init_str};\\n{indent_str}\", first_segment.ident)\n            },\n            _ => String::new(),\n        }\n    }\n\n    fn is_used_other_than_swapping(&self, idx_ident: Ident) -> bool {\n        if Self::is_used_slice_indexed(self.swap1_idx, idx_ident)\n            || Self::is_used_slice_indexed(self.swap2_idx, idx_ident)\n        {\n            return true;\n        }\n        self.is_used_after_swap(idx_ident)\n    }\n\n    fn is_used_after_swap(&self, idx_ident: Ident) -> bool {\n        let mut v = IndexBindingVisitor {\n            idx: idx_ident,\n            suggest_span: self.suggest_span,\n            found_used: false,\n        };\n\n        for stmt in self.block.stmts {\n            match stmt.kind {\n                StmtKind::Expr(expr) | StmtKind::Semi(expr) => v.visit_expr(expr),\n                StmtKind::Let(LetStmt { init, .. }) => {\n                    if let Some(init) = init.as_ref() {\n                        v.visit_expr(init);\n                    }\n                },\n                StmtKind::Item(_) => {},\n            }\n        }\n\n        v.found_used\n    }\n\n    fn is_used_slice_indexed(swap_index: &Expr<'_>, idx_ident: Ident) -> bool {\n        match swap_index.kind {\n            ExprKind::Binary(_, lhs, rhs) => {\n                if matches!(lhs.kind, ExprKind::Lit(_)) && matches!(rhs.kind, ExprKind::Lit(_)) {\n                    return false;\n                }\n                Self::is_used_slice_indexed(lhs, idx_ident) || Self::is_used_slice_indexed(rhs, idx_ident)\n            },\n            ExprKind::Path(QPath::Resolved(_, path)) => path.segments.first().is_some_and(|idx| idx.ident == idx_ident),\n            _ => false,\n        }\n    }\n}\n\nstruct IndexBindingVisitor {\n    idx: Ident,\n    suggest_span: Span,\n    found_used: bool,\n}\n\nimpl<'tcx> Visitor<'tcx> for IndexBindingVisitor {\n    fn visit_path_segment(&mut self, path_segment: &'tcx rustc_hir::PathSegment<'tcx>) -> Self::Result {\n        if path_segment.ident == self.idx {\n            self.found_used = true;\n        }\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> Self::Result {\n        if expr.span.hi() <= self.suggest_span.hi() {\n            return;\n        }\n\n        match expr.kind {\n            ExprKind::Path(QPath::Resolved(_, path)) => {\n                for segment in path.segments {\n                    self.visit_path_segment(segment);\n                }\n            },\n            _ => walk_expr(self, expr),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/swap_ptr_to_ref.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet_with_context;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{Span, SyntaxContext, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `core::mem::swap` where either parameter is derived from a pointer\n    ///\n    /// ### Why is this bad?\n    /// When at least one parameter to `swap` is derived from a pointer it may overlap with the\n    /// other. This would then lead to undefined behavior.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// unsafe fn swap(x: &[*mut u32], y: &[*mut u32]) {\n    ///     for (&x, &y) in x.iter().zip(y) {\n    ///         core::mem::swap(&mut *x, &mut *y);\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// unsafe fn swap(x: &[*mut u32], y: &[*mut u32]) {\n    ///     for (&x, &y) in x.iter().zip(y) {\n    ///         core::ptr::swap(x, y);\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub SWAP_PTR_TO_REF,\n    suspicious,\n    \"call to `mem::swap` using pointer derived references\"\n}\n\ndeclare_lint_pass!(SwapPtrToRef => [SWAP_PTR_TO_REF]);\n\nimpl LateLintPass<'_> for SwapPtrToRef {\n    fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {\n        if let ExprKind::Call(fn_expr, [arg1, arg2]) = e.kind\n            && fn_expr.basic_res().is_diag_item(cx, sym::mem_swap)\n            && let ctxt = e.span.ctxt()\n            && let (from_ptr1, arg1_span) = is_ptr_to_ref(cx, arg1, ctxt)\n            && let (from_ptr2, arg2_span) = is_ptr_to_ref(cx, arg2, ctxt)\n            && (from_ptr1 || from_ptr2)\n        {\n            span_lint_and_then(\n                cx,\n                SWAP_PTR_TO_REF,\n                e.span,\n                \"call to `core::mem::swap` with a parameter derived from a raw pointer\",\n                |diag| {\n                    if !((from_ptr1 && arg1_span.is_none()) || (from_ptr2 && arg2_span.is_none())) {\n                        let mut app = Applicability::MachineApplicable;\n                        let snip1 = snippet_with_context(cx, arg1_span.unwrap_or(arg1.span), ctxt, \"..\", &mut app).0;\n                        let snip2 = snippet_with_context(cx, arg2_span.unwrap_or(arg2.span), ctxt, \"..\", &mut app).0;\n                        diag.span_suggestion(\n                            e.span,\n                            \"use ptr::swap\",\n                            format!(\"core::ptr::swap({snip1}, {snip2})\"),\n                            app,\n                        );\n                    }\n                },\n            );\n        }\n    }\n}\n\n/// Checks if the expression converts a mutable pointer to a mutable reference. If it is, also\n/// returns the span of the pointer expression if it's suitable for making a suggestion.\nfn is_ptr_to_ref(cx: &LateContext<'_>, e: &Expr<'_>, ctxt: SyntaxContext) -> (bool, Option<Span>) {\n    if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, borrowed_expr) = e.kind\n        && let ExprKind::Unary(UnOp::Deref, derefed_expr) = borrowed_expr.kind\n        && cx.typeck_results().expr_ty(derefed_expr).is_raw_ptr()\n    {\n        (\n            true,\n            (borrowed_expr.span.ctxt() == ctxt || derefed_expr.span.ctxt() == ctxt).then_some(derefed_expr.span),\n        )\n    } else {\n        (false, None)\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/tabs_in_doc_comments.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse rustc_ast::ast;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{BytePos, Span};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks doc comments for usage of tab characters.\n    ///\n    /// ### Why is this bad?\n    /// The rust style-guide promotes spaces instead of tabs for indentation.\n    /// To keep a consistent view on the source, also doc comments should not have tabs.\n    /// Also, explaining ascii-diagrams containing tabs can get displayed incorrectly when the\n    /// display settings of the author and reader differ.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// ///\n    /// /// Struct to hold two strings:\n    /// /// \t- first\t\tone\n    /// /// \t- second\tone\n    /// pub struct DoubleString {\n    ///    ///\n    ///    /// \t- First String:\n    ///    /// \t\t- needs to be inside here\n    ///    first_string: String,\n    ///    ///\n    ///    /// \t- Second String:\n    ///    /// \t\t- needs to be inside here\n    ///    second_string: String,\n    ///}\n    /// ```\n    ///\n    /// Will be converted to:\n    /// ```no_run\n    /// ///\n    /// /// Struct to hold two strings:\n    /// ///     - first        one\n    /// ///     - second    one\n    /// pub struct DoubleString {\n    ///    ///\n    ///    ///     - First String:\n    ///    ///         - needs to be inside here\n    ///    first_string: String,\n    ///    ///\n    ///    ///     - Second String:\n    ///    ///         - needs to be inside here\n    ///    second_string: String,\n    ///}\n    /// ```\n    #[clippy::version = \"1.41.0\"]\n    pub TABS_IN_DOC_COMMENTS,\n    style,\n    \"using tabs in doc comments is not recommended\"\n}\n\ndeclare_lint_pass!(TabsInDocComments => [TABS_IN_DOC_COMMENTS]);\n\nimpl TabsInDocComments {\n    fn warn_if_tabs_in_doc(cx: &EarlyContext<'_>, attr: &ast::Attribute) {\n        if let ast::AttrKind::DocComment(_, comment) = attr.kind {\n            let comment = comment.as_str();\n\n            for (lo, hi) in get_chunks_of_tabs(comment) {\n                // +3 skips the opening delimiter\n                let new_span = Span::new(\n                    attr.span.lo() + BytePos(3 + lo),\n                    attr.span.lo() + BytePos(3 + hi),\n                    attr.span.ctxt(),\n                    attr.span.parent(),\n                );\n                span_lint_and_sugg(\n                    cx,\n                    TABS_IN_DOC_COMMENTS,\n                    new_span,\n                    \"using tabs in doc comments is not recommended\",\n                    \"consider using four spaces per tab\",\n                    \"    \".repeat((hi - lo) as usize),\n                    Applicability::MaybeIncorrect,\n                );\n            }\n        }\n    }\n}\n\nimpl EarlyLintPass for TabsInDocComments {\n    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attribute: &ast::Attribute) {\n        Self::warn_if_tabs_in_doc(cx, attribute);\n    }\n}\n\n///\n/// scans the string for groups of tabs and returns the start(inclusive) and end positions\n/// (exclusive) of all groups\n/// e.g. \"sd\\tasd\\t\\taa\" will be converted to [(2, 3), (6, 8)] as\n///       012 3456 7 89\n///         ^-^  ^---^\nfn get_chunks_of_tabs(the_str: &str) -> Vec<(u32, u32)> {\n    let line_length_way_to_long = \"doc comment longer than 2^32 chars\";\n    let mut spans: Vec<(u32, u32)> = vec![];\n    let mut current_start: u32 = 0;\n\n    // tracker to decide if the last group of tabs is not closed by a non-tab character\n    let mut is_active = false;\n\n    // Note that we specifically need the char _byte_ indices here, not the positional indexes\n    // within the char array to deal with multi-byte characters properly. `char_indices` does\n    // exactly that. It provides an iterator over tuples of the form `(byte position, char)`.\n    let char_indices: Vec<_> = the_str.char_indices().collect();\n\n    if let [(_, '\\t')] = char_indices.as_slice() {\n        return vec![(0, 1)];\n    }\n\n    for entry in char_indices.windows(2) {\n        match entry {\n            [(_, '\\t'), (_, '\\t')] => {\n                // either string starts with double tab, then we have to set it active,\n                // otherwise is_active is true anyway\n                is_active = true;\n            },\n            [(_, _), (index_b, '\\t')] => {\n                // as ['\\t', '\\t'] is excluded, this has to be a start of a tab group,\n                // set indices accordingly\n                is_active = true;\n                current_start = u32::try_from(*index_b).unwrap();\n            },\n            [(_, '\\t'), (index_b, _)] => {\n                // this now has to be an end of the group, hence we have to push a new tuple\n                is_active = false;\n                spans.push((current_start, u32::try_from(*index_b).unwrap()));\n            },\n            _ => {},\n        }\n    }\n\n    // only possible when tabs are at the end, insert last group\n    if is_active {\n        spans.push((\n            current_start,\n            u32::try_from(char_indices.last().unwrap().0 + 1).expect(line_length_way_to_long),\n        ));\n    }\n\n    spans\n}\n\n#[cfg(test)]\nmod tests_for_get_chunks_of_tabs {\n    use super::get_chunks_of_tabs;\n\n    #[test]\n    fn test_unicode_han_string() {\n        let res = get_chunks_of_tabs(\" \\u{4f4d}\\t\");\n\n        assert_eq!(res, vec![(4, 5)]);\n    }\n\n    #[test]\n    fn test_empty_string() {\n        let res = get_chunks_of_tabs(\"\");\n\n        assert_eq!(res, vec![]);\n    }\n\n    #[test]\n    fn test_simple() {\n        let res = get_chunks_of_tabs(\"sd\\t\\t\\taa\");\n\n        assert_eq!(res, vec![(2, 5)]);\n    }\n\n    #[test]\n    fn test_only_t() {\n        let res = get_chunks_of_tabs(\"\\t\\t\");\n\n        assert_eq!(res, vec![(0, 2)]);\n    }\n\n    #[test]\n    fn test_only_one_t() {\n        let res = get_chunks_of_tabs(\"\\t\");\n\n        assert_eq!(res, vec![(0, 1)]);\n    }\n\n    #[test]\n    fn test_double() {\n        let res = get_chunks_of_tabs(\"sd\\tasd\\t\\taa\");\n\n        assert_eq!(res, vec![(2, 3), (6, 8)]);\n    }\n\n    #[test]\n    fn test_start() {\n        let res = get_chunks_of_tabs(\"\\t\\taa\");\n\n        assert_eq!(res, vec![(0, 2)]);\n    }\n\n    #[test]\n    fn test_end() {\n        let res = get_chunks_of_tabs(\"aa\\t\\t\");\n\n        assert_eq!(res, vec![(2, 4)]);\n    }\n\n    #[test]\n    fn test_start_single() {\n        let res = get_chunks_of_tabs(\"\\taa\");\n\n        assert_eq!(res, vec![(0, 1)]);\n    }\n\n    #[test]\n    fn test_end_single() {\n        let res = get_chunks_of_tabs(\"aa\\t\");\n\n        assert_eq!(res, vec![(2, 3)]);\n    }\n\n    #[test]\n    fn test_no_tabs() {\n        let res = get_chunks_of_tabs(\"dsfs\");\n\n        assert_eq!(res, vec![]);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/temporary_assignment.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::is_adjusted;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for construction of a structure or tuple just to\n    /// assign a value in it.\n    ///\n    /// ### Why is this bad?\n    /// Readability. If the structure is only created to be\n    /// updated, why not write the structure you want in the first place?\n    ///\n    /// ### Example\n    /// ```no_run\n    /// (0, 0).0 = 1\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TEMPORARY_ASSIGNMENT,\n    complexity,\n    \"assignments to temporaries\"\n}\n\ndeclare_lint_pass!(TemporaryAssignment => [TEMPORARY_ASSIGNMENT]);\n\nfn is_temporary(expr: &Expr<'_>) -> bool {\n    matches!(&expr.kind, ExprKind::Struct(..) | ExprKind::Tup(..))\n}\n\nimpl<'tcx> LateLintPass<'tcx> for TemporaryAssignment {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Assign(target, ..) = &expr.kind {\n            let mut base = target;\n            while let ExprKind::Field(f, _) | ExprKind::Index(f, _, _) = &base.kind {\n                base = f;\n            }\n            if is_temporary(base) && !is_adjusted(cx, base) {\n                span_lint(cx, TEMPORARY_ASSIGNMENT, expr.span, \"assignment to temporary\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/tests_outside_test_module.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::{is_in_cfg_test, is_in_test_function};\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, FnDecl};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Triggers when a testing function (marked with the `#[test]` attribute) isn't inside a testing module\n    /// (marked with `#[cfg(test)]`).\n    ///\n    /// ### Why restrict this?\n    /// The idiomatic (and more performant) way of writing tests is inside a testing module (flagged with `#[cfg(test)]`),\n    /// having test functions outside of this module is confusing and may lead to them being \"hidden\".\n    ///\n    /// ### Example\n    /// ```no_run\n    /// #[test]\n    /// fn my_cool_test() {\n    ///     // [...]\n    /// }\n    ///\n    /// #[cfg(test)]\n    /// mod tests {\n    ///     // [...]\n    /// }\n    ///\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[cfg(test)]\n    /// mod tests {\n    ///     #[test]\n    ///     fn my_cool_test() {\n    ///         // [...]\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub TESTS_OUTSIDE_TEST_MODULE,\n    restriction,\n    \"A test function is outside the testing module.\"\n}\n\ndeclare_lint_pass!(TestsOutsideTestModule => [TESTS_OUTSIDE_TEST_MODULE]);\n\nimpl LateLintPass<'_> for TestsOutsideTestModule {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'_>,\n        kind: FnKind<'_>,\n        _: &FnDecl<'_>,\n        body: &Body<'_>,\n        sp: Span,\n        _: LocalDefId,\n    ) {\n        if !matches!(kind, FnKind::Closure)\n            && is_in_test_function(cx.tcx, body.id().hir_id)\n            && !is_in_cfg_test(cx.tcx, body.id().hir_id)\n        {\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                TESTS_OUTSIDE_TEST_MODULE,\n                sp,\n                \"this function marked with #[test] is outside a #[cfg(test)] module\",\n                |diag| {\n                    diag.note(\"move it to a testing module marked with #[cfg(test)]\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/time_subtraction.rs",
    "content": "use std::time::Duration;\n\nuse clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::SyntaxContext;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints subtraction between `Instant::now()` and another `Instant`.\n    ///\n    /// ### Why is this bad?\n    /// It is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns\n    /// as `Instant` subtraction saturates.\n    ///\n    /// `prev_instant.elapsed()` also more clearly signals intention.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::time::Instant;\n    /// let prev_instant = Instant::now();\n    /// let duration = Instant::now() - prev_instant;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::time::Instant;\n    /// let prev_instant = Instant::now();\n    /// let duration = prev_instant.elapsed();\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub MANUAL_INSTANT_ELAPSED,\n    pedantic,\n    \"subtraction between `Instant::now()` and previous `Instant`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Lints subtraction between an `Instant` and a `Duration`, or between two `Duration` values.\n    ///\n    /// ### Why is this bad?\n    /// Unchecked subtraction could cause underflow on certain platforms, leading to\n    /// unintentional panics.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::time::{Instant, Duration};\n    /// let time_passed = Instant::now() - Duration::from_secs(5);\n    /// let dur1 = Duration::from_secs(3);\n    /// let dur2 = Duration::from_secs(5);\n    /// let diff = dur1 - dur2;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::time::{Instant, Duration};\n    /// let time_passed = Instant::now().checked_sub(Duration::from_secs(5));\n    /// let dur1 = Duration::from_secs(3);\n    /// let dur2 = Duration::from_secs(5);\n    /// let diff = dur1.checked_sub(dur2);\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub UNCHECKED_TIME_SUBTRACTION,\n    pedantic,\n    \"finds unchecked subtraction involving 'Duration' or 'Instant'\"\n}\n\nimpl_lint_pass!(UncheckedTimeSubtraction => [\n    MANUAL_INSTANT_ELAPSED,\n    UNCHECKED_TIME_SUBTRACTION,\n]);\n\npub struct UncheckedTimeSubtraction {\n    msrv: Msrv,\n}\n\nimpl UncheckedTimeSubtraction {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for UncheckedTimeSubtraction {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        let (lhs, rhs) = match expr.kind {\n            ExprKind::Binary(op, lhs, rhs) if matches!(op.node, BinOpKind::Sub,) => (lhs, rhs),\n            ExprKind::MethodCall(_, lhs, [rhs], _) if cx.ty_based_def(expr).is_diag_item(cx, sym::sub) => (lhs, rhs),\n            _ => return,\n        };\n        let typeck = cx.typeck_results();\n        let lhs_name = typeck.expr_ty(lhs).opt_diag_name(cx);\n        let rhs_name = typeck.expr_ty(rhs).opt_diag_name(cx);\n\n        if lhs_name == Some(sym::Instant) {\n            // Instant::now() - instant\n            if is_instant_now_call(cx, lhs) && rhs_name == Some(sym::Instant) {\n                print_manual_instant_elapsed_sugg(cx, expr, rhs);\n            }\n            // instant - duration\n            else if rhs_name == Some(sym::Duration)\n                && !expr.span.from_expansion()\n                && self.msrv.meets(cx, msrvs::TRY_FROM)\n            {\n                print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr);\n            }\n        }\n        // duration - duration\n        else if lhs_name == Some(sym::Duration)\n            && rhs_name == Some(sym::Duration)\n            && !expr.span.from_expansion()\n            && self.msrv.meets(cx, msrvs::TRY_FROM)\n        {\n            let const_eval = ConstEvalCtxt::new(cx);\n            let ctxt = expr.span.ctxt();\n            if let Some(lhs) = const_eval_duration(&const_eval, lhs, ctxt)\n                && let Some(rhs) = const_eval_duration(&const_eval, rhs, ctxt)\n            {\n                if lhs >= rhs {\n                    // If the duration subtraction can be proven to not underflow, then we don't lint\n                    return;\n                }\n\n                span_lint_and_note(\n                    cx,\n                    UNCHECKED_TIME_SUBTRACTION,\n                    expr.span,\n                    \"unchecked subtraction of two `Duration` that will underflow\",\n                    None,\n                    \"if this is intentional, consider allowing the lint\",\n                );\n                return;\n            }\n\n            print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr);\n        }\n    }\n}\n\nfn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {\n    if let ExprKind::Call(fn_expr, []) = expr_block.kind\n        && cx.ty_based_def(fn_expr).is_diag_item(cx, sym::instant_now)\n    {\n        true\n    } else {\n        false\n    }\n}\n\n/// Returns true if this subtraction is part of a chain like `(a - b) - c`\nfn is_chained_time_subtraction(cx: &LateContext<'_>, lhs: &Expr<'_>) -> bool {\n    if let ExprKind::Binary(op, inner_lhs, inner_rhs) = &lhs.kind\n        && matches!(op.node, BinOpKind::Sub)\n    {\n        let typeck = cx.typeck_results();\n        let left_ty = typeck.expr_ty(inner_lhs);\n        let right_ty = typeck.expr_ty(inner_rhs);\n        is_time_type(cx, left_ty) && is_time_type(cx, right_ty)\n    } else {\n        false\n    }\n}\n\n/// Returns true if the type is Duration or Instant\nfn is_time_type(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    matches!(ty.opt_diag_name(cx), Some(sym::Duration | sym::Instant))\n}\n\nfn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, rhs: &Expr<'_>) {\n    let mut applicability = Applicability::MachineApplicable;\n    let sugg = Sugg::hir_with_context(cx, rhs, expr.span.ctxt(), \"<instant>\", &mut applicability);\n    span_lint_and_sugg(\n        cx,\n        MANUAL_INSTANT_ELAPSED,\n        expr.span,\n        \"manual implementation of `Instant::elapsed`\",\n        \"try\",\n        format!(\"{}.elapsed()\", sugg.maybe_paren()),\n        applicability,\n    );\n}\n\nfn print_unchecked_duration_subtraction_sugg(\n    cx: &LateContext<'_>,\n    left_expr: &Expr<'_>,\n    right_expr: &Expr<'_>,\n    expr: &Expr<'_>,\n) {\n    span_lint_and_then(\n        cx,\n        UNCHECKED_TIME_SUBTRACTION,\n        expr.span,\n        \"unchecked subtraction of a `Duration`\",\n        |diag| {\n            // For chained subtraction, like `(dur1 - dur2) - dur3` or `(instant - dur1) - dur2`,\n            // avoid suggestions\n            if !is_chained_time_subtraction(cx, left_expr) {\n                let mut applicability = Applicability::MachineApplicable;\n                let left_sugg = Sugg::hir_with_context(cx, left_expr, expr.span.ctxt(), \"<left>\", &mut applicability);\n                let right_sugg =\n                    Sugg::hir_with_context(cx, right_expr, expr.span.ctxt(), \"<right>\", &mut applicability);\n\n                diag.span_suggestion(\n                    expr.span,\n                    \"try\",\n                    format!(\"{}.checked_sub({}).unwrap()\", left_sugg.maybe_paren(), right_sugg),\n                    applicability,\n                );\n            }\n        },\n    );\n}\n\nfn const_eval_duration(const_eval: &ConstEvalCtxt<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> Option<Duration> {\n    if let ExprKind::Call(func, args) = expr.kind\n        && let ExprKind::Path(QPath::TypeRelative(_, func_name)) = func.kind\n    {\n        macro_rules! try_parse_duration {\n            (($( $name:ident : $var:ident ( $ty:ty ) ),+ $(,)?) -> $ctor:ident ( $($args:tt)* )) => {{\n                let [$( $name ),+] = args else { return None };\n                $(\n                    let Some(Constant::$var(v)) = const_eval.eval_local($name, ctxt) else { return None };\n                    let $name = <$ty>::try_from(v).ok()?;\n                )+\n                Some(Duration::$ctor($($args)*))\n            }};\n        }\n\n        return match func_name.ident.name {\n            sym::new => try_parse_duration! { (secs: Int(u64), nanos: Int(u32)) -> new(secs, nanos) },\n            sym::from_nanos => try_parse_duration! { (nanos: Int(u64)) -> from_nanos(nanos) },\n            sym::from_nanos_u128 => try_parse_duration! { (nanos: Int(u128)) -> from_nanos_u128(nanos) },\n            sym::from_micros => try_parse_duration! { (micros: Int(u64)) -> from_micros(micros) },\n            sym::from_millis => try_parse_duration! { (millis: Int(u64)) -> from_millis(millis) },\n            sym::from_secs => try_parse_duration! { (secs: Int(u64)) -> from_secs(secs) },\n            sym::from_secs_f32 => try_parse_duration! { (secs: F32(f32)) -> from_secs_f32(secs) },\n            sym::from_secs_f64 => try_parse_duration! { (secs: F64(f64)) -> from_secs_f64(secs) },\n            sym::from_mins => try_parse_duration! { (mins: Int(u64)) -> from_mins(mins) },\n            sym::from_hours => {\n                try_parse_duration! { (hours: Int(u64)) -> from_hours(hours) }\n            },\n            sym::from_days => {\n                try_parse_duration! { (days: Int(u64)) -> from_hours(days * 24) }\n            },\n            sym::from_weeks => {\n                try_parse_duration! { (weeks: Int(u64)) -> from_hours(weeks * 24 * 7) }\n            },\n            _ => None,\n        };\n    }\n\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/to_digit_is_some.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{is_in_const_context, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `.to_digit(..).is_some()` on `char`s.\n    ///\n    /// ### Why is this bad?\n    /// This is a convoluted way of checking if a `char` is a digit. It's\n    /// more straight forward to use the dedicated `is_digit` method.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let c = 'c';\n    /// # let radix = 10;\n    /// let is_digit = c.to_digit(radix).is_some();\n    /// ```\n    /// can be written as:\n    /// ```no_run\n    /// # let c = 'c';\n    /// # let radix = 10;\n    /// let is_digit = c.is_digit(radix);\n    /// ```\n    #[clippy::version = \"1.41.0\"]\n    pub TO_DIGIT_IS_SOME,\n    style,\n    \"`char.is_digit()` is clearer\"\n}\n\nimpl_lint_pass!(ToDigitIsSome => [TO_DIGIT_IS_SOME]);\n\npub(crate) struct ToDigitIsSome {\n    msrv: Msrv,\n}\n\nimpl ToDigitIsSome {\n    pub(crate) fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        if let hir::ExprKind::MethodCall(is_some_path, to_digit_expr, [], _) = &expr.kind\n            && is_some_path.ident.name == sym::is_some\n        {\n            let match_result = match to_digit_expr.kind {\n                hir::ExprKind::MethodCall(to_digits_path, char_arg, [radix_arg], _) => {\n                    if to_digits_path.ident.name == sym::to_digit\n                        && cx.typeck_results().expr_ty_adjusted(char_arg).is_char()\n                    {\n                        Some((true, char_arg, radix_arg))\n                    } else {\n                        None\n                    }\n                },\n                hir::ExprKind::Call(to_digits_call, [char_arg, radix_arg]) => {\n                    if to_digits_call.res(cx).is_diag_item(cx, sym::char_to_digit) {\n                        Some((false, char_arg, radix_arg))\n                    } else {\n                        None\n                    }\n                },\n                _ => None,\n            };\n\n            if let Some((is_method_call, char_arg, radix_arg)) = match_result\n                && (!is_in_const_context(cx) || self.msrv.meets(cx, msrvs::CONST_CHAR_IS_DIGIT))\n            {\n                let mut applicability = Applicability::MachineApplicable;\n                let char_arg_snip = snippet_with_applicability(cx, char_arg.span, \"_\", &mut applicability);\n                let radix_snip = snippet_with_applicability(cx, radix_arg.span, \"_\", &mut applicability);\n\n                span_lint_and_sugg(\n                    cx,\n                    TO_DIGIT_IS_SOME,\n                    expr.span,\n                    \"use of `.to_digit(..).is_some()`\",\n                    \"try\",\n                    if is_method_call {\n                        format!(\"{char_arg_snip}.is_digit({radix_snip})\")\n                    } else {\n                        format!(\"char::is_digit({char_arg_snip}, {radix_snip})\")\n                    },\n                    applicability,\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/to_string_trait_impl.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::sym;\nuse rustc_hir::{Impl, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for direct implementations of `ToString`.\n    /// ### Why is this bad?\n    /// This trait is automatically implemented for any type which implements the `Display` trait.\n    /// As such, `ToString` shouldn’t be implemented directly: `Display` should be implemented instead,\n    /// and you get the `ToString` implementation for free.\n    /// ### Example\n    /// ```no_run\n    /// struct Point {\n    ///   x: usize,\n    ///   y: usize,\n    /// }\n    ///\n    /// impl ToString for Point {\n    ///   fn to_string(&self) -> String {\n    ///     format!(\"({}, {})\", self.x, self.y)\n    ///   }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct Point {\n    ///   x: usize,\n    ///   y: usize,\n    /// }\n    ///\n    /// impl std::fmt::Display for Point {\n    ///   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n    ///     write!(f, \"({}, {})\", self.x, self.y)\n    ///   }\n    /// }\n    /// ```\n    #[clippy::version = \"1.78.0\"]\n    pub TO_STRING_TRAIT_IMPL,\n    style,\n    \"check for direct implementations of `ToString`\"\n}\n\ndeclare_lint_pass!(ToStringTraitImpl => [TO_STRING_TRAIT_IMPL]);\n\nimpl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'tcx>) {\n        if let ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            ..\n        }) = it.kind\n            && let Some(trait_did) = of_trait.trait_ref.trait_def_id()\n            && cx.tcx.is_diagnostic_item(sym::ToString, trait_did)\n        {\n            span_lint_and_help(\n                cx,\n                TO_STRING_TRAIT_IMPL,\n                it.span,\n                \"direct implementation of `ToString`\",\n                None,\n                \"prefer implementing `Display` instead\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/toplevel_ref_arg.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};\nuse clippy_utils::source::{snippet, snippet_with_context};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::{is_lint_allowed, iter_input_pats};\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{BindingMode, Body, ByRef, FnDecl, Mutability, PatKind, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\nuse crate::ref_patterns::REF_PATTERNS;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for function arguments and let bindings denoted as\n    /// `ref`.\n    ///\n    /// ### Why is this bad?\n    /// The `ref` declaration makes the function take an owned\n    /// value, but turns the argument into a reference (which means that the value\n    /// is destroyed when exiting the function). This adds not much value: either\n    /// take a reference type, or take an owned value and create references in the\n    /// body.\n    ///\n    /// For let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The\n    /// type of `x` is more obvious with the former.\n    ///\n    /// ### Known problems\n    /// If the argument is dereferenced within the function,\n    /// removing the `ref` will lead to errors. This can be fixed by removing the\n    /// dereferences, e.g., changing `*x` to `x` within the function.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(ref _x: u8) {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn foo(_x: &u8) {}\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TOPLEVEL_REF_ARG,\n    style,\n    \"an entire binding declared as `ref`, in a function argument or a `let` statement\"\n}\n\ndeclare_lint_pass!(ToplevelRefArg => [TOPLEVEL_REF_ARG]);\n\nimpl<'tcx> LateLintPass<'tcx> for ToplevelRefArg {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        k: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        _: Span,\n        _: LocalDefId,\n    ) {\n        if !matches!(k, FnKind::Closure) {\n            for arg in iter_input_pats(decl, body) {\n                if let PatKind::Binding(BindingMode(ByRef::Yes(..), _), ..) = arg.pat.kind\n                    && is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id)\n                    && !arg.span.in_external_macro(cx.tcx.sess.source_map())\n                {\n                    span_lint_hir(\n                        cx,\n                        TOPLEVEL_REF_ARG,\n                        arg.hir_id,\n                        arg.pat.span,\n                        \"`ref` directly on a function parameter does not prevent taking ownership of the passed argument. \\\n                            Consider using a reference type instead\",\n                    );\n                }\n            }\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if let StmtKind::Let(local) = stmt.kind\n            && let PatKind::Binding(BindingMode(ByRef::Yes(_, mutabl), _), .., name, None) = local.pat.kind\n            && let Some(init) = local.init\n            // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue.\n            && is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id)\n            && !stmt.span.in_external_macro(cx.tcx.sess.source_map())\n        {\n            let ctxt = local.span.ctxt();\n            let mut app = Applicability::MachineApplicable;\n            let sugg_init = Sugg::hir_with_context(cx, init, ctxt, \"..\", &mut app);\n            let (mutopt, initref) = match mutabl {\n                Mutability::Mut => (\"mut \", sugg_init.mut_addr()),\n                Mutability::Not => (\"\", sugg_init.addr()),\n            };\n            let tyopt = if let Some(ty) = local.ty {\n                let ty_snip = snippet_with_context(cx, ty.span, ctxt, \"_\", &mut app).0;\n                format!(\": &{mutopt}{ty_snip}\")\n            } else {\n                String::new()\n            };\n            span_lint_hir_and_then(\n                cx,\n                TOPLEVEL_REF_ARG,\n                init.hir_id,\n                local.pat.span,\n                \"`ref` on an entire `let` pattern is discouraged, take a reference with `&` instead\",\n                |diag| {\n                    diag.span_suggestion(\n                        stmt.span,\n                        \"try\",\n                        format!(\"let {name}{tyopt} = {initref};\", name = snippet(cx, name.span, \"..\")),\n                        app,\n                    );\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/trailing_empty_array.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::{has_repr_attr, is_in_test};\nuse rustc_hir::{Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute.\n    ///\n    /// ### Why is this bad?\n    /// Zero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjunction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct RarelyUseful {\n    ///     some_field: u32,\n    ///     last: [u32; 0],\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// #[repr(C)]\n    /// struct MoreOftenUseful {\n    ///     some_field: usize,\n    ///     last: [u32; 0],\n    /// }\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub TRAILING_EMPTY_ARRAY,\n    nursery,\n    \"struct with a trailing zero-sized array but without `#[repr(C)]` or another `repr` attribute\"\n}\n\ndeclare_lint_pass!(TrailingEmptyArray => [TRAILING_EMPTY_ARRAY]);\n\nimpl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if is_struct_with_trailing_zero_sized_array(cx, item)\n            && !has_repr_attr(cx, item.hir_id())\n            && !is_in_test(cx.tcx, item.hir_id())\n        {\n            span_lint_and_help(\n                cx,\n                TRAILING_EMPTY_ARRAY,\n                item.span,\n                \"trailing zero-sized array in a struct which is not marked with a `repr` attribute\",\n                None,\n                format!(\n                    \"consider annotating `{}` with `#[repr(C)]` or another `repr` attribute\",\n                    cx.tcx.def_path_str(item.owner_id)\n                ),\n            );\n        }\n    }\n}\n\nfn is_struct_with_trailing_zero_sized_array<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {\n    if let ItemKind::Struct(_, _, data) = &item.kind\n        && let Some(last_field) = data.fields().last()\n        && let field_ty = cx.tcx.normalize_erasing_regions(\n            cx.typing_env(),\n            cx.tcx.type_of(last_field.def_id).instantiate_identity(),\n        )\n        && let ty::Array(_, array_len) = *field_ty.kind()\n        && let Some(0) = array_len.try_to_target_usize(cx.tcx)\n    {\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/trait_bounds.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};\nuse clippy_utils::{SpanlessEq, SpanlessHash, is_from_proc_macro};\nuse core::hash::{Hash, Hasher};\nuse itertools::Itertools;\nuse rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, IndexEntry};\nuse rustc_data_structures::unhash::UnhashMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{\n    AmbigArg, BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment,\n    PredicateOrigin, QPath, TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicateKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for cases where generics or trait objects are being used and multiple\n    /// syntax specifications for trait bounds are used simultaneously.\n    ///\n    /// ### Why is this bad?\n    /// Duplicate bounds makes the code\n    /// less readable than specifying them only once.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn func<T: Clone + Default>(arg: T) where T: Clone + Default {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # mod hidden {\n    /// fn func<T: Clone + Default>(arg: T) {}\n    /// # }\n    ///\n    /// // or\n    ///\n    /// fn func<T>(arg: T) where T: Clone + Default {}\n    /// ```\n    ///\n    /// ```no_run\n    /// fn foo<T: Default + Default>(bar: T) {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo<T: Default>(bar: T) {}\n    /// ```\n    ///\n    /// ```no_run\n    /// fn foo<T>(bar: T) where T: Default + Default {}\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo<T>(bar: T) where T: Default {}\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub TRAIT_DUPLICATION_IN_BOUNDS,\n    nursery,\n    \"check if the same trait bounds are specified more than once during a generic declaration\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns about unnecessary type repetitions in trait bounds\n    ///\n    /// ### Why is this bad?\n    /// Repeating the type for every bound makes the code\n    /// less readable than combining the bounds\n    ///\n    /// ### Example\n    /// ```no_run\n    /// pub fn foo<T>(t: T) where T: Copy, T: Clone {}\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// pub fn foo<T>(t: T) where T: Copy + Clone {}\n    /// ```\n    #[clippy::version = \"1.38.0\"]\n    pub TYPE_REPETITION_IN_BOUNDS,\n    nursery,\n    \"types are repeated unnecessarily in trait bounds, use `+` instead of using `T: _, T: _`\"\n}\n\nimpl_lint_pass!(TraitBounds => [\n    TRAIT_DUPLICATION_IN_BOUNDS,\n    TYPE_REPETITION_IN_BOUNDS,\n]);\n\npub struct TraitBounds {\n    max_trait_bounds: u64,\n    msrv: Msrv,\n}\n\nimpl TraitBounds {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            max_trait_bounds: conf.max_trait_bounds,\n            msrv: conf.msrv,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for TraitBounds {\n    fn check_generics(&mut self, cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) {\n        self.check_type_repetition(cx, generics);\n        check_trait_bound_duplication(cx, generics);\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        // special handling for self trait bounds as these are not considered generics\n        // i.e. trait Foo: Display {}\n        if let Item {\n            kind: ItemKind::Trait(_, _, _, _, _, bounds, ..),\n            ..\n        } = item\n        {\n            rollup_traits(cx, bounds, \"these bounds contain repeated elements\");\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) {\n        let mut self_bounds_map = FxHashMap::default();\n\n        for predicate in item.generics.predicates {\n            if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind\n                && bound_predicate.origin != PredicateOrigin::ImplTrait\n                && !predicate.span.from_expansion()\n                && let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind\n                && let Some(PathSegment {\n                    res: Res::SelfTyParam { trait_: def_id },\n                    ..\n                }) = segments.first()\n                && let Some(Node::Item(Item {\n                    kind: ItemKind::Trait(_, _, _, _, _, self_bounds, _),\n                    ..\n                })) = cx.tcx.hir_get_if_local(*def_id)\n            {\n                if self_bounds_map.is_empty() {\n                    for bound in *self_bounds {\n                        let Some((self_res, self_segments, _)) = get_trait_info_from_bound(bound) else {\n                            continue;\n                        };\n                        self_bounds_map.insert(self_res, self_segments);\n                    }\n                }\n\n                bound_predicate\n                    .bounds\n                    .iter()\n                    .filter_map(get_trait_info_from_bound)\n                    .for_each(|(trait_item_res, trait_item_segments, span)| {\n                        if let Some(self_segments) = self_bounds_map.get(&trait_item_res)\n                            && SpanlessEq::new(cx)\n                                .paths_by_resolution()\n                                .eq_path_segments(self_segments, trait_item_segments)\n                        {\n                            span_lint_and_help(\n                                cx,\n                                TRAIT_DUPLICATION_IN_BOUNDS,\n                                span,\n                                \"this trait bound is already specified in trait declaration\",\n                                None,\n                                \"consider removing this trait bound\",\n                            );\n                        }\n                    });\n            }\n        }\n    }\n\n    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx, AmbigArg>) {\n        if let TyKind::Ref(.., mut_ty) = &ty.kind\n            && let TyKind::TraitObject(bounds, ..) = mut_ty.ty.kind\n            && bounds.len() > 2\n        {\n            // Build up a hash of every trait we've seen\n            // When we see a trait for the first time, add it to unique_traits\n            // so we can later use it to build a string of all traits exactly once, without duplicates\n\n            let mut seen_def_ids = FxHashSet::default();\n            let mut unique_traits = Vec::new();\n\n            // Iterate the bounds and add them to our seen hash\n            // If we haven't yet seen it, add it to the fixed traits\n            for bound in bounds {\n                let Some(def_id) = bound.trait_ref.trait_def_id() else {\n                    continue;\n                };\n\n                let new_trait = seen_def_ids.insert(def_id);\n\n                if new_trait {\n                    unique_traits.push(bound);\n                }\n            }\n\n            // If the number of unique traits isn't the same as the number of traits in the bounds,\n            // there must be 1 or more duplicates\n            if bounds.len() != unique_traits.len() {\n                let mut bounds_span = bounds[0].span;\n\n                for bound in bounds.iter().skip(1) {\n                    bounds_span = bounds_span.to(bound.span);\n                }\n\n                let fixed_trait_snippet = unique_traits\n                    .iter()\n                    .filter_map(|b| b.span.get_source_text(cx))\n                    .join(\" + \");\n\n                span_lint_and_sugg(\n                    cx,\n                    TRAIT_DUPLICATION_IN_BOUNDS,\n                    bounds_span,\n                    \"this trait bound is already specified in trait declaration\",\n                    \"try\",\n                    fixed_trait_snippet,\n                    Applicability::MaybeIncorrect,\n                );\n            }\n        }\n    }\n}\n\nimpl TraitBounds {\n    /// Is the given bound a `?Sized` bound, and is combining it (i.e. `T: X + ?Sized`) an error on\n    /// this MSRV? See <https://github.com/rust-lang/rust-clippy/issues/8772> for details.\n    fn cannot_combine_maybe_bound(&self, cx: &LateContext<'_>, bound: &GenericBound<'_>) -> bool {\n        if let GenericBound::Trait(tr) = bound\n            && let BoundPolarity::Maybe(_) = tr.modifiers.polarity\n            && !self.msrv.meets(cx, msrvs::MAYBE_BOUND_IN_WHERE)\n        {\n            cx.tcx.lang_items().get(LangItem::Sized) == tr.trait_ref.path.res.opt_def_id()\n        } else {\n            false\n        }\n    }\n\n    #[expect(clippy::mutable_key_type)]\n    fn check_type_repetition<'tcx>(&self, cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) {\n        struct SpanlessTy<'cx, 'tcx> {\n            ty: &'tcx Ty<'tcx>,\n            cx: &'cx LateContext<'tcx>,\n        }\n        impl PartialEq for SpanlessTy<'_, '_> {\n            fn eq(&self, other: &Self) -> bool {\n                let mut eq = SpanlessEq::new(self.cx);\n                eq.inter_expr().eq_ty(self.ty, other.ty)\n            }\n        }\n        impl Hash for SpanlessTy<'_, '_> {\n            fn hash<H: Hasher>(&self, h: &mut H) {\n                let mut t = SpanlessHash::new(self.cx);\n                t.hash_ty(self.ty);\n                h.write_u64(t.finish());\n            }\n        }\n        impl Eq for SpanlessTy<'_, '_> {}\n\n        if generics.span.from_expansion() {\n            return;\n        }\n        let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();\n        let mut applicability = Applicability::MaybeIncorrect;\n        for bound in generics.predicates {\n            if let WherePredicateKind::BoundPredicate(p) = bound.kind\n                && p.origin != PredicateOrigin::ImplTrait\n                && p.bounds.len() as u64 <= self.max_trait_bounds\n                && !bound.span.from_expansion()\n                && let bounds = p\n                    .bounds\n                    .iter()\n                    .filter(|b| !self.cannot_combine_maybe_bound(cx, b))\n                    .collect::<Vec<_>>()\n                && !bounds.is_empty()\n                && let Some(ref v) = map.insert(SpanlessTy { ty: p.bounded_ty, cx }, bounds)\n                && !is_from_proc_macro(cx, p.bounded_ty)\n            {\n                let trait_bounds = v\n                    .iter()\n                    .copied()\n                    .chain(p.bounds.iter())\n                    .map(|bound| snippet_with_applicability(cx, bound.span(), \"_\", &mut applicability))\n                    .join(\" + \");\n                let hint_string = format!(\n                    \"consider combining the bounds: `{}: {trait_bounds}`\",\n                    snippet(cx, p.bounded_ty.span, \"_\"),\n                );\n                let ty_name = snippet(cx, p.bounded_ty.span, \"_\");\n                span_lint_and_help(\n                    cx,\n                    TYPE_REPETITION_IN_BOUNDS,\n                    bound.span,\n                    format!(\"type `{ty_name}` has already been used as a bound predicate\"),\n                    None,\n                    hint_string,\n                );\n            }\n        }\n    }\n}\n\nfn check_trait_bound_duplication<'tcx>(cx: &LateContext<'tcx>, generics: &'_ Generics<'tcx>) {\n    if generics.span.from_expansion() {\n        return;\n    }\n\n    // Explanation:\n    // fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)\n    // where T: Clone + Default, { unimplemented!(); }\n    //       ^^^^^^^^^^^^^^^^^^\n    //       |\n    // collects each of these where clauses into a set keyed by generic name and comparable trait\n    // eg. (T, Clone)\n    #[expect(clippy::mutable_key_type)]\n    let where_predicates = generics\n        .predicates\n        .iter()\n        .filter_map(|pred| {\n            if pred.kind.in_where_clause()\n                && let WherePredicateKind::BoundPredicate(bound_predicate) = pred.kind\n                && let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind\n            {\n                return Some(\n                    rollup_traits(\n                        cx,\n                        bound_predicate.bounds,\n                        \"these where clauses contain repeated elements\",\n                    )\n                    .into_iter()\n                    .map(|(trait_ref, _)| (path.res, trait_ref)),\n                );\n            }\n            None\n        })\n        .flatten()\n        .collect::<FxHashSet<_>>();\n\n    // Explanation:\n    // fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) ...\n    //            ^^^^^^^^^^^^^^^^^^  ^^^^^^^\n    //            |\n    // compare trait bounds keyed by generic name and comparable trait to collected where\n    // predicates eg. (T, Clone)\n    for predicate in generics.predicates.iter().filter(|pred| !pred.kind.in_where_clause()) {\n        if let WherePredicateKind::BoundPredicate(bound_predicate) = predicate.kind\n            && bound_predicate.origin != PredicateOrigin::ImplTrait\n            && !predicate.span.from_expansion()\n            && let TyKind::Path(QPath::Resolved(_, path)) = bound_predicate.bounded_ty.kind\n        {\n            let traits = rollup_traits(cx, bound_predicate.bounds, \"these bounds contain repeated elements\");\n            for (trait_ref, span) in traits {\n                let key = (path.res, trait_ref);\n                if where_predicates.contains(&key) {\n                    span_lint_and_help(\n                        cx,\n                        TRAIT_DUPLICATION_IN_BOUNDS,\n                        span,\n                        \"this trait bound is already specified in the where clause\",\n                        None,\n                        \"consider removing this trait bound\",\n                    );\n                }\n            }\n        }\n    }\n}\n\nstruct ComparableTraitRef<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    trait_ref: &'tcx TraitRef<'tcx>,\n    modifiers: TraitBoundModifiers,\n}\n\nimpl PartialEq for ComparableTraitRef<'_, '_> {\n    fn eq(&self, other: &Self) -> bool {\n        SpanlessEq::eq_modifiers(self.modifiers, other.modifiers)\n            && SpanlessEq::new(self.cx)\n                .paths_by_resolution()\n                .eq_path(self.trait_ref.path, other.trait_ref.path)\n    }\n}\nimpl Eq for ComparableTraitRef<'_, '_> {}\nimpl Hash for ComparableTraitRef<'_, '_> {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        let mut s = SpanlessHash::new(self.cx).paths_by_resolution();\n        s.hash_path(self.trait_ref.path);\n        s.hash_modifiers(self.modifiers);\n        state.write_u64(s.finish());\n    }\n}\n\nfn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'a [PathSegment<'a>], Span)> {\n    if let GenericBound::Trait(t) = bound {\n        let trait_path = t.trait_ref.path;\n        Some((trait_path.res, trait_path.segments, t.span))\n    } else {\n        None\n    }\n}\n\nfn rollup_traits<'cx, 'tcx>(\n    cx: &'cx LateContext<'tcx>,\n    bounds: &'tcx [GenericBound<'tcx>],\n    msg: &'static str,\n) -> Vec<(ComparableTraitRef<'cx, 'tcx>, Span)> {\n    // Source order is needed for joining spans\n    let mut map = FxIndexMap::default();\n    let mut repeated_res = false;\n\n    let only_comparable_trait_refs = |bound: &'tcx GenericBound<'tcx>| {\n        if let GenericBound::Trait(t) = bound {\n            Some((\n                ComparableTraitRef {\n                    cx,\n                    trait_ref: &t.trait_ref,\n                    modifiers: t.modifiers,\n                },\n                t.span,\n            ))\n        } else {\n            None\n        }\n    };\n\n    for bound in bounds.iter().filter_map(only_comparable_trait_refs) {\n        let (comparable_bound, span_direct) = bound;\n        match map.entry(comparable_bound) {\n            IndexEntry::Occupied(_) => repeated_res = true,\n            IndexEntry::Vacant(e) => {\n                e.insert(span_direct);\n            },\n        }\n    }\n\n    let comparable_bounds: Vec<_> = map.into_iter().collect();\n\n    if repeated_res && let [first_trait, .., last_trait] = bounds {\n        let all_trait_span = first_trait.span().to(last_trait.span());\n\n        let traits = comparable_bounds\n            .iter()\n            .filter_map(|&(_, span)| span.get_source_text(cx))\n            .join(\" + \");\n\n        span_lint_and_sugg(\n            cx,\n            TRAIT_DUPLICATION_IN_BOUNDS,\n            all_trait_span,\n            msg,\n            \"try\",\n            traits,\n            Applicability::MachineApplicable,\n        );\n    }\n\n    comparable_bounds\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/crosspointer_transmute.rs",
    "content": "use super::CROSSPOINTER_TRANSMUTE;\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\n/// Checks for `crosspointer_transmute` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {\n    match (*from_ty.kind(), *to_ty.kind()) {\n        (ty::RawPtr(from_ptr_ty, _), _) if from_ptr_ty == to_ty => {\n            span_lint(\n                cx,\n                CROSSPOINTER_TRANSMUTE,\n                e.span,\n                format!(\"transmute from a type (`{from_ty}`) to the type that it points to (`{to_ty}`)\"),\n            );\n            true\n        },\n        (_, ty::RawPtr(to_ptr_ty, _)) if to_ptr_ty == from_ty => {\n            span_lint(\n                cx,\n                CROSSPOINTER_TRANSMUTE,\n                e.span,\n                format!(\"transmute from a type (`{from_ty}`) to a pointer to that type (`{to_ty}`)\"),\n            );\n            true\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/eager_transmute.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::{eq_expr_value, path_to_local_with_projections, sym};\nuse rustc_abi::WrappingRange;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, Node};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\nuse super::EAGER_TRANSMUTE;\n\nfn peel_parent_unsafe_blocks<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    for (_, parent) in cx.tcx.hir_parent_iter(expr.hir_id) {\n        match parent {\n            Node::Block(_) => {},\n            Node::Expr(e) if let ExprKind::Block(..) = e.kind => {},\n            Node::Expr(e) => return Some(e),\n            _ => break,\n        }\n    }\n    None\n}\n\nfn range_fully_contained(from: WrappingRange, to: WrappingRange) -> bool {\n    to.contains(from.start) && to.contains(from.end)\n}\n\n/// Checks if a given expression is a binary operation involving a local variable or is made up of\n/// other (nested) binary expressions involving the local. There must be at least one local\n/// reference that is the same as `local_expr`.\n///\n/// This is used as a heuristic to detect if a variable\n/// is checked to be within the valid range of a transmuted type.\n/// All of these would return true:\n/// * `x < 4`\n/// * `x < 4 && x > 1`\n/// * `x.field < 4 && x.field > 1` (given `x.field`)\n/// * `x.field < 4 && unrelated()`\n/// * `(1..=3).contains(&x)`\nfn binops_with_local(cx: &LateContext<'_>, local_expr: &Expr<'_>, expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Binary(_, lhs, rhs) => {\n            binops_with_local(cx, local_expr, lhs) || binops_with_local(cx, local_expr, rhs)\n        },\n        ExprKind::MethodCall(path, receiver, [arg], _)\n            if path.ident.name == sym::contains\n                // ... `contains` called on some kind of range\n                && let Some(receiver_adt) = cx.typeck_results().expr_ty(receiver).peel_refs().ty_adt_def()\n                && let lang_items = cx.tcx.lang_items()\n                && [\n                    lang_items.range_from_struct(),\n                    lang_items.range_inclusive_struct(),\n                    lang_items.range_struct(),\n                    lang_items.range_to_inclusive_struct(),\n                    lang_items.range_to_struct()\n                ].into_iter().any(|did| did == Some(receiver_adt.did())) =>\n        {\n            eq_expr_value(cx, local_expr, arg.peel_borrows())\n        },\n        _ => eq_expr_value(cx, local_expr, expr),\n    }\n}\n\n/// Checks if an expression is a path to a local variable (with optional projections), e.g.\n/// `x.field[0].field2` would return true.\nfn is_local_with_projections(expr: &Expr<'_>) -> bool {\n    path_to_local_with_projections(expr).is_some()\n}\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    transmutable: &'tcx Expr<'tcx>,\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n) -> bool {\n    if let Some(then_some_call) = peel_parent_unsafe_blocks(cx, expr)\n        && let ExprKind::MethodCall(path, receiver, [arg], _) = then_some_call.kind\n        && cx.typeck_results().expr_ty(receiver).is_bool()\n        && path.ident.name == sym::then_some\n        && is_local_with_projections(transmutable)\n        && binops_with_local(cx, transmutable, receiver)\n        // we only want to lint if the target type has a niche that is larger than the one of the source type\n        // e.g. `u8` to `NonZero<u8>` should lint, but `NonZero<u8>` to `u8` should not\n        && let Ok(from_layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(from_ty))\n        && let Ok(to_layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(to_ty))\n        && match (from_layout.largest_niche, to_layout.largest_niche) {\n            (Some(from_niche), Some(to_niche)) => !range_fully_contained(from_niche.valid_range, to_niche.valid_range),\n            (None, Some(_)) => true,\n            (_, None) => false,\n        }\n    {\n        span_lint_and_then(\n            cx,\n            EAGER_TRANSMUTE,\n            expr.span,\n            \"this transmute is always evaluated eagerly, even if the condition is false\",\n            |diag| {\n                diag.multipart_suggestion(\n                    \"consider using `bool::then` to only transmute if the condition holds\",\n                    vec![\n                        (path.ident.span, \"then\".into()),\n                        (arg.span.shrink_to_lo(), \"|| \".into()),\n                    ],\n                    Applicability::MaybeIncorrect,\n                );\n            },\n        );\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/missing_transmute_annotations.rs",
    "content": "use std::borrow::Cow;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{HasSession, SpanRangeExt as _};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, GenericArg, HirId, LetStmt, Node, Path, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::Span;\n\nuse crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;\n\nfn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) -> Option<LetStmt<'tcx>> {\n    let mut parent_iter = cx.tcx.hir_parent_iter(expr_hir_id);\n    if let Some((_, node)) = parent_iter.next() {\n        match node {\n            Node::LetStmt(local) => Some(*local),\n            Node::Block(_) => {\n                if let Some((parent_hir_id, Node::Expr(expr))) = parent_iter.next()\n                    && matches!(expr.kind, rustc_hir::ExprKind::Block(_, _))\n                {\n                    get_parent_local_binding_ty(cx, parent_hir_id)\n                } else {\n                    None\n                }\n            },\n            _ => None,\n        }\n    } else {\n        None\n    }\n}\n\nfn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool {\n    let def_id = cx.tcx.hir_enclosing_body_owner(expr_hir_id);\n    if let Some(body) = cx.tcx.hir_maybe_body_owned_by(def_id) {\n        return body.value.peel_blocks().hir_id == expr_hir_id;\n    }\n    false\n}\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    path: &Path<'tcx>,\n    arg: &Expr<'tcx>,\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n    expr_hir_id: HirId,\n) -> bool {\n    let last = path.segments.last().unwrap();\n    if last.ident.span.in_external_macro(cx.tcx.sess.source_map()) {\n        // If it comes from a non-local macro, we ignore it.\n        return false;\n    }\n    let args = last.args;\n    let missing_generic = match args {\n        Some(args) if !args.args.is_empty() => args.args.iter().any(|arg| matches!(arg, GenericArg::Infer(_))),\n        _ => true,\n    };\n    if !missing_generic {\n        return false;\n    }\n    // If it's being set as a local variable value...\n    if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id) {\n        // ... which does have type annotations.\n        if let Some(ty) = local.ty\n            // If this is a `let x: _ =`, we should lint.\n            && !matches!(ty.kind, TyKind::Infer(()))\n        {\n            return false;\n        }\n    // We check if this transmute is not the only element in the function\n    } else if is_function_block(cx, expr_hir_id) {\n        return false;\n    }\n    let span = last.ident.span.with_hi(path.span.hi());\n    span_lint_and_then(\n        cx,\n        MISSING_TRANSMUTE_ANNOTATIONS,\n        span,\n        \"transmute used without annotations\",\n        |diag| {\n            let from_ty_no_name = ty_cannot_be_named(from_ty);\n            let to_ty_no_name = ty_cannot_be_named(to_ty);\n            if from_ty_no_name || to_ty_no_name {\n                let to_name = match (from_ty_no_name, to_ty_no_name) {\n                    (true, false) => maybe_name_by_expr(cx, arg.span, \"the origin type\"),\n                    (false, true) => \"the destination type\".into(),\n                    _ => \"the source and destination types\".into(),\n                };\n                diag.help(format!(\n                    \"consider giving {to_name} a name, and adding missing type annotations\"\n                ));\n            } else {\n                diag.span_suggestion(\n                    span,\n                    \"consider adding missing annotations\",\n                    format!(\"{}::<{from_ty}, {to_ty}>\", last.ident),\n                    Applicability::MaybeIncorrect,\n                );\n            }\n        },\n    );\n    true\n}\n\nfn ty_cannot_be_named(ty: Ty<'_>) -> bool {\n    matches!(\n        ty.kind(),\n        ty::Alias(ty::AliasTyKind::Opaque | ty::AliasTyKind::Inherent, _)\n    )\n}\n\nfn maybe_name_by_expr<'a>(sess: &impl HasSession, span: Span, default: &'a str) -> Cow<'a, str> {\n    span.with_source_text(sess, |name| {\n        (name.len() + 9 < default.len()).then_some(format!(\"`{name}`'s type\").into())\n    })\n    .flatten()\n    .unwrap_or(default.into())\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/mod.rs",
    "content": "mod crosspointer_transmute;\nmod eager_transmute;\nmod missing_transmute_annotations;\nmod transmute_int_to_bool;\nmod transmute_int_to_non_zero;\nmod transmute_null_to_fn;\nmod transmute_ptr_to_ptr;\nmod transmute_ptr_to_ref;\nmod transmute_ref_to_ref;\nmod transmute_undefined_repr;\nmod transmutes_expressible_as_ptr_casts;\nmod transmuting_null;\nmod unsound_collection_transmute;\nmod useless_transmute;\nmod utils;\nmod wrong_transmute;\n\nuse clippy_config::Conf;\nuse clippy_utils::is_in_const_context;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::sugg::Sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes between a type `T` and `*T`.\n    ///\n    /// ### Why is this bad?\n    /// It's easy to mistakenly transmute between a type and a\n    /// pointer to that type.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// core::intrinsics::transmute(t) // where the result type is the same as\n    ///                                // `*t` or `&t`'s\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub CROSSPOINTER_TRANSMUTE,\n    suspicious,\n    \"transmutes that have to or from types that are a pointer to the other\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for integer validity checks, followed by a transmute that is (incorrectly) evaluated\n    /// eagerly (e.g. using `bool::then_some`).\n    ///\n    /// ### Why is this bad?\n    /// Eager evaluation means that the `transmute` call is executed regardless of whether the condition is true or false.\n    /// This can introduce unsoundness and other subtle bugs.\n    ///\n    /// ### Example\n    /// Consider the following function which is meant to convert an unsigned integer to its enum equivalent via transmute.\n    ///\n    /// ```no_run\n    /// #[repr(u8)]\n    /// enum Opcode {\n    ///     Add = 0,\n    ///     Sub = 1,\n    ///     Mul = 2,\n    ///     Div = 3\n    /// }\n    ///\n    /// fn int_to_opcode(op: u8) -> Option<Opcode> {\n    ///     (op < 4).then_some(unsafe { std::mem::transmute(op) })\n    /// }\n    /// ```\n    /// This may appear fine at first given that it checks that the `u8` is within the validity range of the enum,\n    /// *however* the transmute is evaluated eagerly, meaning that it executes even if `op >= 4`!\n    ///\n    /// This makes the function unsound, because it is possible for the caller to cause undefined behavior\n    /// (creating an enum with an invalid bitpattern) entirely in safe code only by passing an incorrect value,\n    /// which is normally only a bug that is possible in unsafe code.\n    ///\n    /// One possible way in which this can go wrong practically is that the compiler sees it as:\n    /// ```rust,ignore (illustrative)\n    /// let temp: Foo = unsafe { std::mem::transmute(op) };\n    /// (0 < 4).then_some(temp)\n    /// ```\n    /// and optimizes away the `(0 < 4)` check based on the assumption that since a `Foo` was created from `op` with the validity range `0..3`,\n    /// it is **impossible** for this condition to be false.\n    ///\n    /// In short, it is possible for this function to be optimized in a way that makes it [never return `None`](https://godbolt.org/z/ocrcenevq),\n    /// even if passed the value `4`.\n    ///\n    /// This can be avoided by instead using lazy evaluation. For the example above, this should be written:\n    /// ```rust,ignore (illustrative)\n    /// fn int_to_opcode(op: u8) -> Option<Opcode> {\n    ///     (op < 4).then(|| unsafe { std::mem::transmute(op) })\n    ///              ^^^^ ^^ `bool::then` only executes the closure if the condition is true!\n    /// }\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub EAGER_TRANSMUTE,\n    correctness,\n    \"eager evaluation of `transmute`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks if transmute calls have all generics specified.\n    ///\n    /// ### Why is this bad?\n    /// If not, one or more unexpected types could be used during `transmute()`, potentially leading\n    /// to Undefined Behavior or other problems.\n    ///\n    /// This is particularly dangerous in case a seemingly innocent/unrelated change causes type\n    /// inference to result in a different type. For example, if `transmute()` is the tail\n    /// expression of an `if`-branch, and the `else`-branch type changes, the compiler may silently\n    /// infer a different type to be returned by `transmute()`. That is because the compiler is\n    /// free to change the inference of a type as long as that inference is technically correct,\n    /// regardless of the programmer's unknown expectation.\n    ///\n    /// Both type-parameters, the input- and the output-type, to any `transmute()` should\n    /// be given explicitly: Setting the input-type explicitly avoids confusion about what the\n    /// argument's type actually is. Setting the output-type explicitly avoids type-inference\n    /// to infer a technically correct yet unexpected type.\n    ///\n    /// ### Example\n    /// ```\n    /// # unsafe {\n    /// let mut x: i32 = 0;\n    /// // Avoid \"naked\" calls to `transmute()`!\n    /// x = std::mem::transmute([1u16, 2u16]);\n    ///\n    /// // `first_answers` is intended to transmute a slice of bool to a slice of u8.\n    /// // But the programmer forgot to index the first element of the outer slice,\n    /// // so we are actually transmuting from \"pointers to slices\" instead of\n    /// // transmuting from \"a slice of bool\", causing a nonsensical result.\n    /// let the_answers: &[&[bool]] = &[&[true, false, true]];\n    /// let first_answers: &[u8] = std::mem::transmute(the_answers);\n    /// # }\n    /// ```\n    /// Use instead:\n    /// ```\n    /// # unsafe {\n    /// let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n    ///\n    /// // The explicit type parameters on `transmute()` makes the intention clear,\n    /// // and cause a type-error if the actual types don't match our expectation.\n    /// let the_answers: &[&[bool]] = &[&[true, false, true]];\n    /// let first_answers: &[u8] = std::mem::transmute::<&[bool], &[u8]>(the_answers[0]);\n    /// # }\n    /// ```\n    #[clippy::version = \"1.79.0\"]\n    pub MISSING_TRANSMUTE_ANNOTATIONS,\n    suspicious,\n    \"warns if a transmute call doesn't have all generics specified\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes from a `&[u8]` to a `&str`.\n    ///\n    /// ### Why is this bad?\n    /// Not every byte slice is a valid UTF-8 string.\n    ///\n    /// ### Known problems\n    /// - [`from_utf8`] which this lint suggests using is slower than `transmute`\n    /// as it needs to validate the input.\n    /// If you are certain that the input is always a valid UTF-8,\n    /// use [`from_utf8_unchecked`] which is as fast as `transmute`\n    /// but has a semantically meaningful name.\n    /// - You might want to handle errors returned from [`from_utf8`] instead of calling `unwrap`.\n    ///\n    /// [`from_utf8`]: https://doc.rust-lang.org/std/str/fn.from_utf8.html\n    /// [`from_utf8_unchecked`]: https://doc.rust-lang.org/std/str/fn.from_utf8_unchecked.html\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let b: &[u8] = &[1_u8, 2_u8];\n    /// unsafe {\n    ///     let _: &str = std::mem::transmute(b); // where b: &[u8]\n    /// }\n    ///\n    /// // should be:\n    /// let _ = std::str::from_utf8(b).unwrap();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TRANSMUTE_BYTES_TO_STR,\n    complexity,\n    \"transmutes from a `&[u8]` to a `&str`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes from an integer to a `bool`.\n    ///\n    /// ### Why is this bad?\n    /// This might result in an invalid in-memory representation of a `bool`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 1_u8;\n    /// unsafe {\n    ///     let _: bool = std::mem::transmute(x); // where x: u8\n    /// }\n    ///\n    /// // should be:\n    /// let _: bool = x != 0;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TRANSMUTE_INT_TO_BOOL,\n    complexity,\n    \"transmutes from an integer to a `bool`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes from `T` to `NonZero<T>`, and suggests the `new_unchecked`\n    /// method instead.\n    ///\n    /// ### Why is this bad?\n    /// Transmutes work on any types and thus might cause unsoundness when those types change\n    /// elsewhere. `new_unchecked` only works for the appropriate types instead.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use core::num::NonZero;\n    /// let _: NonZero<u32> = unsafe { std::mem::transmute(123) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use core::num::NonZero;\n    /// let _: NonZero<u32> = unsafe { NonZero::new_unchecked(123) };\n    /// ```\n    #[clippy::version = \"1.69.0\"]\n    pub TRANSMUTE_INT_TO_NON_ZERO,\n    complexity,\n    \"transmutes from an integer to a non-zero wrapper\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for null function pointer creation through transmute.\n    ///\n    /// ### Why is this bad?\n    /// Creating a null function pointer is undefined behavior.\n    ///\n    /// More info: https://doc.rust-lang.org/nomicon/ffi.html#the-nullable-pointer-optimization\n    ///\n    /// ### Known problems\n    /// Not all cases can be detected at the moment of this writing.\n    /// For example, variables which hold a null pointer and are then fed to a `transmute`\n    /// call, aren't detectable yet.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let null_fn: fn() = unsafe { std::mem::transmute( std::ptr::null::<()>() ) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let null_fn: Option<fn()> = None;\n    /// ```\n    #[clippy::version = \"1.68.0\"]\n    pub TRANSMUTE_NULL_TO_FN,\n    correctness,\n    \"transmute results in a null function pointer, which is undefined behavior\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes from a pointer to a pointer, or\n    /// from a reference to a reference.\n    ///\n    /// ### Why is this bad?\n    /// Transmutes are dangerous, and these can instead be\n    /// written as casts.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let ptr = &1u32 as *const u32;\n    /// unsafe {\n    ///     // pointer-to-pointer transmute\n    ///     let _: *const f32 = std::mem::transmute(ptr);\n    ///     // ref-ref transmute\n    ///     let _: &f32 = std::mem::transmute(&1u32);\n    /// }\n    /// // These can be respectively written:\n    /// let _ = ptr as *const f32;\n    /// let _ = unsafe{ &*(&1u32 as *const u32 as *const f32) };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TRANSMUTE_PTR_TO_PTR,\n    pedantic,\n    \"transmutes from a pointer to a pointer / a reference to a reference\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes from a pointer to a reference.\n    ///\n    /// ### Why is this bad?\n    /// This can always be rewritten with `&` and `*`.\n    ///\n    /// ### Known problems\n    /// - `mem::transmute` in statics and constants is stable from Rust 1.46.0,\n    /// while dereferencing raw pointer is not stable yet.\n    /// If you need to do this in those places,\n    /// you would have to use `transmute` instead.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// unsafe {\n    ///     let _: &T = std::mem::transmute(p); // where p: *const T\n    /// }\n    ///\n    /// // can be written:\n    /// let _: &T = &*p;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TRANSMUTE_PTR_TO_REF,\n    complexity,\n    \"transmutes from a pointer to a reference type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes between types which do not have a representation defined relative to\n    /// each other.\n    ///\n    /// ### Why is this bad?\n    /// The results of such a transmute are not defined.\n    ///\n    /// ### Known problems\n    /// This lint has had multiple problems in the past and was moved to `nursery`. See issue\n    /// [#8496](https://github.com/rust-lang/rust-clippy/issues/8496) for more details.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo<T>(u32, T);\n    /// let _ = unsafe { core::mem::transmute::<Foo<u32>, Foo<i32>>(Foo(0u32, 0u32)) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// #[repr(C)]\n    /// struct Foo<T>(u32, T);\n    /// let _ = unsafe { core::mem::transmute::<Foo<u32>, Foo<i32>>(Foo(0u32, 0u32)) };\n    /// ```\n    #[clippy::version = \"1.60.0\"]\n    pub TRANSMUTE_UNDEFINED_REPR,\n    nursery,\n    \"transmute to or from a type with an undefined representation\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///Checks for transmutes that could be a pointer cast.\n    ///\n    /// ### Why is this bad?\n    /// Readability. The code tricks people into thinking that\n    /// something complex is going on.\n    ///\n    /// ### Example\n    ///\n    /// ```no_run\n    /// # let p: *const [i32] = &[];\n    /// unsafe { std::mem::transmute::<*const [i32], *const [u16]>(p) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let p: *const [i32] = &[];\n    /// p as *const [u16];\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,\n    complexity,\n    \"transmutes that could be a pointer cast\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmute calls which would receive a null pointer.\n    ///\n    /// ### Why is this bad?\n    /// Transmuting a null pointer is undefined behavior.\n    ///\n    /// ### Known problems\n    /// Not all cases can be detected at the moment of this writing.\n    /// For example, variables which hold a null pointer and are then fed to a `transmute`\n    /// call, aren't detectable yet.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let null_ref: &u64 = unsafe { std::mem::transmute(0 as *const u64) };\n    /// ```\n    #[clippy::version = \"1.35.0\"]\n    pub TRANSMUTING_NULL,\n    correctness,\n    \"transmutes from a null pointer to a reference, which is undefined behavior\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes between collections whose\n    /// types have different ABI, size or alignment.\n    ///\n    /// ### Why is this bad?\n    /// This is undefined behavior.\n    ///\n    /// ### Known problems\n    /// Currently, we cannot know whether a type is a\n    /// collection, so we just lint the ones that come with `std`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // different size, therefore likely out-of-bounds memory access\n    /// // You absolutely do not want this in your code!\n    /// unsafe {\n    ///     std::mem::transmute::<_, Vec<u32>>(vec![2_u16])\n    /// };\n    /// ```\n    ///\n    /// You must always iterate, map and collect the values:\n    ///\n    /// ```no_run\n    /// vec![2_u16].into_iter().map(u32::from).collect::<Vec<_>>();\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub UNSOUND_COLLECTION_TRANSMUTE,\n    correctness,\n    \"transmute between collections of layout-incompatible types\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes to the original type of the object\n    /// and transmutes that could be a cast.\n    ///\n    /// ### Why is this bad?\n    /// Readability. The code tricks people into thinking that\n    /// something complex is going on.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// core::intrinsics::transmute(t); // where the result type is the same as `t`'s\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USELESS_TRANSMUTE,\n    complexity,\n    \"transmutes that have the same to and from types or could be a cast/coercion\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for transmutes that can't ever be correct on any\n    /// architecture.\n    ///\n    /// ### Why is this bad?\n    /// It's basically guaranteed to be undefined behavior.\n    ///\n    /// ### Known problems\n    /// When accessing C, users might want to store pointer\n    /// sized objects in `extradata` arguments to save an allocation.\n    ///\n    /// ### Example\n    /// ```ignore\n    /// let ptr: *const T = core::intrinsics::transmute('x')\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub WRONG_TRANSMUTE,\n    correctness,\n    \"transmutes that are confusing at best, undefined behavior at worst and always useless\"\n}\n\nimpl_lint_pass!(Transmute => [\n    CROSSPOINTER_TRANSMUTE,\n    EAGER_TRANSMUTE,\n    MISSING_TRANSMUTE_ANNOTATIONS,\n    TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,\n    TRANSMUTE_BYTES_TO_STR,\n    TRANSMUTE_INT_TO_BOOL,\n    TRANSMUTE_INT_TO_NON_ZERO,\n    TRANSMUTE_NULL_TO_FN,\n    TRANSMUTE_PTR_TO_PTR,\n    TRANSMUTE_PTR_TO_REF,\n    TRANSMUTE_UNDEFINED_REPR,\n    TRANSMUTING_NULL,\n    UNSOUND_COLLECTION_TRANSMUTE,\n    USELESS_TRANSMUTE,\n    WRONG_TRANSMUTE,\n]);\n\n// FIXME: Merge this lint with USELESS_TRANSMUTE once that is out of the nursery.\n\npub struct Transmute {\n    msrv: Msrv,\n}\nimpl Transmute {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n\n    /// When transmuting, a struct containing a single field works like the field.\n    /// This function extracts the field type and the expression to get the field.\n    fn extract_struct_field<'tcx>(\n        cx: &LateContext<'tcx>,\n        e: &'tcx Expr<'_>,\n        outer_type: Ty<'tcx>,\n        outer: &'tcx Expr<'tcx>,\n    ) -> (Ty<'tcx>, Sugg<'tcx>) {\n        let mut applicability = Applicability::MachineApplicable;\n        let outer_sugg = Sugg::hir_with_context(cx, outer, e.span.ctxt(), \"..\", &mut applicability);\n        if let ty::Adt(struct_def, struct_args) = *outer_type.kind()\n            && struct_def.is_struct()\n            && let mut fields = struct_def.all_fields()\n            && let Some(first) = fields.next()\n            && fields.next().is_none()\n            && first.vis.is_accessible_from(cx.tcx.parent_module(outer.hir_id), cx.tcx)\n        {\n            (\n                first.ty(cx.tcx, struct_args),\n                Sugg::NonParen(format!(\"{}.{}\", outer_sugg.maybe_paren(), first.name).into()),\n            )\n        } else {\n            (outer_type, outer_sugg)\n        }\n    }\n}\nimpl<'tcx> LateLintPass<'tcx> for Transmute {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if let ExprKind::Call(path_expr, [arg]) = e.kind\n            && let ExprKind::Path(QPath::Resolved(None, path)) = path_expr.kind\n            && let Some(def_id) = path.res.opt_def_id()\n            && cx.tcx.is_diagnostic_item(sym::transmute, def_id)\n        {\n            // Avoid suggesting non-const operations in const contexts:\n            // - from/to bits (https://github.com/rust-lang/rust/issues/73736)\n            // - dereferencing raw pointers (https://github.com/rust-lang/rust/issues/51911)\n            // - char conversions (https://github.com/rust-lang/rust/issues/89259)\n            let const_context = is_in_const_context(cx);\n\n            let (from_ty, from_ty_adjusted) = match cx.typeck_results().expr_adjustments(arg) {\n                [] => (cx.typeck_results().expr_ty(arg), false),\n                [.., a] => (a.target, true),\n            };\n            // Adjustments for `to_ty` happen after the call to `transmute`, so don't use them.\n            let to_ty = cx.typeck_results().expr_ty(e);\n\n            // If useless_transmute is triggered, the other lints can be skipped.\n            if useless_transmute::check(cx, e, from_ty, to_ty, arg) {\n                return;\n            }\n\n            // A struct having a single pointer can be treated like a pointer.\n            let (from_field_ty, from_field_expr) = Self::extract_struct_field(cx, e, from_ty, arg);\n\n            let linted = wrong_transmute::check(cx, e, from_ty, to_ty)\n                | crosspointer_transmute::check(cx, e, from_ty, to_ty)\n                | transmuting_null::check(cx, e, arg, to_ty)\n                | transmute_null_to_fn::check(cx, e, arg, to_ty)\n                | transmute_ptr_to_ref::check(cx, e, from_field_ty, to_ty, from_field_expr.clone(), path, self.msrv)\n                | missing_transmute_annotations::check(cx, path, arg, from_ty, to_ty, e.hir_id)\n                | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)\n                | transmute_ptr_to_ptr::check(cx, e, from_field_ty, to_ty, from_field_expr, self.msrv)\n                | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)\n                | transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg)\n                | (unsound_collection_transmute::check(cx, e, from_ty, to_ty)\n                    || transmute_undefined_repr::check(cx, e, from_ty, to_ty))\n                | (eager_transmute::check(cx, e, arg, from_ty, to_ty));\n\n            if !linted {\n                transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, from_ty_adjusted, to_ty, arg, const_context);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmute_int_to_bool.rs",
    "content": "use super::TRANSMUTE_INT_TO_BOOL;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::sugg;\nuse rustc_ast as ast;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse std::borrow::Cow;\n\n/// Checks for `transmute_int_to_bool` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n    arg: &'tcx Expr<'_>,\n) -> bool {\n    match (&from_ty.kind(), &to_ty.kind()) {\n        (ty::Int(ty::IntTy::I8) | ty::Uint(ty::UintTy::U8), ty::Bool) => {\n            span_lint_and_then(\n                cx,\n                TRANSMUTE_INT_TO_BOOL,\n                e.span,\n                format!(\"transmute from a `{from_ty}` to a `bool`\"),\n                |diag| {\n                    let arg = sugg::Sugg::hir(cx, arg, \"..\");\n                    let zero = sugg::Sugg::NonParen(Cow::from(\"0\"));\n                    diag.span_suggestion(\n                        e.span,\n                        \"consider using\",\n                        sugg::make_binop(ast::BinOpKind::Ne, &arg, &zero).to_string(),\n                        Applicability::Unspecified,\n                    );\n                },\n            );\n            true\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmute_int_to_non_zero.rs",
    "content": "use super::TRANSMUTE_INT_TO_NON_ZERO;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::Sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\nuse rustc_span::symbol::sym;\n\n/// Checks for `transmute_int_to_non_zero` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n    arg: &'tcx Expr<'_>,\n) -> bool {\n    if let ty::Int(_) | ty::Uint(_) = from_ty.kind()\n        && let ty::Adt(adt, substs) = to_ty.kind()\n        && cx.tcx.is_diagnostic_item(sym::NonZero, adt.did())\n        && let int_ty = substs.type_at(0)\n        && from_ty == int_ty\n    {\n        let arg = Sugg::hir(cx, arg, \"..\");\n        span_lint_and_sugg(\n            cx,\n            TRANSMUTE_INT_TO_NON_ZERO,\n            e.span,\n            format!(\"transmute from a `{from_ty}` to a `{}<{int_ty}>`\", sym::NonZero),\n            \"consider using\",\n            format!(\"{}::{}({arg})\", sym::NonZero, sym::new_unchecked),\n            Applicability::Unspecified,\n        );\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmute_null_to_fn.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_integer_literal;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_span::symbol::sym;\n\nuse super::TRANSMUTE_NULL_TO_FN;\n\nfn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    span_lint_and_then(\n        cx,\n        TRANSMUTE_NULL_TO_FN,\n        expr.span,\n        \"transmuting a known null pointer into a function pointer\",\n        |diag| {\n            diag.span_label(expr.span, \"this transmute results in undefined behavior\");\n            diag.help(\n               \"try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value\"\n            );\n        },\n    );\n}\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>, to_ty: Ty<'tcx>) -> bool {\n    if !to_ty.is_fn() {\n        return false;\n    }\n\n    let casts_peeled = peel_casts(arg);\n    match casts_peeled.kind {\n        // Catching:\n        // transmute over constants that resolve to `null`.\n        ExprKind::Path(ref _qpath)\n            if matches!(ConstEvalCtxt::new(cx).eval(casts_peeled), Some(Constant::RawPtr(0))) =>\n        {\n            lint_expr(cx, expr);\n            true\n        },\n        // Catching:\n        // `std::mem::transmute(std::ptr::null::<i32>())`\n        ExprKind::Call(func1, []) if func1.basic_res().is_diag_item(cx, sym::ptr_null) => {\n            lint_expr(cx, expr);\n            true\n        },\n        _ => {\n            // FIXME:\n            // Also catch transmutations of variables which are known nulls.\n            // To do this, MIR const propagation seems to be the better tool.\n            // Whenever MIR const prop routines are more developed, this will\n            // become available. As of this writing (25/03/19) it is not yet.\n            if is_integer_literal(casts_peeled, 0) {\n                lint_expr(cx, expr);\n                return true;\n            }\n            false\n        },\n    }\n}\n\nfn peel_casts<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {\n    match &expr.kind {\n        ExprKind::Cast(inner_expr, _) => peel_casts(inner_expr),\n        _ => expr,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmute_ptr_to_ptr.rs",
    "content": "use super::TRANSMUTE_PTR_TO_PTR;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty, TypeVisitableExt};\n\n/// Checks for `transmute_ptr_to_ptr` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n    arg: sugg::Sugg<'_>,\n    msrv: Msrv,\n) -> bool {\n    match (from_ty.kind(), to_ty.kind()) {\n        (ty::RawPtr(from_pointee_ty, from_mutbl), ty::RawPtr(to_pointee_ty, to_mutbl)) => {\n            span_lint_and_then(\n                cx,\n                TRANSMUTE_PTR_TO_PTR,\n                e.span,\n                \"transmute from a pointer to a pointer\",\n                |diag| {\n                    if from_mutbl == to_mutbl\n                        && to_pointee_ty.is_sized(cx.tcx, cx.typing_env())\n                        && msrv.meets(cx, msrvs::POINTER_CAST)\n                    {\n                        diag.span_suggestion_verbose(\n                            e.span,\n                            \"use `pointer::cast` instead\",\n                            format!(\"{}.cast::<{to_pointee_ty}>()\", arg.maybe_paren()),\n                            Applicability::MaybeIncorrect,\n                        );\n                    } else if from_pointee_ty == to_pointee_ty\n                        && let Some(method) = match (from_mutbl, to_mutbl) {\n                            (ty::Mutability::Not, ty::Mutability::Mut) => Some(\"cast_mut\"),\n                            (ty::Mutability::Mut, ty::Mutability::Not) => Some(\"cast_const\"),\n                            _ => None,\n                        }\n                        && !from_pointee_ty.has_erased_regions()\n                        && msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS)\n                    {\n                        diag.span_suggestion_verbose(\n                            e.span,\n                            format!(\"use `pointer::{method}` instead\"),\n                            format!(\"{}.{method}()\", arg.maybe_paren()),\n                            Applicability::MaybeIncorrect,\n                        );\n                    } else {\n                        diag.span_suggestion_verbose(\n                            e.span,\n                            \"use an `as` cast instead\",\n                            arg.as_ty(to_ty),\n                            Applicability::MaybeIncorrect,\n                        );\n                    }\n                },\n            );\n            true\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmute_ptr_to_ref.rs",
    "content": "use super::TRANSMUTE_PTR_TO_REF;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, Expr, GenericArg, Mutability, Path, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty, TypeVisitableExt};\n\n/// Checks for `transmute_ptr_to_ref` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n    arg: sugg::Sugg<'_>,\n    path: &'tcx Path<'_>,\n    msrv: Msrv,\n) -> bool {\n    match (&from_ty.kind(), &to_ty.kind()) {\n        (ty::RawPtr(from_ptr_ty, _), ty::Ref(_, to_ref_ty, mutbl)) => {\n            span_lint_and_then(\n                cx,\n                TRANSMUTE_PTR_TO_REF,\n                e.span,\n                format!(\"transmute from a pointer type (`{from_ty}`) to a reference type (`{to_ty}`)\"),\n                |diag| {\n                    let (deref, cast) = match mutbl {\n                        Mutability::Mut => (\"&mut *\", \"*mut\"),\n                        Mutability::Not => (\"&*\", \"*const\"),\n                    };\n                    let mut app = Applicability::MachineApplicable;\n\n                    let sugg = if let Some(ty) = get_explicit_type(path) {\n                        let ty_snip = snippet_with_applicability(cx, ty.span, \"..\", &mut app);\n                        if !to_ref_ty.is_sized(cx.tcx, cx.typing_env()) {\n                            // We can't suggest `.cast()`, because that requires `to_ref_ty` to be Sized.\n                            if from_ptr_ty.has_erased_regions() {\n                                // We can't suggest `as *mut/const () as *mut/const to_ref_ty`, because the former is a\n                                // thin pointer, whereas the latter is a wide pointer, due of its pointee, `to_ref_ty`,\n                                // being !Sized.\n                                //\n                                // The only remaining option is be to skip `*mut/const ()`, but that might not be safe\n                                // to do because of the erased regions in `from_ptr_ty`, so reduce the applicability.\n                                app = Applicability::MaybeIncorrect;\n                            }\n                            sugg::make_unop(deref, arg.as_ty(format!(\"{cast} {ty_snip}\"))).to_string()\n                        } else if msrv.meets(cx, msrvs::POINTER_CAST) {\n                            format!(\"{deref}{}.cast::<{ty_snip}>()\", arg.maybe_paren())\n                        } else if from_ptr_ty.has_erased_regions() {\n                            sugg::make_unop(deref, arg.as_ty(format!(\"{cast} () as {cast} {ty_snip}\"))).to_string()\n                        } else {\n                            sugg::make_unop(deref, arg.as_ty(format!(\"{cast} {ty_snip}\"))).to_string()\n                        }\n                    } else if *from_ptr_ty == *to_ref_ty {\n                        if !from_ptr_ty.has_erased_regions() {\n                            sugg::make_unop(deref, arg).to_string()\n                        } else if !to_ref_ty.is_sized(cx.tcx, cx.typing_env()) {\n                            // 1. We can't suggest `.cast()`, because that requires `to_ref_ty` to be Sized.\n                            // 2. We can't suggest `as *mut/const () as *mut/const to_ref_ty`, because the former is a\n                            //    thin pointer, whereas the latter is a wide pointer, due of its pointee, `to_ref_ty`,\n                            //    being !Sized.\n                            //\n                            // The only remaining option is be to skip `*mut/const ()`, but that might not be safe to do\n                            // because of the erased regions in `from_ptr_ty`, so reduce the applicability.\n                            app = Applicability::MaybeIncorrect;\n                            sugg::make_unop(deref, arg.as_ty(format!(\"{cast} {to_ref_ty}\"))).to_string()\n                        } else if msrv.meets(cx, msrvs::POINTER_CAST) {\n                            format!(\"{deref}{}.cast::<{to_ref_ty}>()\", arg.maybe_paren())\n                        } else {\n                            sugg::make_unop(deref, arg.as_ty(format!(\"{cast} () as {cast} {to_ref_ty}\"))).to_string()\n                        }\n                    } else {\n                        sugg::make_unop(deref, arg.as_ty(format!(\"{cast} {to_ref_ty}\"))).to_string()\n                    };\n\n                    diag.span_suggestion(e.span, \"try\", sugg, app);\n                },\n            );\n            true\n        },\n        _ => false,\n    }\n}\n\n/// Gets the type `Bar` in `…::transmute<Foo, &Bar>`.\nfn get_explicit_type<'tcx>(path: &'tcx Path<'tcx>) -> Option<&'tcx hir::Ty<'tcx>> {\n    if let GenericArg::Type(ty) = path.segments.last()?.args?.args.get(1)?\n        && let TyKind::Ref(_, ty) = &ty.kind\n    {\n        Some(ty.ty)\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmute_ref_to_ref.rs",
    "content": "use super::{TRANSMUTE_BYTES_TO_STR, TRANSMUTE_PTR_TO_PTR};\nuse clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::{std_or_core, sugg};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, Mutability};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\n/// Checks for `transmute_bytes_to_str` and `transmute_ptr_to_ptr` lints.\n/// Returns `true` if either one triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n    arg: &'tcx Expr<'_>,\n    const_context: bool,\n) -> bool {\n    let arg_sugg = || sugg::Sugg::hir_with_context(cx, arg, e.span.ctxt(), \"..\", &mut Applicability::Unspecified);\n    if let (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) = (*from_ty.kind(), *to_ty.kind()) {\n        if let ty::Slice(slice_ty) = *ty_from.kind()\n            && ty_to.is_str()\n            && let ty::Uint(ty::UintTy::U8) = slice_ty.kind()\n            && from_mutbl == to_mutbl\n        {\n            let Some(top_crate) = std_or_core(cx) else { return true };\n\n            let postfix = if from_mutbl == Mutability::Mut { \"_mut\" } else { \"\" };\n\n            span_lint_and_sugg(\n                cx,\n                TRANSMUTE_BYTES_TO_STR,\n                e.span,\n                format!(\"transmute from a `{from_ty}` to a `{to_ty}`\"),\n                \"consider using\",\n                if const_context {\n                    format!(\"{top_crate}::str::from_utf8_unchecked{postfix}({})\", arg_sugg())\n                } else {\n                    format!(\"{top_crate}::str::from_utf8{postfix}({}).unwrap()\", arg_sugg())\n                },\n                Applicability::MaybeIncorrect,\n            );\n\n            return true;\n        }\n\n        if (cx.tcx.erase_and_anonymize_regions(from_ty) != cx.tcx.erase_and_anonymize_regions(to_ty)) && !const_context\n        {\n            span_lint_and_then(\n                cx,\n                TRANSMUTE_PTR_TO_PTR,\n                e.span,\n                \"transmute from a reference to a reference\",\n                |diag| {\n                    let sugg_paren = arg_sugg()\n                        .as_ty(Ty::new_ptr(cx.tcx, ty_from, from_mutbl))\n                        .as_ty(Ty::new_ptr(cx.tcx, ty_to, to_mutbl));\n                    let sugg = if to_mutbl == Mutability::Mut {\n                        sugg_paren.mut_addr_deref()\n                    } else {\n                        sugg_paren.addr_deref()\n                    };\n                    diag.span_suggestion(e.span, \"try\", sugg, Applicability::Unspecified);\n                },\n            );\n\n            return true;\n        }\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmute_undefined_repr.rs",
    "content": "use super::TRANSMUTE_UNDEFINED_REPR;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::ty::is_c_void;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, GenericArgsRef, IntTy, Ty, UintTy};\n\n#[expect(clippy::too_many_lines)]\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    from_ty_orig: Ty<'tcx>,\n    to_ty_orig: Ty<'tcx>,\n) -> bool {\n    let mut from_ty = cx.tcx.erase_and_anonymize_regions(from_ty_orig);\n    let mut to_ty = cx.tcx.erase_and_anonymize_regions(to_ty_orig);\n\n    while from_ty != to_ty {\n        let reduced_tys = reduce_refs(cx, from_ty, to_ty);\n        match (reduce_ty(cx, reduced_tys.from_ty), reduce_ty(cx, reduced_tys.to_ty)) {\n            // Various forms of type erasure.\n            (ReducedTy::TypeErasure { raw_ptr_only: false }, _)\n            | (_, ReducedTy::TypeErasure { raw_ptr_only: false }) => return false,\n            (ReducedTy::TypeErasure { .. }, _) if reduced_tys.from_raw_ptr => return false,\n            (_, ReducedTy::TypeErasure { .. }) if reduced_tys.to_raw_ptr => return false,\n\n            // `Repr(C)` <-> unordered type.\n            // If the first field of the `Repr(C)` type matches then the transmute is ok\n            (ReducedTy::OrderedFields(Some(from_sub_ty)), ReducedTy::UnorderedFields(to_sub_ty))\n            | (ReducedTy::UnorderedFields(from_sub_ty), ReducedTy::OrderedFields(Some(to_sub_ty))) => {\n                from_ty = from_sub_ty;\n                to_ty = to_sub_ty;\n            },\n            (ReducedTy::OrderedFields(Some(from_sub_ty)), ReducedTy::Other(to_sub_ty)) if reduced_tys.to_fat_ptr => {\n                from_ty = from_sub_ty;\n                to_ty = to_sub_ty;\n            },\n            (ReducedTy::Other(from_sub_ty), ReducedTy::OrderedFields(Some(to_sub_ty))) if reduced_tys.from_fat_ptr => {\n                from_ty = from_sub_ty;\n                to_ty = to_sub_ty;\n            },\n\n            // ptr <-> ptr\n            (ReducedTy::Other(from_sub_ty), ReducedTy::Other(to_sub_ty))\n                if matches!(from_sub_ty.kind(), ty::Ref(..) | ty::RawPtr(_, _))\n                    && matches!(to_sub_ty.kind(), ty::Ref(..) | ty::RawPtr(_, _)) =>\n            {\n                from_ty = from_sub_ty;\n                to_ty = to_sub_ty;\n            },\n\n            // fat ptr <-> (*size, *size)\n            (ReducedTy::Other(_), ReducedTy::UnorderedFields(to_ty))\n                if reduced_tys.from_fat_ptr && is_size_pair(to_ty) =>\n            {\n                return false;\n            },\n            (ReducedTy::UnorderedFields(from_ty), ReducedTy::Other(_))\n                if reduced_tys.to_fat_ptr && is_size_pair(from_ty) =>\n            {\n                return false;\n            },\n\n            // fat ptr -> some struct | some struct -> fat ptr\n            (ReducedTy::Other(_), _) if reduced_tys.from_fat_ptr => {\n                span_lint_and_then(\n                    cx,\n                    TRANSMUTE_UNDEFINED_REPR,\n                    e.span,\n                    format!(\"transmute from `{from_ty_orig}` which has an undefined layout\"),\n                    |diag| {\n                        if from_ty_orig.peel_refs() != from_ty.peel_refs() {\n                            diag.note(format!(\"the contained type `{from_ty}` has an undefined layout\"));\n                        }\n                    },\n                );\n                return true;\n            },\n            (_, ReducedTy::Other(_)) if reduced_tys.to_fat_ptr => {\n                span_lint_and_then(\n                    cx,\n                    TRANSMUTE_UNDEFINED_REPR,\n                    e.span,\n                    format!(\"transmute to `{to_ty_orig}` which has an undefined layout\"),\n                    |diag| {\n                        if to_ty_orig.peel_refs() != to_ty.peel_refs() {\n                            diag.note(format!(\"the contained type `{to_ty}` has an undefined layout\"));\n                        }\n                    },\n                );\n                return true;\n            },\n\n            (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => {\n                let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs)) =\n                    (from_ty.kind(), to_ty.kind())\n                    && from_def == to_def\n                {\n                    if same_except_params(from_subs, to_subs) {\n                        return false;\n                    }\n                    Some(from_def.did())\n                } else {\n                    None\n                };\n                span_lint_and_then(\n                    cx,\n                    TRANSMUTE_UNDEFINED_REPR,\n                    e.span,\n                    format!(\n                        \"transmute from `{from_ty_orig}` to `{to_ty_orig}`, both of which have an undefined layout\"\n                    ),\n                    |diag| {\n                        if let Some(same_adt_did) = same_adt_did {\n                            diag.note(format!(\n                                \"two instances of the same generic type (`{}`) may have different layouts\",\n                                cx.tcx.item_name(same_adt_did)\n                            ));\n                        } else {\n                            if from_ty_orig.peel_refs() != from_ty {\n                                diag.note(format!(\"the contained type `{from_ty}` has an undefined layout\"));\n                            }\n                            if to_ty_orig.peel_refs() != to_ty {\n                                diag.note(format!(\"the contained type `{to_ty}` has an undefined layout\"));\n                            }\n                        }\n                    },\n                );\n                return true;\n            },\n            (\n                ReducedTy::UnorderedFields(from_ty),\n                ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },\n            ) => {\n                span_lint_and_then(\n                    cx,\n                    TRANSMUTE_UNDEFINED_REPR,\n                    e.span,\n                    format!(\"transmute from `{from_ty_orig}` which has an undefined layout\"),\n                    |diag| {\n                        if from_ty_orig.peel_refs() != from_ty {\n                            diag.note(format!(\"the contained type `{from_ty}` has an undefined layout\"));\n                        }\n                    },\n                );\n                return true;\n            },\n            (\n                ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },\n                ReducedTy::UnorderedFields(to_ty),\n            ) => {\n                span_lint_and_then(\n                    cx,\n                    TRANSMUTE_UNDEFINED_REPR,\n                    e.span,\n                    format!(\"transmute into `{to_ty_orig}` which has an undefined layout\"),\n                    |diag| {\n                        if to_ty_orig.peel_refs() != to_ty {\n                            diag.note(format!(\"the contained type `{to_ty}` has an undefined layout\"));\n                        }\n                    },\n                );\n                return true;\n            },\n            (\n                ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },\n                ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },\n            )\n            | (ReducedTy::UnorderedFields(_), ReducedTy::UnorderedFields(_)) => {\n                break;\n            },\n        }\n    }\n\n    false\n}\n\n#[expect(clippy::struct_excessive_bools)]\nstruct ReducedTys<'tcx> {\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n    from_raw_ptr: bool,\n    to_raw_ptr: bool,\n    from_fat_ptr: bool,\n    to_fat_ptr: bool,\n}\n\n/// Remove references so long as both types are references.\nfn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: Ty<'tcx>) -> ReducedTys<'tcx> {\n    let mut from_raw_ptr = false;\n    let mut to_raw_ptr = false;\n    let (from_fat_ptr, to_fat_ptr) = loop {\n        break match (from_ty.kind(), to_ty.kind()) {\n            (\n                &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(from_sub_ty, _)),\n                &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(to_sub_ty, _)),\n            ) => {\n                from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_, _));\n                from_ty = from_sub_ty;\n                to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_, _));\n                to_ty = to_sub_ty;\n                continue;\n            },\n            (&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(unsized_ty, _)), _)\n                if !unsized_ty.is_sized(cx.tcx, cx.typing_env()) =>\n            {\n                (true, false)\n            },\n            (_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(unsized_ty, _)))\n                if !unsized_ty.is_sized(cx.tcx, cx.typing_env()) =>\n            {\n                (false, true)\n            },\n            _ => (false, false),\n        };\n    };\n    ReducedTys {\n        from_ty,\n        to_ty,\n        from_raw_ptr,\n        to_raw_ptr,\n        from_fat_ptr,\n        to_fat_ptr,\n    }\n}\n\nenum ReducedTy<'tcx> {\n    /// The type can be used for type erasure.\n    TypeErasure { raw_ptr_only: bool },\n    /// The type is a struct containing either zero non-zero sized fields, or multiple non-zero\n    /// sized fields with a defined order.\n    /// The value is the first non-zero sized type.\n    OrderedFields(Option<Ty<'tcx>>),\n    /// The type is a struct containing multiple non-zero sized fields with no defined order.\n    UnorderedFields(Ty<'tcx>),\n    /// Any other type.\n    Other(Ty<'tcx>),\n}\n\n/// Reduce structs containing a single non-zero sized field to it's contained type.\nfn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> {\n    loop {\n        ty = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty);\n        return match *ty.kind() {\n            ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => {\n                ReducedTy::TypeErasure { raw_ptr_only: false }\n            },\n            ty::Array(sub_ty, _) | ty::Slice(sub_ty) => {\n                ty = sub_ty;\n                continue;\n            },\n            ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure { raw_ptr_only: false },\n            ty::Tuple(args) => {\n                let mut iter = args.iter();\n                let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else {\n                    return ReducedTy::OrderedFields(None);\n                };\n                if iter.all(|ty| is_zero_sized_ty(cx, ty)) {\n                    ty = sized_ty;\n                    continue;\n                }\n                ReducedTy::UnorderedFields(ty)\n            },\n            ty::Adt(def, args) if def.is_struct() => {\n                let mut iter = def\n                    .non_enum_variant()\n                    .fields\n                    .iter()\n                    .map(|f| cx.tcx.type_of(f.did).instantiate(cx.tcx, args));\n                let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else {\n                    return ReducedTy::TypeErasure { raw_ptr_only: false };\n                };\n                if iter.all(|ty| is_zero_sized_ty(cx, ty)) {\n                    ty = sized_ty;\n                    continue;\n                }\n                if def.repr().inhibit_struct_field_reordering() {\n                    ReducedTy::OrderedFields(Some(sized_ty))\n                } else {\n                    ReducedTy::UnorderedFields(ty)\n                }\n            },\n            ty::Adt(def, _) if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) => {\n                ReducedTy::TypeErasure { raw_ptr_only: false }\n            },\n            // TODO: Check if the conversion to or from at least one of a union's fields is valid.\n            ty::Adt(def, _) if def.is_union() => ReducedTy::TypeErasure { raw_ptr_only: false },\n            ty::Foreign(_) | ty::Param(_) => ReducedTy::TypeErasure { raw_ptr_only: false },\n            ty::Int(_) | ty::Uint(_) => ReducedTy::TypeErasure { raw_ptr_only: true },\n            _ => ReducedTy::Other(ty),\n        };\n    }\n}\n\nfn is_zero_sized_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    if let Ok(ty) = cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty)\n        && let Ok(layout) = cx.tcx.layout_of(cx.typing_env().as_query_input(ty))\n    {\n        layout.layout.size().bytes() == 0\n    } else {\n        false\n    }\n}\n\nfn is_size_pair(ty: Ty<'_>) -> bool {\n    if let ty::Tuple(tys) = *ty.kind()\n        && let [ty1, ty2] = &**tys\n    {\n        matches!(ty1.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize))\n            && matches!(ty2.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize))\n    } else {\n        false\n    }\n}\n\nfn same_except_params<'tcx>(subs1: GenericArgsRef<'tcx>, subs2: GenericArgsRef<'tcx>) -> bool {\n    // TODO: check const parameters as well. Currently this will consider `Array<5>` the same as\n    // `Array<6>`\n    for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) {\n        match (ty1.kind(), ty2.kind()) {\n            (ty::Param(_), _) | (_, ty::Param(_)) => (),\n            (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (),\n            _ => return false,\n        }\n    }\n    true\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs",
    "content": "use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::sugg::Sugg;\nuse rustc_ast::util::parser::ExprPrecedence;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, Node};\nuse rustc_hir_typeck::cast::check_cast;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\nuse rustc_middle::ty::cast::CastKind;\n\n/// Checks for `transmutes_expressible_as_ptr_casts` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    from_ty: Ty<'tcx>,\n    from_ty_adjusted: bool,\n    to_ty: Ty<'tcx>,\n    arg: &'tcx Expr<'_>,\n    const_context: bool,\n) -> bool {\n    use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast};\n    let mut app = Applicability::MachineApplicable;\n    let mut sugg = match check_cast(cx.tcx, cx.param_env, e, from_ty, to_ty) {\n        Some(FnPtrAddrCast | PtrAddrCast) if const_context => return false,\n        Some(PtrPtrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast) => {\n            Sugg::hir_with_context(cx, arg, e.span.ctxt(), \"..\", &mut app)\n                .as_ty(to_ty.to_string())\n                .to_string()\n        },\n        Some(PtrAddrCast) if !from_ty_adjusted => Sugg::hir_with_context(cx, arg, e.span.ctxt(), \"..\", &mut app)\n            .as_ty(to_ty.to_string())\n            .to_string(),\n\n        // The only adjustments here would be ref-to-ptr and unsize coercions. The result of an unsize coercions can't\n        // be transmuted to a usize. For ref-to-ptr coercions, borrows need to be cast to a pointer before being cast to\n        // a usize.\n        Some(PtrAddrCast) => format!(\n            \"{} as {to_ty}\",\n            Sugg::hir_with_context(cx, arg, e.span.ctxt(), \"..\", &mut app).as_ty(from_ty)\n        ),\n        _ => return false,\n    };\n\n    if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)\n        && cx.precedence(parent) > ExprPrecedence::Cast\n    {\n        sugg = format!(\"({sugg})\");\n    }\n\n    span_lint_and_sugg(\n        cx,\n        TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,\n        e.span,\n        format!(\"transmute from `{from_ty}` to `{to_ty}` which could be expressed as a pointer cast instead\"),\n        \"try\",\n        sugg,\n        app,\n    );\n    true\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/transmuting_null.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::{is_integer_const, sym};\nuse rustc_hir::{ConstBlock, Expr, ExprKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\nuse super::TRANSMUTING_NULL;\n\nconst LINT_MSG: &str = \"transmuting a known null pointer into a reference\";\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>, to_ty: Ty<'tcx>) -> bool {\n    if !to_ty.is_ref() {\n        return false;\n    }\n\n    // Catching transmute over constants that resolve to `null`.\n    if let ExprKind::Path(ref _qpath) = arg.kind\n        && let Some(Constant::RawPtr(0)) = ConstEvalCtxt::new(cx).eval(arg)\n    {\n        span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);\n        return true;\n    }\n\n    // Catching:\n    // `std::mem::transmute(0 as *const i32)`\n    if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind\n        && is_integer_const(cx, inner_expr, 0)\n    {\n        span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);\n        return true;\n    }\n\n    // Catching:\n    // `std::mem::transmute(std::ptr::null::<i32>())`\n    if let ExprKind::Call(func1, []) = arg.kind\n        && func1.basic_res().is_diag_item(cx, sym::ptr_null)\n    {\n        span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);\n        return true;\n    }\n\n    // Catching:\n    // `std::mem::transmute(std::ptr::without_provenance::<i32>(0))`\n    // `std::mem::transmute(std::ptr::without_provenance_mut::<i32>(0))`\n    if let ExprKind::Call(func1, [arg1]) = arg.kind\n        && (func1.basic_res().is_diag_item(cx, sym::ptr_without_provenance)\n            || func1.basic_res().is_diag_item(cx, sym::ptr_without_provenance_mut))\n        && is_integer_const(cx, arg1, 0)\n    {\n        span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);\n        return true;\n    }\n\n    // Catching:\n    // `std::mem::transmute({ 0 as *const u64 })` and similar const blocks\n    if let ExprKind::Block(block, _) = arg.kind\n        && block.stmts.is_empty()\n        && let Some(inner) = block.expr\n    {\n        // Run again with the inner expression\n        return check(cx, expr, inner, to_ty);\n    }\n\n    // Catching:\n    // `std::mem::transmute(const { u64::MIN as *const u64 });`\n    if let ExprKind::ConstBlock(ConstBlock { body, .. }) = arg.kind {\n        // Strip out the const and run again\n        let block = cx.tcx.hir_body(body).value;\n        return check(cx, expr, block, to_ty);\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/unsound_collection_transmute.rs",
    "content": "use super::UNSOUND_COLLECTION_TRANSMUTE;\nuse super::utils::is_layout_incompatible;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::sym;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\n/// Checks for `unsound_collection_transmute` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {\n    match (&from_ty.kind(), &to_ty.kind()) {\n        (ty::Adt(from_adt, from_args), ty::Adt(to_adt, to_args)) => {\n            if from_adt.did() != to_adt.did() {\n                return false;\n            }\n            if !matches!(\n                cx.tcx.get_diagnostic_name(to_adt.did()),\n                Some(\n                    sym::BTreeMap\n                        | sym::BTreeSet\n                        | sym::BinaryHeap\n                        | sym::HashMap\n                        | sym::HashSet\n                        | sym::Vec\n                        | sym::VecDeque\n                )\n            ) {\n                return false;\n            }\n            if from_args\n                .types()\n                .zip(to_args.types())\n                .any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty))\n            {\n                span_lint(\n                    cx,\n                    UNSOUND_COLLECTION_TRANSMUTE,\n                    e.span,\n                    format!(\"transmute from `{from_ty}` to `{to_ty}` with mismatched layout is unsound\"),\n                );\n                true\n            } else {\n                false\n            }\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/useless_transmute.rs",
    "content": "use super::USELESS_TRANSMUTE;\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_then};\nuse clippy_utils::sugg;\nuse rustc_errors::Applicability;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty, TypeVisitableExt};\n\n/// Checks for `useless_transmute` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'_>,\n    from_ty: Ty<'tcx>,\n    to_ty: Ty<'tcx>,\n    arg: &'tcx Expr<'_>,\n) -> bool {\n    match (*from_ty.kind(), *to_ty.kind()) {\n        _ if from_ty == to_ty && !from_ty.has_erased_regions() => {\n            span_lint(\n                cx,\n                USELESS_TRANSMUTE,\n                e.span,\n                format!(\"transmute from a type (`{from_ty}`) to itself\"),\n            );\n            true\n        },\n        (ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty, ptr_mutbl)) => {\n            // No way to give the correct suggestion here. Avoid linting for now.\n            if !rty.has_erased_regions() {\n                span_lint_and_then(\n                    cx,\n                    USELESS_TRANSMUTE,\n                    e.span,\n                    \"transmute from a reference to a pointer\",\n                    |diag| {\n                        if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {\n                            let sugg = if ptr_ty == rty && rty_mutbl == ptr_mutbl {\n                                arg.as_ty(to_ty)\n                            } else {\n                                arg.as_ty(Ty::new_ptr(cx.tcx, rty, rty_mutbl)).as_ty(to_ty)\n                            };\n\n                            diag.span_suggestion(e.span, \"try\", sugg, Applicability::Unspecified);\n                        }\n                    },\n                );\n            }\n            true\n        },\n        (ty::Int(_) | ty::Uint(_), ty::RawPtr(_, _)) => {\n            // Handled by the upstream rustc `integer_to_ptr_transmutes` lint\n            true\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/utils.rs",
    "content": "use rustc_lint::LateContext;\nuse rustc_middle::ty::Ty;\n\n// check if the component types of the transmuted collection and the result have different ABI,\n// size or alignment\npub(super) fn is_layout_incompatible<'tcx>(cx: &LateContext<'tcx>, from: Ty<'tcx>, to: Ty<'tcx>) -> bool {\n    let typing_env = cx.typing_env();\n    if let Ok(from) = cx.tcx.try_normalize_erasing_regions(typing_env, from)\n        && let Ok(to) = cx.tcx.try_normalize_erasing_regions(typing_env, to)\n        && let Ok(from_layout) = cx.tcx.layout_of(typing_env.as_query_input(from))\n        && let Ok(to_layout) = cx.tcx.layout_of(typing_env.as_query_input(to))\n    {\n        from_layout.size != to_layout.size || from_layout.align.abi != to_layout.align.abi\n    } else {\n        // no idea about layout, so don't lint\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/transmute/wrong_transmute.rs",
    "content": "use super::WRONG_TRANSMUTE;\nuse clippy_utils::diagnostics::span_lint;\nuse rustc_hir::Expr;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, Ty};\n\n/// Checks for `wrong_transmute` lint.\n/// Returns `true` if it's triggered, otherwise returns `false`.\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {\n    match (&from_ty.kind(), &to_ty.kind()) {\n        (ty::Float(_) | ty::Char, ty::Ref(..) | ty::RawPtr(_, _)) => {\n            span_lint(\n                cx,\n                WRONG_TRANSMUTE,\n                e.span,\n                format!(\"transmute from a `{from_ty}` to a pointer\"),\n            );\n            true\n        },\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/tuple_array_conversions.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::visitors::local_used_once;\nuse clippy_utils::{get_enclosing_block, is_from_proc_macro};\nuse itertools::Itertools;\nuse rustc_ast::LitKind;\nuse rustc_hir::{Expr, ExprKind, Node, PatKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::impl_lint_pass;\nuse std::iter::once;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for tuple<=>array conversions that are not done with `.into()`.\n    ///\n    /// ### Why is this bad?\n    /// It may be unnecessary complexity. `.into()` works for converting tuples<=> arrays of up to\n    /// 12 elements and conveys the intent more clearly, while also leaving less room for hard to\n    /// spot bugs!\n    ///\n    /// ### Known issues\n    /// The suggested code may hide potential asymmetry in some cases. See\n    /// [#11085](https://github.com/rust-lang/rust-clippy/issues/11085) for more info.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let t1 = &[(1, 2), (3, 4)];\n    /// let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect();\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// let t1 = &[(1, 2), (3, 4)];\n    /// let v1: Vec<[u32; 2]> = t1.iter().map(|&t| t.into()).collect();\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub TUPLE_ARRAY_CONVERSIONS,\n    nursery,\n    \"checks for tuple<=>array conversions that are not done with `.into()`\"\n}\n\nimpl_lint_pass!(TupleArrayConversions => [TUPLE_ARRAY_CONVERSIONS]);\n\npub struct TupleArrayConversions {\n    msrv: Msrv,\n}\nimpl TupleArrayConversions {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl LateLintPass<'_> for TupleArrayConversions {\n    fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if expr.span.in_external_macro(cx.sess().source_map()) || !self.msrv.meets(cx, msrvs::TUPLE_ARRAY_CONVERSIONS) {\n            return;\n        }\n\n        match expr.kind {\n            ExprKind::Array(elements) if (1..=12).contains(&elements.len()) => check_array(cx, expr, elements),\n            ExprKind::Tup(elements) if (1..=12).contains(&elements.len()) => check_tuple(cx, expr, elements),\n            _ => {},\n        }\n    }\n}\n\nfn check_array<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &'tcx [Expr<'tcx>]) {\n    let Some(ty) = cx.typeck_results().expr_ty(expr).builtin_index() else {\n        unreachable!(\"`expr` must be an array or slice due to `ExprKind::Array`\");\n    };\n\n    if let [first, ..] = elements\n        && let Some(locals) = (match first.kind {\n            ExprKind::Field(_, _) => elements\n                .iter()\n                .enumerate()\n                .map(|(i, f)| -> Option<&'tcx Expr<'tcx>> {\n                    let ExprKind::Field(lhs, ident) = f.kind else {\n                        return None;\n                    };\n                    (ident.name.as_str() == i.to_string()).then_some(lhs)\n                })\n                .collect::<Option<Vec<_>>>(),\n            ExprKind::Path(_) => Some(elements.iter().collect()),\n            _ => None,\n        })\n        && all_bindings_are_for_conv(cx, &[ty], elements, &locals, ToType::Array)\n        && !is_from_proc_macro(cx, expr)\n    {\n        span_lint_and_help(\n            cx,\n            TUPLE_ARRAY_CONVERSIONS,\n            expr.span,\n            \"it looks like you're trying to convert a tuple to an array\",\n            None,\n            \"use `.into()` instead, or `<[T; N]>::from` if type annotations are needed\",\n        );\n    }\n}\n\nfn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &'tcx [Expr<'tcx>]) {\n    if let ty::Tuple(tys) = cx.typeck_results().expr_ty(expr).kind()\n        && let [first, ..] = elements\n        // Fix #11100\n        && tys.iter().all_equal()\n        && let Some(locals) = (match first.kind {\n            ExprKind::Index(..) => elements\n                .iter()\n                .enumerate()\n                .map(|(i, i_expr)| -> Option<&'tcx Expr<'tcx>> {\n                    if let ExprKind::Index(lhs, index, _) = i_expr.kind\n                        && let ExprKind::Lit(lit) = index.kind\n                        && let LitKind::Int(val, _) = lit.node\n                    {\n                        return (val == i as u128).then_some(lhs);\n                    }\n\n                    None\n                })\n                .collect::<Option<Vec<_>>>(),\n            ExprKind::Path(_) => Some(elements.iter().collect()),\n            _ => None,\n        })\n        && all_bindings_are_for_conv(cx, tys, elements, &locals, ToType::Tuple)\n        && !is_from_proc_macro(cx, expr)\n    {\n        span_lint_and_help(\n            cx,\n            TUPLE_ARRAY_CONVERSIONS,\n            expr.span,\n            \"it looks like you're trying to convert an array to a tuple\",\n            None,\n            \"use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed\",\n        );\n    }\n}\n\n/// Checks that every binding in `elements` comes from the same parent `Pat` with the kind if there\n/// is a parent `Pat`. Returns false in any of the following cases:\n/// * `kind` does not match `pat.kind`\n/// * one or more elements in `elements` is not a binding\n/// * one or more bindings does not have the same parent `Pat`\n/// * one or more bindings are used after `expr`\n/// * the bindings do not all have the same type\n#[expect(clippy::cast_possible_truncation)]\nfn all_bindings_are_for_conv<'tcx>(\n    cx: &LateContext<'tcx>,\n    final_tys: &[Ty<'tcx>],\n    elements: &[Expr<'_>],\n    locals: &[&Expr<'_>],\n    kind: ToType,\n) -> bool {\n    let Some(locals) = locals.iter().map(|e| e.res_local_id()).collect::<Option<Vec<_>>>() else {\n        return false;\n    };\n    let local_parents = locals.iter().map(|l| cx.tcx.parent_hir_node(*l)).collect::<Vec<_>>();\n\n    local_parents\n        .iter()\n        .map(|node| match node {\n            Node::Pat(pat) => kind.eq(&pat.kind).then_some(pat.hir_id),\n            Node::LetStmt(l) => Some(l.hir_id),\n            _ => None,\n        })\n        .all_equal()\n        && locals.iter().zip(local_parents.iter()).all(|(&l, &parent)| {\n            if let Node::LetStmt(_) = parent {\n                return true;\n            }\n\n            let Some(b) = get_enclosing_block(cx, l) else {\n                return true;\n            };\n            local_used_once(cx, b, l).is_some()\n        })\n        && local_parents.first().is_some_and(|node| {\n            let Some(ty) = match node {\n                Node::Pat(pat)\n                    if let PatKind::Tuple(pats, _) | PatKind::Slice(pats, None, []) = &pat.kind\n                        && pats.iter().zip(locals.iter()).all(|(p, l)| {\n                            if let PatKind::Binding(_, id, _, _) = p.kind {\n                                id == *l\n                            } else {\n                                true\n                            }\n                        }) =>\n                {\n                    Some(pat.hir_id)\n                },\n                Node::LetStmt(l) => Some(l.hir_id),\n                _ => None,\n            }\n            .map(|hir_id| cx.typeck_results().node_type(hir_id)) else {\n                return false;\n            };\n            match (kind, ty.kind()) {\n                // Ensure the final type and the original type have the same length, and that there\n                // is no implicit `&mut`<=>`&` anywhere (#11100). Bit ugly, I know, but it works.\n                (ToType::Array, ty::Tuple(tys)) => {\n                    tys.len() == elements.len() && tys.iter().chain(final_tys.iter().copied()).all_equal()\n                },\n                (ToType::Tuple, ty::Array(ty, len)) => {\n                    let Some(len) = len.try_to_target_usize(cx.tcx) else {\n                        return false;\n                    };\n                    len as usize == elements.len() && final_tys.iter().chain(once(ty)).all_equal()\n                },\n                _ => false,\n            }\n        })\n}\n\n#[derive(Clone, Copy)]\nenum ToType {\n    Array,\n    Tuple,\n}\n\nimpl PartialEq<PatKind<'_>> for ToType {\n    fn eq(&self, other: &PatKind<'_>) -> bool {\n        match self {\n            ToType::Array => matches!(other, PatKind::Tuple(_, _)),\n            ToType::Tuple => matches!(other, PatKind::Slice(_, _, _)),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/types/borrowed_box.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{\n    self as hir, GenericArg, GenericBounds, GenericParamKind, HirId, Lifetime, MutTy, Mutability, Node, QPath, TyKind,\n};\nuse rustc_lint::LateContext;\n\nuse super::BORROWED_BOX;\n\npub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, mut_ty: &MutTy<'_>) -> bool {\n    match mut_ty.ty.kind {\n        TyKind::Path(ref qpath) => {\n            let hir_id = mut_ty.ty.hir_id;\n            let def = cx.qpath_res(qpath, hir_id);\n            if let Some(def_id) = def.opt_def_id()\n                && Some(def_id) == cx.tcx.lang_items().owned_box()\n                && let QPath::Resolved(None, path) = *qpath\n                && let [ref bx] = *path.segments\n                && let Some(params) = bx.args\n                && params.parenthesized == hir::GenericArgsParentheses::No\n                && let Some(inner) = params.args.iter().find_map(|arg| match arg {\n                    GenericArg::Type(ty) => Some(ty),\n                    _ => None,\n                })\n            {\n                if is_any_trait(cx, inner.as_unambig_ty()) {\n                    // Ignore `Box<Any>` types; see issue #1884 for details.\n                    return false;\n                }\n\n                let ltopt = if lt.is_anonymous() {\n                    String::new()\n                } else {\n                    format!(\"{} \", lt.ident)\n                };\n\n                if mut_ty.mutbl == Mutability::Mut {\n                    // Ignore `&mut Box<T>` types; see issue #2907 for\n                    // details.\n                    return false;\n                }\n\n                // When trait objects or opaque types have lifetime or auto-trait bounds,\n                // we need to add parentheses to avoid a syntax error due to its ambiguity.\n                // Originally reported as the issue #3128.\n                let inner_snippet = snippet(cx, inner.span, \"..\");\n                let suggestion = match &inner.kind {\n                    TyKind::TraitObject(bounds, lt_bound) if bounds.len() > 1 || !lt_bound.is_elided() => {\n                        format!(\"&{ltopt}({inner_snippet})\")\n                    },\n                    TyKind::Path(qpath)\n                        if get_bounds_if_impl_trait(cx, qpath, inner.hir_id).is_some_and(|bounds| bounds.len() > 1) =>\n                    {\n                        format!(\"&{ltopt}({inner_snippet})\")\n                    },\n                    _ => format!(\"&{ltopt}{inner_snippet}\"),\n                };\n                span_lint_and_sugg(\n                    cx,\n                    BORROWED_BOX,\n                    hir_ty.span,\n                    \"you seem to be trying to use `&Box<T>`. Consider using just `&T`\",\n                    \"try\",\n                    suggestion,\n                    // To make this `MachineApplicable`, at least one needs to check if it isn't a trait item\n                    // because the trait impls of it will break otherwise;\n                    // and there may be other cases that result in invalid code.\n                    // For example, type coercion doesn't work nicely.\n                    Applicability::Unspecified,\n                );\n                return true;\n            }\n            false\n        },\n        _ => false,\n    }\n}\n\n// Returns true if given type is `Any` trait.\nfn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {\n    if let TyKind::TraitObject(traits, ..) = t.kind {\n        return traits.iter().any(|bound| {\n            if let Some(trait_did) = bound.trait_ref.trait_def_id()\n                && cx.tcx.is_diagnostic_item(sym::Any, trait_did)\n            {\n                return true;\n            }\n            false\n        });\n    }\n\n    false\n}\n\nfn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id: HirId) -> Option<GenericBounds<'tcx>> {\n    if let Some(did) = cx.qpath_res(qpath, id).opt_def_id()\n        && let Some(Node::GenericParam(generic_param)) = cx.tcx.hir_get_if_local(did)\n        && let GenericParamKind::Type { synthetic, .. } = generic_param.kind\n        && synthetic\n        && let Some(generics) = cx.tcx.hir_get_generics(id.owner.def_id)\n        && let Some(pred) = generics.bounds_for_param(did.expect_local()).next()\n    {\n        Some(pred.bounds)\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/types/box_collection.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::{qpath_generic_tys, sym};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{self as hir, QPath};\nuse rustc_lint::LateContext;\nuse rustc_span::Symbol;\n\nuse super::BOX_COLLECTION;\n\npub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {\n    if Some(def_id) == cx.tcx.lang_items().owned_box()\n        && let Some(item_type) = get_std_collection(cx, qpath)\n    {\n        let generic = match item_type {\n            sym::String => \"\",\n            _ => \"<..>\",\n        };\n\n        let box_content = format!(\"{item_type}{generic}\");\n        span_lint_and_help(\n            cx,\n            BOX_COLLECTION,\n            hir_ty.span,\n            format!(\"you seem to be trying to use `Box<{box_content}>`. Consider using just `{box_content}`\"),\n            None,\n            format!(\"`{box_content}` is already on the heap, `Box<{box_content}>` makes an extra allocation\"),\n        );\n        true\n    } else {\n        false\n    }\n}\n\nfn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol> {\n    let param = qpath_generic_tys(qpath).next()?;\n    let id = param.basic_res().opt_def_id()?;\n    cx.tcx\n        .get_diagnostic_name(id)\n        .filter(|&name| {\n            matches!(\n                name,\n                sym::HashMap\n                    | sym::Vec\n                    | sym::HashSet\n                    | sym::VecDeque\n                    | sym::LinkedList\n                    | sym::BTreeMap\n                    | sym::BTreeSet\n                    | sym::BinaryHeap\n            )\n        })\n        .or_else(|| {\n            cx.tcx\n                .lang_items()\n                .string()\n                .filter(|did| id == *did)\n                .map(|_| sym::String)\n        })\n}\n"
  },
  {
    "path": "clippy_lints/src/types/linked_list.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::sym;\nuse rustc_hir as hir;\nuse rustc_hir::def_id::DefId;\nuse rustc_lint::LateContext;\n\nuse super::LINKEDLIST;\n\npub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, def_id: DefId) -> bool {\n    if cx.tcx.is_diagnostic_item(sym::LinkedList, def_id) {\n        span_lint_and_help(\n            cx,\n            LINKEDLIST,\n            hir_ty.span,\n            \"you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\",\n            None,\n            \"a `VecDeque` might work\",\n        );\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/types/mod.rs",
    "content": "mod borrowed_box;\nmod box_collection;\nmod linked_list;\nmod option_option;\nmod owned_cow;\nmod rc_buffer;\nmod rc_mutex;\nmod redundant_allocation;\nmod type_complexity;\nmod utils;\nmod vec_box;\n\nuse clippy_config::Conf;\nuse rustc_hir as hir;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{\n    Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, MutTy, QPath, TraitFn,\n    TraitItem, TraitItemKind, TyKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `&Box<T>` anywhere in the code.\n    /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.\n    ///\n    /// ### Why is this bad?\n    /// A `&Box<T>` parameter requires the function caller to box `T` first before passing it to a function.\n    /// Using `&T` defines a concrete type for the parameter and generalizes the function, this would also\n    /// auto-deref to `&T` at the function call site if passed a `&Box<T>`.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// fn foo(bar: &Box<T>) { ... }\n    /// ```\n    ///\n    /// Better:\n    ///\n    /// ```rust,ignore\n    /// fn foo(bar: &T) { ... }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub BORROWED_BOX,\n    complexity,\n    \"a borrow of a boxed type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Box<T>` where T is a collection such as Vec anywhere in the code.\n    /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.\n    ///\n    /// ### Why is this bad?\n    /// Collections already keeps their contents in a separate area on\n    /// the heap. So if you `Box` them, you just add another level of indirection\n    /// without any benefit whatsoever.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// struct X {\n    ///     values: Box<Vec<Foo>>,\n    /// }\n    /// ```\n    ///\n    /// Better:\n    ///\n    /// ```rust,ignore\n    /// struct X {\n    ///     values: Vec<Foo>,\n    /// }\n    /// ```\n    #[clippy::version = \"1.57.0\"]\n    pub BOX_COLLECTION,\n    perf,\n    \"usage of `Box<Vec<T>>`, vector elements are already on the heap\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of any `LinkedList`, suggesting to use a\n    /// `Vec` or a `VecDeque` (formerly called `RingBuf`).\n    ///\n    /// ### Why is this bad?\n    /// Gankra says:\n    ///\n    /// > The TL;DR of `LinkedList` is that it's built on a massive amount of\n    /// pointers and indirection.\n    /// > It wastes memory, it has terrible cache locality, and is all-around slow.\n    /// `RingBuf`, while\n    /// > \"only\" amortized for push/pop, should be faster in the general case for\n    /// almost every possible\n    /// > workload, and isn't even amortized at all if you can predict the capacity\n    /// you need.\n    /// >\n    /// > `LinkedList`s are only really good if you're doing a lot of merging or\n    /// splitting of lists.\n    /// > This is because they can just mangle some pointers instead of actually\n    /// copying the data. Even\n    /// > if you're doing a lot of insertion in the middle of the list, `RingBuf`\n    /// can still be better\n    /// > because of how expensive it is to seek to the middle of a `LinkedList`.\n    ///\n    /// ### Known problems\n    /// False positives – the instances where using a\n    /// `LinkedList` makes sense are few and far between, but they can still happen.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::collections::LinkedList;\n    /// let x: LinkedList<usize> = LinkedList::new();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub LINKEDLIST,\n    pedantic,\n    \"usage of LinkedList, usually a vector is faster, or a more specialized data structure like a `VecDeque`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Option<Option<_>>` in function signatures and type\n    /// definitions\n    ///\n    /// ### Why is this bad?\n    /// `Option<_>` represents an optional value. `Option<Option<_>>`\n    /// represents an optional value which itself wraps an optional. This is logically the\n    /// same thing as an optional value but has an unneeded extra level of wrapping.\n    ///\n    /// If you have a case where `Some(Some(_))`, `Some(None)` and `None` are distinct cases,\n    /// consider a custom `enum` instead, with clear names for each case.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn get_data() -> Option<Option<u32>> {\n    ///     None\n    /// }\n    /// ```\n    ///\n    /// Better:\n    ///\n    /// ```no_run\n    /// pub enum Contents {\n    ///     Data(Vec<u8>), // Was Some(Some(Vec<u8>))\n    ///     NotYetFetched, // Was Some(None)\n    ///     None,          // Was None\n    /// }\n    ///\n    /// fn get_data() -> Contents {\n    ///     Contents::None\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub OPTION_OPTION,\n    pedantic,\n    \"usage of `Option<Option<T>>`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects needlessly owned `Cow` types.\n    ///\n    /// ### Why is this bad?\n    /// The borrowed types are usually more flexible, in that e.g. a\n    /// `Cow<'_, str>` can accept both `&str` and `String` while\n    /// `Cow<'_, String>` can only accept `&String` and `String`. In\n    /// particular, `&str` is more general, because it allows for string\n    /// literals while `&String` can only be borrowed from a heap-owned\n    /// `String`).\n    ///\n    /// ### Known Problems\n    /// The lint does not check for usage of the type. There may be external\n    /// interfaces that require the use of an owned type.\n    ///\n    /// At least the `CString` type also has a different API than `CStr`: The\n    /// former has an `as_bytes` method which the latter calls `to_bytes`.\n    /// There is no guarantee that other types won't gain additional methods\n    /// leading to a similar mismatch.\n    ///\n    /// In addition, the lint only checks for the known problematic types\n    /// `String`, `Vec<_>`, `CString`, `OsString` and `PathBuf`. Custom types\n    /// that implement `ToOwned` will not be detected.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let wrogn: std::borrow::Cow<'_, Vec<u8>>;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let right: std::borrow::Cow<'_, [u8]>;\n    /// ```\n    #[clippy::version = \"1.87.0\"]\n    pub OWNED_COW,\n    style,\n    \"needlessly owned Cow type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`.\n    ///\n    /// ### Why restrict this?\n    /// Expressions such as `Rc<String>` usually have no advantage over `Rc<str>`, since\n    /// it is larger and involves an extra level of indirection, and doesn't implement `Borrow<str>`.\n    ///\n    /// While mutating a buffer type would still be possible with `Rc::get_mut()`, it only\n    /// works if there are no additional references yet, which usually defeats the purpose of\n    /// enclosing it in a shared ownership type. Instead, additionally wrapping the inner\n    /// type with an interior mutable container (such as `RefCell` or `Mutex`) would normally\n    /// be used.\n    ///\n    /// ### Known problems\n    /// This pattern can be desirable to avoid the overhead of a `RefCell` or `Mutex` for\n    /// cases where mutation only happens before there are any additional references.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// # use std::rc::Rc;\n    /// fn foo(interned: Rc<String>) { ... }\n    /// ```\n    ///\n    /// Better:\n    ///\n    /// ```rust,ignore\n    /// fn foo(interned: Rc<str>) { ... }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub RC_BUFFER,\n    restriction,\n    \"shared ownership of a buffer type\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `Rc<Mutex<T>>`.\n    ///\n    /// ### Why restrict this?\n    /// `Rc` is used in single thread and `Mutex` is used in multi thread.\n    /// Consider using `Rc<RefCell<T>>` in single thread or `Arc<Mutex<T>>` in multi thread.\n    ///\n    /// ### Known problems\n    /// Sometimes combining generic types can lead to the requirement that a\n    /// type use Rc in conjunction with Mutex. We must consider those cases false positives, but\n    /// alas they are quite hard to rule out. Luckily they are also rare.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// use std::rc::Rc;\n    /// use std::sync::Mutex;\n    /// fn foo(interned: Rc<Mutex<i32>>) { ... }\n    /// ```\n    ///\n    /// Better:\n    ///\n    /// ```rust,ignore\n    /// use std::rc::Rc;\n    /// use std::cell::RefCell\n    /// fn foo(interned: Rc<RefCell<i32>>) { ... }\n    /// ```\n    #[clippy::version = \"1.55.0\"]\n    pub RC_MUTEX,\n    restriction,\n    \"usage of `Rc<Mutex<T>>`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of redundant allocations anywhere in the code.\n    ///\n    /// ### Why is this bad?\n    /// Expressions such as `Rc<&T>`, `Rc<Rc<T>>`, `Rc<Arc<T>>`, `Rc<Box<T>>`, `Arc<&T>`, `Arc<Rc<T>>`,\n    /// `Arc<Arc<T>>`, `Arc<Box<T>>`, `Box<&T>`, `Box<Rc<T>>`, `Box<Arc<T>>`, `Box<Box<T>>`, add an unnecessary level of indirection.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::rc::Rc;\n    /// fn foo(bar: Rc<&usize>) {}\n    /// ```\n    ///\n    /// Better:\n    ///\n    /// ```no_run\n    /// fn foo(bar: &usize) {}\n    /// ```\n    #[clippy::version = \"1.44.0\"]\n    pub REDUNDANT_ALLOCATION,\n    perf,\n    \"redundant allocation\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for types used in structs, parameters and `let`\n    /// declarations above a certain complexity threshold.\n    ///\n    /// ### Why is this bad?\n    /// Too complex types make the code less readable. Consider\n    /// using a `type` definition to simplify them.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::rc::Rc;\n    /// struct PointMatrixContainer {\n    ///     matrix: Rc<Vec<Vec<Box<(u32, u32, u32, u32)>>>>,\n    /// }\n    ///\n    /// fn main() {\n    ///     let point_matrix: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![\n    ///         vec![\n    ///             Box::new((1, 2, 3, 4)),\n    ///             Box::new((5, 6, 7, 8)),\n    ///         ],\n    ///         vec![\n    ///             Box::new((9, 10, 11, 12)),\n    ///         ],\n    ///     ];\n    ///\n    ///     let shared_point_matrix: Rc<Vec<Vec<Box<(u32, u32, u32, u32)>>>> = Rc::new(point_matrix);\n    ///\n    ///     let container = PointMatrixContainer {\n    ///         matrix: shared_point_matrix,\n    ///     };\n    ///\n    ///     // ...\n    /// }\n    /// ```\n    /// Use instead:\n    /// ### Example\n    /// ```no_run\n    /// # use std::rc::Rc;\n    /// type PointMatrix = Vec<Vec<Box<(u32, u32, u32, u32)>>>;\n    /// type SharedPointMatrix = Rc<PointMatrix>;\n    ///\n    /// struct PointMatrixContainer {\n    ///     matrix: SharedPointMatrix,\n    /// }\n    ///\n    /// fn main() {\n    ///     let point_matrix: PointMatrix = vec![\n    ///         vec![\n    ///             Box::new((1, 2, 3, 4)),\n    ///             Box::new((5, 6, 7, 8)),\n    ///         ],\n    ///         vec![\n    ///             Box::new((9, 10, 11, 12)),\n    ///         ],\n    ///     ];\n    ///\n    ///     let shared_point_matrix: SharedPointMatrix = Rc::new(point_matrix);\n    ///\n    ///     let container = PointMatrixContainer {\n    ///         matrix: shared_point_matrix,\n    ///     };\n    ///\n    ///     // ...\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub TYPE_COMPLEXITY,\n    complexity,\n    \"usage of very complex types that might be better factored into `type` definitions\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Vec<Box<T>>` where T: Sized anywhere in the code.\n    /// Check the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information.\n    ///\n    /// ### Why is this bad?\n    /// `Vec` already keeps its contents in a separate area on\n    /// the heap. So if you `Box` its contents, you just add another level of indirection.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct X {\n    ///     values: Vec<Box<i32>>,\n    /// }\n    /// ```\n    ///\n    /// Better:\n    ///\n    /// ```no_run\n    /// struct X {\n    ///     values: Vec<i32>,\n    /// }\n    /// ```\n    #[clippy::version = \"1.33.0\"]\n    pub VEC_BOX,\n    complexity,\n    \"usage of `Vec<Box<T>>` where T: Sized, vector elements are already on the heap\"\n}\n\nimpl_lint_pass!(Types => [\n    BORROWED_BOX,\n    BOX_COLLECTION,\n    LINKEDLIST,\n    OPTION_OPTION,\n    OWNED_COW,\n    RC_BUFFER,\n    RC_MUTEX,\n    REDUNDANT_ALLOCATION,\n    TYPE_COMPLEXITY,\n    VEC_BOX,\n]);\n\npub struct Types {\n    vec_box_size_threshold: u64,\n    type_complexity_threshold: u64,\n    avoid_breaking_exported_api: bool,\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Types {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        fn_kind: FnKind<'_>,\n        decl: &FnDecl<'tcx>,\n        _: &Body<'_>,\n        _: Span,\n        def_id: LocalDefId,\n    ) {\n        let is_in_trait_impl = if let hir::Node::Item(item) = cx\n            .tcx\n            .hir_node_by_def_id(cx.tcx.hir_get_parent_item(cx.tcx.local_def_id_to_hir_id(def_id)).def_id)\n        {\n            matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))\n        } else {\n            false\n        };\n\n        let is_exported = cx.effective_visibilities.is_exported(def_id);\n\n        self.check_fn_decl(\n            cx,\n            decl,\n            CheckTyContext {\n                is_in_trait_impl,\n                in_body: matches!(fn_kind, FnKind::Closure),\n                is_exported,\n                ..CheckTyContext::default()\n            },\n        );\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);\n\n        match item.kind {\n            ItemKind::Static(_, _, ty, _) | ItemKind::Const(_, _, ty, _) => self.check_ty(\n                cx,\n                ty,\n                CheckTyContext {\n                    is_exported,\n                    ..CheckTyContext::default()\n                },\n            ),\n            // functions, enums, structs, impls and traits are covered\n            _ => (),\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'tcx>) {\n        match item.kind {\n            ImplItemKind::Const(ty, _) => {\n                let is_in_trait_impl = if let hir::Node::Item(item) = cx\n                    .tcx\n                    .hir_node_by_def_id(cx.tcx.hir_get_parent_item(item.hir_id()).def_id)\n                {\n                    matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))\n                } else {\n                    false\n                };\n\n                self.check_ty(\n                    cx,\n                    ty,\n                    CheckTyContext {\n                        is_in_trait_impl,\n                        ..CheckTyContext::default()\n                    },\n                );\n            },\n            // Methods are covered by check_fn.\n            // Type aliases are ignored because oftentimes it's impossible to\n            // make type alias declaration in trait simpler, see #1013\n            ImplItemKind::Fn(..) | ImplItemKind::Type(..) => (),\n        }\n    }\n\n    fn check_field_def(&mut self, cx: &LateContext<'tcx>, field: &hir::FieldDef<'tcx>) {\n        if field.span.from_expansion() {\n            return;\n        }\n\n        let is_exported = cx.effective_visibilities.is_exported(field.def_id);\n\n        self.check_ty(\n            cx,\n            field.ty,\n            CheckTyContext {\n                is_exported,\n                ..CheckTyContext::default()\n            },\n        );\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'tcx>) {\n        let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);\n\n        let context = CheckTyContext {\n            is_exported,\n            ..CheckTyContext::default()\n        };\n\n        match item.kind {\n            TraitItemKind::Const(ty, _, _) | TraitItemKind::Type(_, Some(ty)) => {\n                self.check_ty(cx, ty, context);\n            },\n            TraitItemKind::Fn(ref sig, trait_method) => {\n                // Check only methods without body\n                // Methods with body are covered by check_fn.\n                if let TraitFn::Required(_) = trait_method {\n                    self.check_fn_decl(cx, sig.decl, context);\n                }\n            },\n            TraitItemKind::Type(..) => (),\n        }\n    }\n\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {\n        if let Some(ty) = local.ty {\n            self.check_ty(\n                cx,\n                ty,\n                CheckTyContext {\n                    in_body: true,\n                    ..CheckTyContext::default()\n                },\n            );\n        }\n    }\n}\n\nimpl Types {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            vec_box_size_threshold: conf.vec_box_size_threshold,\n            type_complexity_threshold: conf.type_complexity_threshold,\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n        }\n    }\n\n    fn check_fn_decl<'tcx>(&mut self, cx: &LateContext<'tcx>, decl: &FnDecl<'tcx>, context: CheckTyContext) {\n        // Ignore functions in trait implementations as they are usually forced by the trait definition.\n        //\n        // FIXME: ideally we would like to warn *if the complicated type can be simplified*, but it's hard\n        // to check.\n        if context.is_in_trait_impl {\n            return;\n        }\n\n        for input in decl.inputs {\n            self.check_ty(cx, input, context);\n        }\n\n        if let FnRetTy::Return(ty) = decl.output {\n            self.check_ty(cx, ty, context);\n        }\n    }\n\n    /// Recursively check for `TypePass` lints in the given type. Stop at the first\n    /// lint found.\n    ///\n    /// The parameter `is_local` distinguishes the context of the type.\n    fn check_ty<'tcx>(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, mut context: CheckTyContext) {\n        if hir_ty.span.from_expansion() {\n            return;\n        }\n\n        // Skip trait implementations; see issue #605.\n        if context.is_in_trait_impl {\n            return;\n        }\n\n        if !context.is_nested_call && type_complexity::check(cx, hir_ty, self.type_complexity_threshold) {\n            return;\n        }\n\n        match hir_ty.kind {\n            TyKind::Path(ref qpath) if !context.in_body => {\n                let hir_id = hir_ty.hir_id;\n                let res = cx.qpath_res(qpath, hir_id);\n                if let Some(def_id) = res.opt_def_id()\n                    && self.is_type_change_allowed(context)\n                {\n                    // All lints that are being checked in this block are guarded by\n                    // the `avoid_breaking_exported_api` configuration. When adding a\n                    // new lint, please also add the name to the configuration documentation\n                    // in `clippy_config::conf`\n\n                    let mut triggered = false;\n                    triggered |= box_collection::check(cx, hir_ty, qpath, def_id);\n                    triggered |= redundant_allocation::check(cx, hir_ty, qpath, def_id);\n                    triggered |= rc_buffer::check(cx, hir_ty, qpath, def_id);\n                    triggered |= vec_box::check(cx, hir_ty, qpath, def_id, self.vec_box_size_threshold);\n                    triggered |= option_option::check(cx, hir_ty, qpath, def_id);\n                    triggered |= linked_list::check(cx, hir_ty, def_id);\n                    triggered |= rc_mutex::check(cx, hir_ty, qpath, def_id);\n                    triggered |= owned_cow::check(cx, qpath, def_id);\n\n                    if triggered {\n                        return;\n                    }\n                }\n                match *qpath {\n                    QPath::Resolved(Some(ty), p) => {\n                        context.is_nested_call = true;\n                        self.check_ty(cx, ty, context);\n                        for ty in p.segments.iter().flat_map(|seg| {\n                            seg.args\n                                .as_ref()\n                                .map_or_else(|| [].iter(), |params| params.args.iter())\n                                .filter_map(|arg| match arg {\n                                    GenericArg::Type(ty) => Some(ty),\n                                    _ => None,\n                                })\n                        }) {\n                            self.check_ty(cx, ty.as_unambig_ty(), context);\n                        }\n                    },\n                    QPath::Resolved(None, p) => {\n                        context.is_nested_call = true;\n                        for ty in p.segments.iter().flat_map(|seg| {\n                            seg.args\n                                .as_ref()\n                                .map_or_else(|| [].iter(), |params| params.args.iter())\n                                .filter_map(|arg| match arg {\n                                    GenericArg::Type(ty) => Some(ty),\n                                    _ => None,\n                                })\n                        }) {\n                            self.check_ty(cx, ty.as_unambig_ty(), context);\n                        }\n                    },\n                    QPath::TypeRelative(ty, seg) => {\n                        context.is_nested_call = true;\n                        self.check_ty(cx, ty, context);\n                        if let Some(params) = seg.args {\n                            for ty in params.args.iter().filter_map(|arg| match arg {\n                                GenericArg::Type(ty) => Some(ty),\n                                _ => None,\n                            }) {\n                                self.check_ty(cx, ty.as_unambig_ty(), context);\n                            }\n                        }\n                    },\n                }\n            },\n            TyKind::Path(ref qpath) => {\n                let res = cx.qpath_res(qpath, hir_ty.hir_id);\n                if let Some(def_id) = res.opt_def_id()\n                    && self.is_type_change_allowed(context)\n                {\n                    owned_cow::check(cx, qpath, def_id);\n                }\n            },\n            TyKind::Ref(lt, ref mut_ty) => {\n                context.is_nested_call = true;\n                if !borrowed_box::check(cx, hir_ty, lt, mut_ty) {\n                    self.check_ty(cx, mut_ty.ty, context);\n                }\n            },\n            TyKind::Slice(ty) | TyKind::Array(ty, _) | TyKind::Ptr(MutTy { ty, .. }) => {\n                context.is_nested_call = true;\n                self.check_ty(cx, ty, context);\n            },\n            TyKind::Tup(tys) => {\n                context.is_nested_call = true;\n                for ty in tys {\n                    self.check_ty(cx, ty, context);\n                }\n            },\n            _ => {},\n        }\n    }\n\n    /// This function checks if the type is allowed to change in the current context\n    /// based on the `avoid_breaking_exported_api` configuration\n    fn is_type_change_allowed(&self, context: CheckTyContext) -> bool {\n        !(context.is_exported && self.avoid_breaking_exported_api)\n    }\n}\n\n#[expect(clippy::struct_excessive_bools)]\n#[derive(Clone, Copy, Default)]\nstruct CheckTyContext {\n    is_in_trait_impl: bool,\n    /// `true` for types on local variables and in closure signatures.\n    in_body: bool,\n    /// `true` for types that are part of the public API.\n    is_exported: bool,\n    is_nested_call: bool,\n}\n"
  },
  {
    "path": "clippy_lints/src/types/option_option.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::qpath_generic_tys;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{self as hir, QPath};\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::sym;\n\nuse super::OPTION_OPTION;\n\npub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {\n    if cx.tcx.is_diagnostic_item(sym::Option, def_id)\n        && let Some(arg) = qpath_generic_tys(qpath).next()\n        && arg.basic_res().opt_def_id() == Some(def_id)\n    {\n        span_lint_and_then(\n            cx,\n            OPTION_OPTION,\n            hir_ty.span,\n            // use just `T` here, as the inner type is not what's problematic\n            \"use of `Option<Option<T>>`\",\n            |diag| {\n                // but use the specific type here, as:\n                // - this is kind of a suggestion\n                // - it's printed right after the linted type\n                let inner_opt = snippet(cx, arg.span, \"_\");\n                diag.help(format!(\n                    \"consider using `{inner_opt}`, or a custom enum if you need to distinguish all 3 cases\"\n                ));\n            },\n        );\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/types/owned_cow.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet_opt;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_hir::def_id::DefId;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\npub(super) fn check(cx: &LateContext<'_>, qpath: &hir::QPath<'_>, def_id: DefId) -> bool {\n    if cx.tcx.is_diagnostic_item(sym::Cow, def_id)\n        && let hir::QPath::Resolved(_, path) = qpath\n        && let [.., last_seg] = path.segments\n        && let Some(args) = last_seg.args\n        && let [_lt, carg] = args.args\n        && let hir::GenericArg::Type(cty) = carg\n        && let Some((span, repl)) = replacement(cx, cty.as_unambig_ty())\n    {\n        span_lint_and_sugg(\n            cx,\n            super::OWNED_COW,\n            span,\n            \"needlessly owned Cow type\",\n            \"use\",\n            repl,\n            Applicability::Unspecified,\n        );\n        return true;\n    }\n    false\n}\n\nfn replacement(cx: &LateContext<'_>, cty: &hir::Ty<'_>) -> Option<(Span, String)> {\n    if cty.basic_res().is_lang_item(cx, hir::LangItem::String) {\n        return Some((cty.span, \"str\".into()));\n    }\n    if cty.basic_res().is_diag_item(cx, sym::Vec) {\n        return if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = cty.kind\n            && let [.., last_seg] = path.segments\n            && let Some(args) = last_seg.args\n            && let [t, ..] = args.args\n            && let Some(snip) = snippet_opt(cx, t.span())\n        {\n            Some((cty.span, format!(\"[{snip}]\")))\n        } else {\n            None\n        };\n    }\n    if cty.basic_res().is_diag_item(cx, sym::cstring_type) {\n        return Some((\n            cty.span,\n            (if clippy_utils::is_no_std_crate(cx) {\n                \"core::ffi::CStr\"\n            } else {\n                \"std::ffi::CStr\"\n            })\n            .into(),\n        ));\n    }\n    // Neither OsString nor PathBuf are available outside std\n    for (diag, repl) in [(sym::OsString, \"std::ffi::OsStr\"), (sym::PathBuf, \"std::path::Path\")] {\n        if cty.basic_res().is_diag_item(cx, diag) {\n            return Some((cty.span, repl.into()));\n        }\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/types/rc_buffer.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet_with_applicability;\nuse clippy_utils::{qpath_generic_tys, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{QPath, Ty, TyKind};\nuse rustc_lint::LateContext;\nuse std::borrow::Cow;\n\nuse super::RC_BUFFER;\n\npub(super) fn check(cx: &LateContext<'_>, hir_ty: &Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {\n    let mut app = Applicability::Unspecified;\n    let rc = match cx.tcx.get_diagnostic_name(def_id) {\n        Some(sym::Rc) => \"Rc\",\n        Some(sym::Arc) => \"Arc\",\n        _ => return false,\n    };\n    if let Some(ty) = qpath_generic_tys(qpath).next()\n        && let Some(alternate) = match_buffer_type(cx, ty, &mut app)\n    {\n        span_lint_and_then(\n            cx,\n            RC_BUFFER,\n            hir_ty.span,\n            format!(\"usage of `{rc}<T>` when `T` is a buffer type\"),\n            |diag| {\n                diag.span_suggestion_verbose(ty.span, \"try\", alternate, app);\n            },\n        );\n        true\n    } else {\n        false\n    }\n}\n\nfn match_buffer_type(\n    cx: &LateContext<'_>,\n    ty: &Ty<'_>,\n    applicability: &mut Applicability,\n) -> Option<Cow<'static, str>> {\n    let id = ty.basic_res().opt_def_id()?;\n    let path = match cx.tcx.get_diagnostic_name(id) {\n        Some(sym::OsString) => \"std::ffi::OsStr\".into(),\n        Some(sym::PathBuf) => \"std::path::Path\".into(),\n        Some(sym::Vec) => {\n            let TyKind::Path(vec_qpath) = &ty.kind else {\n                return None;\n            };\n            let vec_generic_ty = qpath_generic_tys(vec_qpath).next()?;\n            let snippet = snippet_with_applicability(cx, vec_generic_ty.span, \"_\", applicability);\n            format!(\"[{snippet}]\").into()\n        },\n        _ if Some(id) == cx.tcx.lang_items().string() => \"str\".into(),\n        _ => return None,\n    };\n    Some(path)\n}\n"
  },
  {
    "path": "clippy_lints/src/types/rc_mutex.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::qpath_generic_tys;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{self as hir, QPath};\nuse rustc_lint::LateContext;\nuse rustc_span::symbol::sym;\n\nuse super::RC_MUTEX;\n\npub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {\n    if cx.tcx.is_diagnostic_item(sym::Rc, def_id)\n        && let Some(arg) = qpath_generic_tys(qpath).next()\n        && arg.basic_res().is_diag_item(cx, sym::Mutex)\n    {\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(cx, RC_MUTEX, hir_ty.span, \"usage of `Rc<Mutex<_>>`\", |diag| {\n            diag.help(\"consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead\");\n        });\n        return true;\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/types/redundant_allocation.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::qpath_generic_tys;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::{snippet, snippet_with_applicability};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{self as hir, QPath, TyKind};\nuse rustc_hir_analysis::lower_ty;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::TypeVisitableExt;\nuse rustc_span::symbol::sym;\n\nuse super::{REDUNDANT_ALLOCATION, utils};\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath: &QPath<'tcx>, def_id: DefId) -> bool {\n    let mut applicability = Applicability::MaybeIncorrect;\n    let outer_sym = match cx.tcx.get_diagnostic_name(def_id) {\n        _ if Some(def_id) == cx.tcx.lang_items().owned_box() => \"Box\",\n        Some(sym::Rc) => \"Rc\",\n        Some(sym::Arc) => \"Arc\",\n        _ => return false,\n    };\n\n    if let Some(span) = utils::match_borrows_parameter(cx, qpath) {\n        let generic_snippet = snippet_with_applicability(cx, span, \"..\", &mut applicability);\n        span_lint_and_then(\n            cx,\n            REDUNDANT_ALLOCATION,\n            hir_ty.span,\n            format!(\"usage of `{outer_sym}<{generic_snippet}>`\"),\n            |diag| {\n                diag.span_suggestion(hir_ty.span, \"try\", format!(\"{generic_snippet}\"), applicability);\n                diag.note(format!(\n                    \"`{generic_snippet}` is already a pointer, `{outer_sym}<{generic_snippet}>` allocates a pointer on the heap\"\n                ));\n            },\n        );\n        return true;\n    }\n\n    let Some(ty) = qpath_generic_tys(qpath).next() else {\n        return false;\n    };\n    let Some(id) = ty.basic_res().opt_def_id() else {\n        return false;\n    };\n    let (inner_sym, ty) = match cx.tcx.get_diagnostic_name(id) {\n        Some(sym::Arc) => (\"Arc\", ty),\n        Some(sym::Rc) => (\"Rc\", ty),\n        _ if Some(id) == cx.tcx.lang_items().owned_box() => (\"Box\", ty),\n        _ => return false,\n    };\n\n    let TyKind::Path(inner_qpath) = &ty.kind else {\n        return false;\n    };\n    let inner_span = match qpath_generic_tys(inner_qpath).next() {\n        Some(hir_ty) => {\n            // Reallocation of a fat pointer causes it to become thin. `lower_ty` is safe to use\n            // here because `mod.rs` guarantees this lint is only run on types outside of bodies and\n            // is not run on locals.\n            let ty = lower_ty(cx.tcx, hir_ty);\n            if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.typing_env()) {\n                return false;\n            }\n            hir_ty.span\n        },\n        None => return false,\n    };\n    if inner_sym == outer_sym {\n        let generic_snippet = snippet_with_applicability(cx, inner_span, \"..\", &mut applicability);\n        span_lint_and_then(\n            cx,\n            REDUNDANT_ALLOCATION,\n            hir_ty.span,\n            format!(\"usage of `{outer_sym}<{inner_sym}<{generic_snippet}>>`\"),\n            |diag| {\n                diag.span_suggestion(\n                    hir_ty.span,\n                    \"try\",\n                    format!(\"{outer_sym}<{generic_snippet}>\"),\n                    applicability,\n                );\n                diag.note(format!(\n                    \"`{inner_sym}<{generic_snippet}>` is already on the heap, `{outer_sym}<{inner_sym}<{generic_snippet}>>` makes an extra allocation\"\n                ));\n            },\n        );\n    } else {\n        let generic_snippet = snippet(cx, inner_span, \"..\");\n        span_lint_and_then(\n            cx,\n            REDUNDANT_ALLOCATION,\n            hir_ty.span,\n            format!(\"usage of `{outer_sym}<{inner_sym}<{generic_snippet}>>`\"),\n            |diag| {\n                diag.note(format!(\n                    \"`{inner_sym}<{generic_snippet}>` is already on the heap, `{outer_sym}<{inner_sym}<{generic_snippet}>>` makes an extra allocation\"\n                ));\n                diag.help(format!(\n                    \"consider using just `{outer_sym}<{generic_snippet}>` or `{inner_sym}<{generic_snippet}>`\"\n                ));\n            },\n        );\n    }\n    true\n}\n"
  },
  {
    "path": "clippy_lints/src/types/type_complexity.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_abi::ExternAbi;\nuse rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};\nuse rustc_hir::{self as hir, AmbigArg, GenericParamKind, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::TYPE_COMPLEXITY;\n\npub(super) fn check(cx: &LateContext<'_>, ty: &hir::Ty<'_>, type_complexity_threshold: u64) -> bool {\n    let score = {\n        let mut visitor = TypeComplexityVisitor { score: 0, nest: 1 };\n        visitor.visit_ty_unambig(ty);\n        visitor.score\n    };\n\n    if score > type_complexity_threshold {\n        span_lint(\n            cx,\n            TYPE_COMPLEXITY,\n            ty.span,\n            \"very complex type used. Consider factoring parts into `type` definitions\",\n        );\n        true\n    } else {\n        false\n    }\n}\n\n/// Walks a type and assigns a complexity score to it.\nstruct TypeComplexityVisitor {\n    /// total complexity score of the type\n    score: u64,\n    /// current nesting level\n    nest: u64,\n}\n\nimpl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {\n    fn visit_infer(&mut self, inf_id: hir::HirId, _inf_span: Span, _kind: InferKind<'tcx>) -> Self::Result {\n        self.score += 1;\n        self.visit_id(inf_id);\n    }\n\n    fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_, AmbigArg>) {\n        let (add_score, sub_nest) = match ty.kind {\n            // &x and *x have only small overhead; don't mess with nesting level\n            TyKind::Ptr(..) | TyKind::Ref(..) => (1, 0),\n\n            // the \"normal\" components of a type: named types, arrays/tuples\n            TyKind::Path(..) | TyKind::Slice(..) | TyKind::Tup(..) | TyKind::Array(..) => (10 * self.nest, 1),\n\n            // function types bring a lot of overhead\n            TyKind::FnPtr(fn_ptr) if fn_ptr.abi == ExternAbi::Rust => (50 * self.nest, 1),\n\n            TyKind::TraitObject(param_bounds, _) => {\n                let has_lifetime_parameters = param_bounds.iter().any(|bound| {\n                    bound\n                        .bound_generic_params\n                        .iter()\n                        .any(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))\n                });\n                if has_lifetime_parameters {\n                    // complex trait bounds like A<'a, 'b>\n                    (50 * self.nest, 1)\n                } else {\n                    // simple trait bounds like A + B\n                    (20 * self.nest, 0)\n                }\n            },\n\n            _ => (0, 0),\n        };\n        self.score += add_score;\n        self.nest += sub_nest;\n        walk_ty(self, ty);\n        self.nest -= sub_nest;\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/types/utils.rs",
    "content": "use clippy_utils::last_path_segment;\nuse rustc_hir::{GenericArg, GenericArgsParentheses, QPath, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\npub(super) fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Span> {\n    let last = last_path_segment(qpath);\n    if let Some(params) = last.args\n        && params.parenthesized == GenericArgsParentheses::No\n        && let Some(ty) = params.args.iter().find_map(|arg| match arg {\n            GenericArg::Type(ty) => Some(ty),\n            _ => None,\n        })\n        && let TyKind::Ref(..) = ty.kind\n    {\n        return Some(ty.span);\n    }\n    None\n}\n"
  },
  {
    "path": "clippy_lints/src/types/vec_box.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::last_path_segment;\nuse clippy_utils::source::snippet;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind};\nuse rustc_hir_analysis::lower_ty;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::TypeVisitableExt;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_span::symbol::sym;\n\nuse super::VEC_BOX;\n\npub(super) fn check<'tcx>(\n    cx: &LateContext<'tcx>,\n    hir_ty: &hir::Ty<'_>,\n    qpath: &QPath<'tcx>,\n    def_id: DefId,\n    box_size_threshold: u64,\n) -> bool {\n    if cx.tcx.is_diagnostic_item(sym::Vec, def_id)\n        && let Some(last) = last_path_segment(qpath).args\n        // Get the _ part of Vec<_>\n        && let Some(GenericArg::Type(ty)) = last.args.first()\n        // extract allocator from the Vec for later\n        && let vec_alloc_ty = last.args.get(1)\n        // ty is now _ at this point\n        && let TyKind::Path(ref ty_qpath) = ty.kind\n        && let res = cx.qpath_res(ty_qpath, ty.hir_id)\n        && let Some(def_id) = res.opt_def_id()\n        && Some(def_id) == cx.tcx.lang_items().owned_box()\n        // At this point, we know ty is Box<T>, now get T\n        && let Some(last) = last_path_segment(ty_qpath).args\n        && let Some(GenericArg::Type(boxed_ty)) = last.args.first()\n        // extract allocator from the Box for later\n        && let boxed_alloc_ty = last.args.get(1)\n        // we don't expect to encounter `_` here so ignore `GenericArg::Infer` is okay\n        && let ty_ty = lower_ty(cx.tcx, boxed_ty.as_unambig_ty())\n        && !ty_ty.has_escaping_bound_vars()\n        && ty_ty.is_sized(cx.tcx, cx.typing_env())\n        && let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes())\n        && ty_ty_size < box_size_threshold\n        // https://github.com/rust-lang/rust-clippy/issues/7114\n        && match (vec_alloc_ty, boxed_alloc_ty) {\n            (None, None) => true,\n            // this is in the event that we have something like\n            // Vec<_, Global>, in which case is equivalent to\n            // Vec<_>\n            (None, Some(GenericArg::Type(inner))) | (Some(GenericArg::Type(inner)), None) => {\n                if let TyKind::Path(path) = inner.kind\n                    && let Some(did) = cx.qpath_res(&path, inner.hir_id).opt_def_id() {\n                    cx.tcx.lang_items().get(LangItem::GlobalAlloc) == Some(did)\n                } else {\n                    false\n                }\n            },\n            (Some(GenericArg::Type(l)), Some(GenericArg::Type(r))) =>\n                // we don't expect to encounter `_` here so ignore `GenericArg::Infer` is okay\n                lower_ty(cx.tcx, l.as_unambig_ty()) == lower_ty(cx.tcx, r.as_unambig_ty()),\n            _ => false\n        }\n    {\n        span_lint_and_sugg(\n            cx,\n            VEC_BOX,\n            hir_ty.span,\n            \"`Vec<T>` is already on the heap, the boxing is unnecessary\",\n            \"try\",\n            format!(\"Vec<{}>\", snippet(cx, boxed_ty.span, \"..\")),\n            Applicability::Unspecified,\n        );\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unconditional_recursion.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::MaybeQPath;\nuse clippy_utils::{expr_or_init, fn_def_id_with_node_args, sym};\nuse rustc_ast::BinOpKind;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir as hir;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::{DefId, LocalDefId};\nuse rustc_hir::intravisit::{FnKind, Visitor, walk_body, walk_expr};\nuse rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind};\nuse rustc_hir_analysis::lower_ty;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::{self, Ty, TyCtxt};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::{Ident, kw};\nuse rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks that there isn't an infinite recursion in trait\n    /// implementations.\n    ///\n    /// ### Why is this bad?\n    /// Infinite recursion in trait implementation will either cause crashes\n    /// or result in an infinite loop, and it is hard to detect.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// enum Foo {\n    ///     A,\n    ///     B,\n    /// }\n    ///\n    /// impl PartialEq for Foo {\n    ///     fn eq(&self, other: &Self) -> bool {\n    ///         self == other // bad!\n    ///     }\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    ///\n    /// ```no_run\n    /// #[derive(PartialEq)]\n    /// enum Foo {\n    ///     A,\n    ///     B,\n    /// }\n    /// ```\n    ///\n    /// As an alternative, rewrite the logic without recursion:\n    ///\n    /// ```no_run\n    /// enum Foo {\n    ///     A,\n    ///     B,\n    /// }\n    ///\n    /// impl PartialEq for Foo {\n    ///     fn eq(&self, other: &Self) -> bool {\n    ///         matches!((self, other), (Foo::A, Foo::A) | (Foo::B, Foo::B))\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.77.0\"]\n    pub UNCONDITIONAL_RECURSION,\n    suspicious,\n    \"detect unconditional recursion in some traits implementation\"\n}\n\nimpl_lint_pass!(UnconditionalRecursion => [UNCONDITIONAL_RECURSION]);\n\n#[derive(Default)]\npub struct UnconditionalRecursion {\n    /// The key is the `DefId` of the type implementing the `Default` trait and the value is the\n    /// `DefId` of the return call.\n    default_impl_for_type: FxHashMap<DefId, DefId>,\n}\n\nfn span_error(cx: &LateContext<'_>, method_span: Span, expr: &Expr<'_>) {\n    span_lint_and_then(\n        cx,\n        UNCONDITIONAL_RECURSION,\n        method_span,\n        \"function cannot return without recursing\",\n        |diag| {\n            diag.span_note(expr.span, \"recursive call site\");\n        },\n    );\n}\n\nfn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Option<DefId> {\n    let TyKind::Path(qpath) = hir_ty.kind else { return None };\n    match qpath {\n        QPath::Resolved(_, path) => path.res.opt_def_id(),\n        QPath::TypeRelative(_, _) => {\n            let ty = lower_ty(tcx, &hir_ty);\n\n            match ty.kind() {\n                ty::Alias(ty::Projection, proj) => {\n                    Res::<HirId>::Def(DefKind::Trait, proj.trait_ref(tcx).def_id).opt_def_id()\n                },\n                _ => None,\n            }\n        },\n    }\n}\n\nfn get_return_calls_in_body<'tcx>(body: &'tcx Body<'tcx>) -> Vec<&'tcx Expr<'tcx>> {\n    let mut visitor = ReturnsVisitor::default();\n\n    visitor.visit_body(body);\n    visitor.returns\n}\n\nfn has_conditional_return(body: &Body<'_>, expr: &Expr<'_>) -> bool {\n    match get_return_calls_in_body(body).as_slice() {\n        [] => false,\n        [return_expr] => return_expr.hir_id != expr.hir_id,\n        _ => true,\n    }\n}\n\nfn get_impl_trait_def_id(cx: &LateContext<'_>, method_def_id: LocalDefId) -> Option<DefId> {\n    let hir_id = cx.tcx.local_def_id_to_hir_id(method_def_id);\n    if let Some((\n        _,\n        Node::Item(Item {\n            kind: ItemKind::Impl(impl_),\n            owner_id,\n            ..\n        }),\n    )) = cx.tcx.hir_parent_iter(hir_id).next()\n        // We exclude `impl` blocks generated from rustc's proc macros.\n        && !cx.tcx.is_automatically_derived(owner_id.to_def_id())\n        // It is a implementation of a trait.\n        && let Some(of_trait) = impl_.of_trait\n    {\n        of_trait.trait_ref.trait_def_id()\n    } else {\n        None\n    }\n}\n\n/// When we have `x == y` where `x = &T` and `y = &T`, then that resolves to\n/// `<&T as PartialEq<&T>>::eq`, which is not the same as `<T as PartialEq<T>>::eq`,\n/// however we still would want to treat it the same, because we know that it's a blanket impl\n/// that simply delegates to the `PartialEq` impl with one reference removed.\n///\n/// Still, we can't just do `lty.peel_refs() == rty.peel_refs()` because when we have `x = &T` and\n/// `y = &&T`, this is not necessarily the same as `<T as PartialEq<T>>::eq`\n///\n/// So to avoid these FNs and FPs, we keep removing a layer of references from *both* sides\n/// until both sides match the expected LHS and RHS type (or they don't).\nfn matches_ty<'tcx>(\n    mut left: Ty<'tcx>,\n    mut right: Ty<'tcx>,\n    expected_left: Ty<'tcx>,\n    expected_right: Ty<'tcx>,\n) -> bool {\n    while let (&ty::Ref(_, lty, _), &ty::Ref(_, rty, _)) = (left.kind(), right.kind()) {\n        if lty == expected_left && rty == expected_right {\n            return true;\n        }\n        left = lty;\n        right = rty;\n    }\n    false\n}\n\nfn check_partial_eq(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId, name: Ident, expr: &Expr<'_>) {\n    let Some(sig) = cx\n        .typeck_results()\n        .liberated_fn_sigs()\n        .get(cx.tcx.local_def_id_to_hir_id(method_def_id))\n    else {\n        return;\n    };\n\n    // That has two arguments.\n    if let [self_arg, other_arg] = sig.inputs()\n        && let &ty::Ref(_, self_arg, _) = self_arg.kind()\n        && let &ty::Ref(_, other_arg, _) = other_arg.kind()\n        // The two arguments are of the same type.\n        && let Some(trait_def_id) = get_impl_trait_def_id(cx, method_def_id)\n        // The trait is `PartialEq`.\n        && cx.tcx.is_diagnostic_item(sym::PartialEq, trait_def_id)\n    {\n        let to_check_op = if name.name == sym::eq {\n            BinOpKind::Eq\n        } else {\n            BinOpKind::Ne\n        };\n        let is_bad = match expr.kind {\n            ExprKind::Binary(op, left, right) if op.node == to_check_op => {\n                // Then we check if the LHS matches self_arg and RHS matches other_arg\n                let left_ty = cx.typeck_results().expr_ty_adjusted(left);\n                let right_ty = cx.typeck_results().expr_ty_adjusted(right);\n                matches_ty(left_ty, right_ty, self_arg, other_arg)\n            },\n            ExprKind::MethodCall(segment, receiver, [arg], _) if segment.ident.name == name.name => {\n                let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver);\n                let arg_ty = cx.typeck_results().expr_ty_adjusted(arg);\n\n                if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n                    && let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id)\n                    && trait_id == trait_def_id\n                    && matches_ty(receiver_ty, arg_ty, self_arg, other_arg)\n                {\n                    true\n                } else {\n                    false\n                }\n            },\n            _ => false,\n        };\n        if is_bad {\n            span_error(cx, method_span, expr);\n        }\n    }\n}\n\nfn check_to_string(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId, name: Ident, expr: &Expr<'_>) {\n    let args = cx\n        .tcx\n        .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(method_def_id).skip_binder())\n        .inputs();\n    // That has one argument.\n    if let [_self_arg] = args\n        && let hir_id = cx.tcx.local_def_id_to_hir_id(method_def_id)\n        && let Some((\n            _,\n            Node::Item(Item {\n                kind: ItemKind::Impl(impl_),\n                owner_id,\n                ..\n            }),\n        )) = cx.tcx.hir_parent_iter(hir_id).next()\n        // We exclude `impl` blocks generated from rustc's proc macros.\n        && !cx.tcx.is_automatically_derived(owner_id.to_def_id())\n        // It is a implementation of a trait.\n        && let Some(of_trait) = impl_.of_trait\n        && let Some(trait_def_id) = of_trait.trait_ref.trait_def_id()\n        // The trait is `ToString`.\n        && cx.tcx.is_diagnostic_item(sym::ToString, trait_def_id)\n    {\n        let is_bad = match expr.kind {\n            ExprKind::MethodCall(segment, _receiver, &[_arg], _) if segment.ident.name == name.name => {\n                if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n                    && let Some(trait_id) = cx.tcx.trait_of_assoc(fn_id)\n                    && trait_id == trait_def_id\n                {\n                    true\n                } else {\n                    false\n                }\n            },\n            _ => false,\n        };\n        if is_bad {\n            span_error(cx, method_span, expr);\n        }\n    }\n}\n\nfn is_default_method_on_current_ty<'tcx>(tcx: TyCtxt<'tcx>, qpath: QPath<'tcx>, implemented_ty_id: DefId) -> bool {\n    match qpath {\n        QPath::Resolved(_, path) => match path.segments {\n            [first, .., last] => last.ident.name == kw::Default && first.res.opt_def_id() == Some(implemented_ty_id),\n            _ => false,\n        },\n        QPath::TypeRelative(ty, segment) => {\n            if segment.ident.name != kw::Default {\n                return false;\n            }\n            if matches!(\n                ty.kind,\n                TyKind::Path(QPath::Resolved(\n                    _,\n                    hir::Path {\n                        res: Res::SelfTyAlias { .. },\n                        ..\n                    },\n                ))\n            ) {\n                return true;\n            }\n            get_hir_ty_def_id(tcx, *ty) == Some(implemented_ty_id)\n        },\n    }\n}\n\nstruct CheckCalls<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    implemented_ty_id: DefId,\n    method_span: Span,\n}\n\nimpl<'a, 'tcx> Visitor<'tcx> for CheckCalls<'a, 'tcx>\nwhere\n    'tcx: 'a,\n{\n    type NestedFilter = nested_filter::OnlyBodies;\n    type Result = ControlFlow<()>;\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {\n        walk_expr(self, expr)?;\n\n        if let ExprKind::Call(f, _) = expr.kind\n            && let ExprKind::Path(qpath) = f.kind\n            && is_default_method_on_current_ty(self.cx.tcx, qpath, self.implemented_ty_id)\n            && let Some(method_def_id) = f.res(self.cx).opt_def_id()\n            && let Some(trait_def_id) = self.cx.tcx.trait_of_assoc(method_def_id)\n            && self.cx.tcx.is_diagnostic_item(sym::Default, trait_def_id)\n        {\n            span_error(self.cx, self.method_span, expr);\n            return ControlFlow::Break(());\n        }\n        ControlFlow::Continue(())\n    }\n}\n\nimpl UnconditionalRecursion {\n    fn init_default_impl_for_type_if_needed(&mut self, cx: &LateContext<'_>) {\n        if self.default_impl_for_type.is_empty()\n            && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)\n        {\n            let impls = cx.tcx.trait_impls_of(default_trait_id);\n            for (ty, impl_def_ids) in impls.non_blanket_impls() {\n                let Some(self_def_id) = ty.def() else { continue };\n                for &impl_def_id in impl_def_ids {\n                    if !cx.tcx.is_automatically_derived(impl_def_id) &&\n                        let Some(assoc_item) = cx\n                            .tcx\n                            .associated_items(impl_def_id)\n                            .in_definition_order()\n                            // We're not interested in foreign implementations of the `Default` trait.\n                            .find(|item| {\n                                item.is_fn() && item.def_id.is_local() && item.name() == kw::Default\n                            })\n                        && let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id)\n                        && let Some(body_id) = body_node.body_id()\n                        && let body = cx.tcx.hir_body(body_id)\n                        // We don't want to keep it if it has conditional return.\n                        && let [return_expr] = get_return_calls_in_body(body).as_slice()\n                        && let ExprKind::Call(call_expr, _) = return_expr.kind\n                        // We need to use typeck here to infer the actual function being called.\n                        && let body_def_id = cx.tcx.hir_enclosing_body_owner(call_expr.hir_id)\n                        && let Some(body_owner) = cx.tcx.hir_maybe_body_owned_by(body_def_id)\n                        && let typeck = cx.tcx.typeck_body(body_owner.id())\n                        && let Some(call_def_id) = typeck.type_dependent_def_id(call_expr.hir_id)\n                    {\n                        self.default_impl_for_type.insert(self_def_id, call_def_id);\n                    }\n                }\n            }\n        }\n    }\n\n    fn check_default_new<'tcx>(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        decl: &FnDecl<'tcx>,\n        body: &'tcx Body<'tcx>,\n        method_span: Span,\n        method_def_id: LocalDefId,\n    ) {\n        // We're only interested into static methods.\n        if decl.implicit_self.has_implicit_self() {\n            return;\n        }\n        // We don't check trait implementations.\n        if get_impl_trait_def_id(cx, method_def_id).is_some() {\n            return;\n        }\n\n        let hir_id = cx.tcx.local_def_id_to_hir_id(method_def_id);\n        if let Some((\n            _,\n            Node::Item(Item {\n                kind: ItemKind::Impl(impl_),\n                ..\n            }),\n        )) = cx.tcx.hir_parent_iter(hir_id).next()\n            && let Some(implemented_ty_id) = get_hir_ty_def_id(cx.tcx, *impl_.self_ty)\n            && {\n                self.init_default_impl_for_type_if_needed(cx);\n                true\n            }\n            && let Some(return_def_id) = self.default_impl_for_type.get(&implemented_ty_id)\n            && method_def_id.to_def_id() == *return_def_id\n        {\n            let mut c = CheckCalls {\n                cx,\n                implemented_ty_id,\n                method_span,\n            };\n            let _ = walk_body(&mut c, body);\n        }\n    }\n}\n\nfn check_from(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId, expr: &Expr<'_>) {\n    let Some(sig) = cx\n        .typeck_results()\n        .liberated_fn_sigs()\n        .get(cx.tcx.local_def_id_to_hir_id(method_def_id))\n    else {\n        return;\n    };\n\n    // Check if we are calling `Into::into` where the node args match with our `From::from` signature:\n    // From::from signature: fn(S1) -> S2\n    // <S1 as Into<S2>>::into(s1), node_args=[S1, S2]\n    // If they do match, then it must mean that it is the blanket impl,\n    // which calls back into our `From::from` again (`Into` is not specializable).\n    // rustc's unconditional_recursion already catches calling `From::from` directly\n    if let Some((fn_def_id, node_args)) = fn_def_id_with_node_args(cx, expr)\n        && let [s1, s2] = **node_args\n        && let (Some(s1), Some(s2)) = (s1.as_type(), s2.as_type())\n        && let Some(trait_def_id) = cx.tcx.trait_of_assoc(fn_def_id)\n        && cx.tcx.is_diagnostic_item(sym::Into, trait_def_id)\n        && get_impl_trait_def_id(cx, method_def_id) == cx.tcx.get_diagnostic_item(sym::From)\n        && s1 == sig.inputs()[0]\n        && s2 == sig.output()\n    {\n        span_error(cx, method_span, expr);\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnconditionalRecursion {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'tcx>,\n        body: &'tcx Body<'tcx>,\n        method_span: Span,\n        method_def_id: LocalDefId,\n    ) {\n        // If the function is a method...\n        if let FnKind::Method(name, _) = kind\n            && let expr = expr_or_init(cx, body.value).peel_blocks()\n            // Doesn't have a conditional return.\n            && !has_conditional_return(body, expr)\n        {\n            match name.name {\n                sym::eq | sym::ne => check_partial_eq(cx, method_span, method_def_id, name, expr),\n                sym::to_string => check_to_string(cx, method_span, method_def_id, name, expr),\n                sym::from => check_from(cx, method_span, method_def_id, expr),\n                _ => {},\n            }\n            self.check_default_new(cx, decl, body, method_span, method_def_id);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/undocumented_unsafe_blocks.rs",
    "content": "use std::ops::ControlFlow;\nuse std::sync::Arc;\n\nuse clippy_config::Conf;\nuse clippy_utils::consts::const_item_rhs_to_expr;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_lint_allowed;\nuse clippy_utils::source::walk_span_to_context;\nuse clippy_utils::visitors::{Descend, for_each_expr};\nuse hir::HirId;\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, Block, BlockCheckMode, FnSig, Impl, ItemKind, Node, UnsafeSource};\nuse rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{BytePos, Pos, RelativeBytePos, Span, SyntaxContext};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `unsafe` blocks and impls without a `// SAFETY: ` comment\n    /// explaining why the unsafe operations performed inside\n    /// the block are safe.\n    ///\n    /// Note the comment must appear on the line(s) preceding the unsafe block\n    /// with nothing appearing in between. The following is ok:\n    /// ```ignore\n    /// foo(\n    ///     // SAFETY:\n    ///     // This is a valid safety comment\n    ///     unsafe { *x }\n    /// )\n    /// ```\n    /// But neither of these are:\n    /// ```ignore\n    /// // SAFETY:\n    /// // This is not a valid safety comment\n    /// foo(\n    ///     /* SAFETY: Neither is this */ unsafe { *x },\n    /// );\n    /// ```\n    ///\n    /// ### Why restrict this?\n    /// Undocumented unsafe blocks and impls can make it difficult to read and maintain code.\n    /// Writing out the safety justification may help in discovering unsoundness or bugs.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::ptr::NonNull;\n    /// let a = &mut 42;\n    ///\n    /// let ptr = unsafe { NonNull::new_unchecked(a) };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::ptr::NonNull;\n    /// let a = &mut 42;\n    ///\n    /// // SAFETY: references are guaranteed to be non-null.\n    /// let ptr = unsafe { NonNull::new_unchecked(a) };\n    /// ```\n    #[clippy::version = \"1.58.0\"]\n    pub UNDOCUMENTED_UNSAFE_BLOCKS,\n    restriction,\n    \"creating an unsafe block without explaining why it is safe\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `// SAFETY: ` comments on safe code.\n    ///\n    /// ### Why restrict this?\n    /// Safe code has no safety requirements, so there is no need to\n    /// describe safety invariants.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::ptr::NonNull;\n    /// let a = &mut 42;\n    ///\n    /// // SAFETY: references are guaranteed to be non-null.\n    /// let ptr = NonNull::new(a).unwrap();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::ptr::NonNull;\n    /// let a = &mut 42;\n    ///\n    /// let ptr = NonNull::new(a).unwrap();\n    /// ```\n    #[clippy::version = \"1.67.0\"]\n    pub UNNECESSARY_SAFETY_COMMENT,\n    restriction,\n    \"annotating safe code with a safety comment\"\n}\n\nimpl_lint_pass!(UndocumentedUnsafeBlocks => [\n    UNDOCUMENTED_UNSAFE_BLOCKS,\n    UNNECESSARY_SAFETY_COMMENT,\n]);\n\npub struct UndocumentedUnsafeBlocks {\n    accept_comment_above_statement: bool,\n    accept_comment_above_attributes: bool,\n}\n\nimpl UndocumentedUnsafeBlocks {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            accept_comment_above_statement: conf.accept_comment_above_statement,\n            accept_comment_above_attributes: conf.accept_comment_above_attributes,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {\n        if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)\n            && !block.span.in_external_macro(cx.tcx.sess.source_map())\n            && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)\n            && !is_unsafe_from_proc_macro(cx, block.span)\n            && !block_has_safety_comment(cx, block.span, self.accept_comment_above_attributes)\n            && !block_has_inner_safety_comment(cx, block.span)\n            && !block_parents_have_safety_comment(\n                self.accept_comment_above_statement,\n                self.accept_comment_above_attributes,\n                cx,\n                block.hir_id,\n            )\n        {\n            let source_map = cx.tcx.sess.source_map();\n            let span = if source_map.is_multiline(block.span) {\n                source_map.span_until_char(block.span, '\\n')\n            } else {\n                block.span\n            };\n\n            #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n            span_lint_and_then(\n                cx,\n                UNDOCUMENTED_UNSAFE_BLOCKS,\n                span,\n                \"unsafe block missing a safety comment\",\n                |diag| {\n                    diag.help(\"consider adding a safety comment on the preceding line\");\n                },\n            );\n        }\n\n        if let Some(tail) = block.expr\n            && !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, tail.hir_id)\n            && !tail.span.in_external_macro(cx.tcx.sess.source_map())\n            && let HasSafetyComment::Yes(pos, _) =\n                stmt_has_safety_comment(cx, tail.span, tail.hir_id, self.accept_comment_above_attributes)\n            && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, tail, pos)\n        {\n            span_lint_and_then(\n                cx,\n                UNNECESSARY_SAFETY_COMMENT,\n                tail.span,\n                \"expression has unnecessary safety comment\",\n                |diag| {\n                    diag.span_help(help_span, \"consider removing the safety comment\");\n                },\n            );\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &hir::Stmt<'tcx>) {\n        let (hir::StmtKind::Let(&hir::LetStmt { init: Some(expr), .. })\n        | hir::StmtKind::Expr(expr)\n        | hir::StmtKind::Semi(expr)) = stmt.kind\n        else {\n            return;\n        };\n        if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, stmt.hir_id)\n            && !stmt.span.in_external_macro(cx.tcx.sess.source_map())\n            && let HasSafetyComment::Yes(pos, _) =\n                stmt_has_safety_comment(cx, stmt.span, stmt.hir_id, self.accept_comment_above_attributes)\n            && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, expr, pos)\n        {\n            span_lint_and_then(\n                cx,\n                UNNECESSARY_SAFETY_COMMENT,\n                stmt.span,\n                \"statement has unnecessary safety comment\",\n                |diag| {\n                    diag.span_help(help_span, \"consider removing the safety comment\");\n                },\n            );\n        }\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &hir::Item<'tcx>) {\n        if item.span.in_external_macro(cx.tcx.sess.source_map()) {\n            return;\n        }\n\n        let mk_spans = |pos: BytePos| {\n            let source_map = cx.tcx.sess.source_map();\n            let help_span = Span::new(\n                pos,\n                pos + BytePos(u32::try_from(\"SAFETY:\".len()).unwrap()),\n                SyntaxContext::root(),\n                None,\n            );\n            let span = if source_map.is_multiline(item.span) {\n                source_map.span_until_char(item.span, '\\n')\n            } else {\n                item.span\n            };\n            (span, help_span)\n        };\n\n        let item_has_safety_comment = item_has_safety_comment(cx, item, self.accept_comment_above_attributes);\n        match item_has_safety_comment {\n            HasSafetyComment::Yes(pos, is_doc) => check_has_safety_comment(cx, item, mk_spans(pos), is_doc),\n            HasSafetyComment::No => check_has_no_safety_comment(cx, item),\n            HasSafetyComment::Maybe => {},\n        }\n    }\n}\n\n#[expect(clippy::too_many_lines)]\nfn check_has_safety_comment<'tcx>(\n    cx: &LateContext<'tcx>,\n    item: &hir::Item<'tcx>,\n    (span, help_span): (Span, Span),\n    is_doc: bool,\n) {\n    match &item.kind {\n        ItemKind::Impl(Impl {\n            of_trait: Some(of_trait),\n            ..\n        }) if of_trait.safety.is_safe() => {\n            if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {\n                span_lint_and_then(\n                    cx,\n                    UNNECESSARY_SAFETY_COMMENT,\n                    span,\n                    \"impl has unnecessary safety comment\",\n                    |diag| {\n                        diag.span_help(help_span, \"consider removing the safety comment\");\n                    },\n                );\n            }\n        },\n        ItemKind::Impl(_) => {},\n        // const and static items only need a safety comment if their body is an unsafe block, lint otherwise\n        &ItemKind::Const(.., ct_rhs) => {\n            if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, ct_rhs.hir_id()) {\n                let expr = const_item_rhs_to_expr(cx.tcx, ct_rhs);\n                if let Some(expr) = expr\n                    && !matches!(\n                        expr.kind, hir::ExprKind::Block(block, _)\n                        if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)\n                    )\n                {\n                    span_lint_and_then(\n                        cx,\n                        UNNECESSARY_SAFETY_COMMENT,\n                        span,\n                        format!(\n                            \"{} has unnecessary safety comment\",\n                            cx.tcx.def_descr(item.owner_id.to_def_id()),\n                        ),\n                        |diag| {\n                            diag.span_help(help_span, \"consider removing the safety comment\");\n                        },\n                    );\n                }\n            }\n        },\n        &ItemKind::Static(.., body) => {\n            if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) {\n                let body = cx.tcx.hir_body(body);\n                if !matches!(\n                    body.value.kind, hir::ExprKind::Block(block, _)\n                    if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)\n                ) {\n                    span_lint_and_then(\n                        cx,\n                        UNNECESSARY_SAFETY_COMMENT,\n                        span,\n                        format!(\n                            \"{} has unnecessary safety comment\",\n                            cx.tcx.def_descr(item.owner_id.to_def_id()),\n                        ),\n                        |diag| {\n                            diag.span_help(help_span, \"consider removing the safety comment\");\n                        },\n                    );\n                }\n            }\n        },\n        // Unsafe functions with a SAFETY comment are suggested to change it to a `# Safety` comment\n        ItemKind::Fn {\n            sig: FnSig { header, .. },\n            ..\n        } if header.is_unsafe() => {\n            if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {\n                span_lint_and_then(\n                    cx,\n                    UNNECESSARY_SAFETY_COMMENT,\n                    span,\n                    format!(\n                        \"{} has unnecessary safety comment\",\n                        cx.tcx.def_descr(item.owner_id.to_def_id()),\n                    ),\n                    |diag| {\n                        if is_doc {\n                            // If it's already within a doc comment, we try to suggest the change\n\n                            diag.span_suggestion(\n                                help_span,\n                                \"consider changing it to a `# Safety` section\",\n                                \"# Safety\",\n                                Applicability::MachineApplicable,\n                            );\n                        } else {\n                            diag.span_help(\n                                help_span,\n                                \"consider changing the `safety` comment for a `# Safety` doc comment\",\n                            );\n                        }\n                    },\n                );\n            }\n        },\n        // Aside from unsafe impls and consts/statics with an unsafe block, items in general\n        // do not have safety invariants that need to be documented, so lint those.\n        _ => {\n            if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {\n                span_lint_and_then(\n                    cx,\n                    UNNECESSARY_SAFETY_COMMENT,\n                    span,\n                    format!(\n                        \"{} has unnecessary safety comment\",\n                        cx.tcx.def_descr(item.owner_id.to_def_id()),\n                    ),\n                    |diag| {\n                        diag.span_help(help_span, \"consider removing the safety comment\");\n                    },\n                );\n            }\n        },\n    }\n}\n\nfn check_has_no_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) {\n    if let ItemKind::Impl(Impl {\n        of_trait: Some(of_trait),\n        ..\n    }) = item.kind\n        && of_trait.safety.is_unsafe()\n        && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id())\n        && !is_unsafe_from_proc_macro(cx, item.span)\n    {\n        let source_map = cx.tcx.sess.source_map();\n        let span = if source_map.is_multiline(item.span) {\n            source_map.span_until_char(item.span, '\\n')\n        } else {\n            item.span\n        };\n\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(\n            cx,\n            UNDOCUMENTED_UNSAFE_BLOCKS,\n            span,\n            \"unsafe impl missing a safety comment\",\n            |diag| {\n                diag.help(\"consider adding a safety comment on the preceding line\");\n            },\n        );\n    }\n}\nfn expr_has_unnecessary_safety_comment<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'tcx>,\n    comment_pos: BytePos,\n) -> Option<Span> {\n    if cx.tcx.hir_parent_iter(expr.hir_id).any(|(_, ref node)| {\n        matches!(\n            node,\n            Node::Block(Block {\n                rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),\n                ..\n            }),\n        )\n    }) {\n        return None;\n    }\n\n    // this should roughly be the reverse of `block_parents_have_safety_comment`\n    if for_each_expr(cx, expr, |expr| match expr.kind {\n        hir::ExprKind::Block(\n            Block {\n                rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),\n                ..\n            },\n            _,\n        ) => ControlFlow::Break(()),\n        // `_ = foo()` is desugared to `{ let _ = foo(); }`\n        hir::ExprKind::Block(\n            Block {\n                rules: BlockCheckMode::DefaultBlock,\n                stmts:\n                    [\n                        hir::Stmt {\n                            kind:\n                                hir::StmtKind::Let(hir::LetStmt {\n                                    source: hir::LocalSource::AssignDesugar,\n                                    ..\n                                }),\n                            ..\n                        },\n                    ],\n                ..\n            },\n            _,\n        ) => ControlFlow::Continue(Descend::Yes),\n        // statements will be handled by check_stmt itself again\n        hir::ExprKind::Block(..) => ControlFlow::Continue(Descend::No),\n        _ => ControlFlow::Continue(Descend::Yes),\n    })\n    .is_some()\n    {\n        return None;\n    }\n\n    let source_map = cx.tcx.sess.source_map();\n    let span = Span::new(comment_pos, comment_pos, SyntaxContext::root(), None);\n    let help_span = source_map.span_extend_to_next_char(span, '\\n', true);\n\n    Some(help_span)\n}\n\nfn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {\n    let source_map = cx.sess().source_map();\n    let file_pos = source_map.lookup_byte_offset(span.lo());\n    file_pos\n        .sf\n        .src\n        .as_deref()\n        .and_then(|src| src.get(file_pos.pos.to_usize()..))\n        .is_none_or(|src| !src.starts_with(\"unsafe\"))\n}\n\nfn find_unsafe_block_parent_in_expr<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx hir::Expr<'tcx>,\n) -> Option<(Span, HirId)> {\n    match cx.tcx.parent_hir_node(expr.hir_id) {\n        Node::LetStmt(hir::LetStmt { span, hir_id, .. })\n        | Node::Expr(hir::Expr {\n            hir_id,\n            kind: hir::ExprKind::Assign(_, _, span),\n            ..\n        }) => Some((*span, *hir_id)),\n        Node::Expr(expr) => find_unsafe_block_parent_in_expr(cx, expr),\n        node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)\n            && is_const_or_static(&node) =>\n        {\n            Some((span, hir_id))\n        },\n\n        _ => {\n            if is_branchy(expr) {\n                return None;\n            }\n            Some((expr.span, expr.hir_id))\n        },\n    }\n}\n\n// Checks if any parent {expression, statement, block, local, const, static}\n// has a safety comment\nfn block_parents_have_safety_comment(\n    accept_comment_above_statement: bool,\n    accept_comment_above_attributes: bool,\n    cx: &LateContext<'_>,\n    id: HirId,\n) -> bool {\n    let span = match cx.tcx.parent_hir_node(id) {\n        Node::Expr(expr) if let Some((span, _)) = find_unsafe_block_parent_in_expr(cx, expr) => span,\n        Node::Stmt(hir::Stmt {\n            kind:\n                hir::StmtKind::Let(hir::LetStmt { span, .. })\n                | hir::StmtKind::Expr(hir::Expr { span, .. })\n                | hir::StmtKind::Semi(hir::Expr { span, .. }),\n            ..\n        })\n        | Node::LetStmt(hir::LetStmt { span, .. }) => *span,\n\n        node if let Some((span, _)) = span_and_hid_of_item_alike_node(&node)\n            && is_const_or_static(&node) =>\n        {\n            span\n        },\n\n        _ => return false,\n    };\n    // if unsafe block is part of a let/const/static statement,\n    // and accept_comment_above_statement is set to true\n    // we accept the safety comment in the line the precedes this statement.\n    accept_comment_above_statement && span_has_safety_comment(cx, span, accept_comment_above_attributes)\n}\n\n/// Checks if an expression is \"branchy\", e.g. loop, match/if/etc.\nfn is_branchy(expr: &hir::Expr<'_>) -> bool {\n    matches!(\n        expr.kind,\n        hir::ExprKind::If(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..)\n    )\n}\n\n/// Checks if the lines immediately preceding the block contain a safety comment.\nfn block_has_safety_comment(cx: &LateContext<'_>, span: Span, accept_comment_above_attributes: bool) -> bool {\n    // This intentionally ignores text before the start of a function so something like:\n    // ```\n    //     // SAFETY: reason\n    //     fn foo() { unsafe { .. } }\n    // ```\n    // won't work. This is to avoid dealing with where such a comment should be place relative to\n    // attributes and doc comments.\n\n    matches!(\n        span_from_macro_expansion_has_safety_comment(cx, span, accept_comment_above_attributes),\n        HasSafetyComment::Yes(_, _)\n    ) || span_has_safety_comment(cx, span, accept_comment_above_attributes)\n}\n\n#[derive(Debug)]\nenum HasSafetyComment {\n    Yes(BytePos, bool),\n    No,\n    Maybe,\n}\n\n/// Checks if the lines immediately preceding the item contain a safety comment.\nfn item_has_safety_comment(\n    cx: &LateContext<'_>,\n    item: &hir::Item<'_>,\n    accept_comment_above_attributes: bool,\n) -> HasSafetyComment {\n    match span_from_macro_expansion_has_safety_comment(cx, item.span, accept_comment_above_attributes) {\n        HasSafetyComment::Maybe => (),\n        has_safety_comment => return has_safety_comment,\n    }\n\n    if item.span.ctxt() != SyntaxContext::root() {\n        return HasSafetyComment::No;\n    }\n    let comment_start = match cx.tcx.parent_hir_node(item.hir_id()) {\n        Node::Crate(parent_mod) => comment_start_before_item_in_mod(cx, parent_mod, parent_mod.spans.inner_span, item),\n        Node::Item(parent_item) => {\n            if let ItemKind::Mod(_, parent_mod) = &parent_item.kind {\n                comment_start_before_item_in_mod(cx, parent_mod, parent_item.span, item)\n            } else {\n                // Doesn't support impls in this position. Pretend a comment was found.\n                return HasSafetyComment::Maybe;\n            }\n        },\n        Node::Stmt(stmt) => {\n            if let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id) {\n                walk_span_to_context(block.span, SyntaxContext::root())\n                    .map(|sp| CommentStartBeforeItem::Offset(sp.lo()))\n            } else {\n                // Problem getting the parent node. Pretend a comment was found.\n                return HasSafetyComment::Maybe;\n            }\n        },\n        _ => {\n            // Doesn't support impls in this position. Pretend a comment was found.\n            return HasSafetyComment::Maybe;\n        },\n    };\n\n    let source_map = cx.sess().source_map();\n    // If the comment is in the first line of the file, there is no preceding line\n    if let Some(comment_start) = comment_start\n        && let Ok(unsafe_line) = source_map.lookup_line(item.span.lo())\n        && let Ok(comment_start_line) = source_map.lookup_line(comment_start.into())\n        && let include_first_line_of_file = matches!(comment_start, CommentStartBeforeItem::Start)\n        && (include_first_line_of_file || Arc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf))\n        && let Some(src) = unsafe_line.sf.src.as_deref()\n    {\n        return if comment_start_line.line >= unsafe_line.line {\n            HasSafetyComment::No\n        } else {\n            text_has_safety_comment(\n                src,\n                &unsafe_line.sf.lines()\n                    [(comment_start_line.line + usize::from(!include_first_line_of_file))..=unsafe_line.line],\n                unsafe_line.sf.start_pos,\n                accept_comment_above_attributes,\n            )\n        };\n    }\n    HasSafetyComment::Maybe\n}\n\n/// Checks if the lines immediately preceding the item contain a safety comment.\nfn stmt_has_safety_comment(\n    cx: &LateContext<'_>,\n    span: Span,\n    hir_id: HirId,\n    accept_comment_above_attributes: bool,\n) -> HasSafetyComment {\n    match span_from_macro_expansion_has_safety_comment(cx, span, accept_comment_above_attributes) {\n        HasSafetyComment::Maybe => (),\n        has_safety_comment => return has_safety_comment,\n    }\n\n    if span.ctxt() != SyntaxContext::root() {\n        return HasSafetyComment::No;\n    }\n\n    let comment_start = match cx.tcx.parent_hir_node(hir_id) {\n        Node::Block(block) => walk_span_to_context(block.span, SyntaxContext::root()).map(Span::lo),\n        _ => return HasSafetyComment::Maybe,\n    };\n\n    let source_map = cx.sess().source_map();\n    if let Some(comment_start) = comment_start\n        && let Ok(unsafe_line) = source_map.lookup_line(span.lo())\n        && let Ok(comment_start_line) = source_map.lookup_line(comment_start)\n        && Arc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)\n        && let Some(src) = unsafe_line.sf.src.as_deref()\n    {\n        return if comment_start_line.line >= unsafe_line.line {\n            HasSafetyComment::No\n        } else {\n            text_has_safety_comment(\n                src,\n                &unsafe_line.sf.lines()[comment_start_line.line + 1..=unsafe_line.line],\n                unsafe_line.sf.start_pos,\n                accept_comment_above_attributes,\n            )\n        };\n    }\n    HasSafetyComment::Maybe\n}\n\n#[derive(Clone, Copy, Debug)]\nenum CommentStartBeforeItem {\n    Offset(BytePos),\n    Start,\n}\n\nimpl From<CommentStartBeforeItem> for BytePos {\n    fn from(value: CommentStartBeforeItem) -> Self {\n        match value {\n            CommentStartBeforeItem::Offset(loc) => loc,\n            CommentStartBeforeItem::Start => BytePos(0),\n        }\n    }\n}\n\nfn comment_start_before_item_in_mod(\n    cx: &LateContext<'_>,\n    parent_mod: &hir::Mod<'_>,\n    parent_mod_span: Span,\n    item: &hir::Item<'_>,\n) -> Option<CommentStartBeforeItem> {\n    parent_mod.item_ids.iter().enumerate().find_map(|(idx, item_id)| {\n        if *item_id == item.item_id() {\n            if idx == 0 {\n                // mod A { /* comment */ unsafe impl T {} ... }\n                // ^------------------------------------------^ returns the start of this span\n                // ^---------------------^ finally checks comments in this range\n                if let Some(sp) = walk_span_to_context(parent_mod_span, SyntaxContext::root()) {\n                    return Some(CommentStartBeforeItem::Offset(sp.lo()));\n                }\n            } else {\n                // some_item /* comment */ unsafe impl T {}\n                // ^-------^ returns the end of this span\n                //         ^---------------^ finally checks comments in this range\n                let prev_item = cx.tcx.hir_item(parent_mod.item_ids[idx - 1]);\n                if prev_item.span.is_dummy() {\n                    return Some(CommentStartBeforeItem::Start);\n                }\n                if let Some(sp) = walk_span_to_context(prev_item.span, SyntaxContext::root()) {\n                    return Some(CommentStartBeforeItem::Offset(sp.hi()));\n                }\n            }\n        }\n        None\n    })\n}\n\nfn span_from_macro_expansion_has_safety_comment(\n    cx: &LateContext<'_>,\n    span: Span,\n    accept_comment_above_attributes: bool,\n) -> HasSafetyComment {\n    let source_map = cx.sess().source_map();\n    let ctxt = span.ctxt();\n    if ctxt == SyntaxContext::root() {\n        HasSafetyComment::Maybe\n    }\n    // From a macro expansion. Get the text from the start of the macro declaration to start of the\n    // unsafe block.\n    //     macro_rules! foo { () => { stuff }; (x) => { unsafe { stuff } }; }\n    //     ^--------------------------------------------^\n    else if let Ok(unsafe_line) = source_map.lookup_line(span.lo())\n        && let Ok(macro_line) = source_map.lookup_line(ctxt.outer_expn_data().def_site.lo())\n        && Arc::ptr_eq(&unsafe_line.sf, &macro_line.sf)\n        && let Some(src) = unsafe_line.sf.src.as_deref()\n    {\n        if macro_line.line < unsafe_line.line {\n            text_has_safety_comment(\n                src,\n                &unsafe_line.sf.lines()[macro_line.line + 1..=unsafe_line.line],\n                unsafe_line.sf.start_pos,\n                accept_comment_above_attributes,\n            )\n        } else {\n            HasSafetyComment::No\n        }\n    } else {\n        // Problem getting source text. Pretend a comment was found.\n        HasSafetyComment::Maybe\n    }\n}\n\nfn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {\n    let body = cx.enclosing_body?;\n    let mut maybe_mod_item = None;\n\n    for (_, parent_node) in cx.tcx.hir_parent_iter(body.hir_id) {\n        match parent_node {\n            Node::Crate(mod_) => return Some(mod_.spans.inner_span),\n            Node::Item(hir::Item {\n                kind: ItemKind::Mod(_, mod_),\n                span,\n                ..\n            }) => {\n                return maybe_mod_item\n                    .and_then(|item| comment_start_before_item_in_mod(cx, mod_, *span, &item))\n                    .map(|comment_start| mod_.spans.inner_span.with_lo(comment_start.into()))\n                    .or(Some(*span));\n            },\n            node if let Some((span, _)) = span_and_hid_of_item_alike_node(&node)\n                && !is_const_or_static(&node) =>\n            {\n                return Some(span);\n            },\n            Node::Item(item) => {\n                maybe_mod_item = Some(*item);\n            },\n            _ => {\n                maybe_mod_item = None;\n            },\n        }\n    }\n    None\n}\n\nfn span_has_safety_comment(cx: &LateContext<'_>, span: Span, accept_comment_above_attributes: bool) -> bool {\n    let source_map = cx.sess().source_map();\n    let ctxt = span.ctxt();\n    if ctxt.is_root()\n        && let Some(search_span) = get_body_search_span(cx)\n    {\n        if let Ok(unsafe_line) = source_map.lookup_line(span.lo())\n            && let Some(body_span) = walk_span_to_context(search_span, SyntaxContext::root())\n            && let Ok(body_line) = source_map.lookup_line(body_span.lo())\n            && Arc::ptr_eq(&unsafe_line.sf, &body_line.sf)\n            && let Some(src) = unsafe_line.sf.src.as_deref()\n        {\n            // Get the text from the start of function body to the unsafe block.\n            //     fn foo() { some_stuff; unsafe { stuff }; other_stuff; }\n            //              ^-------------^\n            body_line.line < unsafe_line.line\n                && matches!(\n                    text_has_safety_comment(\n                        src,\n                        &unsafe_line.sf.lines()[body_line.line + 1..=unsafe_line.line],\n                        unsafe_line.sf.start_pos,\n                        accept_comment_above_attributes,\n                    ),\n                    HasSafetyComment::Yes(..)\n                )\n        } else {\n            // Problem getting source text. Pretend a comment was found.\n            true\n        }\n    } else {\n        false\n    }\n}\n\n/// Checks if the given text has a safety comment for the immediately proceeding line.\n///\n/// If `accept_comment_above_attributes` is true, it will ignore attributes inbetween blocks of\n/// comments\nfn text_has_safety_comment(\n    src: &str,\n    line_starts: &[RelativeBytePos],\n    start_pos: BytePos,\n    accept_comment_above_attributes: bool,\n) -> HasSafetyComment {\n    let mut lines = line_starts\n        .array_windows::<2>()\n        .rev()\n        .map_while(|[start, end]| {\n            let start = start.to_usize();\n            let end = end.to_usize();\n            let text = src.get(start..end)?;\n            let trimmed = text.trim_start();\n            Some((start + (text.len() - trimmed.len()), trimmed))\n        })\n        .filter(|(_, text)| !(text.is_empty() || (accept_comment_above_attributes && is_attribute(text))));\n\n    let Some((line_start, line)) = lines.next() else {\n        return HasSafetyComment::No;\n    };\n\n    let mut in_codeblock = false;\n    // Check for a sequence of line comments.\n    if line.starts_with(\"//\") {\n        let (mut line, mut line_start) = (line, line_start);\n        loop {\n            // Don't lint if the safety comment is part of a codeblock in a doc comment.\n            // It may or may not be required, and we can't very easily check it (and we shouldn't, since\n            // the safety comment isn't referring to the node we're currently checking)\n            if let Some(doc) = line.strip_prefix(\"///\").or_else(|| line.strip_prefix(\"//!\"))\n                && doc.trim_start().starts_with(\"```\")\n            {\n                in_codeblock = !in_codeblock;\n            }\n\n            if !in_codeblock && let Some(safety_pos) = line.to_ascii_uppercase().find(\"SAFETY:\") {\n                return HasSafetyComment::Yes(\n                    start_pos\n                        + BytePos(u32::try_from(line_start).unwrap())\n                        + BytePos(u32::try_from(safety_pos).unwrap()),\n                    line.starts_with(\"///\"),\n                );\n            }\n            match lines.next() {\n                Some((s, x)) if x.starts_with(\"//\") => (line, line_start) = (x, s),\n                _ => return HasSafetyComment::No,\n            }\n        }\n    }\n    // Check for a comment that appears after other code on the same line (e.g., `let x = // SAFETY:`)\n    // This handles cases in macros where the comment is on the same line as preceding code.\n    // We only check the first (immediate preceding) line for this pattern.\n    // Only whitespace is allowed between the comment marker and `SAFETY:`.\n    if let Some(comment_start) = [line.find(\"//\"), line.find(\"/*\")].into_iter().flatten().min()\n        && let after_marker = &line[comment_start + 2..] // skip marker\n        && let trimmed = after_marker.trim_start() // skip whitespace\n        && trimmed.get(..7).is_some_and(|s| s.eq_ignore_ascii_case(\"SAFETY:\"))\n    {\n        let safety_offset = 2 + (after_marker.len() - trimmed.len());\n        return HasSafetyComment::Yes(\n            start_pos\n                + BytePos(u32::try_from(line_start).unwrap())\n                + BytePos(u32::try_from(comment_start + safety_offset).unwrap()),\n            false,\n        );\n    }\n    // No line comments; look for the start of a block comment.\n    // This will only find them if they are at the start of a line.\n    let (mut line_start, mut line) = (line_start, line);\n    loop {\n        if line.starts_with(\"/*\") {\n            let src = &src[line_start..line_starts.last().unwrap().to_usize()];\n            let mut tokens = tokenize(src, FrontmatterAllowed::No);\n            let a = tokens.next();\n            if let Some(safety_pos) = src[..a.unwrap().len as usize].to_ascii_uppercase().find(\"SAFETY:\")\n                && tokens.all(|t| t.kind == TokenKind::Whitespace)\n            {\n                return HasSafetyComment::Yes(\n                    start_pos\n                        + BytePos(u32::try_from(line_start).unwrap())\n                        + BytePos(u32::try_from(safety_pos).unwrap()),\n                    line.starts_with(\"/**\"),\n                );\n            }\n            return HasSafetyComment::No;\n        }\n        match lines.next() {\n            Some(x) => (line_start, line) = x,\n            None => return HasSafetyComment::No,\n        }\n    }\n}\n\nfn is_attribute(text: &str) -> bool {\n    (text.starts_with(\"#[\") || text.starts_with(\"#![\")) && text.trim_end().ends_with(']')\n}\n\nfn span_and_hid_of_item_alike_node(node: &Node<'_>) -> Option<(Span, HirId)> {\n    match node {\n        Node::Item(item) => Some((item.span, item.owner_id.into())),\n        Node::TraitItem(ti) => Some((ti.span, ti.owner_id.into())),\n        Node::ImplItem(ii) => Some((ii.span, ii.owner_id.into())),\n        _ => None,\n    }\n}\n\nfn is_const_or_static(node: &Node<'_>) -> bool {\n    matches!(\n        node,\n        Node::Item(hir::Item {\n            kind: ItemKind::Const(..) | ItemKind::Static(..),\n            ..\n        }) | Node::ImplItem(hir::ImplItem {\n            kind: hir::ImplItemKind::Const(..),\n            ..\n        }) | Node::TraitItem(hir::TraitItem {\n            kind: hir::TraitItemKind::Const(..),\n            ..\n        })\n    )\n}\n\nfn block_has_inner_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {\n    let source_map = cx.sess().source_map();\n    if let Ok(src) = source_map.span_to_snippet(span)\n        && let Some(after_brace) = src\n            .strip_prefix(\"unsafe\")\n            .and_then(|s| s.trim_start().strip_prefix('{'))\n        && let Some(comment) = after_brace\n            .trim_start()\n            .strip_prefix(\"//\")\n            .or_else(|| after_brace.trim_start().strip_prefix(\"/*\"))\n    {\n        comment.trim_start().to_ascii_uppercase().starts_with(\"SAFETY:\")\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unicode.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::is_lint_allowed;\nuse clippy_utils::macros::span_is_local;\nuse clippy_utils::source::snippet;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind, HirId};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse unicode_normalization::UnicodeNormalization;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for invisible Unicode characters in the code.\n    ///\n    /// ### Why is this bad?\n    /// Having an invisible character in the code makes for all\n    /// sorts of April fools, but otherwise is very much frowned upon.\n    ///\n    /// ### Example\n    /// You don't see it, but there may be a zero-width space or soft hyphen\n    /// some­where in this text.\n    #[clippy::version = \"1.49.0\"]\n    pub INVISIBLE_CHARACTERS,\n    correctness,\n    \"using an invisible character in a string literal, which is confusing\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for non-ASCII characters in string and char literals.\n    ///\n    /// ### Why restrict this?\n    /// Yeah, we know, the 90's called and wanted their charset\n    /// back. Even so, there still are editors and other programs out there that\n    /// don't work well with Unicode. So if the code is meant to be used\n    /// internationally, on multiple operating systems, or has other portability\n    /// requirements, activating this lint could be useful.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = String::from(\"€\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let x = String::from(\"\\u{20ac}\");\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub NON_ASCII_LITERAL,\n    restriction,\n    \"using any literal non-ASCII chars in a string literal instead of using the `\\\\u` escape\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for string literals that contain Unicode in a form\n    /// that is not equal to its\n    /// [NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms).\n    ///\n    /// ### Why is this bad?\n    /// If such a string is compared to another, the results\n    /// may be surprising.\n    ///\n    /// ### Example\n    /// You may not see it, but \"à\"\" and \"à\"\" aren't the same string. The\n    /// former when escaped is actually `\"a\\u{300}\"` while the latter is `\"\\u{e0}\"`.\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNICODE_NOT_NFC,\n    pedantic,\n    \"using a Unicode literal not in NFC normal form (see [Unicode tr15](http://www.unicode.org/reports/tr15/) for further information)\"\n}\n\ndeclare_lint_pass!(Unicode => [\n    INVISIBLE_CHARACTERS,\n    NON_ASCII_LITERAL,\n    UNICODE_NOT_NFC,\n]);\n\nimpl LateLintPass<'_> for Unicode {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        if let ExprKind::Lit(lit) = expr.kind\n            && let LitKind::Str(_, _) | LitKind::Char(_) = lit.node\n        {\n            check_str(cx, lit.span, expr.hir_id);\n        }\n    }\n}\n\nfn escape<T: Iterator<Item = char>>(s: T) -> String {\n    let mut result = String::new();\n    for c in s {\n        if c as u32 > 0x7F {\n            for d in c.escape_unicode() {\n                result.push(d);\n            }\n        } else {\n            result.push(c);\n        }\n    }\n    result\n}\n\nfn check_str(cx: &LateContext<'_>, span: Span, id: HirId) {\n    if !span_is_local(span) {\n        return;\n    }\n\n    let string = snippet(cx, span, \"\");\n    if string.chars().any(|c| ['\\u{200B}', '\\u{ad}', '\\u{2060}'].contains(&c)) {\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(cx, INVISIBLE_CHARACTERS, span, \"invisible character detected\", |diag| {\n            diag.span_suggestion(\n                span,\n                \"consider replacing the string with\",\n                string\n                    .replace('\\u{200B}', \"\\\\u{200B}\")\n                    .replace('\\u{ad}', \"\\\\u{AD}\")\n                    .replace('\\u{2060}', \"\\\\u{2060}\"),\n                Applicability::MachineApplicable,\n            );\n        });\n    }\n\n    if string.chars().any(|c| c as u32 > 0x7F) {\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(\n            cx,\n            NON_ASCII_LITERAL,\n            span,\n            \"literal non-ASCII character detected\",\n            |diag| {\n                diag.span_suggestion(\n                    span,\n                    \"consider replacing the string with\",\n                    if is_lint_allowed(cx, UNICODE_NOT_NFC, id) {\n                        escape(string.chars())\n                    } else {\n                        escape(string.nfc())\n                    },\n                    Applicability::MachineApplicable,\n                );\n            },\n        );\n    }\n\n    if is_lint_allowed(cx, NON_ASCII_LITERAL, id) && string.chars().zip(string.nfc()).any(|(a, b)| a != b) {\n        #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n        span_lint_and_then(cx, UNICODE_NOT_NFC, span, \"non-NFC Unicode sequence detected\", |diag| {\n            diag.span_suggestion(\n                span,\n                \"consider replacing the string with\",\n                string.nfc().collect::<String>(),\n                Applicability::MachineApplicable,\n            );\n        });\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/uninhabited_references.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp};\nuse rustc_hir_analysis::lower_ty;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// It detects references to uninhabited types, such as `!` and\n    /// warns when those are either dereferenced or returned from a function.\n    ///\n    /// ### Why is this bad?\n    /// Dereferencing a reference to an uninhabited type would create\n    /// an instance of such a type, which cannot exist. This constitutes\n    /// undefined behaviour. Such a reference could have been created\n    /// by `unsafe` code.\n    ///\n    /// ### Example\n    /// The following function can return a reference to an uninhabited type\n    /// (`Infallible`) because it uses `unsafe` code to create it. However,\n    /// the user of such a function could dereference the return value and\n    /// trigger an undefined behavior from safe code.\n    ///\n    /// ```no_run\n    /// fn create_ref() -> &'static std::convert::Infallible {\n    ///     unsafe { std::mem::transmute(&()) }\n    /// }\n    /// ```\n    #[clippy::version = \"1.76.0\"]\n    pub UNINHABITED_REFERENCES,\n    nursery,\n    \"reference to uninhabited type\"\n}\n\ndeclare_lint_pass!(UninhabitedReferences => [UNINHABITED_REFERENCES]);\n\nimpl LateLintPass<'_> for UninhabitedReferences {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {\n        if expr.span.in_external_macro(cx.tcx.sess.source_map()) {\n            return;\n        }\n\n        if let ExprKind::Unary(UnOp::Deref, _) = expr.kind {\n            let ty = cx.typeck_results().expr_ty_adjusted(expr);\n            if ty.is_privately_uninhabited(cx.tcx, cx.typing_env()) {\n                span_lint(\n                    cx,\n                    UNINHABITED_REFERENCES,\n                    expr.span,\n                    \"dereferencing a reference to an uninhabited type is undefined behavior\",\n                );\n            }\n        }\n    }\n\n    fn check_fn<'tcx>(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'_>,\n        fndecl: &'_ FnDecl<'tcx>,\n        _: &'_ Body<'_>,\n        span: Span,\n        _: LocalDefId,\n    ) {\n        if span.in_external_macro(cx.tcx.sess.source_map()) || matches!(kind, FnKind::Closure) {\n            return;\n        }\n        if let FnRetTy::Return(hir_ty) = fndecl.output\n            && let TyKind::Ref(_, mut_ty) = hir_ty.kind\n            && lower_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.typing_env())\n        {\n            span_lint(\n                cx,\n                UNINHABITED_REFERENCES,\n                hir_ty.span,\n                \"dereferencing a reference to an uninhabited type would be undefined behavior\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/uninit_vec.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_help};\nuse clippy_utils::higher::{VecInitKind, get_vec_init_kind};\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::ty::is_uninit_value_valid_for_ty;\nuse clippy_utils::{SpanlessEq, is_integer_literal, is_lint_allowed, peel_hir_expr_while, sym};\nuse rustc_hir::{Block, Expr, ExprKind, HirId, PatKind, PathSegment, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\n// TODO: add `ReadBuf` (RFC 2930) in \"How to fix\" once it is available in std\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `set_len()` call that creates `Vec` with uninitialized elements.\n    /// This is commonly caused by calling `set_len()` right after allocating or\n    /// reserving a buffer with `new()`, `default()`, `with_capacity()`, or `reserve()`.\n    ///\n    /// ### Why is this bad?\n    /// It creates a `Vec` with uninitialized data, which leads to\n    /// undefined behavior with most safe operations. Notably, uninitialized\n    /// `Vec<u8>` must not be used with generic `Read`.\n    ///\n    /// Moreover, calling `set_len()` on a `Vec` created with `new()` or `default()`\n    /// creates out-of-bound values that lead to heap memory corruption when used.\n    ///\n    /// ### Known Problems\n    /// This lint only checks directly adjacent statements.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let mut vec: Vec<u8> = Vec::with_capacity(1000);\n    /// unsafe { vec.set_len(1000); }\n    /// reader.read(&mut vec); // undefined behavior!\n    /// ```\n    ///\n    /// ### How to fix?\n    /// 1. Use an initialized buffer:\n    ///    ```rust,ignore\n    ///    let mut vec: Vec<u8> = vec![0; 1000];\n    ///    reader.read(&mut vec);\n    ///    ```\n    /// 2. Wrap the content in `MaybeUninit`:\n    ///    ```rust,ignore\n    ///    let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000);\n    ///    vec.set_len(1000);  // `MaybeUninit` can be uninitialized\n    ///    ```\n    /// 3. If you are on 1.60.0 or later, `Vec::spare_capacity_mut()` is available:\n    ///    ```rust,ignore\n    ///    let mut vec: Vec<u8> = Vec::with_capacity(1000);\n    ///    let remaining = vec.spare_capacity_mut();  // `&mut [MaybeUninit<u8>]`\n    ///    // perform initialization with `remaining`\n    ///    vec.set_len(...);  // Safe to call `set_len()` on initialized part\n    ///    ```\n    #[clippy::version = \"1.58.0\"]\n    pub UNINIT_VEC,\n    correctness,\n    \"Vec with uninitialized data\"\n}\n\ndeclare_lint_pass!(UninitVec => [UNINIT_VEC]);\n\n// FIXME: update to a visitor-based implementation.\n// Threads: https://github.com/rust-lang/rust-clippy/pull/7682#discussion_r710998368\nimpl<'tcx> LateLintPass<'tcx> for UninitVec {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {\n        if !block.span.in_external_macro(cx.tcx.sess.source_map()) {\n            for w in block.stmts.windows(2) {\n                if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = w[1].kind {\n                    handle_uninit_vec_pair(cx, &w[0], expr);\n                }\n            }\n\n            if let (Some(stmt), Some(expr)) = (block.stmts.last(), block.expr) {\n                handle_uninit_vec_pair(cx, stmt, expr);\n            }\n        }\n    }\n}\n\nfn handle_uninit_vec_pair<'tcx>(\n    cx: &LateContext<'tcx>,\n    maybe_init_or_reserve: &'tcx Stmt<'tcx>,\n    maybe_set_len: &'tcx Expr<'tcx>,\n) {\n    if let Some(vec) = extract_init_or_reserve_target(cx, maybe_init_or_reserve)\n        && let Some((set_len_self, call_span)) = extract_set_len_self(cx, maybe_set_len)\n        && vec.location.eq_expr(cx, set_len_self)\n        && let ty::Ref(_, vec_ty, _) = cx.typeck_results().expr_ty_adjusted(set_len_self).kind()\n        && let ty::Adt(_, args) = vec_ty.kind()\n        // `#[allow(...)]` attribute can be set on enclosing unsafe block of `set_len()`\n        && !is_lint_allowed(cx, UNINIT_VEC, maybe_set_len.hir_id)\n    {\n        if vec.has_capacity() {\n            // with_capacity / reserve -> set_len\n\n            // Check T of Vec<T>\n            if !is_uninit_value_valid_for_ty(cx, args.type_at(0)) {\n                span_lint_and_help(\n                    cx,\n                    UNINIT_VEC,\n                    vec![call_span, maybe_init_or_reserve.span],\n                    \"calling `set_len()` immediately after reserving a buffer creates uninitialized values\",\n                    None,\n                    \"initialize the buffer or wrap the content in `MaybeUninit`\",\n                );\n            }\n        } else {\n            // new / default -> set_len\n            span_lint(\n                cx,\n                UNINIT_VEC,\n                vec![call_span, maybe_init_or_reserve.span],\n                \"calling `set_len()` on empty `Vec` creates out-of-bound values\",\n            );\n        }\n    }\n}\n\n/// The target `Vec` that is initialized or reserved\n#[derive(Clone, Copy)]\nstruct TargetVec<'tcx> {\n    location: VecLocation<'tcx>,\n    /// `None` if `reserve()`\n    init_kind: Option<VecInitKind>,\n}\n\nimpl TargetVec<'_> {\n    pub fn has_capacity(self) -> bool {\n        !matches!(self.init_kind, Some(VecInitKind::New | VecInitKind::Default))\n    }\n}\n\n#[derive(Clone, Copy)]\nenum VecLocation<'tcx> {\n    Local(HirId),\n    Expr(&'tcx Expr<'tcx>),\n}\n\nimpl<'tcx> VecLocation<'tcx> {\n    pub fn eq_expr(self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {\n        match self {\n            VecLocation::Local(hir_id) => expr.res_local_id() == Some(hir_id),\n            VecLocation::Expr(self_expr) => SpanlessEq::new(cx).eq_expr(self_expr, expr),\n        }\n    }\n}\n\n/// Finds the target location where the result of `Vec` initialization is stored\n/// or `self` expression for `Vec::reserve()`.\nfn extract_init_or_reserve_target<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'tcx>) -> Option<TargetVec<'tcx>> {\n    match stmt.kind {\n        StmtKind::Let(local) => {\n            if let Some(init_expr) = local.init\n                && let PatKind::Binding(_, hir_id, _, None) = local.pat.kind\n                && let Some(init_kind) = get_vec_init_kind(cx, init_expr)\n            {\n                return Some(TargetVec {\n                    location: VecLocation::Local(hir_id),\n                    init_kind: Some(init_kind),\n                });\n            }\n        },\n        StmtKind::Expr(expr) | StmtKind::Semi(expr) => match expr.kind {\n            ExprKind::Assign(lhs, rhs, _span) => {\n                if let Some(init_kind) = get_vec_init_kind(cx, rhs) {\n                    return Some(TargetVec {\n                        location: VecLocation::Expr(lhs),\n                        init_kind: Some(init_kind),\n                    });\n                }\n            },\n            ExprKind::MethodCall(path, self_expr, [_], _) if is_reserve(cx, path, self_expr) => {\n                return Some(TargetVec {\n                    location: VecLocation::Expr(self_expr),\n                    init_kind: None,\n                });\n            },\n            _ => (),\n        },\n        StmtKind::Item(_) => (),\n    }\n    None\n}\n\nfn is_reserve(cx: &LateContext<'_>, path: &PathSegment<'_>, self_expr: &Expr<'_>) -> bool {\n    cx.typeck_results()\n        .expr_ty(self_expr)\n        .peel_refs()\n        .is_diag_item(cx, sym::Vec)\n        && path.ident.name == sym::reserve\n}\n\n/// Returns self if the expression is `Vec::set_len()`\nfn extract_set_len_self<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Option<(&'tcx Expr<'tcx>, Span)> {\n    // peel unsafe blocks in `unsafe { vec.set_len() }`\n    let expr = peel_hir_expr_while(expr, |e| {\n        if let ExprKind::Block(block, _) = e.kind {\n            // Extract the first statement/expression\n            match (block.stmts.first().map(|stmt| &stmt.kind), block.expr) {\n                (None, Some(expr)) => Some(expr),\n                (Some(StmtKind::Expr(expr) | StmtKind::Semi(expr)), _) => Some(expr),\n                _ => None,\n            }\n        } else {\n            None\n        }\n    });\n    match expr.kind {\n        ExprKind::MethodCall(path, self_expr, [arg], _) => {\n            let self_type = cx.typeck_results().expr_ty(self_expr).peel_refs();\n            if self_type.is_diag_item(cx, sym::Vec) && path.ident.name == sym::set_len && !is_integer_literal(arg, 0) {\n                Some((self_expr, expr.span))\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unit_return_expecting_ord.rs",
    "content": "use clippy_utils::diagnostics::{span_lint, span_lint_and_help};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{Closure, Expr, ExprKind, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_middle::ty::{ClauseKind, GenericPredicates, ProjectionPredicate, TraitPredicate};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{BytePos, Span, Symbol, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions that expect closures of type\n    /// Fn(...) -> Ord where the implemented closure returns the unit type.\n    /// The lint also suggests to remove the semi-colon at the end of the statement if present.\n    ///\n    /// ### Why is this bad?\n    /// Likely, returning the unit type is unintentional, and\n    /// could simply be caused by an extra semi-colon. Since () implements Ord\n    /// it doesn't cause a compilation error.\n    /// This is the same reasoning behind the unit_cmp lint.\n    ///\n    /// ### Known problems\n    /// If returning unit is intentional, then there is no\n    /// way of specifying this without triggering needless_return lint\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut twins = vec![(1, 1), (2, 2)];\n    /// twins.sort_by_key(|x| { x.1; });\n    /// ```\n    #[clippy::version = \"1.47.0\"]\n    pub UNIT_RETURN_EXPECTING_ORD,\n    correctness,\n    \"fn arguments of type Fn(...) -> Ord returning the unit type ().\"\n}\n\ndeclare_lint_pass!(UnitReturnExpectingOrd => [UNIT_RETURN_EXPECTING_ORD]);\n\n// For each\nfn get_trait_predicates_for_trait_ids<'tcx>(\n    cx: &LateContext<'tcx>,\n    generics: GenericPredicates<'tcx>,\n    trait_ids: &[Option<DefId>], // At least 2 ids\n) -> [Vec<TraitPredicate<'tcx>>; 3] {\n    debug_assert!(trait_ids.len() >= 2);\n    let mut preds = [Vec::new(), Vec::new(), Vec::new()];\n    for (pred, _) in generics.predicates {\n        if let ClauseKind::Trait(poly_trait_pred) = pred.kind().skip_binder() {\n            let trait_pred = cx\n                .tcx\n                .instantiate_bound_regions_with_erased(pred.kind().rebind(poly_trait_pred));\n            for (i, tid) in trait_ids.iter().enumerate() {\n                if let Some(tid) = tid\n                    && *tid == trait_pred.trait_ref.def_id\n                {\n                    preds[i].push(trait_pred);\n                }\n            }\n        }\n    }\n    preds\n}\n\nfn get_projection_pred<'tcx>(\n    cx: &LateContext<'tcx>,\n    generics: GenericPredicates<'tcx>,\n    trait_pred: TraitPredicate<'tcx>,\n) -> Option<ProjectionPredicate<'tcx>> {\n    generics.predicates.iter().find_map(|(proj_pred, _)| {\n        if let ClauseKind::Projection(pred) = proj_pred.kind().skip_binder() {\n            let projection_pred = cx\n                .tcx\n                .instantiate_bound_regions_with_erased(proj_pred.kind().rebind(pred));\n            if projection_pred.projection_term.args == trait_pred.trait_ref.args {\n                return Some(projection_pred);\n            }\n        }\n        None\n    })\n}\n\nfn get_args_to_check<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n    args_len: usize,\n    fn_mut_trait: DefId,\n    ord_trait: Option<DefId>,\n    partial_ord_trait: Option<DefId>,\n) -> Vec<(usize, Symbol)> {\n    let mut args_to_check = Vec::new();\n    if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {\n        let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity();\n        let generics = cx.tcx.predicates_of(def_id);\n        let [fn_mut_preds, ord_preds, partial_ord_preds] =\n            get_trait_predicates_for_trait_ids(cx, generics, &[Some(fn_mut_trait), ord_trait, partial_ord_trait]);\n        if fn_mut_preds.is_empty() {\n            return vec![];\n        }\n\n        // Trying to call instantiate_bound_regions_with_erased on fn_sig.inputs() gives the following error\n        // The trait `rustc::ty::TypeFoldable<'_>` is not implemented for\n        // `&[rustc_middle::ty::Ty<'_>]`\n        let inputs_output = cx.tcx.instantiate_bound_regions_with_erased(fn_sig.inputs_and_output());\n        inputs_output\n            .iter()\n            .rev()\n            .skip(1)\n            .rev()\n            .enumerate()\n            .for_each(|(i, inp)| {\n                for trait_pred in &fn_mut_preds {\n                    if trait_pred.self_ty() == inp\n                        && let Some(return_ty_pred) = get_projection_pred(cx, generics, *trait_pred)\n                    {\n                        if ord_preds\n                            .iter()\n                            .any(|ord| Some(ord.self_ty()) == return_ty_pred.term.as_type())\n                        {\n                            args_to_check.push((i, sym::Ord));\n                            if args_to_check.len() == args_len - 1 {\n                                break;\n                            }\n                        } else if partial_ord_preds\n                            .iter()\n                            .any(|pord| pord.self_ty() == return_ty_pred.term.expect_type())\n                        {\n                            args_to_check.push((i, sym::PartialOrd));\n                            if args_to_check.len() == args_len - 1 {\n                                break;\n                            }\n                        }\n                    }\n                }\n            });\n    }\n    args_to_check\n}\n\nfn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> {\n    if let ExprKind::Closure(&Closure { body, fn_decl_span, .. }) = arg.kind\n        && let ty::Closure(_def_id, args) = &cx.typeck_results().node_type(arg.hir_id).kind()\n        && let ret_ty = args.as_closure().sig().output()\n        && let ty = cx.tcx.instantiate_bound_regions_with_erased(ret_ty)\n        && ty.is_unit()\n    {\n        let body = cx.tcx.hir_body(body);\n        if let ExprKind::Block(block, _) = body.value.kind\n            && block.expr.is_none()\n            && let Some(stmt) = block.stmts.last()\n            && let StmtKind::Semi(_) = stmt.kind\n        {\n            let data = stmt.span.data();\n            // Make a span out of the semicolon for the help message\n            Some((fn_decl_span, Some(data.with_lo(data.hi - BytePos(1)))))\n        } else {\n            Some((fn_decl_span, None))\n        }\n    } else {\n        None\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnitReturnExpectingOrd {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::MethodCall(_, receiver, args, _) = expr.kind\n            && args.iter().any(|arg| {\n                matches!(\n                    arg.peel_blocks().peel_borrows().peel_drop_temps().kind,\n                    ExprKind::Path(_) | ExprKind::Closure(_)\n                )\n            })\n            && let Some(fn_mut_trait) = cx.tcx.lang_items().fn_mut_trait()\n        {\n            let ord_trait = cx.tcx.get_diagnostic_item(sym::Ord);\n            let partial_ord_trait = cx.tcx.lang_items().partial_ord_trait();\n            if (ord_trait, partial_ord_trait) == (None, None) {\n                return;\n            }\n\n            let args = std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>();\n            let arg_indices = get_args_to_check(cx, expr, args.len(), fn_mut_trait, ord_trait, partial_ord_trait);\n            for (i, trait_name) in arg_indices {\n                match check_arg(cx, args[i]) {\n                    Some((span, None)) => {\n                        span_lint(\n                            cx,\n                            UNIT_RETURN_EXPECTING_ORD,\n                            span,\n                            format!(\n                                \"this closure returns \\\n                                   the unit type which also implements {trait_name}\"\n                            ),\n                        );\n                    },\n                    Some((span, Some(last_semi))) => {\n                        span_lint_and_help(\n                            cx,\n                            UNIT_RETURN_EXPECTING_ORD,\n                            span,\n                            format!(\n                                \"this closure returns \\\n                                   the unit type which also implements {trait_name}\"\n                            ),\n                            Some(last_semi),\n                            \"probably caused by this trailing semicolon\",\n                        );\n                    },\n                    None => {},\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unit_types/let_unit_value.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, is_format_macro, root_macro_call_first_node};\nuse clippy_utils::source::{snippet_indent, walk_span_to_context};\nuse clippy_utils::visitors::{for_each_local_assignment, for_each_value_source};\nuse core::ops::ControlFlow;\nuse rustc_ast::{FormatArgs, FormatArgumentKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::intravisit::{Visitor, walk_body, walk_expr};\nuse rustc_hir::{Expr, ExprKind, HirId, HirIdSet, LetStmt, MatchSource, Node, PatKind, QPath, TyKind};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_middle::ty;\nuse rustc_span::Span;\n\nuse super::LET_UNIT_VALUE;\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, format_args: &FormatArgsStorage, local: &'tcx LetStmt<'_>) {\n    // skip `let () = { ... }`\n    if let PatKind::Tuple(fields, ..) = local.pat.kind\n        && fields.is_empty()\n    {\n        return;\n    }\n\n    if let Some(init) = local.init\n        && !local.pat.span.from_expansion()\n        && !local.span.in_external_macro(cx.sess().source_map())\n        && !local.span.is_from_async_await()\n        && cx.typeck_results().pat_ty(local.pat).is_unit()\n    {\n        // skip `let awa = ()`\n        if let ExprKind::Tup([]) = init.kind {\n            return;\n        }\n\n        // skip `let _: () = { ... }`\n        if let Some(ty) = local.ty\n            && let TyKind::Tup([]) = ty.kind\n        {\n            return;\n        }\n\n        if (local.ty.is_some_and(|ty| !matches!(ty.kind, TyKind::Infer(())))\n            || matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none()))\n            && expr_needs_inferred_result(cx, init)\n        {\n            if !matches!(local.pat.kind, PatKind::Wild)\n                && !matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none())\n            {\n                span_lint_and_then(\n                    cx,\n                    LET_UNIT_VALUE,\n                    local.span,\n                    \"this let-binding has unit value\",\n                    |diag| {\n                        diag.span_suggestion(\n                            local.pat.span,\n                            \"use a wildcard binding\",\n                            \"_\",\n                            Applicability::MaybeIncorrect, // snippet\n                        );\n                    },\n                );\n            }\n        } else {\n            if let ExprKind::Match(_, _, MatchSource::AwaitDesugar) = init.kind {\n                return;\n            }\n\n            span_lint_and_then(\n                cx,\n                LET_UNIT_VALUE,\n                local.span,\n                \"this let-binding has unit value\",\n                |diag| {\n                    let mut suggestions = Vec::new();\n                    let init_new_span = walk_span_to_context(init.span, local.span.ctxt()).unwrap();\n\n                    // Suggest omitting the `let` binding\n                    let app = Applicability::MachineApplicable;\n\n                    // If this is a binding pattern, we need to add suggestions to remove any usages\n                    // of the variable\n                    if let PatKind::Binding(_, binding_hir_id, ..) = local.pat.kind\n                        && let Some(body_id) = cx.enclosing_body.as_ref()\n                    {\n                        let body = cx.tcx.hir_body(*body_id);\n                        let mut visitor = UnitVariableCollector::new(cx, format_args, binding_hir_id);\n                        walk_body(&mut visitor, body);\n\n                        let mut has_in_format_capture = false;\n                        suggestions.extend(visitor.spans.into_iter().filter_map(|span| match span {\n                            VariableUsage::FormatCapture => {\n                                has_in_format_capture = true;\n                                None\n                            },\n                            VariableUsage::Normal(span) => Some((span, \"()\".to_string())),\n                            VariableUsage::FieldShorthand(span) => Some((span.shrink_to_hi(), \": ()\".to_string())),\n                        }));\n\n                        if has_in_format_capture {\n                            // In a case like this:\n                            // ```\n                            // let unit = returns_unit();\n                            // eprintln!(\"{unit}\");\n                            // ```\n                            // we can't remove the `unit` binding and replace its uses with a `()`,\n                            // because the `eprintln!` would break.\n                            //\n                            // So do the following instead:\n                            // ```\n                            // let unit = ();\n                            // returns_unit();\n                            // eprintln!(\"{unit}\");\n                            // ```\n                            // TODO: find a less awkward way to do this\n                            suggestions.push((\n                                init_new_span.shrink_to_lo(),\n                                format!(\"();\\n{}\", snippet_indent(cx, local.span).as_deref().unwrap_or(\"\")),\n                            ));\n                            diag.multipart_suggestion(\"replace variable usages with `()`\", suggestions, app);\n                            return;\n                        }\n                    }\n\n                    // let local = returns_unit();\n                    // ^^^^^^^^^^^^ remove this\n                    suggestions.push((local.span.until(init_new_span), String::new()));\n                    let message = if suggestions.len() == 1 {\n                        \"omit the `let` binding\"\n                    } else {\n                        \"omit the `let` binding and replace variable usages with `()`\"\n                    };\n                    diag.multipart_suggestion(message, suggestions, app);\n                },\n            );\n        }\n    }\n}\n\nstruct UnitVariableCollector<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    format_args: &'a FormatArgsStorage,\n    id: HirId,\n    spans: Vec<VariableUsage>,\n    macro_call: Option<&'a FormatArgs>,\n}\n\n/// How the unit variable is used\nenum VariableUsage {\n    Normal(Span),\n    /// Captured in a `format!`:\n    ///\n    /// ```ignore\n    /// let unit = ();\n    /// eprintln!(\"{unit}\");\n    /// ```\n    FormatCapture,\n    /// In a field shorthand init:\n    ///\n    /// ```ignore\n    /// struct Foo {\n    ///    unit: (),\n    /// }\n    /// let unit = ();\n    /// Foo { unit };\n    /// ```\n    FieldShorthand(Span),\n}\n\nimpl<'a, 'tcx> UnitVariableCollector<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>, format_args: &'a FormatArgsStorage, id: HirId) -> Self {\n        Self {\n            cx,\n            format_args,\n            id,\n            spans: Vec::new(),\n            macro_call: None,\n        }\n    }\n}\n\n/**\n * Collect all instances where a variable is used based on its `HirId`.\n */\nimpl<'tcx> Visitor<'tcx> for UnitVariableCollector<'_, 'tcx> {\n    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> Self::Result {\n        if let Some(macro_call) = root_macro_call_first_node(self.cx, ex)\n            && is_format_macro(self.cx, macro_call.def_id)\n            && let Some(format_args) = self.format_args.get(self.cx, ex, macro_call.expn)\n        {\n            let parent_macro_call = self.macro_call;\n            self.macro_call = Some(format_args);\n            walk_expr(self, ex);\n            self.macro_call = parent_macro_call;\n            return;\n        }\n\n        if let ExprKind::Path(QPath::Resolved(None, path)) = ex.kind\n            && let Res::Local(id) = path.res\n            && id == self.id\n        {\n            if let Some(macro_call) = self.macro_call\n                && macro_call.arguments.all_args().iter().any(|arg| {\n                    matches!(arg.kind, FormatArgumentKind::Captured(_)) && find_format_arg_expr(ex, arg).is_some()\n                })\n            {\n                self.spans.push(VariableUsage::FormatCapture);\n            } else {\n                let parent = self.cx.tcx.parent_hir_node(ex.hir_id);\n                match parent {\n                    Node::ExprField(expr_field) if expr_field.is_shorthand => {\n                        self.spans.push(VariableUsage::FieldShorthand(ex.span));\n                    },\n                    _ => {\n                        self.spans.push(VariableUsage::Normal(path.span));\n                    },\n                }\n            }\n        }\n\n        walk_expr(self, ex);\n    }\n}\n\n/// Checks sub-expressions which create the value returned by the given expression for whether\n/// return value inference is needed. This checks through locals to see if they also need inference\n/// at this point.\n///\n/// e.g.\n/// ```rust,ignore\n/// let bar = foo();\n/// let x: u32 = if true { baz() } else { bar };\n/// ```\n/// Here the sources of the value assigned to `x` would be `baz()`, and `foo()` via the\n/// initialization of `bar`. If both `foo` and `baz` have a return type which require type\n/// inference then this function would return `true`.\nfn expr_needs_inferred_result<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {\n    // The locals used for initialization which have yet to be checked.\n    let mut locals_to_check = Vec::new();\n    // All the locals which have been added to `locals_to_check`. Needed to prevent cycles.\n    let mut seen_locals = HirIdSet::default();\n    if !each_value_source_needs_inference(cx, e, &mut locals_to_check, &mut seen_locals) {\n        return false;\n    }\n    while let Some(id) = locals_to_check.pop() {\n        if let Node::LetStmt(l) = cx.tcx.parent_hir_node(id) {\n            if !l.ty.is_none_or(|ty| matches!(ty.kind, TyKind::Infer(()))) {\n                return false;\n            }\n            if let Some(e) = l.init {\n                if !each_value_source_needs_inference(cx, e, &mut locals_to_check, &mut seen_locals) {\n                    return false;\n                }\n            } else if for_each_local_assignment(cx, id, |e| {\n                if each_value_source_needs_inference(cx, e, &mut locals_to_check, &mut seen_locals) {\n                    ControlFlow::Continue(())\n                } else {\n                    ControlFlow::Break(())\n                }\n            })\n            .is_break()\n            {\n                return false;\n            }\n        }\n    }\n\n    true\n}\n\nfn each_value_source_needs_inference(\n    cx: &LateContext<'_>,\n    e: &Expr<'_>,\n    locals_to_check: &mut Vec<HirId>,\n    seen_locals: &mut HirIdSet,\n) -> bool {\n    for_each_value_source(e, &mut |e| {\n        if needs_inferred_result_ty(cx, e, locals_to_check, seen_locals) {\n            ControlFlow::Continue(())\n        } else {\n            ControlFlow::Break(())\n        }\n    })\n    .is_continue()\n}\n\nfn needs_inferred_result_ty(\n    cx: &LateContext<'_>,\n    e: &Expr<'_>,\n    locals_to_check: &mut Vec<HirId>,\n    seen_locals: &mut HirIdSet,\n) -> bool {\n    let (id, receiver, args) = match e.kind {\n        ExprKind::Call(\n            Expr {\n                kind: ExprKind::Path(path),\n                hir_id,\n                ..\n            },\n            args,\n        ) => match cx.qpath_res(path, *hir_id) {\n            Res::Def(DefKind::AssocFn | DefKind::Fn, id) => (id, None, args),\n            _ => return false,\n        },\n        ExprKind::MethodCall(_, receiver, args, _) => match cx.typeck_results().type_dependent_def_id(e.hir_id) {\n            Some(id) => (id, Some(receiver), args),\n            None => return false,\n        },\n        ExprKind::Path(QPath::Resolved(None, path)) => {\n            if let Res::Local(id) = path.res\n                && seen_locals.insert(id)\n            {\n                locals_to_check.push(id);\n            }\n            return true;\n        },\n        _ => return false,\n    };\n    let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_binder();\n    if let ty::Param(output_ty) = *sig.output().kind() {\n        let args: Vec<&Expr<'_>> = if let Some(receiver) = receiver {\n            std::iter::once(receiver).chain(args.iter()).collect()\n        } else {\n            args.iter().collect()\n        };\n        sig.inputs().iter().zip(args).all(|(&ty, arg)| {\n            !ty.is_param(output_ty.index) || each_value_source_needs_inference(cx, arg, locals_to_check, seen_locals)\n        })\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unit_types/mod.rs",
    "content": "mod let_unit_value;\nmod unit_arg;\nmod unit_cmp;\nmod utils;\n\nuse clippy_utils::macros::FormatArgsStorage;\nuse rustc_hir::{Expr, LetStmt};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for binding a unit value.\n    ///\n    /// ### Why is this bad?\n    /// A unit value cannot usefully be used anywhere. So\n    /// binding one is kind of pointless.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = {\n    ///     1;\n    /// };\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub LET_UNIT_VALUE,\n    style,\n    \"creating a `let` binding to a value of unit type, which usually can't be used afterwards\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for passing a unit value as an argument to a function without using a\n    /// unit literal (`()`).\n    ///\n    /// ### Why is this bad?\n    /// This is likely the result of an accidental semicolon.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// foo({\n    ///     let a = bar();\n    ///     baz(a);\n    /// })\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNIT_ARG,\n    complexity,\n    \"passing unit to a function\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for comparisons to unit. This includes all binary\n    /// comparisons (like `==` and `<`) and asserts.\n    ///\n    /// ### Why is this bad?\n    /// Unit is always equal to itself, and thus is just a\n    /// clumsily written constant. Mostly this happens when someone accidentally\n    /// adds semicolons at the end of the operands.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn foo() {};\n    /// # fn bar() {};\n    /// # fn baz() {};\n    /// if {\n    ///     foo();\n    /// } == {\n    ///     bar();\n    /// } {\n    ///     baz();\n    /// }\n    /// ```\n    /// is equal to\n    /// ```no_run\n    /// # fn foo() {};\n    /// # fn bar() {};\n    /// # fn baz() {};\n    /// {\n    ///     foo();\n    ///     bar();\n    ///     baz();\n    /// }\n    /// ```\n    ///\n    /// For asserts:\n    /// ```no_run\n    /// # fn foo() {};\n    /// # fn bar() {};\n    /// assert_eq!({ foo(); }, { bar(); });\n    /// ```\n    /// will always succeed\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNIT_CMP,\n    correctness,\n    \"comparing unit values\"\n}\n\nimpl_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_ARG, UNIT_CMP]);\n\npub struct UnitTypes {\n    format_args: FormatArgsStorage,\n}\n\nimpl UnitTypes {\n    pub fn new(format_args: FormatArgsStorage) -> Self {\n        Self { format_args }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnitTypes {\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {\n        let_unit_value::check(cx, &self.format_args, local);\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        unit_cmp::check(cx, expr);\n        unit_arg::check(cx, expr);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unit_types/unit_arg.rs",
    "content": "use std::iter;\n\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::{SpanRangeExt, indent_of, reindent_multiline};\nuse clippy_utils::sugg::Sugg;\nuse clippy_utils::ty::expr_type_is_certain;\nuse clippy_utils::{is_expr_default, is_from_proc_macro};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, Expr, ExprKind, MatchSource, Node, StmtKind};\nuse rustc_lint::LateContext;\nuse rustc_span::SyntaxContext;\n\nuse super::{UNIT_ARG, utils};\n\npub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n    if expr.span.from_expansion() {\n        return;\n    }\n\n    // apparently stuff in the desugaring of `?` can trigger this\n    // so check for that here\n    // only the calls to `Try::from_error` is marked as desugared,\n    // so we need to check both the current Expr and its parent.\n    if is_questionmark_desugar_marked_call(expr) {\n        return;\n    }\n    if let Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id)\n        && is_questionmark_desugar_marked_call(parent_expr)\n    {\n        return;\n    }\n\n    let (receiver, args) = match expr.kind {\n        ExprKind::Call(_, args) => (None, args),\n        ExprKind::MethodCall(_, receiver, args, _) => (Some(receiver), args),\n        _ => return,\n    };\n\n    let args_to_recover = receiver\n        .into_iter()\n        .chain(args)\n        .filter(|arg| {\n            if cx.typeck_results().expr_ty(arg).is_unit() && !utils::is_unit_literal(arg) {\n                !matches!(\n                    &arg.kind,\n                    ExprKind::Match(.., MatchSource::TryDesugar(_)) | ExprKind::Path(..)\n                )\n            } else {\n                false\n            }\n        })\n        .collect::<Vec<_>>();\n    if !args_to_recover.is_empty() && !is_from_proc_macro(cx, expr) {\n        lint_unit_args(cx, expr, args_to_recover.as_slice());\n    }\n}\n\nfn is_questionmark_desugar_marked_call(expr: &Expr<'_>) -> bool {\n    use rustc_span::hygiene::DesugaringKind;\n    if let ExprKind::Call(callee, _) = expr.kind {\n        callee.span.is_desugaring(DesugaringKind::QuestionMark)\n    } else {\n        false\n    }\n}\n\nfn lint_unit_args<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, args_to_recover: &[&'tcx Expr<'tcx>]) {\n    let mut applicability = Applicability::MachineApplicable;\n    let (singular, plural) = if args_to_recover.len() > 1 {\n        (\"\", \"s\")\n    } else {\n        (\"a \", \"\")\n    };\n    span_lint_and_then(\n        cx,\n        UNIT_ARG,\n        expr.span,\n        format!(\"passing {singular}unit value{plural} to a function\"),\n        |db| {\n            let mut or = \"\";\n            args_to_recover\n                .iter()\n                .filter_map(|arg| {\n                    if let ExprKind::Block(block, _) = arg.kind\n                        && block.expr.is_none()\n                        && let Some(last_stmt) = block.stmts.iter().last()\n                        && let StmtKind::Semi(last_expr) = last_stmt.kind\n                        && let Some(snip) = last_expr.span.get_source_text(cx)\n                    {\n                        Some((last_stmt.span, snip))\n                    } else {\n                        None\n                    }\n                })\n                .for_each(|(span, sugg)| {\n                    db.span_suggestion(\n                        span,\n                        \"remove the semicolon from the last statement in the block\",\n                        sugg.as_str(),\n                        Applicability::MaybeIncorrect,\n                    );\n                    or = \"or \";\n                    applicability = Applicability::MaybeIncorrect;\n                });\n\n            let arg_snippets: Vec<_> = args_to_recover\n                .iter()\n                // If the argument is from an expansion and is a `Default::default()`, we skip it\n                .filter(|arg| !arg.span.from_expansion() || !is_expr_default_nested(cx, arg))\n                .filter_map(|arg| get_expr_snippet(cx, arg))\n                .collect();\n\n            // If the argument is an empty block or `Default::default()`, we can replace it with `()`.\n            let arg_snippets_without_redundant_exprs: Vec<_> = args_to_recover\n                .iter()\n                .filter(|arg| !is_expr_default_nested(cx, arg) && (arg.span.from_expansion() || !is_empty_block(arg)))\n                .filter_map(|arg| get_expr_snippet_with_type_certainty(cx, arg))\n                .collect();\n\n            if let Some(call_snippet) = expr.span.get_source_text(cx) {\n                if arg_snippets_without_redundant_exprs.is_empty()\n                    && let suggestions = args_to_recover\n                        .iter()\n                        .filter(|arg| !arg.span.from_expansion() || !is_expr_default_nested(cx, arg))\n                        .map(|arg| (arg.span.parent_callsite().unwrap_or(arg.span), \"()\".to_string()))\n                        .collect::<Vec<_>>()\n                    && !suggestions.is_empty()\n                {\n                    db.multipart_suggestion(\n                        format!(\"use {singular}unit literal{plural} instead\"),\n                        suggestions,\n                        applicability,\n                    );\n                } else {\n                    let plural = arg_snippets_without_redundant_exprs.len() > 1;\n                    let sugg = fmt_stmts_and_call(\n                        cx,\n                        expr,\n                        &call_snippet,\n                        arg_snippets,\n                        arg_snippets_without_redundant_exprs,\n                    );\n                    let empty_or_s = if plural { \"s\" } else { \"\" };\n                    let it_or_them = if plural { \"them\" } else { \"it\" };\n                    db.span_suggestion(\n                        expr.span,\n                        format!(\n                            \"{or}move the expression{empty_or_s} in front of the call and replace {it_or_them} with the unit literal `()`\"\n                        ),\n                        sugg,\n                        applicability,\n                    );\n                }\n            }\n        },\n    );\n}\n\nfn is_expr_default_nested<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {\n    is_expr_default(cx, expr)\n        || matches!(expr.kind, ExprKind::Block(block, _)\n        if block.expr.is_some() && is_expr_default_nested(cx, block.expr.unwrap()))\n}\n\nenum MaybeTypeUncertain<'tcx> {\n    Certain(Sugg<'tcx>),\n    Uncertain(Sugg<'tcx>),\n}\n\nimpl From<MaybeTypeUncertain<'_>> for String {\n    fn from(value: MaybeTypeUncertain<'_>) -> Self {\n        match value {\n            MaybeTypeUncertain::Certain(sugg) => sugg.to_string(),\n            MaybeTypeUncertain::Uncertain(sugg) => format!(\"let _: () = {sugg}\"),\n        }\n    }\n}\n\nfn get_expr_snippet<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<Sugg<'tcx>> {\n    let mut app = Applicability::MachineApplicable;\n    let snip = Sugg::hir_with_context(cx, expr, SyntaxContext::root(), \"..\", &mut app);\n    if app != Applicability::MachineApplicable {\n        return None;\n    }\n\n    Some(snip)\n}\n\nfn get_expr_snippet_with_type_certainty<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'tcx>,\n) -> Option<MaybeTypeUncertain<'tcx>> {\n    get_expr_snippet(cx, expr).map(|snip| {\n        // If the type of the expression is certain, we can use it directly.\n        // Otherwise, we wrap it in a `let _: () = ...` to ensure the type is correct.\n        if !expr_type_is_certain(cx, expr) && !is_block_with_no_expr(expr) {\n            MaybeTypeUncertain::Uncertain(snip)\n        } else {\n            MaybeTypeUncertain::Certain(snip)\n        }\n    })\n}\n\nfn is_block_with_no_expr(expr: &Expr<'_>) -> bool {\n    matches!(expr.kind, ExprKind::Block(Block { expr: None, .. }, _))\n}\n\nfn is_empty_block(expr: &Expr<'_>) -> bool {\n    matches!(\n        expr.kind,\n        ExprKind::Block(\n            Block {\n                stmts: [],\n                expr: None,\n                ..\n            },\n            _,\n        )\n    )\n}\n\nfn fmt_stmts_and_call(\n    cx: &LateContext<'_>,\n    call_expr: &Expr<'_>,\n    call_snippet: &str,\n    args_snippets: Vec<Sugg<'_>>,\n    non_empty_block_args_snippets: Vec<MaybeTypeUncertain<'_>>,\n) -> String {\n    let call_expr_indent = indent_of(cx, call_expr.span).unwrap_or(0);\n    let call_snippet_with_replacements = args_snippets.into_iter().fold(call_snippet.to_owned(), |acc, arg| {\n        acc.replacen(&arg.to_string(), \"()\", 1)\n    });\n\n    let stmts_and_call = non_empty_block_args_snippets\n        .into_iter()\n        .map(Into::into)\n        .chain(iter::once(call_snippet_with_replacements))\n        .map(|v| reindent_multiline(&v, true, Some(call_expr_indent)))\n        .collect::<Vec<_>>();\n\n    let mut stmts_and_call_snippet = stmts_and_call.join(&format!(\"{}{}\", \";\\n\", \" \".repeat(call_expr_indent)));\n    // expr is not in a block statement or result expression position, wrap in a block\n    let parent_node = cx.tcx.parent_hir_node(call_expr.hir_id);\n    if !matches!(parent_node, Node::Block(_)) && !matches!(parent_node, Node::Stmt(_)) {\n        let block_indent = call_expr_indent + 4;\n        stmts_and_call_snippet = reindent_multiline(&stmts_and_call_snippet, true, Some(block_indent));\n        stmts_and_call_snippet = format!(\n            \"{{\\n{}{}\\n{}}}\",\n            \" \".repeat(block_indent),\n            &stmts_and_call_snippet,\n            \" \".repeat(call_expr_indent)\n        );\n    }\n    stmts_and_call_snippet\n}\n"
  },
  {
    "path": "clippy_lints/src/unit_types/unit_cmp.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node};\nuse clippy_utils::{is_unit_expr, sym};\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::LateContext;\n\nuse super::UNIT_CMP;\n\npub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {\n    if expr.span.from_expansion() {\n        if let Some(macro_call) = root_macro_call_first_node(cx, expr)\n            && let Some(diag_name) = cx.tcx.get_diagnostic_name(macro_call.def_id)\n        {\n            let result = match diag_name {\n                sym::assert_eq_macro | sym::debug_assert_eq_macro => \"succeed\",\n                sym::assert_ne_macro | sym::debug_assert_ne_macro => \"fail\",\n                _ => return,\n            };\n            let Some((lhs, rhs, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else {\n                return;\n            };\n            if is_unit_expr(lhs) || is_unit_expr(rhs) {\n                return;\n            }\n            if !cx.typeck_results().expr_ty(lhs).is_unit() {\n                return;\n            }\n            span_lint(\n                cx,\n                UNIT_CMP,\n                macro_call.span,\n                format!(\n                    \"`{}` of unit values detected. This will always {result}\",\n                    cx.tcx.item_name(macro_call.def_id)\n                ),\n            );\n        }\n        return;\n    }\n\n    if let ExprKind::Binary(ref cmp, left, _) = expr.kind {\n        let op = cmp.node;\n        if op.is_comparison() && cx.typeck_results().expr_ty(left).is_unit() {\n            let result = match op {\n                BinOpKind::Eq | BinOpKind::Le | BinOpKind::Ge => \"true\",\n                _ => \"false\",\n            };\n            span_lint(\n                cx,\n                UNIT_CMP,\n                expr.span,\n                format!(\n                    \"{}-comparison of unit values detected. This will always be {result}\",\n                    op.as_str()\n                ),\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unit_types/utils.rs",
    "content": "use rustc_hir::{Expr, ExprKind};\n\npub(super) fn is_unit_literal(expr: &Expr<'_>) -> bool {\n    matches!(expr.kind, ExprKind::Tup(slice) if slice.is_empty())\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_box_returns.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::ty::approx_ty_size;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::{FnDecl, FnRetTy, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Checks for a return type containing a `Box<T>` where `T` implements `Sized`\n    ///\n    /// The lint ignores `Box<T>` where `T` is larger than `unnecessary_box_size`,\n    /// as returning a large `T` directly may be detrimental to performance.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// It's better to just return `T` in these cases. The caller may not need\n    /// the value to be boxed, and it's expensive to free the memory once the\n    /// `Box<T>` been dropped.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo() -> Box<String> {\n    ///     Box::new(String::from(\"Hello, world!\"))\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn foo() -> String {\n    ///     String::from(\"Hello, world!\")\n    /// }\n    /// ```\n    #[clippy::version = \"1.70.0\"]\n    pub UNNECESSARY_BOX_RETURNS,\n    pedantic,\n    \"Needlessly returning a Box\"\n}\n\nimpl_lint_pass!(UnnecessaryBoxReturns => [UNNECESSARY_BOX_RETURNS]);\n\npub struct UnnecessaryBoxReturns {\n    avoid_breaking_exported_api: bool,\n    maximum_size: u64,\n}\n\nimpl UnnecessaryBoxReturns {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n            maximum_size: conf.unnecessary_box_size,\n        }\n    }\n\n    fn check_fn_item(&self, cx: &LateContext<'_>, decl: &FnDecl<'_>, def_id: LocalDefId, name: Symbol) {\n        // we don't want to tell someone to break an exported function if they ask us not to\n        if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {\n            return;\n        }\n\n        // functions which contain the word \"box\" are exempt from this lint\n        if name.as_str().contains(\"box\") {\n            return;\n        }\n\n        let FnRetTy::Return(return_ty_hir) = &decl.output else {\n            return;\n        };\n\n        let return_ty = cx\n            .tcx\n            .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(def_id).skip_binder())\n            .output();\n\n        let Some(boxed_ty) = return_ty.boxed_ty() else {\n            return;\n        };\n\n        // It's sometimes useful to return Box<T> if T is unsized, so don't lint those.\n        // Also, don't lint if we know that T is very large, in which case returning\n        // a Box<T> may be beneficial.\n        if boxed_ty.is_sized(cx.tcx, cx.typing_env()) && approx_ty_size(cx, boxed_ty) <= self.maximum_size {\n            span_lint_and_then(\n                cx,\n                UNNECESSARY_BOX_RETURNS,\n                return_ty_hir.span,\n                format!(\"boxed return of the sized type `{boxed_ty}`\"),\n                |diagnostic| {\n                    diagnostic.span_suggestion(\n                        return_ty_hir.span,\n                        \"try\",\n                        boxed_ty.to_string(),\n                        // the return value and function callers also needs to\n                        // be changed, so this can't be MachineApplicable\n                        Applicability::Unspecified,\n                    );\n                    diagnostic.help(\"changing this also requires a change to the return expressions in this function\");\n                },\n            );\n        }\n    }\n}\n\nimpl LateLintPass<'_> for UnnecessaryBoxReturns {\n    fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {\n        let TraitItemKind::Fn(signature, _) = &item.kind else {\n            return;\n        };\n        self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {\n        // Ignore implementations of traits, because the lint should be on the\n        // trait, not on the implementation of it.\n        let Node::Item(parent) = cx.tcx.parent_hir_node(item.hir_id()) else {\n            return;\n        };\n        let ItemKind::Impl(parent) = parent.kind else { return };\n        if parent.of_trait.is_some() {\n            return;\n        }\n\n        let ImplItemKind::Fn(signature, ..) = &item.kind else {\n            return;\n        };\n        self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        let ItemKind::Fn { ident, sig, .. } = &item.kind else {\n            return;\n        };\n        self.check_fn_item(cx, sig.decl, item.owner_id.def_id, ident.name);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_literal_bound.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeResPath;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::intravisit::{FnKind, Visitor};\nuse rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, Lit, MutTy, Mutability, PrimTy, Ty, TyKind, intravisit};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Detects functions that are written to return `&str` that could return `&'static str` but instead return a `&'a str`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// This leaves the caller unable to use the `&str` as `&'static str`, causing unnecessary allocations or confusion.\n    /// This is also most likely what you meant to write.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # struct MyType;\n    /// impl MyType {\n    ///     fn returns_literal(&self) -> &str {\n    ///         \"Literal\"\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # struct MyType;\n    /// impl MyType {\n    ///     fn returns_literal(&self) -> &'static str {\n    ///         \"Literal\"\n    ///     }\n    /// }\n    /// ```\n    /// Or, in case you may return a non-literal `str` in future:\n    /// ```no_run\n    /// # struct MyType;\n    /// impl MyType {\n    ///     fn returns_literal<'a>(&'a self) -> &'a str {\n    ///         \"Literal\"\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.84.0\"]\n    pub UNNECESSARY_LITERAL_BOUND,\n    pedantic,\n    \"detects &str that could be &'static str in function return types\"\n}\n\ndeclare_lint_pass!(UnnecessaryLiteralBound => [UNNECESSARY_LITERAL_BOUND]);\n\nfn extract_anonymous_ref<'tcx>(hir_ty: &Ty<'tcx>) -> Option<&'tcx Ty<'tcx>> {\n    let TyKind::Ref(lifetime, MutTy { ty, mutbl }) = hir_ty.kind else {\n        return None;\n    };\n\n    if !lifetime.is_anonymous() || !matches!(mutbl, Mutability::Not) {\n        return None;\n    }\n\n    Some(ty)\n}\n\nfn is_str_literal(expr: &Expr<'_>) -> bool {\n    matches!(\n        expr.kind,\n        ExprKind::Lit(Lit {\n            node: LitKind::Str(..),\n            ..\n        }),\n    )\n}\n\nstruct FindNonLiteralReturn;\n\nimpl<'hir> Visitor<'hir> for FindNonLiteralReturn {\n    type Result = std::ops::ControlFlow<()>;\n    type NestedFilter = intravisit::nested_filter::None;\n\n    fn visit_expr(&mut self, expr: &'hir Expr<'hir>) -> Self::Result {\n        if let ExprKind::Ret(Some(ret_val_expr)) = expr.kind\n            && !is_str_literal(ret_val_expr)\n        {\n            Self::Result::Break(())\n        } else {\n            intravisit::walk_expr(self, expr)\n        }\n    }\n}\n\nfn check_implicit_returns_static_str(body: &Body<'_>) -> bool {\n    // TODO: Improve this to the same complexity as the Visitor to catch more implicit return cases.\n    if let ExprKind::Block(block, _) = body.value.kind\n        && let Some(implicit_ret) = block.expr\n    {\n        return is_str_literal(implicit_ret);\n    }\n\n    false\n}\n\nfn check_explicit_returns_static_str(expr: &Expr<'_>) -> bool {\n    let mut visitor = FindNonLiteralReturn;\n    visitor.visit_expr(expr).is_continue()\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnnecessaryLiteralBound {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        span: Span,\n        _: LocalDefId,\n    ) {\n        if span.from_expansion() {\n            return;\n        }\n\n        // Checking closures would be a little silly\n        if matches!(kind, FnKind::Closure) {\n            return;\n        }\n\n        // Check for `-> &str`\n        let FnRetTy::Return(ret_hir_ty) = decl.output else {\n            return;\n        };\n\n        let Some(inner_hir_ty) = extract_anonymous_ref(ret_hir_ty) else {\n            return;\n        };\n\n        if !matches!(inner_hir_ty.basic_res(), Res::PrimTy(PrimTy::Str)) {\n            return;\n        }\n\n        // Check for all return statements returning literals\n        if check_explicit_returns_static_str(body.value) && check_implicit_returns_static_str(body) {\n            span_lint_and_sugg(\n                cx,\n                UNNECESSARY_LITERAL_BOUND,\n                ret_hir_ty.span,\n                \"returning a `str` unnecessarily tied to the lifetime of arguments\",\n                \"try\",\n                \"&'static str\".into(), // how ironic, a lint about `&'static str` requiring a `String` alloc...\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_map_on_constructor.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_applicability;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Suggests removing the use of a `map()` (or `map_err()`) method when an `Option` or `Result`\n    /// is being constructed.\n    ///\n    /// ### Why is this bad?\n    /// It introduces unnecessary complexity. Instead, the function can be called before\n    /// constructing the `Option` or `Result` from its return value.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// Some(4).map(i32::swap_bytes)\n    /// # ;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// Some(i32::swap_bytes(4))\n    /// # ;\n    /// ```\n    #[clippy::version = \"1.74.0\"]\n    pub UNNECESSARY_MAP_ON_CONSTRUCTOR,\n    complexity,\n    \"using `map`/`map_err` on `Option` or `Result` constructors\"\n}\n\ndeclare_lint_pass!(UnnecessaryMapOnConstructor => [\n    UNNECESSARY_MAP_ON_CONSTRUCTOR,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {\n        if !expr.span.from_expansion()\n            && let hir::ExprKind::MethodCall(path, recv, [map_arg], ..) = expr.kind\n            && !map_arg.span.from_expansion()\n            && let hir::ExprKind::Path(fun) = map_arg.kind\n            && let Some(sym::Option | sym::Result) = cx.typeck_results().expr_ty(recv).opt_diag_name(cx)\n        {\n            let (constructor_path, constructor_item) = if let hir::ExprKind::Call(constructor, [arg, ..]) = recv.kind\n                && let hir::ExprKind::Path(constructor_path) = constructor.kind\n                && !constructor.span.from_expansion()\n                && !arg.span.from_expansion()\n            {\n                (constructor_path, arg)\n            } else {\n                return;\n            };\n            let constructor_symbol = match constructor_path {\n                hir::QPath::Resolved(_, path) => {\n                    if let Some(path_segment) = path.segments.last() {\n                        path_segment.ident.name\n                    } else {\n                        return;\n                    }\n                },\n                hir::QPath::TypeRelative(_, path) => path.ident.name,\n            };\n            match constructor_symbol {\n                sym::Some | sym::Ok if path.ident.name == sym::map => (),\n                sym::Err if path.ident.name == sym::map_err => (),\n                _ => return,\n            }\n\n            let mut app = Applicability::MachineApplicable;\n            let fun_snippet = snippet_with_applicability(cx, fun.span(), \"_\", &mut app);\n            let constructor_snippet = snippet_with_applicability(cx, constructor_path.span(), \"_\", &mut app);\n            let constructor_arg_snippet = snippet_with_applicability(cx, constructor_item.span, \"_\", &mut app);\n            span_lint_and_sugg(\n                cx,\n                UNNECESSARY_MAP_ON_CONSTRUCTOR,\n                expr.span,\n                format!(\n                    \"unnecessary `{}` on constructor `{constructor_snippet}(_)`\",\n                    path.ident.name\n                ),\n                \"try\",\n                format!(\"{constructor_snippet}({fun_snippet}({constructor_arg_snippet}))\"),\n                app,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_mut_passed.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{self, Ty};\nuse rustc_session::declare_lint_pass;\nuse std::iter;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Detects passing a mutable reference to a function that only\n    /// requires an immutable reference.\n    ///\n    /// ### Why is this bad?\n    /// The mutable reference rules out all other references to\n    /// the value. Also the code misleads about the intent of the call site.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let mut vec = Vec::new();\n    /// # let mut value = 5;\n    /// vec.push(&mut value);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # let mut vec = Vec::new();\n    /// # let value = 5;\n    /// vec.push(&value);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNNECESSARY_MUT_PASSED,\n    style,\n    \"an argument passed as a mutable reference although the callee only demands an immutable reference\"\n}\n\ndeclare_lint_pass!(UnnecessaryMutPassed => [UNNECESSARY_MUT_PASSED]);\n\nimpl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if e.span.from_expansion() {\n            // Issue #11268\n            return;\n        }\n\n        match e.kind {\n            ExprKind::Call(fn_expr, arguments) => {\n                if let ExprKind::Path(ref path) = fn_expr.kind {\n                    check_arguments(\n                        cx,\n                        &mut arguments.iter(),\n                        cx.typeck_results().expr_ty(fn_expr),\n                        &rustc_hir_pretty::qpath_to_string(&cx.tcx, path),\n                        \"function\",\n                    );\n                }\n            },\n            ExprKind::MethodCall(path, receiver, arguments, _)\n                if let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) =>\n            {\n                let args = cx.typeck_results().node_args(e.hir_id);\n                let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args);\n                check_arguments(\n                    cx,\n                    &mut iter::once(receiver).chain(arguments.iter()),\n                    method_type,\n                    path.ident.as_str(),\n                    \"method\",\n                );\n            },\n            _ => (),\n        }\n    }\n}\n\nfn check_arguments<'tcx>(\n    cx: &LateContext<'tcx>,\n    arguments: &mut dyn Iterator<Item = &'tcx Expr<'tcx>>,\n    type_definition: Ty<'tcx>,\n    name: &str,\n    fn_kind: &str,\n) {\n    if type_definition.is_fn() {\n        let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();\n        for (argument, parameter) in iter::zip(arguments, parameters) {\n            if let ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not) = parameter.kind()\n                && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, arg) = argument.kind\n            {\n                let applicability = Applicability::MachineApplicable;\n\n                let span_to_remove = {\n                    let span_until_arg = argument.span.until(arg.span);\n                    if let Some(Some(ref_pos)) = span_until_arg.with_source_text(cx, |src| {\n                        src\n                            // we don't use `strip_prefix` here, because `argument` might be enclosed in parens, in\n                            // which case `&` is no longer the prefix\n                            .find('&')\n                            // just a sanity check, in case some proc-macro messes up the spans\n                            .filter(|ref_pos| src[*ref_pos..].contains(\"mut\"))\n                    }) && let Ok(lo) = u32::try_from(ref_pos + '&'.len_utf8())\n                    {\n                        span_until_arg.split_at(lo).1\n                    } else {\n                        return;\n                    }\n                };\n\n                span_lint_and_then(\n                    cx,\n                    UNNECESSARY_MUT_PASSED,\n                    argument.span,\n                    format!(\"the {fn_kind} `{name}` doesn't need a mutable reference\"),\n                    |diag| {\n                        diag.span_suggestion_verbose(span_to_remove, \"remove this `mut`\", String::new(), applicability);\n                    },\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_owned_empty_strings.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_ast::ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Detects cases of owned empty strings being passed as an argument to a function expecting `&str`\n    ///\n    /// ### Why is this bad?\n    ///\n    /// This results in longer and less readable code\n    ///\n    /// ### Example\n    /// ```no_run\n    /// vec![\"1\", \"2\", \"3\"].join(&String::new());\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// vec![\"1\", \"2\", \"3\"].join(\"\");\n    /// ```\n    #[clippy::version = \"1.62.0\"]\n    pub UNNECESSARY_OWNED_EMPTY_STRINGS,\n    style,\n    \"detects cases of references to owned empty strings being passed as an argument to a function expecting `&str`\"\n}\n\ndeclare_lint_pass!(UnnecessaryOwnedEmptyStrings => [\n    UNNECESSARY_OWNED_EMPTY_STRINGS,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner_expr) = expr.kind\n            && let ExprKind::Call(fun, args) = inner_expr.kind\n            && let ExprKind::Path(ref qpath) = fun.kind\n            && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()\n            && let ty::Ref(_, inner_str, _) = cx.typeck_results().expr_ty_adjusted(expr).kind()\n            && inner_str.is_str()\n        {\n            let fun_name = cx.tcx.get_diagnostic_name(fun_def_id);\n            if fun_name == Some(sym::string_new) {\n                span_lint_and_sugg(\n                    cx,\n                    UNNECESSARY_OWNED_EMPTY_STRINGS,\n                    expr.span,\n                    \"usage of `&String::new()` for a function expecting a `&str` argument\",\n                    \"try\",\n                    \"\\\"\\\"\".to_owned(),\n                    Applicability::MachineApplicable,\n                );\n            } else if fun_name == Some(sym::from_fn)\n                && let [arg] = args\n                && let ExprKind::Lit(spanned) = &arg.kind\n                && let LitKind::Str(symbol, _) = spanned.node\n                && symbol.is_empty()\n                && let inner_expr_type = cx.typeck_results().expr_ty(inner_expr)\n                && inner_expr_type.is_lang_item(cx, LangItem::String)\n            {\n                span_lint_and_sugg(\n                    cx,\n                    UNNECESSARY_OWNED_EMPTY_STRINGS,\n                    expr.span,\n                    \"usage of `&String::from(\\\"\\\")` for a function expecting a `&str` argument\",\n                    \"try\",\n                    \"\\\"\\\"\".to_owned(),\n                    Applicability::MachineApplicable,\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_self_imports.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::{Item, ItemKind, UseTreeKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for imports ending in `::{self}`.\n    ///\n    /// ### Why restrict this?\n    /// In most cases, this can be written much more cleanly by omitting `::{self}`.\n    ///\n    /// ### Known problems\n    /// Removing `::{self}` will cause any non-module items at the same path to also be imported.\n    /// This might cause a naming conflict (https://github.com/rust-lang/rustfmt/issues/3568). This lint makes no attempt\n    /// to detect this scenario and that is why it is a restriction lint.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::io::{self};\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::io;\n    /// ```\n    #[clippy::version = \"1.53.0\"]\n    pub UNNECESSARY_SELF_IMPORTS,\n    restriction,\n    \"imports ending in `::{self}`, which can be omitted\"\n}\n\ndeclare_lint_pass!(UnnecessarySelfImports => [UNNECESSARY_SELF_IMPORTS]);\n\nimpl EarlyLintPass for UnnecessarySelfImports {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if let ItemKind::Use(use_tree) = &item.kind\n            && let UseTreeKind::Nested { items, .. } = &use_tree.kind\n            && let [(self_tree, _)] = &**items\n            && let [self_seg] = &*self_tree.prefix.segments\n            && self_seg.ident.name == kw::SelfLower\n            && let Some(last_segment) = use_tree.prefix.segments.last()\n        {\n            span_lint_and_then(\n                cx,\n                UNNECESSARY_SELF_IMPORTS,\n                item.span,\n                \"import ending with `::{self}`\",\n                |diag| {\n                    diag.span_suggestion(\n                        last_segment.span().with_hi(item.span.hi()),\n                        \"consider omitting `::{self}`\",\n                        format!(\n                            \"{}{};\",\n                            last_segment.ident,\n                            if let UseTreeKind::Simple(Some(alias)) = self_tree.kind {\n                                format!(\" as {alias}\")\n                            } else {\n                                String::new()\n                            },\n                        ),\n                        Applicability::MaybeIncorrect,\n                    );\n                    diag.note(\"this will slightly change semantics; any non-module items at the same path will also be imported\");\n                },\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_semicolon.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::leaks_droppable_temporary_with_limited_lifetime;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Block, ExprKind, HirId, MatchSource, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::edition::Edition::Edition2021;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the presence of a semicolon at the end of\n    /// a `match` or `if` statement evaluating to `()`.\n    ///\n    /// ### Why is this bad?\n    /// The semicolon is not needed, and may be removed to\n    /// avoid confusion and visual clutter.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let a: u32 = 42;\n    /// if a > 10 {\n    ///     println!(\"a is greater than 10\");\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # let a: u32 = 42;\n    /// if a > 10 {\n    ///     println!(\"a is greater than 10\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub UNNECESSARY_SEMICOLON,\n    pedantic,\n    \"unnecessary semicolon after expression returning `()`\"\n}\n\nimpl_lint_pass!(UnnecessarySemicolon => [UNNECESSARY_SEMICOLON]);\n\n#[derive(Default)]\npub struct UnnecessarySemicolon {\n    last_statements: Vec<(HirId, bool)>,\n}\n\nimpl UnnecessarySemicolon {\n    /// Enter or leave a block, remembering the last statement of the block.\n    fn handle_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>, enter: bool) {\n        // The last statement of an expressionless block deserves a special treatment.\n        if block.expr.is_none()\n            && let Some(last_stmt) = block.stmts.last()\n        {\n            if enter {\n                let block_ty = cx.typeck_results().node_type(block.hir_id);\n                self.last_statements.push((last_stmt.hir_id, block_ty.is_unit()));\n            } else {\n                self.last_statements.pop();\n            }\n        }\n    }\n\n    /// Checks if `stmt` is the last statement in an expressionless block. In this case,\n    /// return `Some` with a boolean which is `true` if the block type is `()`.\n    fn is_last_in_block(&self, stmt: &Stmt<'_>) -> Option<bool> {\n        self.last_statements\n            .last()\n            .and_then(|&(stmt_id, is_unit)| (stmt_id == stmt.hir_id).then_some(is_unit))\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnnecessarySemicolon {\n    fn check_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>) {\n        self.handle_block(cx, block, true);\n    }\n\n    fn check_block_post(&mut self, cx: &LateContext<'_>, block: &Block<'_>) {\n        self.handle_block(cx, block, false);\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'tcx>) {\n        // rustfmt already takes care of removing semicolons at the end\n        // of loops.\n        if let StmtKind::Semi(expr) = stmt.kind\n            && !stmt.span.from_expansion()\n            && !expr.span.from_expansion()\n            && matches!(\n                expr.kind,\n                ExprKind::If(..) | ExprKind::Match(_, _, MatchSource::Normal | MatchSource::Postfix)\n            )\n            && cx.typeck_results().expr_ty(expr).is_unit()\n            // if a stmt has attrs, then turning it into an expr will break the code, since attrs aren't allowed on exprs\n            // -- unless the corresponding feature is enabled\n            && (cx.tcx.hir_attrs(stmt.hir_id).is_empty() || cx.tcx.features().stmt_expr_attributes())\n        {\n            if let Some(block_is_unit) = self.is_last_in_block(stmt) {\n                if cx.tcx.sess.edition() <= Edition2021 && leaks_droppable_temporary_with_limited_lifetime(cx, expr) {\n                    // The expression contains temporaries with limited lifetimes in edition lower than 2024. Those may\n                    // survive until after the end of the current scope instead of until the end of the statement, so do\n                    // not lint this situation.\n                    return;\n                }\n\n                if !block_is_unit {\n                    // Although the expression returns `()`, the block doesn't. This may happen if the expression\n                    // returns early in all code paths, such as a `return value` in the condition of an `if` statement,\n                    // in which case the block type would be `!`. Do not lint in this case, as the statement would\n                    // become the block expression; the block type would become `()` and this may not type correctly\n                    // if the expected type for the block is not `()`.\n                    return;\n                }\n            }\n\n            let semi_span = expr.span.shrink_to_hi().to(stmt.span.shrink_to_hi());\n            span_lint_and_sugg(\n                cx,\n                UNNECESSARY_SEMICOLON,\n                semi_span,\n                \"unnecessary semicolon\",\n                \"remove\",\n                String::new(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_struct_initialization.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet;\nuse clippy_utils::ty::is_copy;\nuse clippy_utils::{get_parent_expr, is_mutable};\nuse rustc_hir::{Expr, ExprField, ExprKind, Path, QPath, StructTailExpr, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::{DesugaringKind, Ident};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for initialization of an identical `struct` from another instance\n    /// of the type, either by copying a base without setting any field or by\n    /// moving all fields individually.\n    ///\n    /// ### Why is this bad?\n    /// Readability suffers from unnecessary struct building.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct S { s: String }\n    ///\n    /// let a = S { s: String::from(\"Hello, world!\") };\n    /// let b = S { ..a };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct S { s: String }\n    ///\n    /// let a = S { s: String::from(\"Hello, world!\") };\n    /// let b = a;\n    /// ```\n    ///\n    /// The struct literal ``S { ..a }`` in the assignment to ``b`` could be replaced\n    /// with just ``a``.\n    ///\n    /// ### Known Problems\n    /// Has false positives when the base is a place expression that cannot be\n    /// moved out of, see [#10547](https://github.com/rust-lang/rust-clippy/issues/10547).\n    ///\n    /// Empty structs are ignored by the lint.\n    #[clippy::version = \"1.70.0\"]\n    pub UNNECESSARY_STRUCT_INITIALIZATION,\n    nursery,\n    \"struct built from a base that can be written mode concisely\"\n}\n\ndeclare_lint_pass!(UnnecessaryStruct => [UNNECESSARY_STRUCT_INITIALIZATION]);\n\nimpl LateLintPass<'_> for UnnecessaryStruct {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        let ExprKind::Struct(_, fields, base) = expr.kind else {\n            return;\n        };\n\n        let expr_span = expr.range_span().unwrap_or(expr.span);\n        if expr_span.from_expansion() {\n            // Prevent lint from hitting inside macro code\n            return;\n        }\n\n        let field_path = same_path_in_all_fields(cx, expr, fields);\n\n        let sugg = match (field_path, base) {\n            (Some(&path), StructTailExpr::None | StructTailExpr::DefaultFields(_)) => {\n                // all fields match, no base given\n                path.span\n            },\n            (Some(path), StructTailExpr::Base(base))\n                if base_is_suitable(cx, expr, base) && path_matches_base(path, base) =>\n            {\n                // all fields match, has base: ensure that the path of the base matches\n                base.span\n            },\n            (None, StructTailExpr::Base(base)) if fields.is_empty() && base_is_suitable(cx, expr, base) => {\n                // just the base, no explicit fields\n                base.span\n            },\n            _ => return,\n        };\n\n        span_lint_and_sugg(\n            cx,\n            UNNECESSARY_STRUCT_INITIALIZATION,\n            expr_span,\n            \"unnecessary struct building\",\n            \"replace with\",\n            snippet(cx, sugg, \"..\").into_owned(),\n            rustc_errors::Applicability::MachineApplicable,\n        );\n    }\n}\n\nfn base_is_suitable(cx: &LateContext<'_>, expr: &Expr<'_>, base: &Expr<'_>) -> bool {\n    if !check_references(cx, expr, base) {\n        return false;\n    }\n\n    // TODO: do not propose to replace *XX if XX is not Copy\n    if let ExprKind::Unary(UnOp::Deref, target) = base.kind\n        && matches!(target.kind, ExprKind::Path(..))\n        && !is_copy(cx, cx.typeck_results().expr_ty(expr))\n    {\n        // `*base` cannot be used instead of the struct in the general case if it is not Copy.\n        return false;\n    }\n    true\n}\n\n/// Check whether all fields of a struct assignment match.\n/// Returns a [Path] item that one can obtain a span from for the lint suggestion.\n///\n/// Conditions that must be satisfied to trigger this variant of the lint:\n///\n/// - source struct of the assignment must be of same type as the destination\n/// - names of destination struct fields must match the field names of the source\n///\n/// We don’t check here if all struct fields are assigned as the remainder may\n/// be filled in from a base struct.\nfn same_path_in_all_fields<'tcx>(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    fields: &[ExprField<'tcx>],\n) -> Option<&'tcx Path<'tcx>> {\n    let ty = cx.typeck_results().expr_ty(expr);\n\n    let mut found = None;\n\n    for f in fields {\n        // fields are assigned from expression\n        if let ExprKind::Field(src_expr, ident) = f.expr.kind\n            // expression type matches\n            && ty == cx.typeck_results().expr_ty(src_expr)\n            // field name matches\n            && ident_without_range_desugaring(f.ident) == ident\n            // assigned from a path expression\n            && let ExprKind::Path(QPath::Resolved(None, src_path)) = src_expr.kind\n        {\n            let Some((_, p)) = found else {\n                // this is the first field assignment in the list\n                found = Some((src_expr, src_path));\n                continue;\n            };\n\n            if p.res == src_path.res {\n                // subsequent field assignment with same origin struct as before\n                continue;\n            }\n        }\n        // source of field assignment doesn’t qualify\n        return None;\n    }\n\n    if let Some((src_expr, src_path)) = found\n        && check_references(cx, expr, src_expr)\n    {\n        Some(src_path)\n    } else {\n        None\n    }\n}\n\nfn check_references(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>) -> bool {\n    if let Some(parent) = get_parent_expr(cx, expr_a)\n        && let parent_ty = cx.typeck_results().expr_ty_adjusted(parent)\n        && parent_ty.is_any_ptr()\n    {\n        if is_copy(cx, cx.typeck_results().expr_ty(expr_a)) && expr_b.res_local_id().is_some() {\n            // When the type implements `Copy`, a reference to the new struct works on the\n            // copy. Using the original would borrow it.\n            return false;\n        }\n\n        if parent_ty.is_mutable_ptr() && !is_mutable(cx, expr_b) {\n            // The original can be used in a mutable reference context only if it is mutable.\n            return false;\n        }\n    }\n\n    true\n}\n\n/// When some fields are assigned from a base struct and others individually\n/// the lint applies only if the source of the field is the same as the base.\n/// This is enforced here by comparing the path of the base expression;\n/// needless to say the lint only applies if it (or whatever expression it is\n/// a reference of) actually has a path.\nfn path_matches_base(path: &Path<'_>, base: &Expr<'_>) -> bool {\n    let base_path = match base.kind {\n        ExprKind::Unary(UnOp::Deref, base_expr) => {\n            if let ExprKind::Path(QPath::Resolved(_, base_path)) = base_expr.kind {\n                base_path\n            } else {\n                return false;\n            }\n        },\n        ExprKind::Path(QPath::Resolved(_, base_path)) => base_path,\n        _ => return false,\n    };\n    path.res == base_path.res\n}\n\nfn ident_without_range_desugaring(ident: Ident) -> Ident {\n    if ident.span.desugaring_kind() == Some(DesugaringKind::RangeExpr) {\n        Ident {\n            span: ident.span.parent_callsite().unwrap(),\n            ..ident\n        }\n    } else {\n        ident\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnecessary_wraps.rs",
    "content": "use std::borrow::Cow;\n\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeQPath};\nuse clippy_utils::source::snippet;\nuse clippy_utils::visitors::find_all_ret_expressions;\nuse clippy_utils::{contains_return, return_ty};\nuse rustc_errors::Applicability;\nuse rustc_hir::LangItem::{OptionSome, ResultOk};\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, ExprKind, FnDecl, Impl, ItemKind, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::symbol::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for private functions that only return `Ok` or `Some`.\n    ///\n    /// ### Why is this bad?\n    /// It is not meaningful to wrap values when no `None` or `Err` is returned.\n    ///\n    /// ### Known problems\n    /// There can be false positives if the function signature is designed to\n    /// fit some external requirement.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn get_cool_number(a: bool, b: bool) -> Option<i32> {\n    ///     if a && b {\n    ///         return Some(50);\n    ///     }\n    ///     if a {\n    ///         Some(0)\n    ///     } else {\n    ///         Some(10)\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn get_cool_number(a: bool, b: bool) -> i32 {\n    ///     if a && b {\n    ///         return 50;\n    ///     }\n    ///     if a {\n    ///         0\n    ///     } else {\n    ///         10\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.50.0\"]\n    pub UNNECESSARY_WRAPS,\n    pedantic,\n    \"functions that only return `Ok` or `Some`\"\n}\n\nimpl_lint_pass!(UnnecessaryWraps => [UNNECESSARY_WRAPS]);\n\npub struct UnnecessaryWraps {\n    avoid_breaking_exported_api: bool,\n}\n\nimpl UnnecessaryWraps {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        fn_kind: FnKind<'tcx>,\n        fn_decl: &FnDecl<'tcx>,\n        body: &Body<'tcx>,\n        _span: Span,\n        def_id: LocalDefId,\n    ) {\n        // Abort if public function/method or closure.\n        match fn_kind {\n            FnKind::ItemFn(..) | FnKind::Method(..) => {\n                if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {\n                    return;\n                }\n            },\n            FnKind::Closure => return,\n        }\n\n        // Abort if the method is implementing a trait or of it a trait method.\n        let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);\n        if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id)\n            && matches!(\n                item.kind,\n                ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)\n            )\n        {\n            return;\n        }\n\n        // Get the wrapper and inner types, if can't, abort.\n        let (return_type_label, lang_item, inner_type) =\n            if let ty::Adt(adt_def, subst) = return_ty(cx, hir_id.expect_owner()).kind() {\n                match cx.tcx.get_diagnostic_name(adt_def.did()) {\n                    Some(sym::Option) => (\"Option\", OptionSome, subst.type_at(0)),\n                    Some(sym::Result) => (\"Result\", ResultOk, subst.type_at(0)),\n                    _ => return,\n                }\n            } else {\n                return;\n            };\n\n        // Check if all return expression respect the following condition and collect them.\n        let mut suggs = Vec::new();\n        let can_sugg = find_all_ret_expressions(cx, body.value, |ret_expr| {\n            if !ret_expr.span.from_expansion()\n                // Check if a function call.\n                && let ExprKind::Call(func, [arg]) = ret_expr.kind\n                && func.res(cx).ctor_parent(cx).is_lang_item(cx, lang_item)\n                // Make sure the function argument does not contain a return expression.\n                && !contains_return(arg)\n            {\n                suggs.push((\n                    ret_expr.span,\n                    if inner_type.is_unit() {\n                        String::new()\n                    } else {\n                        snippet(cx, arg.span.source_callsite(), \"..\").to_string()\n                    },\n                ));\n                true\n            } else {\n                false\n            }\n        });\n\n        if can_sugg && !suggs.is_empty() {\n            let (lint_msg, return_type_sugg_msg, return_type_sugg, body_sugg_msg) = if inner_type.is_unit() {\n                (\n                    \"this function's return value is unnecessary\".to_string(),\n                    \"remove the return type...\".to_string(),\n                    // FIXME: we should instead get the span including the `->` and suggest an\n                    // empty string for this case.\n                    Cow::Borrowed(\"()\"),\n                    Cow::Borrowed(\"...and then remove returned values\"),\n                )\n            } else {\n                let wrapper = if lang_item == OptionSome { \"Some\" } else { \"Ok\" };\n                (\n                    format!(\"this function's return value is unnecessarily wrapped by `{return_type_label}`\"),\n                    format!(\"remove `{return_type_label}` from the return type...\"),\n                    Cow::Owned(inner_type.to_string()),\n                    Cow::Owned(format!(\n                        \"...and then remove the surrounding `{wrapper}()` from returning expressions\"\n                    )),\n                )\n            };\n\n            span_lint_and_then(cx, UNNECESSARY_WRAPS, cx.tcx.def_span(def_id), lint_msg, |diag| {\n                diag.span_suggestion(\n                    fn_decl.output.span(),\n                    return_type_sugg_msg,\n                    return_type_sugg,\n                    Applicability::MaybeIncorrect,\n                );\n                diag.multipart_suggestion(body_sugg_msg, suggs, Applicability::MaybeIncorrect);\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unneeded_struct_pattern.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_from_proc_macro;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Pat, PatKind, QPath};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for struct patterns that match against unit variant.\n    ///\n    /// ### Why is this bad?\n    /// Struct pattern `{ }` or `{ .. }` is not needed for unit variant.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// match Some(42) {\n    ///     Some(v) => v,\n    ///     None { .. } => 0,\n    /// };\n    /// // Or\n    /// match Some(42) {\n    ///     Some(v) => v,\n    ///     None { } => 0,\n    /// };\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// match Some(42) {\n    ///     Some(v) => v,\n    ///     None => 0,\n    /// };\n    /// ```\n    #[clippy::version = \"1.86.0\"]\n    pub UNNEEDED_STRUCT_PATTERN,\n    style,\n    \"using struct pattern to match against unit variant\"\n}\n\ndeclare_lint_pass!(UnneededStructPattern => [UNNEEDED_STRUCT_PATTERN]);\n\nimpl LateLintPass<'_> for UnneededStructPattern {\n    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {\n        if !pat.span.from_expansion()\n            && let PatKind::Struct(path, [], _) = &pat.kind\n            && let QPath::Resolved(_, path) = path\n            && let Res::Def(DefKind::Variant, did) = path.res\n        {\n            let enum_did = cx.tcx.parent(did);\n            let variant = cx.tcx.adt_def(enum_did).variant_with_id(did);\n\n            let has_only_fields_brackets = variant.ctor.is_some() && variant.fields.is_empty();\n            let non_exhaustive_activated = variant.field_list_has_applicable_non_exhaustive();\n            if !has_only_fields_brackets || non_exhaustive_activated {\n                return;\n            }\n\n            if is_from_proc_macro(cx, *path) {\n                return;\n            }\n\n            if let Some(brackets_span) = pat.span.trim_start(path.span) {\n                span_lint_and_sugg(\n                    cx,\n                    UNNEEDED_STRUCT_PATTERN,\n                    brackets_span,\n                    \"struct pattern is not needed for a unit variant\",\n                    \"remove the struct pattern\",\n                    String::new(),\n                    Applicability::MachineApplicable,\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unnested_or_patterns.rs",
    "content": "#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]\n\nuse clippy_config::Conf;\nuse clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::msrvs::{self, MsrvStack};\nuse clippy_utils::over;\nuse rustc_ast::PatKind::*;\nuse rustc_ast::mut_visit::*;\nuse rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind, Pinnedness};\nuse rustc_ast_pretty::pprust;\nuse rustc_data_structures::thin_vec::{ThinVec, thin_vec};\nuse rustc_data_structures::thinvec::ExtractIf;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::DUMMY_SP;\n// import needed to shadow `PatKind::Box` glob-imported above\nuse std::boxed::Box;\nuse std::cell::Cell;\nuse std::mem;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnested or-patterns, e.g., `Some(0) | Some(2)` and\n    /// suggests replacing the pattern with a nested one, `Some(0 | 2)`.\n    ///\n    /// Another way to think of this is that it rewrites patterns in\n    /// *disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*.\n    ///\n    /// ### Why is this bad?\n    /// In the example above, `Some` is repeated, which unnecessarily complicates the pattern.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn main() {\n    ///     if let Some(0) | Some(2) = Some(0) {}\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn main() {\n    ///     if let Some(0 | 2) = Some(0) {}\n    /// }\n    /// ```\n    #[clippy::version = \"1.46.0\"]\n    pub UNNESTED_OR_PATTERNS,\n    pedantic,\n    \"unnested or-patterns, e.g., `Foo(Bar) | Foo(Baz) instead of `Foo(Bar | Baz)`\"\n}\n\nimpl_lint_pass!(UnnestedOrPatterns => [UNNESTED_OR_PATTERNS]);\n\npub struct UnnestedOrPatterns {\n    msrv: MsrvStack,\n}\n\nimpl UnnestedOrPatterns {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: MsrvStack::new(conf.msrv),\n        }\n    }\n}\n\nimpl EarlyLintPass for UnnestedOrPatterns {\n    fn check_arm(&mut self, cx: &EarlyContext<'_>, a: &ast::Arm) {\n        if self.msrv.meets(msrvs::OR_PATTERNS) {\n            lint_unnested_or_patterns(cx, &a.pat);\n        }\n    }\n\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {\n        if self.msrv.meets(msrvs::OR_PATTERNS)\n            && let ast::ExprKind::Let(pat, _, _, _) = &e.kind\n        {\n            lint_unnested_or_patterns(cx, pat);\n        }\n    }\n\n    fn check_param(&mut self, cx: &EarlyContext<'_>, p: &ast::Param) {\n        if self.msrv.meets(msrvs::OR_PATTERNS) {\n            lint_unnested_or_patterns(cx, &p.pat);\n        }\n    }\n\n    fn check_local(&mut self, cx: &EarlyContext<'_>, l: &ast::Local) {\n        if self.msrv.meets(msrvs::OR_PATTERNS) {\n            lint_unnested_or_patterns(cx, &l.pat);\n        }\n    }\n\n    extract_msrv_attr!();\n}\n\nfn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {\n    if let Ident(.., None) | Expr(_) | Wild | Path(..) | Range(..) | Rest | MacCall(_) = pat.kind {\n        // This is a leaf pattern, so cloning is unprofitable.\n        return;\n    }\n\n    let mut pat = pat.clone();\n\n    // Nix all the paren patterns everywhere so that they aren't in our way.\n    remove_all_parens(&mut pat);\n\n    // Transform all unnested or-patterns into nested ones, and if there were none, quit.\n    if !unnest_or_patterns(&mut pat) {\n        return;\n    }\n\n    span_lint_and_then(cx, UNNESTED_OR_PATTERNS, pat.span, \"unnested or-patterns\", |db| {\n        insert_necessary_parens(&mut pat);\n        db.span_suggestion_verbose(\n            pat.span,\n            \"nest the patterns\",\n            pprust::pat_to_string(&pat),\n            Applicability::MachineApplicable,\n        );\n    });\n}\n\n/// Remove all `(p)` patterns in `pat`.\nfn remove_all_parens(pat: &mut Pat) {\n    #[derive(Default)]\n    struct Visitor {\n        /// If is not in the outer most pattern. This is needed to avoid removing the outermost\n        /// parens because top-level or-patterns are not allowed in let statements.\n        is_inner: bool,\n    }\n\n    impl MutVisitor for Visitor {\n        fn visit_pat(&mut self, pat: &mut Pat) {\n            let is_inner = mem::replace(&mut self.is_inner, true);\n            walk_pat(self, pat);\n            let inner = match &mut pat.kind {\n                Paren(i) if is_inner => mem::replace(&mut i.kind, Wild),\n                _ => return,\n            };\n            pat.kind = inner;\n        }\n    }\n    Visitor::default().visit_pat(pat);\n}\n\n/// Insert parens where necessary according to Rust's precedence rules for patterns.\nfn insert_necessary_parens(pat: &mut Pat) {\n    struct Visitor;\n    impl MutVisitor for Visitor {\n        fn visit_pat(&mut self, pat: &mut Pat) {\n            use ast::BindingMode;\n            walk_pat(self, pat);\n            let target = match &mut pat.kind {\n                // `i @ a | b`, `box a | b`, and `& mut? a | b`.\n                Ident(.., Some(p)) | Box(p) | Ref(p, _, _)\n                    if let Or(ps) = &p.kind\n                        && ps.len() > 1 =>\n                {\n                    p\n                },\n                // `&(mut x)`\n                Ref(p, Pinnedness::Not, Mutability::Not) if matches!(p.kind, Ident(BindingMode::MUT, ..)) => p,\n                _ => return,\n            };\n            target.kind = Paren(Box::new(take_pat(target)));\n        }\n    }\n    Visitor.visit_pat(pat);\n}\n\n/// Unnest or-patterns `p0 | ... | p1` in the pattern `pat`.\n/// For example, this would transform `Some(0) | FOO | Some(2)` into `Some(0 | 2) | FOO`.\nfn unnest_or_patterns(pat: &mut Pat) -> bool {\n    struct Visitor {\n        changed: bool,\n    }\n    impl MutVisitor for Visitor {\n        fn visit_pat(&mut self, p: &mut Pat) {\n            // This is a bottom up transformation, so recurse first.\n            walk_pat(self, p);\n\n            // Don't have an or-pattern? Just quit early on.\n            let Or(alternatives) = &mut p.kind else { return };\n\n            // Collapse or-patterns directly nested in or-patterns.\n            let mut idx = 0;\n            let mut this_level_changed = false;\n            while idx < alternatives.len() {\n                let inner = if let Or(ps) = &mut alternatives[idx].kind {\n                    mem::take(ps)\n                } else {\n                    idx += 1;\n                    continue;\n                };\n                this_level_changed = true;\n                alternatives.splice(idx..=idx, inner);\n            }\n\n            // Focus on `p_n` and then try to transform all `p_i` where `i > n`.\n            let mut focus_idx = 0;\n            while focus_idx < alternatives.len() {\n                this_level_changed |= transform_with_focus_on_idx(alternatives, focus_idx);\n                focus_idx += 1;\n            }\n            self.changed |= this_level_changed;\n\n            // Deal with `Some(Some(0)) | Some(Some(1))`.\n            if this_level_changed {\n                walk_pat(self, p);\n            }\n        }\n    }\n\n    let mut visitor = Visitor { changed: false };\n    visitor.visit_pat(pat);\n    visitor.changed\n}\n\n/// Match `$scrutinee` against `$pat` and extract `$then` from it.\n/// Panics if there is no match.\nmacro_rules! always_pat {\n    ($scrutinee:expr, $pat:pat => $then:expr) => {\n        match $scrutinee {\n            $pat => $then,\n            _ => unreachable!(),\n        }\n    };\n}\n\n/// Focus on `focus_idx` in `alternatives`,\n/// attempting to extend it with elements of the same constructor `C`\n/// in `alternatives[focus_idx + 1..]`.\nfn transform_with_focus_on_idx(alternatives: &mut ThinVec<Pat>, focus_idx: usize) -> bool {\n    // Extract the kind; we'll need to make some changes in it.\n    let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, Wild);\n    // We'll focus on `alternatives[focus_idx]`,\n    // so we're draining from `alternatives[focus_idx + 1..]`.\n    let start = focus_idx + 1;\n\n    // We're trying to find whatever kind (~\"constructor\") we found in `alternatives[start..]`.\n    let changed = match &mut focus_kind {\n        Missing => unreachable!(),\n        // These pattern forms are \"leafs\" and do not have sub-patterns.\n        // Therefore they are not some form of constructor `C`,\n        // with which a pattern `C(p_0)` may be formed,\n        // which we would want to join with other `C(p_j)`s.\n        Ident(.., None) | Expr(_) | Wild | Err(_) | Never | Path(..) | Range(..) | Rest | MacCall(_)\n        // Skip immutable refs, as grouping them saves few characters,\n        // and almost always requires adding parens (increasing noisiness).\n        // In the case of only two patterns, replacement adds net characters.\n        // FIXME(pin_ergonomics): handle pinned patterns\n        | Ref(_, _, Mutability::Not)\n        // Dealt with elsewhere.\n        | Or(_) | Paren(_) | Deref(_) | Guard(..) => false,\n        // Transform `box x | ... | box y` into `box (x | y)`.\n        //\n        // The cases below until `Slice(...)` deal with *singleton* products.\n        // These patterns have the shape `C(p)`, and not e.g., `C(p0, ..., pn)`.\n        Box(target) => extend_with_matching(\n            target, start, alternatives,\n            |k| matches!(k, Box(_)),\n            |k| always_pat!(k, Box(p) => *p),\n        ),\n        // Transform `&mut x | ... | &mut y` into `&mut (x | y)`.\n        Ref(target, _, Mutability::Mut) => extend_with_matching(\n            target, start, alternatives,\n            |k| matches!(k, Ref(_, _, Mutability::Mut)),\n            |k| always_pat!(k, Ref(p, _, _) => *p),\n        ),\n        // Transform `b @ p0 | ... b @ p1` into `b @ (p0 | p1)`.\n        Ident(b1, i1, Some(target)) => extend_with_matching(\n            target, start, alternatives,\n            // Binding names must match.\n            |k| matches!(k, Ident(b2, i2, Some(_)) if b1 == b2 && eq_id(*i1, *i2)),\n            |k| always_pat!(k, Ident(_, _, Some(p)) => *p),\n        ),\n        // Transform `[pre, x, post] | ... | [pre, y, post]` into `[pre, x | y, post]`.\n        Slice(ps1) => extend_with_matching_product(\n            ps1, start, alternatives,\n            |k, ps1, idx| matches!(k, Slice(ps2) if eq_pre_post(ps1, ps2, idx)),\n            |k| always_pat!(k, Slice(ps) => ps),\n        ),\n        // Transform `(pre, x, post) | ... | (pre, y, post)` into `(pre, x | y, post)`.\n        Tuple(ps1) => extend_with_matching_product(\n            ps1, start, alternatives,\n            |k, ps1, idx| matches!(k, Tuple(ps2) if eq_pre_post(ps1, ps2, idx)),\n            |k| always_pat!(k, Tuple(ps) => ps),\n        ),\n        // Transform `S(pre, x, post) | ... | S(pre, y, post)` into `S(pre, x | y, post)`.\n        TupleStruct(qself1, path1, ps1) => extend_with_matching_product(\n            ps1, start, alternatives,\n            |k, ps1, idx| matches!(\n                k,\n                TupleStruct(qself2, path2, ps2)\n                    if eq_maybe_qself(qself1.as_deref(), qself2.as_deref())\n                       && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)\n            ),\n            |k| always_pat!(k, TupleStruct(_, _, ps) => ps),\n        ),\n        // Transform a record pattern `S { fp_0, ..., fp_n }`.\n        Struct(qself1, path1, fps1, rest1) => {\n            extend_with_struct_pat(qself1.as_deref(), path1, fps1, *rest1, start, alternatives)\n        },\n    };\n\n    alternatives[focus_idx].kind = focus_kind;\n    changed\n}\n\n/// Here we focusing on a record pattern `S { fp_0, ..., fp_n }`.\n/// In particular, for a record pattern, the order in which the field patterns is irrelevant.\n/// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern\n/// and check that all `fp_i` where `i ∈ ((0...n) \\ k)` between two patterns are equal.\nfn extend_with_struct_pat(\n    qself1: Option<&ast::QSelf>,\n    path1: &ast::Path,\n    fps1: &mut [ast::PatField],\n    rest1: ast::PatFieldsRest,\n    start: usize,\n    alternatives: &mut ThinVec<Pat>,\n) -> bool {\n    (0..fps1.len()).any(|idx| {\n        let pos_in_2 = Cell::new(None); // The element `k`.\n        let tail_or = drain_matching(\n            start,\n            alternatives,\n            |k| {\n                matches!(k, Struct(qself2, path2, fps2, rest2)\n                if rest1 == *rest2 // If one struct pattern has `..` so must the other.\n                && eq_maybe_qself(qself1, qself2.as_deref())\n                && eq_path(path1, path2)\n                && fps1.len() == fps2.len()\n                && fps1.iter().enumerate().all(|(idx_1, fp1)| {\n                    if idx_1 == idx {\n                        // In the case of `k`, we merely require identical field names\n                        // so that we will transform into `ident_k: p1_k | p2_k`.\n                        let pos = fps2.iter().position(|fp2| {\n                            // Avoid `Foo { bar } | Foo { bar }` => `Foo { bar | bar }`\n                            !(fp1.is_shorthand && fp2.is_shorthand)\n                                && eq_id(fp1.ident, fp2.ident)\n                        });\n                        pos_in_2.set(pos);\n                        pos.is_some()\n                    } else {\n                        fps2.iter().any(|fp2| eq_field_pat(fp1, fp2))\n                    }\n                }))\n            },\n            // Extract `p2_k`.\n            |k| always_pat!(k, Struct(_, _, mut fps, _) => *fps.swap_remove(pos_in_2.take().unwrap()).pat),\n        );\n        extend_with_tail_or(&mut fps1[idx].pat, tail_or)\n    })\n}\n\n/// Like `extend_with_matching` but for products with > 1 factor, e.g., `C(p_0, ..., p_n)`.\n/// Here, the idea is that we fixate on some `p_k` in `C`,\n/// allowing it to vary between two `targets` and `ps2` (returned by `extract`),\n/// while also requiring `ps1[..n] ~ ps2[..n]` (pre) and `ps1[n + 1..] ~ ps2[n + 1..]` (post),\n/// where `~` denotes semantic equality.\nfn extend_with_matching_product(\n    targets: &mut [Pat],\n    start: usize,\n    alternatives: &mut ThinVec<Pat>,\n    predicate: impl Fn(&PatKind, &[Pat], usize) -> bool,\n    extract: impl Fn(PatKind) -> ThinVec<Pat>,\n) -> bool {\n    (0..targets.len()).any(|idx| {\n        let tail_or = drain_matching(\n            start,\n            alternatives,\n            |k| predicate(k, targets, idx),\n            |k| extract(k).swap_remove(idx),\n        );\n        extend_with_tail_or(&mut targets[idx], tail_or)\n    })\n}\n\n/// Extract the pattern from the given one and replace it with `Wild`.\n/// This is meant for temporarily swapping out the pattern for manipulation.\nfn take_pat(from: &mut Pat) -> Pat {\n    let dummy = Pat {\n        id: DUMMY_NODE_ID,\n        kind: Wild,\n        span: DUMMY_SP,\n        tokens: None,\n    };\n    mem::replace(from, dummy)\n}\n\n/// Extend `target` as an or-pattern with the alternatives\n/// in `tail_or` if there are any and return if there were.\nfn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<Pat>) -> bool {\n    fn extend(target: &mut Pat, mut tail_or: ThinVec<Pat>) {\n        // On an existing or-pattern in the target, append to it,\n        // otherwise convert the target to an or-pattern.\n        if let Or(ps) = &mut target.kind {\n            ps.append(&mut tail_or);\n        } else {\n            let mut init_or = thin_vec![take_pat(target)];\n            init_or.append(&mut tail_or);\n            target.kind = Or(init_or);\n        }\n    }\n\n    let changed = !tail_or.is_empty();\n    if changed {\n        // Extend the target.\n        extend(target, tail_or);\n    }\n    changed\n}\n\n// Extract all inner patterns in `alternatives` matching our `predicate`.\n// Only elements beginning with `start` are considered for extraction.\nfn drain_matching(\n    start: usize,\n    alternatives: &mut ThinVec<Pat>,\n    predicate: impl Fn(&PatKind) -> bool,\n    extract: impl Fn(PatKind) -> Pat,\n) -> ThinVec<Pat> {\n    let mut tail_or = ThinVec::new();\n    let mut idx = 0;\n\n    // FIXME: once `thin-vec` releases a new version, change this to `alternatives.extract_if()`\n    // See https://github.com/mozilla/thin-vec/issues/77\n    for pat in ExtractIf::new(alternatives, |p| {\n        // Check if we should extract, but only if `idx >= start`.\n        idx += 1;\n        idx > start && predicate(&p.kind)\n    }) {\n        tail_or.push(extract(pat.kind));\n    }\n\n    tail_or\n}\n\nfn extend_with_matching(\n    target: &mut Pat,\n    start: usize,\n    alternatives: &mut ThinVec<Pat>,\n    predicate: impl Fn(&PatKind) -> bool,\n    extract: impl Fn(PatKind) -> Pat,\n) -> bool {\n    extend_with_tail_or(target, drain_matching(start, alternatives, predicate, extract))\n}\n\n/// Are the patterns in `ps1` and `ps2` equal save for `ps1[idx]` compared to `ps2[idx]`?\nfn eq_pre_post(ps1: &[Pat], ps2: &[Pat], idx: usize) -> bool {\n    ps1.len() == ps2.len()\n        && ps1[idx].is_rest() == ps2[idx].is_rest() // Avoid `[x, ..] | [x, 0]` => `[x, .. | 0]`.\n        && over(&ps1[..idx], &ps2[..idx], eq_pat)\n        && over(&ps1[idx + 1..], &ps2[idx + 1..], eq_pat)\n}\n"
  },
  {
    "path": "clippy_lints/src/unsafe_removed_from_name.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_ast::ast::{Item, ItemKind, UseTree, UseTreeKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::Ident;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for imports that remove \"unsafe\" from an item's\n    /// name.\n    ///\n    /// ### Why is this bad?\n    /// Renaming makes it less clear which traits and\n    /// structures are unsafe.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// use std::cell::{UnsafeCell as TotallySafeCell};\n    ///\n    /// extern crate crossbeam;\n    /// use crossbeam::{spawn_unsafe as spawn};\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNSAFE_REMOVED_FROM_NAME,\n    style,\n    \"`unsafe` removed from API names on import\"\n}\n\ndeclare_lint_pass!(UnsafeNameRemoval => [UNSAFE_REMOVED_FROM_NAME]);\n\nimpl EarlyLintPass for UnsafeNameRemoval {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if let ItemKind::Use(ref use_tree) = item.kind {\n            check_use_tree(use_tree, cx, item.span);\n        }\n    }\n}\n\nfn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {\n    match use_tree.kind {\n        UseTreeKind::Simple(Some(new_name)) => {\n            let old_name = use_tree\n                .prefix\n                .segments\n                .last()\n                .expect(\"use paths cannot be empty\")\n                .ident;\n            unsafe_to_safe_check(old_name, new_name, cx, span);\n        },\n        UseTreeKind::Simple(None) | UseTreeKind::Glob => {},\n        UseTreeKind::Nested { ref items, .. } => {\n            for (use_tree, _) in items {\n                check_use_tree(use_tree, cx, span);\n            }\n        },\n    }\n}\n\nfn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext<'_>, span: Span) {\n    let old_str = old_name.name.as_str();\n    let new_str = new_name.name.as_str();\n    if contains_unsafe(old_str) && !contains_unsafe(new_str) {\n        span_lint(\n            cx,\n            UNSAFE_REMOVED_FROM_NAME,\n            span,\n            format!(\"removed `unsafe` from the name of `{old_str}` in use as `{new_str}`\"),\n        );\n    }\n}\n\n#[must_use]\nfn contains_unsafe(name: &str) -> bool {\n    name.contains(\"Unsafe\") || name.contains(\"unsafe\")\n}\n"
  },
  {
    "path": "clippy_lints/src/unused_async.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::is_def_id_trait_method;\nuse clippy_utils::usage::is_todo_unimplemented_stub;\nuse rustc_hir::def::DefKind;\nuse rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};\nuse rustc_hir::{\n    Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, Defaultness, Expr, ExprKind, FnDecl, HirId, Node,\n    TraitItem, YieldSource,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::def_id::{LocalDefId, LocalDefIdSet};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions that are declared `async` but have no `.await`s inside of them.\n    ///\n    /// ### Why is this bad?\n    /// Async functions with no async code create overhead, both mentally and computationally.\n    /// Callers of async methods either need to be calling from an async function themselves or run it on an executor, both of which\n    /// causes runtime overhead and hassle for the caller.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// async fn get_random_number() -> i64 {\n    ///     4 // Chosen by fair dice roll. Guaranteed to be random.\n    /// }\n    /// let number_future = get_random_number();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// fn get_random_number_improved() -> i64 {\n    ///     4 // Chosen by fair dice roll. Guaranteed to be random.\n    /// }\n    /// let number_future = async { get_random_number_improved() };\n    /// ```\n    #[clippy::version = \"1.54.0\"]\n    pub UNUSED_ASYNC,\n    pedantic,\n    \"finds async functions with no await statements\"\n}\n\nimpl_lint_pass!(UnusedAsync => [UNUSED_ASYNC]);\n\n#[derive(Default)]\npub struct UnusedAsync {\n    /// Keeps track of async functions used as values (i.e. path expressions to async functions that\n    /// are not immediately called)\n    async_fns_as_value: LocalDefIdSet,\n    /// Functions with unused `async`, linted post-crate after we've found all uses of local async\n    /// functions\n    unused_async_fns: Vec<UnusedAsyncFn>,\n}\n\n#[derive(Copy, Clone)]\nstruct UnusedAsyncFn {\n    def_id: LocalDefId,\n    fn_span: Span,\n    await_in_async_block: Option<Span>,\n}\n\nstruct AsyncFnVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    found_await: bool,\n    /// Also keep track of `await`s in nested async blocks so we can mention\n    /// it in a note\n    await_in_async_block: Option<Span>,\n    async_depth: usize,\n}\n\nimpl<'tcx> Visitor<'tcx> for AsyncFnVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {\n        if let ExprKind::Yield(_, YieldSource::Await { .. }) = ex.kind {\n            if self.async_depth == 1 {\n                self.found_await = true;\n            } else if self.await_in_async_block.is_none() {\n                self.await_in_async_block = Some(ex.span);\n            }\n        }\n\n        let is_async_block = matches!(\n            ex.kind,\n            ExprKind::Closure(Closure {\n                kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)),\n                ..\n            })\n        );\n\n        if is_async_block {\n            self.async_depth += 1;\n        }\n\n        walk_expr(self, ex);\n\n        if is_async_block {\n            self.async_depth -= 1;\n        }\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnusedAsync {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        fn_kind: FnKind<'tcx>,\n        fn_decl: &'tcx FnDecl<'tcx>,\n        body: &Body<'tcx>,\n        span: Span,\n        def_id: LocalDefId,\n    ) {\n        if !span.from_expansion()\n            && fn_kind.asyncness().is_async()\n            && !is_def_id_trait_method(cx, def_id)\n            && !is_default_trait_impl(cx, def_id)\n            && !async_fn_contains_todo_unimplemented_macro(cx, body)\n        {\n            let mut visitor = AsyncFnVisitor {\n                cx,\n                found_await: false,\n                await_in_async_block: None,\n                async_depth: 0,\n            };\n            walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), def_id);\n            if !visitor.found_await {\n                // Don't lint just yet, but store the necessary information for later.\n                // The actual linting happens in `check_crate_post`, once we've found all\n                // uses of local async functions that do require asyncness to pass typeck\n                self.unused_async_fns.push(UnusedAsyncFn {\n                    def_id,\n                    fn_span: span,\n                    await_in_async_block: visitor.await_in_async_block,\n                });\n            }\n        }\n    }\n\n    fn check_path(&mut self, cx: &LateContext<'tcx>, path: &rustc_hir::Path<'tcx>, hir_id: HirId) {\n        // Find paths to local async functions that aren't immediately called.\n        // E.g. `async fn f() {}; let x = f;`\n        // Depending on how `x` is used, f's asyncness might be required despite not having any `await`\n        // statements, so don't lint at all if there are any such paths.\n        if let Some(def_id) = path.res.opt_def_id()\n            && let Some(local_def_id) = def_id.as_local()\n            && cx.tcx.def_kind(def_id) == DefKind::Fn\n            && cx.tcx.asyncness(def_id).is_async()\n            && let parent = cx.tcx.parent_hir_node(hir_id)\n            && !matches!(\n                parent,\n                Node::Expr(Expr {\n                    kind: ExprKind::Call(Expr { span, .. }, _),\n                    ..\n                }) if *span == path.span\n            )\n        {\n            self.async_fns_as_value.insert(local_def_id);\n        }\n    }\n\n    // After collecting all unused `async` and problematic paths to such functions,\n    // lint those unused ones that didn't have any path expressions to them.\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        let iter = self\n            .unused_async_fns\n            .iter()\n            .filter(|UnusedAsyncFn { def_id, .. }| !self.async_fns_as_value.contains(def_id));\n\n        for fun in iter {\n            span_lint_hir_and_then(\n                cx,\n                UNUSED_ASYNC,\n                cx.tcx.local_def_id_to_hir_id(fun.def_id),\n                fun.fn_span,\n                \"unused `async` for function with no await statements\",\n                |diag| {\n                    diag.help(\"consider removing the `async` from this function\");\n\n                    if let Some(span) = fun.await_in_async_block {\n                        diag.span_note(\n                            span,\n                            \"`await` used in an async block, which does not require \\\n                            the enclosing function to be `async`\",\n                        );\n                    }\n                },\n            );\n        }\n    }\n}\n\nfn is_default_trait_impl(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {\n    matches!(\n        cx.tcx.hir_node_by_def_id(def_id),\n        Node::TraitItem(TraitItem {\n            defaultness: Defaultness::Default { .. },\n            ..\n        })\n    )\n}\n\nfn async_fn_contains_todo_unimplemented_macro(cx: &LateContext<'_>, body: &Body<'_>) -> bool {\n    if let ExprKind::Closure(closure) = body.value.kind\n        && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) = closure.kind\n        && let body = cx.tcx.hir_body(closure.body)\n        && let ExprKind::Block(block, _) = body.value.kind\n        && block.stmts.is_empty()\n        && let Some(expr) = block.expr\n        && let ExprKind::DropTemps(inner) = expr.kind\n    {\n        return is_todo_unimplemented_stub(cx, inner);\n    }\n\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/unused_io_amount.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::macros::{is_panic, root_macro_call_first_node};\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::{paths, peel_blocks, sym};\nuse hir::{ExprKind, HirId, PatKind};\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unused written/read amount.\n    ///\n    /// ### Why is this bad?\n    /// `io::Write::write(_vectored)` and\n    /// `io::Read::read(_vectored)` are not guaranteed to\n    /// process the entire buffer. They return how many bytes were processed, which\n    /// might be smaller\n    /// than a given buffer's length. If you don't need to deal with\n    /// partial-write/read, use\n    /// `write_all`/`read_exact` instead.\n    ///\n    /// When working with asynchronous code (either with the `futures`\n    /// crate or with `tokio`), a similar issue exists for\n    /// `AsyncWriteExt::write()` and `AsyncReadExt::read()` : these\n    /// functions are also not guaranteed to process the entire\n    /// buffer.  Your code should either handle partial-writes/reads, or\n    /// call the `write_all`/`read_exact` methods on those traits instead.\n    ///\n    /// ### Known problems\n    /// Detects only common patterns.\n    ///\n    /// ### Examples\n    /// ```rust,ignore\n    /// use std::io;\n    /// fn foo<W: io::Write>(w: &mut W) -> io::Result<()> {\n    ///     w.write(b\"foo\")?;\n    ///     Ok(())\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// use std::io;\n    /// fn foo<W: io::Write>(w: &mut W) -> io::Result<()> {\n    ///     w.write_all(b\"foo\")?;\n    ///     Ok(())\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNUSED_IO_AMOUNT,\n    correctness,\n    \"unused written/read amount\"\n}\n\ndeclare_lint_pass!(UnusedIoAmount => [UNUSED_IO_AMOUNT]);\n\n#[derive(Copy, Clone)]\nenum IoOp {\n    AsyncWrite(bool),\n    AsyncRead(bool),\n    SyncRead(bool),\n    SyncWrite(bool),\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {\n    /// We perform the check on the block level.\n    /// If we want to catch match and if expressions that act as returns of the block\n    ///   we need to check them at `check_expr` or `check_block` as they are not stmts\n    ///   but we can't check them at `check_expr` because we need the broader context\n    ///   because we should do this only for the final expression of the block, and not for\n    ///   `StmtKind::Let` which binds values => the io amount is used.\n    ///\n    /// To check for unused io amount in stmts, we only consider `StmtKind::Semi`.\n    /// `StmtKind::Let` is not considered because it binds values => the io amount is used.\n    /// `StmtKind::Expr` is not considered because requires unit type => the io amount is used.\n    /// `StmtKind::Item` is not considered because it's not an expression.\n    ///\n    /// We then check the individual expressions via `check_expr`. We use the same logic for\n    /// semi expressions and the final expression as we need to check match and if expressions\n    /// for binding of the io amount to `Ok(_)`.\n    ///\n    /// We explicitly check for the match source to be Normal as it needs special logic\n    /// to consider the arms, and we want to avoid breaking the logic for situations where things\n    /// get desugared to match.\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'tcx>) {\n        let fn_def_id = block.hir_id.owner.to_def_id();\n        if let Some(impl_id) = cx.tcx.trait_impl_of_assoc(fn_def_id) {\n            let trait_id = cx.tcx.impl_trait_id(impl_id);\n            // We don't want to lint inside io::Read or io::Write implementations, as the author has more\n            // information about their trait implementation than our lint, see https://github.com/rust-lang/rust-clippy/issues/4836\n            if let Some(trait_name) = cx.tcx.get_diagnostic_name(trait_id)\n                && matches!(trait_name, sym::IoRead | sym::IoWrite)\n            {\n                return;\n            }\n\n            let async_paths = [\n                &paths::TOKIO_IO_ASYNCREADEXT,\n                &paths::TOKIO_IO_ASYNCWRITEEXT,\n                &paths::FUTURES_IO_ASYNCREADEXT,\n                &paths::FUTURES_IO_ASYNCWRITEEXT,\n            ];\n\n            if async_paths.into_iter().any(|path| path.matches(cx, trait_id)) {\n                return;\n            }\n        }\n\n        for stmt in block.stmts {\n            if let hir::StmtKind::Semi(exp) = stmt.kind {\n                check_expr(cx, exp);\n            }\n        }\n\n        if let Some(exp) = block.expr\n            && matches!(\n                exp.kind,\n                ExprKind::If(_, _, _) | ExprKind::Match(_, _, hir::MatchSource::Normal)\n            )\n        {\n            check_expr(cx, exp);\n        }\n    }\n}\n\nfn non_consuming_err_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {\n    // if there is a guard, we consider the result to be consumed\n    if arm.guard.is_some() {\n        return false;\n    }\n    if is_unreachable_or_panic(cx, arm.body) {\n        // if the body is unreachable or there is a panic,\n        // we consider the result to be consumed\n        return false;\n    }\n\n    if let PatKind::TupleStruct(ref path, [inner_pat], _) = arm.pat.kind {\n        return cx\n            .qpath_res(path, inner_pat.hir_id)\n            .ctor_parent(cx)\n            .is_lang_item(cx, hir::LangItem::ResultErr);\n    }\n\n    false\n}\n\nfn non_consuming_ok_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {\n    // if there is a guard, we consider the result to be consumed\n    if arm.guard.is_some() {\n        return false;\n    }\n    if is_unreachable_or_panic(cx, arm.body) {\n        // if the body is unreachable or there is a panic,\n        // we consider the result to be consumed\n        return false;\n    }\n\n    if is_ok_wild_or_dotdot_pattern(cx, arm.pat) {\n        return true;\n    }\n    false\n}\n\nfn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {\n    match expr.kind {\n        ExprKind::If(cond, _, _)\n            if let ExprKind::Let(hir::LetExpr { pat, init, .. }) = cond.kind\n                && is_ok_wild_or_dotdot_pattern(cx, pat)\n                && let Some(op) = should_lint(cx, init) =>\n        {\n            emit_lint(cx, cond.span, cond.hir_id, op, &[pat.span]);\n        },\n        // we will capture only the case where the match is Ok( ) or Err( )\n        // prefer to match the minimum possible, and expand later if needed\n        // to avoid false positives on something as used as this\n        ExprKind::Match(expr, [arm1, arm2], hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {\n            if non_consuming_ok_arm(cx, arm1) && non_consuming_err_arm(cx, arm2) {\n                emit_lint(cx, expr.span, expr.hir_id, op, &[arm1.pat.span]);\n            }\n            if non_consuming_ok_arm(cx, arm2) && non_consuming_err_arm(cx, arm1) {\n                emit_lint(cx, expr.span, expr.hir_id, op, &[arm2.pat.span]);\n            }\n        },\n        ExprKind::Match(_, _, hir::MatchSource::Normal) => {},\n        _ if let Some(op) = should_lint(cx, expr) => {\n            emit_lint(cx, expr.span, expr.hir_id, op, &[]);\n        },\n        _ => {},\n    }\n}\n\nfn should_lint<'a>(cx: &LateContext<'a>, mut inner: &'a hir::Expr<'a>) -> Option<IoOp> {\n    inner = unpack_match(inner);\n    inner = unpack_try(cx, inner);\n    inner = unpack_call_chain(inner);\n    inner = unpack_await(cx, inner);\n    // we type-check it to get whether it's a read/write or their vectorized forms\n    // and keep only the ones that are produce io amount\n    check_io_mode(cx, inner)\n}\n\nfn is_ok_wild_or_dotdot_pattern<'a>(cx: &LateContext<'a>, pat: &hir::Pat<'a>) -> bool {\n    // the if checks whether we are in a result Ok( ) pattern\n    // and the return checks whether it is unhandled\n\n    if let PatKind::TupleStruct(ref path, inner_pat, _) = pat.kind\n        // we check against Result::Ok to avoid linting on Err(_) or something else.\n        && cx.qpath_res(path, pat.hir_id).ctor_parent(cx).is_lang_item(cx, hir::LangItem::ResultOk)\n    {\n        if matches!(inner_pat, []) {\n            return true;\n        }\n\n        if let [cons_pat] = inner_pat\n            && matches!(cons_pat.kind, PatKind::Wild)\n        {\n            return true;\n        }\n        return false;\n    }\n    false\n}\n\n// this is partially taken from panic_unimplemented\nfn is_unreachable_or_panic(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {\n    let expr = peel_blocks(expr);\n    let Some(macro_call) = root_macro_call_first_node(cx, expr) else {\n        return false;\n    };\n    if is_panic(cx, macro_call.def_id) {\n        return !cx.tcx.hir_is_inside_const_context(expr.hir_id);\n    }\n    cx.tcx.is_diagnostic_item(sym::unreachable_macro, macro_call.def_id)\n}\n\nfn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {\n    while let ExprKind::MethodCall(path, receiver, ..) = expr.kind {\n        if matches!(\n            path.ident.name,\n            sym::unwrap\n                | sym::expect\n                | sym::unwrap_or\n                | sym::unwrap_or_else\n                | sym::ok\n                | sym::is_ok\n                | sym::is_err\n                | sym::or_else\n                | sym::or\n        ) {\n            expr = receiver;\n        } else {\n            break;\n        }\n    }\n    expr\n}\n\nfn unpack_try<'a>(cx: &LateContext<'_>, mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {\n    while let ExprKind::Call(func, [arg_0]) = expr.kind\n        && let ExprKind::Path(qpath) = func.kind\n        && cx.tcx.qpath_is_lang_item(qpath, hir::LangItem::TryTraitBranch)\n    {\n        expr = arg_0;\n    }\n    expr\n}\n\nfn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {\n    while let ExprKind::Match(res, _, _) = expr.kind {\n        expr = res;\n    }\n    expr\n}\n\n/// If `expr` is an (e).await, return the inner expression \"e\" that's being\n/// waited on.  Otherwise return None.\nfn unpack_await<'a>(cx: &LateContext<'_>, expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {\n    if let ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind\n        && let ExprKind::Call(func, [arg_0]) = expr.kind\n        && let ExprKind::Path(qpath) = func.kind\n        && cx.tcx.qpath_is_lang_item(qpath, hir::LangItem::IntoFutureIntoFuture)\n    {\n        return arg_0;\n    }\n    expr\n}\n\n/// Check whether the current expr is a function call for an IO operation\nfn check_io_mode(cx: &LateContext<'_>, call: &hir::Expr<'_>) -> Option<IoOp> {\n    let ExprKind::MethodCall(path, ..) = call.kind else {\n        return None;\n    };\n\n    let vectorized = match path.ident.as_str() {\n        \"write_vectored\" | \"read_vectored\" => true,\n        \"write\" | \"read\" => false,\n        _ => {\n            return None;\n        },\n    };\n\n    if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(call.hir_id)\n        && let Some(trait_def_id) = cx.tcx.trait_of_assoc(method_def_id)\n    {\n        if let Some(diag_name) = cx.tcx.get_diagnostic_name(trait_def_id) {\n            match diag_name {\n                sym::IoRead => Some(IoOp::SyncRead(vectorized)),\n                sym::IoWrite => Some(IoOp::SyncWrite(vectorized)),\n                _ => None,\n            }\n        } else if paths::FUTURES_IO_ASYNCREADEXT.matches(cx, trait_def_id)\n            || paths::TOKIO_IO_ASYNCREADEXT.matches(cx, trait_def_id)\n        {\n            Some(IoOp::AsyncRead(vectorized))\n        } else if paths::TOKIO_IO_ASYNCWRITEEXT.matches(cx, trait_def_id)\n            || paths::FUTURES_IO_ASYNCWRITEEXT.matches(cx, trait_def_id)\n        {\n            Some(IoOp::AsyncWrite(vectorized))\n        } else {\n            None\n        }\n    } else {\n        None\n    }\n}\n\nfn emit_lint(cx: &LateContext<'_>, span: Span, at: HirId, op: IoOp, wild_cards: &[Span]) {\n    let (msg, help) = match op {\n        IoOp::AsyncRead(false) => (\n            \"read amount is not handled\",\n            Some(\"use `AsyncReadExt::read_exact` instead, or handle partial reads\"),\n        ),\n        IoOp::SyncRead(false) => (\n            \"read amount is not handled\",\n            Some(\"use `Read::read_exact` instead, or handle partial reads\"),\n        ),\n        IoOp::SyncWrite(false) => (\n            \"written amount is not handled\",\n            Some(\"use `Write::write_all` instead, or handle partial writes\"),\n        ),\n        IoOp::AsyncWrite(false) => (\n            \"written amount is not handled\",\n            Some(\"use `AsyncWriteExt::write_all` instead, or handle partial writes\"),\n        ),\n        IoOp::SyncRead(true) | IoOp::AsyncRead(true) => (\"read amount is not handled\", None),\n        IoOp::SyncWrite(true) | IoOp::AsyncWrite(true) => (\"written amount is not handled\", None),\n    };\n\n    span_lint_hir_and_then(cx, UNUSED_IO_AMOUNT, at, span, msg, |diag| {\n        if let Some(help_str) = help {\n            diag.help(help_str);\n        }\n        for span in wild_cards {\n            diag.span_note(\n                *span,\n                \"the result is consumed here, but the amount of I/O bytes remains unhandled\",\n            );\n        }\n    });\n}\n"
  },
  {
    "path": "clippy_lints/src/unused_peekable.rs",
    "content": "use clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::ty::peel_and_count_ty_refs;\nuse clippy_utils::{fn_def_id, peel_ref_operators, sym};\nuse rustc_ast::Mutability;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{Block, Expr, ExprKind, HirId, LetStmt, Node, PatKind, PathSegment, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter::OnlyBodies;\nuse rustc_session::declare_lint_pass;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for the creation of a `peekable` iterator that is never `.peek()`ed\n    ///\n    /// ### Why is this bad?\n    /// Creating a peekable iterator without using any of its methods is likely a mistake,\n    /// or just a leftover after a refactor.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let collection = vec![1, 2, 3];\n    /// let iter = collection.iter().peekable();\n    ///\n    /// for item in iter {\n    ///     // ...\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let collection = vec![1, 2, 3];\n    /// let iter = collection.iter();\n    ///\n    /// for item in iter {\n    ///     // ...\n    /// }\n    /// ```\n    #[clippy::version = \"1.65.0\"]\n    pub UNUSED_PEEKABLE,\n    nursery,\n    \"creating a peekable iterator without using any of its methods\"\n}\n\ndeclare_lint_pass!(UnusedPeekable => [UNUSED_PEEKABLE]);\n\nimpl<'tcx> LateLintPass<'tcx> for UnusedPeekable {\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {\n        // Don't lint `Peekable`s returned from a block\n        if let Some(expr) = block.expr\n            && let Some(ty) = cx.typeck_results().expr_ty_opt(peel_ref_operators(cx, expr))\n            && ty.is_diag_item(cx, sym::IterPeekable)\n        {\n            return;\n        }\n\n        for (idx, stmt) in block.stmts.iter().enumerate() {\n            if !stmt.span.from_expansion()\n                && let StmtKind::Let(local) = stmt.kind\n                && let PatKind::Binding(_, binding, ident, _) = local.pat.kind\n                && let Some(init) = local.init\n                && !init.span.from_expansion()\n                && let Some(ty) = cx.typeck_results().expr_ty_opt(init)\n                && let (ty, _, None | Some(Mutability::Mut)) = peel_and_count_ty_refs(ty)\n                && ty.is_diag_item(cx, sym::IterPeekable)\n            {\n                let mut vis = PeekableVisitor::new(cx, binding);\n\n                if idx + 1 == block.stmts.len() && block.expr.is_none() {\n                    return;\n                }\n\n                let mut found_peek_call = block.stmts[idx..].iter().any(|stmt| vis.visit_stmt(stmt).is_break());\n\n                if !found_peek_call\n                    && let Some(expr) = block.expr\n                    && vis.visit_expr(expr).is_break()\n                {\n                    found_peek_call = true;\n                }\n\n                if !found_peek_call {\n                    span_lint_hir_and_then(\n                        cx,\n                        UNUSED_PEEKABLE,\n                        local.hir_id,\n                        ident.span,\n                        \"`peek` never called on `Peekable` iterator\",\n                        |diag| {\n                            diag.help(\"consider removing the call to `peekable`\");\n                        },\n                    );\n                }\n            }\n        }\n    }\n}\n\nstruct PeekableVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    expected_hir_id: HirId,\n}\n\nimpl<'a, 'tcx> PeekableVisitor<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>, expected_hir_id: HirId) -> Self {\n        Self { cx, expected_hir_id }\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {\n    type NestedFilter = OnlyBodies;\n    type Result = ControlFlow<()>;\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n\n    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> ControlFlow<()> {\n        if ex.res_local_id() == Some(self.expected_hir_id) {\n            for (_, node) in self.cx.tcx.hir_parent_iter(ex.hir_id) {\n                match node {\n                    Node::Expr(expr) => {\n                        match expr.kind {\n                            // some_function(peekable)\n                            //\n                            // If the Peekable is passed to a function, stop\n                            ExprKind::Call(_, args) => {\n                                if let Some(func_did) = fn_def_id(self.cx, expr)\n                                    && let Some(into_iter_did) = self.cx.tcx.lang_items().into_iter_fn()\n                                    && func_did == into_iter_did\n                                {\n                                    // Probably a for loop desugar, stop searching\n                                    return ControlFlow::Continue(());\n                                }\n\n                                if args.iter().any(|arg| arg_is_mut_peekable(self.cx, arg)) {\n                                    return ControlFlow::Break(());\n                                }\n\n                                return ControlFlow::Continue(());\n                            },\n                            // Catch anything taking a Peekable mutably\n                            ExprKind::MethodCall(\n                                PathSegment {\n                                    ident: method_name_ident,\n                                    ..\n                                },\n                                self_arg,\n                                remaining_args,\n                                _,\n                            ) => {\n                                let method_name = method_name_ident.name;\n\n                                // `Peekable` methods\n                                if matches!(method_name, sym::peek | sym::peek_mut | sym::next_if | sym::next_if_eq)\n                                    && arg_is_mut_peekable(self.cx, self_arg)\n                                {\n                                    return ControlFlow::Break(());\n                                }\n\n                                // foo.some_method() excluding Iterator methods\n                                if remaining_args.iter().any(|arg| arg_is_mut_peekable(self.cx, arg))\n                                    && !self\n                                        .cx\n                                        .ty_based_def(expr)\n                                        .opt_parent(self.cx)\n                                        .is_diag_item(self.cx, sym::Iterator)\n                                {\n                                    return ControlFlow::Break(());\n                                }\n\n                                // foo.by_ref(), keep checking for `peek`\n                                if method_name == sym::by_ref {\n                                    continue;\n                                }\n\n                                return ControlFlow::Continue(());\n                            },\n                            ExprKind::AddrOf(_, Mutability::Mut, _) | ExprKind::Unary(..) | ExprKind::DropTemps(_) => {\n                            },\n                            ExprKind::AddrOf(_, Mutability::Not, _) => return ControlFlow::Continue(()),\n                            _ => {\n                                return ControlFlow::Break(());\n                            },\n                        }\n                    },\n                    Node::LetStmt(LetStmt { init: Some(init), .. }) => {\n                        if arg_is_mut_peekable(self.cx, init) {\n                            return ControlFlow::Break(());\n                        }\n\n                        return ControlFlow::Continue(());\n                    },\n                    Node::Stmt(stmt) => {\n                        match stmt.kind {\n                            StmtKind::Let(_) | StmtKind::Item(_) => {\n                                return ControlFlow::Break(());\n                            },\n                            StmtKind::Expr(_) | StmtKind::Semi(_) => {},\n                        }\n\n                        return ControlFlow::Continue(());\n                    },\n                    Node::Block(_) | Node::ExprField(_) => {},\n                    _ => {\n                        return ControlFlow::Continue(());\n                    },\n                }\n            }\n        }\n\n        walk_expr(self, ex)\n    }\n}\n\nfn arg_is_mut_peekable(cx: &LateContext<'_>, arg: &Expr<'_>) -> bool {\n    if let Some(ty) = cx.typeck_results().expr_ty_opt(arg)\n        && let (ty, _, None | Some(Mutability::Mut)) = peel_and_count_ty_refs(ty)\n        && ty.is_diag_item(cx, sym::IterPeekable)\n    {\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unused_result_ok.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::source::snippet_with_context;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir::{ExprKind, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `Result::ok()` without using the returned `Option`.\n    ///\n    /// ### Why is this bad?\n    /// Using `Result::ok()` may look like the result is checked like `unwrap` or `expect` would do\n    /// but it only silences the warning caused by `#[must_use]` on the `Result`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # fn some_function() -> Result<(), ()> { Ok(()) }\n    /// some_function().ok();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # fn some_function() -> Result<(), ()> { Ok(()) }\n    /// let _ = some_function();\n    /// ```\n    #[clippy::version = \"1.82.0\"]\n    pub UNUSED_RESULT_OK,\n    restriction,\n    \"Use of `.ok()` to silence `Result`'s `#[must_use]` is misleading. Use `let _ =` instead.\"\n}\n\ndeclare_lint_pass!(UnusedResultOk => [UNUSED_RESULT_OK]);\n\nimpl LateLintPass<'_> for UnusedResultOk {\n    fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {\n        if let StmtKind::Semi(expr) = stmt.kind\n            && let ExprKind::MethodCall(ok_path, recv, [], ..) = expr.kind //check is expr.ok() has type Result<T,E>.ok(, _)\n            && ok_path.ident.name == sym::ok\n            && cx.typeck_results().expr_ty(recv).is_diag_item(cx, sym::Result)\n            && !stmt.span.in_external_macro(cx.sess().source_map())\n        {\n            let ctxt = expr.span.ctxt();\n            let mut applicability = Applicability::MaybeIncorrect;\n            let snippet = snippet_with_context(cx, recv.span, ctxt, \"\", &mut applicability).0;\n            let sugg = format!(\"let _ = {snippet}\");\n            span_lint_and_sugg(\n                cx,\n                UNUSED_RESULT_OK,\n                expr.span,\n                \"ignoring a result with `.ok()` is misleading\",\n                \"consider using `let _ =` and removing the call to `.ok()` instead\",\n                sugg,\n                applicability,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unused_rounding.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sym;\nuse rustc_ast::ast::{Expr, ExprKind, MethodCall};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Symbol;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// Detects cases where a whole-number literal float is being rounded, using\n    /// the `floor`, `ceil`, or `round` methods.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// This is unnecessary and confusing to the reader. Doing this is probably a mistake.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = 1f32.ceil();\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = 1f32;\n    /// ```\n    #[clippy::version = \"1.63.0\"]\n    pub UNUSED_ROUNDING,\n    nursery,\n    \"Uselessly rounding a whole number floating-point literal\"\n}\n\ndeclare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);\n\nfn is_useless_rounding(cx: &EarlyContext<'_>, expr: &Expr) -> Option<(Symbol, String)> {\n    if let ExprKind::MethodCall(box MethodCall {\n        seg: name_ident,\n        receiver,\n        ..\n    }) = &expr.kind\n        && let method_name = name_ident.ident.name\n        && matches!(method_name, sym::ceil | sym::floor | sym::round)\n        && let ExprKind::Lit(token_lit) = &receiver.kind\n        && token_lit.is_semantic_float()\n        && let Ok(f) = token_lit.symbol.as_str().replace('_', \"\").parse::<f64>()\n        && f.fract() == 0.0\n    {\n        Some((method_name, snippet(cx, receiver.span, \"..\").into()))\n    } else {\n        None\n    }\n}\n\nimpl EarlyLintPass for UnusedRounding {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let Some((method_name, float)) = is_useless_rounding(cx, expr) {\n            span_lint_and_sugg(\n                cx,\n                UNUSED_ROUNDING,\n                expr.span,\n                format!(\"used the `{method_name}` method with a whole number float\"),\n                format!(\"remove the `{method_name}` method call\"),\n                float,\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unused_self.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::usage::is_todo_unimplemented_stub;\nuse clippy_utils::visitors::is_local_used;\nuse rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::impl_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks methods that contain a `self` argument but don't use it\n    ///\n    /// ### Why is this bad?\n    /// It may be clearer to define the method as an associated function instead\n    /// of an instance method if it doesn't require `self`.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// struct A;\n    /// impl A {\n    ///     fn method(&self) {}\n    /// }\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```rust,ignore\n    /// struct A;\n    /// impl A {\n    ///     fn method() {}\n    /// }\n    /// ```\n    #[clippy::version = \"1.40.0\"]\n    pub UNUSED_SELF,\n    pedantic,\n    \"methods that contain a `self` argument but don't use it\"\n}\n\nimpl_lint_pass!(UnusedSelf => [UNUSED_SELF]);\n\npub struct UnusedSelf {\n    avoid_breaking_exported_api: bool,\n}\n\nimpl UnusedSelf {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnusedSelf {\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &ImplItem<'_>) {\n        if impl_item.span.from_expansion() {\n            return;\n        }\n        let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id;\n        let parent_item = cx.tcx.hir_expect_item(parent);\n        let assoc_item = cx.tcx.associated_item(impl_item.owner_id);\n        if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind\n            && assoc_item.is_method()\n            && let ImplItemKind::Fn(.., body_id) = &impl_item.kind\n            && (!cx.effective_visibilities.is_exported(impl_item.owner_id.def_id) || !self.avoid_breaking_exported_api)\n            && let body = cx.tcx.hir_body(*body_id)\n            && let [self_param, ..] = body.params\n            && !is_local_used(cx, body, self_param.pat.hir_id)\n            && !is_todo_unimplemented_stub(cx, body.value)\n        {\n            span_lint_and_help(\n                cx,\n                UNUSED_SELF,\n                self_param.span,\n                \"unused `self` argument\",\n                None,\n                \"consider refactoring to an associated function\",\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unused_trait_names.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::snippet_opt;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Item, ItemKind, UseKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Visibility;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `use Trait` where the Trait is only used for its methods and not referenced by a path directly.\n    ///\n    /// ### Why is this bad?\n    /// Traits imported that aren't used directly can be imported anonymously with `use Trait as _`.\n    /// It is more explicit, avoids polluting the current scope with unused names and can be useful to show which imports are required for traits.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::fmt::Write;\n    ///\n    /// fn main() {\n    ///     let mut s = String::new();\n    ///     let _ = write!(s, \"hello, world!\");\n    ///     println!(\"{s}\");\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// use std::fmt::Write as _;\n    ///\n    /// fn main() {\n    ///     let mut s = String::new();\n    ///     let _ = write!(s, \"hello, world!\");\n    ///     println!(\"{s}\");\n    /// }\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub UNUSED_TRAIT_NAMES,\n    restriction,\n    \"use items that import a trait but only use it anonymously\"\n}\n\nimpl_lint_pass!(UnusedTraitNames => [UNUSED_TRAIT_NAMES]);\n\npub struct UnusedTraitNames {\n    msrv: Msrv,\n}\n\nimpl UnusedTraitNames {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnusedTraitNames {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if !item.span.from_expansion()\n            && let ItemKind::Use(path, UseKind::Single(ident)) = item.kind\n            // Ignore imports that already use Underscore\n            && ident.name != kw::Underscore\n            // Only check traits\n            && let Some(Res::Def(DefKind::Trait, _)) = path.res.type_ns\n            && cx.tcx.resolutions(()).maybe_unused_trait_imports.contains(&item.owner_id.def_id)\n            // Only check this import if it is visible to its module only (no pub, pub(crate), ...)\n            && let module = cx.tcx.parent_module_from_def_id(item.owner_id.def_id)\n            && cx.tcx.visibility(item.owner_id.def_id) == Visibility::Restricted(module.to_def_id())\n            && let Some(last_segment) = path.segments.last()\n            && let Some(snip) = snippet_opt(cx, last_segment.ident.span)\n            && self.msrv.meets(cx, msrvs::UNDERSCORE_IMPORTS)\n            && !is_from_proc_macro(cx, &last_segment.ident)\n        {\n            let complete_span = last_segment.ident.span.to(ident.span);\n            span_lint_and_sugg(\n                cx,\n                UNUSED_TRAIT_NAMES,\n                complete_span,\n                \"importing trait that is only used anonymously\",\n                \"use\",\n                format!(\"{snip} as _\"),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unused_unit.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{SpanRangeExt, position_before_rarrow};\nuse clippy_utils::{is_never_expr, is_unit_expr};\nuse rustc_ast::{Block, StmtKind};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{\n    AssocItemConstraintKind, Body, Expr, ExprKind, FnDecl, FnRetTy, GenericArgsParentheses, PolyTraitRef, Term, Ty,\n    TyKind,\n};\nuse rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::edition::Edition;\nuse rustc_span::{BytePos, Pos as _, Span, sym};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unit (`()`) expressions that can be removed.\n    ///\n    /// ### Why is this bad?\n    /// Such expressions add no value, but can make the code\n    /// less readable. Depending on formatting they can make a `break` or `return`\n    /// statement look like a function call.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn return_unit() -> () {\n    ///     ()\n    /// }\n    /// ```\n    /// is equivalent to\n    /// ```no_run\n    /// fn return_unit() {}\n    /// ```\n    #[clippy::version = \"1.31.0\"]\n    pub UNUSED_UNIT,\n    style,\n    \"needless unit expression\"\n}\n\ndeclare_lint_pass!(UnusedUnit => [UNUSED_UNIT]);\n\nimpl<'tcx> LateLintPass<'tcx> for UnusedUnit {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'tcx>,\n        body: &'tcx Body<'tcx>,\n        span: Span,\n        _def_id: LocalDefId,\n    ) {\n        if let FnRetTy::Return(hir_ty) = decl.output\n            && is_unit_ty(hir_ty)\n            && !hir_ty.span.from_expansion()\n            && get_def(span) == get_def(hir_ty.span)\n        {\n            // The explicit `-> ()` in the closure signature might be necessary for multiple reasons:\n            // - Implicit types in closure signatures are forbidden when `for<...>` is present\n            // - If the closure body ends with a function call, and that function's return type is generic, the\n            //   `-> ()` could be required for it to be inferred\n            //\n            // There could be more reasons to have it, and, in general, we shouldn't discourage the users from\n            // writing more type annotations than strictly necessary, because it can help readability and\n            // maintainability\n            if let FnKind::Closure = kind {\n                return;\n            }\n\n            // unit never type fallback is no longer supported since Rust 2024. For more information,\n            // see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>\n            if cx.tcx.sess.edition() >= Edition::Edition2024\n                && let ExprKind::Block(block, _) = body.value.kind\n                && let Some(expr) = block.expr\n                && is_never_expr(cx, expr).is_some()\n            {\n                return;\n            }\n\n            lint_unneeded_unit_return(cx, hir_ty.span, span);\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Ret(Some(expr)) | ExprKind::Break(_, Some(expr)) = expr.kind\n            && is_unit_expr(expr)\n            && !expr.span.from_expansion()\n        {\n            span_lint_and_sugg(\n                cx,\n                UNUSED_UNIT,\n                expr.span,\n                \"unneeded `()`\",\n                \"remove the `()`\",\n                String::new(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n\n    fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>) {\n        if let [segment] = &poly.trait_ref.path.segments\n            && matches!(segment.ident.name, sym::Fn | sym::FnMut | sym::FnOnce)\n            && let Some(args) = segment.args\n            && args.parenthesized == GenericArgsParentheses::ParenSugar\n            && let [constraint] = &args.constraints\n            && constraint.ident.name == sym::Output\n            && let AssocItemConstraintKind::Equality { term: Term::Ty(hir_ty) } = constraint.kind\n            && args.span_ext.hi() != poly.span.hi()\n            && !hir_ty.span.from_expansion()\n            && args.span_ext.hi() != hir_ty.span.hi()\n            && is_unit_ty(hir_ty)\n        {\n            lint_unneeded_unit_return(cx, hir_ty.span, poly.span);\n        }\n    }\n}\n\nimpl EarlyLintPass for UnusedUnit {\n    /// Check for unit expressions in blocks. This is left in the early pass because some macros\n    /// expand its inputs as-is, making it invisible to the late pass. See #4076.\n    fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) {\n        if let Some(stmt) = block.stmts.last()\n            && let StmtKind::Expr(expr) = &stmt.kind\n            && let rustc_ast::ExprKind::Tup(inner) = &expr.kind\n            && inner.is_empty()\n            && let ctxt = block.span.ctxt()\n            && stmt.span.ctxt() == ctxt\n            && expr.span.ctxt() == ctxt\n            && expr.attrs.is_empty()\n        {\n            let sp = expr.span;\n            span_lint_and_sugg(\n                cx,\n                UNUSED_UNIT,\n                sp,\n                \"unneeded unit expression\",\n                \"remove the final `()`\",\n                String::new(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n\nfn is_unit_ty(ty: &Ty<'_>) -> bool {\n    matches!(ty.kind, TyKind::Tup([]))\n}\n\n// get the def site\n#[must_use]\nfn get_def(span: Span) -> Option<Span> {\n    if span.from_expansion() {\n        Some(span.ctxt().outer_expn_data().def_site)\n    } else {\n        None\n    }\n}\n\nfn lint_unneeded_unit_return(cx: &LateContext<'_>, ty_span: Span, span: Span) {\n    let (ret_span, appl) =\n        if let Some(Some(rpos)) = span.with_hi(ty_span.hi()).with_source_text(cx, position_before_rarrow) {\n            (\n                ty_span.with_lo(span.lo() + BytePos::from_usize(rpos)),\n                Applicability::MachineApplicable,\n            )\n        } else {\n            (ty_span, Applicability::MaybeIncorrect)\n        };\n\n    span_lint_and_sugg(\n        cx,\n        UNUSED_UNIT,\n        ret_span,\n        \"unneeded unit return type\",\n        \"remove the `-> ()`\",\n        String::new(),\n        appl,\n    );\n}\n"
  },
  {
    "path": "clippy_lints/src/unwrap.rs",
    "content": "use std::borrow::Cow;\nuse std::iter;\n\nuse clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::msrvs::Msrv;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::source::snippet;\nuse clippy_utils::usage::is_potentially_local_place;\nuse clippy_utils::{can_use_if_let_chains, higher, sym};\nuse rustc_abi::FieldIdx;\nuse rustc_errors::Applicability;\nuse rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};\nuse rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, UnOp};\nuse rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, Place, PlaceWithHirId};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::hir::place::ProjectionKind;\nuse rustc_middle::mir::FakeReadCause;\nuse rustc_middle::ty::{self, Ty, TyCtxt};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::def_id::LocalDefId;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls of `unwrap[_err]()` that will always fail.\n    ///\n    /// ### Why is this bad?\n    /// If panicking is desired, an explicit `panic!()` should be used.\n    ///\n    /// ### Known problems\n    /// This lint only checks `if` conditions not assignments.\n    /// So something like `let x: Option<()> = None; x.unwrap();` will not be recognized.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let option = Some(0);\n    /// # fn do_something_with(_x: usize) {}\n    /// if option.is_none() {\n    ///     do_something_with(option.unwrap())\n    /// }\n    /// ```\n    ///\n    /// This code will always panic. The if condition should probably be inverted.\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PANICKING_UNWRAP,\n    correctness,\n    \"checks for calls of `unwrap[_err]()` that will always fail\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls of `unwrap[_err]()` that cannot fail.\n    ///\n    /// ### Why is this bad?\n    /// Using `if let` or `match` is more idiomatic.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let option = Some(0);\n    /// # fn do_something_with(_x: usize) {}\n    /// if option.is_some() {\n    ///     do_something_with(option.unwrap())\n    /// }\n    /// ```\n    ///\n    /// Could be written:\n    ///\n    /// ```no_run\n    /// # let option = Some(0);\n    /// # fn do_something_with(_x: usize) {}\n    /// if let Some(value) = option {\n    ///     do_something_with(value)\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub UNNECESSARY_UNWRAP,\n    complexity,\n    \"checks for calls of `unwrap[_err]()` that cannot fail\"\n}\n\nimpl_lint_pass!(Unwrap => [PANICKING_UNWRAP, UNNECESSARY_UNWRAP]);\n\npub(crate) struct Unwrap {\n    msrv: Msrv,\n}\n\nimpl Unwrap {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self { msrv: conf.msrv }\n    }\n}\n\n/// Visitor that keeps track of which variables are unwrappable.\nstruct UnwrappableVariablesVisitor<'a, 'tcx> {\n    unwrappables: Vec<UnwrapInfo<'tcx>>,\n    cx: &'a LateContext<'tcx>,\n    msrv: Msrv,\n}\n\n/// What kind of unwrappable this is.\n#[derive(Copy, Clone, Debug)]\nenum UnwrappableKind {\n    Option,\n    Result,\n}\n\nimpl UnwrappableKind {\n    fn success_variant_pattern(self) -> &'static str {\n        match self {\n            UnwrappableKind::Option => \"Some(<item>)\",\n            UnwrappableKind::Result => \"Ok(<item>)\",\n        }\n    }\n\n    fn error_variant_pattern(self) -> &'static str {\n        match self {\n            UnwrappableKind::Option => \"None\",\n            UnwrappableKind::Result => \"Err(<item>)\",\n        }\n    }\n}\n\n#[derive(Clone, Debug, Eq)]\nenum Local {\n    /// `x.field1.field2.field3`\n    WithFieldAccess {\n        local_id: HirId,\n        /// The indices of the field accessed.\n        ///\n        /// Stored last-to-first, e.g. for the example above: `[field3, field2, field1]`\n        field_indices: Vec<FieldIdx>,\n        /// The span of the whole expression\n        span: Span,\n    },\n    /// `x`\n    Pure { local_id: HirId },\n}\n\n/// Identical to derived impl, but ignores `span` on [`Local::WithFieldAccess`]\nimpl PartialEq for Local {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (\n                Self::WithFieldAccess {\n                    local_id: self_local_id,\n                    field_indices: self_field_indices,\n                    ..\n                },\n                Self::WithFieldAccess {\n                    local_id: other_local_id,\n                    field_indices: other_field_indices,\n                    ..\n                },\n            ) => self_local_id == other_local_id && self_field_indices == other_field_indices,\n            (\n                Self::Pure {\n                    local_id: self_local_id,\n                },\n                Self::Pure {\n                    local_id: other_local_id,\n                },\n            ) => self_local_id == other_local_id,\n            _ => false,\n        }\n    }\n}\n\nimpl Local {\n    fn snippet(&self, cx: &LateContext<'_>) -> Cow<'static, str> {\n        match *self {\n            Self::WithFieldAccess { span, .. } => snippet(cx.sess(), span, \"_\"),\n            Self::Pure { local_id } => cx.tcx.hir_name(local_id).to_string().into(),\n        }\n    }\n\n    fn is_potentially_local_place(&self, place: &Place<'_>) -> bool {\n        match self {\n            Self::WithFieldAccess {\n                local_id,\n                field_indices,\n                ..\n            } => {\n                let field_projections = place\n                    .projections\n                    .iter()\n                    .filter(|proj| matches!(proj.kind, ProjectionKind::Field(_, _)))\n                    .collect::<Vec<_>>();\n                is_potentially_local_place(*local_id, place)\n                    // If there were projections other than field projections, err on the side of caution and say that they\n                    // _might_ be mutating something.\n                    //\n                    // The reason we use `<=` and not `==` is that a mutation of `struct` or `struct.field1` should count as\n                    // mutation of the child fields such as `struct.field1.field2`\n                    && field_projections.len() <= field_indices.len()\n                    && iter::zip(&field_projections, field_indices.iter().copied().rev()).all(|(proj, field_idx)| {\n                         match proj.kind {\n                            ProjectionKind::Field(f_idx, _) => f_idx == field_idx,\n                                // If this is a projection we don't expect, it _might_ be mutating something\n                                _ => false,\n                        }\n                    })\n            },\n            Self::Pure { local_id } => is_potentially_local_place(*local_id, place),\n        }\n    }\n}\n\n/// Contains information about whether a variable can be unwrapped.\n#[derive(Clone, Debug)]\nstruct UnwrapInfo<'tcx> {\n    /// The variable that is checked\n    local: Local,\n    /// The if itself\n    if_expr: &'tcx Expr<'tcx>,\n    /// The check, like `x.is_ok()`\n    check: &'tcx Expr<'tcx>,\n    /// The check's name, like `is_ok`\n    check_name: Symbol,\n    /// The branch where the check takes place, like `if x.is_ok() { .. }`\n    branch: &'tcx Expr<'tcx>,\n    /// Whether `is_some()` or `is_ok()` was called (as opposed to `is_err()` or `is_none()`).\n    safe_to_unwrap: bool,\n    /// What kind of unwrappable this is.\n    kind: UnwrappableKind,\n    /// If the check is the entire condition (`if x.is_ok()`) or only a part of it (`foo() &&\n    /// x.is_ok()`)\n    is_entire_condition: bool,\n}\n\n/// Collects the information about unwrappable variables from an if condition\n/// The `invert` argument tells us whether the condition is negated.\nfn collect_unwrap_info<'tcx>(\n    cx: &LateContext<'tcx>,\n    if_expr: &'tcx Expr<'_>,\n    expr: &'tcx Expr<'_>,\n    branch: &'tcx Expr<'_>,\n    invert: bool,\n    is_entire_condition: bool,\n) -> Vec<UnwrapInfo<'tcx>> {\n    fn option_or_result_call(cx: &LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> Option<(UnwrappableKind, bool)> {\n        match (ty.opt_diag_name(cx)?, method_name) {\n            (sym::Option, sym::is_some) => Some((UnwrappableKind::Option, true)),\n            (sym::Option, sym::is_none) => Some((UnwrappableKind::Option, false)),\n            (sym::Result, sym::is_ok) => Some((UnwrappableKind::Result, true)),\n            (sym::Result, sym::is_err) => Some((UnwrappableKind::Result, false)),\n            _ => None,\n        }\n    }\n\n    fn inner<'tcx>(\n        cx: &LateContext<'tcx>,\n        if_expr: &'tcx Expr<'_>,\n        expr: &'tcx Expr<'_>,\n        branch: &'tcx Expr<'_>,\n        invert: bool,\n        is_entire_condition: bool,\n        out: &mut Vec<UnwrapInfo<'tcx>>,\n    ) {\n        match expr.kind {\n            ExprKind::Binary(op, left, right)\n                if matches!(\n                    (invert, op.node),\n                    (false, BinOpKind::And | BinOpKind::BitAnd) | (true, BinOpKind::Or | BinOpKind::BitOr)\n                ) =>\n            {\n                inner(cx, if_expr, left, branch, invert, false, out);\n                inner(cx, if_expr, right, branch, invert, false, out);\n            },\n            ExprKind::Unary(UnOp::Not, expr) => inner(cx, if_expr, expr, branch, !invert, false, out),\n            ExprKind::MethodCall(method_name, receiver, [], _)\n                if let Some(local) = extract_local(cx, receiver)\n                    && let ty = cx.typeck_results().expr_ty(receiver)\n                    && let name = method_name.ident.name\n                    && let Some((kind, unwrappable)) = option_or_result_call(cx, ty, name) =>\n            {\n                let safe_to_unwrap = unwrappable != invert;\n\n                out.push(UnwrapInfo {\n                    local,\n                    if_expr,\n                    check: expr,\n                    check_name: name,\n                    branch,\n                    safe_to_unwrap,\n                    kind,\n                    is_entire_condition,\n                });\n            },\n            _ => {},\n        }\n    }\n\n    let mut out = vec![];\n    inner(cx, if_expr, expr, branch, invert, is_entire_condition, &mut out);\n    out\n}\n\n/// Extracts either a local used by itself ([`Local::Pure`]), or (one or more levels of) field\n/// access to a local ([`Local::WithFieldAccess`])\nfn extract_local(cx: &LateContext<'_>, mut expr: &Expr<'_>) -> Option<Local> {\n    let span = expr.span;\n    let mut field_indices = vec![];\n    while let ExprKind::Field(recv, _) = expr.kind\n        && let Some(field_idx) = cx.typeck_results().opt_field_index(expr.hir_id)\n    {\n        field_indices.push(field_idx);\n        expr = recv;\n    }\n    if let Some(local_id) = expr.res_local_id() {\n        if field_indices.is_empty() {\n            Some(Local::Pure { local_id })\n        } else {\n            Some(Local::WithFieldAccess {\n                local_id,\n                field_indices,\n                span,\n            })\n        }\n    } else {\n        None\n    }\n}\n\n/// A HIR visitor delegate that checks if a local variable of type `Option` or `Result` is mutated,\n/// *except* for if `.as_mut()` is called.\n/// The reason for why we allow that one specifically is that `.as_mut()` cannot change\n/// the variant, and that is important because this lint relies on the fact that\n/// `is_some` + `unwrap` is equivalent to `if let Some(..) = ..`, which it would not be if\n/// the option is changed to None between `is_some` and `unwrap`, ditto for `Result`.\n/// (And also `.as_mut()` is a somewhat common method that is still worth linting on.)\nstruct MutationVisitor<'tcx, 'lcl> {\n    is_mutated: bool,\n    local: &'lcl Local,\n    tcx: TyCtxt<'tcx>,\n}\n\n/// Checks if the parent of the expression pointed at by the given `HirId` is a call to\n/// `.as_mut()`.\n///\n/// Used by the mutation visitor to specifically allow `.as_mut()` calls.\n/// In particular, the `HirId` that the visitor receives is the id of the local expression\n/// (i.e. the `x` in `x.as_mut()`), and that is the reason for why we care about its parent\n/// expression: that will be where the actual method call is.\nfn is_as_mut_use(tcx: TyCtxt<'_>, expr_id: HirId) -> bool {\n    if let Node::Expr(mutating_expr) = tcx.parent_hir_node(expr_id)\n        && let ExprKind::MethodCall(path, _, [], _) = mutating_expr.kind\n    {\n        path.ident.name == sym::as_mut\n    } else {\n        false\n    }\n}\n\nimpl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx, '_> {\n    fn borrow(&mut self, cat: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) {\n        if let ty::BorrowKind::Mutable = bk\n            && self.local.is_potentially_local_place(&cat.place)\n            && !is_as_mut_use(self.tcx, diag_expr_id)\n        {\n            self.is_mutated = true;\n        }\n    }\n\n    fn mutate(&mut self, cat: &PlaceWithHirId<'tcx>, _: HirId) {\n        if self.local.is_potentially_local_place(&cat.place) {\n            self.is_mutated = true;\n        }\n    }\n\n    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}\n}\n\nimpl<'tcx> UnwrappableVariablesVisitor<'_, 'tcx> {\n    fn visit_branch(\n        &mut self,\n        if_expr: &'tcx Expr<'_>,\n        cond: &'tcx Expr<'_>,\n        branch: &'tcx Expr<'_>,\n        else_branch: bool,\n    ) {\n        let prev_len = self.unwrappables.len();\n        for unwrap_info in collect_unwrap_info(self.cx, if_expr, cond, branch, else_branch, true) {\n            let mut delegate = MutationVisitor {\n                is_mutated: false,\n                local: &unwrap_info.local,\n                tcx: self.cx.tcx,\n            };\n\n            let vis = ExprUseVisitor::for_clippy(self.cx, cond.hir_id.owner.def_id, &mut delegate);\n            vis.walk_expr(cond).into_ok();\n            vis.walk_expr(branch).into_ok();\n\n            if delegate.is_mutated {\n                // if the variable is mutated, we don't know whether it can be unwrapped.\n                // it might have been changed to `None` in between `is_some` + `unwrap`.\n                continue;\n            }\n            self.unwrappables.push(unwrap_info);\n        }\n        walk_expr(self, branch);\n        self.unwrappables.truncate(prev_len);\n    }\n}\n\nenum AsRefKind {\n    AsRef,\n    AsMut,\n}\n\n/// Checks if the expression is a method call to `as_{ref,mut}` and returns the receiver of it.\n/// If it isn't, the expression itself is returned.\nfn consume_option_as_ref<'tcx>(expr: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, Option<AsRefKind>) {\n    if let ExprKind::MethodCall(path, recv, [], _) = expr.kind {\n        match path.ident.name {\n            sym::as_ref => (recv, Some(AsRefKind::AsRef)),\n            sym::as_mut => (recv, Some(AsRefKind::AsMut)),\n            _ => (expr, None),\n        }\n    } else {\n        (expr, None)\n    }\n}\n\nimpl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {\n        // Shouldn't lint when `expr` is in macro.\n        if expr.span.in_external_macro(self.cx.tcx.sess.source_map()) {\n            walk_expr(self, expr);\n            return;\n        }\n        // Skip checking inside closures since they are visited through `Unwrap::check_fn()` already.\n        if matches!(expr.kind, ExprKind::Closure(_)) {\n            return;\n        }\n        if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr) {\n            walk_expr(self, cond);\n            self.visit_branch(expr, cond, then, false);\n            if let Some(else_inner) = r#else {\n                self.visit_branch(expr, cond, else_inner, true);\n            }\n        } else {\n            // find `unwrap[_err]()` or `expect(\"...\")` calls:\n            if let ExprKind::MethodCall(method_name, self_arg, ..) = expr.kind\n                && let (self_arg, as_ref_kind) = consume_option_as_ref(self_arg)\n                && let Some(local) = extract_local(self.cx, self_arg)\n                && matches!(method_name.ident.name, sym::unwrap | sym::expect | sym::unwrap_err)\n                && let call_to_unwrap = matches!(method_name.ident.name, sym::unwrap | sym::expect)\n                && let Some(unwrappable) = self.unwrappables.iter().find(|u| u.local == local)\n                // Span contexts should not differ with the conditional branch\n                && let span_ctxt = expr.span.ctxt()\n                && unwrappable.branch.span.ctxt() == span_ctxt\n                && unwrappable.check.span.ctxt() == span_ctxt\n            {\n                if call_to_unwrap == unwrappable.safe_to_unwrap {\n                    let unwrappable_variable_str = unwrappable.local.snippet(self.cx);\n\n                    span_lint_hir_and_then(\n                        self.cx,\n                        UNNECESSARY_UNWRAP,\n                        expr.hir_id,\n                        expr.span,\n                        format!(\n                            \"called `{}` on `{unwrappable_variable_str}` after checking its variant with `{}`\",\n                            method_name.ident.name, unwrappable.check_name,\n                        ),\n                        |diag| {\n                            if unwrappable.is_entire_condition {\n                                diag.span_suggestion(\n                                    unwrappable.check.span.with_lo(unwrappable.if_expr.span.lo()),\n                                    \"try\",\n                                    format!(\n                                        \"if let {suggested_pattern} = {borrow_prefix}{unwrappable_variable_str}\",\n                                        suggested_pattern = if call_to_unwrap {\n                                            unwrappable.kind.success_variant_pattern()\n                                        } else {\n                                            unwrappable.kind.error_variant_pattern()\n                                        },\n                                        borrow_prefix = match as_ref_kind {\n                                            Some(AsRefKind::AsRef) => \"&\",\n                                            Some(AsRefKind::AsMut) => \"&mut \",\n                                            None => \"\",\n                                        },\n                                    ),\n                                    // We don't track how the unwrapped value is used inside the\n                                    // block or suggest deleting the unwrap, so we can't offer a\n                                    // fixable solution.\n                                    Applicability::Unspecified,\n                                );\n                            } else {\n                                diag.span_label(unwrappable.check.span, \"the check is happening here\");\n                                if can_use_if_let_chains(self.cx, self.msrv) {\n                                    diag.help(\"try using `if let` or `match`\");\n                                } else {\n                                    diag.help(\"try using `match`\");\n                                }\n                            }\n                        },\n                    );\n                } else {\n                    span_lint_hir_and_then(\n                        self.cx,\n                        PANICKING_UNWRAP,\n                        expr.hir_id,\n                        expr.span,\n                        format!(\"this call to `{}()` will always panic\", method_name.ident.name),\n                        |diag| {\n                            diag.span_label(unwrappable.check.span, \"because of this check\");\n                        },\n                    );\n                }\n            }\n            walk_expr(self, expr);\n        }\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Unwrap {\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        decl: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        span: Span,\n        fn_id: LocalDefId,\n    ) {\n        if span.from_expansion() {\n            return;\n        }\n\n        let mut v = UnwrappableVariablesVisitor {\n            unwrappables: Vec::new(),\n            cx,\n            msrv: self.msrv,\n        };\n\n        walk_fn(&mut v, kind, decl, body.id(), fn_id);\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/unwrap_in_result.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::{return_ty, sym};\nuse rustc_hir::{\n    Body, BodyOwnerKind, Expr, ExprKind, FnSig, ImplItem, ImplItemKind, Item, ItemKind, OwnerId, PathSegment, QPath,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Ident, Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for functions of type `Result` that contain `expect()` or `unwrap()`\n    ///\n    /// ### Why restrict this?\n    /// These functions promote recoverable errors to non-recoverable errors,\n    /// which may be undesirable in code bases which wish to avoid panics,\n    /// or be a bug in the specific function.\n    ///\n    /// ### Known problems\n    /// This can cause false positives in functions that handle both recoverable and non recoverable errors.\n    ///\n    /// ### Example\n    /// Before:\n    /// ```no_run\n    /// fn divisible_by_3(i_str: String) -> Result<(), String> {\n    ///     let i = i_str\n    ///         .parse::<i32>()\n    ///         .expect(\"cannot divide the input by three\");\n    ///\n    ///     if i % 3 != 0 {\n    ///         Err(\"Number is not divisible by 3\")?\n    ///     }\n    ///\n    ///     Ok(())\n    /// }\n    /// ```\n    ///\n    /// After:\n    /// ```no_run\n    /// fn divisible_by_3(i_str: String) -> Result<(), String> {\n    ///     let i = i_str\n    ///         .parse::<i32>()\n    ///         .map_err(|e| format!(\"cannot divide the input by three: {}\", e))?;\n    ///\n    ///     if i % 3 != 0 {\n    ///         Err(\"Number is not divisible by 3\")?\n    ///     }\n    ///\n    ///     Ok(())\n    /// }\n    /// ```\n    #[clippy::version = \"1.48.0\"]\n    pub UNWRAP_IN_RESULT,\n    restriction,\n    \"functions of type `Result<..>` or `Option`<...> that contain `expect()` or `unwrap()`\"\n}\n\nimpl_lint_pass!(UnwrapInResult => [UNWRAP_IN_RESULT]);\n\n#[derive(Clone, Copy, Eq, PartialEq)]\nenum OptionOrResult {\n    Option,\n    Result,\n}\n\nimpl OptionOrResult {\n    fn with_article(self) -> &'static str {\n        match self {\n            Self::Option => \"an `Option`\",\n            Self::Result => \"a `Result`\",\n        }\n    }\n}\n\nstruct OptionOrResultFn {\n    kind: OptionOrResult,\n    return_ty_span: Option<Span>,\n}\n\n#[derive(Default)]\npub struct UnwrapInResult {\n    fn_stack: Vec<Option<OptionOrResultFn>>,\n    current_fn: Option<OptionOrResultFn>,\n}\n\nimpl UnwrapInResult {\n    fn enter_item(&mut self, cx: &LateContext<'_>, fn_def_id: OwnerId, sig: &FnSig<'_>) {\n        self.fn_stack.push(self.current_fn.take());\n        self.current_fn = is_option_or_result(cx, return_ty(cx, fn_def_id)).map(|kind| OptionOrResultFn {\n            kind,\n            return_ty_span: Some(sig.decl.output.span()),\n        });\n    }\n\n    fn leave_item(&mut self) {\n        self.current_fn = self.fn_stack.pop().unwrap();\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UnwrapInResult {\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {\n        if let ImplItemKind::Fn(sig, _) = &impl_item.kind {\n            self.enter_item(cx, impl_item.owner_id, sig);\n        }\n    }\n\n    fn check_impl_item_post(&mut self, _: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'tcx>) {\n        if let ImplItemKind::Fn(..) = impl_item.kind {\n            self.leave_item();\n        }\n    }\n\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if let ItemKind::Fn {\n            has_body: true, sig, ..\n        } = &item.kind\n        {\n            self.enter_item(cx, item.owner_id, sig);\n        }\n    }\n\n    fn check_item_post(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        if let ItemKind::Fn { has_body: true, .. } = item.kind {\n            self.leave_item();\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {\n        if expr.span.from_expansion() {\n            return;\n        }\n\n        if let Some(OptionOrResultFn {\n            kind,\n            ref mut return_ty_span,\n        }) = self.current_fn\n            && let Some((oor, fn_name)) = is_unwrap_or_expect_call(cx, expr)\n            && oor == kind\n        {\n            span_lint_and_then(\n                cx,\n                UNWRAP_IN_RESULT,\n                expr.span,\n                format!(\"`{fn_name}` used in a function that returns {}\", kind.with_article()),\n                |diag| {\n                    // Issue the note and help only once per function\n                    if let Some(span) = return_ty_span.take() {\n                        diag.span_note(span, \"in this function signature\");\n                        let complement = if kind == OptionOrResult::Result {\n                            \" or calling the `.map_err()` method\"\n                        } else {\n                            \"\"\n                        };\n                        diag.help(format!(\"consider using the `?` operator{complement}\"));\n                    }\n                },\n            );\n        }\n    }\n\n    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {\n        let body_def_id = cx.tcx.hir_body_owner_def_id(body.id());\n        if !matches!(cx.tcx.hir_body_owner_kind(body_def_id), BodyOwnerKind::Fn) {\n            // When entering a body which is not a function, mask the potential surrounding\n            // function to not apply the lint.\n            self.fn_stack.push(self.current_fn.take());\n        }\n    }\n\n    fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {\n        let body_def_id = cx.tcx.hir_body_owner_def_id(body.id());\n        if !matches!(cx.tcx.hir_body_owner_kind(body_def_id), BodyOwnerKind::Fn) {\n            // Unmask the potential surrounding function.\n            self.current_fn = self.fn_stack.pop().unwrap();\n        }\n    }\n}\n\nfn is_option_or_result(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<OptionOrResult> {\n    match ty.ty_adt_def().and_then(|def| cx.tcx.get_diagnostic_name(def.did())) {\n        Some(sym::Option) => Some(OptionOrResult::Option),\n        Some(sym::Result) => Some(OptionOrResult::Result),\n        _ => None,\n    }\n}\n\nfn is_unwrap_or_expect_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(OptionOrResult, Symbol)> {\n    if let ExprKind::Call(func, _) = expr.kind\n        && let ExprKind::Path(QPath::TypeRelative(\n            hir_ty,\n            PathSegment {\n                ident:\n                    Ident {\n                        name: name @ (sym::unwrap | sym::expect),\n                        ..\n                    },\n                ..\n            },\n        )) = func.kind\n    {\n        is_option_or_result(cx, cx.typeck_results().node_type(hir_ty.hir_id)).map(|oor| (oor, *name))\n    } else if let ExprKind::MethodCall(\n        PathSegment {\n            ident: Ident {\n                name: name @ (sym::unwrap | sym::expect),\n                ..\n            },\n            ..\n        },\n        recv,\n        _,\n        _,\n    ) = expr.kind\n    {\n        is_option_or_result(cx, cx.typeck_results().expr_ty_adjusted(recv)).map(|oor| (oor, *name))\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/upper_case_acronyms.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse core::mem::replace;\nuse rustc_errors::Applicability;\nuse rustc_hir::{HirId, Item, ItemKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::symbol::Ident;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for fully capitalized names and optionally names containing a capitalized acronym.\n    ///\n    /// ### Why is this bad?\n    /// In CamelCase, acronyms count as one word.\n    /// See [naming conventions](https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case)\n    /// for more.\n    ///\n    /// By default, the lint only triggers on fully-capitalized names.\n    /// You can use the `upper-case-acronyms-aggressive: true` config option to enable linting\n    /// on all camel case names\n    ///\n    /// ### Known problems\n    /// When two acronyms are contiguous, the lint can't tell where\n    /// the first acronym ends and the second starts, so it suggests to lowercase all of\n    /// the letters in the second acronym.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct HTTPResponse;\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// struct HttpResponse;\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub UPPER_CASE_ACRONYMS,\n    style,\n    \"capitalized acronyms are against the naming convention\"\n}\n\nimpl_lint_pass!(UpperCaseAcronyms => [UPPER_CASE_ACRONYMS]);\n\npub struct UpperCaseAcronyms {\n    avoid_breaking_exported_api: bool,\n    upper_case_acronyms_aggressive: bool,\n}\n\nimpl UpperCaseAcronyms {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            avoid_breaking_exported_api: conf.avoid_breaking_exported_api,\n            upper_case_acronyms_aggressive: conf.upper_case_acronyms_aggressive,\n        }\n    }\n}\n\nfn contains_acronym(s: &str) -> bool {\n    let mut count = 0;\n    for c in s.chars() {\n        if c.is_ascii_uppercase() {\n            count += 1;\n            if count == 3 {\n                return true;\n            }\n        } else {\n            count = 0;\n        }\n    }\n    count == 2\n}\n\nfn check_ident(cx: &LateContext<'_>, ident: &Ident, hir_id: HirId, be_aggressive: bool) {\n    let s = ident.as_str();\n\n    // By default, only warn for upper case identifiers with at least 3 characters.\n    let replacement = if s.len() > 2 && s.bytes().all(|c| c.is_ascii_uppercase()) {\n        let mut r = String::with_capacity(s.len());\n        let mut s = s.chars();\n        r.push(s.next().unwrap());\n        r.extend(s.map(|c| c.to_ascii_lowercase()));\n        r\n    } else if be_aggressive\n        // Only lint if the ident starts with an upper case character.\n        && let unprefixed = s.trim_start_matches('_')\n        && unprefixed.starts_with(|c: char| c.is_ascii_uppercase())\n        && contains_acronym(unprefixed)\n    {\n        let mut r = String::with_capacity(s.len());\n        let mut s = s.chars();\n        let mut prev_upper = false;\n        while let Some(c) = s.next() {\n            r.push(\n                if replace(&mut prev_upper, c.is_ascii_uppercase())\n                    && s.clone().next().is_none_or(|c| c.is_ascii_uppercase())\n                {\n                    c.to_ascii_lowercase()\n                } else {\n                    c\n                },\n            );\n        }\n        r\n    } else {\n        return;\n    };\n\n    span_lint_hir_and_then(\n        cx,\n        UPPER_CASE_ACRONYMS,\n        hir_id,\n        ident.span,\n        format!(\"name `{ident}` contains a capitalized acronym\"),\n        |diag| {\n            diag.span_suggestion(\n                ident.span,\n                \"consider making the acronym lowercase, except the initial letter\",\n                replacement,\n                Applicability::MaybeIncorrect,\n            );\n        },\n    );\n}\n\nimpl LateLintPass<'_> for UpperCaseAcronyms {\n    fn check_item(&mut self, cx: &LateContext<'_>, it: &Item<'_>) {\n        // do not lint public items or in macros\n        if it.span.in_external_macro(cx.sess().source_map())\n            || (self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(it.owner_id.def_id))\n        {\n            return;\n        }\n        match it.kind {\n            ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, _, ident, ..) => {\n                check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive);\n            },\n            ItemKind::Enum(ident, _, ref enumdef) => {\n                check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive);\n                // check enum variants separately because again we only want to lint on private enums and\n                // the fn check_variant does not know about the vis of the enum of its variants\n                enumdef.variants.iter().for_each(|variant| {\n                    check_ident(cx, &variant.ident, variant.hir_id, self.upper_case_acronyms_aggressive);\n                });\n            },\n            _ => {},\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/use_self.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_from_proc_macro;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::ty::{same_type_modulo_regions, ty_from_hir_ty};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{CtorOf, DefKind, Res};\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};\nuse rustc_hir::{\n    self as hir, AmbigArg, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParamKind, HirId, Impl,\n    ImplItemImplKind, ImplItemKind, Item, ItemKind, Node, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Ty as MiddleTy;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse std::iter;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for unnecessary repetition of structure name when a\n    /// replacement with `Self` is applicable.\n    ///\n    /// ### Why is this bad?\n    /// Unnecessary repetition. Mixed use of `Self` and struct\n    /// name\n    /// feels inconsistent.\n    ///\n    /// ### Known problems\n    /// - Unaddressed false negative in fn bodies of trait implementations\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct Foo;\n    /// impl Foo {\n    ///     fn new() -> Foo {\n    ///         Foo {}\n    ///     }\n    /// }\n    /// ```\n    /// could be\n    /// ```no_run\n    /// struct Foo;\n    /// impl Foo {\n    ///     fn new() -> Self {\n    ///         Self {}\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USE_SELF,\n    nursery,\n    \"unnecessary structure name repetition whereas `Self` is applicable\"\n}\n\nimpl_lint_pass!(UseSelf => [USE_SELF]);\n\npub struct UseSelf {\n    msrv: Msrv,\n    stack: Vec<StackItem>,\n    recursive_self_in_type_definitions: bool,\n}\n\nimpl UseSelf {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            msrv: conf.msrv,\n            stack: Vec::new(),\n            recursive_self_in_type_definitions: conf.recursive_self_in_type_definitions,\n        }\n    }\n}\n\n#[derive(Debug)]\nenum StackItem {\n    Check {\n        impl_id: LocalDefId,\n        types_to_skip: FxHashSet<HirId>,\n    },\n    NoCheck,\n}\n\nconst SEGMENTS_MSG: &str = \"segments should be composed of at least 1 element\";\n\nimpl<'tcx> LateLintPass<'tcx> for UseSelf {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {\n        // We push the self types of items on a stack here. Only the top type on the stack is\n        // relevant for linting, since this is the self type of the item we're currently in. To\n        // avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal that\n        // we're in an item or nested item that we don't want to lint\n        let stack_item = if let ItemKind::Impl(Impl { self_ty, generics, .. }) = item.kind\n            && let TyKind::Path(QPath::Resolved(_, item_path)) = self_ty.kind\n            && let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args\n            && parameters\n                .as_ref()\n                .is_none_or(|params| params.parenthesized == GenericArgsParentheses::No)\n            && !item.span.from_expansion()\n            // expensive, should be last check\n            && !is_from_proc_macro(cx, item)\n        {\n            // Self cannot be used inside const generic parameters\n            let types_to_skip = generics\n                .params\n                .iter()\n                .filter_map(|param| match param.kind {\n                    GenericParamKind::Const { ty, .. } => Some(ty.hir_id),\n                    _ => None,\n                })\n                .chain([self_ty.hir_id])\n                .collect();\n            StackItem::Check {\n                impl_id: item.owner_id.def_id,\n                types_to_skip,\n            }\n        } else if let ItemKind::Struct(..) | ItemKind::Enum(..) = item.kind\n            && self.recursive_self_in_type_definitions\n            && !item.span.from_expansion()\n            && !is_from_proc_macro(cx, item)\n        {\n            StackItem::Check {\n                impl_id: item.owner_id.def_id,\n                types_to_skip: FxHashSet::default(),\n            }\n        } else {\n            StackItem::NoCheck\n        };\n        self.stack.push(stack_item);\n    }\n\n    fn check_item_post(&mut self, _: &LateContext<'_>, _: &Item<'_>) {\n        self.stack.pop();\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {\n        // Checking items of `impl Self` blocks in which macro expands into.\n        if impl_item.span.from_expansion() {\n            self.stack.push(StackItem::NoCheck);\n            return;\n        }\n        // We want to skip types in trait `impl`s that aren't declared as `Self` in the trait\n        // declaration. The collection of those types is all this method implementation does.\n        if let ImplItemKind::Fn(FnSig { decl, .. }, ..) = impl_item.kind\n            && let ImplItemImplKind::Trait { .. } = impl_item.impl_kind\n            && let Some(&mut StackItem::Check {\n                impl_id,\n                ref mut types_to_skip,\n                ..\n            }) = self.stack.last_mut()\n        {\n            let impl_trait_ref = cx.tcx.impl_trait_ref(impl_id);\n            // `self_ty` is the semantic self type of `impl <trait> for <type>`. This cannot be\n            // `Self`.\n            let self_ty = impl_trait_ref.instantiate_identity().self_ty();\n\n            // `trait_method_sig` is the signature of the function, how it is declared in the\n            // trait, not in the impl of the trait.\n            let trait_method = cx\n                .tcx\n                .trait_item_of(impl_item.owner_id)\n                .expect(\"impl method matches a trait method\");\n            let trait_method_sig = cx.tcx.fn_sig(trait_method).instantiate_identity();\n            let trait_method_sig = cx.tcx.instantiate_bound_regions_with_erased(trait_method_sig);\n\n            // `impl_inputs_outputs` is an iterator over the types (`hir::Ty`) declared in the\n            // implementation of the trait.\n            let output_hir_ty = if let FnRetTy::Return(ty) = &decl.output {\n                Some(&**ty)\n            } else {\n                None\n            };\n            let impl_inputs_outputs = decl.inputs.iter().chain(output_hir_ty);\n\n            // `impl_hir_ty` (of type `hir::Ty`) represents the type written in the signature.\n            //\n            // `trait_sem_ty` (of type `ty::Ty`) is the semantic type for the signature in the\n            // trait declaration. This is used to check if `Self` was used in the trait\n            // declaration.\n            //\n            // If `any`where in the `trait_sem_ty` the `self_ty` was used verbatim (as opposed\n            // to `Self`), we want to skip linting that type and all subtypes of it. This\n            // avoids suggestions to e.g. replace `Vec<u8>` with `Vec<Self>`, in an `impl Trait\n            // for u8`, when the trait always uses `Vec<u8>`.\n            //\n            // See also https://github.com/rust-lang/rust-clippy/issues/2894.\n            for (impl_hir_ty, trait_sem_ty) in impl_inputs_outputs.zip(trait_method_sig.inputs_and_output) {\n                if trait_sem_ty.walk().any(|inner| inner == self_ty.into()) {\n                    let mut visitor = SkipTyCollector::default();\n                    visitor.visit_ty_unambig(impl_hir_ty);\n                    types_to_skip.extend(visitor.types_to_skip);\n                }\n            }\n        }\n    }\n\n    fn check_impl_item_post(&mut self, _: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {\n        if impl_item.span.from_expansion()\n            && let Some(StackItem::NoCheck) = self.stack.last()\n        {\n            self.stack.pop();\n        }\n    }\n\n    fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) {\n        if !hir_ty.span.from_expansion()\n            && let Some(&StackItem::Check {\n                impl_id,\n                ref types_to_skip,\n            }) = self.stack.last()\n            && let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind\n            && !matches!(\n                path.res,\n                Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _)\n            )\n            && !ty_is_in_generic_args(cx, hir_ty)\n            && !types_to_skip.contains(&hir_ty.hir_id)\n            && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty())\n            && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity()\n            && same_type_modulo_regions(ty, impl_ty)\n            // Ensure the type we encounter and the one from the impl have the same lifetime parameters. It may be that\n            // the lifetime parameters of `ty` are elided (`impl<'a> Foo<'a> { fn new() -> Self { Foo{..} } }`), in\n            // which case we must still trigger the lint.\n            && same_lifetimes(ty, impl_ty)\n            && self.msrv.meets(cx, msrvs::TYPE_ALIAS_ENUM_VARIANTS)\n        {\n            span_lint(cx, hir_ty.span);\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if !expr.span.from_expansion()\n            && let Some(&StackItem::Check { impl_id, .. }) = self.stack.last()\n            && cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).instantiate_identity()\n            && self.msrv.meets(cx, msrvs::TYPE_ALIAS_ENUM_VARIANTS)\n        {\n            match expr.kind {\n                ExprKind::Struct(QPath::Resolved(_, path), ..) => check_path(cx, path),\n                ExprKind::Call(fun, _) => {\n                    if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind {\n                        check_path(cx, path);\n                    }\n                },\n                ExprKind::Path(QPath::Resolved(_, path)) => check_path(cx, path),\n                _ => (),\n            }\n        }\n    }\n\n    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {\n        if !pat.span.from_expansion()\n            && let Some(&StackItem::Check { impl_id, .. }) = self.stack.last()\n            // get the path from the pattern\n            && let PatKind::Expr(&PatExpr { kind: PatExprKind::Path(QPath::Resolved(_, path)), .. })\n                 | PatKind::TupleStruct(QPath::Resolved(_, path), _, _)\n                 | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind\n            && cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).instantiate_identity()\n            && self.msrv.meets(cx, msrvs::TYPE_ALIAS_ENUM_VARIANTS)\n        {\n            check_path(cx, path);\n        }\n    }\n}\n\n#[derive(Default)]\nstruct SkipTyCollector {\n    types_to_skip: Vec<HirId>,\n}\n\nimpl Visitor<'_> for SkipTyCollector {\n    fn visit_infer(&mut self, inf_id: HirId, _inf_span: Span, kind: InferKind<'_>) -> Self::Result {\n        // Conservatively assume ambiguously kinded inferred arguments are type arguments\n        if let InferKind::Ambig(_) | InferKind::Ty(_) = kind {\n            self.types_to_skip.push(inf_id);\n        }\n        self.visit_id(inf_id);\n    }\n    fn visit_ty(&mut self, hir_ty: &Ty<'_, AmbigArg>) {\n        self.types_to_skip.push(hir_ty.hir_id);\n\n        walk_ty(self, hir_ty);\n    }\n}\n\nfn span_lint(cx: &LateContext<'_>, span: Span) {\n    span_lint_and_sugg(\n        cx,\n        USE_SELF,\n        span,\n        \"unnecessary structure name repetition\",\n        \"use the applicable keyword\",\n        \"Self\".to_owned(),\n        Applicability::MachineApplicable,\n    );\n}\n\nfn check_path(cx: &LateContext<'_>, path: &Path<'_>) {\n    match path.res {\n        Res::Def(DefKind::Ctor(CtorOf::Variant, _) | DefKind::Variant, ..) => {\n            lint_path_to_variant(cx, path);\n        },\n        Res::Def(DefKind::Ctor(CtorOf::Struct, _) | DefKind::Struct, ..) => span_lint(cx, path.span),\n        _ => (),\n    }\n}\n\nfn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) {\n    if let [.., self_seg, _variant] = path.segments {\n        let span = path\n            .span\n            .with_hi(self_seg.args().span_ext().unwrap_or(self_seg.ident.span).hi());\n        span_lint(cx, span);\n    }\n}\n\nfn ty_is_in_generic_args<'tcx>(cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) -> bool {\n    cx.tcx.hir_parent_iter(hir_ty.hir_id).any(|(_, parent)| {\n        matches!(parent, Node::ImplItem(impl_item) if impl_item.generics.params.iter().any(|param| {\n            let GenericParamKind::Const { ty: const_ty, .. } = &param.kind else {\n                return false;\n            };\n            ty_contains_ty(const_ty, hir_ty)\n        }))\n    })\n}\n\nfn ty_contains_ty<'tcx>(outer: &Ty<'tcx>, inner: &Ty<'tcx, AmbigArg>) -> bool {\n    struct ContainsVisitor<'tcx> {\n        inner: &'tcx Ty<'tcx, AmbigArg>,\n    }\n\n    impl<'tcx> Visitor<'tcx> for ContainsVisitor<'tcx> {\n        type Result = ControlFlow<()>;\n\n        fn visit_ty(&mut self, t: &'tcx Ty<'tcx, AmbigArg>) -> Self::Result {\n            if t.hir_id == self.inner.hir_id {\n                return ControlFlow::Break(());\n            }\n\n            walk_ty(self, t)\n        }\n    }\n\n    let mut visitor = ContainsVisitor { inner };\n    visitor.visit_ty_unambig(outer).is_break()\n}\n\n/// Checks whether types `a` and `b` have the same lifetime parameters.\n///\n/// This function does not check that types `a` and `b` are the same types.\nfn same_lifetimes<'tcx>(a: MiddleTy<'tcx>, b: MiddleTy<'tcx>) -> bool {\n    use rustc_middle::ty::{Adt, GenericArgKind};\n    match (a.kind(), b.kind()) {\n        (Adt(_, args_a), Adt(_, args_b)) => {\n            iter::zip(*args_a, *args_b).all(|(arg_a, arg_b)| match (arg_a.kind(), arg_b.kind()) {\n                // TODO: Handle inferred lifetimes\n                (GenericArgKind::Lifetime(inner_a), GenericArgKind::Lifetime(inner_b)) => inner_a == inner_b,\n                (GenericArgKind::Type(type_a), GenericArgKind::Type(type_b)) => same_lifetimes(type_a, type_b),\n                _ => true,\n            })\n        },\n        _ => a == b,\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/useless_concat.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::macros::macro_backtrace;\nuse clippy_utils::source::snippet_opt;\nuse clippy_utils::{sym, tokenize_with_text};\nuse rustc_ast::LitKind;\nuse rustc_errors::Applicability;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lexer::TokenKind;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks that the `concat!` macro has at least two arguments.\n    ///\n    /// ### Why is this bad?\n    /// If there are less than 2 arguments, then calling the macro is doing nothing.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let x = concat!(\"a\");\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let x = \"a\";\n    /// ```\n    #[clippy::version = \"1.89.0\"]\n    pub USELESS_CONCAT,\n    complexity,\n    \"checks that the `concat` macro has at least two arguments\"\n}\n\ndeclare_lint_pass!(UselessConcat => [USELESS_CONCAT]);\n\nimpl LateLintPass<'_> for UselessConcat {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        // Check that the expression is generated by a macro.\n        if expr.span.from_expansion()\n            // Check that it's a string literal.\n            && let ExprKind::Lit(lit) = expr.kind\n            && let LitKind::Str(lit_s, _) = lit.node\n            // Get the direct parent of the expression.\n            && let Some(macro_call) = macro_backtrace(expr.span).next()\n            // Check if the `concat` macro from the `core` library.\n            && cx.tcx.is_diagnostic_item(sym::macro_concat, macro_call.def_id)\n            // We get the original code to parse it.\n            && let Some(original_code) = snippet_opt(cx, macro_call.span)\n            // This check allows us to ensure that the code snippet:\n            // 1. Doesn't come from proc-macro expansion.\n            // 2. Doesn't come from foreign macro expansion.\n            //\n            // It works as follows: if the snippet we get doesn't contain `concat!(`, then it\n            // means it's not code written in the current crate so we shouldn't lint.\n            && let mut parts = original_code.split('!')\n            && parts.next().is_some_and(|p| p.trim() == \"concat\")\n            && parts.next().is_some_and(|p| p.trim().starts_with('('))\n        {\n            let mut literal = None;\n            let mut nb_commas = 0;\n            let mut nb_idents = 0;\n            for (token_kind, token_s, _) in tokenize_with_text(&original_code) {\n                match token_kind {\n                    TokenKind::Eof => break,\n                    TokenKind::Literal { .. } => {\n                        if literal.is_some() {\n                            return;\n                        }\n                        literal = Some(token_s);\n                    },\n                    TokenKind::Ident => {\n                        if token_s == \"true\" || token_s == \"false\" {\n                            literal = Some(token_s);\n                        } else {\n                            nb_idents += 1;\n                        }\n                    },\n                    TokenKind::Comma => {\n                        nb_commas += 1;\n                        if nb_commas > 1 {\n                            return;\n                        }\n                    },\n                    // We're inside a macro definition and we are manipulating something we likely\n                    // shouldn't, so aborting.\n                    TokenKind::Dollar => return,\n                    _ => {},\n                }\n            }\n            // There should always be the ident of the `concat` macro.\n            if nb_idents == 1 {\n                span_lint_and_sugg(\n                    cx,\n                    USELESS_CONCAT,\n                    macro_call.span,\n                    \"unneeded use of `concat!` macro\",\n                    \"replace with\",\n                    format!(\"{lit_s:?}\"),\n                    Applicability::MachineApplicable,\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/useless_conversion.rs",
    "content": "use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};\nuse clippy_utils::res::{MaybeDef, MaybeQPath, MaybeResPath, MaybeTypeckRes};\nuse clippy_utils::source::{snippet, snippet_with_context};\nuse clippy_utils::sugg::{DiagExt as _, Sugg};\nuse clippy_utils::ty::{is_copy, same_type_modulo_regions};\nuse clippy_utils::{get_parent_expr, is_ty_alias, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{BindingMode, Expr, ExprKind, HirId, MatchSource, Mutability, Node, PatKind};\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_infer::traits::Obligation;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::traits::ObligationCause;\nuse rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};\nuse rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\nuse rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls\n    /// which uselessly convert to the same type.\n    ///\n    /// ### Why is this bad?\n    /// Redundant code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// // format!() returns a `String`\n    /// let s: String = format!(\"hello\").into();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let s: String = format!(\"hello\");\n    /// ```\n    #[clippy::version = \"1.45.0\"]\n    pub USELESS_CONVERSION,\n    complexity,\n    \"calls to `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` which perform useless conversions to the same type\"\n}\n\nimpl_lint_pass!(UselessConversion => [USELESS_CONVERSION]);\n\n#[derive(Default)]\npub struct UselessConversion {\n    try_desugar_arm: Vec<HirId>,\n    expn_depth: u32,\n}\n\nenum MethodOrFunction {\n    Method,\n    Function,\n}\n\nimpl MethodOrFunction {\n    /// Maps the argument position in `pos` to the parameter position.\n    /// For methods, `self` is skipped.\n    fn param_pos(self, pos: usize) -> usize {\n        match self {\n            MethodOrFunction::Method => pos + 1,\n            MethodOrFunction::Function => pos,\n        }\n    }\n}\n\n/// Returns the span of the `IntoIterator` trait bound in the function pointed to by `fn_did`,\n/// iff all of the bounds also hold for the type of the `.into_iter()` receiver.\n/// ```ignore\n/// pub fn foo<I>(i: I)\n/// where I: IntoIterator<Item=i32> + ExactSizeIterator\n///                                   ^^^^^^^^^^^^^^^^^ this extra bound stops us from suggesting to remove `.into_iter()` ...\n/// {\n///     assert_eq!(i.len(), 3);\n/// }\n///\n/// pub fn bar() {\n///     foo([1, 2, 3].into_iter());\n///                  ^^^^^^^^^^^^ ... here, because `[i32; 3]` is not `ExactSizeIterator`\n/// }\n/// ```\nfn into_iter_bound<'tcx>(\n    cx: &LateContext<'tcx>,\n    fn_did: DefId,\n    into_iter_did: DefId,\n    into_iter_receiver: Ty<'tcx>,\n    param_index: u32,\n    node_args: GenericArgsRef<'tcx>,\n) -> Option<Span> {\n    let mut into_iter_span = None;\n\n    for (pred, span) in cx.tcx.explicit_predicates_of(fn_did).predicates {\n        if let ty::ClauseKind::Trait(tr) = pred.kind().skip_binder()\n            && tr.self_ty().is_param(param_index)\n        {\n            if tr.def_id() == into_iter_did {\n                into_iter_span = Some(*span);\n            } else {\n                let tr = cx.tcx.erase_and_anonymize_regions(tr);\n                if tr.has_escaping_bound_vars() {\n                    return None;\n                }\n\n                // Substitute generics in the predicate and replace the IntoIterator type parameter with the\n                // `.into_iter()` receiver to see if the bound also holds for that type.\n                let args = cx.tcx.mk_args_from_iter(node_args.iter().enumerate().map(|(i, arg)| {\n                    if i == param_index as usize {\n                        GenericArg::from(into_iter_receiver)\n                    } else {\n                        arg\n                    }\n                }));\n\n                let predicate = EarlyBinder::bind(tr).instantiate(cx.tcx, args);\n                let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);\n                if !cx\n                    .tcx\n                    .infer_ctxt()\n                    .build(cx.typing_mode())\n                    .predicate_must_hold_modulo_regions(&obligation)\n                {\n                    return None;\n                }\n            }\n        }\n    }\n\n    into_iter_span\n}\n\n/// Extracts the receiver of a `.into_iter()` method call.\nfn into_iter_call<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>) -> Option<&'hir Expr<'hir>> {\n    if let ExprKind::MethodCall(name, recv, [], _) = expr.kind\n        && cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::IntoIterator)\n        && name.ident.name == sym::into_iter\n    {\n        Some(recv)\n    } else {\n        None\n    }\n}\n\n/// Same as [`into_iter_call`], but tries to look for the innermost `.into_iter()` call, e.g.:\n/// `foo.into_iter().into_iter()`\n///  ^^^  we want this expression\nfn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -> (&'hir Expr<'hir>, usize) {\n    let mut depth = 0;\n    while let Some(recv) = into_iter_call(cx, expr) {\n        expr = recv;\n        depth += 1;\n    }\n    (expr, depth)\n}\n\n#[expect(clippy::too_many_lines)]\nimpl<'tcx> LateLintPass<'tcx> for UselessConversion {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if e.span.from_expansion() {\n            if e.span.desugaring_kind().is_none() {\n                self.expn_depth += 1;\n            }\n            return;\n        }\n\n        if Some(&e.hir_id) == self.try_desugar_arm.last() {\n            return;\n        }\n\n        match e.kind {\n            ExprKind::Match(_, arms, MatchSource::TryDesugar(_)) => {\n                let (ExprKind::Ret(Some(e)) | ExprKind::Break(_, Some(e))) = arms[0].body.kind else {\n                    return;\n                };\n                if let ExprKind::Call(_, [arg, ..]) = e.kind {\n                    self.try_desugar_arm.push(arg.hir_id);\n                }\n            },\n\n            ExprKind::MethodCall(path, recv, [arg], _) => {\n                if matches!(\n                    path.ident.name,\n                    sym::map | sym::map_err | sym::map_break | sym::map_continue\n                ) && has_eligible_receiver(cx, recv, e)\n                    && matches!(\n                        arg.res(cx).assoc_parent(cx).opt_diag_name(cx),\n                        Some(sym::Into | sym::From)\n                    )\n                    && let ty::FnDef(_, args) = cx.typeck_results().expr_ty(arg).kind()\n                    && let &[from_ty, to_ty] = args.into_type_list(cx.tcx).as_slice()\n                    && same_type_modulo_regions(from_ty, to_ty)\n                {\n                    span_lint_and_then(\n                        cx,\n                        USELESS_CONVERSION,\n                        e.span.with_lo(recv.span.hi()),\n                        format!(\"useless conversion to the same type: `{from_ty}`\"),\n                        |diag| {\n                            diag.suggest_remove_item(\n                                cx,\n                                e.span.with_lo(recv.span.hi()),\n                                \"consider removing\",\n                                Applicability::MachineApplicable,\n                            );\n                        },\n                    );\n                }\n            },\n\n            ExprKind::MethodCall(name, recv, [], _) => {\n                if cx.ty_based_def(e).opt_parent(cx).is_diag_item(cx, sym::Into) && name.ident.name == sym::into {\n                    let a = cx.typeck_results().expr_ty(e);\n                    let b = cx.typeck_results().expr_ty(recv);\n                    if same_type_modulo_regions(a, b) {\n                        let mut app = Applicability::MachineApplicable;\n                        let sugg = snippet_with_context(cx, recv.span, e.span.ctxt(), \"<expr>\", &mut app).0;\n                        span_lint_and_sugg(\n                            cx,\n                            USELESS_CONVERSION,\n                            e.span,\n                            format!(\"useless conversion to the same type: `{b}`\"),\n                            \"consider removing `.into()`\",\n                            sugg.into_owned(),\n                            app,\n                        );\n                    }\n                }\n                if let Some(into_iter_recv) = into_iter_call(cx, e)\n                    // Make sure that there is no parent expression, or if there is, make sure it's not a `.into_iter()` call.\n                    // The reason for that is that we only want to lint once (the outermost call)\n                    // in cases like `foo.into_iter().into_iter()`\n                    && get_parent_expr(cx, e)\n                        .and_then(|parent| into_iter_call(cx, parent))\n                        .is_none()\n                {\n                    if let Some(parent) = get_parent_expr(cx, e) {\n                        let parent_fn = match parent.kind {\n                            ExprKind::Call(recv, args)\n                                if let ExprKind::Path(ref qpath) = recv.kind\n                                    && let Some(did) = cx.qpath_res(qpath, recv.hir_id).opt_def_id()\n                                    // make sure that the path indeed points to a fn-like item, so that\n                                    // `fn_sig` does not ICE. (see #11065)\n                                    && cx.tcx.def_kind(did).is_fn_like() =>\n                            {\n                                Some((\n                                    did,\n                                    args,\n                                    cx.typeck_results().node_args(recv.hir_id),\n                                    MethodOrFunction::Function,\n                                ))\n                            },\n                            ExprKind::MethodCall(.., args, _) => {\n                                cx.typeck_results().type_dependent_def_id(parent.hir_id).map(|did| {\n                                    (\n                                        did,\n                                        args,\n                                        cx.typeck_results().node_args(parent.hir_id),\n                                        MethodOrFunction::Method,\n                                    )\n                                })\n                            },\n                            _ => None,\n                        };\n\n                        if let Some((parent_fn_did, args, node_args, kind)) = parent_fn\n                            && let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator)\n                            && let sig = cx.tcx.fn_sig(parent_fn_did).skip_binder().skip_binder()\n                            && let Some(arg_pos) = args.iter().position(|x| x.hir_id == e.hir_id)\n                            && let Some(&into_iter_param) = sig.inputs().get(kind.param_pos(arg_pos))\n                            && let ty::Param(param) = into_iter_param.kind()\n                            && let Some(span) = into_iter_bound(\n                                cx,\n                                parent_fn_did,\n                                into_iter_did,\n                                cx.typeck_results().expr_ty(into_iter_recv),\n                                param.index,\n                                node_args,\n                            )\n                            && self.expn_depth == 0\n                        {\n                            // Get the \"innermost\" `.into_iter()` call, e.g. given this expression:\n                            // `foo.into_iter().into_iter()`\n                            //  ^^^\n                            let (into_iter_recv, depth) = into_iter_deep_call(cx, into_iter_recv);\n\n                            span_lint_and_then(\n                                cx,\n                                USELESS_CONVERSION,\n                                e.span,\n                                \"explicit call to `.into_iter()` in function argument accepting `IntoIterator`\",\n                                |diag| {\n                                    let receiver_span = into_iter_recv.span.source_callsite();\n                                    let adjustments = adjustments(cx, into_iter_recv);\n                                    let mut sugg = if adjustments.is_empty() {\n                                        vec![]\n                                    } else {\n                                        vec![(receiver_span.shrink_to_lo(), adjustments)]\n                                    };\n                                    let plural = if depth == 0 { \"\" } else { \"s\" };\n                                    sugg.push((e.span.with_lo(receiver_span.hi()), String::new()));\n                                    diag.multipart_suggestion(\n                                        format!(\"consider removing the `.into_iter()`{plural}\"),\n                                        sugg,\n                                        Applicability::MachineApplicable,\n                                    );\n                                    diag.span_note(span, \"this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\");\n                                },\n                            );\n\n                            // Early return to avoid linting again with contradicting suggestions\n                            return;\n                        }\n                    }\n\n                    if let Some(id) = recv.res_local_id()\n                        && let Node::Pat(pat) = cx.tcx.hir_node(id)\n                        && let PatKind::Binding(ann, ..) = pat.kind\n                        && ann != BindingMode::MUT\n                    {\n                        // Do not remove .into_iter() applied to a non-mutable local variable used in\n                        // a larger expression context as it would differ in mutability.\n                        return;\n                    }\n\n                    let a = cx.typeck_results().expr_ty(e);\n                    let b = cx.typeck_results().expr_ty(recv);\n\n                    // If the types are identical then .into_iter() can be removed, unless the type\n                    // implements Copy, in which case .into_iter() returns a copy of the receiver and\n                    // cannot be safely omitted.\n                    if same_type_modulo_regions(a, b) && !is_copy(cx, b) {\n                        // Below we check if the parent method call meets the following conditions:\n                        // 1. First parameter is `&mut self` (requires mutable reference)\n                        // 2. Second parameter implements the `FnMut` trait (e.g., Iterator::any)\n                        // For methods satisfying these conditions (like any), .into_iter() must be preserved.\n                        if let Some(parent) = get_parent_expr(cx, e)\n                            && let ExprKind::MethodCall(_, recv, _, _) = parent.kind\n                            && recv.hir_id == e.hir_id\n                            && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id)\n                            && let sig = cx.tcx.fn_sig(def_id).skip_binder().skip_binder()\n                            && let inputs = sig.inputs()\n                            && inputs.len() >= 2\n                            && let Some(self_ty) = inputs.first()\n                            && let ty::Ref(_, _, Mutability::Mut) = self_ty.kind()\n                            && let Some(second_ty) = inputs.get(1)\n                            && let predicates = cx.tcx.param_env(def_id).caller_bounds()\n                            && predicates.iter().any(|pred| {\n                                if let ty::ClauseKind::Trait(trait_pred) = pred.kind().skip_binder() {\n                                    trait_pred.self_ty() == *second_ty\n                                        && cx.tcx.lang_items().fn_mut_trait() == Some(trait_pred.def_id())\n                                } else {\n                                    false\n                                }\n                            })\n                        {\n                            return;\n                        }\n\n                        let mut applicability = Applicability::MachineApplicable;\n                        let sugg = snippet_with_context(cx, recv.span, e.span.ctxt(), \"<expr>\", &mut applicability)\n                            .0\n                            .into_owned();\n                        span_lint_and_sugg(\n                            cx,\n                            USELESS_CONVERSION,\n                            e.span,\n                            format!(\"useless conversion to the same type: `{b}`\"),\n                            \"consider removing `.into_iter()`\",\n                            sugg,\n                            applicability,\n                        );\n                    }\n                }\n                if cx.ty_based_def(e).opt_parent(cx).is_diag_item(cx, sym::TryInto)\n                    && name.ident.name == sym::try_into\n                    && let a = cx.typeck_results().expr_ty(e)\n                    && let b = cx.typeck_results().expr_ty(recv)\n                    && a.is_diag_item(cx, sym::Result)\n                    && let ty::Adt(_, args) = a.kind()\n                    && let Some(a_type) = args.types().next()\n                    && same_type_modulo_regions(a_type, b)\n                {\n                    span_lint_and_help(\n                        cx,\n                        USELESS_CONVERSION,\n                        e.span,\n                        format!(\"useless conversion to the same type: `{b}`\"),\n                        None,\n                        \"consider removing `.try_into()`\",\n                    );\n                }\n            },\n\n            ExprKind::Call(path, [arg]) => {\n                if let ExprKind::Path(ref qpath) = path.kind\n                    && !is_ty_alias(qpath)\n                    && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()\n                    && let Some(name) = cx.tcx.get_diagnostic_name(def_id)\n                {\n                    let a = cx.typeck_results().expr_ty(e);\n                    let b = cx.typeck_results().expr_ty(arg);\n                    if name == sym::try_from_fn\n                        && a.is_diag_item(cx, sym::Result)\n                        && let ty::Adt(_, args) = a.kind()\n                        && let Some(a_type) = args.types().next()\n                        && same_type_modulo_regions(a_type, b)\n                    {\n                        let hint = format!(\"consider removing `{}()`\", snippet(cx, path.span, \"TryFrom::try_from\"));\n                        span_lint_and_help(\n                            cx,\n                            USELESS_CONVERSION,\n                            e.span,\n                            format!(\"useless conversion to the same type: `{b}`\"),\n                            None,\n                            hint,\n                        );\n                    } else if name == sym::from_fn && same_type_modulo_regions(a, b) {\n                        let mut app = Applicability::MachineApplicable;\n                        let sugg = Sugg::hir_with_context(cx, arg, e.span.ctxt(), \"<expr>\", &mut app).maybe_paren();\n                        let sugg_msg = format!(\"consider removing `{}()`\", snippet(cx, path.span, \"From::from\"));\n                        span_lint_and_sugg(\n                            cx,\n                            USELESS_CONVERSION,\n                            e.span,\n                            format!(\"useless conversion to the same type: `{b}`\"),\n                            sugg_msg,\n                            sugg.to_string(),\n                            app,\n                        );\n                    }\n                }\n            },\n\n            _ => {},\n        }\n    }\n\n    fn check_expr_post(&mut self, _: &LateContext<'tcx>, e: &'tcx Expr<'_>) {\n        if Some(&e.hir_id) == self.try_desugar_arm.last() {\n            self.try_desugar_arm.pop();\n        }\n        if e.span.from_expansion() && e.span.desugaring_kind().is_none() {\n            self.expn_depth -= 1;\n        }\n    }\n}\n\nfn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>) -> bool {\n    if cx.ty_based_def(expr).opt_parent(cx).is_impl(cx) {\n        matches!(\n            cx.typeck_results().expr_ty(recv).opt_diag_name(cx),\n            Some(sym::Option | sym::Result | sym::ControlFlow)\n        )\n    } else {\n        cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)\n    }\n}\n\nfn adjustments(cx: &LateContext<'_>, expr: &Expr<'_>) -> String {\n    let mut prefix = String::new();\n\n    let adjustments = cx.typeck_results().expr_adjustments(expr);\n\n    let [.., last] = adjustments else { return prefix };\n    let target = last.target;\n\n    for adj in adjustments {\n        match adj.kind {\n            Adjust::Deref(_) => prefix = format!(\"*{prefix}\"),\n            Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })) => prefix = format!(\"&mut {prefix}\"),\n            Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)) => prefix = format!(\"&{prefix}\"),\n            _ => {},\n        }\n\n        // Stop once we reach the final target type.\n        // This prevents over-adjusting (e.g. suggesting &**y instead of *y).\n        if adj.target == target {\n            break;\n        }\n    }\n    prefix\n}\n"
  },
  {
    "path": "clippy_lints/src/useless_vec.rs",
    "content": "use std::collections::BTreeMap;\nuse std::collections::btree_map::Entry;\nuse std::mem;\nuse std::ops::ControlFlow;\n\nuse clippy_config::Conf;\nuse clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_hir_and_then;\nuse clippy_utils::msrvs::{self, Msrv};\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::ty::is_copy;\nuse clippy_utils::visitors::for_each_local_use_after_expr;\nuse clippy_utils::{VEC_METHODS_SHADOWING_SLICE_METHODS, get_parent_expr, higher, is_in_test, span_contains_comment};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty;\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{DesugaringKind, Span};\n\npub struct UselessVec {\n    too_large_for_stack: u64,\n    msrv: Msrv,\n    /// Maps from a `vec![]` source callsite invocation span to the \"state\" (i.e., whether we can\n    /// emit a warning there or not).\n    ///\n    /// The purpose of this is to buffer lints up until `check_crate_post` so that we can cancel a\n    /// lint while visiting, because a `vec![]` invocation span can appear multiple times when\n    /// it is passed as a macro argument, once in a context that doesn't require a `Vec<_>` and\n    /// another time that does. Consider:\n    /// ```\n    /// macro_rules! m {\n    ///     ($v:expr) => {\n    ///         let a = $v;\n    ///         $v.push(3);\n    ///     }\n    /// }\n    /// m!(vec![1, 2]);\n    /// ```\n    /// The macro invocation expands to two `vec![1, 2]` invocations. If we eagerly suggest changing\n    /// the first `vec![1, 2]` (which is shared with the other expn) to an array which indeed would\n    /// work, we get a false positive warning on the `$v.push(3)` which really requires `$v` to\n    /// be a vector.\n    span_to_state: BTreeMap<Span, VecState>,\n    allow_in_test: bool,\n}\n\nimpl UselessVec {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            too_large_for_stack: conf.too_large_for_stack,\n            msrv: conf.msrv,\n            span_to_state: BTreeMap::new(),\n            allow_in_test: conf.allow_useless_vec_in_tests,\n        }\n    }\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `vec![..]` when using `[..]` would\n    /// be possible.\n    ///\n    /// ### Why is this bad?\n    /// This is less efficient.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn foo(_x: &[u8]) {}\n    ///\n    /// foo(&vec![1, 2]);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # fn foo(_x: &[u8]) {}\n    /// foo(&[1, 2]);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USELESS_VEC,\n    perf,\n    \"useless `vec!`\"\n}\n\nimpl_lint_pass!(UselessVec => [USELESS_VEC]);\n\n/// The \"state\" of a `vec![]` invocation, indicating whether it can or cannot be changed.\nenum VecState {\n    Change {\n        suggest_ty: SuggestedType,\n        vec_snippet: String,\n        expr_hir_id: HirId,\n    },\n    NoChange,\n}\n\nenum VecToArray {\n    /// Expression does not need to be a `Vec<_>` and its type can be changed to an array (or\n    /// slice).\n    Possible,\n    /// Expression must be a `Vec<_>`. Type cannot change.\n    Impossible,\n}\n\nimpl UselessVec {\n    /// Checks if the surrounding environment requires this expression to actually be of type\n    /// `Vec<_>`, or if it can be changed to `&[]`/`[]` without causing type errors.\n    fn expr_usage_requires_vec(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) -> VecToArray {\n        match cx.tcx.parent_hir_node(expr.hir_id) {\n            // search for `let foo = vec![_]` expressions where all uses of `foo`\n            // adjust to slices or call a method that exist on slices (e.g. len)\n            Node::LetStmt(LetStmt {\n                ty: None,\n                pat:\n                    Pat {\n                        kind: PatKind::Binding(_, id, ..),\n                        ..\n                    },\n                ..\n            }) => {\n                let only_slice_uses = for_each_local_use_after_expr(cx, *id, expr.hir_id, |expr| {\n                    // allow indexing into a vec and some set of allowed method calls that exist on slices, too\n                    if let Some(parent) = get_parent_expr(cx, expr)\n                        && (adjusts_to_slice(cx, expr)\n                            || match parent.kind {\n                                ExprKind::Index(..) => true,\n                                ExprKind::MethodCall(path, _, [], _) => {\n                                    // If the given expression is a method call to a `Vec` method that also exists on\n                                    // slices, it means that this expression does not actually require a `Vec` and could\n                                    // just work with an array.\n                                    VEC_METHODS_SHADOWING_SLICE_METHODS.contains(&path.ident.name)\n                                },\n                                _ => false,\n                            })\n                    {\n                        ControlFlow::Continue(())\n                    } else {\n                        ControlFlow::Break(())\n                    }\n                })\n                .is_continue();\n\n                if only_slice_uses {\n                    VecToArray::Possible\n                } else {\n                    VecToArray::Impossible\n                }\n            },\n            // if the local pattern has a specified type, do not lint.\n            Node::LetStmt(LetStmt { ty: Some(_), .. }) if higher::VecArgs::hir(cx, expr).is_some() => {\n                VecToArray::Impossible\n            },\n            // search for `for _ in vec![...]`\n            Node::Expr(expr)\n                if expr.span.is_desugaring(DesugaringKind::ForLoop)\n                    && self.msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) =>\n            {\n                VecToArray::Possible\n            },\n            // search for `&vec![_]` or `vec![_]` expressions where the adjusted type is `&[_]`\n            _ => {\n                if adjusts_to_slice(cx, expr) {\n                    VecToArray::Possible\n                } else {\n                    VecToArray::Impossible\n                }\n            },\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for UselessVec {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows())\n            // The `vec![]` or `&vec![]` invocation span.\n            && let vec_span = expr.span.parent_callsite().unwrap_or(expr.span)\n            && !vec_span.from_expansion()\n        {\n            if self.allow_in_test && is_in_test(cx.tcx, expr.hir_id) {\n                return;\n            }\n\n            match self.expr_usage_requires_vec(cx, expr) {\n                VecToArray::Possible => {\n                    let suggest_ty = suggest_type(expr);\n\n                    // Size and `Copy` checks don't depend on the enclosing usage of the expression\n                    // and don't need to be inserted into the state map.\n                    let vec_snippet = match vec_args {\n                        higher::VecArgs::Repeat(expr, len) => {\n                            if is_copy(cx, cx.typeck_results().expr_ty(expr))\n                                && let Some(Constant::Int(length)) = ConstEvalCtxt::new(cx).eval(len)\n                                && let Ok(length) = u64::try_from(length)\n                                && size_of(cx, expr)\n                                    .checked_mul(length)\n                                    .is_some_and(|size| size <= self.too_large_for_stack)\n                            {\n                                suggest_ty.snippet(\n                                    cx,\n                                    Some(expr.span.source_callsite()),\n                                    Some(len.span.source_callsite()),\n                                )\n                            } else {\n                                return;\n                            }\n                        },\n                        higher::VecArgs::Vec(args) => {\n                            if let Ok(length) = u64::try_from(args.len())\n                                && size_of(cx, expr)\n                                    .checked_mul(length)\n                                    .is_some_and(|size| size <= self.too_large_for_stack)\n                            {\n                                suggest_ty.snippet(\n                                    cx,\n                                    args.first().zip(args.last()).map(|(first, last)| {\n                                        first.span.source_callsite().to(last.span.source_callsite())\n                                    }),\n                                    None,\n                                )\n                            } else {\n                                return;\n                            }\n                        },\n                    };\n\n                    if let Entry::Vacant(entry) = self.span_to_state.entry(vec_span) {\n                        entry.insert(VecState::Change {\n                            suggest_ty,\n                            vec_snippet,\n                            expr_hir_id: expr.hir_id,\n                        });\n                    }\n                },\n                VecToArray::Impossible => {\n                    self.span_to_state.insert(vec_span, VecState::NoChange);\n                },\n            }\n        }\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        for (span, state) in mem::take(&mut self.span_to_state) {\n            if let VecState::Change {\n                suggest_ty,\n                vec_snippet,\n                expr_hir_id,\n            } = state\n            {\n                span_lint_hir_and_then(cx, USELESS_VEC, expr_hir_id, span, \"useless use of `vec!`\", |diag| {\n                    let help_msg = format!(\"you can use {} directly\", suggest_ty.desc());\n                    // If the `vec!` macro contains comment, better not make the suggestion machine applicable as it\n                    // would remove them.\n                    let applicability = if span_contains_comment(cx, span) {\n                        Applicability::Unspecified\n                    } else {\n                        Applicability::MachineApplicable\n                    };\n                    diag.span_suggestion(span, help_msg, vec_snippet, applicability);\n                });\n            }\n        }\n    }\n}\n\n#[derive(Copy, Clone)]\npub(crate) enum SuggestedType {\n    /// Suggest using a slice `&[..]` / `&mut [..]`\n    SliceRef(Mutability),\n    /// Suggest using an array: `[..]`\n    Array,\n}\n\nimpl SuggestedType {\n    fn desc(self) -> &'static str {\n        match self {\n            Self::SliceRef(_) => \"a slice\",\n            Self::Array => \"an array\",\n        }\n    }\n\n    fn snippet(self, cx: &LateContext<'_>, args_span: Option<Span>, len_span: Option<Span>) -> String {\n        // Invariant of the lint as implemented: all spans are from the root context (and as a result,\n        // always trivially crate-local).\n        assert!(args_span.is_none_or(|s| !s.from_expansion()));\n        assert!(len_span.is_none_or(|s| !s.from_expansion()));\n\n        let maybe_args = args_span.map(|sp| sp.get_source_text(cx).expect(\"spans are always crate-local\"));\n        let maybe_args = maybe_args.as_deref().unwrap_or_default();\n        let maybe_len = len_span\n            .map(|sp| sp.get_source_text(cx).expect(\"spans are always crate-local\"))\n            .map(|st| format!(\"; {st}\"))\n            .unwrap_or_default();\n\n        match self {\n            Self::SliceRef(Mutability::Mut) => format!(\"&mut [{maybe_args}{maybe_len}]\"),\n            Self::SliceRef(Mutability::Not) => format!(\"&[{maybe_args}{maybe_len}]\"),\n            Self::Array => format!(\"[{maybe_args}{maybe_len}]\"),\n        }\n    }\n}\n\nfn size_of(cx: &LateContext<'_>, expr: &Expr<'_>) -> u64 {\n    let ty = cx.typeck_results().expr_ty_adjusted(expr);\n    cx.layout_of(ty).map_or(0, |l| l.size.bytes())\n}\n\nfn adjusts_to_slice(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    matches!(cx.typeck_results().expr_ty_adjusted(e).kind(), ty::Ref(_, ty, _) if ty.is_slice())\n}\n\nfn suggest_type(expr: &Expr<'_>) -> SuggestedType {\n    if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind {\n        // `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.)\n        SuggestedType::SliceRef(mutability)\n    } else {\n        // `expr` is the `vec![_]` expansion, so suggest `[_]`\n        SuggestedType::Array\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/utils/attr_collector.rs",
    "content": "use std::mem;\nuse std::sync::{Arc, OnceLock};\n\nuse rustc_ast::{Attribute, Crate};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::Span;\n\n#[derive(Clone, Default)]\npub struct AttrStorage(pub Arc<OnceLock<Vec<Span>>>);\n\npub struct AttrCollector {\n    storage: AttrStorage,\n    attrs: Vec<Span>,\n}\n\nimpl AttrCollector {\n    pub fn new(storage: AttrStorage) -> Self {\n        Self {\n            storage,\n            attrs: Vec::new(),\n        }\n    }\n}\n\nimpl_lint_pass!(AttrCollector => []);\n\nimpl EarlyLintPass for AttrCollector {\n    fn check_attribute(&mut self, _cx: &EarlyContext<'_>, attr: &Attribute) {\n        self.attrs.push(attr.span);\n    }\n\n    fn check_crate_post(&mut self, _: &EarlyContext<'_>, _: &Crate) {\n        self.storage\n            .0\n            .set(mem::take(&mut self.attrs))\n            .expect(\"should only be called once\");\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/utils/author.rs",
    "content": "use clippy_utils::res::MaybeQPath;\nuse clippy_utils::{get_builtin_attr, higher, sym};\nuse itertools::Itertools;\nuse rustc_ast::LitIntType;\nuse rustc_ast::ast::{LitFloatType, LitKind};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{\n    self as hir, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind, ExprKind,\n    FnRetTy, HirId, Lit, PatExprKind, PatKind, QPath, StmtKind, StructTailExpr,\n};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{FloatTy, IntTy, UintTy};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::symbol::{Ident, Symbol};\nuse std::cell::Cell;\nuse std::fmt::{Display, Formatter};\n\ndeclare_lint_pass!(\n    /// ### What it does\n    /// Generates clippy code that detects the offending pattern\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// // ./tests/ui/my_lint.rs\n    /// fn foo() {\n    ///     // detect the following pattern\n    ///     #[clippy::author]\n    ///     if x == 42 {\n    ///         // but ignore everything from here on\n    ///         #![clippy::author = \"ignore\"]\n    ///     }\n    ///     ()\n    /// }\n    /// ```\n    ///\n    /// Running `TESTNAME=ui/my_lint cargo uitest` will produce\n    /// a `./tests/ui/new_lint.stdout` file with the generated code:\n    ///\n    /// ```rust,ignore\n    /// // ./tests/ui/new_lint.stdout\n    /// if ExprKind::If(ref cond, ref then, None) = item.kind\n    ///     && let ExprKind::Binary(BinOp::Eq, ref left, ref right) = cond.kind\n    ///     && let ExprKind::Path(ref path) = left.kind\n    ///     && let ExprKind::Lit(ref lit) = right.kind\n    ///     && let LitKind::Int(42, _) = lit.node\n    /// {\n    ///     // report your lint here\n    /// }\n    /// ```\n    Author => []\n);\n\n/// Writes a line of output with indentation added\nmacro_rules! out {\n    ($($t:tt)*) => {\n        println!(\"    {}\", format_args!($($t)*))\n    };\n}\n\n/// The variables passed in are replaced with `&Binding`s where the `value` field is set\n/// to the original value of the variable. The `name` field is set to the name of the variable\n/// (using `stringify!`) and is adjusted to avoid duplicate names.\n/// Note that the `Binding` may be printed directly to output the `name`.\nmacro_rules! bind {\n    ($self:ident $(, $name:ident)+) => {\n        $(let $name = & $self.bind(stringify!($name), $name);)+\n    };\n}\n\n/// Transforms the given `Option<T>` variables into `OptionPat<Binding<T>>`.\n/// This displays as `Some($name)` or `None` when printed. The name of the inner binding\n/// is set to the name of the variable passed to the macro.\nmacro_rules! opt_bind {\n    ($self:ident $(, $name:ident)+) => {\n        $(let $name = OptionPat::new($name.map(|o| $self.bind(stringify!($name), o)));)+\n    };\n}\n\n/// Creates a `Binding` that accesses the field of an existing `Binding`\nmacro_rules! field {\n    ($binding:ident.$field:ident) => {\n        &Binding {\n            name: $binding.name.to_string() + stringify!(.$field),\n            value: $binding.value.$field,\n        }\n    };\n}\n\n/// Print a condition of a let chain, `chain!(self, \"let Some(x) = y\")` will print\n/// `if let Some(x) = y` on the first call and `    && let Some(x) = y` thereafter\nmacro_rules! chain {\n    ($self:ident, $($t:tt)*) => {\n        if $self.first.take() {\n            println!(\"if {}\", format_args!($($t)*));\n        } else {\n            println!(\"    && {}\", format_args!($($t)*));\n        }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Author {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {\n        check_item(cx, item.hir_id());\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {\n        check_item(cx, item.hir_id());\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {\n        check_item(cx, item.hir_id());\n    }\n\n    fn check_arm(&mut self, cx: &LateContext<'tcx>, arm: &'tcx hir::Arm<'_>) {\n        check_node(cx, arm.hir_id, |v| {\n            v.arm(&v.bind(\"arm\", arm));\n        });\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        check_node(cx, expr.hir_id, |v| {\n            v.expr(&v.bind(\"expr\", expr));\n        });\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) {\n        match stmt.kind {\n            StmtKind::Expr(e) | StmtKind::Semi(e) if has_attr(cx, e.hir_id) => return,\n            _ => {},\n        }\n        check_node(cx, stmt.hir_id, |v| {\n            v.stmt(&v.bind(\"stmt\", stmt));\n        });\n    }\n}\n\nfn check_item(cx: &LateContext<'_>, hir_id: HirId) {\n    if let Some(body) = cx.tcx.hir_maybe_body_owned_by(hir_id.expect_owner().def_id) {\n        check_node(cx, hir_id, |v| {\n            v.expr(&v.bind(\"expr\", body.value));\n        });\n    }\n}\n\nfn check_node(cx: &LateContext<'_>, hir_id: HirId, f: impl Fn(&PrintVisitor<'_, '_>)) {\n    if has_attr(cx, hir_id) {\n        f(&PrintVisitor::new(cx));\n        println!(\"{{\");\n        println!(\"    // report your lint here\");\n        println!(\"}}\");\n    }\n}\n\nfn paths_static_name(cx: &LateContext<'_>, id: DefId) -> String {\n    cx.get_def_path(id)\n        .iter()\n        .map(Symbol::as_str)\n        .filter(|s| !s.starts_with('<'))\n        .join(\"_\")\n        .to_uppercase()\n}\n\nstruct Binding<T> {\n    name: String,\n    value: T,\n}\n\nimpl<T> Display for Binding<T> {\n    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {\n        f.write_str(&self.name)\n    }\n}\n\nstruct OptionPat<T> {\n    pub opt: Option<T>,\n}\n\nimpl<T> OptionPat<T> {\n    fn new(opt: Option<T>) -> Self {\n        Self { opt }\n    }\n\n    fn if_some(&self, f: impl Fn(&T)) {\n        if let Some(t) = &self.opt {\n            f(t);\n        }\n    }\n}\n\nimpl<T: Display> Display for OptionPat<T> {\n    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {\n        match &self.opt {\n            None => f.write_str(\"None\"),\n            Some(node) => write!(f, \"Some({node})\"),\n        }\n    }\n}\n\nstruct PrintVisitor<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    /// Fields are the current index that needs to be appended to pattern\n    /// binding names\n    ids: Cell<FxHashMap<&'static str, u32>>,\n    /// Currently at the first condition in the if chain\n    first: Cell<bool>,\n}\n\nimpl<'a, 'tcx> PrintVisitor<'a, 'tcx> {\n    fn new(cx: &'a LateContext<'tcx>) -> Self {\n        Self {\n            cx,\n            ids: Cell::default(),\n            first: Cell::new(true),\n        }\n    }\n\n    fn next(&self, s: &'static str) -> String {\n        let mut ids = self.ids.take();\n        let out = match *ids.entry(s).and_modify(|n| *n += 1).or_default() {\n            // first usage of the name, use it as is\n            0 => s.to_string(),\n            // append a number starting with 1\n            n => format!(\"{s}{n}\"),\n        };\n        self.ids.set(ids);\n        out\n    }\n\n    fn bind<T>(&self, name: &'static str, value: T) -> Binding<T> {\n        let name = self.next(name);\n        Binding { name, value }\n    }\n\n    fn option<T: Copy>(&self, option: &Binding<Option<T>>, name: &'static str, f: impl Fn(&Binding<T>)) {\n        match option.value {\n            None => chain!(self, \"{option}.is_none()\"),\n            Some(value) => {\n                let value = &self.bind(name, value);\n                chain!(self, \"let Some({value}) = {option}\");\n                f(value);\n            },\n        }\n    }\n\n    fn slice<T>(&self, slice: &Binding<&[T]>, f: impl Fn(&Binding<&T>)) {\n        if slice.value.is_empty() {\n            chain!(self, \"{slice}.is_empty()\");\n        } else {\n            chain!(self, \"{slice}.len() == {}\", slice.value.len());\n            for (i, value) in slice.value.iter().enumerate() {\n                let name = format!(\"{slice}[{i}]\");\n                f(&Binding { name, value });\n            }\n        }\n    }\n\n    fn destination(&self, destination: &Binding<hir::Destination>) {\n        self.option(field!(destination.label), \"label\", |label| {\n            self.ident(field!(label.ident));\n        });\n    }\n\n    fn ident(&self, ident: &Binding<Ident>) {\n        chain!(self, \"{ident}.as_str() == {:?}\", ident.value.as_str());\n    }\n\n    fn symbol(&self, symbol: &Binding<Symbol>) {\n        chain!(self, \"{symbol}.as_str() == {:?}\", symbol.value.as_str());\n    }\n\n    fn qpath(&self, qpath: &Binding<&QPath<'_>>, hir_id_binding: &str, hir_id: HirId) {\n        if let Some(def_id) = self.cx.qpath_res(qpath.value, hir_id).opt_def_id()\n            && !def_id.is_local()\n        {\n            bind!(self, def_id);\n            chain!(\n                self,\n                \"let Some({def_id}) = cx.qpath_res({qpath}, {hir_id_binding}.hir_id).opt_def_id()\"\n            );\n            if let Some(name) = self.cx.tcx.get_diagnostic_name(def_id.value) {\n                chain!(self, \"cx.tcx.is_diagnostic_item(sym::{name}, {def_id})\");\n            } else {\n                chain!(\n                    self,\n                    \"paths::{}.matches(cx, {def_id}) // Add the path to `clippy_utils::paths` if needed\",\n                    paths_static_name(self.cx, def_id.value)\n                );\n            }\n        }\n    }\n\n    fn maybe_path<'p>(&self, path: &Binding<impl MaybeQPath<'p>>) {\n        if let Some(id) = path.value.res(self.cx).opt_def_id()\n            && !id.is_local()\n        {\n            if let Some(lang) = self.cx.tcx.lang_items().from_def_id(id) {\n                chain!(self, \"{path}.res(cx).is_lang_item(cx, LangItem::{}\", lang.name());\n            } else if let Some(name) = self.cx.tcx.get_diagnostic_name(id) {\n                chain!(self, \"{path}.res(cx).is_diag_item(cx, sym::{name})\");\n            } else {\n                chain!(\n                    self,\n                    \"paths::{}.matches_path(cx, {path}) // Add the path to `clippy_utils::paths` if needed\",\n                    paths_static_name(self.cx, id)\n                );\n            }\n        }\n    }\n\n    fn const_arg(&self, const_arg: &Binding<&ConstArg<'_>>) {\n        match const_arg.value.kind {\n            ConstArgKind::Path(ref qpath) => {\n                bind!(self, qpath);\n                chain!(self, \"let ConstArgKind::Path(ref {qpath}) = {const_arg}.kind\");\n            },\n            ConstArgKind::Anon(anon_const) => {\n                bind!(self, anon_const);\n                chain!(self, \"let ConstArgKind::Anon({anon_const}) = {const_arg}.kind\");\n                self.body(field!(anon_const.body));\n            },\n            ConstArgKind::Struct(..) => chain!(self, \"let ConstArgKind::Struct(..) = {const_arg}.kind\"),\n            ConstArgKind::TupleCall(..) => chain!(self, \"let ConstArgKind::TupleCall(..) = {const_arg}.kind\"),\n            ConstArgKind::Array(..) => chain!(self, \"let ConstArgKind::Array(..) = {const_arg}.kind\"),\n            ConstArgKind::Infer(..) => chain!(self, \"let ConstArgKind::Infer(..) = {const_arg}.kind\"),\n            ConstArgKind::Error(..) => chain!(self, \"let ConstArgKind::Error(..) = {const_arg}.kind\"),\n            ConstArgKind::Tup(..) => chain!(self, \"let ConstArgKind::Tup(..) = {const_arg}.kind\"),\n            ConstArgKind::Literal { .. } => chain!(self, \"let ConstArgKind::Literal {{ .. }} = {const_arg}.kind\"),\n        }\n    }\n\n    fn lit(&self, lit: &Binding<Lit>) {\n        let kind = |kind| chain!(self, \"let LitKind::{kind} = {lit}.node\");\n        macro_rules! kind {\n            ($($t:tt)*) => (kind(format_args!($($t)*)));\n        }\n\n        match lit.value.node {\n            LitKind::Bool(val) => kind!(\"Bool({val:?})\"),\n            LitKind::Char(c) => kind!(\"Char({c:?})\"),\n            LitKind::Err(_) => kind!(\"Err\"),\n            LitKind::Byte(b) => kind!(\"Byte({b})\"),\n            LitKind::Int(i, suffix) => {\n                let int_ty = match suffix {\n                    LitIntType::Signed(int_ty) => {\n                        let t = match int_ty {\n                            IntTy::Isize => \"Isize\",\n                            IntTy::I8 => \"I8\",\n                            IntTy::I16 => \"I16\",\n                            IntTy::I32 => \"I32\",\n                            IntTy::I64 => \"I64\",\n                            IntTy::I128 => \"I128\",\n                        };\n                        format!(\"LitIntType::Signed(IntTy::{t})\")\n                    },\n                    LitIntType::Unsigned(uint_ty) => {\n                        let t = match uint_ty {\n                            UintTy::Usize => \"Usize\",\n                            UintTy::U8 => \"U8\",\n                            UintTy::U16 => \"U16\",\n                            UintTy::U32 => \"U32\",\n                            UintTy::U64 => \"U64\",\n                            UintTy::U128 => \"U128\",\n                        };\n                        format!(\"LitIntType::Unsigned(UintTy::{t})\")\n                    },\n                    LitIntType::Unsuffixed => String::from(\"LitIntType::Unsuffixed\"),\n                };\n                kind!(\"Int({i}, {int_ty})\");\n            },\n            LitKind::Float(_, suffix) => {\n                let float_ty = match suffix {\n                    LitFloatType::Suffixed(suffix_ty) => {\n                        let t = match suffix_ty {\n                            FloatTy::F16 => \"F16\",\n                            FloatTy::F32 => \"F32\",\n                            FloatTy::F64 => \"F64\",\n                            FloatTy::F128 => \"F128\",\n                        };\n                        format!(\"LitFloatType::Suffixed(FloatTy::{t})\")\n                    },\n                    LitFloatType::Unsuffixed => String::from(\"LitFloatType::Unsuffixed\"),\n                };\n                kind!(\"Float(_, {float_ty})\");\n            },\n            LitKind::ByteStr(ref vec, _) => {\n                bind!(self, vec);\n                kind!(\"ByteStr(ref {vec})\");\n                chain!(self, \"let [{:?}] = **{vec}\", vec.value);\n            },\n            LitKind::CStr(ref vec, _) => {\n                bind!(self, vec);\n                kind!(\"CStr(ref {vec})\");\n                chain!(self, \"let [{:?}] = **{vec}\", vec.value);\n            },\n            LitKind::Str(s, _) => {\n                bind!(self, s);\n                kind!(\"Str({s}, _)\");\n                self.symbol(s);\n            },\n        }\n    }\n\n    fn arm(&self, arm: &Binding<&hir::Arm<'_>>) {\n        self.pat(field!(arm.pat));\n        match arm.value.guard {\n            None => chain!(self, \"{arm}.guard.is_none()\"),\n            Some(expr) => {\n                bind!(self, expr);\n                chain!(self, \"let Some({expr}) = {arm}.guard\");\n                self.expr(expr);\n            },\n        }\n        self.expr(field!(arm.body));\n    }\n\n    #[expect(clippy::too_many_lines)]\n    fn expr(&self, expr: &Binding<&hir::Expr<'_>>) {\n        if let Some(higher::While { condition, body, .. }) = higher::While::hir(expr.value) {\n            bind!(self, condition, body);\n            chain!(\n                self,\n                \"let Some(higher::While {{ condition: {condition}, body: {body} }}) \\\n                = higher::While::hir({expr})\"\n            );\n            self.expr(condition);\n            self.expr(body);\n            return;\n        }\n\n        if let Some(higher::WhileLet {\n            let_pat,\n            let_expr,\n            if_then,\n            ..\n        }) = higher::WhileLet::hir(expr.value)\n        {\n            bind!(self, let_pat, let_expr, if_then);\n            chain!(\n                self,\n                \"let Some(higher::WhileLet {{ let_pat: {let_pat}, let_expr: {let_expr}, if_then: {if_then} }}) \\\n                = higher::WhileLet::hir({expr})\"\n            );\n            self.pat(let_pat);\n            self.expr(let_expr);\n            self.expr(if_then);\n            return;\n        }\n\n        if let Some(higher::ForLoop { pat, arg, body, .. }) = higher::ForLoop::hir(expr.value) {\n            bind!(self, pat, arg, body);\n            chain!(\n                self,\n                \"let Some(higher::ForLoop {{ pat: {pat}, arg: {arg}, body: {body}, .. }}) \\\n                = higher::ForLoop::hir({expr})\"\n            );\n            self.pat(pat);\n            self.expr(arg);\n            self.expr(body);\n            return;\n        }\n\n        let kind = |kind| chain!(self, \"let ExprKind::{kind} = {expr}.kind\");\n        macro_rules! kind {\n            ($($t:tt)*) => (kind(format_args!($($t)*)));\n        }\n\n        match expr.value.kind {\n            ExprKind::Let(let_expr) => {\n                bind!(self, let_expr);\n                kind!(\"Let({let_expr})\");\n                self.pat(field!(let_expr.pat));\n                if let Some(ty) = let_expr.value.ty {\n                    bind!(self, ty);\n                    chain!(self, \"let Some({ty}) = {let_expr}.ty\");\n                    self.maybe_path(ty);\n                }\n                self.expr(field!(let_expr.init));\n            },\n            ExprKind::Array(elements) => {\n                bind!(self, elements);\n                kind!(\"Array({elements})\");\n                self.slice(elements, |e| self.expr(e));\n            },\n            ExprKind::Call(func, args) => {\n                bind!(self, func, args);\n                kind!(\"Call({func}, {args})\");\n                self.expr(func);\n                self.slice(args, |e| self.expr(e));\n            },\n            ExprKind::MethodCall(method_name, receiver, args, _) => {\n                bind!(self, method_name, receiver, args);\n                kind!(\"MethodCall({method_name}, {receiver}, {args}, _)\");\n                self.ident(field!(method_name.ident));\n                self.expr(receiver);\n                self.slice(args, |e| self.expr(e));\n            },\n            ExprKind::Tup(elements) => {\n                bind!(self, elements);\n                kind!(\"Tup({elements})\");\n                self.slice(elements, |e| self.expr(e));\n            },\n            ExprKind::Use(expr, _) => {\n                bind!(self, expr);\n                kind!(\"Use({expr})\");\n                self.expr(expr);\n            },\n            ExprKind::Binary(op, left, right) => {\n                bind!(self, op, left, right);\n                kind!(\"Binary({op}, {left}, {right})\");\n                chain!(self, \"BinOpKind::{:?} == {op}.node\", op.value.node);\n                self.expr(left);\n                self.expr(right);\n            },\n            ExprKind::Unary(op, inner) => {\n                bind!(self, inner);\n                kind!(\"Unary(UnOp::{op:?}, {inner})\");\n                self.expr(inner);\n            },\n            ExprKind::Lit(lit) => {\n                bind!(self, lit);\n                kind!(\"Lit(ref {lit})\");\n                self.lit(lit);\n            },\n            ExprKind::Cast(expr, cast_ty) => {\n                bind!(self, expr, cast_ty);\n                kind!(\"Cast({expr}, {cast_ty})\");\n                self.maybe_path(cast_ty);\n                self.expr(expr);\n            },\n            ExprKind::Type(expr, _ty) => {\n                bind!(self, expr);\n                kind!(\"Type({expr}, _)\");\n                self.expr(expr);\n            },\n            ExprKind::Loop(body, label, des, _) => {\n                bind!(self, body);\n                opt_bind!(self, label);\n                kind!(\"Loop({body}, {label}, LoopSource::{des:?}, _)\");\n                self.block(body);\n                label.if_some(|l| self.ident(field!(l.ident)));\n            },\n            ExprKind::If(cond, then, else_expr) => {\n                bind!(self, cond, then);\n                opt_bind!(self, else_expr);\n                kind!(\"If({cond}, {then}, {else_expr})\");\n                self.expr(cond);\n                self.expr(then);\n                else_expr.if_some(|e| self.expr(e));\n            },\n            ExprKind::Match(scrutinee, arms, des) => {\n                bind!(self, scrutinee, arms);\n                kind!(\"Match({scrutinee}, {arms}, MatchSource::{des:?})\");\n                self.expr(scrutinee);\n                self.slice(arms, |arm| self.arm(arm));\n            },\n            ExprKind::Closure(&Closure {\n                capture_clause,\n                fn_decl,\n                body: body_id,\n                kind,\n                ..\n            }) => {\n                let capture_clause = match capture_clause {\n                    CaptureBy::Value { .. } => \"Value { .. }\",\n                    CaptureBy::Use { .. } => \"Use { .. }\",\n                    CaptureBy::Ref => \"Ref\",\n                };\n\n                let closure_kind = match kind {\n                    ClosureKind::Closure => \"ClosureKind::Closure\".to_string(),\n                    ClosureKind::Coroutine(coroutine_kind) => match coroutine_kind {\n                        CoroutineKind::Desugared(desugaring, source) => format!(\n                            \"ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::{desugaring:?}, CoroutineSource::{source:?}))\"\n                        ),\n                        CoroutineKind::Coroutine(movability) => {\n                            format!(\"ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})\")\n                        },\n                    },\n                    ClosureKind::CoroutineClosure(desugaring) => {\n                        format!(\"ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})\")\n                    },\n                };\n\n                let ret_ty = match fn_decl.output {\n                    FnRetTy::DefaultReturn(_) => \"FnRetTy::DefaultReturn(_)\",\n                    FnRetTy::Return(_) => \"FnRetTy::Return(_ty)\",\n                };\n\n                bind!(self, fn_decl, body_id);\n                kind!(\n                    \"Closure {{ capture_clause: CaptureBy::{capture_clause}, fn_decl: {fn_decl}, body: {body_id}, closure_kind: {closure_kind}, .. }}\"\n                );\n                chain!(self, \"let {ret_ty} = {fn_decl}.output\");\n                self.body(body_id);\n            },\n            ExprKind::Yield(sub, source) => {\n                bind!(self, sub);\n                kind!(\"Yield(sub, YieldSource::{source:?})\");\n                self.expr(sub);\n            },\n            ExprKind::Block(block, label) => {\n                bind!(self, block);\n                opt_bind!(self, label);\n                kind!(\"Block({block}, {label})\");\n                self.block(block);\n                label.if_some(|l| self.ident(field!(l.ident)));\n            },\n            ExprKind::Assign(target, value, _) => {\n                bind!(self, target, value);\n                kind!(\"Assign({target}, {value}, _span)\");\n                self.expr(target);\n                self.expr(value);\n            },\n            ExprKind::AssignOp(op, target, value) => {\n                bind!(self, op, target, value);\n                kind!(\"AssignOp({op}, {target}, {value})\");\n                chain!(self, \"BinOpKind::{:?} == {op}.node\", op.value.node);\n                self.expr(target);\n                self.expr(value);\n            },\n            ExprKind::Field(object, field_name) => {\n                bind!(self, object, field_name);\n                kind!(\"Field({object}, {field_name})\");\n                self.ident(field_name);\n                self.expr(object);\n            },\n            ExprKind::Index(object, index, _) => {\n                bind!(self, object, index);\n                kind!(\"Index({object}, {index})\");\n                self.expr(object);\n                self.expr(index);\n            },\n            ExprKind::Path(_) => {\n                self.maybe_path(expr);\n            },\n            ExprKind::AddrOf(kind, mutability, inner) => {\n                bind!(self, inner);\n                kind!(\"AddrOf(BorrowKind::{kind:?}, Mutability::{mutability:?}, {inner})\");\n                self.expr(inner);\n            },\n            ExprKind::Break(destination, value) => {\n                bind!(self, destination);\n                opt_bind!(self, value);\n                kind!(\"Break({destination}, {value})\");\n                self.destination(destination);\n                value.if_some(|e| self.expr(e));\n            },\n            ExprKind::Continue(destination) => {\n                bind!(self, destination);\n                kind!(\"Continue({destination})\");\n                self.destination(destination);\n            },\n            ExprKind::Ret(value) => {\n                opt_bind!(self, value);\n                kind!(\"Ret({value})\");\n                value.if_some(|e| self.expr(e));\n            },\n            ExprKind::Become(value) => {\n                bind!(self, value);\n                kind!(\"Become({value})\");\n                self.expr(value);\n            },\n            ExprKind::InlineAsm(_) => {\n                kind!(\"InlineAsm(_)\");\n                out!(\"// unimplemented: `ExprKind::InlineAsm` is not further destructured at the moment\");\n            },\n            ExprKind::OffsetOf(container, ref fields) => {\n                bind!(self, container, fields);\n                kind!(\"OffsetOf({container}, {fields})\");\n            },\n            ExprKind::Struct(qpath, fields, base) => {\n                bind!(self, qpath, fields);\n                let base = OptionPat::new(match base {\n                    StructTailExpr::Base(base) => Some(self.bind(\"base\", base)),\n                    StructTailExpr::None | StructTailExpr::NoneWithError(_) | StructTailExpr::DefaultFields(_) => None,\n                });\n                kind!(\"Struct({qpath}, {fields}, {base})\");\n                self.qpath(qpath, &expr.name, expr.value.hir_id);\n                self.slice(fields, |field| {\n                    self.ident(field!(field.ident));\n                    self.expr(field!(field.expr));\n                });\n                base.if_some(|e| self.expr(e));\n            },\n            ExprKind::ConstBlock(_) => kind!(\"ConstBlock(_)\"),\n            ExprKind::Repeat(value, length) => {\n                bind!(self, value, length);\n                kind!(\"Repeat({value}, {length})\");\n                self.expr(value);\n                self.const_arg(length);\n            },\n            ExprKind::Err(_) => kind!(\"Err(_)\"),\n            ExprKind::DropTemps(expr) => {\n                bind!(self, expr);\n                kind!(\"DropTemps({expr})\");\n                self.expr(expr);\n            },\n            ExprKind::UnsafeBinderCast(..) => {\n                unimplemented!(\"unsafe binders are not implemented yet\");\n            },\n        }\n    }\n\n    fn block(&self, block: &Binding<&hir::Block<'_>>) {\n        self.slice(field!(block.stmts), |stmt| self.stmt(stmt));\n        self.option(field!(block.expr), \"trailing_expr\", |expr| {\n            self.expr(expr);\n        });\n    }\n\n    fn body(&self, body_id: &Binding<hir::BodyId>) {\n        let expr = self.cx.tcx.hir_body(body_id.value).value;\n        bind!(self, expr);\n        chain!(self, \"{expr} = &cx.tcx.hir_body({body_id}).value\");\n        self.expr(expr);\n    }\n\n    fn pat_expr(&self, lit: &Binding<&hir::PatExpr<'_>>, pat: &Binding<&hir::Pat<'_>>) {\n        let kind = |kind| chain!(self, \"let PatExprKind::{kind} = {lit}.kind\");\n        macro_rules! kind {\n            ($($t:tt)*) => (kind(format_args!($($t)*)));\n        }\n        match lit.value.kind {\n            PatExprKind::Lit { lit, negated } => {\n                bind!(self, lit);\n                bind!(self, negated);\n                kind!(\"Lit {{ ref {lit}, {negated} }}\");\n                self.lit(lit);\n            },\n            PatExprKind::Path(_) => self.maybe_path(pat),\n        }\n    }\n\n    fn pat(&self, pat: &Binding<&hir::Pat<'_>>) {\n        let kind = |kind| chain!(self, \"let PatKind::{kind} = {pat}.kind\");\n        macro_rules! kind {\n            ($($t:tt)*) => (kind(format_args!($($t)*)));\n        }\n\n        match pat.value.kind {\n            PatKind::Missing => unreachable!(),\n            PatKind::Wild => kind!(\"Wild\"),\n            PatKind::Never => kind!(\"Never\"),\n            PatKind::Binding(ann, _, name, sub) => {\n                bind!(self, name);\n                opt_bind!(self, sub);\n                let ann = match ann {\n                    BindingMode::NONE => \"NONE\",\n                    BindingMode::REF => \"REF\",\n                    BindingMode::REF_PIN => \"REF_PIN\",\n                    BindingMode::MUT => \"MUT\",\n                    BindingMode::REF_MUT => \"REF_MUT\",\n                    BindingMode::REF_PIN_MUT => \"REF_PIN_MUT\",\n                    BindingMode::MUT_REF => \"MUT_REF\",\n                    BindingMode::MUT_REF_PIN => \"MUT_REF_PIN\",\n                    BindingMode::MUT_REF_MUT => \"MUT_REF_MUT\",\n                    BindingMode::MUT_REF_PIN_MUT => \"MUT_REF_PIN_MUT\",\n                };\n                kind!(\"Binding(BindingMode::{ann}, _, {name}, {sub})\");\n                self.ident(name);\n                sub.if_some(|p| self.pat(p));\n            },\n            PatKind::Struct(ref qpath, fields, etc) => {\n                let ignore = etc.is_some();\n                bind!(self, qpath, fields);\n                kind!(\"Struct(ref {qpath}, {fields}, {ignore})\");\n                self.qpath(qpath, &pat.name, pat.value.hir_id);\n                self.slice(fields, |field| {\n                    self.ident(field!(field.ident));\n                    self.pat(field!(field.pat));\n                });\n            },\n            PatKind::Or(fields) => {\n                bind!(self, fields);\n                kind!(\"Or({fields})\");\n                self.slice(fields, |pat| self.pat(pat));\n            },\n            PatKind::TupleStruct(ref qpath, fields, skip_pos) => {\n                bind!(self, qpath, fields);\n                kind!(\"TupleStruct(ref {qpath}, {fields}, {skip_pos:?})\");\n                self.qpath(qpath, &pat.name, pat.value.hir_id);\n                self.slice(fields, |pat| self.pat(pat));\n            },\n            PatKind::Tuple(fields, skip_pos) => {\n                bind!(self, fields);\n                kind!(\"Tuple({fields}, {skip_pos:?})\");\n                self.slice(fields, |field| self.pat(field));\n            },\n            PatKind::Box(pat) => {\n                bind!(self, pat);\n                kind!(\"Box({pat})\");\n                self.pat(pat);\n            },\n            PatKind::Deref(pat) => {\n                bind!(self, pat);\n                kind!(\"Deref({pat})\");\n                self.pat(pat);\n            },\n            PatKind::Ref(pat, pinn, muta) => {\n                bind!(self, pat);\n                kind!(\"Ref({pat}, Pinning::{pinn:?}, Mutability::{muta:?})\");\n                self.pat(pat);\n            },\n            PatKind::Guard(pat, cond) => {\n                bind!(self, pat, cond);\n                kind!(\"Guard({pat}, {cond})\");\n                self.pat(pat);\n                self.expr(cond);\n            },\n            PatKind::Expr(lit_expr) => {\n                bind!(self, lit_expr);\n                kind!(\"Expr({lit_expr})\");\n                self.pat_expr(lit_expr, pat);\n            },\n            PatKind::Range(start, end, end_kind) => {\n                opt_bind!(self, start, end);\n                kind!(\"Range({start}, {end}, RangeEnd::{end_kind:?})\");\n                start.if_some(|e| self.pat_expr(e, pat));\n                end.if_some(|e| self.pat_expr(e, pat));\n            },\n            PatKind::Slice(start, middle, end) => {\n                bind!(self, start, end);\n                opt_bind!(self, middle);\n                kind!(\"Slice({start}, {middle}, {end})\");\n                middle.if_some(|p| self.pat(p));\n                self.slice(start, |pat| self.pat(pat));\n                self.slice(end, |pat| self.pat(pat));\n            },\n            PatKind::Err(_) => kind!(\"Err\"),\n        }\n    }\n\n    fn stmt(&self, stmt: &Binding<&hir::Stmt<'_>>) {\n        let kind = |kind| chain!(self, \"let StmtKind::{kind} = {stmt}.kind\");\n        macro_rules! kind {\n            ($($t:tt)*) => (kind(format_args!($($t)*)));\n        }\n\n        match stmt.value.kind {\n            StmtKind::Let(local) => {\n                bind!(self, local);\n                kind!(\"Let({local})\");\n                self.option(field!(local.init), \"init\", |init| {\n                    self.expr(init);\n                });\n                self.pat(field!(local.pat));\n            },\n            StmtKind::Item(_) => kind!(\"Item(item_id)\"),\n            StmtKind::Expr(e) => {\n                bind!(self, e);\n                kind!(\"Expr({e})\");\n                self.expr(e);\n            },\n            StmtKind::Semi(e) => {\n                bind!(self, e);\n                kind!(\"Semi({e})\");\n                self.expr(e);\n            },\n        }\n    }\n}\n\nfn has_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {\n    let attrs = cx.tcx.hir_attrs(hir_id);\n    get_builtin_attr(cx.sess(), attrs, sym::author).count() > 0\n}\n"
  },
  {
    "path": "clippy_lints/src/utils/dump_hir.rs",
    "content": "use clippy_utils::{get_builtin_attr, sym};\nuse hir::TraitItem;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\n\ndeclare_lint_pass!(\n    /// ### What it does\n    /// It formats the attached node with `{:#?}` and writes the result to the\n    /// standard output. This is intended for debugging.\n    ///\n    /// ### Examples\n    /// ```rs\n    /// #[clippy::dump]\n    /// use std::mem;\n    ///\n    /// #[clippy::dump]\n    /// fn foo(input: u32) -> u64 {\n    ///     input as u64\n    /// }\n    /// ```\n    DumpHir => []\n);\n\nimpl<'tcx> LateLintPass<'tcx> for DumpHir {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {\n        if has_attr(cx, item.hir_id()) {\n            println!(\"{item:#?}\");\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        if has_attr(cx, expr.hir_id) {\n            println!(\"{expr:#?}\");\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx hir::Stmt<'_>) {\n        match stmt.kind {\n            hir::StmtKind::Expr(e) | hir::StmtKind::Semi(e) if has_attr(cx, e.hir_id) => return,\n            _ => {},\n        }\n        if has_attr(cx, stmt.hir_id) {\n            println!(\"{stmt:#?}\");\n        }\n    }\n\n    fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &TraitItem<'_>) {\n        if has_attr(cx, item.hir_id()) {\n            println!(\"{item:#?}\");\n        }\n    }\n\n    fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &hir::ImplItem<'_>) {\n        if has_attr(cx, item.hir_id()) {\n            println!(\"{item:#?}\");\n        }\n    }\n}\n\nfn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool {\n    let attrs = cx.tcx.hir_attrs(hir_id);\n    get_builtin_attr(cx.sess(), attrs, sym::dump).count() > 0\n}\n"
  },
  {
    "path": "clippy_lints/src/utils/format_args_collector.rs",
    "content": "use clippy_utils::macros::FormatArgsStorage;\nuse clippy_utils::source::SpanRangeExt;\nuse itertools::Itertools;\nuse rustc_ast::{Crate, Expr, ExprKind, FormatArgs};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, hygiene};\nuse std::iter::once;\nuse std::mem;\n\n/// Populates [`FormatArgsStorage`] with AST [`FormatArgs`] nodes\npub struct FormatArgsCollector {\n    format_args: FxHashMap<Span, FormatArgs>,\n    storage: FormatArgsStorage,\n}\n\nimpl FormatArgsCollector {\n    pub fn new(storage: FormatArgsStorage) -> Self {\n        Self {\n            format_args: FxHashMap::default(),\n            storage,\n        }\n    }\n}\n\nimpl_lint_pass!(FormatArgsCollector => []);\n\nimpl EarlyLintPass for FormatArgsCollector {\n    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {\n        if let ExprKind::FormatArgs(args) = &expr.kind {\n            if has_span_from_proc_macro(cx, args) {\n                return;\n            }\n\n            self.format_args.insert(expr.span.with_parent(None), (**args).clone());\n        }\n    }\n\n    fn check_crate_post(&mut self, _: &EarlyContext<'_>, _: &Crate) {\n        self.storage.set(mem::take(&mut self.format_args));\n    }\n}\n\n/// Detects if the format string or an argument has its span set by a proc macro to something inside\n/// a macro callsite, e.g.\n///\n/// ```ignore\n/// println!(some_proc_macro!(\"input {}\"), a);\n/// ```\n///\n/// Where `some_proc_macro` expands to\n///\n/// ```ignore\n/// println!(\"output {}\", a);\n/// ```\n///\n/// But with the span of `\"output {}\"` set to the macro input\n///\n/// ```ignore\n/// println!(some_proc_macro!(\"input {}\"), a);\n/// //                        ^^^^^^^^^^\n/// ```\nfn has_span_from_proc_macro(cx: &EarlyContext<'_>, args: &FormatArgs) -> bool {\n    let ctxt = args.span.ctxt();\n\n    // `format!(\"{} {} {c}\", \"one\", \"two\", c = \"three\")`\n    //                       ^^^^^  ^^^^^      ^^^^^^^\n    let argument_span = args\n        .arguments\n        .explicit_args()\n        .iter()\n        .map(|argument| hygiene::walk_chain(argument.expr.span, ctxt));\n\n    // `format!(\"{} {} {c}\", \"one\", \"two\", c = \"three\")`\n    //                     ^^     ^^     ^^^^^^\n    !once(args.span)\n        .chain(argument_span)\n        .tuple_windows()\n        .map(|(start, end)| start.between(end))\n        .all(|sp| {\n            sp.check_source_text(cx, |src| {\n                // text should be either `, name` or `, name =`\n                let mut iter = tokenize(src, FrontmatterAllowed::No).filter(|t| {\n                    !matches!(\n                        t.kind,\n                        TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace\n                    )\n                });\n                iter.next().is_some_and(|t| matches!(t.kind, TokenKind::Comma))\n                    && iter.all(|t| matches!(t.kind, TokenKind::Ident | TokenKind::Eq))\n            })\n        })\n}\n"
  },
  {
    "path": "clippy_lints/src/utils/mod.rs",
    "content": "pub mod attr_collector;\npub mod author;\npub mod dump_hir;\npub mod format_args_collector;\n"
  },
  {
    "path": "clippy_lints/src/vec_init_then_push.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::higher::{VecInitKind, get_vec_init_kind};\nuse clippy_utils::res::MaybeResPath;\nuse clippy_utils::source::snippet;\nuse clippy_utils::visitors::for_each_local_use_after_expr;\nuse clippy_utils::{get_parent_expr, sym};\nuse core::ops::ControlFlow;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::Res;\nuse rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\nuse rustc_span::{Span, Symbol};\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for calls to `push` immediately after creating a new `Vec`.\n    ///\n    /// If the `Vec` is created using `with_capacity` this will only lint if the capacity is a\n    /// constant and the number of pushes is greater than or equal to the initial capacity.\n    ///\n    /// If the `Vec` is extended after the initial sequence of pushes and it was default initialized\n    /// then this will only lint after there were at least four pushes. This number may change in\n    /// the future.\n    ///\n    /// ### Why is this bad?\n    /// The `vec![]` macro is both more performant and easier to read than\n    /// multiple `push` calls.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let mut v = Vec::new();\n    /// v.push(0);\n    /// v.push(1);\n    /// v.push(2);\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// let v = vec![0, 1, 2];\n    /// ```\n    #[clippy::version = \"1.51.0\"]\n    pub VEC_INIT_THEN_PUSH,\n    perf,\n    \"`push` immediately after `Vec` creation\"\n}\n\nimpl_lint_pass!(VecInitThenPush => [VEC_INIT_THEN_PUSH]);\n\n#[derive(Default)]\npub struct VecInitThenPush {\n    searcher: Option<VecPushSearcher>,\n}\n\nstruct VecPushSearcher {\n    local_id: HirId,\n    init: VecInitKind,\n    lhs_is_let: bool,\n    let_ty_span: Option<Span>,\n    name: Symbol,\n    err_span: Span,\n    found: u128,\n    last_push_expr: HirId,\n}\nimpl VecPushSearcher {\n    fn display_err(&self, cx: &LateContext<'_>) {\n        let required_pushes_before_extension = match self.init {\n            _ if self.found == 0 => return,\n            VecInitKind::WithConstCapacity(x) if x > self.found => return,\n            VecInitKind::WithConstCapacity(x) => x,\n            VecInitKind::WithExprCapacity(_) => return,\n            _ => 3,\n        };\n\n        let mut needs_mut = false;\n        let res = for_each_local_use_after_expr(cx, self.local_id, self.last_push_expr, |e| {\n            let Some(parent) = get_parent_expr(cx, e) else {\n                return ControlFlow::Continue(());\n            };\n            let adjusted_ty = cx.typeck_results().expr_ty_adjusted(e);\n            let adjusted_mut = adjusted_ty.ref_mutability().unwrap_or(Mutability::Not);\n            needs_mut |= adjusted_mut == Mutability::Mut;\n            match parent.kind {\n                ExprKind::AddrOf(_, Mutability::Mut, _) => {\n                    needs_mut = true;\n                    return ControlFlow::Break(true);\n                },\n                ExprKind::Unary(UnOp::Deref, _) | ExprKind::Index(..) if !needs_mut => {\n                    let mut last_place = parent;\n                    while let Some(parent) = get_parent_expr(cx, last_place) {\n                        if matches!(parent.kind, ExprKind::Unary(UnOp::Deref, _) | ExprKind::Field(..))\n                            || matches!(parent.kind, ExprKind::Index(e, _, _) if e.hir_id == last_place.hir_id)\n                        {\n                            last_place = parent;\n                        } else {\n                            break;\n                        }\n                    }\n                    needs_mut |= cx.typeck_results().expr_ty_adjusted(last_place).ref_mutability()\n                        == Some(Mutability::Mut)\n                        || get_parent_expr(cx, last_place)\n                            .is_some_and(|e| matches!(e.kind, ExprKind::AddrOf(_, Mutability::Mut, _)));\n                },\n                ExprKind::MethodCall(_, recv, ..)\n                    if recv.hir_id == e.hir_id\n                        && adjusted_mut == Mutability::Mut\n                        && !adjusted_ty.peel_refs().is_slice() =>\n                {\n                    // No need to set `needs_mut` to true. The receiver will be either explicitly borrowed, or it will\n                    // be implicitly borrowed via an adjustment. Both of these cases are already handled by this point.\n                    return ControlFlow::Break(true);\n                },\n                ExprKind::Assign(lhs, ..) if e.hir_id == lhs.hir_id => {\n                    needs_mut = true;\n                    return ControlFlow::Break(false);\n                },\n                _ => (),\n            }\n            ControlFlow::Continue(())\n        });\n\n        // Avoid allocating small `Vec`s when they'll be extended right after.\n        if res == ControlFlow::Break(true) && self.found <= required_pushes_before_extension {\n            return;\n        }\n\n        let mut s = if self.lhs_is_let {\n            String::from(\"let \")\n        } else {\n            String::new()\n        };\n        if needs_mut {\n            s.push_str(\"mut \");\n        }\n        s.push_str(self.name.as_str());\n        if let Some(span) = self.let_ty_span {\n            s.push_str(\": \");\n            s.push_str(&snippet(cx, span, \"_\"));\n        }\n        s.push_str(\" = vec![..];\");\n\n        span_lint_and_sugg(\n            cx,\n            VEC_INIT_THEN_PUSH,\n            self.err_span,\n            \"calls to `push` immediately after creation\",\n            \"consider using the `vec![]` macro\",\n            s,\n            Applicability::HasPlaceholders,\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for VecInitThenPush {\n    fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {\n        self.searcher = None;\n    }\n\n    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {\n        if let Some(init_expr) = local.init\n            && let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind\n            && !local.span.in_external_macro(cx.sess().source_map())\n            && let Some(init) = get_vec_init_kind(cx, init_expr)\n            && !matches!(init, VecInitKind::WithExprCapacity(_))\n        {\n            self.searcher = Some(VecPushSearcher {\n                local_id: id,\n                init,\n                lhs_is_let: true,\n                let_ty_span: local.ty.map(|ty| ty.span),\n                name: name.name,\n                err_span: local.span,\n                found: 0,\n                last_push_expr: init_expr.hir_id,\n            });\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if self.searcher.is_none()\n            && let ExprKind::Assign(left, right, _) = expr.kind\n            && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind\n            && let [name] = &path.segments\n            && let Res::Local(id) = path.res\n            && !expr.span.in_external_macro(cx.sess().source_map())\n            && let Some(init) = get_vec_init_kind(cx, right)\n            && !matches!(init, VecInitKind::WithExprCapacity(_))\n        {\n            self.searcher = Some(VecPushSearcher {\n                local_id: id,\n                init,\n                lhs_is_let: false,\n                let_ty_span: None,\n                name: name.ident.name,\n                err_span: expr.span,\n                found: 0,\n                last_push_expr: expr.hir_id,\n            });\n        }\n    }\n\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if let Some(searcher) = self.searcher.take() {\n            if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind\n                && let ExprKind::MethodCall(name, self_arg, [_], _) = expr.kind\n                && self_arg.res_local_id() == Some(searcher.local_id)\n                && name.ident.name == sym::push\n            {\n                self.searcher = Some(VecPushSearcher {\n                    err_span: searcher.err_span.to(stmt.span),\n                    found: searcher.found + 1,\n                    last_push_expr: expr.hir_id,\n                    ..searcher\n                });\n            } else {\n                searcher.display_err(cx);\n            }\n        }\n    }\n\n    fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx Block<'tcx>) {\n        if let Some(searcher) = self.searcher.take() {\n            searcher.display_err(cx);\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/visibility.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::source::SpanRangeExt;\nuse rustc_ast::ast::{Item, VisibilityKind};\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `pub(self)` and `pub(in self)`.\n    ///\n    /// ### Why is this bad?\n    /// It's unnecessary, omitting the `pub` entirely will give the same results.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// pub(self) type OptBox<T> = Option<Box<T>>;\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// type OptBox<T> = Option<Box<T>>;\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub NEEDLESS_PUB_SELF,\n    style,\n    \"checks for usage of `pub(self)` and `pub(in self)`.\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `pub(<loc>)` with `in`.\n    ///\n    /// ### Why restrict this?\n    /// Consistency. Use it or don't, just be consistent about it.\n    ///\n    /// Also see the `pub_without_shorthand` lint for an alternative.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// pub(super) type OptBox<T> = Option<Box<T>>;\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// pub(in super) type OptBox<T> = Option<Box<T>>;\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub PUB_WITH_SHORTHAND,\n    restriction,\n    \"disallows usage of `pub(<loc>)`, without `in`\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `pub(<loc>)` without `in`.\n    ///\n    /// Note: As you cannot write a module's path in `pub(<loc>)`, this will only trigger on\n    /// `pub(super)` and the like.\n    ///\n    /// ### Why restrict this?\n    /// Consistency. Use it or don't, just be consistent about it.\n    ///\n    /// Also see the `pub_with_shorthand` lint for an alternative.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// pub(in super) type OptBox<T> = Option<Box<T>>;\n    /// ```\n    /// Use instead:\n    /// ```rust,ignore\n    /// pub(super) type OptBox<T> = Option<Box<T>>;\n    /// ```\n    #[clippy::version = \"1.72.0\"]\n    pub PUB_WITHOUT_SHORTHAND,\n    restriction,\n    \"disallows usage of `pub(in <loc>)` with `in`\"\n}\n\ndeclare_lint_pass!(Visibility => [\n    NEEDLESS_PUB_SELF,\n    PUB_WITHOUT_SHORTHAND,\n    PUB_WITH_SHORTHAND,\n]);\n\nimpl EarlyLintPass for Visibility {\n    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {\n        if !item.span.in_external_macro(cx.sess().source_map())\n            && let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind\n        {\n            if **path == kw::SelfLower && !is_from_proc_macro(cx, item.vis.span) {\n                span_lint_and_then(\n                    cx,\n                    NEEDLESS_PUB_SELF,\n                    item.vis.span,\n                    format!(\"unnecessary `pub({}self)`\", if *shorthand { \"\" } else { \"in \" }),\n                    |diag| {\n                        diag.span_suggestion_hidden(\n                            item.vis.span,\n                            \"remove it\",\n                            String::new(),\n                            Applicability::MachineApplicable,\n                        );\n                    },\n                );\n            }\n\n            if (**path == kw::Super || **path == kw::SelfLower || **path == kw::Crate)\n                && !*shorthand\n                && let [.., last] = &*path.segments\n                && !is_from_proc_macro(cx, item.vis.span)\n            {\n                #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                span_lint_and_then(\n                    cx,\n                    PUB_WITHOUT_SHORTHAND,\n                    item.vis.span,\n                    \"usage of `pub` with `in`\",\n                    |diag| {\n                        diag.span_suggestion(\n                            item.vis.span,\n                            \"remove it\",\n                            format!(\"pub({})\", last.ident),\n                            Applicability::MachineApplicable,\n                        );\n                    },\n                );\n            }\n\n            if *shorthand\n                && let [.., last] = &*path.segments\n                && !is_from_proc_macro(cx, item.vis.span)\n            {\n                #[expect(clippy::collapsible_span_lint_calls, reason = \"rust-clippy#7797\")]\n                span_lint_and_then(\n                    cx,\n                    PUB_WITH_SHORTHAND,\n                    item.vis.span,\n                    \"usage of `pub` without `in`\",\n                    |diag| {\n                        diag.span_suggestion(\n                            item.vis.span,\n                            \"add it\",\n                            format!(\"pub(in {})\", last.ident),\n                            Applicability::MachineApplicable,\n                        );\n                    },\n                );\n            }\n        }\n    }\n}\n\nfn is_from_proc_macro(cx: &EarlyContext<'_>, span: Span) -> bool {\n    !span.check_source_text(cx, |src| src.starts_with(\"pub\"))\n}\n"
  },
  {
    "path": "clippy_lints/src/volatile_composites.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::layout::LayoutOf;\nuse rustc_middle::ty::{self, Ty, TypeVisitableExt};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    ///\n    /// This lint warns when volatile load/store operations\n    /// (`write_volatile`/`read_volatile`) are applied to composite types.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Volatile operations are typically used with memory mapped IO devices,\n    /// where the precise number and ordering of load and store instructions is\n    /// important because they can have side effects. This is well defined for\n    /// primitive types like `u32`, but less well defined for structures and\n    /// other composite types. In practice it's implementation defined, and the\n    /// behavior can be rustc-version dependent.\n    ///\n    /// As a result, code should only apply `write_volatile`/`read_volatile` to\n    /// primitive types to be fully well-defined.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// struct MyDevice {\n    ///     addr: usize,\n    ///     count: usize\n    /// }\n    ///\n    /// fn start_device(device: *mut MyDevice, addr: usize, count: usize) {\n    ///     unsafe {\n    ///         device.write_volatile(MyDevice { addr, count });\n    ///     }\n    /// }\n    /// ```\n    /// Instead, operate on each primtive field individually:\n    /// ```no_run\n    /// struct MyDevice {\n    ///     addr: usize,\n    ///     count: usize\n    /// }\n    ///\n    /// fn start_device(device: *mut MyDevice, addr: usize, count: usize) {\n    ///     unsafe {\n    ///         (&raw mut (*device).addr).write_volatile(addr);\n    ///         (&raw mut (*device).count).write_volatile(count);\n    ///     }\n    /// }\n    /// ```\n    #[clippy::version = \"1.92.0\"]\n    pub VOLATILE_COMPOSITES,\n    nursery,\n    \"warn about volatile read/write applied to composite types\"\n}\n\ndeclare_lint_pass!(VolatileComposites => [VOLATILE_COMPOSITES]);\n\n/// Zero-sized types are intrinsically safe to use volatile on since they won't\n/// actually generate *any* loads or stores. But this is also used to skip zero-sized\n/// fields of `#[repr(transparent)]` structures.\nfn is_zero_sized_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    cx.layout_of(ty).is_ok_and(|layout| layout.is_zst())\n}\n\n/// A thin raw pointer or reference.\nfn is_narrow_ptr<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    match ty.kind() {\n        ty::RawPtr(inner, _) | ty::Ref(_, inner, _) => inner.has_trivial_sizedness(cx.tcx, ty::SizedTraitKind::Sized),\n        _ => false,\n    }\n}\n\n/// Enum with some fixed representation and no data-carrying variants.\nfn is_enum_repr_c<'tcx>(_cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    ty.ty_adt_def().is_some_and(|adt_def| {\n        adt_def.is_enum() && adt_def.repr().inhibit_struct_field_reordering() && adt_def.is_payloadfree()\n    })\n}\n\n/// `#[repr(transparent)]` structures are also OK if the only non-zero\n/// sized field contains a volatile-safe type.\nfn is_struct_repr_transparent<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    if let ty::Adt(adt_def, args) = ty.kind()\n        && adt_def.is_struct()\n        && adt_def.repr().transparent()\n        && let [fieldty] = adt_def\n            .all_fields()\n            .filter_map(|field| {\n                let fty = field.ty(cx.tcx, args);\n                if is_zero_sized_ty(cx, fty) { None } else { Some(fty) }\n            })\n            .collect::<Vec<_>>()\n            .as_slice()\n    {\n        is_volatile_safe_ty(cx, *fieldty)\n    } else {\n        false\n    }\n}\n\n/// SIMD can be useful to get larger single loads/stores, though this is still\n/// pretty machine-dependent.\nfn is_simd_repr<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    if let ty::Adt(adt_def, _args) = ty.kind()\n        && adt_def.is_struct()\n        && adt_def.repr().simd()\n    {\n        let (_size, simdty) = ty.simd_size_and_type(cx.tcx);\n        is_volatile_safe_ty(cx, simdty)\n    } else {\n        false\n    }\n}\n\n/// Top-level predicate for whether a type is volatile-safe or not.\nfn is_volatile_safe_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    ty.is_primitive()\n        || is_narrow_ptr(cx, ty)\n        || is_zero_sized_ty(cx, ty)\n        || is_enum_repr_c(cx, ty)\n        || is_simd_repr(cx, ty)\n        || is_struct_repr_transparent(cx, ty)\n        // We can't know about a generic type, so just let it pass to avoid noise\n        || ty.has_non_region_param()\n}\n\n/// Print diagnostic for volatile read/write on non-volatile-safe types.\nfn report_volatile_safe<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, ty: Ty<'tcx>) {\n    if !is_volatile_safe_ty(cx, ty) {\n        span_lint(\n            cx,\n            VOLATILE_COMPOSITES,\n            expr.span,\n            format!(\"type `{ty}` is not volatile-compatible\"),\n        );\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for VolatileComposites {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {\n        // Check our expr is calling a method with pattern matching\n        match expr.kind {\n            // Look for method calls to `write_volatile`/`read_volatile`, which\n            // apply to both raw pointers and std::ptr::NonNull.\n            ExprKind::MethodCall(name, self_arg, _, _)\n                if matches!(name.ident.name, sym::read_volatile | sym::write_volatile) =>\n            {\n                let self_ty = cx.typeck_results().expr_ty(self_arg);\n                match self_ty.kind() {\n                    // Raw pointers\n                    ty::RawPtr(innerty, _) => report_volatile_safe(cx, expr, *innerty),\n                    // std::ptr::NonNull\n                    ty::Adt(_, args) if self_ty.is_diag_item(cx, sym::NonNull) => {\n                        report_volatile_safe(cx, expr, args.type_at(0));\n                    },\n                    _ => (),\n                }\n            },\n\n            // Also plain function calls to std::ptr::{read,write}_volatile\n            ExprKind::Call(func, [arg_ptr, ..]) => {\n                if let ExprKind::Path(ref qpath) = func.kind\n                    && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id()\n                    && matches!(\n                        cx.tcx.get_diagnostic_name(def_id),\n                        Some(sym::ptr_read_volatile | sym::ptr_write_volatile)\n                    )\n                    && let ty::RawPtr(ptrty, _) = cx.typeck_results().expr_ty_adjusted(arg_ptr).kind()\n                {\n                    report_volatile_safe(cx, expr, *ptrty);\n                }\n            },\n            _ => {},\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/wildcard_imports.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::is_in_test;\nuse clippy_utils::source::{snippet, snippet_with_applicability};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Item, ItemKind, PathSegment, UseKind};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty;\nuse rustc_session::impl_lint_pass;\nuse rustc_span::BytePos;\nuse rustc_span::symbol::kw;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `use Enum::*`.\n    ///\n    /// ### Why is this bad?\n    /// It is usually better style to use the prefixed name of\n    /// an enumeration variant, rather than importing variants.\n    ///\n    /// ### Known problems\n    /// Old-style enumerations that prefix the variants are\n    /// still around.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// use std::cmp::Ordering::*;\n    ///\n    /// # fn foo(_: std::cmp::Ordering) {}\n    /// foo(Less);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// use std::cmp::Ordering;\n    ///\n    /// # fn foo(_: Ordering) {}\n    /// foo(Ordering::Less)\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ENUM_GLOB_USE,\n    pedantic,\n    \"use items that import all variants of an enum\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for wildcard imports `use _::*`.\n    ///\n    /// ### Why is this bad?\n    /// wildcard imports can pollute the namespace. This is especially bad if\n    /// you try to import something through a wildcard, that already has been imported by name from\n    /// a different source:\n    ///\n    /// ```rust,ignore\n    /// use crate1::foo; // Imports a function named foo\n    /// use crate2::*; // Has a function named foo\n    ///\n    /// foo(); // Calls crate1::foo\n    /// ```\n    ///\n    /// This can lead to confusing error messages at best and to unexpected behavior at worst.\n    ///\n    /// ### Exceptions\n    /// Wildcard imports are allowed from modules that their name contains `prelude`. Many crates\n    /// (including the standard library) provide modules named \"prelude\" specifically designed\n    /// for wildcard import.\n    ///\n    /// Wildcard imports reexported through `pub use` are also allowed.\n    ///\n    /// `use super::*` is allowed in test modules. This is defined as any module with \"test\" in the name.\n    ///\n    /// These exceptions can be disabled using the `warn-on-all-wildcard-imports` configuration flag.\n    ///\n    /// ### Known problems\n    /// If macros are imported through the wildcard, this macro is not included\n    /// by the suggestion and has to be added by hand.\n    ///\n    /// Applying the suggestion when explicit imports of the things imported with a glob import\n    /// exist, may result in `unused_imports` warnings.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// use crate1::*;\n    ///\n    /// foo();\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// use crate1::foo;\n    ///\n    /// foo();\n    /// ```\n    #[clippy::version = \"1.43.0\"]\n    pub WILDCARD_IMPORTS,\n    pedantic,\n    \"lint `use _::*` statements\"\n}\n\nimpl_lint_pass!(WildcardImports => [ENUM_GLOB_USE, WILDCARD_IMPORTS]);\n\npub struct WildcardImports {\n    warn_on_all: bool,\n    allowed_segments: FxHashSet<String>,\n}\n\nimpl WildcardImports {\n    pub fn new(conf: &'static Conf) -> Self {\n        Self {\n            warn_on_all: conf.warn_on_all_wildcard_imports,\n            allowed_segments: conf.allowed_wildcard_imports.iter().cloned().collect(),\n        }\n    }\n}\n\nimpl LateLintPass<'_> for WildcardImports {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        if cx.sess().is_test_crate() || item.span.in_external_macro(cx.sess().source_map()) {\n            return;\n        }\n\n        let module = cx.tcx.parent_module_from_def_id(item.owner_id.def_id);\n        if cx.tcx.visibility(item.owner_id.def_id) != ty::Visibility::Restricted(module.to_def_id())\n            && !self.warn_on_all\n        {\n            return;\n        }\n        if let ItemKind::Use(use_path, UseKind::Glob) = &item.kind\n            && (self.warn_on_all || !self.check_exceptions(cx, item, use_path.segments))\n            && let Some(used_imports) = cx.tcx.resolutions(()).glob_map.get(&item.owner_id.def_id)\n            && !used_imports.is_empty() // Already handled by `unused_imports`\n            && !used_imports.contains(&kw::Underscore)\n        {\n            let mut applicability = Applicability::MachineApplicable;\n            let import_source_snippet = snippet_with_applicability(cx, use_path.span, \"..\", &mut applicability);\n            let (span, braced_glob) = if import_source_snippet.is_empty() {\n                // This is a `_::{_, *}` import\n                // In this case `use_path.span` is empty and ends directly in front of the `*`,\n                // so we need to extend it by one byte.\n                (use_path.span.with_hi(use_path.span.hi() + BytePos(1)), true)\n            } else {\n                // In this case, the `use_path.span` ends right before the `::*`, so we need to\n                // extend it up to the `*`. Since it is hard to find the `*` in weird\n                // formatting like `use _ ::  *;`, we extend it up to, but not including the\n                // `;`. In nested imports, like `use _::{inner::*, _}` there is no `;` and we\n                // can just use the end of the item span\n                let mut span = use_path.span.with_hi(item.span.hi());\n                if snippet(cx, span, \"\").ends_with(';') {\n                    span = use_path.span.with_hi(item.span.hi() - BytePos(1));\n                }\n                (span, false)\n            };\n\n            let mut imports: Vec<_> = used_imports.iter().map(ToString::to_string).collect();\n            let imports_string = if imports.len() == 1 {\n                imports.pop().unwrap()\n            } else if braced_glob {\n                imports.join(\", \")\n            } else {\n                format!(\"{{{}}}\", imports.join(\", \"))\n            };\n\n            let sugg = if braced_glob {\n                imports_string\n            } else {\n                format!(\"{import_source_snippet}::{imports_string}\")\n            };\n\n            // Glob imports always have a single resolution. Enums are in the value namespace.\n            let (lint, message) = if let Some(Res::Def(DefKind::Enum, _)) = use_path.res.value_ns {\n                (ENUM_GLOB_USE, \"usage of wildcard import for enum variants\")\n            } else {\n                (WILDCARD_IMPORTS, \"usage of wildcard import\")\n            };\n\n            span_lint_and_sugg(cx, lint, span, message, \"try\", sugg, applicability);\n        }\n    }\n}\n\nimpl WildcardImports {\n    fn check_exceptions(&self, cx: &LateContext<'_>, item: &Item<'_>, segments: &[PathSegment<'_>]) -> bool {\n        item.span.from_expansion()\n            || is_prelude_import(segments)\n            || is_allowed_via_config(segments, &self.allowed_segments)\n            || (is_super_only_import(segments) && is_in_test(cx.tcx, item.hir_id()))\n    }\n}\n\n// Allow \"...prelude::..::*\" imports.\n// Many crates have a prelude, and it is imported as a glob by design.\nfn is_prelude_import(segments: &[PathSegment<'_>]) -> bool {\n    segments.iter().any(|ps| ps.ident.as_str().contains(\"prelude\"))\n}\n\n// Allow \"super::*\" imports in tests.\nfn is_super_only_import(segments: &[PathSegment<'_>]) -> bool {\n    segments.len() == 1 && segments[0].ident.name == kw::Super\n}\n\n// Allow skipping imports containing user configured segments,\n// i.e. \"...::utils::...::*\" if user put `allowed-wildcard-imports = [\"utils\"]` in `Clippy.toml`\nfn is_allowed_via_config(segments: &[PathSegment<'_>], allowed_segments: &FxHashSet<String>) -> bool {\n    // segment matching need to be exact instead of using 'contains', in case user unintentionally put\n    // a single character in the config thus skipping most of the warnings.\n    segments.iter().any(|seg| allowed_segments.contains(seg.ident.as_str()))\n}\n"
  },
  {
    "path": "clippy_lints/src/write/empty_string.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::MacroCall;\nuse clippy_utils::source::expand_past_previous_comma;\nuse clippy_utils::{span_extract_comments, sym};\nuse rustc_ast::{FormatArgs, FormatArgsPiece};\nuse rustc_errors::Applicability;\nuse rustc_lint::{LateContext, LintContext};\n\nuse super::{PRINTLN_EMPTY_STRING, WRITELN_EMPTY_STRING};\n\npub(super) fn check(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) {\n    if let [FormatArgsPiece::Literal(sym::LF)] = &format_args.template[..] {\n        let is_writeln = name == \"writeln\";\n\n        span_lint_and_then(\n            cx,\n            if is_writeln {\n                WRITELN_EMPTY_STRING\n            } else {\n                PRINTLN_EMPTY_STRING\n            },\n            macro_call.span,\n            format!(\"empty string literal in `{name}!`\"),\n            |diag| {\n                if span_extract_comments(cx, macro_call.span).is_empty() {\n                    let closing_paren = cx.sess().source_map().span_extend_to_prev_char_before(\n                        macro_call.span.shrink_to_hi(),\n                        ')',\n                        false,\n                    );\n                    let mut span = format_args.span.with_hi(closing_paren.lo());\n                    if is_writeln {\n                        span = expand_past_previous_comma(cx, span);\n                    }\n\n                    diag.span_suggestion(span, \"remove the empty string\", \"\", Applicability::MachineApplicable);\n                } else {\n                    // If there is a comment in the span of macro call, we don't provide an auto-fix suggestion.\n                    diag.span_note(format_args.span, \"remove the empty string\");\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/write/literal.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::format_arg_removal_span;\nuse clippy_utils::source::SpanRangeExt;\nuse clippy_utils::sym;\nuse rustc_ast::token::LitKind;\nuse rustc_ast::{\n    FormatArgPosition, FormatArgPositionKind, FormatArgs, FormatArgsPiece, FormatCount, FormatOptions,\n    FormatPlaceholder, FormatTrait,\n};\nuse rustc_errors::Applicability;\nuse rustc_lint::LateContext;\nuse rustc_span::Span;\n\nuse super::{PRINT_LITERAL, WRITE_LITERAL};\n\npub(super) fn check(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {\n    let arg_index = |argument: &FormatArgPosition| argument.index.unwrap_or_else(|pos| pos);\n\n    let lint_name = if name.starts_with(\"write\") {\n        WRITE_LITERAL\n    } else {\n        PRINT_LITERAL\n    };\n\n    let mut counts = vec![0u32; format_args.arguments.all_args().len()];\n    for piece in &format_args.template {\n        if let FormatArgsPiece::Placeholder(placeholder) = piece {\n            counts[arg_index(&placeholder.argument)] += 1;\n        }\n    }\n\n    let mut suggestion: Vec<(Span, String)> = vec![];\n    // holds index of replaced positional arguments; used to decrement the index of the remaining\n    // positional arguments.\n    let mut replaced_position: Vec<usize> = vec![];\n    let mut sug_span: Option<Span> = None;\n\n    for piece in &format_args.template {\n        if let FormatArgsPiece::Placeholder(FormatPlaceholder {\n            argument,\n            span: Some(placeholder_span),\n            format_trait: FormatTrait::Display,\n            format_options,\n        }) = piece\n            && *format_options == FormatOptions::default()\n            && let index = arg_index(argument)\n            && counts[index] == 1\n            && let Some(arg) = format_args.arguments.by_index(index)\n            && let rustc_ast::ExprKind::Lit(lit) = &arg.expr.kind\n            && !arg.expr.span.from_expansion()\n            && let Some(value_string) = arg.expr.span.get_source_text(cx)\n        {\n            let (replacement, replace_raw) = match lit.kind {\n                LitKind::Str | LitKind::StrRaw(_) => match extract_str_literal(&value_string) {\n                    Some(extracted) => extracted,\n                    None => return,\n                },\n                LitKind::Char => (\n                    match lit.symbol {\n                        sym::DOUBLE_QUOTE => \"\\\\\\\"\",\n                        sym::BACKSLASH_SINGLE_QUOTE => \"'\",\n                        _ => match value_string.strip_prefix('\\'').and_then(|s| s.strip_suffix('\\'')) {\n                            Some(stripped) => stripped,\n                            None => return,\n                        },\n                    }\n                    .to_string(),\n                    false,\n                ),\n                LitKind::Bool => (lit.symbol.to_string(), false),\n                _ => continue,\n            };\n\n            let Some(format_string_snippet) = format_args.span.get_source_text(cx) else {\n                continue;\n            };\n            let format_string_is_raw = format_string_snippet.starts_with('r');\n\n            let replacement = match (format_string_is_raw, replace_raw) {\n                (false, false) => Some(replacement),\n                (false, true) => Some(replacement.replace('\\\\', \"\\\\\\\\\").replace('\"', \"\\\\\\\"\")),\n                (true, false) => match conservative_unescape(&replacement) {\n                    Ok(unescaped) => Some(unescaped),\n                    Err(UnescapeErr::Lint) => None,\n                    Err(UnescapeErr::Ignore) => continue,\n                },\n                (true, true) => {\n                    if replacement.contains(['#', '\"']) {\n                        None\n                    } else {\n                        Some(replacement)\n                    }\n                },\n            };\n\n            sug_span = Some(sug_span.unwrap_or(arg.expr.span).to(arg.expr.span));\n\n            if let Some((_, index)) = format_arg_piece_span(piece) {\n                replaced_position.push(index);\n            }\n\n            if let Some(replacement) = replacement\n                // `format!(\"{}\", \"a\")`, `format!(\"{named}\", named = \"b\")\n                //              ~~~~~                      ~~~~~~~~~~~~~\n                && let Some(removal_span) = format_arg_removal_span(format_args, index)\n            {\n                let replacement = escape_braces(&replacement, !format_string_is_raw && !replace_raw);\n                suggestion.push((*placeholder_span, replacement));\n                suggestion.push((removal_span, String::new()));\n            }\n        }\n    }\n\n    // Decrement the index of the remaining by the number of replaced positional arguments\n    if !suggestion.is_empty() {\n        for piece in &format_args.template {\n            relocalize_format_args_indexes(piece, &mut suggestion, &replaced_position);\n        }\n    }\n\n    if let Some(span) = sug_span {\n        span_lint_and_then(cx, lint_name, span, \"literal with an empty format string\", |diag| {\n            if !suggestion.is_empty() {\n                diag.multipart_suggestion(\"try\", suggestion, Applicability::MachineApplicable);\n            }\n        });\n    }\n}\n\n/// Extract Span and its index from the given `piece`\nfn format_arg_piece_span(piece: &FormatArgsPiece) -> Option<(Span, usize)> {\n    match piece {\n        FormatArgsPiece::Placeholder(FormatPlaceholder {\n            argument: FormatArgPosition { index: Ok(index), .. },\n            span: Some(span),\n            ..\n        }) => Some((*span, *index)),\n        _ => None,\n    }\n}\n\n/// Relocalizes the indexes of positional arguments in the format string\nfn relocalize_format_args_indexes(\n    piece: &FormatArgsPiece,\n    suggestion: &mut Vec<(Span, String)>,\n    replaced_position: &[usize],\n) {\n    if let FormatArgsPiece::Placeholder(FormatPlaceholder {\n        argument:\n            FormatArgPosition {\n                index: Ok(index),\n                // Only consider positional arguments\n                kind: FormatArgPositionKind::Number,\n                span: Some(span),\n            },\n        format_options,\n        ..\n    }) = piece\n    {\n        if suggestion.iter().any(|(s, _)| s.overlaps(*span)) {\n            // If the span is already in the suggestion, we don't need to process it again\n            return;\n        }\n\n        // lambda to get the decremented index based on the replaced positions\n        let decremented_index = |index: usize| -> usize {\n            let decrement = replaced_position.iter().filter(|&&i| i < index).count();\n            index - decrement\n        };\n\n        suggestion.push((*span, decremented_index(*index).to_string()));\n\n        // If there are format options, we need to handle them as well\n        if *format_options != FormatOptions::default() {\n            // lambda to process width and precision format counts and add them to the suggestion\n            let mut process_format_count = |count: &Option<FormatCount>, formatter: &dyn Fn(usize) -> String| {\n                if let Some(FormatCount::Argument(FormatArgPosition {\n                    index: Ok(format_arg_index),\n                    kind: FormatArgPositionKind::Number,\n                    span: Some(format_arg_span),\n                })) = count\n                {\n                    suggestion.push((*format_arg_span, formatter(decremented_index(*format_arg_index))));\n                }\n            };\n\n            process_format_count(&format_options.width, &|index: usize| format!(\"{index}$\"));\n            process_format_count(&format_options.precision, &|index: usize| format!(\".{index}$\"));\n        }\n    }\n}\n\n/// Removes the raw marker, `#`s and quotes from a str, and returns if the literal is raw\n///\n/// `r#\"a\"#` -> (`a`, true)\n///\n/// `\"b\"` -> (`b`, false)\nfn extract_str_literal(literal: &str) -> Option<(String, bool)> {\n    let (literal, raw) = match literal.strip_prefix('r') {\n        Some(stripped) => (stripped.trim_matches('#'), true),\n        None => (literal, false),\n    };\n\n    Some((literal.strip_prefix('\"')?.strip_suffix('\"')?.to_string(), raw))\n}\n\nenum UnescapeErr {\n    /// Should still be linted, can be manually resolved by author, e.g.\n    ///\n    /// ```ignore\n    /// print!(r\"{}\", '\"');\n    /// ```\n    Lint,\n    /// Should not be linted, e.g.\n    ///\n    /// ```ignore\n    /// print!(r\"{}\", '\\r');\n    /// ```\n    Ignore,\n}\n\n/// Unescape a normal string into a raw string\nfn conservative_unescape(literal: &str) -> Result<String, UnescapeErr> {\n    let mut unescaped = String::with_capacity(literal.len());\n    let mut chars = literal.chars();\n    let mut err = false;\n\n    while let Some(ch) = chars.next() {\n        match ch {\n            '#' => err = true,\n            '\\\\' => match chars.next() {\n                Some('\\\\') => unescaped.push('\\\\'),\n                Some('\"') => err = true,\n                _ => return Err(UnescapeErr::Ignore),\n            },\n            _ => unescaped.push(ch),\n        }\n    }\n\n    if err { Err(UnescapeErr::Lint) } else { Ok(unescaped) }\n}\n\n/// Replaces `{` with `{{` and `}` with `}}`. If `preserve_unicode_escapes` is `true` the braces\n/// in `\\u{xxxx}` are left unmodified\n#[expect(clippy::match_same_arms)]\nfn escape_braces(literal: &str, preserve_unicode_escapes: bool) -> String {\n    #[derive(Clone, Copy)]\n    enum State {\n        Normal,\n        Backslash,\n        UnicodeEscape,\n    }\n\n    let mut escaped = String::with_capacity(literal.len());\n    let mut state = State::Normal;\n\n    for ch in literal.chars() {\n        state = match (ch, state) {\n            // Escape braces outside of unicode escapes by doubling them up\n            ('{' | '}', State::Normal) => {\n                escaped.push(ch);\n                State::Normal\n            },\n            // If `preserve_unicode_escapes` isn't enabled stay in `State::Normal`, otherwise:\n            //\n            // \\u{aaaa} \\\\ \\x01\n            // ^        ^  ^\n            ('\\\\', State::Normal) if preserve_unicode_escapes => State::Backslash,\n            // \\u{aaaa}\n            //  ^\n            ('u', State::Backslash) => State::UnicodeEscape,\n            // \\xAA \\\\\n            //  ^    ^\n            (_, State::Backslash) => State::Normal,\n            // \\u{aaaa}\n            //        ^\n            ('}', State::UnicodeEscape) => State::Normal,\n            _ => state,\n        };\n\n        escaped.push(ch);\n    }\n\n    escaped\n}\n"
  },
  {
    "path": "clippy_lints/src/write/mod.rs",
    "content": "use clippy_config::Conf;\nuse clippy_utils::diagnostics::span_lint;\nuse clippy_utils::macros::{FormatArgsStorage, root_macro_call_first_node};\nuse clippy_utils::{is_in_test, sym};\nuse rustc_hir::{Expr, Impl, Item, ItemKind, OwnerId};\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_session::impl_lint_pass;\n\nmod empty_string;\nmod literal;\nmod use_debug;\nmod with_newline;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns about the use of literals as `print!`/`println!` args.\n    ///\n    /// ### Why is this bad?\n    /// Using literals as `println!` args is inefficient\n    /// (c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary\n    /// (i.e., just put the literal in the format string)\n    ///\n    /// ### Example\n    /// ```no_run\n    /// println!(\"{}\", \"foo\");\n    /// ```\n    /// use the literal without formatting:\n    /// ```no_run\n    /// println!(\"foo\");\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PRINT_LITERAL,\n    style,\n    \"printing a literal with a format string\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for printing on *stderr*. The purpose of this lint\n    /// is to catch debugging remnants.\n    ///\n    /// ### Why restrict this?\n    /// People often print on *stderr* while debugging an\n    /// application and might forget to remove those prints afterward.\n    ///\n    /// ### Known problems\n    /// Only catches `eprint!` and `eprintln!` calls.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// eprintln!(\"Hello world!\");\n    /// ```\n    #[clippy::version = \"1.50.0\"]\n    pub PRINT_STDERR,\n    restriction,\n    \"printing on stderr\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for printing on *stdout*. The purpose of this lint\n    /// is to catch debugging remnants.\n    ///\n    /// ### Why restrict this?\n    /// People often print on *stdout* while debugging an\n    /// application and might forget to remove those prints afterward.\n    ///\n    /// ### Known problems\n    /// Only catches `print!` and `println!` calls.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// println!(\"Hello world!\");\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PRINT_STDOUT,\n    restriction,\n    \"printing on stdout\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns when you use `print!()` with a format\n    /// string that ends in a newline.\n    ///\n    /// ### Why is this bad?\n    /// You should use `println!()` instead, which appends the\n    /// newline.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let name = \"World\";\n    /// print!(\"Hello {}!\\n\", name);\n    /// ```\n    /// use println!() instead\n    /// ```no_run\n    /// # let name = \"World\";\n    /// println!(\"Hello {}!\", name);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PRINT_WITH_NEWLINE,\n    style,\n    \"using `print!()` with a format string that ends in a single newline\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns when you use `println!(\"\")` to\n    /// print a newline.\n    ///\n    /// ### Why is this bad?\n    /// You should use `println!()`, which is simpler.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// println!(\"\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// println!();\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub PRINTLN_EMPTY_STRING,\n    style,\n    \"using `println!(\\\"\\\")` with an empty string\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for usage of `Debug` formatting. The purpose of this\n    /// lint is to catch debugging remnants.\n    ///\n    /// ### Why restrict this?\n    /// The purpose of the `Debug` trait is to facilitate debugging Rust code,\n    /// and [no guarantees are made about its output][stability].\n    /// It should not be used in user-facing output.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # let foo = \"bar\";\n    /// println!(\"{:?}\", foo);\n    /// ```\n    ///\n    /// [stability]: https://doc.rust-lang.org/stable/std/fmt/trait.Debug.html#stability\n    #[clippy::version = \"pre 1.29.0\"]\n    pub USE_DEBUG,\n    restriction,\n    \"use of `Debug`-based formatting\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns about the use of literals as `write!`/`writeln!` args.\n    ///\n    /// ### Why is this bad?\n    /// Using literals as `writeln!` args is inefficient\n    /// (c.f., https://github.com/matthiaskrgr/rust-str-bench) and unnecessary\n    /// (i.e., just put the literal in the format string)\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::fmt::Write;\n    /// # let mut buf = String::new();\n    /// writeln!(buf, \"{}\", \"foo\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::fmt::Write;\n    /// # let mut buf = String::new();\n    /// writeln!(buf, \"foo\");\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub WRITE_LITERAL,\n    style,\n    \"writing a literal with a format string\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns when you use `write!()` with a format\n    /// string that\n    /// ends in a newline.\n    ///\n    /// ### Why is this bad?\n    /// You should use `writeln!()` instead, which appends the\n    /// newline.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::fmt::Write;\n    /// # let mut buf = String::new();\n    /// # let name = \"World\";\n    /// write!(buf, \"Hello {}!\\n\", name);\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::fmt::Write;\n    /// # let mut buf = String::new();\n    /// # let name = \"World\";\n    /// writeln!(buf, \"Hello {}!\", name);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub WRITE_WITH_NEWLINE,\n    style,\n    \"using `write!()` with a format string that ends in a single newline\"\n}\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// This lint warns when you use `writeln!(buf, \"\")` to\n    /// print a newline.\n    ///\n    /// ### Why is this bad?\n    /// You should use `writeln!(buf)`, which is simpler.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::fmt::Write;\n    /// # let mut buf = String::new();\n    /// writeln!(buf, \"\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// # use std::fmt::Write;\n    /// # let mut buf = String::new();\n    /// writeln!(buf);\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub WRITELN_EMPTY_STRING,\n    style,\n    \"using `writeln!(buf, \\\"\\\")` with an empty string\"\n}\n\nimpl_lint_pass!(Write => [\n    PRINTLN_EMPTY_STRING,\n    PRINT_LITERAL,\n    PRINT_STDERR,\n    PRINT_STDOUT,\n    PRINT_WITH_NEWLINE,\n    USE_DEBUG,\n    WRITELN_EMPTY_STRING,\n    WRITE_LITERAL,\n    WRITE_WITH_NEWLINE,\n]);\n\npub struct Write {\n    format_args: FormatArgsStorage,\n    // The outermost `impl Debug` we're currently in. While we're in one, `USE_DEBUG` is deactivated\n    outermost_debug_impl: Option<OwnerId>,\n    allow_print_in_tests: bool,\n}\n\nimpl Write {\n    pub fn new(conf: &'static Conf, format_args: FormatArgsStorage) -> Self {\n        Self {\n            format_args,\n            outermost_debug_impl: None,\n            allow_print_in_tests: conf.allow_print_in_tests,\n        }\n    }\n\n    fn in_debug_impl(&self) -> bool {\n        self.outermost_debug_impl.is_some()\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Write {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {\n        // Only check for `impl Debug`s if we're not already in one\n        if self.outermost_debug_impl.is_none() && is_debug_impl(cx, item) {\n            self.outermost_debug_impl = Some(item.owner_id);\n        }\n    }\n\n    fn check_item_post(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) {\n        // Only clear `self.outermost_debug_impl` if we're escaping the _outermost_ debug impl\n        if self.outermost_debug_impl == Some(item.owner_id) {\n            self.outermost_debug_impl = None;\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {\n            return;\n        };\n        let Some(diag_name) = cx.tcx.get_diagnostic_name(macro_call.def_id) else {\n            return;\n        };\n        let Some(name) = diag_name.as_str().strip_suffix(\"_macro\") else {\n            return;\n        };\n\n        let is_build_script = cx\n            .sess()\n            .opts\n            .crate_name\n            .as_ref()\n            .is_some_and(|crate_name| crate_name == \"build_script_build\");\n\n        let allowed_in_tests = self.allow_print_in_tests && is_in_test(cx.tcx, expr.hir_id);\n        match diag_name {\n            sym::print_macro | sym::println_macro if !allowed_in_tests => {\n                if !is_build_script {\n                    span_lint(cx, PRINT_STDOUT, macro_call.span, format!(\"use of `{name}!`\"));\n                }\n            },\n            sym::eprint_macro | sym::eprintln_macro if !allowed_in_tests => {\n                span_lint(cx, PRINT_STDERR, macro_call.span, format!(\"use of `{name}!`\"));\n            },\n            sym::write_macro | sym::writeln_macro => {},\n            _ => return,\n        }\n\n        if let Some(format_args) = self.format_args.get(cx, expr, macro_call.expn) {\n            // ignore `writeln!(w)` and `write!(v, some_macro!())`\n            if format_args.span.from_expansion() {\n                return;\n            }\n\n            match diag_name {\n                sym::print_macro | sym::eprint_macro | sym::write_macro => {\n                    with_newline::check(cx, format_args, &macro_call, name);\n                },\n                sym::println_macro | sym::eprintln_macro | sym::writeln_macro => {\n                    empty_string::check(cx, format_args, &macro_call, name);\n                },\n                _ => {},\n            }\n\n            literal::check(cx, format_args, name);\n\n            if !self.in_debug_impl() {\n                use_debug::check(cx, format_args);\n            }\n        }\n    }\n}\n\nfn is_debug_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool {\n    if let ItemKind::Impl(Impl {\n        of_trait: Some(of_trait),\n        ..\n    }) = &item.kind\n        && let Some(trait_id) = of_trait.trait_ref.trait_def_id()\n    {\n        cx.tcx.is_diagnostic_item(sym::Debug, trait_id)\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/write/use_debug.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse rustc_ast::{FormatArgs, FormatArgsPiece, FormatPlaceholder, FormatTrait};\nuse rustc_lint::LateContext;\n\nuse super::USE_DEBUG;\n\npub(super) fn check(cx: &LateContext<'_>, format_args: &FormatArgs) {\n    for piece in &format_args.template {\n        if let &FormatArgsPiece::Placeholder(FormatPlaceholder {\n            span: Some(span),\n            format_trait: FormatTrait::Debug,\n            ..\n        }) = piece\n        {\n            span_lint(cx, USE_DEBUG, span, \"use of `Debug`-based formatting\");\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/write/with_newline.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::macros::MacroCall;\nuse clippy_utils::source::{SpanRangeExt, expand_past_previous_comma};\nuse clippy_utils::sym;\nuse rustc_ast::{FormatArgs, FormatArgsPiece};\nuse rustc_errors::Applicability;\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_span::BytePos;\n\nuse super::{PRINT_WITH_NEWLINE, WRITE_WITH_NEWLINE};\n\npub(super) fn check(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) {\n    let Some(&FormatArgsPiece::Literal(last)) = format_args.template.last() else {\n        return;\n    };\n\n    let count_vertical_whitespace = || {\n        format_args\n            .template\n            .iter()\n            .filter_map(|piece| match piece {\n                FormatArgsPiece::Literal(literal) => Some(literal),\n                FormatArgsPiece::Placeholder(_) => None,\n            })\n            .flat_map(|literal| literal.as_str().chars())\n            .filter(|ch| matches!(ch, '\\r' | '\\n'))\n            .count()\n    };\n\n    if last.as_str().ends_with('\\n')\n        // ignore format strings with other internal vertical whitespace\n        && count_vertical_whitespace() == 1\n    {\n        let mut format_string_span = format_args.span;\n\n        let lint = if name == \"write\" {\n            format_string_span = expand_past_previous_comma(cx, format_string_span);\n\n            WRITE_WITH_NEWLINE\n        } else {\n            PRINT_WITH_NEWLINE\n        };\n\n        span_lint_and_then(\n            cx,\n            lint,\n            macro_call.span,\n            format!(\"using `{name}!()` with a format string that ends in a single newline\"),\n            |diag| {\n                let name_span = cx.sess().source_map().span_until_char(macro_call.span, '!');\n                let Some(format_snippet) = format_string_span.get_source_text(cx) else {\n                    return;\n                };\n\n                if format_args.template.len() == 1 && last == sym::LF {\n                    // print!(\"\\n\"), write!(f, \"\\n\")\n\n                    diag.multipart_suggestion(\n                        format!(\"use `{name}ln!` instead\"),\n                        vec![(name_span, format!(\"{name}ln\")), (format_string_span, String::new())],\n                        Applicability::MachineApplicable,\n                    );\n                } else if format_snippet.ends_with(\"\\\\n\\\"\") {\n                    // print!(\"...\\n\"), write!(f, \"...\\n\")\n\n                    let hi = format_string_span.hi();\n                    let newline_span = format_string_span.with_lo(hi - BytePos(3)).with_hi(hi - BytePos(1));\n\n                    diag.multipart_suggestion(\n                        format!(\"use `{name}ln!` instead\"),\n                        vec![(name_span, format!(\"{name}ln\")), (newline_span, String::new())],\n                        Applicability::MachineApplicable,\n                    );\n                }\n            },\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/zero_div_zero.rs",
    "content": "use clippy_utils::consts::{ConstEvalCtxt, Constant};\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse rustc_hir::{BinOpKind, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::declare_lint_pass;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for `0.0 / 0.0`.\n    ///\n    /// ### Why is this bad?\n    /// It's less readable than `f32::NAN` or `f64::NAN`.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// let nan = 0.0f32 / 0.0;\n    /// ```\n    ///\n    /// Use instead:\n    /// ```no_run\n    /// let nan = f32::NAN;\n    /// ```\n    #[clippy::version = \"pre 1.29.0\"]\n    pub ZERO_DIVIDED_BY_ZERO,\n    complexity,\n    \"usage of `0.0 / 0.0` to obtain NaN instead of `f32::NAN` or `f64::NAN`\"\n}\n\ndeclare_lint_pass!(ZeroDiv => [ZERO_DIVIDED_BY_ZERO]);\n\nimpl<'tcx> LateLintPass<'tcx> for ZeroDiv {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        // check for instances of 0.0/0.0\n        if let ExprKind::Binary(ref op, left, right) = expr.kind\n            && op.node == BinOpKind::Div\n            // TODO - constant_simple does not fold many operations involving floats.\n            // That's probably fine for this lint - it's pretty unlikely that someone would\n            // do something like 0.0/(2.0 - 2.0), but it would be nice to warn on that case too.\n            && let ecx = ConstEvalCtxt::new(cx)\n            && let ctxt = expr.span.ctxt()\n            && let Some(lhs_value) = ecx.eval_local(left, ctxt)\n            && let Some(rhs_value) = ecx.eval_local(right, ctxt)\n            // FIXME(f16_f128): add these types when eq is available on all platforms\n            && (Constant::F32(0.0) == lhs_value || Constant::F64(0.0) == lhs_value)\n            && (Constant::F32(0.0) == rhs_value || Constant::F64(0.0) == rhs_value)\n        {\n            // since we're about to suggest a use of f32::NAN or f64::NAN,\n            // match the precision of the literals that are given.\n            let float_type = match (lhs_value, rhs_value) {\n                (Constant::F64(_), _) | (_, Constant::F64(_)) => \"f64\",\n                _ => \"f32\",\n            };\n            span_lint_and_help(\n                cx,\n                ZERO_DIVIDED_BY_ZERO,\n                expr.span,\n                \"constant division of `0.0` with `0.0` will always result in NaN\",\n                None,\n                format!(\"consider using `{float_type}::NAN` if you would like a constant representing NaN\"),\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/zero_repeat_side_effects.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::higher::VecArgs;\nuse clippy_utils::source::{snippet, snippet_indent};\nuse rustc_ast::LitKind;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_errors::Applicability;\nuse rustc_hir::{ConstArgKind, Expr, ExprKind, LetStmt, LocalSource, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::{IsSuggestable, Ty};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for array or vec initializations which contain an expression with side effects,\n    /// but which have a repeat count of zero.\n    ///\n    /// ### Why is this bad?\n    /// Such an initialization, despite having a repeat length of 0, will still call the inner function.\n    /// This may not be obvious and as such there may be unintended side effects in code.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// fn side_effect() -> i32 {\n    ///     println!(\"side effect\");\n    ///     10\n    /// }\n    /// let a = [side_effect(); 0];\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// fn side_effect() -> i32 {\n    ///     println!(\"side effect\");\n    ///     10\n    /// }\n    /// side_effect();\n    /// let a: [i32; 0] = [];\n    /// ```\n    #[clippy::version = \"1.79.0\"]\n    pub ZERO_REPEAT_SIDE_EFFECTS,\n    suspicious,\n    \"usage of zero-sized initializations of arrays or vecs causing side effects\"\n}\n\ndeclare_lint_pass!(ZeroRepeatSideEffects => [ZERO_REPEAT_SIDE_EFFECTS]);\n\nimpl LateLintPass<'_> for ZeroRepeatSideEffects {\n    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {\n        if let Some(args) = VecArgs::hir(cx, expr)\n            && let VecArgs::Repeat(inner_expr, len) = args\n            && let ExprKind::Lit(l) = len.kind\n            && let LitKind::Int(Pu128(0), _) = l.node\n        {\n            inner_check(cx, expr, inner_expr, true);\n        }\n        // Lint only if the length is a literal zero, and not a path to any constants.\n        // NOTE(@y21): When reading `[f(); LEN]`, I intuitively expect that the function is called and it\n        // doesn't seem as confusing as `[f(); 0]`. It would also have false positives when eg.\n        // the const item depends on `#[cfg]s` and has different values in different compilation\n        // sessions).\n        else if let ExprKind::Repeat(inner_expr, const_arg) = expr.kind\n            && let ConstArgKind::Anon(anon_const) = const_arg.kind\n            && let length_expr = cx.tcx.hir_body(anon_const.body).value\n            && !length_expr.span.from_expansion()\n            && let ExprKind::Lit(literal) = length_expr.kind\n            && let LitKind::Int(Pu128(0), _) = literal.node\n        {\n            inner_check(cx, expr, inner_expr, false);\n        }\n    }\n}\n\nfn inner_check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, inner_expr: &'_ Expr<'_>, is_vec: bool) {\n    // check if expr is a call or has a call inside it\n    if inner_expr.can_have_side_effects() {\n        let parent_hir_node = cx.tcx.parent_hir_node(expr.hir_id);\n        let inner_expr_ty = cx.typeck_results().expr_ty(inner_expr);\n        let return_type = cx.typeck_results().expr_ty(expr);\n\n        let inner_expr = snippet(cx, inner_expr.span.source_callsite(), \"..\");\n        let indent = snippet_indent(cx, expr.span).unwrap_or_default();\n        let vec = if is_vec { \"vec!\" } else { \"\" };\n\n        let (span, sugg) = match parent_hir_node {\n            Node::LetStmt(l)\n                if matches!(l.source, LocalSource::AssignDesugar)\n                    && let mut parent_iter = cx.tcx.hir_parent_iter(l.hir_id)\n                    && let Some((_, Node::Stmt(_))) = parent_iter.next()\n                    && let Some((_, Node::Block(_))) = parent_iter.next()\n                    && let Some((_, Node::Expr(x))) = parent_iter.next() =>\n            {\n                (\n                    x.span,\n                    assign_expr_suggestion(cx, x, l.pat.span, &inner_expr, return_type, vec),\n                )\n            },\n            Node::LetStmt(l) => (l.span, let_stmt_suggestion(cx, l, &inner_expr, return_type, vec)),\n            Node::Expr(x) if let ExprKind::Assign(l, _, _) = x.kind => (\n                x.span,\n                assign_expr_suggestion(cx, x, l.span, &inner_expr, return_type, vec),\n            ),\n            // NOTE: don't use the stmt span to avoid touching the trailing semicolon\n            Node::Stmt(_) => (expr.span, format!(\"{inner_expr};\\n{indent}{vec}[] as {return_type}\")),\n            _ => (\n                expr.span,\n                format!(\n                    \"\\\n{{\n{indent}    {inner_expr};\n{indent}    {vec}[] as {return_type}\n{indent}}}\"\n                ),\n            ),\n        };\n        let span = span.source_callsite();\n        span_lint_and_then(\n            cx,\n            ZERO_REPEAT_SIDE_EFFECTS,\n            span,\n            \"expression with side effects as the initial value in a zero-sized array initializer\",\n            |diag| {\n                if (!inner_expr_ty.is_never() || cx.tcx.features().never_type())\n                    && return_type.is_suggestable(cx.tcx, true)\n                {\n                    diag.span_suggestion_verbose(\n                        span,\n                        \"consider performing the side effect separately\",\n                        sugg,\n                        Applicability::Unspecified,\n                    );\n                } else {\n                    diag.help(\"consider performing the side effect separately\");\n                }\n            },\n        );\n    }\n}\n\nfn let_stmt_suggestion(\n    cx: &LateContext<'_>,\n    let_stmt: &LetStmt<'_>,\n    inner_expr: &str,\n    return_type: Ty<'_>,\n    vec_str: &str,\n) -> String {\n    let indent = snippet_indent(cx, let_stmt.span).unwrap_or_default();\n    format!(\n        \"{inner_expr};\\n{}let {var_name}: {return_type} = {vec_str}[];\",\n        indent,\n        var_name = snippet(cx, let_stmt.pat.span.source_callsite(), \"..\")\n    )\n}\n\nfn assign_expr_suggestion(\n    cx: &LateContext<'_>,\n    outer_expr: &Expr<'_>,\n    assign_expr_span: Span,\n    inner_expr: &str,\n    return_type: Ty<'_>,\n    vec_str: &str,\n) -> String {\n    let mut parent_hir_node = cx.tcx.parent_hir_node(outer_expr.hir_id);\n    if let Node::Stmt(stmt) = parent_hir_node {\n        parent_hir_node = cx.tcx.parent_hir_node(stmt.hir_id);\n    }\n    let needs_curly = !matches!(parent_hir_node, Node::Block(_));\n\n    let indent = snippet_indent(cx, outer_expr.span).unwrap_or_default();\n    let var_name = snippet(cx, assign_expr_span.source_callsite(), \"..\");\n    if needs_curly {\n        format!(\"{{\\n    {indent}{inner_expr};\\n    {indent}{var_name} = {vec_str}[] as {return_type}\\n{indent}}}\")\n    } else {\n        format!(\"{inner_expr};\\n{indent}{var_name} = {vec_str}[] as {return_type}\")\n    }\n}\n"
  },
  {
    "path": "clippy_lints/src/zero_sized_map_values.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::ty::ty_from_hir_ty;\nuse rustc_hir::{self as hir, AmbigArg, HirId, ItemKind, Node};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::layout::LayoutOf as _;\nuse rustc_middle::ty::{self, TypeVisitableExt};\nuse rustc_session::declare_lint_pass;\nuse rustc_span::sym;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Checks for maps with zero-sized value types anywhere in the code.\n    ///\n    /// ### Why is this bad?\n    /// Since there is only a single value for a zero-sized type, a map\n    /// containing zero sized values is effectively a set. Using a set in that case improves\n    /// readability and communicates intent more clearly.\n    ///\n    /// ### Known problems\n    /// * A zero-sized type cannot be recovered later if it contains private fields.\n    /// * This lints the signature of public items\n    ///\n    /// ### Example\n    /// ```no_run\n    /// # use std::collections::HashMap;\n    /// fn unique_words(text: &str) -> HashMap<&str, ()> {\n    ///     todo!();\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// # use std::collections::HashSet;\n    /// fn unique_words(text: &str) -> HashSet<&str> {\n    ///     todo!();\n    /// }\n    /// ```\n    #[clippy::version = \"1.50.0\"]\n    pub ZERO_SIZED_MAP_VALUES,\n    pedantic,\n    \"usage of map with zero-sized value type\"\n}\n\ndeclare_lint_pass!(ZeroSizedMapValues => [ZERO_SIZED_MAP_VALUES]);\n\nimpl LateLintPass<'_> for ZeroSizedMapValues {\n    fn check_ty<'tcx>(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx, AmbigArg>) {\n        if !hir_ty.span.from_expansion()\n            && !in_trait_impl(cx, hir_ty.hir_id)\n            // We don't care about infer vars\n            && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty())\n            && matches!(ty.opt_diag_name(cx), Some(sym::HashMap | sym::BTreeMap))\n            && let ty::Adt(_, args) = ty.kind()\n            && let ty = args.type_at(1)\n            // Ensure that no type information is missing, to avoid a delayed bug in the compiler if this is not the case.\n            // This might happen when computing a reference/pointer metadata on a type for which we\n            // cannot check if it is `Sized` or not, such as an incomplete associated type in a\n            // type alias. See an example in `issue14822()` of `tests/ui/zero_sized_hashmap_values.rs`.\n            && !ty.has_non_region_param()\n            // Ensure that no region escapes to avoid an assertion error when computing the layout.\n            // See an example in `issue15429()` of `tests/ui/zero_sized_hashmap_values.rs`.\n            && !ty.has_escaping_bound_vars()\n            && let Ok(layout) = cx.layout_of(ty)\n            && layout.is_zst()\n        {\n            span_lint_and_help(\n                cx,\n                ZERO_SIZED_MAP_VALUES,\n                hir_ty.span,\n                \"map with zero-sized value type\",\n                None,\n                \"consider using a set instead\",\n            );\n        }\n    }\n}\n\nfn in_trait_impl(cx: &LateContext<'_>, hir_id: HirId) -> bool {\n    let parent_id = cx.tcx.hir_get_parent_item(hir_id);\n    let second_parent_id = cx.tcx.hir_get_parent_item(parent_id.into()).def_id;\n    if let Node::Item(item) = cx.tcx.hir_node_by_def_id(second_parent_id)\n        && let ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = item.kind\n    {\n        return true;\n    }\n    false\n}\n"
  },
  {
    "path": "clippy_lints/src/zombie_processes.rs",
    "content": "use ControlFlow::{Break, Continue};\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeResPath};\nuse clippy_utils::{fn_def_id, get_enclosing_block, sym};\nuse rustc_ast::Mutability;\nuse rustc_ast::visit::visit_opt;\nuse rustc_errors::Applicability;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::{Visitor, walk_block, walk_expr};\nuse rustc_hir::{Expr, ExprKind, HirId, LetStmt, Node, PatKind, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_session::declare_lint_pass;\nuse rustc_span::Span;\nuse std::ops::ControlFlow;\n\ndeclare_clippy_lint! {\n    /// ### What it does\n    /// Looks for code that spawns a process but never calls `wait()` on the child.\n    ///\n    /// ### Why is this bad?\n    /// As explained in the [standard library documentation](https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning),\n    /// calling `wait()` is necessary on Unix platforms to properly release all OS resources associated with the process.\n    /// Not doing so will effectively leak process IDs and/or other limited global resources,\n    /// which can eventually lead to resource exhaustion, so it's recommended to call `wait()` in long-running applications.\n    /// Such processes are called \"zombie processes\".\n    ///\n    /// To reduce the rate of false positives, if the spawned process is assigned to a binding, the lint actually works the other way around; it\n    /// conservatively checks that all uses of a variable definitely don't call `wait()` and only then emits a warning.\n    /// For that reason, a seemingly unrelated use can get called out as calling `wait()` in help messages.\n    ///\n    /// ### Control flow\n    /// If a `wait()` call exists in an if/then block but not in the else block (or there is no else block),\n    /// then this still gets linted as not calling `wait()` in all code paths.\n    /// Likewise, when early-returning from the function, `wait()` calls that appear after the return expression\n    /// are also not accepted.\n    /// In other words, the `wait()` call must be unconditionally reachable after the spawn expression.\n    ///\n    /// ### Example\n    /// ```rust\n    /// use std::process::Command;\n    ///\n    /// let _child = Command::new(\"ls\").spawn().expect(\"failed to execute child\");\n    /// ```\n    /// Use instead:\n    /// ```rust\n    /// use std::process::Command;\n    ///\n    /// let mut child = Command::new(\"ls\").spawn().expect(\"failed to execute child\");\n    /// child.wait().expect(\"failed to wait on child\");\n    /// ```\n    #[clippy::version = \"1.83.0\"]\n    pub ZOMBIE_PROCESSES,\n    suspicious,\n    \"not waiting on a spawned child process\"\n}\n\ndeclare_lint_pass!(ZombieProcesses => [ZOMBIE_PROCESSES]);\n\nimpl<'tcx> LateLintPass<'tcx> for ZombieProcesses {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {\n        if let ExprKind::Call(..) | ExprKind::MethodCall(..) = expr.kind\n            && let child_ty = cx.typeck_results().expr_ty(expr)\n            && child_ty.is_diag_item(cx, sym::Child)\n        {\n            match cx.tcx.parent_hir_node(expr.hir_id) {\n                Node::LetStmt(local)\n                    if let PatKind::Binding(_, local_id, ..) = local.pat.kind\n                        && let Some(enclosing_block) = get_enclosing_block(cx, expr.hir_id) =>\n                {\n                    let mut vis = WaitFinder {\n                        cx,\n                        local_id,\n                        create_id: expr.hir_id,\n                        body_id: cx.tcx.hir_enclosing_body_owner(expr.hir_id),\n                        state: VisitorState::WalkUpToCreate,\n                        early_return: None,\n                        missing_wait_branch: None,\n                    };\n\n                    let res = (\n                        walk_block(&mut vis, enclosing_block),\n                        vis.missing_wait_branch,\n                        vis.early_return,\n                    );\n\n                    let cause = match res {\n                        (Break(MaybeWait(wait_span)), _, Some(return_span)) => {\n                            Cause::EarlyReturn { wait_span, return_span }\n                        },\n                        (Break(MaybeWait(_)), _, None) => return,\n                        (Continue(()), None, _) => Cause::NeverWait,\n                        (Continue(()), Some(MissingWaitBranch::MissingElse { if_span, wait_span }), _) => {\n                            Cause::MissingElse { wait_span, if_span }\n                        },\n                        (Continue(()), Some(MissingWaitBranch::MissingWaitInBranch { branch_span, wait_span }), _) => {\n                            Cause::MissingWaitInBranch { wait_span, branch_span }\n                        },\n                    };\n\n                    // Don't emit a suggestion since the binding is used later\n                    check(cx, expr, cause, false);\n                },\n                Node::LetStmt(&LetStmt { pat, .. }) if let PatKind::Wild = pat.kind => {\n                    // `let _ = child;`, also dropped immediately without `wait()`ing\n                    check(cx, expr, Cause::NeverWait, true);\n                },\n                Node::Stmt(&Stmt {\n                    kind: StmtKind::Semi(_),\n                    ..\n                }) => {\n                    // Immediately dropped. E.g. `std::process::Command::new(\"echo\").spawn().unwrap();`\n                    check(cx, expr, Cause::NeverWait, true);\n                },\n                _ => {},\n            }\n        }\n    }\n}\n\nstruct MaybeWait(Span);\n\n/// A visitor responsible for finding a `wait()` call on a local variable.\n///\n/// Note that this visitor does NOT explicitly look for `wait()` calls directly, but rather does the\n/// inverse -- checking if all uses of the local are either:\n/// - a field access (`child.{stderr,stdin,stdout}`)\n/// - calling `id` or `kill`\n/// - no use at all (e.g. `let _x = child;`)\n/// - taking a shared reference (`&`), `wait()` can't go through that\n///\n/// None of these are sufficient to prevent zombie processes.\n/// Doing it like this means more FNs, but FNs are better than FPs.\nstruct WaitFinder<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    local_id: HirId,\n    create_id: HirId,\n    body_id: LocalDefId,\n    state: VisitorState,\n    early_return: Option<Span>,\n    // When joining two if branches where one of them doesn't call `wait()`, stores its span for more targeted help\n    // messages\n    missing_wait_branch: Option<MissingWaitBranch>,\n}\n\n#[derive(PartialEq)]\nenum VisitorState {\n    WalkUpToCreate,\n    CreateFound,\n}\n\n#[derive(Copy, Clone)]\nenum MissingWaitBranch {\n    MissingElse { if_span: Span, wait_span: Span },\n    MissingWaitInBranch { branch_span: Span, wait_span: Span },\n}\n\nimpl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {\n    type NestedFilter = nested_filter::OnlyBodies;\n    type Result = ControlFlow<MaybeWait>;\n\n    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> Self::Result {\n        if ex.hir_id == self.create_id {\n            self.state = VisitorState::CreateFound;\n            return Continue(());\n        }\n\n        if self.state != VisitorState::CreateFound {\n            return walk_expr(self, ex);\n        }\n\n        if ex.res_local_id() == Some(self.local_id) {\n            match self.cx.tcx.parent_hir_node(ex.hir_id) {\n                Node::Stmt(Stmt {\n                    kind: StmtKind::Semi(_),\n                    ..\n                }) => {},\n                Node::Expr(expr) if let ExprKind::Field(..) = expr.kind => {},\n                Node::Expr(expr) if let ExprKind::AddrOf(_, Mutability::Not, _) = expr.kind => {},\n                Node::Expr(expr)\n                    if let Some(fn_did) = fn_def_id(self.cx, expr)\n                        && let Some(fn_name) = self.cx.tcx.get_diagnostic_name(fn_did)\n                        && matches!(fn_name, sym::child_id | sym::child_kill) => {},\n\n                // Conservatively assume that all other kinds of nodes call `.wait()` somehow.\n                _ => return Break(MaybeWait(ex.span)),\n            }\n        } else {\n            match ex.kind {\n                ExprKind::Ret(e) if self.cx.tcx.hir_enclosing_body_owner(ex.hir_id) == self.body_id => {\n                    visit_opt!(self, visit_expr, e);\n                    if self.early_return.is_none() {\n                        self.early_return = Some(ex.span);\n                    }\n\n                    return Continue(());\n                },\n                ExprKind::If(cond, then, None) => {\n                    walk_expr(self, cond)?;\n\n                    if let Break(MaybeWait(wait_span)) = walk_expr(self, then)\n                        && self.missing_wait_branch.is_none()\n                    {\n                        self.missing_wait_branch = Some(MissingWaitBranch::MissingElse {\n                            if_span: ex.span,\n                            wait_span,\n                        });\n                    }\n\n                    return Continue(());\n                },\n\n                ExprKind::If(cond, then, Some(else_)) => {\n                    walk_expr(self, cond)?;\n\n                    match (walk_expr(self, then), walk_expr(self, else_)) {\n                        (Continue(()), Continue(())) => {},\n\n                        // `wait()` in one branch but nothing in the other does not count\n                        (Continue(()), Break(MaybeWait(wait_span))) => {\n                            if self.missing_wait_branch.is_none() {\n                                self.missing_wait_branch = Some(MissingWaitBranch::MissingWaitInBranch {\n                                    branch_span: ex.span.shrink_to_lo().to(then.span),\n                                    wait_span,\n                                });\n                            }\n                        },\n                        (Break(MaybeWait(wait_span)), Continue(())) => {\n                            if self.missing_wait_branch.is_none() {\n                                self.missing_wait_branch = Some(MissingWaitBranch::MissingWaitInBranch {\n                                    branch_span: then.span.shrink_to_hi().to(else_.span),\n                                    wait_span,\n                                });\n                            }\n                        },\n\n                        // `wait()` in both branches is ok\n                        (Break(MaybeWait(wait_span)), Break(MaybeWait(_))) => {\n                            self.missing_wait_branch = None;\n                            return Break(MaybeWait(wait_span));\n                        },\n                    }\n\n                    return Continue(());\n                },\n                _ => {},\n            }\n        }\n\n        walk_expr(self, ex)\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\n#[derive(Copy, Clone)]\nenum Cause {\n    /// No call to `wait()` at all\n    NeverWait,\n    /// `wait()` call exists, but not all code paths definitely lead to one due to\n    /// an early return\n    EarlyReturn { wait_span: Span, return_span: Span },\n    /// `wait()` call exists in some if branches but not this one\n    MissingWaitInBranch { wait_span: Span, branch_span: Span },\n    /// `wait()` call exists in an if/then branch but it is missing an else block\n    MissingElse { wait_span: Span, if_span: Span },\n}\n\nimpl Cause {\n    fn message(self) -> &'static str {\n        match self {\n            Cause::NeverWait => \"spawned process is never `wait()`ed on\",\n            Cause::EarlyReturn { .. } | Cause::MissingWaitInBranch { .. } | Cause::MissingElse { .. } => {\n                \"spawned process is not `wait()`ed on in all code paths\"\n            },\n        }\n    }\n\n    fn fallback_help(self) -> &'static str {\n        match self {\n            Cause::NeverWait => \"consider calling `.wait()`\",\n            Cause::EarlyReturn { .. } | Cause::MissingWaitInBranch { .. } | Cause::MissingElse { .. } => {\n                \"consider calling `.wait()` in all code paths\"\n            },\n        }\n    }\n}\n\n/// This function has shared logic between the different kinds of nodes that can trigger the lint.\n///\n/// In particular, `let <binding> = <expr that spawns child>;` requires some custom additional logic\n/// such as checking that the binding is not used in certain ways, which isn't necessary for\n/// `let _ = <expr that spawns child>;`.\n///\n/// This checks if the program doesn't unconditionally exit after the spawn expression.\nfn check<'tcx>(cx: &LateContext<'tcx>, spawn_expr: &'tcx Expr<'tcx>, cause: Cause, emit_suggestion: bool) {\n    let Some(block) = get_enclosing_block(cx, spawn_expr.hir_id) else {\n        return;\n    };\n\n    let mut vis = ExitPointFinder {\n        state: ExitPointState::WalkUpTo(spawn_expr.hir_id),\n        cx,\n    };\n    if let Break(ExitCallFound) = vis.visit_block(block) {\n        // Visitor found an unconditional `exit()` call, so don't lint.\n        return;\n    }\n\n    span_lint_and_then(cx, ZOMBIE_PROCESSES, spawn_expr.span, cause.message(), |diag| {\n        match cause {\n            Cause::EarlyReturn { wait_span, return_span } => {\n                diag.span_note(\n                    return_span,\n                    \"no `wait()` call exists on the code path to this early return\",\n                );\n                diag.span_note(\n                    wait_span,\n                    \"`wait()` call exists, but it is unreachable due to the early return\",\n                );\n            },\n            Cause::MissingWaitInBranch { wait_span, branch_span } => {\n                diag.span_note(branch_span, \"`wait()` is not called in this if branch\");\n                diag.span_note(wait_span, \"`wait()` is called in the other branch\");\n            },\n            Cause::MissingElse { if_span, wait_span } => {\n                diag.span_note(\n                    if_span,\n                    \"this if expression has a `wait()` call, but it is missing an else block\",\n                );\n                diag.span_note(wait_span, \"`wait()` called here\");\n            },\n            Cause::NeverWait => {},\n        }\n\n        if emit_suggestion {\n            diag.span_suggestion(\n                spawn_expr.span.shrink_to_hi(),\n                \"try\",\n                \".wait()\",\n                Applicability::MaybeIncorrect,\n            );\n        } else {\n            diag.help(cause.fallback_help());\n        }\n\n        diag.note(\"not doing so might leave behind zombie processes\")\n            .note(\"see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\");\n    });\n}\n\n/// Checks if the given expression exits the process.\nfn is_exit_expression(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let Some(fn_did) = fn_def_id(cx, expr)\n        && let Some(fn_name) = cx.tcx.get_diagnostic_name(fn_did)\n        && matches!(fn_name, sym::process_exit | sym::process_abort)\n    {\n        true\n    } else {\n        false\n    }\n}\n\n#[derive(Debug)]\nenum ExitPointState {\n    /// Still walking up to the expression that initiated the visitor.\n    WalkUpTo(HirId),\n    /// We're inside of a control flow construct (e.g. `if`, `match`, `loop`)\n    /// Within this, we shouldn't accept any `exit()` calls in here, but we can leave all of these\n    /// constructs later and still continue looking for an `exit()` call afterwards. Example:\n    /// ```ignore\n    /// Command::new(\"\").spawn().unwrap();\n    ///\n    /// if true {                // depth=1\n    ///     if true {            // depth=2\n    ///         match () {       // depth=3\n    ///             () => loop { // depth=4\n    ///\n    ///                 std::process::exit();\n    ///                 ^^^^^^^^^^^^^^^^^^^^^ conditional exit call, ignored\n    ///\n    ///             }           // depth=3\n    ///         }               // depth=2\n    ///     }                   // depth=1\n    /// }                       // depth=0\n    ///\n    /// std::process::exit();\n    /// ^^^^^^^^^^^^^^^^^^^^^ this exit call is accepted because we're now unconditionally calling it\n    /// ```\n    /// We can only get into this state from `NoExit`.\n    InControlFlow { depth: u32 },\n    /// No exit call found yet, but looking for one.\n    NoExit,\n}\n\nfn expr_enters_control_flow(expr: &Expr<'_>) -> bool {\n    matches!(expr.kind, ExprKind::If(..) | ExprKind::Match(..) | ExprKind::Loop(..))\n}\n\nstruct ExitPointFinder<'a, 'tcx> {\n    state: ExitPointState,\n    cx: &'a LateContext<'tcx>,\n}\n\nstruct ExitCallFound;\n\nimpl<'tcx> Visitor<'tcx> for ExitPointFinder<'_, 'tcx> {\n    type Result = ControlFlow<ExitCallFound>;\n\n    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> Self::Result {\n        match self.state {\n            ExitPointState::WalkUpTo(id) if expr.hir_id == id => {\n                self.state = ExitPointState::NoExit;\n                walk_expr(self, expr)\n            },\n            ExitPointState::NoExit if expr_enters_control_flow(expr) => {\n                self.state = ExitPointState::InControlFlow { depth: 1 };\n                walk_expr(self, expr)?;\n                if let ExitPointState::InControlFlow { .. } = self.state {\n                    self.state = ExitPointState::NoExit;\n                }\n                Continue(())\n            },\n            ExitPointState::NoExit if is_exit_expression(self.cx, expr) => Break(ExitCallFound),\n            ExitPointState::InControlFlow { ref mut depth } if expr_enters_control_flow(expr) => {\n                *depth += 1;\n                walk_expr(self, expr)?;\n                match self.state {\n                    ExitPointState::InControlFlow { depth: 1 } => self.state = ExitPointState::NoExit,\n                    ExitPointState::InControlFlow { ref mut depth } => *depth -= 1,\n                    _ => {},\n                }\n                Continue(())\n            },\n            _ => Continue(()),\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/Cargo.toml",
    "content": "[package]\nname = \"clippy_lints_internal\"\nversion = \"0.0.1\"\nedition = \"2024\"\n\n[dependencies]\nclippy_config = { path = \"../clippy_config\" }\nclippy_utils = { path = \"../clippy_utils\" }\nitertools = \"0.12\"\nregex = { version = \"1.5\" }\nrustc-semver = \"1.1\"\n\n[package.metadata.rust-analyzer]\n# This crate uses #[feature(rustc_private)]\nrustc_private = true\n"
  },
  {
    "path": "clippy_lints_internal/src/almost_standard_lint_formulation.rs",
    "content": "use crate::lint_without_lint_pass::is_lint_ref_type;\nuse clippy_utils::diagnostics::span_lint_and_help;\nuse regex::Regex;\nuse rustc_ast::token::DocFragmentKind;\nuse rustc_hir::{Attribute, Item, ItemKind, Mutability};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::{declare_tool_lint, impl_lint_pass};\nuse rustc_span::{Span, Symbol};\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks if lint formulations have a standardized format.\n    ///\n    /// ### Why is this bad?\n    /// It's not necessarily bad, but we try to enforce a standard in Clippy.\n    ///\n    /// ### Example\n    /// `Checks for use...` can be written as `Checks for usage...` .\n    pub clippy::ALMOST_STANDARD_LINT_FORMULATION,\n    Warn,\n    \"lint formulations must have a standardized format.\",\n    report_in_external_macro: true\n}\n\nimpl_lint_pass!(AlmostStandardFormulation => [ALMOST_STANDARD_LINT_FORMULATION]);\n\npub struct AlmostStandardFormulation {\n    standard_formulations: Vec<StandardFormulations<'static>>,\n}\n\n#[derive(Debug)]\nstruct StandardFormulations<'a> {\n    wrong_pattern: Regex,\n    correction: &'a str,\n}\n\nimpl AlmostStandardFormulation {\n    pub fn new() -> Self {\n        let standard_formulations = vec![StandardFormulations {\n            wrong_pattern: Regex::new(\"^(Check for|Detects? uses?)\").unwrap(),\n            correction: \"Checks for\",\n        }];\n        Self { standard_formulations }\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        let mut check_next = false;\n        if let ItemKind::Static(Mutability::Not, _, ty, _) = item.kind {\n            let lines = cx.tcx.hir_attrs(item.hir_id()).iter().filter_map(doc_attr);\n            if is_lint_ref_type(cx, ty) {\n                for (line, span) in lines {\n                    let cur_line = line.as_str().trim();\n                    if check_next && !cur_line.is_empty() {\n                        for formulation in &self.standard_formulations {\n                            let starts_with_correct_formulation = cur_line.starts_with(formulation.correction);\n                            if !starts_with_correct_formulation && formulation.wrong_pattern.is_match(cur_line) {\n                                span_lint_and_help(\n                                    cx,\n                                    ALMOST_STANDARD_LINT_FORMULATION,\n                                    span,\n                                    \"non-standard lint formulation\",\n                                    None,\n                                    format!(\"consider using `{}`\", formulation.correction),\n                                );\n                                return;\n                            }\n                        }\n                        return;\n                    } else if cur_line.contains(\"What it does\") {\n                        check_next = true;\n                    } else if cur_line.contains(\"Why is this bad\") {\n                        // Formulation documentation is done. Can add check to ensure that missing formulation is added\n                        // and add a check if it matches no accepted formulation\n                        return;\n                    }\n                }\n            }\n        }\n    }\n}\n\nfn doc_attr(attr: &Attribute) -> Option<(Symbol, Span)> {\n    match Attribute::doc_str_and_fragment_kind(attr) {\n        Some((symbol, DocFragmentKind::Raw(span))) => Some((symbol, span)),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/collapsible_span_lint_calls.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::{snippet_with_applicability, snippet_with_context};\nuse clippy_utils::{SpanlessEq, is_lint_allowed, peel_blocks_with_stmt, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{Closure, Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_session::{declare_lint_pass, declare_tool_lint};\nuse rustc_span::{Span, SyntaxContext};\n\nuse std::borrow::{Borrow, Cow};\n\nuse crate::internal_paths;\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Lints `span_lint_and_then` function calls, where the\n    /// closure argument has only one statement and that statement is a method\n    /// call to `span_suggestion`, `span_help`, `span_note` (using the same\n    /// span), `help` or `note`.\n    ///\n    /// These usages of `span_lint_and_then` should be replaced with one of the\n    /// wrapper functions `span_lint_and_sugg`, span_lint_and_help`, or\n    /// `span_lint_and_note`.\n    ///\n    /// ### Why is this bad?\n    /// Using the wrapper `span_lint_and_*` functions, is more\n    /// convenient, readable and less error prone.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |diag| {\n    ///     diag.span_suggestion(\n    ///         expr.span,\n    ///         help_msg,\n    ///         sugg.to_string(),\n    ///         Applicability::MachineApplicable,\n    ///     );\n    /// });\n    /// span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |diag| {\n    ///     diag.span_help(expr.span, help_msg);\n    /// });\n    /// span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |diag| {\n    ///     diag.help(help_msg);\n    /// });\n    /// span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |diag| {\n    ///     diag.span_note(expr.span, note_msg);\n    /// });\n    /// span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |diag| {\n    ///     diag.note(note_msg);\n    /// });\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// span_lint_and_sugg(\n    ///     cx,\n    ///     TEST_LINT,\n    ///     expr.span,\n    ///     lint_msg,\n    ///     help_msg,\n    ///     sugg.to_string(),\n    ///     Applicability::MachineApplicable,\n    /// );\n    /// span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg);\n    /// span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg);\n    /// span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg);\n    /// span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, note_msg);\n    /// ```\n    pub clippy::COLLAPSIBLE_SPAN_LINT_CALLS,\n    Warn,\n    \"found collapsible `span_lint_and_then` calls\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(CollapsibleCalls => [COLLAPSIBLE_SPAN_LINT_CALLS]);\n\nimpl<'tcx> LateLintPass<'tcx> for CollapsibleCalls {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if is_lint_allowed(cx, COLLAPSIBLE_SPAN_LINT_CALLS, expr.hir_id) {\n            return;\n        }\n\n        if let ExprKind::Call(func, [call_cx, call_lint, call_sp, call_msg, call_f]) = expr.kind\n            && internal_paths::SPAN_LINT_AND_THEN.matches_path(cx, func)\n            && let ExprKind::Closure(&Closure { body, .. }) = call_f.kind\n            && let body = cx.tcx.hir_body(body)\n            && let only_expr = peel_blocks_with_stmt(body.value)\n            && let ExprKind::MethodCall(ps, recv, span_call_args, _) = &only_expr.kind\n            && let ExprKind::Path(..) = recv.kind\n        {\n            let mut app = Applicability::MachineApplicable;\n            let expr_ctxt = expr.span.ctxt();\n            let and_then_snippets = get_and_then_snippets(\n                cx,\n                expr_ctxt,\n                call_cx.span,\n                call_lint.span,\n                call_sp.span,\n                call_msg.span,\n                &mut app,\n            );\n            let mut sle = SpanlessEq::new(cx).deny_side_effects();\n            match ps.ident.name {\n                sym::span_suggestion if sle.eq_expr(call_sp, &span_call_args[0]) => {\n                    let snippets = span_suggestion_snippets(cx, expr_ctxt, span_call_args, &mut app);\n                    suggest_suggestion(cx, expr, &and_then_snippets, &snippets, app);\n                },\n                sym::span_help if sle.eq_expr(call_sp, &span_call_args[0]) => {\n                    let help_snippet =\n                        snippet_with_context(cx, span_call_args[1].span, expr_ctxt, r#\"\"...\"\"#, &mut app).0;\n                    suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), true, app);\n                },\n                sym::span_note if sle.eq_expr(call_sp, &span_call_args[0]) => {\n                    let note_snippet =\n                        snippet_with_context(cx, span_call_args[1].span, expr_ctxt, r#\"\"...\"\"#, &mut app).0;\n                    suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), true, app);\n                },\n                sym::help => {\n                    let help_snippet =\n                        snippet_with_context(cx, span_call_args[0].span, expr_ctxt, r#\"\"...\"\"#, &mut app).0;\n                    suggest_help(cx, expr, &and_then_snippets, help_snippet.borrow(), false, app);\n                },\n                sym::note => {\n                    let note_snippet =\n                        snippet_with_context(cx, span_call_args[0].span, expr_ctxt, r#\"\"...\"\"#, &mut app).0;\n                    suggest_note(cx, expr, &and_then_snippets, note_snippet.borrow(), false, app);\n                },\n                _ => (),\n            }\n        }\n    }\n}\n\nstruct AndThenSnippets {\n    cx: Cow<'static, str>,\n    lint: Cow<'static, str>,\n    span: Cow<'static, str>,\n    msg: Cow<'static, str>,\n}\n\nfn get_and_then_snippets(\n    cx: &LateContext<'_>,\n    expr_ctxt: SyntaxContext,\n    cx_span: Span,\n    lint_span: Span,\n    span_span: Span,\n    msg_span: Span,\n    app: &mut Applicability,\n) -> AndThenSnippets {\n    let cx_snippet = snippet_with_applicability(cx, cx_span, \"cx\", app);\n    let lint_snippet = snippet_with_applicability(cx, lint_span, \"..\", app);\n    let span_snippet = snippet_with_applicability(cx, span_span, \"span\", app);\n    let msg_snippet = snippet_with_context(cx, msg_span, expr_ctxt, r#\"\"...\"\"#, app).0;\n\n    AndThenSnippets {\n        cx: cx_snippet,\n        lint: lint_snippet,\n        span: span_snippet,\n        msg: msg_snippet,\n    }\n}\n\nstruct SpanSuggestionSnippets {\n    help: Cow<'static, str>,\n    sugg: Cow<'static, str>,\n    applicability: Cow<'static, str>,\n}\n\nfn span_suggestion_snippets<'hir>(\n    cx: &LateContext<'_>,\n    expr_ctxt: SyntaxContext,\n    span_call_args: &'hir [Expr<'hir>],\n    app: &mut Applicability,\n) -> SpanSuggestionSnippets {\n    let help_snippet = snippet_with_context(cx, span_call_args[1].span, expr_ctxt, r#\"\"...\"\"#, app).0;\n    let sugg_snippet = snippet_with_context(cx, span_call_args[2].span, expr_ctxt, \"..\", app).0;\n    let applicability_snippet =\n        snippet_with_applicability(cx, span_call_args[3].span, \"Applicability::MachineApplicable\", app);\n\n    SpanSuggestionSnippets {\n        help: help_snippet,\n        sugg: sugg_snippet,\n        applicability: applicability_snippet,\n    }\n}\n\nfn suggest_suggestion(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    and_then_snippets: &AndThenSnippets,\n    span_suggestion_snippets: &SpanSuggestionSnippets,\n    app: Applicability,\n) {\n    span_lint_and_sugg(\n        cx,\n        COLLAPSIBLE_SPAN_LINT_CALLS,\n        expr.span,\n        \"this call is collapsible\",\n        \"collapse into\",\n        format!(\n            \"span_lint_and_sugg({}, {}, {}, {}, {}, {}, {})\",\n            and_then_snippets.cx,\n            and_then_snippets.lint,\n            and_then_snippets.span,\n            and_then_snippets.msg,\n            span_suggestion_snippets.help,\n            span_suggestion_snippets.sugg,\n            span_suggestion_snippets.applicability\n        ),\n        app,\n    );\n}\n\nfn suggest_help(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    and_then_snippets: &AndThenSnippets,\n    help: &str,\n    with_span: bool,\n    app: Applicability,\n) {\n    let option_span = if with_span {\n        format!(\"Some({})\", and_then_snippets.span)\n    } else {\n        \"None\".to_string()\n    };\n\n    span_lint_and_sugg(\n        cx,\n        COLLAPSIBLE_SPAN_LINT_CALLS,\n        expr.span,\n        \"this call is collapsible\",\n        \"collapse into\",\n        format!(\n            \"span_lint_and_help({}, {}, {}, {}, {}, {help})\",\n            and_then_snippets.cx, and_then_snippets.lint, and_then_snippets.span, and_then_snippets.msg, &option_span,\n        ),\n        app,\n    );\n}\n\nfn suggest_note(\n    cx: &LateContext<'_>,\n    expr: &Expr<'_>,\n    and_then_snippets: &AndThenSnippets,\n    note: &str,\n    with_span: bool,\n    app: Applicability,\n) {\n    let note_span = if with_span {\n        format!(\"Some({})\", and_then_snippets.span)\n    } else {\n        \"None\".to_string()\n    };\n\n    span_lint_and_sugg(\n        cx,\n        COLLAPSIBLE_SPAN_LINT_CALLS,\n        expr.span,\n        \"this call is collapsible\",\n        \"collapse into\",\n        format!(\n            \"span_lint_and_note({}, {}, {}, {}, {note_span}, {note})\",\n            and_then_snippets.cx, and_then_snippets.lint, and_then_snippets.span, and_then_snippets.msg,\n        ),\n        app,\n    );\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::paths;\nuse rustc_ast::tokenstream::{TokenStream, TokenTree};\nuse rustc_ast::{AttrStyle, DelimArgs};\nuse rustc_hir::def::Res;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::{\n    AttrArgs, AttrItem, AttrPath, Attribute, HirId, Impl, Item, ItemKind, Path, QPath, TraitImplHeader, TraitRef, Ty,\n    TyKind, find_attr,\n};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_lint_defs::declare_tool_lint;\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::declare_lint_pass;\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for structs or enums that derive `serde::Deserialize` and that\n    /// do not have a `#[serde(deny_unknown_fields)]` attribute.\n    ///\n    /// ### Why is this bad?\n    /// If the struct or enum is used in [`clippy_config::conf::Conf`] and a\n    /// user inserts an unknown field by mistake, the user's error will be\n    /// silently ignored.\n    ///\n    /// ### Example\n    /// ```rust\n    /// #[derive(serde::Deserialize)]\n    /// pub struct DisallowedPath {\n    ///     path: String,\n    ///     reason: Option<String>,\n    ///     replacement: Option<String>,\n    /// }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust\n    /// #[derive(serde::Deserialize)]\n    /// #[serde(deny_unknown_fields)]\n    /// pub struct DisallowedPath {\n    ///     path: String,\n    ///     reason: Option<String>,\n    ///     replacement: Option<String>,\n    /// }\n    /// ```\n    pub clippy::DERIVE_DESERIALIZE_ALLOWING_UNKNOWN,\n    Allow,\n    \"`#[derive(serde::Deserialize)]` without `#[serde(deny_unknown_fields)]`\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(DeriveDeserializeAllowingUnknown => [DERIVE_DESERIALIZE_ALLOWING_UNKNOWN]);\n\nimpl<'tcx> LateLintPass<'tcx> for DeriveDeserializeAllowingUnknown {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {\n        // Is this an `impl` (of a certain form)?\n        let ItemKind::Impl(Impl {\n            of_trait:\n                Some(TraitImplHeader {\n                    trait_ref:\n                        TraitRef {\n                            path:\n                                Path {\n                                    res: Res::Def(_, trait_def_id),\n                                    ..\n                                },\n                            ..\n                        },\n                    ..\n                }),\n            self_ty:\n                Ty {\n                    kind:\n                        TyKind::Path(QPath::Resolved(\n                            None,\n                            Path {\n                                res: Res::Def(_, self_ty_def_id),\n                                ..\n                            },\n                        )),\n                    ..\n                },\n            ..\n        }) = item.kind\n        else {\n            return;\n        };\n\n        // Is it an `impl` of the trait `serde::Deserialize`?\n        if !paths::SERDE_DESERIALIZE.get(cx).contains(trait_def_id) {\n            return;\n        }\n\n        // Is it derived?\n        if !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AutomaticallyDerived(..)) {\n            return;\n        }\n\n        // Is `self_ty` local?\n        let Some(local_def_id) = self_ty_def_id.as_local() else {\n            return;\n        };\n\n        // Does `self_ty` have a variant with named fields?\n        if !has_variant_with_named_fields(cx.tcx, local_def_id) {\n            return;\n        }\n\n        let hir_id = cx.tcx.local_def_id_to_hir_id(local_def_id);\n\n        // Does `self_ty` have `#[serde(deny_unknown_fields)]`?\n        if let Some(tokens) = find_serde_attr_item(cx.tcx, hir_id)\n            && tokens.iter().any(is_deny_unknown_fields_token)\n        {\n            return;\n        }\n\n        span_lint(\n            cx,\n            DERIVE_DESERIALIZE_ALLOWING_UNKNOWN,\n            item.span,\n            \"`#[derive(serde::Deserialize)]` without `#[serde(deny_unknown_fields)]`\",\n        );\n    }\n}\n\n// Determines whether `def_id` corresponds to an ADT with at least one variant with named fields. A\n// variant has named fields if its `ctor` field is `None`.\nfn has_variant_with_named_fields(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {\n    let ty = tcx.type_of(def_id).skip_binder();\n\n    let rustc_middle::ty::Adt(adt_def, _) = ty.kind() else {\n        return false;\n    };\n\n    adt_def.variants().iter().any(|variant_def| variant_def.ctor.is_none())\n}\n\nfn find_serde_attr_item(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<&TokenStream> {\n    tcx.hir_attrs(hir_id).iter().find_map(|attribute| {\n        if let Attribute::Unparsed(attr_item) = attribute\n            && let AttrItem {\n                path: AttrPath { segments, .. },\n                args: AttrArgs::Delimited(DelimArgs { tokens, .. }),\n                style: AttrStyle::Outer,\n                ..\n            } = &**attr_item\n            && segments.len() == 1\n            && segments[0].as_str() == \"serde\"\n        {\n            Some(tokens)\n        } else {\n            None\n        }\n    })\n}\n\nfn is_deny_unknown_fields_token(tt: &TokenTree) -> bool {\n    if let TokenTree::Token(token, _) = tt\n        && token\n            .ident()\n            .is_some_and(|(token, _)| token.as_str() == \"deny_unknown_fields\")\n    {\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/internal_paths.rs",
    "content": "use clippy_utils::paths::{PathLookup, PathNS};\nuse clippy_utils::{sym, type_path, value_path};\n\n// Paths inside rustc\npub static APPLICABILITY: PathLookup = type_path!(rustc_errors::Applicability);\npub static EARLY_CONTEXT: PathLookup = type_path!(rustc_lint::EarlyContext);\npub static EARLY_LINT_PASS: PathLookup = type_path!(rustc_lint::passes::EarlyLintPass);\npub static KW_MODULE: PathLookup = type_path!(rustc_span::symbol::kw);\npub static LATE_CONTEXT: PathLookup = type_path!(rustc_lint::LateContext);\npub static LINT: PathLookup = type_path!(rustc_lint_defs::Lint);\npub static SYMBOL: PathLookup = type_path!(rustc_span::symbol::Symbol);\npub static SYMBOL_AS_STR: PathLookup = value_path!(rustc_span::symbol::Symbol::as_str);\npub static SYM_MODULE: PathLookup = type_path!(rustc_span::symbol::sym);\npub static SYNTAX_CONTEXT: PathLookup = type_path!(rustc_span::hygiene::SyntaxContext);\n#[expect(clippy::unnecessary_def_path, reason = \"for uniform checking in internal lint\")]\npub static TY_CTXT: PathLookup = type_path!(rustc_middle::ty::TyCtxt);\n\n// Paths in clippy itself\npub static CLIPPY_SYM_MODULE: PathLookup = type_path!(clippy_utils::sym);\npub static MAYBE_DEF: PathLookup = type_path!(clippy_utils::res::MaybeDef);\npub static MSRV_STACK: PathLookup = type_path!(clippy_utils::msrvs::MsrvStack);\npub static PATH_LOOKUP_NEW: PathLookup = value_path!(clippy_utils::paths::PathLookup::new);\npub static SPAN_LINT_AND_THEN: PathLookup = value_path!(clippy_utils::diagnostics::span_lint_and_then);\n"
  },
  {
    "path": "clippy_lints_internal/src/lib.rs",
    "content": "#![feature(rustc_private)]\n#![allow(\n    clippy::missing_docs_in_private_items,\n    clippy::must_use_candidate,\n    clippy::symbol_as_str\n)]\n#![warn(\n    trivial_casts,\n    trivial_numeric_casts,\n    rust_2018_idioms,\n    unused_lifetimes,\n    unused_qualifications,\n    rustc::internal\n)]\n// Disable this rustc lint for now, as it was also done in rustc\n#![allow(rustc::potential_query_instability)]\n// None of these lints need a version.\n#![allow(clippy::missing_clippy_version_attribute)]\n\nextern crate rustc_ast;\nextern crate rustc_attr_parsing;\nextern crate rustc_data_structures;\nextern crate rustc_errors;\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_lint_defs;\nextern crate rustc_middle;\nextern crate rustc_session;\nextern crate rustc_span;\n\nmod almost_standard_lint_formulation;\nmod collapsible_span_lint_calls;\nmod derive_deserialize_allowing_unknown;\nmod internal_paths;\nmod lint_without_lint_pass;\nmod msrv_attr_impl;\nmod outer_expn_data_pass;\nmod produce_ice;\nmod repeated_is_diagnostic_item;\nmod symbols;\nmod unnecessary_def_path;\nmod unsorted_clippy_utils_paths;\nmod unusual_names;\n\nuse rustc_lint::{Lint, LintStore};\n\nstatic LINTS: &[&Lint] = &[\n    almost_standard_lint_formulation::ALMOST_STANDARD_LINT_FORMULATION,\n    collapsible_span_lint_calls::COLLAPSIBLE_SPAN_LINT_CALLS,\n    derive_deserialize_allowing_unknown::DERIVE_DESERIALIZE_ALLOWING_UNKNOWN,\n    lint_without_lint_pass::DEFAULT_LINT,\n    lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE,\n    lint_without_lint_pass::LINT_WITHOUT_LINT_PASS,\n    lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE,\n    msrv_attr_impl::MISSING_MSRV_ATTR_IMPL,\n    outer_expn_data_pass::OUTER_EXPN_EXPN_DATA,\n    produce_ice::PRODUCE_ICE,\n    symbols::INTERNING_LITERALS,\n    symbols::SYMBOL_AS_STR,\n    unnecessary_def_path::UNNECESSARY_DEF_PATH,\n    unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS,\n    unusual_names::UNUSUAL_NAMES,\n];\n\npub fn register_lints(store: &mut LintStore) {\n    store.register_lints(LINTS);\n\n    store.register_early_pass(|| Box::new(unsorted_clippy_utils_paths::UnsortedClippyUtilsPaths));\n    store.register_early_pass(|| Box::new(produce_ice::ProduceIce));\n    store.register_late_pass(|_| Box::new(collapsible_span_lint_calls::CollapsibleCalls));\n    store.register_late_pass(|_| Box::new(derive_deserialize_allowing_unknown::DeriveDeserializeAllowingUnknown));\n    store.register_late_pass(|_| Box::<symbols::Symbols>::default());\n    store.register_late_pass(|_| Box::<lint_without_lint_pass::LintWithoutLintPass>::default());\n    store.register_late_pass(|_| Box::new(unnecessary_def_path::UnnecessaryDefPath));\n    store.register_late_pass(|_| Box::new(outer_expn_data_pass::OuterExpnDataPass));\n    store.register_late_pass(|_| Box::new(msrv_attr_impl::MsrvAttrImpl));\n    store.register_late_pass(|_| Box::new(almost_standard_lint_formulation::AlmostStandardFormulation::new()));\n    store.register_late_pass(|_| Box::new(unusual_names::UnusualNames));\n    store.register_late_pass(|_| Box::new(repeated_is_diagnostic_item::RepeatedIsDiagnosticItem));\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/lint_without_lint_pass.rs",
    "content": "use crate::internal_paths;\nuse clippy_utils::diagnostics::{span_lint, span_lint_and_help};\nuse clippy_utils::macros::root_macro_call_first_node;\nuse clippy_utils::{is_lint_allowed, sym};\nuse rustc_ast::ast::LitKind;\nuse rustc_data_structures::fx::{FxIndexMap, FxIndexSet};\nuse rustc_hir as hir;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::hir_id::CRATE_HIR_ID;\nuse rustc_hir::intravisit::Visitor;\nuse rustc_hir::{ExprKind, HirId, Item, MutTy, Mutability, Path, TyKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::hir::nested_filter;\nuse rustc_session::{declare_tool_lint, impl_lint_pass};\nuse rustc_span::Span;\nuse rustc_span::source_map::Spanned;\nuse rustc_span::symbol::Symbol;\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Ensures every lint is associated to a `LintPass`.\n    ///\n    /// ### Why is this bad?\n    /// The compiler only knows lints via a `LintPass`. Without\n    /// putting a lint to a `LintPass::lint_vec()`'s return, the compiler will not\n    /// know the name of the lint.\n    ///\n    /// ### Known problems\n    /// Only checks for lints associated using the `declare_lint_pass!` and\n    /// `impl_lint_pass!` macros.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// declare_lint! { pub LINT_1, ... }\n    /// declare_lint! { pub LINT_2, ... }\n    /// declare_lint! { pub FORGOTTEN_LINT, ... }\n    /// // ...\n    /// declare_lint_pass!(Pass => [LINT_1, LINT_2]);\n    /// // missing FORGOTTEN_LINT\n    /// ```\n    pub clippy::LINT_WITHOUT_LINT_PASS,\n    Warn,\n    \"declaring a lint without associating it in a LintPass\",\n    report_in_external_macro: true\n\n}\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for cases of an auto-generated lint without an updated description,\n    /// i.e. `default lint description`.\n    ///\n    /// ### Why is this bad?\n    /// Indicates that the lint is not finished.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// declare_lint! { pub COOL_LINT, nursery, \"default lint description\" }\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// declare_lint! { pub COOL_LINT, nursery, \"a great new lint\" }\n    /// ```\n    pub clippy::DEFAULT_LINT,\n    Warn,\n    \"found 'default lint description' in a lint declaration\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for invalid `clippy::version` attributes.\n    ///\n    /// Valid values are:\n    /// * \"pre 1.29.0\"\n    /// * any valid semantic version\n    pub clippy::INVALID_CLIPPY_VERSION_ATTRIBUTE,\n    Warn,\n    \"found an invalid `clippy::version` attribute\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for declared clippy lints without the `clippy::version` attribute.\n    pub clippy::MISSING_CLIPPY_VERSION_ATTRIBUTE,\n    Warn,\n    \"found clippy lint without `clippy::version` attribute\",\n    report_in_external_macro: true\n}\n\n#[derive(Clone, Debug, Default)]\npub struct LintWithoutLintPass {\n    declared_lints: FxIndexMap<Symbol, Span>,\n    registered_lints: FxIndexSet<Symbol>,\n}\n\nimpl_lint_pass!(LintWithoutLintPass => [\n    DEFAULT_LINT,\n    LINT_WITHOUT_LINT_PASS,\n    INVALID_CLIPPY_VERSION_ATTRIBUTE,\n    MISSING_CLIPPY_VERSION_ATTRIBUTE,\n]);\n\nimpl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {\n    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {\n        if let hir::ItemKind::Static(Mutability::Not, ident, ty, body_id) = item.kind {\n            if is_lint_ref_type(cx, ty) {\n                check_invalid_clippy_version_attribute(cx, item);\n\n                let expr = &cx.tcx.hir_body(body_id).value;\n                let fields = if let ExprKind::AddrOf(_, _, inner_exp) = expr.kind\n                    && let ExprKind::Struct(_, struct_fields, _) = inner_exp.kind\n                {\n                    struct_fields\n                } else {\n                    return;\n                };\n\n                let field = fields\n                    .iter()\n                    .find(|f| f.ident.as_str() == \"desc\")\n                    .expect(\"lints must have a description field\");\n\n                if let ExprKind::Lit(Spanned {\n                    node: LitKind::Str(sym, _),\n                    ..\n                }) = field.expr.kind\n                {\n                    let sym_str = sym.as_str();\n                    if sym_str == \"default lint description\" {\n                        span_lint(\n                            cx,\n                            DEFAULT_LINT,\n                            item.span,\n                            format!(\"the lint `{}` has the default lint description\", ident.name),\n                        );\n                    }\n                    self.declared_lints.insert(ident.name, item.span);\n                }\n            }\n        } else if let Some(macro_call) = root_macro_call_first_node(cx, item) {\n            if !matches!(\n                cx.tcx.item_name(macro_call.def_id).as_str(),\n                \"impl_lint_pass\" | \"declare_lint_pass\"\n            ) {\n                return;\n            }\n            if let hir::ItemKind::Impl(hir::Impl {\n                of_trait: None,\n                items: impl_item_refs,\n                ..\n            }) = item.kind\n            {\n                let mut collector = LintCollector {\n                    output: &mut self.registered_lints,\n                    cx,\n                };\n                let body = cx.tcx.hir_body_owned_by(\n                    impl_item_refs\n                        .iter()\n                        .find(|&&iiref| cx.tcx.item_name(iiref.owner_id) == sym::lint_vec)\n                        .expect(\"LintPass needs to implement lint_vec\")\n                        .owner_id\n                        .def_id,\n                );\n                collector.visit_expr(body.value);\n            }\n        }\n    }\n\n    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {\n        if is_lint_allowed(cx, LINT_WITHOUT_LINT_PASS, CRATE_HIR_ID) {\n            return;\n        }\n\n        for (lint_name, &lint_span) in &self.declared_lints {\n            // When using the `declare_tool_lint!` macro, the original `lint_span`'s\n            // file points to \"<rustc macros>\".\n            // `compiletest-rs` thinks that's an error in a different file and\n            // just ignores it. This causes the test in compile-fail/lint_pass\n            // not able to capture the error.\n            // Therefore, we need to climb the macro expansion tree and find the\n            // actual span that invoked `declare_tool_lint!`:\n            let lint_span = lint_span.ctxt().outer_expn_data().call_site;\n\n            if !self.registered_lints.contains(lint_name) {\n                span_lint(\n                    cx,\n                    LINT_WITHOUT_LINT_PASS,\n                    lint_span,\n                    format!(\"the lint `{lint_name}` is not added to any `LintPass`\"),\n                );\n            }\n        }\n    }\n}\n\npub(super) fn is_lint_ref_type(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {\n    if let TyKind::Ref(\n        _,\n        MutTy {\n            ty: inner,\n            mutbl: Mutability::Not,\n        },\n    ) = ty.kind\n        && let TyKind::Path(ref path) = inner.kind\n        && let Res::Def(DefKind::Struct, def_id) = cx.qpath_res(path, inner.hir_id)\n    {\n        internal_paths::LINT.matches(cx, def_id)\n    } else {\n        false\n    }\n}\n\nfn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'_>) {\n    if let Some(value) = extract_clippy_version_value(cx, item) {\n        if value.as_str() == \"pre 1.29.0\" {\n            return;\n        }\n\n        if rustc_attr_parsing::parse_version(value).is_none() {\n            span_lint_and_help(\n                cx,\n                INVALID_CLIPPY_VERSION_ATTRIBUTE,\n                item.span,\n                \"this item has an invalid `clippy::version` attribute\",\n                None,\n                \"please use a valid semantic version, see `doc/adding_lints.md`\",\n            );\n        }\n    } else {\n        span_lint_and_help(\n            cx,\n            MISSING_CLIPPY_VERSION_ATTRIBUTE,\n            item.span,\n            \"this lint is missing the `clippy::version` attribute or version value\",\n            None,\n            \"please use a `clippy::version` attribute, see `doc/adding_lints.md`\",\n        );\n    }\n}\n\n/// This function extracts the version value of a `clippy::version` attribute if the given value has\n/// one\npub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option<Symbol> {\n    let attrs = cx.tcx.hir_attrs(item.hir_id());\n    attrs.iter().find_map(|attr| {\n        if let hir::Attribute::Unparsed(attr_kind) = &attr\n            // Identify attribute\n            && let [tool_name, attr_name] = &attr_kind.path.segments[..]\n            && tool_name == &sym::clippy\n            && attr_name == &sym::version\n            && let Some(version) = attr.value_str()\n        {\n            Some(version)\n        } else {\n            None\n        }\n    })\n}\n\nstruct LintCollector<'a, 'tcx> {\n    output: &'a mut FxIndexSet<Symbol>,\n    cx: &'a LateContext<'tcx>,\n}\n\nimpl<'tcx> Visitor<'tcx> for LintCollector<'_, 'tcx> {\n    type NestedFilter = nested_filter::All;\n\n    fn visit_path(&mut self, path: &Path<'_>, _: HirId) {\n        if path.segments.len() == 1 {\n            self.output.insert(path.segments[0].ident.name);\n        }\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/msrv_attr_impl.rs",
    "content": "use crate::internal_paths;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::source::snippet;\nuse clippy_utils::sym;\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass, LintContext};\nuse rustc_middle::ty::{self, GenericArgKind};\nuse rustc_session::{declare_lint_pass, declare_tool_lint};\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Check that the `extract_msrv_attr!` macro is used, when a lint has a MSRV.\n    pub clippy::MISSING_MSRV_ATTR_IMPL,\n    Warn,\n    \"checking if all necessary steps were taken when adding a MSRV to a lint\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(MsrvAttrImpl => [MISSING_MSRV_ATTR_IMPL]);\n\nimpl LateLintPass<'_> for MsrvAttrImpl {\n    fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {\n        if let hir::ItemKind::Impl(hir::Impl {\n            of_trait: Some(_),\n            items,\n            ..\n        }) = &item.kind\n            && let trait_ref = cx.tcx.impl_trait_ref(item.owner_id).instantiate_identity()\n            && internal_paths::EARLY_LINT_PASS.matches(cx, trait_ref.def_id)\n            && let ty::Adt(self_ty_def, _) = trait_ref.self_ty().kind()\n            && self_ty_def.is_struct()\n            && self_ty_def.all_fields().any(|f| {\n                cx.tcx\n                    .type_of(f.did)\n                    .instantiate_identity()\n                    .walk()\n                    .filter(|t| matches!(t.kind(), GenericArgKind::Type(_)))\n                    .any(|t| internal_paths::MSRV_STACK.matches_ty(cx, t.expect_ty()))\n            })\n            && !items\n                .iter()\n                .any(|&item| cx.tcx.item_name(item.owner_id) == sym::check_attributes)\n        {\n            let span = cx.sess().source_map().span_through_char(item.span, '{');\n            span_lint_and_sugg(\n                cx,\n                MISSING_MSRV_ATTR_IMPL,\n                span,\n                \"`extract_msrv_attr!` macro missing from `EarlyLintPass` implementation\",\n                \"add `extract_msrv_attr!()` to the `EarlyLintPass` implementation\",\n                format!(\"{}\\n    extract_msrv_attr!();\", snippet(cx, span, \"..\")),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/outer_expn_data_pass.rs",
    "content": "use crate::internal_paths;\nuse clippy_utils::diagnostics::span_lint_and_sugg;\nuse clippy_utils::{is_lint_allowed, method_calls, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir as hir;\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_lint_defs::declare_tool_lint;\nuse rustc_session::declare_lint_pass;\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for calls to `cx.outer().expn_data()` and suggests to use\n    /// the `cx.outer_expn_data()`\n    ///\n    /// ### Why is this bad?\n    /// `cx.outer_expn_data()` is faster and more concise.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// expr.span.ctxt().outer().expn_data()\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// expr.span.ctxt().outer_expn_data()\n    /// ```\n    pub clippy::OUTER_EXPN_EXPN_DATA,\n    Warn,\n    \"using `cx.outer_expn().expn_data()` instead of `cx.outer_expn_data()`\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(OuterExpnDataPass => [OUTER_EXPN_EXPN_DATA]);\n\nimpl<'tcx> LateLintPass<'tcx> for OuterExpnDataPass {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {\n        if is_lint_allowed(cx, OUTER_EXPN_EXPN_DATA, expr.hir_id) {\n            return;\n        }\n\n        let (method_names, arg_lists, spans) = method_calls(expr, 2);\n        if let [sym::expn_data, sym::outer_expn] = method_names.as_slice()\n            && let (self_arg, args) = arg_lists[1]\n            && args.is_empty()\n            && let self_ty = cx.typeck_results().expr_ty(self_arg).peel_refs()\n            && internal_paths::SYNTAX_CONTEXT.matches_ty(cx, self_ty)\n        {\n            span_lint_and_sugg(\n                cx,\n                OUTER_EXPN_EXPN_DATA,\n                spans[1].with_hi(expr.span.hi()),\n                \"usage of `outer_expn().expn_data()`\",\n                \"try\",\n                \"outer_expn_data()\".to_string(),\n                Applicability::MachineApplicable,\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/produce_ice.rs",
    "content": "use rustc_ast::ast::NodeId;\nuse rustc_ast::visit::FnKind;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LintContext};\nuse rustc_session::{declare_lint_pass, declare_tool_lint};\nuse rustc_span::Span;\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Not an actual lint. This lint is only meant for testing our customized internal compiler\n    /// error message by calling `panic`.\n    ///\n    /// ### Why is this bad?\n    /// ICE in large quantities can damage your teeth\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// 🍦🍦🍦🍦🍦\n    /// ```\n    pub clippy::PRODUCE_ICE,\n    Warn,\n    \"this message should not appear anywhere as we ICE before and don't emit the lint\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(ProduceIce => [PRODUCE_ICE]);\n\nimpl EarlyLintPass for ProduceIce {\n    fn check_fn(&mut self, cx: &EarlyContext<'_>, fn_kind: FnKind<'_>, span: Span, _: NodeId) {\n        if is_trigger_fn(fn_kind) {\n            cx.sess()\n                .dcx()\n                .span_delayed_bug(span, \"Would you like some help with that?\");\n        }\n    }\n}\n\nfn is_trigger_fn(fn_kind: FnKind<'_>) -> bool {\n    match fn_kind {\n        FnKind::Fn(_, _, func) => func.ident.name.as_str() == \"it_looks_like_you_are_trying_to_kill_clippy\",\n        FnKind::Closure(..) => false,\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/repeated_is_diagnostic_item.rs",
    "content": "use std::iter;\nuse std::ops::ControlFlow;\n\nuse crate::internal_paths::MAYBE_DEF;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::res::{MaybeDef, MaybeTypeckRes};\nuse clippy_utils::source::{snippet_indent, snippet_with_applicability};\nuse clippy_utils::visitors::for_each_expr;\nuse clippy_utils::{eq_expr_value, if_sequence, sym};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BinOpKind, Block, Expr, ExprKind, Node, StmtKind, UnOp};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::print::with_forced_trimmed_paths;\nuse rustc_session::{declare_lint_pass, declare_tool_lint};\nuse rustc_span::Span;\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for repeated use of `MaybeDef::is_diag_item`/`TyCtxt::is_diagnostic_item`;\n    /// suggests to first call `MaybDef::opt_diag_name`/`TyCtxt::get_diagnostic_name` and then\n    /// compare the output with all the `Symbol`s.\n    ///\n    /// ### Why is this bad?\n    /// Each of such calls ultimately invokes the `diagnostic_items` query.\n    /// While the query is cached, it's still better to avoid calling it multiple times if possible.\n    ///\n    /// ### Example\n    /// ```no_run\n    /// ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result)\n    /// cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did)\n    ///\n    /// if ty.is_diag_item(cx, sym::Option) {\n    ///     ..\n    /// } else if ty.is_diag_item(cx, sym::Result) {\n    ///     ..\n    /// } else {\n    ///     ..\n    /// }\n    ///\n    /// if cx.tcx.is_diagnostic_item(sym::Option, did) {\n    ///     ..\n    /// } else if cx.tcx.is_diagnostic_item(sym::Result, did) {\n    ///     ..\n    /// } else {\n    ///     ..\n    /// }\n    ///\n    /// {\n    ///     if ty.is_diag_item(cx, sym::Option) {\n    ///         ..\n    ///     }\n    ///     if ty.is_diag_item(cx, sym::Result) {\n    ///         ..\n    ///     }\n    /// }\n    ///\n    /// {\n    ///     if cx.tcx.is_diagnostic_item(sym::Option, did) {\n    ///         ..\n    ///     }\n    ///     if cx.tcx.is_diagnostic_item(sym::Result, did) {\n    ///         ..\n    ///     }\n    /// }\n    /// ```\n    /// Use instead:\n    /// ```no_run\n    /// matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result))\n    /// matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result))\n    ///\n    /// match ty.opt_diag_name(cx) {\n    ///     Some(sym::Option) => {\n    ///         ..\n    ///     }\n    ///     Some(sym::Result) => {\n    ///         ..\n    ///     }\n    ///     _ => {\n    ///         ..\n    ///     }\n    /// }\n    ///\n    /// match cx.tcx.get_diagnostic_name(did) {\n    ///     Some(sym::Option) => {\n    ///         ..\n    ///     }\n    ///     Some(sym::Result) => {\n    ///         ..\n    ///     }\n    ///     _ => {\n    ///         ..\n    ///     }\n    /// }\n    ///\n    /// {\n    ///     let name = ty.opt_diag_name(cx);\n    ///     if name == Some(sym::Option) {\n    ///         ..\n    ///     }\n    ///     if name == Some(sym::Result) {\n    ///         ..\n    ///     }\n    /// }\n    ///\n    /// {\n    ///     let name = cx.tcx.get_diagnostic_name(did);\n    ///     if name == Some(sym::Option) {\n    ///         ..\n    ///     }\n    ///     if name == Some(sym::Result) {\n    ///         ..\n    ///     }\n    /// }\n    /// ```\n    pub clippy::REPEATED_IS_DIAGNOSTIC_ITEM,\n    Warn,\n    \"repeated use of `MaybeDef::is_diag_item`/`TyCtxt::is_diagnostic_item`\"\n}\ndeclare_lint_pass!(RepeatedIsDiagnosticItem => [REPEATED_IS_DIAGNOSTIC_ITEM]);\n\nconst NOTE: &str = \"each call performs the same compiler query -- it's faster to query once, and reuse the results\";\n\nimpl<'tcx> LateLintPass<'tcx> for RepeatedIsDiagnosticItem {\n    #[expect(clippy::too_many_lines)]\n    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {\n        for [(cond1, stmt1_span), (cond2, stmt2_span)] in block\n            .stmts\n            .windows(2)\n            .filter_map(|pair| {\n                if let [if1, if2] = pair\n                    && let StmtKind::Expr(e1) | StmtKind::Semi(e1) = if1.kind\n                    && let ExprKind::If(cond1, ..) = e1.kind\n                    && let StmtKind::Expr(e2) | StmtKind::Semi(e2) = if2.kind\n                    && let ExprKind::If(cond2, ..) = e2.kind\n                {\n                    Some([(cond1, if1.span), (cond2, if2.span)])\n                } else {\n                    None\n                }\n            })\n            .chain(\n                if let Some(if1) = block.stmts.last()\n                    && let StmtKind::Expr(e1) | StmtKind::Semi(e1) = if1.kind\n                    && let ExprKind::If(cond1, ..) = e1.kind\n                    && let Some(e2) = block.expr\n                    && let ExprKind::If(cond2, ..) = e2.kind\n                {\n                    Some([(cond1, if1.span), (cond2, e2.span)])\n                } else {\n                    None\n                },\n            )\n        {\n            let lint_span = stmt1_span.to(stmt2_span);\n\n            // if recv1.is_diag_item(cx, sym1) && .. {\n            //     ..\n            // }\n            // if recv2.is_diag_item(cx, sym2) && .. {\n            //     ..\n            // }\n            if let Some(first @ (span1, (cx1, recv1, _))) = extract_nested_is_diag_item(cx, cond1)\n                && let Some(second @ (span2, (cx2, recv2, _))) = extract_nested_is_diag_item(cx, cond2)\n                && eq_expr_value(cx, cx1, cx2)\n                && eq_expr_value(cx, recv1, recv2)\n            {\n                let recv_ty =\n                    with_forced_trimmed_paths!(format!(\"{}\", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs()));\n                let recv_ty = recv_ty.trim_end_matches(\"<'_>\");\n                span_lint_and_then(\n                    cx,\n                    REPEATED_IS_DIAGNOSTIC_ITEM,\n                    lint_span,\n                    format!(\"repeated calls to `{recv_ty}::is_diag_item`\"),\n                    |diag| {\n                        diag.span_labels([span1, span2], \"called here\");\n                        diag.note(NOTE);\n\n                        let mut app = Applicability::HasPlaceholders;\n                        let cx_str = snippet_with_applicability(cx, cx1.span, \"_\", &mut app);\n                        let recv = snippet_with_applicability(cx, recv1.span, \"_\", &mut app);\n                        let indent = snippet_indent(cx, stmt1_span).unwrap_or_default();\n                        let sugg: Vec<_> = iter::once((\n                            stmt1_span.shrink_to_lo(),\n                            format!(\"let /* name */ = {recv}.opt_diag_name({cx_str});\\n{indent}\"),\n                        )) // call `opt_diag_name` once\n                        .chain([first, second].into_iter().map(|(expr_span, (_, _, sym))| {\n                            let sym = snippet_with_applicability(cx, sym.span, \"_\", &mut app);\n                            (expr_span, format!(\"/* name */ == Some({sym})\"))\n                        }))\n                        .collect();\n\n                        diag.multipart_suggestion(\n                            format!(\"call `{recv_ty}::opt_diag_name`, and reuse the results\"),\n                            sugg,\n                            app,\n                        );\n                    },\n                );\n                return;\n            }\n\n            // if cx.tcx.is_diagnostic_item(sym1, did) && .. {\n            //     ..\n            // }\n            // if cx.tcx.is_diagnostic_item(sym2, did) && .. {\n            //     ..\n            // }\n            if let Some(first @ (span1, (tcx1, did1, _))) = extract_nested_is_diagnostic_item(cx, cond1)\n                && let Some(second @ (span2, (tcx2, did2, _))) = extract_nested_is_diagnostic_item(cx, cond2)\n                && eq_expr_value(cx, tcx1, tcx2)\n                && eq_expr_value(cx, did1, did2)\n            {\n                span_lint_and_then(\n                    cx,\n                    REPEATED_IS_DIAGNOSTIC_ITEM,\n                    lint_span,\n                    \"repeated calls to `TyCtxt::is_diagnostic_item`\",\n                    |diag| {\n                        diag.span_labels([span1, span2], \"called here\");\n                        diag.note(NOTE);\n\n                        let mut app = Applicability::HasPlaceholders;\n                        let tcx = snippet_with_applicability(cx, tcx1.span, \"_\", &mut app);\n                        let did = snippet_with_applicability(cx, did1.span, \"_\", &mut app);\n                        let indent = snippet_indent(cx, stmt1_span).unwrap_or_default();\n                        let sugg: Vec<_> = iter::once((\n                            stmt1_span.shrink_to_lo(),\n                            format!(\"let /* name */ = {tcx}.get_diagnostic_name({did});\\n{indent}\"),\n                        )) // call `get_diagnostic_name` once\n                        .chain([first, second].into_iter().map(|(expr_span, (_, _, sym))| {\n                            let sym = snippet_with_applicability(cx, sym.span, \"_\", &mut app);\n                            (expr_span, format!(\"/* name */ == Some({sym})\"))\n                        }))\n                        .collect();\n\n                        diag.multipart_suggestion(\n                            \"call `TyCtxt::get_diagnostic_name`, and reuse the results\",\n                            sugg,\n                            app,\n                        );\n                    },\n                );\n            }\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Binary(op, left, right) = expr.kind {\n            if op.node == BinOpKind::Or {\n                check_ors(cx, expr.span, left, right);\n            } else if op.node == BinOpKind::And\n                && let ExprKind::Unary(UnOp::Not, left) = left.kind\n                && let ExprKind::Unary(UnOp::Not, right) = right.kind\n            {\n                check_ands(cx, expr.span, left, right);\n            }\n        } else if let (conds, _) = if_sequence(expr)\n            && !conds.is_empty()\n        {\n            check_if_chains(cx, expr, conds);\n        }\n    }\n}\n\nfn check_ors(cx: &LateContext<'_>, span: Span, left: &Expr<'_>, right: &Expr<'_>) {\n    // recv1.is_diag_item(cx, sym1) || recv2.is_diag_item(cx, sym2)\n    if let Some((cx1, recv1, sym1)) = extract_is_diag_item(cx, left)\n        && let Some((cx2, recv2, sym2)) = extract_is_diag_item(cx, right)\n        && eq_expr_value(cx, cx1, cx2)\n        && eq_expr_value(cx, recv1, recv2)\n    {\n        let recv_ty =\n            with_forced_trimmed_paths!(format!(\"{}\", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs()));\n        let recv_ty = recv_ty.trim_end_matches(\"<'_>\");\n        span_lint_and_then(\n            cx,\n            REPEATED_IS_DIAGNOSTIC_ITEM,\n            span,\n            format!(\"repeated calls to `{recv_ty}::is_diag_item`\"),\n            |diag| {\n                diag.note(NOTE);\n\n                let mut app = Applicability::MachineApplicable;\n                let cx_str = snippet_with_applicability(cx, cx1.span, \"_\", &mut app);\n                let recv = snippet_with_applicability(cx, recv1.span, \"_\", &mut app);\n                let sym1 = snippet_with_applicability(cx, sym1.span, \"_\", &mut app);\n                let sym2 = snippet_with_applicability(cx, sym2.span, \"_\", &mut app);\n                diag.span_suggestion_verbose(\n                    span,\n                    format!(\"call `{recv_ty}::opt_diag_name`, and reuse the results\"),\n                    format!(\"matches!({recv}.opt_diag_name({cx_str}), Some({sym1} | {sym2}))\"),\n                    app,\n                );\n            },\n        );\n        return;\n    }\n\n    // cx.tcx.is_diagnostic_item(sym1, did) || cx.tcx.is_diagnostic_item(sym2, did)\n    if let Some((tcx1, did1, sym1)) = extract_is_diagnostic_item(cx, left)\n        && let Some((tcx2, did2, sym2)) = extract_is_diagnostic_item(cx, right)\n        && eq_expr_value(cx, tcx1, tcx2)\n        && eq_expr_value(cx, did1, did2)\n    {\n        span_lint_and_then(\n            cx,\n            REPEATED_IS_DIAGNOSTIC_ITEM,\n            span,\n            \"repeated calls to `TyCtxt::is_diagnostic_item`\",\n            |diag| {\n                diag.note(NOTE);\n\n                let mut app = Applicability::MachineApplicable;\n                let tcx = snippet_with_applicability(cx, tcx1.span, \"_\", &mut app);\n                let did = snippet_with_applicability(cx, did1.span, \"_\", &mut app);\n                let sym1 = snippet_with_applicability(cx, sym1.span, \"_\", &mut app);\n                let sym2 = snippet_with_applicability(cx, sym2.span, \"_\", &mut app);\n                diag.span_suggestion_verbose(\n                    span,\n                    \"call `TyCtxt::get_diagnostic_name`, and reuse the results\",\n                    format!(\"matches!({tcx}.get_diagnostic_name({did}), Some({sym1} | {sym2}))\"),\n                    app,\n                );\n            },\n        );\n    }\n}\n\nfn check_ands(cx: &LateContext<'_>, span: Span, left: &Expr<'_>, right: &Expr<'_>) {\n    // !recv1.is_diag_item(cx, sym1) && !recv2.is_diag_item(cx, sym2)\n    if let Some((cx1, recv1, sym1)) = extract_is_diag_item(cx, left)\n        && let Some((cx2, recv2, sym2)) = extract_is_diag_item(cx, right)\n        && eq_expr_value(cx, cx1, cx2)\n        && eq_expr_value(cx, recv1, recv2)\n    {\n        let recv_ty =\n            with_forced_trimmed_paths!(format!(\"{}\", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs()));\n        let recv_ty = recv_ty.trim_end_matches(\"<'_>\");\n        span_lint_and_then(\n            cx,\n            REPEATED_IS_DIAGNOSTIC_ITEM,\n            span,\n            format!(\"repeated calls to `{recv_ty}::is_diag_item`\"),\n            |diag| {\n                diag.note(NOTE);\n\n                let mut app = Applicability::MachineApplicable;\n                let cx_str = snippet_with_applicability(cx, cx1.span, \"_\", &mut app);\n                let recv = snippet_with_applicability(cx, recv1.span, \"_\", &mut app);\n                let sym1 = snippet_with_applicability(cx, sym1.span, \"_\", &mut app);\n                let sym2 = snippet_with_applicability(cx, sym2.span, \"_\", &mut app);\n                diag.span_suggestion_verbose(\n                    span,\n                    format!(\"call `{recv_ty}::opt_diag_name`, and reuse the results\"),\n                    format!(\"!matches!({recv}.opt_diag_name({cx_str}), Some({sym1} | {sym2}))\"),\n                    app,\n                );\n            },\n        );\n        return;\n    }\n\n    // !cx.tcx.is_diagnostic_item(sym1, did) && !cx.tcx.is_diagnostic_item(sym2, did)\n    if let Some((tcx1, did1, sym1)) = extract_is_diagnostic_item(cx, left)\n        && let Some((tcx2, did2, sym2)) = extract_is_diagnostic_item(cx, right)\n        && eq_expr_value(cx, tcx1, tcx2)\n        && eq_expr_value(cx, did1, did2)\n    {\n        span_lint_and_then(\n            cx,\n            REPEATED_IS_DIAGNOSTIC_ITEM,\n            span,\n            \"repeated calls to `TyCtxt::is_diagnostic_item`\",\n            |diag| {\n                diag.note(NOTE);\n\n                let mut app = Applicability::MachineApplicable;\n                let tcx = snippet_with_applicability(cx, tcx1.span, \"_\", &mut app);\n                let did = snippet_with_applicability(cx, did1.span, \"_\", &mut app);\n                let sym1 = snippet_with_applicability(cx, sym1.span, \"_\", &mut app);\n                let sym2 = snippet_with_applicability(cx, sym2.span, \"_\", &mut app);\n                diag.span_suggestion_verbose(\n                    span,\n                    \"call `TyCtxt::get_diagnostic_name`, and reuse the results\",\n                    format!(\"!matches!({tcx}.get_diagnostic_name({did}), Some({sym1} | {sym2}))\"),\n                    app,\n                );\n            },\n        );\n    }\n}\n\nfn check_if_chains<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, conds: Vec<&'tcx Expr<'_>>) {\n    // if ty.is_diag_item(cx, sym1) {\n    //     ..\n    // } else if ty.is_diag_item(cx, sym2) {\n    //     ..\n    // } else {\n    //     ..\n    // }\n    let mut found = conds.iter().filter_map(|cond| extract_nested_is_diag_item(cx, cond));\n    if let Some(first @ (_, (cx_1, recv1, _))) = found.next()\n        && let other =\n            found.filter(|(_, (cx_, recv, _))| eq_expr_value(cx, cx_, cx_1) && eq_expr_value(cx, recv, recv1))\n        && let results = iter::once(first).chain(other).collect::<Vec<_>>()\n        && results.len() > 1\n    {\n        let recv_ty =\n            with_forced_trimmed_paths!(format!(\"{}\", cx.typeck_results().expr_ty_adjusted(recv1).peel_refs()));\n        let recv_ty = recv_ty.trim_end_matches(\"<'_>\");\n        span_lint_and_then(\n            cx,\n            REPEATED_IS_DIAGNOSTIC_ITEM,\n            expr.span,\n            format!(\"repeated calls to `{recv_ty}::is_diag_item`\"),\n            |diag| {\n                diag.span_labels(results.iter().map(|(span, _)| *span), \"called here\");\n                diag.note(NOTE);\n\n                let mut app = Applicability::HasPlaceholders;\n                let cx_str = snippet_with_applicability(cx, cx_1.span, \"_\", &mut app);\n                let recv = snippet_with_applicability(cx, recv1.span, \"_\", &mut app);\n                let span_before = if let Node::LetStmt(let_stmt) = cx.tcx.parent_hir_node(expr.hir_id) {\n                    let_stmt.span\n                } else {\n                    expr.span\n                };\n                let indent = snippet_indent(cx, span_before).unwrap_or_default();\n                let sugg: Vec<_> = iter::once((\n                    span_before.shrink_to_lo(),\n                    format!(\"let /* name */ = {recv}.opt_diag_name({cx_str});\\n{indent}\"),\n                )) // call `opt_diag_name` once\n                .chain(results.into_iter().map(|(expr_span, (_, _, sym))| {\n                    let sym = snippet_with_applicability(cx, sym.span, \"_\", &mut app);\n                    (expr_span, format!(\"/* name */ == Some({sym})\"))\n                }))\n                .collect();\n\n                diag.multipart_suggestion(\n                    format!(\"call `{recv_ty}::opt_diag_name`, and reuse the results\"),\n                    sugg,\n                    app,\n                );\n            },\n        );\n    }\n\n    // if cx.tcx.is_diagnostic_item(sym1, did) {\n    //     ..\n    // } else if cx.tcx.is_diagnostic_item(sym2, did) {\n    //     ..\n    // } else {\n    //     ..\n    // }\n    let mut found = conds\n        .into_iter()\n        .filter_map(|cond| extract_nested_is_diagnostic_item(cx, cond));\n    if let Some(first @ (_, (tcx1, did1, _))) = found.next()\n        && let other = found.filter(|(_, (tcx, did, _))| eq_expr_value(cx, tcx, tcx1) && eq_expr_value(cx, did, did1))\n        && let results = iter::once(first).chain(other).collect::<Vec<_>>()\n        && results.len() > 1\n    {\n        span_lint_and_then(\n            cx,\n            REPEATED_IS_DIAGNOSTIC_ITEM,\n            expr.span,\n            \"repeated calls to `TyCtxt::is_diagnostic_item`\",\n            |diag| {\n                diag.span_labels(results.iter().map(|(span, _)| *span), \"called here\");\n                diag.note(NOTE);\n\n                let mut app = Applicability::HasPlaceholders;\n                let tcx = snippet_with_applicability(cx, tcx1.span, \"_\", &mut app);\n                let recv = snippet_with_applicability(cx, did1.span, \"_\", &mut app);\n                let span_before = if let Node::LetStmt(let_stmt) = cx.tcx.parent_hir_node(expr.hir_id) {\n                    let_stmt.span\n                } else {\n                    expr.span\n                };\n                let indent = snippet_indent(cx, span_before).unwrap_or_default();\n                let sugg: Vec<_> = iter::once((\n                    span_before.shrink_to_lo(),\n                    format!(\"let /* name */ = {tcx}.get_diagnostic_name({recv});\\n{indent}\"),\n                )) // call `get_diagnostic_name` once\n                .chain(results.into_iter().map(|(expr_span, (_, _, sym))| {\n                    let sym = snippet_with_applicability(cx, sym.span, \"_\", &mut app);\n                    (expr_span, format!(\"/* name */ == Some({sym})\"))\n                }))\n                .collect();\n\n                diag.multipart_suggestion(\"call `TyCtxt::get_diagnostic_name`, and reuse the results\", sugg, app);\n            },\n        );\n    }\n}\n\nfn extract_is_diag_item<'tcx>(\n    cx: &LateContext<'_>,\n    expr: &'tcx Expr<'tcx>,\n) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {\n    if let ExprKind::MethodCall(is_diag_item, recv, [cx_, sym], _) = expr.kind\n        && is_diag_item.ident.name == sym::is_diag_item\n        // Whether this a method from the `MaybeDef` trait\n        && let Some(did) = cx.ty_based_def(expr).opt_parent(cx).opt_def_id()\n        && MAYBE_DEF.matches(cx, did)\n    {\n        Some((cx_, recv, sym))\n    } else {\n        None\n    }\n}\n\nfn extract_is_diagnostic_item<'tcx>(\n    cx: &LateContext<'_>,\n    expr: &'tcx Expr<'tcx>,\n) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {\n    if let ExprKind::MethodCall(is_diag_item, tcx, [sym, did], _) = expr.kind\n        && is_diag_item.ident.name == sym::is_diagnostic_item\n        // Whether this is an inherent method on `TyCtxt`\n        && cx\n            .ty_based_def(expr)\n            .opt_parent(cx)\n            .opt_impl_ty(cx)\n            .is_diag_item(cx, sym::TyCtxt)\n    {\n        Some((tcx, did, sym))\n    } else {\n        None\n    }\n}\n\nfn extract_nested_is_diag_item<'tcx>(\n    cx: &LateContext<'tcx>,\n    cond: &'tcx Expr<'_>,\n) -> Option<(Span, (&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>))> {\n    for_each_expr(cx, cond, |cond_part| {\n        if let Some(res) = extract_is_diag_item(cx, cond_part) {\n            ControlFlow::Break((cond_part.span, res))\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n}\n\nfn extract_nested_is_diagnostic_item<'tcx>(\n    cx: &LateContext<'tcx>,\n    cond: &'tcx Expr<'_>,\n) -> Option<(Span, (&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>))> {\n    for_each_expr(cx, cond, |cond_part| {\n        if let Some(res) = extract_is_diagnostic_item(cx, cond_part) {\n            ControlFlow::Break((cond_part.span, res))\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/symbols.rs",
    "content": "use crate::internal_paths;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse rustc_ast::LitKind;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_errors::Applicability;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{Expr, ExprKind, Lit, Node, Pat, PatExprKind, PatKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::mir::ConstValue;\nuse rustc_middle::ty;\nuse rustc_session::{declare_tool_lint, impl_lint_pass};\nuse rustc_span::symbol::Symbol;\nuse rustc_span::{Span, sym};\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for interning string literals as symbols\n    ///\n    /// ### Why is this bad?\n    /// It's faster and easier to use the symbol constant. If one doesn't exist it can be added to `clippy_utils/src/sym.rs`\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// let _ = Symbol::intern(\"f32\");\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// let _ = sym::f32;\n    /// ```\n    pub clippy::INTERNING_LITERALS,\n    Warn,\n    \"interning a symbol that is a literal\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for calls to `Symbol::as_str`\n    ///\n    /// ### Why is this bad?\n    /// It's faster and easier to use the symbol constant. If one doesn't exist it can be added to `clippy_utils/src/sym.rs`\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// symbol.as_str() == \"foo\"\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// symbol == sym::foo\n    /// ```\n    pub clippy::SYMBOL_AS_STR,\n    Warn,\n    \"calls to `Symbol::as_str`\",\n    report_in_external_macro: true\n}\n\n#[derive(Default)]\npub struct Symbols {\n    // Maps the symbol to the import path\n    symbol_map: FxHashMap<u32, (&'static str, Symbol)>,\n}\n\nimpl_lint_pass!(Symbols => [INTERNING_LITERALS, SYMBOL_AS_STR]);\n\nimpl Symbols {\n    fn lit_suggestion(&self, lit: Lit) -> Option<(Span, String)> {\n        if let LitKind::Str(name, _) = lit.node {\n            let sugg = if let Some((prefix, name)) = self.symbol_map.get(&name.as_u32()) {\n                format!(\"{prefix}::{name}\")\n            } else {\n                format!(\"sym::{}\", name.as_str().replace(|ch: char| !ch.is_alphanumeric(), \"_\"))\n            };\n            Some((lit.span, sugg))\n        } else {\n            None\n        }\n    }\n\n    fn expr_suggestion(&self, expr: &Expr<'_>) -> Option<(Span, String)> {\n        if let ExprKind::Lit(lit) = expr.kind {\n            self.lit_suggestion(lit)\n        } else {\n            None\n        }\n    }\n\n    fn pat_suggestions(&self, pat: &Pat<'_>, suggestions: &mut Vec<(Span, String)>) {\n        pat.walk_always(|pat| {\n            if let PatKind::Expr(pat_expr) = pat.kind\n                && let PatExprKind::Lit { lit, .. } = pat_expr.kind\n            {\n                suggestions.extend(self.lit_suggestion(lit));\n            }\n        });\n    }\n}\n\nimpl<'tcx> LateLintPass<'tcx> for Symbols {\n    fn check_crate(&mut self, cx: &LateContext<'_>) {\n        let modules = [\n            (\"kw\", &internal_paths::KW_MODULE),\n            (\"sym\", &internal_paths::SYM_MODULE),\n            (\"sym\", &internal_paths::CLIPPY_SYM_MODULE),\n        ];\n        for (prefix, module) in modules {\n            for def_id in module.get(cx) {\n                // When linting `clippy_utils` itself we can't use `module_children` as it's a local def id. It will\n                // still lint but the suggestion may suggest the incorrect name for symbols such as `sym::CRLF`\n                if def_id.is_local() {\n                    continue;\n                }\n\n                for item in cx.tcx.module_children(*def_id) {\n                    if let Res::Def(DefKind::Const { .. }, item_def_id) = item.res\n                        && let ty = cx.tcx.type_of(item_def_id).instantiate_identity()\n                        && internal_paths::SYMBOL.matches_ty(cx, ty)\n                        && let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id)\n                        && let Some(value) = value.to_u32().discard_err()\n                    {\n                        self.symbol_map.insert(value, (prefix, item.ident.name));\n                    }\n                }\n            }\n        }\n    }\n\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Call(func, [arg]) = &expr.kind\n            && let ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(func).kind()\n            && cx.tcx.is_diagnostic_item(sym::SymbolIntern, *def_id)\n            && let Some((_, sugg)) = self.expr_suggestion(arg)\n        {\n            span_lint_and_then(\n                cx,\n                INTERNING_LITERALS,\n                expr.span,\n                \"interning a string literal\",\n                |diag| {\n                    diag.span_suggestion_verbose(\n                        expr.span,\n                        \"use a preinterned symbol instead\",\n                        sugg,\n                        Applicability::MaybeIncorrect,\n                    );\n                    diag.help(\"add the symbol to `clippy_utils/src/sym.rs` if needed\");\n                },\n            );\n        }\n\n        if let Some(as_str) = as_str_span(cx, expr)\n            && let Node::Expr(parent) = cx.tcx.parent_hir_node(expr.hir_id)\n        {\n            let mut suggestions = Vec::new();\n\n            match parent.kind {\n                ExprKind::Binary(_, lhs, rhs) => {\n                    suggestions.extend(self.expr_suggestion(lhs));\n                    suggestions.extend(self.expr_suggestion(rhs));\n                },\n                ExprKind::Match(_, arms, _) => {\n                    for arm in arms {\n                        self.pat_suggestions(arm.pat, &mut suggestions);\n                    }\n                },\n                _ => {},\n            }\n\n            if suggestions.is_empty() {\n                return;\n            }\n\n            span_lint_and_then(\n                cx,\n                SYMBOL_AS_STR,\n                expr.span,\n                \"converting a Symbol to a string\",\n                |diag| {\n                    suggestions.push((as_str, String::new()));\n                    diag.multipart_suggestion(\n                        \"use preinterned symbols instead\",\n                        suggestions,\n                        Applicability::MaybeIncorrect,\n                    );\n                    diag.help(\"add the symbols to `clippy_utils/src/sym.rs` if needed\");\n                },\n            );\n        }\n    }\n}\n\n/// ```ignore\n/// symbol.as_str()\n/// //     ^^^^^^^^\n/// ```\nfn as_str_span(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Span> {\n    if let ExprKind::MethodCall(_, recv, [], _) = expr.kind\n        && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n        && internal_paths::SYMBOL_AS_STR.matches(cx, method_def_id)\n    {\n        Some(recv.span.shrink_to_hi().to(expr.span.shrink_to_hi()))\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/unnecessary_def_path.rs",
    "content": "use crate::internal_paths;\nuse clippy_utils::diagnostics::span_lint_and_then;\nuse clippy_utils::paths::{PathNS, lookup_path};\nuse clippy_utils::peel_ref_operators;\nuse clippy_utils::res::MaybeQPath;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{Expr, ExprKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_lint_defs::{declare_lint_pass, declare_tool_lint};\nuse rustc_middle::mir::ConstValue;\nuse rustc_span::symbol::Symbol;\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks for usage of def paths when a diagnostic item or a `LangItem` could be used.\n    ///\n    /// ### Why is this bad?\n    /// The path for an item is subject to change and is less efficient to look up than a\n    /// diagnostic item or a `LangItem`.\n    ///\n    /// ### Example\n    /// ```rust,ignore\n    /// pub static VEC: PathLookup = path!(alloc::vec::Vec);\n    ///\n    /// VEC.contains_ty(cx, ty)\n    /// ```\n    ///\n    /// Use instead:\n    /// ```rust,ignore\n    /// ty.is_diag_item(cx, sym::Vec)\n    /// ```\n    pub clippy::UNNECESSARY_DEF_PATH,\n    Warn,\n    \"using a def path when a diagnostic item or a `LangItem` is available\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(UnnecessaryDefPath => [UNNECESSARY_DEF_PATH]);\n\nimpl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath {\n    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {\n        if let ExprKind::Call(ctor, [_, path]) = expr.kind\n            && internal_paths::PATH_LOOKUP_NEW.matches_path(cx, ctor)\n            && let ExprKind::Array(segments) = peel_ref_operators(cx, path).kind\n            && let Some(macro_id) = expr.span.ctxt().outer_expn_data().macro_def_id\n        {\n            let ns = match cx.tcx.item_name(macro_id).as_str() {\n                \"type_path\" => PathNS::Type,\n                \"value_path\" => PathNS::Value,\n                \"macro_path\" => PathNS::Macro,\n                _ => unreachable!(),\n            };\n\n            let path: Vec<Symbol> = segments\n                .iter()\n                .map(|segment| {\n                    if let Some(const_def_id) = segment.res(cx).opt_def_id()\n                        && let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(const_def_id)\n                        && let Some(value) = value.to_u32().discard_err()\n                    {\n                        Symbol::new(value)\n                    } else {\n                        panic!(\"failed to resolve path {:?}\", expr.span);\n                    }\n                })\n                .collect();\n\n            for def_id in lookup_path(cx.tcx, ns, &path) {\n                if let Some(name) = cx.tcx.get_diagnostic_name(def_id) {\n                    span_lint_and_then(\n                        cx,\n                        UNNECESSARY_DEF_PATH,\n                        expr.span.source_callsite(),\n                        format!(\"a diagnostic name exists for this path: sym::{name}\"),\n                        |diag| {\n                            diag.help(\n                                \"remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead\",\n                            );\n                            diag.help(\"see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils\");\n                        },\n                    );\n                } else if let Some(item_name) = get_lang_item_name(cx, def_id) {\n                    span_lint_and_then(\n                        cx,\n                        UNNECESSARY_DEF_PATH,\n                        expr.span.source_callsite(),\n                        format!(\"a language item exists for this path: LangItem::{item_name}\"),\n                        |diag| {\n                            diag.help(\"remove the `PathLookup` and use utilities such as `cx.tcx.lang_items` instead\");\n                            diag.help(\"see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=lang&filter-crate=clippy_utils\");\n                        },\n                    );\n                }\n            }\n        }\n    }\n}\n\nfn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {\n    if let Some((lang_item, _)) = cx.tcx.lang_items().iter().find(|(_, id)| *id == def_id) {\n        Some(lang_item.variant_name())\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/unsorted_clippy_utils_paths.rs",
    "content": "use clippy_utils::diagnostics::span_lint;\nuse clippy_utils::sym;\nuse rustc_ast::ast::{Crate, ItemKind, ModKind};\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::{declare_lint_pass, declare_tool_lint};\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks that [`clippy_utils::paths`] is sorted lexically\n    ///\n    /// ### Why is this bad?\n    /// We like to pretend we're an example of tidy code.\n    ///\n    /// ### Example\n    /// Wrong ordering of the util::paths constants.\n    pub clippy::UNSORTED_CLIPPY_UTILS_PATHS,\n    Warn,\n    \"various things that will negatively affect your clippy experience\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(UnsortedClippyUtilsPaths => [UNSORTED_CLIPPY_UTILS_PATHS]);\n\nimpl EarlyLintPass for UnsortedClippyUtilsPaths {\n    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {\n        if let Some(utils) = krate\n            .items\n            .iter()\n            .find(|item| item.kind.ident().is_some_and(|i| i.name == sym::utils))\n            && let ItemKind::Mod(_, _, ModKind::Loaded(ref items, ..)) = utils.kind\n            && let Some(paths) = items\n                .iter()\n                .find(|item| item.kind.ident().is_some_and(|i| i.name == sym::paths))\n            && let ItemKind::Mod(_, _, ModKind::Loaded(ref items, ..)) = paths.kind\n        {\n            let mut last_name: Option<String> = None;\n            for item in items {\n                let name = item.kind.ident().expect(\"const items have idents\").to_string();\n                if let Some(last_name) = last_name\n                    && *last_name > *name\n                {\n                    span_lint(\n                        cx,\n                        UNSORTED_CLIPPY_UTILS_PATHS,\n                        item.span,\n                        \"this constant should be before the previous constant due to lexical \\\n                                         ordering\",\n                    );\n                }\n                last_name = Some(name);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_lints_internal/src/unusual_names.rs",
    "content": "use clippy_utils::diagnostics::span_lint_and_help;\nuse clippy_utils::paths::PathLookup;\nuse clippy_utils::sym;\nuse itertools::Itertools;\nuse rustc_hir::def_id::LocalDefId;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{Body, FnDecl, Pat, PatKind, Stmt, StmtKind};\nuse rustc_lint::{LateContext, LateLintPass};\nuse rustc_middle::ty::Ty;\nuse rustc_session::{declare_lint_pass, declare_tool_lint};\nuse rustc_span::symbol::kw;\nuse rustc_span::{Span, Symbol};\n\nuse crate::internal_paths::{APPLICABILITY, EARLY_CONTEXT, LATE_CONTEXT, TY_CTXT};\n\ndeclare_tool_lint! {\n    /// ### What it does\n    /// Checks if variables of some types use the usual name.\n    ///\n    /// ### Why is this bad?\n    /// Restricting the identifiers used for common things in\n    /// Clippy sources increases consistency.\n    ///\n    /// ### Example\n    /// Check that an `rustc_errors::Applicability` variable is\n    /// named either `app` or `applicability`, and not\n    /// `a` or `appl`.\n    pub clippy::UNUSUAL_NAMES,\n    Warn,\n    \"commonly used concepts should use usual same variable name.\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(UnusualNames => [UNUSUAL_NAMES]);\n\nconst USUAL_NAMES: [(&PathLookup, &str, &[Symbol]); 4] = [\n    (\n        &APPLICABILITY,\n        \"rustc_errors::Applicability\",\n        &[sym::app, sym::applicability],\n    ),\n    (&EARLY_CONTEXT, \"rustc_lint::EarlyContext\", &[sym::cx]),\n    (&LATE_CONTEXT, \"rustc_lint::LateContext\", &[sym::cx]),\n    (&TY_CTXT, \"rustc_middle::ty::TyCtxt\", &[sym::tcx]),\n];\n\nimpl<'tcx> LateLintPass<'tcx> for UnusualNames {\n    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {\n        if let StmtKind::Let(let_stmt) = stmt.kind\n            && let Some(init_expr) = let_stmt.init\n        {\n            check_pat_name_for_ty(cx, let_stmt.pat, cx.typeck_results().expr_ty(init_expr), \"variable\");\n        }\n    }\n\n    fn check_fn(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        kind: FnKind<'tcx>,\n        _decl: &'tcx FnDecl<'_>,\n        body: &'tcx Body<'_>,\n        _span: Span,\n        def_id: LocalDefId,\n    ) {\n        if matches!(kind, FnKind::Closure) {\n            return;\n        }\n        for (param, ty) in body\n            .params\n            .iter()\n            .zip(cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder().inputs())\n        {\n            check_pat_name_for_ty(cx, param.pat, *ty, \"parameter\");\n        }\n    }\n}\n\nfn check_pat_name_for_ty(cx: &LateContext<'_>, pat: &Pat<'_>, ty: Ty<'_>, kind: &str) {\n    if let PatKind::Binding(_, _, ident, _) = pat.kind {\n        let ty = ty.peel_refs();\n        for (usual_ty, ty_str, usual_names) in USUAL_NAMES {\n            if usual_ty.matches_ty(cx, ty)\n                && !usual_names.contains(&ident.name)\n                && ident.name != kw::SelfLower\n                && !ident.name.as_str().starts_with('_')\n            {\n                let usual_names = usual_names.iter().map(|name| format!(\"`{name}`\")).join(\" or \");\n                span_lint_and_help(\n                    cx,\n                    UNUSUAL_NAMES,\n                    ident.span,\n                    format!(\"unusual name for a {kind} of type `{ty_str}`\"),\n                    None,\n                    format!(\"prefer using {usual_names}\"),\n                );\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_test_deps/Cargo.lock",
    "content": "# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.\nversion = 4\n\n[[package]]\nname = \"addr2line\"\nversion = \"0.24.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1\"\ndependencies = [\n \"gimli\",\n]\n\n[[package]]\nname = \"adler2\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa\"\n\n[[package]]\nname = \"aho-corasick\"\nversion = \"1.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"autocfg\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8\"\n\n[[package]]\nname = \"backtrace\"\nversion = \"0.3.75\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002\"\ndependencies = [\n \"addr2line\",\n \"cfg-if\",\n \"libc\",\n \"miniz_oxide\",\n \"object\",\n \"rustc-demangle\",\n \"windows-targets\",\n]\n\n[[package]]\nname = \"bitflags\"\nversion = \"2.9.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967\"\n\n[[package]]\nname = \"bytes\"\nversion = \"1.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a\"\n\n[[package]]\nname = \"cfg-if\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268\"\n\n[[package]]\nname = \"clippy_test_deps\"\nversion = \"0.1.0\"\ndependencies = [\n \"futures\",\n \"itertools\",\n \"libc\",\n \"parking_lot\",\n \"quote\",\n \"regex\",\n \"serde\",\n \"syn\",\n \"tokio\",\n]\n\n[[package]]\nname = \"either\"\nversion = \"1.15.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719\"\n\n[[package]]\nname = \"futures\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-io\",\n \"futures-sink\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-channel\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n]\n\n[[package]]\nname = \"futures-core\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e\"\n\n[[package]]\nname = \"futures-executor\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f\"\ndependencies = [\n \"futures-core\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-io\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6\"\n\n[[package]]\nname = \"futures-macro\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn\",\n]\n\n[[package]]\nname = \"futures-sink\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7\"\n\n[[package]]\nname = \"futures-task\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988\"\n\n[[package]]\nname = \"futures-util\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-macro\",\n \"futures-sink\",\n \"futures-task\",\n \"memchr\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"slab\",\n]\n\n[[package]]\nname = \"gimli\"\nversion = \"0.31.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f\"\n\n[[package]]\nname = \"io-uring\"\nversion = \"0.7.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013\"\ndependencies = [\n \"bitflags\",\n \"cfg-if\",\n \"libc\",\n]\n\n[[package]]\nname = \"itertools\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569\"\ndependencies = [\n \"either\",\n]\n\n[[package]]\nname = \"libc\"\nversion = \"0.2.174\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776\"\n\n[[package]]\nname = \"lock_api\"\nversion = \"0.4.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765\"\ndependencies = [\n \"autocfg\",\n \"scopeguard\",\n]\n\n[[package]]\nname = \"memchr\"\nversion = \"2.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0\"\n\n[[package]]\nname = \"miniz_oxide\"\nversion = \"0.8.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316\"\ndependencies = [\n \"adler2\",\n]\n\n[[package]]\nname = \"mio\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c\"\ndependencies = [\n \"libc\",\n \"wasi\",\n \"windows-sys\",\n]\n\n[[package]]\nname = \"object\"\nversion = \"0.36.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"parking_lot\"\nversion = \"0.12.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13\"\ndependencies = [\n \"lock_api\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"parking_lot_core\"\nversion = \"0.9.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"redox_syscall\",\n \"smallvec\",\n \"windows-targets\",\n]\n\n[[package]]\nname = \"pin-project-lite\"\nversion = \"0.2.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b\"\n\n[[package]]\nname = \"pin-utils\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184\"\n\n[[package]]\nname = \"proc-macro2\"\nversion = \"1.0.95\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"quote\"\nversion = \"1.0.40\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d\"\ndependencies = [\n \"proc-macro2\",\n]\n\n[[package]]\nname = \"redox_syscall\"\nversion = \"0.5.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6\"\ndependencies = [\n \"bitflags\",\n]\n\n[[package]]\nname = \"regex\"\nversion = \"1.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-automata\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"regex-automata\"\nversion = \"0.4.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"regex-syntax\"\nversion = \"0.8.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c\"\n\n[[package]]\nname = \"rustc-demangle\"\nversion = \"0.1.25\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f\"\n\n[[package]]\nname = \"scopeguard\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\"\n\n[[package]]\nname = \"serde\"\nversion = \"1.0.219\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6\"\ndependencies = [\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_derive\"\nversion = \"1.0.219\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn\",\n]\n\n[[package]]\nname = \"slab\"\nversion = \"0.4.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589\"\n\n[[package]]\nname = \"smallvec\"\nversion = \"1.15.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03\"\n\n[[package]]\nname = \"syn\"\nversion = \"2.0.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"tokio\"\nversion = \"1.46.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17\"\ndependencies = [\n \"backtrace\",\n \"bytes\",\n \"io-uring\",\n \"libc\",\n \"mio\",\n \"pin-project-lite\",\n \"slab\",\n]\n\n[[package]]\nname = \"unicode-ident\"\nversion = \"1.0.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512\"\n\n[[package]]\nname = \"wasi\"\nversion = \"0.11.1+wasi-snapshot-preview1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\"\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.59.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b\"\ndependencies = [\n \"windows-targets\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973\"\ndependencies = [\n \"windows_aarch64_gnullvm\",\n \"windows_aarch64_msvc\",\n \"windows_i686_gnu\",\n \"windows_i686_gnullvm\",\n \"windows_i686_msvc\",\n \"windows_x86_64_gnu\",\n \"windows_x86_64_gnullvm\",\n \"windows_x86_64_msvc\",\n]\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec\"\n"
  },
  {
    "path": "clippy_test_deps/Cargo.toml",
    "content": "[package]\nname = \"clippy_test_deps\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n# Add dependencies here to make them available in ui tests.\n\n[dependencies]\nlibc = \"0.2\"\nregex = \"1.5.5\"\nserde = { version = \"1.0.145\", features = [\"derive\"] }\nquote = \"1.0.25\"\nsyn = { version = \"2.0\", features = [\"full\"] }\nfutures = \"0.3\"\nparking_lot = \"0.12\"\ntokio = { version = \"1\", features = [\"io-util\"] }\nitertools = \"0.12\"\n\n# Make sure we are not part of the rustc workspace.\n[workspace]\n"
  },
  {
    "path": "clippy_test_deps/src/main.rs",
    "content": "fn main() {}\n"
  },
  {
    "path": "clippy_utils/Cargo.toml",
    "content": "[package]\nname = \"clippy_utils\"\nversion = \"0.1.96\"\nedition = \"2024\"\ndescription = \"Helpful tools for writing lints, provided as they are used in Clippy\"\nrepository = \"https://github.com/rust-lang/rust-clippy\"\nreadme = \"README.md\"\nlicense = \"MIT OR Apache-2.0\"\nkeywords = [\"clippy\", \"lint\", \"utils\"]\ncategories = [\"development-tools\"]\n\n[dependencies]\narrayvec = { version = \"0.7\", default-features = false }\nitertools = \"0.12\"\n# FIXME(f16_f128): remove when no longer needed for parsing\nrustc_apfloat = \"0.2.0\"\nserde = { version = \"1.0\", features = [\"derive\"] }\n\n[lints.rust.unexpected_cfgs]\nlevel = \"warn\"\ncheck-cfg = ['cfg(bootstrap)']\n\n[package.metadata.rust-analyzer]\n# This crate uses #[feature(rustc_private)]\nrustc_private = true\n"
  },
  {
    "path": "clippy_utils/README.md",
    "content": "# `clippy-utils`\n\nHelpful tools for writing lints, provided as they are used in Clippy.\n\n## Usage\n\nThis crate is only guaranteed to build with this `nightly` toolchain:\n\n<!-- begin autogenerated nightly -->\n```\nnightly-2026-03-05\n```\n<!-- end autogenerated nightly -->\n\nTo use `clippy-utils` in your lint, add the following to your `Cargo.toml`:\n\n```\nclippy_utils = \"0.1.XY\"\n```\n\n`XY` is the version of the nightly toolchain above and can be determined with `rustc +nightly-YYYY-MM-DD -V`.\n\n## :warning: Stability :warning:\n\nNo stability guarantees are made for this crate! Use at your own risk.\n\nFunction signatures can change or be removed without replacement without any prior notice.\n\n## LICENSE\n\n<!-- REUSE-IgnoreStart -->\n\nCopyright (c) The Rust Project Contributors\n\nLicensed under the Apache License, Version 2.0\n<[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0)> or the MIT license\n<[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT)>, at your option. Files in the project may\nnot be copied, modified, or distributed except according to those terms.\n\n<!-- REUSE-IgnoreEnd -->\n"
  },
  {
    "path": "clippy_utils/src/ast_utils/ident_iter.rs",
    "content": "use core::iter::FusedIterator;\nuse rustc_ast::visit::{Visitor, walk_attribute, walk_expr};\nuse rustc_ast::{Attribute, Expr};\nuse rustc_span::symbol::Ident;\n\npub struct IdentIter(std::vec::IntoIter<Ident>);\n\nimpl Iterator for IdentIter {\n    type Item = Ident;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.0.next()\n    }\n}\n\nimpl FusedIterator for IdentIter {}\n\nimpl From<&Expr> for IdentIter {\n    fn from(expr: &Expr) -> Self {\n        let mut visitor = IdentCollector::default();\n\n        walk_expr(&mut visitor, expr);\n\n        IdentIter(visitor.0.into_iter())\n    }\n}\n\nimpl From<&Attribute> for IdentIter {\n    fn from(attr: &Attribute) -> Self {\n        let mut visitor = IdentCollector::default();\n\n        walk_attribute(&mut visitor, attr);\n\n        IdentIter(visitor.0.into_iter())\n    }\n}\n\n#[derive(Default)]\nstruct IdentCollector(Vec<Ident>);\n\nimpl Visitor<'_> for IdentCollector {\n    fn visit_ident(&mut self, ident: &Ident) {\n        self.0.push(*ident);\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/ast_utils/mod.rs",
    "content": "//! Utilities for manipulating and extracting information from `rustc_ast::ast`.\n//!\n//! - The `eq_foobar` functions test for semantic equality but ignores `NodeId`s and `Span`s.\n\n#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]\n\nuse crate::{both, over};\nuse rustc_ast::{self as ast, *};\nuse rustc_span::symbol::Ident;\nuse std::mem;\n\npub mod ident_iter;\npub use ident_iter::IdentIter;\n\npub fn is_useless_with_eq_exprs(kind: BinOpKind) -> bool {\n    use BinOpKind::*;\n    matches!(\n        kind,\n        Sub | Div | Eq | Lt | Le | Gt | Ge | Ne | And | Or | BitXor | BitAnd | BitOr\n    )\n}\n\n/// Checks if each element in the first slice is contained within the latter as per `eq_fn`.\npub fn unordered_over<X, Y>(left: &[X], right: &[Y], mut eq_fn: impl FnMut(&X, &Y) -> bool) -> bool {\n    left.len() == right.len() && left.iter().all(|l| right.iter().any(|r| eq_fn(l, r)))\n}\n\npub fn eq_id(l: Ident, r: Ident) -> bool {\n    l.name == r.name\n}\n\npub fn eq_pat(l: &Pat, r: &Pat) -> bool {\n    use PatKind::*;\n    match (&l.kind, &r.kind) {\n        (Missing, _) | (_, Missing) => unreachable!(),\n        (Paren(l), _) => eq_pat(l, r),\n        (_, Paren(r)) => eq_pat(l, r),\n        (Wild, Wild) | (Rest, Rest) => true,\n        (Expr(l), Expr(r)) => eq_expr(l, r),\n        (Ident(b1, i1, s1), Ident(b2, i2, s2)) => {\n            b1 == b2 && eq_id(*i1, *i2) && both(s1.as_deref(), s2.as_deref(), eq_pat)\n        },\n        (Range(lf, lt, le), Range(rf, rt, re)) => {\n            eq_expr_opt(lf.as_deref(), rf.as_deref())\n                && eq_expr_opt(lt.as_deref(), rt.as_deref())\n                && eq_range_end(le.node, re.node)\n        },\n        (Box(l), Box(r)) => eq_pat(l, r),\n        (Ref(l, l_pin, l_mut), Ref(r, r_pin, r_mut)) => l_pin == r_pin && l_mut == r_mut && eq_pat(l, r),\n        (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, eq_pat),\n        (Path(lq, lp), Path(rq, rp)) => both(lq.as_deref(), rq.as_deref(), eq_qself) && eq_path(lp, rp),\n        (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => {\n            eq_maybe_qself(lqself.as_deref(), rqself.as_deref()) && eq_path(lp, rp) && over(lfs, rfs, eq_pat)\n        },\n        (Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => {\n            lr == rr\n                && eq_maybe_qself(lqself.as_deref(), rqself.as_deref())\n                && eq_path(lp, rp)\n                && unordered_over(lfs, rfs, eq_field_pat)\n        },\n        (Or(ls), Or(rs)) => unordered_over(ls, rs, eq_pat),\n        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_range_end(l: RangeEnd, r: RangeEnd) -> bool {\n    match (l, r) {\n        (RangeEnd::Excluded, RangeEnd::Excluded) => true,\n        (RangeEnd::Included(l), RangeEnd::Included(r)) => {\n            matches!(l, RangeSyntax::DotDotEq) == matches!(r, RangeSyntax::DotDotEq)\n        },\n        _ => false,\n    }\n}\n\npub fn eq_field_pat(l: &PatField, r: &PatField) -> bool {\n    l.is_placeholder == r.is_placeholder\n        && eq_id(l.ident, r.ident)\n        && eq_pat(&l.pat, &r.pat)\n        && over(&l.attrs, &r.attrs, eq_attr)\n}\n\npub fn eq_qself(l: &QSelf, r: &QSelf) -> bool {\n    l.position == r.position && eq_ty(&l.ty, &r.ty)\n}\n\npub fn eq_maybe_qself(l: Option<&QSelf>, r: Option<&QSelf>) -> bool {\n    match (l, r) {\n        (Some(l), Some(r)) => eq_qself(l, r),\n        (None, None) => true,\n        _ => false,\n    }\n}\n\npub fn eq_path(l: &Path, r: &Path) -> bool {\n    over(&l.segments, &r.segments, eq_path_seg)\n}\n\npub fn eq_path_seg(l: &PathSegment, r: &PathSegment) -> bool {\n    eq_id(l.ident, r.ident) && both(l.args.as_ref(), r.args.as_ref(), |l, r| eq_generic_args(l, r))\n}\n\npub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool {\n    match (l, r) {\n        (AngleBracketed(l), AngleBracketed(r)) => over(&l.args, &r.args, eq_angle_arg),\n        (Parenthesized(l), Parenthesized(r)) => {\n            over(&l.inputs, &r.inputs, |l, r| eq_ty(l, r)) && eq_fn_ret_ty(&l.output, &r.output)\n        },\n        _ => false,\n    }\n}\n\npub fn eq_angle_arg(l: &AngleBracketedArg, r: &AngleBracketedArg) -> bool {\n    match (l, r) {\n        (AngleBracketedArg::Arg(l), AngleBracketedArg::Arg(r)) => eq_generic_arg(l, r),\n        (AngleBracketedArg::Constraint(l), AngleBracketedArg::Constraint(r)) => eq_assoc_item_constraint(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_generic_arg(l: &GenericArg, r: &GenericArg) -> bool {\n    match (l, r) {\n        (GenericArg::Lifetime(l), GenericArg::Lifetime(r)) => eq_id(l.ident, r.ident),\n        (GenericArg::Type(l), GenericArg::Type(r)) => eq_ty(l, r),\n        (GenericArg::Const(l), GenericArg::Const(r)) => eq_expr(&l.value, &r.value),\n        _ => false,\n    }\n}\n\npub fn eq_expr_opt(l: Option<&Expr>, r: Option<&Expr>) -> bool {\n    both(l, r, eq_expr)\n}\n\npub fn eq_struct_rest(l: &StructRest, r: &StructRest) -> bool {\n    match (l, r) {\n        (StructRest::Base(lb), StructRest::Base(rb)) => eq_expr(lb, rb),\n        (StructRest::Rest(_), StructRest::Rest(_)) | (StructRest::None, StructRest::None) => true,\n        _ => false,\n    }\n}\n\n#[expect(clippy::too_many_lines, reason = \"big match statement\")]\npub fn eq_expr(l: &Expr, r: &Expr) -> bool {\n    use ExprKind::*;\n    if !over(&l.attrs, &r.attrs, eq_attr) {\n        return false;\n    }\n    match (&l.kind, &r.kind) {\n        (Paren(l), _) => eq_expr(l, r),\n        (_, Paren(r)) => eq_expr(l, r),\n        (Err(_), Err(_)) => true,\n        (Dummy, _) | (_, Dummy) => unreachable!(\"comparing `ExprKind::Dummy`\"),\n        (Try(l), Try(r)) | (Await(l, _), Await(r, _)) => eq_expr(l, r),\n        (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)),\n        (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),\n        (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value),\n        (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)),\n        (\n            MethodCall(box ast::MethodCall {\n                seg: ls,\n                receiver: lr,\n                args: la,\n                ..\n            }),\n            MethodCall(box ast::MethodCall {\n                seg: rs,\n                receiver: rr,\n                args: ra,\n                ..\n            }),\n        ) => eq_path_seg(ls, rs) && eq_expr(lr, rr) && over(la, ra, |l, r| eq_expr(l, r)),\n        (Binary(lo, ll, lr), Binary(ro, rl, rr)) => lo.node == ro.node && eq_expr(ll, rl) && eq_expr(lr, rr),\n        (Unary(lo, l), Unary(ro, r)) => mem::discriminant(lo) == mem::discriminant(ro) && eq_expr(l, r),\n        (Lit(l), Lit(r)) => l == r,\n        (Cast(l, lt), Cast(r, rt)) | (Type(l, lt), Type(r, rt)) => eq_expr(l, r) && eq_ty(lt, rt),\n        (Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re),\n        (If(lc, lt, le), If(rc, rt, re)) => {\n            eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le.as_deref(), re.as_deref())\n        },\n        (While(lc, lt, ll), While(rc, rt, rl)) => {\n            eq_label(ll.as_ref(), rl.as_ref()) && eq_expr(lc, rc) && eq_block(lt, rt)\n        },\n        (\n            ForLoop {\n                pat: lp,\n                iter: li,\n                body: lt,\n                label: ll,\n                kind: lk,\n            },\n            ForLoop {\n                pat: rp,\n                iter: ri,\n                body: rt,\n                label: rl,\n                kind: rk,\n            },\n        ) => eq_label(ll.as_ref(), rl.as_ref()) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,\n        (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lt, rt),\n        (Block(lb, ll), Block(rb, rl)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lb, rb),\n        (TryBlock(lb, lt), TryBlock(rb, rt)) => eq_block(lb, rb) && both(lt.as_deref(), rt.as_deref(), eq_ty),\n        (Yield(l), Yield(r)) => eq_expr_opt(l.expr().map(Box::as_ref), r.expr().map(Box::as_ref)) && l.same_kind(r),\n        (Ret(l), Ret(r)) => eq_expr_opt(l.as_deref(), r.as_deref()),\n        (Break(ll, le), Break(rl, re)) => {\n            eq_label(ll.as_ref(), rl.as_ref()) && eq_expr_opt(le.as_deref(), re.as_deref())\n        },\n        (Continue(ll), Continue(rl)) => eq_label(ll.as_ref(), rl.as_ref()),\n        (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => {\n            eq_expr(l1, r1) && eq_expr(l2, r2)\n        },\n        (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),\n        (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),\n        (Match(ls, la, lkind), Match(rs, ra, rkind)) => (lkind == rkind) && eq_expr(ls, rs) && over(la, ra, eq_arm),\n        (\n            Closure(box ast::Closure {\n                binder: lb,\n                capture_clause: lc,\n                coroutine_kind: la,\n                movability: lm,\n                fn_decl: lf,\n                body: le,\n                ..\n            }),\n            Closure(box ast::Closure {\n                binder: rb,\n                capture_clause: rc,\n                coroutine_kind: ra,\n                movability: rm,\n                fn_decl: rf,\n                body: re,\n                ..\n            }),\n        ) => {\n            eq_closure_binder(lb, rb)\n                && lc == rc\n                && eq_coroutine_kind(*la, *ra)\n                && lm == rm\n                && eq_fn_decl(lf, rf)\n                && eq_expr(le, re)\n        },\n        (Gen(lc, lb, lk, _), Gen(rc, rb, rk, _)) => lc == rc && eq_block(lb, rb) && lk == rk,\n        (Range(lf, lt, ll), Range(rf, rt, rl)) => {\n            ll == rl && eq_expr_opt(lf.as_deref(), rf.as_deref()) && eq_expr_opt(lt.as_deref(), rt.as_deref())\n        },\n        (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re),\n        (Path(lq, lp), Path(rq, rp)) => both(lq.as_deref(), rq.as_deref(), eq_qself) && eq_path(lp, rp),\n        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),\n        (Struct(lse), Struct(rse)) => {\n            eq_maybe_qself(lse.qself.as_deref(), rse.qself.as_deref())\n                && eq_path(&lse.path, &rse.path)\n                && eq_struct_rest(&lse.rest, &rse.rest)\n                && unordered_over(&lse.fields, &rse.fields, eq_field)\n        },\n        _ => false,\n    }\n}\n\nfn eq_coroutine_kind(a: Option<CoroutineKind>, b: Option<CoroutineKind>) -> bool {\n    matches!(\n        (a, b),\n        (Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))\n            | (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))\n            | (\n                Some(CoroutineKind::AsyncGen { .. }),\n                Some(CoroutineKind::AsyncGen { .. })\n            )\n            | (None, None)\n    )\n}\n\npub fn eq_field(l: &ExprField, r: &ExprField) -> bool {\n    l.is_placeholder == r.is_placeholder\n        && eq_id(l.ident, r.ident)\n        && eq_expr(&l.expr, &r.expr)\n        && over(&l.attrs, &r.attrs, eq_attr)\n}\n\npub fn eq_arm(l: &Arm, r: &Arm) -> bool {\n    l.is_placeholder == r.is_placeholder\n        && eq_pat(&l.pat, &r.pat)\n        && eq_expr_opt(l.body.as_deref(), r.body.as_deref())\n        && eq_expr_opt(l.guard.as_deref(), r.guard.as_deref())\n        && over(&l.attrs, &r.attrs, eq_attr)\n}\n\npub fn eq_label(l: Option<&Label>, r: Option<&Label>) -> bool {\n    both(l, r, |l, r| eq_id(l.ident, r.ident))\n}\n\npub fn eq_block(l: &Block, r: &Block) -> bool {\n    l.rules == r.rules && over(&l.stmts, &r.stmts, eq_stmt)\n}\n\npub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool {\n    use StmtKind::*;\n    match (&l.kind, &r.kind) {\n        (Let(l), Let(r)) => {\n            eq_pat(&l.pat, &r.pat)\n                && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| eq_ty(l, r))\n                && eq_local_kind(&l.kind, &r.kind)\n                && over(&l.attrs, &r.attrs, eq_attr)\n        },\n        (Item(l), Item(r)) => eq_item(l, r, eq_item_kind),\n        (Expr(l), Expr(r)) | (Semi(l), Semi(r)) => eq_expr(l, r),\n        (Empty, Empty) => true,\n        (MacCall(l), MacCall(r)) => {\n            l.style == r.style && eq_mac_call(&l.mac, &r.mac) && over(&l.attrs, &r.attrs, eq_attr)\n        },\n        _ => false,\n    }\n}\n\npub fn eq_local_kind(l: &LocalKind, r: &LocalKind) -> bool {\n    use LocalKind::*;\n    match (l, r) {\n        (Decl, Decl) => true,\n        (Init(l), Init(r)) => eq_expr(l, r),\n        (InitElse(li, le), InitElse(ri, re)) => eq_expr(li, ri) && eq_block(le, re),\n        _ => false,\n    }\n}\n\npub fn eq_item<K>(l: &Item<K>, r: &Item<K>, mut eq_kind: impl FnMut(&K, &K) -> bool) -> bool {\n    over(&l.attrs, &r.attrs, eq_attr) && eq_vis(&l.vis, &r.vis) && eq_kind(&l.kind, &r.kind)\n}\n\n#[expect(clippy::too_many_lines, reason = \"big match statement\")]\npub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {\n    use ItemKind::*;\n    match (l, r) {\n        (ExternCrate(ls, li), ExternCrate(rs, ri)) => ls == rs && eq_id(*li, *ri),\n        (Use(l), Use(r)) => eq_use_tree(l, r),\n        (\n            Static(box StaticItem {\n                ident: li,\n                ty: lt,\n                mutability: lm,\n                expr: le,\n                safety: ls,\n                define_opaque: _,\n            }),\n            Static(box StaticItem {\n                ident: ri,\n                ty: rt,\n                mutability: rm,\n                expr: re,\n                safety: rs,\n                define_opaque: _,\n            }),\n        ) => eq_id(*li, *ri) && lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_deref(), re.as_deref()),\n        (\n            Const(box ConstItem {\n                defaultness: ld,\n                ident: li,\n                generics: lg,\n                ty: lt,\n                rhs_kind: lb,\n                define_opaque: _,\n            }),\n            Const(box ConstItem {\n                defaultness: rd,\n                ident: ri,\n                generics: rg,\n                ty: rt,\n                rhs_kind: rb,\n                define_opaque: _,\n            }),\n        ) => {\n            eq_defaultness(*ld, *rd)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && eq_ty(lt, rt)\n                && both(Some(lb), Some(rb), eq_const_item_rhs)\n        },\n        (\n            Fn(box ast::Fn {\n                defaultness: ld,\n                sig: lf,\n                ident: li,\n                generics: lg,\n                contract: lc,\n                body: lb,\n                define_opaque: _,\n                eii_impls: _,\n            }),\n            Fn(box ast::Fn {\n                defaultness: rd,\n                sig: rf,\n                ident: ri,\n                generics: rg,\n                contract: rc,\n                body: rb,\n                define_opaque: _,\n                eii_impls: _,\n            }),\n        ) => {\n            eq_defaultness(*ld, *rd)\n                && eq_fn_sig(lf, rf)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && eq_opt_fn_contract(lc, rc)\n                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))\n        },\n        (Mod(ls, li, lmk), Mod(rs, ri, rmk)) => {\n            ls == rs\n                && eq_id(*li, *ri)\n                && match (lmk, rmk) {\n                    (ModKind::Loaded(litems, linline, _), ModKind::Loaded(ritems, rinline, _)) => {\n                        linline == rinline && over(litems, ritems, |l, r| eq_item(l, r, eq_item_kind))\n                    },\n                    (ModKind::Unloaded, ModKind::Unloaded) => true,\n                    _ => false,\n                }\n        },\n        (ForeignMod(l), ForeignMod(r)) => {\n            both(l.abi.as_ref(), r.abi.as_ref(), eq_str_lit)\n                && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))\n        },\n        (\n            TyAlias(box ast::TyAlias {\n                defaultness: ld,\n                generics: lg,\n                bounds: lb,\n                ty: lt,\n                ..\n            }),\n            TyAlias(box ast::TyAlias {\n                defaultness: rd,\n                generics: rg,\n                bounds: rb,\n                ty: rt,\n                ..\n            }),\n        ) => {\n            eq_defaultness(*ld, *rd)\n                && eq_generics(lg, rg)\n                && over(lb, rb, eq_generic_bound)\n                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))\n        },\n        (Enum(li, lg, le), Enum(ri, rg, re)) => {\n            eq_id(*li, *ri) && eq_generics(lg, rg) && over(&le.variants, &re.variants, eq_variant)\n        },\n        (Struct(li, lg, lv), Struct(ri, rg, rv)) | (Union(li, lg, lv), Union(ri, rg, rv)) => {\n            eq_id(*li, *ri) && eq_generics(lg, rg) && eq_variant_data(lv, rv)\n        },\n        (\n            Trait(box ast::Trait {\n                constness: lc,\n                is_auto: la,\n                safety: lu,\n                impl_restriction: liprt,\n                ident: li,\n                generics: lg,\n                bounds: lb,\n                items: lis,\n            }),\n            Trait(box ast::Trait {\n                constness: rc,\n                is_auto: ra,\n                safety: ru,\n                impl_restriction: riprt,\n                ident: ri,\n                generics: rg,\n                bounds: rb,\n                items: ris,\n            }),\n        ) => {\n            matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)\n                && la == ra\n                && matches!(lu, Safety::Default) == matches!(ru, Safety::Default)\n                && eq_impl_restriction(liprt, riprt)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && over(lb, rb, eq_generic_bound)\n                && over(lis, ris, |l, r| eq_item(l, r, eq_assoc_item_kind))\n        },\n        (\n            TraitAlias(box ast::TraitAlias {\n                ident: li,\n                generics: lg,\n                bounds: lb,\n                constness: lc,\n            }),\n            TraitAlias(box ast::TraitAlias {\n                ident: ri,\n                generics: rg,\n                bounds: rb,\n                constness: rc,\n            }),\n        ) => {\n            matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && over(lb, rb, eq_generic_bound)\n        },\n        (\n            Impl(ast::Impl {\n                generics: lg,\n                of_trait: lot,\n                self_ty: lst,\n                items: li,\n                constness: lc,\n            }),\n            Impl(ast::Impl {\n                generics: rg,\n                of_trait: rot,\n                self_ty: rst,\n                items: ri,\n                constness: rc,\n            }),\n        ) => {\n            eq_generics(lg, rg)\n                && both(lot.as_deref(), rot.as_deref(), |l, r| {\n                    matches!(l.safety, Safety::Default) == matches!(r.safety, Safety::Default)\n                        && matches!(l.polarity, ImplPolarity::Positive) == matches!(r.polarity, ImplPolarity::Positive)\n                        && eq_defaultness(l.defaultness, r.defaultness)\n                        && matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)\n                        && eq_path(&l.trait_ref.path, &r.trait_ref.path)\n                })\n                && eq_ty(lst, rst)\n                && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))\n        },\n        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),\n        (MacroDef(li, ld), MacroDef(ri, rd)) => {\n            eq_id(*li, *ri) && ld.macro_rules == rd.macro_rules && eq_delim_args(&ld.body, &rd.body)\n        },\n        _ => false,\n    }\n}\n\npub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {\n    use ForeignItemKind::*;\n    match (l, r) {\n        (\n            Static(box StaticItem {\n                ident: li,\n                ty: lt,\n                mutability: lm,\n                expr: le,\n                safety: ls,\n                define_opaque: _,\n            }),\n            Static(box StaticItem {\n                ident: ri,\n                ty: rt,\n                mutability: rm,\n                expr: re,\n                safety: rs,\n                define_opaque: _,\n            }),\n        ) => eq_id(*li, *ri) && eq_ty(lt, rt) && lm == rm && eq_expr_opt(le.as_deref(), re.as_deref()) && ls == rs,\n        (\n            Fn(box ast::Fn {\n                defaultness: ld,\n                sig: lf,\n                ident: li,\n                generics: lg,\n                contract: lc,\n                body: lb,\n                define_opaque: _,\n                eii_impls: _,\n            }),\n            Fn(box ast::Fn {\n                defaultness: rd,\n                sig: rf,\n                ident: ri,\n                generics: rg,\n                contract: rc,\n                body: rb,\n                define_opaque: _,\n                eii_impls: _,\n            }),\n        ) => {\n            eq_defaultness(*ld, *rd)\n                && eq_fn_sig(lf, rf)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && eq_opt_fn_contract(lc, rc)\n                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))\n        },\n        (\n            TyAlias(box ast::TyAlias {\n                defaultness: ld,\n                ident: li,\n                generics: lg,\n                after_where_clause: lw,\n                bounds: lb,\n                ty: lt,\n            }),\n            TyAlias(box ast::TyAlias {\n                defaultness: rd,\n                ident: ri,\n                generics: rg,\n                after_where_clause: rw,\n                bounds: rb,\n                ty: rt,\n            }),\n        ) => {\n            eq_defaultness(*ld, *rd)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && over(&lw.predicates, &rw.predicates, eq_where_predicate)\n                && over(lb, rb, eq_generic_bound)\n                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))\n        },\n        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {\n    use AssocItemKind::*;\n    match (l, r) {\n        (\n            Const(box ConstItem {\n                defaultness: ld,\n                ident: li,\n                generics: lg,\n                ty: lt,\n                rhs_kind: lb,\n                define_opaque: _,\n            }),\n            Const(box ConstItem {\n                defaultness: rd,\n                ident: ri,\n                generics: rg,\n                ty: rt,\n                rhs_kind: rb,\n                define_opaque: _,\n            }),\n        ) => {\n            eq_defaultness(*ld, *rd)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && eq_ty(lt, rt)\n                && both(Some(lb), Some(rb), eq_const_item_rhs)\n        },\n        (\n            Fn(box ast::Fn {\n                defaultness: ld,\n                sig: lf,\n                ident: li,\n                generics: lg,\n                contract: lc,\n                body: lb,\n                define_opaque: _,\n                eii_impls: _,\n            }),\n            Fn(box ast::Fn {\n                defaultness: rd,\n                sig: rf,\n                ident: ri,\n                generics: rg,\n                contract: rc,\n                body: rb,\n                define_opaque: _,\n                eii_impls: _,\n            }),\n        ) => {\n            eq_defaultness(*ld, *rd)\n                && eq_fn_sig(lf, rf)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && eq_opt_fn_contract(lc, rc)\n                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))\n        },\n        (\n            Type(box TyAlias {\n                defaultness: ld,\n                ident: li,\n                generics: lg,\n                after_where_clause: lw,\n                bounds: lb,\n                ty: lt,\n            }),\n            Type(box TyAlias {\n                defaultness: rd,\n                ident: ri,\n                generics: rg,\n                after_where_clause: rw,\n                bounds: rb,\n                ty: rt,\n            }),\n        ) => {\n            eq_defaultness(*ld, *rd)\n                && eq_id(*li, *ri)\n                && eq_generics(lg, rg)\n                && over(&lw.predicates, &rw.predicates, eq_where_predicate)\n                && over(lb, rb, eq_generic_bound)\n                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))\n        },\n        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_variant(l: &Variant, r: &Variant) -> bool {\n    l.is_placeholder == r.is_placeholder\n        && over(&l.attrs, &r.attrs, eq_attr)\n        && eq_vis(&l.vis, &r.vis)\n        && eq_id(l.ident, r.ident)\n        && eq_variant_data(&l.data, &r.data)\n        && both(l.disr_expr.as_ref(), r.disr_expr.as_ref(), |l, r| {\n            eq_expr(&l.value, &r.value)\n        })\n}\n\npub fn eq_variant_data(l: &VariantData, r: &VariantData) -> bool {\n    use VariantData::*;\n    match (l, r) {\n        (Unit(_), Unit(_)) => true,\n        (Struct { fields: l, .. }, Struct { fields: r, .. }) | (Tuple(l, _), Tuple(r, _)) => {\n            over(l, r, eq_struct_field)\n        },\n        _ => false,\n    }\n}\n\npub fn eq_struct_field(l: &FieldDef, r: &FieldDef) -> bool {\n    l.is_placeholder == r.is_placeholder\n        && over(&l.attrs, &r.attrs, eq_attr)\n        && eq_vis(&l.vis, &r.vis)\n        && both(l.ident.as_ref(), r.ident.as_ref(), |l, r| eq_id(*l, *r))\n        && eq_ty(&l.ty, &r.ty)\n}\n\npub fn eq_fn_sig(l: &FnSig, r: &FnSig) -> bool {\n    eq_fn_decl(&l.decl, &r.decl) && eq_fn_header(&l.header, &r.header)\n}\n\nfn eq_opt_coroutine_kind(l: Option<CoroutineKind>, r: Option<CoroutineKind>) -> bool {\n    matches!(\n        (l, r),\n        (Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))\n            | (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))\n            | (\n                Some(CoroutineKind::AsyncGen { .. }),\n                Some(CoroutineKind::AsyncGen { .. })\n            )\n            | (None, None)\n    )\n}\n\npub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {\n    matches!(l.safety, Safety::Default) == matches!(r.safety, Safety::Default)\n        && eq_opt_coroutine_kind(l.coroutine_kind, r.coroutine_kind)\n        && matches!(l.constness, Const::No) == matches!(r.constness, Const::No)\n        && eq_ext(&l.ext, &r.ext)\n}\n\n#[expect(clippy::ref_option, reason = \"This is the type how it is stored in the AST\")]\npub fn eq_opt_fn_contract(l: &Option<Box<FnContract>>, r: &Option<Box<FnContract>>) -> bool {\n    match (l, r) {\n        (Some(l), Some(r)) => {\n            eq_expr_opt(l.requires.as_deref(), r.requires.as_deref())\n                && eq_expr_opt(l.ensures.as_deref(), r.ensures.as_deref())\n        },\n        (None, None) => true,\n        (Some(_), None) | (None, Some(_)) => false,\n    }\n}\n\npub fn eq_generics(l: &Generics, r: &Generics) -> bool {\n    over(&l.params, &r.params, eq_generic_param)\n        && over(&l.where_clause.predicates, &r.where_clause.predicates, |l, r| {\n            eq_where_predicate(l, r)\n        })\n}\n\npub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool {\n    use WherePredicateKind::*;\n    over(&l.attrs, &r.attrs, eq_attr)\n        && match (&l.kind, &r.kind) {\n            (BoundPredicate(l), BoundPredicate(r)) => {\n                over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {\n                    eq_generic_param(l, r)\n                }) && eq_ty(&l.bounded_ty, &r.bounded_ty)\n                    && over(&l.bounds, &r.bounds, eq_generic_bound)\n            },\n            (RegionPredicate(l), RegionPredicate(r)) => {\n                eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound)\n            },\n            (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty),\n            _ => false,\n        }\n}\n\npub fn eq_use_tree(l: &UseTree, r: &UseTree) -> bool {\n    eq_path(&l.prefix, &r.prefix) && eq_use_tree_kind(&l.kind, &r.kind)\n}\n\npub fn eq_anon_const(l: &AnonConst, r: &AnonConst) -> bool {\n    eq_expr(&l.value, &r.value)\n}\n\npub fn eq_const_item_rhs(l: &ConstItemRhsKind, r: &ConstItemRhsKind) -> bool {\n    use ConstItemRhsKind::*;\n    match (l, r) {\n        (TypeConst { rhs: Some(l) }, TypeConst { rhs: Some(r) }) => eq_anon_const(l, r),\n        (TypeConst { rhs: None }, TypeConst { rhs: None }) | (Body { rhs: None }, Body { rhs: None }) => true,\n        (Body { rhs: Some(l) }, Body { rhs: Some(r) }) => eq_expr(l, r),\n        (TypeConst { rhs: Some(..) }, TypeConst { rhs: None })\n        | (TypeConst { rhs: None }, TypeConst { rhs: Some(..) })\n        | (Body { rhs: None }, Body { rhs: Some(..) })\n        | (Body { rhs: Some(..) }, Body { rhs: None })\n        | (TypeConst { .. }, Body { .. })\n        | (Body { .. }, TypeConst { .. }) => false,\n    }\n}\n\npub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {\n    use UseTreeKind::*;\n    match (l, r) {\n        (Glob, Glob) => true,\n        (Simple(l), Simple(r)) => both(l.as_ref(), r.as_ref(), |l, r| eq_id(*l, *r)),\n        (Nested { items: l, .. }, Nested { items: r, .. }) => over(l, r, |(l, _), (r, _)| eq_use_tree(l, r)),\n        _ => false,\n    }\n}\n\npub fn eq_defaultness(l: Defaultness, r: Defaultness) -> bool {\n    matches!(\n        (l, r),\n        (Defaultness::Implicit, Defaultness::Implicit)\n            | (Defaultness::Default(_), Defaultness::Default(_))\n            | (Defaultness::Final(_), Defaultness::Final(_))\n    )\n}\n\npub fn eq_vis(l: &Visibility, r: &Visibility) -> bool {\n    use VisibilityKind::*;\n    match (&l.kind, &r.kind) {\n        (Public, Public) | (Inherited, Inherited) => true,\n        (Restricted { path: l, .. }, Restricted { path: r, .. }) => eq_path(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_impl_restriction(l: &ImplRestriction, r: &ImplRestriction) -> bool {\n    eq_restriction_kind(&l.kind, &r.kind)\n}\n\nfn eq_restriction_kind(l: &RestrictionKind, r: &RestrictionKind) -> bool {\n    match (l, r) {\n        (RestrictionKind::Unrestricted, RestrictionKind::Unrestricted) => true,\n        (\n            RestrictionKind::Restricted {\n                path: l_path,\n                shorthand: l_short,\n                id: _,\n            },\n            RestrictionKind::Restricted {\n                path: r_path,\n                shorthand: r_short,\n                id: _,\n            },\n        ) => l_short == r_short && eq_path(l_path, r_path),\n        _ => false,\n    }\n}\n\npub fn eq_fn_decl(l: &FnDecl, r: &FnDecl) -> bool {\n    eq_fn_ret_ty(&l.output, &r.output)\n        && over(&l.inputs, &r.inputs, |l, r| {\n            l.is_placeholder == r.is_placeholder\n                && eq_pat(&l.pat, &r.pat)\n                && eq_ty(&l.ty, &r.ty)\n                && over(&l.attrs, &r.attrs, eq_attr)\n        })\n}\n\npub fn eq_closure_binder(l: &ClosureBinder, r: &ClosureBinder) -> bool {\n    match (l, r) {\n        (ClosureBinder::NotPresent, ClosureBinder::NotPresent) => true,\n        (ClosureBinder::For { generic_params: lp, .. }, ClosureBinder::For { generic_params: rp, .. }) => {\n            lp.len() == rp.len() && std::iter::zip(lp.iter(), rp.iter()).all(|(l, r)| eq_generic_param(l, r))\n        },\n        _ => false,\n    }\n}\n\npub fn eq_fn_ret_ty(l: &FnRetTy, r: &FnRetTy) -> bool {\n    match (l, r) {\n        (FnRetTy::Default(_), FnRetTy::Default(_)) => true,\n        (FnRetTy::Ty(l), FnRetTy::Ty(r)) => eq_ty(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_ty(l: &Ty, r: &Ty) -> bool {\n    use TyKind::*;\n    match (&l.kind, &r.kind) {\n        (Paren(l), _) => eq_ty(l, r),\n        (_, Paren(r)) => eq_ty(l, r),\n        (Never, Never) | (Infer, Infer) | (ImplicitSelf, ImplicitSelf) | (Err(_), Err(_)) | (CVarArgs, CVarArgs) => {\n            true\n        },\n        (Slice(l), Slice(r)) => eq_ty(l, r),\n        (Array(le, ls), Array(re, rs)) => eq_ty(le, re) && eq_expr(&ls.value, &rs.value),\n        (Ptr(l), Ptr(r)) => l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty),\n        (Ref(ll, l), Ref(rl, r)) => {\n            both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)\n        },\n        (PinnedRef(ll, l), PinnedRef(rl, r)) => {\n            both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)\n        },\n        (FnPtr(l), FnPtr(r)) => {\n            l.safety == r.safety\n                && eq_ext(&l.ext, &r.ext)\n                && over(&l.generic_params, &r.generic_params, eq_generic_param)\n                && eq_fn_decl(&l.decl, &r.decl)\n        },\n        (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)),\n        (Path(lq, lp), Path(rq, rp)) => both(lq.as_deref(), rq.as_deref(), eq_qself) && eq_path(lp, rp),\n        (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, eq_generic_bound),\n        (ImplTrait(_, lg), ImplTrait(_, rg)) => over(lg, rg, eq_generic_bound),\n        (MacCall(l), MacCall(r)) => eq_mac_call(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_ext(l: &Extern, r: &Extern) -> bool {\n    use Extern::*;\n    match (l, r) {\n        (None, None) | (Implicit(_), Implicit(_)) => true,\n        (Explicit(l, _), Explicit(r, _)) => eq_str_lit(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_str_lit(l: &StrLit, r: &StrLit) -> bool {\n    l.style == r.style && l.symbol == r.symbol && l.suffix == r.suffix\n}\n\npub fn eq_poly_ref_trait(l: &PolyTraitRef, r: &PolyTraitRef) -> bool {\n    l.modifiers == r.modifiers\n        && eq_path(&l.trait_ref.path, &r.trait_ref.path)\n        && over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {\n            eq_generic_param(l, r)\n        })\n}\n\npub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {\n    use GenericParamKind::*;\n    l.is_placeholder == r.is_placeholder\n        && eq_id(l.ident, r.ident)\n        && over(&l.bounds, &r.bounds, eq_generic_bound)\n        && match (&l.kind, &r.kind) {\n            (Lifetime, Lifetime) => true,\n            (Type { default: l }, Type { default: r }) => both(l.as_ref(), r.as_ref(), |l, r| eq_ty(l, r)),\n            (\n                Const {\n                    ty: lt,\n                    default: ld,\n                    span: _,\n                },\n                Const {\n                    ty: rt,\n                    default: rd,\n                    span: _,\n                },\n            ) => eq_ty(lt, rt) && both(ld.as_ref(), rd.as_ref(), eq_anon_const),\n            _ => false,\n        }\n        && over(&l.attrs, &r.attrs, eq_attr)\n}\n\npub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool {\n    use GenericBound::*;\n    match (l, r) {\n        (Trait(ptr1), Trait(ptr2)) => eq_poly_ref_trait(ptr1, ptr2),\n        (Outlives(l), Outlives(r)) => eq_id(l.ident, r.ident),\n        _ => false,\n    }\n}\n\npub fn eq_precise_capture(l: &PreciseCapturingArg, r: &PreciseCapturingArg) -> bool {\n    match (l, r) {\n        (PreciseCapturingArg::Lifetime(l), PreciseCapturingArg::Lifetime(r)) => l.ident == r.ident,\n        (PreciseCapturingArg::Arg(l, _), PreciseCapturingArg::Arg(r, _)) => l.segments[0].ident == r.segments[0].ident,\n        _ => false,\n    }\n}\n\nfn eq_term(l: &Term, r: &Term) -> bool {\n    match (l, r) {\n        (Term::Ty(l), Term::Ty(r)) => eq_ty(l, r),\n        (Term::Const(l), Term::Const(r)) => eq_anon_const(l, r),\n        _ => false,\n    }\n}\n\npub fn eq_assoc_item_constraint(l: &AssocItemConstraint, r: &AssocItemConstraint) -> bool {\n    use AssocItemConstraintKind::*;\n    eq_id(l.ident, r.ident)\n        && match (&l.kind, &r.kind) {\n            (Equality { term: l }, Equality { term: r }) => eq_term(l, r),\n            (Bound { bounds: l }, Bound { bounds: r }) => over(l, r, eq_generic_bound),\n            _ => false,\n        }\n}\n\npub fn eq_mac_call(l: &MacCall, r: &MacCall) -> bool {\n    eq_path(&l.path, &r.path) && eq_delim_args(&l.args, &r.args)\n}\n\npub fn eq_attr(l: &Attribute, r: &Attribute) -> bool {\n    use AttrKind::*;\n    l.style == r.style\n        && match (&l.kind, &r.kind) {\n            (DocComment(l1, l2), DocComment(r1, r2)) => l1 == r1 && l2 == r2,\n            (Normal(l), Normal(r)) => {\n                eq_path(&l.item.path, &r.item.path) && eq_attr_item_kind(&l.item.args, &r.item.args)\n            },\n            _ => false,\n        }\n}\n\npub fn eq_attr_item_kind(l: &AttrItemKind, r: &AttrItemKind) -> bool {\n    match (l, r) {\n        (AttrItemKind::Unparsed(l), AttrItemKind::Unparsed(r)) => eq_attr_args(l, r),\n        (AttrItemKind::Parsed(_l), AttrItemKind::Parsed(_r)) => todo!(),\n        _ => false,\n    }\n}\n\npub fn eq_attr_args(l: &AttrArgs, r: &AttrArgs) -> bool {\n    use AttrArgs::*;\n    match (l, r) {\n        (Empty, Empty) => true,\n        (Delimited(la), Delimited(ra)) => eq_delim_args(la, ra),\n        (Eq { eq_span: _, expr: le }, Eq { eq_span: _, expr: re }) => eq_expr(le, re),\n        _ => false,\n    }\n}\n\npub fn eq_delim_args(l: &DelimArgs, r: &DelimArgs) -> bool {\n    l.delim == r.delim\n        && l.tokens.len() == r.tokens.len()\n        && l.tokens.iter().zip(r.tokens.iter()).all(|(a, b)| a.eq_unspanned(b))\n}\n"
  },
  {
    "path": "clippy_utils/src/attrs.rs",
    "content": "//! Utility functions for attributes, including Clippy's built-in ones\n\nuse crate::source::SpanRangeExt;\nuse crate::{sym, tokenize_with_text};\nuse rustc_ast::attr::AttributeExt;\nuse rustc_errors::Applicability;\nuse rustc_hir::find_attr;\nuse rustc_lexer::TokenKind;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{AdtDef, TyCtxt};\nuse rustc_session::Session;\nuse rustc_span::{Span, Symbol};\nuse std::str::FromStr;\n\n/// Given `attrs`, extract all the instances of a built-in Clippy attribute called `name`\npub fn get_builtin_attr<'a, A: AttributeExt + 'a>(\n    sess: &'a Session,\n    attrs: &'a [A],\n    name: Symbol,\n) -> impl Iterator<Item = &'a A> {\n    attrs.iter().filter(move |attr| {\n        if let [clippy, segment2] = &*attr.path()\n            && *clippy == sym::clippy\n        {\n            let path_span = attr\n                .path_span()\n                .expect(\"Clippy attributes are unparsed and have a span\");\n            let new_name = match *segment2 {\n                sym::cyclomatic_complexity => Some(\"cognitive_complexity\"),\n                sym::author\n                | sym::version\n                | sym::cognitive_complexity\n                | sym::dump\n                | sym::msrv\n                // The following attributes are for the 3rd party crate authors.\n                // See book/src/attribs.md\n                | sym::has_significant_drop\n                | sym::format_args => None,\n                _ => {\n                    sess.dcx().span_err(path_span, \"usage of unknown attribute\");\n                    return false;\n                },\n            };\n\n            match new_name {\n                Some(new_name) => {\n                    sess.dcx()\n                        .struct_span_err(path_span, \"usage of deprecated attribute\")\n                        .with_span_suggestion(\n                            path_span,\n                            \"consider using\",\n                            format!(\"clippy::{new_name}\"),\n                            Applicability::MachineApplicable,\n                        )\n                        .emit();\n                    false\n                },\n                None => *segment2 == name,\n            }\n        } else {\n            false\n        }\n    })\n}\n\n/// If `attrs` contain exactly one instance of a built-in Clippy attribute called `name`,\n/// returns that attribute, and `None` otherwise\npub fn get_unique_builtin_attr<'a, A: AttributeExt>(sess: &'a Session, attrs: &'a [A], name: Symbol) -> Option<&'a A> {\n    let mut unique_attr: Option<&A> = None;\n    for attr in get_builtin_attr(sess, attrs, name) {\n        if let Some(duplicate) = unique_attr {\n            sess.dcx()\n                .struct_span_err(attr.span(), format!(\"`{name}` is defined multiple times\"))\n                .with_span_note(duplicate.span(), \"first definition found here\")\n                .emit();\n        } else {\n            unique_attr = Some(attr);\n        }\n    }\n    unique_attr\n}\n\n/// Checks whether `attrs` contain any of `proc_macro`, `proc_macro_derive` or\n/// `proc_macro_attribute`\npub fn is_proc_macro(attrs: &[impl AttributeExt]) -> bool {\n    attrs.iter().any(AttributeExt::is_proc_macro_attr)\n}\n\n/// Checks whether `attrs` contain `#[doc(hidden)]`\npub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool {\n    attrs.iter().any(AttributeExt::is_doc_hidden)\n}\n\n/// Checks whether the given ADT, or any of its fields/variants, are marked as `#[non_exhaustive]`\npub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {\n    adt.is_variant_list_non_exhaustive()\n        || find_attr!(tcx, adt.did(), NonExhaustive(..))\n        || adt.variants().iter().any(|variant_def| {\n            variant_def.is_field_list_non_exhaustive() || find_attr!(tcx, variant_def.def_id, NonExhaustive(..))\n        })\n        || adt\n            .all_fields()\n            .any(|field_def| find_attr!(tcx, field_def.did, NonExhaustive(..)))\n}\n\n/// Checks whether the given span contains a `#[cfg(..)]` attribute\npub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {\n    s.check_source_text(cx, |src| {\n        let mut iter = tokenize_with_text(src);\n\n        // Search for the token sequence [`#`, `[`, `cfg`]\n        while iter.any(|(t, ..)| matches!(t, TokenKind::Pound)) {\n            let mut iter = iter.by_ref().skip_while(|(t, ..)| {\n                matches!(\n                    t,\n                    TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }\n                )\n            });\n            if matches!(iter.next(), Some((TokenKind::OpenBracket, ..)))\n                && matches!(iter.next(), Some((TokenKind::Ident, \"cfg\", _)))\n            {\n                return true;\n            }\n        }\n        false\n    })\n}\n\n/// Currently used to keep track of the current value of `#[clippy::cognitive_complexity(N)]`\npub struct LimitStack {\n    default: u64,\n    stack: Vec<u64>,\n}\n\nimpl Drop for LimitStack {\n    fn drop(&mut self) {\n        debug_assert_eq!(self.stack, Vec::<u64>::new()); // avoid `.is_empty()`, for a nicer error message\n    }\n}\n\n#[expect(missing_docs, reason = \"they're all trivial...\")]\nimpl LimitStack {\n    #[must_use]\n    /// Initialize the stack starting with a default value, which usually comes from configuration\n    pub fn new(limit: u64) -> Self {\n        Self {\n            default: limit,\n            stack: vec![],\n        }\n    }\n    pub fn limit(&self) -> u64 {\n        self.stack.last().copied().unwrap_or(self.default)\n    }\n    pub fn push_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: Symbol) {\n        let stack = &mut self.stack;\n        parse_attrs(sess, attrs, name, |val| stack.push(val));\n    }\n    pub fn pop_attrs(&mut self, sess: &Session, attrs: &[impl AttributeExt], name: Symbol) {\n        let stack = &mut self.stack;\n        parse_attrs(sess, attrs, name, |val| {\n            let popped = stack.pop();\n            debug_assert_eq!(popped, Some(val));\n        });\n    }\n}\n\nfn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[impl AttributeExt], name: Symbol, mut f: F) {\n    for attr in get_builtin_attr(sess, attrs, name) {\n        let Some(value) = attr.value_str() else {\n            sess.dcx().span_err(attr.span(), \"bad clippy attribute\");\n            continue;\n        };\n        let Ok(value) = u64::from_str(value.as_str()) else {\n            sess.dcx().span_err(attr.span(), \"not a number\");\n            continue;\n        };\n        f(value);\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/check_proc_macro.rs",
    "content": "//! This module handles checking if the span given is from a proc-macro or not.\n//!\n//! Proc-macros are capable of setting the span of every token they output to a few possible spans.\n//! This includes spans we can detect easily as coming from a proc-macro (e.g. the call site\n//! or the def site), and spans we can't easily detect as such (e.g. the span of any token\n//! passed into the proc macro). This capability means proc-macros are capable of generating code\n//! with a span that looks like it was written by the user, but which should not be linted by clippy\n//! as it was generated by an external macro.\n//!\n//! That brings us to this module. The current approach is to determine a small bit of text which\n//! must exist at both the start and the end of an item (e.g. an expression or a path) assuming the\n//! code was written, and check if the span contains that text. Note this will only work correctly\n//! if the span is not from a `macro_rules` based macro.\n\nuse rustc_abi::ExternAbi;\nuse rustc_ast as ast;\nuse rustc_ast::AttrStyle;\nuse rustc_ast::ast::{\n    AttrKind, Attribute, GenericArgs, IntTy, LitIntType, LitKind, StrStyle, TraitObjectSyntax, UintTy,\n};\nuse rustc_ast::token::CommentKind;\nuse rustc_hir::intravisit::FnKind;\nuse rustc_hir::{\n    Block, BlockCheckMode, Body, BoundConstness, BoundPolarity, Closure, Destination, Expr, ExprKind, FieldDef,\n    FnHeader, FnRetTy, HirId, Impl, ImplItem, ImplItemImplKind, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource,\n    MatchSource, MutTy, Node, Path, PolyTraitRef, QPath, Safety, TraitBoundModifiers, TraitImplHeader, TraitItem,\n    TraitItemKind, TraitRef, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource,\n};\nuse rustc_lint::{EarlyContext, LateContext, LintContext};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::Session;\nuse rustc_span::symbol::{Ident, kw};\nuse rustc_span::{Span, Symbol, sym};\n\n/// The search pattern to look for. Used by `span_matches_pat`\n#[derive(Clone)]\npub enum Pat {\n    /// A single string.\n    Str(&'static str),\n    /// Any of the given strings.\n    MultiStr(&'static [&'static str]),\n    /// Any of the given strings.\n    OwnedMultiStr(Vec<String>),\n    /// The string representation of the symbol.\n    Sym(Symbol),\n    /// Any decimal or hexadecimal digit depending on the location.\n    Num,\n    /// An attribute.\n    Attr(Symbol),\n}\n\n/// Checks if the start and the end of the span's text matches the patterns. This will return false\n/// if the span crosses multiple files or if source is not available.\nfn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) -> bool {\n    let pos = sess.source_map().lookup_byte_offset(span.lo());\n    let Some(ref src) = pos.sf.src else {\n        return false;\n    };\n    let end = span.hi() - pos.sf.start_pos;\n    src.get(pos.pos.0 as usize..end.0 as usize).is_some_and(|s| {\n        // Spans can be wrapped in a mixture or parenthesis, whitespace, and trailing commas.\n        let start_str = s.trim_start_matches(|c: char| c.is_whitespace() || c == '(');\n        let end_str = s.trim_end_matches(|c: char| c.is_whitespace() || c == ')' || c == ',');\n        (match start_pat {\n            Pat::Str(text) => start_str.starts_with(text),\n            Pat::MultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),\n            Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),\n            Pat::Sym(sym) => start_str.starts_with(sym.as_str()),\n            Pat::Num => start_str.as_bytes().first().is_some_and(u8::is_ascii_digit),\n            Pat::Attr(sym) => {\n                let start_str = start_str\n                    .strip_prefix(\"#[\")\n                    .or_else(|| start_str.strip_prefix(\"#![\"))\n                    .unwrap_or(start_str);\n                start_str.trim_start().starts_with(sym.as_str())\n            },\n        } && match end_pat {\n            Pat::Str(text) => end_str.ends_with(text),\n            Pat::MultiStr(texts) => texts.iter().any(|s| end_str.ends_with(s)),\n            Pat::OwnedMultiStr(texts) => texts.iter().any(|s| end_str.ends_with(s)),\n            Pat::Sym(sym) => end_str.ends_with(sym.as_str()),\n            Pat::Num => end_str.as_bytes().last().is_some_and(u8::is_ascii_hexdigit),\n            Pat::Attr(_) => false,\n        })\n    })\n}\n\n/// Get the search patterns to use for the given literal\nfn lit_search_pat(lit: &LitKind) -> (Pat, Pat) {\n    match lit {\n        LitKind::Str(_, StrStyle::Cooked) => (Pat::Str(\"\\\"\"), Pat::Str(\"\\\"\")),\n        LitKind::Str(_, StrStyle::Raw(0)) => (Pat::Str(\"r\"), Pat::Str(\"\\\"\")),\n        LitKind::Str(_, StrStyle::Raw(_)) => (Pat::Str(\"r#\"), Pat::Str(\"#\")),\n        LitKind::ByteStr(_, StrStyle::Cooked) => (Pat::Str(\"b\\\"\"), Pat::Str(\"\\\"\")),\n        LitKind::ByteStr(_, StrStyle::Raw(0)) => (Pat::Str(\"br\\\"\"), Pat::Str(\"\\\"\")),\n        LitKind::ByteStr(_, StrStyle::Raw(_)) => (Pat::Str(\"br#\\\"\"), Pat::Str(\"#\")),\n        LitKind::Byte(_) => (Pat::Str(\"b'\"), Pat::Str(\"'\")),\n        LitKind::Char(_) => (Pat::Str(\"'\"), Pat::Str(\"'\")),\n        LitKind::Int(_, LitIntType::Signed(IntTy::Isize)) => (Pat::Num, Pat::Str(\"isize\")),\n        LitKind::Int(_, LitIntType::Unsigned(UintTy::Usize)) => (Pat::Num, Pat::Str(\"usize\")),\n        LitKind::Int(..) => (Pat::Num, Pat::Num),\n        LitKind::Float(..) => (Pat::Num, Pat::Str(\"\")),\n        LitKind::Bool(true) => (Pat::Str(\"true\"), Pat::Str(\"true\")),\n        LitKind::Bool(false) => (Pat::Str(\"false\"), Pat::Str(\"false\")),\n        _ => (Pat::Str(\"\"), Pat::Str(\"\")),\n    }\n}\n\n/// Get the search patterns to use for the given path\nfn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) {\n    match path {\n        QPath::Resolved(ty, path) => {\n            let start = if ty.is_some() {\n                Pat::Str(\"<\")\n            } else {\n                path.segments.first().map_or(Pat::Str(\"\"), |seg| {\n                    if seg.ident.name == kw::PathRoot {\n                        Pat::Str(\"::\")\n                    } else {\n                        Pat::Sym(seg.ident.name)\n                    }\n                })\n            };\n            let end = path.segments.last().map_or(Pat::Str(\"\"), |seg| {\n                if seg.args.is_some() {\n                    Pat::Str(\">\")\n                } else {\n                    Pat::Sym(seg.ident.name)\n                }\n            });\n            (start, end)\n        },\n        QPath::TypeRelative(_, name) => (Pat::Str(\"\"), Pat::Sym(name.ident.name)),\n    }\n}\n\nfn path_search_pat(path: &Path<'_>) -> (Pat, Pat) {\n    let (head, tail) = match path.segments {\n        [] => return (Pat::Str(\"\"), Pat::Str(\"\")),\n        [p] => (Pat::Sym(p.ident.name), p),\n        // QPath::Resolved can have a path that looks like `<Foo as Bar>::baz` where\n        // the path (`Bar::baz`) has it's span covering the whole QPath.\n        [.., tail] => (Pat::Str(\"\"), tail),\n    };\n    (\n        head,\n        if tail.args.is_some() {\n            Pat::Str(\">\")\n        } else {\n            Pat::Sym(tail.ident.name)\n        },\n    )\n}\n\n/// Get the search patterns to use for the given expression\nfn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {\n    fn expr_search_pat_inner(tcx: TyCtxt<'_>, e: &Expr<'_>, outer_span: Span) -> (Pat, Pat) {\n        // The expression can have subexpressions in different contexts, in which case\n        // building up a search pattern from the macro expansion would lead to false positives;\n        // e.g. `return format!(..)` would be considered to be from a proc macro\n        // if we build up a pattern for the macro expansion and compare it to the invocation `format!()`.\n        // So instead we return an empty pattern such that `span_matches_pat` always returns true.\n        if !e.span.eq_ctxt(outer_span) {\n            return (Pat::Str(\"\"), Pat::Str(\"\"));\n        }\n\n        match e.kind {\n            ExprKind::ConstBlock(_) => (Pat::Str(\"const\"), Pat::Str(\"}\")),\n            // Parenthesis are trimmed from the text before the search patterns are matched.\n            // See: `span_matches_pat`\n            ExprKind::Tup([]) => (Pat::Str(\")\"), Pat::Str(\"(\")),\n            ExprKind::Unary(UnOp::Deref, e) => (Pat::Str(\"*\"), expr_search_pat_inner(tcx, e, outer_span).1),\n            ExprKind::Unary(UnOp::Not, e) => (Pat::Str(\"!\"), expr_search_pat_inner(tcx, e, outer_span).1),\n            ExprKind::Unary(UnOp::Neg, e) => (Pat::Str(\"-\"), expr_search_pat_inner(tcx, e, outer_span).1),\n            ExprKind::Lit(lit) => lit_search_pat(&lit.node),\n            ExprKind::Array(_) | ExprKind::Repeat(..) => (Pat::Str(\"[\"), Pat::Str(\"]\")),\n            ExprKind::Call(e, []) | ExprKind::MethodCall(_, e, [], _) => {\n                (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str(\"(\"))\n            },\n            ExprKind::Call(first, [.., last])\n            | ExprKind::MethodCall(_, first, [.., last], _)\n            | ExprKind::Binary(_, first, last)\n            | ExprKind::Tup([first, .., last])\n            | ExprKind::Assign(first, last, _)\n            | ExprKind::AssignOp(_, first, last) => (\n                expr_search_pat_inner(tcx, first, outer_span).0,\n                expr_search_pat_inner(tcx, last, outer_span).1,\n            ),\n            ExprKind::Tup([e]) | ExprKind::DropTemps(e) => expr_search_pat_inner(tcx, e, outer_span),\n            ExprKind::Cast(e, _) | ExprKind::Type(e, _) => (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str(\"\")),\n            ExprKind::Let(let_expr) => (Pat::Str(\"let\"), expr_search_pat_inner(tcx, let_expr.init, outer_span).1),\n            ExprKind::If(..) => (Pat::Str(\"if\"), Pat::Str(\"}\")),\n            ExprKind::Loop(_, Some(_), _, _) | ExprKind::Block(_, Some(_)) => (Pat::Str(\"'\"), Pat::Str(\"}\")),\n            ExprKind::Loop(_, None, LoopSource::Loop, _) => (Pat::Str(\"loop\"), Pat::Str(\"}\")),\n            ExprKind::Loop(_, None, LoopSource::While, _) => (Pat::Str(\"while\"), Pat::Str(\"}\")),\n            ExprKind::Loop(_, None, LoopSource::ForLoop, _) | ExprKind::Match(_, _, MatchSource::ForLoopDesugar) => {\n                (Pat::Str(\"for\"), Pat::Str(\"}\"))\n            },\n            ExprKind::Match(_, _, MatchSource::Normal) => (Pat::Str(\"match\"), Pat::Str(\"}\")),\n            ExprKind::Match(e, _, MatchSource::TryDesugar(_)) => {\n                (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str(\"?\"))\n            },\n            ExprKind::Match(e, _, MatchSource::AwaitDesugar) | ExprKind::Yield(e, YieldSource::Await { .. }) => {\n                (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str(\"await\"))\n            },\n            ExprKind::Closure(&Closure { body, .. }) => (\n                Pat::Str(\"\"),\n                expr_search_pat_inner(tcx, tcx.hir_body(body).value, outer_span).1,\n            ),\n            ExprKind::Block(\n                Block {\n                    rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),\n                    ..\n                },\n                None,\n            ) => (Pat::Str(\"unsafe\"), Pat::Str(\"}\")),\n            ExprKind::Block(_, None) => (Pat::Str(\"{\"), Pat::Str(\"}\")),\n            ExprKind::Field(e, name) => (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Sym(name.name)),\n            ExprKind::Index(e, _, _) => (expr_search_pat_inner(tcx, e, outer_span).0, Pat::Str(\"]\")),\n            ExprKind::Path(ref path) => qpath_search_pat(path),\n            ExprKind::AddrOf(_, _, e) => (Pat::Str(\"&\"), expr_search_pat_inner(tcx, e, outer_span).1),\n            ExprKind::Break(Destination { label: None, .. }, None) => (Pat::Str(\"break\"), Pat::Str(\"break\")),\n            ExprKind::Break(Destination { label: Some(name), .. }, None) => {\n                (Pat::Str(\"break\"), Pat::Sym(name.ident.name))\n            },\n            ExprKind::Break(_, Some(e)) => (Pat::Str(\"break\"), expr_search_pat_inner(tcx, e, outer_span).1),\n            ExprKind::Continue(Destination { label: None, .. }) => (Pat::Str(\"continue\"), Pat::Str(\"continue\")),\n            ExprKind::Continue(Destination { label: Some(name), .. }) => {\n                (Pat::Str(\"continue\"), Pat::Sym(name.ident.name))\n            },\n            ExprKind::Ret(None) => (Pat::Str(\"return\"), Pat::Str(\"return\")),\n            ExprKind::Ret(Some(e)) => (Pat::Str(\"return\"), expr_search_pat_inner(tcx, e, outer_span).1),\n            ExprKind::Struct(path, _, _) => (qpath_search_pat(path).0, Pat::Str(\"}\")),\n            ExprKind::Yield(e, YieldSource::Yield) => (Pat::Str(\"yield\"), expr_search_pat_inner(tcx, e, outer_span).1),\n            _ => (Pat::Str(\"\"), Pat::Str(\"\")),\n        }\n    }\n\n    expr_search_pat_inner(tcx, e, e.span)\n}\n\nfn fn_header_search_pat(header: FnHeader) -> Pat {\n    if header.is_async() {\n        Pat::Str(\"async\")\n    } else if header.is_const() {\n        Pat::Str(\"const\")\n    } else if header.is_unsafe() {\n        Pat::Str(\"unsafe\")\n    } else if header.abi != ExternAbi::Rust {\n        Pat::Str(\"extern\")\n    } else {\n        Pat::MultiStr(&[\"fn\", \"extern\"])\n    }\n}\n\nfn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {\n    let (start_pat, end_pat) = match &item.kind {\n        ItemKind::ExternCrate(..) => (Pat::Str(\"extern\"), Pat::Str(\";\")),\n        ItemKind::Static(..) => (Pat::Str(\"static\"), Pat::Str(\";\")),\n        ItemKind::Const(..) => (Pat::Str(\"const\"), Pat::Str(\";\")),\n        ItemKind::Fn { sig, .. } => (fn_header_search_pat(sig.header), Pat::Str(\"\")),\n        ItemKind::ForeignMod { .. } => (Pat::Str(\"extern\"), Pat::Str(\"}\")),\n        ItemKind::TyAlias(..) => (Pat::Str(\"type\"), Pat::Str(\";\")),\n        ItemKind::Enum(..) => (Pat::Str(\"enum\"), Pat::Str(\"}\")),\n        ItemKind::Struct(_, _, VariantData::Struct { .. }) => (Pat::Str(\"struct\"), Pat::Str(\"}\")),\n        ItemKind::Struct(..) => (Pat::Str(\"struct\"), Pat::Str(\";\")),\n        ItemKind::Union(..) => (Pat::Str(\"union\"), Pat::Str(\"}\")),\n        ItemKind::Trait(_, _, Safety::Unsafe, ..)\n        | ItemKind::Impl(Impl {\n            of_trait: Some(TraitImplHeader {\n                safety: Safety::Unsafe, ..\n            }),\n            ..\n        }) => (Pat::Str(\"unsafe\"), Pat::Str(\"}\")),\n        ItemKind::Trait(_, IsAuto::Yes, ..) => (Pat::Str(\"auto\"), Pat::Str(\"}\")),\n        ItemKind::Trait(..) => (Pat::Str(\"trait\"), Pat::Str(\"}\")),\n        ItemKind::Impl(_) => (Pat::Str(\"impl\"), Pat::Str(\"}\")),\n        ItemKind::Mod(..) => (Pat::Str(\"mod\"), Pat::Str(\"\")),\n        ItemKind::Macro(_, def, _) => (\n            Pat::Str(if def.macro_rules { \"macro_rules\" } else { \"macro\" }),\n            Pat::Str(\"\"),\n        ),\n        ItemKind::TraitAlias(..) => (Pat::Str(\"trait\"), Pat::Str(\";\")),\n        ItemKind::GlobalAsm { .. } => return (Pat::Str(\"global_asm\"), Pat::Str(\"\")),\n        ItemKind::Use(..) => return (Pat::Str(\"\"), Pat::Str(\"\")),\n    };\n    if item.vis_span.is_empty() {\n        (start_pat, end_pat)\n    } else {\n        (Pat::Str(\"pub\"), end_pat)\n    }\n}\n\nfn trait_item_search_pat(item: &TraitItem<'_>) -> (Pat, Pat) {\n    match &item.kind {\n        TraitItemKind::Const(..) => (Pat::Str(\"const\"), Pat::Str(\";\")),\n        TraitItemKind::Type(..) => (Pat::Str(\"type\"), Pat::Str(\";\")),\n        TraitItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str(\"\")),\n    }\n}\n\nfn impl_item_search_pat(item: &ImplItem<'_>) -> (Pat, Pat) {\n    let (mut start_pat, end_pat) = match &item.kind {\n        ImplItemKind::Const(..) => (Pat::Str(\"const\"), Pat::Str(\";\")),\n        ImplItemKind::Type(..) => (Pat::Str(\"type\"), Pat::Str(\";\")),\n        ImplItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str(\"\")),\n    };\n    if let ImplItemImplKind::Inherent { vis_span, .. } = item.impl_kind\n        && !vis_span.is_empty()\n    {\n        start_pat = Pat::Str(\"pub\");\n    }\n    (start_pat, end_pat)\n}\n\nfn field_def_search_pat(def: &FieldDef<'_>) -> (Pat, Pat) {\n    if def.vis_span.is_empty() {\n        if def.is_positional() {\n            (Pat::Str(\"\"), Pat::Str(\"\"))\n        } else {\n            (Pat::Sym(def.ident.name), Pat::Str(\"\"))\n        }\n    } else {\n        (Pat::Str(\"pub\"), Pat::Str(\"\"))\n    }\n}\n\nfn variant_search_pat(v: &Variant<'_>) -> (Pat, Pat) {\n    match v.data {\n        VariantData::Struct { .. } => (Pat::Sym(v.ident.name), Pat::Str(\"}\")),\n        VariantData::Tuple(..) => (Pat::Sym(v.ident.name), Pat::Str(\"\")),\n        VariantData::Unit(..) => (Pat::Sym(v.ident.name), Pat::Sym(v.ident.name)),\n    }\n}\n\nfn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirId) -> (Pat, Pat) {\n    let (mut start_pat, end_pat) = match kind {\n        FnKind::ItemFn(.., header) => (fn_header_search_pat(*header), Pat::Str(\"\")),\n        FnKind::Method(.., sig) => (fn_header_search_pat(sig.header), Pat::Str(\"\")),\n        FnKind::Closure => return (Pat::Str(\"\"), expr_search_pat(tcx, body.value).1),\n    };\n    match tcx.hir_node(hir_id) {\n        Node::Item(Item { vis_span, .. })\n        | Node::ImplItem(ImplItem {\n            impl_kind: ImplItemImplKind::Inherent { vis_span, .. },\n            ..\n        }) => {\n            if !vis_span.is_empty() {\n                start_pat = Pat::Str(\"pub\");\n            }\n        },\n        Node::ImplItem(_) | Node::TraitItem(_) => {},\n        _ => start_pat = Pat::Str(\"\"),\n    }\n    (start_pat, end_pat)\n}\n\nfn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {\n    match attr.kind {\n        AttrKind::Normal(..) => {\n            if let Some(name) = attr.name() {\n                // NOTE: This will likely have false positives, like `allow = 1`\n                (Pat::Attr(name), Pat::Str(\"\"))\n            } else {\n                (Pat::Str(\"#\"), Pat::Str(\"]\"))\n            }\n        },\n        AttrKind::DocComment(_kind @ CommentKind::Line, ..) => {\n            if attr.style == AttrStyle::Outer {\n                (Pat::Str(\"///\"), Pat::Str(\"\"))\n            } else {\n                (Pat::Str(\"//!\"), Pat::Str(\"\"))\n            }\n        },\n        AttrKind::DocComment(_kind @ CommentKind::Block, ..) => {\n            if attr.style == AttrStyle::Outer {\n                (Pat::Str(\"/**\"), Pat::Str(\"*/\"))\n            } else {\n                (Pat::Str(\"/*!\"), Pat::Str(\"*/\"))\n            }\n        },\n    }\n}\n\nfn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {\n    match ty.kind {\n        TyKind::Slice(..) | TyKind::Array(..) => (Pat::Str(\"[\"), Pat::Str(\"]\")),\n        TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str(\"*\"), ty_search_pat(ty).1),\n        TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str(\"&\"), ty_search_pat(ty).1),\n        TyKind::FnPtr(fn_ptr) => (\n            if fn_ptr.safety.is_unsafe() {\n                Pat::Str(\"unsafe\")\n            } else if fn_ptr.abi != ExternAbi::Rust {\n                Pat::Str(\"extern\")\n            } else {\n                Pat::MultiStr(&[\"fn\", \"extern\"])\n            },\n            match fn_ptr.decl.output {\n                FnRetTy::DefaultReturn(_) => {\n                    if let [.., ty] = fn_ptr.decl.inputs {\n                        ty_search_pat(ty).1\n                    } else {\n                        Pat::Str(\"(\")\n                    }\n                },\n                FnRetTy::Return(ty) => ty_search_pat(ty).1,\n            },\n        ),\n        TyKind::Never => (Pat::Str(\"!\"), Pat::Str(\"!\")),\n        // Parenthesis are trimmed from the text before the search patterns are matched.\n        // See: `span_matches_pat`\n        TyKind::Tup([]) => (Pat::Str(\")\"), Pat::Str(\"(\")),\n        TyKind::Tup([ty]) => ty_search_pat(ty),\n        TyKind::Tup([head, .., tail]) => (ty_search_pat(head).0, ty_search_pat(tail).1),\n        TyKind::OpaqueDef(..) => (Pat::Str(\"impl\"), Pat::Str(\"\")),\n        TyKind::Path(qpath) => qpath_search_pat(&qpath),\n        TyKind::Infer(()) => (Pat::Str(\"_\"), Pat::Str(\"_\")),\n        TyKind::UnsafeBinder(binder_ty) => (Pat::Str(\"unsafe\"), ty_search_pat(binder_ty.inner_ty).1),\n        TyKind::TraitObject(_, tagged_ptr) if let TraitObjectSyntax::Dyn = tagged_ptr.tag() => {\n            (Pat::Str(\"dyn\"), Pat::Str(\"\"))\n        },\n        // NOTE: `TraitObject` is incomplete. It will always return true then.\n        _ => (Pat::Str(\"\"), Pat::Str(\"\")),\n    }\n}\n\nfn ast_ty_search_pat(ty: &ast::Ty) -> (Pat, Pat) {\n    use ast::{Extern, FnRetTy, MutTy, Safety, TraitObjectSyntax, TyKind};\n\n    match &ty.kind {\n        TyKind::Slice(..) | TyKind::Array(..) => (Pat::Str(\"[\"), Pat::Str(\"]\")),\n        TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str(\"*\"), ast_ty_search_pat(ty).1),\n        TyKind::Ref(_, MutTy { ty, .. }) | TyKind::PinnedRef(_, MutTy { ty, .. }) => {\n            (Pat::Str(\"&\"), ast_ty_search_pat(ty).1)\n        },\n        TyKind::FnPtr(fn_ptr) => (\n            if let Safety::Unsafe(_) = fn_ptr.safety {\n                Pat::Str(\"unsafe\")\n            } else if let Extern::Explicit(strlit, _) = fn_ptr.ext\n                && strlit.symbol == sym::rust\n            {\n                Pat::MultiStr(&[\"fn\", \"extern\"])\n            } else {\n                Pat::Str(\"extern\")\n            },\n            match &fn_ptr.decl.output {\n                FnRetTy::Default(_) => {\n                    if let [.., param] = &*fn_ptr.decl.inputs {\n                        ast_ty_search_pat(&param.ty).1\n                    } else {\n                        Pat::Str(\"(\")\n                    }\n                },\n                FnRetTy::Ty(ty) => ast_ty_search_pat(ty).1,\n            },\n        ),\n        TyKind::Never => (Pat::Str(\"!\"), Pat::Str(\"!\")),\n        // Parenthesis are trimmed from the text before the search patterns are matched.\n        // See: `span_matches_pat`\n        TyKind::Tup(tup) => match &**tup {\n            [] => (Pat::Str(\")\"), Pat::Str(\"(\")),\n            [ty] => ast_ty_search_pat(ty),\n            [head, .., tail] => (ast_ty_search_pat(head).0, ast_ty_search_pat(tail).1),\n        },\n        TyKind::ImplTrait(..) => (Pat::Str(\"impl\"), Pat::Str(\"\")),\n        TyKind::Path(qself_path, path) => {\n            let start = if qself_path.is_some() {\n                Pat::Str(\"<\")\n            } else if let Some(first) = path.segments.first() {\n                ident_search_pat(first.ident).0\n            } else {\n                // this shouldn't be possible, but sure\n                Pat::Str(\"\")\n            };\n            let end = if let Some(last) = path.segments.last() {\n                match last.args.as_deref() {\n                    // last `>` in `std::foo::Bar<T>`\n                    Some(GenericArgs::AngleBracketed(_)) => Pat::Str(\">\"),\n                    Some(GenericArgs::Parenthesized(par_args)) => match &par_args.output {\n                        FnRetTy::Default(_) => {\n                            if let Some(last) = par_args.inputs.last() {\n                                // `B` in `(A, B)` -- `)` gets stripped\n                                ast_ty_search_pat(last).1\n                            } else {\n                                // `(` in `()` -- `)` gets stripped\n                                Pat::Str(\"(\")\n                            }\n                        },\n                        // `C` in `(A, B) -> C`\n                        FnRetTy::Ty(ty) => ast_ty_search_pat(ty).1,\n                    },\n                    // last `..` in `(..)` -- `)` gets stripped\n                    Some(GenericArgs::ParenthesizedElided(_)) => Pat::Str(\"..\"),\n                    // `bar` in `std::foo::bar`\n                    None => ident_search_pat(last.ident).1,\n                }\n            } else {\n                // this shouldn't be possible\n                Pat::Str(\n                    if qself_path.is_some() {\n                        \">\"  // last `>` in `<Vec as IntoIterator>`\n                    } else {\n                        \"\"\n                    }\n                )\n            };\n            (start, end)\n        },\n        TyKind::Infer => (Pat::Str(\"_\"), Pat::Str(\"_\")),\n        TyKind::Paren(ty) => ast_ty_search_pat(ty),\n        TyKind::UnsafeBinder(binder_ty) => (Pat::Str(\"unsafe\"), ast_ty_search_pat(&binder_ty.inner_ty).1),\n        TyKind::TraitObject(_, trait_obj_syntax) => {\n            if let TraitObjectSyntax::Dyn = trait_obj_syntax {\n                (Pat::Str(\"dyn\"), Pat::Str(\"\"))\n            } else {\n                // NOTE: `TraitObject` is incomplete. It will always return true then.\n                (Pat::Str(\"\"), Pat::Str(\"\"))\n            }\n        },\n        TyKind::MacCall(mac_call) => {\n            let start = if let Some(first) = mac_call.path.segments.first() {\n                ident_search_pat(first.ident).0\n            } else {\n                Pat::Str(\"\")\n            };\n            (start, Pat::Str(\"\"))\n        },\n\n        // implicit, so has no contents to match against\n        TyKind::ImplicitSelf\n\n        // experimental\n        | TyKind::Pat(..)\n        | TyKind::FieldOf(..)\n\n        // unused\n        | TyKind::CVarArgs\n\n        // placeholder\n        | TyKind::Dummy\n        | TyKind::Err(_) => (Pat::Str(\"\"), Pat::Str(\"\")),\n    }\n}\n\n// NOTE: can't `impl WithSearchPat for TraitRef`, because `TraitRef` doesn't have a `span` field\n// (nor a method)\nfn trait_ref_search_pat(trait_ref: &TraitRef<'_>) -> (Pat, Pat) {\n    path_search_pat(trait_ref.path)\n}\n\nfn poly_trait_ref_search_pat(poly_trait_ref: &PolyTraitRef<'_>) -> (Pat, Pat) {\n    // NOTE: unfortunately we can't use `bound_generic_params` to see whether the pattern starts with\n    // `for<..>`, because if it's empty, we could have either `for<>` (nothing bound), or\n    // no `for` at all\n    let PolyTraitRef {\n        modifiers: TraitBoundModifiers { constness, polarity },\n        trait_ref,\n        ..\n    } = poly_trait_ref;\n\n    let trait_ref_search_pat = trait_ref_search_pat(trait_ref);\n\n    #[expect(\n        clippy::unnecessary_lazy_evaluations,\n        reason = \"the closure in `or_else` has `match polarity`, which isn't free\"\n    )]\n    let start = match constness {\n        BoundConstness::Never => None,\n        BoundConstness::Maybe(_) => Some(Pat::Str(\"[const]\")),\n        BoundConstness::Always(_) => Some(Pat::Str(\"const\")),\n    }\n    .or_else(|| match polarity {\n        BoundPolarity::Negative(_) => Some(Pat::Str(\"!\")),\n        BoundPolarity::Maybe(_) => Some(Pat::Str(\"?\")),\n        BoundPolarity::Positive => None,\n    })\n    .unwrap_or(trait_ref_search_pat.0);\n    let end = trait_ref_search_pat.1;\n\n    (start, end)\n}\n\nfn ident_search_pat(ident: Ident) -> (Pat, Pat) {\n    (Pat::Sym(ident.name), Pat::Sym(ident.name))\n}\n\npub trait WithSearchPat<'cx> {\n    type Context: LintContext;\n    fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat);\n    fn span(&self) -> Span;\n}\nmacro_rules! impl_with_search_pat {\n    (($cx_ident:ident: $cx_ty:ident<$cx_lt:lifetime>, $self:tt: $ty:ty) => $fn:ident($($args:tt)*)) => {\n        impl<$cx_lt> WithSearchPat<$cx_lt> for $ty {\n            type Context = $cx_ty<$cx_lt>;\n            fn search_pat(&$self, $cx_ident: &Self::Context) -> (Pat, Pat) {\n                $fn($($args)*)\n            }\n            fn span(&self) -> Span {\n                self.span\n            }\n        }\n    };\n}\nimpl_with_search_pat!((cx: LateContext<'tcx>, self: Expr<'tcx>) => expr_search_pat(cx.tcx, self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: Item<'_>) => item_search_pat(self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: TraitItem<'_>) => trait_item_search_pat(self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: ImplItem<'_>) => impl_item_search_pat(self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: FieldDef<'_>) => field_def_search_pat(self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: Variant<'_>) => variant_search_pat(self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: Ty<'_>) => ty_search_pat(self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: Ident) => ident_search_pat(*self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: Lit) => lit_search_pat(&self.node));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: Path<'_>) => path_search_pat(self));\nimpl_with_search_pat!((_cx: LateContext<'tcx>, self: PolyTraitRef<'_>) => poly_trait_ref_search_pat(self));\n\nimpl_with_search_pat!((_cx: EarlyContext<'tcx>, self: Attribute) => attr_search_pat(self));\nimpl_with_search_pat!((_cx: EarlyContext<'tcx>, self: ast::Ty) => ast_ty_search_pat(self));\n\nimpl<'cx> WithSearchPat<'cx> for (&FnKind<'cx>, &Body<'cx>, HirId, Span) {\n    type Context = LateContext<'cx>;\n\n    fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat) {\n        fn_kind_pat(cx.tcx, self.0, self.1, self.2)\n    }\n\n    fn span(&self) -> Span {\n        self.3\n    }\n}\n\n/// Checks if the item likely came from a proc-macro.\n///\n/// This should be called after `in_external_macro` and the initial pattern matching of the ast as\n/// it is significantly slower than both of those.\npub fn is_from_proc_macro<'cx, T: WithSearchPat<'cx>>(cx: &T::Context, item: &T) -> bool {\n    let (start_pat, end_pat) = item.search_pat(cx);\n    !span_matches_pat(cx.sess(), item.span(), start_pat, end_pat)\n}\n\n/// Checks if the span actually refers to a match expression\npub fn is_span_match(cx: &impl LintContext, span: Span) -> bool {\n    span_matches_pat(cx.sess(), span, Pat::Str(\"match\"), Pat::Str(\"}\"))\n}\n\n/// Checks if the span actually refers to an if expression\npub fn is_span_if(cx: &impl LintContext, span: Span) -> bool {\n    span_matches_pat(cx.sess(), span, Pat::Str(\"if\"), Pat::Str(\"}\"))\n}\n"
  },
  {
    "path": "clippy_utils/src/comparisons.rs",
    "content": "//! Utility functions for comparison operators.\n\n#![deny(clippy::missing_docs_in_private_items)]\n\nuse rustc_hir::{BinOpKind, Expr};\n\n#[derive(PartialEq, Eq, Debug, Copy, Clone)]\n/// Represents a normalized comparison operator.\npub enum Rel {\n    /// `<`\n    Lt,\n    /// `<=`\n    Le,\n    /// `==`\n    Eq,\n    /// `!=`\n    Ne,\n}\n\n/// Put the expression in the form  `lhs < rhs`, `lhs <= rhs`, `lhs == rhs` or\n/// `lhs != rhs`.\npub fn normalize_comparison<'a>(\n    op: BinOpKind,\n    lhs: &'a Expr<'a>,\n    rhs: &'a Expr<'a>,\n) -> Option<(Rel, &'a Expr<'a>, &'a Expr<'a>)> {\n    match op {\n        BinOpKind::Lt => Some((Rel::Lt, lhs, rhs)),\n        BinOpKind::Le => Some((Rel::Le, lhs, rhs)),\n        BinOpKind::Gt => Some((Rel::Lt, rhs, lhs)),\n        BinOpKind::Ge => Some((Rel::Le, rhs, lhs)),\n        BinOpKind::Eq => Some((Rel::Eq, rhs, lhs)),\n        BinOpKind::Ne => Some((Rel::Ne, rhs, lhs)),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/consts.rs",
    "content": "//! A simple const eval API, for use on arbitrary HIR expressions.\n//!\n//! This cannot use rustc's const eval, aka miri, as arbitrary HIR expressions cannot be lowered to\n//! executable MIR bodies, so we have to do this instead.\n#![expect(clippy::float_cmp)]\n\nuse crate::res::MaybeDef;\nuse crate::source::{SpanRangeExt, walk_span_to_context};\nuse crate::{clip, is_direct_expn_of, sext, sym, unsext};\n\nuse rustc_abi::Size;\nuse rustc_apfloat::Float;\nuse rustc_apfloat::ieee::{Half, Quad};\nuse rustc_ast::ast::{LitFloatType, LitKind};\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::{\n    BinOpKind, Block, ConstArgKind, ConstBlock, ConstItemRhs, Expr, ExprKind, HirId, PatExpr, PatExprKind, QPath,\n    TyKind, UnOp,\n};\nuse rustc_lexer::{FrontmatterAllowed, tokenize};\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::ConstValue;\nuse rustc_middle::mir::interpret::{Scalar, alloc_range};\nuse rustc_middle::ty::{self, FloatTy, IntTy, ScalarInt, Ty, TyCtxt, TypeckResults, UintTy};\nuse rustc_middle::{bug, mir, span_bug};\nuse rustc_span::{Symbol, SyntaxContext};\nuse std::cell::Cell;\nuse std::cmp::Ordering;\nuse std::hash::{Hash, Hasher};\nuse std::iter;\n\n/// A `LitKind`-like enum to fold constant `Expr`s into.\n#[derive(Debug, Clone)]\npub enum Constant {\n    Adt(ConstValue),\n    /// A `String` (e.g., \"abc\").\n    Str(String),\n    /// A binary string (e.g., `b\"abc\"`).\n    Binary(Vec<u8>),\n    /// A single `char` (e.g., `'a'`).\n    Char(char),\n    /// An integer's bit representation.\n    Int(u128),\n    /// An `f16` bitcast to a `u16`.\n    // FIXME(f16_f128): use `f16` once builtins are available on all host tools platforms.\n    F16(u16),\n    /// An `f32`.\n    F32(f32),\n    /// An `f64`.\n    F64(f64),\n    /// An `f128` bitcast to a `u128`.\n    // FIXME(f16_f128): use `f128` once builtins are available on all host tools platforms.\n    F128(u128),\n    /// `true` or `false`.\n    Bool(bool),\n    /// An array of constants.\n    Vec(Vec<Self>),\n    /// Also an array, but with only one constant, repeated N times.\n    Repeat(Box<Self>, u64),\n    /// A tuple of constants.\n    Tuple(Vec<Self>),\n    /// A raw pointer.\n    RawPtr(u128),\n    /// A reference\n    Ref(Box<Self>),\n    /// A literal with syntax error.\n    Err,\n}\n\ntrait IntTypeBounds: Sized {\n    type Output: PartialOrd;\n\n    fn min_max(self) -> Option<(Self::Output, Self::Output)>;\n    fn bits(self) -> Self::Output;\n    fn ensure_fits(self, val: Self::Output) -> Option<Self::Output> {\n        let (min, max) = self.min_max()?;\n        (min <= val && val <= max).then_some(val)\n    }\n}\nimpl IntTypeBounds for UintTy {\n    type Output = u128;\n    fn min_max(self) -> Option<(Self::Output, Self::Output)> {\n        Some(match self {\n            UintTy::U8 => (u8::MIN.into(), u8::MAX.into()),\n            UintTy::U16 => (u16::MIN.into(), u16::MAX.into()),\n            UintTy::U32 => (u32::MIN.into(), u32::MAX.into()),\n            UintTy::U64 => (u64::MIN.into(), u64::MAX.into()),\n            UintTy::U128 => (u128::MIN, u128::MAX),\n            UintTy::Usize => (usize::MIN.try_into().ok()?, usize::MAX.try_into().ok()?),\n        })\n    }\n    fn bits(self) -> Self::Output {\n        match self {\n            UintTy::U8 => 8,\n            UintTy::U16 => 16,\n            UintTy::U32 => 32,\n            UintTy::U64 => 64,\n            UintTy::U128 => 128,\n            UintTy::Usize => usize::BITS.into(),\n        }\n    }\n}\nimpl IntTypeBounds for IntTy {\n    type Output = i128;\n    fn min_max(self) -> Option<(Self::Output, Self::Output)> {\n        Some(match self {\n            IntTy::I8 => (i8::MIN.into(), i8::MAX.into()),\n            IntTy::I16 => (i16::MIN.into(), i16::MAX.into()),\n            IntTy::I32 => (i32::MIN.into(), i32::MAX.into()),\n            IntTy::I64 => (i64::MIN.into(), i64::MAX.into()),\n            IntTy::I128 => (i128::MIN, i128::MAX),\n            IntTy::Isize => (isize::MIN.try_into().ok()?, isize::MAX.try_into().ok()?),\n        })\n    }\n    fn bits(self) -> Self::Output {\n        match self {\n            IntTy::I8 => 8,\n            IntTy::I16 => 16,\n            IntTy::I32 => 32,\n            IntTy::I64 => 64,\n            IntTy::I128 => 128,\n            IntTy::Isize => isize::BITS.into(),\n        }\n    }\n}\n\nimpl PartialEq for Constant {\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (Self::Str(ls), Self::Str(rs)) => ls == rs,\n            (Self::Binary(l), Self::Binary(r)) => l == r,\n            (&Self::Char(l), &Self::Char(r)) => l == r,\n            (&Self::Int(l), &Self::Int(r)) => l == r,\n            (&Self::F64(l), &Self::F64(r)) => {\n                // `to_bits` is required to catch non-matching `0.0` and `-0.0`.\n                l.to_bits() == r.to_bits() && !l.is_nan()\n            },\n            (&Self::F32(l), &Self::F32(r)) => {\n                // `to_bits` is required to catch non-matching `0.0` and `-0.0`.\n                l.to_bits() == r.to_bits() && !l.is_nan()\n            },\n            (&Self::Bool(l), &Self::Bool(r)) => l == r,\n            (&Self::Vec(ref l), &Self::Vec(ref r)) | (&Self::Tuple(ref l), &Self::Tuple(ref r)) => l == r,\n            (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => ls == rs && lv == rv,\n            (Self::Ref(lb), Self::Ref(rb)) => *lb == *rb,\n            // TODO: are there inter-type equalities?\n            _ => false,\n        }\n    }\n}\n\nimpl Hash for Constant {\n    fn hash<H>(&self, state: &mut H)\n    where\n        H: Hasher,\n    {\n        std::mem::discriminant(self).hash(state);\n        match *self {\n            Self::Adt(ref elem) => {\n                elem.hash(state);\n            },\n            Self::Str(ref s) => {\n                s.hash(state);\n            },\n            Self::Binary(ref b) => {\n                b.hash(state);\n            },\n            Self::Char(c) => {\n                c.hash(state);\n            },\n            Self::Int(i) => {\n                i.hash(state);\n            },\n            Self::F16(f) => {\n                // FIXME(f16_f128): once conversions to/from `f128` are available on all platforms,\n                f.hash(state);\n            },\n            Self::F32(f) => {\n                f64::from(f).to_bits().hash(state);\n            },\n            Self::F64(f) => {\n                f.to_bits().hash(state);\n            },\n            Self::F128(f) => {\n                f.hash(state);\n            },\n            Self::Bool(b) => {\n                b.hash(state);\n            },\n            Self::Vec(ref v) | Self::Tuple(ref v) => {\n                v.hash(state);\n            },\n            Self::Repeat(ref c, l) => {\n                c.hash(state);\n                l.hash(state);\n            },\n            Self::RawPtr(u) => {\n                u.hash(state);\n            },\n            Self::Ref(ref r) => {\n                r.hash(state);\n            },\n            Self::Err => {},\n        }\n    }\n}\n\nimpl Constant {\n    pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self) -> Option<Ordering> {\n        match (left, right) {\n            (Self::Str(ls), Self::Str(rs)) => Some(ls.cmp(rs)),\n            (Self::Char(l), Self::Char(r)) => Some(l.cmp(r)),\n            (&Self::Int(l), &Self::Int(r)) => match *cmp_type.kind() {\n                ty::Int(int_ty) => Some(sext(tcx, l, int_ty).cmp(&sext(tcx, r, int_ty))),\n                ty::Uint(_) => Some(l.cmp(&r)),\n                _ => bug!(\"Not an int type\"),\n            },\n            (&Self::F64(l), &Self::F64(r)) => l.partial_cmp(&r),\n            (&Self::F32(l), &Self::F32(r)) => l.partial_cmp(&r),\n            (Self::Bool(l), Self::Bool(r)) => Some(l.cmp(r)),\n            (Self::Tuple(l), Self::Tuple(r)) if l.len() == r.len() => match *cmp_type.kind() {\n                ty::Tuple(tys) if tys.len() == l.len() => l\n                    .iter()\n                    .zip(r)\n                    .zip(tys)\n                    .map(|((li, ri), cmp_type)| Self::partial_cmp(tcx, cmp_type, li, ri))\n                    .find(|r| r.is_none_or(|o| o != Ordering::Equal))\n                    .unwrap_or_else(|| Some(l.len().cmp(&r.len()))),\n                _ => None,\n            },\n            (Self::Vec(l), Self::Vec(r)) => {\n                let cmp_type = cmp_type.builtin_index()?;\n                iter::zip(l, r)\n                    .map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri))\n                    .find(|r| r.is_none_or(|o| o != Ordering::Equal))\n                    .unwrap_or_else(|| Some(l.len().cmp(&r.len())))\n            },\n            (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => {\n                match Self::partial_cmp(\n                    tcx,\n                    match *cmp_type.kind() {\n                        ty::Array(ty, _) => ty,\n                        _ => return None,\n                    },\n                    lv,\n                    rv,\n                ) {\n                    Some(Ordering::Equal) => Some(ls.cmp(rs)),\n                    x => x,\n                }\n            },\n            (Self::Ref(lb), Self::Ref(rb)) => Self::partial_cmp(\n                tcx,\n                match *cmp_type.kind() {\n                    ty::Ref(_, ty, _) => ty,\n                    _ => return None,\n                },\n                lb,\n                rb,\n            ),\n            // TODO: are there any useful inter-type orderings?\n            _ => None,\n        }\n    }\n\n    /// Returns the integer value or `None` if `self` or `val_type` is not integer type.\n    pub fn int_value(&self, tcx: TyCtxt<'_>, val_type: Ty<'_>) -> Option<FullInt> {\n        if let Constant::Int(const_int) = *self {\n            match *val_type.kind() {\n                ty::Int(ity) => Some(FullInt::S(sext(tcx, const_int, ity))),\n                ty::Uint(_) => Some(FullInt::U(const_int)),\n                _ => None,\n            }\n        } else {\n            None\n        }\n    }\n\n    #[must_use]\n    pub fn peel_refs(mut self) -> Self {\n        while let Constant::Ref(r) = self {\n            self = *r;\n        }\n        self\n    }\n\n    fn parse_f16(s: &str) -> Self {\n        let f: Half = s.parse().unwrap();\n        Self::F16(f.to_bits().try_into().unwrap())\n    }\n\n    fn parse_f128(s: &str) -> Self {\n        let f: Quad = s.parse().unwrap();\n        Self::F128(f.to_bits())\n    }\n\n    pub fn new_numeric_min<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Self> {\n        match *ty.kind() {\n            ty::Uint(_) => Some(Self::Int(0)),\n            ty::Int(ty) => {\n                let val = match ty.normalize(tcx.sess.target.pointer_width) {\n                    IntTy::I8 => i128::from(i8::MIN),\n                    IntTy::I16 => i128::from(i16::MIN),\n                    IntTy::I32 => i128::from(i32::MIN),\n                    IntTy::I64 => i128::from(i64::MIN),\n                    IntTy::I128 => i128::MIN,\n                    IntTy::Isize => return None,\n                };\n                Some(Self::Int(val.cast_unsigned()))\n            },\n            ty::Char => Some(Self::Char(char::MIN)),\n            ty::Float(FloatTy::F32) => Some(Self::F32(f32::NEG_INFINITY)),\n            ty::Float(FloatTy::F64) => Some(Self::F64(f64::NEG_INFINITY)),\n            _ => None,\n        }\n    }\n\n    pub fn new_numeric_max<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<Self> {\n        match *ty.kind() {\n            ty::Uint(ty) => Some(Self::Int(match ty.normalize(tcx.sess.target.pointer_width) {\n                UintTy::U8 => u128::from(u8::MAX),\n                UintTy::U16 => u128::from(u16::MAX),\n                UintTy::U32 => u128::from(u32::MAX),\n                UintTy::U64 => u128::from(u64::MAX),\n                UintTy::U128 => u128::MAX,\n                UintTy::Usize => return None,\n            })),\n            ty::Int(ty) => {\n                let val = match ty.normalize(tcx.sess.target.pointer_width) {\n                    IntTy::I8 => i128::from(i8::MAX),\n                    IntTy::I16 => i128::from(i16::MAX),\n                    IntTy::I32 => i128::from(i32::MAX),\n                    IntTy::I64 => i128::from(i64::MAX),\n                    IntTy::I128 => i128::MAX,\n                    IntTy::Isize => return None,\n                };\n                Some(Self::Int(val.cast_unsigned()))\n            },\n            ty::Char => Some(Self::Char(char::MAX)),\n            ty::Float(FloatTy::F32) => Some(Self::F32(f32::INFINITY)),\n            ty::Float(FloatTy::F64) => Some(Self::F64(f64::INFINITY)),\n            _ => None,\n        }\n    }\n\n    pub fn is_numeric_min<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {\n        match (self, ty.kind()) {\n            (&Self::Int(x), &ty::Uint(_)) => x == 0,\n            (&Self::Int(x), &ty::Int(ty)) => {\n                let limit = match ty.normalize(tcx.sess.target.pointer_width) {\n                    IntTy::I8 => i128::from(i8::MIN),\n                    IntTy::I16 => i128::from(i16::MIN),\n                    IntTy::I32 => i128::from(i32::MIN),\n                    IntTy::I64 => i128::from(i64::MIN),\n                    IntTy::I128 => i128::MIN,\n                    IntTy::Isize => return false,\n                };\n                x.cast_signed() == limit\n            },\n            (&Self::Char(x), &ty::Char) => x == char::MIN,\n            (&Self::F32(x), &ty::Float(FloatTy::F32)) => x == f32::NEG_INFINITY,\n            (&Self::F64(x), &ty::Float(FloatTy::F64)) => x == f64::NEG_INFINITY,\n            _ => false,\n        }\n    }\n\n    pub fn is_numeric_max<'tcx>(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {\n        match (self, ty.kind()) {\n            (&Self::Int(x), &ty::Uint(ty)) => {\n                let limit = match ty.normalize(tcx.sess.target.pointer_width) {\n                    UintTy::U8 => u128::from(u8::MAX),\n                    UintTy::U16 => u128::from(u16::MAX),\n                    UintTy::U32 => u128::from(u32::MAX),\n                    UintTy::U64 => u128::from(u64::MAX),\n                    UintTy::U128 => u128::MAX,\n                    UintTy::Usize => return false,\n                };\n                x == limit\n            },\n            (&Self::Int(x), &ty::Int(ty)) => {\n                let limit = match ty.normalize(tcx.sess.target.pointer_width) {\n                    IntTy::I8 => i128::from(i8::MAX),\n                    IntTy::I16 => i128::from(i16::MAX),\n                    IntTy::I32 => i128::from(i32::MAX),\n                    IntTy::I64 => i128::from(i64::MAX),\n                    IntTy::I128 => i128::MAX,\n                    IntTy::Isize => return false,\n                };\n                x.cast_signed() == limit\n            },\n            (&Self::Char(x), &ty::Char) => x == char::MAX,\n            (&Self::F32(x), &ty::Float(FloatTy::F32)) => x == f32::INFINITY,\n            (&Self::F64(x), &ty::Float(FloatTy::F64)) => x == f64::INFINITY,\n            _ => false,\n        }\n    }\n\n    pub fn is_pos_infinity(&self) -> bool {\n        match *self {\n            // FIXME(f16_f128): add f16 and f128 when constants are available\n            Constant::F32(x) => x == f32::INFINITY,\n            Constant::F64(x) => x == f64::INFINITY,\n            _ => false,\n        }\n    }\n\n    pub fn is_neg_infinity(&self) -> bool {\n        match *self {\n            // FIXME(f16_f128): add f16 and f128 when constants are available\n            Constant::F32(x) => x == f32::NEG_INFINITY,\n            Constant::F64(x) => x == f64::NEG_INFINITY,\n            _ => false,\n        }\n    }\n}\n\n/// Parses a `LitKind` to a `Constant`.\npub fn lit_to_mir_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant {\n    match *lit {\n        LitKind::Str(ref is, _) => Constant::Str(is.to_string()),\n        LitKind::Byte(b) => Constant::Int(u128::from(b)),\n        LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(s.as_byte_str().to_vec()),\n        LitKind::Char(c) => Constant::Char(c),\n        LitKind::Int(n, _) => Constant::Int(n.get()),\n        LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {\n            // FIXME(f16_f128): just use `parse()` directly when available for `f16`/`f128`\n            FloatTy::F16 => Constant::parse_f16(is.as_str()),\n            FloatTy::F32 => Constant::F32(is.as_str().parse().unwrap()),\n            FloatTy::F64 => Constant::F64(is.as_str().parse().unwrap()),\n            FloatTy::F128 => Constant::parse_f128(is.as_str()),\n        },\n        LitKind::Float(ref is, LitFloatType::Unsuffixed) => match ty.expect(\"type of float is known\").kind() {\n            ty::Float(FloatTy::F16) => Constant::parse_f16(is.as_str()),\n            ty::Float(FloatTy::F32) => Constant::F32(is.as_str().parse().unwrap()),\n            ty::Float(FloatTy::F64) => Constant::F64(is.as_str().parse().unwrap()),\n            ty::Float(FloatTy::F128) => Constant::parse_f128(is.as_str()),\n            _ => bug!(),\n        },\n        LitKind::Bool(b) => Constant::Bool(b),\n        LitKind::Err(_) => Constant::Err,\n    }\n}\n\n/// The source of a constant value.\n#[derive(Clone, Copy)]\npub enum ConstantSource {\n    /// The value is determined solely from the expression.\n    Local,\n    /// The value is dependent on another definition that may change independently from the local\n    /// expression.\n    NonLocal,\n}\nimpl ConstantSource {\n    pub fn is_local(self) -> bool {\n        matches!(self, Self::Local)\n    }\n}\n\n#[derive(Copy, Clone, Debug, Eq)]\npub enum FullInt {\n    S(i128),\n    U(u128),\n}\n\nimpl PartialEq for FullInt {\n    fn eq(&self, other: &Self) -> bool {\n        self.cmp(other) == Ordering::Equal\n    }\n}\n\nimpl PartialOrd for FullInt {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\nimpl Ord for FullInt {\n    fn cmp(&self, other: &Self) -> Ordering {\n        use FullInt::{S, U};\n\n        fn cmp_s_u(s: i128, u: u128) -> Ordering {\n            u128::try_from(s).map_or(Ordering::Less, |x| x.cmp(&u))\n        }\n\n        match (*self, *other) {\n            (S(s), S(o)) => s.cmp(&o),\n            (U(s), U(o)) => s.cmp(&o),\n            (S(s), U(o)) => cmp_s_u(s, o),\n            (U(s), S(o)) => cmp_s_u(o, s).reverse(),\n        }\n    }\n}\n\n/// The context required to evaluate a constant expression.\n///\n/// This is currently limited to constant folding and reading the value of named constants.\n///\n/// See the module level documentation for some context.\npub struct ConstEvalCtxt<'tcx> {\n    tcx: TyCtxt<'tcx>,\n    typing_env: ty::TypingEnv<'tcx>,\n    typeck: &'tcx TypeckResults<'tcx>,\n    source: Cell<ConstantSource>,\n    ctxt: Cell<SyntaxContext>,\n}\n\nimpl<'tcx> ConstEvalCtxt<'tcx> {\n    /// Creates the evaluation context from the lint context. This requires the lint context to be\n    /// in a body (i.e. `cx.enclosing_body.is_some()`).\n    pub fn new(cx: &LateContext<'tcx>) -> Self {\n        Self {\n            tcx: cx.tcx,\n            typing_env: cx.typing_env(),\n            typeck: cx.typeck_results(),\n            source: Cell::new(ConstantSource::Local),\n            ctxt: Cell::new(SyntaxContext::root()),\n        }\n    }\n\n    /// Creates an evaluation context.\n    pub fn with_env(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, typeck: &'tcx TypeckResults<'tcx>) -> Self {\n        Self {\n            tcx,\n            typing_env,\n            typeck,\n            source: Cell::new(ConstantSource::Local),\n            ctxt: Cell::new(SyntaxContext::root()),\n        }\n    }\n\n    /// Attempts to evaluate the expression and returns both the value and whether it's dependant on\n    /// other items.\n    pub fn eval_with_source(&self, e: &Expr<'_>, ctxt: SyntaxContext) -> Option<(Constant, ConstantSource)> {\n        self.source.set(ConstantSource::Local);\n        self.ctxt.set(ctxt);\n        self.expr(e).map(|c| (c, self.source.get()))\n    }\n\n    /// Attempts to evaluate the expression.\n    pub fn eval(&self, e: &Expr<'_>) -> Option<Constant> {\n        self.expr(e)\n    }\n\n    /// Attempts to evaluate the expression without accessing other items.\n    ///\n    /// The context argument is the context used to view the evaluated expression. e.g. when\n    /// evaluating the argument in `f(m!(1))` the context of the call expression should be used.\n    /// This is need so the const evaluator can see the `m` macro and marke the evaluation as\n    /// non-local independant of what the macro expands to.\n    pub fn eval_local(&self, e: &Expr<'_>, ctxt: SyntaxContext) -> Option<Constant> {\n        match self.eval_with_source(e, ctxt) {\n            Some((x, ConstantSource::Local)) => Some(x),\n            _ => None,\n        }\n    }\n\n    /// Attempts to evaluate the expression as an integer without accessing other items.\n    ///\n    /// The context argument is the context used to view the evaluated expression. e.g. when\n    /// evaluating the argument in `f(m!(1))` the context of the call expression should be used.\n    /// This is need so the const evaluator can see the `m` macro and marke the evaluation as\n    /// non-local independant of what the macro expands to.\n    pub fn eval_full_int(&self, e: &Expr<'_>, ctxt: SyntaxContext) -> Option<FullInt> {\n        match self.eval_with_source(e, ctxt) {\n            Some((x, ConstantSource::Local)) => x.int_value(self.tcx, self.typeck.expr_ty(e)),\n            _ => None,\n        }\n    }\n\n    pub fn eval_pat_expr(&self, pat_expr: &PatExpr<'_>) -> Option<Constant> {\n        match &pat_expr.kind {\n            PatExprKind::Lit { lit, negated } => {\n                let ty = self.typeck.node_type_opt(pat_expr.hir_id);\n                let val = lit_to_mir_constant(&lit.node, ty);\n                if *negated {\n                    self.constant_negate(&val, ty?)\n                } else {\n                    Some(val)\n                }\n            },\n            PatExprKind::Path(qpath) => self.qpath(qpath, pat_expr.hir_id),\n        }\n    }\n\n    fn check_ctxt(&self, ctxt: SyntaxContext) {\n        if self.ctxt.get() != ctxt {\n            self.source.set(ConstantSource::NonLocal);\n        }\n    }\n\n    fn qpath(&self, qpath: &QPath<'_>, hir_id: HirId) -> Option<Constant> {\n        self.fetch_path(qpath, hir_id)\n            .and_then(|c| mir_to_const(self.tcx, c, self.typeck.node_type(hir_id)))\n    }\n\n    /// Simple constant folding: Insert an expression, get a constant or none.\n    fn expr(&self, e: &Expr<'_>) -> Option<Constant> {\n        self.check_ctxt(e.span.ctxt());\n        match e.kind {\n            ExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir_body(body).value),\n            ExprKind::DropTemps(e) => self.expr(e),\n            ExprKind::Path(ref qpath) => self.qpath(qpath, e.hir_id),\n            ExprKind::Block(block, _) => {\n                self.check_ctxt(block.span.ctxt());\n                self.block(block)\n            },\n            ExprKind::Lit(lit) => {\n                self.check_ctxt(lit.span.ctxt());\n                Some(lit_to_mir_constant(&lit.node, self.typeck.expr_ty_opt(e)))\n            },\n            ExprKind::Array(vec) => self.multi(vec).map(Constant::Vec),\n            ExprKind::Tup(tup) => self.multi(tup).map(Constant::Tuple),\n            ExprKind::Repeat(value, _) => {\n                let n = match self.typeck.expr_ty(e).kind() {\n                    ty::Array(_, n) => n.try_to_target_usize(self.tcx)?,\n                    _ => span_bug!(e.span, \"typeck error\"),\n                };\n                self.expr(value).map(|v| Constant::Repeat(Box::new(v), n))\n            },\n            ExprKind::Unary(op, operand) => self.expr(operand).and_then(|o| match op {\n                UnOp::Not => self.constant_not(&o, self.typeck.expr_ty(e)),\n                UnOp::Neg => self.constant_negate(&o, self.typeck.expr_ty(e)),\n                UnOp::Deref => Some(if let Constant::Ref(r) = o { *r } else { o }),\n            }),\n            ExprKind::If(cond, then, ref otherwise) => self.ifthenelse(cond, then, *otherwise),\n            ExprKind::Binary(op, left, right) => {\n                self.check_ctxt(e.span.ctxt());\n                self.binop(op.node, left, right)\n            },\n            ExprKind::Call(callee, []) => {\n                // We only handle a few const functions for now.\n                if let ExprKind::Path(qpath) = &callee.kind\n                    && let Some(did) = self.typeck.qpath_res(qpath, callee.hir_id).opt_def_id()\n                {\n                    match self.tcx.get_diagnostic_name(did) {\n                        Some(sym::i8_legacy_fn_max_value) => Some(Constant::Int(i8::MAX as u128)),\n                        Some(sym::i16_legacy_fn_max_value) => Some(Constant::Int(i16::MAX as u128)),\n                        Some(sym::i32_legacy_fn_max_value) => Some(Constant::Int(i32::MAX as u128)),\n                        Some(sym::i64_legacy_fn_max_value) => Some(Constant::Int(i64::MAX as u128)),\n                        Some(sym::i128_legacy_fn_max_value) => Some(Constant::Int(i128::MAX as u128)),\n                        _ => None,\n                    }\n                } else {\n                    None\n                }\n            },\n            ExprKind::Index(arr, index, _) => self.index(arr, index),\n            ExprKind::AddrOf(_, _, inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))),\n            ExprKind::Field(base, ref field)\n                if let base_ty = self.typeck.expr_ty(base)\n                    && match self.typeck.expr_adjustments(base) {\n                        [] => true,\n                        [.., a] => a.target == base_ty,\n                    }\n                    && let Some(Constant::Adt(constant)) = self.expr(base)\n                    && let ty::Adt(adt_def, _) = *base_ty.kind()\n                    && adt_def.is_struct()\n                    && let Some((desired_field, ty)) =\n                        field_of_struct(adt_def, self.tcx, constant, base_ty, field.name) =>\n            {\n                self.check_ctxt(field.span.ctxt());\n                mir_to_const(self.tcx, desired_field, ty)\n            },\n            _ => None,\n        }\n    }\n\n    /// Simple constant folding to determine if an expression is an empty slice, str, array, …\n    /// `None` will be returned if the constness cannot be determined, or if the resolution\n    /// leaves the local crate.\n    pub fn eval_is_empty(&self, e: &Expr<'_>) -> Option<bool> {\n        match e.kind {\n            ExprKind::ConstBlock(ConstBlock { body, .. }) => self.eval_is_empty(self.tcx.hir_body(body).value),\n            ExprKind::DropTemps(e) => self.eval_is_empty(e),\n            ExprKind::Lit(lit) => {\n                if is_direct_expn_of(e.span, sym::cfg).is_some() {\n                    None\n                } else {\n                    match &lit.node {\n                        LitKind::Str(is, _) => Some(is.is_empty()),\n                        LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => Some(s.as_byte_str().is_empty()),\n                        _ => None,\n                    }\n                }\n            },\n            ExprKind::Array(vec) => self.multi(vec).map(|v| v.is_empty()),\n            ExprKind::Repeat(..) => {\n                if let ty::Array(_, n) = self.typeck.expr_ty(e).kind() {\n                    Some(n.try_to_target_usize(self.tcx)? == 0)\n                } else {\n                    span_bug!(e.span, \"typeck error\");\n                }\n            },\n            _ => None,\n        }\n    }\n\n    #[expect(clippy::cast_possible_wrap)]\n    fn constant_not(&self, o: &Constant, ty: Ty<'_>) -> Option<Constant> {\n        use self::Constant::{Bool, Int};\n        match *o {\n            Bool(b) => Some(Bool(!b)),\n            Int(value) => {\n                let value = !value;\n                match *ty.kind() {\n                    ty::Int(ity) => Some(Int(unsext(self.tcx, value as i128, ity))),\n                    ty::Uint(ity) => Some(Int(clip(self.tcx, value, ity))),\n                    _ => None,\n                }\n            },\n            _ => None,\n        }\n    }\n\n    fn constant_negate(&self, o: &Constant, ty: Ty<'_>) -> Option<Constant> {\n        use self::Constant::{F32, F64, Int};\n        match *o {\n            Int(value) => {\n                let ty::Int(ity) = *ty.kind() else { return None };\n                let (min, _) = ity.min_max()?;\n                // sign extend\n                let value = sext(self.tcx, value, ity);\n\n                // Applying unary - to the most negative value of any signed integer type panics.\n                if value == min {\n                    return None;\n                }\n\n                let value = value.checked_neg()?;\n                // clear unused bits\n                Some(Int(unsext(self.tcx, value, ity)))\n            },\n            F32(f) => Some(F32(-f)),\n            F64(f) => Some(F64(-f)),\n            _ => None,\n        }\n    }\n\n    /// Create `Some(Vec![..])` of all constants, unless there is any\n    /// non-constant part.\n    fn multi(&self, vec: &[Expr<'_>]) -> Option<Vec<Constant>> {\n        vec.iter().map(|elem| self.expr(elem)).collect::<Option<_>>()\n    }\n\n    /// Lookup a possibly constant expression from an `ExprKind::Path` and apply a function on it.\n    #[expect(clippy::too_many_lines)]\n    fn fetch_path(&self, qpath: &QPath<'_>, id: HirId) -> Option<ConstValue> {\n        // Resolve the path to a constant and check if that constant is known to\n        // not change based on the target.\n        //\n        // This should be replaced with an attribute at some point.\n        let did = match *qpath {\n            QPath::Resolved(None, path)\n                if path.span.ctxt() == self.ctxt.get()\n                    && path.segments.iter().all(|s| self.ctxt.get() == s.ident.span.ctxt())\n                    && let Res::Def(DefKind::Const { .. }, did) = path.res\n                    && (matches!(\n                        self.tcx.get_diagnostic_name(did),\n                        Some(\n                            sym::f32_legacy_const_digits\n                                | sym::f32_legacy_const_epsilon\n                                | sym::f32_legacy_const_infinity\n                                | sym::f32_legacy_const_mantissa_dig\n                                | sym::f32_legacy_const_max\n                                | sym::f32_legacy_const_max_10_exp\n                                | sym::f32_legacy_const_max_exp\n                                | sym::f32_legacy_const_min\n                                | sym::f32_legacy_const_min_10_exp\n                                | sym::f32_legacy_const_min_exp\n                                | sym::f32_legacy_const_min_positive\n                                | sym::f32_legacy_const_nan\n                                | sym::f32_legacy_const_neg_infinity\n                                | sym::f32_legacy_const_radix\n                                | sym::f64_legacy_const_digits\n                                | sym::f64_legacy_const_epsilon\n                                | sym::f64_legacy_const_infinity\n                                | sym::f64_legacy_const_mantissa_dig\n                                | sym::f64_legacy_const_max\n                                | sym::f64_legacy_const_max_10_exp\n                                | sym::f64_legacy_const_max_exp\n                                | sym::f64_legacy_const_min\n                                | sym::f64_legacy_const_min_10_exp\n                                | sym::f64_legacy_const_min_exp\n                                | sym::f64_legacy_const_min_positive\n                                | sym::f64_legacy_const_nan\n                                | sym::f64_legacy_const_neg_infinity\n                                | sym::f64_legacy_const_radix\n                                | sym::u8_legacy_const_min\n                                | sym::u16_legacy_const_min\n                                | sym::u32_legacy_const_min\n                                | sym::u64_legacy_const_min\n                                | sym::u128_legacy_const_min\n                                | sym::usize_legacy_const_min\n                                | sym::u8_legacy_const_max\n                                | sym::u16_legacy_const_max\n                                | sym::u32_legacy_const_max\n                                | sym::u64_legacy_const_max\n                                | sym::u128_legacy_const_max\n                                | sym::i8_legacy_const_min\n                                | sym::i16_legacy_const_min\n                                | sym::i32_legacy_const_min\n                                | sym::i64_legacy_const_min\n                                | sym::i128_legacy_const_min\n                                | sym::i8_legacy_const_max\n                                | sym::i16_legacy_const_max\n                                | sym::i32_legacy_const_max\n                                | sym::i64_legacy_const_max\n                                | sym::i128_legacy_const_max\n                        )\n                    ) || self.tcx.opt_parent(did).is_some_and(|parent| {\n                        matches!(\n                            parent.opt_diag_name(&self.tcx),\n                            Some(\n                                sym::f16_consts_mod | sym::f32_consts_mod | sym::f64_consts_mod | sym::f128_consts_mod\n                            )\n                        )\n                    })) =>\n            {\n                did\n            },\n            QPath::TypeRelative(ty, const_name)\n                if let TyKind::Path(QPath::Resolved(None, ty_path)) = ty.kind\n                    && let [.., ty_name] = ty_path.segments\n                    && (matches!(\n                        ty_name.ident.name,\n                        sym::i8\n                            | sym::i16\n                            | sym::i32\n                            | sym::i64\n                            | sym::i128\n                            | sym::u8\n                            | sym::u16\n                            | sym::u32\n                            | sym::u64\n                            | sym::u128\n                            | sym::f32\n                            | sym::f64\n                            | sym::char\n                    ) || (ty_name.ident.name == sym::usize && const_name.ident.name == sym::MIN))\n                    && const_name.ident.span.ctxt() == self.ctxt.get()\n                    && ty.span.ctxt() == self.ctxt.get()\n                    && ty_name.ident.span.ctxt() == self.ctxt.get()\n                    && matches!(ty_path.res, Res::PrimTy(_))\n                    && let Some((DefKind::AssocConst { .. }, did)) = self.typeck.type_dependent_def(id)\n                    && self.tcx.inherent_impl_of_assoc(did).is_some() =>\n            {\n                did\n            },\n            // TODO: revisit when feature `min_generic_const_args` is stabilized. In the meantime,\n            // `TyCtxt::const_eval_resolve()` will trigger an ICE when evaluating the body of the\n            // `type const` definition.\n            _ if let Res::Def(\n                DefKind::Const { is_type_const: false } | DefKind::AssocConst { is_type_const: false },\n                did,\n            ) = self.typeck.qpath_res(qpath, id) =>\n            {\n                self.source.set(ConstantSource::NonLocal);\n                did\n            },\n            _ => return None,\n        };\n\n        self.tcx\n            .const_eval_resolve(\n                self.typing_env,\n                mir::UnevaluatedConst::new(did, self.typeck.node_args(id)),\n                qpath.span(),\n            )\n            .ok()\n    }\n\n    fn index(&self, lhs: &'_ Expr<'_>, index: &'_ Expr<'_>) -> Option<Constant> {\n        let lhs = self.expr(lhs);\n        let index = self.expr(index);\n\n        match (lhs, index) {\n            (Some(Constant::Vec(vec)), Some(Constant::Int(index))) => match vec.get(index as usize) {\n                Some(Constant::F16(x)) => Some(Constant::F16(*x)),\n                Some(Constant::F32(x)) => Some(Constant::F32(*x)),\n                Some(Constant::F64(x)) => Some(Constant::F64(*x)),\n                Some(Constant::F128(x)) => Some(Constant::F128(*x)),\n                _ => None,\n            },\n            (Some(Constant::Vec(vec)), _) => {\n                if !vec.is_empty() && vec.iter().all(|x| *x == vec[0]) {\n                    match vec.first() {\n                        Some(Constant::F16(x)) => Some(Constant::F16(*x)),\n                        Some(Constant::F32(x)) => Some(Constant::F32(*x)),\n                        Some(Constant::F64(x)) => Some(Constant::F64(*x)),\n                        Some(Constant::F128(x)) => Some(Constant::F128(*x)),\n                        _ => None,\n                    }\n                } else {\n                    None\n                }\n            },\n            _ => None,\n        }\n    }\n\n    /// A block can only yield a constant if it has exactly one constant expression.\n    fn block(&self, block: &Block<'_>) -> Option<Constant> {\n        if block.stmts.is_empty()\n            && let Some(expr) = block.expr\n        {\n            // Try to detect any `cfg`ed statements or empty macro expansions.\n            let span = block.span.data();\n            if span.ctxt == SyntaxContext::root() {\n                if let Some(expr_span) = walk_span_to_context(expr.span, span.ctxt)\n                    && let expr_lo = expr_span.lo()\n                    && expr_lo >= span.lo\n                    && let Some(src) = (span.lo..expr_lo).get_source_range(&self.tcx)\n                    && let Some(src) = src.as_str()\n                {\n                    use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace};\n                    if !tokenize(src, FrontmatterAllowed::No)\n                        .map(|t| t.kind)\n                        .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi))\n                        .eq([OpenBrace])\n                    {\n                        self.source.set(ConstantSource::NonLocal);\n                    }\n                } else {\n                    // Unable to access the source. Assume a non-local dependency.\n                    self.source.set(ConstantSource::NonLocal);\n                }\n            }\n\n            self.expr(expr)\n        } else {\n            None\n        }\n    }\n\n    fn ifthenelse(&self, cond: &Expr<'_>, then: &Expr<'_>, otherwise: Option<&Expr<'_>>) -> Option<Constant> {\n        if let Some(Constant::Bool(b)) = self.expr(cond) {\n            if b {\n                self.expr(then)\n            } else {\n                otherwise.as_ref().and_then(|expr| self.expr(expr))\n            }\n        } else {\n            None\n        }\n    }\n\n    fn binop(&self, op: BinOpKind, left: &Expr<'_>, right: &Expr<'_>) -> Option<Constant> {\n        let l = self.expr(left)?;\n        let r = self.expr(right);\n        match (l, r) {\n            (Constant::Int(l), Some(Constant::Int(r))) => match *self.typeck.expr_ty_opt(left)?.kind() {\n                ty::Int(ity) => {\n                    let (ty_min_value, _) = ity.min_max()?;\n                    let bits = ity.bits();\n                    let l = sext(self.tcx, l, ity);\n                    let r = sext(self.tcx, r, ity);\n\n                    // Using / or %, where the left-hand argument is the smallest integer of a signed integer type and\n                    // the right-hand argument is -1 always panics, even with overflow-checks disabled\n                    if let BinOpKind::Div | BinOpKind::Rem = op\n                        && l == ty_min_value\n                        && r == -1\n                    {\n                        return None;\n                    }\n\n                    let zext = |n: i128| Constant::Int(unsext(self.tcx, n, ity));\n                    match op {\n                        // When +, * or binary - create a value greater than the maximum value, or less than\n                        // the minimum value that can be stored, it panics.\n                        BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(zext),\n                        BinOpKind::Sub => l.checked_sub(r).and_then(|n| ity.ensure_fits(n)).map(zext),\n                        BinOpKind::Mul => l.checked_mul(r).and_then(|n| ity.ensure_fits(n)).map(zext),\n                        BinOpKind::Div if r != 0 => l.checked_div(r).map(zext),\n                        BinOpKind::Rem if r != 0 => l.checked_rem(r).map(zext),\n                        // Using << or >> where the right-hand argument is greater than or equal to the number of bits\n                        // in the type of the left-hand argument, or is negative panics.\n                        BinOpKind::Shr if r < bits && !r.is_negative() => l.checked_shr(r.try_into().ok()?).map(zext),\n                        BinOpKind::Shl if r < bits && !r.is_negative() => l.checked_shl(r.try_into().ok()?).map(zext),\n                        BinOpKind::BitXor => Some(zext(l ^ r)),\n                        BinOpKind::BitOr => Some(zext(l | r)),\n                        BinOpKind::BitAnd => Some(zext(l & r)),\n                        // FIXME: f32/f64 currently consider `0.0` and `-0.0` as different.\n                        BinOpKind::Eq => Some(Constant::Bool(l == r)),\n                        BinOpKind::Ne => Some(Constant::Bool(l != r)),\n                        BinOpKind::Lt => Some(Constant::Bool(l < r)),\n                        BinOpKind::Le => Some(Constant::Bool(l <= r)),\n                        BinOpKind::Ge => Some(Constant::Bool(l >= r)),\n                        BinOpKind::Gt => Some(Constant::Bool(l > r)),\n                        _ => None,\n                    }\n                },\n                ty::Uint(ity) => {\n                    let bits = ity.bits();\n\n                    match op {\n                        BinOpKind::Add => l.checked_add(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),\n                        BinOpKind::Sub => l.checked_sub(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),\n                        BinOpKind::Mul => l.checked_mul(r).and_then(|n| ity.ensure_fits(n)).map(Constant::Int),\n                        BinOpKind::Div => l.checked_div(r).map(Constant::Int),\n                        BinOpKind::Rem => l.checked_rem(r).map(Constant::Int),\n                        BinOpKind::Shr if r < bits => l.checked_shr(r.try_into().ok()?).map(Constant::Int),\n                        BinOpKind::Shl if r < bits => l.checked_shl(r.try_into().ok()?).map(Constant::Int),\n                        BinOpKind::BitXor => Some(Constant::Int(l ^ r)),\n                        BinOpKind::BitOr => Some(Constant::Int(l | r)),\n                        BinOpKind::BitAnd => Some(Constant::Int(l & r)),\n                        BinOpKind::Eq => Some(Constant::Bool(l == r)),\n                        BinOpKind::Ne => Some(Constant::Bool(l != r)),\n                        BinOpKind::Lt => Some(Constant::Bool(l < r)),\n                        BinOpKind::Le => Some(Constant::Bool(l <= r)),\n                        BinOpKind::Ge => Some(Constant::Bool(l >= r)),\n                        BinOpKind::Gt => Some(Constant::Bool(l > r)),\n                        _ => None,\n                    }\n                },\n                _ => None,\n            },\n            // FIXME(f16_f128): add these types when binary operations are available on all platforms\n            (Constant::F32(l), Some(Constant::F32(r))) => match op {\n                BinOpKind::Add => Some(Constant::F32(l + r)),\n                BinOpKind::Sub => Some(Constant::F32(l - r)),\n                BinOpKind::Mul => Some(Constant::F32(l * r)),\n                BinOpKind::Div => Some(Constant::F32(l / r)),\n                BinOpKind::Rem => Some(Constant::F32(l % r)),\n                BinOpKind::Eq => Some(Constant::Bool(l == r)),\n                BinOpKind::Ne => Some(Constant::Bool(l != r)),\n                BinOpKind::Lt => Some(Constant::Bool(l < r)),\n                BinOpKind::Le => Some(Constant::Bool(l <= r)),\n                BinOpKind::Ge => Some(Constant::Bool(l >= r)),\n                BinOpKind::Gt => Some(Constant::Bool(l > r)),\n                _ => None,\n            },\n            (Constant::F64(l), Some(Constant::F64(r))) => match op {\n                BinOpKind::Add => Some(Constant::F64(l + r)),\n                BinOpKind::Sub => Some(Constant::F64(l - r)),\n                BinOpKind::Mul => Some(Constant::F64(l * r)),\n                BinOpKind::Div => Some(Constant::F64(l / r)),\n                BinOpKind::Rem => Some(Constant::F64(l % r)),\n                BinOpKind::Eq => Some(Constant::Bool(l == r)),\n                BinOpKind::Ne => Some(Constant::Bool(l != r)),\n                BinOpKind::Lt => Some(Constant::Bool(l < r)),\n                BinOpKind::Le => Some(Constant::Bool(l <= r)),\n                BinOpKind::Ge => Some(Constant::Bool(l >= r)),\n                BinOpKind::Gt => Some(Constant::Bool(l > r)),\n                _ => None,\n            },\n            (l, r) => match (op, l, r) {\n                (BinOpKind::And, Constant::Bool(false), _) => Some(Constant::Bool(false)),\n                (BinOpKind::Or, Constant::Bool(true), _) => Some(Constant::Bool(true)),\n                (BinOpKind::And, Constant::Bool(true), Some(r)) | (BinOpKind::Or, Constant::Bool(false), Some(r)) => {\n                    Some(r)\n                },\n                (BinOpKind::BitXor, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l ^ r)),\n                (BinOpKind::BitAnd, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l & r)),\n                (BinOpKind::BitOr, Constant::Bool(l), Some(Constant::Bool(r))) => Some(Constant::Bool(l | r)),\n                _ => None,\n            },\n        }\n    }\n}\n\npub fn mir_to_const<'tcx>(tcx: TyCtxt<'tcx>, val: ConstValue, ty: Ty<'tcx>) -> Option<Constant> {\n    match (val, ty.kind()) {\n        (_, &ty::Adt(adt_def, _)) if adt_def.is_struct() => Some(Constant::Adt(val)),\n        (ConstValue::Scalar(Scalar::Int(int)), _) => match ty.kind() {\n            ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)),\n            ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.to_bits(int.size()))),\n            ty::Float(FloatTy::F16) => Some(Constant::F16(int.into())),\n            ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits(int.into()))),\n            ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(int.into()))),\n            ty::Float(FloatTy::F128) => Some(Constant::F128(int.into())),\n            ty::RawPtr(_, _) => Some(Constant::RawPtr(int.to_bits(int.size()))),\n            _ => None,\n        },\n        (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => {\n            let data = val.try_get_slice_bytes_for_diagnostics(tcx)?;\n            String::from_utf8(data.to_owned()).ok().map(Constant::Str)\n        },\n        (ConstValue::Indirect { alloc_id, offset }, ty::Array(sub_type, len)) => {\n            let alloc = tcx.global_alloc(alloc_id).unwrap_memory().inner();\n            let len = len.try_to_target_usize(tcx)?;\n            let ty::Float(flt) = sub_type.kind() else {\n                return None;\n            };\n            let size = Size::from_bits(flt.bit_width());\n            let mut res = Vec::new();\n            for idx in 0..len {\n                let range = alloc_range(offset + size * idx, size);\n                let val = alloc.read_scalar(&tcx, range, /* read_provenance */ false).ok()?;\n                res.push(match flt {\n                    FloatTy::F16 => Constant::F16(val.to_u16().discard_err()?),\n                    FloatTy::F32 => Constant::F32(f32::from_bits(val.to_u32().discard_err()?)),\n                    FloatTy::F64 => Constant::F64(f64::from_bits(val.to_u64().discard_err()?)),\n                    FloatTy::F128 => Constant::F128(val.to_u128().discard_err()?),\n                });\n            }\n            Some(Constant::Vec(res))\n        },\n        _ => None,\n    }\n}\n\nfn field_of_struct<'tcx>(\n    adt_def: ty::AdtDef<'tcx>,\n    tcx: TyCtxt<'tcx>,\n    value: ConstValue,\n    ty: Ty<'tcx>,\n    field: Symbol,\n) -> Option<(ConstValue, Ty<'tcx>)> {\n    if let Some(dc) = tcx.try_destructure_mir_constant_for_user_output(value, ty)\n        && let Some(dc_variant) = dc.variant\n        && let Some(variant) = adt_def.variants().get(dc_variant)\n        && let Some(field_idx) = variant.fields.iter().position(|el| el.name == field)\n    {\n        dc.fields.get(field_idx).copied()\n    } else {\n        None\n    }\n}\n\n/// If `expr` evaluates to an integer constant, return its value.\n///\n/// The context argument is the context used to view the evaluated expression. e.g. when evaluating\n/// the argument in `f(m!(1))` the context of the call expression should be used. This is need so\n/// the const evaluator can see the `m` macro and marke the evaluation as non-local independant of\n/// what the macro expands to.\npub fn integer_const(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> Option<u128> {\n    if let Some(Constant::Int(value)) = ConstEvalCtxt::new(cx).eval_local(expr, ctxt) {\n        Some(value)\n    } else {\n        None\n    }\n}\n\n/// Check if `expr` evaluates to an integer constant of 0.\n///\n/// The context argument is the context used to view the evaluated expression. e.g. when evaluating\n/// the argument in `f(m!(1))` the context of the call expression should be used. This is need so\n/// the const evaluator can see the `m` macro and marke the evaluation as non-local independant of\n/// what the macro expands to.\n#[inline]\npub fn is_zero_integer_const(cx: &LateContext<'_>, expr: &Expr<'_>, ctxt: SyntaxContext) -> bool {\n    integer_const(cx, expr, ctxt) == Some(0)\n}\n\npub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    match ct_rhs {\n        ConstItemRhs::Body(body_id) => Some(tcx.hir_body(body_id).value),\n        ConstItemRhs::TypeConst(const_arg) => match const_arg.kind {\n            ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value),\n            ConstArgKind::Struct(..)\n            | ConstArgKind::Tup(..)\n            | ConstArgKind::Literal { .. }\n            | ConstArgKind::TupleCall(..)\n            | ConstArgKind::Array(..)\n            | ConstArgKind::Path(_)\n            | ConstArgKind::Error(..)\n            | ConstArgKind::Infer(..) => None,\n        },\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/diagnostics.rs",
    "content": "//! Clippy wrappers around rustc's diagnostic functions.\n//!\n//! These functions are used by the `INTERNAL_METADATA_COLLECTOR` lint to collect the corresponding\n//! lint applicability. Please make sure that you update the `LINT_EMISSION_FUNCTIONS` variable in\n//! `clippy_lints::utils::internal_lints::metadata_collector` when a new function is added\n//! or renamed.\n//!\n//! Thank you!\n//! ~The `INTERNAL_METADATA_COLLECTOR` lint\n\nuse rustc_errors::{Applicability, Diag, DiagMessage, MultiSpan};\n#[cfg(debug_assertions)]\nuse rustc_errors::{EmissionGuarantee, SubstitutionPart, Suggestions};\nuse rustc_hir::HirId;\nuse rustc_lint::{LateContext, Lint, LintContext};\nuse rustc_span::Span;\nuse std::env;\n\nfn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {\n    if env::var(\"CLIPPY_DISABLE_DOCS_LINKS\").is_err()\n        && let Some(lint) = lint.name_lower().strip_prefix(\"clippy::\")\n    {\n        diag.help(format!(\n            \"for further information visit https://rust-lang.github.io/rust-clippy/{}/index.html#{lint}\",\n            match option_env!(\"CFG_RELEASE_CHANNEL\") {\n                // Clippy version is 0.1.xx\n                //\n                // Always use .0 because we do not generate separate lint doc pages for rust patch releases\n                Some(\"stable\") => concat!(\"rust-1.\", env!(\"CARGO_PKG_VERSION_PATCH\"), \".0\"),\n                Some(\"beta\") => \"beta\",\n                _ => \"master\",\n            }\n        ));\n    }\n}\n\n/// Makes sure that a diagnostic is well formed.\n///\n/// rustc debug asserts a few properties about spans,\n/// but the clippy repo uses a distributed rustc build with debug assertions disabled,\n/// so this has historically led to problems during subtree syncs where those debug assertions\n/// only started triggered there.\n///\n/// This function makes sure we also validate them in debug clippy builds.\n#[cfg(debug_assertions)]\nfn validate_diag(diag: &Diag<'_, impl EmissionGuarantee>) {\n    let suggestions = match &diag.suggestions {\n        Suggestions::Enabled(suggs) => &**suggs,\n        Suggestions::Sealed(suggs) => &**suggs,\n        Suggestions::Disabled => return,\n    };\n\n    for substitution in suggestions.iter().flat_map(|s| &s.substitutions) {\n        assert_eq!(\n            substitution\n                .parts\n                .iter()\n                .find(|SubstitutionPart { snippet, span }| snippet.is_empty() && span.is_empty()),\n            None,\n            \"span must not be empty and have no suggestion\"\n        );\n\n        assert_eq!(\n            substitution\n                .parts\n                .array_windows()\n                .find(|[a, b]| a.span.overlaps(b.span)),\n            None,\n            \"suggestion must not have overlapping parts\"\n        );\n    }\n}\n\n/// Emit a basic lint message with a `msg` and a `span`.\n///\n/// This is the most primitive of our lint emission methods and can\n/// be a good way to get a new lint started.\n///\n/// Usually it's nicer to provide more context for lint messages.\n/// Be sure the output is understandable when you use this method.\n///\n/// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine\n/// the lint level.\n/// For the `span_lint` function, the node that was passed into the `LintPass::check_*` function is\n/// used.\n///\n/// If you're emitting the lint at the span of a different node than the one provided by the\n/// `LintPass::check_*` function, consider using [`span_lint_hir`] instead.\n/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node\n/// highlighted in the displayed warning.\n///\n/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works\n/// where you would expect it to.\n/// If it doesn't, you likely need to use [`span_lint_hir`] instead.\n///\n/// # Example\n///\n/// ```ignore\n/// error: usage of mem::forget on Drop type\n///   --> tests/ui/mem_forget.rs:17:5\n///    |\n/// 17 |     std::mem::forget(seven);\n///    |     ^^^^^^^^^^^^^^^^^^^^^^^\n/// ```\n#[track_caller]\npub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {\n    span_lint_and_then(cx, lint, sp, msg, |_| {});\n}\n\n/// Same as [`span_lint`] but with an extra `help` message.\n///\n/// Use this if you want to provide some general help but\n/// can't provide a specific machine applicable suggestion.\n///\n/// The `help` message can be optionally attached to a `Span`.\n///\n/// If you change the signature, remember to update the internal lint `CollapsibleCalls`\n///\n/// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine\n/// the lint level.\n/// For the `span_lint_and_help` function, the node that was passed into the `LintPass::check_*`\n/// function is used.\n///\n/// If you're emitting the lint at the span of a different node than the one provided by the\n/// `LintPass::check_*` function, consider using [`span_lint_hir_and_then`] instead.\n/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node\n/// highlighted in the displayed warning.\n///\n/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works\n/// where you would expect it to.\n/// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.\n///\n/// # Example\n///\n/// ```text\n/// error: constant division of 0.0 with 0.0 will always result in NaN\n///   --> tests/ui/zero_div_zero.rs:6:25\n///    |\n/// 6  |     let other_f64_nan = 0.0f64 / 0.0;\n///    |                         ^^^^^^^^^^^^\n///    |\n///    = help: consider using `f64::NAN` if you would like a constant representing NaN\n/// ```\n#[track_caller]\npub fn span_lint_and_help<T: LintContext>(\n    cx: &T,\n    lint: &'static Lint,\n    span: impl Into<MultiSpan>,\n    msg: impl Into<DiagMessage>,\n    help_span: Option<Span>,\n    help: impl Into<DiagMessage>,\n) {\n    span_lint_and_then(cx, lint, span, msg, |diag| {\n        if let Some(help_span) = help_span {\n            diag.span_help(help_span, help.into());\n        } else {\n            diag.help(help.into());\n        }\n    });\n}\n\n/// Like [`span_lint`] but with a `note` section instead of a `help` message.\n///\n/// The `note` message is presented separately from the main lint message\n/// and is attached to a specific span:\n///\n/// If you change the signature, remember to update the internal lint `CollapsibleCalls`\n///\n/// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine\n/// the lint level.\n/// For the `span_lint_and_note` function, the node that was passed into the `LintPass::check_*`\n/// function is used.\n///\n/// If you're emitting the lint at the span of a different node than the one provided by the\n/// `LintPass::check_*` function, consider using [`span_lint_hir_and_then`] instead.\n/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node\n/// highlighted in the displayed warning.\n///\n/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works\n/// where you would expect it to.\n/// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.\n///\n/// # Example\n///\n/// ```text\n/// error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing.\n///   --> tests/ui/drop_forget_ref.rs:10:5\n///    |\n/// 10 |     forget(&SomeStruct);\n///    |     ^^^^^^^^^^^^^^^^^^^\n///    |\n///    = note: `-D clippy::forget-ref` implied by `-D warnings`\n/// note: argument has type &SomeStruct\n///   --> tests/ui/drop_forget_ref.rs:10:12\n///    |\n/// 10 |     forget(&SomeStruct);\n///    |            ^^^^^^^^^^^\n/// ```\n#[track_caller]\npub fn span_lint_and_note<T: LintContext>(\n    cx: &T,\n    lint: &'static Lint,\n    span: impl Into<MultiSpan>,\n    msg: impl Into<DiagMessage>,\n    note_span: Option<Span>,\n    note: impl Into<DiagMessage>,\n) {\n    span_lint_and_then(cx, lint, span, msg, |diag| {\n        if let Some(note_span) = note_span {\n            diag.span_note(note_span, note.into());\n        } else {\n            diag.note(note.into());\n        }\n    });\n}\n\n/// Like [`span_lint`] but allows to add notes, help and suggestions using a closure.\n///\n/// If you need to customize your lint output a lot, use this function.\n/// If you change the signature, remember to update the internal lint `CollapsibleCalls`\n///\n/// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine\n/// the lint level.\n/// For the `span_lint_and_then` function, the node that was passed into the `LintPass::check_*`\n/// function is used.\n///\n/// If you're emitting the lint at the span of a different node than the one provided by the\n/// `LintPass::check_*` function, consider using [`span_lint_hir_and_then`] instead.\n/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node\n/// highlighted in the displayed warning.\n///\n/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works\n/// where you would expect it to.\n/// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.\n#[track_caller]\npub fn span_lint_and_then<C, S, M, F>(cx: &C, lint: &'static Lint, sp: S, msg: M, f: F)\nwhere\n    C: LintContext,\n    S: Into<MultiSpan>,\n    M: Into<DiagMessage>,\n    F: FnOnce(&mut Diag<'_, ()>),\n{\n    #[expect(clippy::disallowed_methods)]\n    cx.span_lint(lint, sp, |diag| {\n        diag.primary_message(msg);\n        f(diag);\n        docs_link(diag, lint);\n\n        #[cfg(debug_assertions)]\n        validate_diag(diag);\n    });\n}\n\n/// Like [`span_lint`], but emits the lint at the node identified by the given `HirId`.\n///\n/// This is in contrast to [`span_lint`], which always emits the lint at the node that was last\n/// passed to the `LintPass::check_*` function.\n///\n/// The `HirId` is used for checking lint level attributes and to fulfill lint expectations defined\n/// via the `#[expect]` attribute.\n///\n/// For example:\n/// ```ignore\n/// fn f() { /* <node_1> */\n///\n///     #[allow(clippy::some_lint)]\n///     let _x = /* <expr_1> */;\n/// }\n/// ```\n/// If `some_lint` does its analysis in `LintPass::check_fn` (at `<node_1>`) and emits a lint at\n/// `<expr_1>` using [`span_lint`], then allowing the lint at `<expr_1>` as attempted in the snippet\n/// will not work!\n/// Even though that is where the warning points at, which would be confusing to users.\n///\n/// Instead, use this function and also pass the `HirId` of `<expr_1>`, which will let\n/// the compiler check lint level attributes at the place of the expression and\n/// the `#[allow]` will work.\n#[track_caller]\npub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: impl Into<DiagMessage>) {\n    span_lint_hir_and_then(cx, lint, hir_id, sp, msg, |_| {});\n}\n\n/// Like [`span_lint_and_then`], but emits the lint at the node identified by the given `HirId`.\n///\n/// This is in contrast to [`span_lint_and_then`], which always emits the lint at the node that was\n/// last passed to the `LintPass::check_*` function.\n///\n/// The `HirId` is used for checking lint level attributes and to fulfill lint expectations defined\n/// via the `#[expect]` attribute.\n///\n/// For example:\n/// ```ignore\n/// fn f() { /* <node_1> */\n///\n///     #[allow(clippy::some_lint)]\n///     let _x = /* <expr_1> */;\n/// }\n/// ```\n/// If `some_lint` does its analysis in `LintPass::check_fn` (at `<node_1>`) and emits a lint at\n/// `<expr_1>` using [`span_lint`], then allowing the lint at `<expr_1>` as attempted in the snippet\n/// will not work!\n/// Even though that is where the warning points at, which would be confusing to users.\n///\n/// Instead, use this function and also pass the `HirId` of `<expr_1>`, which will let\n/// the compiler check lint level attributes at the place of the expression and\n/// the `#[allow]` will work.\n#[track_caller]\npub fn span_lint_hir_and_then(\n    cx: &LateContext<'_>,\n    lint: &'static Lint,\n    hir_id: HirId,\n    sp: impl Into<MultiSpan>,\n    msg: impl Into<DiagMessage>,\n    f: impl FnOnce(&mut Diag<'_, ()>),\n) {\n    #[expect(clippy::disallowed_methods)]\n    cx.tcx.node_span_lint(lint, hir_id, sp, |diag| {\n        diag.primary_message(msg);\n        f(diag);\n        docs_link(diag, lint);\n\n        #[cfg(debug_assertions)]\n        validate_diag(diag);\n    });\n}\n\n/// Add a span lint with a suggestion on how to fix it.\n///\n/// These suggestions can be parsed by rustfix to allow it to automatically fix your code.\n/// In the example below, `help` is `\"try\"` and `sugg` is the suggested replacement `\".any(|x| x >\n/// 2)\"`.\n///\n/// If you change the signature, remember to update the internal lint `CollapsibleCalls`\n///\n/// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine\n/// the lint level.\n/// For the `span_lint_and_sugg` function, the node that was passed into the `LintPass::check_*`\n/// function is used.\n///\n/// If you're emitting the lint at the span of a different node than the one provided by the\n/// `LintPass::check_*` function, consider using [`span_lint_hir_and_then`] instead.\n/// This is needed for `#[allow]` and `#[expect]` attributes to work on the node\n/// highlighted in the displayed warning.\n///\n/// If you're unsure which function you should use, you can test if the `#[expect]` attribute works\n/// where you would expect it to.\n/// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.\n///\n/// # Example\n///\n/// ```text\n/// error: This `.fold` can be more succinctly expressed as `.any`\n/// --> tests/ui/methods.rs:390:13\n///     |\n/// 390 |     let _ = (0..3).fold(false, |acc, x| acc || x > 2);\n///     |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.any(|x| x > 2)`\n///     |\n///     = note: `-D fold-any` implied by `-D warnings`\n/// ```\n#[track_caller]\npub fn span_lint_and_sugg<T: LintContext>(\n    cx: &T,\n    lint: &'static Lint,\n    sp: Span,\n    msg: impl Into<DiagMessage>,\n    help: impl Into<DiagMessage>,\n    sugg: String,\n    applicability: Applicability,\n) {\n    span_lint_and_then(cx, lint, sp, msg.into(), |diag| {\n        diag.span_suggestion(sp, help.into(), sugg, applicability);\n\n        // This dummy construct is here to prevent the internal `clippy::collapsible_span_lint_calls`\n        // lint from triggering. We don't want to allow/expect it as internal lints might or might\n        // not be activated when linting, and we don't want an unknown lint warning either.\n        std::hint::black_box(());\n    });\n}\n"
  },
  {
    "path": "clippy_utils/src/eager_or_lazy.rs",
    "content": "//! Utilities for evaluating whether eagerly evaluated expressions can be made lazy and vice versa.\n//!\n//! Things to consider:\n//!  - does the expression have side-effects?\n//!  - is the expression computationally expensive?\n//!\n//! See lints:\n//!  - unnecessary-lazy-evaluations\n//!  - or-fun-call\n//!  - option-if-let-else\n\nuse crate::consts::{ConstEvalCtxt, FullInt};\nuse crate::sym;\nuse crate::ty::{all_predicates_of, is_copy};\nuse crate::visitors::is_const_evaluatable;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{BinOpKind, Block, Expr, ExprKind, QPath, UnOp};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty;\nuse rustc_middle::ty::adjustment::{Adjust, DerefAdjustKind};\nuse rustc_span::Symbol;\nuse std::{cmp, ops};\n\n#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]\nenum EagernessSuggestion {\n    // The expression is cheap and should be evaluated eagerly\n    Eager,\n    // The expression may be cheap, so don't suggested lazy evaluation; or the expression may not be safe to switch to\n    // eager evaluation.\n    NoChange,\n    // The expression is likely expensive and should be evaluated lazily.\n    Lazy,\n    // The expression cannot be placed into a closure.\n    ForceNoChange,\n}\nimpl ops::BitOr for EagernessSuggestion {\n    type Output = Self;\n    fn bitor(self, rhs: Self) -> Self {\n        cmp::max(self, rhs)\n    }\n}\nimpl ops::BitOrAssign for EagernessSuggestion {\n    fn bitor_assign(&mut self, rhs: Self) {\n        *self = *self | rhs;\n    }\n}\n\n/// Determine the eagerness of the given function call.\nfn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: bool) -> EagernessSuggestion {\n    use EagernessSuggestion::{Eager, Lazy, NoChange};\n\n    let ty = match cx.tcx.impl_of_assoc(fn_id) {\n        Some(id) => cx.tcx.type_of(id).instantiate_identity(),\n        None => return Lazy,\n    };\n\n    if (matches!(name, sym::is_empty | sym::len) || name.as_str().starts_with(\"as_\")) && have_one_arg {\n        if matches!(\n            cx.tcx.crate_name(fn_id.krate),\n            sym::std | sym::core | sym::alloc | sym::proc_macro\n        ) {\n            Eager\n        } else {\n            NoChange\n        }\n    } else if let ty::Adt(def, subs) = ty.kind() {\n        // Types where the only fields are generic types (or references to) with no trait bounds other\n        // than marker traits.\n        // Due to the limited operations on these types functions should be fairly cheap.\n        if def.variants().iter().flat_map(|v| v.fields.iter()).any(|x| {\n            matches!(\n                cx.tcx.type_of(x.did).instantiate_identity().peel_refs().kind(),\n                ty::Param(_)\n            )\n        }) && all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() {\n            ty::ClauseKind::Trait(pred) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker,\n            _ => true,\n        }) && subs.types().all(|x| matches!(x.peel_refs().kind(), ty::Param(_)))\n        {\n            // Limit the function to either `(self) -> bool` or `(&self) -> bool`\n            match &**cx\n                .tcx\n                .fn_sig(fn_id)\n                .instantiate_identity()\n                .skip_binder()\n                .inputs_and_output\n            {\n                [arg, res] if !arg.is_mutable_ptr() && arg.peel_refs() == ty && res.is_bool() => NoChange,\n                _ => Lazy,\n            }\n        } else {\n            Lazy\n        }\n    } else {\n        Lazy\n    }\n}\n\nfn res_has_significant_drop(res: Res, cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    if let Res::Def(DefKind::Ctor(..) | DefKind::Variant | DefKind::Enum | DefKind::Struct, _)\n    | Res::SelfCtor(_)\n    | Res::SelfTyAlias { .. } = res\n    {\n        cx.typeck_results()\n            .expr_ty(e)\n            .has_significant_drop(cx.tcx, cx.typing_env())\n    } else {\n        false\n    }\n}\n\n#[expect(clippy::too_many_lines)]\nfn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessSuggestion {\n    struct V<'cx, 'tcx> {\n        cx: &'cx LateContext<'tcx>,\n        eagerness: EagernessSuggestion,\n    }\n\n    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {\n            use EagernessSuggestion::{ForceNoChange, Lazy, NoChange};\n            if self.eagerness == ForceNoChange {\n                return;\n            }\n\n            // Autoderef through a user-defined `Deref` impl can have side-effects,\n            // so don't suggest changing it.\n            if self\n                .cx\n                .typeck_results()\n                .expr_adjustments(e)\n                .iter()\n                .any(|adj| matches!(adj.kind, Adjust::Deref(DerefAdjustKind::Overloaded(_))))\n            {\n                self.eagerness |= NoChange;\n                return;\n            }\n\n            match e.kind {\n                ExprKind::Call(\n                    &Expr {\n                        kind: ExprKind::Path(ref path),\n                        hir_id,\n                        ..\n                    },\n                    args,\n                ) => match self.cx.qpath_res(path, hir_id) {\n                    res @ (Res::Def(DefKind::Ctor(..) | DefKind::Variant, _) | Res::SelfCtor(_)) => {\n                        if res_has_significant_drop(res, self.cx, e) {\n                            self.eagerness = ForceNoChange;\n                            return;\n                        }\n                    },\n                    Res::Def(_, id) if self.cx.tcx.is_promotable_const_fn(id) => (),\n                    // No need to walk the arguments here, `is_const_evaluatable` already did\n                    Res::Def(..) if is_const_evaluatable(self.cx, e) => {\n                        self.eagerness |= NoChange;\n                        return;\n                    },\n                    Res::Def(_, id) => match path {\n                        QPath::Resolved(_, p) => {\n                            self.eagerness |=\n                                fn_eagerness(self.cx, id, p.segments.last().unwrap().ident.name, !args.is_empty());\n                        },\n                        QPath::TypeRelative(_, name) => {\n                            self.eagerness |= fn_eagerness(self.cx, id, name.ident.name, !args.is_empty());\n                        },\n                    },\n                    _ => self.eagerness = Lazy,\n                },\n                // No need to walk the arguments here, `is_const_evaluatable` already did\n                ExprKind::MethodCall(..) if is_const_evaluatable(self.cx, e) => {\n                    self.eagerness |= NoChange;\n                    return;\n                },\n                #[expect(clippy::match_same_arms)] // arm pattern can't be merged due to `ref`, see rust#105778\n                ExprKind::Struct(path, ..) => {\n                    if res_has_significant_drop(self.cx.qpath_res(path, e.hir_id), self.cx, e) {\n                        self.eagerness = ForceNoChange;\n                        return;\n                    }\n                },\n                ExprKind::Path(ref path) => {\n                    if res_has_significant_drop(self.cx.qpath_res(path, e.hir_id), self.cx, e) {\n                        self.eagerness = ForceNoChange;\n                        return;\n                    }\n                },\n                ExprKind::MethodCall(name, ..) => {\n                    self.eagerness |= self\n                        .cx\n                        .typeck_results()\n                        .type_dependent_def_id(e.hir_id)\n                        .map_or(Lazy, |id| fn_eagerness(self.cx, id, name.ident.name, true));\n                },\n                ExprKind::Index(_, e, _) => {\n                    let ty = self.cx.typeck_results().expr_ty_adjusted(e);\n                    if is_copy(self.cx, ty) && !ty.is_ref() {\n                        self.eagerness |= NoChange;\n                    } else {\n                        self.eagerness = Lazy;\n                    }\n                },\n\n                // `-i32::MIN` panics with overflow checks\n                ExprKind::Unary(UnOp::Neg, right) if ConstEvalCtxt::new(self.cx).eval(right).is_none() => {\n                    self.eagerness |= NoChange;\n                },\n\n                // Custom `Deref` impl might have side effects\n                ExprKind::Unary(UnOp::Deref, e)\n                    if self.cx.typeck_results().expr_ty(e).builtin_deref(true).is_none() =>\n                {\n                    self.eagerness |= NoChange;\n                },\n                // Dereferences should be cheap, but dereferencing a raw pointer earlier may not be safe.\n                ExprKind::Unary(UnOp::Deref, e) if !self.cx.typeck_results().expr_ty(e).is_raw_ptr() => (),\n                ExprKind::Unary(UnOp::Deref, _) => self.eagerness |= NoChange,\n                ExprKind::Unary(_, e)\n                    if matches!(\n                        self.cx.typeck_results().expr_ty(e).kind(),\n                        ty::Bool | ty::Int(_) | ty::Uint(_),\n                    ) => {},\n\n                // `>>` and `<<` panic when the right-hand side is greater than or equal to the number of bits in the\n                // type of the left-hand side, or is negative.\n                // We intentionally only check if the right-hand isn't a constant, because even if the suggestion would\n                // overflow with constants, the compiler emits an error for it and the programmer will have to fix it.\n                // Thus, we would realistically only delay the lint.\n                ExprKind::Binary(op, _, right)\n                    if matches!(op.node, BinOpKind::Shl | BinOpKind::Shr)\n                        && ConstEvalCtxt::new(self.cx).eval(right).is_none() =>\n                {\n                    self.eagerness |= NoChange;\n                },\n\n                ExprKind::Binary(op, left, right)\n                    if matches!(op.node, BinOpKind::Div | BinOpKind::Rem)\n                        && let right_ty = self.cx.typeck_results().expr_ty(right)\n                        && let ecx = ConstEvalCtxt::new(self.cx)\n                        && let left = ecx.eval(left)\n                        && let right = ecx.eval(right).and_then(|c| c.int_value(self.cx.tcx, right_ty))\n                        && matches!(\n                            (left, right),\n                            // `1 / x`: x might be zero\n                            (_, None)\n                            // `x / -1`: x might be T::MIN\n                            | (None, Some(FullInt::S(-1)))\n                        ) =>\n                {\n                    self.eagerness |= NoChange;\n                },\n\n                // Similar to `>>` and `<<`, we only want to avoid linting entirely if either side is unknown and the\n                // compiler can't emit an error for an overflowing expression.\n                // Suggesting eagerness for `true.then(|| i32::MAX + 1)` is okay because the compiler will emit an\n                // error and it's good to have the eagerness warning up front when the user fixes the logic error.\n                ExprKind::Binary(op, left, right)\n                    if matches!(op.node, BinOpKind::Add | BinOpKind::Sub | BinOpKind::Mul)\n                        && !self.cx.typeck_results().expr_ty(e).is_floating_point()\n                        && let ecx = ConstEvalCtxt::new(self.cx)\n                        && (ecx.eval(left).is_none() || ecx.eval(right).is_none()) =>\n                {\n                    self.eagerness |= NoChange;\n                },\n\n                ExprKind::Binary(_, lhs, rhs)\n                    if self.cx.typeck_results().expr_ty(lhs).is_primitive()\n                        && self.cx.typeck_results().expr_ty(rhs).is_primitive() => {},\n\n                // Can't be moved into a closure\n                ExprKind::Break(..)\n                | ExprKind::Continue(_)\n                | ExprKind::Ret(_)\n                | ExprKind::Become(_)\n                | ExprKind::InlineAsm(_)\n                | ExprKind::Yield(..)\n                | ExprKind::Err(_) => {\n                    self.eagerness = ForceNoChange;\n                    return;\n                },\n\n                // Memory allocation, custom operator, loop, or call to an unknown function\n                ExprKind::Unary(..) | ExprKind::Binary(..) | ExprKind::Loop(..) | ExprKind::Call(..) => {\n                    self.eagerness = Lazy;\n                },\n\n                ExprKind::ConstBlock(_)\n                | ExprKind::Array(_)\n                | ExprKind::Tup(_)\n                | ExprKind::Use(..)\n                | ExprKind::Lit(_)\n                | ExprKind::Cast(..)\n                | ExprKind::Type(..)\n                | ExprKind::DropTemps(_)\n                | ExprKind::Let(..)\n                | ExprKind::If(..)\n                | ExprKind::Match(..)\n                | ExprKind::Closure { .. }\n                | ExprKind::Field(..)\n                | ExprKind::AddrOf(..)\n                | ExprKind::Repeat(..)\n                | ExprKind::Block(Block { stmts: [], .. }, _)\n                | ExprKind::OffsetOf(..)\n                | ExprKind::UnsafeBinderCast(..) => (),\n\n                // Assignment might be to a local defined earlier, so don't eagerly evaluate.\n                // Blocks with multiple statements might be expensive, so don't eagerly evaluate.\n                // TODO: Actually check if either of these are true here.\n                ExprKind::Assign(..) | ExprKind::AssignOp(..) | ExprKind::Block(..) => self.eagerness |= NoChange,\n            }\n            walk_expr(self, e);\n        }\n    }\n\n    let mut v = V {\n        cx,\n        eagerness: EagernessSuggestion::Eager,\n    };\n    v.visit_expr(e);\n    v.eagerness\n}\n\n/// Whether the given expression should be changed to evaluate eagerly\npub fn switch_to_eager_eval<'tcx>(cx: &'_ LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {\n    expr_eagerness(cx, expr) == EagernessSuggestion::Eager\n}\n\n/// Whether the given expression should be changed to evaluate lazily\npub fn switch_to_lazy_eval<'tcx>(cx: &'_ LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {\n    expr_eagerness(cx, expr) == EagernessSuggestion::Lazy\n}\n"
  },
  {
    "path": "clippy_utils/src/higher.rs",
    "content": "//! This module contains functions that retrieve specific elements.\n\n#![deny(clippy::missing_docs_in_private_items)]\n\nuse crate::consts::{ConstEvalCtxt, Constant};\nuse crate::res::MaybeDef;\nuse crate::{is_expn_of, sym};\n\nuse rustc_ast::ast;\nuse rustc_hir as hir;\nuse rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath, StructTailExpr};\nuse rustc_lint::LateContext;\nuse rustc_span::{Span, symbol};\n\n/// The essential nodes of a desugared for loop as well as the entire span:\n/// `for pat in arg { body }` becomes `(pat, arg, body)`. Returns `(pat, arg, body, span)`.\n#[derive(Debug)]\npub struct ForLoop<'tcx> {\n    /// `for` loop item\n    pub pat: &'tcx Pat<'tcx>,\n    /// `IntoIterator` argument\n    pub arg: &'tcx Expr<'tcx>,\n    /// `for` loop body\n    pub body: &'tcx Expr<'tcx>,\n    /// Compare this against `hir::Destination.target`\n    pub loop_id: HirId,\n    /// entire `for` loop span\n    pub span: Span,\n    /// label\n    pub label: Option<ast::Label>,\n}\n\nimpl<'tcx> ForLoop<'tcx> {\n    /// Parses a desugared `for` loop\n    pub fn hir(expr: &Expr<'tcx>) -> Option<Self> {\n        if let ExprKind::DropTemps(e) = expr.kind\n            && let ExprKind::Match(iterexpr, [arm], MatchSource::ForLoopDesugar) = e.kind\n            && let ExprKind::Call(_, [arg]) = iterexpr.kind\n            && let ExprKind::Loop(block, label, ..) = arm.body.kind\n            && let [stmt] = block.stmts\n            && let hir::StmtKind::Expr(e) = stmt.kind\n            && let ExprKind::Match(_, [_, some_arm], _) = e.kind\n            && let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind\n        {\n            return Some(Self {\n                pat: field.pat,\n                arg,\n                body: some_arm.body,\n                loop_id: arm.body.hir_id,\n                span: expr.span.ctxt().outer_expn_data().call_site,\n                label,\n            });\n        }\n        None\n    }\n}\n\n/// An `if` expression without `let`\npub struct If<'hir> {\n    /// `if` condition\n    pub cond: &'hir Expr<'hir>,\n    /// `if` then expression\n    pub then: &'hir Expr<'hir>,\n    /// `else` expression\n    pub r#else: Option<&'hir Expr<'hir>>,\n}\n\nimpl<'hir> If<'hir> {\n    #[inline]\n    /// Parses an `if` expression without `let`\n    pub const fn hir(expr: &Expr<'hir>) -> Option<Self> {\n        if let ExprKind::If(cond, then, r#else) = expr.kind\n            && !has_let_expr(cond)\n        {\n            Some(Self { cond, then, r#else })\n        } else {\n            None\n        }\n    }\n}\n\n/// An `if let` expression\npub struct IfLet<'hir> {\n    /// `if let` pattern\n    pub let_pat: &'hir Pat<'hir>,\n    /// `if let` scrutinee\n    pub let_expr: &'hir Expr<'hir>,\n    /// `if let` then expression\n    pub if_then: &'hir Expr<'hir>,\n    /// `if let` else expression\n    pub if_else: Option<&'hir Expr<'hir>>,\n    /// `if let PAT = EXPR`\n    ///     ^^^^^^^^^^^^^^\n    pub let_span: Span,\n}\n\nimpl<'hir> IfLet<'hir> {\n    /// Parses an `if let` expression\n    pub fn hir(cx: &LateContext<'_>, expr: &Expr<'hir>) -> Option<Self> {\n        if let ExprKind::If(\n            &Expr {\n                kind:\n                    ExprKind::Let(&hir::LetExpr {\n                        pat: let_pat,\n                        init: let_expr,\n                        span: let_span,\n                        ..\n                    }),\n                ..\n            },\n            if_then,\n            if_else,\n        ) = expr.kind\n        {\n            let mut iter = cx.tcx.hir_parent_iter(expr.hir_id);\n            if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next()\n                && let Some((\n                    _,\n                    Node::Expr(Expr {\n                        kind: ExprKind::Loop(_, _, LoopSource::While, _),\n                        ..\n                    }),\n                )) = iter.next()\n            {\n                // while loop desugar\n                return None;\n            }\n            return Some(Self {\n                let_pat,\n                let_expr,\n                if_then,\n                if_else,\n                let_span,\n            });\n        }\n        None\n    }\n}\n\n/// An `if let` or `match` expression. Useful for lints that trigger on one or the other.\n#[derive(Debug)]\npub enum IfLetOrMatch<'hir> {\n    /// Any `match` expression\n    Match(&'hir Expr<'hir>, &'hir [Arm<'hir>], MatchSource),\n    /// scrutinee, pattern, then block, else block\n    IfLet(\n        &'hir Expr<'hir>,\n        &'hir Pat<'hir>,\n        &'hir Expr<'hir>,\n        Option<&'hir Expr<'hir>>,\n        /// `if let PAT = EXPR`\n        ///     ^^^^^^^^^^^^^^\n        Span,\n    ),\n}\n\nimpl<'hir> IfLetOrMatch<'hir> {\n    /// Parses an `if let` or `match` expression\n    pub fn parse(cx: &LateContext<'_>, expr: &Expr<'hir>) -> Option<Self> {\n        match expr.kind {\n            ExprKind::Match(expr, arms, source) => Some(Self::Match(expr, arms, source)),\n            _ => IfLet::hir(cx, expr).map(\n                |IfLet {\n                     let_expr,\n                     let_pat,\n                     if_then,\n                     if_else,\n                     let_span,\n                 }| { Self::IfLet(let_expr, let_pat, if_then, if_else, let_span) },\n            ),\n        }\n    }\n\n    pub fn scrutinee(&self) -> &'hir Expr<'hir> {\n        match self {\n            Self::Match(scrutinee, _, _) | Self::IfLet(scrutinee, _, _, _, _) => scrutinee,\n        }\n    }\n}\n\n/// An `if` or `if let` expression\npub struct IfOrIfLet<'hir> {\n    /// `if` condition that is maybe a `let` expression\n    pub cond: &'hir Expr<'hir>,\n    /// `if` then expression\n    pub then: &'hir Expr<'hir>,\n    /// `else` expression\n    pub r#else: Option<&'hir Expr<'hir>>,\n}\n\nimpl<'hir> IfOrIfLet<'hir> {\n    #[inline]\n    /// Parses an `if` or `if let` expression\n    pub const fn hir(expr: &Expr<'hir>) -> Option<Self> {\n        if let ExprKind::If(cond, then, r#else) = expr.kind {\n            Some(Self { cond, then, r#else })\n        } else {\n            None\n        }\n    }\n}\n\n/// Represent a range akin to `ast::ExprKind::Range`.\n#[derive(Debug, Copy, Clone)]\npub struct Range<'a> {\n    /// The lower bound of the range, or `None` for ranges such as `..X`.\n    pub start: Option<&'a Expr<'a>>,\n    /// The upper bound of the range, or `None` for ranges such as `X..`.\n    pub end: Option<&'a Expr<'a>>,\n    /// Whether the interval is open or closed.\n    pub limits: ast::RangeLimits,\n    pub span: Span,\n}\n\nimpl<'a> Range<'a> {\n    /// Higher a `hir` range to something similar to `ast::ExprKind::Range`.\n    #[expect(clippy::similar_names)]\n    pub fn hir(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<Range<'a>> {\n        let span = expr.range_span()?;\n        match expr.kind {\n            ExprKind::Call(path, [arg1, arg2])\n                if let ExprKind::Path(qpath) = path.kind\n                    && cx.tcx.qpath_is_lang_item(qpath, hir::LangItem::RangeInclusiveNew) =>\n            {\n                Some(Range {\n                    start: Some(arg1),\n                    end: Some(arg2),\n                    limits: ast::RangeLimits::Closed,\n                    span,\n                })\n            },\n            ExprKind::Struct(&qpath, fields, StructTailExpr::None) => match (cx.tcx.qpath_lang_item(qpath)?, fields) {\n                (hir::LangItem::RangeFull, []) => Some(Range {\n                    start: None,\n                    end: None,\n                    limits: ast::RangeLimits::HalfOpen,\n                    span,\n                }),\n                (hir::LangItem::RangeFrom, [field]) if field.ident.name == sym::start => Some(Range {\n                    start: Some(field.expr),\n                    end: None,\n                    limits: ast::RangeLimits::HalfOpen,\n                    span,\n                }),\n                (hir::LangItem::Range, [field1, field2]) => {\n                    let (start, end) = match (field1.ident.name, field2.ident.name) {\n                        (sym::start, sym::end) => (field1.expr, field2.expr),\n                        (sym::end, sym::start) => (field2.expr, field1.expr),\n                        _ => return None,\n                    };\n                    Some(Range {\n                        start: Some(start),\n                        end: Some(end),\n                        limits: ast::RangeLimits::HalfOpen,\n                        span,\n                    })\n                },\n                (hir::LangItem::RangeToInclusive, [field]) if field.ident.name == sym::end => Some(Range {\n                    start: None,\n                    end: Some(field.expr),\n                    limits: ast::RangeLimits::Closed,\n                    span,\n                }),\n                (hir::LangItem::RangeTo, [field]) if field.ident.name == sym::end => Some(Range {\n                    start: None,\n                    end: Some(field.expr),\n                    limits: ast::RangeLimits::HalfOpen,\n                    span,\n                }),\n                _ => None,\n            },\n            _ => None,\n        }\n    }\n}\n\n/// Represents the pre-expansion arguments of a `vec!` invocation.\npub enum VecArgs<'a> {\n    /// `vec![elem; len]`\n    Repeat(&'a Expr<'a>, &'a Expr<'a>),\n    /// `vec![a, b, c]`\n    Vec(&'a [Expr<'a>]),\n}\n\nimpl<'a> VecArgs<'a> {\n    /// Returns the arguments of the `vec!` macro if this expression was expanded\n    /// from `vec!`.\n    pub fn hir(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<VecArgs<'a>> {\n        if let ExprKind::Call(fun, args) = expr.kind\n            && let ExprKind::Path(ref qpath) = fun.kind\n            && is_expn_of(fun.span, sym::vec).is_some()\n            && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()\n            && let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id)\n        {\n            return match (name, args) {\n                (sym::vec_from_elem, [elem, size]) => {\n                    // `vec![elem; size]` case\n                    Some(VecArgs::Repeat(elem, size))\n                },\n                (sym::box_assume_init_into_vec_unsafe, [write_box_via_move])\n                    if let ExprKind::Call(_, [_box, elems]) = write_box_via_move.kind\n                        && let ExprKind::Array(elems) = elems.kind =>\n                {\n                    // `vec![a, b, c]` case\n                    Some(VecArgs::Vec(elems))\n                },\n                (sym::vec_new, []) => Some(VecArgs::Vec(&[])),\n                _ => None,\n            };\n        }\n\n        None\n    }\n}\n\n/// A desugared `while` loop\npub struct While<'hir> {\n    /// `while` loop condition\n    pub condition: &'hir Expr<'hir>,\n    /// `while` loop body\n    pub body: &'hir Expr<'hir>,\n    /// Span of the loop header\n    pub span: Span,\n    pub label: Option<ast::Label>,\n}\n\nimpl<'hir> While<'hir> {\n    #[inline]\n    /// Parses a desugared `while` loop\n    pub const fn hir(expr: &Expr<'hir>) -> Option<Self> {\n        if let ExprKind::Loop(\n            Block {\n                expr:\n                    Some(Expr {\n                        kind: ExprKind::If(condition, body, _),\n                        ..\n                    }),\n                ..\n            },\n            label,\n            LoopSource::While,\n            span,\n        ) = expr.kind\n            && !has_let_expr(condition)\n        {\n            return Some(Self {\n                condition,\n                body,\n                span,\n                label,\n            });\n        }\n        None\n    }\n}\n\n/// A desugared `while let` loop\npub struct WhileLet<'hir> {\n    /// `while let` loop item pattern\n    pub let_pat: &'hir Pat<'hir>,\n    /// `while let` loop scrutinee\n    pub let_expr: &'hir Expr<'hir>,\n    /// `while let` loop body\n    pub if_then: &'hir Expr<'hir>,\n    pub label: Option<ast::Label>,\n    /// `while let PAT = EXPR`\n    ///        ^^^^^^^^^^^^^^\n    pub let_span: Span,\n}\n\nimpl<'hir> WhileLet<'hir> {\n    #[inline]\n    /// Parses a desugared `while let` loop\n    pub const fn hir(expr: &Expr<'hir>) -> Option<Self> {\n        if let ExprKind::Loop(\n            &Block {\n                expr:\n                    Some(&Expr {\n                        kind:\n                            ExprKind::If(\n                                &Expr {\n                                    kind:\n                                        ExprKind::Let(&hir::LetExpr {\n                                            pat: let_pat,\n                                            init: let_expr,\n                                            span: let_span,\n                                            ..\n                                        }),\n                                    ..\n                                },\n                                if_then,\n                                _,\n                            ),\n                        ..\n                    }),\n                ..\n            },\n            label,\n            LoopSource::While,\n            _,\n        ) = expr.kind\n        {\n            return Some(Self {\n                let_pat,\n                let_expr,\n                if_then,\n                label,\n                let_span,\n            });\n        }\n        None\n    }\n}\n\n/// Converts a `hir` binary operator to the corresponding `ast` type.\n#[must_use]\npub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {\n    match op {\n        hir::BinOpKind::Eq => ast::BinOpKind::Eq,\n        hir::BinOpKind::Ge => ast::BinOpKind::Ge,\n        hir::BinOpKind::Gt => ast::BinOpKind::Gt,\n        hir::BinOpKind::Le => ast::BinOpKind::Le,\n        hir::BinOpKind::Lt => ast::BinOpKind::Lt,\n        hir::BinOpKind::Ne => ast::BinOpKind::Ne,\n        hir::BinOpKind::Or => ast::BinOpKind::Or,\n        hir::BinOpKind::Add => ast::BinOpKind::Add,\n        hir::BinOpKind::And => ast::BinOpKind::And,\n        hir::BinOpKind::BitAnd => ast::BinOpKind::BitAnd,\n        hir::BinOpKind::BitOr => ast::BinOpKind::BitOr,\n        hir::BinOpKind::BitXor => ast::BinOpKind::BitXor,\n        hir::BinOpKind::Div => ast::BinOpKind::Div,\n        hir::BinOpKind::Mul => ast::BinOpKind::Mul,\n        hir::BinOpKind::Rem => ast::BinOpKind::Rem,\n        hir::BinOpKind::Shl => ast::BinOpKind::Shl,\n        hir::BinOpKind::Shr => ast::BinOpKind::Shr,\n        hir::BinOpKind::Sub => ast::BinOpKind::Sub,\n    }\n}\n\n/// A parsed `Vec` initialization expression\n#[derive(Clone, Copy)]\npub enum VecInitKind {\n    /// `Vec::new()`\n    New,\n    /// `Vec::default()` or `Default::default()`\n    Default,\n    /// `Vec::with_capacity(123)`\n    WithConstCapacity(u128),\n    /// `Vec::with_capacity(slice.len())`\n    WithExprCapacity(HirId),\n}\n\n/// Checks if the given expression is an initialization of `Vec` and returns its kind.\npub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<VecInitKind> {\n    if let ExprKind::Call(func, args) = expr.kind {\n        match func.kind {\n            ExprKind::Path(QPath::TypeRelative(ty, name))\n                if cx.typeck_results().node_type(ty.hir_id).is_diag_item(cx, sym::Vec) =>\n            {\n                if name.ident.name == sym::new {\n                    return Some(VecInitKind::New);\n                } else if name.ident.name == symbol::kw::Default {\n                    return Some(VecInitKind::Default);\n                } else if name.ident.name == sym::with_capacity {\n                    let arg = args.first()?;\n                    return match ConstEvalCtxt::new(cx).eval_local(arg, expr.span.ctxt()) {\n                        Some(Constant::Int(num)) => Some(VecInitKind::WithConstCapacity(num)),\n                        _ => Some(VecInitKind::WithExprCapacity(arg.hir_id)),\n                    };\n                }\n            },\n            ExprKind::Path(QPath::Resolved(_, path))\n                if cx.tcx.is_diagnostic_item(sym::default_fn, path.res.opt_def_id()?)\n                    && cx.typeck_results().expr_ty(expr).is_diag_item(cx, sym::Vec) =>\n            {\n                return Some(VecInitKind::Default);\n            },\n            _ => (),\n        }\n    }\n    None\n}\n\n/// Checks that a condition doesn't have a `let` expression, to keep `If` and `While` from accepting\n/// `if let` and `while let`.\npub const fn has_let_expr<'tcx>(cond: &'tcx Expr<'tcx>) -> bool {\n    match &cond.kind {\n        ExprKind::Let(_) => true,\n        ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/hir_utils.rs",
    "content": "use crate::consts::ConstEvalCtxt;\nuse crate::macros::macro_backtrace;\nuse crate::source::{SpanRange, SpanRangeExt, walk_span_to_context};\nuse crate::{sym, tokenize_with_text};\nuse rustc_ast::ast;\nuse rustc_ast::ast::InlineAsmTemplatePiece;\nuse rustc_data_structures::fx::{FxHasher, FxIndexMap};\nuse rustc_hir::MatchSource::TryDesugar;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{\n    AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, ByRef, Closure, ConstArg, ConstArgKind, ConstItemRhs,\n    Expr, ExprField, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, GenericArgs, GenericBound, GenericBounds,\n    GenericParam, GenericParamKind, GenericParamSource, Generics, HirId, HirIdMap, InlineAsmOperand, ItemId, ItemKind,\n    LetExpr, Lifetime, LifetimeKind, LifetimeParamKind, Node, ParamName, Pat, PatExpr, PatExprKind, PatField, PatKind,\n    Path, PathSegment, PreciseCapturingArgKind, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty,\n    TyFieldPath, TyKind, TyPat, TyPatKind, UseKind, WherePredicate, WherePredicateKind,\n};\nuse rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::TypeckResults;\nuse rustc_span::{BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext};\nuse std::hash::{Hash, Hasher};\nuse std::ops::Range;\nuse std::slice;\n\n/// Callback that is called when two expressions are not equal in the sense of `SpanlessEq`, but\n/// other conditions would make them equal.\ntype SpanlessEqCallback<'a, 'tcx> =\n    dyn FnMut(&TypeckResults<'tcx>, &Expr<'_>, &TypeckResults<'tcx>, &Expr<'_>) -> bool + 'a;\n\n/// Determines how paths are hashed and compared for equality.\n#[derive(Copy, Clone, Debug, Default)]\npub enum PathCheck {\n    /// Paths must match exactly and are hashed by their exact HIR tree.\n    ///\n    /// Thus, `std::iter::Iterator` and `Iterator` are not considered equal even though they refer\n    /// to the same item.\n    #[default]\n    Exact,\n    /// Paths are compared and hashed based on their resolution.\n    ///\n    /// They can appear different in the HIR tree but are still considered equal\n    /// and have equal hashes as long as they refer to the same item.\n    ///\n    /// Note that this is currently only partially implemented specifically for paths that are\n    /// resolved before type-checking, i.e. the final segment must have a non-error resolution.\n    /// If a path with an error resolution is encountered, it falls back to the default exact\n    /// matching behavior.\n    Resolution,\n}\n\n/// Type used to check whether two ast are the same. This is different from the\n/// operator `==` on ast types as this operator would compare true equality with\n/// ID and span.\n///\n/// Note that some expressions kinds are not considered but could be added.\npub struct SpanlessEq<'a, 'tcx> {\n    /// Context used to evaluate constant expressions.\n    cx: &'a LateContext<'tcx>,\n    maybe_typeck_results: Option<(&'tcx TypeckResults<'tcx>, &'tcx TypeckResults<'tcx>)>,\n    allow_side_effects: bool,\n    expr_fallback: Option<Box<SpanlessEqCallback<'a, 'tcx>>>,\n    path_check: PathCheck,\n}\n\nimpl<'a, 'tcx> SpanlessEq<'a, 'tcx> {\n    pub fn new(cx: &'a LateContext<'tcx>) -> Self {\n        Self {\n            cx,\n            maybe_typeck_results: cx.maybe_typeck_results().map(|x| (x, x)),\n            allow_side_effects: true,\n            expr_fallback: None,\n            path_check: PathCheck::default(),\n        }\n    }\n\n    /// Consider expressions containing potential side effects as not equal.\n    #[must_use]\n    pub fn deny_side_effects(self) -> Self {\n        Self {\n            allow_side_effects: false,\n            ..self\n        }\n    }\n\n    /// Check paths by their resolution instead of exact equality. See [`PathCheck`] for more\n    /// details.\n    #[must_use]\n    pub fn paths_by_resolution(self) -> Self {\n        Self {\n            path_check: PathCheck::Resolution,\n            ..self\n        }\n    }\n\n    #[must_use]\n    pub fn expr_fallback(\n        self,\n        expr_fallback: impl FnMut(&TypeckResults<'tcx>, &Expr<'_>, &TypeckResults<'tcx>, &Expr<'_>) -> bool + 'a,\n    ) -> Self {\n        Self {\n            expr_fallback: Some(Box::new(expr_fallback)),\n            ..self\n        }\n    }\n\n    /// Use this method to wrap comparisons that may involve inter-expression context.\n    /// See `self.locals`.\n    pub fn inter_expr(&mut self) -> HirEqInterExpr<'_, 'a, 'tcx> {\n        HirEqInterExpr {\n            inner: self,\n            left_ctxt: SyntaxContext::root(),\n            right_ctxt: SyntaxContext::root(),\n            locals: HirIdMap::default(),\n            local_items: FxIndexMap::default(),\n        }\n    }\n\n    pub fn eq_block(&mut self, left: &Block<'_>, right: &Block<'_>) -> bool {\n        self.inter_expr().eq_block(left, right)\n    }\n\n    pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {\n        self.inter_expr().eq_expr(left, right)\n    }\n\n    pub fn eq_path(&mut self, left: &Path<'_>, right: &Path<'_>) -> bool {\n        self.inter_expr().eq_path(left, right)\n    }\n\n    pub fn eq_path_segment(&mut self, left: &PathSegment<'_>, right: &PathSegment<'_>) -> bool {\n        self.inter_expr().eq_path_segment(left, right)\n    }\n\n    pub fn eq_path_segments(&mut self, left: &[PathSegment<'_>], right: &[PathSegment<'_>]) -> bool {\n        self.inter_expr().eq_path_segments(left, right)\n    }\n\n    pub fn eq_modifiers(left: TraitBoundModifiers, right: TraitBoundModifiers) -> bool {\n        std::mem::discriminant(&left.constness) == std::mem::discriminant(&right.constness)\n            && std::mem::discriminant(&left.polarity) == std::mem::discriminant(&right.polarity)\n    }\n}\n\npub struct HirEqInterExpr<'a, 'b, 'tcx> {\n    inner: &'a mut SpanlessEq<'b, 'tcx>,\n    left_ctxt: SyntaxContext,\n    right_ctxt: SyntaxContext,\n\n    // When binding are declared, the binding ID in the left expression is mapped to the one on the\n    // right. For example, when comparing `{ let x = 1; x + 2 }` and `{ let y = 1; y + 2 }`,\n    // these blocks are considered equal since `x` is mapped to `y`.\n    pub locals: HirIdMap<HirId>,\n    pub local_items: FxIndexMap<DefId, DefId>,\n}\n\nimpl HirEqInterExpr<'_, '_, '_> {\n    pub fn eq_stmt(&mut self, left: &Stmt<'_>, right: &Stmt<'_>) -> bool {\n        match (&left.kind, &right.kind) {\n            (StmtKind::Let(l), StmtKind::Let(r)) => {\n                // This additional check ensures that the type of the locals are equivalent even if the init\n                // expression or type have some inferred parts.\n                if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results {\n                    let l_ty = typeck_lhs.pat_ty(l.pat);\n                    let r_ty = typeck_rhs.pat_ty(r.pat);\n                    if l_ty != r_ty {\n                        return false;\n                    }\n                }\n\n                // eq_pat adds the HirIds to the locals map. We therefore call it last to make sure that\n                // these only get added if the init and type is equal.\n                both(l.init.as_ref(), r.init.as_ref(), |l, r| self.eq_expr(l, r))\n                    && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| self.eq_ty(l, r))\n                    && both(l.els.as_ref(), r.els.as_ref(), |l, r| self.eq_block(l, r))\n                    && self.eq_pat(l.pat, r.pat)\n            },\n            (StmtKind::Expr(l), StmtKind::Expr(r)) | (StmtKind::Semi(l), StmtKind::Semi(r)) => self.eq_expr(l, r),\n            (StmtKind::Item(l), StmtKind::Item(r)) => self.eq_item(*l, *r),\n            _ => false,\n        }\n    }\n\n    pub fn eq_item(&mut self, l: ItemId, r: ItemId) -> bool {\n        let left = self.inner.cx.tcx.hir_item(l);\n        let right = self.inner.cx.tcx.hir_item(r);\n        let eq = match (left.kind, right.kind) {\n            (\n                ItemKind::Const(l_ident, l_generics, l_ty, ConstItemRhs::Body(l_body)),\n                ItemKind::Const(r_ident, r_generics, r_ty, ConstItemRhs::Body(r_body)),\n            ) => {\n                l_ident.name == r_ident.name\n                    && self.eq_generics(l_generics, r_generics)\n                    && self.eq_ty(l_ty, r_ty)\n                    && self.eq_body(l_body, r_body)\n            },\n            (ItemKind::Static(l_mut, l_ident, l_ty, l_body), ItemKind::Static(r_mut, r_ident, r_ty, r_body)) => {\n                l_mut == r_mut && l_ident.name == r_ident.name && self.eq_ty(l_ty, r_ty) && self.eq_body(l_body, r_body)\n            },\n            (\n                ItemKind::Fn {\n                    sig: l_sig,\n                    ident: l_ident,\n                    generics: l_generics,\n                    body: l_body,\n                    has_body: l_has_body,\n                },\n                ItemKind::Fn {\n                    sig: r_sig,\n                    ident: r_ident,\n                    generics: r_generics,\n                    body: r_body,\n                    has_body: r_has_body,\n                },\n            ) => {\n                l_ident.name == r_ident.name\n                    && (l_has_body == r_has_body)\n                    && self.eq_fn_sig(&l_sig, &r_sig)\n                    && self.eq_generics(l_generics, r_generics)\n                    && self.eq_body(l_body, r_body)\n            },\n            (ItemKind::TyAlias(l_ident, l_generics, l_ty), ItemKind::TyAlias(r_ident, r_generics, r_ty)) => {\n                l_ident.name == r_ident.name && self.eq_generics(l_generics, r_generics) && self.eq_ty(l_ty, r_ty)\n            },\n            (ItemKind::Use(l_path, l_kind), ItemKind::Use(r_path, r_kind)) => {\n                self.eq_path_segments(l_path.segments, r_path.segments)\n                    && match (l_kind, r_kind) {\n                        (UseKind::Single(l_ident), UseKind::Single(r_ident)) => l_ident.name == r_ident.name,\n                        (UseKind::Glob, UseKind::Glob) | (UseKind::ListStem, UseKind::ListStem) => true,\n                        _ => false,\n                    }\n            },\n            (ItemKind::Mod(l_ident, l_mod), ItemKind::Mod(r_ident, r_mod)) => {\n                l_ident.name == r_ident.name && over(l_mod.item_ids, r_mod.item_ids, |l, r| self.eq_item(*l, *r))\n            },\n            _ => false,\n        };\n        if eq {\n            self.local_items.insert(l.owner_id.to_def_id(), r.owner_id.to_def_id());\n        }\n        eq\n    }\n\n    fn eq_fn_sig(&mut self, left: &FnSig<'_>, right: &FnSig<'_>) -> bool {\n        left.header.safety == right.header.safety\n            && left.header.constness == right.header.constness\n            && left.header.asyncness == right.header.asyncness\n            && left.header.abi == right.header.abi\n            && self.eq_fn_decl(left.decl, right.decl)\n    }\n\n    fn eq_fn_decl(&mut self, left: &FnDecl<'_>, right: &FnDecl<'_>) -> bool {\n        over(left.inputs, right.inputs, |l, r| self.eq_ty(l, r))\n            && (match (left.output, right.output) {\n                (FnRetTy::DefaultReturn(_), FnRetTy::DefaultReturn(_)) => true,\n                (FnRetTy::Return(l_ty), FnRetTy::Return(r_ty)) => self.eq_ty(l_ty, r_ty),\n                _ => false,\n            })\n            && left.c_variadic == right.c_variadic\n            && left.implicit_self == right.implicit_self\n            && left.lifetime_elision_allowed == right.lifetime_elision_allowed\n    }\n\n    fn eq_generics(&mut self, left: &Generics<'_>, right: &Generics<'_>) -> bool {\n        self.eq_generics_param(left.params, right.params)\n            && self.eq_generics_predicate(left.predicates, right.predicates)\n    }\n\n    fn eq_generics_predicate(&mut self, left: &[WherePredicate<'_>], right: &[WherePredicate<'_>]) -> bool {\n        over(left, right, |l, r| match (l.kind, r.kind) {\n            (WherePredicateKind::BoundPredicate(l_bound), WherePredicateKind::BoundPredicate(r_bound)) => {\n                l_bound.origin == r_bound.origin\n                    && self.eq_ty(l_bound.bounded_ty, r_bound.bounded_ty)\n                    && self.eq_generics_param(l_bound.bound_generic_params, r_bound.bound_generic_params)\n                    && self.eq_generics_bound(l_bound.bounds, r_bound.bounds)\n            },\n            (WherePredicateKind::RegionPredicate(l_region), WherePredicateKind::RegionPredicate(r_region)) => {\n                Self::eq_lifetime(l_region.lifetime, r_region.lifetime)\n                    && self.eq_generics_bound(l_region.bounds, r_region.bounds)\n            },\n            (WherePredicateKind::EqPredicate(l_eq), WherePredicateKind::EqPredicate(r_eq)) => {\n                self.eq_ty(l_eq.lhs_ty, r_eq.lhs_ty)\n            },\n            _ => false,\n        })\n    }\n\n    fn eq_generics_bound(&mut self, left: GenericBounds<'_>, right: GenericBounds<'_>) -> bool {\n        over(left, right, |l, r| match (l, r) {\n            (GenericBound::Trait(l_trait), GenericBound::Trait(r_trait)) => {\n                l_trait.modifiers == r_trait.modifiers\n                    && self.eq_path(l_trait.trait_ref.path, r_trait.trait_ref.path)\n                    && self.eq_generics_param(l_trait.bound_generic_params, r_trait.bound_generic_params)\n            },\n            (GenericBound::Outlives(l_lifetime), GenericBound::Outlives(r_lifetime)) => {\n                Self::eq_lifetime(l_lifetime, r_lifetime)\n            },\n            (GenericBound::Use(l_capture, _), GenericBound::Use(r_capture, _)) => {\n                over(l_capture, r_capture, |l, r| match (l, r) {\n                    (PreciseCapturingArgKind::Lifetime(l_lifetime), PreciseCapturingArgKind::Lifetime(r_lifetime)) => {\n                        Self::eq_lifetime(l_lifetime, r_lifetime)\n                    },\n                    (PreciseCapturingArgKind::Param(l_param), PreciseCapturingArgKind::Param(r_param)) => {\n                        l_param.ident == r_param.ident && l_param.res == r_param.res\n                    },\n                    _ => false,\n                })\n            },\n            _ => false,\n        })\n    }\n\n    fn eq_generics_param(&mut self, left: &[GenericParam<'_>], right: &[GenericParam<'_>]) -> bool {\n        over(left, right, |l, r| {\n            (match (l.name, r.name) {\n                (ParamName::Plain(l_ident), ParamName::Plain(r_ident))\n                | (ParamName::Error(l_ident), ParamName::Error(r_ident)) => l_ident.name == r_ident.name,\n                (ParamName::Fresh, ParamName::Fresh) => true,\n                _ => false,\n            }) && l.pure_wrt_drop == r.pure_wrt_drop\n                && self.eq_generics_param_kind(&l.kind, &r.kind)\n                && (matches!(\n                    (l.source, r.source),\n                    (GenericParamSource::Generics, GenericParamSource::Generics)\n                        | (GenericParamSource::Binder, GenericParamSource::Binder)\n                ))\n        })\n    }\n\n    fn eq_generics_param_kind(&mut self, left: &GenericParamKind<'_>, right: &GenericParamKind<'_>) -> bool {\n        match (left, right) {\n            (GenericParamKind::Lifetime { kind: l_kind }, GenericParamKind::Lifetime { kind: r_kind }) => {\n                match (l_kind, r_kind) {\n                    (LifetimeParamKind::Explicit, LifetimeParamKind::Explicit)\n                    | (LifetimeParamKind::Error, LifetimeParamKind::Error) => true,\n                    (LifetimeParamKind::Elided(l_lifetime_kind), LifetimeParamKind::Elided(r_lifetime_kind)) => {\n                        l_lifetime_kind == r_lifetime_kind\n                    },\n                    _ => false,\n                }\n            },\n            (\n                GenericParamKind::Type {\n                    default: l_default,\n                    synthetic: l_synthetic,\n                },\n                GenericParamKind::Type {\n                    default: r_default,\n                    synthetic: r_synthetic,\n                },\n            ) => both(*l_default, *r_default, |l, r| self.eq_ty(l, r)) && l_synthetic == r_synthetic,\n            (\n                GenericParamKind::Const {\n                    ty: l_ty,\n                    default: l_default,\n                },\n                GenericParamKind::Const {\n                    ty: r_ty,\n                    default: r_default,\n                },\n            ) => self.eq_ty(l_ty, r_ty) && both(*l_default, *r_default, |l, r| self.eq_const_arg(l, r)),\n            _ => false,\n        }\n    }\n\n    /// Checks whether two blocks are the same.\n    fn eq_block(&mut self, left: &Block<'_>, right: &Block<'_>) -> bool {\n        use TokenKind::{Semi, Whitespace};\n        if left.stmts.len() != right.stmts.len() {\n            return false;\n        }\n        let lspan = left.span.data();\n        let rspan = right.span.data();\n        if lspan.ctxt != SyntaxContext::root() && rspan.ctxt != SyntaxContext::root() {\n            // Don't try to check in between statements inside macros.\n            return over(left.stmts, right.stmts, |left, right| self.eq_stmt(left, right))\n                && both(left.expr.as_ref(), right.expr.as_ref(), |left, right| {\n                    self.eq_expr(left, right)\n                });\n        }\n        if lspan.ctxt != rspan.ctxt {\n            return false;\n        }\n\n        let mut lstart = lspan.lo;\n        let mut rstart = rspan.lo;\n\n        for (left, right) in left.stmts.iter().zip(right.stmts) {\n            if !self.eq_stmt(left, right) {\n                return false;\n            }\n\n            // Try to detect any `cfg`ed statements or empty macro expansions.\n            let Some(lstmt_span) = walk_span_to_context(left.span, lspan.ctxt) else {\n                return false;\n            };\n            let Some(rstmt_span) = walk_span_to_context(right.span, rspan.ctxt) else {\n                return false;\n            };\n            let lstmt_span = lstmt_span.data();\n            let rstmt_span = rstmt_span.data();\n\n            if lstmt_span.lo < lstart && rstmt_span.lo < rstart {\n                // Can happen when macros expand to multiple statements, or rearrange statements.\n                // Nothing in between the statements to check in this case.\n                continue;\n            }\n            if lstmt_span.lo < lstart || rstmt_span.lo < rstart {\n                // Only one of the blocks had a weird macro.\n                return false;\n            }\n            if !eq_span_tokens(self.inner.cx, lstart..lstmt_span.lo, rstart..rstmt_span.lo, |t| {\n                !matches!(t, Whitespace | Semi)\n            }) {\n                return false;\n            }\n\n            lstart = lstmt_span.hi;\n            rstart = rstmt_span.hi;\n        }\n\n        let (lend, rend) = match (left.expr, right.expr) {\n            (Some(left), Some(right)) => {\n                if !self.eq_expr(left, right) {\n                    return false;\n                }\n                let Some(lexpr_span) = walk_span_to_context(left.span, lspan.ctxt) else {\n                    return false;\n                };\n                let Some(rexpr_span) = walk_span_to_context(right.span, rspan.ctxt) else {\n                    return false;\n                };\n                (lexpr_span.lo(), rexpr_span.lo())\n            },\n            (None, None) => (lspan.hi, rspan.hi),\n            (Some(_), None) | (None, Some(_)) => return false,\n        };\n\n        if lend < lstart && rend < rstart {\n            // Can happen when macros rearrange the input.\n            // Nothing in between the statements to check in this case.\n            return true;\n        } else if lend < lstart || rend < rstart {\n            // Only one of the blocks had a weird macro\n            return false;\n        }\n        eq_span_tokens(self.inner.cx, lstart..lend, rstart..rend, |t| {\n            !matches!(t, Whitespace | Semi)\n        })\n    }\n\n    fn should_ignore(&self, expr: &Expr<'_>) -> bool {\n        macro_backtrace(expr.span).last().is_some_and(|macro_call| {\n            matches!(\n                self.inner.cx.tcx.get_diagnostic_name(macro_call.def_id),\n                Some(sym::todo_macro | sym::unimplemented_macro)\n            )\n        })\n    }\n\n    pub fn eq_body(&mut self, left: BodyId, right: BodyId) -> bool {\n        // swap out TypeckResults when hashing a body\n        let old_maybe_typeck_results = self.inner.maybe_typeck_results.replace((\n            self.inner.cx.tcx.typeck_body(left),\n            self.inner.cx.tcx.typeck_body(right),\n        ));\n        let res = self.eq_expr(\n            self.inner.cx.tcx.hir_body(left).value,\n            self.inner.cx.tcx.hir_body(right).value,\n        );\n        self.inner.maybe_typeck_results = old_maybe_typeck_results;\n        res\n    }\n\n    #[expect(clippy::too_many_lines)]\n    pub fn eq_expr(&mut self, left: &Expr<'_>, right: &Expr<'_>) -> bool {\n        if !self.check_ctxt(left.span.ctxt(), right.span.ctxt()) {\n            return false;\n        }\n\n        if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results\n            && typeck_lhs.expr_ty(left) == typeck_rhs.expr_ty(right)\n            && let (Some(l), Some(r)) = (\n                ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.typing_env(), typeck_lhs)\n                    .eval_local(left, self.left_ctxt),\n                ConstEvalCtxt::with_env(self.inner.cx.tcx, self.inner.cx.typing_env(), typeck_rhs)\n                    .eval_local(right, self.right_ctxt),\n            )\n            && l == r\n        {\n            return true;\n        }\n\n        let is_eq = match (\n            reduce_exprkind(self.inner.cx, &left.kind),\n            reduce_exprkind(self.inner.cx, &right.kind),\n        ) {\n            (ExprKind::AddrOf(lb, l_mut, le), ExprKind::AddrOf(rb, r_mut, re)) => {\n                lb == rb && l_mut == r_mut && self.eq_expr(le, re)\n            },\n            (ExprKind::Array(l), ExprKind::Array(r)) => self.eq_exprs(l, r),\n            (ExprKind::Assign(ll, lr, _), ExprKind::Assign(rl, rr, _)) => {\n                self.inner.allow_side_effects && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)\n            },\n            (ExprKind::AssignOp(lo, ll, lr), ExprKind::AssignOp(ro, rl, rr)) => {\n                self.inner.allow_side_effects && lo.node == ro.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)\n            },\n            (ExprKind::Block(l, _), ExprKind::Block(r, _)) => self.eq_block(l, r),\n            (ExprKind::Binary(l_op, ll, lr), ExprKind::Binary(r_op, rl, rr)) => {\n                l_op.node == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)\n                    || self.swap_binop(l_op.node, ll, lr).is_some_and(|(l_op, ll, lr)| {\n                        l_op == r_op.node && self.eq_expr(ll, rl) && self.eq_expr(lr, rr)\n                    })\n            },\n            (ExprKind::Break(li, le), ExprKind::Break(ri, re)) => {\n                both(li.label.as_ref(), ri.label.as_ref(), |l, r| l.ident.name == r.ident.name)\n                    && both(le.as_ref(), re.as_ref(), |l, r| self.eq_expr(l, r))\n            },\n            (ExprKind::Call(l_fun, l_args), ExprKind::Call(r_fun, r_args)) => {\n                self.inner.allow_side_effects && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args)\n            },\n            (ExprKind::Cast(lx, lt), ExprKind::Cast(rx, rt)) => {\n                self.eq_expr(lx, rx) && self.eq_ty(lt, rt)\n            },\n            (ExprKind::Closure(_l), ExprKind::Closure(_r)) => false,\n            (ExprKind::ConstBlock(lb), ExprKind::ConstBlock(rb)) => self.eq_body(lb.body, rb.body),\n            (ExprKind::Continue(li), ExprKind::Continue(ri)) => {\n                both(li.label.as_ref(), ri.label.as_ref(), |l, r| l.ident.name == r.ident.name)\n            },\n            (ExprKind::DropTemps(le), ExprKind::DropTemps(re)) => self.eq_expr(le, re),\n            (ExprKind::Field(l_f_exp, l_f_ident), ExprKind::Field(r_f_exp, r_f_ident)) => {\n                l_f_ident.name == r_f_ident.name && self.eq_expr(l_f_exp, r_f_exp)\n            },\n            (ExprKind::Index(la, li, _), ExprKind::Index(ra, ri, _)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),\n            (ExprKind::If(lc, lt, le), ExprKind::If(rc, rt, re)) => {\n                self.eq_expr(lc, rc) && self.eq_expr(lt, rt)\n                    && both(le.as_ref(), re.as_ref(), |l, r| self.eq_expr(l, r))\n            },\n            (ExprKind::Let(l), ExprKind::Let(r)) => {\n                self.eq_pat(l.pat, r.pat)\n                    && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| self.eq_ty(l, r))\n                    && self.eq_expr(l.init, r.init)\n            },\n            (ExprKind::Lit(l), ExprKind::Lit(r)) => l.node == r.node,\n            (ExprKind::Loop(lb, ll, lls, _), ExprKind::Loop(rb, rl, rls, _)) => {\n                lls == rls && self.eq_block(lb, rb)\n                    && both(ll.as_ref(), rl.as_ref(), |l, r| l.ident.name == r.ident.name)\n            },\n            (ExprKind::Match(le, la, ls), ExprKind::Match(re, ra, rs)) => {\n                (ls == rs || (matches!((ls, rs), (TryDesugar(_), TryDesugar(_)))))\n                    && self.eq_expr(le, re)\n                    && over(la, ra, |l, r| {\n                        self.eq_pat(l.pat, r.pat)\n                            && both(l.guard.as_ref(), r.guard.as_ref(), |l, r| self.eq_expr(l, r))\n                            && self.eq_expr(l.body, r.body)\n                    })\n            },\n            (\n                ExprKind::MethodCall(l_path, l_receiver, l_args, _),\n                ExprKind::MethodCall(r_path, r_receiver, r_args, _),\n            ) => {\n                self.inner.allow_side_effects\n                    && self.eq_path_segment(l_path, r_path)\n                    && self.eq_expr(l_receiver, r_receiver)\n                    && self.eq_exprs(l_args, r_args)\n            },\n            (ExprKind::UnsafeBinderCast(lkind, le, None), ExprKind::UnsafeBinderCast(rkind, re, None)) =>\n                lkind == rkind && self.eq_expr(le, re),\n            (ExprKind::UnsafeBinderCast(lkind, le, Some(lt)), ExprKind::UnsafeBinderCast(rkind, re, Some(rt))) =>\n                lkind == rkind && self.eq_expr(le, re) && self.eq_ty(lt, rt),\n            (ExprKind::OffsetOf(l_container, l_fields), ExprKind::OffsetOf(r_container, r_fields)) => {\n                self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name)\n            },\n            (ExprKind::Path(l), ExprKind::Path(r)) => self.eq_qpath(l, r),\n            (ExprKind::Repeat(le, ll), ExprKind::Repeat(re, rl)) => {\n                self.eq_expr(le, re) && self.eq_const_arg(ll, rl)\n            },\n            (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l.as_ref(), r.as_ref(), |l, r| self.eq_expr(l, r)),\n            (ExprKind::Struct(l_path, lf, lo), ExprKind::Struct(r_path, rf, ro)) => {\n                self.eq_qpath(l_path, r_path)\n                    && match (lo, ro) {\n                        (StructTailExpr::Base(l),StructTailExpr::Base(r)) => self.eq_expr(l, r),\n                        (StructTailExpr::None, StructTailExpr::None) |\n                        (StructTailExpr::DefaultFields(_), StructTailExpr::DefaultFields(_)) => true,\n                        _ => false,\n                    }\n                    && over(lf, rf, |l, r| self.eq_expr_field(l, r))\n            },\n            (ExprKind::Tup(l_tup), ExprKind::Tup(r_tup)) => self.eq_exprs(l_tup, r_tup),\n            (ExprKind::Use(l_expr, _), ExprKind::Use(r_expr, _)) => self.eq_expr(l_expr, r_expr),\n            (ExprKind::Type(le, lt), ExprKind::Type(re, rt)) => self.eq_expr(le, re) && self.eq_ty(lt, rt),\n            (ExprKind::Unary(l_op, le), ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re),\n            (ExprKind::Yield(le, _), ExprKind::Yield(re, _)) => return self.eq_expr(le, re),\n            (\n                // Else branches for branches above, grouped as per `match_same_arms`.\n                | ExprKind::AddrOf(..)\n                | ExprKind::Array(..)\n                | ExprKind::Assign(..)\n                | ExprKind::AssignOp(..)\n                | ExprKind::Binary(..)\n                | ExprKind::Become(..)\n                | ExprKind::Block(..)\n                | ExprKind::Break(..)\n                | ExprKind::Call(..)\n                | ExprKind::Cast(..)\n                | ExprKind::ConstBlock(..)\n                | ExprKind::Continue(..)\n                | ExprKind::DropTemps(..)\n                | ExprKind::Field(..)\n                | ExprKind::Index(..)\n                | ExprKind::If(..)\n                | ExprKind::Let(..)\n                | ExprKind::Lit(..)\n                | ExprKind::Loop(..)\n                | ExprKind::Match(..)\n                | ExprKind::MethodCall(..)\n                | ExprKind::OffsetOf(..)\n                | ExprKind::Path(..)\n                | ExprKind::Repeat(..)\n                | ExprKind::Ret(..)\n                | ExprKind::Struct(..)\n                | ExprKind::Tup(..)\n                | ExprKind::Use(..)\n                | ExprKind::Type(..)\n                | ExprKind::Unary(..)\n                | ExprKind::Yield(..)\n                | ExprKind::UnsafeBinderCast(..)\n\n                // --- Special cases that do not have a positive branch.\n\n                // `Err` represents an invalid expression, so let's never assume that\n                // an invalid expressions is equal to anything.\n                | ExprKind::Err(..)\n\n                // For the time being, we always consider that two closures are unequal.\n                // This behavior may change in the future.\n                | ExprKind::Closure(..)\n                // For the time being, we always consider that two instances of InlineAsm are different.\n                // This behavior may change in the future.\n                | ExprKind::InlineAsm(_)\n                , _\n            ) => false,\n        };\n        (is_eq && (!self.should_ignore(left) || !self.should_ignore(right)))\n            || self\n                .inner\n                .maybe_typeck_results\n                .is_some_and(|(left_typeck_results, right_typeck_results)| {\n                    self.inner\n                        .expr_fallback\n                        .as_mut()\n                        .is_some_and(|f| f(left_typeck_results, left, right_typeck_results, right))\n                })\n    }\n\n    fn eq_exprs(&mut self, left: &[Expr<'_>], right: &[Expr<'_>]) -> bool {\n        over(left, right, |l, r| self.eq_expr(l, r))\n    }\n\n    fn eq_expr_field(&mut self, left: &ExprField<'_>, right: &ExprField<'_>) -> bool {\n        left.ident.name == right.ident.name && self.eq_expr(left.expr, right.expr)\n    }\n\n    fn eq_generic_arg(&mut self, left: &GenericArg<'_>, right: &GenericArg<'_>) -> bool {\n        match (left, right) {\n            (GenericArg::Const(l), GenericArg::Const(r)) => self.eq_const_arg(l.as_unambig_ct(), r.as_unambig_ct()),\n            (GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => Self::eq_lifetime(l_lt, r_lt),\n            (GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty.as_unambig_ty(), r_ty.as_unambig_ty()),\n            (GenericArg::Infer(l_inf), GenericArg::Infer(r_inf)) => self.eq_ty(&l_inf.to_ty(), &r_inf.to_ty()),\n            _ => false,\n        }\n    }\n\n    fn eq_const_arg(&mut self, left: &ConstArg<'_>, right: &ConstArg<'_>) -> bool {\n        if !self.check_ctxt(left.span.ctxt(), right.span.ctxt()) {\n            return false;\n        }\n\n        match (&left.kind, &right.kind) {\n            (ConstArgKind::Tup(l_t), ConstArgKind::Tup(r_t)) => {\n                l_t.len() == r_t.len() && l_t.iter().zip(*r_t).all(|(l_c, r_c)| self.eq_const_arg(l_c, r_c))\n            },\n            (ConstArgKind::Path(l_p), ConstArgKind::Path(r_p)) => self.eq_qpath(l_p, r_p),\n            (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body),\n            (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true,\n            (ConstArgKind::Struct(path_a, inits_a), ConstArgKind::Struct(path_b, inits_b)) => {\n                self.eq_qpath(path_a, path_b)\n                    && inits_a\n                        .iter()\n                        .zip(*inits_b)\n                        .all(|(init_a, init_b)| self.eq_const_arg(init_a.expr, init_b.expr))\n            },\n            (ConstArgKind::TupleCall(path_a, args_a), ConstArgKind::TupleCall(path_b, args_b)) => {\n                self.eq_qpath(path_a, path_b)\n                    && args_a\n                        .iter()\n                        .zip(*args_b)\n                        .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b))\n            },\n            (\n                ConstArgKind::Literal {\n                    lit: kind_l,\n                    negated: negated_l,\n                },\n                ConstArgKind::Literal {\n                    lit: kind_r,\n                    negated: negated_r,\n                },\n            ) => kind_l == kind_r && negated_l == negated_r,\n            (ConstArgKind::Array(l_arr), ConstArgKind::Array(r_arr)) => {\n                l_arr.elems.len() == r_arr.elems.len()\n                    && l_arr\n                        .elems\n                        .iter()\n                        .zip(r_arr.elems.iter())\n                        .all(|(l_elem, r_elem)| self.eq_const_arg(l_elem, r_elem))\n            },\n            // Use explicit match for now since ConstArg is undergoing flux.\n            (\n                ConstArgKind::Path(..)\n                | ConstArgKind::Tup(..)\n                | ConstArgKind::Anon(..)\n                | ConstArgKind::TupleCall(..)\n                | ConstArgKind::Infer(..)\n                | ConstArgKind::Struct(..)\n                | ConstArgKind::Literal { .. }\n                | ConstArgKind::Array(..)\n                | ConstArgKind::Error(..),\n                _,\n            ) => false,\n        }\n    }\n\n    fn eq_lifetime(left: &Lifetime, right: &Lifetime) -> bool {\n        left.kind == right.kind\n    }\n\n    fn eq_pat_field(&mut self, left: &PatField<'_>, right: &PatField<'_>) -> bool {\n        let (PatField { ident: li, pat: lp, .. }, PatField { ident: ri, pat: rp, .. }) = (&left, &right);\n        li.name == ri.name && self.eq_pat(lp, rp)\n    }\n\n    fn eq_pat_expr(&mut self, left: &PatExpr<'_>, right: &PatExpr<'_>) -> bool {\n        match (&left.kind, &right.kind) {\n            (\n                PatExprKind::Lit {\n                    lit: left,\n                    negated: left_neg,\n                },\n                PatExprKind::Lit {\n                    lit: right,\n                    negated: right_neg,\n                },\n            ) => left_neg == right_neg && left.node == right.node,\n            (PatExprKind::Path(left), PatExprKind::Path(right)) => self.eq_qpath(left, right),\n            (PatExprKind::Lit { .. } | PatExprKind::Path(..), _) => false,\n        }\n    }\n\n    /// Checks whether two patterns are the same.\n    fn eq_pat(&mut self, left: &Pat<'_>, right: &Pat<'_>) -> bool {\n        match (&left.kind, &right.kind) {\n            (PatKind::Box(l), PatKind::Box(r)) => self.eq_pat(l, r),\n            (PatKind::Struct(lp, la, ..), PatKind::Struct(rp, ra, ..)) => {\n                self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat_field(l, r))\n            },\n            (PatKind::TupleStruct(lp, la, ls), PatKind::TupleStruct(rp, ra, rs)) => {\n                self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs\n            },\n            (PatKind::Binding(lb, li, _, lp), PatKind::Binding(rb, ri, _, rp)) => {\n                let eq = lb == rb && both(lp.as_ref(), rp.as_ref(), |l, r| self.eq_pat(l, r));\n                if eq {\n                    self.locals.insert(*li, *ri);\n                }\n                eq\n            },\n            (PatKind::Expr(l), PatKind::Expr(r)) => self.eq_pat_expr(l, r),\n            (PatKind::Tuple(l, ls), PatKind::Tuple(r, rs)) => ls == rs && over(l, r, |l, r| self.eq_pat(l, r)),\n            (PatKind::Range(ls, le, li), PatKind::Range(rs, re, ri)) => {\n                both(ls.as_ref(), rs.as_ref(), |a, b| self.eq_pat_expr(a, b))\n                    && both(le.as_ref(), re.as_ref(), |a, b| self.eq_pat_expr(a, b))\n                    && (li == ri)\n            },\n            (PatKind::Ref(le, lp, lm), PatKind::Ref(re, rp, rm)) => lp == rp && lm == rm && self.eq_pat(le, re),\n            (PatKind::Slice(ls, li, le), PatKind::Slice(rs, ri, re)) => {\n                over(ls, rs, |l, r| self.eq_pat(l, r))\n                    && over(le, re, |l, r| self.eq_pat(l, r))\n                    && both(li.as_ref(), ri.as_ref(), |l, r| self.eq_pat(l, r))\n            },\n            (PatKind::Wild, PatKind::Wild) => true,\n            _ => false,\n        }\n    }\n\n    fn eq_qpath(&mut self, left: &QPath<'_>, right: &QPath<'_>) -> bool {\n        match (left, right) {\n            (QPath::Resolved(lty, lpath), QPath::Resolved(rty, rpath)) => {\n                both(lty.as_ref(), rty.as_ref(), |l, r| self.eq_ty(l, r)) && self.eq_path(lpath, rpath)\n            },\n            (QPath::TypeRelative(lty, lseg), QPath::TypeRelative(rty, rseg)) => {\n                self.eq_ty(lty, rty) && self.eq_path_segment(lseg, rseg)\n            },\n            _ => false,\n        }\n    }\n\n    pub fn eq_path(&mut self, left: &Path<'_>, right: &Path<'_>) -> bool {\n        match (left.res, right.res) {\n            (Res::Local(l), Res::Local(r)) => l == r || self.locals.get(&l) == Some(&r),\n            (Res::Local(_), _) | (_, Res::Local(_)) => false,\n            (Res::Def(l_kind, l), Res::Def(r_kind, r))\n                if l_kind == r_kind\n                    && let DefKind::Const { .. }\n                    | DefKind::Static { .. }\n                    | DefKind::Fn\n                    | DefKind::TyAlias\n                    | DefKind::Use\n                    | DefKind::Mod = l_kind =>\n            {\n                (l == r || self.local_items.get(&l) == Some(&r)) && self.eq_path_segments(left.segments, right.segments)\n            },\n            _ => self.eq_path_segments(left.segments, right.segments),\n        }\n    }\n\n    fn eq_path_parameters(&mut self, left: &GenericArgs<'_>, right: &GenericArgs<'_>) -> bool {\n        if left.parenthesized == right.parenthesized {\n            over(left.args, right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work\n                && over(left.constraints, right.constraints, |l, r| self.eq_assoc_eq_constraint(l, r))\n        } else {\n            false\n        }\n    }\n\n    pub fn eq_path_segments<'tcx>(\n        &mut self,\n        mut left: &'tcx [PathSegment<'tcx>],\n        mut right: &'tcx [PathSegment<'tcx>],\n    ) -> bool {\n        if let PathCheck::Resolution = self.inner.path_check\n            && let Some(left_seg) = generic_path_segments(left)\n            && let Some(right_seg) = generic_path_segments(right)\n        {\n            // If we compare by resolution, then only check the last segments that could possibly have generic\n            // arguments\n            left = left_seg;\n            right = right_seg;\n        }\n\n        over(left, right, |l, r| self.eq_path_segment(l, r))\n    }\n\n    pub fn eq_path_segment(&mut self, left: &PathSegment<'_>, right: &PathSegment<'_>) -> bool {\n        if !self.eq_path_parameters(left.args(), right.args()) {\n            return false;\n        }\n\n        if let PathCheck::Resolution = self.inner.path_check\n            && left.res != Res::Err\n            && right.res != Res::Err\n        {\n            left.res == right.res\n        } else {\n            // The == of idents doesn't work with different contexts,\n            // we have to be explicit about hygiene\n            left.ident.name == right.ident.name\n        }\n    }\n\n    pub fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool {\n        match (&left.kind, &right.kind) {\n            (TyKind::Slice(l_vec), TyKind::Slice(r_vec)) => self.eq_ty(l_vec, r_vec),\n            (TyKind::Array(lt, ll), TyKind::Array(rt, rl)) => self.eq_ty(lt, rt) && self.eq_const_arg(ll, rl),\n            (TyKind::Ptr(l_mut), TyKind::Ptr(r_mut)) => l_mut.mutbl == r_mut.mutbl && self.eq_ty(l_mut.ty, r_mut.ty),\n            (TyKind::Ref(_, l_rmut), TyKind::Ref(_, r_rmut)) => {\n                l_rmut.mutbl == r_rmut.mutbl && self.eq_ty(l_rmut.ty, r_rmut.ty)\n            },\n            (TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r),\n            (TyKind::Tup(l), TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)),\n            (TyKind::Infer(()), TyKind::Infer(())) => true,\n            _ => false,\n        }\n    }\n\n    /// Checks whether two constraints designate the same equality constraint (same name, and same\n    /// type or const).\n    fn eq_assoc_eq_constraint(&mut self, left: &AssocItemConstraint<'_>, right: &AssocItemConstraint<'_>) -> bool {\n        // TODO: this could be extended to check for identical associated item bound constraints\n        left.ident.name == right.ident.name\n            && (both_some_and(left.ty(), right.ty(), |l, r| self.eq_ty(l, r))\n                || both_some_and(left.ct(), right.ct(), |l, r| self.eq_const_arg(l, r)))\n    }\n\n    fn check_ctxt(&mut self, left: SyntaxContext, right: SyntaxContext) -> bool {\n        if self.left_ctxt == left && self.right_ctxt == right {\n            return true;\n        } else if self.left_ctxt == left || self.right_ctxt == right {\n            // Only one context has changed. This can only happen if the two nodes are written differently.\n            return false;\n        } else if left != SyntaxContext::root() {\n            let mut left_data = left.outer_expn_data();\n            let mut right_data = right.outer_expn_data();\n            loop {\n                use TokenKind::{BlockComment, LineComment, Whitespace};\n                if left_data.macro_def_id != right_data.macro_def_id\n                    || (matches!(\n                        left_data.kind,\n                        ExpnKind::Macro(MacroKind::Bang, name)\n                        if name == sym::cfg || name == sym::option_env\n                    ) && !eq_span_tokens(self.inner.cx, left_data.call_site, right_data.call_site, |t| {\n                        !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. })\n                    }))\n                {\n                    // Either a different chain of macro calls, or different arguments to the `cfg` macro.\n                    return false;\n                }\n                let left_ctxt = left_data.call_site.ctxt();\n                let right_ctxt = right_data.call_site.ctxt();\n                if left_ctxt == SyntaxContext::root() && right_ctxt == SyntaxContext::root() {\n                    break;\n                }\n                if left_ctxt == SyntaxContext::root() || right_ctxt == SyntaxContext::root() {\n                    // Different lengths for the expansion stack. This can only happen if nodes are written differently,\n                    // or shouldn't be compared to start with.\n                    return false;\n                }\n                left_data = left_ctxt.outer_expn_data();\n                right_data = right_ctxt.outer_expn_data();\n            }\n        }\n        self.left_ctxt = left;\n        self.right_ctxt = right;\n        true\n    }\n\n    fn swap_binop<'a>(\n        &self,\n        binop: BinOpKind,\n        lhs: &'a Expr<'a>,\n        rhs: &'a Expr<'a>,\n    ) -> Option<(BinOpKind, &'a Expr<'a>, &'a Expr<'a>)> {\n        match binop {\n            // `==` and `!=`, are commutative\n            BinOpKind::Eq | BinOpKind::Ne => Some((binop, rhs, lhs)),\n            // Comparisons can be reversed\n            BinOpKind::Lt => Some((BinOpKind::Gt, rhs, lhs)),\n            BinOpKind::Le => Some((BinOpKind::Ge, rhs, lhs)),\n            BinOpKind::Ge => Some((BinOpKind::Le, rhs, lhs)),\n            BinOpKind::Gt => Some((BinOpKind::Lt, rhs, lhs)),\n            // Non-commutative operators\n            BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Rem | BinOpKind::Sub | BinOpKind::Div => None,\n            // We know that those operators are commutative for primitive types,\n            // and we don't assume anything for other types\n            BinOpKind::Mul\n            | BinOpKind::Add\n            | BinOpKind::And\n            | BinOpKind::Or\n            | BinOpKind::BitAnd\n            | BinOpKind::BitXor\n            | BinOpKind::BitOr => self.inner.maybe_typeck_results.and_then(|(typeck_lhs, _)| {\n                typeck_lhs\n                    .expr_ty_adjusted(lhs)\n                    .peel_refs()\n                    .is_primitive()\n                    .then_some((binop, rhs, lhs))\n            }),\n        }\n    }\n}\n\n/// Some simple reductions like `{ return }` => `return`\nfn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &'hir ExprKind<'hir> {\n    if let ExprKind::Block(block, _) = kind {\n        match (block.stmts, block.expr) {\n            // From an `if let` expression without an `else` block. The arm for the implicit wild pattern is an empty\n            // block with an empty span.\n            ([], None) if block.span.is_empty() => &ExprKind::Tup(&[]),\n            // `{}` => `()`\n            ([], None)\n                if block.span.check_source_text(cx, |src| {\n                    tokenize(src, FrontmatterAllowed::No)\n                        .map(|t| t.kind)\n                        .filter(|t| {\n                            !matches!(\n                                t,\n                                TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace\n                            )\n                        })\n                        .eq([TokenKind::OpenBrace, TokenKind::CloseBrace].iter().copied())\n                }) =>\n            {\n                &ExprKind::Tup(&[])\n            },\n            ([], Some(expr)) => match expr.kind {\n                // `{ return .. }` => `return ..`\n                ExprKind::Ret(..) => &expr.kind,\n                _ => kind,\n            },\n            ([stmt], None) => match stmt.kind {\n                StmtKind::Expr(expr) | StmtKind::Semi(expr) => match expr.kind {\n                    // `{ return ..; }` => `return ..`\n                    ExprKind::Ret(..) => &expr.kind,\n                    _ => kind,\n                },\n                _ => kind,\n            },\n            _ => kind,\n        }\n    } else {\n        kind\n    }\n}\n\n/// Checks if the two `Option`s are both `None` or some equal values as per\n/// `eq_fn`.\npub fn both<X>(l: Option<&X>, r: Option<&X>, mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {\n    l.as_ref()\n        .map_or_else(|| r.is_none(), |x| r.as_ref().is_some_and(|y| eq_fn(x, y)))\n}\n\n/// Checks if the two `Option`s are both `Some` and pass the predicate function.\npub fn both_some_and<X, Y>(l: Option<X>, r: Option<Y>, mut pred: impl FnMut(X, Y) -> bool) -> bool {\n    l.is_some_and(|l| r.is_some_and(|r| pred(l, r)))\n}\n\n/// Checks if two slices are equal as per `eq_fn`.\npub fn over<X, Y>(left: &[X], right: &[Y], mut eq_fn: impl FnMut(&X, &Y) -> bool) -> bool {\n    left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y))\n}\n\n/// Counts how many elements of the slices are equal as per `eq_fn`.\npub fn count_eq<X: Sized>(\n    left: &mut dyn Iterator<Item = X>,\n    right: &mut dyn Iterator<Item = X>,\n    mut eq_fn: impl FnMut(&X, &X) -> bool,\n) -> usize {\n    left.zip(right).take_while(|(l, r)| eq_fn(l, r)).count()\n}\n\n/// Checks if two expressions evaluate to the same value, and don't contain any side effects.\npub fn eq_expr_value(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>) -> bool {\n    SpanlessEq::new(cx).deny_side_effects().eq_expr(left, right)\n}\n\n/// Returns the segments of a path that might have generic parameters.\n/// Usually just the last segment for free items, except for when the path resolves to an associated\n/// item, in which case it is the last two\nfn generic_path_segments<'tcx>(segments: &'tcx [PathSegment<'tcx>]) -> Option<&'tcx [PathSegment<'tcx>]> {\n    match segments.last()?.res {\n        Res::Def(DefKind::AssocConst { .. } | DefKind::AssocFn | DefKind::AssocTy, _) => {\n            // <Ty as module::Trait<T>>::assoc::<U>\n            //        ^^^^^^^^^^^^^^^^   ^^^^^^^^^^ segments: [module, Trait<T>, assoc<U>]\n            Some(&segments[segments.len().checked_sub(2)?..])\n        },\n        Res::Err => None,\n        _ => Some(slice::from_ref(segments.last()?)),\n    }\n}\n\n/// Type used to hash an ast element. This is different from the `Hash` trait\n/// on ast types as this\n/// trait would consider IDs and spans.\n///\n/// All expressions kind are hashed, but some might have a weaker hash.\npub struct SpanlessHash<'a, 'tcx> {\n    /// Context used to evaluate constant expressions.\n    cx: &'a LateContext<'tcx>,\n    maybe_typeck_results: Option<&'tcx TypeckResults<'tcx>>,\n    s: FxHasher,\n    path_check: PathCheck,\n}\n\nimpl<'a, 'tcx> SpanlessHash<'a, 'tcx> {\n    pub fn new(cx: &'a LateContext<'tcx>) -> Self {\n        Self {\n            cx,\n            maybe_typeck_results: cx.maybe_typeck_results(),\n            s: FxHasher::default(),\n            path_check: PathCheck::default(),\n        }\n    }\n\n    /// Check paths by their resolution instead of exact equality. See [`PathCheck`] for more\n    /// details.\n    #[must_use]\n    pub fn paths_by_resolution(self) -> Self {\n        Self {\n            path_check: PathCheck::Resolution,\n            ..self\n        }\n    }\n\n    pub fn finish(self) -> u64 {\n        self.s.finish()\n    }\n\n    pub fn hash_block(&mut self, b: &Block<'_>) {\n        for s in b.stmts {\n            self.hash_stmt(s);\n        }\n\n        if let Some(e) = b.expr {\n            self.hash_expr(e);\n        }\n\n        std::mem::discriminant(&b.rules).hash(&mut self.s);\n    }\n\n    #[expect(clippy::too_many_lines)]\n    pub fn hash_expr(&mut self, e: &Expr<'_>) {\n        let simple_const = self.maybe_typeck_results.and_then(|typeck_results| {\n            ConstEvalCtxt::with_env(self.cx.tcx, self.cx.typing_env(), typeck_results).eval_local(e, e.span.ctxt())\n        });\n\n        // const hashing may result in the same hash as some unrelated node, so add a sort of\n        // discriminant depending on which path we're choosing next\n        simple_const.hash(&mut self.s);\n        if simple_const.is_some() {\n            return;\n        }\n\n        std::mem::discriminant(&e.kind).hash(&mut self.s);\n\n        match &e.kind {\n            ExprKind::AddrOf(kind, m, e) => {\n                std::mem::discriminant(kind).hash(&mut self.s);\n                m.hash(&mut self.s);\n                self.hash_expr(e);\n            },\n            ExprKind::Continue(i) => {\n                if let Some(i) = i.label {\n                    self.hash_name(i.ident.name);\n                }\n            },\n            ExprKind::Array(v) => {\n                self.hash_exprs(v);\n            },\n            ExprKind::Assign(l, r, _) => {\n                self.hash_expr(l);\n                self.hash_expr(r);\n            },\n            ExprKind::AssignOp(o, l, r) => {\n                std::mem::discriminant(&o.node).hash(&mut self.s);\n                self.hash_expr(l);\n                self.hash_expr(r);\n            },\n            ExprKind::Become(f) => {\n                self.hash_expr(f);\n            },\n            ExprKind::Block(b, _) => {\n                self.hash_block(b);\n            },\n            ExprKind::Binary(op, l, r) => {\n                std::mem::discriminant(&op.node).hash(&mut self.s);\n                self.hash_expr(l);\n                self.hash_expr(r);\n            },\n            ExprKind::Break(i, j) => {\n                if let Some(i) = i.label {\n                    self.hash_name(i.ident.name);\n                }\n                if let Some(j) = j {\n                    self.hash_expr(j);\n                }\n            },\n            ExprKind::Call(fun, args) => {\n                self.hash_expr(fun);\n                self.hash_exprs(args);\n            },\n            ExprKind::Cast(e, ty) | ExprKind::Type(e, ty) => {\n                self.hash_expr(e);\n                self.hash_ty(ty);\n            },\n            ExprKind::Closure(Closure {\n                capture_clause, body, ..\n            }) => {\n                std::mem::discriminant(capture_clause).hash(&mut self.s);\n                // closures inherit TypeckResults\n                self.hash_expr(self.cx.tcx.hir_body(*body).value);\n            },\n            ExprKind::ConstBlock(l_id) => {\n                self.hash_body(l_id.body);\n            },\n            ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => {\n                self.hash_expr(e);\n            },\n            ExprKind::Field(e, f) => {\n                self.hash_expr(e);\n                self.hash_name(f.name);\n            },\n            ExprKind::Index(a, i, _) => {\n                self.hash_expr(a);\n                self.hash_expr(i);\n            },\n            ExprKind::InlineAsm(asm) => {\n                for piece in asm.template {\n                    match piece {\n                        InlineAsmTemplatePiece::String(s) => s.hash(&mut self.s),\n                        InlineAsmTemplatePiece::Placeholder {\n                            operand_idx,\n                            modifier,\n                            span: _,\n                        } => {\n                            operand_idx.hash(&mut self.s);\n                            modifier.hash(&mut self.s);\n                        },\n                    }\n                }\n                asm.options.hash(&mut self.s);\n                for (op, _op_sp) in asm.operands {\n                    match op {\n                        InlineAsmOperand::In { reg, expr } => {\n                            reg.hash(&mut self.s);\n                            self.hash_expr(expr);\n                        },\n                        InlineAsmOperand::Out { reg, late, expr } => {\n                            reg.hash(&mut self.s);\n                            late.hash(&mut self.s);\n                            if let Some(expr) = expr {\n                                self.hash_expr(expr);\n                            }\n                        },\n                        InlineAsmOperand::InOut { reg, late, expr } => {\n                            reg.hash(&mut self.s);\n                            late.hash(&mut self.s);\n                            self.hash_expr(expr);\n                        },\n                        InlineAsmOperand::SplitInOut {\n                            reg,\n                            late,\n                            in_expr,\n                            out_expr,\n                        } => {\n                            reg.hash(&mut self.s);\n                            late.hash(&mut self.s);\n                            self.hash_expr(in_expr);\n                            if let Some(out_expr) = out_expr {\n                                self.hash_expr(out_expr);\n                            }\n                        },\n                        InlineAsmOperand::SymFn { expr } => {\n                            self.hash_expr(expr);\n                        },\n                        InlineAsmOperand::Const { anon_const } => {\n                            self.hash_body(anon_const.body);\n                        },\n                        InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path),\n                        InlineAsmOperand::Label { block } => self.hash_block(block),\n                    }\n                }\n            },\n            ExprKind::Let(LetExpr { pat, init, ty, .. }) => {\n                self.hash_expr(init);\n                if let Some(ty) = ty {\n                    self.hash_ty(ty);\n                }\n                self.hash_pat(pat);\n            },\n            ExprKind::Lit(l) => {\n                l.node.hash(&mut self.s);\n            },\n            ExprKind::Loop(b, i, ..) => {\n                self.hash_block(b);\n                if let Some(i) = i {\n                    self.hash_name(i.ident.name);\n                }\n            },\n            ExprKind::If(cond, then, else_opt) => {\n                self.hash_expr(cond);\n                self.hash_expr(then);\n                if let Some(e) = else_opt {\n                    self.hash_expr(e);\n                }\n            },\n            ExprKind::Match(scrutinee, arms, _) => {\n                self.hash_expr(scrutinee);\n\n                for arm in *arms {\n                    self.hash_pat(arm.pat);\n                    if let Some(e) = arm.guard {\n                        self.hash_expr(e);\n                    }\n                    self.hash_expr(arm.body);\n                }\n            },\n            ExprKind::MethodCall(path, receiver, args, _fn_span) => {\n                self.hash_name(path.ident.name);\n                self.hash_expr(receiver);\n                self.hash_exprs(args);\n            },\n            ExprKind::OffsetOf(container, fields) => {\n                self.hash_ty(container);\n                for field in *fields {\n                    self.hash_name(field.name);\n                }\n            },\n            ExprKind::Path(qpath) => {\n                self.hash_qpath(qpath);\n            },\n            ExprKind::Repeat(e, len) => {\n                self.hash_expr(e);\n                self.hash_const_arg(len);\n            },\n            ExprKind::Ret(e) => {\n                if let Some(e) = e {\n                    self.hash_expr(e);\n                }\n            },\n            ExprKind::Struct(path, fields, expr) => {\n                self.hash_qpath(path);\n\n                for f in *fields {\n                    self.hash_name(f.ident.name);\n                    self.hash_expr(f.expr);\n                }\n\n                if let StructTailExpr::Base(e) = expr {\n                    self.hash_expr(e);\n                }\n            },\n            ExprKind::Tup(tup) => {\n                self.hash_exprs(tup);\n            },\n            ExprKind::Use(expr, _) => {\n                self.hash_expr(expr);\n            },\n            ExprKind::Unary(l_op, le) => {\n                std::mem::discriminant(l_op).hash(&mut self.s);\n                self.hash_expr(le);\n            },\n            ExprKind::UnsafeBinderCast(kind, expr, ty) => {\n                std::mem::discriminant(kind).hash(&mut self.s);\n                self.hash_expr(expr);\n                if let Some(ty) = ty {\n                    self.hash_ty(ty);\n                }\n            },\n            ExprKind::Err(_) => {},\n        }\n    }\n\n    pub fn hash_exprs(&mut self, e: &[Expr<'_>]) {\n        for e in e {\n            self.hash_expr(e);\n        }\n    }\n\n    pub fn hash_name(&mut self, n: Symbol) {\n        n.hash(&mut self.s);\n    }\n\n    pub fn hash_qpath(&mut self, p: &QPath<'_>) {\n        match p {\n            QPath::Resolved(_, path) => {\n                self.hash_path(path);\n            },\n            QPath::TypeRelative(_, path) => {\n                self.hash_name(path.ident.name);\n            },\n        }\n        // self.maybe_typeck_results.unwrap().qpath_res(p, id).hash(&mut self.s);\n    }\n\n    pub fn hash_pat_expr(&mut self, lit: &PatExpr<'_>) {\n        std::mem::discriminant(&lit.kind).hash(&mut self.s);\n        match &lit.kind {\n            PatExprKind::Lit { lit, negated } => {\n                lit.node.hash(&mut self.s);\n                negated.hash(&mut self.s);\n            },\n            PatExprKind::Path(qpath) => self.hash_qpath(qpath),\n        }\n    }\n\n    pub fn hash_ty_pat(&mut self, pat: &TyPat<'_>) {\n        std::mem::discriminant(&pat.kind).hash(&mut self.s);\n        match pat.kind {\n            TyPatKind::Range(s, e) => {\n                self.hash_const_arg(s);\n                self.hash_const_arg(e);\n            },\n            TyPatKind::Or(variants) => {\n                for variant in variants {\n                    self.hash_ty_pat(variant);\n                }\n            },\n            TyPatKind::NotNull | TyPatKind::Err(_) => {},\n        }\n    }\n\n    pub fn hash_pat(&mut self, pat: &Pat<'_>) {\n        std::mem::discriminant(&pat.kind).hash(&mut self.s);\n        match &pat.kind {\n            PatKind::Missing => unreachable!(),\n            PatKind::Binding(BindingMode(by_ref, mutability), _, _, pat) => {\n                std::mem::discriminant(by_ref).hash(&mut self.s);\n                if let ByRef::Yes(pi, mu) = by_ref {\n                    std::mem::discriminant(pi).hash(&mut self.s);\n                    std::mem::discriminant(mu).hash(&mut self.s);\n                }\n                std::mem::discriminant(mutability).hash(&mut self.s);\n                if let Some(pat) = pat {\n                    self.hash_pat(pat);\n                }\n            },\n            PatKind::Box(pat) | PatKind::Deref(pat) => self.hash_pat(pat),\n            PatKind::Expr(expr) => self.hash_pat_expr(expr),\n            PatKind::Or(pats) => {\n                for pat in *pats {\n                    self.hash_pat(pat);\n                }\n            },\n            PatKind::Range(s, e, i) => {\n                if let Some(s) = s {\n                    self.hash_pat_expr(s);\n                }\n                if let Some(e) = e {\n                    self.hash_pat_expr(e);\n                }\n                std::mem::discriminant(i).hash(&mut self.s);\n            },\n            PatKind::Ref(pat, pi, mu) => {\n                self.hash_pat(pat);\n                std::mem::discriminant(pi).hash(&mut self.s);\n                std::mem::discriminant(mu).hash(&mut self.s);\n            },\n            PatKind::Guard(pat, guard) => {\n                self.hash_pat(pat);\n                self.hash_expr(guard);\n            },\n            PatKind::Slice(l, m, r) => {\n                for pat in *l {\n                    self.hash_pat(pat);\n                }\n                if let Some(pat) = m {\n                    self.hash_pat(pat);\n                }\n                for pat in *r {\n                    self.hash_pat(pat);\n                }\n            },\n            PatKind::Struct(qpath, fields, e) => {\n                self.hash_qpath(qpath);\n                for f in *fields {\n                    self.hash_name(f.ident.name);\n                    self.hash_pat(f.pat);\n                }\n                e.hash(&mut self.s);\n            },\n            PatKind::Tuple(pats, e) => {\n                for pat in *pats {\n                    self.hash_pat(pat);\n                }\n                e.hash(&mut self.s);\n            },\n            PatKind::TupleStruct(qpath, pats, e) => {\n                self.hash_qpath(qpath);\n                for pat in *pats {\n                    self.hash_pat(pat);\n                }\n                e.hash(&mut self.s);\n            },\n            PatKind::Never | PatKind::Wild | PatKind::Err(_) => {},\n        }\n    }\n\n    pub fn hash_path(&mut self, path: &Path<'_>) {\n        match path.res {\n            // constant hash since equality is dependant on inter-expression context\n            // e.g. The expressions `if let Some(x) = foo() {}` and `if let Some(y) = foo() {}` are considered equal\n            // even though the binding names are different and they have different `HirId`s.\n            Res::Local(_) => 1_usize.hash(&mut self.s),\n            _ => {\n                if let PathCheck::Resolution = self.path_check\n                    && let [.., last] = path.segments\n                    && let Some(segments) = generic_path_segments(path.segments)\n                {\n                    for seg in segments {\n                        self.hash_generic_args(seg.args().args);\n                    }\n                    last.res.hash(&mut self.s);\n                } else {\n                    for seg in path.segments {\n                        self.hash_name(seg.ident.name);\n                        self.hash_generic_args(seg.args().args);\n                    }\n                }\n            },\n        }\n    }\n\n    pub fn hash_modifiers(&mut self, modifiers: TraitBoundModifiers) {\n        let TraitBoundModifiers { constness, polarity } = modifiers;\n        std::mem::discriminant(&polarity).hash(&mut self.s);\n        std::mem::discriminant(&constness).hash(&mut self.s);\n    }\n\n    pub fn hash_stmt(&mut self, b: &Stmt<'_>) {\n        std::mem::discriminant(&b.kind).hash(&mut self.s);\n\n        match &b.kind {\n            StmtKind::Let(local) => {\n                self.hash_pat(local.pat);\n                if let Some(init) = local.init {\n                    self.hash_expr(init);\n                }\n                if let Some(els) = local.els {\n                    self.hash_block(els);\n                }\n            },\n            StmtKind::Item(..) => {},\n            StmtKind::Expr(expr) | StmtKind::Semi(expr) => {\n                self.hash_expr(expr);\n            },\n        }\n    }\n\n    pub fn hash_lifetime(&mut self, lifetime: &Lifetime) {\n        lifetime.ident.name.hash(&mut self.s);\n        std::mem::discriminant(&lifetime.kind).hash(&mut self.s);\n        if let LifetimeKind::Param(param_id) = lifetime.kind {\n            param_id.hash(&mut self.s);\n        }\n    }\n\n    pub fn hash_ty(&mut self, ty: &Ty<'_>) {\n        std::mem::discriminant(&ty.kind).hash(&mut self.s);\n        self.hash_tykind(&ty.kind);\n    }\n\n    pub fn hash_tykind(&mut self, ty: &TyKind<'_>) {\n        match ty {\n            TyKind::Slice(ty) => {\n                self.hash_ty(ty);\n            },\n            TyKind::Array(ty, len) => {\n                self.hash_ty(ty);\n                self.hash_const_arg(len);\n            },\n            TyKind::Pat(ty, pat) => {\n                self.hash_ty(ty);\n                self.hash_ty_pat(pat);\n            },\n            TyKind::FieldOf(base, TyFieldPath { variant, field }) => {\n                self.hash_ty(base);\n                if let Some(variant) = variant {\n                    self.hash_name(variant.name);\n                }\n                self.hash_name(field.name);\n            },\n            TyKind::Ptr(mut_ty) => {\n                self.hash_ty(mut_ty.ty);\n                mut_ty.mutbl.hash(&mut self.s);\n            },\n            TyKind::Ref(lifetime, mut_ty) => {\n                self.hash_lifetime(lifetime);\n                self.hash_ty(mut_ty.ty);\n                mut_ty.mutbl.hash(&mut self.s);\n            },\n            TyKind::FnPtr(fn_ptr) => {\n                fn_ptr.safety.hash(&mut self.s);\n                fn_ptr.abi.hash(&mut self.s);\n                for arg in fn_ptr.decl.inputs {\n                    self.hash_ty(arg);\n                }\n                std::mem::discriminant(&fn_ptr.decl.output).hash(&mut self.s);\n                match fn_ptr.decl.output {\n                    FnRetTy::DefaultReturn(_) => {},\n                    FnRetTy::Return(ty) => {\n                        self.hash_ty(ty);\n                    },\n                }\n                fn_ptr.decl.c_variadic.hash(&mut self.s);\n            },\n            TyKind::Tup(ty_list) => {\n                for ty in *ty_list {\n                    self.hash_ty(ty);\n                }\n            },\n            TyKind::Path(qpath) => self.hash_qpath(qpath),\n            TyKind::TraitObject(_, lifetime) => {\n                self.hash_lifetime(lifetime);\n            },\n            TyKind::UnsafeBinder(binder) => {\n                self.hash_ty(binder.inner_ty);\n            },\n            TyKind::Err(_)\n            | TyKind::Infer(())\n            | TyKind::Never\n            | TyKind::InferDelegation(..)\n            | TyKind::OpaqueDef(_)\n            | TyKind::TraitAscription(_) => {},\n        }\n    }\n\n    pub fn hash_body(&mut self, body_id: BodyId) {\n        // swap out TypeckResults when hashing a body\n        let old_maybe_typeck_results = self.maybe_typeck_results.replace(self.cx.tcx.typeck_body(body_id));\n        self.hash_expr(self.cx.tcx.hir_body(body_id).value);\n        self.maybe_typeck_results = old_maybe_typeck_results;\n    }\n\n    fn hash_const_arg(&mut self, const_arg: &ConstArg<'_>) {\n        match &const_arg.kind {\n            ConstArgKind::Tup(tup) => {\n                for arg in *tup {\n                    self.hash_const_arg(arg);\n                }\n            },\n            ConstArgKind::Path(path) => self.hash_qpath(path),\n            ConstArgKind::Anon(anon) => self.hash_body(anon.body),\n            ConstArgKind::Struct(path, inits) => {\n                self.hash_qpath(path);\n                for init in *inits {\n                    self.hash_const_arg(init.expr);\n                }\n            },\n            ConstArgKind::TupleCall(path, args) => {\n                self.hash_qpath(path);\n                for arg in *args {\n                    self.hash_const_arg(arg);\n                }\n            },\n            ConstArgKind::Array(array_expr) => {\n                for elem in array_expr.elems {\n                    self.hash_const_arg(elem);\n                }\n            },\n            ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {},\n            ConstArgKind::Literal { lit, negated } => {\n                lit.hash(&mut self.s);\n                negated.hash(&mut self.s);\n            },\n        }\n    }\n\n    fn hash_generic_args(&mut self, arg_list: &[GenericArg<'_>]) {\n        for arg in arg_list {\n            match arg {\n                GenericArg::Lifetime(l) => self.hash_lifetime(l),\n                GenericArg::Type(ty) => self.hash_ty(ty.as_unambig_ty()),\n                GenericArg::Const(ca) => self.hash_const_arg(ca.as_unambig_ct()),\n                GenericArg::Infer(inf) => self.hash_ty(&inf.to_ty()),\n            }\n        }\n    }\n}\n\npub fn hash_stmt(cx: &LateContext<'_>, s: &Stmt<'_>) -> u64 {\n    let mut h = SpanlessHash::new(cx);\n    h.hash_stmt(s);\n    h.finish()\n}\n\npub fn is_bool(ty: &Ty<'_>) -> bool {\n    if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind {\n        matches!(path.res, Res::PrimTy(PrimTy::Bool))\n    } else {\n        false\n    }\n}\n\npub fn hash_expr(cx: &LateContext<'_>, e: &Expr<'_>) -> u64 {\n    let mut h = SpanlessHash::new(cx);\n    h.hash_expr(e);\n    h.finish()\n}\n\nfn eq_span_tokens(\n    cx: &LateContext<'_>,\n    left: impl SpanRange,\n    right: impl SpanRange,\n    pred: impl Fn(TokenKind) -> bool,\n) -> bool {\n    fn f(cx: &LateContext<'_>, left: Range<BytePos>, right: Range<BytePos>, pred: impl Fn(TokenKind) -> bool) -> bool {\n        if let Some(lsrc) = left.get_source_range(cx)\n            && let Some(lsrc) = lsrc.as_str()\n            && let Some(rsrc) = right.get_source_range(cx)\n            && let Some(rsrc) = rsrc.as_str()\n        {\n            let pred = |&(token, ..): &(TokenKind, _, _)| pred(token);\n            let map = |(_, source, _)| source;\n\n            let ltok = tokenize_with_text(lsrc).filter(pred).map(map);\n            let rtok = tokenize_with_text(rsrc).filter(pred).map(map);\n            ltok.eq(rtok)\n        } else {\n            // Unable to access the source. Conservatively assume the blocks aren't equal.\n            false\n        }\n    }\n    f(cx, left.into_range(), right.into_range(), pred)\n}\n\n/// Returns true if the expression contains ambiguous literals (unsuffixed float or int literals)\n/// that could be interpreted as either f32/f64 or i32/i64 depending on context.\npub fn has_ambiguous_literal_in_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Path(ref qpath) => {\n            if let Res::Local(hir_id) = cx.qpath_res(qpath, expr.hir_id)\n                && let Node::LetStmt(local) = cx.tcx.parent_hir_node(hir_id)\n                && local.ty.is_none()\n                && let Some(init) = local.init\n            {\n                return has_ambiguous_literal_in_expr(cx, init);\n            }\n            false\n        },\n        ExprKind::Lit(lit) => matches!(\n            lit.node,\n            ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) | ast::LitKind::Int(_, ast::LitIntType::Unsuffixed)\n        ),\n\n        ExprKind::Array(exprs) | ExprKind::Tup(exprs) => exprs.iter().any(|e| has_ambiguous_literal_in_expr(cx, e)),\n\n        ExprKind::Assign(lhs, rhs, _) | ExprKind::AssignOp(_, lhs, rhs) | ExprKind::Binary(_, lhs, rhs) => {\n            has_ambiguous_literal_in_expr(cx, lhs) || has_ambiguous_literal_in_expr(cx, rhs)\n        },\n\n        ExprKind::Unary(_, e)\n        | ExprKind::Cast(e, _)\n        | ExprKind::Type(e, _)\n        | ExprKind::DropTemps(e)\n        | ExprKind::AddrOf(_, _, e)\n        | ExprKind::Field(e, _)\n        | ExprKind::Index(e, _, _)\n        | ExprKind::Yield(e, _) => has_ambiguous_literal_in_expr(cx, e),\n\n        ExprKind::MethodCall(_, receiver, args, _) | ExprKind::Call(receiver, args) => {\n            has_ambiguous_literal_in_expr(cx, receiver) || args.iter().any(|e| has_ambiguous_literal_in_expr(cx, e))\n        },\n\n        ExprKind::Closure(Closure { body, .. }) => {\n            let body = cx.tcx.hir_body(*body);\n            let closure_expr = crate::peel_blocks(body.value);\n            has_ambiguous_literal_in_expr(cx, closure_expr)\n        },\n\n        ExprKind::Block(blk, _) => blk.expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e)),\n\n        ExprKind::If(cond, then_expr, else_expr) => {\n            has_ambiguous_literal_in_expr(cx, cond)\n                || has_ambiguous_literal_in_expr(cx, then_expr)\n                || else_expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e))\n        },\n\n        ExprKind::Match(scrutinee, arms, _) => {\n            has_ambiguous_literal_in_expr(cx, scrutinee)\n                || arms.iter().any(|arm| has_ambiguous_literal_in_expr(cx, arm.body))\n        },\n\n        ExprKind::Loop(body, ..) => body.expr.is_some_and(|e| has_ambiguous_literal_in_expr(cx, e)),\n\n        ExprKind::Ret(opt_expr) | ExprKind::Break(_, opt_expr) => {\n            opt_expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e))\n        },\n\n        _ => false,\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/lib.rs",
    "content": "#![cfg_attr(bootstrap, feature(if_let_guard))]\n#![feature(box_patterns)]\n#![feature(macro_metavar_expr)]\n#![feature(never_type)]\n#![feature(rustc_private)]\n#![cfg_attr(bootstrap, feature(assert_matches))]\n#![feature(unwrap_infallible)]\n#![recursion_limit = \"512\"]\n#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc, clippy::must_use_candidate)]\n#![warn(\n    trivial_casts,\n    trivial_numeric_casts,\n    rust_2018_idioms,\n    unused_lifetimes,\n    unused_qualifications,\n    rustc::internal\n)]\n\n// FIXME: switch to something more ergonomic here, once available.\n// (Currently there is no way to opt into sysroot crates without `extern crate`.)\nextern crate rustc_abi;\nextern crate rustc_ast;\nextern crate rustc_attr_parsing;\nextern crate rustc_const_eval;\nextern crate rustc_data_structures;\n#[expect(\n    unused_extern_crates,\n    reason = \"The `rustc_driver` crate seems to be required in order to use the `rust_ast` crate.\"\n)]\nextern crate rustc_driver;\nextern crate rustc_errors;\nextern crate rustc_hir;\nextern crate rustc_hir_analysis;\nextern crate rustc_hir_typeck;\nextern crate rustc_index;\nextern crate rustc_infer;\nextern crate rustc_lexer;\nextern crate rustc_lint;\nextern crate rustc_middle;\nextern crate rustc_mir_dataflow;\nextern crate rustc_session;\nextern crate rustc_span;\nextern crate rustc_trait_selection;\n\npub mod ast_utils;\n#[deny(missing_docs)]\npub mod attrs;\nmod check_proc_macro;\npub mod comparisons;\npub mod consts;\npub mod diagnostics;\npub mod eager_or_lazy;\npub mod higher;\nmod hir_utils;\npub mod macros;\npub mod mir;\npub mod msrvs;\npub mod numeric_literal;\npub mod paths;\npub mod qualify_min_const_fn;\npub mod res;\npub mod source;\npub mod str_utils;\npub mod sugg;\npub mod sym;\npub mod ty;\npub mod usage;\npub mod visitors;\n\npub use self::attrs::*;\npub use self::check_proc_macro::{is_from_proc_macro, is_span_if, is_span_match};\npub use self::hir_utils::{\n    HirEqInterExpr, SpanlessEq, SpanlessHash, both, count_eq, eq_expr_value, has_ambiguous_literal_in_expr, hash_expr,\n    hash_stmt, is_bool, over,\n};\n\nuse core::mem;\nuse core::ops::ControlFlow;\nuse std::collections::hash_map::Entry;\nuse std::iter::{once, repeat_n, zip};\nuse std::sync::{Mutex, MutexGuard, OnceLock};\n\nuse itertools::Itertools;\nuse rustc_abi::Integer;\nuse rustc_ast::ast::{self, LitKind, RangeLimits};\nuse rustc_ast::{LitIntType, join_path_syms};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_data_structures::indexmap;\nuse rustc_data_structures::packed::Pu128;\nuse rustc_data_structures::unhash::UnindexMap;\nuse rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};\nuse rustc_hir::attrs::CfgEntry;\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};\nuse rustc_hir::definitions::{DefPath, DefPathData};\nuse rustc_hir::hir_id::{HirIdMap, HirIdSet};\nuse rustc_hir::intravisit::{Visitor, walk_expr};\nuse rustc_hir::{\n    self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, CoroutineDesugaring,\n    CoroutineKind, CoroutineSource, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArg, GenericArgs,\n    HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId,\n    OwnerNode, Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem,\n    TraitItemKind, TraitRef, TyKind, UnOp, def, find_attr,\n};\nuse rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};\nuse rustc_lint::{LateContext, Level, Lint, LintContext};\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::hir::place::PlaceBase;\nuse rustc_middle::lint::LevelAndSource;\nuse rustc_middle::mir::{AggregateKind, Operand, RETURN_PLACE, Rvalue, StatementKind, TerminatorKind};\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, DerefAdjustKind, PointerCoercion};\nuse rustc_middle::ty::layout::IntegerExt;\nuse rustc_middle::ty::{\n    self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, GenericArgKind, GenericArgsRef, IntTy, Ty, TyCtxt,\n    TypeFlags, TypeVisitableExt, UintTy, UpvarCapture,\n};\nuse rustc_span::hygiene::{ExpnKind, MacroKind};\nuse rustc_span::source_map::SourceMap;\nuse rustc_span::symbol::{Ident, Symbol, kw};\nuse rustc_span::{InnerSpan, Span};\nuse source::{SpanRangeExt, walk_span_to_context};\nuse visitors::{Visitable, for_each_unconsumed_temporary};\n\nuse crate::ast_utils::unordered_over;\nuse crate::consts::{ConstEvalCtxt, Constant};\nuse crate::higher::Range;\nuse crate::msrvs::Msrv;\nuse crate::res::{MaybeDef, MaybeQPath, MaybeResPath};\nuse crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type};\nuse crate::visitors::for_each_expr_without_closures;\n\n/// Methods on `Vec` that also exists on slices.\npub const VEC_METHODS_SHADOWING_SLICE_METHODS: [Symbol; 3] = [sym::as_ptr, sym::is_empty, sym::len];\n\n#[macro_export]\nmacro_rules! extract_msrv_attr {\n    () => {\n        fn check_attributes(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::ast::Attribute]) {\n            let sess = rustc_lint::LintContext::sess(cx);\n            self.msrv.check_attributes(sess, attrs);\n        }\n\n        fn check_attributes_post(&mut self, cx: &rustc_lint::EarlyContext<'_>, attrs: &[rustc_ast::ast::Attribute]) {\n            let sess = rustc_lint::LintContext::sess(cx);\n            self.msrv.check_attributes_post(sess, attrs);\n        }\n    };\n}\n\n/// If the given expression is a local binding, find the initializer expression.\n/// If that initializer expression is another local binding, find its initializer again.\n///\n/// This process repeats as long as possible (but usually no more than once). Initializer\n/// expressions with adjustments are ignored. If this is not desired, use [`find_binding_init`]\n/// instead.\n///\n/// Examples:\n/// ```no_run\n/// let abc = 1;\n/// //        ^ output\n/// let def = abc;\n/// dbg!(def);\n/// //   ^^^ input\n///\n/// // or...\n/// let abc = 1;\n/// let def = abc + 2;\n/// //        ^^^^^^^ output\n/// dbg!(def);\n/// //   ^^^ input\n/// ```\npub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr<'b>) -> &'a Expr<'b> {\n    while let Some(init) = expr\n        .res_local_id()\n        .and_then(|id| find_binding_init(cx, id))\n        .filter(|init| cx.typeck_results().expr_adjustments(init).is_empty())\n    {\n        expr = init;\n    }\n    expr\n}\n\n/// Finds the initializer expression for a local binding. Returns `None` if the binding is mutable.\n///\n/// By only considering immutable bindings, we guarantee that the returned expression represents the\n/// value of the binding wherever it is referenced.\n///\n/// Example: For `let x = 1`, if the `HirId` of `x` is provided, the `Expr` `1` is returned.\n/// Note: If you have an expression that references a binding `x`, use `path_to_local` to get the\n/// canonical binding `HirId`.\npub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {\n    if let Node::Pat(pat) = cx.tcx.hir_node(hir_id)\n        && matches!(pat.kind, PatKind::Binding(BindingMode::NONE, ..))\n        && let Node::LetStmt(local) = cx.tcx.parent_hir_node(hir_id)\n    {\n        return local.init;\n    }\n    None\n}\n\n/// Checks if the given local has an initializer or is from something other than a `let` statement\n///\n/// e.g. returns true for `x` in `fn f(x: usize) { .. }` and `let x = 1;` but false for `let x;`\npub fn local_is_initialized(cx: &LateContext<'_>, local: HirId) -> bool {\n    for (_, node) in cx.tcx.hir_parent_iter(local) {\n        match node {\n            Node::Pat(..) | Node::PatField(..) => {},\n            Node::LetStmt(let_stmt) => return let_stmt.init.is_some(),\n            _ => return true,\n        }\n    }\n\n    false\n}\n\n/// Checks if we are currently in a const context (e.g. `const fn`, `static`/`const` initializer).\n///\n/// The current context is determined based on the current body which is set before calling a lint's\n/// entry point (any function on `LateLintPass`). If you need to check in a different context use\n/// `tcx.hir_is_inside_const_context(_)`.\n///\n/// Do not call this unless the `LateContext` has an enclosing body. For release build this case\n/// will safely return `false`, but debug builds will ICE. Note that `check_expr`, `check_block`,\n/// `check_pat` and a few other entry points will always have an enclosing body. Some entry points\n/// like `check_path` or `check_ty` may or may not have one.\npub fn is_in_const_context(cx: &LateContext<'_>) -> bool {\n    debug_assert!(cx.enclosing_body.is_some(), \"`LateContext` has no enclosing body\");\n    cx.enclosing_body.is_some_and(|id| {\n        cx.tcx\n            .hir_body_const_context(cx.tcx.hir_body_owner_def_id(id))\n            .is_some()\n    })\n}\n\n/// Returns `true` if the given `HirId` is inside an always constant context.\n///\n/// This context includes:\n///  * const/static items\n///  * const blocks (or inline consts)\n///  * associated constants\npub fn is_inside_always_const_context(tcx: TyCtxt<'_>, hir_id: HirId) -> bool {\n    use rustc_hir::ConstContext::{Const, ConstFn, Static};\n    let Some(ctx) = tcx.hir_body_const_context(tcx.hir_enclosing_body_owner(hir_id)) else {\n        return false;\n    };\n    match ctx {\n        ConstFn => false,\n        Static(_) | Const { inline: _ } => true,\n    }\n}\n\n/// Checks if `{ctor_call_id}(...)` is `{enum_item}::{variant_name}(...)`.\npub fn is_enum_variant_ctor(\n    cx: &LateContext<'_>,\n    enum_item: Symbol,\n    variant_name: Symbol,\n    ctor_call_id: DefId,\n) -> bool {\n    let Some(enum_def_id) = cx.tcx.get_diagnostic_item(enum_item) else {\n        return false;\n    };\n\n    let variants = cx.tcx.adt_def(enum_def_id).variants().iter();\n    variants\n        .filter(|variant| variant.name == variant_name)\n        .filter_map(|variant| variant.ctor.as_ref())\n        .any(|(_, ctor_def_id)| *ctor_def_id == ctor_call_id)\n}\n\n/// Checks if the `DefId` matches the given diagnostic item or it's constructor.\npub fn is_diagnostic_item_or_ctor(cx: &LateContext<'_>, did: DefId, item: Symbol) -> bool {\n    let did = match cx.tcx.def_kind(did) {\n        DefKind::Ctor(..) => cx.tcx.parent(did),\n        // Constructors for types in external crates seem to have `DefKind::Variant`\n        DefKind::Variant => match cx.tcx.opt_parent(did) {\n            Some(did) if matches!(cx.tcx.def_kind(did), DefKind::Variant) => did,\n            _ => did,\n        },\n        _ => did,\n    };\n\n    cx.tcx.is_diagnostic_item(item, did)\n}\n\n/// Checks if the `DefId` matches the given `LangItem` or it's constructor.\npub fn is_lang_item_or_ctor(cx: &LateContext<'_>, did: DefId, item: LangItem) -> bool {\n    let did = match cx.tcx.def_kind(did) {\n        DefKind::Ctor(..) => cx.tcx.parent(did),\n        // Constructors for types in external crates seem to have `DefKind::Variant`\n        DefKind::Variant => match cx.tcx.opt_parent(did) {\n            Some(did) if matches!(cx.tcx.def_kind(did), DefKind::Variant) => did,\n            _ => did,\n        },\n        _ => did,\n    };\n\n    cx.tcx.lang_items().get(item) == Some(did)\n}\n\n/// Checks is `expr` is `None`\npub fn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    expr.res(cx).ctor_parent(cx).is_lang_item(cx, OptionNone)\n}\n\n/// If `expr` is `Some(inner)`, returns `inner`\npub fn as_some_expr<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    if let ExprKind::Call(e, [arg]) = expr.kind\n        && e.res(cx).ctor_parent(cx).is_lang_item(cx, OptionSome)\n    {\n        Some(arg)\n    } else {\n        None\n    }\n}\n\n/// Checks if `expr` is an empty block or an empty tuple.\npub fn is_unit_expr(expr: &Expr<'_>) -> bool {\n    matches!(\n        expr.kind,\n        ExprKind::Block(\n            Block {\n                stmts: [],\n                expr: None,\n                ..\n            },\n            _\n        ) | ExprKind::Tup([])\n    )\n}\n\n/// Checks if given pattern is a wildcard (`_`)\npub fn is_wild(pat: &Pat<'_>) -> bool {\n    matches!(pat.kind, PatKind::Wild)\n}\n\n/// If `pat` is:\n/// - `Some(inner)`, returns `inner`\n///    - it will _usually_ contain just one element, but could have two, given patterns like\n///      `Some(inner, ..)` or `Some(.., inner)`\n/// - `Some`, returns `[]`\n/// - otherwise, returns `None`\npub fn as_some_pattern<'a, 'hir>(cx: &LateContext<'_>, pat: &'a Pat<'hir>) -> Option<&'a [Pat<'hir>]> {\n    if let PatKind::TupleStruct(ref qpath, inner, _) = pat.kind\n        && cx\n            .qpath_res(qpath, pat.hir_id)\n            .ctor_parent(cx)\n            .is_lang_item(cx, OptionSome)\n    {\n        Some(inner)\n    } else {\n        None\n    }\n}\n\n/// Checks if the `pat` is `None`.\npub fn is_none_pattern(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {\n    matches!(pat.kind,\n        PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), .. })\n            if cx.qpath_res(qpath, pat.hir_id).ctor_parent(cx).is_lang_item(cx, OptionNone))\n}\n\n/// Checks if `arm` has the form `None => None`.\npub fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {\n    is_none_pattern(cx, arm.pat)\n        && matches!(\n            peel_blocks(arm.body).kind,\n            ExprKind::Path(qpath)\n            if cx.qpath_res(&qpath, arm.body.hir_id).ctor_parent(cx).is_lang_item(cx, OptionNone)\n        )\n}\n\n/// Checks if the given `QPath` belongs to a type alias.\npub fn is_ty_alias(qpath: &QPath<'_>) -> bool {\n    match *qpath {\n        QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)),\n        QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => is_ty_alias(&qpath),\n        QPath::TypeRelative(..) => false,\n    }\n}\n\n/// Checks if the `def_id` belongs to a function that is part of a trait impl.\npub fn is_def_id_trait_method(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {\n    if let Node::Item(item) = cx.tcx.parent_hir_node(cx.tcx.local_def_id_to_hir_id(def_id))\n        && let ItemKind::Impl(imp) = item.kind\n    {\n        imp.of_trait.is_some()\n    } else {\n        false\n    }\n}\n\npub fn last_path_segment<'tcx>(path: &QPath<'tcx>) -> &'tcx PathSegment<'tcx> {\n    match *path {\n        QPath::Resolved(_, path) => path.segments.last().expect(\"A path must have at least one segment\"),\n        QPath::TypeRelative(_, seg) => seg,\n    }\n}\n\npub fn qpath_generic_tys<'tcx>(qpath: &QPath<'tcx>) -> impl Iterator<Item = &'tcx hir::Ty<'tcx>> {\n    last_path_segment(qpath)\n        .args\n        .map_or(&[][..], |a| a.args)\n        .iter()\n        .filter_map(|a| match a {\n            GenericArg::Type(ty) => Some(ty.as_unambig_ty()),\n            _ => None,\n        })\n}\n\n/// If the expression is a path to a local (with optional projections),\n/// returns the canonical `HirId` of the local.\n///\n/// For example, `x.field[0].field2` would return the `HirId` of `x`.\npub fn path_to_local_with_projections(expr: &Expr<'_>) -> Option<HirId> {\n    match expr.kind {\n        ExprKind::Field(recv, _) | ExprKind::Index(recv, _, _) => path_to_local_with_projections(recv),\n        ExprKind::Path(QPath::Resolved(\n            _,\n            Path {\n                res: Res::Local(local), ..\n            },\n        )) => Some(*local),\n        _ => None,\n    }\n}\n\n/// Gets the `hir::TraitRef` of the trait the given method is implemented for.\n///\n/// Use this if you want to find the `TraitRef` of the `Add` trait in this example:\n///\n/// ```no_run\n/// struct Point(isize, isize);\n///\n/// impl std::ops::Add for Point {\n///     type Output = Self;\n///\n///     fn add(self, other: Self) -> Self {\n///         Point(0, 0)\n///     }\n/// }\n/// ```\npub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, owner: OwnerId) -> Option<&'tcx TraitRef<'tcx>> {\n    if let Node::Item(item) = cx.tcx.hir_node(cx.tcx.hir_owner_parent(owner))\n        && let ItemKind::Impl(impl_) = &item.kind\n        && let Some(of_trait) = impl_.of_trait\n    {\n        return Some(&of_trait.trait_ref);\n    }\n    None\n}\n\n/// This method will return tuple of projection stack and root of the expression,\n/// used in `can_mut_borrow_both`.\n///\n/// For example, if `e` represents the `v[0].a.b[x]`\n/// this method will return a tuple, composed of a `Vec`\n/// containing the `Expr`s for `v[0], v[0].a, v[0].a.b, v[0].a.b[x]`\n/// and an `Expr` for root of them, `v`\nfn projection_stack<'a, 'hir>(mut e: &'a Expr<'hir>) -> (Vec<&'a Expr<'hir>>, &'a Expr<'hir>) {\n    let mut result = vec![];\n    let root = loop {\n        match e.kind {\n            ExprKind::Index(ep, _, _) | ExprKind::Field(ep, _) => {\n                result.push(e);\n                e = ep;\n            },\n            _ => break e,\n        }\n    };\n    result.reverse();\n    (result, root)\n}\n\n/// Gets the mutability of the custom deref adjustment, if any.\npub fn expr_custom_deref_adjustment(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<Mutability> {\n    cx.typeck_results()\n        .expr_adjustments(e)\n        .iter()\n        .find_map(|a| match a.kind {\n            Adjust::Deref(DerefAdjustKind::Overloaded(d)) => Some(Some(d.mutbl)),\n            Adjust::Deref(DerefAdjustKind::Builtin) => None,\n            _ => Some(None),\n        })\n        .and_then(|x| x)\n}\n\n/// Checks if two expressions can be mutably borrowed simultaneously\n/// and they aren't dependent on borrowing same thing twice\npub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -> bool {\n    let (s1, r1) = projection_stack(e1);\n    let (s2, r2) = projection_stack(e2);\n    if !eq_expr_value(cx, r1, r2) {\n        return true;\n    }\n    if expr_custom_deref_adjustment(cx, r1).is_some() || expr_custom_deref_adjustment(cx, r2).is_some() {\n        return false;\n    }\n\n    for (x1, x2) in zip(&s1, &s2) {\n        if expr_custom_deref_adjustment(cx, x1).is_some() || expr_custom_deref_adjustment(cx, x2).is_some() {\n            return false;\n        }\n\n        match (&x1.kind, &x2.kind) {\n            (ExprKind::Field(_, i1), ExprKind::Field(_, i2)) => {\n                if i1 != i2 {\n                    return true;\n                }\n            },\n            (ExprKind::Index(_, i1, _), ExprKind::Index(_, i2, _)) => {\n                if !eq_expr_value(cx, i1, i2) {\n                    return false;\n                }\n            },\n            _ => return false,\n        }\n    }\n    false\n}\n\n/// Returns true if the `def_id` associated with the `path` is recognized as a \"default-equivalent\"\n/// constructor from the std library\nfn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<'_>) -> bool {\n    let std_types_symbols = &[\n        sym::Vec,\n        sym::VecDeque,\n        sym::LinkedList,\n        sym::HashMap,\n        sym::BTreeMap,\n        sym::HashSet,\n        sym::BTreeSet,\n        sym::BinaryHeap,\n    ];\n\n    if let QPath::TypeRelative(_, method) = path\n        && method.ident.name == sym::new\n        && let Some(impl_did) = cx.tcx.impl_of_assoc(def_id)\n        && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def()\n    {\n        return Some(adt.did()) == cx.tcx.lang_items().string()\n            || (cx.tcx.get_diagnostic_name(adt.did())).is_some_and(|adt_name| std_types_symbols.contains(&adt_name));\n    }\n    false\n}\n\n/// Returns true if the expr is equal to `Default::default` when evaluated.\npub fn is_default_equivalent_call(\n    cx: &LateContext<'_>,\n    repl_func: &Expr<'_>,\n    whole_call_expr: Option<&Expr<'_>>,\n) -> bool {\n    if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind\n        && let Some(repl_def) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def(cx)\n        && (repl_def.assoc_fn_parent(cx).is_diag_item(cx, sym::Default)\n            || is_default_equivalent_ctor(cx, repl_def.1, repl_func_qpath))\n    {\n        return true;\n    }\n\n    // Get the type of the whole method call expression, find the exact method definition, look at\n    // its body and check if it is similar to the corresponding `Default::default()` body.\n    let Some(e) = whole_call_expr else { return false };\n    let Some(default_fn_def_id) = cx.tcx.get_diagnostic_item(sym::default_fn) else {\n        return false;\n    };\n    let Some(ty) = cx.tcx.typeck(e.hir_id.owner.def_id).expr_ty_adjusted_opt(e) else {\n        return false;\n    };\n    let args = rustc_ty::GenericArgs::for_item(cx.tcx, default_fn_def_id, |param, _| {\n        if let rustc_ty::GenericParamDefKind::Lifetime = param.kind {\n            cx.tcx.lifetimes.re_erased.into()\n        } else if param.index == 0 && param.name == kw::SelfUpper {\n            ty.into()\n        } else {\n            param.to_error(cx.tcx)\n        }\n    });\n    let instance = rustc_ty::Instance::try_resolve(cx.tcx, cx.typing_env(), default_fn_def_id, args);\n\n    let Ok(Some(instance)) = instance else { return false };\n    if let rustc_ty::InstanceKind::Item(def) = instance.def\n        && !cx.tcx.is_mir_available(def)\n    {\n        return false;\n    }\n    let ExprKind::Path(ref repl_func_qpath) = repl_func.kind else {\n        return false;\n    };\n    let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id() else {\n        return false;\n    };\n\n    // Get the MIR Body for the `<Ty as Default>::default()` function.\n    // If it is a value or call (either fn or ctor), we compare its `DefId` against the one for the\n    // resolution of the expression we had in the path. This lets us identify, for example, that\n    // the body of `<Vec<T> as Default>::default()` is a `Vec::new()`, and the field was being\n    // initialized to `Vec::new()` as well.\n    let body = cx.tcx.instance_mir(instance.def);\n    for block_data in body.basic_blocks.iter() {\n        if block_data.statements.len() == 1\n            && let StatementKind::Assign(assign) = &block_data.statements[0].kind\n            && assign.0.local == RETURN_PLACE\n            && let Rvalue::Aggregate(kind, _places) = &assign.1\n            && let AggregateKind::Adt(did, variant_index, _, _, _) = **kind\n            && let def = cx.tcx.adt_def(did)\n            && let variant = &def.variant(variant_index)\n            && variant.fields.is_empty()\n            && let Some((_, did)) = variant.ctor\n            && did == repl_def_id\n        {\n            return true;\n        } else if block_data.statements.is_empty()\n            && let Some(term) = &block_data.terminator\n        {\n            match &term.kind {\n                TerminatorKind::Call {\n                    func: Operand::Constant(c),\n                    ..\n                } if let rustc_ty::FnDef(did, _args) = c.ty().kind()\n                    && *did == repl_def_id =>\n                {\n                    return true;\n                },\n                TerminatorKind::TailCall {\n                    func: Operand::Constant(c),\n                    ..\n                } if let rustc_ty::FnDef(did, _args) = c.ty().kind()\n                    && *did == repl_def_id =>\n                {\n                    return true;\n                },\n                _ => {},\n            }\n        }\n    }\n    false\n}\n\n/// Returns true if the expr is equal to `Default::default()` of its type when evaluated.\n///\n/// It doesn't cover all cases, like struct literals, but it is a close approximation.\npub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    match &e.kind {\n        ExprKind::Lit(lit) => match lit.node {\n            LitKind::Bool(false) | LitKind::Int(Pu128(0), _) => true,\n            LitKind::Str(s, _) => s.is_empty(),\n            _ => false,\n        },\n        ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)),\n        ExprKind::Repeat(x, len) => {\n            if let ConstArgKind::Anon(anon_const) = len.kind\n                && let ExprKind::Lit(const_lit) = cx.tcx.hir_body(anon_const.body).value.kind\n                && let LitKind::Int(v, _) = const_lit.node\n                && v <= 32\n                && is_default_equivalent(cx, x)\n            {\n                true\n            } else {\n                false\n            }\n        },\n        ExprKind::Call(repl_func, []) => is_default_equivalent_call(cx, repl_func, Some(e)),\n        ExprKind::Call(from_func, [arg]) => is_default_equivalent_from(cx, from_func, arg),\n        ExprKind::Path(qpath) => cx\n            .qpath_res(qpath, e.hir_id)\n            .ctor_parent(cx)\n            .is_lang_item(cx, OptionNone),\n        ExprKind::AddrOf(rustc_hir::BorrowKind::Ref, _, expr) => matches!(expr.kind, ExprKind::Array([])),\n        ExprKind::Block(Block { stmts: [], expr, .. }, _) => expr.is_some_and(|e| is_default_equivalent(cx, e)),\n        _ => false,\n    }\n}\n\nfn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &Expr<'_>) -> bool {\n    if let ExprKind::Path(QPath::TypeRelative(ty, seg)) = from_func.kind\n        && seg.ident.name == sym::from\n    {\n        match arg.kind {\n            ExprKind::Lit(hir::Lit {\n                node: LitKind::Str(sym, _),\n                ..\n            }) => return sym.is_empty() && ty.basic_res().is_lang_item(cx, LangItem::String),\n            ExprKind::Array([]) => return ty.basic_res().is_diag_item(cx, sym::Vec),\n            ExprKind::Repeat(_, len) => {\n                if let ConstArgKind::Anon(anon_const) = len.kind\n                    && let ExprKind::Lit(const_lit) = cx.tcx.hir_body(anon_const.body).value.kind\n                    && let LitKind::Int(v, _) = const_lit.node\n                {\n                    return v == 0 && ty.basic_res().is_diag_item(cx, sym::Vec);\n                }\n            },\n            _ => (),\n        }\n    }\n    false\n}\n\n/// Checks if the top level expression can be moved into a closure as is.\n/// Currently checks for:\n/// * Break/Continue outside the given loop HIR ids.\n/// * Yield/Return statements.\n/// * Inline assembly.\n/// * Usages of a field of a local where the type of the local can be partially moved.\n///\n/// For example, given the following function:\n///\n/// ```no_run\n/// fn f<'a>(iter: &mut impl Iterator<Item = (usize, &'a mut String)>) {\n///     for item in iter {\n///         let s = item.1;\n///         if item.0 > 10 {\n///             continue;\n///         } else {\n///             s.clear();\n///         }\n///     }\n/// }\n/// ```\n///\n/// When called on the expression `item.0` this will return false unless the local `item` is in the\n/// `ignore_locals` set. The type `(usize, &mut String)` can have the second element moved, so it\n/// isn't always safe to move into a closure when only a single field is needed.\n///\n/// When called on the `continue` expression this will return false unless the outer loop expression\n/// is in the `loop_ids` set.\n///\n/// Note that this check is not recursive, so passing the `if` expression will always return true\n/// even though sub-expressions might return false.\npub fn can_move_expr_to_closure_no_visit<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &'tcx Expr<'_>,\n    loop_ids: &[HirId],\n    ignore_locals: &HirIdSet,\n) -> bool {\n    match expr.kind {\n        ExprKind::Break(Destination { target_id: Ok(id), .. }, _)\n        | ExprKind::Continue(Destination { target_id: Ok(id), .. })\n            if loop_ids.contains(&id) =>\n        {\n            true\n        },\n        ExprKind::Break(..)\n        | ExprKind::Continue(_)\n        | ExprKind::Ret(_)\n        | ExprKind::Yield(..)\n        | ExprKind::InlineAsm(_) => false,\n        // Accessing a field of a local value can only be done if the type isn't\n        // partially moved.\n        ExprKind::Field(\n            &Expr {\n                hir_id,\n                kind:\n                    ExprKind::Path(QPath::Resolved(\n                        _,\n                        Path {\n                            res: Res::Local(local_id),\n                            ..\n                        },\n                    )),\n                ..\n            },\n            _,\n        ) if !ignore_locals.contains(local_id) && can_partially_move_ty(cx, cx.typeck_results().node_type(hir_id)) => {\n            // TODO: check if the local has been partially moved. Assume it has for now.\n            false\n        },\n        _ => true,\n    }\n}\n\n/// How a local is captured by a closure\n#[derive(Debug, Clone, Copy, PartialEq, Eq)]\npub enum CaptureKind {\n    Value,\n    Use,\n    Ref(Mutability),\n}\nimpl CaptureKind {\n    pub fn is_imm_ref(self) -> bool {\n        self == Self::Ref(Mutability::Not)\n    }\n}\nimpl std::ops::BitOr for CaptureKind {\n    type Output = Self;\n    fn bitor(self, rhs: Self) -> Self::Output {\n        match (self, rhs) {\n            (CaptureKind::Value, _) | (_, CaptureKind::Value) => CaptureKind::Value,\n            (CaptureKind::Use, _) | (_, CaptureKind::Use) => CaptureKind::Use,\n            (CaptureKind::Ref(Mutability::Mut), CaptureKind::Ref(_))\n            | (CaptureKind::Ref(_), CaptureKind::Ref(Mutability::Mut)) => CaptureKind::Ref(Mutability::Mut),\n            (CaptureKind::Ref(Mutability::Not), CaptureKind::Ref(Mutability::Not)) => CaptureKind::Ref(Mutability::Not),\n        }\n    }\n}\nimpl std::ops::BitOrAssign for CaptureKind {\n    fn bitor_assign(&mut self, rhs: Self) {\n        *self = *self | rhs;\n    }\n}\n\n/// Given an expression referencing a local, determines how it would be captured in a closure.\n///\n/// Note as this will walk up to parent expressions until the capture can be determined it should\n/// only be used while making a closure somewhere a value is consumed. e.g. a block, match arm, or\n/// function argument (other than a receiver).\npub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {\n    fn pat_capture_kind(cx: &LateContext<'_>, pat: &Pat<'_>) -> CaptureKind {\n        let mut capture = CaptureKind::Ref(Mutability::Not);\n        pat.each_binding_or_first(&mut |_, id, span, _| match cx\n            .typeck_results()\n            .extract_binding_mode(cx.sess(), id, span)\n            .0\n        {\n            ByRef::No if !is_copy(cx, cx.typeck_results().node_type(id)) => {\n                capture = CaptureKind::Value;\n            },\n            ByRef::Yes(_, Mutability::Mut) if capture != CaptureKind::Value => {\n                capture = CaptureKind::Ref(Mutability::Mut);\n            },\n            _ => (),\n        });\n        capture\n    }\n\n    debug_assert!(matches!(\n        e.kind,\n        ExprKind::Path(QPath::Resolved(None, Path { res: Res::Local(_), .. }))\n    ));\n\n    let mut child_id = e.hir_id;\n    let mut capture = CaptureKind::Value;\n    let mut capture_expr_ty = e;\n\n    for (parent_id, parent) in cx.tcx.hir_parent_iter(e.hir_id) {\n        if let [\n            Adjustment {\n                kind: Adjust::Deref(_) | Adjust::Borrow(AutoBorrow::Ref(..)),\n                target,\n            },\n            ref adjust @ ..,\n        ] = *cx\n            .typeck_results()\n            .adjustments()\n            .get(child_id)\n            .map_or(&[][..], |x| &**x)\n            && let rustc_ty::RawPtr(_, mutability) | rustc_ty::Ref(_, _, mutability) =\n                *adjust.last().map_or(target, |a| a.target).kind()\n        {\n            return CaptureKind::Ref(mutability);\n        }\n\n        match parent {\n            Node::Expr(e) => match e.kind {\n                ExprKind::AddrOf(_, mutability, _) => return CaptureKind::Ref(mutability),\n                ExprKind::Index(..) | ExprKind::Unary(UnOp::Deref, _) => capture = CaptureKind::Ref(Mutability::Not),\n                ExprKind::Assign(lhs, ..) | ExprKind::AssignOp(_, lhs, _) if lhs.hir_id == child_id => {\n                    return CaptureKind::Ref(Mutability::Mut);\n                },\n                ExprKind::Field(..) => {\n                    if capture == CaptureKind::Value {\n                        capture_expr_ty = e;\n                    }\n                },\n                ExprKind::Let(let_expr) => {\n                    let mutability = match pat_capture_kind(cx, let_expr.pat) {\n                        CaptureKind::Value | CaptureKind::Use => Mutability::Not,\n                        CaptureKind::Ref(m) => m,\n                    };\n                    return CaptureKind::Ref(mutability);\n                },\n                ExprKind::Match(_, arms, _) => {\n                    let mut mutability = Mutability::Not;\n                    for capture in arms.iter().map(|arm| pat_capture_kind(cx, arm.pat)) {\n                        match capture {\n                            CaptureKind::Value | CaptureKind::Use => break,\n                            CaptureKind::Ref(Mutability::Mut) => mutability = Mutability::Mut,\n                            CaptureKind::Ref(Mutability::Not) => (),\n                        }\n                    }\n                    return CaptureKind::Ref(mutability);\n                },\n                _ => break,\n            },\n            Node::LetStmt(l) => match pat_capture_kind(cx, l.pat) {\n                CaptureKind::Value | CaptureKind::Use => break,\n                capture @ CaptureKind::Ref(_) => return capture,\n            },\n            _ => break,\n        }\n\n        child_id = parent_id;\n    }\n\n    if capture == CaptureKind::Value && is_copy(cx, cx.typeck_results().expr_ty(capture_expr_ty)) {\n        // Copy types are never automatically captured by value.\n        CaptureKind::Ref(Mutability::Not)\n    } else {\n        capture\n    }\n}\n\n/// Checks if the expression can be moved into a closure as is. This will return a list of captures\n/// if so, otherwise, `None`.\npub fn can_move_expr_to_closure<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<HirIdMap<CaptureKind>> {\n    struct V<'cx, 'tcx> {\n        cx: &'cx LateContext<'tcx>,\n        // Stack of potential break targets contained in the expression.\n        loops: Vec<HirId>,\n        /// Local variables created in the expression. These don't need to be captured.\n        locals: HirIdSet,\n        /// Whether this expression can be turned into a closure.\n        allow_closure: bool,\n        /// Locals which need to be captured, and whether they need to be by value, reference, or\n        /// mutable reference.\n        captures: HirIdMap<CaptureKind>,\n    }\n    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {\n            if !self.allow_closure {\n                return;\n            }\n\n            match e.kind {\n                ExprKind::Path(QPath::Resolved(None, &Path { res: Res::Local(l), .. })) => {\n                    if !self.locals.contains(&l) {\n                        let cap = capture_local_usage(self.cx, e);\n                        self.captures.entry(l).and_modify(|e| *e |= cap).or_insert(cap);\n                    }\n                },\n                ExprKind::Closure(closure) => {\n                    for capture in self.cx.typeck_results().closure_min_captures_flattened(closure.def_id) {\n                        let local_id = match capture.place.base {\n                            PlaceBase::Local(id) => id,\n                            PlaceBase::Upvar(var) => var.var_path.hir_id,\n                            _ => continue,\n                        };\n                        if !self.locals.contains(&local_id) {\n                            let capture = match capture.info.capture_kind {\n                                UpvarCapture::ByValue => CaptureKind::Value,\n                                UpvarCapture::ByUse => CaptureKind::Use,\n                                UpvarCapture::ByRef(kind) => match kind {\n                                    BorrowKind::Immutable => CaptureKind::Ref(Mutability::Not),\n                                    BorrowKind::UniqueImmutable | BorrowKind::Mutable => {\n                                        CaptureKind::Ref(Mutability::Mut)\n                                    },\n                                },\n                            };\n                            self.captures\n                                .entry(local_id)\n                                .and_modify(|e| *e |= capture)\n                                .or_insert(capture);\n                        }\n                    }\n                },\n                ExprKind::Loop(b, ..) => {\n                    self.loops.push(e.hir_id);\n                    self.visit_block(b);\n                    self.loops.pop();\n                },\n                _ => {\n                    self.allow_closure &= can_move_expr_to_closure_no_visit(self.cx, e, &self.loops, &self.locals);\n                    walk_expr(self, e);\n                },\n            }\n        }\n\n        fn visit_pat(&mut self, p: &'tcx Pat<'tcx>) {\n            p.each_binding_or_first(&mut |_, id, _, _| {\n                self.locals.insert(id);\n            });\n        }\n    }\n\n    let mut v = V {\n        cx,\n        loops: Vec::new(),\n        locals: HirIdSet::default(),\n        allow_closure: true,\n        captures: HirIdMap::default(),\n    };\n    v.visit_expr(expr);\n    v.allow_closure.then_some(v.captures)\n}\n\n/// Arguments of a method: the receiver and all the additional arguments.\npub type MethodArguments<'tcx> = Vec<(&'tcx Expr<'tcx>, &'tcx [Expr<'tcx>])>;\n\n/// Returns the method names and argument list of nested method call expressions that make up\n/// `expr`. method/span lists are sorted with the most recent call first.\npub fn method_calls<'tcx>(expr: &'tcx Expr<'tcx>, max_depth: usize) -> (Vec<Symbol>, MethodArguments<'tcx>, Vec<Span>) {\n    let mut method_names = Vec::with_capacity(max_depth);\n    let mut arg_lists = Vec::with_capacity(max_depth);\n    let mut spans = Vec::with_capacity(max_depth);\n\n    let mut current = expr;\n    for _ in 0..max_depth {\n        if let ExprKind::MethodCall(path, receiver, args, _) = &current.kind {\n            if receiver.span.from_expansion() || args.iter().any(|e| e.span.from_expansion()) {\n                break;\n            }\n            method_names.push(path.ident.name);\n            arg_lists.push((*receiver, &**args));\n            spans.push(path.ident.span);\n            current = receiver;\n        } else {\n            break;\n        }\n    }\n\n    (method_names, arg_lists, spans)\n}\n\n/// Matches an `Expr` against a chain of methods, and return the matched `Expr`s.\n///\n/// For example, if `expr` represents the `.baz()` in `foo.bar().baz()`,\n/// `method_chain_args(expr, &[\"bar\", \"baz\"])` will return a `Vec`\n/// containing the `Expr`s for\n/// `.bar()` and `.baz()`\npub fn method_chain_args<'a>(expr: &'a Expr<'_>, methods: &[Symbol]) -> Option<Vec<(&'a Expr<'a>, &'a [Expr<'a>])>> {\n    let mut current = expr;\n    let mut matched = Vec::with_capacity(methods.len());\n    for method_name in methods.iter().rev() {\n        // method chains are stored last -> first\n        if let ExprKind::MethodCall(path, receiver, args, _) = current.kind {\n            if path.ident.name == *method_name {\n                if receiver.span.from_expansion() || args.iter().any(|e| e.span.from_expansion()) {\n                    return None;\n                }\n                matched.push((receiver, args)); // build up `matched` backwards\n                current = receiver; // go to parent expression\n            } else {\n                return None;\n            }\n        } else {\n            return None;\n        }\n    }\n    // Reverse `matched` so that it is in the same order as `methods`.\n    matched.reverse();\n    Some(matched)\n}\n\n/// Returns `true` if the provided `def_id` is an entrypoint to a program.\npub fn is_entrypoint_fn(cx: &LateContext<'_>, def_id: DefId) -> bool {\n    cx.tcx\n        .entry_fn(())\n        .is_some_and(|(entry_fn_def_id, _)| def_id == entry_fn_def_id)\n}\n\n/// Returns `true` if the expression is in the program's `#[panic_handler]`.\npub fn is_in_panic_handler(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    let parent = cx.tcx.hir_get_parent_item(e.hir_id);\n    Some(parent.to_def_id()) == cx.tcx.lang_items().panic_impl()\n}\n\n/// Gets the name of the item the expression is in, if available.\npub fn parent_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {\n    let parent_id = cx.tcx.hir_get_parent_item(expr.hir_id).def_id;\n    match cx.tcx.hir_node_by_def_id(parent_id) {\n        Node::Item(item) => item.kind.ident().map(|ident| ident.name),\n        Node::TraitItem(TraitItem { ident, .. }) | Node::ImplItem(ImplItem { ident, .. }) => Some(ident.name),\n        _ => None,\n    }\n}\n\npub struct ContainsName<'a, 'tcx> {\n    pub cx: &'a LateContext<'tcx>,\n    pub name: Symbol,\n}\n\nimpl<'tcx> Visitor<'tcx> for ContainsName<'_, 'tcx> {\n    type Result = ControlFlow<()>;\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_name(&mut self, name: Symbol) -> Self::Result {\n        if self.name == name {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\n/// Checks if an `Expr` contains a certain name.\npub fn contains_name<'tcx>(name: Symbol, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool {\n    let mut cn = ContainsName { cx, name };\n    cn.visit_expr(expr).is_break()\n}\n\n/// Returns `true` if `expr` contains a return expression\npub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool {\n    for_each_expr_without_closures(expr, |e| {\n        if matches!(e.kind, ExprKind::Ret(..)) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\n/// Gets the parent expression, if any –- this is useful to constrain a lint.\npub fn get_parent_expr<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {\n    get_parent_expr_for_hir(cx, e.hir_id)\n}\n\n/// This retrieves the parent for the given `HirId` if it's an expression. This is useful for\n/// constraint lints\npub fn get_parent_expr_for_hir<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {\n    match cx.tcx.parent_hir_node(hir_id) {\n        Node::Expr(parent) => Some(parent),\n        _ => None,\n    }\n}\n\n/// Gets the enclosing block, if any.\npub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Block<'tcx>> {\n    let enclosing_node = cx\n        .tcx\n        .hir_get_enclosing_scope(hir_id)\n        .map(|enclosing_id| cx.tcx.hir_node(enclosing_id));\n    enclosing_node.and_then(|node| match node {\n        Node::Block(block) => Some(block),\n        Node::Item(&Item {\n            kind: ItemKind::Fn { body: eid, .. },\n            ..\n        })\n        | Node::ImplItem(&ImplItem {\n            kind: ImplItemKind::Fn(_, eid),\n            ..\n        })\n        | Node::TraitItem(&TraitItem {\n            kind: TraitItemKind::Fn(_, TraitFn::Provided(eid)),\n            ..\n        }) => match cx.tcx.hir_body(eid).value.kind {\n            ExprKind::Block(block, _) => Some(block),\n            _ => None,\n        },\n        _ => None,\n    })\n}\n\n/// Returns the [`Closure`] enclosing `hir_id`, if any.\npub fn get_enclosing_closure<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Closure<'tcx>> {\n    cx.tcx.hir_parent_iter(hir_id).find_map(|(_, node)| {\n        if let Node::Expr(expr) = node\n            && let ExprKind::Closure(closure) = expr.kind\n        {\n            Some(closure)\n        } else {\n            None\n        }\n    })\n}\n\n/// Checks whether a local identified by `local_id` is captured as an upvar by the given `closure`.\npub fn is_upvar_in_closure(cx: &LateContext<'_>, closure: &Closure<'_>, local_id: HirId) -> bool {\n    cx.typeck_results()\n        .closure_min_captures\n        .get(&closure.def_id)\n        .is_some_and(|x| x.contains_key(&local_id))\n}\n\n/// Gets the loop or closure enclosing the given expression, if any.\npub fn get_enclosing_loop_or_multi_call_closure<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'_>,\n) -> Option<&'tcx Expr<'tcx>> {\n    for (_, node) in cx.tcx.hir_parent_iter(expr.hir_id) {\n        match node {\n            Node::Expr(e) => match e.kind {\n                ExprKind::Closure { .. }\n                    if let rustc_ty::Closure(_, subs) = cx.typeck_results().expr_ty(e).kind()\n                        && subs.as_closure().kind() == ClosureKind::FnOnce => {},\n\n                // Note: A closure's kind is determined by how it's used, not it's captures.\n                ExprKind::Closure { .. } | ExprKind::Loop(..) => return Some(e),\n                _ => (),\n            },\n            Node::Stmt(_) | Node::Block(_) | Node::LetStmt(_) | Node::Arm(_) | Node::ExprField(_) => (),\n            _ => break,\n        }\n    }\n    None\n}\n\n/// Gets the parent node if it's an impl block.\npub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> {\n    match tcx.hir_parent_iter(id).next() {\n        Some((\n            _,\n            Node::Item(Item {\n                kind: ItemKind::Impl(imp),\n                ..\n            }),\n        )) => Some(imp),\n        _ => None,\n    }\n}\n\n/// Removes blocks around an expression, only if the block contains just one expression\n/// and no statements. Unsafe blocks are not removed.\n///\n/// Examples:\n///  * `{}`               -> `{}`\n///  * `{ x }`            -> `x`\n///  * `{{ x }}`          -> `x`\n///  * `{ x; }`           -> `{ x; }`\n///  * `{ x; y }`         -> `{ x; y }`\n///  * `{ unsafe { x } }` -> `unsafe { x }`\npub fn peel_blocks<'a>(mut expr: &'a Expr<'a>) -> &'a Expr<'a> {\n    while let ExprKind::Block(\n        Block {\n            stmts: [],\n            expr: Some(inner),\n            rules: BlockCheckMode::DefaultBlock,\n            ..\n        },\n        _,\n    ) = expr.kind\n    {\n        expr = inner;\n    }\n    expr\n}\n\n/// Removes blocks around an expression, only if the block contains just one expression\n/// or just one expression statement with a semicolon. Unsafe blocks are not removed.\n///\n/// Examples:\n///  * `{}`               -> `{}`\n///  * `{ x }`            -> `x`\n///  * `{ x; }`           -> `x`\n///  * `{{ x; }}`         -> `x`\n///  * `{ x; y }`         -> `{ x; y }`\n///  * `{ unsafe { x } }` -> `unsafe { x }`\npub fn peel_blocks_with_stmt<'a>(mut expr: &'a Expr<'a>) -> &'a Expr<'a> {\n    while let ExprKind::Block(\n        Block {\n            stmts: [],\n            expr: Some(inner),\n            rules: BlockCheckMode::DefaultBlock,\n            ..\n        }\n        | Block {\n            stmts:\n                [\n                    Stmt {\n                        kind: StmtKind::Expr(inner) | StmtKind::Semi(inner),\n                        ..\n                    },\n                ],\n            expr: None,\n            rules: BlockCheckMode::DefaultBlock,\n            ..\n        },\n        _,\n    ) = expr.kind\n    {\n        expr = inner;\n    }\n    expr\n}\n\n/// Checks if the given expression is the else clause of either an `if` or `if let` expression.\npub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {\n    let mut iter = tcx.hir_parent_iter(expr.hir_id);\n    match iter.next() {\n        Some((\n            _,\n            Node::Expr(Expr {\n                kind: ExprKind::If(_, _, Some(else_expr)),\n                ..\n            }),\n        )) => else_expr.hir_id == expr.hir_id,\n        _ => false,\n    }\n}\n\n/// Checks if the given expression is a part of `let else`\n/// returns `true` for both the `init` and the `else` part\npub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {\n    let mut child_id = expr.hir_id;\n    for (parent_id, node) in tcx.hir_parent_iter(child_id) {\n        if let Node::LetStmt(LetStmt {\n            init: Some(init),\n            els: Some(els),\n            ..\n        }) = node\n            && (init.hir_id == child_id || els.hir_id == child_id)\n        {\n            return true;\n        }\n\n        child_id = parent_id;\n    }\n\n    false\n}\n\n/// Checks if the given expression is the else clause of a `let else` expression\npub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {\n    let mut child_id = expr.hir_id;\n    for (parent_id, node) in tcx.hir_parent_iter(child_id) {\n        if let Node::LetStmt(LetStmt { els: Some(els), .. }) = node\n            && els.hir_id == child_id\n        {\n            return true;\n        }\n\n        child_id = parent_id;\n    }\n\n    false\n}\n\n/// Checks whether the given `Expr` is a range equivalent to a `RangeFull`.\n///\n/// For the lower bound, this means that:\n/// - either there is none\n/// - or it is the smallest value that can be represented by the range's integer type\n///\n/// For the upper bound, this means that:\n/// - either there is none\n/// - or it is the largest value that can be represented by the range's integer type and is\n///   inclusive\n/// - or it is a call to some container's `len` method and is exclusive, and the range is passed to\n///   a method call on that same container (e.g. `v.drain(..v.len())`)\n///\n/// If the given `Expr` is not some kind of range, the function returns `false`.\npub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Option<&Path<'_>>) -> bool {\n    let ty = cx.typeck_results().expr_ty(expr);\n    if let Some(Range { start, end, limits, .. }) = Range::hir(cx, expr) {\n        let start_is_none_or_min = start.is_none_or(|start| {\n            if let rustc_ty::Adt(_, subst) = ty.kind()\n                && let bnd_ty = subst.type_at(0)\n                && let Some(start_const) = ConstEvalCtxt::new(cx).eval(start)\n            {\n                start_const.is_numeric_min(cx.tcx, bnd_ty)\n            } else {\n                false\n            }\n        });\n        let end_is_none_or_max = end.is_none_or(|end| match limits {\n            RangeLimits::Closed => {\n                if let rustc_ty::Adt(_, subst) = ty.kind()\n                    && let bnd_ty = subst.type_at(0)\n                    && let Some(end_const) = ConstEvalCtxt::new(cx).eval(end)\n                {\n                    end_const.is_numeric_max(cx.tcx, bnd_ty)\n                } else {\n                    false\n                }\n            },\n            RangeLimits::HalfOpen => {\n                if let Some(container_path) = container_path\n                    && let ExprKind::MethodCall(name, self_arg, [], _) = end.kind\n                    && name.ident.name == sym::len\n                    && let ExprKind::Path(QPath::Resolved(None, path)) = self_arg.kind\n                {\n                    container_path.res == path.res\n                } else {\n                    false\n                }\n            },\n        });\n        return start_is_none_or_min && end_is_none_or_max;\n    }\n    false\n}\n\n/// Checks whether the given expression is a constant integer of the given value.\n/// unlike `is_integer_literal`, this version does const folding\npub fn is_integer_const(cx: &LateContext<'_>, e: &Expr<'_>, value: u128) -> bool {\n    if is_integer_literal(e, value) {\n        return true;\n    }\n    let enclosing_body = cx.tcx.hir_enclosing_body_owner(e.hir_id);\n    if let Some(Constant::Int(v)) =\n        ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), cx.tcx.typeck(enclosing_body)).eval(e)\n    {\n        return value == v;\n    }\n    false\n}\n\n/// Checks whether the given expression is a constant literal of the given value.\npub fn is_integer_literal(expr: &Expr<'_>, value: u128) -> bool {\n    // FIXME: use constant folding\n    if let ExprKind::Lit(spanned) = expr.kind\n        && let LitKind::Int(v, _) = spanned.node\n    {\n        return v == value;\n    }\n    false\n}\n\n/// Checks whether the given expression is an untyped integer literal.\npub fn is_integer_literal_untyped(expr: &Expr<'_>) -> bool {\n    if let ExprKind::Lit(spanned) = expr.kind\n        && let LitKind::Int(_, suffix) = spanned.node\n    {\n        return suffix == LitIntType::Unsuffixed;\n    }\n\n    false\n}\n\n/// Checks whether the given expression is a constant literal of the given value.\npub fn is_float_literal(expr: &Expr<'_>, value: f64) -> bool {\n    if let ExprKind::Lit(spanned) = expr.kind\n        && let LitKind::Float(v, _) = spanned.node\n    {\n        v.as_str().parse() == Ok(value)\n    } else {\n        false\n    }\n}\n\n/// Returns `true` if the given `Expr` has been coerced before.\n///\n/// Examples of coercions can be found in the Nomicon at\n/// <https://doc.rust-lang.org/nomicon/coercions.html>.\n///\n/// See `rustc_middle::ty::adjustment::Adjustment` and `rustc_hir_analysis::check::coercion` for\n/// more information on adjustments and coercions.\npub fn is_adjusted(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {\n    cx.typeck_results().adjustments().get(e.hir_id).is_some()\n}\n\n/// Returns the pre-expansion span if this comes from an expansion of the\n/// macro `name`.\n/// See also [`is_direct_expn_of`].\n#[must_use]\npub fn is_expn_of(mut span: Span, name: Symbol) -> Option<Span> {\n    loop {\n        if span.from_expansion() {\n            let data = span.ctxt().outer_expn_data();\n            let new_span = data.call_site;\n\n            if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind\n                && mac_name == name\n            {\n                return Some(new_span);\n            }\n\n            span = new_span;\n        } else {\n            return None;\n        }\n    }\n}\n\n/// Returns the pre-expansion span if the span directly comes from an expansion\n/// of the macro `name`.\n/// The difference with [`is_expn_of`] is that in\n/// ```no_run\n/// # macro_rules! foo { ($name:tt!$args:tt) => { $name!$args } }\n/// # macro_rules! bar { ($e:expr) => { $e } }\n/// foo!(bar!(42));\n/// ```\n/// `42` is considered expanded from `foo!` and `bar!` by `is_expn_of` but only\n/// from `bar!` by `is_direct_expn_of`.\n#[must_use]\npub fn is_direct_expn_of(span: Span, name: Symbol) -> Option<Span> {\n    if span.from_expansion() {\n        let data = span.ctxt().outer_expn_data();\n        let new_span = data.call_site;\n\n        if let ExpnKind::Macro(MacroKind::Bang, mac_name) = data.kind\n            && mac_name == name\n        {\n            return Some(new_span);\n        }\n    }\n\n    None\n}\n\n/// Convenience function to get the return type of a function.\npub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId) -> Ty<'tcx> {\n    let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().output();\n    cx.tcx.instantiate_bound_regions_with_erased(ret_ty)\n}\n\n/// Convenience function to get the nth argument type of a function.\npub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId, nth: usize) -> Ty<'tcx> {\n    let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().input(nth);\n    cx.tcx.instantiate_bound_regions_with_erased(arg)\n}\n\n/// Checks if an expression is constructing a tuple-like enum variant or struct\npub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let ExprKind::Call(fun, _) = expr.kind\n        && let ExprKind::Path(ref qp) = fun.kind\n    {\n        let res = cx.qpath_res(qp, fun.hir_id);\n        return match res {\n            Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,\n            Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),\n            _ => false,\n        };\n    }\n    false\n}\n\n/// Returns `true` if a pattern is refutable.\n// TODO: should be implemented using rustc/mir_build/thir machinery\npub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {\n    fn is_qpath_refutable(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool {\n        !matches!(\n            cx.qpath_res(qpath, id),\n            Res::Def(DefKind::Struct, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Struct, _), _)\n        )\n    }\n\n    fn are_refutable<'a, I: IntoIterator<Item = &'a Pat<'a>>>(cx: &LateContext<'_>, i: I) -> bool {\n        i.into_iter().any(|pat| is_refutable(cx, pat))\n    }\n\n    match pat.kind {\n        PatKind::Missing => unreachable!(),\n        PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.\n        PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)),\n        PatKind::Box(pat) | PatKind::Ref(pat, _, _) => is_refutable(cx, pat),\n        PatKind::Expr(PatExpr {\n            kind: PatExprKind::Path(qpath),\n            hir_id,\n            ..\n        }) => is_qpath_refutable(cx, qpath, *hir_id),\n        PatKind::Or(pats) => {\n            // TODO: should be the honest check, that pats is exhaustive set\n            are_refutable(cx, pats)\n        },\n        PatKind::Tuple(pats, _) => are_refutable(cx, pats),\n        PatKind::Struct(ref qpath, fields, _) => {\n            is_qpath_refutable(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| field.pat))\n        },\n        PatKind::TupleStruct(ref qpath, pats, _) => {\n            is_qpath_refutable(cx, qpath, pat.hir_id) || are_refutable(cx, pats)\n        },\n        PatKind::Slice(head, middle, tail) => {\n            match &cx.typeck_results().node_type(pat.hir_id).kind() {\n                rustc_ty::Slice(..) => {\n                    // [..] is the only irrefutable slice pattern.\n                    !head.is_empty() || middle.is_none() || !tail.is_empty()\n                },\n                rustc_ty::Array(..) => are_refutable(cx, head.iter().chain(middle).chain(tail.iter())),\n                _ => {\n                    // unreachable!()\n                    true\n                },\n            }\n        },\n        PatKind::Expr(..) | PatKind::Range(..) | PatKind::Err(_) | PatKind::Deref(_) | PatKind::Guard(..) => true,\n    }\n}\n\n/// If the pattern is an `or` pattern, call the function once for each sub pattern. Otherwise, call\n/// the function once on the given pattern.\npub fn recurse_or_patterns<'tcx, F: FnMut(&'tcx Pat<'tcx>)>(pat: &'tcx Pat<'tcx>, mut f: F) {\n    if let PatKind::Or(pats) = pat.kind {\n        pats.iter().for_each(f);\n    } else {\n        f(pat);\n    }\n}\n\npub fn is_self(slf: &Param<'_>) -> bool {\n    if let PatKind::Binding(.., name, _) = slf.pat.kind {\n        name.name == kw::SelfLower\n    } else {\n        false\n    }\n}\n\npub fn is_self_ty(slf: &hir::Ty<'_>) -> bool {\n    if let TyKind::Path(QPath::Resolved(None, path)) = slf.kind\n        && let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path.res\n    {\n        return true;\n    }\n    false\n}\n\npub fn iter_input_pats<'tcx>(decl: &FnDecl<'_>, body: &'tcx Body<'_>) -> impl Iterator<Item = &'tcx Param<'tcx>> {\n    (0..decl.inputs.len()).map(move |i| &body.params[i])\n}\n\n/// Checks if a given expression is a match expression expanded from the `?`\n/// operator or the `try` macro.\npub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {\n    fn is_ok(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {\n        if let PatKind::TupleStruct(ref path, pat, ddpos) = arm.pat.kind\n            && ddpos.as_opt_usize().is_none()\n            && cx\n                .qpath_res(path, arm.pat.hir_id)\n                .ctor_parent(cx)\n                .is_lang_item(cx, ResultOk)\n            && let PatKind::Binding(_, hir_id, _, None) = pat[0].kind\n            && arm.body.res_local_id() == Some(hir_id)\n        {\n            return true;\n        }\n        false\n    }\n\n    fn is_err(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {\n        if let PatKind::TupleStruct(ref path, _, _) = arm.pat.kind {\n            cx.qpath_res(path, arm.pat.hir_id)\n                .ctor_parent(cx)\n                .is_lang_item(cx, ResultErr)\n        } else {\n            false\n        }\n    }\n\n    if let ExprKind::Match(_, arms, ref source) = expr.kind {\n        // desugared from a `?` operator\n        if let MatchSource::TryDesugar(_) = *source {\n            return Some(expr);\n        }\n\n        if arms.len() == 2\n            && arms[0].guard.is_none()\n            && arms[1].guard.is_none()\n            && ((is_ok(cx, &arms[0]) && is_err(cx, &arms[1])) || (is_ok(cx, &arms[1]) && is_err(cx, &arms[0])))\n        {\n            return Some(expr);\n        }\n    }\n\n    None\n}\n\n/// Returns `true` if the lint is `#[allow]`ed or `#[expect]`ed at any of the `ids`, fulfilling all\n/// of the expectations in `ids`\n///\n/// This should only be used when the lint would otherwise be emitted, for a way to check if a lint\n/// is allowed early to skip work see [`is_lint_allowed`]\n///\n/// To emit at a lint at a different context than the one current see\n/// [`span_lint_hir`](diagnostics::span_lint_hir) or\n/// [`span_lint_hir_and_then`](diagnostics::span_lint_hir_and_then)\npub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl IntoIterator<Item = HirId>) -> bool {\n    let mut suppress_lint = false;\n\n    for id in ids {\n        let LevelAndSource { level, lint_id, .. } = cx.tcx.lint_level_at_node(lint, id);\n        if let Some(expectation) = lint_id {\n            cx.fulfill_expectation(expectation);\n        }\n\n        match level {\n            Level::Allow | Level::Expect => suppress_lint = true,\n            Level::Warn | Level::ForceWarn | Level::Deny | Level::Forbid => {},\n        }\n    }\n\n    suppress_lint\n}\n\n/// Returns `true` if the lint is allowed in the current context. This is useful for\n/// skipping long running code when it's unnecessary\n///\n/// This function should check the lint level for the same node, that the lint will\n/// be emitted at. If the information is buffered to be emitted at a later point, please\n/// make sure to use `span_lint_hir` functions to emit the lint. This ensures that\n/// expectations at the checked nodes will be fulfilled.\npub fn is_lint_allowed(cx: &LateContext<'_>, lint: &'static Lint, id: HirId) -> bool {\n    cx.tcx.lint_level_at_node(lint, id).level == Level::Allow\n}\n\npub fn strip_pat_refs<'hir>(mut pat: &'hir Pat<'hir>) -> &'hir Pat<'hir> {\n    while let PatKind::Ref(subpat, _, _) = pat.kind {\n        pat = subpat;\n    }\n    pat\n}\n\npub fn int_bits(tcx: TyCtxt<'_>, ity: IntTy) -> u64 {\n    Integer::from_int_ty(&tcx, ity).size().bits()\n}\n\n#[expect(clippy::cast_possible_wrap)]\n/// Turn a constant int byte representation into an i128\npub fn sext(tcx: TyCtxt<'_>, u: u128, ity: IntTy) -> i128 {\n    let amt = 128 - int_bits(tcx, ity);\n    ((u as i128) << amt) >> amt\n}\n\n#[expect(clippy::cast_sign_loss)]\n/// clip unused bytes\npub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: IntTy) -> u128 {\n    let amt = 128 - int_bits(tcx, ity);\n    ((u as u128) << amt) >> amt\n}\n\n/// clip unused bytes\npub fn clip(tcx: TyCtxt<'_>, u: u128, ity: UintTy) -> u128 {\n    let bits = Integer::from_uint_ty(&tcx, ity).size().bits();\n    let amt = 128 - bits;\n    (u << amt) >> amt\n}\n\npub fn has_attr(attrs: &[hir::Attribute], symbol: Symbol) -> bool {\n    attrs.iter().any(|attr| attr.has_name(symbol))\n}\n\npub fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {\n    find_attr!(cx.tcx.hir_attrs(hir_id), Repr { .. })\n}\n\npub fn any_parent_has_attr(tcx: TyCtxt<'_>, node: HirId, symbol: Symbol) -> bool {\n    let mut prev_enclosing_node = None;\n    let mut enclosing_node = node;\n    while Some(enclosing_node) != prev_enclosing_node {\n        if has_attr(tcx.hir_attrs(enclosing_node), symbol) {\n            return true;\n        }\n        prev_enclosing_node = Some(enclosing_node);\n        enclosing_node = tcx.hir_get_parent_item(enclosing_node).into();\n    }\n\n    false\n}\n\n/// Checks if the given HIR node is inside an `impl` block with the `automatically_derived`\n/// attribute.\npub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool {\n    tcx.hir_parent_owner_iter(id)\n        .filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_))))\n        .any(|(id, _)| {\n            find_attr!(\n                tcx.hir_attrs(tcx.local_def_id_to_hir_id(id.def_id)),\n                AutomaticallyDerived(..)\n            )\n        })\n}\n\n/// Checks if the given `DefId` matches the `libc` item.\npub fn match_libc_symbol(cx: &LateContext<'_>, did: DefId, name: Symbol) -> bool {\n    // libc is meant to be used as a flat list of names, but they're all actually defined in different\n    // modules based on the target platform. Ignore everything but crate name and the item name.\n    cx.tcx.crate_name(did.krate) == sym::libc && cx.tcx.def_path_str(did).ends_with(name.as_str())\n}\n\n/// Returns the list of condition expressions and the list of blocks in a\n/// sequence of `if/else`.\n/// E.g., this returns `([a, b], [c, d, e])` for the expression\n/// `if a { c } else if b { d } else { e }`.\npub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>, Vec<&'tcx Block<'tcx>>) {\n    let mut conds = Vec::new();\n    let mut blocks: Vec<&Block<'_>> = Vec::new();\n\n    while let Some(higher::IfOrIfLet { cond, then, r#else }) = higher::IfOrIfLet::hir(expr) {\n        conds.push(cond);\n        if let ExprKind::Block(block, _) = then.kind {\n            blocks.push(block);\n        } else {\n            panic!(\"ExprKind::If node is not an ExprKind::Block\");\n        }\n\n        if let Some(else_expr) = r#else {\n            expr = else_expr;\n        } else {\n            break;\n        }\n    }\n\n    // final `else {..}`\n    if !blocks.is_empty()\n        && let ExprKind::Block(block, _) = expr.kind\n    {\n        blocks.push(block);\n    }\n\n    (conds, blocks)\n}\n\n/// Peels away all the compiler generated code surrounding the body of an async closure.\npub fn get_async_closure_expr<'tcx>(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {\n    if let ExprKind::Closure(&Closure {\n        body,\n        kind: hir::ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)),\n        ..\n    }) = expr.kind\n        && let ExprKind::Block(\n            Block {\n                expr:\n                    Some(Expr {\n                        kind: ExprKind::DropTemps(inner_expr),\n                        ..\n                    }),\n                ..\n            },\n            _,\n        ) = tcx.hir_body(body).value.kind\n    {\n        Some(inner_expr)\n    } else {\n        None\n    }\n}\n\n/// Peels away all the compiler generated code surrounding the body of an async function,\npub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'tcx Expr<'tcx>> {\n    get_async_closure_expr(tcx, body.value)\n}\n\n// check if expr is calling method or function with #[must_use] attribute\npub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let did = match expr.kind {\n        ExprKind::Call(path, _) => {\n            if let ExprKind::Path(ref qpath) = path.kind\n                && let Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id)\n            {\n                Some(did)\n            } else {\n                None\n            }\n        },\n        ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id),\n        _ => None,\n    };\n\n    did.is_some_and(|did| find_attr!(cx.tcx, did, MustUse { .. }))\n}\n\n/// Checks if a function's body represents the identity function. Looks for bodies of the form:\n/// * `|x| x`\n/// * `|x| return x`\n/// * `|x| { return x }`\n/// * `|x| { return x; }`\n/// * `|(x, y)| (x, y)`\n/// * `|[x, y]| [x, y]`\n/// * `|Foo(bar, baz)| Foo(bar, baz)`\n/// * `|Foo { bar, baz }| Foo { bar, baz }`\n/// * `|x| { let y = x; ...; let z = y; z }`\n/// * `|x| { let y = x; ...; let z = y; return z }`\n///\n/// Consider calling [`is_expr_untyped_identity_function`] or [`is_expr_identity_function`] instead.\nfn is_body_identity_function<'hir>(cx: &LateContext<'_>, func: &Body<'hir>) -> bool {\n    let [param] = func.params else {\n        return false;\n    };\n\n    let mut param_pat = param.pat;\n\n    // Given a sequence of `Stmt`s of the form `let p = e` where `e` is an expr identical to the\n    // current `param_pat`, advance the current `param_pat` to `p`.\n    //\n    // Note: This is similar to `clippy_utils::get_last_chain_binding_hir_id`, but it works\n    // directly over a `Pattern` rather than a `HirId`. And it checks for compatibility via\n    // `is_expr_identity_of_pat` rather than `HirId` equality\n    let mut advance_param_pat_over_stmts = |stmts: &[Stmt<'hir>]| {\n        for stmt in stmts {\n            if let StmtKind::Let(local) = stmt.kind\n                && let Some(init) = local.init\n                && is_expr_identity_of_pat(cx, param_pat, init, true)\n            {\n                param_pat = local.pat;\n            } else {\n                return false;\n            }\n        }\n\n        true\n    };\n\n    let mut expr = func.value;\n    loop {\n        match expr.kind {\n            ExprKind::Block(\n                &Block {\n                    stmts: [],\n                    expr: Some(e),\n                    ..\n                },\n                _,\n            )\n            | ExprKind::Ret(Some(e)) => expr = e,\n            ExprKind::Block(\n                &Block {\n                    stmts: [stmt],\n                    expr: None,\n                    ..\n                },\n                _,\n            ) => {\n                if let StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind\n                    && let ExprKind::Ret(Some(ret_val)) = e.kind\n                {\n                    expr = ret_val;\n                } else {\n                    return false;\n                }\n            },\n            ExprKind::Block(\n                &Block {\n                    stmts, expr: Some(e), ..\n                },\n                _,\n            ) => {\n                if !advance_param_pat_over_stmts(stmts) {\n                    return false;\n                }\n\n                expr = e;\n            },\n            ExprKind::Block(&Block { stmts, expr: None, .. }, _) => {\n                if let Some((last_stmt, stmts)) = stmts.split_last()\n                    && advance_param_pat_over_stmts(stmts)\n                    && let StmtKind::Semi(e) | StmtKind::Expr(e) = last_stmt.kind\n                    && let ExprKind::Ret(Some(ret_val)) = e.kind\n                {\n                    expr = ret_val;\n                } else {\n                    return false;\n                }\n            },\n            _ => return is_expr_identity_of_pat(cx, param_pat, expr, true),\n        }\n    }\n}\n\n/// Checks if the given expression is an identity representation of the given pattern:\n/// * `x` is the identity representation of `x`\n/// * `(x, y)` is the identity representation of `(x, y)`\n/// * `[x, y]` is the identity representation of `[x, y]`\n/// * `Foo(bar, baz)` is the identity representation of `Foo(bar, baz)`\n/// * `Foo { bar, baz }` is the identity representation of `Foo { bar, baz }`\n///\n/// Note that `by_hir` is used to determine bindings are checked by their `HirId` or by their name.\n/// This can be useful when checking patterns in `let` bindings or `match` arms.\npub fn is_expr_identity_of_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>, by_hir: bool) -> bool {\n    if cx\n        .typeck_results()\n        .pat_binding_modes()\n        .get(pat.hir_id)\n        .is_some_and(|mode| matches!(mode.0, ByRef::Yes(..)))\n    {\n        // If the parameter is `(x, y)` of type `&(T, T)`, or `[x, y]` of type `&[T; 2]`, then\n        // due to match ergonomics, the inner patterns become references. Don't consider this\n        // the identity function as that changes types.\n        return false;\n    }\n\n    // NOTE: we're inside a (function) body, so this won't ICE\n    let qpath_res = |qpath, hir| cx.typeck_results().qpath_res(qpath, hir);\n\n    match (pat.kind, expr.kind) {\n        (PatKind::Binding(_, id, _, _), _) if by_hir => {\n            expr.res_local_id() == Some(id) && cx.typeck_results().expr_adjustments(expr).is_empty()\n        },\n        (PatKind::Binding(_, _, ident, _), ExprKind::Path(QPath::Resolved(_, path))) => {\n            matches!(path.segments, [ segment] if segment.ident.name == ident.name)\n        },\n        (PatKind::Tuple(pats, dotdot), ExprKind::Tup(tup))\n            if dotdot.as_opt_usize().is_none() && pats.len() == tup.len() =>\n        {\n            over(pats, tup, |pat, expr| is_expr_identity_of_pat(cx, pat, expr, by_hir))\n        },\n        (PatKind::Slice(before, None, after), ExprKind::Array(arr)) if before.len() + after.len() == arr.len() => {\n            zip(before.iter().chain(after), arr).all(|(pat, expr)| is_expr_identity_of_pat(cx, pat, expr, by_hir))\n        },\n        (PatKind::TupleStruct(pat_ident, field_pats, dotdot), ExprKind::Call(ident, fields))\n            if dotdot.as_opt_usize().is_none() && field_pats.len() == fields.len() =>\n        {\n            // check ident\n            if let ExprKind::Path(ident) = &ident.kind\n                && qpath_res(&pat_ident, pat.hir_id) == qpath_res(ident, expr.hir_id)\n                // check fields\n                && over(field_pats, fields, |pat, expr| is_expr_identity_of_pat(cx, pat, expr,by_hir))\n            {\n                true\n            } else {\n                false\n            }\n        },\n        (PatKind::Struct(pat_ident, field_pats, None), ExprKind::Struct(ident, fields, hir::StructTailExpr::None))\n            if field_pats.len() == fields.len() =>\n        {\n            // check ident\n            qpath_res(&pat_ident, pat.hir_id) == qpath_res(ident, expr.hir_id)\n                // check fields\n                && unordered_over(field_pats, fields, |field_pat, field| {\n                    field_pat.ident == field.ident && is_expr_identity_of_pat(cx, field_pat.pat, field.expr, by_hir)\n                })\n        },\n        _ => false,\n    }\n}\n\n/// This is the same as [`is_expr_identity_function`], but does not consider closures\n/// with type annotations for its bindings (or similar) as identity functions:\n/// * `|x: u8| x`\n/// * `std::convert::identity::<u8>`\npub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Closure(&Closure { body, fn_decl, .. })\n            if fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer(()))) =>\n        {\n            is_body_identity_function(cx, cx.tcx.hir_body(body))\n        },\n        ExprKind::Path(QPath::Resolved(_, path))\n            if path.segments.iter().all(|seg| seg.infer_args)\n                && let Some(did) = path.res.opt_def_id() =>\n        {\n            cx.tcx.is_diagnostic_item(sym::convert_identity, did)\n        },\n        _ => false,\n    }\n}\n\n/// Checks if an expression represents the identity function\n/// Only examines closures and `std::convert::identity`\n///\n/// NOTE: If you want to use this function to find out if a closure is unnecessary, you likely want\n/// to call [`is_expr_untyped_identity_function`] instead, which makes sure that the closure doesn't\n/// have type annotations. This is important because removing a closure with bindings can\n/// remove type information that helped type inference before, which can then lead to compile\n/// errors.\npub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    match expr.kind {\n        ExprKind::Closure(&Closure { body, .. }) => is_body_identity_function(cx, cx.tcx.hir_body(body)),\n        _ => expr.basic_res().is_diag_item(cx, sym::convert_identity),\n    }\n}\n\n/// Gets the node where an expression is either used, or it's type is unified with another branch.\n/// Returns both the node and the `HirId` of the closest child node.\npub fn get_expr_use_or_unification_node<'tcx>(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<(Node<'tcx>, HirId)> {\n    let mut child_id = expr.hir_id;\n    let mut iter = tcx.hir_parent_iter(child_id);\n    loop {\n        match iter.next() {\n            None => break None,\n            Some((id, Node::Block(_))) => child_id = id,\n            Some((id, Node::Arm(arm))) if arm.body.hir_id == child_id => child_id = id,\n            Some((_, Node::Expr(expr))) => match expr.kind {\n                ExprKind::Match(_, [arm], _) if arm.hir_id == child_id => child_id = expr.hir_id,\n                ExprKind::Block(..) | ExprKind::DropTemps(_) => child_id = expr.hir_id,\n                ExprKind::If(_, then_expr, None) if then_expr.hir_id == child_id => break None,\n                _ => break Some((Node::Expr(expr), child_id)),\n            },\n            Some((_, node)) => break Some((node, child_id)),\n        }\n    }\n}\n\n/// Checks if the result of an expression is used, or it's type is unified with another branch.\npub fn is_expr_used_or_unified(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {\n    !matches!(\n        get_expr_use_or_unification_node(tcx, expr),\n        None | Some((\n            Node::Stmt(Stmt {\n                kind: StmtKind::Expr(_)\n                    | StmtKind::Semi(_)\n                    | StmtKind::Let(LetStmt {\n                        pat: Pat {\n                            kind: PatKind::Wild,\n                            ..\n                        },\n                        ..\n                    }),\n                ..\n            }),\n            _\n        ))\n    )\n}\n\n/// Checks if the expression is the final expression returned from a block.\npub fn is_expr_final_block_expr(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {\n    matches!(tcx.parent_hir_node(expr.hir_id), Node::Block(..))\n}\n\n/// Checks if the expression is a temporary value.\n// This logic is the same as the one used in rustc's `check_named_place_expr function`.\n// https://github.com/rust-lang/rust/blob/3ed2a10d173d6c2e0232776af338ca7d080b1cd4/compiler/rustc_hir_typeck/src/expr.rs#L482-L499\npub fn is_expr_temporary_value(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    !expr.is_place_expr(|base| {\n        cx.typeck_results()\n            .adjustments()\n            .get(base.hir_id)\n            .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))\n    })\n}\n\npub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {\n    if is_no_core_crate(cx) {\n        None\n    } else if is_no_std_crate(cx) {\n        Some(\"core\")\n    } else {\n        Some(\"std\")\n    }\n}\n\npub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {\n    find_attr!(cx.tcx, crate, NoStd(..))\n}\n\npub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {\n    find_attr!(cx.tcx, crate, NoCore(..))\n}\n\n/// Check if parent of a hir node is a trait implementation block.\n/// For example, `f` in\n/// ```no_run\n/// # struct S;\n/// # trait Trait { fn f(); }\n/// impl Trait for S {\n///     fn f() {}\n/// }\n/// ```\npub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {\n    if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) {\n        matches!(item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }))\n    } else {\n        false\n    }\n}\n\n/// Check if it's even possible to satisfy the `where` clause for the item.\n///\n/// `trivial_bounds` feature allows functions with unsatisfiable bounds, for example:\n///\n/// ```ignore\n/// fn foo() where i32: Iterator {\n///     for _ in 2i32 {}\n/// }\n/// ```\npub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool {\n    use rustc_trait_selection::traits;\n    let predicates = cx\n        .tcx\n        .predicates_of(did)\n        .predicates\n        .iter()\n        .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None });\n    traits::impossible_predicates(cx.tcx, traits::elaborate(cx.tcx, predicates).collect::<Vec<_>>())\n}\n\n/// Returns the `DefId` of the callee if the given expression is a function or method call.\npub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {\n    fn_def_id_with_node_args(cx, expr).map(|(did, _)| did)\n}\n\n/// Returns the `DefId` of the callee if the given expression is a function or method call,\n/// as well as its node args.\npub fn fn_def_id_with_node_args<'tcx>(\n    cx: &LateContext<'tcx>,\n    expr: &Expr<'_>,\n) -> Option<(DefId, GenericArgsRef<'tcx>)> {\n    let typeck = cx.typeck_results();\n    match &expr.kind {\n        ExprKind::MethodCall(..) => Some((\n            typeck.type_dependent_def_id(expr.hir_id)?,\n            typeck.node_args(expr.hir_id),\n        )),\n        ExprKind::Call(\n            Expr {\n                kind: ExprKind::Path(qpath),\n                hir_id: path_hir_id,\n                ..\n            },\n            ..,\n        ) => {\n            // Only return Fn-like DefIds, not the DefIds of statics/consts/etc that contain or\n            // deref to fn pointers, dyn Fn, impl Fn - #8850\n            if let Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) =\n                typeck.qpath_res(qpath, *path_hir_id)\n            {\n                Some((id, typeck.node_args(*path_hir_id)))\n            } else {\n                None\n            }\n        },\n        _ => None,\n    }\n}\n\n/// Returns `Option<String>` where String is a textual representation of the type encapsulated in\n/// the slice iff the given expression is a slice of primitives.\n///\n/// (As defined in the `is_recursively_primitive_type` function.) Returns `None` otherwise.\npub fn is_slice_of_primitives(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {\n    let expr_type = cx.typeck_results().expr_ty_adjusted(expr);\n    let expr_kind = expr_type.kind();\n    let is_primitive = match expr_kind {\n        rustc_ty::Slice(element_type) => is_recursively_primitive_type(*element_type),\n        rustc_ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), &rustc_ty::Slice(_)) => {\n            if let rustc_ty::Slice(element_type) = inner_ty.kind() {\n                is_recursively_primitive_type(*element_type)\n            } else {\n                unreachable!()\n            }\n        },\n        _ => false,\n    };\n\n    if is_primitive {\n        // if we have wrappers like Array, Slice or Tuple, print these\n        // and get the type enclosed in the slice ref\n        match expr_type.peel_refs().walk().nth(1).unwrap().expect_ty().kind() {\n            rustc_ty::Slice(..) => return Some(\"slice\".into()),\n            rustc_ty::Array(..) => return Some(\"array\".into()),\n            rustc_ty::Tuple(..) => return Some(\"tuple\".into()),\n            _ => {\n                // is_recursively_primitive_type() should have taken care\n                // of the rest and we can rely on the type that is found\n                let refs_peeled = expr_type.peel_refs();\n                return Some(refs_peeled.walk().last().unwrap().to_string());\n            },\n        }\n    }\n    None\n}\n\n/// Returns a list of groups where elements in each group are equal according to `eq`\n///\n/// - Within each group the elements are sorted by the order they appear in `exprs`\n/// - The groups themselves are sorted by their first element's appearence in `exprs`\n///\n/// Given functions `eq` and `hash` such that `eq(a, b) == true`\n/// implies `hash(a) == hash(b)`\npub fn search_same<T, Hash, Eq>(exprs: &[T], mut hash: Hash, mut eq: Eq) -> Vec<Vec<&T>>\nwhere\n    Hash: FnMut(&T) -> u64,\n    Eq: FnMut(&T, &T) -> bool,\n{\n    match exprs {\n        [a, b] if eq(a, b) => return vec![vec![a, b]],\n        _ if exprs.len() <= 2 => return vec![],\n        _ => {},\n    }\n\n    let mut buckets: UnindexMap<u64, Vec<Vec<&T>>> = UnindexMap::default();\n\n    for expr in exprs {\n        match buckets.entry(hash(expr)) {\n            indexmap::map::Entry::Occupied(mut o) => {\n                let bucket = o.get_mut();\n                match bucket.iter_mut().find(|group| eq(expr, group[0])) {\n                    Some(group) => group.push(expr),\n                    None => bucket.push(vec![expr]),\n                }\n            },\n            indexmap::map::Entry::Vacant(v) => {\n                v.insert(vec![vec![expr]]);\n            },\n        }\n    }\n\n    buckets\n        .into_values()\n        .flatten()\n        .filter(|group| group.len() > 1)\n        .collect()\n}\n\n/// Peels off all references on the pattern. Returns the underlying pattern and the number of\n/// references removed.\npub fn peel_hir_pat_refs<'a>(pat: &'a Pat<'a>) -> (&'a Pat<'a>, usize) {\n    fn peel<'a>(pat: &'a Pat<'a>, count: usize) -> (&'a Pat<'a>, usize) {\n        if let PatKind::Ref(pat, _, _) = pat.kind {\n            peel(pat, count + 1)\n        } else {\n            (pat, count)\n        }\n    }\n    peel(pat, 0)\n}\n\n/// Peels of expressions while the given closure returns `Some`.\npub fn peel_hir_expr_while<'tcx>(\n    mut expr: &'tcx Expr<'tcx>,\n    mut f: impl FnMut(&'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>>,\n) -> &'tcx Expr<'tcx> {\n    while let Some(e) = f(expr) {\n        expr = e;\n    }\n    expr\n}\n\n/// Peels off up to the given number of references on the expression. Returns the underlying\n/// expression and the number of references removed.\npub fn peel_n_hir_expr_refs<'a>(expr: &'a Expr<'a>, count: usize) -> (&'a Expr<'a>, usize) {\n    let mut remaining = count;\n    let e = peel_hir_expr_while(expr, |e| match e.kind {\n        ExprKind::AddrOf(ast::BorrowKind::Ref, _, e) if remaining != 0 => {\n            remaining -= 1;\n            Some(e)\n        },\n        _ => None,\n    });\n    (e, count - remaining)\n}\n\n/// Peels off all unary operators of an expression. Returns the underlying expression and the number\n/// of operators removed.\npub fn peel_hir_expr_unary<'a>(expr: &'a Expr<'a>) -> (&'a Expr<'a>, usize) {\n    let mut count: usize = 0;\n    let mut curr_expr = expr;\n    while let ExprKind::Unary(_, local_expr) = curr_expr.kind {\n        count = count.wrapping_add(1);\n        curr_expr = local_expr;\n    }\n    (curr_expr, count)\n}\n\n/// Peels off all references on the expression. Returns the underlying expression and the number of\n/// references removed.\npub fn peel_hir_expr_refs<'a>(expr: &'a Expr<'a>) -> (&'a Expr<'a>, usize) {\n    let mut count = 0;\n    let e = peel_hir_expr_while(expr, |e| match e.kind {\n        ExprKind::AddrOf(ast::BorrowKind::Ref, _, e) => {\n            count += 1;\n            Some(e)\n        },\n        _ => None,\n    });\n    (e, count)\n}\n\n/// Peels off all references on the type. Returns the underlying type and the number of references\n/// removed.\npub fn peel_hir_ty_refs<'a>(mut ty: &'a hir::Ty<'a>) -> (&'a hir::Ty<'a>, usize) {\n    let mut count = 0;\n    loop {\n        match &ty.kind {\n            TyKind::Ref(_, ref_ty) => {\n                ty = ref_ty.ty;\n                count += 1;\n            },\n            _ => break (ty, count),\n        }\n    }\n}\n\n/// Returns the base type for HIR references and pointers.\npub fn peel_hir_ty_refs_and_ptrs<'tcx>(ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {\n    match &ty.kind {\n        TyKind::Ptr(mut_ty) | TyKind::Ref(_, mut_ty) => peel_hir_ty_refs_and_ptrs(mut_ty.ty),\n        _ => ty,\n    }\n}\n\n/// Removes `AddrOf` operators (`&`) or deref operators (`*`), but only if a reference type is\n/// dereferenced. An overloaded deref such as `Vec` to slice would not be removed.\npub fn peel_ref_operators<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -> &'hir Expr<'hir> {\n    loop {\n        match expr.kind {\n            ExprKind::AddrOf(_, _, e) => expr = e,\n            ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty(e).is_ref() => expr = e,\n            _ => break,\n        }\n    }\n    expr\n}\n\n/// Returns a `Vec` of `Expr`s containing `AddrOf` operators (`&`) or deref operators (`*`) of a\n/// given expression.\npub fn get_ref_operators<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>) -> Vec<&'hir Expr<'hir>> {\n    let mut operators = Vec::new();\n    peel_hir_expr_while(expr, |expr| match expr.kind {\n        ExprKind::AddrOf(_, _, e) => {\n            operators.push(expr);\n            Some(e)\n        },\n        ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty(e).is_ref() => {\n            operators.push(expr);\n            Some(e)\n        },\n        _ => None,\n    });\n    operators\n}\n\npub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {\n    if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind\n        && let Res::Def(_, def_id) = path.res\n    {\n        #[allow(deprecated)]\n        return cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr);\n    }\n    false\n}\n\nstatic TEST_ITEM_NAMES_CACHE: OnceLock<Mutex<FxHashMap<LocalModDefId, Vec<Symbol>>>> = OnceLock::new();\n\n/// Apply `f()` to the set of test item names.\n/// The names are sorted using the default `Symbol` ordering.\nfn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl FnOnce(&[Symbol]) -> bool) -> bool {\n    let cache = TEST_ITEM_NAMES_CACHE.get_or_init(|| Mutex::new(FxHashMap::default()));\n    let mut map: MutexGuard<'_, FxHashMap<LocalModDefId, Vec<Symbol>>> = cache.lock().unwrap();\n    let value = map.entry(module);\n    match value {\n        Entry::Occupied(entry) => f(entry.get()),\n        Entry::Vacant(entry) => {\n            let mut names = Vec::new();\n            for id in tcx.hir_module_free_items(module) {\n                if matches!(tcx.def_kind(id.owner_id), DefKind::Const { .. })\n                    && let item = tcx.hir_item(id)\n                    && let ItemKind::Const(ident, _generics, ty, _body) = item.kind\n                    && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind\n                    // We could also check for the type name `test::TestDescAndFn`\n                    && let Res::Def(DefKind::Struct, _) = path.res\n                    && find_attr!(tcx.hir_attrs(item.hir_id()), RustcTestMarker(..))\n                {\n                    names.push(ident.name);\n                }\n            }\n            names.sort_unstable();\n            f(entry.insert(names))\n        },\n    }\n}\n\n/// Checks if the function containing the given `HirId` is a `#[test]` function\n///\n/// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function\npub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool {\n    with_test_item_names(tcx, tcx.parent_module(id), |names| {\n        let node = tcx.hir_node(id);\n        once((id, node))\n            .chain(tcx.hir_parent_iter(id))\n            // Since you can nest functions we need to collect all until we leave\n            // function scope\n            .any(|(_id, node)| {\n                if let Node::Item(item) = node\n                    && let ItemKind::Fn { ident, .. } = item.kind\n                {\n                    // Note that we have sorted the item names in the visitor,\n                    // so the binary_search gets the same as `contains`, but faster.\n                    return names.binary_search(&ident.name).is_ok();\n                }\n                false\n            })\n    })\n}\n\n/// Checks if `fn_def_id` has a `#[test]` attribute applied\n///\n/// This only checks directly applied attributes. To see if a node has a parent function marked with\n/// `#[test]` use [`is_in_test_function`].\n///\n/// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function\npub fn is_test_function(tcx: TyCtxt<'_>, fn_def_id: LocalDefId) -> bool {\n    let id = tcx.local_def_id_to_hir_id(fn_def_id);\n    if let Node::Item(item) = tcx.hir_node(id)\n        && let ItemKind::Fn { ident, .. } = item.kind\n    {\n        with_test_item_names(tcx, tcx.parent_module(id), |names| {\n            names.binary_search(&ident.name).is_ok()\n        })\n    } else {\n        false\n    }\n}\n\n/// Checks if `id` has a `#[cfg(test)]` attribute applied\n///\n/// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent\n/// use [`is_in_cfg_test`]\npub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {\n    if let Some(cfgs) = find_attr!(tcx.hir_attrs(id), CfgTrace(cfgs) => cfgs)\n        && cfgs\n            .iter()\n            .any(|(cfg, _)| matches!(cfg, CfgEntry::NameValue { name: sym::test, .. }))\n    {\n        true\n    } else {\n        false\n    }\n}\n\n/// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied\npub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {\n    tcx.hir_parent_id_iter(id).any(|parent_id| is_cfg_test(tcx, parent_id))\n}\n\n/// Checks if the node is in a `#[test]` function or has any parent node marked `#[cfg(test)]`\npub fn is_in_test(tcx: TyCtxt<'_>, hir_id: HirId) -> bool {\n    is_in_test_function(tcx, hir_id) || is_in_cfg_test(tcx, hir_id)\n}\n\n/// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied.\npub fn inherits_cfg(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {\n    find_attr!(tcx, def_id, CfgTrace(..))\n        || find_attr!(\n            tcx.hir_parent_iter(tcx.local_def_id_to_hir_id(def_id))\n                .flat_map(|(parent_id, _)| tcx.hir_attrs(parent_id)),\n            CfgTrace(..)\n        )\n}\n\n/// Walks up the HIR tree from the given expression in an attempt to find where the value is\n/// consumed.\n///\n/// Termination has three conditions:\n/// - The given function returns `Break`. This function will return the value.\n/// - The consuming node is found. This function will return `Continue(use_node, child_id)`.\n/// - No further parent nodes are found. This will trigger a debug assert or return `None`.\n///\n/// This allows walking through `if`, `match`, `break`, and block expressions to find where the\n/// value produced by the expression is consumed.\npub fn walk_to_expr_usage<'tcx, T>(\n    cx: &LateContext<'tcx>,\n    e: &Expr<'tcx>,\n    mut f: impl FnMut(HirId, Node<'tcx>, HirId) -> ControlFlow<T>,\n) -> Option<ControlFlow<T, (Node<'tcx>, HirId)>> {\n    let mut iter = cx.tcx.hir_parent_iter(e.hir_id);\n    let mut child_id = e.hir_id;\n\n    while let Some((parent_id, parent)) = iter.next() {\n        if let ControlFlow::Break(x) = f(parent_id, parent, child_id) {\n            return Some(ControlFlow::Break(x));\n        }\n        let parent_expr = match parent {\n            Node::Expr(e) => e,\n            Node::Block(Block { expr: Some(body), .. }) | Node::Arm(Arm { body, .. }) if body.hir_id == child_id => {\n                child_id = parent_id;\n                continue;\n            },\n            Node::Arm(a) if a.body.hir_id == child_id => {\n                child_id = parent_id;\n                continue;\n            },\n            _ => return Some(ControlFlow::Continue((parent, child_id))),\n        };\n        match parent_expr.kind {\n            ExprKind::If(child, ..) | ExprKind::Match(child, ..) if child.hir_id != child_id => child_id = parent_id,\n            ExprKind::Break(Destination { target_id: Ok(id), .. }, _) => {\n                child_id = id;\n                iter = cx.tcx.hir_parent_iter(id);\n            },\n            ExprKind::Block(..) | ExprKind::DropTemps(_) => child_id = parent_id,\n            _ => return Some(ControlFlow::Continue((parent, child_id))),\n        }\n    }\n    debug_assert!(false, \"no parent node found for `{child_id:?}`\");\n    None\n}\n\n/// A type definition as it would be viewed from within a function.\n#[derive(Clone, Copy)]\npub enum DefinedTy<'tcx> {\n    // Used for locals and closures defined within the function.\n    Hir(&'tcx hir::Ty<'tcx>),\n    /// Used for function signatures, and constant and static values. The type is\n    /// in the context of its definition site. We also track the `def_id` of its\n    /// definition site.\n    ///\n    /// WARNING: As the `ty` is in the scope of the definition, not of the function\n    /// using it, you must be very careful with how you use it. Using it in the wrong\n    /// scope easily results in ICEs.\n    Mir {\n        def_site_def_id: Option<DefId>,\n        ty: Binder<'tcx, Ty<'tcx>>,\n    },\n}\n\n/// The context an expressions value is used in.\npub struct ExprUseCtxt<'tcx> {\n    /// The parent node which consumes the value.\n    pub node: Node<'tcx>,\n    /// The child id of the node the value came from.\n    pub child_id: HirId,\n    /// Any adjustments applied to the type.\n    pub adjustments: &'tcx [Adjustment<'tcx>],\n    /// Whether the type must unify with another code path.\n    pub is_ty_unified: bool,\n    /// Whether the value will be moved before it's used.\n    pub moved_before_use: bool,\n    /// Whether the use site has the same `SyntaxContext` as the value.\n    pub same_ctxt: bool,\n}\nimpl<'tcx> ExprUseCtxt<'tcx> {\n    pub fn use_node(&self, cx: &LateContext<'tcx>) -> ExprUseNode<'tcx> {\n        match self.node {\n            Node::LetStmt(l) => ExprUseNode::LetStmt(l),\n            Node::ExprField(field) => ExprUseNode::Field(field),\n\n            Node::Item(&Item {\n                kind: ItemKind::Static(..) | ItemKind::Const(..),\n                owner_id,\n                ..\n            })\n            | Node::TraitItem(&TraitItem {\n                kind: TraitItemKind::Const(..),\n                owner_id,\n                ..\n            })\n            | Node::ImplItem(&ImplItem {\n                kind: ImplItemKind::Const(..),\n                owner_id,\n                ..\n            }) => ExprUseNode::ConstStatic(owner_id),\n\n            Node::Item(&Item {\n                kind: ItemKind::Fn { .. },\n                owner_id,\n                ..\n            })\n            | Node::TraitItem(&TraitItem {\n                kind: TraitItemKind::Fn(..),\n                owner_id,\n                ..\n            })\n            | Node::ImplItem(&ImplItem {\n                kind: ImplItemKind::Fn(..),\n                owner_id,\n                ..\n            }) => ExprUseNode::Return(owner_id),\n\n            Node::Expr(use_expr) => match use_expr.kind {\n                ExprKind::Ret(_) => ExprUseNode::Return(OwnerId {\n                    def_id: cx.tcx.hir_body_owner_def_id(cx.enclosing_body.unwrap()),\n                }),\n\n                ExprKind::Closure(closure) => ExprUseNode::Return(OwnerId { def_id: closure.def_id }),\n                ExprKind::Call(func, args) => match args.iter().position(|arg| arg.hir_id == self.child_id) {\n                    Some(i) => ExprUseNode::FnArg(func, i),\n                    None => ExprUseNode::Callee,\n                },\n                ExprKind::MethodCall(name, _, args, _) => ExprUseNode::MethodArg(\n                    use_expr.hir_id,\n                    name.args,\n                    args.iter()\n                        .position(|arg| arg.hir_id == self.child_id)\n                        .map_or(0, |i| i + 1),\n                ),\n                ExprKind::Field(_, name) => ExprUseNode::FieldAccess(name),\n                ExprKind::AddrOf(kind, mutbl, _) => ExprUseNode::AddrOf(kind, mutbl),\n                _ => ExprUseNode::Other,\n            },\n            _ => ExprUseNode::Other,\n        }\n    }\n}\n\n/// The node which consumes a value.\npub enum ExprUseNode<'tcx> {\n    /// Assignment to, or initializer for, a local\n    LetStmt(&'tcx LetStmt<'tcx>),\n    /// Initializer for a const or static item.\n    ConstStatic(OwnerId),\n    /// Implicit or explicit return from a function.\n    Return(OwnerId),\n    /// Initialization of a struct field.\n    Field(&'tcx ExprField<'tcx>),\n    /// An argument to a function.\n    FnArg(&'tcx Expr<'tcx>, usize),\n    /// An argument to a method.\n    MethodArg(HirId, Option<&'tcx GenericArgs<'tcx>>, usize),\n    /// The callee of a function call.\n    Callee,\n    /// Access of a field.\n    FieldAccess(Ident),\n    /// Borrow expression.\n    AddrOf(ast::BorrowKind, Mutability),\n    Other,\n}\nimpl<'tcx> ExprUseNode<'tcx> {\n    /// Checks if the value is returned from the function.\n    pub fn is_return(&self) -> bool {\n        matches!(self, Self::Return(_))\n    }\n\n    /// Checks if the value is used as a method call receiver.\n    pub fn is_recv(&self) -> bool {\n        matches!(self, Self::MethodArg(_, _, 0))\n    }\n\n    /// Gets the needed type as it's defined without any type inference.\n    pub fn defined_ty(&self, cx: &LateContext<'tcx>) -> Option<DefinedTy<'tcx>> {\n        match *self {\n            Self::LetStmt(LetStmt { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)),\n            Self::ConstStatic(id) => Some(DefinedTy::Mir {\n                def_site_def_id: Some(id.def_id.to_def_id()),\n                ty: Binder::dummy(cx.tcx.type_of(id).instantiate_identity()),\n            }),\n            Self::Return(id) => {\n                if let Node::Expr(Expr {\n                    kind: ExprKind::Closure(c),\n                    ..\n                }) = cx.tcx.hir_node_by_def_id(id.def_id)\n                {\n                    match c.fn_decl.output {\n                        FnRetTy::DefaultReturn(_) => None,\n                        FnRetTy::Return(ty) => Some(DefinedTy::Hir(ty)),\n                    }\n                } else {\n                    let ty = cx.tcx.fn_sig(id).instantiate_identity().output();\n                    Some(DefinedTy::Mir {\n                        def_site_def_id: Some(id.def_id.to_def_id()),\n                        ty,\n                    })\n                }\n            },\n            Self::Field(field) => match get_parent_expr_for_hir(cx, field.hir_id) {\n                Some(Expr {\n                    hir_id,\n                    kind: ExprKind::Struct(path, ..),\n                    ..\n                }) => adt_and_variant_of_res(cx, cx.qpath_res(path, *hir_id))\n                    .and_then(|(adt, variant)| {\n                        variant\n                            .fields\n                            .iter()\n                            .find(|f| f.name == field.ident.name)\n                            .map(|f| (adt, f))\n                    })\n                    .map(|(adt, field_def)| DefinedTy::Mir {\n                        def_site_def_id: Some(adt.did()),\n                        ty: Binder::dummy(cx.tcx.type_of(field_def.did).instantiate_identity()),\n                    }),\n                _ => None,\n            },\n            Self::FnArg(callee, i) => {\n                let sig = expr_sig(cx, callee)?;\n                let (hir_ty, ty) = sig.input_with_hir(i)?;\n                Some(match hir_ty {\n                    Some(hir_ty) => DefinedTy::Hir(hir_ty),\n                    None => DefinedTy::Mir {\n                        def_site_def_id: sig.predicates_id(),\n                        ty,\n                    },\n                })\n            },\n            Self::MethodArg(id, _, i) => {\n                let id = cx.typeck_results().type_dependent_def_id(id)?;\n                let sig = cx.tcx.fn_sig(id).skip_binder();\n                Some(DefinedTy::Mir {\n                    def_site_def_id: Some(id),\n                    ty: sig.input(i),\n                })\n            },\n            Self::LetStmt(_) | Self::FieldAccess(..) | Self::Callee | Self::Other | Self::AddrOf(..) => None,\n        }\n    }\n}\n\n/// Gets the context an expression's value is used in.\npub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'tcx>) -> ExprUseCtxt<'tcx> {\n    let mut adjustments = [].as_slice();\n    let mut is_ty_unified = false;\n    let mut moved_before_use = false;\n    let mut same_ctxt = true;\n    let ctxt = e.span.ctxt();\n    let node = walk_to_expr_usage(cx, e, &mut |parent_id, parent, child_id| -> ControlFlow<!> {\n        if adjustments.is_empty()\n            && let Node::Expr(e) = cx.tcx.hir_node(child_id)\n        {\n            adjustments = cx.typeck_results().expr_adjustments(e);\n        }\n        same_ctxt &= cx.tcx.hir_span(parent_id).ctxt() == ctxt;\n        if let Node::Expr(e) = parent {\n            match e.kind {\n                ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id != child_id => {\n                    is_ty_unified = true;\n                    moved_before_use = true;\n                },\n                ExprKind::Block(_, Some(_)) | ExprKind::Break(..) => {\n                    is_ty_unified = true;\n                    moved_before_use = true;\n                },\n                ExprKind::Block(..) => moved_before_use = true,\n                _ => {},\n            }\n        }\n        ControlFlow::Continue(())\n    });\n    match node {\n        Some(ControlFlow::Continue((node, child_id))) => ExprUseCtxt {\n            node,\n            child_id,\n            adjustments,\n            is_ty_unified,\n            moved_before_use,\n            same_ctxt,\n        },\n        None => ExprUseCtxt {\n            node: Node::Crate(cx.tcx.hir_root_module()),\n            child_id: HirId::INVALID,\n            adjustments: &[],\n            is_ty_unified: true,\n            moved_before_use: true,\n            same_ctxt: false,\n        },\n    }\n}\n\n/// Tokenizes the input while keeping the text associated with each token.\npub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str, InnerSpan)> {\n    let mut pos = 0;\n    tokenize(s, FrontmatterAllowed::No).map(move |t| {\n        let end = pos + t.len;\n        let range = pos as usize..end as usize;\n        let inner = InnerSpan::new(range.start, range.end);\n        pos = end;\n        (t.kind, s.get(range).unwrap_or_default(), inner)\n    })\n}\n\n/// Checks whether a given span has any comment token\n/// This checks for all types of comment: line \"//\", block \"/**\", doc \"///\" \"//!\"\npub fn span_contains_comment(cx: &impl source::HasSession, span: Span) -> bool {\n    span.check_source_text(cx, |snippet| {\n        tokenize(snippet, FrontmatterAllowed::No).any(|token| {\n            matches!(\n                token.kind,\n                TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }\n            )\n        })\n    })\n}\n\n/// Checks whether a given span has any significant token. A significant token is a non-whitespace\n/// token, including comments unless `skip_comments` is set.\n/// This is useful to determine if there are any actual code tokens in the span that are omitted in\n/// the late pass, such as platform-specific code.\npub fn span_contains_non_whitespace(cx: &impl source::HasSession, span: Span, skip_comments: bool) -> bool {\n    span.check_source_text(cx, |snippet| {\n        tokenize_with_text(snippet).any(|(token, _, _)| match token {\n            TokenKind::Whitespace => false,\n            TokenKind::BlockComment { .. } | TokenKind::LineComment { .. } => !skip_comments,\n            _ => true,\n        })\n    })\n}\n/// Returns all the comments a given span contains\n///\n/// Comments are returned wrapped with their relevant delimiters\npub fn span_extract_comment(cx: &impl source::HasSession, span: Span) -> String {\n    span_extract_comments(cx, span).join(\"\\n\")\n}\n\n/// Returns all the comments a given span contains.\n///\n/// Comments are returned wrapped with their relevant delimiters.\npub fn span_extract_comments(cx: &impl source::HasSession, span: Span) -> Vec<String> {\n    span.with_source_text(cx, |snippet| {\n        tokenize_with_text(snippet)\n            .filter(|(t, ..)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }))\n            .map(|(_, s, _)| s.to_string())\n            .collect::<Vec<_>>()\n    })\n    .unwrap_or_default()\n}\n\npub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {\n    sm.span_take_while(span, |&ch| ch == ' ' || ch == ';')\n}\n\n/// Returns whether the given let pattern and else body can be turned into the `?` operator\n///\n/// For this example:\n/// ```ignore\n/// let FooBar { a, b } = if let Some(a) = ex { a } else { return None };\n/// ```\n/// We get as parameters:\n/// ```ignore\n/// pat: Some(a)\n/// else_body: return None\n/// ```\n///\n/// And for this example:\n/// ```ignore\n/// let Some(FooBar { a, b }) = ex else { return None };\n/// ```\n/// We get as parameters:\n/// ```ignore\n/// pat: Some(FooBar { a, b })\n/// else_body: return None\n/// ```\n///\n/// We output `Some(a)` in the first instance, and `Some(FooBar { a, b })` in the second, because\n/// the `?` operator is applicable here. Callers have to check whether we are in a constant or not.\npub fn pat_and_expr_can_be_question_mark<'a, 'hir>(\n    cx: &LateContext<'_>,\n    pat: &'a Pat<'hir>,\n    else_body: &Expr<'_>,\n) -> Option<&'a Pat<'hir>> {\n    if let Some([inner_pat]) = as_some_pattern(cx, pat)\n        && !is_refutable(cx, inner_pat)\n        && let else_body = peel_blocks(else_body)\n        && let ExprKind::Ret(Some(ret_val)) = else_body.kind\n        && let ExprKind::Path(ret_path) = ret_val.kind\n        && cx\n            .qpath_res(&ret_path, ret_val.hir_id)\n            .ctor_parent(cx)\n            .is_lang_item(cx, OptionNone)\n    {\n        Some(inner_pat)\n    } else {\n        None\n    }\n}\n\nmacro_rules! op_utils {\n    ($($name:ident $assign:ident)*) => {\n        /// Binary operation traits like `LangItem::Add`\n        pub static BINOP_TRAITS: &[LangItem] = &[$(LangItem::$name,)*];\n\n        /// Operator-Assign traits like `LangItem::AddAssign`\n        pub static OP_ASSIGN_TRAITS: &[LangItem] = &[$(LangItem::$assign,)*];\n\n        /// Converts `BinOpKind::Add` to `(LangItem::Add, LangItem::AddAssign)`, for example\n        pub fn binop_traits(kind: hir::BinOpKind) -> Option<(LangItem, LangItem)> {\n            match kind {\n                $(hir::BinOpKind::$name => Some((LangItem::$name, LangItem::$assign)),)*\n                _ => None,\n            }\n        }\n    };\n}\n\nop_utils! {\n    Add    AddAssign\n    Sub    SubAssign\n    Mul    MulAssign\n    Div    DivAssign\n    Rem    RemAssign\n    BitXor BitXorAssign\n    BitAnd BitAndAssign\n    BitOr  BitOrAssign\n    Shl    ShlAssign\n    Shr    ShrAssign\n}\n\n/// Returns `true` if the pattern is a `PatWild`, or is an ident prefixed with `_`\n/// that is not locally used.\npub fn pat_is_wild<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx PatKind<'_>, body: impl Visitable<'tcx>) -> bool {\n    match *pat {\n        PatKind::Wild => true,\n        PatKind::Binding(_, id, ident, None) if ident.as_str().starts_with('_') => {\n            !visitors::is_local_used(cx, body, id)\n        },\n        _ => false,\n    }\n}\n\n#[derive(Clone, Copy)]\npub enum RequiresSemi {\n    Yes,\n    No,\n}\nimpl RequiresSemi {\n    pub fn requires_semi(self) -> bool {\n        matches!(self, Self::Yes)\n    }\n}\n\n/// Check if the expression return `!`, a type coerced from `!`, or could return `!` if the final\n/// expression were turned into a statement.\n#[expect(clippy::too_many_lines)]\npub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<RequiresSemi> {\n    struct BreakTarget {\n        id: HirId,\n        unused: bool,\n    }\n\n    struct V<'cx, 'tcx> {\n        cx: &'cx LateContext<'tcx>,\n        break_targets: Vec<BreakTarget>,\n        break_targets_for_result_ty: u32,\n        in_final_expr: bool,\n        requires_semi: bool,\n        is_never: bool,\n    }\n\n    impl V<'_, '_> {\n        fn push_break_target(&mut self, id: HirId) {\n            self.break_targets.push(BreakTarget { id, unused: true });\n            self.break_targets_for_result_ty += u32::from(self.in_final_expr);\n        }\n    }\n\n    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {\n            // Note: Part of the complexity here comes from the fact that\n            // coercions are applied to the innermost expression.\n            // e.g. In `let x: u32 = { break () };` the never-to-any coercion\n            // is applied to the break expression. This means we can't just\n            // check the block's type as it will be `u32` despite the fact\n            // that the block always diverges.\n\n            // The rest of the complexity comes from checking blocks which\n            // syntactically return a value, but will always diverge before\n            // reaching that point.\n            // e.g. In `let x = { foo(panic!()) };` the block's type will be the\n            // return type of `foo` even though it will never actually run. This\n            // can be trivially fixed by adding a semicolon after the call, but\n            // we must first detect that a semicolon is needed to make that\n            // suggestion.\n\n            if self.is_never && self.break_targets.is_empty() {\n                if self.in_final_expr && !self.requires_semi {\n                    // This expression won't ever run, but we still need to check\n                    // if it can affect the type of the final expression.\n                    match e.kind {\n                        ExprKind::DropTemps(e) => self.visit_expr(e),\n                        ExprKind::If(_, then, Some(else_)) => {\n                            self.visit_expr(then);\n                            self.visit_expr(else_);\n                        },\n                        ExprKind::Match(_, arms, _) => {\n                            for arm in arms {\n                                self.visit_expr(arm.body);\n                            }\n                        },\n                        ExprKind::Loop(b, ..) => {\n                            self.push_break_target(e.hir_id);\n                            self.in_final_expr = false;\n                            self.visit_block(b);\n                            self.break_targets.pop();\n                        },\n                        ExprKind::Block(b, _) => {\n                            if b.targeted_by_break {\n                                self.push_break_target(b.hir_id);\n                                self.visit_block(b);\n                                self.break_targets.pop();\n                            } else {\n                                self.visit_block(b);\n                            }\n                        },\n                        _ => {\n                            self.requires_semi = !self.cx.typeck_results().expr_ty(e).is_never();\n                        },\n                    }\n                }\n                return;\n            }\n            match e.kind {\n                ExprKind::DropTemps(e) => self.visit_expr(e),\n                ExprKind::Ret(None) | ExprKind::Continue(_) => self.is_never = true,\n                ExprKind::Ret(Some(e)) | ExprKind::Become(e) => {\n                    self.in_final_expr = false;\n                    self.visit_expr(e);\n                    self.is_never = true;\n                },\n                ExprKind::Break(dest, e) => {\n                    if let Some(e) = e {\n                        self.in_final_expr = false;\n                        self.visit_expr(e);\n                    }\n                    if let Ok(id) = dest.target_id\n                        && let Some((i, target)) = self\n                            .break_targets\n                            .iter_mut()\n                            .enumerate()\n                            .find(|(_, target)| target.id == id)\n                    {\n                        target.unused &= self.is_never;\n                        if i < self.break_targets_for_result_ty as usize {\n                            self.requires_semi = true;\n                        }\n                    }\n                    self.is_never = true;\n                },\n                ExprKind::If(cond, then, else_) => {\n                    let in_final_expr = mem::replace(&mut self.in_final_expr, false);\n                    self.visit_expr(cond);\n                    self.in_final_expr = in_final_expr;\n\n                    if self.is_never {\n                        self.visit_expr(then);\n                        if let Some(else_) = else_ {\n                            self.visit_expr(else_);\n                        }\n                    } else {\n                        self.visit_expr(then);\n                        let is_never = mem::replace(&mut self.is_never, false);\n                        if let Some(else_) = else_ {\n                            self.visit_expr(else_);\n                            self.is_never &= is_never;\n                        }\n                    }\n                },\n                ExprKind::Match(scrutinee, arms, _) => {\n                    let in_final_expr = mem::replace(&mut self.in_final_expr, false);\n                    self.visit_expr(scrutinee);\n                    self.in_final_expr = in_final_expr;\n\n                    if self.is_never {\n                        for arm in arms {\n                            self.visit_arm(arm);\n                        }\n                    } else {\n                        let mut is_never = true;\n                        for arm in arms {\n                            self.is_never = false;\n                            if let Some(guard) = arm.guard {\n                                let in_final_expr = mem::replace(&mut self.in_final_expr, false);\n                                self.visit_expr(guard);\n                                self.in_final_expr = in_final_expr;\n                                // The compiler doesn't consider diverging guards as causing the arm to diverge.\n                                self.is_never = false;\n                            }\n                            self.visit_expr(arm.body);\n                            is_never &= self.is_never;\n                        }\n                        self.is_never = is_never;\n                    }\n                },\n                ExprKind::Loop(b, _, _, _) => {\n                    self.push_break_target(e.hir_id);\n                    self.in_final_expr = false;\n                    self.visit_block(b);\n                    self.is_never = self.break_targets.pop().unwrap().unused;\n                },\n                ExprKind::Block(b, _) => {\n                    if b.targeted_by_break {\n                        self.push_break_target(b.hir_id);\n                        self.visit_block(b);\n                        self.is_never &= self.break_targets.pop().unwrap().unused;\n                    } else {\n                        self.visit_block(b);\n                    }\n                },\n                _ => {\n                    self.in_final_expr = false;\n                    walk_expr(self, e);\n                    self.is_never |= self.cx.typeck_results().expr_ty(e).is_never();\n                },\n            }\n        }\n\n        fn visit_block(&mut self, b: &'tcx Block<'_>) {\n            let in_final_expr = mem::replace(&mut self.in_final_expr, false);\n            for s in b.stmts {\n                self.visit_stmt(s);\n            }\n            self.in_final_expr = in_final_expr;\n            if let Some(e) = b.expr {\n                self.visit_expr(e);\n            }\n        }\n\n        fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {\n            if let Some(e) = l.init {\n                self.visit_expr(e);\n            }\n            if let Some(else_) = l.els {\n                let is_never = self.is_never;\n                self.visit_block(else_);\n                self.is_never = is_never;\n            }\n        }\n\n        fn visit_arm(&mut self, arm: &Arm<'tcx>) {\n            if let Some(guard) = arm.guard {\n                let in_final_expr = mem::replace(&mut self.in_final_expr, false);\n                self.visit_expr(guard);\n                self.in_final_expr = in_final_expr;\n            }\n            self.visit_expr(arm.body);\n        }\n    }\n\n    if cx.typeck_results().expr_ty(e).is_never() {\n        Some(RequiresSemi::No)\n    } else if let ExprKind::Block(b, _) = e.kind\n        && !b.targeted_by_break\n        && b.expr.is_none()\n    {\n        // If a block diverges without a final expression then it's type is `!`.\n        None\n    } else {\n        let mut v = V {\n            cx,\n            break_targets: Vec::new(),\n            break_targets_for_result_ty: 0,\n            in_final_expr: true,\n            requires_semi: false,\n            is_never: false,\n        };\n        v.visit_expr(e);\n        v.is_never\n            .then_some(if v.requires_semi && matches!(e.kind, ExprKind::Block(..)) {\n                RequiresSemi::Yes\n            } else {\n                RequiresSemi::No\n            })\n    }\n}\n\n/// Produces a path from a local caller to the type of the called method. Suitable for user\n/// output/suggestions.\n///\n/// Returned path can be either absolute (for methods defined non-locally), or relative (for local\n/// methods).\npub fn get_path_from_caller_to_method_type<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    from: LocalDefId,\n    method: DefId,\n    args: GenericArgsRef<'tcx>,\n) -> String {\n    let assoc_item = tcx.associated_item(method);\n    let def_id = assoc_item.container_id(tcx);\n    match assoc_item.container {\n        rustc_ty::AssocContainer::Trait => get_path_to_callee(tcx, from, def_id),\n        rustc_ty::AssocContainer::InherentImpl | rustc_ty::AssocContainer::TraitImpl(_) => {\n            let ty = tcx.type_of(def_id).instantiate_identity();\n            get_path_to_ty(tcx, from, ty, args)\n        },\n    }\n}\n\nfn get_path_to_ty<'tcx>(tcx: TyCtxt<'tcx>, from: LocalDefId, ty: Ty<'tcx>, args: GenericArgsRef<'tcx>) -> String {\n    match ty.kind() {\n        rustc_ty::Adt(adt, _) => get_path_to_callee(tcx, from, adt.did()),\n        // TODO these types need to be recursively resolved as well\n        rustc_ty::Array(..)\n        | rustc_ty::Dynamic(..)\n        | rustc_ty::Never\n        | rustc_ty::RawPtr(_, _)\n        | rustc_ty::Ref(..)\n        | rustc_ty::Slice(_)\n        | rustc_ty::Tuple(_) => format!(\"<{}>\", EarlyBinder::bind(ty).instantiate(tcx, args)),\n        _ => ty.to_string(),\n    }\n}\n\n/// Produce a path from some local caller to the callee. Suitable for user output/suggestions.\nfn get_path_to_callee(tcx: TyCtxt<'_>, from: LocalDefId, callee: DefId) -> String {\n    // only search for a relative path if the call is fully local\n    if callee.is_local() {\n        let callee_path = tcx.def_path(callee);\n        let caller_path = tcx.def_path(from.to_def_id());\n        maybe_get_relative_path(&caller_path, &callee_path, 2)\n    } else {\n        tcx.def_path_str(callee)\n    }\n}\n\n/// Tries to produce a relative path from `from` to `to`; if such a path would contain more than\n/// `max_super` `super` items, produces an absolute path instead. Both `from` and `to` should be in\n/// the local crate.\n///\n/// Suitable for user output/suggestions.\n///\n/// This ignores use items, and assumes that the target path is visible from the source\n/// path (which _should_ be a reasonable assumption since we in order to be able to use an object of\n/// certain type T, T is required to be visible).\n///\n/// TODO make use of `use` items. Maybe we should have something more sophisticated like\n/// rust-analyzer does? <https://docs.rs/ra_ap_hir_def/0.0.169/src/ra_ap_hir_def/find_path.rs.html#19-27>\nfn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> String {\n    use itertools::EitherOrBoth::{Both, Left, Right};\n\n    // 1. skip the segments common for both paths (regardless of their type)\n    let unique_parts = to\n        .data\n        .iter()\n        .zip_longest(from.data.iter())\n        .skip_while(|el| matches!(el, Both(l, r) if l == r))\n        .map(|el| match el {\n            Both(l, r) => Both(l.data, r.data),\n            Left(l) => Left(l.data),\n            Right(r) => Right(r.data),\n        });\n\n    // 2. for the remaining segments, construct relative path using only mod names and `super`\n    let mut go_up_by = 0;\n    let mut path = Vec::new();\n    for el in unique_parts {\n        match el {\n            Both(l, r) => {\n                // consider:\n                // a::b::sym:: ::    refers to\n                // c::d::e  ::f::sym\n                // result should be super::super::c::d::e::f\n                //\n                // alternatively:\n                // a::b::c  ::d::sym refers to\n                // e::f::sym:: ::\n                // result should be super::super::super::super::e::f\n                if let DefPathData::TypeNs(sym) = l {\n                    path.push(sym);\n                }\n                if let DefPathData::TypeNs(_) = r {\n                    go_up_by += 1;\n                }\n            },\n            // consider:\n            // a::b::sym:: ::    refers to\n            // c::d::e  ::f::sym\n            // when looking at `f`\n            Left(DefPathData::TypeNs(sym)) => path.push(sym),\n            // consider:\n            // a::b::c  ::d::sym refers to\n            // e::f::sym:: ::\n            // when looking at `d`\n            Right(DefPathData::TypeNs(_)) => go_up_by += 1,\n            _ => {},\n        }\n    }\n\n    if go_up_by > max_super {\n        // `super` chain would be too long, just use the absolute path instead\n        join_path_syms(once(kw::Crate).chain(to.data.iter().filter_map(|el| {\n            if let DefPathData::TypeNs(sym) = el.data {\n                Some(sym)\n            } else {\n                None\n            }\n        })))\n    } else if go_up_by == 0 && path.is_empty() {\n        String::from(\"Self\")\n    } else {\n        join_path_syms(repeat_n(kw::Super, go_up_by).chain(path))\n    }\n}\n\n/// Returns true if the specified `HirId` is the top-level expression of a statement or the only\n/// expression in a block.\npub fn is_parent_stmt(cx: &LateContext<'_>, id: HirId) -> bool {\n    matches!(\n        cx.tcx.parent_hir_node(id),\n        Node::Stmt(..) | Node::Block(Block { stmts: [], .. })\n    )\n}\n\n/// Returns true if the given `expr` is a block or resembled as a block,\n/// such as `if`, `loop`, `match` expressions etc.\npub fn is_block_like(expr: &Expr<'_>) -> bool {\n    matches!(\n        expr.kind,\n        ExprKind::Block(..) | ExprKind::ConstBlock(..) | ExprKind::If(..) | ExprKind::Loop(..) | ExprKind::Match(..)\n    )\n}\n\n/// Returns true if the given `expr` is binary expression that needs to be wrapped in parentheses.\npub fn binary_expr_needs_parentheses(expr: &Expr<'_>) -> bool {\n    fn contains_block(expr: &Expr<'_>, is_operand: bool) -> bool {\n        match expr.kind {\n            ExprKind::Binary(_, lhs, _) | ExprKind::Cast(lhs, _) => contains_block(lhs, true),\n            _ if is_block_like(expr) => is_operand,\n            _ => false,\n        }\n    }\n\n    contains_block(expr, false)\n}\n\n/// Returns true if the specified expression is in a receiver position.\npub fn is_receiver_of_method_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let Some(parent_expr) = get_parent_expr(cx, expr)\n        && let ExprKind::MethodCall(_, receiver, ..) = parent_expr.kind\n        && receiver.hir_id == expr.hir_id\n    {\n        return true;\n    }\n    false\n}\n\n/// Returns true if `expr` creates any temporary whose type references a non-static lifetime and has\n/// a significant drop and does not consume it.\npub fn leaks_droppable_temporary_with_limited_lifetime<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {\n    for_each_unconsumed_temporary(cx, expr, |temporary_ty| {\n        if temporary_ty.has_significant_drop(cx.tcx, cx.typing_env())\n            && temporary_ty\n                .walk()\n                .any(|arg| matches!(arg.kind(), GenericArgKind::Lifetime(re) if !re.is_static()))\n        {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_break()\n}\n\n/// Returns true if the specified `expr` requires coercion,\n/// meaning that it either has a coercion or propagates a coercion from one of its sub expressions.\n///\n/// Similar to [`is_adjusted`], this not only checks if an expression's type was adjusted,\n/// but also going through extra steps to see if it fits the description of [coercion sites].\n///\n/// You should used this when you want to avoid suggesting replacing an expression that is currently\n/// a coercion site or coercion propagating expression with one that is not.\n///\n/// [coercion sites]: https://doc.rust-lang.org/stable/reference/type-coercions.html#coercion-sites\npub fn expr_requires_coercion<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> bool {\n    let expr_ty_is_adjusted = cx\n        .typeck_results()\n        .expr_adjustments(expr)\n        .iter()\n        // ignore `NeverToAny` adjustments, such as `panic!` call.\n        .any(|adj| !matches!(adj.kind, Adjust::NeverToAny));\n    if expr_ty_is_adjusted {\n        return true;\n    }\n\n    // Identify coercion sites and recursively check if those sites\n    // actually have type adjustments.\n    match expr.kind {\n        ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) if let Some(def_id) = fn_def_id(cx, expr) => {\n            let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity();\n\n            if !fn_sig.output().skip_binder().has_type_flags(TypeFlags::HAS_TY_PARAM) {\n                return false;\n            }\n\n            let self_arg_count = usize::from(matches!(expr.kind, ExprKind::MethodCall(..)));\n            let mut args_with_ty_param = {\n                fn_sig\n                    .inputs()\n                    .skip_binder()\n                    .iter()\n                    .skip(self_arg_count)\n                    .zip(args)\n                    .filter_map(|(arg_ty, arg)| {\n                        if arg_ty.has_type_flags(TypeFlags::HAS_TY_PARAM) {\n                            Some(arg)\n                        } else {\n                            None\n                        }\n                    })\n            };\n            args_with_ty_param.any(|arg| expr_requires_coercion(cx, arg))\n        },\n        // Struct/union initialization.\n        ExprKind::Struct(qpath, _, _) => {\n            let res = cx.typeck_results().qpath_res(qpath, expr.hir_id);\n            if let Some((_, v_def)) = adt_and_variant_of_res(cx, res) {\n                let rustc_ty::Adt(_, generic_args) = cx.typeck_results().expr_ty_adjusted(expr).kind() else {\n                    // This should never happen, but when it does, not linting is the better option.\n                    return true;\n                };\n                v_def\n                    .fields\n                    .iter()\n                    .any(|field| field.ty(cx.tcx, generic_args).has_type_flags(TypeFlags::HAS_TY_PARAM))\n            } else {\n                false\n            }\n        },\n        // Function results, including the final line of a block or a `return` expression.\n        ExprKind::Block(\n            &Block {\n                expr: Some(ret_expr), ..\n            },\n            _,\n        )\n        | ExprKind::Ret(Some(ret_expr)) => expr_requires_coercion(cx, ret_expr),\n\n        // ===== Coercion-propagation expressions =====\n        ExprKind::Array(elems) | ExprKind::Tup(elems) => elems.iter().any(|elem| expr_requires_coercion(cx, elem)),\n        // Array but with repeating syntax.\n        ExprKind::Repeat(rep_elem, _) => expr_requires_coercion(cx, rep_elem),\n        // Others that may contain coercion sites.\n        ExprKind::If(_, then, maybe_else) => {\n            expr_requires_coercion(cx, then) || maybe_else.is_some_and(|e| expr_requires_coercion(cx, e))\n        },\n        ExprKind::Match(_, arms, _) => arms\n            .iter()\n            .map(|arm| arm.body)\n            .any(|body| expr_requires_coercion(cx, body)),\n        _ => false,\n    }\n}\n\n/// Returns `true` if `expr` designates a mutable static, a mutable local binding, or an expression\n/// that can be owned.\npub fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let Some(hir_id) = expr.res_local_id()\n        && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)\n    {\n        matches!(pat.kind, PatKind::Binding(BindingMode::MUT, ..))\n    } else if let ExprKind::Path(p) = &expr.kind\n        && let Some(mutability) = cx\n            .qpath_res(p, expr.hir_id)\n            .opt_def_id()\n            .and_then(|id| cx.tcx.static_mutability(id))\n    {\n        mutability == Mutability::Mut\n    } else if let ExprKind::Field(parent, _) = expr.kind {\n        is_mutable(cx, parent)\n    } else {\n        true\n    }\n}\n\n/// Peel `Option<…>` from `hir_ty` as long as the HIR name is `Option` and it corresponds to the\n/// `core::Option<_>` type.\npub fn peel_hir_ty_options<'tcx>(cx: &LateContext<'tcx>, mut hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {\n    let Some(option_def_id) = cx.tcx.get_diagnostic_item(sym::Option) else {\n        return hir_ty;\n    };\n    while let TyKind::Path(QPath::Resolved(None, path)) = hir_ty.kind\n        && let Some(segment) = path.segments.last()\n        && segment.ident.name == sym::Option\n        && let Res::Def(DefKind::Enum, def_id) = segment.res\n        && def_id == option_def_id\n        && let [GenericArg::Type(arg_ty)] = segment.args().args\n    {\n        hir_ty = arg_ty.as_unambig_ty();\n    }\n    hir_ty\n}\n\n/// If `expr` is a desugared `.await`, return the original expression if it does not come from a\n/// macro expansion.\npub fn desugar_await<'tcx>(expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {\n    if let ExprKind::Match(match_value, _, MatchSource::AwaitDesugar) = expr.kind\n        && let ExprKind::Call(_, [into_future_arg]) = match_value.kind\n        && let ctxt = expr.span.ctxt()\n        && for_each_expr_without_closures(into_future_arg, |e| {\n            walk_span_to_context(e.span, ctxt).map_or(ControlFlow::Break(()), |_| ControlFlow::Continue(()))\n        })\n        .is_none()\n    {\n        Some(into_future_arg)\n    } else {\n        None\n    }\n}\n\n/// Checks if the given expression is a call to `Default::default()`.\npub fn is_expr_default<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {\n    if let ExprKind::Call(fn_expr, []) = &expr.kind\n        && let ExprKind::Path(qpath) = &fn_expr.kind\n        && let Res::Def(_, def_id) = cx.qpath_res(qpath, fn_expr.hir_id)\n    {\n        cx.tcx.is_diagnostic_item(sym::default_fn, def_id)\n    } else {\n        false\n    }\n}\n\n/// Checks if `expr` may be directly used as the return value of its enclosing body.\n/// The following cases are covered:\n/// - `expr` as the last expression of the body, or of a block that can be used as the return value\n/// - `return expr`\n/// - then or else part of a `if` in return position\n/// - arm body of a `match` in a return position\n/// - `break expr` or `break 'label expr` if the loop or block being exited is used as a return\n///   value\n///\n/// Contrary to [`TyCtxt::hir_get_fn_id_for_return_block()`], if `expr` is part of a\n/// larger expression, for example a field expression of a `struct`, it will not be\n/// considered as matching the condition and will return `false`.\n///\n/// Also, even if `expr` is assigned to a variable which is later returned, this function\n/// will still return `false` because `expr` is not used *directly* as the return value\n/// as it goes through the intermediate variable.\npub fn potential_return_of_enclosing_body(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let enclosing_body_owner = cx\n        .tcx\n        .local_def_id_to_hir_id(cx.tcx.hir_enclosing_body_owner(expr.hir_id));\n    let mut prev_id = expr.hir_id;\n    let mut skip_until_id = None;\n    for (hir_id, node) in cx.tcx.hir_parent_iter(expr.hir_id) {\n        if hir_id == enclosing_body_owner {\n            return true;\n        }\n        if let Some(id) = skip_until_id {\n            prev_id = hir_id;\n            if id == hir_id {\n                skip_until_id = None;\n            }\n            continue;\n        }\n        match node {\n            Node::Block(Block { expr, .. }) if expr.is_some_and(|expr| expr.hir_id == prev_id) => {},\n            Node::Arm(arm) if arm.body.hir_id == prev_id => {},\n            Node::Expr(expr) => match expr.kind {\n                ExprKind::Ret(_) => return true,\n                ExprKind::If(_, then, opt_else)\n                    if then.hir_id == prev_id || opt_else.is_some_and(|els| els.hir_id == prev_id) => {},\n                ExprKind::Match(_, arms, _) if arms.iter().any(|arm| arm.hir_id == prev_id) => {},\n                ExprKind::Block(block, _) if block.hir_id == prev_id => {},\n                ExprKind::Break(\n                    Destination {\n                        target_id: Ok(target_id),\n                        ..\n                    },\n                    _,\n                ) => skip_until_id = Some(target_id),\n                _ => break,\n            },\n            _ => break,\n        }\n        prev_id = hir_id;\n    }\n\n    // `expr` is used as part of \"something\" and is not returned directly from its\n    // enclosing body.\n    false\n}\n\n/// Checks if the expression has adjustments that require coercion, for example: dereferencing with\n/// overloaded deref, coercing pointers and `dyn` objects.\npub fn expr_adjustment_requires_coercion(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    cx.typeck_results().expr_adjustments(expr).iter().any(|adj| {\n        matches!(\n            adj.kind,\n            Adjust::Deref(DerefAdjustKind::Overloaded(_))\n                | Adjust::Pointer(PointerCoercion::Unsize)\n                | Adjust::NeverToAny\n        )\n    })\n}\n\n/// Checks if the expression is an async block (i.e., `async { ... }`).\npub fn is_expr_async_block(expr: &Expr<'_>) -> bool {\n    matches!(\n        expr.kind,\n        ExprKind::Closure(Closure {\n            kind: hir::ClosureKind::Coroutine(CoroutineKind::Desugared(\n                CoroutineDesugaring::Async,\n                CoroutineSource::Block\n            )),\n            ..\n        })\n    )\n}\n\n/// Checks if the chosen edition and `msrv` allows using `if let` chains.\npub fn can_use_if_let_chains(cx: &LateContext<'_>, msrv: Msrv) -> bool {\n    cx.tcx.sess.edition().at_least_rust_2024() && msrv.meets(cx, msrvs::LET_CHAINS)\n}\n"
  },
  {
    "path": "clippy_utils/src/macros.rs",
    "content": "#![allow(clippy::similar_names)] // `expr` and `expn`\n\nuse std::sync::{Arc, OnceLock};\n\nuse crate::visitors::{Descend, for_each_expr_without_closures};\nuse crate::{get_unique_builtin_attr, sym};\n\nuse arrayvec::ArrayVec;\nuse rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder};\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};\nuse rustc_lint::{LateContext, LintContext};\nuse rustc_span::def_id::DefId;\nuse rustc_span::hygiene::{self, MacroKind, SyntaxContext};\nuse rustc_span::{BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol};\nuse std::ops::ControlFlow;\n\nconst FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[\n    sym::assert_eq_macro,\n    sym::assert_macro,\n    sym::assert_ne_macro,\n    sym::core_panic_macro,\n    sym::debug_assert_eq_macro,\n    sym::debug_assert_macro,\n    sym::debug_assert_ne_macro,\n    sym::eprint_macro,\n    sym::eprintln_macro,\n    sym::format_args_macro,\n    sym::format_macro,\n    sym::print_macro,\n    sym::println_macro,\n    sym::std_panic_macro,\n    sym::todo_macro,\n    sym::unimplemented_macro,\n    sym::write_macro,\n    sym::writeln_macro,\n];\n\n/// Returns true if a given Macro `DefId` is a format macro (e.g. `println!`)\npub fn is_format_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool {\n    if let Some(name) = cx.tcx.get_diagnostic_name(macro_def_id) {\n        FORMAT_MACRO_DIAG_ITEMS.contains(&name)\n    } else {\n        // Allow users to tag any macro as being format!-like\n        // TODO: consider deleting FORMAT_MACRO_DIAG_ITEMS and using just this method\n        get_unique_builtin_attr(\n            cx.sess(),\n            #[allow(deprecated)]\n            cx.tcx.get_all_attrs(macro_def_id),\n            sym::format_args,\n        )\n        .is_some()\n    }\n}\n\n/// A macro call, like `vec![1, 2, 3]`.\n///\n/// Use `tcx.item_name(macro_call.def_id)` to get the macro name.\n/// Even better is to check if it is a diagnostic item.\n///\n/// This structure is similar to `ExpnData` but it precludes desugaring expansions.\n#[derive(Debug)]\npub struct MacroCall {\n    /// Macro `DefId`\n    pub def_id: DefId,\n    /// Kind of macro\n    pub kind: MacroKind,\n    /// The expansion produced by the macro call\n    pub expn: ExpnId,\n    /// Span of the macro call site\n    pub span: Span,\n}\n\nimpl MacroCall {\n    pub fn is_local(&self) -> bool {\n        span_is_local(self.span)\n    }\n}\n\n/// Returns an iterator of expansions that created the given span\npub fn expn_backtrace(mut span: Span) -> impl Iterator<Item = (ExpnId, ExpnData)> {\n    std::iter::from_fn(move || {\n        let ctxt = span.ctxt();\n        if ctxt == SyntaxContext::root() {\n            return None;\n        }\n        let expn = ctxt.outer_expn();\n        let data = expn.expn_data();\n        span = data.call_site;\n        Some((expn, data))\n    })\n}\n\n/// Checks whether the span is from the root expansion or a locally defined macro\npub fn span_is_local(span: Span) -> bool {\n    !span.from_expansion() || expn_is_local(span.ctxt().outer_expn())\n}\n\n/// Checks whether the expansion is the root expansion or a locally defined macro\npub fn expn_is_local(expn: ExpnId) -> bool {\n    if expn == ExpnId::root() {\n        return true;\n    }\n    let data = expn.expn_data();\n    let backtrace = expn_backtrace(data.call_site);\n    std::iter::once((expn, data))\n        .chain(backtrace)\n        .find_map(|(_, data)| data.macro_def_id)\n        .is_none_or(DefId::is_local)\n}\n\n/// Returns an iterator of macro expansions that created the given span.\n/// Note that desugaring expansions are skipped.\npub fn macro_backtrace(span: Span) -> impl Iterator<Item = MacroCall> {\n    expn_backtrace(span).filter_map(|(expn, data)| match data {\n        ExpnData {\n            kind: ExpnKind::Macro(kind, _),\n            macro_def_id: Some(def_id),\n            call_site: span,\n            ..\n        } => Some(MacroCall {\n            def_id,\n            kind,\n            expn,\n            span,\n        }),\n        _ => None,\n    })\n}\n\n/// If the macro backtrace of `span` has a macro call at the root expansion\n/// (i.e. not a nested macro call), returns `Some` with the `MacroCall`\n///\n/// If you only want to check whether the root macro has a specific name,\n/// consider using [`matching_root_macro_call`] instead.\npub fn root_macro_call(span: Span) -> Option<MacroCall> {\n    macro_backtrace(span).last()\n}\n\n/// A combination of [`root_macro_call`] and\n/// [`is_diagnostic_item`](rustc_middle::ty::TyCtxt::is_diagnostic_item) that returns a `MacroCall`\n/// at the root expansion if only it matches the given name.\npub fn matching_root_macro_call(cx: &LateContext<'_>, span: Span, name: Symbol) -> Option<MacroCall> {\n    root_macro_call(span).filter(|mc| cx.tcx.is_diagnostic_item(name, mc.def_id))\n}\n\n/// Like [`root_macro_call`], but only returns `Some` if `node` is the \"first node\"\n/// produced by the macro call, as in [`first_node_in_macro`].\npub fn root_macro_call_first_node(cx: &LateContext<'_>, node: &impl HirNode) -> Option<MacroCall> {\n    if first_node_in_macro(cx, node) != Some(ExpnId::root()) {\n        return None;\n    }\n    root_macro_call(node.span())\n}\n\n/// Like [`macro_backtrace`], but only returns macro calls where `node` is the \"first node\" of the\n/// macro call, as in [`first_node_in_macro`].\npub fn first_node_macro_backtrace(cx: &LateContext<'_>, node: &impl HirNode) -> impl Iterator<Item = MacroCall> {\n    let span = node.span();\n    first_node_in_macro(cx, node)\n        .into_iter()\n        .flat_map(move |expn| macro_backtrace(span).take_while(move |macro_call| macro_call.expn != expn))\n}\n\n/// If `node` is the \"first node\" in a macro expansion, returns `Some` with the `ExpnId` of the\n/// macro call site (i.e. the parent of the macro expansion).\n///\n/// This generally means that `node` is the outermost node of an entire macro expansion, but there\n/// are some caveats noted below. This is useful for finding macro calls while visiting the HIR\n/// without processing the macro call at every node within its expansion.\n///\n/// If you already have immediate access to the parent node, it is simpler to\n/// just check the context of that span directly (e.g. `parent.span.from_expansion()`).\n///\n/// If a macro call is in statement position, it expands to one or more statements.\n/// In that case, each statement *and* their immediate descendants will all yield `Some`\n/// with the `ExpnId` of the containing block.\n///\n/// A node may be the \"first node\" of multiple macro calls in a macro backtrace.\n/// The expansion of the outermost macro call site is returned in such cases.\npub fn first_node_in_macro(cx: &LateContext<'_>, node: &impl HirNode) -> Option<ExpnId> {\n    // get the macro expansion or return `None` if not found\n    // `macro_backtrace` importantly ignores desugaring expansions\n    let expn = macro_backtrace(node.span()).next()?.expn;\n\n    // get the parent node, possibly skipping over a statement\n    // if the parent is not found, it is sensible to return `Some(root)`\n    let mut parent_iter = cx.tcx.hir_parent_iter(node.hir_id());\n    let (parent_id, _) = match parent_iter.next() {\n        None => return Some(ExpnId::root()),\n        Some((_, Node::Stmt(_))) => match parent_iter.next() {\n            None => return Some(ExpnId::root()),\n            Some(next) => next,\n        },\n        Some(next) => next,\n    };\n\n    // get the macro expansion of the parent node\n    let parent_span = cx.tcx.hir_span(parent_id);\n    let Some(parent_macro_call) = macro_backtrace(parent_span).next() else {\n        // the parent node is not in a macro\n        return Some(ExpnId::root());\n    };\n\n    if parent_macro_call.expn.is_descendant_of(expn) {\n        // `node` is input to a macro call\n        return None;\n    }\n\n    Some(parent_macro_call.expn)\n}\n\n/* Specific Macro Utils */\n\n/// Is `def_id` of `std::panic`, `core::panic` or any inner implementation macros\npub fn is_panic(cx: &LateContext<'_>, def_id: DefId) -> bool {\n    let Some(name) = cx.tcx.get_diagnostic_name(def_id) else {\n        return false;\n    };\n    matches!(\n        name,\n        sym::core_panic_macro\n            | sym::std_panic_macro\n            | sym::core_panic_2015_macro\n            | sym::std_panic_2015_macro\n            | sym::core_panic_2021_macro\n    )\n}\n\n/// Is `def_id` of `assert!` or `debug_assert!`\npub fn is_assert_macro(cx: &LateContext<'_>, def_id: DefId) -> bool {\n    let Some(name) = cx.tcx.get_diagnostic_name(def_id) else {\n        return false;\n    };\n    matches!(name, sym::assert_macro | sym::debug_assert_macro)\n}\n\n/// A call to a function in [`std::rt`] or [`core::panicking`] that results in a panic, typically\n/// part of a `panic!()` expansion (often wrapped in a block) but may be called directly by other\n/// macros such as `assert`.\n#[derive(Debug)]\npub enum PanicCall<'a> {\n    // The default message - `panic!()`, `assert!(true)`, etc.\n    DefaultMessage,\n    /// A string literal or any `&str` in edition 2015/2018 - `panic!(\"message\")` or\n    /// `panic!(message)`.\n    ///\n    /// In edition 2021+ `panic!(\"message\")` will be a [`PanicCall::Format`] and `panic!(message)` a\n    /// compile error.\n    Str2015(&'a Expr<'a>),\n    /// A single argument that implements `Display` - `panic!(\"{}\", object)`.\n    ///\n    /// `panic!(\"{object}\")` will still be a [`PanicCall::Format`].\n    Display(&'a Expr<'a>),\n    /// Anything else - `panic!(\"error {}: {}\", a, b)`, `panic!(\"on edition 2021+\")`.\n    ///\n    /// See [`FormatArgsStorage::get`] to examine the contents of the formatting.\n    Format(&'a Expr<'a>),\n}\n\nimpl<'a> PanicCall<'a> {\n    pub fn parse(expr: &'a Expr<'a>) -> Option<Self> {\n        let ExprKind::Call(callee, args) = &expr.kind else {\n            return None;\n        };\n        let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else {\n            return None;\n        };\n        let name = path.segments.last().unwrap().ident.name;\n\n        let [arg, rest @ ..] = args else {\n            return None;\n        };\n        let result = match name {\n            sym::panic | sym::begin_panic | sym::panic_str_2015 => {\n                if arg.span.eq_ctxt(expr.span) || arg.span.is_dummy() {\n                    Self::DefaultMessage\n                } else {\n                    Self::Str2015(arg)\n                }\n            },\n            sym::panic_display => {\n                let ExprKind::AddrOf(_, _, e) = &arg.kind else {\n                    return None;\n                };\n                Self::Display(e)\n            },\n            sym::panic_fmt => Self::Format(arg),\n            // Since Rust 1.52, `assert_{eq,ne}` macros expand to use:\n            // `core::panicking::assert_failed(.., left_val, right_val, None | Some(format_args!(..)));`\n            sym::assert_failed => {\n                // It should have 4 arguments in total (we already matched with the first argument,\n                // so we're just checking for 3)\n                if rest.len() != 3 {\n                    return None;\n                }\n                // `msg_arg` is either `None` (no custom message) or `Some(format_args!(..))` (custom message)\n                let msg_arg = &rest[2];\n                match msg_arg.kind {\n                    ExprKind::Call(_, [fmt_arg]) => Self::Format(fmt_arg),\n                    _ => Self::DefaultMessage,\n                }\n            },\n            _ => return None,\n        };\n        Some(result)\n    }\n\n    pub fn is_default_message(&self) -> bool {\n        matches!(self, Self::DefaultMessage)\n    }\n}\n\n/// Finds the arguments of an `assert!` or `debug_assert!` macro call within the macro expansion\npub fn find_assert_args<'a>(\n    cx: &LateContext<'_>,\n    expr: &'a Expr<'a>,\n    expn: ExpnId,\n) -> Option<(&'a Expr<'a>, PanicCall<'a>)> {\n    find_assert_args_inner(cx, expr, expn).map(|([e], p)| (e, p))\n}\n\n/// Finds the arguments of an `assert_eq!` or `debug_assert_eq!` macro call within the macro\n/// expansion\npub fn find_assert_eq_args<'a>(\n    cx: &LateContext<'_>,\n    expr: &'a Expr<'a>,\n    expn: ExpnId,\n) -> Option<(&'a Expr<'a>, &'a Expr<'a>, PanicCall<'a>)> {\n    find_assert_args_inner(cx, expr, expn).map(|([a, b], p)| (a, b, p))\n}\n\nfn find_assert_args_inner<'a, const N: usize>(\n    cx: &LateContext<'_>,\n    expr: &'a Expr<'a>,\n    expn: ExpnId,\n) -> Option<([&'a Expr<'a>; N], PanicCall<'a>)> {\n    let macro_id = expn.expn_data().macro_def_id?;\n    let (expr, expn) = match cx.tcx.item_name(macro_id).as_str().strip_prefix(\"debug_\") {\n        None => (expr, expn),\n        Some(inner_name) => find_assert_within_debug_assert(cx, expr, expn, Symbol::intern(inner_name))?,\n    };\n    let mut args = ArrayVec::new();\n    let panic_expn = for_each_expr_without_closures(expr, |e| {\n        if args.is_full() {\n            match PanicCall::parse(e) {\n                Some(expn) => ControlFlow::Break(expn),\n                None => ControlFlow::Continue(Descend::Yes),\n            }\n        } else if is_assert_arg(cx, e, expn) {\n            args.push(e);\n            ControlFlow::Continue(Descend::No)\n        } else {\n            ControlFlow::Continue(Descend::Yes)\n        }\n    });\n    let args = args.into_inner().ok()?;\n    Some((args, panic_expn?))\n}\n\nfn find_assert_within_debug_assert<'a>(\n    cx: &LateContext<'_>,\n    expr: &'a Expr<'a>,\n    expn: ExpnId,\n    assert_name: Symbol,\n) -> Option<(&'a Expr<'a>, ExpnId)> {\n    for_each_expr_without_closures(expr, |e| {\n        if !e.span.from_expansion() {\n            return ControlFlow::Continue(Descend::No);\n        }\n        let e_expn = e.span.ctxt().outer_expn();\n        if e_expn == expn {\n            ControlFlow::Continue(Descend::Yes)\n        } else if e_expn.expn_data().macro_def_id.map(|id| cx.tcx.item_name(id)) == Some(assert_name) {\n            ControlFlow::Break((e, e_expn))\n        } else {\n            ControlFlow::Continue(Descend::No)\n        }\n    })\n}\n\nfn is_assert_arg(cx: &LateContext<'_>, expr: &Expr<'_>, assert_expn: ExpnId) -> bool {\n    if !expr.span.from_expansion() {\n        return true;\n    }\n    let result = macro_backtrace(expr.span).try_for_each(|macro_call| {\n        if macro_call.expn == assert_expn {\n            ControlFlow::Break(false)\n        } else {\n            match cx.tcx.item_name(macro_call.def_id) {\n                // `cfg!(debug_assertions)` in `debug_assert!`\n                sym::cfg => ControlFlow::Continue(()),\n                // assert!(other_macro!(..))\n                _ => ControlFlow::Break(true),\n            }\n        }\n    });\n    match result {\n        ControlFlow::Break(is_assert_arg) => is_assert_arg,\n        ControlFlow::Continue(()) => true,\n    }\n}\n\n/// Stores AST [`FormatArgs`] nodes for use in late lint passes, as they are in a desugared form in\n/// the HIR\n#[derive(Default, Clone)]\npub struct FormatArgsStorage(Arc<OnceLock<FxHashMap<Span, FormatArgs>>>);\n\nimpl FormatArgsStorage {\n    /// Returns an AST [`FormatArgs`] node if a `format_args` expansion is found as a descendant of\n    /// `expn_id`\n    ///\n    /// See also [`find_format_arg_expr`]\n    pub fn get(&self, cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId) -> Option<&FormatArgs> {\n        let format_args_expr = for_each_expr_without_closures(start, |expr| {\n            let ctxt = expr.span.ctxt();\n            if ctxt.outer_expn().is_descendant_of(expn_id) {\n                if macro_backtrace(expr.span)\n                    .map(|macro_call| cx.tcx.item_name(macro_call.def_id))\n                    .any(|name| matches!(name, sym::const_format_args | sym::format_args | sym::format_args_nl))\n                {\n                    ControlFlow::Break(expr)\n                } else {\n                    ControlFlow::Continue(Descend::Yes)\n                }\n            } else {\n                ControlFlow::Continue(Descend::No)\n            }\n        })?;\n\n        debug_assert!(self.0.get().is_some(), \"`FormatArgsStorage` not yet populated\");\n\n        self.0.get()?.get(&format_args_expr.span.with_parent(None))\n    }\n\n    /// Should only be called by `FormatArgsCollector`\n    pub fn set(&self, format_args: FxHashMap<Span, FormatArgs>) {\n        self.0\n            .set(format_args)\n            .expect(\"`FormatArgsStorage::set` should only be called once\");\n    }\n}\n\n/// Attempt to find the [`rustc_hir::Expr`] that corresponds to the [`FormatArgument`]'s value\npub fn find_format_arg_expr<'hir>(start: &'hir Expr<'hir>, target: &FormatArgument) -> Option<&'hir Expr<'hir>> {\n    let SpanData {\n        lo,\n        hi,\n        ctxt,\n        parent: _,\n    } = target.expr.span.data();\n\n    for_each_expr_without_closures(start, |expr| {\n        // When incremental compilation is enabled spans gain a parent during AST to HIR lowering,\n        // since we're comparing an AST span to a HIR one we need to ignore the parent field\n        let data = expr.span.data();\n        if data.lo == lo && data.hi == hi && data.ctxt == ctxt {\n            ControlFlow::Break(expr)\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n}\n\n/// Span of the `:` and format specifiers\n///\n/// ```ignore\n/// format!(\"{:.}\"), format!(\"{foo:.}\")\n///           ^^                  ^^\n/// ```\npub fn format_placeholder_format_span(placeholder: &FormatPlaceholder) -> Option<Span> {\n    let base = placeholder.span?.data();\n\n    // `base.hi` is `{...}|`, subtract 1 byte (the length of '}') so that it points before the closing\n    // brace `{...|}`\n    Some(Span::new(\n        placeholder.argument.span?.hi(),\n        base.hi - BytePos(1),\n        base.ctxt,\n        base.parent,\n    ))\n}\n\n/// Span covering the format string and values\n///\n/// ```ignore\n/// format(\"{}.{}\", 10, 11)\n/// //     ^^^^^^^^^^^^^^^\n/// ```\npub fn format_args_inputs_span(format_args: &FormatArgs) -> Span {\n    match format_args.arguments.explicit_args() {\n        [] => format_args.span,\n        [.., last] => format_args\n            .span\n            .to(hygiene::walk_chain(last.expr.span, format_args.span.ctxt())),\n    }\n}\n\n/// Returns the [`Span`] of the value at `index` extended to the previous comma, e.g. for the value\n/// `10`\n///\n/// ```ignore\n/// format(\"{}.{}\", 10, 11)\n/// //            ^^^^\n/// ```\npub fn format_arg_removal_span(format_args: &FormatArgs, index: usize) -> Option<Span> {\n    let ctxt = format_args.span.ctxt();\n\n    let current = hygiene::walk_chain(format_args.arguments.by_index(index)?.expr.span, ctxt);\n\n    let prev = if index == 0 {\n        format_args.span\n    } else {\n        hygiene::walk_chain(format_args.arguments.by_index(index - 1)?.expr.span, ctxt)\n    };\n\n    Some(current.with_lo(prev.hi()))\n}\n\n/// Where a format parameter is being used in the format string\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum FormatParamUsage {\n    /// Appears as an argument, e.g. `format!(\"{}\", foo)`\n    Argument,\n    /// Appears as a width, e.g. `format!(\"{:width$}\", foo, width = 1)`\n    Width,\n    /// Appears as a precision, e.g. `format!(\"{:.precision$}\", foo, precision = 1)`\n    Precision,\n}\n\n/// A node with a `HirId` and a `Span`\npub trait HirNode {\n    fn hir_id(&self) -> HirId;\n    fn span(&self) -> Span;\n}\n\nmacro_rules! impl_hir_node {\n    ($($t:ident),*) => {\n        $(impl HirNode for hir::$t<'_> {\n            fn hir_id(&self) -> HirId {\n                self.hir_id\n            }\n            fn span(&self) -> Span {\n                self.span\n            }\n        })*\n    };\n}\n\nimpl_hir_node!(Expr, Pat);\n\nimpl HirNode for hir::Item<'_> {\n    fn hir_id(&self) -> HirId {\n        self.hir_id()\n    }\n\n    fn span(&self) -> Span {\n        self.span\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/mir/mod.rs",
    "content": "use std::iter;\n\nuse rustc_data_structures::either::Either;\nuse rustc_hir::{Expr, HirId};\nuse rustc_index::bit_set::DenseBitSet;\nuse rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};\nuse rustc_middle::mir::{\n    BasicBlock, Body, InlineAsmOperand, Local, Location, Place, START_BLOCK, StatementKind, TerminatorKind, traversal,\n};\nuse rustc_middle::ty::TyCtxt;\n\nmod possible_borrower;\npub use possible_borrower::PossibleBorrowerMap;\n\nmod possible_origin;\n\nmod transitive_relation;\n\n#[derive(Clone, Debug, Default)]\npub struct LocalUsage {\n    /// The locations where the local is used, if any.\n    pub local_use_locs: Vec<Location>,\n    /// The locations where the local is consumed or mutated, if any.\n    pub local_consume_or_mutate_locs: Vec<Location>,\n}\n\npub fn visit_local_usage<const N: usize>(\n    locals: [Local; N],\n    mir: &Body<'_>,\n    location: Location,\n) -> Option<[LocalUsage; N]> {\n    let init = [const {\n        LocalUsage {\n            local_use_locs: Vec::new(),\n            local_consume_or_mutate_locs: Vec::new(),\n        }\n    }; N];\n\n    traversal::Postorder::new(&mir.basic_blocks, location.block, None)\n        .collect::<Vec<_>>()\n        .into_iter()\n        .rev()\n        .try_fold(init, |usage, tbb| {\n            let tdata = &mir.basic_blocks[tbb];\n\n            // Give up on loops\n            if tdata.terminator().successors().any(|s| s == location.block) {\n                return None;\n            }\n\n            let mut v = V {\n                locals: &locals,\n                location,\n                results: usage,\n            };\n            v.visit_basic_block_data(tbb, tdata);\n            Some(v.results)\n        })\n}\n\nstruct V<'a, const N: usize> {\n    locals: &'a [Local; N],\n    location: Location,\n    results: [LocalUsage; N],\n}\n\nimpl<'tcx, const N: usize> Visitor<'tcx> for V<'_, N> {\n    fn visit_place(&mut self, place: &Place<'tcx>, ctx: PlaceContext, loc: Location) {\n        if loc.block == self.location.block && loc.statement_index <= self.location.statement_index {\n            return;\n        }\n\n        let local = place.local;\n\n        for (self_local, result) in iter::zip(self.locals, &mut self.results) {\n            if local == *self_local {\n                if !matches!(\n                    ctx,\n                    PlaceContext::MutatingUse(MutatingUseContext::Drop) | PlaceContext::NonUse(_)\n                ) {\n                    result.local_use_locs.push(loc);\n                }\n                if matches!(\n                    ctx,\n                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Move | NonMutatingUseContext::Inspect)\n                        | PlaceContext::MutatingUse(MutatingUseContext::Borrow)\n                ) {\n                    result.local_consume_or_mutate_locs.push(loc);\n                }\n            }\n        }\n    }\n}\n\n/// Checks if the block is part of a cycle\npub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool {\n    let mut seen = DenseBitSet::new_empty(body.basic_blocks.len());\n    let mut to_visit = Vec::with_capacity(body.basic_blocks.len() / 2);\n\n    seen.insert(block);\n    let mut next = block;\n    loop {\n        for succ in body.basic_blocks[next].terminator().successors() {\n            if seen.insert(succ) {\n                to_visit.push(succ);\n            } else if succ == block {\n                return true;\n            }\n        }\n\n        if let Some(x) = to_visit.pop() {\n            next = x;\n        } else {\n            return false;\n        }\n    }\n}\n\n/// Convenience wrapper around `visit_local_usage`.\npub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option<bool> {\n    visit_local_usage(\n        [local],\n        mir,\n        Location {\n            block: START_BLOCK,\n            statement_index: 0,\n        },\n    )\n    .map(|[local_usage]| {\n        let mut locations = local_usage\n            .local_use_locs\n            .into_iter()\n            .filter(|&location| !is_local_assignment(mir, local, location));\n        if let Some(location) = locations.next() {\n            locations.next().is_none() && !block_in_cycle(mir, location.block)\n        } else {\n            false\n        }\n    })\n}\n\n/// Returns the `mir::Body` containing the node associated with `hir_id`.\n#[expect(clippy::module_name_repetitions)]\npub fn enclosing_mir(tcx: TyCtxt<'_>, hir_id: HirId) -> Option<&Body<'_>> {\n    let body_owner_local_def_id = tcx.hir_enclosing_body_owner(hir_id);\n    if tcx.hir_body_owner_kind(body_owner_local_def_id).is_fn_or_closure() {\n        Some(tcx.optimized_mir(body_owner_local_def_id.to_def_id()))\n    } else {\n        None\n    }\n}\n\n/// Tries to determine the `Local` corresponding to `expr`, if any.\n/// This function is expensive and should be used sparingly.\npub fn expr_local(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> Option<Local> {\n    enclosing_mir(tcx, expr.hir_id).and_then(|mir| {\n        mir.local_decls.iter_enumerated().find_map(|(local, local_decl)| {\n            if local_decl.source_info.span == expr.span {\n                Some(local)\n            } else {\n                None\n            }\n        })\n    })\n}\n\n/// Returns a vector of `mir::Location` where `local` is assigned.\npub fn local_assignments(mir: &Body<'_>, local: Local) -> Vec<Location> {\n    let mut locations = Vec::new();\n    for (block, data) in mir.basic_blocks.iter_enumerated() {\n        for statement_index in 0..=data.statements.len() {\n            let location = Location { block, statement_index };\n            if is_local_assignment(mir, local, location) {\n                locations.push(location);\n            }\n        }\n    }\n    locations\n}\n\n// `is_local_assignment` is based on `is_place_assignment`:\n// https://github.com/rust-lang/rust/blob/b7413511dc85ec01ef4b91785f86614589ac6103/compiler/rustc_middle/src/mir/visit.rs#L1350\nfn is_local_assignment(mir: &Body<'_>, local: Local, location: Location) -> bool {\n    match mir.stmt_at(location) {\n        Either::Left(statement) => {\n            if let StatementKind::Assign(box (place, _)) = statement.kind {\n                place.as_local() == Some(local)\n            } else {\n                false\n            }\n        },\n        Either::Right(terminator) => match &terminator.kind {\n            TerminatorKind::Call { destination, .. } => destination.as_local() == Some(local),\n            TerminatorKind::InlineAsm { operands, .. } => operands.iter().any(|operand| {\n                if let InlineAsmOperand::Out { place: Some(place), .. } = operand {\n                    place.as_local() == Some(local)\n                } else {\n                    false\n                }\n            }),\n            _ => false,\n        },\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/mir/possible_borrower.rs",
    "content": "use super::possible_origin::PossibleOriginVisitor;\nuse super::transitive_relation::TransitiveRelation;\nuse crate::ty::is_copy;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_index::bit_set::DenseBitSet;\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::visit::Visitor as _;\nuse rustc_middle::mir::{self, Mutability};\nuse rustc_middle::ty::{self, TyCtxt, TypeVisitor};\nuse rustc_mir_dataflow::impls::MaybeStorageLive;\nuse rustc_mir_dataflow::{Analysis, ResultsCursor};\nuse std::borrow::Cow;\nuse std::ops::ControlFlow;\n\n/// Collects the possible borrowers of each local.\n/// For example, `b = &a; c = &a;` will make `b` and (transitively) `c`\n/// possible borrowers of `a`.\nstruct PossibleBorrowerVisitor<'a, 'b, 'tcx> {\n    possible_borrower: TransitiveRelation,\n    body: &'b mir::Body<'tcx>,\n    cx: &'a LateContext<'tcx>,\n    possible_origin: FxHashMap<mir::Local, DenseBitSet<mir::Local>>,\n}\n\nimpl<'a, 'b, 'tcx> PossibleBorrowerVisitor<'a, 'b, 'tcx> {\n    fn new(\n        cx: &'a LateContext<'tcx>,\n        body: &'b mir::Body<'tcx>,\n        possible_origin: FxHashMap<mir::Local, DenseBitSet<mir::Local>>,\n    ) -> Self {\n        Self {\n            possible_borrower: TransitiveRelation::default(),\n            body,\n            cx,\n            possible_origin,\n        }\n    }\n\n    fn into_map(\n        self,\n        cx: &'a LateContext<'tcx>,\n        maybe_live: ResultsCursor<'b, 'tcx, MaybeStorageLive<'tcx>>,\n    ) -> PossibleBorrowerMap<'b, 'tcx> {\n        let mut map = FxHashMap::default();\n        for row in (1..self.body.local_decls.len()).map(mir::Local::from_usize) {\n            if is_copy(cx, self.body.local_decls[row].ty) {\n                continue;\n            }\n\n            let mut borrowers = self.possible_borrower.reachable_from(row, self.body.local_decls.len());\n            borrowers.remove(mir::Local::from_usize(0));\n            if !borrowers.is_empty() {\n                map.insert(row, borrowers);\n            }\n        }\n\n        let bs = DenseBitSet::new_empty(self.body.local_decls.len());\n        PossibleBorrowerMap {\n            map,\n            maybe_live,\n            bitset: (bs.clone(), bs),\n        }\n    }\n}\n\nimpl<'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'_, '_, 'tcx> {\n    fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {\n        let lhs = place.local;\n        match rvalue {\n            mir::Rvalue::Ref(_, _, borrowed) | mir::Rvalue::CopyForDeref(borrowed) => {\n                self.possible_borrower.add(borrowed.local, lhs);\n            },\n            other => {\n                if ContainsRegion\n                    .visit_ty(place.ty(&self.body.local_decls, self.cx.tcx).ty)\n                    .is_continue()\n                {\n                    return;\n                }\n                rvalue_locals(other, |rhs| {\n                    if lhs != rhs {\n                        self.possible_borrower.add(rhs, lhs);\n                    }\n                });\n            },\n        }\n    }\n\n    fn visit_terminator(&mut self, terminator: &mir::Terminator<'_>, _loc: mir::Location) {\n        if let mir::TerminatorKind::Call {\n            args,\n            destination: mir::Place { local: dest, .. },\n            ..\n        } = &terminator.kind\n        {\n            // TODO add doc\n            // If the call returns something with lifetimes,\n            // let's conservatively assume the returned value contains lifetime of all the arguments.\n            // For example, given `let y: Foo<'a> = foo(x)`, `y` is considered to be a possible borrower of `x`.\n\n            let mut immutable_borrowers = vec![];\n            let mut mutable_borrowers = vec![];\n\n            for op in args {\n                match &op.node {\n                    mir::Operand::Copy(p) | mir::Operand::Move(p) => {\n                        if let ty::Ref(_, _, Mutability::Mut) = self.body.local_decls[p.local].ty.kind() {\n                            mutable_borrowers.push(p.local);\n                        } else {\n                            immutable_borrowers.push(p.local);\n                        }\n                    },\n                    mir::Operand::Constant(..) | mir::Operand::RuntimeChecks(..) => (),\n                }\n            }\n\n            let mut mutable_variables: Vec<mir::Local> = mutable_borrowers\n                .iter()\n                .filter_map(|r| self.possible_origin.get(r))\n                .flat_map(DenseBitSet::iter)\n                .collect();\n\n            if ContainsRegion.visit_ty(self.body.local_decls[*dest].ty).is_break() {\n                mutable_variables.push(*dest);\n            }\n\n            for y in mutable_variables {\n                for x in &immutable_borrowers {\n                    self.possible_borrower.add(*x, y);\n                }\n                for x in &mutable_borrowers {\n                    self.possible_borrower.add(*x, y);\n                }\n            }\n        }\n    }\n}\n\nstruct ContainsRegion;\n\nimpl TypeVisitor<TyCtxt<'_>> for ContainsRegion {\n    type Result = ControlFlow<()>;\n\n    fn visit_region(&mut self, _: ty::Region<'_>) -> Self::Result {\n        ControlFlow::Break(())\n    }\n}\n\nfn rvalue_locals(rvalue: &mir::Rvalue<'_>, mut visit: impl FnMut(mir::Local)) {\n    use rustc_middle::mir::Rvalue::{Aggregate, BinaryOp, Cast, Repeat, UnaryOp, Use};\n\n    let mut visit_op = |op: &mir::Operand<'_>| match op {\n        mir::Operand::Copy(p) | mir::Operand::Move(p) => visit(p.local),\n        mir::Operand::Constant(..) | mir::Operand::RuntimeChecks(..) => (),\n    };\n\n    match rvalue {\n        Use(op) | Repeat(op, _) | Cast(_, op, _) | UnaryOp(_, op) => visit_op(op),\n        Aggregate(_, ops) => ops.iter().for_each(visit_op),\n        BinaryOp(_, box (lhs, rhs)) => {\n            visit_op(lhs);\n            visit_op(rhs);\n        },\n        _ => (),\n    }\n}\n\n/// Result of `PossibleBorrowerVisitor`.\npub struct PossibleBorrowerMap<'b, 'tcx> {\n    /// Mapping `Local -> its possible borrowers`\n    pub map: FxHashMap<mir::Local, DenseBitSet<mir::Local>>,\n    maybe_live: ResultsCursor<'b, 'tcx, MaybeStorageLive<'tcx>>,\n    // Caches to avoid allocation of `DenseBitSet` on every query\n    pub bitset: (DenseBitSet<mir::Local>, DenseBitSet<mir::Local>),\n}\n\nimpl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {\n    pub fn new(cx: &LateContext<'tcx>, mir: &'b mir::Body<'tcx>) -> Self {\n        let possible_origin = {\n            let mut vis = PossibleOriginVisitor::new(mir);\n            vis.visit_body(mir);\n            vis.into_map(cx)\n        };\n        let maybe_storage_live_result =\n            MaybeStorageLive::new(Cow::Owned(DenseBitSet::new_empty(mir.local_decls.len())))\n                .iterate_to_fixpoint(cx.tcx, mir, Some(\"redundant_clone\"))\n                .into_results_cursor(mir);\n        let mut vis = PossibleBorrowerVisitor::new(cx, mir, possible_origin);\n        vis.visit_body(mir);\n        vis.into_map(cx, maybe_storage_live_result)\n    }\n\n    /// Returns true if the set of borrowers of `borrowed` living at `at` matches with `borrowers`.\n    pub fn only_borrowers(&mut self, borrowers: &[mir::Local], borrowed: mir::Local, at: mir::Location) -> bool {\n        self.bounded_borrowers(borrowers, borrowers, borrowed, at)\n    }\n\n    /// Returns true if the set of borrowers of `borrowed` living at `at` includes at least `below`\n    /// but no more than `above`.\n    pub fn bounded_borrowers(\n        &mut self,\n        below: &[mir::Local],\n        above: &[mir::Local],\n        borrowed: mir::Local,\n        at: mir::Location,\n    ) -> bool {\n        self.maybe_live.seek_after_primary_effect(at);\n\n        self.bitset.0.clear();\n        let maybe_live = &mut self.maybe_live;\n        if let Some(bitset) = self.map.get(&borrowed) {\n            for b in bitset.iter().filter(move |b| maybe_live.get().contains(*b)) {\n                self.bitset.0.insert(b);\n            }\n        } else {\n            return false;\n        }\n\n        self.bitset.1.clear();\n        for b in below {\n            self.bitset.1.insert(*b);\n        }\n\n        if !self.bitset.0.superset(&self.bitset.1) {\n            return false;\n        }\n\n        for b in above {\n            self.bitset.0.remove(*b);\n        }\n\n        self.bitset.0.is_empty()\n    }\n\n    pub fn local_is_alive_at(&mut self, local: mir::Local, at: mir::Location) -> bool {\n        self.maybe_live.seek_after_primary_effect(at);\n        self.maybe_live.get().contains(local)\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/mir/possible_origin.rs",
    "content": "use super::transitive_relation::TransitiveRelation;\nuse crate::ty::is_copy;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_index::bit_set::DenseBitSet;\nuse rustc_lint::LateContext;\nuse rustc_middle::mir;\n\n/// Collect possible borrowed for every `&mut` local.\n/// For example, `_1 = &mut _2` generate _1: {_2,...}\n/// Known Problems: not sure all borrowed are tracked\npub(super) struct PossibleOriginVisitor<'a, 'tcx> {\n    possible_origin: TransitiveRelation,\n    body: &'a mir::Body<'tcx>,\n}\n\nimpl<'a, 'tcx> PossibleOriginVisitor<'a, 'tcx> {\n    pub fn new(body: &'a mir::Body<'tcx>) -> Self {\n        Self {\n            possible_origin: TransitiveRelation::default(),\n            body,\n        }\n    }\n\n    pub fn into_map(self, cx: &LateContext<'tcx>) -> FxHashMap<mir::Local, DenseBitSet<mir::Local>> {\n        let mut map = FxHashMap::default();\n        for row in (1..self.body.local_decls.len()).map(mir::Local::from_usize) {\n            if is_copy(cx, self.body.local_decls[row].ty) {\n                continue;\n            }\n\n            let mut borrowers = self.possible_origin.reachable_from(row, self.body.local_decls.len());\n            borrowers.remove(mir::Local::from_usize(0));\n            if !borrowers.is_empty() {\n                map.insert(row, borrowers);\n            }\n        }\n        map\n    }\n}\n\nimpl<'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'_, 'tcx> {\n    fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {\n        let lhs = place.local;\n        match rvalue {\n            // Only consider `&mut`, which can modify origin place\n            mir::Rvalue::Ref(_, mir::BorrowKind::Mut { .. }, borrowed) |\n            // _2: &mut _;\n            // _3 = move _2\n            mir::Rvalue::Use(mir::Operand::Move(borrowed))  |\n            // _3 = move _2 as &mut _;\n            mir::Rvalue::Cast(_, mir::Operand::Move(borrowed), _)\n                => {\n                self.possible_origin.add(lhs, borrowed.local);\n            },\n            _ => {},\n        }\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/mir/transitive_relation.rs",
    "content": "use rustc_data_structures::fx::FxHashMap;\nuse rustc_index::bit_set::DenseBitSet;\nuse rustc_middle::mir;\n\n#[derive(Default)]\npub(super) struct TransitiveRelation {\n    relations: FxHashMap<mir::Local, Vec<mir::Local>>,\n}\n\nimpl TransitiveRelation {\n    pub fn add(&mut self, a: mir::Local, b: mir::Local) {\n        self.relations.entry(a).or_default().push(b);\n    }\n\n    pub fn reachable_from(&self, a: mir::Local, domain_size: usize) -> DenseBitSet<mir::Local> {\n        let mut seen = DenseBitSet::new_empty(domain_size);\n        let mut stack = vec![a];\n        while let Some(u) = stack.pop() {\n            if let Some(edges) = self.relations.get(&u) {\n                for &v in edges {\n                    if seen.insert(v) {\n                        stack.push(v);\n                    }\n                }\n            }\n        }\n        seen\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/msrvs.rs",
    "content": "use crate::sym;\nuse rustc_ast::Attribute;\nuse rustc_ast::attr::AttributeExt;\nuse rustc_attr_parsing::parse_version;\nuse rustc_data_structures::smallvec::SmallVec;\nuse rustc_hir::RustcVersion;\nuse rustc_lint::LateContext;\nuse rustc_session::Session;\nuse rustc_span::Symbol;\nuse serde::Deserialize;\nuse std::iter::once;\nuse std::sync::atomic::{AtomicBool, Ordering};\n\nmacro_rules! msrv_aliases {\n    ($($major:literal,$minor:literal,$patch:literal {\n        $($name:ident),* $(,)?\n    })*) => {\n        $($(\n        pub const $name: RustcVersion = RustcVersion { major: $major, minor :$minor, patch: $patch };\n        )*)*\n    };\n}\n\n// names may refer to stabilized feature flags or library items\nmsrv_aliases! {\n    1,93,0 { VEC_DEQUE_POP_BACK_IF, VEC_DEQUE_POP_FRONT_IF }\n    1,91,0 { DURATION_FROM_MINUTES_HOURS }\n    1,88,0 { LET_CHAINS }\n    1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT, CONST_CHAR_IS_DIGIT, UNSIGNED_IS_MULTIPLE_OF, INTEGER_SIGN_CAST }\n    1,86,0 { VEC_POP_IF }\n    1,85,0 { UINT_FLOAT_MIDPOINT, CONST_SIZE_OF_VAL }\n    1,84,0 { CONST_OPTION_AS_SLICE, MANUAL_DANGLING_PTR }\n    1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP }\n    1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP, SPECIALIZED_TO_STRING_FOR_REFS }\n    1,81,0 { LINT_REASONS_STABILIZATION, ERROR_IN_CORE, EXPLICIT_SELF_TYPE_ELISION, DURATION_ABS_DIFF }\n    1,80,0 { BOX_INTO_ITER, LAZY_CELL }\n    1,79,0 { CONST_BLOCKS, CSTR_COUNT_BYTES }\n    1,77,0 { C_STR_LITERALS }\n    1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }\n    1,75,0 { OPTION_AS_SLICE }\n    1,74,0 { REPR_RUST, IO_ERROR_OTHER }\n    1,73,0 { DIV_CEIL }\n    1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }\n    1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN }\n    1,68,0 { PATH_MAIN_SEPARATOR_STR }\n    1,67,0 { ILOG2 }\n    1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }\n    1,63,0 { CLONE_INTO, CONST_SLICE_FROM_REF }\n    1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE, CONST_EXTERN_C_FN }\n    1,61,0 { CONST_FN_TRAIT_BOUND }\n    1,60,0 { ABS_DIFF }\n    1,59,0 { THREAD_LOCAL_CONST_INIT }\n    1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY, CONST_RAW_PTR_DEREF }\n    1,57,0 { MAP_WHILE, CONST_PANIC }\n    1,56,0 { CONST_FN_UNION }\n    1,55,0 { SEEK_REWIND }\n    1,54,0 { INTO_KEYS }\n    1,53,0 { OR_PATTERNS, INTEGER_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR }\n    1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST }\n    1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS }\n    1,50,0 { BOOL_THEN, CLAMP, SLICE_FILL }\n    1,47,0 { TAU, IS_ASCII_DIGIT_CONST, ARRAY_IMPL_ANY_LEN, SATURATING_SUB_CONST }\n    1,46,0 { CONST_IF_MATCH }\n    1,45,0 { STR_STRIP_PREFIX }\n    1,43,0 { LOG2_10, LOG10_2, NUMERIC_ASSOCIATED_CONSTANTS }\n    1,42,0 { MATCHES_MACRO, SLICE_PATTERNS, PTR_SLICE_RAW_PARTS }\n    1,41,0 { RE_REBALANCING_COHERENCE, RESULT_MAP_OR, RESULT_MAP_OR_ELSE }\n    1,40,0 { MEM_TAKE, NON_EXHAUSTIVE, OPTION_AS_DEREF }\n    1,38,0 { POINTER_CAST, REM_EUCLID }\n    1,37,0 { TYPE_ALIAS_ENUM_VARIANTS }\n    1,36,0 { ITERATOR_COPIED }\n    1,35,0 { OPTION_COPIED, RANGE_CONTAINS }\n    1,34,0 { TRY_FROM }\n    1,33,0 { UNDERSCORE_IMPORTS }\n    1,32,0 { CONST_IS_POWER_OF_TWO, CONST_DURATION_FROM_NANOS_MICROS_MILLIS_SECS }\n    1,31,0 { OPTION_REPLACE }\n    1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES }\n    1,29,0 { ITER_FLATTEN }\n    1,28,0 { FROM_BOOL, REPEAT_WITH, SLICE_FROM_REF }\n    1,27,0 { ITERATOR_TRY_FOLD, DOUBLE_ENDED_ITERATOR_RFIND, DURATION_FROM_NANOS_MICROS }\n    1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN, POINTER_ADD_SUB_METHODS }\n    1,24,0 { IS_ASCII_DIGIT, PTR_NULL }\n    1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN }\n    1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }\n    1,16,0 { STR_REPEAT, RESULT_UNWRAP_OR_DEFAULT }\n    1,15,0 { MAYBE_BOUND_IN_WHERE }\n    1,13,0 { QUESTION_MARK_OPERATOR }\n    1,3,0 { DURATION_FROM_MILLIS_SECS }\n}\n\n/// `#[clippy::msrv]` attributes are rarely used outside of Clippy's test suite, as a basic\n/// optimization we can skip traversing the HIR in [`Msrv::meets`] if we never saw an MSRV attribute\n/// during the early lint passes\nstatic SEEN_MSRV_ATTR: AtomicBool = AtomicBool::new(false);\n\n/// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]` in late\n/// lint passes, use [`MsrvStack`] for early passes\n#[derive(Copy, Clone, Debug, Default)]\npub struct Msrv(Option<RustcVersion>);\n\nimpl<'de> Deserialize<'de> for Msrv {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        let v = String::deserialize(deserializer)?;\n        parse_version(Symbol::intern(&v))\n            .map(|v| Self(Some(v)))\n            .ok_or_else(|| serde::de::Error::custom(\"not a valid Rust version\"))\n    }\n}\n\nimpl Msrv {\n    /// Returns the MSRV at the current node\n    ///\n    /// If the crate being linted uses an `#[clippy::msrv]` attribute this will search the parent\n    /// nodes for that attribute, prefer to run this check after cheaper pattern matching operations\n    pub fn current(self, cx: &LateContext<'_>) -> Option<RustcVersion> {\n        if SEEN_MSRV_ATTR.load(Ordering::Relaxed) {\n            let start = cx.last_node_with_lint_attrs;\n            if let Some(msrv_attr) = once(start)\n                .chain(cx.tcx.hir_parent_id_iter(start))\n                .find_map(|id| parse_attrs(cx.tcx.sess, cx.tcx.hir_attrs(id)))\n            {\n                return Some(msrv_attr);\n            }\n        }\n\n        self.0\n    }\n\n    /// Checks if a required version from [this module](self) is met at the current node\n    ///\n    /// If the crate being linted uses an `#[clippy::msrv]` attribute this will search the parent\n    /// nodes for that attribute, prefer to run this check after cheaper pattern matching operations\n    pub fn meets(self, cx: &LateContext<'_>, required: RustcVersion) -> bool {\n        self.current(cx).is_none_or(|msrv| msrv >= required)\n    }\n\n    pub fn read_cargo(&mut self, sess: &Session) {\n        let cargo_msrv = std::env::var(\"CARGO_PKG_RUST_VERSION\")\n            .ok()\n            .and_then(|v| parse_version(Symbol::intern(&v)));\n\n        match (self.0, cargo_msrv) {\n            (None, Some(cargo_msrv)) => self.0 = Some(cargo_msrv),\n            (Some(clippy_msrv), Some(cargo_msrv)) if clippy_msrv != cargo_msrv => {\n                sess.dcx().warn(format!(\n                    \"the MSRV in `clippy.toml` and `Cargo.toml` differ; using `{clippy_msrv}` from `clippy.toml`\"\n                ));\n            },\n            _ => {},\n        }\n    }\n}\n\n/// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]` in early\n/// lint passes, use [`Msrv`] for late passes\n#[derive(Debug, Clone)]\npub struct MsrvStack {\n    stack: SmallVec<[RustcVersion; 2]>,\n}\n\nimpl MsrvStack {\n    pub fn new(initial: Msrv) -> Self {\n        Self {\n            stack: SmallVec::from_iter(initial.0),\n        }\n    }\n\n    pub fn current(&self) -> Option<RustcVersion> {\n        self.stack.last().copied()\n    }\n\n    pub fn meets(&self, required: RustcVersion) -> bool {\n        self.current().is_none_or(|msrv| msrv >= required)\n    }\n\n    pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) {\n        if let Some(version) = parse_attrs(sess, attrs) {\n            SEEN_MSRV_ATTR.store(true, Ordering::Relaxed);\n            self.stack.push(version);\n        }\n    }\n\n    pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) {\n        if parse_attrs(sess, attrs).is_some() {\n            self.stack.pop();\n        }\n    }\n}\n\nfn parse_attrs(sess: &Session, attrs: &[impl AttributeExt]) -> Option<RustcVersion> {\n    let mut msrv_attrs = attrs.iter().filter(|attr| attr.path_matches(&[sym::clippy, sym::msrv]));\n\n    let msrv_attr = msrv_attrs.next()?;\n\n    if let Some(duplicate) = msrv_attrs.next_back() {\n        sess.dcx()\n            .struct_span_err(duplicate.span(), \"`clippy::msrv` is defined multiple times\")\n            .with_span_note(msrv_attr.span(), \"first definition found here\")\n            .emit();\n    }\n\n    let Some(msrv) = msrv_attr.value_str() else {\n        sess.dcx().span_err(msrv_attr.span(), \"bad clippy attribute\");\n        return None;\n    };\n\n    let Some(version) = parse_version(msrv) else {\n        sess.dcx()\n            .span_err(msrv_attr.span(), format!(\"`{msrv}` is not a valid Rust version\"));\n        return None;\n    };\n\n    Some(version)\n}\n"
  },
  {
    "path": "clippy_utils/src/numeric_literal.rs",
    "content": "use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};\nuse std::iter;\n\n/// Represents the base of a numeric literal, used for parsing and formatting.\n#[derive(Debug, PartialEq, Eq, Copy, Clone)]\npub enum Radix {\n    /// A binary literal (e.g., `0b1010`)\n    Binary,\n    /// An octal literal (e.g., `0o670`)\n    Octal,\n    /// A decimal literal (e.g., `123`)\n    Decimal,\n    /// A hexadecimal literal (e.g., `0xFF`)\n    Hexadecimal,\n}\n\nimpl Radix {\n    /// Returns a reasonable digit group size for this radix.\n    #[must_use]\n    fn suggest_grouping(self) -> usize {\n        match self {\n            Self::Binary | Self::Hexadecimal => 4,\n            Self::Octal | Self::Decimal => 3,\n        }\n    }\n}\n\n/// A helper method to format numeric literals with digit grouping.\n/// `lit` must be a valid numeric literal without suffix.\npub fn format(lit: &str, type_suffix: Option<&str>, float: bool) -> String {\n    NumericLiteral::new(lit, type_suffix, float).format()\n}\n\n#[derive(Debug)]\npub struct NumericLiteral<'a> {\n    /// Which radix the literal was represented in.\n    pub radix: Radix,\n    /// The radix prefix, if present.\n    pub prefix: Option<&'a str>,\n\n    /// The integer part of the number.\n    pub integer: &'a str,\n    /// The fraction part of the number.\n    pub fraction: Option<&'a str>,\n    /// The exponent separator (b'e' or b'E') including preceding underscore if present\n    /// and the exponent part.\n    pub exponent: Option<(&'a str, &'a str)>,\n\n    /// The type suffix, including preceding underscore if present.\n    pub suffix: Option<&'a str>,\n}\n\nimpl<'a> NumericLiteral<'a> {\n    /// Attempts to parse a `NumericLiteral` from the source string of an `ast::LitKind`.\n    pub fn from_lit_kind(src: &'a str, lit_kind: &LitKind) -> Option<NumericLiteral<'a>> {\n        let unsigned_src = src.strip_prefix('-').map_or(src, |s| s);\n        if lit_kind.is_numeric()\n            && unsigned_src\n                .trim_start()\n                .chars()\n                .next()\n                .is_some_and(|c| c.is_ascii_digit())\n        {\n            let (unsuffixed, suffix) = split_suffix(src, lit_kind);\n            let float = matches!(lit_kind, LitKind::Float(..));\n            Some(NumericLiteral::new(unsuffixed, suffix, float))\n        } else {\n            None\n        }\n    }\n\n    /// Parses a raw numeric literal string into its structured `NumericLiteral` parts.\n    #[must_use]\n    pub fn new(lit: &'a str, suffix: Option<&'a str>, float: bool) -> Self {\n        let unsigned_lit = lit.trim_start_matches('-');\n        // Determine delimiter for radix prefix, if present, and radix.\n        let radix = if unsigned_lit.starts_with(\"0x\") {\n            Radix::Hexadecimal\n        } else if unsigned_lit.starts_with(\"0b\") {\n            Radix::Binary\n        } else if unsigned_lit.starts_with(\"0o\") {\n            Radix::Octal\n        } else {\n            Radix::Decimal\n        };\n\n        // Grab part of the literal after prefix, if present.\n        let (prefix, mut sans_prefix) = if radix == Radix::Decimal {\n            (None, lit)\n        } else {\n            let (p, s) = lit.split_at(2);\n            (Some(p), s)\n        };\n\n        if suffix.is_some() && sans_prefix.ends_with('_') {\n            // The '_' before the suffix isn't part of the digits\n            sans_prefix = &sans_prefix[..sans_prefix.len() - 1];\n        }\n\n        let (integer, fraction, exponent) = Self::split_digit_parts(sans_prefix, float);\n\n        Self {\n            radix,\n            prefix,\n            integer,\n            fraction,\n            exponent,\n            suffix,\n        }\n    }\n\n    /// Checks if the literal's radix is `Radix::Decimal`\n    pub fn is_decimal(&self) -> bool {\n        self.radix == Radix::Decimal\n    }\n\n    fn split_digit_parts(digits: &str, float: bool) -> (&str, Option<&str>, Option<(&str, &str)>) {\n        let mut integer = digits;\n        let mut fraction = None;\n        let mut exponent = None;\n\n        if float {\n            for (i, c) in digits.char_indices() {\n                match c {\n                    '.' => {\n                        integer = &digits[..i];\n                        fraction = Some(&digits[i + 1..]);\n                    },\n                    'e' | 'E' => {\n                        let exp_start = if digits[..i].ends_with('_') { i - 1 } else { i };\n\n                        if integer.len() > exp_start {\n                            integer = &digits[..exp_start];\n                        } else {\n                            fraction = Some(&digits[integer.len() + 1..exp_start]);\n                        }\n                        exponent = Some((&digits[exp_start..=i], &digits[i + 1..]));\n                        break;\n                    },\n                    _ => {},\n                }\n            }\n        }\n\n        (integer, fraction, exponent)\n    }\n\n    /// Returns literal formatted in a sensible way.\n    pub fn format(&self) -> String {\n        let mut output = String::new();\n\n        if let Some(prefix) = self.prefix {\n            output.push_str(prefix);\n        }\n\n        let group_size = self.radix.suggest_grouping();\n\n        Self::group_digits(\n            &mut output,\n            self.integer,\n            group_size,\n            true,\n            self.radix == Radix::Hexadecimal,\n        );\n\n        if let Some(fraction) = self.fraction {\n            output.push('.');\n            Self::group_digits(&mut output, fraction, group_size, false, false);\n        }\n\n        if let Some((separator, exponent)) = self.exponent {\n            if !exponent.is_empty() && exponent != \"0\" {\n                output.push_str(separator);\n                Self::group_digits(&mut output, exponent, group_size, true, false);\n            } else if exponent == \"0\" && self.fraction.is_none() && self.suffix.is_none() {\n                output.push_str(\".0\");\n            }\n        }\n\n        if let Some(suffix) = self.suffix {\n            if output.ends_with('.') {\n                output.push('0');\n            }\n            output.push('_');\n            output.push_str(suffix);\n        }\n\n        output\n    }\n\n    fn group_digits(output: &mut String, input: &str, group_size: usize, partial_group_first: bool, zero_pad: bool) {\n        debug_assert!(group_size > 0);\n\n        let mut digits = input.chars().filter(|&c| c != '_');\n\n        // The exponent may have a sign, output it early, otherwise it will be\n        // treated as a digit\n        if digits.clone().next() == Some('-') {\n            let _: Option<char> = digits.next();\n            output.push('-');\n        }\n\n        let first_group_size;\n\n        if partial_group_first {\n            first_group_size = (digits.clone().count() - 1) % group_size + 1;\n            if zero_pad {\n                for _ in 0..group_size - first_group_size {\n                    output.push('0');\n                }\n            }\n        } else {\n            first_group_size = group_size;\n        }\n\n        for _ in 0..first_group_size {\n            if let Some(digit) = digits.next() {\n                output.push(digit);\n            }\n        }\n\n        for (c, i) in iter::zip(digits, (0..group_size).cycle()) {\n            if i == 0 {\n                output.push('_');\n            }\n            output.push(c);\n        }\n    }\n}\n\nfn split_suffix<'a>(src: &'a str, lit_kind: &LitKind) -> (&'a str, Option<&'a str>) {\n    debug_assert!(lit_kind.is_numeric());\n    lit_suffix_length(lit_kind)\n        .and_then(|suffix_length| src.len().checked_sub(suffix_length))\n        .map_or((src, None), |split_pos| {\n            let (unsuffixed, suffix) = src.split_at(split_pos);\n            (unsuffixed, Some(suffix))\n        })\n}\n\nfn lit_suffix_length(lit_kind: &LitKind) -> Option<usize> {\n    debug_assert!(lit_kind.is_numeric());\n    let suffix = match lit_kind {\n        LitKind::Int(_, int_lit_kind) => match int_lit_kind {\n            LitIntType::Signed(int_ty) => Some(int_ty.name_str()),\n            LitIntType::Unsigned(uint_ty) => Some(uint_ty.name_str()),\n            LitIntType::Unsuffixed => None,\n        },\n        LitKind::Float(_, float_lit_kind) => match float_lit_kind {\n            LitFloatType::Suffixed(float_ty) => Some(float_ty.name_str()),\n            LitFloatType::Unsuffixed => None,\n        },\n        _ => None,\n    };\n\n    suffix.map(str::len)\n}\n"
  },
  {
    "path": "clippy_utils/src/paths.rs",
    "content": "//! This module contains paths to types and functions Clippy needs to know\n//! about.\n//!\n//! Whenever possible, please consider diagnostic items over hardcoded paths.\n//! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.\n\nuse crate::res::MaybeQPath;\nuse crate::sym;\nuse rustc_ast::Mutability;\nuse rustc_data_structures::fx::FxHashMap;\nuse rustc_hir::def::Namespace::{MacroNS, TypeNS, ValueNS};\nuse rustc_hir::def::{DefKind, Namespace, Res};\nuse rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};\nuse rustc_hir::{ItemKind, Node, UseKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::fast_reject::SimplifiedType;\nuse rustc_middle::ty::layout::HasTyCtxt;\nuse rustc_middle::ty::{FloatTy, IntTy, Ty, TyCtxt, UintTy};\nuse rustc_span::{Ident, STDLIB_STABLE_CRATES, Symbol};\nuse std::sync::OnceLock;\n\n/// Specifies whether to resolve a path in the [`TypeNS`], [`ValueNS`], [`MacroNS`] or in an\n/// arbitrary namespace\n#[derive(Clone, Copy, PartialEq, Debug)]\npub enum PathNS {\n    Type,\n    Value,\n    Macro,\n    Field,\n\n    /// Resolves to the name in the first available namespace, e.g. for `std::vec` this would return\n    /// either the macro or the module but **not** both\n    ///\n    /// Must only be used when the specific resolution is unimportant such as in\n    /// `missing_enforced_import_renames`\n    Arbitrary,\n}\n\nimpl PathNS {\n    fn matches(self, ns: Option<Namespace>) -> bool {\n        let required = match self {\n            PathNS::Type => TypeNS,\n            PathNS::Value => ValueNS,\n            PathNS::Macro => MacroNS,\n            PathNS::Field => return false,\n            PathNS::Arbitrary => return true,\n        };\n\n        ns == Some(required)\n    }\n}\n\n/// Lazily resolves a path into a list of [`DefId`]s using [`lookup_path`].\n///\n/// Typically it will contain one [`DefId`] or none, but in some situations there can be multiple:\n/// - `memchr::memchr` could return the functions from both memchr 1.0 and memchr 2.0\n/// - `alloc::boxed::Box::downcast` would return a function for each of the different inherent impls\n///   ([1], [2], [3])\n///\n/// [1]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast\n/// [2]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast-1\n/// [3]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast-2\npub struct PathLookup {\n    ns: PathNS,\n    path: &'static [Symbol],\n    once: OnceLock<Vec<DefId>>,\n}\n\nimpl PathLookup {\n    /// Only exported for tests and `clippy_lints_internal`\n    #[doc(hidden)]\n    pub const fn new(ns: PathNS, path: &'static [Symbol]) -> Self {\n        Self {\n            ns,\n            path,\n            once: OnceLock::new(),\n        }\n    }\n\n    /// Returns the list of [`DefId`]s that the path resolves to\n    pub fn get<'tcx>(&self, tcx: &impl HasTyCtxt<'tcx>) -> &[DefId] {\n        self.once.get_or_init(|| lookup_path(tcx.tcx(), self.ns, self.path))\n    }\n\n    /// Returns the single [`DefId`] that the path resolves to, this can only be used for paths into\n    /// stdlib crates to avoid the issue of multiple [`DefId`]s being returned\n    ///\n    /// May return [`None`] in `no_std`/`no_core` environments\n    pub fn only(&self, cx: &LateContext<'_>) -> Option<DefId> {\n        let ids = self.get(cx);\n        debug_assert!(STDLIB_STABLE_CRATES.contains(&self.path[0]));\n        debug_assert!(ids.len() <= 1, \"{ids:?}\");\n        ids.first().copied()\n    }\n\n    /// Checks if the path resolves to the given `def_id`\n    pub fn matches<'tcx>(&self, tcx: &impl HasTyCtxt<'tcx>, def_id: DefId) -> bool {\n        self.get(&tcx.tcx()).contains(&def_id)\n    }\n\n    /// Resolves `maybe_path` to a [`DefId`] and checks if the [`PathLookup`] matches it\n    pub fn matches_path<'tcx>(&self, cx: &LateContext<'_>, maybe_path: impl MaybeQPath<'tcx>) -> bool {\n        maybe_path\n            .res(cx)\n            .opt_def_id()\n            .is_some_and(|def_id| self.matches(cx, def_id))\n    }\n\n    /// Checks if the path resolves to `ty`'s definition, must be an `Adt`\n    pub fn matches_ty<'tcx>(&self, tcx: &impl HasTyCtxt<'tcx>, ty: Ty<'_>) -> bool {\n        ty.ty_adt_def().is_some_and(|adt| self.matches(&tcx.tcx(), adt.did()))\n    }\n}\n\nmacro_rules! path_macros {\n    ($($name:ident: $ns:expr,)*) => {\n        $(\n            /// Only exported for tests and `clippy_lints_internal`\n            #[doc(hidden)]\n            #[macro_export]\n            macro_rules! $name {\n                ($$($$seg:ident $$(::)?)*) => {\n                    PathLookup::new($ns, &[$$(sym::$$seg,)*])\n                };\n            }\n        )*\n    };\n}\n\npath_macros! {\n    type_path: PathNS::Type,\n    value_path: PathNS::Value,\n    macro_path: PathNS::Macro,\n}\n\n// Paths in external crates\npub static FUTURES_IO_ASYNCREADEXT: PathLookup = type_path!(futures_util::AsyncReadExt);\npub static FUTURES_IO_ASYNCWRITEEXT: PathLookup = type_path!(futures_util::AsyncWriteExt);\npub static ITERTOOLS_NEXT_TUPLE: PathLookup = value_path!(itertools::Itertools::next_tuple);\npub static PARKING_LOT_GUARDS: [PathLookup; 3] = [\n    type_path!(lock_api::mutex::MutexGuard),\n    type_path!(lock_api::rwlock::RwLockReadGuard),\n    type_path!(lock_api::rwlock::RwLockWriteGuard),\n];\npub static REGEX_BUILDER_NEW: PathLookup = value_path!(regex::RegexBuilder::new);\npub static REGEX_BYTES_BUILDER_NEW: PathLookup = value_path!(regex::bytes::RegexBuilder::new);\npub static REGEX_BYTES_NEW: PathLookup = value_path!(regex::bytes::Regex::new);\npub static REGEX_BYTES_SET_NEW: PathLookup = value_path!(regex::bytes::RegexSet::new);\npub static REGEX_NEW: PathLookup = value_path!(regex::Regex::new);\npub static REGEX_SET_NEW: PathLookup = value_path!(regex::RegexSet::new);\npub static SERDE_DESERIALIZE: PathLookup = type_path!(serde::de::Deserialize);\npub static SERDE_DE_VISITOR: PathLookup = type_path!(serde::de::Visitor);\npub static TOKIO_FILE_OPTIONS: PathLookup = value_path!(tokio::fs::File::options);\npub static TOKIO_IO_ASYNCREADEXT: PathLookup = type_path!(tokio::io::AsyncReadExt);\npub static TOKIO_IO_ASYNCWRITEEXT: PathLookup = type_path!(tokio::io::AsyncWriteExt);\npub static TOKIO_IO_OPEN_OPTIONS: PathLookup = type_path!(tokio::fs::OpenOptions);\npub static TOKIO_IO_OPEN_OPTIONS_NEW: PathLookup = value_path!(tokio::fs::OpenOptions::new);\npub static LAZY_STATIC: PathLookup = macro_path!(lazy_static::lazy_static);\npub static ONCE_CELL_SYNC_LAZY: PathLookup = type_path!(once_cell::sync::Lazy);\npub static ONCE_CELL_SYNC_LAZY_NEW: PathLookup = value_path!(once_cell::sync::Lazy::new);\n\n// Paths for internal lints go in `clippy_lints_internal/src/internal_paths.rs`\n\n/// Equivalent to a [`lookup_path`] after splitting the input string on `::`\n///\n/// This function is expensive and should be used sparingly.\npub fn lookup_path_str(tcx: TyCtxt<'_>, ns: PathNS, path: &str) -> Vec<DefId> {\n    let path: Vec<Symbol> = path.split(\"::\").map(Symbol::intern).collect();\n    lookup_path(tcx, ns, &path)\n}\n\n/// Resolves a def path like `std::vec::Vec`.\n///\n/// Typically it will return one [`DefId`] or none, but in some situations there can be multiple:\n/// - `memchr::memchr` could return the functions from both memchr 1.0 and memchr 2.0\n/// - `alloc::boxed::Box::downcast` would return a function for each of the different inherent impls\n///   ([1], [2], [3])\n///\n/// This function is expensive and should be used sparingly.\n///\n/// [1]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast\n/// [2]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast-1\n/// [3]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.downcast-2\npub fn lookup_path(tcx: TyCtxt<'_>, ns: PathNS, path: &[Symbol]) -> Vec<DefId> {\n    let (root, rest) = match *path {\n        [] | [_] => return Vec::new(),\n        [root, ref rest @ ..] => (root, rest),\n    };\n\n    let mut out = Vec::new();\n    for &base in find_crates(tcx, root).iter().chain(find_primitive_impls(tcx, root)) {\n        lookup_with_base(tcx, base, ns, rest, &mut out);\n    }\n    out\n}\n\n/// Finds the crates called `name`, may be multiple due to multiple major versions.\npub fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> &'static [DefId] {\n    static BY_NAME: OnceLock<FxHashMap<Symbol, Vec<DefId>>> = OnceLock::new();\n    let map = BY_NAME.get_or_init(|| {\n        let mut map = FxHashMap::default();\n        map.insert(tcx.crate_name(LOCAL_CRATE), vec![LOCAL_CRATE.as_def_id()]);\n        for &num in tcx.crates(()) {\n            map.entry(tcx.crate_name(num)).or_default().push(num.as_def_id());\n        }\n        map\n    });\n    match map.get(&name) {\n        Some(def_ids) => def_ids,\n        None => &[],\n    }\n}\n\nfn find_primitive_impls(tcx: TyCtxt<'_>, name: Symbol) -> &[DefId] {\n    let ty = match name {\n        sym::bool => SimplifiedType::Bool,\n        sym::char => SimplifiedType::Char,\n        sym::str => SimplifiedType::Str,\n        sym::array => SimplifiedType::Array,\n        sym::slice => SimplifiedType::Slice,\n        // FIXME: rustdoc documents these two using just `pointer`.\n        //\n        // Maybe this is something we should do here too.\n        sym::const_ptr => SimplifiedType::Ptr(Mutability::Not),\n        sym::mut_ptr => SimplifiedType::Ptr(Mutability::Mut),\n        sym::isize => SimplifiedType::Int(IntTy::Isize),\n        sym::i8 => SimplifiedType::Int(IntTy::I8),\n        sym::i16 => SimplifiedType::Int(IntTy::I16),\n        sym::i32 => SimplifiedType::Int(IntTy::I32),\n        sym::i64 => SimplifiedType::Int(IntTy::I64),\n        sym::i128 => SimplifiedType::Int(IntTy::I128),\n        sym::usize => SimplifiedType::Uint(UintTy::Usize),\n        sym::u8 => SimplifiedType::Uint(UintTy::U8),\n        sym::u16 => SimplifiedType::Uint(UintTy::U16),\n        sym::u32 => SimplifiedType::Uint(UintTy::U32),\n        sym::u64 => SimplifiedType::Uint(UintTy::U64),\n        sym::u128 => SimplifiedType::Uint(UintTy::U128),\n        sym::f32 => SimplifiedType::Float(FloatTy::F32),\n        sym::f64 => SimplifiedType::Float(FloatTy::F64),\n        _ => return &[],\n    };\n\n    tcx.incoherent_impls(ty)\n}\n\n/// Resolves a def path like `vec::Vec` with the base `std`.\nfn lookup_with_base(tcx: TyCtxt<'_>, mut base: DefId, ns: PathNS, mut path: &[Symbol], out: &mut Vec<DefId>) {\n    loop {\n        match *path {\n            [segment] => {\n                out.extend(item_child_by_name(tcx, base, ns, segment));\n\n                // When the current def_id is e.g. `struct S`, check the impl items in\n                // `impl S { ... }`\n                let inherent_impl_children = tcx\n                    .inherent_impls(base)\n                    .iter()\n                    .filter_map(|&impl_def_id| item_child_by_name(tcx, impl_def_id, ns, segment));\n                out.extend(inherent_impl_children);\n\n                return;\n            },\n            [segment, ref rest @ ..] => {\n                path = rest;\n                let Some(child) = item_child_by_name(tcx, base, PathNS::Type, segment) else {\n                    return;\n                };\n                base = child;\n            },\n            [] => unreachable!(),\n        }\n    }\n}\n\nfn item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, ns: PathNS, name: Symbol) -> Option<DefId> {\n    if let Some(local_id) = def_id.as_local() {\n        local_item_child_by_name(tcx, local_id, ns, name)\n    } else {\n        non_local_item_child_by_name(tcx, def_id, ns, name)\n    }\n}\n\nfn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, name: Symbol) -> Option<DefId> {\n    let root_mod;\n    let item_kind = match tcx.hir_node_by_def_id(local_id) {\n        Node::Crate(r#mod) => {\n            root_mod = ItemKind::Mod(Ident::dummy(), r#mod);\n            &root_mod\n        },\n        Node::Item(item) => &item.kind,\n        Node::Variant(variant) if ns == PathNS::Field => {\n            return if let rustc_hir::VariantData::Struct { fields, .. } = variant.data\n                && let Some(field_def_id) = fields.iter().find_map(|field| {\n                    if field.ident.name == name {\n                        Some(field.def_id.to_def_id())\n                    } else {\n                        None\n                    }\n                }) {\n                Some(field_def_id)\n            } else {\n                None\n            };\n        },\n        _ => return None,\n    };\n\n    match item_kind {\n        ItemKind::Mod(_, r#mod) => r#mod.item_ids.iter().find_map(|&item_id| {\n            let item = tcx.hir_item(item_id);\n            if let ItemKind::Use(path, UseKind::Single(ident)) = item.kind {\n                if ident.name == name {\n                    let opt_def_id = |ns: Option<Res>| ns.and_then(|res| res.opt_def_id());\n                    match ns {\n                        PathNS::Type => opt_def_id(path.res.type_ns),\n                        PathNS::Value => opt_def_id(path.res.value_ns),\n                        PathNS::Macro => opt_def_id(path.res.macro_ns),\n                        PathNS::Field => None,\n                        PathNS::Arbitrary => unreachable!(),\n                    }\n                } else {\n                    None\n                }\n            } else if let Some(ident) = item.kind.ident()\n                && ident.name == name\n                && ns.matches(tcx.def_kind(item.owner_id).ns())\n            {\n                Some(item.owner_id.to_def_id())\n            } else {\n                None\n            }\n        }),\n        ItemKind::Impl(..) | ItemKind::Trait(..) => tcx\n            .associated_items(local_id)\n            .filter_by_name_unhygienic(name)\n            .find(|assoc_item| ns.matches(Some(assoc_item.namespace())))\n            .map(|assoc_item| assoc_item.def_id),\n        ItemKind::Struct(_, _, rustc_hir::VariantData::Struct { fields, .. }) if ns == PathNS::Field => {\n            fields.iter().find_map(|field| {\n                if field.ident.name == name {\n                    Some(field.def_id.to_def_id())\n                } else {\n                    None\n                }\n            })\n        },\n        ItemKind::Enum(_, _, rustc_hir::EnumDef { variants }) if ns == PathNS::Type => {\n            variants.iter().find_map(|variant| {\n                if variant.ident.name == name {\n                    Some(variant.def_id.to_def_id())\n                } else {\n                    None\n                }\n            })\n        },\n        _ => None,\n    }\n}\n\nfn non_local_item_child_by_name(tcx: TyCtxt<'_>, def_id: DefId, ns: PathNS, name: Symbol) -> Option<DefId> {\n    match tcx.def_kind(def_id) {\n        DefKind::Mod | DefKind::Enum | DefKind::Trait => tcx.module_children(def_id).iter().find_map(|child| {\n            if child.ident.name == name && ns.matches(child.res.ns()) {\n                child.res.opt_def_id()\n            } else {\n                None\n            }\n        }),\n        DefKind::Impl { .. } => tcx\n            .associated_item_def_ids(def_id)\n            .iter()\n            .copied()\n            .find(|&assoc_def_id| tcx.item_name(assoc_def_id) == name && ns.matches(tcx.def_kind(assoc_def_id).ns())),\n        DefKind::Struct => tcx\n            .associated_item_def_ids(def_id)\n            .iter()\n            .copied()\n            .find(|&assoc_def_id| tcx.item_name(assoc_def_id) == name),\n        _ => None,\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/qualify_min_const_fn.rs",
    "content": "// This code used to be a part of `rustc` but moved to Clippy as a result of\n// https://github.com/rust-lang/rust/issues/76618. Because of that, it contains unused code and some\n// of terminologies might not be relevant in the context of Clippy. Note that its behavior might\n// differ from the time of `rustc` even if the name stays the same.\n\nuse crate::msrvs::{self, Msrv};\nuse hir::LangItem;\nuse rustc_const_eval::check_consts::ConstCx;\nuse rustc_hir as hir;\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{RustcVersion, StableSince};\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_infer::traits::Obligation;\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::{\n    Body, CastKind, NonDivergingIntrinsic, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind,\n    Terminator, TerminatorKind,\n};\nuse rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause};\nuse rustc_middle::ty::adjustment::PointerCoercion;\nuse rustc_middle::ty::{self, GenericArgKind, Instance, TraitRef, Ty, TyCtxt};\nuse rustc_span::Span;\nuse rustc_span::symbol::sym;\nuse rustc_trait_selection::traits::{ObligationCtxt, SelectionContext};\nuse std::borrow::Cow;\n\ntype McfResult = Result<(), (Span, Cow<'static, str>)>;\n\npub fn is_min_const_fn<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, msrv: Msrv) -> McfResult {\n    let def_id = body.source.def_id();\n\n    for local in &body.local_decls {\n        check_ty(cx, local.ty, local.source_info.span, msrv)?;\n    }\n    if !msrv.meets(cx, msrvs::CONST_FN_TRAIT_BOUND)\n        && let Some(sized_did) = cx.tcx.lang_items().sized_trait()\n        && let Some(meta_sized_did) = cx.tcx.lang_items().meta_sized_trait()\n        && cx.tcx.param_env(def_id).caller_bounds().iter().any(|bound| {\n            bound.as_trait_clause().is_some_and(|clause| {\n                let did = clause.def_id();\n                did != sized_did && did != meta_sized_did\n            })\n        })\n    {\n        return Err((\n            body.span,\n            \"non-`Sized` trait clause before `const_fn_trait_bound` is stabilized\".into(),\n        ));\n    }\n    // impl trait is gone in MIR, so check the return type manually\n    check_ty(\n        cx,\n        cx.tcx.fn_sig(def_id).instantiate_identity().output().skip_binder(),\n        body.local_decls.iter().next().unwrap().source_info.span,\n        msrv,\n    )?;\n\n    for bb in &*body.basic_blocks {\n        // Cleanup blocks are ignored entirely by const eval, so we can too:\n        // https://github.com/rust-lang/rust/blob/1dea922ea6e74f99a0e97de5cdb8174e4dea0444/compiler/rustc_const_eval/src/transform/check_consts/check.rs#L382\n        if !bb.is_cleanup {\n            check_terminator(cx, body, bb.terminator(), msrv)?;\n            for stmt in &bb.statements {\n                check_statement(cx, body, def_id, stmt, msrv)?;\n            }\n        }\n    }\n    Ok(())\n}\n\nfn check_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, msrv: Msrv) -> McfResult {\n    for arg in ty.walk() {\n        let ty = match arg.kind() {\n            GenericArgKind::Type(ty) => ty,\n\n            // No constraints on lifetimes or constants, except potentially\n            // constants' types, but `walk` will get to them as well.\n            GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => continue,\n        };\n\n        match ty.kind() {\n            ty::Ref(_, _, hir::Mutability::Mut) if !msrv.meets(cx, msrvs::CONST_MUT_REFS) => {\n                return Err((span, \"mutable references in const fn are unstable\".into()));\n            },\n            ty::Alias(ty::Opaque, ..) => return Err((span, \"`impl Trait` in const fn is unstable\".into())),\n            ty::FnPtr(..) => {\n                return Err((span, \"function pointers in const fn are unstable\".into()));\n            },\n            ty::Dynamic(preds, _) => {\n                for pred in *preds {\n                    match pred.skip_binder() {\n                        ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => {\n                            return Err((\n                                span,\n                                \"trait bounds other than `Sized` \\\n                                 on const fn parameters are unstable\"\n                                    .into(),\n                            ));\n                        },\n                        ty::ExistentialPredicate::Trait(trait_ref) => {\n                            if Some(trait_ref.def_id) != cx.tcx.lang_items().sized_trait() {\n                                return Err((\n                                    span,\n                                    \"trait bounds other than `Sized` \\\n                                     on const fn parameters are unstable\"\n                                        .into(),\n                                ));\n                            }\n                        },\n                    }\n                }\n            },\n            _ => {},\n        }\n    }\n    Ok(())\n}\n\nfn check_rvalue<'tcx>(\n    cx: &LateContext<'tcx>,\n    body: &Body<'tcx>,\n    def_id: DefId,\n    rvalue: &Rvalue<'tcx>,\n    span: Span,\n    msrv: Msrv,\n) -> McfResult {\n    match rvalue {\n        Rvalue::ThreadLocalRef(_) => Err((span, \"cannot access thread local storage in const fn\".into())),\n        Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {\n            check_place(cx, *place, span, body, msrv)\n        },\n        Rvalue::CopyForDeref(place) => check_place(cx, *place, span, body, msrv),\n        Rvalue::Repeat(operand, _)\n        | Rvalue::Use(operand)\n        | Rvalue::WrapUnsafeBinder(operand, _)\n        | Rvalue::Cast(\n            CastKind::PointerWithExposedProvenance\n            | CastKind::IntToInt\n            | CastKind::FloatToInt\n            | CastKind::IntToFloat\n            | CastKind::FloatToFloat\n            | CastKind::FnPtrToPtr\n            | CastKind::PtrToPtr\n            | CastKind::PointerCoercion(PointerCoercion::MutToConstPointer | PointerCoercion::ArrayToPointer, _)\n            | CastKind::Subtype,\n            operand,\n            _,\n        ) => check_operand(cx, operand, span, body, msrv),\n        Rvalue::Cast(\n            CastKind::PointerCoercion(\n                PointerCoercion::UnsafeFnPointer\n                | PointerCoercion::ClosureFnPointer(_)\n                | PointerCoercion::ReifyFnPointer(_),\n                _,\n            ),\n            _,\n            _,\n        ) => Err((span, \"function pointer casts are not allowed in const fn\".into())),\n        Rvalue::Cast(CastKind::PointerCoercion(PointerCoercion::Unsize, _), op, cast_ty) => {\n            let Some(pointee_ty) = cast_ty.builtin_deref(true) else {\n                // We cannot allow this for now.\n                return Err((span, \"unsizing casts are only allowed for references right now\".into()));\n            };\n            let unsized_ty = cx\n                .tcx\n                .struct_tail_for_codegen(pointee_ty, ty::TypingEnv::post_analysis(cx.tcx, def_id));\n            if let ty::Slice(_) | ty::Str = unsized_ty.kind() {\n                check_operand(cx, op, span, body, msrv)?;\n                // Casting/coercing things to slices is fine.\n                Ok(())\n            } else {\n                // We just can't allow trait objects until we have figured out trait method calls.\n                Err((span, \"unsizing casts are not allowed in const fn\".into()))\n            }\n        },\n        Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {\n            Err((span, \"casting pointers to ints is unstable in const fn\".into()))\n        },\n        Rvalue::Cast(CastKind::Transmute, _, _) => Err((\n            span,\n            \"transmute can attempt to turn pointers into integers, so is unstable in const fn\".into(),\n        )),\n        // binops are fine on integers\n        Rvalue::BinaryOp(_, box (lhs, rhs)) => {\n            check_operand(cx, lhs, span, body, msrv)?;\n            check_operand(cx, rhs, span, body, msrv)?;\n            let ty = lhs.ty(body, cx.tcx);\n            if ty.is_integral() || ty.is_bool() || ty.is_char() {\n                Ok(())\n            } else {\n                Err((\n                    span,\n                    \"only int, `bool` and `char` operations are stable in const fn\".into(),\n                ))\n            }\n        },\n        Rvalue::UnaryOp(_, operand) => {\n            let ty = operand.ty(body, cx.tcx);\n            if ty.is_integral() || ty.is_bool() {\n                check_operand(cx, operand, span, body, msrv)\n            } else {\n                Err((span, \"only int and `bool` operations are stable in const fn\".into()))\n            }\n        },\n        Rvalue::Aggregate(_, operands) => {\n            for operand in operands {\n                check_operand(cx, operand, span, body, msrv)?;\n            }\n            Ok(())\n        },\n    }\n}\n\nfn check_statement<'tcx>(\n    cx: &LateContext<'tcx>,\n    body: &Body<'tcx>,\n    def_id: DefId,\n    statement: &Statement<'tcx>,\n    msrv: Msrv,\n) -> McfResult {\n    let span = statement.source_info.span;\n    match &statement.kind {\n        StatementKind::Assign(box (place, rval)) => {\n            check_place(cx, *place, span, body, msrv)?;\n            check_rvalue(cx, body, def_id, rval, span, msrv)\n        },\n\n        StatementKind::FakeRead(box (_, place)) => check_place(cx, *place, span, body, msrv),\n        // just an assignment\n        StatementKind::SetDiscriminant { place, .. } => check_place(cx, **place, span, body, msrv),\n\n        StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(op)) => check_operand(cx, op, span, body, msrv),\n\n        StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(\n            rustc_middle::mir::CopyNonOverlapping { dst, src, count },\n        )) => {\n            check_operand(cx, dst, span, body, msrv)?;\n            check_operand(cx, src, span, body, msrv)?;\n            check_operand(cx, count, span, body, msrv)\n        },\n        // These are all NOPs\n        StatementKind::StorageLive(_)\n        | StatementKind::StorageDead(_)\n        | StatementKind::Retag { .. }\n        | StatementKind::AscribeUserType(..)\n        | StatementKind::PlaceMention(..)\n        | StatementKind::Coverage(..)\n        | StatementKind::ConstEvalCounter\n        | StatementKind::BackwardIncompatibleDropHint { .. }\n        | StatementKind::Nop => Ok(()),\n    }\n}\n\nfn check_operand<'tcx>(\n    cx: &LateContext<'tcx>,\n    operand: &Operand<'tcx>,\n    span: Span,\n    body: &Body<'tcx>,\n    msrv: Msrv,\n) -> McfResult {\n    match operand {\n        Operand::Move(place) => {\n            if !place.projection.as_ref().is_empty()\n                && !is_ty_const_destruct(cx.tcx, place.ty(&body.local_decls, cx.tcx).ty, body)\n            {\n                return Err((\n                    span,\n                    \"cannot drop locals with a non constant destructor in const fn\".into(),\n                ));\n            }\n\n            check_place(cx, *place, span, body, msrv)\n        },\n        Operand::Copy(place) => check_place(cx, *place, span, body, msrv),\n        Operand::Constant(c) => match c.check_static_ptr(cx.tcx) {\n            Some(_) => Err((span, \"cannot access `static` items in const fn\".into())),\n            None => Ok(()),\n        },\n        Operand::RuntimeChecks(..) => Ok(()),\n    }\n}\n\nfn check_place<'tcx>(\n    cx: &LateContext<'tcx>,\n    place: Place<'tcx>,\n    span: Span,\n    body: &Body<'tcx>,\n    msrv: Msrv,\n) -> McfResult {\n    for (base, elem) in place.as_ref().iter_projections() {\n        match elem {\n            ProjectionElem::Field(..) => {\n                if base.ty(body, cx.tcx).ty.is_union() && !msrv.meets(cx, msrvs::CONST_FN_UNION) {\n                    return Err((span, \"accessing union fields is unstable\".into()));\n                }\n            },\n            ProjectionElem::Deref => match base.ty(body, cx.tcx).ty.kind() {\n                ty::RawPtr(_, hir::Mutability::Mut) => {\n                    return Err((span, \"dereferencing raw mut pointer in const fn is unstable\".into()));\n                },\n                ty::RawPtr(_, hir::Mutability::Not) if !msrv.meets(cx, msrvs::CONST_RAW_PTR_DEREF) => {\n                    return Err((span, \"dereferencing raw const pointer in const fn is unstable\".into()));\n                },\n                _ => (),\n            },\n            ProjectionElem::ConstantIndex { .. }\n            | ProjectionElem::OpaqueCast(..)\n            | ProjectionElem::Downcast(..)\n            | ProjectionElem::Subslice { .. }\n            | ProjectionElem::Index(_)\n            | ProjectionElem::UnwrapUnsafeBinder(_) => {},\n        }\n    }\n\n    Ok(())\n}\n\nfn check_terminator<'tcx>(\n    cx: &LateContext<'tcx>,\n    body: &Body<'tcx>,\n    terminator: &Terminator<'tcx>,\n    msrv: Msrv,\n) -> McfResult {\n    let span = terminator.source_info.span;\n    match &terminator.kind {\n        TerminatorKind::FalseEdge { .. }\n        | TerminatorKind::FalseUnwind { .. }\n        | TerminatorKind::Goto { .. }\n        | TerminatorKind::Return\n        | TerminatorKind::UnwindResume\n        | TerminatorKind::UnwindTerminate(_)\n        | TerminatorKind::Unreachable => Ok(()),\n        TerminatorKind::Drop { place, .. } => {\n            if !is_ty_const_destruct(cx.tcx, place.ty(&body.local_decls, cx.tcx).ty, body) {\n                return Err((\n                    span,\n                    \"cannot drop locals with a non constant destructor in const fn\".into(),\n                ));\n            }\n            Ok(())\n        },\n        TerminatorKind::SwitchInt { discr, targets: _ } => check_operand(cx, discr, span, body, msrv),\n        TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } => {\n            Err((span, \"const fn coroutines are unstable\".into()))\n        },\n        TerminatorKind::Call {\n            func,\n            args,\n            call_source: _,\n            destination: _,\n            target: _,\n            unwind: _,\n            fn_span: _,\n        }\n        | TerminatorKind::TailCall { func, args, fn_span: _ } => {\n            let fn_ty = func.ty(body, cx.tcx);\n            if let ty::FnDef(fn_def_id, fn_substs) = fn_ty.kind() {\n                // FIXME: when analyzing a function with generic parameters, we may not have enough information to\n                // resolve to an instance. However, we could check if a host effect predicate can guarantee that\n                // this can be made a `const` call.\n                let fn_def_id = match Instance::try_resolve(cx.tcx, cx.typing_env(), *fn_def_id, fn_substs) {\n                    Ok(Some(fn_inst)) => fn_inst.def_id(),\n                    Ok(None) => return Err((span, format!(\"cannot resolve instance for {func:?}\").into())),\n                    Err(_) => return Err((span, format!(\"error during instance resolution of {func:?}\").into())),\n                };\n                if !is_stable_const_fn(cx, fn_def_id, msrv) {\n                    return Err((\n                        span,\n                        format!(\n                            \"can only call other `const fn` within a `const fn`, \\\n                             but `{func:?}` is not stable as `const fn`\",\n                        )\n                        .into(),\n                    ));\n                }\n\n                // HACK: This is to \"unstabilize\" the `transmute` intrinsic\n                // within const fns. `transmute` is allowed in all other const contexts.\n                // This won't really scale to more intrinsics or functions. Let's allow const\n                // transmutes in const fn before we add more hacks to this.\n                if cx.tcx.is_intrinsic(fn_def_id, sym::transmute) {\n                    return Err((\n                        span,\n                        \"can only call `transmute` from const items, not `const fn`\".into(),\n                    ));\n                }\n\n                check_operand(cx, func, span, body, msrv)?;\n\n                for arg in args {\n                    check_operand(cx, &arg.node, span, body, msrv)?;\n                }\n                Ok(())\n            } else {\n                Err((span, \"can only call other const fns within const fn\".into()))\n            }\n        },\n        TerminatorKind::Assert {\n            cond,\n            expected: _,\n            msg: _,\n            target: _,\n            unwind: _,\n        } => check_operand(cx, cond, span, body, msrv),\n        TerminatorKind::InlineAsm { .. } => Err((span, \"cannot use inline assembly in const fn\".into())),\n    }\n}\n\n/// Checks if the given `def_id` is a stable const fn, in respect to the given MSRV.\npub fn is_stable_const_fn(cx: &LateContext<'_>, def_id: DefId, msrv: Msrv) -> bool {\n    cx.tcx.is_const_fn(def_id)\n        && cx\n            .tcx\n            .lookup_const_stability(def_id)\n            .or_else(|| {\n                cx.tcx\n                    .trait_of_assoc(def_id)\n                    .and_then(|trait_def_id| cx.tcx.lookup_const_stability(trait_def_id))\n            })\n            .is_none_or(|const_stab| {\n                if let rustc_hir::StabilityLevel::Stable { since, .. } = const_stab.level {\n                    // Checking MSRV is manually necessary because `rustc` has no such concept. This entire\n                    // function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.\n                    // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.\n\n                    let const_stab_rust_version = match since {\n                        StableSince::Version(version) => version,\n                        StableSince::Current => RustcVersion::CURRENT,\n                        StableSince::Err(_) => return false,\n                    };\n\n                    msrv.meets(cx, const_stab_rust_version)\n                } else {\n                    // Unstable const fn, check if the feature is enabled.\n                    cx.tcx.features().enabled(const_stab.feature) && msrv.current(cx).is_none()\n                }\n            })\n}\n\nfn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {\n    // FIXME(const_trait_impl, fee1-dead) revert to const destruct once it works again\n    #[expect(unused)]\n    fn is_ty_const_destruct_unused<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {\n        // If this doesn't need drop at all, then don't select `[const] Destruct`.\n        if !ty.needs_drop(tcx, body.typing_env(tcx)) {\n            return false;\n        }\n\n        let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(body.typing_env(tcx));\n        // FIXME(const_trait_impl) constness\n        let obligation = Obligation::new(\n            tcx,\n            ObligationCause::dummy_with_span(body.span),\n            param_env,\n            TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, body.span), [ty]),\n        );\n\n        let mut selcx = SelectionContext::new(&infcx);\n        let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {\n            return false;\n        };\n\n        if !matches!(\n            impl_src,\n            ImplSource::Builtin(BuiltinImplSource::Misc, _) | ImplSource::Param(_)\n        ) {\n            return false;\n        }\n\n        let ocx = ObligationCtxt::new(&infcx);\n        ocx.register_obligations(impl_src.nested_obligations());\n        ocx.evaluate_obligations_error_on_ambiguity().is_empty()\n    }\n\n    !ty.needs_drop(tcx, ConstCx::new(tcx, body).typing_env)\n}\n"
  },
  {
    "path": "clippy_utils/src/res.rs",
    "content": "use rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{\n    self as hir, Expr, ExprKind, HirId, LangItem, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, TyKind,\n};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::layout::HasTyCtxt;\nuse rustc_middle::ty::{AdtDef, AdtKind, Binder, EarlyBinder, Ty, TypeckResults};\nuse rustc_span::{Ident, Symbol};\n\n/// Either a `HirId` or a type which can be identified by one.\npub trait HasHirId: Copy {\n    fn hir_id(self) -> HirId;\n}\nimpl HasHirId for HirId {\n    #[inline]\n    fn hir_id(self) -> HirId {\n        self\n    }\n}\nimpl HasHirId for &Expr<'_> {\n    #[inline]\n    fn hir_id(self) -> HirId {\n        self.hir_id\n    }\n}\n\ntype DefRes = (DefKind, DefId);\n\npub trait MaybeTypeckRes<'tcx> {\n    /// Gets the contained `TypeckResults`.\n    ///\n    /// With debug assertions enabled this will always return `Some`. `None` is\n    /// only returned so logic errors can be handled by not emitting a lint on\n    /// release builds.\n    fn typeck_res(&self) -> Option<&TypeckResults<'tcx>>;\n\n    /// Gets the type-dependent resolution of the specified node.\n    ///\n    /// With debug assertions enabled this will always return `Some`. `None` is\n    /// only returned so logic errors can be handled by not emitting a lint on\n    /// release builds.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn ty_based_def(&self, node: impl HasHirId) -> Option<DefRes> {\n        #[inline]\n        #[cfg_attr(debug_assertions, track_caller)]\n        fn f(typeck: &TypeckResults<'_>, id: HirId) -> Option<DefRes> {\n            if typeck.hir_owner == id.owner {\n                let def = typeck.type_dependent_def(id);\n                debug_assert!(\n                    def.is_some(),\n                    \"attempted type-dependent lookup for a node with no definition\\\n                        \\n  node `{id:?}`\",\n                );\n                def\n            } else {\n                debug_assert!(\n                    false,\n                    \"attempted type-dependent lookup for a node in the wrong body\\\n                        \\n  in body `{:?}`\\\n                        \\n  expected body `{:?}`\",\n                    typeck.hir_owner, id.owner,\n                );\n                None\n            }\n        }\n        self.typeck_res().and_then(|typeck| f(typeck, node.hir_id()))\n    }\n}\nimpl<'tcx> MaybeTypeckRes<'tcx> for LateContext<'tcx> {\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn typeck_res(&self) -> Option<&TypeckResults<'tcx>> {\n        if let Some(typeck) = self.maybe_typeck_results() {\n            Some(typeck)\n        } else {\n            // It's possible to get the `TypeckResults` for any other body, but\n            // attempting to lookup the type of something across bodies like this\n            // is a good indication of a bug.\n            debug_assert!(false, \"attempted type-dependent lookup in a non-body context\");\n            None\n        }\n    }\n}\nimpl<'tcx> MaybeTypeckRes<'tcx> for TypeckResults<'tcx> {\n    #[inline]\n    fn typeck_res(&self) -> Option<&TypeckResults<'tcx>> {\n        Some(self)\n    }\n}\n\n/// A `QPath` with the `HirId` of the node containing it.\ntype QPathId<'tcx> = (&'tcx QPath<'tcx>, HirId);\n\n/// A HIR node which might be a `QPath`.\npub trait MaybeQPath<'a>: Copy {\n    /// If this node is a path gets both the contained path and the `HirId` to\n    /// use for type dependant lookup.\n    fn opt_qpath(self) -> Option<QPathId<'a>>;\n\n    /// If this is a path gets its resolution. Returns `Res::Err` otherwise.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn res<'tcx>(self, typeck: &impl MaybeTypeckRes<'tcx>) -> Res {\n        #[cfg_attr(debug_assertions, track_caller)]\n        fn f(qpath: &QPath<'_>, id: HirId, typeck: &TypeckResults<'_>) -> Res {\n            match *qpath {\n                QPath::Resolved(_, p) => p.res,\n                QPath::TypeRelative(..) if let Some((kind, id)) = typeck.ty_based_def(id) => Res::Def(kind, id),\n                QPath::TypeRelative(..) => Res::Err,\n            }\n        }\n        match self.opt_qpath() {\n            Some((qpath, id)) if let Some(typeck) = typeck.typeck_res() => f(qpath, id, typeck),\n            _ => Res::Err,\n        }\n    }\n\n    /// If this is a path with the specified name as its final segment gets its\n    /// resolution. Returns `Res::Err` otherwise.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn res_if_named<'tcx>(self, typeck: &impl MaybeTypeckRes<'tcx>, name: Symbol) -> Res {\n        #[cfg_attr(debug_assertions, track_caller)]\n        fn f(qpath: &QPath<'_>, id: HirId, typeck: &TypeckResults<'_>, name: Symbol) -> Res {\n            match *qpath {\n                QPath::Resolved(_, p)\n                    if let [.., seg] = p.segments\n                        && seg.ident.name == name =>\n                {\n                    p.res\n                },\n                QPath::TypeRelative(_, seg)\n                    if seg.ident.name == name\n                        && let Some((kind, id)) = typeck.ty_based_def(id) =>\n                {\n                    Res::Def(kind, id)\n                },\n                QPath::Resolved(..) | QPath::TypeRelative(..) => Res::Err,\n            }\n        }\n        match self.opt_qpath() {\n            Some((qpath, id)) if let Some(typeck) = typeck.typeck_res() => f(qpath, id, typeck, name),\n            _ => Res::Err,\n        }\n    }\n\n    /// If this is a path gets both its resolution and final segment.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn res_with_seg<'tcx>(self, typeck: &impl MaybeTypeckRes<'tcx>) -> (Res, Option<&'a PathSegment<'a>>) {\n        #[cfg_attr(debug_assertions, track_caller)]\n        fn f<'a>(qpath: &QPath<'a>, id: HirId, typeck: &TypeckResults<'_>) -> (Res, Option<&'a PathSegment<'a>>) {\n            match *qpath {\n                QPath::Resolved(_, p) if let [.., seg] = p.segments => (p.res, Some(seg)),\n                QPath::TypeRelative(_, seg) if let Some((kind, id)) = typeck.ty_based_def(id) => {\n                    (Res::Def(kind, id), Some(seg))\n                },\n                QPath::Resolved(..) | QPath::TypeRelative(..) => (Res::Err, None),\n            }\n        }\n        match self.opt_qpath() {\n            Some((qpath, id)) if let Some(typeck) = typeck.typeck_res() => f(qpath, id, typeck),\n            _ => (Res::Err, None),\n        }\n    }\n\n    /// If this is a path without an explicit `Self` type gets its resolution.\n    /// Returns `Res::Err` otherwise.\n    ///\n    /// Only paths to trait items can optionally contain a `Self` type.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn typeless_res<'tcx>(self, typeck: &impl MaybeTypeckRes<'tcx>) -> Res {\n        #[cfg_attr(debug_assertions, track_caller)]\n        fn f(qpath: &QPath<'_>, id: HirId, typeck: &TypeckResults<'_>) -> Res {\n            match *qpath {\n                QPath::Resolved(\n                    None\n                    | Some(&hir::Ty {\n                        kind: TyKind::Infer(()),\n                        ..\n                    }),\n                    p,\n                ) => p.res,\n                QPath::TypeRelative(\n                    &hir::Ty {\n                        kind: TyKind::Infer(()),\n                        ..\n                    },\n                    _,\n                ) if let Some((kind, id)) = typeck.ty_based_def(id) => Res::Def(kind, id),\n                QPath::Resolved(..) | QPath::TypeRelative(..) => Res::Err,\n            }\n        }\n        match self.opt_qpath() {\n            Some((qpath, id)) if let Some(typeck) = typeck.typeck_res() => f(qpath, id, typeck),\n            _ => Res::Err,\n        }\n    }\n\n    /// If this is a path without an explicit `Self` type to an item with the\n    /// specified name gets its resolution. Returns `Res::Err` otherwise.\n    ///\n    /// Only paths to trait items can optionally contain a `Self` type.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn typeless_res_if_named<'tcx>(self, typeck: &impl MaybeTypeckRes<'tcx>, name: Symbol) -> Res {\n        #[cfg_attr(debug_assertions, track_caller)]\n        fn f(qpath: &QPath<'_>, id: HirId, typeck: &TypeckResults<'_>, name: Symbol) -> Res {\n            match *qpath {\n                QPath::Resolved(\n                    None\n                    | Some(&hir::Ty {\n                        kind: TyKind::Infer(()),\n                        ..\n                    }),\n                    p,\n                ) if let [.., seg] = p.segments\n                    && seg.ident.name == name =>\n                {\n                    p.res\n                },\n                QPath::TypeRelative(\n                    &hir::Ty {\n                        kind: TyKind::Infer(()),\n                        ..\n                    },\n                    seg,\n                ) if seg.ident.name == name\n                    && let Some((kind, id)) = typeck.ty_based_def(id) =>\n                {\n                    Res::Def(kind, id)\n                },\n                QPath::Resolved(..) | QPath::TypeRelative(..) => Res::Err,\n            }\n        }\n        match self.opt_qpath() {\n            Some((qpath, id)) if let Some(typeck) = typeck.typeck_res() => f(qpath, id, typeck, name),\n            _ => Res::Err,\n        }\n    }\n\n    /// If this is a type-relative path gets the definition it resolves to.\n    ///\n    /// Only inherent associated items require a type-relative path.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn ty_rel_def<'tcx>(self, typeck: &impl MaybeTypeckRes<'tcx>) -> Option<DefRes> {\n        match self.opt_qpath() {\n            Some((QPath::TypeRelative(..), id)) => typeck.ty_based_def(id),\n            _ => None,\n        }\n    }\n\n    /// If this is a type-relative path to an item with the specified name gets\n    /// the definition it resolves to.\n    ///\n    /// Only inherent associated items require a type-relative path.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn ty_rel_def_if_named<'tcx>(self, typeck: &impl MaybeTypeckRes<'tcx>, name: Symbol) -> Option<DefRes> {\n        match self.opt_qpath() {\n            Some((&QPath::TypeRelative(_, seg), id)) if seg.ident.name == name => typeck.ty_based_def(id),\n            _ => None,\n        }\n    }\n\n    /// If this is a type-relative path gets the definition it resolves to and\n    /// its final segment.\n    ///\n    /// Only inherent associated items require a type-relative path.\n    #[inline]\n    #[cfg_attr(debug_assertions, track_caller)]\n    fn ty_rel_def_with_seg<'tcx>(self, typeck: &impl MaybeTypeckRes<'tcx>) -> Option<(DefRes, &'a PathSegment<'a>)> {\n        match self.opt_qpath() {\n            Some((QPath::TypeRelative(_, seg), id)) if let Some(def) = typeck.ty_based_def(id) => Some((def, seg)),\n            _ => None,\n        }\n    }\n}\n\nimpl<'tcx> MaybeQPath<'tcx> for QPathId<'tcx> {\n    #[inline]\n    fn opt_qpath(self) -> Option<QPathId<'tcx>> {\n        Some((self.0, self.1))\n    }\n}\nimpl<'tcx> MaybeQPath<'tcx> for &'tcx Expr<'_> {\n    #[inline]\n    fn opt_qpath(self) -> Option<QPathId<'tcx>> {\n        match &self.kind {\n            ExprKind::Path(qpath) => Some((qpath, self.hir_id)),\n            _ => None,\n        }\n    }\n}\nimpl<'tcx> MaybeQPath<'tcx> for &'tcx PatExpr<'_> {\n    #[inline]\n    fn opt_qpath(self) -> Option<QPathId<'tcx>> {\n        match &self.kind {\n            PatExprKind::Path(qpath) => Some((qpath, self.hir_id)),\n            PatExprKind::Lit { .. } => None,\n        }\n    }\n}\nimpl<'tcx, AmbigArg> MaybeQPath<'tcx> for &'tcx hir::Ty<'_, AmbigArg> {\n    #[inline]\n    fn opt_qpath(self) -> Option<QPathId<'tcx>> {\n        match &self.kind {\n            TyKind::Path(qpath) => Some((qpath, self.hir_id)),\n            _ => None,\n        }\n    }\n}\nimpl<'tcx> MaybeQPath<'tcx> for &'_ Pat<'tcx> {\n    #[inline]\n    fn opt_qpath(self) -> Option<QPathId<'tcx>> {\n        match self.kind {\n            PatKind::Expr(e) => e.opt_qpath(),\n            _ => None,\n        }\n    }\n}\nimpl<'tcx, T: MaybeQPath<'tcx>> MaybeQPath<'tcx> for Option<T> {\n    #[inline]\n    fn opt_qpath(self) -> Option<QPathId<'tcx>> {\n        self.and_then(T::opt_qpath)\n    }\n}\nimpl<'tcx, T: Copy + MaybeQPath<'tcx>> MaybeQPath<'tcx> for &Option<T> {\n    #[inline]\n    fn opt_qpath(self) -> Option<QPathId<'tcx>> {\n        self.and_then(T::opt_qpath)\n    }\n}\n\n/// A resolved path and the explicit `Self` type if there is one.\ntype OptResPath<'tcx> = (Option<&'tcx hir::Ty<'tcx>>, Option<&'tcx Path<'tcx>>);\n\n/// A HIR node which might be a `QPath::Resolved`.\n///\n/// The following are resolved paths:\n/// * A path to a module or crate item.\n/// * A path to a trait item via the trait's name.\n/// * A path to a struct or variant constructor via the original type's path.\n/// * A local.\n///\n/// All other paths are `TypeRelative` and require using `PathRes` to lookup the\n/// resolution.\npub trait MaybeResPath<'a>: Copy {\n    /// If this node is a resolved path gets both the contained path and the\n    /// type associated with it.\n    fn opt_res_path(self) -> OptResPath<'a>;\n\n    /// If this node is a resolved path gets it's resolution. Returns `Res::Err`\n    /// otherwise.\n    #[inline]\n    fn basic_res(self) -> &'a Res {\n        self.opt_res_path().1.map_or(&Res::Err, |p| &p.res)\n    }\n\n    /// If this node is a path to a local gets the local's `HirId`.\n    #[inline]\n    fn res_local_id(self) -> Option<HirId> {\n        if let (_, Some(p)) = self.opt_res_path()\n            && let Res::Local(id) = p.res\n        {\n            Some(id)\n        } else {\n            None\n        }\n    }\n\n    /// If this node is a path to a local gets the local's `HirId` and identifier.\n    fn res_local_id_and_ident(self) -> Option<(HirId, &'a Ident)> {\n        if let (_, Some(p)) = self.opt_res_path()\n            && let Res::Local(id) = p.res\n            && let [seg] = p.segments\n        {\n            Some((id, &seg.ident))\n        } else {\n            None\n        }\n    }\n}\nimpl<'a> MaybeResPath<'a> for &'a Path<'a> {\n    #[inline]\n    fn opt_res_path(self) -> OptResPath<'a> {\n        (None, Some(self))\n    }\n\n    #[inline]\n    fn basic_res(self) -> &'a Res {\n        &self.res\n    }\n}\nimpl<'a> MaybeResPath<'a> for &QPath<'a> {\n    #[inline]\n    fn opt_res_path(self) -> OptResPath<'a> {\n        match *self {\n            QPath::Resolved(ty, path) => (ty, Some(path)),\n            QPath::TypeRelative(..) => (None, None),\n        }\n    }\n}\nimpl<'a> MaybeResPath<'a> for &Expr<'a> {\n    #[inline]\n    fn opt_res_path(self) -> OptResPath<'a> {\n        match &self.kind {\n            ExprKind::Path(qpath) => qpath.opt_res_path(),\n            _ => (None, None),\n        }\n    }\n}\nimpl<'a> MaybeResPath<'a> for &PatExpr<'a> {\n    #[inline]\n    fn opt_res_path(self) -> OptResPath<'a> {\n        match &self.kind {\n            PatExprKind::Path(qpath) => qpath.opt_res_path(),\n            PatExprKind::Lit { .. } => (None, None),\n        }\n    }\n}\nimpl<'a, AmbigArg> MaybeResPath<'a> for &hir::Ty<'a, AmbigArg> {\n    #[inline]\n    fn opt_res_path(self) -> OptResPath<'a> {\n        match &self.kind {\n            TyKind::Path(qpath) => qpath.opt_res_path(),\n            _ => (None, None),\n        }\n    }\n}\nimpl<'a> MaybeResPath<'a> for &Pat<'a> {\n    #[inline]\n    fn opt_res_path(self) -> OptResPath<'a> {\n        match self.kind {\n            PatKind::Expr(e) => e.opt_res_path(),\n            _ => (None, None),\n        }\n    }\n}\nimpl<'a, T: MaybeResPath<'a>> MaybeResPath<'a> for Option<T> {\n    #[inline]\n    fn opt_res_path(self) -> OptResPath<'a> {\n        match self {\n            Some(x) => T::opt_res_path(x),\n            None => (None, None),\n        }\n    }\n\n    #[inline]\n    fn basic_res(self) -> &'a Res {\n        self.map_or(&Res::Err, T::basic_res)\n    }\n}\n\n/// A type which may either contain a `DefId` or be referred to by a `DefId`.\npub trait MaybeDef: Copy {\n    fn opt_def_id(self) -> Option<DefId>;\n\n    /// Gets this definition's id and kind. This will lookup the kind in the def\n    /// tree if needed.\n    fn opt_def<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)>;\n\n    /// Gets the diagnostic name of this definition if it has one.\n    #[inline]\n    fn opt_diag_name<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<Symbol> {\n        self.opt_def_id().and_then(|id| tcx.tcx().get_diagnostic_name(id))\n    }\n\n    /// Checks if this definition has the specified diagnostic name.\n    #[inline]\n    fn is_diag_item<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>, name: Symbol) -> bool {\n        self.opt_def_id()\n            .is_some_and(|id| tcx.tcx().is_diagnostic_item(name, id))\n    }\n\n    /// Checks if this definition is the specified `LangItem`.\n    #[inline]\n    fn is_lang_item<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>, item: LangItem) -> bool {\n        self.opt_def_id()\n            .is_some_and(|id| tcx.tcx().lang_items().get(item) == Some(id))\n    }\n\n    /// If this definition is an impl block gets its type.\n    #[inline]\n    fn opt_impl_ty<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<EarlyBinder<'tcx, Ty<'tcx>>> {\n        match self.opt_def(tcx) {\n            Some((DefKind::Impl { .. }, id)) => Some(tcx.tcx().type_of(id)),\n            _ => None,\n        }\n    }\n\n    /// Gets the parent of this definition if it has one.\n    #[inline]\n    fn opt_parent<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<DefId> {\n        self.opt_def_id().and_then(|id| tcx.tcx().opt_parent(id))\n    }\n\n    /// Checks if this definition is an impl block.\n    #[inline]\n    fn is_impl<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> bool {\n        matches!(self.opt_def(tcx), Some((DefKind::Impl { .. }, _)))\n    }\n\n    /// If this definition is a constructor gets the `DefId` of it's type or variant.\n    #[inline]\n    fn ctor_parent<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<DefId> {\n        match self.opt_def(tcx) {\n            Some((DefKind::Ctor(..), id)) => tcx.tcx().opt_parent(id),\n            _ => None,\n        }\n    }\n\n    /// If this definition is an associated item of an impl or trait gets the\n    /// `DefId` of its parent.\n    #[inline]\n    fn assoc_parent<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<DefId> {\n        match self.opt_def(tcx) {\n            Some((DefKind::AssocConst { .. } | DefKind::AssocFn | DefKind::AssocTy, id)) => tcx.tcx().opt_parent(id),\n            _ => None,\n        }\n    }\n\n    /// If this definition is an associated function of an impl or trait gets the\n    /// `DefId` of its parent.\n    #[inline]\n    fn assoc_fn_parent<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<DefId> {\n        match self.opt_def(tcx) {\n            Some((DefKind::AssocFn, id)) => tcx.tcx().opt_parent(id),\n            _ => None,\n        }\n    }\n}\nimpl MaybeDef for DefId {\n    #[inline]\n    fn opt_def_id(self) -> Option<DefId> {\n        Some(self)\n    }\n\n    #[inline]\n    fn opt_def<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)> {\n        self.opt_def_id().map(|id| (tcx.tcx().def_kind(id), id))\n    }\n}\nimpl MaybeDef for (DefKind, DefId) {\n    #[inline]\n    fn opt_def_id(self) -> Option<DefId> {\n        Some(self.1)\n    }\n\n    #[inline]\n    fn opt_def<'tcx>(self, _: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)> {\n        Some(self)\n    }\n}\nimpl MaybeDef for AdtDef<'_> {\n    #[inline]\n    fn opt_def_id(self) -> Option<DefId> {\n        Some(self.did())\n    }\n\n    #[inline]\n    fn opt_def<'tcx>(self, _: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)> {\n        let did = self.did();\n        match self.adt_kind() {\n            AdtKind::Enum => Some((DefKind::Enum, did)),\n            AdtKind::Struct => Some((DefKind::Struct, did)),\n            AdtKind::Union => Some((DefKind::Union, did)),\n        }\n    }\n}\nimpl MaybeDef for Ty<'_> {\n    #[inline]\n    fn opt_def_id(self) -> Option<DefId> {\n        self.ty_adt_def().opt_def_id()\n    }\n\n    #[inline]\n    fn opt_def<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)> {\n        self.ty_adt_def().opt_def(tcx)\n    }\n}\nimpl MaybeDef for Res {\n    #[inline]\n    fn opt_def_id(self) -> Option<DefId> {\n        Res::opt_def_id(&self)\n    }\n\n    #[inline]\n    fn opt_def<'tcx>(self, _: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)> {\n        match self {\n            Res::Def(kind, id) => Some((kind, id)),\n            _ => None,\n        }\n    }\n}\nimpl<T: MaybeDef> MaybeDef for Option<T> {\n    #[inline]\n    fn opt_def_id(self) -> Option<DefId> {\n        self.and_then(T::opt_def_id)\n    }\n\n    #[inline]\n    fn opt_def<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)> {\n        self.and_then(|x| T::opt_def(x, tcx))\n    }\n}\nimpl<T: MaybeDef> MaybeDef for EarlyBinder<'_, T> {\n    #[inline]\n    fn opt_def_id(self) -> Option<DefId> {\n        self.skip_binder().opt_def_id()\n    }\n\n    #[inline]\n    fn opt_def<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)> {\n        self.skip_binder().opt_def(tcx)\n    }\n}\nimpl<T: MaybeDef> MaybeDef for Binder<'_, T> {\n    #[inline]\n    fn opt_def_id(self) -> Option<DefId> {\n        self.skip_binder().opt_def_id()\n    }\n\n    #[inline]\n    fn opt_def<'tcx>(self, tcx: &impl HasTyCtxt<'tcx>) -> Option<(DefKind, DefId)> {\n        self.skip_binder().opt_def(tcx)\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/source.rs",
    "content": "//! Utils for extracting, inspecting or transforming source code\n\n#![allow(clippy::module_name_repetitions)]\n\nuse std::sync::Arc;\n\nuse rustc_ast::{LitKind, StrStyle};\nuse rustc_errors::Applicability;\nuse rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource};\nuse rustc_lexer::{FrontmatterAllowed, LiteralKind, TokenKind, tokenize};\nuse rustc_lint::{EarlyContext, LateContext};\nuse rustc_middle::ty::TyCtxt;\nuse rustc_session::Session;\nuse rustc_span::source_map::{SourceMap, original_sp};\nuse rustc_span::{\n    BytePos, DUMMY_SP, DesugaringKind, Pos, RelativeBytePos, SourceFile, SourceFileAndLine, Span, SpanData,\n    SyntaxContext, hygiene,\n};\nuse std::borrow::Cow;\nuse std::fmt;\nuse std::ops::{Deref, Index, Range};\n\npub trait HasSession {\n    fn sess(&self) -> &Session;\n}\nimpl HasSession for Session {\n    fn sess(&self) -> &Session {\n        self\n    }\n}\nimpl HasSession for TyCtxt<'_> {\n    fn sess(&self) -> &Session {\n        self.sess\n    }\n}\nimpl HasSession for EarlyContext<'_> {\n    fn sess(&self) -> &Session {\n        ::rustc_lint::LintContext::sess(self)\n    }\n}\nimpl HasSession for LateContext<'_> {\n    fn sess(&self) -> &Session {\n        self.tcx.sess()\n    }\n}\n\n/// Conversion of a value into the range portion of a `Span`.\npub trait SpanRange: Sized {\n    fn into_range(self) -> Range<BytePos>;\n}\nimpl SpanRange for Span {\n    fn into_range(self) -> Range<BytePos> {\n        let data = self.data();\n        data.lo..data.hi\n    }\n}\nimpl SpanRange for SpanData {\n    fn into_range(self) -> Range<BytePos> {\n        self.lo..self.hi\n    }\n}\nimpl SpanRange for Range<BytePos> {\n    fn into_range(self) -> Range<BytePos> {\n        self\n    }\n}\n\n/// Conversion of a value into a `Span`\npub trait IntoSpan: Sized {\n    fn into_span(self) -> Span;\n    fn with_ctxt(self, ctxt: SyntaxContext) -> Span;\n}\nimpl IntoSpan for Span {\n    fn into_span(self) -> Span {\n        self\n    }\n    fn with_ctxt(self, ctxt: SyntaxContext) -> Span {\n        self.with_ctxt(ctxt)\n    }\n}\nimpl IntoSpan for SpanData {\n    fn into_span(self) -> Span {\n        self.span()\n    }\n    fn with_ctxt(self, ctxt: SyntaxContext) -> Span {\n        Span::new(self.lo, self.hi, ctxt, self.parent)\n    }\n}\nimpl IntoSpan for Range<BytePos> {\n    fn into_span(self) -> Span {\n        Span::with_root_ctxt(self.start, self.end)\n    }\n    fn with_ctxt(self, ctxt: SyntaxContext) -> Span {\n        Span::new(self.start, self.end, ctxt, None)\n    }\n}\n\npub trait SpanRangeExt: SpanRange {\n    /// Attempts to get a handle to the source text. Returns `None` if either the span is malformed,\n    /// or the source text is not accessible.\n    fn get_source_text(self, cx: &impl HasSession) -> Option<SourceText> {\n        get_source_range(cx.sess().source_map(), self.into_range()).and_then(SourceText::new)\n    }\n\n    /// Gets the source file, and range in the file, of the given span. Returns `None` if the span\n    /// extends through multiple files, or is malformed.\n    fn get_source_range(self, cx: &impl HasSession) -> Option<SourceFileRange> {\n        get_source_range(cx.sess().source_map(), self.into_range())\n    }\n\n    /// Calls the given function with the source text referenced and returns the value. Returns\n    /// `None` if the source text cannot be retrieved.\n    fn with_source_text<T>(self, cx: &impl HasSession, f: impl for<'a> FnOnce(&'a str) -> T) -> Option<T> {\n        with_source_text(cx.sess().source_map(), self.into_range(), f)\n    }\n\n    /// Checks if the referenced source text satisfies the given predicate. Returns `false` if the\n    /// source text cannot be retrieved.\n    fn check_source_text(self, cx: &impl HasSession, pred: impl for<'a> FnOnce(&'a str) -> bool) -> bool {\n        self.with_source_text(cx, pred).unwrap_or(false)\n    }\n\n    /// Calls the given function with the both the text of the source file and the referenced range,\n    /// and returns the value. Returns `None` if the source text cannot be retrieved.\n    fn with_source_text_and_range<T>(\n        self,\n        cx: &impl HasSession,\n        f: impl for<'a> FnOnce(&'a str, Range<usize>) -> T,\n    ) -> Option<T> {\n        with_source_text_and_range(cx.sess().source_map(), self.into_range(), f)\n    }\n\n    /// Calls the given function with the both the text of the source file and the referenced range,\n    /// and creates a new span with the returned range. Returns `None` if the source text cannot be\n    /// retrieved, or no result is returned.\n    ///\n    /// The new range must reside within the same source file.\n    fn map_range(\n        self,\n        cx: &impl HasSession,\n        f: impl for<'a> FnOnce(&'a SourceFile, &'a str, Range<usize>) -> Option<Range<usize>>,\n    ) -> Option<Range<BytePos>> {\n        map_range(cx.sess().source_map(), self.into_range(), f)\n    }\n\n    /// Extends the range to include all preceding whitespace characters.\n    ///\n    /// The range will not be expanded if it would cross a line boundary, the line the range would\n    /// be extended to ends with a line comment and the text after the range contains a\n    /// non-whitespace character on the same line. e.g.\n    ///\n    /// ```ignore\n    /// ( // Some comment\n    /// foo)\n    /// ```\n    ///\n    /// When the range points to `foo`, suggesting to remove the range after it's been extended will\n    /// cause the `)` to be placed inside the line comment as `( // Some comment)`.\n    fn with_leading_whitespace(self, cx: &impl HasSession) -> Range<BytePos> {\n        with_leading_whitespace(cx.sess().source_map(), self.into_range())\n    }\n\n    /// Trims the leading whitespace from the range.\n    fn trim_start(self, cx: &impl HasSession) -> Range<BytePos> {\n        trim_start(cx.sess().source_map(), self.into_range())\n    }\n}\nimpl<T: SpanRange> SpanRangeExt for T {}\n\n/// Handle to a range of text in a source file.\npub struct SourceText(SourceFileRange);\nimpl SourceText {\n    /// Takes ownership of the source file handle if the source text is accessible.\n    pub fn new(text: SourceFileRange) -> Option<Self> {\n        if text.as_str().is_some() {\n            Some(Self(text))\n        } else {\n            None\n        }\n    }\n\n    /// Gets the source text.\n    pub fn as_str(&self) -> &str {\n        self.0.as_str().unwrap()\n    }\n\n    /// Converts this into an owned string.\n    pub fn to_owned(&self) -> String {\n        self.as_str().to_owned()\n    }\n}\nimpl Deref for SourceText {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.as_str()\n    }\n}\nimpl AsRef<str> for SourceText {\n    fn as_ref(&self) -> &str {\n        self.as_str()\n    }\n}\nimpl<T> Index<T> for SourceText\nwhere\n    str: Index<T>,\n{\n    type Output = <str as Index<T>>::Output;\n    fn index(&self, idx: T) -> &Self::Output {\n        &self.as_str()[idx]\n    }\n}\nimpl fmt::Display for SourceText {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.as_str().fmt(f)\n    }\n}\nimpl fmt::Debug for SourceText {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.as_str().fmt(f)\n    }\n}\n\nfn get_source_range(sm: &SourceMap, sp: Range<BytePos>) -> Option<SourceFileRange> {\n    let start = sm.lookup_byte_offset(sp.start);\n    let end = sm.lookup_byte_offset(sp.end);\n    if !Arc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos {\n        return None;\n    }\n    sm.ensure_source_file_source_present(&start.sf);\n    let range = start.pos.to_usize()..end.pos.to_usize();\n    Some(SourceFileRange { sf: start.sf, range })\n}\n\nfn with_source_text<T>(sm: &SourceMap, sp: Range<BytePos>, f: impl for<'a> FnOnce(&'a str) -> T) -> Option<T> {\n    if let Some(src) = get_source_range(sm, sp)\n        && let Some(src) = src.as_str()\n    {\n        Some(f(src))\n    } else {\n        None\n    }\n}\n\nfn with_source_text_and_range<T>(\n    sm: &SourceMap,\n    sp: Range<BytePos>,\n    f: impl for<'a> FnOnce(&'a str, Range<usize>) -> T,\n) -> Option<T> {\n    if let Some(src) = get_source_range(sm, sp)\n        && let Some(text) = &src.sf.src\n    {\n        Some(f(text, src.range))\n    } else {\n        None\n    }\n}\n\n#[expect(clippy::cast_possible_truncation)]\nfn map_range(\n    sm: &SourceMap,\n    sp: Range<BytePos>,\n    f: impl for<'a> FnOnce(&'a SourceFile, &'a str, Range<usize>) -> Option<Range<usize>>,\n) -> Option<Range<BytePos>> {\n    if let Some(src) = get_source_range(sm, sp.clone())\n        && let Some(text) = &src.sf.src\n        && let Some(range) = f(&src.sf, text, src.range.clone())\n    {\n        debug_assert!(\n            range.start <= text.len() && range.end <= text.len(),\n            \"Range `{range:?}` is outside the source file (file `{}`, length `{}`)\",\n            src.sf.name.prefer_local_unconditionally(),\n            text.len(),\n        );\n        debug_assert!(range.start <= range.end, \"Range `{range:?}` has overlapping bounds\");\n        let dstart = (range.start as u32).wrapping_sub(src.range.start as u32);\n        let dend = (range.end as u32).wrapping_sub(src.range.start as u32);\n        Some(BytePos(sp.start.0.wrapping_add(dstart))..BytePos(sp.start.0.wrapping_add(dend)))\n    } else {\n        None\n    }\n}\n\nfn ends_with_line_comment_or_broken(text: &str) -> bool {\n    let Some(last) = tokenize(text, FrontmatterAllowed::No).last() else {\n        return false;\n    };\n    match last.kind {\n        // Will give the wrong result on text like `\" // \"` where the first quote ends a string\n        // started earlier. The only workaround is to lex the whole file which we don't really want\n        // to do.\n        TokenKind::LineComment { .. } | TokenKind::BlockComment { terminated: false, .. } => true,\n        TokenKind::Literal { kind, .. } => matches!(\n            kind,\n            LiteralKind::Byte { terminated: false }\n                | LiteralKind::ByteStr { terminated: false }\n                | LiteralKind::CStr { terminated: false }\n                | LiteralKind::Char { terminated: false }\n                | LiteralKind::RawByteStr { n_hashes: None }\n                | LiteralKind::RawCStr { n_hashes: None }\n                | LiteralKind::RawStr { n_hashes: None }\n        ),\n        _ => false,\n    }\n}\n\nfn with_leading_whitespace_inner(lines: &[RelativeBytePos], src: &str, range: Range<usize>) -> Option<usize> {\n    debug_assert!(lines.is_empty() || lines[0].to_u32() == 0);\n\n    let start = src.get(..range.start)?.trim_end();\n    let next_line = lines.partition_point(|&pos| pos.to_usize() <= start.len());\n    if let Some(line_end) = lines.get(next_line)\n        && line_end.to_usize() <= range.start\n        && let prev_start = lines.get(next_line - 1).map_or(0, |&x| x.to_usize())\n        && ends_with_line_comment_or_broken(&start[prev_start..])\n        && let next_line = lines.partition_point(|&pos| pos.to_usize() < range.end)\n        && let next_start = lines.get(next_line).map_or(src.len(), |&x| x.to_usize())\n        && tokenize(src.get(range.end..next_start)?, FrontmatterAllowed::No)\n            .any(|t| !matches!(t.kind, TokenKind::Whitespace))\n    {\n        Some(range.start)\n    } else {\n        Some(start.len())\n    }\n}\n\nfn with_leading_whitespace(sm: &SourceMap, sp: Range<BytePos>) -> Range<BytePos> {\n    map_range(sm, sp.clone(), |sf, src, range| {\n        Some(with_leading_whitespace_inner(sf.lines(), src, range.clone())?..range.end)\n    })\n    .unwrap_or(sp)\n}\n\nfn trim_start(sm: &SourceMap, sp: Range<BytePos>) -> Range<BytePos> {\n    map_range(sm, sp.clone(), |_, src, range| {\n        let src = src.get(range.clone())?;\n        Some(range.start + (src.len() - src.trim_start().len())..range.end)\n    })\n    .unwrap_or(sp)\n}\n\npub struct SourceFileRange {\n    pub sf: Arc<SourceFile>,\n    pub range: Range<usize>,\n}\nimpl SourceFileRange {\n    /// Attempts to get the text from the source file. This can fail if the source text isn't\n    /// loaded.\n    pub fn as_str(&self) -> Option<&str> {\n        (self.sf.src.as_ref().map(|src| src.as_str()))\n            .or_else(|| self.sf.external_src.get()?.get_source())\n            .and_then(|x| x.get(self.range.clone()))\n    }\n}\n\n/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block` with no label.\npub fn expr_block(\n    sess: &impl HasSession,\n    expr: &Expr<'_>,\n    outer: SyntaxContext,\n    default: &str,\n    indent_relative_to: Option<Span>,\n    app: &mut Applicability,\n) -> String {\n    let (code, from_macro) = snippet_block_with_context(sess, expr.span, outer, default, indent_relative_to, app);\n    if !from_macro\n        && let ExprKind::Block(block, None) = expr.kind\n        && block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)\n    {\n        code\n    } else {\n        // FIXME: add extra indent for the unsafe blocks:\n        //     original code:   unsafe { ... }\n        //     result code:     { unsafe { ... } }\n        //     desired code:    {\\n  unsafe { ... }\\n}\n        format!(\"{{ {code} }}\")\n    }\n}\n\n/// Returns a new Span that extends the original Span to the first non-whitespace char of the first\n/// line.\n///\n/// ```rust,ignore\n///     let x = ();\n/// //          ^^\n/// // will be converted to\n///     let x = ();\n/// //  ^^^^^^^^^^\n/// ```\npub fn first_line_of_span(sess: &impl HasSession, span: Span) -> Span {\n    first_char_in_first_line(sess, span).map_or(span, |first_char_pos| span.with_lo(first_char_pos))\n}\n\nfn first_char_in_first_line(sess: &impl HasSession, span: Span) -> Option<BytePos> {\n    let line_span = line_span(sess, span);\n    snippet_opt(sess, line_span).and_then(|snip| {\n        snip.find(|c: char| !c.is_whitespace())\n            .map(|pos| line_span.lo() + BytePos::from_usize(pos))\n    })\n}\n\n/// Extends the span to the beginning of the spans line, incl. whitespaces.\n///\n/// ```no_run\n///        let x = ();\n/// //             ^^\n/// // will be converted to\n///        let x = ();\n/// // ^^^^^^^^^^^^^^\n/// ```\nfn line_span(sess: &impl HasSession, span: Span) -> Span {\n    let span = original_sp(span, DUMMY_SP);\n    let SourceFileAndLine { sf, line } = sess.sess().source_map().lookup_line(span.lo()).unwrap();\n    let line_start = sf.lines()[line];\n    let line_start = sf.absolute_position(line_start);\n    span.with_lo(line_start)\n}\n\n/// Returns the indentation of the line of a span\n///\n/// ```rust,ignore\n/// let x = ();\n/// //      ^^ -- will return 0\n///     let x = ();\n/// //          ^^ -- will return 4\n/// ```\npub fn indent_of(sess: &impl HasSession, span: Span) -> Option<usize> {\n    snippet_opt(sess, line_span(sess, span)).and_then(|snip| snip.find(|c: char| !c.is_whitespace()))\n}\n\n/// Gets a snippet of the indentation of the line of a span\npub fn snippet_indent(sess: &impl HasSession, span: Span) -> Option<String> {\n    snippet_opt(sess, line_span(sess, span)).map(|mut s| {\n        let len = s.len() - s.trim_start().len();\n        s.truncate(len);\n        s\n    })\n}\n\n// If the snippet is empty, it's an attribute that was inserted during macro\n// expansion and we want to ignore those, because they could come from external\n// sources that the user has no control over.\n// For some reason these attributes don't have any expansion info on them, so\n// we have to check it this way until there is a better way.\npub fn is_present_in_source(sess: &impl HasSession, span: Span) -> bool {\n    if let Some(snippet) = snippet_opt(sess, span)\n        && snippet.is_empty()\n    {\n        return false;\n    }\n    true\n}\n\n/// Returns the position just before rarrow\n///\n/// ```rust,ignore\n/// fn into(self) -> () {}\n///              ^\n/// // in case of unformatted code\n/// fn into2(self)-> () {}\n///               ^\n/// fn into3(self)   -> () {}\n///               ^\n/// ```\npub fn position_before_rarrow(s: &str) -> Option<usize> {\n    s.rfind(\"->\").map(|rpos| {\n        let mut rpos = rpos;\n        let chars: Vec<char> = s.chars().collect();\n        while rpos > 1 {\n            if let Some(c) = chars.get(rpos - 1)\n                && c.is_whitespace()\n            {\n                rpos -= 1;\n                continue;\n            }\n            break;\n        }\n        rpos\n    })\n}\n\n/// Reindent a multiline string with possibility of ignoring the first line.\npub fn reindent_multiline(s: &str, ignore_first: bool, indent: Option<usize>) -> String {\n    let s_space = reindent_multiline_inner(s, ignore_first, indent, ' ');\n    let s_tab = reindent_multiline_inner(&s_space, ignore_first, indent, '\\t');\n    reindent_multiline_inner(&s_tab, ignore_first, indent, ' ')\n}\n\nfn reindent_multiline_inner(s: &str, ignore_first: bool, indent: Option<usize>, ch: char) -> String {\n    let x = s\n        .lines()\n        .skip(usize::from(ignore_first))\n        .filter_map(|l| {\n            if l.is_empty() {\n                None\n            } else {\n                // ignore empty lines\n                Some(l.char_indices().find(|&(_, x)| x != ch).unwrap_or((l.len(), ch)).0)\n            }\n        })\n        .min()\n        .unwrap_or(0);\n    let indent = indent.unwrap_or(0);\n    s.lines()\n        .enumerate()\n        .map(|(i, l)| {\n            if (ignore_first && i == 0) || l.is_empty() {\n                l.to_owned()\n            } else if x > indent {\n                l.split_at(x - indent).1.to_owned()\n            } else {\n                \" \".repeat(indent - x) + l\n            }\n        })\n        .collect::<Vec<String>>()\n        .join(\"\\n\")\n}\n\n/// Converts a span to a code snippet if available, otherwise returns the default.\n///\n/// This is useful if you want to provide suggestions for your lint or more generally, if you want\n/// to convert a given `Span` to a `str`. To create suggestions consider using\n/// [`snippet_with_applicability`] to ensure that the applicability stays correct.\n///\n/// # Example\n/// ```rust,ignore\n/// // Given two spans one for `value` and one for the `init` expression.\n/// let value = Vec::new();\n/// //  ^^^^^   ^^^^^^^^^^\n/// //  span1   span2\n///\n/// // The snipped call would return the corresponding code snippet\n/// snippet(cx, span1, \"..\") // -> \"value\"\n/// snippet(cx, span2, \"..\") // -> \"Vec::new()\"\n/// ```\npub fn snippet<'a>(sess: &impl HasSession, span: Span, default: &'a str) -> Cow<'a, str> {\n    snippet_opt(sess, span).map_or_else(|| Cow::Borrowed(default), From::from)\n}\n\n/// Same as [`snippet`], but it adapts the applicability level by following rules:\n///\n/// - Applicability level `Unspecified` will never be changed.\n/// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`.\n/// - If the default value is used and the applicability level is `MachineApplicable`, change it to\n///   `HasPlaceholders`\npub fn snippet_with_applicability<'a>(\n    sess: &impl HasSession,\n    span: Span,\n    default: &'a str,\n    applicability: &mut Applicability,\n) -> Cow<'a, str> {\n    snippet_with_applicability_sess(sess.sess(), span, default, applicability)\n}\n\nfn snippet_with_applicability_sess<'a>(\n    sess: &Session,\n    span: Span,\n    default: &'a str,\n    applicability: &mut Applicability,\n) -> Cow<'a, str> {\n    if *applicability != Applicability::Unspecified && span.from_expansion() {\n        *applicability = Applicability::MaybeIncorrect;\n    }\n    snippet_opt(sess, span).map_or_else(\n        || {\n            if *applicability == Applicability::MachineApplicable {\n                *applicability = Applicability::HasPlaceholders;\n            }\n            Cow::Borrowed(default)\n        },\n        From::from,\n    )\n}\n\n/// Converts a span to a code snippet. Returns `None` if not available.\npub fn snippet_opt(sess: &impl HasSession, span: Span) -> Option<String> {\n    sess.sess().source_map().span_to_snippet(span).ok()\n}\n\n/// Converts a span (from a block) to a code snippet if available, otherwise use default.\n///\n/// This trims the code of indentation, except for the first line. Use it for blocks or block-like\n/// things which need to be printed as such.\n///\n/// The `indent_relative_to` arg can be used, to provide a span, where the indentation of the\n/// resulting snippet of the given span.\n///\n/// # Example\n///\n/// ```rust,ignore\n/// snippet_block(cx, block.span, \"..\", None)\n/// // where, `block` is the block of the if expr\n///     if x {\n///         y;\n///     }\n/// // will return the snippet\n/// {\n///     y;\n/// }\n/// ```\n///\n/// ```rust,ignore\n/// snippet_block(cx, block.span, \"..\", Some(if_expr.span))\n/// // where, `block` is the block of the if expr\n///     if x {\n///         y;\n///     }\n/// // will return the snippet\n/// {\n///         y;\n///     } // aligned with `if`\n/// ```\n/// Note that the first line of the snippet always has 0 indentation.\npub fn snippet_block(sess: &impl HasSession, span: Span, default: &str, indent_relative_to: Option<Span>) -> String {\n    let snip = snippet(sess, span, default);\n    let indent = indent_relative_to.and_then(|s| indent_of(sess, s));\n    reindent_multiline(&snip, true, indent)\n}\n\n/// Same as `snippet_block`, but adapts the applicability level by the rules of\n/// `snippet_with_applicability`.\npub fn snippet_block_with_applicability(\n    sess: &impl HasSession,\n    span: Span,\n    default: &str,\n    indent_relative_to: Option<Span>,\n    applicability: &mut Applicability,\n) -> String {\n    let snip = snippet_with_applicability(sess, span, default, applicability);\n    let indent = indent_relative_to.and_then(|s| indent_of(sess, s));\n    reindent_multiline(&snip, true, indent)\n}\n\npub fn snippet_block_with_context(\n    sess: &impl HasSession,\n    span: Span,\n    outer: SyntaxContext,\n    default: &str,\n    indent_relative_to: Option<Span>,\n    app: &mut Applicability,\n) -> (String, bool) {\n    let (snip, from_macro) = snippet_with_context(sess, span, outer, default, app);\n    let indent = indent_relative_to.and_then(|s| indent_of(sess, s));\n    (reindent_multiline(&snip, true, indent), from_macro)\n}\n\n/// Same as `snippet_with_applicability`, but first walks the span up to the given context.\n///\n/// This will result in the macro call, rather than the expansion, if the span is from a child\n/// context. If the span is not from a child context, it will be used directly instead.\n///\n/// e.g. Given the expression `&vec![]`, getting a snippet from the span for `vec![]` as a HIR node\n/// would result in `box []`. If given the context of the address of expression, this function will\n/// correctly get a snippet of `vec![]`.\n///\n/// This will also return whether or not the snippet is a macro call.\npub fn snippet_with_context<'a>(\n    sess: &impl HasSession,\n    span: Span,\n    outer: SyntaxContext,\n    default: &'a str,\n    applicability: &mut Applicability,\n) -> (Cow<'a, str>, bool) {\n    snippet_with_context_sess(sess.sess(), span, outer, default, applicability)\n}\n\nfn snippet_with_context_sess<'a>(\n    sess: &Session,\n    span: Span,\n    outer: SyntaxContext,\n    default: &'a str,\n    applicability: &mut Applicability,\n) -> (Cow<'a, str>, bool) {\n    // If it is just range desugaring, use the desugaring span since it may include parenthesis.\n    if span.desugaring_kind() == Some(DesugaringKind::RangeExpr) && span.parent_callsite().unwrap().ctxt() == outer {\n        return (\n            snippet_with_applicability_sess(sess, span, default, applicability),\n            false,\n        );\n    }\n\n    let (span, is_macro_call) = walk_span_to_context(span, outer).map_or_else(\n        || {\n            // The span is from a macro argument, and the outer context is the macro using the argument\n            if *applicability != Applicability::Unspecified {\n                *applicability = Applicability::MaybeIncorrect;\n            }\n            // TODO: get the argument span.\n            (span, false)\n        },\n        |outer_span| (outer_span, span.ctxt() != outer),\n    );\n\n    (\n        snippet_with_applicability_sess(sess, span, default, applicability),\n        is_macro_call,\n    )\n}\n\n/// Walks the span up to the target context, thereby returning the macro call site if the span is\n/// inside a macro expansion, or the original span if it is not.\n///\n/// Note this will return `None` in the case of the span being in a macro expansion, but the target\n/// context is from expanding a macro argument.\n///\n/// Given the following\n///\n/// ```rust,ignore\n/// macro_rules! m { ($e:expr) => { f($e) }; }\n/// g(m!(0))\n/// ```\n///\n/// If called with a span of the call to `f` and a context of the call to `g` this will return a\n/// span containing `m!(0)`. However, if called with a span of the literal `0` this will give a span\n/// containing `0` as the context is the same as the outer context.\n///\n/// This will traverse through multiple macro calls. Given the following:\n///\n/// ```rust,ignore\n/// macro_rules! m { ($e:expr) => { n!($e, 0) }; }\n/// macro_rules! n { ($e:expr, $f:expr) => { f($e, $f) }; }\n/// g(m!(0))\n/// ```\n///\n/// If called with a span of the call to `f` and a context of the call to `g` this will return a\n/// span containing `m!(0)`.\npub fn walk_span_to_context(span: Span, outer: SyntaxContext) -> Option<Span> {\n    let outer_span = hygiene::walk_chain(span, outer);\n    (outer_span.ctxt() == outer).then_some(outer_span)\n}\n\n/// Trims the whitespace from the start and the end of the span.\npub fn trim_span(sm: &SourceMap, span: Span) -> Span {\n    let data = span.data();\n    let sf: &_ = &sm.lookup_source_file(data.lo);\n    let Some(src) = sf.src.as_deref() else {\n        return span;\n    };\n    let Some(snip) = &src.get((data.lo - sf.start_pos).to_usize()..(data.hi - sf.start_pos).to_usize()) else {\n        return span;\n    };\n    let trim_start = snip.len() - snip.trim_start().len();\n    let trim_end = snip.len() - snip.trim_end().len();\n    SpanData {\n        lo: data.lo + BytePos::from_usize(trim_start),\n        hi: data.hi - BytePos::from_usize(trim_end),\n        ctxt: data.ctxt,\n        parent: data.parent,\n    }\n    .span()\n}\n\n/// Expand a span to include a preceding comma\n/// ```rust,ignore\n/// writeln!(o, \"\")   ->   writeln!(o, \"\")\n///             ^^                   ^^^^\n/// ```\npub fn expand_past_previous_comma(sess: &impl HasSession, span: Span) -> Span {\n    let extended = sess.sess().source_map().span_extend_to_prev_char(span, ',', true);\n    extended.with_lo(extended.lo() - BytePos(1))\n}\n\n/// Converts `expr` to a `char` literal if it's a `str` literal containing a single\n/// character (or a single byte with `ascii_only`)\npub fn str_literal_to_char_literal(\n    sess: &impl HasSession,\n    expr: &Expr<'_>,\n    applicability: &mut Applicability,\n    ascii_only: bool,\n) -> Option<String> {\n    if let ExprKind::Lit(lit) = &expr.kind\n        && let LitKind::Str(r, style) = lit.node\n        && let string = r.as_str()\n        && let len = if ascii_only {\n            string.len()\n        } else {\n            string.chars().count()\n        }\n        && len == 1\n    {\n        let snip = snippet_with_applicability(sess, expr.span, string, applicability);\n        let ch = if let StrStyle::Raw(nhash) = style {\n            let nhash = nhash as usize;\n            // for raw string: r##\"a\"##\n            &snip[(nhash + 2)..(snip.len() - 1 - nhash)]\n        } else {\n            // for regular string: \"a\"\n            &snip[1..(snip.len() - 1)]\n        };\n\n        let hint = format!(\n            \"'{}'\",\n            match ch {\n                \"'\" => \"\\\\'\",\n                r\"\\\" => \"\\\\\\\\\",\n                \"\\\\\\\"\" => \"\\\"\", // no need to escape `\"` in `'\"'`\n                _ => ch,\n            }\n        );\n\n        Some(hint)\n    } else {\n        None\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::reindent_multiline;\n\n    #[test]\n    fn test_reindent_multiline_single_line() {\n        assert_eq!(\"\", reindent_multiline(\"\", false, None));\n        assert_eq!(\"...\", reindent_multiline(\"...\", false, None));\n        assert_eq!(\"...\", reindent_multiline(\"    ...\", false, None));\n        assert_eq!(\"...\", reindent_multiline(\"\\t...\", false, None));\n        assert_eq!(\"...\", reindent_multiline(\"\\t\\t...\", false, None));\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_reindent_multiline_block() {\n        assert_eq!(\"\\\n    if x {\n        y\n    } else {\n        z\n    }\", reindent_multiline(\"    if x {\n            y\n        } else {\n            z\n        }\", false, None));\n        assert_eq!(\"\\\n    if x {\n    \\ty\n    } else {\n    \\tz\n    }\", reindent_multiline(\"    if x {\n        \\ty\n        } else {\n        \\tz\n        }\", false, None));\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_reindent_multiline_empty_line() {\n        assert_eq!(\"\\\n    if x {\n        y\n\n    } else {\n        z\n    }\", reindent_multiline(\"    if x {\n            y\n\n        } else {\n            z\n        }\", false, None));\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_reindent_multiline_lines_deeper() {\n        assert_eq!(\"\\\n        if x {\n            y\n        } else {\n            z\n        }\", reindent_multiline(\"\\\n    if x {\n        y\n    } else {\n        z\n    }\", true, Some(8)));\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/str_utils.rs",
    "content": "/// Dealing with string indices can be hard, this struct ensures that both the\n/// character and byte index are provided for correct indexing.\n#[derive(Debug, Default, PartialEq, Eq)]\npub struct StrIndex {\n    pub char_index: usize,\n    pub byte_index: usize,\n}\n\nimpl StrIndex {\n    pub fn new(char_index: usize, byte_index: usize) -> Self {\n        Self { char_index, byte_index }\n    }\n}\n\n/// Returns the index of the character after the first camel-case component of `s`.\n///\n/// ```no_run\n/// # use clippy_utils::str_utils::{camel_case_until, StrIndex};\n/// assert_eq!(camel_case_until(\"AbcDef\"), StrIndex::new(6, 6));\n/// assert_eq!(camel_case_until(\"ABCD\"), StrIndex::new(0, 0));\n/// assert_eq!(camel_case_until(\"AbcDD\"), StrIndex::new(3, 3));\n/// assert_eq!(camel_case_until(\"Abc\\u{f6}\\u{f6}DD\"), StrIndex::new(5, 7));\n/// ```\n#[must_use]\npub fn camel_case_until(s: &str) -> StrIndex {\n    let mut iter = s.char_indices().enumerate();\n    if let Some((_char_index, (_, first))) = iter.next() {\n        if !first.is_uppercase() {\n            return StrIndex::new(0, 0);\n        }\n    } else {\n        return StrIndex::new(0, 0);\n    }\n    let mut up = true;\n    let mut last_index = StrIndex::new(0, 0);\n    for (char_index, (byte_index, c)) in iter {\n        if up {\n            if c.is_lowercase() {\n                up = false;\n            } else {\n                return last_index;\n            }\n        } else if c.is_uppercase() {\n            up = true;\n            last_index.byte_index = byte_index;\n            last_index.char_index = char_index;\n        } else if !c.is_lowercase() {\n            return StrIndex::new(char_index, byte_index);\n        }\n    }\n\n    if up {\n        last_index\n    } else {\n        StrIndex::new(s.chars().count(), s.len())\n    }\n}\n\n/// Returns index of the first camel-case component of `s`.\n///\n/// ```no_run\n/// # use clippy_utils::str_utils::{camel_case_start, StrIndex};\n/// assert_eq!(camel_case_start(\"AbcDef\"), StrIndex::new(0, 0));\n/// assert_eq!(camel_case_start(\"abcDef\"), StrIndex::new(3, 3));\n/// assert_eq!(camel_case_start(\"ABCD\"), StrIndex::new(4, 4));\n/// assert_eq!(camel_case_start(\"abcd\"), StrIndex::new(4, 4));\n/// assert_eq!(camel_case_start(\"\\u{f6}\\u{f6}cd\"), StrIndex::new(4, 6));\n/// ```\n#[must_use]\npub fn camel_case_start(s: &str) -> StrIndex {\n    camel_case_start_from_idx(s, 0)\n}\n\n/// Returns `StrIndex` of the last camel-case component of `s[idx..]`.\n///\n/// ```no_run\n/// # use clippy_utils::str_utils::{camel_case_start_from_idx, StrIndex};\n/// assert_eq!(camel_case_start_from_idx(\"AbcDef\", 0), StrIndex::new(0, 0));\n/// assert_eq!(camel_case_start_from_idx(\"AbcDef\", 1), StrIndex::new(3, 3));\n/// assert_eq!(camel_case_start_from_idx(\"AbcDefGhi\", 0), StrIndex::new(0, 0));\n/// assert_eq!(camel_case_start_from_idx(\"AbcDefGhi\", 1), StrIndex::new(3, 3));\n/// assert_eq!(camel_case_start_from_idx(\"Abcdefg\", 1), StrIndex::new(7, 7));\n/// ```\npub fn camel_case_start_from_idx(s: &str, start_idx: usize) -> StrIndex {\n    let char_count = s.chars().count();\n    let range = 0..char_count;\n    let mut iter = range.rev().zip(s.char_indices().rev());\n    if let Some((_, (_, first))) = iter.next() {\n        if !first.is_lowercase() {\n            return StrIndex::new(char_count, s.len());\n        }\n    } else {\n        return StrIndex::new(char_count, s.len());\n    }\n\n    let mut down = true;\n    let mut last_index = StrIndex::new(char_count, s.len());\n    for (char_index, (byte_index, c)) in iter {\n        if byte_index < start_idx {\n            break;\n        }\n        if down {\n            if c.is_uppercase() {\n                down = false;\n                last_index.byte_index = byte_index;\n                last_index.char_index = char_index;\n            } else if !c.is_lowercase() {\n                return last_index;\n            }\n        } else if c.is_lowercase() {\n            down = true;\n        } else if c.is_uppercase() {\n            last_index.byte_index = byte_index;\n            last_index.char_index = char_index;\n        } else {\n            return last_index;\n        }\n    }\n\n    last_index\n}\n\n/// Get the indexes of camel case components of a string `s`\n///\n/// ```no_run\n/// # use clippy_utils::str_utils::{camel_case_indices, StrIndex};\n/// assert_eq!(\n///     camel_case_indices(\"AbcDef\"),\n///     vec![StrIndex::new(0, 0), StrIndex::new(3, 3), StrIndex::new(6, 6)]\n/// );\n/// assert_eq!(\n///     camel_case_indices(\"abcDef\"),\n///     vec![StrIndex::new(3, 3), StrIndex::new(6, 6)]\n/// );\n/// ```\npub fn camel_case_indices(s: &str) -> Vec<StrIndex> {\n    let mut result = Vec::new();\n    let mut str_idx = camel_case_start(s);\n\n    while str_idx.byte_index < s.len() {\n        let next_idx = str_idx.byte_index + 1;\n        result.push(str_idx);\n        str_idx = camel_case_start_from_idx(s, next_idx);\n    }\n    result.push(str_idx);\n\n    result\n}\n\n/// Split camel case string into a vector of its components\n///\n/// ```no_run\n/// # use clippy_utils::str_utils::{camel_case_split, StrIndex};\n/// assert_eq!(camel_case_split(\"AbcDef\"), vec![\"Abc\", \"Def\"]);\n/// ```\npub fn camel_case_split(s: &str) -> Vec<&str> {\n    let mut offsets = camel_case_indices(s)\n        .iter()\n        .map(|e| e.byte_index)\n        .collect::<Vec<usize>>();\n    if offsets[0] != 0 {\n        offsets.insert(0, 0);\n    }\n\n    offsets.windows(2).map(|w| &s[w[0]..w[1]]).collect()\n}\n\n/// Dealing with string comparison can be complicated, this struct ensures that both the\n/// character and byte count are provided for correct indexing.\n#[derive(Debug, Default, PartialEq, Eq)]\npub struct StrCount {\n    pub char_count: usize,\n    pub byte_count: usize,\n}\n\nimpl StrCount {\n    pub fn new(char_count: usize, byte_count: usize) -> Self {\n        Self { char_count, byte_count }\n    }\n}\n\n/// Returns the number of chars that match from the start\n///\n/// ```no_run\n/// # use clippy_utils::str_utils::{count_match_start, StrCount};\n/// assert_eq!(count_match_start(\"hello_mouse\", \"hello_penguin\"), StrCount::new(6, 6));\n/// assert_eq!(count_match_start(\"hello_clippy\", \"bye_bugs\"), StrCount::new(0, 0));\n/// assert_eq!(count_match_start(\"hello_world\", \"hello_world\"), StrCount::new(11, 11));\n/// assert_eq!(count_match_start(\"T\\u{f6}ffT\\u{f6}ff\", \"T\\u{f6}ff\"), StrCount::new(4, 5));\n/// ```\n#[must_use]\npub fn count_match_start(str1: &str, str2: &str) -> StrCount {\n    // (char_index, char1)\n    let char_count = str1.chars().count();\n    let iter1 = (0..=char_count).zip(str1.chars());\n    // (byte_index, char2)\n    let iter2 = str2.char_indices();\n\n    iter1\n        .zip(iter2)\n        .take_while(|((_, c1), (_, c2))| c1 == c2)\n        .last()\n        .map_or_else(StrCount::default, |((char_index, _), (byte_index, character))| {\n            StrCount::new(char_index + 1, byte_index + character.len_utf8())\n        })\n}\n\n/// Returns the number of chars and bytes that match from the end\n///\n/// ```no_run\n/// # use clippy_utils::str_utils::{count_match_end, StrCount};\n/// assert_eq!(count_match_end(\"hello_cat\", \"bye_cat\"), StrCount::new(4, 4));\n/// assert_eq!(count_match_end(\"if_item_thing\", \"enum_value\"), StrCount::new(0, 0));\n/// assert_eq!(count_match_end(\"Clippy\", \"Clippy\"), StrCount::new(6, 6));\n/// assert_eq!(count_match_end(\"MyT\\u{f6}ff\", \"YourT\\u{f6}ff\"), StrCount::new(4, 5));\n/// ```\n#[must_use]\npub fn count_match_end(str1: &str, str2: &str) -> StrCount {\n    let char_count = str1.chars().count();\n    if char_count == 0 {\n        return StrCount::default();\n    }\n\n    // (char_index, char1)\n    let iter1 = (0..char_count).rev().zip(str1.chars().rev());\n    // (byte_index, char2)\n    let byte_count = str2.len();\n    let iter2 = str2.char_indices().rev();\n\n    iter1\n        .zip(iter2)\n        .take_while(|((_, c1), (_, c2))| c1 == c2)\n        .last()\n        .map_or_else(StrCount::default, |((char_index, _), (byte_index, _))| {\n            StrCount::new(char_count - char_index, byte_count - byte_index)\n        })\n}\n\n/// Returns a `snake_case` version of the input\n/// ```no_run\n/// use clippy_utils::str_utils::to_snake_case;\n/// assert_eq!(to_snake_case(\"AbcDef\"), \"abc_def\");\n/// assert_eq!(to_snake_case(\"ABCD\"), \"a_b_c_d\");\n/// assert_eq!(to_snake_case(\"AbcDD\"), \"abc_d_d\");\n/// assert_eq!(to_snake_case(\"Abc1DD\"), \"abc1_d_d\");\n/// ```\npub fn to_snake_case(name: &str) -> String {\n    let mut s = String::new();\n    for (i, c) in name.chars().enumerate() {\n        if c.is_uppercase() {\n            // characters without capitalization are considered lowercase\n            if i != 0 {\n                s.push('_');\n            }\n            s.extend(c.to_lowercase());\n        } else {\n            s.push(c);\n        }\n    }\n    s\n}\n/// Returns a `CamelCase` version of the input\n/// ```no_run\n/// use clippy_utils::str_utils::to_camel_case;\n/// assert_eq!(to_camel_case(\"abc_def\"), \"AbcDef\");\n/// assert_eq!(to_camel_case(\"a_b_c_d\"), \"ABCD\");\n/// assert_eq!(to_camel_case(\"abc_d_d\"), \"AbcDD\");\n/// assert_eq!(to_camel_case(\"abc1_d_d\"), \"Abc1DD\");\n/// ```\npub fn to_camel_case(item_name: &str) -> String {\n    let mut s = String::new();\n    let mut up = true;\n    for c in item_name.chars() {\n        if c.is_uppercase() {\n            // we only turn snake case text into CamelCase\n            return item_name.to_string();\n        }\n        if c == '_' {\n            up = true;\n            continue;\n        }\n        if up {\n            up = false;\n            s.extend(c.to_uppercase());\n        } else {\n            s.push(c);\n        }\n    }\n    s\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn camel_case_start_full() {\n        assert_eq!(camel_case_start(\"AbcDef\"), StrIndex::new(0, 0));\n        assert_eq!(camel_case_start(\"Abc\"), StrIndex::new(0, 0));\n        assert_eq!(camel_case_start(\"ABcd\"), StrIndex::new(0, 0));\n        assert_eq!(camel_case_start(\"ABcdEf\"), StrIndex::new(0, 0));\n        assert_eq!(camel_case_start(\"AabABcd\"), StrIndex::new(0, 0));\n    }\n\n    #[test]\n    fn camel_case_start_partial() {\n        assert_eq!(camel_case_start(\"abcDef\"), StrIndex::new(3, 3));\n        assert_eq!(camel_case_start(\"aDbc\"), StrIndex::new(1, 1));\n        assert_eq!(camel_case_start(\"aabABcd\"), StrIndex::new(3, 3));\n        assert_eq!(camel_case_start(\"\\u{f6}\\u{f6}AabABcd\"), StrIndex::new(2, 4));\n    }\n\n    #[test]\n    fn camel_case_start_not() {\n        assert_eq!(camel_case_start(\"AbcDef_\"), StrIndex::new(7, 7));\n        assert_eq!(camel_case_start(\"AbcDD\"), StrIndex::new(5, 5));\n        assert_eq!(camel_case_start(\"all_small\"), StrIndex::new(9, 9));\n        assert_eq!(camel_case_start(\"\\u{f6}_all_small\"), StrIndex::new(11, 12));\n    }\n\n    #[test]\n    fn camel_case_start_caps() {\n        assert_eq!(camel_case_start(\"ABCD\"), StrIndex::new(4, 4));\n    }\n\n    #[test]\n    fn camel_case_until_full() {\n        assert_eq!(camel_case_until(\"AbcDef\"), StrIndex::new(6, 6));\n        assert_eq!(camel_case_until(\"Abc\"), StrIndex::new(3, 3));\n        assert_eq!(camel_case_until(\"Abc\\u{f6}\\u{f6}\\u{f6}\"), StrIndex::new(6, 9));\n    }\n\n    #[test]\n    fn camel_case_until_not() {\n        assert_eq!(camel_case_until(\"abcDef\"), StrIndex::new(0, 0));\n        assert_eq!(camel_case_until(\"aDbc\"), StrIndex::new(0, 0));\n    }\n\n    #[test]\n    fn camel_case_until_partial() {\n        assert_eq!(camel_case_until(\"AbcDef_\"), StrIndex::new(6, 6));\n        assert_eq!(camel_case_until(\"CallTypeC\"), StrIndex::new(8, 8));\n        assert_eq!(camel_case_until(\"AbcDD\"), StrIndex::new(3, 3));\n        assert_eq!(camel_case_until(\"Abc\\u{f6}\\u{f6}DD\"), StrIndex::new(5, 7));\n    }\n\n    #[test]\n    fn until_caps() {\n        assert_eq!(camel_case_until(\"ABCD\"), StrIndex::new(0, 0));\n    }\n\n    #[test]\n    fn camel_case_start_from_idx_full() {\n        assert_eq!(camel_case_start_from_idx(\"AbcDef\", 0), StrIndex::new(0, 0));\n        assert_eq!(camel_case_start_from_idx(\"AbcDef\", 1), StrIndex::new(3, 3));\n        assert_eq!(camel_case_start_from_idx(\"AbcDef\", 4), StrIndex::new(6, 6));\n        assert_eq!(camel_case_start_from_idx(\"AbcDefGhi\", 0), StrIndex::new(0, 0));\n        assert_eq!(camel_case_start_from_idx(\"AbcDefGhi\", 1), StrIndex::new(3, 3));\n        assert_eq!(camel_case_start_from_idx(\"Abcdefg\", 1), StrIndex::new(7, 7));\n    }\n\n    #[test]\n    fn camel_case_indices_full() {\n        assert_eq!(camel_case_indices(\"Abc\\u{f6}\\u{f6}DD\"), vec![StrIndex::new(7, 9)]);\n    }\n\n    #[test]\n    fn camel_case_split_full() {\n        assert_eq!(camel_case_split(\"A\"), vec![\"A\"]);\n        assert_eq!(camel_case_split(\"AbcDef\"), vec![\"Abc\", \"Def\"]);\n        assert_eq!(camel_case_split(\"Abc\"), vec![\"Abc\"]);\n        assert_eq!(camel_case_split(\"abcDef\"), vec![\"abc\", \"Def\"]);\n        assert_eq!(\n            camel_case_split(\"\\u{f6}\\u{f6}AabABcd\"),\n            vec![\"\\u{f6}\\u{f6}\", \"Aab\", \"A\", \"Bcd\"]\n        );\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/sugg.rs",
    "content": "//! Contains utility functions to generate suggestions.\n#![deny(clippy::missing_docs_in_private_items)]\n\nuse crate::source::{snippet, snippet_opt, snippet_with_applicability, snippet_with_context};\nuse crate::ty::expr_sig;\nuse crate::{get_parent_expr_for_hir, higher};\nuse rustc_ast::util::parser::AssocOp;\nuse rustc_ast::{UnOp, ast};\nuse rustc_data_structures::fx::FxHashSet;\nuse rustc_errors::Applicability;\nuse rustc_hir::{self as hir, Closure, ExprKind, HirId, MatchSource, MutTy, Node, TyKind};\nuse rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};\nuse rustc_lint::{EarlyContext, LateContext, LintContext};\nuse rustc_middle::hir::place::ProjectionKind;\nuse rustc_middle::mir::{FakeReadCause, Mutability};\nuse rustc_middle::ty;\nuse rustc_span::{BytePos, CharPos, Pos, Span, SyntaxContext};\nuse std::borrow::Cow;\nuse std::fmt::{self, Display, Write as _};\nuse std::ops::{Add, Neg, Not, Sub};\n\n/// A helper type to build suggestion correctly handling parentheses.\n#[derive(Clone, Debug, PartialEq)]\npub enum Sugg<'a> {\n    /// An expression that never needs parentheses such as `1337` or `[0; 42]`.\n    NonParen(Cow<'a, str>),\n    /// An expression that does not fit in other variants.\n    MaybeParen(Cow<'a, str>),\n    /// A binary operator expression, including `as`-casts and explicit type\n    /// coercion.\n    BinOp(AssocOp, Cow<'a, str>, Cow<'a, str>),\n    /// A unary operator expression. This is used to sometimes represent `!`\n    /// or `-`, but only if the type with and without the operator is kept identical.\n    /// It means that doubling the operator can be used to remove it instead, in\n    /// order to provide better suggestions.\n    UnOp(UnOp, Box<Self>),\n}\n\n/// Literal constant `0`, for convenience.\npub const ZERO: Sugg<'static> = Sugg::NonParen(Cow::Borrowed(\"0\"));\n/// Literal constant `1`, for convenience.\npub const ONE: Sugg<'static> = Sugg::NonParen(Cow::Borrowed(\"1\"));\n/// a constant represents an empty string, for convenience.\npub const EMPTY: Sugg<'static> = Sugg::NonParen(Cow::Borrowed(\"\"));\n\nimpl Display for Sugg<'_> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {\n        match self {\n            Sugg::NonParen(s) | Sugg::MaybeParen(s) => s.fmt(f),\n            Sugg::BinOp(op, lhs, rhs) => binop_to_string(*op, lhs, rhs).fmt(f),\n            Sugg::UnOp(op, inner) => write!(f, \"{}{}\", op.as_str(), inner.clone().maybe_inner_paren()),\n        }\n    }\n}\n\n#[expect(clippy::wrong_self_convention)] // ok, because of the function `as_ty` method\nimpl<'a> Sugg<'a> {\n    /// Prepare a suggestion from an expression.\n    pub fn hir_opt(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Self> {\n        let ctxt = expr.span.ctxt();\n        let get_snippet = |span| snippet_with_context(cx, span, ctxt, \"\", &mut Applicability::Unspecified).0;\n        snippet_opt(cx, expr.span).map(|_| Self::hir_from_snippet(cx, expr, get_snippet))\n    }\n\n    /// Convenience function around `hir_opt` for suggestions with a default\n    /// text.\n    pub fn hir(cx: &LateContext<'_>, expr: &hir::Expr<'_>, default: &'a str) -> Self {\n        Self::hir_opt(cx, expr).unwrap_or(Sugg::NonParen(Cow::Borrowed(default)))\n    }\n\n    /// Same as `hir`, but it adapts the applicability level by following rules:\n    ///\n    /// - Applicability level `Unspecified` will never be changed.\n    /// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`.\n    /// - If the default value is used and the applicability level is `MachineApplicable`, change it\n    ///   to `HasPlaceholders`\n    pub fn hir_with_applicability(\n        cx: &LateContext<'_>,\n        expr: &hir::Expr<'_>,\n        default: &'a str,\n        applicability: &mut Applicability,\n    ) -> Self {\n        if *applicability != Applicability::Unspecified && expr.span.from_expansion() {\n            *applicability = Applicability::MaybeIncorrect;\n        }\n        Self::hir_opt(cx, expr).unwrap_or_else(|| {\n            if *applicability == Applicability::MachineApplicable {\n                *applicability = Applicability::HasPlaceholders;\n            }\n            Sugg::NonParen(Cow::Borrowed(default))\n        })\n    }\n\n    /// Same as `hir`, but first walks the span up to the given context. This will result in the\n    /// macro call, rather than the expansion, if the span is from a child context. If the span is\n    /// not from a child context, it will be used directly instead.\n    ///\n    /// e.g. Given the expression `&vec![]`, getting a snippet from the span for `vec![]` as a HIR\n    /// node would result in `box []`. If given the context of the address of expression, this\n    /// function will correctly get a snippet of `vec![]`.\n    pub fn hir_with_context(\n        cx: &LateContext<'_>,\n        expr: &hir::Expr<'_>,\n        ctxt: SyntaxContext,\n        default: &'a str,\n        applicability: &mut Applicability,\n    ) -> Self {\n        if expr.span.ctxt() == ctxt {\n            if let ExprKind::Unary(op, inner) = expr.kind\n                && matches!(op, UnOp::Neg | UnOp::Not)\n                && cx.typeck_results().expr_ty(expr) == cx.typeck_results().expr_ty(inner)\n            {\n                Sugg::UnOp(\n                    op,\n                    Box::new(Self::hir_with_context(cx, inner, ctxt, default, applicability)),\n                )\n            } else {\n                Self::hir_from_snippet(cx, expr, |span| {\n                    snippet_with_context(cx, span, ctxt, default, applicability).0\n                })\n            }\n        } else {\n            let (snip, _) = snippet_with_context(cx, expr.span, ctxt, default, applicability);\n            Sugg::NonParen(snip)\n        }\n    }\n\n    /// Generate a suggestion for an expression with the given snippet. This is used by the `hir_*`\n    /// function variants of `Sugg`, since these use different snippet functions.\n    pub fn hir_from_snippet(\n        cx: &LateContext<'_>,\n        expr: &hir::Expr<'_>,\n        mut get_snippet: impl FnMut(Span) -> Cow<'a, str>,\n    ) -> Self {\n        if let Some(range) = higher::Range::hir(cx, expr) {\n            let op = AssocOp::Range(range.limits);\n            let start = range.start.map_or(\"\".into(), |expr| get_snippet(expr.span));\n            let end = range.end.map_or(\"\".into(), |expr| get_snippet(expr.span));\n\n            return Sugg::BinOp(op, start, end);\n        }\n\n        match expr.kind {\n            ExprKind::AddrOf(..)\n            | ExprKind::If(..)\n            | ExprKind::Let(..)\n            | ExprKind::Closure { .. }\n            | ExprKind::Unary(..)\n            | ExprKind::Match(_, _,\n                MatchSource::Normal | MatchSource::Postfix | MatchSource::ForLoopDesugar\n            ) => Sugg::MaybeParen(get_snippet(expr.span)),\n            ExprKind::Continue(..)\n            | ExprKind::Yield(..)\n            | ExprKind::Array(..)\n            | ExprKind::Block(..)\n            | ExprKind::Break(..)\n            | ExprKind::Call(..)\n            | ExprKind::Field(..)\n            | ExprKind::Index(..)\n            | ExprKind::InlineAsm(..)\n            | ExprKind::OffsetOf(..)\n            | ExprKind::ConstBlock(..)\n            | ExprKind::Lit(..)\n            | ExprKind::Loop(..)\n            | ExprKind::MethodCall(..)\n            | ExprKind::Path(..)\n            | ExprKind::Repeat(..)\n            | ExprKind::Ret(..)\n            | ExprKind::Become(..)\n            | ExprKind::Struct(..)\n            | ExprKind::Tup(..)\n            | ExprKind::Use(..)\n            | ExprKind::Err(_)\n            | ExprKind::UnsafeBinderCast(..)\n            | ExprKind::Match(_, _,\n                MatchSource::AwaitDesugar | MatchSource::TryDesugar(_) | MatchSource::FormatArgs\n            ) => Sugg::NonParen(get_snippet(expr.span)),\n            ExprKind::DropTemps(inner) => Self::hir_from_snippet(cx, inner, get_snippet),\n            ExprKind::Assign(lhs, rhs, _) => {\n                Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span))\n            },\n            ExprKind::AssignOp(op, lhs, rhs) => {\n                Sugg::BinOp(AssocOp::AssignOp(op.node), get_snippet(lhs.span), get_snippet(rhs.span))\n            },\n            ExprKind::Binary(op, lhs, rhs) => Sugg::BinOp(\n                AssocOp::Binary(op.node),\n                get_snippet(lhs.span),\n                get_snippet(rhs.span),\n            ),\n            ExprKind::Cast(lhs, ty) |\n            //FIXME(chenyukang), remove this after type ascription is removed from AST\n            ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::Cast, get_snippet(lhs.span), get_snippet(ty.span)),\n        }\n    }\n\n    /// Prepare a suggestion from an expression.\n    pub fn ast(\n        cx: &EarlyContext<'_>,\n        expr: &ast::Expr,\n        default: &'a str,\n        ctxt: SyntaxContext,\n        app: &mut Applicability,\n    ) -> Self {\n        let mut snippet = |span: Span| snippet_with_context(cx, span, ctxt, default, app).0;\n\n        match expr.kind {\n            _ if expr.span.ctxt() != ctxt => Sugg::NonParen(snippet(expr.span)),\n            ast::ExprKind::AddrOf(..)\n            | ast::ExprKind::Closure { .. }\n            | ast::ExprKind::If(..)\n            | ast::ExprKind::Let(..)\n            | ast::ExprKind::Unary(..)\n            | ast::ExprKind::Match(..) => match snippet_with_context(cx, expr.span, ctxt, default, app) {\n                (snip, false) => Sugg::MaybeParen(snip),\n                (snip, true) => Sugg::NonParen(snip),\n            },\n            ast::ExprKind::Gen(..)\n            | ast::ExprKind::Block(..)\n            | ast::ExprKind::Break(..)\n            | ast::ExprKind::Call(..)\n            | ast::ExprKind::Continue(..)\n            | ast::ExprKind::Yield(..)\n            | ast::ExprKind::Field(..)\n            | ast::ExprKind::ForLoop { .. }\n            | ast::ExprKind::Index(..)\n            | ast::ExprKind::InlineAsm(..)\n            | ast::ExprKind::OffsetOf(..)\n            | ast::ExprKind::ConstBlock(..)\n            | ast::ExprKind::Lit(..)\n            | ast::ExprKind::IncludedBytes(..)\n            | ast::ExprKind::Loop(..)\n            | ast::ExprKind::MacCall(..)\n            | ast::ExprKind::MethodCall(..)\n            | ast::ExprKind::Paren(..)\n            | ast::ExprKind::Underscore\n            | ast::ExprKind::Path(..)\n            | ast::ExprKind::Repeat(..)\n            | ast::ExprKind::Ret(..)\n            | ast::ExprKind::Become(..)\n            | ast::ExprKind::Yeet(..)\n            | ast::ExprKind::FormatArgs(..)\n            | ast::ExprKind::Struct(..)\n            | ast::ExprKind::Try(..)\n            | ast::ExprKind::TryBlock(..)\n            | ast::ExprKind::Tup(..)\n            | ast::ExprKind::Use(..)\n            | ast::ExprKind::Array(..)\n            | ast::ExprKind::While(..)\n            | ast::ExprKind::Await(..)\n            | ast::ExprKind::Err(_)\n            | ast::ExprKind::Dummy\n            | ast::ExprKind::UnsafeBinderCast(..) => Sugg::NonParen(snippet(expr.span)),\n            ast::ExprKind::Range(ref lhs, ref rhs, limits) => Sugg::BinOp(\n                AssocOp::Range(limits),\n                lhs.as_ref().map_or(\"\".into(), |lhs| snippet(lhs.span)),\n                rhs.as_ref().map_or(\"\".into(), |rhs| snippet(rhs.span)),\n            ),\n            ast::ExprKind::Assign(ref lhs, ref rhs, _) => Sugg::BinOp(\n                AssocOp::Assign,\n                snippet(lhs.span),\n                snippet(rhs.span),\n            ),\n            ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => Sugg::BinOp(\n                AssocOp::AssignOp(op.node),\n                snippet(lhs.span),\n                snippet(rhs.span),\n            ),\n            ast::ExprKind::Binary(op, ref lhs, ref rhs) => Sugg::BinOp(\n                AssocOp::Binary(op.node),\n                snippet(lhs.span),\n                snippet(rhs.span),\n            ),\n            ast::ExprKind::Cast(ref lhs, ref ty) |\n            //FIXME(chenyukang), remove this after type ascription is removed from AST\n            ast::ExprKind::Type(ref lhs, ref ty) => Sugg::BinOp(\n                AssocOp::Cast,\n                snippet(lhs.span),\n                snippet(ty.span),\n            ),\n        }\n    }\n\n    /// Convenience method to create the `<lhs> && <rhs>` suggestion.\n    pub fn and(self, rhs: &Self) -> Sugg<'static> {\n        make_binop(ast::BinOpKind::And, &self, rhs)\n    }\n\n    /// Convenience method to create the `<lhs> & <rhs>` suggestion.\n    pub fn bit_and(self, rhs: &Self) -> Sugg<'static> {\n        make_binop(ast::BinOpKind::BitAnd, &self, rhs)\n    }\n\n    /// Convenience method to create the `<lhs> as <rhs>` suggestion.\n    pub fn as_ty<R: Display>(self, rhs: R) -> Sugg<'static> {\n        make_assoc(AssocOp::Cast, &self, &Sugg::NonParen(rhs.to_string().into()))\n    }\n\n    /// Convenience method to create the `&<expr>` suggestion.\n    pub fn addr(self) -> Sugg<'static> {\n        make_unop(\"&\", self)\n    }\n\n    /// Convenience method to create the `&mut <expr>` suggestion.\n    pub fn mut_addr(self) -> Sugg<'static> {\n        make_unop(\"&mut \", self)\n    }\n\n    /// Convenience method to create the `*<expr>` suggestion.\n    pub fn deref(self) -> Sugg<'static> {\n        make_unop(\"*\", self)\n    }\n\n    /// Convenience method to create the `&*<expr>` suggestion. Currently this\n    /// is needed because `sugg.deref().addr()` produces an unnecessary set of\n    /// parentheses around the deref.\n    pub fn addr_deref(self) -> Sugg<'static> {\n        make_unop(\"&*\", self)\n    }\n\n    /// Convenience method to create the `&mut *<expr>` suggestion. Currently\n    /// this is needed because `sugg.deref().mut_addr()` produces an unnecessary\n    /// set of parentheses around the deref.\n    pub fn mut_addr_deref(self) -> Sugg<'static> {\n        make_unop(\"&mut *\", self)\n    }\n\n    /// Convenience method to transform suggestion into a return call\n    pub fn make_return(self) -> Sugg<'static> {\n        Sugg::NonParen(Cow::Owned(format!(\"return {self}\")))\n    }\n\n    /// Convenience method to transform suggestion into a block\n    /// where the suggestion is a trailing expression\n    pub fn blockify(self) -> Sugg<'static> {\n        Sugg::NonParen(Cow::Owned(format!(\"{{ {self} }}\")))\n    }\n\n    /// Convenience method to prefix the expression with the `async` keyword.\n    /// Can be used after `blockify` to create an async block.\n    pub fn asyncify(self) -> Sugg<'static> {\n        Sugg::NonParen(Cow::Owned(format!(\"async {self}\")))\n    }\n\n    /// Convenience method to create the `<lhs>..<rhs>` or `<lhs>...<rhs>`\n    /// suggestion.\n    pub fn range(self, end: &Self, limits: ast::RangeLimits) -> Sugg<'static> {\n        make_assoc(AssocOp::Range(limits), &self, end)\n    }\n\n    /// Adds parentheses to any expression that might need them. Suitable to the\n    /// `self` argument of a method call\n    /// (e.g., to build `bar.foo()` or `(1 + 2).foo()`).\n    #[must_use]\n    pub fn maybe_paren(self) -> Self {\n        match self {\n            Sugg::NonParen(..) => self,\n            // `(x)` and `(x).y()` both don't need additional parens.\n            Sugg::MaybeParen(sugg) => {\n                if has_enclosing_paren(&sugg) {\n                    Sugg::MaybeParen(sugg)\n                } else {\n                    Sugg::NonParen(format!(\"({sugg})\").into())\n                }\n            },\n            Sugg::BinOp(op, lhs, rhs) => {\n                let sugg = binop_to_string(op, &lhs, &rhs);\n                Sugg::NonParen(format!(\"({sugg})\").into())\n            },\n            Sugg::UnOp(op, inner) => Sugg::NonParen(format!(\"({}{})\", op.as_str(), inner.maybe_inner_paren()).into()),\n        }\n    }\n\n    /// Strip enclosing parentheses if present. This method must be called when\n    /// it is known that removing those will not change the meaning. For example,\n    /// if `self` is known to represent a reference and the suggestion will be\n    /// used as the argument of a function call, it is safe to remove the enclosing\n    /// parentheses. It would not be safe to do so for an expression that might\n    /// represent a tuple.\n    #[must_use]\n    pub fn strip_paren(self) -> Self {\n        match self {\n            Sugg::NonParen(s) | Sugg::MaybeParen(s) => Sugg::NonParen(strip_enclosing_paren(s)),\n            sugg => sugg,\n        }\n    }\n\n    pub fn into_string(self) -> String {\n        match self {\n            Sugg::NonParen(p) | Sugg::MaybeParen(p) => p.into_owned(),\n            Sugg::BinOp(b, l, r) => binop_to_string(b, &l, &r),\n            Sugg::UnOp(op, inner) => format!(\"{}{}\", op.as_str(), inner.maybe_inner_paren()),\n        }\n    }\n\n    /// Checks if `self` starts with a unary operator.\n    fn starts_with_unary_op(&self) -> bool {\n        match self {\n            Sugg::UnOp(..) => true,\n            Sugg::BinOp(..) => false,\n            Sugg::MaybeParen(s) | Sugg::NonParen(s) => s.starts_with(['*', '!', '-', '&']),\n        }\n    }\n\n    /// Call `maybe_paren` on `self` if it doesn't start with a unary operator,\n    /// don't touch it otherwise.\n    fn maybe_inner_paren(self) -> Self {\n        if self.starts_with_unary_op() {\n            self\n        } else {\n            self.maybe_paren()\n        }\n    }\n}\n\n/// Generates a string from the operator and both sides.\nfn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {\n    match op {\n        AssocOp::Binary(op) => format!(\"{lhs} {} {rhs}\", op.as_str()),\n        AssocOp::Assign => format!(\"{lhs} = {rhs}\"),\n        AssocOp::AssignOp(op) => format!(\"{lhs} {} {rhs}\", op.as_str()),\n        AssocOp::Cast => format!(\"{lhs} as {rhs}\"),\n        AssocOp::Range(limits) => format!(\"{lhs}{}{rhs}\", limits.as_str()),\n    }\n}\n\n/// Returns `true` if `sugg` is enclosed in parenthesis.\npub fn has_enclosing_paren(sugg: impl AsRef<str>) -> bool {\n    let mut chars = sugg.as_ref().chars();\n    if chars.next() == Some('(') {\n        let mut depth = 1;\n        for c in &mut chars {\n            if c == '(' {\n                depth += 1;\n            } else if c == ')' {\n                depth -= 1;\n            }\n            if depth == 0 {\n                break;\n            }\n        }\n        chars.next().is_none()\n    } else {\n        false\n    }\n}\n\n/// Strip enclosing parentheses from a snippet if present.\nfn strip_enclosing_paren(snippet: Cow<'_, str>) -> Cow<'_, str> {\n    if has_enclosing_paren(&snippet) {\n        match snippet {\n            Cow::Borrowed(s) => Cow::Borrowed(&s[1..s.len() - 1]),\n            Cow::Owned(mut s) => {\n                s.pop();\n                s.remove(0);\n                Cow::Owned(s)\n            },\n        }\n    } else {\n        snippet\n    }\n}\n\n/// Copied from the rust standard library, and then edited\nmacro_rules! forward_binop_impls_to_ref {\n    (impl $imp:ident, $method:ident for $t:ty, type Output = $o:ty) => {\n        impl $imp<$t> for &$t {\n            type Output = $o;\n\n            fn $method(self, other: $t) -> $o {\n                $imp::$method(self, &other)\n            }\n        }\n\n        impl $imp<&$t> for $t {\n            type Output = $o;\n\n            fn $method(self, other: &$t) -> $o {\n                $imp::$method(&self, other)\n            }\n        }\n\n        impl $imp for $t {\n            type Output = $o;\n\n            fn $method(self, other: $t) -> $o {\n                $imp::$method(&self, &other)\n            }\n        }\n    };\n}\n\nimpl Add for &Sugg<'_> {\n    type Output = Sugg<'static>;\n    fn add(self, rhs: &Sugg<'_>) -> Sugg<'static> {\n        make_binop(ast::BinOpKind::Add, self, rhs)\n    }\n}\n\nimpl Sub for &Sugg<'_> {\n    type Output = Sugg<'static>;\n    fn sub(self, rhs: &Sugg<'_>) -> Sugg<'static> {\n        make_binop(ast::BinOpKind::Sub, self, rhs)\n    }\n}\n\nforward_binop_impls_to_ref!(impl Add, add for Sugg<'_>, type Output = Sugg<'static>);\nforward_binop_impls_to_ref!(impl Sub, sub for Sugg<'_>, type Output = Sugg<'static>);\n\nimpl<'a> Neg for Sugg<'a> {\n    type Output = Sugg<'a>;\n    fn neg(self) -> Self::Output {\n        match self {\n            Self::UnOp(UnOp::Neg, sugg) => *sugg,\n            Self::BinOp(AssocOp::Cast, ..) => Sugg::MaybeParen(format!(\"-({self})\").into()),\n            _ => make_unop(\"-\", self),\n        }\n    }\n}\n\nimpl<'a> Not for Sugg<'a> {\n    type Output = Sugg<'a>;\n    fn not(self) -> Sugg<'a> {\n        use AssocOp::Binary;\n        use ast::BinOpKind::{Eq, Ge, Gt, Le, Lt, Ne};\n\n        match self {\n            Sugg::BinOp(op, lhs, rhs) => {\n                let to_op = match op {\n                    Binary(Eq) => Binary(Ne),\n                    Binary(Ne) => Binary(Eq),\n                    Binary(Lt) => Binary(Ge),\n                    Binary(Ge) => Binary(Lt),\n                    Binary(Gt) => Binary(Le),\n                    Binary(Le) => Binary(Gt),\n                    _ => return make_unop(\"!\", Sugg::BinOp(op, lhs, rhs)),\n                };\n                Sugg::BinOp(to_op, lhs, rhs)\n            },\n            Sugg::UnOp(UnOp::Not, expr) => *expr,\n            _ => make_unop(\"!\", self),\n        }\n    }\n}\n\n/// Helper type to display either `foo` or `(foo)`.\nstruct ParenHelper<T> {\n    /// `true` if parentheses are needed.\n    paren: bool,\n    /// The main thing to display.\n    wrapped: T,\n}\n\nimpl<T> ParenHelper<T> {\n    /// Builds a `ParenHelper`.\n    fn new(paren: bool, wrapped: T) -> Self {\n        Self { paren, wrapped }\n    }\n}\n\nimpl<T: Display> Display for ParenHelper<T> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {\n        if self.paren {\n            write!(f, \"({})\", self.wrapped)\n        } else {\n            self.wrapped.fmt(f)\n        }\n    }\n}\n\n/// Builds the string for `<op><expr>` adding parenthesis when necessary.\n///\n/// For convenience, the operator is taken as a string because all unary\n/// operators have the same precedence.\npub fn make_unop(op: &str, expr: Sugg<'_>) -> Sugg<'static> {\n    // If the `expr` starts with a unary operator already, do not wrap it in\n    // parentheses.\n    Sugg::MaybeParen(format!(\"{op}{}\", expr.maybe_inner_paren()).into())\n}\n\n/// Builds the string for `<lhs> <op> <rhs>` adding parenthesis when necessary.\n///\n/// Precedence of shift operator relative to other arithmetic operation is\n/// often confusing so\n/// parenthesis will always be added for a mix of these.\npub fn make_assoc(op: AssocOp, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static> {\n    /// Returns `true` if the operator is a shift operator `<<` or `>>`.\n    fn is_shift(op: AssocOp) -> bool {\n        matches!(op, AssocOp::Binary(ast::BinOpKind::Shl | ast::BinOpKind::Shr))\n    }\n\n    /// Returns `true` if the operator is an arithmetic operator\n    /// (i.e., `+`, `-`, `*`, `/`, `%`).\n    fn is_arith(op: AssocOp) -> bool {\n        matches!(\n            op,\n            AssocOp::Binary(\n                ast::BinOpKind::Add\n                    | ast::BinOpKind::Sub\n                    | ast::BinOpKind::Mul\n                    | ast::BinOpKind::Div\n                    | ast::BinOpKind::Rem\n            )\n        )\n    }\n\n    /// Returns `true` if the operator `op` needs parenthesis with the operator\n    /// `other` in the direction `dir`.\n    fn needs_paren(op: AssocOp, other: AssocOp, dir: Associativity) -> bool {\n        other.precedence() < op.precedence()\n            || (other.precedence() == op.precedence()\n                && ((op != other && associativity(op) != dir)\n                    || (op == other && associativity(op) != Associativity::Both)))\n            || is_shift(op) && is_arith(other)\n            || is_shift(other) && is_arith(op)\n    }\n\n    let lhs_paren = if let Sugg::BinOp(lop, _, _) = *lhs {\n        needs_paren(op, lop, Associativity::Left)\n    } else {\n        false\n    };\n\n    let rhs_paren = if let Sugg::BinOp(rop, _, _) = *rhs {\n        needs_paren(op, rop, Associativity::Right)\n    } else {\n        false\n    };\n\n    let lhs = ParenHelper::new(lhs_paren, lhs).to_string();\n    let rhs = ParenHelper::new(rhs_paren, rhs).to_string();\n    Sugg::BinOp(op, lhs.into(), rhs.into())\n}\n\n/// Convenience wrapper around `make_assoc` and `AssocOp::Binary`.\npub fn make_binop(op: ast::BinOpKind, lhs: &Sugg<'_>, rhs: &Sugg<'_>) -> Sugg<'static> {\n    make_assoc(AssocOp::Binary(op), lhs, rhs)\n}\n\n#[derive(PartialEq, Eq, Clone, Copy)]\n/// Operator associativity.\nenum Associativity {\n    /// The operator is both left-associative and right-associative.\n    Both,\n    /// The operator is left-associative.\n    Left,\n    /// The operator is not associative.\n    None,\n    /// The operator is right-associative.\n    Right,\n}\n\n/// Returns the associativity/fixity of an operator. The difference with\n/// `AssocOp::fixity` is that an operator can be both left and right associative\n/// (such as `+`: `a + b + c == (a + b) + c == a + (b + c)`.\n///\n/// Chained `as` and explicit `:` type coercion never need inner parenthesis so\n/// they are considered\n/// associative.\n#[must_use]\nfn associativity(op: AssocOp) -> Associativity {\n    use ast::BinOpKind::{Add, And, BitAnd, BitOr, BitXor, Div, Eq, Ge, Gt, Le, Lt, Mul, Ne, Or, Rem, Shl, Shr, Sub};\n    use rustc_ast::util::parser::AssocOp::{Assign, AssignOp, Binary, Cast, Range};\n\n    match op {\n        Assign | AssignOp(_) => Associativity::Right,\n        Binary(Add | BitAnd | BitOr | BitXor | And | Or | Mul) | Cast => Associativity::Both,\n        Binary(Div | Eq | Gt | Ge | Lt | Le | Rem | Ne | Shl | Shr | Sub) => Associativity::Left,\n        Range(_) => Associativity::None,\n    }\n}\n\n/// Returns the indentation before `span` if there are nothing but `[ \\t]`\n/// before it on its line.\nfn indentation<T: LintContext>(cx: &T, span: Span) -> Option<String> {\n    let lo = cx.sess().source_map().lookup_char_pos(span.lo());\n    lo.file\n        .get_line(lo.line - 1 /* line numbers in `Loc` are 1-based */)\n        .and_then(|line| {\n            if let Some((pos, _)) = line.char_indices().find(|&(_, c)| c != ' ' && c != '\\t') {\n                // We can mix char and byte positions here because we only consider `[ \\t]`.\n                if lo.col == CharPos(pos) {\n                    Some(line[..pos].into())\n                } else {\n                    None\n                }\n            } else {\n                None\n            }\n        })\n}\n\n/// Convenience extension trait for `Diag`.\npub trait DiagExt<T: LintContext> {\n    /// Suggests to add an attribute to an item.\n    ///\n    /// Correctly handles indentation of the attribute and item.\n    ///\n    /// # Example\n    ///\n    /// ```rust,ignore\n    /// diag.suggest_item_with_attr(cx, item, \"#[derive(Default)]\");\n    /// ```\n    fn suggest_item_with_attr<D: Display + ?Sized>(\n        &mut self,\n        cx: &T,\n        item: Span,\n        msg: &str,\n        attr: &D,\n        applicability: Applicability,\n    );\n\n    /// Suggest to add an item before another.\n    ///\n    /// The item should not be indented (except for inner indentation).\n    ///\n    /// # Example\n    ///\n    /// ```rust,ignore\n    /// diag.suggest_prepend_item(cx, item,\n    /// \"fn foo() {\n    ///     bar();\n    /// }\");\n    /// ```\n    fn suggest_prepend_item(&mut self, cx: &T, item: Span, msg: &str, new_item: &str, applicability: Applicability);\n\n    /// Suggest to completely remove an item.\n    ///\n    /// This will remove an item and all following whitespace until the next non-whitespace\n    /// character. This should work correctly if item is on the same indentation level as the\n    /// following item.\n    ///\n    /// # Example\n    ///\n    /// ```rust,ignore\n    /// diag.suggest_remove_item(cx, item, \"remove this\")\n    /// ```\n    fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str, applicability: Applicability);\n}\n\nimpl<T: LintContext> DiagExt<T> for rustc_errors::Diag<'_, ()> {\n    fn suggest_item_with_attr<D: Display + ?Sized>(\n        &mut self,\n        cx: &T,\n        item: Span,\n        msg: &str,\n        attr: &D,\n        applicability: Applicability,\n    ) {\n        if let Some(indent) = indentation(cx, item) {\n            let span = item.with_hi(item.lo());\n\n            self.span_suggestion(span, msg.to_string(), format!(\"{attr}\\n{indent}\"), applicability);\n        }\n    }\n\n    fn suggest_prepend_item(&mut self, cx: &T, item: Span, msg: &str, new_item: &str, applicability: Applicability) {\n        if let Some(indent) = indentation(cx, item) {\n            let span = item.with_hi(item.lo());\n\n            let mut first = true;\n            let new_item = new_item\n                .lines()\n                .map(|l| {\n                    if first {\n                        first = false;\n                        format!(\"{l}\\n\")\n                    } else {\n                        format!(\"{indent}{l}\\n\")\n                    }\n                })\n                .collect::<String>();\n\n            self.span_suggestion(span, msg.to_string(), format!(\"{new_item}\\n{indent}\"), applicability);\n        }\n    }\n\n    fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str, applicability: Applicability) {\n        let mut remove_span = item;\n        let fmpos = cx.sess().source_map().lookup_byte_offset(remove_span.hi());\n\n        if let Some(ref src) = fmpos.sf.src {\n            let non_whitespace_offset = src[fmpos.pos.to_usize()..].find(|c| c != ' ' && c != '\\t' && c != '\\n');\n\n            if let Some(non_whitespace_offset) = non_whitespace_offset {\n                remove_span = remove_span\n                    .with_hi(remove_span.hi() + BytePos(non_whitespace_offset.try_into().expect(\"offset too large\")));\n            }\n        }\n\n        self.span_suggestion(remove_span, msg.to_string(), \"\", applicability);\n    }\n}\n\n/// Suggestion results for handling closure\n/// args dereferencing and borrowing\npub struct DerefClosure {\n    /// confidence on the built suggestion\n    pub applicability: Applicability,\n    /// gradually built suggestion\n    pub suggestion: String,\n}\n\n/// Build suggestion gradually by handling closure arg specific usages,\n/// such as explicit deref and borrowing cases.\n/// Returns `None` if no such use cases have been triggered in closure body\n///\n/// note: This only works on immutable closures with exactly one input parameter.\npub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Option<DerefClosure> {\n    if let ExprKind::Closure(&Closure {\n        fn_decl, def_id, body, ..\n    }) = closure.kind\n    {\n        let closure_body = cx.tcx.hir_body(body);\n        // is closure arg a type annotated double reference (i.e.: `|x: &&i32| ...`)\n        // a type annotation is present if param `kind` is different from `TyKind::Infer`\n        let closure_arg_is_type_annotated_double_ref = if let TyKind::Ref(_, MutTy { ty, .. }) = fn_decl.inputs[0].kind\n        {\n            matches!(ty.kind, TyKind::Ref(_, MutTy { .. }))\n        } else {\n            false\n        };\n\n        let mut visitor = DerefDelegate {\n            cx,\n            closure_span: closure.span,\n            closure_arg_id: closure_body.params[0].pat.hir_id,\n            closure_arg_is_type_annotated_double_ref,\n            next_pos: closure.span.lo(),\n            checked_borrows: FxHashSet::default(),\n            suggestion_start: String::new(),\n            applicability: Applicability::MachineApplicable,\n        };\n\n        ExprUseVisitor::for_clippy(cx, def_id, &mut visitor)\n            .consume_body(closure_body)\n            .into_ok();\n\n        if !visitor.suggestion_start.is_empty() {\n            return Some(DerefClosure {\n                applicability: visitor.applicability,\n                suggestion: visitor.finish(),\n            });\n        }\n    }\n    None\n}\n\n/// Visitor struct used for tracking down\n/// dereferencing and borrowing of closure's args\nstruct DerefDelegate<'a, 'tcx> {\n    /// The late context of the lint\n    cx: &'a LateContext<'tcx>,\n    /// The span of the input closure to adapt\n    closure_span: Span,\n    /// The `hir_id` of the closure argument being checked\n    closure_arg_id: HirId,\n    /// Indicates if the arg of the closure is a type annotated double reference\n    closure_arg_is_type_annotated_double_ref: bool,\n    /// last position of the span to gradually build the suggestion\n    next_pos: BytePos,\n    /// `hir_id`s that has been checked. This is used to avoid checking the same `hir_id` multiple\n    /// times when inside macro expansions.\n    checked_borrows: FxHashSet<HirId>,\n    /// starting part of the gradually built suggestion\n    suggestion_start: String,\n    /// confidence on the built suggestion\n    applicability: Applicability,\n}\n\nimpl<'tcx> DerefDelegate<'_, 'tcx> {\n    /// build final suggestion:\n    /// - create the ending part of suggestion\n    /// - concatenate starting and ending parts\n    /// - potentially remove needless borrowing\n    pub fn finish(&mut self) -> String {\n        let end_span = Span::new(self.next_pos, self.closure_span.hi(), self.closure_span.ctxt(), None);\n        let end_snip = snippet_with_applicability(self.cx, end_span, \"..\", &mut self.applicability);\n        let sugg = format!(\"{}{end_snip}\", self.suggestion_start);\n        if self.closure_arg_is_type_annotated_double_ref {\n            sugg.replacen('&', \"\", 1)\n        } else {\n            sugg\n        }\n    }\n\n    /// indicates whether the function from `parent_expr` takes its args by double reference\n    fn func_takes_arg_by_double_ref(&self, parent_expr: &'tcx hir::Expr<'_>, cmt_hir_id: HirId) -> bool {\n        let ty = match parent_expr.kind {\n            ExprKind::MethodCall(_, receiver, call_args, _) => {\n                if let Some(sig) = self\n                    .cx\n                    .typeck_results()\n                    .type_dependent_def_id(parent_expr.hir_id)\n                    .map(|did| self.cx.tcx.fn_sig(did).instantiate_identity().skip_binder())\n                {\n                    std::iter::once(receiver)\n                        .chain(call_args.iter())\n                        .position(|arg| arg.hir_id == cmt_hir_id)\n                        .map(|i| sig.inputs()[i])\n                } else {\n                    return false;\n                }\n            },\n            ExprKind::Call(func, call_args) => {\n                if let Some(sig) = expr_sig(self.cx, func) {\n                    call_args\n                        .iter()\n                        .position(|arg| arg.hir_id == cmt_hir_id)\n                        .and_then(|i| sig.input(i))\n                        .map(ty::Binder::skip_binder)\n                } else {\n                    return false;\n                }\n            },\n            _ => return false,\n        };\n\n        ty.is_some_and(|ty| matches!(ty.kind(), ty::Ref(_, inner, _) if inner.is_ref()))\n    }\n}\n\nimpl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {\n    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    #[expect(clippy::too_many_lines)]\n    fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {\n        if let PlaceBase::Local(id) = cmt.place.base {\n            let span = self.cx.tcx.hir_span(cmt.hir_id);\n            if !self.checked_borrows.insert(cmt.hir_id) {\n                // already checked this span and hir_id, skip\n                return;\n            }\n\n            let start_span = Span::new(self.next_pos, span.lo(), span.ctxt(), None);\n            let mut start_snip = snippet_with_applicability(self.cx, start_span, \"..\", &mut self.applicability);\n\n            // identifier referring to the variable currently triggered (i.e.: `fp`)\n            let ident_str = self.cx.tcx.hir_name(id).to_string();\n            // full identifier that includes projection (i.e.: `fp.field`)\n            let ident_str_with_proj = snippet(self.cx, span, \"..\").to_string();\n\n            // Make sure to get in all projections if we're on a `matches!`\n            if let Node::Pat(pat) = self.cx.tcx.hir_node(id)\n                && pat.hir_id != self.closure_arg_id\n            {\n                let _ = write!(self.suggestion_start, \"{start_snip}{ident_str_with_proj}\");\n            } else if cmt.place.projections.is_empty() {\n                // handle item without any projection, that needs an explicit borrowing\n                // i.e.: suggest `&x` instead of `x`\n                let _: fmt::Result = write!(self.suggestion_start, \"{start_snip}&{ident_str}\");\n            } else {\n                // cases where a parent `Call` or `MethodCall` is using the item\n                // i.e.: suggest `.contains(&x)` for `.find(|x| [1, 2, 3].contains(x)).is_none()`\n                //\n                // Note about method calls:\n                // - compiler automatically dereference references if the target type is a reference (works also for\n                //   function call)\n                // - `self` arguments in the case of `x.is_something()` are also automatically (de)referenced, and\n                //   no projection should be suggested\n                if let Some(parent_expr) = get_parent_expr_for_hir(self.cx, cmt.hir_id) {\n                    match &parent_expr.kind {\n                        // given expression is the self argument and will be handled completely by the compiler\n                        // i.e.: `|x| x.is_something()`\n                        ExprKind::MethodCall(_, self_expr, ..) if self_expr.hir_id == cmt.hir_id => {\n                            let _: fmt::Result = write!(self.suggestion_start, \"{start_snip}{ident_str_with_proj}\");\n                            self.next_pos = span.hi();\n                            return;\n                        },\n                        // item is used in a call\n                        // i.e.: `Call`: `|x| please(x)` or `MethodCall`: `|x| [1, 2, 3].contains(x)`\n                        ExprKind::Call(_, call_args) | ExprKind::MethodCall(_, _, call_args, _) => {\n                            let expr = self.cx.tcx.hir_expect_expr(cmt.hir_id);\n                            let arg_ty_kind = self.cx.typeck_results().expr_ty(expr).kind();\n\n                            if matches!(arg_ty_kind, ty::Ref(_, _, Mutability::Not)) {\n                                // suggest ampersand if call function is taking args by double reference\n                                let takes_arg_by_double_ref =\n                                    self.func_takes_arg_by_double_ref(parent_expr, cmt.hir_id);\n\n                                // compiler will automatically dereference field or index projection, so no need\n                                // to suggest ampersand, but full identifier that includes projection is required\n                                let has_field_or_index_projection =\n                                    cmt.place.projections.iter().any(|proj| {\n                                        matches!(proj.kind, ProjectionKind::Field(..) | ProjectionKind::Index)\n                                    });\n\n                                // no need to bind again if the function doesn't take arg by double ref\n                                // and if the item is already a double ref\n                                let ident_sugg = if !call_args.is_empty()\n                                    && !takes_arg_by_double_ref\n                                    && (self.closure_arg_is_type_annotated_double_ref || has_field_or_index_projection)\n                                {\n                                    let ident = if has_field_or_index_projection {\n                                        ident_str_with_proj\n                                    } else {\n                                        ident_str\n                                    };\n                                    format!(\"{start_snip}{ident}\")\n                                } else {\n                                    format!(\"{start_snip}&{ident_str}\")\n                                };\n                                self.suggestion_start.push_str(&ident_sugg);\n                                self.next_pos = span.hi();\n                                return;\n                            }\n\n                            self.applicability = Applicability::Unspecified;\n                        },\n                        _ => (),\n                    }\n                }\n\n                let mut replacement_str = ident_str;\n                let mut projections_handled = false;\n                cmt.place.projections.iter().enumerate().for_each(|(i, proj)| {\n                    match proj.kind {\n                        // Field projection like `|v| v.foo`\n                        // no adjustment needed here, as field projections are handled by the compiler\n                        ProjectionKind::Field(..) => match cmt.place.ty_before_projection(i).kind() {\n                            ty::Adt(..) | ty::Tuple(_) => {\n                                replacement_str.clone_from(&ident_str_with_proj);\n                                projections_handled = true;\n                            },\n                            _ => (),\n                        },\n                        // Index projection like `|x| foo[x]`\n                        // the index is dropped so we can't get it to build the suggestion,\n                        // so the span is set-up again to get more code, using `span.hi()` (i.e.: `foo[x]`)\n                        // instead of `span.lo()` (i.e.: `foo`)\n                        ProjectionKind::Index => {\n                            let start_span = Span::new(self.next_pos, span.hi(), span.ctxt(), None);\n                            start_snip = snippet_with_applicability(self.cx, start_span, \"..\", &mut self.applicability);\n                            replacement_str.clear();\n                            projections_handled = true;\n                        },\n                        // note: unable to trigger `Subslice` kind in tests\n                        ProjectionKind::Subslice |\n                        // Doesn't have surface syntax. Only occurs in patterns.\n                        ProjectionKind::OpaqueCast |\n                        // Only occurs in closure captures.\n                        ProjectionKind::UnwrapUnsafeBinder => (),\n                        ProjectionKind::Deref => {\n                            // Explicit derefs are typically handled later on, but\n                            // some items do not need explicit deref, such as array accesses,\n                            // so we mark them as already processed\n                            // i.e.: don't suggest `*sub[1..4].len()` for `|sub| sub[1..4].len() == 3`\n                            if let ty::Ref(_, inner, _) = cmt.place.ty_before_projection(i).kind()\n                                && matches!(inner.kind(), ty::Ref(_, innermost, _) if innermost.is_array()) {\n                                projections_handled = true;\n                            }\n                        },\n                    }\n                });\n\n                // handle `ProjectionKind::Deref` by removing one explicit deref\n                // if no special case was detected (i.e.: suggest `*x` instead of `**x`)\n                if !projections_handled {\n                    let last_deref = cmt\n                        .place\n                        .projections\n                        .iter()\n                        .rposition(|proj| proj.kind == ProjectionKind::Deref);\n\n                    if let Some(pos) = last_deref {\n                        let mut projections = cmt.place.projections.clone();\n                        projections.truncate(pos);\n\n                        for item in projections {\n                            if item.kind == ProjectionKind::Deref {\n                                replacement_str = format!(\"*{replacement_str}\");\n                            }\n                        }\n                    }\n                }\n\n                let _: fmt::Result = write!(self.suggestion_start, \"{start_snip}{replacement_str}\");\n            }\n            self.next_pos = span.hi();\n        }\n    }\n\n    fn mutate(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}\n}\n\n#[cfg(test)]\nmod test {\n    use super::Sugg;\n\n    use rustc_ast as ast;\n    use rustc_ast::util::parser::AssocOp;\n    use std::borrow::Cow;\n\n    const SUGGESTION: Sugg<'static> = Sugg::NonParen(Cow::Borrowed(\"function_call()\"));\n\n    #[test]\n    fn make_return_transform_sugg_into_a_return_call() {\n        assert_eq!(\"return function_call()\", SUGGESTION.make_return().to_string());\n    }\n\n    #[test]\n    fn blockify_transforms_sugg_into_a_block() {\n        assert_eq!(\"{ function_call() }\", SUGGESTION.blockify().to_string());\n    }\n\n    #[test]\n    fn binop_maybe_paren() {\n        let sugg = Sugg::BinOp(AssocOp::Binary(ast::BinOpKind::Add), \"1\".into(), \"1\".into());\n        assert_eq!(\"(1 + 1)\", sugg.maybe_paren().to_string());\n\n        let sugg = Sugg::BinOp(AssocOp::Binary(ast::BinOpKind::Add), \"(1 + 1)\".into(), \"(1 + 1)\".into());\n        assert_eq!(\"((1 + 1) + (1 + 1))\", sugg.maybe_paren().to_string());\n    }\n\n    #[test]\n    fn unop_parenthesize() {\n        let sugg = Sugg::NonParen(\"x\".into()).mut_addr();\n        assert_eq!(\"&mut x\", sugg.to_string());\n        let sugg = sugg.mut_addr();\n        assert_eq!(\"&mut &mut x\", sugg.to_string());\n        assert_eq!(\"(&mut &mut x)\", sugg.maybe_paren().to_string());\n    }\n\n    #[test]\n    fn not_op() {\n        use ast::BinOpKind::{Add, And, Eq, Ge, Gt, Le, Lt, Ne, Or};\n\n        fn test_not(op: AssocOp, correct: &str) {\n            let sugg = Sugg::BinOp(op, \"x\".into(), \"y\".into());\n            assert_eq!((!sugg).to_string(), correct);\n        }\n\n        // Invert the comparison operator.\n        test_not(AssocOp::Binary(Eq), \"x != y\");\n        test_not(AssocOp::Binary(Ne), \"x == y\");\n        test_not(AssocOp::Binary(Lt), \"x >= y\");\n        test_not(AssocOp::Binary(Le), \"x > y\");\n        test_not(AssocOp::Binary(Gt), \"x <= y\");\n        test_not(AssocOp::Binary(Ge), \"x < y\");\n\n        // Other operators are inverted like !(..).\n        test_not(AssocOp::Binary(Add), \"!(x + y)\");\n        test_not(AssocOp::Binary(And), \"!(x && y)\");\n        test_not(AssocOp::Binary(Or), \"!(x || y)\");\n    }\n}\n"
  },
  {
    "path": "clippy_utils/src/sym.rs",
    "content": "#![allow(non_upper_case_globals)]\n\nuse rustc_span::symbol::PREDEFINED_SYMBOLS_COUNT;\n\n#[doc(no_inline)]\npub use rustc_span::sym::*;\n\nmacro_rules! val {\n    ($name:ident) => {\n        stringify!($name)\n    };\n    ($name:ident $value:literal) => {\n        $value\n    };\n}\n\nmacro_rules! generate {\n    ($($name:ident $(: $value:literal)? ,)*) => {\n        /// To be supplied to `rustc_interface::Config`\n        pub const EXTRA_SYMBOLS: &[&str] = &[\n            $(\n                val!($name $($value)?),\n            )*\n        ];\n\n        $(\n            pub const $name: rustc_span::Symbol = rustc_span::Symbol::new(PREDEFINED_SYMBOLS_COUNT + ${index()});\n        )*\n    };\n}\n\n// List of extra symbols to be included in Clippy (for example, as `sym::ambiguous_glob_reexports`).\n// An alternative content can be specified using a colon after the symbol name.\n//\n// `cargo dev fmt` ensures that the content of the `generate!()` macro call stays sorted.\ngenerate! {\n    Any,\n    Applicability,\n    ArrayIntoIter,\n    AsyncReadExt,\n    AsyncWriteExt,\n    BACKSLASH_SINGLE_QUOTE: r\"\\'\",\n    BTreeEntry,\n    BTreeSet,\n    Binary,\n    BinaryHeap,\n    CLIPPY_ARGS,\n    CLIPPY_CONF_DIR,\n    CRLF: \"\\r\\n\",\n    Cargo_toml: \"Cargo.toml\",\n    Child,\n    Command,\n    Cow,\n    Current,\n    DOUBLE_QUOTE: \"\\\"\",\n    DebugStruct,\n    Deserialize,\n    DirBuilder,\n    DoubleEndedIterator,\n    Duration,\n    EarlyContext,\n    EarlyLintPass,\n    Enumerate,\n    Error,\n    File,\n    FileType,\n    FsOpenOptions,\n    FsPermissions,\n    HashMapEntry,\n    Instant,\n    IntoIter,\n    IoBufRead,\n    IoLines,\n    IoRead,\n    IoSeek,\n    IoWrite,\n    IpAddr,\n    Ipv4Addr,\n    Ipv6Addr,\n    IterEmpty,\n    IterOnce,\n    IterPeekable,\n    Itertools,\n    LF: \"\\n\",\n    LateContext,\n    Lazy,\n    LinkedList,\n    Lint,\n    LowerExp,\n    LowerHex,\n    MAX,\n    MIN,\n    MaybeDef,\n    MsrvStack,\n    Octal,\n    OpenOptions,\n    OsStr,\n    OsString,\n    Path,\n    PathBuf,\n    PathLookup,\n    RangeBounds,\n    Receiver,\n    RefCellRef,\n    RefCellRefMut,\n    Regex,\n    RegexBuilder,\n    RegexSet,\n    Saturating,\n    SeekFrom,\n    SliceIter,\n    Start,\n    Stdin,\n    Symbol,\n    SyntaxContext,\n    TBD,\n    ToOwned,\n    ToString,\n    UpperExp,\n    UpperHex,\n    V4,\n    V6,\n    VecDeque,\n    Visitor,\n    Waker,\n    Weak,\n    Wrapping,\n    abs,\n    ambiguous_glob_reexports,\n    app,\n    append,\n    applicability,\n    arg,\n    as_bytes,\n    as_deref,\n    as_deref_mut,\n    as_mut,\n    as_path,\n    as_ptr,\n    as_str,\n    assert_failed,\n    author,\n    back,\n    binaryheap_iter,\n    bool_then,\n    borrow,\n    borrow_mut,\n    box_assume_init_into_vec_unsafe,\n    btreemap_contains_key,\n    btreemap_insert,\n    btreeset_iter,\n    build_hasher,\n    by_ref,\n    bytes,\n    capacity,\n    cargo_clippy: \"cargo-clippy\",\n    cast,\n    cast_const,\n    cast_mut,\n    ceil,\n    ceil_char_boundary,\n    chain,\n    char_is_ascii,\n    char_to_digit,\n    chars,\n    check_attributes,\n    checked_abs,\n    checked_add,\n    checked_isqrt,\n    checked_mul,\n    checked_pow,\n    checked_rem_euclid,\n    checked_sub,\n    child_id,\n    child_kill,\n    clamp,\n    clippy_utils,\n    clone_into,\n    cloned,\n    cmp_max,\n    cmp_min,\n    cognitive_complexity,\n    collapsible_else_if,\n    collapsible_if,\n    collect,\n    const_ptr,\n    contains,\n    convert_identity,\n    copied,\n    copy_from,\n    copy_from_nonoverlapping,\n    copy_to,\n    copy_to_nonoverlapping,\n    core_arch,\n    core_panic_2021_macro,\n    count_ones,\n    create,\n    create_new,\n    cstring_as_c_str,\n    cx,\n    cycle,\n    cyclomatic_complexity,\n    dbg_macro,\n    de,\n    debug_struct,\n    deprecated_in_future,\n    deref_mut_method,\n    diagnostics,\n    disallowed_types,\n    drain,\n    dump,\n    duration_constructors,\n    ends_with,\n    enum_glob_use,\n    enumerate,\n    enumerate_method,\n    eprint_macro,\n    eprintln_macro,\n    err,\n    exp,\n    expect_err,\n    expn_data,\n    exported_private_dependencies,\n    extend,\n    f128_consts_mod,\n    f128_epsilon,\n    f16_consts_mod,\n    f16_epsilon,\n    f32_consts_mod,\n    f32_epsilon,\n    f32_legacy_const_digits,\n    f32_legacy_const_epsilon,\n    f32_legacy_const_infinity,\n    f32_legacy_const_mantissa_dig,\n    f32_legacy_const_max,\n    f32_legacy_const_max_10_exp,\n    f32_legacy_const_max_exp,\n    f32_legacy_const_min,\n    f32_legacy_const_min_10_exp,\n    f32_legacy_const_min_exp,\n    f32_legacy_const_min_positive,\n    f32_legacy_const_nan,\n    f32_legacy_const_neg_infinity,\n    f32_legacy_const_radix,\n    f64_consts_mod,\n    f64_epsilon,\n    f64_legacy_const_digits,\n    f64_legacy_const_epsilon,\n    f64_legacy_const_infinity,\n    f64_legacy_const_mantissa_dig,\n    f64_legacy_const_max,\n    f64_legacy_const_max_10_exp,\n    f64_legacy_const_max_exp,\n    f64_legacy_const_min,\n    f64_legacy_const_min_10_exp,\n    f64_legacy_const_min_exp,\n    f64_legacy_const_min_positive,\n    f64_legacy_const_nan,\n    f64_legacy_const_neg_infinity,\n    f64_legacy_const_radix,\n    file_options,\n    filter,\n    filter_map,\n    find,\n    find_map,\n    finish,\n    finish_non_exhaustive,\n    first,\n    flat_map,\n    flatten,\n    floor,\n    floor_char_boundary,\n    fold,\n    for_each,\n    format_args_macro,\n    from_be_bytes,\n    from_bytes_with_nul,\n    from_bytes_with_nul_unchecked,\n    from_days,\n    from_fn,\n    from_hours,\n    from_iter_fn,\n    from_le_bytes,\n    from_micros,\n    from_millis,\n    from_mins,\n    from_nanos,\n    from_nanos_u128,\n    from_ne_bytes,\n    from_ptr,\n    from_raw,\n    from_raw_parts,\n    from_secs,\n    from_secs_f32,\n    from_secs_f64,\n    from_str_method,\n    from_str_radix,\n    from_weeks,\n    front,\n    fs,\n    fs_create_dir,\n    fuse,\n    futures_util,\n    get,\n    get_mut,\n    get_or_insert,\n    get_or_insert_with,\n    get_unchecked,\n    get_unchecked_mut,\n    has_significant_drop,\n    hashmap_contains_key,\n    hashmap_drain_ty,\n    hashmap_insert,\n    hashmap_iter_mut_ty,\n    hashmap_iter_ty,\n    hashmap_keys_ty,\n    hashmap_values_mut_ty,\n    hashmap_values_ty,\n    hashset_drain_ty,\n    hashset_iter,\n    hashset_iter_ty,\n    help,\n    hidden_glob_reexports,\n    hygiene,\n    i128_legacy_const_max,\n    i128_legacy_const_min,\n    i128_legacy_fn_max_value,\n    i128_legacy_fn_min_value,\n    i128_legacy_mod,\n    i16_legacy_const_max,\n    i16_legacy_const_min,\n    i16_legacy_fn_max_value,\n    i16_legacy_fn_min_value,\n    i16_legacy_mod,\n    i32_legacy_const_max,\n    i32_legacy_const_min,\n    i32_legacy_fn_max_value,\n    i32_legacy_fn_min_value,\n    i32_legacy_mod,\n    i64_legacy_const_max,\n    i64_legacy_const_min,\n    i64_legacy_fn_max_value,\n    i64_legacy_fn_min_value,\n    i64_legacy_mod,\n    i8_legacy_const_max,\n    i8_legacy_const_min,\n    i8_legacy_fn_max_value,\n    i8_legacy_fn_min_value,\n    i8_legacy_mod,\n    ilog,\n    include_bytes_macro,\n    include_str_macro,\n    insert,\n    insert_str,\n    inspect,\n    instant_now,\n    int_roundings,\n    into,\n    into_bytes,\n    into_ok,\n    into_owned,\n    intrinsics_unaligned_volatile_load,\n    intrinsics_unaligned_volatile_store,\n    io,\n    io_error_new,\n    io_errorkind,\n    io_stderr,\n    io_stdout,\n    is_ascii,\n    is_char_boundary,\n    is_diag_item,\n    is_diagnostic_item,\n    is_digit,\n    is_empty,\n    is_err,\n    is_file,\n    is_none,\n    is_none_or,\n    is_ok,\n    is_partitioned,\n    is_some,\n    is_some_and,\n    is_sorted_by_key,\n    isize_legacy_const_max,\n    isize_legacy_const_min,\n    isize_legacy_fn_max_value,\n    isize_legacy_fn_min_value,\n    isize_legacy_mod,\n    isqrt,\n    iter_cloned,\n    iter_copied,\n    iter_filter,\n    iter_repeat,\n    itertools,\n    join,\n    kw,\n    lazy_static,\n    leading_zeros,\n    lint_vec,\n    ln,\n    lock,\n    lock_api,\n    log,\n    log10,\n    log2,\n    macro_concat,\n    macro_use_imports,\n    map_break,\n    map_continue,\n    map_or,\n    map_or_else,\n    map_while,\n    match_indices,\n    matches,\n    matches_macro,\n    max,\n    max_by,\n    max_by_key,\n    max_value,\n    maximum,\n    mem_align_of,\n    mem_replace,\n    mem_size_of,\n    mem_size_of_val,\n    min,\n    min_by,\n    min_by_key,\n    min_value,\n    minimum,\n    mode,\n    module_name_repetitions,\n    msrv,\n    msrvs,\n    mut_ptr,\n    mutex,\n    needless_return,\n    next_back,\n    next_if,\n    next_if_eq,\n    next_multiple_of,\n    next_tuple,\n    nth,\n    ok,\n    ok_or,\n    once_cell,\n    open,\n    open_options_new,\n    option_expect,\n    option_unwrap,\n    or_default,\n    or_else,\n    or_insert,\n    or_insert_with,\n    os_str_to_os_string,\n    os_string_as_os_str,\n    outer_expn,\n    panic_any,\n    parse,\n    partition,\n    path_main_separator,\n    path_to_pathbuf,\n    pathbuf_as_path,\n    paths,\n    peek,\n    peek_mut,\n    peekable,\n    permissions_from_mode,\n    pin_macro,\n    pop,\n    pop_back,\n    pop_back_if,\n    pop_front,\n    pop_front_if,\n    pop_if,\n    position,\n    pow,\n    powf,\n    powi,\n    print_macro,\n    println_macro,\n    process_abort,\n    process_exit,\n    product,\n    ptr_read_volatile,\n    ptr_slice_from_raw_parts,\n    ptr_slice_from_raw_parts_mut,\n    ptr_without_provenance,\n    ptr_without_provenance_mut,\n    push,\n    push_back,\n    push_front,\n    push_str,\n    range_step,\n    read,\n    read_exact,\n    read_line,\n    read_to_end,\n    read_to_string,\n    read_unaligned,\n    read_volatile,\n    reduce,\n    redundant_imports,\n    redundant_pub_crate,\n    regex,\n    rem_euclid,\n    repeat,\n    replace,\n    replacen,\n    res,\n    reserve,\n    resize,\n    restriction,\n    result_ok_method,\n    rev,\n    rfind,\n    rmatch_indices,\n    rmatches,\n    round,\n    rposition,\n    rsplit,\n    rsplit_once,\n    rsplit_terminator,\n    rsplitn,\n    rsplitn_mut,\n    rustc_errors,\n    rustc_lint,\n    rustc_lint_defs,\n    rustc_middle,\n    rustc_span,\n    rustfmt_skip,\n    rwlock,\n    saturating_abs,\n    saturating_div,\n    saturating_pow,\n    scan,\n    seek,\n    serde,\n    set_len,\n    set_mode,\n    set_readonly,\n    signum,\n    single_component_path_imports,\n    skip,\n    skip_while,\n    slice_from_ref,\n    slice_iter,\n    slice_mut_unchecked,\n    slice_unchecked,\n    sort,\n    sort_by,\n    sort_unstable_by,\n    span_help,\n    span_lint_and_then,\n    span_note,\n    span_suggestion,\n    split,\n    split_at,\n    split_at_checked,\n    split_at_mut,\n    split_at_mut_checked,\n    split_inclusive,\n    split_once,\n    split_terminator,\n    split_whitespace,\n    splitn,\n    splitn_mut,\n    sqrt,\n    starts_with,\n    std_detect,\n    step_by,\n    str_chars,\n    str_ends_with,\n    str_len,\n    str_split_whitespace,\n    str_starts_with,\n    str_trim,\n    str_trim_end,\n    str_trim_start,\n    string_as_mut_str,\n    string_as_str,\n    string_from_utf8,\n    string_insert_str,\n    string_new,\n    string_push_str,\n    strlen,\n    style,\n    subsec_micros,\n    subsec_nanos,\n    sum,\n    symbol,\n    take,\n    take_while,\n    tcx,\n    then,\n    then_some,\n    thread_local_macro,\n    to_ascii_lowercase,\n    to_ascii_uppercase,\n    to_be_bytes,\n    to_digit,\n    to_le_bytes,\n    to_lowercase,\n    to_ne_bytes,\n    to_os_string,\n    to_owned,\n    to_owned_method,\n    to_path_buf,\n    to_string_method,\n    to_uppercase,\n    todo_macro,\n    tokio,\n    trim,\n    trim_end,\n    trim_end_matches,\n    trim_start,\n    trim_start_matches,\n    truncate,\n    try_fold,\n    try_for_each,\n    try_from_fn,\n    unimplemented_macro,\n    unreachable_pub,\n    unsafe_removed_from_name,\n    unused,\n    unused_braces,\n    unused_extern_crates,\n    unused_import_braces,\n    unused_trait_names,\n    unwrap_err,\n    unwrap_err_unchecked,\n    unwrap_or_default,\n    unwrap_or_else,\n    unwrap_unchecked,\n    unzip,\n    utils,\n    vec_as_mut_slice,\n    vec_as_slice,\n    vec_from_elem,\n    vec_is_empty,\n    vec_macro,\n    vec_new,\n    vec_pop,\n    vec_with_capacity,\n    vecdeque_iter,\n    visit_str,\n    visit_string,\n    wake,\n    warnings,\n    wildcard_imports,\n    with_capacity,\n    wrapping_offset,\n    write,\n    write_unaligned,\n    write_volatile,\n    writeln,\n    zip,\n}\n"
  },
  {
    "path": "clippy_utils/src/ty/mod.rs",
    "content": "//! Util methods for [`rustc_middle::ty`]\n\n#![allow(clippy::module_name_repetitions)]\n\nuse core::ops::ControlFlow;\nuse rustc_abi::VariantIdx;\nuse rustc_ast::ast::Mutability;\nuse rustc_data_structures::fx::{FxHashMap, FxHashSet};\nuse rustc_hir as hir;\nuse rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::{Expr, FnDecl, LangItem, find_attr};\nuse rustc_hir_analysis::lower_ty;\nuse rustc_infer::infer::TyCtxtInferExt;\nuse rustc_lint::LateContext;\nuse rustc_middle::mir::ConstValue;\nuse rustc_middle::mir::interpret::Scalar;\nuse rustc_middle::traits::EvaluationResult;\nuse rustc_middle::ty::adjustment::{Adjust, Adjustment, DerefAdjustKind};\nuse rustc_middle::ty::layout::ValidityRequirement;\nuse rustc_middle::ty::{\n    self, AdtDef, AliasTy, AssocItem, AssocTag, Binder, BoundRegion, BoundVarIndexKind, FnSig, GenericArg,\n    GenericArgKind, GenericArgsRef, IntTy, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,\n    TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,\n};\nuse rustc_span::symbol::Ident;\nuse rustc_span::{DUMMY_SP, Span, Symbol};\nuse rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;\nuse rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;\nuse rustc_trait_selection::traits::{Obligation, ObligationCause};\n#[cfg(bootstrap)]\nuse std::assert_matches::debug_assert_matches;\nuse std::collections::hash_map::Entry;\n#[cfg(not(bootstrap))]\nuse std::debug_assert_matches;\nuse std::{iter, mem};\n\nuse crate::paths::{PathNS, lookup_path_str};\nuse crate::res::{MaybeDef, MaybeQPath};\nuse crate::sym;\n\nmod type_certainty;\npub use type_certainty::expr_type_is_certain;\n\n/// Lower a [`hir::Ty`] to a [`rustc_middle::ty::Ty`].\npub fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {\n    cx.maybe_typeck_results()\n        .filter(|results| results.hir_owner == hir_ty.hir_id.owner)\n        .and_then(|results| results.node_type_opt(hir_ty.hir_id))\n        .unwrap_or_else(|| lower_ty(cx.tcx, hir_ty))\n}\n\n/// Checks if the given type implements copy.\npub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    cx.type_is_copy_modulo_regions(ty)\n}\n\n/// This checks whether a given type is known to implement Debug.\npub fn has_debug_impl<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    cx.tcx\n        .get_diagnostic_item(sym::Debug)\n        .is_some_and(|debug| implements_trait(cx, ty, debug, &[]))\n}\n\n/// Checks whether a type can be partially moved.\npub fn can_partially_move_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    if has_drop(cx, ty) || is_copy(cx, ty) {\n        return false;\n    }\n    match ty.kind() {\n        ty::Param(_) => false,\n        ty::Adt(def, subs) => def.all_fields().any(|f| !is_copy(cx, f.ty(cx.tcx, subs))),\n        _ => true,\n    }\n}\n\n/// Walks into `ty` and returns `true` if any inner type is an instance of the given adt\n/// constructor.\npub fn contains_adt_constructor<'tcx>(ty: Ty<'tcx>, adt: AdtDef<'tcx>) -> bool {\n    ty.walk().any(|inner| match inner.kind() {\n        GenericArgKind::Type(inner_ty) => inner_ty.ty_adt_def() == Some(adt),\n        GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,\n    })\n}\n\n/// Walks into `ty` and returns `true` if any inner type is an instance of the given type, or adt\n/// constructor of the same type.\n///\n/// This method also recurses into opaque type predicates, so call it with `impl Trait<U>` and `U`\n/// will also return `true`.\npub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, needle: Ty<'tcx>) -> bool {\n    fn contains_ty_adt_constructor_opaque_inner<'tcx>(\n        cx: &LateContext<'tcx>,\n        ty: Ty<'tcx>,\n        needle: Ty<'tcx>,\n        seen: &mut FxHashSet<DefId>,\n    ) -> bool {\n        ty.walk().any(|inner| match inner.kind() {\n            GenericArgKind::Type(inner_ty) => {\n                if inner_ty == needle {\n                    return true;\n                }\n\n                if inner_ty.ty_adt_def() == needle.ty_adt_def() {\n                    return true;\n                }\n\n                if let ty::Alias(ty::Opaque, AliasTy { def_id, .. }) = *inner_ty.kind() {\n                    if !seen.insert(def_id) {\n                        return false;\n                    }\n\n                    for (predicate, _span) in cx.tcx.explicit_item_self_bounds(def_id).iter_identity_copied() {\n                        match predicate.kind().skip_binder() {\n                            // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through\n                            // and check substitutions to find `U`.\n                            ty::ClauseKind::Trait(trait_predicate)\n                                if trait_predicate\n                                    .trait_ref\n                                    .args\n                                    .types()\n                                    .skip(1) // Skip the implicit `Self` generic parameter\n                                    .any(|ty| contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen)) =>\n                            {\n                                return true;\n                            },\n                            // For `impl Trait<Assoc=U>`, it will register a predicate of `<T as Trait>::Assoc = U`,\n                            // so we check the term for `U`.\n                            ty::ClauseKind::Projection(projection_predicate) => {\n                                if let ty::TermKind::Ty(ty) = projection_predicate.term.kind()\n                                    && contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen)\n                                {\n                                    return true;\n                                }\n                            },\n                            _ => (),\n                        }\n                    }\n                }\n\n                false\n            },\n            GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,\n        })\n    }\n\n    // A hash set to ensure that the same opaque type (`impl Trait` in RPIT or TAIT) is not\n    // visited twice.\n    let mut seen = FxHashSet::default();\n    contains_ty_adt_constructor_opaque_inner(cx, ty, needle, &mut seen)\n}\n\n/// Resolves `<T as Iterator>::Item` for `T`\n/// Do not invoke without first verifying that the type implements `Iterator`\npub fn get_iterator_item_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {\n    cx.tcx\n        .get_diagnostic_item(sym::Iterator)\n        .and_then(|iter_did| cx.get_associated_type(ty, iter_did, sym::Item))\n}\n\n/// Returns true if `ty` is a type on which calling `Clone` through a function instead of\n/// as a method, such as `Arc::clone()` is considered idiomatic.\n///\n/// Lints should avoid suggesting to replace instances of `ty::Clone()` by `.clone()` for objects\n/// of those types.\npub fn should_call_clone_as_function(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    matches!(\n        ty.opt_diag_name(cx),\n        Some(sym::Arc | sym::ArcWeak | sym::Rc | sym::RcWeak)\n    )\n}\n\n/// If `ty` is known to have a `iter` or `iter_mut` method, returns a symbol representing the type.\npub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<Symbol> {\n    // FIXME: instead of this hard-coded list, we should check if `<adt>::iter`\n    // exists and has the desired signature. Unfortunately FnCtxt is not exported\n    // so we can't use its `lookup_method` method.\n    let into_iter_collections: &[Symbol] = &[\n        sym::Vec,\n        sym::Option,\n        sym::Result,\n        sym::BTreeMap,\n        sym::BTreeSet,\n        sym::VecDeque,\n        sym::LinkedList,\n        sym::BinaryHeap,\n        sym::HashSet,\n        sym::HashMap,\n        sym::PathBuf,\n        sym::Path,\n        sym::Receiver,\n    ];\n\n    let ty_to_check = match probably_ref_ty.kind() {\n        ty::Ref(_, ty_to_check, _) => *ty_to_check,\n        _ => probably_ref_ty,\n    };\n\n    let def_id = match ty_to_check.kind() {\n        ty::Array(..) => return Some(sym::array),\n        ty::Slice(..) => return Some(sym::slice),\n        ty::Adt(adt, _) => adt.did(),\n        _ => return None,\n    };\n\n    for &name in into_iter_collections {\n        if cx.tcx.is_diagnostic_item(name, def_id) {\n            return Some(cx.tcx.item_name(def_id));\n        }\n    }\n    None\n}\n\n/// Checks whether a type implements a trait.\n/// The function returns false in case the type contains an inference variable.\n///\n/// See [Common tools for writing lints] for an example how to use this function and other options.\n///\n/// [Common tools for writing lints]: https://github.com/rust-lang/rust-clippy/blob/master/book/src/development/common_tools_writing_lints.md#checking-if-a-type-implements-a-specific-trait\npub fn implements_trait<'tcx>(\n    cx: &LateContext<'tcx>,\n    ty: Ty<'tcx>,\n    trait_id: DefId,\n    args: &[GenericArg<'tcx>],\n) -> bool {\n    implements_trait_with_env_from_iter(\n        cx.tcx,\n        cx.typing_env(),\n        ty,\n        trait_id,\n        None,\n        args.iter().map(|&x| Some(x)),\n    )\n}\n\n/// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.\n///\n/// The `callee_id` argument is used to determine whether this is a function call in a `const fn`\n/// environment, used for checking const traits.\npub fn implements_trait_with_env<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    typing_env: ty::TypingEnv<'tcx>,\n    ty: Ty<'tcx>,\n    trait_id: DefId,\n    callee_id: Option<DefId>,\n    args: &[GenericArg<'tcx>],\n) -> bool {\n    implements_trait_with_env_from_iter(tcx, typing_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x)))\n}\n\n/// Same as `implements_trait_from_env` but takes the arguments as an iterator.\npub fn implements_trait_with_env_from_iter<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    typing_env: ty::TypingEnv<'tcx>,\n    ty: Ty<'tcx>,\n    trait_id: DefId,\n    callee_id: Option<DefId>,\n    args: impl IntoIterator<Item = impl Into<Option<GenericArg<'tcx>>>>,\n) -> bool {\n    // Clippy shouldn't have infer types\n    assert!(!ty.has_infer());\n\n    // If a `callee_id` is passed, then we assert that it is a body owner\n    // through calling `body_owner_kind`, which would panic if the callee\n    // does not have a body.\n    if let Some(callee_id) = callee_id {\n        let _ = tcx.hir_body_owner_kind(callee_id);\n    }\n\n    let ty = tcx.erase_and_anonymize_regions(ty);\n    if ty.has_escaping_bound_vars() {\n        return false;\n    }\n\n    let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);\n    let args = args\n        .into_iter()\n        .map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into()))\n        .collect::<Vec<_>>();\n\n    let trait_ref = TraitRef::new(tcx, trait_id, [GenericArg::from(ty)].into_iter().chain(args));\n\n    debug_assert_matches!(\n        tcx.def_kind(trait_id),\n        DefKind::Trait | DefKind::TraitAlias,\n        \"`DefId` must belong to a trait or trait alias\"\n    );\n    #[cfg(debug_assertions)]\n    assert_generic_args_match(tcx, trait_id, trait_ref.args);\n\n    let obligation = Obligation {\n        cause: ObligationCause::dummy(),\n        param_env,\n        recursion_depth: 0,\n        predicate: trait_ref.upcast(tcx),\n    };\n    infcx\n        .evaluate_obligation(&obligation)\n        .is_ok_and(EvaluationResult::must_apply_modulo_regions)\n}\n\n/// Checks whether this type implements `Drop`.\npub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    match ty.ty_adt_def() {\n        Some(def) => def.has_dtor(cx.tcx),\n        None => false,\n    }\n}\n\n// Returns whether the `ty` has `#[must_use]` attribute. If `ty` is a `Result`/`ControlFlow`\n// whose `Err`/`Break` payload is an uninhabited type, the `Ok`/`Continue` payload type\n// will be used instead. See <https://github.com/rust-lang/rust/pull/148214>.\npub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    match ty.kind() {\n        ty::Adt(adt, args) => match cx.tcx.get_diagnostic_name(adt.did()) {\n            Some(sym::Result) if args.type_at(1).is_privately_uninhabited(cx.tcx, cx.typing_env()) => {\n                is_must_use_ty(cx, args.type_at(0))\n            },\n            Some(sym::ControlFlow) if args.type_at(0).is_privately_uninhabited(cx.tcx, cx.typing_env()) => {\n                is_must_use_ty(cx, args.type_at(1))\n            },\n            _ => find_attr!(cx.tcx, adt.did(), MustUse { .. }),\n        },\n        ty::Foreign(did) => find_attr!(cx.tcx, *did, MustUse { .. }),\n        ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => {\n            // for the Array case we don't need to care for the len == 0 case\n            // because we don't want to lint functions returning empty arrays\n            is_must_use_ty(cx, *ty)\n        },\n        ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)),\n        ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {\n            for (predicate, _) in cx.tcx.explicit_item_self_bounds(*def_id).skip_binder() {\n                if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()\n                    && find_attr!(cx.tcx, trait_predicate.trait_ref.def_id, MustUse { .. })\n                {\n                    return true;\n                }\n            }\n            false\n        },\n        ty::Dynamic(binder, _) => {\n            for predicate in *binder {\n                if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder()\n                    && find_attr!(cx.tcx, trait_ref.def_id, MustUse { .. })\n                {\n                    return true;\n                }\n            }\n            false\n        },\n        _ => false,\n    }\n}\n\n/// Returns `true` if the given type is a non aggregate primitive (a `bool` or `char`, any\n/// integer or floating-point number type).\n///\n/// For checking aggregation of primitive types (e.g. tuples and slices of primitive type) see\n/// `is_recursively_primitive_type`\npub fn is_non_aggregate_primitive_type(ty: Ty<'_>) -> bool {\n    matches!(ty.kind(), ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_))\n}\n\n/// Returns `true` if the given type is a primitive (a `bool` or `char`, any integer or\n/// floating-point number type, a `str`, or an array, slice, or tuple of those types).\npub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {\n    match *ty.kind() {\n        ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => true,\n        ty::Ref(_, inner, _) if inner.is_str() => true,\n        ty::Array(inner_type, _) | ty::Slice(inner_type) => is_recursively_primitive_type(inner_type),\n        ty::Tuple(inner_types) => inner_types.iter().all(is_recursively_primitive_type),\n        _ => false,\n    }\n}\n\n/// Return `true` if the passed `typ` is `isize` or `usize`.\npub fn is_isize_or_usize(typ: Ty<'_>) -> bool {\n    matches!(typ.kind(), ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize))\n}\n\n/// Checks if the drop order for a type matters.\n///\n/// Some std types implement drop solely to deallocate memory. For these types, and composites\n/// containing them, changing the drop order won't result in any observable side effects.\npub fn needs_ordered_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    fn needs_ordered_drop_inner<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, seen: &mut FxHashSet<Ty<'tcx>>) -> bool {\n        if !seen.insert(ty) {\n            return false;\n        }\n        if !ty.has_significant_drop(cx.tcx, cx.typing_env()) {\n            false\n        }\n        // Check for std types which implement drop, but only for memory allocation.\n        else if ty.is_lang_item(cx, LangItem::OwnedBox)\n            || matches!(\n                ty.opt_diag_name(cx),\n                Some(sym::HashSet | sym::Rc | sym::Arc | sym::cstring_type | sym::RcWeak | sym::ArcWeak)\n            )\n        {\n            // Check all of the generic arguments.\n            if let ty::Adt(_, subs) = ty.kind() {\n                subs.types().any(|ty| needs_ordered_drop_inner(cx, ty, seen))\n            } else {\n                true\n            }\n        } else if !cx\n            .tcx\n            .lang_items()\n            .drop_trait()\n            .is_some_and(|id| implements_trait(cx, ty, id, &[]))\n        {\n            // This type doesn't implement drop, so no side effects here.\n            // Check if any component type has any.\n            match ty.kind() {\n                ty::Tuple(fields) => fields.iter().any(|ty| needs_ordered_drop_inner(cx, ty, seen)),\n                ty::Array(ty, _) => needs_ordered_drop_inner(cx, *ty, seen),\n                ty::Adt(adt, subs) => adt\n                    .all_fields()\n                    .map(|f| f.ty(cx.tcx, subs))\n                    .any(|ty| needs_ordered_drop_inner(cx, ty, seen)),\n                _ => true,\n            }\n        } else {\n            true\n        }\n    }\n\n    needs_ordered_drop_inner(cx, ty, &mut FxHashSet::default())\n}\n\n/// Returns `true` if `ty` denotes an `unsafe fn`.\npub fn is_unsafe_fn<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    ty.is_fn() && ty.fn_sig(cx.tcx).safety().is_unsafe()\n}\n\n/// Peels off all references on the type. Returns the underlying type, the number of references\n/// removed, and, if there were any such references, whether the pointer is ultimately mutable or\n/// not.\npub fn peel_and_count_ty_refs(mut ty: Ty<'_>) -> (Ty<'_>, usize, Option<Mutability>) {\n    let mut count = 0;\n    let mut mutbl = None;\n    while let ty::Ref(_, dest_ty, m) = ty.kind() {\n        ty = *dest_ty;\n        count += 1;\n        mutbl.replace(mutbl.map_or(*m, |mutbl: Mutability| mutbl.min(*m)));\n    }\n    (ty, count, mutbl)\n}\n\n/// Peels off `n` references on the type. Returns the underlying type and, if any references\n/// were removed, whether the pointer is ultimately mutable or not.\npub fn peel_n_ty_refs(mut ty: Ty<'_>, n: usize) -> (Ty<'_>, Option<Mutability>) {\n    let mut mutbl = None;\n    for _ in 0..n {\n        if let ty::Ref(_, dest_ty, m) = ty.kind() {\n            ty = *dest_ty;\n            mutbl.replace(mutbl.map_or(*m, |mutbl: Mutability| mutbl.min(*m)));\n        } else {\n            break;\n        }\n    }\n    (ty, mutbl)\n}\n\n/// Checks whether `a` and `b` are same types having same `Const` generic args, but ignores\n/// lifetimes.\n///\n/// For example, the function would return `true` for\n/// - `u32` and `u32`\n/// - `[u8; N]` and `[u8; M]`, if `N=M`\n/// - `Option<T>` and `Option<U>`, if `same_type_modulo_regions(T, U)` holds\n/// - `&'a str` and `&'b str`\n///\n/// and `false` for:\n/// - `Result<u32, String>` and `Result<usize, String>`\npub fn same_type_modulo_regions<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {\n    match (&a.kind(), &b.kind()) {\n        (&ty::Adt(did_a, args_a), &ty::Adt(did_b, args_b)) => {\n            if did_a != did_b {\n                return false;\n            }\n\n            iter::zip(*args_a, *args_b).all(|(arg_a, arg_b)| match (arg_a.kind(), arg_b.kind()) {\n                (GenericArgKind::Const(inner_a), GenericArgKind::Const(inner_b)) => inner_a == inner_b,\n                (GenericArgKind::Type(type_a), GenericArgKind::Type(type_b)) => {\n                    same_type_modulo_regions(type_a, type_b)\n                },\n                _ => true,\n            })\n        },\n        _ => a == b,\n    }\n}\n\n/// Checks if a given type looks safe to be uninitialized.\npub fn is_uninit_value_valid_for_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    let typing_env = cx.typing_env().with_post_analysis_normalized(cx.tcx);\n    cx.tcx\n        .check_validity_requirement((ValidityRequirement::Uninit, typing_env.as_query_input(ty)))\n        .unwrap_or_else(|_| is_uninit_value_valid_for_ty_fallback(cx, ty))\n}\n\n/// A fallback for polymorphic types, which are not supported by `check_validity_requirement`.\nfn is_uninit_value_valid_for_ty_fallback<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    match *ty.kind() {\n        // The array length may be polymorphic, let's try the inner type.\n        ty::Array(component, _) => is_uninit_value_valid_for_ty(cx, component),\n        // Peek through tuples and try their fallbacks.\n        ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),\n        // Unions are always fine right now.\n        // This includes MaybeUninit, the main way people use uninitialized memory.\n        ty::Adt(adt, _) if adt.is_union() => true,\n        // Types (e.g. `UnsafeCell<MaybeUninit<T>>`) that recursively contain only types that can be uninit\n        // can themselves be uninit too.\n        // This purposefully ignores enums as they may have a discriminant that can't be uninit.\n        ty::Adt(adt, args) if adt.is_struct() => adt\n            .all_fields()\n            .all(|field| is_uninit_value_valid_for_ty(cx, field.ty(cx.tcx, args))),\n        // For the rest, conservatively assume that they cannot be uninit.\n        _ => false,\n    }\n}\n\n/// Gets an iterator over all predicates which apply to the given item.\npub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator<Item = &(ty::Clause<'_>, Span)> {\n    let mut next_id = Some(id);\n    iter::from_fn(move || {\n        next_id.take().map(|id| {\n            let preds = tcx.predicates_of(id);\n            next_id = preds.parent;\n            preds.predicates.iter()\n        })\n    })\n    .flatten()\n}\n\n/// A signature for a function like type.\n#[derive(Clone, Copy, Debug)]\npub enum ExprFnSig<'tcx> {\n    Sig(Binder<'tcx, FnSig<'tcx>>, Option<DefId>),\n    Closure(Option<&'tcx FnDecl<'tcx>>, Binder<'tcx, FnSig<'tcx>>),\n    Trait(Binder<'tcx, Ty<'tcx>>, Option<Binder<'tcx, Ty<'tcx>>>, Option<DefId>),\n}\nimpl<'tcx> ExprFnSig<'tcx> {\n    /// Gets the argument type at the given offset. This will return `None` when the index is out of\n    /// bounds only for variadic functions, otherwise this will panic.\n    pub fn input(self, i: usize) -> Option<Binder<'tcx, Ty<'tcx>>> {\n        match self {\n            Self::Sig(sig, _) => {\n                if sig.c_variadic() {\n                    sig.inputs().map_bound(|inputs| inputs.get(i).copied()).transpose()\n                } else {\n                    Some(sig.input(i))\n                }\n            },\n            Self::Closure(_, sig) => Some(sig.input(0).map_bound(|ty| ty.tuple_fields()[i])),\n            Self::Trait(inputs, _, _) => Some(inputs.map_bound(|ty| ty.tuple_fields()[i])),\n        }\n    }\n\n    /// Gets the argument type at the given offset. For closures this will also get the type as\n    /// written. This will return `None` when the index is out of bounds only for variadic\n    /// functions, otherwise this will panic.\n    pub fn input_with_hir(self, i: usize) -> Option<(Option<&'tcx hir::Ty<'tcx>>, Binder<'tcx, Ty<'tcx>>)> {\n        match self {\n            Self::Sig(sig, _) => {\n                if sig.c_variadic() {\n                    sig.inputs()\n                        .map_bound(|inputs| inputs.get(i).copied())\n                        .transpose()\n                        .map(|arg| (None, arg))\n                } else {\n                    Some((None, sig.input(i)))\n                }\n            },\n            Self::Closure(decl, sig) => Some((\n                decl.and_then(|decl| decl.inputs.get(i)),\n                sig.input(0).map_bound(|ty| ty.tuple_fields()[i]),\n            )),\n            Self::Trait(inputs, _, _) => Some((None, inputs.map_bound(|ty| ty.tuple_fields()[i]))),\n        }\n    }\n\n    /// Gets the result type, if one could be found. Note that the result type of a trait may not be\n    /// specified.\n    pub fn output(self) -> Option<Binder<'tcx, Ty<'tcx>>> {\n        match self {\n            Self::Sig(sig, _) | Self::Closure(_, sig) => Some(sig.output()),\n            Self::Trait(_, output, _) => output,\n        }\n    }\n\n    pub fn predicates_id(&self) -> Option<DefId> {\n        if let ExprFnSig::Sig(_, id) | ExprFnSig::Trait(_, _, id) = *self {\n            id\n        } else {\n            None\n        }\n    }\n}\n\n/// If the expression is function like, get the signature for it.\npub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnSig<'tcx>> {\n    if let Res::Def(DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::AssocFn, id) = expr.res(cx) {\n        Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate_identity(), Some(id)))\n    } else {\n        ty_sig(cx, cx.typeck_results().expr_ty_adjusted(expr).peel_refs())\n    }\n}\n\n/// If the type is function like, get the signature for it.\npub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>> {\n    if let Some(boxed_ty) = ty.boxed_ty() {\n        return ty_sig(cx, boxed_ty);\n    }\n    match *ty.kind() {\n        ty::Closure(id, subs) => {\n            let decl = id\n                .as_local()\n                .and_then(|id| cx.tcx.hir_fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(id)));\n            Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))\n        },\n        ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))),\n        ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) => sig_from_bounds(\n            cx,\n            ty,\n            cx.tcx.item_self_bounds(def_id).iter_instantiated(cx.tcx, args),\n            cx.tcx.opt_parent(def_id),\n        ),\n        ty::FnPtr(sig_tys, hdr) => Some(ExprFnSig::Sig(sig_tys.with(hdr), None)),\n        ty::Dynamic(bounds, _) => {\n            let lang_items = cx.tcx.lang_items();\n            match bounds.principal() {\n                Some(bound)\n                    if Some(bound.def_id()) == lang_items.fn_trait()\n                        || Some(bound.def_id()) == lang_items.fn_once_trait()\n                        || Some(bound.def_id()) == lang_items.fn_mut_trait() =>\n                {\n                    let output = bounds\n                        .projection_bounds()\n                        .find(|p| lang_items.fn_once_output().is_some_and(|id| id == p.item_def_id()))\n                        .map(|p| p.map_bound(|p| p.term.expect_type()));\n                    Some(ExprFnSig::Trait(bound.map_bound(|b| b.args.type_at(0)), output, None))\n                },\n                _ => None,\n            }\n        },\n        ty::Alias(ty::Projection, proj) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) {\n            Ok(normalized_ty) if normalized_ty != ty => ty_sig(cx, normalized_ty),\n            _ => sig_for_projection(cx, proj).or_else(|| sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None)),\n        },\n        ty::Param(_) => sig_from_bounds(cx, ty, cx.param_env.caller_bounds(), None),\n        _ => None,\n    }\n}\n\nfn sig_from_bounds<'tcx>(\n    cx: &LateContext<'tcx>,\n    ty: Ty<'tcx>,\n    predicates: impl IntoIterator<Item = ty::Clause<'tcx>>,\n    predicates_id: Option<DefId>,\n) -> Option<ExprFnSig<'tcx>> {\n    let mut inputs = None;\n    let mut output = None;\n    let lang_items = cx.tcx.lang_items();\n\n    for pred in predicates {\n        match pred.kind().skip_binder() {\n            ty::ClauseKind::Trait(p)\n                if (lang_items.fn_trait() == Some(p.def_id())\n                    || lang_items.fn_mut_trait() == Some(p.def_id())\n                    || lang_items.fn_once_trait() == Some(p.def_id()))\n                    && p.self_ty() == ty =>\n            {\n                let i = pred.kind().rebind(p.trait_ref.args.type_at(1));\n                if inputs.is_some_and(|inputs| i != inputs) {\n                    // Multiple different fn trait impls. Is this even allowed?\n                    return None;\n                }\n                inputs = Some(i);\n            },\n            ty::ClauseKind::Projection(p)\n                if Some(p.projection_term.def_id) == lang_items.fn_once_output()\n                    && p.projection_term.self_ty() == ty =>\n            {\n                if output.is_some() {\n                    // Multiple different fn trait impls. Is this even allowed?\n                    return None;\n                }\n                output = Some(pred.kind().rebind(p.term.expect_type()));\n            },\n            _ => (),\n        }\n    }\n\n    inputs.map(|ty| ExprFnSig::Trait(ty, output, predicates_id))\n}\n\nfn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option<ExprFnSig<'tcx>> {\n    let mut inputs = None;\n    let mut output = None;\n    let lang_items = cx.tcx.lang_items();\n\n    for (pred, _) in cx\n        .tcx\n        .explicit_item_bounds(ty.def_id)\n        .iter_instantiated_copied(cx.tcx, ty.args)\n    {\n        match pred.kind().skip_binder() {\n            ty::ClauseKind::Trait(p)\n                if (lang_items.fn_trait() == Some(p.def_id())\n                    || lang_items.fn_mut_trait() == Some(p.def_id())\n                    || lang_items.fn_once_trait() == Some(p.def_id())) =>\n            {\n                let i = pred.kind().rebind(p.trait_ref.args.type_at(1));\n\n                if inputs.is_some_and(|inputs| inputs != i) {\n                    // Multiple different fn trait impls. Is this even allowed?\n                    return None;\n                }\n                inputs = Some(i);\n            },\n            ty::ClauseKind::Projection(p) if Some(p.projection_term.def_id) == lang_items.fn_once_output() => {\n                if output.is_some() {\n                    // Multiple different fn trait impls. Is this even allowed?\n                    return None;\n                }\n                output = pred.kind().rebind(p.term.as_type()).transpose();\n            },\n            _ => (),\n        }\n    }\n\n    inputs.map(|ty| ExprFnSig::Trait(ty, output, None))\n}\n\n#[derive(Clone, Copy)]\npub enum EnumValue {\n    Unsigned(u128),\n    Signed(i128),\n}\nimpl core::ops::Add<u32> for EnumValue {\n    type Output = Self;\n    fn add(self, n: u32) -> Self::Output {\n        match self {\n            Self::Unsigned(x) => Self::Unsigned(x + u128::from(n)),\n            Self::Signed(x) => Self::Signed(x + i128::from(n)),\n        }\n    }\n}\n\n/// Attempts to read the given constant as though it were an enum value.\npub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option<EnumValue> {\n    if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) {\n        match tcx.type_of(id).instantiate_identity().kind() {\n            ty::Int(_) => Some(EnumValue::Signed(value.to_int(value.size()))),\n            ty::Uint(_) => Some(EnumValue::Unsigned(value.to_uint(value.size()))),\n            _ => None,\n        }\n    } else {\n        None\n    }\n}\n\n/// Gets the value of the given variant.\npub fn get_discriminant_value(tcx: TyCtxt<'_>, adt: AdtDef<'_>, i: VariantIdx) -> EnumValue {\n    let variant = &adt.variant(i);\n    match variant.discr {\n        VariantDiscr::Explicit(id) => read_explicit_enum_value(tcx, id).unwrap(),\n        VariantDiscr::Relative(x) => match adt.variant((i.as_usize() - x as usize).into()).discr {\n            VariantDiscr::Explicit(id) => read_explicit_enum_value(tcx, id).unwrap() + x,\n            VariantDiscr::Relative(_) => EnumValue::Unsigned(x.into()),\n        },\n    }\n}\n\n/// Check if the given type is either `core::ffi::c_void`, `std::os::raw::c_void`, or one of the\n/// platform specific `libc::<platform>::c_void` types in libc.\npub fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {\n    if let ty::Adt(adt, _) = ty.kind()\n        && let &[krate, .., name] = &*cx.get_def_path(adt.did())\n        && let sym::libc | sym::core | sym::std = krate\n        && name == sym::c_void\n    {\n        true\n    } else {\n        false\n    }\n}\n\npub fn for_each_top_level_late_bound_region<'cx, B>(\n    ty: Ty<'cx>,\n    f: impl FnMut(BoundRegion<'cx>) -> ControlFlow<B>,\n) -> ControlFlow<B> {\n    struct V<F> {\n        index: u32,\n        f: F,\n    }\n    impl<'tcx, B, F: FnMut(BoundRegion<'tcx>) -> ControlFlow<B>> TypeVisitor<TyCtxt<'tcx>> for V<F> {\n        type Result = ControlFlow<B>;\n        fn visit_region(&mut self, r: Region<'tcx>) -> Self::Result {\n            if let RegionKind::ReBound(BoundVarIndexKind::Bound(idx), bound) = r.kind()\n                && idx.as_u32() == self.index\n            {\n                (self.f)(bound)\n            } else {\n                ControlFlow::Continue(())\n            }\n        }\n        fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> Self::Result {\n            self.index += 1;\n            let res = t.super_visit_with(self);\n            self.index -= 1;\n            res\n        }\n    }\n    ty.visit_with(&mut V { index: 0, f })\n}\n\npub struct AdtVariantInfo {\n    pub ind: usize,\n    pub size: u64,\n\n    /// (ind, size)\n    pub fields_size: Vec<(usize, u64)>,\n}\n\nimpl AdtVariantInfo {\n    /// Returns ADT variants ordered by size\n    pub fn new<'tcx>(cx: &LateContext<'tcx>, adt: AdtDef<'tcx>, subst: GenericArgsRef<'tcx>) -> Vec<Self> {\n        let mut variants_size = adt\n            .variants()\n            .iter()\n            .enumerate()\n            .map(|(i, variant)| {\n                let mut fields_size = variant\n                    .fields\n                    .iter()\n                    .enumerate()\n                    .map(|(i, f)| (i, approx_ty_size(cx, f.ty(cx.tcx, subst))))\n                    .collect::<Vec<_>>();\n                fields_size.sort_by_key(|(_, a_size)| *a_size);\n\n                Self {\n                    ind: i,\n                    size: fields_size.iter().map(|(_, size)| size).sum(),\n                    fields_size,\n                }\n            })\n            .collect::<Vec<_>>();\n        variants_size.sort_by_key(|b| std::cmp::Reverse(b.size));\n        variants_size\n    }\n}\n\n/// Gets the struct or enum variant from the given `Res`\npub fn adt_and_variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option<(AdtDef<'tcx>, &'tcx VariantDef)> {\n    match res {\n        Res::Def(DefKind::Struct, id) => {\n            let adt = cx.tcx.adt_def(id);\n            Some((adt, adt.non_enum_variant()))\n        },\n        Res::Def(DefKind::Variant, id) => {\n            let adt = cx.tcx.adt_def(cx.tcx.parent(id));\n            Some((adt, adt.variant_with_id(id)))\n        },\n        Res::Def(DefKind::Ctor(CtorOf::Struct, _), id) => {\n            let adt = cx.tcx.adt_def(cx.tcx.parent(id));\n            Some((adt, adt.non_enum_variant()))\n        },\n        Res::Def(DefKind::Ctor(CtorOf::Variant, _), id) => {\n            let var_id = cx.tcx.parent(id);\n            let adt = cx.tcx.adt_def(cx.tcx.parent(var_id));\n            Some((adt, adt.variant_with_id(var_id)))\n        },\n        Res::SelfCtor(id) => {\n            let adt = cx.tcx.type_of(id).instantiate_identity().ty_adt_def().unwrap();\n            Some((adt, adt.non_enum_variant()))\n        },\n        _ => None,\n    }\n}\n\n/// Comes up with an \"at least\" guesstimate for the type's size, not taking into\n/// account the layout of type parameters.\npub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 {\n    use rustc_middle::ty::layout::LayoutOf;\n    match (cx.layout_of(ty).map(|layout| layout.size.bytes()), ty.kind()) {\n        (Ok(size), _) => size,\n        (Err(_), ty::Tuple(list)) => list.iter().map(|t| approx_ty_size(cx, t)).sum(),\n        (Err(_), ty::Array(t, n)) => n.try_to_target_usize(cx.tcx).unwrap_or_default() * approx_ty_size(cx, *t),\n        (Err(_), ty::Adt(def, subst)) if def.is_struct() => def\n            .variants()\n            .iter()\n            .map(|v| {\n                v.fields\n                    .iter()\n                    .map(|field| approx_ty_size(cx, field.ty(cx.tcx, subst)))\n                    .sum::<u64>()\n            })\n            .sum(),\n        (Err(_), ty::Adt(def, subst)) if def.is_enum() => def\n            .variants()\n            .iter()\n            .map(|v| {\n                v.fields\n                    .iter()\n                    .map(|field| approx_ty_size(cx, field.ty(cx.tcx, subst)))\n                    .sum::<u64>()\n            })\n            .max()\n            .unwrap_or_default(),\n        (Err(_), ty::Adt(def, subst)) if def.is_union() => def\n            .variants()\n            .iter()\n            .map(|v| {\n                v.fields\n                    .iter()\n                    .map(|field| approx_ty_size(cx, field.ty(cx.tcx, subst)))\n                    .max()\n                    .unwrap_or_default()\n            })\n            .max()\n            .unwrap_or_default(),\n        (Err(_), _) => 0,\n    }\n}\n\n#[cfg(debug_assertions)]\n/// Asserts that the given arguments match the generic parameters of the given item.\nfn assert_generic_args_match<'tcx>(tcx: TyCtxt<'tcx>, did: DefId, args: &[GenericArg<'tcx>]) {\n    use itertools::Itertools;\n    let g = tcx.generics_of(did);\n    let parent = g.parent.map(|did| tcx.generics_of(did));\n    let count = g.parent_count + g.own_params.len();\n    let params = parent\n        .map_or([].as_slice(), |p| p.own_params.as_slice())\n        .iter()\n        .chain(&g.own_params)\n        .map(|x| &x.kind);\n\n    assert!(\n        count == args.len(),\n        \"wrong number of arguments for `{did:?}`: expected `{count}`, found {}\\n\\\n            note: the expected arguments are: `[{}]`\\n\\\n            the given arguments are: `{args:#?}`\",\n        args.len(),\n        params.clone().map(ty::GenericParamDefKind::descr).format(\", \"),\n    );\n\n    if let Some((idx, (param, arg))) =\n        params\n            .clone()\n            .zip(args.iter().map(|&x| x.kind()))\n            .enumerate()\n            .find(|(_, (param, arg))| match (param, arg) {\n                (ty::GenericParamDefKind::Lifetime, GenericArgKind::Lifetime(_))\n                | (ty::GenericParamDefKind::Type { .. }, GenericArgKind::Type(_))\n                | (ty::GenericParamDefKind::Const { .. }, GenericArgKind::Const(_)) => false,\n                (\n                    ty::GenericParamDefKind::Lifetime\n                    | ty::GenericParamDefKind::Type { .. }\n                    | ty::GenericParamDefKind::Const { .. },\n                    _,\n                ) => true,\n            })\n    {\n        panic!(\n            \"incorrect argument for `{did:?}` at index `{idx}`: expected a {}, found `{arg:?}`\\n\\\n                note: the expected arguments are `[{}]`\\n\\\n                the given arguments are `{args:#?}`\",\n            param.descr(),\n            params.clone().map(ty::GenericParamDefKind::descr).format(\", \"),\n        );\n    }\n}\n\n/// Returns whether `ty` is never-like; i.e., `!` (never) or an enum with zero variants.\npub fn is_never_like(ty: Ty<'_>) -> bool {\n    ty.is_never() || (ty.is_enum() && ty.ty_adt_def().is_some_and(|def| def.variants().is_empty()))\n}\n\n/// Makes the projection type for the named associated type in the given impl or trait impl.\n///\n/// This function is for associated types which are \"known\" to exist, and as such, will only return\n/// `None` when debug assertions are disabled in order to prevent ICE's. With debug assertions\n/// enabled this will check that the named associated type exists, the correct number of\n/// arguments are given, and that the correct kinds of arguments are given (lifetime,\n/// constant or type). This will not check if type normalization would succeed.\npub fn make_projection<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    container_id: DefId,\n    assoc_ty: Symbol,\n    args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,\n) -> Option<AliasTy<'tcx>> {\n    fn helper<'tcx>(\n        tcx: TyCtxt<'tcx>,\n        container_id: DefId,\n        assoc_ty: Symbol,\n        args: GenericArgsRef<'tcx>,\n    ) -> Option<AliasTy<'tcx>> {\n        let Some(assoc_item) = tcx.associated_items(container_id).find_by_ident_and_kind(\n            tcx,\n            Ident::with_dummy_span(assoc_ty),\n            AssocTag::Type,\n            container_id,\n        ) else {\n            debug_assert!(false, \"type `{assoc_ty}` not found in `{container_id:?}`\");\n            return None;\n        };\n        #[cfg(debug_assertions)]\n        assert_generic_args_match(tcx, assoc_item.def_id, args);\n\n        Some(AliasTy::new_from_args(tcx, assoc_item.def_id, args))\n    }\n    helper(\n        tcx,\n        container_id,\n        assoc_ty,\n        tcx.mk_args_from_iter(args.into_iter().map(Into::into)),\n    )\n}\n\n/// Normalizes the named associated type in the given impl or trait impl.\n///\n/// This function is for associated types which are \"known\" to be valid with the given\n/// arguments, and as such, will only return `None` when debug assertions are disabled in order\n/// to prevent ICE's. With debug assertions enabled this will check that type normalization\n/// succeeds as well as everything checked by `make_projection`.\npub fn make_normalized_projection<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    typing_env: ty::TypingEnv<'tcx>,\n    container_id: DefId,\n    assoc_ty: Symbol,\n    args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,\n) -> Option<Ty<'tcx>> {\n    fn helper<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> {\n        #[cfg(debug_assertions)]\n        if let Some((i, arg)) = ty\n            .args\n            .iter()\n            .enumerate()\n            .find(|(_, arg)| arg.has_escaping_bound_vars())\n        {\n            debug_assert!(\n                false,\n                \"args contain late-bound region at index `{i}` which can't be normalized.\\n\\\n                    use `TyCtxt::instantiate_bound_regions_with_erased`\\n\\\n                    note: arg is `{arg:#?}`\",\n            );\n            return None;\n        }\n        match tcx.try_normalize_erasing_regions(typing_env, Ty::new_projection_from_args(tcx, ty.def_id, ty.args)) {\n            Ok(ty) => Some(ty),\n            Err(e) => {\n                debug_assert!(false, \"failed to normalize type `{ty}`: {e:#?}\");\n                None\n            },\n        }\n    }\n    helper(tcx, typing_env, make_projection(tcx, container_id, assoc_ty, args)?)\n}\n\n/// Helper to check if given type has inner mutability such as [`std::cell::Cell`] or\n/// [`std::cell::RefCell`].\n#[derive(Default, Debug)]\npub struct InteriorMut<'tcx> {\n    ignored_def_ids: FxHashSet<DefId>,\n    ignore_pointers: bool,\n    tys: FxHashMap<Ty<'tcx>, Option<&'tcx ty::List<Ty<'tcx>>>>,\n}\n\nimpl<'tcx> InteriorMut<'tcx> {\n    pub fn new(tcx: TyCtxt<'tcx>, ignore_interior_mutability: &[String]) -> Self {\n        let ignored_def_ids = ignore_interior_mutability\n            .iter()\n            .flat_map(|ignored_ty| lookup_path_str(tcx, PathNS::Type, ignored_ty))\n            .collect();\n\n        Self {\n            ignored_def_ids,\n            ..Self::default()\n        }\n    }\n\n    pub fn without_pointers(tcx: TyCtxt<'tcx>, ignore_interior_mutability: &[String]) -> Self {\n        Self {\n            ignore_pointers: true,\n            ..Self::new(tcx, ignore_interior_mutability)\n        }\n    }\n\n    /// Check if given type has interior mutability such as [`std::cell::Cell`] or\n    /// [`std::cell::RefCell`] etc. and if it does, returns a chain of types that causes\n    /// this type to be interior mutable.  False negatives may be expected for infinitely recursive\n    /// types, and `None` will be returned there.\n    pub fn interior_mut_ty_chain(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx ty::List<Ty<'tcx>>> {\n        self.interior_mut_ty_chain_inner(cx, ty, 0)\n    }\n\n    fn interior_mut_ty_chain_inner(\n        &mut self,\n        cx: &LateContext<'tcx>,\n        ty: Ty<'tcx>,\n        depth: usize,\n    ) -> Option<&'tcx ty::List<Ty<'tcx>>> {\n        if !cx.tcx.recursion_limit().value_within_limit(depth) {\n            return None;\n        }\n\n        match self.tys.entry(ty) {\n            Entry::Occupied(o) => return *o.get(),\n            // Temporarily insert a `None` to break cycles\n            Entry::Vacant(v) => v.insert(None),\n        };\n        let depth = depth + 1;\n\n        let chain = match *ty.kind() {\n            ty::RawPtr(inner_ty, _) if !self.ignore_pointers => self.interior_mut_ty_chain_inner(cx, inner_ty, depth),\n            ty::Ref(_, inner_ty, _) | ty::Slice(inner_ty) => self.interior_mut_ty_chain_inner(cx, inner_ty, depth),\n            ty::Array(inner_ty, size) if size.try_to_target_usize(cx.tcx) != Some(0) => {\n                self.interior_mut_ty_chain_inner(cx, inner_ty, depth)\n            },\n            ty::Tuple(fields) => fields\n                .iter()\n                .find_map(|ty| self.interior_mut_ty_chain_inner(cx, ty, depth)),\n            ty::Adt(def, _) if def.is_unsafe_cell() => Some(ty::List::empty()),\n            ty::Adt(def, args) => {\n                let is_std_collection = matches!(\n                    cx.tcx.get_diagnostic_name(def.did()),\n                    Some(\n                        sym::LinkedList\n                            | sym::Vec\n                            | sym::VecDeque\n                            | sym::BTreeMap\n                            | sym::BTreeSet\n                            | sym::HashMap\n                            | sym::HashSet\n                            | sym::Arc\n                            | sym::Rc\n                    )\n                );\n\n                if is_std_collection || def.is_box() {\n                    // Include the types from std collections that are behind pointers internally\n                    args.types()\n                        .find_map(|ty| self.interior_mut_ty_chain_inner(cx, ty, depth))\n                } else if self.ignored_def_ids.contains(&def.did()) || def.is_phantom_data() {\n                    None\n                } else {\n                    def.all_fields()\n                        .find_map(|f| self.interior_mut_ty_chain_inner(cx, f.ty(cx.tcx, args), depth))\n                }\n            },\n            ty::Alias(ty::Projection, _) => match cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty) {\n                Ok(normalized_ty) if ty != normalized_ty => self.interior_mut_ty_chain_inner(cx, normalized_ty, depth),\n                _ => None,\n            },\n            _ => None,\n        };\n\n        chain.map(|chain| {\n            let list = cx.tcx.mk_type_list_from_iter(chain.iter().chain([ty]));\n            self.tys.insert(ty, Some(list));\n            list\n        })\n    }\n\n    /// Check if given type has interior mutability such as [`std::cell::Cell`] or\n    /// [`std::cell::RefCell`] etc.\n    pub fn is_interior_mut_ty(&mut self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n        self.interior_mut_ty_chain(cx, ty).is_some()\n    }\n}\n\npub fn make_normalized_projection_with_regions<'tcx>(\n    tcx: TyCtxt<'tcx>,\n    typing_env: ty::TypingEnv<'tcx>,\n    container_id: DefId,\n    assoc_ty: Symbol,\n    args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>,\n) -> Option<Ty<'tcx>> {\n    fn helper<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> {\n        #[cfg(debug_assertions)]\n        if let Some((i, arg)) = ty\n            .args\n            .iter()\n            .enumerate()\n            .find(|(_, arg)| arg.has_escaping_bound_vars())\n        {\n            debug_assert!(\n                false,\n                \"args contain late-bound region at index `{i}` which can't be normalized.\\n\\\n                    use `TyCtxt::instantiate_bound_regions_with_erased`\\n\\\n                    note: arg is `{arg:#?}`\",\n            );\n            return None;\n        }\n        let cause = ObligationCause::dummy();\n        let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);\n        match infcx\n            .at(&cause, param_env)\n            .query_normalize(Ty::new_projection_from_args(tcx, ty.def_id, ty.args))\n        {\n            Ok(ty) => Some(ty.value),\n            Err(e) => {\n                debug_assert!(false, \"failed to normalize type `{ty}`: {e:#?}\");\n                None\n            },\n        }\n    }\n    helper(tcx, typing_env, make_projection(tcx, container_id, assoc_ty, args)?)\n}\n\npub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {\n    let cause = ObligationCause::dummy();\n    let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);\n    infcx\n        .at(&cause, param_env)\n        .query_normalize(ty)\n        .map_or(ty, |ty| ty.value)\n}\n\n/// Checks if the type is `core::mem::ManuallyDrop<_>`\npub fn is_manually_drop(ty: Ty<'_>) -> bool {\n    ty.ty_adt_def().is_some_and(AdtDef::is_manually_drop)\n}\n\n/// Returns the deref chain of a type, starting with the type itself.\npub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl Iterator<Item = Ty<'tcx>> + 'cx {\n    iter::successors(Some(ty), |&ty| {\n        if let Some(deref_did) = cx.tcx.lang_items().deref_trait()\n            && implements_trait(cx, ty, deref_did, &[])\n        {\n            make_normalized_projection(cx.tcx, cx.typing_env(), deref_did, sym::Target, [ty])\n        } else {\n            None\n        }\n    })\n}\n\n/// Checks if a Ty<'_> has some inherent method Symbol.\n///\n/// This does not look for impls in the type's `Deref::Target` type.\n/// If you need this, you should wrap this call in `clippy_utils::ty::deref_chain().any(...)`.\npub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> Option<&'a AssocItem> {\n    if let Some(ty_did) = ty.ty_adt_def().map(AdtDef::did) {\n        cx.tcx.inherent_impls(ty_did).iter().find_map(|&did| {\n            cx.tcx\n                .associated_items(did)\n                .filter_by_name_unhygienic(method_name)\n                .next()\n                .filter(|item| item.tag() == AssocTag::Fn)\n        })\n    } else {\n        None\n    }\n}\n\n/// Gets the type of a field by name.\npub fn get_field_by_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>> {\n    match *ty.kind() {\n        ty::Adt(def, args) if def.is_union() || def.is_struct() => def\n            .non_enum_variant()\n            .fields\n            .iter()\n            .find(|f| f.name == name)\n            .map(|f| f.ty(tcx, args)),\n        ty::Tuple(args) => name.as_str().parse::<usize>().ok().and_then(|i| args.get(i).copied()),\n        _ => None,\n    }\n}\n\npub fn get_field_def_id_by_name(ty: Ty<'_>, name: Symbol) -> Option<DefId> {\n    let ty::Adt(adt_def, ..) = ty.kind() else { return None };\n    adt_def\n        .all_fields()\n        .find_map(|field| if field.name == name { Some(field.did) } else { None })\n}\n\n/// Check if `ty` is an `Option` and return its argument type if it is.\npub fn option_arg_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {\n    match *ty.kind() {\n        ty::Adt(adt, args)\n            if let [arg] = &**args\n                && let Some(arg) = arg.as_type()\n                && adt.is_diag_item(cx, sym::Option) =>\n        {\n            Some(arg)\n        },\n        _ => None,\n    }\n}\n\n/// Check if a Ty<'_> of `Iterator` contains any mutable access to non-owning types by checking if\n/// it contains fields of mutable references or pointers, or references/pointers to non-`Freeze`\n/// types, or `PhantomData` types containing any of the previous. This can be used to check whether\n/// skipping iterating over an iterator will change its behavior.\npub fn has_non_owning_mutable_access<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>) -> bool {\n    fn normalize_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {\n        cx.tcx.try_normalize_erasing_regions(cx.typing_env(), ty).unwrap_or(ty)\n    }\n\n    /// Check if `ty` contains mutable references or equivalent, which includes:\n    /// - A mutable reference/pointer.\n    /// - A reference/pointer to a non-`Freeze` type.\n    /// - A `PhantomData` type containing any of the previous.\n    fn has_non_owning_mutable_access_inner<'tcx>(\n        cx: &LateContext<'tcx>,\n        phantoms: &mut FxHashSet<Ty<'tcx>>,\n        ty: Ty<'tcx>,\n    ) -> bool {\n        match ty.kind() {\n            ty::Adt(adt_def, args) if adt_def.is_phantom_data() => {\n                phantoms.insert(ty)\n                    && args\n                        .types()\n                        .any(|arg_ty| has_non_owning_mutable_access_inner(cx, phantoms, arg_ty))\n            },\n            ty::Adt(adt_def, args) => adt_def.all_fields().any(|field| {\n                has_non_owning_mutable_access_inner(cx, phantoms, normalize_ty(cx, field.ty(cx.tcx, args)))\n            }),\n            ty::Array(elem_ty, _) | ty::Slice(elem_ty) => has_non_owning_mutable_access_inner(cx, phantoms, *elem_ty),\n            ty::RawPtr(pointee_ty, mutability) | ty::Ref(_, pointee_ty, mutability) => {\n                mutability.is_mut() || !pointee_ty.is_freeze(cx.tcx, cx.typing_env())\n            },\n            ty::Closure(_, closure_args) => {\n                matches!(closure_args.types().next_back(),\n                         Some(captures) if has_non_owning_mutable_access_inner(cx, phantoms, captures))\n            },\n            ty::Tuple(tuple_args) => tuple_args\n                .iter()\n                .any(|arg_ty| has_non_owning_mutable_access_inner(cx, phantoms, arg_ty)),\n            _ => false,\n        }\n    }\n\n    let mut phantoms = FxHashSet::default();\n    has_non_owning_mutable_access_inner(cx, &mut phantoms, iter_ty)\n}\n\n/// Check if `ty` is slice-like, i.e., `&[T]`, `[T; N]`, or `Vec<T>`.\npub fn is_slice_like<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {\n    ty.is_slice() || ty.is_array() || ty.is_diag_item(cx, sym::Vec)\n}\n\npub fn get_field_idx_by_name(ty: Ty<'_>, name: Symbol) -> Option<usize> {\n    match *ty.kind() {\n        ty::Adt(def, _) if def.is_union() || def.is_struct() => {\n            def.non_enum_variant().fields.iter().position(|f| f.name == name)\n        },\n        ty::Tuple(_) => name.as_str().parse::<usize>().ok(),\n        _ => None,\n    }\n}\n\n/// Checks if the adjustments contain a mutable dereference of a `ManuallyDrop<_>`.\npub fn adjust_derefs_manually_drop<'tcx>(adjustments: &'tcx [Adjustment<'tcx>], mut ty: Ty<'tcx>) -> bool {\n    adjustments.iter().any(|a| {\n        let ty = mem::replace(&mut ty, a.target);\n        matches!(a.kind, Adjust::Deref(DerefAdjustKind::Overloaded(op)) if op.mutbl == Mutability::Mut)\n            && is_manually_drop(ty)\n    })\n}\n"
  },
  {
    "path": "clippy_utils/src/ty/type_certainty/certainty.rs",
    "content": "use rustc_hir::def_id::DefId;\nuse std::fmt::Debug;\n\n#[derive(Clone, Copy, Debug, PartialEq, Eq)]\npub enum Certainty {\n    /// Determining the type requires contextual information.\n    Uncertain,\n\n    /// The type can be determined purely from subexpressions. If the argument is `Some(..)`, the\n    /// specific `DefId` is known. Such arguments are needed to handle path segments whose `res` is\n    /// `Res::Err`.\n    Certain(Option<DefId>),\n\n    /// The heuristic believes that more than one `DefId` applies to a type---this is a bug.\n    Contradiction,\n}\n\npub trait Meet {\n    fn meet(self, other: Self) -> Self;\n}\n\npub trait TryJoin: Sized {\n    fn try_join(self, other: Self) -> Option<Self>;\n}\n\nimpl Meet for Option<DefId> {\n    fn meet(self, other: Self) -> Self {\n        match (self, other) {\n            (None, _) | (_, None) => None,\n            (Some(lhs), Some(rhs)) => (lhs == rhs).then_some(lhs),\n        }\n    }\n}\n\nimpl TryJoin for Option<DefId> {\n    fn try_join(self, other: Self) -> Option<Self> {\n        match (self, other) {\n            (Some(lhs), Some(rhs)) => (lhs == rhs).then_some(Some(lhs)),\n            (Some(def_id), _) | (_, Some(def_id)) => Some(Some(def_id)),\n            (None, None) => Some(None),\n        }\n    }\n}\n\nimpl Meet for Certainty {\n    fn meet(self, other: Self) -> Self {\n        match (self, other) {\n            (Certainty::Uncertain, _) | (_, Certainty::Uncertain) => Certainty::Uncertain,\n            (Certainty::Certain(lhs), Certainty::Certain(rhs)) => Certainty::Certain(lhs.meet(rhs)),\n            (Certainty::Certain(inner), _) | (_, Certainty::Certain(inner)) => Certainty::Certain(inner),\n            (Certainty::Contradiction, Certainty::Contradiction) => Certainty::Contradiction,\n        }\n    }\n}\n\nimpl Certainty {\n    /// Join two `Certainty`s preserving their `DefId`s (if any). Generally speaking, this method\n    /// should be used only when `self` and `other` refer directly to types. Otherwise,\n    /// `join_clearing_def_ids` should be used.\n    pub fn join(self, other: Self) -> Self {\n        match (self, other) {\n            (Certainty::Contradiction, _) | (_, Certainty::Contradiction) => Certainty::Contradiction,\n\n            (Certainty::Certain(lhs), Certainty::Certain(rhs)) => {\n                if let Some(inner) = lhs.try_join(rhs) {\n                    Certainty::Certain(inner)\n                } else {\n                    debug_assert!(false, \"Contradiction with {lhs:?} and {rhs:?}\");\n                    Certainty::Contradiction\n                }\n            },\n\n            (Certainty::Certain(inner), _) | (_, Certainty::Certain(inner)) => Certainty::Certain(inner),\n\n            (Certainty::Uncertain, Certainty::Uncertain) => Certainty::Uncertain,\n        }\n    }\n\n    /// Join two `Certainty`s after clearing their `DefId`s. This method should be used when `self`\n    /// or `other` do not necessarily refer to types, e.g., when they are aggregations of other\n    /// `Certainty`s.\n    pub fn join_clearing_def_ids(self, other: Self) -> Self {\n        self.clear_def_id().join(other.clear_def_id())\n    }\n\n    pub fn clear_def_id(self) -> Certainty {\n        if matches!(self, Certainty::Certain(_)) {\n            Certainty::Certain(None)\n        } else {\n            self\n        }\n    }\n\n    pub fn with_def_id(self, def_id: DefId) -> Certainty {\n        if matches!(self, Certainty::Certain(_)) {\n            Certainty::Certain(Some(def_id))\n        } else {\n            self\n        }\n    }\n\n    pub fn to_def_id(self) -> Option<DefId> {\n        match self {\n            Certainty::Certain(inner) => inner,\n            _ => None,\n        }\n    }\n\n    pub fn is_certain(self) -> bool {\n        matches!(self, Self::Certain(_))\n    }\n}\n\n/// Think: `iter.all(/* is certain */)`\npub fn meet(iter: impl Iterator<Item = Certainty>) -> Certainty {\n    iter.fold(Certainty::Certain(None), Certainty::meet)\n}\n\n/// Think: `iter.any(/* is certain */)`\npub fn join(iter: impl Iterator<Item = Certainty>) -> Certainty {\n    iter.fold(Certainty::Uncertain, Certainty::join)\n}\n"
  },
  {
    "path": "clippy_utils/src/ty/type_certainty/mod.rs",
    "content": "//! A heuristic to tell whether an expression's type can be determined purely from its\n//! subexpressions, and the arguments and locals they use. Put another way, `expr_type_is_certain`\n//! tries to tell whether an expression's type can be determined without appeal to the surrounding\n//! context.\n//!\n//! This is, in some sense, a counterpart to `let_unit_value`'s `expr_needs_inferred_result`.\n//! Intuitively, that function determines whether an expression's type is needed for type inference,\n//! whereas `expr_type_is_certain` determines whether type inference is needed for an expression's\n//! type.\n//!\n//! As a heuristic, `expr_type_is_certain` may produce false negatives, but a false positive should\n//! be considered a bug.\n\nuse crate::paths::{PathNS, lookup_path};\nuse rustc_ast::{LitFloatType, LitIntType, LitKind};\nuse rustc_hir::def::{DefKind, Res};\nuse rustc_hir::def_id::DefId;\nuse rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_qpath, walk_ty};\nuse rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, GenericArgs, HirId, Node, Param, PathSegment, QPath, TyKind};\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{self, AdtDef, GenericArgKind, Ty};\nuse rustc_span::Span;\n\nmod certainty;\nuse certainty::{Certainty, Meet, join, meet};\n\npub fn expr_type_is_certain(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    expr_type_certainty(cx, expr, false).is_certain()\n}\n\n/// Determine the type certainty of `expr`. `in_arg` indicates that the expression happens within\n/// the evaluation of a function or method call argument.\nfn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>, in_arg: bool) -> Certainty {\n    let certainty = match &expr.kind {\n        ExprKind::Unary(_, expr)\n        | ExprKind::Field(expr, _)\n        | ExprKind::Index(expr, _, _)\n        | ExprKind::AddrOf(_, _, expr) => expr_type_certainty(cx, expr, in_arg),\n\n        ExprKind::Array(exprs) => join(exprs.iter().map(|expr| expr_type_certainty(cx, expr, in_arg))),\n\n        ExprKind::Call(callee, args) => {\n            let lhs = expr_type_certainty(cx, callee, false);\n            let rhs = if type_is_inferable_from_arguments(cx, expr) {\n                meet(args.iter().map(|arg| expr_type_certainty(cx, arg, true)))\n            } else {\n                Certainty::Uncertain\n            };\n            lhs.join_clearing_def_ids(rhs)\n        },\n\n        ExprKind::MethodCall(method, receiver, args, _) => {\n            let mut receiver_type_certainty = expr_type_certainty(cx, receiver, false);\n            // Even if `receiver_type_certainty` is `Certain(Some(..))`, the `Self` type in the method\n            // identified by `type_dependent_def_id(..)` can differ. This can happen as a result of a `deref`,\n            // for example. So update the `DefId` in `receiver_type_certainty` (if any).\n            if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)\n                && let Some(self_ty_def_id) = adt_def_id(self_ty(cx, method_def_id))\n            {\n                receiver_type_certainty = receiver_type_certainty.with_def_id(self_ty_def_id);\n            }\n            let lhs = path_segment_certainty(cx, receiver_type_certainty, method, false);\n            let rhs = if type_is_inferable_from_arguments(cx, expr) {\n                meet(\n                    std::iter::once(receiver_type_certainty)\n                        .chain(args.iter().map(|arg| expr_type_certainty(cx, arg, true))),\n                )\n            } else {\n                Certainty::Uncertain\n            };\n            lhs.join(rhs)\n        },\n\n        ExprKind::Tup(exprs) => meet(exprs.iter().map(|expr| expr_type_certainty(cx, expr, in_arg))),\n\n        ExprKind::Binary(_, lhs, rhs) => {\n            // If one of the side of the expression is uncertain, the certainty will come from the other side,\n            // with no information on the type.\n            match (\n                expr_type_certainty(cx, lhs, in_arg),\n                expr_type_certainty(cx, rhs, in_arg),\n            ) {\n                (Certainty::Uncertain, Certainty::Certain(_)) | (Certainty::Certain(_), Certainty::Uncertain) => {\n                    Certainty::Certain(None)\n                },\n                (l, r) => l.meet(r),\n            }\n        },\n\n        ExprKind::Lit(lit) => {\n            if !in_arg\n                && matches!(\n                    lit.node,\n                    LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed)\n                )\n            {\n                Certainty::Uncertain\n            } else {\n                Certainty::Certain(None)\n            }\n        },\n\n        ExprKind::Cast(_, ty) => type_certainty(cx, ty),\n\n        ExprKind::If(_, if_expr, Some(else_expr)) => {\n            expr_type_certainty(cx, if_expr, in_arg).join(expr_type_certainty(cx, else_expr, in_arg))\n        },\n\n        ExprKind::Path(qpath) => qpath_certainty(cx, qpath, false),\n\n        ExprKind::Struct(qpath, _, _) => qpath_certainty(cx, qpath, true),\n\n        _ => Certainty::Uncertain,\n    };\n\n    let expr_ty = cx.typeck_results().expr_ty(expr);\n    if let Some(def_id) = adt_def_id(expr_ty) {\n        certainty.with_def_id(def_id)\n    } else {\n        certainty.clear_def_id()\n    }\n}\n\nstruct CertaintyVisitor<'cx, 'tcx> {\n    cx: &'cx LateContext<'tcx>,\n    certainty: Certainty,\n}\n\nimpl<'cx, 'tcx> CertaintyVisitor<'cx, 'tcx> {\n    fn new(cx: &'cx LateContext<'tcx>) -> Self {\n        Self {\n            cx,\n            certainty: Certainty::Certain(None),\n        }\n    }\n}\n\nimpl<'cx> Visitor<'cx> for CertaintyVisitor<'cx, '_> {\n    fn visit_qpath(&mut self, qpath: &'cx QPath<'_>, hir_id: HirId, _: Span) {\n        self.certainty = self.certainty.meet(qpath_certainty(self.cx, qpath, true));\n        if self.certainty != Certainty::Uncertain {\n            walk_qpath(self, qpath, hir_id);\n        }\n    }\n\n    fn visit_ty(&mut self, ty: &'cx hir::Ty<'_, AmbigArg>) {\n        if self.certainty != Certainty::Uncertain {\n            walk_ty(self, ty);\n        }\n    }\n\n    fn visit_infer(&mut self, _inf_id: HirId, _inf_span: Span, _kind: InferKind<'cx>) -> Self::Result {\n        self.certainty = Certainty::Uncertain;\n    }\n}\n\nfn type_certainty(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Certainty {\n    // Handle `TyKind::Path` specially so that its `DefId` can be preserved.\n    //\n    // Note that `CertaintyVisitor::new` initializes the visitor's internal certainty to\n    // `Certainty::Certain(None)`. Furthermore, if a `TyKind::Path` is encountered while traversing\n    // `ty`, the result of the call to `qpath_certainty` is combined with the visitor's internal\n    // certainty using `Certainty::meet`. Thus, if the `TyKind::Path` were not treated specially here,\n    // the resulting certainty would be `Certainty::Certain(None)`.\n    if let TyKind::Path(qpath) = &ty.kind {\n        return qpath_certainty(cx, qpath, true);\n    }\n\n    let mut visitor = CertaintyVisitor::new(cx);\n    visitor.visit_ty_unambig(ty);\n    visitor.certainty\n}\n\nfn generic_args_certainty(cx: &LateContext<'_>, args: &GenericArgs<'_>) -> Certainty {\n    let mut visitor = CertaintyVisitor::new(cx);\n    visitor.visit_generic_args(args);\n    visitor.certainty\n}\n\n/// Tries to tell whether a `QPath` resolves to something certain, e.g., whether all of its path\n/// segments generic arguments are instantiated.\n///\n/// `qpath` could refer to either a type or a value. The heuristic never needs the `DefId` of a\n/// value. So `DefId`s are retained only when `resolves_to_type` is true.\nfn qpath_certainty(cx: &LateContext<'_>, qpath: &QPath<'_>, resolves_to_type: bool) -> Certainty {\n    let certainty = match qpath {\n        QPath::Resolved(ty, path) => {\n            let len = path.segments.len();\n            path.segments.iter().enumerate().fold(\n                ty.map_or(Certainty::Uncertain, |ty| type_certainty(cx, ty)),\n                |parent_certainty, (i, path_segment)| {\n                    path_segment_certainty(cx, parent_certainty, path_segment, i != len - 1 || resolves_to_type)\n                },\n            )\n        },\n\n        QPath::TypeRelative(ty, path_segment) => {\n            path_segment_certainty(cx, type_certainty(cx, ty), path_segment, resolves_to_type)\n        },\n    };\n    debug_assert!(resolves_to_type || certainty.to_def_id().is_none());\n    certainty\n}\n\n/// Tries to tell whether `param` resolves to something certain, e.g., a non-wildcard type if\n/// present. The certainty `DefId` is cleared before returning.\nfn param_certainty(cx: &LateContext<'_>, param: &Param<'_>) -> Certainty {\n    let owner_did = cx.tcx.hir_enclosing_body_owner(param.hir_id);\n    let Some(fn_decl) = cx.tcx.hir_fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(owner_did)) else {\n        return Certainty::Uncertain;\n    };\n    let inputs = fn_decl.inputs;\n    let body_params = cx.tcx.hir_body_owned_by(owner_did).params;\n    std::iter::zip(body_params, inputs)\n        .find(|(p, _)| p.hir_id == param.hir_id)\n        .map_or(Certainty::Uncertain, |(_, ty)| type_certainty(cx, ty).clear_def_id())\n}\n\nfn path_segment_certainty(\n    cx: &LateContext<'_>,\n    parent_certainty: Certainty,\n    path_segment: &PathSegment<'_>,\n    resolves_to_type: bool,\n) -> Certainty {\n    let certainty = match update_res(cx, parent_certainty, path_segment, resolves_to_type).unwrap_or(path_segment.res) {\n        // A definition's type is certain if it refers to something without generics (e.g., a crate or module, or\n        // an unparameterized type), or the generics are instantiated with arguments that are certain.\n        //\n        // If the parent is uncertain, then the current path segment must account for the parent's generic arguments.\n        // Consider the following examples, where the current path segment is `None`:\n        // - `Option::None`             // uncertain; parent (i.e., `Option`) is uncertain\n        // - `Option::<Vec<u64>>::None` // certain; parent (i.e., `Option::<..>`) is certain\n        // - `Option::None::<Vec<u64>>` // certain; parent (i.e., `Option`) is uncertain\n        Res::Def(_, def_id) => {\n            // Checking `res_generics_def_id(..)` before calling `generics_of` avoids an ICE.\n            if cx.tcx.res_generics_def_id(path_segment.res).is_some() {\n                let generics = cx.tcx.generics_of(def_id);\n\n                let own_count = generics.own_params.len();\n                let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && own_count == 0 {\n                    Certainty::Certain(None)\n                } else {\n                    Certainty::Uncertain\n                };\n                let rhs = path_segment\n                    .args\n                    .map_or(Certainty::Uncertain, |args| generic_args_certainty(cx, args));\n                // See the comment preceding `qpath_certainty`. `def_id` could refer to a type or a value.\n                let certainty = lhs.join_clearing_def_ids(rhs);\n                if resolves_to_type {\n                    if let DefKind::TyAlias = cx.tcx.def_kind(def_id) {\n                        adt_def_id(cx.tcx.type_of(def_id).instantiate_identity())\n                            .map_or(certainty, |def_id| certainty.with_def_id(def_id))\n                    } else {\n                        certainty.with_def_id(def_id)\n                    }\n                } else {\n                    certainty\n                }\n            } else {\n                Certainty::Certain(None)\n            }\n        },\n\n        Res::PrimTy(_) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::SelfCtor(_) => {\n            Certainty::Certain(None)\n        },\n\n        // `get_parent` because `hir_id` refers to a `Pat`, and we're interested in the node containing the `Pat`.\n        Res::Local(hir_id) => match cx.tcx.parent_hir_node(hir_id) {\n            // A parameter's type is not always certain, as it may come from an untyped closure definition,\n            // or from a wildcard in a typed closure definition.\n            Node::Param(param) => param_certainty(cx, param),\n            // A local's type is certain if its type annotation is certain or it has an initializer whose\n            // type is certain.\n            Node::LetStmt(local) => {\n                let lhs = local.ty.map_or(Certainty::Uncertain, |ty| type_certainty(cx, ty));\n                let rhs = local\n                    .init\n                    .map_or(Certainty::Uncertain, |init| expr_type_certainty(cx, init, false));\n                let certainty = lhs.join(rhs);\n                if resolves_to_type {\n                    certainty\n                } else {\n                    certainty.clear_def_id()\n                }\n            },\n            _ => Certainty::Uncertain,\n        },\n\n        _ => Certainty::Uncertain,\n    };\n    debug_assert!(resolves_to_type || certainty.to_def_id().is_none());\n    certainty\n}\n\n/// For at least some `QPath::TypeRelative`, the path segment's `res` can be `Res::Err`.\n/// `update_res` tries to fix the resolution when `parent_certainty` is `Certain(Some(..))`.\nfn update_res(\n    cx: &LateContext<'_>,\n    parent_certainty: Certainty,\n    path_segment: &PathSegment<'_>,\n    resolves_to_type: bool,\n) -> Option<Res> {\n    if path_segment.res == Res::Err\n        && let Some(def_id) = parent_certainty.to_def_id()\n    {\n        let mut def_path = cx.get_def_path(def_id);\n        def_path.push(path_segment.ident.name);\n        let ns = if resolves_to_type { PathNS::Type } else { PathNS::Value };\n        if let &[id] = lookup_path(cx.tcx, ns, &def_path).as_slice() {\n            return Some(Res::Def(cx.tcx.def_kind(id), id));\n        }\n    }\n\n    None\n}\n\n#[expect(clippy::cast_possible_truncation)]\nfn type_is_inferable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    let Some(callee_def_id) = (match expr.kind {\n        ExprKind::Call(callee, _) => {\n            let callee_ty = cx.typeck_results().expr_ty(callee);\n            if let ty::FnDef(callee_def_id, _) = callee_ty.kind() {\n                Some(*callee_def_id)\n            } else {\n                None\n            }\n        },\n        ExprKind::MethodCall(_, _, _, _) => cx.typeck_results().type_dependent_def_id(expr.hir_id),\n        _ => None,\n    }) else {\n        return false;\n    };\n\n    let generics = cx.tcx.generics_of(callee_def_id);\n    let fn_sig = cx.tcx.fn_sig(callee_def_id).skip_binder();\n\n    // Check that all type parameters appear in the functions input types.\n    (0..(generics.parent_count + generics.own_params.len()) as u32).all(|index| {\n        fn_sig\n            .inputs()\n            .iter()\n            .any(|input_ty| contains_param(*input_ty.skip_binder(), index))\n    })\n}\n\nfn self_ty<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId) -> Ty<'tcx> {\n    cx.tcx.fn_sig(method_def_id).skip_binder().inputs().skip_binder()[0]\n}\n\nfn adt_def_id(ty: Ty<'_>) -> Option<DefId> {\n    ty.peel_refs().ty_adt_def().map(AdtDef::did)\n}\n\nfn contains_param(ty: Ty<'_>, index: u32) -> bool {\n    ty.walk()\n        .any(|arg| matches!(arg.kind(), GenericArgKind::Type(ty) if ty.is_param(index)))\n}\n"
  },
  {
    "path": "clippy_utils/src/usage.rs",
    "content": "use crate::macros::root_macro_call_first_node;\nuse crate::res::MaybeResPath;\nuse crate::visitors::{Descend, Visitable, for_each_expr, for_each_expr_without_closures};\nuse crate::{self as utils, get_enclosing_loop_or_multi_call_closure, sym};\nuse core::ops::ControlFlow;\nuse hir::def::Res;\nuse rustc_hir::intravisit::{self, Visitor};\nuse rustc_hir::{self as hir, Expr, ExprKind, HirId, HirIdSet};\nuse rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, Place, PlaceBase, PlaceWithHirId};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::mir::FakeReadCause;\nuse rustc_middle::ty;\n\n/// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined.\npub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> Option<HirIdSet> {\n    let mut delegate = MutVarsDelegate {\n        used_mutably: HirIdSet::default(),\n        skip: false,\n    };\n    ExprUseVisitor::for_clippy(cx, expr.hir_id.owner.def_id, &mut delegate)\n        .walk_expr(expr)\n        .into_ok();\n\n    if delegate.skip {\n        return None;\n    }\n    Some(delegate.used_mutably)\n}\n\npub fn is_potentially_mutated<'tcx>(variable: HirId, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool {\n    mutated_variables(expr, cx).is_none_or(|mutated| mutated.contains(&variable))\n}\n\npub fn is_potentially_local_place(local_id: HirId, place: &Place<'_>) -> bool {\n    match place.base {\n        PlaceBase::Local(id) => id == local_id,\n        PlaceBase::Upvar(_) => {\n            // Conservatively assume yes.\n            true\n        },\n        _ => false,\n    }\n}\n\nstruct MutVarsDelegate {\n    used_mutably: HirIdSet,\n    skip: bool,\n}\n\nimpl MutVarsDelegate {\n    fn update(&mut self, cat: &PlaceWithHirId<'_>) {\n        match cat.place.base {\n            PlaceBase::Local(id) => {\n                self.used_mutably.insert(id);\n            },\n            PlaceBase::Upvar(_) => {\n                //FIXME: This causes false negatives. We can't get the `NodeId` from\n                //`Categorization::Upvar(_)`. So we search for any `Upvar`s in the\n                //`while`-body, not just the ones in the condition.\n                self.skip = true;\n            },\n            _ => {},\n        }\n    }\n}\n\nimpl<'tcx> Delegate<'tcx> for MutVarsDelegate {\n    fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}\n\n    fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind) {\n        if bk == ty::BorrowKind::Mutable {\n            self.update(cmt);\n        }\n    }\n\n    fn mutate(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {\n        self.update(cmt);\n    }\n\n    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}\n}\n\npub struct ParamBindingIdCollector {\n    pub binding_hir_ids: Vec<HirId>,\n}\nimpl<'tcx> ParamBindingIdCollector {\n    fn collect_binding_hir_ids(body: &'tcx hir::Body<'tcx>) -> Vec<HirId> {\n        let mut hir_ids: Vec<HirId> = Vec::new();\n        for param in body.params {\n            let mut finder = ParamBindingIdCollector {\n                binding_hir_ids: Vec::new(),\n            };\n            finder.visit_param(param);\n            for hir_id in &finder.binding_hir_ids {\n                hir_ids.push(*hir_id);\n            }\n        }\n        hir_ids\n    }\n}\nimpl<'tcx> Visitor<'tcx> for ParamBindingIdCollector {\n    fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {\n        if let hir::PatKind::Binding(_, hir_id, ..) = pat.kind {\n            self.binding_hir_ids.push(hir_id);\n        }\n        intravisit::walk_pat(self, pat);\n    }\n}\n\npub struct BindingUsageFinder<'a, 'tcx> {\n    cx: &'a LateContext<'tcx>,\n    binding_ids: Vec<HirId>,\n}\nimpl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {\n    pub fn are_params_used(cx: &'a LateContext<'tcx>, body: &'tcx hir::Body<'tcx>) -> bool {\n        let mut finder = BindingUsageFinder {\n            cx,\n            binding_ids: ParamBindingIdCollector::collect_binding_hir_ids(body),\n        };\n        finder.visit_body(body).is_break()\n    }\n}\nimpl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> {\n    type Result = ControlFlow<()>;\n    type NestedFilter = nested_filter::OnlyBodies;\n\n    fn visit_path(&mut self, path: &hir::Path<'tcx>, _: HirId) -> Self::Result {\n        if let Res::Local(id) = path.res\n            && self.binding_ids.contains(&id)\n        {\n            return ControlFlow::Break(());\n        }\n\n        ControlFlow::Continue(())\n    }\n\n    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n        self.cx.tcx\n    }\n}\n\n/// Checks if the given expression is a macro call to `todo!()` or `unimplemented!()`.\npub fn is_todo_unimplemented_macro(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    root_macro_call_first_node(cx, expr)\n        .and_then(|macro_call| cx.tcx.get_diagnostic_name(macro_call.def_id))\n        .is_some_and(|macro_name| matches!(macro_name, sym::todo_macro | sym::unimplemented_macro))\n}\n\n/// Checks if the given expression is a stub, i.e., a `todo!()` or `unimplemented!()` expression,\n/// or a block whose last expression is a `todo!()` or `unimplemented!()`.\npub fn is_todo_unimplemented_stub(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {\n    if let ExprKind::Block(block, _) = expr.kind {\n        if let Some(last_expr) = block.expr {\n            return is_todo_unimplemented_macro(cx, last_expr);\n        }\n\n        return block.stmts.last().is_some_and(|stmt| {\n            if let hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) = stmt.kind {\n                return is_todo_unimplemented_macro(cx, expr);\n            }\n            false\n        });\n    }\n\n    is_todo_unimplemented_macro(cx, expr)\n}\n\n/// Checks if the given expression contains macro call to `todo!()` or `unimplemented!()`.\npub fn contains_todo_unimplement_macro(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {\n    for_each_expr_without_closures(expr, |e| {\n        if is_todo_unimplemented_macro(cx, e) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\npub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool {\n    for_each_expr_without_closures(expression, |e| {\n        match e.kind {\n            ExprKind::Ret(..) | ExprKind::Break(..) | ExprKind::Continue(..) => ControlFlow::Break(()),\n            // Something special could be done here to handle while or for loop\n            // desugaring, as this will detect a break if there's a while loop\n            // or a for loop inside the expression.\n            _ if e.span.from_expansion() => ControlFlow::Break(()),\n            _ => ControlFlow::Continue(()),\n        }\n    })\n    .is_some()\n}\n\npub fn local_used_in<'tcx>(cx: &LateContext<'tcx>, local_id: HirId, v: impl Visitable<'tcx>) -> bool {\n    for_each_expr(cx, v, |e| {\n        if e.res_local_id() == Some(local_id) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\npub fn local_used_after_expr(cx: &LateContext<'_>, local_id: HirId, after: &Expr<'_>) -> bool {\n    let Some(block) = utils::get_enclosing_block(cx, local_id) else {\n        return false;\n    };\n\n    // for _ in 1..3 {\n    //    local\n    // }\n    //\n    // let closure = || local;\n    // closure();\n    // closure();\n    let loop_start = get_enclosing_loop_or_multi_call_closure(cx, after).map(|e| e.hir_id);\n\n    let mut past_expr = false;\n    for_each_expr(cx, block, |e| {\n        if past_expr {\n            if e.res_local_id() == Some(local_id) {\n                ControlFlow::Break(())\n            } else {\n                ControlFlow::Continue(Descend::Yes)\n            }\n        } else if e.hir_id == after.hir_id {\n            past_expr = true;\n            ControlFlow::Continue(Descend::No)\n        } else {\n            past_expr = Some(e.hir_id) == loop_start;\n            ControlFlow::Continue(Descend::Yes)\n        }\n    })\n    .is_some()\n}\n"
  },
  {
    "path": "clippy_utils/src/visitors.rs",
    "content": "use crate::get_enclosing_block;\nuse crate::msrvs::Msrv;\nuse crate::qualify_min_const_fn::is_stable_const_fn;\nuse crate::res::MaybeResPath;\nuse crate::ty::needs_ordered_drop;\nuse core::ops::ControlFlow;\nuse rustc_ast::visit::{VisitorResult, try_visit};\nuse rustc_hir::def::{CtorKind, DefKind, Res};\nuse rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr};\nuse rustc_hir::{\n    self as hir, AmbigArg, AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId,\n    ItemKind, LetExpr, Pat, QPath, Stmt, StructTailExpr, UnOp, UnsafeSource,\n};\nuse rustc_lint::LateContext;\nuse rustc_middle::hir::nested_filter;\nuse rustc_middle::ty::adjustment::Adjust;\nuse rustc_middle::ty::{self, Ty, TyCtxt, TypeckResults};\nuse rustc_span::Span;\n\nmod internal {\n    /// Trait for visitor functions to control whether or not to descend to child nodes. Implemented\n    /// for only two types. `()` always descends. `Descend` allows controlled descent.\n    pub trait Continue {\n        fn descend(&self) -> bool;\n    }\n}\nuse internal::Continue;\n\nimpl Continue for () {\n    fn descend(&self) -> bool {\n        true\n    }\n}\n\n/// Allows for controlled descent when using visitor functions. Use `()` instead when always\n/// descending into child nodes.\n#[derive(Clone, Copy)]\npub enum Descend {\n    Yes,\n    No,\n}\nimpl From<bool> for Descend {\n    fn from(from: bool) -> Self {\n        if from { Self::Yes } else { Self::No }\n    }\n}\nimpl Continue for Descend {\n    fn descend(&self) -> bool {\n        matches!(self, Self::Yes)\n    }\n}\n\n/// A type which can be visited.\npub trait Visitable<'tcx> {\n    /// Calls the corresponding `visit_*` function on the visitor.\n    fn visit<V: Visitor<'tcx>>(self, visitor: &mut V) -> V::Result;\n}\nimpl<'tcx, T> Visitable<'tcx> for &'tcx [T]\nwhere\n    &'tcx T: Visitable<'tcx>,\n{\n    fn visit<V: Visitor<'tcx>>(self, visitor: &mut V) -> V::Result {\n        for x in self {\n            try_visit!(x.visit(visitor));\n        }\n        V::Result::output()\n    }\n}\nimpl<'tcx, A, B> Visitable<'tcx> for (A, B)\nwhere\n    A: Visitable<'tcx>,\n    B: Visitable<'tcx>,\n{\n    fn visit<V: Visitor<'tcx>>(self, visitor: &mut V) -> V::Result {\n        let (a, b) = self;\n        try_visit!(a.visit(visitor));\n        b.visit(visitor)\n    }\n}\nimpl<'tcx, T> Visitable<'tcx> for Option<T>\nwhere\n    T: Visitable<'tcx>,\n{\n    fn visit<V: Visitor<'tcx>>(self, visitor: &mut V) -> V::Result {\n        if let Some(x) = self {\n            try_visit!(x.visit(visitor));\n        }\n        V::Result::output()\n    }\n}\nmacro_rules! visitable_ref {\n    ($t:ident, $f:ident) => {\n        impl<'tcx> Visitable<'tcx> for &'tcx $t<'tcx> {\n            fn visit<V: Visitor<'tcx>>(self, visitor: &mut V) -> V::Result {\n                visitor.$f(self)\n            }\n        }\n    };\n}\nvisitable_ref!(Arm, visit_arm);\nvisitable_ref!(Block, visit_block);\nvisitable_ref!(Body, visit_body);\nvisitable_ref!(Expr, visit_expr);\nvisitable_ref!(Stmt, visit_stmt);\n\n/// Calls the given function once for each expression contained. This does not enter any bodies or\n/// nested items.\npub fn for_each_expr_without_closures<'tcx, B, C: Continue>(\n    node: impl Visitable<'tcx>,\n    f: impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B, C>,\n) -> Option<B> {\n    struct V<F> {\n        f: F,\n    }\n    impl<'tcx, B, C: Continue, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B, C>> Visitor<'tcx> for V<F> {\n        type Result = ControlFlow<B>;\n\n        fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) -> Self::Result {\n            match (self.f)(e) {\n                ControlFlow::Continue(c) if c.descend() => walk_expr(self, e),\n                ControlFlow::Break(b) => ControlFlow::Break(b),\n                ControlFlow::Continue(_) => ControlFlow::Continue(()),\n            }\n        }\n\n        // Avoid unnecessary `walk_*` calls.\n        fn visit_ty(&mut self, _: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n        fn visit_pat(&mut self, _: &'tcx Pat<'tcx>) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n        fn visit_qpath(&mut self, _: &'tcx QPath<'tcx>, _: HirId, _: Span) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n        // Avoid monomorphising all `visit_*` functions.\n        fn visit_nested_item(&mut self, _: ItemId) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n    }\n    let mut v = V { f };\n    node.visit(&mut v).break_value()\n}\n\n/// Calls the given function once for each expression contained. This will enter bodies, but not\n/// nested items.\npub fn for_each_expr<'tcx, B, C: Continue>(\n    cx: &LateContext<'tcx>,\n    node: impl Visitable<'tcx>,\n    f: impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B, C>,\n) -> Option<B> {\n    struct V<'tcx, F> {\n        tcx: TyCtxt<'tcx>,\n        f: F,\n    }\n    impl<'tcx, B, C: Continue, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B, C>> Visitor<'tcx> for V<'tcx, F> {\n        type NestedFilter = nested_filter::OnlyBodies;\n        type Result = ControlFlow<B>;\n\n        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n            self.tcx\n        }\n\n        fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) -> Self::Result {\n            match (self.f)(e) {\n                ControlFlow::Continue(c) if c.descend() => walk_expr(self, e),\n                ControlFlow::Break(b) => ControlFlow::Break(b),\n                ControlFlow::Continue(_) => ControlFlow::Continue(()),\n            }\n        }\n\n        // Only walk closures\n        fn visit_anon_const(&mut self, _: &'tcx AnonConst) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n        // Avoid unnecessary `walk_*` calls.\n        fn visit_ty(&mut self, _: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n        fn visit_pat(&mut self, _: &'tcx Pat<'tcx>) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n        fn visit_qpath(&mut self, _: &'tcx QPath<'tcx>, _: HirId, _: Span) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n        // Avoid monomorphising all `visit_*` functions.\n        fn visit_nested_item(&mut self, _: ItemId) -> Self::Result {\n            ControlFlow::Continue(())\n        }\n    }\n    let mut v = V { tcx: cx.tcx, f };\n    node.visit(&mut v).break_value()\n}\n\n/// returns `true` if expr contains match expr desugared from try\nfn contains_try(expr: &Expr<'_>) -> bool {\n    for_each_expr_without_closures(expr, |e| {\n        if matches!(e.kind, ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\npub fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir Expr<'hir>, callback: F) -> bool\nwhere\n    F: FnMut(&'hir Expr<'hir>) -> bool,\n{\n    struct RetFinder<F> {\n        in_stmt: bool,\n        failed: bool,\n        cb: F,\n    }\n\n    struct WithStmtGuard<'a, F> {\n        val: &'a mut RetFinder<F>,\n        prev_in_stmt: bool,\n    }\n\n    impl<F> RetFinder<F> {\n        fn inside_stmt(&mut self, in_stmt: bool) -> WithStmtGuard<'_, F> {\n            let prev_in_stmt = std::mem::replace(&mut self.in_stmt, in_stmt);\n            WithStmtGuard {\n                val: self,\n                prev_in_stmt,\n            }\n        }\n    }\n\n    impl<F> std::ops::Deref for WithStmtGuard<'_, F> {\n        type Target = RetFinder<F>;\n\n        fn deref(&self) -> &Self::Target {\n            self.val\n        }\n    }\n\n    impl<F> std::ops::DerefMut for WithStmtGuard<'_, F> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            self.val\n        }\n    }\n\n    impl<F> Drop for WithStmtGuard<'_, F> {\n        fn drop(&mut self) {\n            self.val.in_stmt = self.prev_in_stmt;\n        }\n    }\n\n    impl<'hir, F: FnMut(&'hir Expr<'hir>) -> bool> Visitor<'hir> for RetFinder<F> {\n        fn visit_stmt(&mut self, stmt: &'hir Stmt<'_>) {\n            intravisit::walk_stmt(&mut *self.inside_stmt(true), stmt);\n        }\n\n        fn visit_expr(&mut self, expr: &'hir Expr<'_>) {\n            if self.failed {\n                return;\n            }\n            if self.in_stmt {\n                match expr.kind {\n                    ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr),\n                    _ => walk_expr(self, expr),\n                }\n            } else {\n                match expr.kind {\n                    ExprKind::If(cond, then, else_opt) => {\n                        self.inside_stmt(true).visit_expr(cond);\n                        self.visit_expr(then);\n                        if let Some(el) = else_opt {\n                            self.visit_expr(el);\n                        }\n                    },\n                    ExprKind::Match(cond, arms, _) => {\n                        self.inside_stmt(true).visit_expr(cond);\n                        for arm in arms {\n                            self.visit_expr(arm.body);\n                        }\n                    },\n                    ExprKind::Block(..) => walk_expr(self, expr),\n                    ExprKind::Ret(Some(expr)) => self.visit_expr(expr),\n                    _ => self.failed |= !(self.cb)(expr),\n                }\n            }\n        }\n    }\n\n    !contains_try(expr) && {\n        let mut ret_finder = RetFinder {\n            in_stmt: false,\n            failed: false,\n            cb: callback,\n        };\n        ret_finder.visit_expr(expr);\n        !ret_finder.failed\n    }\n}\n\n/// Checks if the given resolved path is used in the given body.\npub fn is_res_used(cx: &LateContext<'_>, res: Res, body: BodyId) -> bool {\n    for_each_expr(cx, cx.tcx.hir_body(body).value, |e| {\n        if let ExprKind::Path(p) = &e.kind\n            && cx.qpath_res(p, e.hir_id) == res\n        {\n            return ControlFlow::Break(());\n        }\n        ControlFlow::Continue(())\n    })\n    .is_some()\n}\n\n/// Checks if the given local is used.\npub fn is_local_used<'tcx>(cx: &LateContext<'tcx>, visitable: impl Visitable<'tcx>, id: HirId) -> bool {\n    for_each_expr(cx, visitable, |e| {\n        if e.res_local_id() == Some(id) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\n/// Checks if the given expression is a constant.\npub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {\n    struct V<'a, 'tcx> {\n        cx: &'a LateContext<'tcx>,\n    }\n\n    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {\n        type Result = ControlFlow<()>;\n        type NestedFilter = intravisit::nested_filter::None;\n\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {\n            match e.kind {\n                ExprKind::ConstBlock(_) => return ControlFlow::Continue(()),\n                ExprKind::Call(\n                    &Expr {\n                        kind: ExprKind::Path(ref p),\n                        hir_id,\n                        ..\n                    },\n                    _,\n                ) if self\n                    .cx\n                    .qpath_res(p, hir_id)\n                    .opt_def_id()\n                    .is_some_and(|id| is_stable_const_fn(self.cx, id, Msrv::default())) => {},\n                ExprKind::MethodCall(..)\n                    if self\n                        .cx\n                        .typeck_results()\n                        .type_dependent_def_id(e.hir_id)\n                        .is_some_and(|id| is_stable_const_fn(self.cx, id, Msrv::default())) => {},\n                ExprKind::Binary(_, lhs, rhs)\n                    if self.cx.typeck_results().expr_ty(lhs).peel_refs().is_primitive_ty()\n                        && self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},\n                ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_raw_ptr() => (),\n                ExprKind::Unary(_, e) if self.cx.typeck_results().expr_ty(e).peel_refs().is_primitive_ty() => (),\n                ExprKind::Index(base, _, _)\n                    if matches!(\n                        self.cx.typeck_results().expr_ty(base).peel_refs().kind(),\n                        ty::Slice(_) | ty::Array(..)\n                    ) => {},\n                ExprKind::Path(ref p)\n                    if matches!(\n                        self.cx.qpath_res(p, e.hir_id),\n                        Res::Def(\n                            DefKind::Const { .. }\n                                | DefKind::AssocConst { .. }\n                                | DefKind::AnonConst\n                                | DefKind::ConstParam\n                                | DefKind::Ctor(..)\n                                | DefKind::Fn\n                                | DefKind::AssocFn,\n                            _\n                        ) | Res::SelfCtor(_)\n                    ) => {},\n\n                ExprKind::AddrOf(..)\n                | ExprKind::Array(_)\n                | ExprKind::Block(..)\n                | ExprKind::Cast(..)\n                | ExprKind::DropTemps(_)\n                | ExprKind::Field(..)\n                | ExprKind::If(..)\n                | ExprKind::Let(..)\n                | ExprKind::Lit(_)\n                | ExprKind::Match(..)\n                | ExprKind::Repeat(..)\n                | ExprKind::Struct(..)\n                | ExprKind::Tup(_)\n                | ExprKind::Type(..)\n                | ExprKind::UnsafeBinderCast(..) => (),\n\n                _ => {\n                    return ControlFlow::Break(());\n                },\n            }\n\n            walk_expr(self, e)\n        }\n    }\n\n    let mut v = V { cx };\n    v.visit_expr(e).is_continue()\n}\n\n/// Checks if the given expression performs an unsafe operation outside of an unsafe block.\npub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {\n    struct V<'a, 'tcx> {\n        cx: &'a LateContext<'tcx>,\n    }\n    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {\n        type NestedFilter = nested_filter::OnlyBodies;\n        type Result = ControlFlow<()>;\n\n        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n            self.cx.tcx\n        }\n        fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {\n            match e.kind {\n                ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_raw_ptr() => {\n                    ControlFlow::Break(())\n                },\n                ExprKind::MethodCall(..)\n                    if self\n                        .cx\n                        .typeck_results()\n                        .type_dependent_def_id(e.hir_id)\n                        .is_some_and(|id| self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe()) =>\n                {\n                    ControlFlow::Break(())\n                },\n                ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() {\n                    ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety().is_unsafe() => {\n                        ControlFlow::Break(())\n                    },\n                    ty::FnPtr(_, hdr) if hdr.safety.is_unsafe() => ControlFlow::Break(()),\n                    _ => walk_expr(self, e),\n                },\n                ExprKind::Path(ref p)\n                    if self\n                        .cx\n                        .qpath_res(p, e.hir_id)\n                        .opt_def_id()\n                        .is_some_and(|id| self.cx.tcx.is_mutable_static(id)) =>\n                {\n                    ControlFlow::Break(())\n                },\n                _ => walk_expr(self, e),\n            }\n        }\n        fn visit_block(&mut self, b: &'tcx Block<'_>) -> Self::Result {\n            if matches!(b.rules, BlockCheckMode::UnsafeBlock(_)) {\n                ControlFlow::Continue(())\n            } else {\n                walk_block(self, b)\n            }\n        }\n        fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {\n            if let ItemKind::Impl(i) = &self.cx.tcx.hir_item(id).kind\n                && let Some(of_trait) = i.of_trait\n                && of_trait.safety.is_unsafe()\n            {\n                ControlFlow::Break(())\n            } else {\n                ControlFlow::Continue(())\n            }\n        }\n    }\n    let mut v = V { cx };\n    v.visit_expr(e).is_break()\n}\n\n/// Checks if the given expression contains an unsafe block\npub fn contains_unsafe_block<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {\n    struct V<'cx, 'tcx> {\n        cx: &'cx LateContext<'tcx>,\n    }\n    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {\n        type Result = ControlFlow<()>;\n        type NestedFilter = nested_filter::OnlyBodies;\n        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n            self.cx.tcx\n        }\n\n        fn visit_block(&mut self, b: &'tcx Block<'_>) -> Self::Result {\n            if b.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) {\n                ControlFlow::Break(())\n            } else {\n                walk_block(self, b)\n            }\n        }\n    }\n    let mut v = V { cx };\n    v.visit_expr(e).is_break()\n}\n\n/// Runs the given function for each sub-expression producing the final value consumed by the parent\n/// of the give expression.\n///\n/// e.g. for the following expression\n/// ```rust,ignore\n/// if foo {\n///     f(0)\n/// } else {\n///     1 + 1\n/// }\n/// ```\n/// this will pass both `f(0)` and `1+1` to the given function.\npub fn for_each_value_source<'tcx, B>(\n    e: &'tcx Expr<'tcx>,\n    f: &mut impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>,\n) -> ControlFlow<B> {\n    match e.kind {\n        ExprKind::Block(Block { expr: Some(e), .. }, _) => for_each_value_source(e, f),\n        ExprKind::Match(_, arms, _) => {\n            for arm in arms {\n                for_each_value_source(arm.body, f)?;\n            }\n            ControlFlow::Continue(())\n        },\n        ExprKind::If(_, if_expr, Some(else_expr)) => {\n            for_each_value_source(if_expr, f)?;\n            for_each_value_source(else_expr, f)\n        },\n        ExprKind::DropTemps(e) => for_each_value_source(e, f),\n        _ => f(e),\n    }\n}\n\n/// Runs the given function for each path expression referencing the given local which occur after\n/// the given expression.\npub fn for_each_local_use_after_expr<'tcx, B>(\n    cx: &LateContext<'tcx>,\n    local_id: HirId,\n    expr_id: HirId,\n    f: impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>,\n) -> ControlFlow<B> {\n    struct V<'cx, 'tcx, F, B> {\n        cx: &'cx LateContext<'tcx>,\n        local_id: HirId,\n        expr_id: HirId,\n        found: bool,\n        res: ControlFlow<B>,\n        f: F,\n    }\n    impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> {\n        type NestedFilter = nested_filter::OnlyBodies;\n        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n            self.cx.tcx\n        }\n\n        fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) {\n            if !self.found {\n                if e.hir_id == self.expr_id {\n                    self.found = true;\n                } else {\n                    walk_expr(self, e);\n                }\n                return;\n            }\n            if self.res.is_break() {\n                return;\n            }\n            if e.res_local_id() == Some(self.local_id) {\n                self.res = (self.f)(e);\n            } else {\n                walk_expr(self, e);\n            }\n        }\n    }\n\n    if let Some(b) = get_enclosing_block(cx, local_id) {\n        let mut v = V {\n            cx,\n            local_id,\n            expr_id,\n            found: false,\n            res: ControlFlow::Continue(()),\n            f,\n        };\n        v.visit_block(b);\n        v.res\n    } else {\n        ControlFlow::Continue(())\n    }\n}\n\n// Calls the given function for every unconsumed temporary created by the expression. Note the\n// function is only guaranteed to be called for types which need to be dropped, but it may be called\n// for other types.\n#[expect(clippy::too_many_lines)]\npub fn for_each_unconsumed_temporary<'tcx, B>(\n    cx: &LateContext<'tcx>,\n    e: &'tcx Expr<'tcx>,\n    mut f: impl FnMut(Ty<'tcx>) -> ControlFlow<B>,\n) -> ControlFlow<B> {\n    // Todo: Handle partially consumed values.\n    fn helper<'tcx, B>(\n        typeck: &'tcx TypeckResults<'tcx>,\n        consume: bool,\n        e: &'tcx Expr<'tcx>,\n        f: &mut impl FnMut(Ty<'tcx>) -> ControlFlow<B>,\n    ) -> ControlFlow<B> {\n        if !consume\n            || matches!(\n                typeck.expr_adjustments(e),\n                [adjust, ..] if matches!(adjust.kind, Adjust::Borrow(_) | Adjust::Deref(_))\n            )\n        {\n            match e.kind {\n                ExprKind::Path(QPath::Resolved(None, p))\n                    if matches!(p.res, Res::Def(DefKind::Ctor(_, CtorKind::Const), _)) =>\n                {\n                    f(typeck.expr_ty(e))?;\n                },\n                ExprKind::Path(_)\n                | ExprKind::Unary(UnOp::Deref, _)\n                | ExprKind::Index(..)\n                | ExprKind::Field(..)\n                | ExprKind::AddrOf(..) => (),\n                _ => f(typeck.expr_ty(e))?,\n            }\n        }\n        match e.kind {\n            ExprKind::AddrOf(_, _, e)\n            | ExprKind::Field(e, _)\n            | ExprKind::Unary(UnOp::Deref, e)\n            | ExprKind::Match(e, ..)\n            | ExprKind::Let(&LetExpr { init: e, .. }) => {\n                helper(typeck, false, e, f)?;\n            },\n            ExprKind::Block(&Block { expr: Some(e), .. }, _) | ExprKind::Cast(e, _) | ExprKind::Unary(_, e) => {\n                helper(typeck, true, e, f)?;\n            },\n            ExprKind::Call(callee, args) => {\n                helper(typeck, true, callee, f)?;\n                for arg in args {\n                    helper(typeck, true, arg, f)?;\n                }\n            },\n            ExprKind::MethodCall(_, receiver, args, _) => {\n                helper(typeck, true, receiver, f)?;\n                for arg in args {\n                    helper(typeck, true, arg, f)?;\n                }\n            },\n            ExprKind::Tup(args) | ExprKind::Array(args) => {\n                for arg in args {\n                    helper(typeck, true, arg, f)?;\n                }\n            },\n            ExprKind::Use(expr, _) => {\n                helper(typeck, true, expr, f)?;\n            },\n            ExprKind::Index(borrowed, consumed, _)\n            | ExprKind::Assign(borrowed, consumed, _)\n            | ExprKind::AssignOp(_, borrowed, consumed) => {\n                helper(typeck, false, borrowed, f)?;\n                helper(typeck, true, consumed, f)?;\n            },\n            ExprKind::Binary(_, lhs, rhs) => {\n                helper(typeck, true, lhs, f)?;\n                helper(typeck, true, rhs, f)?;\n            },\n            ExprKind::Struct(_, fields, default) => {\n                for field in fields {\n                    helper(typeck, true, field.expr, f)?;\n                }\n                if let StructTailExpr::Base(default) = default {\n                    helper(typeck, false, default, f)?;\n                }\n            },\n            ExprKind::If(cond, then, else_expr) => {\n                helper(typeck, true, cond, f)?;\n                helper(typeck, true, then, f)?;\n                if let Some(else_expr) = else_expr {\n                    helper(typeck, true, else_expr, f)?;\n                }\n            },\n            ExprKind::Type(e, _) | ExprKind::UnsafeBinderCast(_, e, _) => {\n                helper(typeck, consume, e, f)?;\n            },\n\n            // Either drops temporaries, jumps out of the current expression, or has no sub expression.\n            ExprKind::DropTemps(_)\n            | ExprKind::Ret(_)\n            | ExprKind::Become(_)\n            | ExprKind::Break(..)\n            | ExprKind::Yield(..)\n            | ExprKind::Block(..)\n            | ExprKind::Loop(..)\n            | ExprKind::Repeat(..)\n            | ExprKind::Lit(_)\n            | ExprKind::ConstBlock(_)\n            | ExprKind::Closure { .. }\n            | ExprKind::Path(_)\n            | ExprKind::Continue(_)\n            | ExprKind::InlineAsm(_)\n            | ExprKind::OffsetOf(..)\n            | ExprKind::Err(_) => (),\n        }\n        ControlFlow::Continue(())\n    }\n    helper(cx.typeck_results(), true, e, &mut f)\n}\n\npub fn any_temporaries_need_ordered_drop<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {\n    for_each_unconsumed_temporary(cx, e, |ty| {\n        if needs_ordered_drop(cx, ty) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_break()\n}\n\n/// Runs the given function for each path expression referencing the given local which occur after\n/// the given expression.\npub fn for_each_local_assignment<'tcx, B>(\n    cx: &LateContext<'tcx>,\n    local_id: HirId,\n    f: impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>,\n) -> ControlFlow<B> {\n    struct V<'cx, 'tcx, F, B> {\n        cx: &'cx LateContext<'tcx>,\n        local_id: HirId,\n        res: ControlFlow<B>,\n        f: F,\n    }\n    impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> {\n        type NestedFilter = nested_filter::OnlyBodies;\n        fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {\n            self.cx.tcx\n        }\n\n        fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) {\n            if let ExprKind::Assign(lhs, rhs, _) = e.kind\n                && self.res.is_continue()\n                && lhs.res_local_id() == Some(self.local_id)\n            {\n                self.res = (self.f)(rhs);\n                self.visit_expr(rhs);\n            } else {\n                walk_expr(self, e);\n            }\n        }\n    }\n\n    if let Some(b) = get_enclosing_block(cx, local_id) {\n        let mut v = V {\n            cx,\n            local_id,\n            res: ControlFlow::Continue(()),\n            f,\n        };\n        v.visit_block(b);\n        v.res\n    } else {\n        ControlFlow::Continue(())\n    }\n}\n\npub fn contains_break_or_continue(expr: &Expr<'_>) -> bool {\n    for_each_expr_without_closures(expr, |e| {\n        if matches!(e.kind, ExprKind::Break(..) | ExprKind::Continue(..)) {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    })\n    .is_some()\n}\n\n/// If the local is only used once in `visitable` returns the path expression referencing the given\n/// local\npub fn local_used_once<'tcx>(\n    cx: &LateContext<'tcx>,\n    visitable: impl Visitable<'tcx>,\n    id: HirId,\n) -> Option<&'tcx Expr<'tcx>> {\n    let mut expr = None;\n\n    let cf = for_each_expr(cx, visitable, |e| {\n        if e.res_local_id() == Some(id) && expr.replace(e).is_some() {\n            ControlFlow::Break(())\n        } else {\n            ControlFlow::Continue(())\n        }\n    });\n    if cf.is_some() {\n        return None;\n    }\n\n    expr\n}\n"
  },
  {
    "path": "declare_clippy_lint/Cargo.toml",
    "content": "[package]\nname = \"declare_clippy_lint\"\nversion = \"0.1.96\"\nedition = \"2024\"\nrepository = \"https://github.com/rust-lang/rust-clippy\"\nlicense = \"MIT OR Apache-2.0\"\n\n[package.metadata.rust-analyzer]\n# This crate uses #[feature(rustc_private)]\nrustc_private = true\n"
  },
  {
    "path": "declare_clippy_lint/src/lib.rs",
    "content": "#![feature(macro_metavar_expr_concat, rustc_private)]\n\nextern crate rustc_lint;\n\nuse rustc_lint::{Lint, LintId, LintStore};\n\n// Needed by `declare_clippy_lint!`.\npub extern crate rustc_session;\n\n#[derive(Default)]\npub struct LintListBuilder {\n    lints: Vec<&'static Lint>,\n    all: Vec<LintId>,\n    cargo: Vec<LintId>,\n    complexity: Vec<LintId>,\n    correctness: Vec<LintId>,\n    nursery: Vec<LintId>,\n    pedantic: Vec<LintId>,\n    perf: Vec<LintId>,\n    restriction: Vec<LintId>,\n    style: Vec<LintId>,\n    suspicious: Vec<LintId>,\n}\nimpl LintListBuilder {\n    pub fn insert(&mut self, lints: &[&LintInfo]) {\n        #[allow(clippy::enum_glob_use)]\n        use LintCategory::*;\n\n        self.lints.extend(lints.iter().map(|&x| x.lint));\n        for &&LintInfo { lint, category, .. } in lints {\n            let (all, cat) = match category {\n                Complexity => (Some(&mut self.all), &mut self.complexity),\n                Correctness => (Some(&mut self.all), &mut self.correctness),\n                Perf => (Some(&mut self.all), &mut self.perf),\n                Style => (Some(&mut self.all), &mut self.style),\n                Suspicious => (Some(&mut self.all), &mut self.suspicious),\n                Cargo => (None, &mut self.cargo),\n                Nursery => (None, &mut self.nursery),\n                Pedantic => (None, &mut self.pedantic),\n                Restriction => (None, &mut self.restriction),\n            };\n            if let Some(all) = all {\n                all.push(LintId::of(lint));\n            }\n            cat.push(LintId::of(lint));\n        }\n    }\n\n    pub fn register(self, store: &mut LintStore) {\n        store.register_lints(&self.lints);\n        store.register_group(true, \"clippy::all\", Some(\"clippy_all\"), self.all);\n        store.register_group(true, \"clippy::cargo\", Some(\"clippy_cargo\"), self.cargo);\n        store.register_group(true, \"clippy::complexity\", Some(\"clippy_complexity\"), self.complexity);\n        store.register_group(\n            true,\n            \"clippy::correctness\",\n            Some(\"clippy_correctness\"),\n            self.correctness,\n        );\n        store.register_group(true, \"clippy::nursery\", Some(\"clippy_nursery\"), self.nursery);\n        store.register_group(true, \"clippy::pedantic\", Some(\"clippy_pedantic\"), self.pedantic);\n        store.register_group(true, \"clippy::perf\", Some(\"clippy_perf\"), self.perf);\n        store.register_group(\n            true,\n            \"clippy::restriction\",\n            Some(\"clippy_restriction\"),\n            self.restriction,\n        );\n        store.register_group(true, \"clippy::style\", Some(\"clippy_style\"), self.style);\n        store.register_group(true, \"clippy::suspicious\", Some(\"clippy_suspicious\"), self.suspicious);\n    }\n}\n\n#[derive(Copy, Clone, Debug)]\npub enum LintCategory {\n    Cargo,\n    Complexity,\n    Correctness,\n    Nursery,\n    Pedantic,\n    Perf,\n    Restriction,\n    Style,\n    Suspicious,\n}\nimpl LintCategory {\n    #[must_use]\n    pub fn name(self) -> &'static str {\n        match self {\n            Self::Cargo => \"cargo\",\n            Self::Complexity => \"complexity\",\n            Self::Correctness => \"correctness\",\n            Self::Nursery => \"nursery\",\n            Self::Pedantic => \"pedantic\",\n            Self::Perf => \"perf\",\n            Self::Restriction => \"restriction\",\n            Self::Style => \"style\",\n            Self::Suspicious => \"suspicious\",\n        }\n    }\n}\n\npub struct LintInfo {\n    pub lint: &'static Lint,\n    pub category: LintCategory,\n    pub explanation: &'static str,\n    /// e.g. `clippy_lints/src/absolute_paths.rs#43`\n    pub location: &'static str,\n    pub version: &'static str,\n}\n\nimpl LintInfo {\n    /// Returns the lint name in lowercase without the `clippy::` prefix\n    #[must_use]\n    #[expect(clippy::missing_panics_doc)]\n    pub fn name_lower(&self) -> String {\n        self.lint.name.strip_prefix(\"clippy::\").unwrap().to_ascii_lowercase()\n    }\n}\n\n#[macro_export]\nmacro_rules! declare_clippy_lint_inner {\n    (\n        $(#[doc = $docs:literal])*\n        #[clippy::version = $version:literal]\n        $vis:vis $lint_name:ident,\n        $level:ident,\n        $category:ident,\n        $desc:literal\n        $(, @eval_always = $eval_always:literal)?\n    ) => {\n        $crate::rustc_session::declare_tool_lint! {\n            $(#[doc = $docs])*\n            #[clippy::version = $version]\n            $vis clippy::$lint_name,\n            $level,\n            $desc,\n            report_in_external_macro:true\n            $(, @eval_always = $eval_always)?\n        }\n\n        pub(crate) static ${concat($lint_name, _INFO)}: &'static $crate::LintInfo = &$crate::LintInfo {\n            lint: $lint_name,\n            category: $crate::LintCategory::$category,\n            explanation: concat!($($docs,\"\\n\",)*),\n            location: concat!(file!(), \"#L\", line!()),\n            version: $version,\n        };\n    };\n}\n\n#[macro_export]\nmacro_rules! declare_clippy_lint {\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        correctness,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Deny,\n            Correctness,\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        complexity,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Warn,\n            Complexity,\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        perf,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Warn,\n            Perf,\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        style,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Warn,\n            Style,\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        suspicious,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Warn,\n            Suspicious,\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        cargo,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Allow,\n            Cargo,\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        nursery,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Allow,\n            Nursery,\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        pedantic,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Allow,\n            Pedantic,\n            $($rest)*\n        }\n    };\n    (\n        $(#[$($meta:tt)*])*\n        $vis:vis $lint_name:ident,\n        restriction,\n        $($rest:tt)*\n    ) => {\n        $crate::declare_clippy_lint_inner! {\n            $(#[$($meta)*])*\n            $vis $lint_name,\n            Allow,\n            Restriction,\n            $($rest)*\n        }\n    };\n}\n"
  },
  {
    "path": "etc/relicense/RELICENSE_DOCUMENTATION.md",
    "content": "This repository was previously licensed under MPL-2.0, however in #3093\n([archive](http://web.archive.org/web/20181005185227/https://github.com/rust-lang-nursery/rust-clippy/issues/3093),\n[screenshot](https://user-images.githubusercontent.com/1617736/46573505-5b856880-c94b-11e8-9a14-981c889b4981.png)) we\nrelicensed it to the Rust license (dual licensed as Apache v2 / MIT)\n\nAt the time, the contributors were those listed in contributors.txt.\n\nWe opened a bunch of issues asking for an explicit relicensing approval. Screenshots of all these issues at the time of\nrelicensing are archived on GitHub. We also have saved Wayback Machine copies of these:\n\n- #3094\n  ([archive](http://web.archive.org/web/20181005191247/https://github.com/rust-lang-nursery/rust-clippy/issues/3094),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573506-5b856880-c94b-11e8-8a44-51cb40bc16ee.png))\n- #3095\n  ([archive](http://web.archive.org/web/20181005184416/https://github.com/rust-lang-nursery/rust-clippy/issues/3095),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573507-5c1dff00-c94b-11e8-912a-4bd6b5f838f5.png))\n- #3096\n  ([archive](http://web.archive.org/web/20181005184802/https://github.com/rust-lang-nursery/rust-clippy/issues/3096),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573508-5c1dff00-c94b-11e8-9425-2464f7260ff0.png))\n- #3097\n  ([archive](http://web.archive.org/web/20181005184821/https://github.com/rust-lang-nursery/rust-clippy/issues/3097),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573509-5c1dff00-c94b-11e8-8ba2-53f687984fe7.png))\n- #3098\n  ([archive](http://web.archive.org/web/20181005184900/https://github.com/rust-lang-nursery/rust-clippy/issues/3098),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573510-5c1dff00-c94b-11e8-8f64-371698401c60.png))\n- #3099\n  ([archive](http://web.archive.org/web/20181005184901/https://github.com/rust-lang-nursery/rust-clippy/issues/3099),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573511-5c1dff00-c94b-11e8-8e20-7d0eeb392b95.png))\n- #3100\n  ([archive](http://web.archive.org/web/20181005184901/https://github.com/rust-lang-nursery/rust-clippy/issues/3100),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573512-5c1dff00-c94b-11e8-8a13-7d758ed3563d.png))\n- #3230\n  ([archive](http://web.archive.org/web/20181005184903/https://github.com/rust-lang-nursery/rust-clippy/issues/3230),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573513-5cb69580-c94b-11e8-86b1-14ce82741e5c.png))\n\nThe usernames of commenters on these issues can be found in relicense_comments.txt\n\nThere are a few people in relicense_comments.txt who are not found in contributors.txt:\n\n- @EpocSquadron has [made minor text contributions to the\n  README](https://github.com/rust-lang/rust-clippy/commits?author=EpocSquadron) which have since been overwritten, and\n  doesn't count\n- @JayKickliter [agreed to the relicense on their pull\n  request](https://github.com/rust-lang/rust-clippy/pull/3195#issuecomment-423781016)\n  ([archive](https://web.archive.org/web/20181005190730/https://github.com/rust-lang/rust-clippy/pull/3195),\n  [screenshot](https://user-images.githubusercontent.com/1617736/46573514-5cb69580-c94b-11e8-8ffb-05a5bd02e2cc.png)\n\n- @sanmai-NL's [contribution](https://github.com/rust-lang/rust-clippy/commits?author=sanmai-NL) is a minor one-word\n  addition which doesn't count for copyright assignment\n- @zmt00's [contributions](https://github.com/rust-lang/rust-clippy/commits?author=zmt00) are minor typo fixes and don't\n  count\n- @VKlayd has [nonminor contributions](https://github.com/rust-lang/rust-clippy/commits?author=VKlayd) which we rewrote\n  (see below)\n- @wartman4404 has [nonminor contributions](https://github.com/rust-lang/rust-clippy/commits?author=wartman4404) which\n  we rewrote (see below)\n\n\nTwo of these contributors had non-minor contributions (#2184, #427) requiring a rewrite, carried out in #3251\n([archive](http://web.archive.org/web/20181005192411/https://github.com/rust-lang-nursery/rust-clippy/pull/3251),\n[screenshot](https://user-images.githubusercontent.com/1617736/46573515-5cb69580-c94b-11e8-86e5-b456452121b2.png))\n\nFirst, I (Manishearth) removed the lints they had added. I then documented at a high level what the lints did in #3251,\nasking for co-maintainers who had not seen the code for the lints to rewrite them. #2814 was rewritten by @phansch, and\n#427 was rewritten by @oli-obk, who did not recall having previously seen the code they were rewriting.\n\n------\n\nSince this document was written, @JayKickliter and @sanmai-ML added their consent in #3230\n([archive](http://web.archive.org/web/20181006171926/https://github.com/rust-lang-nursery/rust-clippy/issues/3230))\n"
  },
  {
    "path": "etc/relicense/contributors.txt",
    "content": "0ndorio\n0xbsec\n17cupsofcoffee\nAaron1011\nAaronepower\naaudiber\nafck\nalexcrichton\nAlexEne\nalexeyzab\nalexheretic\nalexreg\nalusch\nandersk\naochagavia\napasel422\nArnavion\nAtheMathmo\nauscompgeek\nAVerm\nbadboy\nBaelyk\nBenoitZugmeyer\nbestouff\nbirkenfeld\nbjgill\nbkchr\nBobo1239\nbood\nbootandy\nb-r-u\nbudziq\nCAD97\nCaemor\ncamsteffen\ncarols10cents\nCBenoit\ncesarb\ncgm616\nchrisduerr\nchrisvittal\nchyvonomys\nclarcharr\nclippered\ncommandline\ncramertj\ncsmoe\nctjhoa\ncuviper\nCYBAI\ndarArch\nDarkEld3r\ndashed\ndaubaris\nd-dorazio\ndebris\ndereckson\ndetrumi\ndevonhollowood\ndtolnay\ndurka\ndwijnand\neddyb\nelliottneilclark\nelpiel\nensch\nEpicatSupercell\nEpocSquadron\nerickt\nestk\netaoins\nF001\nfanzier\nFauxFaux\nfhartwig\nflip1995\nFraser999\nFrederick888\nfrewsxcv\ngbip\ngendx\ngibfahn\ngnieto\ngnzlbg\ngoodmanjonathan\nguido4000\nGuillaumeGomez\nHanaasagi\nhdhoang\nHMPerson1\nhobofan\niKevinY\nillicitonion\nimp\ninrustwetrust\nishitatsuyuki\nJascha-N\njayhardee9\nJayKickliter\nJDemler\njedisct1\njmquigs\njoelgallant\njoeratt\njosephDunne\nJoshMcguigan\njoshtriplett\njugglerchris\nkaryon\nKeats\nkennytm\nKha\nkillercup\nkimsnj\nKitFreddura\nkoivunej\nkraai\nkvikas\nLaurentMazare\nletheed\nllogiq\nlo48576\nlpesk\nlucab\nluisbg\nlukasstevens\nMachtan\nMaloJaffre\nManishearth\nmarcusklaas\nmark-i-m\nmartiansideofthemoon\nmartinlindhe\nmathstuf\nmati865\nmatthiaskrgr\nmattyhall\nmbrubeck\nmcarton\nmemoryleak47\nmessense\nmichaelrutherford\nmikerite\nmipli\nmockersf\nmontrivo\nmrecachinas\nMrmaxmeier\nmrmonday\nms2300\nMs2ger\nmusoke\nnathan\nNemo157\nNiekGr\nniklasf\nnrc\nnweston\no01eg\nogham\noli-obk\nordovicia\npengowen123\npgerber\nphansch\nphilipturnbull\npickfire\npietro\nPixelPirate\npizzaiter\nPSeitz\nPyriphlegethon\npythonesque\nquininer\nRantanen\nrcoh\nreiner-dolp\nreujab\nRobzz\nsamueltardieu\nsanmai-NL\nsanxiyn\nscott-linder\nscottmcm\nscurest\nsenden9\nshahn\nshepmaster\nshnewto\nshssoichiro\nsiiptuo\nsinkuu\nskade\nsourcefrog\nsourcejedi\nsteveklabnik\nsunfishcode\nsunjay\nswgillespie\nTechcable\nterry90\ntheemathas\nthekidxp\ntheotherphil\nTimNN\nTomasKralCZ\ntomprince\ntopecongiro\ntspiteri\nTwisol\nU007D\nuHOOCCOOHu\nuntitaker\nupsuper\nutaal\nutam0k\nvi\nVKlayd\nVlad-Shcherbina\nvorner\nwafflespeanut\nwartman4404\nwaywardmonkeys\nyaahallo\nyangby-cryptape\nyati-sagade\nykrivopalov\nysimonson\nzayenz\nzmanian\nzmbush\nzmt00\n"
  },
  {
    "path": "etc/relicense/relicense_comments.txt",
    "content": "0ndorio\n0xbsec\n17cupsofcoffee\nAaron1011\nAaronepower\naaudiber\nafck\nalexcrichton\nAlexEne\nalexeyzab\nalexheretic\nalexreg\nalusch\nandersk\naochagavia\napasel422\nArnavion\nAtheMathmo\nauscompgeek\nAVerm\nbadboy\nBaelyk\nBenoitZugmeyer\nbestouff\nbirkenfeld\nbjgill\nbkchr\nBobo1239\nbood\nbootandy\nb-r-u\nbudziq\nCAD97\nCaemor\ncamsteffen\ncarols10cents\nCBenoit\ncesarb\ncgm616\nchrisduerr\nchrisvittal\nchyvonomys\nclarcharr\nclippered\ncommandline\ncramertj\ncsmoe\nctjhoa\ncuviper\nCYBAI\ndarArch\nDarkEld3r\ndashed\ndaubaris\nd-dorazio\ndebris\ndereckson\ndetrumi\ndevonhollowood\ndtolnay\ndurka\ndwijnand\neddyb\nelliottneilclark\nelpiel\nensch\nEpicatSupercell\nerickt\nestk\netaoins\nF001\nfanzier\nFauxFaux\nfhartwig\nflip1995\nFraser999\nFrederick888\nfrewsxcv\ngbip\ngendx\ngibfahn\ngnieto\ngnzlbg\ngoodmanjonathan\nguido4000\nGuillaumeGomez\nHanaasagi\nhdhoang\nHMPerson1\nhobofan\niKevinY\nillicitonion\nimp\ninrustwetrust\nishitatsuyuki\nJascha-N\njayhardee9\nJDemler\njedisct1\njmquigs\njoelgallant\njoeratt\njosephDunne\nJoshMcguigan\njoshtriplett\njugglerchris\nkaryon\nKeats\nkennytm\nKha\nkillercup\nkimsnj\nKitFreddura\nkoivunej\nkraai\nkvikas\nLaurentMazare\nletheed\nllogiq\nlo48576\nlpesk\nlucab\nluisbg\nlukasstevens\nMachtan\nMaloJaffre\nManishearth\nmarcusklaas\nmark-i-m\nmartiansideofthemoon\nmartinlindhe\nmathstuf\nmati865\nmatthiaskrgr\nmattyhall\nmbrubeck\nmcarton\nmemoryleak47\nmessense\nmichaelrutherford\nmikerite\nmipli\nmockersf\nmontrivo\nmrecachinas\nMrmaxmeier\nmrmonday\nms2300\nMs2ger\nmusoke\nnathan\nNemo157\nNiekGr\nniklasf\nnrc\nnweston\no01eg\nogham\noli-obk\nordovicia\npengowen123\npgerber\nphansch\nphilipturnbull\npickfire\npietro\nPixelPirate\npizzaiter\nPSeitz\nPyriphlegethon\npythonesque\nquininer\nRantanen\nrcoh\nreiner-dolp\nreujab\nRobzz\nsamueltardieu\nsanxiyn\nscott-linder\nscottmcm\nscurest\nsenden9\nshahn\nshepmaster\nshnewto\nshssoichiro\nsiiptuo\nsinkuu\nskade\nsourcefrog\nsourcejedi\nsteveklabnik\nsunfishcode\nsunjay\nswgillespie\nTechcable\nterry90\ntheemathas\nthekidxp\ntheotherphil\nTimNN\nTomasKralCZ\ntommilligan\ntomprince\ntopecongiro\ntspiteri\nTwisol\nU007D\nuHOOCCOOHu\nuntitaker\nupsuper\nutaal\nutam0k\nvi\nVlad-Shcherbina\nvorner\nwafflespeanut\nwaywardmonkeys\nyaahallo\nyangby-cryptape\nyati-sagade\nykrivopalov\nysimonson\nzayenz\nzmanian\nzmbush\n"
  },
  {
    "path": "lintcheck/Cargo.toml",
    "content": "[package]\nname = \"lintcheck\"\nversion = \"0.0.1\"\ndescription = \"tool to monitor impact of changes in Clippy's lints on a part of the ecosystem\"\nreadme = \"README.md\"\nlicense = \"MIT OR Apache-2.0\"\nrepository = \"https://github.com/rust-lang/rust-clippy\"\ncategories = [\"development-tools\"]\nedition = \"2024\"\npublish = false\ndefault-run = \"lintcheck\"\n\n[dependencies]\ncargo_metadata = \"0.15.3\"\nclap = { version = \"4.4\", features = [\"derive\", \"env\"] }\ncrossbeam-channel = \"0.5.6\"\ndiff = \"0.1.13\"\nflate2 = \"1.0\"\nitertools = \"0.13\"\nrayon = \"1.5.1\"\nserde = { version = \"1.0\", features = [\"derive\"] }\nserde_json = \"1.0.85\"\nstrip-ansi-escapes = \"0.2.0\"\ntar = \"0.4\"\ntoml = \"0.9.7\"\nureq = { version = \"2.2\", features = [\"json\"] }\nwalkdir = \"2.3\"\n"
  },
  {
    "path": "lintcheck/README.md",
    "content": "## `cargo lintcheck`\n\nRuns Clippy on a fixed set of crates read from\n`lintcheck/lintcheck_crates.toml` and saves logs of the lint warnings into the\nrepo.  We can then check the diff and spot new or disappearing warnings.\n\nFrom the repo root, run:\n\n```\ncargo lintcheck\n```\n\nor\n\n```\ncargo run --target-dir lintcheck/target --manifest-path lintcheck/Cargo.toml\n```\n\nBy default, the logs will be saved into\n`lintcheck-logs/lintcheck_crates_logs.txt`.\n\nYou can set a custom sources.toml by adding `--crates-toml custom.toml` or using\n`LINTCHECK_TOML=\"custom.toml\"` where `custom.toml` must be a relative path from\nthe repo root.\n\nThe results will then be saved to `lintcheck-logs/custom_logs.toml`.\n\nThe `custom.toml` file may be built using <https://crates.io> recently most\ndownloaded crates by using `cargo lintcheck popular`. For example, to retrieve\nthe 200 recently most downloaded crates:\n\n```\ncargo lintcheck popular -n 200 custom.toml\n```\n\n> Note: Lintcheck isn't sandboxed. Only use it to check crates that you trust or\n> sandbox it manually.\n\n### Configuring the Crate Sources\n\nThe sources to check are saved in a `toml` file. There are three types of\nsources.\n\n1. Crates-io Source\n\n   ```toml\n   bitflags = {name = \"bitflags\", versions = ['1.2.1']}\n   ```\n   Requires a \"name\" and one or multiple \"versions\" to be checked.\n\n2. `git` Source\n   ````toml\n   puffin = {name = \"puffin\", git_url = \"https://github.com/EmbarkStudios/puffin\", git_hash = \"02dd4a3\"}\n   ````\n   Requires a name, the url to the repo and unique identifier of a commit,\n   branch or tag which is checked out before linting.  There is no way to always\n   check `HEAD` because that would lead to changing lint-results as the repo\n   would get updated.  If `git_url` or `git_hash` is missing, an error will be\n   thrown.\n\n3. Local Dependency\n   ```toml\n   clippy = {name = \"clippy\", path = \"/home/user/clippy\"}\n   ```\n   For when you want to add a repository that is not published yet.\n\n#### Command Line Options (optional)\n\n```toml\nclap = {name = \"clap\", versions = ['4.5.8'], options = ['-Fderive']}\n```\n\nIt is possible to specify command line options for each crate. This makes it\npossible to enable or disable features.\n\n### Fix mode\nYou can run `cargo lintcheck --fix` which will run Clippy with `--fix` and\nprint a warning if Clippy's suggestions fail to apply (if the resulting code does not build). \nThis lets us spot bad suggestions or false positives automatically in some cases.  \n\n> Note: Fix mode implies `--all-targets`, so it can fix as much code as it can.\n\nPlease note that the target dir should be cleaned afterwards since Clippy will modify\nthe downloaded sources which can lead to unexpected results when running lintcheck again afterwards.\n\n### Recursive mode\nYou can run `cargo lintcheck --recursive` to also run Clippy on the dependencies\nof the crates listed in the crates source `.toml`. e.g. adding `rand 0.8.5`\nwould also lint `rand_core`, `rand_chacha`, etc.\n\nParticularly slow crates in the dependency graph can be ignored using\n`recursive.ignore`:\n\n```toml\n[crates]\ncargo = {name = \"cargo\", versions = ['0.64.0']}\n\n[recursive]\nignore = [\n    \"unicode-normalization\",\n]\n```\n"
  },
  {
    "path": "lintcheck/ci-config/clippy.toml",
    "content": "# Configuration applied when running lintcheck from the CI\n#\n# The CI will set the `CLIPPY_CONF_DIR` environment variable\n# to `$PWD/lintcheck/ci-config`.\n\navoid-breaking-exported-api = false\nlint-commented-code = false\n"
  },
  {
    "path": "lintcheck/ci_crates.toml",
    "content": "[crates]\n# Binaries projects\ncargo = {name = \"cargo\", version = '0.64.0', online_link = 'https://docs.rs/cargo/{version}/src/{file}.html#{line}'}\nripgrep = {name = \"ripgrep\", version = '14.1.0'}\nbat = {name = \"bat\", version = '0.24.0'}\nfend = {name = \"fend\", version = '1.5.0'}\nmdbook = {name = \"mdbook\", version = '0.4.40'}\n\n# Bigger crates from ICE issues:\nwasmi = {name = \"wasmi\", version = '0.35.0'}\nwgpu = {name = \"wgpu\", version = '0.20.1'}\nbytes = {name = \"bytes\", version = '1.6.1'}\nskrifa = {name = \"skrifa\", version = '0.19.3'}\n\n# Random crates which are part of the default test set\npuffin = {name = \"puffin\", version = '0.19.0'}\n\n# Top ~200 crates from crates.io\nsyn = { name = 'syn', version = '2.0.71' }\nbitflags = { name = 'bitflags', version = '2.6.0' }\nhashbrown = { name = 'hashbrown', version = '0.14.5' }\nbase64 = { name = 'base64', version = '0.22.1' }\nregex-syntax = { name = 'regex-syntax', version = '0.8.4' }\nproc-macro2 = { name = 'proc-macro2', version = '1.0.86' }\nindexmap = { name = 'indexmap', version = '2.2.6' }\nquote = { name = 'quote', version = '1.0.36' }\nregex-automata = { name = 'regex-automata', version = '0.4.7' }\nlibc = { name = 'libc', version = '0.2.155' }\nserde = { name = 'serde', version = '1.0.204' }\nitertools = { name = 'itertools', version = '0.13.0' }\nheck = { name = 'heck', version = '0.5.0' }\nmemchr = { name = 'memchr', version = '2.7.4' }\nserde_derive = { name = 'serde_derive', version = '1.0.204' }\nunicode-ident = { name = 'unicode-ident', version = '1.0.12' }\nautocfg = { name = 'autocfg', version = '1.3.0' }\ncfg-if = { name = 'cfg-if', version = '1.0.0' }\naho-corasick = { name = 'aho-corasick', version = '1.1.3' }\ngetrandom = { name = 'getrandom', version = '0.2.15' }\nrand_core = { name = 'rand_core', version = '0.6.4' }\nserde_json = { name = 'serde_json', version = '1.0.120' }\nitoa = { name = 'itoa', version = '1.0.11' }\nrand = { name = 'rand', version = '0.8.5' }\nryu = { name = 'ryu', version = '1.0.18' }\nonce_cell = { name = 'once_cell', version = '1.19.0' }\nrustix = { name = 'rustix', version = '0.38.34' }\nregex = { name = 'regex', version = '1.10.5' }\nlog = { name = 'log', version = '0.4.22' }\nparking_lot_core = { name = 'parking_lot_core', version = '0.9.10' }\ncc = { name = 'cc', version = '1.1.5' }\nstrsim = { name = 'strsim', version = '0.11.1' }\nclap = { name = 'clap', version = '4.5.9' }\nparking_lot = { name = 'parking_lot', version = '0.12.3' }\nsmallvec = { name = 'smallvec', version = '2.0.0-alpha.6' }\nthiserror-impl = { name = 'thiserror-impl', version = '1.0.63' }\nthiserror = { name = 'thiserror', version = '1.0.63' }\nlinux-raw-sys = { name = 'linux-raw-sys', version = '0.6.4' }\nsocket2 = { name = 'socket2', version = '0.5.7' }\nidna = { name = 'idna', version = '1.0.2' }\nfastrand = { name = 'fastrand', version = '2.1.0' }\neither = { name = 'either', version = '1.13.0' }\nnum-traits = { name = 'num-traits', version = '0.2.19' }\nrand_chacha = { name = 'rand_chacha', version = '0.3.1' }\nlazy_static = { name = 'lazy_static', version = '1.5.0' }\nsemver = { name = 'semver', version = '1.0.23' }\nlock_api = { name = 'lock_api', version = '0.4.12' }\nscopeguard = { name = 'scopeguard', version = '1.2.0' }\nahash = { name = 'ahash', version = '0.8.11' }\nanyhow = { name = 'anyhow', version = '1.0.86' }\nrustls = { name = 'rustls', version = '0.23.11' }\nhttp = { name = 'http', version = '1.1.0' }\ntoml_edit = { name = 'toml_edit', version = '0.22.16' }\npin-project-lite = { name = 'pin-project-lite', version = '0.2.14' }\nspin = { name = 'spin', version = '0.9.8' }\nminiz_oxide = { name = 'miniz_oxide', version = '0.7.4' }\nmemoffset = { name = 'memoffset', version = '0.9.1' }\ndigest = { name = 'digest', version = '0.11.0-pre.8' }\nversion_check = { name = 'version_check', version = '0.9.4' }\nclap_lex = { name = 'clap_lex', version = '0.7.1' }\ncrossbeam-utils = { name = 'crossbeam-utils', version = '0.8.20' }\ntoml = { name = 'toml', version = '0.8.15' }\nblock-buffer = { name = 'block-buffer', version = '0.10.4' }\ntime = { name = 'time', version = '0.3.36' }\nhyper = { name = 'hyper', version = '1.4.1' }\nurl = { name = 'url', version = '2.5.2' }\npercent-encoding = { name = 'percent-encoding', version = '2.3.1' }\ntokio = { name = 'tokio', version = '1.38.1' }\nerrno = { name = 'errno', version = '0.3.9' }\nuuid = { name = 'uuid', version = '1.10.0' }\nunicode-normalization = { name = 'unicode-normalization', version = '0.1.23' }\nppv-lite86 = { name = 'ppv-lite86', version = '0.2.17' }\nfutures-core = { name = 'futures-core', version = '0.3.31' }\nhttp-body = { name = 'http-body', version = '1.0.1' }\ntinyvec = { name = 'tinyvec', version = '1.8.0' }\nfutures-util = { name = 'futures-util', version = '0.3.31' }\nfutures-task = { name = 'futures-task', version = '0.3.31' }\nsha2 = { name = 'sha2', version = '0.11.0-pre.3' }\nring = { name = 'ring', version = '0.17.8' }\nslab = { name = 'slab', version = '0.4.9' }\nchrono = { name = 'chrono', version = '0.4.38' }\nfutures-sink = { name = 'futures-sink', version = '0.3.31' }\nfutures-channel = { name = 'futures-channel', version = '0.3.31' }\nnum_cpus = { name = 'num_cpus', version = '1.16.0' }\nuntrusted = { name = 'untrusted', version = '0.9.0' }\ntinyvec_macros = { name = 'tinyvec_macros', version = '0.1.1' }\nmio = { name = 'mio', version = '1.0.0' }\nbyteorder = { name = 'byteorder', version = '1.5.0' }\nform_urlencoded = { name = 'form_urlencoded', version = '1.2.1' }\nunicode-bidi = { name = 'unicode-bidi', version = '0.3.15' }\nfutures-io = { name = 'futures-io', version = '0.3.31' }\ntokio-util = { name = 'tokio-util', version = '0.7.11' }\nrustls-pemfile = { name = 'rustls-pemfile', version = '2.1.2' }\ngeneric-array = { name = 'generic-array', version = '1.1.0' }\ntracing = { name = 'tracing', version = '0.1.40' }\nequivalent = { name = 'equivalent', version = '1.0.1' }\ntracing-core = { name = 'tracing-core', version = '0.1.32' }\npin-utils = { name = 'pin-utils', version = '0.1.0' }\ntempfile = { name = 'tempfile', version = '3.10.1' }\nh2 = { name = 'h2', version = '0.4.5' }\nfutures = { name = 'futures', version = '0.3.31' }\ntypenum = { name = 'typenum', version = '1.17.0' }\nwinnow = { name = 'winnow', version = '0.6.13' }\ncpufeatures = { name = 'cpufeatures', version = '0.2.12' }\nnix = { name = 'nix', version = '0.29.0' }\nfnv = { name = 'fnv', version = '1.0.7' }\ntokio-rustls = { name = 'tokio-rustls', version = '0.26.0' }\niana-time-zone = { name = 'iana-time-zone', version = '0.1.60' }\nrustls-webpki = { name = 'rustls-webpki', version = '0.102.5' }\ncrc32fast = { name = 'crc32fast', version = '1.4.2' }\nadler = { name = 'adler', version = '1.0.2' }\npkg-config = { name = 'pkg-config', version = '0.3.30' }\nredox_syscall = { name = 'redox_syscall', version = '0.5.3' }\nnom = { name = 'nom', version = '8.0.0-alpha2' }\nrustc_version = { name = 'rustc_version', version = '0.4.0' }\nfutures-macro = { name = 'futures-macro', version = '0.3.31' }\nclap_derive = { name = 'clap_derive', version = '4.5.8' }\nfutures-executor = { name = 'futures-executor', version = '0.3.31' }\nevent-listener = { name = 'event-listener', version = '5.3.1' }\nnum-integer = { name = 'num-integer', version = '0.1.46' }\ntime-macros = { name = 'time-macros', version = '0.2.18' }\nflate2 = { name = 'flate2', version = '1.0.30' }\ntokio-macros = { name = 'tokio-macros', version = '2.3.0' }\nstrum_macros = { name = 'strum_macros', version = '0.26.4' }\ntracing-attributes = { name = 'tracing-attributes', version = '0.1.27' }\nasync-trait = { name = 'async-trait', version = '0.1.81' }\ncrypto-common = { name = 'crypto-common', version = '0.1.6' }\nunicode-width = { name = 'unicode-width', version = '0.1.13' }\nanstyle = { name = 'anstyle', version = '1.0.7' }\nobject = { name = 'object', version = '0.36.1' }\ngimli = { name = 'gimli', version = '0.31.0' }\ncrossbeam-epoch = { name = 'crossbeam-epoch', version = '0.9.18' }\nthread_local = { name = 'thread_local', version = '1.1.8' }\nstrum = { name = 'strum', version = '0.26.3' }\ndarling_core = { name = 'darling_core', version = '0.20.10' }\ndarling_macro = { name = 'darling_macro', version = '0.20.10' }\nminimal-lexical = { name = 'minimal-lexical', version = '0.2.1' }\nclap_builder = { name = 'clap_builder', version = '4.5.9' }\ntime-core = { name = 'time-core', version = '0.1.2' }\nhttparse = { name = 'httparse', version = '1.9.4' }\nsignal-hook-registry = { name = 'signal-hook-registry', version = '1.4.2' }\nhex = { name = 'hex', version = '0.4.3' }\ncrossbeam-deque = { name = 'crossbeam-deque', version = '0.8.5' }\nzerocopy = { name = 'zerocopy', version = '0.7.35' }\nrustversion = { name = 'rustversion', version = '1.0.17' }\nenv_logger = { name = 'env_logger', version = '0.11.3' }\nwebpki-roots = { name = 'webpki-roots', version = '0.26.3' }\nrustc-demangle = { name = 'rustc-demangle', version = '0.1.24' }\nmime = { name = 'mime', version = '0.3.17' }\ntermcolor = { name = 'termcolor', version = '1.4.1' }\nsubtle = { name = 'subtle', version = '2.6.1' }\nwalkdir = { name = 'walkdir', version = '2.5.0' }\nhermit-abi = { name = 'hermit-abi', version = '0.4.0' }\npin-project = { name = 'pin-project', version = '1.1.5' }\npin-project-internal = { name = 'pin-project-internal', version = '1.1.5' }\ntry-lock = { name = 'try-lock', version = '0.2.5' }\ntracing-log = { name = 'tracing-log', version = '0.2.0' }\nhttpdate = { name = 'httpdate', version = '1.0.3' }\nanstream = { name = 'anstream', version = '0.6.14' }\ncrossbeam-channel = { name = 'crossbeam-channel', version = '0.5.13' }\nreqwest = { name = 'reqwest', version = '0.12.5' }\nwant = { name = 'want', version = '0.3.1' }\npaste = { name = 'paste', version = '1.0.15' }\nanstyle-parse = { name = 'anstyle-parse', version = '0.2.4' }\ntoml_datetime = { name = 'toml_datetime', version = '0.6.6' }\nanstyle-query = { name = 'anstyle-query', version = '1.1.0' }\naddr2line = { name = 'addr2line', version = '0.24.0' }\nglob = { name = 'glob', version = '0.3.1' }\nnum-bigint = { name = 'num-bigint', version = '0.4.6' }\nbacktrace = { name = 'backtrace', version = '0.3.73' }\nwasi = { name = 'wasi', version = '0.13.1+wasi-0.2.0' }\ntower-service = { name = 'tower-service', version = '0.3.2' }\nsync_wrapper = { name = 'sync_wrapper', version = '1.0.1' }\nlibloading = { name = 'libloading', version = '0.8.4' }\nrayon = { name = 'rayon', version = '1.10.0' }\ncolorchoice = { name = 'colorchoice', version = '1.0.1' }\nencoding_rs = { name = 'encoding_rs', version = '0.8.34' }\nderanged = { name = 'deranged', version = '0.3.11' }\nzeroize = { name = 'zeroize', version = '1.8.1' }\nutf8parse = { name = 'utf8parse', version = '0.2.2' }\ntracing-subscriber = { name = 'tracing-subscriber', version = '0.3.18' }\nhyper-rustls = { name = 'hyper-rustls', version = '0.27.2' }\nhmac = { name = 'hmac', version = '0.13.0-pre.3' }\nrayon-core = { name = 'rayon-core', version = '1.12.1' }\nsame-file = { name = 'same-file', version = '1.0.6' }\nprost = { name = 'prost', version = '0.13.1' }\nsharded-slab = { name = 'sharded-slab', version = '0.1.7' }\ntextwrap = { name = 'textwrap', version = '0.16.1' }\nbumpalo = {name = \"bumpalo\", version = '3.16.0'}\narrayvec = { name = 'arrayvec', version = '0.7.4' }\n"
  },
  {
    "path": "lintcheck/lintcheck_crates.toml",
    "content": "# If you want to check a local project it's usually easier to use:\n# ```\n# cargo dev lint <path>\n# ```\n#\n# For testing you can also add sources to git and local repos like this:\n# ```\n# crate = {name = \"crate\", git_url = \"https://github.com/name/repo.git\", git_hash = \"coo1cafe\"}\n# crate = {name = \"crate\", path = \"/path/to/project\"}\n# ```\n\n[crates]\n\n# Some binaries\ncargo = {name = \"cargo\", version = '0.80.0', online_link = 'https://docs.rs/cargo/{version}/src/{file}.html#{line}'}\nripgrep = {name = \"ripgrep\", version = '14.1.0'}\nmdbook = {name = \"mdbook\", version = '0.4.40'}\n\n# Common libraries\nrayon = {name = \"rayon\", version = '1.10.0'}\nserde = {name = \"serde\", version = '1.0.204'}\nbitflags = {name = \"bitflags\", version = '2.6.0'}\nlog = {name = \"log\", version = '0.4.22'}\nquote = {name = \"quote\", version = '1.0.36'}\nproc-macro2 = {name = \"proc-macro2\", version = '1.0.86'}\nrand = {name = \"rand\", version = '0.8.5'}\nrand_core = {name = \"rand_core\", version = '0.6.4'}\nregex = {name = \"regex\", version = '1.10.5'}\nsyn = {name = \"syn\", version = '2.0.71'}\nanyhow = {name = \"anyhow\", version = '1.0.86'}\nasync-trait = { name = 'async-trait', version = '0.1.81' }\ncxx = {name = \"cxx\", version = '1.0.124'}\nryu = {name = \"ryu\", version = '1.0.18'}\nthiserror = {name = \"thiserror\", version = '1.0.63'}\nserde_yaml = {name = \"serde_yaml\", version = '0.9.33'}\npuffin = {name = \"puffin\", version = '0.19.0'}\nbumpalo = {name = \"bumpalo\", version = '3.16.0'}\nwasmi = {name = \"wasmi\", version = '0.35.0'}\nbase64 = { name = 'base64', version = '0.22.1' }\nonce_cell = { name = 'once_cell', version = '1.19.0' }\ntokio = { name = 'tokio', version = '1.38.1' }\n\n[recursive]\nignore = [\n    # Takes ~30s to lint\n    \"combine\",\n    # Has 1.2 million `clippy::match_same_arms`s\n    \"unicode-normalization\",\n]\n"
  },
  {
    "path": "lintcheck/src/config.rs",
    "content": "use clap::{Parser, Subcommand, ValueEnum};\nuse std::num::NonZero;\nuse std::path::PathBuf;\n\n#[expect(clippy::struct_excessive_bools)]\n#[derive(Parser, Clone, Debug)]\n#[command(args_conflicts_with_subcommands = true)]\npub(crate) struct LintcheckConfig {\n    /// Number of threads to use (default: all unless --fix or --recursive)\n    #[clap(\n        long = \"jobs\",\n        short = 'j',\n        value_name = \"N\",\n        default_value_t = 0,\n        default_value_if(\"perf\", \"true\", Some(\"1\")), // Limit jobs to 1 when benchmarking\n        conflicts_with(\"perf\"),\n        required = false,\n        hide_default_value = true\n    )]\n    pub max_jobs: usize,\n    /// Set the path for a crates.toml where lintcheck should read the sources from\n    #[clap(\n        long = \"crates-toml\",\n        value_name = \"CRATES-SOURCES-TOML-PATH\",\n        default_value = \"lintcheck/lintcheck_crates.toml\",\n        hide_default_value = true,\n        env = \"LINTCHECK_TOML\",\n        hide_env = true\n    )]\n    pub sources_toml_path: PathBuf,\n    /// File to save the clippy lint results here\n    #[clap(skip = \"\")]\n    pub lintcheck_results_path: PathBuf, // Overridden in new()\n    /// Only process a single crate on the list\n    #[clap(long, value_name = \"CRATE\")]\n    pub only: Option<String>,\n    /// Runs cargo clippy --fix and checks if all suggestions apply\n    #[clap(long, conflicts_with(\"max_jobs\"))]\n    pub fix: bool,\n    /// Apply a filter to only collect specified lints\n    #[clap(long = \"filter\", value_name = \"clippy_lint_name\", use_value_delimiter = true)]\n    pub lint_filter: Vec<String>,\n    /// Check all Clippy lints, by default only `clippy::all` and `clippy::pedantic` are checked.\n    /// Usually, it's better to use `--filter` instead\n    #[clap(long, conflicts_with(\"lint_filter\"))]\n    pub all_lints: bool,\n    /// Set the output format of the log file\n    #[clap(long, short, default_value = \"text\")]\n    pub format: OutputFormat,\n    /// Run clippy on the dependencies of crates specified in crates-toml\n    #[clap(long, conflicts_with(\"max_jobs\"))]\n    pub recursive: bool,\n    /// Also produce a `perf.data` file, implies --jobs=1,\n    /// the `perf.data` file can be found at\n    /// `target/lintcheck/sources/<package>-<version>/perf.data`\n    #[clap(long)]\n    pub perf: bool,\n    #[command(subcommand)]\n    pub subcommand: Option<Commands>,\n}\n\n#[derive(Subcommand, Clone, Debug)]\npub(crate) enum Commands {\n    /// Display a markdown diff between two lintcheck log files in JSON format\n    Diff {\n        old: PathBuf,\n        new: PathBuf,\n        /// This will limit the number of warnings that will be printed for each lint\n        #[clap(long)]\n        truncate: bool,\n        /// Write the diff summary to a JSON file if there are any changes\n        #[clap(long, value_name = \"PATH\")]\n        write_summary: Option<PathBuf>,\n    },\n    /// Create a lintcheck crates TOML file containing the top N popular crates\n    Popular {\n        /// Output TOML file name\n        output: PathBuf,\n        /// Number of crate names to download\n        #[clap(short, long, default_value_t = 100)]\n        number: usize,\n    },\n}\n\n#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq)]\npub(crate) enum OutputFormat {\n    Text,\n    Markdown,\n    Json,\n}\n\nimpl OutputFormat {\n    fn file_extension(self) -> &'static str {\n        match self {\n            OutputFormat::Text => \"txt\",\n            OutputFormat::Markdown => \"md\",\n            OutputFormat::Json => \"json\",\n        }\n    }\n}\n\nimpl LintcheckConfig {\n    pub fn new() -> Self {\n        let mut config = LintcheckConfig::parse();\n\n        // for the path where we save the lint results, get the filename without extension (so for\n        // wasd.toml, use \"wasd\"...)\n        let filename: PathBuf = config.sources_toml_path.file_stem().unwrap().into();\n        config.lintcheck_results_path = PathBuf::from(format!(\n            \"lintcheck-logs/{}_logs.{}\",\n            filename.display(),\n            config.format.file_extension(),\n        ));\n\n        // look at the --threads arg, if 0 is passed, use the threads count\n        if config.max_jobs == 0 {\n            config.max_jobs = if config.fix || config.recursive {\n                1\n            } else {\n                std::thread::available_parallelism().map_or(1, NonZero::get)\n            };\n        }\n\n        for lint_name in &mut config.lint_filter {\n            *lint_name = format!(\n                \"clippy::{}\",\n                lint_name\n                    .strip_prefix(\"clippy::\")\n                    .unwrap_or(lint_name)\n                    .replace('_', \"-\")\n            );\n        }\n\n        config\n    }\n}\n"
  },
  {
    "path": "lintcheck/src/driver.rs",
    "content": "use crate::recursive::{DriverInfo, deserialize_line, serialize_line};\n\nuse std::io::{self, BufReader, Write};\nuse std::net::TcpStream;\nuse std::process::{self, Command, Stdio};\nuse std::{env, mem};\n\n/// 1. Sends [`DriverInfo`] to the [`crate::recursive::LintcheckServer`] running on `addr`\n/// 2. Receives [bool] from the server, if `false` returns `None`\n/// 3. Otherwise sends the stderr of running `clippy-driver` to the server\nfn run_clippy(addr: &str) -> Option<i32> {\n    let driver_info = DriverInfo {\n        package_name: env::var(\"CARGO_PKG_NAME\").ok()?,\n        version: env::var(\"CARGO_PKG_VERSION\").ok()?,\n    };\n\n    let mut stream = BufReader::new(TcpStream::connect(addr).unwrap());\n\n    serialize_line(&driver_info, stream.get_mut());\n\n    let should_run = deserialize_line::<bool, _>(&mut stream);\n    if !should_run {\n        return None;\n    }\n\n    // Remove --cap-lints allow so that clippy runs and lints are emitted\n    let mut include_next = true;\n    let args = env::args().skip(1).filter(|arg| match arg.as_str() {\n        \"--cap-lints=allow\" => false,\n        \"--cap-lints\" => {\n            include_next = false;\n            false\n        },\n        _ => mem::replace(&mut include_next, true),\n    });\n\n    let output = Command::new(env::var(\"CLIPPY_DRIVER\").expect(\"missing env CLIPPY_DRIVER\"))\n        .args(args)\n        .stdout(Stdio::inherit())\n        .output()\n        .expect(\"failed to run clippy-driver\");\n\n    stream\n        .get_mut()\n        .write_all(&output.stderr)\n        .unwrap_or_else(|e| panic!(\"{e:?} in {driver_info:?}\"));\n\n    match output.status.code() {\n        Some(0) => Some(0),\n        code => {\n            io::stderr().write_all(&output.stderr).unwrap();\n            Some(code.expect(\"killed by signal\"))\n        },\n    }\n}\n\npub fn drive(addr: &str) {\n    process::exit(run_clippy(addr).unwrap_or_else(|| {\n        Command::new(\"rustc\")\n            .args(env::args_os().skip(2))\n            .status()\n            .unwrap()\n            .code()\n            .unwrap()\n    }))\n}\n"
  },
  {
    "path": "lintcheck/src/input.rs",
    "content": "use std::collections::{HashMap, HashSet};\nuse std::fs::{self};\nuse std::io::{self, ErrorKind};\nuse std::path::{Path, PathBuf};\nuse std::process::Command;\nuse std::time::Duration;\n\nuse serde::Deserialize;\nuse walkdir::{DirEntry, WalkDir};\n\nuse crate::{Crate, lintcheck_sources, target_dir};\n\nconst DEFAULT_DOCS_LINK: &str = \"https://docs.rs/{krate}/{version}/src/{krate_}/{file}.html#{line}\";\nconst DEFAULT_GITHUB_LINK: &str = \"{url}/blob/{hash}/src/{file}#L{line}\";\nconst DEFAULT_PATH_LINK: &str = \"{path}/src/{file}:{line}\";\n\n/// List of sources to check, loaded from a .toml file\n#[derive(Debug, Deserialize)]\npub struct SourceList {\n    crates: HashMap<String, TomlCrate>,\n    #[serde(default)]\n    recursive: RecursiveOptions,\n}\n\n#[derive(Debug, Deserialize, Default)]\npub struct RecursiveOptions {\n    pub ignore: HashSet<String>,\n}\n\n/// A crate source stored inside the .toml\n/// will be translated into on one of the `CrateSource` variants\n#[derive(Debug, Deserialize)]\nstruct TomlCrate {\n    name: String,\n    version: Option<String>,\n    git_url: Option<String>,\n    git_hash: Option<String>,\n    path: Option<String>,\n    options: Option<Vec<String>>,\n    /// Magic values:\n    /// * `{krate}` will be replaced by `self.name`\n    /// * `{krate_}` will be replaced by `self.name` with all `-` replaced by `_`\n    /// * `{version}` will be replaced by `self.version`\n    /// * `{url}` will be replaced with `self.git_url`\n    /// * `{hash}` will be replaced with `self.git_hash`\n    /// * `{path}` will be replaced with `self.path`\n    /// * `{file}` will be replaced by the path after `src/`\n    /// * `{line}` will be replaced by the line\n    ///\n    /// If unset, this will be filled by [`read_crates`] since it depends on\n    /// the source.\n    online_link: Option<String>,\n}\n\nimpl TomlCrate {\n    fn file_link(&self, default: &str) -> String {\n        let mut link = self.online_link.clone().unwrap_or_else(|| default.to_string());\n        link = link.replace(\"{krate}\", &self.name);\n        link = link.replace(\"{krate_}\", &self.name.replace('-', \"_\"));\n\n        if let Some(version) = &self.version {\n            link = link.replace(\"{version}\", version);\n        }\n        if let Some(url) = &self.git_url {\n            link = link.replace(\"{url}\", url);\n        }\n        if let Some(hash) = &self.git_hash {\n            link = link.replace(\"{hash}\", hash);\n        }\n        if let Some(path) = &self.path {\n            link = link.replace(\"{path}\", path);\n        }\n        link\n    }\n}\n\n/// Represents an archive we download from crates.io, or a git repo, or a local repo/folder\n/// Once processed (downloaded/extracted/cloned/copied...), this will be translated into a `Crate`\n#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Ord, PartialOrd)]\npub struct CrateWithSource {\n    pub name: String,\n    pub source: CrateSource,\n    pub file_link: String,\n    pub options: Option<Vec<String>>,\n}\n\n#[derive(Debug, Deserialize, Eq, Hash, PartialEq, Ord, PartialOrd)]\npub enum CrateSource {\n    CratesIo { version: String },\n    Git { url: String, commit: String },\n    Path { path: PathBuf },\n}\n\n/// Read a `lintcheck_crates.toml` file\npub fn read_crates(toml_path: &Path) -> (Vec<CrateWithSource>, RecursiveOptions) {\n    let toml_content: String =\n        fs::read_to_string(toml_path).unwrap_or_else(|_| panic!(\"Failed to read {}\", toml_path.display()));\n    let crate_list: SourceList =\n        toml::from_str(&toml_content).unwrap_or_else(|e| panic!(\"Failed to parse {}: \\n{e}\", toml_path.display()));\n    // parse the hashmap of the toml file into a list of crates\n    let toml_crates: Vec<TomlCrate> = crate_list.crates.into_values().collect();\n\n    // flatten TomlCrates into CrateSources (one TomlCrates may represent several versions of a crate =>\n    // multiple CrateSources)\n    let mut crate_sources = Vec::new();\n    for tk in toml_crates {\n        if let Some(ref path) = tk.path {\n            crate_sources.push(CrateWithSource {\n                name: tk.name.clone(),\n                source: CrateSource::Path {\n                    path: PathBuf::from(path),\n                },\n                file_link: tk.file_link(DEFAULT_PATH_LINK),\n                options: tk.options.clone(),\n            });\n        } else if let Some(ref version) = tk.version {\n            crate_sources.push(CrateWithSource {\n                name: tk.name.clone(),\n                source: CrateSource::CratesIo {\n                    version: version.clone(),\n                },\n                file_link: tk.file_link(DEFAULT_DOCS_LINK),\n                options: tk.options.clone(),\n            });\n        } else if tk.git_url.is_some() && tk.git_hash.is_some() {\n            // otherwise, we should have a git source\n            crate_sources.push(CrateWithSource {\n                name: tk.name.clone(),\n                source: CrateSource::Git {\n                    url: tk.git_url.clone().unwrap(),\n                    commit: tk.git_hash.clone().unwrap(),\n                },\n                file_link: tk.file_link(DEFAULT_GITHUB_LINK),\n                options: tk.options.clone(),\n            });\n        } else {\n            panic!(\"Invalid crate source: {tk:?}\");\n        }\n\n        // if we have a version as well as a git data OR only one git data, something is funky\n        if tk.version.is_some() && (tk.git_url.is_some() || tk.git_hash.is_some())\n            || tk.git_hash.is_some() != tk.git_url.is_some()\n        {\n            eprintln!(\"tomlkrate: {tk:?}\");\n            assert_eq!(\n                tk.git_hash.is_some(),\n                tk.git_url.is_some(),\n                \"Error: Encountered TomlCrate with only one of git_hash and git_url!\"\n            );\n            assert!(\n                tk.path.is_none() || (tk.git_hash.is_none() && tk.version.is_none()),\n                \"Error: TomlCrate can only have one of 'git_.*', 'version' or 'path' fields\"\n            );\n            unreachable!(\"Failed to translate TomlCrate into CrateSource!\");\n        }\n    }\n    // sort the crates\n    crate_sources.sort();\n\n    (crate_sources, crate_list.recursive)\n}\n\nimpl CrateWithSource {\n    pub fn download_and_prepare(&self) -> Crate {\n        let krate = self.download_and_extract();\n\n        // Downloaded crates might contain a `rust-toolchain` file. This file\n        // seems to be accessed when `build.rs` files are present. This access\n        // results in build errors since lintcheck and clippy will most certainly\n        // use a different toolchain.\n        // Lintcheck simply removes these files and assumes that our toolchain\n        // is more up to date.\n        let _ = fs::remove_file(krate.path.join(\"rust-toolchain\"));\n        let _ = fs::remove_file(krate.path.join(\"rust-toolchain.toml\"));\n\n        krate\n    }\n    /// Makes the sources available on the disk for clippy to check.\n    /// Clones a git repo and checks out the specified commit or downloads a crate from crates.io or\n    /// copies a local folder\n    #[expect(clippy::too_many_lines)]\n    fn download_and_extract(&self) -> Crate {\n        #[expect(clippy::result_large_err)]\n        fn get(path: &str) -> Result<ureq::Response, ureq::Error> {\n            const MAX_RETRIES: u8 = 4;\n            let mut retries = 0;\n            loop {\n                match ureq::get(path).call() {\n                    Ok(res) => return Ok(res),\n                    Err(e) if retries >= MAX_RETRIES => return Err(e),\n                    Err(ureq::Error::Transport(e)) => eprintln!(\"Error: {e}\"),\n                    Err(e) => return Err(e),\n                }\n                eprintln!(\"retrying in {retries} seconds...\");\n                std::thread::sleep(Duration::from_secs(u64::from(retries)));\n                retries += 1;\n            }\n        }\n        let name = &self.name;\n        let options = &self.options;\n        let file_link = &self.file_link;\n        match &self.source {\n            CrateSource::CratesIo { version } => {\n                let extract_dir = PathBuf::from(lintcheck_sources());\n                // Keep constant downloads path to avoid repeating work and\n                // filling up disk space unnecessarily.\n                let krate_download_dir = PathBuf::from(\"target/lintcheck/downloads/\");\n\n                // url to download the crate from crates.io\n                let url = format!(\"https://crates.io/api/v1/crates/{name}/{version}/download\");\n                println!(\"Downloading and extracting {name} {version} from {url}\");\n                create_dirs(&krate_download_dir, &extract_dir);\n\n                let krate_file_path = krate_download_dir.join(format!(\"{name}-{version}.crate.tar.gz\"));\n                // don't download/extract if we already have done so\n                if !krate_file_path.is_file() || !extract_dir.join(format!(\"{name}-{version}\")).exists() {\n                    // create a file path to download and write the crate data into\n                    let mut krate_dest = fs::File::create(&krate_file_path).unwrap();\n                    let mut krate_req = get(&url).unwrap().into_reader();\n                    // copy the crate into the file\n                    io::copy(&mut krate_req, &mut krate_dest).unwrap();\n\n                    // unzip the tarball\n                    let ungz_tar = flate2::read::GzDecoder::new(fs::File::open(&krate_file_path).unwrap());\n                    // extract the tar archive\n                    let mut archive = tar::Archive::new(ungz_tar);\n                    archive.unpack(&extract_dir).expect(\"Failed to extract!\");\n                }\n                // crate is extracted, return a new Krate object which contains the path to the extracted\n                // sources that clippy can check\n                Crate {\n                    version: version.clone(),\n                    name: name.clone(),\n                    path: extract_dir.join(format!(\"{name}-{version}/\")),\n                    options: options.clone(),\n                    base_url: file_link.clone(),\n                }\n            },\n            CrateSource::Git { url, commit } => {\n                let repo_path = {\n                    let mut repo_path = PathBuf::from(lintcheck_sources());\n                    // add a -git suffix in case we have the same crate from crates.io and a git repo\n                    repo_path.push(format!(\"{name}-git\"));\n                    repo_path\n                };\n                // clone the repo if we have not done so\n                if !repo_path.is_dir() {\n                    println!(\"Cloning {url} and checking out {commit}\");\n                    if !Command::new(\"git\")\n                        .arg(\"clone\")\n                        .arg(url)\n                        .arg(&repo_path)\n                        .status()\n                        .expect(\"Failed to clone git repo!\")\n                        .success()\n                    {\n                        eprintln!(\"Failed to clone {url} into {}\", repo_path.display());\n                    }\n                }\n                // check out the commit/branch/whatever\n                if !Command::new(\"git\")\n                    .args([\"-c\", \"advice.detachedHead=false\"])\n                    .arg(\"checkout\")\n                    .arg(commit)\n                    .current_dir(&repo_path)\n                    .status()\n                    .expect(\"Failed to check out commit\")\n                    .success()\n                {\n                    eprintln!(\"Failed to checkout {commit} of repo at {}\", repo_path.display());\n                }\n\n                Crate {\n                    version: commit.clone(),\n                    name: name.clone(),\n                    path: repo_path,\n                    options: options.clone(),\n                    base_url: file_link.clone(),\n                }\n            },\n            CrateSource::Path { path } => {\n                fn is_cache_dir(entry: &DirEntry) -> bool {\n                    fs::read(entry.path().join(\"CACHEDIR.TAG\"))\n                        .is_ok_and(|x| x.starts_with(b\"Signature: 8a477f597d28d172789f06886806bc55\"))\n                }\n\n                // copy path into the dest_crate_root but skip directories that contain a CACHEDIR.TAG file.\n                // The target/ directory contains a CACHEDIR.TAG file so it is the most commonly skipped directory\n                // as a result of this filter.\n                let dest_crate_root = PathBuf::from(lintcheck_sources()).join(name);\n                if dest_crate_root.exists() {\n                    println!(\"Deleting existing directory at `{}`\", dest_crate_root.display());\n                    fs::remove_dir_all(&dest_crate_root).unwrap();\n                }\n\n                println!(\"Copying `{}` to `{}`\", path.display(), dest_crate_root.display());\n\n                for entry in WalkDir::new(path).into_iter().filter_entry(|e| !is_cache_dir(e)) {\n                    let entry = entry.unwrap();\n                    let entry_path = entry.path();\n                    let relative_entry_path = entry_path.strip_prefix(path).unwrap();\n                    let dest_path = dest_crate_root.join(relative_entry_path);\n                    let metadata = entry_path.symlink_metadata().unwrap();\n\n                    if metadata.is_dir() {\n                        fs::create_dir(dest_path).unwrap();\n                    } else if metadata.is_file() {\n                        fs::copy(entry_path, dest_path).unwrap();\n                    }\n                }\n\n                Crate {\n                    version: String::from(\"local\"),\n                    name: name.clone(),\n                    path: dest_crate_root,\n                    options: options.clone(),\n                    base_url: file_link.clone(),\n                }\n            },\n        }\n    }\n}\n\n/// Create necessary directories to run the lintcheck tool.\n///\n/// # Panics\n///\n/// This function panics if creating one of the dirs fails.\nfn create_dirs(krate_download_dir: &Path, extract_dir: &Path) {\n    fs::create_dir(format!(\"{}/lintcheck/\", target_dir())).unwrap_or_else(|err| {\n        assert_eq!(\n            err.kind(),\n            ErrorKind::AlreadyExists,\n            \"cannot create lintcheck target dir\"\n        );\n    });\n    fs::create_dir_all(krate_download_dir).unwrap_or_else(|err| {\n        // We are allowed to reuse download dirs\n        assert_ne!(err.kind(), ErrorKind::AlreadyExists);\n    });\n    fs::create_dir(extract_dir).unwrap_or_else(|err| {\n        assert_eq!(\n            err.kind(),\n            ErrorKind::AlreadyExists,\n            \"cannot create crate extraction dir\"\n        );\n    });\n}\n"
  },
  {
    "path": "lintcheck/src/json.rs",
    "content": "//! JSON output and comparison functionality for Clippy warnings.\n//!\n//! This module handles serialization of Clippy warnings to JSON format,\n//! loading warnings from JSON files, and generating human-readable diffs\n//! between different linting runs.\n\nuse std::path::{Path, PathBuf};\nuse std::{fmt, fs};\n\nuse itertools::{EitherOrBoth, Itertools};\nuse serde::{Deserialize, Serialize};\n\nuse crate::ClippyWarning;\n\n/// This is the total number. 300 warnings results in 100 messages per section.\nconst DEFAULT_LIMIT_PER_LINT: usize = 300;\n/// Target for total warnings to display across all lints when truncating output.\nconst TRUNCATION_TOTAL_TARGET: usize = 1000;\n\n#[derive(Debug, Deserialize, Serialize)]\nstruct LintJson {\n    /// The lint name e.g. `clippy::bytes_nth`\n    name: String,\n    /// The filename and line number e.g. `anyhow-1.0.86/src/error.rs:42`\n    file_line: String,\n    file_url: String,\n    rendered: String,\n}\n\nimpl LintJson {\n    fn key(&self) -> impl Ord + '_ {\n        (self.name.as_str(), self.file_line.as_str())\n    }\n\n    /// Formats the warning information with an action verb for display.\n    fn info_text(&self, action: &str) -> String {\n        format!(\"{action} `{}` at [`{}`]({})\", self.name, self.file_line, self.file_url)\n    }\n}\n\n#[derive(Debug, Serialize)]\nstruct SummaryRow {\n    name: String,\n    added: usize,\n    removed: usize,\n    changed: usize,\n}\n\n#[derive(Debug, Serialize)]\nstruct Summary(Vec<SummaryRow>);\n\nimpl fmt::Display for Summary {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.write_str(\n            \"\\\n| Lint | Added | Removed | Changed |\n| ---- | ----: | ------: | ------: |\n\",\n        )?;\n\n        for SummaryRow {\n            name,\n            added,\n            changed,\n            removed,\n        } in &self.0\n        {\n            let html_id = to_html_id(name);\n            writeln!(f, \"| [`{name}`](#{html_id}) | {added} | {removed} | {changed} |\")?;\n        }\n\n        Ok(())\n    }\n}\n\nimpl Summary {\n    fn new(lints: &[LintWarnings]) -> Self {\n        Summary(\n            lints\n                .iter()\n                .map(|lint| SummaryRow {\n                    name: lint.name.clone(),\n                    added: lint.added.len(),\n                    removed: lint.removed.len(),\n                    changed: lint.changed.len(),\n                })\n                .collect(),\n        )\n    }\n}\n\n/// Creates the log file output for [`crate::config::OutputFormat::Json`]\npub(crate) fn output(clippy_warnings: Vec<ClippyWarning>) -> String {\n    let mut lints: Vec<LintJson> = clippy_warnings\n        .into_iter()\n        .map(|warning| {\n            let span = warning.span();\n            let file_name = span\n                .file_name\n                .strip_prefix(\"target/lintcheck/sources/\")\n                .unwrap_or(&span.file_name);\n            let file_line = format!(\"{file_name}:{}\", span.line_start);\n            LintJson {\n                name: warning.name,\n                file_line,\n                file_url: warning.url,\n                rendered: warning.diag.rendered.unwrap().trim().to_string(),\n            }\n        })\n        .collect();\n    lints.sort_by(|a, b| a.key().cmp(&b.key()));\n    serde_json::to_string(&lints).unwrap()\n}\n\n/// Loads lint warnings from a JSON file at the given path.\nfn load_warnings(path: &Path) -> Vec<LintJson> {\n    let file = fs::read(path).unwrap_or_else(|e| panic!(\"failed to read {}: {e}\", path.display()));\n\n    serde_json::from_slice(&file).unwrap_or_else(|e| panic!(\"failed to deserialize {}: {e}\", path.display()))\n}\n\n/// Generates and prints a diff between two sets of lint warnings.\n///\n/// Compares warnings from `old_path` and `new_path`, then displays a summary table\n/// and detailed information about added, removed, and changed warnings.\npub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool, write_summary: Option<PathBuf>) {\n    let old_warnings = load_warnings(old_path);\n    let new_warnings = load_warnings(new_path);\n\n    let mut lint_warnings = vec![];\n\n    for (name, changes) in &itertools::merge_join_by(old_warnings, new_warnings, |old, new| old.key().cmp(&new.key()))\n        .chunk_by(|change| change.as_ref().into_left().name.clone())\n    {\n        let mut added = Vec::new();\n        let mut removed = Vec::new();\n        let mut changed = Vec::new();\n        for change in changes {\n            match change {\n                EitherOrBoth::Both(old, new) => {\n                    if old.rendered != new.rendered {\n                        changed.push((old, new));\n                    }\n                },\n                EitherOrBoth::Left(old) => removed.push(old),\n                EitherOrBoth::Right(new) => added.push(new),\n            }\n        }\n\n        if !added.is_empty() || !removed.is_empty() || !changed.is_empty() {\n            lint_warnings.push(LintWarnings {\n                name,\n                added,\n                removed,\n                changed,\n            });\n        }\n    }\n\n    if lint_warnings.is_empty() {\n        return;\n    }\n\n    let summary = Summary::new(&lint_warnings);\n    if let Some(path) = write_summary {\n        let json = serde_json::to_string(&summary).unwrap();\n        fs::write(path, json).unwrap();\n    }\n\n    let truncate_after = if truncate {\n        // Max 15 ensures that we at least have five messages per lint\n        DEFAULT_LIMIT_PER_LINT\n            .min(TRUNCATION_TOTAL_TARGET / lint_warnings.len())\n            .max(15)\n    } else {\n        // No lint should ever each this number of lint emissions, so this is equivialent to\n        // No truncation\n        usize::MAX\n    };\n\n    println!(\"{summary}\");\n    for lint in lint_warnings {\n        print_lint_warnings(&lint, truncate_after);\n    }\n}\n\n/// Container for grouped lint warnings organized by status (added/removed/changed).\n#[derive(Debug)]\nstruct LintWarnings {\n    name: String,\n    added: Vec<LintJson>,\n    removed: Vec<LintJson>,\n    changed: Vec<(LintJson, LintJson)>,\n}\n\nfn print_lint_warnings(lint: &LintWarnings, truncate_after: usize) {\n    let name = &lint.name;\n    let html_id = to_html_id(name);\n\n    println!(r#\"<h2 id=\"{html_id}\"><code>{name}</code></h2>\"#);\n    println!();\n\n    print!(\n        r\"{}, {}, {}\",\n        count_string(name, \"added\", lint.added.len()),\n        count_string(name, \"removed\", lint.removed.len()),\n        count_string(name, \"changed\", lint.changed.len()),\n    );\n    println!();\n\n    print_warnings(\"Added\", &lint.added, truncate_after / 3);\n    print_warnings(\"Removed\", &lint.removed, truncate_after / 3);\n    print_changed_diff(&lint.changed, truncate_after / 3);\n}\n\n/// Prints a section of warnings with a header and formatted code blocks.\nfn print_warnings(title: &str, warnings: &[LintJson], truncate_after: usize) {\n    if warnings.is_empty() {\n        return;\n    }\n\n    print_h3(&warnings[0].name, title);\n    println!();\n\n    let warnings = truncate(warnings, truncate_after);\n\n    for warning in warnings {\n        println!(\"{}\", warning.info_text(title));\n        println!();\n        println!(\"```\");\n        println!(\"{}\", warning.rendered);\n        println!(\"```\");\n        println!();\n    }\n}\n\n/// Prints a section of changed warnings with unified diff format.\nfn print_changed_diff(changed: &[(LintJson, LintJson)], truncate_after: usize) {\n    if changed.is_empty() {\n        return;\n    }\n\n    print_h3(&changed[0].0.name, \"Changed\");\n    println!();\n\n    let changed = truncate(changed, truncate_after);\n\n    for (old, new) in changed {\n        println!(\"{}\", new.info_text(\"Changed\"));\n        println!();\n        println!(\"```diff\");\n        for change in diff::lines(&old.rendered, &new.rendered) {\n            use diff::Result::{Both, Left, Right};\n\n            match change {\n                Both(unchanged, _) => {\n                    println!(\" {unchanged}\");\n                },\n                Left(removed) => {\n                    println!(\"-{removed}\");\n                },\n                Right(added) => {\n                    println!(\"+{added}\");\n                },\n            }\n        }\n        println!(\"```\");\n    }\n}\n\n/// Truncates a list to a maximum number of items and prints a message about truncation.\nfn truncate<T>(list: &[T], truncate_after: usize) -> &[T] {\n    if list.len() > truncate_after {\n        println!(\n            \"{} warnings have been truncated for this summary.\",\n            list.len() - truncate_after\n        );\n        println!();\n\n        list.split_at(truncate_after).0\n    } else {\n        list\n    }\n}\n\nfn print_h3(lint: &str, title: &str) {\n    let html_id = to_html_id(lint);\n    // We have to use HTML here to be able to manually add an id, GitHub doesn't add them automatically\n    println!(r#\"<h3 id=\"{html_id}-{title}\">{title}</h3>\"#);\n}\n\n/// Creates a custom ID allowed by GitHub, they must start with `user-content-` and cannot contain\n/// `::`/`_`\nfn to_html_id(lint_name: &str) -> String {\n    lint_name.replace(\"clippy::\", \"user-content-\").replace('_', \"-\")\n}\n\n/// This generates the `x added` string for the start of the job summery.\n/// It linkifies them if possible to jump to the respective heading.\nfn count_string(lint: &str, label: &str, count: usize) -> String {\n    // Headlines are only added, if anything will be displayed under the headline.\n    // We therefore only want to add links to them if they exist\n    if count == 0 {\n        format!(\"0 {label}\")\n    } else {\n        let html_id = to_html_id(lint);\n        format!(\"[{count} {label}](#{html_id}-{label})\")\n    }\n}\n"
  },
  {
    "path": "lintcheck/src/main.rs",
    "content": "// Run clippy on a fixed set of crates and collect the warnings.\n// This helps observing the impact clippy changes have on a set of real-world code (and not just our\n// testsuite).\n//\n// When a new lint is introduced, we can search the results for new warnings and check for false\n// positives.\n\n#![feature(iter_collect_into)]\n#![warn(\n    trivial_casts,\n    trivial_numeric_casts,\n    rust_2018_idioms,\n    unused_lifetimes,\n    unused_qualifications\n)]\n#![allow(\n    clippy::collapsible_else_if,\n    clippy::needless_borrows_for_generic_args,\n    clippy::module_name_repetitions,\n    clippy::literal_string_with_formatting_args\n)]\n\nmod config;\nmod driver;\nmod input;\nmod json;\nmod output;\nmod popular_crates;\nmod recursive;\n\nuse crate::config::{Commands, LintcheckConfig, OutputFormat};\nuse crate::recursive::LintcheckServer;\n\nuse std::env::consts::EXE_SUFFIX;\nuse std::io::{self};\nuse std::path::{Path, PathBuf};\nuse std::process::{Command, Stdio};\nuse std::sync::atomic::{AtomicUsize, Ordering};\nuse std::{env, fs};\n\nuse cargo_metadata::Message;\nuse input::read_crates;\nuse output::{ClippyCheckOutput, ClippyWarning, RustcIce};\nuse rayon::prelude::*;\n\n#[must_use]\npub fn target_dir() -> String {\n    env::var(\"CARGO_TARGET_DIR\").unwrap_or_else(|_| \"target\".to_owned())\n}\n\nfn lintcheck_sources() -> String {\n    format!(\"{}/lintcheck/sources\", target_dir())\n}\n\n/// Represents the actual source code of a crate that we ran \"cargo clippy\" on\n#[derive(Debug)]\nstruct Crate {\n    version: String,\n    name: String,\n    // path to the extracted sources that clippy can check\n    path: PathBuf,\n    options: Option<Vec<String>>,\n    base_url: String,\n}\n\nimpl Crate {\n    /// Run `cargo clippy` on the `Crate` and collect and return all the lint warnings that clippy\n    /// issued\n    #[expect(clippy::too_many_lines)]\n    fn run_clippy_lints(\n        &self,\n        clippy_driver_path: &Path,\n        target_dir_index: &AtomicUsize,\n        total_crates_to_lint: usize,\n        config: &LintcheckConfig,\n        lint_levels_args: &[String],\n        server: Option<&LintcheckServer>,\n    ) -> Vec<ClippyCheckOutput> {\n        // advance the atomic index by one\n        let index = target_dir_index.fetch_add(1, Ordering::SeqCst);\n        // \"loop\" the index within 0..thread_limit\n        let thread_index = index % config.max_jobs;\n        let perc = (index * 100) / total_crates_to_lint;\n\n        if config.max_jobs == 1 {\n            println!(\n                \"{index}/{total_crates_to_lint} {perc}% Linting {} {}\",\n                &self.name, &self.version\n            );\n        } else {\n            println!(\n                \"{index}/{total_crates_to_lint} {perc}% Linting {} {} in target dir {thread_index:?}\",\n                &self.name, &self.version\n            );\n        }\n\n        let cargo_home = env!(\"CARGO_HOME\");\n\n        // `src/lib.rs` -> `target/lintcheck/sources/crate-1.2.3/src/lib.rs`\n        let remap_relative = format!(\"={}\", self.path.display());\n        // Fallback for other sources, `~/.cargo/...` -> `$CARGO_HOME/...`\n        let remap_cargo_home = format!(\"{cargo_home}=$CARGO_HOME\");\n        // `~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/crate-2.3.4/src/lib.rs`\n        //     -> `crate-2.3.4/src/lib.rs`\n        let remap_crates_io = format!(\"{cargo_home}/registry/src/index.crates.io-6f17d22bba15001f/=\");\n\n        let mut clippy_args = vec![\n            \"--remap-path-prefix\",\n            &remap_relative,\n            \"--remap-path-prefix\",\n            &remap_cargo_home,\n            \"--remap-path-prefix\",\n            &remap_crates_io,\n        ];\n\n        if let Some(options) = &self.options {\n            for opt in options {\n                clippy_args.push(opt);\n            }\n        }\n\n        clippy_args.extend(lint_levels_args.iter().map(String::as_str));\n\n        let mut cmd;\n\n        if config.perf {\n            cmd = Command::new(\"perf\");\n            let perf_data_filename = get_perf_data_filename(&self.path);\n            cmd.args(&[\n                \"record\",\n                \"-e\",\n                \"instructions\", // Only count instructions\n                \"-g\",           // Enable call-graph, useful for flamegraphs and produces richer reports\n                \"--quiet\",      // Do not tamper with lintcheck's normal output\n                \"--compression-level=22\",\n                \"--freq=3000\", // Slow down program to capture all events\n                \"-o\",\n                &perf_data_filename,\n                \"--\",\n                \"cargo\",\n            ]);\n        } else {\n            cmd = Command::new(\"cargo\");\n        }\n\n        cmd.arg(if config.fix { \"fix\" } else { \"check\" })\n            .arg(\"--quiet\")\n            .current_dir(&self.path)\n            .env(\"CLIPPY_ARGS\", clippy_args.join(\"__CLIPPY_HACKERY__\"))\n            .env(\"CLIPPY_DISABLE_DOCS_LINKS\", \"1\");\n\n        if let Some(server) = server {\n            // `cargo clippy` is a wrapper around `cargo check` that mainly sets `RUSTC_WORKSPACE_WRAPPER` to\n            // `clippy-driver`. We do the same thing here with a couple changes:\n            //\n            // `RUSTC_WRAPPER` is used instead of `RUSTC_WORKSPACE_WRAPPER` so that we can lint all crate\n            // dependencies rather than only workspace members\n            //\n            // The wrapper is set to `lintcheck` itself so we can force enable linting and ignore certain crates\n            // (see `crate::driver`)\n            let status = cmd\n                .env(\"CARGO_TARGET_DIR\", shared_target_dir(\"recursive\"))\n                .env(\"RUSTC_WRAPPER\", env::current_exe().unwrap())\n                // Pass the absolute path so `crate::driver` can find `clippy-driver`, as it's executed in various\n                // different working directories\n                .env(\"CLIPPY_DRIVER\", clippy_driver_path)\n                .env(\"LINTCHECK_SERVER\", server.local_addr.to_string())\n                .status()\n                .expect(\"failed to run cargo\");\n\n            assert_eq!(status.code(), Some(0));\n\n            return Vec::new();\n        }\n\n        if !config.fix && !config.perf {\n            cmd.arg(\"--message-format=json\");\n        }\n\n        let shared_target_dir = shared_target_dir(&format!(\"_{thread_index:?}\"));\n        let all_output = cmd\n            // use the looping index to create individual target dirs\n            .env(\"CARGO_TARGET_DIR\", shared_target_dir.as_os_str())\n            // Roughly equivalent to `cargo clippy`/`cargo clippy --fix`\n            .env(\"RUSTC_WORKSPACE_WRAPPER\", clippy_driver_path)\n            .output()\n            .unwrap();\n        let stdout = String::from_utf8_lossy(&all_output.stdout);\n        let stderr = String::from_utf8_lossy(&all_output.stderr);\n        let status = &all_output.status;\n\n        if !status.success() {\n            eprintln!(\n                \"\\nWARNING: bad exit status after checking {} {} \\n\",\n                self.name, self.version\n            );\n        }\n\n        if config.fix {\n            if let Some(stderr) = stderr\n                .lines()\n                .find(|line| line.contains(\"failed to automatically apply fixes suggested by rustc to crate\"))\n            {\n                let subcrate = &stderr[63..];\n                println!(\n                    \"ERROR: failed to apply some suggestion to {} / to (sub)crate {subcrate}\",\n                    self.name\n                );\n            }\n            // fast path, we don't need the warnings anyway\n            return Vec::new();\n        }\n\n        // We don't want to keep target directories if benchmarking\n        if config.perf {\n            let _ = fs::remove_dir_all(&shared_target_dir);\n        }\n\n        // get all clippy warnings and ICEs\n        let mut entries: Vec<ClippyCheckOutput> = Message::parse_stream(stdout.as_bytes())\n            .filter_map(|msg| match msg {\n                Ok(Message::CompilerMessage(message)) => ClippyWarning::new(\n                    normalize_diag(message.message, shared_target_dir.to_str().unwrap()),\n                    &self.base_url,\n                    &self.name,\n                ),\n                _ => None,\n            })\n            .map(ClippyCheckOutput::ClippyWarning)\n            .collect();\n\n        if let Some(ice) = RustcIce::from_stderr_and_status(&self.name, *status, &stderr) {\n            entries.push(ClippyCheckOutput::RustcIce(ice));\n        } else if !status.success() {\n            println!(\"non-ICE bad exit status for {} {}: {}\", self.name, self.version, stderr);\n        }\n\n        entries\n    }\n}\n\n/// The target directory can sometimes be stored in the file name of spans.\n/// This is problematic since the directory in constructed from the thread\n/// ID and also used in our CI to determine if two lint emissions are the\n/// same or not. This function simply normalizes the `_<thread_id>` to `_*`.\nfn normalize_diag(\n    mut message: cargo_metadata::diagnostic::Diagnostic,\n    thread_target_dir: &str,\n) -> cargo_metadata::diagnostic::Diagnostic {\n    let mut dir_found = false;\n    message\n        .spans\n        .iter_mut()\n        .filter(|span| span.file_name.starts_with(thread_target_dir))\n        .for_each(|span| {\n            dir_found = true;\n            span.file_name\n                .replace_range(0..thread_target_dir.len(), shared_target_dir(\"_*\").to_str().unwrap());\n        });\n\n    if dir_found && let Some(rendered) = &mut message.rendered {\n        *rendered = rendered.replace(thread_target_dir, shared_target_dir(\"_*\").to_str().unwrap());\n    }\n    message\n}\n\n/// Builds clippy inside the repo to make sure we have a clippy executable we can use.\nfn build_clippy(release_build: bool) -> String {\n    let mut build_cmd = Command::new(\"cargo\");\n    build_cmd.args([\n        \"run\",\n        \"--bin=clippy-driver\",\n        if release_build { \"-r\" } else { \"\" },\n        \"--\",\n        \"--version\",\n    ]);\n\n    if release_build {\n        build_cmd.env(\"CARGO_PROFILE_RELEASE_DEBUG\", \"true\");\n    }\n\n    let output = build_cmd.stderr(Stdio::inherit()).output().unwrap();\n\n    if !output.status.success() {\n        eprintln!(\"Error: Failed to compile Clippy!\");\n        std::process::exit(1);\n    }\n    String::from_utf8_lossy(&output.stdout).into_owned()\n}\n\nfn main() {\n    // We're being executed as a `RUSTC_WRAPPER` as part of `--recursive`\n    if let Ok(addr) = env::var(\"LINTCHECK_SERVER\") {\n        driver::drive(&addr);\n    }\n\n    // assert that we launch lintcheck from the repo root (via cargo lintcheck)\n    if fs::metadata(\"lintcheck/Cargo.toml\").is_err() {\n        eprintln!(\"lintcheck needs to be run from clippy's repo root!\\nUse `cargo lintcheck` alternatively.\");\n        std::process::exit(3);\n    }\n\n    let config = LintcheckConfig::new();\n\n    match config.subcommand {\n        Some(Commands::Diff {\n            old,\n            new,\n            truncate,\n            write_summary,\n        }) => json::diff(&old, &new, truncate, write_summary),\n        Some(Commands::Popular { output, number }) => popular_crates::fetch(output, number).unwrap(),\n        None => lintcheck(config),\n    }\n}\n\n#[expect(clippy::too_many_lines)]\nfn lintcheck(config: LintcheckConfig) {\n    let clippy_ver = build_clippy(config.perf);\n    let clippy_driver_path = fs::canonicalize(format!(\n        \"{}/{}/clippy-driver{EXE_SUFFIX}\",\n        target_dir(),\n        if config.perf { \"release\" } else { \"debug\" }\n    ))\n    .unwrap();\n\n    // assert that clippy is found\n    assert!(\n        clippy_driver_path.is_file(),\n        \"{}/{}/clippy-driver binary not found! {}\",\n        target_dir(),\n        if config.perf { \"release\" } else { \"debug\" },\n        clippy_driver_path.display()\n    );\n\n    // download and extract the crates, then run clippy on them and collect clippy's warnings\n    // flatten into one big list of warnings\n\n    let (crates, recursive_options) = read_crates(&config.sources_toml_path);\n\n    let counter = AtomicUsize::new(1);\n    let mut lint_level_args: Vec<String> = vec![\"--cap-lints=allow\".into()];\n    if config.lint_filter.is_empty() {\n        let groups = if config.all_lints {\n            &[\n                \"clippy::all\",\n                \"clippy::cargo\",\n                \"clippy::nursery\",\n                \"clippy::pedantic\",\n                \"clippy::restriction\",\n            ][..]\n        } else {\n            &[\"clippy::all\", \"clippy::pedantic\"]\n        };\n        groups\n            .iter()\n            .map(|group| format!(\"--force-warn={group}\"))\n            .collect_into(&mut lint_level_args);\n    } else {\n        config\n            .lint_filter\n            .iter()\n            .map(|filter| {\n                let mut filter = filter.clone();\n                filter.insert_str(0, \"--force-warn=\");\n                filter\n            })\n            .collect_into(&mut lint_level_args);\n    }\n\n    let crates: Vec<Crate> = crates\n        .into_iter()\n        .filter(|krate| {\n            if let Some(only_one_crate) = &config.only {\n                krate.name == *only_one_crate\n            } else {\n                true\n            }\n        })\n        .map(|krate| krate.download_and_prepare())\n        .collect();\n\n    if crates.is_empty() {\n        eprintln!(\n            \"ERROR: could not find crate '{}' in lintcheck/lintcheck_crates.toml\",\n            config.only.unwrap(),\n        );\n        std::process::exit(1);\n    }\n\n    // run parallel with rayon\n\n    // This helps when we check many small crates with dep-trees that don't have a lot of branches in\n    // order to achieve some kind of parallelism\n\n    rayon::ThreadPoolBuilder::new()\n        .num_threads(config.max_jobs)\n        .build_global()\n        .unwrap();\n\n    let server = config.recursive.then(|| {\n        let _: io::Result<()> = fs::remove_dir_all(format!(\"{}/lintcheck/shared_target_dir/recursive\", target_dir()));\n\n        LintcheckServer::spawn(recursive_options)\n    });\n\n    let mut clippy_entries: Vec<ClippyCheckOutput> = crates\n        .par_iter()\n        .flat_map(|krate| {\n            krate.run_clippy_lints(\n                &clippy_driver_path,\n                &counter,\n                crates.len(),\n                &config,\n                &lint_level_args,\n                server.as_ref(),\n            )\n        })\n        .collect();\n\n    if let Some(server) = server {\n        let server_clippy_entries = server.warnings().map(ClippyCheckOutput::ClippyWarning);\n\n        clippy_entries.extend(server_clippy_entries);\n    }\n\n    // if we are in --fix mode, don't change the log files, terminate here\n    if config.fix {\n        return;\n    }\n\n    // split up warnings and ices\n    let mut warnings: Vec<ClippyWarning> = vec![];\n    let mut raw_ices: Vec<RustcIce> = vec![];\n    for entry in clippy_entries {\n        if let ClippyCheckOutput::ClippyWarning(x) = entry {\n            warnings.push(x);\n        } else if let ClippyCheckOutput::RustcIce(x) = entry {\n            raw_ices.push(x);\n        }\n    }\n\n    let text = match config.format {\n        OutputFormat::Text | OutputFormat::Markdown => {\n            output::summarize_and_print_changes(&warnings, &raw_ices, clippy_ver, &config)\n        },\n        OutputFormat::Json => {\n            if !raw_ices.is_empty() {\n                for ice in raw_ices {\n                    println!(\"{ice}\");\n                }\n                panic!(\"Some crates ICEd\");\n            }\n\n            json::output(warnings)\n        },\n    };\n\n    println!(\"Writing logs to {}\", config.lintcheck_results_path.display());\n    fs::create_dir_all(config.lintcheck_results_path.parent().unwrap()).unwrap();\n    fs::write(&config.lintcheck_results_path, text).unwrap();\n}\n\n/// Traverse a directory looking for `perf.data.<number>` files, and adds one\n/// to the most recent of those files, returning the new most recent `perf.data`\n/// file name.\nfn get_perf_data_filename(source_path: &Path) -> String {\n    if source_path.join(\"perf.data\").exists() {\n        let mut max_number = 0;\n        fs::read_dir(source_path)\n            .unwrap()\n            .filter_map(Result::ok)\n            .filter(|path| {\n                path.file_name()\n                    .as_os_str()\n                    .to_string_lossy() // We don't care about data loss, as we're checking for equality\n                    .starts_with(\"perf.data\")\n            })\n            .for_each(|path| {\n                let file_name = path.file_name();\n                let file_name = file_name.as_os_str().to_str().unwrap().split('.').next_back().unwrap();\n                if let Ok(parsed_file_name) = file_name.parse::<usize>()\n                    && parsed_file_name >= max_number\n                {\n                    max_number = parsed_file_name + 1;\n                }\n            });\n        return format!(\"perf.data.{max_number}\");\n    }\n    String::from(\"perf.data\")\n}\n\n/// Returns the path to the Clippy project directory\n#[must_use]\nfn clippy_project_root() -> &'static Path {\n    Path::new(env!(\"CARGO_MANIFEST_DIR\")).parent().unwrap()\n}\n\n/// The qualifier can be used to separate different threads from another. By\n/// default it should be set to `_<thread_id>`\n#[must_use]\nfn shared_target_dir(qualifier: &str) -> PathBuf {\n    clippy_project_root()\n        .join(format!(\"{}/lintcheck/shared_target_dir\", target_dir()))\n        .join(qualifier)\n}\n\n#[test]\nfn lintcheck_test() {\n    let args = [\n        \"run\",\n        \"--target-dir\",\n        \"lintcheck/target\",\n        \"--manifest-path\",\n        \"./lintcheck/Cargo.toml\",\n        \"--\",\n        \"--crates-toml\",\n        \"lintcheck/test_sources.toml\",\n    ];\n    let status = Command::new(\"cargo\")\n        .args(args)\n        .current_dir(\"..\") // repo root\n        .status();\n    //.output();\n\n    assert!(status.unwrap().success());\n}\n"
  },
  {
    "path": "lintcheck/src/output.rs",
    "content": "use cargo_metadata::diagnostic::{Diagnostic, DiagnosticSpan};\nuse serde::{Deserialize, Serialize};\nuse std::collections::HashMap;\nuse std::fmt::{self, Write as _};\nuse std::fs;\nuse std::path::Path;\nuse std::process::ExitStatus;\n\nuse crate::config::{LintcheckConfig, OutputFormat};\n\n/// A single emitted output from clippy being executed on a crate. It may either be a\n/// `ClippyWarning`, or a `RustcIce` caused by a panic within clippy. A crate may have many\n/// `ClippyWarning`s but a maximum of one `RustcIce` (at which point clippy halts execution).\n#[derive(Debug)]\npub enum ClippyCheckOutput {\n    ClippyWarning(ClippyWarning),\n    RustcIce(RustcIce),\n}\n\n#[derive(Debug)]\npub struct RustcIce {\n    pub crate_name: String,\n    pub ice_content: String,\n}\n\nimpl fmt::Display for RustcIce {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(\n            f,\n            \"{}:\\n{}\\n========================================\\n\",\n            self.crate_name, self.ice_content\n        )\n    }\n}\n\nimpl RustcIce {\n    pub fn from_stderr_and_status(crate_name: &str, status: ExitStatus, stderr: &str) -> Option<Self> {\n        if status.code().unwrap_or(0) == 101\n        /* ice exit status */\n        {\n            Some(Self {\n                crate_name: crate_name.to_owned(),\n                ice_content: stderr.to_owned(),\n            })\n        } else {\n            None\n        }\n    }\n}\n\n/// A single warning that clippy issued while checking a `Crate`\n#[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]\npub struct ClippyWarning {\n    pub name: String,\n    pub diag: Diagnostic,\n    pub krate: String,\n    /// The URL that points to the file and line of the lint emission\n    pub url: String,\n}\n\nimpl ClippyWarning {\n    pub fn new(mut diag: Diagnostic, base_url: &str, krate: &str) -> Option<Self> {\n        let name = diag.code.clone()?.code;\n        if !(name.contains(\"clippy\") || diag.message.contains(\"clippy\"))\n            || diag.message.contains(\"could not read cargo metadata\")\n        {\n            return None;\n        }\n\n        // --recursive bypasses cargo so we have to strip the rendered output ourselves\n        let rendered = diag.rendered.as_mut().unwrap();\n        *rendered = strip_ansi_escapes::strip_str(&rendered);\n\n        // Turns out that there are lints without spans... For example Rust's\n        // `renamed_and_removed_lints` if the lint is given via the CLI.\n        let span = diag\n            .spans\n            .iter()\n            .find(|span| span.is_primary)\n            .or(diag.spans.first())\n            .unwrap_or_else(|| panic!(\"Diagnostic without span: {diag}\"));\n        let file = &span.file_name;\n        let url = if let Some(src_split) = file.find(\"/src/\") {\n            // This removes the initial `target/lintcheck/sources/<crate>-<version>/`\n            let src_split = src_split + \"/src/\".len();\n            let (_, file) = file.split_at(src_split);\n\n            let line_no = span.line_start;\n            base_url.replace(\"{file}\", file).replace(\"{line}\", &line_no.to_string())\n        } else {\n            file.clone()\n        };\n\n        Some(Self {\n            name,\n            diag,\n            krate: krate.to_string(),\n            url,\n        })\n    }\n\n    pub fn span(&self) -> &DiagnosticSpan {\n        self.diag.spans.iter().find(|span| span.is_primary).unwrap()\n    }\n\n    pub fn to_output(&self, format: OutputFormat) -> String {\n        let span = self.span();\n        let mut file = span.file_name.clone();\n        let file_with_pos = format!(\"{file}:{}:{}\", span.line_start, span.line_end);\n        match format {\n            OutputFormat::Text => format!(\"{file_with_pos} {} \\\"{}\\\"\\n\", self.name, self.diag.message),\n            OutputFormat::Markdown => {\n                if file.starts_with(\"target\") {\n                    file.insert_str(0, \"../\");\n                }\n\n                let mut output = String::from(\"| \");\n                write!(output, \"[`{file_with_pos}`]({file}#L{})\", span.line_start).unwrap();\n                write!(output, r#\" | `{:<50}` | \"{}\" |\"#, self.name, self.diag.message).unwrap();\n                output.push('\\n');\n                output\n            },\n            OutputFormat::Json => unreachable!(\"JSON output is handled via serde\"),\n        }\n    }\n}\n\n/// Creates the log file output for [`OutputFormat::Text`] and [`OutputFormat::Markdown`]\npub fn summarize_and_print_changes(\n    warnings: &[ClippyWarning],\n    ices: &[RustcIce],\n    clippy_ver: String,\n    config: &LintcheckConfig,\n) -> String {\n    // generate some stats\n    let (stats_formatted, new_stats) = gather_stats(warnings);\n    let old_stats = read_stats_from_file(&config.lintcheck_results_path);\n\n    let mut all_msgs: Vec<String> = warnings.iter().map(|warn| warn.to_output(config.format)).collect();\n    all_msgs.sort();\n    all_msgs.push(\"\\n\\n### Stats:\\n\\n\".into());\n    all_msgs.push(stats_formatted);\n\n    let mut text = clippy_ver; // clippy version number on top\n    text.push_str(\"\\n### Reports\\n\\n\");\n    if config.format == OutputFormat::Markdown {\n        text.push_str(\"| file | lint | message |\\n\");\n        text.push_str(\"| --- | --- | --- |\\n\");\n    }\n    write!(text, \"{}\", all_msgs.join(\"\")).unwrap();\n    text.push_str(\"\\n\\n### ICEs:\\n\");\n    for ice in ices {\n        writeln!(text, \"{ice}\").unwrap();\n    }\n\n    print_stats(old_stats, new_stats, &config.lint_filter);\n\n    text\n}\n\n/// Generate a short list of occurring lints-types and their count\nfn gather_stats(warnings: &[ClippyWarning]) -> (String, HashMap<&String, usize>) {\n    // count lint type occurrences\n    let mut counter: HashMap<&String, usize> = HashMap::new();\n    for wrn in warnings {\n        *counter.entry(&wrn.name).or_insert(0) += 1;\n    }\n\n    // collect into a tupled list for sorting\n    let mut stats: Vec<(&&String, &usize)> = counter.iter().collect();\n    // sort by \"000{count} {clippy::lintname}\"\n    // to not have a lint with 200 and 2 warnings take the same spot\n    stats.sort_by_key(|(lint, count)| format!(\"{count:0>4}, {lint}\"));\n\n    let mut header = String::from(\"| lint                                               | count |\\n\");\n    header.push_str(\"| -------------------------------------------------- | ----- |\\n\");\n    let stats_string = stats\n        .iter()\n        .map(|(lint, count)| format!(\"| {lint:<50} |  {count:>4} |\\n\"))\n        .fold(header, |mut table, line| {\n            table.push_str(&line);\n            table\n        });\n\n    (stats_string, counter)\n}\n\n/// read the previous stats from the lintcheck-log file\nfn read_stats_from_file(file_path: &Path) -> HashMap<String, usize> {\n    let file_content: String = match fs::read_to_string(file_path).ok() {\n        Some(content) => content,\n        None => {\n            return HashMap::new();\n        },\n    };\n\n    let lines: Vec<String> = file_content.lines().map(ToString::to_string).collect();\n\n    lines\n        .iter()\n        .skip_while(|line| line.as_str() != \"### Stats:\")\n        // Skipping the table header and the `Stats:` label\n        .skip(4)\n        .take_while(|line| line.starts_with(\"| \"))\n        .filter_map(|line| {\n            let mut spl = line.split('|');\n            // Skip the first `|` symbol\n            spl.next();\n            if let (Some(lint), Some(count)) = (spl.next(), spl.next()) {\n                Some((lint.trim().to_string(), count.trim().parse::<usize>().unwrap()))\n            } else {\n                None\n            }\n        })\n        .collect::<HashMap<String, usize>>()\n}\n\n/// print how lint counts changed between runs\nfn print_stats(old_stats: HashMap<String, usize>, new_stats: HashMap<&String, usize>, lint_filter: &[String]) {\n    let same_in_both_hashmaps = old_stats\n        .iter()\n        .filter(|(old_key, old_val)| new_stats.get::<&String>(old_key) == Some(old_val))\n        .map(|(k, v)| (k.clone(), *v))\n        .collect::<Vec<(String, usize)>>();\n\n    let mut old_stats_deduped = old_stats;\n    let mut new_stats_deduped = new_stats;\n\n    // remove duplicates from both hashmaps\n    for (k, v) in &same_in_both_hashmaps {\n        assert!(old_stats_deduped.remove(k) == Some(*v));\n        assert!(new_stats_deduped.remove(k) == Some(*v));\n    }\n\n    println!(\"\\nStats:\");\n\n    // list all new counts  (key is in new stats but not in old stats)\n    new_stats_deduped\n        .iter()\n        .filter(|(new_key, _)| !old_stats_deduped.contains_key::<str>(new_key))\n        .for_each(|(new_key, new_value)| {\n            println!(\"{new_key} 0 => {new_value}\");\n        });\n\n    // list all changed counts (key is in both maps but value differs)\n    new_stats_deduped\n        .iter()\n        .filter(|(new_key, _new_val)| old_stats_deduped.contains_key::<str>(new_key))\n        .for_each(|(new_key, new_val)| {\n            let old_val = old_stats_deduped.get::<str>(new_key).unwrap();\n            println!(\"{new_key} {old_val} => {new_val}\");\n        });\n\n    // list all gone counts (key is in old status but not in new stats)\n    old_stats_deduped\n        .iter()\n        .filter(|(old_key, _)| !new_stats_deduped.contains_key::<&String>(old_key))\n        .filter(|(old_key, _)| lint_filter.is_empty() || lint_filter.contains(old_key))\n        .for_each(|(old_key, old_value)| {\n            println!(\"{old_key} {old_value} => 0\");\n        });\n}\n"
  },
  {
    "path": "lintcheck/src/popular_crates.rs",
    "content": "use serde::Deserialize;\nuse std::error::Error;\nuse std::fmt::Write;\nuse std::fs;\nuse std::path::PathBuf;\n\n#[derive(Deserialize, Debug)]\nstruct Page {\n    crates: Vec<Crate>,\n    meta: Meta,\n}\n\n#[derive(Deserialize, Debug)]\nstruct Crate {\n    name: String,\n    max_version: String,\n}\n\n#[derive(Deserialize, Debug)]\nstruct Meta {\n    next_page: String,\n}\n\npub(crate) fn fetch(output: PathBuf, number: usize) -> Result<(), Box<dyn Error>> {\n    let agent = ureq::builder()\n        .user_agent(\"clippy/lintcheck (github.com/rust-lang/rust-clippy/)\")\n        .build();\n\n    let mut crates = Vec::with_capacity(number);\n    let mut query = \"?sort=recent-downloads&per_page=100\".to_string();\n    while crates.len() < number {\n        let page: Page = agent\n            .get(&format!(\"https://crates.io/api/v1/crates{query}\"))\n            .call()?\n            .into_json()?;\n\n        query = page.meta.next_page;\n        crates.extend(page.crates);\n        crates.truncate(number);\n\n        let width = number.ilog10() as usize + 1;\n        println!(\"Fetched {:>width$}/{number} crates\", crates.len());\n    }\n\n    let mut out = \"[crates]\\n\".to_string();\n    for Crate { name, max_version } in crates {\n        writeln!(out, \"{name} = {{ name = '{name}', version = '{max_version}' }}\").unwrap();\n    }\n    fs::write(output, out)?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "lintcheck/src/recursive.rs",
    "content": "//! In `--recursive` mode we set the `lintcheck` binary as the `RUSTC_WRAPPER` of `cargo check`,\n//! this allows [`crate::driver`] to be run for every dependency. The driver connects to\n//! [`LintcheckServer`] to ask if it should be skipped, and if not sends the stderr of running\n//! clippy on the crate to the server\n\nuse crate::ClippyWarning;\nuse crate::input::RecursiveOptions;\n\nuse std::collections::HashSet;\nuse std::io::{BufRead, BufReader, Read, Write};\nuse std::net::{SocketAddr, TcpListener, TcpStream};\nuse std::sync::{Arc, Mutex};\nuse std::thread;\n\nuse cargo_metadata::diagnostic::Diagnostic;\nuse crossbeam_channel::{Receiver, Sender};\nuse serde::de::DeserializeOwned;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Debug, Eq, Hash, PartialEq, Clone, Serialize, Deserialize)]\npub(crate) struct DriverInfo {\n    pub package_name: String,\n    pub version: String,\n}\n\npub(crate) fn serialize_line<T, W>(value: &T, writer: &mut W)\nwhere\n    T: Serialize,\n    W: Write,\n{\n    let mut buf = serde_json::to_vec(&value).expect(\"failed to serialize\");\n    buf.push(b'\\n');\n    writer.write_all(&buf).expect(\"write_all failed\");\n}\n\npub(crate) fn deserialize_line<T, R>(reader: &mut R) -> T\nwhere\n    T: DeserializeOwned,\n    R: BufRead,\n{\n    let mut string = String::new();\n    reader.read_line(&mut string).expect(\"read_line failed\");\n    serde_json::from_str(&string).expect(\"failed to deserialize\")\n}\n\nfn process_stream(\n    stream: TcpStream,\n    sender: &Sender<ClippyWarning>,\n    options: &RecursiveOptions,\n    seen: &Mutex<HashSet<DriverInfo>>,\n) {\n    let mut stream = BufReader::new(stream);\n\n    let driver_info: DriverInfo = deserialize_line(&mut stream);\n\n    let unseen = seen.lock().unwrap().insert(driver_info.clone());\n    let ignored = options.ignore.contains(&driver_info.package_name);\n    let should_run = unseen && !ignored;\n\n    serialize_line(&should_run, stream.get_mut());\n\n    let mut stderr = String::new();\n    stream.read_to_string(&mut stderr).unwrap();\n\n    // It's 99% likely that dependencies compiled with recursive mode are on crates.io\n    // and therefore on docs.rs. This links to the sources directly, do avoid invalid\n    // links due to remapped paths. See rust-lang/docs.rs#2551 for more details.\n    let base_url = format!(\n        \"https://docs.rs/crate/{}/{}/source/src/{{file}}#{{line}}\",\n        driver_info.package_name, driver_info.version\n    );\n    let messages = stderr\n        .lines()\n        .filter_map(|json_msg| serde_json::from_str::<Diagnostic>(json_msg).ok())\n        .filter_map(|diag| ClippyWarning::new(diag, &base_url, &driver_info.package_name));\n\n    for message in messages {\n        sender.send(message).unwrap();\n    }\n}\n\npub(crate) struct LintcheckServer {\n    pub local_addr: SocketAddr,\n    receiver: Receiver<ClippyWarning>,\n    sender: Arc<Sender<ClippyWarning>>,\n}\n\nimpl LintcheckServer {\n    pub fn spawn(options: RecursiveOptions) -> Self {\n        let listener = TcpListener::bind(\"localhost:0\").unwrap();\n        let local_addr = listener.local_addr().unwrap();\n\n        let (sender, receiver) = crossbeam_channel::unbounded::<ClippyWarning>();\n        let sender = Arc::new(sender);\n        // The spawned threads hold a `Weak<Sender>` so that they don't keep the channel connected\n        // indefinitely\n        let sender_weak = Arc::downgrade(&sender);\n\n        // Ignore dependencies multiple times, e.g. for when it's both checked and compiled for a\n        // build dependency\n        let seen = Mutex::default();\n\n        thread::spawn(move || {\n            thread::scope(|s| {\n                s.spawn(|| {\n                    while let Ok((stream, _)) = listener.accept() {\n                        let sender = sender_weak.upgrade().expect(\"received connection after server closed\");\n                        let options = &options;\n                        let seen = &seen;\n                        s.spawn(move || process_stream(stream, &sender, options, seen));\n                    }\n                });\n            });\n        });\n\n        Self {\n            local_addr,\n            receiver,\n            sender,\n        }\n    }\n\n    pub fn warnings(self) -> impl Iterator<Item = ClippyWarning> {\n        // causes the channel to become disconnected so that the receiver iterator ends\n        drop(self.sender);\n\n        self.receiver.into_iter()\n    }\n}\n"
  },
  {
    "path": "lintcheck/test_sources.toml",
    "content": "[crates]\ncc = {name = \"cc\", versions = ['1.0.67']}\nhome = {name = \"home\", git_url = \"https://github.com/brson/home\", git_hash = \"32044e53dfbdcd32bafad3109d1fbab805fc0f40\"}\nrustc_tools_util = {name = \"rustc_tools_util\", versions = ['0.2.0']}\n"
  },
  {
    "path": "rust-toolchain.toml",
    "content": "[toolchain]\n# begin autogenerated nightly\nchannel = \"nightly-2026-03-05\"\n# end autogenerated nightly\ncomponents = [\"cargo\", \"llvm-tools\", \"rust-src\", \"rust-std\", \"rustc\", \"rustc-dev\", \"rustfmt\"]\nprofile = \"minimal\"\n"
  },
  {
    "path": "rustc_tools_util/CHANGELOG.md",
    "content": "# Changelog\n\n## Version 0.4.0\n\n* The commit hashes are now always 10 characters long [#13222](https://github.com/rust-lang/rust-clippy/pull/13222)\n* `get_commit_date` and `get_commit_hash` now return `None` if the `git` command fails instead of `Some(\"\")`\n  [#13217](https://github.com/rust-lang/rust-clippy/pull/13217)\n* `setup_version_info` will now re-run when the git commit changes\n  [#13329](https://github.com/rust-lang/rust-clippy/pull/13329)\n* New `rerun_if_git_changes` function was added [#13329](https://github.com/rust-lang/rust-clippy/pull/13329)\n\n## Version 0.3.0\n\n* Added `setup_version_info!();` macro for automated scripts.\n* `get_version_info!()` no longer requires the user to import `rustc_tools_util::VersionInfo` and `std::env`\n"
  },
  {
    "path": "rustc_tools_util/Cargo.toml",
    "content": "[package]\nname = \"rustc_tools_util\"\nversion = \"0.4.2\"\ndescription = \"small helper to generate version information for git packages\"\nrepository = \"https://github.com/rust-lang/rust-clippy\"\nreadme = \"README.md\"\nlicense = \"MIT OR Apache-2.0\"\nkeywords = [\"rustc\", \"tool\", \"git\", \"version\", \"hash\"]\ncategories = [\"development-tools\"]\nedition = \"2021\" # Keep this, for this crate's MSRV to stay low\n\n[dependencies]\n"
  },
  {
    "path": "rustc_tools_util/README.md",
    "content": "# rustc_tools_util\n\nA small tool to help you generate version information\nfor packages installed from a git repo\n\n## Usage\n\nAdd a `build.rs` file to your repo and list it in `Cargo.toml`\n````toml\nbuild = \"build.rs\"\n````\n\nList rustc_tools_util as regular AND build dependency.\n````toml\n[dependencies]\nrustc_tools_util = \"0.4.2\"\n\n[build-dependencies]\nrustc_tools_util = \"0.4.2\"\n````\n\nIn `build.rs`, generate the data in your `main()`\n\n```rust\nfn main() {\n    rustc_tools_util::setup_version_info!();\n}\n```\n\nUse the version information in your main.rs\n\n```rust\nfn show_version() {\n    let version_info = rustc_tools_util::get_version_info!();\n    println!(\"{}\", version_info);\n}\n```\n\nThis gives the following output in clippy:\n`clippy 0.1.66 (a28f3c8 2022-11-20)`\n\n## Repository\n\nThis project is part of the rust-lang/rust-clippy repository. The source code\ncan be found under `./rustc_tools_util/`.\n\nThe changelog for `rustc_tools_util` is available under:\n[`rustc_tools_util/CHANGELOG.md`](https://github.com/rust-lang/rust-clippy/blob/master/rustc_tools_util/CHANGELOG.md)\n\n## License\n\n<!-- REUSE-IgnoreStart -->\n\nCopyright (c) The Rust Project Contributors\n\nLicensed under the Apache License, Version 2.0 <LICENSE-APACHE or\nhttp://www.apache.org/licenses/LICENSE-2.0> or the MIT license\n<LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\noption. All files in the project carrying such notice may not be\ncopied, modified, or distributed except according to those terms.\n\n<!-- REUSE-IgnoreEnd -->\n"
  },
  {
    "path": "rustc_tools_util/src/lib.rs",
    "content": "use std::path::PathBuf;\nuse std::process::Command;\nuse std::str;\n\n/// This macro creates the version string during compilation from the\n/// current environment\n#[macro_export]\nmacro_rules! get_version_info {\n    () => {{\n        let major = std::env!(\"CARGO_PKG_VERSION_MAJOR\").parse::<u8>().unwrap();\n        let minor = std::env!(\"CARGO_PKG_VERSION_MINOR\").parse::<u8>().unwrap();\n        let patch = std::env!(\"CARGO_PKG_VERSION_PATCH\").parse::<u16>().unwrap();\n        let crate_name = String::from(std::env!(\"CARGO_PKG_NAME\"));\n\n        let host_compiler = std::option_env!(\"RUSTC_RELEASE_CHANNEL\").map(str::to_string);\n        let commit_hash = std::option_env!(\"GIT_HASH\").map(str::to_string);\n        let commit_date = std::option_env!(\"COMMIT_DATE\").map(str::to_string);\n\n        $crate::VersionInfo {\n            major,\n            minor,\n            patch,\n            host_compiler,\n            commit_hash,\n            commit_date,\n            crate_name,\n        }\n    }};\n}\n\n/// This macro can be used in `build.rs` to automatically set the needed environment values, namely\n/// `GIT_HASH`, `COMMIT_DATE`  and `RUSTC_RELEASE_CHANNEL`\n#[macro_export]\nmacro_rules! setup_version_info {\n    () => {{\n        let _ = $crate::rerun_if_git_changes();\n        println!(\n            \"cargo:rustc-env=GIT_HASH={}\",\n            $crate::get_commit_hash().unwrap_or_default()\n        );\n        println!(\n            \"cargo:rustc-env=COMMIT_DATE={}\",\n            $crate::get_commit_date().unwrap_or_default()\n        );\n        let compiler_version = $crate::get_compiler_version();\n        println!(\n            \"cargo:rustc-env=RUSTC_RELEASE_CHANNEL={}\",\n            $crate::get_channel(compiler_version)\n        );\n    }};\n}\n\n// some code taken and adapted from RLS and cargo\npub struct VersionInfo {\n    pub major: u8,\n    pub minor: u8,\n    pub patch: u16,\n    pub host_compiler: Option<String>,\n    pub commit_hash: Option<String>,\n    pub commit_date: Option<String>,\n    pub crate_name: String,\n}\n\nimpl std::fmt::Display for VersionInfo {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        let hash = self.commit_hash.clone().unwrap_or_default();\n        let hash_trimmed = hash.trim();\n\n        let date = self.commit_date.clone().unwrap_or_default();\n        let date_trimmed = date.trim();\n\n        if (hash_trimmed.len() + date_trimmed.len()) > 0 {\n            write!(\n                f,\n                \"{} {}.{}.{} ({hash_trimmed} {date_trimmed})\",\n                self.crate_name, self.major, self.minor, self.patch,\n            )?;\n        } else {\n            write!(f, \"{} {}.{}.{}\", self.crate_name, self.major, self.minor, self.patch)?;\n        }\n\n        Ok(())\n    }\n}\n\nimpl std::fmt::Debug for VersionInfo {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(\n            f,\n            \"VersionInfo {{ crate_name: \\\"{}\\\", major: {}, minor: {}, patch: {}\",\n            self.crate_name, self.major, self.minor, self.patch,\n        )?;\n        if let Some(ref commit_hash) = self.commit_hash {\n            write!(f, \", commit_hash: \\\"{}\\\"\", commit_hash.trim())?;\n        }\n        if let Some(ref commit_date) = self.commit_date {\n            write!(f, \", commit_date: \\\"{}\\\"\", commit_date.trim())?;\n        }\n        if let Some(ref host_compiler) = self.host_compiler {\n            write!(f, \", host_compiler: \\\"{}\\\"\", host_compiler.trim())?;\n        }\n\n        write!(f, \" }}\")?;\n\n        Ok(())\n    }\n}\n\n#[must_use]\nfn get_output(cmd: &str, args: &[&str]) -> Option<String> {\n    let output = Command::new(cmd).args(args).output().ok()?;\n    let mut stdout = output.status.success().then_some(output.stdout)?;\n    // Remove trailing newlines.\n    while stdout.last().copied() == Some(b'\\n') {\n        stdout.pop();\n    }\n    String::from_utf8(stdout).ok()\n}\n\n#[must_use]\npub fn rerun_if_git_changes() -> Option<()> {\n    // Make sure we get rerun when the git commit changes.\n    // We want to watch two files: HEAD, which tracks which branch we are on,\n    // and the file for that branch that tracks which commit is checked out.\n\n    // First, find the `HEAD` file. This should work even with worktrees.\n    let git_head_file = PathBuf::from(get_output(\"git\", &[\"rev-parse\", \"--git-path\", \"HEAD\"])?);\n    if git_head_file.exists() {\n        println!(\"cargo::rerun-if-changed={}\", git_head_file.display());\n    }\n\n    // Determine the name of the current ref.\n    // This will quit if HEAD is detached.\n    let git_head_ref = get_output(\"git\", &[\"symbolic-ref\", \"-q\", \"HEAD\"])?;\n    // Ask git where this ref is stored.\n    let git_head_ref_file = PathBuf::from(get_output(\"git\", &[\"rev-parse\", \"--git-path\", &git_head_ref])?);\n    // If this ref is packed, the file does not exist. However, the checked-out branch is never (?)\n    // packed, so we should always be able to find this file.\n    if git_head_ref_file.exists() {\n        println!(\"cargo::rerun-if-changed={}\", git_head_ref_file.display());\n    }\n\n    Some(())\n}\n\n#[must_use]\npub fn get_commit_hash() -> Option<String> {\n    let mut stdout = get_output(\"git\", &[\"rev-parse\", \"HEAD\"])?;\n    stdout.truncate(10);\n    Some(stdout)\n}\n\n#[must_use]\npub fn get_commit_date() -> Option<String> {\n    get_output(\"git\", &[\"log\", \"-1\", \"--date=short\", \"--pretty=format:%cd\"])\n}\n\n#[must_use]\npub fn get_compiler_version() -> Option<String> {\n    let compiler = std::option_env!(\"RUSTC\").unwrap_or(\"rustc\");\n    get_output(compiler, &[\"-V\"])\n}\n\n#[must_use]\npub fn get_channel(compiler_version: Option<String>) -> String {\n    if let Ok(channel) = std::env::var(\"CFG_RELEASE_CHANNEL\") {\n        return channel;\n    }\n\n    // if that failed, try to ask rustc -V, do some parsing and find out\n    if let Some(rustc_output) = compiler_version {\n        if rustc_output.contains(\"beta\") {\n            return String::from(\"beta\");\n        } else if rustc_output.contains(\"nightly\") {\n            return String::from(\"nightly\");\n        } else if rustc_output.contains(\"dev\") {\n            return String::from(\"dev\");\n        }\n    }\n\n    // default to stable\n    String::from(\"stable\")\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_struct_local() {\n        let vi = get_version_info!();\n        assert_eq!(vi.major, 0);\n        assert_eq!(vi.minor, 4);\n        assert_eq!(vi.patch, 2);\n        assert_eq!(vi.crate_name, \"rustc_tools_util\");\n        // hard to make positive tests for these since they will always change\n        assert!(vi.commit_hash.is_none());\n        assert!(vi.commit_date.is_none());\n\n        assert!(vi.host_compiler.is_none());\n    }\n\n    #[test]\n    fn test_display_local() {\n        let vi = get_version_info!();\n        assert_eq!(vi.to_string(), \"rustc_tools_util 0.4.2\");\n    }\n\n    #[test]\n    fn test_debug_local() {\n        let vi = get_version_info!();\n        let s = format!(\"{vi:?}\");\n        assert_eq!(\n            s,\n            \"VersionInfo { crate_name: \\\"rustc_tools_util\\\", major: 0, minor: 4, patch: 2 }\"\n        );\n    }\n}\n"
  },
  {
    "path": "rustfmt.toml",
    "content": "max_width = 120\ncomment_width = 100\nmatch_block_trailing_comma = true\nwrap_comments = true\nedition = \"2024\"\nerror_on_line_overflow = true\nimports_granularity = \"Module\"\nstyle_edition = \"2024\"\nignore = [\n    \"tests/ui/crashes/ice-9405.rs\",\n    \"tests/ui/crashes/ice-10912.rs\",\n    \"tests/ui/non_expressive_names_error_recovery.rs\",\n]\n"
  },
  {
    "path": "src/driver.rs",
    "content": "#![feature(rustc_private)]\n// warn on lints, that are included in `rust-lang/rust`s bootstrap\n#![warn(rust_2018_idioms, unused_lifetimes)]\n// warn on rustc internal lints\n#![warn(rustc::internal)]\n\n// FIXME: switch to something more ergonomic here, once available.\n// (Currently there is no way to opt into sysroot crates without `extern crate`.)\nextern crate rustc_driver;\nextern crate rustc_interface;\nextern crate rustc_session;\nextern crate rustc_span;\n\n/// See docs in <https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc/src/main.rs>\n/// and <https://github.com/rust-lang/rust/pull/146627> for why we need this.\n///\n/// FIXME(madsmtm): This is loaded from the sysroot that was built with the other `rustc` crates\n/// above, instead of via Cargo as you'd normally do. This is currently needed for LTO due to\n/// <https://github.com/rust-lang/cc-rs/issues/1613>.\n#[cfg(feature = \"jemalloc\")]\nextern crate tikv_jemalloc_sys as _;\n\nuse clippy_utils::sym;\nuse declare_clippy_lint::LintListBuilder;\nuse rustc_interface::interface;\nuse rustc_session::EarlyDiagCtxt;\nuse rustc_session::config::ErrorOutputType;\nuse rustc_session::parse::ParseSess;\nuse rustc_span::symbol::Symbol;\n\nuse std::env;\nuse std::fs::read_to_string;\nuse std::io::Write as _;\nuse std::path::Path;\nuse std::process::ExitCode;\n\n/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If\n/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.\nfn arg_value<'a>(args: &'a [String], find_arg: &str, pred: impl Fn(&str) -> bool) -> Option<&'a str> {\n    let mut args = args.iter().map(String::as_str);\n    while let Some(arg) = args.next() {\n        let mut arg = arg.splitn(2, '=');\n        if arg.next() != Some(find_arg) {\n            continue;\n        }\n\n        match arg.next().or_else(|| args.next()) {\n            Some(v) if pred(v) => return Some(v),\n            _ => {},\n        }\n    }\n    None\n}\n\nfn has_arg(args: &[String], find_arg: &str) -> bool {\n    args.iter().any(|arg| find_arg == arg.split('=').next().unwrap())\n}\n\n#[test]\nfn test_arg_value() {\n    let args = &[\"--bar=bar\", \"--foobar\", \"123\", \"--foo\"].map(String::from);\n\n    assert_eq!(arg_value(&[], \"--foobar\", |_| true), None);\n    assert_eq!(arg_value(args, \"--bar\", |_| false), None);\n    assert_eq!(arg_value(args, \"--bar\", |_| true), Some(\"bar\"));\n    assert_eq!(arg_value(args, \"--bar\", |p| p == \"bar\"), Some(\"bar\"));\n    assert_eq!(arg_value(args, \"--bar\", |p| p == \"foo\"), None);\n    assert_eq!(arg_value(args, \"--foobar\", |p| p == \"foo\"), None);\n    assert_eq!(arg_value(args, \"--foobar\", |p| p == \"123\"), Some(\"123\"));\n    assert_eq!(arg_value(args, \"--foobar\", |p| p.contains(\"12\")), Some(\"123\"));\n    assert_eq!(arg_value(args, \"--foo\", |_| true), None);\n}\n\n#[test]\nfn test_has_arg() {\n    let args = &[\"--foo=bar\", \"-vV\", \"--baz\"].map(String::from);\n    assert!(has_arg(args, \"--foo\"));\n    assert!(has_arg(args, \"--baz\"));\n    assert!(has_arg(args, \"-vV\"));\n\n    assert!(!has_arg(args, \"--bar\"));\n}\n\nfn track_clippy_args(psess: &mut ParseSess, args_env_var: Option<&str>) {\n    psess\n        .env_depinfo\n        .get_mut()\n        .insert((sym::CLIPPY_ARGS, args_env_var.map(Symbol::intern)));\n}\n\n/// Track files that may be accessed at runtime in `file_depinfo` so that cargo will re-run clippy\n/// when any of them are modified\nfn track_files(psess: &mut ParseSess) {\n    let file_depinfo = psess.file_depinfo.get_mut();\n\n    // Used by `clippy::cargo` lints and to determine the MSRV. `cargo clippy` executes `clippy-driver`\n    // with the current directory set to `CARGO_MANIFEST_DIR` so a relative path is fine\n    if Path::new(\"Cargo.toml\").exists() {\n        file_depinfo.insert(sym::Cargo_toml);\n    }\n\n    // `clippy.toml` will be automatically tracked as it's loaded with `sess.source_map().load_file()`\n\n    // During development track the `clippy-driver` executable so that cargo will re-run clippy whenever\n    // it is rebuilt\n    if cfg!(debug_assertions)\n        && let Ok(current_exe) = env::current_exe()\n        && let Some(current_exe) = current_exe.to_str()\n    {\n        file_depinfo.insert(Symbol::intern(current_exe));\n    }\n}\n\nstruct DefaultCallbacks;\nimpl rustc_driver::Callbacks for DefaultCallbacks {}\n\n/// This is different from `DefaultCallbacks` that it will inform Cargo to track the value of\n/// `CLIPPY_ARGS` environment variable.\nstruct RustcCallbacks {\n    clippy_args_var: Option<String>,\n}\n\nimpl rustc_driver::Callbacks for RustcCallbacks {\n    fn config(&mut self, config: &mut interface::Config) {\n        let clippy_args_var = self.clippy_args_var.take();\n        config.psess_created = Some(Box::new(move |psess| {\n            track_clippy_args(psess, clippy_args_var.as_deref());\n        }));\n        config.extra_symbols = sym::EXTRA_SYMBOLS.into();\n    }\n}\n\nstruct ClippyCallbacks {\n    clippy_args_var: Option<String>,\n}\n\nimpl rustc_driver::Callbacks for ClippyCallbacks {\n    #[expect(rustc::bad_opt_access, reason = \"necessary in clippy driver to set `mir_opt_level`\")]\n    fn config(&mut self, config: &mut interface::Config) {\n        let conf_path = clippy_config::lookup_conf_file();\n        let previous = config.register_lints.take();\n        let clippy_args_var = self.clippy_args_var.take();\n        config.psess_created = Some(Box::new(move |psess| {\n            track_clippy_args(psess, clippy_args_var.as_deref());\n            track_files(psess);\n\n            // Trigger a rebuild if CLIPPY_CONF_DIR changes. The value must be a valid string so\n            // changes between dirs that are invalid UTF-8 will not trigger rebuilds\n            psess.env_depinfo.get_mut().insert((\n                sym::CLIPPY_CONF_DIR,\n                env::var(\"CLIPPY_CONF_DIR\").ok().map(|dir| Symbol::intern(&dir)),\n            ));\n        }));\n        config.register_lints = Some(Box::new(move |sess, lint_store| {\n            // technically we're ~guaranteed that this is none but might as well call anything that\n            // is there already. Certainly it can't hurt.\n            if let Some(previous) = &previous {\n                (previous)(sess, lint_store);\n            }\n\n            let mut list_builder = LintListBuilder::default();\n            list_builder.insert(clippy_lints::declared_lints::LINTS);\n            list_builder.register(lint_store);\n\n            let conf = clippy_config::Conf::read(sess, &conf_path);\n            clippy_lints::register_lint_passes(lint_store, conf);\n\n            #[cfg(feature = \"internal\")]\n            clippy_lints_internal::register_lints(lint_store);\n        }));\n        config.extra_symbols = sym::EXTRA_SYMBOLS.into();\n\n        // FIXME: #4825; This is required, because Clippy lints that are based on MIR have to be\n        // run on the unoptimized MIR. On the other hand this results in some false negatives. If\n        // MIR passes can be enabled / disabled separately, we should figure out, what passes to\n        // use for Clippy.\n        config.opts.unstable_opts.mir_opt_level = Some(0);\n        config.opts.unstable_opts.mir_enable_passes =\n            vec![(\"CheckNull\".to_owned(), false), (\"CheckAlignment\".to_owned(), false)];\n\n        // Disable flattening and inlining of format_args!(), so the HIR matches with the AST.\n        config.opts.unstable_opts.flatten_format_args = false;\n    }\n}\n\nfn display_help() -> ExitCode {\n    if writeln!(&mut anstream::stdout().lock(), \"{}\", help_message()).is_err() {\n        ExitCode::FAILURE\n    } else {\n        ExitCode::SUCCESS\n    }\n}\n\nconst BUG_REPORT_URL: &str = \"https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml\";\n\nfn main() -> ExitCode {\n    let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());\n\n    rustc_driver::init_rustc_env_logger(&early_dcx);\n\n    rustc_driver::install_ice_hook(BUG_REPORT_URL, |dcx| {\n        // FIXME: this macro calls unwrap internally but is called in a panicking context!  It's not\n        // as simple as moving the call from the hook to main, because `install_ice_hook` doesn't\n        // accept a generic closure.\n        let version_info = rustc_tools_util::get_version_info!();\n        dcx.handle().note(format!(\"Clippy version: {version_info}\"));\n    });\n\n    rustc_driver::catch_with_exit_code(move || {\n        let mut orig_args = rustc_driver::args::raw_args(&early_dcx);\n\n        let has_sysroot_arg = |args: &mut [String]| -> bool {\n            if has_arg(args, \"--sysroot\") {\n                return true;\n            }\n            // https://doc.rust-lang.org/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path\n            // Beside checking for existence of `--sysroot` on the command line, we need to\n            // check for the arg files that are prefixed with @ as well to be consistent with rustc\n            for arg in args.iter() {\n                if let Some(arg_file_path) = arg.strip_prefix('@')\n                    && let Ok(arg_file) = read_to_string(arg_file_path)\n                {\n                    let split_arg_file: Vec<String> = arg_file.lines().map(ToString::to_string).collect();\n                    if has_arg(&split_arg_file, \"--sysroot\") {\n                        return true;\n                    }\n                }\n            }\n            false\n        };\n\n        let sys_root_env = std::env::var(\"SYSROOT\").ok();\n        let pass_sysroot_env_if_given = |args: &mut Vec<String>, sys_root_env| {\n            if let Some(sys_root) = sys_root_env\n                && !has_sysroot_arg(args)\n            {\n                args.extend(vec![\"--sysroot\".into(), sys_root]);\n            }\n        };\n\n        // make \"clippy-driver --rustc\" work like a subcommand that passes further args to \"rustc\"\n        // for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver\n        // uses\n        if let Some(pos) = orig_args.iter().position(|arg| arg == \"--rustc\") {\n            orig_args.remove(pos);\n            orig_args[0] = \"rustc\".to_string();\n\n            let mut args: Vec<String> = orig_args.clone();\n            pass_sysroot_env_if_given(&mut args, sys_root_env);\n\n            rustc_driver::run_compiler(&args, &mut DefaultCallbacks);\n            return ExitCode::SUCCESS;\n        }\n\n        if orig_args.iter().any(|a| a == \"--version\" || a == \"-V\") {\n            let version_info = rustc_tools_util::get_version_info!();\n\n            return match writeln!(&mut anstream::stdout().lock(), \"{version_info}\") {\n                Ok(()) => ExitCode::SUCCESS,\n                Err(_) => ExitCode::FAILURE,\n            };\n        }\n\n        // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.\n        // We're invoking the compiler programmatically, so we ignore this/\n        let wrapper_mode = orig_args.get(1).map(Path::new).and_then(Path::file_stem) == Some(\"rustc\".as_ref());\n\n        if wrapper_mode {\n            // we still want to be able to invoke it normally though\n            orig_args.remove(1);\n        }\n\n        if !wrapper_mode && (orig_args.iter().any(|a| a == \"--help\" || a == \"-h\") || orig_args.len() == 1) {\n            return display_help();\n        }\n\n        let mut args: Vec<String> = orig_args.clone();\n        pass_sysroot_env_if_given(&mut args, sys_root_env);\n\n        let mut no_deps = false;\n        let clippy_args_var = env::var(\"CLIPPY_ARGS\").ok();\n        let clippy_args = clippy_args_var\n            .as_deref()\n            .unwrap_or_default()\n            .split(\"__CLIPPY_HACKERY__\")\n            .filter_map(|s| match s {\n                \"\" => None,\n                \"--no-deps\" => {\n                    no_deps = true;\n                    None\n                },\n                _ => Some(s.to_string()),\n            })\n            .chain(vec![\"--cfg\".into(), \"clippy\".into()])\n            .collect::<Vec<String>>();\n\n        // If no Clippy lints will be run we do not need to run Clippy\n        let cap_lints_allow = arg_value(&orig_args, \"--cap-lints\", |val| val == \"allow\").is_some()\n            && arg_value(&orig_args, \"--force-warn\", |val| val.contains(\"clippy::\")).is_none();\n\n        // If `--no-deps` is enabled only lint the primary package\n        let relevant_package = !no_deps || env::var(\"CARGO_PRIMARY_PACKAGE\").is_ok();\n\n        // Do not run Clippy for Cargo's info queries so that invalid CLIPPY_ARGS are not cached\n        // https://github.com/rust-lang/cargo/issues/14385\n        let info_query = has_arg(&orig_args, \"-vV\")\n            || arg_value(&orig_args, \"--print\", |val| val != \"crate-root-lint-levels\").is_some();\n\n        let clippy_enabled = !cap_lints_allow && relevant_package && !info_query;\n        if clippy_enabled {\n            args.extend(clippy_args);\n            rustc_driver::run_compiler(&args, &mut ClippyCallbacks { clippy_args_var });\n        } else {\n            rustc_driver::run_compiler(&args, &mut RustcCallbacks { clippy_args_var });\n        }\n        ExitCode::SUCCESS\n    })\n}\n\n#[must_use]\nfn help_message() -> &'static str {\n    color_print::cstr!(\n        \"Checks a file to catch common mistakes and improve your Rust code.\nRun <cyan>clippy-driver</> with the same arguments you use for <cyan>rustc</>\n\n<green,bold>Usage</>:\n    <cyan,bold>clippy-driver</> <cyan>[OPTIONS] INPUT</>\n\n<green,bold>Common options:</>\n    <cyan,bold>-h</>, <cyan,bold>--help</>               Print this message\n    <cyan,bold>-V</>, <cyan,bold>--version</>            Print version info and exit\n    <cyan,bold>--rustc</>                  Pass all arguments to <cyan>rustc</>\n\n<green,bold>Allowing / Denying lints</>\nYou can use tool lints to allow or deny lints from your code, e.g.:\n\n    <yellow,bold>#[allow(clippy::needless_lifetimes)]</>\n\"\n    )\n}\n"
  },
  {
    "path": "src/main.rs",
    "content": "// We need this feature as it changes `dylib` linking behavior and allows us to link to\n// `rustc_driver`.\n#![feature(rustc_private)]\n// warn on lints, that are included in `rust-lang/rust`s bootstrap\n#![warn(rust_2018_idioms, unused_lifetimes)]\n\nextern crate rustc_driver;\n\nuse std::env;\nuse std::io::Write as _;\nuse std::path::PathBuf;\nuse std::process::{self, Command, exit};\n\nfn show_help() {\n    if writeln!(&mut anstream::stdout().lock(), \"{}\", help_message()).is_err() {\n        exit(rustc_driver::EXIT_FAILURE);\n    }\n}\n\nfn show_version() {\n    let version_info = rustc_tools_util::get_version_info!();\n    if writeln!(&mut anstream::stdout().lock(), \"{version_info}\").is_err() {\n        exit(rustc_driver::EXIT_FAILURE);\n    }\n}\n\npub fn main() {\n    // Check for version and help flags even when invoked as 'cargo-clippy'\n    if env::args().any(|a| a == \"--help\" || a == \"-h\") {\n        show_help();\n        return;\n    }\n\n    if env::args().any(|a| a == \"--version\" || a == \"-V\") {\n        show_version();\n        return;\n    }\n\n    if let Some(pos) = env::args().position(|a| a == \"--explain\") {\n        if let Some(mut lint) = env::args().nth(pos + 1) {\n            lint.make_ascii_lowercase();\n            process::exit(clippy_lints::explain(\n                &lint.strip_prefix(\"clippy::\").unwrap_or(&lint).replace('-', \"_\"),\n            ));\n        } else {\n            show_help();\n        }\n        return;\n    }\n\n    if let Err(code) = process(env::args().skip(2)) {\n        process::exit(code);\n    }\n}\n\nstruct ClippyCmd {\n    cargo_subcommand: &'static str,\n    args: Vec<String>,\n    clippy_args: Vec<String>,\n}\n\nimpl ClippyCmd {\n    fn new<I>(mut old_args: I) -> Self\n    where\n        I: Iterator<Item = String>,\n    {\n        let mut cargo_subcommand = \"check\";\n        let mut args = vec![];\n        let mut clippy_args: Vec<String> = vec![];\n\n        for arg in old_args.by_ref() {\n            match arg.as_str() {\n                \"--fix\" => {\n                    cargo_subcommand = \"fix\";\n                    continue;\n                },\n                \"--no-deps\" => {\n                    clippy_args.push(\"--no-deps\".into());\n                    continue;\n                },\n                \"--\" => break,\n                _ => {},\n            }\n\n            args.push(arg);\n        }\n\n        clippy_args.append(&mut (old_args.collect()));\n        if cargo_subcommand == \"fix\" && !clippy_args.iter().any(|arg| arg == \"--no-deps\") {\n            clippy_args.push(\"--no-deps\".into());\n        }\n\n        Self {\n            cargo_subcommand,\n            args,\n            clippy_args,\n        }\n    }\n\n    fn path() -> PathBuf {\n        let mut path = env::current_exe()\n            .expect(\"current executable path invalid\")\n            .with_file_name(\"clippy-driver\");\n\n        if cfg!(windows) {\n            path.set_extension(\"exe\");\n        }\n\n        path\n    }\n\n    fn into_std_cmd(self) -> Command {\n        let mut cmd = Command::new(env::var(\"CARGO\").unwrap_or_else(|_| \"cargo\".into()));\n        let clippy_args: String = self\n            .clippy_args\n            .iter()\n            .fold(String::new(), |s, arg| s + arg + \"__CLIPPY_HACKERY__\");\n\n        // Currently, `CLIPPY_TERMINAL_WIDTH` is used only to format \"unknown field\" error messages.\n        let terminal_width = termize::dimensions().map_or(0, |(w, _)| w);\n\n        cmd.env(\"RUSTC_WORKSPACE_WRAPPER\", Self::path())\n            .env(\"CLIPPY_ARGS\", clippy_args)\n            .env(\"CLIPPY_TERMINAL_WIDTH\", terminal_width.to_string())\n            .arg(self.cargo_subcommand)\n            .args(&self.args);\n\n        cmd\n    }\n}\n\nfn process<I>(old_args: I) -> Result<(), i32>\nwhere\n    I: Iterator<Item = String>,\n{\n    let cmd = ClippyCmd::new(old_args);\n\n    let mut cmd = cmd.into_std_cmd();\n\n    let exit_status = cmd\n        .spawn()\n        .expect(\"could not run cargo\")\n        .wait()\n        .expect(\"failed to wait for cargo?\");\n\n    if exit_status.success() {\n        Ok(())\n    } else {\n        Err(exit_status.code().unwrap_or(-1))\n    }\n}\n\n#[must_use]\npub fn help_message() -> &'static str {\n    color_print::cstr!(\n\"Checks a package to catch common mistakes and improve your Rust code.\n\n<green,bold>Usage</>:\n    <cyan,bold>cargo clippy</> <cyan>[OPTIONS] [--] [<<ARGS>>...]</>\n\n<green,bold>Common options:</>\n    <cyan,bold>--no-deps</>                Run Clippy only on the given crate, without linting the dependencies\n    <cyan,bold>--fix</>                    Automatically apply lint suggestions. This flag implies <cyan>--no-deps</> and <cyan>--all-targets</>\n    <cyan,bold>-h</>, <cyan,bold>--help</>               Print this message\n    <cyan,bold>-V</>, <cyan,bold>--version</>            Print version info and exit\n    <cyan,bold>--explain [LINT]</>         Print the documentation for a given lint\n\nSee all options with <cyan,bold>cargo check --help</>.\n\n<green,bold>Allowing / Denying lints</>\n\nTo allow or deny a lint from the command line you can use <cyan,bold>cargo clippy --</> with:\n\n    <cyan,bold>-W</> / <cyan,bold>--warn</> <cyan>[LINT]</>       Set lint warnings\n    <cyan,bold>-A</> / <cyan,bold>--allow</> <cyan>[LINT]</>      Set lint allowed\n    <cyan,bold>-D</> / <cyan,bold>--deny</> <cyan>[LINT]</>       Set lint denied\n    <cyan,bold>-F</> / <cyan,bold>--forbid</> <cyan>[LINT]</>     Set lint forbidden\n\nYou can use tool lints to allow or deny lints from your code, e.g.:\n\n    <yellow,bold>#[allow(clippy::needless_lifetimes)]</>\n\n<green,bold>Manifest Options:</>\n    <cyan,bold>--manifest-path</> <cyan><<PATH>></>  Path to Cargo.toml\n    <cyan,bold>--frozen</>                Require Cargo.lock and cache are up to date\n    <cyan,bold>--locked</>                Require Cargo.lock is up to date\n    <cyan,bold>--offline</>               Run without accessing the network\n\")\n}\n#[cfg(test)]\nmod tests {\n    use super::ClippyCmd;\n\n    #[test]\n    fn fix() {\n        let args = \"cargo clippy --fix\".split_whitespace().map(ToString::to_string);\n        let cmd = ClippyCmd::new(args);\n        assert_eq!(\"fix\", cmd.cargo_subcommand);\n        assert!(!cmd.args.iter().any(|arg| arg.ends_with(\"unstable-options\")));\n    }\n\n    #[test]\n    fn fix_implies_no_deps() {\n        let args = \"cargo clippy --fix\".split_whitespace().map(ToString::to_string);\n        let cmd = ClippyCmd::new(args);\n        assert!(cmd.clippy_args.iter().any(|arg| arg == \"--no-deps\"));\n    }\n\n    #[test]\n    fn no_deps_not_duplicated_with_fix() {\n        let args = \"cargo clippy --fix -- --no-deps\"\n            .split_whitespace()\n            .map(ToString::to_string);\n        let cmd = ClippyCmd::new(args);\n        assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == \"--no-deps\").count(), 1);\n    }\n\n    #[test]\n    fn check() {\n        let args = \"cargo clippy\".split_whitespace().map(ToString::to_string);\n        let cmd = ClippyCmd::new(args);\n        assert_eq!(\"check\", cmd.cargo_subcommand);\n    }\n}\n"
  },
  {
    "path": "tests/check-fmt.rs",
    "content": "#![warn(rust_2018_idioms, unused_lifetimes)]\n\nuse std::path::PathBuf;\nuse std::process::Command;\n\n#[test]\nfn fmt() {\n    if option_env!(\"RUSTC_TEST_SUITE\").is_some() || option_env!(\"NO_FMT_TEST\").is_some() {\n        return;\n    }\n\n    let root_dir = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"));\n    let output = Command::new(\"cargo\")\n        .current_dir(root_dir)\n        .args([\"dev\", \"fmt\", \"--check\"])\n        .output()\n        .unwrap();\n\n    println!(\"status: {}\", output.status);\n    println!(\"stdout: {}\", String::from_utf8_lossy(&output.stdout));\n    println!(\"stderr: {}\", String::from_utf8_lossy(&output.stderr));\n\n    assert!(\n        output.status.success(),\n        \"Formatting check failed. Run `cargo dev fmt` to update formatting.\"\n    );\n}\n"
  },
  {
    "path": "tests/clippy.toml",
    "content": "# default config for tests, overrides clippy.toml at the project root\nlint-commented-code = false\n"
  },
  {
    "path": "tests/compile-test.rs",
    "content": "#![feature(rustc_private)]\n#![warn(rust_2018_idioms, unused_lifetimes)]\n#![allow(unused_extern_crates)]\n\nuse askama::Template;\nuse askama::filters::Safe;\nuse cargo_metadata::Message;\nuse cargo_metadata::diagnostic::{Applicability, Diagnostic};\nuse clippy_config::ClippyConfiguration;\nuse clippy_lints::declared_lints::LINTS;\nuse clippy_lints::deprecated_lints::{DEPRECATED, DEPRECATED_VERSION, RENAMED};\nuse declare_clippy_lint::LintInfo;\nuse pulldown_cmark::{Options, Parser, html};\nuse serde::Deserialize;\nuse test_utils::IS_RUSTC_TEST_SUITE;\nuse ui_test::custom_flags::Flag;\nuse ui_test::custom_flags::edition::Edition;\nuse ui_test::custom_flags::rustfix::RustfixMode;\nuse ui_test::dependencies::DependencyBuilder;\nuse ui_test::spanned::Spanned;\nuse ui_test::status_emitter::StatusEmitter;\nuse ui_test::{Args, CommandBuilder, Config, Match, error_on_output_conflict};\n\nuse std::collections::{BTreeMap, HashMap};\nuse std::env::{self, set_var, var_os};\nuse std::ffi::{OsStr, OsString};\nuse std::fmt::Write;\nuse std::path::{Path, PathBuf};\nuse std::sync::mpsc::{Sender, channel};\nuse std::{fs, iter, thread};\n\nmod test_utils;\n\n/// All crates used in internal UI tests are listed here.\n/// We directly re-use these crates from their normal clippy builds, so we don't have them\n/// in `clippy_test_devs`. That saves a lot of time but also means they don't work in a stage 1\n/// test in rustc bootstrap.\nstatic INTERNAL_TEST_DEPENDENCIES: &[&str] = &[\"clippy_config\", \"clippy_lints\", \"clippy_utils\"];\n\n/// Produces a string with an `--extern` flag for all `INTERNAL_TEST_DEPENDENCIES`.\n///\n/// The dependency files are located by parsing the depinfo file for this test\n/// module. This assumes the `-Z binary-dep-depinfo` flag is enabled. All test\n/// dependencies must be added to Cargo.toml at the project root. Test\n/// dependencies that are not *directly* used by this test module require an\n/// `extern crate` declaration.\nfn internal_extern_flags() -> Vec<String> {\n    let current_exe_path = env::current_exe().unwrap();\n    let deps_path = current_exe_path.parent().unwrap();\n    let current_exe_depinfo = {\n        let mut path = current_exe_path.clone();\n        path.set_extension(\"d\");\n        fs::read_to_string(path).unwrap()\n    };\n    let mut crates = BTreeMap::<&str, &str>::new();\n    for line in current_exe_depinfo.lines() {\n        // each dependency is expected to have a Makefile rule like `/path/to/crate-hash.rlib:`\n        let parse_name_path = || {\n            if line.starts_with(char::is_whitespace) {\n                return None;\n            }\n            let path_str = line.strip_suffix(':')?;\n            let path = Path::new(path_str);\n            if !matches!(path.extension()?.to_str()?, \"rlib\" | \"so\" | \"dylib\" | \"dll\") {\n                return None;\n            }\n            let (name, _hash) = path.file_stem()?.to_str()?.rsplit_once('-')?;\n            // the \"lib\" prefix is not present for dll files\n            let name = name.strip_prefix(\"lib\").unwrap_or(name);\n            Some((name, path_str))\n        };\n        if let Some((name, path)) = parse_name_path()\n            && INTERNAL_TEST_DEPENDENCIES.contains(&name)\n        {\n            // A dependency may be listed twice if it is available in sysroot,\n            // and the sysroot dependencies are listed first.\n            crates.insert(name, path);\n        }\n    }\n    let not_found: Vec<&str> = INTERNAL_TEST_DEPENDENCIES\n        .iter()\n        .copied()\n        .filter(|n| !crates.contains_key(n))\n        .collect();\n    assert!(\n        not_found.is_empty(),\n        \"dependencies not found in depinfo: {not_found:?}\\n\\\n        help: Make sure the `-Z binary-dep-depinfo` rust flag is enabled\\n\\\n        help: Try adding to dev-dependencies in Cargo.toml\\n\\\n        help: Be sure to also add `extern crate ...;` to tests/compile-test.rs\",\n    );\n    crates\n        .into_iter()\n        .map(|(name, path)| format!(\"--extern={name}={path}\"))\n        .chain([format!(\"-Ldependency={}\", deps_path.display())])\n        .collect()\n}\n\n// whether to run internal tests or not\nconst RUN_INTERNAL_TESTS: bool = cfg!(feature = \"internal\");\n\nstruct TestContext {\n    args: Args,\n    diagnostic_collector: Option<DiagnosticCollector>,\n    collector_thread: Option<thread::JoinHandle<()>>,\n}\n\nimpl TestContext {\n    fn new() -> Self {\n        let mut args = Args::test().unwrap();\n        args.bless |= var_os(\"RUSTC_BLESS\").is_some_and(|v| v != \"0\");\n        let (diagnostic_collector, collector_thread) = var_os(\"COLLECT_METADATA\")\n            .is_some()\n            .then(DiagnosticCollector::spawn)\n            .unzip();\n        Self {\n            args,\n            diagnostic_collector,\n            collector_thread,\n        }\n    }\n\n    fn base_config(&self, test_dir: &str, mandatory_annotations: bool) -> Config {\n        let target_dir = PathBuf::from(var_os(\"CARGO_TARGET_DIR\").unwrap_or_else(|| \"target\".into()));\n        let mut config = Config {\n            output_conflict_handling: error_on_output_conflict,\n            // Pre-fill filters with TESTNAME; will be later extended with `self.args`.\n            filter_files: env::var(\"TESTNAME\")\n                .map(|filters| {\n                    filters\n                        .split(',')\n                        // Make sure that if TESTNAME is empty we produce the empty list here,\n                        // not a list containing an empty string.\n                        .filter(|s| !s.is_empty())\n                        .map(str::to_string)\n                        .collect()\n                })\n                .unwrap_or_default(),\n            target: None,\n            bless_command: Some(if IS_RUSTC_TEST_SUITE {\n                \"./x test src/tools/clippy --bless\".into()\n            } else {\n                \"cargo uibless\".into()\n            }),\n            out_dir: target_dir.join(\"ui_test\"),\n            ..Config::rustc(Path::new(\"tests\").join(test_dir))\n        };\n        let defaults = config.comment_defaults.base();\n        defaults.set_custom(\"edition\", Edition(\"2024\".into()));\n        defaults.set_custom(\n            \"dependencies\",\n            DependencyBuilder {\n                program: {\n                    let mut p = CommandBuilder::cargo();\n                    // If we run in bootstrap, we need to use the right compiler for building the\n                    // tests -- not the compiler that built clippy, but the compiler that got linked\n                    // into clippy. Just invoking TEST_RUSTC does not work because LD_LIBRARY_PATH\n                    // is set in a way that makes it pick the wrong sysroot. Sadly due to\n                    // <https://github.com/rust-lang/cargo/issues/4423> we cannot use RUSTFLAGS to\n                    // set `--sysroot`, so we need to use bootstrap's rustc wrapper. That wrapper\n                    // however has some staging logic that is hurting us here, so to work around\n                    // that we set both the \"real\" and \"staging\" rustc to TEST_RUSTC, including the\n                    // associated library paths.\n                    #[expect(\n                        clippy::option_env_unwrap,\n                        reason = \"TEST_RUSTC will ensure that the requested env vars are set during compile time\"\n                    )]\n                    if let Some(rustc) = option_env!(\"TEST_RUSTC\") {\n                        let libdir = option_env!(\"TEST_RUSTC_LIB\").unwrap();\n                        let sysroot = option_env!(\"TEST_SYSROOT\").unwrap();\n                        p.envs.push((\"RUSTC_REAL\".into(), Some(rustc.into())));\n                        p.envs.push((\"RUSTC_REAL_LIBDIR\".into(), Some(libdir.into())));\n                        p.envs.push((\"RUSTC_SNAPSHOT\".into(), Some(rustc.into())));\n                        p.envs.push((\"RUSTC_SNAPSHOT_LIBDIR\".into(), Some(libdir.into())));\n                        p.envs.push((\"RUSTC_SYSROOT\".into(), Some(sysroot.into())));\n                        // Ensure we rebuild the dependencies when the sysroot changes.\n                        // (Bootstrap usually sets this automatically, but since we invoke cargo\n                        // ourselves we have to do it.)\n                        p.args.push(\"-Zbinary-dep-depinfo\".into());\n                    }\n                    p\n                },\n                crate_manifest_path: Path::new(\"clippy_test_deps\").join(\"Cargo.toml\"),\n                build_std: None,\n                bless_lockfile: self.args.bless,\n            },\n        );\n        defaults.exit_status = None.into();\n        if mandatory_annotations {\n            defaults.require_annotations = Some(Spanned::dummy(true)).into();\n        } else {\n            defaults.require_annotations = None.into();\n        }\n        defaults.diagnostic_code_prefix = Some(Spanned::dummy(\"clippy::\".into())).into();\n        defaults.set_custom(\"rustfix\", RustfixMode::Everything);\n        if let Some(collector) = self.diagnostic_collector.clone() {\n            defaults.set_custom(\"diagnostic-collector\", collector);\n        }\n        config.with_args(&self.args);\n\n        config.program.args.extend(\n            [\n                \"--emit=metadata\",\n                \"-Aunused\",\n                \"-Ainternal_features\",\n                \"-Zui-testing\",\n                \"-Zdeduplicate-diagnostics=no\",\n                \"-Dwarnings\",\n            ]\n            .map(OsString::from),\n        );\n\n        // Prevent rustc from creating `rustc-ice-*` files the console output is enough.\n        config.program.envs.push((\"RUSTC_ICE\".into(), Some(\"0\".into())));\n\n        if let Some(host_libs) = option_env!(\"HOST_LIBS\") {\n            let dep = format!(\"-Ldependency={}\", Path::new(host_libs).join(\"deps\").display());\n            config.program.args.push(dep.into());\n        }\n        if let Some(sysroot) = option_env!(\"TEST_SYSROOT\") {\n            config.program.args.push(format!(\"--sysroot={sysroot}\").into());\n        }\n\n        config.program.program = PathBuf::from(env!(\"CARGO_BIN_EXE_clippy-driver\"));\n\n        config\n    }\n}\n\nfn run_ui(cx: &TestContext) {\n    let mut config = cx.base_config(\"ui\", true);\n    config\n        .program\n        .envs\n        .push((\"CLIPPY_CONF_DIR\".into(), Some(\"tests\".into())));\n\n    ui_test::run_tests_generic(\n        vec![config],\n        ui_test::default_file_filter,\n        ui_test::default_per_file_config,\n        Box::<dyn StatusEmitter>::from(cx.args.format),\n    )\n    .unwrap();\n}\n\nfn run_internal_tests(cx: &TestContext) {\n    if !RUN_INTERNAL_TESTS {\n        return;\n    }\n    let mut config = cx.base_config(\"ui-internal\", true);\n    config\n        .program\n        .args\n        .extend(internal_extern_flags().iter().map(OsString::from));\n    config.bless_command = Some(\"cargo uitest --features internal -- -- --bless\".into());\n\n    ui_test::run_tests_generic(\n        vec![config],\n        ui_test::default_file_filter,\n        ui_test::default_per_file_config,\n        Box::<dyn StatusEmitter>::from(cx.args.format),\n    )\n    .unwrap();\n}\n\nfn run_ui_toml(cx: &TestContext) {\n    let mut config = cx.base_config(\"ui-toml\", true);\n\n    config\n        .comment_defaults\n        .base()\n        .normalize_stderr\n        .push((Match::from(env::current_dir().unwrap().as_path()), b\"$DIR\".into()));\n\n    ui_test::run_tests_generic(\n        vec![config],\n        ui_test::default_file_filter,\n        |config, file_contents| {\n            let path = file_contents.span().file;\n            config\n                .program\n                .envs\n                .push((\"CLIPPY_CONF_DIR\".into(), Some(path.parent().unwrap().into())));\n        },\n        Box::<dyn StatusEmitter>::from(cx.args.format),\n    )\n    .unwrap();\n}\n\n// Allow `Default::default` as `OptWithSpan` is not nameable\nfn run_ui_cargo(cx: &TestContext) {\n    if IS_RUSTC_TEST_SUITE {\n        return;\n    }\n\n    let mut config = cx.base_config(\"ui-cargo\", false);\n    config.program.input_file_flag = CommandBuilder::cargo().input_file_flag;\n    config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag;\n    config.program.args = vec![\"clippy\".into(), \"--color\".into(), \"never\".into(), \"--quiet\".into()];\n    config.program.envs.extend([\n        (\"RUSTFLAGS\".into(), Some(\"-Dwarnings\".into())),\n        (\"CARGO_INCREMENTAL\".into(), Some(\"0\".into())),\n    ]);\n    // We need to do this while we still have a rustc in the `program` field.\n    config.fill_host_and_target().unwrap();\n    config.program.program.set_file_name(if cfg!(windows) {\n        \"cargo-clippy.exe\"\n    } else {\n        \"cargo-clippy\"\n    });\n    config.comment_defaults.base().custom.clear();\n\n    config\n        .comment_defaults\n        .base()\n        .normalize_stderr\n        .push((Match::from(env::current_dir().unwrap().as_path()), b\"$DIR\".into()));\n\n    let ignored_32bit = |path: &Path| {\n        // FIXME: for some reason the modules are linted in a different order for this test\n        cfg!(target_pointer_width = \"32\") && path.ends_with(\"tests/ui-cargo/module_style/fail_mod/Cargo.toml\")\n    };\n\n    ui_test::run_tests_generic(\n        vec![config],\n        |path, config| {\n            path.ends_with(\"Cargo.toml\")\n                .then(|| ui_test::default_any_file_filter(path, config) && !ignored_32bit(path))\n        },\n        |_config, _file_contents| {},\n        Box::<dyn StatusEmitter>::from(cx.args.format),\n    )\n    .unwrap();\n}\n\nfn main() {\n    unsafe {\n        set_var(\"CLIPPY_DISABLE_DOCS_LINKS\", \"true\");\n    }\n\n    let cx = TestContext::new();\n\n    // The SPEEDTEST_* env variables can be used to check Clippy's performance on your PR. It runs the\n    // affected test 1000 times and gets the average.\n    if let Ok(speedtest) = std::env::var(\"SPEEDTEST\") {\n        println!(\"----------- STARTING SPEEDTEST -----------\");\n        let f = match speedtest.as_str() {\n            \"ui\" => run_ui,\n            \"cargo\" => run_ui_cargo,\n            \"toml\" => run_ui_toml,\n            \"internal\" => run_internal_tests,\n\n            _ => panic!(\"unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]\"),\n        };\n\n        let iterations;\n        if let Ok(iterations_str) = std::env::var(\"SPEEDTEST_ITERATIONS\") {\n            iterations = iterations_str\n                .parse::<u64>()\n                .unwrap_or_else(|_| panic!(\"Couldn't parse `{iterations_str}`, please use a valid u64\"));\n        } else {\n            iterations = 1000;\n        }\n\n        let mut sum = 0;\n        for _ in 0..iterations {\n            let start = std::time::Instant::now();\n            f(&cx);\n            sum += start.elapsed().as_millis();\n        }\n        println!(\n            \"average {} time: {} millis.\",\n            speedtest.to_uppercase(),\n            sum / u128::from(iterations)\n        );\n    } else {\n        run_ui(&cx);\n        run_ui_toml(&cx);\n        run_ui_cargo(&cx);\n        run_internal_tests(&cx);\n        drop(cx.diagnostic_collector);\n\n        ui_cargo_toml_metadata();\n\n        if let Some(thread) = cx.collector_thread {\n            thread.join().unwrap();\n        }\n    }\n}\n\nfn ui_cargo_toml_metadata() {\n    let ui_cargo_path = Path::new(\"tests/ui-cargo\");\n    let cargo_common_metadata_path = ui_cargo_path.join(\"cargo_common_metadata\");\n    let publish_exceptions =\n        [\"fail_publish\", \"fail_publish_true\", \"pass_publish_empty\"].map(|path| cargo_common_metadata_path.join(path));\n\n    for entry in walkdir::WalkDir::new(ui_cargo_path) {\n        let entry = entry.unwrap();\n        let path = entry.path();\n        if path.file_name() != Some(OsStr::new(\"Cargo.toml\")) {\n            continue;\n        }\n\n        let toml = fs::read_to_string(path).unwrap();\n        let toml = toml::de::DeTable::parse(&toml).unwrap();\n\n        let package = toml.get_ref().get(\"package\").unwrap().get_ref().as_table().unwrap();\n\n        let name = package\n            .get(\"name\")\n            .unwrap()\n            .as_ref()\n            .as_str()\n            .unwrap()\n            .replace('-', \"_\");\n        assert!(\n            path.parent()\n                .unwrap()\n                .components()\n                .map(|component| component.as_os_str().to_string_lossy().replace('-', \"_\"))\n                .any(|s| *s == name)\n                || path.starts_with(&cargo_common_metadata_path),\n            \"`{}` has incorrect package name\",\n            path.display(),\n        );\n\n        let publish = package\n            .get(\"publish\")\n            .and_then(|x| x.get_ref().as_bool())\n            .unwrap_or(true);\n        assert!(\n            !publish || publish_exceptions.contains(&path.parent().unwrap().to_path_buf()),\n            \"`{}` lacks `publish = false`\",\n            path.display(),\n        );\n    }\n}\n\n#[derive(Template)]\n#[template(path = \"index_template.html\")]\nstruct Renderer<'a> {\n    count: usize,\n    lints: &'a Vec<LintMetadata>,\n}\n\nimpl Renderer<'_> {\n    fn markdown(input: &str) -> Safe<String> {\n        let input = clippy_config::sanitize_explanation(input);\n        let parser = Parser::new_ext(&input, Options::all());\n        let mut html_output = String::new();\n        html::push_html(&mut html_output, parser);\n        // Oh deer, what a hack :O\n        Safe(html_output.replace(\"<table\", \"<table class=\\\"table\\\"\"))\n    }\n}\n\n#[derive(Deserialize)]\n#[serde(untagged)]\nenum DiagnosticOrMessage {\n    Diagnostic(Diagnostic),\n    Message(Message),\n}\n\n/// Collects applicabilities from the diagnostics produced for each UI test, producing the\n/// `util/gh-pages/index.html` file used by <https://rust-lang.github.io/rust-clippy/>\n#[derive(Debug, Clone)]\nstruct DiagnosticCollector {\n    sender: Sender<Vec<u8>>,\n}\n\nimpl DiagnosticCollector {\n    #[expect(clippy::assertions_on_constants)]\n    fn spawn() -> (Self, thread::JoinHandle<()>) {\n        assert!(!IS_RUSTC_TEST_SUITE && !RUN_INTERNAL_TESTS);\n\n        let (sender, receiver) = channel::<Vec<u8>>();\n\n        let handle = thread::spawn(|| {\n            let mut applicabilities = HashMap::new();\n\n            for stderr in receiver {\n                for line in stderr.split(|&byte| byte == b'\\n') {\n                    let diag = match serde_json::from_slice(line) {\n                        Ok(DiagnosticOrMessage::Diagnostic(diag)) => diag,\n                        Ok(DiagnosticOrMessage::Message(Message::CompilerMessage(message))) => message.message,\n                        _ => continue,\n                    };\n\n                    if let Some(lint) = diag.code.as_ref().and_then(|code| code.code.strip_prefix(\"clippy::\")) {\n                        let applicability = applicabilities\n                            .entry(lint.to_string())\n                            .or_insert(Applicability::Unspecified);\n                        let diag_applicability = diag\n                            .children\n                            .iter()\n                            .flat_map(|child| &child.spans)\n                            .filter_map(|span| span.suggestion_applicability.clone())\n                            .max_by_key(applicability_ord);\n                        if let Some(diag_applicability) = diag_applicability\n                            && applicability_ord(&diag_applicability) > applicability_ord(applicability)\n                        {\n                            *applicability = diag_applicability;\n                        }\n                    }\n                }\n            }\n\n            let configs = clippy_config::get_configuration_metadata();\n            let mut metadata: Vec<LintMetadata> = LINTS\n                .iter()\n                .map(|lint| LintMetadata::new(lint, &applicabilities, &configs))\n                .chain(\n                    iter::zip(DEPRECATED, DEPRECATED_VERSION)\n                        .map(|((lint, reason), version)| LintMetadata::new_deprecated(lint, reason, version)),\n                )\n                .collect();\n\n            metadata.sort_unstable_by(|a, b| a.id.cmp(&b.id));\n\n            fs::write(\n                \"util/gh-pages/index.html\",\n                Renderer {\n                    count: LINTS.len(),\n                    lints: &metadata,\n                }\n                .render()\n                .unwrap(),\n            )\n            .unwrap();\n        });\n\n        (Self { sender }, handle)\n    }\n}\n\nfn applicability_ord(applicability: &Applicability) -> u8 {\n    match applicability {\n        Applicability::MachineApplicable => 4,\n        Applicability::HasPlaceholders => 3,\n        Applicability::MaybeIncorrect => 2,\n        Applicability::Unspecified => 1,\n        _ => unimplemented!(),\n    }\n}\n\nimpl Flag for DiagnosticCollector {\n    fn post_test_action(\n        &self,\n        _config: &ui_test::per_test_config::TestConfig,\n        output: &std::process::Output,\n        _build_manager: &ui_test::build_manager::BuildManager,\n    ) -> Result<(), ui_test::Errored> {\n        if !output.stderr.is_empty() {\n            self.sender.send(output.stderr.clone()).unwrap();\n        }\n        Ok(())\n    }\n\n    fn clone_inner(&self) -> Box<dyn Flag> {\n        Box::new(self.clone())\n    }\n\n    fn must_be_unique(&self) -> bool {\n        true\n    }\n}\n\n#[derive(Debug)]\nstruct LintMetadata {\n    id: String,\n    id_location: Option<&'static str>,\n    group: &'static str,\n    level: &'static str,\n    docs: String,\n    version: &'static str,\n    applicability: Applicability,\n}\n\nimpl LintMetadata {\n    fn new(lint: &LintInfo, applicabilities: &HashMap<String, Applicability>, configs: &[ClippyConfiguration]) -> Self {\n        let name = lint.name_lower();\n        let applicability = applicabilities\n            .get(&name)\n            .cloned()\n            .unwrap_or(Applicability::Unspecified);\n        let past_names = RENAMED\n            .iter()\n            .filter(|(_, new_name)| new_name.strip_prefix(\"clippy::\") == Some(&name))\n            .map(|(old_name, _)| old_name.strip_prefix(\"clippy::\").unwrap())\n            .collect::<Vec<_>>();\n        let mut docs = lint.explanation.to_string();\n        if !past_names.is_empty() {\n            docs.push_str(\"\\n### Past names\\n\\n\");\n            for past_name in past_names {\n                writeln!(&mut docs, \" * {past_name}\").unwrap();\n            }\n        }\n        let configs: Vec<_> = configs\n            .iter()\n            .filter(|conf| conf.lints.contains(&name.as_str()))\n            .collect();\n        if !configs.is_empty() {\n            docs.push_str(\"\\n### Configuration\\n\\n\");\n            for config in configs {\n                writeln!(&mut docs, \"{config}\").unwrap();\n            }\n        }\n        Self {\n            id: name,\n            id_location: Some(lint.location),\n            group: lint.category.name(),\n            level: lint.lint.default_level.as_str(),\n            docs,\n            version: lint.version,\n            applicability,\n        }\n    }\n\n    fn new_deprecated(name: &str, reason: &str, version: &'static str) -> Self {\n        // The reason starts with a lowercase letter and ends without a period.\n        // This needs to be fixed for the website.\n        let mut reason = reason.to_owned();\n        if let Some(reason) = reason.get_mut(0..1) {\n            reason.make_ascii_uppercase();\n        }\n        Self {\n            id: name.strip_prefix(\"clippy::\").unwrap().into(),\n            id_location: None,\n            group: \"deprecated\",\n            level: \"none\",\n            docs: format!(\n                \"### What it does\\n\\n\\\n                Nothing. This lint has been deprecated\\n\\n\\\n                ### Deprecation reason\\n\\n{reason}.\\n\",\n            ),\n            version,\n            applicability: Applicability::Unspecified,\n        }\n    }\n\n    fn applicability_str(&self) -> &str {\n        match self.applicability {\n            Applicability::MachineApplicable => \"MachineApplicable\",\n            Applicability::HasPlaceholders => \"HasPlaceholders\",\n            Applicability::MaybeIncorrect => \"MaybeIncorrect\",\n            Applicability::Unspecified => \"Unspecified\",\n            _ => panic!(\"needs to update this code\"),\n        }\n    }\n}\n"
  },
  {
    "path": "tests/config-consistency.rs",
    "content": "#![feature(rustc_private)]\n\n// This test checks that all lints defined in `clippy_config::conf` in `#[lints]`\n// attributes exist as Clippy lints.\n//\n// This test is a no-op if run as part of the compiler test suite\n// and will always succeed.\n\nuse std::collections::HashSet;\n\n#[test]\nfn config_consistency() {\n    if option_env!(\"RUSTC_TEST_SUITE\").is_some() {\n        return;\n    }\n\n    let lint_names: HashSet<String> = clippy_lints::declared_lints::LINTS\n        .iter()\n        .map(|lint_info| lint_info.lint.name.strip_prefix(\"clippy::\").unwrap().to_lowercase())\n        .collect();\n    for conf in clippy_config::get_configuration_metadata() {\n        for lint in conf.lints {\n            assert!(\n                lint_names.contains(*lint),\n                \"Configuration option {} references lint `{lint}` which does not exist\",\n                conf.name\n            );\n        }\n    }\n}\n"
  },
  {
    "path": "tests/config-metadata.rs",
    "content": "#![feature(rustc_private)]\n\nuse clippy_config::{ClippyConfiguration, get_configuration_metadata};\nuse itertools::Itertools;\nuse regex::Regex;\nuse std::borrow::Cow;\nuse std::{env, fs};\n\nfn metadata() -> impl Iterator<Item = ClippyConfiguration> {\n    get_configuration_metadata()\n        .into_iter()\n        .filter(|config| config.deprecation_reason.is_none())\n        .filter(|config| !config.lints.is_empty())\n}\n\n#[test]\nfn book() {\n    let path = \"book/src/lint_configuration.md\";\n    let current = fs::read_to_string(path).unwrap();\n\n    let configs = metadata().map(|conf| conf.to_markdown_paragraph()).join(\"\\n\");\n    let expected = format!(\n        r\"<!--\nThis file is generated by `cargo bless --test config-metadata`.\nPlease use that command to update the file and do not edit it by hand.\n-->\n\n# Lint Configuration Options\n\nThe following list shows each configuration option, along with a description, its default value, an example\nand lints affected.\n\n---\n\n{}\n\",\n        configs.trim(),\n    );\n\n    if current != expected {\n        if env::var_os(\"RUSTC_BLESS\").is_some_and(|v| v != \"0\") {\n            fs::write(path, expected).unwrap();\n        } else {\n            panic!(\"`{path}` is out of date, run `cargo bless --test config-metadata` to update it\");\n        }\n    }\n}\n\n#[test]\nfn changelog() {\n    let path = \"CHANGELOG.md\";\n    let current = fs::read_to_string(path).unwrap();\n\n    let configs = metadata().map(|conf| conf.to_markdown_link()).join(\"\\n\");\n\n    let re = Regex::new(\n        \"(?s)\\\n        (<!-- begin autogenerated links to configuration documentation -->)\\\n        .*\\\n        (<!-- end autogenerated links to configuration documentation -->)\\\n        \",\n    )\n    .unwrap();\n    let expected = re.replace(&current, format!(\"$1\\n{configs}\\n$2\"));\n\n    assert!(\n        matches!(expected, Cow::Owned(_)),\n        \"failed to find configuration section in `{path}`\"\n    );\n\n    if current != expected {\n        if env::var_os(\"RUSTC_BLESS\").is_some_and(|v| v != \"0\") {\n            fs::write(path, expected.as_bytes()).unwrap();\n        } else {\n            panic!(\"`{path}` is out of date, run `cargo bless --test config-metadata` to update it\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/dogfood.rs",
    "content": "//! This test is a part of quality control and makes clippy eat what it produces. Awesome lints and\n//! long error messages\n//!\n//! See [Eating your own dog food](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) for context\n\n#![warn(rust_2018_idioms, unused_lifetimes)]\n\nuse itertools::Itertools;\nuse std::io::{self, IsTerminal};\nuse std::path::PathBuf;\nuse std::process::Command;\nuse test_utils::IS_RUSTC_TEST_SUITE;\nuse ui_test::Args;\n\nmod test_utils;\n\nfn main() {\n    if IS_RUSTC_TEST_SUITE {\n        return;\n    }\n\n    let args = Args::test().unwrap();\n\n    if args.list {\n        if !args.ignored {\n            println!(\"dogfood: test\");\n        }\n    } else if !args.skip.iter().any(|arg| arg == \"dogfood\") {\n        dogfood();\n    }\n}\n\nfn dogfood() {\n    let mut failed_packages = Vec::new();\n\n    for package in [\n        \"./\",\n        \"clippy_dev\",\n        \"clippy_lints_internal\",\n        \"clippy_lints\",\n        \"clippy_utils\",\n        \"clippy_config\",\n        \"declare_clippy_lint\",\n        \"lintcheck\",\n        \"rustc_tools_util\",\n    ] {\n        println!(\"linting {package}\");\n        if !run_clippy_for_package(package) {\n            failed_packages.push(package);\n        }\n    }\n\n    assert!(\n        failed_packages.is_empty(),\n        \"Dogfood failed for packages `{}`\",\n        failed_packages.iter().join(\", \"),\n    );\n}\n\n#[must_use]\nfn run_clippy_for_package(project: &str) -> bool {\n    let root_dir = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"));\n\n    let mut command = Command::new(&*test_utils::CARGO_CLIPPY_PATH);\n\n    command\n        .current_dir(root_dir.join(project))\n        .env(\"CARGO_INCREMENTAL\", \"0\")\n        .arg(\"clippy\")\n        .arg(\"--all-targets\")\n        .arg(\"--all-features\");\n\n    if !io::stdout().is_terminal() {\n        command.arg(\"-q\");\n    }\n\n    if let Ok(dogfood_args) = std::env::var(\"__CLIPPY_DOGFOOD_ARGS\") {\n        for arg in dogfood_args.split_whitespace() {\n            command.arg(arg);\n        }\n    }\n\n    command.arg(\"--\");\n    command.arg(\"-Cdebuginfo=0\"); // disable debuginfo to generate less data in the target dir\n    command.args([\"-D\", \"clippy::all\", \"-D\", \"clippy::pedantic\", \"-D\", \"clippy::dbg_macro\"]);\n    if !cfg!(feature = \"internal\") {\n        // running a clippy built without internal lints on the clippy source\n        // that contains e.g. `allow(clippy::symbol_as_str)`\n        command.args([\"-A\", \"unknown_lints\"]);\n    }\n\n    // Workaround for not being a workspace, add the crate's directory back to the path\n    command.args([\"--remap-path-prefix\", &format!(\"={project}\")]);\n\n    command.status().unwrap().success()\n}\n"
  },
  {
    "path": "tests/integration.rs",
    "content": "//! This test is meant to only be run in CI. To run it locally use:\n//!\n//! `env INTEGRATION=rust-lang/log cargo test --test integration --features=integration`\n//!\n//! You can use a different `INTEGRATION` value to test different repositories.\n//!\n//! This test will clone the specified repository and run Clippy on it. The test succeeds, if\n//! Clippy doesn't produce an ICE. Lint warnings are ignored by this test.\n\n#![cfg(feature = \"integration\")]\n#![warn(rust_2018_idioms, unused_lifetimes)]\n\nuse std::env;\nuse std::ffi::OsStr;\nuse std::process::Command;\n\n#[cfg(not(windows))]\nconst CARGO_CLIPPY: &str = \"cargo-clippy\";\n#[cfg(windows)]\nconst CARGO_CLIPPY: &str = \"cargo-clippy.exe\";\n\n#[cfg_attr(feature = \"integration\", test)]\nfn integration_test() {\n    let repo_name = env::var(\"INTEGRATION\").expect(\"`INTEGRATION` var not set\");\n    let repo_url = format!(\"https://github.com/{repo_name}\");\n    let crate_name = repo_name\n        .split('/')\n        .nth(1)\n        .expect(\"repo name should have format `<org>/<name>`\");\n\n    let repo_dir = tempfile::tempdir()\n        .expect(\"couldn't create temp dir\")\n        .keep()\n        .join(crate_name);\n\n    let st = Command::new(\"git\")\n        .args([\n            OsStr::new(\"clone\"),\n            OsStr::new(\"--depth=1\"),\n            OsStr::new(&repo_url),\n            OsStr::new(&repo_dir),\n        ])\n        .status()\n        .expect(\"unable to run git\");\n    assert!(st.success());\n\n    let root_dir = std::path::PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"));\n    let target_dir = std::path::Path::new(&root_dir).join(\"target\");\n    let clippy_binary = target_dir.join(env!(\"PROFILE\")).join(CARGO_CLIPPY);\n\n    let output = Command::new(clippy_binary)\n        .current_dir(repo_dir)\n        .env(\"RUST_BACKTRACE\", \"full\")\n        .env(\"CARGO_TARGET_DIR\", target_dir)\n        .args([\n            \"clippy\",\n            \"--all-targets\",\n            \"--all-features\",\n            \"--message-format=short\",\n            \"--\",\n            \"--cap-lints\",\n            \"warn\",\n            \"-Wclippy::pedantic\",\n            \"-Wclippy::nursery\",\n        ])\n        .output()\n        .expect(\"unable to run clippy\");\n\n    let stderr = String::from_utf8_lossy(&output.stderr);\n\n    // debug:\n    eprintln!(\"{stderr}\");\n\n    // this is an internal test to make sure we would correctly panic on a span_delayed_bug\n    if repo_name == \"matthiaskrgr/clippy_ci_panic_test\" {\n        // we need to kind of switch around our logic here:\n        // if we find a panic, everything is fine, if we don't panic, SOMETHING is broken about our testing\n\n        // the repo basically just contains a span_delayed_bug that forces rustc/clippy to panic:\n        /*\n           #![feature(rustc_attrs)]\n           #[rustc_error(delayed_bug_from_inside_query)]\n           fn main() {}\n        */\n\n        if stderr.find(\"error: internal compiler error\").is_some() {\n            eprintln!(\"we saw that we intentionally panicked, yay\");\n            return;\n        }\n\n        panic!(\"panic caused by span_delayed_bug was NOT detected! Something is broken!\");\n    }\n\n    if let Some(backtrace_start) = stderr.find(\"error: internal compiler error\") {\n        static BACKTRACE_END_MSG: &str = \"end of query stack\";\n        let backtrace_end = stderr[backtrace_start..]\n            .find(BACKTRACE_END_MSG)\n            .expect(\"end of backtrace not found\");\n\n        panic!(\n            \"internal compiler error\\nBacktrace:\\n\\n{}\",\n            &stderr[backtrace_start..backtrace_start + backtrace_end + BACKTRACE_END_MSG.len()]\n        );\n    } else if stderr.contains(\"query stack during panic\") {\n        panic!(\"query stack during panic in the output\");\n    } else if stderr.contains(\"E0463\") {\n        // Encountering E0463 (can't find crate for `x`) did _not_ cause the build to fail in the\n        // past. Even though it should have. That's why we explicitly panic here.\n        // See PR #3552 and issue #3523 for more background.\n        panic!(\"error: E0463\");\n    } else if stderr.contains(\"E0514\") {\n        panic!(\"incompatible crate versions\");\n    } else if stderr.contains(\"failed to run `rustc` to learn about target-specific information\") {\n        panic!(\"couldn't find librustc_driver, consider setting `LD_LIBRARY_PATH`\");\n    } else {\n        assert!(\n            !stderr.contains(\"toolchain\") || !stderr.contains(\"is not installed\"),\n            \"missing required toolchain\"\n        );\n    }\n\n    match output.status.code() {\n        Some(0) => println!(\"Compilation successful\"),\n        Some(code) => eprintln!(\"Compilation failed. Exit code: {code}\"),\n        None => panic!(\"Process terminated by signal\"),\n    }\n}\n"
  },
  {
    "path": "tests/lint_message_convention.rs",
    "content": "#![warn(rust_2018_idioms, unused_lifetimes)]\n\nuse std::ffi::OsStr;\nuse std::path::PathBuf;\nuse std::sync::LazyLock;\n\nuse regex::RegexSet;\n\n#[derive(Debug)]\nstruct Message {\n    path: PathBuf,\n    bad_lines: Vec<String>,\n}\n\nimpl Message {\n    fn new(path: PathBuf) -> Self {\n        // we don't want the first letter after \"error: \", \"help: \" ... to be capitalized\n        // also no punctuation (except for \"?\" ?) at the end of a line\n        // Prefer \"try\" over \"try this\".\n        static REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| {\n            RegexSet::new([\n                \"error: [A-Z]\",\n                \"help: [A-Z]\",\n                \"warning: [A-Z]\",\n                \"note: [A-Z]\",\n                \"try: [A-Z]\",\n                \"error: .*[.!]$\",\n                \"help: .*[.!]$\",\n                \"warning: .*[.!]$\",\n                \"note: .*[.!]$\",\n                \"try: .*[.!]$\",\n                \"try this\",\n            ])\n            .unwrap()\n        });\n\n        // sometimes the first character is capitalized and it is legal (like in \"C-like enum variants\") or\n        // we want to ask a question ending in \"?\"\n        static EXCEPTIONS_SET: LazyLock<RegexSet> = LazyLock::new(|| {\n            RegexSet::new([\n                r\"\\.\\.\\.$\",\n                \".*C-like enum variant discriminant is not portable to 32-bit targets\",\n                \".*Intel x86 assembly syntax used\",\n                \".*AT&T x86 assembly syntax used\",\n                \"note: Clippy version: .*\",\n                \"the compiler unexpectedly panicked. this is a bug.\",\n                \"internal compiler error:\",\n            ])\n            .unwrap()\n        });\n\n        let content: String = std::fs::read_to_string(&path).unwrap();\n\n        let bad_lines = content\n            .lines()\n            .filter(|line| REGEX_SET.matches(line).matched_any())\n            // ignore exceptions\n            .filter(|line| !EXCEPTIONS_SET.matches(line).matched_any())\n            .map(ToOwned::to_owned)\n            .collect::<Vec<String>>();\n\n        Message { path, bad_lines }\n    }\n}\n\n#[test]\nfn lint_message_convention() {\n    // disable the test inside the rustc test suite\n    if option_env!(\"RUSTC_TEST_SUITE\").is_some() {\n        return;\n    }\n\n    // make sure that lint messages:\n    // * are not capitalized\n    // * don't have punctuation at the end of the last sentence\n\n    // these directories have interesting tests\n    let test_dirs = [\"ui\", \"ui-cargo\", \"ui-internal\", \"ui-toml\"]\n        .iter()\n        .map(PathBuf::from)\n        .map(|p| {\n            let base = PathBuf::from(\"tests\");\n            base.join(p)\n        });\n\n    // gather all .stderr files\n    let tests = test_dirs\n        .flat_map(|dir| {\n            std::fs::read_dir(dir)\n                .expect(\"failed to read dir\")\n                .map(|direntry| direntry.unwrap().path())\n        })\n        .filter(|file| matches!(file.extension().map(OsStr::to_str), Some(Some(\"stderr\"))));\n\n    // get all files that have any \"bad lines\" in them\n    let bad_tests: Vec<Message> = tests\n        .map(Message::new)\n        .filter(|message| !message.bad_lines.is_empty())\n        .collect();\n\n    for message in &bad_tests {\n        eprintln!(\n            \"error: the test '{}' contained the following nonconforming lines :\",\n            message.path.display()\n        );\n        message.bad_lines.iter().for_each(|line| eprintln!(\"{line}\"));\n        eprintln!(\"\\n\\n\");\n    }\n\n    eprintln!(\n        \"\\n\\n\\nLint message should not start with a capital letter and should not have punctuation at the end of the message unless multiple sentences are needed.\"\n    );\n    eprintln!(\"Check out the rustc-dev-guide for more information:\");\n    eprintln!(\"https://rustc-dev-guide.rust-lang.org/diagnostics.html#diagnostic-structure\\n\\n\\n\");\n\n    assert!(bad_tests.is_empty());\n}\n"
  },
  {
    "path": "tests/missing-test-files.rs",
    "content": "#![warn(rust_2018_idioms, unused_lifetimes)]\n#![allow(clippy::assertions_on_constants)]\n\nuse std::cmp::Ordering;\nuse std::ffi::OsStr;\nuse std::fs::{self, DirEntry};\nuse std::path::Path;\n\n#[test]\nfn test_missing_tests() {\n    let missing_files = explore_directory(Path::new(\"./tests\"));\n    if !missing_files.is_empty() {\n        assert!(\n            false,\n            \"Didn't see a test file for the following files:\\n\\n{}\\n\",\n            missing_files\n                .iter()\n                .map(|s| format!(\"\\t{s}\"))\n                .collect::<Vec<_>>()\n                .join(\"\\n\")\n        );\n    }\n}\n\n// Test for missing files.\nfn explore_directory(dir: &Path) -> Vec<String> {\n    let mut missing_files: Vec<String> = Vec::new();\n    let mut current_file = String::new();\n    let mut files: Vec<DirEntry> = fs::read_dir(dir).unwrap().filter_map(Result::ok).collect();\n    files.sort_by(|x, y| {\n        match x.path().file_prefix().cmp(&y.path().file_prefix()) {\n            Ordering::Equal => (),\n            ord => return ord,\n        }\n        // Sort rs files before the others if they share the same prefix. So when we see\n        // the file prefix for the first time and it's not a rust file, it means the rust\n        // file has to be missing.\n        match (\n            x.path().extension().and_then(OsStr::to_str),\n            y.path().extension().and_then(OsStr::to_str),\n        ) {\n            (Some(\"rs\" | \"toml\"), _) => Ordering::Less,\n            (_, Some(\"rs\" | \"toml\")) => Ordering::Greater,\n            _ => Ordering::Equal,\n        }\n    });\n    for entry in &files {\n        let path = entry.path();\n        if path.is_dir() {\n            missing_files.extend(explore_directory(&path));\n        } else {\n            let file_prefix = path.file_prefix().unwrap().to_str().unwrap().to_string();\n            if let Some(ext) = path.extension() {\n                match ext.to_str().unwrap() {\n                    \"rs\" | \"toml\" => current_file.clone_from(&file_prefix),\n                    \"stderr\" | \"stdout\" if file_prefix != current_file => {\n                        missing_files.push(path.to_str().unwrap().to_string());\n                    },\n                    _ => {},\n                }\n            }\n        }\n    }\n    missing_files\n}\n"
  },
  {
    "path": "tests/no-profile-in-cargo-toml.rs",
    "content": "// Check that we do not have `profile.*` sections in our `Cargo.toml` files,\n// as this causes warnings when run from the compiler repository which includes\n// Clippy in a workspace.\n//\n// Those sections can be put into `.cargo/config.toml` which will be read\n// when commands are issued from the top-level Clippy directory, outside of\n// a workspace.\n\nuse std::fs::File;\nuse std::io::{self, BufRead as _};\nuse walkdir::WalkDir;\n\n#[test]\nfn no_profile_in_cargo_toml() {\n    // This check could parse `Cargo.toml` using a TOML deserializer, but in practice\n    // profile sections would be added at the beginning of a line as `[profile.*]`, so\n    // keep it fast and simple.\n    for entry in WalkDir::new(\".\")\n        .into_iter()\n        // Do not recurse into `target` as lintcheck might put some sources (and their\n        //  `Cargo.toml`) there.\n        .filter_entry(|e| e.file_name() != \"target\")\n        .filter_map(Result::ok)\n        .filter(|e| e.file_name().to_str() == Some(\"Cargo.toml\"))\n    {\n        for line in io::BufReader::new(File::open(entry.path()).unwrap())\n            .lines()\n            .map(Result::unwrap)\n        {\n            if line.starts_with(\"[profile.\") {\n                eprintln!(\"Profile section `{line}` found in file `{}`.\", entry.path().display());\n                eprintln!(\"Use `.cargo/config.toml` for profiles specific to the standalone Clippy repository.\");\n                panic!(\"Profile section found in `Cargo.toml`\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/symbols-used.rs",
    "content": "// This test checks that all symbols defined in Clippy's `sym.rs` file\n// are used in Clippy. Otherwise, it will fail with a list of symbols\n// which are unused.\n//\n// This test is a no-op if run as part of the compiler test suite\n// and will always succeed.\n\nuse std::collections::HashSet;\nuse std::ffi::OsStr;\nuse std::fs;\n\nuse regex::Regex;\nuse walkdir::{DirEntry, WalkDir};\n\nconst SYM_FILE: &str = \"clippy_utils/src/sym.rs\";\n\ntype Result<T, E = AnyError> = std::result::Result<T, E>;\ntype AnyError = Box<dyn std::error::Error>;\n\n#[test]\nfn all_symbols_are_used() -> Result<()> {\n    if option_env!(\"RUSTC_TEST_SUITE\").is_some() {\n        return Ok(());\n    }\n\n    // Load all symbols defined in `SYM_FILE`.\n    let content = fs::read_to_string(SYM_FILE)?;\n    let content = content\n        .split_once(\"generate! {\")\n        .ok_or(\"cannot find symbols start\")?\n        .1\n        .split_once(\"\\n}\\n\")\n        .ok_or(\"cannot find symbols end\")?\n        .0;\n    let mut interned: HashSet<String> = Regex::new(r\"(?m)^    (\\w+)\")\n        .unwrap()\n        .captures_iter(content)\n        .map(|m| m[1].to_owned())\n        .collect();\n\n    // Remove symbols used as `sym::*`.\n    let used_re = Regex::new(r\"\\bsym::(\\w+)\\b\").unwrap();\n    let rs_ext = OsStr::new(\"rs\");\n    for dir in [\"clippy_lints\", \"clippy_lints_internal\", \"clippy_utils\", \"src\"] {\n        for file in WalkDir::new(dir)\n            .into_iter()\n            .flatten()\n            .map(DirEntry::into_path)\n            .filter(|p| p.extension() == Some(rs_ext))\n        {\n            for cap in used_re.captures_iter(&fs::read_to_string(file)?) {\n                interned.remove(&cap[1]);\n            }\n        }\n    }\n\n    // Remove symbols used as part of paths.\n    let paths_re = Regex::new(r\"path!\\(([\\w:]+)\\)\").unwrap();\n    for path in [\n        \"clippy_utils/src/paths.rs\",\n        \"clippy_lints_internal/src/internal_paths.rs\",\n    ] {\n        for cap in paths_re.captures_iter(&fs::read_to_string(path)?) {\n            for sym in cap[1].split(\"::\") {\n                interned.remove(sym);\n            }\n        }\n    }\n\n    let mut extra = interned.iter().collect::<Vec<_>>();\n    if !extra.is_empty() {\n        extra.sort_unstable();\n        eprintln!(\"Unused symbols defined in {SYM_FILE}:\");\n        for sym in extra {\n            eprintln!(\"  - {sym}\");\n        }\n        Err(format!(\"extra symbols found — remove them from {SYM_FILE}\"))?;\n    }\n    Ok(())\n}\n"
  },
  {
    "path": "tests/test_utils/mod.rs",
    "content": "#![allow(dead_code)] // see https://github.com/rust-lang/rust/issues/46379\n\nuse std::path::PathBuf;\nuse std::sync::LazyLock;\n\npub static CARGO_CLIPPY_PATH: LazyLock<PathBuf> = LazyLock::new(|| PathBuf::from(env!(\"CARGO_BIN_EXE_cargo-clippy\")));\n\npub const IS_RUSTC_TEST_SUITE: bool = option_env!(\"RUSTC_TEST_SUITE\").is_some();\n"
  },
  {
    "path": "tests/ui/absurd-extreme-comparisons.rs",
    "content": "#![warn(clippy::absurd_extreme_comparisons)]\n#![allow(\n    unused,\n    clippy::eq_op,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::needless_pass_by_value\n)]\n\n#[rustfmt::skip]\nfn main() {\n    const Z: u32 = 0;\n    let u: u32 = 42;\n    u <= 0;\n    //~^ absurd_extreme_comparisons\n\n    u <= Z;\n    //~^ absurd_extreme_comparisons\n\n    u < Z;\n    //~^ absurd_extreme_comparisons\n\n    Z >= u;\n    //~^ absurd_extreme_comparisons\n\n    Z > u;\n    //~^ absurd_extreme_comparisons\n\n    u > u32::MAX;\n    //~^ absurd_extreme_comparisons\n\n    u >= u32::MAX;\n    //~^ absurd_extreme_comparisons\n\n    u32::MAX < u;\n    //~^ absurd_extreme_comparisons\n\n    u32::MAX <= u;\n    //~^ absurd_extreme_comparisons\n\n    1-1 > u;\n    //~^ absurd_extreme_comparisons\n\n    u >= !0;\n    //~^ absurd_extreme_comparisons\n\n    u <= 12 - 2*6;\n    //~^ absurd_extreme_comparisons\n\n    let i: i8 = 0;\n    i < -127 - 1;\n    //~^ absurd_extreme_comparisons\n\n    i8::MAX >= i;\n    //~^ absurd_extreme_comparisons\n\n    3-7 < i32::MIN;\n    //~^ absurd_extreme_comparisons\n\n    let b = false;\n    b >= true;\n    //~^ absurd_extreme_comparisons\n\n    false > b;\n    //~^ absurd_extreme_comparisons\n\n    u > 0; // ok\n    // this is handled by clippy::unit_cmp\n    () < {};\n    //~^ unit_cmp\n\n\n}\n\nuse std::cmp::{Ordering, PartialEq, PartialOrd};\n\n#[derive(PartialEq, Eq, PartialOrd)]\npub struct U(u64);\n\nimpl PartialEq<u32> for U {\n    fn eq(&self, other: &u32) -> bool {\n        self.eq(&U(u64::from(*other)))\n    }\n}\nimpl PartialOrd<u32> for U {\n    fn partial_cmp(&self, other: &u32) -> Option<Ordering> {\n        self.partial_cmp(&U(u64::from(*other)))\n    }\n}\n\npub fn foo(val: U) -> bool {\n    val > u32::MAX\n}\n\npub fn bar(len: u64) -> bool {\n    // This is OK as we are casting from target sized to fixed size\n    len >= usize::MAX as u64\n}\n"
  },
  {
    "path": "tests/ui/absurd-extreme-comparisons.stderr",
    "content": "error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:14:5\n   |\nLL |     u <= 0;\n   |     ^^^^^^\n   |\n   = help: because `0` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `u == 0` instead\n   = note: `-D clippy::absurd-extreme-comparisons` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::absurd_extreme_comparisons)]`\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:17:5\n   |\nLL |     u <= Z;\n   |     ^^^^^^\n   |\n   = help: because `Z` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `u == Z` instead\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:20:5\n   |\nLL |     u < Z;\n   |     ^^^^^\n   |\n   = help: because `Z` is the minimum value for this type, this comparison is always false\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:23:5\n   |\nLL |     Z >= u;\n   |     ^^^^^^\n   |\n   = help: because `Z` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `Z == u` instead\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:26:5\n   |\nLL |     Z > u;\n   |     ^^^^^\n   |\n   = help: because `Z` is the minimum value for this type, this comparison is always false\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:29:5\n   |\nLL |     u > u32::MAX;\n   |     ^^^^^^^^^^^^\n   |\n   = help: because `u32::MAX` is the maximum value for this type, this comparison is always false\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:32:5\n   |\nLL |     u >= u32::MAX;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: because `u32::MAX` is the maximum value for this type, the case where the two sides are not equal never occurs, consider using `u == u32::MAX` instead\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:35:5\n   |\nLL |     u32::MAX < u;\n   |     ^^^^^^^^^^^^\n   |\n   = help: because `u32::MAX` is the maximum value for this type, this comparison is always false\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:38:5\n   |\nLL |     u32::MAX <= u;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: because `u32::MAX` is the maximum value for this type, the case where the two sides are not equal never occurs, consider using `u32::MAX == u` instead\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:41:5\n   |\nLL |     1-1 > u;\n   |     ^^^^^^^\n   |\n   = help: because `1-1` is the minimum value for this type, this comparison is always false\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:44:5\n   |\nLL |     u >= !0;\n   |     ^^^^^^^\n   |\n   = help: because `!0` is the maximum value for this type, the case where the two sides are not equal never occurs, consider using `u == !0` instead\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:47:5\n   |\nLL |     u <= 12 - 2*6;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: because `12 - 2*6` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `u == 12 - 2*6` instead\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:51:5\n   |\nLL |     i < -127 - 1;\n   |     ^^^^^^^^^^^^\n   |\n   = help: because `-127 - 1` is the minimum value for this type, this comparison is always false\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:54:5\n   |\nLL |     i8::MAX >= i;\n   |     ^^^^^^^^^^^^\n   |\n   = help: because `i8::MAX` is the maximum value for this type, this comparison is always true\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:57:5\n   |\nLL |     3-7 < i32::MIN;\n   |     ^^^^^^^^^^^^^^\n   |\n   = help: because `i32::MIN` is the minimum value for this type, this comparison is always false\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:61:5\n   |\nLL |     b >= true;\n   |     ^^^^^^^^^\n   |\n   = help: because `true` is the maximum value for this type, the case where the two sides are not equal never occurs, consider using `b == true` instead\n\nerror: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false\n  --> tests/ui/absurd-extreme-comparisons.rs:64:5\n   |\nLL |     false > b;\n   |     ^^^^^^^^^\n   |\n   = help: because `false` is the minimum value for this type, this comparison is always false\n\nerror: <-comparison of unit values detected. This will always be false\n  --> tests/ui/absurd-extreme-comparisons.rs:69:5\n   |\nLL |     () < {};\n   |     ^^^^^^^\n   |\n   = note: `#[deny(clippy::unit_cmp)]` on by default\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/allow_attributes.fixed",
    "content": "//@aux-build:proc_macros.rs\n//@aux-build:proc_macro_derive.rs\n#![allow(unused)]\n#![warn(clippy::allow_attributes)]\n#![no_main]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\n// Using clippy::needless_borrow just as a placeholder, it isn't relevant.\n\n// Should lint\n#[expect(dead_code)]\n//~^ allow_attributes\nstruct T1;\n\nstruct T2; // Should not lint\n#[deny(clippy::needless_borrow)] // Should not lint\nstruct T3;\n#[warn(clippy::needless_borrow)] // Should not lint\nstruct T4;\n// `panic = \"unwind\"` should always be true\n#[cfg_attr(panic = \"unwind\", expect(dead_code))]\n//~^ allow_attributes\nstruct CfgT;\n\n#[allow(clippy::allow_attributes, unused)]\nstruct Allowed;\n\n#[expect(clippy::allow_attributes)]\n#[allow(unused)]\nstruct Expected;\n\nfn ignore_external() {\n    external! {\n        #[allow(clippy::needless_borrow)] // Should not lint\n        fn a() {}\n    }\n}\n\nfn ignore_proc_macro() {\n    with_span! {\n        span\n        #[allow(clippy::needless_borrow)] // Should not lint\n        fn a() {}\n    }\n}\n\nfn ignore_inner_attr() {\n    #![allow(unused)] // Should not lint\n}\n\n#[clippy::msrv = \"1.81\"]\nfn msrv_1_81() {\n    #[expect(unused)]\n    //~^ allow_attributes\n    let x = 1;\n}\n\n#[clippy::msrv = \"1.80\"]\nfn msrv_1_80() {\n    #[allow(unused)]\n    let x = 1;\n}\n\n#[rustfmt::skip]\n#[ expect ( dead_code ) ]\n//~^ allow_attributes\nstruct Spaced;\n\n#[deny(clippy::allow_attributes)]\nfn deny_allow_attributes() -> Option<u8> {\n    let allow = None;\n    allow?;\n    Some(42)\n}\n\n// Edge case where the generated tokens spans match on #[repr(transparent)] which tricks the proc\n// macro check\n#[repr(transparent)]\n#[derive(proc_macro_derive::AllowLintSameSpan)] // This macro generates tokens with the same span as the whole struct and repr\nstruct IgnoreDerived;\n"
  },
  {
    "path": "tests/ui/allow_attributes.rs",
    "content": "//@aux-build:proc_macros.rs\n//@aux-build:proc_macro_derive.rs\n#![allow(unused)]\n#![warn(clippy::allow_attributes)]\n#![no_main]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\n// Using clippy::needless_borrow just as a placeholder, it isn't relevant.\n\n// Should lint\n#[allow(dead_code)]\n//~^ allow_attributes\nstruct T1;\n\nstruct T2; // Should not lint\n#[deny(clippy::needless_borrow)] // Should not lint\nstruct T3;\n#[warn(clippy::needless_borrow)] // Should not lint\nstruct T4;\n// `panic = \"unwind\"` should always be true\n#[cfg_attr(panic = \"unwind\", allow(dead_code))]\n//~^ allow_attributes\nstruct CfgT;\n\n#[allow(clippy::allow_attributes, unused)]\nstruct Allowed;\n\n#[expect(clippy::allow_attributes)]\n#[allow(unused)]\nstruct Expected;\n\nfn ignore_external() {\n    external! {\n        #[allow(clippy::needless_borrow)] // Should not lint\n        fn a() {}\n    }\n}\n\nfn ignore_proc_macro() {\n    with_span! {\n        span\n        #[allow(clippy::needless_borrow)] // Should not lint\n        fn a() {}\n    }\n}\n\nfn ignore_inner_attr() {\n    #![allow(unused)] // Should not lint\n}\n\n#[clippy::msrv = \"1.81\"]\nfn msrv_1_81() {\n    #[allow(unused)]\n    //~^ allow_attributes\n    let x = 1;\n}\n\n#[clippy::msrv = \"1.80\"]\nfn msrv_1_80() {\n    #[allow(unused)]\n    let x = 1;\n}\n\n#[rustfmt::skip]\n#[ allow ( dead_code ) ]\n//~^ allow_attributes\nstruct Spaced;\n\n#[deny(clippy::allow_attributes)]\nfn deny_allow_attributes() -> Option<u8> {\n    let allow = None;\n    allow?;\n    Some(42)\n}\n\n// Edge case where the generated tokens spans match on #[repr(transparent)] which tricks the proc\n// macro check\n#[repr(transparent)]\n#[derive(proc_macro_derive::AllowLintSameSpan)] // This macro generates tokens with the same span as the whole struct and repr\nstruct IgnoreDerived;\n"
  },
  {
    "path": "tests/ui/allow_attributes.stderr",
    "content": "error: #[allow] attribute found\n  --> tests/ui/allow_attributes.rs:13:3\n   |\nLL | #[allow(dead_code)]\n   |   ^^^^^ help: replace it with: `expect`\n   |\n   = note: `-D clippy::allow-attributes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::allow_attributes)]`\n\nerror: #[allow] attribute found\n  --> tests/ui/allow_attributes.rs:23:30\n   |\nLL | #[cfg_attr(panic = \"unwind\", allow(dead_code))]\n   |                              ^^^^^ help: replace it with: `expect`\n\nerror: #[allow] attribute found\n  --> tests/ui/allow_attributes.rs:55:7\n   |\nLL |     #[allow(unused)]\n   |       ^^^^^ help: replace it with: `expect`\n\nerror: #[allow] attribute found\n  --> tests/ui/allow_attributes.rs:67:4\n   |\nLL | #[ allow ( dead_code ) ]\n   |    ^^^^^ help: replace it with: `expect`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/allow_attributes_without_reason.rs",
    "content": "//@aux-build:proc_macros.rs\n#![deny(clippy::allow_attributes_without_reason)]\n#![allow(unfulfilled_lint_expectations, clippy::duplicated_attributes)]\n//~^ allow_attributes_without_reason\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\n// These should trigger the lint\n#[allow(dead_code)]\n//~^ allow_attributes_without_reason\n#[allow(dead_code, deprecated)]\n//~^ allow_attributes_without_reason\n#[expect(dead_code)]\n//~^ allow_attributes_without_reason\n// These should be fine\n#[allow(dead_code, reason = \"This should be allowed\")]\n#[warn(dyn_drop, reason = \"Warnings can also have reasons\")]\n#[warn(deref_nullptr)]\n#[deny(deref_nullptr)]\n#[forbid(deref_nullptr)]\nfn main() {\n    external! {\n        #[allow(dead_code)]\n        fn a() {}\n    }\n    with_span! {\n        span\n        #[allow(dead_code)]\n        fn b() {}\n    }\n}\n\n// Make sure this is not triggered on `?` desugaring\n\npub fn trigger_fp_option() -> Option<()> {\n    Some(())?;\n    None?;\n    Some(())\n}\n\npub fn trigger_fp_result() -> Result<(), &'static str> {\n    Ok(())?;\n    Err(\"asdf\")?;\n    Ok(())\n}\n\n#[clippy::msrv = \"1.81\"]\nfn msrv_1_81() {\n    #[allow(unused)]\n    //~^ allow_attributes_without_reason\n    let _ = 1;\n}\n\n#[clippy::msrv = \"1.80\"]\nfn msrv_1_80() {\n    #[allow(unused)]\n    let _ = 1;\n}\n"
  },
  {
    "path": "tests/ui/allow_attributes_without_reason.stderr",
    "content": "error: `allow` attribute without specifying a reason\n  --> tests/ui/allow_attributes_without_reason.rs:3:1\n   |\nLL | #![allow(unfulfilled_lint_expectations, clippy::duplicated_attributes)]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try adding a reason at the end with `, reason = \"..\"`\nnote: the lint level is defined here\n  --> tests/ui/allow_attributes_without_reason.rs:2:9\n   |\nLL | #![deny(clippy::allow_attributes_without_reason)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `allow` attribute without specifying a reason\n  --> tests/ui/allow_attributes_without_reason.rs:10:1\n   |\nLL | #[allow(dead_code)]\n   | ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try adding a reason at the end with `, reason = \"..\"`\n\nerror: `allow` attribute without specifying a reason\n  --> tests/ui/allow_attributes_without_reason.rs:12:1\n   |\nLL | #[allow(dead_code, deprecated)]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try adding a reason at the end with `, reason = \"..\"`\n\nerror: `expect` attribute without specifying a reason\n  --> tests/ui/allow_attributes_without_reason.rs:14:1\n   |\nLL | #[expect(dead_code)]\n   | ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try adding a reason at the end with `, reason = \"..\"`\n\nerror: `allow` attribute without specifying a reason\n  --> tests/ui/allow_attributes_without_reason.rs:50:5\n   |\nLL |     #[allow(unused)]\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = help: try adding a reason at the end with `, reason = \"..\"`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/almost_complete_range.fixed",
    "content": "//@edition:2018\n//@aux-build:proc_macros.rs\n\n#![feature(stmt_expr_attributes)]\n#![warn(clippy::almost_complete_range)]\n#![allow(ellipsis_inclusive_range_patterns)]\n#![allow(clippy::needless_parens_on_range_literals)]\n#![allow(clippy::double_parens)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n#[inline_macros]\nfn main() {\n    #[rustfmt::skip]\n    {\n        let _ = ('a') ..='z';\n        //~^ almost_complete_range\n        let _ = 'A' ..= ('Z');\n        //~^ almost_complete_range\n        let _ = ((('0'))) ..= ('9');\n        //~^ almost_complete_range\n    }\n\n    let _ = 'b'..'z';\n    let _ = 'B'..'Z';\n    let _ = '1'..'9';\n\n    let _ = (b'a')..=(b'z');\n    //~^ almost_complete_range\n    let _ = b'A'..=b'Z';\n    //~^ almost_complete_range\n    let _ = b'0'..=b'9';\n    //~^ almost_complete_range\n\n    let _ = b'b'..b'z';\n    let _ = b'B'..b'Z';\n    let _ = b'1'..b'9';\n\n    let _ = inline!('a')..='z';\n    //~^ almost_complete_range\n    let _ = inline!('A')..='Z';\n    //~^ almost_complete_range\n    let _ = inline!('0')..='9';\n    //~^ almost_complete_range\n\n    let _ = match 0u8 {\n        b'a'..=b'z' if true => 1,\n        //~^ almost_complete_range\n        b'A'..=b'Z' if true => 2,\n        //~^ almost_complete_range\n        b'0'..=b'9' if true => 3,\n        //~^ almost_complete_range\n        b'b'..b'z' => 4,\n        b'B'..b'Z' => 5,\n        b'1'..b'9' => 6,\n        _ => 7,\n    };\n\n    let _ = match 'x' {\n        'a'..='z' if true => 1,\n        //~^ almost_complete_range\n        'A'..='Z' if true => 2,\n        //~^ almost_complete_range\n        '0'..='9' if true => 3,\n        //~^ almost_complete_range\n        'b'..'z' => 4,\n        'B'..'Z' => 5,\n        '1'..'9' => 6,\n        _ => 7,\n    };\n\n    external!(\n        let _ = 'a'..'z';\n        let _ = 'A'..'Z';\n        let _ = '0'..'9';\n    );\n    inline!(\n        let _ = 'a'..='z';\n        //~^ almost_complete_range\n        let _ = 'A'..='Z';\n        //~^ almost_complete_range\n        let _ = '0'..='9';\n        //~^ almost_complete_range\n    );\n}\n\n#[clippy::msrv = \"1.25\"]\nfn _under_msrv() {\n    let _ = match 'a' {\n        'a'...'z' => 1,\n        //~^ almost_complete_range\n        'A'...'Z' => 2,\n        //~^ almost_complete_range\n        '0'...'9' => 3,\n        //~^ almost_complete_range\n        _ => 4,\n    };\n}\n\n#[clippy::msrv = \"1.26\"]\nfn _meets_msrv() {\n    let _ = 'a'..='z';\n    //~^ almost_complete_range\n    let _ = 'A'..='Z';\n    //~^ almost_complete_range\n    let _ = '0'..='9';\n    //~^ almost_complete_range\n    let _ = match 'a' {\n        'a'..='z' => 1,\n        //~^ almost_complete_range\n        'A'..='Z' => 1,\n        //~^ almost_complete_range\n        '0'..='9' => 3,\n        //~^ almost_complete_range\n        _ => 4,\n    };\n}\n"
  },
  {
    "path": "tests/ui/almost_complete_range.rs",
    "content": "//@edition:2018\n//@aux-build:proc_macros.rs\n\n#![feature(stmt_expr_attributes)]\n#![warn(clippy::almost_complete_range)]\n#![allow(ellipsis_inclusive_range_patterns)]\n#![allow(clippy::needless_parens_on_range_literals)]\n#![allow(clippy::double_parens)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n#[inline_macros]\nfn main() {\n    #[rustfmt::skip]\n    {\n        let _ = ('a') ..'z';\n        //~^ almost_complete_range\n        let _ = 'A' .. ('Z');\n        //~^ almost_complete_range\n        let _ = ((('0'))) .. ('9');\n        //~^ almost_complete_range\n    }\n\n    let _ = 'b'..'z';\n    let _ = 'B'..'Z';\n    let _ = '1'..'9';\n\n    let _ = (b'a')..(b'z');\n    //~^ almost_complete_range\n    let _ = b'A'..b'Z';\n    //~^ almost_complete_range\n    let _ = b'0'..b'9';\n    //~^ almost_complete_range\n\n    let _ = b'b'..b'z';\n    let _ = b'B'..b'Z';\n    let _ = b'1'..b'9';\n\n    let _ = inline!('a')..'z';\n    //~^ almost_complete_range\n    let _ = inline!('A')..'Z';\n    //~^ almost_complete_range\n    let _ = inline!('0')..'9';\n    //~^ almost_complete_range\n\n    let _ = match 0u8 {\n        b'a'..b'z' if true => 1,\n        //~^ almost_complete_range\n        b'A'..b'Z' if true => 2,\n        //~^ almost_complete_range\n        b'0'..b'9' if true => 3,\n        //~^ almost_complete_range\n        b'b'..b'z' => 4,\n        b'B'..b'Z' => 5,\n        b'1'..b'9' => 6,\n        _ => 7,\n    };\n\n    let _ = match 'x' {\n        'a'..'z' if true => 1,\n        //~^ almost_complete_range\n        'A'..'Z' if true => 2,\n        //~^ almost_complete_range\n        '0'..'9' if true => 3,\n        //~^ almost_complete_range\n        'b'..'z' => 4,\n        'B'..'Z' => 5,\n        '1'..'9' => 6,\n        _ => 7,\n    };\n\n    external!(\n        let _ = 'a'..'z';\n        let _ = 'A'..'Z';\n        let _ = '0'..'9';\n    );\n    inline!(\n        let _ = 'a'..'z';\n        //~^ almost_complete_range\n        let _ = 'A'..'Z';\n        //~^ almost_complete_range\n        let _ = '0'..'9';\n        //~^ almost_complete_range\n    );\n}\n\n#[clippy::msrv = \"1.25\"]\nfn _under_msrv() {\n    let _ = match 'a' {\n        'a'..'z' => 1,\n        //~^ almost_complete_range\n        'A'..'Z' => 2,\n        //~^ almost_complete_range\n        '0'..'9' => 3,\n        //~^ almost_complete_range\n        _ => 4,\n    };\n}\n\n#[clippy::msrv = \"1.26\"]\nfn _meets_msrv() {\n    let _ = 'a'..'z';\n    //~^ almost_complete_range\n    let _ = 'A'..'Z';\n    //~^ almost_complete_range\n    let _ = '0'..'9';\n    //~^ almost_complete_range\n    let _ = match 'a' {\n        'a'..'z' => 1,\n        //~^ almost_complete_range\n        'A'..'Z' => 1,\n        //~^ almost_complete_range\n        '0'..'9' => 3,\n        //~^ almost_complete_range\n        _ => 4,\n    };\n}\n"
  },
  {
    "path": "tests/ui/almost_complete_range.stderr",
    "content": "error: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:17:17\n   |\nLL |         let _ = ('a') ..'z';\n   |                 ^^^^^^--^^^\n   |                       |\n   |                       help: use an inclusive range: `..=`\n   |\n   = note: `-D clippy::almost-complete-range` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::almost_complete_range)]`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:19:17\n   |\nLL |         let _ = 'A' .. ('Z');\n   |                 ^^^^--^^^^^^\n   |                     |\n   |                     help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:21:17\n   |\nLL |         let _ = ((('0'))) .. ('9');\n   |                 ^^^^^^^^^^--^^^^^^\n   |                           |\n   |                           help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:29:13\n   |\nLL |     let _ = (b'a')..(b'z');\n   |             ^^^^^^--^^^^^^\n   |                   |\n   |                   help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:31:13\n   |\nLL |     let _ = b'A'..b'Z';\n   |             ^^^^--^^^^\n   |                 |\n   |                 help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:33:13\n   |\nLL |     let _ = b'0'..b'9';\n   |             ^^^^--^^^^\n   |                 |\n   |                 help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:40:13\n   |\nLL |     let _ = inline!('a')..'z';\n   |             ^^^^^^^^^^^^--^^^\n   |                         |\n   |                         help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:42:13\n   |\nLL |     let _ = inline!('A')..'Z';\n   |             ^^^^^^^^^^^^--^^^\n   |                         |\n   |                         help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:44:13\n   |\nLL |     let _ = inline!('0')..'9';\n   |             ^^^^^^^^^^^^--^^^\n   |                         |\n   |                         help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:48:9\n   |\nLL |         b'a'..b'z' if true => 1,\n   |         ^^^^--^^^^\n   |             |\n   |             help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:50:9\n   |\nLL |         b'A'..b'Z' if true => 2,\n   |         ^^^^--^^^^\n   |             |\n   |             help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:52:9\n   |\nLL |         b'0'..b'9' if true => 3,\n   |         ^^^^--^^^^\n   |             |\n   |             help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:61:9\n   |\nLL |         'a'..'z' if true => 1,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:63:9\n   |\nLL |         'A'..'Z' if true => 2,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:65:9\n   |\nLL |         '0'..'9' if true => 3,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:79:17\n   |\nLL |         let _ = 'a'..'z';\n   |                 ^^^--^^^\n   |                    |\n   |                    help: use an inclusive range: `..=`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:81:17\n   |\nLL |         let _ = 'A'..'Z';\n   |                 ^^^--^^^\n   |                    |\n   |                    help: use an inclusive range: `..=`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:83:17\n   |\nLL |         let _ = '0'..'9';\n   |                 ^^^--^^^\n   |                    |\n   |                    help: use an inclusive range: `..=`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:91:9\n   |\nLL |         'a'..'z' => 1,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `...`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:93:9\n   |\nLL |         'A'..'Z' => 2,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `...`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:95:9\n   |\nLL |         '0'..'9' => 3,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `...`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:103:13\n   |\nLL |     let _ = 'a'..'z';\n   |             ^^^--^^^\n   |                |\n   |                help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:105:13\n   |\nLL |     let _ = 'A'..'Z';\n   |             ^^^--^^^\n   |                |\n   |                help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:107:13\n   |\nLL |     let _ = '0'..'9';\n   |             ^^^--^^^\n   |                |\n   |                help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:110:9\n   |\nLL |         'a'..'z' => 1,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:112:9\n   |\nLL |         'A'..'Z' => 1,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `..=`\n\nerror: almost complete ascii range\n  --> tests/ui/almost_complete_range.rs:114:9\n   |\nLL |         '0'..'9' => 3,\n   |         ^^^--^^^\n   |            |\n   |            help: use an inclusive range: `..=`\n\nerror: aborting due to 27 previous errors\n\n"
  },
  {
    "path": "tests/ui/approx_const.rs",
    "content": "#[warn(clippy::approx_constant)]\nfn main() {\n    let my_e = 2.7182;\n    //~^ approx_constant\n\n    let almost_e = 2.718;\n    //~^ approx_constant\n\n    let no_e = 2.71;\n\n    let my_1_frac_pi = 0.3183;\n    //~^ approx_constant\n\n    let no_1_frac_pi = 0.31;\n\n    let my_frac_1_sqrt_2 = 0.70710678;\n    //~^ approx_constant\n\n    let almost_frac_1_sqrt_2 = 0.70711;\n    //~^ approx_constant\n\n    let my_frac_1_sqrt_2 = 0.707;\n\n    let my_frac_2_pi = 0.63661977;\n    //~^ approx_constant\n\n    let no_frac_2_pi = 0.636;\n\n    let my_frac_2_sq_pi = 1.128379;\n    //~^ approx_constant\n\n    let no_frac_2_sq_pi = 1.128;\n\n    let my_frac_pi_2 = 1.57079632679;\n    //~^ approx_constant\n\n    let no_frac_pi_2 = 1.5705;\n\n    let my_frac_pi_3 = 1.04719755119;\n    //~^ approx_constant\n\n    let no_frac_pi_3 = 1.047;\n\n    let my_frac_pi_4 = 0.785398163397;\n    //~^ approx_constant\n\n    let no_frac_pi_4 = 0.785;\n\n    let my_frac_pi_6 = 0.523598775598;\n    //~^ approx_constant\n\n    let no_frac_pi_6 = 0.523;\n\n    let my_frac_pi_8 = 0.3926990816987;\n    //~^ approx_constant\n\n    let no_frac_pi_8 = 0.392;\n\n    let my_ln_10 = 2.302585092994046;\n    //~^ approx_constant\n\n    let no_ln_10 = 2.303;\n\n    let my_ln_2 = 0.6931471805599453;\n    //~^ approx_constant\n\n    let no_ln_2 = 0.693;\n\n    let my_log10_e = 0.4342944819032518;\n    //~^ approx_constant\n\n    let no_log10_e = 0.434;\n\n    let my_log2_e = 1.4426950408889634;\n    //~^ approx_constant\n\n    let no_log2_e = 1.442;\n\n    let log2_10 = 3.321928094887362;\n    //~^ approx_constant\n\n    let no_log2_10 = 3.321;\n\n    let log10_2 = 0.301029995663981;\n    //~^ approx_constant\n\n    let no_log10_2 = 0.301;\n\n    let my_pi = 3.1415;\n    //~^ approx_constant\n\n    let almost_pi = 3.14;\n    //~^ approx_constant\n\n    let no_pi = 3.15;\n\n    let my_sq2 = 1.4142;\n    //~^ approx_constant\n\n    let no_sq2 = 1.414;\n\n    let my_tau = 6.2832;\n    //~^ approx_constant\n\n    let almost_tau = 6.28;\n    //~^ approx_constant\n\n    let no_tau = 6.3;\n\n    // issue #15194\n    #[allow(clippy::excessive_precision)]\n    let x: f64 = 3.1415926535897932384626433832;\n    //~^ approx_constant\n\n    #[allow(clippy::excessive_precision)]\n    let _: f64 = 003.14159265358979311599796346854418516159057617187500;\n    //~^ approx_constant\n\n    let almost_frac_1_sqrt_2 = 00.70711;\n    //~^ approx_constant\n\n    let almost_frac_1_sqrt_2 = 00.707_11;\n    //~^ approx_constant\n}\n"
  },
  {
    "path": "tests/ui/approx_const.stderr",
    "content": "error: approximate value of `f{32, 64}::consts::E` found\n  --> tests/ui/approx_const.rs:3:16\n   |\nLL |     let my_e = 2.7182;\n   |                ^^^^^^\n   |\n   = help: consider using the constant directly\n   = note: `-D clippy::approx-constant` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::approx_constant)]`\n\nerror: approximate value of `f{32, 64}::consts::E` found\n  --> tests/ui/approx_const.rs:6:20\n   |\nLL |     let almost_e = 2.718;\n   |                    ^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_1_PI` found\n  --> tests/ui/approx_const.rs:11:24\n   |\nLL |     let my_1_frac_pi = 0.3183;\n   |                        ^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found\n  --> tests/ui/approx_const.rs:16:28\n   |\nLL |     let my_frac_1_sqrt_2 = 0.70710678;\n   |                            ^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found\n  --> tests/ui/approx_const.rs:19:32\n   |\nLL |     let almost_frac_1_sqrt_2 = 0.70711;\n   |                                ^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_2_PI` found\n  --> tests/ui/approx_const.rs:24:24\n   |\nLL |     let my_frac_2_pi = 0.63661977;\n   |                        ^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_2_SQRT_PI` found\n  --> tests/ui/approx_const.rs:29:27\n   |\nLL |     let my_frac_2_sq_pi = 1.128379;\n   |                           ^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_PI_2` found\n  --> tests/ui/approx_const.rs:34:24\n   |\nLL |     let my_frac_pi_2 = 1.57079632679;\n   |                        ^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_PI_3` found\n  --> tests/ui/approx_const.rs:39:24\n   |\nLL |     let my_frac_pi_3 = 1.04719755119;\n   |                        ^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_PI_4` found\n  --> tests/ui/approx_const.rs:44:24\n   |\nLL |     let my_frac_pi_4 = 0.785398163397;\n   |                        ^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_PI_6` found\n  --> tests/ui/approx_const.rs:49:24\n   |\nLL |     let my_frac_pi_6 = 0.523598775598;\n   |                        ^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_PI_8` found\n  --> tests/ui/approx_const.rs:54:24\n   |\nLL |     let my_frac_pi_8 = 0.3926990816987;\n   |                        ^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LN_10` found\n  --> tests/ui/approx_const.rs:59:20\n   |\nLL |     let my_ln_10 = 2.302585092994046;\n   |                    ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LN_2` found\n  --> tests/ui/approx_const.rs:64:19\n   |\nLL |     let my_ln_2 = 0.6931471805599453;\n   |                   ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LOG10_E` found\n  --> tests/ui/approx_const.rs:69:22\n   |\nLL |     let my_log10_e = 0.4342944819032518;\n   |                      ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LOG2_E` found\n  --> tests/ui/approx_const.rs:74:21\n   |\nLL |     let my_log2_e = 1.4426950408889634;\n   |                     ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LOG2_10` found\n  --> tests/ui/approx_const.rs:79:19\n   |\nLL |     let log2_10 = 3.321928094887362;\n   |                   ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LOG10_2` found\n  --> tests/ui/approx_const.rs:84:19\n   |\nLL |     let log10_2 = 0.301029995663981;\n   |                   ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::PI` found\n  --> tests/ui/approx_const.rs:89:17\n   |\nLL |     let my_pi = 3.1415;\n   |                 ^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::PI` found\n  --> tests/ui/approx_const.rs:92:21\n   |\nLL |     let almost_pi = 3.14;\n   |                     ^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::SQRT_2` found\n  --> tests/ui/approx_const.rs:97:18\n   |\nLL |     let my_sq2 = 1.4142;\n   |                  ^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::TAU` found\n  --> tests/ui/approx_const.rs:102:18\n   |\nLL |     let my_tau = 6.2832;\n   |                  ^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::TAU` found\n  --> tests/ui/approx_const.rs:105:22\n   |\nLL |     let almost_tau = 6.28;\n   |                      ^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::PI` found\n  --> tests/ui/approx_const.rs:112:18\n   |\nLL |     let x: f64 = 3.1415926535897932384626433832;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::PI` found\n  --> tests/ui/approx_const.rs:116:18\n   |\nLL |     let _: f64 = 003.14159265358979311599796346854418516159057617187500;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found\n  --> tests/ui/approx_const.rs:119:32\n   |\nLL |     let almost_frac_1_sqrt_2 = 00.70711;\n   |                                ^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found\n  --> tests/ui/approx_const.rs:122:32\n   |\nLL |     let almost_frac_1_sqrt_2 = 00.707_11;\n   |                                ^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: aborting due to 27 previous errors\n\n"
  },
  {
    "path": "tests/ui/arc_with_non_send_sync.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::arc_with_non_send_sync)]\n#![allow(unused_variables)]\n\n#[macro_use]\nextern crate proc_macros;\n\nuse std::cell::RefCell;\nuse std::ptr::{null, null_mut};\nuse std::sync::{Arc, Mutex};\n\nfn foo<T>(x: T) {\n    // Should not lint - purposefully ignoring generic args.\n    let a = Arc::new(x);\n}\nfn issue11076<T>() {\n    let a: Arc<Vec<T>> = Arc::new(Vec::new());\n}\n\nfn issue11232() {\n    external! {\n        let a: Arc<*const u8> = Arc::new(null());\n        let a: Arc<*mut u8> = Arc::new(null_mut());\n    }\n    with_span! {\n        span\n        let a: Arc<*const u8> = Arc::new(null());\n        let a: Arc<*mut u8> = Arc::new(null_mut());\n    }\n}\n\nfn main() {\n    let _ = Arc::new(42);\n\n    let _ = Arc::new(RefCell::new(42));\n    //~^ arc_with_non_send_sync\n\n    let mutex = Mutex::new(1);\n    let _ = Arc::new(mutex.lock().unwrap());\n    //~^ arc_with_non_send_sync\n\n    let _ = Arc::new(&42 as *const i32);\n    //~^ arc_with_non_send_sync\n}\n"
  },
  {
    "path": "tests/ui/arc_with_non_send_sync.stderr",
    "content": "error: usage of an `Arc` that is not `Send` and `Sync`\n  --> tests/ui/arc_with_non_send_sync.rs:35:13\n   |\nLL |     let _ = Arc::new(RefCell::new(42));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Arc<RefCell<i32>>` is not `Send` and `Sync` as `RefCell<i32>` is not `Sync`\n   = help: if the `Arc` will not be used across threads replace it with an `Rc`\n   = help: otherwise make `RefCell<i32>` `Send` and `Sync` or consider a wrapper type such as `Mutex`\n   = note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]`\n\nerror: usage of an `Arc` that is not `Send` and `Sync`\n  --> tests/ui/arc_with_non_send_sync.rs:39:13\n   |\nLL |     let _ = Arc::new(mutex.lock().unwrap());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Arc<MutexGuard<'_, i32>>` is not `Send` and `Sync` as `MutexGuard<'_, i32>` is not `Send`\n   = help: if the `Arc` will not be used across threads replace it with an `Rc`\n   = help: otherwise make `MutexGuard<'_, i32>` `Send` and `Sync` or consider a wrapper type such as `Mutex`\n\nerror: usage of an `Arc` that is not `Send` and `Sync`\n  --> tests/ui/arc_with_non_send_sync.rs:42:13\n   |\nLL |     let _ = Arc::new(&42 as *const i32);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Arc<*const i32>` is not `Send` and `Sync` as `*const i32` is neither `Send` nor `Sync`\n   = help: if the `Arc` will not be used across threads replace it with an `Rc`\n   = help: otherwise make `*const i32` `Send` and `Sync` or consider a wrapper type such as `Mutex`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/arithmetic_side_effects.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![feature(f128)]\n#![feature(f16)]\n#![allow(\n    clippy::assign_op_pattern,\n    clippy::erasing_op,\n    clippy::identity_op,\n    clippy::no_effect,\n    clippy::op_ref,\n    clippy::unnecessary_owned_empty_strings,\n    arithmetic_overflow,\n    unconditional_panic\n)]\n#![warn(clippy::arithmetic_side_effects)]\n\nextern crate proc_macro_derive;\n\nuse core::num::{NonZero, Saturating, Wrapping};\nuse core::time::Duration;\n\nconst ONE: i32 = 1;\nconst ZERO: i32 = 0;\n\n#[derive(Clone, Copy)]\npub struct Custom;\n\n#[derive(proc_macro_derive::ShadowDerive)]\npub struct Nothing;\n\nmacro_rules! impl_arith {\n    ( $( $_trait:ident, $lhs:ty, $rhs:ty, $method:ident; )* ) => {\n        $(\n            impl core::ops::$_trait<$lhs> for $rhs {\n                type Output = Custom;\n                fn $method(self, _: $lhs) -> Self::Output { todo!() }\n            }\n        )*\n    }\n}\n\nmacro_rules! impl_assign_arith {\n    ( $( $_trait:ident, $lhs:ty, $rhs:ty, $method:ident; )* ) => {\n        $(\n            impl core::ops::$_trait<$lhs> for $rhs {\n                fn $method(&mut self, _: $lhs) {}\n            }\n        )*\n    }\n}\n\nimpl_arith!(\n    Add, Custom, Custom, add;\n    Div, Custom, Custom, div;\n    Mul, Custom, Custom, mul;\n    Rem, Custom, Custom, rem;\n    Shl, Custom, Custom, shl;\n    Shr, Custom, Custom, shr;\n    Sub, Custom, Custom, sub;\n\n    Add, Custom, &Custom, add;\n    Div, Custom, &Custom, div;\n    Mul, Custom, &Custom, mul;\n    Rem, Custom, &Custom, rem;\n    Shl, Custom, &Custom, shl;\n    Shr, Custom, &Custom, shr;\n    Sub, Custom, &Custom, sub;\n\n    Add, &Custom, Custom, add;\n    Div, &Custom, Custom, div;\n    Mul, &Custom, Custom, mul;\n    Rem, &Custom, Custom, rem;\n    Shl, &Custom, Custom, shl;\n    Shr, &Custom, Custom, shr;\n    Sub, &Custom, Custom, sub;\n\n    Add, &Custom, &Custom, add;\n    Div, &Custom, &Custom, div;\n    Mul, &Custom, &Custom, mul;\n    Rem, &Custom, &Custom, rem;\n    Shl, &Custom, &Custom, shl;\n    Shr, &Custom, &Custom, shr;\n    Sub, &Custom, &Custom, sub;\n);\n\nimpl_assign_arith!(\n    AddAssign, Custom, Custom, add_assign;\n    DivAssign, Custom, Custom, div_assign;\n    MulAssign, Custom, Custom, mul_assign;\n    RemAssign, Custom, Custom, rem_assign;\n    ShlAssign, Custom, Custom, shl_assign;\n    ShrAssign, Custom, Custom, shr_assign;\n    SubAssign, Custom, Custom, sub_assign;\n\n    AddAssign, Custom, &Custom, add_assign;\n    DivAssign, Custom, &Custom, div_assign;\n    MulAssign, Custom, &Custom, mul_assign;\n    RemAssign, Custom, &Custom, rem_assign;\n    ShlAssign, Custom, &Custom, shl_assign;\n    ShrAssign, Custom, &Custom, shr_assign;\n    SubAssign, Custom, &Custom, sub_assign;\n\n    AddAssign, &Custom, Custom, add_assign;\n    DivAssign, &Custom, Custom, div_assign;\n    MulAssign, &Custom, Custom, mul_assign;\n    RemAssign, &Custom, Custom, rem_assign;\n    ShlAssign, &Custom, Custom, shl_assign;\n    ShrAssign, &Custom, Custom, shr_assign;\n    SubAssign, &Custom, Custom, sub_assign;\n\n    AddAssign, &Custom, &Custom, add_assign;\n    DivAssign, &Custom, &Custom, div_assign;\n    MulAssign, &Custom, &Custom, mul_assign;\n    RemAssign, &Custom, &Custom, rem_assign;\n    ShlAssign, &Custom, &Custom, shl_assign;\n    ShrAssign, &Custom, &Custom, shr_assign;\n    SubAssign, &Custom, &Custom, sub_assign;\n);\n\nimpl core::ops::Neg for Custom {\n    type Output = Custom;\n    fn neg(self) -> Self::Output {\n        todo!()\n    }\n}\nimpl core::ops::Neg for &Custom {\n    type Output = Custom;\n    fn neg(self) -> Self::Output {\n        todo!()\n    }\n}\n\npub fn association_with_structures_should_not_trigger_the_lint() {\n    enum Foo {\n        Bar = -2,\n    }\n\n    impl Trait for Foo {\n        const ASSOC: i32 = {\n            let _: [i32; 1 + 1];\n            fn foo() {}\n            1 + 1\n        };\n    }\n\n    struct Baz([i32; 1 + 1]);\n\n    trait Trait {\n        const ASSOC: i32 = 1 + 1;\n    }\n\n    type Alias = [i32; 1 + 1];\n\n    union Qux {\n        field: [i32; 1 + 1],\n    }\n\n    let _: [i32; 1 + 1] = [0, 0];\n\n    let _: [i32; 1 + 1] = {\n        let a: [i32; 1 + 1] = [0, 0];\n        a\n    };\n}\n\npub fn hard_coded_allowed() {\n    let _ = 1f16 + 1f16;\n    //~^ arithmetic_side_effects\n    let _ = 1f32 + 1f32;\n    let _ = 1f64 + 1f64;\n    let _ = 1f128 + 1f128;\n    //~^ arithmetic_side_effects\n\n    let _ = Saturating(0u32) + Saturating(0u32);\n    let _ = String::new() + \"\";\n    let _ = String::new() + &String::new();\n    let _ = Wrapping(0u32) + Wrapping(0u32);\n\n    let saturating: Saturating<u32> = Saturating(0u32);\n    let string: String = String::new();\n    let wrapping: Wrapping<u32> = Wrapping(0u32);\n\n    let inferred_saturating = saturating + saturating;\n    let inferred_string = string + \"\";\n    let inferred_wrapping = wrapping + wrapping;\n\n    let _ = inferred_saturating + inferred_saturating;\n    let _ = inferred_string + \"\";\n    let _ = inferred_wrapping + inferred_wrapping;\n}\n\n#[rustfmt::skip]\npub fn const_ops_should_not_trigger_the_lint() {\n    const _: i32 = { let mut n = 1; n += 1; n };\n    let _ = const { let mut n = 1; n += 1; n };\n\n    const _: i32 = { let mut n = 1; n = n + 1; n };\n    let _ = const { let mut n = 1; n = n + 1; n };\n\n    const _: i32 = { let mut n = 1; n = 1 + n; n };\n    let _ = const { let mut n = 1; n = 1 + n; n };\n\n    const _: i32 = 1 + 1;\n    let _ = const { 1 + 1 };\n\n    const _: i32 = { let mut n = 1; n = -1; n = -(-1); n = -n; n };\n    let _ = const { let mut n = 1; n = -1; n = -(-1); n = -n; n };\n}\n\npub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_trigger_the_lint() {\n    let mut _n = i32::MAX;\n\n    // Assign\n    _n += 0;\n    _n += &0;\n    _n -= 0;\n    _n -= &0;\n    _n += ZERO;\n    _n += &ZERO;\n    _n -= ZERO;\n    _n -= &ZERO;\n    _n /= 99;\n    _n /= &99;\n    _n %= 99;\n    _n %= &99;\n    _n *= 0;\n    _n *= &0;\n    _n *= 1;\n    _n *= &1;\n    _n *= ZERO;\n    _n *= &ZERO;\n    _n *= ONE;\n    _n *= &ONE;\n    _n += -0;\n    _n += &-0;\n    _n -= -0;\n    _n -= &-0;\n    _n += -ZERO;\n    _n += &-ZERO;\n    _n -= -ZERO;\n    _n -= &-ZERO;\n    _n /= -99;\n    _n /= &-99;\n    _n %= -99;\n    _n %= &-99;\n    _n *= -0;\n    _n *= &-0;\n    _n *= -1;\n    _n *= &-1;\n\n    // Binary\n    _n = _n + 0;\n    _n = _n + &0;\n    _n = 0 + _n;\n    _n = &0 + _n;\n    _n = _n + ZERO;\n    _n = _n + &ZERO;\n    _n = ZERO + _n;\n    _n = &ZERO + _n;\n    _n = _n - 0;\n    _n = _n - &0;\n    _n = 0 - _n;\n    _n = &0 - _n;\n    _n = _n - ZERO;\n    _n = _n - &ZERO;\n    _n = ZERO - _n;\n    _n = &ZERO - _n;\n    _n = _n / 99;\n    _n = _n / &99;\n    _n = _n % 99;\n    _n = _n % &99;\n    _n = _n * 0;\n    _n = _n * &0;\n    _n = 0 * _n;\n    _n = &0 * _n;\n    _n = _n * 1;\n    _n = _n * &1;\n    _n = ZERO * _n;\n    _n = &ZERO * _n;\n    _n = _n * ONE;\n    _n = _n * &ONE;\n    _n = 1 * _n;\n    _n = &1 * _n;\n    _n = 23 + 85;\n\n    // Method\n    _n.saturating_div(1);\n    _n.wrapping_div(1);\n    _n.wrapping_rem(1);\n    _n.wrapping_rem_euclid(1);\n\n    _n.saturating_div(1);\n    _n.checked_div(1);\n    _n.checked_rem(1);\n    _n.checked_rem_euclid(1);\n\n    // Unary\n    _n = -2147483647;\n    _n = -i32::MAX;\n    _n = -i32::MIN;\n    _n = -&2147483647;\n    _n = -&i32::MAX;\n    _n = -&i32::MIN;\n}\n\npub fn unknown_ops_or_runtime_ops_that_can_overflow() {\n    let mut _n = i32::MAX;\n    let mut _custom = Custom;\n\n    // Assign\n    _n += 1;\n    //~^ arithmetic_side_effects\n    _n += &1;\n    //~^ arithmetic_side_effects\n    _n -= 1;\n    //~^ arithmetic_side_effects\n    _n -= &1;\n    //~^ arithmetic_side_effects\n    _n /= 0;\n    //~^ arithmetic_side_effects\n    _n /= &0;\n    //~^ arithmetic_side_effects\n    _n %= 0;\n    //~^ arithmetic_side_effects\n    _n %= &0;\n    //~^ arithmetic_side_effects\n    _n *= 2;\n    //~^ arithmetic_side_effects\n    _n *= &2;\n    //~^ arithmetic_side_effects\n    _n += -1;\n    //~^ arithmetic_side_effects\n    _n += &-1;\n    //~^ arithmetic_side_effects\n    _n -= -1;\n    //~^ arithmetic_side_effects\n    _n -= &-1;\n    //~^ arithmetic_side_effects\n    _n /= -0;\n    //~^ arithmetic_side_effects\n    _n /= &-0;\n    //~^ arithmetic_side_effects\n    _n %= -0;\n    //~^ arithmetic_side_effects\n    _n %= &-0;\n    //~^ arithmetic_side_effects\n    _n *= -2;\n    //~^ arithmetic_side_effects\n    _n *= &-2;\n    //~^ arithmetic_side_effects\n    _custom += Custom;\n    //~^ arithmetic_side_effects\n    _custom += &Custom;\n    //~^ arithmetic_side_effects\n    _custom -= Custom;\n    //~^ arithmetic_side_effects\n    _custom -= &Custom;\n    //~^ arithmetic_side_effects\n    _custom /= Custom;\n    //~^ arithmetic_side_effects\n    _custom /= &Custom;\n    //~^ arithmetic_side_effects\n    _custom %= Custom;\n    //~^ arithmetic_side_effects\n    _custom %= &Custom;\n    //~^ arithmetic_side_effects\n    _custom *= Custom;\n    //~^ arithmetic_side_effects\n    _custom *= &Custom;\n    //~^ arithmetic_side_effects\n    _custom >>= Custom;\n    //~^ arithmetic_side_effects\n    _custom >>= &Custom;\n    //~^ arithmetic_side_effects\n    _custom <<= Custom;\n    //~^ arithmetic_side_effects\n    _custom <<= &Custom;\n    //~^ arithmetic_side_effects\n    _custom += -Custom;\n    //~^ arithmetic_side_effects\n    _custom += &-Custom;\n    //~^ arithmetic_side_effects\n    _custom -= -Custom;\n    //~^ arithmetic_side_effects\n    _custom -= &-Custom;\n    //~^ arithmetic_side_effects\n    _custom /= -Custom;\n    //~^ arithmetic_side_effects\n    _custom /= &-Custom;\n    //~^ arithmetic_side_effects\n    _custom %= -Custom;\n    //~^ arithmetic_side_effects\n    _custom %= &-Custom;\n    //~^ arithmetic_side_effects\n    _custom *= -Custom;\n    //~^ arithmetic_side_effects\n    _custom *= &-Custom;\n    //~^ arithmetic_side_effects\n    _custom >>= -Custom;\n    //~^ arithmetic_side_effects\n    _custom >>= &-Custom;\n    //~^ arithmetic_side_effects\n    _custom <<= -Custom;\n    //~^ arithmetic_side_effects\n    _custom <<= &-Custom;\n    //~^ arithmetic_side_effects\n\n    // Binary\n    _n = _n + 1;\n    //~^ arithmetic_side_effects\n    _n = _n + &1;\n    //~^ arithmetic_side_effects\n    _n = 1 + _n;\n    //~^ arithmetic_side_effects\n    _n = &1 + _n;\n    //~^ arithmetic_side_effects\n    _n = _n - 1;\n    //~^ arithmetic_side_effects\n    _n = _n - &1;\n    //~^ arithmetic_side_effects\n    _n = 1 - _n;\n    //~^ arithmetic_side_effects\n    _n = &1 - _n;\n    //~^ arithmetic_side_effects\n    _n = _n / 0;\n    //~^ arithmetic_side_effects\n    _n = _n / &0;\n    //~^ arithmetic_side_effects\n    _n = _n % 0;\n    //~^ arithmetic_side_effects\n    _n = _n % &0;\n    //~^ arithmetic_side_effects\n    _n = _n * 2;\n    //~^ arithmetic_side_effects\n    _n = _n * &2;\n    //~^ arithmetic_side_effects\n    _n = 2 * _n;\n    //~^ arithmetic_side_effects\n    _n = &2 * _n;\n    //~^ arithmetic_side_effects\n    _n = 23 + &85;\n    //~^ arithmetic_side_effects\n    _n = &23 + 85;\n    //~^ arithmetic_side_effects\n    _n = &23 + &85;\n    //~^ arithmetic_side_effects\n    _custom = _custom + _custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom + &_custom;\n    //~^ arithmetic_side_effects\n    _custom = Custom + _custom;\n    //~^ arithmetic_side_effects\n    _custom = &Custom + _custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom - Custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom - &Custom;\n    //~^ arithmetic_side_effects\n    _custom = Custom - _custom;\n    //~^ arithmetic_side_effects\n    _custom = &Custom - _custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom / Custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom / &Custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom % Custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom % &Custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom * Custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom * &Custom;\n    //~^ arithmetic_side_effects\n    _custom = Custom * _custom;\n    //~^ arithmetic_side_effects\n    _custom = &Custom * _custom;\n    //~^ arithmetic_side_effects\n    _custom = Custom + &Custom;\n    //~^ arithmetic_side_effects\n    _custom = &Custom + Custom;\n    //~^ arithmetic_side_effects\n    _custom = &Custom + &Custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom >> _custom;\n    //~^ arithmetic_side_effects\n    _custom = _custom >> &_custom;\n    //~^ arithmetic_side_effects\n    _custom = Custom << _custom;\n    //~^ arithmetic_side_effects\n    _custom = &Custom << _custom;\n    //~^ arithmetic_side_effects\n\n    // Method\n    _n.saturating_div(0);\n    //~^ arithmetic_side_effects\n    _n.wrapping_div(0);\n    //~^ arithmetic_side_effects\n    _n.wrapping_rem(0);\n    //~^ arithmetic_side_effects\n    _n.wrapping_rem_euclid(0);\n    //~^ arithmetic_side_effects\n\n    _n.saturating_div(_n);\n    //~^ arithmetic_side_effects\n    _n.wrapping_div(_n);\n    //~^ arithmetic_side_effects\n    _n.wrapping_rem(_n);\n    //~^ arithmetic_side_effects\n    _n.wrapping_rem_euclid(_n);\n    //~^ arithmetic_side_effects\n\n    _n.saturating_div(*Box::new(_n));\n    //~^ arithmetic_side_effects\n\n    // Unary\n    _n = -_n;\n    //~^ arithmetic_side_effects\n    _n = -&_n;\n    //~^ arithmetic_side_effects\n    _custom = -_custom;\n    //~^ arithmetic_side_effects\n    _custom = -&_custom;\n    //~^ arithmetic_side_effects\n    _ = -*Box::new(_n);\n    //~^ arithmetic_side_effects\n}\n\n// Copied and pasted from the `integer_arithmetic` lint for comparison.\npub fn integer_arithmetic() {\n    let mut i = 1i32;\n    let mut var1 = 0i32;\n    let mut var2 = -1i32;\n\n    1 + i;\n    //~^ arithmetic_side_effects\n    i * 2;\n    //~^ arithmetic_side_effects\n    1 % i / 2;\n    //~^ arithmetic_side_effects\n    i - 2 + 2 - i;\n    //~^ arithmetic_side_effects\n    -i;\n    //~^ arithmetic_side_effects\n    i >> 1;\n    i << 1;\n\n    -1;\n    -(-1);\n\n    i & 1;\n    i | 1;\n    i ^ 1;\n\n    i += 1;\n    //~^ arithmetic_side_effects\n    i -= 1;\n    //~^ arithmetic_side_effects\n    i *= 2;\n    //~^ arithmetic_side_effects\n    i /= 2;\n    i /= 0;\n    //~^ arithmetic_side_effects\n    i /= -1;\n    i /= var1;\n    //~^ arithmetic_side_effects\n    i /= var2;\n    //~^ arithmetic_side_effects\n    i %= 2;\n    i %= 0;\n    //~^ arithmetic_side_effects\n    i %= -1;\n    i %= var1;\n    //~^ arithmetic_side_effects\n    i %= var2;\n    //~^ arithmetic_side_effects\n    i <<= 3;\n    i >>= 2;\n\n    i |= 1;\n    i &= 1;\n    i ^= i;\n}\n\npub fn issue_10583(a: u16) -> u16 {\n    10 / a\n    //~^ arithmetic_side_effects\n}\n\npub fn issue_10767() {\n    let n = &1.0;\n    n + n;\n    3.1_f32 + &1.2_f32;\n    &3.4_f32 + 1.5_f32;\n    &3.5_f32 + &1.3_f32;\n}\n\npub fn issue_10792() {\n    struct One {\n        a: u32,\n    }\n    struct Two {\n        b: u32,\n        c: u64,\n    }\n    const ONE: One = One { a: 1 };\n    const TWO: Two = Two { b: 2, c: 3 };\n    let _ = 10 / ONE.a;\n    let _ = 10 / TWO.b;\n    let _ = 10 / TWO.c;\n}\n\npub fn issue_11145() {\n    let mut x: Wrapping<u32> = Wrapping(0_u32);\n    x += 1;\n}\n\npub fn issue_11262() {\n    let one = 1;\n    let zero = 0;\n    let _ = 2 / one;\n    let _ = 2 / zero;\n}\n\npub fn issue_11392() {\n    fn example_div(unsigned: usize, nonzero_unsigned: NonZero<usize>) -> usize {\n        unsigned / nonzero_unsigned\n    }\n\n    fn example_rem(unsigned: usize, nonzero_unsigned: NonZero<usize>) -> usize {\n        unsigned % nonzero_unsigned\n    }\n\n    let (unsigned, nonzero_unsigned) = (0, NonZero::new(1).unwrap());\n    example_div(unsigned, nonzero_unsigned);\n    example_rem(unsigned, nonzero_unsigned);\n}\n\npub fn issue_11393() {\n    fn example_div(x: Wrapping<i32>, maybe_zero: Wrapping<i32>) -> Wrapping<i32> {\n        x / maybe_zero\n        //~^ arithmetic_side_effects\n    }\n\n    fn example_rem(x: Wrapping<i32>, maybe_zero: Wrapping<i32>) -> Wrapping<i32> {\n        x % maybe_zero\n        //~^ arithmetic_side_effects\n    }\n\n    let [x, maybe_zero] = [1, 0].map(Wrapping);\n    example_div(x, maybe_zero);\n    example_rem(x, maybe_zero);\n}\n\npub fn issue_12318() {\n    use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};\n    let mut one: i32 = 1;\n    one.add_assign(1);\n    //~^ arithmetic_side_effects\n    one.div_assign(1);\n    one.mul_assign(1);\n    one.rem_assign(1);\n    one.sub_assign(1);\n    //~^ arithmetic_side_effects\n}\n\npub fn issue_15225() {\n    use core::num::{NonZero, NonZeroU8};\n\n    let one = const { NonZeroU8::new(1).unwrap() };\n    let _ = one.get() - 1;\n\n    let one: NonZero<u8> = const { NonZero::new(1).unwrap() };\n    let _ = one.get() - 1;\n\n    type AliasedType = u8;\n    let one: NonZero<AliasedType> = const { NonZero::new(1).unwrap() };\n    let _ = one.get() - 1;\n}\n\npub fn explicit_methods() {\n    use core::ops::Add;\n    let one: i32 = 1;\n    one.add(&one);\n    //~^ arithmetic_side_effects\n    Box::new(one).add(one);\n    //~^ arithmetic_side_effects\n}\n\npub fn issue_15943(days: u8) -> Duration {\n    Duration::from_secs(86400 * u64::from(days))\n}\n\npub fn type_conversion_add() {\n    let _ = u128::MAX + u128::from(1u8);\n    //~^ arithmetic_side_effects\n    let _ = 1u128 + u128::from(1u16);\n    let _ = 1u128 + u128::from(1u32);\n    let _ = 1u128 + u128::from(1u64);\n\n    let _ = 1u64 + u64::from(1u8);\n    let _ = 1u64 + u64::from(1u16);\n    let _ = 1u64 + u64::from(1u32);\n\n    let _ = 1u32 + u32::from(1u8);\n    let _ = 1u32 + u32::from(1u16);\n\n    let _ = 1u16 + u16::from(1u8);\n}\n\npub fn type_conversion_mul() {\n    let _ = u128::MAX * u128::from(1u8);\n    //~^ arithmetic_side_effects\n    let _ = 1u128 * u128::from(1u16);\n    let _ = 1u128 * u128::from(1u32);\n    let _ = 1u128 * u128::from(1u64);\n\n    let _ = 1u64 * u64::from(1u8);\n    let _ = 1u64 * u64::from(1u16);\n    let _ = 1u64 * u64::from(1u32);\n\n    let _ = 1u32 * u32::from(1u8);\n    let _ = 1u32 * u32::from(1u16);\n\n    let _ = 1u16 * u16::from(1u8);\n}\n\npub fn type_conversion_does_not_escape_its_context() {\n    struct Foo;\n    impl Foo {\n        fn from(n: u8) -> u64 {\n            u64::from(n)\n        }\n    }\n    let _ = Duration::from_secs(86400 * Foo::from(1));\n    //~^ arithmetic_side_effects\n\n    fn shift(x: u8) -> u64 {\n        1 << u64::from(x)\n    }\n    let _ = Duration::from_secs(86400 * shift(1));\n    //~^ arithmetic_side_effects\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/arithmetic_side_effects.stderr",
    "content": "error: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:167:13\n   |\nLL |     let _ = 1f16 + 1f16;\n   |             ^^^^^^^^^^^\n   |\n   = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:171:13\n   |\nLL |     let _ = 1f128 + 1f128;\n   |             ^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:311:5\n   |\nLL |     _n += 1;\n   |     ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:313:5\n   |\nLL |     _n += &1;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:315:5\n   |\nLL |     _n -= 1;\n   |     ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:317:5\n   |\nLL |     _n -= &1;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:319:5\n   |\nLL |     _n /= 0;\n   |     ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:321:5\n   |\nLL |     _n /= &0;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:323:5\n   |\nLL |     _n %= 0;\n   |     ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:325:5\n   |\nLL |     _n %= &0;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:327:5\n   |\nLL |     _n *= 2;\n   |     ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:329:5\n   |\nLL |     _n *= &2;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:331:5\n   |\nLL |     _n += -1;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:333:5\n   |\nLL |     _n += &-1;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:335:5\n   |\nLL |     _n -= -1;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:337:5\n   |\nLL |     _n -= &-1;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:339:5\n   |\nLL |     _n /= -0;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:341:5\n   |\nLL |     _n /= &-0;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:343:5\n   |\nLL |     _n %= -0;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:345:5\n   |\nLL |     _n %= &-0;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:347:5\n   |\nLL |     _n *= -2;\n   |     ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:349:5\n   |\nLL |     _n *= &-2;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:351:5\n   |\nLL |     _custom += Custom;\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:353:5\n   |\nLL |     _custom += &Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:355:5\n   |\nLL |     _custom -= Custom;\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:357:5\n   |\nLL |     _custom -= &Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:359:5\n   |\nLL |     _custom /= Custom;\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:361:5\n   |\nLL |     _custom /= &Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:363:5\n   |\nLL |     _custom %= Custom;\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:365:5\n   |\nLL |     _custom %= &Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:367:5\n   |\nLL |     _custom *= Custom;\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:369:5\n   |\nLL |     _custom *= &Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:371:5\n   |\nLL |     _custom >>= Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:373:5\n   |\nLL |     _custom >>= &Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:375:5\n   |\nLL |     _custom <<= Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:377:5\n   |\nLL |     _custom <<= &Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:379:5\n   |\nLL |     _custom += -Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:381:5\n   |\nLL |     _custom += &-Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:383:5\n   |\nLL |     _custom -= -Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:385:5\n   |\nLL |     _custom -= &-Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:387:5\n   |\nLL |     _custom /= -Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:389:5\n   |\nLL |     _custom /= &-Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:391:5\n   |\nLL |     _custom %= -Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:393:5\n   |\nLL |     _custom %= &-Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:395:5\n   |\nLL |     _custom *= -Custom;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:397:5\n   |\nLL |     _custom *= &-Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:399:5\n   |\nLL |     _custom >>= -Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:401:5\n   |\nLL |     _custom >>= &-Custom;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:403:5\n   |\nLL |     _custom <<= -Custom;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:405:5\n   |\nLL |     _custom <<= &-Custom;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:409:10\n   |\nLL |     _n = _n + 1;\n   |          ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:411:10\n   |\nLL |     _n = _n + &1;\n   |          ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:413:10\n   |\nLL |     _n = 1 + _n;\n   |          ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:415:10\n   |\nLL |     _n = &1 + _n;\n   |          ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:417:10\n   |\nLL |     _n = _n - 1;\n   |          ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:419:10\n   |\nLL |     _n = _n - &1;\n   |          ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:421:10\n   |\nLL |     _n = 1 - _n;\n   |          ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:423:10\n   |\nLL |     _n = &1 - _n;\n   |          ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:425:10\n   |\nLL |     _n = _n / 0;\n   |          ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:427:10\n   |\nLL |     _n = _n / &0;\n   |          ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:429:10\n   |\nLL |     _n = _n % 0;\n   |          ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:431:10\n   |\nLL |     _n = _n % &0;\n   |          ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:433:10\n   |\nLL |     _n = _n * 2;\n   |          ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:435:10\n   |\nLL |     _n = _n * &2;\n   |          ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:437:10\n   |\nLL |     _n = 2 * _n;\n   |          ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:439:10\n   |\nLL |     _n = &2 * _n;\n   |          ^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:441:10\n   |\nLL |     _n = 23 + &85;\n   |          ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:443:10\n   |\nLL |     _n = &23 + 85;\n   |          ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:445:10\n   |\nLL |     _n = &23 + &85;\n   |          ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:447:15\n   |\nLL |     _custom = _custom + _custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:449:15\n   |\nLL |     _custom = _custom + &_custom;\n   |               ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:451:15\n   |\nLL |     _custom = Custom + _custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:453:15\n   |\nLL |     _custom = &Custom + _custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:455:15\n   |\nLL |     _custom = _custom - Custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:457:15\n   |\nLL |     _custom = _custom - &Custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:459:15\n   |\nLL |     _custom = Custom - _custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:461:15\n   |\nLL |     _custom = &Custom - _custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:463:15\n   |\nLL |     _custom = _custom / Custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:465:15\n   |\nLL |     _custom = _custom / &Custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:467:15\n   |\nLL |     _custom = _custom % Custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:469:15\n   |\nLL |     _custom = _custom % &Custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:471:15\n   |\nLL |     _custom = _custom * Custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:473:15\n   |\nLL |     _custom = _custom * &Custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:475:15\n   |\nLL |     _custom = Custom * _custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:477:15\n   |\nLL |     _custom = &Custom * _custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:479:15\n   |\nLL |     _custom = Custom + &Custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:481:15\n   |\nLL |     _custom = &Custom + Custom;\n   |               ^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:483:15\n   |\nLL |     _custom = &Custom + &Custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:485:15\n   |\nLL |     _custom = _custom >> _custom;\n   |               ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:487:15\n   |\nLL |     _custom = _custom >> &_custom;\n   |               ^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:489:15\n   |\nLL |     _custom = Custom << _custom;\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:491:15\n   |\nLL |     _custom = &Custom << _custom;\n   |               ^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:495:23\n   |\nLL |     _n.saturating_div(0);\n   |                       ^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:497:21\n   |\nLL |     _n.wrapping_div(0);\n   |                     ^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:499:21\n   |\nLL |     _n.wrapping_rem(0);\n   |                     ^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:501:28\n   |\nLL |     _n.wrapping_rem_euclid(0);\n   |                            ^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:504:23\n   |\nLL |     _n.saturating_div(_n);\n   |                       ^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:506:21\n   |\nLL |     _n.wrapping_div(_n);\n   |                     ^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:508:21\n   |\nLL |     _n.wrapping_rem(_n);\n   |                     ^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:510:28\n   |\nLL |     _n.wrapping_rem_euclid(_n);\n   |                            ^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:513:23\n   |\nLL |     _n.saturating_div(*Box::new(_n));\n   |                       ^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:517:10\n   |\nLL |     _n = -_n;\n   |          ^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:519:10\n   |\nLL |     _n = -&_n;\n   |          ^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:521:15\n   |\nLL |     _custom = -_custom;\n   |               ^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:523:15\n   |\nLL |     _custom = -&_custom;\n   |               ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:525:9\n   |\nLL |     _ = -*Box::new(_n);\n   |         ^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:535:5\n   |\nLL |     1 + i;\n   |     ^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:537:5\n   |\nLL |     i * 2;\n   |     ^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:539:5\n   |\nLL |     1 % i / 2;\n   |     ^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:541:5\n   |\nLL |     i - 2 + 2 - i;\n   |     ^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:543:5\n   |\nLL |     -i;\n   |     ^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:555:5\n   |\nLL |     i += 1;\n   |     ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:557:5\n   |\nLL |     i -= 1;\n   |     ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:559:5\n   |\nLL |     i *= 2;\n   |     ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:562:5\n   |\nLL |     i /= 0;\n   |     ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:565:5\n   |\nLL |     i /= var1;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:567:5\n   |\nLL |     i /= var2;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:570:5\n   |\nLL |     i %= 0;\n   |     ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:573:5\n   |\nLL |     i %= var1;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:575:5\n   |\nLL |     i %= var2;\n   |     ^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:586:5\n   |\nLL |     10 / a\n   |     ^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:641:9\n   |\nLL |         x / maybe_zero\n   |         ^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:646:9\n   |\nLL |         x % maybe_zero\n   |         ^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:658:5\n   |\nLL |     one.add_assign(1);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:663:5\n   |\nLL |     one.sub_assign(1);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:684:5\n   |\nLL |     one.add(&one);\n   |     ^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:686:5\n   |\nLL |     Box::new(one).add(one);\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:695:13\n   |\nLL |     let _ = u128::MAX + u128::from(1u8);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:712:13\n   |\nLL |     let _ = u128::MAX * u128::from(1u8);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:735:33\n   |\nLL |     let _ = Duration::from_secs(86400 * Foo::from(1));\n   |                                 ^^^^^^^^^^^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui/arithmetic_side_effects.rs:741:33\n   |\nLL |     let _ = Duration::from_secs(86400 * shift(1));\n   |                                 ^^^^^^^^^^^^^^^^\n\nerror: aborting due to 131 previous errors\n\n"
  },
  {
    "path": "tests/ui/as_conversions.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::as_conversions)]\n#![allow(clippy::borrow_as_ptr, unused)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nfn main() {\n    let i = 0u32 as u64; //~ as_conversions\n\n    let j = &i as *const u64 as *mut u64;\n    //~^ as_conversions\n    //~| as_conversions\n\n    external!(0u32 as u64);\n}\n\nwith_span!(\n    span\n\n    fn converting() {\n        let x = 0u32 as u64;\n    }\n);\n"
  },
  {
    "path": "tests/ui/as_conversions.stderr",
    "content": "error: using a potentially dangerous silent `as` conversion\n  --> tests/ui/as_conversions.rs:10:13\n   |\nLL |     let i = 0u32 as u64;\n   |             ^^^^^^^^^^^\n   |\n   = help: consider using a safe wrapper for this conversion\n   = note: `-D clippy::as-conversions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::as_conversions)]`\n\nerror: using a potentially dangerous silent `as` conversion\n  --> tests/ui/as_conversions.rs:12:13\n   |\nLL |     let j = &i as *const u64 as *mut u64;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a safe wrapper for this conversion\n\nerror: using a potentially dangerous silent `as` conversion\n  --> tests/ui/as_conversions.rs:12:13\n   |\nLL |     let j = &i as *const u64 as *mut u64;\n   |             ^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a safe wrapper for this conversion\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/as_pointer_underscore.fixed",
    "content": "#![warn(clippy::as_pointer_underscore)]\n#![crate_type = \"lib\"]\n#![no_std]\n\nstruct S;\n\nfn f(s: &S) -> usize {\n    &s as *const &S as usize\n    //~^ as_pointer_underscore\n}\n\nfn g(s: &mut S) -> usize {\n    s as *mut S as usize\n    //~^ as_pointer_underscore\n}\n"
  },
  {
    "path": "tests/ui/as_pointer_underscore.rs",
    "content": "#![warn(clippy::as_pointer_underscore)]\n#![crate_type = \"lib\"]\n#![no_std]\n\nstruct S;\n\nfn f(s: &S) -> usize {\n    &s as *const _ as usize\n    //~^ as_pointer_underscore\n}\n\nfn g(s: &mut S) -> usize {\n    s as *mut _ as usize\n    //~^ as_pointer_underscore\n}\n"
  },
  {
    "path": "tests/ui/as_pointer_underscore.stderr",
    "content": "error: using inferred pointer cast\n  --> tests/ui/as_pointer_underscore.rs:8:11\n   |\nLL |     &s as *const _ as usize\n   |           ^^^^^^^^ help: use explicit type: `*const &S`\n   |\n   = note: `-D clippy::as-pointer-underscore` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::as_pointer_underscore)]`\n\nerror: using inferred pointer cast\n  --> tests/ui/as_pointer_underscore.rs:13:10\n   |\nLL |     s as *mut _ as usize\n   |          ^^^^^^ help: use explicit type: `*mut S`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/as_ptr_cast_mut.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::as_ptr_cast_mut)]\n#![allow(clippy::wrong_self_convention, clippy::unnecessary_cast)]\n\nstruct MutPtrWrapper(Vec<u8>);\nimpl MutPtrWrapper {\n    fn as_ptr(&mut self) -> *const u8 {\n        self.0.as_mut_ptr() as *const u8\n    }\n}\n\nstruct Covariant<T>(*const T);\nimpl<T> Covariant<T> {\n    fn as_ptr(self) -> *const T {\n        self.0\n    }\n}\n\nfn main() {\n    let mut string = String::new();\n    let _ = string.as_mut_ptr();\n    //~^ as_ptr_cast_mut\n\n    let _ = string.as_ptr() as *const i8;\n    let _ = string.as_mut_ptr();\n    let _ = string.as_mut_ptr() as *mut u8;\n    let _ = string.as_mut_ptr() as *const u8;\n\n    let nn = std::ptr::NonNull::new(4 as *mut u8).unwrap();\n    let _ = nn.as_ptr() as *mut u8;\n\n    let mut wrap = MutPtrWrapper(Vec::new());\n    let _ = wrap.as_ptr() as *mut u8;\n\n    let mut local = 4;\n    let ref_with_write_perm = Covariant(std::ptr::addr_of_mut!(local) as *const _);\n    let _ = ref_with_write_perm.as_ptr() as *mut u8;\n}\n"
  },
  {
    "path": "tests/ui/as_ptr_cast_mut.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::as_ptr_cast_mut)]\n#![allow(clippy::wrong_self_convention, clippy::unnecessary_cast)]\n\nstruct MutPtrWrapper(Vec<u8>);\nimpl MutPtrWrapper {\n    fn as_ptr(&mut self) -> *const u8 {\n        self.0.as_mut_ptr() as *const u8\n    }\n}\n\nstruct Covariant<T>(*const T);\nimpl<T> Covariant<T> {\n    fn as_ptr(self) -> *const T {\n        self.0\n    }\n}\n\nfn main() {\n    let mut string = String::new();\n    let _ = string.as_ptr() as *mut u8;\n    //~^ as_ptr_cast_mut\n\n    let _ = string.as_ptr() as *const i8;\n    let _ = string.as_mut_ptr();\n    let _ = string.as_mut_ptr() as *mut u8;\n    let _ = string.as_mut_ptr() as *const u8;\n\n    let nn = std::ptr::NonNull::new(4 as *mut u8).unwrap();\n    let _ = nn.as_ptr() as *mut u8;\n\n    let mut wrap = MutPtrWrapper(Vec::new());\n    let _ = wrap.as_ptr() as *mut u8;\n\n    let mut local = 4;\n    let ref_with_write_perm = Covariant(std::ptr::addr_of_mut!(local) as *const _);\n    let _ = ref_with_write_perm.as_ptr() as *mut u8;\n}\n"
  },
  {
    "path": "tests/ui/as_ptr_cast_mut.stderr",
    "content": "error: casting the result of `as_ptr` to *mut u8\n  --> tests/ui/as_ptr_cast_mut.rs:21:13\n   |\nLL |     let _ = string.as_ptr() as *mut u8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `string.as_mut_ptr()`\n   |\n   = note: `-D clippy::as-ptr-cast-mut` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::as_ptr_cast_mut)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/as_ptr_cast_mut_unfixable.rs",
    "content": "//@no-rustfix\n#![allow(unused)]\n#![warn(clippy::as_ptr_cast_mut)]\n\nfn main() {\n    let mut string = String::new();\n\n    // the `*mut _` is actually necessary since it does two things at once:\n    // - changes the mutability (caught by the lint)\n    // - changes the type\n    //\n    // and so replacing this with `as_mut_ptr` removes the second thing,\n    // resulting in a type mismatch\n    let _: *mut i8 = string.as_ptr() as *mut _;\n    //~^ as_ptr_cast_mut\n}\n"
  },
  {
    "path": "tests/ui/as_ptr_cast_mut_unfixable.stderr",
    "content": "error: casting the result of `as_ptr` to *mut i8\n  --> tests/ui/as_ptr_cast_mut_unfixable.rs:14:22\n   |\nLL |     let _: *mut i8 = string.as_ptr() as *mut _;\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `string.as_mut_ptr()`\n   |\n   = note: `-D clippy::as-ptr-cast-mut` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::as_ptr_cast_mut)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/as_underscore.fixed",
    "content": "#![warn(clippy::as_underscore)]\n\nfn foo(_n: usize) {}\n\nfn main() {\n    let n: u16 = 256;\n    foo(n as usize);\n    //~^ as_underscore\n\n    let n = 0_u128;\n    let _n: u8 = n as u8;\n    //~^ as_underscore\n}\n"
  },
  {
    "path": "tests/ui/as_underscore.rs",
    "content": "#![warn(clippy::as_underscore)]\n\nfn foo(_n: usize) {}\n\nfn main() {\n    let n: u16 = 256;\n    foo(n as _);\n    //~^ as_underscore\n\n    let n = 0_u128;\n    let _n: u8 = n as _;\n    //~^ as_underscore\n}\n"
  },
  {
    "path": "tests/ui/as_underscore.stderr",
    "content": "error: using `as _` conversion\n  --> tests/ui/as_underscore.rs:7:9\n   |\nLL |     foo(n as _);\n   |         ^^^^^-\n   |              |\n   |              help: consider giving the type explicitly: `usize`\n   |\n   = note: `-D clippy::as-underscore` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::as_underscore)]`\n\nerror: using `as _` conversion\n  --> tests/ui/as_underscore.rs:11:18\n   |\nLL |     let _n: u8 = n as _;\n   |                  ^^^^^-\n   |                       |\n   |                       help: consider giving the type explicitly: `u8`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/as_underscore_unfixable.rs",
    "content": "//@no-rustfix\n\n#![warn(clippy::as_underscore)]\n\nfn main() {\n    // From issue #15282\n    let f = async || ();\n    let _: Box<dyn FnOnce() -> _> = Box::new(f) as _;\n    //~^ as_underscore\n\n    let barr = || (|| ());\n    let _: Box<dyn Fn() -> _> = Box::new(barr) as _;\n    //~^ as_underscore\n}\n"
  },
  {
    "path": "tests/ui/as_underscore_unfixable.stderr",
    "content": "error: using `as _` conversion\n  --> tests/ui/as_underscore_unfixable.rs:8:37\n   |\nLL |     let _: Box<dyn FnOnce() -> _> = Box::new(f) as _;\n   |                                     ^^^^^^^^^^^^^^^^\n   |\n   = help: consider giving the type explicitly\n   = note: `-D clippy::as-underscore` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::as_underscore)]`\n\nerror: using `as _` conversion\n  --> tests/ui/as_underscore_unfixable.rs:12:33\n   |\nLL |     let _: Box<dyn Fn() -> _> = Box::new(barr) as _;\n   |                                 ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider giving the type explicitly\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/asm_syntax_not_x86.rs",
    "content": "//@ignore-target: i686 x86\n//@needs-asm-support\n//@check-pass\n\n#[warn(clippy::inline_asm_x86_intel_syntax)]\n#[warn(clippy::inline_asm_x86_att_syntax)]\nmod dont_warn {\n    use std::arch::{asm, global_asm};\n\n    pub(super) unsafe fn use_asm() {\n        unsafe {\n            asm!(\"\");\n            asm!(\"\", options());\n            asm!(\"\", options(nostack));\n        }\n    }\n\n    global_asm!(\"\");\n    global_asm!(\"\", options());\n}\n\nfn main() {\n    unsafe {\n        dont_warn::use_asm();\n    }\n}\n"
  },
  {
    "path": "tests/ui/asm_syntax_x86.i686.stderr",
    "content": "error: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:10:9\n   |\nLL |         asm!(\"\");\n   |         ^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n   = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_intel_syntax)]`\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:12:9\n   |\nLL |         asm!(\"\", options());\n   |         ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:14:9\n   |\nLL |         asm!(\"\", options(nostack));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:20:5\n   |\nLL |     global_asm!(\"\");\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:22:5\n   |\nLL |     global_asm!(\"\", options());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:35:9\n   |\nLL |         asm!(\"\", options(att_syntax));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n   = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_att_syntax)]`\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:37:9\n   |\nLL |         asm!(\"\", options(nostack, att_syntax));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:43:5\n   |\nLL |     global_asm!(\"\", options(att_syntax));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/asm_syntax_x86.rs",
    "content": "//@only-target: i686 x86_64\n\n#[warn(clippy::inline_asm_x86_intel_syntax)]\nmod warn_intel {\n    use std::arch::{asm, global_asm};\n\n    pub(super) unsafe fn use_asm() {\n        unsafe {\n            asm!(\"\");\n            //~^ inline_asm_x86_intel_syntax\n\n            asm!(\"\", options());\n            //~^ inline_asm_x86_intel_syntax\n\n            asm!(\"\", options(nostack));\n            //~^ inline_asm_x86_intel_syntax\n\n            asm!(\"\", options(att_syntax));\n            asm!(\"\", options(nostack, att_syntax));\n        }\n    }\n\n    global_asm!(\"\");\n    //~^ inline_asm_x86_intel_syntax\n\n    global_asm!(\"\", options());\n    //~^ inline_asm_x86_intel_syntax\n\n    global_asm!(\"\", options(att_syntax));\n}\n\n#[warn(clippy::inline_asm_x86_att_syntax)]\nmod warn_att {\n    use std::arch::{asm, global_asm};\n\n    pub(super) unsafe fn use_asm() {\n        unsafe {\n            asm!(\"\");\n            asm!(\"\", options());\n            asm!(\"\", options(nostack));\n            asm!(\"\", options(att_syntax));\n            //~^ inline_asm_x86_att_syntax\n\n            asm!(\"\", options(nostack, att_syntax));\n            //~^ inline_asm_x86_att_syntax\n        }\n    }\n\n    global_asm!(\"\");\n    global_asm!(\"\", options());\n    global_asm!(\"\", options(att_syntax));\n    //~^ inline_asm_x86_att_syntax\n}\n\nfn main() {\n    unsafe {\n        warn_att::use_asm();\n        warn_intel::use_asm();\n    }\n}\n"
  },
  {
    "path": "tests/ui/asm_syntax_x86.stderr",
    "content": "error: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:9:13\n   |\nLL |             asm!(\"\");\n   |             ^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n   = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_intel_syntax)]`\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:12:13\n   |\nLL |             asm!(\"\", options());\n   |             ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:15:13\n   |\nLL |             asm!(\"\", options(nostack));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:23:5\n   |\nLL |     global_asm!(\"\");\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:26:5\n   |\nLL |     global_asm!(\"\", options());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:41:13\n   |\nLL |             asm!(\"\", options(att_syntax));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n   = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_att_syntax)]`\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:44:13\n   |\nLL |             asm!(\"\", options(nostack, att_syntax));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:51:5\n   |\nLL |     global_asm!(\"\", options(att_syntax));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/asm_syntax_x86.x86_64.stderr",
    "content": "error: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:10:9\n   |\nLL |         asm!(\"\");\n   |         ^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n   = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_intel_syntax)]`\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:12:9\n   |\nLL |         asm!(\"\", options());\n   |         ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:14:9\n   |\nLL |         asm!(\"\", options(nostack));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:20:5\n   |\nLL |     global_asm!(\"\");\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: Intel x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:22:5\n   |\nLL |     global_asm!(\"\", options());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use AT&T x86 assembly syntax\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:35:9\n   |\nLL |         asm!(\"\", options(att_syntax));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n   = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_att_syntax)]`\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:37:9\n   |\nLL |         asm!(\"\", options(nostack, att_syntax));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n\nerror: AT&T x86 assembly syntax used\n  --> tests/ui/asm_syntax_x86.rs:43:5\n   |\nLL |     global_asm!(\"\", options(att_syntax));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use Intel x86 assembly syntax\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/assertions_on_constants.rs",
    "content": "#![allow(non_fmt_panics, clippy::needless_bool, clippy::eq_op)]\n\nmacro_rules! assert_const {\n    ($len:expr) => {\n        assert!($len > 0);\n        debug_assert!($len < 0);\n    };\n}\nfn main() {\n    assert!(true);\n    //~^ assertions_on_constants\n\n    assert!(false);\n    //~^ assertions_on_constants\n\n    assert!(true, \"true message\");\n    //~^ assertions_on_constants\n\n    assert!(false, \"false message\");\n    //~^ assertions_on_constants\n\n    let msg = \"panic message\";\n    assert!(false, \"{}\", msg.to_uppercase());\n    //~^ assertions_on_constants\n\n    const B: bool = true;\n    assert!(B);\n    //~^ assertions_on_constants\n\n    const C: bool = false;\n    assert!(C);\n    //~^ assertions_on_constants\n\n    assert!(C, \"C message\");\n    //~^ assertions_on_constants\n\n    debug_assert!(true);\n    //~^ assertions_on_constants\n\n    // Don't lint this, since there is no better way for expressing \"Only panic in debug mode\".\n    debug_assert!(false); // #3948\n    assert_const!(3);\n    assert_const!(-1);\n\n    assert!(cfg!(feature = \"hey\") || cfg!(not(feature = \"asdf\")));\n    //~^ assertions_on_constants\n\n    let flag: bool = cfg!(not(feature = \"asdf\"));\n    assert!(flag);\n\n    const CFG_FLAG: &bool = &cfg!(feature = \"hey\");\n    assert!(!CFG_FLAG);\n\n    const _: () = assert!(true);\n    //~^ assertions_on_constants\n\n    assert!(8 == (7 + 1));\n    //~^ assertions_on_constants\n\n    // Don't lint if the value is dependent on a defined constant:\n    const N: usize = 1024;\n    const _: () = assert!(N.is_power_of_two());\n}\n\nconst C: bool = true;\n\nconst _: () = {\n    assert!(true);\n    //~^ assertions_on_constants\n\n    assert!(8 == (7 + 1));\n    //~^ assertions_on_constants\n\n    assert!(C);\n};\n\n#[clippy::msrv = \"1.57\"]\nfn _f1() {\n    assert!(C);\n    //~^ assertions_on_constants\n}\n\n#[clippy::msrv = \"1.56\"]\nfn _f2() {\n    assert!(C);\n}\n\n#[clippy::msrv = \"1.79\"]\nfn _f3() {\n    assert!(C);\n    //~^ assertions_on_constants\n}\n\n#[clippy::msrv = \"1.78\"]\nfn _f4() {\n    assert!(C);\n    //~^ assertions_on_constants\n}\n\nfn issue_16242(var: bool) {\n    // should not lint\n    assert!(cfg!(feature = \"hey\") && var);\n}\n"
  },
  {
    "path": "tests/ui/assertions_on_constants.stderr",
    "content": "error: this assertion is always `true`\n  --> tests/ui/assertions_on_constants.rs:10:5\n   |\nLL |     assert!(true);\n   |     ^^^^^^^^^^^^^\n   |\n   = help: remove the assertion\n   = note: `-D clippy::assertions-on-constants` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::assertions_on_constants)]`\n\nerror: this assertion is always `false`\n  --> tests/ui/assertions_on_constants.rs:13:5\n   |\nLL |     assert!(false);\n   |     ^^^^^^^^^^^^^^\n   |\n   = help: replace this with `panic!()` or `unreachable!()`\n\nerror: this assertion is always `true`\n  --> tests/ui/assertions_on_constants.rs:16:5\n   |\nLL |     assert!(true, \"true message\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the assertion\n\nerror: this assertion is always `false`\n  --> tests/ui/assertions_on_constants.rs:19:5\n   |\nLL |     assert!(false, \"false message\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: replace this with `panic!()` or `unreachable!()`\n\nerror: this assertion is always `false`\n  --> tests/ui/assertions_on_constants.rs:23:5\n   |\nLL |     assert!(false, \"{}\", msg.to_uppercase());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: replace this with `panic!()` or `unreachable!()`\n\nerror: this assertion has a constant value\n  --> tests/ui/assertions_on_constants.rs:27:5\n   |\nLL |     assert!(B);\n   |     ^^^^^^^^^^\n   |\n   = help: consider moving this into a const block: `const { assert!(..) }`\n\nerror: this assertion has a constant value\n  --> tests/ui/assertions_on_constants.rs:31:5\n   |\nLL |     assert!(C);\n   |     ^^^^^^^^^^\n   |\n   = help: consider moving this into a const block: `const { assert!(..) }`\n\nerror: this assertion has a constant value\n  --> tests/ui/assertions_on_constants.rs:34:5\n   |\nLL |     assert!(C, \"C message\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider moving this into a const block: `const { assert!(..) }`\n\nerror: this assertion is always `true`\n  --> tests/ui/assertions_on_constants.rs:37:5\n   |\nLL |     debug_assert!(true);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the assertion\n\nerror: this assertion has a constant value\n  --> tests/ui/assertions_on_constants.rs:45:5\n   |\nLL |     assert!(cfg!(feature = \"hey\") || cfg!(not(feature = \"asdf\")));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider moving this into a const block: `const { assert!(..) }`\n\nerror: this assertion is always `true`\n  --> tests/ui/assertions_on_constants.rs:54:19\n   |\nLL |     const _: () = assert!(true);\n   |                   ^^^^^^^^^^^^^\n   |\n   = help: remove the assertion\n\nerror: this assertion is always `true`\n  --> tests/ui/assertions_on_constants.rs:57:5\n   |\nLL |     assert!(8 == (7 + 1));\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the assertion\n\nerror: this assertion is always `true`\n  --> tests/ui/assertions_on_constants.rs:68:5\n   |\nLL |     assert!(true);\n   |     ^^^^^^^^^^^^^\n   |\n   = help: remove the assertion\n\nerror: this assertion is always `true`\n  --> tests/ui/assertions_on_constants.rs:71:5\n   |\nLL |     assert!(8 == (7 + 1));\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the assertion\n\nerror: this assertion has a constant value\n  --> tests/ui/assertions_on_constants.rs:79:5\n   |\nLL |     assert!(C);\n   |     ^^^^^^^^^^\n   |\n   = help: consider moving this to an anonymous constant: `const _: () = { assert!(..); }`\n\nerror: this assertion has a constant value\n  --> tests/ui/assertions_on_constants.rs:90:5\n   |\nLL |     assert!(C);\n   |     ^^^^^^^^^^\n   |\n   = help: consider moving this into a const block: `const { assert!(..) }`\n\nerror: this assertion has a constant value\n  --> tests/ui/assertions_on_constants.rs:96:5\n   |\nLL |     assert!(C);\n   |     ^^^^^^^^^^\n   |\n   = help: consider moving this to an anonymous constant: `const _: () = { assert!(..); }`\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/assertions_on_result_states.fixed",
    "content": "#![warn(clippy::assertions_on_result_states)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nuse std::result::Result;\n\nstruct Foo;\n\n#[derive(Debug)]\nstruct DebugFoo;\n\n#[derive(Copy, Clone, Debug)]\nstruct CopyFoo;\n\nmacro_rules! get_ok_macro {\n    () => {\n        Ok::<_, DebugFoo>(Foo)\n    };\n}\n\nfn main() {\n    // test ok\n    let r: Result<Foo, DebugFoo> = Ok(Foo);\n    debug_assert!(r.is_ok());\n    r.unwrap();\n    //~^ assertions_on_result_states\n\n    // test ok with non-debug error type\n    let r: Result<Foo, Foo> = Ok(Foo);\n    assert!(r.is_ok());\n\n    // test ok with some messages\n    let r: Result<Foo, DebugFoo> = Ok(Foo);\n    assert!(r.is_ok(), \"oops\");\n\n    // test ok with unit error\n    let r: Result<Foo, ()> = Ok(Foo);\n    assert!(r.is_ok());\n\n    // test temporary ok\n    fn get_ok() -> Result<Foo, DebugFoo> {\n        Ok(Foo)\n    }\n    get_ok().unwrap();\n    //~^ assertions_on_result_states\n\n    // test macro ok\n    get_ok_macro!().unwrap();\n    //~^ assertions_on_result_states\n\n    // test ok that shouldn't be moved\n    let r: Result<CopyFoo, DebugFoo> = Ok(CopyFoo);\n    fn test_ref_unmoveable_ok(r: &Result<CopyFoo, DebugFoo>) {\n        assert!(r.is_ok());\n    }\n    test_ref_unmoveable_ok(&r);\n    assert!(r.is_ok());\n    r.unwrap();\n\n    // test ok that is copied\n    let r: Result<CopyFoo, CopyFoo> = Ok(CopyFoo);\n    r.unwrap();\n    //~^ assertions_on_result_states\n    r.unwrap();\n\n    // test reference to ok\n    let r: Result<CopyFoo, CopyFoo> = Ok(CopyFoo);\n    fn test_ref_copy_ok(r: &Result<CopyFoo, CopyFoo>) {\n        r.unwrap();\n        //~^ assertions_on_result_states\n    }\n    test_ref_copy_ok(&r);\n    r.unwrap();\n\n    // test err\n    let r: Result<DebugFoo, Foo> = Err(Foo);\n    debug_assert!(r.is_err());\n    r.unwrap_err();\n    //~^ assertions_on_result_states\n\n    // test err with non-debug value type\n    let r: Result<Foo, Foo> = Err(Foo);\n    assert!(r.is_err());\n}\n\nfn issue9450() {\n    let res: Result<i32, i32> = Ok(1);\n    res.unwrap_err();\n    //~^ assertions_on_result_states\n}\n\nfn issue9916(res: Result<u32, u32>) {\n    let a = 0;\n    match a {\n        0 => {},\n        1 => { res.unwrap(); },\n        //~^ assertions_on_result_states\n        _ => todo!(),\n    }\n}\n"
  },
  {
    "path": "tests/ui/assertions_on_result_states.rs",
    "content": "#![warn(clippy::assertions_on_result_states)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nuse std::result::Result;\n\nstruct Foo;\n\n#[derive(Debug)]\nstruct DebugFoo;\n\n#[derive(Copy, Clone, Debug)]\nstruct CopyFoo;\n\nmacro_rules! get_ok_macro {\n    () => {\n        Ok::<_, DebugFoo>(Foo)\n    };\n}\n\nfn main() {\n    // test ok\n    let r: Result<Foo, DebugFoo> = Ok(Foo);\n    debug_assert!(r.is_ok());\n    assert!(r.is_ok());\n    //~^ assertions_on_result_states\n\n    // test ok with non-debug error type\n    let r: Result<Foo, Foo> = Ok(Foo);\n    assert!(r.is_ok());\n\n    // test ok with some messages\n    let r: Result<Foo, DebugFoo> = Ok(Foo);\n    assert!(r.is_ok(), \"oops\");\n\n    // test ok with unit error\n    let r: Result<Foo, ()> = Ok(Foo);\n    assert!(r.is_ok());\n\n    // test temporary ok\n    fn get_ok() -> Result<Foo, DebugFoo> {\n        Ok(Foo)\n    }\n    assert!(get_ok().is_ok());\n    //~^ assertions_on_result_states\n\n    // test macro ok\n    assert!(get_ok_macro!().is_ok());\n    //~^ assertions_on_result_states\n\n    // test ok that shouldn't be moved\n    let r: Result<CopyFoo, DebugFoo> = Ok(CopyFoo);\n    fn test_ref_unmoveable_ok(r: &Result<CopyFoo, DebugFoo>) {\n        assert!(r.is_ok());\n    }\n    test_ref_unmoveable_ok(&r);\n    assert!(r.is_ok());\n    r.unwrap();\n\n    // test ok that is copied\n    let r: Result<CopyFoo, CopyFoo> = Ok(CopyFoo);\n    assert!(r.is_ok());\n    //~^ assertions_on_result_states\n    r.unwrap();\n\n    // test reference to ok\n    let r: Result<CopyFoo, CopyFoo> = Ok(CopyFoo);\n    fn test_ref_copy_ok(r: &Result<CopyFoo, CopyFoo>) {\n        assert!(r.is_ok());\n        //~^ assertions_on_result_states\n    }\n    test_ref_copy_ok(&r);\n    r.unwrap();\n\n    // test err\n    let r: Result<DebugFoo, Foo> = Err(Foo);\n    debug_assert!(r.is_err());\n    assert!(r.is_err());\n    //~^ assertions_on_result_states\n\n    // test err with non-debug value type\n    let r: Result<Foo, Foo> = Err(Foo);\n    assert!(r.is_err());\n}\n\nfn issue9450() {\n    let res: Result<i32, i32> = Ok(1);\n    assert!(res.is_err())\n    //~^ assertions_on_result_states\n}\n\nfn issue9916(res: Result<u32, u32>) {\n    let a = 0;\n    match a {\n        0 => {},\n        1 => assert!(res.is_ok()),\n        //~^ assertions_on_result_states\n        _ => todo!(),\n    }\n}\n"
  },
  {
    "path": "tests/ui/assertions_on_result_states.stderr",
    "content": "error: called `assert!` with `Result::is_ok`\n  --> tests/ui/assertions_on_result_states.rs:24:5\n   |\nLL |     assert!(r.is_ok());\n   |     ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()`\n   |\n   = note: `-D clippy::assertions-on-result-states` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::assertions_on_result_states)]`\n\nerror: called `assert!` with `Result::is_ok`\n  --> tests/ui/assertions_on_result_states.rs:43:5\n   |\nLL |     assert!(get_ok().is_ok());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok().unwrap()`\n\nerror: called `assert!` with `Result::is_ok`\n  --> tests/ui/assertions_on_result_states.rs:47:5\n   |\nLL |     assert!(get_ok_macro!().is_ok());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get_ok_macro!().unwrap()`\n\nerror: called `assert!` with `Result::is_ok`\n  --> tests/ui/assertions_on_result_states.rs:61:5\n   |\nLL |     assert!(r.is_ok());\n   |     ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()`\n\nerror: called `assert!` with `Result::is_ok`\n  --> tests/ui/assertions_on_result_states.rs:68:9\n   |\nLL |         assert!(r.is_ok());\n   |         ^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap()`\n\nerror: called `assert!` with `Result::is_err`\n  --> tests/ui/assertions_on_result_states.rs:77:5\n   |\nLL |     assert!(r.is_err());\n   |     ^^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap_err()`\n\nerror: called `assert!` with `Result::is_err`\n  --> tests/ui/assertions_on_result_states.rs:87:5\n   |\nLL |     assert!(res.is_err())\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: replace with: `res.unwrap_err();`\n\nerror: called `assert!` with `Result::is_ok`\n  --> tests/ui/assertions_on_result_states.rs:95:14\n   |\nLL |         1 => assert!(res.is_ok()),\n   |              ^^^^^^^^^^^^^^^^^^^^ help: replace with: `{ res.unwrap(); }`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/assign_ops.fixed",
    "content": "#![allow(clippy::useless_vec)]\n#![warn(clippy::assign_op_pattern)]\n#![feature(const_ops)]\n#![feature(const_trait_impl)]\n\nuse std::num::Wrapping;\nuse std::ops::{Mul, MulAssign};\n\nfn main() {\n    let mut a = 5;\n    a += 1;\n    //~^ assign_op_pattern\n    a += 1;\n    //~^ assign_op_pattern\n    a -= 1;\n    //~^ assign_op_pattern\n    a *= 99;\n    //~^ assign_op_pattern\n    a *= 42;\n    //~^ assign_op_pattern\n    a /= 2;\n    //~^ assign_op_pattern\n    a %= 5;\n    //~^ assign_op_pattern\n    a &= 1;\n    //~^ assign_op_pattern\n    a = 1 - a;\n    a = 5 / a;\n    a = 42 % a;\n    a = 6 << a;\n    let mut s = String::new();\n    s += \"bla\";\n    //~^ assign_op_pattern\n\n    // Issue #9180\n    let mut a = Wrapping(0u32);\n    a += Wrapping(1u32);\n    //~^ assign_op_pattern\n    let mut v = vec![0u32, 1u32];\n    v[0] += v[1];\n    //~^ assign_op_pattern\n    let mut v = vec![Wrapping(0u32), Wrapping(1u32)];\n    v[0] = v[0] + v[1];\n    let _ = || v[0] = v[0] + v[1];\n}\n\nfn cow_add_assign() {\n    use std::borrow::Cow;\n    let mut buf = Cow::Owned(String::from(\"bar\"));\n    let cows = Cow::Borrowed(\"foo\");\n\n    // this can be linted\n    buf += cows.clone();\n    //~^ assign_op_pattern\n\n    // this should not as cow<str> Add is not commutative\n    buf = cows + buf;\n}\n\n// check that we don't lint on op assign impls, because that's just the way to impl them\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\npub struct Wrap(i64);\n\nimpl Mul<i64> for Wrap {\n    type Output = Self;\n\n    fn mul(self, rhs: i64) -> Self {\n        Wrap(self.0 * rhs)\n    }\n}\n\nimpl MulAssign<i64> for Wrap {\n    fn mul_assign(&mut self, rhs: i64) {\n        *self = *self * rhs\n    }\n}\n\nmod issue14871 {\n\n    use std::ops::{Add, AddAssign};\n\n    pub trait Number: Copy + Add<Self, Output = Self> + AddAssign {\n        const ZERO: Self;\n        const ONE: Self;\n\n        fn non_constant(value: usize) -> Self {\n            let mut res = Self::ZERO;\n            let mut count = 0;\n            while count < value {\n                res += Self::ONE;\n                //~^ assign_op_pattern\n                count += 1;\n                //~^ assign_op_pattern\n            }\n            res\n        }\n    }\n\n    #[rustfmt::skip] // rustfmt doesn't understand the order of pub const on traits (yet)\n    pub const trait NumberConstants {\n        fn constant(value: usize) -> Self;\n    }\n\n    impl<T> const NumberConstants for T\n    where\n        T: Number + [const] std::ops::Add,\n    {\n        fn constant(value: usize) -> Self {\n            let mut res = Self::ZERO;\n            let mut count = 0;\n            while count < value {\n                res = res + Self::ONE;\n                count += 1;\n                //~^ assign_op_pattern\n            }\n            res\n        }\n    }\n\n    pub struct S;\n\n    impl const std::ops::Add for S {\n        type Output = S;\n        fn add(self, _rhs: S) -> S {\n            S\n        }\n    }\n\n    impl const std::ops::AddAssign for S {\n        fn add_assign(&mut self, rhs: S) {}\n    }\n\n    const fn do_add() {\n        let mut s = S;\n        s += S;\n        //~^ assign_op_pattern\n    }\n}\n"
  },
  {
    "path": "tests/ui/assign_ops.rs",
    "content": "#![allow(clippy::useless_vec)]\n#![warn(clippy::assign_op_pattern)]\n#![feature(const_ops)]\n#![feature(const_trait_impl)]\n\nuse std::num::Wrapping;\nuse std::ops::{Mul, MulAssign};\n\nfn main() {\n    let mut a = 5;\n    a = a + 1;\n    //~^ assign_op_pattern\n    a = 1 + a;\n    //~^ assign_op_pattern\n    a = a - 1;\n    //~^ assign_op_pattern\n    a = a * 99;\n    //~^ assign_op_pattern\n    a = 42 * a;\n    //~^ assign_op_pattern\n    a = a / 2;\n    //~^ assign_op_pattern\n    a = a % 5;\n    //~^ assign_op_pattern\n    a = a & 1;\n    //~^ assign_op_pattern\n    a = 1 - a;\n    a = 5 / a;\n    a = 42 % a;\n    a = 6 << a;\n    let mut s = String::new();\n    s = s + \"bla\";\n    //~^ assign_op_pattern\n\n    // Issue #9180\n    let mut a = Wrapping(0u32);\n    a = a + Wrapping(1u32);\n    //~^ assign_op_pattern\n    let mut v = vec![0u32, 1u32];\n    v[0] = v[0] + v[1];\n    //~^ assign_op_pattern\n    let mut v = vec![Wrapping(0u32), Wrapping(1u32)];\n    v[0] = v[0] + v[1];\n    let _ = || v[0] = v[0] + v[1];\n}\n\nfn cow_add_assign() {\n    use std::borrow::Cow;\n    let mut buf = Cow::Owned(String::from(\"bar\"));\n    let cows = Cow::Borrowed(\"foo\");\n\n    // this can be linted\n    buf = buf + cows.clone();\n    //~^ assign_op_pattern\n\n    // this should not as cow<str> Add is not commutative\n    buf = cows + buf;\n}\n\n// check that we don't lint on op assign impls, because that's just the way to impl them\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\npub struct Wrap(i64);\n\nimpl Mul<i64> for Wrap {\n    type Output = Self;\n\n    fn mul(self, rhs: i64) -> Self {\n        Wrap(self.0 * rhs)\n    }\n}\n\nimpl MulAssign<i64> for Wrap {\n    fn mul_assign(&mut self, rhs: i64) {\n        *self = *self * rhs\n    }\n}\n\nmod issue14871 {\n\n    use std::ops::{Add, AddAssign};\n\n    pub trait Number: Copy + Add<Self, Output = Self> + AddAssign {\n        const ZERO: Self;\n        const ONE: Self;\n\n        fn non_constant(value: usize) -> Self {\n            let mut res = Self::ZERO;\n            let mut count = 0;\n            while count < value {\n                res = res + Self::ONE;\n                //~^ assign_op_pattern\n                count = count + 1;\n                //~^ assign_op_pattern\n            }\n            res\n        }\n    }\n\n    #[rustfmt::skip] // rustfmt doesn't understand the order of pub const on traits (yet)\n    pub const trait NumberConstants {\n        fn constant(value: usize) -> Self;\n    }\n\n    impl<T> const NumberConstants for T\n    where\n        T: Number + [const] std::ops::Add,\n    {\n        fn constant(value: usize) -> Self {\n            let mut res = Self::ZERO;\n            let mut count = 0;\n            while count < value {\n                res = res + Self::ONE;\n                count = count + 1;\n                //~^ assign_op_pattern\n            }\n            res\n        }\n    }\n\n    pub struct S;\n\n    impl const std::ops::Add for S {\n        type Output = S;\n        fn add(self, _rhs: S) -> S {\n            S\n        }\n    }\n\n    impl const std::ops::AddAssign for S {\n        fn add_assign(&mut self, rhs: S) {}\n    }\n\n    const fn do_add() {\n        let mut s = S;\n        s = s + S;\n        //~^ assign_op_pattern\n    }\n}\n"
  },
  {
    "path": "tests/ui/assign_ops.stderr",
    "content": "error: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:11:5\n   |\nLL |     a = a + 1;\n   |     ^^^^^^^^^ help: replace it with: `a += 1`\n   |\n   = note: `-D clippy::assign-op-pattern` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:13:5\n   |\nLL |     a = 1 + a;\n   |     ^^^^^^^^^ help: replace it with: `a += 1`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:15:5\n   |\nLL |     a = a - 1;\n   |     ^^^^^^^^^ help: replace it with: `a -= 1`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:17:5\n   |\nLL |     a = a * 99;\n   |     ^^^^^^^^^^ help: replace it with: `a *= 99`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:19:5\n   |\nLL |     a = 42 * a;\n   |     ^^^^^^^^^^ help: replace it with: `a *= 42`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:21:5\n   |\nLL |     a = a / 2;\n   |     ^^^^^^^^^ help: replace it with: `a /= 2`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:23:5\n   |\nLL |     a = a % 5;\n   |     ^^^^^^^^^ help: replace it with: `a %= 5`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:25:5\n   |\nLL |     a = a & 1;\n   |     ^^^^^^^^^ help: replace it with: `a &= 1`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:32:5\n   |\nLL |     s = s + \"bla\";\n   |     ^^^^^^^^^^^^^ help: replace it with: `s += \"bla\"`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:37:5\n   |\nLL |     a = a + Wrapping(1u32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a += Wrapping(1u32)`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:40:5\n   |\nLL |     v[0] = v[0] + v[1];\n   |     ^^^^^^^^^^^^^^^^^^ help: replace it with: `v[0] += v[1]`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:53:5\n   |\nLL |     buf = buf + cows.clone();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `buf += cows.clone()`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:91:17\n   |\nLL |                 res = res + Self::ONE;\n   |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `res += Self::ONE`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:93:17\n   |\nLL |                 count = count + 1;\n   |                 ^^^^^^^^^^^^^^^^^ help: replace it with: `count += 1`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:114:17\n   |\nLL |                 count = count + 1;\n   |                 ^^^^^^^^^^^^^^^^^ help: replace it with: `count += 1`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/assign_ops.rs:136:9\n   |\nLL |         s = s + S;\n   |         ^^^^^^^^^ help: replace it with: `s += S`\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/assigning_clones.fixed",
    "content": "#![allow(unused)]\n#![allow(clippy::redundant_clone)]\n#![allow(clippy::ptr_arg)] // https://github.com/rust-lang/rust-clippy/issues/10612\n#![allow(clippy::needless_late_init)]\n#![allow(clippy::box_collection)]\n#![allow(clippy::boxed_local)]\n#![warn(clippy::assigning_clones)]\n\nuse std::borrow::ToOwned;\nuse std::ops::{Add, Deref, DerefMut};\n\n// Clone\npub struct HasCloneFrom;\n\nimpl Clone for HasCloneFrom {\n    fn clone(&self) -> Self {\n        Self\n    }\n    fn clone_from(&mut self, source: &Self) {\n        *self = HasCloneFrom;\n    }\n}\n\nfn clone_method_rhs_val(mut_thing: &mut HasCloneFrom, value_thing: HasCloneFrom) {\n    mut_thing.clone_from(&value_thing);\n    //~^ assigning_clones\n}\n\nfn clone_method_rhs_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    mut_thing.clone_from(ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_method_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {\n    mut_thing.clone_from(ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_lhs_mut_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    Clone::clone_from(mut_thing, ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {\n    Clone::clone_from(&mut mut_thing, ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_through_trait(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    Clone::clone_from(mut_thing, ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_through_type(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    Clone::clone_from(mut_thing, ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_fully_qualified(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    Clone::clone_from(mut_thing, ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_method_lhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    // These parens should be kept as necessary for a receiver\n    (mut_thing + &mut HasCloneFrom).clone_from(ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_method_rhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    // These parens should be removed since they are not needed in a function argument\n    mut_thing.clone_from(ref_thing + ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_method_macro() {\n    let mut s = String::from(\"\");\n    s.clone_from(&format!(\"{} {}\", \"hello\", \"world\"));\n    //~^ assigning_clones\n}\n\nfn clone_function_macro() {\n    let mut s = String::from(\"\");\n    Clone::clone_from(&mut s, &format!(\"{} {}\", \"hello\", \"world\"));\n    //~^ assigning_clones\n}\n\nfn assign_to_init_mut_var(b: HasCloneFrom) -> HasCloneFrom {\n    let mut a = HasCloneFrom;\n    for _ in 1..10 {\n        a.clone_from(&b);\n        //~^ assigning_clones\n    }\n    a\n}\n\nfn assign_to_late_init_mut_var(b: HasCloneFrom) {\n    let mut a;\n    a = HasCloneFrom;\n    a = b.clone();\n}\n\nfn assign_to_uninit_var(b: HasCloneFrom) {\n    let a;\n    a = b.clone();\n}\n\nfn assign_to_uninit_mut_var(b: HasCloneFrom) {\n    let mut a;\n    a = b.clone();\n}\n\nfn late_init_let_tuple() {\n    let (p, q): (String, String);\n    p = \"ghi\".to_string();\n    q = p.clone();\n}\n\n#[derive(Clone)]\npub struct HasDeriveClone;\n\nfn ignore_derive_clone(a: &mut HasDeriveClone, b: &HasDeriveClone) {\n    // Should not be linted, since the Clone impl is derived\n    *a = b.clone();\n}\n\npub struct HasCloneImpl;\n\nimpl Clone for HasCloneImpl {\n    fn clone(&self) -> Self {\n        Self\n    }\n}\n\nfn ignore_missing_clone_from(a: &mut HasCloneImpl, b: &HasCloneImpl) {\n    // Should not be linted, since the Clone impl doesn't override clone_from\n    *a = b.clone();\n}\n\nstruct FakeClone;\n\nimpl FakeClone {\n    /// This looks just like `Clone::clone`\n    fn clone(&self) -> Self {\n        FakeClone\n    }\n}\n\nfn ignore_fake_clone() {\n    let mut a = FakeClone;\n    let b = FakeClone;\n    // Should not be linted, since the Clone impl doesn't come from std\n    a = b.clone();\n}\n\nfn ignore_generic_clone<T: Clone>(a: &mut T, b: &T) {\n    // Should not be linted, since we don't know the actual clone impl\n    *a = b.clone();\n}\n\n#[clippy::msrv = \"1.62\"]\nfn msrv_1_62(mut a: String, b: String, c: &str) {\n    a.clone_from(&b);\n    //~^ assigning_clones\n    // Should not be linted, as clone_into wasn't stabilized until 1.63\n    a = c.to_owned();\n}\n\n#[clippy::msrv = \"1.63\"]\nfn msrv_1_63(mut a: String, b: String, c: &str) {\n    a.clone_from(&b);\n    //~^ assigning_clones\n    c.clone_into(&mut a);\n    //~^ assigning_clones\n}\n\nmacro_rules! clone_inside {\n    ($a:expr, $b: expr) => {\n        $a = $b.clone();\n    };\n}\n\nfn clone_inside_macro() {\n    let mut a = String::new();\n    let b = String::new();\n    clone_inside!(a, b);\n}\n\n// Make sure that we don't suggest the lint when we call clone inside a Clone impl\n// https://github.com/rust-lang/rust-clippy/issues/12600\npub struct AvoidRecursiveCloneFrom;\n\nimpl Clone for AvoidRecursiveCloneFrom {\n    fn clone(&self) -> Self {\n        Self\n    }\n    fn clone_from(&mut self, source: &Self) {\n        *self = source.clone();\n    }\n}\n\n// Deref handling\nfn clone_into_deref_method(mut a: DerefWrapper<HasCloneFrom>, b: HasCloneFrom) {\n    (*a).clone_from(&b);\n    //~^ assigning_clones\n}\n\nfn clone_into_deref_with_clone_method(mut a: DerefWrapperWithClone<HasCloneFrom>, b: HasCloneFrom) {\n    (*a).clone_from(&b);\n    //~^ assigning_clones\n}\n\nfn clone_into_box_method(mut a: Box<HasCloneFrom>, b: HasCloneFrom) {\n    (*a).clone_from(&b);\n    //~^ assigning_clones\n}\n\nfn clone_into_self_deref_method(a: &mut DerefWrapperWithClone<HasCloneFrom>, b: DerefWrapperWithClone<HasCloneFrom>) {\n    a.clone_from(&b);\n    //~^ assigning_clones\n}\n\nfn clone_into_deref_function(mut a: DerefWrapper<HasCloneFrom>, b: HasCloneFrom) {\n    Clone::clone_from(&mut *a, &b);\n    //~^ assigning_clones\n}\n\nfn clone_into_box_function(mut a: Box<HasCloneFrom>, b: HasCloneFrom) {\n    Clone::clone_from(&mut *a, &b);\n    //~^ assigning_clones\n}\n\n// ToOwned\nfn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) {\n    ref_str.clone_into(mut_string);\n    //~^ assigning_clones\n}\n\nfn owned_method_val(mut mut_string: String, ref_str: &str) {\n    ref_str.clone_into(&mut mut_string);\n    //~^ assigning_clones\n}\n\nstruct HasDeref {\n    a: String,\n}\n\nimpl Deref for HasDeref {\n    type Target = String;\n    fn deref(&self) -> &Self::Target {\n        &self.a\n    }\n}\n\nimpl DerefMut for HasDeref {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.a\n    }\n}\n\nfn owned_method_box(mut_box_string: &mut Box<String>, ref_str: &str) {\n    ref_str.clone_into(&mut (*mut_box_string));\n    //~^ assigning_clones\n}\n\nfn owned_method_deref(mut_box_string: &mut HasDeref, ref_str: &str) {\n    ref_str.clone_into(&mut (*mut_box_string));\n    //~^ assigning_clones\n}\n\nfn owned_function_mut_ref(mut_thing: &mut String, ref_str: &str) {\n    ToOwned::clone_into(ref_str, mut_thing);\n    //~^ assigning_clones\n}\n\nfn owned_function_val(mut mut_thing: String, ref_str: &str) {\n    ToOwned::clone_into(ref_str, &mut mut_thing);\n    //~^ assigning_clones\n}\n\nfn owned_method_macro() {\n    let mut s = String::from(\"\");\n    format!(\"{} {}\", \"hello\", \"world\").clone_into(&mut s);\n    //~^ assigning_clones\n}\n\nfn owned_function_macro() {\n    let mut s = String::from(\"\");\n    ToOwned::clone_into(&format!(\"{} {}\", \"hello\", \"world\"), &mut s);\n    //~^ assigning_clones\n}\n\nstruct FakeToOwned;\nimpl FakeToOwned {\n    /// This looks just like `ToOwned::to_owned`\n    fn to_owned(&self) -> Self {\n        FakeToOwned\n    }\n}\n\nfn fake_to_owned() {\n    let mut a = FakeToOwned;\n    let b = FakeToOwned;\n    // Should not be linted, since the ToOwned impl doesn't come from std\n    a = b.to_owned();\n}\n\nfn main() {}\n\n/// Trait implementation to allow producing a `Thing` with a low-precedence expression.\nimpl Add for HasCloneFrom {\n    type Output = Self;\n    fn add(self, _: HasCloneFrom) -> Self {\n        self\n    }\n}\n/// Trait implementation to allow producing a `&Thing` with a low-precedence expression.\nimpl<'a> Add for &'a HasCloneFrom {\n    type Output = Self;\n    fn add(self, _: &'a HasCloneFrom) -> Self {\n        self\n    }\n}\n/// Trait implementation to allow producing a `&mut Thing` with a low-precedence expression.\nimpl<'a> Add for &'a mut HasCloneFrom {\n    type Output = Self;\n    fn add(self, _: &'a mut HasCloneFrom) -> Self {\n        self\n    }\n}\n\nmod borrowck_conflicts {\n    //! Cases where clone_into and friends cannot be used because the src/dest have conflicting\n    //! borrows.\n    use std::path::PathBuf;\n\n    fn issue12444(mut name: String) {\n        let parts = name.split(\", \").collect::<Vec<_>>();\n        let first = *parts.first().unwrap();\n        name = first.to_owned();\n    }\n\n    fn issue12444_simple() {\n        let mut s = String::new();\n        let s2 = &s;\n        s = s2.to_owned();\n    }\n\n    fn issue12444_nodrop_projections() {\n        struct NoDrop;\n\n        impl Clone for NoDrop {\n            fn clone(&self) -> Self {\n                todo!()\n            }\n            fn clone_from(&mut self, other: &Self) {\n                todo!()\n            }\n        }\n\n        let mut s = NoDrop;\n        let s2 = &s;\n        s = s2.clone();\n\n        let mut s = (NoDrop, NoDrop);\n        let s2 = &s.0;\n        s.0 = s2.clone();\n\n        // This *could* emit a warning, but PossibleBorrowerMap only works with locals so it\n        // considers `s` fully borrowed\n        let mut s = (NoDrop, NoDrop);\n        let s2 = &s.1;\n        s.0 = s2.clone();\n    }\n\n    fn issue12460(mut name: String) {\n        if let Some(stripped_name) = name.strip_prefix(\"baz-\") {\n            name = stripped_name.to_owned();\n        }\n    }\n\n    fn issue12749() {\n        let mut path = PathBuf::from(\"/a/b/c\");\n        path = path.components().as_path().to_owned();\n    }\n}\n\nstruct DerefWrapper<T>(T);\n\nimpl<T> Deref for DerefWrapper<T> {\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl<T> DerefMut for DerefWrapper<T> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\nstruct DerefWrapperWithClone<T>(T);\n\nimpl<T> Deref for DerefWrapperWithClone<T> {\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl<T> DerefMut for DerefWrapperWithClone<T> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\nimpl<T: Clone> Clone for DerefWrapperWithClone<T> {\n    fn clone(&self) -> Self {\n        Self(self.0.clone())\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        *self = Self(source.0.clone());\n    }\n}\n\n#[cfg(test)]\nmod test {\n    #[derive(Default)]\n    struct Data {\n        field: String,\n    }\n\n    fn test_data() -> Data {\n        Data {\n            field: \"default_value\".to_string(),\n        }\n    }\n\n    #[test]\n    fn test() {\n        let mut data = test_data();\n        data.field = \"override_value\".to_owned();\n    }\n}\n"
  },
  {
    "path": "tests/ui/assigning_clones.rs",
    "content": "#![allow(unused)]\n#![allow(clippy::redundant_clone)]\n#![allow(clippy::ptr_arg)] // https://github.com/rust-lang/rust-clippy/issues/10612\n#![allow(clippy::needless_late_init)]\n#![allow(clippy::box_collection)]\n#![allow(clippy::boxed_local)]\n#![warn(clippy::assigning_clones)]\n\nuse std::borrow::ToOwned;\nuse std::ops::{Add, Deref, DerefMut};\n\n// Clone\npub struct HasCloneFrom;\n\nimpl Clone for HasCloneFrom {\n    fn clone(&self) -> Self {\n        Self\n    }\n    fn clone_from(&mut self, source: &Self) {\n        *self = HasCloneFrom;\n    }\n}\n\nfn clone_method_rhs_val(mut_thing: &mut HasCloneFrom, value_thing: HasCloneFrom) {\n    *mut_thing = value_thing.clone();\n    //~^ assigning_clones\n}\n\nfn clone_method_rhs_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    *mut_thing = ref_thing.clone();\n    //~^ assigning_clones\n}\n\nfn clone_method_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {\n    mut_thing = ref_thing.clone();\n    //~^ assigning_clones\n}\n\nfn clone_function_lhs_mut_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    *mut_thing = Clone::clone(ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {\n    mut_thing = Clone::clone(ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_through_trait(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    *mut_thing = Clone::clone(ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_through_type(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    *mut_thing = HasCloneFrom::clone(ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_function_fully_qualified(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    *mut_thing = <HasCloneFrom as Clone>::clone(ref_thing);\n    //~^ assigning_clones\n}\n\nfn clone_method_lhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    // These parens should be kept as necessary for a receiver\n    *(mut_thing + &mut HasCloneFrom) = ref_thing.clone();\n    //~^ assigning_clones\n}\n\nfn clone_method_rhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {\n    // These parens should be removed since they are not needed in a function argument\n    *mut_thing = (ref_thing + ref_thing).clone();\n    //~^ assigning_clones\n}\n\nfn clone_method_macro() {\n    let mut s = String::from(\"\");\n    s = format!(\"{} {}\", \"hello\", \"world\").clone();\n    //~^ assigning_clones\n}\n\nfn clone_function_macro() {\n    let mut s = String::from(\"\");\n    s = Clone::clone(&format!(\"{} {}\", \"hello\", \"world\"));\n    //~^ assigning_clones\n}\n\nfn assign_to_init_mut_var(b: HasCloneFrom) -> HasCloneFrom {\n    let mut a = HasCloneFrom;\n    for _ in 1..10 {\n        a = b.clone();\n        //~^ assigning_clones\n    }\n    a\n}\n\nfn assign_to_late_init_mut_var(b: HasCloneFrom) {\n    let mut a;\n    a = HasCloneFrom;\n    a = b.clone();\n}\n\nfn assign_to_uninit_var(b: HasCloneFrom) {\n    let a;\n    a = b.clone();\n}\n\nfn assign_to_uninit_mut_var(b: HasCloneFrom) {\n    let mut a;\n    a = b.clone();\n}\n\nfn late_init_let_tuple() {\n    let (p, q): (String, String);\n    p = \"ghi\".to_string();\n    q = p.clone();\n}\n\n#[derive(Clone)]\npub struct HasDeriveClone;\n\nfn ignore_derive_clone(a: &mut HasDeriveClone, b: &HasDeriveClone) {\n    // Should not be linted, since the Clone impl is derived\n    *a = b.clone();\n}\n\npub struct HasCloneImpl;\n\nimpl Clone for HasCloneImpl {\n    fn clone(&self) -> Self {\n        Self\n    }\n}\n\nfn ignore_missing_clone_from(a: &mut HasCloneImpl, b: &HasCloneImpl) {\n    // Should not be linted, since the Clone impl doesn't override clone_from\n    *a = b.clone();\n}\n\nstruct FakeClone;\n\nimpl FakeClone {\n    /// This looks just like `Clone::clone`\n    fn clone(&self) -> Self {\n        FakeClone\n    }\n}\n\nfn ignore_fake_clone() {\n    let mut a = FakeClone;\n    let b = FakeClone;\n    // Should not be linted, since the Clone impl doesn't come from std\n    a = b.clone();\n}\n\nfn ignore_generic_clone<T: Clone>(a: &mut T, b: &T) {\n    // Should not be linted, since we don't know the actual clone impl\n    *a = b.clone();\n}\n\n#[clippy::msrv = \"1.62\"]\nfn msrv_1_62(mut a: String, b: String, c: &str) {\n    a = b.clone();\n    //~^ assigning_clones\n    // Should not be linted, as clone_into wasn't stabilized until 1.63\n    a = c.to_owned();\n}\n\n#[clippy::msrv = \"1.63\"]\nfn msrv_1_63(mut a: String, b: String, c: &str) {\n    a = b.clone();\n    //~^ assigning_clones\n    a = c.to_owned();\n    //~^ assigning_clones\n}\n\nmacro_rules! clone_inside {\n    ($a:expr, $b: expr) => {\n        $a = $b.clone();\n    };\n}\n\nfn clone_inside_macro() {\n    let mut a = String::new();\n    let b = String::new();\n    clone_inside!(a, b);\n}\n\n// Make sure that we don't suggest the lint when we call clone inside a Clone impl\n// https://github.com/rust-lang/rust-clippy/issues/12600\npub struct AvoidRecursiveCloneFrom;\n\nimpl Clone for AvoidRecursiveCloneFrom {\n    fn clone(&self) -> Self {\n        Self\n    }\n    fn clone_from(&mut self, source: &Self) {\n        *self = source.clone();\n    }\n}\n\n// Deref handling\nfn clone_into_deref_method(mut a: DerefWrapper<HasCloneFrom>, b: HasCloneFrom) {\n    *a = b.clone();\n    //~^ assigning_clones\n}\n\nfn clone_into_deref_with_clone_method(mut a: DerefWrapperWithClone<HasCloneFrom>, b: HasCloneFrom) {\n    *a = b.clone();\n    //~^ assigning_clones\n}\n\nfn clone_into_box_method(mut a: Box<HasCloneFrom>, b: HasCloneFrom) {\n    *a = b.clone();\n    //~^ assigning_clones\n}\n\nfn clone_into_self_deref_method(a: &mut DerefWrapperWithClone<HasCloneFrom>, b: DerefWrapperWithClone<HasCloneFrom>) {\n    *a = b.clone();\n    //~^ assigning_clones\n}\n\nfn clone_into_deref_function(mut a: DerefWrapper<HasCloneFrom>, b: HasCloneFrom) {\n    *a = Clone::clone(&b);\n    //~^ assigning_clones\n}\n\nfn clone_into_box_function(mut a: Box<HasCloneFrom>, b: HasCloneFrom) {\n    *a = Clone::clone(&b);\n    //~^ assigning_clones\n}\n\n// ToOwned\nfn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) {\n    *mut_string = ref_str.to_owned();\n    //~^ assigning_clones\n}\n\nfn owned_method_val(mut mut_string: String, ref_str: &str) {\n    mut_string = ref_str.to_owned();\n    //~^ assigning_clones\n}\n\nstruct HasDeref {\n    a: String,\n}\n\nimpl Deref for HasDeref {\n    type Target = String;\n    fn deref(&self) -> &Self::Target {\n        &self.a\n    }\n}\n\nimpl DerefMut for HasDeref {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.a\n    }\n}\n\nfn owned_method_box(mut_box_string: &mut Box<String>, ref_str: &str) {\n    **mut_box_string = ref_str.to_owned();\n    //~^ assigning_clones\n}\n\nfn owned_method_deref(mut_box_string: &mut HasDeref, ref_str: &str) {\n    **mut_box_string = ref_str.to_owned();\n    //~^ assigning_clones\n}\n\nfn owned_function_mut_ref(mut_thing: &mut String, ref_str: &str) {\n    *mut_thing = ToOwned::to_owned(ref_str);\n    //~^ assigning_clones\n}\n\nfn owned_function_val(mut mut_thing: String, ref_str: &str) {\n    mut_thing = ToOwned::to_owned(ref_str);\n    //~^ assigning_clones\n}\n\nfn owned_method_macro() {\n    let mut s = String::from(\"\");\n    s = format!(\"{} {}\", \"hello\", \"world\").to_owned();\n    //~^ assigning_clones\n}\n\nfn owned_function_macro() {\n    let mut s = String::from(\"\");\n    s = ToOwned::to_owned(&format!(\"{} {}\", \"hello\", \"world\"));\n    //~^ assigning_clones\n}\n\nstruct FakeToOwned;\nimpl FakeToOwned {\n    /// This looks just like `ToOwned::to_owned`\n    fn to_owned(&self) -> Self {\n        FakeToOwned\n    }\n}\n\nfn fake_to_owned() {\n    let mut a = FakeToOwned;\n    let b = FakeToOwned;\n    // Should not be linted, since the ToOwned impl doesn't come from std\n    a = b.to_owned();\n}\n\nfn main() {}\n\n/// Trait implementation to allow producing a `Thing` with a low-precedence expression.\nimpl Add for HasCloneFrom {\n    type Output = Self;\n    fn add(self, _: HasCloneFrom) -> Self {\n        self\n    }\n}\n/// Trait implementation to allow producing a `&Thing` with a low-precedence expression.\nimpl<'a> Add for &'a HasCloneFrom {\n    type Output = Self;\n    fn add(self, _: &'a HasCloneFrom) -> Self {\n        self\n    }\n}\n/// Trait implementation to allow producing a `&mut Thing` with a low-precedence expression.\nimpl<'a> Add for &'a mut HasCloneFrom {\n    type Output = Self;\n    fn add(self, _: &'a mut HasCloneFrom) -> Self {\n        self\n    }\n}\n\nmod borrowck_conflicts {\n    //! Cases where clone_into and friends cannot be used because the src/dest have conflicting\n    //! borrows.\n    use std::path::PathBuf;\n\n    fn issue12444(mut name: String) {\n        let parts = name.split(\", \").collect::<Vec<_>>();\n        let first = *parts.first().unwrap();\n        name = first.to_owned();\n    }\n\n    fn issue12444_simple() {\n        let mut s = String::new();\n        let s2 = &s;\n        s = s2.to_owned();\n    }\n\n    fn issue12444_nodrop_projections() {\n        struct NoDrop;\n\n        impl Clone for NoDrop {\n            fn clone(&self) -> Self {\n                todo!()\n            }\n            fn clone_from(&mut self, other: &Self) {\n                todo!()\n            }\n        }\n\n        let mut s = NoDrop;\n        let s2 = &s;\n        s = s2.clone();\n\n        let mut s = (NoDrop, NoDrop);\n        let s2 = &s.0;\n        s.0 = s2.clone();\n\n        // This *could* emit a warning, but PossibleBorrowerMap only works with locals so it\n        // considers `s` fully borrowed\n        let mut s = (NoDrop, NoDrop);\n        let s2 = &s.1;\n        s.0 = s2.clone();\n    }\n\n    fn issue12460(mut name: String) {\n        if let Some(stripped_name) = name.strip_prefix(\"baz-\") {\n            name = stripped_name.to_owned();\n        }\n    }\n\n    fn issue12749() {\n        let mut path = PathBuf::from(\"/a/b/c\");\n        path = path.components().as_path().to_owned();\n    }\n}\n\nstruct DerefWrapper<T>(T);\n\nimpl<T> Deref for DerefWrapper<T> {\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl<T> DerefMut for DerefWrapper<T> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\nstruct DerefWrapperWithClone<T>(T);\n\nimpl<T> Deref for DerefWrapperWithClone<T> {\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl<T> DerefMut for DerefWrapperWithClone<T> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\nimpl<T: Clone> Clone for DerefWrapperWithClone<T> {\n    fn clone(&self) -> Self {\n        Self(self.0.clone())\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        *self = Self(source.0.clone());\n    }\n}\n\n#[cfg(test)]\nmod test {\n    #[derive(Default)]\n    struct Data {\n        field: String,\n    }\n\n    fn test_data() -> Data {\n        Data {\n            field: \"default_value\".to_string(),\n        }\n    }\n\n    #[test]\n    fn test() {\n        let mut data = test_data();\n        data.field = \"override_value\".to_owned();\n    }\n}\n"
  },
  {
    "path": "tests/ui/assigning_clones.stderr",
    "content": "error: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:25:5\n   |\nLL |     *mut_thing = value_thing.clone();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(&value_thing)`\n   |\n   = note: `-D clippy::assigning-clones` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::assigning_clones)]`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:30:5\n   |\nLL |     *mut_thing = ref_thing.clone();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:35:5\n   |\nLL |     mut_thing = ref_thing.clone();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:40:5\n   |\nLL |     *mut_thing = Clone::clone(ref_thing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:45:5\n   |\nLL |     mut_thing = Clone::clone(ref_thing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut mut_thing, ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:50:5\n   |\nLL |     *mut_thing = Clone::clone(ref_thing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:55:5\n   |\nLL |     *mut_thing = HasCloneFrom::clone(ref_thing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:60:5\n   |\nLL |     *mut_thing = <HasCloneFrom as Clone>::clone(ref_thing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:66:5\n   |\nLL |     *(mut_thing + &mut HasCloneFrom) = ref_thing.clone();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `(mut_thing + &mut HasCloneFrom).clone_from(ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:72:5\n   |\nLL |     *mut_thing = (ref_thing + ref_thing).clone();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing + ref_thing)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:78:5\n   |\nLL |     s = format!(\"{} {}\", \"hello\", \"world\").clone();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `s.clone_from(&format!(\"{} {}\", \"hello\", \"world\"))`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:84:5\n   |\nLL |     s = Clone::clone(&format!(\"{} {}\", \"hello\", \"world\"));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut s, &format!(\"{} {}\", \"hello\", \"world\"))`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:91:9\n   |\nLL |         a = b.clone();\n   |         ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:163:5\n   |\nLL |     a = b.clone();\n   |     ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:171:5\n   |\nLL |     a = b.clone();\n   |     ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:173:5\n   |\nLL |     a = c.to_owned();\n   |     ^^^^^^^^^^^^^^^^ help: use `clone_into()`: `c.clone_into(&mut a)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:204:5\n   |\nLL |     *a = b.clone();\n   |     ^^^^^^^^^^^^^^ help: use `clone_from()`: `(*a).clone_from(&b)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:209:5\n   |\nLL |     *a = b.clone();\n   |     ^^^^^^^^^^^^^^ help: use `clone_from()`: `(*a).clone_from(&b)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:214:5\n   |\nLL |     *a = b.clone();\n   |     ^^^^^^^^^^^^^^ help: use `clone_from()`: `(*a).clone_from(&b)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:219:5\n   |\nLL |     *a = b.clone();\n   |     ^^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:224:5\n   |\nLL |     *a = Clone::clone(&b);\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut *a, &b)`\n\nerror: assigning the result of `Clone::clone()` may be inefficient\n  --> tests/ui/assigning_clones.rs:229:5\n   |\nLL |     *a = Clone::clone(&b);\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut *a, &b)`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:235:5\n   |\nLL |     *mut_string = ref_str.to_owned();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(mut_string)`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:240:5\n   |\nLL |     mut_string = ref_str.to_owned();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut mut_string)`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:262:5\n   |\nLL |     **mut_box_string = ref_str.to_owned();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:267:5\n   |\nLL |     **mut_box_string = ref_str.to_owned();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:272:5\n   |\nLL |     *mut_thing = ToOwned::to_owned(ref_str);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, mut_thing)`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:277:5\n   |\nLL |     mut_thing = ToOwned::to_owned(ref_str);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, &mut mut_thing)`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:283:5\n   |\nLL |     s = format!(\"{} {}\", \"hello\", \"world\").to_owned();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `format!(\"{} {}\", \"hello\", \"world\").clone_into(&mut s)`\n\nerror: assigning the result of `ToOwned::to_owned()` may be inefficient\n  --> tests/ui/assigning_clones.rs:289:5\n   |\nLL |     s = ToOwned::to_owned(&format!(\"{} {}\", \"hello\", \"world\"));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(&format!(\"{} {}\", \"hello\", \"world\"), &mut s)`\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/async_yields_async.fixed",
    "content": "#![warn(clippy::async_yields_async)]\n#![allow(clippy::redundant_async_block)]\n\nuse core::future::Future;\nuse core::pin::Pin;\nuse core::task::{Context, Poll};\n\nstruct CustomFutureType;\n\nimpl Future for CustomFutureType {\n    type Output = u8;\n\n    fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {\n        Poll::Ready(3)\n    }\n}\n\nfn custom_future_type_ctor() -> CustomFutureType {\n    CustomFutureType\n}\n\nasync fn f() -> CustomFutureType {\n    // Don't warn for functions since you have to explicitly declare their\n    // return types.\n    CustomFutureType\n}\n\n#[rustfmt::skip]\nfn main() {\n    let _f = {\n        3\n    };\n    let _g = async {\n        3\n    };\n    let _h = async {\n        async {\n            3\n        }.await\n    };\n    //~^^^^ async_yields_async\n    let _i = async {\n        CustomFutureType.await\n    };\n    //~^^ async_yields_async\n    let _i = async || {\n        3\n    };\n    let _j = async || {\n        async {\n            3\n        }.await\n    };\n    //~^^^^ async_yields_async\n    let _k = async || {\n        CustomFutureType.await\n    };\n    //~^^ async_yields_async\n    let _l = async || CustomFutureType.await;\n    //~^ async_yields_async\n    let _m = async || {\n        println!(\"I'm bored\");\n        // Some more stuff\n\n        // Finally something to await\n        CustomFutureType.await\n    };\n    //~^^ async_yields_async\n    let _n = async || custom_future_type_ctor();\n    let _o = async || f();\n}\n\n#[rustfmt::skip]\n#[allow(dead_code)]\nfn check_expect_suppression() {\n    #[expect(clippy::async_yields_async)]\n    let _j = async || {\n        async {\n            3\n        }\n    };\n}\n\n#[allow(clippy::let_underscore_future)]\nfn issue15552() {\n    async fn bar(i: i32) {}\n\n    macro_rules! call_bar {\n        () => {\n            async { bar(5).await }\n        };\n        ($e:expr) => {\n            bar($e)\n        };\n    }\n    let x = async { call_bar!(5).await };\n    //~^ async_yields_async\n    let y = async { call_bar!().await };\n    //~^ async_yields_async\n    //~| async_yields_async\n\n    use std::future::{Future, Ready};\n    use std::ops::Add;\n    use std::pin::Pin;\n    use std::task::{Context, Poll};\n    struct CustomFutureType;\n    impl Add for CustomFutureType {\n        type Output = Self;\n        fn add(self, other: Self) -> Self {\n            self\n        }\n    }\n    impl Future for CustomFutureType {\n        type Output = ();\n        fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {\n            Poll::Ready(())\n        }\n    }\n    let _ = async { (CustomFutureType + CustomFutureType).await };\n    //~^ async_yields_async\n}\n"
  },
  {
    "path": "tests/ui/async_yields_async.rs",
    "content": "#![warn(clippy::async_yields_async)]\n#![allow(clippy::redundant_async_block)]\n\nuse core::future::Future;\nuse core::pin::Pin;\nuse core::task::{Context, Poll};\n\nstruct CustomFutureType;\n\nimpl Future for CustomFutureType {\n    type Output = u8;\n\n    fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {\n        Poll::Ready(3)\n    }\n}\n\nfn custom_future_type_ctor() -> CustomFutureType {\n    CustomFutureType\n}\n\nasync fn f() -> CustomFutureType {\n    // Don't warn for functions since you have to explicitly declare their\n    // return types.\n    CustomFutureType\n}\n\n#[rustfmt::skip]\nfn main() {\n    let _f = {\n        3\n    };\n    let _g = async {\n        3\n    };\n    let _h = async {\n        async {\n            3\n        }\n    };\n    //~^^^^ async_yields_async\n    let _i = async {\n        CustomFutureType\n    };\n    //~^^ async_yields_async\n    let _i = async || {\n        3\n    };\n    let _j = async || {\n        async {\n            3\n        }\n    };\n    //~^^^^ async_yields_async\n    let _k = async || {\n        CustomFutureType\n    };\n    //~^^ async_yields_async\n    let _l = async || CustomFutureType;\n    //~^ async_yields_async\n    let _m = async || {\n        println!(\"I'm bored\");\n        // Some more stuff\n\n        // Finally something to await\n        CustomFutureType\n    };\n    //~^^ async_yields_async\n    let _n = async || custom_future_type_ctor();\n    let _o = async || f();\n}\n\n#[rustfmt::skip]\n#[allow(dead_code)]\nfn check_expect_suppression() {\n    #[expect(clippy::async_yields_async)]\n    let _j = async || {\n        async {\n            3\n        }\n    };\n}\n\n#[allow(clippy::let_underscore_future)]\nfn issue15552() {\n    async fn bar(i: i32) {}\n\n    macro_rules! call_bar {\n        () => {\n            async { bar(5) }\n        };\n        ($e:expr) => {\n            bar($e)\n        };\n    }\n    let x = async { call_bar!(5) };\n    //~^ async_yields_async\n    let y = async { call_bar!() };\n    //~^ async_yields_async\n    //~| async_yields_async\n\n    use std::future::{Future, Ready};\n    use std::ops::Add;\n    use std::pin::Pin;\n    use std::task::{Context, Poll};\n    struct CustomFutureType;\n    impl Add for CustomFutureType {\n        type Output = Self;\n        fn add(self, other: Self) -> Self {\n            self\n        }\n    }\n    impl Future for CustomFutureType {\n        type Output = ();\n        fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {\n            Poll::Ready(())\n        }\n    }\n    let _ = async { CustomFutureType + CustomFutureType };\n    //~^ async_yields_async\n}\n"
  },
  {
    "path": "tests/ui/async_yields_async.stderr",
    "content": "error: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:37:9\n   |\nLL |        let _h = async {\n   |  _____________________-\nLL | |/         async {\nLL | ||             3\nLL | ||         }\n   | ||_________^ awaitable value not awaited\nLL | |      };\n   | |______- outer async construct\n   |\n   = note: `-D clippy::async-yields-async` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::async_yields_async)]`\nhelp: consider awaiting this value\n   |\nLL |         async {\nLL |             3\nLL ~         }.await\n   |\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:43:9\n   |\nLL |       let _i = async {\n   |  ____________________-\nLL | |         CustomFutureType\n   | |         ^^^^^^^^^^^^^^^^\n   | |         |\n   | |         awaitable value not awaited\n   | |         help: consider awaiting this value: `CustomFutureType.await`\nLL | |     };\n   | |_____- outer async construct\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:50:9\n   |\nLL |        let _j = async || {\n   |  ________________________-\nLL | |/         async {\nLL | ||             3\nLL | ||         }\n   | ||_________^ awaitable value not awaited\nLL | |      };\n   | |______- outer async construct\n   |\nhelp: consider awaiting this value\n   |\nLL |         async {\nLL |             3\nLL ~         }.await\n   |\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:56:9\n   |\nLL |       let _k = async || {\n   |  _______________________-\nLL | |         CustomFutureType\n   | |         ^^^^^^^^^^^^^^^^\n   | |         |\n   | |         awaitable value not awaited\n   | |         help: consider awaiting this value: `CustomFutureType.await`\nLL | |     };\n   | |_____- outer async construct\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:59:23\n   |\nLL |     let _l = async || CustomFutureType;\n   |                       ^^^^^^^^^^^^^^^^\n   |                       |\n   |                       outer async construct\n   |                       awaitable value not awaited\n   |                       help: consider awaiting this value: `CustomFutureType.await`\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:66:9\n   |\nLL |       let _m = async || {\n   |  _______________________-\nLL | |         println!(\"I'm bored\");\n...  |\nLL | |         CustomFutureType\n   | |         ^^^^^^^^^^^^^^^^\n   | |         |\n   | |         awaitable value not awaited\n   | |         help: consider awaiting this value: `CustomFutureType.await`\nLL | |     };\n   | |_____- outer async construct\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:96:21\n   |\nLL |     let x = async { call_bar!(5) };\n   |                   --^^^^^^^^^^^^--\n   |                   | |\n   |                   | awaitable value not awaited\n   |                   | help: consider awaiting this value: `call_bar!(5).await`\n   |                   outer async construct\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:98:21\n   |\nLL |     let y = async { call_bar!() };\n   |                   --^^^^^^^^^^^--\n   |                   | |\n   |                   | awaitable value not awaited\n   |                   | help: consider awaiting this value: `call_bar!().await`\n   |                   outer async construct\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:90:21\n   |\nLL |             async { bar(5) }\n   |                   --^^^^^^--\n   |                   | |\n   |                   | awaitable value not awaited\n   |                   | help: consider awaiting this value: `bar(5).await`\n   |                   outer async construct\n...\nLL |     let y = async { call_bar!() };\n   |                     ----------- in this macro invocation\n   |\n   = note: this error originates in the macro `call_bar` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: an async construct yields a type which is itself awaitable\n  --> tests/ui/async_yields_async.rs:119:21\n   |\nLL |     let _ = async { CustomFutureType + CustomFutureType };\n   |                   --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--\n   |                   | |\n   |                   | awaitable value not awaited\n   |                   | help: consider awaiting this value: `(CustomFutureType + CustomFutureType).await`\n   |                   outer async construct\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/attrs.rs",
    "content": "#![warn(clippy::inline_always, clippy::deprecated_semver)]\n#![allow(clippy::assertions_on_constants)]\n#![allow(clippy::missing_docs_in_private_items, clippy::panic, clippy::unreachable)]\n\n#[inline(always)]\n//~^ inline_always\nfn test_attr_lint() {\n    assert!(true)\n}\n\n#[inline(always)]\nfn false_positive_expr() {\n    unreachable!()\n}\n\n#[inline(always)]\nfn false_positive_stmt() {\n    unreachable!();\n}\n\n#[inline(always)]\nfn empty_and_false_positive_stmt() {\n    unreachable!();\n}\n\n#[deprecated(since = \"forever\")]\n//~^ deprecated_semver\npub const SOME_CONST: u8 = 42;\n\n#[deprecated(since = \"1\")]\n//~^ deprecated_semver\npub const ANOTHER_CONST: u8 = 23;\n\n#[deprecated(since = \"0.1.1\")]\npub const YET_ANOTHER_CONST: u8 = 0;\n\n#[deprecated(since = \"TBD\")]\npub const GONNA_DEPRECATE_THIS_LATER: u8 = 0;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/attrs.stderr",
    "content": "error: the since field must contain a semver-compliant version\n  --> tests/ui/attrs.rs:26:14\n   |\nLL | #[deprecated(since = \"forever\")]\n   |              ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::deprecated-semver` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::deprecated_semver)]`\n\nerror: the since field must contain a semver-compliant version\n  --> tests/ui/attrs.rs:30:14\n   |\nLL | #[deprecated(since = \"1\")]\n   |              ^^^^^^^^^^^\n\nerror: you have declared `#[inline(always)]` on `test_attr_lint`. This is usually a bad idea\n  --> tests/ui/attrs.rs:5:1\n   |\nLL | #[inline(always)]\n   | ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::inline-always` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inline_always)]`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/author/blocks.rs",
    "content": "//@ check-pass\n//@edition:2018\n\n#![allow(redundant_semicolons, clippy::no_effect)]\n#![feature(stmt_expr_attributes)]\n\n#[rustfmt::skip]\nfn main() {\n    #[clippy::author]\n    {\n        let x = 42i32;\n        let _t = 1f32;\n\n        -x;\n    };\n    #[clippy::author]\n    {\n        let expr = String::new();\n        drop(expr)\n    };\n\n    #[clippy::author]\n    async move || {};\n}\n"
  },
  {
    "path": "tests/ui/author/blocks.stdout",
    "content": "if let ExprKind::Block(block, None) = expr.kind\n    && block.stmts.len() == 3\n    && let StmtKind::Let(local) = block.stmts[0].kind\n    && let Some(init) = local.init\n    && let ExprKind::Lit(ref lit) = init.kind\n    && let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node\n    && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind\n    && name.as_str() == \"x\"\n    && let StmtKind::Let(local1) = block.stmts[1].kind\n    && let Some(init1) = local1.init\n    && let ExprKind::Lit(ref lit1) = init1.kind\n    && let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node\n    && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local1.pat.kind\n    && name1.as_str() == \"_t\"\n    && let StmtKind::Semi(e) = block.stmts[2].kind\n    && let ExprKind::Unary(UnOp::Neg, inner) = e.kind\n    && block.expr.is_none()\n{\n    // report your lint here\n}\nif let ExprKind::Block(block, None) = expr.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Let(local) = block.stmts[0].kind\n    && let Some(init) = local.init\n    && let ExprKind::Call(func, args) = init.kind\n    && func.res(cx).is_diag_item(cx, sym::string_new)\n    && args.is_empty()\n    && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind\n    && name.as_str() == \"expr\"\n    && let Some(trailing_expr) = block.expr\n    && let ExprKind::Call(func1, args1) = trailing_expr.kind\n    && func1.res(cx).is_diag_item(cx, sym::mem_drop)\n    && args1.len() == 1\n{\n    // report your lint here\n}\nif let ExprKind::Closure { capture_clause: CaptureBy::Value { .. }, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::CoroutineClosure(CoroutineDesugaring::Async), .. } = expr.kind\n    && let FnRetTy::DefaultReturn(_) = fn_decl.output\n    && expr1 = &cx.tcx.hir_body(body_id).value\n    && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl1, body: body_id1, closure_kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)), .. } = expr1.kind\n    && let FnRetTy::DefaultReturn(_) = fn_decl1.output\n    && expr2 = &cx.tcx.hir_body(body_id1).value\n    && let ExprKind::Block(block, None) = expr2.kind\n    && block.stmts.is_empty()\n    && let Some(trailing_expr) = block.expr\n    && let ExprKind::DropTemps(expr3) = trailing_expr.kind\n    && let ExprKind::Block(block1, None) = expr3.kind\n    && block1.stmts.is_empty()\n    && block1.expr.is_none()\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/call.rs",
    "content": "//@ check-pass\n\nfn main() {\n    #[clippy::author]\n    let _ = ::std::cmp::min(3, 4);\n}\n"
  },
  {
    "path": "tests/ui/author/call.stdout",
    "content": "if let StmtKind::Let(local) = stmt.kind\n    && let Some(init) = local.init\n    && let ExprKind::Call(func, args) = init.kind\n    && func.res(cx).is_diag_item(cx, sym::cmp_min)\n    && args.len() == 2\n    && let ExprKind::Lit(ref lit) = args[0].kind\n    && let LitKind::Int(3, LitIntType::Unsuffixed) = lit.node\n    && let ExprKind::Lit(ref lit1) = args[1].kind\n    && let LitKind::Int(4, LitIntType::Unsuffixed) = lit1.node\n    && let PatKind::Wild = local.pat.kind\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/if.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::all)]\n\nfn main() {\n    #[clippy::author]\n    let _ = if true {\n        1 == 1;\n    } else {\n        2 == 2;\n    };\n\n    let a = true;\n\n    #[clippy::author]\n    if let true = a {\n    } else {\n    };\n}\n"
  },
  {
    "path": "tests/ui/author/if.stdout",
    "content": "if let StmtKind::Let(local) = stmt.kind\n    && let Some(init) = local.init\n    && let ExprKind::If(cond, then, Some(else_expr)) = init.kind\n    && let ExprKind::Lit(ref lit) = cond.kind\n    && let LitKind::Bool(true) = lit.node\n    && let ExprKind::Block(block, None) = then.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Semi(e) = block.stmts[0].kind\n    && let ExprKind::Binary(op, left, right) = e.kind\n    && BinOpKind::Eq == op.node\n    && let ExprKind::Lit(ref lit1) = left.kind\n    && let LitKind::Int(1, LitIntType::Unsuffixed) = lit1.node\n    && let ExprKind::Lit(ref lit2) = right.kind\n    && let LitKind::Int(1, LitIntType::Unsuffixed) = lit2.node\n    && block.expr.is_none()\n    && let ExprKind::Block(block1, None) = else_expr.kind\n    && block1.stmts.len() == 1\n    && let StmtKind::Semi(e1) = block1.stmts[0].kind\n    && let ExprKind::Binary(op1, left1, right1) = e1.kind\n    && BinOpKind::Eq == op1.node\n    && let ExprKind::Lit(ref lit3) = left1.kind\n    && let LitKind::Int(2, LitIntType::Unsuffixed) = lit3.node\n    && let ExprKind::Lit(ref lit4) = right1.kind\n    && let LitKind::Int(2, LitIntType::Unsuffixed) = lit4.node\n    && block1.expr.is_none()\n    && let PatKind::Wild = local.pat.kind\n{\n    // report your lint here\n}\nif let ExprKind::If(cond, then, Some(else_expr)) = expr.kind\n    && let ExprKind::Let(let_expr) = cond.kind\n    && let PatKind::Expr(lit_expr) = let_expr.pat.kind\n    && let PatExprKind::Lit { ref lit, negated } = lit_expr.kind\n    && let LitKind::Bool(true) = lit.node\n    && let ExprKind::Block(block, None) = then.kind\n    && block.stmts.is_empty()\n    && block.expr.is_none()\n    && let ExprKind::Block(block1, None) = else_expr.kind\n    && block1.stmts.is_empty()\n    && block1.expr.is_none()\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/issue_3849.rs",
    "content": "//@ check-pass\n\n#![allow(dead_code)]\n#![allow(clippy::zero_ptr)]\n#![allow(clippy::transmute_ptr_to_ref)]\n#![allow(clippy::transmuting_null, clippy::missing_transmute_annotations)]\n\npub const ZPTR: *const usize = 0 as *const _;\n\nfn main() {\n    unsafe {\n        #[clippy::author]\n        let _: &i32 = std::mem::transmute(ZPTR);\n        let _: &i32 = std::mem::transmute(0 as *const i32);\n    }\n}\n"
  },
  {
    "path": "tests/ui/author/issue_3849.stdout",
    "content": "if let StmtKind::Let(local) = stmt.kind\n    && let Some(init) = local.init\n    && let ExprKind::Call(func, args) = init.kind\n    && func.res(cx).is_diag_item(cx, sym::transmute)\n    && args.len() == 1\n    && let PatKind::Wild = local.pat.kind\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/loop.rs",
    "content": "//@ check-pass\n\n#![feature(stmt_expr_attributes)]\n#![allow(\n    clippy::never_loop,\n    clippy::while_immutable_condition,\n    clippy::redundant_pattern_matching\n)]\n\nfn main() {\n    #[clippy::author]\n    for y in 0..10 {\n        let z = y;\n    }\n\n    #[clippy::author]\n    for _ in 0..10 {\n        break;\n    }\n\n    #[clippy::author]\n    'label: for _ in 0..10 {\n        break 'label;\n    }\n\n    let a = true;\n\n    #[clippy::author]\n    while a {\n        break;\n    }\n\n    #[clippy::author]\n    while let true = a {\n        break;\n    }\n\n    #[clippy::author]\n    loop {\n        break;\n    }\n}\n"
  },
  {
    "path": "tests/ui/author/loop.stdout",
    "content": "if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr)\n    && let PatKind::Binding(BindingMode::NONE, _, name, None) = pat.kind\n    && name.as_str() == \"y\"\n    && let ExprKind::Struct(qpath, fields, None) = arg.kind\n    && let Some(def_id) = cx.qpath_res(qpath, arg.hir_id).opt_def_id()\n    && paths::CORE_OPS_RANGE_RANGE.matches(cx, def_id) // Add the path to `clippy_utils::paths` if needed\n    && fields.len() == 2\n    && fields[0].ident.as_str() == \"start\"\n    && let ExprKind::Lit(ref lit) = fields[0].expr.kind\n    && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node\n    && fields[1].ident.as_str() == \"end\"\n    && let ExprKind::Lit(ref lit1) = fields[1].expr.kind\n    && let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node\n    && let ExprKind::Block(block, None) = body.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Let(local) = block.stmts[0].kind\n    && let Some(init) = local.init\n    && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind\n    && name1.as_str() == \"z\"\n    && block.expr.is_none()\n{\n    // report your lint here\n}\nif let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr)\n    && let PatKind::Wild = pat.kind\n    && let ExprKind::Struct(qpath, fields, None) = arg.kind\n    && let Some(def_id) = cx.qpath_res(qpath, arg.hir_id).opt_def_id()\n    && paths::CORE_OPS_RANGE_RANGE.matches(cx, def_id) // Add the path to `clippy_utils::paths` if needed\n    && fields.len() == 2\n    && fields[0].ident.as_str() == \"start\"\n    && let ExprKind::Lit(ref lit) = fields[0].expr.kind\n    && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node\n    && fields[1].ident.as_str() == \"end\"\n    && let ExprKind::Lit(ref lit1) = fields[1].expr.kind\n    && let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node\n    && let ExprKind::Block(block, None) = body.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Semi(e) = block.stmts[0].kind\n    && let ExprKind::Break(destination, None) = e.kind\n    && destination.label.is_none()\n    && block.expr.is_none()\n{\n    // report your lint here\n}\nif let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr)\n    && let PatKind::Wild = pat.kind\n    && let ExprKind::Struct(qpath, fields, None) = arg.kind\n    && let Some(def_id) = cx.qpath_res(qpath, arg.hir_id).opt_def_id()\n    && paths::CORE_OPS_RANGE_RANGE.matches(cx, def_id) // Add the path to `clippy_utils::paths` if needed\n    && fields.len() == 2\n    && fields[0].ident.as_str() == \"start\"\n    && let ExprKind::Lit(ref lit) = fields[0].expr.kind\n    && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node\n    && fields[1].ident.as_str() == \"end\"\n    && let ExprKind::Lit(ref lit1) = fields[1].expr.kind\n    && let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node\n    && let ExprKind::Block(block, None) = body.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Semi(e) = block.stmts[0].kind\n    && let ExprKind::Break(destination, None) = e.kind\n    && let Some(label) = destination.label\n    && label.ident.as_str() == \"'label\"\n    && block.expr.is_none()\n{\n    // report your lint here\n}\nif let Some(higher::While { condition: condition, body: body }) = higher::While::hir(expr)\n    && let ExprKind::Block(block, None) = body.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Semi(e) = block.stmts[0].kind\n    && let ExprKind::Break(destination, None) = e.kind\n    && destination.label.is_none()\n    && block.expr.is_none()\n{\n    // report your lint here\n}\nif let Some(higher::WhileLet { let_pat: let_pat, let_expr: let_expr, if_then: if_then }) = higher::WhileLet::hir(expr)\n    && let PatKind::Expr(lit_expr) = let_pat.kind\n    && let PatExprKind::Lit { ref lit, negated } = lit_expr.kind\n    && let LitKind::Bool(true) = lit.node\n    && let ExprKind::Block(block, None) = if_then.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Semi(e) = block.stmts[0].kind\n    && let ExprKind::Break(destination, None) = e.kind\n    && destination.label.is_none()\n    && block.expr.is_none()\n{\n    // report your lint here\n}\nif let ExprKind::Loop(body, None, LoopSource::Loop, _) = expr.kind\n    && body.stmts.len() == 1\n    && let StmtKind::Semi(e) = body.stmts[0].kind\n    && let ExprKind::Break(destination, None) = e.kind\n    && destination.label.is_none()\n    && body.expr.is_none()\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/macro_in_closure.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::uninlined_format_args)]\n\nfn main() {\n    #[clippy::author]\n    let print_text = |x| println!(\"{}\", x);\n    print_text(\"hello\");\n}\n"
  },
  {
    "path": "tests/ui/author/macro_in_closure.stdout",
    "content": "if let StmtKind::Let(local) = stmt.kind\n    && let Some(init) = local.init\n    && let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = init.kind\n    && let FnRetTy::DefaultReturn(_) = fn_decl.output\n    && expr = &cx.tcx.hir_body(body_id).value\n    && let ExprKind::Block(block, None) = expr.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Semi(e) = block.stmts[0].kind\n    && let ExprKind::Call(func, args) = e.kind\n    && paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed\n    && args.len() == 1\n    && let ExprKind::Block(block1, None) = args[0].kind\n    && block1.stmts.len() == 2\n    && let StmtKind::Let(local1) = block1.stmts[0].kind\n    && let Some(init1) = local1.init\n    && let ExprKind::Tup(elements) = init1.kind\n    && elements.len() == 1\n    && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = elements[0].kind\n    && let PatKind::Binding(BindingMode::NONE, _, name, None) = local1.pat.kind\n    && name.as_str() == \"args\"\n    && let StmtKind::Let(local2) = block1.stmts[1].kind\n    && let Some(init2) = local2.init\n    && let ExprKind::Array(elements1) = init2.kind\n    && elements1.len() == 1\n    && let ExprKind::Call(func1, args1) = elements1[0].kind\n    && paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed\n    && args1.len() == 1\n    && let ExprKind::Field(object, field_name) = args1[0].kind\n    && field_name.as_str() == \"0\"\n    && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local2.pat.kind\n    && name1.as_str() == \"args\"\n    && let Some(trailing_expr) = block1.expr\n    && let ExprKind::Block(block2, None) = trailing_expr.kind\n    && block2.stmts.is_empty()\n    && let Some(trailing_expr1) = block2.expr\n    && let ExprKind::Call(func2, args2) = trailing_expr1.kind\n    && paths::CORE_FMT_ARGUMENTS_NEW.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed\n    && args2.len() == 2\n    && let ExprKind::Lit(ref lit) = args2[0].kind\n    && let LitKind::ByteStr(ref vec) = lit.node\n    && let [[192, 1, 10, 0]] = **vec\n    && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[1].kind\n    && block.expr.is_none()\n    && let PatKind::Binding(BindingMode::NONE, _, name2, None) = local.pat.kind\n    && name2.as_str() == \"print_text\"\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/macro_in_loop.rs",
    "content": "//@ check-pass\n\n#![feature(stmt_expr_attributes)]\n#![allow(clippy::uninlined_format_args)]\n\nfn main() {\n    #[clippy::author]\n    for i in 0..1 {\n        println!(\"{}\", i);\n    }\n}\n"
  },
  {
    "path": "tests/ui/author/macro_in_loop.stdout",
    "content": "if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::ForLoop::hir(expr)\n    && let PatKind::Binding(BindingMode::NONE, _, name, None) = pat.kind\n    && name.as_str() == \"i\"\n    && let ExprKind::Struct(qpath, fields, None) = arg.kind\n    && let Some(def_id) = cx.qpath_res(qpath, arg.hir_id).opt_def_id()\n    && paths::CORE_OPS_RANGE_RANGE.matches(cx, def_id) // Add the path to `clippy_utils::paths` if needed\n    && fields.len() == 2\n    && fields[0].ident.as_str() == \"start\"\n    && let ExprKind::Lit(ref lit) = fields[0].expr.kind\n    && let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node\n    && fields[1].ident.as_str() == \"end\"\n    && let ExprKind::Lit(ref lit1) = fields[1].expr.kind\n    && let LitKind::Int(1, LitIntType::Unsuffixed) = lit1.node\n    && let ExprKind::Block(block, None) = body.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Semi(e) = block.stmts[0].kind\n    && let ExprKind::Block(block1, None) = e.kind\n    && block1.stmts.len() == 1\n    && let StmtKind::Semi(e1) = block1.stmts[0].kind\n    && let ExprKind::Call(func, args) = e1.kind\n    && paths::STD_IO_STDIO__PRINT.matches_path(cx, func) // Add the path to `clippy_utils::paths` if needed\n    && args.len() == 1\n    && let ExprKind::Block(block2, None) = args[0].kind\n    && block2.stmts.len() == 2\n    && let StmtKind::Let(local) = block2.stmts[0].kind\n    && let Some(init) = local.init\n    && let ExprKind::Tup(elements) = init.kind\n    && elements.len() == 1\n    && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = elements[0].kind\n    && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind\n    && name1.as_str() == \"args\"\n    && let StmtKind::Let(local1) = block2.stmts[1].kind\n    && let Some(init1) = local1.init\n    && let ExprKind::Array(elements1) = init1.kind\n    && elements1.len() == 1\n    && let ExprKind::Call(func1, args1) = elements1[0].kind\n    && paths::CORE_FMT_RT_ARGUMENT_NEW_DISPLAY.matches_path(cx, func1) // Add the path to `clippy_utils::paths` if needed\n    && args1.len() == 1\n    && let ExprKind::Field(object, field_name) = args1[0].kind\n    && field_name.as_str() == \"0\"\n    && let PatKind::Binding(BindingMode::NONE, _, name2, None) = local1.pat.kind\n    && name2.as_str() == \"args\"\n    && let Some(trailing_expr) = block2.expr\n    && let ExprKind::Block(block3, None) = trailing_expr.kind\n    && block3.stmts.is_empty()\n    && let Some(trailing_expr1) = block3.expr\n    && let ExprKind::Call(func2, args2) = trailing_expr1.kind\n    && paths::CORE_FMT_ARGUMENTS_NEW.matches_path(cx, func2) // Add the path to `clippy_utils::paths` if needed\n    && args2.len() == 2\n    && let ExprKind::Lit(ref lit2) = args2[0].kind\n    && let LitKind::ByteStr(ref vec) = lit2.node\n    && let [[192, 1, 10, 0]] = **vec\n    && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner1) = args2[1].kind\n    && block1.expr.is_none()\n    && block.expr.is_none()\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/matches.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::let_and_return)]\n\nfn main() {\n    #[clippy::author]\n    let a = match 42 {\n        16 => 5,\n        17 => {\n            let x = 3;\n            x\n        },\n        _ => 1,\n    };\n}\n"
  },
  {
    "path": "tests/ui/author/matches.stdout",
    "content": "if let StmtKind::Let(local) = stmt.kind\n    && let Some(init) = local.init\n    && let ExprKind::Match(scrutinee, arms, MatchSource::Normal) = init.kind\n    && let ExprKind::Lit(ref lit) = scrutinee.kind\n    && let LitKind::Int(42, LitIntType::Unsuffixed) = lit.node\n    && arms.len() == 3\n    && let PatKind::Expr(lit_expr) = arms[0].pat.kind\n    && let PatExprKind::Lit { ref lit1, negated } = lit_expr.kind\n    && let LitKind::Int(16, LitIntType::Unsuffixed) = lit1.node\n    && arms[0].guard.is_none()\n    && let ExprKind::Lit(ref lit2) = arms[0].body.kind\n    && let LitKind::Int(5, LitIntType::Unsuffixed) = lit2.node\n    && let PatKind::Expr(lit_expr1) = arms[1].pat.kind\n    && let PatExprKind::Lit { ref lit3, negated1 } = lit_expr1.kind\n    && let LitKind::Int(17, LitIntType::Unsuffixed) = lit3.node\n    && arms[1].guard.is_none()\n    && let ExprKind::Block(block, None) = arms[1].body.kind\n    && block.stmts.len() == 1\n    && let StmtKind::Let(local1) = block.stmts[0].kind\n    && let Some(init1) = local1.init\n    && let ExprKind::Lit(ref lit4) = init1.kind\n    && let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node\n    && let PatKind::Binding(BindingMode::NONE, _, name, None) = local1.pat.kind\n    && name.as_str() == \"x\"\n    && let Some(trailing_expr) = block.expr\n    && let PatKind::Wild = arms[2].pat.kind\n    && arms[2].guard.is_none()\n    && let ExprKind::Lit(ref lit5) = arms[2].body.kind\n    && let LitKind::Int(1, LitIntType::Unsuffixed) = lit5.node\n    && let PatKind::Binding(BindingMode::NONE, _, name1, None) = local.pat.kind\n    && name1.as_str() == \"a\"\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/repeat.rs",
    "content": "//@ check-pass\n\n#[allow(clippy::no_effect)]\nfn main() {\n    #[clippy::author]\n    [1_u8; 5];\n}\n"
  },
  {
    "path": "tests/ui/author/repeat.stdout",
    "content": "if let ExprKind::Repeat(value, length) = expr.kind\n    && let ExprKind::Lit(ref lit) = value.kind\n    && let LitKind::Int(1, LitIntType::Unsigned(UintTy::U8)) = lit.node\n    && let ConstArgKind::Anon(anon_const) = length.kind\n    && expr1 = &cx.tcx.hir_body(anon_const.body).value\n    && let ExprKind::Lit(ref lit1) = expr1.kind\n    && let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author/struct.rs",
    "content": "//@ check-pass\n\n#![allow(\n    clippy::unnecessary_operation,\n    clippy::single_match,\n    clippy::no_effect,\n    clippy::bool_to_int_with_if\n)]\nfn main() {\n    struct Test {\n        field: u32,\n    }\n\n    #[clippy::author]\n    Test {\n        field: if true { 1 } else { 0 },\n    };\n\n    let test = Test { field: 1 };\n\n    match test {\n        #[clippy::author]\n        Test { field: 1 } => {},\n        _ => {},\n    }\n\n    struct TestTuple(u32);\n\n    let test_tuple = TestTuple(1);\n\n    match test_tuple {\n        #[clippy::author]\n        TestTuple(1) => {},\n        _ => {},\n    }\n\n    struct TestMethodCall(u32);\n\n    impl TestMethodCall {\n        fn test(&self) {}\n    }\n\n    let test_method_call = TestMethodCall(1);\n\n    #[clippy::author]\n    test_method_call.test();\n}\n"
  },
  {
    "path": "tests/ui/author/struct.stdout",
    "content": "if let ExprKind::Struct(qpath, fields, None) = expr.kind\n    && fields.len() == 1\n    && fields[0].ident.as_str() == \"field\"\n    && let ExprKind::If(cond, then, Some(else_expr)) = fields[0].expr.kind\n    && let ExprKind::Lit(ref lit) = cond.kind\n    && let LitKind::Bool(true) = lit.node\n    && let ExprKind::Block(block, None) = then.kind\n    && block.stmts.is_empty()\n    && let Some(trailing_expr) = block.expr\n    && let ExprKind::Lit(ref lit1) = trailing_expr.kind\n    && let LitKind::Int(1, LitIntType::Unsuffixed) = lit1.node\n    && let ExprKind::Block(block1, None) = else_expr.kind\n    && block1.stmts.is_empty()\n    && let Some(trailing_expr1) = block1.expr\n    && let ExprKind::Lit(ref lit2) = trailing_expr1.kind\n    && let LitKind::Int(0, LitIntType::Unsuffixed) = lit2.node\n{\n    // report your lint here\n}\nif let PatKind::Struct(ref qpath, fields, false) = arm.pat.kind\n    && fields.len() == 1\n    && fields[0].ident.as_str() == \"field\"\n    && let PatKind::Expr(lit_expr) = fields[0].pat.kind\n    && let PatExprKind::Lit { ref lit, negated } = lit_expr.kind\n    && let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node\n    && arm.guard.is_none()\n    && let ExprKind::Block(block, None) = arm.body.kind\n    && block.stmts.is_empty()\n    && block.expr.is_none()\n{\n    // report your lint here\n}\nif let PatKind::TupleStruct(ref qpath, fields, None) = arm.pat.kind\n    && fields.len() == 1\n    && let PatKind::Expr(lit_expr) = fields[0].kind\n    && let PatExprKind::Lit { ref lit, negated } = lit_expr.kind\n    && let LitKind::Int(1, LitIntType::Unsuffixed) = lit.node\n    && arm.guard.is_none()\n    && let ExprKind::Block(block, None) = arm.body.kind\n    && block.stmts.is_empty()\n    && block.expr.is_none()\n{\n    // report your lint here\n}\nif let ExprKind::MethodCall(method_name, receiver, args, _) = expr.kind\n    && method_name.ident.as_str() == \"test\"\n    && args.is_empty()\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/author.rs",
    "content": "//@ check-pass\n\nfn main() {\n    #[clippy::author]\n    let x: char = 0x45 as char;\n}\n"
  },
  {
    "path": "tests/ui/author.stdout",
    "content": "if let StmtKind::Let(local) = stmt.kind\n    && let Some(init) = local.init\n    && let ExprKind::Cast(expr, cast_ty) = init.kind\n    && let ExprKind::Lit(ref lit) = expr.kind\n    && let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node\n    && let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind\n    && name.as_str() == \"x\"\n{\n    // report your lint here\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/extern_fake_libc.rs",
    "content": "#![allow(nonstandard_style)]\n#![allow(clippy::missing_safety_doc, unused)]\n\ntype pid_t = i32;\npub unsafe fn getpid() -> pid_t {\n    pid_t::from(0)\n}\npub fn getpid_SAFE_TRUTH() -> pid_t {\n    unsafe { getpid() }\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/external_consts.rs",
    "content": "pub const MAGIC_NUMBER: i32 = 1;\n"
  },
  {
    "path": "tests/ui/auxiliary/external_item.rs",
    "content": "pub struct _ExternalStruct {}\n\nimpl _ExternalStruct {\n    pub fn _foo(self) {}\n}\n\npub fn _external_foo() {}\n"
  },
  {
    "path": "tests/ui/auxiliary/interior_mutable_const.rs",
    "content": "// this file solely exists to test constants defined in foreign crates.\n// As the most common case is the `http` crate, it replicates `http::HeaderName`'s structure.\n\n#![allow(clippy::declare_interior_mutable_const)]\n\nuse std::sync::atomic::AtomicUsize;\n\nenum Private<T> {\n    ToBeUnfrozen(T),\n    Frozen(usize),\n}\n\npub struct Wrapper(Private<AtomicUsize>);\n\npub const WRAPPED_PRIVATE_UNFROZEN_VARIANT: Wrapper = Wrapper(Private::ToBeUnfrozen(AtomicUsize::new(6)));\npub const WRAPPED_PRIVATE_FROZEN_VARIANT: Wrapper = Wrapper(Private::Frozen(7));\n"
  },
  {
    "path": "tests/ui/auxiliary/macro_rules.rs",
    "content": "#![allow(dead_code)]\n\n//! Used to test that certain lints don't trigger in imported external macros\n#[macro_export]\nmacro_rules! try_err {\n    () => {\n        pub fn try_err_fn() -> Result<i32, i32> {\n            let err: i32 = 1;\n            // To avoid warnings during rustfix\n            if true { Err(err)? } else { Ok(2) }\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! string_add {\n    () => {\n        let y = \"\".to_owned();\n        let z = y + \"...\";\n    };\n}\n\n#[macro_export]\nmacro_rules! string_lit_as_bytes {\n    ($s:literal) => {\n        const C: &[u8] = $s.as_bytes();\n    };\n}\n\n#[macro_export]\nmacro_rules! mut_mut {\n    () => {\n        let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32;\n    };\n}\n\n#[macro_export]\nmacro_rules! issue_10421 {\n    () => {\n        let mut a = 1;\n        let mut b = 2;\n        a = b;\n        b = a;\n    };\n}\n\n#[macro_export]\nmacro_rules! macro_with_panic {\n    () => {\n        panic!()\n    };\n}\n\n#[macro_export]\nmacro_rules! bad_transmute {\n    ($e:expr) => {\n        std::mem::transmute($e)\n    };\n}\n\n#[macro_export]\n#[rustfmt::skip]\nmacro_rules! double_parens {\n    ($a:expr, $b:expr, $c:expr, $d:expr) => {{\n        let a = ($a);\n        let a = (());\n        let b = ((5));\n        let c = std::convert::identity((5));\n        InterruptMask((($a.union($b).union($c).union($d)).into_bits()) as u32)\n    }};\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/macro_use_helper.rs",
    "content": "//@aux-build:macro_rules.rs\n\nextern crate macro_rules;\n\n// STMT\n#[macro_export]\nmacro_rules! pub_macro {\n    () => {\n        let _ = \"hello Mr. Vonnegut\";\n    };\n}\n\npub mod inner {\n    pub use super::*;\n\n    // RE-EXPORT\n    // this will stick in `inner` module\n    pub use macro_rules::{mut_mut, try_err};\n\n    pub mod nested {\n        pub use macro_rules::string_add;\n    }\n\n    // ITEM\n    #[macro_export]\n    macro_rules! inner_mod_macro {\n        () => {\n            #[allow(dead_code)]\n            pub struct Tardis;\n        };\n    }\n}\n\n// EXPR\n#[macro_export]\nmacro_rules! function_macro {\n    () => {\n        if true {\n        } else {\n        }\n    };\n}\n\n// TYPE\n#[macro_export]\nmacro_rules! ty_macro {\n    () => {\n        Vec<u8>\n    };\n}\n\nmod extern_exports {\n    pub(super) mod private_inner {\n        #[macro_export]\n        macro_rules! pub_in_private_macro {\n            ($name:ident) => {\n                let $name = String::from(\"secrets and lies\");\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/non-exhaustive-enum.rs",
    "content": "// Stripped down version of the ErrorKind enum of std\n#[non_exhaustive]\npub enum ErrorKind {\n    NotFound,\n    PermissionDenied,\n    #[doc(hidden)]\n    Uncategorized,\n}\n\n#[non_exhaustive]\npub enum ExtNonExhaustiveEnum {\n    Unit,\n    Tuple(i32),\n    Struct { field: i32 },\n}\n\npub enum ExtNonExhaustiveVariant {\n    ExhaustiveUnit,\n    #[non_exhaustive]\n    Unit,\n    #[non_exhaustive]\n    Tuple(i32),\n    #[non_exhaustive]\n    StructNoField {},\n    #[non_exhaustive]\n    Struct {\n        field: i32,\n    },\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/option_helpers.rs",
    "content": "#![allow(dead_code, unused_variables, clippy::return_self_not_must_use)]\n\n/// Utility macro to test linting behavior in `option_methods()`\n/// The lints included in `option_methods()` should not lint if the call to map is partially\n/// within a macro\n#[macro_export]\nmacro_rules! opt_map {\n    ($opt:expr, $map:expr) => {\n        ($opt).map($map)\n    };\n}\n\n/// Struct to generate false positive for Iterator-based lints\n#[derive(Copy, Clone)]\npub struct IteratorFalsePositives {\n    pub foo: u32,\n}\n\nimpl IteratorFalsePositives {\n    pub fn filter(self) -> IteratorFalsePositives {\n        self\n    }\n\n    pub fn next(self) -> IteratorFalsePositives {\n        self\n    }\n\n    pub fn next_back(self) -> IteratorFalsePositives {\n        self\n    }\n\n    pub fn find(self) -> Option<u32> {\n        Some(self.foo)\n    }\n\n    pub fn position(self) -> Option<u32> {\n        Some(self.foo)\n    }\n\n    pub fn rposition(self) -> Option<u32> {\n        Some(self.foo)\n    }\n\n    pub fn nth(self, n: usize) -> Option<u32> {\n        Some(self.foo)\n    }\n\n    pub fn skip(self, _: usize) -> IteratorFalsePositives {\n        self\n    }\n\n    pub fn skip_while(self) -> IteratorFalsePositives {\n        self\n    }\n\n    pub fn count(self) -> usize {\n        self.foo as usize\n    }\n}\n\n#[derive(Copy, Clone)]\npub struct IteratorMethodFalsePositives;\n\nimpl IteratorMethodFalsePositives {\n    pub fn filter(&self, _s: i32) -> std::vec::IntoIter<i32> {\n        unimplemented!();\n    }\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/proc_macro_attr.rs",
    "content": "#![feature(proc_macro_hygiene, proc_macro_quote, box_patterns)]\n#![allow(clippy::useless_conversion, clippy::uninlined_format_args)]\n\nextern crate proc_macro;\nextern crate quote;\nextern crate syn;\n\nuse proc_macro::TokenStream;\nuse quote::{quote, quote_spanned};\nuse syn::spanned::Spanned;\nuse syn::token::Star;\nuse syn::{\n    FnArg, ImplItem, ItemFn, ItemImpl, ItemStruct, ItemTrait, Lifetime, Pat, PatIdent, PatType, Signature, TraitItem,\n    Type, Visibility, parse_macro_input, parse_quote,\n};\n\n#[proc_macro_attribute]\npub fn dummy(_args: TokenStream, input: TokenStream) -> TokenStream {\n    input\n}\n\n#[proc_macro_attribute]\npub fn fake_async_trait(_args: TokenStream, input: TokenStream) -> TokenStream {\n    let mut item = parse_macro_input!(input as ItemTrait);\n    for inner in &mut item.items {\n        if let TraitItem::Fn(method) = inner {\n            let sig = &method.sig;\n            let block = &mut method.default;\n            if let Some(block) = block {\n                let brace = block.brace_token;\n\n                let my_block = quote_spanned!( brace.span => {\n                    // Should not trigger `empty_line_after_outer_attr`\n                    #[crate_type = \"lib\"]\n                    #sig #block\n                    Vec::new()\n                });\n                *block = parse_quote!(#my_block);\n            }\n        }\n    }\n    TokenStream::from(quote!(#item))\n}\n\n#[proc_macro_attribute]\npub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStream {\n    fn make_name(count: usize) -> String {\n        format!(\"'life{}\", count)\n    }\n\n    fn mut_receiver_of(sig: &mut Signature) -> Option<&mut FnArg> {\n        let arg = sig.inputs.first_mut()?;\n        if let FnArg::Typed(PatType { pat, .. }) = arg\n            && let Pat::Ident(PatIdent { ident, .. }) = &**pat\n            && ident == \"self\"\n        {\n            Some(arg)\n        } else {\n            None\n        }\n    }\n\n    let mut elided = 0;\n    let mut item = parse_macro_input!(input as ItemImpl);\n\n    // Look for methods having arbitrary self type taken by &mut ref\n    for inner in &mut item.items {\n        if let ImplItem::Fn(method) = inner\n            && let Some(FnArg::Typed(pat_type)) = mut_receiver_of(&mut method.sig)\n            && let box Type::Reference(reference) = &mut pat_type.ty\n        {\n            // Target only unnamed lifetimes\n            let name = match &reference.lifetime {\n                Some(lt) if lt.ident == \"_\" => make_name(elided),\n                None => make_name(elided),\n                _ => continue,\n            };\n            elided += 1;\n\n            // HACK: Syn uses `Span` from the proc_macro2 crate, and does not seem to reexport it.\n            // In order to avoid adding the dependency, get a default span from a nonexistent token.\n            // A default span is needed to mark the code as coming from expansion.\n            let span = Star::default().span();\n\n            // Replace old lifetime with the named one\n            let lifetime = Lifetime::new(&name, span);\n            reference.lifetime = Some(parse_quote!(#lifetime));\n\n            // Add lifetime to the generics of the method\n            method.sig.generics.params.push(parse_quote!(#lifetime));\n        }\n    }\n\n    TokenStream::from(quote!(#item))\n}\n\n#[proc_macro_attribute]\npub fn fake_main(_attr: TokenStream, item: TokenStream) -> TokenStream {\n    let mut item = parse_macro_input!(item as ItemFn);\n    let span = item.block.brace_token.span;\n\n    item.sig.asyncness = None;\n\n    let crate_name = quote! { fake_crate };\n    let block = item.block;\n    item.block = syn::parse_quote_spanned! {\n        span =>\n        {\n            #crate_name::block_on(async {\n                #block\n            })\n        }\n    };\n\n    quote! {\n        mod #crate_name {\n            pub fn block_on<F: ::std::future::Future>(_fut: F) {}\n        }\n\n        #item\n    }\n    .into()\n}\n\n#[proc_macro_attribute]\npub fn fake_desugar_await(_args: TokenStream, input: TokenStream) -> TokenStream {\n    let mut async_fn = parse_macro_input!(input as syn::ItemFn);\n\n    for stmt in &mut async_fn.block.stmts {\n        if let syn::Stmt::Expr(syn::Expr::Match(syn::ExprMatch { expr: scrutinee, .. }), _) = stmt\n            && let syn::Expr::Await(syn::ExprAwait { base, await_token, .. }) = scrutinee.as_mut()\n        {\n            let blc = quote_spanned!( await_token.span => {\n                #[allow(clippy::let_and_return)]\n                let __pinned = #base;\n                __pinned\n            });\n            *scrutinee = parse_quote!(#blc);\n        }\n    }\n\n    quote!(#async_fn).into()\n}\n\n#[proc_macro_attribute]\npub fn rewrite_struct(_args: TokenStream, input: TokenStream) -> TokenStream {\n    let mut item_struct = parse_macro_input!(input as syn::ItemStruct);\n    // remove struct attributes including doc comments.\n    item_struct.attrs = vec![];\n    if let Visibility::Public(token) = item_struct.vis {\n        // set vis to `pub(crate)` to trigger `missing_docs_in_private_items` lint.\n        let new_vis: Visibility = syn::parse_quote_spanned!(token.span() => pub(crate));\n        item_struct.vis = new_vis;\n    }\n    if let syn::Fields::Named(fields) = &mut item_struct.fields {\n        for field in &mut fields.named {\n            // remove all attributes from fields as well.\n            field.attrs = vec![];\n        }\n    }\n\n    quote!(#item_struct).into()\n}\n\n#[proc_macro_attribute]\npub fn with_empty_docs(_attr: TokenStream, input: TokenStream) -> TokenStream {\n    let item = parse_macro_input!(input as syn::Item);\n    let attrs: Vec<syn::Attribute> = vec![];\n    let doc_comment = \"\";\n    quote! {\n        #(#attrs)*\n        #[doc = #doc_comment]\n        #item\n    }\n    .into()\n}\n\n#[proc_macro_attribute]\npub fn duplicated_attr(_attr: TokenStream, input: TokenStream) -> TokenStream {\n    let item = parse_macro_input!(input as syn::Item);\n    let attrs: Vec<syn::Attribute> = vec![];\n    quote! {\n        #(#attrs)*\n        #[allow(unused)]\n        #[allow(unused)]\n        #[allow(unused)]\n        #item\n    }\n    .into()\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/proc_macro_derive.rs",
    "content": "#![feature(proc_macro_quote, proc_macro_span)]\n#![allow(clippy::field_reassign_with_default)]\n#![allow(clippy::eq_op)]\n#![allow(clippy::literal_string_with_formatting_args)]\n\nextern crate proc_macro;\n\nuse proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree, quote};\n\n#[proc_macro_derive(DeriveSomething)]\npub fn derive(_: TokenStream) -> TokenStream {\n    // Should not trigger `used_underscore_binding`\n    let _inside_derive = 1;\n    assert_eq!(_inside_derive, _inside_derive);\n\n    let output = quote! {\n        // Should not trigger `useless_attribute`\n        #[allow(dead_code)]\n        extern crate core;\n    };\n    output\n}\n\n#[proc_macro_derive(ImplStructWithStdDisplay)]\npub fn derive_std(_: TokenStream) -> TokenStream {\n    quote! {\n        struct A {}\n        impl ::std::fmt::Display for A {\n            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {\n                write!(f, \"A\")\n            }\n        }\n    }\n}\n\n#[proc_macro_derive(FieldReassignWithDefault)]\npub fn derive_foo(_input: TokenStream) -> TokenStream {\n    quote! {\n        #[derive(Default)]\n        struct A {\n            pub i: i32,\n            pub j: i64,\n        }\n        #[automatically_derived]\n        fn lint() {\n            let mut a: A = Default::default();\n            a.i = 42;\n            a;\n        }\n    }\n}\n\n#[proc_macro_derive(StructAUseSelf)]\npub fn derive_use_self(_input: TokenStream) -> proc_macro::TokenStream {\n    quote! {\n        struct A;\n        impl A {\n            fn new() -> A {\n                A\n            }\n        }\n    }\n}\n\n#[proc_macro_derive(ClippyMiniMacroTest)]\npub fn mini_macro(_: TokenStream) -> TokenStream {\n    quote!(\n        #[allow(unused)]\n        fn needless_take_by_value(s: String) {\n            println!(\"{}\", s.len());\n        }\n        #[allow(unused)]\n        fn needless_loop(items: &[u8]) {\n            for i in 0..items.len() {\n                println!(\"{}\", items[i]);\n            }\n        }\n        fn line_wrapper() {\n            println!(\"{}\", line!());\n        }\n    )\n}\n\n#[proc_macro_derive(ExtraLifetimeDerive)]\n#[allow(unused)]\npub fn extra_lifetime(_input: TokenStream) -> TokenStream {\n    quote!(\n        pub struct ExtraLifetime;\n\n        impl<'b> ExtraLifetime {\n            pub fn something<'c>() -> Self {\n                Self\n            }\n        }\n    )\n}\n\n#[allow(unused)]\n#[proc_macro_derive(ArithmeticDerive)]\npub fn arithmetic_derive(_: TokenStream) -> TokenStream {\n    <TokenStream as FromIterator<TokenTree>>::from_iter([\n        Ident::new(\"fn\", Span::call_site()).into(),\n        Ident::new(\"_foo\", Span::call_site()).into(),\n        Group::new(Delimiter::Parenthesis, TokenStream::new()).into(),\n        Group::new(\n            Delimiter::Brace,\n            <TokenStream as FromIterator<TokenTree>>::from_iter([\n                Ident::new(\"let\", Span::call_site()).into(),\n                Ident::new(\"mut\", Span::call_site()).into(),\n                Ident::new(\"_n\", Span::call_site()).into(),\n                Punct::new('=', Spacing::Alone).into(),\n                Literal::i32_unsuffixed(9).into(),\n                Punct::new(';', Spacing::Alone).into(),\n                Ident::new(\"_n\", Span::call_site()).into(),\n                Punct::new('=', Spacing::Alone).into(),\n                Literal::i32_unsuffixed(9).into(),\n                Punct::new('/', Spacing::Alone).into(),\n                Literal::i32_unsuffixed(2).into(),\n                Punct::new(';', Spacing::Alone).into(),\n                Ident::new(\"_n\", Span::call_site()).into(),\n                Punct::new('=', Spacing::Alone).into(),\n                Punct::new('-', Spacing::Alone).into(),\n                Ident::new(\"_n\", Span::call_site()).into(),\n                Punct::new(';', Spacing::Alone).into(),\n            ]),\n        )\n        .into(),\n    ])\n}\n\n#[allow(unused)]\n#[proc_macro_derive(ShadowDerive)]\npub fn shadow_derive(_: TokenStream) -> TokenStream {\n    <TokenStream as FromIterator<TokenTree>>::from_iter([\n        Ident::new(\"fn\", Span::call_site()).into(),\n        Ident::new(\"_foo\", Span::call_site()).into(),\n        Group::new(Delimiter::Parenthesis, TokenStream::new()).into(),\n        Group::new(\n            Delimiter::Brace,\n            <TokenStream as FromIterator<TokenTree>>::from_iter([\n                Ident::new(\"let\", Span::call_site()).into(),\n                Ident::new(\"_x\", Span::call_site()).into(),\n                Punct::new('=', Spacing::Alone).into(),\n                Literal::i32_unsuffixed(2).into(),\n                Punct::new(';', Spacing::Alone).into(),\n                Ident::new(\"let\", Span::call_site()).into(),\n                Ident::new(\"_x\", Span::call_site()).into(),\n                Punct::new('=', Spacing::Alone).into(),\n                Ident::new(\"_x\", Span::call_site()).into(),\n                Punct::new(';', Spacing::Alone).into(),\n            ]),\n        )\n        .into(),\n    ])\n}\n\n#[proc_macro_derive(StructIgnoredUnitPattern)]\npub fn derive_ignored_unit_pattern(_: TokenStream) -> TokenStream {\n    quote! {\n        struct A;\n        impl A {\n            fn a(&self) -> Result<(), ()> {\n                unimplemented!()\n            }\n\n            pub fn b(&self) {\n                let _ = self.a().unwrap();\n            }\n        }\n    }\n}\n\n#[proc_macro_derive(NonCanonicalClone)]\npub fn non_canonical_clone_derive(_: TokenStream) -> TokenStream {\n    quote! {\n        struct NonCanonicalClone;\n        impl Clone for NonCanonicalClone {\n            fn clone(&self) -> Self {\n                todo!()\n            }\n        }\n        impl Copy for NonCanonicalClone {}\n    }\n}\n\n// Derive macro that generates the following but where all generated spans are set to the entire\n// input span.\n//\n// ```\n// #[allow(clippy::missing_const_for_fn)]\n// fn check() {}\n// ```\n#[proc_macro_derive(AllowLintSameSpan)]\npub fn allow_lint_same_span_derive(input: TokenStream) -> TokenStream {\n    let mut iter = input.into_iter();\n    let first = iter.next().unwrap();\n    let last = iter.last().unwrap();\n    let span = first.span().join(last.span()).unwrap();\n    let span_help = |mut t: TokenTree| -> TokenTree {\n        t.set_span(span);\n        t\n    };\n    // Generate the TokenStream but setting all the spans to the entire input span\n    <TokenStream as FromIterator<TokenTree>>::from_iter([\n        span_help(Punct::new('#', Spacing::Alone).into()),\n        span_help(\n            Group::new(\n                Delimiter::Bracket,\n                <TokenStream as FromIterator<TokenTree>>::from_iter([\n                    Ident::new(\"allow\", span).into(),\n                    span_help(\n                        Group::new(\n                            Delimiter::Parenthesis,\n                            <TokenStream as FromIterator<TokenTree>>::from_iter([\n                                Ident::new(\"clippy\", span).into(),\n                                span_help(Punct::new(':', Spacing::Joint).into()),\n                                span_help(Punct::new(':', Spacing::Alone).into()),\n                                Ident::new(\"missing_const_for_fn\", span).into(),\n                            ]),\n                        )\n                        .into(),\n                    ),\n                ]),\n            )\n            .into(),\n        ),\n        Ident::new(\"fn\", span).into(),\n        Ident::new(\"check\", span).into(),\n        span_help(Group::new(Delimiter::Parenthesis, TokenStream::new()).into()),\n        span_help(Group::new(Delimiter::Brace, TokenStream::new()).into()),\n    ])\n}\n\n#[proc_macro_derive(DoubleParens)]\npub fn derive_double_parens(_: TokenStream) -> TokenStream {\n    quote! {\n        fn foo() {\n            let a = (());\n            let b = ((5));\n            let c = std::convert::identity((5));\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs",
    "content": "extern crate proc_macro;\nuse proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree, token_stream};\n\nfn read_ident(iter: &mut token_stream::IntoIter) -> Ident {\n    match iter.next() {\n        Some(TokenTree::Ident(i)) => i,\n        _ => panic!(\"expected ident\"),\n    }\n}\n\n#[proc_macro_derive(DeriveBadSpan)]\npub fn derive_bad_span(input: TokenStream) -> TokenStream {\n    let mut input = input.into_iter();\n    assert_eq!(read_ident(&mut input).to_string(), \"struct\");\n    let ident = read_ident(&mut input);\n    let mut tys = match input.next() {\n        Some(TokenTree::Group(g)) if g.delimiter() == Delimiter::Parenthesis => g.stream().into_iter(),\n        _ => panic!(),\n    };\n    let field1 = read_ident(&mut tys);\n    tys.next();\n    let field2 = read_ident(&mut tys);\n\n    <TokenStream as FromIterator<TokenTree>>::from_iter(\n        [\n            Ident::new(\"impl\", Span::call_site()).into(),\n            ident.into(),\n            Group::new(\n                Delimiter::Brace,\n                <TokenStream as FromIterator<TokenTree>>::from_iter(\n                    [\n                        Ident::new(\"fn\", Span::call_site()).into(),\n                        Ident::new(\"_foo\", Span::call_site()).into(),\n                        Group::new(Delimiter::Parenthesis, TokenStream::new()).into(),\n                        Group::new(\n                            Delimiter::Brace,\n                            <TokenStream as FromIterator<TokenTree>>::from_iter(\n                                [\n                                    Ident::new(\"if\", field1.span()).into(),\n                                    Ident::new(\"true\", field1.span()).into(),\n                                    {\n                                        let mut group = Group::new(Delimiter::Brace, TokenStream::new());\n                                        group.set_span(field1.span());\n                                        group.into()\n                                    },\n                                    Ident::new(\"if\", field2.span()).into(),\n                                    Ident::new(\"true\", field2.span()).into(),\n                                    {\n                                        let mut group = Group::new(Delimiter::Brace, TokenStream::new());\n                                        group.set_span(field2.span());\n                                        group.into()\n                                    },\n                                ]\n                                .iter()\n                                .cloned(),\n                            ),\n                        )\n                        .into(),\n                    ]\n                    .iter()\n                    .cloned(),\n                ),\n            )\n            .into(),\n        ]\n        .iter()\n        .cloned(),\n    )\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/proc_macro_unsafe.rs",
    "content": "extern crate proc_macro;\n\nuse proc_macro::{Delimiter, Group, Ident, TokenStream, TokenTree};\n\n#[proc_macro]\npub fn unsafe_block(input: TokenStream) -> TokenStream {\n    let span = input.into_iter().next().unwrap().span();\n    TokenStream::from_iter([TokenTree::Ident(Ident::new(\"unsafe\", span)), {\n        let mut group = Group::new(Delimiter::Brace, TokenStream::new());\n        group.set_span(span);\n        TokenTree::Group(group)\n    }])\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/proc_macros.rs",
    "content": "#![feature(proc_macro_span)]\n#![allow(clippy::needless_ifs, dead_code)]\n\nextern crate proc_macro;\n\nuse core::mem;\nuse proc_macro::Delimiter::{self, Brace, Parenthesis};\nuse proc_macro::Spacing::{self, Alone, Joint};\nuse proc_macro::token_stream::IntoIter;\nuse proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree as TT};\nuse syn::spanned::Spanned;\n\ntype Result<T> = core::result::Result<T, TokenStream>;\n\n/// Make a `compile_error!` pointing to the given span.\nfn make_error(msg: &str, span: Span) -> TokenStream {\n    TokenStream::from_iter([\n        TT::Ident(Ident::new(\"compile_error\", span)),\n        TT::Punct(punct_with_span('!', Alone, span)),\n        TT::Group({\n            let mut msg = Literal::string(msg);\n            msg.set_span(span);\n            group_with_span(Parenthesis, TokenStream::from_iter([TT::Literal(msg)]), span)\n        }),\n    ])\n}\n\nfn expect_tt<T>(tt: Option<TT>, f: impl FnOnce(TT) -> Option<T>, expected: &str, span: Span) -> Result<T> {\n    match tt {\n        None => Err(make_error(\n            &format!(\"unexpected end of input, expected {expected}\"),\n            span,\n        )),\n        Some(tt) => {\n            let span = tt.span();\n            match f(tt) {\n                Some(x) => Ok(x),\n                None => Err(make_error(&format!(\"unexpected token, expected {expected}\"), span)),\n            }\n        },\n    }\n}\n\nfn punct_with_span(c: char, spacing: Spacing, span: Span) -> Punct {\n    let mut p = Punct::new(c, spacing);\n    p.set_span(span);\n    p\n}\n\nfn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Group {\n    let mut g = Group::new(delimiter, stream);\n    g.set_span(span);\n    g\n}\n\n/// Token used to escape the following token from the macro's span rules.\nconst ESCAPE_CHAR: char = '$';\n\n/// Takes a single token followed by a sequence of tokens. Returns the sequence of tokens with their\n/// span set to that of the first token. Tokens may be escaped with either `$ident` or `$(tokens)`.\n#[proc_macro]\npub fn with_span(input: TokenStream) -> TokenStream {\n    let mut iter = input.into_iter();\n    let span = iter.next().unwrap().span();\n    let mut res = TokenStream::new();\n    if let Err(e) = write_with_span(span, iter, &mut res) {\n        e\n    } else {\n        res\n    }\n}\n\n/// Takes a sequence of tokens and return the tokens with the span set such that they appear to be\n/// from an external macro. Tokens may be escaped with either `$ident` or `$(tokens)`.\n#[proc_macro]\npub fn external(input: TokenStream) -> TokenStream {\n    let mut res = TokenStream::new();\n    if let Err(e) = write_with_span(Span::mixed_site(), input.into_iter(), &mut res) {\n        e\n    } else {\n        res\n    }\n}\n\n/// Copies all the tokens, replacing all their spans with the given span. Tokens can be escaped\n/// either by `$ident` or `$(tokens)`.\nfn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Result<()> {\n    while let Some(tt) = input.next() {\n        match tt {\n            TT::Punct(p) if p.as_char() == ESCAPE_CHAR => {\n                expect_tt(\n                    input.next(),\n                    |tt| match tt {\n                        tt @ (TT::Ident(_) | TT::Literal(_)) => {\n                            out.extend([tt]);\n                            Some(())\n                        },\n                        TT::Punct(mut p) if p.as_char() == ESCAPE_CHAR => {\n                            p.set_span(s);\n                            out.extend([TT::Punct(p)]);\n                            Some(())\n                        },\n                        TT::Group(g) if g.delimiter() == Parenthesis => {\n                            out.extend([TT::Group(group_with_span(Delimiter::None, g.stream(), g.span()))]);\n                            Some(())\n                        },\n                        _ => None,\n                    },\n                    \"an ident, a literal, or parenthesized tokens\",\n                    p.span(),\n                )?;\n            },\n            TT::Group(g) => {\n                let mut stream = TokenStream::new();\n                write_with_span(s, g.stream().into_iter(), &mut stream)?;\n                out.extend([TT::Group(group_with_span(g.delimiter(), stream, s))]);\n            },\n            mut tt => {\n                tt.set_span(s);\n                out.extend([tt]);\n            },\n        }\n    }\n    Ok(())\n}\n\n/// Takes an array repeat expression such as `[0_u32; 2]`, and return the tokens with 10 times the\n/// original size, which turns to `[0_u32; 20]`.\n#[proc_macro]\npub fn make_it_big(input: TokenStream) -> TokenStream {\n    let mut expr_repeat = syn::parse_macro_input!(input as syn::ExprRepeat);\n    let len_span = expr_repeat.len.span();\n    if let syn::Expr::Lit(expr_lit) = &mut *expr_repeat.len\n        && let syn::Lit::Int(lit_int) = &expr_lit.lit\n    {\n        let orig_val = lit_int.base10_parse::<usize>().expect(\"not a valid length parameter\");\n        let new_val = orig_val.saturating_mul(10);\n        expr_lit.lit = syn::parse_quote_spanned!( len_span => #new_val);\n    }\n    quote::quote!(#expr_repeat).into()\n}\n\n/// Within the item this attribute is attached to, an `inline!` macro is available which expands the\n/// contained tokens as though they came from a macro expansion.\n///\n/// Within the `inline!` macro, any token preceded by `$` is passed as though it were an argument\n/// with an automatically chosen fragment specifier. `$ident` will be passed as `ident`, `$1` or\n/// `$\"literal\"` will be passed as `literal`, `$'lt` will be passed as `lifetime`, and `$(...)` will\n/// pass the contained tokens as a `tt` sequence (the wrapping parenthesis are removed). If another\n/// specifier is required it can be specified within parenthesis like `$(@expr ...)`. This will\n/// expand the remaining tokens as a single argument.\n///\n/// Multiple `inline!` macros may be nested within each other. This will expand as nested macro\n/// calls. However, any arguments will be passed as though they came from the outermost context.\n#[proc_macro_attribute]\npub fn inline_macros(args: TokenStream, input: TokenStream) -> TokenStream {\n    let mut args = args.into_iter();\n    let mac_name = match args.next() {\n        Some(TT::Ident(name)) => Some(name),\n        Some(tt) => {\n            return make_error(\n                \"unexpected argument, expected either an ident or no arguments\",\n                tt.span(),\n            );\n        },\n        None => None,\n    };\n    if let Some(tt) = args.next() {\n        return make_error(\n            \"unexpected argument, expected either an ident or no arguments\",\n            tt.span(),\n        );\n    };\n\n    let mac_name = if let Some(mac_name) = mac_name {\n        Ident::new(&format!(\"__inline_mac_{mac_name}\"), Span::call_site())\n    } else {\n        let mut input = match LookaheadIter::new(input.clone().into_iter()) {\n            Some(x) => x,\n            None => return input,\n        };\n        loop {\n            match input.next() {\n                None => break Ident::new(\"__inline_mac\", Span::call_site()),\n                Some(TT::Ident(kind)) => match &*kind.to_string() {\n                    \"impl\" => break Ident::new(\"__inline_mac_impl\", Span::call_site()),\n                    kind @ (\"struct\" | \"enum\" | \"union\" | \"fn\" | \"mod\" | \"trait\" | \"type\" | \"const\" | \"static\") => {\n                        if let TT::Ident(name) = &input.tt {\n                            break Ident::new(&format!(\"__inline_mac_{kind}_{name}\"), Span::call_site());\n                        } else {\n                            break Ident::new(&format!(\"__inline_mac_{kind}\"), Span::call_site());\n                        }\n                    },\n                    _ => {},\n                },\n                _ => {},\n            }\n        }\n    };\n\n    let mut expander = Expander::default();\n    let mut mac = MacWriter::new(mac_name);\n    if let Err(e) = expander.expand(input.into_iter(), &mut mac) {\n        return e;\n    }\n    let mut out = TokenStream::new();\n    mac.finish(&mut out);\n    out.extend(expander.expn);\n    out\n}\n\n/// Wraps a `TokenStream` iterator with a single token lookahead.\nstruct LookaheadIter {\n    tt: TT,\n    iter: IntoIter,\n}\nimpl LookaheadIter {\n    fn new(mut iter: IntoIter) -> Option<Self> {\n        iter.next().map(|tt| Self { tt, iter })\n    }\n\n    /// Get's the lookahead token, replacing it with the next token in the stream.\n    /// Note: If there isn't a next token, this will not return the lookahead token.\n    fn next(&mut self) -> Option<TT> {\n        self.iter.next().map(|tt| mem::replace(&mut self.tt, tt))\n    }\n}\n\n/// Builds the macro used to implement all the `inline!` macro calls.\nstruct MacWriter {\n    name: Ident,\n    macros: TokenStream,\n    next_idx: usize,\n}\nimpl MacWriter {\n    fn new(name: Ident) -> Self {\n        Self {\n            name,\n            macros: TokenStream::new(),\n            next_idx: 0,\n        }\n    }\n\n    /// Inserts a new `inline!` call.\n    fn insert(&mut self, name_span: Span, bang_span: Span, body: Group, expander: &mut Expander) -> Result<()> {\n        let idx = self.next_idx;\n        self.next_idx += 1;\n\n        let mut inner = Expander::for_arm(idx);\n        inner.expand(body.stream().into_iter(), self)?;\n        let new_arm = inner.arm.unwrap();\n\n        self.macros.extend([\n            TT::Group(Group::new(Parenthesis, new_arm.args_def)),\n            TT::Punct(Punct::new('=', Joint)),\n            TT::Punct(Punct::new('>', Alone)),\n            TT::Group(Group::new(Parenthesis, inner.expn)),\n            TT::Punct(Punct::new(';', Alone)),\n        ]);\n\n        expander.expn.extend([\n            TT::Ident({\n                let mut name = self.name.clone();\n                name.set_span(name_span);\n                name\n            }),\n            TT::Punct(punct_with_span('!', Alone, bang_span)),\n        ]);\n        let mut call_body = TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]);\n        if let Some(arm) = expander.arm.as_mut() {\n            if !new_arm.args.is_empty() {\n                arm.add_sub_args(new_arm.args, &mut call_body);\n            }\n        } else {\n            call_body.extend(new_arm.args);\n        }\n        let mut g = Group::new(body.delimiter(), call_body);\n        g.set_span(body.span());\n        expander.expn.extend([TT::Group(g)]);\n        Ok(())\n    }\n\n    /// Creates the macro definition.\n    fn finish(self, out: &mut TokenStream) {\n        if self.next_idx != 0 {\n            out.extend([\n                TT::Ident(Ident::new(\"macro_rules\", Span::call_site())),\n                TT::Punct(Punct::new('!', Alone)),\n                TT::Ident(self.name),\n                TT::Group(Group::new(Brace, self.macros)),\n            ])\n        }\n    }\n}\n\nstruct MacroArm {\n    args_def: TokenStream,\n    args: Vec<TT>,\n}\nimpl MacroArm {\n    fn add_single_arg_def(&mut self, kind: &str, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {\n        let mut name = Ident::new(&format!(\"_{}\", self.args.len()), Span::call_site());\n        self.args_def.extend([\n            TT::Punct(Punct::new('$', Alone)),\n            TT::Ident(name.clone()),\n            TT::Punct(Punct::new(':', Alone)),\n            TT::Ident(Ident::new(kind, Span::call_site())),\n        ]);\n        name.set_span(arg_span);\n        out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]);\n    }\n\n    fn add_parenthesized_arg_def(&mut self, kind: Ident, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {\n        let mut name = Ident::new(&format!(\"_{}\", self.args.len()), Span::call_site());\n        self.args_def.extend([TT::Group(Group::new(\n            Parenthesis,\n            TokenStream::from_iter([\n                TT::Punct(Punct::new('$', Alone)),\n                TT::Ident(name.clone()),\n                TT::Punct(Punct::new(':', Alone)),\n                TT::Ident(kind),\n            ]),\n        ))]);\n        name.set_span(arg_span);\n        out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]);\n    }\n\n    fn add_multi_arg_def(&mut self, dollar_span: Span, arg_span: Span, out: &mut TokenStream) {\n        let mut name = Ident::new(&format!(\"_{}\", self.args.len()), Span::call_site());\n        self.args_def.extend([TT::Group(Group::new(\n            Parenthesis,\n            TokenStream::from_iter([\n                TT::Punct(Punct::new('$', Alone)),\n                TT::Group(Group::new(\n                    Parenthesis,\n                    TokenStream::from_iter([\n                        TT::Punct(Punct::new('$', Alone)),\n                        TT::Ident(name.clone()),\n                        TT::Punct(Punct::new(':', Alone)),\n                        TT::Ident(Ident::new(\"tt\", Span::call_site())),\n                    ]),\n                )),\n                TT::Punct(Punct::new('*', Alone)),\n            ]),\n        ))]);\n        name.set_span(arg_span);\n        out.extend([\n            TT::Punct(punct_with_span('$', Alone, dollar_span)),\n            TT::Group(group_with_span(\n                Parenthesis,\n                TokenStream::from_iter([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]),\n                dollar_span,\n            )),\n            TT::Punct(punct_with_span('*', Alone, dollar_span)),\n        ]);\n    }\n\n    fn add_arg(&mut self, dollar_span: Span, tt: TT, input: &mut IntoIter, out: &mut TokenStream) -> Result<()> {\n        match tt {\n            TT::Punct(p) if p.as_char() == ESCAPE_CHAR => out.extend([TT::Punct(p)]),\n            TT::Punct(p) if p.as_char() == '\\'' && p.spacing() == Joint => {\n                let lt_name = expect_tt(\n                    input.next(),\n                    |tt| match tt {\n                        TT::Ident(x) => Some(x),\n                        _ => None,\n                    },\n                    \"lifetime name\",\n                    p.span(),\n                )?;\n                let arg_span = p.span().join(lt_name.span()).unwrap_or(p.span());\n                self.add_single_arg_def(\"lifetime\", dollar_span, arg_span, out);\n                self.args.extend([TT::Punct(p), TT::Ident(lt_name)]);\n            },\n            TT::Ident(x) => {\n                self.add_single_arg_def(\"ident\", dollar_span, x.span(), out);\n                self.args.push(TT::Ident(x));\n            },\n            TT::Literal(x) => {\n                self.add_single_arg_def(\"literal\", dollar_span, x.span(), out);\n                self.args.push(TT::Literal(x));\n            },\n            TT::Group(g) if g.delimiter() == Parenthesis => {\n                let mut inner = g.stream().into_iter();\n                if let Some(TT::Punct(p)) = inner.next()\n                    && p.as_char() == '@'\n                {\n                    let kind = expect_tt(\n                        inner.next(),\n                        |tt| match tt {\n                            TT::Ident(kind) => Some(kind),\n                            _ => None,\n                        },\n                        \"a macro fragment specifier\",\n                        p.span(),\n                    )?;\n                    self.add_parenthesized_arg_def(kind, dollar_span, g.span(), out);\n                    self.args\n                        .push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span())))\n                } else {\n                    self.add_multi_arg_def(dollar_span, g.span(), out);\n                    self.args.push(TT::Group(g));\n                }\n            },\n            tt => return Err(make_error(\"unsupported escape\", tt.span())),\n        };\n        Ok(())\n    }\n\n    fn add_sub_args(&mut self, args: Vec<TT>, out: &mut TokenStream) {\n        self.add_multi_arg_def(Span::call_site(), Span::call_site(), out);\n        self.args\n            .extend([TT::Group(Group::new(Parenthesis, TokenStream::from_iter(args)))]);\n    }\n}\n\n#[derive(Default)]\nstruct Expander {\n    arm: Option<MacroArm>,\n    expn: TokenStream,\n}\nimpl Expander {\n    fn for_arm(idx: usize) -> Self {\n        Self {\n            arm: Some(MacroArm {\n                args_def: TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]),\n                args: Vec::new(),\n            }),\n            expn: TokenStream::new(),\n        }\n    }\n\n    fn write_tt(&mut self, tt: TT, mac: &mut MacWriter) -> Result<()> {\n        match tt {\n            TT::Group(g) => {\n                let outer = mem::take(&mut self.expn);\n                self.expand(g.stream().into_iter(), mac)?;\n                let inner = mem::replace(&mut self.expn, outer);\n                self.expn\n                    .extend([TT::Group(group_with_span(g.delimiter(), inner, g.span()))]);\n            },\n            tt => self.expn.extend([tt]),\n        }\n        Ok(())\n    }\n\n    fn expand(&mut self, input: IntoIter, mac: &mut MacWriter) -> Result<()> {\n        let Some(mut input) = LookaheadIter::new(input) else {\n            return Ok(());\n        };\n        while let Some(tt) = input.next() {\n            if let TT::Punct(p) = &tt\n                && p.as_char() == ESCAPE_CHAR\n                && let Some(arm) = self.arm.as_mut()\n            {\n                arm.add_arg(\n                    p.span(),\n                    mem::replace(&mut input.tt, tt),\n                    &mut input.iter,\n                    &mut self.expn,\n                )?;\n                if input.next().is_none() {\n                    return Ok(());\n                }\n            } else if let TT::Punct(p) = &input.tt\n                && p.as_char() == '!'\n                && let TT::Ident(name) = &tt\n                && name.to_string() == \"inline\"\n            {\n                let g = expect_tt(\n                    input.iter.next(),\n                    |tt| match tt {\n                        TT::Group(g) => Some(g),\n                        _ => None,\n                    },\n                    \"macro arguments\",\n                    p.span(),\n                )?;\n                mac.insert(name.span(), p.span(), g, self)?;\n                if input.next().is_none() {\n                    return Ok(());\n                }\n            } else {\n                self.write_tt(tt, mac)?;\n            }\n        }\n        self.write_tt(input.tt, mac)\n    }\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/test_macro.rs",
    "content": "pub trait A {}\n\nmacro_rules! __implicit_hasher_test_macro {\n    (impl< $($impl_arg:tt),* > for $kind:ty where $($bounds:tt)*) => {\n        __implicit_hasher_test_macro!( ($($impl_arg),*) ($kind) ($($bounds)*) );\n    };\n\n    (($($impl_arg:tt)*) ($($kind_arg:tt)*) ($($bounds:tt)*)) => {\n        impl< $($impl_arg)* > test_macro::A for $($kind_arg)* where $($bounds)* { }\n    };\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/use_self_macro.rs",
    "content": "macro_rules! use_self {\n    (\n        impl $ty:ident {\n            fn func(&$this:ident) {\n                [fields($($field:ident)*)]\n            }\n        }\n    ) => (\n        impl  $ty {\n            fn func(&$this) {\n                let $ty { $($field),* } = $this;\n            }\n        }\n    )\n}\n"
  },
  {
    "path": "tests/ui/auxiliary/wildcard_imports_helper.rs",
    "content": "pub use crate::extern_exports::*;\n\npub fn extern_foo() {}\npub fn extern_bar() {}\n\npub struct ExternA;\n\npub mod inner {\n    pub mod inner_for_self_import {\n        pub fn inner_extern_foo() {}\n        pub fn inner_extern_bar() {}\n    }\n}\n\nmod extern_exports {\n    pub fn extern_exported() {}\n    pub struct ExternExportedStruct;\n    pub enum ExternExportedEnum {\n        A,\n    }\n}\n\npub mod prelude {\n    pub mod v1 {\n        pub struct PreludeModAnywhere;\n    }\n}\n\npub mod extern_prelude {\n    pub mod v1 {\n        pub struct ExternPreludeModAnywhere;\n    }\n}\n"
  },
  {
    "path": "tests/ui/await_holding_lock.rs",
    "content": "#![warn(clippy::await_holding_lock)]\n#![allow(clippy::readonly_write_lock)]\n\n// When adding or modifying a test, please do the same for parking_lot::Mutex.\nmod std_mutex {\n    use super::baz;\n    use std::sync::{Mutex, RwLock};\n\n    pub async fn bad(x: &Mutex<u32>) -> u32 {\n        let guard = x.lock().unwrap();\n        //~^ ERROR: this `MutexGuard` is held across an await point\n        baz().await\n    }\n\n    pub async fn good(x: &Mutex<u32>) -> u32 {\n        {\n            let guard = x.lock().unwrap();\n            let y = *guard + 1;\n        }\n        baz().await;\n        let guard = x.lock().unwrap();\n        47\n    }\n\n    pub async fn bad_rw(x: &RwLock<u32>) -> u32 {\n        let guard = x.read().unwrap();\n        //~^ ERROR: this `MutexGuard` is held across an await point\n        baz().await\n    }\n\n    pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {\n        let mut guard = x.write().unwrap();\n        //~^ ERROR: this `MutexGuard` is held across an await point\n        baz().await\n    }\n\n    pub async fn good_rw(x: &RwLock<u32>) -> u32 {\n        {\n            let guard = x.read().unwrap();\n            let y = *guard + 1;\n        }\n        {\n            let mut guard = x.write().unwrap();\n            *guard += 1;\n        }\n        baz().await;\n        let guard = x.read().unwrap();\n        47\n    }\n\n    pub async fn also_bad(x: &Mutex<u32>) -> u32 {\n        let first = baz().await;\n\n        let guard = x.lock().unwrap();\n        //~^ ERROR: this `MutexGuard` is held across an await point\n\n        let second = baz().await;\n\n        let third = baz().await;\n\n        first + second + third\n    }\n\n    pub async fn not_good(x: &Mutex<u32>) -> u32 {\n        let first = baz().await;\n\n        let second = {\n            let guard = x.lock().unwrap();\n            //~^ ERROR: this `MutexGuard` is held across an await point\n            baz().await\n        };\n\n        let third = baz().await;\n\n        first + second + third\n    }\n\n    #[allow(clippy::manual_async_fn)]\n    pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {\n        async move {\n            let guard = x.lock().unwrap();\n            //~^ ERROR: this `MutexGuard` is held across an await point\n            baz().await\n        }\n    }\n}\n\n// When adding or modifying a test, please do the same for std::Mutex.\nmod parking_lot_mutex {\n    use super::baz;\n    use parking_lot::{Mutex, RwLock};\n\n    pub async fn bad(x: &Mutex<u32>) -> u32 {\n        let guard = x.lock();\n        //~^ ERROR: this `MutexGuard` is held across an await point\n        baz().await\n    }\n\n    pub async fn good(x: &Mutex<u32>) -> u32 {\n        {\n            let guard = x.lock();\n            let y = *guard + 1;\n        }\n        baz().await;\n        let guard = x.lock();\n        47\n    }\n\n    pub async fn bad_rw(x: &RwLock<u32>) -> u32 {\n        let guard = x.read();\n        //~^ ERROR: this `MutexGuard` is held across an await point\n        baz().await\n    }\n\n    pub async fn bad_rw_write(x: &RwLock<u32>) -> u32 {\n        let mut guard = x.write();\n        //~^ ERROR: this `MutexGuard` is held across an await point\n        baz().await\n    }\n\n    pub async fn good_rw(x: &RwLock<u32>) -> u32 {\n        {\n            let guard = x.read();\n            let y = *guard + 1;\n        }\n        {\n            let mut guard = x.write();\n            *guard += 1;\n        }\n        baz().await;\n        let guard = x.read();\n        47\n    }\n\n    pub async fn also_bad(x: &Mutex<u32>) -> u32 {\n        let first = baz().await;\n\n        let guard = x.lock();\n        //~^ ERROR: this `MutexGuard` is held across an await point\n\n        let second = baz().await;\n\n        let third = baz().await;\n\n        first + second + third\n    }\n\n    pub async fn not_good(x: &Mutex<u32>) -> u32 {\n        let first = baz().await;\n\n        let second = {\n            let guard = x.lock();\n            //~^ ERROR: this `MutexGuard` is held across an await point\n            baz().await\n        };\n\n        let third = baz().await;\n\n        first + second + third\n    }\n\n    #[allow(clippy::manual_async_fn)]\n    pub fn block_bad(x: &Mutex<u32>) -> impl std::future::Future<Output = u32> + '_ {\n        async move {\n            let guard = x.lock();\n            //~^ ERROR: this `MutexGuard` is held across an await point\n            baz().await\n        }\n    }\n}\n\nasync fn baz() -> u32 {\n    42\n}\n\nasync fn no_await(x: std::sync::Mutex<u32>) {\n    let mut guard = x.lock().unwrap();\n    *guard += 1;\n}\n\n// FIXME: FP, because the `MutexGuard` is dropped before crossing the await point. This is\n// something the needs to be fixed in rustc. There's already drop-tracking, but this is currently\n// disabled, see rust-lang/rust#93751. This case isn't picked up by drop-tracking though. If the\n// `*guard += 1` is removed it is picked up.\nasync fn dropped_before_await(x: std::sync::Mutex<u32>) {\n    let mut guard = x.lock().unwrap();\n    //~^ ERROR: this `MutexGuard` is held across an await point\n    *guard += 1;\n    drop(guard);\n    baz().await;\n}\n\nfn main() {\n    let m = std::sync::Mutex::new(100);\n    std_mutex::good(&m);\n    std_mutex::bad(&m);\n    std_mutex::also_bad(&m);\n    std_mutex::not_good(&m);\n    std_mutex::block_bad(&m);\n\n    let m = parking_lot::Mutex::new(100);\n    parking_lot_mutex::good(&m);\n    parking_lot_mutex::bad(&m);\n    parking_lot_mutex::also_bad(&m);\n    parking_lot_mutex::not_good(&m);\n}\n"
  },
  {
    "path": "tests/ui/await_holding_lock.stderr",
    "content": "error: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:10:13\n   |\nLL |         let guard = x.lock().unwrap();\n   |             ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:12:15\n   |\nLL |         baz().await\n   |               ^^^^^\n   = note: `-D clippy::await-holding-lock` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::await_holding_lock)]`\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:26:13\n   |\nLL |         let guard = x.read().unwrap();\n   |             ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:28:15\n   |\nLL |         baz().await\n   |               ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:32:13\n   |\nLL |         let mut guard = x.write().unwrap();\n   |             ^^^^^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:34:15\n   |\nLL |         baz().await\n   |               ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:54:13\n   |\nLL |         let guard = x.lock().unwrap();\n   |             ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:57:28\n   |\nLL |         let second = baz().await;\n   |                            ^^^^^\nLL |\nLL |         let third = baz().await;\n   |                           ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:68:17\n   |\nLL |             let guard = x.lock().unwrap();\n   |                 ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:70:19\n   |\nLL |             baz().await\n   |                   ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:81:17\n   |\nLL |             let guard = x.lock().unwrap();\n   |                 ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:83:19\n   |\nLL |             baz().await\n   |                   ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:94:13\n   |\nLL |         let guard = x.lock();\n   |             ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:96:15\n   |\nLL |         baz().await\n   |               ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:110:13\n   |\nLL |         let guard = x.read();\n   |             ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:112:15\n   |\nLL |         baz().await\n   |               ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:116:13\n   |\nLL |         let mut guard = x.write();\n   |             ^^^^^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:118:15\n   |\nLL |         baz().await\n   |               ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:138:13\n   |\nLL |         let guard = x.lock();\n   |             ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:141:28\n   |\nLL |         let second = baz().await;\n   |                            ^^^^^\nLL |\nLL |         let third = baz().await;\n   |                           ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:152:17\n   |\nLL |             let guard = x.lock();\n   |                 ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:154:19\n   |\nLL |             baz().await\n   |                   ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:165:17\n   |\nLL |             let guard = x.lock();\n   |                 ^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:167:19\n   |\nLL |             baz().await\n   |                   ^^^^^\n\nerror: this `MutexGuard` is held across an await point\n  --> tests/ui/await_holding_lock.rs:186:9\n   |\nLL |     let mut guard = x.lock().unwrap();\n   |         ^^^^^^^^^\n   |\n   = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling `await`\nnote: these are all the await points this lock is held through\n  --> tests/ui/await_holding_lock.rs:190:11\n   |\nLL |     baz().await;\n   |           ^^^^^\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/await_holding_refcell_ref.rs",
    "content": "#![warn(clippy::await_holding_refcell_ref)]\n\nuse std::cell::RefCell;\n\nasync fn bad(x: &RefCell<u32>) -> u32 {\n    let b = x.borrow();\n    //~^ await_holding_refcell_ref\n\n    baz().await\n}\n\nasync fn bad_mut(x: &RefCell<u32>) -> u32 {\n    let b = x.borrow_mut();\n    //~^ await_holding_refcell_ref\n\n    baz().await\n}\n\nasync fn good(x: &RefCell<u32>) -> u32 {\n    {\n        let b = x.borrow_mut();\n        let y = *b + 1;\n    }\n    baz().await;\n    let b = x.borrow_mut();\n    47\n}\n\nasync fn baz() -> u32 {\n    42\n}\n\nasync fn also_bad(x: &RefCell<u32>) -> u32 {\n    let first = baz().await;\n\n    let b = x.borrow_mut();\n    //~^ await_holding_refcell_ref\n\n    let second = baz().await;\n\n    let third = baz().await;\n\n    first + second + third\n}\n\nasync fn less_bad(x: &RefCell<u32>) -> u32 {\n    let first = baz().await;\n\n    let b = x.borrow_mut();\n    //~^ await_holding_refcell_ref\n\n    let second = baz().await;\n\n    drop(b);\n\n    let third = baz().await;\n\n    first + second + third\n}\n\nasync fn not_good(x: &RefCell<u32>) -> u32 {\n    let first = baz().await;\n\n    let second = {\n        let b = x.borrow_mut();\n        //~^ await_holding_refcell_ref\n\n        baz().await\n    };\n\n    let third = baz().await;\n\n    first + second + third\n}\n\n#[allow(clippy::manual_async_fn)]\nfn block_bad(x: &RefCell<u32>) -> impl std::future::Future<Output = u32> + '_ {\n    async move {\n        let b = x.borrow_mut();\n        //~^ await_holding_refcell_ref\n\n        baz().await\n    }\n}\n\nfn main() {\n    let rc = RefCell::new(100);\n    good(&rc);\n    bad(&rc);\n    bad_mut(&rc);\n    also_bad(&rc);\n    less_bad(&rc);\n    not_good(&rc);\n    block_bad(&rc);\n}\n"
  },
  {
    "path": "tests/ui/await_holding_refcell_ref.stderr",
    "content": "error: this `RefCell` reference is held across an await point\n  --> tests/ui/await_holding_refcell_ref.rs:6:9\n   |\nLL |     let b = x.borrow();\n   |         ^\n   |\n   = help: ensure the reference is dropped before calling `await`\nnote: these are all the await points this reference is held through\n  --> tests/ui/await_holding_refcell_ref.rs:9:11\n   |\nLL |     baz().await\n   |           ^^^^^\n   = note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::await_holding_refcell_ref)]`\n\nerror: this `RefCell` reference is held across an await point\n  --> tests/ui/await_holding_refcell_ref.rs:13:9\n   |\nLL |     let b = x.borrow_mut();\n   |         ^\n   |\n   = help: ensure the reference is dropped before calling `await`\nnote: these are all the await points this reference is held through\n  --> tests/ui/await_holding_refcell_ref.rs:16:11\n   |\nLL |     baz().await\n   |           ^^^^^\n\nerror: this `RefCell` reference is held across an await point\n  --> tests/ui/await_holding_refcell_ref.rs:36:9\n   |\nLL |     let b = x.borrow_mut();\n   |         ^\n   |\n   = help: ensure the reference is dropped before calling `await`\nnote: these are all the await points this reference is held through\n  --> tests/ui/await_holding_refcell_ref.rs:39:24\n   |\nLL |     let second = baz().await;\n   |                        ^^^^^\nLL |\nLL |     let third = baz().await;\n   |                       ^^^^^\n\nerror: this `RefCell` reference is held across an await point\n  --> tests/ui/await_holding_refcell_ref.rs:49:9\n   |\nLL |     let b = x.borrow_mut();\n   |         ^\n   |\n   = help: ensure the reference is dropped before calling `await`\nnote: these are all the await points this reference is held through\n  --> tests/ui/await_holding_refcell_ref.rs:52:24\n   |\nLL |     let second = baz().await;\n   |                        ^^^^^\n\nerror: this `RefCell` reference is held across an await point\n  --> tests/ui/await_holding_refcell_ref.rs:65:13\n   |\nLL |         let b = x.borrow_mut();\n   |             ^\n   |\n   = help: ensure the reference is dropped before calling `await`\nnote: these are all the await points this reference is held through\n  --> tests/ui/await_holding_refcell_ref.rs:68:15\n   |\nLL |         baz().await\n   |               ^^^^^\n\nerror: this `RefCell` reference is held across an await point\n  --> tests/ui/await_holding_refcell_ref.rs:79:13\n   |\nLL |         let b = x.borrow_mut();\n   |             ^\n   |\n   = help: ensure the reference is dropped before calling `await`\nnote: these are all the await points this reference is held through\n  --> tests/ui/await_holding_refcell_ref.rs:82:15\n   |\nLL |         baz().await\n   |               ^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/bind_instead_of_map.fixed",
    "content": "#![deny(clippy::bind_instead_of_map)]\n\n// need a main anyway, use it get rid of unused warnings too\npub fn main() {\n    let x = Some(5);\n    // the easiest cases\n    let _ = x;\n    //~^ bind_instead_of_map\n    let _ = x.map(|o| o + 1);\n    //~^ bind_instead_of_map\n    // and an easy counter-example\n    let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });\n\n    // Different type\n    let x: Result<u32, &str> = Ok(1);\n    let _ = x;\n    //~^ bind_instead_of_map\n}\n\npub fn foo() -> Option<String> {\n    let x = Some(String::from(\"hello\"));\n    Some(\"hello\".to_owned()).and_then(|s| Some(format!(\"{}{}\", s, x?)))\n}\n\npub fn example2(x: bool) -> Option<&'static str> {\n    Some(\"a\").and_then(|s| Some(if x { s } else { return None }))\n}\n"
  },
  {
    "path": "tests/ui/bind_instead_of_map.rs",
    "content": "#![deny(clippy::bind_instead_of_map)]\n\n// need a main anyway, use it get rid of unused warnings too\npub fn main() {\n    let x = Some(5);\n    // the easiest cases\n    let _ = x.and_then(Some);\n    //~^ bind_instead_of_map\n    let _ = x.and_then(|o| Some(o + 1));\n    //~^ bind_instead_of_map\n    // and an easy counter-example\n    let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });\n\n    // Different type\n    let x: Result<u32, &str> = Ok(1);\n    let _ = x.and_then(Ok);\n    //~^ bind_instead_of_map\n}\n\npub fn foo() -> Option<String> {\n    let x = Some(String::from(\"hello\"));\n    Some(\"hello\".to_owned()).and_then(|s| Some(format!(\"{}{}\", s, x?)))\n}\n\npub fn example2(x: bool) -> Option<&'static str> {\n    Some(\"a\").and_then(|s| Some(if x { s } else { return None }))\n}\n"
  },
  {
    "path": "tests/ui/bind_instead_of_map.stderr",
    "content": "error: using `Option.and_then(Some)`, which is a no-op\n  --> tests/ui/bind_instead_of_map.rs:7:13\n   |\nLL |     let _ = x.and_then(Some);\n   |             ^^^^^^^^^^^^^^^^ help: use the expression directly: `x`\n   |\nnote: the lint level is defined here\n  --> tests/ui/bind_instead_of_map.rs:1:9\n   |\nLL | #![deny(clippy::bind_instead_of_map)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`\n  --> tests/ui/bind_instead_of_map.rs:9:13\n   |\nLL |     let _ = x.and_then(|o| Some(o + 1));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map(|o| o + 1)`\n\nerror: using `Result.and_then(Ok)`, which is a no-op\n  --> tests/ui/bind_instead_of_map.rs:16:13\n   |\nLL |     let _ = x.and_then(Ok);\n   |             ^^^^^^^^^^^^^^ help: use the expression directly: `x`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/bind_instead_of_map_multipart.fixed",
    "content": "#![deny(clippy::bind_instead_of_map)]\n#![allow(clippy::blocks_in_conditions)]\n\npub fn main() {\n    let _ = Some(\"42\").map(|s| if s.len() < 42 { 0 } else { s.len() });\n    //~^ bind_instead_of_map\n    let _ = Some(\"42\").and_then(|s| if s.len() < 42 { None } else { Some(s.len()) });\n\n    let _ = Ok::<_, ()>(\"42\").map(|s| if s.len() < 42 { 0 } else { s.len() });\n    //~^ bind_instead_of_map\n    let _ = Ok::<_, ()>(\"42\").and_then(|s| if s.len() < 42 { Err(()) } else { Ok(s.len()) });\n\n    let _ = Err::<(), _>(\"42\").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() });\n    //~^ bind_instead_of_map\n    let _ = Err::<(), _>(\"42\").or_else(|s| if s.len() < 42 { Ok(()) } else { Err(s.len()) });\n\n    hard_example();\n    macro_example();\n}\n\nfn hard_example() {\n    Some(\"42\").map(|s| {\n        //~^ bind_instead_of_map\n        if {\n            if s == \"43\" {\n                return 43;\n            }\n            s == \"42\"\n        } {\n            return 45;\n        }\n        match s.len() {\n            10 => 2,\n            20 => {\n                if foo() {\n                    return {\n                        if foo() {\n                            return 20;\n                        }\n                        println!(\"foo\");\n                        3\n                    };\n                }\n                20\n            },\n            40 => 30,\n            _ => 1,\n        }\n    });\n}\n\nfn foo() -> bool {\n    true\n}\n\nmacro_rules! m {\n    () => {\n        Some(10)\n    };\n}\n\nfn macro_example() {\n    let _ = Some(\"\").and_then(|s| if s.len() == 20 { m!() } else { Some(20) });\n    let _ = Some(\"\").map(|s| if s.len() == 20 { m!() } else { Some(20) });\n    //~^ bind_instead_of_map\n}\n"
  },
  {
    "path": "tests/ui/bind_instead_of_map_multipart.rs",
    "content": "#![deny(clippy::bind_instead_of_map)]\n#![allow(clippy::blocks_in_conditions)]\n\npub fn main() {\n    let _ = Some(\"42\").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });\n    //~^ bind_instead_of_map\n    let _ = Some(\"42\").and_then(|s| if s.len() < 42 { None } else { Some(s.len()) });\n\n    let _ = Ok::<_, ()>(\"42\").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) });\n    //~^ bind_instead_of_map\n    let _ = Ok::<_, ()>(\"42\").and_then(|s| if s.len() < 42 { Err(()) } else { Ok(s.len()) });\n\n    let _ = Err::<(), _>(\"42\").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) });\n    //~^ bind_instead_of_map\n    let _ = Err::<(), _>(\"42\").or_else(|s| if s.len() < 42 { Ok(()) } else { Err(s.len()) });\n\n    hard_example();\n    macro_example();\n}\n\nfn hard_example() {\n    Some(\"42\").and_then(|s| {\n        //~^ bind_instead_of_map\n        if {\n            if s == \"43\" {\n                return Some(43);\n            }\n            s == \"42\"\n        } {\n            return Some(45);\n        }\n        match s.len() {\n            10 => Some(2),\n            20 => {\n                if foo() {\n                    return {\n                        if foo() {\n                            return Some(20);\n                        }\n                        println!(\"foo\");\n                        Some(3)\n                    };\n                }\n                Some(20)\n            },\n            40 => Some(30),\n            _ => Some(1),\n        }\n    });\n}\n\nfn foo() -> bool {\n    true\n}\n\nmacro_rules! m {\n    () => {\n        Some(10)\n    };\n}\n\nfn macro_example() {\n    let _ = Some(\"\").and_then(|s| if s.len() == 20 { m!() } else { Some(20) });\n    let _ = Some(\"\").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) });\n    //~^ bind_instead_of_map\n}\n"
  },
  {
    "path": "tests/ui/bind_instead_of_map_multipart.stderr",
    "content": "error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`\n  --> tests/ui/bind_instead_of_map_multipart.rs:5:13\n   |\nLL |     let _ = Some(\"42\").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/bind_instead_of_map_multipart.rs:1:9\n   |\nLL | #![deny(clippy::bind_instead_of_map)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: use `map` instead\n   |\nLL -     let _ = Some(\"42\").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });\nLL +     let _ = Some(\"42\").map(|s| if s.len() < 42 { 0 } else { s.len() });\n   |\n\nerror: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)`\n  --> tests/ui/bind_instead_of_map_multipart.rs:9:13\n   |\nLL |     let _ = Ok::<_, ()>(\"42\").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) });\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map` instead\n   |\nLL -     let _ = Ok::<_, ()>(\"42\").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) });\nLL +     let _ = Ok::<_, ()>(\"42\").map(|s| if s.len() < 42 { 0 } else { s.len() });\n   |\n\nerror: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)`\n  --> tests/ui/bind_instead_of_map_multipart.rs:13:13\n   |\nLL |     let _ = Err::<(), _>(\"42\").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) });\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map_err` instead\n   |\nLL -     let _ = Err::<(), _>(\"42\").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) });\nLL +     let _ = Err::<(), _>(\"42\").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() });\n   |\n\nerror: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`\n  --> tests/ui/bind_instead_of_map_multipart.rs:22:5\n   |\nLL | /     Some(\"42\").and_then(|s| {\nLL | |\nLL | |         if {\nLL | |             if s == \"43\" {\n...  |\nLL | |     });\n   | |______^\n   |\nhelp: use `map` instead\n   |\nLL ~     Some(\"42\").map(|s| {\nLL |\nLL |         if {\nLL |             if s == \"43\" {\nLL ~                 return 43;\nLL |             }\nLL |             s == \"42\"\nLL |         } {\nLL ~             return 45;\nLL |         }\nLL |         match s.len() {\nLL ~             10 => 2,\nLL |             20 => {\n...\nLL |                         if foo() {\nLL ~                             return 20;\nLL |                         }\nLL |                         println!(\"foo\");\nLL ~                         3\nLL |                     };\nLL |                 }\nLL ~                 20\nLL |             },\nLL ~             40 => 30,\nLL ~             _ => 1,\n   |\n\nerror: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`\n  --> tests/ui/bind_instead_of_map_multipart.rs:64:13\n   |\nLL |     let _ = Some(\"\").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) });\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map` instead\n   |\nLL -     let _ = Some(\"\").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) });\nLL +     let _ = Some(\"\").map(|s| if s.len() == 20 { m!() } else { Some(20) });\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/bit_masks.rs",
    "content": "const THREE_BITS: i64 = 7;\nconst EVEN_MORE_REDIRECTION: i64 = THREE_BITS;\n\n#[warn(clippy::bad_bit_mask)]\n#[allow(\n    clippy::ineffective_bit_mask,\n    clippy::identity_op,\n    clippy::no_effect,\n    clippy::unnecessary_operation\n)]\nfn main() {\n    let x = 5;\n\n    x & 0 == 0;\n    //~^ bad_bit_mask\n    //~| erasing_op\n\n    x & 1 == 1; //ok, distinguishes bit 0\n    x & 1 == 0; //ok, compared with zero\n    x & 2 == 1;\n    //~^ bad_bit_mask\n\n    x | 0 == 0; //ok, equals x == 0 (maybe warn?)\n    x | 1 == 3; //ok, equals x == 2 || x == 3\n    x | 3 == 3; //ok, equals x <= 3\n    x | 3 == 2;\n    //~^ bad_bit_mask\n\n    x & 1 > 1;\n    //~^ bad_bit_mask\n\n    x & 2 > 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0\n    x & 2 < 1; // ok, distinguishes x & 2 == 2 from x & 2 == 0\n    x | 1 > 1; // ok (if a bit silly), equals x > 1\n    x | 2 > 1;\n    //~^ bad_bit_mask\n\n    x | 2 <= 2; // ok (if a bit silly), equals x <= 2\n\n    x & 192 == 128; // ok, tests for bit 7 and not bit 6\n    x & 0xffc0 == 0xfe80; // ok\n\n    // this also now works with constants\n    x & THREE_BITS == 8;\n    //~^ bad_bit_mask\n\n    x | EVEN_MORE_REDIRECTION < 7;\n    //~^ bad_bit_mask\n\n    0 & x == 0;\n    //~^ bad_bit_mask\n    //~| erasing_op\n\n    1 | x > 1;\n\n    // and should now also match uncommon usage\n    1 < 2 | x;\n    //~^ bad_bit_mask\n\n    2 == 3 | x;\n    //~^ bad_bit_mask\n\n    1 == x & 2;\n    //~^ bad_bit_mask\n\n    x | 1 > 2; // no error, because we allowed ineffective bit masks\n    ineffective();\n}\n\n#[warn(clippy::ineffective_bit_mask)]\n#[allow(clippy::bad_bit_mask, clippy::no_effect, clippy::unnecessary_operation)]\nfn ineffective() {\n    let x = 5;\n\n    x | 1 > 3;\n    //~^ ineffective_bit_mask\n\n    x | 1 < 4;\n    //~^ ineffective_bit_mask\n\n    x | 1 <= 3;\n    //~^ ineffective_bit_mask\n\n    x | 1 >= 8;\n    //~^ ineffective_bit_mask\n\n    x | 1 > 2; // not an error (yet), better written as x >= 2\n    x | 1 >= 7; // not an error (yet), better written as x >= 6\n    x | 3 > 4; // not an error (yet), better written as x >= 4\n    x | 4 <= 19;\n}\n"
  },
  {
    "path": "tests/ui/bit_masks.stderr",
    "content": "error: &-masking with zero\n  --> tests/ui/bit_masks.rs:14:5\n   |\nLL |     x & 0 == 0;\n   |     ^^^^^^^^^^\n   |\n   = note: `-D clippy::bad-bit-mask` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::bad_bit_mask)]`\n\nerror: this operation will always return zero. This is likely not the intended outcome\n  --> tests/ui/bit_masks.rs:14:5\n   |\nLL |     x & 0 == 0;\n   |     ^^^^^\n   |\n   = note: `#[deny(clippy::erasing_op)]` on by default\n\nerror: incompatible bit mask: `_ & 2` can never be equal to `1`\n  --> tests/ui/bit_masks.rs:20:5\n   |\nLL |     x & 2 == 1;\n   |     ^^^^^^^^^^\n\nerror: incompatible bit mask: `_ | 3` can never be equal to `2`\n  --> tests/ui/bit_masks.rs:26:5\n   |\nLL |     x | 3 == 2;\n   |     ^^^^^^^^^^\n\nerror: incompatible bit mask: `_ & 1` will never be higher than `1`\n  --> tests/ui/bit_masks.rs:29:5\n   |\nLL |     x & 1 > 1;\n   |     ^^^^^^^^^\n\nerror: incompatible bit mask: `_ | 2` will always be higher than `1`\n  --> tests/ui/bit_masks.rs:35:5\n   |\nLL |     x | 2 > 1;\n   |     ^^^^^^^^^\n\nerror: incompatible bit mask: `_ & 7` can never be equal to `8`\n  --> tests/ui/bit_masks.rs:44:5\n   |\nLL |     x & THREE_BITS == 8;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: incompatible bit mask: `_ | 7` will never be lower than `7`\n  --> tests/ui/bit_masks.rs:47:5\n   |\nLL |     x | EVEN_MORE_REDIRECTION < 7;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: &-masking with zero\n  --> tests/ui/bit_masks.rs:50:5\n   |\nLL |     0 & x == 0;\n   |     ^^^^^^^^^^\n\nerror: this operation will always return zero. This is likely not the intended outcome\n  --> tests/ui/bit_masks.rs:50:5\n   |\nLL |     0 & x == 0;\n   |     ^^^^^\n\nerror: incompatible bit mask: `_ | 2` will always be higher than `1`\n  --> tests/ui/bit_masks.rs:57:5\n   |\nLL |     1 < 2 | x;\n   |     ^^^^^^^^^\n\nerror: incompatible bit mask: `_ | 3` can never be equal to `2`\n  --> tests/ui/bit_masks.rs:60:5\n   |\nLL |     2 == 3 | x;\n   |     ^^^^^^^^^^\n\nerror: incompatible bit mask: `_ & 2` can never be equal to `1`\n  --> tests/ui/bit_masks.rs:63:5\n   |\nLL |     1 == x & 2;\n   |     ^^^^^^^^^^\n\nerror: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly\n  --> tests/ui/bit_masks.rs:75:5\n   |\nLL |     x | 1 > 3;\n   |     ^^^^^^^^^\n   |\n   = note: `-D clippy::ineffective-bit-mask` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ineffective_bit_mask)]`\n\nerror: ineffective bit mask: `x | 1` compared to `4`, is the same as x compared directly\n  --> tests/ui/bit_masks.rs:78:5\n   |\nLL |     x | 1 < 4;\n   |     ^^^^^^^^^\n\nerror: ineffective bit mask: `x | 1` compared to `3`, is the same as x compared directly\n  --> tests/ui/bit_masks.rs:81:5\n   |\nLL |     x | 1 <= 3;\n   |     ^^^^^^^^^^\n\nerror: ineffective bit mask: `x | 1` compared to `8`, is the same as x compared directly\n  --> tests/ui/bit_masks.rs:84:5\n   |\nLL |     x | 1 >= 8;\n   |     ^^^^^^^^^^\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/blanket_clippy_restriction_lints.rs",
    "content": "//@compile-flags: -W clippy::restriction\n//@error-in-other-file: restriction\n\n#![warn(clippy::blanket_clippy_restriction_lints)]\n\n//! Test that the whole restriction group is not enabled.\n#![warn(clippy::restriction)]\n//~^ blanket_clippy_restriction_lints\n#![deny(clippy::restriction)]\n//~^ blanket_clippy_restriction_lints\n#![forbid(clippy::restriction)]\n//~^ blanket_clippy_restriction_lints\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/blanket_clippy_restriction_lints.stderr",
    "content": "error: `clippy::restriction` is not meant to be enabled as a group\n   |\n   = note: because of the command line `--warn clippy::restriction`\n   = help: enable the restriction lints you need individually\n   = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::blanket_clippy_restriction_lints)]`\n\nerror: `clippy::restriction` is not meant to be enabled as a group\n  --> tests/ui/blanket_clippy_restriction_lints.rs:7:9\n   |\nLL | #![warn(clippy::restriction)]\n   |         ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: enable the restriction lints you need individually\n\nerror: `clippy::restriction` is not meant to be enabled as a group\n  --> tests/ui/blanket_clippy_restriction_lints.rs:9:9\n   |\nLL | #![deny(clippy::restriction)]\n   |         ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: enable the restriction lints you need individually\n\nerror: `clippy::restriction` is not meant to be enabled as a group\n  --> tests/ui/blanket_clippy_restriction_lints.rs:11:11\n   |\nLL | #![forbid(clippy::restriction)]\n   |           ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: enable the restriction lints you need individually\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/blocks_in_conditions.fixed",
    "content": "//@aux-build:proc_macro_attr.rs\n\n#![warn(clippy::blocks_in_conditions)]\n#![allow(\n    unused,\n    unnecessary_transmutes,\n    clippy::needless_ifs,\n    clippy::missing_transmute_annotations\n)]\n#![warn(clippy::nonminimal_bool)]\n\nmacro_rules! blocky {\n    () => {{ true }};\n}\n\nmacro_rules! blocky_too {\n    () => {{\n        let r = true;\n        r\n    }};\n}\n\nfn macro_if() {\n    if blocky!() {}\n\n    if blocky_too!() {}\n}\n\nfn condition_has_block() -> i32 {\n    let res = {\n        //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`\n        let x = 3;\n        x == 3\n    }; if res {\n        6\n    } else {\n        10\n    }\n}\n\nfn condition_has_block_with_single_expression() -> i32 {\n    if true { 6 } else { 10 }\n    //~^ ERROR: omit braces around single expression condition\n}\n\nfn condition_is_normal() -> i32 {\n    let x = 3;\n    if x == 3 { 6 } else { 10 }\n    //~^ nonminimal_bool\n}\n\nfn condition_is_unsafe_block() {\n    let a: i32 = 1;\n\n    // this should not warn because the condition is an unsafe block\n    if unsafe { 1u32 == std::mem::transmute(a) } {\n        println!(\"1u32 == a\");\n    }\n}\n\nfn block_in_assert() {\n    let opt = Some(42);\n    assert!(\n        opt.as_ref()\n            .map(|val| {\n                let mut v = val * 2;\n                v -= 1;\n                v * 3\n            })\n            .is_some()\n    );\n}\n\n// issue #12162\nmacro_rules! timed {\n    ($name:expr, $body:expr $(,)?) => {{\n        let __scope = ();\n        $body\n    }};\n}\n\nfn issue_12162() {\n    if timed!(\"check this!\", false) {\n        println!();\n    }\n}\n\nmod issue_12016 {\n    #[proc_macro_attr::fake_desugar_await]\n    pub async fn await_becomes_block() -> i32 {\n        match Some(1).await {\n            Some(1) => 2,\n            Some(2) => 3,\n            _ => 0,\n        }\n    }\n}\n\nfn issue_9911() {\n    if { return } {}\n\n    let a = 1;\n    if { if a == 1 { return } else { true } } {}\n}\n\nfn in_closure() {\n    let v = vec![1, 2, 3];\n    if v.into_iter()\n        .filter(|x| {\n            let y = x + 1;\n            y > 3\n        })\n        .any(|x| x == 5)\n    {\n        println!(\"contains 4!\");\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/blocks_in_conditions.rs",
    "content": "//@aux-build:proc_macro_attr.rs\n\n#![warn(clippy::blocks_in_conditions)]\n#![allow(\n    unused,\n    unnecessary_transmutes,\n    clippy::needless_ifs,\n    clippy::missing_transmute_annotations\n)]\n#![warn(clippy::nonminimal_bool)]\n\nmacro_rules! blocky {\n    () => {{ true }};\n}\n\nmacro_rules! blocky_too {\n    () => {{\n        let r = true;\n        r\n    }};\n}\n\nfn macro_if() {\n    if blocky!() {}\n\n    if blocky_too!() {}\n}\n\nfn condition_has_block() -> i32 {\n    if {\n        //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`\n        let x = 3;\n        x == 3\n    } {\n        6\n    } else {\n        10\n    }\n}\n\nfn condition_has_block_with_single_expression() -> i32 {\n    if { true } { 6 } else { 10 }\n    //~^ ERROR: omit braces around single expression condition\n}\n\nfn condition_is_normal() -> i32 {\n    let x = 3;\n    if true && x == 3 { 6 } else { 10 }\n    //~^ nonminimal_bool\n}\n\nfn condition_is_unsafe_block() {\n    let a: i32 = 1;\n\n    // this should not warn because the condition is an unsafe block\n    if unsafe { 1u32 == std::mem::transmute(a) } {\n        println!(\"1u32 == a\");\n    }\n}\n\nfn block_in_assert() {\n    let opt = Some(42);\n    assert!(\n        opt.as_ref()\n            .map(|val| {\n                let mut v = val * 2;\n                v -= 1;\n                v * 3\n            })\n            .is_some()\n    );\n}\n\n// issue #12162\nmacro_rules! timed {\n    ($name:expr, $body:expr $(,)?) => {{\n        let __scope = ();\n        $body\n    }};\n}\n\nfn issue_12162() {\n    if timed!(\"check this!\", false) {\n        println!();\n    }\n}\n\nmod issue_12016 {\n    #[proc_macro_attr::fake_desugar_await]\n    pub async fn await_becomes_block() -> i32 {\n        match Some(1).await {\n            Some(1) => 2,\n            Some(2) => 3,\n            _ => 0,\n        }\n    }\n}\n\nfn issue_9911() {\n    if { return } {}\n\n    let a = 1;\n    if { if a == 1 { return } else { true } } {}\n}\n\nfn in_closure() {\n    let v = vec![1, 2, 3];\n    if v.into_iter()\n        .filter(|x| {\n            let y = x + 1;\n            y > 3\n        })\n        .any(|x| x == 5)\n    {\n        println!(\"contains 4!\");\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/blocks_in_conditions.stderr",
    "content": "error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`\n  --> tests/ui/blocks_in_conditions.rs:30:5\n   |\nLL | /     if {\nLL | |\nLL | |         let x = 3;\nLL | |         x == 3\nLL | |     } {\n   | |_____^\n   |\n   = note: `-D clippy::blocks-in-conditions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]`\nhelp: try\n   |\nLL ~     let res = {\nLL +\nLL +         let x = 3;\nLL +         x == 3\nLL ~     }; if res {\n   |\n\nerror: omit braces around single expression condition\n  --> tests/ui/blocks_in_conditions.rs:42:8\n   |\nLL |     if { true } { 6 } else { 10 }\n   |        ^^^^^^^^ help: try: `true`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/blocks_in_conditions.rs:48:8\n   |\nLL |     if true && x == 3 { 6 } else { 10 }\n   |        ^^^^^^^^^^^^^^ help: try: `x == 3`\n   |\n   = note: `-D clippy::nonminimal-bool` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/blocks_in_conditions_2021.fixed",
    "content": "//@edition: 2021\n\n#![allow(clippy::let_and_return)]\n\n// issue #11814\nfn block_in_match_expr(num: i32) -> i32 {\n    let res = {\n        //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`\n        let opt = Some(2);\n        opt\n    }; match res {\n        Some(0) => 1,\n        Some(n) => num * 2,\n        None => 0,\n    };\n\n    match unsafe {\n        let hearty_hearty_hearty = vec![240, 159, 146, 150];\n        String::from_utf8_unchecked(hearty_hearty_hearty).as_str()\n    } {\n        \"💖\" => 1,\n        \"what\" => 2,\n        _ => 3,\n    }\n}\n"
  },
  {
    "path": "tests/ui/blocks_in_conditions_2021.rs",
    "content": "//@edition: 2021\n\n#![allow(clippy::let_and_return)]\n\n// issue #11814\nfn block_in_match_expr(num: i32) -> i32 {\n    match {\n        //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`\n        let opt = Some(2);\n        opt\n    } {\n        Some(0) => 1,\n        Some(n) => num * 2,\n        None => 0,\n    };\n\n    match unsafe {\n        let hearty_hearty_hearty = vec![240, 159, 146, 150];\n        String::from_utf8_unchecked(hearty_hearty_hearty).as_str()\n    } {\n        \"💖\" => 1,\n        \"what\" => 2,\n        _ => 3,\n    }\n}\n"
  },
  {
    "path": "tests/ui/blocks_in_conditions_2021.stderr",
    "content": "error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`\n  --> tests/ui/blocks_in_conditions_2021.rs:7:5\n   |\nLL | /     match {\nLL | |\nLL | |         let opt = Some(2);\nLL | |         opt\nLL | |     } {\n   | |_____^\n   |\n   = note: `-D clippy::blocks-in-conditions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]`\nhelp: try\n   |\nLL ~     let res = {\nLL +\nLL +         let opt = Some(2);\nLL +         opt\nLL ~     }; match res {\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/bool_assert_comparison.fixed",
    "content": "#![allow(unused, clippy::assertions_on_constants, clippy::const_is_empty)]\n#![warn(clippy::bool_assert_comparison)]\n\nuse std::ops::{Add, Not};\n\nmacro_rules! a {\n    () => {\n        true\n    };\n}\nmacro_rules! b {\n    () => {\n        true\n    };\n}\n\n// Implements the Not trait but with an output type\n// that's not bool. Should not suggest a rewrite\n#[derive(Debug, Clone, Copy)]\nenum ImplNotTraitWithoutBool {\n    VariantX(bool),\n    VariantY(u32),\n}\n\nimpl PartialEq<bool> for ImplNotTraitWithoutBool {\n    fn eq(&self, other: &bool) -> bool {\n        match *self {\n            ImplNotTraitWithoutBool::VariantX(b) => b == *other,\n            _ => false,\n        }\n    }\n}\n\nimpl Not for ImplNotTraitWithoutBool {\n    type Output = Self;\n\n    fn not(self) -> Self::Output {\n        match self {\n            ImplNotTraitWithoutBool::VariantX(b) => ImplNotTraitWithoutBool::VariantX(!b),\n            ImplNotTraitWithoutBool::VariantY(0) => ImplNotTraitWithoutBool::VariantY(1),\n            ImplNotTraitWithoutBool::VariantY(_) => ImplNotTraitWithoutBool::VariantY(0),\n        }\n    }\n}\n\n// This type implements the Not trait with an Output of\n// type bool. Using assert!(..) must be suggested\n#[derive(Debug, Clone, Copy)]\nstruct ImplNotTraitWithBool;\n\nimpl PartialEq<bool> for ImplNotTraitWithBool {\n    fn eq(&self, other: &bool) -> bool {\n        false\n    }\n}\n\nimpl Not for ImplNotTraitWithBool {\n    type Output = bool;\n\n    fn not(self) -> Self::Output {\n        true\n    }\n}\n\nimpl Add for ImplNotTraitWithBool {\n    type Output = Self;\n\n    fn add(self, other: Self) -> Self::Output {\n        self\n    }\n}\n\n#[derive(Debug)]\nstruct NonCopy;\n\nimpl PartialEq<bool> for NonCopy {\n    fn eq(&self, other: &bool) -> bool {\n        false\n    }\n}\n\nimpl Not for NonCopy {\n    type Output = bool;\n\n    fn not(self) -> Self::Output {\n        true\n    }\n}\n\nfn main() {\n    let a = ImplNotTraitWithoutBool::VariantX(true);\n    let b = ImplNotTraitWithBool;\n\n    assert_eq!(\"a\".len(), 1);\n    assert!(!\"a\".is_empty());\n    //~^ bool_assert_comparison\n    assert!(\"\".is_empty());\n    //~^ bool_assert_comparison\n    assert!(\"\".is_empty());\n    //~^ bool_assert_comparison\n    assert_eq!(a!(), b!());\n    assert_eq!(a!(), \"\".is_empty());\n    assert_eq!(\"\".is_empty(), b!());\n    assert_eq!(a, true);\n    assert!(!!b);\n    //~^ bool_assert_comparison\n\n    assert_ne!(\"a\".len(), 1);\n    assert!(\"a\".is_empty());\n    //~^ bool_assert_comparison\n    assert!(!\"\".is_empty());\n    //~^ bool_assert_comparison\n    assert!(!\"\".is_empty());\n    //~^ bool_assert_comparison\n    assert_ne!(a!(), b!());\n    assert_ne!(a!(), \"\".is_empty());\n    assert_ne!(\"\".is_empty(), b!());\n    assert_ne!(a, true);\n    assert!(!b);\n    //~^ bool_assert_comparison\n\n    debug_assert_eq!(\"a\".len(), 1);\n    debug_assert!(!\"a\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert!(\"\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert!(\"\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert_eq!(a!(), b!());\n    debug_assert_eq!(a!(), \"\".is_empty());\n    debug_assert_eq!(\"\".is_empty(), b!());\n    debug_assert_eq!(a, true);\n    debug_assert!(!!b);\n    //~^ bool_assert_comparison\n\n    debug_assert_ne!(\"a\".len(), 1);\n    debug_assert!(\"a\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert!(!\"\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert!(!\"\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert_ne!(a!(), b!());\n    debug_assert_ne!(a!(), \"\".is_empty());\n    debug_assert_ne!(\"\".is_empty(), b!());\n    debug_assert_ne!(a, true);\n    debug_assert!(!b);\n    //~^ bool_assert_comparison\n\n    // assert with error messages\n    assert_eq!(\"a\".len(), 1, \"tadam {}\", 1);\n    assert_eq!(\"a\".len(), 1, \"tadam {}\", true);\n    assert!(!\"a\".is_empty(), \"tadam {}\", 1);\n    //~^ bool_assert_comparison\n    assert!(!\"a\".is_empty(), \"tadam {}\", true);\n    //~^ bool_assert_comparison\n    assert!(!\"a\".is_empty(), \"tadam {}\", true);\n    //~^ bool_assert_comparison\n    assert_eq!(a, true, \"tadam {}\", false);\n\n    debug_assert_eq!(\"a\".len(), 1, \"tadam {}\", 1);\n    debug_assert_eq!(\"a\".len(), 1, \"tadam {}\", true);\n    debug_assert!(!\"a\".is_empty(), \"tadam {}\", 1);\n    //~^ bool_assert_comparison\n    debug_assert!(!\"a\".is_empty(), \"tadam {}\", true);\n    //~^ bool_assert_comparison\n    debug_assert!(!\"a\".is_empty(), \"tadam {}\", true);\n    //~^ bool_assert_comparison\n    debug_assert_eq!(a, true, \"tadam {}\", false);\n\n    assert!(a!());\n    //~^ bool_assert_comparison\n    assert!(b!());\n    //~^ bool_assert_comparison\n\n    use debug_assert_eq as renamed;\n    renamed!(a, true);\n    debug_assert!(!!b);\n    //~^ bool_assert_comparison\n\n    let non_copy = NonCopy;\n    assert_eq!(non_copy, true);\n    // changing the above to `assert!(non_copy)` would cause a `borrow of moved value`\n    println!(\"{non_copy:?}\");\n\n    macro_rules! in_macro {\n        ($v:expr) => {{\n            assert_eq!($v, true);\n        }};\n    }\n    in_macro!(a);\n\n    assert!(\"\".is_empty());\n    //~^ bool_assert_comparison\n    assert!(\"\".is_empty());\n    //~^ bool_assert_comparison\n    assert!(!\"requires negation\".is_empty());\n    //~^ bool_assert_comparison\n    assert!(!\"requires negation\".is_empty());\n    //~^ bool_assert_comparison\n\n    debug_assert!(\"\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert!(\"\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert!(!\"requires negation\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert!(!\"requires negation\".is_empty());\n    //~^ bool_assert_comparison\n    assert!(!b);\n    //~^ bool_assert_comparison\n    assert!(!(!b));\n    //~^ bool_assert_comparison\n    assert!(!!(b + b));\n    //~^ bool_assert_comparison\n    assert!(!(b + b));\n    //~^ bool_assert_comparison\n}\n\nfn issue16279() {\n    macro_rules! is_empty {\n        ($x:expr) => {\n            $x.is_empty()\n        };\n    }\n\n    assert!(!is_empty!(\"a\"));\n    //~^ bool_assert_comparison\n    assert!(is_empty!(\"\"));\n    //~^ bool_assert_comparison\n}\n"
  },
  {
    "path": "tests/ui/bool_assert_comparison.rs",
    "content": "#![allow(unused, clippy::assertions_on_constants, clippy::const_is_empty)]\n#![warn(clippy::bool_assert_comparison)]\n\nuse std::ops::{Add, Not};\n\nmacro_rules! a {\n    () => {\n        true\n    };\n}\nmacro_rules! b {\n    () => {\n        true\n    };\n}\n\n// Implements the Not trait but with an output type\n// that's not bool. Should not suggest a rewrite\n#[derive(Debug, Clone, Copy)]\nenum ImplNotTraitWithoutBool {\n    VariantX(bool),\n    VariantY(u32),\n}\n\nimpl PartialEq<bool> for ImplNotTraitWithoutBool {\n    fn eq(&self, other: &bool) -> bool {\n        match *self {\n            ImplNotTraitWithoutBool::VariantX(b) => b == *other,\n            _ => false,\n        }\n    }\n}\n\nimpl Not for ImplNotTraitWithoutBool {\n    type Output = Self;\n\n    fn not(self) -> Self::Output {\n        match self {\n            ImplNotTraitWithoutBool::VariantX(b) => ImplNotTraitWithoutBool::VariantX(!b),\n            ImplNotTraitWithoutBool::VariantY(0) => ImplNotTraitWithoutBool::VariantY(1),\n            ImplNotTraitWithoutBool::VariantY(_) => ImplNotTraitWithoutBool::VariantY(0),\n        }\n    }\n}\n\n// This type implements the Not trait with an Output of\n// type bool. Using assert!(..) must be suggested\n#[derive(Debug, Clone, Copy)]\nstruct ImplNotTraitWithBool;\n\nimpl PartialEq<bool> for ImplNotTraitWithBool {\n    fn eq(&self, other: &bool) -> bool {\n        false\n    }\n}\n\nimpl Not for ImplNotTraitWithBool {\n    type Output = bool;\n\n    fn not(self) -> Self::Output {\n        true\n    }\n}\n\nimpl Add for ImplNotTraitWithBool {\n    type Output = Self;\n\n    fn add(self, other: Self) -> Self::Output {\n        self\n    }\n}\n\n#[derive(Debug)]\nstruct NonCopy;\n\nimpl PartialEq<bool> for NonCopy {\n    fn eq(&self, other: &bool) -> bool {\n        false\n    }\n}\n\nimpl Not for NonCopy {\n    type Output = bool;\n\n    fn not(self) -> Self::Output {\n        true\n    }\n}\n\nfn main() {\n    let a = ImplNotTraitWithoutBool::VariantX(true);\n    let b = ImplNotTraitWithBool;\n\n    assert_eq!(\"a\".len(), 1);\n    assert_eq!(\"a\".is_empty(), false);\n    //~^ bool_assert_comparison\n    assert_eq!(\"\".is_empty(), true);\n    //~^ bool_assert_comparison\n    assert_eq!(true, \"\".is_empty());\n    //~^ bool_assert_comparison\n    assert_eq!(a!(), b!());\n    assert_eq!(a!(), \"\".is_empty());\n    assert_eq!(\"\".is_empty(), b!());\n    assert_eq!(a, true);\n    assert_eq!(b, true);\n    //~^ bool_assert_comparison\n\n    assert_ne!(\"a\".len(), 1);\n    assert_ne!(\"a\".is_empty(), false);\n    //~^ bool_assert_comparison\n    assert_ne!(\"\".is_empty(), true);\n    //~^ bool_assert_comparison\n    assert_ne!(true, \"\".is_empty());\n    //~^ bool_assert_comparison\n    assert_ne!(a!(), b!());\n    assert_ne!(a!(), \"\".is_empty());\n    assert_ne!(\"\".is_empty(), b!());\n    assert_ne!(a, true);\n    assert_ne!(b, true);\n    //~^ bool_assert_comparison\n\n    debug_assert_eq!(\"a\".len(), 1);\n    debug_assert_eq!(\"a\".is_empty(), false);\n    //~^ bool_assert_comparison\n    debug_assert_eq!(\"\".is_empty(), true);\n    //~^ bool_assert_comparison\n    debug_assert_eq!(true, \"\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert_eq!(a!(), b!());\n    debug_assert_eq!(a!(), \"\".is_empty());\n    debug_assert_eq!(\"\".is_empty(), b!());\n    debug_assert_eq!(a, true);\n    debug_assert_eq!(b, true);\n    //~^ bool_assert_comparison\n\n    debug_assert_ne!(\"a\".len(), 1);\n    debug_assert_ne!(\"a\".is_empty(), false);\n    //~^ bool_assert_comparison\n    debug_assert_ne!(\"\".is_empty(), true);\n    //~^ bool_assert_comparison\n    debug_assert_ne!(true, \"\".is_empty());\n    //~^ bool_assert_comparison\n    debug_assert_ne!(a!(), b!());\n    debug_assert_ne!(a!(), \"\".is_empty());\n    debug_assert_ne!(\"\".is_empty(), b!());\n    debug_assert_ne!(a, true);\n    debug_assert_ne!(b, true);\n    //~^ bool_assert_comparison\n\n    // assert with error messages\n    assert_eq!(\"a\".len(), 1, \"tadam {}\", 1);\n    assert_eq!(\"a\".len(), 1, \"tadam {}\", true);\n    assert_eq!(\"a\".is_empty(), false, \"tadam {}\", 1);\n    //~^ bool_assert_comparison\n    assert_eq!(\"a\".is_empty(), false, \"tadam {}\", true);\n    //~^ bool_assert_comparison\n    assert_eq!(false, \"a\".is_empty(), \"tadam {}\", true);\n    //~^ bool_assert_comparison\n    assert_eq!(a, true, \"tadam {}\", false);\n\n    debug_assert_eq!(\"a\".len(), 1, \"tadam {}\", 1);\n    debug_assert_eq!(\"a\".len(), 1, \"tadam {}\", true);\n    debug_assert_eq!(\"a\".is_empty(), false, \"tadam {}\", 1);\n    //~^ bool_assert_comparison\n    debug_assert_eq!(\"a\".is_empty(), false, \"tadam {}\", true);\n    //~^ bool_assert_comparison\n    debug_assert_eq!(false, \"a\".is_empty(), \"tadam {}\", true);\n    //~^ bool_assert_comparison\n    debug_assert_eq!(a, true, \"tadam {}\", false);\n\n    assert_eq!(a!(), true);\n    //~^ bool_assert_comparison\n    assert_eq!(true, b!());\n    //~^ bool_assert_comparison\n\n    use debug_assert_eq as renamed;\n    renamed!(a, true);\n    renamed!(b, true);\n    //~^ bool_assert_comparison\n\n    let non_copy = NonCopy;\n    assert_eq!(non_copy, true);\n    // changing the above to `assert!(non_copy)` would cause a `borrow of moved value`\n    println!(\"{non_copy:?}\");\n\n    macro_rules! in_macro {\n        ($v:expr) => {{\n            assert_eq!($v, true);\n        }};\n    }\n    in_macro!(a);\n\n    assert_eq!(\"\".is_empty(), true);\n    //~^ bool_assert_comparison\n    assert_ne!(\"\".is_empty(), false);\n    //~^ bool_assert_comparison\n    assert_ne!(\"requires negation\".is_empty(), true);\n    //~^ bool_assert_comparison\n    assert_eq!(\"requires negation\".is_empty(), false);\n    //~^ bool_assert_comparison\n\n    debug_assert_eq!(\"\".is_empty(), true);\n    //~^ bool_assert_comparison\n    debug_assert_ne!(\"\".is_empty(), false);\n    //~^ bool_assert_comparison\n    debug_assert_ne!(\"requires negation\".is_empty(), true);\n    //~^ bool_assert_comparison\n    debug_assert_eq!(\"requires negation\".is_empty(), false);\n    //~^ bool_assert_comparison\n    assert_eq!(!b, true);\n    //~^ bool_assert_comparison\n    assert_eq!(!b, false);\n    //~^ bool_assert_comparison\n    assert_eq!(b + b, true);\n    //~^ bool_assert_comparison\n    assert_eq!(b + b, false);\n    //~^ bool_assert_comparison\n}\n\nfn issue16279() {\n    macro_rules! is_empty {\n        ($x:expr) => {\n            $x.is_empty()\n        };\n    }\n\n    assert_eq!(is_empty!(\"a\"), false);\n    //~^ bool_assert_comparison\n    assert_eq!(is_empty!(\"\"), true);\n    //~^ bool_assert_comparison\n}\n"
  },
  {
    "path": "tests/ui/bool_assert_comparison.stderr",
    "content": "error: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:95:5\n   |\nLL |     assert_eq!(\"a\".is_empty(), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::bool-assert-comparison` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::bool_assert_comparison)]`\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(\"a\".is_empty(), false);\nLL +     assert!(!\"a\".is_empty());\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:97:5\n   |\nLL |     assert_eq!(\"\".is_empty(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(\"\".is_empty(), true);\nLL +     assert!(\"\".is_empty());\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:99:5\n   |\nLL |     assert_eq!(true, \"\".is_empty());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(true, \"\".is_empty());\nLL +     assert!(\"\".is_empty());\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:105:5\n   |\nLL |     assert_eq!(b, true);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(b, true);\nLL +     assert!(!!b);\n   |\n\nerror: used `assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:109:5\n   |\nLL |     assert_ne!(\"a\".is_empty(), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_ne!(\"a\".is_empty(), false);\nLL +     assert!(\"a\".is_empty());\n   |\n\nerror: used `assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:111:5\n   |\nLL |     assert_ne!(\"\".is_empty(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_ne!(\"\".is_empty(), true);\nLL +     assert!(!\"\".is_empty());\n   |\n\nerror: used `assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:113:5\n   |\nLL |     assert_ne!(true, \"\".is_empty());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_ne!(true, \"\".is_empty());\nLL +     assert!(!\"\".is_empty());\n   |\n\nerror: used `assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:119:5\n   |\nLL |     assert_ne!(b, true);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_ne!(b, true);\nLL +     assert!(!b);\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:123:5\n   |\nLL |     debug_assert_eq!(\"a\".is_empty(), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(\"a\".is_empty(), false);\nLL +     debug_assert!(!\"a\".is_empty());\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:125:5\n   |\nLL |     debug_assert_eq!(\"\".is_empty(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(\"\".is_empty(), true);\nLL +     debug_assert!(\"\".is_empty());\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:127:5\n   |\nLL |     debug_assert_eq!(true, \"\".is_empty());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(true, \"\".is_empty());\nLL +     debug_assert!(\"\".is_empty());\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:133:5\n   |\nLL |     debug_assert_eq!(b, true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(b, true);\nLL +     debug_assert!(!!b);\n   |\n\nerror: used `debug_assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:137:5\n   |\nLL |     debug_assert_ne!(\"a\".is_empty(), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_ne!(\"a\".is_empty(), false);\nLL +     debug_assert!(\"a\".is_empty());\n   |\n\nerror: used `debug_assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:139:5\n   |\nLL |     debug_assert_ne!(\"\".is_empty(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_ne!(\"\".is_empty(), true);\nLL +     debug_assert!(!\"\".is_empty());\n   |\n\nerror: used `debug_assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:141:5\n   |\nLL |     debug_assert_ne!(true, \"\".is_empty());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_ne!(true, \"\".is_empty());\nLL +     debug_assert!(!\"\".is_empty());\n   |\n\nerror: used `debug_assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:147:5\n   |\nLL |     debug_assert_ne!(b, true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_ne!(b, true);\nLL +     debug_assert!(!b);\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:153:5\n   |\nLL |     assert_eq!(\"a\".is_empty(), false, \"tadam {}\", 1);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(\"a\".is_empty(), false, \"tadam {}\", 1);\nLL +     assert!(!\"a\".is_empty(), \"tadam {}\", 1);\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:155:5\n   |\nLL |     assert_eq!(\"a\".is_empty(), false, \"tadam {}\", true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(\"a\".is_empty(), false, \"tadam {}\", true);\nLL +     assert!(!\"a\".is_empty(), \"tadam {}\", true);\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:157:5\n   |\nLL |     assert_eq!(false, \"a\".is_empty(), \"tadam {}\", true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(false, \"a\".is_empty(), \"tadam {}\", true);\nLL +     assert!(!\"a\".is_empty(), \"tadam {}\", true);\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:163:5\n   |\nLL |     debug_assert_eq!(\"a\".is_empty(), false, \"tadam {}\", 1);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(\"a\".is_empty(), false, \"tadam {}\", 1);\nLL +     debug_assert!(!\"a\".is_empty(), \"tadam {}\", 1);\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:165:5\n   |\nLL |     debug_assert_eq!(\"a\".is_empty(), false, \"tadam {}\", true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(\"a\".is_empty(), false, \"tadam {}\", true);\nLL +     debug_assert!(!\"a\".is_empty(), \"tadam {}\", true);\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:167:5\n   |\nLL |     debug_assert_eq!(false, \"a\".is_empty(), \"tadam {}\", true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(false, \"a\".is_empty(), \"tadam {}\", true);\nLL +     debug_assert!(!\"a\".is_empty(), \"tadam {}\", true);\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:171:5\n   |\nLL |     assert_eq!(a!(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(a!(), true);\nLL +     assert!(a!());\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:173:5\n   |\nLL |     assert_eq!(true, b!());\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(true, b!());\nLL +     assert!(b!());\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:178:5\n   |\nLL |     renamed!(b, true);\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     renamed!(b, true);\nLL +     debug_assert!(!!b);\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:193:5\n   |\nLL |     assert_eq!(\"\".is_empty(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(\"\".is_empty(), true);\nLL +     assert!(\"\".is_empty());\n   |\n\nerror: used `assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:195:5\n   |\nLL |     assert_ne!(\"\".is_empty(), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_ne!(\"\".is_empty(), false);\nLL +     assert!(\"\".is_empty());\n   |\n\nerror: used `assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:197:5\n   |\nLL |     assert_ne!(\"requires negation\".is_empty(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_ne!(\"requires negation\".is_empty(), true);\nLL +     assert!(!\"requires negation\".is_empty());\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:199:5\n   |\nLL |     assert_eq!(\"requires negation\".is_empty(), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(\"requires negation\".is_empty(), false);\nLL +     assert!(!\"requires negation\".is_empty());\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:202:5\n   |\nLL |     debug_assert_eq!(\"\".is_empty(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(\"\".is_empty(), true);\nLL +     debug_assert!(\"\".is_empty());\n   |\n\nerror: used `debug_assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:204:5\n   |\nLL |     debug_assert_ne!(\"\".is_empty(), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_ne!(\"\".is_empty(), false);\nLL +     debug_assert!(\"\".is_empty());\n   |\n\nerror: used `debug_assert_ne!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:206:5\n   |\nLL |     debug_assert_ne!(\"requires negation\".is_empty(), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_ne!(\"requires negation\".is_empty(), true);\nLL +     debug_assert!(!\"requires negation\".is_empty());\n   |\n\nerror: used `debug_assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:208:5\n   |\nLL |     debug_assert_eq!(\"requires negation\".is_empty(), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `debug_assert!(..)`\n   |\nLL -     debug_assert_eq!(\"requires negation\".is_empty(), false);\nLL +     debug_assert!(!\"requires negation\".is_empty());\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:210:5\n   |\nLL |     assert_eq!(!b, true);\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(!b, true);\nLL +     assert!(!b);\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:212:5\n   |\nLL |     assert_eq!(!b, false);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(!b, false);\nLL +     assert!(!(!b));\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:214:5\n   |\nLL |     assert_eq!(b + b, true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(b + b, true);\nLL +     assert!(!!(b + b));\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:216:5\n   |\nLL |     assert_eq!(b + b, false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(b + b, false);\nLL +     assert!(!(b + b));\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:227:5\n   |\nLL |     assert_eq!(is_empty!(\"a\"), false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(is_empty!(\"a\"), false);\nLL +     assert!(!is_empty!(\"a\"));\n   |\n\nerror: used `assert_eq!` with a literal bool\n  --> tests/ui/bool_assert_comparison.rs:229:5\n   |\nLL |     assert_eq!(is_empty!(\"\"), true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace it with `assert!(..)`\n   |\nLL -     assert_eq!(is_empty!(\"\"), true);\nLL +     assert!(is_empty!(\"\"));\n   |\n\nerror: aborting due to 39 previous errors\n\n"
  },
  {
    "path": "tests/ui/bool_comparison.fixed",
    "content": "#![allow(non_local_definitions, clippy::needless_ifs)]\n#![warn(clippy::bool_comparison)]\n#![allow(clippy::non_canonical_partial_ord_impl)]\n\nfn main() {\n    let x = true;\n    let _ = if x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if !x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if !x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if !x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if !x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if !x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if !x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n\n    let y = true;\n    let _ = if !x & y { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x & !y { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n}\n\nfn issue3703() {\n    struct Foo;\n    impl PartialEq<bool> for Foo {\n        fn eq(&self, _: &bool) -> bool {\n            true\n        }\n    }\n    impl PartialEq<Foo> for bool {\n        fn eq(&self, _: &Foo) -> bool {\n            true\n        }\n    }\n    impl PartialOrd<bool> for Foo {\n        fn partial_cmp(&self, _: &bool) -> Option<std::cmp::Ordering> {\n            None\n        }\n    }\n    impl PartialOrd<Foo> for bool {\n        fn partial_cmp(&self, _: &Foo) -> Option<std::cmp::Ordering> {\n            None\n        }\n    }\n\n    if Foo == true {}\n    if true == Foo {}\n    if Foo != true {}\n    if true != Foo {}\n    if Foo == false {}\n    if false == Foo {}\n    if Foo != false {}\n    if false != Foo {}\n    if Foo < false {}\n    if false < Foo {}\n}\n\nmacro_rules! m {\n    ($func:ident) => {\n        $func()\n    };\n}\n\nfn func() -> bool {\n    true\n}\n\nfn issue3973() {\n    // ok, don't lint on `cfg` invocation\n    if false == cfg!(feature = \"debugging\") {}\n    if cfg!(feature = \"debugging\") == false {}\n    if true == cfg!(feature = \"debugging\") {}\n    if cfg!(feature = \"debugging\") == true {}\n\n    // lint, could be simplified\n    if !m!(func) {}\n    //~^ bool_comparison\n    if !m!(func) {}\n    //~^ bool_comparison\n    if m!(func) {}\n    //~^ bool_comparison\n    if m!(func) {}\n    //~^ bool_comparison\n\n    // no lint with a variable\n    let is_debug = false;\n    if is_debug == cfg!(feature = \"debugging\") {}\n    if cfg!(feature = \"debugging\") == is_debug {}\n    if is_debug == m!(func) {}\n    if m!(func) == is_debug {}\n    let is_debug = true;\n    if is_debug == cfg!(feature = \"debugging\") {}\n    if cfg!(feature = \"debugging\") == is_debug {}\n    if is_debug == m!(func) {}\n    if m!(func) == is_debug {}\n}\n\n#[allow(clippy::unnecessary_cast)]\nfn issue9907() {\n    let _ = (1 >= 2) as usize;\n    //~^ bool_comparison\n    let _ = (!m!(func)) as usize;\n    //~^ bool_comparison\n    // This is not part of the issue, but an unexpected found when fixing the issue,\n    // the provided span was inside of macro rather than the macro callsite.\n    let _ = ((1 < 2) & !m!(func)) as usize;\n    //~^ bool_comparison\n}\n\n#[allow(clippy::nonminimal_bool)]\nfn issue15367() {\n    let a = true;\n    let b = false;\n\n    // these cases are handled by `nonminimal_bool`, so don't double-lint\n    if a == !b {};\n    if !a == b {};\n    if b == !a {};\n    if !b == a {};\n}\n\nfn issue15497() {\n    fn func() -> bool {\n        true\n    }\n\n    fn foo(x: bool) -> bool {\n        x & !m!(func)\n        //~^ bool_comparison\n    }\n\n    fn bar(x: bool) -> bool {\n        !x & m!(func)\n        //~^ bool_comparison\n    }\n}\n"
  },
  {
    "path": "tests/ui/bool_comparison.rs",
    "content": "#![allow(non_local_definitions, clippy::needless_ifs)]\n#![warn(clippy::bool_comparison)]\n#![allow(clippy::non_canonical_partial_ord_impl)]\n\nfn main() {\n    let x = true;\n    let _ = if x == true { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x == false { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if true == x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if false == x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x != true { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x != false { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if true != x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if false != x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x < true { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if false < x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x > false { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if true > x { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n\n    let y = true;\n    let _ = if x < y { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n    let _ = if x > y { \"yes\" } else { \"no\" };\n    //~^ bool_comparison\n}\n\nfn issue3703() {\n    struct Foo;\n    impl PartialEq<bool> for Foo {\n        fn eq(&self, _: &bool) -> bool {\n            true\n        }\n    }\n    impl PartialEq<Foo> for bool {\n        fn eq(&self, _: &Foo) -> bool {\n            true\n        }\n    }\n    impl PartialOrd<bool> for Foo {\n        fn partial_cmp(&self, _: &bool) -> Option<std::cmp::Ordering> {\n            None\n        }\n    }\n    impl PartialOrd<Foo> for bool {\n        fn partial_cmp(&self, _: &Foo) -> Option<std::cmp::Ordering> {\n            None\n        }\n    }\n\n    if Foo == true {}\n    if true == Foo {}\n    if Foo != true {}\n    if true != Foo {}\n    if Foo == false {}\n    if false == Foo {}\n    if Foo != false {}\n    if false != Foo {}\n    if Foo < false {}\n    if false < Foo {}\n}\n\nmacro_rules! m {\n    ($func:ident) => {\n        $func()\n    };\n}\n\nfn func() -> bool {\n    true\n}\n\nfn issue3973() {\n    // ok, don't lint on `cfg` invocation\n    if false == cfg!(feature = \"debugging\") {}\n    if cfg!(feature = \"debugging\") == false {}\n    if true == cfg!(feature = \"debugging\") {}\n    if cfg!(feature = \"debugging\") == true {}\n\n    // lint, could be simplified\n    if false == m!(func) {}\n    //~^ bool_comparison\n    if m!(func) == false {}\n    //~^ bool_comparison\n    if true == m!(func) {}\n    //~^ bool_comparison\n    if m!(func) == true {}\n    //~^ bool_comparison\n\n    // no lint with a variable\n    let is_debug = false;\n    if is_debug == cfg!(feature = \"debugging\") {}\n    if cfg!(feature = \"debugging\") == is_debug {}\n    if is_debug == m!(func) {}\n    if m!(func) == is_debug {}\n    let is_debug = true;\n    if is_debug == cfg!(feature = \"debugging\") {}\n    if cfg!(feature = \"debugging\") == is_debug {}\n    if is_debug == m!(func) {}\n    if m!(func) == is_debug {}\n}\n\n#[allow(clippy::unnecessary_cast)]\nfn issue9907() {\n    let _ = ((1 < 2) == false) as usize;\n    //~^ bool_comparison\n    let _ = (false == m!(func)) as usize;\n    //~^ bool_comparison\n    // This is not part of the issue, but an unexpected found when fixing the issue,\n    // the provided span was inside of macro rather than the macro callsite.\n    let _ = ((1 < 2) > m!(func)) as usize;\n    //~^ bool_comparison\n}\n\n#[allow(clippy::nonminimal_bool)]\nfn issue15367() {\n    let a = true;\n    let b = false;\n\n    // these cases are handled by `nonminimal_bool`, so don't double-lint\n    if a == !b {};\n    if !a == b {};\n    if b == !a {};\n    if !b == a {};\n}\n\nfn issue15497() {\n    fn func() -> bool {\n        true\n    }\n\n    fn foo(x: bool) -> bool {\n        x > m!(func)\n        //~^ bool_comparison\n    }\n\n    fn bar(x: bool) -> bool {\n        x < m!(func)\n        //~^ bool_comparison\n    }\n}\n"
  },
  {
    "path": "tests/ui/bool_comparison.stderr",
    "content": "error: equality checks against true are unnecessary\n  --> tests/ui/bool_comparison.rs:7:16\n   |\nLL |     let _ = if x == true { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^ help: try: `x`\n   |\n   = note: `-D clippy::bool-comparison` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`\n\nerror: equality checks against false can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:9:16\n   |\nLL |     let _ = if x == false { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^^ help: try: `!x`\n\nerror: equality checks against true are unnecessary\n  --> tests/ui/bool_comparison.rs:11:16\n   |\nLL |     let _ = if true == x { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^ help: try: `x`\n\nerror: equality checks against false can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:13:16\n   |\nLL |     let _ = if false == x { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^^ help: try: `!x`\n\nerror: inequality checks against true can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:15:16\n   |\nLL |     let _ = if x != true { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^ help: try: `!x`\n\nerror: inequality checks against false are unnecessary\n  --> tests/ui/bool_comparison.rs:17:16\n   |\nLL |     let _ = if x != false { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^^ help: try: `x`\n\nerror: inequality checks against true can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:19:16\n   |\nLL |     let _ = if true != x { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^ help: try: `!x`\n\nerror: inequality checks against false are unnecessary\n  --> tests/ui/bool_comparison.rs:21:16\n   |\nLL |     let _ = if false != x { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^^ help: try: `x`\n\nerror: less than comparison against true can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:23:16\n   |\nLL |     let _ = if x < true { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^ help: try: `!x`\n\nerror: greater than checks against false are unnecessary\n  --> tests/ui/bool_comparison.rs:25:16\n   |\nLL |     let _ = if false < x { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^ help: try: `x`\n\nerror: greater than checks against false are unnecessary\n  --> tests/ui/bool_comparison.rs:27:16\n   |\nLL |     let _ = if x > false { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^^ help: try: `x`\n\nerror: less than comparison against true can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:29:16\n   |\nLL |     let _ = if true > x { \"yes\" } else { \"no\" };\n   |                ^^^^^^^^ help: try: `!x`\n\nerror: order comparisons between booleans can be simplified\n  --> tests/ui/bool_comparison.rs:33:16\n   |\nLL |     let _ = if x < y { \"yes\" } else { \"no\" };\n   |                ^^^^^ help: try: `!x & y`\n\nerror: order comparisons between booleans can be simplified\n  --> tests/ui/bool_comparison.rs:35:16\n   |\nLL |     let _ = if x > y { \"yes\" } else { \"no\" };\n   |                ^^^^^ help: try: `x & !y`\n\nerror: equality checks against false can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:92:8\n   |\nLL |     if false == m!(func) {}\n   |        ^^^^^^^^^^^^^^^^^ help: try: `!m!(func)`\n\nerror: equality checks against false can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:94:8\n   |\nLL |     if m!(func) == false {}\n   |        ^^^^^^^^^^^^^^^^^ help: try: `!m!(func)`\n\nerror: equality checks against true are unnecessary\n  --> tests/ui/bool_comparison.rs:96:8\n   |\nLL |     if true == m!(func) {}\n   |        ^^^^^^^^^^^^^^^^ help: try: `m!(func)`\n\nerror: equality checks against true are unnecessary\n  --> tests/ui/bool_comparison.rs:98:8\n   |\nLL |     if m!(func) == true {}\n   |        ^^^^^^^^^^^^^^^^ help: try: `m!(func)`\n\nerror: equality checks against false can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:116:14\n   |\nLL |     let _ = ((1 < 2) == false) as usize;\n   |              ^^^^^^^^^^^^^^^^ help: try: `1 >= 2`\n\nerror: equality checks against false can be replaced by a negation\n  --> tests/ui/bool_comparison.rs:118:14\n   |\nLL |     let _ = (false == m!(func)) as usize;\n   |              ^^^^^^^^^^^^^^^^^ help: try: `!m!(func)`\n\nerror: order comparisons between booleans can be simplified\n  --> tests/ui/bool_comparison.rs:122:14\n   |\nLL |     let _ = ((1 < 2) > m!(func)) as usize;\n   |              ^^^^^^^^^^^^^^^^^^ help: try: `(1 < 2) & !m!(func)`\n\nerror: order comparisons between booleans can be simplified\n  --> tests/ui/bool_comparison.rs:144:9\n   |\nLL |         x > m!(func)\n   |         ^^^^^^^^^^^^ help: try: `x & !m!(func)`\n\nerror: order comparisons between booleans can be simplified\n  --> tests/ui/bool_comparison.rs:149:9\n   |\nLL |         x < m!(func)\n   |         ^^^^^^^^^^^^ help: try: `!x & m!(func)`\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/bool_to_int_with_if.fixed",
    "content": "#![warn(clippy::bool_to_int_with_if)]\n#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]\n\nfn main() {\n    let a = true;\n    let b = false;\n\n    let x = 1;\n    let y = 2;\n\n    // Should lint\n    // precedence\n    i32::from(a);\n    i32::from(!a);\n    i32::from(!a);\n    i32::from(a || b);\n    i32::from(cond(a, b));\n    i32::from(x + y < 4);\n\n    // if else if\n    if a {\n        123\n    } else { i32::from(b) };\n\n    // if else if inverted\n    if a {\n        123\n    } else { i32::from(!b) };\n\n    // Shouldn't lint\n\n    if a {\n        1\n    } else if b {\n        0\n    } else {\n        3\n    };\n\n    if a {\n        3\n    } else if b {\n        1\n    } else {\n        -2\n    };\n\n    if a {\n        3\n    } else {\n        0\n    };\n    if a {\n        side_effect();\n        1\n    } else {\n        0\n    };\n    if a {\n        1\n    } else {\n        side_effect();\n        0\n    };\n\n    // multiple else ifs\n    if a {\n        123\n    } else if b {\n        1\n    } else if a | b {\n        0\n    } else {\n        123\n    };\n\n    pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 };\n\n    // https://github.com/rust-lang/rust-clippy/issues/10452\n    let should_not_lint = [(); if true { 1 } else { 0 }];\n\n    let should_not_lint = const { if true { 1 } else { 0 } };\n\n    some_fn(a);\n}\n\n// Lint returns and type inference\nfn some_fn(a: bool) -> u8 {\n    u8::from(a)\n    //~^ bool_to_int_with_if\n}\n\nfn side_effect() {}\n\nfn cond(a: bool, b: bool) -> bool {\n    a || b\n}\n\nenum Enum {\n    A,\n    B,\n}\n\nfn if_let(a: Enum, b: Enum) {\n    if let Enum::A = a {\n        1\n    } else {\n        0\n    };\n\n    if let Enum::A = a\n        && let Enum::B = b\n    {\n        1\n    } else {\n        0\n    };\n}\n\nfn issue14628() {\n    macro_rules! mac {\n        (if $cond:expr, $then:expr, $else:expr) => {\n            if $cond { $then } else { $else }\n        };\n        (zero) => {\n            0\n        };\n        (one) => {\n            1\n        };\n    }\n\n    let _ = i32::from(dbg!(4 > 0));\n    //~^ bool_to_int_with_if\n\n    let _ = dbg!(i32::from(4 > 0));\n    //~^ bool_to_int_with_if\n\n    let _ = mac!(if 4 > 0, 1, 0);\n    let _ = if 4 > 0 { mac!(one) } else { 0 };\n    let _ = if 4 > 0 { 1 } else { mac!(zero) };\n}\n"
  },
  {
    "path": "tests/ui/bool_to_int_with_if.rs",
    "content": "#![warn(clippy::bool_to_int_with_if)]\n#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]\n\nfn main() {\n    let a = true;\n    let b = false;\n\n    let x = 1;\n    let y = 2;\n\n    // Should lint\n    // precedence\n    if a {\n        //~^ bool_to_int_with_if\n        1\n    } else {\n        0\n    };\n    if a {\n        //~^ bool_to_int_with_if\n        0\n    } else {\n        1\n    };\n    if !a {\n        //~^ bool_to_int_with_if\n        1\n    } else {\n        0\n    };\n    if a || b {\n        //~^ bool_to_int_with_if\n        1\n    } else {\n        0\n    };\n    if cond(a, b) {\n        //~^ bool_to_int_with_if\n        1\n    } else {\n        0\n    };\n    if x + y < 4 {\n        //~^ bool_to_int_with_if\n        1\n    } else {\n        0\n    };\n\n    // if else if\n    if a {\n        123\n    } else if b {\n        //~^ bool_to_int_with_if\n        1\n    } else {\n        0\n    };\n\n    // if else if inverted\n    if a {\n        123\n    } else if b {\n        //~^ bool_to_int_with_if\n        0\n    } else {\n        1\n    };\n\n    // Shouldn't lint\n\n    if a {\n        1\n    } else if b {\n        0\n    } else {\n        3\n    };\n\n    if a {\n        3\n    } else if b {\n        1\n    } else {\n        -2\n    };\n\n    if a {\n        3\n    } else {\n        0\n    };\n    if a {\n        side_effect();\n        1\n    } else {\n        0\n    };\n    if a {\n        1\n    } else {\n        side_effect();\n        0\n    };\n\n    // multiple else ifs\n    if a {\n        123\n    } else if b {\n        1\n    } else if a | b {\n        0\n    } else {\n        123\n    };\n\n    pub const SHOULD_NOT_LINT: usize = if true { 1 } else { 0 };\n\n    // https://github.com/rust-lang/rust-clippy/issues/10452\n    let should_not_lint = [(); if true { 1 } else { 0 }];\n\n    let should_not_lint = const { if true { 1 } else { 0 } };\n\n    some_fn(a);\n}\n\n// Lint returns and type inference\nfn some_fn(a: bool) -> u8 {\n    if a { 1 } else { 0 }\n    //~^ bool_to_int_with_if\n}\n\nfn side_effect() {}\n\nfn cond(a: bool, b: bool) -> bool {\n    a || b\n}\n\nenum Enum {\n    A,\n    B,\n}\n\nfn if_let(a: Enum, b: Enum) {\n    if let Enum::A = a {\n        1\n    } else {\n        0\n    };\n\n    if let Enum::A = a\n        && let Enum::B = b\n    {\n        1\n    } else {\n        0\n    };\n}\n\nfn issue14628() {\n    macro_rules! mac {\n        (if $cond:expr, $then:expr, $else:expr) => {\n            if $cond { $then } else { $else }\n        };\n        (zero) => {\n            0\n        };\n        (one) => {\n            1\n        };\n    }\n\n    let _ = if dbg!(4 > 0) { 1 } else { 0 };\n    //~^ bool_to_int_with_if\n\n    let _ = dbg!(if 4 > 0 { 1 } else { 0 });\n    //~^ bool_to_int_with_if\n\n    let _ = mac!(if 4 > 0, 1, 0);\n    let _ = if 4 > 0 { mac!(one) } else { 0 };\n    let _ = if 4 > 0 { 1 } else { mac!(zero) };\n}\n"
  },
  {
    "path": "tests/ui/bool_to_int_with_if.stderr",
    "content": "error: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:13:5\n   |\nLL | /     if a {\nLL | |\nLL | |         1\nLL | |     } else {\nLL | |         0\nLL | |     };\n   | |_____^ help: replace with from: `i32::from(a)`\n   |\n   = note: `a as i32` or `a.into()` can also be valid options\n   = note: `-D clippy::bool-to-int-with-if` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::bool_to_int_with_if)]`\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:19:5\n   |\nLL | /     if a {\nLL | |\nLL | |         0\nLL | |     } else {\nLL | |         1\nLL | |     };\n   | |_____^ help: replace with from: `i32::from(!a)`\n   |\n   = note: `!a as i32` or `(!a).into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:25:5\n   |\nLL | /     if !a {\nLL | |\nLL | |         1\nLL | |     } else {\nLL | |         0\nLL | |     };\n   | |_____^ help: replace with from: `i32::from(!a)`\n   |\n   = note: `!a as i32` or `(!a).into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:31:5\n   |\nLL | /     if a || b {\nLL | |\nLL | |         1\nLL | |     } else {\nLL | |         0\nLL | |     };\n   | |_____^ help: replace with from: `i32::from(a || b)`\n   |\n   = note: `(a || b) as i32` or `(a || b).into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:37:5\n   |\nLL | /     if cond(a, b) {\nLL | |\nLL | |         1\nLL | |     } else {\nLL | |         0\nLL | |     };\n   | |_____^ help: replace with from: `i32::from(cond(a, b))`\n   |\n   = note: `cond(a, b) as i32` or `cond(a, b).into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:43:5\n   |\nLL | /     if x + y < 4 {\nLL | |\nLL | |         1\nLL | |     } else {\nLL | |         0\nLL | |     };\n   | |_____^ help: replace with from: `i32::from(x + y < 4)`\n   |\n   = note: `(x + y < 4) as i32` or `(x + y < 4).into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:53:12\n   |\nLL |       } else if b {\n   |  ____________^\nLL | |\nLL | |         1\nLL | |     } else {\nLL | |         0\nLL | |     };\n   | |_____^ help: replace with from: `{ i32::from(b) }`\n   |\n   = note: `b as i32` or `b.into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:63:12\n   |\nLL |       } else if b {\n   |  ____________^\nLL | |\nLL | |         0\nLL | |     } else {\nLL | |         1\nLL | |     };\n   | |_____^ help: replace with from: `{ i32::from(!b) }`\n   |\n   = note: `!b as i32` or `(!b).into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:129:5\n   |\nLL |     if a { 1 } else { 0 }\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `u8::from(a)`\n   |\n   = note: `a as u8` or `a.into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:173:13\n   |\nLL |     let _ = if dbg!(4 > 0) { 1 } else { 0 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `i32::from(dbg!(4 > 0))`\n   |\n   = note: `dbg!(4 > 0) as i32` or `dbg!(4 > 0).into()` can also be valid options\n\nerror: boolean to int conversion using if\n  --> tests/ui/bool_to_int_with_if.rs:176:18\n   |\nLL |     let _ = dbg!(if 4 > 0 { 1 } else { 0 });\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with from: `i32::from(4 > 0)`\n   |\n   = note: `(4 > 0) as i32` or `(4 > 0).into()` can also be valid options\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/borrow_and_ref_as_ptr.fixed",
    "content": "// Make sure that `ref_as_ptr` is not emitted when `borrow_as_ptr` is.\n\n#![warn(clippy::ref_as_ptr, clippy::borrow_as_ptr)]\n\nfn f<T>(_: T) {}\n\nfn main() {\n    let mut val = 0;\n    f(&raw const val);\n    //~^ borrow_as_ptr\n    f(&raw mut val);\n    //~^ borrow_as_ptr\n}\n"
  },
  {
    "path": "tests/ui/borrow_and_ref_as_ptr.rs",
    "content": "// Make sure that `ref_as_ptr` is not emitted when `borrow_as_ptr` is.\n\n#![warn(clippy::ref_as_ptr, clippy::borrow_as_ptr)]\n\nfn f<T>(_: T) {}\n\nfn main() {\n    let mut val = 0;\n    f(&val as *const _);\n    //~^ borrow_as_ptr\n    f(&mut val as *mut i32);\n    //~^ borrow_as_ptr\n}\n"
  },
  {
    "path": "tests/ui/borrow_and_ref_as_ptr.stderr",
    "content": "error: borrow as raw pointer\n  --> tests/ui/borrow_and_ref_as_ptr.rs:9:7\n   |\nLL |     f(&val as *const _);\n   |       ^^^^^^^^^^^^^^^^ help: try: `&raw const val`\n   |\n   = note: `-D clippy::borrow-as-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`\n\nerror: borrow as raw pointer\n  --> tests/ui/borrow_and_ref_as_ptr.rs:11:7\n   |\nLL |     f(&mut val as *mut i32);\n   |       ^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut val`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::borrow_as_ptr)]\n#![allow(clippy::useless_vec, clippy::ptr_offset_by_literal)]\n\nextern crate proc_macros;\n\nfn a() -> i32 {\n    0\n}\n\n#[clippy::msrv = \"1.75\"]\nfn main() {\n    let val = 1;\n    let _p = std::ptr::addr_of!(val);\n    //~^ borrow_as_ptr\n    let _p = &0 as *const i32;\n    let _p = &a() as *const i32;\n    let vec = vec![1];\n    let _p = &vec.len() as *const usize;\n\n    let mut val_mut = 1;\n    let _p_mut = std::ptr::addr_of_mut!(val_mut);\n    //~^ borrow_as_ptr\n\n    let mut x: [i32; 2] = [42, 43];\n    let _raw = std::ptr::addr_of_mut!(x[1]).wrapping_offset(-1);\n    //~^ borrow_as_ptr\n}\n\nfn issue_13882() {\n    let mut x: [i32; 2] = [42, 43];\n    let _raw = (&raw mut x[1]).wrapping_offset(-1);\n    //~^ borrow_as_ptr\n}\n\nfn implicit_cast() {\n    let val = 1;\n    let p: *const i32 = &raw const val;\n    //~^ borrow_as_ptr\n\n    let mut val = 1;\n    let p: *mut i32 = &raw mut val;\n    //~^ borrow_as_ptr\n\n    let mut val = 1;\n    // Only lint the leftmost argument, the rightmost is ref to a temporary\n    core::ptr::eq(&raw const val, &1);\n    //~^ borrow_as_ptr\n\n    // Do not lint references to temporaries\n    core::ptr::eq(&0i32, &1i32);\n}\n\nfn issue_15141() {\n    let a = String::new();\n    // Don't lint cast to dyn trait pointers\n    let b = &a as *const dyn std::any::Any;\n}\n\nfn issue15389() {\n    proc_macros::with_span! {\n        span\n        let var = 0u32;\n        // Don't lint in proc-macros\n        let _ = &var as *const u32;\n    };\n}\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::borrow_as_ptr)]\n#![allow(clippy::useless_vec, clippy::ptr_offset_by_literal)]\n\nextern crate proc_macros;\n\nfn a() -> i32 {\n    0\n}\n\n#[clippy::msrv = \"1.75\"]\nfn main() {\n    let val = 1;\n    let _p = &val as *const i32;\n    //~^ borrow_as_ptr\n    let _p = &0 as *const i32;\n    let _p = &a() as *const i32;\n    let vec = vec![1];\n    let _p = &vec.len() as *const usize;\n\n    let mut val_mut = 1;\n    let _p_mut = &mut val_mut as *mut i32;\n    //~^ borrow_as_ptr\n\n    let mut x: [i32; 2] = [42, 43];\n    let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1);\n    //~^ borrow_as_ptr\n}\n\nfn issue_13882() {\n    let mut x: [i32; 2] = [42, 43];\n    let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1);\n    //~^ borrow_as_ptr\n}\n\nfn implicit_cast() {\n    let val = 1;\n    let p: *const i32 = &val;\n    //~^ borrow_as_ptr\n\n    let mut val = 1;\n    let p: *mut i32 = &mut val;\n    //~^ borrow_as_ptr\n\n    let mut val = 1;\n    // Only lint the leftmost argument, the rightmost is ref to a temporary\n    core::ptr::eq(&val, &1);\n    //~^ borrow_as_ptr\n\n    // Do not lint references to temporaries\n    core::ptr::eq(&0i32, &1i32);\n}\n\nfn issue_15141() {\n    let a = String::new();\n    // Don't lint cast to dyn trait pointers\n    let b = &a as *const dyn std::any::Any;\n}\n\nfn issue15389() {\n    proc_macros::with_span! {\n        span\n        let var = 0u32;\n        // Don't lint in proc-macros\n        let _ = &var as *const u32;\n    };\n}\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr.stderr",
    "content": "error: borrow as raw pointer\n  --> tests/ui/borrow_as_ptr.rs:14:14\n   |\nLL |     let _p = &val as *const i32;\n   |              ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of!(val)`\n   |\n   = note: `-D clippy::borrow-as-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`\n\nerror: borrow as raw pointer\n  --> tests/ui/borrow_as_ptr.rs:22:18\n   |\nLL |     let _p_mut = &mut val_mut as *mut i32;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(val_mut)`\n\nerror: borrow as raw pointer\n  --> tests/ui/borrow_as_ptr.rs:26:16\n   |\nLL |     let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(x[1])`\n\nerror: borrow as raw pointer\n  --> tests/ui/borrow_as_ptr.rs:32:17\n   |\nLL |     let _raw = (&mut x[1] as *mut i32).wrapping_offset(-1);\n   |                 ^^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut x[1]`\n\nerror: implicit borrow as raw pointer\n  --> tests/ui/borrow_as_ptr.rs:38:25\n   |\nLL |     let p: *const i32 = &val;\n   |                         ^^^^\n   |\nhelp: use a raw pointer instead\n   |\nLL |     let p: *const i32 = &raw const val;\n   |                          +++++++++\n\nerror: implicit borrow as raw pointer\n  --> tests/ui/borrow_as_ptr.rs:42:23\n   |\nLL |     let p: *mut i32 = &mut val;\n   |                       ^^^^^^^^\n   |\nhelp: use a raw pointer instead\n   |\nLL |     let p: *mut i32 = &raw mut val;\n   |                        +++\n\nerror: implicit borrow as raw pointer\n  --> tests/ui/borrow_as_ptr.rs:47:19\n   |\nLL |     core::ptr::eq(&val, &1);\n   |                   ^^^^\n   |\nhelp: use a raw pointer instead\n   |\nLL |     core::ptr::eq(&raw const val, &1);\n   |                    +++++++++\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr_no_std.fixed",
    "content": "#![warn(clippy::borrow_as_ptr)]\n#![no_std]\n#![crate_type = \"lib\"]\n\n#[clippy::msrv = \"1.75\"]\npub fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    let val = 1;\n    let _p = core::ptr::addr_of!(val);\n    //~^ borrow_as_ptr\n\n    let mut val_mut = 1;\n    let _p_mut = core::ptr::addr_of_mut!(val_mut);\n    //~^ borrow_as_ptr\n    0\n}\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr_no_std.rs",
    "content": "#![warn(clippy::borrow_as_ptr)]\n#![no_std]\n#![crate_type = \"lib\"]\n\n#[clippy::msrv = \"1.75\"]\npub fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    let val = 1;\n    let _p = &val as *const i32;\n    //~^ borrow_as_ptr\n\n    let mut val_mut = 1;\n    let _p_mut = &mut val_mut as *mut i32;\n    //~^ borrow_as_ptr\n    0\n}\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr_no_std.stderr",
    "content": "error: borrow as raw pointer\n  --> tests/ui/borrow_as_ptr_no_std.rs:8:14\n   |\nLL |     let _p = &val as *const i32;\n   |              ^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of!(val)`\n   |\n   = note: `-D clippy::borrow-as-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`\n\nerror: borrow as raw pointer\n  --> tests/ui/borrow_as_ptr_no_std.rs:12:18\n   |\nLL |     let _p_mut = &mut val_mut as *mut i32;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of_mut!(val_mut)`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr_raw_ref.fixed",
    "content": "#![warn(clippy::borrow_as_ptr)]\n#![allow(clippy::useless_vec)]\n\nfn a() -> i32 {\n    0\n}\n\n#[clippy::msrv = \"1.82\"]\nfn main() {\n    let val = 1;\n    let _p = &raw const val;\n    //~^ borrow_as_ptr\n    let _p = &0 as *const i32;\n    let _p = &a() as *const i32;\n    let vec = vec![1];\n    let _p = &vec.len() as *const usize;\n\n    let mut val_mut = 1;\n    let _p_mut = &raw mut val_mut;\n    //~^ borrow_as_ptr\n}\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr_raw_ref.rs",
    "content": "#![warn(clippy::borrow_as_ptr)]\n#![allow(clippy::useless_vec)]\n\nfn a() -> i32 {\n    0\n}\n\n#[clippy::msrv = \"1.82\"]\nfn main() {\n    let val = 1;\n    let _p = &val as *const i32;\n    //~^ borrow_as_ptr\n    let _p = &0 as *const i32;\n    let _p = &a() as *const i32;\n    let vec = vec![1];\n    let _p = &vec.len() as *const usize;\n\n    let mut val_mut = 1;\n    let _p_mut = &mut val_mut as *mut i32;\n    //~^ borrow_as_ptr\n}\n"
  },
  {
    "path": "tests/ui/borrow_as_ptr_raw_ref.stderr",
    "content": "error: borrow as raw pointer\n  --> tests/ui/borrow_as_ptr_raw_ref.rs:11:14\n   |\nLL |     let _p = &val as *const i32;\n   |              ^^^^^^^^^^^^^^^^^^ help: try: `&raw const val`\n   |\n   = note: `-D clippy::borrow-as-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`\n\nerror: borrow as raw pointer\n  --> tests/ui/borrow_as_ptr_raw_ref.rs:19:18\n   |\nLL |     let _p_mut = &mut val_mut as *mut i32;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut val_mut`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/borrow_box.fixed",
    "content": "#![deny(clippy::borrowed_box)]\n#![allow(dead_code, unused_variables)]\n#![allow(\n    clippy::uninlined_format_args,\n    clippy::disallowed_names,\n    clippy::needless_pass_by_ref_mut,\n    clippy::needless_lifetimes\n)]\n\nuse std::fmt::Display;\n\npub fn test1(foo: &mut Box<bool>) {\n    // Although this function could be changed to \"&mut bool\",\n    // avoiding the Box, mutable references to boxes are not\n    // flagged by this lint.\n    //\n    // This omission is intentional: By passing a mutable Box,\n    // the memory location of the pointed-to object could be\n    // modified. By passing a mutable reference, the contents\n    // could change, but not the location.\n    println!(\"{:?}\", foo)\n}\n\npub fn test2() {\n    let foo: &bool;\n    //~^ borrowed_box\n}\n\nstruct Test3<'a> {\n    foo: &'a bool,\n    //~^ borrowed_box\n}\n\ntrait Test4 {\n    fn test4(a: &bool);\n    //~^ borrowed_box\n}\n\nuse std::any::Any;\n\npub fn test5(foo: &mut Box<dyn Any>) {\n    println!(\"{:?}\", foo)\n}\n\npub fn test6() {\n    let foo: &Box<dyn Any>;\n}\n\nstruct Test7<'a> {\n    foo: &'a Box<dyn Any>,\n}\n\ntrait Test8 {\n    fn test8(a: &Box<dyn Any>);\n}\n\nimpl<'a> Test8 for Test7<'a> {\n    fn test8(a: &Box<dyn Any>) {\n        unimplemented!();\n    }\n}\n\npub fn test9(foo: &mut Box<dyn Any + Send + Sync>) {\n    let _ = foo;\n}\n\npub fn test10() {\n    let foo: &Box<dyn Any + Send + 'static>;\n}\n\nstruct Test11<'a> {\n    foo: &'a Box<dyn Any + Send>,\n}\n\ntrait Test12 {\n    fn test4(a: &Box<dyn Any + 'static>);\n}\n\nimpl<'a> Test12 for Test11<'a> {\n    fn test4(a: &Box<dyn Any + 'static>) {\n        unimplemented!();\n    }\n}\n\npub fn test13(boxed_slice: &mut Box<[i32]>) {\n    // Unconditionally replaces the box pointer.\n    //\n    // This cannot be accomplished if \"&mut [i32]\" is passed,\n    // and provides a test case where passing a reference to\n    // a Box is valid.\n    let mut data = vec![12];\n    *boxed_slice = data.into_boxed_slice();\n}\n\n// The suggestion should include proper parentheses to avoid a syntax error.\npub fn test14(_display: &dyn Display) {}\n//~^ borrowed_box\n\npub fn test15(_display: &(dyn Display + Send)) {}\n//~^ borrowed_box\n\npub fn test16<'a>(_display: &'a (dyn Display + 'a)) {}\n//~^ borrowed_box\n\npub fn test17(_display: &impl Display) {}\n//~^ borrowed_box\n\npub fn test18(_display: &(impl Display + Send)) {}\n//~^ borrowed_box\n\npub fn test19<'a>(_display: &'a (impl Display + 'a)) {}\n//~^ borrowed_box\n\n// This exists only to check what happens when parentheses are already present.\n// Even though the current implementation doesn't put extra parentheses,\n// it's fine that unnecessary parentheses appear in the future for some reason.\npub fn test20(_display: &(dyn Display + Send)) {}\n//~^ borrowed_box\n\n#[allow(clippy::borrowed_box)]\ntrait Trait {\n    fn f(b: &Box<bool>);\n}\n\n// Trait impls are not linted\nimpl Trait for () {\n    fn f(_: &Box<bool>) {}\n}\n\nfn main() {\n    test1(&mut Box::new(false));\n    test2();\n    test5(&mut (Box::new(false) as Box<dyn Any>));\n    test6();\n    test9(&mut (Box::new(false) as Box<dyn Any + Send + Sync>));\n    test10();\n}\n"
  },
  {
    "path": "tests/ui/borrow_box.rs",
    "content": "#![deny(clippy::borrowed_box)]\n#![allow(dead_code, unused_variables)]\n#![allow(\n    clippy::uninlined_format_args,\n    clippy::disallowed_names,\n    clippy::needless_pass_by_ref_mut,\n    clippy::needless_lifetimes\n)]\n\nuse std::fmt::Display;\n\npub fn test1(foo: &mut Box<bool>) {\n    // Although this function could be changed to \"&mut bool\",\n    // avoiding the Box, mutable references to boxes are not\n    // flagged by this lint.\n    //\n    // This omission is intentional: By passing a mutable Box,\n    // the memory location of the pointed-to object could be\n    // modified. By passing a mutable reference, the contents\n    // could change, but not the location.\n    println!(\"{:?}\", foo)\n}\n\npub fn test2() {\n    let foo: &Box<bool>;\n    //~^ borrowed_box\n}\n\nstruct Test3<'a> {\n    foo: &'a Box<bool>,\n    //~^ borrowed_box\n}\n\ntrait Test4 {\n    fn test4(a: &Box<bool>);\n    //~^ borrowed_box\n}\n\nuse std::any::Any;\n\npub fn test5(foo: &mut Box<dyn Any>) {\n    println!(\"{:?}\", foo)\n}\n\npub fn test6() {\n    let foo: &Box<dyn Any>;\n}\n\nstruct Test7<'a> {\n    foo: &'a Box<dyn Any>,\n}\n\ntrait Test8 {\n    fn test8(a: &Box<dyn Any>);\n}\n\nimpl<'a> Test8 for Test7<'a> {\n    fn test8(a: &Box<dyn Any>) {\n        unimplemented!();\n    }\n}\n\npub fn test9(foo: &mut Box<dyn Any + Send + Sync>) {\n    let _ = foo;\n}\n\npub fn test10() {\n    let foo: &Box<dyn Any + Send + 'static>;\n}\n\nstruct Test11<'a> {\n    foo: &'a Box<dyn Any + Send>,\n}\n\ntrait Test12 {\n    fn test4(a: &Box<dyn Any + 'static>);\n}\n\nimpl<'a> Test12 for Test11<'a> {\n    fn test4(a: &Box<dyn Any + 'static>) {\n        unimplemented!();\n    }\n}\n\npub fn test13(boxed_slice: &mut Box<[i32]>) {\n    // Unconditionally replaces the box pointer.\n    //\n    // This cannot be accomplished if \"&mut [i32]\" is passed,\n    // and provides a test case where passing a reference to\n    // a Box is valid.\n    let mut data = vec![12];\n    *boxed_slice = data.into_boxed_slice();\n}\n\n// The suggestion should include proper parentheses to avoid a syntax error.\npub fn test14(_display: &Box<dyn Display>) {}\n//~^ borrowed_box\n\npub fn test15(_display: &Box<dyn Display + Send>) {}\n//~^ borrowed_box\n\npub fn test16<'a>(_display: &'a Box<dyn Display + 'a>) {}\n//~^ borrowed_box\n\npub fn test17(_display: &Box<impl Display>) {}\n//~^ borrowed_box\n\npub fn test18(_display: &Box<impl Display + Send>) {}\n//~^ borrowed_box\n\npub fn test19<'a>(_display: &'a Box<impl Display + 'a>) {}\n//~^ borrowed_box\n\n// This exists only to check what happens when parentheses are already present.\n// Even though the current implementation doesn't put extra parentheses,\n// it's fine that unnecessary parentheses appear in the future for some reason.\npub fn test20(_display: &Box<(dyn Display + Send)>) {}\n//~^ borrowed_box\n\n#[allow(clippy::borrowed_box)]\ntrait Trait {\n    fn f(b: &Box<bool>);\n}\n\n// Trait impls are not linted\nimpl Trait for () {\n    fn f(_: &Box<bool>) {}\n}\n\nfn main() {\n    test1(&mut Box::new(false));\n    test2();\n    test5(&mut (Box::new(false) as Box<dyn Any>));\n    test6();\n    test9(&mut (Box::new(false) as Box<dyn Any + Send + Sync>));\n    test10();\n}\n"
  },
  {
    "path": "tests/ui/borrow_box.stderr",
    "content": "error: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:25:14\n   |\nLL |     let foo: &Box<bool>;\n   |              ^^^^^^^^^^ help: try: `&bool`\n   |\nnote: the lint level is defined here\n  --> tests/ui/borrow_box.rs:1:9\n   |\nLL | #![deny(clippy::borrowed_box)]\n   |         ^^^^^^^^^^^^^^^^^^^^\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:30:10\n   |\nLL |     foo: &'a Box<bool>,\n   |          ^^^^^^^^^^^^^ help: try: `&'a bool`\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:35:17\n   |\nLL |     fn test4(a: &Box<bool>);\n   |                 ^^^^^^^^^^ help: try: `&bool`\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:96:25\n   |\nLL | pub fn test14(_display: &Box<dyn Display>) {}\n   |                         ^^^^^^^^^^^^^^^^^ help: try: `&dyn Display`\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:99:25\n   |\nLL | pub fn test15(_display: &Box<dyn Display + Send>) {}\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)`\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:102:29\n   |\nLL | pub fn test16<'a>(_display: &'a Box<dyn Display + 'a>) {}\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (dyn Display + 'a)`\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:105:25\n   |\nLL | pub fn test17(_display: &Box<impl Display>) {}\n   |                         ^^^^^^^^^^^^^^^^^^ help: try: `&impl Display`\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:108:25\n   |\nLL | pub fn test18(_display: &Box<impl Display + Send>) {}\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(impl Display + Send)`\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:111:29\n   |\nLL | pub fn test19<'a>(_display: &'a Box<impl Display + 'a>) {}\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (impl Display + 'a)`\n\nerror: you seem to be trying to use `&Box<T>`. Consider using just `&T`\n  --> tests/ui/borrow_box.rs:117:25\n   |\nLL | pub fn test20(_display: &Box<(dyn Display + Send)>) {}\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/borrow_deref_ref.fixed",
    "content": "//@aux-build: proc_macros.rs\n\n#![allow(dead_code, unused_variables)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nfn main() {}\n\nmod should_lint {\n    fn one_help() {\n        let a = &12;\n        let b = a;\n        //~^ borrow_deref_ref\n\n        let b = &mut bar(&12);\n        //~^ borrow_deref_ref\n    }\n\n    fn bar(x: &u32) -> &u32 {\n        x\n    }\n}\n\n// this mod explains why we should not lint `&mut &* (&T)`\nmod should_not_lint1 {\n    fn foo(x: &mut &u32) {\n        *x = &1;\n    }\n\n    fn main() {\n        let mut x = &0;\n        foo(&mut &*x); // should not lint\n        assert_eq!(*x, 0);\n\n        foo(&mut x);\n        assert_eq!(*x, 1);\n    }\n}\n\n// similar to should_not_lint1\nmod should_not_lint2 {\n    struct S<'a> {\n        a: &'a u32,\n        b: u32,\n    }\n\n    fn main() {\n        let s = S { a: &1, b: 1 };\n        let x = &mut &*s.a;\n        *x = &2;\n    }\n}\n\nwith_span!(\n    span\n\n    fn just_returning(x: &u32) -> &u32 {\n        x\n    }\n\n    fn dont_lint_proc_macro() {\n        let a = &mut &*just_returning(&12);\n    }\n);\n// this mod explains why we should not lint `& &* (&T)`\nmod false_negative {\n    fn foo() {\n        let x = &12;\n        let addr_x = &x as *const _ as usize;\n        let addr_y = &x as *const _ as usize; // assert ok\n        //\n        //~^^ borrow_deref_ref\n        // let addr_y = &x as *const _ as usize; // assert fail\n        assert_ne!(addr_x, addr_y);\n    }\n}\n\nfn issue_13584() {\n    let s = \"Hello, world!\\n\";\n    let p = &raw const *s;\n    let _ = p as *const i8;\n}\n\nmod issue_9905 {\n    use std::{fs, io};\n\n    pub enum File {\n        Stdio,\n        File(fs::File),\n    }\n\n    impl io::Read for &'_ File {\n        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n            match self {\n                File::Stdio => io::stdin().read(buf),\n                File::File(file) => (&*file).read(buf),\n            }\n        }\n    }\n}\n\nmod issue_11346 {\n    struct Struct;\n\n    impl Struct {\n        fn foo(self: &mut &Self) {}\n    }\n\n    trait Trait {\n        fn bar(&mut self) {}\n    }\n\n    impl Trait for &Struct {}\n\n    fn bar() {\n        let s = &Struct;\n        (&*s).foo();\n        (&*s).bar();\n\n        let mut s = &Struct;\n        s.foo(); // To avoid a warning about `s` not needing to be mutable\n        s.foo();\n        //~^ borrow_deref_ref\n    }\n}\n\nfn issue_14934() {\n    let x: &'static str = \"x\";\n    let y = \"y\".to_string();\n    {\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = &*x; // Do not lint\n        *x = &*y;\n    }\n    {\n        let mut x = x;\n        //~^ borrow_deref_ref\n        x = &*y;\n    }\n    {\n        #[expect(clippy::toplevel_ref_arg, clippy::needless_borrow)]\n        let ref x = x;\n        //~^ borrow_deref_ref\n    }\n    {\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = std::convert::identity(x);\n        //~^ borrow_deref_ref\n        *x = &*y;\n    }\n    {\n        #[derive(Clone)]\n        struct S(&'static str);\n        let s = S(\"foo\");\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = &*s.0; // Do not lint\n        *x = \"bar\";\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = s.clone().0;\n        //~^ borrow_deref_ref\n        *x = \"bar\";\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = &*std::convert::identity(&s).0;\n        *x = \"bar\";\n    }\n    {\n        let y = &1;\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = { y };\n        //~^ borrow_deref_ref\n    }\n}\n\nmod issue16556 {\n    use std::pin::Pin;\n\n    async fn async_main() {\n        for_each_city(|city| {\n            Box::pin(async {\n                // Do not lint, as it would not compile without reborrowing\n                let city = &*city;\n                println!(\"{city}\")\n            })\n        })\n        .await;\n    }\n\n    async fn for_each_city<F>(mut f: F)\n    where\n        F: for<'c> FnMut(&'c str) -> Pin<Box<dyn Future<Output = ()> + Send + 'c>>,\n    {\n        for x in [\"New York\", \"London\", \"Tokyo\"] {\n            f(x).await;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/borrow_deref_ref.rs",
    "content": "//@aux-build: proc_macros.rs\n\n#![allow(dead_code, unused_variables)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nfn main() {}\n\nmod should_lint {\n    fn one_help() {\n        let a = &12;\n        let b = &*a;\n        //~^ borrow_deref_ref\n\n        let b = &mut &*bar(&12);\n        //~^ borrow_deref_ref\n    }\n\n    fn bar(x: &u32) -> &u32 {\n        x\n    }\n}\n\n// this mod explains why we should not lint `&mut &* (&T)`\nmod should_not_lint1 {\n    fn foo(x: &mut &u32) {\n        *x = &1;\n    }\n\n    fn main() {\n        let mut x = &0;\n        foo(&mut &*x); // should not lint\n        assert_eq!(*x, 0);\n\n        foo(&mut x);\n        assert_eq!(*x, 1);\n    }\n}\n\n// similar to should_not_lint1\nmod should_not_lint2 {\n    struct S<'a> {\n        a: &'a u32,\n        b: u32,\n    }\n\n    fn main() {\n        let s = S { a: &1, b: 1 };\n        let x = &mut &*s.a;\n        *x = &2;\n    }\n}\n\nwith_span!(\n    span\n\n    fn just_returning(x: &u32) -> &u32 {\n        x\n    }\n\n    fn dont_lint_proc_macro() {\n        let a = &mut &*just_returning(&12);\n    }\n);\n// this mod explains why we should not lint `& &* (&T)`\nmod false_negative {\n    fn foo() {\n        let x = &12;\n        let addr_x = &x as *const _ as usize;\n        let addr_y = &&*x as *const _ as usize; // assert ok\n        //\n        //~^^ borrow_deref_ref\n        // let addr_y = &x as *const _ as usize; // assert fail\n        assert_ne!(addr_x, addr_y);\n    }\n}\n\nfn issue_13584() {\n    let s = \"Hello, world!\\n\";\n    let p = &raw const *s;\n    let _ = p as *const i8;\n}\n\nmod issue_9905 {\n    use std::{fs, io};\n\n    pub enum File {\n        Stdio,\n        File(fs::File),\n    }\n\n    impl io::Read for &'_ File {\n        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n            match self {\n                File::Stdio => io::stdin().read(buf),\n                File::File(file) => (&*file).read(buf),\n            }\n        }\n    }\n}\n\nmod issue_11346 {\n    struct Struct;\n\n    impl Struct {\n        fn foo(self: &mut &Self) {}\n    }\n\n    trait Trait {\n        fn bar(&mut self) {}\n    }\n\n    impl Trait for &Struct {}\n\n    fn bar() {\n        let s = &Struct;\n        (&*s).foo();\n        (&*s).bar();\n\n        let mut s = &Struct;\n        s.foo(); // To avoid a warning about `s` not needing to be mutable\n        (&*s).foo();\n        //~^ borrow_deref_ref\n    }\n}\n\nfn issue_14934() {\n    let x: &'static str = \"x\";\n    let y = \"y\".to_string();\n    {\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = &*x; // Do not lint\n        *x = &*y;\n    }\n    {\n        let mut x = &*x;\n        //~^ borrow_deref_ref\n        x = &*y;\n    }\n    {\n        #[expect(clippy::toplevel_ref_arg, clippy::needless_borrow)]\n        let ref x = &*x;\n        //~^ borrow_deref_ref\n    }\n    {\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = &*std::convert::identity(x);\n        //~^ borrow_deref_ref\n        *x = &*y;\n    }\n    {\n        #[derive(Clone)]\n        struct S(&'static str);\n        let s = S(\"foo\");\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = &*s.0; // Do not lint\n        *x = \"bar\";\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = &*s.clone().0;\n        //~^ borrow_deref_ref\n        *x = \"bar\";\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = &*std::convert::identity(&s).0;\n        *x = \"bar\";\n    }\n    {\n        let y = &1;\n        #[expect(clippy::toplevel_ref_arg)]\n        let ref mut x = { &*y };\n        //~^ borrow_deref_ref\n    }\n}\n\nmod issue16556 {\n    use std::pin::Pin;\n\n    async fn async_main() {\n        for_each_city(|city| {\n            Box::pin(async {\n                // Do not lint, as it would not compile without reborrowing\n                let city = &*city;\n                println!(\"{city}\")\n            })\n        })\n        .await;\n    }\n\n    async fn for_each_city<F>(mut f: F)\n    where\n        F: for<'c> FnMut(&'c str) -> Pin<Box<dyn Future<Output = ()> + Send + 'c>>,\n    {\n        for x in [\"New York\", \"London\", \"Tokyo\"] {\n            f(x).await;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/borrow_deref_ref.stderr",
    "content": "error: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:13:17\n   |\nLL |         let b = &*a;\n   |                 ^^^ help: if you would like to reborrow, try removing `&*`: `a`\n   |\n   = note: `-D clippy::borrow-deref-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::borrow_deref_ref)]`\n\nerror: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:16:22\n   |\nLL |         let b = &mut &*bar(&12);\n   |                      ^^^^^^^^^^ help: if you would like to reborrow, try removing `&*`: `bar(&12)`\n\nerror: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:71:23\n   |\nLL |         let addr_y = &&*x as *const _ as usize; // assert ok\n   |                       ^^^ help: if you would like to reborrow, try removing `&*`: `x`\n\nerror: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:123:9\n   |\nLL |         (&*s).foo();\n   |         ^^^^^ help: if you would like to reborrow, try removing `&*`: `s`\n\nerror: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:137:21\n   |\nLL |         let mut x = &*x;\n   |                     ^^^ help: if you would like to reborrow, try removing `&*`: `x`\n\nerror: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:143:21\n   |\nLL |         let ref x = &*x;\n   |                     ^^^ help: if you would like to reborrow, try removing `&*`: `x`\n\nerror: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:148:25\n   |\nLL |         let ref mut x = &*std::convert::identity(x);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you would like to reborrow, try removing `&*`: `std::convert::identity(x)`\n\nerror: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:160:25\n   |\nLL |         let ref mut x = &*s.clone().0;\n   |                         ^^^^^^^^^^^^^ help: if you would like to reborrow, try removing `&*`: `s.clone().0`\n\nerror: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref.rs:170:27\n   |\nLL |         let ref mut x = { &*y };\n   |                           ^^^ help: if you would like to reborrow, try removing `&*`: `y`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/borrow_deref_ref_unfixable.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![allow(dead_code, unused_variables)]\n\nfn main() {}\n\nmod should_lint {\n    fn two_helps() {\n        let s = &String::new();\n        let x: &str = &*s;\n        //~^ borrow_deref_ref\n    }\n}\n"
  },
  {
    "path": "tests/ui/borrow_deref_ref_unfixable.stderr",
    "content": "error: deref on an immutable reference\n  --> tests/ui/borrow_deref_ref_unfixable.rs:9:23\n   |\nLL |         let x: &str = &*s;\n   |                       ^^^\n   |\n   = note: `-D clippy::borrow-deref-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::borrow_deref_ref)]`\nhelp: if you would like to reborrow, try removing `&*`\n   |\nLL -         let x: &str = &*s;\nLL +         let x: &str = s;\n   |\nhelp: if you would like to deref, try using `&**`\n   |\nLL |         let x: &str = &**s;\n   |                         +\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/borrow_interior_mutable_const.rs",
    "content": "//@aux-build:interior_mutable_const.rs\n\n#![deny(clippy::borrow_interior_mutable_const)]\n#![allow(\n    clippy::declare_interior_mutable_const,\n    clippy::out_of_bounds_indexing,\n    const_item_interior_mutations,\n    const_item_mutation,\n    unconditional_panic\n)]\n\nuse core::cell::{Cell, UnsafeCell};\nuse core::ops::{Deref, Index};\n\ntrait ConstDefault {\n    const DEFAULT: Self;\n}\nimpl ConstDefault for u32 {\n    const DEFAULT: Self = 0;\n}\nimpl<T: ConstDefault> ConstDefault for Cell<T> {\n    const DEFAULT: Self = Cell::new(T::DEFAULT);\n}\n\nfn main() {\n    {\n        const C: String = String::new();\n        let _ = C;\n        let _ = &C;\n        let _ = C.len();\n        let _ = &*C;\n    }\n    {\n        const C: UnsafeCell<u32> = UnsafeCell::new(0);\n        let _ = C;\n        let _ = &C; //~ borrow_interior_mutable_const\n        let _ = C.into_inner();\n        let _ = C.get(); //~ borrow_interior_mutable_const\n    }\n    {\n        const C: Cell<u32> = Cell::new(0);\n        let _ = C;\n        let _ = &C; //~ borrow_interior_mutable_const\n        let _ = &mut C; //~ borrow_interior_mutable_const\n        let _ = C.into_inner();\n\n        let local = C;\n        C.swap(&local) //~ borrow_interior_mutable_const\n    }\n    {\n        const C: [(Cell<u32>,); 1] = [(Cell::new(0),)];\n        let _ = C;\n        let _ = &C; //~ borrow_interior_mutable_const\n        let _ = &C[0]; //~ borrow_interior_mutable_const\n        let _ = &C[0].0; //~ borrow_interior_mutable_const\n        C[0].0.set(1); //~ borrow_interior_mutable_const\n    }\n    {\n        struct S(Cell<u32>);\n        impl S {\n            const C: Self = Self(Cell::new(0));\n        }\n        impl Deref for S {\n            type Target = Cell<u32>;\n            fn deref(&self) -> &Self::Target {\n                &self.0\n            }\n        }\n        let _ = S::C;\n        let _ = S::C.0;\n        let _ = &S::C; //~ borrow_interior_mutable_const\n        let _ = &S::C.0; //~ borrow_interior_mutable_const\n        S::C.set(1); //~ borrow_interior_mutable_const\n        let _ = &*S::C; //~ borrow_interior_mutable_const\n        (*S::C).set(1); //~ borrow_interior_mutable_const\n    }\n    {\n        enum E {\n            Cell(Cell<u32>),\n            Other,\n        }\n        const CELL: E = E::Cell(Cell::new(0));\n        const OTHER: E = E::Other;\n\n        let _ = CELL;\n        let _ = &CELL; //~ borrow_interior_mutable_const\n        let E::Cell(_) = CELL else {\n            return;\n        };\n\n        let _ = OTHER;\n        let _ = &OTHER;\n        let E::Cell(ref _x) = OTHER else {\n            return;\n        };\n    }\n    {\n        struct S<T> {\n            cell: (Cell<T>, u32),\n            other: Option<T>,\n        }\n        impl<T: ConstDefault + Copy> S<T> {\n            const C: Self = Self {\n                cell: (Cell::<T>::DEFAULT, 0),\n                other: Some(T::DEFAULT),\n            };\n\n            fn f() {\n                let _ = Self::C;\n                let _ = &Self::C; //~ borrow_interior_mutable_const\n                let _ = Self::C.other;\n                let _ = &Self::C.other;\n                let _ = &Self::C.cell; //~ borrow_interior_mutable_const\n                let _ = &Self::C.cell.0; //~ borrow_interior_mutable_const\n                Self::C.cell.0.set(T::DEFAULT); //~ borrow_interior_mutable_const\n                let _ = &Self::C.cell.1;\n            }\n        }\n    }\n    {\n        trait T {\n            const VALUE: Option<Cell<u32>> = Some(Cell::new(0));\n        }\n        impl T for u32 {}\n        impl T for i32 {\n            const VALUE: Option<Cell<u32>> = None;\n        }\n\n        let _ = &u32::VALUE; //~ borrow_interior_mutable_const\n        let _ = &i32::VALUE;\n    }\n    {\n        trait Trait<T: ConstDefault> {\n            type T<U: ConstDefault>: ConstDefault;\n            const VALUE: Option<Self::T<T>> = Some(Self::T::<T>::DEFAULT);\n        }\n        impl<T: ConstDefault> Trait<T> for u32 {\n            type T<U: ConstDefault> = Cell<U>;\n        }\n        impl<T: ConstDefault> Trait<T> for i32 {\n            type T<U: ConstDefault> = Cell<U>;\n            const VALUE: Option<Cell<T>> = None;\n        }\n\n        fn f<T: ConstDefault>() {\n            let _ = &<u32 as Trait<T>>::VALUE; //~ borrow_interior_mutable_const\n            let _ = &<i32 as Trait<T>>::VALUE;\n        }\n    }\n    {\n        trait Trait {\n            const UNFROZEN: Option<Cell<u32>> = Some(Cell::new(0));\n            const FROZEN: Option<Cell<u32>> = None;\n            const NON_FREEZE: u32 = 0;\n        }\n        fn f<T: Trait>() {\n            // None of these are guaranteed to be frozen, so don't lint.\n            let _ = &T::UNFROZEN;\n            let _ = &T::FROZEN;\n            let _ = &T::NON_FREEZE;\n        }\n    }\n    {\n        struct S([Option<Cell<u32>>; 2]);\n        impl Index<usize> for S {\n            type Output = Option<Cell<u32>>;\n            fn index(&self, idx: usize) -> &Self::Output {\n                &self.0[idx]\n            }\n        }\n\n        const C: S = S([Some(Cell::new(0)), None]);\n        let _ = &C; //~ borrow_interior_mutable_const\n        let _ = &C[0]; //~ borrow_interior_mutable_const\n        let _ = &C.0[0]; //~ borrow_interior_mutable_const\n        let _ = &C.0[1];\n    }\n    {\n        const C: [Option<Cell<u32>>; 2] = [None, None];\n        let _ = &C[0];\n        let _ = &C[1];\n        let _ = &C[2];\n\n        fn f(i: usize) {\n            let _ = &C[i];\n        }\n    }\n    {\n        const C: [Option<Cell<u32>>; 2] = [None, Some(Cell::new(0))];\n        let _ = &C[0];\n        let _ = &C[1]; //~ borrow_interior_mutable_const\n        let _ = &C[2];\n\n        fn f(i: usize) {\n            let _ = &C[i]; //~ borrow_interior_mutable_const\n        }\n    }\n    {\n        let _ = &interior_mutable_const::WRAPPED_PRIVATE_UNFROZEN_VARIANT; //~ borrow_interior_mutable_const\n        let _ = &interior_mutable_const::WRAPPED_PRIVATE_FROZEN_VARIANT;\n    }\n    {\n        type Cell2<T> = Cell<T>;\n        type MyCell = Cell2<u32>;\n        struct S(Option<MyCell>);\n        trait T {\n            type Assoc;\n        }\n        struct S2<T>(T, T, u32);\n        impl T for S {\n            type Assoc = S2<Self>;\n        }\n        type Assoc<X> = <X as T>::Assoc;\n        impl S {\n            const VALUE: Assoc<Self> = S2(Self(None), Self(Some(Cell::new(0))), 0);\n        }\n        let _ = &S::VALUE; //~ borrow_interior_mutable_const\n        let _ = &S::VALUE.0;\n        let _ = &S::VALUE.1; //~ borrow_interior_mutable_const\n        let _ = &S::VALUE.2;\n    }\n    {\n        pub struct Foo<T, const N: usize>(pub Entry<N>, pub T);\n\n        pub struct Entry<const N: usize>(pub Cell<[u32; N]>);\n\n        impl<const N: usize> Entry<N> {\n            const INIT: Self = Self(Cell::new([42; N]));\n        }\n\n        impl<T, const N: usize> Foo<T, N> {\n            pub fn make_foo(v: T) -> Self {\n                // Used to ICE due to incorrect instantiation.\n                Foo(Entry::INIT, v)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/borrow_interior_mutable_const.stderr",
    "content": "error: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:36:17\n   |\nLL |         let _ = &C;\n   |                 ^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\nnote: the lint level is defined here\n  --> tests/ui/borrow_interior_mutable_const.rs:3:9\n   |\nLL | #![deny(clippy::borrow_interior_mutable_const)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:38:17\n   |\nLL |         let _ = C.get();\n   |                 ^\n   |\n   = note: there is a compiler inserted borrow here\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:43:17\n   |\nLL |         let _ = &C;\n   |                 ^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:44:17\n   |\nLL |         let _ = &mut C;\n   |                 ^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:48:9\n   |\nLL |         C.swap(&local)\n   |         ^\n   |\n   = note: there is a compiler inserted borrow here\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:53:17\n   |\nLL |         let _ = &C;\n   |                 ^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:54:17\n   |\nLL |         let _ = &C[0];\n   |                 ^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:55:17\n   |\nLL |         let _ = &C[0].0;\n   |                 ^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:56:9\n   |\nLL |         C[0].0.set(1);\n   |         ^^^^^^\n   |\n   = note: there is a compiler inserted borrow here\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:71:17\n   |\nLL |         let _ = &S::C;\n   |                 ^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:72:17\n   |\nLL |         let _ = &S::C.0;\n   |                 ^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:73:9\n   |\nLL |         S::C.set(1);\n   |         ^^^^\n   |\n   = note: there is a compiler inserted call to `Deref::deref` here\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:74:18\n   |\nLL |         let _ = &*S::C;\n   |                  ^^^^^\n   |\n   = note: this deref expression is a call to `Deref::deref`\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:75:9\n   |\nLL |         (*S::C).set(1);\n   |         ^^^^^^^\n   |\n   = note: this deref expression is a call to `Deref::deref`\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:86:17\n   |\nLL |         let _ = &CELL;\n   |                 ^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:110:25\n   |\nLL |                 let _ = &Self::C;\n   |                         ^^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:113:25\n   |\nLL |                 let _ = &Self::C.cell;\n   |                         ^^^^^^^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:114:25\n   |\nLL |                 let _ = &Self::C.cell.0;\n   |                         ^^^^^^^^^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:115:17\n   |\nLL |                 Self::C.cell.0.set(T::DEFAULT);\n   |                 ^^^^^^^^^^^^^^\n   |\n   = note: there is a compiler inserted borrow here\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:129:17\n   |\nLL |         let _ = &u32::VALUE;\n   |                 ^^^^^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:146:21\n   |\nLL |             let _ = &<u32 as Trait<T>>::VALUE;\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:173:17\n   |\nLL |         let _ = &C;\n   |                 ^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:174:18\n   |\nLL |         let _ = &C[0];\n   |                  ^^^^\n   |\n   = note: this index expression is a call to `Index::index`\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:175:17\n   |\nLL |         let _ = &C.0[0];\n   |                 ^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:191:17\n   |\nLL |         let _ = &C[1];\n   |                 ^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:195:21\n   |\nLL |             let _ = &C[i];\n   |                     ^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:199:17\n   |\nLL |         let _ = &interior_mutable_const::WRAPPED_PRIVATE_UNFROZEN_VARIANT;\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:217:17\n   |\nLL |         let _ = &S::VALUE;\n   |                 ^^^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: borrow of a named constant with interior mutability\n  --> tests/ui/borrow_interior_mutable_const.rs:219:17\n   |\nLL |         let _ = &S::VALUE.1;\n   |                 ^^^^^^^^^^^\n   |\n   = help: this lint can be silenced by assigning the value to a local variable before borrowing\n\nerror: aborting due to 29 previous errors\n\n"
  },
  {
    "path": "tests/ui/box_collection.rs",
    "content": "#![allow(\n    clippy::boxed_local,\n    clippy::needless_pass_by_value,\n    clippy::disallowed_names,\n    unused\n)]\n\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};\n\nmacro_rules! boxit {\n    ($init:expr, $x:ty) => {\n        let _: Box<$x> = Box::new($init);\n    };\n}\n\nfn test_macro() {\n    boxit!(vec![1], Vec<u8>);\n}\n\nfn test1(foo: Box<Vec<bool>>) {}\n//~^ box_collection\n\nfn test2(foo: Box<dyn Fn(Vec<u32>)>) {\n    // pass if #31 is fixed\n    foo(vec![1, 2, 3])\n}\n\nfn test3(foo: Box<String>) {}\n//~^ box_collection\n\nfn test4(foo: Box<HashMap<String, String>>) {}\n//~^ box_collection\n\nfn test5(foo: Box<HashSet<i64>>) {}\n//~^ box_collection\n\nfn test6(foo: Box<VecDeque<i32>>) {}\n//~^ box_collection\n\nfn test7(foo: Box<LinkedList<i16>>) {}\n//~^ box_collection\n\nfn test8(foo: Box<BTreeMap<i8, String>>) {}\n//~^ box_collection\n\nfn test9(foo: Box<BTreeSet<u64>>) {}\n//~^ box_collection\n\nfn test10(foo: Box<BinaryHeap<u32>>) {}\n//~^ box_collection\n\nfn test_local_not_linted() {\n    let _: Box<Vec<bool>>;\n}\n\n// All of these test should be allowed because they are part of the\n// public api and `avoid_breaking_exported_api` is `false` by default.\npub fn pub_test(foo: Box<Vec<bool>>) {}\n\npub fn pub_test_ret() -> Box<Vec<bool>> {\n    Box::default()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/box_collection.stderr",
    "content": "error: you seem to be trying to use `Box<Vec<..>>`. Consider using just `Vec<..>`\n  --> tests/ui/box_collection.rs:20:15\n   |\nLL | fn test1(foo: Box<Vec<bool>>) {}\n   |               ^^^^^^^^^^^^^^\n   |\n   = help: `Vec<..>` is already on the heap, `Box<Vec<..>>` makes an extra allocation\n   = note: `-D clippy::box-collection` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::box_collection)]`\n\nerror: you seem to be trying to use `Box<String>`. Consider using just `String`\n  --> tests/ui/box_collection.rs:28:15\n   |\nLL | fn test3(foo: Box<String>) {}\n   |               ^^^^^^^^^^^\n   |\n   = help: `String` is already on the heap, `Box<String>` makes an extra allocation\n\nerror: you seem to be trying to use `Box<HashMap<..>>`. Consider using just `HashMap<..>`\n  --> tests/ui/box_collection.rs:31:15\n   |\nLL | fn test4(foo: Box<HashMap<String, String>>) {}\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `HashMap<..>` is already on the heap, `Box<HashMap<..>>` makes an extra allocation\n\nerror: you seem to be trying to use `Box<HashSet<..>>`. Consider using just `HashSet<..>`\n  --> tests/ui/box_collection.rs:34:15\n   |\nLL | fn test5(foo: Box<HashSet<i64>>) {}\n   |               ^^^^^^^^^^^^^^^^^\n   |\n   = help: `HashSet<..>` is already on the heap, `Box<HashSet<..>>` makes an extra allocation\n\nerror: you seem to be trying to use `Box<VecDeque<..>>`. Consider using just `VecDeque<..>`\n  --> tests/ui/box_collection.rs:37:15\n   |\nLL | fn test6(foo: Box<VecDeque<i32>>) {}\n   |               ^^^^^^^^^^^^^^^^^^\n   |\n   = help: `VecDeque<..>` is already on the heap, `Box<VecDeque<..>>` makes an extra allocation\n\nerror: you seem to be trying to use `Box<LinkedList<..>>`. Consider using just `LinkedList<..>`\n  --> tests/ui/box_collection.rs:40:15\n   |\nLL | fn test7(foo: Box<LinkedList<i16>>) {}\n   |               ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `LinkedList<..>` is already on the heap, `Box<LinkedList<..>>` makes an extra allocation\n\nerror: you seem to be trying to use `Box<BTreeMap<..>>`. Consider using just `BTreeMap<..>`\n  --> tests/ui/box_collection.rs:43:15\n   |\nLL | fn test8(foo: Box<BTreeMap<i8, String>>) {}\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `BTreeMap<..>` is already on the heap, `Box<BTreeMap<..>>` makes an extra allocation\n\nerror: you seem to be trying to use `Box<BTreeSet<..>>`. Consider using just `BTreeSet<..>`\n  --> tests/ui/box_collection.rs:46:15\n   |\nLL | fn test9(foo: Box<BTreeSet<u64>>) {}\n   |               ^^^^^^^^^^^^^^^^^^\n   |\n   = help: `BTreeSet<..>` is already on the heap, `Box<BTreeSet<..>>` makes an extra allocation\n\nerror: you seem to be trying to use `Box<BinaryHeap<..>>`. Consider using just `BinaryHeap<..>`\n  --> tests/ui/box_collection.rs:49:16\n   |\nLL | fn test10(foo: Box<BinaryHeap<u32>>) {}\n   |                ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `BinaryHeap<..>` is already on the heap, `Box<BinaryHeap<..>>` makes an extra allocation\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/box_default.fixed",
    "content": "#![warn(clippy::box_default)]\n#![allow(clippy::boxed_local, clippy::default_constructed_unit_structs)]\n\n#[derive(Default)]\nstruct ImplementsDefault;\n\nstruct OwnDefault;\n\nimpl OwnDefault {\n    fn default() -> Self {\n        Self\n    }\n}\n\nmacro_rules! default {\n    () => {\n        Default::default()\n    };\n}\n\nmacro_rules! string_new {\n    () => {\n        String::new()\n    };\n}\n\nmacro_rules! box_new {\n    ($e:expr) => {\n        Box::new($e)\n    };\n}\n\nfn main() {\n    let string1: Box<String> = Box::default();\n    //~^ box_default\n    let string2: Box<String> = Box::default();\n    //~^ box_default\n    let impl1: Box<ImplementsDefault> = Box::default();\n    //~^ box_default\n    let vec: Box<Vec<u8>> = Box::default();\n    //~^ box_default\n    let byte: Box<u8> = Box::default();\n    //~^ box_default\n    let vec2: Box<Vec<ImplementsDefault>> = Box::default();\n    //~^ box_default\n    let vec3: Box<Vec<bool>> = Box::default();\n    //~^ box_default\n\n    let plain_default = Box::default();\n    //~^ box_default\n    let _: Box<String> = plain_default;\n\n    let _: Box<String> = Box::new(default!());\n    let _: Box<String> = Box::new(string_new!());\n    let _: Box<String> = box_new!(Default::default());\n    let _: Box<String> = box_new!(String::new());\n    let _: Box<String> = box_new!(default!());\n    let _: Box<String> = box_new!(string_new!());\n\n    let own: Box<OwnDefault> = Box::new(OwnDefault::default()); // should not lint\n\n    // Do not suggest where a turbofish would be required\n    let impl2 = Box::new(ImplementsDefault::default());\n    let impl3 = Box::new(<ImplementsDefault as Default>::default());\n    let vec4: Box<_> = Box::new(Vec::from([false; 0]));\n    let more = ret_ty_fn();\n    call_ty_fn(Box::default());\n    //~^ box_default\n    issue_10381();\n\n    // `Box::<Option<_>>::default()` would be valid here, but not `Box::default()` or\n    // `Box::<Option<{closure@...}>::default()`\n    //\n    // Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563\n    let mut unnameable = Box::new(Option::default());\n    let _ = unnameable.insert(|| {});\n\n    let _ = Box::into_raw(Box::new(String::default()));\n}\n\nfn ret_ty_fn() -> Box<bool> {\n    Box::new(bool::default()) // Could lint, currently doesn't\n}\n\nfn call_ty_fn(_b: Box<u8>) {\n    issue_9621_dyn_trait();\n}\n\nstruct X<T>(T);\n\nimpl<T: Default> X<T> {\n    fn x(_: Box<T>) {}\n\n    fn same_generic_param() {\n        Self::x(Box::default());\n        //~^ box_default\n    }\n}\n\nuse std::io::{Read, Result};\n\nimpl Read for ImplementsDefault {\n    fn read(&mut self, _: &mut [u8]) -> Result<usize> {\n        Ok(0)\n    }\n}\n\nfn issue_9621_dyn_trait() {\n    let _: Box<dyn Read> = Box::new(ImplementsDefault::default());\n    issue_10089();\n}\n\nfn issue_10089() {\n    let _closure = || {\n        #[derive(Default)]\n        struct WeirdPathed;\n\n        let _ = Box::new(WeirdPathed::default());\n    };\n}\n\nfn issue_10381() {\n    #[derive(Default)]\n    pub struct Foo {}\n    pub trait Bar {}\n    impl Bar for Foo {}\n\n    fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {\n        if i.is_multiple_of(2) {\n            Some(Box::new(Foo::default()))\n        } else {\n            None\n        }\n    }\n\n    assert!(maybe_get_bar(2).is_some());\n}\n\n// Issue #11927: The quickfix for the `Box::new` suggests replacing with `Box::<Inner>::default()`,\n// removing the `outer::` segment.\nfn issue_11927() {\n    mod outer {\n        #[derive(Default)]\n        pub struct Inner {\n            _i: usize,\n        }\n    }\n\n    fn foo() {\n        let _b = Box::new(outer::Inner::default());\n        let _b = Box::new(std::collections::HashSet::<i32>::new());\n    }\n}\n"
  },
  {
    "path": "tests/ui/box_default.rs",
    "content": "#![warn(clippy::box_default)]\n#![allow(clippy::boxed_local, clippy::default_constructed_unit_structs)]\n\n#[derive(Default)]\nstruct ImplementsDefault;\n\nstruct OwnDefault;\n\nimpl OwnDefault {\n    fn default() -> Self {\n        Self\n    }\n}\n\nmacro_rules! default {\n    () => {\n        Default::default()\n    };\n}\n\nmacro_rules! string_new {\n    () => {\n        String::new()\n    };\n}\n\nmacro_rules! box_new {\n    ($e:expr) => {\n        Box::new($e)\n    };\n}\n\nfn main() {\n    let string1: Box<String> = Box::new(Default::default());\n    //~^ box_default\n    let string2: Box<String> = Box::new(String::new());\n    //~^ box_default\n    let impl1: Box<ImplementsDefault> = Box::new(Default::default());\n    //~^ box_default\n    let vec: Box<Vec<u8>> = Box::new(Vec::new());\n    //~^ box_default\n    let byte: Box<u8> = Box::new(u8::default());\n    //~^ box_default\n    let vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]);\n    //~^ box_default\n    let vec3: Box<Vec<bool>> = Box::new(Vec::from([]));\n    //~^ box_default\n\n    let plain_default = Box::new(Default::default());\n    //~^ box_default\n    let _: Box<String> = plain_default;\n\n    let _: Box<String> = Box::new(default!());\n    let _: Box<String> = Box::new(string_new!());\n    let _: Box<String> = box_new!(Default::default());\n    let _: Box<String> = box_new!(String::new());\n    let _: Box<String> = box_new!(default!());\n    let _: Box<String> = box_new!(string_new!());\n\n    let own: Box<OwnDefault> = Box::new(OwnDefault::default()); // should not lint\n\n    // Do not suggest where a turbofish would be required\n    let impl2 = Box::new(ImplementsDefault::default());\n    let impl3 = Box::new(<ImplementsDefault as Default>::default());\n    let vec4: Box<_> = Box::new(Vec::from([false; 0]));\n    let more = ret_ty_fn();\n    call_ty_fn(Box::new(u8::default()));\n    //~^ box_default\n    issue_10381();\n\n    // `Box::<Option<_>>::default()` would be valid here, but not `Box::default()` or\n    // `Box::<Option<{closure@...}>::default()`\n    //\n    // Would have a suggestion after https://github.com/rust-lang/rust/blob/fdd030127cc68afec44a8d3f6341525dd34e50ae/compiler/rustc_middle/src/ty/diagnostics.rs#L554-L563\n    let mut unnameable = Box::new(Option::default());\n    let _ = unnameable.insert(|| {});\n\n    let _ = Box::into_raw(Box::new(String::default()));\n}\n\nfn ret_ty_fn() -> Box<bool> {\n    Box::new(bool::default()) // Could lint, currently doesn't\n}\n\nfn call_ty_fn(_b: Box<u8>) {\n    issue_9621_dyn_trait();\n}\n\nstruct X<T>(T);\n\nimpl<T: Default> X<T> {\n    fn x(_: Box<T>) {}\n\n    fn same_generic_param() {\n        Self::x(Box::new(T::default()));\n        //~^ box_default\n    }\n}\n\nuse std::io::{Read, Result};\n\nimpl Read for ImplementsDefault {\n    fn read(&mut self, _: &mut [u8]) -> Result<usize> {\n        Ok(0)\n    }\n}\n\nfn issue_9621_dyn_trait() {\n    let _: Box<dyn Read> = Box::new(ImplementsDefault::default());\n    issue_10089();\n}\n\nfn issue_10089() {\n    let _closure = || {\n        #[derive(Default)]\n        struct WeirdPathed;\n\n        let _ = Box::new(WeirdPathed::default());\n    };\n}\n\nfn issue_10381() {\n    #[derive(Default)]\n    pub struct Foo {}\n    pub trait Bar {}\n    impl Bar for Foo {}\n\n    fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {\n        if i.is_multiple_of(2) {\n            Some(Box::new(Foo::default()))\n        } else {\n            None\n        }\n    }\n\n    assert!(maybe_get_bar(2).is_some());\n}\n\n// Issue #11927: The quickfix for the `Box::new` suggests replacing with `Box::<Inner>::default()`,\n// removing the `outer::` segment.\nfn issue_11927() {\n    mod outer {\n        #[derive(Default)]\n        pub struct Inner {\n            _i: usize,\n        }\n    }\n\n    fn foo() {\n        let _b = Box::new(outer::Inner::default());\n        let _b = Box::new(std::collections::HashSet::<i32>::new());\n    }\n}\n"
  },
  {
    "path": "tests/ui/box_default.stderr",
    "content": "error: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:34:32\n   |\nLL |     let string1: Box<String> = Box::new(Default::default());\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n   |\n   = note: `-D clippy::box-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::box_default)]`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:36:32\n   |\nLL |     let string2: Box<String> = Box::new(String::new());\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:38:41\n   |\nLL |     let impl1: Box<ImplementsDefault> = Box::new(Default::default());\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:40:29\n   |\nLL |     let vec: Box<Vec<u8>> = Box::new(Vec::new());\n   |                             ^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:42:25\n   |\nLL |     let byte: Box<u8> = Box::new(u8::default());\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:44:45\n   |\nLL |     let vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]);\n   |                                             ^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:46:32\n   |\nLL |     let vec3: Box<Vec<bool>> = Box::new(Vec::from([]));\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:49:25\n   |\nLL |     let plain_default = Box::new(Default::default());\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:67:16\n   |\nLL |     call_ty_fn(Box::new(u8::default()));\n   |                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: `Box::new(_)` of default value\n  --> tests/ui/box_default.rs:95:17\n   |\nLL |         Self::x(Box::new(T::default()));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/box_default_no_std.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::box_default)]\n#![no_std]\n#![crate_type = \"lib\"]\n\npub struct NotBox<T> {\n    _value: T,\n}\n\nimpl<T> NotBox<T> {\n    pub fn new(value: T) -> Self {\n        Self { _value: value }\n    }\n}\n\nimpl<T: Default> Default for NotBox<T> {\n    fn default() -> Self {\n        Self::new(T::default())\n    }\n}\n\npub fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    let _p = NotBox::new(isize::default());\n    0\n}\n"
  },
  {
    "path": "tests/ui/boxed_local.rs",
    "content": "#![allow(\n    clippy::borrowed_box,\n    clippy::needless_pass_by_value,\n    clippy::unused_unit,\n    clippy::redundant_clone,\n    clippy::match_single_binding,\n    clippy::needless_lifetimes\n)]\n#![warn(clippy::boxed_local)]\n\n#[derive(Clone)]\nstruct A;\n\nimpl A {\n    fn foo(&self) {}\n}\n\ntrait Z {\n    fn bar(&self);\n}\n\nimpl Z for A {\n    fn bar(&self) {\n        //nothing\n    }\n}\n\nfn main() {}\n\nfn ok_box_trait(boxed_trait: &Box<dyn Z>) {\n    let boxed_local = boxed_trait;\n    // done\n}\n\nfn warn_call() {\n    let x = Box::new(A);\n    x.foo();\n}\n\nfn warn_arg(x: Box<A>) {\n    //~^ boxed_local\n\n    x.foo();\n}\n\nfn nowarn_closure_arg() {\n    let x = Some(Box::new(A));\n    x.map_or((), |x| take_ref(&x));\n}\n\nfn warn_rename_call() {\n    let x = Box::new(A);\n\n    let y = x;\n    y.foo(); // via autoderef\n}\n\nfn warn_notuse() {\n    let bz = Box::new(A);\n}\n\nfn warn_pass() {\n    let bz = Box::new(A);\n    take_ref(&bz); // via deref coercion\n}\n\nfn nowarn_return() -> Box<A> {\n    Box::new(A) // moved out, \"escapes\"\n}\n\nfn nowarn_move() {\n    let bx = Box::new(A);\n    drop(bx) // moved in, \"escapes\"\n}\nfn nowarn_call() {\n    let bx = Box::new(A);\n    bx.clone(); // method only available to Box, not via autoderef\n}\n\nfn nowarn_pass() {\n    let bx = Box::new(A);\n    take_box(&bx); // fn needs &Box\n}\n\nfn take_box(x: &Box<A>) {}\nfn take_ref(x: &A) {}\n\nfn nowarn_ref_take() {\n    // false positive, should actually warn\n    let x = Box::new(A);\n    let y = &x;\n    take_box(y);\n}\n\nfn nowarn_match() {\n    let x = Box::new(A); // moved into a match\n    match x {\n        y => drop(y),\n    }\n}\n\nfn warn_match() {\n    let x = Box::new(A);\n    match &x {\n        // not moved\n        y => (),\n    }\n}\n\n/// ICE regression test\npub trait Foo {\n    type Item;\n}\n\nimpl<'a> Foo for &'a () {\n    type Item = ();\n}\n\npub struct PeekableSeekable<I: Foo> {\n    _peeked: I::Item,\n}\n\npub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}\n//~^ boxed_local\n\n/// Regression for #916, #1123\n///\n/// This shouldn't warn for `boxed_local`as the implementation of a trait\n/// can't change much about the trait definition.\ntrait BoxedAction {\n    fn do_sth(self: Box<Self>);\n}\n\nimpl BoxedAction for u64 {\n    fn do_sth(self: Box<Self>) {\n        println!(\"{}\", *self)\n    }\n}\n\n/// Regression for #1478\n///\n/// This shouldn't warn for `boxed_local`as self itself is a box type.\ntrait MyTrait {\n    fn do_sth(self);\n}\n\nimpl<T> MyTrait for Box<T> {\n    fn do_sth(self) {}\n}\n\n// Issue #3739 - capture in closures\nmod issue_3739 {\n    use super::A;\n\n    fn consume<T>(_: T) {}\n    fn borrow<T>(_: &T) {}\n\n    fn closure_consume(x: Box<A>) {\n        let _ = move || {\n            consume(x);\n        };\n    }\n\n    fn closure_borrow(x: Box<A>) {\n        let _ = || {\n            borrow(&x);\n        };\n    }\n}\n\n/// Issue #5542\n///\n/// This shouldn't warn for `boxed_local` as it is intended to called from non-Rust code.\npub extern \"C\" fn do_not_warn_me(_c_pointer: Box<String>) -> () {}\n\n#[allow(missing_abi)]\n#[rustfmt::skip] // Forces rustfmt to not add ABI\npub extern fn do_not_warn_me_no_abi(_c_pointer: Box<String>) -> () {}\n\n// Issue #4804 - default implementation in trait\nmod issue4804 {\n    trait DefaultTraitImplTest {\n        // don't warn on `self`\n        fn default_impl(self: Box<Self>) -> u32 {\n            5\n        }\n\n        // warn on `x: Box<u32>`\n        fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {\n            //~^ boxed_local\n\n            4\n        }\n    }\n\n    trait WarnTrait {\n        // warn on `x: Box<u32>`\n        fn foo(x: Box<u32>) {}\n        //~^ boxed_local\n    }\n}\n\nfn check_expect(#[expect(clippy::boxed_local)] x: Box<A>) {\n    x.foo();\n}\n"
  },
  {
    "path": "tests/ui/boxed_local.stderr",
    "content": "error: local variable doesn't need to be boxed here\n  --> tests/ui/boxed_local.rs:40:13\n   |\nLL | fn warn_arg(x: Box<A>) {\n   |             ^\n   |\n   = note: `-D clippy::boxed-local` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`\n\nerror: local variable doesn't need to be boxed here\n  --> tests/ui/boxed_local.rs:123:12\n   |\nLL | pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}\n   |            ^^^^^^^^^^^\n\nerror: local variable doesn't need to be boxed here\n  --> tests/ui/boxed_local.rs:189:44\n   |\nLL |         fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {\n   |                                            ^\n\nerror: local variable doesn't need to be boxed here\n  --> tests/ui/boxed_local.rs:198:16\n   |\nLL |         fn foo(x: Box<u32>) {}\n   |                ^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/false_positives.rs",
    "content": "//@ check-pass\n\n#![allow(dead_code)]\n#![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]\n\nuse std::sync::Mutex;\n\n// ##################################\n// # Issue clippy#7369\n// ##################################\n#[derive(Debug)]\npub struct FooBar {\n    foo: Vec<u32>,\n}\n\nimpl FooBar {\n    pub fn bar(&mut self) {\n        if true {\n            self.foo.pop();\n        } else {\n            self.baz();\n\n            self.foo.pop();\n\n            self.baz()\n        }\n    }\n\n    fn baz(&mut self) {}\n}\n\nfn foo(x: u32, y: u32) -> u32 {\n    x / y\n}\n\nfn main() {\n    let x = (1, 2);\n    let _ = if true {\n        let (x, y) = x;\n        foo(x, y)\n    } else {\n        let (y, x) = x;\n        foo(x, y)\n    };\n\n    let m = Mutex::new(0u32);\n    let l = m.lock().unwrap();\n    let _ = if true {\n        drop(l);\n        println!(\"foo\");\n        m.lock().unwrap();\n        0\n    } else if *l == 0 {\n        drop(l);\n        println!(\"foo\");\n        println!(\"bar\");\n        m.lock().unwrap();\n        1\n    } else {\n        drop(l);\n        println!(\"foo\");\n        println!(\"baz\");\n        m.lock().unwrap();\n        2\n    };\n\n    if true {\n        let _guard = m.lock();\n        println!(\"foo\");\n    } else {\n        println!(\"foo\");\n    }\n\n    if true {\n        let _guard = m.lock();\n        println!(\"foo\");\n        println!(\"bar\");\n    } else {\n        let _guard = m.lock();\n        println!(\"foo\");\n        println!(\"baz\");\n    }\n\n    let mut c = 0;\n    for _ in 0..5 {\n        if c == 0 {\n            c += 1;\n            println!(\"0\");\n        } else if c == 1 {\n            c += 1;\n            println!(\"1\");\n        } else {\n            c += 1;\n            println!(\"more\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/shared_at_bottom.rs",
    "content": "#![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]\n#![allow(\n    clippy::equatable_if_let,\n    clippy::uninlined_format_args,\n    clippy::redundant_pattern_matching,\n    dead_code\n)]\n//@no-rustfix\n// This tests the branches_sharing_code lint at the end of blocks\n\nfn simple_examples() {\n    let x = 1;\n\n    let _ = if x == 7 {\n        println!(\"Branch I\");\n        let start_value = 0;\n        println!(\"=^.^=\");\n\n        // Same but not moveable due to `start_value`\n        let _ = start_value;\n\n        // The rest is self contained and moveable => Only lint the rest\n        let result = false;\n        println!(\"Block end!\");\n        result\n    } else {\n        println!(\"Branch II\");\n        let start_value = 8;\n        println!(\"xD\");\n\n        // Same but not moveable due to `start_value`\n        let _ = start_value;\n\n        // The rest is self contained and moveable => Only lint the rest\n        let result = false;\n        //~^ branches_sharing_code\n\n        println!(\"Block end!\");\n        result\n    };\n\n    // Else if block\n    if x == 9 {\n        println!(\"The index is: 6\");\n\n        println!(\"Same end of block\");\n    } else if x == 8 {\n        println!(\"The index is: 4\");\n\n        // We should only get a lint trigger for the last statement\n        println!(\"This is also eq with the else block\");\n        println!(\"Same end of block\");\n    } else {\n        println!(\"This is also eq with the else block\");\n        println!(\"Same end of block\");\n        //~^ branches_sharing_code\n    }\n\n    // Use of outer scope value\n    let outer_scope_value = \"I'm outside the if block\";\n    if x < 99 {\n        let z = \"How are you\";\n        println!(\"I'm a local because I use the value `z`: `{}`\", z);\n\n        println!(\n            \"I'm moveable because I know: `outer_scope_value`: '{}'\",\n            outer_scope_value\n        );\n    } else {\n        let z = 45678000;\n        println!(\"I'm a local because I use the value `z`: `{}`\", z);\n\n        println!(\n            //~^ branches_sharing_code\n            \"I'm moveable because I know: `outer_scope_value`: '{}'\",\n            outer_scope_value\n        );\n    }\n\n    if x == 9 {\n        if x == 8 {\n            // No parent!!\n            println!(\"---\");\n            println!(\"Hello World\");\n        } else {\n            println!(\"Hello World\");\n            //~^ branches_sharing_code\n        }\n    }\n}\n\n/// Simple examples where the move can cause some problems due to moved values\nfn simple_but_suggestion_is_invalid() {\n    let x = 16;\n\n    // Local value\n    let later_used_value = 17;\n    if x == 9 {\n        let _ = 9;\n        let later_used_value = \"A string value\";\n        println!(\"{}\", later_used_value);\n    } else {\n        let later_used_value = \"A string value\";\n        //~^ branches_sharing_code\n\n        println!(\"{}\", later_used_value);\n        // I'm expecting a note about this\n    }\n    println!(\"{}\", later_used_value);\n\n    // outer function\n    if x == 78 {\n        let simple_examples = \"I now identify as a &str :)\";\n        println!(\"This is the new simple_example: {}\", simple_examples);\n    } else {\n        println!(\"Separator print statement\");\n\n        let simple_examples = \"I now identify as a &str :)\";\n        //~^ branches_sharing_code\n\n        println!(\"This is the new simple_example: {}\", simple_examples);\n    }\n    simple_examples();\n}\n\n/// Tests where the blocks are not linted due to the used value scope\nfn not_moveable_due_to_value_scope() {\n    let x = 18;\n\n    // Using a local value in the moved code\n    if x == 9 {\n        let y = 18;\n        println!(\"y is: `{}`\", y);\n    } else {\n        let y = \"A string\";\n        println!(\"y is: `{}`\", y);\n    }\n\n    // Using a local value in the expression\n    let _ = if x == 0 {\n        let mut result = x + 1;\n\n        println!(\"1. Doing some calculations\");\n        println!(\"2. Some more calculations\");\n        println!(\"3. Setting result\");\n\n        result\n    } else {\n        let mut result = x - 1;\n\n        println!(\"1. Doing some calculations\");\n        println!(\"2. Some more calculations\");\n        println!(\"3. Setting result\");\n\n        result\n    };\n\n    let _ = if x == 7 {\n        let z1 = 100;\n        println!(\"z1: {}\", z1);\n\n        let z2 = z1;\n        println!(\"z2: {}\", z2);\n\n        z2\n    } else {\n        let z1 = 300;\n        println!(\"z1: {}\", z1);\n\n        let z2 = z1;\n        println!(\"z2: {}\", z2);\n\n        z2\n    };\n}\n\n/// This should add a note to the lint msg since the moved expression is not `()`\nfn added_note_for_expression_use() -> u32 {\n    let x = 9;\n\n    let _ = if x == 7 {\n        x << 2\n    } else {\n        let _ = 6;\n        x << 2\n        //~^ branches_sharing_code\n    };\n\n    if x == 9 {\n        x * 4\n    } else {\n        let _ = 17;\n        x * 4\n        //~^ branches_sharing_code\n    }\n}\n\n#[rustfmt::skip]\nfn test_suggestion_with_weird_formatting() {\n    let x = 9;\n    let mut a = 0;\n    let mut b = 0;\n\n    // The error message still looks weird tbh but this is the best I can do\n    // for weird formatting\n    if x == 17 { b = 1; a = 0x99; } else { a = 0x99; }\n    //~^ branches_sharing_code\n\n}\n\nfn fp_test() {\n    let x = 17;\n\n    if x == 18 {\n        let y = 19;\n        if y < x {\n            println!(\"Trigger\")\n        }\n    } else {\n        let z = 166;\n        if z < x {\n            println!(\"Trigger\")\n        }\n    }\n}\n\nfn fp_if_let_issue7054() {\n    // This shouldn't trigger the lint\n    let string;\n    let _x = if let true = true {\n        \"\"\n    } else if true {\n        string = \"x\".to_owned();\n        &string\n    } else {\n        string = \"y\".to_owned();\n        &string\n    };\n}\n\nfn main() {}\n\nmod issue14873 {\n    fn foo() -> i32 {\n        todo!()\n    }\n\n    macro_rules! qux {\n        ($a:ident, $b:ident, $condition:expr) => {\n            if $condition {\n                \".\"\n            } else {\n                \"\"\n            };\n            $a = foo();\n            $b = foo();\n        };\n    }\n\n    fn share_on_bottom() {\n        let mut a = 0;\n        let mut b = 0;\n        if false {\n            qux!(a, b, a == b);\n        } else {\n            qux!(a, b, a != b);\n        };\n\n        if false {\n            qux!(a, b, a == b);\n            let y = 1;\n        } else {\n            qux!(a, b, a != b);\n            let y = 1;\n            //~^ branches_sharing_code\n        }\n    }\n}\n\nfn issue15004() {\n    let a = 12u32;\n    let b = 13u32;\n    let mut c = 8u32;\n\n    let mut result = if b > a {\n        c += 1;\n        0\n    } else {\n        c += 2;\n        0\n        //~^ branches_sharing_code\n    };\n\n    result = if b > a {\n        c += 1;\n        1\n    } else {\n        c += 2;\n        1\n        //~^ branches_sharing_code\n    };\n}\n\npub fn issue15347<T>() -> isize {\n    if false {\n        static A: isize = 4;\n        return A;\n    } else {\n        static A: isize = 5;\n        return A;\n    }\n\n    if false {\n        //~^ branches_sharing_code\n        type ISize = isize;\n        return ISize::MAX;\n    } else {\n        type ISize = isize;\n        return ISize::MAX;\n    }\n\n    if false {\n        //~^ branches_sharing_code\n        fn foo() -> isize {\n            4\n        }\n        return foo();\n    } else {\n        fn foo() -> isize {\n            4\n        }\n        return foo();\n    }\n\n    if false {\n        //~^ branches_sharing_code\n        use std::num::NonZeroIsize;\n        return NonZeroIsize::new(4).unwrap().get();\n    } else {\n        use std::num::NonZeroIsize;\n        return NonZeroIsize::new(4).unwrap().get();\n    }\n\n    if false {\n        //~^ branches_sharing_code\n        const B: isize = 5;\n        return B;\n    } else {\n        const B: isize = 5;\n        return B;\n    }\n\n    // Should not lint!\n    const A: isize = 1;\n    if false {\n        const B: isize = A;\n        return B;\n    } else {\n        const C: isize = A;\n        return C;\n    }\n\n    todo!()\n}\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/shared_at_bottom.stderr",
    "content": "error: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:35:5\n   |\nLL | /         let result = false;\nLL | |\nLL | |\nLL | |         println!(\"Block end!\");\nLL | |         result\nLL | |     };\n   | |_____^\n   |\n   = note: the end suggestion probably needs some adjustments to use the expression result correctly\nnote: the lint level is defined here\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:1:36\n   |\nLL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     let result = false;\nLL +\nLL + \nLL +     println!(\"Block end!\");\nLL ~     result;\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:55:5\n   |\nLL | /         println!(\"Same end of block\");\nLL | |\nLL | |     }\n   | |_____^\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     println!(\"Same end of block\");\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:73:5\n   |\nLL | /         println!(\nLL | |\nLL | |             \"I'm moveable because I know: `outer_scope_value`: '{}'\",\nLL | |             outer_scope_value\nLL | |         );\nLL | |     }\n   | |_____^\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     println!(\nLL +\nLL +         \"I'm moveable because I know: `outer_scope_value`: '{}'\",\nLL +         outer_scope_value\nLL +     );\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:86:9\n   |\nLL | /             println!(\"Hello World\");\nLL | |\nLL | |         }\n   | |_________^\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~         }\nLL +         println!(\"Hello World\");\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:103:5\n   |\nLL | /         let later_used_value = \"A string value\";\nLL | |\nLL | |\nLL | |         println!(\"{}\", later_used_value);\nLL | |         // I'm expecting a note about this\nLL | |     }\n   | |_____^\n   |\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     let later_used_value = \"A string value\";\nLL +\nLL + \nLL +     println!(\"{}\", later_used_value);\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:118:5\n   |\nLL | /         let simple_examples = \"I now identify as a &str :)\";\nLL | |\nLL | |\nLL | |         println!(\"This is the new simple_example: {}\", simple_examples);\nLL | |     }\n   | |_____^\n   |\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     let simple_examples = \"I now identify as a &str :)\";\nLL +\nLL + \nLL +     println!(\"This is the new simple_example: {}\", simple_examples);\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:185:5\n   |\nLL | /         x << 2\nLL | |\nLL | |     };\n   | |_____^\n   |\n   = note: the end suggestion probably needs some adjustments to use the expression result correctly\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL ~     x << 2;\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:193:5\n   |\nLL | /         x * 4\nLL | |\nLL | |     }\n   | |_____^\n   |\n   = note: the end suggestion probably needs some adjustments to use the expression result correctly\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     x * 4\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:206:44\n   |\nLL |     if x == 17 { b = 1; a = 0x99; } else { a = 0x99; }\n   |                                            ^^^^^^^^^^^\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~     if x == 17 { b = 1; a = 0x99; } else { }\nLL +     a = 0x99;\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:274:9\n   |\nLL | /             let y = 1;\nLL | |\nLL | |         }\n   | |_________^\n   |\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements after the if\n   |\nLL ~         }\nLL +         let y = 1;\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:290:5\n   |\nLL | /         0\nLL | |\nLL | |     };\n   | |_____^\n   |\n   = note: the end suggestion probably needs some adjustments to use the expression result correctly\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL ~     0;\n   |\n\nerror: all if blocks contain the same code at the end\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:299:5\n   |\nLL | /         1\nLL | |\nLL | |     };\n   | |_____^\n   |\n   = note: the end suggestion probably needs some adjustments to use the expression result correctly\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL ~     1;\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:313:5\n   |\nLL | /     if false {\nLL | |\nLL | |         type ISize = isize;\nLL | |         return ISize::MAX;\n   | |__________________________^\n   |\nhelp: consider moving these statements before the if\n   |\nLL ~     type ISize = isize;\nLL +     return ISize::MAX;\nLL +     if false {\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:322:5\n   |\nLL | /     if false {\nLL | |\nLL | |         fn foo() -> isize {\nLL | |             4\nLL | |         }\nLL | |         return foo();\n   | |_____________________^\n   |\nhelp: consider moving these statements before the if\n   |\nLL ~     fn foo() -> isize {\nLL +         4\nLL +     }\nLL +     return foo();\nLL +     if false {\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:335:5\n   |\nLL | /     if false {\nLL | |\nLL | |         use std::num::NonZeroIsize;\nLL | |         return NonZeroIsize::new(4).unwrap().get();\n   | |___________________________________________________^\n   |\nhelp: consider moving these statements before the if\n   |\nLL ~     use std::num::NonZeroIsize;\nLL +     return NonZeroIsize::new(4).unwrap().get();\nLL +     if false {\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_bottom.rs:344:5\n   |\nLL | /     if false {\nLL | |\nLL | |         const B: isize = 5;\nLL | |         return B;\n   | |_________________^\n   |\nhelp: consider moving these statements before the if\n   |\nLL ~     const B: isize = 5;\nLL +     return B;\nLL +     if false {\n   |\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/shared_at_top.rs",
    "content": "#![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]\n#![allow(dead_code)]\n#![allow(clippy::mixed_read_write_in_expression, clippy::uninlined_format_args)]\n//@no-rustfix\n// This tests the branches_sharing_code lint at the start of blocks\n\nfn simple_examples() {\n    let x = 0;\n\n    // Simple\n    if true {\n        //~^ branches_sharing_code\n        println!(\"Hello World!\");\n        println!(\"I'm branch nr: 1\");\n    } else {\n        println!(\"Hello World!\");\n        println!(\"I'm branch nr: 2\");\n    }\n\n    // Else if\n    if x == 0 {\n        //~^ branches_sharing_code\n        let y = 9;\n        println!(\"The value y was set to: `{}`\", y);\n        let _z = y;\n\n        println!(\"I'm the true start index of arrays\");\n    } else if x == 1 {\n        let y = 9;\n        println!(\"The value y was set to: `{}`\", y);\n        let _z = y;\n\n        println!(\"I start counting from 1 so my array starts from `1`\");\n    } else {\n        let y = 9;\n        println!(\"The value y was set to: `{}`\", y);\n        let _z = y;\n\n        println!(\"Ha, Pascal allows you to start the array where you want\")\n    }\n\n    // Return a value\n    let _ = if x == 7 {\n        //~^ branches_sharing_code\n\n        let y = 16;\n        println!(\"What can I say except: \\\"you're welcome?\\\"\");\n        let _ = y;\n        x\n    } else {\n        let y = 16;\n        println!(\"Thank you\");\n        y\n    };\n}\n\n/// Simple examples where the move can cause some problems due to moved values\nfn simple_but_suggestion_is_invalid() {\n    let x = 10;\n\n    // Can't be automatically moved because used_value_name is getting used again\n    let used_value_name = 19;\n    if x == 10 {\n        //~^ branches_sharing_code\n        let used_value_name = \"Different type\";\n        println!(\"Str: {}\", used_value_name);\n        let _ = 1;\n    } else {\n        let used_value_name = \"Different type\";\n        println!(\"Str: {}\", used_value_name);\n        let _ = 2;\n    }\n\n    let _ = used_value_name;\n\n    // This can be automatically moved as `can_be_overridden` is not used again\n    let can_be_overridden = 8;\n    let _ = can_be_overridden;\n    if x == 11 {\n        //~^ branches_sharing_code\n\n        let can_be_overridden = \"Move me\";\n        println!(\"I'm also moveable\");\n        let _ = 111;\n    } else {\n        let can_be_overridden = \"Move me\";\n        println!(\"I'm also moveable\");\n        let _ = 222;\n    }\n}\n\n/// This function tests that the `IS_SAME_THAN_ELSE` only covers the lint if it's enabled.\nfn check_if_same_than_else_mask() {\n    let x = 2021;\n\n    #[allow(clippy::if_same_then_else)]\n    if x == 2020 {\n        //~^ branches_sharing_code\n\n        println!(\"This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.\");\n        println!(\"Because `IF_SAME_THEN_ELSE` is allowed here\");\n    } else {\n        println!(\"This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.\");\n        println!(\"Because `IF_SAME_THEN_ELSE` is allowed here\");\n    }\n\n    if x == 2019 {\n        println!(\"This should trigger `IS_SAME_THAN_ELSE` as usual\");\n    } else {\n        println!(\"This should trigger `IS_SAME_THAN_ELSE` as usual\");\n    }\n    //~^^^^^ if_same_then_else\n}\n\n#[allow(clippy::vec_init_then_push)]\nfn pf_local_with_inferred_type_issue7053() {\n    if true {\n        let mut v = Vec::new();\n        v.push(0);\n    } else {\n        let mut v = Vec::new();\n        v.push(\"\");\n    };\n}\n\nfn main() {}\n\nmod issue14873 {\n    fn foo() -> i32 {\n        todo!()\n    }\n\n    macro_rules! qux {\n        ($a:ident, $b:ident, $condition:expr) => {\n            let $a: i32 = foo();\n            let $b: i32 = foo();\n            if $condition { \".\" } else { \"\" }\n        };\n    }\n\n    fn share_on_top() {\n        if false {\n            qux!(a, b, a == b);\n        } else {\n            qux!(a, b, a != b);\n        };\n\n        if false {\n            //~^ branches_sharing_code\n            let x = 1;\n            qux!(a, b, a == b);\n        } else {\n            let x = 1;\n            qux!(a, b, a != b);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/shared_at_top.stderr",
    "content": "error: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:11:5\n   |\nLL | /     if true {\nLL | |\nLL | |         println!(\"Hello World!\");\n   | |_________________________________^\n   |\nnote: the lint level is defined here\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:1:9\n   |\nLL | #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider moving these statements before the if\n   |\nLL ~     println!(\"Hello World!\");\nLL +     if true {\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:21:5\n   |\nLL | /     if x == 0 {\nLL | |\nLL | |         let y = 9;\nLL | |         println!(\"The value y was set to: `{}`\", y);\nLL | |         let _z = y;\n   | |___________________^\n   |\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements before the if\n   |\nLL ~     let y = 9;\nLL +     println!(\"The value y was set to: `{}`\", y);\nLL +     let _z = y;\nLL +     if x == 0 {\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:43:5\n   |\nLL | /     let _ = if x == 7 {\n...  |\nLL | |         let y = 16;\n   | |___________________^\n   |\nhelp: consider moving these statements before the if\n   |\nLL ~     let y = 16;\nLL +     let _ = if x == 7 {\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:63:5\n   |\nLL | /     if x == 10 {\nLL | |\nLL | |         let used_value_name = \"Different type\";\nLL | |         println!(\"Str: {}\", used_value_name);\n   | |_____________________________________________^\n   |\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements before the if\n   |\nLL ~     let used_value_name = \"Different type\";\nLL +     println!(\"Str: {}\", used_value_name);\nLL +     if x == 10 {\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:79:5\n   |\nLL | /     if x == 11 {\nLL | |\nLL | |\nLL | |         let can_be_overridden = \"Move me\";\nLL | |         println!(\"I'm also moveable\");\n   | |______________________________________^\n   |\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements before the if\n   |\nLL ~     let can_be_overridden = \"Move me\";\nLL +     println!(\"I'm also moveable\");\nLL +     if x == 11 {\n   |\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:97:5\n   |\nLL | /     if x == 2020 {\nLL | |\nLL | |\nLL | |         println!(\"This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.\");\nLL | |         println!(\"Because `IF_SAME_THEN_ELSE` is allowed here\");\n   | |________________________________________________________________^\n   |\nhelp: consider moving these statements before the if\n   |\nLL ~     println!(\"This should trigger the `SHARED_CODE_IN_IF_BLOCKS` lint.\");\nLL +     println!(\"Because `IF_SAME_THEN_ELSE` is allowed here\");\nLL +     if x == 2020 {\n   |\n\nerror: this `if` has identical blocks\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:107:18\n   |\nLL |       if x == 2019 {\n   |  __________________^\nLL | |         println!(\"This should trigger `IS_SAME_THAN_ELSE` as usual\");\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:109:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         println!(\"This should trigger `IS_SAME_THAN_ELSE` as usual\");\nLL | |     }\n   | |_____^\nnote: the lint level is defined here\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:1:40\n   |\nLL | #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: all if blocks contain the same code at the start\n  --> tests/ui/branches_sharing_code/shared_at_top.rs:148:9\n   |\nLL | /         if false {\nLL | |\nLL | |             let x = 1;\n   | |______________________^\n   |\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements before the if\n   |\nLL ~         let x = 1;\nLL +         if false {\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs",
    "content": "#![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]\n#![allow(dead_code)]\n//@no-rustfix\n// branches_sharing_code at the top and bottom of the if blocks\n\nstruct DataPack {\n    id: u32,\n    name: String,\n    some_data: Vec<u8>,\n}\n\nfn overlapping_eq_regions() {\n    let x = 9;\n\n    // Overlap with separator\n    if x == 7 {\n        //~^ branches_sharing_code\n\n        let t = 7;\n        let _overlap_start = t * 2;\n        let _overlap_end = 2 * t;\n        let _u = 9;\n    } else {\n        let t = 7;\n        let _overlap_start = t * 2;\n        let _overlap_end = 2 * t;\n        println!(\"Overlap separator\");\n        let _overlap_start = t * 2;\n        let _overlap_end = 2 * t;\n        let _u = 9;\n    }\n\n    // Overlap with separator\n    if x == 99 {\n        //~^ branches_sharing_code\n\n        let r = 7;\n        let _overlap_start = r;\n        let _overlap_middle = r * r;\n        let _overlap_end = r * r * r;\n        let z = \"end\";\n    } else {\n        let r = 7;\n        let _overlap_start = r;\n        let _overlap_middle = r * r;\n        let _overlap_middle = r * r;\n        let _overlap_end = r * r * r;\n        let z = \"end\";\n    }\n}\n\nfn complexer_example() {\n    fn gen_id(x: u32, y: u32) -> u32 {\n        let x = x & 0x0000_ffff;\n        let y = (y & 0xffff_0000) << 16;\n        x | y\n    }\n\n    fn process_data(data: DataPack) {\n        let _ = data;\n    }\n\n    let x = 8;\n    let y = 9;\n    if (x > 7 && y < 13) || (x + y) % 2 == 1 {\n        //~^ branches_sharing_code\n\n        let a = 0xcafe;\n        let b = 0xffff00ff;\n        let e_id = gen_id(a, b);\n\n        println!(\"From the a `{a}` to the b `{b}`\");\n\n        let pack = DataPack {\n            id: e_id,\n            name: \"Player 1\".to_string(),\n            some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90],\n        };\n        process_data(pack);\n    } else {\n        let a = 0xcafe;\n        let b = 0xffff00ff;\n        let e_id = gen_id(a, b);\n\n        println!(\"The new ID is '{e_id}'\");\n\n        let pack = DataPack {\n            id: e_id,\n            name: \"Player 1\".to_string(),\n            some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90],\n        };\n        process_data(pack);\n    }\n}\n\n/// This should add a note to the lint msg since the moved expression is not `()`\nfn added_note_for_expression_use() -> u32 {\n    let x = 9;\n\n    let _ = if x == 7 {\n        //~^ branches_sharing_code\n\n        let _ = 19;\n\n        let _splitter = 6;\n\n        x << 2\n    } else {\n        let _ = 19;\n\n        x << 2\n    };\n\n    if x == 9 {\n        //~^ branches_sharing_code\n\n        let _ = 17;\n\n        let _splitter = 6;\n\n        x * 4\n    } else {\n        let _ = 17;\n\n        x * 4\n    }\n}\n\nfn main() {}\n\nmod issue14873 {\n    fn foo() -> i32 {\n        todo!()\n    }\n\n    macro_rules! qux {\n        ($a:ident, $b:ident, $condition:expr) => {\n            let mut $a: i32 = foo();\n            let mut $b: i32 = foo();\n            if $condition {\n                \".\"\n            } else {\n                \"\"\n            };\n            $a = foo();\n            $b = foo();\n        };\n    }\n\n    fn share_on_top_and_bottom() {\n        if false {\n            qux!(a, b, a == b);\n        } else {\n            qux!(a, b, a != b);\n        };\n\n        if false {\n            //~^ branches_sharing_code\n            let x = 1;\n            qux!(a, b, a == b);\n            let y = 1;\n        } else {\n            let x = 1;\n            qux!(a, b, a != b);\n            let y = 1;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr",
    "content": "error: all if blocks contain the same code at both the start and the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:16:5\n   |\nLL | /     if x == 7 {\nLL | |\nLL | |\nLL | |         let t = 7;\nLL | |         let _overlap_start = t * 2;\nLL | |         let _overlap_end = 2 * t;\n   | |_________________________________^\n   |\nnote: this code is shared at the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:30:5\n   |\nLL | /         let _u = 9;\nLL | |     }\n   | |_____^\nnote: the lint level is defined here\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:1:9\n   |\nLL | #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider moving these statements before the if\n   |\nLL ~     let t = 7;\nLL +     let _overlap_start = t * 2;\nLL +     let _overlap_end = 2 * t;\nLL +     if x == 7 {\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     let _u = 9;\n   |\n\nerror: all if blocks contain the same code at both the start and the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:34:5\n   |\nLL | /     if x == 99 {\nLL | |\nLL | |\nLL | |         let r = 7;\nLL | |         let _overlap_start = r;\nLL | |         let _overlap_middle = r * r;\n   | |____________________________________^\n   |\nnote: this code is shared at the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:47:5\n   |\nLL | /         let _overlap_end = r * r * r;\nLL | |         let z = \"end\";\nLL | |     }\n   | |_____^\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements before the if\n   |\nLL ~     let r = 7;\nLL +     let _overlap_start = r;\nLL +     let _overlap_middle = r * r;\nLL +     if x == 99 {\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     let _overlap_end = r * r * r;\nLL +     let z = \"end\";\n   |\n\nerror: all if blocks contain the same code at both the start and the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:65:5\n   |\nLL | /     if (x > 7 && y < 13) || (x + y) % 2 == 1 {\nLL | |\nLL | |\nLL | |         let a = 0xcafe;\nLL | |         let b = 0xffff00ff;\nLL | |         let e_id = gen_id(a, b);\n   | |________________________________^\n   |\nnote: this code is shared at the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:87:5\n   |\nLL | /         let pack = DataPack {\nLL | |             id: e_id,\nLL | |             name: \"Player 1\".to_string(),\nLL | |             some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90],\nLL | |         };\nLL | |         process_data(pack);\nLL | |     }\n   | |_____^\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements before the if\n   |\nLL ~     let a = 0xcafe;\nLL +     let b = 0xffff00ff;\nLL +     let e_id = gen_id(a, b);\nLL +     if (x > 7 && y < 13) || (x + y) % 2 == 1 {\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     let pack = DataPack {\nLL +         id: e_id,\nLL +         name: \"Player 1\".to_string(),\nLL +         some_data: vec![0x12, 0x34, 0x56, 0x78, 0x90],\nLL +     };\nLL +     process_data(pack);\n   |\n\nerror: all if blocks contain the same code at both the start and the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:100:5\n   |\nLL | /     let _ = if x == 7 {\n...  |\nLL | |         let _ = 19;\n   | |___________________^\n   |\nnote: this code is shared at the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:111:5\n   |\nLL | /         x << 2\nLL | |     };\n   | |_____^\n   = note: the end suggestion probably needs some adjustments to use the expression result correctly\nhelp: consider moving these statements before the if\n   |\nLL ~     let _ = 19;\nLL +     let _ = if x == 7 {\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL ~     x << 2;\n   |\n\nerror: all if blocks contain the same code at both the start and the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:114:5\n   |\nLL | /     if x == 9 {\n...  |\nLL | |         let _ = 17;\n   | |___________________^\n   |\nnote: this code is shared at the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:125:5\n   |\nLL | /         x * 4\nLL | |     }\n   | |_____^\n   = note: the end suggestion probably needs some adjustments to use the expression result correctly\nhelp: consider moving these statements before the if\n   |\nLL ~     let _ = 17;\nLL +     if x == 9 {\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~     }\nLL +     x * 4\n   |\n\nerror: all if blocks contain the same code at both the start and the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:157:9\n   |\nLL | /         if false {\nLL | |\nLL | |             let x = 1;\n   | |______________________^\n   |\nnote: this code is shared at the end\n  --> tests/ui/branches_sharing_code/shared_at_top_and_bottom.rs:165:9\n   |\nLL | /             let y = 1;\nLL | |         }\n   | |_________^\n   = warning: some moved values might need to be renamed to avoid wrong references\nhelp: consider moving these statements before the if\n   |\nLL ~         let x = 1;\nLL +         if false {\n   |\nhelp: consider moving these statements after the if\n   |\nLL ~         }\nLL +         let y = 1;\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/valid_if_blocks.rs",
    "content": "#![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]\n#![allow(dead_code)]\n#![allow(\n    clippy::mixed_read_write_in_expression,\n    clippy::uninlined_format_args,\n    clippy::needless_else\n)]\n\n// This tests valid if blocks that shouldn't trigger the lint\n\n// Tests with value references are includes in \"shared_code_at_bottom.rs\"\n\nfn valid_examples() {\n    let x = 2;\n\n    // The edge statements are different\n    if x == 9 {\n        let y = 1 << 5;\n\n        println!(\"This is the same: vvv\");\n        let _z = y;\n        println!(\"The block expression is different\");\n\n        println!(\"Different end 1\");\n    } else {\n        let y = 1 << 7;\n\n        println!(\"This is the same: vvv\");\n        let _z = y;\n        println!(\"The block expression is different\");\n\n        println!(\"Different end 2\");\n    }\n\n    // No else\n    if x == 2 {\n        println!(\"Hello world!\");\n        println!(\"Hello back, how are you?\");\n\n        // This is different vvvv\n        println!(\"Howdy stranger =^.^=\");\n\n        println!(\"Bye Bye World\");\n    } else if x == 9 {\n        println!(\"Hello world!\");\n        println!(\"Hello back, how are you?\");\n\n        // This is different vvvv\n        println!(\"Hello reviewer :D\");\n\n        println!(\"Bye Bye World\");\n    }\n\n    // Overlapping statements only in else if blocks -> Don't lint\n    if x == 0 {\n        println!(\"I'm important!\")\n    } else if x == 17 {\n        println!(\"I share code in else if\");\n\n        println!(\"x is 17\");\n    } else {\n        println!(\"I share code in else if\");\n\n        println!(\"x is nether x nor 17\");\n    }\n\n    // Mutability is different\n    if x == 13 {\n        let mut y = 9;\n        println!(\"Value y is: {}\", y);\n        y += 16;\n        let _z1 = y;\n    } else {\n        let y = 9;\n        println!(\"Value y is: {}\", y);\n        let _z2 = y;\n    }\n\n    // Same blocks but at start and bottom so no `if_same_then_else` lint\n    if x == 418 {\n        let y = 9;\n        let z = 8;\n        let _ = (x, y, z);\n        // Don't tell the programmer, my code is also in the else block\n    } else if x == 419 {\n        println!(\"+-----------+\");\n        println!(\"|           |\");\n        println!(\"|  O     O  |\");\n        println!(\"|     °     |\");\n        println!(\"|  \\\\_____/  |\");\n        println!(\"|           |\");\n        println!(\"+-----------+\");\n    } else {\n        let y = 9;\n        let z = 8;\n        let _ = (x, y, z);\n        // I'm so much better than the x == 418 block. Trust me\n    }\n\n    let x = 1;\n    if true {\n        println!(\"{}\", x);\n    } else {\n        let x = 2;\n        println!(\"{}\", x);\n    }\n\n    // Let's test empty blocks\n    if false {\n    } else {\n    }\n    //~^^^ if_same_then_else\n}\n\n/// This makes sure that the `if_same_then_else` masks the `shared_code_in_if_blocks` lint\nfn trigger_other_lint() {\n    let x = 0;\n    let y = 1;\n\n    // Same block\n    if x == 0 {\n        let u = 19;\n        println!(\"How are u today?\");\n        let _ = \"This is a string\";\n    } else {\n        let u = 19;\n        println!(\"How are u today?\");\n        let _ = \"This is a string\";\n    }\n    //~^^^^^^^^^ if_same_then_else\n\n    // Only same expression\n    let _ = if x == 6 { 7 } else { 7 };\n    //~^ if_same_then_else\n\n    // Same in else if block\n    let _ = if x == 67 {\n        println!(\"Well I'm the most important block\");\n        \"I'm a pretty string\"\n    } else if x == 68 {\n        println!(\"I'm a doppelgänger\");\n\n        if y == 90 { \"=^.^=\" } else { \":D\" }\n    } else {\n        println!(\"I'm a doppelgänger\");\n\n        if y == 90 { \"=^.^=\" } else { \":D\" }\n    };\n    //~^^^^^^^^^ if_same_then_else\n\n    if x == 0 {\n        println!(\"I'm single\");\n    } else if x == 68 {\n        println!(\"I'm a doppelgänger\");\n    } else {\n        println!(\"I'm a doppelgänger\");\n    }\n    //~^^^^^ if_same_then_else\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/branches_sharing_code/valid_if_blocks.stderr",
    "content": "error: this `if` has identical blocks\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:109:14\n   |\nLL |       if false {\n   |  ______________^\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:110:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |     }\n   | |_____^\nnote: the lint level is defined here\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:1:40\n   |\nLL | #![deny(clippy::branches_sharing_code, clippy::if_same_then_else)]\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:121:15\n   |\nLL |       if x == 0 {\n   |  _______________^\nLL | |         let u = 19;\nLL | |         println!(\"How are u today?\");\nLL | |         let _ = \"This is a string\";\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:125:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         let u = 19;\nLL | |         println!(\"How are u today?\");\nLL | |         let _ = \"This is a string\";\nLL | |     }\n   | |_____^\n\nerror: this `if` has identical blocks\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:133:23\n   |\nLL |     let _ = if x == 6 { 7 } else { 7 };\n   |                       ^^^^^\n   |\nnote: same as this\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:133:34\n   |\nLL |     let _ = if x == 6 { 7 } else { 7 };\n   |                                  ^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:140:23\n   |\nLL |       } else if x == 68 {\n   |  _______________________^\nLL | |         println!(\"I'm a doppelgänger\");\nLL | |\nLL | |         if y == 90 { \"=^.^=\" } else { \":D\" }\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:144:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         println!(\"I'm a doppelgänger\");\nLL | |\nLL | |         if y == 90 { \"=^.^=\" } else { \":D\" }\nLL | |     };\n   | |_____^\n\nerror: this `if` has identical blocks\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:153:23\n   |\nLL |       } else if x == 68 {\n   |  _______________________^\nLL | |         println!(\"I'm a doppelgänger\");\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/branches_sharing_code/valid_if_blocks.rs:155:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         println!(\"I'm a doppelgänger\");\nLL | |     }\n   | |_____^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/builtin_type_shadow.rs",
    "content": "#![warn(clippy::builtin_type_shadow)]\n#![allow(non_camel_case_types)]\n\nfn foo<u32>(a: u32) -> u32 {\n    //~^ builtin_type_shadow\n    42 //~ ERROR: mismatched type\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/builtin_type_shadow.stderr",
    "content": "error: this generic shadows the built-in type `u32`\n  --> tests/ui/builtin_type_shadow.rs:4:8\n   |\nLL | fn foo<u32>(a: u32) -> u32 {\n   |        ^^^\n   |\n   = note: `-D clippy::builtin-type-shadow` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::builtin_type_shadow)]`\n\nerror[E0308]: mismatched types\n  --> tests/ui/builtin_type_shadow.rs:6:5\n   |\nLL | fn foo<u32>(a: u32) -> u32 {\n   |        ---             --- expected `u32` because of return type\n   |        |\n   |        expected this type parameter\nLL |\nLL |     42\n   |     ^^ expected type parameter `u32`, found integer\n   |\n   = note: expected type parameter `u32`\n                        found type `{integer}`\n   = note: the caller chooses a type for `u32` which can be different from `i32`\n\nerror: aborting due to 2 previous errors\n\nFor more information about this error, try `rustc --explain E0308`.\n"
  },
  {
    "path": "tests/ui/byte_char_slices.fixed",
    "content": "#![warn(clippy::byte_char_slices)]\n\nfn main() {\n    let bad = b\"abc\";\n    //~^ byte_char_slices\n    let quotes = b\"\\\"Hi\";\n    //~^ byte_char_slices\n    let quotes = b\"'Sup\";\n    //~^ byte_char_slices\n    let escapes = b\"\\x42Esc\";\n    //~^ byte_char_slices\n\n    let good = &[b'a', 0x42];\n    let good = [b'a', b'a'];\n    //~^ useless_vec\n    let good: u8 = [b'a', b'c'].into_iter().sum();\n}\n"
  },
  {
    "path": "tests/ui/byte_char_slices.rs",
    "content": "#![warn(clippy::byte_char_slices)]\n\nfn main() {\n    let bad = &[b'a', b'b', b'c'];\n    //~^ byte_char_slices\n    let quotes = &[b'\"', b'H', b'i'];\n    //~^ byte_char_slices\n    let quotes = &[b'\\'', b'S', b'u', b'p'];\n    //~^ byte_char_slices\n    let escapes = &[b'\\x42', b'E', b's', b'c'];\n    //~^ byte_char_slices\n\n    let good = &[b'a', 0x42];\n    let good = vec![b'a', b'a'];\n    //~^ useless_vec\n    let good: u8 = [b'a', b'c'].into_iter().sum();\n}\n"
  },
  {
    "path": "tests/ui/byte_char_slices.stderr",
    "content": "error: can be more succinctly written as a byte str\n  --> tests/ui/byte_char_slices.rs:4:15\n   |\nLL |     let bad = &[b'a', b'b', b'c'];\n   |               ^^^^^^^^^^^^^^^^^^^ help: try: `b\"abc\"`\n   |\n   = note: `-D clippy::byte-char-slices` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::byte_char_slices)]`\n\nerror: can be more succinctly written as a byte str\n  --> tests/ui/byte_char_slices.rs:6:18\n   |\nLL |     let quotes = &[b'\"', b'H', b'i'];\n   |                  ^^^^^^^^^^^^^^^^^^^ help: try: `b\"\\\"Hi\"`\n\nerror: can be more succinctly written as a byte str\n  --> tests/ui/byte_char_slices.rs:8:18\n   |\nLL |     let quotes = &[b'\\'', b'S', b'u', b'p'];\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b\"'Sup\"`\n\nerror: can be more succinctly written as a byte str\n  --> tests/ui/byte_char_slices.rs:10:19\n   |\nLL |     let escapes = &[b'\\x42', b'E', b's', b'c'];\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b\"\\x42Esc\"`\n\nerror: useless use of `vec!`\n  --> tests/ui/byte_char_slices.rs:14:16\n   |\nLL |     let good = vec![b'a', b'a'];\n   |                ^^^^^^^^^^^^^^^^ help: you can use an array directly: `[b'a', b'a']`\n   |\n   = note: `-D clippy::useless-vec` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/bytecount.rs",
    "content": "//@no-rustfix: suggests external crate\n\n#![allow(clippy::needless_borrow, clippy::useless_vec)]\n\n#[deny(clippy::naive_bytecount)]\nfn main() {\n    let x = vec![0_u8; 16];\n\n    // naive byte count\n    let _ = x.iter().filter(|&&a| a == 0).count();\n    //~^ naive_bytecount\n\n    // naive byte count\n    let _ = (&x[..]).iter().filter(|&a| *a == 0).count();\n    //~^ naive_bytecount\n\n    // not an equality count, OK.\n    let _ = x.iter().filter(|a| **a > 0).count();\n\n    // not a slice\n    let _ = x.iter().map(|a| a + 1).filter(|&a| a < 15).count();\n\n    let b = 0;\n\n    // woah there\n    let _ = x.iter().filter(|_| b > 0).count();\n\n    // nothing to see here, move along\n    let _ = x.iter().filter(|_a| b == b + 1).count();\n\n    // naive byte count\n    let _ = x.iter().filter(|a| b + 1 == **a).count();\n    //~^ naive_bytecount\n\n    let y = vec![0_u16; 3];\n\n    // naive count, but not bytes\n    let _ = y.iter().filter(|&&a| a == 0).count();\n}\n"
  },
  {
    "path": "tests/ui/bytecount.stderr",
    "content": "error: you appear to be counting bytes the naive way\n  --> tests/ui/bytecount.rs:10:13\n   |\nLL |     let _ = x.iter().filter(|&&a| a == 0).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count(x, 0)`\n   |\nnote: the lint level is defined here\n  --> tests/ui/bytecount.rs:5:8\n   |\nLL | #[deny(clippy::naive_bytecount)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: you appear to be counting bytes the naive way\n  --> tests/ui/bytecount.rs:14:13\n   |\nLL |     let _ = (&x[..]).iter().filter(|&a| *a == 0).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count((&x[..]), 0)`\n\nerror: you appear to be counting bytes the naive way\n  --> tests/ui/bytecount.rs:32:13\n   |\nLL |     let _ = x.iter().filter(|a| b + 1 == **a).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count(x, b + 1)`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/bytes_count_to_len.fixed",
    "content": "#![warn(clippy::bytes_count_to_len)]\nuse std::fs::File;\nuse std::io::{BufReader, Read};\n\nfn main() {\n    // should fix, because type is String\n    let _ = String::from(\"foo\").len();\n    //~^ bytes_count_to_len\n\n    let s1 = String::from(\"foo\");\n    let _ = s1.len();\n    //~^ bytes_count_to_len\n\n    // should fix, because type is &str\n    let _ = \"foo\".len();\n    //~^ bytes_count_to_len\n\n    let s2 = \"foo\";\n    let _ = s2.len();\n    //~^ bytes_count_to_len\n\n    // make sure using count() normally doesn't trigger warning\n    let vector = [0, 1, 2];\n    let _ = vector.iter().count();\n\n    // The type is slice, so should not fix\n    let _ = &[1, 2, 3].bytes().count();\n\n    let bytes: &[u8] = &[1, 2, 3];\n    bytes.bytes().count();\n\n    // The type is File, so should not fix\n    let _ = BufReader::new(File::open(\"foobar\").unwrap()).bytes().count();\n\n    let f = BufReader::new(File::open(\"foobar\").unwrap());\n    let _ = f.bytes().count();\n}\n"
  },
  {
    "path": "tests/ui/bytes_count_to_len.rs",
    "content": "#![warn(clippy::bytes_count_to_len)]\nuse std::fs::File;\nuse std::io::{BufReader, Read};\n\nfn main() {\n    // should fix, because type is String\n    let _ = String::from(\"foo\").bytes().count();\n    //~^ bytes_count_to_len\n\n    let s1 = String::from(\"foo\");\n    let _ = s1.bytes().count();\n    //~^ bytes_count_to_len\n\n    // should fix, because type is &str\n    let _ = \"foo\".bytes().count();\n    //~^ bytes_count_to_len\n\n    let s2 = \"foo\";\n    let _ = s2.bytes().count();\n    //~^ bytes_count_to_len\n\n    // make sure using count() normally doesn't trigger warning\n    let vector = [0, 1, 2];\n    let _ = vector.iter().count();\n\n    // The type is slice, so should not fix\n    let _ = &[1, 2, 3].bytes().count();\n\n    let bytes: &[u8] = &[1, 2, 3];\n    bytes.bytes().count();\n\n    // The type is File, so should not fix\n    let _ = BufReader::new(File::open(\"foobar\").unwrap()).bytes().count();\n\n    let f = BufReader::new(File::open(\"foobar\").unwrap());\n    let _ = f.bytes().count();\n}\n"
  },
  {
    "path": "tests/ui/bytes_count_to_len.stderr",
    "content": "error: using long and hard to read `.bytes().count()`\n  --> tests/ui/bytes_count_to_len.rs:7:13\n   |\nLL |     let _ = String::from(\"foo\").bytes().count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `String::from(\"foo\").len()`\n   |\n   = note: `-D clippy::bytes-count-to-len` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::bytes_count_to_len)]`\n\nerror: using long and hard to read `.bytes().count()`\n  --> tests/ui/bytes_count_to_len.rs:11:13\n   |\nLL |     let _ = s1.bytes().count();\n   |             ^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `s1.len()`\n\nerror: using long and hard to read `.bytes().count()`\n  --> tests/ui/bytes_count_to_len.rs:15:13\n   |\nLL |     let _ = \"foo\".bytes().count();\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `\"foo\".len()`\n\nerror: using long and hard to read `.bytes().count()`\n  --> tests/ui/bytes_count_to_len.rs:19:13\n   |\nLL |     let _ = s2.bytes().count();\n   |             ^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `s2.len()`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/bytes_nth.fixed",
    "content": "#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::sliced_string_as_bytes)]\n#![warn(clippy::bytes_nth)]\n\nfn main() {\n    let s = String::from(\"String\");\n    let _ = s.as_bytes().get(3).copied();\n    //~^ bytes_nth\n    let _ = &s.as_bytes()[3];\n    //~^ bytes_nth\n    let _ = s[..].as_bytes().get(3).copied();\n    //~^ bytes_nth\n}\n"
  },
  {
    "path": "tests/ui/bytes_nth.rs",
    "content": "#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::sliced_string_as_bytes)]\n#![warn(clippy::bytes_nth)]\n\nfn main() {\n    let s = String::from(\"String\");\n    let _ = s.bytes().nth(3);\n    //~^ bytes_nth\n    let _ = &s.bytes().nth(3).unwrap();\n    //~^ bytes_nth\n    let _ = s[..].bytes().nth(3);\n    //~^ bytes_nth\n}\n"
  },
  {
    "path": "tests/ui/bytes_nth.stderr",
    "content": "error: called `.bytes().nth()` on a `String`\n  --> tests/ui/bytes_nth.rs:7:13\n   |\nLL |     let _ = s.bytes().nth(3);\n   |             ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3).copied()`\n   |\n   = note: `-D clippy::bytes-nth` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::bytes_nth)]`\n\nerror: called `.bytes().nth().unwrap()` on a `String`\n  --> tests/ui/bytes_nth.rs:9:14\n   |\nLL |     let _ = &s.bytes().nth(3).unwrap();\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.as_bytes()[3]`\n\nerror: called `.bytes().nth()` on a `str`\n  --> tests/ui/bytes_nth.rs:11:13\n   |\nLL |     let _ = s[..].bytes().nth(3);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3).copied()`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/case_sensitive_file_extension_comparisons.fixed",
    "content": "#![warn(clippy::case_sensitive_file_extension_comparisons)]\n\nuse std::string::String;\n\nstruct TestStruct;\n\nimpl TestStruct {\n    fn ends_with(self, _arg: &str) {}\n}\n\n#[allow(dead_code)]\nfn is_rust_file(filename: &str) -> bool {\n    std::path::Path::new(filename)\n        .extension()\n        .is_some_and(|ext| ext.eq_ignore_ascii_case(\"rs\"))\n    //~^ case_sensitive_file_extension_comparisons\n}\n\nfn main() {\n    // std::string::String and &str should trigger the lint failure with .ext12\n    let _ = std::path::Path::new(&String::new())\n        .extension()\n        .is_some_and(|ext| ext.eq_ignore_ascii_case(\"ext12\"));\n    //~^ case_sensitive_file_extension_comparisons\n    let _ = std::path::Path::new(\"str\")\n        .extension()\n        .is_some_and(|ext| ext.eq_ignore_ascii_case(\"ext12\"));\n    //~^ case_sensitive_file_extension_comparisons\n\n    // The fixup should preserve the indentation level\n    {\n        let _ = std::path::Path::new(\"str\")\n            .extension()\n            .is_some_and(|ext| ext.eq_ignore_ascii_case(\"ext12\"));\n        //~^ case_sensitive_file_extension_comparisons\n    }\n\n    // The test struct should not trigger the lint failure with .ext12\n    TestStruct {}.ends_with(\".ext12\");\n\n    // std::string::String and &str should trigger the lint failure with .EXT12\n    let _ = std::path::Path::new(&String::new())\n        .extension()\n        .is_some_and(|ext| ext.eq_ignore_ascii_case(\"EXT12\"));\n    //~^ case_sensitive_file_extension_comparisons\n    let _ = std::path::Path::new(\"str\")\n        .extension()\n        .is_some_and(|ext| ext.eq_ignore_ascii_case(\"EXT12\"));\n    //~^ case_sensitive_file_extension_comparisons\n\n    // Should not trigger the lint failure because of the calls to to_lowercase and to_uppercase\n    let _ = String::new().to_lowercase().ends_with(\".EXT12\");\n    let _ = String::new().to_uppercase().ends_with(\".EXT12\");\n\n    // The test struct should not trigger the lint failure with .EXT12\n    TestStruct {}.ends_with(\".EXT12\");\n\n    // Should not trigger the lint failure with .eXT12\n    let _ = String::new().ends_with(\".eXT12\");\n    let _ = \"str\".ends_with(\".eXT12\");\n    TestStruct {}.ends_with(\".eXT12\");\n\n    // Should not trigger the lint failure with .EXT123 (too long)\n    let _ = String::new().ends_with(\".EXT123\");\n    let _ = \"str\".ends_with(\".EXT123\");\n    TestStruct {}.ends_with(\".EXT123\");\n\n    // Shouldn't fail if it doesn't start with a dot\n    let _ = String::new().ends_with(\"a.ext\");\n    let _ = \"str\".ends_with(\"a.extA\");\n    TestStruct {}.ends_with(\"a.ext\");\n\n    // Shouldn't fail if the extension has no ascii letter\n    let _ = String::new().ends_with(\".123\");\n    let _ = \"str\".ends_with(\".123\");\n    TestStruct {}.ends_with(\".123\");\n}\n\n#[clippy::msrv = \"1.69\"]\nfn msrv_check() {\n    let _ = std::path::Path::new(&String::new())\n        .extension()\n        .map_or(false, |ext| ext.eq_ignore_ascii_case(\"ext12\"));\n    //~^ case_sensitive_file_extension_comparisons\n}\n"
  },
  {
    "path": "tests/ui/case_sensitive_file_extension_comparisons.rs",
    "content": "#![warn(clippy::case_sensitive_file_extension_comparisons)]\n\nuse std::string::String;\n\nstruct TestStruct;\n\nimpl TestStruct {\n    fn ends_with(self, _arg: &str) {}\n}\n\n#[allow(dead_code)]\nfn is_rust_file(filename: &str) -> bool {\n    filename.ends_with(\".rs\")\n    //~^ case_sensitive_file_extension_comparisons\n}\n\nfn main() {\n    // std::string::String and &str should trigger the lint failure with .ext12\n    let _ = String::new().ends_with(\".ext12\");\n    //~^ case_sensitive_file_extension_comparisons\n    let _ = \"str\".ends_with(\".ext12\");\n    //~^ case_sensitive_file_extension_comparisons\n\n    // The fixup should preserve the indentation level\n    {\n        let _ = \"str\".ends_with(\".ext12\");\n        //~^ case_sensitive_file_extension_comparisons\n    }\n\n    // The test struct should not trigger the lint failure with .ext12\n    TestStruct {}.ends_with(\".ext12\");\n\n    // std::string::String and &str should trigger the lint failure with .EXT12\n    let _ = String::new().ends_with(\".EXT12\");\n    //~^ case_sensitive_file_extension_comparisons\n    let _ = \"str\".ends_with(\".EXT12\");\n    //~^ case_sensitive_file_extension_comparisons\n\n    // Should not trigger the lint failure because of the calls to to_lowercase and to_uppercase\n    let _ = String::new().to_lowercase().ends_with(\".EXT12\");\n    let _ = String::new().to_uppercase().ends_with(\".EXT12\");\n\n    // The test struct should not trigger the lint failure with .EXT12\n    TestStruct {}.ends_with(\".EXT12\");\n\n    // Should not trigger the lint failure with .eXT12\n    let _ = String::new().ends_with(\".eXT12\");\n    let _ = \"str\".ends_with(\".eXT12\");\n    TestStruct {}.ends_with(\".eXT12\");\n\n    // Should not trigger the lint failure with .EXT123 (too long)\n    let _ = String::new().ends_with(\".EXT123\");\n    let _ = \"str\".ends_with(\".EXT123\");\n    TestStruct {}.ends_with(\".EXT123\");\n\n    // Shouldn't fail if it doesn't start with a dot\n    let _ = String::new().ends_with(\"a.ext\");\n    let _ = \"str\".ends_with(\"a.extA\");\n    TestStruct {}.ends_with(\"a.ext\");\n\n    // Shouldn't fail if the extension has no ascii letter\n    let _ = String::new().ends_with(\".123\");\n    let _ = \"str\".ends_with(\".123\");\n    TestStruct {}.ends_with(\".123\");\n}\n\n#[clippy::msrv = \"1.69\"]\nfn msrv_check() {\n    let _ = String::new().ends_with(\".ext12\");\n    //~^ case_sensitive_file_extension_comparisons\n}\n"
  },
  {
    "path": "tests/ui/case_sensitive_file_extension_comparisons.stderr",
    "content": "error: case-sensitive file extension comparison\n  --> tests/ui/case_sensitive_file_extension_comparisons.rs:13:5\n   |\nLL |     filename.ends_with(\".rs\")\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a case-insensitive comparison instead\n   = note: `-D clippy::case-sensitive-file-extension-comparisons` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::case_sensitive_file_extension_comparisons)]`\nhelp: use std::path::Path\n   |\nLL ~     std::path::Path::new(filename)\nLL +         .extension()\nLL +         .is_some_and(|ext| ext.eq_ignore_ascii_case(\"rs\"))\n   |\n\nerror: case-sensitive file extension comparison\n  --> tests/ui/case_sensitive_file_extension_comparisons.rs:19:13\n   |\nLL |     let _ = String::new().ends_with(\".ext12\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a case-insensitive comparison instead\nhelp: use std::path::Path\n   |\nLL ~     let _ = std::path::Path::new(&String::new())\nLL +         .extension()\nLL ~         .is_some_and(|ext| ext.eq_ignore_ascii_case(\"ext12\"));\n   |\n\nerror: case-sensitive file extension comparison\n  --> tests/ui/case_sensitive_file_extension_comparisons.rs:21:13\n   |\nLL |     let _ = \"str\".ends_with(\".ext12\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a case-insensitive comparison instead\nhelp: use std::path::Path\n   |\nLL ~     let _ = std::path::Path::new(\"str\")\nLL +         .extension()\nLL ~         .is_some_and(|ext| ext.eq_ignore_ascii_case(\"ext12\"));\n   |\n\nerror: case-sensitive file extension comparison\n  --> tests/ui/case_sensitive_file_extension_comparisons.rs:26:17\n   |\nLL |         let _ = \"str\".ends_with(\".ext12\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a case-insensitive comparison instead\nhelp: use std::path::Path\n   |\nLL ~         let _ = std::path::Path::new(\"str\")\nLL +             .extension()\nLL ~             .is_some_and(|ext| ext.eq_ignore_ascii_case(\"ext12\"));\n   |\n\nerror: case-sensitive file extension comparison\n  --> tests/ui/case_sensitive_file_extension_comparisons.rs:34:13\n   |\nLL |     let _ = String::new().ends_with(\".EXT12\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a case-insensitive comparison instead\nhelp: use std::path::Path\n   |\nLL ~     let _ = std::path::Path::new(&String::new())\nLL +         .extension()\nLL ~         .is_some_and(|ext| ext.eq_ignore_ascii_case(\"EXT12\"));\n   |\n\nerror: case-sensitive file extension comparison\n  --> tests/ui/case_sensitive_file_extension_comparisons.rs:36:13\n   |\nLL |     let _ = \"str\".ends_with(\".EXT12\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a case-insensitive comparison instead\nhelp: use std::path::Path\n   |\nLL ~     let _ = std::path::Path::new(\"str\")\nLL +         .extension()\nLL ~         .is_some_and(|ext| ext.eq_ignore_ascii_case(\"EXT12\"));\n   |\n\nerror: case-sensitive file extension comparison\n  --> tests/ui/case_sensitive_file_extension_comparisons.rs:69:13\n   |\nLL |     let _ = String::new().ends_with(\".ext12\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a case-insensitive comparison instead\nhelp: use std::path::Path\n   |\nLL ~     let _ = std::path::Path::new(&String::new())\nLL +         .extension()\nLL ~         .map_or(false, |ext| ext.eq_ignore_ascii_case(\"ext12\"));\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast.rs",
    "content": "//@no-rustfix: only some diagnostics have suggestions\n\n#![warn(\n    clippy::cast_precision_loss,\n    clippy::cast_possible_truncation,\n    clippy::cast_sign_loss,\n    clippy::cast_possible_wrap\n)]\n#![allow(\n    clippy::cast_abs_to_unsigned,\n    clippy::no_effect,\n    clippy::unnecessary_min_or_max,\n    clippy::unnecessary_operation,\n    clippy::unnecessary_literal_unwrap,\n    clippy::identity_op\n)]\n\n// FIXME(f16_f128): add tests once const casting is available for these types\n\nfn main() {\n    // Test clippy::cast_precision_loss\n    let x0 = 1i32;\n    x0 as f32;\n    //~^ cast_precision_loss\n\n    let x1 = 1i64;\n    x1 as f32;\n    //~^ cast_precision_loss\n\n    x1 as f64;\n    //~^ cast_precision_loss\n\n    let x2 = 1u32;\n    x2 as f32;\n    //~^ cast_precision_loss\n\n    let x3 = 1u64;\n    x3 as f32;\n    //~^ cast_precision_loss\n\n    x3 as f64;\n    //~^ cast_precision_loss\n\n    // Test clippy::cast_possible_truncation\n    1f32 as i32;\n    //~^ cast_possible_truncation\n\n    1f32 as u32;\n    //~^ cast_possible_truncation\n    //~| cast_sign_loss\n\n    1f64 as f32;\n    //~^ cast_possible_truncation\n\n    1i32 as i8;\n    //~^ cast_possible_truncation\n\n    1i32 as u8;\n    //~^ cast_possible_truncation\n\n    1f64 as isize;\n    //~^ cast_possible_truncation\n\n    1f64 as usize;\n    //~^ cast_possible_truncation\n    //~| cast_sign_loss\n\n    1f32 as u32 as u16;\n    //~^ cast_possible_truncation\n    //~| cast_possible_truncation\n    //~| cast_sign_loss\n\n    {\n        let _x: i8 = 1i32 as _;\n        //~^ cast_possible_truncation\n\n        1f32 as i32;\n        //~^ cast_possible_truncation\n\n        1f64 as i32;\n        //~^ cast_possible_truncation\n\n        1f32 as u8;\n        //~^ cast_possible_truncation\n        //~| cast_sign_loss\n    }\n    // Test clippy::cast_possible_wrap\n    1u8 as i8;\n    //~^ cast_possible_wrap\n\n    1u16 as i16;\n    //~^ cast_possible_wrap\n\n    1u32 as i32;\n    //~^ cast_possible_wrap\n\n    1u64 as i64;\n    //~^ cast_possible_wrap\n\n    1usize as isize;\n    //~^ cast_possible_wrap\n\n    // should not wrap, usize is never 8 bits\n    1usize as i8;\n    //~^ cast_possible_truncation\n\n    // wraps on 16 bit ptr size\n    1usize as i16;\n    //~^ cast_possible_truncation\n    //~| cast_possible_wrap\n\n    // wraps on 32 bit ptr size\n    1usize as i32;\n    //~^ cast_possible_truncation\n    //~| cast_possible_wrap\n\n    // wraps on 64 bit ptr size\n    1usize as i64;\n    //~^ cast_possible_wrap\n\n    // should not wrap, isize is never 8 bits\n    1u8 as isize;\n    // wraps on 16 bit ptr size\n    1u16 as isize;\n    //~^ cast_possible_wrap\n\n    // wraps on 32 bit ptr size\n    1u32 as isize;\n    //~^ cast_possible_wrap\n\n    // wraps on 64 bit ptr size\n    1u64 as isize;\n    //~^ cast_possible_truncation\n    //~| cast_possible_wrap\n\n    // Test clippy::cast_sign_loss\n    1i32 as u32;\n    -1i32 as u32;\n    //~^ cast_sign_loss\n\n    1isize as usize;\n    -1isize as usize;\n    //~^ cast_sign_loss\n\n    0i8 as u8;\n    i8::MAX as u8;\n    i16::MAX as u16;\n    i32::MAX as u32;\n    i64::MAX as u64;\n    i128::MAX as u128;\n\n    (-1i8).saturating_abs() as u8;\n    // abs() can return a negative value in release builds\n    (i8::MIN).abs() as u8;\n    //~^ cast_sign_loss\n\n    (-1i16).saturating_abs() as u16;\n    (-1i32).saturating_abs() as u32;\n    (-1i64).abs() as u64;\n    //~^ cast_sign_loss\n    (-1isize).abs() as usize;\n    //~^ cast_sign_loss\n\n    (-1i8).checked_abs().unwrap() as u8;\n    (i8::MIN).checked_abs().unwrap() as u8;\n    (-1i16).checked_abs().unwrap() as u16;\n    (-1i32).checked_abs().unwrap() as u32;\n    // SAFETY: -1 is a small number which will always return Some\n    (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64;\n    //~^ cast_sign_loss\n    (-1isize).checked_abs().expect(\"-1 is a small number\") as usize;\n\n    (-1i8).isqrt() as u8;\n    (i8::MIN).isqrt() as u8;\n    (-1i16).isqrt() as u16;\n    (-1i32).isqrt() as u32;\n    (-1i64).isqrt() as u64;\n    (-1isize).isqrt() as usize;\n\n    (-1i8).checked_isqrt().unwrap() as u8;\n    (i8::MIN).checked_isqrt().unwrap() as u8;\n    (-1i16).checked_isqrt().unwrap() as u16;\n    (-1i32).checked_isqrt().unwrap() as u32;\n    // SAFETY: -1 is a small number which will always return Some\n    (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64;\n    //~^ cast_sign_loss\n    (-1isize).checked_isqrt().expect(\"-1 is a small number\") as usize;\n\n    (-1i8).rem_euclid(1i8) as u8;\n    (-1i8).wrapping_rem_euclid(1i8) as u16;\n    (-1i16).rem_euclid(1i16) as u16;\n    (-1i16).rem_euclid(1i16) as u32;\n    (-1i32).rem_euclid(1i32) as u32;\n    (-1i32).rem_euclid(1i32) as u64;\n    (-1i64).rem_euclid(1i64) as u64;\n    (-1i64).rem_euclid(1i64) as u128;\n    (-1isize).rem_euclid(1isize) as usize;\n    (1i8).rem_euclid(-1i8) as u8;\n    (1i8).wrapping_rem_euclid(-1i8) as u16;\n    (1i16).rem_euclid(-1i16) as u16;\n    (1i16).rem_euclid(-1i16) as u32;\n    (1i32).rem_euclid(-1i32) as u32;\n    (1i32).rem_euclid(-1i32) as u64;\n    (1i64).rem_euclid(-1i64) as u64;\n    (1i64).rem_euclid(-1i64) as u128;\n    (1isize).rem_euclid(-1isize) as usize;\n\n    (-1i8).checked_rem_euclid(1i8).unwrap() as u8;\n    (-1i8).checked_rem_euclid(1i8).unwrap() as u16;\n    (-1i16).checked_rem_euclid(1i16).unwrap() as u16;\n    (-1i16).checked_rem_euclid(1i16).unwrap() as u32;\n    (-1i32).checked_rem_euclid(1i32).unwrap() as u32;\n    (-1i32).checked_rem_euclid(1i32).unwrap() as u64;\n    (-1i64).checked_rem_euclid(1i64).unwrap() as u64;\n    (-1i64).checked_rem_euclid(1i64).unwrap() as u128;\n    (-1isize).checked_rem_euclid(1isize).unwrap() as usize;\n    (1i8).checked_rem_euclid(-1i8).unwrap() as u8;\n    (1i8).checked_rem_euclid(-1i8).unwrap() as u16;\n    (1i16).checked_rem_euclid(-1i16).unwrap() as u16;\n    (1i16).checked_rem_euclid(-1i16).unwrap() as u32;\n    (1i32).checked_rem_euclid(-1i32).unwrap() as u32;\n    (1i32).checked_rem_euclid(-1i32).unwrap() as u64;\n    (1i64).checked_rem_euclid(-1i64).unwrap() as u64;\n    (1i64).checked_rem_euclid(-1i64).unwrap() as u128;\n    (1isize).checked_rem_euclid(-1isize).unwrap() as usize;\n\n    // no lint for `cast_possible_truncation`\n    // with `signum` method call (see issue #5395)\n    let x: i64 = 5;\n    let _ = x.signum() as i32;\n\n    let s = x.signum();\n    let _ = s as i32;\n\n    // Test for signed min\n    // should be linted because signed\n    (-99999999999i64).min(1) as i8;\n    //~^ cast_possible_truncation\n\n    // Test for various operations that remove enough bits for the result to fit\n    (999999u64 & 1) as u8;\n    (999999u64 % 15) as u8;\n    (999999u64 / 0x1_0000_0000_0000) as u16;\n    ({ 999999u64 >> 56 }) as u8;\n    ({\n        let x = 999999u64;\n        x.min(1)\n    }) as u8;\n    999999u64.clamp(0, 255) as u8;\n    // should still be linted\n    999999u64.clamp(0, 256) as u8;\n    //~^ cast_possible_truncation\n\n    #[derive(Clone, Copy)]\n    enum E1 {\n        A,\n        B,\n        C,\n    }\n    impl E1 {\n        fn test(self) {\n            // Don't lint. `0..=2` fits in u8\n            let _ = self as u8;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    enum E2 {\n        A = 255,\n        B,\n    }\n    impl E2 {\n        fn test(self) {\n            let _ = self as u8;\n            //~^ cast_possible_truncation\n\n            let _ = Self::B as u8;\n            //~^ cast_enum_truncation\n\n            // Don't lint. `255..=256` fits in i16\n            let _ = self as i16;\n            // Don't lint.\n            let _ = Self::A as u8;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    enum E3 {\n        A = -1,\n        B,\n        C = 50,\n    }\n    impl E3 {\n        fn test(self) {\n            // Don't lint. `-1..=50` fits in i8\n            let _ = self as i8;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    enum E4 {\n        A = -128,\n        B,\n    }\n    impl E4 {\n        fn test(self) {\n            // Don't lint. `-128..=-127` fits in i8\n            let _ = self as i8;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    enum E5 {\n        A = -129,\n        B = 127,\n    }\n    impl E5 {\n        fn test(self) {\n            let _ = self as i8;\n            //~^ cast_possible_truncation\n\n            let _ = Self::A as i8;\n            //~^ cast_enum_truncation\n\n            // Don't lint. `-129..=127` fits in i16\n            let _ = self as i16;\n            // Don't lint.\n            let _ = Self::B as u8;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    #[repr(u32)]\n    enum E6 {\n        A = u16::MAX as u32,\n        B,\n    }\n    impl E6 {\n        fn test(self) {\n            let _ = self as i16;\n            //~^ cast_possible_truncation\n\n            // Don't lint. `2^16-1` fits in u16\n            let _ = Self::A as u16;\n            // Don't lint. `2^16-1..=2^16` fits in u32\n            let _ = self as u32;\n            // Don't lint.\n            let _ = Self::A as u16;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    #[repr(u64)]\n    enum E7 {\n        A = u32::MAX as u64,\n        B,\n    }\n    impl E7 {\n        fn test(self) {\n            let _ = self as usize;\n            //~^ cast_possible_truncation\n\n            // Don't lint.\n            let _ = Self::A as usize;\n            // Don't lint. `2^32-1..=2^32` fits in u64\n            let _ = self as u64;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    #[repr(i128)]\n    enum E8 {\n        A = i128::MIN,\n        B,\n        C = 0,\n        D = i128::MAX,\n    }\n    impl E8 {\n        fn test(self) {\n            // Don't lint. `-(2^127)..=2^127-1` fits it i128\n            let _ = self as i128;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    #[repr(u128)]\n    enum E9 {\n        A,\n        B = u128::MAX,\n    }\n    impl E9 {\n        fn test(self) {\n            // Don't lint.\n            let _ = Self::A as u8;\n            // Don't lint. `0..=2^128-1` fits in u128\n            let _ = self as u128;\n        }\n    }\n\n    #[derive(Clone, Copy)]\n    #[repr(usize)]\n    enum E10 {\n        A,\n        B = u32::MAX as usize,\n    }\n    impl E10 {\n        fn test(self) {\n            let _ = self as u16;\n            //~^ cast_possible_truncation\n\n            // Don't lint.\n            let _ = Self::B as u32;\n            // Don't lint.\n            let _ = self as u64;\n        }\n    }\n}\n\nfn avoid_subtract_overflow(q: u32) {\n    let c = (q >> 16) as u8;\n    //~^ cast_possible_truncation\n\n    c as usize;\n\n    let c = (q / 1000) as u8;\n    //~^ cast_possible_truncation\n\n    c as usize;\n}\n\nfn issue11426() {\n    (&42u8 >> 0xa9008fb6c9d81e42_0e25730562a601c8_u128) as usize;\n}\n\nfn issue11642() {\n    fn square(x: i16) -> u32 {\n        let x = x as i32;\n        (x * x) as u32;\n        //~^ cast_sign_loss\n        x.pow(2) as u32;\n        (-2_i32).saturating_pow(2) as u32\n    }\n\n    let _a = |x: i32| -> u32 { (x * x * x * x) as u32 };\n    //~^ cast_sign_loss\n\n    (2_i32).checked_pow(3).unwrap() as u32;\n    //~^ cast_sign_loss\n    (-2_i32).pow(3) as u32;\n    //~^ cast_sign_loss\n\n    (3_i32 % 2) as u32;\n    (3_i32 % -2) as u32;\n    (-5_i32 % 2) as u32;\n    //~^ cast_sign_loss\n\n    (-5_i32 % -2) as u32;\n    //~^ cast_sign_loss\n\n    (2_i32 >> 1) as u32;\n    (-2_i32 >> 1) as u32;\n    //~^ cast_sign_loss\n\n    let x: i32 = 10;\n    (x * x) as u32;\n    //~^ cast_sign_loss\n    (x * x * x) as u32;\n    //~^ cast_sign_loss\n\n    let y: i16 = -2;\n    (y * y * y * y * -2) as u16;\n    //~^ cast_sign_loss\n\n    (y * y * y / y * 2) as u16;\n    //~^ cast_sign_loss\n    (y * y / y * 2) as u16;\n    //~^ cast_sign_loss\n\n    (y / y * y * -2) as u16;\n    //~^ cast_sign_loss\n    //~| eq_op\n\n    (y + y + y + -2) as u16;\n    //~^ cast_sign_loss\n\n    (y + y + y + 2) as u16;\n    //~^ cast_sign_loss\n\n    let z: i16 = 2;\n    (z + -2) as u16;\n    //~^ cast_sign_loss\n\n    (z + z + 2) as u16;\n    //~^ cast_sign_loss\n\n    fn foo(a: i32, b: i32, c: i32) -> u32 {\n        (a * a * b * b * c * c) as u32;\n        //~^ cast_sign_loss\n        (a * b * c) as u32;\n        //~^ cast_sign_loss\n\n        (a * -b * c) as u32;\n        //~^ cast_sign_loss\n\n        (a * b * c * c) as u32;\n        //~^ cast_sign_loss\n        (a * -2) as u32;\n        //~^ cast_sign_loss\n\n        (a * b * c * -2) as u32;\n        //~^ cast_sign_loss\n\n        (a / b) as u32;\n        //~^ cast_sign_loss\n        (a / b * c) as u32;\n        //~^ cast_sign_loss\n\n        (a / b + b * c) as u32;\n        //~^ cast_sign_loss\n\n        a.saturating_pow(3) as u32;\n        //~^ cast_sign_loss\n\n        (a.abs() * b.pow(2) / c.abs()) as u32\n        //~^ cast_sign_loss\n    }\n}\n\nfn issue11738() {\n    macro_rules! m {\n        () => {\n            let _ = i32::MIN as u32; // cast_sign_loss\n            //\n            //~^^ cast_sign_loss\n            let _ = u32::MAX as u8; // cast_possible_truncation\n            //\n            //~^^ cast_possible_truncation\n            let _ = std::f64::consts::PI as f32; // cast_possible_truncation\n            //\n            //~^^ cast_possible_truncation\n            let _ = 0i8 as i32; // cast_lossless\n        };\n    }\n    m!();\n}\n\nfn issue12506() -> usize {\n    let bar: Result<Option<i64>, u32> = Ok(Some(10));\n    bar.unwrap().unwrap() as usize\n    //~^ cast_possible_truncation\n    //~| cast_sign_loss\n}\n\nfn issue12721() {\n    fn x() -> u64 {\n        u64::MAX\n    }\n\n    // Don't lint.\n    (255 & 999999u64) as u8;\n    // Don't lint.\n    let _ = ((x() & 255) & 999999) as u8;\n    // Don't lint.\n    let _ = (999999 & (x() & 255)) as u8;\n\n    (256 & 999999u64) as u8;\n    //~^ cast_possible_truncation\n\n    (255 % 999999u64) as u8;\n    //~^ cast_possible_truncation\n}\n\nmod issue14150 {\n    #[clippy::msrv = \"1.87\"]\n    fn msrv_supports_cast_signed() {\n        _ = 1u8 as i8;\n        //~^ cast_possible_wrap\n    }\n    #[clippy::msrv = \"1.86\"]\n    fn msrv_doesnt_supports_cast_signed() {\n        _ = 1u8 as i8;\n        //~^ cast_possible_wrap\n    }\n}\n\nfn issue16045() {\n    fn f() -> Result<(), ()> {\n        let val = Ok::<_, ()>(0u8);\n        _ = val? as i8;\n        //~^ cast_possible_wrap\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "tests/ui/cast.stderr",
    "content": "error: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast.rs:23:5\n   |\nLL |     x0 as f32;\n   |     ^^^^^^^^^\n   |\n   = note: `-D clippy::cast-precision-loss` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`\n\nerror: casting `i64` to `f32` may cause a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast.rs:27:5\n   |\nLL |     x1 as f32;\n   |     ^^^^^^^^^\n\nerror: casting `i64` to `f64` may cause a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)\n  --> tests/ui/cast.rs:30:5\n   |\nLL |     x1 as f64;\n   |     ^^^^^^^^^\n\nerror: casting `u32` to `f32` may cause a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast.rs:34:5\n   |\nLL |     x2 as f32;\n   |     ^^^^^^^^^\n\nerror: casting `u64` to `f32` may cause a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast.rs:38:5\n   |\nLL |     x3 as f32;\n   |     ^^^^^^^^^\n\nerror: casting `u64` to `f64` may cause a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)\n  --> tests/ui/cast.rs:41:5\n   |\nLL |     x3 as f64;\n   |     ^^^^^^^^^\n\nerror: casting `f32` to `i32` may truncate the value\n  --> tests/ui/cast.rs:45:5\n   |\nLL |     1f32 as i32;\n   |     ^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n   = note: `-D clippy::cast-possible-truncation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`\n\nerror: casting `f32` to `u32` may truncate the value\n  --> tests/ui/cast.rs:48:5\n   |\nLL |     1f32 as u32;\n   |     ^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: casting `f32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:48:5\n   |\nLL |     1f32 as u32;\n   |     ^^^^^^^^^^^\n   |\n   = note: `-D clippy::cast-sign-loss` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]`\n\nerror: casting `f64` to `f32` may truncate the value\n  --> tests/ui/cast.rs:52:5\n   |\nLL |     1f64 as f32;\n   |     ^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: casting `i32` to `i8` may truncate the value\n  --> tests/ui/cast.rs:55:5\n   |\nLL |     1i32 as i8;\n   |     ^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1i32 as i8;\nLL +     i8::try_from(1i32);\n   |\n\nerror: casting `i32` to `u8` may truncate the value\n  --> tests/ui/cast.rs:58:5\n   |\nLL |     1i32 as u8;\n   |     ^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1i32 as u8;\nLL +     u8::try_from(1i32);\n   |\n\nerror: casting `f64` to `isize` may truncate the value\n  --> tests/ui/cast.rs:61:5\n   |\nLL |     1f64 as isize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: casting `f64` to `usize` may truncate the value\n  --> tests/ui/cast.rs:64:5\n   |\nLL |     1f64 as usize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: casting `f64` to `usize` may lose the sign of the value\n  --> tests/ui/cast.rs:64:5\n   |\nLL |     1f64 as usize;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `u32` to `u16` may truncate the value\n  --> tests/ui/cast.rs:68:5\n   |\nLL |     1f32 as u32 as u16;\n   |     ^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1f32 as u32 as u16;\nLL +     u16::try_from(1f32 as u32);\n   |\n\nerror: casting `f32` to `u32` may truncate the value\n  --> tests/ui/cast.rs:68:5\n   |\nLL |     1f32 as u32 as u16;\n   |     ^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: casting `f32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:68:5\n   |\nLL |     1f32 as u32 as u16;\n   |     ^^^^^^^^^^^\n\nerror: casting `i32` to `i8` may truncate the value\n  --> tests/ui/cast.rs:74:22\n   |\nLL |         let _x: i8 = 1i32 as _;\n   |                      ^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -         let _x: i8 = 1i32 as _;\nLL +         let _x: i8 = 1i32.try_into();\n   |\n\nerror: casting `f32` to `i32` may truncate the value\n  --> tests/ui/cast.rs:77:9\n   |\nLL |         1f32 as i32;\n   |         ^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: casting `f64` to `i32` may truncate the value\n  --> tests/ui/cast.rs:80:9\n   |\nLL |         1f64 as i32;\n   |         ^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: casting `f32` to `u8` may truncate the value\n  --> tests/ui/cast.rs:83:9\n   |\nLL |         1f32 as u8;\n   |         ^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: casting `f32` to `u8` may lose the sign of the value\n  --> tests/ui/cast.rs:83:9\n   |\nLL |         1f32 as u8;\n   |         ^^^^^^^^^^\n\nerror: casting `u8` to `i8` may wrap around the value\n  --> tests/ui/cast.rs:88:5\n   |\nLL |     1u8 as i8;\n   |     ^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `1u8.cast_signed()`\n   |\n   = note: `-D clippy::cast-possible-wrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`\n\nerror: casting `u16` to `i16` may wrap around the value\n  --> tests/ui/cast.rs:91:5\n   |\nLL |     1u16 as i16;\n   |     ^^^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `1u16.cast_signed()`\n\nerror: casting `u32` to `i32` may wrap around the value\n  --> tests/ui/cast.rs:94:5\n   |\nLL |     1u32 as i32;\n   |     ^^^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `1u32.cast_signed()`\n\nerror: casting `u64` to `i64` may wrap around the value\n  --> tests/ui/cast.rs:97:5\n   |\nLL |     1u64 as i64;\n   |     ^^^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `1u64.cast_signed()`\n\nerror: casting `usize` to `isize` may wrap around the value\n  --> tests/ui/cast.rs:100:5\n   |\nLL |     1usize as isize;\n   |     ^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `1usize.cast_signed()`\n\nerror: casting `usize` to `i8` may truncate the value\n  --> tests/ui/cast.rs:104:5\n   |\nLL |     1usize as i8;\n   |     ^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1usize as i8;\nLL +     i8::try_from(1usize);\n   |\n\nerror: casting `usize` to `i16` may truncate the value\n  --> tests/ui/cast.rs:108:5\n   |\nLL |     1usize as i16;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1usize as i16;\nLL +     i16::try_from(1usize);\n   |\n\nerror: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers\n  --> tests/ui/cast.rs:108:5\n   |\nLL |     1usize as i16;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: `usize` and `isize` may be as small as 16 bits on some platforms\n   = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types\n\nerror: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast.rs:113:5\n   |\nLL |     1usize as i32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1usize as i32;\nLL +     i32::try_from(1usize);\n   |\n\nerror: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers\n  --> tests/ui/cast.rs:113:5\n   |\nLL |     1usize as i32;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers\n  --> tests/ui/cast.rs:118:5\n   |\nLL |     1usize as i64;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers\n  --> tests/ui/cast.rs:124:5\n   |\nLL |     1u16 as isize;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: `usize` and `isize` may be as small as 16 bits on some platforms\n   = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types\n\nerror: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers\n  --> tests/ui/cast.rs:128:5\n   |\nLL |     1u32 as isize;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast.rs:132:5\n   |\nLL |     1u64 as isize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1u64 as isize;\nLL +     isize::try_from(1u64);\n   |\n\nerror: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers\n  --> tests/ui/cast.rs:132:5\n   |\nLL |     1u64 as isize;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:138:5\n   |\nLL |     -1i32 as u32;\n   |     ^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(-1i32).cast_unsigned()`\n\nerror: casting `isize` to `usize` may lose the sign of the value\n  --> tests/ui/cast.rs:142:5\n   |\nLL |     -1isize as usize;\n   |     ^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(-1isize).cast_unsigned()`\n\nerror: casting `i8` to `u8` may lose the sign of the value\n  --> tests/ui/cast.rs:154:5\n   |\nLL |     (i8::MIN).abs() as u8;\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(i8::MIN).abs().cast_unsigned()`\n\nerror: casting `i64` to `u64` may lose the sign of the value\n  --> tests/ui/cast.rs:159:5\n   |\nLL |     (-1i64).abs() as u64;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(-1i64).abs().cast_unsigned()`\n\nerror: casting `isize` to `usize` may lose the sign of the value\n  --> tests/ui/cast.rs:161:5\n   |\nLL |     (-1isize).abs() as usize;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(-1isize).abs().cast_unsigned()`\n\nerror: casting `i64` to `u64` may lose the sign of the value\n  --> tests/ui/cast.rs:169:5\n   |\nLL |     (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(unsafe { (-1i64).checked_abs().unwrap_unchecked() }).cast_unsigned()`\n\nerror: casting `i64` to `u64` may lose the sign of the value\n  --> tests/ui/cast.rs:185:5\n   |\nLL |     (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }).cast_unsigned()`\n\nerror: casting `i64` to `i8` may truncate the value\n  --> tests/ui/cast.rs:237:5\n   |\nLL |     (-99999999999i64).min(1) as i8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     (-99999999999i64).min(1) as i8;\nLL +     i8::try_from((-99999999999i64).min(1));\n   |\n\nerror: casting `u64` to `u8` may truncate the value\n  --> tests/ui/cast.rs:251:5\n   |\nLL |     999999u64.clamp(0, 256) as u8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     999999u64.clamp(0, 256) as u8;\nLL +     u8::try_from(999999u64.clamp(0, 256));\n   |\n\nerror: casting `main::E2` to `u8` may truncate the value\n  --> tests/ui/cast.rs:274:21\n   |\nLL |             let _ = self as u8;\n   |                     ^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -             let _ = self as u8;\nLL +             let _ = u8::try_from(self);\n   |\n\nerror: casting `main::E2::B` to `u8` will truncate the value\n  --> tests/ui/cast.rs:277:21\n   |\nLL |             let _ = Self::B as u8;\n   |                     ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::cast-enum-truncation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]`\n\nerror: casting `main::E5` to `i8` may truncate the value\n  --> tests/ui/cast.rs:319:21\n   |\nLL |             let _ = self as i8;\n   |                     ^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -             let _ = self as i8;\nLL +             let _ = i8::try_from(self);\n   |\n\nerror: casting `main::E5::A` to `i8` will truncate the value\n  --> tests/ui/cast.rs:322:21\n   |\nLL |             let _ = Self::A as i8;\n   |                     ^^^^^^^^^^^^^\n\nerror: casting `main::E6` to `i16` may truncate the value\n  --> tests/ui/cast.rs:340:21\n   |\nLL |             let _ = self as i16;\n   |                     ^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -             let _ = self as i16;\nLL +             let _ = i16::try_from(self);\n   |\n\nerror: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast.rs:360:21\n   |\nLL |             let _ = self as usize;\n   |                     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -             let _ = self as usize;\nLL +             let _ = usize::try_from(self);\n   |\n\nerror: casting `main::E10` to `u16` may truncate the value\n  --> tests/ui/cast.rs:408:21\n   |\nLL |             let _ = self as u16;\n   |                     ^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -             let _ = self as u16;\nLL +             let _ = u16::try_from(self);\n   |\n\nerror: casting `u32` to `u8` may truncate the value\n  --> tests/ui/cast.rs:420:13\n   |\nLL |     let c = (q >> 16) as u8;\n   |             ^^^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     let c = (q >> 16) as u8;\nLL +     let c = u8::try_from(q >> 16);\n   |\n\nerror: casting `u32` to `u8` may truncate the value\n  --> tests/ui/cast.rs:425:13\n   |\nLL |     let c = (q / 1000) as u8;\n   |             ^^^^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     let c = (q / 1000) as u8;\nLL +     let c = u8::try_from(q / 1000);\n   |\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:438:9\n   |\nLL |         (x * x) as u32;\n   |         ^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(x * x).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:444:32\n   |\nLL |     let _a = |x: i32| -> u32 { (x * x * x * x) as u32 };\n   |                                ^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(x * x * x * x).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:447:5\n   |\nLL |     (2_i32).checked_pow(3).unwrap() as u32;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(2_i32).checked_pow(3).unwrap().cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:449:5\n   |\nLL |     (-2_i32).pow(3) as u32;\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(-2_i32).pow(3).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:454:5\n   |\nLL |     (-5_i32 % 2) as u32;\n   |     ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(-5_i32 % 2).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:457:5\n   |\nLL |     (-5_i32 % -2) as u32;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(-5_i32 % -2).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:461:5\n   |\nLL |     (-2_i32 >> 1) as u32;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(-2_i32 >> 1).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:465:5\n   |\nLL |     (x * x) as u32;\n   |     ^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(x * x).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:467:5\n   |\nLL |     (x * x * x) as u32;\n   |     ^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(x * x * x).cast_unsigned()`\n\nerror: casting `i16` to `u16` may lose the sign of the value\n  --> tests/ui/cast.rs:471:5\n   |\nLL |     (y * y * y * y * -2) as u16;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(y * y * y * y * -2).cast_unsigned()`\n\nerror: casting `i16` to `u16` may lose the sign of the value\n  --> tests/ui/cast.rs:474:5\n   |\nLL |     (y * y * y / y * 2) as u16;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(y * y * y / y * 2).cast_unsigned()`\n\nerror: casting `i16` to `u16` may lose the sign of the value\n  --> tests/ui/cast.rs:476:5\n   |\nLL |     (y * y / y * 2) as u16;\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(y * y / y * 2).cast_unsigned()`\n\nerror: casting `i16` to `u16` may lose the sign of the value\n  --> tests/ui/cast.rs:479:5\n   |\nLL |     (y / y * y * -2) as u16;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(y / y * y * -2).cast_unsigned()`\n\nerror: equal expressions as operands to `/`\n  --> tests/ui/cast.rs:479:6\n   |\nLL |     (y / y * y * -2) as u16;\n   |      ^^^^^\n   |\n   = note: `#[deny(clippy::eq_op)]` on by default\n\nerror: casting `i16` to `u16` may lose the sign of the value\n  --> tests/ui/cast.rs:483:5\n   |\nLL |     (y + y + y + -2) as u16;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(y + y + y + -2).cast_unsigned()`\n\nerror: casting `i16` to `u16` may lose the sign of the value\n  --> tests/ui/cast.rs:486:5\n   |\nLL |     (y + y + y + 2) as u16;\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(y + y + y + 2).cast_unsigned()`\n\nerror: casting `i16` to `u16` may lose the sign of the value\n  --> tests/ui/cast.rs:490:5\n   |\nLL |     (z + -2) as u16;\n   |     ^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(z + -2).cast_unsigned()`\n\nerror: casting `i16` to `u16` may lose the sign of the value\n  --> tests/ui/cast.rs:493:5\n   |\nLL |     (z + z + 2) as u16;\n   |     ^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(z + z + 2).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:497:9\n   |\nLL |         (a * a * b * b * c * c) as u32;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a * a * b * b * c * c).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:499:9\n   |\nLL |         (a * b * c) as u32;\n   |         ^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a * b * c).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:502:9\n   |\nLL |         (a * -b * c) as u32;\n   |         ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a * -b * c).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:505:9\n   |\nLL |         (a * b * c * c) as u32;\n   |         ^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a * b * c * c).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:507:9\n   |\nLL |         (a * -2) as u32;\n   |         ^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a * -2).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:510:9\n   |\nLL |         (a * b * c * -2) as u32;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a * b * c * -2).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:513:9\n   |\nLL |         (a / b) as u32;\n   |         ^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a / b).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:515:9\n   |\nLL |         (a / b * c) as u32;\n   |         ^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a / b * c).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:518:9\n   |\nLL |         (a / b + b * c) as u32;\n   |         ^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a / b + b * c).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:521:9\n   |\nLL |         a.saturating_pow(3) as u32;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `a.saturating_pow(3).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:524:9\n   |\nLL |         (a.abs() * b.pow(2) / c.abs()) as u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `(a.abs() * b.pow(2) / c.abs()).cast_unsigned()`\n\nerror: casting `i32` to `u32` may lose the sign of the value\n  --> tests/ui/cast.rs:532:21\n   |\nLL |             let _ = i32::MIN as u32; // cast_sign_loss\n   |                     ^^^^^^^^^^^^^^^ help: if this is intentional, use `cast_unsigned()` instead: `i32::MIN.cast_unsigned()`\n...\nLL |     m!();\n   |     ---- in this macro invocation\n   |\n   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: casting `u32` to `u8` may truncate the value\n  --> tests/ui/cast.rs:535:21\n   |\nLL |             let _ = u32::MAX as u8; // cast_possible_truncation\n   |                     ^^^^^^^^^^^^^^\n...\nLL |     m!();\n   |     ---- in this macro invocation\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -             let _ = u32::MAX as u8; // cast_possible_truncation\nLL +             let _ = u8::try_from(u32::MAX); // cast_possible_truncation\n   |\n\nerror: casting `f64` to `f32` may truncate the value\n  --> tests/ui/cast.rs:538:21\n   |\nLL |             let _ = std::f64::consts::PI as f32; // cast_possible_truncation\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     m!();\n   |     ---- in this macro invocation\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast.rs:549:5\n   |\nLL |     bar.unwrap().unwrap() as usize\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     bar.unwrap().unwrap() as usize\nLL +     usize::try_from(bar.unwrap().unwrap())\n   |\n\nerror: casting `i64` to `usize` may lose the sign of the value\n  --> tests/ui/cast.rs:549:5\n   |\nLL |     bar.unwrap().unwrap() as usize\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: casting `u64` to `u8` may truncate the value\n  --> tests/ui/cast.rs:566:5\n   |\nLL |     (256 & 999999u64) as u8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     (256 & 999999u64) as u8;\nLL +     u8::try_from(256 & 999999u64);\n   |\n\nerror: casting `u64` to `u8` may truncate the value\n  --> tests/ui/cast.rs:569:5\n   |\nLL |     (255 % 999999u64) as u8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     (255 % 999999u64) as u8;\nLL +     u8::try_from(255 % 999999u64);\n   |\n\nerror: casting `u8` to `i8` may wrap around the value\n  --> tests/ui/cast.rs:576:13\n   |\nLL |         _ = 1u8 as i8;\n   |             ^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `1u8.cast_signed()`\n\nerror: casting `u8` to `i8` may wrap around the value\n  --> tests/ui/cast.rs:581:13\n   |\nLL |         _ = 1u8 as i8;\n   |             ^^^^^^^^^\n\nerror: casting `u8` to `i8` may wrap around the value\n  --> tests/ui/cast.rs:589:13\n   |\nLL |         _ = val? as i8;\n   |             ^^^^^^^^^^ help: if this is intentional, use `cast_signed()` instead: `val?.cast_signed()`\n\nerror: aborting due to 95 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_abs_to_unsigned.fixed",
    "content": "#![warn(clippy::cast_abs_to_unsigned)]\n#![allow(unused)]\n\nfn main() {\n    let x: i32 = -42;\n    let y: u32 = x.unsigned_abs();\n    //~^ cast_abs_to_unsigned\n    println!(\"The absolute value of {x} is {y}\");\n\n    let a: i32 = -3;\n    let _: usize = a.unsigned_abs() as usize;\n    //~^ cast_abs_to_unsigned\n    let _: usize = a.unsigned_abs() as _;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as usize;\n    //~^ cast_abs_to_unsigned\n\n    let a: i64 = -3;\n    let _ = a.unsigned_abs() as usize;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u8;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u16;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u32;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs();\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u128;\n    //~^ cast_abs_to_unsigned\n\n    let a: isize = -3;\n    let _ = a.unsigned_abs();\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u8;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u16;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u32;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u64;\n    //~^ cast_abs_to_unsigned\n    let _ = a.unsigned_abs() as u128;\n    //~^ cast_abs_to_unsigned\n\n    let _ = (x as i64 - y as i64).unsigned_abs() as u32;\n    //~^ cast_abs_to_unsigned\n}\n\n#[clippy::msrv = \"1.50\"]\nfn msrv_1_50() {\n    let x: i32 = 10;\n    assert_eq!(10u32, x.abs() as u32);\n}\n\n#[clippy::msrv = \"1.51\"]\nfn msrv_1_51() {\n    let x: i32 = 10;\n    assert_eq!(10u32, x.unsigned_abs());\n    //~^ cast_abs_to_unsigned\n}\n"
  },
  {
    "path": "tests/ui/cast_abs_to_unsigned.rs",
    "content": "#![warn(clippy::cast_abs_to_unsigned)]\n#![allow(unused)]\n\nfn main() {\n    let x: i32 = -42;\n    let y: u32 = x.abs() as u32;\n    //~^ cast_abs_to_unsigned\n    println!(\"The absolute value of {x} is {y}\");\n\n    let a: i32 = -3;\n    let _: usize = a.abs() as usize;\n    //~^ cast_abs_to_unsigned\n    let _: usize = a.abs() as _;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as usize;\n    //~^ cast_abs_to_unsigned\n\n    let a: i64 = -3;\n    let _ = a.abs() as usize;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u8;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u16;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u32;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u64;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u128;\n    //~^ cast_abs_to_unsigned\n\n    let a: isize = -3;\n    let _ = a.abs() as usize;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u8;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u16;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u32;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u64;\n    //~^ cast_abs_to_unsigned\n    let _ = a.abs() as u128;\n    //~^ cast_abs_to_unsigned\n\n    let _ = (x as i64 - y as i64).abs() as u32;\n    //~^ cast_abs_to_unsigned\n}\n\n#[clippy::msrv = \"1.50\"]\nfn msrv_1_50() {\n    let x: i32 = 10;\n    assert_eq!(10u32, x.abs() as u32);\n}\n\n#[clippy::msrv = \"1.51\"]\nfn msrv_1_51() {\n    let x: i32 = 10;\n    assert_eq!(10u32, x.abs() as u32);\n    //~^ cast_abs_to_unsigned\n}\n"
  },
  {
    "path": "tests/ui/cast_abs_to_unsigned.stderr",
    "content": "error: casting the result of `i32::abs()` to u32\n  --> tests/ui/cast_abs_to_unsigned.rs:6:18\n   |\nLL |     let y: u32 = x.abs() as u32;\n   |                  ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()`\n   |\n   = note: `-D clippy::cast-abs-to-unsigned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_abs_to_unsigned)]`\n\nerror: casting the result of `i32::abs()` to usize\n  --> tests/ui/cast_abs_to_unsigned.rs:11:20\n   |\nLL |     let _: usize = a.abs() as usize;\n   |                    ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i32::abs()` to usize\n  --> tests/ui/cast_abs_to_unsigned.rs:13:20\n   |\nLL |     let _: usize = a.abs() as _;\n   |                    ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i32::abs()` to usize\n  --> tests/ui/cast_abs_to_unsigned.rs:15:13\n   |\nLL |     let _ = a.abs() as usize;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i64::abs()` to usize\n  --> tests/ui/cast_abs_to_unsigned.rs:19:13\n   |\nLL |     let _ = a.abs() as usize;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i64::abs()` to u8\n  --> tests/ui/cast_abs_to_unsigned.rs:21:13\n   |\nLL |     let _ = a.abs() as u8;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i64::abs()` to u16\n  --> tests/ui/cast_abs_to_unsigned.rs:23:13\n   |\nLL |     let _ = a.abs() as u16;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i64::abs()` to u32\n  --> tests/ui/cast_abs_to_unsigned.rs:25:13\n   |\nLL |     let _ = a.abs() as u32;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i64::abs()` to u64\n  --> tests/ui/cast_abs_to_unsigned.rs:27:13\n   |\nLL |     let _ = a.abs() as u64;\n   |             ^^^^^^^^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i64::abs()` to u128\n  --> tests/ui/cast_abs_to_unsigned.rs:29:13\n   |\nLL |     let _ = a.abs() as u128;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `isize::abs()` to usize\n  --> tests/ui/cast_abs_to_unsigned.rs:33:13\n   |\nLL |     let _ = a.abs() as usize;\n   |             ^^^^^^^^^^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `isize::abs()` to u8\n  --> tests/ui/cast_abs_to_unsigned.rs:35:13\n   |\nLL |     let _ = a.abs() as u8;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `isize::abs()` to u16\n  --> tests/ui/cast_abs_to_unsigned.rs:37:13\n   |\nLL |     let _ = a.abs() as u16;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `isize::abs()` to u32\n  --> tests/ui/cast_abs_to_unsigned.rs:39:13\n   |\nLL |     let _ = a.abs() as u32;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `isize::abs()` to u64\n  --> tests/ui/cast_abs_to_unsigned.rs:41:13\n   |\nLL |     let _ = a.abs() as u64;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `isize::abs()` to u128\n  --> tests/ui/cast_abs_to_unsigned.rs:43:13\n   |\nLL |     let _ = a.abs() as u128;\n   |             ^^^^^^^ help: replace with: `a.unsigned_abs()`\n\nerror: casting the result of `i64::abs()` to u32\n  --> tests/ui/cast_abs_to_unsigned.rs:46:13\n   |\nLL |     let _ = (x as i64 - y as i64).abs() as u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `(x as i64 - y as i64).unsigned_abs()`\n\nerror: casting the result of `i32::abs()` to u32\n  --> tests/ui/cast_abs_to_unsigned.rs:59:23\n   |\nLL |     assert_eq!(10u32, x.abs() as u32);\n   |                       ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_alignment.rs",
    "content": "//! Test casts for alignment issues\n\n#![feature(core_intrinsics)]\n#![warn(clippy::cast_ptr_alignment)]\n#![allow(\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::cast_lossless,\n    clippy::borrow_as_ptr\n)]\n\nfn main() {\n    /* These should be warned against */\n\n    // cast to more-strictly-aligned type\n    (&1u8 as *const u8) as *const u16;\n    //~^ cast_ptr_alignment\n\n    (&mut 1u8 as *mut u8) as *mut u16;\n    //~^ cast_ptr_alignment\n\n    // cast to more-strictly-aligned type, but with the `pointer::cast` function.\n    (&1u8 as *const u8).cast::<u16>();\n    //~^ cast_ptr_alignment\n\n    (&mut 1u8 as *mut u8).cast::<u16>();\n    //~^ cast_ptr_alignment\n\n    /* These should be ok */\n\n    // not a pointer type\n    1u8 as u16;\n    // cast to less-strictly-aligned type\n    (&1u16 as *const u16) as *const u8;\n    (&mut 1u16 as *mut u16) as *mut u8;\n    // For c_void, we should trust the user. See #2677\n    (&1u32 as *const u32 as *const std::os::raw::c_void) as *const u32;\n    (&1u32 as *const u32 as *const libc::c_void) as *const u32;\n    // For ZST, we should trust the user. See #4256\n    (&1u32 as *const u32 as *const ()) as *const u32;\n\n    // Issue #2881\n    let mut data = [0u8, 0u8];\n    unsafe {\n        let ptr = &data as *const [u8; 2] as *const u8;\n        let _ = (ptr as *const u16).read_unaligned();\n        let _ = core::ptr::read_unaligned(ptr as *const u16);\n        let _ = core::intrinsics::unaligned_volatile_load(ptr as *const u16);\n        let ptr = &mut data as *mut [u8; 2] as *mut u8;\n        (ptr as *mut u16).write_unaligned(0);\n        core::ptr::write_unaligned(ptr as *mut u16, 0);\n        core::intrinsics::unaligned_volatile_store(ptr as *mut u16, 0);\n    }\n}\n"
  },
  {
    "path": "tests/ui/cast_alignment.stderr",
    "content": "error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)\n  --> tests/ui/cast_alignment.rs:16:5\n   |\nLL |     (&1u8 as *const u8) as *const u16;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::cast-ptr-alignment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_ptr_alignment)]`\n\nerror: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)\n  --> tests/ui/cast_alignment.rs:19:5\n   |\nLL |     (&mut 1u8 as *mut u8) as *mut u16;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)\n  --> tests/ui/cast_alignment.rs:23:5\n   |\nLL |     (&1u8 as *const u8).cast::<u16>();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)\n  --> tests/ui/cast_alignment.rs:26:5\n   |\nLL |     (&mut 1u8 as *mut u8).cast::<u16>();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_enum_constructor.rs",
    "content": "#![warn(clippy::cast_enum_constructor)]\n#![allow(clippy::fn_to_numeric_cast, function_casts_as_integer)]\n\nfn main() {\n    enum Foo {\n        Y(u32),\n    }\n\n    enum Bar {\n        X,\n    }\n\n    let _ = Foo::Y as usize;\n    //~^ cast_enum_constructor\n\n    let _ = Foo::Y as isize;\n    //~^ cast_enum_constructor\n\n    let _ = Foo::Y as fn(u32) -> Foo;\n    let _ = Bar::X as usize;\n}\n"
  },
  {
    "path": "tests/ui/cast_enum_constructor.stderr",
    "content": "error: cast of an enum tuple constructor to an integer\n  --> tests/ui/cast_enum_constructor.rs:13:13\n   |\nLL |     let _ = Foo::Y as usize;\n   |             ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::cast-enum-constructor` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_enum_constructor)]`\n\nerror: cast of an enum tuple constructor to an integer\n  --> tests/ui/cast_enum_constructor.rs:16:13\n   |\nLL |     let _ = Foo::Y as isize;\n   |             ^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_lossless_bool.fixed",
    "content": "#![allow(dead_code)]\n#![warn(clippy::cast_lossless)]\n\ntype U8 = u8;\n\nfn main() {\n    // Test clippy::cast_lossless with casts to integer types\n    let _ = u8::from(true);\n    //~^ cast_lossless\n    let _ = u16::from(true);\n    //~^ cast_lossless\n    let _ = u32::from(true);\n    //~^ cast_lossless\n    let _ = u64::from(true);\n    //~^ cast_lossless\n    let _ = u128::from(true);\n    //~^ cast_lossless\n    let _ = usize::from(true);\n    //~^ cast_lossless\n\n    let _ = i8::from(true);\n    //~^ cast_lossless\n    let _ = i16::from(true);\n    //~^ cast_lossless\n    let _ = i32::from(true);\n    //~^ cast_lossless\n    let _ = i64::from(true);\n    //~^ cast_lossless\n    let _ = i128::from(true);\n    //~^ cast_lossless\n    let _ = isize::from(true);\n    //~^ cast_lossless\n\n    // Test with an expression wrapped in parens\n    let _ = u16::from(true | false);\n    //~^ cast_lossless\n\n    let _ = U8::from(true);\n    //~^ cast_lossless\n}\n\n// The lint would suggest using `u32::from(input)` here but the `XX::from` function is not const,\n// so we skip the lint if the expression is in a const fn.\n// See #3656\nconst fn abc(input: bool) -> u32 {\n    input as u32\n}\n\n// Same as the above issue. We can't suggest `::from` in const fns in impls\nmod cast_lossless_in_impl {\n    struct A;\n\n    impl A {\n        pub const fn convert(x: bool) -> u64 {\n            x as u64\n        }\n    }\n}\n\n#[clippy::msrv = \"1.27\"]\nfn msrv_1_27() {\n    let _ = true as u8;\n}\n\n#[clippy::msrv = \"1.28\"]\nfn msrv_1_28() {\n    let _ = u8::from(true);\n    //~^ cast_lossless\n}\n"
  },
  {
    "path": "tests/ui/cast_lossless_bool.rs",
    "content": "#![allow(dead_code)]\n#![warn(clippy::cast_lossless)]\n\ntype U8 = u8;\n\nfn main() {\n    // Test clippy::cast_lossless with casts to integer types\n    let _ = true as u8;\n    //~^ cast_lossless\n    let _ = true as u16;\n    //~^ cast_lossless\n    let _ = true as u32;\n    //~^ cast_lossless\n    let _ = true as u64;\n    //~^ cast_lossless\n    let _ = true as u128;\n    //~^ cast_lossless\n    let _ = true as usize;\n    //~^ cast_lossless\n\n    let _ = true as i8;\n    //~^ cast_lossless\n    let _ = true as i16;\n    //~^ cast_lossless\n    let _ = true as i32;\n    //~^ cast_lossless\n    let _ = true as i64;\n    //~^ cast_lossless\n    let _ = true as i128;\n    //~^ cast_lossless\n    let _ = true as isize;\n    //~^ cast_lossless\n\n    // Test with an expression wrapped in parens\n    let _ = (true | false) as u16;\n    //~^ cast_lossless\n\n    let _ = true as U8;\n    //~^ cast_lossless\n}\n\n// The lint would suggest using `u32::from(input)` here but the `XX::from` function is not const,\n// so we skip the lint if the expression is in a const fn.\n// See #3656\nconst fn abc(input: bool) -> u32 {\n    input as u32\n}\n\n// Same as the above issue. We can't suggest `::from` in const fns in impls\nmod cast_lossless_in_impl {\n    struct A;\n\n    impl A {\n        pub const fn convert(x: bool) -> u64 {\n            x as u64\n        }\n    }\n}\n\n#[clippy::msrv = \"1.27\"]\nfn msrv_1_27() {\n    let _ = true as u8;\n}\n\n#[clippy::msrv = \"1.28\"]\nfn msrv_1_28() {\n    let _ = true as u8;\n    //~^ cast_lossless\n}\n"
  },
  {
    "path": "tests/ui/cast_lossless_bool.stderr",
    "content": "error: casts from `bool` to `u8` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:8:13\n   |\nLL |     let _ = true as u8;\n   |             ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\n   = note: `-D clippy::cast-lossless` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`\nhelp: use `u8::from` instead\n   |\nLL -     let _ = true as u8;\nLL +     let _ = u8::from(true);\n   |\n\nerror: casts from `bool` to `u16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:10:13\n   |\nLL |     let _ = true as u16;\n   |             ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u16::from` instead\n   |\nLL -     let _ = true as u16;\nLL +     let _ = u16::from(true);\n   |\n\nerror: casts from `bool` to `u32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:12:13\n   |\nLL |     let _ = true as u32;\n   |             ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u32::from` instead\n   |\nLL -     let _ = true as u32;\nLL +     let _ = u32::from(true);\n   |\n\nerror: casts from `bool` to `u64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:14:13\n   |\nLL |     let _ = true as u64;\n   |             ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u64::from` instead\n   |\nLL -     let _ = true as u64;\nLL +     let _ = u64::from(true);\n   |\n\nerror: casts from `bool` to `u128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:16:13\n   |\nLL |     let _ = true as u128;\n   |             ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u128::from` instead\n   |\nLL -     let _ = true as u128;\nLL +     let _ = u128::from(true);\n   |\n\nerror: casts from `bool` to `usize` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:18:13\n   |\nLL |     let _ = true as usize;\n   |             ^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `usize::from` instead\n   |\nLL -     let _ = true as usize;\nLL +     let _ = usize::from(true);\n   |\n\nerror: casts from `bool` to `i8` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:21:13\n   |\nLL |     let _ = true as i8;\n   |             ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i8::from` instead\n   |\nLL -     let _ = true as i8;\nLL +     let _ = i8::from(true);\n   |\n\nerror: casts from `bool` to `i16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:23:13\n   |\nLL |     let _ = true as i16;\n   |             ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i16::from` instead\n   |\nLL -     let _ = true as i16;\nLL +     let _ = i16::from(true);\n   |\n\nerror: casts from `bool` to `i32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:25:13\n   |\nLL |     let _ = true as i32;\n   |             ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i32::from` instead\n   |\nLL -     let _ = true as i32;\nLL +     let _ = i32::from(true);\n   |\n\nerror: casts from `bool` to `i64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:27:13\n   |\nLL |     let _ = true as i64;\n   |             ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i64::from` instead\n   |\nLL -     let _ = true as i64;\nLL +     let _ = i64::from(true);\n   |\n\nerror: casts from `bool` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:29:13\n   |\nLL |     let _ = true as i128;\n   |             ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     let _ = true as i128;\nLL +     let _ = i128::from(true);\n   |\n\nerror: casts from `bool` to `isize` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:31:13\n   |\nLL |     let _ = true as isize;\n   |             ^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `isize::from` instead\n   |\nLL -     let _ = true as isize;\nLL +     let _ = isize::from(true);\n   |\n\nerror: casts from `bool` to `u16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:35:13\n   |\nLL |     let _ = (true | false) as u16;\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u16::from` instead\n   |\nLL -     let _ = (true | false) as u16;\nLL +     let _ = u16::from(true | false);\n   |\n\nerror: casts from `bool` to `u8` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:38:13\n   |\nLL |     let _ = true as U8;\n   |             ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `U8::from` instead\n   |\nLL -     let _ = true as U8;\nLL +     let _ = U8::from(true);\n   |\n\nerror: casts from `bool` to `u8` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_bool.rs:67:13\n   |\nLL |     let _ = true as u8;\n   |             ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u8::from` instead\n   |\nLL -     let _ = true as u8;\nLL +     let _ = u8::from(true);\n   |\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_lossless_float.fixed",
    "content": "#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]\n#![warn(clippy::cast_lossless)]\n\n// FIXME(f16_f128): add tests for these types once const casting is available\n\ntype F32 = f32;\ntype F64 = f64;\n\nfn main() {\n    // Test clippy::cast_lossless with casts to floating-point types\n    let x0 = 1i8;\n    let _ = f32::from(x0);\n    //~^ cast_lossless\n    let _ = f64::from(x0);\n    //~^ cast_lossless\n    let _ = F32::from(x0);\n    //~^ cast_lossless\n    let _ = F64::from(x0);\n    //~^ cast_lossless\n    let x1 = 1u8;\n    let _ = f32::from(x1);\n    //~^ cast_lossless\n    let _ = f64::from(x1);\n    //~^ cast_lossless\n    let x2 = 1i16;\n    let _ = f32::from(x2);\n    //~^ cast_lossless\n    let _ = f64::from(x2);\n    //~^ cast_lossless\n    let x3 = 1u16;\n    let _ = f32::from(x3);\n    //~^ cast_lossless\n    let _ = f64::from(x3);\n    //~^ cast_lossless\n    let x4 = 1i32;\n    let _ = f64::from(x4);\n    //~^ cast_lossless\n    let x5 = 1u32;\n    let _ = f64::from(x5);\n    //~^ cast_lossless\n\n    // Test with casts from floating-point types\n    let _ = f64::from(1.0f32);\n    //~^ cast_lossless\n}\n\n// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,\n// so we skip the lint if the expression is in a const fn.\n// See #3656\nconst fn abc(input: f32) -> f64 {\n    input as f64\n}\n\n// Same as the above issue. We can't suggest `::from` in const fns in impls\nmod cast_lossless_in_impl {\n    struct A;\n\n    impl A {\n        pub const fn convert(x: f32) -> f64 {\n            x as f64\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/cast_lossless_float.rs",
    "content": "#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]\n#![warn(clippy::cast_lossless)]\n\n// FIXME(f16_f128): add tests for these types once const casting is available\n\ntype F32 = f32;\ntype F64 = f64;\n\nfn main() {\n    // Test clippy::cast_lossless with casts to floating-point types\n    let x0 = 1i8;\n    let _ = x0 as f32;\n    //~^ cast_lossless\n    let _ = x0 as f64;\n    //~^ cast_lossless\n    let _ = x0 as F32;\n    //~^ cast_lossless\n    let _ = x0 as F64;\n    //~^ cast_lossless\n    let x1 = 1u8;\n    let _ = x1 as f32;\n    //~^ cast_lossless\n    let _ = x1 as f64;\n    //~^ cast_lossless\n    let x2 = 1i16;\n    let _ = x2 as f32;\n    //~^ cast_lossless\n    let _ = x2 as f64;\n    //~^ cast_lossless\n    let x3 = 1u16;\n    let _ = x3 as f32;\n    //~^ cast_lossless\n    let _ = x3 as f64;\n    //~^ cast_lossless\n    let x4 = 1i32;\n    let _ = x4 as f64;\n    //~^ cast_lossless\n    let x5 = 1u32;\n    let _ = x5 as f64;\n    //~^ cast_lossless\n\n    // Test with casts from floating-point types\n    let _ = 1.0f32 as f64;\n    //~^ cast_lossless\n}\n\n// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,\n// so we skip the lint if the expression is in a const fn.\n// See #3656\nconst fn abc(input: f32) -> f64 {\n    input as f64\n}\n\n// Same as the above issue. We can't suggest `::from` in const fns in impls\nmod cast_lossless_in_impl {\n    struct A;\n\n    impl A {\n        pub const fn convert(x: f32) -> f64 {\n            x as f64\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/cast_lossless_float.stderr",
    "content": "error: casts from `i8` to `f32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:12:13\n   |\nLL |     let _ = x0 as f32;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\n   = note: `-D clippy::cast-lossless` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`\nhelp: use `f32::from` instead\n   |\nLL -     let _ = x0 as f32;\nLL +     let _ = f32::from(x0);\n   |\n\nerror: casts from `i8` to `f64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:14:13\n   |\nLL |     let _ = x0 as f64;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f64::from` instead\n   |\nLL -     let _ = x0 as f64;\nLL +     let _ = f64::from(x0);\n   |\n\nerror: casts from `i8` to `f32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:16:13\n   |\nLL |     let _ = x0 as F32;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `F32::from` instead\n   |\nLL -     let _ = x0 as F32;\nLL +     let _ = F32::from(x0);\n   |\n\nerror: casts from `i8` to `f64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:18:13\n   |\nLL |     let _ = x0 as F64;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `F64::from` instead\n   |\nLL -     let _ = x0 as F64;\nLL +     let _ = F64::from(x0);\n   |\n\nerror: casts from `u8` to `f32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:21:13\n   |\nLL |     let _ = x1 as f32;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f32::from` instead\n   |\nLL -     let _ = x1 as f32;\nLL +     let _ = f32::from(x1);\n   |\n\nerror: casts from `u8` to `f64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:23:13\n   |\nLL |     let _ = x1 as f64;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f64::from` instead\n   |\nLL -     let _ = x1 as f64;\nLL +     let _ = f64::from(x1);\n   |\n\nerror: casts from `i16` to `f32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:26:13\n   |\nLL |     let _ = x2 as f32;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f32::from` instead\n   |\nLL -     let _ = x2 as f32;\nLL +     let _ = f32::from(x2);\n   |\n\nerror: casts from `i16` to `f64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:28:13\n   |\nLL |     let _ = x2 as f64;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f64::from` instead\n   |\nLL -     let _ = x2 as f64;\nLL +     let _ = f64::from(x2);\n   |\n\nerror: casts from `u16` to `f32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:31:13\n   |\nLL |     let _ = x3 as f32;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f32::from` instead\n   |\nLL -     let _ = x3 as f32;\nLL +     let _ = f32::from(x3);\n   |\n\nerror: casts from `u16` to `f64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:33:13\n   |\nLL |     let _ = x3 as f64;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f64::from` instead\n   |\nLL -     let _ = x3 as f64;\nLL +     let _ = f64::from(x3);\n   |\n\nerror: casts from `i32` to `f64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:36:13\n   |\nLL |     let _ = x4 as f64;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f64::from` instead\n   |\nLL -     let _ = x4 as f64;\nLL +     let _ = f64::from(x4);\n   |\n\nerror: casts from `u32` to `f64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:39:13\n   |\nLL |     let _ = x5 as f64;\n   |             ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f64::from` instead\n   |\nLL -     let _ = x5 as f64;\nLL +     let _ = f64::from(x5);\n   |\n\nerror: casts from `f32` to `f64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_float.rs:43:13\n   |\nLL |     let _ = 1.0f32 as f64;\n   |             ^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `f64::from` instead\n   |\nLL -     let _ = 1.0f32 as f64;\nLL +     let _ = f64::from(1.0f32);\n   |\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_lossless_integer.fixed",
    "content": "#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]\n#![warn(clippy::cast_lossless)]\n\ntype I64Alias = i64;\n\nfn main() {\n    // Test clippy::cast_lossless with casts to integer types\n    u16::from(0u8);\n    //~^ cast_lossless\n\n    i16::from(0u8);\n    //~^ cast_lossless\n\n    u32::from(0u8);\n    //~^ cast_lossless\n\n    i32::from(0u8);\n    //~^ cast_lossless\n\n    u64::from(0u8);\n    //~^ cast_lossless\n\n    i64::from(0u8);\n    //~^ cast_lossless\n\n    u128::from(0u8);\n    //~^ cast_lossless\n\n    i128::from(0u8);\n    //~^ cast_lossless\n\n    u32::from(0u16);\n    //~^ cast_lossless\n\n    i32::from(0u16);\n    //~^ cast_lossless\n\n    u64::from(0u16);\n    //~^ cast_lossless\n\n    i64::from(0u16);\n    //~^ cast_lossless\n\n    u128::from(0u16);\n    //~^ cast_lossless\n\n    i128::from(0u16);\n    //~^ cast_lossless\n\n    u64::from(0u32);\n    //~^ cast_lossless\n\n    i64::from(0u32);\n    //~^ cast_lossless\n\n    u128::from(0u32);\n    //~^ cast_lossless\n\n    i128::from(0u32);\n    //~^ cast_lossless\n\n    u128::from(0u64);\n    //~^ cast_lossless\n\n    i128::from(0u64);\n    //~^ cast_lossless\n\n    i16::from(0i8);\n    //~^ cast_lossless\n\n    i32::from(0i8);\n    //~^ cast_lossless\n\n    i64::from(0i8);\n    //~^ cast_lossless\n\n    i128::from(0i8);\n    //~^ cast_lossless\n\n    i32::from(0i16);\n    //~^ cast_lossless\n\n    i64::from(0i16);\n    //~^ cast_lossless\n\n    i128::from(0i16);\n    //~^ cast_lossless\n\n    i64::from(0i32);\n    //~^ cast_lossless\n\n    i128::from(0i32);\n    //~^ cast_lossless\n\n    i128::from(0i64);\n    //~^ cast_lossless\n\n    // Test with an expression wrapped in parens\n    let _ = u16::from(1u8 + 1u8);\n    //~^ cast_lossless\n\n    let _ = I64Alias::from(1i8);\n    //~^ cast_lossless\n\n    let _: u16 = 0u8.into();\n    //~^ cast_lossless\n\n    let _: i16 = (-1i8).into();\n    //~^ cast_lossless\n\n    let _: u16 = (1u8 + 2).into();\n    //~^ cast_lossless\n\n    let _: u32 = (1i8 as u16).into();\n    //~^ cast_lossless\n}\n\n// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,\n// so we skip the lint if the expression is in a const fn.\n// See #3656\nconst fn abc(input: u16) -> u32 {\n    input as u32\n}\n\n// Same as the above issue. We can't suggest `::from` in const fns in impls\nmod cast_lossless_in_impl {\n    struct A;\n\n    impl A {\n        pub const fn convert(x: u32) -> u64 {\n            x as u64\n        }\n    }\n}\n\n#[derive(PartialEq, Debug)]\n#[repr(i64)]\nenum Test {\n    A = u32::MAX as i64 + 1,\n}\n\nfn issue11458() {\n    macro_rules! sign_cast {\n        ($var: ident, $src: ty, $dest: ty) => {\n            <$dest>::from_ne_bytes(($var as $src).to_ne_bytes())\n        };\n    }\n    let x = 10_u128;\n    let _ = i32::from(sign_cast!(x, u8, i8));\n    //~^ cast_lossless\n\n    let _ = i32::from(sign_cast!(x, u8, i8) + 1);\n    //~^ cast_lossless\n}\n\nfn issue12695() {\n    macro_rules! in_macro {\n        () => {\n            u32::from(1u8)\n            //~^ cast_lossless\n        };\n    }\n\n    let _ = in_macro!();\n}\n\nfn ty_from_macro() {\n    macro_rules! ty {\n        () => {\n            u32\n        };\n    }\n\n    let _ = <ty!()>::from(0u8);\n    //~^ cast_lossless\n}\n\nconst IN_CONST: u64 = 0u8 as u64;\n"
  },
  {
    "path": "tests/ui/cast_lossless_integer.rs",
    "content": "#![allow(clippy::no_effect, clippy::unnecessary_operation, dead_code)]\n#![warn(clippy::cast_lossless)]\n\ntype I64Alias = i64;\n\nfn main() {\n    // Test clippy::cast_lossless with casts to integer types\n    0u8 as u16;\n    //~^ cast_lossless\n\n    0u8 as i16;\n    //~^ cast_lossless\n\n    0u8 as u32;\n    //~^ cast_lossless\n\n    0u8 as i32;\n    //~^ cast_lossless\n\n    0u8 as u64;\n    //~^ cast_lossless\n\n    0u8 as i64;\n    //~^ cast_lossless\n\n    0u8 as u128;\n    //~^ cast_lossless\n\n    0u8 as i128;\n    //~^ cast_lossless\n\n    0u16 as u32;\n    //~^ cast_lossless\n\n    0u16 as i32;\n    //~^ cast_lossless\n\n    0u16 as u64;\n    //~^ cast_lossless\n\n    0u16 as i64;\n    //~^ cast_lossless\n\n    0u16 as u128;\n    //~^ cast_lossless\n\n    0u16 as i128;\n    //~^ cast_lossless\n\n    0u32 as u64;\n    //~^ cast_lossless\n\n    0u32 as i64;\n    //~^ cast_lossless\n\n    0u32 as u128;\n    //~^ cast_lossless\n\n    0u32 as i128;\n    //~^ cast_lossless\n\n    0u64 as u128;\n    //~^ cast_lossless\n\n    0u64 as i128;\n    //~^ cast_lossless\n\n    0i8 as i16;\n    //~^ cast_lossless\n\n    0i8 as i32;\n    //~^ cast_lossless\n\n    0i8 as i64;\n    //~^ cast_lossless\n\n    0i8 as i128;\n    //~^ cast_lossless\n\n    0i16 as i32;\n    //~^ cast_lossless\n\n    0i16 as i64;\n    //~^ cast_lossless\n\n    0i16 as i128;\n    //~^ cast_lossless\n\n    0i32 as i64;\n    //~^ cast_lossless\n\n    0i32 as i128;\n    //~^ cast_lossless\n\n    0i64 as i128;\n    //~^ cast_lossless\n\n    // Test with an expression wrapped in parens\n    let _ = (1u8 + 1u8) as u16;\n    //~^ cast_lossless\n\n    let _ = 1i8 as I64Alias;\n    //~^ cast_lossless\n\n    let _: u16 = 0u8 as _;\n    //~^ cast_lossless\n\n    let _: i16 = -1i8 as _;\n    //~^ cast_lossless\n\n    let _: u16 = (1u8 + 2) as _;\n    //~^ cast_lossless\n\n    let _: u32 = 1i8 as u16 as _;\n    //~^ cast_lossless\n}\n\n// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,\n// so we skip the lint if the expression is in a const fn.\n// See #3656\nconst fn abc(input: u16) -> u32 {\n    input as u32\n}\n\n// Same as the above issue. We can't suggest `::from` in const fns in impls\nmod cast_lossless_in_impl {\n    struct A;\n\n    impl A {\n        pub const fn convert(x: u32) -> u64 {\n            x as u64\n        }\n    }\n}\n\n#[derive(PartialEq, Debug)]\n#[repr(i64)]\nenum Test {\n    A = u32::MAX as i64 + 1,\n}\n\nfn issue11458() {\n    macro_rules! sign_cast {\n        ($var: ident, $src: ty, $dest: ty) => {\n            <$dest>::from_ne_bytes(($var as $src).to_ne_bytes())\n        };\n    }\n    let x = 10_u128;\n    let _ = sign_cast!(x, u8, i8) as i32;\n    //~^ cast_lossless\n\n    let _ = (sign_cast!(x, u8, i8) + 1) as i32;\n    //~^ cast_lossless\n}\n\nfn issue12695() {\n    macro_rules! in_macro {\n        () => {\n            1u8 as u32\n            //~^ cast_lossless\n        };\n    }\n\n    let _ = in_macro!();\n}\n\nfn ty_from_macro() {\n    macro_rules! ty {\n        () => {\n            u32\n        };\n    }\n\n    let _ = 0u8 as ty!();\n    //~^ cast_lossless\n}\n\nconst IN_CONST: u64 = 0u8 as u64;\n"
  },
  {
    "path": "tests/ui/cast_lossless_integer.stderr",
    "content": "error: casts from `u8` to `u16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:8:5\n   |\nLL |     0u8 as u16;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\n   = note: `-D clippy::cast-lossless` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`\nhelp: use `u16::from` instead\n   |\nLL -     0u8 as u16;\nLL +     u16::from(0u8);\n   |\n\nerror: casts from `u8` to `i16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:11:5\n   |\nLL |     0u8 as i16;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i16::from` instead\n   |\nLL -     0u8 as i16;\nLL +     i16::from(0u8);\n   |\n\nerror: casts from `u8` to `u32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:14:5\n   |\nLL |     0u8 as u32;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u32::from` instead\n   |\nLL -     0u8 as u32;\nLL +     u32::from(0u8);\n   |\n\nerror: casts from `u8` to `i32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:17:5\n   |\nLL |     0u8 as i32;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i32::from` instead\n   |\nLL -     0u8 as i32;\nLL +     i32::from(0u8);\n   |\n\nerror: casts from `u8` to `u64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:20:5\n   |\nLL |     0u8 as u64;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u64::from` instead\n   |\nLL -     0u8 as u64;\nLL +     u64::from(0u8);\n   |\n\nerror: casts from `u8` to `i64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:23:5\n   |\nLL |     0u8 as i64;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i64::from` instead\n   |\nLL -     0u8 as i64;\nLL +     i64::from(0u8);\n   |\n\nerror: casts from `u8` to `u128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:26:5\n   |\nLL |     0u8 as u128;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u128::from` instead\n   |\nLL -     0u8 as u128;\nLL +     u128::from(0u8);\n   |\n\nerror: casts from `u8` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:29:5\n   |\nLL |     0u8 as i128;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     0u8 as i128;\nLL +     i128::from(0u8);\n   |\n\nerror: casts from `u16` to `u32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:32:5\n   |\nLL |     0u16 as u32;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u32::from` instead\n   |\nLL -     0u16 as u32;\nLL +     u32::from(0u16);\n   |\n\nerror: casts from `u16` to `i32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:35:5\n   |\nLL |     0u16 as i32;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i32::from` instead\n   |\nLL -     0u16 as i32;\nLL +     i32::from(0u16);\n   |\n\nerror: casts from `u16` to `u64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:38:5\n   |\nLL |     0u16 as u64;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u64::from` instead\n   |\nLL -     0u16 as u64;\nLL +     u64::from(0u16);\n   |\n\nerror: casts from `u16` to `i64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:41:5\n   |\nLL |     0u16 as i64;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i64::from` instead\n   |\nLL -     0u16 as i64;\nLL +     i64::from(0u16);\n   |\n\nerror: casts from `u16` to `u128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:44:5\n   |\nLL |     0u16 as u128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u128::from` instead\n   |\nLL -     0u16 as u128;\nLL +     u128::from(0u16);\n   |\n\nerror: casts from `u16` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:47:5\n   |\nLL |     0u16 as i128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     0u16 as i128;\nLL +     i128::from(0u16);\n   |\n\nerror: casts from `u32` to `u64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:50:5\n   |\nLL |     0u32 as u64;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u64::from` instead\n   |\nLL -     0u32 as u64;\nLL +     u64::from(0u32);\n   |\n\nerror: casts from `u32` to `i64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:53:5\n   |\nLL |     0u32 as i64;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i64::from` instead\n   |\nLL -     0u32 as i64;\nLL +     i64::from(0u32);\n   |\n\nerror: casts from `u32` to `u128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:56:5\n   |\nLL |     0u32 as u128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u128::from` instead\n   |\nLL -     0u32 as u128;\nLL +     u128::from(0u32);\n   |\n\nerror: casts from `u32` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:59:5\n   |\nLL |     0u32 as i128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     0u32 as i128;\nLL +     i128::from(0u32);\n   |\n\nerror: casts from `u64` to `u128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:62:5\n   |\nLL |     0u64 as u128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u128::from` instead\n   |\nLL -     0u64 as u128;\nLL +     u128::from(0u64);\n   |\n\nerror: casts from `u64` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:65:5\n   |\nLL |     0u64 as i128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     0u64 as i128;\nLL +     i128::from(0u64);\n   |\n\nerror: casts from `i8` to `i16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:68:5\n   |\nLL |     0i8 as i16;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i16::from` instead\n   |\nLL -     0i8 as i16;\nLL +     i16::from(0i8);\n   |\n\nerror: casts from `i8` to `i32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:71:5\n   |\nLL |     0i8 as i32;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i32::from` instead\n   |\nLL -     0i8 as i32;\nLL +     i32::from(0i8);\n   |\n\nerror: casts from `i8` to `i64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:74:5\n   |\nLL |     0i8 as i64;\n   |     ^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i64::from` instead\n   |\nLL -     0i8 as i64;\nLL +     i64::from(0i8);\n   |\n\nerror: casts from `i8` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:77:5\n   |\nLL |     0i8 as i128;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     0i8 as i128;\nLL +     i128::from(0i8);\n   |\n\nerror: casts from `i16` to `i32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:80:5\n   |\nLL |     0i16 as i32;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i32::from` instead\n   |\nLL -     0i16 as i32;\nLL +     i32::from(0i16);\n   |\n\nerror: casts from `i16` to `i64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:83:5\n   |\nLL |     0i16 as i64;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i64::from` instead\n   |\nLL -     0i16 as i64;\nLL +     i64::from(0i16);\n   |\n\nerror: casts from `i16` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:86:5\n   |\nLL |     0i16 as i128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     0i16 as i128;\nLL +     i128::from(0i16);\n   |\n\nerror: casts from `i32` to `i64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:89:5\n   |\nLL |     0i32 as i64;\n   |     ^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i64::from` instead\n   |\nLL -     0i32 as i64;\nLL +     i64::from(0i32);\n   |\n\nerror: casts from `i32` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:92:5\n   |\nLL |     0i32 as i128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     0i32 as i128;\nLL +     i128::from(0i32);\n   |\n\nerror: casts from `i64` to `i128` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:95:5\n   |\nLL |     0i64 as i128;\n   |     ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i128::from` instead\n   |\nLL -     0i64 as i128;\nLL +     i128::from(0i64);\n   |\n\nerror: casts from `u8` to `u16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:99:13\n   |\nLL |     let _ = (1u8 + 1u8) as u16;\n   |             ^^^^^^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `u16::from` instead\n   |\nLL -     let _ = (1u8 + 1u8) as u16;\nLL +     let _ = u16::from(1u8 + 1u8);\n   |\n\nerror: casts from `i8` to `i64` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:102:13\n   |\nLL |     let _ = 1i8 as I64Alias;\n   |             ^^^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `I64Alias::from` instead\n   |\nLL -     let _ = 1i8 as I64Alias;\nLL +     let _ = I64Alias::from(1i8);\n   |\n\nerror: casts from `u8` to `u16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:105:18\n   |\nLL |     let _: u16 = 0u8 as _;\n   |                  ^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `Into::into` instead\n   |\nLL -     let _: u16 = 0u8 as _;\nLL +     let _: u16 = 0u8.into();\n   |\n\nerror: casts from `i8` to `i16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:108:18\n   |\nLL |     let _: i16 = -1i8 as _;\n   |                  ^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `Into::into` instead\n   |\nLL -     let _: i16 = -1i8 as _;\nLL +     let _: i16 = (-1i8).into();\n   |\n\nerror: casts from `u8` to `u16` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:111:18\n   |\nLL |     let _: u16 = (1u8 + 2) as _;\n   |                  ^^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `Into::into` instead\n   |\nLL -     let _: u16 = (1u8 + 2) as _;\nLL +     let _: u16 = (1u8 + 2).into();\n   |\n\nerror: casts from `u16` to `u32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:114:18\n   |\nLL |     let _: u32 = 1i8 as u16 as _;\n   |                  ^^^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `Into::into` instead\n   |\nLL -     let _: u32 = 1i8 as u16 as _;\nLL +     let _: u32 = (1i8 as u16).into();\n   |\n\nerror: casts from `i8` to `i32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:149:13\n   |\nLL |     let _ = sign_cast!(x, u8, i8) as i32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i32::from` instead\n   |\nLL -     let _ = sign_cast!(x, u8, i8) as i32;\nLL +     let _ = i32::from(sign_cast!(x, u8, i8));\n   |\n\nerror: casts from `i8` to `i32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:152:13\n   |\nLL |     let _ = (sign_cast!(x, u8, i8) + 1) as i32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `i32::from` instead\n   |\nLL -     let _ = (sign_cast!(x, u8, i8) + 1) as i32;\nLL +     let _ = i32::from(sign_cast!(x, u8, i8) + 1);\n   |\n\nerror: casts from `u8` to `u32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:159:13\n   |\nLL |             1u8 as u32\n   |             ^^^^^^^^^^\n...\nLL |     let _ = in_macro!();\n   |             ----------- in this macro invocation\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\n   = note: this error originates in the macro `in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: use `u32::from` instead\n   |\nLL -             1u8 as u32\nLL +             u32::from(1u8)\n   |\n\nerror: casts from `u8` to `u32` can be expressed infallibly using `From`\n  --> tests/ui/cast_lossless_integer.rs:174:13\n   |\nLL |     let _ = 0u8 as ty!();\n   |             ^^^^^^^^^^^^\n   |\n   = help: an `as` cast can become silently lossy if the types change in the future\nhelp: use `<ty!()>::from` instead\n   |\nLL -     let _ = 0u8 as ty!();\nLL +     let _ = <ty!()>::from(0u8);\n   |\n\nerror: aborting due to 40 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_lossless_integer_unfixable.rs",
    "content": "//@check-pass\n#![warn(clippy::cast_lossless)]\n\nfn issue15348() {\n    macro_rules! zero {\n        ($int:ty) => {{\n            let data: [u8; 3] = [0, 0, 0];\n            data[0] as $int\n        }};\n    }\n\n    let _ = zero!(u8);\n    let _ = zero!(u16);\n    let _ = zero!(u32);\n    let _ = zero!(u64);\n    let _ = zero!(u128);\n}\n"
  },
  {
    "path": "tests/ui/cast_nan_to_int.rs",
    "content": "// FIXME(f16_f128): add tests when constants are available\n\n#![warn(clippy::cast_nan_to_int)]\n#![allow(clippy::eq_op)]\n\nfn main() {\n    let _ = (0.0_f32 / -0.0) as usize;\n    //~^ cast_nan_to_int\n\n    let _ = (f64::INFINITY * -0.0) as usize;\n    //~^ cast_nan_to_int\n\n    let _ = (0.0 * f32::INFINITY) as usize;\n    //~^ cast_nan_to_int\n\n    let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize;\n    //~^ cast_nan_to_int\n\n    let _ = (f32::INFINITY - f32::INFINITY) as usize;\n    //~^ cast_nan_to_int\n\n    let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize;\n    //~^ cast_nan_to_int\n\n    // those won't be linted:\n    let _ = (1.0_f32 / 0.0) as usize;\n    let _ = (f32::INFINITY * f32::NEG_INFINITY) as usize;\n    let _ = (f32::INFINITY - f32::NEG_INFINITY) as usize;\n    let _ = (f64::INFINITY - 0.0) as usize;\n}\n"
  },
  {
    "path": "tests/ui/cast_nan_to_int.stderr",
    "content": "error: casting a known NaN to usize\n  --> tests/ui/cast_nan_to_int.rs:7:13\n   |\nLL |     let _ = (0.0_f32 / -0.0) as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this always evaluates to 0\n   = note: `-D clippy::cast-nan-to-int` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_nan_to_int)]`\n\nerror: casting a known NaN to usize\n  --> tests/ui/cast_nan_to_int.rs:10:13\n   |\nLL |     let _ = (f64::INFINITY * -0.0) as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this always evaluates to 0\n\nerror: casting a known NaN to usize\n  --> tests/ui/cast_nan_to_int.rs:13:13\n   |\nLL |     let _ = (0.0 * f32::INFINITY) as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this always evaluates to 0\n\nerror: casting a known NaN to usize\n  --> tests/ui/cast_nan_to_int.rs:16:13\n   |\nLL |     let _ = (f64::INFINITY + f64::NEG_INFINITY) as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this always evaluates to 0\n\nerror: casting a known NaN to usize\n  --> tests/ui/cast_nan_to_int.rs:19:13\n   |\nLL |     let _ = (f32::INFINITY - f32::INFINITY) as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this always evaluates to 0\n\nerror: casting a known NaN to usize\n  --> tests/ui/cast_nan_to_int.rs:22:13\n   |\nLL |     let _ = (f32::INFINITY / f32::NEG_INFINITY) as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this always evaluates to 0\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_raw_slice_pointer_cast.fixed",
    "content": "#![warn(clippy::cast_slice_from_raw_parts)]\n\nconst fn require_raw_slice_ptr<T>(_: *const [T]) {}\n\nfn main() {\n    let mut vec = vec![0u8; 1];\n    let ptr: *const u8 = vec.as_ptr();\n    let mptr = vec.as_mut_ptr();\n    let _: *const [u8] = unsafe { std::ptr::slice_from_raw_parts(ptr, 1) };\n    //~^ cast_slice_from_raw_parts\n    let _: *const [u8] = unsafe { std::ptr::slice_from_raw_parts_mut(mptr, 1) };\n    //~^ cast_slice_from_raw_parts\n    let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);\n    //~^ cast_slice_from_raw_parts\n    {\n        use core::slice;\n        let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);\n        //~^ cast_slice_from_raw_parts\n        use slice as one;\n        let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);\n        //~^ cast_slice_from_raw_parts\n    }\n    {\n        use std::slice;\n        let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);\n        //~^ cast_slice_from_raw_parts\n        use slice as one;\n        let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);\n        //~^ cast_slice_from_raw_parts\n    }\n\n    // implicit cast\n    {\n        let _: *const [u8] = unsafe { std::ptr::slice_from_raw_parts(ptr, 1) };\n        //~^ cast_slice_from_raw_parts\n        let _: *mut [u8] = unsafe { std::ptr::slice_from_raw_parts_mut(mptr, 1) };\n        //~^ cast_slice_from_raw_parts\n        require_raw_slice_ptr(unsafe { std::ptr::slice_from_raw_parts(ptr, 1) });\n        //~^ cast_slice_from_raw_parts\n    }\n\n    // implicit cast in const context\n    const {\n        const PTR: *const u8 = std::ptr::null();\n        const MPTR: *mut u8 = std::ptr::null_mut();\n        let _: *const [u8] = unsafe { std::ptr::slice_from_raw_parts(PTR, 1) };\n        //~^ cast_slice_from_raw_parts\n        let _: *mut [u8] = unsafe { std::ptr::slice_from_raw_parts_mut(MPTR, 1) };\n        //~^ cast_slice_from_raw_parts\n        require_raw_slice_ptr(unsafe { std::ptr::slice_from_raw_parts(PTR, 1) });\n        //~^ cast_slice_from_raw_parts\n    };\n}\n"
  },
  {
    "path": "tests/ui/cast_raw_slice_pointer_cast.rs",
    "content": "#![warn(clippy::cast_slice_from_raw_parts)]\n\nconst fn require_raw_slice_ptr<T>(_: *const [T]) {}\n\nfn main() {\n    let mut vec = vec![0u8; 1];\n    let ptr: *const u8 = vec.as_ptr();\n    let mptr = vec.as_mut_ptr();\n    let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] };\n    //~^ cast_slice_from_raw_parts\n    let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };\n    //~^ cast_slice_from_raw_parts\n    let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8];\n    //~^ cast_slice_from_raw_parts\n    {\n        use core::slice;\n        let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];\n        //~^ cast_slice_from_raw_parts\n        use slice as one;\n        let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];\n        //~^ cast_slice_from_raw_parts\n    }\n    {\n        use std::slice;\n        let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];\n        //~^ cast_slice_from_raw_parts\n        use slice as one;\n        let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];\n        //~^ cast_slice_from_raw_parts\n    }\n\n    // implicit cast\n    {\n        let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) };\n        //~^ cast_slice_from_raw_parts\n        let _: *mut [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) };\n        //~^ cast_slice_from_raw_parts\n        require_raw_slice_ptr(unsafe { std::slice::from_raw_parts(ptr, 1) });\n        //~^ cast_slice_from_raw_parts\n    }\n\n    // implicit cast in const context\n    const {\n        const PTR: *const u8 = std::ptr::null();\n        const MPTR: *mut u8 = std::ptr::null_mut();\n        let _: *const [u8] = unsafe { std::slice::from_raw_parts(PTR, 1) };\n        //~^ cast_slice_from_raw_parts\n        let _: *mut [u8] = unsafe { std::slice::from_raw_parts_mut(MPTR, 1) };\n        //~^ cast_slice_from_raw_parts\n        require_raw_slice_ptr(unsafe { std::slice::from_raw_parts(PTR, 1) });\n        //~^ cast_slice_from_raw_parts\n    };\n}\n"
  },
  {
    "path": "tests/ui/cast_raw_slice_pointer_cast.stderr",
    "content": "error: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:9:35\n   |\nLL |     let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] };\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`\n   |\n   = note: `-D clippy::cast-slice-from-raw-parts` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_slice_from_raw_parts)]`\n\nerror: casting the result of `from_raw_parts_mut` to *mut [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:11:35\n   |\nLL |     let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts_mut(mptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:13:26\n   |\nLL |     let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8];\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:17:30\n   |\nLL |         let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:20:30\n   |\nLL |         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:25:30\n   |\nLL |         let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:28:30\n   |\nLL |         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: implicitly casting the result of `from_raw_parts` to `*const [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:34:39\n   |\nLL |         let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) };\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: implicitly casting the result of `from_raw_parts_mut` to `*mut [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:36:37\n   |\nLL |         let _: *mut [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) };\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts_mut(mptr, 1)`\n\nerror: implicitly casting the result of `from_raw_parts` to `*const [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:38:40\n   |\nLL |         require_raw_slice_ptr(unsafe { std::slice::from_raw_parts(ptr, 1) });\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: implicitly casting the result of `from_raw_parts` to `*const [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:46:39\n   |\nLL |         let _: *const [u8] = unsafe { std::slice::from_raw_parts(PTR, 1) };\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts(PTR, 1)`\n\nerror: implicitly casting the result of `from_raw_parts_mut` to `*mut [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:48:37\n   |\nLL |         let _: *mut [u8] = unsafe { std::slice::from_raw_parts_mut(MPTR, 1) };\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts_mut(MPTR, 1)`\n\nerror: implicitly casting the result of `from_raw_parts` to `*const [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast.rs:50:40\n   |\nLL |         require_raw_slice_ptr(unsafe { std::slice::from_raw_parts(PTR, 1) });\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts(PTR, 1)`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_raw_slice_pointer_cast_no_std.fixed",
    "content": "#![warn(clippy::cast_slice_from_raw_parts)]\n#![no_std]\n#![crate_type = \"lib\"]\n\nconst fn require_raw_slice_ptr<T>(_: *const [T]) {}\n\nfn main() {\n    let mut arr = [0u8; 1];\n    let ptr: *const u8 = arr.as_ptr();\n    let mptr = arr.as_mut_ptr();\n    let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(ptr, 1) };\n    //~^ cast_slice_from_raw_parts\n    let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(mptr, 1) };\n    //~^ cast_slice_from_raw_parts\n    let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);\n    //~^ cast_slice_from_raw_parts\n    {\n        use core::slice;\n        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);\n        //~^ cast_slice_from_raw_parts\n        use slice as one;\n        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);\n        //~^ cast_slice_from_raw_parts\n    }\n    {\n        use core::slice;\n        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);\n        //~^ cast_slice_from_raw_parts\n        use slice as one;\n        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);\n        //~^ cast_slice_from_raw_parts\n    }\n\n    // implicit cast\n    {\n        let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(ptr, 1) };\n        //~^ cast_slice_from_raw_parts\n        let _: *mut [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(mptr, 1) };\n        //~^ cast_slice_from_raw_parts\n        require_raw_slice_ptr(unsafe { core::ptr::slice_from_raw_parts(ptr, 1) });\n        //~^ cast_slice_from_raw_parts\n    }\n\n    // implicit cast in const context\n    const {\n        const PTR: *const u8 = core::ptr::null();\n        const MPTR: *mut u8 = core::ptr::null_mut();\n        let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(PTR, 1) };\n        //~^ cast_slice_from_raw_parts\n        let _: *mut [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(MPTR, 1) };\n        //~^ cast_slice_from_raw_parts\n        require_raw_slice_ptr(unsafe { core::ptr::slice_from_raw_parts(PTR, 1) });\n        //~^ cast_slice_from_raw_parts\n    };\n}\n"
  },
  {
    "path": "tests/ui/cast_raw_slice_pointer_cast_no_std.rs",
    "content": "#![warn(clippy::cast_slice_from_raw_parts)]\n#![no_std]\n#![crate_type = \"lib\"]\n\nconst fn require_raw_slice_ptr<T>(_: *const [T]) {}\n\nfn main() {\n    let mut arr = [0u8; 1];\n    let ptr: *const u8 = arr.as_ptr();\n    let mptr = arr.as_mut_ptr();\n    let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) as *const [u8] };\n    //~^ cast_slice_from_raw_parts\n    let _: *const [u8] = unsafe { core::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };\n    //~^ cast_slice_from_raw_parts\n    let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) } as *const [u8];\n    //~^ cast_slice_from_raw_parts\n    {\n        use core::slice;\n        let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];\n        //~^ cast_slice_from_raw_parts\n        use slice as one;\n        let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];\n        //~^ cast_slice_from_raw_parts\n    }\n    {\n        use core::slice;\n        let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];\n        //~^ cast_slice_from_raw_parts\n        use slice as one;\n        let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];\n        //~^ cast_slice_from_raw_parts\n    }\n\n    // implicit cast\n    {\n        let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) };\n        //~^ cast_slice_from_raw_parts\n        let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(mptr, 1) };\n        //~^ cast_slice_from_raw_parts\n        require_raw_slice_ptr(unsafe { core::slice::from_raw_parts(ptr, 1) });\n        //~^ cast_slice_from_raw_parts\n    }\n\n    // implicit cast in const context\n    const {\n        const PTR: *const u8 = core::ptr::null();\n        const MPTR: *mut u8 = core::ptr::null_mut();\n        let _: *const [u8] = unsafe { core::slice::from_raw_parts(PTR, 1) };\n        //~^ cast_slice_from_raw_parts\n        let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(MPTR, 1) };\n        //~^ cast_slice_from_raw_parts\n        require_raw_slice_ptr(unsafe { core::slice::from_raw_parts(PTR, 1) });\n        //~^ cast_slice_from_raw_parts\n    };\n}\n"
  },
  {
    "path": "tests/ui/cast_raw_slice_pointer_cast_no_std.stderr",
    "content": "error: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:11:35\n   |\nLL |     let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) as *const [u8] };\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`\n   |\n   = note: `-D clippy::cast-slice-from-raw-parts` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_slice_from_raw_parts)]`\n\nerror: casting the result of `from_raw_parts_mut` to *mut [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:13:35\n   |\nLL |     let _: *const [u8] = unsafe { core::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:15:26\n   |\nLL |     let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) } as *const [u8];\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:19:30\n   |\nLL |         let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:22:30\n   |\nLL |         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:27:30\n   |\nLL |         let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: casting the result of `from_raw_parts` to *const [u8]\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:30:30\n   |\nLL |         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: implicitly casting the result of `from_raw_parts` to `*const [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:36:39\n   |\nLL |         let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) };\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: implicitly casting the result of `from_raw_parts_mut` to `*mut [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:38:37\n   |\nLL |         let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(mptr, 1) };\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)`\n\nerror: implicitly casting the result of `from_raw_parts` to `*const [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:40:40\n   |\nLL |         require_raw_slice_ptr(unsafe { core::slice::from_raw_parts(ptr, 1) });\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts(ptr, 1)`\n\nerror: implicitly casting the result of `from_raw_parts` to `*const [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:48:39\n   |\nLL |         let _: *const [u8] = unsafe { core::slice::from_raw_parts(PTR, 1) };\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts(PTR, 1)`\n\nerror: implicitly casting the result of `from_raw_parts_mut` to `*mut [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:50:37\n   |\nLL |         let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(MPTR, 1) };\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts_mut(MPTR, 1)`\n\nerror: implicitly casting the result of `from_raw_parts` to `*const [u8]`\n  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:52:40\n   |\nLL |         require_raw_slice_ptr(unsafe { core::slice::from_raw_parts(PTR, 1) });\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts(PTR, 1)`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_size.r32bit.stderr",
    "content": "error: casting `isize` to `i8` may truncate the value\n  --> tests/ui/cast_size.rs:17:5\n   |\nLL |     1isize as i8;\n   |     ^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n   = note: `-D clippy::cast-possible-truncation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1isize as i8;\nLL +     i8::try_from(1isize);\n   |\n\nerror: casting `isize` to `f32` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast_size.rs:24:5\n   |\nLL |     x0 as f32;\n   |     ^^^^^^^^^\n   |\n   = note: `-D clippy::cast-precision-loss` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`\n\nerror: casting `usize` to `f32` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast_size.rs:26:5\n   |\nLL |     x1 as f32;\n   |     ^^^^^^^^^\n\nerror: casting `isize` to `f64` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide)\n  --> tests/ui/cast_size.rs:28:5\n   |\nLL |     x0 as f64;\n   |     ^^^^^^^^^\n\nerror: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide)\n  --> tests/ui/cast_size.rs:30:5\n   |\nLL |     x1 as f64;\n   |     ^^^^^^^^^\n\nerror: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:35:5\n   |\nLL |     1isize as i32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1isize as i32;\nLL +     i32::try_from(1isize);\n   |\n\nerror: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:37:5\n   |\nLL |     1isize as u32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1isize as u32;\nLL +     u32::try_from(1isize);\n   |\n\nerror: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:39:5\n   |\nLL |     1usize as u32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1usize as u32;\nLL +     u32::try_from(1usize);\n   |\n\nerror: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:41:5\n   |\nLL |     1usize as i32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1usize as i32;\nLL +     i32::try_from(1usize);\n   |\n\nerror: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:41:5\n   |\nLL |     1usize as i32;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::cast-possible-wrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`\n\nerror: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:44:5\n   |\nLL |     1i64 as isize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1i64 as isize;\nLL +     isize::try_from(1i64);\n   |\n\nerror: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:46:5\n   |\nLL |     1i64 as usize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1i64 as usize;\nLL +     usize::try_from(1i64);\n   |\n\nerror: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:48:5\n   |\nLL |     1u64 as isize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1u64 as isize;\nLL +     isize::try_from(1u64);\n   |\n\nerror: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:48:5\n   |\nLL |     1u64 as isize;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:51:5\n   |\nLL |     1u64 as usize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1u64 as usize;\nLL +     usize::try_from(1u64);\n   |\n\nerror: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:53:5\n   |\nLL |     1u32 as isize;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast_size.rs:61:5\n   |\nLL |     999_999_999 as f32;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide)\n  --> tests/ui/cast_size.rs:63:5\n   |\nLL |     9_999_999_999_999_999usize as f64;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: casting `usize` to `u16` may truncate the value\n  --> tests/ui/cast_size.rs:71:20\n   |\nLL |     const N: u16 = M as u16;\n   |                    ^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: literal out of range for `usize`\n  --> tests/ui/cast_size.rs:63:5\n   |\nLL |     9_999_999_999_999_999usize as f64;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the literal `9_999_999_999_999_999usize` does not fit into the type `usize` whose range is `0..=4294967295`\n   = note: `#[deny(overflowing_literals)]` on by default\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_size.r64bit.stderr",
    "content": "error: casting `isize` to `i8` may truncate the value\n  --> tests/ui/cast_size.rs:17:5\n   |\nLL |     1isize as i8;\n   |     ^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n   = note: `-D clippy::cast-possible-truncation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1isize as i8;\nLL +     i8::try_from(1isize);\n   |\n\nerror: casting `isize` to `f32` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast_size.rs:24:5\n   |\nLL |     x0 as f32;\n   |     ^^^^^^^^^\n   |\n   = note: `-D clippy::cast-precision-loss` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`\n\nerror: casting `usize` to `f32` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast_size.rs:26:5\n   |\nLL |     x1 as f32;\n   |     ^^^^^^^^^\n\nerror: casting `isize` to `f64` may cause a loss of precision (`isize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide)\n  --> tests/ui/cast_size.rs:28:5\n   |\nLL |     x0 as f64;\n   |     ^^^^^^^^^\n\nerror: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide)\n  --> tests/ui/cast_size.rs:30:5\n   |\nLL |     x1 as f64;\n   |     ^^^^^^^^^\n\nerror: casting `isize` to `i32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:35:5\n   |\nLL |     1isize as i32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1isize as i32;\nLL +     i32::try_from(1isize);\n   |\n\nerror: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:37:5\n   |\nLL |     1isize as u32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1isize as u32;\nLL +     u32::try_from(1isize);\n   |\n\nerror: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:39:5\n   |\nLL |     1usize as u32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1usize as u32;\nLL +     u32::try_from(1usize);\n   |\n\nerror: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:41:5\n   |\nLL |     1usize as i32;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1usize as i32;\nLL +     i32::try_from(1usize);\n   |\n\nerror: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:41:5\n   |\nLL |     1usize as i32;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::cast-possible-wrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`\n\nerror: casting `i64` to `isize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:44:5\n   |\nLL |     1i64 as isize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1i64 as isize;\nLL +     isize::try_from(1i64);\n   |\n\nerror: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:46:5\n   |\nLL |     1i64 as usize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1i64 as usize;\nLL +     usize::try_from(1i64);\n   |\n\nerror: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:48:5\n   |\nLL |     1u64 as isize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1u64 as isize;\nLL +     isize::try_from(1u64);\n   |\n\nerror: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers\n  --> tests/ui/cast_size.rs:48:5\n   |\nLL |     1u64 as isize;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `u64` to `usize` may truncate the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:51:5\n   |\nLL |     1u64 as usize;\n   |     ^^^^^^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\nhelp: ... or use `try_from` and handle the error accordingly\n   |\nLL -     1u64 as usize;\nLL +     usize::try_from(1u64);\n   |\n\nerror: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers\n  --> tests/ui/cast_size.rs:53:5\n   |\nLL |     1u32 as isize;\n   |     ^^^^^^^^^^^^^\n\nerror: casting `i32` to `f32` may cause a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)\n  --> tests/ui/cast_size.rs:61:5\n   |\nLL |     999_999_999 as f32;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: casting `usize` to `f64` may cause a loss of precision (`usize` can be up to 64 bits wide depending on the target architecture, but `f64`'s mantissa is only 52 bits wide)\n  --> tests/ui/cast_size.rs:63:5\n   |\nLL |     9_999_999_999_999_999usize as f64;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: casting `usize` to `u16` may truncate the value\n  --> tests/ui/cast_size.rs:71:20\n   |\nLL |     const N: u16 = M as u16;\n   |                    ^^^^^^^^\n   |\n   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/cast_size.rs",
    "content": "//@revisions: r32bit r64bit\n//@[r32bit]ignore-bitwidth: 64\n//@[r64bit]ignore-bitwidth: 32\n//@no-rustfix: only some diagnostics have suggestions\n\n#![warn(\n    clippy::cast_precision_loss,\n    clippy::cast_possible_truncation,\n    clippy::cast_sign_loss,\n    clippy::cast_possible_wrap,\n    clippy::cast_lossless\n)]\n#![allow(clippy::no_effect, clippy::unnecessary_operation)]\n\nfn main() {\n    // Casting from *size\n    1isize as i8;\n    //~^ cast_possible_truncation\n    let x0 = 1isize;\n    let x1 = 1usize;\n    // FIXME(f16_f128): enable f16 and f128 conversions once const eval supports them\n    // x0 as f16;\n    // x1 as f16;\n    x0 as f32;\n    //~^ cast_precision_loss\n    x1 as f32;\n    //~^ cast_precision_loss\n    x0 as f64;\n    //~^ cast_precision_loss\n    x1 as f64;\n    //~^ cast_precision_loss\n    // x0 as f128;\n    // x1 as f128;\n\n    1isize as i32;\n    //~^ cast_possible_truncation\n    1isize as u32;\n    //~^ cast_possible_truncation\n    1usize as u32;\n    //~^ cast_possible_truncation\n    1usize as i32;\n    //~^ cast_possible_truncation\n    //~| cast_possible_wrap\n    1i64 as isize;\n    //~^ cast_possible_truncation\n    1i64 as usize;\n    //~^ cast_possible_truncation\n    1u64 as isize;\n    //~^ cast_possible_truncation\n    //~| cast_possible_wrap\n    1u64 as usize;\n    //~^ cast_possible_truncation\n    1u32 as isize;\n    //~^ cast_possible_wrap\n    1u32 as usize; // Should not trigger any lint\n    1i32 as isize; // Neither should this\n    1i32 as usize;\n\n    // Big integer literal to float\n    // 999_999 as f16;\n    999_999_999 as f32;\n    //~^ cast_precision_loss\n    9_999_999_999_999_999usize as f64;\n    //~^ cast_precision_loss\n    //~[r32bit]^^ ERROR: literal out of range for `usize`\n    // 999_999_999_999_999_999_999_999_999_999u128 as f128;\n}\n\nfn issue15163() {\n    const M: usize = 100;\n    const N: u16 = M as u16;\n    //~^ cast_possible_truncation\n}\n"
  },
  {
    "path": "tests/ui/cast_slice_different_sizes.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![allow(clippy::let_unit_value, clippy::unnecessary_cast)]\n\nfn main() {\n    let x: [i32; 3] = [1_i32, 2, 3];\n    let r_x = &x;\n    // Check casting through multiple bindings\n    // Because it's separate, it does not check the cast back to something of the same size\n    let a = r_x as *const [i32];\n    let b = a as *const [u8];\n    //~^ cast_slice_different_sizes\n\n    let c = b as *const [u32];\n    //~^ cast_slice_different_sizes\n\n    // loses data\n    let loss = r_x as *const [i32] as *const [u8];\n    //~^ cast_slice_different_sizes\n\n    // Cast back to same size but different type loses no data, just type conversion\n    // This is weird code but there's no reason for this lint specifically to fire *twice* on it\n    let restore = r_x as *const [i32] as *const [u8] as *const [u32];\n\n    // Check casting through blocks is detected\n    let loss_block_1 = { r_x as *const [i32] } as *const [u8];\n    //~^ cast_slice_different_sizes\n\n    let loss_block_2 = {\n        //~^ cast_slice_different_sizes\n\n        let _ = ();\n        r_x as *const [i32]\n    } as *const [u8];\n\n    // Check that resources of the same size are detected through blocks\n    let restore_block_1 = { r_x as *const [i32] } as *const [u8] as *const [u32];\n    let restore_block_2 = { ({ r_x as *const [i32] }) as *const [u8] } as *const [u32];\n    let restore_block_3 = {\n        let _ = ();\n        ({\n            let _ = ();\n            r_x as *const [i32]\n        }) as *const [u8]\n    } as *const [u32];\n\n    // Check that the result of a long chain of casts is detected\n    let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8];\n    //~^ cast_slice_different_sizes\n\n    let long_chain_restore =\n        r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8] as *const [u32];\n}\n\n// foo and foo2 should not fire, they're the same size\nfn foo(x: *mut [u8]) -> *mut [u8] {\n    x as *mut [u8]\n}\n\nfn foo2(x: *mut [u8]) -> *mut [u8] {\n    x as *mut _\n}\n\n// Test that casts as part of function returns work\nfn bar(x: *mut [u16]) -> *mut [u8] {\n    //~^ cast_slice_different_sizes\n\n    x as *mut [u8]\n}\n\nfn uwu(x: *mut [u16]) -> *mut [u8] {\n    //~^ cast_slice_different_sizes\n\n    x as *mut _\n}\n\nfn bar2(x: *mut [u16]) -> *mut [u8] {\n    //~^ cast_slice_different_sizes\n\n    x as _\n}\n\n// constify\nfn bar3(x: *mut [u16]) -> *const [u8] {\n    //~^ cast_slice_different_sizes\n\n    x as _\n}\n\n// unconstify\nfn bar4(x: *const [u16]) -> *mut [u8] {\n    //~^ cast_slice_different_sizes\n\n    x as _\n}\n\n// function returns plus blocks\nfn blocks(x: *mut [u16]) -> *mut [u8] {\n    //~^ cast_slice_different_sizes\n\n    ({ x }) as _\n}\n\nfn more_blocks(x: *mut [u16]) -> *mut [u8] {\n    //~^ cast_slice_different_sizes\n\n    { ({ x }) as _ }\n    //~^ cast_slice_different_sizes\n}\n"
  },
  {
    "path": "tests/ui/cast_slice_different_sizes.stderr",
    "content": "error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:10:13\n   |\nLL |     let b = a as *const [u8];\n   |             ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(a as *const u8, ..)`\n   |\n   = note: `#[deny(clippy::cast_slice_different_sizes)]` on by default\n\nerror: casting between raw pointers to `[u8]` (element size 1) and `[u32]` (element size 4) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:13:13\n   |\nLL |     let c = b as *const [u32];\n   |             ^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(b as *const u32, ..)`\n\nerror: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:17:16\n   |\nLL |     let loss = r_x as *const [i32] as *const [u8];\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)`\n\nerror: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:25:24\n   |\nLL |     let loss_block_1 = { r_x as *const [i32] } as *const [u8];\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts({ r_x as *const [i32] } as *const u8, ..)`\n\nerror: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:28:24\n   |\nLL |       let loss_block_2 = {\n   |  ________________________^\nLL | |\nLL | |\nLL | |         let _ = ();\nLL | |         r_x as *const [i32]\nLL | |     } as *const [u8];\n   | |____________________^\n   |\nhelp: replace with `ptr::slice_from_raw_parts`\n   |\nLL ~     let loss_block_2 = core::ptr::slice_from_raw_parts({\nLL +\nLL + \nLL +         let _ = ();\nLL +         r_x as *const [i32]\nLL ~     } as *const u8, ..);\n   |\n\nerror: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:47:27\n   |\nLL |     let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8];\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)`\n\nerror: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:64:36\n   |\nLL |   fn bar(x: *mut [u16]) -> *mut [u8] {\n   |  ____________________________________^\nLL | |\nLL | |\nLL | |     x as *mut [u8]\nLL | | }\n   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`\n\nerror: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:70:36\n   |\nLL |   fn uwu(x: *mut [u16]) -> *mut [u8] {\n   |  ____________________________________^\nLL | |\nLL | |\nLL | |     x as *mut _\nLL | | }\n   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`\n\nerror: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:76:37\n   |\nLL |   fn bar2(x: *mut [u16]) -> *mut [u8] {\n   |  _____________________________________^\nLL | |\nLL | |\nLL | |     x as _\nLL | | }\n   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`\n\nerror: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:83:39\n   |\nLL |   fn bar3(x: *mut [u16]) -> *const [u8] {\n   |  _______________________________________^\nLL | |\nLL | |\nLL | |     x as _\nLL | | }\n   | |_^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(x as *const u8, ..)`\n\nerror: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:90:39\n   |\nLL |   fn bar4(x: *const [u16]) -> *mut [u8] {\n   |  _______________________________________^\nLL | |\nLL | |\nLL | |     x as _\nLL | | }\n   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`\n\nerror: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:97:39\n   |\nLL |   fn blocks(x: *mut [u16]) -> *mut [u8] {\n   |  _______________________________________^\nLL | |\nLL | |\nLL | |     ({ x }) as _\nLL | | }\n   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`\n\nerror: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:103:44\n   |\nLL |   fn more_blocks(x: *mut [u16]) -> *mut [u8] {\n   |  ____________________________________________^\nLL | |\nLL | |\nLL | |     { ({ x }) as _ }\nLL | |\nLL | | }\n   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`\n\nerror: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count\n  --> tests/ui/cast_slice_different_sizes.rs:106:5\n   |\nLL |     { ({ x }) as _ }\n   |     ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/cfg_attr_cargo_clippy.fixed",
    "content": "#![warn(clippy::deprecated_clippy_cfg_attr)]\n#![allow(clippy::non_minimal_cfg)]\n#![cfg_attr(clippy, doc = \"a\")]\n//~^ deprecated_clippy_cfg_attr\n\n#[cfg_attr(clippy, derive(Debug))]\n//~^ deprecated_clippy_cfg_attr\n#[cfg_attr(not(clippy), derive(Debug))]\n//~^ deprecated_clippy_cfg_attr\n#[cfg(clippy)]\n//~^ deprecated_clippy_cfg_attr\n#[cfg(not(clippy))]\n//~^ deprecated_clippy_cfg_attr\n#[cfg(any(clippy))]\n//~^ deprecated_clippy_cfg_attr\n#[cfg(all(clippy))]\n//~^ deprecated_clippy_cfg_attr\npub struct Bar;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/cfg_attr_cargo_clippy.rs",
    "content": "#![warn(clippy::deprecated_clippy_cfg_attr)]\n#![allow(clippy::non_minimal_cfg)]\n#![cfg_attr(feature = \"cargo-clippy\", doc = \"a\")]\n//~^ deprecated_clippy_cfg_attr\n\n#[cfg_attr(feature = \"cargo-clippy\", derive(Debug))]\n//~^ deprecated_clippy_cfg_attr\n#[cfg_attr(not(feature = \"cargo-clippy\"), derive(Debug))]\n//~^ deprecated_clippy_cfg_attr\n#[cfg(feature = \"cargo-clippy\")]\n//~^ deprecated_clippy_cfg_attr\n#[cfg(not(feature = \"cargo-clippy\"))]\n//~^ deprecated_clippy_cfg_attr\n#[cfg(any(feature = \"cargo-clippy\"))]\n//~^ deprecated_clippy_cfg_attr\n#[cfg(all(feature = \"cargo-clippy\"))]\n//~^ deprecated_clippy_cfg_attr\npub struct Bar;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/cfg_attr_cargo_clippy.stderr",
    "content": "error: `feature = \"cargo-clippy\"` was replaced by `clippy`\n  --> tests/ui/cfg_attr_cargo_clippy.rs:3:13\n   |\nLL | #![cfg_attr(feature = \"cargo-clippy\", doc = \"a\")]\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`\n   |\n   = note: `-D clippy::deprecated-clippy-cfg-attr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::deprecated_clippy_cfg_attr)]`\n\nerror: `feature = \"cargo-clippy\"` was replaced by `clippy`\n  --> tests/ui/cfg_attr_cargo_clippy.rs:6:12\n   |\nLL | #[cfg_attr(feature = \"cargo-clippy\", derive(Debug))]\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`\n\nerror: `feature = \"cargo-clippy\"` was replaced by `clippy`\n  --> tests/ui/cfg_attr_cargo_clippy.rs:8:16\n   |\nLL | #[cfg_attr(not(feature = \"cargo-clippy\"), derive(Debug))]\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`\n\nerror: `feature = \"cargo-clippy\"` was replaced by `clippy`\n  --> tests/ui/cfg_attr_cargo_clippy.rs:10:7\n   |\nLL | #[cfg(feature = \"cargo-clippy\")]\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`\n\nerror: `feature = \"cargo-clippy\"` was replaced by `clippy`\n  --> tests/ui/cfg_attr_cargo_clippy.rs:12:11\n   |\nLL | #[cfg(not(feature = \"cargo-clippy\"))]\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`\n\nerror: `feature = \"cargo-clippy\"` was replaced by `clippy`\n  --> tests/ui/cfg_attr_cargo_clippy.rs:14:11\n   |\nLL | #[cfg(any(feature = \"cargo-clippy\"))]\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`\n\nerror: `feature = \"cargo-clippy\"` was replaced by `clippy`\n  --> tests/ui/cfg_attr_cargo_clippy.rs:16:11\n   |\nLL | #[cfg(all(feature = \"cargo-clippy\"))]\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `clippy`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/cfg_attr_rustfmt.fixed",
    "content": "\n#![feature(stmt_expr_attributes)]\n\n#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]\n#![warn(clippy::deprecated_cfg_attr)]\n\n// This doesn't get linted, see known problems\n#![cfg_attr(rustfmt, rustfmt_skip)]\n\n#[rustfmt::skip]\ntrait Foo\n{\nfn foo(\n);\n}\n\nfn skip_on_statements() {\n    #[rustfmt::skip]\n    //~^ deprecated_cfg_attr\n    5+3;\n}\n\n#[rustfmt::skip]\n//~^ deprecated_cfg_attr\nfn main() {\n    foo::f();\n}\n\nmod foo {\n    #![cfg_attr(rustfmt, rustfmt_skip)]\n\n    pub fn f() {}\n}\n\n#[clippy::msrv = \"1.29\"]\nfn msrv_1_29() {\n    #[cfg_attr(rustfmt, rustfmt::skip)]\n    1+29;\n}\n\n#[clippy::msrv = \"1.30\"]\nfn msrv_1_30() {\n    #[rustfmt::skip]\n    //~^ deprecated_cfg_attr\n    1+30;\n}\n"
  },
  {
    "path": "tests/ui/cfg_attr_rustfmt.rs",
    "content": "\n#![feature(stmt_expr_attributes)]\n\n#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]\n#![warn(clippy::deprecated_cfg_attr)]\n\n// This doesn't get linted, see known problems\n#![cfg_attr(rustfmt, rustfmt_skip)]\n\n#[rustfmt::skip]\ntrait Foo\n{\nfn foo(\n);\n}\n\nfn skip_on_statements() {\n    #[cfg_attr(rustfmt, rustfmt::skip)]\n    //~^ deprecated_cfg_attr\n    5+3;\n}\n\n#[cfg_attr(rustfmt, rustfmt_skip)]\n//~^ deprecated_cfg_attr\nfn main() {\n    foo::f();\n}\n\nmod foo {\n    #![cfg_attr(rustfmt, rustfmt_skip)]\n\n    pub fn f() {}\n}\n\n#[clippy::msrv = \"1.29\"]\nfn msrv_1_29() {\n    #[cfg_attr(rustfmt, rustfmt::skip)]\n    1+29;\n}\n\n#[clippy::msrv = \"1.30\"]\nfn msrv_1_30() {\n    #[cfg_attr(rustfmt, rustfmt::skip)]\n    //~^ deprecated_cfg_attr\n    1+30;\n}\n"
  },
  {
    "path": "tests/ui/cfg_attr_rustfmt.stderr",
    "content": "error: `cfg_attr` is deprecated for rustfmt and got replaced by tool attributes\n  --> tests/ui/cfg_attr_rustfmt.rs:18:5\n   |\nLL |     #[cfg_attr(rustfmt, rustfmt::skip)]\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `#[rustfmt::skip]`\n   |\n   = note: `-D clippy::deprecated-cfg-attr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::deprecated_cfg_attr)]`\n\nerror: `cfg_attr` is deprecated for rustfmt and got replaced by tool attributes\n  --> tests/ui/cfg_attr_rustfmt.rs:23:1\n   |\nLL | #[cfg_attr(rustfmt, rustfmt_skip)]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `#[rustfmt::skip]`\n\nerror: `cfg_attr` is deprecated for rustfmt and got replaced by tool attributes\n  --> tests/ui/cfg_attr_rustfmt.rs:43:5\n   |\nLL |     #[cfg_attr(rustfmt, rustfmt::skip)]\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `#[rustfmt::skip]`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/cfg_not_test.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::cfg_not_test)]\n\nfn important_check() {}\n\nfn main() {\n    // Statement\n    #[cfg(not(test))]\n    //~^ cfg_not_test\n    let answer = 42;\n\n    // Expression\n    #[cfg(not(test))]\n    //~^ cfg_not_test\n    important_check();\n\n    // Make sure only not(test) are checked, not other attributes\n    #[cfg(not(foo))]\n    important_check();\n}\n\n#[cfg(not(not(test)))]\nstruct CfgNotTest;\n\n// Deeply nested `not(test)`\n#[cfg(not(test))]\n//~^ cfg_not_test\nfn foo() {}\n#[cfg(all(debug_assertions, not(test)))]\n//~^ cfg_not_test\nfn bar() {}\n#[cfg(not(any(not(debug_assertions), test)))]\n//~^ cfg_not_test\nfn baz() {}\n\n#[cfg(test)]\nmod tests {}\n"
  },
  {
    "path": "tests/ui/cfg_not_test.stderr",
    "content": "error: code is excluded from test builds\n  --> tests/ui/cfg_not_test.rs:8:5\n   |\nLL |     #[cfg(not(test))]\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider not excluding any code from test builds\n   = note: this could increase code coverage despite not actually being tested\n   = note: `-D clippy::cfg-not-test` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cfg_not_test)]`\n\nerror: code is excluded from test builds\n  --> tests/ui/cfg_not_test.rs:13:5\n   |\nLL |     #[cfg(not(test))]\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider not excluding any code from test builds\n\nerror: code is excluded from test builds\n  --> tests/ui/cfg_not_test.rs:26:1\n   |\nLL | #[cfg(not(test))]\n   | ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider not excluding any code from test builds\n\nerror: code is excluded from test builds\n  --> tests/ui/cfg_not_test.rs:29:1\n   |\nLL | #[cfg(all(debug_assertions, not(test)))]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider not excluding any code from test builds\n\nerror: code is excluded from test builds\n  --> tests/ui/cfg_not_test.rs:32:1\n   |\nLL | #[cfg(not(any(not(debug_assertions), test)))]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider not excluding any code from test builds\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/char_indices_as_byte_indices.fixed",
    "content": "#![warn(clippy::char_indices_as_byte_indices)]\n\ntrait StrExt {\n    fn use_index(&self, _: usize);\n}\nimpl StrExt for str {\n    fn use_index(&self, _: usize) {}\n}\n\nfn bad(prim: &str, string: String) {\n    for (idx, _) in prim.char_indices() {\n        let _ = prim[..idx];\n        //~^ char_indices_as_byte_indices\n        prim.split_at(idx);\n        //~^ char_indices_as_byte_indices\n\n        // This won't panic, but it can still return a wrong substring\n        let _ = prim[..prim.floor_char_boundary(idx)];\n        //~^ char_indices_as_byte_indices\n\n        // can't use #[expect] here because the .fixed file will still have the attribute and create an\n        // unfulfilled expectation, but make sure lint level attributes work on the use expression:\n        #[allow(clippy::char_indices_as_byte_indices)]\n        let _ = prim[..idx];\n    }\n\n    for c in prim.char_indices() {\n        let _ = prim[..c.0];\n        //~^ char_indices_as_byte_indices\n        prim.split_at(c.0);\n        //~^ char_indices_as_byte_indices\n    }\n\n    for (idx, _) in string.char_indices() {\n        let _ = string[..idx];\n        //~^ char_indices_as_byte_indices\n        string.split_at(idx);\n        //~^ char_indices_as_byte_indices\n    }\n}\n\nfn good(prim: &str, prim2: &str) {\n    for (idx, _) in prim.chars().enumerate() {\n        // Indexing into a different string\n        let _ = prim2[..idx];\n\n        // Unknown use\n        std::hint::black_box(idx);\n\n        // Method call to user defined extension trait\n        prim.use_index(idx);\n\n        // str method taking a usize that doesn't represent a byte index\n        prim.splitn(idx, prim2);\n    }\n\n    let mut string = \"äa\".to_owned();\n    for (idx, _) in string.clone().chars().enumerate() {\n        // Even though the receiver is the same expression, it should not be treated as the same value.\n        string.clone().remove(idx);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/char_indices_as_byte_indices.rs",
    "content": "#![warn(clippy::char_indices_as_byte_indices)]\n\ntrait StrExt {\n    fn use_index(&self, _: usize);\n}\nimpl StrExt for str {\n    fn use_index(&self, _: usize) {}\n}\n\nfn bad(prim: &str, string: String) {\n    for (idx, _) in prim.chars().enumerate() {\n        let _ = prim[..idx];\n        //~^ char_indices_as_byte_indices\n        prim.split_at(idx);\n        //~^ char_indices_as_byte_indices\n\n        // This won't panic, but it can still return a wrong substring\n        let _ = prim[..prim.floor_char_boundary(idx)];\n        //~^ char_indices_as_byte_indices\n\n        // can't use #[expect] here because the .fixed file will still have the attribute and create an\n        // unfulfilled expectation, but make sure lint level attributes work on the use expression:\n        #[allow(clippy::char_indices_as_byte_indices)]\n        let _ = prim[..idx];\n    }\n\n    for c in prim.chars().enumerate() {\n        let _ = prim[..c.0];\n        //~^ char_indices_as_byte_indices\n        prim.split_at(c.0);\n        //~^ char_indices_as_byte_indices\n    }\n\n    for (idx, _) in string.chars().enumerate() {\n        let _ = string[..idx];\n        //~^ char_indices_as_byte_indices\n        string.split_at(idx);\n        //~^ char_indices_as_byte_indices\n    }\n}\n\nfn good(prim: &str, prim2: &str) {\n    for (idx, _) in prim.chars().enumerate() {\n        // Indexing into a different string\n        let _ = prim2[..idx];\n\n        // Unknown use\n        std::hint::black_box(idx);\n\n        // Method call to user defined extension trait\n        prim.use_index(idx);\n\n        // str method taking a usize that doesn't represent a byte index\n        prim.splitn(idx, prim2);\n    }\n\n    let mut string = \"äa\".to_owned();\n    for (idx, _) in string.clone().chars().enumerate() {\n        // Even though the receiver is the same expression, it should not be treated as the same value.\n        string.clone().remove(idx);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/char_indices_as_byte_indices.stderr",
    "content": "error: indexing into a string with a character position where a byte index is expected\n  --> tests/ui/char_indices_as_byte_indices.rs:12:24\n   |\nLL |         let _ = prim[..idx];\n   |                        ^^^\n   |\n   = note: a character can take up more than one byte, so they are not interchangeable\nnote: position comes from the enumerate iterator\n  --> tests/ui/char_indices_as_byte_indices.rs:11:10\n   |\nLL |     for (idx, _) in prim.chars().enumerate() {\n   |          ^^^                     ^^^^^^^^^^^\n   = note: `-D clippy::char-indices-as-byte-indices` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::char_indices_as_byte_indices)]`\nhelp: consider using `.char_indices()` instead\n   |\nLL -     for (idx, _) in prim.chars().enumerate() {\nLL +     for (idx, _) in prim.char_indices() {\n   |\n\nerror: passing a character position to a method that expects a byte index\n  --> tests/ui/char_indices_as_byte_indices.rs:14:23\n   |\nLL |         prim.split_at(idx);\n   |                       ^^^\n   |\n   = note: a character can take up more than one byte, so they are not interchangeable\nnote: position comes from the enumerate iterator\n  --> tests/ui/char_indices_as_byte_indices.rs:11:10\n   |\nLL |     for (idx, _) in prim.chars().enumerate() {\n   |          ^^^                     ^^^^^^^^^^^\nhelp: consider using `.char_indices()` instead\n   |\nLL -     for (idx, _) in prim.chars().enumerate() {\nLL +     for (idx, _) in prim.char_indices() {\n   |\n\nerror: passing a character position to a method that expects a byte index\n  --> tests/ui/char_indices_as_byte_indices.rs:18:49\n   |\nLL |         let _ = prim[..prim.floor_char_boundary(idx)];\n   |                                                 ^^^\n   |\n   = note: a character can take up more than one byte, so they are not interchangeable\nnote: position comes from the enumerate iterator\n  --> tests/ui/char_indices_as_byte_indices.rs:11:10\n   |\nLL |     for (idx, _) in prim.chars().enumerate() {\n   |          ^^^                     ^^^^^^^^^^^\nhelp: consider using `.char_indices()` instead\n   |\nLL -     for (idx, _) in prim.chars().enumerate() {\nLL +     for (idx, _) in prim.char_indices() {\n   |\n\nerror: indexing into a string with a character position where a byte index is expected\n  --> tests/ui/char_indices_as_byte_indices.rs:28:24\n   |\nLL |         let _ = prim[..c.0];\n   |                        ^^^\n   |\n   = note: a character can take up more than one byte, so they are not interchangeable\nnote: position comes from the enumerate iterator\n  --> tests/ui/char_indices_as_byte_indices.rs:27:9\n   |\nLL |     for c in prim.chars().enumerate() {\n   |         ^                 ^^^^^^^^^^^\nhelp: consider using `.char_indices()` instead\n   |\nLL -     for c in prim.chars().enumerate() {\nLL +     for c in prim.char_indices() {\n   |\n\nerror: passing a character position to a method that expects a byte index\n  --> tests/ui/char_indices_as_byte_indices.rs:30:23\n   |\nLL |         prim.split_at(c.0);\n   |                       ^^^\n   |\n   = note: a character can take up more than one byte, so they are not interchangeable\nnote: position comes from the enumerate iterator\n  --> tests/ui/char_indices_as_byte_indices.rs:27:9\n   |\nLL |     for c in prim.chars().enumerate() {\n   |         ^                 ^^^^^^^^^^^\nhelp: consider using `.char_indices()` instead\n   |\nLL -     for c in prim.chars().enumerate() {\nLL +     for c in prim.char_indices() {\n   |\n\nerror: indexing into a string with a character position where a byte index is expected\n  --> tests/ui/char_indices_as_byte_indices.rs:35:26\n   |\nLL |         let _ = string[..idx];\n   |                          ^^^\n   |\n   = note: a character can take up more than one byte, so they are not interchangeable\nnote: position comes from the enumerate iterator\n  --> tests/ui/char_indices_as_byte_indices.rs:34:10\n   |\nLL |     for (idx, _) in string.chars().enumerate() {\n   |          ^^^                       ^^^^^^^^^^^\nhelp: consider using `.char_indices()` instead\n   |\nLL -     for (idx, _) in string.chars().enumerate() {\nLL +     for (idx, _) in string.char_indices() {\n   |\n\nerror: passing a character position to a method that expects a byte index\n  --> tests/ui/char_indices_as_byte_indices.rs:37:25\n   |\nLL |         string.split_at(idx);\n   |                         ^^^\n   |\n   = note: a character can take up more than one byte, so they are not interchangeable\nnote: position comes from the enumerate iterator\n  --> tests/ui/char_indices_as_byte_indices.rs:34:10\n   |\nLL |     for (idx, _) in string.chars().enumerate() {\n   |          ^^^                       ^^^^^^^^^^^\nhelp: consider using `.char_indices()` instead\n   |\nLL -     for (idx, _) in string.chars().enumerate() {\nLL +     for (idx, _) in string.char_indices() {\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/char_lit_as_u8.fixed",
    "content": "#![warn(clippy::char_lit_as_u8)]\n\nfn main() {\n    let _ = b'a';\n    //~^ char_lit_as_u8\n    let _ = b'\\n';\n    //~^ char_lit_as_u8\n    let _ = b'\\0';\n    //~^ char_lit_as_u8\n    let _ = b'\\x01';\n    //~^ char_lit_as_u8\n}\n"
  },
  {
    "path": "tests/ui/char_lit_as_u8.rs",
    "content": "#![warn(clippy::char_lit_as_u8)]\n\nfn main() {\n    let _ = 'a' as u8;\n    //~^ char_lit_as_u8\n    let _ = '\\n' as u8;\n    //~^ char_lit_as_u8\n    let _ = '\\0' as u8;\n    //~^ char_lit_as_u8\n    let _ = '\\x01' as u8;\n    //~^ char_lit_as_u8\n}\n"
  },
  {
    "path": "tests/ui/char_lit_as_u8.stderr",
    "content": "error: casting a character literal to `u8` truncates\n  --> tests/ui/char_lit_as_u8.rs:4:13\n   |\nLL |     let _ = 'a' as u8;\n   |             ^^^^^^^^^ help: use a byte literal instead: `b'a'`\n   |\n   = note: `char` is four bytes wide, but `u8` is a single byte\n   = note: `-D clippy::char-lit-as-u8` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::char_lit_as_u8)]`\n\nerror: casting a character literal to `u8` truncates\n  --> tests/ui/char_lit_as_u8.rs:6:13\n   |\nLL |     let _ = '\\n' as u8;\n   |             ^^^^^^^^^^ help: use a byte literal instead: `b'\\n'`\n   |\n   = note: `char` is four bytes wide, but `u8` is a single byte\n\nerror: casting a character literal to `u8` truncates\n  --> tests/ui/char_lit_as_u8.rs:8:13\n   |\nLL |     let _ = '\\0' as u8;\n   |             ^^^^^^^^^^ help: use a byte literal instead: `b'\\0'`\n   |\n   = note: `char` is four bytes wide, but `u8` is a single byte\n\nerror: casting a character literal to `u8` truncates\n  --> tests/ui/char_lit_as_u8.rs:10:13\n   |\nLL |     let _ = '\\x01' as u8;\n   |             ^^^^^^^^^^^^ help: use a byte literal instead: `b'\\x01'`\n   |\n   = note: `char` is four bytes wide, but `u8` is a single byte\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/char_lit_as_u8_unfixable.rs",
    "content": "#![warn(clippy::char_lit_as_u8)]\n\nfn main() {\n    // no suggestion, since a byte literal won't work.\n    let _ = '❤' as u8;\n    //~^ char_lit_as_u8\n}\n"
  },
  {
    "path": "tests/ui/char_lit_as_u8_unfixable.stderr",
    "content": "error: casting a character literal to `u8` truncates\n  --> tests/ui/char_lit_as_u8_unfixable.rs:5:13\n   |\nLL |     let _ = '❤' as u8;\n   |             ^^^^^^^^^\n   |\n   = note: `char` is four bytes wide, but `u8` is a single byte\n   = note: `-D clippy::char-lit-as-u8` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::char_lit_as_u8)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/checked_conversions.fixed",
    "content": "#![allow(\n    clippy::cast_lossless,\n    clippy::legacy_numeric_constants,\n    clippy::no_effect,\n    unused,\n    // Int::max_value will be deprecated in the future\n    deprecated,\n)]\n#![warn(clippy::checked_conversions)]\n\n// Positive tests\n\n// Signed to unsigned\n\npub fn i64_to_u32(value: i64) {\n    let _ = u32::try_from(value).is_ok();\n    //~^ checked_conversions\n    let _ = u32::try_from(value).is_ok();\n    //~^ checked_conversions\n}\n\npub fn i64_to_u16(value: i64) {\n    let _ = u16::try_from(value).is_ok();\n    //~^ checked_conversions\n    let _ = u16::try_from(value).is_ok();\n    //~^ checked_conversions\n}\n\npub fn isize_to_u8(value: isize) {\n    let _ = u8::try_from(value).is_ok();\n    //~^ checked_conversions\n    let _ = u8::try_from(value).is_ok();\n    //~^ checked_conversions\n}\n\n// Signed to signed\n\npub fn i64_to_i32(value: i64) {\n    let _ = i32::try_from(value).is_ok();\n    //~^ checked_conversions\n    let _ = i32::try_from(value).is_ok();\n    //~^ checked_conversions\n}\n\npub fn i64_to_i16(value: i64) {\n    let _ = i16::try_from(value).is_ok();\n    //~^ checked_conversions\n    let _ = i16::try_from(value).is_ok();\n    //~^ checked_conversions\n}\n\n// Unsigned to X\n\npub fn u32_to_i32(value: u32) {\n    let _ = i32::try_from(value).is_ok();\n    //~^ checked_conversions\n    let _ = i32::try_from(value).is_ok();\n    //~^ checked_conversions\n}\n\npub fn usize_to_isize(value: usize) {\n    let _ = isize::try_from(value).is_ok() && value as i32 == 5;\n    //~^ checked_conversions\n    let _ = isize::try_from(value).is_ok() && value as i32 == 5;\n    //~^ checked_conversions\n}\n\npub fn u32_to_u16(value: u32) {\n    let _ = u16::try_from(value).is_ok() && value as i32 == 5;\n    //~^ checked_conversions\n    let _ = u16::try_from(value).is_ok() && value as i32 == 5;\n    //~^ checked_conversions\n}\n\n// Negative tests\n\npub fn no_i64_to_i32(value: i64) {\n    let _ = value <= (i32::max_value() as i64) && value >= 0;\n    let _ = value <= (i32::MAX as i64) && value >= 0;\n}\n\npub fn no_isize_to_u8(value: isize) {\n    let _ = value <= (u8::max_value() as isize) && value >= (u8::min_value() as isize);\n    let _ = value <= (u8::MAX as isize) && value >= (u8::MIN as isize);\n}\n\npub fn i8_to_u8(value: i8) {\n    let _ = value >= 0;\n}\n\n// Do not lint\npub const fn issue_8898(i: u32) -> bool {\n    i <= i32::MAX as u32\n}\n\n#[clippy::msrv = \"1.33\"]\nfn msrv_1_33() {\n    let value: i64 = 33;\n    let _ = value <= (u32::max_value() as i64) && value >= 0;\n}\n\n#[clippy::msrv = \"1.34\"]\nfn msrv_1_34() {\n    let value: i64 = 34;\n    let _ = u32::try_from(value).is_ok();\n    //~^ checked_conversions\n}\n\nfn issue16293() {\n    struct Outer {\n        inner: u32,\n    }\n    let outer = Outer { inner: 42 };\n    macro_rules! dot_inner {\n        ($obj:expr) => {\n            $obj.inner\n        };\n    }\n\n    i32::try_from(dot_inner!(outer)).is_ok();\n    //~^ checked_conversions\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/checked_conversions.rs",
    "content": "#![allow(\n    clippy::cast_lossless,\n    clippy::legacy_numeric_constants,\n    clippy::no_effect,\n    unused,\n    // Int::max_value will be deprecated in the future\n    deprecated,\n)]\n#![warn(clippy::checked_conversions)]\n\n// Positive tests\n\n// Signed to unsigned\n\npub fn i64_to_u32(value: i64) {\n    let _ = value <= (u32::max_value() as i64) && value >= 0;\n    //~^ checked_conversions\n    let _ = value <= (u32::MAX as i64) && value >= 0;\n    //~^ checked_conversions\n}\n\npub fn i64_to_u16(value: i64) {\n    let _ = value <= i64::from(u16::max_value()) && value >= 0;\n    //~^ checked_conversions\n    let _ = value <= i64::from(u16::MAX) && value >= 0;\n    //~^ checked_conversions\n}\n\npub fn isize_to_u8(value: isize) {\n    let _ = value <= (u8::max_value() as isize) && value >= 0;\n    //~^ checked_conversions\n    let _ = value <= (u8::MAX as isize) && value >= 0;\n    //~^ checked_conversions\n}\n\n// Signed to signed\n\npub fn i64_to_i32(value: i64) {\n    let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64);\n    //~^ checked_conversions\n    let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64);\n    //~^ checked_conversions\n}\n\npub fn i64_to_i16(value: i64) {\n    let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value());\n    //~^ checked_conversions\n    let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN);\n    //~^ checked_conversions\n}\n\n// Unsigned to X\n\npub fn u32_to_i32(value: u32) {\n    let _ = value <= i32::max_value() as u32;\n    //~^ checked_conversions\n    let _ = value <= i32::MAX as u32;\n    //~^ checked_conversions\n}\n\npub fn usize_to_isize(value: usize) {\n    let _ = value <= isize::max_value() as usize && value as i32 == 5;\n    //~^ checked_conversions\n    let _ = value <= isize::MAX as usize && value as i32 == 5;\n    //~^ checked_conversions\n}\n\npub fn u32_to_u16(value: u32) {\n    let _ = value <= u16::max_value() as u32 && value as i32 == 5;\n    //~^ checked_conversions\n    let _ = value <= u16::MAX as u32 && value as i32 == 5;\n    //~^ checked_conversions\n}\n\n// Negative tests\n\npub fn no_i64_to_i32(value: i64) {\n    let _ = value <= (i32::max_value() as i64) && value >= 0;\n    let _ = value <= (i32::MAX as i64) && value >= 0;\n}\n\npub fn no_isize_to_u8(value: isize) {\n    let _ = value <= (u8::max_value() as isize) && value >= (u8::min_value() as isize);\n    let _ = value <= (u8::MAX as isize) && value >= (u8::MIN as isize);\n}\n\npub fn i8_to_u8(value: i8) {\n    let _ = value >= 0;\n}\n\n// Do not lint\npub const fn issue_8898(i: u32) -> bool {\n    i <= i32::MAX as u32\n}\n\n#[clippy::msrv = \"1.33\"]\nfn msrv_1_33() {\n    let value: i64 = 33;\n    let _ = value <= (u32::max_value() as i64) && value >= 0;\n}\n\n#[clippy::msrv = \"1.34\"]\nfn msrv_1_34() {\n    let value: i64 = 34;\n    let _ = value <= (u32::max_value() as i64) && value >= 0;\n    //~^ checked_conversions\n}\n\nfn issue16293() {\n    struct Outer {\n        inner: u32,\n    }\n    let outer = Outer { inner: 42 };\n    macro_rules! dot_inner {\n        ($obj:expr) => {\n            $obj.inner\n        };\n    }\n\n    dot_inner!(outer) <= i32::MAX as u32;\n    //~^ checked_conversions\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/checked_conversions.stderr",
    "content": "error: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:16:13\n   |\nLL |     let _ = value <= (u32::max_value() as i64) && value >= 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`\n   |\n   = note: `-D clippy::checked-conversions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::checked_conversions)]`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:18:13\n   |\nLL |     let _ = value <= (u32::MAX as i64) && value >= 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:23:13\n   |\nLL |     let _ = value <= i64::from(u16::max_value()) && value >= 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:25:13\n   |\nLL |     let _ = value <= i64::from(u16::MAX) && value >= 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:30:13\n   |\nLL |     let _ = value <= (u8::max_value() as isize) && value >= 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:32:13\n   |\nLL |     let _ = value <= (u8::MAX as isize) && value >= 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:39:13\n   |\nLL |     let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:41:13\n   |\nLL |     let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:46:13\n   |\nLL |     let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:48:13\n   |\nLL |     let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:55:13\n   |\nLL |     let _ = value <= i32::max_value() as u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:57:13\n   |\nLL |     let _ = value <= i32::MAX as u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:62:13\n   |\nLL |     let _ = value <= isize::max_value() as usize && value as i32 == 5;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:64:13\n   |\nLL |     let _ = value <= isize::MAX as usize && value as i32 == 5;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:69:13\n   |\nLL |     let _ = value <= u16::max_value() as u32 && value as i32 == 5;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:71:13\n   |\nLL |     let _ = value <= u16::MAX as u32 && value as i32 == 5;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:105:13\n   |\nLL |     let _ = value <= (u32::max_value() as i64) && value >= 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`\n\nerror: checked cast can be simplified\n  --> tests/ui/checked_conversions.rs:120:5\n   |\nLL |     dot_inner!(outer) <= i32::MAX as u32;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(dot_inner!(outer)).is_ok()`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/checked_unwrap/complex_conditionals.rs",
    "content": "#![warn(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]\n#![expect(clippy::branches_sharing_code, clippy::unnecessary_literal_unwrap)]\n\nfn test_complex_conditions() {\n    let x: Result<(), ()> = Ok(());\n    let y: Result<(), ()> = Ok(());\n    if x.is_ok() && y.is_err() {\n        x.unwrap();\n        //~^ unnecessary_unwrap\n\n        x.unwrap_err();\n        //~^ panicking_unwrap\n\n        y.unwrap();\n        //~^ panicking_unwrap\n\n        y.unwrap_err();\n        //~^ unnecessary_unwrap\n    } else {\n        // not statically determinable whether any of the following will always succeed or always fail:\n        x.unwrap();\n        x.unwrap_err();\n        y.unwrap();\n        y.unwrap_err();\n    }\n\n    if x.is_ok() || y.is_ok() {\n        // not statically determinable whether any of the following will always succeed or always fail:\n        x.unwrap();\n        y.unwrap();\n    } else {\n        x.unwrap();\n        //~^ panicking_unwrap\n\n        x.unwrap_err();\n        //~^ unnecessary_unwrap\n\n        y.unwrap();\n        //~^ panicking_unwrap\n\n        y.unwrap_err();\n        //~^ unnecessary_unwrap\n    }\n    let z: Result<(), ()> = Ok(());\n    if x.is_ok() && !(y.is_ok() || z.is_err()) {\n        x.unwrap();\n        //~^ unnecessary_unwrap\n\n        x.unwrap_err();\n        //~^ panicking_unwrap\n\n        y.unwrap();\n        //~^ panicking_unwrap\n\n        y.unwrap_err();\n        //~^ unnecessary_unwrap\n\n        z.unwrap();\n        //~^ unnecessary_unwrap\n\n        z.unwrap_err();\n        //~^ panicking_unwrap\n    }\n    if x.is_ok() || !(y.is_ok() && z.is_err()) {\n        // not statically determinable whether any of the following will always succeed or always fail:\n        x.unwrap();\n        y.unwrap();\n        z.unwrap();\n    } else {\n        x.unwrap();\n        //~^ panicking_unwrap\n\n        x.unwrap_err();\n        //~^ unnecessary_unwrap\n\n        y.unwrap();\n        //~^ unnecessary_unwrap\n\n        y.unwrap_err();\n        //~^ panicking_unwrap\n\n        z.unwrap();\n        //~^ panicking_unwrap\n\n        z.unwrap_err();\n        //~^ unnecessary_unwrap\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/checked_unwrap/complex_conditionals.stderr",
    "content": "error: called `unwrap` on `x` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:8:9\n   |\nLL |     if x.is_ok() && y.is_err() {\n   |        --------- the check is happening here\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n   = note: `-D clippy::unnecessary-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]`\n\nerror: this call to `unwrap_err()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:11:9\n   |\nLL |     if x.is_ok() && y.is_err() {\n   |        --------- because of this check\n...\nLL |         x.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::panicking-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::panicking_unwrap)]`\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:14:9\n   |\nLL |     if x.is_ok() && y.is_err() {\n   |                     ---------- because of this check\n...\nLL |         y.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap_err` on `y` after checking its variant with `is_err`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:17:9\n   |\nLL |     if x.is_ok() && y.is_err() {\n   |                     ---------- the check is happening here\n...\nLL |         y.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:32:9\n   |\nLL |     if x.is_ok() || y.is_ok() {\n   |        --------- because of this check\n...\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap_err` on `x` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:35:9\n   |\nLL |     if x.is_ok() || y.is_ok() {\n   |        --------- the check is happening here\n...\nLL |         x.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:38:9\n   |\nLL |     if x.is_ok() || y.is_ok() {\n   |                     --------- because of this check\n...\nLL |         y.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap_err` on `y` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:41:9\n   |\nLL |     if x.is_ok() || y.is_ok() {\n   |                     --------- the check is happening here\n...\nLL |         y.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: called `unwrap` on `x` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:46:9\n   |\nLL |     if x.is_ok() && !(y.is_ok() || z.is_err()) {\n   |        --------- the check is happening here\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: this call to `unwrap_err()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:49:9\n   |\nLL |     if x.is_ok() && !(y.is_ok() || z.is_err()) {\n   |        --------- because of this check\n...\nLL |         x.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:52:9\n   |\nLL |     if x.is_ok() && !(y.is_ok() || z.is_err()) {\n   |                       --------- because of this check\n...\nLL |         y.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap_err` on `y` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:55:9\n   |\nLL |     if x.is_ok() && !(y.is_ok() || z.is_err()) {\n   |                       --------- the check is happening here\n...\nLL |         y.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: called `unwrap` on `z` after checking its variant with `is_err`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:58:9\n   |\nLL |     if x.is_ok() && !(y.is_ok() || z.is_err()) {\n   |                                    ---------- the check is happening here\n...\nLL |         z.unwrap();\n   |         ^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: this call to `unwrap_err()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:61:9\n   |\nLL |     if x.is_ok() && !(y.is_ok() || z.is_err()) {\n   |                                    ---------- because of this check\n...\nLL |         z.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:70:9\n   |\nLL |     if x.is_ok() || !(y.is_ok() && z.is_err()) {\n   |        --------- because of this check\n...\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap_err` on `x` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:73:9\n   |\nLL |     if x.is_ok() || !(y.is_ok() && z.is_err()) {\n   |        --------- the check is happening here\n...\nLL |         x.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: called `unwrap` on `y` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:76:9\n   |\nLL |     if x.is_ok() || !(y.is_ok() && z.is_err()) {\n   |                       --------- the check is happening here\n...\nLL |         y.unwrap();\n   |         ^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: this call to `unwrap_err()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:79:9\n   |\nLL |     if x.is_ok() || !(y.is_ok() && z.is_err()) {\n   |                       --------- because of this check\n...\nLL |         y.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:82:9\n   |\nLL |     if x.is_ok() || !(y.is_ok() && z.is_err()) {\n   |                                    ---------- because of this check\n...\nLL |         z.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap_err` on `z` after checking its variant with `is_err`\n  --> tests/ui/checked_unwrap/complex_conditionals.rs:85:9\n   |\nLL |     if x.is_ok() || !(y.is_ok() && z.is_err()) {\n   |                                    ---------- the check is happening here\n...\nLL |         z.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/checked_unwrap/complex_conditionals_nested.rs",
    "content": "//@no-rustfix: has placeholders\n#![warn(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]\n#![expect(clippy::branches_sharing_code, clippy::unnecessary_literal_unwrap)]\n\nfn test_nested() {\n    fn nested() {\n        let x = Some(());\n        if x.is_some() {\n            x.unwrap();\n            //~^ unnecessary_unwrap\n        } else {\n            x.unwrap();\n            //~^ panicking_unwrap\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/checked_unwrap/complex_conditionals_nested.stderr",
    "content": "error: called `unwrap` on `x` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:9:13\n   |\nLL |         if x.is_some() {\n   |         -------------- help: try: `if let Some(<item>) = x`\nLL |             x.unwrap();\n   |             ^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]`\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:12:13\n   |\nLL |         if x.is_some() {\n   |            ----------- because of this check\n...\nLL |             x.unwrap();\n   |             ^^^^^^^^^^\n   |\n   = note: `-D clippy::panicking-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::panicking_unwrap)]`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/checked_unwrap/if_let_chains.rs",
    "content": "//@require-annotations-for-level: ERROR\n#![warn(clippy::unnecessary_unwrap)]\n\n#[clippy::msrv = \"1.85\"]\nfn if_let_chains_unsupported(a: Option<u32>, b: Option<u32>) {\n    if a.is_none() || b.is_none() {\n        println!(\"a or b is not set\");\n    } else {\n        println!(\"the value of a is {}\", a.unwrap());\n        //~^ unnecessary_unwrap\n        //~| HELP: try using `match`\n    }\n}\n\n#[clippy::msrv = \"1.88\"]\nfn if_let_chains_supported(a: Option<u32>, b: Option<u32>) {\n    if a.is_none() || b.is_none() {\n        println!(\"a or b is not set\");\n    } else {\n        println!(\"the value of a is {}\", a.unwrap());\n        //~^ unnecessary_unwrap\n        //~| HELP: try using `if let` or `match`\n    }\n}\n"
  },
  {
    "path": "tests/ui/checked_unwrap/if_let_chains.stderr",
    "content": "error: called `unwrap` on `a` after checking its variant with `is_none`\n  --> tests/ui/checked_unwrap/if_let_chains.rs:9:42\n   |\nLL |     if a.is_none() || b.is_none() {\n   |        ----------- the check is happening here\n...\nLL |         println!(\"the value of a is {}\", a.unwrap());\n   |                                          ^^^^^^^^^^\n   |\n   = help: try using `match`\n   = note: `-D clippy::unnecessary-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]`\n\nerror: called `unwrap` on `a` after checking its variant with `is_none`\n  --> tests/ui/checked_unwrap/if_let_chains.rs:20:42\n   |\nLL |     if a.is_none() || b.is_none() {\n   |        ----------- the check is happening here\n...\nLL |         println!(\"the value of a is {}\", a.unwrap());\n   |                                          ^^^^^^^^^^\n   |\n   = help: try using `if let` or `match`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/checked_unwrap/simple_conditionals.rs",
    "content": "//@no-rustfix: has placeholders\n#![warn(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]\n#![expect(\n    clippy::if_same_then_else,\n    clippy::branches_sharing_code,\n    clippy::unnecessary_literal_unwrap,\n    clippy::self_assignment\n)]\n\nmacro_rules! m {\n    ($a:expr) => {\n        if $a.is_some() {\n            $a.unwrap();\n            //~^ unnecessary_unwrap\n        }\n    };\n}\n\nmacro_rules! checks_in_param {\n    ($a:expr, $b:expr) => {\n        if $a {\n            $b;\n        }\n    };\n}\n\nmacro_rules! checks_unwrap {\n    ($a:expr, $b:expr) => {\n        if $a.is_some() {\n            $b;\n        }\n    };\n}\n\nmacro_rules! checks_some {\n    ($a:expr, $b:expr) => {\n        if $a {\n            $b.unwrap();\n        }\n    };\n}\n\nfn main() {\n    let x = Some(());\n    if x.is_some() {\n        x.unwrap();\n        //~^ unnecessary_unwrap\n\n        x.expect(\"an error message\");\n        //~^ unnecessary_unwrap\n    } else {\n        x.unwrap();\n        //~^ panicking_unwrap\n\n        x.expect(\"an error message\");\n        //~^ panicking_unwrap\n    }\n    if x.is_none() {\n        x.unwrap();\n        //~^ panicking_unwrap\n    } else {\n        x.unwrap();\n        //~^ unnecessary_unwrap\n    }\n    m!(x);\n    checks_in_param!(x.is_some(), x.unwrap());\n    checks_unwrap!(x, x.unwrap());\n    checks_some!(x.is_some(), x);\n    let mut x: Result<(), ()> = Ok(());\n    if x.is_ok() {\n        x.unwrap();\n        //~^ unnecessary_unwrap\n\n        x.expect(\"an error message\");\n        //~^ unnecessary_unwrap\n\n        x.unwrap_err();\n        //~^ panicking_unwrap\n    } else {\n        x.unwrap();\n        //~^ panicking_unwrap\n\n        x.expect(\"an error message\");\n        //~^ panicking_unwrap\n\n        x.unwrap_err();\n        //~^ unnecessary_unwrap\n    }\n    if x.is_err() {\n        x.unwrap();\n        //~^ panicking_unwrap\n\n        x.unwrap_err();\n        //~^ unnecessary_unwrap\n    } else {\n        x.unwrap();\n        //~^ unnecessary_unwrap\n\n        x.unwrap_err();\n        //~^ panicking_unwrap\n    }\n    if x.is_ok() {\n        x = Err(());\n        // not unnecessary because of mutation of `x`\n        // it will always panic but the lint is not smart enough to see this (it only\n        // checks if conditions).\n        x.unwrap();\n    } else {\n        x = Ok(());\n        // not unnecessary because of mutation of `x`\n        // it will always panic but the lint is not smart enough to see this (it\n        // only checks if conditions).\n        x.unwrap_err();\n    }\n\n    // ok, it's a common test pattern\n    assert!(x.is_ok(), \"{:?}\", x.unwrap_err());\n}\n\nfn issue11371() {\n    let option = Some(());\n\n    if option.is_some() {\n        option.as_ref().unwrap();\n        //~^ unnecessary_unwrap\n    } else {\n        option.as_ref().unwrap();\n        //~^ panicking_unwrap\n    }\n\n    let result = Ok::<(), ()>(());\n\n    if result.is_ok() {\n        result.as_ref().unwrap();\n        //~^ unnecessary_unwrap\n    } else {\n        result.as_ref().unwrap();\n        //~^ panicking_unwrap\n    }\n\n    let mut option = Some(());\n    if option.is_some() {\n        option.as_mut().unwrap();\n        //~^ unnecessary_unwrap\n    } else {\n        option.as_mut().unwrap();\n        //~^ panicking_unwrap\n    }\n\n    let mut result = Ok::<(), ()>(());\n    if result.is_ok() {\n        result.as_mut().unwrap();\n        //~^ unnecessary_unwrap\n    } else {\n        result.as_mut().unwrap();\n        //~^ panicking_unwrap\n    }\n\n    // This should not lint and suggest `if let Some(..) = X {}`, as `X` is being mutated\n    static mut X: Option<i32> = Some(123);\n    unsafe {\n        #[expect(static_mut_refs)]\n        if X.is_some() {\n            X = None;\n            X.unwrap();\n        }\n    }\n}\n\nfn gen_option() -> Option<()> {\n    Some(())\n    // Or None\n}\n\nfn gen_result() -> Result<(), ()> {\n    Ok(())\n    // Or Err(())\n}\n\nfn issue14725() {\n    let option = Some(());\n\n    if option.is_some() {\n        let _ = option.as_ref().unwrap();\n        //~^ unnecessary_unwrap\n    } else {\n        let _ = option.as_ref().unwrap();\n        //~^ panicking_unwrap\n    }\n\n    let result = Ok::<(), ()>(());\n\n    if result.is_ok() {\n        let _y = 1;\n        result.as_ref().unwrap();\n        //~^ unnecessary_unwrap\n    } else {\n        let _y = 1;\n        result.as_ref().unwrap();\n        //~^ panicking_unwrap\n    }\n\n    let mut option = Some(());\n    if option.is_some() {\n        option = gen_option();\n        option.as_mut().unwrap();\n    } else {\n        option = gen_option();\n        option.as_mut().unwrap();\n    }\n\n    let mut result = Ok::<(), ()>(());\n    if result.is_ok() {\n        result = gen_result();\n        result.as_mut().unwrap();\n    } else {\n        result = gen_result();\n        result.as_mut().unwrap();\n    }\n}\n\nfn issue14763(x: Option<String>, r: Result<(), ()>) {\n    _ = || {\n        if x.is_some() {\n            _ = x.unwrap();\n            //~^ unnecessary_unwrap\n        } else {\n            _ = x.unwrap();\n            //~^ panicking_unwrap\n        }\n    };\n    _ = || {\n        if r.is_ok() {\n            _ = r.as_ref().unwrap();\n            //~^ unnecessary_unwrap\n        } else {\n            _ = r.as_ref().unwrap();\n            //~^ panicking_unwrap\n        }\n    };\n}\n\nconst ISSUE14763: fn(Option<String>) = |x| {\n    _ = || {\n        if x.is_some() {\n            _ = x.unwrap();\n            //~^ unnecessary_unwrap\n        } else {\n            _ = x.unwrap();\n            //~^ panicking_unwrap\n        }\n    }\n};\n\nfn issue12295() {\n    let option = Some(());\n\n    if option.is_some() {\n        println!(\"{:?}\", option.unwrap());\n        //~^ unnecessary_unwrap\n    } else {\n        println!(\"{:?}\", option.unwrap());\n        //~^ panicking_unwrap\n    }\n\n    let result = Ok::<(), ()>(());\n\n    if result.is_ok() {\n        println!(\"{:?}\", result.unwrap());\n        //~^ unnecessary_unwrap\n    } else {\n        println!(\"{:?}\", result.unwrap());\n        //~^ panicking_unwrap\n    }\n}\n\nfn check_expect() {\n    let x = Some(());\n    if x.is_some() {\n        #[expect(clippy::unnecessary_unwrap)]\n        x.unwrap();\n        #[expect(clippy::unnecessary_unwrap)]\n        x.expect(\"an error message\");\n    } else {\n        #[expect(clippy::panicking_unwrap)]\n        x.unwrap();\n        #[expect(clippy::panicking_unwrap)]\n        x.expect(\"an error message\");\n    }\n}\n\nfn partial_moves() {\n    fn borrow_option(_: &Option<()>) {}\n\n    let x = Some(());\n    // Using `if let Some(o) = x` won't work here, as `borrow_option` will try to borrow a moved value\n    if x.is_some() {\n        borrow_option(&x);\n        x.unwrap();\n        //~^ unnecessary_unwrap\n    }\n    // This is fine though, as `if let Some(o) = &x` won't move `x`\n    if x.is_some() {\n        borrow_option(&x);\n        x.as_ref().unwrap();\n        //~^ unnecessary_unwrap\n    }\n}\n\nfn issue15321() {\n    struct Soption {\n        option: Option<bool>,\n        other: bool,\n    }\n    let mut sopt = Soption {\n        option: Some(true),\n        other: true,\n    };\n    // Lint: nothing was mutated\n    let _res = if sopt.option.is_some() {\n        sopt.option.unwrap()\n        //~^ unnecessary_unwrap\n    } else {\n        sopt.option.unwrap()\n        //~^ panicking_unwrap\n    };\n    // Lint: an unrelated field was mutated\n    let _res = if sopt.option.is_some() {\n        sopt.other = false;\n        sopt.option.unwrap()\n        //~^ unnecessary_unwrap\n    } else {\n        sopt.other = false;\n        sopt.option.unwrap()\n        //~^ panicking_unwrap\n    };\n    // No lint: the whole local was mutated\n    let _res = if sopt.option.is_some() {\n        sopt = sopt;\n        sopt.option.unwrap()\n    } else {\n        sopt.option = None;\n        sopt.option.unwrap()\n    };\n    // No lint: the field we're looking at was mutated\n    let _res = if sopt.option.is_some() {\n        sopt = sopt;\n        sopt.option.unwrap()\n    } else {\n        sopt.option = None;\n        sopt.option.unwrap()\n    };\n\n    struct Toption(Option<bool>, bool);\n    let mut topt = Toption(Some(true), true);\n    // Lint: nothing was mutated\n    let _res = if topt.0.is_some() {\n        topt.0.unwrap()\n        //~^ unnecessary_unwrap\n    } else {\n        topt.0.unwrap()\n        //~^ panicking_unwrap\n    };\n    // Lint: an unrelated field was mutated\n    let _res = if topt.0.is_some() {\n        topt.1 = false;\n        topt.0.unwrap()\n        //~^ unnecessary_unwrap\n    } else {\n        topt.1 = false;\n        topt.0.unwrap()\n        //~^ panicking_unwrap\n    };\n    // No lint: the whole local was mutated\n    let _res = if topt.0.is_some() {\n        topt = topt;\n        topt.0.unwrap()\n    } else {\n        topt = topt;\n        topt.0.unwrap()\n    };\n    // No lint: the field we're looking at was mutated\n    let _res = if topt.0.is_some() {\n        topt.0 = None;\n        topt.0.unwrap()\n    } else {\n        topt.0 = None;\n        topt.0.unwrap()\n    };\n\n    // Nested field accesses get linted as well\n    struct Soption2 {\n        other: bool,\n        option: Soption,\n    }\n    let mut sopt2 = Soption2 {\n        other: true,\n        option: Soption {\n            option: Some(true),\n            other: true,\n        },\n    };\n    // Lint: no fields were mutated\n    let _res = if sopt2.option.option.is_some() {\n        sopt2.option.option.unwrap()\n        //~^ unnecessary_unwrap\n    } else {\n        sopt2.option.option.unwrap()\n        //~^ panicking_unwrap\n    };\n    // Lint: an unrelated outer field was mutated -- don't get confused by `Soption2.other` having the\n    // same `FieldIdx` of 1 as `Soption.option`\n    let _res = if sopt2.option.option.is_some() {\n        sopt2.other = false;\n        sopt2.option.option.unwrap()\n        //~^ unnecessary_unwrap\n    } else {\n        sopt2.other = false;\n        sopt2.option.option.unwrap()\n        //~^ panicking_unwrap\n    };\n    // Lint: an unrelated inner field was mutated\n    let _res = if sopt2.option.option.is_some() {\n        sopt2.option.other = false;\n        sopt2.option.option.unwrap()\n        //~^ unnecessary_unwrap\n    } else {\n        sopt2.option.other = false;\n        sopt2.option.option.unwrap()\n        //~^ panicking_unwrap\n    };\n    // Don't lint: the whole local was mutated\n    let _res = if sopt2.option.option.is_some() {\n        sopt2 = sopt2;\n        sopt2.option.option.unwrap()\n    } else {\n        sopt2 = sopt2;\n        sopt2.option.option.unwrap()\n    };\n    // Don't lint: a parent field of the field we're looking at was mutated, and with that the\n    // field we're looking at\n    let _res = if sopt2.option.option.is_some() {\n        sopt2.option = sopt;\n        sopt2.option.option.unwrap()\n    } else {\n        sopt2.option = sopt;\n        sopt2.option.option.unwrap()\n    };\n    // Don't lint: the field we're looking at was mutated directly\n    let _res = if sopt2.option.option.is_some() {\n        sopt2.option.option = None;\n        sopt2.option.option.unwrap()\n    } else {\n        sopt2.option.option = None;\n        sopt2.option.option.unwrap()\n    };\n\n    // Partial moves\n    fn borrow_toption(_: &Toption) {}\n\n    // Using `if let Some(o) = topt.0` won't work here, as `borrow_toption` will try to borrow a\n    // partially moved value\n    if topt.0.is_some() {\n        borrow_toption(&topt);\n        topt.0.unwrap();\n        //~^ unnecessary_unwrap\n    }\n    // This is fine though, as `if let Some(o) = &topt.0` won't (partially) move `topt`\n    if topt.0.is_some() {\n        borrow_toption(&topt);\n        topt.0.as_ref().unwrap();\n        //~^ unnecessary_unwrap\n    }\n}\n\nmod issue16188 {\n    struct Foo {\n        value: Option<i32>,\n    }\n\n    impl Foo {\n        pub fn bar(&mut self) {\n            let print_value = |v: i32| {\n                println!(\"{}\", v);\n            };\n\n            if self.value.is_none() {\n                self.value = Some(10);\n                print_value(self.value.unwrap());\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/checked_unwrap/simple_conditionals.stderr",
    "content": "error: called `unwrap` on `x` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:46:9\n   |\nLL |     if x.is_some() {\n   |     -------------- help: try: `if let Some(<item>) = x`\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]`\n\nerror: called `expect` on `x` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:49:9\n   |\nLL |     if x.is_some() {\n   |     -------------- help: try: `if let Some(<item>) = x`\n...\nLL |         x.expect(\"an error message\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:52:9\n   |\nLL |     if x.is_some() {\n   |        ----------- because of this check\n...\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n   |\n   = note: `-D clippy::panicking-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::panicking_unwrap)]`\n\nerror: this call to `expect()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:55:9\n   |\nLL |     if x.is_some() {\n   |        ----------- because of this check\n...\nLL |         x.expect(\"an error message\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:59:9\n   |\nLL |     if x.is_none() {\n   |        ----------- because of this check\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap` on `x` after checking its variant with `is_none`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:62:9\n   |\nLL |     if x.is_none() {\n   |     -------------- help: try: `if let Some(<item>) = x`\n...\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap` on `x` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:13:13\n   |\nLL |         if $a.is_some() {\n   |         --------------- help: try: `if let Some(<item>) = x`\nLL |             $a.unwrap();\n   |             ^^^^^^^^^^^\n...\nLL |     m!(x);\n   |     ----- in this macro invocation\n   |\n   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: called `unwrap` on `x` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:71:9\n   |\nLL |     if x.is_ok() {\n   |     ------------ help: try: `if let Ok(<item>) = x`\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `expect` on `x` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:74:9\n   |\nLL |     if x.is_ok() {\n   |     ------------ help: try: `if let Ok(<item>) = x`\n...\nLL |         x.expect(\"an error message\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap_err()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:77:9\n   |\nLL |     if x.is_ok() {\n   |        --------- because of this check\n...\nLL |         x.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:80:9\n   |\nLL |     if x.is_ok() {\n   |        --------- because of this check\n...\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: this call to `expect()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:83:9\n   |\nLL |     if x.is_ok() {\n   |        --------- because of this check\n...\nLL |         x.expect(\"an error message\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap_err` on `x` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:86:9\n   |\nLL |     if x.is_ok() {\n   |     ------------ help: try: `if let Err(<item>) = x`\n...\nLL |         x.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:90:9\n   |\nLL |     if x.is_err() {\n   |        ---------- because of this check\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap_err` on `x` after checking its variant with `is_err`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:93:9\n   |\nLL |     if x.is_err() {\n   |     ------------- help: try: `if let Err(<item>) = x`\n...\nLL |         x.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `x` after checking its variant with `is_err`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:96:9\n   |\nLL |     if x.is_err() {\n   |     ------------- help: try: `if let Ok(<item>) = x`\n...\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: this call to `unwrap_err()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:99:9\n   |\nLL |     if x.is_err() {\n   |        ---------- because of this check\n...\nLL |         x.unwrap_err();\n   |         ^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:124:9\n   |\nLL |     if option.is_some() {\n   |     ------------------- help: try: `if let Some(<item>) = &option`\nLL |         option.as_ref().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:127:9\n   |\nLL |     if option.is_some() {\n   |        ---------------- because of this check\n...\nLL |         option.as_ref().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `result` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:134:9\n   |\nLL |     if result.is_ok() {\n   |     ----------------- help: try: `if let Ok(<item>) = &result`\nLL |         result.as_ref().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:137:9\n   |\nLL |     if result.is_ok() {\n   |        -------------- because of this check\n...\nLL |         result.as_ref().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:143:9\n   |\nLL |     if option.is_some() {\n   |     ------------------- help: try: `if let Some(<item>) = &mut option`\nLL |         option.as_mut().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:146:9\n   |\nLL |     if option.is_some() {\n   |        ---------------- because of this check\n...\nLL |         option.as_mut().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `result` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:152:9\n   |\nLL |     if result.is_ok() {\n   |     ----------------- help: try: `if let Ok(<item>) = &mut result`\nLL |         result.as_mut().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:155:9\n   |\nLL |     if result.is_ok() {\n   |        -------------- because of this check\n...\nLL |         result.as_mut().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:184:17\n   |\nLL |     if option.is_some() {\n   |     ------------------- help: try: `if let Some(<item>) = &option`\nLL |         let _ = option.as_ref().unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:187:17\n   |\nLL |     if option.is_some() {\n   |        ---------------- because of this check\n...\nLL |         let _ = option.as_ref().unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `result` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:195:9\n   |\nLL |     if result.is_ok() {\n   |     ----------------- help: try: `if let Ok(<item>) = &result`\nLL |         let _y = 1;\nLL |         result.as_ref().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:199:9\n   |\nLL |     if result.is_ok() {\n   |        -------------- because of this check\n...\nLL |         result.as_ref().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `x` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:225:17\n   |\nLL |         if x.is_some() {\n   |         -------------- help: try: `if let Some(<item>) = x`\nLL |             _ = x.unwrap();\n   |                 ^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:228:17\n   |\nLL |         if x.is_some() {\n   |            ----------- because of this check\n...\nLL |             _ = x.unwrap();\n   |                 ^^^^^^^^^^\n\nerror: called `unwrap` on `r` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:234:17\n   |\nLL |         if r.is_ok() {\n   |         ------------ help: try: `if let Ok(<item>) = &r`\nLL |             _ = r.as_ref().unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:237:17\n   |\nLL |         if r.is_ok() {\n   |            --------- because of this check\n...\nLL |             _ = r.as_ref().unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `x` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:246:17\n   |\nLL |         if x.is_some() {\n   |         -------------- help: try: `if let Some(<item>) = x`\nLL |             _ = x.unwrap();\n   |                 ^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:249:17\n   |\nLL |         if x.is_some() {\n   |            ----------- because of this check\n...\nLL |             _ = x.unwrap();\n   |                 ^^^^^^^^^^\n\nerror: called `unwrap` on `option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:259:26\n   |\nLL |     if option.is_some() {\n   |     ------------------- help: try: `if let Some(<item>) = option`\nLL |         println!(\"{:?}\", option.unwrap());\n   |                          ^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:262:26\n   |\nLL |     if option.is_some() {\n   |        ---------------- because of this check\n...\nLL |         println!(\"{:?}\", option.unwrap());\n   |                          ^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `result` after checking its variant with `is_ok`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:269:26\n   |\nLL |     if result.is_ok() {\n   |     ----------------- help: try: `if let Ok(<item>) = result`\nLL |         println!(\"{:?}\", result.unwrap());\n   |                          ^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:272:26\n   |\nLL |     if result.is_ok() {\n   |        -------------- because of this check\n...\nLL |         println!(\"{:?}\", result.unwrap());\n   |                          ^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `x` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:299:9\n   |\nLL |     if x.is_some() {\n   |     -------------- help: try: `if let Some(<item>) = x`\nLL |         borrow_option(&x);\nLL |         x.unwrap();\n   |         ^^^^^^^^^^\n\nerror: called `unwrap` on `x` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:305:9\n   |\nLL |     if x.is_some() {\n   |     -------------- help: try: `if let Some(<item>) = &x`\nLL |         borrow_option(&x);\nLL |         x.as_ref().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `sopt.option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:321:9\n   |\nLL |     let _res = if sopt.option.is_some() {\n   |                ------------------------ help: try: `if let Some(<item>) = sopt.option`\nLL |         sopt.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:324:9\n   |\nLL |     let _res = if sopt.option.is_some() {\n   |                   --------------------- because of this check\n...\nLL |         sopt.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `sopt.option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:330:9\n   |\nLL |     let _res = if sopt.option.is_some() {\n   |                ------------------------ help: try: `if let Some(<item>) = sopt.option`\nLL |         sopt.other = false;\nLL |         sopt.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:334:9\n   |\nLL |     let _res = if sopt.option.is_some() {\n   |                   --------------------- because of this check\n...\nLL |         sopt.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `topt.0` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:358:9\n   |\nLL |     let _res = if topt.0.is_some() {\n   |                ------------------- help: try: `if let Some(<item>) = topt.0`\nLL |         topt.0.unwrap()\n   |         ^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:361:9\n   |\nLL |     let _res = if topt.0.is_some() {\n   |                   ---------------- because of this check\n...\nLL |         topt.0.unwrap()\n   |         ^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `topt.0` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:367:9\n   |\nLL |     let _res = if topt.0.is_some() {\n   |                ------------------- help: try: `if let Some(<item>) = topt.0`\nLL |         topt.1 = false;\nLL |         topt.0.unwrap()\n   |         ^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:371:9\n   |\nLL |     let _res = if topt.0.is_some() {\n   |                   ---------------- because of this check\n...\nLL |         topt.0.unwrap()\n   |         ^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `sopt2.option.option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:405:9\n   |\nLL |     let _res = if sopt2.option.option.is_some() {\n   |                -------------------------------- help: try: `if let Some(<item>) = sopt2.option.option`\nLL |         sopt2.option.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:408:9\n   |\nLL |     let _res = if sopt2.option.option.is_some() {\n   |                   ----------------------------- because of this check\n...\nLL |         sopt2.option.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `sopt2.option.option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:415:9\n   |\nLL |     let _res = if sopt2.option.option.is_some() {\n   |                -------------------------------- help: try: `if let Some(<item>) = sopt2.option.option`\nLL |         sopt2.other = false;\nLL |         sopt2.option.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:419:9\n   |\nLL |     let _res = if sopt2.option.option.is_some() {\n   |                   ----------------------------- because of this check\n...\nLL |         sopt2.option.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `sopt2.option.option` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:425:9\n   |\nLL |     let _res = if sopt2.option.option.is_some() {\n   |                -------------------------------- help: try: `if let Some(<item>) = sopt2.option.option`\nLL |         sopt2.option.other = false;\nLL |         sopt2.option.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `unwrap()` will always panic\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:429:9\n   |\nLL |     let _res = if sopt2.option.option.is_some() {\n   |                   ----------------------------- because of this check\n...\nLL |         sopt2.option.option.unwrap()\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `topt.0` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:465:9\n   |\nLL |     if topt.0.is_some() {\n   |     ------------------- help: try: `if let Some(<item>) = topt.0`\nLL |         borrow_toption(&topt);\nLL |         topt.0.unwrap();\n   |         ^^^^^^^^^^^^^^^\n\nerror: called `unwrap` on `topt.0` after checking its variant with `is_some`\n  --> tests/ui/checked_unwrap/simple_conditionals.rs:471:9\n   |\nLL |     if topt.0.is_some() {\n   |     ------------------- help: try: `if let Some(<item>) = &topt.0`\nLL |         borrow_toption(&topt);\nLL |         topt.0.as_ref().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 57 previous errors\n\n"
  },
  {
    "path": "tests/ui/clear_with_drain.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::clear_with_drain)]\n\nuse std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};\n\nfn vec_range() {\n    // Do not lint because iterator is assigned\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(0..v.len());\n\n    // Do not lint because iterator is used\n    let mut v = vec![1, 2, 3];\n    let n = v.drain(0..v.len()).count();\n\n    // Do not lint because iterator is assigned and used\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(usize::MIN..v.len());\n    let n = iter.count();\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.clear();\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.clear();\n    //~^ clear_with_drain\n}\n\nfn vec_range_from() {\n    // Do not lint because iterator is assigned\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(0..);\n\n    // Do not lint because iterator is assigned and used\n    let mut v = vec![1, 2, 3];\n    let mut iter = v.drain(0..);\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut v = vec![1, 2, 3];\n    let next = v.drain(usize::MIN..).next();\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.clear();\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.clear();\n    //~^ clear_with_drain\n}\n\nfn vec_range_full() {\n    // Do not lint because iterator is assigned\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(..);\n\n    // Do not lint because iterator is used\n    let mut v = vec![1, 2, 3];\n    for x in v.drain(..) {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.clear();\n    //~^ clear_with_drain\n}\n\nfn vec_range_to() {\n    // Do not lint because iterator is assigned\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(..v.len());\n\n    // Do not lint because iterator is assigned and used\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(..v.len());\n    for x in iter {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.clear();\n    //~^ clear_with_drain\n}\n\nfn vec_partial_drains() {\n    // Do not lint any of these because the ranges are not full\n\n    let mut v = vec![1, 2, 3];\n    v.drain(1..);\n    let mut v = vec![1, 2, 3];\n    v.drain(1..).max();\n\n    let mut v = vec![1, 2, 3];\n    v.drain(..v.len() - 1);\n    let mut v = vec![1, 2, 3];\n    v.drain(..v.len() - 1).min();\n\n    let mut v = vec![1, 2, 3];\n    v.drain(1..v.len() - 1);\n    let mut v = vec![1, 2, 3];\n    let w: Vec<i8> = v.drain(1..v.len() - 1).collect();\n}\n\nfn vec_deque_range() {\n    // Do not lint because iterator is assigned\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(0..deque.len());\n\n    // Do not lint because iterator is used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let n = deque.drain(0..deque.len()).count();\n\n    // Do not lint because iterator is assigned and used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(usize::MIN..deque.len());\n    let n = iter.count();\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.clear();\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.clear();\n    //~^ clear_with_drain\n}\n\nfn vec_deque_range_from() {\n    // Do not lint because iterator is assigned\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(0..);\n\n    // Do not lint because iterator is assigned and used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let mut iter = deque.drain(0..);\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let next = deque.drain(usize::MIN..).next();\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.clear();\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.clear();\n    //~^ clear_with_drain\n}\n\nfn vec_deque_range_full() {\n    // Do not lint because iterator is assigned\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(..);\n\n    // Do not lint because iterator is used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    for x in deque.drain(..) {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.clear();\n    //~^ clear_with_drain\n}\n\nfn vec_deque_range_to() {\n    // Do not lint because iterator is assigned\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(..deque.len());\n\n    // Do not lint because iterator is assigned and used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(..deque.len());\n    for x in iter {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.clear();\n    //~^ clear_with_drain\n}\n\nfn vec_deque_partial_drains() {\n    // Do not lint any of these because the ranges are not full\n\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(1..);\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(1..).max();\n\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(..deque.len() - 1);\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(..deque.len() - 1).min();\n\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(1..deque.len() - 1);\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let w: Vec<i8> = deque.drain(1..deque.len() - 1).collect();\n}\n\nfn string_range() {\n    // Do not lint because iterator is assigned\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(0..s.len());\n\n    // Do not lint because iterator is used\n    let mut s = String::from(\"Hello, world!\");\n    let n = s.drain(0..s.len()).count();\n\n    // Do not lint because iterator is assigned and used\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(usize::MIN..s.len());\n    let n = iter.count();\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.clear();\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.clear();\n    //~^ clear_with_drain\n}\n\nfn string_range_from() {\n    // Do not lint because iterator is assigned\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(0..);\n\n    // Do not lint because iterator is assigned and used\n    let mut s = String::from(\"Hello, world!\");\n    let mut iter = s.drain(0..);\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut s = String::from(\"Hello, world!\");\n    let next = s.drain(usize::MIN..).next();\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.clear();\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.clear();\n    //~^ clear_with_drain\n}\n\nfn string_range_full() {\n    // Do not lint because iterator is assigned\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(..);\n\n    // Do not lint because iterator is used\n    let mut s = String::from(\"Hello, world!\");\n    for x in s.drain(..) {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.clear();\n    //~^ clear_with_drain\n}\n\nfn string_range_to() {\n    // Do not lint because iterator is assigned\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(..s.len());\n\n    // Do not lint because iterator is assigned and used\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(..s.len());\n    for x in iter {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.clear();\n    //~^ clear_with_drain\n}\n\nfn string_partial_drains() {\n    // Do not lint any of these because the ranges are not full\n\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(1..);\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(1..).max();\n\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(..s.len() - 1);\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(..s.len() - 1).min();\n\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(1..s.len() - 1);\n    let mut s = String::from(\"Hello, world!\");\n    let w: String = s.drain(1..s.len() - 1).collect();\n}\n\nfn hash_set() {\n    // Do not lint because iterator is assigned\n    let mut set = HashSet::from([1, 2, 3]);\n    let iter = set.drain();\n\n    // Do not lint because iterator is assigned and used\n    let mut set = HashSet::from([1, 2, 3]);\n    let mut iter = set.drain();\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut set = HashSet::from([1, 2, 3]);\n    let next = set.drain().next();\n\n    // Do lint\n    let mut set = HashSet::from([1, 2, 3]);\n    set.clear();\n    //~^ clear_with_drain\n}\n\nfn hash_map() {\n    // Do not lint because iterator is assigned\n    let mut map = HashMap::from([(1, \"a\"), (2, \"b\")]);\n    let iter = map.drain();\n\n    // Do not lint because iterator is assigned and used\n    let mut map = HashMap::from([(1, \"a\"), (2, \"b\")]);\n    let mut iter = map.drain();\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut map = HashMap::from([(1, \"a\"), (2, \"b\")]);\n    let next = map.drain().next();\n\n    // Do lint\n    let mut map = HashMap::from([(1, \"a\"), (2, \"b\")]);\n    map.clear();\n    //~^ clear_with_drain\n}\n\nfn binary_heap() {\n    // Do not lint because iterator is assigned\n    let mut heap = BinaryHeap::from([1, 2]);\n    let iter = heap.drain();\n\n    // Do not lint because iterator is assigned and used\n    let mut heap = BinaryHeap::from([1, 2]);\n    let mut iter = heap.drain();\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut heap = BinaryHeap::from([1, 2]);\n    let next = heap.drain().next();\n\n    // Do lint\n    let mut heap = BinaryHeap::from([1, 2]);\n    heap.clear();\n    //~^ clear_with_drain\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/clear_with_drain.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::clear_with_drain)]\n\nuse std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};\n\nfn vec_range() {\n    // Do not lint because iterator is assigned\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(0..v.len());\n\n    // Do not lint because iterator is used\n    let mut v = vec![1, 2, 3];\n    let n = v.drain(0..v.len()).count();\n\n    // Do not lint because iterator is assigned and used\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(usize::MIN..v.len());\n    let n = iter.count();\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.drain(0..v.len());\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.drain(usize::MIN..v.len());\n    //~^ clear_with_drain\n}\n\nfn vec_range_from() {\n    // Do not lint because iterator is assigned\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(0..);\n\n    // Do not lint because iterator is assigned and used\n    let mut v = vec![1, 2, 3];\n    let mut iter = v.drain(0..);\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut v = vec![1, 2, 3];\n    let next = v.drain(usize::MIN..).next();\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.drain(0..);\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.drain(usize::MIN..);\n    //~^ clear_with_drain\n}\n\nfn vec_range_full() {\n    // Do not lint because iterator is assigned\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(..);\n\n    // Do not lint because iterator is used\n    let mut v = vec![1, 2, 3];\n    for x in v.drain(..) {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.drain(..);\n    //~^ clear_with_drain\n}\n\nfn vec_range_to() {\n    // Do not lint because iterator is assigned\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(..v.len());\n\n    // Do not lint because iterator is assigned and used\n    let mut v = vec![1, 2, 3];\n    let iter = v.drain(..v.len());\n    for x in iter {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut v = vec![1, 2, 3];\n    v.drain(..v.len());\n    //~^ clear_with_drain\n}\n\nfn vec_partial_drains() {\n    // Do not lint any of these because the ranges are not full\n\n    let mut v = vec![1, 2, 3];\n    v.drain(1..);\n    let mut v = vec![1, 2, 3];\n    v.drain(1..).max();\n\n    let mut v = vec![1, 2, 3];\n    v.drain(..v.len() - 1);\n    let mut v = vec![1, 2, 3];\n    v.drain(..v.len() - 1).min();\n\n    let mut v = vec![1, 2, 3];\n    v.drain(1..v.len() - 1);\n    let mut v = vec![1, 2, 3];\n    let w: Vec<i8> = v.drain(1..v.len() - 1).collect();\n}\n\nfn vec_deque_range() {\n    // Do not lint because iterator is assigned\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(0..deque.len());\n\n    // Do not lint because iterator is used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let n = deque.drain(0..deque.len()).count();\n\n    // Do not lint because iterator is assigned and used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(usize::MIN..deque.len());\n    let n = iter.count();\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(0..deque.len());\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(usize::MIN..deque.len());\n    //~^ clear_with_drain\n}\n\nfn vec_deque_range_from() {\n    // Do not lint because iterator is assigned\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(0..);\n\n    // Do not lint because iterator is assigned and used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let mut iter = deque.drain(0..);\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let next = deque.drain(usize::MIN..).next();\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(0..);\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(usize::MIN..);\n    //~^ clear_with_drain\n}\n\nfn vec_deque_range_full() {\n    // Do not lint because iterator is assigned\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(..);\n\n    // Do not lint because iterator is used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    for x in deque.drain(..) {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(..);\n    //~^ clear_with_drain\n}\n\nfn vec_deque_range_to() {\n    // Do not lint because iterator is assigned\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(..deque.len());\n\n    // Do not lint because iterator is assigned and used\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let iter = deque.drain(..deque.len());\n    for x in iter {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(..deque.len());\n    //~^ clear_with_drain\n}\n\nfn vec_deque_partial_drains() {\n    // Do not lint any of these because the ranges are not full\n\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(1..);\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(1..).max();\n\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(..deque.len() - 1);\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(..deque.len() - 1).min();\n\n    let mut deque = VecDeque::from([1, 2, 3]);\n    deque.drain(1..deque.len() - 1);\n    let mut deque = VecDeque::from([1, 2, 3]);\n    let w: Vec<i8> = deque.drain(1..deque.len() - 1).collect();\n}\n\nfn string_range() {\n    // Do not lint because iterator is assigned\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(0..s.len());\n\n    // Do not lint because iterator is used\n    let mut s = String::from(\"Hello, world!\");\n    let n = s.drain(0..s.len()).count();\n\n    // Do not lint because iterator is assigned and used\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(usize::MIN..s.len());\n    let n = iter.count();\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(0..s.len());\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(usize::MIN..s.len());\n    //~^ clear_with_drain\n}\n\nfn string_range_from() {\n    // Do not lint because iterator is assigned\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(0..);\n\n    // Do not lint because iterator is assigned and used\n    let mut s = String::from(\"Hello, world!\");\n    let mut iter = s.drain(0..);\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut s = String::from(\"Hello, world!\");\n    let next = s.drain(usize::MIN..).next();\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(0..);\n    //~^ clear_with_drain\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(usize::MIN..);\n    //~^ clear_with_drain\n}\n\nfn string_range_full() {\n    // Do not lint because iterator is assigned\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(..);\n\n    // Do not lint because iterator is used\n    let mut s = String::from(\"Hello, world!\");\n    for x in s.drain(..) {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(..);\n    //~^ clear_with_drain\n}\n\nfn string_range_to() {\n    // Do not lint because iterator is assigned\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(..s.len());\n\n    // Do not lint because iterator is assigned and used\n    let mut s = String::from(\"Hello, world!\");\n    let iter = s.drain(..s.len());\n    for x in iter {\n        let y = format!(\"x = {x}\");\n    }\n\n    // Do lint\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(..s.len());\n    //~^ clear_with_drain\n}\n\nfn string_partial_drains() {\n    // Do not lint any of these because the ranges are not full\n\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(1..);\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(1..).max();\n\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(..s.len() - 1);\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(..s.len() - 1).min();\n\n    let mut s = String::from(\"Hello, world!\");\n    s.drain(1..s.len() - 1);\n    let mut s = String::from(\"Hello, world!\");\n    let w: String = s.drain(1..s.len() - 1).collect();\n}\n\nfn hash_set() {\n    // Do not lint because iterator is assigned\n    let mut set = HashSet::from([1, 2, 3]);\n    let iter = set.drain();\n\n    // Do not lint because iterator is assigned and used\n    let mut set = HashSet::from([1, 2, 3]);\n    let mut iter = set.drain();\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut set = HashSet::from([1, 2, 3]);\n    let next = set.drain().next();\n\n    // Do lint\n    let mut set = HashSet::from([1, 2, 3]);\n    set.drain();\n    //~^ clear_with_drain\n}\n\nfn hash_map() {\n    // Do not lint because iterator is assigned\n    let mut map = HashMap::from([(1, \"a\"), (2, \"b\")]);\n    let iter = map.drain();\n\n    // Do not lint because iterator is assigned and used\n    let mut map = HashMap::from([(1, \"a\"), (2, \"b\")]);\n    let mut iter = map.drain();\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut map = HashMap::from([(1, \"a\"), (2, \"b\")]);\n    let next = map.drain().next();\n\n    // Do lint\n    let mut map = HashMap::from([(1, \"a\"), (2, \"b\")]);\n    map.drain();\n    //~^ clear_with_drain\n}\n\nfn binary_heap() {\n    // Do not lint because iterator is assigned\n    let mut heap = BinaryHeap::from([1, 2]);\n    let iter = heap.drain();\n\n    // Do not lint because iterator is assigned and used\n    let mut heap = BinaryHeap::from([1, 2]);\n    let mut iter = heap.drain();\n    let next = iter.next();\n\n    // Do not lint because iterator is used\n    let mut heap = BinaryHeap::from([1, 2]);\n    let next = heap.drain().next();\n\n    // Do lint\n    let mut heap = BinaryHeap::from([1, 2]);\n    heap.drain();\n    //~^ clear_with_drain\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/clear_with_drain.stderr",
    "content": "error: `drain` used to clear a `Vec`\n  --> tests/ui/clear_with_drain.rs:22:7\n   |\nLL |     v.drain(0..v.len());\n   |       ^^^^^^^^^^^^^^^^^ help: try: `clear()`\n   |\n   = note: `-D clippy::clear-with-drain` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::clear_with_drain)]`\n\nerror: `drain` used to clear a `Vec`\n  --> tests/ui/clear_with_drain.rs:27:7\n   |\nLL |     v.drain(usize::MIN..v.len());\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `Vec`\n  --> tests/ui/clear_with_drain.rs:47:7\n   |\nLL |     v.drain(0..);\n   |       ^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `Vec`\n  --> tests/ui/clear_with_drain.rs:52:7\n   |\nLL |     v.drain(usize::MIN..);\n   |       ^^^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `Vec`\n  --> tests/ui/clear_with_drain.rs:69:7\n   |\nLL |     v.drain(..);\n   |       ^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `Vec`\n  --> tests/ui/clear_with_drain.rs:87:7\n   |\nLL |     v.drain(..v.len());\n   |       ^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `VecDeque`\n  --> tests/ui/clear_with_drain.rs:126:11\n   |\nLL |     deque.drain(0..deque.len());\n   |           ^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `VecDeque`\n  --> tests/ui/clear_with_drain.rs:131:11\n   |\nLL |     deque.drain(usize::MIN..deque.len());\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `VecDeque`\n  --> tests/ui/clear_with_drain.rs:151:11\n   |\nLL |     deque.drain(0..);\n   |           ^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `VecDeque`\n  --> tests/ui/clear_with_drain.rs:156:11\n   |\nLL |     deque.drain(usize::MIN..);\n   |           ^^^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `VecDeque`\n  --> tests/ui/clear_with_drain.rs:173:11\n   |\nLL |     deque.drain(..);\n   |           ^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `VecDeque`\n  --> tests/ui/clear_with_drain.rs:191:11\n   |\nLL |     deque.drain(..deque.len());\n   |           ^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `String`\n  --> tests/ui/clear_with_drain.rs:230:7\n   |\nLL |     s.drain(0..s.len());\n   |       ^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `String`\n  --> tests/ui/clear_with_drain.rs:235:7\n   |\nLL |     s.drain(usize::MIN..s.len());\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `String`\n  --> tests/ui/clear_with_drain.rs:255:7\n   |\nLL |     s.drain(0..);\n   |       ^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `String`\n  --> tests/ui/clear_with_drain.rs:260:7\n   |\nLL |     s.drain(usize::MIN..);\n   |       ^^^^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `String`\n  --> tests/ui/clear_with_drain.rs:277:7\n   |\nLL |     s.drain(..);\n   |       ^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `String`\n  --> tests/ui/clear_with_drain.rs:295:7\n   |\nLL |     s.drain(..s.len());\n   |       ^^^^^^^^^^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `HashSet`\n  --> tests/ui/clear_with_drain.rs:334:9\n   |\nLL |     set.drain();\n   |         ^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `HashMap`\n  --> tests/ui/clear_with_drain.rs:354:9\n   |\nLL |     map.drain();\n   |         ^^^^^^^ help: try: `clear()`\n\nerror: `drain` used to clear a `BinaryHeap`\n  --> tests/ui/clear_with_drain.rs:374:10\n   |\nLL |     heap.drain();\n   |          ^^^^^^^ help: try: `clear()`\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/clone_on_copy.fixed",
    "content": "#![warn(clippy::clone_on_copy)]\n#![allow(\n    clippy::redundant_clone,\n    clippy::deref_addrof,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::toplevel_ref_arg,\n    clippy::needless_borrow\n)]\n\nuse std::cell::RefCell;\n\nfn main() {\n    42;\n    //~^ clone_on_copy\n\n    vec![1].clone(); // ok, not a Copy type\n    Some(vec![1]).clone(); // ok, not a Copy type\n    *(&42);\n    //~^ clone_on_copy\n\n    let rc = RefCell::new(0);\n    *rc.borrow();\n    //~^ clone_on_copy\n\n    let x = 0u32;\n    x.rotate_left(1);\n    //~^ clone_on_copy\n\n    #[derive(Clone, Copy)]\n    struct Foo;\n    impl Foo {\n        fn clone(&self) -> u32 {\n            0\n        }\n    }\n    Foo.clone(); // ok, this is not the clone trait\n\n    macro_rules! m {\n        ($e:expr) => {{ $e }};\n    }\n    m!(42);\n    //~^ clone_on_copy\n\n    struct Wrap([u32; 2]);\n    impl core::ops::Deref for Wrap {\n        type Target = [u32; 2];\n        fn deref(&self) -> &[u32; 2] {\n            &self.0\n        }\n    }\n    let x = Wrap([0, 0]);\n    (*x)[0];\n    //~^ clone_on_copy\n\n    let x = 42;\n    let ref y = x.clone(); // ok, binds by reference\n    let ref mut y = x.clone(); // ok, binds by reference\n}\n\nmod issue3052 {\n    struct A;\n    struct B;\n    struct C;\n    struct D;\n    #[derive(Copy, Clone)]\n    struct E;\n\n    macro_rules! impl_deref {\n        ($src:ident, $dst:ident) => {\n            impl std::ops::Deref for $src {\n                type Target = $dst;\n                fn deref(&self) -> &Self::Target {\n                    &$dst\n                }\n            }\n        };\n    }\n\n    impl_deref!(A, B);\n    impl_deref!(B, C);\n    impl_deref!(C, D);\n    impl std::ops::Deref for D {\n        type Target = &'static E;\n        fn deref(&self) -> &Self::Target {\n            &&E\n        }\n    }\n\n    fn go1() {\n        let a = A;\n        let _: E = *****a;\n        //~^ clone_on_copy\n\n        let _: E = *****a;\n    }\n}\n\nfn issue4348() {\n    fn is_ascii(ch: char) -> bool {\n        ch.is_ascii()\n    }\n\n    let mut x = 43;\n    let _ = &x.clone(); // ok, getting a ref\n    'a'.clone().make_ascii_uppercase(); // ok, clone and then mutate\n    is_ascii('z');\n    //~^ clone_on_copy\n}\n\n#[expect(clippy::vec_init_then_push)]\nfn issue5436() {\n    let mut vec = Vec::new();\n    vec.push(42);\n    //~^ clone_on_copy\n}\n\nfn issue9277() -> Option<i32> {\n    let opt: &Option<i32> = &None;\n    let value = (*opt)?; // operator precedence needed (*opt)?\n    //\n    //~^^ clone_on_copy\n    None\n}\n"
  },
  {
    "path": "tests/ui/clone_on_copy.rs",
    "content": "#![warn(clippy::clone_on_copy)]\n#![allow(\n    clippy::redundant_clone,\n    clippy::deref_addrof,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::toplevel_ref_arg,\n    clippy::needless_borrow\n)]\n\nuse std::cell::RefCell;\n\nfn main() {\n    42.clone();\n    //~^ clone_on_copy\n\n    vec![1].clone(); // ok, not a Copy type\n    Some(vec![1]).clone(); // ok, not a Copy type\n    (&42).clone();\n    //~^ clone_on_copy\n\n    let rc = RefCell::new(0);\n    rc.borrow().clone();\n    //~^ clone_on_copy\n\n    let x = 0u32;\n    x.clone().rotate_left(1);\n    //~^ clone_on_copy\n\n    #[derive(Clone, Copy)]\n    struct Foo;\n    impl Foo {\n        fn clone(&self) -> u32 {\n            0\n        }\n    }\n    Foo.clone(); // ok, this is not the clone trait\n\n    macro_rules! m {\n        ($e:expr) => {{ $e }};\n    }\n    m!(42).clone();\n    //~^ clone_on_copy\n\n    struct Wrap([u32; 2]);\n    impl core::ops::Deref for Wrap {\n        type Target = [u32; 2];\n        fn deref(&self) -> &[u32; 2] {\n            &self.0\n        }\n    }\n    let x = Wrap([0, 0]);\n    x.clone()[0];\n    //~^ clone_on_copy\n\n    let x = 42;\n    let ref y = x.clone(); // ok, binds by reference\n    let ref mut y = x.clone(); // ok, binds by reference\n}\n\nmod issue3052 {\n    struct A;\n    struct B;\n    struct C;\n    struct D;\n    #[derive(Copy, Clone)]\n    struct E;\n\n    macro_rules! impl_deref {\n        ($src:ident, $dst:ident) => {\n            impl std::ops::Deref for $src {\n                type Target = $dst;\n                fn deref(&self) -> &Self::Target {\n                    &$dst\n                }\n            }\n        };\n    }\n\n    impl_deref!(A, B);\n    impl_deref!(B, C);\n    impl_deref!(C, D);\n    impl std::ops::Deref for D {\n        type Target = &'static E;\n        fn deref(&self) -> &Self::Target {\n            &&E\n        }\n    }\n\n    fn go1() {\n        let a = A;\n        let _: E = a.clone();\n        //~^ clone_on_copy\n\n        let _: E = *****a;\n    }\n}\n\nfn issue4348() {\n    fn is_ascii(ch: char) -> bool {\n        ch.is_ascii()\n    }\n\n    let mut x = 43;\n    let _ = &x.clone(); // ok, getting a ref\n    'a'.clone().make_ascii_uppercase(); // ok, clone and then mutate\n    is_ascii('z'.clone());\n    //~^ clone_on_copy\n}\n\n#[expect(clippy::vec_init_then_push)]\nfn issue5436() {\n    let mut vec = Vec::new();\n    vec.push(42.clone());\n    //~^ clone_on_copy\n}\n\nfn issue9277() -> Option<i32> {\n    let opt: &Option<i32> = &None;\n    let value = opt.clone()?; // operator precedence needed (*opt)?\n    //\n    //~^^ clone_on_copy\n    None\n}\n"
  },
  {
    "path": "tests/ui/clone_on_copy.stderr",
    "content": "error: using `clone` on type `i32` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:14:5\n   |\nLL |     42.clone();\n   |     ^^^^^^^^^^ help: try removing the `clone` call: `42`\n   |\n   = note: `-D clippy::clone-on-copy` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::clone_on_copy)]`\n\nerror: using `clone` on type `i32` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:19:5\n   |\nLL |     (&42).clone();\n   |     ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)`\n\nerror: using `clone` on type `i32` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:23:5\n   |\nLL |     rc.borrow().clone();\n   |     ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()`\n\nerror: using `clone` on type `u32` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:27:5\n   |\nLL |     x.clone().rotate_left(1);\n   |     ^^^^^^^^^ help: try removing the `clone` call: `x`\n\nerror: using `clone` on type `i32` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:42:5\n   |\nLL |     m!(42).clone();\n   |     ^^^^^^^^^^^^^^ help: try removing the `clone` call: `m!(42)`\n\nerror: using `clone` on type `[u32; 2]` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:53:5\n   |\nLL |     x.clone()[0];\n   |     ^^^^^^^^^ help: try dereferencing it: `(*x)`\n\nerror: using `clone` on type `E` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:92:20\n   |\nLL |         let _: E = a.clone();\n   |                    ^^^^^^^^^ help: try dereferencing it: `*****a`\n\nerror: using `clone` on type `char` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:107:14\n   |\nLL |     is_ascii('z'.clone());\n   |              ^^^^^^^^^^^ help: try removing the `clone` call: `'z'`\n\nerror: using `clone` on type `i32` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:114:14\n   |\nLL |     vec.push(42.clone());\n   |              ^^^^^^^^^^ help: try removing the `clone` call: `42`\n\nerror: using `clone` on type `Option<i32>` which implements the `Copy` trait\n  --> tests/ui/clone_on_copy.rs:120:17\n   |\nLL |     let value = opt.clone()?; // operator precedence needed (*opt)?\n   |                 ^^^^^^^^^^^ help: try dereferencing it: `(*opt)`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/clone_on_copy_impl.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::non_canonical_clone_impl)]\n\nuse std::fmt;\nuse std::marker::PhantomData;\n\npub struct Key<T> {\n    #[doc(hidden)]\n    pub __name: &'static str,\n    #[doc(hidden)]\n    pub __phantom: PhantomData<T>,\n}\n\nimpl<T> Copy for Key<T> {}\n\nimpl<T> Clone for Key<T> {\n    fn clone(&self) -> Self {\n        Key {\n            __name: self.__name,\n            __phantom: self.__phantom,\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/clone_on_ref_ptr.fixed",
    "content": "#![warn(clippy::clone_on_ref_ptr)]\n\nuse std::rc::{Rc, Weak as RcWeak};\nuse std::sync::{Arc, Weak as ArcWeak};\n\nfn main() {}\n\nfn clone_on_ref_ptr(rc: Rc<str>, rc_weak: RcWeak<str>, arc: Arc<str>, arc_weak: ArcWeak<str>) {\n    std::rc::Rc::<str>::clone(&rc);\n    //~^ clone_on_ref_ptr\n    std::rc::Weak::<str>::clone(&rc_weak);\n    //~^ clone_on_ref_ptr\n    std::sync::Arc::<str>::clone(&arc);\n    //~^ clone_on_ref_ptr\n    std::sync::Weak::<str>::clone(&arc_weak);\n    //~^ clone_on_ref_ptr\n\n    Rc::clone(&rc);\n    Arc::clone(&arc);\n    RcWeak::clone(&rc_weak);\n    ArcWeak::clone(&arc_weak);\n}\n\ntrait SomeTrait {}\nstruct SomeImpl;\nimpl SomeTrait for SomeImpl {}\n\nfn trait_object() {\n    let x = Arc::new(SomeImpl);\n    let _: Arc<dyn SomeTrait> = std::sync::Arc::<SomeImpl>::clone(&x);\n    //~^ clone_on_ref_ptr\n}\n\nmod issue2076 {\n    use std::rc::Rc;\n\n    macro_rules! try_opt {\n        ($expr: expr) => {\n            match $expr {\n                Some(value) => value,\n                None => return None,\n            }\n        };\n    }\n\n    fn func() -> Option<Rc<u8>> {\n        let rc = Rc::new(42);\n        Some(std::rc::Rc::<u8>::clone(&try_opt!(Some(rc))))\n        //~^ clone_on_ref_ptr\n    }\n}\n\nmod issue15009 {\n    use std::rc::{Rc, Weak};\n    use std::sync::atomic::{AtomicU32, Ordering};\n\n    fn main() {\n        let counter = AtomicU32::new(0);\n        let counter_ref = &counter;\n        let factorial = Rc::new_cyclic(move |rec| {\n            let rec = std::rc::Weak::</* generic */>::clone(rec) as Weak<dyn Fn(u32) -> u32>;\n            //~^ clone_on_ref_ptr\n            move |x| {\n                // can capture env\n                counter_ref.fetch_add(1, Ordering::Relaxed);\n                match x {\n                    0 => 1,\n                    x => x * rec.upgrade().unwrap()(x - 1),\n                }\n            }\n        });\n        println!(\"{}\", factorial(5)); // 120\n        println!(\"{}\", counter.load(Ordering::Relaxed)); // 6\n        println!(\"{}\", factorial(7)); // 5040\n        println!(\"{}\", counter.load(Ordering::Relaxed)); // 14\n    }\n}\n\nfn issue15741(mut rc: Rc<str>, ref_rc: &Rc<str>, refmut_rc: &mut Rc<str>) {\n    std::rc::Rc::<str>::clone(&rc);\n    //~^ clone_on_ref_ptr\n    std::rc::Rc::<str>::clone(ref_rc);\n    //~^ clone_on_ref_ptr\n    std::rc::Rc::<str>::clone(refmut_rc);\n    //~^ clone_on_ref_ptr\n\n    // The following cases already cause warn-by-default lints to fire, and the suggestion just makes\n    // another set of warn-by-default lints to fire, so this is probably fine\n\n    #[allow(clippy::needless_borrow, clippy::unnecessary_mut_passed)] // before the suggestion\n    #[allow(clippy::double_parens)] // after the suggestion\n    {\n        std::rc::Rc::<str>::clone(&(rc));\n        //~^ clone_on_ref_ptr\n        std::rc::Rc::<str>::clone(&rc);\n        //~^ clone_on_ref_ptr\n        std::rc::Rc::<str>::clone(&mut rc);\n        //~^ clone_on_ref_ptr\n    };\n}\n"
  },
  {
    "path": "tests/ui/clone_on_ref_ptr.rs",
    "content": "#![warn(clippy::clone_on_ref_ptr)]\n\nuse std::rc::{Rc, Weak as RcWeak};\nuse std::sync::{Arc, Weak as ArcWeak};\n\nfn main() {}\n\nfn clone_on_ref_ptr(rc: Rc<str>, rc_weak: RcWeak<str>, arc: Arc<str>, arc_weak: ArcWeak<str>) {\n    rc.clone();\n    //~^ clone_on_ref_ptr\n    rc_weak.clone();\n    //~^ clone_on_ref_ptr\n    arc.clone();\n    //~^ clone_on_ref_ptr\n    arc_weak.clone();\n    //~^ clone_on_ref_ptr\n\n    Rc::clone(&rc);\n    Arc::clone(&arc);\n    RcWeak::clone(&rc_weak);\n    ArcWeak::clone(&arc_weak);\n}\n\ntrait SomeTrait {}\nstruct SomeImpl;\nimpl SomeTrait for SomeImpl {}\n\nfn trait_object() {\n    let x = Arc::new(SomeImpl);\n    let _: Arc<dyn SomeTrait> = x.clone();\n    //~^ clone_on_ref_ptr\n}\n\nmod issue2076 {\n    use std::rc::Rc;\n\n    macro_rules! try_opt {\n        ($expr: expr) => {\n            match $expr {\n                Some(value) => value,\n                None => return None,\n            }\n        };\n    }\n\n    fn func() -> Option<Rc<u8>> {\n        let rc = Rc::new(42);\n        Some(try_opt!(Some(rc)).clone())\n        //~^ clone_on_ref_ptr\n    }\n}\n\nmod issue15009 {\n    use std::rc::{Rc, Weak};\n    use std::sync::atomic::{AtomicU32, Ordering};\n\n    fn main() {\n        let counter = AtomicU32::new(0);\n        let counter_ref = &counter;\n        let factorial = Rc::new_cyclic(move |rec| {\n            let rec = rec.clone() as Weak<dyn Fn(u32) -> u32>;\n            //~^ clone_on_ref_ptr\n            move |x| {\n                // can capture env\n                counter_ref.fetch_add(1, Ordering::Relaxed);\n                match x {\n                    0 => 1,\n                    x => x * rec.upgrade().unwrap()(x - 1),\n                }\n            }\n        });\n        println!(\"{}\", factorial(5)); // 120\n        println!(\"{}\", counter.load(Ordering::Relaxed)); // 6\n        println!(\"{}\", factorial(7)); // 5040\n        println!(\"{}\", counter.load(Ordering::Relaxed)); // 14\n    }\n}\n\nfn issue15741(mut rc: Rc<str>, ref_rc: &Rc<str>, refmut_rc: &mut Rc<str>) {\n    rc.clone();\n    //~^ clone_on_ref_ptr\n    ref_rc.clone();\n    //~^ clone_on_ref_ptr\n    refmut_rc.clone();\n    //~^ clone_on_ref_ptr\n\n    // The following cases already cause warn-by-default lints to fire, and the suggestion just makes\n    // another set of warn-by-default lints to fire, so this is probably fine\n\n    #[allow(clippy::needless_borrow, clippy::unnecessary_mut_passed)] // before the suggestion\n    #[allow(clippy::double_parens)] // after the suggestion\n    {\n        (rc).clone();\n        //~^ clone_on_ref_ptr\n        (&rc).clone();\n        //~^ clone_on_ref_ptr\n        (&mut rc).clone();\n        //~^ clone_on_ref_ptr\n    };\n}\n"
  },
  {
    "path": "tests/ui/clone_on_ref_ptr.stderr",
    "content": "error: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:9:5\n   |\nLL |     rc.clone();\n   |     ^^^^^^^^^^ help: try: `std::rc::Rc::<str>::clone(&rc)`\n   |\n   = note: `-D clippy::clone-on-ref-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::clone_on_ref_ptr)]`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:11:5\n   |\nLL |     rc_weak.clone();\n   |     ^^^^^^^^^^^^^^^ help: try: `std::rc::Weak::<str>::clone(&rc_weak)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:13:5\n   |\nLL |     arc.clone();\n   |     ^^^^^^^^^^^ help: try: `std::sync::Arc::<str>::clone(&arc)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:15:5\n   |\nLL |     arc_weak.clone();\n   |     ^^^^^^^^^^^^^^^^ help: try: `std::sync::Weak::<str>::clone(&arc_weak)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:30:33\n   |\nLL |     let _: Arc<dyn SomeTrait> = x.clone();\n   |                                 ^^^^^^^^^ help: try: `std::sync::Arc::<SomeImpl>::clone(&x)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:48:14\n   |\nLL |         Some(try_opt!(Some(rc)).clone())\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::rc::Rc::<u8>::clone(&try_opt!(Some(rc)))`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:61:23\n   |\nLL |             let rec = rec.clone() as Weak<dyn Fn(u32) -> u32>;\n   |                       ^^^^^^^^^^^ help: try: `std::rc::Weak::</* generic */>::clone(rec)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:80:5\n   |\nLL |     rc.clone();\n   |     ^^^^^^^^^^ help: try: `std::rc::Rc::<str>::clone(&rc)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:82:5\n   |\nLL |     ref_rc.clone();\n   |     ^^^^^^^^^^^^^^ help: try: `std::rc::Rc::<str>::clone(ref_rc)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:84:5\n   |\nLL |     refmut_rc.clone();\n   |     ^^^^^^^^^^^^^^^^^ help: try: `std::rc::Rc::<str>::clone(refmut_rc)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:93:9\n   |\nLL |         (rc).clone();\n   |         ^^^^^^^^^^^^ help: try: `std::rc::Rc::<str>::clone(&(rc))`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:95:9\n   |\nLL |         (&rc).clone();\n   |         ^^^^^^^^^^^^^ help: try: `std::rc::Rc::<str>::clone(&rc)`\n\nerror: using `.clone()` on a ref-counted pointer\n  --> tests/ui/clone_on_ref_ptr.rs:97:9\n   |\nLL |         (&mut rc).clone();\n   |         ^^^^^^^^^^^^^^^^^ help: try: `std::rc::Rc::<str>::clone(&mut rc)`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/cloned_instead_of_copied.fixed",
    "content": "#![warn(clippy::cloned_instead_of_copied)]\n#![allow(unused)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    // yay\n    let _ = [1].iter().copied();\n    //~^ cloned_instead_of_copied\n    let _ = vec![\"hi\"].iter().copied();\n    //~^ cloned_instead_of_copied\n    let _ = Some(&1).copied();\n    //~^ cloned_instead_of_copied\n    let _ = Box::new([1].iter()).copied();\n    //~^ cloned_instead_of_copied\n    let _ = Box::new(Some(&1)).copied();\n    //~^ cloned_instead_of_copied\n\n    // nay\n    let _ = [String::new()].iter().cloned();\n    let _ = Some(&String::new()).cloned();\n}\n\n#[clippy::msrv = \"1.34\"]\nfn msrv_1_34() {\n    let _ = [1].iter().cloned();\n    let _ = Some(&1).cloned();\n}\n\n#[clippy::msrv = \"1.35\"]\nfn msrv_1_35() {\n    let _ = [1].iter().cloned();\n    let _ = Some(&1).copied(); // Option::copied needs 1.35\n    //\n    //~^^ cloned_instead_of_copied\n}\n\n#[clippy::msrv = \"1.36\"]\nfn msrv_1_36() {\n    let _ = [1].iter().copied(); // Iterator::copied needs 1.36\n    //\n    //~^^ cloned_instead_of_copied\n    let _ = Some(&1).copied();\n    //~^ cloned_instead_of_copied\n}\n"
  },
  {
    "path": "tests/ui/cloned_instead_of_copied.rs",
    "content": "#![warn(clippy::cloned_instead_of_copied)]\n#![allow(unused)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    // yay\n    let _ = [1].iter().cloned();\n    //~^ cloned_instead_of_copied\n    let _ = vec![\"hi\"].iter().cloned();\n    //~^ cloned_instead_of_copied\n    let _ = Some(&1).cloned();\n    //~^ cloned_instead_of_copied\n    let _ = Box::new([1].iter()).cloned();\n    //~^ cloned_instead_of_copied\n    let _ = Box::new(Some(&1)).cloned();\n    //~^ cloned_instead_of_copied\n\n    // nay\n    let _ = [String::new()].iter().cloned();\n    let _ = Some(&String::new()).cloned();\n}\n\n#[clippy::msrv = \"1.34\"]\nfn msrv_1_34() {\n    let _ = [1].iter().cloned();\n    let _ = Some(&1).cloned();\n}\n\n#[clippy::msrv = \"1.35\"]\nfn msrv_1_35() {\n    let _ = [1].iter().cloned();\n    let _ = Some(&1).cloned(); // Option::copied needs 1.35\n    //\n    //~^^ cloned_instead_of_copied\n}\n\n#[clippy::msrv = \"1.36\"]\nfn msrv_1_36() {\n    let _ = [1].iter().cloned(); // Iterator::copied needs 1.36\n    //\n    //~^^ cloned_instead_of_copied\n    let _ = Some(&1).cloned();\n    //~^ cloned_instead_of_copied\n}\n"
  },
  {
    "path": "tests/ui/cloned_instead_of_copied.stderr",
    "content": "error: used `cloned` where `copied` could be used instead\n  --> tests/ui/cloned_instead_of_copied.rs:7:24\n   |\nLL |     let _ = [1].iter().cloned();\n   |                        ^^^^^^ help: try: `copied`\n   |\n   = note: `-D clippy::cloned-instead-of-copied` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cloned_instead_of_copied)]`\n\nerror: used `cloned` where `copied` could be used instead\n  --> tests/ui/cloned_instead_of_copied.rs:9:31\n   |\nLL |     let _ = vec![\"hi\"].iter().cloned();\n   |                               ^^^^^^ help: try: `copied`\n\nerror: used `cloned` where `copied` could be used instead\n  --> tests/ui/cloned_instead_of_copied.rs:11:22\n   |\nLL |     let _ = Some(&1).cloned();\n   |                      ^^^^^^ help: try: `copied`\n\nerror: used `cloned` where `copied` could be used instead\n  --> tests/ui/cloned_instead_of_copied.rs:13:34\n   |\nLL |     let _ = Box::new([1].iter()).cloned();\n   |                                  ^^^^^^ help: try: `copied`\n\nerror: used `cloned` where `copied` could be used instead\n  --> tests/ui/cloned_instead_of_copied.rs:15:32\n   |\nLL |     let _ = Box::new(Some(&1)).cloned();\n   |                                ^^^^^^ help: try: `copied`\n\nerror: used `cloned` where `copied` could be used instead\n  --> tests/ui/cloned_instead_of_copied.rs:32:22\n   |\nLL |     let _ = Some(&1).cloned(); // Option::copied needs 1.35\n   |                      ^^^^^^ help: try: `copied`\n\nerror: used `cloned` where `copied` could be used instead\n  --> tests/ui/cloned_instead_of_copied.rs:39:24\n   |\nLL |     let _ = [1].iter().cloned(); // Iterator::copied needs 1.36\n   |                        ^^^^^^ help: try: `copied`\n\nerror: used `cloned` where `copied` could be used instead\n  --> tests/ui/cloned_instead_of_copied.rs:42:22\n   |\nLL |     let _ = Some(&1).cloned();\n   |                      ^^^^^^ help: try: `copied`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/cloned_ref_to_slice_refs.fixed",
    "content": "#![warn(clippy::cloned_ref_to_slice_refs)]\n\n#[derive(Clone)]\nstruct Data;\n\nfn main() {\n    {\n        let data = Data;\n        let data_ref = &data;\n        let _ = std::slice::from_ref(data_ref); //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`\n    }\n\n    {\n        let _ = std::slice::from_ref(&Data); //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`\n    }\n\n    {\n        #[derive(Clone)]\n        struct Point(i32, i32);\n\n        let _ = std::slice::from_ref(&Point(0, 0)); //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`\n    }\n\n    // the string was cloned with the intention to not mutate\n    {\n        struct BetterString(String);\n\n        let mut message = String::from(\"good\");\n        let sender = BetterString(message.clone());\n\n        message.push_str(\"bye!\");\n\n        println!(\"{} {}\", message, sender.0)\n    }\n\n    // the string was cloned with the intention to not mutate\n    {\n        let mut x = String::from(\"Hello\");\n        let r = &[x.clone()];\n        x.push('!');\n        println!(\"r = `{}', x = `{x}'\", r[0]);\n    }\n\n    // mutable borrows may have the intention to clone\n    {\n        let data = Data;\n        let data_ref = &data;\n        let _ = &mut [data_ref.clone()];\n    }\n\n    // `T::clone` is used to denote a clone with side effects\n    {\n        use std::sync::Arc;\n        let data = Arc::new(Data);\n        let _ = &[Arc::clone(&data)];\n    }\n\n    // slices with multiple members can only be made from a singular reference\n    {\n        let data_1 = Data;\n        let data_2 = Data;\n        let _ = &[data_1.clone(), data_2.clone()];\n    }\n}\n"
  },
  {
    "path": "tests/ui/cloned_ref_to_slice_refs.rs",
    "content": "#![warn(clippy::cloned_ref_to_slice_refs)]\n\n#[derive(Clone)]\nstruct Data;\n\nfn main() {\n    {\n        let data = Data;\n        let data_ref = &data;\n        let _ = &[data_ref.clone()]; //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`\n    }\n\n    {\n        let _ = &[Data.clone()]; //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`\n    }\n\n    {\n        #[derive(Clone)]\n        struct Point(i32, i32);\n\n        let _ = &[Point(0, 0).clone()]; //~ ERROR: this call to `clone` can be replaced with `std::slice::from_ref`\n    }\n\n    // the string was cloned with the intention to not mutate\n    {\n        struct BetterString(String);\n\n        let mut message = String::from(\"good\");\n        let sender = BetterString(message.clone());\n\n        message.push_str(\"bye!\");\n\n        println!(\"{} {}\", message, sender.0)\n    }\n\n    // the string was cloned with the intention to not mutate\n    {\n        let mut x = String::from(\"Hello\");\n        let r = &[x.clone()];\n        x.push('!');\n        println!(\"r = `{}', x = `{x}'\", r[0]);\n    }\n\n    // mutable borrows may have the intention to clone\n    {\n        let data = Data;\n        let data_ref = &data;\n        let _ = &mut [data_ref.clone()];\n    }\n\n    // `T::clone` is used to denote a clone with side effects\n    {\n        use std::sync::Arc;\n        let data = Arc::new(Data);\n        let _ = &[Arc::clone(&data)];\n    }\n\n    // slices with multiple members can only be made from a singular reference\n    {\n        let data_1 = Data;\n        let data_2 = Data;\n        let _ = &[data_1.clone(), data_2.clone()];\n    }\n}\n"
  },
  {
    "path": "tests/ui/cloned_ref_to_slice_refs.stderr",
    "content": "error: this call to `clone` can be replaced with `std::slice::from_ref`\n  --> tests/ui/cloned_ref_to_slice_refs.rs:10:17\n   |\nLL |         let _ = &[data_ref.clone()];\n   |                 ^^^^^^^^^^^^^^^^^^^ help: try: `std::slice::from_ref(data_ref)`\n   |\n   = note: `-D clippy::cloned-ref-to-slice-refs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cloned_ref_to_slice_refs)]`\n\nerror: this call to `clone` can be replaced with `std::slice::from_ref`\n  --> tests/ui/cloned_ref_to_slice_refs.rs:14:17\n   |\nLL |         let _ = &[Data.clone()];\n   |                 ^^^^^^^^^^^^^^^ help: try: `std::slice::from_ref(&Data)`\n\nerror: this call to `clone` can be replaced with `std::slice::from_ref`\n  --> tests/ui/cloned_ref_to_slice_refs.rs:21:17\n   |\nLL |         let _ = &[Point(0, 0).clone()];\n   |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::slice::from_ref(&Point(0, 0))`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/cmp_null.fixed",
    "content": "#![warn(clippy::cmp_null)]\n\nuse std::ptr;\n\nfn main() {\n    let x = 0;\n    let p: *const usize = &x;\n    if p.is_null() {\n        //~^ cmp_null\n\n        println!(\"This is surprising!\");\n    }\n    if p.is_null() {\n        //~^ cmp_null\n\n        println!(\"This is surprising!\");\n    }\n\n    let mut y = 0;\n    let m: *mut usize = &mut y;\n    if m.is_null() {\n        //~^ cmp_null\n\n        println!(\"This is surprising, too!\");\n    }\n    if m.is_null() {\n        //~^ cmp_null\n\n        println!(\"This is surprising, too!\");\n    }\n\n    let _ = (x as *const ()).is_null();\n    //~^ cmp_null\n}\n\nfn issue15010() {\n    let f: *mut i32 = std::ptr::null_mut();\n    debug_assert!(!f.is_null());\n    //~^ cmp_null\n}\n\nfn issue16281() {\n    use std::ptr;\n\n    struct Container {\n        value: *const i32,\n    }\n    let x = Container { value: ptr::null() };\n\n    macro_rules! dot_value {\n        ($obj:expr) => {\n            $obj.value\n        };\n    }\n\n    if dot_value!(x).is_null() {\n        //~^ cmp_null\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/cmp_null.rs",
    "content": "#![warn(clippy::cmp_null)]\n\nuse std::ptr;\n\nfn main() {\n    let x = 0;\n    let p: *const usize = &x;\n    if p == ptr::null() {\n        //~^ cmp_null\n\n        println!(\"This is surprising!\");\n    }\n    if ptr::null() == p {\n        //~^ cmp_null\n\n        println!(\"This is surprising!\");\n    }\n\n    let mut y = 0;\n    let m: *mut usize = &mut y;\n    if m == ptr::null_mut() {\n        //~^ cmp_null\n\n        println!(\"This is surprising, too!\");\n    }\n    if ptr::null_mut() == m {\n        //~^ cmp_null\n\n        println!(\"This is surprising, too!\");\n    }\n\n    let _ = x as *const () == ptr::null();\n    //~^ cmp_null\n}\n\nfn issue15010() {\n    let f: *mut i32 = std::ptr::null_mut();\n    debug_assert!(f != std::ptr::null_mut());\n    //~^ cmp_null\n}\n\nfn issue16281() {\n    use std::ptr;\n\n    struct Container {\n        value: *const i32,\n    }\n    let x = Container { value: ptr::null() };\n\n    macro_rules! dot_value {\n        ($obj:expr) => {\n            $obj.value\n        };\n    }\n\n    if dot_value!(x) == ptr::null() {\n        //~^ cmp_null\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/cmp_null.stderr",
    "content": "error: comparing with null is better expressed by the `.is_null()` method\n  --> tests/ui/cmp_null.rs:8:8\n   |\nLL |     if p == ptr::null() {\n   |        ^^^^^^^^^^^^^^^^ help: try: `p.is_null()`\n   |\n   = note: `-D clippy::cmp-null` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cmp_null)]`\n\nerror: comparing with null is better expressed by the `.is_null()` method\n  --> tests/ui/cmp_null.rs:13:8\n   |\nLL |     if ptr::null() == p {\n   |        ^^^^^^^^^^^^^^^^ help: try: `p.is_null()`\n\nerror: comparing with null is better expressed by the `.is_null()` method\n  --> tests/ui/cmp_null.rs:21:8\n   |\nLL |     if m == ptr::null_mut() {\n   |        ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()`\n\nerror: comparing with null is better expressed by the `.is_null()` method\n  --> tests/ui/cmp_null.rs:26:8\n   |\nLL |     if ptr::null_mut() == m {\n   |        ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()`\n\nerror: comparing with null is better expressed by the `.is_null()` method\n  --> tests/ui/cmp_null.rs:32:13\n   |\nLL |     let _ = x as *const () == ptr::null();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(x as *const ()).is_null()`\n\nerror: comparing with null is better expressed by the `.is_null()` method\n  --> tests/ui/cmp_null.rs:38:19\n   |\nLL |     debug_assert!(f != std::ptr::null_mut());\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!f.is_null()`\n\nerror: comparing with null is better expressed by the `.is_null()` method\n  --> tests/ui/cmp_null.rs:56:8\n   |\nLL |     if dot_value!(x) == ptr::null() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dot_value!(x).is_null()`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/cmp_owned/asymmetric_partial_eq.fixed",
    "content": "#![allow(\n    unused,\n    clippy::needless_ifs,\n    clippy::redundant_clone,\n    clippy::derive_partial_eq_without_eq\n)] // See #5700\n\n// Define the types in each module to avoid trait impls leaking between modules.\nmacro_rules! impl_types {\n    () => {\n        #[derive(PartialEq)]\n        pub struct Owned;\n\n        pub struct Borrowed;\n\n        impl ToOwned for Borrowed {\n            type Owned = Owned;\n            fn to_owned(&self) -> Owned {\n                Owned {}\n            }\n        }\n\n        impl std::borrow::Borrow<Borrowed> for Owned {\n            fn borrow(&self) -> &Borrowed {\n                static VALUE: Borrowed = Borrowed {};\n                &VALUE\n            }\n        }\n    };\n}\n\n// Only Borrowed == Owned is implemented\nmod borrowed_eq_owned {\n    impl_types!();\n\n    impl PartialEq<Owned> for Borrowed {\n        fn eq(&self, _: &Owned) -> bool {\n            true\n        }\n    }\n\n    pub fn compare() {\n        let owned = Owned {};\n        let borrowed = Borrowed {};\n\n        if borrowed == owned {}\n        //~^ cmp_owned\n        if borrowed == owned {}\n        //~^ cmp_owned\n    }\n}\n\n// Only Owned == Borrowed is implemented\nmod owned_eq_borrowed {\n    impl_types!();\n\n    impl PartialEq<Borrowed> for Owned {\n        fn eq(&self, _: &Borrowed) -> bool {\n            true\n        }\n    }\n\n    fn compare() {\n        let owned = Owned {};\n        let borrowed = Borrowed {};\n\n        if owned == borrowed {}\n        //~^ cmp_owned\n        if owned == borrowed {}\n        //~^ cmp_owned\n    }\n}\n\nmod issue_4874 {\n    impl_types!();\n\n    // NOTE: PartialEq<Borrowed> for T can't be implemented due to the orphan rules\n    impl<T> PartialEq<T> for Borrowed\n    where\n        T: AsRef<str> + ?Sized,\n    {\n        fn eq(&self, _: &T) -> bool {\n            true\n        }\n    }\n\n    impl std::fmt::Display for Borrowed {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            write!(f, \"borrowed\")\n        }\n    }\n\n    fn compare() {\n        let borrowed = Borrowed {};\n\n        if borrowed == \"Hi\" {}\n        //~^ cmp_owned\n        if borrowed == \"Hi\" {}\n        //~^ cmp_owned\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/cmp_owned/asymmetric_partial_eq.rs",
    "content": "#![allow(\n    unused,\n    clippy::needless_ifs,\n    clippy::redundant_clone,\n    clippy::derive_partial_eq_without_eq\n)] // See #5700\n\n// Define the types in each module to avoid trait impls leaking between modules.\nmacro_rules! impl_types {\n    () => {\n        #[derive(PartialEq)]\n        pub struct Owned;\n\n        pub struct Borrowed;\n\n        impl ToOwned for Borrowed {\n            type Owned = Owned;\n            fn to_owned(&self) -> Owned {\n                Owned {}\n            }\n        }\n\n        impl std::borrow::Borrow<Borrowed> for Owned {\n            fn borrow(&self) -> &Borrowed {\n                static VALUE: Borrowed = Borrowed {};\n                &VALUE\n            }\n        }\n    };\n}\n\n// Only Borrowed == Owned is implemented\nmod borrowed_eq_owned {\n    impl_types!();\n\n    impl PartialEq<Owned> for Borrowed {\n        fn eq(&self, _: &Owned) -> bool {\n            true\n        }\n    }\n\n    pub fn compare() {\n        let owned = Owned {};\n        let borrowed = Borrowed {};\n\n        if borrowed.to_owned() == owned {}\n        //~^ cmp_owned\n        if owned == borrowed.to_owned() {}\n        //~^ cmp_owned\n    }\n}\n\n// Only Owned == Borrowed is implemented\nmod owned_eq_borrowed {\n    impl_types!();\n\n    impl PartialEq<Borrowed> for Owned {\n        fn eq(&self, _: &Borrowed) -> bool {\n            true\n        }\n    }\n\n    fn compare() {\n        let owned = Owned {};\n        let borrowed = Borrowed {};\n\n        if owned == borrowed.to_owned() {}\n        //~^ cmp_owned\n        if borrowed.to_owned() == owned {}\n        //~^ cmp_owned\n    }\n}\n\nmod issue_4874 {\n    impl_types!();\n\n    // NOTE: PartialEq<Borrowed> for T can't be implemented due to the orphan rules\n    impl<T> PartialEq<T> for Borrowed\n    where\n        T: AsRef<str> + ?Sized,\n    {\n        fn eq(&self, _: &T) -> bool {\n            true\n        }\n    }\n\n    impl std::fmt::Display for Borrowed {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            write!(f, \"borrowed\")\n        }\n    }\n\n    fn compare() {\n        let borrowed = Borrowed {};\n\n        if \"Hi\" == borrowed.to_string() {}\n        //~^ cmp_owned\n        if borrowed.to_string() == \"Hi\" {}\n        //~^ cmp_owned\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/cmp_owned/asymmetric_partial_eq.stderr",
    "content": "error: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:46:12\n   |\nLL |         if borrowed.to_owned() == owned {}\n   |            ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed`\n   |\n   = note: `-D clippy::cmp-owned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:48:21\n   |\nLL |         if owned == borrowed.to_owned() {}\n   |            ---------^^^^^^^^^^^^^^^^^^^\n   |            |\n   |            help: try: `borrowed == owned`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:67:21\n   |\nLL |         if owned == borrowed.to_owned() {}\n   |                     ^^^^^^^^^^^^^^^^^^^ help: try: `borrowed`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:69:12\n   |\nLL |         if borrowed.to_owned() == owned {}\n   |            ^^^^^^^^^^^^^^^^^^^---------\n   |            |\n   |            help: try: `owned == borrowed`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:96:20\n   |\nLL |         if \"Hi\" == borrowed.to_string() {}\n   |            --------^^^^^^^^^^^^^^^^^^^^\n   |            |\n   |            help: try: `borrowed == \"Hi\"`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/asymmetric_partial_eq.rs:98:12\n   |\nLL |         if borrowed.to_string() == \"Hi\" {}\n   |            ^^^^^^^^^^^^^^^^^^^^ help: try: `borrowed`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/cmp_owned/comparison_flip.fixed",
    "content": "use std::fmt::{self, Display};\n\nfn main() {\n    let a = Foo;\n\n    if a != \"bar\" {\n        //~^ cmp_owned\n        println!(\"foo\");\n    }\n\n    if a != \"bar\" {\n        //~^ cmp_owned\n        println!(\"foo\");\n    }\n}\n\nstruct Foo;\n\nimpl Display for Foo {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"foo\")\n    }\n}\n\nimpl PartialEq<&str> for Foo {\n    fn eq(&self, other: &&str) -> bool {\n        \"foo\" == *other\n    }\n}\n"
  },
  {
    "path": "tests/ui/cmp_owned/comparison_flip.rs",
    "content": "use std::fmt::{self, Display};\n\nfn main() {\n    let a = Foo;\n\n    if a.to_string() != \"bar\" {\n        //~^ cmp_owned\n        println!(\"foo\");\n    }\n\n    if \"bar\" != a.to_string() {\n        //~^ cmp_owned\n        println!(\"foo\");\n    }\n}\n\nstruct Foo;\n\nimpl Display for Foo {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"foo\")\n    }\n}\n\nimpl PartialEq<&str> for Foo {\n    fn eq(&self, other: &&str) -> bool {\n        \"foo\" == *other\n    }\n}\n"
  },
  {
    "path": "tests/ui/cmp_owned/comparison_flip.stderr",
    "content": "error: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/comparison_flip.rs:6:8\n   |\nLL |     if a.to_string() != \"bar\" {\n   |        ^^^^^^^^^^^^^ help: try: `a`\n   |\n   = note: `-D clippy::cmp-owned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/comparison_flip.rs:11:17\n   |\nLL |     if \"bar\" != a.to_string() {\n   |        ---------^^^^^^^^^^^^^\n   |        |\n   |        help: try: `a != \"bar\"`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/cmp_owned/with_suggestion.fixed",
    "content": "#[warn(clippy::cmp_owned)]\n#[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)]\nfn main() {\n    fn with_to_string(x: &str) {\n        x != \"foo\";\n        //~^ cmp_owned\n\n        \"foo\" != x;\n        //~^ cmp_owned\n    }\n\n    let x = \"oh\";\n\n    with_to_string(x);\n\n    x != \"foo\";\n    //~^ cmp_owned\n\n    x != \"foo\";\n    //~^ cmp_owned\n\n    42.to_string() == \"42\";\n\n    Foo == Foo;\n    //~^ cmp_owned\n\n    \"abc\".chars().filter(|c| *c != 'X');\n    //~^ cmp_owned\n\n    \"abc\".chars().filter(|c| *c != 'X');\n}\n\nstruct Foo;\n\nimpl PartialEq for Foo {\n    // Allow this here, because it emits the lint\n    // without a suggestion. This is tested in\n    // `tests/ui/cmp_owned/without_suggestion.rs`\n    #[allow(clippy::cmp_owned)]\n    fn eq(&self, other: &Self) -> bool {\n        self.to_owned() == *other\n    }\n}\n\nimpl ToOwned for Foo {\n    type Owned = Bar;\n    fn to_owned(&self) -> Bar {\n        Bar\n    }\n}\n\n#[derive(PartialEq, Eq)]\nstruct Bar;\n\nimpl PartialEq<Foo> for Bar {\n    fn eq(&self, _: &Foo) -> bool {\n        true\n    }\n}\n\nimpl std::borrow::Borrow<Foo> for Bar {\n    fn borrow(&self) -> &Foo {\n        static FOO: Foo = Foo;\n        &FOO\n    }\n}\n\n#[derive(PartialEq, Eq)]\nstruct Baz;\n\nimpl ToOwned for Baz {\n    type Owned = Baz;\n    fn to_owned(&self) -> Baz {\n        Baz\n    }\n}\n\nfn issue_8103() {\n    let foo1 = String::from(\"foo\");\n    let _ = foo1 == \"foo\";\n    //~^ cmp_owned\n    let foo2 = \"foo\";\n    let _ = foo1 == foo2;\n    //~^ cmp_owned\n}\n\nmacro_rules! issue16322_macro_generator {\n    ($locale:ident) => {\n        mod $locale {\n            macro_rules! _make {\n                ($token:tt) => {\n                    stringify!($token)\n                };\n            }\n\n            pub(crate) use _make;\n        }\n\n        macro_rules! t {\n            ($token:tt) => {\n                crate::$locale::_make!($token)\n            };\n        }\n    };\n}\n\nissue16322_macro_generator!(de);\n\nfn issue16322(item: String) {\n    if item == t!(frohes_neu_Jahr) {\n        //~^ cmp_owned\n        println!(\"Ja!\");\n    }\n}\n\nfn issue16458() {\n    macro_rules! m {\n        () => {\n            \"\"\n        };\n    }\n\n    macro_rules! partly_comes_from_macro {\n        ($i:ident: $ty:ty, $def:expr) => {\n            let _ = {\n                let res = <$ty>::default() == $def;\n                let _i: $ty = $def;\n                res\n            };\n        };\n    }\n\n    partly_comes_from_macro! {\n        required_version: String, m!().to_string()\n    }\n\n    macro_rules! all_comes_from_macro {\n        ($($i:ident: $ty:ty, $def:expr);+ $(;)*) => {\n            $(\n                let _ = {\n                    let res = <$ty>::default() == \"$def\";\n                    //~^ cmp_owned\n                    let _i: $ty = $def;\n                    res\n                };\n            )+\n        };\n    }\n    all_comes_from_macro! {\n        required_version: String, m!().to_string();\n    }\n}\n\nfn issue16564(path: std::path::PathBuf) {\n    const ROOT: &str = \"root\";\n    if path != *ROOT {\n        //~^ cmp_owned\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/cmp_owned/with_suggestion.rs",
    "content": "#[warn(clippy::cmp_owned)]\n#[allow(clippy::unnecessary_operation, clippy::no_effect, unused_must_use, clippy::eq_op)]\nfn main() {\n    fn with_to_string(x: &str) {\n        x != \"foo\".to_string();\n        //~^ cmp_owned\n\n        \"foo\".to_string() != x;\n        //~^ cmp_owned\n    }\n\n    let x = \"oh\";\n\n    with_to_string(x);\n\n    x != \"foo\".to_owned();\n    //~^ cmp_owned\n\n    x != String::from(\"foo\");\n    //~^ cmp_owned\n\n    42.to_string() == \"42\";\n\n    Foo.to_owned() == Foo;\n    //~^ cmp_owned\n\n    \"abc\".chars().filter(|c| c.to_owned() != 'X');\n    //~^ cmp_owned\n\n    \"abc\".chars().filter(|c| *c != 'X');\n}\n\nstruct Foo;\n\nimpl PartialEq for Foo {\n    // Allow this here, because it emits the lint\n    // without a suggestion. This is tested in\n    // `tests/ui/cmp_owned/without_suggestion.rs`\n    #[allow(clippy::cmp_owned)]\n    fn eq(&self, other: &Self) -> bool {\n        self.to_owned() == *other\n    }\n}\n\nimpl ToOwned for Foo {\n    type Owned = Bar;\n    fn to_owned(&self) -> Bar {\n        Bar\n    }\n}\n\n#[derive(PartialEq, Eq)]\nstruct Bar;\n\nimpl PartialEq<Foo> for Bar {\n    fn eq(&self, _: &Foo) -> bool {\n        true\n    }\n}\n\nimpl std::borrow::Borrow<Foo> for Bar {\n    fn borrow(&self) -> &Foo {\n        static FOO: Foo = Foo;\n        &FOO\n    }\n}\n\n#[derive(PartialEq, Eq)]\nstruct Baz;\n\nimpl ToOwned for Baz {\n    type Owned = Baz;\n    fn to_owned(&self) -> Baz {\n        Baz\n    }\n}\n\nfn issue_8103() {\n    let foo1 = String::from(\"foo\");\n    let _ = foo1 == \"foo\".to_owned();\n    //~^ cmp_owned\n    let foo2 = \"foo\";\n    let _ = foo1 == foo2.to_owned();\n    //~^ cmp_owned\n}\n\nmacro_rules! issue16322_macro_generator {\n    ($locale:ident) => {\n        mod $locale {\n            macro_rules! _make {\n                ($token:tt) => {\n                    stringify!($token)\n                };\n            }\n\n            pub(crate) use _make;\n        }\n\n        macro_rules! t {\n            ($token:tt) => {\n                crate::$locale::_make!($token)\n            };\n        }\n    };\n}\n\nissue16322_macro_generator!(de);\n\nfn issue16322(item: String) {\n    if item == t!(frohes_neu_Jahr).to_string() {\n        //~^ cmp_owned\n        println!(\"Ja!\");\n    }\n}\n\nfn issue16458() {\n    macro_rules! m {\n        () => {\n            \"\"\n        };\n    }\n\n    macro_rules! partly_comes_from_macro {\n        ($i:ident: $ty:ty, $def:expr) => {\n            let _ = {\n                let res = <$ty>::default() == $def;\n                let _i: $ty = $def;\n                res\n            };\n        };\n    }\n\n    partly_comes_from_macro! {\n        required_version: String, m!().to_string()\n    }\n\n    macro_rules! all_comes_from_macro {\n        ($($i:ident: $ty:ty, $def:expr);+ $(;)*) => {\n            $(\n                let _ = {\n                    let res = <$ty>::default() == \"$def\".to_string();\n                    //~^ cmp_owned\n                    let _i: $ty = $def;\n                    res\n                };\n            )+\n        };\n    }\n    all_comes_from_macro! {\n        required_version: String, m!().to_string();\n    }\n}\n\nfn issue16564(path: std::path::PathBuf) {\n    const ROOT: &str = \"root\";\n    if path != std::path::PathBuf::from(ROOT) {\n        //~^ cmp_owned\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/cmp_owned/with_suggestion.stderr",
    "content": "error: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:5:14\n   |\nLL |         x != \"foo\".to_string();\n   |              ^^^^^^^^^^^^^^^^^ help: try: `\"foo\"`\n   |\n   = note: `-D clippy::cmp-owned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:8:9\n   |\nLL |         \"foo\".to_string() != x;\n   |         ^^^^^^^^^^^^^^^^^ help: try: `\"foo\"`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:16:10\n   |\nLL |     x != \"foo\".to_owned();\n   |          ^^^^^^^^^^^^^^^^ help: try: `\"foo\"`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:19:10\n   |\nLL |     x != String::from(\"foo\");\n   |          ^^^^^^^^^^^^^^^^^^^ help: try: `\"foo\"`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:24:5\n   |\nLL |     Foo.to_owned() == Foo;\n   |     ^^^^^^^^^^^^^^ help: try: `Foo`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:27:30\n   |\nLL |     \"abc\".chars().filter(|c| c.to_owned() != 'X');\n   |                              ^^^^^^^^^^^^ help: try: `*c`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:80:21\n   |\nLL |     let _ = foo1 == \"foo\".to_owned();\n   |                     ^^^^^^^^^^^^^^^^ help: try: `\"foo\"`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:83:21\n   |\nLL |     let _ = foo1 == foo2.to_owned();\n   |                     ^^^^^^^^^^^^^^^ help: try: `foo2`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:110:16\n   |\nLL |     if item == t!(frohes_neu_Jahr).to_string() {\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t!(frohes_neu_Jahr)`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:141:51\n   |\nLL |                       let res = <$ty>::default() == \"$def\".to_string();\n   |                                                     ^^^^^^^^^^^^^^^^^^ help: try: `\"$def\"`\n...\nLL | /     all_comes_from_macro! {\nLL | |         required_version: String, m!().to_string();\nLL | |     }\n   | |_____- in this macro invocation\n   |\n   = note: this error originates in the macro `all_comes_from_macro` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/with_suggestion.rs:156:16\n   |\nLL |     if path != std::path::PathBuf::from(ROOT) {\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `*ROOT`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/cmp_owned/without_suggestion.rs",
    "content": "#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::implicit_clone)]\n\nfn main() {\n    let x = &Baz;\n    let y = &Baz;\n    y.to_owned() == *x;\n    //~^ cmp_owned\n\n    let x = &&Baz;\n    let y = &Baz;\n    y.to_owned() == **x;\n    //~^ cmp_owned\n\n    let x = 0u32;\n    let y = U32Wrapper(x);\n    let _ = U32Wrapper::from(x) == y;\n}\n\nstruct Foo;\n\nimpl PartialEq for Foo {\n    fn eq(&self, other: &Self) -> bool {\n        self.to_owned() == *other\n        //~^ cmp_owned\n    }\n}\n\nimpl ToOwned for Foo {\n    type Owned = Bar;\n    fn to_owned(&self) -> Bar {\n        Bar\n    }\n}\n\n#[derive(PartialEq, Eq)]\nstruct Baz;\n\nimpl ToOwned for Baz {\n    type Owned = Baz;\n    fn to_owned(&self) -> Baz {\n        Baz\n    }\n}\n\n#[derive(PartialEq, Eq)]\nstruct Bar;\n\nimpl PartialEq<Foo> for Bar {\n    fn eq(&self, _: &Foo) -> bool {\n        true\n    }\n}\n\nimpl std::borrow::Borrow<Foo> for Bar {\n    fn borrow(&self) -> &Foo {\n        static FOO: Foo = Foo;\n        &FOO\n    }\n}\n\n#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]\nstruct U32Wrapper(u32);\nimpl From<u32> for U32Wrapper {\n    fn from(x: u32) -> Self {\n        Self(x)\n    }\n}\nimpl PartialEq<u32> for U32Wrapper {\n    fn eq(&self, other: &u32) -> bool {\n        self.0 == *other\n    }\n}\nimpl PartialEq<U32Wrapper> for u32 {\n    fn eq(&self, other: &U32Wrapper) -> bool {\n        *self == other.0\n    }\n}\n"
  },
  {
    "path": "tests/ui/cmp_owned/without_suggestion.stderr",
    "content": "error: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/without_suggestion.rs:7:5\n   |\nLL |     y.to_owned() == *x;\n   |     ^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating\n   |\n   = note: `-D clippy::cmp-owned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cmp_owned)]`\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/without_suggestion.rs:12:5\n   |\nLL |     y.to_owned() == **x;\n   |     ^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating\n\nerror: this creates an owned instance just for comparison\n  --> tests/ui/cmp_owned/without_suggestion.rs:24:9\n   |\nLL |         self.to_owned() == *other\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/coerce_container_to_any.fixed",
    "content": "#![warn(clippy::coerce_container_to_any)]\n\nuse std::any::Any;\n\nfn main() {\n    let mut x: Box<dyn Any> = Box::new(());\n    let ref_x = &x;\n\n    f(&*x);\n    //~^ coerce_container_to_any\n\n    f(&**ref_x);\n    //~^ coerce_container_to_any\n\n    let _: &dyn Any = &*x;\n    //~^ coerce_container_to_any\n\n    let _: &dyn Any = &*x;\n    //~^ coerce_container_to_any\n\n    let _: &mut dyn Any = &mut *x;\n    //~^ coerce_container_to_any\n\n    f(&42);\n    f(&Box::new(()));\n    f(&Box::new(Box::new(())));\n    let ref_x = &x;\n    f(&**ref_x);\n    f(&*x);\n    let _: &dyn Any = &*x;\n\n    // https://github.com/rust-lang/rust-clippy/issues/15045\n    #[allow(clippy::needless_borrow)]\n    (&x).downcast_ref::<()>().unwrap();\n}\n\nfn f(_: &dyn Any) {}\n"
  },
  {
    "path": "tests/ui/coerce_container_to_any.rs",
    "content": "#![warn(clippy::coerce_container_to_any)]\n\nuse std::any::Any;\n\nfn main() {\n    let mut x: Box<dyn Any> = Box::new(());\n    let ref_x = &x;\n\n    f(&x);\n    //~^ coerce_container_to_any\n\n    f(ref_x);\n    //~^ coerce_container_to_any\n\n    let _: &dyn Any = &x;\n    //~^ coerce_container_to_any\n\n    let _: &dyn Any = &mut x;\n    //~^ coerce_container_to_any\n\n    let _: &mut dyn Any = &mut x;\n    //~^ coerce_container_to_any\n\n    f(&42);\n    f(&Box::new(()));\n    f(&Box::new(Box::new(())));\n    let ref_x = &x;\n    f(&**ref_x);\n    f(&*x);\n    let _: &dyn Any = &*x;\n\n    // https://github.com/rust-lang/rust-clippy/issues/15045\n    #[allow(clippy::needless_borrow)]\n    (&x).downcast_ref::<()>().unwrap();\n}\n\nfn f(_: &dyn Any) {}\n"
  },
  {
    "path": "tests/ui/coerce_container_to_any.stderr",
    "content": "error: coercing `&std::boxed::Box<dyn std::any::Any>` to `&dyn Any`\n  --> tests/ui/coerce_container_to_any.rs:9:7\n   |\nLL |     f(&x);\n   |       ^^ help: consider dereferencing: `&*x`\n   |\n   = note: `-D clippy::coerce-container-to-any` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::coerce_container_to_any)]`\n\nerror: coercing `&std::boxed::Box<dyn std::any::Any>` to `&dyn Any`\n  --> tests/ui/coerce_container_to_any.rs:12:7\n   |\nLL |     f(ref_x);\n   |       ^^^^^ help: consider dereferencing: `&**ref_x`\n\nerror: coercing `&std::boxed::Box<dyn std::any::Any>` to `&dyn Any`\n  --> tests/ui/coerce_container_to_any.rs:15:23\n   |\nLL |     let _: &dyn Any = &x;\n   |                       ^^ help: consider dereferencing: `&*x`\n\nerror: coercing `&mut std::boxed::Box<dyn std::any::Any>` to `&dyn Any`\n  --> tests/ui/coerce_container_to_any.rs:18:23\n   |\nLL |     let _: &dyn Any = &mut x;\n   |                       ^^^^^^ help: consider dereferencing: `&*x`\n\nerror: coercing `&mut std::boxed::Box<dyn std::any::Any>` to `&mut dyn Any`\n  --> tests/ui/coerce_container_to_any.rs:21:27\n   |\nLL |     let _: &mut dyn Any = &mut x;\n   |                           ^^^^^^ help: consider dereferencing: `&mut *x`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/cognitive_complexity.rs",
    "content": "#![warn(clippy::cognitive_complexity)]\n#![allow(\n    clippy::eq_op,\n    clippy::needless_borrows_for_generic_args,\n    clippy::needless_return,\n    clippy::nonminimal_bool,\n    clippy::uninlined_format_args\n)]\n\n#[rustfmt::skip]\nfn main() {\n//~^ cognitive_complexity\n\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n    if true {\n        println!(\"a\");\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn kaboom() {\n    //~^ cognitive_complexity\n\n    let n = 0;\n    'a: for i in 0..20 {\n        'b: for j in i..20 {\n            for k in j..20 {\n                if k == 5 {\n                    break 'b;\n                }\n                if j == 3 && k == 6 {\n                    continue 'a;\n                }\n                if k == j {\n                    continue;\n                }\n                println!(\"bake\");\n            }\n        }\n        println!(\"cake\");\n    }\n}\n\nfn bloo() {\n    match 42 {\n        0 => println!(\"hi\"),\n        1 => println!(\"hai\"),\n        2 => println!(\"hey\"),\n        3 => println!(\"hallo\"),\n        4 => println!(\"hello\"),\n        5 => println!(\"salut\"),\n        6 => println!(\"good morning\"),\n        7 => println!(\"good evening\"),\n        8 => println!(\"good afternoon\"),\n        9 => println!(\"good night\"),\n        10 => println!(\"bonjour\"),\n        11 => println!(\"hej\"),\n        12 => println!(\"hej hej\"),\n        13 => println!(\"greetings earthling\"),\n        14 => println!(\"take us to you leader\"),\n        15 | 17 | 19 | 21 | 23 | 25 | 27 | 29 | 31 | 33 => println!(\"take us to you leader\"),\n        35 | 37 | 39 | 41 | 43 | 45 | 47 | 49 | 51 | 53 => println!(\"there is no undefined behavior\"),\n        55 | 57 | 59 | 61 | 63 | 65 | 67 | 69 | 71 | 73 => println!(\"I know borrow-fu\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n// Short circuiting operations don't increase the complexity of a function.\n// Note that the minimum complexity of a function is 1.\n#[clippy::cognitive_complexity = \"1\"]\nfn lots_of_short_circuits() -> bool {\n    true && false && true && false && true && false && true\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn lots_of_short_circuits2() -> bool {\n    true || false || true || false || true || false || true\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn baa() {\n    //~^ cognitive_complexity\n\n    let x = || match 99 {\n        //~^ cognitive_complexity\n        0 => 0,\n        1 => 1,\n        2 => 2,\n        4 => 4,\n        6 => 6,\n        9 => 9,\n        _ => 42,\n    };\n    if x() == 42 {\n        println!(\"x\");\n    } else {\n        println!(\"not x\");\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn bar() {\n    //~^ cognitive_complexity\n\n    match 99 {\n        0 => println!(\"hi\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n#[test]\n#[clippy::cognitive_complexity = \"1\"]\n/// Tests are usually complex but simple at the same time. `clippy::cognitive_complexity` used to\n/// give lots of false-positives in tests.\nfn dont_warn_on_tests() {\n    //~^ cognitive_complexity\n\n    match 99 {\n        0 => println!(\"hi\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn barr() {\n    //~^ cognitive_complexity\n\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => println!(\"bla\"),\n        2 | 3 => println!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn barr2() {\n    //~^ cognitive_complexity\n\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => println!(\"bla\"),\n        2 | 3 => println!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => println!(\"bla\"),\n        2 | 3 => println!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn barrr() {\n    //~^ cognitive_complexity\n\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => panic!(\"bla\"),\n        2 | 3 => println!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn barrr2() {\n    //~^ cognitive_complexity\n\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => panic!(\"bla\"),\n        2 | 3 => println!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => panic!(\"bla\"),\n        2 | 3 => println!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn barrrr() {\n    //~^ cognitive_complexity\n\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => println!(\"bla\"),\n        2 | 3 => panic!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn barrrr2() {\n    //~^ cognitive_complexity\n\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => println!(\"bla\"),\n        2 | 3 => panic!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n    match 99 {\n        0 => println!(\"hi\"),\n        1 => println!(\"bla\"),\n        2 | 3 => panic!(\"blub\"),\n        _ => println!(\"bye\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn cake() {\n    //~^ cognitive_complexity\n\n    if 4 == 5 {\n        println!(\"yea\");\n    } else {\n        panic!(\"meh\");\n    }\n    println!(\"whee\");\n}\n\n#[clippy::cognitive_complexity = \"1\"]\npub fn read_file(input_path: &str) -> String {\n    //~^ cognitive_complexity\n\n    use std::fs::File;\n    use std::io::{Read, Write};\n    use std::path::Path;\n    let mut file = match File::open(&Path::new(input_path)) {\n        Ok(f) => f,\n        Err(err) => {\n            panic!(\"Can't open {}: {}\", input_path, err);\n        },\n    };\n\n    let mut bytes = Vec::new();\n\n    match file.read_to_end(&mut bytes) {\n        Ok(..) => {},\n        Err(_) => {\n            panic!(\"Can't read {}\", input_path);\n        },\n    };\n\n    match String::from_utf8(bytes) {\n        Ok(contents) => contents,\n        Err(_) => {\n            panic!(\"{} is not UTF-8 encoded\", input_path);\n        },\n    }\n}\n\nenum Void {}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn void(void: Void) {\n    //~^ cognitive_complexity\n\n    if true {\n        match void {}\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn mcarton_sees_all() {\n    panic!(\"meh\");\n    panic!(\"möh\");\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn try_() -> Result<i32, &'static str> {\n    match 5 {\n        5 => Ok(5),\n        _ => return Err(\"bla\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn try_again() -> Result<i32, &'static str> {\n    let _ = Ok(42)?;\n    let _ = Ok(43)?;\n    let _ = Ok(44)?;\n    let _ = Ok(45)?;\n    let _ = Ok(46)?;\n    let _ = Ok(47)?;\n    let _ = Ok(48)?;\n    let _ = Ok(49)?;\n    match 5 {\n        5 => Ok(5),\n        _ => return Err(\"bla\"),\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn early() -> Result<i32, &'static str> {\n    return Ok(5);\n    return Ok(5);\n    return Ok(5);\n    return Ok(5);\n    return Ok(5);\n    return Ok(5);\n    return Ok(5);\n    return Ok(5);\n    return Ok(5);\n}\n\n#[rustfmt::skip]\n#[clippy::cognitive_complexity = \"1\"]\nfn early_ret() -> i32 {\n//~^ cognitive_complexity\n\n    let a = if true { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    let a = if a < 99 { 42 } else { return 0; };\n    match 5 {\n        5 => 5,\n        _ => return 6,\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nfn closures() {\n    let x = |a: i32, b: i32| -> i32 {\n        //~^ cognitive_complexity\n\n        if true {\n            println!(\"moo\");\n        }\n\n        a + b\n    };\n}\n\nstruct Moo;\n\n#[clippy::cognitive_complexity = \"1\"]\nimpl Moo {\n    fn moo(&self) {\n        //~^ cognitive_complexity\n\n        if true {\n            println!(\"moo\");\n        }\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nmod issue9300 {\n    async fn a() {\n        //~^ cognitive_complexity\n\n        let a = 0;\n        if a == 0 {}\n    }\n\n    pub struct S;\n    impl S {\n        pub async fn async_method() {\n            //~^ cognitive_complexity\n\n            let a = 0;\n            if a == 0 {}\n        }\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nmod issue14422 {\n    fn foo() {\n        //~^ cognitive_complexity\n        for _ in 0..10 {\n            println!(\"hello there\");\n        }\n    }\n\n    fn bar() {\n        //~^ cognitive_complexity\n        for _ in 0..10 {\n            println!(\"hello there\");\n        }\n        return;\n        return;\n    }\n}\n\n#[clippy::cognitive_complexity = \"1\"]\nmod attribute_stacking {\n    fn bad() {\n        //~^ cognitive_complexity\n        if true {\n            println!(\"a\");\n        }\n    }\n\n    #[clippy::cognitive_complexity = \"2\"]\n    fn ok() {\n        if true {\n            println!(\"a\");\n        }\n    }\n\n    // should revert to cognitive_complexity = \"1\"\n    fn bad_again() {\n        //~^ cognitive_complexity\n        if true {\n            println!(\"a\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/cognitive_complexity.stderr",
    "content": "error: the function has a cognitive complexity of (28/25)\n  --> tests/ui/cognitive_complexity.rs:11:4\n   |\nLL | fn main() {\n   |    ^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cognitive_complexity)]`\n\nerror: the function has a cognitive complexity of (7/1)\n  --> tests/ui/cognitive_complexity.rs:98:4\n   |\nLL | fn kaboom() {\n   |    ^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:158:4\n   |\nLL | fn baa() {\n   |    ^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:161:13\n   |\nLL |     let x = || match 99 {\n   |             ^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:179:4\n   |\nLL | fn bar() {\n   |    ^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:192:4\n   |\nLL | fn dont_warn_on_tests() {\n   |    ^^^^^^^^^^^^^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:202:4\n   |\nLL | fn barr() {\n   |    ^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (3/1)\n  --> tests/ui/cognitive_complexity.rs:214:4\n   |\nLL | fn barr2() {\n   |    ^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:232:4\n   |\nLL | fn barrr() {\n   |    ^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (3/1)\n  --> tests/ui/cognitive_complexity.rs:244:4\n   |\nLL | fn barrr2() {\n   |    ^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:262:4\n   |\nLL | fn barrrr() {\n   |    ^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (3/1)\n  --> tests/ui/cognitive_complexity.rs:274:4\n   |\nLL | fn barrrr2() {\n   |    ^^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:292:4\n   |\nLL | fn cake() {\n   |    ^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (4/1)\n  --> tests/ui/cognitive_complexity.rs:304:8\n   |\nLL | pub fn read_file(input_path: &str) -> String {\n   |        ^^^^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:337:4\n   |\nLL | fn void(void: Void) {\n   |    ^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (8/1)\n  --> tests/ui/cognitive_complexity.rs:390:4\n   |\nLL | fn early_ret() -> i32 {\n   |    ^^^^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:413:13\n   |\nLL |     let x = |a: i32, b: i32| -> i32 {\n   |             ^^^^^^^^^^^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:428:8\n   |\nLL |     fn moo(&self) {\n   |        ^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:439:14\n   |\nLL |     async fn a() {\n   |              ^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:448:22\n   |\nLL |         pub async fn async_method() {\n   |                      ^^^^^^^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:459:8\n   |\nLL |     fn foo() {\n   |        ^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:466:8\n   |\nLL |     fn bar() {\n   |        ^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:478:8\n   |\nLL |     fn bad() {\n   |        ^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: the function has a cognitive complexity of (2/1)\n  --> tests/ui/cognitive_complexity.rs:493:8\n   |\nLL |     fn bad_again() {\n   |        ^^^^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/cognitive_complexity_attr_used.rs",
    "content": "#![warn(unused, clippy::cognitive_complexity)]\n#![allow(unused_crate_dependencies)]\n\nfn main() {\n    kaboom();\n}\n\n#[clippy::cognitive_complexity = \"0\"]\nfn kaboom() {\n    //~^ cognitive_complexity\n\n    if 42 == 43 {\n        panic!();\n    } else if \"cake\" == \"lie\" {\n        println!(\"what?\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/cognitive_complexity_attr_used.stderr",
    "content": "error: the function has a cognitive complexity of (3/0)\n  --> tests/ui/cognitive_complexity_attr_used.rs:9:4\n   |\nLL | fn kaboom() {\n   |    ^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cognitive_complexity)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/collapsible_else_if.fixed",
    "content": "#![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_ifs)]\n#![warn(clippy::collapsible_else_if)]\n\n#[rustfmt::skip]\nfn main() {\n    let x = \"hello\";\n    let y = \"world\";\n    // Collapse `else { if .. }` to `else if ..`\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else if y == \"world\" {\n        println!(\"world!\")\n    }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else if let Some(42) = Some(42) {\n        println!(\"world!\")\n    }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else if y == \"world\" {\n        println!(\"world\")\n    }\n    else {\n        println!(\"!\")\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else if let Some(42) = Some(42) {\n        println!(\"world\")\n    }\n    else {\n        println!(\"!\")\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if let Some(42) = Some(42) {\n        print!(\"Hello \");\n    } else if let Some(42) = Some(42) {\n        println!(\"world\")\n    }\n    else {\n        println!(\"!\")\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if let Some(42) = Some(42) {\n        print!(\"Hello \");\n    } else if x == \"hello\" {\n        println!(\"world\")\n    }\n    else {\n        println!(\"!\")\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if let Some(42) = Some(42) {\n        print!(\"Hello \");\n    } else if let Some(42) = Some(42) {\n        println!(\"world\")\n    }\n    else {\n        println!(\"!\")\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        if y == \"world\" {\n            print!(\"Hello \");\n        } else {\n            println!(\"world\");\n        }\n    } else if let Some(42) = Some(42) {\n        println!(\"42\");\n    }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        #[cfg(not(roflol))]\n        if y == \"world\" {\n            println!(\"world!\")\n        }\n    }\n\n    if x == \"hello\" {\n        if y == \"world\" {\n            print!(\"Hello \");\n        } else {\n            println!(\"world\");\n        }\n    } else {\n        if let Some(42) = Some(42) {\n            println!(\"42\");\n        } else {\n            println!(\"!\");\n        }\n    }\n\n}\n\n#[rustfmt::skip]\nfn issue_7318() {\n    if true { println!(\"I've been resolved!\")\n    }else if false {}\n    //~^^^ collapsible_else_if\n}\n\nfn issue_13365() {\n    // ensure we fulfill `#[expect]`\n    if true {\n    } else {\n        #[expect(clippy::collapsible_else_if)]\n        if false {}\n    }\n}\n\nfn issue14799() {\n    use std::ops::ControlFlow;\n\n    let c: ControlFlow<_, ()> = ControlFlow::Break(Some(42));\n    if let ControlFlow::Break(Some(_)) = c {\n        todo!();\n    } else {\n        #[cfg(target_os = \"freebsd\")]\n        todo!();\n\n        if let ControlFlow::Break(None) = c {\n            todo!();\n        } else {\n            todo!();\n        }\n    }\n}\n\nfn in_parens() {\n    let x = \"hello\";\n    let y = \"world\";\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else if y == \"world\" { println!(\"world\") } else { println!(\"!\") }\n    //~^^^ collapsible_else_if\n}\n\nfn in_brackets() {\n    let x = \"hello\";\n    let y = \"world\";\n\n    // There is no lint when the inner `if` is in a block.\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        { if y == \"world\" { println!(\"world\") } else { println!(\"!\") } }\n    }\n}\n"
  },
  {
    "path": "tests/ui/collapsible_else_if.rs",
    "content": "#![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_ifs)]\n#![warn(clippy::collapsible_else_if)]\n\n#[rustfmt::skip]\nfn main() {\n    let x = \"hello\";\n    let y = \"world\";\n    // Collapse `else { if .. }` to `else if ..`\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        if y == \"world\" {\n            println!(\"world!\")\n        }\n    }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        if let Some(42) = Some(42) {\n            println!(\"world!\")\n        }\n    }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        if y == \"world\" {\n            println!(\"world\")\n        }\n        else {\n            println!(\"!\")\n        }\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        if let Some(42) = Some(42) {\n            println!(\"world\")\n        }\n        else {\n            println!(\"!\")\n        }\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if let Some(42) = Some(42) {\n        print!(\"Hello \");\n    } else {\n        if let Some(42) = Some(42) {\n            println!(\"world\")\n        }\n        else {\n            println!(\"!\")\n        }\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if let Some(42) = Some(42) {\n        print!(\"Hello \");\n    } else {\n        if x == \"hello\" {\n            println!(\"world\")\n        }\n        else {\n            println!(\"!\")\n        }\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if let Some(42) = Some(42) {\n        print!(\"Hello \");\n    } else {\n        if let Some(42) = Some(42) {\n            println!(\"world\")\n        }\n        else {\n            println!(\"!\")\n        }\n    }\n    //~^^^^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        if y == \"world\" {\n            print!(\"Hello \");\n        } else {\n            println!(\"world\");\n        }\n    } else {\n        if let Some(42) = Some(42) {\n            println!(\"42\");\n        }\n    }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        #[cfg(not(roflol))]\n        if y == \"world\" {\n            println!(\"world!\")\n        }\n    }\n\n    if x == \"hello\" {\n        if y == \"world\" {\n            print!(\"Hello \");\n        } else {\n            println!(\"world\");\n        }\n    } else {\n        if let Some(42) = Some(42) {\n            println!(\"42\");\n        } else {\n            println!(\"!\");\n        }\n    }\n\n}\n\n#[rustfmt::skip]\nfn issue_7318() {\n    if true { println!(\"I've been resolved!\")\n    }else{\n        if false {}\n    }\n    //~^^^ collapsible_else_if\n}\n\nfn issue_13365() {\n    // ensure we fulfill `#[expect]`\n    if true {\n    } else {\n        #[expect(clippy::collapsible_else_if)]\n        if false {}\n    }\n}\n\nfn issue14799() {\n    use std::ops::ControlFlow;\n\n    let c: ControlFlow<_, ()> = ControlFlow::Break(Some(42));\n    if let ControlFlow::Break(Some(_)) = c {\n        todo!();\n    } else {\n        #[cfg(target_os = \"freebsd\")]\n        todo!();\n\n        if let ControlFlow::Break(None) = c {\n            todo!();\n        } else {\n            todo!();\n        }\n    }\n}\n\nfn in_parens() {\n    let x = \"hello\";\n    let y = \"world\";\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        (if y == \"world\" { println!(\"world\") } else { println!(\"!\") })\n    }\n    //~^^^ collapsible_else_if\n}\n\nfn in_brackets() {\n    let x = \"hello\";\n    let y = \"world\";\n\n    // There is no lint when the inner `if` is in a block.\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        { if y == \"world\" { println!(\"world\") } else { println!(\"!\") } }\n    }\n}\n"
  },
  {
    "path": "tests/ui/collapsible_else_if.stderr",
    "content": "error: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:11:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if y == \"world\" {\nLL | |             println!(\"world!\")\nLL | |         }\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::collapsible-else-if` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_else_if)]`\nhelp: collapse nested if block\n   |\nLL ~     } else if y == \"world\" {\nLL +         println!(\"world!\")\nLL +     }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:20:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if let Some(42) = Some(42) {\nLL | |             println!(\"world!\")\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } else if let Some(42) = Some(42) {\nLL +         println!(\"world!\")\nLL +     }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:29:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if y == \"world\" {\nLL | |             println!(\"world\")\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } else if y == \"world\" {\nLL +         println!(\"world\")\nLL +     }\nLL +     else {\nLL +         println!(\"!\")\nLL +     }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:41:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if let Some(42) = Some(42) {\nLL | |             println!(\"world\")\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } else if let Some(42) = Some(42) {\nLL +         println!(\"world\")\nLL +     }\nLL +     else {\nLL +         println!(\"!\")\nLL +     }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:53:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if let Some(42) = Some(42) {\nLL | |             println!(\"world\")\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } else if let Some(42) = Some(42) {\nLL +         println!(\"world\")\nLL +     }\nLL +     else {\nLL +         println!(\"!\")\nLL +     }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:65:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if x == \"hello\" {\nLL | |             println!(\"world\")\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } else if x == \"hello\" {\nLL +         println!(\"world\")\nLL +     }\nLL +     else {\nLL +         println!(\"!\")\nLL +     }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:77:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if let Some(42) = Some(42) {\nLL | |             println!(\"world\")\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } else if let Some(42) = Some(42) {\nLL +         println!(\"world\")\nLL +     }\nLL +     else {\nLL +         println!(\"!\")\nLL +     }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:93:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if let Some(42) = Some(42) {\nLL | |             println!(\"42\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } else if let Some(42) = Some(42) {\nLL +         println!(\"42\");\nLL +     }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:128:10\n   |\nLL |       }else{\n   |  __________^\nLL | |         if false {}\nLL | |     }\n   | |_____^ help: collapse nested if block: `if false {}`\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui/collapsible_else_if.rs:167:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         (if y == \"world\" { println!(\"world\") } else { println!(\"!\") })\nLL | |     }\n   | |_____^ help: collapse nested if block: `if y == \"world\" { println!(\"world\") } else { println!(\"!\") }`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/collapsible_else_if_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::collapsible_else_if)]\n\nfn issue_13365() {\n    // in the following examples, we won't lint because of the comments,\n    // so the the `expect` will be unfulfilled\n    if true {\n    } else {\n        // some other text before\n        #[expect(clippy::collapsible_else_if)]\n        if false {}\n    }\n    //~^^^ ERROR: this lint expectation is unfulfilled\n\n    if true {\n    } else {\n        #[expect(clippy::collapsible_else_if)]\n        // some other text after\n        if false {}\n    }\n    //~^^^^ ERROR: this lint expectation is unfulfilled\n}\n"
  },
  {
    "path": "tests/ui/collapsible_else_if_unfixable.stderr",
    "content": "error: this lint expectation is unfulfilled\n  --> tests/ui/collapsible_else_if_unfixable.rs:10:18\n   |\nLL |         #[expect(clippy::collapsible_else_if)]\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D unfulfilled-lint-expectations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`\n\nerror: this lint expectation is unfulfilled\n  --> tests/ui/collapsible_else_if_unfixable.rs:17:18\n   |\nLL |         #[expect(clippy::collapsible_else_if)]\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/collapsible_if.fixed",
    "content": "#![allow(\n    clippy::assertions_on_constants,\n    clippy::equatable_if_let,\n    clippy::needless_ifs,\n    clippy::nonminimal_bool,\n    clippy::eq_op,\n    clippy::redundant_pattern_matching\n)]\n\n#[rustfmt::skip]\n#[warn(clippy::collapsible_if)]\nfn main() {\n    let x = \"hello\";\n    let y = \"world\";\n    if x == \"hello\"\n        && y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_if\n\n    if (x == \"hello\" || x == \"world\")\n        && (y == \"world\" || y == \"hello\") {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" && x == \"world\"\n        && (y == \"world\" || y == \"hello\") {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_if\n\n    if (x == \"hello\" || x == \"world\")\n        && y == \"world\" && y == \"hello\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" && x == \"world\"\n        && y == \"world\" && y == \"hello\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_if\n\n    if 42 == 1337\n        && 'a' != 'A' {\n            println!(\"world!\")\n        }\n    //~^^^^^ collapsible_if\n\n    // Works because any if with an else statement cannot be collapsed.\n    if x == \"hello\" {\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    } else {\n        println!(\"Not Hello world\");\n    }\n\n    if x == \"hello\" {\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        } else {\n            println!(\"Hello something else\");\n        }\n    }\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n        if y == \"world\" {\n            println!(\"world!\")\n        }\n    }\n\n    if true {\n    } else {\n        assert!(true); // assert! is just an `if`\n    }\n\n    if x == \"hello\"\n        && y == \"world\" { // Collapsible\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        // Not collapsible\n        if let Some(42) = Some(42) {\n            println!(\"world!\")\n        }\n    }\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        // Not collapsible\n        if y == \"world\" {\n            println!(\"world!\")\n        }\n    }\n\n    fn truth() -> bool { true }\n\n    // Fix #5962\n    if matches!(true, true)\n        && matches!(true, true) {}\n    //~^^^ collapsible_if\n\n    // Issue #9375\n    if matches!(true, true) && truth()\n        && matches!(true, true) {}\n    //~^^^ collapsible_if\n\n    if true {\n        #[cfg(not(teehee))]\n        if true {\n            println!(\"Hello world!\");\n        }\n    }\n\n    if true\n        && true {\n            println!(\"No comment, linted\");\n        }\n    //~^^^^^ collapsible_if\n\n    if true {\n        // Do not collapse because of this comment\n        if true {\n            println!(\"Hello world!\");\n        }\n    }\n}\n\n#[rustfmt::skip]\nfn layout_check() -> u32 {\n    if true\n        && true {\n        }\n        // This is a comment, do not collapse code to it\n    ; 3\n    //~^^^^^ collapsible_if\n}\n\nfn issue13365() {\n    // all the `expect`s that we should fulfill\n    if true {\n        #[expect(clippy::collapsible_if)]\n        if true {}\n    }\n\n    if true {\n        #[expect(clippy::style)]\n        if true {}\n    }\n\n    if true {\n        #[expect(clippy::all)]\n        if true {}\n    }\n}\n\nfn issue14722() {\n    let x = if true {\n        Some(1)\n    } else {\n        if true {\n            println!(\"Some debug information\");\n        };\n        None\n    };\n}\n\nfn issue14799() {\n    if true {\n        #[cfg(target_os = \"freebsd\")]\n        todo!();\n\n        if true {}\n    };\n}\n\nfn in_parens() {\n    if true\n        && true {\n            println!(\"In parens, linted\");\n        }\n    //~^^^^^ collapsible_if\n}\n\nfn in_brackets() {\n    if true {\n        {\n            if true {\n                println!(\"In brackets, not linted\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/collapsible_if.rs",
    "content": "#![allow(\n    clippy::assertions_on_constants,\n    clippy::equatable_if_let,\n    clippy::needless_ifs,\n    clippy::nonminimal_bool,\n    clippy::eq_op,\n    clippy::redundant_pattern_matching\n)]\n\n#[rustfmt::skip]\n#[warn(clippy::collapsible_if)]\nfn main() {\n    let x = \"hello\";\n    let y = \"world\";\n    if x == \"hello\" {\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" || x == \"world\" {\n        if y == \"world\" || y == \"hello\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" && x == \"world\" {\n        if y == \"world\" || y == \"hello\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" || x == \"world\" {\n        if y == \"world\" && y == \"hello\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" && x == \"world\" {\n        if y == \"world\" && y == \"hello\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    if 42 == 1337 {\n        if 'a' != 'A' {\n            println!(\"world!\")\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    // Works because any if with an else statement cannot be collapsed.\n    if x == \"hello\" {\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    } else {\n        println!(\"Not Hello world\");\n    }\n\n    if x == \"hello\" {\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        } else {\n            println!(\"Hello something else\");\n        }\n    }\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n        if y == \"world\" {\n            println!(\"world!\")\n        }\n    }\n\n    if true {\n    } else {\n        assert!(true); // assert! is just an `if`\n    }\n\n    if x == \"hello\" {\n        if y == \"world\" { // Collapsible\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        // Not collapsible\n        if let Some(42) = Some(42) {\n            println!(\"world!\")\n        }\n    }\n\n    if x == \"hello\" {\n        print!(\"Hello \");\n    } else {\n        // Not collapsible\n        if y == \"world\" {\n            println!(\"world!\")\n        }\n    }\n\n    fn truth() -> bool { true }\n\n    // Fix #5962\n    if matches!(true, true) {\n        if matches!(true, true) {}\n    }\n    //~^^^ collapsible_if\n\n    // Issue #9375\n    if matches!(true, true) && truth() {\n        if matches!(true, true) {}\n    }\n    //~^^^ collapsible_if\n\n    if true {\n        #[cfg(not(teehee))]\n        if true {\n            println!(\"Hello world!\");\n        }\n    }\n\n    if true {\n        if true {\n            println!(\"No comment, linted\");\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    if true {\n        // Do not collapse because of this comment\n        if true {\n            println!(\"Hello world!\");\n        }\n    }\n}\n\n#[rustfmt::skip]\nfn layout_check() -> u32 {\n    if true {\n        if true {\n        }\n        // This is a comment, do not collapse code to it\n    }; 3\n    //~^^^^^ collapsible_if\n}\n\nfn issue13365() {\n    // all the `expect`s that we should fulfill\n    if true {\n        #[expect(clippy::collapsible_if)]\n        if true {}\n    }\n\n    if true {\n        #[expect(clippy::style)]\n        if true {}\n    }\n\n    if true {\n        #[expect(clippy::all)]\n        if true {}\n    }\n}\n\nfn issue14722() {\n    let x = if true {\n        Some(1)\n    } else {\n        if true {\n            println!(\"Some debug information\");\n        };\n        None\n    };\n}\n\nfn issue14799() {\n    if true {\n        #[cfg(target_os = \"freebsd\")]\n        todo!();\n\n        if true {}\n    };\n}\n\nfn in_parens() {\n    if true {\n        (if true {\n            println!(\"In parens, linted\");\n        })\n    }\n    //~^^^^^ collapsible_if\n}\n\nfn in_brackets() {\n    if true {\n        {\n            if true {\n                println!(\"In brackets, not linted\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/collapsible_if.stderr",
    "content": "error: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:15:5\n   |\nLL | /     if x == \"hello\" {\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::collapsible-if` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]`\nhelp: collapse nested if block\n   |\nLL ~     if x == \"hello\"\nLL ~         && y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:22:5\n   |\nLL | /     if x == \"hello\" || x == \"world\" {\nLL | |         if y == \"world\" || y == \"hello\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if (x == \"hello\" || x == \"world\") {\nLL ~         && (y == \"world\" || y == \"hello\") {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:29:5\n   |\nLL | /     if x == \"hello\" && x == \"world\" {\nLL | |         if y == \"world\" || y == \"hello\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if x == \"hello\" && x == \"world\"\nLL ~         && (y == \"world\" || y == \"hello\") {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:36:5\n   |\nLL | /     if x == \"hello\" || x == \"world\" {\nLL | |         if y == \"world\" && y == \"hello\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if (x == \"hello\" || x == \"world\") {\nLL ~         && y == \"world\" && y == \"hello\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:43:5\n   |\nLL | /     if x == \"hello\" && x == \"world\" {\nLL | |         if y == \"world\" && y == \"hello\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if x == \"hello\" && x == \"world\"\nLL ~         && y == \"world\" && y == \"hello\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:50:5\n   |\nLL | /     if 42 == 1337 {\nLL | |         if 'a' != 'A' {\nLL | |             println!(\"world!\")\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if 42 == 1337\nLL ~         && 'a' != 'A' {\nLL |             println!(\"world!\")\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:86:5\n   |\nLL | /     if x == \"hello\" {\nLL | |         if y == \"world\" { // Collapsible\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if x == \"hello\"\nLL ~         && y == \"world\" { // Collapsible\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:114:5\n   |\nLL | /     if matches!(true, true) {\nLL | |         if matches!(true, true) {}\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if matches!(true, true)\nLL ~         && matches!(true, true) {}\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:120:5\n   |\nLL | /     if matches!(true, true) && truth() {\nLL | |         if matches!(true, true) {}\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if matches!(true, true) && truth()\nLL ~         && matches!(true, true) {}\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:132:5\n   |\nLL | /     if true {\nLL | |         if true {\nLL | |             println!(\"No comment, linted\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if true\nLL ~         && true {\nLL |             println!(\"No comment, linted\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:149:5\n   |\nLL | /     if true {\nLL | |         if true {\n...  |\nLL | |     }; 3\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if true\nLL ~         && true {\nLL |         }\nLL |         // This is a comment, do not collapse code to it\nLL ~     ; 3\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if.rs:196:5\n   |\nLL | /     if true {\nLL | |         (if true {\nLL | |             println!(\"In parens, linted\");\nLL | |         })\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if true\nLL ~         && true {\nLL |             println!(\"In parens, linted\");\nLL ~         }\n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/collapsible_if_let_chains.edition2024.fixed",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n//@[edition2021] check-pass\n\n#![warn(clippy::collapsible_if)]\n\nfn main() {\n    if let Some(a) = Some(3) {\n        // with comment, so do not lint\n        if let Some(b) = Some(4) {\n            let _ = a + b;\n        }\n    }\n\n    //~[edition2024]v collapsible_if\n    if let Some(a) = Some(3)\n        && let Some(b) = Some(4) {\n            let _ = a + b;\n        }\n\n    //~[edition2024]v collapsible_if\n    if let Some(a) = Some(3)\n        && a + 1 == 4 {\n            let _ = a;\n        }\n\n    //~[edition2024]v collapsible_if\n    if Some(3) == Some(4).map(|x| x - 1)\n        && let Some(b) = Some(4) {\n            let _ = b;\n        }\n\n    fn truth() -> bool {\n        true\n    }\n\n    // Prefix:\n    //~[edition2024]v collapsible_if\n    if let 0 = 1\n        && truth() {}\n\n    // Suffix:\n    //~[edition2024]v collapsible_if\n    if truth()\n        && let 0 = 1 {}\n\n    // Midfix:\n    //~[edition2024]vvv collapsible_if\n    //~[edition2024]v collapsible_if\n    if truth()\n        && let 0 = 1\n            && truth() {}\n}\n\n#[clippy::msrv = \"1.87.0\"]\nfn msrv_1_87() {\n    if let 0 = 1 {\n        if true {}\n    }\n}\n\n#[clippy::msrv = \"1.88.0\"]\nfn msrv_1_88() {\n    //~[edition2024]v collapsible_if\n    if let 0 = 1\n        && true {}\n}\n"
  },
  {
    "path": "tests/ui/collapsible_if_let_chains.edition2024.stderr",
    "content": "error: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if_let_chains.rs:17:5\n   |\nLL | /     if let Some(a) = Some(3) {\nLL | |         if let Some(b) = Some(4) {\nLL | |             let _ = a + b;\nLL | |         }\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::collapsible-if` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]`\nhelp: collapse nested if block\n   |\nLL ~     if let Some(a) = Some(3)\nLL ~         && let Some(b) = Some(4) {\nLL |             let _ = a + b;\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if_let_chains.rs:24:5\n   |\nLL | /     if let Some(a) = Some(3) {\nLL | |         if a + 1 == 4 {\nLL | |             let _ = a;\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if let Some(a) = Some(3)\nLL ~         && a + 1 == 4 {\nLL |             let _ = a;\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if_let_chains.rs:31:5\n   |\nLL | /     if Some(3) == Some(4).map(|x| x - 1) {\nLL | |         if let Some(b) = Some(4) {\nLL | |             let _ = b;\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if Some(3) == Some(4).map(|x| x - 1)\nLL ~         && let Some(b) = Some(4) {\nLL |             let _ = b;\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if_let_chains.rs:43:5\n   |\nLL | /     if let 0 = 1 {\nLL | |         if truth() {}\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if let 0 = 1\nLL ~         && truth() {}\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if_let_chains.rs:49:5\n   |\nLL | /     if truth() {\nLL | |         if let 0 = 1 {}\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if truth()\nLL ~         && let 0 = 1 {}\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if_let_chains.rs:56:5\n   |\nLL | /     if truth() {\nLL | |         if let 0 = 1 {\nLL | |             if truth() {}\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if truth()\nLL ~         && let 0 = 1 {\nLL |             if truth() {}\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if_let_chains.rs:57:9\n   |\nLL | /         if let 0 = 1 {\nLL | |             if truth() {}\nLL | |         }\n   | |_________^\n   |\nhelp: collapse nested if block\n   |\nLL ~         if let 0 = 1\nLL ~             && truth() {}\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui/collapsible_if_let_chains.rs:73:5\n   |\nLL | /     if let 0 = 1 {\nLL | |         if true {}\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if let 0 = 1\nLL ~         && true {}\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/collapsible_if_let_chains.rs",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n//@[edition2021] check-pass\n\n#![warn(clippy::collapsible_if)]\n\nfn main() {\n    if let Some(a) = Some(3) {\n        // with comment, so do not lint\n        if let Some(b) = Some(4) {\n            let _ = a + b;\n        }\n    }\n\n    //~[edition2024]v collapsible_if\n    if let Some(a) = Some(3) {\n        if let Some(b) = Some(4) {\n            let _ = a + b;\n        }\n    }\n\n    //~[edition2024]v collapsible_if\n    if let Some(a) = Some(3) {\n        if a + 1 == 4 {\n            let _ = a;\n        }\n    }\n\n    //~[edition2024]v collapsible_if\n    if Some(3) == Some(4).map(|x| x - 1) {\n        if let Some(b) = Some(4) {\n            let _ = b;\n        }\n    }\n\n    fn truth() -> bool {\n        true\n    }\n\n    // Prefix:\n    //~[edition2024]v collapsible_if\n    if let 0 = 1 {\n        if truth() {}\n    }\n\n    // Suffix:\n    //~[edition2024]v collapsible_if\n    if truth() {\n        if let 0 = 1 {}\n    }\n\n    // Midfix:\n    //~[edition2024]vvv collapsible_if\n    //~[edition2024]v collapsible_if\n    if truth() {\n        if let 0 = 1 {\n            if truth() {}\n        }\n    }\n}\n\n#[clippy::msrv = \"1.87.0\"]\nfn msrv_1_87() {\n    if let 0 = 1 {\n        if true {}\n    }\n}\n\n#[clippy::msrv = \"1.88.0\"]\nfn msrv_1_88() {\n    //~[edition2024]v collapsible_if\n    if let 0 = 1 {\n        if true {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/collapsible_if_unfixable.rs",
    "content": "//@ no-rustfix\n#![warn(clippy::collapsible_if)]\n\nfn issue13365() {\n    // in the following examples, we won't lint because of the comments,\n    // so the the `expect` will be unfulfilled\n    if true {\n        // don't collapsible because of this comment\n        #[expect(clippy::collapsible_if)]\n        if true {}\n    }\n    //~^^^ ERROR: this lint expectation is unfulfilled\n\n    if true {\n        #[expect(clippy::collapsible_if)]\n        // don't collapsible because of this comment\n        if true {}\n    }\n    //~^^^^ ERROR: this lint expectation is unfulfilled\n}\n"
  },
  {
    "path": "tests/ui/collapsible_if_unfixable.stderr",
    "content": "error: this lint expectation is unfulfilled\n  --> tests/ui/collapsible_if_unfixable.rs:9:18\n   |\nLL |         #[expect(clippy::collapsible_if)]\n   |                  ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D unfulfilled-lint-expectations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`\n\nerror: this lint expectation is unfulfilled\n  --> tests/ui/collapsible_if_unfixable.rs:15:18\n   |\nLL |         #[expect(clippy::collapsible_if)]\n   |                  ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/collapsible_match.rs",
    "content": "#![warn(clippy::collapsible_match)]\n#![allow(\n    clippy::collapsible_if,\n    clippy::equatable_if_let,\n    clippy::needless_return,\n    clippy::no_effect,\n    clippy::single_match,\n    clippy::uninlined_format_args,\n    clippy::let_unit_value\n)]\n\nfn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>) {\n    // match without block\n    match res_opt {\n        Ok(val) => match val {\n            //~^ collapsible_match\n            Some(n) => foo(n),\n            _ => return,\n        },\n        _ => return,\n    }\n\n    // match with block\n    match res_opt {\n        Ok(val) => match val {\n            //~^ collapsible_match\n            Some(n) => foo(n),\n            _ => return,\n        },\n        _ => return,\n    }\n\n    // if let, if let\n    if let Ok(val) = res_opt {\n        if let Some(n) = val {\n            //~^ collapsible_match\n\n            take(n);\n        }\n    }\n\n    // if let else, if let else\n    if let Ok(val) = res_opt {\n        if let Some(n) = val {\n            //~^ collapsible_match\n\n            take(n);\n        } else {\n            return;\n        }\n    } else {\n        return;\n    }\n\n    // if let, match\n    if let Ok(val) = res_opt {\n        match val {\n            //~^ collapsible_match\n            Some(n) => foo(n),\n            _ => (),\n        }\n    }\n\n    // match, if let\n    match res_opt {\n        Ok(val) => {\n            if let Some(n) = val {\n                //~^ collapsible_match\n\n                take(n);\n            }\n        },\n        _ => {},\n    }\n\n    // if let else, match\n    if let Ok(val) = res_opt {\n        match val {\n            //~^ collapsible_match\n            Some(n) => foo(n),\n            _ => return,\n        }\n    } else {\n        return;\n    }\n\n    // match, if let else\n    match res_opt {\n        Ok(val) => {\n            if let Some(n) = val {\n                //~^ collapsible_match\n\n                take(n);\n            } else {\n                return;\n            }\n        },\n        _ => return,\n    }\n\n    // None in inner match same as outer wild branch\n    match res_opt {\n        Ok(val) => match val {\n            //~^ collapsible_match\n            Some(n) => foo(n),\n            None => return,\n        },\n        _ => return,\n    }\n\n    // None in outer match same as inner wild branch\n    match opt_opt {\n        Some(val) => match val {\n            //~^ collapsible_match\n            Some(n) => foo(n),\n            _ => return,\n        },\n        None => return,\n    }\n}\n\nfn negative_cases(res_opt: Result<Option<u32>, String>, res_res: Result<Result<u32, String>, String>) {\n    while let Some(x) = make() {\n        if let Some(1) = x {\n            todo!();\n        }\n    }\n    // no wild pattern in outer match\n    match res_opt {\n        Ok(val) => match val {\n            Some(n) => foo(n),\n            _ => return,\n        },\n        Err(_) => return,\n    }\n\n    // inner branch is not wild or None\n    match res_res {\n        Ok(val) => match val {\n            Ok(n) => foo(n),\n            Err(_) => return,\n        },\n        _ => return,\n    }\n\n    // statement before inner match\n    match res_opt {\n        Ok(val) => {\n            \"hi buddy\";\n            match val {\n                Some(n) => foo(n),\n                _ => return,\n            }\n        },\n        _ => return,\n    }\n\n    // statement after inner match\n    match res_opt {\n        Ok(val) => {\n            match val {\n                Some(n) => foo(n),\n                _ => return,\n            }\n            \"hi buddy\";\n        },\n        _ => return,\n    }\n\n    // wild branches do not match\n    match res_opt {\n        Ok(val) => match val {\n            Some(n) => foo(n),\n            _ => {\n                \"sup\";\n                return;\n            },\n        },\n        _ => return,\n    }\n\n    // binding used in if guard\n    match res_opt {\n        Ok(val) if val.is_some() => match val {\n            Some(n) => foo(n),\n            _ => return,\n        },\n        _ => return,\n    }\n\n    // binding used in inner match body\n    match res_opt {\n        Ok(val) => match val {\n            Some(_) => take(val),\n            _ => return,\n        },\n        _ => return,\n    }\n\n    // if guard on inner match\n    {\n        match res_opt {\n            Ok(val) => match val {\n                Some(n) if make() => foo(n),\n                _ => return,\n            },\n            _ => return,\n        }\n        match res_opt {\n            Ok(val) => match val {\n                _ => make(),\n                _ if make() => return,\n            },\n            _ => return,\n        }\n    }\n\n    // differing macro contexts\n    {\n        macro_rules! mac {\n            ($val:ident) => {\n                match $val {\n                    Some(n) => foo(n),\n                    _ => return,\n                }\n            };\n        }\n        match res_opt {\n            Ok(val) => mac!(val),\n            _ => return,\n        }\n    }\n\n    // OR pattern\n    enum E<T> {\n        A(T),\n        B(T),\n        C(T),\n    };\n    match make::<E<Option<u32>>>() {\n        E::A(val) | E::B(val) => match val {\n            Some(n) => foo(n),\n            _ => return,\n        },\n        _ => return,\n    }\n    #[clippy::msrv = \"1.52.0\"]\n    let _ = match make::<Option<E<u32>>>() {\n        Some(val) => match val {\n            E::A(val) | E::B(val) => foo(val),\n            _ => return,\n        },\n        _ => return,\n    };\n    #[clippy::msrv = \"1.53.0\"]\n    let _ = match make::<Option<E<u32>>>() {\n        Some(val) => match val {\n            //~^ collapsible_match\n            E::A(val) | E::B(val) => foo(val),\n            _ => return,\n        },\n        _ => return,\n    };\n    if let Ok(val) = res_opt {\n        if let Some(n) = val {\n            let _ = || {\n                // usage in closure\n                println!(\"{:?}\", val);\n            };\n        }\n    }\n    let _: &dyn std::any::Any = match &Some(Some(1)) {\n        Some(e) => match e {\n            Some(e) => e,\n            e => e,\n        },\n        // else branch looks the same but the binding is different\n        e => e,\n    };\n}\n\npub enum Issue9647 {\n    A { a: Option<Option<u8>>, b: () },\n    B,\n}\n\npub fn test_1(x: Issue9647) {\n    if let Issue9647::A { a, .. } = x {\n        if let Some(u) = a {\n            //~^ collapsible_match\n\n            println!(\"{u:?}\")\n        }\n    }\n}\n\npub fn test_2(x: Issue9647) {\n    if let Issue9647::A { a: Some(a), .. } = x {\n        if let Some(u) = a {\n            //~^ collapsible_match\n\n            println!(\"{u}\")\n        }\n    }\n}\n\nmod issue_13287 {\n    enum Token {\n        Name,\n        Other,\n    }\n\n    struct Error {\n        location: u32,\n        token: Option<Token>,\n    }\n\n    fn struct_field_pat_with_binding_mode(err: Option<Error>) {\n        if let Some(Error { ref token, .. }) = err {\n            if let Some(Token::Name) = token {\n                //~^ collapsible_match\n                println!(\"token used as a ref\");\n            }\n        }\n    }\n}\n\npub fn issue_14155() {\n    let mut arr = [\"a\", \"b\", \"c\"];\n    if let Some(last) = arr.last() {\n        match *last {\n            //~^ collapsible_match\n            \"a\" | \"b\" => {\n                unimplemented!()\n            },\n            _ => (),\n        }\n    }\n\n    if let Some(last) = arr.last() {\n        match &last {\n            //~^ collapsible_match\n            &&\"a\" | &&\"b\" => {\n                unimplemented!()\n            },\n            _ => (),\n        }\n    }\n\n    if let Some(mut last) = arr.last_mut() {\n        match &mut last {\n            //~^ collapsible_match\n            &mut &mut \"a\" | &mut &mut \"b\" => {\n                unimplemented!()\n            },\n            _ => (),\n        }\n    }\n\n    const NULL_PTR: *const &'static str = std::ptr::null();\n    if let Some(last) = arr.last() {\n        match &raw const *last {\n            NULL_PTR => unimplemented!(),\n            _ => (),\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/14281\nfn lint_emitted_at_right_node(opt: Option<Result<u64, String>>) {\n    let n = match opt {\n        #[expect(clippy::collapsible_match)]\n        Some(n) => match n {\n            Ok(n) => n,\n            _ => return,\n        },\n        None => return,\n    };\n}\n\nfn make<T>() -> T {\n    unimplemented!()\n}\n\nfn foo<T, U>(t: T) -> U {\n    unimplemented!()\n}\n\nfn take<T>(t: T) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/collapsible_match.stderr",
    "content": "error: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match.rs:15:20\n   |\nLL |           Ok(val) => match val {\n   |  ____________________^\nLL | |\nLL | |             Some(n) => foo(n),\nLL | |             _ => return,\nLL | |         },\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:15:12\n   |\nLL |         Ok(val) => match val {\n   |            ^^^ replace this binding\nLL |\nLL |             Some(n) => foo(n),\n   |             ^^^^^^^ with this pattern\n   = note: `-D clippy::collapsible-match` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]`\n\nerror: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match.rs:25:20\n   |\nLL |           Ok(val) => match val {\n   |  ____________________^\nLL | |\nLL | |             Some(n) => foo(n),\nLL | |             _ => return,\nLL | |         },\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:25:12\n   |\nLL |         Ok(val) => match val {\n   |            ^^^ replace this binding\nLL |\nLL |             Some(n) => foo(n),\n   |             ^^^^^^^ with this pattern\n\nerror: this `if let` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:35:9\n   |\nLL | /         if let Some(n) = val {\nLL | |\nLL | |\nLL | |             take(n);\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:34:15\n   |\nLL |     if let Ok(val) = res_opt {\n   |               ^^^ replace this binding\nLL |         if let Some(n) = val {\n   |                ^^^^^^^ with this pattern\n\nerror: this `if let` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:44:9\n   |\nLL | /         if let Some(n) = val {\nLL | |\nLL | |\nLL | |             take(n);\nLL | |         } else {\nLL | |             return;\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:43:15\n   |\nLL |     if let Ok(val) = res_opt {\n   |               ^^^ replace this binding\nLL |         if let Some(n) = val {\n   |                ^^^^^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:57:9\n   |\nLL | /         match val {\nLL | |\nLL | |             Some(n) => foo(n),\nLL | |             _ => (),\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:56:15\n   |\nLL |     if let Ok(val) = res_opt {\n   |               ^^^ replace this binding\n...\nLL |             Some(n) => foo(n),\n   |             ^^^^^^^ with this pattern\n\nerror: this `if let` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match.rs:67:13\n   |\nLL | /             if let Some(n) = val {\nLL | |\nLL | |\nLL | |                 take(n);\nLL | |             }\n   | |_____________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:66:12\n   |\nLL |         Ok(val) => {\n   |            ^^^ replace this binding\nLL |             if let Some(n) = val {\n   |                    ^^^^^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:78:9\n   |\nLL | /         match val {\nLL | |\nLL | |             Some(n) => foo(n),\nLL | |             _ => return,\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:77:15\n   |\nLL |     if let Ok(val) = res_opt {\n   |               ^^^ replace this binding\n...\nLL |             Some(n) => foo(n),\n   |             ^^^^^^^ with this pattern\n\nerror: this `if let` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match.rs:90:13\n   |\nLL | /             if let Some(n) = val {\nLL | |\nLL | |\nLL | |                 take(n);\nLL | |             } else {\nLL | |                 return;\nLL | |             }\n   | |_____________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:89:12\n   |\nLL |         Ok(val) => {\n   |            ^^^ replace this binding\nLL |             if let Some(n) = val {\n   |                    ^^^^^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match.rs:103:20\n   |\nLL |           Ok(val) => match val {\n   |  ____________________^\nLL | |\nLL | |             Some(n) => foo(n),\nLL | |             None => return,\nLL | |         },\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:103:12\n   |\nLL |         Ok(val) => match val {\n   |            ^^^ replace this binding\nLL |\nLL |             Some(n) => foo(n),\n   |             ^^^^^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match.rs:113:22\n   |\nLL |           Some(val) => match val {\n   |  ______________________^\nLL | |\nLL | |             Some(n) => foo(n),\nLL | |             _ => return,\nLL | |         },\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:113:14\n   |\nLL |         Some(val) => match val {\n   |              ^^^ replace this binding\nLL |\nLL |             Some(n) => foo(n),\n   |             ^^^^^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match.rs:257:22\n   |\nLL |           Some(val) => match val {\n   |  ______________________^\nLL | |\nLL | |             E::A(val) | E::B(val) => foo(val),\nLL | |             _ => return,\nLL | |         },\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:257:14\n   |\nLL |         Some(val) => match val {\n   |              ^^^ replace this binding\nLL |\nLL |             E::A(val) | E::B(val) => foo(val),\n   |             ^^^^^^^^^^^^^^^^^^^^^ with this pattern\n\nerror: this `if let` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:289:9\n   |\nLL | /         if let Some(u) = a {\nLL | |\nLL | |\nLL | |             println!(\"{u:?}\")\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:288:27\n   |\nLL |     if let Issue9647::A { a, .. } = x {\n   |                           ^ replace this binding\nLL |         if let Some(u) = a {\n   |                ^^^^^^^ with this pattern, prefixed by `a: `\n\nerror: this `if let` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:299:9\n   |\nLL | /         if let Some(u) = a {\nLL | |\nLL | |\nLL | |             println!(\"{u}\")\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:298:35\n   |\nLL |     if let Issue9647::A { a: Some(a), .. } = x {\n   |                                   ^ replace this binding\nLL |         if let Some(u) = a {\n   |                ^^^^^^^ with this pattern\n\nerror: this `if let` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:320:13\n   |\nLL | /             if let Some(Token::Name) = token {\nLL | |\nLL | |                 println!(\"token used as a ref\");\nLL | |             }\n   | |_____________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:319:29\n   |\nLL |         if let Some(Error { ref token, .. }) = err {\n   |                             ^^^^^^^^^ replace this binding\nLL |             if let Some(Token::Name) = token {\n   |                    ^^^^^^^^^^^^^^^^^ with this pattern, prefixed by `token: `\n\nerror: this `match` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:331:9\n   |\nLL | /         match *last {\nLL | |\nLL | |             \"a\" | \"b\" => {\nLL | |                 unimplemented!()\nLL | |             },\nLL | |             _ => (),\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:330:17\n   |\nLL |     if let Some(last) = arr.last() {\n   |                 ^^^^    ---------- use: `arr.last().copied()`\n   |                 |\n   |                 replace this binding\n...\nLL |             \"a\" | \"b\" => {\n   |             ^^^^^^^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:341:9\n   |\nLL | /         match &last {\nLL | |\nLL | |             &&\"a\" | &&\"b\" => {\nLL | |                 unimplemented!()\nLL | |             },\nLL | |             _ => (),\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:340:17\n   |\nLL |     if let Some(last) = arr.last() {\n   |                 ^^^^    ---------- use: `arr.last().as_ref()`\n   |                 |\n   |                 replace this binding\n...\nLL |             &&\"a\" | &&\"b\" => {\n   |             ^^^^^^^^^^^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `if let`\n  --> tests/ui/collapsible_match.rs:351:9\n   |\nLL | /         match &mut last {\nLL | |\nLL | |             &mut &mut \"a\" | &mut &mut \"b\" => {\nLL | |                 unimplemented!()\nLL | |             },\nLL | |             _ => (),\nLL | |         }\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match.rs:350:17\n   |\nLL |     if let Some(mut last) = arr.last_mut() {\n   |                 ^^^^^^^^    -------------- use: `arr.last_mut().as_mut()`\n   |                 |\n   |                 replace this binding\n...\nLL |             &mut &mut \"a\" | &mut &mut \"b\" => {\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ with this pattern\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/collapsible_match2.rs",
    "content": "#![warn(clippy::collapsible_match)]\n#![allow(\n    clippy::needless_return,\n    clippy::no_effect,\n    clippy::single_match,\n    clippy::needless_borrow\n)]\n\nfn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>) {\n    // if guards on outer match\n    {\n        match res_opt {\n            Ok(val) if make() => match val {\n                //~^ collapsible_match\n                Some(n) => foo(n),\n                _ => return,\n            },\n            _ => return,\n        }\n        match res_opt {\n            Ok(val) => match val {\n                //~^ collapsible_match\n                Some(n) => foo(n),\n                _ => return,\n            },\n            _ if make() => return,\n            _ => return,\n        }\n    }\n\n    // macro\n    {\n        macro_rules! mac {\n            ($outer:expr => $pat:pat, $e:expr => $inner_pat:pat, $then:expr) => {\n                match $outer {\n                    $pat => match $e {\n                        //~^ collapsible_match\n                        $inner_pat => $then,\n                        _ => return,\n                    },\n                    _ => return,\n                }\n            };\n        }\n        // Lint this since the patterns are not defined by the macro.\n        // Allows the lint to work on if_chain! for example.\n        // Fixing the lint requires knowledge of the specific macro, but we optimistically assume that\n        // there is still a better way to write this.\n        mac!(res_opt => Ok(val), val => Some(n), foo(n));\n    }\n\n    // deref reference value\n    match Some(&[1]) {\n        Some(s) => match *s {\n            //~^ collapsible_match\n            [n] => foo(n),\n            _ => (),\n        },\n        _ => (),\n    }\n\n    // ref pattern and deref\n    match Some(&[1]) {\n        Some(ref s) => match s {\n            //~^ collapsible_match\n            [n] => foo(n),\n            _ => (),\n        },\n        _ => (),\n    }\n}\n\nfn no_lint() {\n    // deref inner value (cannot pattern match with Vec)\n    match Some(vec![1]) {\n        Some(s) => match *s {\n            [n] => foo(n),\n            _ => (),\n        },\n        _ => (),\n    }\n}\n\nfn make<T>() -> T {\n    unimplemented!()\n}\n\nfn foo<T, U>(t: T) -> U {\n    unimplemented!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/collapsible_match2.stderr",
    "content": "error: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match2.rs:13:34\n   |\nLL |               Ok(val) if make() => match val {\n   |  __________________________________^\nLL | |\nLL | |                 Some(n) => foo(n),\nLL | |                 _ => return,\nLL | |             },\n   | |_____________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match2.rs:13:16\n   |\nLL |             Ok(val) if make() => match val {\n   |                ^^^ replace this binding\nLL |\nLL |                 Some(n) => foo(n),\n   |                 ^^^^^^^ with this pattern\n   = note: `-D clippy::collapsible-match` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]`\n\nerror: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match2.rs:21:24\n   |\nLL |               Ok(val) => match val {\n   |  ________________________^\nLL | |\nLL | |                 Some(n) => foo(n),\nLL | |                 _ => return,\nLL | |             },\n   | |_____________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match2.rs:21:16\n   |\nLL |             Ok(val) => match val {\n   |                ^^^ replace this binding\nLL |\nLL |                 Some(n) => foo(n),\n   |                 ^^^^^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match2.rs:36:29\n   |\nLL |                       $pat => match $e {\n   |  _____________________________^\nLL | |\nLL | |                         $inner_pat => $then,\nLL | |                         _ => return,\nLL | |                     },\n   | |_____________________^\n...\nLL |           mac!(res_opt => Ok(val), val => Some(n), foo(n));\n   |           ------------------------------------------------ in this macro invocation\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match2.rs:49:28\n   |\nLL |         mac!(res_opt => Ok(val), val => Some(n), foo(n));\n   |                            ^^^          ^^^^^^^ with this pattern\n   |                            |\n   |                            replace this binding\n   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match2.rs:54:20\n   |\nLL |           Some(s) => match *s {\n   |  ____________________^\nLL | |\nLL | |             [n] => foo(n),\nLL | |             _ => (),\nLL | |         },\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match2.rs:54:14\n   |\nLL |     match Some(&[1]) {\n   |           ---------- use: `Some(&[1]).copied()`\nLL |         Some(s) => match *s {\n   |              ^ replace this binding\nLL |\nLL |             [n] => foo(n),\n   |             ^^^ with this pattern\n\nerror: this `match` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match2.rs:64:24\n   |\nLL |           Some(ref s) => match s {\n   |  ________________________^\nLL | |\nLL | |             [n] => foo(n),\nLL | |             _ => (),\nLL | |         },\n   | |_________^\n   |\nhelp: the outer pattern can be modified to include the inner pattern\n  --> tests/ui/collapsible_match2.rs:64:14\n   |\nLL |         Some(ref s) => match s {\n   |              ^^^^^ replace this binding\nLL |\nLL |             [n] => foo(n),\n   |             ^^^ with this pattern\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/collapsible_match_fixable.fixed",
    "content": "#![warn(clippy::collapsible_match)]\n#![allow(clippy::single_match, clippy::redundant_guards)]\n\nfn issue16558() {\n    let opt = Some(1);\n    let _ = match opt {\n        Some(s)\n            if s == 1 => { s }\n            //~^ collapsible_match\n        ,\n        _ => 1,\n    };\n\n    match opt {\n        Some(s)\n            if s == 1 => {\n                //~^ collapsible_match\n                todo!()\n            },\n        _ => {},\n    };\n\n    let _ = match opt {\n        Some(s) if s > 2\n            && s == 1 => { s }\n            //~^ collapsible_match\n        ,\n        _ => 1,\n    };\n}\n"
  },
  {
    "path": "tests/ui/collapsible_match_fixable.rs",
    "content": "#![warn(clippy::collapsible_match)]\n#![allow(clippy::single_match, clippy::redundant_guards)]\n\nfn issue16558() {\n    let opt = Some(1);\n    let _ = match opt {\n        Some(s) => {\n            if s == 1 { s } else { 1 }\n            //~^ collapsible_match\n        },\n        _ => 1,\n    };\n\n    match opt {\n        Some(s) => {\n            (if s == 1 {\n                //~^ collapsible_match\n                todo!()\n            })\n        },\n        _ => {},\n    };\n\n    let _ = match opt {\n        Some(s) if s > 2 => {\n            if s == 1 { s } else { 1 }\n            //~^ collapsible_match\n        },\n        _ => 1,\n    };\n}\n"
  },
  {
    "path": "tests/ui/collapsible_match_fixable.stderr",
    "content": "error: this `if` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match_fixable.rs:8:13\n   |\nLL |             if s == 1 { s } else { 1 }\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::collapsible-match` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_match)]`\nhelp: collapse nested if block\n   |\nLL ~         Some(s)\nLL ~             if s == 1 => { s }\nLL |\nLL ~         ,\n   |\n\nerror: this `if` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match_fixable.rs:16:13\n   |\nLL | /             (if s == 1 {\nLL | |\nLL | |                 todo!()\nLL | |             })\n   | |______________^\n   |\nhelp: collapse nested if block\n   |\nLL ~         Some(s)\nLL ~             if s == 1 => {\nLL |\nLL |                 todo!()\nLL ~             },\n   |\n\nerror: this `if` can be collapsed into the outer `match`\n  --> tests/ui/collapsible_match_fixable.rs:26:13\n   |\nLL |             if s == 1 { s } else { 1 }\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: collapse nested if block\n   |\nLL ~         Some(s) if s > 2\nLL ~             && s == 1 => { s }\nLL |\nLL ~         ,\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/collapsible_str_replace.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::collapsible_str_replace)]\n\nfn get_filter() -> char {\n    'u'\n}\n\nfn main() {\n    let d = 'd';\n    let p = 'p';\n    let s = 's';\n    let u = 'u';\n    let l = \"l\";\n\n    let mut iter = [\"l\", \"z\"].iter();\n\n    // LINT CASES\n    let _ = \"hesuo worpd\".replace(['s', 'u'], \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace(['s', 'u'], l);\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace(['s', 'u', 'p'], \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\"\n        .replace(['s', 'u', 'p', 'd'], \"l\");\n\n    let _ = \"hesuo world\".replace([s, 'u'], \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace([s, 'u', 'p'], \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace([s, u, 'p'], \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace([s, u, p], \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worlp\".replace(['s', 'u'], \"l\").replace('p', \"d\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace('s', \"x\").replace(['u', 'p'], \"l\");\n    //~^ collapsible_str_replace\n\n    // Note: Future iterations could lint `replace(|c| matches!(c, \"su\" | 'd' | 'p'), \"l\")`\n    let _ = \"hesudo worpd\".replace(\"su\", \"l\").replace(['d', 'p'], \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesudo worpd\".replace([d, 'p'], \"l\").replace(\"su\", \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo world\".replace([get_filter(), 's'], \"l\");\n    //~^ collapsible_str_replace\n\n    // NO LINT CASES\n    let _ = \"hesuo world\".replace('s', \"l\").replace('u', \"p\");\n\n    let _ = \"hesuo worpd\".replace('s', \"l\").replace('p', l);\n\n    let _ = \"hesudo worpd\".replace('d', \"l\").replace(\"su\", \"l\").replace('p', \"l\");\n\n    // Note: Future iterations of `collapsible_str_replace` might lint this and combine to `[s, u, p]`\n    let _ = \"hesuo worpd\".replace([s, u], \"l\").replace([u, p], \"l\");\n\n    let _ = \"hesuo worpd\".replace(['s', 'u'], \"l\").replace(['u', 'p'], \"l\");\n\n    let _ = \"hesuo worpd\".replace('s', \"l\").replace(['u', 'p'], \"l\");\n\n    let _ = \"hesuo worpd\".replace(['s', 'u', 'p'], \"l\").replace('r', \"l\");\n\n    let _ = \"hesuo worpd\".replace(['s', 'u', 'p'], l).replace('r', l);\n\n    let _ = \"hesuo worpd\".replace(['s', u, 'p'], \"l\").replace('r', \"l\");\n\n    let _ = \"hesuo worpd\".replace([s, u], \"l\").replace(p, \"l\");\n\n    // Regression test\n    let _ = \"hesuo worpd\"\n        .replace('u', iter.next().unwrap())\n        .replace('s', iter.next().unwrap());\n}\n\n#[clippy::msrv = \"1.57\"]\nfn msrv_1_57() {\n    let _ = \"\".replace('a', \"1.57\").replace('b', \"1.57\");\n}\n\n#[clippy::msrv = \"1.58\"]\nfn msrv_1_58() {\n    let _ = \"\".replace(['a', 'b'], \"1.58\");\n    //~^ collapsible_str_replace\n}\n"
  },
  {
    "path": "tests/ui/collapsible_str_replace.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::collapsible_str_replace)]\n\nfn get_filter() -> char {\n    'u'\n}\n\nfn main() {\n    let d = 'd';\n    let p = 'p';\n    let s = 's';\n    let u = 'u';\n    let l = \"l\";\n\n    let mut iter = [\"l\", \"z\"].iter();\n\n    // LINT CASES\n    let _ = \"hesuo worpd\".replace('s', \"l\").replace('u', \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace('s', l).replace('u', l);\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace('s', \"l\").replace('u', \"l\").replace('p', \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\"\n        .replace('s', \"l\")\n        //~^ collapsible_str_replace\n        .replace('u', \"l\")\n        .replace('p', \"l\")\n        .replace('d', \"l\");\n\n    let _ = \"hesuo world\".replace(s, \"l\").replace('u', \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace(s, \"l\").replace('u', \"l\").replace('p', \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace(s, \"l\").replace(u, \"l\").replace('p', \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace(s, \"l\").replace(u, \"l\").replace(p, \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worlp\".replace('s', \"l\").replace('u', \"l\").replace('p', \"d\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo worpd\".replace('s', \"x\").replace('u', \"l\").replace('p', \"l\");\n    //~^ collapsible_str_replace\n\n    // Note: Future iterations could lint `replace(|c| matches!(c, \"su\" | 'd' | 'p'), \"l\")`\n    let _ = \"hesudo worpd\".replace(\"su\", \"l\").replace('d', \"l\").replace('p', \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesudo worpd\".replace(d, \"l\").replace('p', \"l\").replace(\"su\", \"l\");\n    //~^ collapsible_str_replace\n\n    let _ = \"hesuo world\".replace(get_filter(), \"l\").replace('s', \"l\");\n    //~^ collapsible_str_replace\n\n    // NO LINT CASES\n    let _ = \"hesuo world\".replace('s', \"l\").replace('u', \"p\");\n\n    let _ = \"hesuo worpd\".replace('s', \"l\").replace('p', l);\n\n    let _ = \"hesudo worpd\".replace('d', \"l\").replace(\"su\", \"l\").replace('p', \"l\");\n\n    // Note: Future iterations of `collapsible_str_replace` might lint this and combine to `[s, u, p]`\n    let _ = \"hesuo worpd\".replace([s, u], \"l\").replace([u, p], \"l\");\n\n    let _ = \"hesuo worpd\".replace(['s', 'u'], \"l\").replace(['u', 'p'], \"l\");\n\n    let _ = \"hesuo worpd\".replace('s', \"l\").replace(['u', 'p'], \"l\");\n\n    let _ = \"hesuo worpd\".replace(['s', 'u', 'p'], \"l\").replace('r', \"l\");\n\n    let _ = \"hesuo worpd\".replace(['s', 'u', 'p'], l).replace('r', l);\n\n    let _ = \"hesuo worpd\".replace(['s', u, 'p'], \"l\").replace('r', \"l\");\n\n    let _ = \"hesuo worpd\".replace([s, u], \"l\").replace(p, \"l\");\n\n    // Regression test\n    let _ = \"hesuo worpd\"\n        .replace('u', iter.next().unwrap())\n        .replace('s', iter.next().unwrap());\n}\n\n#[clippy::msrv = \"1.57\"]\nfn msrv_1_57() {\n    let _ = \"\".replace('a', \"1.57\").replace('b', \"1.57\");\n}\n\n#[clippy::msrv = \"1.58\"]\nfn msrv_1_58() {\n    let _ = \"\".replace('a', \"1.58\").replace('b', \"1.58\");\n    //~^ collapsible_str_replace\n}\n"
  },
  {
    "path": "tests/ui/collapsible_str_replace.stderr",
    "content": "error: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:18:27\n   |\nLL |     let _ = \"hesuo worpd\".replace('s', \"l\").replace('u', \"l\");\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], \"l\")`\n   |\n   = note: `-D clippy::collapsible-str-replace` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_str_replace)]`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:21:27\n   |\nLL |     let _ = \"hesuo worpd\".replace('s', l).replace('u', l);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], l)`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:24:27\n   |\nLL |     let _ = \"hesuo worpd\".replace('s', \"l\").replace('u', \"l\").replace('p', \"l\");\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u', 'p'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:28:10\n   |\nLL |           .replace('s', \"l\")\n   |  __________^\nLL | |\nLL | |         .replace('u', \"l\")\nLL | |         .replace('p', \"l\")\nLL | |         .replace('d', \"l\");\n   | |__________________________^ help: replace with: `replace(['s', 'u', 'p', 'd'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:34:27\n   |\nLL |     let _ = \"hesuo world\".replace(s, \"l\").replace('u', \"l\");\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:37:27\n   |\nLL |     let _ = \"hesuo worpd\".replace(s, \"l\").replace('u', \"l\").replace('p', \"l\");\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, 'u', 'p'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:40:27\n   |\nLL |     let _ = \"hesuo worpd\".replace(s, \"l\").replace(u, \"l\").replace('p', \"l\");\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, 'p'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:43:27\n   |\nLL |     let _ = \"hesuo worpd\".replace(s, \"l\").replace(u, \"l\").replace(p, \"l\");\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([s, u, p], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:46:27\n   |\nLL |     let _ = \"hesuo worlp\".replace('s', \"l\").replace('u', \"l\").replace('p', \"d\");\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['s', 'u'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:49:45\n   |\nLL |     let _ = \"hesuo worpd\".replace('s', \"x\").replace('u', \"l\").replace('p', \"l\");\n   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['u', 'p'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:53:47\n   |\nLL |     let _ = \"hesudo worpd\".replace(\"su\", \"l\").replace('d', \"l\").replace('p', \"l\");\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['d', 'p'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:56:28\n   |\nLL |     let _ = \"hesudo worpd\".replace(d, \"l\").replace('p', \"l\").replace(\"su\", \"l\");\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([d, 'p'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:59:27\n   |\nLL |     let _ = \"hesuo world\".replace(get_filter(), \"l\").replace('s', \"l\");\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace([get_filter(), 's'], \"l\")`\n\nerror: used consecutive `str::replace` call\n  --> tests/ui/collapsible_str_replace.rs:97:16\n   |\nLL |     let _ = \"\".replace('a', \"1.58\").replace('b', \"1.58\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `replace(['a', 'b'], \"1.58\")`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/collection_is_never_read.rs",
    "content": "#![allow(unused, clippy::useless_vec)]\n#![warn(clippy::collection_is_never_read)]\n\nuse std::collections::{HashMap, HashSet};\n\nfn main() {}\n\nfn not_a_collection() {\n    // TODO: Expand `collection_is_never_read` beyond collections?\n    let mut x = 10; // Ok\n    x += 1;\n}\n\nfn no_access_at_all() {\n    // Other lints should catch this.\n    let x = vec![1, 2, 3]; // Ok\n}\n\nfn write_without_read() {\n    // The main use case for `collection_is_never_read`.\n    let mut x = HashMap::new();\n    //~^ collection_is_never_read\n\n    x.insert(1, 2);\n}\n\nfn read_without_write() {\n    let mut x = vec![1, 2, 3]; // Ok\n    let _ = x.len();\n}\n\nfn write_and_read() {\n    let mut x = vec![1, 2, 3]; // Ok\n    x.push(4);\n    let _ = x.len();\n}\n\nfn write_after_read() {\n    // TODO: Warn here, but this requires more extensive data flow analysis.\n    let mut x = vec![1, 2, 3]; // Ok\n    let _ = x.len();\n    x.push(4); // Pointless\n}\n\nfn write_before_reassign() {\n    // TODO: Warn here, but this requires more extensive data flow analysis.\n    let mut x = HashMap::new(); // Ok\n    x.insert(1, 2); // Pointless\n    x = HashMap::new();\n    let _ = x.len();\n}\n\nfn read_in_closure() {\n    let mut x = HashMap::new(); // Ok\n    x.insert(1, 2);\n    let _ = || {\n        let _ = x.len();\n    };\n}\n\nfn write_in_closure() {\n    let mut x = vec![1, 2, 3];\n    //~^ collection_is_never_read\n\n    let _ = || {\n        x.push(4);\n    };\n}\n\nfn read_in_format() {\n    let mut x = HashMap::new(); // Ok\n    x.insert(1, 2);\n    format!(\"{x:?}\");\n}\n\nfn shadowing_1() {\n    let x = HashMap::<usize, usize>::new(); // Ok\n    let _ = x.len();\n    let mut x = HashMap::new();\n    //~^ collection_is_never_read\n\n    x.insert(1, 2);\n}\n\nfn shadowing_2() {\n    let mut x = HashMap::new();\n    //~^ collection_is_never_read\n\n    x.insert(1, 2);\n    let x = HashMap::<usize, usize>::new(); // Ok\n    let _ = x.len();\n}\n\n#[allow(clippy::let_unit_value)]\nfn fake_read_1() {\n    let mut x = vec![1, 2, 3];\n    //~^ collection_is_never_read\n\n    x.reverse();\n    let _: () = x.clear();\n}\n\nfn fake_read_2() {\n    let mut x = vec![1, 2, 3];\n    //~^ collection_is_never_read\n\n    x.reverse();\n    println!(\"{:?}\", x.push(5));\n}\n\nfn assignment() {\n    let mut x = vec![1, 2, 3];\n    //~^ collection_is_never_read\n\n    let y = vec![4, 5, 6]; // Ok\n    x = y;\n}\n\n#[allow(clippy::self_assignment)]\nfn self_assignment() {\n    let mut x = vec![1, 2, 3];\n    //~^ collection_is_never_read\n\n    x = x;\n}\n\nfn method_argument_but_not_target() {\n    struct MyStruct;\n    impl MyStruct {\n        fn my_method(&self, _argument: &[usize]) {}\n    }\n    let my_struct = MyStruct;\n\n    let mut x = vec![1, 2, 3]; // Ok\n    x.reverse();\n    my_struct.my_method(&x);\n}\n\nfn insert_is_not_a_read() {\n    let mut x = HashSet::new();\n    //~^ collection_is_never_read\n\n    x.insert(5);\n}\n\nfn insert_is_a_read() {\n    let mut x = HashSet::new(); // Ok\n    if x.insert(5) {\n        println!(\"5 was inserted\");\n    }\n}\n\nfn not_read_if_return_value_not_used() {\n    // `is_empty` does not modify the set, so it's a query. But since the return value is not used, the\n    // lint does not consider it a read here.\n    let x = vec![1, 2, 3];\n    //~^ collection_is_never_read\n\n    x.is_empty();\n}\n\nfn extension_traits() {\n    trait VecExt<T> {\n        fn method_with_side_effect(&self);\n        fn method_without_side_effect(&self);\n    }\n\n    impl<T> VecExt<T> for Vec<T> {\n        fn method_with_side_effect(&self) {\n            println!(\"my length: {}\", self.len());\n        }\n        fn method_without_side_effect(&self) {}\n    }\n\n    let x = vec![1, 2, 3]; // Ok\n    x.method_with_side_effect();\n\n    let y = vec![1, 2, 3]; // Ok (false negative)\n    y.method_without_side_effect();\n}\n\nfn function_argument() {\n    #[allow(clippy::ptr_arg)]\n    fn foo<T>(v: &Vec<T>) -> usize {\n        v.len()\n    }\n\n    let x = vec![1, 2, 3]; // Ok\n    foo(&x);\n}\n\nfn supported_types() {\n    let mut x = std::collections::BTreeMap::new();\n    //~^ collection_is_never_read\n\n    x.insert(true, 1);\n\n    let mut x = std::collections::BTreeSet::new();\n    //~^ collection_is_never_read\n\n    x.insert(1);\n\n    let mut x = std::collections::BinaryHeap::new();\n    //~^ collection_is_never_read\n\n    x.push(1);\n\n    let mut x = std::collections::HashMap::new();\n    //~^ collection_is_never_read\n\n    x.insert(1, 2);\n\n    let mut x = std::collections::HashSet::new();\n    //~^ collection_is_never_read\n\n    x.insert(1);\n\n    let mut x = std::collections::LinkedList::new();\n    //~^ collection_is_never_read\n\n    x.push_front(1);\n\n    let mut x = Some(true);\n    //~^ collection_is_never_read\n\n    x.insert(false);\n\n    let mut x = String::from(\"hello\");\n    //~^ collection_is_never_read\n\n    x.push('!');\n\n    let mut x = Vec::new();\n    //~^ collection_is_never_read\n\n    x.clear();\n    x.push(1);\n\n    let mut x = std::collections::VecDeque::new();\n    //~^ collection_is_never_read\n\n    x.push_front(1);\n}\n\nfn issue11783() {\n    struct Sender;\n    impl Sender {\n        fn send(&self, msg: String) -> Result<(), ()> {\n            // pretend to send message\n            println!(\"{msg}\");\n            Ok(())\n        }\n    }\n\n    let mut users: Vec<Sender> = vec![];\n    users.retain(|user| user.send(\"hello\".to_string()).is_ok());\n}\n"
  },
  {
    "path": "tests/ui/collection_is_never_read.stderr",
    "content": "error: collection is never read\n  --> tests/ui/collection_is_never_read.rs:21:5\n   |\nLL |     let mut x = HashMap::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::collection-is-never-read` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collection_is_never_read)]`\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:62:5\n   |\nLL |     let mut x = vec![1, 2, 3];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:79:5\n   |\nLL |     let mut x = HashMap::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:86:5\n   |\nLL |     let mut x = HashMap::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:96:5\n   |\nLL |     let mut x = vec![1, 2, 3];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:104:5\n   |\nLL |     let mut x = vec![1, 2, 3];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:112:5\n   |\nLL |     let mut x = vec![1, 2, 3];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:121:5\n   |\nLL |     let mut x = vec![1, 2, 3];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:140:5\n   |\nLL |     let mut x = HashSet::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:156:5\n   |\nLL |     let x = vec![1, 2, 3];\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:193:5\n   |\nLL |     let mut x = std::collections::BTreeMap::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:198:5\n   |\nLL |     let mut x = std::collections::BTreeSet::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:203:5\n   |\nLL |     let mut x = std::collections::BinaryHeap::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:208:5\n   |\nLL |     let mut x = std::collections::HashMap::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:213:5\n   |\nLL |     let mut x = std::collections::HashSet::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:218:5\n   |\nLL |     let mut x = std::collections::LinkedList::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:223:5\n   |\nLL |     let mut x = Some(true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:228:5\n   |\nLL |     let mut x = String::from(\"hello\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:233:5\n   |\nLL |     let mut x = Vec::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: collection is never read\n  --> tests/ui/collection_is_never_read.rs:239:5\n   |\nLL |     let mut x = std::collections::VecDeque::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/comparison_chain.rs",
    "content": "//@no-rustfix: has placeholders\n#![allow(dead_code)]\n#![warn(clippy::comparison_chain)]\n\nfn a() {}\nfn b() {}\nfn c() {}\n\nfn f(x: u8, y: u8, z: u8) {\n    // Ignored: Only one branch\n    if x > y {\n        a()\n    }\n\n    // Ignored: Not all cases are covered\n    if x < y {\n        a()\n    } else if x > y {\n        b()\n    }\n\n    // Ignored: Only one explicit conditional\n    if x > y {\n        a()\n    } else {\n        b()\n    }\n\n    if x > y {\n        //~^ comparison_chain\n\n        a()\n    } else if x < y {\n        b()\n    } else {\n        c()\n    }\n\n    if x > y {\n        //~^ comparison_chain\n\n        a()\n    } else if y > x {\n        b()\n    } else {\n        c()\n    }\n\n    if x > 1 {\n        //~^ comparison_chain\n\n        a()\n    } else if x < 1 {\n        b()\n    } else if x == 1 {\n        c()\n    }\n\n    // Ignored: Binop args are not equivalent\n    if x > 1 {\n        a()\n    } else if y > 1 {\n        b()\n    } else {\n        c()\n    }\n\n    // Ignored: Binop args are not equivalent\n    if x > y {\n        a()\n    } else if x > z {\n        b()\n    } else if y > z {\n        c()\n    }\n\n    // Ignored: Not binary comparisons\n    if true {\n        a()\n    } else if false {\n        b()\n    } else {\n        c()\n    }\n}\n\n#[allow(clippy::float_cmp)]\nfn g(x: f64, y: f64, z: f64) {\n    // Ignored: f64 doesn't implement Ord\n    if x > y {\n        a()\n    } else if x < y {\n        b()\n    }\n\n    // Ignored: f64 doesn't implement Ord\n    if x > y {\n        a()\n    } else if x < y {\n        b()\n    } else {\n        c()\n    }\n\n    // Ignored: f64 doesn't implement Ord\n    if x > y {\n        a()\n    } else if y > x {\n        b()\n    } else {\n        c()\n    }\n\n    // Ignored: f64 doesn't implement Ord\n    if x > 1.0 {\n        a()\n    } else if x < 1.0 {\n        b()\n    } else if x == 1.0 {\n        c()\n    }\n}\n\nfn h<T: Ord>(x: T, y: T, z: T) {\n    // Ignored: Not all cases are covered\n    if x > y {\n        a()\n    } else if x < y {\n        b()\n    }\n\n    if x > y {\n        //~^ comparison_chain\n\n        a()\n    } else if x < y {\n        b()\n    } else {\n        c()\n    }\n\n    if x > y {\n        //~^ comparison_chain\n\n        a()\n    } else if y > x {\n        b()\n    } else {\n        c()\n    }\n}\n\n// The following uses should be ignored\nmod issue_5212 {\n    use super::{a, b, c};\n    fn foo() -> u8 {\n        21\n    }\n\n    fn same_operation_equals() {\n        // operands are fixed\n\n        if foo() == 42 {\n            a()\n        } else if foo() == 42 {\n            b()\n        }\n\n        if foo() == 42 {\n            a()\n        } else if foo() == 42 {\n            b()\n        } else {\n            c()\n        }\n\n        // operands are transposed\n\n        if foo() == 42 {\n            a()\n        } else if 42 == foo() {\n            b()\n        }\n    }\n\n    fn same_operation_not_equals() {\n        // operands are fixed\n\n        if foo() > 42 {\n            a()\n        } else if foo() > 42 {\n            b()\n        }\n\n        if foo() > 42 {\n            a()\n        } else if foo() > 42 {\n            b()\n        } else {\n            c()\n        }\n\n        if foo() < 42 {\n            a()\n        } else if foo() < 42 {\n            b()\n        }\n\n        if foo() < 42 {\n            a()\n        } else if foo() < 42 {\n            b()\n        } else {\n            c()\n        }\n    }\n}\n\nenum Sign {\n    Negative,\n    Positive,\n    Zero,\n}\n\nimpl Sign {\n    const fn sign_i8(n: i8) -> Self {\n        if n == 0 {\n            Sign::Zero\n        } else if n > 0 {\n            Sign::Positive\n        } else {\n            Sign::Negative\n        }\n    }\n}\n\nconst fn sign_i8(n: i8) -> Sign {\n    if n == 0 {\n        Sign::Zero\n    } else if n > 0 {\n        Sign::Positive\n    } else {\n        Sign::Negative\n    }\n}\n\nfn needs_parens() -> &'static str {\n    let (x, y) = (1, 2);\n    if x + 1 > y * 2 {\n        //~^ comparison_chain\n\n        \"aa\"\n    } else if x + 1 < y * 2 {\n        \"bb\"\n    } else {\n        \"cc\"\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/comparison_chain.stderr",
    "content": "error: `if` chain can be rewritten with `match`\n  --> tests/ui/comparison_chain.rs:29:5\n   |\nLL | /     if x > y {\nLL | |\nLL | |\nLL | |         a()\n...  |\nLL | |         c()\nLL | |     }\n   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`\n   |\n   = note: `-D clippy::comparison-chain` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::comparison_chain)]`\n\nerror: `if` chain can be rewritten with `match`\n  --> tests/ui/comparison_chain.rs:39:5\n   |\nLL | /     if x > y {\nLL | |\nLL | |\nLL | |         a()\n...  |\nLL | |         c()\nLL | |     }\n   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`\n\nerror: `if` chain can be rewritten with `match`\n  --> tests/ui/comparison_chain.rs:49:5\n   |\nLL | /     if x > 1 {\nLL | |\nLL | |\nLL | |         a()\n...  |\nLL | |         c()\nLL | |     }\n   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&1) {...}`\n\nerror: `if` chain can be rewritten with `match`\n  --> tests/ui/comparison_chain.rs:132:5\n   |\nLL | /     if x > y {\nLL | |\nLL | |\nLL | |         a()\n...  |\nLL | |         c()\nLL | |     }\n   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`\n\nerror: `if` chain can be rewritten with `match`\n  --> tests/ui/comparison_chain.rs:142:5\n   |\nLL | /     if x > y {\nLL | |\nLL | |\nLL | |         a()\n...  |\nLL | |         c()\nLL | |     }\n   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`\n\nerror: `if` chain can be rewritten with `match`\n  --> tests/ui/comparison_chain.rs:249:5\n   |\nLL | /     if x + 1 > y * 2 {\nLL | |\nLL | |\nLL | |         \"aa\"\n...  |\nLL | |         \"cc\"\nLL | |     }\n   | |_____^ help: consider rewriting the `if` chain with `match`: `match (x + 1).cmp(&(y * 2)) {...}`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/comparison_to_empty.fixed",
    "content": "#![warn(clippy::comparison_to_empty)]\n#![allow(clippy::borrow_deref_ref, clippy::needless_ifs, clippy::useless_vec)]\n\nfn main() {\n    // Disallow comparisons to empty\n    let s = String::new();\n    let _ = s.is_empty();\n    //~^ comparison_to_empty\n    let _ = !s.is_empty();\n    //~^ comparison_to_empty\n\n    let v = vec![0];\n    let _ = v.is_empty();\n    //~^ comparison_to_empty\n    let _ = !v.is_empty();\n    //~^ comparison_to_empty\n    if (*v).is_empty() {}\n    //~^ comparison_to_empty\n    let s = [0].as_slice();\n    if s.is_empty() {}\n    //~^ comparison_to_empty\n    if s.is_empty() {}\n    //~^ comparison_to_empty\n    if s.is_empty()\n    //~^ comparison_to_empty\n        && s.is_empty()\n    //~^ comparison_to_empty\n    {}\n\n    // Allow comparisons to non-empty\n    let s = String::new();\n    let _ = s == \" \";\n    let _ = s != \" \";\n\n    let v = vec![0];\n    let _ = v == [0];\n    let _ = v != [0];\n    if let [0] = &*v {}\n    let s = [0].as_slice();\n    if let [0] = s {}\n    if let [0] = &*s\n        && s == [0]\n    {}\n\n    // Also lint the `PartialEq` methods\n    let s = String::new();\n    let _ = s.is_empty();\n    //~^ comparison_to_empty\n    let _ = !s.is_empty();\n    //~^ comparison_to_empty\n    let v = vec![0];\n    let _ = v.is_empty();\n    //~^ comparison_to_empty\n    let _ = !v.is_empty();\n    //~^ comparison_to_empty\n}\n"
  },
  {
    "path": "tests/ui/comparison_to_empty.rs",
    "content": "#![warn(clippy::comparison_to_empty)]\n#![allow(clippy::borrow_deref_ref, clippy::needless_ifs, clippy::useless_vec)]\n\nfn main() {\n    // Disallow comparisons to empty\n    let s = String::new();\n    let _ = s == \"\";\n    //~^ comparison_to_empty\n    let _ = s != \"\";\n    //~^ comparison_to_empty\n\n    let v = vec![0];\n    let _ = v == [];\n    //~^ comparison_to_empty\n    let _ = v != [];\n    //~^ comparison_to_empty\n    if let [] = &*v {}\n    //~^ comparison_to_empty\n    let s = [0].as_slice();\n    if let [] = s {}\n    //~^ comparison_to_empty\n    if let [] = &*s {}\n    //~^ comparison_to_empty\n    if let [] = &*s\n    //~^ comparison_to_empty\n        && s == []\n    //~^ comparison_to_empty\n    {}\n\n    // Allow comparisons to non-empty\n    let s = String::new();\n    let _ = s == \" \";\n    let _ = s != \" \";\n\n    let v = vec![0];\n    let _ = v == [0];\n    let _ = v != [0];\n    if let [0] = &*v {}\n    let s = [0].as_slice();\n    if let [0] = s {}\n    if let [0] = &*s\n        && s == [0]\n    {}\n\n    // Also lint the `PartialEq` methods\n    let s = String::new();\n    let _ = s.eq(\"\");\n    //~^ comparison_to_empty\n    let _ = s.ne(\"\");\n    //~^ comparison_to_empty\n    let v = vec![0];\n    let _ = v.eq(&[]);\n    //~^ comparison_to_empty\n    let _ = v.ne(&[]);\n    //~^ comparison_to_empty\n}\n"
  },
  {
    "path": "tests/ui/comparison_to_empty.stderr",
    "content": "error: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:7:13\n   |\nLL |     let _ = s == \"\";\n   |             ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`\n   |\n   = note: `-D clippy::comparison-to-empty` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::comparison_to_empty)]`\n\nerror: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:9:13\n   |\nLL |     let _ = s != \"\";\n   |             ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:13:13\n   |\nLL |     let _ = v == [];\n   |             ^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:15:13\n   |\nLL |     let _ = v != [];\n   |             ^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()`\n\nerror: comparison to empty slice using `if let`\n  --> tests/ui/comparison_to_empty.rs:17:8\n   |\nLL |     if let [] = &*v {}\n   |        ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(*v).is_empty()`\n\nerror: comparison to empty slice using `if let`\n  --> tests/ui/comparison_to_empty.rs:20:8\n   |\nLL |     if let [] = s {}\n   |        ^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`\n\nerror: comparison to empty slice using `if let`\n  --> tests/ui/comparison_to_empty.rs:22:8\n   |\nLL |     if let [] = &*s {}\n   |        ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`\n\nerror: comparison to empty slice using `if let`\n  --> tests/ui/comparison_to_empty.rs:24:8\n   |\nLL |     if let [] = &*s\n   |        ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:26:12\n   |\nLL |         && s == []\n   |            ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:47:13\n   |\nLL |     let _ = s.eq(\"\");\n   |             ^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:49:13\n   |\nLL |     let _ = s.ne(\"\");\n   |             ^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:52:13\n   |\nLL |     let _ = v.eq(&[]);\n   |             ^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/comparison_to_empty.rs:54:13\n   |\nLL |     let _ = v.ne(&[]);\n   |             ^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/confusing_method_to_numeric_cast.fixed",
    "content": "#![feature(float_minimum_maximum)]\n#![warn(clippy::confusing_method_to_numeric_cast)]\n#![allow(function_casts_as_integer)]\n\nfn main() {\n    let _ = u16::MAX as usize; //~ confusing_method_to_numeric_cast\n    let _ = u16::MIN as usize; //~ confusing_method_to_numeric_cast\n    let _ = u16::MAX as usize; //~ confusing_method_to_numeric_cast\n    let _ = u16::MIN as usize; //~ confusing_method_to_numeric_cast\n\n    let _ = f32::MAX as usize; //~ confusing_method_to_numeric_cast\n    let _ = f32::MAX as usize; //~ confusing_method_to_numeric_cast\n    let _ = f32::MIN as usize; //~ confusing_method_to_numeric_cast\n    let _ = f32::MIN as usize; //~ confusing_method_to_numeric_cast\n}\n"
  },
  {
    "path": "tests/ui/confusing_method_to_numeric_cast.rs",
    "content": "#![feature(float_minimum_maximum)]\n#![warn(clippy::confusing_method_to_numeric_cast)]\n#![allow(function_casts_as_integer)]\n\nfn main() {\n    let _ = u16::max as usize; //~ confusing_method_to_numeric_cast\n    let _ = u16::min as usize; //~ confusing_method_to_numeric_cast\n    let _ = u16::max_value as usize; //~ confusing_method_to_numeric_cast\n    let _ = u16::min_value as usize; //~ confusing_method_to_numeric_cast\n\n    let _ = f32::maximum as usize; //~ confusing_method_to_numeric_cast\n    let _ = f32::max as usize; //~ confusing_method_to_numeric_cast\n    let _ = f32::minimum as usize; //~ confusing_method_to_numeric_cast\n    let _ = f32::min as usize; //~ confusing_method_to_numeric_cast\n}\n"
  },
  {
    "path": "tests/ui/confusing_method_to_numeric_cast.stderr",
    "content": "error: casting function pointer `u16::max` to `usize`\n  --> tests/ui/confusing_method_to_numeric_cast.rs:6:13\n   |\nLL |     let _ = u16::max as usize;\n   |             ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::confusing-method-to-numeric-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::confusing_method_to_numeric_cast)]`\nhelp: did you mean to use the associated constant?\n   |\nLL -     let _ = u16::max as usize;\nLL +     let _ = u16::MAX as usize;\n   |\n\nerror: casting function pointer `u16::min` to `usize`\n  --> tests/ui/confusing_method_to_numeric_cast.rs:7:13\n   |\nLL |     let _ = u16::min as usize;\n   |             ^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to use the associated constant?\n   |\nLL -     let _ = u16::min as usize;\nLL +     let _ = u16::MIN as usize;\n   |\n\nerror: casting function pointer `u16::max_value` to `usize`\n  --> tests/ui/confusing_method_to_numeric_cast.rs:8:13\n   |\nLL |     let _ = u16::max_value as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to use the associated constant?\n   |\nLL -     let _ = u16::max_value as usize;\nLL +     let _ = u16::MAX as usize;\n   |\n\nerror: casting function pointer `u16::min_value` to `usize`\n  --> tests/ui/confusing_method_to_numeric_cast.rs:9:13\n   |\nLL |     let _ = u16::min_value as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to use the associated constant?\n   |\nLL -     let _ = u16::min_value as usize;\nLL +     let _ = u16::MIN as usize;\n   |\n\nerror: casting function pointer `f32::maximum` to `usize`\n  --> tests/ui/confusing_method_to_numeric_cast.rs:11:13\n   |\nLL |     let _ = f32::maximum as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to use the associated constant?\n   |\nLL -     let _ = f32::maximum as usize;\nLL +     let _ = f32::MAX as usize;\n   |\n\nerror: casting function pointer `f32::max` to `usize`\n  --> tests/ui/confusing_method_to_numeric_cast.rs:12:13\n   |\nLL |     let _ = f32::max as usize;\n   |             ^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to use the associated constant?\n   |\nLL -     let _ = f32::max as usize;\nLL +     let _ = f32::MAX as usize;\n   |\n\nerror: casting function pointer `f32::minimum` to `usize`\n  --> tests/ui/confusing_method_to_numeric_cast.rs:13:13\n   |\nLL |     let _ = f32::minimum as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to use the associated constant?\n   |\nLL -     let _ = f32::minimum as usize;\nLL +     let _ = f32::MIN as usize;\n   |\n\nerror: casting function pointer `f32::min` to `usize`\n  --> tests/ui/confusing_method_to_numeric_cast.rs:14:13\n   |\nLL |     let _ = f32::min as usize;\n   |             ^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to use the associated constant?\n   |\nLL -     let _ = f32::min as usize;\nLL +     let _ = f32::MIN as usize;\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/const_comparisons.rs",
    "content": "#![allow(\n    unused,\n    clippy::identity_op,\n    clippy::manual_range_contains,\n    clippy::no_effect,\n    clippy::short_circuit_statement\n)]\n#![warn(clippy::impossible_comparisons, clippy::redundant_comparisons)]\n\nconst STATUS_BAD_REQUEST: u16 = 400;\nconst STATUS_SERVER_ERROR: u16 = 500;\n\nstruct Status {\n    code: u16,\n}\n\nimpl PartialEq<u16> for Status {\n    fn eq(&self, other: &u16) -> bool {\n        self.code == *other\n    }\n}\n\nimpl PartialOrd<u16> for Status {\n    fn partial_cmp(&self, other: &u16) -> Option<std::cmp::Ordering> {\n        self.code.partial_cmp(other)\n    }\n}\n\nimpl PartialEq<Status> for u16 {\n    fn eq(&self, other: &Status) -> bool {\n        *self == other.code\n    }\n}\n\nimpl PartialOrd<Status> for u16 {\n    fn partial_cmp(&self, other: &Status) -> Option<std::cmp::Ordering> {\n        self.partial_cmp(&other.code)\n    }\n}\n\nfn main() {\n    let status_code = 500; // Value doesn't matter for the lint\n    let status = Status { code: status_code };\n\n    // Correct\n    status_code >= 400 && status_code < 500;\n    status_code <= 400 && status_code > 500;\n    //~^ impossible_comparisons\n\n    status_code > 500 && status_code < 400;\n    //~^ impossible_comparisons\n\n    status_code < 500 && status_code > 500;\n    //~^ impossible_comparisons\n\n    // More complex expressions\n    status_code < { 400 } && status_code > { 500 };\n    //~^ impossible_comparisons\n\n    status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR;\n    //~^ impossible_comparisons\n\n    status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR;\n    //~^ impossible_comparisons\n\n    status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR;\n    //~^ impossible_comparisons\n\n    // Comparing two different types, via the `impl PartialOrd<u16> for Status`\n    status < { 400 } && status > { 500 };\n    //~^ impossible_comparisons\n\n    status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR;\n    //~^ impossible_comparisons\n\n    status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR;\n    //~^ impossible_comparisons\n\n    status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR;\n    //~^ impossible_comparisons\n\n    // Yoda conditions\n    // Correct\n    500 <= status_code && 600 > status_code;\n    // Correct\n    500 <= status_code && status_code <= 600;\n    // Incorrect\n    500 >= status_code && 600 < status_code;\n    //~^ impossible_comparisons\n\n    // Incorrect\n    500 >= status_code && status_code > 600;\n    //~^ impossible_comparisons\n\n    // Yoda conditions, comparing two different types\n    // Correct\n    500 <= status && 600 > status;\n    // Correct\n    500 <= status && status <= 600;\n    // Incorrect\n    500 >= status && 600 < status;\n    //~^ impossible_comparisons\n\n    // Incorrect\n    500 >= status && status > 600;\n    //~^ impossible_comparisons\n\n    // Expressions where one of the sides has no effect\n    status_code < 200 && status_code <= 299;\n    //~^ redundant_comparisons\n\n    status_code > 200 && status_code >= 299;\n    //~^ redundant_comparisons\n\n    // Useless left\n    status_code >= 500 && status_code > 500;\n    //~^ redundant_comparisons\n\n    // Useless right\n    status_code > 500 && status_code >= 500;\n    //~^ redundant_comparisons\n\n    // Useless left\n    status_code <= 500 && status_code < 500;\n    //~^ redundant_comparisons\n\n    // Useless right\n    status_code < 500 && status_code <= 500;\n    //~^ redundant_comparisons\n\n    // Other types\n    let name = \"Steve\";\n    name < \"Jennifer\" && name > \"Shannon\";\n    //~^ impossible_comparisons\n\n    let numbers = [1, 2];\n    numbers < [3, 4] && numbers > [5, 6];\n    //~^ impossible_comparisons\n\n    let letter = 'a';\n    letter < 'b' && letter > 'c';\n    //~^ impossible_comparisons\n\n    let area = 42.0;\n    area < std::f32::consts::E && area > std::f32::consts::PI;\n    //~^ impossible_comparisons\n}\n"
  },
  {
    "path": "tests/ui/const_comparisons.stderr",
    "content": "error: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:47:5\n   |\nLL |     status_code <= 400 && status_code > 500;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `400` < `500`, the expression evaluates to false for any value of `status_code`\n   = note: `-D clippy::impossible-comparisons` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::impossible_comparisons)]`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:50:5\n   |\nLL |     status_code > 500 && status_code < 400;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `500` > `400`, the expression evaluates to false for any value of `status_code`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:53:5\n   |\nLL |     status_code < 500 && status_code > 500;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `status_code` cannot simultaneously be greater than and less than `500`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:57:5\n   |\nLL |     status_code < { 400 } && status_code > { 500 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any value of `status_code`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:60:5\n   |\nLL |     status_code < STATUS_BAD_REQUEST && status_code > STATUS_SERVER_ERROR;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status_code`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:63:5\n   |\nLL |     status_code <= u16::MIN + 1 && status_code > STATUS_SERVER_ERROR;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status_code`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:66:5\n   |\nLL |     status_code < STATUS_SERVER_ERROR && status_code > STATUS_SERVER_ERROR;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `status_code` cannot simultaneously be greater than and less than `STATUS_SERVER_ERROR`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:70:5\n   |\nLL |     status < { 400 } && status > { 500 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `{ 400 }` < `{ 500 }`, the expression evaluates to false for any value of `status`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:73:5\n   |\nLL |     status < STATUS_BAD_REQUEST && status > STATUS_SERVER_ERROR;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `STATUS_BAD_REQUEST` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:76:5\n   |\nLL |     status <= u16::MIN + 1 && status > STATUS_SERVER_ERROR;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `u16::MIN + 1` < `STATUS_SERVER_ERROR`, the expression evaluates to false for any value of `status`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:79:5\n   |\nLL |     status < STATUS_SERVER_ERROR && status > STATUS_SERVER_ERROR;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `status` cannot simultaneously be greater than and less than `STATUS_SERVER_ERROR`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:88:5\n   |\nLL |     500 >= status_code && 600 < status_code;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `500` < `600`, the expression evaluates to false for any value of `status_code`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:92:5\n   |\nLL |     500 >= status_code && status_code > 600;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `500` < `600`, the expression evaluates to false for any value of `status_code`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:101:5\n   |\nLL |     500 >= status && 600 < status;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `500` < `600`, the expression evaluates to false for any value of `status`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:105:5\n   |\nLL |     500 >= status && status > 600;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `500` < `600`, the expression evaluates to false for any value of `status`\n\nerror: right-hand side of `&&` operator has no effect\n  --> tests/ui/const_comparisons.rs:109:5\n   |\nLL |     status_code < 200 && status_code <= 299;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `if `status_code < 200` evaluates to true, status_code <= 299` will always evaluate to true as well\n  --> tests/ui/const_comparisons.rs:109:23\n   |\nLL |     status_code < 200 && status_code <= 299;\n   |                       ^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::redundant-comparisons` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_comparisons)]`\n\nerror: left-hand side of `&&` operator has no effect\n  --> tests/ui/const_comparisons.rs:112:5\n   |\nLL |     status_code > 200 && status_code >= 299;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `if `status_code >= 299` evaluates to true, status_code > 200` will always evaluate to true as well\n  --> tests/ui/const_comparisons.rs:112:5\n   |\nLL |     status_code > 200 && status_code >= 299;\n   |     ^^^^^^^^^^^^^^^^^^^^^\n\nerror: left-hand side of `&&` operator has no effect\n  --> tests/ui/const_comparisons.rs:116:5\n   |\nLL |     status_code >= 500 && status_code > 500;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `if `status_code > 500` evaluates to true, status_code >= 500` will always evaluate to true as well\n  --> tests/ui/const_comparisons.rs:116:5\n   |\nLL |     status_code >= 500 && status_code > 500;\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: right-hand side of `&&` operator has no effect\n  --> tests/ui/const_comparisons.rs:120:5\n   |\nLL |     status_code > 500 && status_code >= 500;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `if `status_code > 500` evaluates to true, status_code >= 500` will always evaluate to true as well\n  --> tests/ui/const_comparisons.rs:120:23\n   |\nLL |     status_code > 500 && status_code >= 500;\n   |                       ^^^^^^^^^^^^^^^^^^^^^\n\nerror: left-hand side of `&&` operator has no effect\n  --> tests/ui/const_comparisons.rs:124:5\n   |\nLL |     status_code <= 500 && status_code < 500;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `if `status_code < 500` evaluates to true, status_code <= 500` will always evaluate to true as well\n  --> tests/ui/const_comparisons.rs:124:5\n   |\nLL |     status_code <= 500 && status_code < 500;\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: right-hand side of `&&` operator has no effect\n  --> tests/ui/const_comparisons.rs:128:5\n   |\nLL |     status_code < 500 && status_code <= 500;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `if `status_code < 500` evaluates to true, status_code <= 500` will always evaluate to true as well\n  --> tests/ui/const_comparisons.rs:128:23\n   |\nLL |     status_code < 500 && status_code <= 500;\n   |                       ^^^^^^^^^^^^^^^^^^^^^\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:133:5\n   |\nLL |     name < \"Jennifer\" && name > \"Shannon\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `\"Jennifer\"` < `\"Shannon\"`, the expression evaluates to false for any value of `name`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:137:5\n   |\nLL |     numbers < [3, 4] && numbers > [5, 6];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `[3, 4]` < `[5, 6]`, the expression evaluates to false for any value of `numbers`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:141:5\n   |\nLL |     letter < 'b' && letter > 'c';\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `'b'` < `'c'`, the expression evaluates to false for any value of `letter`\n\nerror: boolean expression will never evaluate to 'true'\n  --> tests/ui/const_comparisons.rs:145:5\n   |\nLL |     area < std::f32::consts::E && area > std::f32::consts::PI;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: since `std::f32::consts::E` < `std::f32::consts::PI`, the expression evaluates to false for any value of `area`\n\nerror: aborting due to 25 previous errors\n\n"
  },
  {
    "path": "tests/ui/const_is_empty.rs",
    "content": "#![warn(clippy::const_is_empty)]\n#![allow(clippy::needless_late_init, unused_must_use)]\n\nfn test_literal() {\n    if \"\".is_empty() {\n        //~^ const_is_empty\n    }\n    if \"foobar\".is_empty() {\n        //~^ const_is_empty\n    }\n}\n\nfn test_byte_literal() {\n    if b\"\".is_empty() {\n        //~^ const_is_empty\n    }\n    if b\"foobar\".is_empty() {\n        //~^ const_is_empty\n    }\n}\n\nfn test_no_mut() {\n    let mut empty = \"\";\n    if empty.is_empty() {\n        // No lint because it is mutable\n    }\n}\n\nfn test_propagated() {\n    let empty = \"\";\n    let non_empty = \"foobar\";\n    let empty2 = empty;\n    let non_empty2 = non_empty;\n    if empty2.is_empty() {\n        //~^ const_is_empty\n    }\n    if non_empty2.is_empty() {\n        //~^ const_is_empty\n    }\n}\n\nconst EMPTY_STR: &str = \"\";\nconst NON_EMPTY_STR: &str = \"foo\";\nconst EMPTY_BSTR: &[u8] = b\"\";\nconst NON_EMPTY_BSTR: &[u8] = b\"foo\";\nconst EMPTY_U8_SLICE: &[u8] = &[];\nconst NON_EMPTY_U8_SLICE: &[u8] = &[1, 2];\nconst EMPTY_SLICE: &[u32] = &[];\nconst NON_EMPTY_SLICE: &[u32] = &[1, 2];\nconst NON_EMPTY_SLICE_REPEAT: &[u32] = &[1; 2];\nconst EMPTY_ARRAY: [u32; 0] = [];\nconst EMPTY_ARRAY_REPEAT: [u32; 0] = [1; 0];\nconst NON_EMPTY_ARRAY: [u32; 2] = [1, 2];\nconst NON_EMPTY_ARRAY_REPEAT: [u32; 2] = [1; 2];\nconst EMPTY_REF_ARRAY: &[u32; 0] = &[];\nconst NON_EMPTY_REF_ARRAY: &[u32; 3] = &[1, 2, 3];\n\nfn main() {\n    let value = \"foobar\";\n    let _ = value.is_empty();\n    //~^ const_is_empty\n\n    let x = value;\n    let _ = x.is_empty();\n    //~^ const_is_empty\n\n    let _ = \"\".is_empty();\n    //~^ const_is_empty\n\n    let _ = b\"\".is_empty();\n    //~^ const_is_empty\n}\n\nfn str_from_arg(var: &str) {\n    var.is_empty();\n    // Do not lint, we know nothing about var\n}\n\nfn update_str() {\n    let mut value = \"duck\";\n    value = \"penguin\";\n\n    let _ = value.is_empty();\n    // Do not lint since value is mutable\n}\n\nfn macros() {\n    // Content from Macro\n    let file = include_str!(\"const_is_empty.rs\");\n    let _ = file.is_empty();\n    // No lint because initializer comes from a macro result\n\n    let var = env!(\"PATH\");\n    let _ = var.is_empty();\n    // No lint because initializer comes from a macro result\n}\n\nfn conditional_value() {\n    let value;\n\n    if true {\n        value = \"hey\";\n    } else {\n        value = \"hej\";\n    }\n\n    let _ = value.is_empty();\n    // Do not lint, current constant folding is too simple to detect this\n}\n\nfn cfg_conditioned() {\n    #[cfg(test)]\n    let val = \"\";\n    #[cfg(not(test))]\n    let val = \"foo\";\n\n    let _ = val.is_empty();\n    // Do not lint, value depend on a #[cfg(…)] directive\n}\n\nfn not_cfg_conditioned() {\n    let val = \"\";\n    #[cfg(not(target_os = \"inexistent\"))]\n    let _ = val.is_empty();\n    //~^ const_is_empty\n}\n\nconst fn const_rand() -> &'static str {\n    \"17\"\n}\n\nfn const_expressions() {\n    let _ = const { if true { \"1\" } else { \"2\" } }.is_empty();\n    // Do not lint, we do not recurse into boolean expressions\n\n    let _ = const_rand().is_empty();\n    // Do not lint, we do not recurse into functions\n}\n\nfn constant_from_external_crate() {\n    let _ = std::env::consts::EXE_EXTENSION.is_empty();\n    // Do not lint, `exe_ext` comes from the `std` crate\n}\n\nfn issue_13106() {\n    const {\n        assert!(!NON_EMPTY_STR.is_empty());\n    }\n\n    const {\n        assert!(EMPTY_STR.is_empty());\n    }\n\n    const {\n        EMPTY_STR.is_empty();\n    }\n}\n"
  },
  {
    "path": "tests/ui/const_is_empty.stderr",
    "content": "error: this expression always evaluates to true\n  --> tests/ui/const_is_empty.rs:5:8\n   |\nLL |     if \"\".is_empty() {\n   |        ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::const-is-empty` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::const_is_empty)]`\n\nerror: this expression always evaluates to false\n  --> tests/ui/const_is_empty.rs:8:8\n   |\nLL |     if \"foobar\".is_empty() {\n   |        ^^^^^^^^^^^^^^^^^^^\n\nerror: this expression always evaluates to true\n  --> tests/ui/const_is_empty.rs:14:8\n   |\nLL |     if b\"\".is_empty() {\n   |        ^^^^^^^^^^^^^^\n\nerror: this expression always evaluates to false\n  --> tests/ui/const_is_empty.rs:17:8\n   |\nLL |     if b\"foobar\".is_empty() {\n   |        ^^^^^^^^^^^^^^^^^^^^\n\nerror: this expression always evaluates to true\n  --> tests/ui/const_is_empty.rs:34:8\n   |\nLL |     if empty2.is_empty() {\n   |        ^^^^^^^^^^^^^^^^^\n\nerror: this expression always evaluates to false\n  --> tests/ui/const_is_empty.rs:37:8\n   |\nLL |     if non_empty2.is_empty() {\n   |        ^^^^^^^^^^^^^^^^^^^^^\n\nerror: this expression always evaluates to false\n  --> tests/ui/const_is_empty.rs:60:13\n   |\nLL |     let _ = value.is_empty();\n   |             ^^^^^^^^^^^^^^^^\n\nerror: this expression always evaluates to false\n  --> tests/ui/const_is_empty.rs:64:13\n   |\nLL |     let _ = x.is_empty();\n   |             ^^^^^^^^^^^^\n\nerror: this expression always evaluates to true\n  --> tests/ui/const_is_empty.rs:67:13\n   |\nLL |     let _ = \"\".is_empty();\n   |             ^^^^^^^^^^^^^\n\nerror: this expression always evaluates to true\n  --> tests/ui/const_is_empty.rs:70:13\n   |\nLL |     let _ = b\"\".is_empty();\n   |             ^^^^^^^^^^^^^^\n\nerror: this expression always evaluates to true\n  --> tests/ui/const_is_empty.rs:124:13\n   |\nLL |     let _ = val.is_empty();\n   |             ^^^^^^^^^^^^^^\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/copy_iterator.rs",
    "content": "#![warn(clippy::copy_iterator)]\n#![allow(clippy::manual_inspect)]\n\n#[derive(Copy, Clone)]\nstruct Countdown(u8);\n\nimpl Iterator for Countdown {\n    //~^ copy_iterator\n\n    type Item = u8;\n\n    fn next(&mut self) -> Option<u8> {\n        self.0.checked_sub(1).map(|c| {\n            self.0 = c;\n            c\n        })\n    }\n}\n\nfn main() {\n    let my_iterator = Countdown(5);\n    assert_eq!(my_iterator.take(1).count(), 1);\n    assert_eq!(my_iterator.count(), 5);\n}\n"
  },
  {
    "path": "tests/ui/copy_iterator.stderr",
    "content": "error: you are implementing `Iterator` on a `Copy` type\n  --> tests/ui/copy_iterator.rs:7:1\n   |\nLL | / impl Iterator for Countdown {\nLL | |\nLL | |\nLL | |     type Item = u8;\n...  |\nLL | | }\n   | |_^\n   |\n   = note: consider implementing `IntoIterator` instead\n   = note: `-D clippy::copy-iterator` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::copy_iterator)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/associated-constant-ice.rs",
    "content": "//@ check-pass\n// Test for https://github.com/rust-lang/rust-clippy/issues/1698\n\npub trait Trait {\n    const CONSTANT: u8;\n}\n\nimpl Trait for u8 {\n    const CONSTANT: u8 = 2;\n}\n\nfn main() {\n    println!(\"{}\", u8::CONSTANT * 10);\n}\n"
  },
  {
    "path": "tests/ui/crashes/auxiliary/ice-4727-aux.rs",
    "content": "pub trait Trait {\n    fn fun(par: &str) -> &str;\n}\n\nimpl Trait for str {\n    fn fun(par: &str) -> &str {\n        &par[0..1]\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/auxiliary/ice-7272-aux.rs",
    "content": "pub fn warn<T>(_: T) {}\n\nmacro_rules! define_macro {\n    ($d:tt $lower:ident $upper:ident) => {\n        #[macro_export]\n        macro_rules! $upper {\n            ($arg:tt) => {\n                $crate::$lower($arg)\n            };\n        }\n    };\n}\n\ndefine_macro! {$ warn  WARNING}\n"
  },
  {
    "path": "tests/ui/crashes/auxiliary/ice-7868-aux.rs",
    "content": "fn zero() {\n    unsafe { 0 };\n    //~^ ERROR: unsafe block missing a safety comment\n    //~| NOTE: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`\n}\n"
  },
  {
    "path": "tests/ui/crashes/auxiliary/ice-7934-aux.rs",
    "content": "fn zero() {\n    // SAFETY:\n    unsafe { 0 };\n}\n"
  },
  {
    "path": "tests/ui/crashes/auxiliary/ice-8681-aux.rs",
    "content": "pub fn foo(x: &u32) -> u32 {\n    /* Safety:\n     * This is totally ok.\n     */\n    unsafe { *(x as *const u32) }\n}\n"
  },
  {
    "path": "tests/ui/crashes/auxiliary/proc_macro_crash.rs",
    "content": "extern crate proc_macro;\n\nuse proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};\n\n#[proc_macro]\npub fn macro_test(input_stream: TokenStream) -> TokenStream {\n    let first_token = input_stream.into_iter().next().unwrap();\n    let span = first_token.span();\n\n    TokenStream::from_iter(vec![\n        TokenTree::Ident(Ident::new(\"fn\", Span::call_site())),\n        TokenTree::Ident(Ident::new(\"code\", Span::call_site())),\n        TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),\n        TokenTree::Group(Group::new(Delimiter::Brace, {\n            let mut clause = Group::new(Delimiter::Brace, TokenStream::new());\n            clause.set_span(span);\n\n            TokenStream::from_iter(vec![\n                TokenTree::Ident(Ident::new(\"if\", Span::call_site())),\n                TokenTree::Ident(Ident::new(\"true\", Span::call_site())),\n                TokenTree::Group(clause.clone()),\n                TokenTree::Ident(Ident::new(\"else\", Span::call_site())),\n                TokenTree::Group(clause),\n            ])\n        })),\n    ])\n}\n"
  },
  {
    "path": "tests/ui/crashes/auxiliary/use_self_macro.rs",
    "content": "macro_rules! use_self {\n    (\n        impl $ty:ident {\n            fn func(&$this:ident) {\n                [fields($($field:ident)*)]\n            }\n        }\n    ) => (\n        impl  $ty {\n            fn func(&$this) {\n                let $ty { $($field),* } = $this;\n            }\n        }\n    )\n}\n"
  },
  {
    "path": "tests/ui/crashes/cc_seme.rs",
    "content": "//@ check-pass\n// Test for https://github.com/rust-lang/rust-clippy/issues/478\n\nenum Baz {\n    One,\n    Two,\n}\n\nstruct Test {\n    t: Option<usize>,\n    b: Baz,\n}\n\nfn main() {}\n\npub fn foo() {\n    use Baz::*;\n    let x = Test { t: Some(0), b: One };\n\n    match x {\n        Test { t: Some(_), b: One } => unreachable!(),\n        Test { t: Some(42), b: Two } => unreachable!(),\n        Test { t: None, .. } => unreachable!(),\n        Test { .. } => unreachable!(),\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/elidable_lifetime_names_impl_trait.fixed",
    "content": "#![deny(clippy::elidable_lifetime_names)]\n#![allow(dead_code)]\n\ntrait Foo {}\n\nstruct Bar;\n\nstruct Baz<'a> {\n    bar: &'a Bar,\n}\n\nimpl Foo for Baz<'_> {}\n//~^ elidable_lifetime_names\n\nimpl Bar {\n    fn baz(&self) -> impl Foo + '_ {\n        //~^ elidable_lifetime_names\n\n        Baz { bar: self }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/elidable_lifetime_names_impl_trait.rs",
    "content": "#![deny(clippy::elidable_lifetime_names)]\n#![allow(dead_code)]\n\ntrait Foo {}\n\nstruct Bar;\n\nstruct Baz<'a> {\n    bar: &'a Bar,\n}\n\nimpl<'a> Foo for Baz<'a> {}\n//~^ elidable_lifetime_names\n\nimpl Bar {\n    fn baz<'a>(&'a self) -> impl Foo + 'a {\n        //~^ elidable_lifetime_names\n\n        Baz { bar: self }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/elidable_lifetime_names_impl_trait.stderr",
    "content": "error: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:12:6\n   |\nLL | impl<'a> Foo for Baz<'a> {}\n   |      ^^              ^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:1:9\n   |\nLL | #![deny(clippy::elidable_lifetime_names)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: elide the lifetimes\n   |\nLL - impl<'a> Foo for Baz<'a> {}\nLL + impl Foo for Baz<'_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/crashes/elidable_lifetime_names_impl_trait.rs:16:12\n   |\nLL |     fn baz<'a>(&'a self) -> impl Foo + 'a {\n   |            ^^   ^^                     ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn baz<'a>(&'a self) -> impl Foo + 'a {\nLL +     fn baz(&self) -> impl Foo + '_ {\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/crashes/enum-glob-import-crate.rs",
    "content": "//@ check-pass\n\nuse std::*;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-10148.rs",
    "content": "//@aux-build:../auxiliary/proc_macros.rs\n//@no-rustfix\nextern crate proc_macros;\n\nuse proc_macros::with_span;\n\nfn main() {\n    println!(with_span!(\"\"something \"\"));\n    //~^ println_empty_string\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-10148.stderr",
    "content": "error: empty string literal in `println!`\n  --> tests/ui/crashes/ice-10148.rs:8:5\n   |\nLL |     println!(with_span!(\"\"something \"\"));\n   |     ^^^^^^^^^^^^^^^^^^^^---------------^\n   |                         |\n   |                         help: remove the empty string\n   |\n   = note: `-D clippy::println-empty-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-10508a.rs",
    "content": "//@ check-pass\n// Used to overflow in `is_normalizable`\n\nuse std::marker::PhantomData;\n\nstruct Node<T: 'static> {\n    m: PhantomData<&'static T>,\n}\n\nstruct Digit<T> {\n    elem: T,\n}\n\nenum FingerTree<T: 'static> {\n    Single(T),\n\n    Deep(Digit<T>, Box<FingerTree<Node<T>>>),\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-10508b.rs",
    "content": "//@ check-pass\n\nuse std::marker::PhantomData;\n\nstruct Digit<T> {\n    elem: T,\n}\n\nstruct Node<T: 'static> {\n    m: PhantomData<&'static T>,\n}\n\nenum FingerTree<T: 'static> {\n    Single(T),\n\n    Deep(Digit<T>, Node<FingerTree<Node<T>>>),\n}\n\nenum Wrapper<T: 'static> {\n    Simple,\n    Other(FingerTree<T>),\n}\n\nfn main() {\n    let w = Some(Wrapper::Simple::<u32>);\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-10508c.rs",
    "content": "//@ check-pass\n\n#[derive(Debug)]\nstruct S<T> {\n    t: T,\n    s: Box<S<fn(u: T)>>,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-10912.rs",
    "content": "#![warn(clippy::unreadable_literal)]\n\nfn f2() -> impl Sized { && 3.14159265358979323846E }\n//~^ ERROR: expected at least one digit in exponent\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-10912.stderr",
    "content": "error: expected at least one digit in exponent\n  --> tests/ui/crashes/ice-10912.rs:3:28\n   |\nLL | fn f2() -> impl Sized { && 3.14159265358979323846E }\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-11065.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::useless_conversion)]\n\nuse std::option::IntoIter as OptionIter;\n\nfn eq<T: Eq>(a: T, b: T) -> bool {\n    a == b\n}\n\nmacro_rules! tests {\n    ($($expr:expr, $ty:ty, ($($test:expr),*);)+) => (pub fn main() {$({\n        const C: $ty = $expr;\n        assert!(eq(C($($test),*), $expr($($test),*)));\n    })+})\n}\n\ntests! {\n    FromIterator::from_iter, fn(OptionIter<i32>) -> Vec<i32>, (Some(5).into_iter());\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-11230.fixed",
    "content": "// Test for https://github.com/rust-lang/rust-clippy/issues/11230\n#![warn(clippy::explicit_iter_loop)]\n#![warn(clippy::needless_collect)]\n\n// explicit_iter_loop\nfn main() {\n    const A: &[for<'a> fn(&'a ())] = &[];\n    for v in A {}\n    //~^ explicit_iter_loop\n}\n\n// needless_collect\ntrait Helper<'a>: Iterator<Item = fn()> {}\n\n// Should not be linted because we have no idea whether the iterator has side effects\nfn x(w: &mut dyn for<'a> Helper<'a>) {\n    w.collect::<Vec<_>>().is_empty();\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-11230.rs",
    "content": "// Test for https://github.com/rust-lang/rust-clippy/issues/11230\n#![warn(clippy::explicit_iter_loop)]\n#![warn(clippy::needless_collect)]\n\n// explicit_iter_loop\nfn main() {\n    const A: &[for<'a> fn(&'a ())] = &[];\n    for v in A.iter() {}\n    //~^ explicit_iter_loop\n}\n\n// needless_collect\ntrait Helper<'a>: Iterator<Item = fn()> {}\n\n// Should not be linted because we have no idea whether the iterator has side effects\nfn x(w: &mut dyn for<'a> Helper<'a>) {\n    w.collect::<Vec<_>>().is_empty();\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-11230.stderr",
    "content": "error: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/crashes/ice-11230.rs:8:14\n   |\nLL |     for v in A.iter() {}\n   |              ^^^^^^^^ help: to write this more concisely, try: `A`\n   |\n   = note: `-D clippy::explicit-iter-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::explicit_iter_loop)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-11337.rs",
    "content": "//@ check-pass\n\n#![feature(trait_alias)]\n\ntrait Confusing<F> = Fn(i32) where F: Fn(u32);\n\nfn alias<T: Confusing<F>, F>(_: T, _: F) {}\n\nfn main() {\n    alias(|_| {}, |_| {});\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-11422.fixed",
    "content": "#![warn(clippy::implied_bounds_in_impls)]\n\nuse std::fmt::Debug;\nuse std::ops::*;\n\nfn r#gen() -> impl PartialOrd + Debug {}\n//~^ implied_bounds_in_impls\n\nstruct Bar {}\ntrait Foo<T = Self> {}\ntrait FooNested<T = Option<Self>> {}\nimpl Foo for Bar {}\nimpl FooNested for Bar {}\n\nfn foo() -> impl Foo + FooNested {\n    Bar {}\n}\n\nfn test_impl_ops() -> impl Add + Sub + Mul + Div {\n    1\n}\nfn test_impl_assign_ops() -> impl AddAssign + SubAssign + MulAssign + DivAssign {\n    1\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-11422.rs",
    "content": "#![warn(clippy::implied_bounds_in_impls)]\n\nuse std::fmt::Debug;\nuse std::ops::*;\n\nfn r#gen() -> impl PartialOrd + PartialEq + Debug {}\n//~^ implied_bounds_in_impls\n\nstruct Bar {}\ntrait Foo<T = Self> {}\ntrait FooNested<T = Option<Self>> {}\nimpl Foo for Bar {}\nimpl FooNested for Bar {}\n\nfn foo() -> impl Foo + FooNested {\n    Bar {}\n}\n\nfn test_impl_ops() -> impl Add + Sub + Mul + Div {\n    1\n}\nfn test_impl_assign_ops() -> impl AddAssign + SubAssign + MulAssign + DivAssign {\n    1\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-11422.stderr",
    "content": "error: this bound is already specified as the supertrait of `PartialOrd`\n  --> tests/ui/crashes/ice-11422.rs:6:33\n   |\nLL | fn r#gen() -> impl PartialOrd + PartialEq + Debug {}\n   |                                 ^^^^^^^^^\n   |\n   = note: `-D clippy::implied-bounds-in-impls` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::implied_bounds_in_impls)]`\nhelp: try removing this bound\n   |\nLL - fn r#gen() -> impl PartialOrd + PartialEq + Debug {}\nLL + fn r#gen() -> impl PartialOrd + Debug {}\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-11755.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::unused_enumerate_index)]\n\nfn main() {\n    for () in [()].iter() {}\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-11803.rs",
    "content": "//@no-rustfix\n\n#![warn(clippy::impl_trait_in_params)]\n\npub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() {\n    //~^ impl_trait_in_params\n    //~| impl_trait_in_params\n    extern \"C\" fn implementation_detail() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-11803.stderr",
    "content": "error: `impl Trait` used as a function parameter\n  --> tests/ui/crashes/ice-11803.rs:5:54\n   |\nLL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() {\n   |                                                      ^^^^^^^^^^\n   |\n   = note: `-D clippy::impl-trait-in-params` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::impl_trait_in_params)]`\nhelp: add a type parameter\n   |\nLL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>, { /* Generic name */ }: Clone>() {\n   |                                                                  +++++++++++++++++++++++++++++++\n\nerror: `impl Trait` used as a function parameter\n  --> tests/ui/crashes/ice-11803.rs:5:33\n   |\nLL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>>() {\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: add a type parameter\n   |\nLL | pub fn g<T: IntoIterator<Item = impl Iterator<Item = impl Clone>>, { /* Generic name */ }: Iterator<Item = impl Clone>>() {\n   |                                                                  +++++++++++++++++++++++++++++++++++++++++++++++++++++\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-11939.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::unit_arg, clippy::no_effect)]\n\nconst fn v(_: ()) {}\n\nfn main() {\n    if true {\n        v({\n            [0; 1 + 1];\n        });\n        Some(())\n    } else {\n        None\n    };\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-12253.rs",
    "content": "//@ check-pass\n\n#[allow(overflowing_literals, unconditional_panic, clippy::no_effect)]\nfn main() {\n    let arr: [i32; 5] = [0; 5];\n    arr[0xfffffe7ffffffffffffffffffffffff];\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-12491.fixed",
    "content": "#![warn(clippy::needless_return)]\n\nfn main() {\n    if (true) {\n        // anything一些中文\n        //~^ needless_return\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-12491.rs",
    "content": "#![warn(clippy::needless_return)]\n\nfn main() {\n    if (true) {\n        // anything一些中文\n        return;\n        //~^ needless_return\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-12491.stderr",
    "content": "error: unneeded `return` statement\n  --> tests/ui/crashes/ice-12491.rs:6:9\n   |\nLL |         return;\n   |         ^^^^^^\n   |\n   = note: `-D clippy::needless-return` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_return)]`\nhelp: remove `return`\n   |\nLL -         // anything一些中文\nLL -         return;\nLL +         // anything一些中文\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-12585.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::unit_arg)]\n\nstruct One {\n    x: i32,\n}\nstruct Two {\n    x: i32,\n}\n\nstruct Product {}\n\nimpl Product {\n    pub fn a_method(self, _: ()) {}\n}\n\nfn from_array(_: [i32; 2]) -> Product {\n    todo!()\n}\n\npub fn main() {\n    let one = One { x: 1 };\n    let two = Two { x: 2 };\n\n    let product = from_array([one.x, two.x]);\n    product.a_method(<()>::default());\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-12616.fixed",
    "content": "#![warn(clippy::ptr_as_ptr)]\n#![allow(clippy::unnecessary_operation, clippy::unnecessary_cast)]\n\nfn main() {\n    let s = std::ptr::null::<()>;\n    s().cast::<()>();\n    //~^ ptr_as_ptr\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-12616.rs",
    "content": "#![warn(clippy::ptr_as_ptr)]\n#![allow(clippy::unnecessary_operation, clippy::unnecessary_cast)]\n\nfn main() {\n    let s = std::ptr::null::<()>;\n    s() as *const ();\n    //~^ ptr_as_ptr\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-12616.stderr",
    "content": "error: `as` casting between raw pointers without changing their constness\n  --> tests/ui/crashes/ice-12616.rs:6:5\n   |\nLL |     s() as *const ();\n   |     ^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `s().cast::<()>()`\n   |\n   = note: `-D clippy::ptr-as-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-12979.1.fixed",
    "content": "#[deny(clippy::declare_interior_mutable_const)] //~ empty_line_after_outer_attr\nconst FOO: u8 = 0;\n"
  },
  {
    "path": "tests/ui/crashes/ice-12979.2.fixed",
    "content": "#![deny(clippy::declare_interior_mutable_const)] //~ empty_line_after_outer_attr\n\nconst FOO: u8 = 0;\n"
  },
  {
    "path": "tests/ui/crashes/ice-12979.rs",
    "content": "#[deny(clippy::declare_interior_mutable_const)] //~ empty_line_after_outer_attr\n\nconst FOO: u8 = 0;\n"
  },
  {
    "path": "tests/ui/crashes/ice-12979.stderr",
    "content": "error: empty line after outer attribute\n  --> tests/ui/crashes/ice-12979.rs:1:1\n   |\nLL | / #[deny(clippy::declare_interior_mutable_const)]\nLL | |\n   | |_^\nLL |   const FOO: u8 = 0;\n   |   --------- the attribute applies to this constant item\n   |\n   = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]`\n   = help: if the empty line is unintentional, remove it\nhelp: if the attribute should apply to the crate use an inner attribute\n   |\nLL | #![deny(clippy::declare_interior_mutable_const)]\n   |  +\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-13544-original.rs",
    "content": "//@ check-pass\n#![warn(clippy::significant_drop_tightening)]\n\nuse std::mem::ManuallyDrop;\nuse std::ops::{Deref, DerefMut};\n\ntrait Scopable: Sized {\n    type SubType: Scopable;\n}\n\nstruct Subtree<T: Scopable>(ManuallyDrop<Box<Tree<T::SubType>>>);\n\nimpl<T: Scopable> Drop for Subtree<T> {\n    fn drop(&mut self) {\n        // SAFETY: The field cannot be used after we drop\n        unsafe { ManuallyDrop::drop(&mut self.0) }\n    }\n}\n\nimpl<T: Scopable> Deref for Subtree<T> {\n    type Target = Tree<T::SubType>;\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nimpl<T: Scopable> DerefMut for Subtree<T> {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        &mut self.0\n    }\n}\n\nenum Tree<T: Scopable> {\n    Group(Vec<Tree<T>>),\n    Subtree(Subtree<T>),\n    Leaf(T),\n}\n\nimpl<T: Scopable> Tree<T> {\n    fn foo(self) -> Self {\n        self\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-13544-reduced.rs",
    "content": "//@ check-pass\n#![warn(clippy::significant_drop_tightening)]\n#![allow(unused, clippy::no_effect)]\n\nuse std::marker::PhantomData;\n\ntrait Trait {\n    type Assoc: Trait;\n}\nstruct S<T: Trait>(*const S<T::Assoc>, PhantomData<T>);\n\nfn f<T: Trait>(x: &mut S<T>) {\n    &mut x.0;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-13862.rs",
    "content": "//@ check-pass\n\n#![crate_type = \"lib\"]\n#![no_std]\n\nuse core::future::Future;\nuse core::pin::Pin;\nuse core::task::{Context, Poll};\n\npub struct S<const N: u8>;\n\nimpl<const N: u8> Future for S<N> {\n    type Output = ();\n    fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {\n        todo!()\n    }\n}\n\npub fn f<const N: u8>() -> S<N> {\n    S\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-14303.rs",
    "content": "//@check-pass\n#![warn(clippy::macro_use_imports)]\n\n#[repr(transparent)]\npub struct X(());\n\n#[repr(u8)]\npub enum Action {\n    Off = 0,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-14325.rs",
    "content": "//@check-pass\n\n#![allow(clippy::redundant_pattern_matching)]\n\nstruct S<'a> {\n    s: &'a str,\n}\n\nfn foo() -> Option<S<'static>> {\n    if let Some(_) = Some(0) {\n        Some(S { s: \"xyz\" })\n    } else {\n        None\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-14935.rs",
    "content": "//@check-pass\n#![warn(clippy::mutable_key_type)]\n\nuse std::marker::PhantomData;\n\ntrait Group {\n    type ExposantSet: Group;\n}\n\nstruct Pow<T: Group> {\n    exposant: Box<Pow<T::ExposantSet>>,\n    _p: PhantomData<T>,\n}\n\nimpl<T: Group> Pow<T> {\n    fn is_zero(&self) -> bool {\n        false\n    }\n    fn normalize(&self) {\n        #[expect(clippy::if_same_then_else)]\n        if self.is_zero() {\n        } else if false {\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-15657.rs",
    "content": "//@check-pass\n#![warn(clippy::len_zero)]\n\npub struct S1;\npub struct S2;\n\nimpl S1 {\n    pub fn len(&self) -> S2 {\n        S2\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-15666.fixed",
    "content": "#![warn(clippy::elidable_lifetime_names)]\n\nstruct UnitVariantAccess<'a, 'b, 's>(&'a &'b &'s ());\ntrait Trait<'de> {}\nimpl<'de> Trait<'de> for UnitVariantAccess<'_, 'de, '_> {}\n//~^ elidable_lifetime_names\n"
  },
  {
    "path": "tests/ui/crashes/ice-15666.rs",
    "content": "#![warn(clippy::elidable_lifetime_names)]\n\nstruct UnitVariantAccess<'a, 'b, 's>(&'a &'b &'s ());\ntrait Trait<'de> {}\nimpl<'de, 'a, 's> Trait<'de> for UnitVariantAccess<'a, 'de, 's> {}\n//~^ elidable_lifetime_names\n"
  },
  {
    "path": "tests/ui/crashes/ice-15666.stderr",
    "content": "error: the following explicit lifetimes could be elided: 'a, 's\n  --> tests/ui/crashes/ice-15666.rs:5:11\n   |\nLL | impl<'de, 'a, 's> Trait<'de> for UnitVariantAccess<'a, 'de, 's> {}\n   |           ^^  ^^                                   ^^       ^^\n   |\n   = note: `-D clippy::elidable-lifetime-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::elidable_lifetime_names)]`\nhelp: elide the lifetimes\n   |\nLL - impl<'de, 'a, 's> Trait<'de> for UnitVariantAccess<'a, 'de, 's> {}\nLL + impl<'de> Trait<'de> for UnitVariantAccess<'_, 'de, '_> {}\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-15684.rs",
    "content": "#![warn(clippy::unnecessary_safety_comment)]\n\nfn foo() -> i32 {\n    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n    #[must_use]\n    return 33;\n    //~^ unnecessary_safety_comment\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-15684.stderr",
    "content": "error: statement has unnecessary safety comment\n  --> tests/ui/crashes/ice-15684.rs:6:5\n   |\nLL |     return 33;\n   |     ^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/crashes/ice-15684.rs:4:8\n   |\nLL |     // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-1588.rs",
    "content": "//@ check-pass\n\n#![expect(clippy::no_effect)]\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/1588\n\nfn main() {\n    match 1 {\n        1 => {},\n        2 => {\n            [0; 1];\n        },\n        _ => {},\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-1782.rs",
    "content": "//@ check-pass\n\n#![allow(dead_code, unused_variables, invalid_null_arguments, unnecessary_transmutes)]\n#![allow(clippy::unnecessary_cast, clippy::missing_transmute_annotations)]\n\n/// Should not trigger an ICE in `SpanlessEq` / `consts::constant`\n///\n/// Issue: https://github.com/rust-lang/rust-clippy/issues/1782\nuse std::{mem, ptr};\n\nfn spanless_eq_ice() {\n    let txt = \"something\";\n    match txt {\n        \"something\" => unsafe {\n            ptr::write(\n                ptr::null_mut() as *mut u32,\n                mem::transmute::<[u8; 4], _>([0, 0, 0, 255]),\n            )\n        },\n        _ => unsafe {\n            ptr::write(\n                ptr::null_mut() as *mut u32,\n                mem::transmute::<[u8; 4], _>([13, 246, 24, 255]),\n            )\n        },\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-1969.rs",
    "content": "//@ check-pass\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/1969\n\nfn main() {}\n\npub trait Convert {\n    type Action: From<*const f64>;\n\n    fn convert(val: *const f64) -> Self::Action {\n        val.into()\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-2499.rs",
    "content": "//@ check-pass\n\n#![allow(dead_code, clippy::char_lit_as_u8, clippy::needless_bool)]\n\n// Should not trigger an ICE in `SpanlessHash` / `consts::constant`\n//\n// Issue: https://github.com/rust-lang/rust-clippy/issues/2499\n\nfn f(s: &[u8]) -> bool {\n    let t = s[0] as char;\n\n    match t {\n        'E' | 'W' => {},\n        'T' => {\n            if s[0..4] != ['0' as u8; 4] {\n                return false;\n            } else {\n                return true;\n            }\n        },\n        _ => {\n            return false;\n        },\n    }\n    true\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-2594.rs",
    "content": "//@ check-pass\n\n#![allow(dead_code, unused_variables)]\n\n/// Should not trigger an ICE in `SpanlessHash` / `consts::constant`\n///\n/// Issue: https://github.com/rust-lang/rust-clippy/issues/2594\nfn spanless_hash_ice() {\n    let txt = \"something\";\n    let empty_header: [u8; 1] = [1; 1];\n\n    match txt {\n        \"something\" => {\n            let mut headers = [empty_header; 1];\n        },\n        \"\" => (),\n        _ => (),\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-2727.rs",
    "content": "//@ check-pass\n// Test for https://github.com/rust-lang/rust-clippy/issues/2727\n\npub fn f(new: fn()) {\n    new();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-2760.rs",
    "content": "//@ check-pass\n\n#![allow(\n    unused_variables,\n    clippy::disallowed_names,\n    clippy::needless_pass_by_value,\n    dead_code\n)]\n\n// This should not compile-fail with:\n//\n//      error[E0277]: the trait bound `T: Foo` is not satisfied\n// See https://github.com/rust-lang/rust-clippy/issues/2760\n\ntrait Foo {\n    type Bar;\n}\n\nstruct Baz<T: Foo> {\n    bar: T::Bar,\n}\n\nfn take<T: Foo>(baz: Baz<T>) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-2774.fixed",
    "content": "use std::collections::HashSet;\n\n// See rust-lang/rust-clippy#2774.\n\n#[derive(Eq, PartialEq, Debug, Hash)]\npub struct Bar {\n    foo: Foo,\n}\n\n#[derive(Eq, PartialEq, Debug, Hash)]\npub struct Foo;\n\n#[allow(clippy::implicit_hasher)]\n// This should not cause a \"cannot relate bound region\" ICE.\npub fn add_barfoos_to_foos(bars: &HashSet<&Bar>) {\n    //~^ needless_lifetimes\n\n    let mut foos = HashSet::new();\n    foos.extend(bars.iter().map(|b| &b.foo));\n}\n\n#[allow(clippy::implicit_hasher)]\n// Also, this should not cause a \"cannot relate bound region\" ICE.\npub fn add_barfoos_to_foos2(bars: &HashSet<&Bar>) {\n    let mut foos = HashSet::new();\n    foos.extend(bars.iter().map(|b| &b.foo));\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-2774.rs",
    "content": "use std::collections::HashSet;\n\n// See rust-lang/rust-clippy#2774.\n\n#[derive(Eq, PartialEq, Debug, Hash)]\npub struct Bar {\n    foo: Foo,\n}\n\n#[derive(Eq, PartialEq, Debug, Hash)]\npub struct Foo;\n\n#[allow(clippy::implicit_hasher)]\n// This should not cause a \"cannot relate bound region\" ICE.\npub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {\n    //~^ needless_lifetimes\n\n    let mut foos = HashSet::new();\n    foos.extend(bars.iter().map(|b| &b.foo));\n}\n\n#[allow(clippy::implicit_hasher)]\n// Also, this should not cause a \"cannot relate bound region\" ICE.\npub fn add_barfoos_to_foos2(bars: &HashSet<&Bar>) {\n    let mut foos = HashSet::new();\n    foos.extend(bars.iter().map(|b| &b.foo));\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-2774.stderr",
    "content": "error: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/crashes/ice-2774.rs:15:28\n   |\nLL | pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {\n   |                            ^^                  ^^\n   |\n   = note: `-D clippy::needless-lifetimes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]`\nhelp: elide the lifetimes\n   |\nLL - pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {\nLL + pub fn add_barfoos_to_foos(bars: &HashSet<&Bar>) {\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-2862.rs",
    "content": "//@ check-pass\n// Test for https://github.com/rust-lang/rust-clippy/issues/2862\n\npub trait FooMap {\n    fn map<B, F: Fn() -> B>(&self, f: F) -> B;\n}\n\nimpl FooMap for bool {\n    fn map<B, F: Fn() -> B>(&self, f: F) -> B {\n        f()\n    }\n}\n\nfn main() {\n    let a = true;\n    a.map(|| false);\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-2865.rs",
    "content": "//@ check-pass\n\n#![allow(dead_code, clippy::extra_unused_lifetimes)]\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/2865\n\nstruct Ice {\n    size: String,\n}\n\nimpl<'a> From<String> for Ice {\n    fn from(_: String) -> Self {\n        let text = || \"iceberg\".to_string();\n        Self { size: text() }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-3151.rs",
    "content": "//@ check-pass\n// Test for https://github.com/rust-lang/rust-clippy/issues/3151\n\n#[derive(Clone)]\npub struct HashMap<V, S> {\n    hash_builder: S,\n    table: RawTable<V>,\n}\n\n#[derive(Clone)]\npub struct RawTable<V> {\n    size: usize,\n    val: V,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-3462.rs",
    "content": "//@ check-pass\n\n#![expect(clippy::disallowed_names)]\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/3462\n\nenum Foo {\n    Bar,\n    Baz,\n}\n\nfn bar(foo: Foo) {\n    macro_rules! baz {\n        () => {\n            if let Foo::Bar = foo {}\n        };\n    }\n\n    baz!();\n    baz!();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-360.rs",
    "content": "fn main() {}\n//@no-rustfix\nfn no_panic<T>(slice: &[T]) {\n    let mut iter = slice.iter();\n    loop {\n        //~^ never_loop\n        //~| while_let_loop\n\n        let _ = match iter.next() {\n            Some(ele) => ele,\n            None => break,\n        };\n        loop {}\n        //~^ empty_loop\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-360.stderr",
    "content": "error: this loop never actually loops\n  --> tests/ui/crashes/ice-360.rs:5:5\n   |\nLL | /     loop {\n...  |\nLL | |     }\n   | |_____^\n   |\n   = note: `#[deny(clippy::never_loop)]` on by default\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/crashes/ice-360.rs:5:5\n   |\nLL | /     loop {\n...  |\nLL | |     }\n   | |_____^ help: try: `while let Some(ele) = iter.next() { .. }`\n   |\n   = note: `-D clippy::while-let-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::while_let_loop)]`\n\nerror: empty `loop {}` wastes CPU cycles\n  --> tests/ui/crashes/ice-360.rs:13:9\n   |\nLL |         loop {}\n   |         ^^^^^^^\n   |\n   = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body\n   = note: `-D clippy::empty-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_loop)]`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-3717.fixed",
    "content": "#![deny(clippy::implicit_hasher)]\n\nuse std::collections::HashSet;\n\nfn main() {}\n\npub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {\n    //~^ implicit_hasher\n\n    let _ = [0u8; 0];\n    let _: HashSet<usize> = HashSet::default();\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-3717.rs",
    "content": "#![deny(clippy::implicit_hasher)]\n\nuse std::collections::HashSet;\n\nfn main() {}\n\npub fn ice_3717(_: &HashSet<usize>) {\n    //~^ implicit_hasher\n\n    let _ = [0u8; 0];\n    let _: HashSet<usize> = HashSet::new();\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-3717.stderr",
    "content": "error: parameter of type `HashSet` should be generalized over different hashers\n  --> tests/ui/crashes/ice-3717.rs:7:21\n   |\nLL | pub fn ice_3717(_: &HashSet<usize>) {\n   |                     ^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/crashes/ice-3717.rs:1:9\n   |\nLL | #![deny(clippy::implicit_hasher)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~ pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {\nLL |\nLL |\nLL |     let _ = [0u8; 0];\nLL ~     let _: HashSet<usize> = HashSet::default();\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-3741.rs",
    "content": "//@ check-pass\n//@aux-build:proc_macro_crash.rs\n\n#![warn(clippy::suspicious_else_formatting)]\n\nextern crate proc_macro_crash;\nuse proc_macro_crash::macro_test;\n\nfn main() {\n    macro_test!(2);\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-3747.rs",
    "content": "//@ check-pass\n// Test for https://github.com/rust-lang/rust-clippy/issues/3747\n\nmacro_rules! a {\n    ( $pub:tt $($attr:tt)* ) => {\n        $($attr)* $pub fn say_hello() {}\n    };\n}\n\nmacro_rules! b {\n    () => {\n        a! { pub }\n    };\n}\n\nb! {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-3891.rs",
    "content": "fn main() {\n    1x;\n    //~^ ERROR: invalid suffix `x` for number literal\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-3891.stderr",
    "content": "error: invalid suffix `x` for number literal\n  --> tests/ui/crashes/ice-3891.rs:2:5\n   |\nLL |     1x;\n   |     ^^ invalid suffix `x`\n   |\n   = help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-3969.rs",
    "content": "// https://github.com/rust-lang/rust-clippy/issues/3969\n// used to crash: error: internal compiler error:\n// src/librustc_traits/normalize_erasing_regions.rs:43: could not fully normalize `<i32 as\n// std::iter::Iterator>::Item` test from rustc ./ui/trivial-bounds/trivial-bounds-inconsistent.rs\n\n// Check that tautalogically false bounds are accepted, and are used\n// in type inference.\n#![feature(trivial_bounds)]\n#![allow(unused)]\ntrait A {}\n\nimpl A for i32 {}\n\nstruct Dst<X: ?Sized> {\n    x: X,\n}\n\nstruct TwoStrs(str, str)\nwhere\n    str: Sized;\n//~^ ERROR: trait bound\n\nfn unsized_local()\nwhere\n    for<'a> Dst<dyn A + 'a>: Sized,\n    //~^ ERROR: trait bound\n{\n    let x: Dst<dyn A> = *(Box::new(Dst { x: 1 }) as Box<Dst<dyn A>>);\n}\n\nfn return_str() -> str\nwhere\n    str: Sized,\n    //~^ ERROR: trait bound\n{\n    *\"Sized\".to_string().into_boxed_str()\n}\n\nfn use_op(s: String) -> String\nwhere\n    String: ::std::ops::Neg<Output = String>,\n    //~^ ERROR: trait bound\n{\n    -s\n}\n\nfn use_for()\nwhere\n    i32: Iterator,\n    //~^ ERROR: trait bound\n{\n    for _ in 2i32 {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-3969.stderr",
    "content": "error: trait bound str: std::marker::Sized does not depend on any type or lifetime parameters\n  --> tests/ui/crashes/ice-3969.rs:20:10\n   |\nLL |     str: Sized;\n   |          ^^^^^\n   |\n   = note: `-D trivial-bounds` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(trivial_bounds)]`\n\nerror: trait bound for<'a> Dst<(dyn A + 'a)>: std::marker::Sized does not depend on any type or lifetime parameters\n  --> tests/ui/crashes/ice-3969.rs:25:30\n   |\nLL |     for<'a> Dst<dyn A + 'a>: Sized,\n   |                              ^^^^^\n\nerror: trait bound str: std::marker::Sized does not depend on any type or lifetime parameters\n  --> tests/ui/crashes/ice-3969.rs:33:10\n   |\nLL |     str: Sized,\n   |          ^^^^^\n\nerror: trait bound std::string::String: std::ops::Neg does not depend on any type or lifetime parameters\n  --> tests/ui/crashes/ice-3969.rs:41:13\n   |\nLL |     String: ::std::ops::Neg<Output = String>,\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: trait bound i32: std::iter::Iterator does not depend on any type or lifetime parameters\n  --> tests/ui/crashes/ice-3969.rs:49:10\n   |\nLL |     i32: Iterator,\n   |          ^^^^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-4121.rs",
    "content": "//@ check-pass\n\nuse std::mem;\n\npub struct Foo<A, B>(A, B);\n\nimpl<A, B> Foo<A, B> {\n    const HOST_SIZE: usize = mem::size_of::<B>();\n\n    pub fn crash() -> bool {\n        Self::HOST_SIZE == 0\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-4545.rs",
    "content": "//@ check-pass\n\nfn repro() {\n    trait Foo {\n        type Bar;\n    }\n\n    #[allow(dead_code)]\n    struct Baz<T: Foo> {\n        field: T::Bar,\n    }\n}\n\nfn main() {\n    repro();\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-4579.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::single_match, clippy::ptr_offset_by_literal)]\n\nuse std::ptr;\n\nfn main() {\n    match Some(0_usize) {\n        Some(_) => {\n            let s = \"012345\";\n            unsafe { ptr::read(s.as_ptr().offset(1) as *const [u8; 5]) };\n        },\n        _ => (),\n    };\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-4671.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::use_self)]\n\n#[macro_use]\n#[path = \"auxiliary/use_self_macro.rs\"]\nmod use_self_macro;\n\nstruct Foo {\n    a: u32,\n}\n\nuse_self! {\n    impl Foo {\n        fn func(&self) {\n            [fields(\n                a\n            )]\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-4727.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::use_self)]\n\n#[path = \"auxiliary/ice-4727-aux.rs\"]\nmod aux;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-4760.rs",
    "content": "//@ check-pass\n\n#![allow(non_local_definitions)]\n\nconst COUNT: usize = 2;\nstruct Thing;\ntrait Dummy {}\n\nconst _: () = {\n    impl Dummy for Thing where [i32; COUNT]: Sized {}\n};\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-4775.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::uninlined_format_args)]\n\npub struct ArrayWrapper<const N: usize>([usize; N]);\n\nimpl<const N: usize> ArrayWrapper<{ N }> {\n    pub fn ice(&self) {\n        for i in self.0.iter() {\n            println!(\"{i}\");\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-4968.rs",
    "content": "//@ check-pass\n// Test for https://github.com/rust-lang/rust-clippy/issues/4968\n\n#![warn(clippy::unsound_collection_transmute)]\n#![allow(clippy::transmute_undefined_repr)]\n\ntrait Trait {\n    type Assoc;\n}\n\nuse std::mem::{self, ManuallyDrop};\n\n#[allow(unused)]\nfn func<T: Trait>(slice: Vec<T::Assoc>) {\n    unsafe {\n        let _: Vec<ManuallyDrop<T::Assoc>> = mem::transmute(slice);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5207.rs",
    "content": "//@ check-pass\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/5207\npub async fn bar<'a, T: 'a>(_: T) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5223.rs",
    "content": "//@ check-pass\n// Regression test for #5233\n#![warn(clippy::indexing_slicing, clippy::iter_cloned_collect)]\n\npub struct KotomineArray<T, const N: usize> {\n    arr: [T; N],\n}\n\nimpl<T: std::clone::Clone, const N: usize> KotomineArray<T, N> {\n    pub fn ice(self) {\n        let _ = self.arr[..];\n        let _ = self.arr.iter().cloned().collect::<Vec<_>>();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5238.rs",
    "content": "//@ check-pass\n// Regression test for #5238 / https://github.com/rust-lang/rust/pull/69562\n\n#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]\n\nfn main() {\n    let _ = #[coroutine]\n    || {\n        yield;\n    };\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5389.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::explicit_counter_loop)]\n\nfn main() {\n    let v = vec![1, 2, 3];\n    let mut i = 0;\n    let max_storage_size = [0; 128 * 1024];\n    for item in &v {\n        bar(i, *item);\n        i += 1;\n    }\n}\n\nfn bar(_: usize, _: u32) {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5497.rs",
    "content": "// reduced from rustc issue-69020-assoc-const-arith-overflow.rs\n#![allow(clippy::out_of_bounds_indexing)]\n\npub fn main() {}\n\npub trait Foo {\n    const OOB: i32;\n}\n\nimpl<T: Foo> Foo for Vec<T> {\n    const OOB: i32 = [1][1] + T::OOB;\n    //~^ ERROR: operation will panic\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5497.stderr",
    "content": "error: this operation will panic at runtime\n  --> tests/ui/crashes/ice-5497.rs:11:22\n   |\nLL |     const OOB: i32 = [1][1] + T::OOB;\n   |                      ^^^^^^ index out of bounds: the length is 1 but the index is 1\n   |\n   = note: `#[deny(unconditional_panic)]` on by default\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-5579.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::unnecessary_literal_unwrap)]\n\ntrait IsErr {\n    fn is_err(&self, err: &str) -> bool;\n}\n\nimpl<T> IsErr for Option<T> {\n    fn is_err(&self, _err: &str) -> bool {\n        true\n    }\n}\n\nfn main() {\n    let t = Some(1);\n\n    if t.is_err(\"\") {\n        t.unwrap();\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5835.1.fixed",
    "content": "#[rustfmt::skip]\npub struct Foo {\n    /// 位    \n    //~^ tabs_in_doc_comments\n    //~| empty_line_after_doc_comments\n    ///   ^ Do not remove this tab character.\n    ///   It was required to trigger the ICE.\n    pub bar: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5835.2.fixed",
    "content": "#[rustfmt::skip]\npub struct Foo {\n    // /// 位    \n    //~^ tabs_in_doc_comments\n    //~| empty_line_after_doc_comments\n\n\n    ///   ^ Do not remove this tab character.\n    ///   It was required to trigger the ICE.\n    pub bar: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5835.fixed",
    "content": "#[rustfmt::skip]\npub struct Foo {\n    //~v tabs_in_doc_comments\n    /// 位    \n    ///   ^ Do not remove this tab character.\n    ///   It was required to trigger the ICE.\n    pub bar: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5835.rs",
    "content": "#[rustfmt::skip]\npub struct Foo {\n    //~v tabs_in_doc_comments\n    /// 位\t\n    ///   ^ Do not remove this tab character.\n    ///   It was required to trigger the ICE.\n    pub bar: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5835.stderr",
    "content": "error: using tabs in doc comments is not recommended\n  --> tests/ui/crashes/ice-5835.rs:4:10\n   |\nLL |     /// 位    \n   |           ^^^^ help: consider using four spaces per tab\n   |\n   = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-5872.fixed",
    "content": "#![warn(clippy::needless_collect)]\n\nfn main() {\n    let _ = vec![1, 2, 3].into_iter().next().is_none();\n    //~^ needless_collect\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5872.rs",
    "content": "#![warn(clippy::needless_collect)]\n\nfn main() {\n    let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty();\n    //~^ needless_collect\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-5872.stderr",
    "content": "error: avoid using `collect()` when not needed\n  --> tests/ui/crashes/ice-5872.rs:4:39\n   |\nLL |     let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty();\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`\n   |\n   = note: `-D clippy::needless-collect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-5944.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::repeat_once)]\n#![allow(clippy::let_unit_value)]\n\ntrait Repeat {\n    fn repeat(&self) {}\n}\n\nimpl Repeat for usize {\n    fn repeat(&self) {}\n}\n\nfn main() {\n    let _ = 42.repeat();\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6139.rs",
    "content": "//@ check-pass\n\ntrait T<'a> {}\n\nfn foo(_: Vec<Box<dyn T<'_>>>) {}\n\nfn main() {\n    foo(vec![]);\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6153.rs",
    "content": "//@ check-pass\n\npub struct S<'a, 'e>(&'a str, &'e str);\n\npub type T<'a, 'e> = std::collections::HashMap<S<'a, 'e>, ()>;\n\nimpl<'e, 'a: 'e> S<'a, 'e> {\n    pub fn foo(_a: &str, _b: &str, _map: &T) {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6179.rs",
    "content": "//@ check-pass\n//! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179.\n//! The ICE is mainly caused by using `lower_ty`. See the discussion in the PR for details.\n\n#![warn(clippy::use_self)]\n#![allow(dead_code, clippy::let_with_type_underscore)]\n#![allow(non_local_definitions)]\n\nstruct Foo;\n\nimpl Foo {\n    fn new() -> Self {\n        impl Foo {\n            fn bar() {}\n        }\n\n        let _: _ = 1;\n\n        Self {}\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6250.fixed",
    "content": "// originally from glacier/fixed/77218.rs\n// ice while adjusting...\n#![expect(clippy::useless_vec)]\n\npub struct Cache {\n    data: Vec<i32>,\n}\n\npub fn list_data(cache: &Cache, key: usize) {\n    for reference in vec![1, 2, 3] {\n        if\n        /* let */\n        let Some(reference) = cache.data.get(key) {\n            //~^ ERROR: mismatched types\n            //~| ERROR: mismatched types\n            unimplemented!()\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6250.rs",
    "content": "// originally from glacier/fixed/77218.rs\n// ice while adjusting...\n#![expect(clippy::useless_vec)]\n\npub struct Cache {\n    data: Vec<i32>,\n}\n\npub fn list_data(cache: &Cache, key: usize) {\n    for reference in vec![1, 2, 3] {\n        if\n        /* let */\n        Some(reference) = cache.data.get(key) {\n            //~^ ERROR: mismatched types\n            //~| ERROR: mismatched types\n            unimplemented!()\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6250.stderr",
    "content": "error[E0308]: mismatched types\n  --> tests/ui/crashes/ice-6250.rs:13:14\n   |\nLL |     for reference in vec![1, 2, 3] {\n   |         --------- expected due to the type of this binding\n...\nLL |         Some(reference) = cache.data.get(key) {\n   |              ^^^^^^^^^ expected integer, found `&i32`\n\nerror[E0308]: mismatched types\n  --> tests/ui/crashes/ice-6250.rs:13:9\n   |\nLL |         Some(reference) = cache.data.get(key) {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`\n   |\nhelp: consider adding `let`\n   |\nLL |         let Some(reference) = cache.data.get(key) {\n   |         +++\n\nerror: aborting due to 2 previous errors\n\nFor more information about this error, try `rustc --explain E0308`.\n"
  },
  {
    "path": "tests/ui/crashes/ice-6251.rs",
    "content": "// originally from glacier/fixed/77329.rs\n// assertion failed: `(left == right)` ; different DefIds\n//@no-rustfix\nfn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {\n    //~^ ERROR: the size for values\n    //~| ERROR: the size for values\n    //~| ERROR: mismatched types\n    std::iter::empty()\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6251.stderr",
    "content": "error[E0277]: the size for values of type `[u8]` cannot be known at compilation time\n  --> tests/ui/crashes/ice-6251.rs:4:48\n   |\nLL | fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {\n   |                                                ^^^^ doesn't have a size known at compile-time\n   |\n   = help: the trait `std::marker::Sized` is not implemented for `[u8]`\n   = help: unsized fn params are gated as an unstable feature\nhelp: function arguments must have a statically known size, borrowed slices always have a known size\n   |\nLL | fn bug<T>() -> impl Iterator<Item = [(); { |x: &[u8]| x }]> {\n   |                                                +\n\nerror[E0277]: the size for values of type `[u8]` cannot be known at compilation time\n  --> tests/ui/crashes/ice-6251.rs:4:54\n   |\nLL | fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {\n   |                                                      ^ doesn't have a size known at compile-time\n   |\n   = help: the trait `std::marker::Sized` is not implemented for `[u8]`\n   = note: the return type of a function must have a statically known size\n\nerror[E0308]: mismatched types\n  --> tests/ui/crashes/ice-6251.rs:4:44\n   |\nLL | fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {\n   |                                            ^^^^^^^^^^^ expected `usize`, found closure\n   |\n   = note: expected type `usize`\n           found closure `{closure@tests/ui/crashes/ice-6251.rs:4:44: 4:53}`\n\nerror: aborting due to 3 previous errors\n\nSome errors have detailed explanations: E0277, E0308.\nFor more information about an error, try `rustc --explain E0277`.\n"
  },
  {
    "path": "tests/ui/crashes/ice-6252.rs",
    "content": "// originally from glacier fixed/77919.rs\n// encountered errors resolving bounds after type-checking\n//@no-rustfix\ntrait TypeVal<T> {\n    const VAL: T;\n}\nstruct Five;\nstruct Multiply<N, M> {\n    _n: PhantomData,\n    //~^ ERROR: cannot find type\n}\nimpl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}\n//~^ ERROR: cannot find type\n//~| ERROR: not all trait items\n\nfn main() {\n    [1; <Multiply<Five, Five>>::VAL];\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6252.stderr",
    "content": "error[E0425]: cannot find type `PhantomData` in this scope\n  --> tests/ui/crashes/ice-6252.rs:9:9\n   |\nLL |     _n: PhantomData,\n   |         ^^^^^^^^^^^ not found in this scope\n   |\nhelp: consider importing this struct\n   |\nLL + use std::marker::PhantomData;\n   |\n\nerror[E0425]: cannot find type `VAL` in this scope\n  --> tests/ui/crashes/ice-6252.rs:12:63\n   |\nLL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}\n   |                                                               ^^^ not found in this scope\n   |\nhelp: you might be missing a type parameter\n   |\nLL | impl<N, M, VAL> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}\n   |          +++++\n\nerror[E0046]: not all trait items implemented, missing: `VAL`\n  --> tests/ui/crashes/ice-6252.rs:12:1\n   |\nLL |     const VAL: T;\n   |     ------------ `VAL` from trait\n...\nLL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation\n\nerror: aborting due to 3 previous errors\n\nSome errors have detailed explanations: E0046, E0425.\nFor more information about an error, try `rustc --explain E0046`.\n"
  },
  {
    "path": "tests/ui/crashes/ice-6254.rs",
    "content": "//@ check-pass\n// originally from ./tests/ui/pattern/usefulness/consts-opaque.rs\n// panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())',\n// compiler/rustc_mir_build/src/thir/pattern/_match.rs:2030:5\n\n#![allow(clippy::derive_partial_eq_without_eq, clippy::single_match)]\n\n#[derive(PartialEq)]\nstruct Foo(i32);\nconst FOO_REF_REF: &&Foo = &&Foo(42);\n\nfn main() {\n    // This used to cause an ICE (https://github.com/rust-lang/rust/issues/78071)\n    match FOO_REF_REF {\n        FOO_REF_REF => {},\n        Foo(_) => {},\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6255.rs",
    "content": "// originally from rustc ./tests/ui/macros/issue-78325-inconsistent-resolution.rs\n// inconsistent resolution for a macro\n\nmacro_rules! define_other_core {\n    ( ) => {\n        extern crate std as core;\n        //~^ ERROR: macro-expanded `extern crate` items cannot shadow names passed with `--extern`\n    };\n}\n\nfn main() {\n    core::panic!(); //~ ERROR: `core` is ambiguous\n}\n\ndefine_other_core!();\n"
  },
  {
    "path": "tests/ui/crashes/ice-6255.stderr",
    "content": "error: macro-expanded `extern crate` items cannot shadow names passed with `--extern`\n  --> tests/ui/crashes/ice-6255.rs:6:9\n   |\nLL |         extern crate std as core;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | define_other_core!();\n   | -------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror[E0659]: `core` is ambiguous\n  --> tests/ui/crashes/ice-6255.rs:12:5\n   |\nLL |     core::panic!();\n   |     ^^^^ ambiguous name\n   |\n   = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution\n   = note: `core` could refer to a built-in crate\nnote: `core` could also refer to the crate imported here\n  --> tests/ui/crashes/ice-6255.rs:6:9\n   |\nLL |         extern crate std as core;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | define_other_core!();\n   | -------------------- in this macro invocation\n   = help: use `crate::core` to refer to this crate unambiguously\n   = note: this error originates in the macro `define_other_core` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 2 previous errors\n\nFor more information about this error, try `rustc --explain E0659`.\n"
  },
  {
    "path": "tests/ui/crashes/ice-6256.rs",
    "content": "// originally from rustc ./tests/ui/regions/issue-78262.rs\n// ICE: to get the signature of a closure, use args.as_closure().sig() not fn_sig()\n#![allow(clippy::upper_case_acronyms)]\n\ntrait TT {}\n\nimpl dyn TT {\n    fn func(&self) {}\n}\n\n#[rustfmt::skip]\nfn main() {\n    let f = |x: &dyn TT| x.func();\n    //~^ ERROR: borrowed data escapes outside of closure\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6256.stderr",
    "content": "error[E0521]: borrowed data escapes outside of closure\n  --> tests/ui/crashes/ice-6256.rs:13:26\n   |\nLL |     let f = |x: &dyn TT| x.func();\n   |              -  -        ^^^^^^^^\n   |              |  |        |\n   |              |  |        `x` escapes the closure body here\n   |              |  |        argument requires that `'1` must outlive `'static`\n   |              |  let's call the lifetime of this reference `'1`\n   |              `x` is a reference that is only valid in the closure body\n\nerror: aborting due to 1 previous error\n\nFor more information about this error, try `rustc --explain E0521`.\n"
  },
  {
    "path": "tests/ui/crashes/ice-6332.rs",
    "content": "//@ check-pass\n\nfn cmark_check() {\n    let mut link_err = false;\n    macro_rules! cmark_error {\n        ($bad:expr) => {\n            *$bad = true;\n        };\n    }\n    cmark_error!(&mut link_err);\n}\n\npub fn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6539.rs",
    "content": "//@ check-pass\n// The test for the ICE 6539: https://github.com/rust-lang/rust-clippy/issues/6539.\n// The cause is that `zero_sized_map_values` used `layout_of` with types from type aliases,\n// which is essentially the same as the ICE 4968.\n// Note that only type aliases with associated types caused the crash this time,\n// not others such as trait impls.\n\nuse std::collections::{BTreeMap, HashMap};\n\npub trait Trait {\n    type Assoc;\n}\n\ntype TypeAlias<T> = HashMap<(), <T as Trait>::Assoc>;\ntype TypeAlias2<T> = BTreeMap<(), <T as Trait>::Assoc>;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6792.rs",
    "content": "//@ check-pass\n//! This is a reproducer for the ICE 6792: https://github.com/rust-lang/rust-clippy/issues/6792.\n//! The ICE is caused by using `TyCtxt::type_of(assoc_type_id)`.\n\ntrait Trait {\n    type Ty;\n\n    fn broken() -> Self::Ty;\n}\n\nstruct Foo;\n\nimpl Trait for Foo {\n    type Ty = Foo;\n\n    fn broken() -> Self::Ty {\n        Self::Ty {}\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6793.rs",
    "content": "//@ check-pass\n//! This is a reproducer for the ICE 6793: https://github.com/rust-lang/rust-clippy/issues/6793.\n//! The ICE is caused by using `TyCtxt::type_of(assoc_type_id)`, which is the same as the ICE 6792.\n\ntrait Trait {\n    type Ty: 'static + Clone;\n\n    fn broken() -> Self::Ty;\n}\n\n#[derive(Clone)]\nstruct MyType {\n    x: i32,\n}\n\nimpl Trait for MyType {\n    type Ty = MyType;\n\n    fn broken() -> Self::Ty {\n        Self::Ty { x: 1 }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-6840.rs",
    "content": "//@ check-pass\n//! This is a reproducer for the ICE 6840: https://github.com/rust-lang/rust-clippy/issues/6840.\n//! The ICE is caused by `TyCtxt::layout_of` and `is_normalizable` not being strict enough\n#![allow(dead_code)]\n#![deny(clippy::zero_sized_map_values)] // For ICE 14822\nuse std::collections::HashMap;\n\npub trait Rule {\n    type DependencyKey;\n}\n\npub struct RuleEdges<R: Rule> {\n    dependencies: R::DependencyKey,\n}\n\ntype RuleDependencyEdges<R> = HashMap<u32, RuleEdges<R>>;\n\n// reproducer from the GitHub issue ends here\n//   but check some additional variants\ntype RuleDependencyEdgesArray<R> = HashMap<u32, [RuleEdges<R>; 8]>;\ntype RuleDependencyEdgesSlice<R> = HashMap<u32, &'static [RuleEdges<R>]>;\ntype RuleDependencyEdgesRef<R> = HashMap<u32, &'static RuleEdges<R>>;\ntype RuleDependencyEdgesRaw<R> = HashMap<u32, *const RuleEdges<R>>;\ntype RuleDependencyEdgesTuple<R> = HashMap<u32, (RuleEdges<R>, RuleEdges<R>)>;\n\n// and an additional checks to make sure fix doesn't have stack-overflow issue\n//   on self-containing types\npub struct SelfContaining {\n    inner: Box<SelfContaining>,\n}\ntype SelfContainingEdges = HashMap<u32, SelfContaining>;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-700.rs",
    "content": "//@ check-pass\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/700\n\nfn core() {}\n\nfn main() {\n    core();\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7012.rs",
    "content": "//@ check-pass\n\n#![expect(clippy::single_match)]\n\nenum _MyOption {\n    None,\n    Some(()),\n}\n\nimpl _MyOption {\n    fn _foo(&self) {\n        match self {\n            &Self::Some(_) => {},\n            _ => {},\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7126.rs",
    "content": "//@ check-pass\n// This test requires a feature gated const fn and will stop working in the future.\n\n#![feature(const_btree_len)]\n\nuse std::collections::BTreeMap;\n\nstruct Foo(usize);\nimpl Foo {\n    fn new() -> Self {\n        Self(BTreeMap::len(&BTreeMap::<u8, u8>::new()))\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7169.fixed",
    "content": "#![allow(clippy::needless_ifs)]\n\n#[derive(Default)]\nstruct A<T> {\n    a: Vec<A<T>>,\n    b: T,\n}\n\nfn main() {\n    if Ok::<_, ()>(A::<String>::default()).is_ok() {}\n    //~^ redundant_pattern_matching\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7169.rs",
    "content": "#![allow(clippy::needless_ifs)]\n\n#[derive(Default)]\nstruct A<T> {\n    a: Vec<A<T>>,\n    b: T,\n}\n\nfn main() {\n    if let Ok(_) = Ok::<_, ()>(A::<String>::default()) {}\n    //~^ redundant_pattern_matching\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7169.stderr",
    "content": "error: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/crashes/ice-7169.rs:10:12\n   |\nLL |     if let Ok(_) = Ok::<_, ()>(A::<String>::default()) {}\n   |     -------^^^^^-------------------------------------- help: try: `if Ok::<_, ()>(A::<String>::default()).is_ok()`\n   |\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-7231.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::never_loop)]\n\nasync fn f() {\n    loop {\n        break;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7272.rs",
    "content": "//@ check-pass\n//@aux-build:ice-7272-aux.rs\n\n#![allow(clippy::no_effect)]\n\nextern crate ice_7272_aux;\n\nuse ice_7272_aux::*;\n\npub fn main() {\n    || WARNING!(\"Style changed!\");\n    || \"}{\";\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7340.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::no_effect)]\n\nfn main() {\n    const CONSTANT: usize = 8;\n    [1; 1 % CONSTANT];\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7410.rs",
    "content": "//@ check-pass\n//@compile-flags: -Clink-arg=-nostartfiles\n//@ignore-target: windows\n\n#![crate_type = \"lib\"]\n#![no_std]\n#![allow(clippy::if_same_then_else)]\n#![allow(clippy::redundant_pattern_matching)]\n#![allow(clippy::needless_else)]\n\nuse core::panic::PanicInfo;\n\nstruct S;\n\nimpl Drop for S {\n    fn drop(&mut self) {}\n}\n\npub fn main(argc: isize, argv: *const *const u8) -> isize {\n    if let Some(_) = Some(S) {\n    } else {\n    }\n    0\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7423.rs",
    "content": "//@ check-pass\n\npub trait Trait {\n    fn f();\n}\n\nimpl Trait for usize {\n    fn f() {\n        unsafe extern \"C\" {\n            fn g() -> usize;\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7868.rs",
    "content": "//@error-in-other-file:\n#![warn(clippy::undocumented_unsafe_blocks)]\n#![allow(clippy::no_effect)]\n\n#[path = \"auxiliary/ice-7868-aux.rs\"]\nmod zero;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7868.stderr",
    "content": "error: unsafe block missing a safety comment\n  --> tests/ui/crashes/auxiliary/ice-7868-aux.rs:2:5\n   |\nLL |     unsafe { 0 };\n   |     ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-7869.rs",
    "content": "enum Tila {\n    //~^ enum_variant_names\n    TyöAlkoi,\n    TyöKeskeytyi,\n    TyöValmis,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-7869.stderr",
    "content": "error: all variants have the same prefix: `Työ`\n  --> tests/ui/crashes/ice-7869.rs:1:1\n   |\nLL | / enum Tila {\nLL | |\nLL | |     TyöAlkoi,\nLL | |     TyöKeskeytyi,\nLL | |     TyöValmis,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes and use full paths to the variants instead of glob imports\n   = note: `-D clippy::enum-variant-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-7934.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::undocumented_unsafe_blocks)]\n#![allow(clippy::no_effect)]\n\n#[path = \"auxiliary/ice-7934-aux.rs\"]\nmod zero;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-8250.fixed",
    "content": "fn _f(s: &str) -> Option<()> {\n    let _ = s[1..].split('.').next()?;\n    //~^ needless_splitn\n\n    Some(())\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-8250.rs",
    "content": "fn _f(s: &str) -> Option<()> {\n    let _ = s[1..].splitn(2, '.').next()?;\n    //~^ needless_splitn\n\n    Some(())\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-8250.stderr",
    "content": "error: unnecessary use of `splitn`\n  --> tests/ui/crashes/ice-8250.rs:2:13\n   |\nLL |     let _ = s[1..].splitn(2, '.').next()?;\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `s[1..].split('.')`\n   |\n   = note: `-D clippy::needless-splitn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_splitn)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-8386.rs",
    "content": "//@ check-pass\n\nfn f(x: u32, mut arg: &String) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-8681.rs",
    "content": "//@ check-pass\n//@aux-build: ice-8681-aux.rs\n\n#![warn(clippy::undocumented_unsafe_blocks)]\n\n#[path = \"auxiliary/ice-8681-aux.rs\"]\nmod ice_8681_aux;\n\nfn main() {\n    let _ = ice_8681_aux::foo(&0u32);\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-8821.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::let_unit_value)]\n\nfn f() {}\nstatic FN: fn() = f;\n\nfn main() {\n    let _: () = FN();\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-8850.fixed",
    "content": "fn fn_pointer_static() -> usize {\n    static FN: fn() -> usize = || 1;\n    \n    FN() + 1\n    //~^ let_and_return\n}\n\nfn fn_pointer_const() -> usize {\n    const FN: fn() -> usize = || 1;\n    \n    FN() + 1\n    //~^ let_and_return\n}\n\nfn deref_to_dyn_fn() -> usize {\n    struct Derefs;\n    impl std::ops::Deref for Derefs {\n        type Target = dyn Fn() -> usize;\n\n        fn deref(&self) -> &Self::Target {\n            &|| 2\n        }\n    }\n    static FN: Derefs = Derefs;\n    \n    FN() + 1\n    //~^ let_and_return\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-8850.rs",
    "content": "fn fn_pointer_static() -> usize {\n    static FN: fn() -> usize = || 1;\n    let res = FN() + 1;\n    res\n    //~^ let_and_return\n}\n\nfn fn_pointer_const() -> usize {\n    const FN: fn() -> usize = || 1;\n    let res = FN() + 1;\n    res\n    //~^ let_and_return\n}\n\nfn deref_to_dyn_fn() -> usize {\n    struct Derefs;\n    impl std::ops::Deref for Derefs {\n        type Target = dyn Fn() -> usize;\n\n        fn deref(&self) -> &Self::Target {\n            &|| 2\n        }\n    }\n    static FN: Derefs = Derefs;\n    let res = FN() + 1;\n    res\n    //~^ let_and_return\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-8850.stderr",
    "content": "error: returning the result of a `let` binding from a block\n  --> tests/ui/crashes/ice-8850.rs:4:5\n   |\nLL |     let res = FN() + 1;\n   |     ------------------- unnecessary `let` binding\nLL |     res\n   |     ^^^\n   |\n   = note: `-D clippy::let-and-return` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     FN() + 1\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/crashes/ice-8850.rs:11:5\n   |\nLL |     let res = FN() + 1;\n   |     ------------------- unnecessary `let` binding\nLL |     res\n   |     ^^^\n   |\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     FN() + 1\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/crashes/ice-8850.rs:26:5\n   |\nLL |     let res = FN() + 1;\n   |     ------------------- unnecessary `let` binding\nLL |     res\n   |     ^^^\n   |\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     FN() + 1\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-9041.fixed",
    "content": "#![warn(clippy::search_is_some)]\n#![allow(clippy::needless_borrow)]\n\npub struct Thing;\n\npub fn has_thing(things: &[Thing]) -> bool {\n    let is_thing_ready = |_peer: &Thing| -> bool { todo!() };\n    things.iter().any(|p| is_thing_ready(&p))\n    //~^ search_is_some\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-9041.rs",
    "content": "#![warn(clippy::search_is_some)]\n#![allow(clippy::needless_borrow)]\n\npub struct Thing;\n\npub fn has_thing(things: &[Thing]) -> bool {\n    let is_thing_ready = |_peer: &Thing| -> bool { todo!() };\n    things.iter().find(|p| is_thing_ready(p)).is_some()\n    //~^ search_is_some\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-9041.stderr",
    "content": "error: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/crashes/ice-9041.rs:8:19\n   |\nLL |     things.iter().find(|p| is_thing_ready(p)).is_some()\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|p| is_thing_ready(&p))`\n   |\n   = note: `-D clippy::search-is-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-9238.rs",
    "content": "//@ check-pass\n\n#![allow(incomplete_features)]\n#![feature(generic_const_exprs)]\n#![warn(clippy::branches_sharing_code)]\n\nconst fn f() -> usize {\n    2\n}\nconst C: [f64; f()] = [0f64; f()];\n\nfn main() {\n    let _ = if true { C[0] } else { C[1] };\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-9242.rs",
    "content": "//@ check-pass\n\nenum E {\n    X(),\n    Y,\n}\n\nfn main() {\n    let _ = if let E::X() = E::X() { 1 } else { 2 };\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-9405.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::useless_format)]\n#![allow(clippy::print_literal)]\n\nfn main() {\n    println!(\n        \"\\\n\n            {}\",\n        \"multiple skipped lines\"\n    );\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-9405.stderr",
    "content": "warning: multiple lines skipped by escaped newline\n  --> tests/ui/crashes/ice-9405.rs:8:10\n   |\nLL |           \"\\\n   |  __________^\nLL | |\nLL | |             {}\",\n   | |____________^ skipping everything up to and including this point\n\nwarning: 1 warning emitted\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-9414.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::result_large_err)]\n\ntrait T {}\nfn f(_: &u32) -> Result<(), *const (dyn '_ + T)> {\n    Ok(())\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-9459.rs",
    "content": "//@ check-pass\n\n#![feature(unsized_fn_params)]\n\npub fn f0(_f: dyn FnOnce()) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-9463.rs",
    "content": "//@check-pass\n\nfn main() {\n    let _x = -1_i32 >> -1;\n    #[expect(overflowing_literals)]\n    let _y = 1u32 >> 10000000000000u32;\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-9625.rs",
    "content": "//@ check-pass\n\nfn main() {\n    let x = &1;\n    let _ = &1 < x && x < &10;\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice-96721.fixed",
    "content": "macro_rules! foo {\n    () => {\n        \"bar.rs\"\n    };\n}\n\n#[path = \"file\"] //~ ERROR: malformed `path` attribute\nmod abc {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-96721.rs",
    "content": "macro_rules! foo {\n    () => {\n        \"bar.rs\"\n    };\n}\n\n#[path = foo!()] //~ ERROR: malformed `path` attribute\nmod abc {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-96721.stderr",
    "content": "error: malformed `path` attribute input\n  --> tests/ui/crashes/ice-96721.rs:7:1\n   |\nLL | #[path = foo!()]\n   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[path = \"file\"]`\n   |\n   = note: for more information, visit <https://doc.rust-lang.org/reference/items/modules.html#the-path-attribute>\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/ice-9746.rs",
    "content": "//@ check-pass\n//! <https://github.com/rust-lang/rust-clippy/issues/9746#issuecomment-1297132880>\n\ntrait Trait {}\n\nstruct Struct<'a> {\n    _inner: &'a Struct<'a>,\n}\n\nimpl Trait for Struct<'_> {}\n\nfn example<'a>(s: &'a Struct) -> Box<Box<dyn Trait + 'a>> {\n    Box::new(Box::new(Struct { _inner: s }))\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/ice-rust-107877.rs",
    "content": "//@ check-pass\n\n#![allow(dead_code)]\n\nstruct Foo;\n\n#[allow(clippy::infallible_try_from)]\nimpl<'a> std::convert::TryFrom<&'a String> for Foo {\n    type Error = std::convert::Infallible;\n\n    fn try_from(_: &'a String) -> Result<Self, Self::Error> {\n        Ok(Foo)\n    }\n}\n\nfn find<E>(_: impl std::convert::TryInto<Foo, Error = E>) {}\n\nfn main() {\n    find(&String::new());\n}\n"
  },
  {
    "path": "tests/ui/crashes/ice_exact_size.rs",
    "content": "//@ check-pass\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/1336\n\nstruct Foo;\n\nimpl Iterator for Foo {\n    type Item = ();\n\n    fn next(&mut self) -> Option<()> {\n        let _ = self.len() == 0;\n        unimplemented!()\n    }\n}\n\nimpl ExactSizeIterator for Foo {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/if_same_then_else.rs",
    "content": "//@ check-pass\n\n#![deny(clippy::if_same_then_else)]\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/2426\n\nfn main() {}\n\npub fn foo(a: i32, b: i32) -> Option<&'static str> {\n    if a == b {\n        None\n    } else if a > b {\n        Some(\"a pfeil b\")\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/implements-trait.rs",
    "content": "//@ check-pass\n\n#[allow(clippy::needless_borrowed_reference)]\nfn main() {\n    let mut v = Vec::<String>::new();\n    let _ = v.iter_mut().filter(|&ref a| a.is_empty());\n}\n"
  },
  {
    "path": "tests/ui/crashes/inherent_impl.rs",
    "content": "//@ check-pass\n\n#![deny(clippy::multiple_inherent_impl)]\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/4578\n\nmacro_rules! impl_foo {\n    ($struct:ident) => {\n        impl $struct {\n            fn foo() {}\n        }\n    };\n}\n\nmacro_rules! impl_bar {\n    ($struct:ident) => {\n        impl $struct {\n            fn bar() {}\n        }\n    };\n}\n\nstruct MyStruct;\n\nimpl_foo!(MyStruct);\nimpl_bar!(MyStruct);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/issue-825.rs",
    "content": "//@ check-pass\n\n#![allow(warnings)]\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/825\n\n// this should compile in a reasonable amount of time\nfn rust_type_id(name: &str) {\n    if \"bool\" == &name[..]\n        || \"uint\" == &name[..]\n        || \"u8\" == &name[..]\n        || \"u16\" == &name[..]\n        || \"u32\" == &name[..]\n        || \"f32\" == &name[..]\n        || \"f64\" == &name[..]\n        || \"i8\" == &name[..]\n        || \"i16\" == &name[..]\n        || \"i32\" == &name[..]\n        || \"i64\" == &name[..]\n        || \"Self\" == &name[..]\n        || \"str\" == &name[..]\n    {\n        unreachable!();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/issues_loop_mut_cond.rs",
    "content": "//@ check-pass\n\n#![allow(dead_code)]\n\n/// Issue: https://github.com/rust-lang/rust-clippy/issues/2596\npub fn loop_on_block_condition(u: &mut isize) {\n    while { *u < 0 } {\n        *u += 1;\n    }\n}\n\n/// https://github.com/rust-lang/rust-clippy/issues/2584\nfn loop_with_unsafe_condition(ptr: *const u8) {\n    let mut len = 0;\n    while unsafe { *ptr.offset(len) } != 0 {\n        len += 1;\n    }\n}\n\n/// https://github.com/rust-lang/rust-clippy/issues/2710\nstatic mut RUNNING: bool = true;\nfn loop_on_static_condition() {\n    unsafe {\n        while RUNNING {\n            RUNNING = false;\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/match_same_arms_const.rs",
    "content": "//@ check-pass\n\n#![deny(clippy::match_same_arms)]\n\n// Test for https://github.com/rust-lang/rust-clippy/issues/2427\n\nconst PRICE_OF_SWEETS: u32 = 5;\nconst PRICE_OF_KINDNESS: u32 = 0;\nconst PRICE_OF_DRINKS: u32 = 5;\n\npub fn price(thing: &str) -> u32 {\n    match thing {\n        \"rolo\" => PRICE_OF_SWEETS,\n        \"advice\" => PRICE_OF_KINDNESS,\n        \"juice\" => PRICE_OF_DRINKS,\n        _ => panic!(),\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/mgca-16691.rs",
    "content": "//@ check-pass\n#![allow(incomplete_features)]\n#![feature(min_generic_const_args)]\n\ntrait Trait {\n    type const N: usize;\n    fn process();\n}\n\nimpl Trait for () {\n    type const N: usize = 3;\n    fn process() {\n        const N: usize = <()>::N;\n        _ = 0..Self::N;\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/missing_const_for_fn_14774.fixed",
    "content": "//@compile-flags: -Z validate-mir\n#![warn(clippy::missing_const_for_fn)]\n\nstatic BLOCK_FN_DEF: fn(usize) -> usize = {\n    //~v missing_const_for_fn\n    const fn foo(a: usize) -> usize {\n        a + 10\n    }\n    foo\n};\nstruct X;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/missing_const_for_fn_14774.rs",
    "content": "//@compile-flags: -Z validate-mir\n#![warn(clippy::missing_const_for_fn)]\n\nstatic BLOCK_FN_DEF: fn(usize) -> usize = {\n    //~v missing_const_for_fn\n    fn foo(a: usize) -> usize {\n        a + 10\n    }\n    foo\n};\nstruct X;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/missing_const_for_fn_14774.stderr",
    "content": "error: this could be a `const fn`\n  --> tests/ui/crashes/missing_const_for_fn_14774.rs:6:5\n   |\nLL | /     fn foo(a: usize) -> usize {\nLL | |         a + 10\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::missing-const-for-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_const_for_fn)]`\nhelp: make the function `const`\n   |\nLL |     const fn foo(a: usize) -> usize {\n   |     +++++\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/needless_borrow_fp.rs",
    "content": "//@ check-pass\n\n#[derive(Debug)]\npub enum Error {\n    Type(&'static str),\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/needless_pass_by_value-w-late-bound.fixed",
    "content": "// https://github.com/rust-lang/rust/issues/107147\n\n#![warn(clippy::needless_pass_by_value)]\n\nstruct Foo<'a>(&'a [(); 100]);\n\nfn test(x: &Foo<'_>) {}\n//~^ needless_pass_by_value\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/needless_pass_by_value-w-late-bound.rs",
    "content": "// https://github.com/rust-lang/rust/issues/107147\n\n#![warn(clippy::needless_pass_by_value)]\n\nstruct Foo<'a>(&'a [(); 100]);\n\nfn test(x: Foo<'_>) {}\n//~^ needless_pass_by_value\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr",
    "content": "error: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/crashes/needless_pass_by_value-w-late-bound.rs:7:12\n   |\nLL | fn test(x: Foo<'_>) {}\n   |            ^^^^^^^\n   |\nhelp: or consider marking this type as `Copy`\n  --> tests/ui/crashes/needless_pass_by_value-w-late-bound.rs:5:1\n   |\nLL | struct Foo<'a>(&'a [(); 100]);\n   | ^^^^^^^^^^^^^^\n   = note: `-D clippy::needless-pass-by-value` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`\nhelp: consider taking a reference instead\n   |\nLL | fn test(x: &Foo<'_>) {}\n   |            +\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crashes/regressions.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::disallowed_names, clippy::uninlined_format_args)]\n\npub fn foo(bar: *const u8) {\n    println!(\"{:#p}\", bar);\n}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/4917\n/// <foo\nstruct A;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/returns.rs",
    "content": "//@ check-pass\n// Test for https://github.com/rust-lang/rust-clippy/issues/1346\n\n#[deny(warnings)]\nfn cfg_return() -> i32 {\n    #[cfg(unix)]\n    return 1;\n    #[cfg(not(unix))]\n    return 2;\n}\n\n#[deny(warnings)]\nfn cfg_let_and_return() -> i32 {\n    #[cfg(unix)]\n    let x = 1;\n    #[cfg(not(unix))]\n    let x = 2;\n    x\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/shadow.rs",
    "content": "//@ check-pass\n\nfn main() {\n    let x: [i32; {\n        let u = 2;\n        4\n    }] = [2; { 4 }];\n}\n"
  },
  {
    "path": "tests/ui/crashes/single-match-else.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::single_match_else)]\n\n//! Test for https://github.com/rust-lang/rust-clippy/issues/1588\n\nfn main() {\n    let n = match (42, 43) {\n        (42, n) => n,\n        _ => panic!(\"typeck error\"),\n    };\n    assert_eq!(n, 43);\n}\n"
  },
  {
    "path": "tests/ui/crashes/third-party/clippy.toml",
    "content": "# this is ignored by Clippy, but allowed for other tools like clippy-service\n[third-party]\nclippy-feature = \"nightly\"\n"
  },
  {
    "path": "tests/ui/crashes/third-party/conf_allowlisted.rs",
    "content": "//@ check-pass\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/trivial_bounds.rs",
    "content": "//@ check-pass\n\n#![feature(trivial_bounds)]\n#![allow(unused, trivial_bounds)]\n\nfn test_trivial_bounds()\nwhere\n    i32: Iterator,\n{\n    for _ in 2i32 {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crashes/unreachable-array-or-slice.rs",
    "content": "struct Foo(isize, isize, isize, isize);\n\npub fn main() {\n    let Self::anything_here_kills_it(a, b, ..) = Foo(5, 5, 5, 5);\n    //~^ ERROR: cannot find `Self` in this scope\n    match [5, 5, 5, 5] {\n        [..] => {},\n    }\n}\n"
  },
  {
    "path": "tests/ui/crashes/unreachable-array-or-slice.stderr",
    "content": "error[E0433]: cannot find `Self` in this scope\n  --> tests/ui/crashes/unreachable-array-or-slice.rs:4:9\n   |\nLL |     let Self::anything_here_kills_it(a, b, ..) = Foo(5, 5, 5, 5);\n   |         ^^^^ `Self` is only available in impls, traits, and type definitions\n\nerror: aborting due to 1 previous error\n\nFor more information about this error, try `rustc --explain E0433`.\n"
  },
  {
    "path": "tests/ui/crashes/used_underscore_binding_macro.rs",
    "content": "//@ check-pass\n\nuse serde::Deserialize;\n\n/// Tests that we do not lint for unused underscores in a `MacroAttribute`\n/// expansion\n#[deny(clippy::used_underscore_binding)]\n#[derive(Deserialize)]\nstruct MacroAttributesTest {\n    _foo: u32,\n}\n\n#[test]\nfn macro_attributes_test() {\n    let _ = MacroAttributesTest { _foo: 0 };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crate_in_macro_def.fixed",
    "content": "#![warn(clippy::crate_in_macro_def)]\n\nmod hygienic {\n    #[macro_export]\n    macro_rules! print_message_hygienic {\n        () => {\n            println!(\"{}\", $crate::hygienic::MESSAGE);\n        };\n    }\n\n    pub const MESSAGE: &str = \"Hello!\";\n}\n\nmod unhygienic {\n    #[macro_export]\n    macro_rules! print_message_unhygienic {\n        () => {\n            println!(\"{}\", $crate::unhygienic::MESSAGE);\n            //~^ crate_in_macro_def\n        };\n    }\n\n    pub const MESSAGE: &str = \"Hello!\";\n}\n\nmod unhygienic_intentionally {\n    // For cases where the use of `crate` is intentional, applying `allow` to the macro definition\n    // should suppress the lint.\n    #[allow(clippy::crate_in_macro_def)]\n    #[macro_export]\n    macro_rules! print_message_unhygienic_intentionally {\n        () => {\n            println!(\"{}\", crate::CALLER_PROVIDED_MESSAGE);\n        };\n    }\n}\n\n#[macro_use]\nmod not_exported {\n    macro_rules! print_message_not_exported {\n        () => {\n            println!(\"{}\", crate::not_exported::MESSAGE);\n        };\n    }\n\n    pub const MESSAGE: &str = \"Hello!\";\n}\n\nfn main() {\n    print_message_hygienic!();\n    print_message_unhygienic!();\n    print_message_unhygienic_intentionally!();\n    print_message_not_exported!();\n}\n\npub const CALLER_PROVIDED_MESSAGE: &str = \"Hello!\";\n"
  },
  {
    "path": "tests/ui/crate_in_macro_def.rs",
    "content": "#![warn(clippy::crate_in_macro_def)]\n\nmod hygienic {\n    #[macro_export]\n    macro_rules! print_message_hygienic {\n        () => {\n            println!(\"{}\", $crate::hygienic::MESSAGE);\n        };\n    }\n\n    pub const MESSAGE: &str = \"Hello!\";\n}\n\nmod unhygienic {\n    #[macro_export]\n    macro_rules! print_message_unhygienic {\n        () => {\n            println!(\"{}\", crate::unhygienic::MESSAGE);\n            //~^ crate_in_macro_def\n        };\n    }\n\n    pub const MESSAGE: &str = \"Hello!\";\n}\n\nmod unhygienic_intentionally {\n    // For cases where the use of `crate` is intentional, applying `allow` to the macro definition\n    // should suppress the lint.\n    #[allow(clippy::crate_in_macro_def)]\n    #[macro_export]\n    macro_rules! print_message_unhygienic_intentionally {\n        () => {\n            println!(\"{}\", crate::CALLER_PROVIDED_MESSAGE);\n        };\n    }\n}\n\n#[macro_use]\nmod not_exported {\n    macro_rules! print_message_not_exported {\n        () => {\n            println!(\"{}\", crate::not_exported::MESSAGE);\n        };\n    }\n\n    pub const MESSAGE: &str = \"Hello!\";\n}\n\nfn main() {\n    print_message_hygienic!();\n    print_message_unhygienic!();\n    print_message_unhygienic_intentionally!();\n    print_message_not_exported!();\n}\n\npub const CALLER_PROVIDED_MESSAGE: &str = \"Hello!\";\n"
  },
  {
    "path": "tests/ui/crate_in_macro_def.stderr",
    "content": "error: `crate` references the macro call's crate\n  --> tests/ui/crate_in_macro_def.rs:18:28\n   |\nLL |             println!(\"{}\", crate::unhygienic::MESSAGE);\n   |                            ^^^^^ help: to reference the macro definition's crate, use: `$crate`\n   |\n   = note: `-D clippy::crate-in-macro-def` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::crate_in_macro_def)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crate_level_checks/entrypoint_recursion.rs",
    "content": "//@ignore-target: apple\n#![feature(rustc_attrs)]\n#[warn(clippy::main_recursion)]\n#[allow(unconditional_recursion)]\n#[rustc_main]\nfn a() {\n    a();\n    //~^ main_recursion\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/crate_level_checks/entrypoint_recursion.stderr",
    "content": "error: recursing into entrypoint `a`\n  --> tests/ui/crate_level_checks/entrypoint_recursion.rs:7:5\n   |\nLL |     a();\n   |     ^\n   |\n   = help: consider using another function for this recursion\n   = note: `-D clippy::main-recursion` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::main_recursion)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crate_level_checks/no_std_main_recursion.rs",
    "content": "//@check-pass\n//@compile-flags: -Cpanic=abort\n#![no_std]\n#[warn(clippy::main_recursion)]\n#[allow(unconditional_recursion)]\nfn main() {\n    main();\n}\n\n#[panic_handler]\nfn panic(_info: &core::panic::PanicInfo) -> ! {\n    loop {}\n}\n"
  },
  {
    "path": "tests/ui/crate_level_checks/no_std_swap.fixed",
    "content": "#![no_std]\n#![crate_type = \"lib\"]\n\nuse core::panic::PanicInfo;\n\npub fn main() {\n    let mut a = 42;\n    let mut b = 1337;\n\n    core::mem::swap(&mut a, &mut b);\n}\n"
  },
  {
    "path": "tests/ui/crate_level_checks/no_std_swap.rs",
    "content": "#![no_std]\n#![crate_type = \"lib\"]\n\nuse core::panic::PanicInfo;\n\npub fn main() {\n    let mut a = 42;\n    let mut b = 1337;\n\n    a = b;\n    //~^ almost_swapped\n\n    b = a;\n}\n"
  },
  {
    "path": "tests/ui/crate_level_checks/no_std_swap.stderr",
    "content": "error: this looks like you are trying to swap `a` and `b`\n  --> tests/ui/crate_level_checks/no_std_swap.rs:10:5\n   |\nLL | /     a = b;\n...  |\nLL | |     b = a;\n   | |_________^ help: try: `core::mem::swap(&mut a, &mut b)`\n   |\n   = note: or maybe you should use `core::mem::replace`?\n   = note: `#[deny(clippy::almost_swapped)]` on by default\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/crate_level_checks/std_main_recursion.rs",
    "content": "#[warn(clippy::main_recursion)]\n#[allow(unconditional_recursion)]\nfn main() {\n    println!(\"Hello, World!\");\n    main();\n    //~^ main_recursion\n}\n"
  },
  {
    "path": "tests/ui/crate_level_checks/std_main_recursion.stderr",
    "content": "error: recursing into entrypoint `main`\n  --> tests/ui/crate_level_checks/std_main_recursion.rs:5:5\n   |\nLL |     main();\n   |     ^^^^\n   |\n   = help: consider using another function for this recursion\n   = note: `-D clippy::main-recursion` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::main_recursion)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/create_dir.fixed",
    "content": "#![allow(unused_must_use)]\n#![warn(clippy::create_dir)]\n\nuse std::fs::create_dir_all;\n\nfn create_dir() {}\n\nfn main() {\n    // Should be warned\n    std::fs::create_dir_all(\"foo\");\n    //~^ create_dir\n    std::fs::create_dir_all(\"bar\").unwrap();\n    //~^ create_dir\n\n    // Shouldn't be warned\n    create_dir();\n    std::fs::create_dir_all(\"foobar\");\n}\n\nmod issue14994 {\n    fn with_no_prefix() {\n        use std::fs::create_dir;\n        std::fs::create_dir_all(\"some/dir\").unwrap();\n        //~^ create_dir\n    }\n\n    fn with_fs_prefix() {\n        use std::fs;\n        fs::create_dir_all(\"/some/dir\").unwrap();\n        //~^ create_dir\n    }\n\n    fn with_full_prefix() {\n        std::fs::create_dir_all(\"/some/dir\").unwrap();\n        //~^ create_dir\n    }\n}\n"
  },
  {
    "path": "tests/ui/create_dir.rs",
    "content": "#![allow(unused_must_use)]\n#![warn(clippy::create_dir)]\n\nuse std::fs::create_dir_all;\n\nfn create_dir() {}\n\nfn main() {\n    // Should be warned\n    std::fs::create_dir(\"foo\");\n    //~^ create_dir\n    std::fs::create_dir(\"bar\").unwrap();\n    //~^ create_dir\n\n    // Shouldn't be warned\n    create_dir();\n    std::fs::create_dir_all(\"foobar\");\n}\n\nmod issue14994 {\n    fn with_no_prefix() {\n        use std::fs::create_dir;\n        create_dir(\"some/dir\").unwrap();\n        //~^ create_dir\n    }\n\n    fn with_fs_prefix() {\n        use std::fs;\n        fs::create_dir(\"/some/dir\").unwrap();\n        //~^ create_dir\n    }\n\n    fn with_full_prefix() {\n        std::fs::create_dir(\"/some/dir\").unwrap();\n        //~^ create_dir\n    }\n}\n"
  },
  {
    "path": "tests/ui/create_dir.stderr",
    "content": "error: calling `std::fs::create_dir` where there may be a better way\n  --> tests/ui/create_dir.rs:10:5\n   |\nLL |     std::fs::create_dir(\"foo\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::create-dir` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::create_dir)]`\nhelp: consider calling `std::fs::create_dir_all` instead\n   |\nLL |     std::fs::create_dir_all(\"foo\");\n   |                        ++++\n\nerror: calling `std::fs::create_dir` where there may be a better way\n  --> tests/ui/create_dir.rs:12:5\n   |\nLL |     std::fs::create_dir(\"bar\").unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider calling `std::fs::create_dir_all` instead\n   |\nLL |     std::fs::create_dir_all(\"bar\").unwrap();\n   |                        ++++\n\nerror: calling `std::fs::create_dir` where there may be a better way\n  --> tests/ui/create_dir.rs:23:9\n   |\nLL |         create_dir(\"some/dir\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider calling `std::fs::create_dir_all` instead\n   |\nLL |         std::fs::create_dir_all(\"some/dir\").unwrap();\n   |         +++++++++          ++++\n\nerror: calling `std::fs::create_dir` where there may be a better way\n  --> tests/ui/create_dir.rs:29:9\n   |\nLL |         fs::create_dir(\"/some/dir\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider calling `std::fs::create_dir_all` instead\n   |\nLL |         fs::create_dir_all(\"/some/dir\").unwrap();\n   |                       ++++\n\nerror: calling `std::fs::create_dir` where there may be a better way\n  --> tests/ui/create_dir.rs:34:9\n   |\nLL |         std::fs::create_dir(\"/some/dir\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider calling `std::fs::create_dir_all` instead\n   |\nLL |         std::fs::create_dir_all(\"/some/dir\").unwrap();\n   |                            ++++\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/dbg_macro/auxiliary/submodule.rs",
    "content": "fn f() {\n    dbg!();\n}\n"
  },
  {
    "path": "tests/ui/dbg_macro/dbg_macro.fixed",
    "content": "#![allow(\n    clippy::no_effect,\n    clippy::uninlined_format_args,\n    clippy::unit_arg,\n    clippy::unnecessary_operation\n)]\n#![warn(clippy::dbg_macro)]\n\nfn foo(n: u32) -> u32 {\n    if let Some(n) = n.checked_sub(4) { n } else { n }\n    //~^ dbg_macro\n}\nfn bar(_: ()) {}\n\nfn factorial(n: u32) -> u32 {\n    if n <= 1 {\n        //~^ dbg_macro\n\n        1\n        //~^ dbg_macro\n    } else {\n        n * factorial(n - 1)\n        //~^ dbg_macro\n    }\n}\n\nfn main() {\n    42;\n    //~^ dbg_macro\n\n    foo(3) + factorial(4);\n    //~^ dbg_macro\n\n    (1, 2, 3, 4, 5);\n    //~^ dbg_macro\n}\n\nfn issue9914() {\n    macro_rules! foo {\n        ($x:expr) => {\n            $x;\n        };\n    }\n    macro_rules! foo2 {\n        ($x:expr) => {\n            $x;\n        };\n    }\n    macro_rules! expand_to_dbg {\n        () => {\n            \n            //~^ dbg_macro\n        };\n    }\n\n    \n    //~^ dbg_macro\n\n    #[allow(clippy::let_unit_value)]\n    let _ = ();\n    //~^ dbg_macro\n\n    bar(());\n    //~^ dbg_macro\n\n    foo!(());\n    //~^ dbg_macro\n\n    foo2!(foo!(()));\n    //~^ dbg_macro\n\n    expand_to_dbg!();\n}\n\nmod issue7274 {\n    trait Thing<'b> {\n        fn foo(&self);\n    }\n\n    macro_rules! define_thing {\n        ($thing:ident, $body:expr) => {\n            impl<'a> Thing<'a> for $thing {\n                fn foo<'b>(&self) {\n                    $body\n                }\n            }\n        };\n    }\n\n    struct MyThing;\n    define_thing!(MyThing, {\n        2;\n        //~^ dbg_macro\n    });\n}\n\n#[test]\npub fn issue8481() {\n    1;\n    //~^ dbg_macro\n}\n\n#[cfg(test)]\nfn foo2() {\n    1;\n    //~^ dbg_macro\n}\n\n#[cfg(test)]\nmod mod1 {\n    fn func() {\n        1;\n        //~^ dbg_macro\n    }\n}\n\nmod issue12131 {\n    fn dbg_in_print(s: &str) {\n        println!(\"dbg: {:?}\", s);\n        //~^ dbg_macro\n\n        print!(\"{}\", s);\n        //~^ dbg_macro\n    }\n}\n\nmod issue14914 {\n    use std::future::Future;\n\n    fn takes_async_fn<F, Fut>(_f: F)\n    where\n        F: FnOnce(i32) -> Fut,\n        Fut: Future<Output = i32>,\n    {\n    }\n\n    fn should_not_panic() {\n        takes_async_fn(async |val| val);\n        //~^ dbg_macro\n    }\n}\n"
  },
  {
    "path": "tests/ui/dbg_macro/dbg_macro.rs",
    "content": "#![allow(\n    clippy::no_effect,\n    clippy::uninlined_format_args,\n    clippy::unit_arg,\n    clippy::unnecessary_operation\n)]\n#![warn(clippy::dbg_macro)]\n\nfn foo(n: u32) -> u32 {\n    if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }\n    //~^ dbg_macro\n}\nfn bar(_: ()) {}\n\nfn factorial(n: u32) -> u32 {\n    if dbg!(n <= 1) {\n        //~^ dbg_macro\n\n        dbg!(1)\n        //~^ dbg_macro\n    } else {\n        dbg!(n * factorial(n - 1))\n        //~^ dbg_macro\n    }\n}\n\nfn main() {\n    dbg!(42);\n    //~^ dbg_macro\n\n    foo(3) + dbg!(factorial(4));\n    //~^ dbg_macro\n\n    dbg!(1, 2, 3, 4, 5);\n    //~^ dbg_macro\n}\n\nfn issue9914() {\n    macro_rules! foo {\n        ($x:expr) => {\n            $x;\n        };\n    }\n    macro_rules! foo2 {\n        ($x:expr) => {\n            $x;\n        };\n    }\n    macro_rules! expand_to_dbg {\n        () => {\n            dbg!();\n            //~^ dbg_macro\n        };\n    }\n\n    dbg!();\n    //~^ dbg_macro\n\n    #[allow(clippy::let_unit_value)]\n    let _ = dbg!();\n    //~^ dbg_macro\n\n    bar(dbg!());\n    //~^ dbg_macro\n\n    foo!(dbg!());\n    //~^ dbg_macro\n\n    foo2!(foo!(dbg!()));\n    //~^ dbg_macro\n\n    expand_to_dbg!();\n}\n\nmod issue7274 {\n    trait Thing<'b> {\n        fn foo(&self);\n    }\n\n    macro_rules! define_thing {\n        ($thing:ident, $body:expr) => {\n            impl<'a> Thing<'a> for $thing {\n                fn foo<'b>(&self) {\n                    $body\n                }\n            }\n        };\n    }\n\n    struct MyThing;\n    define_thing!(MyThing, {\n        dbg!(2);\n        //~^ dbg_macro\n    });\n}\n\n#[test]\npub fn issue8481() {\n    dbg!(1);\n    //~^ dbg_macro\n}\n\n#[cfg(test)]\nfn foo2() {\n    dbg!(1);\n    //~^ dbg_macro\n}\n\n#[cfg(test)]\nmod mod1 {\n    fn func() {\n        dbg!(1);\n        //~^ dbg_macro\n    }\n}\n\nmod issue12131 {\n    fn dbg_in_print(s: &str) {\n        println!(\"dbg: {:?}\", dbg!(s));\n        //~^ dbg_macro\n\n        print!(\"{}\", dbg!(s));\n        //~^ dbg_macro\n    }\n}\n\nmod issue14914 {\n    use std::future::Future;\n\n    fn takes_async_fn<F, Fut>(_f: F)\n    where\n        F: FnOnce(i32) -> Fut,\n        Fut: Future<Output = i32>,\n    {\n    }\n\n    fn should_not_panic() {\n        takes_async_fn(async |val| dbg!(val));\n        //~^ dbg_macro\n    }\n}\n"
  },
  {
    "path": "tests/ui/dbg_macro/dbg_macro.stderr",
    "content": "error: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:10:22\n   |\nLL |     if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }\n   |                      ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::dbg-macro` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]`\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }\nLL +     if let Some(n) = n.checked_sub(4) { n } else { n }\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:16:8\n   |\nLL |     if dbg!(n <= 1) {\n   |        ^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     if dbg!(n <= 1) {\nLL +     if n <= 1 {\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:19:9\n   |\nLL |         dbg!(1)\n   |         ^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         dbg!(1)\nLL +         1\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:22:9\n   |\nLL |         dbg!(n * factorial(n - 1))\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         dbg!(n * factorial(n - 1))\nLL +         n * factorial(n - 1)\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:28:5\n   |\nLL |     dbg!(42);\n   |     ^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(42);\nLL +     42;\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:31:14\n   |\nLL |     foo(3) + dbg!(factorial(4));\n   |              ^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     foo(3) + dbg!(factorial(4));\nLL +     foo(3) + factorial(4);\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:34:5\n   |\nLL |     dbg!(1, 2, 3, 4, 5);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(1, 2, 3, 4, 5);\nLL +     (1, 2, 3, 4, 5);\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:56:5\n   |\nLL |     dbg!();\n   |     ^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!();\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:60:13\n   |\nLL |     let _ = dbg!();\n   |             ^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     let _ = dbg!();\nLL +     let _ = ();\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:63:9\n   |\nLL |     bar(dbg!());\n   |         ^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     bar(dbg!());\nLL +     bar(());\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:66:10\n   |\nLL |     foo!(dbg!());\n   |          ^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     foo!(dbg!());\nLL +     foo!(());\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:69:16\n   |\nLL |     foo2!(foo!(dbg!()));\n   |                ^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     foo2!(foo!(dbg!()));\nLL +     foo2!(foo!(()));\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:51:13\n   |\nLL |             dbg!();\n   |             ^^^^^^\n...\nLL |     expand_to_dbg!();\n   |     ---------------- in this macro invocation\n   |\n   = note: this error originates in the macro `expand_to_dbg` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -             dbg!();\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:92:9\n   |\nLL |         dbg!(2);\n   |         ^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         dbg!(2);\nLL +         2;\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:99:5\n   |\nLL |     dbg!(1);\n   |     ^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(1);\nLL +     1;\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:105:5\n   |\nLL |     dbg!(1);\n   |     ^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(1);\nLL +     1;\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:112:9\n   |\nLL |         dbg!(1);\n   |         ^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         dbg!(1);\nLL +         1;\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:119:31\n   |\nLL |         println!(\"dbg: {:?}\", dbg!(s));\n   |                               ^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         println!(\"dbg: {:?}\", dbg!(s));\nLL +         println!(\"dbg: {:?}\", s);\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:122:22\n   |\nLL |         print!(\"{}\", dbg!(s));\n   |                      ^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         print!(\"{}\", dbg!(s));\nLL +         print!(\"{}\", s);\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro.rs:138:36\n   |\nLL |         takes_async_fn(async |val| dbg!(val));\n   |                                    ^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         takes_async_fn(async |val| dbg!(val));\nLL +         takes_async_fn(async |val| val);\n   |\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/dbg_macro/dbg_macro_unfixable.rs",
    "content": "//@no-rustfix: overlapping suggestions\n//@error-in-other-file:\n#![warn(clippy::dbg_macro)]\n\n#[path = \"auxiliary/submodule.rs\"]\nmod submodule;\n\nfn main() {\n    dbg!(dbg!(dbg!(42)));\n    //~^ dbg_macro\n    //~| dbg_macro\n    //~| dbg_macro\n\n    dbg!(1, 2, dbg!(3, 4));\n    //~^ dbg_macro\n    //~| dbg_macro\n}\n"
  },
  {
    "path": "tests/ui/dbg_macro/dbg_macro_unfixable.stderr",
    "content": "error: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/auxiliary/submodule.rs:2:5\n   |\nLL |     dbg!();\n   |     ^^^^^^\n   |\n   = note: `-D clippy::dbg-macro` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]`\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!();\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:9:5\n   |\nLL |     dbg!(dbg!(dbg!(42)));\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(dbg!(dbg!(42)));\nLL +     dbg!(dbg!(42));\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:9:10\n   |\nLL |     dbg!(dbg!(dbg!(42)));\n   |          ^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(dbg!(dbg!(42)));\nLL +     dbg!(dbg!(42));\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:9:15\n   |\nLL |     dbg!(dbg!(dbg!(42)));\n   |               ^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(dbg!(dbg!(42)));\nLL +     dbg!(dbg!(42));\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:14:5\n   |\nLL |     dbg!(1, 2, dbg!(3, 4));\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(1, 2, dbg!(3, 4));\nLL +     (1, 2, dbg!(3, 4));\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:14:16\n   |\nLL |     dbg!(1, 2, dbg!(3, 4));\n   |                ^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(1, 2, dbg!(3, 4));\nLL +     dbg!(1, 2, (3, 4));\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/debug_assert_with_mut_call.rs",
    "content": "#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n#![warn(clippy::debug_assert_with_mut_call)]\n#![allow(clippy::redundant_closure_call, clippy::get_first)]\n\n\nstruct S;\n\nimpl S {\n    fn bool_self_ref(&self) -> bool { false }\n    fn bool_self_mut(&mut self) -> bool { false }\n    fn bool_self_ref_arg_ref(&self, _: &u32) -> bool { false }\n    fn bool_self_ref_arg_mut(&self, _: &mut u32) -> bool { false }\n    fn bool_self_mut_arg_ref(&mut self, _: &u32) -> bool { false }\n    fn bool_self_mut_arg_mut(&mut self, _: &mut u32) -> bool { false }\n\n    fn u32_self_ref(&self) -> u32 { 0 }\n    fn u32_self_mut(&mut self) -> u32 { 0 }\n    fn u32_self_ref_arg_ref(&self, _: &u32) -> u32 { 0 }\n    fn u32_self_ref_arg_mut(&self, _: &mut u32) -> u32 { 0 }\n    fn u32_self_mut_arg_ref(&mut self, _: &u32) -> u32 { 0 }\n    fn u32_self_mut_arg_mut(&mut self, _: &mut u32) -> u32 { 0 }\n}\n\nfn bool_ref(_: &u32) -> bool { false }\nfn bool_mut(_: &mut u32) -> bool { false }\nfn u32_ref(_: &u32) -> u32 { 0 }\nfn u32_mut(_: &mut u32) -> u32 { 0 }\n\nfn func_non_mutable() {\n    debug_assert!(bool_ref(&3));\n    debug_assert!(!bool_ref(&3));\n\n    debug_assert_eq!(0, u32_ref(&3));\n    debug_assert_eq!(u32_ref(&3), 0);\n\n    debug_assert_ne!(1, u32_ref(&3));\n    debug_assert_ne!(u32_ref(&3), 1);\n}\n\nfn func_mutable() {\n    debug_assert!(bool_mut(&mut 3));\n    //~^ debug_assert_with_mut_call\n\n\n    debug_assert!(!bool_mut(&mut 3));\n    //~^ debug_assert_with_mut_call\n\n\n    debug_assert_eq!(0, u32_mut(&mut 3));\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_eq!(u32_mut(&mut 3), 0);\n    //~^ debug_assert_with_mut_call\n\n\n    debug_assert_ne!(1, u32_mut(&mut 3));\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_ne!(u32_mut(&mut 3), 1);\n    //~^ debug_assert_with_mut_call\n\n}\n\nfn method_non_mutable() {\n    debug_assert!(S.bool_self_ref());\n    debug_assert!(S.bool_self_ref_arg_ref(&3));\n\n    debug_assert_eq!(S.u32_self_ref(), 0);\n    debug_assert_eq!(S.u32_self_ref_arg_ref(&3), 0);\n\n    debug_assert_ne!(S.u32_self_ref(), 1);\n    debug_assert_ne!(S.u32_self_ref_arg_ref(&3), 1);\n}\n\nfn method_mutable() {\n    debug_assert!(S.bool_self_mut());\n    //~^ debug_assert_with_mut_call\n\n    debug_assert!(!S.bool_self_mut());\n    //~^ debug_assert_with_mut_call\n\n    debug_assert!(S.bool_self_ref_arg_mut(&mut 3));\n    //~^ debug_assert_with_mut_call\n\n    debug_assert!(S.bool_self_mut_arg_ref(&3));\n    //~^ debug_assert_with_mut_call\n\n    debug_assert!(S.bool_self_mut_arg_mut(&mut 3));\n    //~^ debug_assert_with_mut_call\n\n\n    debug_assert_eq!(S.u32_self_mut(), 0);\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_eq!(S.u32_self_mut_arg_ref(&3), 0);\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_eq!(S.u32_self_ref_arg_mut(&mut 3), 0);\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_eq!(S.u32_self_mut_arg_mut(&mut 3), 0);\n    //~^ debug_assert_with_mut_call\n\n\n    debug_assert_ne!(S.u32_self_mut(), 1);\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_ne!(S.u32_self_mut_arg_ref(&3), 1);\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_ne!(S.u32_self_ref_arg_mut(&mut 3), 1);\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_ne!(S.u32_self_mut_arg_mut(&mut 3), 1);\n    //~^ debug_assert_with_mut_call\n\n}\n\nfn misc() {\n    // with variable\n    let mut v: Vec<u32> = vec![1, 2, 3, 4];\n    debug_assert_eq!(v.get(0), Some(&1));\n    debug_assert_ne!(v[0], 2);\n    debug_assert_eq!(v.pop(), Some(1));\n    //~^ debug_assert_with_mut_call\n\n    debug_assert_ne!(Some(3), v.pop());\n    //~^ debug_assert_with_mut_call\n\n\n    let a = &mut 3;\n    debug_assert!(bool_mut(a));\n    //~^ debug_assert_with_mut_call\n\n\n    // nested\n    debug_assert!(!(bool_ref(&u32_mut(&mut 3))));\n    //~^ debug_assert_with_mut_call\n\n\n    // chained\n    debug_assert_eq!(v.pop().unwrap(), 3);\n    //~^ debug_assert_with_mut_call\n\n\n    // format args\n    debug_assert!(bool_ref(&3), \"w/o format\");\n    debug_assert!(bool_mut(&mut 3), \"w/o format\");\n    //~^ debug_assert_with_mut_call\n\n    debug_assert!(bool_ref(&3), \"{} format\", \"w/\");\n    debug_assert!(bool_mut(&mut 3), \"{} format\", \"w/\");\n    //~^ debug_assert_with_mut_call\n\n\n    // sub block\n    let mut x = 42_u32;\n    debug_assert!({\n        bool_mut(&mut x);\n        //~^ debug_assert_with_mut_call\n\n        x > 10\n    });\n\n    // closures\n    debug_assert!((|| {\n        let mut x = 42;\n        bool_mut(&mut x);\n        //~^ debug_assert_with_mut_call\n\n        x > 10\n    })());\n}\n\nasync fn debug_await() {\n    debug_assert!(async {\n        true\n    }.await);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/debug_assert_with_mut_call.stderr",
    "content": "error: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:42:19\n   |\nLL |     debug_assert!(bool_mut(&mut 3));\n   |                   ^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::debug-assert-with-mut-call` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::debug_assert_with_mut_call)]`\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:46:20\n   |\nLL |     debug_assert!(!bool_mut(&mut 3));\n   |                    ^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_eq!`\n  --> tests/ui/debug_assert_with_mut_call.rs:50:25\n   |\nLL |     debug_assert_eq!(0, u32_mut(&mut 3));\n   |                         ^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_eq!`\n  --> tests/ui/debug_assert_with_mut_call.rs:53:22\n   |\nLL |     debug_assert_eq!(u32_mut(&mut 3), 0);\n   |                      ^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_ne!`\n  --> tests/ui/debug_assert_with_mut_call.rs:57:25\n   |\nLL |     debug_assert_ne!(1, u32_mut(&mut 3));\n   |                         ^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_ne!`\n  --> tests/ui/debug_assert_with_mut_call.rs:60:22\n   |\nLL |     debug_assert_ne!(u32_mut(&mut 3), 1);\n   |                      ^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:77:19\n   |\nLL |     debug_assert!(S.bool_self_mut());\n   |                   ^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:80:20\n   |\nLL |     debug_assert!(!S.bool_self_mut());\n   |                    ^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:83:19\n   |\nLL |     debug_assert!(S.bool_self_ref_arg_mut(&mut 3));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:86:19\n   |\nLL |     debug_assert!(S.bool_self_mut_arg_ref(&3));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:89:19\n   |\nLL |     debug_assert!(S.bool_self_mut_arg_mut(&mut 3));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_eq!`\n  --> tests/ui/debug_assert_with_mut_call.rs:93:22\n   |\nLL |     debug_assert_eq!(S.u32_self_mut(), 0);\n   |                      ^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_eq!`\n  --> tests/ui/debug_assert_with_mut_call.rs:96:22\n   |\nLL |     debug_assert_eq!(S.u32_self_mut_arg_ref(&3), 0);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_eq!`\n  --> tests/ui/debug_assert_with_mut_call.rs:99:22\n   |\nLL |     debug_assert_eq!(S.u32_self_ref_arg_mut(&mut 3), 0);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_eq!`\n  --> tests/ui/debug_assert_with_mut_call.rs:102:22\n   |\nLL |     debug_assert_eq!(S.u32_self_mut_arg_mut(&mut 3), 0);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_ne!`\n  --> tests/ui/debug_assert_with_mut_call.rs:106:22\n   |\nLL |     debug_assert_ne!(S.u32_self_mut(), 1);\n   |                      ^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_ne!`\n  --> tests/ui/debug_assert_with_mut_call.rs:109:22\n   |\nLL |     debug_assert_ne!(S.u32_self_mut_arg_ref(&3), 1);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_ne!`\n  --> tests/ui/debug_assert_with_mut_call.rs:112:22\n   |\nLL |     debug_assert_ne!(S.u32_self_ref_arg_mut(&mut 3), 1);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_ne!`\n  --> tests/ui/debug_assert_with_mut_call.rs:115:22\n   |\nLL |     debug_assert_ne!(S.u32_self_mut_arg_mut(&mut 3), 1);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_eq!`\n  --> tests/ui/debug_assert_with_mut_call.rs:125:22\n   |\nLL |     debug_assert_eq!(v.pop(), Some(1));\n   |                      ^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_ne!`\n  --> tests/ui/debug_assert_with_mut_call.rs:128:31\n   |\nLL |     debug_assert_ne!(Some(3), v.pop());\n   |                               ^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:133:19\n   |\nLL |     debug_assert!(bool_mut(a));\n   |                   ^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:138:31\n   |\nLL |     debug_assert!(!(bool_ref(&u32_mut(&mut 3))));\n   |                               ^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert_eq!`\n  --> tests/ui/debug_assert_with_mut_call.rs:143:22\n   |\nLL |     debug_assert_eq!(v.pop().unwrap(), 3);\n   |                      ^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:149:19\n   |\nLL |     debug_assert!(bool_mut(&mut 3), \"w/o format\");\n   |                   ^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:153:19\n   |\nLL |     debug_assert!(bool_mut(&mut 3), \"{} format\", \"w/\");\n   |                   ^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:160:9\n   |\nLL |         bool_mut(&mut x);\n   |         ^^^^^^^^^^^^^^^^\n\nerror: do not call a function with mutable arguments inside of `debug_assert!`\n  --> tests/ui/debug_assert_with_mut_call.rs:169:9\n   |\nLL |         bool_mut(&mut x);\n   |         ^^^^^^^^^^^^^^^^\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui/decimal_bitwise_operands.rs",
    "content": "#![allow(\n    clippy::erasing_op,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::unnecessary_cast,\n    clippy::op_ref\n)]\n#![warn(clippy::decimal_bitwise_operands)]\n\nmacro_rules! bitwise_op {\n    ($x:expr, $y:expr) => {\n        $x & $y;\n    };\n}\n\npub const SOME_CONST: i32 = 12345;\n\nfn main() {\n    let mut x = 0;\n    // BAD: Bitwise operation, decimal literal, one literal\n    x & 9_8765_4321; //~ decimal_bitwise_operands\n    x & 100_i32; //~ decimal_bitwise_operands\n    x | (/* comment */99); //~ decimal_bitwise_operands\n    x ^ (99); //~ decimal_bitwise_operands\n    x &= 99; //~ decimal_bitwise_operands\n    x |= { 99 }; //~ decimal_bitwise_operands\n    x |= { { 99 } }; //~ decimal_bitwise_operands\n    x |= {\n        0b1000;\n        99 //~ decimal_bitwise_operands\n    };\n    x ^= (99); //~ decimal_bitwise_operands\n\n    // BAD: Bitwise operation, decimal literal, two literals\n    0b1010 & 99; //~ decimal_bitwise_operands\n    0b1010 | (99); //~ decimal_bitwise_operands\n    0b1010 ^ (/* comment */99); //~ decimal_bitwise_operands\n    99 & 0b1010; //~ decimal_bitwise_operands\n    (99) | 0b1010; //~ decimal_bitwise_operands\n    (/* comment */99) ^ 0b1010; //~ decimal_bitwise_operands\n    0xD | { 99 }; //~ decimal_bitwise_operands\n    88 & 99;\n    //~^ decimal_bitwise_operands\n    //~| decimal_bitwise_operands\n    37 & 38 & 39;\n    //~^ decimal_bitwise_operands\n    //~| decimal_bitwise_operands\n    //~| decimal_bitwise_operands\n\n    // GOOD: Bitwise operation, binary/hex/octal literal, one literal\n    x & 0b1010;\n    x | 0b1010;\n    x ^ 0b1010;\n    x &= 0b1010;\n    x |= 0b1010;\n    x ^= 0b1010;\n    x & 0xD;\n    x & 0o77;\n    x | 0o123;\n    x ^ 0o377;\n    x &= 0o777;\n    x |= 0o7;\n    x ^= 0o70;\n\n    // GOOD: Bitwise operation, binary/hex/octal literal, two literals\n    0b1010 & 0b1101;\n    0xD ^ 0xF;\n    0o377 ^ 0o77;\n    0b1101 ^ 0xFF;\n\n    // GOOD: Numeric operation, any literal\n    x += 99;\n    x -= 0b1010;\n    x *= 0xD;\n    99 + 99;\n    0b1010 - 0b1101;\n    0xD * 0xD;\n\n    // BAD: Unary, cast and reference, decimal literal\n    x & !100; //~ decimal_bitwise_operands\n    x & -100; //~ decimal_bitwise_operands\n    x & (100 as i32); //~ decimal_bitwise_operands\n    x & &100; //~ decimal_bitwise_operands\n\n    // GOOD: Unary, cast and reference, non-decimal literal\n    x & !0b1101;\n    x & -0xD;\n    x & (0o333 as i32);\n    x & &0b1010;\n\n    // GOOD: Bitwise operation, variables only\n    let y = 0;\n    x & y;\n    x &= y;\n    x + y;\n    x += y;\n\n    // GOOD: Macro expansion (should be ignored)\n    bitwise_op!(x, 123);\n    bitwise_op!(0b1010, 123);\n\n    // GOOD: Using const (should be ignored)\n    x & SOME_CONST;\n    x |= SOME_CONST;\n\n    // GOOD: Parenthesized binary/hex literal (should not trigger lint)\n    x & (0b1111);\n    x |= (0b1010);\n    x ^ (/* comment */0b1100);\n    (0xFF) & x;\n\n    // GOOD: Power of two and power of two minus one\n    x & 16; // 2^4\n    x | (31); // 2^5 - 1\n    x ^ 0x40; // 2^6 (hex)\n    x ^= 7; // 2^3 - 1\n\n    // GOOD: Bitwise operation, single digit decimal literal\n    5 & 9;\n    x ^ 6;\n    x ^= 7;\n\n    // GOOD: More complex expressions\n    (x + 1) & 0xFF;\n    (x * 2) | (y & 0xF);\n    (x ^ y) & 0b11110000;\n    x | (1 << 9);\n\n    // GOOD: Special cases\n    x & 0; // All bits off\n    x | !0; // All bits on\n    x ^ 1; // Toggle LSB\n}\n"
  },
  {
    "path": "tests/ui/decimal_bitwise_operands.stderr",
    "content": "error: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:21:9\n   |\nLL |     x & 9_8765_4321;\n   |         ^^^^^^^^^^^\n   |\n   = help: use binary (0b11_1010_1101_1110_0110_1000_1011_0001), hex (0x3ade_68b1), or octal (0o7_267_464_261) notation for better readability\n   = note: `-D clippy::decimal-bitwise-operands` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::decimal_bitwise_operands)]`\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:22:9\n   |\nLL |     x & 100_i32;\n   |         ^^^^^^^\n   |\n   = help: use binary (0b110_0100_i32), hex (0x0064_i32), or octal (0o144_i32) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:23:23\n   |\nLL |     x | (/* comment */99);\n   |                       ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:24:10\n   |\nLL |     x ^ (99);\n   |          ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:25:10\n   |\nLL |     x &= 99;\n   |          ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:26:12\n   |\nLL |     x |= { 99 };\n   |            ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:27:14\n   |\nLL |     x |= { { 99 } };\n   |              ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:30:9\n   |\nLL |         99\n   |         ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:32:11\n   |\nLL |     x ^= (99);\n   |           ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:35:14\n   |\nLL |     0b1010 & 99;\n   |              ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:36:15\n   |\nLL |     0b1010 | (99);\n   |               ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:37:28\n   |\nLL |     0b1010 ^ (/* comment */99);\n   |                            ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:38:5\n   |\nLL |     99 & 0b1010;\n   |     ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:39:6\n   |\nLL |     (99) | 0b1010;\n   |      ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:40:19\n   |\nLL |     (/* comment */99) ^ 0b1010;\n   |                   ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:41:13\n   |\nLL |     0xD | { 99 };\n   |             ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:42:5\n   |\nLL |     88 & 99;\n   |     ^^\n   |\n   = help: use binary (0b101_1000), hex (0x0058), or octal (0o130) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:42:10\n   |\nLL |     88 & 99;\n   |          ^^\n   |\n   = help: use binary (0b110_0011), hex (0x0063), or octal (0o143) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:45:15\n   |\nLL |     37 & 38 & 39;\n   |               ^^\n   |\n   = help: use binary (0b10_0111), hex (0x0027), or octal (0o47) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:45:5\n   |\nLL |     37 & 38 & 39;\n   |     ^^\n   |\n   = help: use binary (0b10_0101), hex (0x0025), or octal (0o45) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:45:10\n   |\nLL |     37 & 38 & 39;\n   |          ^^\n   |\n   = help: use binary (0b10_0110), hex (0x0026), or octal (0o46) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:80:10\n   |\nLL |     x & !100;\n   |          ^^^\n   |\n   = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:81:10\n   |\nLL |     x & -100;\n   |          ^^^\n   |\n   = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:82:10\n   |\nLL |     x & (100 as i32);\n   |          ^^^\n   |\n   = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability\n\nerror: using decimal literal for bitwise operation\n  --> tests/ui/decimal_bitwise_operands.rs:83:10\n   |\nLL |     x & &100;\n   |          ^^^\n   |\n   = help: use binary (0b110_0100), hex (0x0064), or octal (0o144) notation for better readability\n\nerror: aborting due to 25 previous errors\n\n"
  },
  {
    "path": "tests/ui/decimal_literal_representation.fixed",
    "content": "#[warn(clippy::decimal_literal_representation)]\n#[allow(unused_variables)]\n#[rustfmt::skip]\nfn main() {\n    let good = (       // Hex:\n        127,           // 0x7F\n        256,           // 0x100\n        511,           // 0x1FF\n        2048,          // 0x800\n        4090,          // 0xFFA\n        16_371,        // 0x3FF3\n        61_683,        // 0xF0F3\n        2_131_750_925, // 0x7F0F_F00D\n    );\n    let bad = (        // Hex:\n        0x8005,        // 0x8005\n        //~^ decimal_literal_representation\n        0xFF00,        // 0xFF00\n        //~^ decimal_literal_representation\n        0x7F0F_F00F, // 0x7F0F_F00F\n        //~^ decimal_literal_representation\n        0x7FFF_FFFF, // 0x7FFF_FFFF\n        //~^ decimal_literal_representation\n        #[allow(overflowing_literals)]\n        0xF0F0_F0F0, // 0xF0F0_F0F0\n        //~^ decimal_literal_representation\n        0x8005_usize,   // 0x8005_usize\n        //~^ decimal_literal_representation\n        0x7F0F_F00F_isize, // 0x7F0F_F00F_isize\n        //~^ decimal_literal_representation\n    );\n}\n"
  },
  {
    "path": "tests/ui/decimal_literal_representation.rs",
    "content": "#[warn(clippy::decimal_literal_representation)]\n#[allow(unused_variables)]\n#[rustfmt::skip]\nfn main() {\n    let good = (       // Hex:\n        127,           // 0x7F\n        256,           // 0x100\n        511,           // 0x1FF\n        2048,          // 0x800\n        4090,          // 0xFFA\n        16_371,        // 0x3FF3\n        61_683,        // 0xF0F3\n        2_131_750_925, // 0x7F0F_F00D\n    );\n    let bad = (        // Hex:\n        32_773,        // 0x8005\n        //~^ decimal_literal_representation\n        65_280,        // 0xFF00\n        //~^ decimal_literal_representation\n        2_131_750_927, // 0x7F0F_F00F\n        //~^ decimal_literal_representation\n        2_147_483_647, // 0x7FFF_FFFF\n        //~^ decimal_literal_representation\n        #[allow(overflowing_literals)]\n        4_042_322_160, // 0xF0F0_F0F0\n        //~^ decimal_literal_representation\n        32_773usize,   // 0x8005_usize\n        //~^ decimal_literal_representation\n        2_131_750_927isize, // 0x7F0F_F00F_isize\n        //~^ decimal_literal_representation\n    );\n}\n"
  },
  {
    "path": "tests/ui/decimal_literal_representation.stderr",
    "content": "error: integer literal has a better hexadecimal representation\n  --> tests/ui/decimal_literal_representation.rs:16:9\n   |\nLL |         32_773,        // 0x8005\n   |         ^^^^^^ help: consider: `0x8005`\n   |\n   = note: `-D clippy::decimal-literal-representation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::decimal_literal_representation)]`\n\nerror: integer literal has a better hexadecimal representation\n  --> tests/ui/decimal_literal_representation.rs:18:9\n   |\nLL |         65_280,        // 0xFF00\n   |         ^^^^^^ help: consider: `0xFF00`\n\nerror: integer literal has a better hexadecimal representation\n  --> tests/ui/decimal_literal_representation.rs:20:9\n   |\nLL |         2_131_750_927, // 0x7F0F_F00F\n   |         ^^^^^^^^^^^^^ help: consider: `0x7F0F_F00F`\n\nerror: integer literal has a better hexadecimal representation\n  --> tests/ui/decimal_literal_representation.rs:22:9\n   |\nLL |         2_147_483_647, // 0x7FFF_FFFF\n   |         ^^^^^^^^^^^^^ help: consider: `0x7FFF_FFFF`\n\nerror: integer literal has a better hexadecimal representation\n  --> tests/ui/decimal_literal_representation.rs:25:9\n   |\nLL |         4_042_322_160, // 0xF0F0_F0F0\n   |         ^^^^^^^^^^^^^ help: consider: `0xF0F0_F0F0`\n\nerror: integer literal has a better hexadecimal representation\n  --> tests/ui/decimal_literal_representation.rs:27:9\n   |\nLL |         32_773usize,   // 0x8005_usize\n   |         ^^^^^^^^^^^ help: consider: `0x8005_usize`\n\nerror: integer literal has a better hexadecimal representation\n  --> tests/ui/decimal_literal_representation.rs:29:9\n   |\nLL |         2_131_750_927isize, // 0x7F0F_F00F_isize\n   |         ^^^^^^^^^^^^^^^^^^ help: consider: `0x7F0F_F00F_isize`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/declare_interior_mutable_const.rs",
    "content": "#![deny(clippy::declare_interior_mutable_const)]\n#![allow(clippy::missing_const_for_thread_local)]\n\nuse core::cell::{Cell, RefCell, UnsafeCell};\nuse core::mem::{ManuallyDrop, MaybeUninit};\nuse core::ptr;\nuse core::sync::atomic::AtomicUsize;\n\nfn main() {}\n\nconst _: Cell<u32> = Cell::new(0);\nconst UNSAFE_CELL: UnsafeCell<u32> = UnsafeCell::new(0); //~ declare_interior_mutable_const\nconst REF_CELL: RefCell<u32> = RefCell::new(0); //~ declare_interior_mutable_const\nconst CELL: Cell<u32> = Cell::new(0); //~ declare_interior_mutable_const\n\n// Constants can't contain pointers or references to type with interior mutability.\nconst fn make_ptr() -> *const Cell<u32> {\n    ptr::null()\n}\nconst PTR: *const Cell<u32> = make_ptr();\n\nconst fn casted_to_cell_ptr() -> *const Cell<u32> {\n    const VALUE: u32 = 0;\n    &VALUE as *const _ as *const Cell<u32>\n}\nconst TRANSMUTED_PTR: *const Cell<u32> = casted_to_cell_ptr();\n\nconst CELL_TUPLE: (bool, Cell<u32>) = (true, Cell::new(0)); //~ declare_interior_mutable_const\nconst CELL_ARRAY: [Cell<u32>; 2] = [Cell::new(0), Cell::new(0)]; //~ declare_interior_mutable_const\n\nconst UNINIT_CELL: MaybeUninit<Cell<&'static ()>> = MaybeUninit::uninit();\n\nstruct CellStruct {\n    x: u32,\n    cell: Cell<u32>,\n}\n//~v declare_interior_mutable_const\nconst CELL_STRUCT: CellStruct = CellStruct {\n    x: 0,\n    cell: Cell::new(0),\n};\n\nenum CellEnum {\n    Cell(Cell<u32>),\n}\nconst CELL_ENUM: CellEnum = CellEnum::Cell(Cell::new(0)); //~ declare_interior_mutable_const\n\nconst NONE_CELL: Option<Cell<u32>> = None;\nconst SOME_CELL: Option<Cell<u32>> = Some(Cell::new(0)); //~ declare_interior_mutable_const\n\nstruct NestedCell([(Option<Cell<u32>>,); 1]);\nconst NONE_NESTED_CELL: NestedCell = NestedCell([(None,)]);\nconst SOME_NESTED_CELL: NestedCell = NestedCell([(Some(Cell::new(0)),)]); //~ declare_interior_mutable_const\n\nunion UnionCell {\n    cell: ManuallyDrop<Cell<u32>>,\n    x: u32,\n}\n//~v declare_interior_mutable_const\nconst UNION_CELL: UnionCell = UnionCell {\n    cell: ManuallyDrop::new(Cell::new(0)),\n};\n// Access to either union field is valid so we have to be conservative here.\nconst UNION_U32: UnionCell = UnionCell { x: 0 }; //~ declare_interior_mutable_const\n\nstruct Assoc;\nimpl Assoc {\n    const SELF: Self = Self;\n    const CELL: Cell<u32> = Cell::new(0); //~ declare_interior_mutable_const\n}\n\nstruct AssocCell(Cell<u32>);\nimpl AssocCell {\n    const SELF: Self = Self(Cell::new(0)); //~ declare_interior_mutable_const\n    const NONE_SELF: Option<Self> = None;\n    const SOME_SELF: Option<Self> = Some(Self(Cell::new(0))); //~ declare_interior_mutable_const\n}\n\ntrait ConstDefault {\n    // May or may not be `Freeze`\n    const DEFAULT: Self;\n}\nimpl ConstDefault for u32 {\n    const DEFAULT: Self = 0;\n}\nimpl<T: ConstDefault> ConstDefault for Cell<T> {\n    // Interior mutability is forced by the trait.\n    const DEFAULT: Self = Cell::new(T::DEFAULT);\n}\nimpl<T: ConstDefault> ConstDefault for Option<Cell<T>> {\n    // Could have been `None`\n    const DEFAULT: Self = Some(Cell::new(T::DEFAULT)); //~ declare_interior_mutable_const\n}\n\nenum GenericEnumCell<T> {\n    Cell(Cell<T>),\n    Other(T),\n}\nimpl<T: ConstDefault> ConstDefault for GenericEnumCell<T> {\n    const DEFAULT: Self = Self::Cell(Cell::new(T::DEFAULT)); //~ declare_interior_mutable_const\n}\nimpl<T: ConstDefault> GenericEnumCell<T> {\n    const CELL: Self = Self::DEFAULT; //~ declare_interior_mutable_const\n    const CELL_BY_DEFAULT: Self = Self::Cell(Cell::DEFAULT); //~ declare_interior_mutable_const\n    const OTHER: Self = Self::Other(T::DEFAULT);\n    const FROM_OTHER: Self = Self::OTHER;\n}\n\nenum GenericNestedEnumCell<T> {\n    GenericEnumCell(GenericEnumCell<T>),\n    EnumCell(GenericEnumCell<u32>),\n    Other(T),\n}\nimpl<T: ConstDefault> GenericNestedEnumCell<T> {\n    const GENERIC_OTHER: Self = Self::GenericEnumCell(GenericEnumCell::<T>::FROM_OTHER);\n    const GENERIC_CELL: Self = Self::GenericEnumCell(GenericEnumCell::<T>::CELL); //~ declare_interior_mutable_const\n    const ENUM_OTHER: Self = Self::EnumCell(GenericEnumCell::<u32>::FROM_OTHER);\n    const ENUM_CELL: Self = Self::EnumCell(GenericEnumCell::<u32>::CELL); //~ declare_interior_mutable_const\n}\n\ntrait CellTrait: ConstDefault + Sized {\n    // Must be non-`Freeze` due to the type\n    const CELL: Cell<Self>; //~ declare_interior_mutable_const\n    // May be non-`Freeze`, but may not be\n    const OPTION_CELL: Option<Cell<Self>>;\n    // May get redefined by the impl, but the default is non-`Freeze`.\n    const SOME_CELL: Option<Cell<Self>> = Some(Cell::new(Self::DEFAULT)); //~ declare_interior_mutable_const\n    // May get redefined by the impl, but the default is `Freeze`.\n    const NONE_CELL: Option<Cell<Self>> = None;\n}\n\ntrait CellWithAssoc {\n    type T;\n    const DEFAULT: Self::T;\n    // Must be non-`Freeze` due to the type\n    const CELL: Cell<Self::T>; //~ declare_interior_mutable_const\n    // May be non-`Freeze`, but may not be\n    const OPTION_CELL: Option<Cell<Self::T>>;\n    // May get redefined by the impl, but the default is non-`Freeze`.\n    const SOME_CELL: Option<Cell<Self::T>> = Some(Cell::new(Self::DEFAULT)); //~ declare_interior_mutable_const\n    // May get redefined by the impl, but the default is `Freeze`.\n    const NONE_CELL: Option<Cell<Self::T>> = None;\n}\n\nimpl CellWithAssoc for () {\n    type T = u32;\n    const DEFAULT: Self::T = 0;\n    const CELL: Cell<Self::T> = Cell::new(0);\n    const OPTION_CELL: Option<Cell<Self::T>> = None;\n}\n\ntrait WithAssoc {\n    type T;\n    const VALUE: Self::T;\n}\n\nimpl WithAssoc for u32 {\n    type T = Cell<u32>;\n    // The cell comes from the impl block, not the trait.\n    const VALUE: Self::T = Cell::new(0); //~ declare_interior_mutable_const\n}\n\ntrait WithLayeredAssoc {\n    type T: WithAssoc;\n    const VALUE: <Self::T as WithAssoc>::T;\n}\n\nimpl WithLayeredAssoc for u32 {\n    type T = u32;\n    // The cell comes from the impl block, not the trait.\n    const VALUE: <Self::T as WithAssoc>::T = Cell::new(0); //~ declare_interior_mutable_const\n}\n\ntrait WithGenericAssoc {\n    type T<U>;\n    const VALUE: Self::T<u32>;\n}\n\nimpl WithGenericAssoc for u32 {\n    type T<U> = Cell<U>;\n    const VALUE: Self::T<u32> = Cell::new(0); //~ declare_interior_mutable_const\n}\n\ntrait WithGenericAssocCell {\n    type T<U>;\n    const VALUE: Self::T<Cell<u32>>;\n}\n\nimpl WithGenericAssocCell for u32 {\n    type T<U> = Option<U>;\n    const VALUE: Self::T<Cell<u32>> = None;\n}\n\nimpl WithGenericAssocCell for i32 {\n    type T<U> = Option<U>;\n    const VALUE: Self::T<Cell<u32>> = Some(Cell::new(0)); //~ declare_interior_mutable_const\n}\n\nthread_local!(static THREAD_LOCAL_CELL: Cell<u32> = const { Cell::new(0) });\nthread_local!(static THREAD_LOCAL_CELL2: Cell<u32> = Cell::new(0));\n"
  },
  {
    "path": "tests/ui/declare_interior_mutable_const.stderr",
    "content": "error: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:12:7\n   |\nLL | const UNSAFE_CELL: UnsafeCell<u32> = UnsafeCell::new(0);\n   |       ^^^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\nnote: the lint level is defined here\n  --> tests/ui/declare_interior_mutable_const.rs:1:9\n   |\nLL | #![deny(clippy::declare_interior_mutable_const)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:13:7\n   |\nLL | const REF_CELL: RefCell<u32> = RefCell::new(0);\n   |       ^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:14:7\n   |\nLL | const CELL: Cell<u32> = Cell::new(0);\n   |       ^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:28:7\n   |\nLL | const CELL_TUPLE: (bool, Cell<u32>) = (true, Cell::new(0));\n   |       ^^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:29:7\n   |\nLL | const CELL_ARRAY: [Cell<u32>; 2] = [Cell::new(0), Cell::new(0)];\n   |       ^^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:38:7\n   |\nLL | const CELL_STRUCT: CellStruct = CellStruct {\n   |       ^^^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:46:7\n   |\nLL | const CELL_ENUM: CellEnum = CellEnum::Cell(Cell::new(0));\n   |       ^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:49:7\n   |\nLL | const SOME_CELL: Option<Cell<u32>> = Some(Cell::new(0));\n   |       ^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:53:7\n   |\nLL | const SOME_NESTED_CELL: NestedCell = NestedCell([(Some(Cell::new(0)),)]);\n   |       ^^^^^^^^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:60:7\n   |\nLL | const UNION_CELL: UnionCell = UnionCell {\n   |       ^^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:64:7\n   |\nLL | const UNION_U32: UnionCell = UnionCell { x: 0 };\n   |       ^^^^^^^^^\n   |\n   = help: did you mean to make this a `thread_local!` item\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:69:11\n   |\nLL |     const CELL: Cell<u32> = Cell::new(0);\n   |           ^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:74:11\n   |\nLL |     const SELF: Self = Self(Cell::new(0));\n   |           ^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:76:11\n   |\nLL |     const SOME_SELF: Option<Self> = Some(Self(Cell::new(0)));\n   |           ^^^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:92:11\n   |\nLL |     const DEFAULT: Self = Some(Cell::new(T::DEFAULT));\n   |           ^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:100:11\n   |\nLL |     const DEFAULT: Self = Self::Cell(Cell::new(T::DEFAULT));\n   |           ^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:103:11\n   |\nLL |     const CELL: Self = Self::DEFAULT;\n   |           ^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:104:11\n   |\nLL |     const CELL_BY_DEFAULT: Self = Self::Cell(Cell::DEFAULT);\n   |           ^^^^^^^^^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:116:11\n   |\nLL |     const GENERIC_CELL: Self = Self::GenericEnumCell(GenericEnumCell::<T>::CELL);\n   |           ^^^^^^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:118:11\n   |\nLL |     const ENUM_CELL: Self = Self::EnumCell(GenericEnumCell::<u32>::CELL);\n   |           ^^^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:123:11\n   |\nLL |     const CELL: Cell<Self>;\n   |           ^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:127:11\n   |\nLL |     const SOME_CELL: Option<Cell<Self>> = Some(Cell::new(Self::DEFAULT));\n   |           ^^^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:136:11\n   |\nLL |     const CELL: Cell<Self::T>;\n   |           ^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:140:11\n   |\nLL |     const SOME_CELL: Option<Cell<Self::T>> = Some(Cell::new(Self::DEFAULT));\n   |           ^^^^^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:160:11\n   |\nLL |     const VALUE: Self::T = Cell::new(0);\n   |           ^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:171:11\n   |\nLL |     const VALUE: <Self::T as WithAssoc>::T = Cell::new(0);\n   |           ^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:181:11\n   |\nLL |     const VALUE: Self::T<u32> = Cell::new(0);\n   |           ^^^^^\n\nerror: named constant with interior mutability\n  --> tests/ui/declare_interior_mutable_const.rs:196:11\n   |\nLL |     const VALUE: Self::T<Cell<u32>> = Some(Cell::new(0));\n   |           ^^^^^\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui/def_id_nocore.rs",
    "content": "#![feature(no_core, lang_items)]\n#![no_core]\n#![allow(clippy::missing_safety_doc)]\n\n#[link(name = \"c\")]\nunsafe extern \"C\" {}\n\n#[lang = \"pointee_sized\"]\npub trait PointeeSized {}\n\n#[lang = \"meta_sized\"]\npub trait MetaSized: PointeeSized {}\n\n#[lang = \"sized\"]\npub trait Sized: MetaSized {}\n#[lang = \"copy\"]\npub trait Copy {}\n#[lang = \"freeze\"]\npub unsafe trait Freeze {}\n\n#[lang = \"start\"]\nfn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {\n    0\n}\n\nfn main() {}\n\nstruct A;\n\nimpl A {\n    pub fn as_ref(self) -> &'static str {\n        //~^ ERROR: methods called `as_*` usually take `self` by reference or `self` by mutabl\n        \"A\"\n    }\n}\n"
  },
  {
    "path": "tests/ui/def_id_nocore.stderr",
    "content": "error: methods called `as_*` usually take `self` by reference or `self` by mutable reference\n  --> tests/ui/def_id_nocore.rs:31:19\n   |\nLL |     pub fn as_ref(self) -> &'static str {\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/default_constructed_unit_structs.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::default_constructed_unit_structs)]\nuse std::marker::PhantomData;\n\n#[derive(Default)]\nstruct UnitStruct;\n\nimpl UnitStruct {\n    fn new() -> Self {\n        //should lint\n        Self\n        //~^ default_constructed_unit_structs\n    }\n}\n\n#[derive(Default)]\nstruct TupleStruct(usize);\n\nimpl TupleStruct {\n    fn new() -> Self {\n        // should not lint\n        Self(Default::default())\n    }\n}\n\n// no lint for derived impl\n#[derive(Default)]\nstruct NormalStruct {\n    inner: PhantomData<usize>,\n}\n\nstruct NonDefaultStruct;\n\nimpl NonDefaultStruct {\n    fn default() -> Self {\n        Self\n    }\n}\n\n#[derive(Default)]\nenum SomeEnum {\n    #[default]\n    Unit,\n    Tuple(UnitStruct),\n    Struct {\n        inner: usize,\n    },\n}\n\nimpl NormalStruct {\n    fn new() -> Self {\n        // should lint\n        Self {\n            inner: PhantomData,\n            //~^ default_constructed_unit_structs\n        }\n    }\n\n    fn new2() -> Self {\n        // should not lint\n        Self {\n            inner: Default::default(),\n        }\n    }\n}\n\n#[derive(Default)]\nstruct GenericStruct<T> {\n    t: T,\n}\n\nimpl<T: Default> GenericStruct<T> {\n    fn new() -> Self {\n        // should not lint\n        Self { t: T::default() }\n    }\n\n    fn new2() -> Self {\n        // should not lint\n        Self { t: Default::default() }\n    }\n}\n\nstruct FakeDefault;\nimpl FakeDefault {\n    fn default() -> Self {\n        Self\n    }\n}\n\nimpl Default for FakeDefault {\n    fn default() -> Self {\n        Self\n    }\n}\n\n#[derive(Default)]\nstruct EmptyStruct {}\n\n#[derive(Default)]\n#[non_exhaustive]\nstruct NonExhaustiveStruct;\n\nmod issue_10755 {\n    struct Sqlite {}\n\n    trait HasArguments<'q> {\n        type Arguments;\n    }\n\n    impl<'q> HasArguments<'q> for Sqlite {\n        type Arguments = std::marker::PhantomData<&'q ()>;\n    }\n\n    type SqliteArguments<'q> = <Sqlite as HasArguments<'q>>::Arguments;\n\n    fn foo() {\n        // should not lint\n        // type alias cannot be used as a constructor\n        let _ = <Sqlite as HasArguments>::Arguments::default();\n\n        let _ = SqliteArguments::default();\n    }\n}\n\nfn main() {\n    // should lint\n    let _ = PhantomData::<usize>;\n    //~^ default_constructed_unit_structs\n    let _: PhantomData<i32> = PhantomData;\n    //~^ default_constructed_unit_structs\n    let _: PhantomData<i32> = std::marker::PhantomData;\n    //~^ default_constructed_unit_structs\n    let _ = UnitStruct;\n    //~^ default_constructed_unit_structs\n\n    // should not lint\n    let _ = TupleStruct::default();\n    let _ = NormalStruct::default();\n    let _ = NonExhaustiveStruct::default();\n    let _ = SomeEnum::default();\n    let _ = NonDefaultStruct::default();\n    let _ = EmptyStruct::default();\n    let _ = FakeDefault::default();\n    let _ = <FakeDefault as Default>::default();\n\n    macro_rules! in_macro {\n        ($i:ident) => {{\n            let _ = UnitStruct::default();\n            let _ = $i::default();\n        }};\n    }\n\n    in_macro!(UnitStruct);\n\n    macro_rules! struct_from_macro {\n        () => {\n            UnitStruct\n        };\n    }\n\n    let _ = <struct_from_macro!()>::default();\n}\n\nfn issue12654() {\n    #[derive(Default)]\n    struct G;\n\n    fn f(_g: G) {}\n\n    f(<_>::default());\n    f(G);\n    //~^ default_constructed_unit_structs\n\n    // No lint because `as Default` hides the singleton\n    f(<G as Default>::default());\n}\n"
  },
  {
    "path": "tests/ui/default_constructed_unit_structs.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::default_constructed_unit_structs)]\nuse std::marker::PhantomData;\n\n#[derive(Default)]\nstruct UnitStruct;\n\nimpl UnitStruct {\n    fn new() -> Self {\n        //should lint\n        Self::default()\n        //~^ default_constructed_unit_structs\n    }\n}\n\n#[derive(Default)]\nstruct TupleStruct(usize);\n\nimpl TupleStruct {\n    fn new() -> Self {\n        // should not lint\n        Self(Default::default())\n    }\n}\n\n// no lint for derived impl\n#[derive(Default)]\nstruct NormalStruct {\n    inner: PhantomData<usize>,\n}\n\nstruct NonDefaultStruct;\n\nimpl NonDefaultStruct {\n    fn default() -> Self {\n        Self\n    }\n}\n\n#[derive(Default)]\nenum SomeEnum {\n    #[default]\n    Unit,\n    Tuple(UnitStruct),\n    Struct {\n        inner: usize,\n    },\n}\n\nimpl NormalStruct {\n    fn new() -> Self {\n        // should lint\n        Self {\n            inner: PhantomData::default(),\n            //~^ default_constructed_unit_structs\n        }\n    }\n\n    fn new2() -> Self {\n        // should not lint\n        Self {\n            inner: Default::default(),\n        }\n    }\n}\n\n#[derive(Default)]\nstruct GenericStruct<T> {\n    t: T,\n}\n\nimpl<T: Default> GenericStruct<T> {\n    fn new() -> Self {\n        // should not lint\n        Self { t: T::default() }\n    }\n\n    fn new2() -> Self {\n        // should not lint\n        Self { t: Default::default() }\n    }\n}\n\nstruct FakeDefault;\nimpl FakeDefault {\n    fn default() -> Self {\n        Self\n    }\n}\n\nimpl Default for FakeDefault {\n    fn default() -> Self {\n        Self\n    }\n}\n\n#[derive(Default)]\nstruct EmptyStruct {}\n\n#[derive(Default)]\n#[non_exhaustive]\nstruct NonExhaustiveStruct;\n\nmod issue_10755 {\n    struct Sqlite {}\n\n    trait HasArguments<'q> {\n        type Arguments;\n    }\n\n    impl<'q> HasArguments<'q> for Sqlite {\n        type Arguments = std::marker::PhantomData<&'q ()>;\n    }\n\n    type SqliteArguments<'q> = <Sqlite as HasArguments<'q>>::Arguments;\n\n    fn foo() {\n        // should not lint\n        // type alias cannot be used as a constructor\n        let _ = <Sqlite as HasArguments>::Arguments::default();\n\n        let _ = SqliteArguments::default();\n    }\n}\n\nfn main() {\n    // should lint\n    let _ = PhantomData::<usize>::default();\n    //~^ default_constructed_unit_structs\n    let _: PhantomData<i32> = PhantomData::default();\n    //~^ default_constructed_unit_structs\n    let _: PhantomData<i32> = std::marker::PhantomData::default();\n    //~^ default_constructed_unit_structs\n    let _ = UnitStruct::default();\n    //~^ default_constructed_unit_structs\n\n    // should not lint\n    let _ = TupleStruct::default();\n    let _ = NormalStruct::default();\n    let _ = NonExhaustiveStruct::default();\n    let _ = SomeEnum::default();\n    let _ = NonDefaultStruct::default();\n    let _ = EmptyStruct::default();\n    let _ = FakeDefault::default();\n    let _ = <FakeDefault as Default>::default();\n\n    macro_rules! in_macro {\n        ($i:ident) => {{\n            let _ = UnitStruct::default();\n            let _ = $i::default();\n        }};\n    }\n\n    in_macro!(UnitStruct);\n\n    macro_rules! struct_from_macro {\n        () => {\n            UnitStruct\n        };\n    }\n\n    let _ = <struct_from_macro!()>::default();\n}\n\nfn issue12654() {\n    #[derive(Default)]\n    struct G;\n\n    fn f(_g: G) {}\n\n    f(<_>::default());\n    f(<G>::default());\n    //~^ default_constructed_unit_structs\n\n    // No lint because `as Default` hides the singleton\n    f(<G as Default>::default());\n}\n"
  },
  {
    "path": "tests/ui/default_constructed_unit_structs.stderr",
    "content": "error: use of `default` to create a unit struct\n  --> tests/ui/default_constructed_unit_structs.rs:11:9\n   |\nLL |         Self::default()\n   |         ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::default-constructed-unit-structs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::default_constructed_unit_structs)]`\nhelp: remove this call to `default`\n   |\nLL -         Self::default()\nLL +         Self\n   |\n\nerror: use of `default` to create a unit struct\n  --> tests/ui/default_constructed_unit_structs.rs:54:20\n   |\nLL |             inner: PhantomData::default(),\n   |                    ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove this call to `default`\n   |\nLL -             inner: PhantomData::default(),\nLL +             inner: PhantomData,\n   |\n\nerror: use of `default` to create a unit struct\n  --> tests/ui/default_constructed_unit_structs.rs:128:13\n   |\nLL |     let _ = PhantomData::<usize>::default();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove this call to `default`\n   |\nLL -     let _ = PhantomData::<usize>::default();\nLL +     let _ = PhantomData::<usize>;\n   |\n\nerror: use of `default` to create a unit struct\n  --> tests/ui/default_constructed_unit_structs.rs:130:31\n   |\nLL |     let _: PhantomData<i32> = PhantomData::default();\n   |                               ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove this call to `default`\n   |\nLL -     let _: PhantomData<i32> = PhantomData::default();\nLL +     let _: PhantomData<i32> = PhantomData;\n   |\n\nerror: use of `default` to create a unit struct\n  --> tests/ui/default_constructed_unit_structs.rs:132:31\n   |\nLL |     let _: PhantomData<i32> = std::marker::PhantomData::default();\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove this call to `default`\n   |\nLL -     let _: PhantomData<i32> = std::marker::PhantomData::default();\nLL +     let _: PhantomData<i32> = std::marker::PhantomData;\n   |\n\nerror: use of `default` to create a unit struct\n  --> tests/ui/default_constructed_unit_structs.rs:134:13\n   |\nLL |     let _ = UnitStruct::default();\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove this call to `default`\n   |\nLL -     let _ = UnitStruct::default();\nLL +     let _ = UnitStruct;\n   |\n\nerror: use of `default` to create a unit struct\n  --> tests/ui/default_constructed_unit_structs.rs:172:7\n   |\nLL |     f(<G>::default());\n   |       ^^^^^^^^^^^^^^\n   |\nhelp: remove this call to `default`\n   |\nLL -     f(<G>::default());\nLL +     f(G);\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/default_instead_of_iter_empty.fixed",
    "content": "#![warn(clippy::default_instead_of_iter_empty)]\n#![allow(dead_code)]\nuse std::collections::HashMap;\n\n#[derive(Default)]\nstruct Iter {\n    iter: std::iter::Empty<usize>,\n}\n\nfn main() {\n    // Do lint.\n    let _ = std::iter::empty::<usize>();\n    //~^ default_instead_of_iter_empty\n    let _ = std::iter::empty::<HashMap<usize, usize>>();\n    //~^ default_instead_of_iter_empty\n    let _foo: std::iter::Empty<usize> = std::iter::empty();\n    //~^ default_instead_of_iter_empty\n\n    // Do not lint.\n    let _ = Vec::<usize>::default();\n    let _ = String::default();\n    let _ = Iter::default();\n}\n"
  },
  {
    "path": "tests/ui/default_instead_of_iter_empty.rs",
    "content": "#![warn(clippy::default_instead_of_iter_empty)]\n#![allow(dead_code)]\nuse std::collections::HashMap;\n\n#[derive(Default)]\nstruct Iter {\n    iter: std::iter::Empty<usize>,\n}\n\nfn main() {\n    // Do lint.\n    let _ = std::iter::Empty::<usize>::default();\n    //~^ default_instead_of_iter_empty\n    let _ = std::iter::Empty::<HashMap<usize, usize>>::default();\n    //~^ default_instead_of_iter_empty\n    let _foo: std::iter::Empty<usize> = std::iter::Empty::default();\n    //~^ default_instead_of_iter_empty\n\n    // Do not lint.\n    let _ = Vec::<usize>::default();\n    let _ = String::default();\n    let _ = Iter::default();\n}\n"
  },
  {
    "path": "tests/ui/default_instead_of_iter_empty.stderr",
    "content": "error: `std::iter::empty()` is the more idiomatic way\n  --> tests/ui/default_instead_of_iter_empty.rs:12:13\n   |\nLL |     let _ = std::iter::Empty::<usize>::default();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::empty::<usize>()`\n   |\n   = note: `-D clippy::default-instead-of-iter-empty` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::default_instead_of_iter_empty)]`\n\nerror: `std::iter::empty()` is the more idiomatic way\n  --> tests/ui/default_instead_of_iter_empty.rs:14:13\n   |\nLL |     let _ = std::iter::Empty::<HashMap<usize, usize>>::default();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::empty::<HashMap<usize, usize>>()`\n\nerror: `std::iter::empty()` is the more idiomatic way\n  --> tests/ui/default_instead_of_iter_empty.rs:16:41\n   |\nLL |     let _foo: std::iter::Empty<usize> = std::iter::Empty::default();\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/default_instead_of_iter_empty_no_std.fixed",
    "content": "#![warn(clippy::default_instead_of_iter_empty)]\n#![allow(dead_code)]\n#![feature(lang_items)]\n#![no_std]\n\nuse core::panic::PanicInfo;\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n\n#[panic_handler]\nfn panic(info: &PanicInfo) -> ! {\n    loop {}\n}\n\n#[derive(Default)]\nstruct Iter {\n    iter: core::iter::Empty<usize>,\n}\n\nfn main() {\n    // Do lint.\n    let _ = core::iter::empty::<usize>();\n    //~^ default_instead_of_iter_empty\n    let _foo: core::iter::Empty<usize> = core::iter::empty();\n    //~^ default_instead_of_iter_empty\n\n    // Do not lint.\n    let _ = Iter::default();\n}\n"
  },
  {
    "path": "tests/ui/default_instead_of_iter_empty_no_std.rs",
    "content": "#![warn(clippy::default_instead_of_iter_empty)]\n#![allow(dead_code)]\n#![feature(lang_items)]\n#![no_std]\n\nuse core::panic::PanicInfo;\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n\n#[panic_handler]\nfn panic(info: &PanicInfo) -> ! {\n    loop {}\n}\n\n#[derive(Default)]\nstruct Iter {\n    iter: core::iter::Empty<usize>,\n}\n\nfn main() {\n    // Do lint.\n    let _ = core::iter::Empty::<usize>::default();\n    //~^ default_instead_of_iter_empty\n    let _foo: core::iter::Empty<usize> = core::iter::Empty::default();\n    //~^ default_instead_of_iter_empty\n\n    // Do not lint.\n    let _ = Iter::default();\n}\n"
  },
  {
    "path": "tests/ui/default_instead_of_iter_empty_no_std.stderr",
    "content": "error: `core::iter::empty()` is the more idiomatic way\n  --> tests/ui/default_instead_of_iter_empty_no_std.rs:23:13\n   |\nLL |     let _ = core::iter::Empty::<usize>::default();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty::<usize>()`\n   |\n   = note: `-D clippy::default-instead-of-iter-empty` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::default_instead_of_iter_empty)]`\n\nerror: `core::iter::empty()` is the more idiomatic way\n  --> tests/ui/default_instead_of_iter_empty_no_std.rs:25:42\n   |\nLL |     let _foo: core::iter::Empty<usize> = core::iter::Empty::default();\n   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty()`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/default_numeric_fallback_f64.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::default_numeric_fallback)]\n#![allow(\n    unused,\n    clippy::never_loop,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::branches_sharing_code,\n    clippy::match_single_binding,\n    clippy::let_unit_value,\n    clippy::let_with_type_underscore\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nmod basic_expr {\n    fn test() {\n        // Should lint unsuffixed literals typed `f64`.\n        let x = 0.12_f64;\n        //~^ default_numeric_fallback\n        let x = [1.0_f64, 2.0_f64, 3.0_f64];\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        let x = if true { (1.0_f64, 2.0_f64) } else { (3.0_f64, 4.0_f64) };\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        let x = match 1.0_f64 {\n            //~^ default_numeric_fallback\n            _ => 1.0_f64,\n            //~^ default_numeric_fallback\n        };\n\n        // Should NOT lint suffixed literals.\n        let x = 0.12_f64;\n\n        // Should NOT lint literals in init expr if `Local` has a type annotation.\n        let x: f64 = 0.1;\n        let x: [f64; 3] = [1., 2., 3.];\n        let x: (f64, f64) = if true { (1., 2.) } else { (3., 4.) };\n        let x: _ = 1.;\n        const X: f32 = 1.;\n    }\n}\n\nmod nested_local {\n    fn test() {\n        let x: _ = {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1.0_f64;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1.\n        };\n\n        let x: _ = if true {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1.0_f64;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1.\n        } else {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1.0_f64;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            2.\n        };\n\n        const X: f32 = {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1.0_f64;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1.\n        };\n    }\n}\n\nmod function_def {\n    fn ret_f64() -> f64 {\n        1.\n    }\n\n    fn test() {\n        // Should lint this because return type is inferred to `f64` and NOT bound to a concrete\n        // type.\n        let f = || -> _ { 1.0_f64 };\n        //~^ default_numeric_fallback\n\n        // Even though the output type is specified,\n        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.\n        let f = || -> f64 { 1.0_f64 };\n        //~^ default_numeric_fallback\n    }\n}\n\nmod function_calls {\n    fn concrete_arg(f: f64) {}\n\n    fn generic_arg<T>(t: T) {}\n\n    fn test() {\n        // Should NOT lint this because the argument type is bound to a concrete type.\n        concrete_arg(1.);\n\n        // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.\n        generic_arg(1.0_f64);\n        //~^ default_numeric_fallback\n\n        // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.\n        let x: _ = generic_arg(1.0_f64);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod struct_ctor {\n    struct ConcreteStruct {\n        x: f64,\n    }\n\n    struct GenericStruct<T> {\n        x: T,\n    }\n\n    fn test() {\n        // Should NOT lint this because the field type is bound to a concrete type.\n        ConcreteStruct { x: 1. };\n\n        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.\n        GenericStruct { x: 1.0_f64 };\n        //~^ default_numeric_fallback\n\n        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.\n        let _ = GenericStruct { x: 1.0_f64 };\n        //~^ default_numeric_fallback\n    }\n}\n\nmod enum_ctor {\n    enum ConcreteEnum {\n        X(f64),\n    }\n\n    enum GenericEnum<T> {\n        X(T),\n    }\n\n    fn test() {\n        // Should NOT lint this because the field type is bound to a concrete type.\n        ConcreteEnum::X(1.);\n\n        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.\n        GenericEnum::X(1.0_f64);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod method_calls {\n    struct StructForMethodCallTest;\n\n    impl StructForMethodCallTest {\n        fn concrete_arg(&self, f: f64) {}\n\n        fn generic_arg<T>(&self, t: T) {}\n    }\n\n    fn test() {\n        let s = StructForMethodCallTest {};\n\n        // Should NOT lint this because the argument type is bound to a concrete type.\n        s.concrete_arg(1.);\n\n        // Should lint this because the argument type is bound to a concrete type.\n        s.generic_arg(1.0_f64);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod in_macro {\n    use super::*;\n\n    // Should lint in internal macro.\n    #[inline_macros]\n    fn internal() {\n        inline!(let x = 22.0_f64;);\n        //~^ default_numeric_fallback\n    }\n\n    // Should NOT lint in external macro.\n    fn external() {\n        external!(let x = 22.;);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/default_numeric_fallback_f64.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::default_numeric_fallback)]\n#![allow(\n    unused,\n    clippy::never_loop,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::branches_sharing_code,\n    clippy::match_single_binding,\n    clippy::let_unit_value,\n    clippy::let_with_type_underscore\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nmod basic_expr {\n    fn test() {\n        // Should lint unsuffixed literals typed `f64`.\n        let x = 0.12;\n        //~^ default_numeric_fallback\n        let x = [1., 2., 3.];\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        let x = if true { (1., 2.) } else { (3., 4.) };\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        let x = match 1. {\n            //~^ default_numeric_fallback\n            _ => 1.,\n            //~^ default_numeric_fallback\n        };\n\n        // Should NOT lint suffixed literals.\n        let x = 0.12_f64;\n\n        // Should NOT lint literals in init expr if `Local` has a type annotation.\n        let x: f64 = 0.1;\n        let x: [f64; 3] = [1., 2., 3.];\n        let x: (f64, f64) = if true { (1., 2.) } else { (3., 4.) };\n        let x: _ = 1.;\n        const X: f32 = 1.;\n    }\n}\n\nmod nested_local {\n    fn test() {\n        let x: _ = {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1.;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1.\n        };\n\n        let x: _ = if true {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1.;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1.\n        } else {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1.;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            2.\n        };\n\n        const X: f32 = {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1.;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1.\n        };\n    }\n}\n\nmod function_def {\n    fn ret_f64() -> f64 {\n        1.\n    }\n\n    fn test() {\n        // Should lint this because return type is inferred to `f64` and NOT bound to a concrete\n        // type.\n        let f = || -> _ { 1. };\n        //~^ default_numeric_fallback\n\n        // Even though the output type is specified,\n        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.\n        let f = || -> f64 { 1. };\n        //~^ default_numeric_fallback\n    }\n}\n\nmod function_calls {\n    fn concrete_arg(f: f64) {}\n\n    fn generic_arg<T>(t: T) {}\n\n    fn test() {\n        // Should NOT lint this because the argument type is bound to a concrete type.\n        concrete_arg(1.);\n\n        // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.\n        generic_arg(1.);\n        //~^ default_numeric_fallback\n\n        // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.\n        let x: _ = generic_arg(1.);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod struct_ctor {\n    struct ConcreteStruct {\n        x: f64,\n    }\n\n    struct GenericStruct<T> {\n        x: T,\n    }\n\n    fn test() {\n        // Should NOT lint this because the field type is bound to a concrete type.\n        ConcreteStruct { x: 1. };\n\n        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.\n        GenericStruct { x: 1. };\n        //~^ default_numeric_fallback\n\n        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.\n        let _ = GenericStruct { x: 1. };\n        //~^ default_numeric_fallback\n    }\n}\n\nmod enum_ctor {\n    enum ConcreteEnum {\n        X(f64),\n    }\n\n    enum GenericEnum<T> {\n        X(T),\n    }\n\n    fn test() {\n        // Should NOT lint this because the field type is bound to a concrete type.\n        ConcreteEnum::X(1.);\n\n        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.\n        GenericEnum::X(1.);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod method_calls {\n    struct StructForMethodCallTest;\n\n    impl StructForMethodCallTest {\n        fn concrete_arg(&self, f: f64) {}\n\n        fn generic_arg<T>(&self, t: T) {}\n    }\n\n    fn test() {\n        let s = StructForMethodCallTest {};\n\n        // Should NOT lint this because the argument type is bound to a concrete type.\n        s.concrete_arg(1.);\n\n        // Should lint this because the argument type is bound to a concrete type.\n        s.generic_arg(1.);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod in_macro {\n    use super::*;\n\n    // Should lint in internal macro.\n    #[inline_macros]\n    fn internal() {\n        inline!(let x = 22.;);\n        //~^ default_numeric_fallback\n    }\n\n    // Should NOT lint in external macro.\n    fn external() {\n        external!(let x = 22.;);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/default_numeric_fallback_f64.stderr",
    "content": "error: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:21:17\n   |\nLL |         let x = 0.12;\n   |                 ^^^^ help: consider adding suffix: `0.12_f64`\n   |\n   = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::default_numeric_fallback)]`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:23:18\n   |\nLL |         let x = [1., 2., 3.];\n   |                  ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:23:22\n   |\nLL |         let x = [1., 2., 3.];\n   |                      ^^ help: consider adding suffix: `2.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:23:26\n   |\nLL |         let x = [1., 2., 3.];\n   |                          ^^ help: consider adding suffix: `3.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:27:28\n   |\nLL |         let x = if true { (1., 2.) } else { (3., 4.) };\n   |                            ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:27:32\n   |\nLL |         let x = if true { (1., 2.) } else { (3., 4.) };\n   |                                ^^ help: consider adding suffix: `2.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:27:46\n   |\nLL |         let x = if true { (1., 2.) } else { (3., 4.) };\n   |                                              ^^ help: consider adding suffix: `3.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:27:50\n   |\nLL |         let x = if true { (1., 2.) } else { (3., 4.) };\n   |                                                  ^^ help: consider adding suffix: `4.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:32:23\n   |\nLL |         let x = match 1. {\n   |                       ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:34:18\n   |\nLL |             _ => 1.,\n   |                  ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:54:21\n   |\nLL |             let y = 1.;\n   |                     ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:63:21\n   |\nLL |             let y = 1.;\n   |                     ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:70:21\n   |\nLL |             let y = 1.;\n   |                     ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:79:21\n   |\nLL |             let y = 1.;\n   |                     ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:96:27\n   |\nLL |         let f = || -> _ { 1. };\n   |                           ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:101:29\n   |\nLL |         let f = || -> f64 { 1. };\n   |                             ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:116:21\n   |\nLL |         generic_arg(1.);\n   |                     ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:120:32\n   |\nLL |         let x: _ = generic_arg(1.);\n   |                                ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:139:28\n   |\nLL |         GenericStruct { x: 1. };\n   |                            ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:143:36\n   |\nLL |         let _ = GenericStruct { x: 1. };\n   |                                    ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:162:24\n   |\nLL |         GenericEnum::X(1.);\n   |                        ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:183:23\n   |\nLL |         s.generic_arg(1.);\n   |                       ^^ help: consider adding suffix: `1.0_f64`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_f64.rs:194:25\n   |\nLL |         inline!(let x = 22.;);\n   |                         ^^^ help: consider adding suffix: `22.0_f64`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/default_numeric_fallback_i32.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::default_numeric_fallback)]\n#![allow(\n    unused,\n    clippy::never_loop,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::branches_sharing_code,\n    clippy::let_unit_value,\n    clippy::let_with_type_underscore\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nmod basic_expr {\n    fn test() {\n        // Should lint unsuffixed literals typed `i32`.\n        let x = 22_i32;\n        //~^ default_numeric_fallback\n        let x = [1_i32, 2_i32, 3_i32];\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        let x = if true { (1_i32, 2_i32) } else { (3_i32, 4_i32) };\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        let x = match 1_i32 {\n            //~^ default_numeric_fallback\n            1_i32 => 1_i32,\n            //~^ default_numeric_fallback\n            //~| default_numeric_fallback\n            _ => 2_i32,\n            //~^ default_numeric_fallback\n        };\n\n        // Should NOT lint suffixed literals.\n        let x = 22_i32;\n\n        // Should NOT lint literals in init expr if `Local` has a type annotation.\n        let x: [i32; 3] = [1, 2, 3];\n        let x: (i32, i32) = if true { (1, 2) } else { (3, 4) };\n        let x: _ = 1;\n        let x: u64 = 1;\n        const CONST_X: i8 = 1;\n    }\n}\n\nmod nested_local {\n    fn test() {\n        let x: _ = {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1_i32;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1\n        };\n\n        let x: _ = if true {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1_i32;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1\n        } else {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1_i32;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            2\n        };\n\n        const CONST_X: i32 = {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1_i32;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1\n        };\n    }\n}\n\nmod function_def {\n    fn ret_i32() -> i32 {\n        1\n    }\n\n    fn test() {\n        // Should lint this because return type is inferred to `i32` and NOT bound to a concrete\n        // type.\n        let f = || -> _ { 1_i32 };\n        //~^ default_numeric_fallback\n\n        // Even though the output type is specified,\n        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.\n        let f = || -> i32 { 1_i32 };\n        //~^ default_numeric_fallback\n    }\n}\n\nmod function_calls {\n    fn concrete_arg(x: i32) {}\n\n    fn generic_arg<T>(t: T) {}\n\n    fn test() {\n        // Should NOT lint this because the argument type is bound to a concrete type.\n        concrete_arg(1);\n\n        // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.\n        generic_arg(1_i32);\n        //~^ default_numeric_fallback\n\n        // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.\n        let x: _ = generic_arg(1_i32);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod struct_ctor {\n    struct ConcreteStruct {\n        x: i32,\n    }\n\n    struct GenericStruct<T> {\n        x: T,\n    }\n\n    fn test() {\n        // Should NOT lint this because the field type is bound to a concrete type.\n        ConcreteStruct { x: 1 };\n\n        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.\n        GenericStruct { x: 1_i32 };\n        //~^ default_numeric_fallback\n\n        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.\n        let _ = GenericStruct { x: 1_i32 };\n        //~^ default_numeric_fallback\n    }\n}\n\nmod enum_ctor {\n    enum ConcreteEnum {\n        X(i32),\n    }\n\n    enum GenericEnum<T> {\n        X(T),\n    }\n\n    fn test() {\n        // Should NOT lint this because the field type is bound to a concrete type.\n        ConcreteEnum::X(1);\n\n        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.\n        GenericEnum::X(1_i32);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod method_calls {\n    struct StructForMethodCallTest;\n\n    impl StructForMethodCallTest {\n        fn concrete_arg(&self, x: i32) {}\n\n        fn generic_arg<T>(&self, t: T) {}\n    }\n\n    fn test() {\n        let s = StructForMethodCallTest {};\n\n        // Should NOT lint this because the argument type is bound to a concrete type.\n        s.concrete_arg(1);\n\n        // Should lint this because the argument type is bound to a concrete type.\n        s.generic_arg(1_i32);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod in_macro {\n    use super::*;\n\n    // Should lint in internal macro.\n    #[inline_macros]\n    fn internal() {\n        inline!(let x = 22_i32;);\n        //~^ default_numeric_fallback\n    }\n\n    // Should NOT lint in external macro.\n    fn external() {\n        external!(let x = 22;);\n    }\n}\n\nfn check_expect_suppression() {\n    #[expect(clippy::default_numeric_fallback)]\n    let x = 21;\n}\n\nmod type_already_inferred {\n    // Should NOT lint if bound to return type\n    fn ret_i32() -> i32 {\n        1\n    }\n\n    // Should NOT lint if bound to return type\n    fn ret_if_i32(b: bool) -> i32 {\n        if b { 100 } else { 0 }\n    }\n\n    // Should NOT lint if bound to return type\n    fn ret_i32_tuple() -> (i32, i32) {\n        (0, 1)\n    }\n\n    // Should NOT lint if bound to return type\n    fn ret_stmt(b: bool) -> (i32, i32) {\n        if b {\n            return (0, 1);\n        }\n        (0, 0)\n    }\n\n    #[allow(clippy::useless_vec)]\n    fn vec_macro() {\n        // Should NOT lint in `vec!` call if the type was already stated\n        let data_i32: Vec<i32> = vec![1, 2, 3];\n        let data_i32 = vec![1_i32, 2_i32, 3_i32];\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n    }\n}\n\nmod issue12159 {\n    #![allow(non_upper_case_globals, clippy::exhaustive_structs)]\n    pub struct Foo;\n\n    static F: i32 = 1;\n    impl Foo {\n        const LIFE_u8: u8 = 42;\n        const LIFE_i8: i8 = 42;\n        const LIFE_u16: u16 = 42;\n        const LIFE_i16: i16 = 42;\n        const LIFE_u32: u32 = 42;\n        const LIFE_i32: i32 = 42;\n        const LIFE_u64: u64 = 42;\n        const LIFE_i64: i64 = 42;\n        const LIFE_u128: u128 = 42;\n        const LIFE_i128: i128 = 42;\n        const LIFE_usize: usize = 42;\n        const LIFE_isize: isize = 42;\n        const LIFE_f32: f32 = 42.;\n        const LIFE_f64: f64 = 42.;\n\n        const fn consts() {\n            const LIFE_u8: u8 = 42;\n            const LIFE_i8: i8 = 42;\n            const LIFE_u16: u16 = 42;\n            const LIFE_i16: i16 = 42;\n            const LIFE_u32: u32 = 42;\n            const LIFE_i32: i32 = 42;\n            const LIFE_u64: u64 = 42;\n            const LIFE_i64: i64 = 42;\n            const LIFE_u128: u128 = 42;\n            const LIFE_i128: i128 = 42;\n            const LIFE_usize: usize = 42;\n            const LIFE_isize: isize = 42;\n            const LIFE_f32: f32 = 42.;\n            const LIFE_f64: f64 = 42.;\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/default_numeric_fallback_i32.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::default_numeric_fallback)]\n#![allow(\n    unused,\n    clippy::never_loop,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::branches_sharing_code,\n    clippy::let_unit_value,\n    clippy::let_with_type_underscore\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nmod basic_expr {\n    fn test() {\n        // Should lint unsuffixed literals typed `i32`.\n        let x = 22;\n        //~^ default_numeric_fallback\n        let x = [1, 2, 3];\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        let x = if true { (1, 2) } else { (3, 4) };\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n        let x = match 1 {\n            //~^ default_numeric_fallback\n            1 => 1,\n            //~^ default_numeric_fallback\n            //~| default_numeric_fallback\n            _ => 2,\n            //~^ default_numeric_fallback\n        };\n\n        // Should NOT lint suffixed literals.\n        let x = 22_i32;\n\n        // Should NOT lint literals in init expr if `Local` has a type annotation.\n        let x: [i32; 3] = [1, 2, 3];\n        let x: (i32, i32) = if true { (1, 2) } else { (3, 4) };\n        let x: _ = 1;\n        let x: u64 = 1;\n        const CONST_X: i8 = 1;\n    }\n}\n\nmod nested_local {\n    fn test() {\n        let x: _ = {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1\n        };\n\n        let x: _ = if true {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1\n        } else {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            2\n        };\n\n        const CONST_X: i32 = {\n            // Should lint this because this literal is not bound to any types.\n            let y = 1;\n            //~^ default_numeric_fallback\n\n            // Should NOT lint this because this literal is bound to `_` of outer `Local`.\n            1\n        };\n    }\n}\n\nmod function_def {\n    fn ret_i32() -> i32 {\n        1\n    }\n\n    fn test() {\n        // Should lint this because return type is inferred to `i32` and NOT bound to a concrete\n        // type.\n        let f = || -> _ { 1 };\n        //~^ default_numeric_fallback\n\n        // Even though the output type is specified,\n        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.\n        let f = || -> i32 { 1 };\n        //~^ default_numeric_fallback\n    }\n}\n\nmod function_calls {\n    fn concrete_arg(x: i32) {}\n\n    fn generic_arg<T>(t: T) {}\n\n    fn test() {\n        // Should NOT lint this because the argument type is bound to a concrete type.\n        concrete_arg(1);\n\n        // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.\n        generic_arg(1);\n        //~^ default_numeric_fallback\n\n        // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.\n        let x: _ = generic_arg(1);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod struct_ctor {\n    struct ConcreteStruct {\n        x: i32,\n    }\n\n    struct GenericStruct<T> {\n        x: T,\n    }\n\n    fn test() {\n        // Should NOT lint this because the field type is bound to a concrete type.\n        ConcreteStruct { x: 1 };\n\n        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.\n        GenericStruct { x: 1 };\n        //~^ default_numeric_fallback\n\n        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.\n        let _ = GenericStruct { x: 1 };\n        //~^ default_numeric_fallback\n    }\n}\n\nmod enum_ctor {\n    enum ConcreteEnum {\n        X(i32),\n    }\n\n    enum GenericEnum<T> {\n        X(T),\n    }\n\n    fn test() {\n        // Should NOT lint this because the field type is bound to a concrete type.\n        ConcreteEnum::X(1);\n\n        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.\n        GenericEnum::X(1);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod method_calls {\n    struct StructForMethodCallTest;\n\n    impl StructForMethodCallTest {\n        fn concrete_arg(&self, x: i32) {}\n\n        fn generic_arg<T>(&self, t: T) {}\n    }\n\n    fn test() {\n        let s = StructForMethodCallTest {};\n\n        // Should NOT lint this because the argument type is bound to a concrete type.\n        s.concrete_arg(1);\n\n        // Should lint this because the argument type is bound to a concrete type.\n        s.generic_arg(1);\n        //~^ default_numeric_fallback\n    }\n}\n\nmod in_macro {\n    use super::*;\n\n    // Should lint in internal macro.\n    #[inline_macros]\n    fn internal() {\n        inline!(let x = 22;);\n        //~^ default_numeric_fallback\n    }\n\n    // Should NOT lint in external macro.\n    fn external() {\n        external!(let x = 22;);\n    }\n}\n\nfn check_expect_suppression() {\n    #[expect(clippy::default_numeric_fallback)]\n    let x = 21;\n}\n\nmod type_already_inferred {\n    // Should NOT lint if bound to return type\n    fn ret_i32() -> i32 {\n        1\n    }\n\n    // Should NOT lint if bound to return type\n    fn ret_if_i32(b: bool) -> i32 {\n        if b { 100 } else { 0 }\n    }\n\n    // Should NOT lint if bound to return type\n    fn ret_i32_tuple() -> (i32, i32) {\n        (0, 1)\n    }\n\n    // Should NOT lint if bound to return type\n    fn ret_stmt(b: bool) -> (i32, i32) {\n        if b {\n            return (0, 1);\n        }\n        (0, 0)\n    }\n\n    #[allow(clippy::useless_vec)]\n    fn vec_macro() {\n        // Should NOT lint in `vec!` call if the type was already stated\n        let data_i32: Vec<i32> = vec![1, 2, 3];\n        let data_i32 = vec![1, 2, 3];\n        //~^ default_numeric_fallback\n        //~| default_numeric_fallback\n        //~| default_numeric_fallback\n    }\n}\n\nmod issue12159 {\n    #![allow(non_upper_case_globals, clippy::exhaustive_structs)]\n    pub struct Foo;\n\n    static F: i32 = 1;\n    impl Foo {\n        const LIFE_u8: u8 = 42;\n        const LIFE_i8: i8 = 42;\n        const LIFE_u16: u16 = 42;\n        const LIFE_i16: i16 = 42;\n        const LIFE_u32: u32 = 42;\n        const LIFE_i32: i32 = 42;\n        const LIFE_u64: u64 = 42;\n        const LIFE_i64: i64 = 42;\n        const LIFE_u128: u128 = 42;\n        const LIFE_i128: i128 = 42;\n        const LIFE_usize: usize = 42;\n        const LIFE_isize: isize = 42;\n        const LIFE_f32: f32 = 42.;\n        const LIFE_f64: f64 = 42.;\n\n        const fn consts() {\n            const LIFE_u8: u8 = 42;\n            const LIFE_i8: i8 = 42;\n            const LIFE_u16: u16 = 42;\n            const LIFE_i16: i16 = 42;\n            const LIFE_u32: u32 = 42;\n            const LIFE_i32: i32 = 42;\n            const LIFE_u64: u64 = 42;\n            const LIFE_i64: i64 = 42;\n            const LIFE_u128: u128 = 42;\n            const LIFE_i128: i128 = 42;\n            const LIFE_usize: usize = 42;\n            const LIFE_isize: isize = 42;\n            const LIFE_f32: f32 = 42.;\n            const LIFE_f64: f64 = 42.;\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/default_numeric_fallback_i32.stderr",
    "content": "error: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:20:17\n   |\nLL |         let x = 22;\n   |                 ^^ help: consider adding suffix: `22_i32`\n   |\n   = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::default_numeric_fallback)]`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:22:18\n   |\nLL |         let x = [1, 2, 3];\n   |                  ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:22:21\n   |\nLL |         let x = [1, 2, 3];\n   |                     ^ help: consider adding suffix: `2_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:22:24\n   |\nLL |         let x = [1, 2, 3];\n   |                        ^ help: consider adding suffix: `3_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:26:28\n   |\nLL |         let x = if true { (1, 2) } else { (3, 4) };\n   |                            ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:26:31\n   |\nLL |         let x = if true { (1, 2) } else { (3, 4) };\n   |                               ^ help: consider adding suffix: `2_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:26:44\n   |\nLL |         let x = if true { (1, 2) } else { (3, 4) };\n   |                                            ^ help: consider adding suffix: `3_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:26:47\n   |\nLL |         let x = if true { (1, 2) } else { (3, 4) };\n   |                                               ^ help: consider adding suffix: `4_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:31:23\n   |\nLL |         let x = match 1 {\n   |                       ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:33:13\n   |\nLL |             1 => 1,\n   |             ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:33:18\n   |\nLL |             1 => 1,\n   |                  ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:36:18\n   |\nLL |             _ => 2,\n   |                  ^ help: consider adding suffix: `2_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:56:21\n   |\nLL |             let y = 1;\n   |                     ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:65:21\n   |\nLL |             let y = 1;\n   |                     ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:72:21\n   |\nLL |             let y = 1;\n   |                     ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:81:21\n   |\nLL |             let y = 1;\n   |                     ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:98:27\n   |\nLL |         let f = || -> _ { 1 };\n   |                           ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:103:29\n   |\nLL |         let f = || -> i32 { 1 };\n   |                             ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:118:21\n   |\nLL |         generic_arg(1);\n   |                     ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:122:32\n   |\nLL |         let x: _ = generic_arg(1);\n   |                                ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:141:28\n   |\nLL |         GenericStruct { x: 1 };\n   |                            ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:145:36\n   |\nLL |         let _ = GenericStruct { x: 1 };\n   |                                    ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:164:24\n   |\nLL |         GenericEnum::X(1);\n   |                        ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:185:23\n   |\nLL |         s.generic_arg(1);\n   |                       ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:196:25\n   |\nLL |         inline!(let x = 22;);\n   |                         ^^ help: consider adding suffix: `22_i32`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:239:29\n   |\nLL |         let data_i32 = vec![1, 2, 3];\n   |                             ^ help: consider adding suffix: `1_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:239:32\n   |\nLL |         let data_i32 = vec![1, 2, 3];\n   |                                ^ help: consider adding suffix: `2_i32`\n\nerror: default numeric fallback might occur\n  --> tests/ui/default_numeric_fallback_i32.rs:239:35\n   |\nLL |         let data_i32 = vec![1, 2, 3];\n   |                                   ^ help: consider adding suffix: `3_i32`\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui/default_trait_access.fixed",
    "content": "//@aux-build: proc_macros.rs\n#![deny(clippy::default_trait_access)]\n#![allow(dead_code, unused_imports)]\n\nextern crate proc_macros;\n\nuse proc_macros::with_span;\nuse std::default::Default as D2;\nuse std::{default, string};\n\nfn main() {\n    let s1: String = String::default();\n    //~^ default_trait_access\n\n    let s2 = String::default();\n\n    let s3: String = String::default();\n    //~^ default_trait_access\n\n    let s4: String = String::default();\n    //~^ default_trait_access\n\n    let s5 = string::String::default();\n\n    let s6: String = String::default();\n    //~^ default_trait_access\n\n    let s7 = std::string::String::default();\n\n    let s8: String = DefaultFactory::make_t_badly();\n\n    let s9: String = DefaultFactory::make_t_nicely();\n\n    let s10 = DerivedDefault::default();\n\n    let s11: GenericDerivedDefault<String> = GenericDerivedDefault::default();\n    //~^ default_trait_access\n\n    let s12 = GenericDerivedDefault::<String>::default();\n\n    let s13 = TupleDerivedDefault::default();\n\n    let s14: TupleDerivedDefault = TupleDerivedDefault::default();\n    //~^ default_trait_access\n\n    let s15: ArrayDerivedDefault = ArrayDerivedDefault::default();\n    //~^ default_trait_access\n\n    let s16 = ArrayDerivedDefault::default();\n\n    let s17: TupleStructDerivedDefault = TupleStructDerivedDefault::default();\n    //~^ default_trait_access\n\n    let s18 = TupleStructDerivedDefault::default();\n\n    let s19 = <DerivedDefault as Default>::default();\n\n    let s20 = UpdateSyntax {\n        s: \"foo\",\n        ..Default::default()\n    };\n\n    let _s21: String = with_span!(s Default::default());\n\n    #[expect(clippy::uninlined_format_args)]\n    println!(\n        \"[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}]\",\n        s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20,\n    );\n}\n\nstruct DefaultFactory;\n\nimpl DefaultFactory {\n    pub fn make_t_badly<T: Default>() -> T {\n        Default::default()\n    }\n\n    pub fn make_t_nicely<T: Default>() -> T {\n        T::default()\n    }\n}\n\n#[derive(Debug, Default)]\nstruct DerivedDefault {\n    pub s: String,\n}\n\n#[derive(Debug, Default)]\nstruct GenericDerivedDefault<T: Default + std::fmt::Debug> {\n    pub s: T,\n}\n\n#[derive(Debug, Default)]\nstruct TupleDerivedDefault {\n    pub s: (String, String),\n}\n\n#[derive(Debug, Default)]\nstruct ArrayDerivedDefault {\n    pub s: [String; 10],\n}\n\n#[derive(Debug, Default)]\nstruct TupleStructDerivedDefault(String);\n\n#[derive(Debug, Default)]\nstruct UpdateSyntax {\n    pub s: &'static str,\n    pub u: u64,\n}\n"
  },
  {
    "path": "tests/ui/default_trait_access.rs",
    "content": "//@aux-build: proc_macros.rs\n#![deny(clippy::default_trait_access)]\n#![allow(dead_code, unused_imports)]\n\nextern crate proc_macros;\n\nuse proc_macros::with_span;\nuse std::default::Default as D2;\nuse std::{default, string};\n\nfn main() {\n    let s1: String = Default::default();\n    //~^ default_trait_access\n\n    let s2 = String::default();\n\n    let s3: String = D2::default();\n    //~^ default_trait_access\n\n    let s4: String = std::default::Default::default();\n    //~^ default_trait_access\n\n    let s5 = string::String::default();\n\n    let s6: String = default::Default::default();\n    //~^ default_trait_access\n\n    let s7 = std::string::String::default();\n\n    let s8: String = DefaultFactory::make_t_badly();\n\n    let s9: String = DefaultFactory::make_t_nicely();\n\n    let s10 = DerivedDefault::default();\n\n    let s11: GenericDerivedDefault<String> = Default::default();\n    //~^ default_trait_access\n\n    let s12 = GenericDerivedDefault::<String>::default();\n\n    let s13 = TupleDerivedDefault::default();\n\n    let s14: TupleDerivedDefault = Default::default();\n    //~^ default_trait_access\n\n    let s15: ArrayDerivedDefault = Default::default();\n    //~^ default_trait_access\n\n    let s16 = ArrayDerivedDefault::default();\n\n    let s17: TupleStructDerivedDefault = Default::default();\n    //~^ default_trait_access\n\n    let s18 = TupleStructDerivedDefault::default();\n\n    let s19 = <DerivedDefault as Default>::default();\n\n    let s20 = UpdateSyntax {\n        s: \"foo\",\n        ..Default::default()\n    };\n\n    let _s21: String = with_span!(s Default::default());\n\n    #[expect(clippy::uninlined_format_args)]\n    println!(\n        \"[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}]\",\n        s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20,\n    );\n}\n\nstruct DefaultFactory;\n\nimpl DefaultFactory {\n    pub fn make_t_badly<T: Default>() -> T {\n        Default::default()\n    }\n\n    pub fn make_t_nicely<T: Default>() -> T {\n        T::default()\n    }\n}\n\n#[derive(Debug, Default)]\nstruct DerivedDefault {\n    pub s: String,\n}\n\n#[derive(Debug, Default)]\nstruct GenericDerivedDefault<T: Default + std::fmt::Debug> {\n    pub s: T,\n}\n\n#[derive(Debug, Default)]\nstruct TupleDerivedDefault {\n    pub s: (String, String),\n}\n\n#[derive(Debug, Default)]\nstruct ArrayDerivedDefault {\n    pub s: [String; 10],\n}\n\n#[derive(Debug, Default)]\nstruct TupleStructDerivedDefault(String);\n\n#[derive(Debug, Default)]\nstruct UpdateSyntax {\n    pub s: &'static str,\n    pub u: u64,\n}\n"
  },
  {
    "path": "tests/ui/default_trait_access.stderr",
    "content": "error: calling `String::default()` is more clear than this expression\n  --> tests/ui/default_trait_access.rs:12:22\n   |\nLL |     let s1: String = Default::default();\n   |                      ^^^^^^^^^^^^^^^^^^ help: try: `String::default()`\n   |\nnote: the lint level is defined here\n  --> tests/ui/default_trait_access.rs:2:9\n   |\nLL | #![deny(clippy::default_trait_access)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: calling `String::default()` is more clear than this expression\n  --> tests/ui/default_trait_access.rs:17:22\n   |\nLL |     let s3: String = D2::default();\n   |                      ^^^^^^^^^^^^^ help: try: `String::default()`\n\nerror: calling `String::default()` is more clear than this expression\n  --> tests/ui/default_trait_access.rs:20:22\n   |\nLL |     let s4: String = std::default::Default::default();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `String::default()`\n\nerror: calling `String::default()` is more clear than this expression\n  --> tests/ui/default_trait_access.rs:25:22\n   |\nLL |     let s6: String = default::Default::default();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `String::default()`\n\nerror: calling `GenericDerivedDefault::default()` is more clear than this expression\n  --> tests/ui/default_trait_access.rs:36:46\n   |\nLL |     let s11: GenericDerivedDefault<String> = Default::default();\n   |                                              ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()`\n\nerror: calling `TupleDerivedDefault::default()` is more clear than this expression\n  --> tests/ui/default_trait_access.rs:43:36\n   |\nLL |     let s14: TupleDerivedDefault = Default::default();\n   |                                    ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()`\n\nerror: calling `ArrayDerivedDefault::default()` is more clear than this expression\n  --> tests/ui/default_trait_access.rs:46:36\n   |\nLL |     let s15: ArrayDerivedDefault = Default::default();\n   |                                    ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()`\n\nerror: calling `TupleStructDerivedDefault::default()` is more clear than this expression\n  --> tests/ui/default_trait_access.rs:51:42\n   |\nLL |     let s17: TupleStructDerivedDefault = Default::default();\n   |                                          ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/default_union_representation.rs",
    "content": "#![feature(transparent_unions)]\n#![warn(clippy::default_union_representation)]\n#![allow(clippy::repr_packed_without_abi)]\n\nunion NoAttribute {\n    //~^ default_union_representation\n    a: i32,\n    b: u32,\n}\n\n#[repr(C)]\nunion ReprC {\n    a: i32,\n    b: u32,\n}\n\n#[repr(packed)]\nunion ReprPacked {\n    //~^ default_union_representation\n    a: i32,\n    b: u32,\n}\n\n#[repr(C, packed)]\nunion ReprCPacked {\n    a: i32,\n    b: u32,\n}\n\n#[repr(C, align(32))]\nunion ReprCAlign {\n    a: i32,\n    b: u32,\n}\n\n#[repr(align(32))]\nunion ReprAlign {\n    //~^ default_union_representation\n    a: i32,\n    b: u32,\n}\n\nunion SingleZST {\n    f0: (),\n}\nunion ZSTsAndField1 {\n    f0: u32,\n    f1: (),\n    f2: (),\n    f3: (),\n}\nunion ZSTsAndField2 {\n    f0: (),\n    f1: (),\n    f2: u32,\n    f3: (),\n}\nunion ZSTAndTwoFields {\n    //~^ default_union_representation\n    f0: u32,\n    f1: u64,\n    f2: (),\n}\n\n#[repr(C)]\nunion CZSTAndTwoFields {\n    f0: u32,\n    f1: u64,\n    f2: (),\n}\n\n#[repr(transparent)]\nunion ReprTransparent {\n    a: i32,\n}\n\n#[repr(transparent)]\nunion ReprTransparentZST {\n    a: i32,\n    b: (),\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/default_union_representation.stderr",
    "content": "error: this union has the default representation\n  --> tests/ui/default_union_representation.rs:5:1\n   |\nLL | / union NoAttribute {\nLL | |\nLL | |     a: i32,\nLL | |     b: u32,\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `NoAttribute` with `#[repr(C)]` to explicitly specify memory layout\n   = note: `-D clippy::default-union-representation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::default_union_representation)]`\n\nerror: this union has the default representation\n  --> tests/ui/default_union_representation.rs:18:1\n   |\nLL | / union ReprPacked {\nLL | |\nLL | |     a: i32,\nLL | |     b: u32,\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `ReprPacked` with `#[repr(C)]` to explicitly specify memory layout\n\nerror: this union has the default representation\n  --> tests/ui/default_union_representation.rs:37:1\n   |\nLL | / union ReprAlign {\nLL | |\nLL | |     a: i32,\nLL | |     b: u32,\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `ReprAlign` with `#[repr(C)]` to explicitly specify memory layout\n\nerror: this union has the default representation\n  --> tests/ui/default_union_representation.rs:58:1\n   |\nLL | / union ZSTAndTwoFields {\nLL | |\nLL | |     f0: u32,\nLL | |     f1: u64,\nLL | |     f2: (),\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `ZSTAndTwoFields` with `#[repr(C)]` to explicitly specify memory layout\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/deprecated.rs",
    "content": "// This file was generated by `cargo dev update_lints`.\n// Use that command to update this file and do not edit by hand.\n// Manual edits will be overwritten.\n\n#![warn(clippy::assign_ops)] //~ ERROR: lint `clippy::assign_ops`\n#![warn(clippy::extend_from_slice)] //~ ERROR: lint `clippy::extend_from_slice`\n#![warn(clippy::match_on_vec_items)] //~ ERROR: lint `clippy::match_on_vec_items`\n#![warn(clippy::misaligned_transmute)] //~ ERROR: lint `clippy::misaligned_transmute`\n#![warn(clippy::option_map_or_err_ok)] //~ ERROR: lint `clippy::option_map_or_err_ok`\n#![warn(clippy::pub_enum_variant_names)] //~ ERROR: lint `clippy::pub_enum_variant_names`\n#![warn(clippy::range_step_by_zero)] //~ ERROR: lint `clippy::range_step_by_zero`\n#![warn(clippy::regex_macro)] //~ ERROR: lint `clippy::regex_macro`\n#![warn(clippy::replace_consts)] //~ ERROR: lint `clippy::replace_consts`\n#![warn(clippy::should_assert_eq)] //~ ERROR: lint `clippy::should_assert_eq`\n#![warn(clippy::string_to_string)] //~ ERROR: lint `clippy::string_to_string`\n#![warn(clippy::unsafe_vector_initialization)] //~ ERROR: lint `clippy::unsafe_vector_initialization`\n#![warn(clippy::unstable_as_mut_slice)] //~ ERROR: lint `clippy::unstable_as_mut_slice`\n#![warn(clippy::unstable_as_slice)] //~ ERROR: lint `clippy::unstable_as_slice`\n#![warn(clippy::unused_collect)] //~ ERROR: lint `clippy::unused_collect`\n#![warn(clippy::wrong_pub_self_convention)] //~ ERROR: lint `clippy::wrong_pub_self_convention`\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/deprecated.stderr",
    "content": "error: lint `clippy::assign_ops` has been removed: compound operators are harmless and linting on them is not in scope for clippy\n  --> tests/ui/deprecated.rs:5:9\n   |\nLL | #![warn(clippy::assign_ops)]\n   |         ^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D renamed-and-removed-lints` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`\n\nerror: lint `clippy::extend_from_slice` has been removed: `Vec::extend_from_slice` is no longer faster than `Vec::extend` due to specialization\n  --> tests/ui/deprecated.rs:6:9\n   |\nLL | #![warn(clippy::extend_from_slice)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::match_on_vec_items` has been removed: `clippy::indexing_slicing` covers indexing and slicing on `Vec<_>`\n  --> tests/ui/deprecated.rs:7:9\n   |\nLL | #![warn(clippy::match_on_vec_items)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::misaligned_transmute` has been removed: split into `clippy::cast_ptr_alignment` and `clippy::transmute_ptr_to_ptr`\n  --> tests/ui/deprecated.rs:8:9\n   |\nLL | #![warn(clippy::misaligned_transmute)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::option_map_or_err_ok` has been removed: `clippy::manual_ok_or` covers this case\n  --> tests/ui/deprecated.rs:9:9\n   |\nLL | #![warn(clippy::option_map_or_err_ok)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::pub_enum_variant_names` has been removed: `clippy::enum_variant_names` now covers this case via the `avoid-breaking-exported-api` config\n  --> tests/ui/deprecated.rs:10:9\n   |\nLL | #![warn(clippy::pub_enum_variant_names)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::range_step_by_zero` has been removed: `Iterator::step_by(0)` now panics and is no longer an infinite iterator\n  --> tests/ui/deprecated.rs:11:9\n   |\nLL | #![warn(clippy::range_step_by_zero)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::regex_macro` has been removed: the `regex!` macro was removed from the regex crate in 2018\n  --> tests/ui/deprecated.rs:12:9\n   |\nLL | #![warn(clippy::regex_macro)]\n   |         ^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::replace_consts` has been removed: `min_value` and `max_value` are now deprecated\n  --> tests/ui/deprecated.rs:13:9\n   |\nLL | #![warn(clippy::replace_consts)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::should_assert_eq` has been removed: `assert!(a == b)` can now print the values the same way `assert_eq!(a, b) can\n  --> tests/ui/deprecated.rs:14:9\n   |\nLL | #![warn(clippy::should_assert_eq)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::string_to_string` has been removed: `clippy::implicit_clone` covers those cases\n  --> tests/ui/deprecated.rs:15:9\n   |\nLL | #![warn(clippy::string_to_string)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::unsafe_vector_initialization` has been removed: the suggested alternative could be substantially slower\n  --> tests/ui/deprecated.rs:16:9\n   |\nLL | #![warn(clippy::unsafe_vector_initialization)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::unstable_as_mut_slice` has been removed: `Vec::as_mut_slice` is now stable\n  --> tests/ui/deprecated.rs:17:9\n   |\nLL | #![warn(clippy::unstable_as_mut_slice)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::unstable_as_slice` has been removed: `Vec::as_slice` is now stable\n  --> tests/ui/deprecated.rs:18:9\n   |\nLL | #![warn(clippy::unstable_as_slice)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::unused_collect` has been removed: `Iterator::collect` is now marked as `#[must_use]`\n  --> tests/ui/deprecated.rs:19:9\n   |\nLL | #![warn(clippy::unused_collect)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: lint `clippy::wrong_pub_self_convention` has been removed: `clippy::wrong_self_convention` now covers this case via the `avoid-breaking-exported-api` config\n  --> tests/ui/deprecated.rs:20:9\n   |\nLL | #![warn(clippy::wrong_pub_self_convention)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/deref_addrof.fixed",
    "content": "#![allow(\n    dangerous_implicit_autorefs,\n    clippy::explicit_auto_deref,\n    clippy::return_self_not_must_use,\n    clippy::useless_vec\n)]\n#![warn(clippy::deref_addrof)]\n\nfn get_number() -> usize {\n    10\n}\n\nfn get_reference(n: &usize) -> &usize {\n    n\n}\n\n#[allow(clippy::double_parens)]\n#[allow(unused_variables, unused_parens)]\nfn main() {\n    let a = 10;\n    let aref = &a;\n\n    let b = a;\n    //~^ deref_addrof\n\n    let b = get_number();\n    //~^ deref_addrof\n\n    let b = *get_reference(&a);\n\n    let bytes: Vec<usize> = vec![1, 2, 3, 4];\n    let b = bytes[1..2][0];\n    //~^ deref_addrof\n\n    //This produces a suggestion of 'let b = (a);' which\n    //will trigger the 'unused_parens' lint\n    let b = (a);\n    //~^ deref_addrof\n\n    let b = a;\n    //~^ deref_addrof\n\n    #[rustfmt::skip]\n    let b = a;\n    //~^ deref_addrof\n\n    let b = &a;\n    //~^ deref_addrof\n\n    let b = *aref;\n    //~^ deref_addrof\n\n    let _ = unsafe { *core::ptr::addr_of!(a) };\n\n    let _repeat = [0; 64];\n    //~^ deref_addrof\n    // do NOT lint for array as semantic differences with/out `*&`.\n    let _arr = *&[0, 1, 2, 3, 4];\n\n    // Do not lint when text comes from macro\n    macro_rules! mac {\n        (dr) => {\n            *&0\n        };\n        (dr $e:expr) => {\n            *&$e\n        };\n        (r $e:expr) => {\n            &$e\n        };\n    }\n    let b = mac!(dr);\n    let b = mac!(dr a);\n    let b = *mac!(r a);\n}\n\nfn issue14386() {\n    use std::mem::ManuallyDrop;\n\n    #[derive(Copy, Clone)]\n    struct Data {\n        num: u64,\n    }\n\n    #[derive(Clone, Copy)]\n    struct M {\n        md: ManuallyDrop<[u8; 4]>,\n    }\n\n    union DataWithPadding<'lt> {\n        data: ManuallyDrop<Data>,\n        prim: ManuallyDrop<u64>,\n        padding: [u8; size_of::<Data>()],\n        tup: (ManuallyDrop<Data>, ()),\n        indirect: M,\n        indirect_arr: [M; 2],\n        indirect_ref: &'lt mut M,\n    }\n\n    let mut a = DataWithPadding {\n        padding: [0; size_of::<DataWithPadding>()],\n    };\n    unsafe {\n        a.padding = [1; size_of::<DataWithPadding>()];\n        //~^ deref_addrof\n        a.tup.1 = ();\n        //~^ deref_addrof\n        *a.prim = 0;\n        //~^ deref_addrof\n\n        (*a.data).num = 42;\n        //~^ deref_addrof\n        (*a.indirect.md)[3] = 1;\n        //~^ deref_addrof\n        (*a.indirect_arr[1].md)[3] = 1;\n        //~^ deref_addrof\n        (*a.indirect_ref.md)[3] = 1;\n        //~^ deref_addrof\n\n        // Check that raw pointers are properly considered as well\n        *a.prim = 0;\n        //~^ deref_addrof\n        (*a.data).num = 42;\n        //~^ deref_addrof\n\n        // Do not lint, as the dereference happens later, we cannot\n        // just remove `&mut`\n        (*&mut a.tup).0.num = 42;\n    }\n}\n"
  },
  {
    "path": "tests/ui/deref_addrof.rs",
    "content": "#![allow(\n    dangerous_implicit_autorefs,\n    clippy::explicit_auto_deref,\n    clippy::return_self_not_must_use,\n    clippy::useless_vec\n)]\n#![warn(clippy::deref_addrof)]\n\nfn get_number() -> usize {\n    10\n}\n\nfn get_reference(n: &usize) -> &usize {\n    n\n}\n\n#[allow(clippy::double_parens)]\n#[allow(unused_variables, unused_parens)]\nfn main() {\n    let a = 10;\n    let aref = &a;\n\n    let b = *&a;\n    //~^ deref_addrof\n\n    let b = *&get_number();\n    //~^ deref_addrof\n\n    let b = *get_reference(&a);\n\n    let bytes: Vec<usize> = vec![1, 2, 3, 4];\n    let b = *&bytes[1..2][0];\n    //~^ deref_addrof\n\n    //This produces a suggestion of 'let b = (a);' which\n    //will trigger the 'unused_parens' lint\n    let b = *&(a);\n    //~^ deref_addrof\n\n    let b = *(&a);\n    //~^ deref_addrof\n\n    #[rustfmt::skip]\n    let b = *((&a));\n    //~^ deref_addrof\n\n    let b = *&&a;\n    //~^ deref_addrof\n\n    let b = **&aref;\n    //~^ deref_addrof\n\n    let _ = unsafe { *core::ptr::addr_of!(a) };\n\n    let _repeat = *&[0; 64];\n    //~^ deref_addrof\n    // do NOT lint for array as semantic differences with/out `*&`.\n    let _arr = *&[0, 1, 2, 3, 4];\n\n    // Do not lint when text comes from macro\n    macro_rules! mac {\n        (dr) => {\n            *&0\n        };\n        (dr $e:expr) => {\n            *&$e\n        };\n        (r $e:expr) => {\n            &$e\n        };\n    }\n    let b = mac!(dr);\n    let b = mac!(dr a);\n    let b = *mac!(r a);\n}\n\nfn issue14386() {\n    use std::mem::ManuallyDrop;\n\n    #[derive(Copy, Clone)]\n    struct Data {\n        num: u64,\n    }\n\n    #[derive(Clone, Copy)]\n    struct M {\n        md: ManuallyDrop<[u8; 4]>,\n    }\n\n    union DataWithPadding<'lt> {\n        data: ManuallyDrop<Data>,\n        prim: ManuallyDrop<u64>,\n        padding: [u8; size_of::<Data>()],\n        tup: (ManuallyDrop<Data>, ()),\n        indirect: M,\n        indirect_arr: [M; 2],\n        indirect_ref: &'lt mut M,\n    }\n\n    let mut a = DataWithPadding {\n        padding: [0; size_of::<DataWithPadding>()],\n    };\n    unsafe {\n        (*&mut a.padding) = [1; size_of::<DataWithPadding>()];\n        //~^ deref_addrof\n        (*&mut a.tup).1 = ();\n        //~^ deref_addrof\n        **&mut a.prim = 0;\n        //~^ deref_addrof\n\n        (*&mut a.data).num = 42;\n        //~^ deref_addrof\n        (*&mut a.indirect.md)[3] = 1;\n        //~^ deref_addrof\n        (*&mut a.indirect_arr[1].md)[3] = 1;\n        //~^ deref_addrof\n        (*&mut a.indirect_ref.md)[3] = 1;\n        //~^ deref_addrof\n\n        // Check that raw pointers are properly considered as well\n        **&raw mut a.prim = 0;\n        //~^ deref_addrof\n        (*&raw mut a.data).num = 42;\n        //~^ deref_addrof\n\n        // Do not lint, as the dereference happens later, we cannot\n        // just remove `&mut`\n        (*&mut a.tup).0.num = 42;\n    }\n}\n"
  },
  {
    "path": "tests/ui/deref_addrof.stderr",
    "content": "error: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:23:13\n   |\nLL |     let b = *&a;\n   |             ^^^ help: try: `a`\n   |\n   = note: `-D clippy::deref-addrof` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::deref_addrof)]`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:26:13\n   |\nLL |     let b = *&get_number();\n   |             ^^^^^^^^^^^^^^ help: try: `get_number()`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:32:13\n   |\nLL |     let b = *&bytes[1..2][0];\n   |             ^^^^^^^^^^^^^^^^ help: try: `bytes[1..2][0]`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:37:13\n   |\nLL |     let b = *&(a);\n   |             ^^^^^ help: try: `(a)`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:40:13\n   |\nLL |     let b = *(&a);\n   |             ^^^^^ help: try: `a`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:44:13\n   |\nLL |     let b = *((&a));\n   |             ^^^^^^^ help: try: `a`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:47:13\n   |\nLL |     let b = *&&a;\n   |             ^^^^ help: try: `&a`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:50:14\n   |\nLL |     let b = **&aref;\n   |              ^^^^^^ help: try: `aref`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:55:19\n   |\nLL |     let _repeat = *&[0; 64];\n   |                   ^^^^^^^^^ help: try: `[0; 64]`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:104:9\n   |\nLL |         (*&mut a.padding) = [1; size_of::<DataWithPadding>()];\n   |         ^^^^^^^^^^^^^^^^^ help: try: `a.padding`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:106:9\n   |\nLL |         (*&mut a.tup).1 = ();\n   |         ^^^^^^^^^^^^^ help: try: `a.tup`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:108:10\n   |\nLL |         **&mut a.prim = 0;\n   |          ^^^^^^^^^^^^ help: try: `a.prim`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:111:9\n   |\nLL |         (*&mut a.data).num = 42;\n   |         ^^^^^^^^^^^^^^ help: try: `(*a.data)`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:113:9\n   |\nLL |         (*&mut a.indirect.md)[3] = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^ help: try: `(*a.indirect.md)`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:115:9\n   |\nLL |         (*&mut a.indirect_arr[1].md)[3] = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*a.indirect_arr[1].md)`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:117:9\n   |\nLL |         (*&mut a.indirect_ref.md)[3] = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*a.indirect_ref.md)`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:121:10\n   |\nLL |         **&raw mut a.prim = 0;\n   |          ^^^^^^^^^^^^^^^^ help: try: `a.prim`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof.rs:123:9\n   |\nLL |         (*&raw mut a.data).num = 42;\n   |         ^^^^^^^^^^^^^^^^^^ help: try: `(*a.data)`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/deref_addrof_double_trigger.rs",
    "content": "//@no-rustfix: this test can't work with run-rustfix because it needs two passes of test+fix\n\n#[warn(clippy::deref_addrof)]\n#[allow(unused_variables, unused_mut)]\nfn main() {\n    let a = 10;\n\n    //This produces a suggestion of 'let b = *&a;' which\n    //will trigger the 'clippy::deref_addrof' lint again\n    let b = **&&a;\n    //~^ deref_addrof\n\n    {\n        let mut x = 10;\n        let y = *&mut x;\n        //~^ deref_addrof\n    }\n\n    {\n        //This produces a suggestion of 'let y = *&mut x' which\n        //will trigger the 'clippy::deref_addrof' lint again\n        let mut x = 10;\n        let y = **&mut &mut x;\n        //~^ deref_addrof\n    }\n}\n"
  },
  {
    "path": "tests/ui/deref_addrof_double_trigger.stderr",
    "content": "error: immediately dereferencing a reference\n  --> tests/ui/deref_addrof_double_trigger.rs:10:14\n   |\nLL |     let b = **&&a;\n   |              ^^^^ help: try: `&a`\n   |\n   = note: `-D clippy::deref-addrof` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::deref_addrof)]`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof_double_trigger.rs:15:17\n   |\nLL |         let y = *&mut x;\n   |                 ^^^^^^^ help: try: `x`\n\nerror: immediately dereferencing a reference\n  --> tests/ui/deref_addrof_double_trigger.rs:23:18\n   |\nLL |         let y = **&mut &mut x;\n   |                  ^^^^^^^^^^^^ help: try: `&mut x`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/deref_addrof_macro.rs",
    "content": "//@ check-pass\n//@aux-build:proc_macros.rs\n\n#![warn(clippy::deref_addrof)]\n\nextern crate proc_macros;\n\n#[proc_macros::inline_macros]\nfn f() -> i32 {\n    // should be fine\n    *inline!(&$1)\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/deref_by_slicing.fixed",
    "content": "#![warn(clippy::deref_by_slicing)]\n#![allow(clippy::borrow_deref_ref)]\n\nuse std::io::Read;\n\nfn main() {\n    let mut vec = vec![0];\n    let _ = &*vec;\n    //~^ deref_by_slicing\n    let _ = &mut *vec;\n    //~^ deref_by_slicing\n\n    let ref_vec = &mut vec;\n    let _ = &**ref_vec;\n    //~^ deref_by_slicing\n    let mut_slice = &mut **ref_vec;\n    //~^ deref_by_slicing\n    let _ = &mut *mut_slice; // Err, re-borrows slice\n    //\n    //~^^ deref_by_slicing\n\n    let s = String::new();\n    let _ = &*s;\n    //~^ deref_by_slicing\n\n    static S: &[u8] = &[0, 1, 2];\n    let _ = &mut &*S; // Err, re-borrows slice\n    //\n    //~^^ deref_by_slicing\n\n    let slice: &[u32] = &[0u32, 1u32];\n    let slice_ref = &slice;\n    let _ = *slice_ref; // Err, derefs slice\n    //\n    //~^^ deref_by_slicing\n\n    let bytes: &[u8] = &[];\n    let _ = (&*bytes).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice\n    //\n    //~^^ deref_by_slicing\n\n    // issue 12751\n    let a = &mut [1, 2, 3][..];\n    let _ = &*a;\n    //~^ deref_by_slicing\n}\n"
  },
  {
    "path": "tests/ui/deref_by_slicing.rs",
    "content": "#![warn(clippy::deref_by_slicing)]\n#![allow(clippy::borrow_deref_ref)]\n\nuse std::io::Read;\n\nfn main() {\n    let mut vec = vec![0];\n    let _ = &vec[..];\n    //~^ deref_by_slicing\n    let _ = &mut vec[..];\n    //~^ deref_by_slicing\n\n    let ref_vec = &mut vec;\n    let _ = &ref_vec[..];\n    //~^ deref_by_slicing\n    let mut_slice = &mut ref_vec[..];\n    //~^ deref_by_slicing\n    let _ = &mut mut_slice[..]; // Err, re-borrows slice\n    //\n    //~^^ deref_by_slicing\n\n    let s = String::new();\n    let _ = &s[..];\n    //~^ deref_by_slicing\n\n    static S: &[u8] = &[0, 1, 2];\n    let _ = &mut &S[..]; // Err, re-borrows slice\n    //\n    //~^^ deref_by_slicing\n\n    let slice: &[u32] = &[0u32, 1u32];\n    let slice_ref = &slice;\n    let _ = &slice_ref[..]; // Err, derefs slice\n    //\n    //~^^ deref_by_slicing\n\n    let bytes: &[u8] = &[];\n    let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice\n    //\n    //~^^ deref_by_slicing\n\n    // issue 12751\n    let a = &mut [1, 2, 3][..];\n    let _ = &a[..];\n    //~^ deref_by_slicing\n}\n"
  },
  {
    "path": "tests/ui/deref_by_slicing.stderr",
    "content": "error: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:8:13\n   |\nLL |     let _ = &vec[..];\n   |             ^^^^^^^^ help: dereference the original value instead: `&*vec`\n   |\n   = note: `-D clippy::deref-by-slicing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::deref_by_slicing)]`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:10:13\n   |\nLL |     let _ = &mut vec[..];\n   |             ^^^^^^^^^^^^ help: dereference the original value instead: `&mut *vec`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:14:13\n   |\nLL |     let _ = &ref_vec[..];\n   |             ^^^^^^^^^^^^ help: dereference the original value instead: `&**ref_vec`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:16:21\n   |\nLL |     let mut_slice = &mut ref_vec[..];\n   |                     ^^^^^^^^^^^^^^^^ help: dereference the original value instead: `&mut **ref_vec`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:18:13\n   |\nLL |     let _ = &mut mut_slice[..]; // Err, re-borrows slice\n   |             ^^^^^^^^^^^^^^^^^^ help: reborrow the original value instead: `&mut *mut_slice`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:23:13\n   |\nLL |     let _ = &s[..];\n   |             ^^^^^^ help: dereference the original value instead: `&*s`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:27:18\n   |\nLL |     let _ = &mut &S[..]; // Err, re-borrows slice\n   |                  ^^^^^^ help: reborrow the original value instead: `&*S`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:33:13\n   |\nLL |     let _ = &slice_ref[..]; // Err, derefs slice\n   |             ^^^^^^^^^^^^^^ help: dereference the original value instead: `*slice_ref`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:38:13\n   |\nLL |     let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Err, re-borrows slice\n   |             ^^^^^^^^^^^^ help: reborrow the original value instead: `(&*bytes)`\n\nerror: slicing when dereferencing would work\n  --> tests/ui/deref_by_slicing.rs:44:13\n   |\nLL |     let _ = &a[..];\n   |             ^^^^^^ help: reborrow the original value instead: `&*a`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/derivable_impls.fixed",
    "content": "#![allow(dead_code)]\n#![feature(const_trait_impl)]\n#![feature(const_default)]\n\nuse std::collections::HashMap;\n\n#[derive(Default)]\nstruct FooDefault<'a> {\n    a: bool,\n    b: i32,\n    c: u64,\n    d: Vec<i32>,\n    e: FooND1,\n    f: FooND2,\n    g: HashMap<i32, i32>,\n    h: (i32, Vec<i32>),\n    i: [Vec<i32>; 3],\n    j: [i32; 5],\n    k: Option<i32>,\n    l: &'a [i32],\n}\n\n\n#[derive(Default)]\nstruct TupleDefault(bool, i32, u64);\n\n\nstruct FooND1 {\n    a: bool,\n}\n\nimpl std::default::Default for FooND1 {\n    fn default() -> Self {\n        Self { a: true }\n    }\n}\n\nstruct FooND2 {\n    a: i32,\n}\n\nimpl std::default::Default for FooND2 {\n    fn default() -> Self {\n        Self { a: 5 }\n    }\n}\n\nstruct FooNDNew {\n    a: bool,\n}\n\nimpl FooNDNew {\n    fn new() -> Self {\n        Self { a: true }\n    }\n}\n\nimpl Default for FooNDNew {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nstruct FooNDVec(Vec<i32>);\n\nimpl Default for FooNDVec {\n    fn default() -> Self {\n        Self(vec![5, 12])\n    }\n}\n\n#[derive(Default)]\nstruct StrDefault<'a>(&'a str);\n\n\n#[derive(Default)]\nstruct AlreadyDerived(i32, bool);\n\nmacro_rules! mac {\n    () => {\n        0\n    };\n    ($e:expr) => {\n        struct X(u32);\n        impl Default for X {\n            fn default() -> Self {\n                Self($e)\n            }\n        }\n    };\n}\n\nmac!(0);\n\n#[derive(Default)]\nstruct Y(u32);\n\nstruct RustIssue26925<T> {\n    a: Option<T>,\n}\n\n// We should watch out for cases where a manual impl is needed because a\n// derive adds different type bounds (https://github.com/rust-lang/rust/issues/26925).\n// For example, a struct with Option<T> does not require T: Default, but a derive adds\n// that type bound anyways. So until #26925 get fixed we should disable lint\n// for the following case\nimpl<T> Default for RustIssue26925<T> {\n    fn default() -> Self {\n        Self { a: None }\n    }\n}\n\nstruct SpecializedImpl<A, B> {\n    a: A,\n    b: B,\n}\n\nimpl<T: Default> Default for SpecializedImpl<T, T> {\n    fn default() -> Self {\n        Self {\n            a: T::default(),\n            b: T::default(),\n        }\n    }\n}\n\n#[derive(Default)]\nstruct WithoutSelfCurly {\n    a: bool,\n}\n\n\n#[derive(Default)]\nstruct WithoutSelfParan(bool);\n\n\n// https://github.com/rust-lang/rust-clippy/issues/7655\n\npub struct SpecializedImpl2<T> {\n    v: Vec<T>,\n}\n\nimpl Default for SpecializedImpl2<String> {\n    fn default() -> Self {\n        Self { v: Vec::new() }\n    }\n}\n\n#[derive(Default)]\npub struct DirectDefaultDefaultCall {\n    v: Vec<i32>,\n}\n\n\n#[derive(Default)]\npub struct EquivalentToDefaultDefaultCallVec {\n    v: Vec<i32>,\n}\n\n\npub struct S {\n    x: i32,\n}\n\nimpl S {\n    fn new() -> S {\n        S { x: 42 }\n    }\n}\n\nimpl Default for S {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\n#[derive(Default)]\npub struct EquivalentToDefaultDefaultCallLocal {\n    v: S,\n}\n\n\n// https://github.com/rust-lang/rust-clippy/issues/7654\n\npub struct Color {\n    pub r: u8,\n    pub g: u8,\n    pub b: u8,\n}\n\n/// `#000000`\nimpl Default for Color {\n    fn default() -> Self {\n        Color { r: 0, g: 0, b: 0 }\n    }\n}\n\npub struct Color2 {\n    pub r: u8,\n    pub g: u8,\n    pub b: u8,\n}\n\nimpl Default for Color2 {\n    /// `#000000`\n    fn default() -> Self {\n        Self { r: 0, g: 0, b: 0 }\n    }\n}\n\n#[derive(Default)]\npub struct RepeatDefault1 {\n    a: [i8; 32],\n}\n\n\npub struct RepeatDefault2 {\n    a: [i8; 33],\n}\n\nimpl Default for RepeatDefault2 {\n    fn default() -> Self {\n        RepeatDefault2 { a: [0; 33] }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7753\n\npub enum IntOrString {\n    Int(i32),\n    String(String),\n}\n\nimpl Default for IntOrString {\n    fn default() -> Self {\n        IntOrString::Int(0)\n    }\n}\n\n#[derive(Default)]\npub enum SimpleEnum {\n    Foo,\n    #[default]\n    Bar,\n}\n\n\npub enum NonExhaustiveEnum {\n    Foo,\n    #[non_exhaustive]\n    Bar,\n}\n\nimpl Default for NonExhaustiveEnum {\n    fn default() -> Self {\n        NonExhaustiveEnum::Bar\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/10396\n\n#[derive(Default)]\nstruct DefaultType;\n\nstruct GenericType<T = DefaultType> {\n    t: T,\n}\n\nimpl Default for GenericType {\n    fn default() -> Self {\n        Self { t: Default::default() }\n    }\n}\n\nstruct InnerGenericType<T> {\n    t: T,\n}\n\nimpl Default for InnerGenericType<DefaultType> {\n    fn default() -> Self {\n        Self { t: Default::default() }\n    }\n}\n\nstruct OtherGenericType<T = DefaultType> {\n    inner: InnerGenericType<T>,\n}\n\nimpl Default for OtherGenericType {\n    fn default() -> Self {\n        Self {\n            inner: Default::default(),\n        }\n    }\n}\n\nmod issue10158 {\n    pub trait T {}\n\n    #[derive(Default)]\n    pub struct S {}\n    impl T for S {}\n\n    pub struct Outer {\n        pub inner: Box<dyn T>,\n    }\n\n    impl Default for Outer {\n        fn default() -> Self {\n            Outer {\n                // Box::<S>::default() adjusts to Box<dyn T>\n                inner: Box::<S>::default(),\n            }\n        }\n    }\n}\n\nmod issue11368 {\n    pub struct A {\n        a: u32,\n    }\n\n    impl Default for A {\n        #[track_caller]\n        fn default() -> Self {\n            Self { a: 0 }\n        }\n    }\n}\n\nmod issue15493 {\n    #[derive(Copy, Clone)]\n    #[repr(transparent)]\n    struct Foo(u64);\n\n    impl const Default for Foo {\n        fn default() -> Self {\n            Self(0)\n        }\n    }\n\n    #[derive(Copy, Clone)]\n    enum Bar {\n        A,\n        B,\n    }\n\n    impl const Default for Bar {\n        fn default() -> Self {\n            Bar::A\n        }\n    }\n}\n\nmod issue15536 {\n    #[derive(Copy, Clone)]\n    #[derive(Default)]\n    enum Bar {\n        #[default]\n        A,\n        B,\n    }\n\n    \n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derivable_impls.rs",
    "content": "#![allow(dead_code)]\n#![feature(const_trait_impl)]\n#![feature(const_default)]\n\nuse std::collections::HashMap;\n\nstruct FooDefault<'a> {\n    a: bool,\n    b: i32,\n    c: u64,\n    d: Vec<i32>,\n    e: FooND1,\n    f: FooND2,\n    g: HashMap<i32, i32>,\n    h: (i32, Vec<i32>),\n    i: [Vec<i32>; 3],\n    j: [i32; 5],\n    k: Option<i32>,\n    l: &'a [i32],\n}\n\nimpl std::default::Default for FooDefault<'_> {\n    //~^ derivable_impls\n    fn default() -> Self {\n        Self {\n            a: false,\n            b: 0,\n            c: 0u64,\n            d: vec![],\n            e: Default::default(),\n            f: FooND2::default(),\n            g: HashMap::new(),\n            h: (0, vec![]),\n            i: [vec![], vec![], vec![]],\n            j: [0; 5],\n            k: None,\n            l: &[],\n        }\n    }\n}\n\nstruct TupleDefault(bool, i32, u64);\n\nimpl std::default::Default for TupleDefault {\n    //~^ derivable_impls\n    fn default() -> Self {\n        Self(false, 0, 0u64)\n    }\n}\n\nstruct FooND1 {\n    a: bool,\n}\n\nimpl std::default::Default for FooND1 {\n    fn default() -> Self {\n        Self { a: true }\n    }\n}\n\nstruct FooND2 {\n    a: i32,\n}\n\nimpl std::default::Default for FooND2 {\n    fn default() -> Self {\n        Self { a: 5 }\n    }\n}\n\nstruct FooNDNew {\n    a: bool,\n}\n\nimpl FooNDNew {\n    fn new() -> Self {\n        Self { a: true }\n    }\n}\n\nimpl Default for FooNDNew {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nstruct FooNDVec(Vec<i32>);\n\nimpl Default for FooNDVec {\n    fn default() -> Self {\n        Self(vec![5, 12])\n    }\n}\n\nstruct StrDefault<'a>(&'a str);\n\nimpl Default for StrDefault<'_> {\n    //~^ derivable_impls\n    fn default() -> Self {\n        Self(\"\")\n    }\n}\n\n#[derive(Default)]\nstruct AlreadyDerived(i32, bool);\n\nmacro_rules! mac {\n    () => {\n        0\n    };\n    ($e:expr) => {\n        struct X(u32);\n        impl Default for X {\n            fn default() -> Self {\n                Self($e)\n            }\n        }\n    };\n}\n\nmac!(0);\n\nstruct Y(u32);\nimpl Default for Y {\n    //~^ derivable_impls\n    fn default() -> Self {\n        Self(mac!())\n    }\n}\n\nstruct RustIssue26925<T> {\n    a: Option<T>,\n}\n\n// We should watch out for cases where a manual impl is needed because a\n// derive adds different type bounds (https://github.com/rust-lang/rust/issues/26925).\n// For example, a struct with Option<T> does not require T: Default, but a derive adds\n// that type bound anyways. So until #26925 get fixed we should disable lint\n// for the following case\nimpl<T> Default for RustIssue26925<T> {\n    fn default() -> Self {\n        Self { a: None }\n    }\n}\n\nstruct SpecializedImpl<A, B> {\n    a: A,\n    b: B,\n}\n\nimpl<T: Default> Default for SpecializedImpl<T, T> {\n    fn default() -> Self {\n        Self {\n            a: T::default(),\n            b: T::default(),\n        }\n    }\n}\n\nstruct WithoutSelfCurly {\n    a: bool,\n}\n\nimpl Default for WithoutSelfCurly {\n    //~^ derivable_impls\n    fn default() -> Self {\n        WithoutSelfCurly { a: false }\n    }\n}\n\nstruct WithoutSelfParan(bool);\n\nimpl Default for WithoutSelfParan {\n    //~^ derivable_impls\n    fn default() -> Self {\n        WithoutSelfParan(false)\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7655\n\npub struct SpecializedImpl2<T> {\n    v: Vec<T>,\n}\n\nimpl Default for SpecializedImpl2<String> {\n    fn default() -> Self {\n        Self { v: Vec::new() }\n    }\n}\n\npub struct DirectDefaultDefaultCall {\n    v: Vec<i32>,\n}\n\nimpl Default for DirectDefaultDefaultCall {\n    //~^ derivable_impls\n    fn default() -> Self {\n        // When calling `Default::default()` in all fields, we know it is the same as deriving.\n        Self { v: Default::default() }\n    }\n}\n\npub struct EquivalentToDefaultDefaultCallVec {\n    v: Vec<i32>,\n}\n\nimpl Default for EquivalentToDefaultDefaultCallVec {\n    //~^ derivable_impls\n    fn default() -> Self {\n        // The body of `<Vec as Default>::default()` is `Vec::new()`, so they are equivalent.\n        Self { v: Vec::new() }\n    }\n}\n\npub struct S {\n    x: i32,\n}\n\nimpl S {\n    fn new() -> S {\n        S { x: 42 }\n    }\n}\n\nimpl Default for S {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\npub struct EquivalentToDefaultDefaultCallLocal {\n    v: S,\n}\n\nimpl Default for EquivalentToDefaultDefaultCallLocal {\n    //~^ derivable_impls\n    fn default() -> Self {\n        // The body of `<S as Default>::default()` is `S::new()`, so they are equivalent.\n        Self { v: S::new() }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7654\n\npub struct Color {\n    pub r: u8,\n    pub g: u8,\n    pub b: u8,\n}\n\n/// `#000000`\nimpl Default for Color {\n    fn default() -> Self {\n        Color { r: 0, g: 0, b: 0 }\n    }\n}\n\npub struct Color2 {\n    pub r: u8,\n    pub g: u8,\n    pub b: u8,\n}\n\nimpl Default for Color2 {\n    /// `#000000`\n    fn default() -> Self {\n        Self { r: 0, g: 0, b: 0 }\n    }\n}\n\npub struct RepeatDefault1 {\n    a: [i8; 32],\n}\n\nimpl Default for RepeatDefault1 {\n    //~^ derivable_impls\n    fn default() -> Self {\n        RepeatDefault1 { a: [0; 32] }\n    }\n}\n\npub struct RepeatDefault2 {\n    a: [i8; 33],\n}\n\nimpl Default for RepeatDefault2 {\n    fn default() -> Self {\n        RepeatDefault2 { a: [0; 33] }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7753\n\npub enum IntOrString {\n    Int(i32),\n    String(String),\n}\n\nimpl Default for IntOrString {\n    fn default() -> Self {\n        IntOrString::Int(0)\n    }\n}\n\npub enum SimpleEnum {\n    Foo,\n    Bar,\n}\n\nimpl Default for SimpleEnum {\n    //~^ derivable_impls\n    fn default() -> Self {\n        SimpleEnum::Bar\n    }\n}\n\npub enum NonExhaustiveEnum {\n    Foo,\n    #[non_exhaustive]\n    Bar,\n}\n\nimpl Default for NonExhaustiveEnum {\n    fn default() -> Self {\n        NonExhaustiveEnum::Bar\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/10396\n\n#[derive(Default)]\nstruct DefaultType;\n\nstruct GenericType<T = DefaultType> {\n    t: T,\n}\n\nimpl Default for GenericType {\n    fn default() -> Self {\n        Self { t: Default::default() }\n    }\n}\n\nstruct InnerGenericType<T> {\n    t: T,\n}\n\nimpl Default for InnerGenericType<DefaultType> {\n    fn default() -> Self {\n        Self { t: Default::default() }\n    }\n}\n\nstruct OtherGenericType<T = DefaultType> {\n    inner: InnerGenericType<T>,\n}\n\nimpl Default for OtherGenericType {\n    fn default() -> Self {\n        Self {\n            inner: Default::default(),\n        }\n    }\n}\n\nmod issue10158 {\n    pub trait T {}\n\n    #[derive(Default)]\n    pub struct S {}\n    impl T for S {}\n\n    pub struct Outer {\n        pub inner: Box<dyn T>,\n    }\n\n    impl Default for Outer {\n        fn default() -> Self {\n            Outer {\n                // Box::<S>::default() adjusts to Box<dyn T>\n                inner: Box::<S>::default(),\n            }\n        }\n    }\n}\n\nmod issue11368 {\n    pub struct A {\n        a: u32,\n    }\n\n    impl Default for A {\n        #[track_caller]\n        fn default() -> Self {\n            Self { a: 0 }\n        }\n    }\n}\n\nmod issue15493 {\n    #[derive(Copy, Clone)]\n    #[repr(transparent)]\n    struct Foo(u64);\n\n    impl const Default for Foo {\n        fn default() -> Self {\n            Self(0)\n        }\n    }\n\n    #[derive(Copy, Clone)]\n    enum Bar {\n        A,\n        B,\n    }\n\n    impl const Default for Bar {\n        fn default() -> Self {\n            Bar::A\n        }\n    }\n}\n\nmod issue15536 {\n    #[derive(Copy, Clone)]\n    enum Bar {\n        A,\n        B,\n    }\n\n    impl Default for Bar {\n        //~^ derivable_impls\n        fn default() -> Self {\n            Self::A\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derivable_impls.stderr",
    "content": "error: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:22:1\n   |\nLL | / impl std::default::Default for FooDefault<'_> {\nLL | |\nLL | |     fn default() -> Self {\nLL | |         Self {\n...  |\nLL | | }\n   | |_^\n   |\n   = note: `-D clippy::derivable-impls` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::derivable_impls)]`\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | struct FooDefault<'a> {\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:44:1\n   |\nLL | / impl std::default::Default for TupleDefault {\nLL | |\nLL | |     fn default() -> Self {\nLL | |         Self(false, 0, 0u64)\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | struct TupleDefault(bool, i32, u64);\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:97:1\n   |\nLL | / impl Default for StrDefault<'_> {\nLL | |\nLL | |     fn default() -> Self {\nLL | |         Self(\"\")\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | struct StrDefault<'a>(&'a str);\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:124:1\n   |\nLL | / impl Default for Y {\nLL | |\nLL | |     fn default() -> Self {\nLL | |         Self(mac!())\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | struct Y(u32);\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:164:1\n   |\nLL | / impl Default for WithoutSelfCurly {\nLL | |\nLL | |     fn default() -> Self {\nLL | |         WithoutSelfCurly { a: false }\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | struct WithoutSelfCurly {\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:173:1\n   |\nLL | / impl Default for WithoutSelfParan {\nLL | |\nLL | |     fn default() -> Self {\nLL | |         WithoutSelfParan(false)\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | struct WithoutSelfParan(bool);\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:196:1\n   |\nLL | / impl Default for DirectDefaultDefaultCall {\nLL | |\nLL | |     fn default() -> Self {\n...  |\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | pub struct DirectDefaultDefaultCall {\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:208:1\n   |\nLL | / impl Default for EquivalentToDefaultDefaultCallVec {\nLL | |\nLL | |     fn default() -> Self {\n...  |\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | pub struct EquivalentToDefaultDefaultCallVec {\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:236:1\n   |\nLL | / impl Default for EquivalentToDefaultDefaultCallLocal {\nLL | |\nLL | |     fn default() -> Self {\n...  |\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | pub struct EquivalentToDefaultDefaultCallLocal {\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:276:1\n   |\nLL | / impl Default for RepeatDefault1 {\nLL | |\nLL | |     fn default() -> Self {\nLL | |         RepeatDefault1 { a: [0; 32] }\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute\n   |\nLL + #[derive(Default)]\nLL | pub struct RepeatDefault1 {\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:311:1\n   |\nLL | / impl Default for SimpleEnum {\nLL | |\nLL | |     fn default() -> Self {\nLL | |         SimpleEnum::Bar\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: replace the manual implementation with a derive attribute and mark the default variant\n   |\nLL + #[derive(Default)]\nLL | pub enum SimpleEnum {\nLL |     Foo,\nLL ~     #[default]\nLL ~     Bar,\n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls.rs:432:5\n   |\nLL | /     impl Default for Bar {\nLL | |\nLL | |         fn default() -> Self {\nLL | |             Self::A\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: replace the manual implementation with a derive attribute and mark the default variant\n   |\nLL ~     #[derive(Default)]\nLL ~     enum Bar {\nLL ~         #[default]\nLL ~         A,\nLL |         B,\nLL |     }\nLL |\nLL ~     \n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/derivable_impls_derive_const.fixed",
    "content": "#![allow(dead_code)]\n#![feature(const_trait_impl)]\n#![feature(const_default)]\n#![feature(derive_const)]\n\nmod issue15493 {\n    #[derive(Copy, Clone)]\n    #[repr(transparent)]\n    #[derive_const(Default)]\n    struct Foo(u64);\n\n    \n\n    #[derive(Copy, Clone)]\n    #[derive_const(Default)]\n    enum Bar {\n        #[default]\n        A,\n        B,\n    }\n\n    \n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derivable_impls_derive_const.rs",
    "content": "#![allow(dead_code)]\n#![feature(const_trait_impl)]\n#![feature(const_default)]\n#![feature(derive_const)]\n\nmod issue15493 {\n    #[derive(Copy, Clone)]\n    #[repr(transparent)]\n    struct Foo(u64);\n\n    impl const Default for Foo {\n        //~^ derivable_impls\n        fn default() -> Self {\n            Self(0)\n        }\n    }\n\n    #[derive(Copy, Clone)]\n    enum Bar {\n        A,\n        B,\n    }\n\n    impl const Default for Bar {\n        //~^ derivable_impls\n        fn default() -> Self {\n            Bar::A\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derivable_impls_derive_const.stderr",
    "content": "error: this `impl` can be derived\n  --> tests/ui/derivable_impls_derive_const.rs:11:5\n   |\nLL | /     impl const Default for Foo {\nLL | |\nLL | |         fn default() -> Self {\nLL | |             Self(0)\nLL | |         }\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::derivable-impls` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::derivable_impls)]`\nhelp: replace the manual implementation with a derive attribute\n   |\nLL ~     #[derive_const(Default)]\nLL ~     struct Foo(u64);\nLL |\nLL ~     \n   |\n\nerror: this `impl` can be derived\n  --> tests/ui/derivable_impls_derive_const.rs:24:5\n   |\nLL | /     impl const Default for Bar {\nLL | |\nLL | |         fn default() -> Self {\nLL | |             Bar::A\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: replace the manual implementation with a derive attribute and mark the default variant\n   |\nLL ~     #[derive_const(Default)]\nLL ~     enum Bar {\nLL ~         #[default]\nLL ~         A,\nLL |         B,\nLL |     }\nLL |\nLL ~     \n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/derive.rs",
    "content": "#![allow(\n    clippy::non_canonical_clone_impl,\n    clippy::non_canonical_partial_ord_impl,\n    clippy::needless_lifetimes,\n    clippy::repr_packed_without_abi,\n    dead_code\n)]\n#![warn(clippy::expl_impl_clone_on_copy)]\n#![expect(incomplete_features)] // `unsafe_fields` is incomplete for the time being\n#![feature(unsafe_fields)] // `clone()` cannot be derived automatically on unsafe fields\n\n#[derive(Copy)]\nstruct Qux;\n\nimpl Clone for Qux {\n    //~^ expl_impl_clone_on_copy\n\n    fn clone(&self) -> Self {\n        Qux\n    }\n}\n\n// looks like unions don't support deriving Clone for now\n#[derive(Copy)]\nunion Union {\n    a: u8,\n}\n\nimpl Clone for Union {\n    fn clone(&self) -> Self {\n        Union { a: 42 }\n    }\n}\n\n// See #666\n#[derive(Copy)]\nstruct Lt<'a> {\n    a: &'a u8,\n}\n\nimpl<'a> Clone for Lt<'a> {\n    //~^ expl_impl_clone_on_copy\n\n    fn clone(&self) -> Self {\n        unimplemented!()\n    }\n}\n\n#[derive(Copy)]\nstruct BigArray {\n    a: [u8; 65],\n}\n\nimpl Clone for BigArray {\n    //~^ expl_impl_clone_on_copy\n\n    fn clone(&self) -> Self {\n        unimplemented!()\n    }\n}\n\n#[derive(Copy)]\nstruct FnPtr {\n    a: fn() -> !,\n}\n\nimpl Clone for FnPtr {\n    //~^ expl_impl_clone_on_copy\n\n    fn clone(&self) -> Self {\n        unimplemented!()\n    }\n}\n\n// Ok, Clone trait impl doesn't have constrained generics.\n#[derive(Copy)]\nstruct Generic<T> {\n    a: T,\n}\n\nimpl<T> Clone for Generic<T> {\n    fn clone(&self) -> Self {\n        unimplemented!()\n    }\n}\n\n#[derive(Copy)]\nstruct Generic2<T>(T);\nimpl<T: Clone> Clone for Generic2<T> {\n    //~^ expl_impl_clone_on_copy\n\n    fn clone(&self) -> Self {\n        Self(self.0.clone())\n    }\n}\n\n// Ok, Clone trait impl doesn't have constrained generics.\n#[derive(Copy)]\nstruct GenericRef<'a, T, U>(T, &'a U);\nimpl<T: Clone, U> Clone for GenericRef<'_, T, U> {\n    fn clone(&self) -> Self {\n        Self(self.0.clone(), self.1)\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/10188\n#[repr(packed)]\n#[derive(Copy)]\nstruct Packed<T>(T);\n\nimpl<T: Copy> Clone for Packed<T> {\n    fn clone(&self) -> Self {\n        *self\n    }\n}\n\nfn issue14558() {\n    pub struct Valid {\n        pub unsafe actual: (),\n    }\n\n    unsafe impl Copy for Valid {}\n\n    impl Clone for Valid {\n        #[inline]\n        fn clone(&self) -> Self {\n            *self\n        }\n    }\n}\n\nfn main() {}\n\nmod issue15708 {\n    // Check that `allow`/`expect` attributes are recognized on the type definition node\n    #[expect(clippy::expl_impl_clone_on_copy)]\n    #[derive(Copy)]\n    struct S;\n\n    impl Clone for S {\n        fn clone(&self) -> Self {\n            S\n        }\n    }\n}\n\nmod issue15842 {\n    #[derive(Copy)]\n    struct S;\n\n    // Check that `allow`/`expect` attributes are recognized on the `impl Clone` node\n    #[expect(clippy::expl_impl_clone_on_copy)]\n    impl Clone for S {\n        fn clone(&self) -> Self {\n            S\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/derive.stderr",
    "content": "error: you are implementing `Clone` explicitly on a `Copy` type\n  --> tests/ui/derive.rs:15:1\n   |\nLL | / impl Clone for Qux {\nLL | |\nLL | |\nLL | |     fn clone(&self) -> Self {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: consider deriving `Clone` or removing `Copy`\n   = note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`\n\nerror: you are implementing `Clone` explicitly on a `Copy` type\n  --> tests/ui/derive.rs:41:1\n   |\nLL | / impl<'a> Clone for Lt<'a> {\nLL | |\nLL | |\nLL | |     fn clone(&self) -> Self {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: consider deriving `Clone` or removing `Copy`\n\nerror: you are implementing `Clone` explicitly on a `Copy` type\n  --> tests/ui/derive.rs:54:1\n   |\nLL | / impl Clone for BigArray {\nLL | |\nLL | |\nLL | |     fn clone(&self) -> Self {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: consider deriving `Clone` or removing `Copy`\n\nerror: you are implementing `Clone` explicitly on a `Copy` type\n  --> tests/ui/derive.rs:67:1\n   |\nLL | / impl Clone for FnPtr {\nLL | |\nLL | |\nLL | |     fn clone(&self) -> Self {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: consider deriving `Clone` or removing `Copy`\n\nerror: you are implementing `Clone` explicitly on a `Copy` type\n  --> tests/ui/derive.rs:89:1\n   |\nLL | / impl<T: Clone> Clone for Generic2<T> {\nLL | |\nLL | |\nLL | |     fn clone(&self) -> Self {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: consider deriving `Clone` or removing `Copy`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/derive_ord_xor_partial_ord.rs",
    "content": "#![warn(clippy::derive_ord_xor_partial_ord)]\n#![allow(clippy::unnecessary_wraps)]\n#![allow(clippy::non_canonical_partial_ord_impl)]\n\nuse std::cmp::Ordering;\n\n#[derive(PartialOrd, Ord, PartialEq, Eq)]\nstruct DeriveBoth;\n\nimpl PartialEq<u64> for DeriveBoth {\n    fn eq(&self, _: &u64) -> bool {\n        true\n    }\n}\n\nimpl PartialOrd<u64> for DeriveBoth {\n    fn partial_cmp(&self, _: &u64) -> Option<Ordering> {\n        Some(Ordering::Equal)\n    }\n}\n\n#[derive(Ord, PartialEq, Eq)]\n//~^ derive_ord_xor_partial_ord\n\nstruct DeriveOrd;\n\nimpl PartialOrd for DeriveOrd {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(other.cmp(self))\n    }\n}\n\n#[derive(Ord, PartialEq, Eq)]\n//~^ derive_ord_xor_partial_ord\n\nstruct DeriveOrdWithExplicitTypeVariable;\n\nimpl PartialOrd<DeriveOrdWithExplicitTypeVariable> for DeriveOrdWithExplicitTypeVariable {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(other.cmp(self))\n    }\n}\n\n#[derive(PartialOrd, PartialEq, Eq)]\nstruct DerivePartialOrd;\n\nimpl std::cmp::Ord for DerivePartialOrd {\n    //~^ derive_ord_xor_partial_ord\n\n    fn cmp(&self, other: &Self) -> Ordering {\n        Ordering::Less\n    }\n}\n\n#[derive(PartialOrd, PartialEq, Eq)]\nstruct ImplUserOrd;\n\ntrait Ord {}\n\n// We don't want to lint on user-defined traits called `Ord`\nimpl Ord for ImplUserOrd {}\n\nmod use_ord {\n    use std::cmp::{Ord, Ordering};\n\n    #[derive(PartialOrd, PartialEq, Eq)]\n    struct DerivePartialOrdInUseOrd;\n\n    impl Ord for DerivePartialOrdInUseOrd {\n        //~^ derive_ord_xor_partial_ord\n\n        fn cmp(&self, other: &Self) -> Ordering {\n            Ordering::Less\n        }\n    }\n}\n\nfn main() {}\n\nmod issue15708 {\n    use std::cmp::{Ord, Ordering};\n\n    // Check that the lint posts on the type definition node\n    #[expect(clippy::derive_ord_xor_partial_ord)]\n    #[derive(PartialOrd, PartialEq, Eq)]\n    struct DerivePartialOrdInUseOrd;\n\n    impl Ord for DerivePartialOrdInUseOrd {\n        fn cmp(&self, other: &Self) -> Ordering {\n            Ordering::Less\n        }\n    }\n}\n\nmod issue16298 {\n    #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)]\n    struct Normalized<S>(S);\n\n    impl<S: Eq> Eq for Normalized<S> {}\n\n    #[expect(clippy::derive_ord_xor_partial_ord)]\n    impl<S: Eq + PartialOrd> Ord for Normalized<S> {\n        fn cmp(&self, other: &Self) -> std::cmp::Ordering {\n            self.partial_cmp(other).unwrap()\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/derive_ord_xor_partial_ord.stderr",
    "content": "error: you are deriving `Ord` but have implemented `PartialOrd` explicitly\n  --> tests/ui/derive_ord_xor_partial_ord.rs:22:10\n   |\nLL | #[derive(Ord, PartialEq, Eq)]\n   |          ^^^\n   |\nnote: `PartialOrd` implemented here\n  --> tests/ui/derive_ord_xor_partial_ord.rs:27:1\n   |\nLL | impl PartialOrd for DeriveOrd {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::derive-ord-xor-partial-ord` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::derive_ord_xor_partial_ord)]`\n\nerror: you are deriving `Ord` but have implemented `PartialOrd` explicitly\n  --> tests/ui/derive_ord_xor_partial_ord.rs:33:10\n   |\nLL | #[derive(Ord, PartialEq, Eq)]\n   |          ^^^\n   |\nnote: `PartialOrd` implemented here\n  --> tests/ui/derive_ord_xor_partial_ord.rs:38:1\n   |\nLL | impl PartialOrd<DeriveOrdWithExplicitTypeVariable> for DeriveOrdWithExplicitTypeVariable {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: you are implementing `Ord` explicitly but have derived `PartialOrd`\n  --> tests/ui/derive_ord_xor_partial_ord.rs:47:1\n   |\nLL | / impl std::cmp::Ord for DerivePartialOrd {\nLL | |\nLL | |\nLL | |     fn cmp(&self, other: &Self) -> Ordering {\n...  |\nLL | | }\n   | |_^\n   |\nnote: `PartialOrd` implemented here\n  --> tests/ui/derive_ord_xor_partial_ord.rs:44:10\n   |\nLL | #[derive(PartialOrd, PartialEq, Eq)]\n   |          ^^^^^^^^^^\n\nerror: you are implementing `Ord` explicitly but have derived `PartialOrd`\n  --> tests/ui/derive_ord_xor_partial_ord.rs:69:5\n   |\nLL | /     impl Ord for DerivePartialOrdInUseOrd {\nLL | |\nLL | |\nLL | |         fn cmp(&self, other: &Self) -> Ordering {\n...  |\nLL | |     }\n   | |_____^\n   |\nnote: `PartialOrd` implemented here\n  --> tests/ui/derive_ord_xor_partial_ord.rs:66:14\n   |\nLL |     #[derive(PartialOrd, PartialEq, Eq)]\n   |              ^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/derive_partial_eq_without_eq.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::derive_partial_eq_without_eq)]\n\n// Don't warn on structs that aren't PartialEq\npub struct NotPartialEq {\n    foo: u32,\n    bar: String,\n}\n\n// Eq can be derived but is missing\n#[derive(Debug, PartialEq, Eq)]\n//~^ derive_partial_eq_without_eq\npub struct MissingEq {\n    foo: u32,\n    bar: String,\n}\n\n// Check that we honor the `allow` attribute\n#[allow(clippy::derive_partial_eq_without_eq)]\n#[derive(Debug, PartialEq)]\npub struct AllowedMissingEq {\n    foo: u32,\n    bar: String,\n}\n\n// Check that we honor the `expect` attribute\n#[expect(clippy::derive_partial_eq_without_eq)]\n#[derive(Debug, PartialEq)]\npub struct ExpectedMissingEq {\n    foo: u32,\n    bar: String,\n}\n\n// Eq is derived\n#[derive(PartialEq, Eq)]\npub struct NotMissingEq {\n    foo: u32,\n    bar: String,\n}\n\n// Eq is manually implemented\n#[derive(PartialEq)]\npub struct ManualEqImpl {\n    foo: u32,\n    bar: String,\n}\n\nimpl Eq for ManualEqImpl {}\n\n// Cannot be Eq because f32 isn't Eq\n#[derive(PartialEq)]\npub struct CannotBeEq {\n    foo: u32,\n    bar: f32,\n}\n\n// Don't warn if PartialEq is manually implemented\npub struct ManualPartialEqImpl {\n    foo: u32,\n    bar: String,\n}\n\nimpl PartialEq for ManualPartialEqImpl {\n    fn eq(&self, other: &Self) -> bool {\n        self.foo == other.foo && self.bar == other.bar\n    }\n}\n\n// Generic fields should be properly checked for Eq-ness\n#[derive(PartialEq, Eq)]\n//~^ derive_partial_eq_without_eq\npub struct GenericNotEq<T: Eq, U: PartialEq> {\n    foo: T,\n    bar: U,\n}\n\n#[derive(PartialEq, Eq)]\n//~^ derive_partial_eq_without_eq\npub struct GenericEq<T: Eq, U: Eq> {\n    foo: T,\n    bar: U,\n}\n\n#[derive(PartialEq, Eq)]\n//~^ derive_partial_eq_without_eq\npub struct TupleStruct(u32);\n\n#[derive(PartialEq, Eq)]\n//~^ derive_partial_eq_without_eq\npub struct GenericTupleStruct<T: Eq>(T);\n\n#[derive(PartialEq)]\npub struct TupleStructNotEq(f32);\n\n#[derive(PartialEq, Eq)]\n//~^ derive_partial_eq_without_eq\npub enum Enum {\n    Foo(u32),\n    Bar { a: String, b: () },\n}\n\n#[derive(PartialEq, Eq)]\n//~^ derive_partial_eq_without_eq\npub enum GenericEnum<T: Eq, U: Eq, V: Eq> {\n    Foo(T),\n    Bar { a: U, b: V },\n}\n\n#[derive(PartialEq)]\npub enum EnumNotEq {\n    Foo(u32),\n    Bar { a: String, b: f32 },\n}\n\n// Ensure that rustfix works properly when `PartialEq` has other derives on either side\n#[derive(Debug, PartialEq, Eq, Clone)]\n//~^ derive_partial_eq_without_eq\npub struct RustFixWithOtherDerives;\n\n#[derive(PartialEq, Eq)]\n//~^ derive_partial_eq_without_eq\npub struct Generic<T>(T);\n\n#[derive(PartialEq, Eq)]\npub struct GenericPhantom<T>(core::marker::PhantomData<T>);\n\nmod _hidden {\n    #[derive(PartialEq, Eq)]\n    //~^ derive_partial_eq_without_eq\n    pub struct Reexported;\n\n    #[derive(PartialEq, Eq)]\n    //~^ derive_partial_eq_without_eq\n    pub struct InPubFn;\n\n    #[derive(PartialEq)]\n    pub(crate) struct PubCrate;\n\n    #[derive(PartialEq)]\n    pub(super) struct PubSuper;\n}\n\npub use _hidden::Reexported;\npub fn _from_mod() -> _hidden::InPubFn {\n    _hidden::InPubFn\n}\n\n#[derive(PartialEq)]\nstruct InternalTy;\n\n// This is a `non_exhaustive` type so should not warn.\n#[derive(Debug, PartialEq)]\n#[non_exhaustive]\npub struct MissingEqNonExhaustive {\n    foo: u32,\n    bar: String,\n}\n\n// This is a `non_exhaustive` type so should not warn.\n#[derive(Debug, PartialEq)]\npub struct MissingEqNonExhaustive1 {\n    foo: u32,\n    #[non_exhaustive]\n    bar: String,\n}\n\n// This is a `non_exhaustive` type so should not warn.\n#[derive(Debug, PartialEq)]\n#[non_exhaustive]\npub enum MissingEqNonExhaustive2 {\n    Foo,\n    Bar,\n}\n\n// This is a `non_exhaustive` type so should not warn.\n#[derive(Debug, PartialEq)]\npub enum MissingEqNonExhaustive3 {\n    Foo,\n    #[non_exhaustive]\n    Bar,\n}\n\nmod struct_gen {\n    // issue 9413\n    pub trait Group {\n        type Element: Eq + PartialEq;\n    }\n\n    pub trait Suite {\n        type Group: Group;\n    }\n\n    #[derive(PartialEq, Eq)]\n    //~^ derive_partial_eq_without_eq\n\n    pub struct Foo<C: Suite>(<C::Group as Group>::Element);\n\n    #[derive(PartialEq, Eq)]\n    pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);\n\n    // issue 9319\n    #[derive(PartialEq, Eq)]\n    //~^ derive_partial_eq_without_eq\n\n    pub struct Oof<T: Fn()>(T);\n\n    #[derive(PartialEq, Eq)]\n    pub struct Rab<T: Fn()>(T);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_partial_eq_without_eq.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::derive_partial_eq_without_eq)]\n\n// Don't warn on structs that aren't PartialEq\npub struct NotPartialEq {\n    foo: u32,\n    bar: String,\n}\n\n// Eq can be derived but is missing\n#[derive(Debug, PartialEq)]\n//~^ derive_partial_eq_without_eq\npub struct MissingEq {\n    foo: u32,\n    bar: String,\n}\n\n// Check that we honor the `allow` attribute\n#[allow(clippy::derive_partial_eq_without_eq)]\n#[derive(Debug, PartialEq)]\npub struct AllowedMissingEq {\n    foo: u32,\n    bar: String,\n}\n\n// Check that we honor the `expect` attribute\n#[expect(clippy::derive_partial_eq_without_eq)]\n#[derive(Debug, PartialEq)]\npub struct ExpectedMissingEq {\n    foo: u32,\n    bar: String,\n}\n\n// Eq is derived\n#[derive(PartialEq, Eq)]\npub struct NotMissingEq {\n    foo: u32,\n    bar: String,\n}\n\n// Eq is manually implemented\n#[derive(PartialEq)]\npub struct ManualEqImpl {\n    foo: u32,\n    bar: String,\n}\n\nimpl Eq for ManualEqImpl {}\n\n// Cannot be Eq because f32 isn't Eq\n#[derive(PartialEq)]\npub struct CannotBeEq {\n    foo: u32,\n    bar: f32,\n}\n\n// Don't warn if PartialEq is manually implemented\npub struct ManualPartialEqImpl {\n    foo: u32,\n    bar: String,\n}\n\nimpl PartialEq for ManualPartialEqImpl {\n    fn eq(&self, other: &Self) -> bool {\n        self.foo == other.foo && self.bar == other.bar\n    }\n}\n\n// Generic fields should be properly checked for Eq-ness\n#[derive(PartialEq)]\n//~^ derive_partial_eq_without_eq\npub struct GenericNotEq<T: Eq, U: PartialEq> {\n    foo: T,\n    bar: U,\n}\n\n#[derive(PartialEq)]\n//~^ derive_partial_eq_without_eq\npub struct GenericEq<T: Eq, U: Eq> {\n    foo: T,\n    bar: U,\n}\n\n#[derive(PartialEq)]\n//~^ derive_partial_eq_without_eq\npub struct TupleStruct(u32);\n\n#[derive(PartialEq)]\n//~^ derive_partial_eq_without_eq\npub struct GenericTupleStruct<T: Eq>(T);\n\n#[derive(PartialEq)]\npub struct TupleStructNotEq(f32);\n\n#[derive(PartialEq)]\n//~^ derive_partial_eq_without_eq\npub enum Enum {\n    Foo(u32),\n    Bar { a: String, b: () },\n}\n\n#[derive(PartialEq)]\n//~^ derive_partial_eq_without_eq\npub enum GenericEnum<T: Eq, U: Eq, V: Eq> {\n    Foo(T),\n    Bar { a: U, b: V },\n}\n\n#[derive(PartialEq)]\npub enum EnumNotEq {\n    Foo(u32),\n    Bar { a: String, b: f32 },\n}\n\n// Ensure that rustfix works properly when `PartialEq` has other derives on either side\n#[derive(Debug, PartialEq, Clone)]\n//~^ derive_partial_eq_without_eq\npub struct RustFixWithOtherDerives;\n\n#[derive(PartialEq)]\n//~^ derive_partial_eq_without_eq\npub struct Generic<T>(T);\n\n#[derive(PartialEq, Eq)]\npub struct GenericPhantom<T>(core::marker::PhantomData<T>);\n\nmod _hidden {\n    #[derive(PartialEq)]\n    //~^ derive_partial_eq_without_eq\n    pub struct Reexported;\n\n    #[derive(PartialEq)]\n    //~^ derive_partial_eq_without_eq\n    pub struct InPubFn;\n\n    #[derive(PartialEq)]\n    pub(crate) struct PubCrate;\n\n    #[derive(PartialEq)]\n    pub(super) struct PubSuper;\n}\n\npub use _hidden::Reexported;\npub fn _from_mod() -> _hidden::InPubFn {\n    _hidden::InPubFn\n}\n\n#[derive(PartialEq)]\nstruct InternalTy;\n\n// This is a `non_exhaustive` type so should not warn.\n#[derive(Debug, PartialEq)]\n#[non_exhaustive]\npub struct MissingEqNonExhaustive {\n    foo: u32,\n    bar: String,\n}\n\n// This is a `non_exhaustive` type so should not warn.\n#[derive(Debug, PartialEq)]\npub struct MissingEqNonExhaustive1 {\n    foo: u32,\n    #[non_exhaustive]\n    bar: String,\n}\n\n// This is a `non_exhaustive` type so should not warn.\n#[derive(Debug, PartialEq)]\n#[non_exhaustive]\npub enum MissingEqNonExhaustive2 {\n    Foo,\n    Bar,\n}\n\n// This is a `non_exhaustive` type so should not warn.\n#[derive(Debug, PartialEq)]\npub enum MissingEqNonExhaustive3 {\n    Foo,\n    #[non_exhaustive]\n    Bar,\n}\n\nmod struct_gen {\n    // issue 9413\n    pub trait Group {\n        type Element: Eq + PartialEq;\n    }\n\n    pub trait Suite {\n        type Group: Group;\n    }\n\n    #[derive(PartialEq)]\n    //~^ derive_partial_eq_without_eq\n\n    pub struct Foo<C: Suite>(<C::Group as Group>::Element);\n\n    #[derive(PartialEq, Eq)]\n    pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);\n\n    // issue 9319\n    #[derive(PartialEq)]\n    //~^ derive_partial_eq_without_eq\n\n    pub struct Oof<T: Fn()>(T);\n\n    #[derive(PartialEq, Eq)]\n    pub struct Rab<T: Fn()>(T);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/derive_partial_eq_without_eq.stderr",
    "content": "error: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:11:17\n   |\nLL | #[derive(Debug, PartialEq)]\n   |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n   |\n   = note: `-D clippy::derive-partial-eq-without-eq` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::derive_partial_eq_without_eq)]`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:70:10\n   |\nLL | #[derive(PartialEq)]\n   |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:77:10\n   |\nLL | #[derive(PartialEq)]\n   |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:84:10\n   |\nLL | #[derive(PartialEq)]\n   |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:88:10\n   |\nLL | #[derive(PartialEq)]\n   |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:95:10\n   |\nLL | #[derive(PartialEq)]\n   |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:102:10\n   |\nLL | #[derive(PartialEq)]\n   |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:116:17\n   |\nLL | #[derive(Debug, PartialEq, Clone)]\n   |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:120:10\n   |\nLL | #[derive(PartialEq)]\n   |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:128:14\n   |\nLL |     #[derive(PartialEq)]\n   |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:132:14\n   |\nLL |     #[derive(PartialEq)]\n   |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:193:14\n   |\nLL |     #[derive(PartialEq)]\n   |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: you are deriving `PartialEq` and can implement `Eq`\n  --> tests/ui/derive_partial_eq_without_eq.rs:202:14\n   |\nLL |     #[derive(PartialEq)]\n   |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/derived_hash_with_manual_eq.rs",
    "content": "#![allow(clippy::derive_partial_eq_without_eq)]\n\n#[derive(PartialEq, Hash)]\nstruct Foo;\n\nimpl PartialEq<u64> for Foo {\n    fn eq(&self, _: &u64) -> bool {\n        true\n    }\n}\n\n#[derive(Hash)]\n//~^ derived_hash_with_manual_eq\n\nstruct Bar;\n\nimpl PartialEq for Bar {\n    fn eq(&self, _: &Bar) -> bool {\n        true\n    }\n}\n\n#[derive(Hash)]\n//~^ derived_hash_with_manual_eq\n\nstruct Baz;\n\nimpl PartialEq<Baz> for Baz {\n    fn eq(&self, _: &Baz) -> bool {\n        true\n    }\n}\n\n// Implementing `Hash` with a derived `PartialEq` is fine. See #2627\n\n#[derive(PartialEq)]\nstruct Bah;\n\nimpl std::hash::Hash for Bah {\n    fn hash<H: std::hash::Hasher>(&self, _: &mut H) {}\n}\n\nfn main() {}\n\nmod issue15708 {\n    // Check that the lint posts on the type definition node\n    #[expect(clippy::derived_hash_with_manual_eq)]\n    #[derive(Debug, Clone, Copy, Eq, PartialOrd, Ord, Hash)]\n    pub struct Span {\n        start: usize,\n        end: usize,\n    }\n\n    impl PartialEq for Span {\n        fn eq(&self, other: &Self) -> bool {\n            self.start.cmp(&other.start).then(self.end.cmp(&other.end)).is_eq()\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/derived_hash_with_manual_eq.stderr",
    "content": "error: you are deriving `Hash` but have implemented `PartialEq` explicitly\n  --> tests/ui/derived_hash_with_manual_eq.rs:12:10\n   |\nLL | #[derive(Hash)]\n   |          ^^^^\n   |\nnote: `PartialEq` implemented here\n  --> tests/ui/derived_hash_with_manual_eq.rs:17:1\n   |\nLL | impl PartialEq for Bar {\n   | ^^^^^^^^^^^^^^^^^^^^^^\n   = note: `#[deny(clippy::derived_hash_with_manual_eq)]` on by default\n\nerror: you are deriving `Hash` but have implemented `PartialEq` explicitly\n  --> tests/ui/derived_hash_with_manual_eq.rs:23:10\n   |\nLL | #[derive(Hash)]\n   |          ^^^^\n   |\nnote: `PartialEq` implemented here\n  --> tests/ui/derived_hash_with_manual_eq.rs:28:1\n   |\nLL | impl PartialEq<Baz> for Baz {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/disallowed_names.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    dead_code,\n    clippy::needless_ifs,\n    clippy::similar_names,\n    clippy::single_match,\n    clippy::toplevel_ref_arg,\n    unused_mut,\n    unused_variables\n)]\n#![warn(clippy::disallowed_names)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nfn test(foo: ()) {}\n//~^ disallowed_names\n\nfn main() {\n    let foo = 42;\n    //~^ disallowed_names\n\n    let baz = 42;\n    //~^ disallowed_names\n\n    let quux = 42;\n    //~^ disallowed_names\n\n    // Unlike these others, `bar` is actually considered an acceptable name.\n    // Among many other legitimate uses, bar commonly refers to a period of time in music.\n    // See https://github.com/rust-lang/rust-clippy/issues/5225.\n    let bar = 42;\n\n    let food = 42;\n    let foodstuffs = 42;\n    let bazaar = 42;\n\n    match (42, Some(1337), Some(0)) {\n        (foo, Some(baz), quux @ Some(_)) => (),\n        //~^ disallowed_names\n        //~| disallowed_names\n        //~| disallowed_names\n        _ => (),\n    }\n}\n\nfn issue_1647(mut foo: u8) {\n    //~^ disallowed_names\n\n    let mut baz = 0;\n    //~^ disallowed_names\n\n    if let Some(mut quux) = Some(42) {}\n    //~^ disallowed_names\n}\n\nfn issue_1647_ref() {\n    let ref baz = 0;\n    //~^ disallowed_names\n\n    if let Some(ref quux) = Some(42) {}\n    //~^ disallowed_names\n}\n\nfn issue_1647_ref_mut() {\n    let ref mut baz = 0;\n    //~^ disallowed_names\n\n    if let Some(ref mut quux) = Some(42) {}\n    //~^ disallowed_names\n}\n\npub fn issue_14958_proc_macro() {\n    // does not lint macro-generated code\n    external! {\n        let foo = 0;\n    }\n    with_span! {\n        span\n        let foo = 0;\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    fn issue_7305() {\n        // `disallowed_names` lint should not be triggered inside of the test code.\n        let foo = 0;\n\n        // Check that even in nested functions warning is still not triggered.\n        fn nested() {\n            let foo = 0;\n        }\n    }\n}\n\n#[test]\nfn test_with_disallowed_name() {\n    let foo = 0;\n}\n"
  },
  {
    "path": "tests/ui/disallowed_names.stderr",
    "content": "error: use of a disallowed/placeholder name `foo`\n  --> tests/ui/disallowed_names.rs:16:9\n   |\nLL | fn test(foo: ()) {}\n   |         ^^^\n   |\n   = note: `-D clippy::disallowed-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]`\n\nerror: use of a disallowed/placeholder name `foo`\n  --> tests/ui/disallowed_names.rs:20:9\n   |\nLL |     let foo = 42;\n   |         ^^^\n\nerror: use of a disallowed/placeholder name `baz`\n  --> tests/ui/disallowed_names.rs:23:9\n   |\nLL |     let baz = 42;\n   |         ^^^\n\nerror: use of a disallowed/placeholder name `quux`\n  --> tests/ui/disallowed_names.rs:26:9\n   |\nLL |     let quux = 42;\n   |         ^^^^\n\nerror: use of a disallowed/placeholder name `foo`\n  --> tests/ui/disallowed_names.rs:39:10\n   |\nLL |         (foo, Some(baz), quux @ Some(_)) => (),\n   |          ^^^\n\nerror: use of a disallowed/placeholder name `baz`\n  --> tests/ui/disallowed_names.rs:39:20\n   |\nLL |         (foo, Some(baz), quux @ Some(_)) => (),\n   |                    ^^^\n\nerror: use of a disallowed/placeholder name `quux`\n  --> tests/ui/disallowed_names.rs:39:26\n   |\nLL |         (foo, Some(baz), quux @ Some(_)) => (),\n   |                          ^^^^\n\nerror: use of a disallowed/placeholder name `foo`\n  --> tests/ui/disallowed_names.rs:47:19\n   |\nLL | fn issue_1647(mut foo: u8) {\n   |                   ^^^\n\nerror: use of a disallowed/placeholder name `baz`\n  --> tests/ui/disallowed_names.rs:50:13\n   |\nLL |     let mut baz = 0;\n   |             ^^^\n\nerror: use of a disallowed/placeholder name `quux`\n  --> tests/ui/disallowed_names.rs:53:21\n   |\nLL |     if let Some(mut quux) = Some(42) {}\n   |                     ^^^^\n\nerror: use of a disallowed/placeholder name `baz`\n  --> tests/ui/disallowed_names.rs:58:13\n   |\nLL |     let ref baz = 0;\n   |             ^^^\n\nerror: use of a disallowed/placeholder name `quux`\n  --> tests/ui/disallowed_names.rs:61:21\n   |\nLL |     if let Some(ref quux) = Some(42) {}\n   |                     ^^^^\n\nerror: use of a disallowed/placeholder name `baz`\n  --> tests/ui/disallowed_names.rs:66:17\n   |\nLL |     let ref mut baz = 0;\n   |                 ^^^\n\nerror: use of a disallowed/placeholder name `quux`\n  --> tests/ui/disallowed_names.rs:69:25\n   |\nLL |     if let Some(ref mut quux) = Some(42) {}\n   |                         ^^^^\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/disallowed_script_idents.rs",
    "content": "#![deny(clippy::disallowed_script_idents)]\n#![allow(dead_code)]\n\nfn main() {\n    // OK, latin is allowed.\n    let counter = 10;\n    // OK, it's still latin.\n    let zähler = 10;\n\n    // Cyrillic is not allowed by default.\n    let счётчик = 10;\n    //~^ disallowed_script_idents\n\n    // Same for japanese.\n    let カウンタ = 10;\n    //~^ disallowed_script_idents\n}\n\nfn issue15116() {\n    const ÄÖÜ: u8 = 0;\n    const _ÄÖÜ: u8 = 0;\n    const Ä_ÖÜ: u8 = 0;\n    const ÄÖ_Ü: u8 = 0;\n    const ÄÖÜ_: u8 = 0;\n    let äöüß = 1;\n    let _äöüß = 1;\n    let ä_öüß = 1;\n    let äö_üß = 1;\n    let äöü_ß = 1;\n    let äöüß_ = 1;\n}\n"
  },
  {
    "path": "tests/ui/disallowed_script_idents.stderr",
    "content": "error: identifier `счётчик` has a Unicode script that is not allowed by configuration: Cyrillic\n  --> tests/ui/disallowed_script_idents.rs:11:9\n   |\nLL |     let счётчик = 10;\n   |         ^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/disallowed_script_idents.rs:1:9\n   |\nLL | #![deny(clippy::disallowed_script_idents)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: identifier `カウンタ` has a Unicode script that is not allowed by configuration: Katakana\n  --> tests/ui/disallowed_script_idents.rs:15:9\n   |\nLL |     let カウンタ = 10;\n   |         ^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/diverging_sub_expression.rs",
    "content": "#![warn(clippy::diverging_sub_expression)]\n#![allow(clippy::match_same_arms, clippy::overly_complex_bool_expr)]\n#![allow(clippy::nonminimal_bool)]\n#[allow(clippy::empty_loop)]\nfn diverge() -> ! {\n    loop {}\n}\n\nstruct A;\n\nimpl A {\n    fn foo(&self) -> ! {\n        diverge()\n    }\n}\n\n#[allow(unused_variables, clippy::unnecessary_operation, clippy::short_circuit_statement)]\nfn main() {\n    let b = true;\n    b || diverge();\n    //~^ diverging_sub_expression\n\n    b || A.foo();\n    //~^ diverging_sub_expression\n}\n\n#[allow(dead_code, unused_variables)]\n#[rustfmt::skip]\nfn foobar() {\n    loop {\n        let x = match 5 {\n            4 => return,\n            5 => continue,\n            6 => true || return,\n            //~^ diverging_sub_expression\n\n            7 => true || continue,\n            //~^ diverging_sub_expression\n\n            8 => break,\n            9 => diverge(),\n            3 => true || diverge(),\n            //~^ diverging_sub_expression\n\n            10 => match 42 {\n                99 => return,\n                _ => true || panic!(\"boo\"),\n                //~^ diverging_sub_expression\n\n            },\n            // lint blocks as well\n            15 => true || { return; },\n            //~^ diverging_sub_expression\n\n            16 => false || { return; },\n            //~^ diverging_sub_expression\n\n            // ... and when it's a single expression\n            17 => true || { return },\n            //~^ diverging_sub_expression\n\n            18 => false || { return },\n            //~^ diverging_sub_expression\n\n            // ... but not when there's both an expression and a statement\n            19 => true || { _ = 1; return },\n            20 => false || { _ = 1; return },\n            // ... or multiple statements\n            21 => true || { _ = 1; return; },\n            22 => false || { _ = 1; return; },\n            23 => true || { return; true },\n            24 => true || { return; true },\n            _ => true || break,\n            //~^ diverging_sub_expression\n\n        };\n    }\n}\n\n#[allow(unused)]\nfn ignore_todo() {\n    let x: u32 = todo!();\n    println!(\"{x}\");\n}\n"
  },
  {
    "path": "tests/ui/diverging_sub_expression.stderr",
    "content": "error: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:20:10\n   |\nLL |     b || diverge();\n   |          ^^^^^^^^^\n   |\n   = note: `-D clippy::diverging-sub-expression` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]`\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:23:10\n   |\nLL |     b || A.foo();\n   |          ^^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:34:26\n   |\nLL |             6 => true || return,\n   |                          ^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:37:26\n   |\nLL |             7 => true || continue,\n   |                          ^^^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:42:26\n   |\nLL |             3 => true || diverge(),\n   |                          ^^^^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:47:30\n   |\nLL |                 _ => true || panic!(\"boo\"),\n   |                              ^^^^^^^^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:52:29\n   |\nLL |             15 => true || { return; },\n   |                             ^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:55:30\n   |\nLL |             16 => false || { return; },\n   |                              ^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:59:29\n   |\nLL |             17 => true || { return },\n   |                             ^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:62:30\n   |\nLL |             18 => false || { return },\n   |                              ^^^^^^\n\nerror: sub-expression diverges\n  --> tests/ui/diverging_sub_expression.rs:73:26\n   |\nLL |             _ => true || break,\n   |                          ^^^^^\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc-fixable.fixed",
    "content": "//! This file tests for the `DOC_MARKDOWN` lint.\n\n#![allow(dead_code, incomplete_features)]\n#![warn(clippy::doc_markdown)]\n#![feature(custom_inner_attributes, generic_const_exprs)]\n#![rustfmt::skip]\n\n/// The `foo_bar` function does _nothing_. See also `foo::bar`. (note the dot there)\n//~^ doc_markdown\n//~| doc_markdown\n/// Markdown is _weird_. I mean _really weird_. This \\_ is ok. So is `_`. But not `Foo::some_fun`\n//~^ doc_markdown\n/// which should be reported only once despite being __doubly bad__.\n/// Here be `::a::global:path`, and _`::another::global::path`_.  :: is not a path though.\n//~^ doc_markdown\n//~| doc_markdown\n/// Import an item from `::awesome::global::blob::` (Intended postfix)\n//~^ doc_markdown\n/// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted)\n//~^ doc_markdown\n/// That's not code ~`NotInCodeBlock`~.\n//~^ doc_markdown\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn foo_bar() {\n}\n\n/// That one tests multiline ticks.\n/// ```rust\n/// foo_bar FOO_BAR\n/// _foo bar_\n/// ```\n///\n/// ~~~rust\n/// foo_bar FOO_BAR\n/// _foo bar_\n/// ~~~\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn multiline_codeblock() {\n}\n\n/// This _is a test for\n/// multiline\n/// emphasis_.\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn test_emphasis() {\n}\n\n/// This tests units. See also #835.\n/// kiB MiB GiB TiB PiB EiB\n/// kib Mib Gib Tib Pib Eib\n/// kB MB GB TB PB EB\n/// kb Mb Gb Tb Pb Eb\n/// 32kiB 32MiB 32GiB 32TiB 32PiB 32EiB\n/// 32kib 32Mib 32Gib 32Tib 32Pib 32Eib\n/// 32kB 32MB 32GB 32TB 32PB 32EB\n/// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb\n/// NaN\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn test_units() {\n}\n\n/// This tests allowed identifiers.\n/// KiB MiB GiB TiB PiB EiB\n/// MHz GHz THz\n/// AccessKit\n/// CoAP CoreFoundation CoreGraphics CoreText\n/// Direct2D Direct3D DirectWrite DirectX\n/// ECMAScript\n/// GPLv2 GPLv3\n/// GitHub GitLab\n/// IPv4 IPv6\n/// InfiniBand RoCE\n/// ClojureScript CoffeeScript JavaScript PostScript PureScript TypeScript\n/// PowerPC PowerShell WebAssembly\n/// NaN NaNs\n/// OAuth GraphQL\n/// OCaml\n/// OpenAL OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry\n/// OpenType\n/// WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport\n/// TensorFlow\n/// TrueType\n/// iOS macOS FreeBSD NetBSD OpenBSD NixOS\n/// TeX LaTeX BibTeX BibLaTeX\n/// MinGW\n/// CamelCase (see also #2395)\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn test_allowed() {\n}\n\n/// This test has [a `link_with_underscores`][chunked-example] inside it. See #823.\n/// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues)\n/// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link].\n/// It can also be [inline_link2]. A link to [StackOverflow](https://stackoverflow.com) is also acceptable.\n///\n/// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example\n/// [inline_link]: https://foobar\n/// [inline_link2]: https://foobar\n/// The `main` function is the entry point of the program. Here it only calls the `foo_bar` and\n/// `multiline_ticks` functions.\n///\n/// expression of the type  `_ <bit_op> m <cmp_op> c` (where `<bit_op>`\n/// is one of {`&`, '|'} and `<cmp_op>` is one of {`!=`, `>=`, `>` ,\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn main() {\n}\n\n/// ## `CamelCaseThing`\n//~^ doc_markdown\n/// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897.\n///\n/// # `CamelCaseThing`\n//~^ doc_markdown\n///\n/// Not a title #897 `CamelCaseThing`\n//~^ doc_markdown\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn issue897() {\n}\n\n/// I am confused by brackets? (`x_y`)\n/// I am confused by brackets? (foo `x_y`)\n/// I am confused by brackets? (`x_y` foo)\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn issue900() {\n}\n\n/// Diesel queries also have a similar problem to [Iterator][iterator], where\n/// /// More talking\n/// returning them from a function requires exposing the implementation of that\n/// function. The [`helper_types`][helper_types] module exists to help with this,\n/// but you might want to hide the return type or have it conditionally change.\n/// Boxing can achieve both.\n///\n/// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html\n/// [helper_types]: ../helper_types/index.html\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn issue883() {\n}\n\n/// `foo_bar\n/// baz_quz`\n/// [foo\n/// bar](https://doc.rust-lang.org/stable/std/iter/trait.IteratorFooBar.html)\nfn multiline() {\n}\n\n/** E.g., serialization of an empty list: `FooBar`\n```\nThat's in a code block: `PackedNode`\n```\n\nAnd `BarQuz` too.\n`be_sure_we_got_to_the_end_of_it`\n*/\n//~^^^ doc_markdown\n//~^^^ doc_markdown\n//~^^^^^^^^^^ doc_markdown\nfn issue1073() {\n}\n\n/** E.g., serialization of an empty list: `FooBar`\n```\nThat's in a code block: PackedNode\n```\n\nAnd `BarQuz` too.\n`be_sure_we_got_to_the_end_of_it`\n*/\n//~^^ doc_markdown\n//~^^^^ doc_markdown\n//~^^^^^^^^^^ doc_markdown\nfn issue1073_alt() {\n}\n\n/// Tests more than three quotes:\n/// ````\n/// DoNotWarn\n/// ```\n/// StillDont\n/// ````\n/// `be_sure_we_got_to_the_end_of_it`\n//~^ doc_markdown\nfn four_quotes() {\n}\n\n#[cfg_attr(feature = \"a\", doc = \" ```\")]\n#[cfg_attr(not(feature = \"a\"), doc = \" ```ignore\")]\n/// fn main() {\n///     let s = \"localhost:10000\".to_string();\n///     println!(\"{}\", s);\n/// }\n/// ```\nfn issue_1469() {}\n\n/**\n * This is a doc comment that should not be a list\n *This would also be an error under a strict common mark interpretation\n */\nfn issue_1920() {}\n\n/// An iterator over `mycrate::Collection`'s values.\n//~^ doc_markdown\n/// It should not lint a `'static` lifetime in ticks.\nfn issue_2210() {}\n\n/// This should not cause the lint to trigger:\n/// #REQ-data-family.lint_partof_exists\nfn issue_2343() {}\n\n/// This should not cause an ICE:\n/// __|_ _|__||_|\nfn pulldown_cmark_crash() {}\n\n/// This should not lint\n/// (regression test for #7758)\n/// [plain text][path::to::item]\nfn intra_doc_link() {}\n\n/// Ignore escaped\\_underscores\n///\n/// \\\\[\n///     \\\\prod\\_{x\\\\in X} p\\_x\n/// \\\\]\nfn issue_2581() {}\n\n/// Foo \\[bar\\] \\[baz\\] \\[qux\\]. `DocMarkdownLint`\n//~^ doc_markdown\nfn lint_after_escaped_chars() {}\n\n// issue #7033 - generic_const_exprs ICE\nstruct S<T, const N: usize>\nwhere [(); N.checked_next_power_of_two().unwrap()]: {\n    arr: [T; N.checked_next_power_of_two().unwrap()],\n    n: usize,\n}\n\nimpl<T: Copy + Default, const N: usize> S<T, N>\nwhere [(); N.checked_next_power_of_two().unwrap()]: {\n    fn new() -> Self {\n        Self {\n            arr: [T::default(); N.checked_next_power_of_two().unwrap()],\n            n: 0,\n        }\n    }\n}\n\n/// this checks if the lowerCamelCase issue is fixed\nfn issue_11568() {}\n\n/// There is no try (`do()` or `do_not()`).\n//~^ doc_markdown\n//~| doc_markdown\nfn parenthesized_word() {}\n\n/// `ABes`\n//~^ doc_markdown\n/// OSes\n/// UXes\nfn plural_acronym_test() {}\n\nunsafe extern \"C\" {\n    /// `foo()`\n    //~^ doc_markdown\n    fn in_extern();\n}\n\n/// <https://github.com/rust-lang/rust-clippy/pull/12836>\n//~^ doc_markdown\nfn check_autofix_for_base_urls() {}\n"
  },
  {
    "path": "tests/ui/doc/doc-fixable.rs",
    "content": "//! This file tests for the `DOC_MARKDOWN` lint.\n\n#![allow(dead_code, incomplete_features)]\n#![warn(clippy::doc_markdown)]\n#![feature(custom_inner_attributes, generic_const_exprs)]\n#![rustfmt::skip]\n\n/// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)\n//~^ doc_markdown\n//~| doc_markdown\n/// Markdown is _weird_. I mean _really weird_. This \\_ is ok. So is `_`. But not Foo::some_fun\n//~^ doc_markdown\n/// which should be reported only once despite being __doubly bad__.\n/// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.\n//~^ doc_markdown\n//~| doc_markdown\n/// Import an item from ::awesome::global::blob:: (Intended postfix)\n//~^ doc_markdown\n/// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted)\n//~^ doc_markdown\n/// That's not code ~NotInCodeBlock~.\n//~^ doc_markdown\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn foo_bar() {\n}\n\n/// That one tests multiline ticks.\n/// ```rust\n/// foo_bar FOO_BAR\n/// _foo bar_\n/// ```\n///\n/// ~~~rust\n/// foo_bar FOO_BAR\n/// _foo bar_\n/// ~~~\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn multiline_codeblock() {\n}\n\n/// This _is a test for\n/// multiline\n/// emphasis_.\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn test_emphasis() {\n}\n\n/// This tests units. See also #835.\n/// kiB MiB GiB TiB PiB EiB\n/// kib Mib Gib Tib Pib Eib\n/// kB MB GB TB PB EB\n/// kb Mb Gb Tb Pb Eb\n/// 32kiB 32MiB 32GiB 32TiB 32PiB 32EiB\n/// 32kib 32Mib 32Gib 32Tib 32Pib 32Eib\n/// 32kB 32MB 32GB 32TB 32PB 32EB\n/// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb\n/// NaN\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn test_units() {\n}\n\n/// This tests allowed identifiers.\n/// KiB MiB GiB TiB PiB EiB\n/// MHz GHz THz\n/// AccessKit\n/// CoAP CoreFoundation CoreGraphics CoreText\n/// Direct2D Direct3D DirectWrite DirectX\n/// ECMAScript\n/// GPLv2 GPLv3\n/// GitHub GitLab\n/// IPv4 IPv6\n/// InfiniBand RoCE\n/// ClojureScript CoffeeScript JavaScript PostScript PureScript TypeScript\n/// PowerPC PowerShell WebAssembly\n/// NaN NaNs\n/// OAuth GraphQL\n/// OCaml\n/// OpenAL OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry\n/// OpenType\n/// WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport\n/// TensorFlow\n/// TrueType\n/// iOS macOS FreeBSD NetBSD OpenBSD NixOS\n/// TeX LaTeX BibTeX BibLaTeX\n/// MinGW\n/// CamelCase (see also #2395)\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn test_allowed() {\n}\n\n/// This test has [a `link_with_underscores`][chunked-example] inside it. See #823.\n/// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues)\n/// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link].\n/// It can also be [inline_link2]. A link to [StackOverflow](https://stackoverflow.com) is also acceptable.\n///\n/// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example\n/// [inline_link]: https://foobar\n/// [inline_link2]: https://foobar\n/// The `main` function is the entry point of the program. Here it only calls the `foo_bar` and\n/// `multiline_ticks` functions.\n///\n/// expression of the type  `_ <bit_op> m <cmp_op> c` (where `<bit_op>`\n/// is one of {`&`, '|'} and `<cmp_op>` is one of {`!=`, `>=`, `>` ,\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn main() {\n}\n\n/// ## CamelCaseThing\n//~^ doc_markdown\n/// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897.\n///\n/// # CamelCaseThing\n//~^ doc_markdown\n///\n/// Not a title #897 CamelCaseThing\n//~^ doc_markdown\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn issue897() {\n}\n\n/// I am confused by brackets? (`x_y`)\n/// I am confused by brackets? (foo `x_y`)\n/// I am confused by brackets? (`x_y` foo)\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn issue900() {\n}\n\n/// Diesel queries also have a similar problem to [Iterator][iterator], where\n/// /// More talking\n/// returning them from a function requires exposing the implementation of that\n/// function. The [`helper_types`][helper_types] module exists to help with this,\n/// but you might want to hide the return type or have it conditionally change.\n/// Boxing can achieve both.\n///\n/// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html\n/// [helper_types]: ../helper_types/index.html\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn issue883() {\n}\n\n/// `foo_bar\n/// baz_quz`\n/// [foo\n/// bar](https://doc.rust-lang.org/stable/std/iter/trait.IteratorFooBar.html)\nfn multiline() {\n}\n\n/** E.g., serialization of an empty list: FooBar\n```\nThat's in a code block: `PackedNode`\n```\n\nAnd BarQuz too.\nbe_sure_we_got_to_the_end_of_it\n*/\n//~^^^ doc_markdown\n//~^^^ doc_markdown\n//~^^^^^^^^^^ doc_markdown\nfn issue1073() {\n}\n\n/** E.g., serialization of an empty list: FooBar\n```\nThat's in a code block: PackedNode\n```\n\nAnd BarQuz too.\nbe_sure_we_got_to_the_end_of_it\n*/\n//~^^ doc_markdown\n//~^^^^ doc_markdown\n//~^^^^^^^^^^ doc_markdown\nfn issue1073_alt() {\n}\n\n/// Tests more than three quotes:\n/// ````\n/// DoNotWarn\n/// ```\n/// StillDont\n/// ````\n/// be_sure_we_got_to_the_end_of_it\n//~^ doc_markdown\nfn four_quotes() {\n}\n\n#[cfg_attr(feature = \"a\", doc = \" ```\")]\n#[cfg_attr(not(feature = \"a\"), doc = \" ```ignore\")]\n/// fn main() {\n///     let s = \"localhost:10000\".to_string();\n///     println!(\"{}\", s);\n/// }\n/// ```\nfn issue_1469() {}\n\n/**\n * This is a doc comment that should not be a list\n *This would also be an error under a strict common mark interpretation\n */\nfn issue_1920() {}\n\n/// An iterator over mycrate::Collection's values.\n//~^ doc_markdown\n/// It should not lint a `'static` lifetime in ticks.\nfn issue_2210() {}\n\n/// This should not cause the lint to trigger:\n/// #REQ-data-family.lint_partof_exists\nfn issue_2343() {}\n\n/// This should not cause an ICE:\n/// __|_ _|__||_|\nfn pulldown_cmark_crash() {}\n\n/// This should not lint\n/// (regression test for #7758)\n/// [plain text][path::to::item]\nfn intra_doc_link() {}\n\n/// Ignore escaped\\_underscores\n///\n/// \\\\[\n///     \\\\prod\\_{x\\\\in X} p\\_x\n/// \\\\]\nfn issue_2581() {}\n\n/// Foo \\[bar\\] \\[baz\\] \\[qux\\]. DocMarkdownLint\n//~^ doc_markdown\nfn lint_after_escaped_chars() {}\n\n// issue #7033 - generic_const_exprs ICE\nstruct S<T, const N: usize>\nwhere [(); N.checked_next_power_of_two().unwrap()]: {\n    arr: [T; N.checked_next_power_of_two().unwrap()],\n    n: usize,\n}\n\nimpl<T: Copy + Default, const N: usize> S<T, N>\nwhere [(); N.checked_next_power_of_two().unwrap()]: {\n    fn new() -> Self {\n        Self {\n            arr: [T::default(); N.checked_next_power_of_two().unwrap()],\n            n: 0,\n        }\n    }\n}\n\n/// this checks if the lowerCamelCase issue is fixed\nfn issue_11568() {}\n\n/// There is no try (do() or do_not()).\n//~^ doc_markdown\n//~| doc_markdown\nfn parenthesized_word() {}\n\n/// ABes\n//~^ doc_markdown\n/// OSes\n/// UXes\nfn plural_acronym_test() {}\n\nunsafe extern \"C\" {\n    /// foo()\n    //~^ doc_markdown\n    fn in_extern();\n}\n\n/// https://github.com/rust-lang/rust-clippy/pull/12836\n//~^ doc_markdown\nfn check_autofix_for_base_urls() {}\n"
  },
  {
    "path": "tests/ui/doc/doc-fixable.stderr",
    "content": "error: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:8:9\n   |\nLL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)\n   |         ^^^^^^^\n   |\n   = note: `-D clippy::doc-markdown` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`\nhelp: try\n   |\nLL - /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)\nLL + /// The `foo_bar` function does _nothing_. See also foo::bar. (note the dot there)\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:8:51\n   |\nLL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)\n   |                                                   ^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)\nLL + /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot there)\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:11:83\n   |\nLL | /// Markdown is _weird_. I mean _really weird_. This \\_ is ok. So is `_`. But not Foo::some_fun\n   |                                                                                   ^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// Markdown is _weird_. I mean _really weird_. This \\_ is ok. So is `_`. But not Foo::some_fun\nLL + /// Markdown is _weird_. I mean _really weird_. This \\_ is ok. So is `_`. But not `Foo::some_fun`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:14:13\n   |\nLL | /// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.\n   |             ^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.\nLL + /// Here be `::a::global:path`, and _::another::global::path_.  :: is not a path though.\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:14:36\n   |\nLL | /// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.\nLL + /// Here be ::a::global:path, and _`::another::global::path`_.  :: is not a path though.\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:17:25\n   |\nLL | /// Import an item from ::awesome::global::blob:: (Intended postfix)\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// Import an item from ::awesome::global::blob:: (Intended postfix)\nLL + /// Import an item from `::awesome::global::blob::` (Intended postfix)\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:19:31\n   |\nLL | /// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted)\n   |                               ^^^^^\n   |\nhelp: try\n   |\nLL - /// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted)\nLL + /// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted)\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:21:22\n   |\nLL | /// That's not code ~NotInCodeBlock~.\n   |                      ^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// That's not code ~NotInCodeBlock~.\nLL + /// That's not code ~`NotInCodeBlock`~.\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:23:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:38:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:46:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:61:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:91:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:109:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:114:8\n   |\nLL | /// ## CamelCaseThing\n   |        ^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// ## CamelCaseThing\nLL + /// ## `CamelCaseThing`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:118:7\n   |\nLL | /// # CamelCaseThing\n   |       ^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// # CamelCaseThing\nLL + /// # `CamelCaseThing`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:121:22\n   |\nLL | /// Not a title #897 CamelCaseThing\n   |                      ^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// Not a title #897 CamelCaseThing\nLL + /// Not a title #897 `CamelCaseThing`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:123:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:131:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:145:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:157:43\n   |\nLL | /** E.g., serialization of an empty list: FooBar\n   |                                           ^^^^^^\n   |\nhelp: try\n   |\nLL - /** E.g., serialization of an empty list: FooBar\nLL + /** E.g., serialization of an empty list: `FooBar`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:162:5\n   |\nLL | And BarQuz too.\n   |     ^^^^^^\n   |\nhelp: try\n   |\nLL - And BarQuz too.\nLL + And `BarQuz` too.\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:163:1\n   |\nLL | be_sure_we_got_to_the_end_of_it\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - be_sure_we_got_to_the_end_of_it\nLL + `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:171:43\n   |\nLL | /** E.g., serialization of an empty list: FooBar\n   |                                           ^^^^^^\n   |\nhelp: try\n   |\nLL - /** E.g., serialization of an empty list: FooBar\nLL + /** E.g., serialization of an empty list: `FooBar`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:176:5\n   |\nLL | And BarQuz too.\n   |     ^^^^^^\n   |\nhelp: try\n   |\nLL - And BarQuz too.\nLL + And `BarQuz` too.\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:177:1\n   |\nLL | be_sure_we_got_to_the_end_of_it\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - be_sure_we_got_to_the_end_of_it\nLL + `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:191:5\n   |\nLL | /// be_sure_we_got_to_the_end_of_it\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// be_sure_we_got_to_the_end_of_it\nLL + /// `be_sure_we_got_to_the_end_of_it`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:211:22\n   |\nLL | /// An iterator over mycrate::Collection's values.\n   |                      ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// An iterator over mycrate::Collection's values.\nLL + /// An iterator over `mycrate::Collection`'s values.\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:236:34\n   |\nLL | /// Foo \\[bar\\] \\[baz\\] \\[qux\\]. DocMarkdownLint\n   |                                  ^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// Foo \\[bar\\] \\[baz\\] \\[qux\\]. DocMarkdownLint\nLL + /// Foo \\[bar\\] \\[baz\\] \\[qux\\]. `DocMarkdownLint`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:260:22\n   |\nLL | /// There is no try (do() or do_not()).\n   |                      ^^^^\n   |\nhelp: try\n   |\nLL - /// There is no try (do() or do_not()).\nLL + /// There is no try (`do()` or do_not()).\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:260:30\n   |\nLL | /// There is no try (do() or do_not()).\n   |                              ^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// There is no try (do() or do_not()).\nLL + /// There is no try (do() or `do_not()`).\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:265:5\n   |\nLL | /// ABes\n   |     ^^^^\n   |\nhelp: try\n   |\nLL - /// ABes\nLL + /// `ABes`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc-fixable.rs:272:9\n   |\nLL |     /// foo()\n   |         ^^^^^\n   |\nhelp: try\n   |\nLL -     /// foo()\nLL +     /// `foo()`\n   |\n\nerror: you should put bare URLs between `<`/`>` or make a proper Markdown link\n  --> tests/ui/doc/doc-fixable.rs:277:5\n   |\nLL | /// https://github.com/rust-lang/rust-clippy/pull/12836\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<https://github.com/rust-lang/rust-clippy/pull/12836>`\n\nerror: aborting due to 34 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_comment_double_space_linebreaks.fixed",
    "content": "#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n\n#![warn(clippy::doc_comment_double_space_linebreaks)]\n#![allow(unused, clippy::empty_docs)]\n\n//~v doc_comment_double_space_linebreaks\n//! Should warn on double space linebreaks\\\n//! in file/module doc comment\n\n/// Should not warn on single-line doc comments\nfn single_line() {}\n\n/// Should not warn on single-line doc comments\n/// split across multiple lines\nfn single_line_split() {}\n\n// Should not warn on normal comments\n\n// note: cargo fmt can remove double spaces from normal and block comments\n// Should not warn on normal comments  \n// with double spaces at the end of a line  \n\n#[doc = \"This is a doc attribute, which should not be linted\"]\nfn normal_comment() {\n   /*\n   Should not warn on block comments\n   */\n  \n  /*\n  Should not warn on block comments  \n  with double space at the end of a line\n  */\n}\n\n//~v doc_comment_double_space_linebreaks\n/// Should warn when doc comment uses double space\\\n/// as a line-break, even when there are multiple\\\n/// in a row\nfn double_space_doc_comment() {}\n\n/// Should not warn when back-slash is used \\\n/// as a line-break\nfn back_slash_doc_comment() {}\n\n//~v doc_comment_double_space_linebreaks\n/// 🌹 are 🟥\\\n/// 🌷 are 🟦\\\n/// 📎 is 😎\\\n/// and so are 🫵\\\n/// (hopefully no formatting weirdness linting this)\nfn multi_byte_chars_tada() {}\n\nmacro_rules! macro_that_makes_function {\n   () => {\n      /// Shouldn't lint on this!  \n      /// (hopefully)\n      fn my_macro_created_function() {}\n   }\n}\n\nmacro_that_makes_function!();\n\n// dont lint when its alone on a line\n///  \nfn alone() {}\n\n/// | First column | Second column |  \n/// | ------------ | ------------- |  \n/// | Not a line   | break when    |  \n/// | after a line | in a table    |  \nfn table() {}\n\n/// ```text  \n/// It's also not a hard line break if  \n/// there's two spaces at the end of a  \n/// line in a block code.  \n/// ```  \nfn codeblock() {}\n\n/// It's also not a hard line break `if  \n/// there's` two spaces in the middle of inline code.  \nfn inline() {}\n\n/// It's also not a hard line break [when](  \n/// https://example.com) in a URL.  \nfn url() {}\n\n//~v doc_comment_double_space_linebreaks\n/// here we mix\\\n/// double spaces\\\n/// and also\\\n/// adding backslash\\\n/// to some of them\\\n/// to see how that looks\nfn mixed() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/doc/doc_comment_double_space_linebreaks.rs",
    "content": "#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n\n#![warn(clippy::doc_comment_double_space_linebreaks)]\n#![allow(unused, clippy::empty_docs)]\n\n//~v doc_comment_double_space_linebreaks\n//! Should warn on double space linebreaks  \n//! in file/module doc comment\n\n/// Should not warn on single-line doc comments\nfn single_line() {}\n\n/// Should not warn on single-line doc comments\n/// split across multiple lines\nfn single_line_split() {}\n\n// Should not warn on normal comments\n\n// note: cargo fmt can remove double spaces from normal and block comments\n// Should not warn on normal comments  \n// with double spaces at the end of a line  \n\n#[doc = \"This is a doc attribute, which should not be linted\"]\nfn normal_comment() {\n   /*\n   Should not warn on block comments\n   */\n  \n  /*\n  Should not warn on block comments  \n  with double space at the end of a line\n  */\n}\n\n//~v doc_comment_double_space_linebreaks\n/// Should warn when doc comment uses double space  \n/// as a line-break, even when there are multiple  \n/// in a row\nfn double_space_doc_comment() {}\n\n/// Should not warn when back-slash is used \\\n/// as a line-break\nfn back_slash_doc_comment() {}\n\n//~v doc_comment_double_space_linebreaks\n/// 🌹 are 🟥  \n/// 🌷 are 🟦  \n/// 📎 is 😎  \n/// and so are 🫵  \n/// (hopefully no formatting weirdness linting this)\nfn multi_byte_chars_tada() {}\n\nmacro_rules! macro_that_makes_function {\n   () => {\n      /// Shouldn't lint on this!  \n      /// (hopefully)\n      fn my_macro_created_function() {}\n   }\n}\n\nmacro_that_makes_function!();\n\n// dont lint when its alone on a line\n///  \nfn alone() {}\n\n/// | First column | Second column |  \n/// | ------------ | ------------- |  \n/// | Not a line   | break when    |  \n/// | after a line | in a table    |  \nfn table() {}\n\n/// ```text  \n/// It's also not a hard line break if  \n/// there's two spaces at the end of a  \n/// line in a block code.  \n/// ```  \nfn codeblock() {}\n\n/// It's also not a hard line break `if  \n/// there's` two spaces in the middle of inline code.  \nfn inline() {}\n\n/// It's also not a hard line break [when](  \n/// https://example.com) in a URL.  \nfn url() {}\n\n//~v doc_comment_double_space_linebreaks\n/// here we mix  \n/// double spaces\\\n/// and also  \n/// adding backslash\\\n/// to some of them  \n/// to see how that looks\nfn mixed() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/doc/doc_comment_double_space_linebreaks.stderr",
    "content": "error: doc comment uses two spaces for a hard line break\n  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:8:43\n   |\nLL | //! Should warn on double space linebreaks  \n   |                                           ^^\n   |\n   = help: replace this double space with a backslash: `\\`\n   = note: `-D clippy::doc-comment-double-space-linebreaks` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_comment_double_space_linebreaks)]`\n\nerror: doc comment uses two spaces for a hard line break\n  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:37:51\n   |\nLL | /// Should warn when doc comment uses double space  \n   |                                                   ^^\nLL | /// as a line-break, even when there are multiple  \n   |                                                  ^^\n   |\n   = help: replace this double space with a backslash: `\\`\n\nerror: doc comment uses two spaces for a hard line break\n  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:47:12\n   |\nLL | /// 🌹 are 🟥  \n   |              ^^\nLL | /// 🌷 are 🟦  \n   |              ^^\nLL | /// 📎 is 😎  \n   |             ^^\nLL | /// and so are 🫵  \n   |                  ^^\n   |\n   = help: replace this double space with a backslash: `\\`\n\nerror: doc comment uses two spaces for a hard line break\n  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:90:16\n   |\nLL | /// here we mix  \n   |                ^^\nLL | /// double spaces\\\nLL | /// and also  \n   |             ^^\nLL | /// adding backslash\\\nLL | /// to some of them  \n   |                    ^^\n   |\n   = help: replace this double space with a backslash: `\\`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_include_without_cfg.fixed",
    "content": "#![warn(clippy::doc_include_without_cfg)]\n// Should not lint.\n#![doc(html_playground_url = \"https://playground.example.com/\")]\n#![cfg_attr(doc, doc = include_str!(\"../approx_const.rs\"))]\n//~^ doc_include_without_cfg\n// Should not lint.\n#![cfg_attr(feature = \"whatever\", doc = include_str!(\"../approx_const.rs\"))]\n#![cfg_attr(doc, doc = include_str!(\"../approx_const.rs\"))]\n#![doc = \"some doc\"]\n//! more doc\n\nmacro_rules! man_link {\n    ($a:literal, $b:literal) => {\n        concat!($a, $b)\n    };\n}\n\n// Should not lint!\nmacro_rules! tst {\n    ($(#[$attr:meta])*) => {\n        $(#[$attr])*\n        fn blue() {\n            println!(\"Hello, world!\");\n        }\n    }\n}\n\ntst! {\n    /// This is a test with no included file\n}\n\n#[cfg_attr(doc, doc = include_str!(\"../approx_const.rs\"))]\n//~^ doc_include_without_cfg\n// Should not lint.\n#[doc = man_link!(\"bla\", \"blob\")]\n#[cfg_attr(feature = \"whatever\", doc = include_str!(\"../approx_const.rs\"))]\n#[cfg_attr(doc, doc = include_str!(\"../approx_const.rs\"))]\n#[doc = \"some doc\"]\n/// more doc\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/doc/doc_include_without_cfg.rs",
    "content": "#![warn(clippy::doc_include_without_cfg)]\n// Should not lint.\n#![doc(html_playground_url = \"https://playground.example.com/\")]\n#![doc = include_str!(\"../approx_const.rs\")]\n//~^ doc_include_without_cfg\n// Should not lint.\n#![cfg_attr(feature = \"whatever\", doc = include_str!(\"../approx_const.rs\"))]\n#![cfg_attr(doc, doc = include_str!(\"../approx_const.rs\"))]\n#![doc = \"some doc\"]\n//! more doc\n\nmacro_rules! man_link {\n    ($a:literal, $b:literal) => {\n        concat!($a, $b)\n    };\n}\n\n// Should not lint!\nmacro_rules! tst {\n    ($(#[$attr:meta])*) => {\n        $(#[$attr])*\n        fn blue() {\n            println!(\"Hello, world!\");\n        }\n    }\n}\n\ntst! {\n    /// This is a test with no included file\n}\n\n#[doc = include_str!(\"../approx_const.rs\")]\n//~^ doc_include_without_cfg\n// Should not lint.\n#[doc = man_link!(\"bla\", \"blob\")]\n#[cfg_attr(feature = \"whatever\", doc = include_str!(\"../approx_const.rs\"))]\n#[cfg_attr(doc, doc = include_str!(\"../approx_const.rs\"))]\n#[doc = \"some doc\"]\n/// more doc\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/doc/doc_include_without_cfg.stderr",
    "content": "error: included a file in documentation unconditionally\n  --> tests/ui/doc/doc_include_without_cfg.rs:4:1\n   |\nLL | #![doc = include_str!(\"../approx_const.rs\")]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `cfg_attr(doc, doc = \"...\")`: `#![cfg_attr(doc, doc = include_str!(\"../approx_const.rs\"))]`\n   |\n   = note: `-D clippy::doc-include-without-cfg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_include_without_cfg)]`\n\nerror: included a file in documentation unconditionally\n  --> tests/ui/doc/doc_include_without_cfg.rs:32:1\n   |\nLL | #[doc = include_str!(\"../approx_const.rs\")]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `cfg_attr(doc, doc = \"...\")`: `#[cfg_attr(doc, doc = include_str!(\"../approx_const.rs\"))]`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_lazy_blockquote.fixed",
    "content": "#![warn(clippy::doc_lazy_continuation)]\n\n/// > blockquote with\n/// > lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn first() {}\n\n/// > blockquote with no\n/// > lazy continuation\nfn first_nowarn() {}\n\n/// > blockquote with no\n///\n/// lazy continuation\nfn two_nowarn() {}\n\n/// > nest here\n/// >\n/// > > nest here\n/// > > lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn two() {}\n\n/// > nest here\n/// >\n/// > > nest here\n/// > > lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn three() {}\n\n/// >   * > nest here\n/// >     > lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn four() {}\n\n/// > * > nest here\n/// >   > lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn four_point_1() {}\n\n/// * > nest here lazy continuation\nfn five() {}\n\n/// 1. > nest here\n///    > lazy continuation (this results in strange indentation, but still works)\n//~^ ERROR: doc quote line without `>` marker\nfn six() {}\n"
  },
  {
    "path": "tests/ui/doc/doc_lazy_blockquote.rs",
    "content": "#![warn(clippy::doc_lazy_continuation)]\n\n/// > blockquote with\n/// lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn first() {}\n\n/// > blockquote with no\n/// > lazy continuation\nfn first_nowarn() {}\n\n/// > blockquote with no\n///\n/// lazy continuation\nfn two_nowarn() {}\n\n/// > nest here\n/// >\n/// > > nest here\n/// > lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn two() {}\n\n/// > nest here\n/// >\n/// > > nest here\n/// lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn three() {}\n\n/// >   * > nest here\n/// lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn four() {}\n\n/// > * > nest here\n/// lazy continuation\n//~^ ERROR: doc quote line without `>` marker\nfn four_point_1() {}\n\n/// * > nest here lazy continuation\nfn five() {}\n\n/// 1. > nest here\n///  lazy continuation (this results in strange indentation, but still works)\n//~^ ERROR: doc quote line without `>` marker\nfn six() {}\n"
  },
  {
    "path": "tests/ui/doc/doc_lazy_blockquote.stderr",
    "content": "error: doc quote line without `>` marker\n  --> tests/ui/doc/doc_lazy_blockquote.rs:4:5\n   |\nLL | /// lazy continuation\n   |     ^\n   |\n   = help: if this not intended to be a quote at all, escape it with `\\>`\n   = note: `-D clippy::doc-lazy-continuation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_lazy_continuation)]`\nhelp: add markers to start of line\n   |\nLL | /// > lazy continuation\n   |     +\n\nerror: doc quote line without `>` marker\n  --> tests/ui/doc/doc_lazy_blockquote.rs:20:5\n   |\nLL | /// > lazy continuation\n   |     ^^\n   |\n   = help: if this not intended to be a quote at all, escape it with `\\>`\nhelp: add markers to start of line\n   |\nLL | /// > > lazy continuation\n   |       +\n\nerror: doc quote line without `>` marker\n  --> tests/ui/doc/doc_lazy_blockquote.rs:27:5\n   |\nLL | /// lazy continuation\n   |     ^\n   |\n   = help: if this not intended to be a quote at all, escape it with `\\>`\nhelp: add markers to start of line\n   |\nLL | /// > > lazy continuation\n   |     +++\n\nerror: doc quote line without `>` marker\n  --> tests/ui/doc/doc_lazy_blockquote.rs:32:5\n   |\nLL | /// lazy continuation\n   |     ^\n   |\n   = help: if this not intended to be a quote at all, escape it with `\\>`\nhelp: add markers to start of line\n   |\nLL | /// >     > lazy continuation\n   |     +++++++\n\nerror: doc quote line without `>` marker\n  --> tests/ui/doc/doc_lazy_blockquote.rs:37:5\n   |\nLL | /// lazy continuation\n   |     ^\n   |\n   = help: if this not intended to be a quote at all, escape it with `\\>`\nhelp: add markers to start of line\n   |\nLL | /// >   > lazy continuation\n   |     +++++\n\nerror: doc quote line without `>` marker\n  --> tests/ui/doc/doc_lazy_blockquote.rs:45:5\n   |\nLL | ///  lazy continuation (this results in strange indentation, but still works)\n   |     ^\n   |\n   = help: if this not intended to be a quote at all, escape it with `\\>`\nhelp: add markers to start of line\n   |\nLL | ///    > lazy continuation (this results in strange indentation, but still works)\n   |        +\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_lazy_list.fixed",
    "content": "#![warn(clippy::doc_lazy_continuation)]\n#![allow(clippy::doc_overindented_list_items)]\n\n/// 1. nest here\n///    lazy continuation\n//~^ ERROR: doc list item without indentation\nfn one() {}\n\n/// 1. first line\n///    lazy list continuations don't make warnings with this lint\n//~^ ERROR: doc list item without indentation\n///    because they don't have the\n//~^ ERROR: doc list item without indentation\nfn two() {}\n\n///   - nest here\n///     lazy continuation\n//~^ ERROR: doc list item without indentation\nfn three() {}\n\n///   - first line\n///     lazy list continuations don't make warnings with this lint\n//~^ ERROR: doc list item without indentation\n///     because they don't have the\n//~^ ERROR: doc list item without indentation\nfn four() {}\n\n///   - nest here\n///     lazy continuation\n//~^ ERROR: doc list item without indentation\nfn five() {}\n\n///   - - first line\n///       this will warn on the lazy continuation\n//~^ ERROR: doc list item without indentation\n///       and so should this\n//~^ ERROR: doc list item without indentation\nfn six() {}\n\n///   - - first line\n///\n///     this is not a lazy continuation\nfn seven() {}\n\n#[rustfmt::skip]\n// https://github.com/rust-lang/rust-clippy/pull/12770#issuecomment-2118601768\n/// Returns a list of ProtocolDescriptors from a Serde JSON input.\n///\n/// Defined Protocol Identifiers for the Protocol Descriptor\n/// We intentionally omit deprecated profile identifiers.\n/// From Bluetooth Assigned Numbers:\n/// https://www.bluetooth.com/specifications/assigned-numbers/service-discovery\n///\n/// # Arguments\n/// * `protocol_descriptors`: A Json Representation of the ProtocolDescriptors\n///     to set up. Example:\n///   'protocol_descriptors': [\n//~^ ERROR: doc list item without indentation\n///      {\n///          'protocol': 25,  # u64 Representation of ProtocolIdentifier::AVDTP\n///          'params': [\n///              {\n///                 'data': 0x0103  # to indicate 1.3\n///              },\n///              {\n///                  'data': 0x0105  # to indicate 1.5\n///              }\n///          ]\n///      },\n///      {\n///          'protocol': 1,  # u64 Representation of ProtocolIdentifier::SDP\n///          'params': [{\n///              'data': 0x0019\n///          }]\n///      }\n///   ]\n//~^ ERROR: doc list item without indentation\nfn eight() {}\n\n#[rustfmt::skip]\n// https://github.com/rust-lang/rust-clippy/issues/13705\n/// - \\[text in square brackets\\] with a long following description\n///   that goes over multiple lines\npub fn backslash_escaped_square_braces() {}\n"
  },
  {
    "path": "tests/ui/doc/doc_lazy_list.rs",
    "content": "#![warn(clippy::doc_lazy_continuation)]\n#![allow(clippy::doc_overindented_list_items)]\n\n/// 1. nest here\n/// lazy continuation\n//~^ ERROR: doc list item without indentation\nfn one() {}\n\n/// 1. first line\n/// lazy list continuations don't make warnings with this lint\n//~^ ERROR: doc list item without indentation\n/// because they don't have the\n//~^ ERROR: doc list item without indentation\nfn two() {}\n\n///   - nest here\n/// lazy continuation\n//~^ ERROR: doc list item without indentation\nfn three() {}\n\n///   - first line\n/// lazy list continuations don't make warnings with this lint\n//~^ ERROR: doc list item without indentation\n/// because they don't have the\n//~^ ERROR: doc list item without indentation\nfn four() {}\n\n///   - nest here\n/// lazy continuation\n//~^ ERROR: doc list item without indentation\nfn five() {}\n\n///   - - first line\n/// this will warn on the lazy continuation\n//~^ ERROR: doc list item without indentation\n///     and so should this\n//~^ ERROR: doc list item without indentation\nfn six() {}\n\n///   - - first line\n///\n///     this is not a lazy continuation\nfn seven() {}\n\n#[rustfmt::skip]\n// https://github.com/rust-lang/rust-clippy/pull/12770#issuecomment-2118601768\n/// Returns a list of ProtocolDescriptors from a Serde JSON input.\n///\n/// Defined Protocol Identifiers for the Protocol Descriptor\n/// We intentionally omit deprecated profile identifiers.\n/// From Bluetooth Assigned Numbers:\n/// https://www.bluetooth.com/specifications/assigned-numbers/service-discovery\n///\n/// # Arguments\n/// * `protocol_descriptors`: A Json Representation of the ProtocolDescriptors\n///     to set up. Example:\n///  'protocol_descriptors': [\n//~^ ERROR: doc list item without indentation\n///      {\n///          'protocol': 25,  # u64 Representation of ProtocolIdentifier::AVDTP\n///          'params': [\n///              {\n///                 'data': 0x0103  # to indicate 1.3\n///              },\n///              {\n///                  'data': 0x0105  # to indicate 1.5\n///              }\n///          ]\n///      },\n///      {\n///          'protocol': 1,  # u64 Representation of ProtocolIdentifier::SDP\n///          'params': [{\n///              'data': 0x0019\n///          }]\n///      }\n///  ]\n//~^ ERROR: doc list item without indentation\nfn eight() {}\n\n#[rustfmt::skip]\n// https://github.com/rust-lang/rust-clippy/issues/13705\n/// - \\[text in square brackets\\] with a long following description\n///   that goes over multiple lines\npub fn backslash_escaped_square_braces() {}\n"
  },
  {
    "path": "tests/ui/doc/doc_lazy_list.stderr",
    "content": "error: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:5:5\n   |\nLL | /// lazy continuation\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\n   = note: `-D clippy::doc-lazy-continuation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_lazy_continuation)]`\nhelp: indent this line\n   |\nLL | ///    lazy continuation\n   |     +++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:10:5\n   |\nLL | /// lazy list continuations don't make warnings with this lint\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///    lazy list continuations don't make warnings with this lint\n   |     +++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:12:5\n   |\nLL | /// because they don't have the\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///    because they don't have the\n   |     +++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:17:5\n   |\nLL | /// lazy continuation\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///     lazy continuation\n   |     ++++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:22:5\n   |\nLL | /// lazy list continuations don't make warnings with this lint\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///     lazy list continuations don't make warnings with this lint\n   |     ++++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:24:5\n   |\nLL | /// because they don't have the\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///     because they don't have the\n   |     ++++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:29:5\n   |\nLL | /// lazy continuation\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///     lazy continuation\n   |     ++++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:34:5\n   |\nLL | /// this will warn on the lazy continuation\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///       this will warn on the lazy continuation\n   |     ++++++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:36:5\n   |\nLL | ///     and so should this\n   |     ^^^^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///       and so should this\n   |         ++\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:57:5\n   |\nLL | ///  'protocol_descriptors': [\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///   'protocol_descriptors': [\n   |      +\n\nerror: doc list item without indentation\n  --> tests/ui/doc/doc_lazy_list.rs:76:5\n   |\nLL | ///  ]\n   |     ^\n   |\n   = help: if this is supposed to be its own paragraph, add a blank line\nhelp: indent this line\n   |\nLL | ///   ]\n   |      +\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_markdown-issue_13097.fixed",
    "content": "#![deny(clippy::doc_markdown)]\n#![allow(clippy::doc_lazy_continuation)]\n\nmod issue13097 {\n    // This test checks that words starting with capital letters and ending with \"ified\" don't\n    // trigger the lint.\n    pub enum OutputFormat {\n        /// `HumaNified`\n        //~^ ERROR: item in documentation is missing backticks\n        Plain,\n        // Should not warn!\n        /// JSONified console output\n        Json,\n    }\n}\n\n#[rustfmt::skip]\npub enum OutputFormat {\n    /**\n     * `HumaNified`\n     //~^ ERROR: item in documentation is missing backticks\n     * Before \\u{08888} `HumaNified` \\{u08888} After\n     //~^ ERROR: item in documentation is missing backticks\n     * meow meow \\[`meow_meow`\\] meow meow?\n     //~^ ERROR: item in documentation is missing backticks\n     * \\u{08888} `meow_meow` \\[meow meow] meow?\n     //~^ ERROR: item in documentation is missing backticks\n     * Above\n     * \\u{08888}\n     * \\[hi\\](<https://example.com>) `HumaNified` \\[example](<https://example.com>)\n     //~^ ERROR: item in documentation is missing backticks\n     * \\u{08888}\n     * Below\n     */\n    Plain,\n    // Should not warn!\n    /// JSONified console output\n    Json,\n}\n"
  },
  {
    "path": "tests/ui/doc/doc_markdown-issue_13097.rs",
    "content": "#![deny(clippy::doc_markdown)]\n#![allow(clippy::doc_lazy_continuation)]\n\nmod issue13097 {\n    // This test checks that words starting with capital letters and ending with \"ified\" don't\n    // trigger the lint.\n    pub enum OutputFormat {\n        /// HumaNified\n        //~^ ERROR: item in documentation is missing backticks\n        Plain,\n        // Should not warn!\n        /// JSONified console output\n        Json,\n    }\n}\n\n#[rustfmt::skip]\npub enum OutputFormat {\n    /**\n     * HumaNified\n     //~^ ERROR: item in documentation is missing backticks\n     * Before \\u{08888} HumaNified \\{u08888} After\n     //~^ ERROR: item in documentation is missing backticks\n     * meow meow \\[meow_meow\\] meow meow?\n     //~^ ERROR: item in documentation is missing backticks\n     * \\u{08888} meow_meow \\[meow meow] meow?\n     //~^ ERROR: item in documentation is missing backticks\n     * Above\n     * \\u{08888}\n     * \\[hi\\](<https://example.com>) HumaNified \\[example](<https://example.com>)\n     //~^ ERROR: item in documentation is missing backticks\n     * \\u{08888}\n     * Below\n     */\n    Plain,\n    // Should not warn!\n    /// JSONified console output\n    Json,\n}\n"
  },
  {
    "path": "tests/ui/doc/doc_markdown-issue_13097.stderr",
    "content": "error: item in documentation is missing backticks\n  --> tests/ui/doc/doc_markdown-issue_13097.rs:8:13\n   |\nLL |         /// HumaNified\n   |             ^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/doc/doc_markdown-issue_13097.rs:1:9\n   |\nLL | #![deny(clippy::doc_markdown)]\n   |         ^^^^^^^^^^^^^^^^^^^^\nhelp: try\n   |\nLL -         /// HumaNified\nLL +         /// `HumaNified`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc_markdown-issue_13097.rs:20:8\n   |\nLL |      * HumaNified\n   |        ^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -      * HumaNified\nLL +      * `HumaNified`\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc_markdown-issue_13097.rs:22:25\n   |\nLL |      * Before \\u{08888} HumaNified \\{u08888} After\n   |                         ^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -      * Before \\u{08888} HumaNified \\{u08888} After\nLL +      * Before \\u{08888} `HumaNified` \\{u08888} After\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc_markdown-issue_13097.rs:24:20\n   |\nLL |      * meow meow \\[meow_meow\\] meow meow?\n   |                    ^^^^^^^^^\n   |\nhelp: try\n   |\nLL -      * meow meow \\[meow_meow\\] meow meow?\nLL +      * meow meow \\[`meow_meow`\\] meow meow?\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc_markdown-issue_13097.rs:26:18\n   |\nLL |      * \\u{08888} meow_meow \\[meow meow] meow?\n   |                  ^^^^^^^^^\n   |\nhelp: try\n   |\nLL -      * \\u{08888} meow_meow \\[meow meow] meow?\nLL +      * \\u{08888} `meow_meow` \\[meow meow] meow?\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/doc_markdown-issue_13097.rs:30:38\n   |\nLL |      * \\[hi\\](<https://example.com>) HumaNified \\[example](<https://example.com>)\n   |                                      ^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -      * \\[hi\\](<https://example.com>) HumaNified \\[example](<https://example.com>)\nLL +      * \\[hi\\](<https://example.com>) `HumaNified` \\[example](<https://example.com>)\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_nested_refdef_blockquote.fixed",
    "content": "// https://github.com/rust-lang/rust/issues/133150\n#![warn(clippy::doc_nested_refdefs)]\n#[rustfmt::skip]\n/// > [link][]: def\n//~^ ERROR: link reference defined in quote\n///\n/// > [link][]: def (title)\n//~^ ERROR: link reference defined in quote\n///\n/// > [link][]: def \"title\"\n//~^ ERROR: link reference defined in quote\n///\n/// > [link]: not def\n///\n/// > [link][]: notdef\n///\n/// > [link]\\: notdef\npub struct Empty;\n\n#[rustfmt::skip]\n/// > [link][]: def\n//~^ ERROR: link reference defined in quote\n/// > inner text\n///\n/// > [link][]: def (title)\n//~^ ERROR: link reference defined in quote\n/// > inner text\n///\n/// > [link][]: def \"title\"\n//~^ ERROR: link reference defined in quote\n/// > inner text\n///\n/// > [link]: not def\n/// > inner text\n///\n/// > [link][]: notdef\n/// > inner text\n///\n/// > [link]\\: notdef\n/// > inner text\npub struct NotEmpty;\n\n#[rustfmt::skip]\n/// > [link][]: def\n//~^ ERROR: link reference defined in quote\n/// >\n/// > inner text\n///\n/// > [link][]: def (title)\n//~^ ERROR: link reference defined in quote\n/// >\n/// > inner text\n///\n/// > [link][]: def \"title\"\n//~^ ERROR: link reference defined in quote\n/// >\n/// > inner text\n///\n/// > [link]: not def\n/// >\n/// > inner text\n///\n/// > [link][]: notdef\n/// >\n/// > inner text\n///\n/// > [link]\\: notdef\n/// >\n/// > inner text\npub struct NotEmptyLoose;\n\n#[rustfmt::skip]\n/// > first lines\n/// > [link]: def\n///\n/// > first lines\n/// > [link]: def (title)\n///\n/// > firs lines\n/// > [link]: def \"title\"\n///\n/// > firs lines\n/// > [link]: not def\n///\n/// > first lines\n/// > [link][]: notdef\n///\n/// > first lines\n/// > [link]\\: notdef\npub struct NotAtStartTight;\n\n#[rustfmt::skip]\n/// > first lines\n/// >\n/// > [link]: def\n///\n/// > first lines\n/// >\n/// > [link]: def (title)\n///\n/// > firs lines\n/// >\n/// > [link]: def \"title\"\n///\n/// > firs lines\n/// >\n/// > [link]: not def\n///\n/// > first lines\n/// >\n/// > [link][]: notdef\n///\n/// > first lines\n/// >\n/// > [link]\\: notdef\npub struct NotAtStartLoose;\n\n#[rustfmt::skip]\n/// > - [link][]: def\n//~^ ERROR: link reference defined in list item\n/// >\n/// > - [link][]: def (title)\n//~^ ERROR: link reference defined in list item\n/// >\n/// > - [link][]: def \"title\"\n//~^ ERROR: link reference defined in list item\n/// >\n/// > - [link]: not def\n/// >\n/// > - [link][]: notdef\n/// >\n/// > - [link]\\: notdef\npub struct ListNested;\n"
  },
  {
    "path": "tests/ui/doc/doc_nested_refdef_blockquote.rs",
    "content": "// https://github.com/rust-lang/rust/issues/133150\n#![warn(clippy::doc_nested_refdefs)]\n#[rustfmt::skip]\n/// > [link]: def\n//~^ ERROR: link reference defined in quote\n///\n/// > [link]: def (title)\n//~^ ERROR: link reference defined in quote\n///\n/// > [link]: def \"title\"\n//~^ ERROR: link reference defined in quote\n///\n/// > [link]: not def\n///\n/// > [link][]: notdef\n///\n/// > [link]\\: notdef\npub struct Empty;\n\n#[rustfmt::skip]\n/// > [link]: def\n//~^ ERROR: link reference defined in quote\n/// > inner text\n///\n/// > [link]: def (title)\n//~^ ERROR: link reference defined in quote\n/// > inner text\n///\n/// > [link]: def \"title\"\n//~^ ERROR: link reference defined in quote\n/// > inner text\n///\n/// > [link]: not def\n/// > inner text\n///\n/// > [link][]: notdef\n/// > inner text\n///\n/// > [link]\\: notdef\n/// > inner text\npub struct NotEmpty;\n\n#[rustfmt::skip]\n/// > [link]: def\n//~^ ERROR: link reference defined in quote\n/// >\n/// > inner text\n///\n/// > [link]: def (title)\n//~^ ERROR: link reference defined in quote\n/// >\n/// > inner text\n///\n/// > [link]: def \"title\"\n//~^ ERROR: link reference defined in quote\n/// >\n/// > inner text\n///\n/// > [link]: not def\n/// >\n/// > inner text\n///\n/// > [link][]: notdef\n/// >\n/// > inner text\n///\n/// > [link]\\: notdef\n/// >\n/// > inner text\npub struct NotEmptyLoose;\n\n#[rustfmt::skip]\n/// > first lines\n/// > [link]: def\n///\n/// > first lines\n/// > [link]: def (title)\n///\n/// > firs lines\n/// > [link]: def \"title\"\n///\n/// > firs lines\n/// > [link]: not def\n///\n/// > first lines\n/// > [link][]: notdef\n///\n/// > first lines\n/// > [link]\\: notdef\npub struct NotAtStartTight;\n\n#[rustfmt::skip]\n/// > first lines\n/// >\n/// > [link]: def\n///\n/// > first lines\n/// >\n/// > [link]: def (title)\n///\n/// > firs lines\n/// >\n/// > [link]: def \"title\"\n///\n/// > firs lines\n/// >\n/// > [link]: not def\n///\n/// > first lines\n/// >\n/// > [link][]: notdef\n///\n/// > first lines\n/// >\n/// > [link]\\: notdef\npub struct NotAtStartLoose;\n\n#[rustfmt::skip]\n/// > - [link]: def\n//~^ ERROR: link reference defined in list item\n/// >\n/// > - [link]: def (title)\n//~^ ERROR: link reference defined in list item\n/// >\n/// > - [link]: def \"title\"\n//~^ ERROR: link reference defined in list item\n/// >\n/// > - [link]: not def\n/// >\n/// > - [link][]: notdef\n/// >\n/// > - [link]\\: notdef\npub struct ListNested;\n"
  },
  {
    "path": "tests/ui/doc/doc_nested_refdef_blockquote.stderr",
    "content": "error: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:4:7\n   |\nLL | /// > [link]: def\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\n   = note: `-D clippy::doc-nested-refdefs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_nested_refdefs)]`\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def\n   |             ++\n\nerror: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:7:7\n   |\nLL | /// > [link]: def (title)\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def (title)\n   |             ++\n\nerror: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:10:7\n   |\nLL | /// > [link]: def \"title\"\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def \"title\"\n   |             ++\n\nerror: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:21:7\n   |\nLL | /// > [link]: def\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def\n   |             ++\n\nerror: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:25:7\n   |\nLL | /// > [link]: def (title)\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def (title)\n   |             ++\n\nerror: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:29:7\n   |\nLL | /// > [link]: def \"title\"\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def \"title\"\n   |             ++\n\nerror: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:44:7\n   |\nLL | /// > [link]: def\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def\n   |             ++\n\nerror: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:49:7\n   |\nLL | /// > [link]: def (title)\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def (title)\n   |             ++\n\nerror: link reference defined in quote\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:54:7\n   |\nLL | /// > [link]: def \"title\"\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > [link][]: def \"title\"\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:119:9\n   |\nLL | /// > - [link]: def\n   |         ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > - [link][]: def\n   |               ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:122:9\n   |\nLL | /// > - [link]: def (title)\n   |         ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > - [link][]: def (title)\n   |               ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:125:9\n   |\nLL | /// > - [link]: def \"title\"\n   |         ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// > - [link][]: def \"title\"\n   |               ++\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_nested_refdef_list_item.fixed",
    "content": "// https://github.com/rust-lang/rust/issues/133150\n#![warn(clippy::doc_nested_refdefs)]\n#[rustfmt::skip]\n/// - [link][]: def\n//~^ ERROR: link reference defined in list item\n///\n/// - [link][]: def (title)\n//~^ ERROR: link reference defined in list item\n///\n/// - [link][]: def \"title\"\n//~^ ERROR: link reference defined in list item\n///\n/// - [link]: not def\n///\n/// - [link][]: notdef\n///\n/// - [link]\\: notdef\npub struct Empty;\n\n#[rustfmt::skip]\n/// - [link][]: def\n//~^ ERROR: link reference defined in list item\n/// - [link][]: def (title)\n//~^ ERROR: link reference defined in list item\n/// - [link][]: def \"title\"\n//~^ ERROR: link reference defined in list item\n/// - [link]: not def\n/// - [link][]: notdef\n/// - [link]\\: notdef\npub struct EmptyTight;\n\n#[rustfmt::skip]\n/// - [link][]: def\n//~^ ERROR: link reference defined in list item\n///   inner text\n///\n/// - [link][]: def (title)\n//~^ ERROR: link reference defined in list item\n///   inner text\n///\n/// - [link][]: def \"title\"\n//~^ ERROR: link reference defined in list item\n///   inner text\n///\n/// - [link]: not def\n///   inner text\n///\n/// - [link][]: notdef\n///   inner text\n///\n/// - [link]\\: notdef\n///   inner text\npub struct NotEmpty;\n\n#[rustfmt::skip]\n/// - [link][]: def\n//~^ ERROR: link reference defined in list item\n///   inner text\n/// - [link][]: def (title)\n//~^ ERROR: link reference defined in list item\n///   inner text\n/// - [link][]: def \"title\"\n//~^ ERROR: link reference defined in list item\n///   inner text\n/// - [link]: not def\n///   inner text\n/// - [link][]: notdef\n///   inner text\n/// - [link]\\: notdef\n///   inner text\npub struct NotEmptyTight;\n\n/// ## Heading\n///\n/// - [x] - Done\n/// - [ ] - Not Done\npub struct GithubCheckboxes;\n"
  },
  {
    "path": "tests/ui/doc/doc_nested_refdef_list_item.rs",
    "content": "// https://github.com/rust-lang/rust/issues/133150\n#![warn(clippy::doc_nested_refdefs)]\n#[rustfmt::skip]\n/// - [link]: def\n//~^ ERROR: link reference defined in list item\n///\n/// - [link]: def (title)\n//~^ ERROR: link reference defined in list item\n///\n/// - [link]: def \"title\"\n//~^ ERROR: link reference defined in list item\n///\n/// - [link]: not def\n///\n/// - [link][]: notdef\n///\n/// - [link]\\: notdef\npub struct Empty;\n\n#[rustfmt::skip]\n/// - [link]: def\n//~^ ERROR: link reference defined in list item\n/// - [link]: def (title)\n//~^ ERROR: link reference defined in list item\n/// - [link]: def \"title\"\n//~^ ERROR: link reference defined in list item\n/// - [link]: not def\n/// - [link][]: notdef\n/// - [link]\\: notdef\npub struct EmptyTight;\n\n#[rustfmt::skip]\n/// - [link]: def\n//~^ ERROR: link reference defined in list item\n///   inner text\n///\n/// - [link]: def (title)\n//~^ ERROR: link reference defined in list item\n///   inner text\n///\n/// - [link]: def \"title\"\n//~^ ERROR: link reference defined in list item\n///   inner text\n///\n/// - [link]: not def\n///   inner text\n///\n/// - [link][]: notdef\n///   inner text\n///\n/// - [link]\\: notdef\n///   inner text\npub struct NotEmpty;\n\n#[rustfmt::skip]\n/// - [link]: def\n//~^ ERROR: link reference defined in list item\n///   inner text\n/// - [link]: def (title)\n//~^ ERROR: link reference defined in list item\n///   inner text\n/// - [link]: def \"title\"\n//~^ ERROR: link reference defined in list item\n///   inner text\n/// - [link]: not def\n///   inner text\n/// - [link][]: notdef\n///   inner text\n/// - [link]\\: notdef\n///   inner text\npub struct NotEmptyTight;\n\n/// ## Heading\n///\n/// - [x] - Done\n/// - [ ] - Not Done\npub struct GithubCheckboxes;\n"
  },
  {
    "path": "tests/ui/doc/doc_nested_refdef_list_item.stderr",
    "content": "error: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:4:7\n   |\nLL | /// - [link]: def\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\n   = note: `-D clippy::doc-nested-refdefs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_nested_refdefs)]`\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:7:7\n   |\nLL | /// - [link]: def (title)\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def (title)\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:10:7\n   |\nLL | /// - [link]: def \"title\"\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def \"title\"\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:21:7\n   |\nLL | /// - [link]: def\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:23:7\n   |\nLL | /// - [link]: def (title)\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def (title)\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:25:7\n   |\nLL | /// - [link]: def \"title\"\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def \"title\"\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:33:7\n   |\nLL | /// - [link]: def\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:37:7\n   |\nLL | /// - [link]: def (title)\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def (title)\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:41:7\n   |\nLL | /// - [link]: def \"title\"\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def \"title\"\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:56:7\n   |\nLL | /// - [link]: def\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:59:7\n   |\nLL | /// - [link]: def (title)\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def (title)\n   |             ++\n\nerror: link reference defined in list item\n  --> tests/ui/doc/doc_nested_refdef_list_item.rs:62:7\n   |\nLL | /// - [link]: def \"title\"\n   |       ^^^^^^\n   |\n   = help: link definitions are not shown in rendered documentation\nhelp: for an intra-doc link, add `[]` between the label and the colon\n   |\nLL | /// - [link][]: def \"title\"\n   |             ++\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_overindented_list_items.fixed",
    "content": "#![warn(clippy::doc_overindented_list_items)]\n\n#[rustfmt::skip]\n/// - first list item\n///   overindented line\n//~^ ERROR: doc list item overindented\n///   this is overindented line too\n//~^ ERROR: doc list item overindented\n/// - second list item\nfn foo() {}\n\n#[rustfmt::skip]\n///   - first list item\n///     overindented line\n//~^ ERROR: doc list item overindented\n///     this is overindented line too\n//~^ ERROR: doc list item overindented\n///   - second list item\nfn bar() {}\n\n#[rustfmt::skip]\n/// * first list item\n///   overindented line\n//~^ ERROR: doc list item overindented\n///   this is overindented line too\n//~^ ERROR: doc list item overindented\n/// * second list item\nfn baz() {}\n"
  },
  {
    "path": "tests/ui/doc/doc_overindented_list_items.rs",
    "content": "#![warn(clippy::doc_overindented_list_items)]\n\n#[rustfmt::skip]\n/// - first list item\n///        overindented line\n//~^ ERROR: doc list item overindented\n///      this is overindented line too\n//~^ ERROR: doc list item overindented\n/// - second list item\nfn foo() {}\n\n#[rustfmt::skip]\n///   - first list item\n///        overindented line\n//~^ ERROR: doc list item overindented\n///      this is overindented line too\n//~^ ERROR: doc list item overindented\n///   - second list item\nfn bar() {}\n\n#[rustfmt::skip]\n/// * first list item\n///        overindented line\n//~^ ERROR: doc list item overindented\n///      this is overindented line too\n//~^ ERROR: doc list item overindented\n/// * second list item\nfn baz() {}\n"
  },
  {
    "path": "tests/ui/doc/doc_overindented_list_items.stderr",
    "content": "error: doc list item overindented\n  --> tests/ui/doc/doc_overindented_list_items.rs:5:5\n   |\nLL | ///        overindented line\n   |     ^^^^^^^ help: try using `  ` (2 spaces)\n   |\n   = note: `-D clippy::doc-overindented-list-items` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_overindented_list_items)]`\n\nerror: doc list item overindented\n  --> tests/ui/doc/doc_overindented_list_items.rs:7:5\n   |\nLL | ///      this is overindented line too\n   |     ^^^^^ help: try using `  ` (2 spaces)\n\nerror: doc list item overindented\n  --> tests/ui/doc/doc_overindented_list_items.rs:14:7\n   |\nLL | ///        overindented line\n   |       ^^^^^ help: try using `  ` (2 spaces)\n\nerror: doc list item overindented\n  --> tests/ui/doc/doc_overindented_list_items.rs:16:7\n   |\nLL | ///      this is overindented line too\n   |       ^^^ help: try using `  ` (2 spaces)\n\nerror: doc list item overindented\n  --> tests/ui/doc/doc_overindented_list_items.rs:23:5\n   |\nLL | ///        overindented line\n   |     ^^^^^^^ help: try using `  ` (2 spaces)\n\nerror: doc list item overindented\n  --> tests/ui/doc/doc_overindented_list_items.rs:25:5\n   |\nLL | ///      this is overindented line too\n   |     ^^^^^ help: try using `  ` (2 spaces)\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_paragraphs_missing_punctuation.fixed",
    "content": "#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n#![warn(clippy::doc_paragraphs_missing_punctuation)]\n\n/// Returns the Answer to the Ultimate Question of Life, the Universe, and Everything.\n//~^ doc_paragraphs_missing_punctuation\nfn answer() -> i32 {\n    42\n}\n\n/// The `Option` type.\n//~^ doc_paragraphs_missing_punctuation\n// Triggers even in the presence of another attribute.\n#[derive(Debug)]\nenum MyOption<T> {\n    /// No value.\n    //~^ doc_paragraphs_missing_punctuation\n    None,\n    /// Some value of type `T`.\n    Some(T),\n}\n\n// Triggers correctly even when interleaved with other attributes.\n/// A multiline\n#[derive(Debug)]\n/// doc comment:\n/// only the last line triggers the lint.\n//~^ doc_paragraphs_missing_punctuation\nenum Exceptions {\n    /// Question marks are fine?\n    QuestionMark,\n    /// Exclamation marks are fine!\n    ExclamationMark,\n    /// Ellipses are ok too…\n    Ellipsis,\n    /// HTML content is however not checked:\n    /// <em>Raw HTML is allowed as well</em>\n    RawHtml,\n    /// The raw HTML exception actually does the right thing to autolinks:\n    /// <https://spec.commonmark.org/0.31.2/#autolinks>.\n    //~^ doc_paragraphs_missing_punctuation\n    MarkdownAutolink,\n    /// This table introduction ends with a colon:\n    ///\n    /// | Exception      | Note  |\n    /// | -------------- | ----- |\n    /// | Markdown table | A-ok  |\n    MarkdownTable,\n}\n\n// Check the lint can be expected on a whole enum at once.\n#[expect(clippy::doc_paragraphs_missing_punctuation)]\nenum Char {\n    /// U+0000\n    Null,\n    /// U+0001\n    StartOfHeading,\n}\n\n// Check the lint can be expected on a single variant without affecting others.\nenum Char2 {\n    #[expect(clippy::doc_paragraphs_missing_punctuation)]\n    /// U+0000\n    Null,\n    /// U+0001.\n    //~^ doc_paragraphs_missing_punctuation\n    StartOfHeading,\n}\n\nmod module {\n    //! Works on\n    //! inner attributes too.\n    //~^ doc_paragraphs_missing_punctuation\n}\n\nenum Trailers {\n    /// Sometimes the last sentence ends with parentheses (and that's ok).\n    ParensPassing,\n    /// (Sometimes the last sentence is in parentheses.)\n    SentenceInParensPassing,\n    /// **Sometimes the last sentence is in bold, and that's ok.**\n    DoubleStarPassing,\n    /// **But sometimes it is missing a period.**\n    //~^ doc_paragraphs_missing_punctuation\n    DoubleStarFailing,\n    /// _Sometimes the last sentence is in italics, and that's ok._\n    UnderscorePassing,\n    /// _But sometimes it is missing a period._\n    //~^ doc_paragraphs_missing_punctuation\n    UnderscoreFailing,\n    /// This comment ends with \"a quote.\"\n    AmericanStyleQuotePassing,\n    /// This comment ends with \"a quote\".\n    BritishStyleQuotePassing,\n}\n\n/// Doc comments can end with an [inline link](#anchor).\n//~^ doc_paragraphs_missing_punctuation\nstruct InlineLink;\n\n/// Some doc comments contain [link reference definitions][spec].\n//~^ doc_paragraphs_missing_punctuation\n///\n/// [spec]: https://spec.commonmark.org/0.31.2/#link-reference-definitions\nstruct LinkRefDefinition;\n\n// List items do not always need to end with a period.\nenum UnorderedLists {\n    /// This list has an introductory sentence:\n    ///\n    /// - A list item\n    Dash,\n    /// + A list item\n    Plus,\n    /// * A list item\n    Star,\n}\n\nenum OrderedLists {\n    /// 1. A list item\n    Dot,\n    /// 42) A list item\n    Paren,\n}\n\n/// Some elements do not have to be introduced by an independent clause.\nenum NotIndependentClause {\n    /// Lists are allowed to be introduced by a clause that is not independent: this usually\n    /// requires that\n    ///\n    /// - items end with a comma or a semicolon, which is not enforced;\n    /// - the last item end with a period, which is also not enforced.\n    List,\n    /// For instance, the function\n    ///\n    /// ```\n    /// fn answer() {}\n    /// ```\n    ///\n    /// returns the Answer to the Ultimate Question of Life, the Universe, and Everything.\n    CodeBlock,\n}\n\n/// Doc comments with trailing blank lines are supported.\n//~^ doc_paragraphs_missing_punctuation\n///\nstruct TrailingBlankLine;\n\n/// This doc comment has multiple paragraph.\n/// This first paragraph is missing punctuation.\n//~^ doc_paragraphs_missing_punctuation\n///\n/// The second one as well\n/// And it has multiple sentences.\n//~^ doc_paragraphs_missing_punctuation\n///\n/// Same for this third and last one.\n//~^ doc_paragraphs_missing_punctuation\nstruct MultiParagraphDocComment;\n\n/// ```\nstruct IncompleteBlockCode;\n\n/// This ends with a code `span`.\n//~^ doc_paragraphs_missing_punctuation\nstruct CodeSpan;\n\n#[expect(clippy::empty_docs)]\n///\nstruct EmptyDocComment;\n\n/**\n * Block doc comments work.\n *\n */\n//~^^^ doc_paragraphs_missing_punctuation\nstruct BlockDocComment;\n\n/// Sometimes a doc attribute is used for concatenation\n/// ```\n#[doc = \"\"]\n/// ```\nstruct DocAttribute;\n"
  },
  {
    "path": "tests/ui/doc/doc_paragraphs_missing_punctuation.rs",
    "content": "#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n#![warn(clippy::doc_paragraphs_missing_punctuation)]\n\n/// Returns the Answer to the Ultimate Question of Life, the Universe, and Everything\n//~^ doc_paragraphs_missing_punctuation\nfn answer() -> i32 {\n    42\n}\n\n/// The `Option` type\n//~^ doc_paragraphs_missing_punctuation\n// Triggers even in the presence of another attribute.\n#[derive(Debug)]\nenum MyOption<T> {\n    /// No value\n    //~^ doc_paragraphs_missing_punctuation\n    None,\n    /// Some value of type `T`.\n    Some(T),\n}\n\n// Triggers correctly even when interleaved with other attributes.\n/// A multiline\n#[derive(Debug)]\n/// doc comment:\n/// only the last line triggers the lint\n//~^ doc_paragraphs_missing_punctuation\nenum Exceptions {\n    /// Question marks are fine?\n    QuestionMark,\n    /// Exclamation marks are fine!\n    ExclamationMark,\n    /// Ellipses are ok too…\n    Ellipsis,\n    /// HTML content is however not checked:\n    /// <em>Raw HTML is allowed as well</em>\n    RawHtml,\n    /// The raw HTML exception actually does the right thing to autolinks:\n    /// <https://spec.commonmark.org/0.31.2/#autolinks>\n    //~^ doc_paragraphs_missing_punctuation\n    MarkdownAutolink,\n    /// This table introduction ends with a colon:\n    ///\n    /// | Exception      | Note  |\n    /// | -------------- | ----- |\n    /// | Markdown table | A-ok  |\n    MarkdownTable,\n}\n\n// Check the lint can be expected on a whole enum at once.\n#[expect(clippy::doc_paragraphs_missing_punctuation)]\nenum Char {\n    /// U+0000\n    Null,\n    /// U+0001\n    StartOfHeading,\n}\n\n// Check the lint can be expected on a single variant without affecting others.\nenum Char2 {\n    #[expect(clippy::doc_paragraphs_missing_punctuation)]\n    /// U+0000\n    Null,\n    /// U+0001\n    //~^ doc_paragraphs_missing_punctuation\n    StartOfHeading,\n}\n\nmod module {\n    //! Works on\n    //! inner attributes too\n    //~^ doc_paragraphs_missing_punctuation\n}\n\nenum Trailers {\n    /// Sometimes the last sentence ends with parentheses (and that's ok).\n    ParensPassing,\n    /// (Sometimes the last sentence is in parentheses.)\n    SentenceInParensPassing,\n    /// **Sometimes the last sentence is in bold, and that's ok.**\n    DoubleStarPassing,\n    /// **But sometimes it is missing a period**\n    //~^ doc_paragraphs_missing_punctuation\n    DoubleStarFailing,\n    /// _Sometimes the last sentence is in italics, and that's ok._\n    UnderscorePassing,\n    /// _But sometimes it is missing a period_\n    //~^ doc_paragraphs_missing_punctuation\n    UnderscoreFailing,\n    /// This comment ends with \"a quote.\"\n    AmericanStyleQuotePassing,\n    /// This comment ends with \"a quote\".\n    BritishStyleQuotePassing,\n}\n\n/// Doc comments can end with an [inline link](#anchor)\n//~^ doc_paragraphs_missing_punctuation\nstruct InlineLink;\n\n/// Some doc comments contain [link reference definitions][spec]\n//~^ doc_paragraphs_missing_punctuation\n///\n/// [spec]: https://spec.commonmark.org/0.31.2/#link-reference-definitions\nstruct LinkRefDefinition;\n\n// List items do not always need to end with a period.\nenum UnorderedLists {\n    /// This list has an introductory sentence:\n    ///\n    /// - A list item\n    Dash,\n    /// + A list item\n    Plus,\n    /// * A list item\n    Star,\n}\n\nenum OrderedLists {\n    /// 1. A list item\n    Dot,\n    /// 42) A list item\n    Paren,\n}\n\n/// Some elements do not have to be introduced by an independent clause.\nenum NotIndependentClause {\n    /// Lists are allowed to be introduced by a clause that is not independent: this usually\n    /// requires that\n    ///\n    /// - items end with a comma or a semicolon, which is not enforced;\n    /// - the last item end with a period, which is also not enforced.\n    List,\n    /// For instance, the function\n    ///\n    /// ```\n    /// fn answer() {}\n    /// ```\n    ///\n    /// returns the Answer to the Ultimate Question of Life, the Universe, and Everything.\n    CodeBlock,\n}\n\n/// Doc comments with trailing blank lines are supported\n//~^ doc_paragraphs_missing_punctuation\n///\nstruct TrailingBlankLine;\n\n/// This doc comment has multiple paragraph.\n/// This first paragraph is missing punctuation\n//~^ doc_paragraphs_missing_punctuation\n///\n/// The second one as well\n/// And it has multiple sentences\n//~^ doc_paragraphs_missing_punctuation\n///\n/// Same for this third and last one\n//~^ doc_paragraphs_missing_punctuation\nstruct MultiParagraphDocComment;\n\n/// ```\nstruct IncompleteBlockCode;\n\n/// This ends with a code `span`\n//~^ doc_paragraphs_missing_punctuation\nstruct CodeSpan;\n\n#[expect(clippy::empty_docs)]\n///\nstruct EmptyDocComment;\n\n/**\n * Block doc comments work\n *\n */\n//~^^^ doc_paragraphs_missing_punctuation\nstruct BlockDocComment;\n\n/// Sometimes a doc attribute is used for concatenation\n/// ```\n#[doc = \"\"]\n/// ```\nstruct DocAttribute;\n"
  },
  {
    "path": "tests/ui/doc/doc_paragraphs_missing_punctuation.stderr",
    "content": "error: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:5:86\n   |\nLL | /// Returns the Answer to the Ultimate Question of Life, the Universe, and Everything\n   |                                                                                      ^ help: end the paragraph with some punctuation: `.`\n   |\n   = note: `-D clippy::doc-paragraphs-missing-punctuation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_paragraphs_missing_punctuation)]`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:11:22\n   |\nLL | /// The `Option` type\n   |                      ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:16:17\n   |\nLL |     /// No value\n   |                 ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:27:41\n   |\nLL | /// only the last line triggers the lint\n   |                                         ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:40:56\n   |\nLL |     /// <https://spec.commonmark.org/0.31.2/#autolinks>\n   |                                                        ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:65:15\n   |\nLL |     /// U+0001\n   |               ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:72:29\n   |\nLL |     //! inner attributes too\n   |                             ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:83:47\n   |\nLL |     /// **But sometimes it is missing a period**\n   |                                               ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:88:46\n   |\nLL |     /// _But sometimes it is missing a period_\n   |                                              ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:97:56\n   |\nLL | /// Doc comments can end with an [inline link](#anchor)\n   |                                                        ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:101:65\n   |\nLL | /// Some doc comments contain [link reference definitions][spec]\n   |                                                                 ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:144:57\n   |\nLL | /// Doc comments with trailing blank lines are supported\n   |                                                         ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:150:48\n   |\nLL | /// This first paragraph is missing punctuation\n   |                                                ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:154:34\n   |\nLL | /// And it has multiple sentences\n   |                                  ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:157:37\n   |\nLL | /// Same for this third and last one\n   |                                     ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:164:33\n   |\nLL | /// This ends with a code `span`\n   |                                 ^ help: end the paragraph with some punctuation: `.`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation.rs:173:27\n   |\nLL |  * Block doc comments work\n   |                           ^ help: end the paragraph with some punctuation: `.`\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/doc_paragraphs_missing_punctuation_emoji.rs",
    "content": "#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n#![warn(clippy::doc_paragraphs_missing_punctuation)]\n//@no-rustfix\n\nenum EmojiTrailers {\n    /// Sometimes the doc comment ends with an emoji! 😅\n    ExistingPunctuationBeforeEmoji,\n    /// But it may still be missing punctuation 😢\n    //~^ doc_paragraphs_missing_punctuation\n    MissingPunctuationBeforeEmoji,\n}\n"
  },
  {
    "path": "tests/ui/doc/doc_paragraphs_missing_punctuation_emoji.stderr",
    "content": "error: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation_emoji.rs:9:50\n   |\nLL |     /// But it may still be missing punctuation 😢\n   |                                                   ^ help: end the paragraph with some punctuation: `.`\n   |\n   = note: `-D clippy::doc-paragraphs-missing-punctuation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_paragraphs_missing_punctuation)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs",
    "content": "#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n#![warn(clippy::doc_paragraphs_missing_punctuation)]\n//@no-rustfix\n\nenum UnfixableTrailers {\n    /// Sometimes the doc comment ends with parentheses (like this)\n    //~^ doc_paragraphs_missing_punctuation\n    EndsWithParens,\n    /// This comment ends with \"a quote\"\n    //~^ doc_paragraphs_missing_punctuation\n    QuoteFailing,\n}\n"
  },
  {
    "path": "tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.stderr",
    "content": "error: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs:7:68\n   |\nLL |     /// Sometimes the doc comment ends with parentheses (like this)\n   |                                                                    ^\n   |\n   = help: end the paragraph with some punctuation\n   = note: `-D clippy::doc-paragraphs-missing-punctuation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_paragraphs_missing_punctuation)]`\n\nerror: doc paragraphs should end with a terminal punctuation mark\n  --> tests/ui/doc/doc_paragraphs_missing_punctuation_unfixable.rs:10:41\n   |\nLL |     /// This comment ends with \"a quote\"\n   |                                         ^\n   |\n   = help: end the paragraph with some punctuation\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/footnote_issue_13183.rs",
    "content": "//@ check-pass\n// This is a regression test for <https://github.com/rust-lang/rust-clippy/issues/13183>.\n// It should not warn on missing backticks on footnote references.\n\n#![warn(clippy::doc_markdown)]\n// Should not warn!\n//! Here's a footnote[^example_footnote_identifier]\n//!\n//! [^example_footnote_identifier]: This is merely an example.\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/doc/issue_10262.fixed",
    "content": "#![warn(clippy::doc_markdown)]\n\n// Should only warn for the first line!\n/// `AviSynth` documentation:\n//~^ ERROR: item in documentation is missing backticks\n///\n/// > AvisynthPluginInit3 may be called more than once with different IScriptEnvironments.\n///\n/// <blockquote>bla AvisynthPluginInit3 bla</blockquote>\n///\n/// <q>bla AvisynthPluginInit3 bla</q>\npub struct Foo;\n"
  },
  {
    "path": "tests/ui/doc/issue_10262.rs",
    "content": "#![warn(clippy::doc_markdown)]\n\n// Should only warn for the first line!\n/// AviSynth documentation:\n//~^ ERROR: item in documentation is missing backticks\n///\n/// > AvisynthPluginInit3 may be called more than once with different IScriptEnvironments.\n///\n/// <blockquote>bla AvisynthPluginInit3 bla</blockquote>\n///\n/// <q>bla AvisynthPluginInit3 bla</q>\npub struct Foo;\n"
  },
  {
    "path": "tests/ui/doc/issue_10262.stderr",
    "content": "error: item in documentation is missing backticks\n  --> tests/ui/doc/issue_10262.rs:4:5\n   |\nLL | /// AviSynth documentation:\n   |     ^^^^^^^^\n   |\n   = note: `-D clippy::doc-markdown` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`\nhelp: try\n   |\nLL - /// AviSynth documentation:\nLL + /// `AviSynth` documentation:\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/doc/issue_12795.fixed",
    "content": "#![warn(clippy::doc_markdown)]\n\n//! A comment with `a_b(x)` and `a_c` in it and (`a_b((c))` ) too and (maybe `a_b((c))`)\n//~^ doc_markdown\n//~| doc_markdown\n//~| doc_markdown\n//~| doc_markdown\n\npub fn main() {}\n"
  },
  {
    "path": "tests/ui/doc/issue_12795.rs",
    "content": "#![warn(clippy::doc_markdown)]\n\n//! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\n//~^ doc_markdown\n//~| doc_markdown\n//~| doc_markdown\n//~| doc_markdown\n\npub fn main() {}\n"
  },
  {
    "path": "tests/ui/doc/issue_12795.stderr",
    "content": "error: item in documentation is missing backticks\n  --> tests/ui/doc/issue_12795.rs:3:20\n   |\nLL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\n   |                    ^^^^^^\n   |\n   = note: `-D clippy::doc-markdown` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`\nhelp: try\n   |\nLL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\nLL + //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/issue_12795.rs:3:31\n   |\nLL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\n   |                               ^^^\n   |\nhelp: try\n   |\nLL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\nLL + //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c)))\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/issue_12795.rs:3:46\n   |\nLL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\n   |                                              ^^^^^^^^\n   |\nhelp: try\n   |\nLL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\nLL + //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c)))\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/issue_12795.rs:3:72\n   |\nLL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\n   |                                                                        ^^^^^^^^\n   |\nhelp: try\n   |\nLL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))\nLL + //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`)\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/issue_1832.rs",
    "content": "//@ check-pass\n/// Ok: <http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels>\n///\n/// Not ok: http://www.unicode.org\n/// Not ok: https://www.unicode.org\n/// Not ok: http://www.unicode.org/\n/// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels\nfn issue_1832() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/doc/issue_902.rs",
    "content": "//@ check-pass\n/// See [NIST SP 800-56A, revision 2].\n///\n/// [NIST SP 800-56A, revision 2]:\n///     https://github.com/rust-lang/rust-clippy/issues/902#issuecomment-261919419\nfn issue_902_comment() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/doc/issue_9473.fixed",
    "content": "#![warn(clippy::doc_markdown)]\n\n// Should not warn!\n/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>.\npub struct Foo(u32);\n\n// Should warn.\n/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[`FooBar`].\n//~^ doc_markdown\npub struct FooBar(u32);\n"
  },
  {
    "path": "tests/ui/doc/issue_9473.rs",
    "content": "#![warn(clippy::doc_markdown)]\n\n// Should not warn!\n/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>.\npub struct Foo(u32);\n\n// Should warn.\n/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].\n//~^ doc_markdown\npub struct FooBar(u32);\n"
  },
  {
    "path": "tests/ui/doc/issue_9473.stderr",
    "content": "error: item in documentation is missing backticks\n  --> tests/ui/doc/issue_9473.rs:8:58\n   |\nLL | /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].\n   |                                                          ^^^^^^\n   |\n   = note: `-D clippy::doc-markdown` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`\nhelp: try\n   |\nLL - /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].\nLL + /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[`FooBar`].\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/doc/link_adjacent.fixed",
    "content": "#![warn(clippy::doc_link_code)]\n\n//! Test case for code links that are adjacent to code text.\n//!\n//! This is not an example: `first``second`\n//!\n//! Neither is this: [`first`](x)\n//!\n//! Neither is this: [`first`](x) `second`\n//!\n//! Neither is this: [first](x)`second`\n//!\n//! This is: <code>[first](x)second</code>\n//~^ ERROR: adjacent\n//!\n//! So is this <code>first[second](x)</code>\n//~^ ERROR: adjacent\n//!\n//! So is this <code>[first](x)[second](x)</code>\n//~^ ERROR: adjacent\n//!\n//! So is this <code>[first](x)[second](x)[third](x)</code>\n//~^ ERROR: adjacent\n//!\n//! So is this <code>[first](x)second[third](x)</code>\n//~^ ERROR: adjacent\n\n/// Test case for code links that are adjacent to code text.\n///\n/// This is not an example: `first``second` arst\n///\n/// Neither is this: [`first`](x) arst\n///\n/// Neither is this: [`first`](x) `second` arst\n///\n/// Neither is this: [first](x)`second` arst\n///\n/// This is: <code>[first](x)second</code> arst\n//~^ ERROR: adjacent\n///\n/// So is this <code>first[second](x)</code> arst\n//~^ ERROR: adjacent\n///\n/// So is this <code>[first](x)[second](x)</code> arst\n//~^ ERROR: adjacent\n///\n/// So is this <code>[first](x)[second](x)[third](x)</code> arst\n//~^ ERROR: adjacent\n///\n/// So is this <code>[first](x)second[third](x)</code> arst\n//~^ ERROR: adjacent\npub struct WithTrailing;\n"
  },
  {
    "path": "tests/ui/doc/link_adjacent.rs",
    "content": "#![warn(clippy::doc_link_code)]\n\n//! Test case for code links that are adjacent to code text.\n//!\n//! This is not an example: `first``second`\n//!\n//! Neither is this: [`first`](x)\n//!\n//! Neither is this: [`first`](x) `second`\n//!\n//! Neither is this: [first](x)`second`\n//!\n//! This is: [`first`](x)`second`\n//~^ ERROR: adjacent\n//!\n//! So is this `first`[`second`](x)\n//~^ ERROR: adjacent\n//!\n//! So is this [`first`](x)[`second`](x)\n//~^ ERROR: adjacent\n//!\n//! So is this [`first`](x)[`second`](x)[`third`](x)\n//~^ ERROR: adjacent\n//!\n//! So is this [`first`](x)`second`[`third`](x)\n//~^ ERROR: adjacent\n\n/// Test case for code links that are adjacent to code text.\n///\n/// This is not an example: `first``second` arst\n///\n/// Neither is this: [`first`](x) arst\n///\n/// Neither is this: [`first`](x) `second` arst\n///\n/// Neither is this: [first](x)`second` arst\n///\n/// This is: [`first`](x)`second` arst\n//~^ ERROR: adjacent\n///\n/// So is this `first`[`second`](x) arst\n//~^ ERROR: adjacent\n///\n/// So is this [`first`](x)[`second`](x) arst\n//~^ ERROR: adjacent\n///\n/// So is this [`first`](x)[`second`](x)[`third`](x) arst\n//~^ ERROR: adjacent\n///\n/// So is this [`first`](x)`second`[`third`](x) arst\n//~^ ERROR: adjacent\npub struct WithTrailing;\n"
  },
  {
    "path": "tests/ui/doc/link_adjacent.stderr",
    "content": "error: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:13:14\n   |\nLL | //! This is: [`first`](x)`second`\n   |              ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\n   = note: `-D clippy::doc-link-code` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_link_code)]`\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - //! This is: [`first`](x)`second`\nLL + //! This is: <code>[first](x)second</code>\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:16:16\n   |\nLL | //! So is this `first`[`second`](x)\n   |                ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - //! So is this `first`[`second`](x)\nLL + //! So is this <code>first[second](x)</code>\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:19:16\n   |\nLL | //! So is this [`first`](x)[`second`](x)\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - //! So is this [`first`](x)[`second`](x)\nLL + //! So is this <code>[first](x)[second](x)</code>\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:22:16\n   |\nLL | //! So is this [`first`](x)[`second`](x)[`third`](x)\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - //! So is this [`first`](x)[`second`](x)[`third`](x)\nLL + //! So is this <code>[first](x)[second](x)[third](x)</code>\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:25:16\n   |\nLL | //! So is this [`first`](x)`second`[`third`](x)\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - //! So is this [`first`](x)`second`[`third`](x)\nLL + //! So is this <code>[first](x)second[third](x)</code>\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:38:14\n   |\nLL | /// This is: [`first`](x)`second` arst\n   |              ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - /// This is: [`first`](x)`second` arst\nLL + /// This is: <code>[first](x)second</code> arst\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:41:16\n   |\nLL | /// So is this `first`[`second`](x) arst\n   |                ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - /// So is this `first`[`second`](x) arst\nLL + /// So is this <code>first[second](x)</code> arst\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:44:16\n   |\nLL | /// So is this [`first`](x)[`second`](x) arst\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - /// So is this [`first`](x)[`second`](x) arst\nLL + /// So is this <code>[first](x)[second](x)</code> arst\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:47:16\n   |\nLL | /// So is this [`first`](x)[`second`](x)[`third`](x) arst\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - /// So is this [`first`](x)[`second`](x)[`third`](x) arst\nLL + /// So is this <code>[first](x)[second](x)[third](x)</code> arst\n   |\n\nerror: code link adjacent to code text\n  --> tests/ui/doc/link_adjacent.rs:50:16\n   |\nLL | /// So is this [`first`](x)`second`[`third`](x) arst\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: separate code snippets will be shown with a gap\nhelp: wrap the entire group in `<code>` tags\n   |\nLL - /// So is this [`first`](x)`second`[`third`](x) arst\nLL + /// So is this <code>[first](x)second[third](x)</code> arst\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/needless_doctest_main.rs",
    "content": "#![warn(clippy::needless_doctest_main)]\n\n/// Description\n/// ```rust\n/// fn main() {\n//~^ needless_doctest_main\n///     let a = 0;\n/// }\n/// ```\nfn mulpipulpi() {}\n\n/// With a `#[no_main]`\n/// ```rust\n/// #[no_main]\n/// fn a() {\n///     let _ = 0;\n/// }\n/// ```\nfn pulpimulpi() {}\n\n// Without a `#[no_main]` attribute\n/// ```rust\n/// fn a() {\n///     let _ = 0;\n/// }\n/// ```\nfn plumilupi() {}\n\n/// Additional function, shouldn't trigger\n/// ```rust\n/// fn additional_function() {\n///     let _ = 0;\n///     // Thus `fn main` is actually relevant!\n/// }\n/// fn main() {\n///     let _ = 0;\n/// }\n/// ```\nfn mlupipupi() {}\n\n/// Additional function AFTER main, shouldn't trigger\n/// ```rust\n/// fn main() {\n///     let _ = 0;\n/// }\n/// fn additional_function() {\n///     let _ = 0;\n///     // Thus `fn main` is actually relevant!\n/// }\n/// ```\nfn lumpimupli() {}\n\n/// Ignore code block, should not lint at all\n/// ```rust, ignore\n/// fn main() {\n///     // Hi!\n///     let _ = 0;\n/// }\n/// ```\nfn mpulpilumi() {}\n\n/// Spaces in weird positions (including an \\u{A0} after `main`)\n/// ```rust\n/// fn     main (){\n//~^ needless_doctest_main\n///     let _ = 0;\n/// }\n/// ```\nfn plumpiplupi() {}\n\n/// 4 Functions, this should not lint because there are several function\n///\n/// ```rust\n/// fn a() {let _ = 0; }\n/// fn b() {let _ = 0; }\n/// fn main() { let _ = 0; }\n/// fn d() { let _ = 0; }\n/// ```\nfn pulmipulmip() {}\n\n/// 3 Functions but main is first, should also not lint\n///\n///```rust\n/// fn main() { let _ = 0; }\n/// fn b() { let _ = 0; }\n/// fn c() { let _ = 0; }\n/// ```\nfn pmuplimulip() {}\n\nfn main() {}\n\nfn issue8244() -> Result<(), ()> {\n    //! ```compile_fail\n    //! fn test() -> Result< {}\n    //! ```\n    Ok(())\n}\n\n/// # Examples\n///\n/// ```\n/// use std::error::Error;\n/// fn main() -> Result<(), Box<dyn Error>/* > */ {\n/// }\n/// ```\nfn issue15041() {}\n"
  },
  {
    "path": "tests/ui/doc/needless_doctest_main.stderr",
    "content": "error: needless `fn main` in doctest\n  --> tests/ui/doc/needless_doctest_main.rs:5:5\n   |\nLL | /// fn main() {\n   |     ^^^^^^^\n   |\n   = note: `-D clippy::needless-doctest-main` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_doctest_main)]`\n\nerror: needless `fn main` in doctest\n  --> tests/ui/doc/needless_doctest_main.rs:64:5\n   |\nLL | /// fn     main (){\n   |     ^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc/unbalanced_ticks.rs",
    "content": "//! This file tests for the `DOC_MARKDOWN` lint, specifically cases\n//! where ticks are unbalanced (see issue #6753).\n//@no-rustfix\n#![allow(dead_code)]\n#![warn(clippy::doc_markdown)]\n\n/// This is a doc comment with `unbalanced_tick marks and several words that\n//~^ doc_markdown\n/// should be `encompassed_by` tick marks because they `contain_underscores`.\n/// Because of the initial `unbalanced_tick` pair, the error message is\n/// very `confusing_and_misleading`.\nfn main() {}\n\n/// This paragraph has `unbalanced_tick marks and should stop_linting.\n//~^ doc_markdown\n///\n/// This paragraph is fine and should_be linted normally.\n//~^ doc_markdown\n///\n/// Double unbalanced backtick from ``here to here` should lint.\n//~^ doc_markdown\n///\n/// Double balanced back ticks ``start end`` is fine.\nfn multiple_paragraphs() {}\n\n/// ```\n/// // Unbalanced tick mark in code block shouldn't warn:\n/// `\n/// ```\nfn in_code_block() {}\n\n/// # `Fine`\n///\n/// ## not_fine\n//~^ doc_markdown\n///\n/// ### `unbalanced\n//~^ doc_markdown\n///\n/// - This `item has unbalanced tick marks\n//~^ doc_markdown\n/// - This item needs backticks_here\n//~^ doc_markdown\nfn other_markdown() {}\n\n#[rustfmt::skip]\n/// - ```rust\n///   /// `lol`\n///   pub struct Struct;\n///   ```\nfn issue_7421() {}\n\n/// `\n//~^ doc_markdown\nfn escape_0() {}\n\n/// Escaped \\` backticks don't count.\nfn escape_1() {}\n\n/// Escaped \\` \\` backticks don't count.\nfn escape_2() {}\n\n/// Escaped \\` ` backticks don't count, but unescaped backticks do.\n//~^ doc_markdown\nfn escape_3() {}\n\n/// Backslashes ` \\` within code blocks don't count.\nfn escape_4() {}\n\ntrait Foo {\n    fn bar();\n}\n\nstruct Bar;\nimpl Foo for Bar {\n    // NOTE: false positive\n    /// Returns an `Option<Month>` from a i64, assuming a 1-index, January = 1.\n    ///\n    /// `Month::from_i64(n: i64)`: | `1`                  | `2`                   | ... | `12`\n    /// ---------------------------| -------------------- | --------------------- | ... | -----\n    /// ``:                        | Some(Month::January) | Some(Month::February) | ... |\n    /// Some(Month::December)\n    //~^^^^ doc_markdown\n    fn bar() {}\n}\n"
  },
  {
    "path": "tests/ui/doc/unbalanced_ticks.stderr",
    "content": "error: backticks are unbalanced\n  --> tests/ui/doc/unbalanced_ticks.rs:7:5\n   |\nLL |   /// This is a doc comment with `unbalanced_tick marks and several words that\n   |  _____^\nLL | |\nLL | | /// should be `encompassed_by` tick marks because they `contain_underscores`.\nLL | | /// Because of the initial `unbalanced_tick` pair, the error message is\nLL | | /// very `confusing_and_misleading`.\n   | |____________________________________^\n   |\n   = help: a backtick may be missing a pair\n   = note: `-D clippy::doc-markdown` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`\n\nerror: backticks are unbalanced\n  --> tests/ui/doc/unbalanced_ticks.rs:14:5\n   |\nLL | /// This paragraph has `unbalanced_tick marks and should stop_linting.\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: a backtick may be missing a pair\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/unbalanced_ticks.rs:17:32\n   |\nLL | /// This paragraph is fine and should_be linted normally.\n   |                                ^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// This paragraph is fine and should_be linted normally.\nLL + /// This paragraph is fine and `should_be` linted normally.\n   |\n\nerror: backticks are unbalanced\n  --> tests/ui/doc/unbalanced_ticks.rs:20:5\n   |\nLL | /// Double unbalanced backtick from ``here to here` should lint.\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: a backtick may be missing a pair\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/unbalanced_ticks.rs:34:8\n   |\nLL | /// ## not_fine\n   |        ^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// ## not_fine\nLL + /// ## `not_fine`\n   |\n\nerror: backticks are unbalanced\n  --> tests/ui/doc/unbalanced_ticks.rs:37:5\n   |\nLL | /// ### `unbalanced\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: a backtick may be missing a pair\n\nerror: backticks are unbalanced\n  --> tests/ui/doc/unbalanced_ticks.rs:40:5\n   |\nLL | /// - This `item has unbalanced tick marks\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: a backtick may be missing a pair\n\nerror: item in documentation is missing backticks\n  --> tests/ui/doc/unbalanced_ticks.rs:42:23\n   |\nLL | /// - This item needs backticks_here\n   |                       ^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// - This item needs backticks_here\nLL + /// - This item needs `backticks_here`\n   |\n\nerror: backticks are unbalanced\n  --> tests/ui/doc/unbalanced_ticks.rs:53:5\n   |\nLL | /// `\n   |     ^\n   |\n   = help: a backtick may be missing a pair\n\nerror: backticks are unbalanced\n  --> tests/ui/doc/unbalanced_ticks.rs:63:5\n   |\nLL | /// Escaped \\` ` backticks don't count, but unescaped backticks do.\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: a backtick may be missing a pair\n\nerror: backticks are unbalanced\n  --> tests/ui/doc/unbalanced_ticks.rs:79:9\n   |\nLL |       /// `Month::from_i64(n: i64)`: | `1`                  | `2`                   | ... | `12`\n   |  _________^\nLL | |     /// ---------------------------| -------------------- | --------------------- | ... | -----\nLL | |     /// ``:                        | Some(Month::January) | Some(Month::February) | ... |\nLL | |     /// Some(Month::December)\n   | |_____________________________^\n   |\n   = help: a backtick may be missing a pair\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc_broken_link.rs",
    "content": "#![warn(clippy::doc_broken_link)]\n\nfn main() {}\n\npub struct FakeType {}\n\n/// This might be considered a link false positive\n/// and should be ignored by this lint rule:\n/// Example of referencing some code with brackets [FakeType].\npub fn doc_ignore_link_false_positive_1() {}\n\n/// This might be considered a link false positive\n/// and should be ignored by this lint rule:\n/// [`FakeType`]. Continue text after brackets,\n/// then (something in\n/// parenthesis).\npub fn doc_ignore_link_false_positive_2() {}\n\n/// Test valid link, whole link single line.\n/// [doc valid link](https://test.fake/doc_valid_link)\npub fn doc_valid_link() {}\n\n/// Test valid link, whole link single line but it has special chars such as brackets and\n/// parenthesis. [doc invalid link url invalid char](https://test.fake/doc_valid_link_url_invalid_char?foo[bar]=1&bar(foo)=2)\npub fn doc_valid_link_url_invalid_char() {}\n\n/// Test valid link, text tag broken across multiple lines.\n/// [doc valid link broken\n/// text](https://test.fake/doc_valid_link_broken_text)\npub fn doc_valid_link_broken_text() {}\n\n/// Test valid link, url tag broken across multiple lines, but\n/// the whole url part in a single line.\n/// [doc valid link broken url tag two lines first](https://test.fake/doc_valid_link_broken_url_tag_two_lines_first\n/// )\npub fn doc_valid_link_broken_url_tag_two_lines_first() {}\n\n/// Test valid link, url tag broken across multiple lines, but\n/// the whole url part in a single line.\n/// [doc valid link broken url tag two lines second](\n/// https://test.fake/doc_valid_link_broken_url_tag_two_lines_second)\npub fn doc_valid_link_broken_url_tag_two_lines_second() {}\n\n/// Test valid link, url tag broken across multiple lines, but\n/// the whole url part in a single line, but the closing pharentesis\n/// in a third line.\n/// [doc valid link broken url tag three lines](\n/// https://test.fake/doc_valid_link_broken_url_tag_three_lines\n/// )\npub fn doc_valid_link_broken_url_tag_three_lines() {}\n\n/// Test invalid link, url part broken across multiple lines.\n/// [doc invalid link broken url scheme part](https://\n/// test.fake/doc_invalid_link_broken_url_scheme_part)\n//~^^ ERROR: possible broken doc link: broken across multiple lines\npub fn doc_invalid_link_broken_url_scheme_part() {}\n\n/// Test invalid link, url part broken across multiple lines.\n/// [doc invalid link broken url host part](https://test\n/// .fake/doc_invalid_link_broken_url_host_part)\n//~^^ ERROR: possible broken doc link: broken across multiple lines\npub fn doc_invalid_link_broken_url_host_part() {}\n\n/// Test invalid link, for multiple urls in the same block of comment.\n/// There is a [fist link - invalid](https://test\n/// .fake) then it continues\n//~^^ ERROR: possible broken doc link: broken across multiple lines\n/// with a [second link - valid](https://test.fake/doc_valid_link) and another [third link - invalid](https://test\n/// .fake). It ends with another\n//~^^ ERROR: possible broken doc link: broken across multiple lines\n/// line of comment.\npub fn doc_multiple_invalid_link_broken_url() {}\n"
  },
  {
    "path": "tests/ui/doc_broken_link.stderr",
    "content": "error: possible broken doc link: broken across multiple lines\n  --> tests/ui/doc_broken_link.rs:53:5\n   |\nLL | /// [doc invalid link broken url scheme part](https://\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::doc-broken-link` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_broken_link)]`\n\nerror: possible broken doc link: broken across multiple lines\n  --> tests/ui/doc_broken_link.rs:59:5\n   |\nLL | /// [doc invalid link broken url host part](https://test\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: possible broken doc link: broken across multiple lines\n  --> tests/ui/doc_broken_link.rs:65:16\n   |\nLL | /// There is a [fist link - invalid](https://test\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: possible broken doc link: broken across multiple lines\n  --> tests/ui/doc_broken_link.rs:68:80\n   |\nLL | /// with a [second link - valid](https://test.fake/doc_valid_link) and another [third link - invalid](https://test\n   |                                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc_errors.rs",
    "content": "#![warn(clippy::missing_errors_doc)]\n#![allow(clippy::result_unit_err)]\n#![allow(clippy::unnecessary_wraps)]\n\nuse std::io;\n\npub fn pub_fn_missing_errors_header() -> Result<(), ()> {\n    //~^ missing_errors_doc\n\n    unimplemented!();\n}\n\npub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> {\n    //~^ missing_errors_doc\n\n    unimplemented!();\n}\n\n/// This is not sufficiently documented.\npub fn pub_fn_returning_io_result() -> io::Result<()> {\n    //~^ missing_errors_doc\n\n    unimplemented!();\n}\n\n/// This is not sufficiently documented.\npub async fn async_pub_fn_returning_io_result() -> io::Result<()> {\n    //~^ missing_errors_doc\n\n    unimplemented!();\n}\n\n/// # Errors\n/// A description of the errors goes here.\npub fn pub_fn_with_errors_header() -> Result<(), ()> {\n    unimplemented!();\n}\n\n/// # Errors\n/// A description of the errors goes here.\npub async fn async_pub_fn_with_errors_header() -> Result<(), ()> {\n    unimplemented!();\n}\n\n/// This function doesn't require the documentation because it is private\nfn priv_fn_missing_errors_header() -> Result<(), ()> {\n    unimplemented!();\n}\n\n/// This function doesn't require the documentation because it is private\nasync fn async_priv_fn_missing_errors_header() -> Result<(), ()> {\n    unimplemented!();\n}\n\npub struct Struct1;\n\nimpl Struct1 {\n    /// This is not sufficiently documented.\n    pub fn pub_method_missing_errors_header() -> Result<(), ()> {\n        //~^ missing_errors_doc\n\n        unimplemented!();\n    }\n\n    /// This is not sufficiently documented.\n    pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> {\n        //~^ missing_errors_doc\n\n        unimplemented!();\n    }\n\n    /// # Errors\n    /// A description of the errors goes here.\n    pub fn pub_method_with_errors_header() -> Result<(), ()> {\n        unimplemented!();\n    }\n\n    /// # Errors\n    /// A description of the errors goes here.\n    pub async fn async_pub_method_with_errors_header() -> Result<(), ()> {\n        unimplemented!();\n    }\n\n    /// This function doesn't require the documentation because it is private.\n    fn priv_method_missing_errors_header() -> Result<(), ()> {\n        unimplemented!();\n    }\n\n    /// This function doesn't require the documentation because it is private.\n    async fn async_priv_method_missing_errors_header() -> Result<(), ()> {\n        unimplemented!();\n    }\n\n    /**\n    # Errors\n    A description of the errors goes here.\n    */\n    fn block_comment() -> Result<(), ()> {\n        unimplemented!();\n    }\n\n    /**\n     * # Errors\n     * A description of the errors goes here.\n     */\n    fn block_comment_leading_asterisks() -> Result<(), ()> {\n        unimplemented!();\n    }\n\n    #[doc(hidden)]\n    fn doc_hidden() -> Result<(), ()> {\n        unimplemented!();\n    }\n}\n\npub trait Trait1 {\n    /// This is not sufficiently documented.\n    fn trait_method_missing_errors_header() -> Result<(), ()>;\n    //~^ missing_errors_doc\n\n    /// # Errors\n    /// A description of the errors goes here.\n    fn trait_method_with_errors_header() -> Result<(), ()>;\n\n    #[doc(hidden)]\n    fn doc_hidden() -> Result<(), ()> {\n        unimplemented!();\n    }\n}\n\nimpl Trait1 for Struct1 {\n    fn trait_method_missing_errors_header() -> Result<(), ()> {\n        unimplemented!();\n    }\n\n    fn trait_method_with_errors_header() -> Result<(), ()> {\n        unimplemented!();\n    }\n}\n\n#[doc(hidden)]\npub trait DocHidden {\n    fn f() -> Result<(), ()>;\n}\n\nfn main() -> Result<(), ()> {\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/doc_errors.stderr",
    "content": "error: docs for function returning `Result` missing `# Errors` section\n  --> tests/ui/doc_errors.rs:7:1\n   |\nLL | pub fn pub_fn_missing_errors_header() -> Result<(), ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::missing-errors-doc` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_errors_doc)]`\n\nerror: docs for function returning `Result` missing `# Errors` section\n  --> tests/ui/doc_errors.rs:13:1\n   |\nLL | pub async fn async_pub_fn_missing_errors_header() -> Result<(), ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function returning `Result` missing `# Errors` section\n  --> tests/ui/doc_errors.rs:20:1\n   |\nLL | pub fn pub_fn_returning_io_result() -> io::Result<()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function returning `Result` missing `# Errors` section\n  --> tests/ui/doc_errors.rs:27:1\n   |\nLL | pub async fn async_pub_fn_returning_io_result() -> io::Result<()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function returning `Result` missing `# Errors` section\n  --> tests/ui/doc_errors.rs:59:5\n   |\nLL |     pub fn pub_method_missing_errors_header() -> Result<(), ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function returning `Result` missing `# Errors` section\n  --> tests/ui/doc_errors.rs:66:5\n   |\nLL |     pub async fn async_pub_method_missing_errors_header() -> Result<(), ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function returning `Result` missing `# Errors` section\n  --> tests/ui/doc_errors.rs:118:5\n   |\nLL |     fn trait_method_missing_errors_header() -> Result<(), ()>;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc_link_with_quotes.rs",
    "content": "#![warn(clippy::doc_link_with_quotes)]\n\nfn main() {}\n\n/// Calls ['bar'] uselessly\n//~^ doc_link_with_quotes\npub fn foo() {\n    bar()\n}\n\n/// Calls [\"bar\"] uselessly\n//~^ doc_link_with_quotes\npub fn foo2() {\n    bar()\n}\n\n/// # Examples\n/// This demonstrates issue \\#8961\n/// ```\n/// let _ = vec!['w', 'a', 't'];\n/// ```\npub fn bar() {}\n"
  },
  {
    "path": "tests/ui/doc_link_with_quotes.stderr",
    "content": "error: possible intra-doc link using quotes instead of backticks\n  --> tests/ui/doc_link_with_quotes.rs:5:12\n   |\nLL | /// Calls ['bar'] uselessly\n   |            ^^^^^\n   |\n   = note: `-D clippy::doc-link-with-quotes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_link_with_quotes)]`\n\nerror: possible intra-doc link using quotes instead of backticks\n  --> tests/ui/doc_link_with_quotes.rs:11:12\n   |\nLL | /// Calls [\"bar\"] uselessly\n   |            ^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc_suspicious_footnotes.fixed",
    "content": "#![warn(clippy::doc_suspicious_footnotes)]\n#![allow(clippy::needless_raw_string_hashes)]\n//! This is not a footnote[^1].\n//!\n//! [^1]: <!-- description -->\n//~^ doc_suspicious_footnotes\n//!\n//! This is not a footnote[^either], but it doesn't warn.\n//!\n//! This is not a footnote\\[^1], but it also doesn't warn.\n//!\n//! This is not a footnote[^1\\], but it also doesn't warn.\n//!\n//! This is not a `footnote[^1]`, but it also doesn't warn.\n//!\n//! This is a footnote[^2].\n//!\n//! [^2]: hello world\n\n/// This is not a footnote[^1].\n///\n/// [^1]: <!-- description -->\n//~^ doc_suspicious_footnotes\n///\n/// This is not a footnote[^either], but it doesn't warn.\n///\n/// This is not a footnote\\[^1], but it also doesn't warn.\n///\n/// This is not a footnote[^1\\], but it also doesn't warn.\n///\n/// This is not a `footnote[^1]`, but it also doesn't warn.\n///\n/// This is a footnote[^2].\n///\n/// [^2]: hello world\npub fn footnotes() {\n    // test code goes here\n}\n\npub struct Foo;\n#[rustfmt::skip]\nimpl Foo {\n    #[doc = r#\"This is not a footnote[^1].\n\n[^1]: <!-- description -->\"#]\n    //~^ doc_suspicious_footnotes\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is not a footnote[^either], but it doesn't warn.\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is not a footnote\\[^1], but it also doesn't warn.\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is not a footnote[^1\\], but it also doesn't warn.\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is not a `footnote[^1]`, but it also doesn't warn.\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is a footnote[^2].\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"[^2]: hello world\"#]\n    pub fn footnotes() {\n        // test code goes here\n    }\n    #[doc = r#\"This is not a footnote[^1].\n\n    This is not a footnote[^either], but it doesn't warn.\n\n    This is not a footnote\\[^1], but it also doesn't warn.\n\n    This is not a footnote[^1\\], but it also doesn't warn.\n\n    This is not a `footnote[^1]`, but it also doesn't warn.\n\n    This is a footnote[^2].\n\n    [^2]: hello world\n    \n\n[^1]: <!-- description -->\"#]\n    //~^^^^^^^^^^^^^^ doc_suspicious_footnotes\n    pub fn footnotes2() {\n        // test code goes here\n    }\n    #[cfg_attr(\n        not(FALSE),\n        doc = r#\"This is not a footnote[^1].\n\nThis is not a footnote[^either], but it doesn't warn.\n\n[^1]: <!-- description -->\"#\n    //~^ doc_suspicious_footnotes\n    )]\n    pub fn footnotes3() {\n        // test code goes here\n    }\n    #[doc = \"My footnote [^foot\\note]\"]\n    pub fn footnote4() {\n        // test code goes here\n    }\n    #[doc = \"Hihi\"]pub fn footnote5() {\n        // test code goes here\n    }\n}\n\n#[doc = r#\"This is not a footnote[^1].\n\n[^1]: <!-- description -->\"#]\n//~^ doc_suspicious_footnotes\n#[doc = r\"\"]\n#[doc = r\"This is not a footnote[^either], but it doesn't warn.\"]\n#[doc = r\"\"]\n#[doc = r\"This is not a footnote\\[^1], but it also doesn't warn.\"]\n#[doc = r\"\"]\n#[doc = r\"This is not a footnote[^1\\], but it also doesn't warn.\"]\n#[doc = r\"\"]\n#[doc = r\"This is not a `footnote[^1]`, but it also doesn't warn.\"]\n#[doc = r\"\"]\n#[doc = r\"This is a footnote[^2].\"]\n#[doc = r\"\"]\n#[doc = r\"[^2]: hello world\"]\npub fn footnotes_attrs() {\n    // test code goes here\n}\n\npub mod multiline {\n    /*!\n     * This is not a footnote[^1]. //~ doc_suspicious_footnotes\n     *\n     * This is not a footnote\\[^1], but it doesn't warn.\n     *\n     * This is a footnote[^2].\n     *\n     * These give weird results, but correct ones, so it works.\n     *\n     * [^2]: hello world\n     */\n/*! [^1]: <!-- description --> */\n    /**\n     * This is not a footnote[^1]. //~ doc_suspicious_footnotes\n     *\n     * This is not a footnote\\[^1], but it doesn't warn.\n     *\n     * This is a footnote[^2].\n     *\n     * These give weird results, but correct ones, so it works.\n     *\n     * [^2]: hello world\n     */\n/** [^1]: <!-- description --> */\n    pub fn foo() {}\n}\n\n/// This is not a footnote [^1]\n///\n/// [^1]: <!-- description -->\n//~^ doc_suspicious_footnotes\n///\n/// This one is [^2]\n///\n/// [^2]: contents\n#[doc = r#\"This is not a footnote [^3]\n\n[^3]: <!-- description -->\"#]\n//~^ doc_suspicious_footnotes\n#[doc = \"\"]\n#[doc = \"This one is [^4]\"]\n#[doc = \"\"]\n#[doc = \"[^4]: contents\"]\npub struct MultiFragmentFootnote;\n\n#[doc(inline)]\n/// This is not a footnote [^5]\n///\n/// [^5]: <!-- description -->\n//~^ doc_suspicious_footnotes\n///\n/// This one is [^6]\n///\n/// [^6]: contents\n#[doc = r#\"This is not a footnote [^7]\n\n[^7]: <!-- description -->\"#]\n//~^ doc_suspicious_footnotes\n#[doc = \"\"]\n#[doc = \"This one is [^8]\"]\n#[doc = \"\"]\n#[doc = \"[^8]: contents\"]\npub use MultiFragmentFootnote as OtherInlinedFootnote;\n"
  },
  {
    "path": "tests/ui/doc_suspicious_footnotes.rs",
    "content": "#![warn(clippy::doc_suspicious_footnotes)]\n#![allow(clippy::needless_raw_string_hashes)]\n//! This is not a footnote[^1].\n//~^ doc_suspicious_footnotes\n//!\n//! This is not a footnote[^either], but it doesn't warn.\n//!\n//! This is not a footnote\\[^1], but it also doesn't warn.\n//!\n//! This is not a footnote[^1\\], but it also doesn't warn.\n//!\n//! This is not a `footnote[^1]`, but it also doesn't warn.\n//!\n//! This is a footnote[^2].\n//!\n//! [^2]: hello world\n\n/// This is not a footnote[^1].\n//~^ doc_suspicious_footnotes\n///\n/// This is not a footnote[^either], but it doesn't warn.\n///\n/// This is not a footnote\\[^1], but it also doesn't warn.\n///\n/// This is not a footnote[^1\\], but it also doesn't warn.\n///\n/// This is not a `footnote[^1]`, but it also doesn't warn.\n///\n/// This is a footnote[^2].\n///\n/// [^2]: hello world\npub fn footnotes() {\n    // test code goes here\n}\n\npub struct Foo;\n#[rustfmt::skip]\nimpl Foo {\n    #[doc = r#\"This is not a footnote[^1].\"#]\n    //~^ doc_suspicious_footnotes\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is not a footnote[^either], but it doesn't warn.\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is not a footnote\\[^1], but it also doesn't warn.\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is not a footnote[^1\\], but it also doesn't warn.\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is not a `footnote[^1]`, but it also doesn't warn.\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"This is a footnote[^2].\"#]\n    #[doc = r#\"\"#]\n    #[doc = r#\"[^2]: hello world\"#]\n    pub fn footnotes() {\n        // test code goes here\n    }\n    #[doc = \"This is not a footnote[^1].\n\n    This is not a footnote[^either], but it doesn't warn.\n\n    This is not a footnote\\\\[^1], but it also doesn't warn.\n\n    This is not a footnote[^1\\\\], but it also doesn't warn.\n\n    This is not a `footnote[^1]`, but it also doesn't warn.\n\n    This is a footnote[^2].\n\n    [^2]: hello world\n    \"]\n    //~^^^^^^^^^^^^^^ doc_suspicious_footnotes\n    pub fn footnotes2() {\n        // test code goes here\n    }\n    #[cfg_attr(\n        not(FALSE),\n        doc = \"This is not a footnote[^1].\\n\\nThis is not a footnote[^either], but it doesn't warn.\"\n    //~^ doc_suspicious_footnotes\n    )]\n    pub fn footnotes3() {\n        // test code goes here\n    }\n    #[doc = \"My footnote [^foot\\note]\"]\n    pub fn footnote4() {\n        // test code goes here\n    }\n    #[doc = \"Hihi\"]pub fn footnote5() {\n        // test code goes here\n    }\n}\n\n#[doc = r\"This is not a footnote[^1].\"]\n//~^ doc_suspicious_footnotes\n#[doc = r\"\"]\n#[doc = r\"This is not a footnote[^either], but it doesn't warn.\"]\n#[doc = r\"\"]\n#[doc = r\"This is not a footnote\\[^1], but it also doesn't warn.\"]\n#[doc = r\"\"]\n#[doc = r\"This is not a footnote[^1\\], but it also doesn't warn.\"]\n#[doc = r\"\"]\n#[doc = r\"This is not a `footnote[^1]`, but it also doesn't warn.\"]\n#[doc = r\"\"]\n#[doc = r\"This is a footnote[^2].\"]\n#[doc = r\"\"]\n#[doc = r\"[^2]: hello world\"]\npub fn footnotes_attrs() {\n    // test code goes here\n}\n\npub mod multiline {\n    /*!\n     * This is not a footnote[^1]. //~ doc_suspicious_footnotes\n     *\n     * This is not a footnote\\[^1], but it doesn't warn.\n     *\n     * This is a footnote[^2].\n     *\n     * These give weird results, but correct ones, so it works.\n     *\n     * [^2]: hello world\n     */\n    /**\n     * This is not a footnote[^1]. //~ doc_suspicious_footnotes\n     *\n     * This is not a footnote\\[^1], but it doesn't warn.\n     *\n     * This is a footnote[^2].\n     *\n     * These give weird results, but correct ones, so it works.\n     *\n     * [^2]: hello world\n     */\n    pub fn foo() {}\n}\n\n/// This is not a footnote [^1]\n//~^ doc_suspicious_footnotes\n///\n/// This one is [^2]\n///\n/// [^2]: contents\n#[doc = \"This is not a footnote [^3]\"]\n//~^ doc_suspicious_footnotes\n#[doc = \"\"]\n#[doc = \"This one is [^4]\"]\n#[doc = \"\"]\n#[doc = \"[^4]: contents\"]\npub struct MultiFragmentFootnote;\n\n#[doc(inline)]\n/// This is not a footnote [^5]\n//~^ doc_suspicious_footnotes\n///\n/// This one is [^6]\n///\n/// [^6]: contents\n#[doc = \"This is not a footnote [^7]\"]\n//~^ doc_suspicious_footnotes\n#[doc = \"\"]\n#[doc = \"This one is [^8]\"]\n#[doc = \"\"]\n#[doc = \"[^8]: contents\"]\npub use MultiFragmentFootnote as OtherInlinedFootnote;\n"
  },
  {
    "path": "tests/ui/doc_suspicious_footnotes.stderr",
    "content": "error: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:3:27\n   |\nLL | //! This is not a footnote[^1].\n   |                           ^^^^\n   |\n   = note: `-D clippy::doc-suspicious-footnotes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_suspicious_footnotes)]`\nhelp: add footnote definition\n   |\nLL ~ //! This is not a footnote[^1].\nLL + //!\nLL + //! [^1]: <!-- description -->\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:18:27\n   |\nLL | /// This is not a footnote[^1].\n   |                           ^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~ /// This is not a footnote[^1].\nLL + ///\nLL + /// [^1]: <!-- description -->\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:39:13\n   |\nLL |     #[doc = r#\"This is not a footnote[^1].\"#]\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~     #[doc = r#\"This is not a footnote[^1].\nLL + \nLL ~ [^1]: <!-- description -->\"#]\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:56:13\n   |\nLL |       #[doc = \"This is not a footnote[^1].\n   |  _____________^\nLL | |\nLL | |     This is not a footnote[^either], but it doesn't warn.\n...  |\nLL | |     [^2]: hello world\nLL | |     \"]\n   | |_____^\n   |\nhelp: add footnote definition\n   |\nLL ~     #[doc = r#\"This is not a footnote[^1].\nLL + \nLL +     This is not a footnote[^either], but it doesn't warn.\nLL + \nLL +     This is not a footnote\\[^1], but it also doesn't warn.\nLL + \nLL +     This is not a footnote[^1\\], but it also doesn't warn.\nLL + \nLL +     This is not a `footnote[^1]`, but it also doesn't warn.\nLL + \nLL +     This is a footnote[^2].\nLL + \nLL +     [^2]: hello world\nLL +     \nLL + \nLL ~ [^1]: <!-- description -->\"#]\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:76:38\n   |\nLL |         doc = \"This is not a footnote[^1].\\n\\nThis is not a footnote[^either], but it doesn't warn.\"\n   |                                      ^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~         doc = r#\"This is not a footnote[^1].\nLL + \nLL + This is not a footnote[^either], but it doesn't warn.\nLL + \nLL + [^1]: <!-- description -->\"#\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:91:9\n   |\nLL | #[doc = r\"This is not a footnote[^1].\"]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~ #[doc = r#\"This is not a footnote[^1].\nLL + \nLL ~ [^1]: <!-- description -->\"#]\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:111:30\n   |\nLL |      * This is not a footnote[^1].\n   |                              ^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~      */\nLL + /*! [^1]: <!-- description --> */\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:122:30\n   |\nLL |      * This is not a footnote[^1].\n   |                              ^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~      */\nLL + /** [^1]: <!-- description --> */\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:135:28\n   |\nLL | /// This is not a footnote [^1]\n   |                            ^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~ /// This is not a footnote [^1]\nLL + ///\nLL + /// [^1]: <!-- description -->\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:141:33\n   |\nLL | #[doc = \"This is not a footnote [^3]\"]\n   |                                 ^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~ #[doc = r#\"This is not a footnote [^3]\nLL + \nLL ~ [^3]: <!-- description -->\"#]\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:150:28\n   |\nLL | /// This is not a footnote [^5]\n   |                            ^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~ /// This is not a footnote [^5]\nLL + ///\nLL + /// [^5]: <!-- description -->\n   |\n\nerror: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes.rs:156:33\n   |\nLL | #[doc = \"This is not a footnote [^7]\"]\n   |                                 ^^^^\n   |\nhelp: add footnote definition\n   |\nLL ~ #[doc = r#\"This is not a footnote [^7]\nLL + \nLL ~ [^7]: <!-- description -->\"#]\n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/doc_suspicious_footnotes_include.rs",
    "content": "//@ error-in-other-file: footnote\n//@ no-rustfix\n#![warn(clippy::doc_suspicious_footnotes)]\n#![doc=include_str!(\"doc_suspicious_footnotes_include.txt\")]\n"
  },
  {
    "path": "tests/ui/doc_suspicious_footnotes_include.stderr",
    "content": "error: looks like a footnote ref, but has no matching footnote\n  --> tests/ui/doc_suspicious_footnotes_include.txt:1:23\n   |\nLL | This is not a footnote[^1].\n   |                       ^^^^\n   |\n   = note: `-D clippy::doc-suspicious-footnotes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_suspicious_footnotes)]`\nhelp: add footnote definition\n   |\nLL ~ [^2]: hello world\nLL + \nLL + [^1]: <!-- description -->\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/doc_suspicious_footnotes_include.txt",
    "content": "This is not a footnote[^1]. //~ doc_suspicious_footnotes\n\nThis is not a footnote[^either], but it doesn't warn.\n\nThis is not a footnote\\[^1], but it also doesn't warn.\n\nThis is not a footnote[^1\\], but it also doesn't warn.\n\nThis is not a `footnote[^1]`, but it also doesn't warn.\n\nThis is a footnote[^2].\n\n[^2]: hello world\n"
  },
  {
    "path": "tests/ui/doc_unsafe.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![allow(clippy::let_unit_value, clippy::needless_pass_by_ref_mut)]\n\nextern crate proc_macros;\nuse proc_macros::external;\n\n/// This is not sufficiently documented\npub unsafe fn destroy_the_planet() {\n    //~^ missing_safety_doc\n    unimplemented!();\n}\n\n/// This one is\n///\n/// # Safety\n///\n/// This function shouldn't be called unless the horsemen are ready\npub unsafe fn apocalypse(universe: &mut ()) {\n    unimplemented!();\n}\n\n/// This is a private function, so docs aren't necessary\nunsafe fn you_dont_see_me() {\n    unimplemented!();\n}\n\nmod private_mod {\n    pub unsafe fn only_crate_wide_accessible() {\n        unimplemented!();\n    }\n\n    pub unsafe fn republished() {\n        //~^ missing_safety_doc\n        unimplemented!();\n    }\n}\n\npub use private_mod::republished;\n\npub trait SafeTraitUnsafeMethods {\n    unsafe fn woefully_underdocumented(self);\n    //~^ missing_safety_doc\n\n    /// # Safety\n    unsafe fn at_least_somewhat_documented(self);\n}\n\npub unsafe trait UnsafeTrait {\n    //~^ missing_safety_doc\n    fn method();\n}\n\n/// # Safety\npub unsafe trait DocumentedUnsafeTrait {\n    fn method2();\n}\n\npub struct Struct;\n\nimpl SafeTraitUnsafeMethods for Struct {\n    unsafe fn woefully_underdocumented(self) {\n        // all is well\n    }\n\n    unsafe fn at_least_somewhat_documented(self) {\n        // all is still well\n    }\n}\n\nunsafe impl UnsafeTrait for Struct {\n    fn method() {}\n}\n\nunsafe impl DocumentedUnsafeTrait for Struct {\n    fn method2() {}\n}\n\nimpl Struct {\n    pub unsafe fn more_undocumented_unsafe() -> Self {\n        //~^ missing_safety_doc\n        unimplemented!();\n    }\n\n    /// # Safety\n    pub unsafe fn somewhat_documented(&self) {\n        unimplemented!();\n    }\n\n    unsafe fn private(&self) {\n        unimplemented!();\n    }\n}\n\nmacro_rules! very_unsafe {\n    () => {\n        pub unsafe fn whee() {\n            //~^ missing_safety_doc\n            unimplemented!()\n        }\n\n        /// # Safety\n        ///\n        /// Please keep the seat belt fastened\n        pub unsafe fn drive() {\n            unsafe { whee() }\n        }\n    };\n}\n\nvery_unsafe!();\n\n// we don't lint code from external macros\nexternal! {\n    pub unsafe fn oy_vey() {\n        unimplemented!();\n    }\n}\n\nfn main() {\n    unsafe {\n        you_dont_see_me();\n        destroy_the_planet();\n        let mut universe = ();\n        apocalypse(&mut universe);\n        private_mod::only_crate_wide_accessible();\n        drive();\n    }\n}\n\n// do not lint if any parent has `#[doc(hidden)]` attribute\n// see #7347\n#[doc(hidden)]\npub mod __macro {\n    pub struct T;\n    impl T {\n        pub unsafe fn f() {}\n    }\n}\n\n/// # Implementation safety\npub unsafe trait DocumentedUnsafeTraitWithImplementationHeader {\n    fn method();\n}\n"
  },
  {
    "path": "tests/ui/doc_unsafe.stderr",
    "content": "error: unsafe function's docs are missing a `# Safety` section\n  --> tests/ui/doc_unsafe.rs:9:1\n   |\nLL | pub unsafe fn destroy_the_planet() {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::missing-safety-doc` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_safety_doc)]`\n\nerror: unsafe function's docs are missing a `# Safety` section\n  --> tests/ui/doc_unsafe.rs:33:5\n   |\nLL |     pub unsafe fn republished() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unsafe function's docs are missing a `# Safety` section\n  --> tests/ui/doc_unsafe.rs:42:5\n   |\nLL |     unsafe fn woefully_underdocumented(self);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for unsafe trait missing `# Safety` section\n  --> tests/ui/doc_unsafe.rs:49:1\n   |\nLL | pub unsafe trait UnsafeTrait {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unsafe function's docs are missing a `# Safety` section\n  --> tests/ui/doc_unsafe.rs:80:5\n   |\nLL |     pub unsafe fn more_undocumented_unsafe() -> Self {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unsafe function's docs are missing a `# Safety` section\n  --> tests/ui/doc_unsafe.rs:97:9\n   |\nLL |         pub unsafe fn whee() {\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | very_unsafe!();\n   | -------------- in this macro invocation\n   |\n   = note: this error originates in the macro `very_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/double_comparison.fixed",
    "content": "#![allow(clippy::needless_ifs)]\n\nfn main() {\n    let x = 1;\n    let y = 2;\n    if x <= y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x <= y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x >= y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x >= y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x != y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x != y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x == y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x == y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x < y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x < y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x > y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x > y {\n        //~^ double_comparisons\n        // do something\n    }\n}\n"
  },
  {
    "path": "tests/ui/double_comparison.rs",
    "content": "#![allow(clippy::needless_ifs)]\n\nfn main() {\n    let x = 1;\n    let y = 2;\n    if x == y || x < y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x < y || x == y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x == y || x > y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x > y || x == y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x < y || x > y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x > y || x < y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x <= y && x >= y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x >= y && x <= y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x != y && x <= y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x <= y && x != y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x != y && x >= y {\n        //~^ double_comparisons\n        // do something\n    }\n    if x >= y && x != y {\n        //~^ double_comparisons\n        // do something\n    }\n}\n"
  },
  {
    "path": "tests/ui/double_comparison.stderr",
    "content": "error: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:6:8\n   |\nLL |     if x == y || x < y {\n   |        ^^^^^^^^^^^^^^^ help: try: `x <= y`\n   |\n   = note: `-D clippy::double-comparisons` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::double_comparisons)]`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:10:8\n   |\nLL |     if x < y || x == y {\n   |        ^^^^^^^^^^^^^^^ help: try: `x <= y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:14:8\n   |\nLL |     if x == y || x > y {\n   |        ^^^^^^^^^^^^^^^ help: try: `x >= y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:18:8\n   |\nLL |     if x > y || x == y {\n   |        ^^^^^^^^^^^^^^^ help: try: `x >= y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:22:8\n   |\nLL |     if x < y || x > y {\n   |        ^^^^^^^^^^^^^^ help: try: `x != y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:26:8\n   |\nLL |     if x > y || x < y {\n   |        ^^^^^^^^^^^^^^ help: try: `x != y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:30:8\n   |\nLL |     if x <= y && x >= y {\n   |        ^^^^^^^^^^^^^^^^ help: try: `x == y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:34:8\n   |\nLL |     if x >= y && x <= y {\n   |        ^^^^^^^^^^^^^^^^ help: try: `x == y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:38:8\n   |\nLL |     if x != y && x <= y {\n   |        ^^^^^^^^^^^^^^^^ help: try: `x < y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:42:8\n   |\nLL |     if x <= y && x != y {\n   |        ^^^^^^^^^^^^^^^^ help: try: `x < y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:46:8\n   |\nLL |     if x != y && x >= y {\n   |        ^^^^^^^^^^^^^^^^ help: try: `x > y`\n\nerror: this binary expression can be simplified\n  --> tests/ui/double_comparison.rs:50:8\n   |\nLL |     if x >= y && x != y {\n   |        ^^^^^^^^^^^^^^^^ help: try: `x > y`\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/double_ended_iterator_last.fixed",
    "content": "#![warn(clippy::double_ended_iterator_last)]\n\n// Typical case\npub fn last_arg(s: &str) -> Option<&str> {\n    s.split(' ').next_back() //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator`\n}\n\nfn main() {\n    // General case\n    struct DeIterator;\n    impl Iterator for DeIterator {\n        type Item = ();\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    impl DoubleEndedIterator for DeIterator {\n        fn next_back(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    let _ = DeIterator.next_back(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator`\n    // Should not apply to other methods of Iterator\n    let _ = DeIterator.count();\n\n    // Should not apply to simple iterators\n    struct SimpleIterator;\n    impl Iterator for SimpleIterator {\n        type Item = ();\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    let _ = SimpleIterator.last();\n\n    // Should not apply to custom implementations of last()\n    struct CustomLast;\n    impl Iterator for CustomLast {\n        type Item = ();\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n        fn last(self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    impl DoubleEndedIterator for CustomLast {\n        fn next_back(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    let _ = CustomLast.last();\n}\n\n// Should not be linted because applying the lint would move the original iterator. This can only be\n// linted if the iterator is used thereafter.\nfn issue_14139() {\n    let mut index = [true, true, false, false, false, true].iter();\n    let subindex = index.by_ref().take(3);\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let mut subindex = index.by_ref().take(3);\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let mut subindex = index.by_ref().take(3);\n    let subindex = &mut subindex;\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let mut subindex = index.by_ref().take(3);\n    let subindex = &mut subindex;\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let (subindex, _) = (index.by_ref().take(3), 42);\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let subindex = (index.by_ref().take(3), 42);\n    let _ = subindex.0.last();\n    let _ = index.next();\n}\n\nfn drop_order() {\n    struct DropDeIterator(std::vec::IntoIter<S>);\n    impl Iterator for DropDeIterator {\n        type Item = S;\n        fn next(&mut self) -> Option<Self::Item> {\n            self.0.next()\n        }\n    }\n    impl DoubleEndedIterator for DropDeIterator {\n        fn next_back(&mut self) -> Option<Self::Item> {\n            self.0.next_back()\n        }\n    }\n\n    struct S(&'static str);\n    impl std::ops::Drop for S {\n        fn drop(&mut self) {\n            println!(\"Dropping {}\", self.0);\n        }\n    }\n\n    let v = vec![S(\"one\"), S(\"two\"), S(\"three\")];\n    let mut v = DropDeIterator(v.into_iter());\n    println!(\"Last element is {}\", v.next_back().unwrap().0);\n    //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`\n\n    let v = vec![S(\"four\"), S(\"five\"), S(\"six\")];\n    let mut v = (DropDeIterator(v.into_iter()), 42);\n    println!(\"Last element is {}\", v.0.next_back().unwrap().0);\n    //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`\n\n    println!(\"Done\");\n}\n\nfn issue_14444() {\n    let mut squares = vec![];\n    let last_square = [1, 2, 3]\n        .into_iter()\n        .map(|x| {\n            squares.push(x * x);\n            Some(x * x)\n        })\n        .last();\n}\n"
  },
  {
    "path": "tests/ui/double_ended_iterator_last.rs",
    "content": "#![warn(clippy::double_ended_iterator_last)]\n\n// Typical case\npub fn last_arg(s: &str) -> Option<&str> {\n    s.split(' ').last() //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator`\n}\n\nfn main() {\n    // General case\n    struct DeIterator;\n    impl Iterator for DeIterator {\n        type Item = ();\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    impl DoubleEndedIterator for DeIterator {\n        fn next_back(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    let _ = DeIterator.last(); //~ ERROR: called `Iterator::last` on a `DoubleEndedIterator`\n    // Should not apply to other methods of Iterator\n    let _ = DeIterator.count();\n\n    // Should not apply to simple iterators\n    struct SimpleIterator;\n    impl Iterator for SimpleIterator {\n        type Item = ();\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    let _ = SimpleIterator.last();\n\n    // Should not apply to custom implementations of last()\n    struct CustomLast;\n    impl Iterator for CustomLast {\n        type Item = ();\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n        fn last(self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    impl DoubleEndedIterator for CustomLast {\n        fn next_back(&mut self) -> Option<Self::Item> {\n            Some(())\n        }\n    }\n    let _ = CustomLast.last();\n}\n\n// Should not be linted because applying the lint would move the original iterator. This can only be\n// linted if the iterator is used thereafter.\nfn issue_14139() {\n    let mut index = [true, true, false, false, false, true].iter();\n    let subindex = index.by_ref().take(3);\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let mut subindex = index.by_ref().take(3);\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let mut subindex = index.by_ref().take(3);\n    let subindex = &mut subindex;\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let mut subindex = index.by_ref().take(3);\n    let subindex = &mut subindex;\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let (subindex, _) = (index.by_ref().take(3), 42);\n    let _ = subindex.last();\n    let _ = index.next();\n\n    let mut index = [true, true, false, false, false, true].iter();\n    let subindex = (index.by_ref().take(3), 42);\n    let _ = subindex.0.last();\n    let _ = index.next();\n}\n\nfn drop_order() {\n    struct DropDeIterator(std::vec::IntoIter<S>);\n    impl Iterator for DropDeIterator {\n        type Item = S;\n        fn next(&mut self) -> Option<Self::Item> {\n            self.0.next()\n        }\n    }\n    impl DoubleEndedIterator for DropDeIterator {\n        fn next_back(&mut self) -> Option<Self::Item> {\n            self.0.next_back()\n        }\n    }\n\n    struct S(&'static str);\n    impl std::ops::Drop for S {\n        fn drop(&mut self) {\n            println!(\"Dropping {}\", self.0);\n        }\n    }\n\n    let v = vec![S(\"one\"), S(\"two\"), S(\"three\")];\n    let v = DropDeIterator(v.into_iter());\n    println!(\"Last element is {}\", v.last().unwrap().0);\n    //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`\n\n    let v = vec![S(\"four\"), S(\"five\"), S(\"six\")];\n    let v = (DropDeIterator(v.into_iter()), 42);\n    println!(\"Last element is {}\", v.0.last().unwrap().0);\n    //~^ ERROR: called `Iterator::last` on a `DoubleEndedIterator`\n\n    println!(\"Done\");\n}\n\nfn issue_14444() {\n    let mut squares = vec![];\n    let last_square = [1, 2, 3]\n        .into_iter()\n        .map(|x| {\n            squares.push(x * x);\n            Some(x * x)\n        })\n        .last();\n}\n"
  },
  {
    "path": "tests/ui/double_ended_iterator_last.stderr",
    "content": "error: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator\n  --> tests/ui/double_ended_iterator_last.rs:5:5\n   |\nLL |     s.split(' ').last()\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::double-ended-iterator-last` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::double_ended_iterator_last)]`\nhelp: try\n   |\nLL -     s.split(' ').last()\nLL +     s.split(' ').next_back()\n   |\n\nerror: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator\n  --> tests/ui/double_ended_iterator_last.rs:22:13\n   |\nLL |     let _ = DeIterator.last();\n   |             ^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let _ = DeIterator.last();\nLL +     let _ = DeIterator.next_back();\n   |\n\nerror: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator\n  --> tests/ui/double_ended_iterator_last.rs:114:36\n   |\nLL |     println!(\"Last element is {}\", v.last().unwrap().0);\n   |                                    ^^^^^^^^\n   |\n   = note: this change will alter drop order which may be undesirable\nhelp: try\n   |\nLL ~     let mut v = DropDeIterator(v.into_iter());\nLL ~     println!(\"Last element is {}\", v.next_back().unwrap().0);\n   |\n\nerror: called `Iterator::last` on a `DoubleEndedIterator`; this will needlessly iterate the entire iterator\n  --> tests/ui/double_ended_iterator_last.rs:119:36\n   |\nLL |     println!(\"Last element is {}\", v.0.last().unwrap().0);\n   |                                    ^^^^^^^^^^\n   |\n   = note: this change will alter drop order which may be undesirable\nhelp: try\n   |\nLL ~     let mut v = (DropDeIterator(v.into_iter()), 42);\nLL ~     println!(\"Last element is {}\", v.0.next_back().unwrap().0);\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/double_must_use.rs",
    "content": "#![warn(clippy::double_must_use)]\n#![allow(clippy::result_unit_err)]\n#![feature(never_type)]\n\nuse std::ops::ControlFlow;\n\n#[must_use]\npub fn must_use_result() -> Result<(), ()> {\n    //~^ double_must_use\n\n    unimplemented!();\n}\n\n#[must_use]\npub fn must_use_tuple() -> (Result<(), ()>, u8) {\n    //~^ double_must_use\n\n    unimplemented!();\n}\n\n#[must_use]\npub fn must_use_array() -> [Result<(), ()>; 1] {\n    //~^ double_must_use\n\n    unimplemented!();\n}\n\n#[must_use = \"With note\"]\npub fn must_use_with_note() -> Result<(), ()> {\n    unimplemented!();\n}\n\n// vvvv Should not lint (#10486)\n#[must_use]\nasync fn async_must_use() -> usize {\n    unimplemented!();\n}\n\n#[must_use]\nasync fn async_must_use_result() -> Result<(), ()> {\n    //~^ double_must_use\n\n    Ok(())\n}\n\n#[must_use]\npub fn must_use_result_with_uninhabited() -> Result<(), !> {\n    unimplemented!();\n}\n\n#[must_use]\npub struct T;\n\n#[must_use]\npub fn must_use_result_with_uninhabited_2() -> Result<T, !> {\n    //~^ double_must_use\n    unimplemented!();\n}\n\n#[must_use]\npub fn must_use_controlflow_with_uninhabited() -> ControlFlow<std::convert::Infallible> {\n    unimplemented!();\n}\n\n#[must_use]\npub fn must_use_controlflow_with_uninhabited_2() -> ControlFlow<std::convert::Infallible, T> {\n    //~^ double_must_use\n    unimplemented!();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/double_must_use.stderr",
    "content": "error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`\n  --> tests/ui/double_must_use.rs:8:1\n   |\nLL | pub fn must_use_result() -> Result<(), ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: either add some descriptive message or remove the attribute\n   = note: `-D clippy::double-must-use` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]`\n\nerror: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`\n  --> tests/ui/double_must_use.rs:15:1\n   |\nLL | pub fn must_use_tuple() -> (Result<(), ()>, u8) {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: either add some descriptive message or remove the attribute\n\nerror: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`\n  --> tests/ui/double_must_use.rs:22:1\n   |\nLL | pub fn must_use_array() -> [Result<(), ()>; 1] {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: either add some descriptive message or remove the attribute\n\nerror: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`\n  --> tests/ui/double_must_use.rs:40:1\n   |\nLL | async fn async_must_use_result() -> Result<(), ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: either add some descriptive message or remove the attribute\n\nerror: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`\n  --> tests/ui/double_must_use.rs:55:1\n   |\nLL | pub fn must_use_result_with_uninhabited_2() -> Result<T, !> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: either add some descriptive message or remove the attribute\n\nerror: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`\n  --> tests/ui/double_must_use.rs:66:1\n   |\nLL | pub fn must_use_controlflow_with_uninhabited_2() -> ControlFlow<std::convert::Infallible, T> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: either add some descriptive message or remove the attribute\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/double_parens.fixed",
    "content": "//@aux-build:proc_macros.rs\n//@aux-build:proc_macro_derive.rs\n//@aux-build:macro_rules.rs\n#![warn(clippy::double_parens)]\n#![expect(clippy::eq_op, clippy::no_effect)]\n#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n\nuse proc_macros::{external, with_span};\n\nfn dummy_fn<T>(_: T) {}\n\nstruct DummyStruct;\n\nimpl DummyStruct {\n    fn dummy_method<T>(&self, _: T) {}\n}\n\nfn simple_double_parens() -> i32 {\n    (0)\n    //~^ double_parens\n}\n\nfn fn_double_parens() {\n    dummy_fn(0);\n    //~^ double_parens\n}\n\nfn method_double_parens(x: DummyStruct) {\n    x.dummy_method(0);\n    //~^ double_parens\n}\n\nfn tuple_double_parens() -> (i32, i32) {\n    (1, 2)\n    //~^ double_parens\n}\n\n#[allow(clippy::unused_unit)]\nfn unit_double_parens() {\n    ()\n    //~^ double_parens\n}\n\nfn fn_tuple_ok() {\n    dummy_fn((1, 2));\n}\n\nfn method_tuple_ok(x: DummyStruct) {\n    x.dummy_method((1, 2));\n}\n\nfn fn_unit_ok() {\n    dummy_fn(());\n}\n\nfn method_unit_ok(x: DummyStruct) {\n    x.dummy_method(());\n}\n\n// Issue #3206\nfn inside_macro() {\n    assert_eq!((1, 2), (1, 2), \"Error\");\n    assert_eq!((1, 2), (1, 2), \"Error\");\n    //~^ double_parens\n}\n\nfn issue9000(x: DummyStruct) {\n    macro_rules! foo {\n        () => {(100)}\n    }\n    // don't lint: the inner paren comes from the macro expansion\n    (foo!());\n    dummy_fn(foo!());\n    x.dummy_method(foo!());\n\n    macro_rules! baz {\n        ($n:literal) => {($n)}\n    }\n    // don't lint: don't get confused by the expression inside the inner paren\n    // having the same `ctxt` as the overall expression\n    // (this is a bug that happened during the development of the fix)\n    (baz!(100));\n    dummy_fn(baz!(100));\n    x.dummy_method(baz!(100));\n\n    // should lint: both parens are from inside the macro\n    macro_rules! bar {\n        () => {(100)}\n        //~^ double_parens\n    }\n    bar!();\n\n    // should lint: both parens are from outside the macro;\n    // make sure to suggest the macro unexpanded\n    (vec![1, 2]);\n    //~^ double_parens\n    dummy_fn(vec![1, 2]);\n    //~^ double_parens\n    x.dummy_method(vec![1, 2]);\n    //~^ double_parens\n}\n\nfn issue15892() {\n    use macro_rules::double_parens as double_parens_external;\n\n    macro_rules! double_parens{\n        ($a:expr, $b:expr, $c:expr, $d:expr) => {{\n            let a = ($a);\n            let a = ();\n            //~^ double_parens\n            let b = (5);\n            //~^ double_parens\n            let c = std::convert::identity(5);\n            //~^ double_parens\n            InterruptMask((($a.union($b).union($c).union($d)).into_bits()) as u32)\n        }};\n    }\n\n    // Don't lint: external macro\n    (external!((5)));\n    external!(((5)));\n\n    #[repr(transparent)]\n    #[derive(Clone, Copy, PartialEq, Eq)]\n    pub struct InterruptMask(u32);\n\n    impl InterruptMask {\n        pub const OE: InterruptMask = InterruptMask(1 << 10);\n        pub const BE: InterruptMask = InterruptMask(1 << 9);\n        pub const PE: InterruptMask = InterruptMask(1 << 8);\n        pub const FE: InterruptMask = InterruptMask(1 << 7);\n        // Lint: internal macro\n        pub const E: InterruptMask = double_parens!((Self::OE), Self::BE, Self::PE, Self::FE);\n        // Don't lint: external macro\n        pub const F: InterruptMask = double_parens_external!((Self::OE), Self::BE, Self::PE, Self::FE);\n        #[allow(clippy::unnecessary_cast)]\n        pub const G: InterruptMask = external!(\n            InterruptMask((((Self::OE.union(Self::BE).union(Self::PE).union(Self::FE))).into_bits()) as u32)\n        );\n        #[allow(clippy::unnecessary_cast)]\n        // Don't lint: external proc-macro\n        pub const H: InterruptMask = with_span!(span\n            InterruptMask((((Self::OE.union(Self::BE).union(Self::PE).union(Self::FE))).into_bits()) as u32)\n        );\n        pub const fn into_bits(self) -> u32 {\n            self.0\n        }\n        #[must_use]\n        pub const fn union(self, rhs: Self) -> Self {\n            InterruptMask(self.0 | rhs.0)\n        }\n    }\n}\n\nfn issue15940() {\n    use proc_macro_derive::DoubleParens;\n\n    #[derive(DoubleParens)]\n    // Don't lint: external derive macro\n    pub struct Person;\n}\n\nfn issue16224() {\n    fn test() -> i32 { 42 }\n\n    macro_rules! call {\n        ($matcher:pat $(=> $result:expr)?) => {\n            match test() {\n                $matcher => Result::Ok(($($result),*)),\n                _ => Result::Err(\"No match\".to_string()),\n            }\n        };\n    }\n\n    let _: Result<(), String> = call!(_);\n    let _: Result<i32, String> = call!(_ => 42);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/double_parens.rs",
    "content": "//@aux-build:proc_macros.rs\n//@aux-build:proc_macro_derive.rs\n//@aux-build:macro_rules.rs\n#![warn(clippy::double_parens)]\n#![expect(clippy::eq_op, clippy::no_effect)]\n#![feature(custom_inner_attributes)]\n#![rustfmt::skip]\n\nuse proc_macros::{external, with_span};\n\nfn dummy_fn<T>(_: T) {}\n\nstruct DummyStruct;\n\nimpl DummyStruct {\n    fn dummy_method<T>(&self, _: T) {}\n}\n\nfn simple_double_parens() -> i32 {\n    ((0))\n    //~^ double_parens\n}\n\nfn fn_double_parens() {\n    dummy_fn((0));\n    //~^ double_parens\n}\n\nfn method_double_parens(x: DummyStruct) {\n    x.dummy_method((0));\n    //~^ double_parens\n}\n\nfn tuple_double_parens() -> (i32, i32) {\n    ((1, 2))\n    //~^ double_parens\n}\n\n#[allow(clippy::unused_unit)]\nfn unit_double_parens() {\n    (())\n    //~^ double_parens\n}\n\nfn fn_tuple_ok() {\n    dummy_fn((1, 2));\n}\n\nfn method_tuple_ok(x: DummyStruct) {\n    x.dummy_method((1, 2));\n}\n\nfn fn_unit_ok() {\n    dummy_fn(());\n}\n\nfn method_unit_ok(x: DummyStruct) {\n    x.dummy_method(());\n}\n\n// Issue #3206\nfn inside_macro() {\n    assert_eq!((1, 2), (1, 2), \"Error\");\n    assert_eq!(((1, 2)), (1, 2), \"Error\");\n    //~^ double_parens\n}\n\nfn issue9000(x: DummyStruct) {\n    macro_rules! foo {\n        () => {(100)}\n    }\n    // don't lint: the inner paren comes from the macro expansion\n    (foo!());\n    dummy_fn(foo!());\n    x.dummy_method(foo!());\n\n    macro_rules! baz {\n        ($n:literal) => {($n)}\n    }\n    // don't lint: don't get confused by the expression inside the inner paren\n    // having the same `ctxt` as the overall expression\n    // (this is a bug that happened during the development of the fix)\n    (baz!(100));\n    dummy_fn(baz!(100));\n    x.dummy_method(baz!(100));\n\n    // should lint: both parens are from inside the macro\n    macro_rules! bar {\n        () => {((100))}\n        //~^ double_parens\n    }\n    bar!();\n\n    // should lint: both parens are from outside the macro;\n    // make sure to suggest the macro unexpanded\n    ((vec![1, 2]));\n    //~^ double_parens\n    dummy_fn((vec![1, 2]));\n    //~^ double_parens\n    x.dummy_method((vec![1, 2]));\n    //~^ double_parens\n}\n\nfn issue15892() {\n    use macro_rules::double_parens as double_parens_external;\n\n    macro_rules! double_parens{\n        ($a:expr, $b:expr, $c:expr, $d:expr) => {{\n            let a = ($a);\n            let a = (());\n            //~^ double_parens\n            let b = ((5));\n            //~^ double_parens\n            let c = std::convert::identity((5));\n            //~^ double_parens\n            InterruptMask((($a.union($b).union($c).union($d)).into_bits()) as u32)\n        }};\n    }\n\n    // Don't lint: external macro\n    (external!((5)));\n    external!(((5)));\n\n    #[repr(transparent)]\n    #[derive(Clone, Copy, PartialEq, Eq)]\n    pub struct InterruptMask(u32);\n\n    impl InterruptMask {\n        pub const OE: InterruptMask = InterruptMask(1 << 10);\n        pub const BE: InterruptMask = InterruptMask(1 << 9);\n        pub const PE: InterruptMask = InterruptMask(1 << 8);\n        pub const FE: InterruptMask = InterruptMask(1 << 7);\n        // Lint: internal macro\n        pub const E: InterruptMask = double_parens!((Self::OE), Self::BE, Self::PE, Self::FE);\n        // Don't lint: external macro\n        pub const F: InterruptMask = double_parens_external!((Self::OE), Self::BE, Self::PE, Self::FE);\n        #[allow(clippy::unnecessary_cast)]\n        pub const G: InterruptMask = external!(\n            InterruptMask((((Self::OE.union(Self::BE).union(Self::PE).union(Self::FE))).into_bits()) as u32)\n        );\n        #[allow(clippy::unnecessary_cast)]\n        // Don't lint: external proc-macro\n        pub const H: InterruptMask = with_span!(span\n            InterruptMask((((Self::OE.union(Self::BE).union(Self::PE).union(Self::FE))).into_bits()) as u32)\n        );\n        pub const fn into_bits(self) -> u32 {\n            self.0\n        }\n        #[must_use]\n        pub const fn union(self, rhs: Self) -> Self {\n            InterruptMask(self.0 | rhs.0)\n        }\n    }\n}\n\nfn issue15940() {\n    use proc_macro_derive::DoubleParens;\n\n    #[derive(DoubleParens)]\n    // Don't lint: external derive macro\n    pub struct Person;\n}\n\nfn issue16224() {\n    fn test() -> i32 { 42 }\n\n    macro_rules! call {\n        ($matcher:pat $(=> $result:expr)?) => {\n            match test() {\n                $matcher => Result::Ok(($($result),*)),\n                _ => Result::Err(\"No match\".to_string()),\n            }\n        };\n    }\n\n    let _: Result<(), String> = call!(_);\n    let _: Result<i32, String> = call!(_ => 42);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/double_parens.stderr",
    "content": "error: unnecessary parentheses\n  --> tests/ui/double_parens.rs:20:5\n   |\nLL |     ((0))\n   |     ^^^^^ help: remove them: `(0)`\n   |\n   = note: `-D clippy::double-parens` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::double_parens)]`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:25:14\n   |\nLL |     dummy_fn((0));\n   |              ^^^ help: remove them: `0`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:30:20\n   |\nLL |     x.dummy_method((0));\n   |                    ^^^ help: remove them: `0`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:35:5\n   |\nLL |     ((1, 2))\n   |     ^^^^^^^^ help: remove them: `(1, 2)`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:41:5\n   |\nLL |     (())\n   |     ^^^^ help: remove them: `()`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:64:16\n   |\nLL |     assert_eq!(((1, 2)), (1, 2), \"Error\");\n   |                ^^^^^^^^ help: remove them: `(1, 2)`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:89:16\n   |\nLL |         () => {((100))}\n   |                ^^^^^^^ help: remove them: `(100)`\n...\nLL |     bar!();\n   |     ------ in this macro invocation\n   |\n   = note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:96:5\n   |\nLL |     ((vec![1, 2]));\n   |     ^^^^^^^^^^^^^^ help: remove them: `(vec![1, 2])`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:98:14\n   |\nLL |     dummy_fn((vec![1, 2]));\n   |              ^^^^^^^^^^^^ help: remove them: `vec![1, 2]`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:100:20\n   |\nLL |     x.dummy_method((vec![1, 2]));\n   |                    ^^^^^^^^^^^^ help: remove them: `vec![1, 2]`\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:110:21\n   |\nLL |             let a = (());\n   |                     ^^^^ help: remove them: `()`\n...\nLL |         pub const E: InterruptMask = double_parens!((Self::OE), Self::BE, Self::PE, Self::FE);\n   |                                      -------------------------------------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `double_parens` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:112:21\n   |\nLL |             let b = ((5));\n   |                     ^^^^^ help: remove them: `(5)`\n...\nLL |         pub const E: InterruptMask = double_parens!((Self::OE), Self::BE, Self::PE, Self::FE);\n   |                                      -------------------------------------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `double_parens` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unnecessary parentheses\n  --> tests/ui/double_parens.rs:114:44\n   |\nLL |             let c = std::convert::identity((5));\n   |                                            ^^^ help: remove them: `5`\n...\nLL |         pub const E: InterruptMask = double_parens!((Self::OE), Self::BE, Self::PE, Self::FE);\n   |                                      -------------------------------------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `double_parens` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/drain_collect.fixed",
    "content": "#![deny(clippy::drain_collect)]\n#![allow(dead_code)]\n\nuse std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};\n\nfn binaryheap(b: &mut BinaryHeap<i32>) -> BinaryHeap<i32> {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn binaryheap_dont_lint(b: &mut BinaryHeap<i32>) -> HashSet<i32> {\n    b.drain().collect()\n}\n\nfn hashmap(b: &mut HashMap<i32, i32>) -> HashMap<i32, i32> {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn hashmap_dont_lint(b: &mut HashMap<i32, i32>) -> Vec<(i32, i32)> {\n    b.drain().collect()\n}\n\nfn hashset(b: &mut HashSet<i32>) -> HashSet<i32> {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn hashset_dont_lint(b: &mut HashSet<i32>) -> Vec<i32> {\n    b.drain().collect()\n}\n\nfn vecdeque(b: &mut VecDeque<i32>) -> VecDeque<i32> {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn vecdeque_dont_lint(b: &mut VecDeque<i32>) -> HashSet<i32> {\n    b.drain(..).collect()\n}\n\nfn vec(b: &mut Vec<i32>) -> Vec<i32> {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn vec2(b: &mut Vec<i32>) -> Vec<i32> {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn vec3(b: &mut Vec<i32>) -> Vec<i32> {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn vec4(b: &mut Vec<i32>) -> Vec<i32> {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn vec_no_reborrow() -> Vec<i32> {\n    let mut b = vec![1, 2, 3];\n    std::mem::take(&mut b)\n    //~^ drain_collect\n}\n\nfn vec_dont_lint(b: &mut Vec<i32>) -> HashSet<i32> {\n    b.drain(..).collect()\n}\n\nfn string(b: &mut String) -> String {\n    std::mem::take(b)\n    //~^ drain_collect\n}\n\nfn string_dont_lint(b: &mut String) -> HashSet<char> {\n    b.drain(..).collect()\n}\n\nfn not_whole_length(v: &mut Vec<i32>) -> Vec<i32> {\n    v.drain(1..).collect()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/drain_collect.rs",
    "content": "#![deny(clippy::drain_collect)]\n#![allow(dead_code)]\n\nuse std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};\n\nfn binaryheap(b: &mut BinaryHeap<i32>) -> BinaryHeap<i32> {\n    b.drain().collect()\n    //~^ drain_collect\n}\n\nfn binaryheap_dont_lint(b: &mut BinaryHeap<i32>) -> HashSet<i32> {\n    b.drain().collect()\n}\n\nfn hashmap(b: &mut HashMap<i32, i32>) -> HashMap<i32, i32> {\n    b.drain().collect()\n    //~^ drain_collect\n}\n\nfn hashmap_dont_lint(b: &mut HashMap<i32, i32>) -> Vec<(i32, i32)> {\n    b.drain().collect()\n}\n\nfn hashset(b: &mut HashSet<i32>) -> HashSet<i32> {\n    b.drain().collect()\n    //~^ drain_collect\n}\n\nfn hashset_dont_lint(b: &mut HashSet<i32>) -> Vec<i32> {\n    b.drain().collect()\n}\n\nfn vecdeque(b: &mut VecDeque<i32>) -> VecDeque<i32> {\n    b.drain(..).collect()\n    //~^ drain_collect\n}\n\nfn vecdeque_dont_lint(b: &mut VecDeque<i32>) -> HashSet<i32> {\n    b.drain(..).collect()\n}\n\nfn vec(b: &mut Vec<i32>) -> Vec<i32> {\n    b.drain(..).collect()\n    //~^ drain_collect\n}\n\nfn vec2(b: &mut Vec<i32>) -> Vec<i32> {\n    b.drain(0..).collect()\n    //~^ drain_collect\n}\n\nfn vec3(b: &mut Vec<i32>) -> Vec<i32> {\n    b.drain(..b.len()).collect()\n    //~^ drain_collect\n}\n\nfn vec4(b: &mut Vec<i32>) -> Vec<i32> {\n    b.drain(0..b.len()).collect()\n    //~^ drain_collect\n}\n\nfn vec_no_reborrow() -> Vec<i32> {\n    let mut b = vec![1, 2, 3];\n    b.drain(..).collect()\n    //~^ drain_collect\n}\n\nfn vec_dont_lint(b: &mut Vec<i32>) -> HashSet<i32> {\n    b.drain(..).collect()\n}\n\nfn string(b: &mut String) -> String {\n    b.drain(..).collect()\n    //~^ drain_collect\n}\n\nfn string_dont_lint(b: &mut String) -> HashSet<char> {\n    b.drain(..).collect()\n}\n\nfn not_whole_length(v: &mut Vec<i32>) -> Vec<i32> {\n    v.drain(1..).collect()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/drain_collect.stderr",
    "content": "error: you seem to be trying to move all elements into a new `BinaryHeap`\n  --> tests/ui/drain_collect.rs:7:5\n   |\nLL |     b.drain().collect()\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n   |\nnote: the lint level is defined here\n  --> tests/ui/drain_collect.rs:1:9\n   |\nLL | #![deny(clippy::drain_collect)]\n   |         ^^^^^^^^^^^^^^^^^^^^^\n\nerror: you seem to be trying to move all elements into a new `HashMap`\n  --> tests/ui/drain_collect.rs:16:5\n   |\nLL |     b.drain().collect()\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n\nerror: you seem to be trying to move all elements into a new `HashSet`\n  --> tests/ui/drain_collect.rs:25:5\n   |\nLL |     b.drain().collect()\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n\nerror: you seem to be trying to move all elements into a new `Vec`\n  --> tests/ui/drain_collect.rs:34:5\n   |\nLL |     b.drain(..).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n\nerror: you seem to be trying to move all elements into a new `Vec`\n  --> tests/ui/drain_collect.rs:43:5\n   |\nLL |     b.drain(..).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n\nerror: you seem to be trying to move all elements into a new `Vec`\n  --> tests/ui/drain_collect.rs:48:5\n   |\nLL |     b.drain(0..).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n\nerror: you seem to be trying to move all elements into a new `Vec`\n  --> tests/ui/drain_collect.rs:53:5\n   |\nLL |     b.drain(..b.len()).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n\nerror: you seem to be trying to move all elements into a new `Vec`\n  --> tests/ui/drain_collect.rs:58:5\n   |\nLL |     b.drain(0..b.len()).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n\nerror: you seem to be trying to move all elements into a new `Vec`\n  --> tests/ui/drain_collect.rs:64:5\n   |\nLL |     b.drain(..).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(&mut b)`\n\nerror: you seem to be trying to move all elements into a new `String`\n  --> tests/ui/drain_collect.rs:73:5\n   |\nLL |     b.drain(..).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `std::mem::take(b)`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/drain_collect_nostd.fixed",
    "content": "#![warn(clippy::drain_collect)]\n#![no_std]\nextern crate alloc;\nuse alloc::vec::Vec;\n\nfn remove_all(v: &mut Vec<i32>) -> Vec<i32> {\n    core::mem::take(v)\n    //~^ drain_collect\n}\n"
  },
  {
    "path": "tests/ui/drain_collect_nostd.rs",
    "content": "#![warn(clippy::drain_collect)]\n#![no_std]\nextern crate alloc;\nuse alloc::vec::Vec;\n\nfn remove_all(v: &mut Vec<i32>) -> Vec<i32> {\n    v.drain(..).collect()\n    //~^ drain_collect\n}\n"
  },
  {
    "path": "tests/ui/drain_collect_nostd.stderr",
    "content": "error: you seem to be trying to move all elements into a new `Vec`\n  --> tests/ui/drain_collect_nostd.rs:7:5\n   |\nLL |     v.drain(..).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `core::mem::take(v)`\n   |\n   = note: `-D clippy::drain-collect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::drain_collect)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/drop_non_drop.rs",
    "content": "#![warn(clippy::drop_non_drop)]\n\nuse core::mem::drop;\n\nfn make_result<T>(t: T) -> Result<T, ()> {\n    Ok(t)\n}\n\n// The return type should behave as `T` as the `Err` variant is uninhabited\nfn make_result_uninhabited_err<T>(t: T) -> Result<T, std::convert::Infallible> {\n    Ok(t)\n}\n\n#[must_use]\nfn must_use<T>(t: T) -> T {\n    t\n}\n\nfn drop_generic<T>(t: T) {\n    // Don't lint\n    drop(t)\n}\n\nfn main() {\n    struct Foo;\n    // Lint\n    drop(Foo);\n    //~^ drop_non_drop\n\n    // Don't lint\n    drop(make_result(Foo));\n    // Don't lint\n    drop(must_use(Foo));\n\n    struct Bar;\n    impl Drop for Bar {\n        fn drop(&mut self) {}\n    }\n    // Don't lint\n    drop(Bar);\n\n    struct Baz<T>(T);\n    // Lint\n    drop(Baz(Foo));\n    //~^ drop_non_drop\n\n    // Don't lint\n    drop(Baz(Bar));\n\n    // Lint\n    drop(make_result_uninhabited_err(Foo));\n    //~^ drop_non_drop\n}\n"
  },
  {
    "path": "tests/ui/drop_non_drop.stderr",
    "content": "error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes\n  --> tests/ui/drop_non_drop.rs:27:5\n   |\nLL |     drop(Foo);\n   |     ^^^^^^^^^\n   |\nnote: argument has type `main::Foo`\n  --> tests/ui/drop_non_drop.rs:27:10\n   |\nLL |     drop(Foo);\n   |          ^^^\n   = note: `-D clippy::drop-non-drop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::drop_non_drop)]`\n\nerror: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes\n  --> tests/ui/drop_non_drop.rs:44:5\n   |\nLL |     drop(Baz(Foo));\n   |     ^^^^^^^^^^^^^^\n   |\nnote: argument has type `main::Baz<main::Foo>`\n  --> tests/ui/drop_non_drop.rs:44:10\n   |\nLL |     drop(Baz(Foo));\n   |          ^^^^^^^^\n\nerror: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes\n  --> tests/ui/drop_non_drop.rs:51:5\n   |\nLL |     drop(make_result_uninhabited_err(Foo));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: argument has type `std::result::Result<main::Foo, std::convert::Infallible>`\n  --> tests/ui/drop_non_drop.rs:51:10\n   |\nLL |     drop(make_result_uninhabited_err(Foo));\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/duplicate_underscore_argument.rs",
    "content": "#![warn(clippy::duplicate_underscore_argument)]\n\nfn join_the_dark_side(darth: i32, _darth: i32) {}\n//~^ duplicate_underscore_argument\n\nfn join_the_light_side(knight: i32, _master: i32) {} // the Force is strong with this one\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/duplicate_underscore_argument.stderr",
    "content": "error: `darth` already exists, having another argument having almost the same name makes code comprehension and documentation more difficult\n  --> tests/ui/duplicate_underscore_argument.rs:3:23\n   |\nLL | fn join_the_dark_side(darth: i32, _darth: i32) {}\n   |                       ^^^^^\n   |\n   = note: `-D clippy::duplicate-underscore-argument` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::duplicate_underscore_argument)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/duplicated_attributes.rs",
    "content": "//@aux-build:proc_macro_attr.rs\n#![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)] //~ ERROR: duplicated attribute\n#![feature(rustc_attrs)]\n#![cfg(any(unix, windows))]\n#![allow(dead_code)]\n#![allow(dead_code)] //~ ERROR: duplicated attribute\n#![cfg(any(unix, windows))] // Should not warn!\n\n#[macro_use]\nextern crate proc_macro_attr;\n\n#[cfg(any(unix, windows, target_os = \"linux\"))]\n#[allow(dead_code)]\n#[allow(dead_code)] //~ ERROR: duplicated attribute\n#[cfg(any(unix, windows, target_os = \"linux\"))] // Should not warn!\nfn foo() {}\n\n#[cfg(unix)]\n#[cfg(windows)]\n#[cfg(unix)] // cfgs are not handled\nfn bar() {}\n\n// No warning:\n#[rustc_on_unimplemented(on(Self = \"&str\", label = \"`a\"), on(Self = \"alloc::string::String\", label = \"a\"))]\ntrait Abc {}\n\n#[proc_macro_attr::duplicated_attr()] // Should not warn!\nfn babar() {}\n\n#[allow(missing_docs, reason = \"library for internal use only\")]\n#[allow(exported_private_dependencies, reason = \"library for internal use only\")]\nfn duplicate_reason() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/duplicated_attributes.stderr",
    "content": "error: duplicated attribute\n  --> tests/ui/duplicated_attributes.rs:2:40\n   |\nLL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first defined here\n  --> tests/ui/duplicated_attributes.rs:2:9\n   |\nLL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: remove this attribute\n  --> tests/ui/duplicated_attributes.rs:2:40\n   |\nLL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::duplicated-attributes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`\n\nerror: duplicated attribute\n  --> tests/ui/duplicated_attributes.rs:6:10\n   |\nLL | #![allow(dead_code)]\n   |          ^^^^^^^^^\n   |\nnote: first defined here\n  --> tests/ui/duplicated_attributes.rs:5:10\n   |\nLL | #![allow(dead_code)]\n   |          ^^^^^^^^^\nhelp: remove this attribute\n  --> tests/ui/duplicated_attributes.rs:6:10\n   |\nLL | #![allow(dead_code)]\n   |          ^^^^^^^^^\n\nerror: duplicated attribute\n  --> tests/ui/duplicated_attributes.rs:14:9\n   |\nLL | #[allow(dead_code)]\n   |         ^^^^^^^^^\n   |\nnote: first defined here\n  --> tests/ui/duplicated_attributes.rs:13:9\n   |\nLL | #[allow(dead_code)]\n   |         ^^^^^^^^^\nhelp: remove this attribute\n  --> tests/ui/duplicated_attributes.rs:14:9\n   |\nLL | #[allow(dead_code)]\n   |         ^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/duration_suboptimal_units.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::duration_suboptimal_units)]\n\nuse std::time::Duration;\n\nconst SIXTY: u64 = 60;\n\nmacro_rules! mac {\n    (slow_rythm) => {\n        3600\n    };\n    (duration) => {\n        Duration::from_mins(5)\n        //~^ duration_suboptimal_units\n    };\n    (arg => $e:expr) => {\n        Duration::from_secs($e)\n    };\n}\n\nfn main() {\n    let dur = Duration::from_secs(0);\n    let dur = Duration::from_secs(42);\n    let dur = Duration::from_hours(3);\n\n    let dur = Duration::from_mins(1);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_mins(3);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_mins(10);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_hours(24);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_secs(5);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_hours(13);\n    //~^ duration_suboptimal_units\n\n    // Constants are intentionally not resolved, as we don't want to recommend a literal value over\n    // using constants.\n    let dur = Duration::from_secs(SIXTY);\n    // Technically it would be nice to use Duration::from_mins(SIXTY) here, but that is a follow-up\n    let dur = Duration::from_secs(SIXTY * 60);\n\n    const {\n        let dur = Duration::from_secs(0);\n        let dur = Duration::from_secs(5);\n        //~^ duration_suboptimal_units\n        let dur = Duration::from_mins(3);\n        //~^ duration_suboptimal_units\n        let dur = Duration::from_hours(24);\n        //~^ duration_suboptimal_units\n\n        let dur = Duration::from_secs(SIXTY);\n    }\n\n    // Qualified Durations must be kept\n    std::time::Duration::from_mins(1);\n    //~^ duration_suboptimal_units\n\n    // We lint in normal macros\n    assert_eq!(Duration::from_hours(1), Duration::from_mins(6));\n    //~^ duration_suboptimal_units\n\n    // We lint in normal macros (marker is in macro itself)\n    let dur = mac!(duration);\n\n    // We don't lint in macros if duration comes from outside\n    let dur = mac!(arg => 3600);\n\n    // We don't lint in external macros\n    let dur = proc_macros::external! { Duration::from_secs(3_600) };\n\n    // We don't lint values coming from macros\n    let dur = Duration::from_secs(mac!(slow_rythm));\n}\n\nmod my_duration {\n    struct Duration {}\n\n    impl Duration {\n        pub const fn from_secs(_secs: u64) -> Self {\n            Self {}\n        }\n    }\n\n    fn test() {\n        // Only suggest the change for std::time::Duration, not for other Duration structs\n        let dur = Duration::from_secs(60);\n    }\n}\n\nfn issue16457() {\n    // Methods taking something else than `u64` are not covered\n    _ = Duration::from_nanos_u128(1 << 90);\n}\n\n#[clippy::msrv = \"1.90\"]\nfn insufficient_msrv() {\n    _ = Duration::from_secs(67_768_040_922_076_800);\n}\n\n#[clippy::msrv = \"1.91\"]\nfn sufficient_msrv() {\n    _ = Duration::from_hours(18824455811688);\n    //~^ duration_suboptimal_units\n}\n"
  },
  {
    "path": "tests/ui/duration_suboptimal_units.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::duration_suboptimal_units)]\n\nuse std::time::Duration;\n\nconst SIXTY: u64 = 60;\n\nmacro_rules! mac {\n    (slow_rythm) => {\n        3600\n    };\n    (duration) => {\n        Duration::from_secs(300)\n        //~^ duration_suboptimal_units\n    };\n    (arg => $e:expr) => {\n        Duration::from_secs($e)\n    };\n}\n\nfn main() {\n    let dur = Duration::from_secs(0);\n    let dur = Duration::from_secs(42);\n    let dur = Duration::from_hours(3);\n\n    let dur = Duration::from_secs(60);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_secs(180);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_secs(10 * 60);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_mins(24 * 60);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_millis(5_000);\n    //~^ duration_suboptimal_units\n    let dur = Duration::from_nanos(13 * 60 * 60 * 1_000 * 1_000 * 1_000);\n    //~^ duration_suboptimal_units\n\n    // Constants are intentionally not resolved, as we don't want to recommend a literal value over\n    // using constants.\n    let dur = Duration::from_secs(SIXTY);\n    // Technically it would be nice to use Duration::from_mins(SIXTY) here, but that is a follow-up\n    let dur = Duration::from_secs(SIXTY * 60);\n\n    const {\n        let dur = Duration::from_secs(0);\n        let dur = Duration::from_millis(5_000);\n        //~^ duration_suboptimal_units\n        let dur = Duration::from_secs(180);\n        //~^ duration_suboptimal_units\n        let dur = Duration::from_mins(24 * 60);\n        //~^ duration_suboptimal_units\n\n        let dur = Duration::from_secs(SIXTY);\n    }\n\n    // Qualified Durations must be kept\n    std::time::Duration::from_secs(60);\n    //~^ duration_suboptimal_units\n\n    // We lint in normal macros\n    assert_eq!(Duration::from_secs(3_600), Duration::from_mins(6));\n    //~^ duration_suboptimal_units\n\n    // We lint in normal macros (marker is in macro itself)\n    let dur = mac!(duration);\n\n    // We don't lint in macros if duration comes from outside\n    let dur = mac!(arg => 3600);\n\n    // We don't lint in external macros\n    let dur = proc_macros::external! { Duration::from_secs(3_600) };\n\n    // We don't lint values coming from macros\n    let dur = Duration::from_secs(mac!(slow_rythm));\n}\n\nmod my_duration {\n    struct Duration {}\n\n    impl Duration {\n        pub const fn from_secs(_secs: u64) -> Self {\n            Self {}\n        }\n    }\n\n    fn test() {\n        // Only suggest the change for std::time::Duration, not for other Duration structs\n        let dur = Duration::from_secs(60);\n    }\n}\n\nfn issue16457() {\n    // Methods taking something else than `u64` are not covered\n    _ = Duration::from_nanos_u128(1 << 90);\n}\n\n#[clippy::msrv = \"1.90\"]\nfn insufficient_msrv() {\n    _ = Duration::from_secs(67_768_040_922_076_800);\n}\n\n#[clippy::msrv = \"1.91\"]\nfn sufficient_msrv() {\n    _ = Duration::from_secs(67_768_040_922_076_800);\n    //~^ duration_suboptimal_units\n}\n"
  },
  {
    "path": "tests/ui/duration_suboptimal_units.stderr",
    "content": "error: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:26:15\n   |\nLL |     let dur = Duration::from_secs(60);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::duration-suboptimal-units` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::duration_suboptimal_units)]`\nhelp: try using from_mins\n   |\nLL -     let dur = Duration::from_secs(60);\nLL +     let dur = Duration::from_mins(1);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:28:15\n   |\nLL |     let dur = Duration::from_secs(180);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_mins\n   |\nLL -     let dur = Duration::from_secs(180);\nLL +     let dur = Duration::from_mins(3);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:30:15\n   |\nLL |     let dur = Duration::from_secs(10 * 60);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_mins\n   |\nLL -     let dur = Duration::from_secs(10 * 60);\nLL +     let dur = Duration::from_mins(10);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:32:15\n   |\nLL |     let dur = Duration::from_mins(24 * 60);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_hours\n   |\nLL -     let dur = Duration::from_mins(24 * 60);\nLL +     let dur = Duration::from_hours(24);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:34:15\n   |\nLL |     let dur = Duration::from_millis(5_000);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_secs\n   |\nLL -     let dur = Duration::from_millis(5_000);\nLL +     let dur = Duration::from_secs(5);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:36:15\n   |\nLL |     let dur = Duration::from_nanos(13 * 60 * 60 * 1_000 * 1_000 * 1_000);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_hours\n   |\nLL -     let dur = Duration::from_nanos(13 * 60 * 60 * 1_000 * 1_000 * 1_000);\nLL +     let dur = Duration::from_hours(13);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:47:19\n   |\nLL |         let dur = Duration::from_millis(5_000);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_secs\n   |\nLL -         let dur = Duration::from_millis(5_000);\nLL +         let dur = Duration::from_secs(5);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:49:19\n   |\nLL |         let dur = Duration::from_secs(180);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_mins\n   |\nLL -         let dur = Duration::from_secs(180);\nLL +         let dur = Duration::from_mins(3);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:51:19\n   |\nLL |         let dur = Duration::from_mins(24 * 60);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_hours\n   |\nLL -         let dur = Duration::from_mins(24 * 60);\nLL +         let dur = Duration::from_hours(24);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:58:5\n   |\nLL |     std::time::Duration::from_secs(60);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_mins\n   |\nLL -     std::time::Duration::from_secs(60);\nLL +     std::time::Duration::from_mins(1);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:62:16\n   |\nLL |     assert_eq!(Duration::from_secs(3_600), Duration::from_mins(6));\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_hours\n   |\nLL -     assert_eq!(Duration::from_secs(3_600), Duration::from_mins(6));\nLL +     assert_eq!(Duration::from_hours(1), Duration::from_mins(6));\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:13:9\n   |\nLL |         Duration::from_secs(300)\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     let dur = mac!(duration);\n   |               -------------- in this macro invocation\n   |\n   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: try using from_mins\n   |\nLL -         Duration::from_secs(300)\nLL +         Duration::from_mins(5)\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units.rs:105:9\n   |\nLL |     _ = Duration::from_secs(67_768_040_922_076_800);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_hours\n   |\nLL -     _ = Duration::from_secs(67_768_040_922_076_800);\nLL +     _ = Duration::from_hours(18824455811688);\n   |\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/duration_suboptimal_units_days_weeks.fixed",
    "content": "#![warn(clippy::duration_suboptimal_units)]\n// The duration_constructors feature enables `Duration::from_days` and `Duration::from_weeks`, so we\n// should suggest them\n#![feature(duration_constructors)]\n\nuse std::time::Duration;\n\nfn main() {\n    let dur = Duration::from_mins(1);\n    //~^ duration_suboptimal_units\n\n    let dur = Duration::from_days(1);\n    //~^ duration_suboptimal_units\n\n    let dur = Duration::from_weeks(13);\n    //~^ duration_suboptimal_units\n}\n"
  },
  {
    "path": "tests/ui/duration_suboptimal_units_days_weeks.rs",
    "content": "#![warn(clippy::duration_suboptimal_units)]\n// The duration_constructors feature enables `Duration::from_days` and `Duration::from_weeks`, so we\n// should suggest them\n#![feature(duration_constructors)]\n\nuse std::time::Duration;\n\nfn main() {\n    let dur = Duration::from_secs(60);\n    //~^ duration_suboptimal_units\n\n    let dur = Duration::from_hours(24);\n    //~^ duration_suboptimal_units\n\n    let dur = Duration::from_nanos(13 * 7 * 24 * 60 * 60 * 1_000 * 1_000 * 1_000);\n    //~^ duration_suboptimal_units\n}\n"
  },
  {
    "path": "tests/ui/duration_suboptimal_units_days_weeks.stderr",
    "content": "error: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units_days_weeks.rs:9:15\n   |\nLL |     let dur = Duration::from_secs(60);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::duration-suboptimal-units` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::duration_suboptimal_units)]`\nhelp: try using from_mins\n   |\nLL -     let dur = Duration::from_secs(60);\nLL +     let dur = Duration::from_mins(1);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units_days_weeks.rs:12:15\n   |\nLL |     let dur = Duration::from_hours(24);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_days\n   |\nLL -     let dur = Duration::from_hours(24);\nLL +     let dur = Duration::from_days(1);\n   |\n\nerror: constructing a `Duration` using a smaller unit when a larger unit would be more readable\n  --> tests/ui/duration_suboptimal_units_days_weeks.rs:15:15\n   |\nLL |     let dur = Duration::from_nanos(13 * 7 * 24 * 60 * 60 * 1_000 * 1_000 * 1_000);\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try using from_weeks\n   |\nLL -     let dur = Duration::from_nanos(13 * 7 * 24 * 60 * 60 * 1_000 * 1_000 * 1_000);\nLL +     let dur = Duration::from_weeks(13);\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/duration_subsec.fixed",
    "content": "#![allow(dead_code, clippy::needless_borrow)]\n#![warn(clippy::duration_subsec)]\n\nuse std::time::Duration;\n\nfn main() {\n    let dur = Duration::new(5, 0);\n\n    let bad_millis_1 = dur.subsec_millis();\n    //~^ duration_subsec\n    let bad_millis_2 = dur.subsec_millis();\n    //~^ duration_subsec\n    let good_millis = dur.subsec_millis();\n    assert_eq!(bad_millis_1, good_millis);\n    assert_eq!(bad_millis_2, good_millis);\n\n    let bad_micros = dur.subsec_micros();\n    //~^ duration_subsec\n    let good_micros = dur.subsec_micros();\n    assert_eq!(bad_micros, good_micros);\n\n    // Handle refs\n    let _ = (&dur).subsec_micros();\n    //~^ duration_subsec\n\n    // Handle constants\n    const NANOS_IN_MICRO: u32 = 1_000;\n    let _ = dur.subsec_nanos() / NANOS_IN_MICRO;\n\n    // Other literals aren't linted\n    let _ = dur.subsec_nanos() / 699;\n}\n"
  },
  {
    "path": "tests/ui/duration_subsec.rs",
    "content": "#![allow(dead_code, clippy::needless_borrow)]\n#![warn(clippy::duration_subsec)]\n\nuse std::time::Duration;\n\nfn main() {\n    let dur = Duration::new(5, 0);\n\n    let bad_millis_1 = dur.subsec_micros() / 1_000;\n    //~^ duration_subsec\n    let bad_millis_2 = dur.subsec_nanos() / 1_000_000;\n    //~^ duration_subsec\n    let good_millis = dur.subsec_millis();\n    assert_eq!(bad_millis_1, good_millis);\n    assert_eq!(bad_millis_2, good_millis);\n\n    let bad_micros = dur.subsec_nanos() / 1_000;\n    //~^ duration_subsec\n    let good_micros = dur.subsec_micros();\n    assert_eq!(bad_micros, good_micros);\n\n    // Handle refs\n    let _ = (&dur).subsec_nanos() / 1_000;\n    //~^ duration_subsec\n\n    // Handle constants\n    const NANOS_IN_MICRO: u32 = 1_000;\n    let _ = dur.subsec_nanos() / NANOS_IN_MICRO;\n\n    // Other literals aren't linted\n    let _ = dur.subsec_nanos() / 699;\n}\n"
  },
  {
    "path": "tests/ui/duration_subsec.stderr",
    "content": "error: calling `subsec_millis()` is more concise than this calculation\n  --> tests/ui/duration_subsec.rs:9:24\n   |\nLL |     let bad_millis_1 = dur.subsec_micros() / 1_000;\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_millis()`\n   |\n   = note: `-D clippy::duration-subsec` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::duration_subsec)]`\n\nerror: calling `subsec_millis()` is more concise than this calculation\n  --> tests/ui/duration_subsec.rs:11:24\n   |\nLL |     let bad_millis_2 = dur.subsec_nanos() / 1_000_000;\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_millis()`\n\nerror: calling `subsec_micros()` is more concise than this calculation\n  --> tests/ui/duration_subsec.rs:17:22\n   |\nLL |     let bad_micros = dur.subsec_nanos() / 1_000;\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_micros()`\n\nerror: calling `subsec_micros()` is more concise than this calculation\n  --> tests/ui/duration_subsec.rs:23:13\n   |\nLL |     let _ = (&dur).subsec_nanos() / 1_000;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&dur).subsec_micros()`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/eager_transmute.fixed",
    "content": "#![feature(rustc_attrs)]\n#![warn(clippy::eager_transmute)]\n#![allow(clippy::transmute_int_to_non_zero, clippy::missing_transmute_annotations)]\n\nuse std::num::NonZero;\n\n#[repr(u8)]\nenum Opcode {\n    Add = 0,\n    Sub = 1,\n    Mul = 2,\n    Div = 3,\n}\n\nstruct Data {\n    foo: &'static [u8],\n    bar: &'static [u8],\n}\n\nfn int_to_opcode(op: u8) -> Option<Opcode> {\n    (op < 4).then(|| unsafe { std::mem::transmute(op) })\n    //~^ eager_transmute\n}\n\nfn f(op: u8, op2: Data, unrelated: u8) {\n    true.then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n    (unrelated < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n    (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });\n    //~^ eager_transmute\n    (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });\n    //~^ eager_transmute\n    (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });\n    //~^ eager_transmute\n\n    let _: Option<Opcode> = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n\n    // lint even when the transmutable goes through field/array accesses\n    let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) });\n    //~^ eager_transmute\n\n    // don't lint: wrong index used in the transmute\n    let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[1]) });\n\n    // don't lint: no check for the transmutable in the condition\n    let _: Option<Opcode> = (op2.foo[0] > 0 && op2.bar[1] < 10).then_some(unsafe { std::mem::transmute(op2.bar[0]) });\n\n    // don't lint: wrong variable\n    let _: Option<Opcode> = (op2.foo[0] > 0 && op2.bar[1] < 10).then_some(unsafe { std::mem::transmute(op) });\n\n    // range contains checks\n    let _: Option<Opcode> = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n\n    // unrelated binding in contains\n    let _: Option<Opcode> = (1..=3)\n        .contains(&unrelated)\n        .then_some(unsafe { std::mem::transmute(op) });\n}\n\nunsafe fn f2(op: u8) {\n    unsafe {\n        (op < 4).then(|| std::mem::transmute::<_, Opcode>(op));\n        //~^ eager_transmute\n    }\n}\n\n#[rustc_layout_scalar_valid_range_end(254)]\nstruct NonMaxU8(u8);\n#[rustc_layout_scalar_valid_range_end(254)]\n#[rustc_layout_scalar_valid_range_start(1)]\nstruct NonZeroNonMaxU8(u8);\n\nmacro_rules! impls {\n    ($($t:ty),*) => {\n        $(\n            impl PartialEq<u8> for $t {\n                fn eq(&self, other: &u8) -> bool {\n                    self.0 == *other\n                }\n            }\n            impl PartialOrd<u8> for $t {\n                fn partial_cmp(&self, other: &u8) -> Option<std::cmp::Ordering> {\n                    self.0.partial_cmp(other)\n                }\n            }\n        )*\n    };\n}\nimpls!(NonMaxU8, NonZeroNonMaxU8);\n\nfn niche_tests(v1: u8, v2: NonZero<u8>, v3: NonZeroNonMaxU8) {\n    // u8 -> NonZero<u8>, do lint\n    let _: Option<NonZero<u8>> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) });\n    //~^ eager_transmute\n\n    // NonZero<u8> -> u8, don't lint, target type has no niche and therefore a higher validity range\n    let _: Option<u8> = (v2 > NonZero::new(1u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });\n\n    // NonZero<u8> -> NonMaxU8, do lint, different niche\n    let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });\n    //~^ eager_transmute\n\n    // NonZeroNonMaxU8 -> NonMaxU8, don't lint, target type has more validity\n    let _: Option<NonMaxU8> = (v3 < 255).then_some(unsafe { std::mem::transmute(v2) });\n\n    // NonZero<u8> -> NonZeroNonMaxU8, do lint, target type has less validity\n    let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });\n    //~^ eager_transmute\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/eager_transmute.rs",
    "content": "#![feature(rustc_attrs)]\n#![warn(clippy::eager_transmute)]\n#![allow(clippy::transmute_int_to_non_zero, clippy::missing_transmute_annotations)]\n\nuse std::num::NonZero;\n\n#[repr(u8)]\nenum Opcode {\n    Add = 0,\n    Sub = 1,\n    Mul = 2,\n    Div = 3,\n}\n\nstruct Data {\n    foo: &'static [u8],\n    bar: &'static [u8],\n}\n\nfn int_to_opcode(op: u8) -> Option<Opcode> {\n    (op < 4).then_some(unsafe { std::mem::transmute(op) })\n    //~^ eager_transmute\n}\n\nfn f(op: u8, op2: Data, unrelated: u8) {\n    true.then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n    (unrelated < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n    (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n    //~^ eager_transmute\n    (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n    //~^ eager_transmute\n    (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n    //~^ eager_transmute\n\n    let _: Option<Opcode> = (op > 0 && op < 10).then_some(unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then_some(unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n\n    // lint even when the transmutable goes through field/array accesses\n    let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[0]) });\n    //~^ eager_transmute\n\n    // don't lint: wrong index used in the transmute\n    let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[1]) });\n\n    // don't lint: no check for the transmutable in the condition\n    let _: Option<Opcode> = (op2.foo[0] > 0 && op2.bar[1] < 10).then_some(unsafe { std::mem::transmute(op2.bar[0]) });\n\n    // don't lint: wrong variable\n    let _: Option<Opcode> = (op2.foo[0] > 0 && op2.bar[1] < 10).then_some(unsafe { std::mem::transmute(op) });\n\n    // range contains checks\n    let _: Option<Opcode> = (1..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then_some(unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (1..3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (1..).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (..3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n    let _: Option<Opcode> = (..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n    //~^ eager_transmute\n\n    // unrelated binding in contains\n    let _: Option<Opcode> = (1..=3)\n        .contains(&unrelated)\n        .then_some(unsafe { std::mem::transmute(op) });\n}\n\nunsafe fn f2(op: u8) {\n    unsafe {\n        (op < 4).then_some(std::mem::transmute::<_, Opcode>(op));\n        //~^ eager_transmute\n    }\n}\n\n#[rustc_layout_scalar_valid_range_end(254)]\nstruct NonMaxU8(u8);\n#[rustc_layout_scalar_valid_range_end(254)]\n#[rustc_layout_scalar_valid_range_start(1)]\nstruct NonZeroNonMaxU8(u8);\n\nmacro_rules! impls {\n    ($($t:ty),*) => {\n        $(\n            impl PartialEq<u8> for $t {\n                fn eq(&self, other: &u8) -> bool {\n                    self.0 == *other\n                }\n            }\n            impl PartialOrd<u8> for $t {\n                fn partial_cmp(&self, other: &u8) -> Option<std::cmp::Ordering> {\n                    self.0.partial_cmp(other)\n                }\n            }\n        )*\n    };\n}\nimpls!(NonMaxU8, NonZeroNonMaxU8);\n\nfn niche_tests(v1: u8, v2: NonZero<u8>, v3: NonZeroNonMaxU8) {\n    // u8 -> NonZero<u8>, do lint\n    let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) });\n    //~^ eager_transmute\n\n    // NonZero<u8> -> u8, don't lint, target type has no niche and therefore a higher validity range\n    let _: Option<u8> = (v2 > NonZero::new(1u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });\n\n    // NonZero<u8> -> NonMaxU8, do lint, different niche\n    let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });\n    //~^ eager_transmute\n\n    // NonZeroNonMaxU8 -> NonMaxU8, don't lint, target type has more validity\n    let _: Option<NonMaxU8> = (v3 < 255).then_some(unsafe { std::mem::transmute(v2) });\n\n    // NonZero<u8> -> NonZeroNonMaxU8, do lint, target type has less validity\n    let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });\n    //~^ eager_transmute\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/eager_transmute.stderr",
    "content": "error: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:21:33\n   |\nLL |     (op < 4).then_some(unsafe { std::mem::transmute(op) })\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::eager-transmute` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::eager_transmute)]`\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     (op < 4).then_some(unsafe { std::mem::transmute(op) })\nLL +     (op < 4).then(|| unsafe { std::mem::transmute(op) })\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:28:33\n   |\nLL |     (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\nLL +     (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:30:33\n   |\nLL |     (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\nLL +     (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:32:34\n   |\nLL |     (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });\nLL +     (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:35:68\n   |\nLL |     let _: Option<Opcode> = (op > 0 && op < 10).then_some(unsafe { std::mem::transmute(op) });\n   |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = (op > 0 && op < 10).then_some(unsafe { std::mem::transmute(op) });\nLL +     let _: Option<Opcode> = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:37:86\n   |\nLL |     let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then_some(unsafe { std::mem::transmute(op) });\n   |                                                                                      ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then_some(unsafe { std::mem::transmute(op) });\nLL +     let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:41:84\n   |\nLL |     let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[0]) });\n   |                                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[0]) });\nLL +     let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:54:70\n   |\nLL |     let _: Option<Opcode> = (1..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n   |                                                                      ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = (1..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\nLL +     let _: Option<Opcode> = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:56:83\n   |\nLL |     let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then_some(unsafe { std::mem::transmute(op) });\n   |                                                                                   ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then_some(unsafe { std::mem::transmute(op) });\nLL +     let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:58:69\n   |\nLL |     let _: Option<Opcode> = (1..3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n   |                                                                     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = (1..3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\nLL +     let _: Option<Opcode> = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:60:68\n   |\nLL |     let _: Option<Opcode> = (1..).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n   |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = (1..).contains(&op).then_some(unsafe { std::mem::transmute(op) });\nLL +     let _: Option<Opcode> = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:62:68\n   |\nLL |     let _: Option<Opcode> = (..3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n   |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = (..3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\nLL +     let _: Option<Opcode> = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:64:69\n   |\nLL |     let _: Option<Opcode> = (..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\n   |                                                                     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<Opcode> = (..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) });\nLL +     let _: Option<Opcode> = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:75:28\n   |\nLL |         (op < 4).then_some(std::mem::transmute::<_, Opcode>(op));\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -         (op < 4).then_some(std::mem::transmute::<_, Opcode>(op));\nLL +         (op < 4).then(|| std::mem::transmute::<_, Opcode>(op));\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:106:62\n   |\nLL |     let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) });\n   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) });\nLL +     let _: Option<NonZero<u8>> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:113:86\n   |\nLL |     let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });\n   |                                                                                      ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });\nLL +     let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });\n   |\n\nerror: this transmute is always evaluated eagerly, even if the condition is false\n  --> tests/ui/eager_transmute.rs:120:93\n   |\nLL |     let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });\n   |                                                                                             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `bool::then` to only transmute if the condition holds\n   |\nLL -     let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });\nLL +     let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });\n   |\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/elidable_lifetime_names.fixed",
    "content": "#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)]\n\ntype Ref<'r> = &'r u8;\n\n// No error; same lifetime on two params.\nfn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {}\n\n//~v ERROR: could be elided: 'a, 'b\nfn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}\n\n// No error; bounded lifetime.\nfn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {}\n\n// No error; bounded lifetime.\nfn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8)\nwhere\n    'b: 'a,\n{\n}\n\nstruct Lt<'a, I: 'static> {\n    x: &'a I,\n}\n\n// No error; fn bound references `'a`.\nfn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>\nwhere\n    F: Fn(Lt<'a, I>) -> Lt<'a, I>,\n{\n    unreachable!()\n}\n\n//~v ERROR: could be elided: 'a\nfn fn_bound_2<F, I>(_m: Lt<'_, I>, _f: F) -> Lt<'_, I>\nwhere\n    for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>,\n{\n    unreachable!()\n}\n\nstruct Foo<'a>(&'a u8);\n\n//~v ERROR: could be elided: 'a\nfn struct_with_lt(_foo: Foo<'_>) -> &str {\n    unimplemented!()\n}\n\n// No warning; two input lifetimes (named on the reference, anonymous on `Foo`).\nfn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str {\n    unimplemented!()\n}\n\n// No warning; two input lifetimes (anonymous on the reference, named on `Foo`).\nfn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {\n    unimplemented!()\n}\n\n//~v ERROR: could be elided: 'b\nfn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str {\n    unimplemented!()\n}\n\ntype FooAlias<'a> = Foo<'a>;\n\n//~v ERROR: could be elided: 'a\nfn alias_with_lt(_foo: FooAlias<'_>) -> &str {\n    unimplemented!()\n}\n\n// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`).\nfn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str {\n    unimplemented!()\n}\n\n// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`).\nfn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {\n    unimplemented!()\n}\n\n//~v ERROR: could be elided: 'b\nfn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {\n    unimplemented!()\n}\n\n// Issue #3284: give hint regarding lifetime in return type.\nstruct Cow<'a> {\n    x: &'a str,\n}\n\n//~v ERROR: could be elided: 'a\nfn out_return_type_lts(e: &str) -> Cow<'_> {\n    unimplemented!()\n}\n\nmod issue2944 {\n    trait Foo {}\n    struct Bar;\n    struct Baz<'a> {\n        bar: &'a Bar,\n    }\n\n    //~v ERROR: could be elided: 'a\n    impl Foo for Baz<'_> {}\n    impl Bar {\n        //~v ERROR: could be elided: 'a\n        fn baz(&self) -> impl Foo + '_ {\n            Baz { bar: self }\n        }\n    }\n}\n\nmod issue13923 {\n    struct Py<'py> {\n        data: &'py str,\n    }\n\n    enum Content<'t, 'py> {\n        Py(Py<'py>),\n        T1(&'t str),\n        T2(&'t str),\n    }\n\n    enum ContentString<'t> {\n        T1(&'t str),\n        T2(&'t str),\n    }\n\n    impl<'t, 'py> ContentString<'t> {\n        // `'py` cannot be elided\n        fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {\n            match self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(content) => Content::T2(f(content)),\n            }\n        }\n    }\n\n    //~v ERROR: could be elided: 'py\n    impl<'t> ContentString<'t> {\n        // `'py` can be elided because of `&self`\n        fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {\n            match self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(content) => Content::T2(f(content)),\n            }\n        }\n    }\n\n    //~v ERROR: could be elided: 'py\n    impl<'t> ContentString<'t> {\n        // `'py` can be elided because of `&'_ self`\n        fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {\n            match self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(content) => Content::T2(f(content)),\n            }\n        }\n    }\n\n    impl<'t, 'py> ContentString<'t> {\n        // `'py` should not be elided as the default lifetime, even if working, could be named as `'t`\n        fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> {\n            match self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(_) => Content::T2(o),\n            }\n        }\n    }\n\n    //~v ERROR: could be elided: 'py\n    impl<'t> ContentString<'t> {\n        // `'py` can be elided because of `&Self`\n        fn map_content5(\n            self: std::pin::Pin<&Self>,\n            f: impl FnOnce(&'t str) -> &'t str,\n            o: &'t str,\n        ) -> Content<'t, '_> {\n            match *self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(_) => Content::T2(o),\n            }\n        }\n    }\n\n    struct Cx<'a, 'b> {\n        a: &'a u32,\n        b: &'b u32,\n    }\n\n    // `'c` cannot be elided because we have several input lifetimes\n    fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 {\n        x.b\n    }\n}\n\nfn issue15666_original() {\n    struct UnitVariantAccess<'a, 'b, 's>(&'a &'b &'s ());\n\n    trait Trait<'de> {}\n\n    //~v elidable_lifetime_names\n    impl<'de> Trait<'de> for UnitVariantAccess<'_, 'de, '_> {}\n    //        ^^  ^^                                   ^^       ^^\n}\n\n#[allow(clippy::upper_case_acronyms)]\nfn issue15666() {\n    struct S1<'a>(&'a ());\n    struct S2<'a, 'b>(&'a &'b ());\n    struct S3<'a, 'b, 'c>(&'a &'b &'c ());\n\n    trait T {}\n    trait TA<'a> {}\n    trait TB<'b> {}\n    trait TC<'c> {}\n    trait TAB<'a, 'b> {}\n    trait TAC<'a, 'c> {}\n    trait TBC<'b, 'c> {}\n    trait TABC<'a, 'b, 'c> {}\n\n    // 1 lifetime\n\n    impl<'a> TA<'a> for S1<'a> {}\n\n    //~v elidable_lifetime_names\n    impl T for S1<'_> {}\n    //   ^^\n\n    // 2 lifetimes\n\n    impl<'a, 'b> TAB<'a, 'b> for S2<'a, 'b> {}\n\n    //~v elidable_lifetime_names\n    impl<'a> TA<'a> for S2<'a, '_> {}\n    //       ^^\n\n    //~v elidable_lifetime_names\n    impl<'b> TB<'b> for S2<'_, 'b> {}\n    //   ^^\n\n    //~v elidable_lifetime_names\n    impl T for S2<'_, '_> {}\n    //   ^^  ^^\n\n    // 3 lifetimes\n\n    impl<'a, 'b, 'c> TABC<'a, 'b, 'c> for S3<'a, 'b, 'c> {}\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b> TAB<'a, 'b> for S3<'a, 'b, '_> {}\n    //           ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'c> TAC<'a, 'c> for S3<'a, '_, 'c> {}\n    //       ^^\n\n    //~v elidable_lifetime_names\n    impl<'a> TA<'a> for S3<'a, '_, '_> {}\n    //       ^^  ^^\n\n    //~v elidable_lifetime_names\n    impl<'b, 'c> TBC<'b, 'c> for S3<'_, 'b, 'c> {}\n    //   ^^\n\n    //~v elidable_lifetime_names\n    impl<'b> TB<'b> for S3<'_, 'b, '_> {}\n    //   ^^      ^^\n\n    //~v elidable_lifetime_names\n    impl<'c> TC<'c> for S3<'_, '_, 'c> {}\n    //   ^^  ^^\n\n    //~v elidable_lifetime_names\n    impl T for S3<'_, '_, '_> {}\n    //   ^^  ^^  ^^\n}\n"
  },
  {
    "path": "tests/ui/elidable_lifetime_names.rs",
    "content": "#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)]\n\ntype Ref<'r> = &'r u8;\n\n// No error; same lifetime on two params.\nfn lifetime_param_1<'a>(_x: Ref<'a>, _y: &'a u8) {}\n\n//~v ERROR: could be elided: 'a, 'b\nfn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}\n\n// No error; bounded lifetime.\nfn lifetime_param_3<'a, 'b: 'a>(_x: Ref<'a>, _y: &'b u8) {}\n\n// No error; bounded lifetime.\nfn lifetime_param_4<'a, 'b>(_x: Ref<'a>, _y: &'b u8)\nwhere\n    'b: 'a,\n{\n}\n\nstruct Lt<'a, I: 'static> {\n    x: &'a I,\n}\n\n// No error; fn bound references `'a`.\nfn fn_bound<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>\nwhere\n    F: Fn(Lt<'a, I>) -> Lt<'a, I>,\n{\n    unreachable!()\n}\n\n//~v ERROR: could be elided: 'a\nfn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>\nwhere\n    for<'x> F: Fn(Lt<'x, I>) -> Lt<'x, I>,\n{\n    unreachable!()\n}\n\nstruct Foo<'a>(&'a u8);\n\n//~v ERROR: could be elided: 'a\nfn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {\n    unimplemented!()\n}\n\n// No warning; two input lifetimes (named on the reference, anonymous on `Foo`).\nfn struct_with_lt2<'a>(_foo: &'a Foo) -> &'a str {\n    unimplemented!()\n}\n\n// No warning; two input lifetimes (anonymous on the reference, named on `Foo`).\nfn struct_with_lt3<'a>(_foo: &Foo<'a>) -> &'a str {\n    unimplemented!()\n}\n\n//~v ERROR: could be elided: 'b\nfn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {\n    unimplemented!()\n}\n\ntype FooAlias<'a> = Foo<'a>;\n\n//~v ERROR: could be elided: 'a\nfn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {\n    unimplemented!()\n}\n\n// No warning; two input lifetimes (named on the reference, anonymous on `FooAlias`).\nfn alias_with_lt2<'a>(_foo: &'a FooAlias) -> &'a str {\n    unimplemented!()\n}\n\n// No warning; two input lifetimes (anonymous on the reference, named on `FooAlias`).\nfn alias_with_lt3<'a>(_foo: &FooAlias<'a>) -> &'a str {\n    unimplemented!()\n}\n\n//~v ERROR: could be elided: 'b\nfn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {\n    unimplemented!()\n}\n\n// Issue #3284: give hint regarding lifetime in return type.\nstruct Cow<'a> {\n    x: &'a str,\n}\n\n//~v ERROR: could be elided: 'a\nfn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {\n    unimplemented!()\n}\n\nmod issue2944 {\n    trait Foo {}\n    struct Bar;\n    struct Baz<'a> {\n        bar: &'a Bar,\n    }\n\n    //~v ERROR: could be elided: 'a\n    impl<'a> Foo for Baz<'a> {}\n    impl Bar {\n        //~v ERROR: could be elided: 'a\n        fn baz<'a>(&'a self) -> impl Foo + 'a {\n            Baz { bar: self }\n        }\n    }\n}\n\nmod issue13923 {\n    struct Py<'py> {\n        data: &'py str,\n    }\n\n    enum Content<'t, 'py> {\n        Py(Py<'py>),\n        T1(&'t str),\n        T2(&'t str),\n    }\n\n    enum ContentString<'t> {\n        T1(&'t str),\n        T2(&'t str),\n    }\n\n    impl<'t, 'py> ContentString<'t> {\n        // `'py` cannot be elided\n        fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {\n            match self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(content) => Content::T2(f(content)),\n            }\n        }\n    }\n\n    //~v ERROR: could be elided: 'py\n    impl<'t, 'py> ContentString<'t> {\n        // `'py` can be elided because of `&self`\n        fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {\n            match self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(content) => Content::T2(f(content)),\n            }\n        }\n    }\n\n    //~v ERROR: could be elided: 'py\n    impl<'t, 'py> ContentString<'t> {\n        // `'py` can be elided because of `&'_ self`\n        fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {\n            match self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(content) => Content::T2(f(content)),\n            }\n        }\n    }\n\n    impl<'t, 'py> ContentString<'t> {\n        // `'py` should not be elided as the default lifetime, even if working, could be named as `'t`\n        fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> {\n            match self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(_) => Content::T2(o),\n            }\n        }\n    }\n\n    //~v ERROR: could be elided: 'py\n    impl<'t, 'py> ContentString<'t> {\n        // `'py` can be elided because of `&Self`\n        fn map_content5(\n            self: std::pin::Pin<&Self>,\n            f: impl FnOnce(&'t str) -> &'t str,\n            o: &'t str,\n        ) -> Content<'t, 'py> {\n            match *self {\n                Self::T1(content) => Content::T1(f(content)),\n                Self::T2(_) => Content::T2(o),\n            }\n        }\n    }\n\n    struct Cx<'a, 'b> {\n        a: &'a u32,\n        b: &'b u32,\n    }\n\n    // `'c` cannot be elided because we have several input lifetimes\n    fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 {\n        x.b\n    }\n}\n\nfn issue15666_original() {\n    struct UnitVariantAccess<'a, 'b, 's>(&'a &'b &'s ());\n\n    trait Trait<'de> {}\n\n    //~v elidable_lifetime_names\n    impl<'de, 'a, 's> Trait<'de> for UnitVariantAccess<'a, 'de, 's> {}\n    //        ^^  ^^                                   ^^       ^^\n}\n\n#[allow(clippy::upper_case_acronyms)]\nfn issue15666() {\n    struct S1<'a>(&'a ());\n    struct S2<'a, 'b>(&'a &'b ());\n    struct S3<'a, 'b, 'c>(&'a &'b &'c ());\n\n    trait T {}\n    trait TA<'a> {}\n    trait TB<'b> {}\n    trait TC<'c> {}\n    trait TAB<'a, 'b> {}\n    trait TAC<'a, 'c> {}\n    trait TBC<'b, 'c> {}\n    trait TABC<'a, 'b, 'c> {}\n\n    // 1 lifetime\n\n    impl<'a> TA<'a> for S1<'a> {}\n\n    //~v elidable_lifetime_names\n    impl<'a> T for S1<'a> {}\n    //   ^^\n\n    // 2 lifetimes\n\n    impl<'a, 'b> TAB<'a, 'b> for S2<'a, 'b> {}\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b> TA<'a> for S2<'a, 'b> {}\n    //       ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b> TB<'b> for S2<'a, 'b> {}\n    //   ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b> T for S2<'a, 'b> {}\n    //   ^^  ^^\n\n    // 3 lifetimes\n\n    impl<'a, 'b, 'c> TABC<'a, 'b, 'c> for S3<'a, 'b, 'c> {}\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b, 'c> TAB<'a, 'b> for S3<'a, 'b, 'c> {}\n    //           ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b, 'c> TAC<'a, 'c> for S3<'a, 'b, 'c> {}\n    //       ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b, 'c> TA<'a> for S3<'a, 'b, 'c> {}\n    //       ^^  ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b, 'c> TBC<'b, 'c> for S3<'a, 'b, 'c> {}\n    //   ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b, 'c> TB<'b> for S3<'a, 'b, 'c> {}\n    //   ^^      ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b, 'c> TC<'c> for S3<'a, 'b, 'c> {}\n    //   ^^  ^^\n\n    //~v elidable_lifetime_names\n    impl<'a, 'b, 'c> T for S3<'a, 'b, 'c> {}\n    //   ^^  ^^  ^^\n}\n"
  },
  {
    "path": "tests/ui/elidable_lifetime_names.stderr",
    "content": "error: the following explicit lifetimes could be elided: 'a, 'b\n  --> tests/ui/elidable_lifetime_names.rs:9:21\n   |\nLL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}\n   |                     ^^  ^^          ^^        ^^\n   |\n   = note: `-D clippy::elidable-lifetime-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::elidable_lifetime_names)]`\nhelp: elide the lifetimes\n   |\nLL - fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}\nLL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:34:15\n   |\nLL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>\n   |               ^^               ^^                   ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>\nLL + fn fn_bound_2<F, I>(_m: Lt<'_, I>, _f: F) -> Lt<'_, I>\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:44:19\n   |\nLL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {\n   |                   ^^            ^^       ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {\nLL + fn struct_with_lt(_foo: Foo<'_>) -> &str {\n   |\n\nerror: the following explicit lifetimes could be elided: 'b\n  --> tests/ui/elidable_lifetime_names.rs:59:25\n   |\nLL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {\n   |                         ^^                ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {\nLL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:66:18\n   |\nLL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {\n   |                  ^^                 ^^       ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {\nLL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str {\n   |\n\nerror: the following explicit lifetimes could be elided: 'b\n  --> tests/ui/elidable_lifetime_names.rs:81:24\n   |\nLL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {\n   |                        ^^                     ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {\nLL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:91:24\n   |\nLL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {\n   |                        ^^      ^^             ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {\nLL + fn out_return_type_lts(e: &str) -> Cow<'_> {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:103:10\n   |\nLL |     impl<'a> Foo for Baz<'a> {}\n   |          ^^              ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a> Foo for Baz<'a> {}\nLL +     impl Foo for Baz<'_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:106:16\n   |\nLL |         fn baz<'a>(&'a self) -> impl Foo + 'a {\n   |                ^^   ^^                     ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn baz<'a>(&'a self) -> impl Foo + 'a {\nLL +         fn baz(&self) -> impl Foo + '_ {\n   |\n\nerror: the following explicit lifetimes could be elided: 'py\n  --> tests/ui/elidable_lifetime_names.rs:139:14\n   |\nLL |     impl<'t, 'py> ContentString<'t> {\n   |              ^^^\nLL |         // `'py` can be elided because of `&self`\nLL |         fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {\n   |                                                                                   ^^^\n   |\nhelp: elide the lifetimes\n   |\nLL ~     impl<'t> ContentString<'t> {\nLL |         // `'py` can be elided because of `&self`\nLL ~         fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {\n   |\n\nerror: the following explicit lifetimes could be elided: 'py\n  --> tests/ui/elidable_lifetime_names.rs:150:14\n   |\nLL |     impl<'t, 'py> ContentString<'t> {\n   |              ^^^\nLL |         // `'py` can be elided because of `&'_ self`\nLL |         fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {\n   |                                                                                      ^^^\n   |\nhelp: elide the lifetimes\n   |\nLL ~     impl<'t> ContentString<'t> {\nLL |         // `'py` can be elided because of `&'_ self`\nLL ~         fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {\n   |\n\nerror: the following explicit lifetimes could be elided: 'py\n  --> tests/ui/elidable_lifetime_names.rs:171:14\n   |\nLL |     impl<'t, 'py> ContentString<'t> {\n   |              ^^^\n...\nLL |         ) -> Content<'t, 'py> {\n   |                          ^^^\n   |\nhelp: elide the lifetimes\n   |\nLL ~     impl<'t> ContentString<'t> {\nLL |         // `'py` can be elided because of `&Self`\n...\nLL |             o: &'t str,\nLL ~         ) -> Content<'t, '_> {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a, 's\n  --> tests/ui/elidable_lifetime_names.rs:202:15\n   |\nLL |     impl<'de, 'a, 's> Trait<'de> for UnitVariantAccess<'a, 'de, 's> {}\n   |               ^^  ^^                                   ^^       ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'de, 'a, 's> Trait<'de> for UnitVariantAccess<'a, 'de, 's> {}\nLL +     impl<'de> Trait<'de> for UnitVariantAccess<'_, 'de, '_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:226:10\n   |\nLL |     impl<'a> T for S1<'a> {}\n   |          ^^           ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a> T for S1<'a> {}\nLL +     impl T for S1<'_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'b\n  --> tests/ui/elidable_lifetime_names.rs:234:14\n   |\nLL |     impl<'a, 'b> TA<'a> for S2<'a, 'b> {}\n   |              ^^                    ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b> TA<'a> for S2<'a, 'b> {}\nLL +     impl<'a> TA<'a> for S2<'a, '_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:238:10\n   |\nLL |     impl<'a, 'b> TB<'b> for S2<'a, 'b> {}\n   |          ^^                    ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b> TB<'b> for S2<'a, 'b> {}\nLL +     impl<'b> TB<'b> for S2<'_, 'b> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a, 'b\n  --> tests/ui/elidable_lifetime_names.rs:242:10\n   |\nLL |     impl<'a, 'b> T for S2<'a, 'b> {}\n   |          ^^  ^^           ^^  ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b> T for S2<'a, 'b> {}\nLL +     impl T for S2<'_, '_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'c\n  --> tests/ui/elidable_lifetime_names.rs:250:18\n   |\nLL |     impl<'a, 'b, 'c> TAB<'a, 'b> for S3<'a, 'b, 'c> {}\n   |                  ^^                             ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b, 'c> TAB<'a, 'b> for S3<'a, 'b, 'c> {}\nLL +     impl<'a, 'b> TAB<'a, 'b> for S3<'a, 'b, '_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'b\n  --> tests/ui/elidable_lifetime_names.rs:254:14\n   |\nLL |     impl<'a, 'b, 'c> TAC<'a, 'c> for S3<'a, 'b, 'c> {}\n   |              ^^                             ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b, 'c> TAC<'a, 'c> for S3<'a, 'b, 'c> {}\nLL +     impl<'a, 'c> TAC<'a, 'c> for S3<'a, '_, 'c> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'b, 'c\n  --> tests/ui/elidable_lifetime_names.rs:258:14\n   |\nLL |     impl<'a, 'b, 'c> TA<'a> for S3<'a, 'b, 'c> {}\n   |              ^^  ^^                    ^^  ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b, 'c> TA<'a> for S3<'a, 'b, 'c> {}\nLL +     impl<'a> TA<'a> for S3<'a, '_, '_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/elidable_lifetime_names.rs:262:10\n   |\nLL |     impl<'a, 'b, 'c> TBC<'b, 'c> for S3<'a, 'b, 'c> {}\n   |          ^^                             ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b, 'c> TBC<'b, 'c> for S3<'a, 'b, 'c> {}\nLL +     impl<'b, 'c> TBC<'b, 'c> for S3<'_, 'b, 'c> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a, 'c\n  --> tests/ui/elidable_lifetime_names.rs:266:10\n   |\nLL |     impl<'a, 'b, 'c> TB<'b> for S3<'a, 'b, 'c> {}\n   |          ^^      ^^                ^^      ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b, 'c> TB<'b> for S3<'a, 'b, 'c> {}\nLL +     impl<'b> TB<'b> for S3<'_, 'b, '_> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a, 'b\n  --> tests/ui/elidable_lifetime_names.rs:270:10\n   |\nLL |     impl<'a, 'b, 'c> TC<'c> for S3<'a, 'b, 'c> {}\n   |          ^^  ^^                    ^^  ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b, 'c> TC<'c> for S3<'a, 'b, 'c> {}\nLL +     impl<'c> TC<'c> for S3<'_, '_, 'c> {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a, 'b, 'c\n  --> tests/ui/elidable_lifetime_names.rs:274:10\n   |\nLL |     impl<'a, 'b, 'c> T for S3<'a, 'b, 'c> {}\n   |          ^^  ^^  ^^           ^^  ^^  ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     impl<'a, 'b, 'c> T for S3<'a, 'b, 'c> {}\nLL +     impl T for S3<'_, '_, '_> {}\n   |\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/else_if_without_else.rs",
    "content": "#![warn(clippy::else_if_without_else)]\n#![allow(clippy::collapsible_else_if)]\n\nfn bla1() -> bool {\n    unimplemented!()\n}\nfn bla2() -> bool {\n    unimplemented!()\n}\nfn bla3() -> bool {\n    unimplemented!()\n}\nfn bla4() -> bool {\n    unimplemented!()\n}\nfn bla5() -> bool {\n    unimplemented!()\n}\n\nfn main() {\n    if bla1() {\n        println!(\"if\");\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else {\n        println!(\"else\");\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else if bla2() {\n        println!(\"else if\");\n    } else {\n        println!(\"else\")\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else if bla2() {\n        println!(\"else if 1\");\n    } else if bla3() {\n        println!(\"else if 2\");\n    } else {\n        println!(\"else\")\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else if bla2() {\n        //~^ else_if_without_else\n\n        println!(\"else if\");\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else if bla2() {\n        println!(\"else if 1\");\n    } else if bla3() {\n        //~^ else_if_without_else\n\n        println!(\"else if 2\");\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else if bla2() {\n        println!(\"else if 1\");\n    } else if bla3() {\n        println!(\"else if 2\");\n    } else if bla4() {\n        println!(\"else if 3\");\n    } else if bla5() {\n        println!(\"else if 4\");\n    } else {\n        println!(\"else\");\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else if bla2() {\n        println!(\"else if 1\");\n    } else if bla3() {\n        println!(\"else if 2\");\n    } else if bla4() {\n        println!(\"else if 3\");\n    } else if bla5() {\n        //~^ else_if_without_else\n\n        println!(\"else if 4\");\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else if bla2() {\n        println!(\"else if 1\");\n    } else {\n        if bla3() {\n            println!(\"else if 2\");\n        } else if bla4() {\n            println!(\"else if 3\");\n        } else if bla5() {\n            println!(\"else if 4\");\n        } else {\n            println!(\"else\");\n        }\n    }\n\n    if bla1() {\n        println!(\"if\");\n    } else if bla2() {\n        println!(\"else if 1\");\n    } else {\n        if bla3() {\n            println!(\"else if 2\");\n        } else if bla4() {\n            println!(\"else if 3\");\n        } else if bla5() {\n            //~^ else_if_without_else\n\n            println!(\"else if 4\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/else_if_without_else.stderr",
    "content": "error: `if` expression with an `else if`, but without a final `else`\n  --> tests/ui/else_if_without_else.rs:51:12\n   |\nLL |       } else if bla2() {\n   |  ____________^\nLL | |\nLL | |\nLL | |         println!(\"else if\");\nLL | |     }\n   | |_____^\n   |\n   = help: add an `else` block here\n   = note: `-D clippy::else-if-without-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::else_if_without_else)]`\n\nerror: `if` expression with an `else if`, but without a final `else`\n  --> tests/ui/else_if_without_else.rs:61:12\n   |\nLL |       } else if bla3() {\n   |  ____________^\nLL | |\nLL | |\nLL | |         println!(\"else if 2\");\nLL | |     }\n   | |_____^\n   |\n   = help: add an `else` block here\n\nerror: `if` expression with an `else if`, but without a final `else`\n  --> tests/ui/else_if_without_else.rs:89:12\n   |\nLL |       } else if bla5() {\n   |  ____________^\nLL | |\nLL | |\nLL | |         println!(\"else if 4\");\nLL | |     }\n   | |_____^\n   |\n   = help: add an `else` block here\n\nerror: `if` expression with an `else if`, but without a final `else`\n  --> tests/ui/else_if_without_else.rs:120:16\n   |\nLL |           } else if bla5() {\n   |  ________________^\nLL | |\nLL | |\nLL | |             println!(\"else if 4\");\nLL | |         }\n   | |_________^\n   |\n   = help: add an `else` block here\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/empty_docs.rs",
    "content": "//@aux-build:proc_macro_attr.rs\n\n#![allow(unused)]\n#![warn(clippy::empty_docs)]\n#![allow(clippy::mixed_attributes_style)]\n#![feature(extern_types)]\n\nmod outer {\n    //!\n    //~^ empty_docs\n\n    /// this is a struct\n    struct Bananas {\n        /// count\n        count: usize,\n    }\n\n    ///\n    //~^ empty_docs\n    enum Warn {\n        ///\n        //~^ empty_docs\n        A,\n        B,\n    }\n\n    enum DontWarn {\n        /// i\n        A,\n        B,\n    }\n\n    #[doc = \"\"]\n    //~^ empty_docs\n    fn warn_about_this() {}\n\n    #[doc = \"\"]\n    #[doc = \"\"]\n    //~^^ empty_docs\n    fn this_doesn_warn() {}\n\n    #[doc = \"a fine function\"]\n    fn this_is_fine() {}\n\n    ///\n    //~^ empty_docs\n    mod inner {\n        ///\n        fn dont_warn_inner_outer() {\n            //!w\n        }\n\n        fn this_is_ok() {\n            //!\n            //! inside the function\n        }\n\n        fn warn() {\n            /*! */\n            //~^ empty_docs\n        }\n\n        fn dont_warn() {\n            /*! dont warn me */\n        }\n\n        trait NoDoc {\n            ///\n            //~^ empty_docs\n            fn some() {}\n        }\n    }\n\n    union Unite {\n        /// lint y\n        x: i32,\n        ///\n        //~^ empty_docs\n        y: i32,\n    }\n}\n\nmod issue_12377 {\n    use proc_macro_attr::with_empty_docs;\n\n    #[with_empty_docs]\n    unsafe extern \"C\" {\n        type Test;\n    }\n\n    #[with_empty_docs]\n    struct Foo {\n        a: u8,\n    }\n}\n"
  },
  {
    "path": "tests/ui/empty_docs.stderr",
    "content": "error: empty doc comment\n  --> tests/ui/empty_docs.rs:9:5\n   |\nLL |     //!\n   |     ^^^\n   |\n   = help: consider removing or filling it\n   = note: `-D clippy::empty-docs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_docs)]`\n\nerror: empty doc comment\n  --> tests/ui/empty_docs.rs:18:5\n   |\nLL |     ///\n   |     ^^^\n   |\n   = help: consider removing or filling it\n\nerror: empty doc comment\n  --> tests/ui/empty_docs.rs:21:9\n   |\nLL |         ///\n   |         ^^^\n   |\n   = help: consider removing or filling it\n\nerror: empty doc comment\n  --> tests/ui/empty_docs.rs:33:13\n   |\nLL |     #[doc = \"\"]\n   |             ^^\n   |\n   = help: consider removing or filling it\n\nerror: empty doc comment\n  --> tests/ui/empty_docs.rs:37:13\n   |\nLL |       #[doc = \"\"]\n   |  _____________^\nLL | |     #[doc = \"\"]\n   | |______________^\n   |\n   = help: consider removing or filling it\n\nerror: empty doc comment\n  --> tests/ui/empty_docs.rs:45:5\n   |\nLL |     ///\n   |     ^^^\n   |\n   = help: consider removing or filling it\n\nerror: empty doc comment\n  --> tests/ui/empty_docs.rs:59:13\n   |\nLL |             /*! */\n   |             ^^^^^^\n   |\n   = help: consider removing or filling it\n\nerror: empty doc comment\n  --> tests/ui/empty_docs.rs:68:13\n   |\nLL |             ///\n   |             ^^^\n   |\n   = help: consider removing or filling it\n\nerror: empty doc comment\n  --> tests/ui/empty_docs.rs:77:9\n   |\nLL |         ///\n   |         ^^^\n   |\n   = help: consider removing or filling it\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/empty_drop.fixed",
    "content": "#![warn(clippy::empty_drop)]\n#![allow(unused)]\n\n// should cause an error\nstruct Foo;\n\n\n// shouldn't cause an error\nstruct Bar;\n\nimpl Drop for Bar {\n    fn drop(&mut self) {\n        println!(\"dropping bar!\");\n    }\n}\n\n// should error\nstruct Baz;\n\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_drop.rs",
    "content": "#![warn(clippy::empty_drop)]\n#![allow(unused)]\n\n// should cause an error\nstruct Foo;\n\nimpl Drop for Foo {\n    //~^ empty_drop\n    fn drop(&mut self) {}\n}\n\n// shouldn't cause an error\nstruct Bar;\n\nimpl Drop for Bar {\n    fn drop(&mut self) {\n        println!(\"dropping bar!\");\n    }\n}\n\n// should error\nstruct Baz;\n\nimpl Drop for Baz {\n    //~^ empty_drop\n    fn drop(&mut self) {\n        {}\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_drop.stderr",
    "content": "error: empty drop implementation\n  --> tests/ui/empty_drop.rs:7:1\n   |\nLL | / impl Drop for Foo {\nLL | |\nLL | |     fn drop(&mut self) {}\nLL | | }\n   | |_^\n   |\n   = note: `-D clippy::empty-drop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_drop)]`\n   = help: try removing this impl\n\nerror: empty drop implementation\n  --> tests/ui/empty_drop.rs:24:1\n   |\nLL | / impl Drop for Baz {\nLL | |\nLL | |     fn drop(&mut self) {\nLL | |         {}\nLL | |     }\nLL | | }\n   | |_^\n   |\n   = help: try removing this impl\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/empty_enum_variants_with_brackets.fixed",
    "content": "#![warn(clippy::empty_enum_variants_with_brackets)]\n#![allow(dead_code)]\n#![feature(more_qualified_paths)]\n\npub enum PublicTestEnum {\n    NonEmptyBraces { x: i32, y: i32 }, // No error\n    NonEmptyParentheses(i32, i32),     // No error\n    EmptyBraces,\n    //~^ empty_enum_variants_with_brackets\n    EmptyParentheses(), // No error as enum is pub\n}\n\nenum TestEnum {\n    NonEmptyBraces { x: i32, y: i32 }, // No error\n    NonEmptyParentheses(i32, i32),     // No error\n    EmptyBraces,\n    //~^ empty_enum_variants_with_brackets\n    EmptyParentheses,\n    //~^ empty_enum_variants_with_brackets\n    AnotherEnum, // No error\n}\n\nmod issue12551 {\n    enum EvenOdd {\n        // Used as functions -> no error\n        Even(),\n        Odd(),\n        // Not used as a function\n        Unknown,\n        //~^ empty_enum_variants_with_brackets\n    }\n\n    fn even_odd(x: i32) -> EvenOdd {\n        (x % 2 == 0).then(EvenOdd::Even).unwrap_or_else(EvenOdd::Odd)\n    }\n\n    fn natural_number(x: i32) -> NaturalOrNot {\n        (x > 0)\n            .then(NaturalOrNot::Natural)\n            .unwrap_or_else(NaturalOrNot::NotNatural)\n    }\n\n    enum NaturalOrNot {\n        // Used as functions -> no error\n        Natural(),\n        NotNatural(),\n        // Not used as a function\n        Unknown,\n        //~^ empty_enum_variants_with_brackets\n    }\n\n    enum RedundantParenthesesFunctionCall {\n        // Used as a function call but with redundant parentheses\n        Parentheses,\n        //~^ empty_enum_variants_with_brackets\n        // Not used as a function\n        NoParentheses,\n    }\n\n    #[allow(clippy::no_effect)]\n    fn redundant_parentheses_function_call() {\n        // The parentheses in the below line are redundant.\n        RedundantParenthesesFunctionCall::Parentheses;\n        RedundantParenthesesFunctionCall::NoParentheses;\n    }\n\n    // Same test as above but with usage of the enum occurring before the definition.\n    #[allow(clippy::no_effect)]\n    fn redundant_parentheses_function_call_2() {\n        // The parentheses in the below line are redundant.\n        RedundantParenthesesFunctionCall2::Parentheses;\n        RedundantParenthesesFunctionCall2::NoParentheses;\n    }\n\n    enum RedundantParenthesesFunctionCall2 {\n        // Used as a function call but with redundant parentheses\n        Parentheses,\n        //~^ empty_enum_variants_with_brackets\n        // Not used as a function\n        NoParentheses,\n    }\n}\n\nenum TestEnumWithFeatures {\n    NonEmptyBraces {\n        #[cfg(feature = \"thisisneverenabled\")]\n        x: i32,\n    }, // No error\n    NonEmptyParentheses(#[cfg(feature = \"thisisneverenabled\")] i32), // No error\n}\n\n#[derive(Clone)]\nenum Foo {\n    Variant1(i32),\n    Variant2,\n    Variant3, //~ ERROR: enum variant has empty brackets\n}\n\n#[derive(Clone)]\npub enum PubFoo {\n    Variant1(i32),\n    Variant2,\n    Variant3(),\n}\n\nfn issue16157() {\n    enum E {\n        V,\n        //~^ empty_enum_variants_with_brackets\n    }\n\n    let E::V = E::V;\n\n    <E>::V = E::V;\n    <E>::V = E::V;\n}\n\nfn variant_with_braces() {\n    enum E {\n        V,\n        //~^ empty_enum_variants_with_brackets\n    }\n    E::V = E::V;\n    E::V = E::V;\n    <E>::V = <E>::V;\n\n    enum F {\n        U,\n        //~^ empty_enum_variants_with_brackets\n    }\n    F::U = F::U;\n    <F>::U = F::U;\n}\n\nfn variant_with_comments_and_cfg() {\n    enum E {\n        V(\n            // This is a comment\n        ),\n    }\n    E::V() = E::V();\n\n    enum F {\n        U {\n            // This is a comment\n        },\n    }\n    F::U {} = F::U {};\n\n    enum G {\n        V(#[cfg(target_os = \"cuda\")] String),\n    }\n    G::V() = G::V();\n\n    enum H {\n        U {\n            #[cfg(target_os = \"cuda\")]\n            value: String,\n        },\n    }\n    H::U {} = H::U {};\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_enum_variants_with_brackets.rs",
    "content": "#![warn(clippy::empty_enum_variants_with_brackets)]\n#![allow(dead_code)]\n#![feature(more_qualified_paths)]\n\npub enum PublicTestEnum {\n    NonEmptyBraces { x: i32, y: i32 }, // No error\n    NonEmptyParentheses(i32, i32),     // No error\n    EmptyBraces {},\n    //~^ empty_enum_variants_with_brackets\n    EmptyParentheses(), // No error as enum is pub\n}\n\nenum TestEnum {\n    NonEmptyBraces { x: i32, y: i32 }, // No error\n    NonEmptyParentheses(i32, i32),     // No error\n    EmptyBraces {},\n    //~^ empty_enum_variants_with_brackets\n    EmptyParentheses(),\n    //~^ empty_enum_variants_with_brackets\n    AnotherEnum, // No error\n}\n\nmod issue12551 {\n    enum EvenOdd {\n        // Used as functions -> no error\n        Even(),\n        Odd(),\n        // Not used as a function\n        Unknown(),\n        //~^ empty_enum_variants_with_brackets\n    }\n\n    fn even_odd(x: i32) -> EvenOdd {\n        (x % 2 == 0).then(EvenOdd::Even).unwrap_or_else(EvenOdd::Odd)\n    }\n\n    fn natural_number(x: i32) -> NaturalOrNot {\n        (x > 0)\n            .then(NaturalOrNot::Natural)\n            .unwrap_or_else(NaturalOrNot::NotNatural)\n    }\n\n    enum NaturalOrNot {\n        // Used as functions -> no error\n        Natural(),\n        NotNatural(),\n        // Not used as a function\n        Unknown(),\n        //~^ empty_enum_variants_with_brackets\n    }\n\n    enum RedundantParenthesesFunctionCall {\n        // Used as a function call but with redundant parentheses\n        Parentheses(),\n        //~^ empty_enum_variants_with_brackets\n        // Not used as a function\n        NoParentheses,\n    }\n\n    #[allow(clippy::no_effect)]\n    fn redundant_parentheses_function_call() {\n        // The parentheses in the below line are redundant.\n        RedundantParenthesesFunctionCall::Parentheses();\n        RedundantParenthesesFunctionCall::NoParentheses;\n    }\n\n    // Same test as above but with usage of the enum occurring before the definition.\n    #[allow(clippy::no_effect)]\n    fn redundant_parentheses_function_call_2() {\n        // The parentheses in the below line are redundant.\n        RedundantParenthesesFunctionCall2::Parentheses();\n        RedundantParenthesesFunctionCall2::NoParentheses;\n    }\n\n    enum RedundantParenthesesFunctionCall2 {\n        // Used as a function call but with redundant parentheses\n        Parentheses(),\n        //~^ empty_enum_variants_with_brackets\n        // Not used as a function\n        NoParentheses,\n    }\n}\n\nenum TestEnumWithFeatures {\n    NonEmptyBraces {\n        #[cfg(feature = \"thisisneverenabled\")]\n        x: i32,\n    }, // No error\n    NonEmptyParentheses(#[cfg(feature = \"thisisneverenabled\")] i32), // No error\n}\n\n#[derive(Clone)]\nenum Foo {\n    Variant1(i32),\n    Variant2,\n    Variant3(), //~ ERROR: enum variant has empty brackets\n}\n\n#[derive(Clone)]\npub enum PubFoo {\n    Variant1(i32),\n    Variant2,\n    Variant3(),\n}\n\nfn issue16157() {\n    enum E {\n        V(),\n        //~^ empty_enum_variants_with_brackets\n    }\n\n    let E::V() = E::V();\n\n    <E>::V() = E::V();\n    <E>::V {} = E::V();\n}\n\nfn variant_with_braces() {\n    enum E {\n        V(),\n        //~^ empty_enum_variants_with_brackets\n    }\n    E::V() = E::V();\n    E::V() = E::V {};\n    <E>::V {} = <E>::V {};\n\n    enum F {\n        U {},\n        //~^ empty_enum_variants_with_brackets\n    }\n    F::U {} = F::U {};\n    <F>::U {} = F::U {};\n}\n\nfn variant_with_comments_and_cfg() {\n    enum E {\n        V(\n            // This is a comment\n        ),\n    }\n    E::V() = E::V();\n\n    enum F {\n        U {\n            // This is a comment\n        },\n    }\n    F::U {} = F::U {};\n\n    enum G {\n        V(#[cfg(target_os = \"cuda\")] String),\n    }\n    G::V() = G::V();\n\n    enum H {\n        U {\n            #[cfg(target_os = \"cuda\")]\n            value: String,\n        },\n    }\n    H::U {} = H::U {};\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_enum_variants_with_brackets.stderr",
    "content": "error: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:8:16\n   |\nLL |     EmptyBraces {},\n   |                ^^^\n   |\n   = note: `-D clippy::empty-enum-variants-with-brackets` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_enum_variants_with_brackets)]`\n   = help: remove the brackets\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:16:16\n   |\nLL |     EmptyBraces {},\n   |                ^^^\n   |\n   = help: remove the brackets\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:18:21\n   |\nLL |     EmptyParentheses(),\n   |                     ^^\n   |\n   = help: remove the brackets\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:29:16\n   |\nLL |         Unknown(),\n   |                ^^\n   |\n   = help: remove the brackets\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:48:16\n   |\nLL |         Unknown(),\n   |                ^^\n   |\n   = help: remove the brackets\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:54:20\n   |\nLL |         Parentheses(),\n   |                    ^^\n   |\nhelp: remove the brackets\n   |\nLL ~         Parentheses,\nLL |\n...\nLL |         // The parentheses in the below line are redundant.\nLL ~         RedundantParenthesesFunctionCall::Parentheses;\n   |\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:77:20\n   |\nLL |         Parentheses(),\n   |                    ^^\n   |\nhelp: remove the brackets\n   |\nLL ~         RedundantParenthesesFunctionCall2::Parentheses;\nLL |         RedundantParenthesesFunctionCall2::NoParentheses;\n...\nLL |         // Used as a function call but with redundant parentheses\nLL ~         Parentheses,\n   |\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:96:13\n   |\nLL |     Variant3(),\n   |             ^^\n   |\n   = help: remove the brackets\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:108:10\n   |\nLL |         V(),\n   |          ^^\n   |\nhelp: remove the brackets\n   |\nLL ~         V,\nLL |\nLL |     }\nLL |\nLL ~     let E::V = E::V;\nLL |\nLL ~     <E>::V = E::V;\nLL ~     <E>::V = E::V;\n   |\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:120:10\n   |\nLL |         V(),\n   |          ^^\n   |\nhelp: remove the brackets\n   |\nLL ~         V,\nLL |\nLL |     }\nLL ~     E::V = E::V;\nLL ~     E::V = E::V;\nLL ~     <E>::V = <E>::V;\n   |\n\nerror: enum variant has empty brackets\n  --> tests/ui/empty_enum_variants_with_brackets.rs:128:10\n   |\nLL |         U {},\n   |          ^^^\n   |\nhelp: remove the brackets\n   |\nLL ~         U,\nLL |\nLL |     }\nLL ~     F::U = F::U;\nLL ~     <F>::U = F::U;\n   |\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/empty_enums.rs",
    "content": "#![warn(clippy::empty_enums)]\n// Enable never type to test empty enum lint\n#![feature(never_type)]\n\nenum Empty {}\n//~^ empty_enums\n\nmod issue15910 {\n    enum NotReallyEmpty {\n        #[cfg(false)]\n        Hidden,\n    }\n\n    enum OneVisibleVariant {\n        #[cfg(false)]\n        Hidden,\n        Visible,\n    }\n\n    enum CfgInsideVariant {\n        Variant(#[cfg(false)] String),\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_enums.stderr",
    "content": "error: enum with no variants\n  --> tests/ui/empty_enums.rs:5:1\n   |\nLL | enum Empty {}\n   | ^^^^^^^^^^^^^\n   |\n   = help: consider using the uninhabited type `!` (never type) or a wrapper around it to introduce a type which can't be instantiated\n   = note: `-D clippy::empty-enums` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_enums)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/empty_enums_without_never_type.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::empty_enums)]\n\n// `never_type` is not enabled; this test has no stderr file\nenum Empty {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_line_after/doc_comments.1.fixed",
    "content": "#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]\n\n//~vvv empty_line_after_doc_comments\n/// Meant to be an\n/// inner doc comment\n/// for the crate\nfn first_in_crate() {}\n\nmod m {\n    //~vvv empty_line_after_doc_comments\n    /// Meant to be an\n    /// inner doc comment\n    /// for the module\n    fn first_in_module() {}\n}\n\nmod some_mod {\n    //! This doc comment should *NOT* produce a warning\n\n    mod some_inner_mod {\n        fn some_noop() {}\n    }\n\n    //~v empty_line_after_doc_comments\n    /// # Indented\n    /// Blank line\n    fn indented() {}\n}\n\n//~v empty_line_after_doc_comments\n/// This should produce a warning\nfn with_doc_and_newline() {}\n\n// This should *NOT* produce a warning\n#[crate_type = \"lib\"]\n/// some comment\nfn with_no_newline_and_comment() {}\n\n//~v empty_line_after_doc_comments\n/// This doc comment should produce a warning\n/** This is also a doc comment and is part of the warning\n */\n#[allow(non_camel_case_types)]\n#[allow(missing_docs)]\n#[allow(dead_code)]\nfn three_attributes() {}\n\nmod misattributed {\n    //~v empty_line_after_doc_comments\n    /// docs for `old_code`\n    // fn old_code() {}\n    fn new_code() {}\n\n    //~vv empty_line_after_doc_comments\n    /// Docs\n    /// for OldA\n    // struct OldA;\n    /// Docs\n    /// for OldB\n    // struct OldB;\n    /// Docs\n    /// for Multiple\n    #[allow(dead_code)]\n    struct Multiple;\n}\n\nmod block_comments {\n    //~v empty_line_after_doc_comments\n    /**\n     * Meant to be inner doc comment\n     */\n    fn first_in_module() {}\n\n    //~v empty_line_after_doc_comments\n    /**\n     * Docs for `old_code`\n     */\n    /* fn old_code() {} */\n    /**\n     * Docs for `new_code`\n     */\n    fn new_code() {}\n\n    //~v empty_line_after_doc_comments\n    /// Docs for `old_code2`\n    /* fn old_code2() {} */\n    /// Docs for `new_code2`\n    fn new_code2() {}\n}\n\n// This should *NOT* produce a warning\n#[doc = \"\nReturns the escaped value of the textual representation of\n\n\"]\npub fn function() -> bool {\n    true\n}\n\n// This should *NOT* produce a warning\n#[derive(Clone, Copy)]\npub enum FooFighter {\n    Bar1,\n\n    Bar2,\n\n    Bar3,\n\n    Bar4,\n}\n\n/// Should not lint\n// some line comment\n/// gaps without an empty line\nstruct LineComment;\n\n/// This should *NOT* produce a warning because the empty line is inside a block comment\n/*\n\n*/\npub struct EmptyInBlockComment;\n\n/// This should *NOT* produce a warning\n/* test */\npub struct BlockComment;\n\n/// Ignore the empty line inside a cfg_attr'd out attribute\n#[cfg_attr(any(), multiline(\n    foo = 1\n\n    bar = 2\n))]\nfn empty_line_in_cfg_attr() {}\n\ntrait Foo {\n    fn bar();\n}\n\nimpl Foo for LineComment {\n    /// comment on assoc item\n    //~^ empty_line_after_doc_comments\n    fn bar() {}\n}\n\n//~v empty_line_after_doc_comments\n/// Docs for this item.\n// fn some_item() {}\nimpl LineComment {} // or any other nameless item kind\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_line_after/doc_comments.2.fixed",
    "content": "#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]\n\n//~vvv empty_line_after_doc_comments\n//! Meant to be an\n//! inner doc comment\n//! for the crate\n\nfn first_in_crate() {}\n\nmod m {\n    //~vvv empty_line_after_doc_comments\n    //! Meant to be an\n    //! inner doc comment\n    //! for the module\n\n    fn first_in_module() {}\n}\n\nmod some_mod {\n    //! This doc comment should *NOT* produce a warning\n\n    mod some_inner_mod {\n        fn some_noop() {}\n    }\n\n    //~v empty_line_after_doc_comments\n    /// # Indented\n    ///\n    /// Blank line\n    fn indented() {}\n}\n\n//~v empty_line_after_doc_comments\n/// This should produce a warning\nfn with_doc_and_newline() {}\n\n// This should *NOT* produce a warning\n#[crate_type = \"lib\"]\n/// some comment\nfn with_no_newline_and_comment() {}\n\n//~v empty_line_after_doc_comments\n/// This doc comment should produce a warning\n/** This is also a doc comment and is part of the warning\n */\n#[allow(non_camel_case_types)]\n#[allow(missing_docs)]\n#[allow(dead_code)]\nfn three_attributes() {}\n\nmod misattributed {\n    //~v empty_line_after_doc_comments\n    // /// docs for `old_code`\n    // fn old_code() {}\n\n    fn new_code() {}\n\n    //~vv empty_line_after_doc_comments\n    // /// Docs\n    // /// for OldA\n    // struct OldA;\n\n    // /// Docs\n    // /// for OldB\n    // struct OldB;\n\n    /// Docs\n    /// for Multiple\n    #[allow(dead_code)]\n    struct Multiple;\n}\n\nmod block_comments {\n    //~v empty_line_after_doc_comments\n    /*!\n     * Meant to be inner doc comment\n     */\n\n    fn first_in_module() {}\n\n    //~v empty_line_after_doc_comments\n    /*\n     * Docs for `old_code`\n     */\n    /* fn old_code() {} */\n\n    /**\n     * Docs for `new_code`\n     */\n    fn new_code() {}\n\n    //~v empty_line_after_doc_comments\n    // /// Docs for `old_code2`\n    /* fn old_code2() {} */\n\n    /// Docs for `new_code2`\n    fn new_code2() {}\n}\n\n// This should *NOT* produce a warning\n#[doc = \"\nReturns the escaped value of the textual representation of\n\n\"]\npub fn function() -> bool {\n    true\n}\n\n// This should *NOT* produce a warning\n#[derive(Clone, Copy)]\npub enum FooFighter {\n    Bar1,\n\n    Bar2,\n\n    Bar3,\n\n    Bar4,\n}\n\n/// Should not lint\n// some line comment\n/// gaps without an empty line\nstruct LineComment;\n\n/// This should *NOT* produce a warning because the empty line is inside a block comment\n/*\n\n*/\npub struct EmptyInBlockComment;\n\n/// This should *NOT* produce a warning\n/* test */\npub struct BlockComment;\n\n/// Ignore the empty line inside a cfg_attr'd out attribute\n#[cfg_attr(any(), multiline(\n    foo = 1\n\n    bar = 2\n))]\nfn empty_line_in_cfg_attr() {}\n\ntrait Foo {\n    fn bar();\n}\n\nimpl Foo for LineComment {\n    // /// comment on assoc item\n    //~^ empty_line_after_doc_comments\n\n    fn bar() {}\n}\n\n//~v empty_line_after_doc_comments\n// /// Docs for this item.\n// fn some_item() {}\n\nimpl LineComment {} // or any other nameless item kind\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_line_after/doc_comments.rs",
    "content": "#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]\n\n//~vvv empty_line_after_doc_comments\n/// Meant to be an\n/// inner doc comment\n/// for the crate\n\nfn first_in_crate() {}\n\nmod m {\n    //~vvv empty_line_after_doc_comments\n    /// Meant to be an\n    /// inner doc comment\n    /// for the module\n\n    fn first_in_module() {}\n}\n\nmod some_mod {\n    //! This doc comment should *NOT* produce a warning\n\n    mod some_inner_mod {\n        fn some_noop() {}\n    }\n\n    //~v empty_line_after_doc_comments\n    /// # Indented\n\n    /// Blank line\n    fn indented() {}\n}\n\n//~v empty_line_after_doc_comments\n/// This should produce a warning\n\nfn with_doc_and_newline() {}\n\n// This should *NOT* produce a warning\n#[crate_type = \"lib\"]\n/// some comment\nfn with_no_newline_and_comment() {}\n\n//~v empty_line_after_doc_comments\n/// This doc comment should produce a warning\n\n/** This is also a doc comment and is part of the warning\n */\n\n#[allow(non_camel_case_types)]\n#[allow(missing_docs)]\n#[allow(dead_code)]\nfn three_attributes() {}\n\nmod misattributed {\n    //~v empty_line_after_doc_comments\n    /// docs for `old_code`\n    // fn old_code() {}\n\n    fn new_code() {}\n\n    //~vv empty_line_after_doc_comments\n    /// Docs\n    /// for OldA\n    // struct OldA;\n\n    /// Docs\n    /// for OldB\n    // struct OldB;\n\n    /// Docs\n    /// for Multiple\n    #[allow(dead_code)]\n    struct Multiple;\n}\n\nmod block_comments {\n    //~v empty_line_after_doc_comments\n    /**\n     * Meant to be inner doc comment\n     */\n\n    fn first_in_module() {}\n\n    //~v empty_line_after_doc_comments\n    /**\n     * Docs for `old_code`\n     */\n    /* fn old_code() {} */\n\n    /**\n     * Docs for `new_code`\n     */\n    fn new_code() {}\n\n    //~v empty_line_after_doc_comments\n    /// Docs for `old_code2`\n    /* fn old_code2() {} */\n\n    /// Docs for `new_code2`\n    fn new_code2() {}\n}\n\n// This should *NOT* produce a warning\n#[doc = \"\nReturns the escaped value of the textual representation of\n\n\"]\npub fn function() -> bool {\n    true\n}\n\n// This should *NOT* produce a warning\n#[derive(Clone, Copy)]\npub enum FooFighter {\n    Bar1,\n\n    Bar2,\n\n    Bar3,\n\n    Bar4,\n}\n\n/// Should not lint\n// some line comment\n/// gaps without an empty line\nstruct LineComment;\n\n/// This should *NOT* produce a warning because the empty line is inside a block comment\n/*\n\n*/\npub struct EmptyInBlockComment;\n\n/// This should *NOT* produce a warning\n/* test */\npub struct BlockComment;\n\n/// Ignore the empty line inside a cfg_attr'd out attribute\n#[cfg_attr(any(), multiline(\n    foo = 1\n\n    bar = 2\n))]\nfn empty_line_in_cfg_attr() {}\n\ntrait Foo {\n    fn bar();\n}\n\nimpl Foo for LineComment {\n    /// comment on assoc item\n    //~^ empty_line_after_doc_comments\n\n    fn bar() {}\n}\n\n//~v empty_line_after_doc_comments\n/// Docs for this item.\n// fn some_item() {}\n\nimpl LineComment {} // or any other nameless item kind\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_line_after/doc_comments.stderr",
    "content": "error: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:6:1\n   |\nLL | / /// for the crate\nLL | |\n   | |_^\nLL |   fn first_in_crate() {}\n   |   ----------------- the comment documents this function\n   |\n   = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]`\n   = help: if the empty line is unintentional, remove it\nhelp: if the comment should document the crate use an inner doc comment\n   |\nLL ~ //! Meant to be an\nLL ~ //! inner doc comment\nLL ~ //! for the crate\n   |\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:14:5\n   |\nLL | /     /// for the module\nLL | |\n   | |_^\nLL |       fn first_in_module() {}\n   |       ------------------ the comment documents this function\n   |\n   = help: if the empty line is unintentional, remove it\nhelp: if the comment should document the parent module use an inner doc comment\n   |\nLL ~     //! Meant to be an\nLL ~     //! inner doc comment\nLL ~     //! for the module\n   |\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:27:5\n   |\nLL | /     /// # Indented\nLL | |\n   | |_^\nLL |       /// Blank line\nLL |       fn indented() {}\n   |       ----------- the comment documents this function\n   |\n   = help: if the empty line is unintentional, remove it\nhelp: if the documentation should include the empty line include it in the comment\n   |\nLL |     ///\n   |\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:34:1\n   |\nLL | / /// This should produce a warning\nLL | |\n   | |_^\nLL |   fn with_doc_and_newline() {}\n   |   ----------------------- the comment documents this function\n   |\n   = help: if the empty line is unintentional, remove it\n\nerror: empty lines after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:44:1\n   |\nLL | / /// This doc comment should produce a warning\nLL | |\nLL | | /** This is also a doc comment and is part of the warning\nLL | |  */\nLL | |\n   | |_^\n...\nLL |   fn three_attributes() {}\n   |   ------------------- the comment documents this function\n   |\n   = help: if the empty lines are unintentional, remove them\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:56:5\n   |\nLL | /     /// docs for `old_code`\nLL | |     // fn old_code() {}\nLL | |\n   | |_^\nLL |       fn new_code() {}\n   |       ----------- the comment documents this function\n   |\n   = help: if the empty line is unintentional, remove it\nhelp: if the doc comment should not document function `new_code` then comment it out\n   |\nLL |     // /// docs for `old_code`\n   |     ++\n\nerror: empty lines after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:63:5\n   |\nLL | /     /// for OldA\nLL | |     // struct OldA;\nLL | |\nLL | |     /// Docs\n...  |\nLL | |\n   | |_^\n...\nLL |       struct Multiple;\n   |       --------------- the comment documents this struct\n   |\n   = help: if the empty lines are unintentional, remove them\nhelp: if the doc comment should not document struct `Multiple` then comment it out\n   |\nLL ~     // /// Docs\nLL ~     // /// for OldA\nLL |     // struct OldA;\nLL |\nLL ~     // /// Docs\nLL ~     // /// for OldB\n   |\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:78:5\n   |\nLL | /     /**\nLL | |      * Meant to be inner doc comment\nLL | |      */\nLL | |\n   | |_^\nLL |       fn first_in_module() {}\n   |       ------------------ the comment documents this function\n   |\n   = help: if the empty line is unintentional, remove it\nhelp: if the comment should document the parent module use an inner doc comment\n   |\nLL -     /**\nLL +     /*!\n   |\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:85:5\n   |\nLL | /     /**\nLL | |      * Docs for `old_code`\nLL | |      */\nLL | |     /* fn old_code() {} */\nLL | |\n   | |_^\n...\nLL |       fn new_code() {}\n   |       ----------- the comment documents this function\n   |\n   = help: if the empty line is unintentional, remove it\nhelp: if the doc comment should not document function `new_code` then comment it out\n   |\nLL -     /**\nLL +     /*\n   |\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:96:5\n   |\nLL | /     /// Docs for `old_code2`\nLL | |     /* fn old_code2() {} */\nLL | |\n   | |_^\nLL |       /// Docs for `new_code2`\nLL |       fn new_code2() {}\n   |       ------------ the comment documents this function\n   |\n   = help: if the empty line is unintentional, remove it\nhelp: if the doc comment should not document function `new_code2` then comment it out\n   |\nLL |     // /// Docs for `old_code2`\n   |     ++\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:152:5\n   |\nLL | /     /// comment on assoc item\nLL | |\nLL | |\n   | |_^\nLL |       fn bar() {}\n   |       ------ the comment documents this function\n   |\n   = help: if the empty line is unintentional, remove it\nhelp: if the doc comment should not document function `bar` then comment it out\n   |\nLL |     // /// comment on assoc item\n   |     ++\n\nerror: empty line after doc comment\n  --> tests/ui/empty_line_after/doc_comments.rs:159:1\n   |\nLL | / /// Docs for this item.\nLL | | // fn some_item() {}\nLL | |\n   | |_^\nLL |   impl LineComment {} // or any other nameless item kind\n   |   - the comment documents this implementation\n   |\n   = help: if the empty line is unintentional, remove it\nhelp: if the doc comment should not document the following item then comment it out\n   |\nLL | // /// Docs for this item.\n   | ++\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/empty_line_after/outer_attribute.1.fixed",
    "content": "//@aux-build:../auxiliary/proc_macro_attr.rs\n#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]\n\n//~v empty_line_after_outer_attr\n#[crate_type = \"lib\"]\nfn first_in_crate() {}\n\n#[macro_use]\nextern crate proc_macro_attr;\n\n//~v empty_line_after_outer_attr\n#[inline]\n/// some comment\nfn with_one_newline_and_comment() {}\n\n#[inline]\n/// some comment\nfn with_no_newline_and_comment() {}\n\n//~v empty_line_after_outer_attr\n#[inline]\nfn with_one_newline() {}\n\n#[rustfmt::skip]\nmod two_lines {\n    //~v empty_line_after_outer_attr\n    #[crate_type = \"lib\"]\n    fn with_two_newlines() {}\n}\n\n//~v empty_line_after_outer_attr\n#[doc = \"doc attributes should be considered attributes\"]\nenum Baz {\n    One,\n    Two,\n}\n\n//~v empty_line_after_outer_attr\n#[repr(C)]\nstruct Foo {\n    one: isize,\n    two: isize,\n}\n\n//~v empty_line_after_outer_attr\n#[allow(dead_code)]\nmod foo {}\n\n//~v empty_line_after_outer_attr\n#[inline]\n// Still lint cases where the empty line does not immediately follow the attribute\nfn comment_before_empty_line() {}\n\n//~v empty_line_after_outer_attr\n#[allow(unused)]\n// This comment is isolated\npub fn isolated_comment() {}\n\n#[doc = \"\nReturns the escaped value of the textual representation of\n\n\"]\npub fn function() -> bool {\n    true\n}\n\n#[derive(Clone, Copy)]\npub enum FooFighter {\n    Bar1,\n\n    Bar2,\n\n    Bar3,\n\n    Bar4,\n}\n\n#[crate_type = \"lib\"]\n/*\n\n*/\npub struct EmptyLineInBlockComment;\n\n#[crate_type = \"lib\"]\n/* test */\npub struct BlockComment;\n\n// See https://github.com/rust-lang/rust-clippy/issues/5567\n#[rustfmt::skip]\n#[fake_async_trait]\npub trait Bazz {\n    fn foo() -> Vec<u8> {\n        let _i = \"\";\n\n\n\n        vec![]\n    }\n}\n\n#[derive(Clone, Copy)]\n#[dummy(string = \"first line\n\nsecond line\n\")]\npub struct Args;\n\nmod issue_14980 {\n    //~v empty_line_after_outer_attr\n    #[repr(align(536870912))]\n    enum Aligned {\n        Zero = 0,\n        One = 1,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_line_after/outer_attribute.2.fixed",
    "content": "//@aux-build:../auxiliary/proc_macro_attr.rs\n#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]\n\n//~v empty_line_after_outer_attr\n#![crate_type = \"lib\"]\n\nfn first_in_crate() {}\n\n#[macro_use]\nextern crate proc_macro_attr;\n\n//~v empty_line_after_outer_attr\n#[inline]\n/// some comment\nfn with_one_newline_and_comment() {}\n\n#[inline]\n/// some comment\nfn with_no_newline_and_comment() {}\n\n//~v empty_line_after_outer_attr\n#[inline]\nfn with_one_newline() {}\n\n#[rustfmt::skip]\nmod two_lines {\n    //~v empty_line_after_outer_attr\n    #![crate_type = \"lib\"]\n\n\n    fn with_two_newlines() {}\n}\n\n//~v empty_line_after_outer_attr\n#[doc = \"doc attributes should be considered attributes\"]\nenum Baz {\n    One,\n    Two,\n}\n\n//~v empty_line_after_outer_attr\n#[repr(C)]\nstruct Foo {\n    one: isize,\n    two: isize,\n}\n\n//~v empty_line_after_outer_attr\n#[allow(dead_code)]\nmod foo {}\n\n//~v empty_line_after_outer_attr\n#[inline]\n// Still lint cases where the empty line does not immediately follow the attribute\nfn comment_before_empty_line() {}\n\n//~v empty_line_after_outer_attr\n#[allow(unused)]\n// This comment is isolated\npub fn isolated_comment() {}\n\n#[doc = \"\nReturns the escaped value of the textual representation of\n\n\"]\npub fn function() -> bool {\n    true\n}\n\n#[derive(Clone, Copy)]\npub enum FooFighter {\n    Bar1,\n\n    Bar2,\n\n    Bar3,\n\n    Bar4,\n}\n\n#[crate_type = \"lib\"]\n/*\n\n*/\npub struct EmptyLineInBlockComment;\n\n#[crate_type = \"lib\"]\n/* test */\npub struct BlockComment;\n\n// See https://github.com/rust-lang/rust-clippy/issues/5567\n#[rustfmt::skip]\n#[fake_async_trait]\npub trait Bazz {\n    fn foo() -> Vec<u8> {\n        let _i = \"\";\n\n\n\n        vec![]\n    }\n}\n\n#[derive(Clone, Copy)]\n#[dummy(string = \"first line\n\nsecond line\n\")]\npub struct Args;\n\nmod issue_14980 {\n    //~v empty_line_after_outer_attr\n    #[repr(align(536870912))]\n    enum Aligned {\n        Zero = 0,\n        One = 1,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_line_after/outer_attribute.rs",
    "content": "//@aux-build:../auxiliary/proc_macro_attr.rs\n#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]\n\n//~v empty_line_after_outer_attr\n#[crate_type = \"lib\"]\n\nfn first_in_crate() {}\n\n#[macro_use]\nextern crate proc_macro_attr;\n\n//~v empty_line_after_outer_attr\n#[inline]\n\n/// some comment\nfn with_one_newline_and_comment() {}\n\n#[inline]\n/// some comment\nfn with_no_newline_and_comment() {}\n\n//~v empty_line_after_outer_attr\n#[inline]\n\nfn with_one_newline() {}\n\n#[rustfmt::skip]\nmod two_lines {\n    //~v empty_line_after_outer_attr\n    #[crate_type = \"lib\"]\n\n\n    fn with_two_newlines() {}\n}\n\n//~v empty_line_after_outer_attr\n#[doc = \"doc attributes should be considered attributes\"]\n\nenum Baz {\n    One,\n    Two,\n}\n\n//~v empty_line_after_outer_attr\n#[repr(C)]\n\nstruct Foo {\n    one: isize,\n    two: isize,\n}\n\n//~v empty_line_after_outer_attr\n#[allow(dead_code)]\n\nmod foo {}\n\n//~v empty_line_after_outer_attr\n#[inline]\n// Still lint cases where the empty line does not immediately follow the attribute\n\nfn comment_before_empty_line() {}\n\n//~v empty_line_after_outer_attr\n#[allow(unused)]\n\n// This comment is isolated\n\npub fn isolated_comment() {}\n\n#[doc = \"\nReturns the escaped value of the textual representation of\n\n\"]\npub fn function() -> bool {\n    true\n}\n\n#[derive(Clone, Copy)]\npub enum FooFighter {\n    Bar1,\n\n    Bar2,\n\n    Bar3,\n\n    Bar4,\n}\n\n#[crate_type = \"lib\"]\n/*\n\n*/\npub struct EmptyLineInBlockComment;\n\n#[crate_type = \"lib\"]\n/* test */\npub struct BlockComment;\n\n// See https://github.com/rust-lang/rust-clippy/issues/5567\n#[rustfmt::skip]\n#[fake_async_trait]\npub trait Bazz {\n    fn foo() -> Vec<u8> {\n        let _i = \"\";\n\n\n\n        vec![]\n    }\n}\n\n#[derive(Clone, Copy)]\n#[dummy(string = \"first line\n\nsecond line\n\")]\npub struct Args;\n\nmod issue_14980 {\n    //~v empty_line_after_outer_attr\n    #[repr(align(536870912))]\n\n    enum Aligned {\n        Zero = 0,\n        One = 1,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_line_after/outer_attribute.stderr",
    "content": "error: empty line after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:5:1\n   |\nLL | / #[crate_type = \"lib\"]\nLL | |\n   | |_^\nLL |   fn first_in_crate() {}\n   |   ----------------- the attribute applies to this function\n   |\n   = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]`\n   = help: if the empty line is unintentional, remove it\nhelp: if the attribute should apply to the crate use an inner attribute\n   |\nLL | #![crate_type = \"lib\"]\n   |  +\n\nerror: empty line after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:13:1\n   |\nLL | / #[inline]\nLL | |\n   | |_^\nLL |   /// some comment\nLL |   fn with_one_newline_and_comment() {}\n   |   ------------------------------- the attribute applies to this function\n   |\n   = help: if the empty line is unintentional, remove it\n\nerror: empty line after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:23:1\n   |\nLL | / #[inline]\nLL | |\n   | |_^\nLL |   fn with_one_newline() {}\n   |   ------------------- the attribute applies to this function\n   |\n   = help: if the empty line is unintentional, remove it\n\nerror: empty lines after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:30:5\n   |\nLL | /     #[crate_type = \"lib\"]\nLL | |\nLL | |\n   | |_^\nLL |       fn with_two_newlines() {}\n   |       -------------------- the attribute applies to this function\n   |\n   = help: if the empty lines are unintentional, remove them\nhelp: if the attribute should apply to the parent module use an inner attribute\n   |\nLL |     #![crate_type = \"lib\"]\n   |      +\n\nerror: empty line after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:37:1\n   |\nLL | / #[doc = \"doc attributes should be considered attributes\"]\nLL | |\n   | |_^\nLL |   enum Baz {\n   |   -------- the attribute applies to this enum\n   |\n   = help: if the empty line is unintentional, remove it\n\nerror: empty line after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:45:1\n   |\nLL | / #[repr(C)]\nLL | |\n   | |_^\nLL |   struct Foo {\n   |   ---------- the attribute applies to this struct\n   |\n   = help: if the empty line is unintentional, remove it\n\nerror: empty line after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:53:1\n   |\nLL | / #[allow(dead_code)]\nLL | |\n   | |_^\nLL |   mod foo {}\n   |   ------- the attribute applies to this module\n   |\n   = help: if the empty line is unintentional, remove it\n\nerror: empty line after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:58:1\n   |\nLL | / #[inline]\nLL | | // Still lint cases where the empty line does not immediately follow the attribute\nLL | |\n   | |_^\nLL |   fn comment_before_empty_line() {}\n   |   ---------------------------- the attribute applies to this function\n   |\n   = help: if the empty line is unintentional, remove it\n\nerror: empty lines after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:64:1\n   |\nLL | / #[allow(unused)]\n...  |\nLL | |\n   | |_^\nLL |   pub fn isolated_comment() {}\n   |   ----------------------- the attribute applies to this function\n   |\n   = help: if the empty lines are unintentional, remove them\n\nerror: empty line after outer attribute\n  --> tests/ui/empty_line_after/outer_attribute.rs:121:5\n   |\nLL | /     #[repr(align(536870912))]\nLL | |\n   | |_^\nLL |       enum Aligned {\n   |       ------------ the attribute applies to this enum\n   |\n   = help: if the empty line is unintentional, remove it\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/empty_loop.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::empty_loop)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nfn should_trigger() {\n    loop {}\n    //~^ empty_loop\n    #[allow(clippy::never_loop)]\n    loop {\n        loop {}\n        //~^ empty_loop\n    }\n\n    #[allow(clippy::never_loop)]\n    'outer: loop {\n        'inner: loop {}\n        //~^ empty_loop\n    }\n}\n\n#[inline_macros]\nfn should_not_trigger() {\n    #[allow(clippy::never_loop)]\n    loop {\n        panic!(\"This is fine\")\n    }\n    let ten_millis = std::time::Duration::from_millis(10);\n    loop {\n        std::thread::sleep(ten_millis)\n    }\n\n    #[allow(clippy::never_loop)]\n    'outer: loop {\n        'inner: loop {\n            break 'inner;\n        }\n        break 'outer;\n    }\n\n    // Make sure `allow` works for this lint\n    #[allow(clippy::empty_loop)]\n    loop {}\n\n    // We don't lint loops inside macros\n    inline!(loop {});\n\n    // We don't lint external macros\n    external!(loop {});\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_loop.stderr",
    "content": "error: empty `loop {}` wastes CPU cycles\n  --> tests/ui/empty_loop.rs:9:5\n   |\nLL |     loop {}\n   |     ^^^^^^^\n   |\n   = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body\n   = note: `-D clippy::empty-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_loop)]`\n\nerror: empty `loop {}` wastes CPU cycles\n  --> tests/ui/empty_loop.rs:13:9\n   |\nLL |         loop {}\n   |         ^^^^^^^\n   |\n   = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body\n\nerror: empty `loop {}` wastes CPU cycles\n  --> tests/ui/empty_loop.rs:19:9\n   |\nLL |         'inner: loop {}\n   |         ^^^^^^^^^^^^^^^\n   |\n   = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/empty_loop_intrinsic.rs",
    "content": "//@check-pass\n\n#![warn(clippy::empty_loop)]\n#![feature(intrinsics)]\n#![feature(rustc_attrs)]\n\n// From issue #15200\n#[rustc_intrinsic]\n#[rustc_nounwind]\n/// # Safety\npub const unsafe fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/empty_loop_no_std.rs",
    "content": "//@compile-flags: -Clink-arg=-nostartfiles\n#![warn(clippy::empty_loop)]\n#![crate_type = \"lib\"]\n#![no_std]\n\npub fn main(argc: isize, argv: *const *const u8) -> isize {\n    // This should trigger the lint\n    loop {}\n    //~^ empty_loop\n}\n"
  },
  {
    "path": "tests/ui/empty_loop_no_std.stderr",
    "content": "error: empty `loop {}` wastes CPU cycles\n  --> tests/ui/empty_loop_no_std.rs:8:5\n   |\nLL |     loop {}\n   |     ^^^^^^^\n   |\n   = help: you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body\n   = note: `-D clippy::empty-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_loop)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/empty_structs_with_brackets.fixed",
    "content": "#![warn(clippy::empty_structs_with_brackets)]\n#![allow(dead_code)]\n\npub struct MyEmptyStruct; // should trigger lint\n//~^ empty_structs_with_brackets\nstruct MyEmptyTupleStruct; // should trigger lint\n//~^ empty_structs_with_brackets\n\n// should not trigger lint\nstruct MyCfgStruct {\n    #[cfg(feature = \"thisisneverenabled\")]\n    field: u8,\n}\n\n// should not trigger lint\nstruct MyCfgTupleStruct(#[cfg(feature = \"thisisneverenabled\")] u8);\n\n// should not trigger lint\nstruct MyStruct {\n    field: u8,\n}\nstruct MyTupleStruct(usize, String); // should not trigger lint\nstruct MySingleTupleStruct(usize); // should not trigger lint\nstruct MyUnitLikeStruct; // should not trigger lint\n\nmacro_rules! empty_struct {\n    ($s:ident) => {\n        struct $s {}\n    };\n}\n\nempty_struct!(FromMacro);\n\nfn main() {}\n\nmod issue15349 {\n    trait Bar<T> {}\n    impl<T> Bar<T> for [u8; 7] {}\n\n    struct Foo<const N: usize>;\n    //~^ empty_structs_with_brackets\n    impl<const N: usize> Foo<N>\n    where\n        [u8; N]: Bar<[(); N]>,\n    {\n        fn foo() {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/empty_structs_with_brackets.rs",
    "content": "#![warn(clippy::empty_structs_with_brackets)]\n#![allow(dead_code)]\n\npub struct MyEmptyStruct {} // should trigger lint\n//~^ empty_structs_with_brackets\nstruct MyEmptyTupleStruct(); // should trigger lint\n//~^ empty_structs_with_brackets\n\n// should not trigger lint\nstruct MyCfgStruct {\n    #[cfg(feature = \"thisisneverenabled\")]\n    field: u8,\n}\n\n// should not trigger lint\nstruct MyCfgTupleStruct(#[cfg(feature = \"thisisneverenabled\")] u8);\n\n// should not trigger lint\nstruct MyStruct {\n    field: u8,\n}\nstruct MyTupleStruct(usize, String); // should not trigger lint\nstruct MySingleTupleStruct(usize); // should not trigger lint\nstruct MyUnitLikeStruct; // should not trigger lint\n\nmacro_rules! empty_struct {\n    ($s:ident) => {\n        struct $s {}\n    };\n}\n\nempty_struct!(FromMacro);\n\nfn main() {}\n\nmod issue15349 {\n    trait Bar<T> {}\n    impl<T> Bar<T> for [u8; 7] {}\n\n    struct Foo<const N: usize> {}\n    //~^ empty_structs_with_brackets\n    impl<const N: usize> Foo<N>\n    where\n        [u8; N]: Bar<[(); N]>,\n    {\n        fn foo() {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/empty_structs_with_brackets.stderr",
    "content": "error: found empty brackets on struct declaration\n  --> tests/ui/empty_structs_with_brackets.rs:4:25\n   |\nLL | pub struct MyEmptyStruct {} // should trigger lint\n   |                         ^^^\n   |\n   = note: `-D clippy::empty-structs-with-brackets` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::empty_structs_with_brackets)]`\n   = help: remove the brackets\n\nerror: found empty brackets on struct declaration\n  --> tests/ui/empty_structs_with_brackets.rs:6:26\n   |\nLL | struct MyEmptyTupleStruct(); // should trigger lint\n   |                          ^^^\n   |\n   = help: remove the brackets\n\nerror: found empty brackets on struct declaration\n  --> tests/ui/empty_structs_with_brackets.rs:40:31\n   |\nLL |     struct Foo<const N: usize> {}\n   |                               ^^^\n   |\n   = help: remove the brackets\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/endian_bytes.rs",
    "content": "#![allow(unused)]\n#![allow(clippy::diverging_sub_expression)]\n#![no_main]\n\n// FIXME(f16_f128): add these types when `{to_from}_*_bytes` are available\n\nmacro_rules! fn_body {\n    () => {\n        2u8.to_ne_bytes();\n        //~^ host_endian_bytes\n        2i8.to_ne_bytes();\n        //~^ host_endian_bytes\n        2u16.to_ne_bytes();\n        //~^ host_endian_bytes\n        2i16.to_ne_bytes();\n        //~^ host_endian_bytes\n        2u32.to_ne_bytes();\n        //~^ host_endian_bytes\n        2i32.to_ne_bytes();\n        //~^ host_endian_bytes\n        2u64.to_ne_bytes();\n        //~^ host_endian_bytes\n        2i64.to_ne_bytes();\n        //~^ host_endian_bytes\n        2u128.to_ne_bytes();\n        //~^ host_endian_bytes\n        2i128.to_ne_bytes();\n        //~^ host_endian_bytes\n        2.0f32.to_ne_bytes();\n        //~^ host_endian_bytes\n        2.0f64.to_ne_bytes();\n        //~^ host_endian_bytes\n        2usize.to_ne_bytes();\n        //~^ host_endian_bytes\n        2isize.to_ne_bytes();\n        //~^ host_endian_bytes\n        u8::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        i8::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        u16::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        i16::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        u32::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        i32::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        u64::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        i64::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        u128::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        i128::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        usize::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        isize::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        f32::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        f64::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n\n        2u8.to_le_bytes();\n        //~^ little_endian_bytes\n        2i8.to_le_bytes();\n        //~^ little_endian_bytes\n        2u16.to_le_bytes();\n        //~^ little_endian_bytes\n        2i16.to_le_bytes();\n        //~^ little_endian_bytes\n        2u32.to_le_bytes();\n        //~^ little_endian_bytes\n        2i32.to_le_bytes();\n        //~^ little_endian_bytes\n        2u64.to_le_bytes();\n        //~^ little_endian_bytes\n        2i64.to_le_bytes();\n        //~^ little_endian_bytes\n        2u128.to_le_bytes();\n        //~^ little_endian_bytes\n        2i128.to_le_bytes();\n        //~^ little_endian_bytes\n        2.0f32.to_le_bytes();\n        //~^ little_endian_bytes\n        2.0f64.to_le_bytes();\n        //~^ little_endian_bytes\n        2usize.to_le_bytes();\n        //~^ little_endian_bytes\n        2isize.to_le_bytes();\n        //~^ little_endian_bytes\n        u8::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        i8::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        u16::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        i16::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        u32::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        i32::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        u64::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        i64::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        u128::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        i128::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        usize::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        isize::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        f32::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        f64::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n    };\n}\n\n// bless breaks if I use fn_body too much (oops)\nmacro_rules! fn_body_smol {\n    () => {\n        2u8.to_ne_bytes();\n        //~^ host_endian_bytes\n        //~| host_endian_bytes\n        //~| host_endian_bytes\n        //~| host_endian_bytes\n        //~| host_endian_bytes\n        u8::from_ne_bytes(todo!());\n        //~^ host_endian_bytes\n        //~| host_endian_bytes\n        //~| host_endian_bytes\n        //~| host_endian_bytes\n        //~| host_endian_bytes\n\n        2u8.to_le_bytes();\n        //~^ little_endian_bytes\n        //~| little_endian_bytes\n        //~| little_endian_bytes\n        //~| little_endian_bytes\n        //~| little_endian_bytes\n        u8::from_le_bytes(todo!());\n        //~^ little_endian_bytes\n        //~| little_endian_bytes\n        //~| little_endian_bytes\n        //~| little_endian_bytes\n        //~| little_endian_bytes\n\n        2u8.to_be_bytes();\n        //~^ big_endian_bytes\n        //~| big_endian_bytes\n        //~| big_endian_bytes\n        //~| big_endian_bytes\n        //~| big_endian_bytes\n        u8::from_be_bytes(todo!());\n        //~^ big_endian_bytes\n        //~| big_endian_bytes\n        //~| big_endian_bytes\n        //~| big_endian_bytes\n        //~| big_endian_bytes\n    };\n}\n\n#[rustfmt::skip]\n#[warn(clippy::host_endian_bytes)]\nfn host() { fn_body!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::little_endian_bytes)]\nfn little() { fn_body!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::big_endian_bytes)]\nfn big() { fn_body!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::host_endian_bytes)]\n#[warn(clippy::big_endian_bytes)]\nfn host_encourage_little() { fn_body_smol!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::host_endian_bytes)]\n#[warn(clippy::little_endian_bytes)]\nfn host_encourage_big() { fn_body_smol!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::host_endian_bytes)]\n#[warn(clippy::little_endian_bytes)]\n#[warn(clippy::big_endian_bytes)]\nfn no_help() { fn_body_smol!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::little_endian_bytes)]\n#[warn(clippy::big_endian_bytes)]\nfn little_encourage_host() { fn_body_smol!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::host_endian_bytes)]\n#[warn(clippy::little_endian_bytes)]\nfn little_encourage_big() { fn_body_smol!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::big_endian_bytes)]\n#[warn(clippy::little_endian_bytes)]\nfn big_encourage_host() { fn_body_smol!(); }\n\n#[rustfmt::skip]\n#[warn(clippy::host_endian_bytes)]\n#[warn(clippy::big_endian_bytes)]\nfn big_encourage_little() { fn_body_smol!(); }\n"
  },
  {
    "path": "tests/ui/endian_bytes.stderr",
    "content": "error: usage of the `u8::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:9:9\n   |\nLL |         2u8.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: `-D clippy::host-endian-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::host_endian_bytes)]`\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i8::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:11:9\n   |\nLL |         2i8.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u16::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:13:9\n   |\nLL |         2u16.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i16::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:15:9\n   |\nLL |         2i16.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u32::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:17:9\n   |\nLL |         2u32.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i32::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:19:9\n   |\nLL |         2i32.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u64::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:21:9\n   |\nLL |         2u64.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i64::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:23:9\n   |\nLL |         2i64.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u128::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:25:9\n   |\nLL |         2u128.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i128::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:27:9\n   |\nLL |         2i128.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `f32::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:29:9\n   |\nLL |         2.0f32.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `f64::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:31:9\n   |\nLL |         2.0f64.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `usize::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:33:9\n   |\nLL |         2usize.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `isize::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:35:9\n   |\nLL |         2isize.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:37:9\n   |\nLL |         u8::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i8::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:39:9\n   |\nLL |         i8::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u16::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:41:9\n   |\nLL |         u16::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i16::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:43:9\n   |\nLL |         i16::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u32::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:45:9\n   |\nLL |         u32::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i32::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:47:9\n   |\nLL |         i32::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u64::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:49:9\n   |\nLL |         u64::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i64::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:51:9\n   |\nLL |         i64::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u128::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:53:9\n   |\nLL |         u128::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i128::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:55:9\n   |\nLL |         i128::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `usize::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:57:9\n   |\nLL |         usize::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `isize::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:59:9\n   |\nLL |         isize::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `f32::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:61:9\n   |\nLL |         f32::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `f64::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:63:9\n   |\nLL |         f64::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host() { fn_body!(); }\n   |             ---------- in this macro invocation\n   |\n   = help: specify the desired endianness explicitly\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:66:9\n   |\nLL |         2u8.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: `-D clippy::little-endian-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::little_endian_bytes)]`\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i8::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:68:9\n   |\nLL |         2i8.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u16::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:70:9\n   |\nLL |         2u16.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i16::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:72:9\n   |\nLL |         2i16.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u32::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:74:9\n   |\nLL |         2u32.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i32::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:76:9\n   |\nLL |         2i32.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u64::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:78:9\n   |\nLL |         2u64.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i64::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:80:9\n   |\nLL |         2i64.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u128::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:82:9\n   |\nLL |         2u128.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `i128::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:84:9\n   |\nLL |         2i128.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `f32::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:86:9\n   |\nLL |         2.0f32.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `f64::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:88:9\n   |\nLL |         2.0f64.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `usize::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:90:9\n   |\nLL |         2usize.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `isize::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:92:9\n   |\nLL |         2isize.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:94:9\n   |\nLL |         u8::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i8::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:96:9\n   |\nLL |         i8::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u16::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:98:9\n   |\nLL |         u16::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i16::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:100:9\n   |\nLL |         i16::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u32::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:102:9\n   |\nLL |         u32::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i32::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:104:9\n   |\nLL |         i32::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u64::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:106:9\n   |\nLL |         u64::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i64::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:108:9\n   |\nLL |         i64::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u128::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:110:9\n   |\nLL |         u128::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `i128::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:112:9\n   |\nLL |         i128::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `usize::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:114:9\n   |\nLL |         usize::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `isize::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:116:9\n   |\nLL |         isize::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `f32::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:118:9\n   |\nLL |         f32::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `f64::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:120:9\n   |\nLL |         f64::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little() { fn_body!(); }\n   |               ---------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:128:9\n   |\nLL |         2u8.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn host_encourage_little() { fn_body_smol!(); }\n   |                              --------------- in this macro invocation\n   |\n   = help: use `u8::to_le_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:134:9\n   |\nLL |         u8::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host_encourage_little() { fn_body_smol!(); }\n   |                              --------------- in this macro invocation\n   |\n   = help: use `u8::from_le_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_be_bytes` method\n  --> tests/ui/endian_bytes.rs:154:9\n   |\nLL |         2u8.to_be_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn host_encourage_little() { fn_body_smol!(); }\n   |                              --------------- in this macro invocation\n   |\n   = help: use `u8::to_le_bytes` instead\n   = note: `-D clippy::big-endian-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::big_endian_bytes)]`\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_be_bytes`\n  --> tests/ui/endian_bytes.rs:160:9\n   |\nLL |         u8::from_be_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host_encourage_little() { fn_body_smol!(); }\n   |                              --------------- in this macro invocation\n   |\n   = help: use `u8::from_le_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:128:9\n   |\nLL |         2u8.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn host_encourage_big() { fn_body_smol!(); }\n   |                           --------------- in this macro invocation\n   |\n   = help: use `u8::to_be_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:134:9\n   |\nLL |         u8::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host_encourage_big() { fn_body_smol!(); }\n   |                           --------------- in this macro invocation\n   |\n   = help: use `u8::from_be_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:141:9\n   |\nLL |         2u8.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn host_encourage_big() { fn_body_smol!(); }\n   |                           --------------- in this macro invocation\n   |\n   = help: use `u8::to_be_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:147:9\n   |\nLL |         u8::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn host_encourage_big() { fn_body_smol!(); }\n   |                           --------------- in this macro invocation\n   |\n   = help: use `u8::from_be_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:128:9\n   |\nLL |         2u8.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn no_help() { fn_body_smol!(); }\n   |                --------------- in this macro invocation\n   |\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:134:9\n   |\nLL |         u8::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn no_help() { fn_body_smol!(); }\n   |                --------------- in this macro invocation\n   |\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:141:9\n   |\nLL |         2u8.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn no_help() { fn_body_smol!(); }\n   |                --------------- in this macro invocation\n   |\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:147:9\n   |\nLL |         u8::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn no_help() { fn_body_smol!(); }\n   |                --------------- in this macro invocation\n   |\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_be_bytes` method\n  --> tests/ui/endian_bytes.rs:154:9\n   |\nLL |         2u8.to_be_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn no_help() { fn_body_smol!(); }\n   |                --------------- in this macro invocation\n   |\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_be_bytes`\n  --> tests/ui/endian_bytes.rs:160:9\n   |\nLL |         u8::from_be_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn no_help() { fn_body_smol!(); }\n   |                --------------- in this macro invocation\n   |\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:141:9\n   |\nLL |         2u8.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn little_encourage_host() { fn_body_smol!(); }\n   |                              --------------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:147:9\n   |\nLL |         u8::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little_encourage_host() { fn_body_smol!(); }\n   |                              --------------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_be_bytes` method\n  --> tests/ui/endian_bytes.rs:154:9\n   |\nLL |         2u8.to_be_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn little_encourage_host() { fn_body_smol!(); }\n   |                              --------------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_be_bytes`\n  --> tests/ui/endian_bytes.rs:160:9\n   |\nLL |         u8::from_be_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little_encourage_host() { fn_body_smol!(); }\n   |                              --------------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:128:9\n   |\nLL |         2u8.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn little_encourage_big() { fn_body_smol!(); }\n   |                             --------------- in this macro invocation\n   |\n   = help: use `u8::to_be_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:134:9\n   |\nLL |         u8::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little_encourage_big() { fn_body_smol!(); }\n   |                             --------------- in this macro invocation\n   |\n   = help: use `u8::from_be_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:141:9\n   |\nLL |         2u8.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn little_encourage_big() { fn_body_smol!(); }\n   |                             --------------- in this macro invocation\n   |\n   = help: use `u8::to_be_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:147:9\n   |\nLL |         u8::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn little_encourage_big() { fn_body_smol!(); }\n   |                             --------------- in this macro invocation\n   |\n   = help: use `u8::from_be_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_le_bytes` method\n  --> tests/ui/endian_bytes.rs:141:9\n   |\nLL |         2u8.to_le_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn big_encourage_host() { fn_body_smol!(); }\n   |                           --------------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_le_bytes`\n  --> tests/ui/endian_bytes.rs:147:9\n   |\nLL |         u8::from_le_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn big_encourage_host() { fn_body_smol!(); }\n   |                           --------------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_be_bytes` method\n  --> tests/ui/endian_bytes.rs:154:9\n   |\nLL |         2u8.to_be_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn big_encourage_host() { fn_body_smol!(); }\n   |                           --------------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_be_bytes`\n  --> tests/ui/endian_bytes.rs:160:9\n   |\nLL |         u8::from_be_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn big_encourage_host() { fn_body_smol!(); }\n   |                           --------------- in this macro invocation\n   |\n   = help: use the native endianness instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_ne_bytes` method\n  --> tests/ui/endian_bytes.rs:128:9\n   |\nLL |         2u8.to_ne_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn big_encourage_little() { fn_body_smol!(); }\n   |                             --------------- in this macro invocation\n   |\n   = help: use `u8::to_le_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_ne_bytes`\n  --> tests/ui/endian_bytes.rs:134:9\n   |\nLL |         u8::from_ne_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn big_encourage_little() { fn_body_smol!(); }\n   |                             --------------- in this macro invocation\n   |\n   = help: use `u8::from_le_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the `u8::to_be_bytes` method\n  --> tests/ui/endian_bytes.rs:154:9\n   |\nLL |         2u8.to_be_bytes();\n   |         ^^^^^^^^^^^^^^^^^\n...\nLL | fn big_encourage_little() { fn_body_smol!(); }\n   |                             --------------- in this macro invocation\n   |\n   = help: use `u8::to_le_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: usage of the function `u8::from_be_bytes`\n  --> tests/ui/endian_bytes.rs:160:9\n   |\nLL |         u8::from_be_bytes(todo!());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL | fn big_encourage_little() { fn_body_smol!(); }\n   |                             --------------- in this macro invocation\n   |\n   = help: use `u8::from_le_bytes` instead\n   = note: this error originates in the macro `fn_body_smol` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 86 previous errors\n\n"
  },
  {
    "path": "tests/ui/entry.fixed",
    "content": "//@needs-asm-support\n\n#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]\n#![warn(clippy::map_entry)]\n\nuse std::arch::asm;\nuse std::collections::HashMap;\nuse std::hash::Hash;\n\nmacro_rules! m {\n    ($e:expr) => {{ $e }};\n}\n\nmacro_rules! insert {\n    ($map:expr, $key:expr, $val:expr) => {\n        $map.insert($key, $val)\n    };\n}\n\nfn foo() {}\n\nfn hash_map<K: Eq + Hash + Copy, V: Copy>(m: &mut HashMap<K, V>, m2: &mut HashMap<K, V>, k: K, k2: K, v: V, v2: V) {\n    // or_insert(v)\n    m.entry(k).or_insert(v);\n\n    // semicolon on insert, use or_insert_with(..)\n    m.entry(k).or_insert_with(|| {\n        //~^ map_entry\n        if true {\n            v\n        } else {\n            v2\n        }\n    });\n\n    // semicolon on if, use or_insert_with(..)\n    m.entry(k).or_insert_with(|| {\n        //~^ map_entry\n        if true {\n            v\n        } else {\n            v2\n        }\n    });\n\n    // early return, use if let\n    if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {\n        //~^ map_entry\n        if true {\n            e.insert(v);\n        } else {\n            e.insert(v2);\n            return;\n        }\n    }\n\n    // use or_insert_with(..)\n    m.entry(k).or_insert_with(|| {\n        //~^ map_entry\n        foo();\n        v\n    });\n\n    // semicolon on insert and match, use or_insert_with(..)\n    m.entry(k).or_insert_with(|| {\n        //~^ map_entry\n        match 0 {\n            1 if true => {\n                v\n            },\n            _ => {\n                v2\n            },\n        }\n    });\n\n    // one branch doesn't insert, use if let\n    if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {\n        //~^ map_entry\n        match 0 {\n            0 => foo(),\n            _ => {\n                e.insert(v2);\n            },\n        };\n    }\n\n    // use or_insert_with\n    m.entry(k).or_insert_with(|| {\n        //~^ map_entry\n        foo();\n        match 0 {\n            0 if false => {\n                v\n            },\n            1 => {\n                foo();\n                v\n            },\n            2 | 3 => {\n                for _ in 0..2 {\n                    foo();\n                }\n                if true {\n                    v\n                } else {\n                    v2\n                }\n            },\n            _ => {\n                v2\n            },\n        }\n    });\n\n    // ok, insert in loop\n    if !m.contains_key(&k) {\n        for _ in 0..2 {\n            m.insert(k, v);\n        }\n    }\n\n    // macro_expansion test, use or_insert(..)\n    m.entry(m!(k)).or_insert_with(|| m!(v));\n\n    // ok, map used before insertion\n    if !m.contains_key(&k) {\n        let _ = m.len();\n        m.insert(k, v);\n    }\n\n    // ok, inline asm\n    if !m.contains_key(&k) {\n        unsafe { asm!(\"nop\") }\n        m.insert(k, v);\n    }\n\n    // ok, different keys.\n    if !m.contains_key(&k) {\n        m.insert(k2, v);\n    }\n\n    // ok, different maps\n    if !m.contains_key(&k) {\n        m2.insert(k, v);\n    }\n\n    // ok, insert in macro\n    if !m.contains_key(&k) {\n        insert!(m, k, v);\n    }\n\n    // or_insert_with. Partial move of a local declared in the closure is ok.\n    m.entry(k).or_insert_with(|| {\n        //~^ map_entry\n        let x = (String::new(), String::new());\n        let _ = x.0;\n        v\n    });\n}\n\n// Issue 10331\n// do not suggest a bad expansion because the compiler unrolls the first\n// occurrence of the loop\npub fn issue_10331() {\n    let mut m = HashMap::new();\n    let mut i = 0;\n    let mut x = 0;\n    while !m.contains_key(&x) {\n        m.insert(x, i);\n        i += 1;\n        x += 1;\n    }\n}\n\n/// Issue 11935\n/// Do not suggest using entries if the map is used inside the `insert` expression.\npub fn issue_11935() {\n    let mut counts: HashMap<u64, u64> = HashMap::new();\n    if !counts.contains_key(&1) {\n        counts.insert(1, 1);\n    } else {\n        counts.insert(1, counts.get(&1).unwrap() + 1);\n    }\n}\n\nfn issue12489(map: &mut HashMap<u64, u64>) -> Option<()> {\n    if let std::collections::hash_map::Entry::Vacant(e) = map.entry(1) {\n        //~^ map_entry\n        let Some(1) = Some(2) else {\n            return None;\n        };\n        e.insert(42);\n    }\n    Some(())\n}\n\nmod issue13934 {\n    use std::collections::HashMap;\n\n    struct Member {}\n\n    pub struct Foo {\n        members: HashMap<u8, Member>,\n    }\n\n    impl Foo {\n        pub fn should_also_not_cause_lint(&mut self, input: u8) {\n            if self.members.contains_key(&input) {\n                todo!();\n            } else {\n                self.other();\n                self.members.insert(input, Member {});\n            }\n        }\n\n        fn other(&self) {}\n    }\n}\n\nfn issue11976() {\n    let mut hashmap = std::collections::HashMap::new();\n    if !hashmap.contains_key(&0) {\n        let _ = || hashmap.get(&0);\n        hashmap.insert(0, 0);\n    }\n}\n\nmod issue14449 {\n    use std::collections::BTreeMap;\n\n    pub struct Meow {\n        map: BTreeMap<String, String>,\n    }\n\n    impl Meow {\n        fn pet(&self, _key: &str, _v: u32) -> u32 {\n            42\n        }\n    }\n\n    pub fn f(meow: &Meow, x: String) {\n        if meow.map.contains_key(&x) {\n            let _ = meow.pet(&x, 1);\n        } else {\n            let _ = meow.pet(&x, 0);\n        }\n    }\n}\n\n// Don't suggest when it would cause `MutexGuard` to be held across an await point.\nmod issue_16173 {\n    use std::collections::HashMap;\n    use std::sync::Mutex;\n\n    async fn f() {}\n\n    async fn foo() {\n        let mu_map = Mutex::new(HashMap::new());\n        if !mu_map.lock().unwrap().contains_key(&0) {\n            f().await;\n            mu_map.lock().unwrap().insert(0, 0);\n        }\n\n        if mu_map.lock().unwrap().contains_key(&1) {\n            todo!();\n        } else {\n            mu_map.lock().unwrap().insert(1, 42);\n            todo!();\n            f().await;\n        }\n    }\n}\n\nfn main() {}\n\nfn issue15781(m: &mut std::collections::HashMap<i32, i32>, k: i32, v: i32) {\n    fn very_important_fn() {}\n    m.entry(k).or_insert_with(|| {\n        //~^ map_entry\n        #[cfg(test)]\n        very_important_fn();\n        v\n    });\n}\n"
  },
  {
    "path": "tests/ui/entry.rs",
    "content": "//@needs-asm-support\n\n#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]\n#![warn(clippy::map_entry)]\n\nuse std::arch::asm;\nuse std::collections::HashMap;\nuse std::hash::Hash;\n\nmacro_rules! m {\n    ($e:expr) => {{ $e }};\n}\n\nmacro_rules! insert {\n    ($map:expr, $key:expr, $val:expr) => {\n        $map.insert($key, $val)\n    };\n}\n\nfn foo() {}\n\nfn hash_map<K: Eq + Hash + Copy, V: Copy>(m: &mut HashMap<K, V>, m2: &mut HashMap<K, V>, k: K, k2: K, v: V, v2: V) {\n    // or_insert(v)\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        m.insert(k, v);\n    }\n\n    // semicolon on insert, use or_insert_with(..)\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        if true {\n            m.insert(k, v);\n        } else {\n            m.insert(k, v2);\n        }\n    }\n\n    // semicolon on if, use or_insert_with(..)\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        if true {\n            m.insert(k, v)\n        } else {\n            m.insert(k, v2)\n        };\n    }\n\n    // early return, use if let\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        if true {\n            m.insert(k, v);\n        } else {\n            m.insert(k, v2);\n            return;\n        }\n    }\n\n    // use or_insert_with(..)\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        foo();\n        m.insert(k, v);\n    }\n\n    // semicolon on insert and match, use or_insert_with(..)\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        match 0 {\n            1 if true => {\n                m.insert(k, v);\n            },\n            _ => {\n                m.insert(k, v2);\n            },\n        };\n    }\n\n    // one branch doesn't insert, use if let\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        match 0 {\n            0 => foo(),\n            _ => {\n                m.insert(k, v2);\n            },\n        };\n    }\n\n    // use or_insert_with\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        foo();\n        match 0 {\n            0 if false => {\n                m.insert(k, v);\n            },\n            1 => {\n                foo();\n                m.insert(k, v);\n            },\n            2 | 3 => {\n                for _ in 0..2 {\n                    foo();\n                }\n                if true {\n                    m.insert(k, v);\n                } else {\n                    m.insert(k, v2);\n                };\n            },\n            _ => {\n                m.insert(k, v2);\n            },\n        }\n    }\n\n    // ok, insert in loop\n    if !m.contains_key(&k) {\n        for _ in 0..2 {\n            m.insert(k, v);\n        }\n    }\n\n    // macro_expansion test, use or_insert(..)\n    if !m.contains_key(&m!(k)) {\n        //~^ map_entry\n        m.insert(m!(k), m!(v));\n    }\n\n    // ok, map used before insertion\n    if !m.contains_key(&k) {\n        let _ = m.len();\n        m.insert(k, v);\n    }\n\n    // ok, inline asm\n    if !m.contains_key(&k) {\n        unsafe { asm!(\"nop\") }\n        m.insert(k, v);\n    }\n\n    // ok, different keys.\n    if !m.contains_key(&k) {\n        m.insert(k2, v);\n    }\n\n    // ok, different maps\n    if !m.contains_key(&k) {\n        m2.insert(k, v);\n    }\n\n    // ok, insert in macro\n    if !m.contains_key(&k) {\n        insert!(m, k, v);\n    }\n\n    // or_insert_with. Partial move of a local declared in the closure is ok.\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        let x = (String::new(), String::new());\n        let _ = x.0;\n        m.insert(k, v);\n    }\n}\n\n// Issue 10331\n// do not suggest a bad expansion because the compiler unrolls the first\n// occurrence of the loop\npub fn issue_10331() {\n    let mut m = HashMap::new();\n    let mut i = 0;\n    let mut x = 0;\n    while !m.contains_key(&x) {\n        m.insert(x, i);\n        i += 1;\n        x += 1;\n    }\n}\n\n/// Issue 11935\n/// Do not suggest using entries if the map is used inside the `insert` expression.\npub fn issue_11935() {\n    let mut counts: HashMap<u64, u64> = HashMap::new();\n    if !counts.contains_key(&1) {\n        counts.insert(1, 1);\n    } else {\n        counts.insert(1, counts.get(&1).unwrap() + 1);\n    }\n}\n\nfn issue12489(map: &mut HashMap<u64, u64>) -> Option<()> {\n    if !map.contains_key(&1) {\n        //~^ map_entry\n        let Some(1) = Some(2) else {\n            return None;\n        };\n        map.insert(1, 42);\n    }\n    Some(())\n}\n\nmod issue13934 {\n    use std::collections::HashMap;\n\n    struct Member {}\n\n    pub struct Foo {\n        members: HashMap<u8, Member>,\n    }\n\n    impl Foo {\n        pub fn should_also_not_cause_lint(&mut self, input: u8) {\n            if self.members.contains_key(&input) {\n                todo!();\n            } else {\n                self.other();\n                self.members.insert(input, Member {});\n            }\n        }\n\n        fn other(&self) {}\n    }\n}\n\nfn issue11976() {\n    let mut hashmap = std::collections::HashMap::new();\n    if !hashmap.contains_key(&0) {\n        let _ = || hashmap.get(&0);\n        hashmap.insert(0, 0);\n    }\n}\n\nmod issue14449 {\n    use std::collections::BTreeMap;\n\n    pub struct Meow {\n        map: BTreeMap<String, String>,\n    }\n\n    impl Meow {\n        fn pet(&self, _key: &str, _v: u32) -> u32 {\n            42\n        }\n    }\n\n    pub fn f(meow: &Meow, x: String) {\n        if meow.map.contains_key(&x) {\n            let _ = meow.pet(&x, 1);\n        } else {\n            let _ = meow.pet(&x, 0);\n        }\n    }\n}\n\n// Don't suggest when it would cause `MutexGuard` to be held across an await point.\nmod issue_16173 {\n    use std::collections::HashMap;\n    use std::sync::Mutex;\n\n    async fn f() {}\n\n    async fn foo() {\n        let mu_map = Mutex::new(HashMap::new());\n        if !mu_map.lock().unwrap().contains_key(&0) {\n            f().await;\n            mu_map.lock().unwrap().insert(0, 0);\n        }\n\n        if mu_map.lock().unwrap().contains_key(&1) {\n            todo!();\n        } else {\n            mu_map.lock().unwrap().insert(1, 42);\n            todo!();\n            f().await;\n        }\n    }\n}\n\nfn main() {}\n\nfn issue15781(m: &mut std::collections::HashMap<i32, i32>, k: i32, v: i32) {\n    fn very_important_fn() {}\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        #[cfg(test)]\n        very_important_fn();\n        m.insert(k, v);\n    }\n}\n"
  },
  {
    "path": "tests/ui/entry.stderr",
    "content": "error: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:24:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         m.insert(k, v);\nLL | |     }\n   | |_____^ help: try: `m.entry(k).or_insert(v);`\n   |\n   = note: `-D clippy::map-entry` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:30:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         if true {\nLL | |             m.insert(k, v);\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     m.entry(k).or_insert_with(|| {\nLL +\nLL +         if true {\nLL +             v\nLL +         } else {\nLL +             v2\nLL +         }\nLL +     });\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:40:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         if true {\nLL | |             m.insert(k, v)\n...  |\nLL | |         };\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     m.entry(k).or_insert_with(|| {\nLL +\nLL +         if true {\nLL +             v\nLL +         } else {\nLL +             v2\nLL +         }\nLL +     });\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:50:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         if true {\nLL | |             m.insert(k, v);\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {\nLL +\nLL +         if true {\nLL +             e.insert(v);\nLL +         } else {\nLL +             e.insert(v2);\nLL +             return;\nLL +         }\nLL +     }\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:61:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         foo();\nLL | |         m.insert(k, v);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     m.entry(k).or_insert_with(|| {\nLL +\nLL +         foo();\nLL +         v\nLL +     });\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:68:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         match 0 {\nLL | |             1 if true => {\n...  |\nLL | |         };\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     m.entry(k).or_insert_with(|| {\nLL +\nLL +         match 0 {\nLL +             1 if true => {\nLL +                 v\nLL +             },\nLL +             _ => {\nLL +                 v2\nLL +             },\nLL +         }\nLL +     });\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:81:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         match 0 {\nLL | |             0 => foo(),\n...  |\nLL | |         };\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {\nLL +\nLL +         match 0 {\nLL +             0 => foo(),\nLL +             _ => {\nLL +                 e.insert(v2);\nLL +             },\nLL +         };\nLL +     }\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:92:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         foo();\nLL | |         match 0 {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     m.entry(k).or_insert_with(|| {\nLL +\nLL +         foo();\nLL +         match 0 {\nLL +             0 if false => {\nLL +                 v\nLL +             },\nLL +             1 => {\nLL +                 foo();\nLL +                 v\nLL +             },\nLL +             2 | 3 => {\nLL +                 for _ in 0..2 {\nLL +                     foo();\nLL +                 }\nLL +                 if true {\nLL +                     v\nLL +                 } else {\nLL +                     v2\nLL +                 }\nLL +             },\nLL +             _ => {\nLL +                 v2\nLL +             },\nLL +         }\nLL +     });\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:127:5\n   |\nLL | /     if !m.contains_key(&m!(k)) {\nLL | |\nLL | |         m.insert(m!(k), m!(v));\nLL | |     }\n   | |_____^ help: try: `m.entry(m!(k)).or_insert_with(|| m!(v));`\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:160:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         let x = (String::new(), String::new());\nLL | |         let _ = x.0;\nLL | |         m.insert(k, v);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     m.entry(k).or_insert_with(|| {\nLL +\nLL +         let x = (String::new(), String::new());\nLL +         let _ = x.0;\nLL +         v\nLL +     });\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:194:5\n   |\nLL | /     if !map.contains_key(&1) {\nLL | |\nLL | |         let Some(1) = Some(2) else {\nLL | |             return None;\nLL | |         };\nLL | |         map.insert(1, 42);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let std::collections::hash_map::Entry::Vacant(e) = map.entry(1) {\nLL +\nLL +         let Some(1) = Some(2) else {\nLL +             return None;\nLL +         };\nLL +         e.insert(42);\nLL +     }\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry.rs:285:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         #[cfg(test)]\nLL | |         very_important_fn();\nLL | |         m.insert(k, v);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     m.entry(k).or_insert_with(|| {\nLL +\nLL +         #[cfg(test)]\nLL +         very_important_fn();\nLL +         v\nLL +     });\n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/entry_btree.fixed",
    "content": "#![warn(clippy::map_entry)]\n#![allow(dead_code)]\n\nuse std::collections::BTreeMap;\n\nfn foo() {}\n\nfn btree_map<K: Eq + Ord + Copy, V: Copy>(m: &mut BTreeMap<K, V>, k: K, v: V) {\n    // insert then do something, use if let\n    if let std::collections::btree_map::Entry::Vacant(e) = m.entry(k) {\n        //~^ map_entry\n        e.insert(v);\n        foo();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/entry_btree.rs",
    "content": "#![warn(clippy::map_entry)]\n#![allow(dead_code)]\n\nuse std::collections::BTreeMap;\n\nfn foo() {}\n\nfn btree_map<K: Eq + Ord + Copy, V: Copy>(m: &mut BTreeMap<K, V>, k: K, v: V) {\n    // insert then do something, use if let\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        m.insert(k, v);\n        foo();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/entry_btree.stderr",
    "content": "error: usage of `contains_key` followed by `insert` on a `BTreeMap`\n  --> tests/ui/entry_btree.rs:10:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         m.insert(k, v);\nLL | |         foo();\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::map-entry` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`\nhelp: try\n   |\nLL ~     if let std::collections::btree_map::Entry::Vacant(e) = m.entry(k) {\nLL +\nLL +         e.insert(v);\nLL +         foo();\nLL +     }\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/entry_unfixable.rs",
    "content": "#![allow(clippy::needless_pass_by_value, clippy::collapsible_if)]\n#![warn(clippy::map_entry)]\n\nuse std::collections::HashMap;\nuse std::hash::Hash;\n\nmacro_rules! m {\n    ($e:expr) => {{ $e }};\n}\n\nmacro_rules! insert {\n    ($map:expr, $key:expr, $val:expr) => {\n        $map.insert($key, $val)\n    };\n}\n\nmod issue13306 {\n    use std::collections::HashMap;\n\n    struct Env {\n        enclosing: Option<Box<Env>>,\n        values: HashMap<String, usize>,\n    }\n\n    impl Env {\n        fn assign(&mut self, name: String, value: usize) -> bool {\n            if !self.values.contains_key(&name) {\n                //~^ map_entry\n                self.values.insert(name, value);\n                true\n            } else if let Some(enclosing) = &mut self.enclosing {\n                enclosing.assign(name, value)\n            } else {\n                false\n            }\n        }\n    }\n}\n\nfn issue9925(mut hm: HashMap<String, bool>) {\n    let key = \"hello\".to_string();\n    if hm.contains_key(&key) {\n        //~^ map_entry\n        let bval = hm.get_mut(&key).unwrap();\n        *bval = false;\n    } else {\n        hm.insert(key, true);\n    }\n}\n\nmod issue9470 {\n    use std::collections::HashMap;\n    use std::sync::Mutex;\n\n    struct Interner(i32);\n\n    impl Interner {\n        const fn new() -> Self {\n            Interner(0)\n        }\n\n        fn resolve(&self, name: String) -> Option<String> {\n            todo!()\n        }\n    }\n\n    static INTERNER: Mutex<Interner> = Mutex::new(Interner::new());\n\n    struct VM {\n        stack: Vec<i32>,\n        globals: HashMap<String, i32>,\n    }\n\n    impl VM {\n        fn stack_top(&self) -> &i32 {\n            self.stack.last().unwrap()\n        }\n\n        fn resolve(&mut self, name: String, value: i32) -> Result<(), String> {\n            if self.globals.contains_key(&name) {\n                //~^ map_entry\n                self.globals.insert(name, value);\n            } else {\n                let interner = INTERNER.lock().unwrap();\n                return Err(interner.resolve(name).unwrap().to_owned());\n            }\n\n            Ok(())\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/entry_unfixable.stderr",
    "content": "error: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_unfixable.rs:27:13\n   |\nLL | /             if !self.values.contains_key(&name) {\nLL | |\nLL | |                 self.values.insert(name, value);\nLL | |                 true\n...  |\nLL | |                 false\nLL | |             }\n   | |_____________^\n   |\n   = help: consider using the `Entry` API: https://doc.rust-lang.org/std/collections/struct.HashMap.html#entry-api\n   = note: `-D clippy::map-entry` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_unfixable.rs:42:5\n   |\nLL | /     if hm.contains_key(&key) {\nLL | |\nLL | |         let bval = hm.get_mut(&key).unwrap();\nLL | |         *bval = false;\nLL | |     } else {\nLL | |         hm.insert(key, true);\nLL | |     }\n   | |_____^\n   |\n   = help: consider using the `Entry` API: https://doc.rust-lang.org/std/collections/struct.HashMap.html#entry-api\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_unfixable.rs:80:13\n   |\nLL | /             if self.globals.contains_key(&name) {\nLL | |\nLL | |                 self.globals.insert(name, value);\nLL | |             } else {\nLL | |                 let interner = INTERNER.lock().unwrap();\nLL | |                 return Err(interner.resolve(name).unwrap().to_owned());\nLL | |             }\n   | |_____________^\n   |\n   = help: consider using the `Entry` API: https://doc.rust-lang.org/std/collections/struct.HashMap.html#entry-api\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/entry_with_else.fixed",
    "content": "#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]\n#![warn(clippy::map_entry)]\n\nuse std::collections::{BTreeMap, HashMap};\nuse std::hash::Hash;\n\nmacro_rules! m {\n    ($e:expr) => {{ $e }};\n}\n\nfn foo() {}\n\nfn insert_if_absent0<K: Eq + Hash + Copy, V: Copy>(m: &mut HashMap<K, V>, k: K, v: V, v2: V) {\n    match m.entry(k) {\n        std::collections::hash_map::Entry::Vacant(e) => {\n            //~^ map_entry\n            e.insert(v);\n        }\n        std::collections::hash_map::Entry::Occupied(mut e) => {\n            e.insert(v2);\n        }\n    }\n\n    match m.entry(k) {\n        std::collections::hash_map::Entry::Occupied(mut e) => {\n            //~^ map_entry\n            e.insert(v);\n        }\n        std::collections::hash_map::Entry::Vacant(e) => {\n            e.insert(v2);\n        }\n    }\n\n    if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {\n        //~^ map_entry\n        e.insert(v);\n    } else {\n        foo();\n    }\n\n    if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) {\n        e.insert(v);\n    } else {\n        //~^ map_entry\n        foo();\n    }\n\n    match m.entry(k) {\n        std::collections::hash_map::Entry::Vacant(e) => {\n            //~^ map_entry\n            e.insert(v);\n        }\n        std::collections::hash_map::Entry::Occupied(mut e) => {\n            e.insert(v2);\n        }\n    }\n\n    match m.entry(k) {\n        std::collections::hash_map::Entry::Occupied(mut e) => {\n            //~^ map_entry\n            if true { Some(e.insert(v)) } else { Some(e.insert(v2)) }\n        }\n        std::collections::hash_map::Entry::Vacant(e) => {\n            e.insert(v);\n            None\n        }\n    };\n\n    if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) {\n        //~^ map_entry\n        foo();\n        Some(e.insert(v))\n    } else {\n        None\n    };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/entry_with_else.rs",
    "content": "#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]\n#![warn(clippy::map_entry)]\n\nuse std::collections::{BTreeMap, HashMap};\nuse std::hash::Hash;\n\nmacro_rules! m {\n    ($e:expr) => {{ $e }};\n}\n\nfn foo() {}\n\nfn insert_if_absent0<K: Eq + Hash + Copy, V: Copy>(m: &mut HashMap<K, V>, k: K, v: V, v2: V) {\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        m.insert(k, v);\n    } else {\n        m.insert(k, v2);\n    }\n\n    if m.contains_key(&k) {\n        //~^ map_entry\n        m.insert(k, v);\n    } else {\n        m.insert(k, v2);\n    }\n\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        m.insert(k, v);\n    } else {\n        foo();\n    }\n\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        foo();\n    } else {\n        m.insert(k, v);\n    }\n\n    if !m.contains_key(&k) {\n        //~^ map_entry\n        m.insert(k, v);\n    } else {\n        m.insert(k, v2);\n    }\n\n    if m.contains_key(&k) {\n        //~^ map_entry\n        if true { m.insert(k, v) } else { m.insert(k, v2) }\n    } else {\n        m.insert(k, v)\n    };\n\n    if m.contains_key(&k) {\n        //~^ map_entry\n        foo();\n        m.insert(k, v)\n    } else {\n        None\n    };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/entry_with_else.stderr",
    "content": "error: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_with_else.rs:14:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         m.insert(k, v);\nLL | |     } else {\nLL | |         m.insert(k, v2);\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::map-entry` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`\nhelp: try\n   |\nLL ~     match m.entry(k) {\nLL +         std::collections::hash_map::Entry::Vacant(e) => {\nLL +\nLL +             e.insert(v);\nLL +         }\nLL +         std::collections::hash_map::Entry::Occupied(mut e) => {\nLL +             e.insert(v2);\nLL +         }\nLL +     }\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_with_else.rs:21:5\n   |\nLL | /     if m.contains_key(&k) {\nLL | |\nLL | |         m.insert(k, v);\nLL | |     } else {\nLL | |         m.insert(k, v2);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     match m.entry(k) {\nLL +         std::collections::hash_map::Entry::Occupied(mut e) => {\nLL +\nLL +             e.insert(v);\nLL +         }\nLL +         std::collections::hash_map::Entry::Vacant(e) => {\nLL +             e.insert(v2);\nLL +         }\nLL +     }\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_with_else.rs:28:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         m.insert(k, v);\nLL | |     } else {\nLL | |         foo();\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let std::collections::hash_map::Entry::Vacant(e) = m.entry(k) {\nLL +\nLL +         e.insert(v);\nLL +     } else {\nLL +         foo();\nLL +     }\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_with_else.rs:35:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         foo();\nLL | |     } else {\nLL | |         m.insert(k, v);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) {\nLL +         e.insert(v);\nLL +     } else {\nLL +\nLL +         foo();\nLL +     }\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_with_else.rs:42:5\n   |\nLL | /     if !m.contains_key(&k) {\nLL | |\nLL | |         m.insert(k, v);\nLL | |     } else {\nLL | |         m.insert(k, v2);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     match m.entry(k) {\nLL +         std::collections::hash_map::Entry::Vacant(e) => {\nLL +\nLL +             e.insert(v);\nLL +         }\nLL +         std::collections::hash_map::Entry::Occupied(mut e) => {\nLL +             e.insert(v2);\nLL +         }\nLL +     }\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_with_else.rs:49:5\n   |\nLL | /     if m.contains_key(&k) {\nLL | |\nLL | |         if true { m.insert(k, v) } else { m.insert(k, v2) }\nLL | |     } else {\nLL | |         m.insert(k, v)\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     match m.entry(k) {\nLL +         std::collections::hash_map::Entry::Occupied(mut e) => {\nLL +\nLL +             if true { Some(e.insert(v)) } else { Some(e.insert(v2)) }\nLL +         }\nLL +         std::collections::hash_map::Entry::Vacant(e) => {\nLL +             e.insert(v);\nLL +             None\nLL +         }\nLL ~     };\n   |\n\nerror: usage of `contains_key` followed by `insert` on a `HashMap`\n  --> tests/ui/entry_with_else.rs:56:5\n   |\nLL | /     if m.contains_key(&k) {\nLL | |\nLL | |         foo();\nLL | |         m.insert(k, v)\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let std::collections::hash_map::Entry::Occupied(mut e) = m.entry(k) {\nLL +\nLL +         foo();\nLL +         Some(e.insert(v))\nLL +     } else {\nLL +         None\nLL ~     };\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/enum_clike_unportable_variant.rs",
    "content": "//@ignore-bitwidth: 32\n\n#![warn(clippy::enum_clike_unportable_variant)]\n#![allow(unused, non_upper_case_globals)]\n\n#[repr(usize)]\nenum NonPortable {\n    X = 0x1_0000_0000,\n    //~^ enum_clike_unportable_variant\n    Y = 0,\n    Z = 0x7FFF_FFFF,\n    A = 0xFFFF_FFFF,\n}\n\nenum NonPortableNoHint {\n    X = 0x1_0000_0000,\n    //~^ enum_clike_unportable_variant\n    Y = 0,\n    Z = 0x7FFF_FFFF,\n    A = 0xFFFF_FFFF,\n    //~^ enum_clike_unportable_variant\n}\n\n#[repr(isize)]\nenum NonPortableSigned {\n    X = -1,\n    Y = 0x7FFF_FFFF,\n    Z = 0xFFFF_FFFF,\n    //~^ enum_clike_unportable_variant\n    A = 0x1_0000_0000,\n    //~^ enum_clike_unportable_variant\n    B = i32::MIN as isize,\n    C = (i32::MIN as isize) - 1,\n    //~^ enum_clike_unportable_variant\n}\n\nenum NonPortableSignedNoHint {\n    X = -1,\n    Y = 0x7FFF_FFFF,\n    Z = 0xFFFF_FFFF,\n    //~^ enum_clike_unportable_variant\n    A = 0x1_0000_0000,\n    //~^ enum_clike_unportable_variant\n}\n\n#[repr(usize)]\nenum NonPortable2 {\n    X = <usize as Trait>::Number,\n    //~^ enum_clike_unportable_variant\n    Y = 0,\n}\n\ntrait Trait {\n    const Number: usize = 0x1_0000_0000;\n}\n\nimpl Trait for usize {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/enum_clike_unportable_variant.stderr",
    "content": "error: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:8:5\n   |\nLL |     X = 0x1_0000_0000,\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::enum-clike-unportable-variant` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::enum_clike_unportable_variant)]`\n\nerror: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:16:5\n   |\nLL |     X = 0x1_0000_0000,\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:20:5\n   |\nLL |     A = 0xFFFF_FFFF,\n   |     ^^^^^^^^^^^^^^^\n\nerror: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:28:5\n   |\nLL |     Z = 0xFFFF_FFFF,\n   |     ^^^^^^^^^^^^^^^\n\nerror: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:30:5\n   |\nLL |     A = 0x1_0000_0000,\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:33:5\n   |\nLL |     C = (i32::MIN as isize) - 1,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:40:5\n   |\nLL |     Z = 0xFFFF_FFFF,\n   |     ^^^^^^^^^^^^^^^\n\nerror: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:42:5\n   |\nLL |     A = 0x1_0000_0000,\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: C-like enum variant discriminant is not portable to 32-bit targets\n  --> tests/ui/enum_clike_unportable_variant.rs:48:5\n   |\nLL |     X = <usize as Trait>::Number,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/enum_glob_use.fixed",
    "content": "#![warn(clippy::enum_glob_use)]\n#![allow(unused)]\n#![warn(unused_imports)]\n\nuse std::cmp::Ordering::Less;\n//~^ enum_glob_use\n\nenum Enum {\n    Foo,\n}\n\nuse self::Enum::Foo;\n//~^ enum_glob_use\n\nmod in_fn_test {\n    fn blarg() {\n        use crate::Enum::Foo;\n        //~^ enum_glob_use\n\n        let _ = Foo;\n    }\n}\n\nmod blurg {\n    #[allow(unused_imports)]\n    pub use std::cmp::Ordering::*; // ok, re-export\n}\n\nfn main() {\n    let _ = Foo;\n    let _ = Less;\n}\n"
  },
  {
    "path": "tests/ui/enum_glob_use.rs",
    "content": "#![warn(clippy::enum_glob_use)]\n#![allow(unused)]\n#![warn(unused_imports)]\n\nuse std::cmp::Ordering::*;\n//~^ enum_glob_use\n\nenum Enum {\n    Foo,\n}\n\nuse self::Enum::*;\n//~^ enum_glob_use\n\nmod in_fn_test {\n    fn blarg() {\n        use crate::Enum::*;\n        //~^ enum_glob_use\n\n        let _ = Foo;\n    }\n}\n\nmod blurg {\n    #[allow(unused_imports)]\n    pub use std::cmp::Ordering::*; // ok, re-export\n}\n\nfn main() {\n    let _ = Foo;\n    let _ = Less;\n}\n"
  },
  {
    "path": "tests/ui/enum_glob_use.stderr",
    "content": "error: usage of wildcard import for enum variants\n  --> tests/ui/enum_glob_use.rs:5:5\n   |\nLL | use std::cmp::Ordering::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::cmp::Ordering::Less`\n   |\n   = note: `-D clippy::enum-glob-use` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::enum_glob_use)]`\n\nerror: usage of wildcard import for enum variants\n  --> tests/ui/enum_glob_use.rs:12:5\n   |\nLL | use self::Enum::*;\n   |     ^^^^^^^^^^^^^ help: try: `self::Enum::Foo`\n\nerror: usage of wildcard import for enum variants\n  --> tests/ui/enum_glob_use.rs:17:13\n   |\nLL |         use crate::Enum::*;\n   |             ^^^^^^^^^^^^^^ help: try: `crate::Enum::Foo`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/enum_variants.rs",
    "content": "#![warn(clippy::enum_variant_names)]\n#![allow(non_camel_case_types, clippy::upper_case_acronyms)]\n\nenum FakeCallType {\n    CALL,\n    CREATE,\n}\n\nenum FakeCallType2 {\n    CALL,\n    CREATELL,\n}\n\nenum Foo {\n    //~^ enum_variant_names\n    cFoo,\n    //~^ enum_variant_names\n    cBar,\n    cBaz,\n}\n\nenum Fooo {\n    cFoo, // no error, threshold is 3 variants by default\n    cBar,\n}\n\nenum Food {\n    //~^ enum_variant_names\n    FoodGood,\n    //~^ enum_variant_names\n    FoodMiddle,\n    //~^ enum_variant_names\n    FoodBad,\n    //~^ enum_variant_names\n}\n\nenum Stuff {\n    StuffBad, // no error\n}\n\nenum BadCallType {\n    //~^ enum_variant_names\n    CallTypeCall,\n    CallTypeCreate,\n    CallTypeDestroy,\n}\n\nenum TwoCallType {\n    // no error\n    CallTypeCall,\n    CallTypeCreate,\n}\n\nenum Consts {\n    //~^ enum_variant_names\n    ConstantInt,\n    ConstantCake,\n    ConstantLie,\n}\n\nenum Two {\n    // no error here\n    ConstantInt,\n    ConstantInfer,\n}\n\nenum Something {\n    //~^ enum_variant_names\n    CCall,\n    CCreate,\n    CCryogenize,\n}\n\nenum Seal {\n    With,\n    Without,\n}\n\nenum Seall {\n    With,\n    WithOut,\n    Withbroken,\n}\n\nenum Sealll {\n    With,\n    WithOut,\n}\n\nenum Seallll {\n    //~^ enum_variant_names\n    WithOutCake,\n    WithOutTea,\n    WithOut,\n}\n\nenum NonCaps {\n    Prefix的,\n    PrefixTea,\n    PrefixCake,\n}\n\npub enum PubSeall {\n    WithOutCake,\n    WithOutTea,\n    WithOut,\n}\n\n#[allow(clippy::enum_variant_names)]\npub mod allowed {\n    pub enum PubAllowed {\n        SomeThis,\n        SomeThat,\n        SomeOtherWhat,\n    }\n}\n\n// should not lint\nenum Pat {\n    Foo,\n    Bar,\n    Path,\n}\n\n// should not lint\nenum N {\n    Pos,\n    Neg,\n    Float,\n}\n\n// should not lint\nenum Peek {\n    Peek1,\n    Peek2,\n    Peek3,\n}\n\n// should not lint\npub enum NetworkLayer {\n    Layer2,\n    Layer3,\n}\n\n// should lint suggesting `IData`, not only `Data` (see #4639)\nenum IDataRequest {\n    //~^ enum_variant_names\n    PutIData(String),\n    GetIData(String),\n    DeleteUnpubIData(String),\n}\n\nenum HIDataRequest {\n    //~^ enum_variant_names\n    PutHIData(String),\n    GetHIData(String),\n    DeleteUnpubHIData(String),\n}\n\nenum North {\n    Normal,\n    NoLeft,\n    NoRight,\n}\n\n// #8324\nenum Phase {\n    PreLookup,\n    Lookup,\n    PostLookup,\n}\n\nmod issue9018 {\n    enum DoLint {\n        //~^ enum_variant_names\n        _TypeCreate,\n        _TypeRead,\n        _TypeUpdate,\n        _TypeDestroy,\n    }\n\n    enum DoLintToo {\n        //~^ enum_variant_names\n        _CreateType,\n        _UpdateType,\n        _DeleteType,\n    }\n\n    enum DoNotLint {\n        _Foo,\n        _Bar,\n        _Baz,\n    }\n}\n\nmod allow_attributes_on_variants {\n    enum Enum {\n        #[allow(clippy::enum_variant_names)]\n        EnumStartsWith,\n        #[allow(clippy::enum_variant_names)]\n        EndsWithEnum,\n        Foo,\n    }\n}\n\nmod issue11494 {\n    // variant order should not affect lint\n    enum Data {\n        Valid,\n        Invalid,\n        DataDependent,\n        //~^ enum_variant_names\n    }\n\n    enum Datas {\n        DatasDependent,\n        //~^ enum_variant_names\n        Valid,\n        Invalid,\n    }\n}\n\nmod encapsulated {\n    mod types {\n        pub struct FooError;\n        pub struct BarError;\n        pub struct BazError;\n    }\n\n    enum Error {\n        FooError(types::FooError),\n        BarError(types::BarError),\n        BazError(types::BazError),\n        Other,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/enum_variants.stderr",
    "content": "error: variant name ends with the enum's name\n  --> tests/ui/enum_variants.rs:16:5\n   |\nLL |     cFoo,\n   |     ^^^^\n   |\n   = note: `-D clippy::enum-variant-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`\n\nerror: all variants have the same prefix: `c`\n  --> tests/ui/enum_variants.rs:14:1\n   |\nLL | / enum Foo {\nLL | |\nLL | |     cFoo,\n...  |\nLL | |     cBaz,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes and use full paths to the variants instead of glob imports\n\nerror: variant name starts with the enum's name\n  --> tests/ui/enum_variants.rs:29:5\n   |\nLL |     FoodGood,\n   |     ^^^^^^^^\n\nerror: variant name starts with the enum's name\n  --> tests/ui/enum_variants.rs:31:5\n   |\nLL |     FoodMiddle,\n   |     ^^^^^^^^^^\n\nerror: variant name starts with the enum's name\n  --> tests/ui/enum_variants.rs:33:5\n   |\nLL |     FoodBad,\n   |     ^^^^^^^\n\nerror: all variants have the same prefix: `Food`\n  --> tests/ui/enum_variants.rs:27:1\n   |\nLL | / enum Food {\nLL | |\nLL | |     FoodGood,\n...  |\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes and use full paths to the variants instead of glob imports\n\nerror: all variants have the same prefix: `CallType`\n  --> tests/ui/enum_variants.rs:41:1\n   |\nLL | / enum BadCallType {\nLL | |\nLL | |     CallTypeCall,\nLL | |     CallTypeCreate,\nLL | |     CallTypeDestroy,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes and use full paths to the variants instead of glob imports\n\nerror: all variants have the same prefix: `Constant`\n  --> tests/ui/enum_variants.rs:54:1\n   |\nLL | / enum Consts {\nLL | |\nLL | |     ConstantInt,\nLL | |     ConstantCake,\nLL | |     ConstantLie,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes and use full paths to the variants instead of glob imports\n\nerror: all variants have the same prefix: `C`\n  --> tests/ui/enum_variants.rs:67:1\n   |\nLL | / enum Something {\nLL | |\nLL | |     CCall,\nLL | |     CCreate,\nLL | |     CCryogenize,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes and use full paths to the variants instead of glob imports\n\nerror: all variants have the same prefix: `WithOut`\n  --> tests/ui/enum_variants.rs:90:1\n   |\nLL | / enum Seallll {\nLL | |\nLL | |     WithOutCake,\nLL | |     WithOutTea,\nLL | |     WithOut,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes and use full paths to the variants instead of glob imports\n\nerror: all variants have the same postfix: `IData`\n  --> tests/ui/enum_variants.rs:146:1\n   |\nLL | / enum IDataRequest {\nLL | |\nLL | |     PutIData(String),\nLL | |     GetIData(String),\nLL | |     DeleteUnpubIData(String),\nLL | | }\n   | |_^\n   |\n   = help: remove the postfixes and use full paths to the variants instead of glob imports\n\nerror: all variants have the same postfix: `HIData`\n  --> tests/ui/enum_variants.rs:153:1\n   |\nLL | / enum HIDataRequest {\nLL | |\nLL | |     PutHIData(String),\nLL | |     GetHIData(String),\nLL | |     DeleteUnpubHIData(String),\nLL | | }\n   | |_^\n   |\n   = help: remove the postfixes and use full paths to the variants instead of glob imports\n\nerror: all variants have the same prefix: `_Type`\n  --> tests/ui/enum_variants.rs:174:5\n   |\nLL | /     enum DoLint {\nLL | |\nLL | |         _TypeCreate,\nLL | |         _TypeRead,\nLL | |         _TypeUpdate,\nLL | |         _TypeDestroy,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the prefixes and use full paths to the variants instead of glob imports\n\nerror: all variants have the same postfix: `Type`\n  --> tests/ui/enum_variants.rs:182:5\n   |\nLL | /     enum DoLintToo {\nLL | |\nLL | |         _CreateType,\nLL | |         _UpdateType,\nLL | |         _DeleteType,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the postfixes and use full paths to the variants instead of glob imports\n\nerror: variant name starts with the enum's name\n  --> tests/ui/enum_variants.rs:211:9\n   |\nLL |         DataDependent,\n   |         ^^^^^^^^^^^^^\n\nerror: variant name starts with the enum's name\n  --> tests/ui/enum_variants.rs:216:9\n   |\nLL |         DatasDependent,\n   |         ^^^^^^^^^^^^^^\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/eprint_with_newline.fixed",
    "content": "#![allow(clippy::print_literal)]\n#![warn(clippy::print_with_newline)]\n\nfn main() {\n    eprintln!(\"Hello\");\n    //~^ print_with_newline\n\n    eprintln!(\"Hello {}\", \"world\");\n    //~^ print_with_newline\n\n    eprintln!(\"Hello {} {}\", \"world\", \"#2\");\n    //~^ print_with_newline\n\n    eprintln!(\"{}\", 1265);\n    //~^ print_with_newline\n\n    eprintln!();\n    //~^ print_with_newline\n\n    // these are all fine\n    eprint!(\"\");\n    eprint!(\"Hello\");\n    eprintln!(\"Hello\");\n    eprintln!(\"Hello\\n\");\n    eprintln!(\"Hello {}\\n\", \"world\");\n    eprint!(\"Issue\\n{}\", 1265);\n    eprint!(\"{}\", 1265);\n    eprint!(\"\\n{}\", 1275);\n    eprint!(\"\\n\\n\");\n    eprint!(\"like eof\\n\\n\");\n    eprint!(\"Hello {} {}\\n\\n\", \"world\", \"#2\");\n    // #3126\n    eprintln!(\"\\ndon't\\nwarn\\nfor\\nmultiple\\nnewlines\\n\");\n    // #3126\n    eprintln!(\"\\nbla\\n\\n\");\n\n    // Escaping\n    // #3514\n    eprint!(\"\\\\n\");\n    eprintln!(\"\\\\\");\n    //~^ print_with_newline\n\n    eprint!(\"\\\\\\\\n\");\n\n    // Raw strings\n    // #3778\n    eprint!(r\"\\n\");\n\n    // Literal newlines should also fail\n    eprintln!(\n        //~^ print_with_newline\n        \n    );\n    eprintln!(\n        //~^ print_with_newline\n        \n    );\n\n    // Don't warn on CRLF (#4208)\n    eprint!(\"\\r\\n\");\n    eprint!(\"foo\\r\\n\");\n    eprintln!(\"\\\\r\");\n    //~^ print_with_newline\n\n    eprint!(\"foo\\rbar\\n\");\n\n    // Ignore expanded format strings\n    macro_rules! newline {\n        () => {\n            \"\\n\"\n        };\n    }\n    eprint!(newline!());\n}\n"
  },
  {
    "path": "tests/ui/eprint_with_newline.rs",
    "content": "#![allow(clippy::print_literal)]\n#![warn(clippy::print_with_newline)]\n\nfn main() {\n    eprint!(\"Hello\\n\");\n    //~^ print_with_newline\n\n    eprint!(\"Hello {}\\n\", \"world\");\n    //~^ print_with_newline\n\n    eprint!(\"Hello {} {}\\n\", \"world\", \"#2\");\n    //~^ print_with_newline\n\n    eprint!(\"{}\\n\", 1265);\n    //~^ print_with_newline\n\n    eprint!(\"\\n\");\n    //~^ print_with_newline\n\n    // these are all fine\n    eprint!(\"\");\n    eprint!(\"Hello\");\n    eprintln!(\"Hello\");\n    eprintln!(\"Hello\\n\");\n    eprintln!(\"Hello {}\\n\", \"world\");\n    eprint!(\"Issue\\n{}\", 1265);\n    eprint!(\"{}\", 1265);\n    eprint!(\"\\n{}\", 1275);\n    eprint!(\"\\n\\n\");\n    eprint!(\"like eof\\n\\n\");\n    eprint!(\"Hello {} {}\\n\\n\", \"world\", \"#2\");\n    // #3126\n    eprintln!(\"\\ndon't\\nwarn\\nfor\\nmultiple\\nnewlines\\n\");\n    // #3126\n    eprintln!(\"\\nbla\\n\\n\");\n\n    // Escaping\n    // #3514\n    eprint!(\"\\\\n\");\n    eprint!(\"\\\\\\n\");\n    //~^ print_with_newline\n\n    eprint!(\"\\\\\\\\n\");\n\n    // Raw strings\n    // #3778\n    eprint!(r\"\\n\");\n\n    // Literal newlines should also fail\n    eprint!(\n        //~^ print_with_newline\n        \"\n\"\n    );\n    eprint!(\n        //~^ print_with_newline\n        r\"\n\"\n    );\n\n    // Don't warn on CRLF (#4208)\n    eprint!(\"\\r\\n\");\n    eprint!(\"foo\\r\\n\");\n    eprint!(\"\\\\r\\n\");\n    //~^ print_with_newline\n\n    eprint!(\"foo\\rbar\\n\");\n\n    // Ignore expanded format strings\n    macro_rules! newline {\n        () => {\n            \"\\n\"\n        };\n    }\n    eprint!(newline!());\n}\n"
  },
  {
    "path": "tests/ui/eprint_with_newline.stderr",
    "content": "error: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:5:5\n   |\nLL |     eprint!(\"Hello\\n\");\n   |     ^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::print-with-newline` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_with_newline)]`\nhelp: use `eprintln!` instead\n   |\nLL -     eprint!(\"Hello\\n\");\nLL +     eprintln!(\"Hello\");\n   |\n\nerror: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:8:5\n   |\nLL |     eprint!(\"Hello {}\\n\", \"world\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `eprintln!` instead\n   |\nLL -     eprint!(\"Hello {}\\n\", \"world\");\nLL +     eprintln!(\"Hello {}\", \"world\");\n   |\n\nerror: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:11:5\n   |\nLL |     eprint!(\"Hello {} {}\\n\", \"world\", \"#2\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `eprintln!` instead\n   |\nLL -     eprint!(\"Hello {} {}\\n\", \"world\", \"#2\");\nLL +     eprintln!(\"Hello {} {}\", \"world\", \"#2\");\n   |\n\nerror: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:14:5\n   |\nLL |     eprint!(\"{}\\n\", 1265);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `eprintln!` instead\n   |\nLL -     eprint!(\"{}\\n\", 1265);\nLL +     eprintln!(\"{}\", 1265);\n   |\n\nerror: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:17:5\n   |\nLL |     eprint!(\"\\n\");\n   |     ^^^^^^^^^^^^^\n   |\nhelp: use `eprintln!` instead\n   |\nLL -     eprint!(\"\\n\");\nLL +     eprintln!();\n   |\n\nerror: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:40:5\n   |\nLL |     eprint!(\"\\\\\\n\");\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: use `eprintln!` instead\n   |\nLL -     eprint!(\"\\\\\\n\");\nLL +     eprintln!(\"\\\\\");\n   |\n\nerror: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:50:5\n   |\nLL | /     eprint!(\nLL | |\nLL | |         \"\nLL | | \"\nLL | |     );\n   | |_____^\n   |\nhelp: use `eprintln!` instead\n   |\nLL ~     eprintln!(\nLL |\nLL ~         \n   |\n\nerror: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:55:5\n   |\nLL | /     eprint!(\nLL | |\nLL | |         r\"\nLL | | \"\nLL | |     );\n   | |_____^\n   |\nhelp: use `eprintln!` instead\n   |\nLL ~     eprintln!(\nLL |\nLL ~         \n   |\n\nerror: using `eprint!()` with a format string that ends in a single newline\n  --> tests/ui/eprint_with_newline.rs:64:5\n   |\nLL |     eprint!(\"\\\\r\\n\");\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: use `eprintln!` instead\n   |\nLL -     eprint!(\"\\\\r\\n\");\nLL +     eprintln!(\"\\\\r\");\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/eq_op.rs",
    "content": "#![warn(clippy::eq_op)]\n#![allow(clippy::double_parens, clippy::identity_op, clippy::nonminimal_bool)]\n#![allow(clippy::suspicious_xor_used_as_pow)]\n\nfn main() {\n    // simple values and comparisons\n    let _ = 1 == 1;\n    //~^ eq_op\n\n    let _ = \"no\" == \"no\";\n    //~^ eq_op\n\n    // even though I agree that no means no ;-)\n    let _ = false != false;\n    //~^ eq_op\n\n    let _ = 1.5 < 1.5;\n    //~^ eq_op\n\n    let _ = 1u64 >= 1u64;\n    //~^ eq_op\n\n    let x = f32::NAN;\n    let _ = x != x;\n    //~^ eq_op\n\n    // casts, methods, parentheses\n    let _ = (1u32 as u64) & (1u32 as u64);\n    //~^ eq_op\n\n    #[rustfmt::skip]\n    {\n        let _ = 1 ^ ((((((1))))));\n        //~^ eq_op\n\n    };\n\n    // unary and binary operators\n    let _ = (-(2) < -(2));\n    //~^ eq_op\n\n    let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));\n    //~^ eq_op\n    //~| eq_op\n    //~| eq_op\n\n    let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4;\n    //~^ eq_op\n\n    // various other things\n    let _ = ([1] != [1]);\n    //~^ eq_op\n\n    let _ = ((1, 2) != (1, 2));\n    //~^ eq_op\n\n    let _ = vec![1, 2, 3] == vec![1, 2, 3]; //no error yet, as we don't match macros\n\n    // const folding\n    let _ = 1 + 1 == 2;\n    //~^ eq_op\n\n    let _ = 1 - 1 == 0;\n    //~^ eq_op\n    //~| eq_op\n\n    let _ = 1 - 1;\n    //~^ eq_op\n\n    let _ = 1 / 1;\n    //~^ eq_op\n\n    let _ = true && true;\n    //~^ eq_op\n\n    let _ = true || true;\n    //~^ eq_op\n\n    let a: u32 = 0;\n    let b: u32 = 0;\n\n    let _ = a == b && b == a;\n    //~^ eq_op\n\n    let _ = a != b && b != a;\n    //~^ eq_op\n\n    let _ = a < b && b > a;\n    //~^ eq_op\n\n    let _ = a <= b && b >= a;\n    //~^ eq_op\n\n    let mut a = vec![1];\n    let _ = a == a;\n    //~^ eq_op\n\n    let _ = 2 * a.len() == 2 * a.len(); // ok, functions\n    let _ = a.pop() == a.pop(); // ok, functions\n\n    check_ignore_macro();\n\n    // named constants\n    const A: u32 = 10;\n    const B: u32 = 10;\n    const C: u32 = A / B; // ok, different named constants\n    const D: u32 = A / A;\n    //~^ eq_op\n}\n\nmacro_rules! check_if_named_foo {\n    ($expression:expr) => {\n        if stringify!($expression) == \"foo\" {\n            println!(\"foo!\");\n        } else {\n            println!(\"not foo.\");\n        }\n    };\n}\n\nmacro_rules! bool_macro {\n    ($expression:expr) => {\n        true\n    };\n}\n\nfn check_ignore_macro() {\n    check_if_named_foo!(foo);\n    // checks if the lint ignores macros with `!` operator\n    let _ = !bool_macro!(1) && !bool_macro!(\"\");\n}\n\nstruct Nested {\n    inner: ((i32,), (i32,), (i32,)),\n}\n\nfn check_nested(n1: &Nested, n2: &Nested) -> bool {\n    // `n2.inner.0.0` mistyped as `n1.inner.0.0`\n    (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0\n    //~^ eq_op\n}\n\n#[test]\nfn eq_op_shouldnt_trigger_in_tests() {\n    let a = 1;\n    let result = a + 1 == 1 + a;\n    assert!(result);\n}\n\n#[test]\nfn eq_op_macros_shouldnt_trigger_in_tests() {\n    let a = 1;\n    let b = 2;\n    assert_eq!(a, a);\n    assert_eq!(a + b, b + a);\n}\n"
  },
  {
    "path": "tests/ui/eq_op.stderr",
    "content": "error: equal expressions as operands to `==`\n  --> tests/ui/eq_op.rs:7:13\n   |\nLL |     let _ = 1 == 1;\n   |             ^^^^^^\n   |\n   = note: `-D clippy::eq-op` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::eq_op)]`\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/eq_op.rs:10:13\n   |\nLL |     let _ = \"no\" == \"no\";\n   |             ^^^^^^^^^^^^\n\nerror: equal expressions as operands to `!=`\n  --> tests/ui/eq_op.rs:14:13\n   |\nLL |     let _ = false != false;\n   |             ^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `<`\n  --> tests/ui/eq_op.rs:17:13\n   |\nLL |     let _ = 1.5 < 1.5;\n   |             ^^^^^^^^^\n\nerror: equal expressions as operands to `>=`\n  --> tests/ui/eq_op.rs:20:13\n   |\nLL |     let _ = 1u64 >= 1u64;\n   |             ^^^^^^^^^^^^\n\nerror: equal expressions as operands to `!=`\n  --> tests/ui/eq_op.rs:24:13\n   |\nLL |     let _ = x != x;\n   |             ^^^^^^\n   |\n   = note: if you intended to check if the operand is NaN, use `.is_nan()` instead\n\nerror: equal expressions as operands to `&`\n  --> tests/ui/eq_op.rs:28:13\n   |\nLL |     let _ = (1u32 as u64) & (1u32 as u64);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `^`\n  --> tests/ui/eq_op.rs:33:17\n   |\nLL |         let _ = 1 ^ ((((((1))))));\n   |                 ^^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `<`\n  --> tests/ui/eq_op.rs:39:13\n   |\nLL |     let _ = (-(2) < -(2));\n   |             ^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/eq_op.rs:42:13\n   |\nLL |     let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `&`\n  --> tests/ui/eq_op.rs:42:14\n   |\nLL |     let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));\n   |              ^^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `&`\n  --> tests/ui/eq_op.rs:42:35\n   |\nLL |     let _ = ((1 + 1) & (1 + 1) == (1 + 1) & (1 + 1));\n   |                                   ^^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/eq_op.rs:47:13\n   |\nLL |     let _ = (1 * 2) + (3 * 4) == 1 * 2 + 3 * 4;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `!=`\n  --> tests/ui/eq_op.rs:51:13\n   |\nLL |     let _ = ([1] != [1]);\n   |             ^^^^^^^^^^^^\n\nerror: equal expressions as operands to `!=`\n  --> tests/ui/eq_op.rs:54:13\n   |\nLL |     let _ = ((1, 2) != (1, 2));\n   |             ^^^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/eq_op.rs:60:13\n   |\nLL |     let _ = 1 + 1 == 2;\n   |             ^^^^^^^^^^\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/eq_op.rs:63:13\n   |\nLL |     let _ = 1 - 1 == 0;\n   |             ^^^^^^^^^^\n\nerror: equal expressions as operands to `-`\n  --> tests/ui/eq_op.rs:63:13\n   |\nLL |     let _ = 1 - 1 == 0;\n   |             ^^^^^\n\nerror: equal expressions as operands to `-`\n  --> tests/ui/eq_op.rs:67:13\n   |\nLL |     let _ = 1 - 1;\n   |             ^^^^^\n\nerror: equal expressions as operands to `/`\n  --> tests/ui/eq_op.rs:70:13\n   |\nLL |     let _ = 1 / 1;\n   |             ^^^^^\n\nerror: equal expressions as operands to `&&`\n  --> tests/ui/eq_op.rs:73:13\n   |\nLL |     let _ = true && true;\n   |             ^^^^^^^^^^^^\n\nerror: equal expressions as operands to `||`\n  --> tests/ui/eq_op.rs:76:13\n   |\nLL |     let _ = true || true;\n   |             ^^^^^^^^^^^^\n\nerror: equal expressions as operands to `&&`\n  --> tests/ui/eq_op.rs:82:13\n   |\nLL |     let _ = a == b && b == a;\n   |             ^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `&&`\n  --> tests/ui/eq_op.rs:85:13\n   |\nLL |     let _ = a != b && b != a;\n   |             ^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `&&`\n  --> tests/ui/eq_op.rs:88:13\n   |\nLL |     let _ = a < b && b > a;\n   |             ^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `&&`\n  --> tests/ui/eq_op.rs:91:13\n   |\nLL |     let _ = a <= b && b >= a;\n   |             ^^^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/eq_op.rs:95:13\n   |\nLL |     let _ = a == a;\n   |             ^^^^^^\n\nerror: equal expressions as operands to `/`\n  --> tests/ui/eq_op.rs:107:20\n   |\nLL |     const D: u32 = A / A;\n   |                    ^^^^^\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/eq_op.rs:139:5\n   |\nLL |     (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 29 previous errors\n\n"
  },
  {
    "path": "tests/ui/eq_op_macros.rs",
    "content": "#![warn(clippy::eq_op)]\n#![allow(clippy::useless_vec)]\n\n// lint also in macro definition\nmacro_rules! assert_in_macro_def {\n    () => {\n        let a = 42;\n        assert_eq!(a, a);\n        //~^ eq_op\n        assert_ne!(a, a);\n        //~^ eq_op\n        debug_assert_eq!(a, a);\n        //~^ eq_op\n        debug_assert_ne!(a, a);\n        //~^ eq_op\n    };\n}\n\n// lint identical args in assert-like macro invocations (see #3574)\nfn main() {\n    assert_in_macro_def!();\n\n    let a = 1;\n    let b = 2;\n\n    // lint identical args in `assert_eq!`\n    assert_eq!(a, a);\n    //~^ eq_op\n\n    assert_eq!(a + 1, a + 1);\n    //~^ eq_op\n\n    // ok\n    assert_eq!(a, b);\n    assert_eq!(a, a + 1);\n    assert_eq!(a + 1, b + 1);\n\n    // lint identical args in `assert_ne!`\n    assert_ne!(a, a);\n    //~^ eq_op\n\n    assert_ne!(a + 1, a + 1);\n    //~^ eq_op\n\n    // ok\n    assert_ne!(a, b);\n    assert_ne!(a, a + 1);\n    assert_ne!(a + 1, b + 1);\n\n    // lint identical args in `debug_assert_eq!`\n    debug_assert_eq!(a, a);\n    //~^ eq_op\n\n    debug_assert_eq!(a + 1, a + 1);\n    //~^ eq_op\n\n    // ok\n    debug_assert_eq!(a, b);\n    debug_assert_eq!(a, a + 1);\n    debug_assert_eq!(a + 1, b + 1);\n\n    // lint identical args in `debug_assert_ne!`\n    debug_assert_ne!(a, a);\n    //~^ eq_op\n\n    debug_assert_ne!(a + 1, a + 1);\n    //~^ eq_op\n\n    // ok\n    debug_assert_ne!(a, b);\n    debug_assert_ne!(a, a + 1);\n    debug_assert_ne!(a + 1, b + 1);\n\n    let my_vec = vec![1; 5];\n    let mut my_iter = my_vec.iter();\n    assert_ne!(my_iter.next(), my_iter.next());\n}\n"
  },
  {
    "path": "tests/ui/eq_op_macros.stderr",
    "content": "error: identical args used in this `assert_eq!` macro call\n  --> tests/ui/eq_op_macros.rs:8:20\n   |\nLL |         assert_eq!(a, a);\n   |                    ^^^^\n...\nLL |     assert_in_macro_def!();\n   |     ---------------------- in this macro invocation\n   |\n   = note: `-D clippy::eq-op` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::eq_op)]`\n   = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: identical args used in this `assert_ne!` macro call\n  --> tests/ui/eq_op_macros.rs:10:20\n   |\nLL |         assert_ne!(a, a);\n   |                    ^^^^\n...\nLL |     assert_in_macro_def!();\n   |     ---------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: identical args used in this `debug_assert_eq!` macro call\n  --> tests/ui/eq_op_macros.rs:12:26\n   |\nLL |         debug_assert_eq!(a, a);\n   |                          ^^^^\n...\nLL |     assert_in_macro_def!();\n   |     ---------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: identical args used in this `debug_assert_ne!` macro call\n  --> tests/ui/eq_op_macros.rs:14:26\n   |\nLL |         debug_assert_ne!(a, a);\n   |                          ^^^^\n...\nLL |     assert_in_macro_def!();\n   |     ---------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `assert_in_macro_def` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: identical args used in this `assert_eq!` macro call\n  --> tests/ui/eq_op_macros.rs:27:16\n   |\nLL |     assert_eq!(a, a);\n   |                ^^^^\n\nerror: identical args used in this `assert_eq!` macro call\n  --> tests/ui/eq_op_macros.rs:30:16\n   |\nLL |     assert_eq!(a + 1, a + 1);\n   |                ^^^^^^^^^^^^\n\nerror: identical args used in this `assert_ne!` macro call\n  --> tests/ui/eq_op_macros.rs:39:16\n   |\nLL |     assert_ne!(a, a);\n   |                ^^^^\n\nerror: identical args used in this `assert_ne!` macro call\n  --> tests/ui/eq_op_macros.rs:42:16\n   |\nLL |     assert_ne!(a + 1, a + 1);\n   |                ^^^^^^^^^^^^\n\nerror: identical args used in this `debug_assert_eq!` macro call\n  --> tests/ui/eq_op_macros.rs:51:22\n   |\nLL |     debug_assert_eq!(a, a);\n   |                      ^^^^\n\nerror: identical args used in this `debug_assert_eq!` macro call\n  --> tests/ui/eq_op_macros.rs:54:22\n   |\nLL |     debug_assert_eq!(a + 1, a + 1);\n   |                      ^^^^^^^^^^^^\n\nerror: identical args used in this `debug_assert_ne!` macro call\n  --> tests/ui/eq_op_macros.rs:63:22\n   |\nLL |     debug_assert_ne!(a, a);\n   |                      ^^^^\n\nerror: identical args used in this `debug_assert_ne!` macro call\n  --> tests/ui/eq_op_macros.rs:66:22\n   |\nLL |     debug_assert_ne!(a + 1, a + 1);\n   |                      ^^^^^^^^^^^^\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/equatable_if_let.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::derive_partial_eq_without_eq, clippy::needless_ifs)]\n#![warn(clippy::equatable_if_let)]\nuse proc_macros::{external, inline_macros};\n\nuse std::cmp::Ordering;\n\n#[derive(PartialEq)]\nenum Enum {\n    TupleVariant(i32, u64),\n    RecordVariant { a: i64, b: u32 },\n    UnitVariant,\n    Recursive(Struct),\n}\n\n#[derive(PartialEq)]\nstruct Struct {\n    a: i32,\n    b: bool,\n}\n\nstruct NoPartialEqStruct {\n    a: i32,\n    b: bool,\n}\n\nenum NotPartialEq {\n    A,\n    B,\n}\n\nenum NotStructuralEq {\n    A,\n    B,\n}\n\nimpl PartialEq for NotStructuralEq {\n    fn eq(&self, _: &NotStructuralEq) -> bool {\n        false\n    }\n}\n\nfn main() {\n    let a = 2;\n    let b = 3;\n    let c = Some(2);\n    let d = Struct { a: 2, b: false };\n    let e = Enum::UnitVariant;\n    let f = NotPartialEq::A;\n    let g = NotStructuralEq::A;\n    let h = NoPartialEqStruct { a: 2, b: false };\n\n    // true\n\n    if a == 2 {}\n    //~^ equatable_if_let\n    if a.cmp(&b) == Ordering::Greater {}\n    //~^ equatable_if_let\n    if c == Some(2) {}\n    //~^ equatable_if_let\n    if d == (Struct { a: 2, b: false }) {}\n    //~^ equatable_if_let\n    if e == Enum::TupleVariant(32, 64) {}\n    //~^ equatable_if_let\n    if e == (Enum::RecordVariant { a: 64, b: 32 }) {}\n    //~^ equatable_if_let\n    if e == Enum::UnitVariant {}\n    //~^ equatable_if_let\n    if (e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false }) {}\n    //~^ equatable_if_let\n\n    // false\n\n    if let 2 | 3 = a {}\n    if let x @ 2 = a {}\n    if let Some(3 | 4) = c {}\n    if let Struct { a, b: false } = d {}\n    if let Struct { a: 2, b: x } = d {}\n    if matches!(f, NotPartialEq::A) {}\n    //~^ equatable_if_let\n    if g == NotStructuralEq::A {}\n    //~^ equatable_if_let\n    if matches!(Some(f), Some(NotPartialEq::A)) {}\n    //~^ equatable_if_let\n    if Some(g) == Some(NotStructuralEq::A) {}\n    //~^ equatable_if_let\n    if matches!(h, NoPartialEqStruct { a: 2, b: false }) {}\n    //~^ equatable_if_let\n}\n\nmod issue8710 {\n    fn str_ref(cs: &[char]) {\n        if matches!(cs.iter().next(), Some('i')) {\n            //~^ equatable_if_let\n        } else {\n            todo!();\n        }\n    }\n\n    fn i32_ref(cs: &[i32]) {\n        if matches!(cs.iter().next(), Some(1)) {\n            //~^ equatable_if_let\n        } else {\n            todo!();\n        }\n    }\n\n    fn enum_ref() {\n        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]\n        enum MyEnum {\n            A(i32),\n            B,\n        }\n\n        fn get_enum() -> Option<&'static MyEnum> {\n            todo!()\n        }\n\n        if matches!(get_enum(), Some(MyEnum::B)) {\n            //~^ equatable_if_let\n        } else {\n            todo!();\n        }\n    }\n}\n\n#[inline_macros]\nfn issue14548() {\n    if let inline!(\"abc\") = \"abc\" {\n        println!(\"OK\");\n    }\n\n    let a = 2;\n    external!({ if let 2 = $a {} });\n\n    // Don't lint: `==`/`matches!` might be correct for a particular `$($font)|*`, but not in general\n    macro_rules! m1 {\n        ($($font:pat_param)|*) => {\n            if let $($font)|* = \"from_expansion\" {}\n        }\n    }\n    m1!(\"foo\");\n    m1!(\"Sans\" | \"Serif\" | \"Sans Mono\");\n    m1!(inline!(\"foo\"));\n\n    // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in\n    // general\n    macro_rules! m2 {\n        ($from_root_ctxt:pat) => {\n            if let $from_root_ctxt = \"from_expansion\" {}\n        };\n    }\n    m2!(\"foo\");\n    m2!(\"Sans\" | \"Serif\" | \"Sans Mono\");\n    m2!(inline!(\"foo\"));\n\n    // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in\n    // general\n    macro_rules! m3 {\n        ($from_root_ctxt:expr) => {\n            if let \"from_expansion\" = $from_root_ctxt {}\n        };\n    }\n    m3!(\"foo\");\n    m3!(\"foo\");\n    m3!(inline!(\"foo\"));\n\n    // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in\n    // general. Don't get confused by the scrutinee coming from macro invocation\n    macro_rules! m4 {\n        ($from_root_ctxt:pat) => {\n            if let $from_root_ctxt = inline!(\"from_expansion\") {}\n        };\n    }\n    m4!(\"foo\");\n    m4!(\"Sans\" | \"Serif\" | \"Sans Mono\");\n    m4!(inline!(\"foo\"));\n\n    // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in\n    // general. Don't get confused by the scrutinee coming from macro invocation\n    macro_rules! m5 {\n        ($from_root_ctxt:expr) => {\n            if let inline!(\"from_expansion\") = $from_root_ctxt {}\n        };\n    }\n    m5!(\"foo\");\n    m5!(\"foo\");\n    m5!(inline!(\"foo\"));\n\n    // Would be nice to lint: both sides are macro _invocations_, so the suggestion is correct in\n    // general\n    if let inline!(\"foo\") = inline!(\"bar\") {}\n}\n\n// PartialEq is not stable in consts yet\nfn issue15376() {\n    enum NonConstEq {\n        A,\n        B,\n    }\n    impl PartialEq for NonConstEq {\n        fn eq(&self, _other: &Self) -> bool {\n            true\n        }\n    }\n\n    const N: NonConstEq = NonConstEq::A;\n\n    // `impl PartialEq` is not const, suggest `matches!`\n    const _: u32 = if matches!(N, NonConstEq::A) { 0 } else { 1 };\n    //~^ ERROR: this pattern matching can be expressed using `matches!`\n    const _: u32 = if matches!(Some(N), Some(NonConstEq::A)) { 0 } else { 1 };\n    //~^ ERROR: this pattern matching can be expressed using `matches!`\n}\n"
  },
  {
    "path": "tests/ui/equatable_if_let.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::derive_partial_eq_without_eq, clippy::needless_ifs)]\n#![warn(clippy::equatable_if_let)]\nuse proc_macros::{external, inline_macros};\n\nuse std::cmp::Ordering;\n\n#[derive(PartialEq)]\nenum Enum {\n    TupleVariant(i32, u64),\n    RecordVariant { a: i64, b: u32 },\n    UnitVariant,\n    Recursive(Struct),\n}\n\n#[derive(PartialEq)]\nstruct Struct {\n    a: i32,\n    b: bool,\n}\n\nstruct NoPartialEqStruct {\n    a: i32,\n    b: bool,\n}\n\nenum NotPartialEq {\n    A,\n    B,\n}\n\nenum NotStructuralEq {\n    A,\n    B,\n}\n\nimpl PartialEq for NotStructuralEq {\n    fn eq(&self, _: &NotStructuralEq) -> bool {\n        false\n    }\n}\n\nfn main() {\n    let a = 2;\n    let b = 3;\n    let c = Some(2);\n    let d = Struct { a: 2, b: false };\n    let e = Enum::UnitVariant;\n    let f = NotPartialEq::A;\n    let g = NotStructuralEq::A;\n    let h = NoPartialEqStruct { a: 2, b: false };\n\n    // true\n\n    if let 2 = a {}\n    //~^ equatable_if_let\n    if let Ordering::Greater = a.cmp(&b) {}\n    //~^ equatable_if_let\n    if let Some(2) = c {}\n    //~^ equatable_if_let\n    if let Struct { a: 2, b: false } = d {}\n    //~^ equatable_if_let\n    if let Enum::TupleVariant(32, 64) = e {}\n    //~^ equatable_if_let\n    if let Enum::RecordVariant { a: 64, b: 32 } = e {}\n    //~^ equatable_if_let\n    if let Enum::UnitVariant = e {}\n    //~^ equatable_if_let\n    if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {}\n    //~^ equatable_if_let\n\n    // false\n\n    if let 2 | 3 = a {}\n    if let x @ 2 = a {}\n    if let Some(3 | 4) = c {}\n    if let Struct { a, b: false } = d {}\n    if let Struct { a: 2, b: x } = d {}\n    if let NotPartialEq::A = f {}\n    //~^ equatable_if_let\n    if let NotStructuralEq::A = g {}\n    //~^ equatable_if_let\n    if let Some(NotPartialEq::A) = Some(f) {}\n    //~^ equatable_if_let\n    if let Some(NotStructuralEq::A) = Some(g) {}\n    //~^ equatable_if_let\n    if let NoPartialEqStruct { a: 2, b: false } = h {}\n    //~^ equatable_if_let\n}\n\nmod issue8710 {\n    fn str_ref(cs: &[char]) {\n        if let Some('i') = cs.iter().next() {\n            //~^ equatable_if_let\n        } else {\n            todo!();\n        }\n    }\n\n    fn i32_ref(cs: &[i32]) {\n        if let Some(1) = cs.iter().next() {\n            //~^ equatable_if_let\n        } else {\n            todo!();\n        }\n    }\n\n    fn enum_ref() {\n        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]\n        enum MyEnum {\n            A(i32),\n            B,\n        }\n\n        fn get_enum() -> Option<&'static MyEnum> {\n            todo!()\n        }\n\n        if let Some(MyEnum::B) = get_enum() {\n            //~^ equatable_if_let\n        } else {\n            todo!();\n        }\n    }\n}\n\n#[inline_macros]\nfn issue14548() {\n    if let inline!(\"abc\") = \"abc\" {\n        println!(\"OK\");\n    }\n\n    let a = 2;\n    external!({ if let 2 = $a {} });\n\n    // Don't lint: `==`/`matches!` might be correct for a particular `$($font)|*`, but not in general\n    macro_rules! m1 {\n        ($($font:pat_param)|*) => {\n            if let $($font)|* = \"from_expansion\" {}\n        }\n    }\n    m1!(\"foo\");\n    m1!(\"Sans\" | \"Serif\" | \"Sans Mono\");\n    m1!(inline!(\"foo\"));\n\n    // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in\n    // general\n    macro_rules! m2 {\n        ($from_root_ctxt:pat) => {\n            if let $from_root_ctxt = \"from_expansion\" {}\n        };\n    }\n    m2!(\"foo\");\n    m2!(\"Sans\" | \"Serif\" | \"Sans Mono\");\n    m2!(inline!(\"foo\"));\n\n    // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in\n    // general\n    macro_rules! m3 {\n        ($from_root_ctxt:expr) => {\n            if let \"from_expansion\" = $from_root_ctxt {}\n        };\n    }\n    m3!(\"foo\");\n    m3!(\"foo\");\n    m3!(inline!(\"foo\"));\n\n    // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in\n    // general. Don't get confused by the scrutinee coming from macro invocation\n    macro_rules! m4 {\n        ($from_root_ctxt:pat) => {\n            if let $from_root_ctxt = inline!(\"from_expansion\") {}\n        };\n    }\n    m4!(\"foo\");\n    m4!(\"Sans\" | \"Serif\" | \"Sans Mono\");\n    m4!(inline!(\"foo\"));\n\n    // Don't lint: the suggestion might be correct for a particular `$from_root_ctxt`, but not in\n    // general. Don't get confused by the scrutinee coming from macro invocation\n    macro_rules! m5 {\n        ($from_root_ctxt:expr) => {\n            if let inline!(\"from_expansion\") = $from_root_ctxt {}\n        };\n    }\n    m5!(\"foo\");\n    m5!(\"foo\");\n    m5!(inline!(\"foo\"));\n\n    // Would be nice to lint: both sides are macro _invocations_, so the suggestion is correct in\n    // general\n    if let inline!(\"foo\") = inline!(\"bar\") {}\n}\n\n// PartialEq is not stable in consts yet\nfn issue15376() {\n    enum NonConstEq {\n        A,\n        B,\n    }\n    impl PartialEq for NonConstEq {\n        fn eq(&self, _other: &Self) -> bool {\n            true\n        }\n    }\n\n    const N: NonConstEq = NonConstEq::A;\n\n    // `impl PartialEq` is not const, suggest `matches!`\n    const _: u32 = if let NonConstEq::A = N { 0 } else { 1 };\n    //~^ ERROR: this pattern matching can be expressed using `matches!`\n    const _: u32 = if let Some(NonConstEq::A) = Some(N) { 0 } else { 1 };\n    //~^ ERROR: this pattern matching can be expressed using `matches!`\n}\n"
  },
  {
    "path": "tests/ui/equatable_if_let.stderr",
    "content": "error: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:55:8\n   |\nLL |     if let 2 = a {}\n   |        ^^^^^^^^^ help: try: `a == 2`\n   |\n   = note: `-D clippy::equatable-if-let` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::equatable_if_let)]`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:57:8\n   |\nLL |     if let Ordering::Greater = a.cmp(&b) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:59:8\n   |\nLL |     if let Some(2) = c {}\n   |        ^^^^^^^^^^^^^^^ help: try: `c == Some(2)`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:61:8\n   |\nLL |     if let Struct { a: 2, b: false } = d {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:63:8\n   |\nLL |     if let Enum::TupleVariant(32, 64) = e {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:65:8\n   |\nLL |     if let Enum::RecordVariant { a: 64, b: 32 } = e {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:67:8\n   |\nLL |     if let Enum::UnitVariant = e {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:69:8\n   |\nLL |     if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let.rs:79:8\n   |\nLL |     if let NotPartialEq::A = f {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:81:8\n   |\nLL |     if let NotStructuralEq::A = g {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let.rs:83:8\n   |\nLL |     if let Some(NotPartialEq::A) = Some(f) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))`\n\nerror: this pattern matching can be expressed using equality\n  --> tests/ui/equatable_if_let.rs:85:8\n   |\nLL |     if let Some(NotStructuralEq::A) = Some(g) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let.rs:87:8\n   |\nLL |     if let NoPartialEqStruct { a: 2, b: false } = h {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let.rs:93:12\n   |\nLL |         if let Some('i') = cs.iter().next() {\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(cs.iter().next(), Some('i'))`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let.rs:101:12\n   |\nLL |         if let Some(1) = cs.iter().next() {\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(cs.iter().next(), Some(1))`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let.rs:119:12\n   |\nLL |         if let Some(MyEnum::B) = get_enum() {\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(get_enum(), Some(MyEnum::B))`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let.rs:210:23\n   |\nLL |     const _: u32 = if let NonConstEq::A = N { 0 } else { 1 };\n   |                       ^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(N, NonConstEq::A)`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let.rs:212:23\n   |\nLL |     const _: u32 = if let Some(NonConstEq::A) = Some(N) { 0 } else { 1 };\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(N), Some(NonConstEq::A))`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/equatable_if_let_const_cmp.fixed",
    "content": "#![warn(clippy::equatable_if_let)]\n#![allow(clippy::eq_op)]\n#![feature(const_trait_impl, const_cmp)]\n\nfn issue15376() {\n    enum ConstEq {\n        A,\n        B,\n    }\n    impl const PartialEq for ConstEq {\n        fn eq(&self, _other: &Self) -> bool {\n            true\n        }\n    }\n\n    const C: ConstEq = ConstEq::A;\n\n    // `impl PartialEq` is const... but we still suggest `matches!` for now\n    // TODO: detect this and suggest `=`\n    const _: u32 = if matches!(C, ConstEq::A) { 0 } else { 1 };\n    //~^ ERROR: this pattern matching can be expressed using `matches!`\n    const _: u32 = if matches!(Some(C), Some(ConstEq::A)) { 0 } else { 1 };\n    //~^ ERROR: this pattern matching can be expressed using `matches!`\n}\n"
  },
  {
    "path": "tests/ui/equatable_if_let_const_cmp.rs",
    "content": "#![warn(clippy::equatable_if_let)]\n#![allow(clippy::eq_op)]\n#![feature(const_trait_impl, const_cmp)]\n\nfn issue15376() {\n    enum ConstEq {\n        A,\n        B,\n    }\n    impl const PartialEq for ConstEq {\n        fn eq(&self, _other: &Self) -> bool {\n            true\n        }\n    }\n\n    const C: ConstEq = ConstEq::A;\n\n    // `impl PartialEq` is const... but we still suggest `matches!` for now\n    // TODO: detect this and suggest `=`\n    const _: u32 = if let ConstEq::A = C { 0 } else { 1 };\n    //~^ ERROR: this pattern matching can be expressed using `matches!`\n    const _: u32 = if let Some(ConstEq::A) = Some(C) { 0 } else { 1 };\n    //~^ ERROR: this pattern matching can be expressed using `matches!`\n}\n"
  },
  {
    "path": "tests/ui/equatable_if_let_const_cmp.stderr",
    "content": "error: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let_const_cmp.rs:20:23\n   |\nLL |     const _: u32 = if let ConstEq::A = C { 0 } else { 1 };\n   |                       ^^^^^^^^^^^^^^^^^^ help: try: `matches!(C, ConstEq::A)`\n   |\n   = note: `-D clippy::equatable-if-let` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::equatable_if_let)]`\n\nerror: this pattern matching can be expressed using `matches!`\n  --> tests/ui/equatable_if_let_const_cmp.rs:22:23\n   |\nLL |     const _: u32 = if let Some(ConstEq::A) = Some(C) { 0 } else { 1 };\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(C), Some(ConstEq::A))`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/erasing_op.rs",
    "content": "struct Length(u8);\nstruct Meter;\n\nimpl core::ops::Mul<Meter> for u8 {\n    type Output = Length;\n    fn mul(self, _: Meter) -> Length {\n        Length(self)\n    }\n}\n\n#[derive(Clone, Default, PartialEq, Eq, Hash)]\nstruct Vec1 {\n    x: i32,\n}\n\nimpl core::ops::Mul<Vec1> for i32 {\n    type Output = Vec1;\n    fn mul(self, mut right: Vec1) -> Vec1 {\n        right.x *= self;\n        right\n    }\n}\n\nimpl core::ops::Mul<i32> for Vec1 {\n    type Output = Vec1;\n    fn mul(mut self, right: i32) -> Vec1 {\n        self.x *= right;\n        self\n    }\n}\n\n#[allow(clippy::no_effect)]\n#[warn(clippy::erasing_op)]\nfn test(x: u8) {\n    x * 0;\n    //~^ erasing_op\n\n    0 & x;\n    //~^ erasing_op\n\n    0 / x;\n    //~^ erasing_op\n\n    0 * Meter; // no error: Output type is different from the non-zero argument\n    0 * Vec1 { x: 5 };\n    //~^ erasing_op\n\n    Vec1 { x: 5 } * 0;\n    //~^ erasing_op\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/erasing_op.stderr",
    "content": "error: this operation will always return zero. This is likely not the intended outcome\n  --> tests/ui/erasing_op.rs:35:5\n   |\nLL |     x * 0;\n   |     ^^^^^\n   |\n   = note: `-D clippy::erasing-op` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::erasing_op)]`\n\nerror: this operation will always return zero. This is likely not the intended outcome\n  --> tests/ui/erasing_op.rs:38:5\n   |\nLL |     0 & x;\n   |     ^^^^^\n\nerror: this operation will always return zero. This is likely not the intended outcome\n  --> tests/ui/erasing_op.rs:41:5\n   |\nLL |     0 / x;\n   |     ^^^^^\n\nerror: this operation will always return zero. This is likely not the intended outcome\n  --> tests/ui/erasing_op.rs:45:5\n   |\nLL |     0 * Vec1 { x: 5 };\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: this operation will always return zero. This is likely not the intended outcome\n  --> tests/ui/erasing_op.rs:48:5\n   |\nLL |     Vec1 { x: 5 } * 0;\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/err_expect.fixed",
    "content": "#![allow(unused, clippy::unnecessary_literal_unwrap)]\n\nstruct MyTypeNonDebug;\n\n#[derive(Debug)]\nstruct MyTypeDebug;\n\nfn main() {\n    let test_debug: Result<MyTypeDebug, u32> = Ok(MyTypeDebug);\n    test_debug.expect_err(\"Testing debug type\");\n    //~^ err_expect\n\n    let test_non_debug: Result<MyTypeNonDebug, u32> = Ok(MyTypeNonDebug);\n    test_non_debug.err().expect(\"Testing non debug type\");\n}\n\n#[clippy::msrv = \"1.16\"]\nfn msrv_1_16() {\n    let x: Result<u32, &str> = Ok(16);\n    x.err().expect(\"16\");\n}\n\n#[clippy::msrv = \"1.17\"]\nfn msrv_1_17() {\n    let x: Result<u32, &str> = Ok(17);\n    x.expect_err(\"17\");\n    //~^ err_expect\n}\n"
  },
  {
    "path": "tests/ui/err_expect.rs",
    "content": "#![allow(unused, clippy::unnecessary_literal_unwrap)]\n\nstruct MyTypeNonDebug;\n\n#[derive(Debug)]\nstruct MyTypeDebug;\n\nfn main() {\n    let test_debug: Result<MyTypeDebug, u32> = Ok(MyTypeDebug);\n    test_debug.err().expect(\"Testing debug type\");\n    //~^ err_expect\n\n    let test_non_debug: Result<MyTypeNonDebug, u32> = Ok(MyTypeNonDebug);\n    test_non_debug.err().expect(\"Testing non debug type\");\n}\n\n#[clippy::msrv = \"1.16\"]\nfn msrv_1_16() {\n    let x: Result<u32, &str> = Ok(16);\n    x.err().expect(\"16\");\n}\n\n#[clippy::msrv = \"1.17\"]\nfn msrv_1_17() {\n    let x: Result<u32, &str> = Ok(17);\n    x.err().expect(\"17\");\n    //~^ err_expect\n}\n"
  },
  {
    "path": "tests/ui/err_expect.stderr",
    "content": "error: called `.err().expect()` on a `Result` value\n  --> tests/ui/err_expect.rs:10:16\n   |\nLL |     test_debug.err().expect(\"Testing debug type\");\n   |                ^^^^^^^^^^^^ help: try: `expect_err`\n   |\n   = note: `-D clippy::err-expect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::err_expect)]`\n\nerror: called `.err().expect()` on a `Result` value\n  --> tests/ui/err_expect.rs:26:7\n   |\nLL |     x.err().expect(\"17\");\n   |       ^^^^^^^^^^^^ help: try: `expect_err`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/error_impl_error.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::error_impl_error)]\n#![no_main]\n\npub mod a {\n    #[derive(Debug)]\n    pub struct Error;\n    //~^ error_impl_error\n\n    impl std::fmt::Display for Error {\n        fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            todo!()\n        }\n    }\n\n    impl std::error::Error for Error {}\n}\n\nmod b {\n    #[derive(Debug)]\n    pub(super) enum Error {}\n    //~^ error_impl_error\n\n    impl std::fmt::Display for Error {\n        fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            todo!()\n        }\n    }\n\n    impl std::error::Error for Error {}\n}\n\npub mod c {\n    pub union Error {\n        //~^ error_impl_error\n        a: u32,\n        b: u32,\n    }\n\n    impl std::fmt::Debug for Error {\n        fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            todo!()\n        }\n    }\n\n    impl std::fmt::Display for Error {\n        fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            todo!()\n        }\n    }\n\n    impl std::error::Error for Error {}\n}\n\npub mod d {\n    pub type Error = std::fmt::Error;\n    //~^ error_impl_error\n}\n\nmod e {\n    #[derive(Debug)]\n    pub(super) struct MyError;\n\n    impl std::fmt::Display for MyError {\n        fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            todo!()\n        }\n    }\n\n    impl std::error::Error for MyError {}\n}\n\npub mod f {\n    pub type MyError = std::fmt::Error;\n}\n\n// Do not lint module-private types\n\nmod g {\n    #[derive(Debug)]\n    enum Error {}\n\n    impl std::fmt::Display for Error {\n        fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            todo!()\n        }\n    }\n\n    impl std::error::Error for Error {}\n}\n\nmod h {\n    type Error = std::fmt::Error;\n}\n"
  },
  {
    "path": "tests/ui/error_impl_error.stderr",
    "content": "error: exported type named `Error` that implements `Error`\n  --> tests/ui/error_impl_error.rs:7:16\n   |\nLL |     pub struct Error;\n   |                ^^^^^\n   |\nnote: `Error` was implemented here\n  --> tests/ui/error_impl_error.rs:16:5\n   |\nLL |     impl std::error::Error for Error {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::error-impl-error` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::error_impl_error)]`\n\nerror: exported type named `Error` that implements `Error`\n  --> tests/ui/error_impl_error.rs:21:21\n   |\nLL |     pub(super) enum Error {}\n   |                     ^^^^^\n   |\nnote: `Error` was implemented here\n  --> tests/ui/error_impl_error.rs:30:5\n   |\nLL |     impl std::error::Error for Error {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: exported type named `Error` that implements `Error`\n  --> tests/ui/error_impl_error.rs:34:15\n   |\nLL |     pub union Error {\n   |               ^^^^^\n   |\nnote: `Error` was implemented here\n  --> tests/ui/error_impl_error.rs:52:5\n   |\nLL |     impl std::error::Error for Error {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: exported type alias named `Error` that implements `Error`\n  --> tests/ui/error_impl_error.rs:56:14\n   |\nLL |     pub type Error = std::fmt::Error;\n   |              ^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/eta.fixed",
    "content": "// we have some HELP annotations -- don't complain about them not being present everywhere\n//@require-annotations-for-level: ERROR\n\n#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]\n#![allow(unused)]\n#![allow(\n    clippy::needless_borrow,\n    clippy::needless_option_as_deref,\n    clippy::needless_pass_by_value,\n    clippy::no_effect,\n    clippy::option_map_unit_fn,\n    clippy::redundant_closure_call,\n    clippy::uninlined_format_args,\n    clippy::useless_vec,\n    clippy::unnecessary_map_on_constructor,\n    clippy::needless_lifetimes,\n    clippy::unnecessary_option_map_or_else\n)]\n\nuse std::path::{Path, PathBuf};\n\nmacro_rules! mac {\n    () => {\n        foobar()\n    };\n}\n\nmacro_rules! closure_mac {\n    () => {\n        |n| foo(n)\n    };\n}\n\nfn main() {\n    let a = Some(1u8).map(foo);\n    //~^ redundant_closure\n    let c = Some(1u8).map(|a| {1+2; foo}(a));\n    true.then(|| mac!()); // don't lint function in macro expansion\n    Some(1).map(closure_mac!()); // don't lint closure in macro expansion\n    let _: Option<Vec<u8>> = true.then(std::vec::Vec::new); // special case vec!\n    //\n    //~^^ redundant_closure\n    let d = Some(1u8).map(|a| foo(foo2(a))); //is adjusted?\n    //\n    //~^^ redundant_closure\n    all(&[1, 2, 3], &&2, below); //is adjusted\n    //\n    //~^^ redundant_closure\n    unsafe {\n        Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn\n    }\n\n    // See #815\n    let e = Some(1u8).map(|a| divergent(a));\n    let e = Some(1u8).map(generic);\n    //~^ redundant_closure\n    let e = Some(1u8).map(generic);\n    // See #515\n    let a: Option<Box<dyn (::std::ops::Deref<Target = [i32]>)>> =\n        Some(vec![1i32, 2]).map(|v| -> Box<dyn (::std::ops::Deref<Target = [i32]>)> { Box::new(v) });\n\n    // issue #7224\n    let _: Option<Vec<u32>> = Some(0).map(|_| vec![]);\n\n    // issue #10684\n    fn test<T>(x: impl Fn(usize, usize) -> T) -> T {\n        x(1, 2)\n    }\n    test(|start, end| start..=end);\n}\n\ntrait TestTrait {\n    fn trait_foo(self) -> bool;\n    fn trait_foo_ref(&self) -> bool;\n}\n\nstruct TestStruct<'a> {\n    some_ref: &'a i32,\n}\n\nimpl<'a> TestStruct<'a> {\n    fn foo(self) -> bool {\n        false\n    }\n    unsafe fn foo_unsafe(self) -> bool {\n        true\n    }\n}\n\nimpl<'a> TestTrait for TestStruct<'a> {\n    fn trait_foo(self) -> bool {\n        false\n    }\n    fn trait_foo_ref(&self) -> bool {\n        false\n    }\n}\n\nimpl<'a> std::ops::Deref for TestStruct<'a> {\n    type Target = char;\n    fn deref(&self) -> &char {\n        &'a'\n    }\n}\n\nfn test_redundant_closures_containing_method_calls() {\n    let i = 10;\n    let e = Some(TestStruct { some_ref: &i }).map(TestStruct::foo);\n    //~^ redundant_closure_for_method_calls\n    let e = Some(TestStruct { some_ref: &i }).map(TestTrait::trait_foo);\n    //~^ redundant_closure_for_method_calls\n    let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo_ref());\n    let e = Some(&mut vec![1, 2, 3]).map(std::vec::Vec::clear);\n    //~^ redundant_closure_for_method_calls\n    unsafe {\n        let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo_unsafe());\n    }\n    let e = Some(\"str\").map(std::string::ToString::to_string);\n    //~^ redundant_closure_for_method_calls\n    let e = Some('a').map(char::to_uppercase);\n    //~^ redundant_closure_for_method_calls\n    let e: std::vec::Vec<usize> = vec!['a', 'b', 'c'].iter().map(|c| c.len_utf8()).collect();\n    let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(char::to_ascii_uppercase).collect();\n    //~^ redundant_closure_for_method_calls\n    let e = Some(PathBuf::new()).as_ref().and_then(|s| s.to_str());\n    let c = Some(TestStruct { some_ref: &i })\n        .as_ref()\n        .map(|c| c.to_ascii_uppercase());\n\n    fn test_different_borrow_levels<T>(t: &[&T])\n    where\n        T: TestTrait,\n    {\n        t.iter().filter(|x| x.trait_foo_ref());\n        t.iter().map(|x| x.trait_foo_ref());\n    }\n\n    fn issue14096() {\n        let x = Some(\"42\");\n        let _ = x.map(str::parse::<i16>);\n        //~^ redundant_closure_for_method_calls\n    }\n}\n\nstruct Thunk<T>(Box<dyn FnMut() -> T>);\n\nimpl<T> Thunk<T> {\n    fn new<F: 'static + FnOnce() -> T>(f: F) -> Thunk<T> {\n        let mut option = Some(f);\n        // This should not trigger redundant_closure (#1439)\n        Thunk(Box::new(move || option.take().unwrap()()))\n    }\n\n    fn unwrap(self) -> T {\n        let Thunk(mut f) = self;\n        f()\n    }\n}\n\nfn foobar() {\n    let thunk = Thunk::new(|| println!(\"Hello, world!\"));\n    thunk.unwrap()\n}\n\nfn foo(_: u8) {}\n\nfn foo2(_: u8) -> u8 {\n    1u8\n}\n\nfn all<X, F>(x: &[X], y: &X, f: F) -> bool\nwhere\n    F: Fn(&X, &X) -> bool,\n{\n    x.iter().all(|e| f(e, y))\n}\n\nfn below(x: &u8, y: &u8) -> bool {\n    x < y\n}\n\nunsafe fn unsafe_fn(_: u8) {}\n\nfn divergent(_: u8) -> ! {\n    unimplemented!()\n}\n\nfn generic<T>(_: T) -> u8 {\n    0\n}\n\nfn passes_fn_mut(mut x: Box<dyn FnMut()>) {\n    requires_fn_once(x);\n    //~^ redundant_closure\n}\nfn requires_fn_once<T: FnOnce()>(_: T) {}\n\nfn test_redundant_closure_with_function_pointer() {\n    type FnPtrType = fn(u8);\n    let foo_ptr: FnPtrType = foo;\n    let a = Some(1u8).map(foo_ptr);\n    //~^ redundant_closure\n}\n\nfn test_redundant_closure_with_another_closure() {\n    let closure = |a| println!(\"{}\", a);\n    let a = Some(1u8).map(closure);\n    //~^ redundant_closure\n}\n\nfn make_lazy(f: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 {\n    // Currently f is called when result of make_lazy is called.\n    // If the closure is removed, f will be called when make_lazy itself is\n    // called. This changes semantics, so the closure must stay.\n    Box::new(move |x| f()(x))\n}\n\nfn call<F: FnOnce(&mut String) -> String>(f: F) -> String {\n    f(&mut \"Hello\".to_owned())\n}\nfn test_difference_in_mutability() {\n    call(|s| s.clone());\n}\n\nstruct Bar;\nimpl std::ops::Deref for Bar {\n    type Target = str;\n    fn deref(&self) -> &str {\n        \"hi\"\n    }\n}\n\nfn test_deref_with_trait_method() {\n    let _ = [Bar].iter().map(|s| s.to_string()).collect::<Vec<_>>();\n}\n\nfn mutable_closure_used_again(x: Vec<i32>, y: Vec<i32>, z: Vec<i32>) {\n    let mut res = Vec::new();\n    let mut add_to_res = |n| res.push(n);\n    x.into_iter().for_each(&mut add_to_res);\n    //~^ redundant_closure\n    y.into_iter().for_each(&mut add_to_res);\n    //~^ redundant_closure\n    z.into_iter().for_each(add_to_res);\n    //~^ redundant_closure\n}\n\nfn mutable_closure_in_loop() {\n    let mut value = 0;\n    let mut closure = |n| value += n;\n    for _ in 0..5 {\n        Some(1).map(&mut closure);\n        //~^ redundant_closure\n\n        let mut value = 0;\n        let mut in_loop = |n| value += n;\n        Some(1).map(in_loop);\n        //~^ redundant_closure\n    }\n}\n\nfn late_bound_lifetimes() {\n    fn take_asref_path<P: AsRef<Path>>(path: P) {}\n\n    fn map_str<F>(thunk: F)\n    where\n        F: FnOnce(&str),\n    {\n    }\n\n    fn map_str_to_path<F>(thunk: F)\n    where\n        F: FnOnce(&str) -> &Path,\n    {\n    }\n    map_str(|s| take_asref_path(s));\n    map_str_to_path(|s| s.as_ref());\n}\n\nmod type_param_bound {\n    trait Trait {\n        fn fun();\n    }\n\n    fn take<T: 'static>(_: T) {}\n\n    fn test<X: Trait>() {\n        // don't lint, but it's questionable that rust requires a cast\n        take(|| X::fun());\n        take(X::fun as fn());\n    }\n}\n\n// #8073 Don't replace closure with `Arc<F>` or `Rc<F>`\nfn arc_fp() {\n    let rc = std::rc::Rc::new(|| 7);\n    let arc = std::sync::Arc::new(|n| n + 1);\n    let ref_arc = &std::sync::Arc::new(|_| 5);\n\n    true.then(|| rc());\n    (0..5).map(|n| arc(n));\n    Some(4).map(|n| ref_arc(n));\n}\n\n// #8460 Don't replace closures with params bounded as `ref`\nmod bind_by_ref {\n    struct A;\n    struct B;\n\n    impl From<&A> for B {\n        fn from(A: &A) -> Self {\n            B\n        }\n    }\n\n    fn test() {\n        // should not lint\n        Some(A).map(|a| B::from(&a));\n        // should not lint\n        Some(A).map(|ref a| B::from(a));\n    }\n}\n\n// #7812 False positive on coerced closure\nfn coerced_closure() {\n    fn function_returning_unit<F: FnMut(i32)>(f: F) {}\n    function_returning_unit(|x| std::process::exit(x));\n\n    fn arr() -> &'static [u8; 0] {\n        &[]\n    }\n    fn slice_fn(_: impl FnOnce() -> &'static [u8]) {}\n    slice_fn(|| arr());\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7861\nfn box_dyn() {\n    fn f(_: impl Fn(usize) -> Box<dyn std::any::Any>) {}\n    f(|x| Box::new(x));\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/5939\nfn not_general_enough() {\n    fn f(_: impl FnMut(&Path) -> std::io::Result<()>) {}\n    f(|path| std::fs::remove_file(path));\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/9369\npub fn mutable_impl_fn_mut(mut f: impl FnMut(), mut f_used_once: impl FnMut()) -> impl FnMut() {\n    fn takes_fn_mut(_: impl FnMut()) {}\n    takes_fn_mut(&mut f);\n    //~^ redundant_closure\n\n    fn takes_fn_once(_: impl FnOnce()) {}\n    takes_fn_once(&mut f);\n    //~^ redundant_closure\n\n    f();\n\n    move || takes_fn_mut(&mut f_used_once)\n    //~^ redundant_closure\n}\n\nimpl dyn TestTrait + '_ {\n    fn method_on_dyn(&self) -> bool {\n        false\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7746\nfn angle_brackets_and_args() {\n    let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]);\n    array_opt.map(<[u8; 3]>::as_slice);\n    //~^ redundant_closure_for_method_calls\n\n    let slice_opt: Option<&[u8]> = Some(b\"slice\");\n    slice_opt.map(<[u8]>::len);\n    //~^ redundant_closure_for_method_calls\n\n    let ptr_opt: Option<*const usize> = Some(&487);\n    ptr_opt.map(<*const usize>::is_null);\n    //~^ redundant_closure_for_method_calls\n\n    let test_struct = TestStruct { some_ref: &487 };\n    let dyn_opt: Option<&dyn TestTrait> = Some(&test_struct);\n    dyn_opt.map(<dyn TestTrait>::method_on_dyn);\n    //~^ redundant_closure_for_method_calls\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/12199\nfn track_caller_fp() {\n    struct S;\n    impl S {\n        #[track_caller]\n        fn add_location(self) {}\n    }\n\n    #[track_caller]\n    fn add_location() {}\n\n    fn foo(_: fn()) {}\n    fn foo2(_: fn(S)) {}\n    foo(|| add_location());\n    foo2(|s| s.add_location());\n}\n\nfn _late_bound_to_early_bound_regions() {\n    struct Foo<'a>(&'a u32);\n    impl<'a> Foo<'a> {\n        fn f(x: &'a u32) -> Self {\n            Foo(x)\n        }\n    }\n    fn f(f: impl for<'a> Fn(&'a u32) -> Foo<'a>) -> Foo<'static> {\n        f(&0)\n    }\n\n    let _ = f(|x| Foo::f(x));\n\n    struct Bar;\n    impl<'a> From<&'a u32> for Bar {\n        fn from(x: &'a u32) -> Bar {\n            Bar\n        }\n    }\n    fn f2(f: impl for<'a> Fn(&'a u32) -> Bar) -> Bar {\n        f(&0)\n    }\n\n    let _ = f2(|x| <Bar>::from(x));\n\n    struct Baz<'a>(&'a u32);\n    fn f3(f: impl Fn(&u32) -> Baz<'_>) -> Baz<'static> {\n        f(&0)\n    }\n\n    let _ = f3(|x| Baz(x));\n}\n\nfn _mixed_late_bound_and_early_bound_regions() {\n    fn f<T>(t: T, f: impl Fn(T, &u32) -> u32) -> u32 {\n        f(t, &0)\n    }\n    fn f2<'a, T: 'a>(_: &'a T, y: &u32) -> u32 {\n        *y\n    }\n    let _ = f(&0, f2);\n    //~^ redundant_closure\n}\n\nfn _closure_with_types() {\n    fn f<T>(x: T) -> T {\n        x\n    }\n    fn f2<T: Default>(f: impl Fn(T) -> T) -> T {\n        f(T::default())\n    }\n\n    let _ = f2(|x: u32| f(x));\n    let _ = f2(|x| -> u32 { f(x) });\n}\n\n/// https://github.com/rust-lang/rust-clippy/issues/10854\n/// This is to verify that redundant_closure_for_method_calls resolves suggested paths to relative.\nmod issue_10854 {\n    pub mod test_mod {\n        pub struct Test;\n\n        impl Test {\n            pub fn method(self) -> i32 {\n                0\n            }\n        }\n\n        pub fn calls_test(test: Option<Test>) -> Option<i32> {\n            test.map(Test::method)\n            //~^ redundant_closure_for_method_calls\n        }\n\n        pub fn calls_outer(test: Option<super::Outer>) -> Option<i32> {\n            test.map(super::Outer::method)\n            //~^ redundant_closure_for_method_calls\n        }\n    }\n\n    pub struct Outer;\n\n    impl Outer {\n        pub fn method(self) -> i32 {\n            0\n        }\n    }\n\n    pub fn calls_into_mod(test: Option<test_mod::Test>) -> Option<i32> {\n        test.map(test_mod::Test::method)\n        //~^ redundant_closure_for_method_calls\n    }\n\n    mod a {\n        pub mod b {\n            pub mod c {\n                pub fn extreme_nesting(test: Option<super::super::super::d::Test>) -> Option<i32> {\n                    test.map(crate::issue_10854::d::Test::method)\n                    //~^ redundant_closure_for_method_calls\n                }\n            }\n        }\n    }\n\n    mod d {\n        pub struct Test;\n\n        impl Test {\n            pub fn method(self) -> i32 {\n                0\n            }\n        }\n    }\n}\n\nmod issue_12853 {\n    fn f_by_value<F: Fn(u32)>(f: F) {\n        let x = Box::new(|| None.map(&f));\n        //~^ redundant_closure\n        x();\n    }\n    fn f_by_ref<F: Fn(u32)>(f: &F) {\n        let x = Box::new(|| None.map(f));\n        //~^ redundant_closure\n        x();\n    }\n}\n\nmod issue_13073 {\n    fn get_default() -> Option<&'static str> {\n        Some(\"foo\")\n    }\n\n    pub fn foo() {\n        // shouldn't lint\n        let bind: Option<String> = None;\n        let _field = bind.as_deref().or_else(|| get_default()).unwrap();\n        let bind: Option<&'static str> = None;\n        let _field = bind.as_deref().or_else(|| get_default()).unwrap();\n        // should lint\n        let _field = bind.or_else(get_default).unwrap();\n        //~^ redundant_closure\n    }\n}\n\nfn issue_14789() {\n    _ = Some(1u8).map(\n        #[expect(clippy::redundant_closure)]\n        |a| foo(a),\n    );\n\n    _ = Some(\"foo\").map(\n        #[expect(clippy::redundant_closure_for_method_calls)]\n        |s| s.to_owned(),\n    );\n\n    let _: Vec<u8> = None.map_or_else(\n        #[expect(clippy::redundant_closure)]\n        || vec![],\n        std::convert::identity,\n    );\n}\n\nfn issue_15072() {\n    use std::ops::Deref;\n\n    struct Foo;\n    impl Deref for Foo {\n        type Target = fn() -> &'static str;\n\n        fn deref(&self) -> &Self::Target {\n            fn hello() -> &'static str {\n                \"Hello, world!\"\n            }\n            &(hello as fn() -> &'static str)\n        }\n    }\n\n    fn accepts_fn(f: impl Fn() -> &'static str) {\n        println!(\"{}\", f());\n    }\n\n    fn some_fn() -> &'static str {\n        todo!()\n    }\n\n    let f = &Foo;\n    accepts_fn(**f);\n    //~^ redundant_closure\n\n    let g = &some_fn;\n    accepts_fn(g);\n    //~^ redundant_closure\n\n    struct Bar(Foo);\n    impl Deref for Bar {\n        type Target = Foo;\n\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n\n    let b = &Bar(Foo);\n    accepts_fn(***b);\n    //~^ redundant_closure\n}\n\nfn issue8817() {\n    fn f(_: u32) -> u32 {\n        todo!()\n    }\n    let g = |_: u32| -> u32 { todo!() };\n    struct S(u32);\n    enum MyError {\n        A(S),\n    }\n\n    Some(5)\n        .map(f)\n        //~^ redundant_closure\n        //~| HELP: replace the closure with the function itself\n        .map(g)\n        //~^ redundant_closure\n        //~| HELP: replace the closure with the function itself\n        .map(S)\n        //~^ redundant_closure\n        //~| HELP: replace the closure with the tuple struct itself\n        .map(MyError::A)\n        //~^ redundant_closure\n        //~| HELP: replace the closure with the tuple variant itself\n        .unwrap(); // just for nicer formatting\n}\n\nasync fn issue13892<'a, T, F>(maybe: Option<&'a T>, visitor: F)\nwhere\n    F: AsyncFn(&'a T),\n    T: 'a,\n{\n    maybe.map(|x| visitor(x));\n}\n\ntrait Issue16360: Sized {\n    fn method(&self);\n\n    fn ice_machine(array: [Self; 1]) {\n        array.iter().for_each(Self::method);\n        //~^ redundant_closure_for_method_calls\n    }\n}\n\nfn issue16641() {\n    use std::cell::LazyCell;\n\n    let closure = LazyCell::new(|| |x: usize| println!(\"{x}\"));\n\n    (0..10).flat_map(|x| (0..10).map(&*closure)).count();\n    //~^ redundant_closure\n}\n"
  },
  {
    "path": "tests/ui/eta.rs",
    "content": "// we have some HELP annotations -- don't complain about them not being present everywhere\n//@require-annotations-for-level: ERROR\n\n#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]\n#![allow(unused)]\n#![allow(\n    clippy::needless_borrow,\n    clippy::needless_option_as_deref,\n    clippy::needless_pass_by_value,\n    clippy::no_effect,\n    clippy::option_map_unit_fn,\n    clippy::redundant_closure_call,\n    clippy::uninlined_format_args,\n    clippy::useless_vec,\n    clippy::unnecessary_map_on_constructor,\n    clippy::needless_lifetimes,\n    clippy::unnecessary_option_map_or_else\n)]\n\nuse std::path::{Path, PathBuf};\n\nmacro_rules! mac {\n    () => {\n        foobar()\n    };\n}\n\nmacro_rules! closure_mac {\n    () => {\n        |n| foo(n)\n    };\n}\n\nfn main() {\n    let a = Some(1u8).map(|a| foo(a));\n    //~^ redundant_closure\n    let c = Some(1u8).map(|a| {1+2; foo}(a));\n    true.then(|| mac!()); // don't lint function in macro expansion\n    Some(1).map(closure_mac!()); // don't lint closure in macro expansion\n    let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!\n    //\n    //~^^ redundant_closure\n    let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?\n    //\n    //~^^ redundant_closure\n    all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted\n    //\n    //~^^ redundant_closure\n    unsafe {\n        Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn\n    }\n\n    // See #815\n    let e = Some(1u8).map(|a| divergent(a));\n    let e = Some(1u8).map(|a| generic(a));\n    //~^ redundant_closure\n    let e = Some(1u8).map(generic);\n    // See #515\n    let a: Option<Box<dyn (::std::ops::Deref<Target = [i32]>)>> =\n        Some(vec![1i32, 2]).map(|v| -> Box<dyn (::std::ops::Deref<Target = [i32]>)> { Box::new(v) });\n\n    // issue #7224\n    let _: Option<Vec<u32>> = Some(0).map(|_| vec![]);\n\n    // issue #10684\n    fn test<T>(x: impl Fn(usize, usize) -> T) -> T {\n        x(1, 2)\n    }\n    test(|start, end| start..=end);\n}\n\ntrait TestTrait {\n    fn trait_foo(self) -> bool;\n    fn trait_foo_ref(&self) -> bool;\n}\n\nstruct TestStruct<'a> {\n    some_ref: &'a i32,\n}\n\nimpl<'a> TestStruct<'a> {\n    fn foo(self) -> bool {\n        false\n    }\n    unsafe fn foo_unsafe(self) -> bool {\n        true\n    }\n}\n\nimpl<'a> TestTrait for TestStruct<'a> {\n    fn trait_foo(self) -> bool {\n        false\n    }\n    fn trait_foo_ref(&self) -> bool {\n        false\n    }\n}\n\nimpl<'a> std::ops::Deref for TestStruct<'a> {\n    type Target = char;\n    fn deref(&self) -> &char {\n        &'a'\n    }\n}\n\nfn test_redundant_closures_containing_method_calls() {\n    let i = 10;\n    let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());\n    //~^ redundant_closure_for_method_calls\n    let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());\n    //~^ redundant_closure_for_method_calls\n    let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo_ref());\n    let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());\n    //~^ redundant_closure_for_method_calls\n    unsafe {\n        let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo_unsafe());\n    }\n    let e = Some(\"str\").map(|s| s.to_string());\n    //~^ redundant_closure_for_method_calls\n    let e = Some('a').map(|s| s.to_uppercase());\n    //~^ redundant_closure_for_method_calls\n    let e: std::vec::Vec<usize> = vec!['a', 'b', 'c'].iter().map(|c| c.len_utf8()).collect();\n    let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();\n    //~^ redundant_closure_for_method_calls\n    let e = Some(PathBuf::new()).as_ref().and_then(|s| s.to_str());\n    let c = Some(TestStruct { some_ref: &i })\n        .as_ref()\n        .map(|c| c.to_ascii_uppercase());\n\n    fn test_different_borrow_levels<T>(t: &[&T])\n    where\n        T: TestTrait,\n    {\n        t.iter().filter(|x| x.trait_foo_ref());\n        t.iter().map(|x| x.trait_foo_ref());\n    }\n\n    fn issue14096() {\n        let x = Some(\"42\");\n        let _ = x.map(|x| x.parse::<i16>());\n        //~^ redundant_closure_for_method_calls\n    }\n}\n\nstruct Thunk<T>(Box<dyn FnMut() -> T>);\n\nimpl<T> Thunk<T> {\n    fn new<F: 'static + FnOnce() -> T>(f: F) -> Thunk<T> {\n        let mut option = Some(f);\n        // This should not trigger redundant_closure (#1439)\n        Thunk(Box::new(move || option.take().unwrap()()))\n    }\n\n    fn unwrap(self) -> T {\n        let Thunk(mut f) = self;\n        f()\n    }\n}\n\nfn foobar() {\n    let thunk = Thunk::new(|| println!(\"Hello, world!\"));\n    thunk.unwrap()\n}\n\nfn foo(_: u8) {}\n\nfn foo2(_: u8) -> u8 {\n    1u8\n}\n\nfn all<X, F>(x: &[X], y: &X, f: F) -> bool\nwhere\n    F: Fn(&X, &X) -> bool,\n{\n    x.iter().all(|e| f(e, y))\n}\n\nfn below(x: &u8, y: &u8) -> bool {\n    x < y\n}\n\nunsafe fn unsafe_fn(_: u8) {}\n\nfn divergent(_: u8) -> ! {\n    unimplemented!()\n}\n\nfn generic<T>(_: T) -> u8 {\n    0\n}\n\nfn passes_fn_mut(mut x: Box<dyn FnMut()>) {\n    requires_fn_once(|| x());\n    //~^ redundant_closure\n}\nfn requires_fn_once<T: FnOnce()>(_: T) {}\n\nfn test_redundant_closure_with_function_pointer() {\n    type FnPtrType = fn(u8);\n    let foo_ptr: FnPtrType = foo;\n    let a = Some(1u8).map(|a| foo_ptr(a));\n    //~^ redundant_closure\n}\n\nfn test_redundant_closure_with_another_closure() {\n    let closure = |a| println!(\"{}\", a);\n    let a = Some(1u8).map(|a| closure(a));\n    //~^ redundant_closure\n}\n\nfn make_lazy(f: impl Fn() -> fn(u8) -> u8) -> impl Fn(u8) -> u8 {\n    // Currently f is called when result of make_lazy is called.\n    // If the closure is removed, f will be called when make_lazy itself is\n    // called. This changes semantics, so the closure must stay.\n    Box::new(move |x| f()(x))\n}\n\nfn call<F: FnOnce(&mut String) -> String>(f: F) -> String {\n    f(&mut \"Hello\".to_owned())\n}\nfn test_difference_in_mutability() {\n    call(|s| s.clone());\n}\n\nstruct Bar;\nimpl std::ops::Deref for Bar {\n    type Target = str;\n    fn deref(&self) -> &str {\n        \"hi\"\n    }\n}\n\nfn test_deref_with_trait_method() {\n    let _ = [Bar].iter().map(|s| s.to_string()).collect::<Vec<_>>();\n}\n\nfn mutable_closure_used_again(x: Vec<i32>, y: Vec<i32>, z: Vec<i32>) {\n    let mut res = Vec::new();\n    let mut add_to_res = |n| res.push(n);\n    x.into_iter().for_each(|x| add_to_res(x));\n    //~^ redundant_closure\n    y.into_iter().for_each(|x| add_to_res(x));\n    //~^ redundant_closure\n    z.into_iter().for_each(|x| add_to_res(x));\n    //~^ redundant_closure\n}\n\nfn mutable_closure_in_loop() {\n    let mut value = 0;\n    let mut closure = |n| value += n;\n    for _ in 0..5 {\n        Some(1).map(|n| closure(n));\n        //~^ redundant_closure\n\n        let mut value = 0;\n        let mut in_loop = |n| value += n;\n        Some(1).map(|n| in_loop(n));\n        //~^ redundant_closure\n    }\n}\n\nfn late_bound_lifetimes() {\n    fn take_asref_path<P: AsRef<Path>>(path: P) {}\n\n    fn map_str<F>(thunk: F)\n    where\n        F: FnOnce(&str),\n    {\n    }\n\n    fn map_str_to_path<F>(thunk: F)\n    where\n        F: FnOnce(&str) -> &Path,\n    {\n    }\n    map_str(|s| take_asref_path(s));\n    map_str_to_path(|s| s.as_ref());\n}\n\nmod type_param_bound {\n    trait Trait {\n        fn fun();\n    }\n\n    fn take<T: 'static>(_: T) {}\n\n    fn test<X: Trait>() {\n        // don't lint, but it's questionable that rust requires a cast\n        take(|| X::fun());\n        take(X::fun as fn());\n    }\n}\n\n// #8073 Don't replace closure with `Arc<F>` or `Rc<F>`\nfn arc_fp() {\n    let rc = std::rc::Rc::new(|| 7);\n    let arc = std::sync::Arc::new(|n| n + 1);\n    let ref_arc = &std::sync::Arc::new(|_| 5);\n\n    true.then(|| rc());\n    (0..5).map(|n| arc(n));\n    Some(4).map(|n| ref_arc(n));\n}\n\n// #8460 Don't replace closures with params bounded as `ref`\nmod bind_by_ref {\n    struct A;\n    struct B;\n\n    impl From<&A> for B {\n        fn from(A: &A) -> Self {\n            B\n        }\n    }\n\n    fn test() {\n        // should not lint\n        Some(A).map(|a| B::from(&a));\n        // should not lint\n        Some(A).map(|ref a| B::from(a));\n    }\n}\n\n// #7812 False positive on coerced closure\nfn coerced_closure() {\n    fn function_returning_unit<F: FnMut(i32)>(f: F) {}\n    function_returning_unit(|x| std::process::exit(x));\n\n    fn arr() -> &'static [u8; 0] {\n        &[]\n    }\n    fn slice_fn(_: impl FnOnce() -> &'static [u8]) {}\n    slice_fn(|| arr());\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7861\nfn box_dyn() {\n    fn f(_: impl Fn(usize) -> Box<dyn std::any::Any>) {}\n    f(|x| Box::new(x));\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/5939\nfn not_general_enough() {\n    fn f(_: impl FnMut(&Path) -> std::io::Result<()>) {}\n    f(|path| std::fs::remove_file(path));\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/9369\npub fn mutable_impl_fn_mut(mut f: impl FnMut(), mut f_used_once: impl FnMut()) -> impl FnMut() {\n    fn takes_fn_mut(_: impl FnMut()) {}\n    takes_fn_mut(|| f());\n    //~^ redundant_closure\n\n    fn takes_fn_once(_: impl FnOnce()) {}\n    takes_fn_once(|| f());\n    //~^ redundant_closure\n\n    f();\n\n    move || takes_fn_mut(|| f_used_once())\n    //~^ redundant_closure\n}\n\nimpl dyn TestTrait + '_ {\n    fn method_on_dyn(&self) -> bool {\n        false\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7746\nfn angle_brackets_and_args() {\n    let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]);\n    array_opt.map(|a| a.as_slice());\n    //~^ redundant_closure_for_method_calls\n\n    let slice_opt: Option<&[u8]> = Some(b\"slice\");\n    slice_opt.map(|s| s.len());\n    //~^ redundant_closure_for_method_calls\n\n    let ptr_opt: Option<*const usize> = Some(&487);\n    ptr_opt.map(|p| p.is_null());\n    //~^ redundant_closure_for_method_calls\n\n    let test_struct = TestStruct { some_ref: &487 };\n    let dyn_opt: Option<&dyn TestTrait> = Some(&test_struct);\n    dyn_opt.map(|d| d.method_on_dyn());\n    //~^ redundant_closure_for_method_calls\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/12199\nfn track_caller_fp() {\n    struct S;\n    impl S {\n        #[track_caller]\n        fn add_location(self) {}\n    }\n\n    #[track_caller]\n    fn add_location() {}\n\n    fn foo(_: fn()) {}\n    fn foo2(_: fn(S)) {}\n    foo(|| add_location());\n    foo2(|s| s.add_location());\n}\n\nfn _late_bound_to_early_bound_regions() {\n    struct Foo<'a>(&'a u32);\n    impl<'a> Foo<'a> {\n        fn f(x: &'a u32) -> Self {\n            Foo(x)\n        }\n    }\n    fn f(f: impl for<'a> Fn(&'a u32) -> Foo<'a>) -> Foo<'static> {\n        f(&0)\n    }\n\n    let _ = f(|x| Foo::f(x));\n\n    struct Bar;\n    impl<'a> From<&'a u32> for Bar {\n        fn from(x: &'a u32) -> Bar {\n            Bar\n        }\n    }\n    fn f2(f: impl for<'a> Fn(&'a u32) -> Bar) -> Bar {\n        f(&0)\n    }\n\n    let _ = f2(|x| <Bar>::from(x));\n\n    struct Baz<'a>(&'a u32);\n    fn f3(f: impl Fn(&u32) -> Baz<'_>) -> Baz<'static> {\n        f(&0)\n    }\n\n    let _ = f3(|x| Baz(x));\n}\n\nfn _mixed_late_bound_and_early_bound_regions() {\n    fn f<T>(t: T, f: impl Fn(T, &u32) -> u32) -> u32 {\n        f(t, &0)\n    }\n    fn f2<'a, T: 'a>(_: &'a T, y: &u32) -> u32 {\n        *y\n    }\n    let _ = f(&0, |x, y| f2(x, y));\n    //~^ redundant_closure\n}\n\nfn _closure_with_types() {\n    fn f<T>(x: T) -> T {\n        x\n    }\n    fn f2<T: Default>(f: impl Fn(T) -> T) -> T {\n        f(T::default())\n    }\n\n    let _ = f2(|x: u32| f(x));\n    let _ = f2(|x| -> u32 { f(x) });\n}\n\n/// https://github.com/rust-lang/rust-clippy/issues/10854\n/// This is to verify that redundant_closure_for_method_calls resolves suggested paths to relative.\nmod issue_10854 {\n    pub mod test_mod {\n        pub struct Test;\n\n        impl Test {\n            pub fn method(self) -> i32 {\n                0\n            }\n        }\n\n        pub fn calls_test(test: Option<Test>) -> Option<i32> {\n            test.map(|t| t.method())\n            //~^ redundant_closure_for_method_calls\n        }\n\n        pub fn calls_outer(test: Option<super::Outer>) -> Option<i32> {\n            test.map(|t| t.method())\n            //~^ redundant_closure_for_method_calls\n        }\n    }\n\n    pub struct Outer;\n\n    impl Outer {\n        pub fn method(self) -> i32 {\n            0\n        }\n    }\n\n    pub fn calls_into_mod(test: Option<test_mod::Test>) -> Option<i32> {\n        test.map(|t| t.method())\n        //~^ redundant_closure_for_method_calls\n    }\n\n    mod a {\n        pub mod b {\n            pub mod c {\n                pub fn extreme_nesting(test: Option<super::super::super::d::Test>) -> Option<i32> {\n                    test.map(|t| t.method())\n                    //~^ redundant_closure_for_method_calls\n                }\n            }\n        }\n    }\n\n    mod d {\n        pub struct Test;\n\n        impl Test {\n            pub fn method(self) -> i32 {\n                0\n            }\n        }\n    }\n}\n\nmod issue_12853 {\n    fn f_by_value<F: Fn(u32)>(f: F) {\n        let x = Box::new(|| None.map(|x| f(x)));\n        //~^ redundant_closure\n        x();\n    }\n    fn f_by_ref<F: Fn(u32)>(f: &F) {\n        let x = Box::new(|| None.map(|x| f(x)));\n        //~^ redundant_closure\n        x();\n    }\n}\n\nmod issue_13073 {\n    fn get_default() -> Option<&'static str> {\n        Some(\"foo\")\n    }\n\n    pub fn foo() {\n        // shouldn't lint\n        let bind: Option<String> = None;\n        let _field = bind.as_deref().or_else(|| get_default()).unwrap();\n        let bind: Option<&'static str> = None;\n        let _field = bind.as_deref().or_else(|| get_default()).unwrap();\n        // should lint\n        let _field = bind.or_else(|| get_default()).unwrap();\n        //~^ redundant_closure\n    }\n}\n\nfn issue_14789() {\n    _ = Some(1u8).map(\n        #[expect(clippy::redundant_closure)]\n        |a| foo(a),\n    );\n\n    _ = Some(\"foo\").map(\n        #[expect(clippy::redundant_closure_for_method_calls)]\n        |s| s.to_owned(),\n    );\n\n    let _: Vec<u8> = None.map_or_else(\n        #[expect(clippy::redundant_closure)]\n        || vec![],\n        std::convert::identity,\n    );\n}\n\nfn issue_15072() {\n    use std::ops::Deref;\n\n    struct Foo;\n    impl Deref for Foo {\n        type Target = fn() -> &'static str;\n\n        fn deref(&self) -> &Self::Target {\n            fn hello() -> &'static str {\n                \"Hello, world!\"\n            }\n            &(hello as fn() -> &'static str)\n        }\n    }\n\n    fn accepts_fn(f: impl Fn() -> &'static str) {\n        println!(\"{}\", f());\n    }\n\n    fn some_fn() -> &'static str {\n        todo!()\n    }\n\n    let f = &Foo;\n    accepts_fn(|| f());\n    //~^ redundant_closure\n\n    let g = &some_fn;\n    accepts_fn(|| g());\n    //~^ redundant_closure\n\n    struct Bar(Foo);\n    impl Deref for Bar {\n        type Target = Foo;\n\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n\n    let b = &Bar(Foo);\n    accepts_fn(|| b());\n    //~^ redundant_closure\n}\n\nfn issue8817() {\n    fn f(_: u32) -> u32 {\n        todo!()\n    }\n    let g = |_: u32| -> u32 { todo!() };\n    struct S(u32);\n    enum MyError {\n        A(S),\n    }\n\n    Some(5)\n        .map(|n| f(n))\n        //~^ redundant_closure\n        //~| HELP: replace the closure with the function itself\n        .map(|n| g(n))\n        //~^ redundant_closure\n        //~| HELP: replace the closure with the function itself\n        .map(|n| S(n))\n        //~^ redundant_closure\n        //~| HELP: replace the closure with the tuple struct itself\n        .map(|n| MyError::A(n))\n        //~^ redundant_closure\n        //~| HELP: replace the closure with the tuple variant itself\n        .unwrap(); // just for nicer formatting\n}\n\nasync fn issue13892<'a, T, F>(maybe: Option<&'a T>, visitor: F)\nwhere\n    F: AsyncFn(&'a T),\n    T: 'a,\n{\n    maybe.map(|x| visitor(x));\n}\n\ntrait Issue16360: Sized {\n    fn method(&self);\n\n    fn ice_machine(array: [Self; 1]) {\n        array.iter().for_each(|item| item.method());\n        //~^ redundant_closure_for_method_calls\n    }\n}\n\nfn issue16641() {\n    use std::cell::LazyCell;\n\n    let closure = LazyCell::new(|| |x: usize| println!(\"{x}\"));\n\n    (0..10).flat_map(|x| (0..10).map(|y| closure(y))).count();\n    //~^ redundant_closure\n}\n"
  },
  {
    "path": "tests/ui/eta.stderr",
    "content": "error: redundant closure\n  --> tests/ui/eta.rs:35:27\n   |\nLL |     let a = Some(1u8).map(|a| foo(a));\n   |                           ^^^^^^^^^^ help: replace the closure with the function itself: `foo`\n   |\n   = note: `-D clippy::redundant-closure` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:40:40\n   |\nLL |     let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!\n   |                                        ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:43:35\n   |\nLL |     let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?\n   |                                   ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:46:26\n   |\nLL |     all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted\n   |                          ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:55:27\n   |\nLL |     let e = Some(1u8).map(|a| generic(a));\n   |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:108:51\n   |\nLL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());\n   |                                                   ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`\n   |\n   = note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:110:51\n   |\nLL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());\n   |                                                   ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:113:42\n   |\nLL |     let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());\n   |                                          ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:118:29\n   |\nLL |     let e = Some(\"str\").map(|s| s.to_string());\n   |                             ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:120:27\n   |\nLL |     let e = Some('a').map(|s| s.to_uppercase());\n   |                           ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:123:65\n   |\nLL |     let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();\n   |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:140:23\n   |\nLL |         let _ = x.map(|x| x.parse::<i16>());\n   |                       ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `str::parse::<i16>`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:193:22\n   |\nLL |     requires_fn_once(|| x());\n   |                      ^^^^^^ help: replace the closure with the function itself: `x`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:201:27\n   |\nLL |     let a = Some(1u8).map(|a| foo_ptr(a));\n   |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:207:27\n   |\nLL |     let a = Some(1u8).map(|a| closure(a));\n   |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:240:28\n   |\nLL |     x.into_iter().for_each(|x| add_to_res(x));\n   |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:242:28\n   |\nLL |     y.into_iter().for_each(|x| add_to_res(x));\n   |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:244:28\n   |\nLL |     z.into_iter().for_each(|x| add_to_res(x));\n   |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:252:21\n   |\nLL |         Some(1).map(|n| closure(n));\n   |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:257:21\n   |\nLL |         Some(1).map(|n| in_loop(n));\n   |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:351:18\n   |\nLL |     takes_fn_mut(|| f());\n   |                  ^^^^^^ help: replace the closure with the function itself: `&mut f`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:355:19\n   |\nLL |     takes_fn_once(|| f());\n   |                   ^^^^^^ help: replace the closure with the function itself: `&mut f`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:360:26\n   |\nLL |     move || takes_fn_mut(|| f_used_once())\n   |                          ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:373:19\n   |\nLL |     array_opt.map(|a| a.as_slice());\n   |                   ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:377:19\n   |\nLL |     slice_opt.map(|s| s.len());\n   |                   ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:381:17\n   |\nLL |     ptr_opt.map(|p| p.is_null());\n   |                 ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:386:17\n   |\nLL |     dyn_opt.map(|d| d.method_on_dyn());\n   |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:447:19\n   |\nLL |     let _ = f(&0, |x, y| f2(x, y));\n   |                   ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:476:22\n   |\nLL |             test.map(|t| t.method())\n   |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:481:22\n   |\nLL |             test.map(|t| t.method())\n   |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `super::Outer::method`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:495:18\n   |\nLL |         test.map(|t| t.method())\n   |                  ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `test_mod::Test::method`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:503:30\n   |\nLL |                     test.map(|t| t.method())\n   |                              ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:523:38\n   |\nLL |         let x = Box::new(|| None.map(|x| f(x)));\n   |                                      ^^^^^^^^ help: replace the closure with the function itself: `&f`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:528:38\n   |\nLL |         let x = Box::new(|| None.map(|x| f(x)));\n   |                                      ^^^^^^^^ help: replace the closure with the function itself: `f`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:546:35\n   |\nLL |         let _field = bind.or_else(|| get_default()).unwrap();\n   |                                   ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:593:16\n   |\nLL |     accepts_fn(|| f());\n   |                ^^^^^^ help: replace the closure with the function itself: `**f`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:597:16\n   |\nLL |     accepts_fn(|| g());\n   |                ^^^^^^ help: replace the closure with the function itself: `g`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:610:16\n   |\nLL |     accepts_fn(|| b());\n   |                ^^^^^^ help: replace the closure with the function itself: `***b`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:634:14\n   |\nLL |         .map(|n| MyError::A(n))\n   |              ^^^^^^^^^^^^^^^^^ help: replace the closure with the tuple variant itself: `MyError::A`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:631:14\n   |\nLL |         .map(|n| S(n))\n   |              ^^^^^^^^ help: replace the closure with the tuple struct itself: `S`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:628:14\n   |\nLL |         .map(|n| g(n))\n   |              ^^^^^^^^ help: replace the closure with the function itself: `g`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:625:14\n   |\nLL |         .map(|n| f(n))\n   |              ^^^^^^^^ help: replace the closure with the function itself: `f`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:652:31\n   |\nLL |         array.iter().for_each(|item| item.method());\n   |                               ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Self::method`\n\nerror: redundant closure\n  --> tests/ui/eta.rs:662:38\n   |\nLL |     (0..10).flat_map(|x| (0..10).map(|y| closure(y))).count();\n   |                                      ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&*closure`\n\nerror: aborting due to 44 previous errors\n\n"
  },
  {
    "path": "tests/ui/eta_nostd.fixed",
    "content": "#![warn(clippy::redundant_closure)]\n#![no_std]\n\nextern crate alloc;\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nfn issue_13895() {\n    let _: Option<Vec<u8>> = true.then(alloc::vec::Vec::new);\n    //~^ redundant_closure\n}\n"
  },
  {
    "path": "tests/ui/eta_nostd.rs",
    "content": "#![warn(clippy::redundant_closure)]\n#![no_std]\n\nextern crate alloc;\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nfn issue_13895() {\n    let _: Option<Vec<u8>> = true.then(|| vec![]);\n    //~^ redundant_closure\n}\n"
  },
  {
    "path": "tests/ui/eta_nostd.stderr",
    "content": "error: redundant closure\n  --> tests/ui/eta_nostd.rs:9:40\n   |\nLL |     let _: Option<Vec<u8>> = true.then(|| vec![]);\n   |                                        ^^^^^^^^^ help: replace the closure with `Vec::new`: `alloc::vec::Vec::new`\n   |\n   = note: `-D clippy::redundant-closure` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/excessive_precision.fixed",
    "content": "#![warn(clippy::excessive_precision)]\n#![allow(\n    dead_code,\n    overflowing_literals,\n    unused_variables,\n    clippy::print_literal,\n    clippy::useless_vec,\n    clippy::approx_constant\n)]\n\nmacro_rules! make_pi {\n    ($i:ident : $t:ty) => {\n        const $i: $t = 3.14159265358979323846264338327950288419716939937510582097494459230781640628;\n    };\n}\n\nfn main() {\n    // Consts\n    const GOOD32: f32 = 0.123_456;\n    const GOOD32_SM: f32 = 0.000_000_000_1;\n    const GOOD32_DOT: f32 = 10_000_000_000.0;\n    const GOOD32_EDGE: f32 = 1.000_000_8;\n    const GOOD64: f64 = 0.123_456_789_012;\n    const GOOD64_SM: f32 = 0.000_000_000_000_000_1;\n    const GOOD64_DOT: f32 = 10_000_000_000_000_000.0;\n\n    const BAD32_1: f32 = 0.123_456_79_f32;\n    //~^ excessive_precision\n    const BAD32_2: f32 = 0.123_456_79;\n    //~^ excessive_precision\n    const BAD32_3: f32 = 0.1;\n    //~^ excessive_precision\n    const BAD32_EDGE: f32 = 1.000_001;\n    //~^ excessive_precision\n\n    const BAD64_1: f64 = 0.123_456_789_012_345_67f64;\n    const BAD64_2: f64 = 0.123_456_789_012_345_67;\n    const BAD64_3: f64 = 0.1;\n    //~^ excessive_precision\n\n    // Literal as param\n    println!(\"{:?}\", 8.888_888_888_888_89);\n    //~^ excessive_precision\n\n    // // TODO add inferred type tests for f32\n    // Locals\n    let good32: f32 = 0.123_456_f32;\n    let good32_2: f32 = 0.123_456;\n\n    let good64: f64 = 0.123_456_789_012;\n    let good64_suf: f64 = 0.123_456_789_012f64;\n    let good64_inf = 0.123_456_789_012;\n\n    let bad32: f32 = 1.123_456_8;\n    //~^ excessive_precision\n    let bad32_suf: f32 = 1.123_456_8_f32;\n    //~^ excessive_precision\n    let bad32_inf = 1.123_456_8_f32;\n    //~^ excessive_precision\n\n    let bad64: f64 = 0.123_456_789_012_345_67;\n    let bad64_suf: f64 = 0.123_456_789_012_345_67f64;\n    let bad64_inf = 0.123_456_789_012_345_67;\n\n    // Vectors\n    let good_vec32: Vec<f32> = vec![0.123_456];\n    let good_vec64: Vec<f64> = vec![0.123_456_789];\n\n    let bad_vec32: Vec<f32> = vec![0.123_456_79];\n    //~^ excessive_precision\n    let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_78];\n    //~^ excessive_precision\n\n    // Exponential float notation\n    let good_e32: f32 = 1e-10;\n    let bad_e32: f32 = 1.123_456_8e-10;\n    //~^ excessive_precision\n\n    let good_bige32: f32 = 1E-10;\n    let bad_bige32: f32 = 1.123_456_8E-10;\n    //~^ excessive_precision\n\n    // Inferred type\n    let good_inferred: f32 = 1f32 * 1_000_000_000.;\n\n    // issue #2840\n    let num = 0.000_000_000_01e-10f64;\n\n    // issue #6341\n    let exponential: f64 = 4.886506780521244E-03;\n\n    // issue #7744\n    let _ = 2.225_073_858_507_201e-308_f64;\n    //~^ excessive_precision\n\n    // issue #7745\n    let _ = 0_f64;\n    //~^ excessive_precision\n\n    // issue #9910\n    const INF1: f32 = 1.0e+33f32;\n    const INF2: f64 = 1.0e+3300f64;\n    const NEG_INF1: f32 = -1.0e+33f32;\n    const NEG_INF2: f64 = -1.0e+3300f64;\n    const NEG_INF3: f32 = -3.40282357e+38_f32;\n\n    // issue #12954\n    const _: f64 = 3.0;\n    //~^ excessive_precision\n    const _: f64 = 3.0000000000000000;\n\n    // Overly specified constants\n    let _: f32 = 1.012_345_7;\n    //~^ excessive_precision\n    let _: f64 = 1.012_345_678_901_234_6;\n    //~^ excessive_precision\n    const _: f32 = 1.01234567890123456789012345678901234567890;\n    const _: f64 = 1.01234567890123456789012345678901234567890;\n\n    static STATIC1: f32 = 1.01234567890123456789012345678901234567890;\n    static STATIC2: f64 = 1.01234567890123456789012345678901234567890;\n\n    static mut STATIC_MUT1: f32 = 1.01234567890123456789012345678901234567890;\n    static mut STATIC_MUT2: f64 = 1.01234567890123456789012345678901234567890;\n\n    // From issue #13855\n    let gamma = 0.577_215_664_901_532_9;\n    //~^ excessive_precision\n    const GAMMA: f64 = 0.5772156649015328606065120900824024310421;\n\n    make_pi!(P32: f32);\n    make_pi!(P64: f64);\n}\n\ntrait ExcessivelyPreciseTrait {\n    // Overly specified constants\n    const GOOD1: f32 = 1.01234567890123456789012345678901234567890;\n    const GOOD2: f64 = 1.01234567890123456789012345678901234567890;\n}\n\nstruct ExcessivelyPreciseStruct;\n\nimpl ExcessivelyPreciseStruct {\n    // Overly specified constants\n    const GOOD1: f32 = 1.01234567890123456789012345678901234567890;\n    const GOOD2: f64 = 1.01234567890123456789012345678901234567890;\n}\n"
  },
  {
    "path": "tests/ui/excessive_precision.rs",
    "content": "#![warn(clippy::excessive_precision)]\n#![allow(\n    dead_code,\n    overflowing_literals,\n    unused_variables,\n    clippy::print_literal,\n    clippy::useless_vec,\n    clippy::approx_constant\n)]\n\nmacro_rules! make_pi {\n    ($i:ident : $t:ty) => {\n        const $i: $t = 3.14159265358979323846264338327950288419716939937510582097494459230781640628;\n    };\n}\n\nfn main() {\n    // Consts\n    const GOOD32: f32 = 0.123_456;\n    const GOOD32_SM: f32 = 0.000_000_000_1;\n    const GOOD32_DOT: f32 = 10_000_000_000.0;\n    const GOOD32_EDGE: f32 = 1.000_000_8;\n    const GOOD64: f64 = 0.123_456_789_012;\n    const GOOD64_SM: f32 = 0.000_000_000_000_000_1;\n    const GOOD64_DOT: f32 = 10_000_000_000_000_000.0;\n\n    const BAD32_1: f32 = 0.123_456_789_f32;\n    //~^ excessive_precision\n    const BAD32_2: f32 = 0.123_456_789;\n    //~^ excessive_precision\n    const BAD32_3: f32 = 0.100_000_000_000_1;\n    //~^ excessive_precision\n    const BAD32_EDGE: f32 = 1.000_000_9;\n    //~^ excessive_precision\n\n    const BAD64_1: f64 = 0.123_456_789_012_345_67f64;\n    const BAD64_2: f64 = 0.123_456_789_012_345_67;\n    const BAD64_3: f64 = 0.100_000_000_000_000_000_1;\n    //~^ excessive_precision\n\n    // Literal as param\n    println!(\"{:?}\", 8.888_888_888_888_888_888_888);\n    //~^ excessive_precision\n\n    // // TODO add inferred type tests for f32\n    // Locals\n    let good32: f32 = 0.123_456_f32;\n    let good32_2: f32 = 0.123_456;\n\n    let good64: f64 = 0.123_456_789_012;\n    let good64_suf: f64 = 0.123_456_789_012f64;\n    let good64_inf = 0.123_456_789_012;\n\n    let bad32: f32 = 1.123_456_789;\n    //~^ excessive_precision\n    let bad32_suf: f32 = 1.123_456_789_f32;\n    //~^ excessive_precision\n    let bad32_inf = 1.123_456_789_f32;\n    //~^ excessive_precision\n\n    let bad64: f64 = 0.123_456_789_012_345_67;\n    let bad64_suf: f64 = 0.123_456_789_012_345_67f64;\n    let bad64_inf = 0.123_456_789_012_345_67;\n\n    // Vectors\n    let good_vec32: Vec<f32> = vec![0.123_456];\n    let good_vec64: Vec<f64> = vec![0.123_456_789];\n\n    let bad_vec32: Vec<f32> = vec![0.123_456_789];\n    //~^ excessive_precision\n    let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];\n    //~^ excessive_precision\n\n    // Exponential float notation\n    let good_e32: f32 = 1e-10;\n    let bad_e32: f32 = 1.123_456_788_888e-10;\n    //~^ excessive_precision\n\n    let good_bige32: f32 = 1E-10;\n    let bad_bige32: f32 = 1.123_456_788_888E-10;\n    //~^ excessive_precision\n\n    // Inferred type\n    let good_inferred: f32 = 1f32 * 1_000_000_000.;\n\n    // issue #2840\n    let num = 0.000_000_000_01e-10f64;\n\n    // issue #6341\n    let exponential: f64 = 4.886506780521244E-03;\n\n    // issue #7744\n    let _ = 2.225_073_858_507_201_1e-308_f64;\n    //~^ excessive_precision\n\n    // issue #7745\n    let _ = 1.000_000_000_000_001e-324_f64;\n    //~^ excessive_precision\n\n    // issue #9910\n    const INF1: f32 = 1.0e+33f32;\n    const INF2: f64 = 1.0e+3300f64;\n    const NEG_INF1: f32 = -1.0e+33f32;\n    const NEG_INF2: f64 = -1.0e+3300f64;\n    const NEG_INF3: f32 = -3.40282357e+38_f32;\n\n    // issue #12954\n    const _: f64 = 3.0000000000000000e+00;\n    //~^ excessive_precision\n    const _: f64 = 3.0000000000000000;\n\n    // Overly specified constants\n    let _: f32 = 1.01234567890123456789012345678901234567890;\n    //~^ excessive_precision\n    let _: f64 = 1.01234567890123456789012345678901234567890;\n    //~^ excessive_precision\n    const _: f32 = 1.01234567890123456789012345678901234567890;\n    const _: f64 = 1.01234567890123456789012345678901234567890;\n\n    static STATIC1: f32 = 1.01234567890123456789012345678901234567890;\n    static STATIC2: f64 = 1.01234567890123456789012345678901234567890;\n\n    static mut STATIC_MUT1: f32 = 1.01234567890123456789012345678901234567890;\n    static mut STATIC_MUT2: f64 = 1.01234567890123456789012345678901234567890;\n\n    // From issue #13855\n    let gamma = 0.5772156649015328606065120900824024310421;\n    //~^ excessive_precision\n    const GAMMA: f64 = 0.5772156649015328606065120900824024310421;\n\n    make_pi!(P32: f32);\n    make_pi!(P64: f64);\n}\n\ntrait ExcessivelyPreciseTrait {\n    // Overly specified constants\n    const GOOD1: f32 = 1.01234567890123456789012345678901234567890;\n    const GOOD2: f64 = 1.01234567890123456789012345678901234567890;\n}\n\nstruct ExcessivelyPreciseStruct;\n\nimpl ExcessivelyPreciseStruct {\n    // Overly specified constants\n    const GOOD1: f32 = 1.01234567890123456789012345678901234567890;\n    const GOOD2: f64 = 1.01234567890123456789012345678901234567890;\n}\n"
  },
  {
    "path": "tests/ui/excessive_precision.stderr",
    "content": "error: float has excessive precision\n  --> tests/ui/excessive_precision.rs:27:26\n   |\nLL |     const BAD32_1: f32 = 0.123_456_789_f32;\n   |                          ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::excessive-precision` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::excessive_precision)]`\nhelp: consider changing the type or truncating it to\n   |\nLL -     const BAD32_1: f32 = 0.123_456_789_f32;\nLL +     const BAD32_1: f32 = 0.123_456_79_f32;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:29:26\n   |\nLL |     const BAD32_2: f32 = 0.123_456_789;\n   |                          ^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     const BAD32_2: f32 = 0.123_456_789;\nLL +     const BAD32_2: f32 = 0.123_456_79;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:31:26\n   |\nLL |     const BAD32_3: f32 = 0.100_000_000_000_1;\n   |                          ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     const BAD32_3: f32 = 0.100_000_000_000_1;\nLL +     const BAD32_3: f32 = 0.1;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:33:29\n   |\nLL |     const BAD32_EDGE: f32 = 1.000_000_9;\n   |                             ^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     const BAD32_EDGE: f32 = 1.000_000_9;\nLL +     const BAD32_EDGE: f32 = 1.000_001;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:38:26\n   |\nLL |     const BAD64_3: f64 = 0.100_000_000_000_000_000_1;\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     const BAD64_3: f64 = 0.100_000_000_000_000_000_1;\nLL +     const BAD64_3: f64 = 0.1;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:42:22\n   |\nLL |     println!(\"{:?}\", 8.888_888_888_888_888_888_888);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     println!(\"{:?}\", 8.888_888_888_888_888_888_888);\nLL +     println!(\"{:?}\", 8.888_888_888_888_89);\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:54:22\n   |\nLL |     let bad32: f32 = 1.123_456_789;\n   |                      ^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let bad32: f32 = 1.123_456_789;\nLL +     let bad32: f32 = 1.123_456_8;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:56:26\n   |\nLL |     let bad32_suf: f32 = 1.123_456_789_f32;\n   |                          ^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let bad32_suf: f32 = 1.123_456_789_f32;\nLL +     let bad32_suf: f32 = 1.123_456_8_f32;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:58:21\n   |\nLL |     let bad32_inf = 1.123_456_789_f32;\n   |                     ^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let bad32_inf = 1.123_456_789_f32;\nLL +     let bad32_inf = 1.123_456_8_f32;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:69:36\n   |\nLL |     let bad_vec32: Vec<f32> = vec![0.123_456_789];\n   |                                    ^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let bad_vec32: Vec<f32> = vec![0.123_456_789];\nLL +     let bad_vec32: Vec<f32> = vec![0.123_456_79];\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:71:36\n   |\nLL |     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];\nLL +     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_78];\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:76:24\n   |\nLL |     let bad_e32: f32 = 1.123_456_788_888e-10;\n   |                        ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let bad_e32: f32 = 1.123_456_788_888e-10;\nLL +     let bad_e32: f32 = 1.123_456_8e-10;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:80:27\n   |\nLL |     let bad_bige32: f32 = 1.123_456_788_888E-10;\n   |                           ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let bad_bige32: f32 = 1.123_456_788_888E-10;\nLL +     let bad_bige32: f32 = 1.123_456_8E-10;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:93:13\n   |\nLL |     let _ = 2.225_073_858_507_201_1e-308_f64;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let _ = 2.225_073_858_507_201_1e-308_f64;\nLL +     let _ = 2.225_073_858_507_201e-308_f64;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:97:13\n   |\nLL |     let _ = 1.000_000_000_000_001e-324_f64;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     let _ = 1.000_000_000_000_001e-324_f64;\nLL +     let _ = 0_f64;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:108:20\n   |\nLL |     const _: f64 = 3.0000000000000000e+00;\n   |                    ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or truncating it to\n   |\nLL -     const _: f64 = 3.0000000000000000e+00;\nLL +     const _: f64 = 3.0;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:113:18\n   |\nLL |     let _: f32 = 1.01234567890123456789012345678901234567890;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider making it a `const` item\n  --> tests/ui/excessive_precision.rs:113:5\n   |\nLL |     let _: f32 = 1.01234567890123456789012345678901234567890;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider changing the type or truncating it to\n   |\nLL -     let _: f32 = 1.01234567890123456789012345678901234567890;\nLL +     let _: f32 = 1.012_345_7;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:115:18\n   |\nLL |     let _: f64 = 1.01234567890123456789012345678901234567890;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider making it a `const` item\n  --> tests/ui/excessive_precision.rs:115:5\n   |\nLL |     let _: f64 = 1.01234567890123456789012345678901234567890;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider changing the type or truncating it to\n   |\nLL -     let _: f64 = 1.01234567890123456789012345678901234567890;\nLL +     let _: f64 = 1.012_345_678_901_234_6;\n   |\n\nerror: float has excessive precision\n  --> tests/ui/excessive_precision.rs:127:17\n   |\nLL |     let gamma = 0.5772156649015328606065120900824024310421;\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider making it a `const` item\n  --> tests/ui/excessive_precision.rs:127:5\n   |\nLL |     let gamma = 0.5772156649015328606065120900824024310421;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider changing the type or truncating it to\n   |\nLL -     let gamma = 0.5772156649015328606065120900824024310421;\nLL +     let gamma = 0.577_215_664_901_532_9;\n   |\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/exhaustive_items.fixed",
    "content": "#![feature(default_field_values)]\n#![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)]\n#![allow(unused)]\n\nfn main() {\n    // nop\n}\n\npub mod enums {\n    #[non_exhaustive]\n    pub enum Exhaustive {\n        //~^ exhaustive_enums\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n\n    /// Some docs\n    #[repr(C)]\n    #[non_exhaustive]\n    pub enum ExhaustiveWithAttrs {\n        //~^ exhaustive_enums\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n\n    // no warning, already non_exhaustive\n    #[non_exhaustive]\n    pub enum NonExhaustive {\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n\n    // no warning, private\n    enum ExhaustivePrivate {\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n\n    // no warning, private\n    #[non_exhaustive]\n    enum NonExhaustivePrivate {\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n}\n\npub mod structs {\n    #[non_exhaustive]\n    pub struct Exhaustive {\n        //~^ exhaustive_structs\n        pub foo: u8,\n        pub bar: String,\n    }\n\n    // no warning, already non_exhaustive\n    #[non_exhaustive]\n    pub struct NonExhaustive {\n        pub foo: u8,\n        pub bar: String,\n    }\n\n    // no warning, private fields\n    pub struct ExhaustivePrivateFieldTuple(u8);\n\n    // no warning, private fields\n    pub struct ExhaustivePrivateField {\n        pub foo: u8,\n        bar: String,\n    }\n\n    // no warning, private\n    struct ExhaustivePrivate {\n        pub foo: u8,\n        pub bar: String,\n    }\n\n    // no warning, private\n    #[non_exhaustive]\n    struct NonExhaustivePrivate {\n        pub foo: u8,\n        pub bar: String,\n    }\n}\n\npub mod issue14992 {\n    pub struct A {\n        pub a: isize = 42,\n    }\n}\n"
  },
  {
    "path": "tests/ui/exhaustive_items.rs",
    "content": "#![feature(default_field_values)]\n#![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)]\n#![allow(unused)]\n\nfn main() {\n    // nop\n}\n\npub mod enums {\n    pub enum Exhaustive {\n        //~^ exhaustive_enums\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n\n    /// Some docs\n    #[repr(C)]\n    pub enum ExhaustiveWithAttrs {\n        //~^ exhaustive_enums\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n\n    // no warning, already non_exhaustive\n    #[non_exhaustive]\n    pub enum NonExhaustive {\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n\n    // no warning, private\n    enum ExhaustivePrivate {\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n\n    // no warning, private\n    #[non_exhaustive]\n    enum NonExhaustivePrivate {\n        Foo,\n        Bar,\n        Baz,\n        Quux(String),\n    }\n}\n\npub mod structs {\n    pub struct Exhaustive {\n        //~^ exhaustive_structs\n        pub foo: u8,\n        pub bar: String,\n    }\n\n    // no warning, already non_exhaustive\n    #[non_exhaustive]\n    pub struct NonExhaustive {\n        pub foo: u8,\n        pub bar: String,\n    }\n\n    // no warning, private fields\n    pub struct ExhaustivePrivateFieldTuple(u8);\n\n    // no warning, private fields\n    pub struct ExhaustivePrivateField {\n        pub foo: u8,\n        bar: String,\n    }\n\n    // no warning, private\n    struct ExhaustivePrivate {\n        pub foo: u8,\n        pub bar: String,\n    }\n\n    // no warning, private\n    #[non_exhaustive]\n    struct NonExhaustivePrivate {\n        pub foo: u8,\n        pub bar: String,\n    }\n}\n\npub mod issue14992 {\n    pub struct A {\n        pub a: isize = 42,\n    }\n}\n"
  },
  {
    "path": "tests/ui/exhaustive_items.stderr",
    "content": "error: exported enums should not be exhaustive\n  --> tests/ui/exhaustive_items.rs:10:5\n   |\nLL | /     pub enum Exhaustive {\nLL | |\nLL | |         Foo,\nLL | |         Bar,\nLL | |         Baz,\nLL | |         Quux(String),\nLL | |     }\n   | |_____^\n   |\nnote: the lint level is defined here\n  --> tests/ui/exhaustive_items.rs:2:9\n   |\nLL | #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try adding #[non_exhaustive]\n   |\nLL ~     #[non_exhaustive]\nLL ~     pub enum Exhaustive {\n   |\n\nerror: exported enums should not be exhaustive\n  --> tests/ui/exhaustive_items.rs:20:5\n   |\nLL | /     pub enum ExhaustiveWithAttrs {\nLL | |\nLL | |         Foo,\nLL | |         Bar,\nLL | |         Baz,\nLL | |         Quux(String),\nLL | |     }\n   | |_____^\n   |\nhelp: try adding #[non_exhaustive]\n   |\nLL ~     #[non_exhaustive]\nLL ~     pub enum ExhaustiveWithAttrs {\n   |\n\nerror: exported structs should not be exhaustive\n  --> tests/ui/exhaustive_items.rs:56:5\n   |\nLL | /     pub struct Exhaustive {\nLL | |\nLL | |         pub foo: u8,\nLL | |         pub bar: String,\nLL | |     }\n   | |_____^\n   |\nnote: the lint level is defined here\n  --> tests/ui/exhaustive_items.rs:2:35\n   |\nLL | #![deny(clippy::exhaustive_enums, clippy::exhaustive_structs)]\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try adding #[non_exhaustive]\n   |\nLL ~     #[non_exhaustive]\nLL ~     pub struct Exhaustive {\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/exit1.rs",
    "content": "#![warn(clippy::exit)]\n\nfn not_main() {\n    if true {\n        std::process::exit(4);\n        //~^ exit\n    }\n}\n\nfn main() {\n    if true {\n        std::process::exit(2);\n    };\n    not_main();\n    std::process::exit(1);\n}\n"
  },
  {
    "path": "tests/ui/exit1.stderr",
    "content": "error: usage of `process::exit`\n  --> tests/ui/exit1.rs:5:9\n   |\nLL |         std::process::exit(4);\n   |         ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::exit` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::exit)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/exit1_compile_flag_test.rs",
    "content": "//@compile-flags: --test\n#![warn(clippy::exit)]\n\nfn not_main() {\n    if true {\n        std::process::exit(4);\n        //~^ exit\n    }\n}\n\nfn main() {\n    if true {\n        std::process::exit(2);\n    };\n    not_main();\n    std::process::exit(1);\n}\n"
  },
  {
    "path": "tests/ui/exit1_compile_flag_test.stderr",
    "content": "error: usage of `process::exit`\n  --> tests/ui/exit1_compile_flag_test.rs:6:9\n   |\nLL |         std::process::exit(4);\n   |         ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::exit` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::exit)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/exit2.rs",
    "content": "#![warn(clippy::exit)]\n\nfn also_not_main() {\n    std::process::exit(3);\n    //~^ exit\n}\n\nfn main() {\n    if true {\n        std::process::exit(2);\n    };\n    also_not_main();\n    std::process::exit(1);\n}\n"
  },
  {
    "path": "tests/ui/exit2.stderr",
    "content": "error: usage of `process::exit`\n  --> tests/ui/exit2.rs:4:5\n   |\nLL |     std::process::exit(3);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::exit` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::exit)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/exit2_compile_flag_test.rs",
    "content": "//@compile-flags: --test\n#![warn(clippy::exit)]\n\nfn also_not_main() {\n    std::process::exit(3);\n    //~^ exit\n}\n\nfn main() {\n    if true {\n        std::process::exit(2);\n    };\n    also_not_main();\n    std::process::exit(1);\n}\n"
  },
  {
    "path": "tests/ui/exit2_compile_flag_test.stderr",
    "content": "error: usage of `process::exit`\n  --> tests/ui/exit2_compile_flag_test.rs:5:5\n   |\nLL |     std::process::exit(3);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::exit` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::exit)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/exit3.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::exit)]\n\nfn main() {\n    if true {\n        std::process::exit(2);\n    };\n    std::process::exit(1);\n}\n"
  },
  {
    "path": "tests/ui/exit3_compile_flag_test.rs",
    "content": "//@ check-pass\n//@compile-flags: --test\n\n#![warn(clippy::exit)]\n\nfn main() {\n    if true {\n        std::process::exit(2);\n    };\n    std::process::exit(1);\n}\n"
  },
  {
    "path": "tests/ui/exit4.rs",
    "content": "//@ check-pass\n//@compile-flags: --test\n\n#![warn(clippy::exit)]\n\nfn main() {\n    std::process::exit(0)\n}\n"
  },
  {
    "path": "tests/ui/expect.rs",
    "content": "#![warn(clippy::expect_used)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nfn expect_option() {\n    let opt = Some(0);\n    let _ = opt.expect(\"\");\n    //~^ expect_used\n}\n\nfn expect_result() {\n    let res: Result<u8, u8> = Ok(0);\n    let _ = res.expect(\"\");\n    //~^ expect_used\n\n    let _ = res.expect_err(\"\");\n    //~^ expect_used\n}\n\n#[allow(clippy::ok_expect)]\n#[allow(clippy::err_expect)]\nfn issue_15247() {\n    let x: Result<u8, u8> = Err(0);\n    x.ok().expect(\"Huh\");\n    //~^ expect_used\n\n    { x.ok() }.expect(\"...\");\n    //~^ expect_used\n\n    let y: Result<u8, u8> = Ok(0);\n    y.err().expect(\"Huh\");\n    //~^ expect_used\n\n    { y.err() }.expect(\"...\");\n    //~^ expect_used\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/expect.stderr",
    "content": "error: used `expect()` on an `Option` value\n  --> tests/ui/expect.rs:6:13\n   |\nLL |     let _ = opt.expect(\"\");\n   |             ^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = note: `-D clippy::expect-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::expect_used)]`\n\nerror: used `expect()` on a `Result` value\n  --> tests/ui/expect.rs:12:13\n   |\nLL |     let _ = res.expect(\"\");\n   |             ^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n\nerror: used `expect_err()` on a `Result` value\n  --> tests/ui/expect.rs:15:13\n   |\nLL |     let _ = res.expect_err(\"\");\n   |             ^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Ok`, it will panic\n\nerror: used `expect()` on an `Option` value\n  --> tests/ui/expect.rs:23:5\n   |\nLL |     x.ok().expect(\"Huh\");\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n\nerror: used `expect()` on an `Option` value\n  --> tests/ui/expect.rs:26:5\n   |\nLL |     { x.ok() }.expect(\"...\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n\nerror: used `expect()` on an `Option` value\n  --> tests/ui/expect.rs:30:5\n   |\nLL |     y.err().expect(\"Huh\");\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n\nerror: used `expect()` on an `Option` value\n  --> tests/ui/expect.rs:33:5\n   |\nLL |     { y.err() }.expect(\"...\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/expect_fun_call.fixed",
    "content": "#![warn(clippy::expect_fun_call)]\n#![allow(\n    clippy::to_string_in_format_args,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_literal_unwrap\n)]\n\nmacro_rules! one {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Self {\n            Foo\n        }\n\n        fn expect(&self, msg: &str) {\n            panic!(\"{}\", msg)\n        }\n    }\n\n    let with_some = Some(\"value\");\n    with_some.expect(\"error\");\n\n    let with_none: Option<i32> = None;\n    with_none.expect(\"error\");\n\n    let error_code = 123_i32;\n    let with_none_and_format: Option<i32> = None;\n    with_none_and_format.unwrap_or_else(|| panic!(\"Error {}: fake error\", error_code));\n    //~^ expect_fun_call\n\n    let with_none_and_as_str: Option<i32> = None;\n    with_none_and_as_str.unwrap_or_else(|| panic!(\"Error {}: fake error\", error_code));\n    //~^ expect_fun_call\n\n    let with_none_and_format_with_macro: Option<i32> = None;\n    with_none_and_format_with_macro.unwrap_or_else(|| panic!(\"Error {}: fake error\", one!()));\n    //~^ expect_fun_call\n\n    let with_ok: Result<(), ()> = Ok(());\n    with_ok.expect(\"error\");\n\n    let with_err: Result<(), ()> = Err(());\n    with_err.expect(\"error\");\n\n    let error_code = 123_i32;\n    let with_err_and_format: Result<(), ()> = Err(());\n    with_err_and_format.unwrap_or_else(|_| panic!(\"Error {}: fake error\", error_code));\n    //~^ expect_fun_call\n\n    let with_err_and_as_str: Result<(), ()> = Err(());\n    with_err_and_as_str.unwrap_or_else(|_| panic!(\"Error {}: fake error\", error_code));\n    //~^ expect_fun_call\n\n    let with_dummy_type = Foo::new();\n    with_dummy_type.expect(\"another test string\");\n\n    let with_dummy_type_and_format = Foo::new();\n    with_dummy_type_and_format.expect(&format!(\"Error {}: fake error\", error_code));\n\n    let with_dummy_type_and_as_str = Foo::new();\n    with_dummy_type_and_as_str.expect(format!(\"Error {}: fake error\", error_code).as_str());\n\n    //Issue #2937\n    Some(\"foo\").unwrap_or_else(|| panic!(\"{} {}\", 1, 2));\n    //~^ expect_fun_call\n\n    //Issue #2979 - this should not lint\n    {\n        let msg = \"bar\";\n        Some(\"foo\").expect(msg);\n    }\n\n    {\n        fn get_string() -> String {\n            \"foo\".to_string()\n        }\n\n        fn get_static_str() -> &'static str {\n            \"foo\"\n        }\n\n        fn get_non_static_str(_: &u32) -> &str {\n            \"foo\"\n        }\n\n        const fn const_evaluable() -> &'static str {\n            \"foo\"\n        }\n\n        Some(\"foo\").unwrap_or_else(|| panic!(\"{}\", get_string()));\n        //~^ expect_fun_call\n        Some(\"foo\").unwrap_or_else(|| panic!(\"{}\", get_string()));\n        //~^ expect_fun_call\n        Some(\"foo\").unwrap_or_else(|| panic!(\"{}\", get_string()));\n        //~^ expect_fun_call\n\n        Some(\"foo\").unwrap_or_else(|| panic!(\"{}\", get_static_str()));\n        //~^ expect_fun_call\n        Some(\"foo\").unwrap_or_else(|| panic!(\"{}\", get_non_static_str(&0)));\n        //~^ expect_fun_call\n\n        Some(\"foo\").unwrap_or_else(|| panic!(\"{}\", const_evaluable()));\n        //~^ expect_fun_call\n\n        const {\n            Some(\"foo\").expect(const_evaluable());\n        }\n\n        Some(\"foo\").expect(const { const_evaluable() });\n    }\n\n    //Issue #3839\n    Some(true).unwrap_or_else(|| panic!(\"key {}, {}\", 1, 2));\n    //~^ expect_fun_call\n\n    //Issue #4912 - the receiver is a &Option\n    {\n        let opt = Some(1);\n        let opt_ref = &opt;\n        opt_ref.unwrap_or_else(|| panic!(\"{:?}\", opt_ref));\n        //~^ expect_fun_call\n    }\n\n    let format_capture: Option<i32> = None;\n    format_capture.unwrap_or_else(|| panic!(\"{error_code}\"));\n    //~^ expect_fun_call\n\n    let format_capture_and_value: Option<i32> = None;\n    format_capture_and_value.unwrap_or_else(|| panic!(\"{error_code}, {}\", 1));\n    //~^ expect_fun_call\n\n    // Issue #15056\n    let a = false;\n    Some(5).expect(if a { \"a\" } else { \"b\" });\n\n    let return_in_expect: Option<i32> = None;\n    return_in_expect.expect(if true {\n        \"Error\"\n    } else {\n        return;\n    });\n}\n"
  },
  {
    "path": "tests/ui/expect_fun_call.rs",
    "content": "#![warn(clippy::expect_fun_call)]\n#![allow(\n    clippy::to_string_in_format_args,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_literal_unwrap\n)]\n\nmacro_rules! one {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Self {\n            Foo\n        }\n\n        fn expect(&self, msg: &str) {\n            panic!(\"{}\", msg)\n        }\n    }\n\n    let with_some = Some(\"value\");\n    with_some.expect(\"error\");\n\n    let with_none: Option<i32> = None;\n    with_none.expect(\"error\");\n\n    let error_code = 123_i32;\n    let with_none_and_format: Option<i32> = None;\n    with_none_and_format.expect(&format!(\"Error {}: fake error\", error_code));\n    //~^ expect_fun_call\n\n    let with_none_and_as_str: Option<i32> = None;\n    with_none_and_as_str.expect(format!(\"Error {}: fake error\", error_code).as_str());\n    //~^ expect_fun_call\n\n    let with_none_and_format_with_macro: Option<i32> = None;\n    with_none_and_format_with_macro.expect(format!(\"Error {}: fake error\", one!()).as_str());\n    //~^ expect_fun_call\n\n    let with_ok: Result<(), ()> = Ok(());\n    with_ok.expect(\"error\");\n\n    let with_err: Result<(), ()> = Err(());\n    with_err.expect(\"error\");\n\n    let error_code = 123_i32;\n    let with_err_and_format: Result<(), ()> = Err(());\n    with_err_and_format.expect(&format!(\"Error {}: fake error\", error_code));\n    //~^ expect_fun_call\n\n    let with_err_and_as_str: Result<(), ()> = Err(());\n    with_err_and_as_str.expect(format!(\"Error {}: fake error\", error_code).as_str());\n    //~^ expect_fun_call\n\n    let with_dummy_type = Foo::new();\n    with_dummy_type.expect(\"another test string\");\n\n    let with_dummy_type_and_format = Foo::new();\n    with_dummy_type_and_format.expect(&format!(\"Error {}: fake error\", error_code));\n\n    let with_dummy_type_and_as_str = Foo::new();\n    with_dummy_type_and_as_str.expect(format!(\"Error {}: fake error\", error_code).as_str());\n\n    //Issue #2937\n    Some(\"foo\").expect(format!(\"{} {}\", 1, 2).as_ref());\n    //~^ expect_fun_call\n\n    //Issue #2979 - this should not lint\n    {\n        let msg = \"bar\";\n        Some(\"foo\").expect(msg);\n    }\n\n    {\n        fn get_string() -> String {\n            \"foo\".to_string()\n        }\n\n        fn get_static_str() -> &'static str {\n            \"foo\"\n        }\n\n        fn get_non_static_str(_: &u32) -> &str {\n            \"foo\"\n        }\n\n        const fn const_evaluable() -> &'static str {\n            \"foo\"\n        }\n\n        Some(\"foo\").expect(&get_string());\n        //~^ expect_fun_call\n        Some(\"foo\").expect(get_string().as_ref());\n        //~^ expect_fun_call\n        Some(\"foo\").expect(get_string().as_str());\n        //~^ expect_fun_call\n\n        Some(\"foo\").expect(get_static_str());\n        //~^ expect_fun_call\n        Some(\"foo\").expect(get_non_static_str(&0));\n        //~^ expect_fun_call\n\n        Some(\"foo\").expect(const_evaluable());\n        //~^ expect_fun_call\n\n        const {\n            Some(\"foo\").expect(const_evaluable());\n        }\n\n        Some(\"foo\").expect(const { const_evaluable() });\n    }\n\n    //Issue #3839\n    Some(true).expect(&format!(\"key {}, {}\", 1, 2));\n    //~^ expect_fun_call\n\n    //Issue #4912 - the receiver is a &Option\n    {\n        let opt = Some(1);\n        let opt_ref = &opt;\n        opt_ref.expect(&format!(\"{:?}\", opt_ref));\n        //~^ expect_fun_call\n    }\n\n    let format_capture: Option<i32> = None;\n    format_capture.expect(&format!(\"{error_code}\"));\n    //~^ expect_fun_call\n\n    let format_capture_and_value: Option<i32> = None;\n    format_capture_and_value.expect(&format!(\"{error_code}, {}\", 1));\n    //~^ expect_fun_call\n\n    // Issue #15056\n    let a = false;\n    Some(5).expect(if a { \"a\" } else { \"b\" });\n\n    let return_in_expect: Option<i32> = None;\n    return_in_expect.expect(if true {\n        \"Error\"\n    } else {\n        return;\n    });\n}\n"
  },
  {
    "path": "tests/ui/expect_fun_call.stderr",
    "content": "error: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:35:26\n   |\nLL |     with_none_and_format.expect(&format!(\"Error {}: fake error\", error_code));\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"Error {}: fake error\", error_code))`\n   |\n   = note: `-D clippy::expect-fun-call` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::expect_fun_call)]`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:39:26\n   |\nLL |     with_none_and_as_str.expect(format!(\"Error {}: fake error\", error_code).as_str());\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"Error {}: fake error\", error_code))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:43:37\n   |\nLL |     with_none_and_format_with_macro.expect(format!(\"Error {}: fake error\", one!()).as_str());\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"Error {}: fake error\", one!()))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:54:25\n   |\nLL |     with_err_and_format.expect(&format!(\"Error {}: fake error\", error_code));\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!(\"Error {}: fake error\", error_code))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:58:25\n   |\nLL |     with_err_and_as_str.expect(format!(\"Error {}: fake error\", error_code).as_str());\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!(\"Error {}: fake error\", error_code))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:71:17\n   |\nLL |     Some(\"foo\").expect(format!(\"{} {}\", 1, 2).as_ref());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{} {}\", 1, 2))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:97:21\n   |\nLL |         Some(\"foo\").expect(&get_string());\n   |                     ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{}\", get_string()))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:99:21\n   |\nLL |         Some(\"foo\").expect(get_string().as_ref());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{}\", get_string()))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:101:21\n   |\nLL |         Some(\"foo\").expect(get_string().as_str());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{}\", get_string()))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:104:21\n   |\nLL |         Some(\"foo\").expect(get_static_str());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{}\", get_static_str()))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:106:21\n   |\nLL |         Some(\"foo\").expect(get_non_static_str(&0));\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{}\", get_non_static_str(&0)))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:109:21\n   |\nLL |         Some(\"foo\").expect(const_evaluable());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{}\", const_evaluable()))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:120:16\n   |\nLL |     Some(true).expect(&format!(\"key {}, {}\", 1, 2));\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"key {}, {}\", 1, 2))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:127:17\n   |\nLL |         opt_ref.expect(&format!(\"{:?}\", opt_ref));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{:?}\", opt_ref))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:132:20\n   |\nLL |     format_capture.expect(&format!(\"{error_code}\"));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{error_code}\"))`\n\nerror: function call inside of `expect`\n  --> tests/ui/expect_fun_call.rs:136:30\n   |\nLL |     format_capture_and_value.expect(&format!(\"{error_code}, {}\", 1));\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!(\"{error_code}, {}\", 1))`\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/expect_tool_lint_rfc_2383.rs",
    "content": "//! This file tests the `#[expect]` attribute implementation for tool lints. The same\n//! file is used to test clippy and rustdoc. Any changes to this file should be synced\n//! to the other test files as well.\n//!\n//! Expectations:\n//! * rustc: only rustc lint expectations are emitted\n//! * clippy: rustc and Clippy's expectations are emitted\n//! * rustdoc: only rustdoc lint expectations are emitted\n//!\n//! This test can't cover every lint from Clippy, rustdoc and potentially other\n//! tools that will be developed. This therefore only tests a small subset of lints\n#![expect(rustdoc::missing_crate_level_docs)]\n#![allow(clippy::needless_ifs)]\n\nmod rustc_ok {\n    //! See <https://doc.rust-lang.org/rustc/lints/index.html>\n\n    #[expect(dead_code)]\n    pub fn rustc_lints() {\n        let x = 42.0;\n\n        #[expect(invalid_nan_comparisons)]\n        let _b = x == f32::NAN;\n    }\n}\n\nmod rustc_warn {\n    //! See <https://doc.rust-lang.org/rustc/lints/index.html>\n\n    #[expect(dead_code)]\n    //~^ ERROR: this lint expectation is unfulfilled\n    //~| NOTE: `-D unfulfilled-lint-expectations` implied by `-D warnings`\n    //~| HELP: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`\n    pub fn rustc_lints() {\n        let x = 42;\n\n        #[expect(invalid_nan_comparisons)]\n        //~^ ERROR: this lint expectation is unfulfilled\n        //~| NOTE: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n        //~| ERROR: this lint expectation is unfulfilled\n        let _b = x == 5;\n    }\n}\n\npub mod rustdoc_ok {\n    //! See <https://doc.rust-lang.org/rustdoc/lints.html>\n\n    #[expect(rustdoc::broken_intra_doc_links)]\n    /// I want to link to [`Nonexistent`] but it doesn't exist!\n    pub fn foo() {}\n\n    #[expect(rustdoc::invalid_html_tags)]\n    /// <h1>\n    pub fn bar() {}\n\n    #[expect(rustdoc::bare_urls)]\n    /// http://example.org\n    pub fn baz() {}\n}\n\npub mod rustdoc_warn {\n    //! See <https://doc.rust-lang.org/rustdoc/lints.html>\n\n    #[expect(rustdoc::broken_intra_doc_links)]\n    /// I want to link to [`bar`] but it doesn't exist!\n    pub fn foo() {}\n\n    #[expect(rustdoc::invalid_html_tags)]\n    /// <h1></h1>\n    pub fn bar() {}\n\n    #[expect(rustdoc::bare_urls)]\n    /// <http://example.org>\n    pub fn baz() {}\n}\n\nmod clippy_ok {\n    //! See <https://rust-lang.github.io/rust-clippy/master/index.html>\n\n    #[expect(clippy::almost_swapped)]\n    fn foo() {\n        let mut a = 0;\n        let mut b = 9;\n        a = b;\n        b = a;\n    }\n\n    #[expect(clippy::bytes_nth)]\n    fn bar() {\n        let _ = \"Hello\".bytes().nth(3);\n    }\n\n    #[expect(clippy::if_same_then_else)]\n    fn baz() {\n        let _ = if true { 42 } else { 42 };\n    }\n\n    #[expect(clippy::overly_complex_bool_expr)]\n    fn burger() {\n        let a = false;\n        let b = true;\n\n        if a && b || a {}\n    }\n}\n\nmod clippy_warn {\n    //! See <https://rust-lang.github.io/rust-clippy/master/index.html>\n\n    #[expect(clippy::almost_swapped)]\n    //~^ ERROR: this lint expectation is unfulfilled\n    fn foo() {\n        let mut a = 0;\n        let mut b = 9;\n        a = b;\n    }\n\n    #[expect(clippy::bytes_nth)]\n    //~^ ERROR: this lint expectation is unfulfilled\n    fn bar() {\n        let _ = \"Hello\".as_bytes().get(3);\n    }\n\n    #[expect(clippy::if_same_then_else)]\n    //~^ ERROR: this lint expectation is unfulfilled\n    fn baz() {\n        let _ = if true { 33 } else { 42 };\n    }\n\n    #[expect(clippy::overly_complex_bool_expr)]\n    //~^ ERROR: this lint expectation is unfulfilled\n    fn burger() {\n        let a = false;\n        let b = true;\n        let c = false;\n\n        if a && b || c {}\n    }\n}\n\nfn main() {\n    rustc_warn::rustc_lints();\n}\n"
  },
  {
    "path": "tests/ui/expect_tool_lint_rfc_2383.stderr",
    "content": "error: this lint expectation is unfulfilled\n  --> tests/ui/expect_tool_lint_rfc_2383.rs:30:14\n   |\nLL |     #[expect(dead_code)]\n   |              ^^^^^^^^^\n   |\n   = note: `-D unfulfilled-lint-expectations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`\n\nerror: this lint expectation is unfulfilled\n  --> tests/ui/expect_tool_lint_rfc_2383.rs:37:18\n   |\nLL |         #[expect(invalid_nan_comparisons)]\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this lint expectation is unfulfilled\n  --> tests/ui/expect_tool_lint_rfc_2383.rs:37:18\n   |\nLL |         #[expect(invalid_nan_comparisons)]\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n\nerror: this lint expectation is unfulfilled\n  --> tests/ui/expect_tool_lint_rfc_2383.rs:110:14\n   |\nLL |     #[expect(clippy::almost_swapped)]\n   |              ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this lint expectation is unfulfilled\n  --> tests/ui/expect_tool_lint_rfc_2383.rs:118:14\n   |\nLL |     #[expect(clippy::bytes_nth)]\n   |              ^^^^^^^^^^^^^^^^^\n\nerror: this lint expectation is unfulfilled\n  --> tests/ui/expect_tool_lint_rfc_2383.rs:124:14\n   |\nLL |     #[expect(clippy::if_same_then_else)]\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this lint expectation is unfulfilled\n  --> tests/ui/expect_tool_lint_rfc_2383.rs:130:14\n   |\nLL |     #[expect(clippy::overly_complex_bool_expr)]\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/explicit_auto_deref.fixed",
    "content": "#![feature(closure_lifetime_binder)]\n#![warn(clippy::explicit_auto_deref)]\n#![allow(\n    dead_code,\n    unused_braces,\n    clippy::borrowed_box,\n    clippy::needless_borrow,\n    clippy::needless_return,\n    clippy::ptr_arg,\n    clippy::redundant_field_names,\n    clippy::too_many_arguments,\n    clippy::borrow_deref_ref,\n    clippy::let_unit_value,\n    clippy::needless_lifetimes\n)]\n\ntrait CallableStr {\n    type T: Fn(&str);\n    fn callable_str(&self) -> Self::T;\n}\nimpl CallableStr for () {\n    type T = fn(&str);\n    fn callable_str(&self) -> Self::T {\n        fn f(_: &str) {}\n        f\n    }\n}\nimpl CallableStr for i32 {\n    type T = <() as CallableStr>::T;\n    fn callable_str(&self) -> Self::T {\n        ().callable_str()\n    }\n}\n\ntrait CallableT<U: ?Sized> {\n    type T: Fn(&U);\n    fn callable_t(&self) -> Self::T;\n}\nimpl<U: ?Sized> CallableT<U> for () {\n    type T = fn(&U);\n    fn callable_t(&self) -> Self::T {\n        fn f<U: ?Sized>(_: &U) {}\n        f::<U>\n    }\n}\nimpl<U: ?Sized> CallableT<U> for i32 {\n    type T = <() as CallableT<U>>::T;\n    fn callable_t(&self) -> Self::T {\n        ().callable_t()\n    }\n}\n\nfn f_str(_: &str) {}\nfn f_string(_: &String) {}\nfn f_t<T>(_: T) {}\nfn f_ref_t<T: ?Sized>(_: &T) {}\n\nfn f_str_t<T>(_: &str, _: T) {}\n\nfn f_box_t<T>(_: &Box<T>) {}\n\nunsafe extern \"C\" {\n    fn var(_: u32, ...);\n}\n\nfn main() {\n    let s = String::new();\n\n    let _: &str = &s;\n    //~^ explicit_auto_deref\n    let _: &str = &{ String::new() };\n    //~^ explicit_auto_deref\n    let _: &str = &mut { String::new() };\n    //~^ explicit_auto_deref\n    let _ = &*s; // Don't lint. Inferred type would change.\n    let _: &_ = &*s; // Don't lint. Inferred type would change.\n\n    f_str(&s);\n    //~^ explicit_auto_deref\n    f_t(&*s); // Don't lint. Inferred type would change.\n    f_ref_t(&*s); // Don't lint. Inferred type would change.\n\n    f_str_t(&s, &*s); // Don't lint second param.\n    //\n    //~^^ explicit_auto_deref\n\n    let b = Box::new(Box::new(Box::new(5)));\n    let _: &Box<i32> = &b;\n    //~^ explicit_auto_deref\n    let _: &Box<_> = &**b; // Don't lint. Inferred type would change.\n\n    f_box_t(&**b); // Don't lint. Inferred type would change.\n\n    let c = |_x: &str| ();\n    c(&s);\n    //~^ explicit_auto_deref\n\n    let c = |_x| ();\n    c(&*s); // Don't lint. Inferred type would change.\n\n    fn _f(x: &String) -> &str {\n        x\n        //~^ explicit_auto_deref\n    }\n\n    fn _f1(x: &String) -> &str {\n        { x }\n        //~^ explicit_auto_deref\n    }\n\n    fn _f2(x: &String) -> &str {\n        { x }\n        //~^ explicit_auto_deref\n    }\n\n    fn _f3(x: &Box<Box<Box<i32>>>) -> &Box<i32> {\n        x\n        //~^ explicit_auto_deref\n    }\n\n    fn _f4(\n        x: String,\n        f1: impl Fn(&str),\n        f2: &dyn Fn(&str),\n        f3: fn(&str),\n        f4: impl CallableStr,\n        f5: <() as CallableStr>::T,\n        f6: <i32 as CallableStr>::T,\n        f7: &dyn CallableStr<T = fn(&str)>,\n        f8: impl CallableT<str>,\n        f9: <() as CallableT<str>>::T,\n        f10: <i32 as CallableT<str>>::T,\n        f11: &dyn CallableT<str, T = fn(&str)>,\n    ) {\n        f1(&x);\n        //~^ explicit_auto_deref\n        f2(&x);\n        //~^ explicit_auto_deref\n        f3(&x);\n        //~^ explicit_auto_deref\n        f4.callable_str()(&x);\n        //~^ explicit_auto_deref\n        f5(&x);\n        //~^ explicit_auto_deref\n        f6(&x);\n        //~^ explicit_auto_deref\n        f7.callable_str()(&x);\n        //~^ explicit_auto_deref\n        f8.callable_t()(&x);\n        //~^ explicit_auto_deref\n        f9(&x);\n        //~^ explicit_auto_deref\n        f10(&x);\n        //~^ explicit_auto_deref\n        f11.callable_t()(&x);\n        //~^ explicit_auto_deref\n    }\n\n    struct S1<'a>(&'a str);\n    let _ = S1(&s);\n    //~^ explicit_auto_deref\n\n    struct S2<'a> {\n        s: &'a str,\n    }\n    let _ = S2 { s: &s };\n    //~^ explicit_auto_deref\n\n    struct S3<'a, T: ?Sized>(&'a T);\n    let _ = S3(&*s); // Don't lint. Inferred type would change.\n\n    struct S4<'a, T: ?Sized> {\n        s: &'a T,\n    }\n    let _ = S4 { s: &*s }; // Don't lint. Inferred type would change.\n\n    enum E1<'a> {\n        S1(&'a str),\n        S2 { s: &'a str },\n    }\n    impl<'a> E1<'a> {\n        fn m1(s: &'a String) {\n            let _ = Self::S1(s);\n            //~^ explicit_auto_deref\n            let _ = Self::S2 { s: s };\n            //~^ explicit_auto_deref\n        }\n    }\n    let _ = E1::S1(&s);\n    //~^ explicit_auto_deref\n    let _ = E1::S2 { s: &s };\n    //~^ explicit_auto_deref\n\n    enum E2<'a, T: ?Sized> {\n        S1(&'a T),\n        S2 { s: &'a T },\n    }\n    let _ = E2::S1(&*s); // Don't lint. Inferred type would change.\n    let _ = E2::S2 { s: &*s }; // Don't lint. Inferred type would change.\n\n    let ref_s = &s;\n    let _: &String = &*ref_s; // Don't lint reborrow.\n    f_string(&*ref_s); // Don't lint reborrow.\n\n    struct S5 {\n        foo: u32,\n    }\n    let b = Box::new(Box::new(S5 { foo: 5 }));\n    let _ = b.foo;\n    let _ = b.foo;\n    //~^ explicit_auto_deref\n    let _ = b.foo;\n    //~^ explicit_auto_deref\n\n    struct S6 {\n        foo: S5,\n    }\n    impl core::ops::Deref for S6 {\n        type Target = S5;\n        fn deref(&self) -> &Self::Target {\n            &self.foo\n        }\n    }\n    let s6 = S6 { foo: S5 { foo: 5 } };\n    let _ = (*s6).foo; // Don't lint. `S6` also has a field named `foo`\n\n    let ref_str = &\"foo\";\n    let _ = f_str(ref_str);\n    //~^ explicit_auto_deref\n    let ref_ref_str = &ref_str;\n    let _ = f_str(ref_ref_str);\n    //~^ explicit_auto_deref\n\n    fn _f5(x: &u32) -> u32 {\n        if true {\n            *x\n        } else {\n            return *x;\n        }\n    }\n\n    f_str(&ref_str); // `needless_borrow` will suggest removing both references\n    //\n    //~^^ explicit_auto_deref\n    f_str(&ref_str); // `needless_borrow` will suggest removing only one reference\n    //\n    //~^^ explicit_auto_deref\n\n    let x = &&40;\n    unsafe {\n        var(0, &**x);\n    }\n\n    let s = &\"str\";\n    let _ = || return *s;\n    let _ = || -> &'static str { return s };\n    //~^ explicit_auto_deref\n\n    struct X;\n    struct Y(X);\n    impl core::ops::Deref for Y {\n        type Target = X;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    let _: &X = &*{ Y(X) };\n    let _: &X = &*match 0 {\n        #[rustfmt::skip]\n        0 => { Y(X) },\n        _ => panic!(),\n    };\n    let _: &X = &*if true { Y(X) } else { panic!() };\n\n    fn deref_to_u<U, T: core::ops::Deref<Target = U>>(x: &T) -> &U {\n        x\n        //~^ explicit_auto_deref\n    }\n\n    let _ = |x: &'static Box<dyn Iterator<Item = u32>>| -> &'static dyn Iterator<Item = u32> { &**x };\n    fn ret_any(x: &Box<dyn std::any::Any>) -> &dyn std::any::Any {\n        &**x\n    }\n\n    let x = String::new();\n    let _: *const str = &*x;\n\n    struct S7([u32; 1]);\n    impl core::ops::Deref for S7 {\n        type Target = [u32; 1];\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    let x = S7([0]);\n    let _: &[u32] = &*x;\n\n    let c1 = |_: &Vec<&u32>| {};\n    let x = &&vec![&1u32];\n    c1(x);\n    //~^ explicit_auto_deref\n    let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> {\n        if b {\n            return x;\n            //~^ explicit_auto_deref\n        }\n        x\n        //~^ explicit_auto_deref\n    };\n\n    trait WithAssoc {\n        type Assoc: ?Sized;\n        fn to_assoc(&self) -> &Self::Assoc {\n            panic!()\n        }\n    }\n    impl WithAssoc for String {\n        type Assoc = str;\n    }\n    fn takes_assoc<T: WithAssoc>(_: &T::Assoc) -> T {\n        unimplemented!()\n    }\n    let _: String = takes_assoc(&*String::new());\n\n    // Issue #9901\n    fn takes_ref(_: &i32) {}\n    takes_ref(*Box::new(&0i32));\n\n    // Issue #10384\n    impl<'a> WithAssoc for &'a u32 {\n        type Assoc = dyn core::fmt::Display;\n        fn to_assoc(&self) -> &Self::Assoc {\n            *self\n        }\n    }\n    fn return_dyn_assoc<'a>(x: &'a &'a u32) -> &'a <&'a u32 as WithAssoc>::Assoc {\n        *x\n    }\n\n    // Issue #11366\n    let _: &mut u32 = match &mut Some(&mut 0u32) {\n        Some(x) => x,\n        //~^ explicit_auto_deref\n        None => panic!(),\n    };\n\n    // Issue #11474\n    #[derive(Clone, Copy)]\n    struct Wrap<T>(T);\n    impl<T> core::ops::Deref for Wrap<T> {\n        type Target = T;\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for Wrap<T> {\n        fn deref_mut(&mut self) -> &mut T {\n            &mut self.0\n        }\n    }\n\n    union U<T: Copy> {\n        u: T,\n    }\n\n    #[derive(Clone, Copy)]\n    struct S8 {\n        x: &'static str,\n    }\n\n    unsafe {\n        let mut x = U {\n            u: core::mem::ManuallyDrop::new(S8 { x: \"\" }),\n        };\n        let _ = &mut (*x.u).x;\n        let _ = &mut { x.u }.x;\n        //~^ explicit_auto_deref\n        let _ = &mut ({ *x.u }).x;\n\n        let mut x = U {\n            u: Wrap(core::mem::ManuallyDrop::new(S8 { x: \"\" })),\n        };\n        let _ = &mut (*x.u).x;\n        //~^ explicit_auto_deref\n        let _ = &mut { x.u }.x;\n        //~^ explicit_auto_deref\n        let _ = &mut ({ **x.u }).x;\n\n        let mut x = U { u: Wrap(S8 { x: \"\" }) };\n        let _ = &mut x.u.x;\n        //~^ explicit_auto_deref\n        let _ = &mut { x.u }.x;\n        //~^ explicit_auto_deref\n        let _ = &mut ({ *x.u }).x;\n    }\n}\n\nmod issue_12969 {\n    use std::ops::Deref;\n\n    struct Wrapper<T>(T);\n\n    impl<T> Deref for Wrapper<T> {\n        type Target = T;\n\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n\n    fn foo(_bar: &str) {}\n\n    fn bar() {\n        let wrapped_bar = Wrapper(\"\");\n\n        foo(&wrapped_bar);\n        //~^ explicit_auto_deref\n    }\n}\n\nmod issue_9841 {\n    fn takes_array_ref<T, const N: usize>(array: &&[T; N]) {\n        takes_slice(*array)\n    }\n\n    fn takes_array_ref_ref<T, const N: usize>(array: &&&[T; N]) {\n        takes_slice(**array)\n    }\n\n    fn takes_slice<T>(slice: &[T]) {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/explicit_auto_deref.rs",
    "content": "#![feature(closure_lifetime_binder)]\n#![warn(clippy::explicit_auto_deref)]\n#![allow(\n    dead_code,\n    unused_braces,\n    clippy::borrowed_box,\n    clippy::needless_borrow,\n    clippy::needless_return,\n    clippy::ptr_arg,\n    clippy::redundant_field_names,\n    clippy::too_many_arguments,\n    clippy::borrow_deref_ref,\n    clippy::let_unit_value,\n    clippy::needless_lifetimes\n)]\n\ntrait CallableStr {\n    type T: Fn(&str);\n    fn callable_str(&self) -> Self::T;\n}\nimpl CallableStr for () {\n    type T = fn(&str);\n    fn callable_str(&self) -> Self::T {\n        fn f(_: &str) {}\n        f\n    }\n}\nimpl CallableStr for i32 {\n    type T = <() as CallableStr>::T;\n    fn callable_str(&self) -> Self::T {\n        ().callable_str()\n    }\n}\n\ntrait CallableT<U: ?Sized> {\n    type T: Fn(&U);\n    fn callable_t(&self) -> Self::T;\n}\nimpl<U: ?Sized> CallableT<U> for () {\n    type T = fn(&U);\n    fn callable_t(&self) -> Self::T {\n        fn f<U: ?Sized>(_: &U) {}\n        f::<U>\n    }\n}\nimpl<U: ?Sized> CallableT<U> for i32 {\n    type T = <() as CallableT<U>>::T;\n    fn callable_t(&self) -> Self::T {\n        ().callable_t()\n    }\n}\n\nfn f_str(_: &str) {}\nfn f_string(_: &String) {}\nfn f_t<T>(_: T) {}\nfn f_ref_t<T: ?Sized>(_: &T) {}\n\nfn f_str_t<T>(_: &str, _: T) {}\n\nfn f_box_t<T>(_: &Box<T>) {}\n\nunsafe extern \"C\" {\n    fn var(_: u32, ...);\n}\n\nfn main() {\n    let s = String::new();\n\n    let _: &str = &*s;\n    //~^ explicit_auto_deref\n    let _: &str = &*{ String::new() };\n    //~^ explicit_auto_deref\n    let _: &str = &mut *{ String::new() };\n    //~^ explicit_auto_deref\n    let _ = &*s; // Don't lint. Inferred type would change.\n    let _: &_ = &*s; // Don't lint. Inferred type would change.\n\n    f_str(&*s);\n    //~^ explicit_auto_deref\n    f_t(&*s); // Don't lint. Inferred type would change.\n    f_ref_t(&*s); // Don't lint. Inferred type would change.\n\n    f_str_t(&*s, &*s); // Don't lint second param.\n    //\n    //~^^ explicit_auto_deref\n\n    let b = Box::new(Box::new(Box::new(5)));\n    let _: &Box<i32> = &**b;\n    //~^ explicit_auto_deref\n    let _: &Box<_> = &**b; // Don't lint. Inferred type would change.\n\n    f_box_t(&**b); // Don't lint. Inferred type would change.\n\n    let c = |_x: &str| ();\n    c(&*s);\n    //~^ explicit_auto_deref\n\n    let c = |_x| ();\n    c(&*s); // Don't lint. Inferred type would change.\n\n    fn _f(x: &String) -> &str {\n        &**x\n        //~^ explicit_auto_deref\n    }\n\n    fn _f1(x: &String) -> &str {\n        { &**x }\n        //~^ explicit_auto_deref\n    }\n\n    fn _f2(x: &String) -> &str {\n        &**{ x }\n        //~^ explicit_auto_deref\n    }\n\n    fn _f3(x: &Box<Box<Box<i32>>>) -> &Box<i32> {\n        &***x\n        //~^ explicit_auto_deref\n    }\n\n    fn _f4(\n        x: String,\n        f1: impl Fn(&str),\n        f2: &dyn Fn(&str),\n        f3: fn(&str),\n        f4: impl CallableStr,\n        f5: <() as CallableStr>::T,\n        f6: <i32 as CallableStr>::T,\n        f7: &dyn CallableStr<T = fn(&str)>,\n        f8: impl CallableT<str>,\n        f9: <() as CallableT<str>>::T,\n        f10: <i32 as CallableT<str>>::T,\n        f11: &dyn CallableT<str, T = fn(&str)>,\n    ) {\n        f1(&*x);\n        //~^ explicit_auto_deref\n        f2(&*x);\n        //~^ explicit_auto_deref\n        f3(&*x);\n        //~^ explicit_auto_deref\n        f4.callable_str()(&*x);\n        //~^ explicit_auto_deref\n        f5(&*x);\n        //~^ explicit_auto_deref\n        f6(&*x);\n        //~^ explicit_auto_deref\n        f7.callable_str()(&*x);\n        //~^ explicit_auto_deref\n        f8.callable_t()(&*x);\n        //~^ explicit_auto_deref\n        f9(&*x);\n        //~^ explicit_auto_deref\n        f10(&*x);\n        //~^ explicit_auto_deref\n        f11.callable_t()(&*x);\n        //~^ explicit_auto_deref\n    }\n\n    struct S1<'a>(&'a str);\n    let _ = S1(&*s);\n    //~^ explicit_auto_deref\n\n    struct S2<'a> {\n        s: &'a str,\n    }\n    let _ = S2 { s: &*s };\n    //~^ explicit_auto_deref\n\n    struct S3<'a, T: ?Sized>(&'a T);\n    let _ = S3(&*s); // Don't lint. Inferred type would change.\n\n    struct S4<'a, T: ?Sized> {\n        s: &'a T,\n    }\n    let _ = S4 { s: &*s }; // Don't lint. Inferred type would change.\n\n    enum E1<'a> {\n        S1(&'a str),\n        S2 { s: &'a str },\n    }\n    impl<'a> E1<'a> {\n        fn m1(s: &'a String) {\n            let _ = Self::S1(&**s);\n            //~^ explicit_auto_deref\n            let _ = Self::S2 { s: &**s };\n            //~^ explicit_auto_deref\n        }\n    }\n    let _ = E1::S1(&*s);\n    //~^ explicit_auto_deref\n    let _ = E1::S2 { s: &*s };\n    //~^ explicit_auto_deref\n\n    enum E2<'a, T: ?Sized> {\n        S1(&'a T),\n        S2 { s: &'a T },\n    }\n    let _ = E2::S1(&*s); // Don't lint. Inferred type would change.\n    let _ = E2::S2 { s: &*s }; // Don't lint. Inferred type would change.\n\n    let ref_s = &s;\n    let _: &String = &*ref_s; // Don't lint reborrow.\n    f_string(&*ref_s); // Don't lint reborrow.\n\n    struct S5 {\n        foo: u32,\n    }\n    let b = Box::new(Box::new(S5 { foo: 5 }));\n    let _ = b.foo;\n    let _ = (*b).foo;\n    //~^ explicit_auto_deref\n    let _ = (**b).foo;\n    //~^ explicit_auto_deref\n\n    struct S6 {\n        foo: S5,\n    }\n    impl core::ops::Deref for S6 {\n        type Target = S5;\n        fn deref(&self) -> &Self::Target {\n            &self.foo\n        }\n    }\n    let s6 = S6 { foo: S5 { foo: 5 } };\n    let _ = (*s6).foo; // Don't lint. `S6` also has a field named `foo`\n\n    let ref_str = &\"foo\";\n    let _ = f_str(*ref_str);\n    //~^ explicit_auto_deref\n    let ref_ref_str = &ref_str;\n    let _ = f_str(**ref_ref_str);\n    //~^ explicit_auto_deref\n\n    fn _f5(x: &u32) -> u32 {\n        if true {\n            *x\n        } else {\n            return *x;\n        }\n    }\n\n    f_str(&&*ref_str); // `needless_borrow` will suggest removing both references\n    //\n    //~^^ explicit_auto_deref\n    f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference\n    //\n    //~^^ explicit_auto_deref\n\n    let x = &&40;\n    unsafe {\n        var(0, &**x);\n    }\n\n    let s = &\"str\";\n    let _ = || return *s;\n    let _ = || -> &'static str { return *s };\n    //~^ explicit_auto_deref\n\n    struct X;\n    struct Y(X);\n    impl core::ops::Deref for Y {\n        type Target = X;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    let _: &X = &*{ Y(X) };\n    let _: &X = &*match 0 {\n        #[rustfmt::skip]\n        0 => { Y(X) },\n        _ => panic!(),\n    };\n    let _: &X = &*if true { Y(X) } else { panic!() };\n\n    fn deref_to_u<U, T: core::ops::Deref<Target = U>>(x: &T) -> &U {\n        &**x\n        //~^ explicit_auto_deref\n    }\n\n    let _ = |x: &'static Box<dyn Iterator<Item = u32>>| -> &'static dyn Iterator<Item = u32> { &**x };\n    fn ret_any(x: &Box<dyn std::any::Any>) -> &dyn std::any::Any {\n        &**x\n    }\n\n    let x = String::new();\n    let _: *const str = &*x;\n\n    struct S7([u32; 1]);\n    impl core::ops::Deref for S7 {\n        type Target = [u32; 1];\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    let x = S7([0]);\n    let _: &[u32] = &*x;\n\n    let c1 = |_: &Vec<&u32>| {};\n    let x = &&vec![&1u32];\n    c1(*x);\n    //~^ explicit_auto_deref\n    let _ = for<'a, 'b> |x: &'a &'a Vec<&'b u32>, b: bool| -> &'a Vec<&'b u32> {\n        if b {\n            return *x;\n            //~^ explicit_auto_deref\n        }\n        *x\n        //~^ explicit_auto_deref\n    };\n\n    trait WithAssoc {\n        type Assoc: ?Sized;\n        fn to_assoc(&self) -> &Self::Assoc {\n            panic!()\n        }\n    }\n    impl WithAssoc for String {\n        type Assoc = str;\n    }\n    fn takes_assoc<T: WithAssoc>(_: &T::Assoc) -> T {\n        unimplemented!()\n    }\n    let _: String = takes_assoc(&*String::new());\n\n    // Issue #9901\n    fn takes_ref(_: &i32) {}\n    takes_ref(*Box::new(&0i32));\n\n    // Issue #10384\n    impl<'a> WithAssoc for &'a u32 {\n        type Assoc = dyn core::fmt::Display;\n        fn to_assoc(&self) -> &Self::Assoc {\n            *self\n        }\n    }\n    fn return_dyn_assoc<'a>(x: &'a &'a u32) -> &'a <&'a u32 as WithAssoc>::Assoc {\n        *x\n    }\n\n    // Issue #11366\n    let _: &mut u32 = match &mut Some(&mut 0u32) {\n        Some(x) => &mut *x,\n        //~^ explicit_auto_deref\n        None => panic!(),\n    };\n\n    // Issue #11474\n    #[derive(Clone, Copy)]\n    struct Wrap<T>(T);\n    impl<T> core::ops::Deref for Wrap<T> {\n        type Target = T;\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for Wrap<T> {\n        fn deref_mut(&mut self) -> &mut T {\n            &mut self.0\n        }\n    }\n\n    union U<T: Copy> {\n        u: T,\n    }\n\n    #[derive(Clone, Copy)]\n    struct S8 {\n        x: &'static str,\n    }\n\n    unsafe {\n        let mut x = U {\n            u: core::mem::ManuallyDrop::new(S8 { x: \"\" }),\n        };\n        let _ = &mut (*x.u).x;\n        let _ = &mut (*{ x.u }).x;\n        //~^ explicit_auto_deref\n        let _ = &mut ({ *x.u }).x;\n\n        let mut x = U {\n            u: Wrap(core::mem::ManuallyDrop::new(S8 { x: \"\" })),\n        };\n        let _ = &mut (**x.u).x;\n        //~^ explicit_auto_deref\n        let _ = &mut (**{ x.u }).x;\n        //~^ explicit_auto_deref\n        let _ = &mut ({ **x.u }).x;\n\n        let mut x = U { u: Wrap(S8 { x: \"\" }) };\n        let _ = &mut (*x.u).x;\n        //~^ explicit_auto_deref\n        let _ = &mut (*{ x.u }).x;\n        //~^ explicit_auto_deref\n        let _ = &mut ({ *x.u }).x;\n    }\n}\n\nmod issue_12969 {\n    use std::ops::Deref;\n\n    struct Wrapper<T>(T);\n\n    impl<T> Deref for Wrapper<T> {\n        type Target = T;\n\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n\n    fn foo(_bar: &str) {}\n\n    fn bar() {\n        let wrapped_bar = Wrapper(\"\");\n\n        foo(&*wrapped_bar);\n        //~^ explicit_auto_deref\n    }\n}\n\nmod issue_9841 {\n    fn takes_array_ref<T, const N: usize>(array: &&[T; N]) {\n        takes_slice(*array)\n    }\n\n    fn takes_array_ref_ref<T, const N: usize>(array: &&&[T; N]) {\n        takes_slice(**array)\n    }\n\n    fn takes_slice<T>(slice: &[T]) {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/explicit_auto_deref.stderr",
    "content": "error: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:69:19\n   |\nLL |     let _: &str = &*s;\n   |                   ^^^ help: try: `&s`\n   |\n   = note: `-D clippy::explicit-auto-deref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::explicit_auto_deref)]`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:71:19\n   |\nLL |     let _: &str = &*{ String::new() };\n   |                   ^^^^^^^^^^^^^^^^^^^ help: try: `&{ String::new() }`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:73:19\n   |\nLL |     let _: &str = &mut *{ String::new() };\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut { String::new() }`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:78:11\n   |\nLL |     f_str(&*s);\n   |           ^^^ help: try: `&s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:83:13\n   |\nLL |     f_str_t(&*s, &*s); // Don't lint second param.\n   |             ^^^ help: try: `&s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:88:24\n   |\nLL |     let _: &Box<i32> = &**b;\n   |                        ^^^^ help: try: `&b`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:95:7\n   |\nLL |     c(&*s);\n   |       ^^^ help: try: `&s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:102:9\n   |\nLL |         &**x\n   |         ^^^^ help: try: `x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:107:11\n   |\nLL |         { &**x }\n   |           ^^^^ help: try: `x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:112:9\n   |\nLL |         &**{ x }\n   |         ^^^^^^^^ help: try: `{ x }`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:117:9\n   |\nLL |         &***x\n   |         ^^^^^ help: try: `x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:135:12\n   |\nLL |         f1(&*x);\n   |            ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:137:12\n   |\nLL |         f2(&*x);\n   |            ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:139:12\n   |\nLL |         f3(&*x);\n   |            ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:141:27\n   |\nLL |         f4.callable_str()(&*x);\n   |                           ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:143:12\n   |\nLL |         f5(&*x);\n   |            ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:145:12\n   |\nLL |         f6(&*x);\n   |            ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:147:27\n   |\nLL |         f7.callable_str()(&*x);\n   |                           ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:149:25\n   |\nLL |         f8.callable_t()(&*x);\n   |                         ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:151:12\n   |\nLL |         f9(&*x);\n   |            ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:153:13\n   |\nLL |         f10(&*x);\n   |             ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:155:26\n   |\nLL |         f11.callable_t()(&*x);\n   |                          ^^^ help: try: `&x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:160:16\n   |\nLL |     let _ = S1(&*s);\n   |                ^^^ help: try: `&s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:166:21\n   |\nLL |     let _ = S2 { s: &*s };\n   |                     ^^^ help: try: `&s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:183:30\n   |\nLL |             let _ = Self::S1(&**s);\n   |                              ^^^^ help: try: `s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:185:35\n   |\nLL |             let _ = Self::S2 { s: &**s };\n   |                                   ^^^^ help: try: `s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:189:20\n   |\nLL |     let _ = E1::S1(&*s);\n   |                    ^^^ help: try: `&s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:191:25\n   |\nLL |     let _ = E1::S2 { s: &*s };\n   |                         ^^^ help: try: `&s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:210:13\n   |\nLL |     let _ = (*b).foo;\n   |             ^^^^ help: try: `b`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:212:13\n   |\nLL |     let _ = (**b).foo;\n   |             ^^^^^ help: try: `b`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:228:19\n   |\nLL |     let _ = f_str(*ref_str);\n   |                   ^^^^^^^^ help: try: `ref_str`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:231:19\n   |\nLL |     let _ = f_str(**ref_ref_str);\n   |                   ^^^^^^^^^^^^^ help: try: `ref_ref_str`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:242:12\n   |\nLL |     f_str(&&*ref_str); // `needless_borrow` will suggest removing both references\n   |            ^^^^^^^^^ help: try: `ref_str`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:245:12\n   |\nLL |     f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference\n   |            ^^^^^^^^^^ help: try: `ref_str`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:256:41\n   |\nLL |     let _ = || -> &'static str { return *s };\n   |                                         ^^ help: try: `s`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:276:9\n   |\nLL |         &**x\n   |         ^^^^ help: try: `x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:300:8\n   |\nLL |     c1(*x);\n   |        ^^ help: try: `x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:304:20\n   |\nLL |             return *x;\n   |                    ^^ help: try: `x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:307:9\n   |\nLL |         *x\n   |         ^^ help: try: `x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:342:20\n   |\nLL |         Some(x) => &mut *x,\n   |                    ^^^^^^^ help: try: `x`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:376:22\n   |\nLL |         let _ = &mut (*{ x.u }).x;\n   |                      ^^^^^^^^^^ help: try: `{ x.u }`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:383:22\n   |\nLL |         let _ = &mut (**x.u).x;\n   |                      ^^^^^^^ help: try: `(*x.u)`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:385:22\n   |\nLL |         let _ = &mut (**{ x.u }).x;\n   |                      ^^^^^^^^^^^ help: try: `{ x.u }`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:390:22\n   |\nLL |         let _ = &mut (*x.u).x;\n   |                      ^^^^^^ help: try: `x.u`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:392:22\n   |\nLL |         let _ = &mut (*{ x.u }).x;\n   |                      ^^^^^^^^^^ help: try: `{ x.u }`\n\nerror: deref which would be done by auto-deref\n  --> tests/ui/explicit_auto_deref.rs:416:13\n   |\nLL |         foo(&*wrapped_bar);\n   |             ^^^^^^^^^^^^^ help: try: `&wrapped_bar`\n\nerror: aborting due to 46 previous errors\n\n"
  },
  {
    "path": "tests/ui/explicit_counter_loop.rs",
    "content": "#![warn(clippy::explicit_counter_loop)]\n#![allow(clippy::useless_vec)]\n//@no-rustfix: suggestion does not remove the `+= 1`\nfn main() {\n    let mut vec = vec![1, 2, 3, 4];\n    let mut _index = 0;\n    for _v in &vec {\n        //~^ explicit_counter_loop\n\n        _index += 1\n    }\n\n    let mut _index = 1;\n    _index = 0;\n    for _v in &vec {\n        //~^ explicit_counter_loop\n\n        _index += 1\n    }\n\n    let mut _index = 0;\n    for _v in &mut vec {\n        //~^ explicit_counter_loop\n\n        _index += 1;\n    }\n\n    let mut _index = 0;\n    for _v in vec {\n        //~^ explicit_counter_loop\n\n        _index += 1;\n    }\n\n    let vec = [1, 2, 3, 4];\n    let mut _index = 0;\n    _index = 1;\n    for _v in &vec {\n        //~^ explicit_counter_loop\n        _index += 1\n    }\n\n    let mut _index = 0;\n    _index += 1;\n    for _v in &vec {\n        _index += 1\n    }\n\n    let mut _index = 0;\n    for _v in &vec {\n        _index = 1;\n        _index += 1\n    }\n\n    let mut _index = 0;\n    for _v in &vec {\n        let mut _index = 0;\n        _index += 1\n    }\n\n    let mut _index = 0;\n    for _v in &vec {\n        _index += 1;\n        _index = 0;\n    }\n\n    let mut _index = 0;\n    if true {\n        _index = 1\n    };\n    for _v in &vec {\n        _index += 1\n    }\n\n    let mut _index = 1;\n    if false {\n        _index = 0\n    };\n    for _v in &vec {\n        _index += 1\n    }\n}\n\nmod issue_1219 {\n    pub fn test() {\n        // should not trigger the lint because variable is used after the loop #473\n        let vec = vec![1, 2, 3];\n        let mut index = 0;\n        for _v in &vec {\n            index += 1\n        }\n        println!(\"index: {index}\");\n\n        // should not trigger the lint because the count is conditional #1219\n        let text = \"banana\";\n        let mut count = 0;\n        for ch in text.chars() {\n            println!(\"{count}\");\n            if ch == 'a' {\n                continue;\n            }\n            count += 1;\n        }\n\n        // should not trigger the lint because the count is conditional\n        let text = \"banana\";\n        let mut count = 0;\n        for ch in text.chars() {\n            println!(\"{count}\");\n            if ch == 'a' {\n                count += 1;\n            }\n        }\n\n        // should trigger the lint because the count is not conditional\n        let text = \"banana\";\n        let mut count = 0;\n        for ch in text.chars() {\n            //~^ explicit_counter_loop\n\n            println!(\"{count}\");\n            count += 1;\n            if ch == 'a' {\n                continue;\n            }\n        }\n\n        // should trigger the lint because the count is not conditional\n        let text = \"banana\";\n        let mut count = 0;\n        for ch in text.chars() {\n            //~^ explicit_counter_loop\n\n            println!(\"{count}\");\n            count += 1;\n            for i in 0..2 {\n                let _ = 123;\n            }\n        }\n\n        // should not trigger the lint because the count is incremented multiple times\n        let text = \"banana\";\n        let mut count = 0;\n        for ch in text.chars() {\n            println!(\"{count}\");\n            count += 1;\n            for i in 0..2 {\n                count += 1;\n            }\n        }\n    }\n}\n\nmod issue_3308 {\n    pub fn test() {\n        // should not trigger the lint because the count is incremented multiple times\n        let mut skips = 0;\n        let erasures = vec![];\n        for i in 0..10 {\n            println!(\"{skips}\");\n            while erasures.contains(&(i + skips)) {\n                skips += 1;\n            }\n        }\n\n        // should not trigger the lint because the count is incremented multiple times\n        let mut skips = 0;\n        for i in 0..10 {\n            println!(\"{skips}\");\n            let mut j = 0;\n            while j < 5 {\n                skips += 1;\n                j += 1;\n            }\n        }\n\n        // should not trigger the lint because the count is incremented multiple times\n        let mut skips = 0;\n        for i in 0..10 {\n            println!(\"{skips}\");\n            for j in 0..5 {\n                skips += 1;\n            }\n        }\n    }\n}\n\nmod issue_1670 {\n    pub fn test() {\n        let mut count = 0;\n        for _i in 3..10 {\n            //~^ explicit_counter_loop\n\n            count += 1;\n        }\n    }\n}\n\nmod issue_4732 {\n    pub fn test() {\n        let slice = &[1, 2, 3];\n        let mut index = 0;\n\n        // should not trigger the lint because the count is used after the loop\n        for _v in slice {\n            index += 1\n        }\n        let _closure = || println!(\"index: {index}\");\n    }\n}\n\nmod issue_4677 {\n    pub fn test() {\n        let slice = &[1, 2, 3];\n\n        // should not trigger the lint because the count is used after incremented\n        let mut count = 0;\n        for _i in slice {\n            count += 1;\n            println!(\"{count}\");\n        }\n    }\n}\n\nmod issue_7920 {\n    pub fn test() {\n        let slice = &[1, 2, 3];\n\n        let index_usize: usize = 0;\n        let mut idx_usize: usize = 0;\n\n        // should suggest `enumerate`\n        for _item in slice {\n            //~^ explicit_counter_loop\n\n            if idx_usize == index_usize {\n                break;\n            }\n\n            idx_usize += 1;\n        }\n\n        let index_u32: u32 = 0;\n        let mut idx_u32: u32 = 0;\n\n        // should suggest `zip`\n        for _item in slice {\n            //~^ explicit_counter_loop\n\n            if idx_u32 == index_u32 {\n                break;\n            }\n\n            idx_u32 += 1;\n        }\n    }\n}\n\nmod issue_10058 {\n    pub fn test() {\n        // should not lint since we are increasing counter potentially more than once in the loop\n        let values = [0, 1, 0, 1, 1, 1, 0, 1, 0, 1];\n        let mut counter = 0;\n        for value in values {\n            counter += 1;\n\n            if value == 0 {\n                continue;\n            }\n\n            counter += 1;\n        }\n    }\n\n    pub fn test2() {\n        // should not lint since we are increasing counter potentially more than once in the loop\n        let values = [0, 1, 0, 1, 1, 1, 0, 1, 0, 1];\n        let mut counter = 0;\n        for value in values {\n            counter += 1;\n\n            if value != 0 {\n                counter += 1;\n            }\n        }\n    }\n}\n\nmod issue_13123 {\n    pub fn test() {\n        let mut vec = vec![1, 2, 3, 4];\n        let mut _index = 0;\n        'label: for v in vec {\n            //~^ explicit_counter_loop\n            _index += 1;\n            if v == 1 {\n                break 'label;\n            }\n        }\n    }\n}\n\nfn issue16612(v: Vec<u8>, s: i64) {\n    use std::hint::black_box;\n\n    let mut i = 1;\n    for item in &v {\n        //~^ explicit_counter_loop\n        black_box((i, *item));\n        i += 1;\n    }\n\n    let mut j = s + 1;\n    for item in &v {\n        //~^ explicit_counter_loop\n        black_box((j, *item));\n        j += 1;\n    }\n}\n\nfn issue16640(x: &[u8]) {\n    struct Priority(u8);\n\n    impl core::ops::AddAssign<u8> for Priority {\n        fn add_assign(&mut self, rhs: u8) {\n            self.0 += rhs\n        }\n    }\n\n    let mut priority = Priority(1);\n    for _val in x {\n        priority += 1;\n    }\n}\n"
  },
  {
    "path": "tests/ui/explicit_counter_loop.stderr",
    "content": "error: the variable `_index` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:7:5\n   |\nLL |     for _v in &vec {\n   |     ^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter().enumerate()`\n   |\n   = note: `-D clippy::explicit-counter-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::explicit_counter_loop)]`\n\nerror: the variable `_index` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:15:5\n   |\nLL |     for _v in &vec {\n   |     ^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter().enumerate()`\n\nerror: the variable `_index` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:22:5\n   |\nLL |     for _v in &mut vec {\n   |     ^^^^^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.iter_mut().enumerate()`\n\nerror: the variable `_index` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:29:5\n   |\nLL |     for _v in vec {\n   |     ^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.into_iter().enumerate()`\n\nerror: the variable `_index` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:38:5\n   |\nLL |     for _v in &vec {\n   |     ^^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in (1..).zip(vec.iter())`\n\nerror: the variable `count` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:118:9\n   |\nLL |         for ch in text.chars() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`\n\nerror: the variable `count` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:131:9\n   |\nLL |         for ch in text.chars() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`\n\nerror: the variable `count` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:191:9\n   |\nLL |         for _i in 3..10 {\n   |         ^^^^^^^^^^^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()`\n\nerror: the variable `idx_usize` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:233:9\n   |\nLL |         for _item in slice {\n   |         ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_usize, _item) in slice.iter().enumerate()`\n\nerror: the variable `idx_u32` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:247:9\n   |\nLL |         for _item in slice {\n   |         ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_u32, _item) in (0_u32..).zip(slice.iter())`\n   |\n   = note: `idx_u32` is of type `u32`, making it ineligible for `Iterator::enumerate`\n\nerror: the variable `_index` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:293:9\n   |\nLL |         'label: for v in vec {\n   |         ^^^^^^^^^^^^^^^^^^^^ help: consider using: `'label: for (_index, v) in vec.into_iter().enumerate()`\n\nerror: the variable `i` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:307:5\n   |\nLL |     for item in &v {\n   |     ^^^^^^^^^^^^^^ help: consider using: `for (i, item) in (1..).zip(v.iter())`\n\nerror: the variable `j` is used as a loop counter\n  --> tests/ui/explicit_counter_loop.rs:314:5\n   |\nLL |     for item in &v {\n   |     ^^^^^^^^^^^^^^ help: consider using: `for (j, item) in (s + 1..).zip(v.iter())`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/explicit_deref_methods.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::explicit_deref_methods)]\n#![allow(unused_variables, unused_must_use)]\n#![allow(\n    clippy::borrow_deref_ref,\n    suspicious_double_ref_op,\n    noop_method_call,\n    clippy::explicit_auto_deref,\n    clippy::needless_borrow,\n    clippy::no_effect,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_literal_unwrap,\n    clippy::deref_addrof\n)]\n\nuse std::ops::{Deref, DerefMut};\n\nextern crate proc_macros;\n\nfn concat(deref_str: &str) -> String {\n    format!(\"{}bar\", deref_str)\n}\n\nfn just_return(deref_str: &str) -> &str {\n    deref_str\n}\n\nstruct CustomVec(Vec<u8>);\nimpl Deref for CustomVec {\n    type Target = Vec<u8>;\n\n    fn deref(&self) -> &Vec<u8> {\n        &self.0\n    }\n}\n\nstruct Aaa;\n\nimpl Deref for Aaa {\n    type Target = ();\n\n    fn deref(&self) -> &Self::Target {\n        todo!();\n    }\n}\n\nimpl DerefMut for Aaa {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        todo!();\n    }\n}\n\nfn main() {\n    let a: &mut String = &mut String::from(\"foo\");\n\n    // these should require linting\n\n    let b: &str = &*a;\n    //~^ explicit_deref_methods\n\n    let b: &mut str = &mut **a;\n    //~^ explicit_deref_methods\n\n    // both derefs should get linted here\n    let b: String = format!(\"{}, {}\", &*a, &*a);\n    //~^ explicit_deref_methods\n    //~| explicit_deref_methods\n\n    println!(\"{}\", &*a);\n    //~^ explicit_deref_methods\n\n    #[allow(clippy::match_single_binding)]\n    match &*a {\n        //~^ explicit_deref_methods\n        _ => (),\n    }\n\n    let b: String = concat(&*a);\n    //~^ explicit_deref_methods\n\n    let b = just_return(a);\n    //~^ explicit_deref_methods\n\n    let b: String = concat(just_return(a));\n    //~^ explicit_deref_methods\n\n    let b: &str = a.deref().deref();\n\n    let opt_a = Some(a.clone());\n    let b = opt_a.unwrap().deref();\n\n    Aaa::deref(&Aaa);\n    Aaa::deref_mut(&mut Aaa);\n    <Aaa as Deref>::deref(&Aaa);\n    <Aaa as DerefMut>::deref_mut(&mut Aaa);\n    let mut aaa = Aaa;\n    Aaa::deref(&aaa);\n    Aaa::deref_mut(&mut aaa);\n\n    // following should not require linting\n\n    let cv = CustomVec(vec![0, 42]);\n    let c = cv.deref()[0];\n\n    let b: &str = &*a.deref();\n\n    let b: String = a.deref().clone();\n\n    let b: usize = a.deref_mut().len();\n\n    let b: &usize = &a.deref().len();\n\n    let b: &str = &*a;\n\n    let b: &mut str = &mut *a;\n\n    macro_rules! expr_deref {\n        ($body:expr) => {\n            $body.deref()\n        };\n    }\n    let b: &str = expr_deref!(a);\n\n    let b: &str = expr_deref!(&*a);\n    //~^ explicit_deref_methods\n\n    proc_macros::external! {\n        let a: &mut String = &mut String::from(\"foo\");\n        let b: &str = a.deref();\n    }\n\n    // Issue #15168\n    proc_macros::with_span! {\n        span\n        let a: &mut String = &mut String::from(\"foo\");\n        let b: &str = a.deref();\n    }\n\n    // The struct does not implement Deref trait\n    #[derive(Copy, Clone)]\n    struct NoLint(u32);\n    impl NoLint {\n        pub fn deref(self) -> u32 {\n            self.0\n        }\n        pub fn deref_mut(self) -> u32 {\n            self.0\n        }\n    }\n    let no_lint = NoLint(42);\n    let b = no_lint.deref();\n    let b = no_lint.deref_mut();\n\n    let _ = &*&\"foo\"; //~ explicit_deref_methods\n    let mut x = String::new();\n    let _ = &&mut **&mut x; //~ explicit_deref_methods\n    let _ = &&mut ***(&mut &mut x); //~ explicit_deref_methods\n}\n\nmod issue_15392 {\n    use std::ops::{Deref, DerefMut};\n\n    struct Wrapper(String);\n\n    impl Deref for Wrapper {\n        type Target = str;\n        fn deref(&self) -> &Self::Target {\n            // forwarding is ok\n            let res = Deref::deref(&self.0);\n            // we let `deref_mut` pass as well\n            let _ = DerefMut::deref_mut(&mut String::new());\n            res\n        }\n    }\n\n    impl DerefMut for Wrapper {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            // forwarding is ok\n            let res = DerefMut::deref_mut(&mut self.0);\n            // we let `deref` pass as well\n            let _ = Deref::deref(&String::new());\n            res\n        }\n    }\n\n    struct A(String);\n    struct AA(String);\n    struct AB(String);\n\n    impl Deref for A {\n        type Target = str;\n\n        fn deref(&self) -> &Self::Target {\n            // in a top-level `Deref` impl, ok\n            let _ = self.0.deref();\n            // in a top-level `Deref` impl, acceptable\n            let _ = String::new().deref_mut();\n\n            #[allow(non_local_definitions)]\n            impl Deref for AA {\n                type Target = str;\n                fn deref(&self) -> &Self::Target {\n                    // in a nested `Deref` impl, acceptable\n                    let _ = String::new().deref_mut();\n                    // in a nested `Deref` impl, ok\n                    self.0.deref()\n                }\n            }\n\n            // still in a top-level `Deref` impl, ok\n            let _ = self.0.deref();\n            // still in a top-level `Deref` impl, acceptable\n            let _ = String::new().deref_mut();\n\n            #[allow(non_local_definitions)]\n            impl DerefMut for AA {\n                fn deref_mut(&mut self) -> &mut Self::Target {\n                    // in a top-level `DerefMut` impl, acceptable\n                    let _ = self.0.deref();\n                    // in a top-level `DerefMut` impl, ok\n                    self.0.deref_mut()\n                }\n            }\n\n            // still in a top-level `Deref` impl, acceptable\n            let _ = String::new().deref_mut();\n            // still in a top-level `Deref` impl, ok\n            self.0.deref()\n        }\n    }\n\n    impl DerefMut for A {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            // in a top-level `DerefMut` impl, acceptable\n            let _ = self.0.deref();\n            // in a top-level `DerefMut` impl, ok\n            let _ = self.0.deref_mut();\n\n            #[allow(non_local_definitions)]\n            impl Deref for AB {\n                type Target = str;\n                fn deref(&self) -> &Self::Target {\n                    // in a nested `Deref` impl, acceptable\n                    let _ = String::new().deref_mut();\n                    // in a nested `Deref` impl, ok\n                    Deref::deref(&self.0)\n                }\n            }\n\n            // still in a top-level `DerefMut` impl, acceptable\n            let _ = self.0.deref();\n            // still in a top-level `DerefMut` impl, ok\n            let _ = self.0.deref_mut();\n\n            #[allow(non_local_definitions)]\n            impl DerefMut for AB {\n                fn deref_mut(&mut self) -> &mut Self::Target {\n                    // in a nested `DerefMut` impl, acceptable\n                    self.0.deref();\n                    // in a nested `DerefMut` impl, ok\n                    self.0.deref_mut()\n                }\n            }\n\n            // still in a top-level `DerefMut` impl, acceptable\n            let _ = self.0.deref();\n            // still in a top-level `DerefMut` impl, ok\n            self.0.deref_mut()\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/explicit_deref_methods.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::explicit_deref_methods)]\n#![allow(unused_variables, unused_must_use)]\n#![allow(\n    clippy::borrow_deref_ref,\n    suspicious_double_ref_op,\n    noop_method_call,\n    clippy::explicit_auto_deref,\n    clippy::needless_borrow,\n    clippy::no_effect,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_literal_unwrap,\n    clippy::deref_addrof\n)]\n\nuse std::ops::{Deref, DerefMut};\n\nextern crate proc_macros;\n\nfn concat(deref_str: &str) -> String {\n    format!(\"{}bar\", deref_str)\n}\n\nfn just_return(deref_str: &str) -> &str {\n    deref_str\n}\n\nstruct CustomVec(Vec<u8>);\nimpl Deref for CustomVec {\n    type Target = Vec<u8>;\n\n    fn deref(&self) -> &Vec<u8> {\n        &self.0\n    }\n}\n\nstruct Aaa;\n\nimpl Deref for Aaa {\n    type Target = ();\n\n    fn deref(&self) -> &Self::Target {\n        todo!();\n    }\n}\n\nimpl DerefMut for Aaa {\n    fn deref_mut(&mut self) -> &mut Self::Target {\n        todo!();\n    }\n}\n\nfn main() {\n    let a: &mut String = &mut String::from(\"foo\");\n\n    // these should require linting\n\n    let b: &str = a.deref();\n    //~^ explicit_deref_methods\n\n    let b: &mut str = a.deref_mut();\n    //~^ explicit_deref_methods\n\n    // both derefs should get linted here\n    let b: String = format!(\"{}, {}\", a.deref(), a.deref());\n    //~^ explicit_deref_methods\n    //~| explicit_deref_methods\n\n    println!(\"{}\", a.deref());\n    //~^ explicit_deref_methods\n\n    #[allow(clippy::match_single_binding)]\n    match a.deref() {\n        //~^ explicit_deref_methods\n        _ => (),\n    }\n\n    let b: String = concat(a.deref());\n    //~^ explicit_deref_methods\n\n    let b = just_return(a).deref();\n    //~^ explicit_deref_methods\n\n    let b: String = concat(just_return(a).deref());\n    //~^ explicit_deref_methods\n\n    let b: &str = a.deref().deref();\n\n    let opt_a = Some(a.clone());\n    let b = opt_a.unwrap().deref();\n\n    Aaa::deref(&Aaa);\n    Aaa::deref_mut(&mut Aaa);\n    <Aaa as Deref>::deref(&Aaa);\n    <Aaa as DerefMut>::deref_mut(&mut Aaa);\n    let mut aaa = Aaa;\n    Aaa::deref(&aaa);\n    Aaa::deref_mut(&mut aaa);\n\n    // following should not require linting\n\n    let cv = CustomVec(vec![0, 42]);\n    let c = cv.deref()[0];\n\n    let b: &str = &*a.deref();\n\n    let b: String = a.deref().clone();\n\n    let b: usize = a.deref_mut().len();\n\n    let b: &usize = &a.deref().len();\n\n    let b: &str = &*a;\n\n    let b: &mut str = &mut *a;\n\n    macro_rules! expr_deref {\n        ($body:expr) => {\n            $body.deref()\n        };\n    }\n    let b: &str = expr_deref!(a);\n\n    let b: &str = expr_deref!(a.deref());\n    //~^ explicit_deref_methods\n\n    proc_macros::external! {\n        let a: &mut String = &mut String::from(\"foo\");\n        let b: &str = a.deref();\n    }\n\n    // Issue #15168\n    proc_macros::with_span! {\n        span\n        let a: &mut String = &mut String::from(\"foo\");\n        let b: &str = a.deref();\n    }\n\n    // The struct does not implement Deref trait\n    #[derive(Copy, Clone)]\n    struct NoLint(u32);\n    impl NoLint {\n        pub fn deref(self) -> u32 {\n            self.0\n        }\n        pub fn deref_mut(self) -> u32 {\n            self.0\n        }\n    }\n    let no_lint = NoLint(42);\n    let b = no_lint.deref();\n    let b = no_lint.deref_mut();\n\n    let _ = &Deref::deref(&\"foo\"); //~ explicit_deref_methods\n    let mut x = String::new();\n    let _ = &DerefMut::deref_mut(&mut x); //~ explicit_deref_methods\n    let _ = &DerefMut::deref_mut((&mut &mut x).deref_mut()); //~ explicit_deref_methods\n}\n\nmod issue_15392 {\n    use std::ops::{Deref, DerefMut};\n\n    struct Wrapper(String);\n\n    impl Deref for Wrapper {\n        type Target = str;\n        fn deref(&self) -> &Self::Target {\n            // forwarding is ok\n            let res = Deref::deref(&self.0);\n            // we let `deref_mut` pass as well\n            let _ = DerefMut::deref_mut(&mut String::new());\n            res\n        }\n    }\n\n    impl DerefMut for Wrapper {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            // forwarding is ok\n            let res = DerefMut::deref_mut(&mut self.0);\n            // we let `deref` pass as well\n            let _ = Deref::deref(&String::new());\n            res\n        }\n    }\n\n    struct A(String);\n    struct AA(String);\n    struct AB(String);\n\n    impl Deref for A {\n        type Target = str;\n\n        fn deref(&self) -> &Self::Target {\n            // in a top-level `Deref` impl, ok\n            let _ = self.0.deref();\n            // in a top-level `Deref` impl, acceptable\n            let _ = String::new().deref_mut();\n\n            #[allow(non_local_definitions)]\n            impl Deref for AA {\n                type Target = str;\n                fn deref(&self) -> &Self::Target {\n                    // in a nested `Deref` impl, acceptable\n                    let _ = String::new().deref_mut();\n                    // in a nested `Deref` impl, ok\n                    self.0.deref()\n                }\n            }\n\n            // still in a top-level `Deref` impl, ok\n            let _ = self.0.deref();\n            // still in a top-level `Deref` impl, acceptable\n            let _ = String::new().deref_mut();\n\n            #[allow(non_local_definitions)]\n            impl DerefMut for AA {\n                fn deref_mut(&mut self) -> &mut Self::Target {\n                    // in a top-level `DerefMut` impl, acceptable\n                    let _ = self.0.deref();\n                    // in a top-level `DerefMut` impl, ok\n                    self.0.deref_mut()\n                }\n            }\n\n            // still in a top-level `Deref` impl, acceptable\n            let _ = String::new().deref_mut();\n            // still in a top-level `Deref` impl, ok\n            self.0.deref()\n        }\n    }\n\n    impl DerefMut for A {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            // in a top-level `DerefMut` impl, acceptable\n            let _ = self.0.deref();\n            // in a top-level `DerefMut` impl, ok\n            let _ = self.0.deref_mut();\n\n            #[allow(non_local_definitions)]\n            impl Deref for AB {\n                type Target = str;\n                fn deref(&self) -> &Self::Target {\n                    // in a nested `Deref` impl, acceptable\n                    let _ = String::new().deref_mut();\n                    // in a nested `Deref` impl, ok\n                    Deref::deref(&self.0)\n                }\n            }\n\n            // still in a top-level `DerefMut` impl, acceptable\n            let _ = self.0.deref();\n            // still in a top-level `DerefMut` impl, ok\n            let _ = self.0.deref_mut();\n\n            #[allow(non_local_definitions)]\n            impl DerefMut for AB {\n                fn deref_mut(&mut self) -> &mut Self::Target {\n                    // in a nested `DerefMut` impl, acceptable\n                    self.0.deref();\n                    // in a nested `DerefMut` impl, ok\n                    self.0.deref_mut()\n                }\n            }\n\n            // still in a top-level `DerefMut` impl, acceptable\n            let _ = self.0.deref();\n            // still in a top-level `DerefMut` impl, ok\n            self.0.deref_mut()\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/explicit_deref_methods.stderr",
    "content": "error: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:58:19\n   |\nLL |     let b: &str = a.deref();\n   |                   ^^^^^^^^^ help: try: `&*a`\n   |\n   = note: `-D clippy::explicit-deref-methods` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::explicit_deref_methods)]`\n\nerror: explicit `deref_mut` method call\n  --> tests/ui/explicit_deref_methods.rs:61:23\n   |\nLL |     let b: &mut str = a.deref_mut();\n   |                       ^^^^^^^^^^^^^ help: try: `&mut **a`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:65:39\n   |\nLL |     let b: String = format!(\"{}, {}\", a.deref(), a.deref());\n   |                                       ^^^^^^^^^ help: try: `&*a`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:65:50\n   |\nLL |     let b: String = format!(\"{}, {}\", a.deref(), a.deref());\n   |                                                  ^^^^^^^^^ help: try: `&*a`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:69:20\n   |\nLL |     println!(\"{}\", a.deref());\n   |                    ^^^^^^^^^ help: try: `&*a`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:73:11\n   |\nLL |     match a.deref() {\n   |           ^^^^^^^^^ help: try: `&*a`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:78:28\n   |\nLL |     let b: String = concat(a.deref());\n   |                            ^^^^^^^^^ help: try: `&*a`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:81:13\n   |\nLL |     let b = just_return(a).deref();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:84:28\n   |\nLL |     let b: String = concat(just_return(a).deref());\n   |                            ^^^^^^^^^^^^^^^^^^^^^^ help: try: `just_return(a)`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:124:31\n   |\nLL |     let b: &str = expr_deref!(a.deref());\n   |                               ^^^^^^^^^ help: try: `&*a`\n\nerror: explicit `deref` method call\n  --> tests/ui/explicit_deref_methods.rs:154:14\n   |\nLL |     let _ = &Deref::deref(&\"foo\");\n   |              ^^^^^^^^^^^^^^^^^^^^ help: try: `*&\"foo\"`\n\nerror: explicit `deref_mut` method call\n  --> tests/ui/explicit_deref_methods.rs:156:14\n   |\nLL |     let _ = &DerefMut::deref_mut(&mut x);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut **&mut x`\n\nerror: explicit `deref_mut` method call\n  --> tests/ui/explicit_deref_methods.rs:157:14\n   |\nLL |     let _ = &DerefMut::deref_mut((&mut &mut x).deref_mut());\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut ***(&mut &mut x)`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/explicit_into_iter_loop.fixed",
    "content": "#![allow(non_local_definitions)]\n#![warn(clippy::explicit_into_iter_loop)]\n\nfn main() {\n    // Issue #4958\n    fn _takes_iterator<T>(iterator: &T)\n    where\n        for<'a> &'a T: IntoIterator<Item = &'a String>,\n    {\n        for _ in iterator {}\n        //~^ explicit_into_iter_loop\n    }\n\n    struct T;\n    impl IntoIterator for &T {\n        type Item = ();\n        type IntoIter = std::vec::IntoIter<Self::Item>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n\n    let mut t = T;\n    for _ in &t {}\n    //~^ explicit_into_iter_loop\n\n    let r = &t;\n    for _ in r {}\n    //~^ explicit_into_iter_loop\n\n    // No suggestion for this.\n    // We'd have to suggest `for _ in *rr {}` which is less clear.\n    let rr = &&t;\n    for _ in rr.into_iter() {}\n\n    let mr = &mut t;\n    for _ in &*mr {}\n    //~^ explicit_into_iter_loop\n\n    struct U;\n    impl IntoIterator for &mut U {\n        type Item = ();\n        type IntoIter = std::vec::IntoIter<Self::Item>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n\n    let mut u = U;\n    for _ in &mut u {}\n    //~^ explicit_into_iter_loop\n\n    let mr = &mut u;\n    for _ in &mut *mr {}\n    //~^ explicit_into_iter_loop\n\n    // Issue #6900\n    struct S;\n    impl S {\n        #[allow(clippy::should_implement_trait)]\n        pub fn into_iter<T>(self) -> I<T> {\n            unimplemented!()\n        }\n    }\n\n    struct I<T>(T);\n    impl<T> Iterator for I<T> {\n        type Item = T;\n        fn next(&mut self) -> Option<Self::Item> {\n            unimplemented!()\n        }\n    }\n\n    for _ in S.into_iter::<u32>() {}\n}\n\nfn issue14630() {\n    macro_rules! mac {\n        (into_iter $e:expr) => {\n            $e.into_iter()\n        };\n    }\n\n    for _ in dbg!([1, 2]) {}\n    //~^ explicit_into_iter_loop\n\n    for _ in mac!(into_iter [1, 2]) {}\n}\n"
  },
  {
    "path": "tests/ui/explicit_into_iter_loop.rs",
    "content": "#![allow(non_local_definitions)]\n#![warn(clippy::explicit_into_iter_loop)]\n\nfn main() {\n    // Issue #4958\n    fn _takes_iterator<T>(iterator: &T)\n    where\n        for<'a> &'a T: IntoIterator<Item = &'a String>,\n    {\n        for _ in iterator.into_iter() {}\n        //~^ explicit_into_iter_loop\n    }\n\n    struct T;\n    impl IntoIterator for &T {\n        type Item = ();\n        type IntoIter = std::vec::IntoIter<Self::Item>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n\n    let mut t = T;\n    for _ in t.into_iter() {}\n    //~^ explicit_into_iter_loop\n\n    let r = &t;\n    for _ in r.into_iter() {}\n    //~^ explicit_into_iter_loop\n\n    // No suggestion for this.\n    // We'd have to suggest `for _ in *rr {}` which is less clear.\n    let rr = &&t;\n    for _ in rr.into_iter() {}\n\n    let mr = &mut t;\n    for _ in mr.into_iter() {}\n    //~^ explicit_into_iter_loop\n\n    struct U;\n    impl IntoIterator for &mut U {\n        type Item = ();\n        type IntoIter = std::vec::IntoIter<Self::Item>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n\n    let mut u = U;\n    for _ in u.into_iter() {}\n    //~^ explicit_into_iter_loop\n\n    let mr = &mut u;\n    for _ in mr.into_iter() {}\n    //~^ explicit_into_iter_loop\n\n    // Issue #6900\n    struct S;\n    impl S {\n        #[allow(clippy::should_implement_trait)]\n        pub fn into_iter<T>(self) -> I<T> {\n            unimplemented!()\n        }\n    }\n\n    struct I<T>(T);\n    impl<T> Iterator for I<T> {\n        type Item = T;\n        fn next(&mut self) -> Option<Self::Item> {\n            unimplemented!()\n        }\n    }\n\n    for _ in S.into_iter::<u32>() {}\n}\n\nfn issue14630() {\n    macro_rules! mac {\n        (into_iter $e:expr) => {\n            $e.into_iter()\n        };\n    }\n\n    for _ in dbg!([1, 2]).into_iter() {}\n    //~^ explicit_into_iter_loop\n\n    for _ in mac!(into_iter [1, 2]) {}\n}\n"
  },
  {
    "path": "tests/ui/explicit_into_iter_loop.stderr",
    "content": "error: it is more concise to loop over containers instead of using explicit iteration methods\n  --> tests/ui/explicit_into_iter_loop.rs:10:18\n   |\nLL |         for _ in iterator.into_iter() {}\n   |                  ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator`\n   |\n   = note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::explicit_into_iter_loop)]`\n\nerror: it is more concise to loop over containers instead of using explicit iteration methods\n  --> tests/ui/explicit_into_iter_loop.rs:24:14\n   |\nLL |     for _ in t.into_iter() {}\n   |              ^^^^^^^^^^^^^ help: to write this more concisely, try: `&t`\n\nerror: it is more concise to loop over containers instead of using explicit iteration methods\n  --> tests/ui/explicit_into_iter_loop.rs:28:14\n   |\nLL |     for _ in r.into_iter() {}\n   |              ^^^^^^^^^^^^^ help: to write this more concisely, try: `r`\n\nerror: it is more concise to loop over containers instead of using explicit iteration methods\n  --> tests/ui/explicit_into_iter_loop.rs:37:14\n   |\nLL |     for _ in mr.into_iter() {}\n   |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&*mr`\n\nerror: it is more concise to loop over containers instead of using explicit iteration methods\n  --> tests/ui/explicit_into_iter_loop.rs:50:14\n   |\nLL |     for _ in u.into_iter() {}\n   |              ^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut u`\n\nerror: it is more concise to loop over containers instead of using explicit iteration methods\n  --> tests/ui/explicit_into_iter_loop.rs:54:14\n   |\nLL |     for _ in mr.into_iter() {}\n   |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *mr`\n\nerror: it is more concise to loop over containers instead of using explicit iteration methods\n  --> tests/ui/explicit_into_iter_loop.rs:84:14\n   |\nLL |     for _ in dbg!([1, 2]).into_iter() {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `dbg!([1, 2])`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/explicit_iter_loop.fixed",
    "content": "#![deny(clippy::explicit_iter_loop)]\n#![allow(\n    clippy::linkedlist,\n    clippy::similar_names,\n    clippy::needless_borrow,\n    clippy::deref_addrof,\n    clippy::unnecessary_mut_passed,\n    dead_code,\n    non_local_definitions\n)]\n\nuse core::slice;\nuse std::collections::*;\n\nfn main() {\n    let mut vec = vec![1, 2, 3, 4];\n\n    for _ in &vec {}\n    //~^ explicit_iter_loop\n    for _ in &mut vec {}\n    //~^ explicit_iter_loop\n\n    let rvec = &vec;\n    for _ in rvec {}\n    //~^ explicit_iter_loop\n\n    let rmvec = &mut vec;\n    for _ in rmvec.iter() {}\n    for _ in rmvec.iter_mut() {}\n\n    for _ in &vec {} // these are fine\n    for _ in &mut vec {} // these are fine\n\n    for _ in &[1, 2, 3] {}\n    //~^ explicit_iter_loop\n\n    for _ in (&mut [1, 2, 3]).iter() {}\n\n    for _ in &[0; 32] {}\n    //~^ explicit_iter_loop\n    for _ in &[0; 33] {}\n    //~^ explicit_iter_loop\n\n    let ll: LinkedList<()> = LinkedList::new();\n    for _ in &ll {}\n    //~^ explicit_iter_loop\n    let rll = &ll;\n    for _ in rll {}\n    //~^ explicit_iter_loop\n\n    let vd: VecDeque<()> = VecDeque::new();\n    for _ in &vd {}\n    //~^ explicit_iter_loop\n    let rvd = &vd;\n    for _ in rvd {}\n    //~^ explicit_iter_loop\n\n    let bh: BinaryHeap<()> = BinaryHeap::new();\n    for _ in &bh {}\n    //~^ explicit_iter_loop\n\n    let hm: HashMap<(), ()> = HashMap::new();\n    for _ in &hm {}\n    //~^ explicit_iter_loop\n\n    let bt: BTreeMap<(), ()> = BTreeMap::new();\n    for _ in &bt {}\n    //~^ explicit_iter_loop\n\n    let hs: HashSet<()> = HashSet::new();\n    for _ in &hs {}\n    //~^ explicit_iter_loop\n\n    let bs: BTreeSet<()> = BTreeSet::new();\n    for _ in &bs {}\n    //~^ explicit_iter_loop\n\n    struct NoIntoIter();\n    impl NoIntoIter {\n        fn iter(&self) -> slice::Iter<'_, u8> {\n            unimplemented!()\n        }\n\n        fn iter_mut(&mut self) -> slice::IterMut<'_, u8> {\n            unimplemented!()\n        }\n    }\n    let mut x = NoIntoIter();\n    for _ in x.iter() {} // no error\n    for _ in x.iter_mut() {} // no error\n\n    struct IntoIterDiffTy;\n    impl IntoIterator for &'_ IntoIterDiffTy {\n        type Item = &'static ();\n        type IntoIter = core::slice::Iter<'static, ()>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl IntoIterDiffTy {\n        fn iter(&self) -> core::slice::Iter<'static, i32> {\n            unimplemented!()\n        }\n    }\n    let x = IntoIterDiffTy;\n    for _ in x.iter() {}\n\n    struct IntoIterDiffSig;\n    impl IntoIterator for &'_ IntoIterDiffSig {\n        type Item = &'static ();\n        type IntoIter = core::slice::Iter<'static, ()>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl IntoIterDiffSig {\n        fn iter(&self, _: u32) -> core::slice::Iter<'static, ()> {\n            unimplemented!()\n        }\n    }\n    let x = IntoIterDiffSig;\n    for _ in x.iter(0) {}\n\n    struct IntoIterDiffLt<'a>(&'a ());\n    impl<'a> IntoIterator for &'a IntoIterDiffLt<'_> {\n        type Item = &'a ();\n        type IntoIter = core::slice::Iter<'a, ()>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl<'a> IntoIterDiffLt<'a> {\n        fn iter(&self) -> core::slice::Iter<'a, ()> {\n            unimplemented!()\n        }\n    }\n    let x = IntoIterDiffLt(&());\n    for _ in x.iter() {}\n\n    struct CustomType;\n    impl<'a> IntoIterator for &'a CustomType {\n        type Item = &'a u32;\n        type IntoIter = core::slice::Iter<'a, u32>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl<'a> IntoIterator for &'a mut CustomType {\n        type Item = &'a mut u32;\n        type IntoIter = core::slice::IterMut<'a, u32>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl CustomType {\n        fn iter(&self) -> <&'_ Self as IntoIterator>::IntoIter {\n            panic!()\n        }\n\n        fn iter_mut(&mut self) -> core::slice::IterMut<'_, u32> {\n            panic!()\n        }\n    }\n    let mut x = CustomType;\n    for _ in &x {}\n    //~^ explicit_iter_loop\n    for _ in &mut x {}\n    //~^ explicit_iter_loop\n\n    let r = &x;\n    for _ in r {}\n    //~^ explicit_iter_loop\n}\n\n#[clippy::msrv = \"1.79\"]\npub fn issue_13184() {\n    // https://github.com/rust-lang/rust-clippy/issues/13184\n    // No need to fix, as IntoIterator for Box is valid starting from 1.80\n    let mut values: Box<[u32]> = Box::new([1, 2]);\n    for _ in values.iter() {}\n    for _ in values.iter_mut() {}\n\n    let rvalues = &values;\n    for _ in rvalues.iter() {}\n}\n\nfn issue14630() {\n    macro_rules! mac {\n        (iter $e:expr) => {\n            $e.into_iter()\n        };\n    }\n\n    for _ in &dbg!([1, 2]) {}\n    //~^ explicit_iter_loop\n\n    for _ in mac!(iter [1, 2]) {}\n}\n"
  },
  {
    "path": "tests/ui/explicit_iter_loop.rs",
    "content": "#![deny(clippy::explicit_iter_loop)]\n#![allow(\n    clippy::linkedlist,\n    clippy::similar_names,\n    clippy::needless_borrow,\n    clippy::deref_addrof,\n    clippy::unnecessary_mut_passed,\n    dead_code,\n    non_local_definitions\n)]\n\nuse core::slice;\nuse std::collections::*;\n\nfn main() {\n    let mut vec = vec![1, 2, 3, 4];\n\n    for _ in vec.iter() {}\n    //~^ explicit_iter_loop\n    for _ in vec.iter_mut() {}\n    //~^ explicit_iter_loop\n\n    let rvec = &vec;\n    for _ in rvec.iter() {}\n    //~^ explicit_iter_loop\n\n    let rmvec = &mut vec;\n    for _ in rmvec.iter() {}\n    for _ in rmvec.iter_mut() {}\n\n    for _ in &vec {} // these are fine\n    for _ in &mut vec {} // these are fine\n\n    for _ in [1, 2, 3].iter() {}\n    //~^ explicit_iter_loop\n\n    for _ in (&mut [1, 2, 3]).iter() {}\n\n    for _ in [0; 32].iter() {}\n    //~^ explicit_iter_loop\n    for _ in [0; 33].iter() {}\n    //~^ explicit_iter_loop\n\n    let ll: LinkedList<()> = LinkedList::new();\n    for _ in ll.iter() {}\n    //~^ explicit_iter_loop\n    let rll = &ll;\n    for _ in rll.iter() {}\n    //~^ explicit_iter_loop\n\n    let vd: VecDeque<()> = VecDeque::new();\n    for _ in vd.iter() {}\n    //~^ explicit_iter_loop\n    let rvd = &vd;\n    for _ in rvd.iter() {}\n    //~^ explicit_iter_loop\n\n    let bh: BinaryHeap<()> = BinaryHeap::new();\n    for _ in bh.iter() {}\n    //~^ explicit_iter_loop\n\n    let hm: HashMap<(), ()> = HashMap::new();\n    for _ in hm.iter() {}\n    //~^ explicit_iter_loop\n\n    let bt: BTreeMap<(), ()> = BTreeMap::new();\n    for _ in bt.iter() {}\n    //~^ explicit_iter_loop\n\n    let hs: HashSet<()> = HashSet::new();\n    for _ in hs.iter() {}\n    //~^ explicit_iter_loop\n\n    let bs: BTreeSet<()> = BTreeSet::new();\n    for _ in bs.iter() {}\n    //~^ explicit_iter_loop\n\n    struct NoIntoIter();\n    impl NoIntoIter {\n        fn iter(&self) -> slice::Iter<'_, u8> {\n            unimplemented!()\n        }\n\n        fn iter_mut(&mut self) -> slice::IterMut<'_, u8> {\n            unimplemented!()\n        }\n    }\n    let mut x = NoIntoIter();\n    for _ in x.iter() {} // no error\n    for _ in x.iter_mut() {} // no error\n\n    struct IntoIterDiffTy;\n    impl IntoIterator for &'_ IntoIterDiffTy {\n        type Item = &'static ();\n        type IntoIter = core::slice::Iter<'static, ()>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl IntoIterDiffTy {\n        fn iter(&self) -> core::slice::Iter<'static, i32> {\n            unimplemented!()\n        }\n    }\n    let x = IntoIterDiffTy;\n    for _ in x.iter() {}\n\n    struct IntoIterDiffSig;\n    impl IntoIterator for &'_ IntoIterDiffSig {\n        type Item = &'static ();\n        type IntoIter = core::slice::Iter<'static, ()>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl IntoIterDiffSig {\n        fn iter(&self, _: u32) -> core::slice::Iter<'static, ()> {\n            unimplemented!()\n        }\n    }\n    let x = IntoIterDiffSig;\n    for _ in x.iter(0) {}\n\n    struct IntoIterDiffLt<'a>(&'a ());\n    impl<'a> IntoIterator for &'a IntoIterDiffLt<'_> {\n        type Item = &'a ();\n        type IntoIter = core::slice::Iter<'a, ()>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl<'a> IntoIterDiffLt<'a> {\n        fn iter(&self) -> core::slice::Iter<'a, ()> {\n            unimplemented!()\n        }\n    }\n    let x = IntoIterDiffLt(&());\n    for _ in x.iter() {}\n\n    struct CustomType;\n    impl<'a> IntoIterator for &'a CustomType {\n        type Item = &'a u32;\n        type IntoIter = core::slice::Iter<'a, u32>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl<'a> IntoIterator for &'a mut CustomType {\n        type Item = &'a mut u32;\n        type IntoIter = core::slice::IterMut<'a, u32>;\n        fn into_iter(self) -> Self::IntoIter {\n            unimplemented!()\n        }\n    }\n    impl CustomType {\n        fn iter(&self) -> <&'_ Self as IntoIterator>::IntoIter {\n            panic!()\n        }\n\n        fn iter_mut(&mut self) -> core::slice::IterMut<'_, u32> {\n            panic!()\n        }\n    }\n    let mut x = CustomType;\n    for _ in x.iter() {}\n    //~^ explicit_iter_loop\n    for _ in x.iter_mut() {}\n    //~^ explicit_iter_loop\n\n    let r = &x;\n    for _ in r.iter() {}\n    //~^ explicit_iter_loop\n}\n\n#[clippy::msrv = \"1.79\"]\npub fn issue_13184() {\n    // https://github.com/rust-lang/rust-clippy/issues/13184\n    // No need to fix, as IntoIterator for Box is valid starting from 1.80\n    let mut values: Box<[u32]> = Box::new([1, 2]);\n    for _ in values.iter() {}\n    for _ in values.iter_mut() {}\n\n    let rvalues = &values;\n    for _ in rvalues.iter() {}\n}\n\nfn issue14630() {\n    macro_rules! mac {\n        (iter $e:expr) => {\n            $e.into_iter()\n        };\n    }\n\n    for _ in dbg!([1, 2]).iter() {}\n    //~^ explicit_iter_loop\n\n    for _ in mac!(iter [1, 2]) {}\n}\n"
  },
  {
    "path": "tests/ui/explicit_iter_loop.stderr",
    "content": "error: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:18:14\n   |\nLL |     for _ in vec.iter() {}\n   |              ^^^^^^^^^^ help: to write this more concisely, try: `&vec`\n   |\nnote: the lint level is defined here\n  --> tests/ui/explicit_iter_loop.rs:1:9\n   |\nLL | #![deny(clippy::explicit_iter_loop)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:20:14\n   |\nLL |     for _ in vec.iter_mut() {}\n   |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:24:14\n   |\nLL |     for _ in rvec.iter() {}\n   |              ^^^^^^^^^^^ help: to write this more concisely, try: `rvec`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:34:14\n   |\nLL |     for _ in [1, 2, 3].iter() {}\n   |              ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:39:14\n   |\nLL |     for _ in [0; 32].iter() {}\n   |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:41:14\n   |\nLL |     for _ in [0; 33].iter() {}\n   |              ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 33]`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:45:14\n   |\nLL |     for _ in ll.iter() {}\n   |              ^^^^^^^^^ help: to write this more concisely, try: `&ll`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:48:14\n   |\nLL |     for _ in rll.iter() {}\n   |              ^^^^^^^^^^ help: to write this more concisely, try: `rll`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:52:14\n   |\nLL |     for _ in vd.iter() {}\n   |              ^^^^^^^^^ help: to write this more concisely, try: `&vd`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:55:14\n   |\nLL |     for _ in rvd.iter() {}\n   |              ^^^^^^^^^^ help: to write this more concisely, try: `rvd`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:59:14\n   |\nLL |     for _ in bh.iter() {}\n   |              ^^^^^^^^^ help: to write this more concisely, try: `&bh`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:63:14\n   |\nLL |     for _ in hm.iter() {}\n   |              ^^^^^^^^^ help: to write this more concisely, try: `&hm`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:67:14\n   |\nLL |     for _ in bt.iter() {}\n   |              ^^^^^^^^^ help: to write this more concisely, try: `&bt`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:71:14\n   |\nLL |     for _ in hs.iter() {}\n   |              ^^^^^^^^^ help: to write this more concisely, try: `&hs`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:75:14\n   |\nLL |     for _ in bs.iter() {}\n   |              ^^^^^^^^^ help: to write this more concisely, try: `&bs`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:165:14\n   |\nLL |     for _ in x.iter() {}\n   |              ^^^^^^^^ help: to write this more concisely, try: `&x`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:167:14\n   |\nLL |     for _ in x.iter_mut() {}\n   |              ^^^^^^^^^^^^ help: to write this more concisely, try: `&mut x`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:171:14\n   |\nLL |     for _ in r.iter() {}\n   |              ^^^^^^^^ help: to write this more concisely, try: `r`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui/explicit_iter_loop.rs:194:14\n   |\nLL |     for _ in dbg!([1, 2]).iter() {}\n   |              ^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&dbg!([1, 2])`\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/explicit_write.fixed",
    "content": "#![warn(clippy::explicit_write)]\n#![allow(unused_imports)]\n\nfn stdout() -> String {\n    String::new()\n}\n\nfn stderr() -> String {\n    String::new()\n}\n\nmacro_rules! one {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    // these should warn\n    {\n        use std::io::Write;\n        print!(\"test\");\n        //~^ explicit_write\n        eprint!(\"test\");\n        //~^ explicit_write\n        println!(\"test\");\n        //~^ explicit_write\n        eprintln!(\"test\");\n        //~^ explicit_write\n        print!(\"test\");\n        //~^ explicit_write\n        eprint!(\"test\");\n        //~^ explicit_write\n\n        // including newlines\n        println!(\"test\\ntest\");\n        //~^ explicit_write\n        eprintln!(\"test\\ntest\");\n        //~^ explicit_write\n\n        let value = 1;\n        eprintln!(\"with {value}\");\n        //~^ explicit_write\n        eprintln!(\"with {} {}\", 2, value);\n        //~^ explicit_write\n        eprintln!(\"with {value}\");\n        //~^ explicit_write\n        eprintln!(\"macro arg {}\", one!());\n        //~^ explicit_write\n        let width = 2;\n        eprintln!(\"{value:w$}\", w = width);\n        //~^ explicit_write\n    }\n    // these should not warn, different destination\n    {\n        use std::fmt::Write;\n        let mut s = String::new();\n        write!(s, \"test\").unwrap();\n        write!(s, \"test\").unwrap();\n        writeln!(s, \"test\").unwrap();\n        writeln!(s, \"test\").unwrap();\n        s.write_fmt(format_args!(\"test\")).unwrap();\n        s.write_fmt(format_args!(\"test\")).unwrap();\n        write!(stdout(), \"test\").unwrap();\n        write!(stderr(), \"test\").unwrap();\n        writeln!(stdout(), \"test\").unwrap();\n        writeln!(stderr(), \"test\").unwrap();\n        stdout().write_fmt(format_args!(\"test\")).unwrap();\n        stderr().write_fmt(format_args!(\"test\")).unwrap();\n    }\n    // these should not warn, no unwrap\n    {\n        use std::io::Write;\n        std::io::stdout().write_fmt(format_args!(\"test\")).expect(\"no stdout\");\n        std::io::stderr().write_fmt(format_args!(\"test\")).expect(\"no stderr\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/explicit_write.rs",
    "content": "#![warn(clippy::explicit_write)]\n#![allow(unused_imports)]\n\nfn stdout() -> String {\n    String::new()\n}\n\nfn stderr() -> String {\n    String::new()\n}\n\nmacro_rules! one {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    // these should warn\n    {\n        use std::io::Write;\n        write!(std::io::stdout(), \"test\").unwrap();\n        //~^ explicit_write\n        write!(std::io::stderr(), \"test\").unwrap();\n        //~^ explicit_write\n        writeln!(std::io::stdout(), \"test\").unwrap();\n        //~^ explicit_write\n        writeln!(std::io::stderr(), \"test\").unwrap();\n        //~^ explicit_write\n        std::io::stdout().write_fmt(format_args!(\"test\")).unwrap();\n        //~^ explicit_write\n        std::io::stderr().write_fmt(format_args!(\"test\")).unwrap();\n        //~^ explicit_write\n\n        // including newlines\n        writeln!(std::io::stdout(), \"test\\ntest\").unwrap();\n        //~^ explicit_write\n        writeln!(std::io::stderr(), \"test\\ntest\").unwrap();\n        //~^ explicit_write\n\n        let value = 1;\n        writeln!(std::io::stderr(), \"with {value}\").unwrap();\n        //~^ explicit_write\n        writeln!(std::io::stderr(), \"with {} {}\", 2, value).unwrap();\n        //~^ explicit_write\n        writeln!(std::io::stderr(), \"with {value}\").unwrap();\n        //~^ explicit_write\n        writeln!(std::io::stderr(), \"macro arg {}\", one!()).unwrap();\n        //~^ explicit_write\n        let width = 2;\n        writeln!(std::io::stderr(), \"{value:w$}\", w = width).unwrap();\n        //~^ explicit_write\n    }\n    // these should not warn, different destination\n    {\n        use std::fmt::Write;\n        let mut s = String::new();\n        write!(s, \"test\").unwrap();\n        write!(s, \"test\").unwrap();\n        writeln!(s, \"test\").unwrap();\n        writeln!(s, \"test\").unwrap();\n        s.write_fmt(format_args!(\"test\")).unwrap();\n        s.write_fmt(format_args!(\"test\")).unwrap();\n        write!(stdout(), \"test\").unwrap();\n        write!(stderr(), \"test\").unwrap();\n        writeln!(stdout(), \"test\").unwrap();\n        writeln!(stderr(), \"test\").unwrap();\n        stdout().write_fmt(format_args!(\"test\")).unwrap();\n        stderr().write_fmt(format_args!(\"test\")).unwrap();\n    }\n    // these should not warn, no unwrap\n    {\n        use std::io::Write;\n        std::io::stdout().write_fmt(format_args!(\"test\")).expect(\"no stdout\");\n        std::io::stderr().write_fmt(format_args!(\"test\")).expect(\"no stderr\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/explicit_write.stderr",
    "content": "error: use of `write!(stdout(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:22:9\n   |\nLL |         write!(std::io::stdout(), \"test\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `print!(\"test\")`\n   |\n   = note: `-D clippy::explicit-write` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::explicit_write)]`\n\nerror: use of `write!(stderr(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:24:9\n   |\nLL |         write!(std::io::stderr(), \"test\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprint!(\"test\")`\n\nerror: use of `writeln!(stdout(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:26:9\n   |\nLL |         writeln!(std::io::stdout(), \"test\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!(\"test\")`\n\nerror: use of `writeln!(stderr(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:28:9\n   |\nLL |         writeln!(std::io::stderr(), \"test\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!(\"test\")`\n\nerror: use of `stdout().write_fmt(...).unwrap()`\n  --> tests/ui/explicit_write.rs:30:9\n   |\nLL |         std::io::stdout().write_fmt(format_args!(\"test\")).unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `print!(\"test\")`\n\nerror: use of `stderr().write_fmt(...).unwrap()`\n  --> tests/ui/explicit_write.rs:32:9\n   |\nLL |         std::io::stderr().write_fmt(format_args!(\"test\")).unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprint!(\"test\")`\n\nerror: use of `writeln!(stdout(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:36:9\n   |\nLL |         writeln!(std::io::stdout(), \"test\\ntest\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `println!(\"test\\ntest\")`\n\nerror: use of `writeln!(stderr(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:38:9\n   |\nLL |         writeln!(std::io::stderr(), \"test\\ntest\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!(\"test\\ntest\")`\n\nerror: use of `writeln!(stderr(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:42:9\n   |\nLL |         writeln!(std::io::stderr(), \"with {value}\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!(\"with {value}\")`\n\nerror: use of `writeln!(stderr(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:44:9\n   |\nLL |         writeln!(std::io::stderr(), \"with {} {}\", 2, value).unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!(\"with {} {}\", 2, value)`\n\nerror: use of `writeln!(stderr(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:46:9\n   |\nLL |         writeln!(std::io::stderr(), \"with {value}\").unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!(\"with {value}\")`\n\nerror: use of `writeln!(stderr(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:48:9\n   |\nLL |         writeln!(std::io::stderr(), \"macro arg {}\", one!()).unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!(\"macro arg {}\", one!())`\n\nerror: use of `writeln!(stderr(), ...).unwrap()`\n  --> tests/ui/explicit_write.rs:51:9\n   |\nLL |         writeln!(std::io::stderr(), \"{value:w$}\", w = width).unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `eprintln!(\"{value:w$}\", w = width)`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/explicit_write_in_test.rs",
    "content": "//@ check-pass\n#![warn(clippy::explicit_write)]\n\n#[test]\nfn test() {\n    use std::io::Write;\n    writeln!(std::io::stderr(), \"I am an explicit write.\").unwrap();\n    eprintln!(\"I am not an explicit write.\");\n}\n"
  },
  {
    "path": "tests/ui/extend_with_drain.fixed",
    "content": "#![warn(clippy::extend_with_drain)]\n#![allow(clippy::iter_with_drain)]\nuse std::collections::BinaryHeap;\nfn main() {\n    //gets linted\n    let mut vec1 = vec![0u8; 1024];\n    let mut vec2: std::vec::Vec<u8> = Vec::new();\n    vec2.append(&mut vec1);\n    //~^ extend_with_drain\n\n    let mut vec3 = vec![0u8; 1024];\n    let mut vec4: std::vec::Vec<u8> = Vec::new();\n\n    vec4.append(&mut vec3);\n    //~^ extend_with_drain\n\n    let mut vec11: std::vec::Vec<u8> = Vec::new();\n\n    vec11.append(&mut return_vector());\n    //~^ extend_with_drain\n\n    //won't get linted it doesn't move the entire content of a vec into another\n    let mut test1 = vec![0u8, 10];\n    let mut test2: std::vec::Vec<u8> = Vec::new();\n\n    test2.extend(test1.drain(4..10));\n\n    let mut vec3 = vec![0u8; 104];\n    let mut vec7: std::vec::Vec<u8> = Vec::new();\n\n    vec3.append(&mut vec7);\n\n    let mut vec5 = vec![0u8; 1024];\n    let mut vec6: std::vec::Vec<u8> = Vec::new();\n\n    vec5.extend(vec6.drain(..4));\n\n    let mut vec9: std::vec::Vec<u8> = Vec::new();\n\n    return_vector().append(&mut vec9);\n\n    //won't get linted because it is not a vec\n\n    let mut heap = BinaryHeap::from(vec![1, 3]);\n    let mut heap2 = BinaryHeap::from(vec![]);\n    heap2.extend(heap.drain());\n\n    let mut x = vec![0, 1, 2, 3, 5];\n    let ref_x = &mut x;\n    let mut y = Vec::new();\n    y.append(ref_x);\n    //~^ extend_with_drain\n}\n\nfn return_vector() -> Vec<u8> {\n    let mut new_vector = vec![];\n\n    for i in 1..10 {\n        new_vector.push(i)\n    }\n\n    new_vector\n}\n"
  },
  {
    "path": "tests/ui/extend_with_drain.rs",
    "content": "#![warn(clippy::extend_with_drain)]\n#![allow(clippy::iter_with_drain)]\nuse std::collections::BinaryHeap;\nfn main() {\n    //gets linted\n    let mut vec1 = vec![0u8; 1024];\n    let mut vec2: std::vec::Vec<u8> = Vec::new();\n    vec2.extend(vec1.drain(..));\n    //~^ extend_with_drain\n\n    let mut vec3 = vec![0u8; 1024];\n    let mut vec4: std::vec::Vec<u8> = Vec::new();\n\n    vec4.extend(vec3.drain(..));\n    //~^ extend_with_drain\n\n    let mut vec11: std::vec::Vec<u8> = Vec::new();\n\n    vec11.extend(return_vector().drain(..));\n    //~^ extend_with_drain\n\n    //won't get linted it doesn't move the entire content of a vec into another\n    let mut test1 = vec![0u8, 10];\n    let mut test2: std::vec::Vec<u8> = Vec::new();\n\n    test2.extend(test1.drain(4..10));\n\n    let mut vec3 = vec![0u8; 104];\n    let mut vec7: std::vec::Vec<u8> = Vec::new();\n\n    vec3.append(&mut vec7);\n\n    let mut vec5 = vec![0u8; 1024];\n    let mut vec6: std::vec::Vec<u8> = Vec::new();\n\n    vec5.extend(vec6.drain(..4));\n\n    let mut vec9: std::vec::Vec<u8> = Vec::new();\n\n    return_vector().append(&mut vec9);\n\n    //won't get linted because it is not a vec\n\n    let mut heap = BinaryHeap::from(vec![1, 3]);\n    let mut heap2 = BinaryHeap::from(vec![]);\n    heap2.extend(heap.drain());\n\n    let mut x = vec![0, 1, 2, 3, 5];\n    let ref_x = &mut x;\n    let mut y = Vec::new();\n    y.extend(ref_x.drain(..));\n    //~^ extend_with_drain\n}\n\nfn return_vector() -> Vec<u8> {\n    let mut new_vector = vec![];\n\n    for i in 1..10 {\n        new_vector.push(i)\n    }\n\n    new_vector\n}\n"
  },
  {
    "path": "tests/ui/extend_with_drain.stderr",
    "content": "error: use of `extend` instead of `append` for adding the full range of a second vector\n  --> tests/ui/extend_with_drain.rs:8:5\n   |\nLL |     vec2.extend(vec1.drain(..));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec2.append(&mut vec1)`\n   |\n   = note: `-D clippy::extend-with-drain` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::extend_with_drain)]`\n\nerror: use of `extend` instead of `append` for adding the full range of a second vector\n  --> tests/ui/extend_with_drain.rs:14:5\n   |\nLL |     vec4.extend(vec3.drain(..));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec4.append(&mut vec3)`\n\nerror: use of `extend` instead of `append` for adding the full range of a second vector\n  --> tests/ui/extend_with_drain.rs:19:5\n   |\nLL |     vec11.extend(return_vector().drain(..));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec11.append(&mut return_vector())`\n\nerror: use of `extend` instead of `append` for adding the full range of a second vector\n  --> tests/ui/extend_with_drain.rs:51:5\n   |\nLL |     y.extend(ref_x.drain(..));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `y.append(ref_x)`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/extra_unused_lifetimes.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n//@aux-build:proc_macros.rs\n\n#![allow(\n    unused,\n    dead_code,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_value,\n    clippy::needless_arbitrary_self_type\n)]\n#![warn(clippy::extra_unused_lifetimes)]\n\n#[macro_use]\nextern crate proc_macro_derive;\nextern crate proc_macros;\n\nfn empty() {}\n\nfn used_lt<'a>(x: &'a u8) {}\n\nfn unused_lt<'a>(x: u8) {}\n//~^ extra_unused_lifetimes\n\nfn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) {\n    // 'a is useless here since it's not directly bound\n}\n\nfn lt_return<'a, 'b: 'a>(x: &'b u8) -> &'a u8 {\n    panic!()\n}\n\nfn lt_return_only<'a>() -> &'a u8 {\n    panic!()\n}\n\nfn unused_lt_blergh<'a>(x: Option<Box<dyn Send + 'a>>) {}\n\ntrait Foo<'a> {\n    fn x(&self, a: &'a u8);\n}\n\nimpl<'a> Foo<'a> for u8 {\n    fn x(&self, a: &'a u8) {}\n}\n\nstruct Bar;\n\nimpl Bar {\n    fn x<'a>(&self) {}\n    //~^ extra_unused_lifetimes\n}\n\n// test for #489 (used lifetimes in bounds)\npub fn parse<'a, I: Iterator<Item = &'a str>>(_it: &mut I) {\n    unimplemented!()\n}\npub fn parse2<'a, I>(_it: &mut I)\nwhere\n    I: Iterator<Item = &'a str>,\n{\n    unimplemented!()\n}\n\nstruct X {\n    x: u32,\n}\n\nimpl X {\n    fn self_ref_with_lifetime<'a>(&'a self) {}\n    fn explicit_self_with_lifetime<'a>(self: &'a Self) {}\n}\n\n// Methods implementing traits must have matching lifetimes\nmod issue4291 {\n    trait BadTrait {\n        fn unused_lt<'a>(x: u8) {}\n        //~^ extra_unused_lifetimes\n    }\n\n    impl BadTrait for () {\n        fn unused_lt<'a>(_x: u8) {}\n    }\n}\n\nmod issue6437 {\n    pub struct Scalar;\n\n    impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar {\n        //~^ extra_unused_lifetimes\n        fn add_assign(&mut self, _rhs: &Scalar) {\n            unimplemented!();\n        }\n    }\n\n    impl<'b> Scalar {\n        //~^ extra_unused_lifetimes\n        pub fn something<'c>() -> Self {\n            //~^ extra_unused_lifetimes\n            Self\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/8737#pullrequestreview-951268213\nmod first_case {\n    use serde::de::Visitor;\n    pub trait Expected {\n        fn fmt(&self, formatter: &mut std::fmt::Formatter);\n    }\n\n    impl<'de, T> Expected for T\n    where\n        T: Visitor<'de>,\n    {\n        fn fmt(&self, formatter: &mut std::fmt::Formatter) {}\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/8737#pullrequestreview-951268213\nmod second_case {\n    pub trait Source {\n        fn hey();\n    }\n\n    // Should lint. The response to the above comment incorrectly called this a false positive. The\n    // lifetime `'a` can be removed, as demonstrated below.\n    impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {\n        //~^ extra_unused_lifetimes\n        fn hey() {}\n    }\n\n    struct OtherBox<T: ?Sized>(Box<T>);\n\n    impl<T: Source + ?Sized> Source for OtherBox<T> {\n        fn hey() {}\n    }\n}\n\n// Should not lint\n#[derive(ExtraLifetimeDerive)]\nstruct Human<'a> {\n    pub bones: i32,\n    pub name: &'a str,\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/13578\nmod issue_13578 {\n    pub trait Foo {}\n\n    impl<'a, T: 'a> Foo for Option<T> where &'a T: Foo {}\n}\n\n// no lint on proc macro generated code\nmod proc_macro_generated {\n    use proc_macros::external;\n\n    // no lint on external macro (extra unused lifetimes in impl block)\n    external! {\n        struct ExternalImplStruct;\n\n        impl<'a> ExternalImplStruct {\n            fn foo() {}\n        }\n    }\n\n    // no lint on external macro (extra unused lifetimes in method)\n    external! {\n        struct ExternalMethodStruct;\n\n        impl ExternalMethodStruct {\n            fn bar<'a>(&self) {}\n        }\n    }\n\n    // no lint on external macro (extra unused lifetimes in trait method)\n    external! {\n        trait ExternalUnusedLifetimeTrait {\n            fn unused_lt<'a>(x: u8) {}\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extra_unused_lifetimes.stderr",
    "content": "error: this lifetime isn't used in the function definition\n  --> tests/ui/extra_unused_lifetimes.rs:21:14\n   |\nLL | fn unused_lt<'a>(x: u8) {}\n   |              ^^\n   |\n   = note: `-D clippy::extra-unused-lifetimes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::extra_unused_lifetimes)]`\n\nerror: this lifetime isn't used in the function definition\n  --> tests/ui/extra_unused_lifetimes.rs:49:10\n   |\nLL |     fn x<'a>(&self) {}\n   |          ^^\n\nerror: this lifetime isn't used in the function definition\n  --> tests/ui/extra_unused_lifetimes.rs:76:22\n   |\nLL |         fn unused_lt<'a>(x: u8) {}\n   |                      ^^\n\nerror: this lifetime isn't used in the impl\n  --> tests/ui/extra_unused_lifetimes.rs:88:10\n   |\nLL |     impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar {\n   |          ^^\n\nerror: this lifetime isn't used in the impl\n  --> tests/ui/extra_unused_lifetimes.rs:95:10\n   |\nLL |     impl<'b> Scalar {\n   |          ^^\n\nerror: this lifetime isn't used in the function definition\n  --> tests/ui/extra_unused_lifetimes.rs:97:26\n   |\nLL |         pub fn something<'c>() -> Self {\n   |                          ^^\n\nerror: this lifetime isn't used in the impl\n  --> tests/ui/extra_unused_lifetimes.rs:127:10\n   |\nLL |     impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {\n   |          ^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/extra_unused_type_parameters.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![allow(unused, clippy::needless_lifetimes)]\n#![warn(clippy::extra_unused_type_parameters)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nfn unused_ty(x: u8) {\n    //~^ extra_unused_type_parameters\n    unimplemented!()\n}\n\nfn unused_multi(x: u8) {\n    //~^ extra_unused_type_parameters\n    unimplemented!()\n}\n\nfn unused_with_lt<'a>(x: &'a u8) {\n    //~^ extra_unused_type_parameters\n    unimplemented!()\n}\n\nfn used_ty<T>(x: T, y: u8) {}\n\nfn used_ref<'a, T>(x: &'a T) {}\n\nfn used_ret<T: Default>(x: u8) -> T {\n    T::default()\n}\n\nfn unused_bounded<U>(x: U) {\n    //~^ extra_unused_type_parameters\n    unimplemented!();\n}\n\nfn some_unused<B, C>(b: B, c: C) {\n    //~^ extra_unused_type_parameters\n    unimplemented!();\n}\n\nfn used_opaque<A>(iter: impl Iterator<Item = A>) -> usize {\n    iter.count()\n}\n\nfn used_ret_opaque<A>() -> impl Iterator<Item = A> {\n    std::iter::empty()\n}\n\nfn used_vec_box<T>(x: Vec<Box<T>>) {}\n\nfn used_body<T: Default + ToString>() -> String {\n    T::default().to_string()\n}\n\nfn used_closure<T: Default + ToString>() -> impl Fn() {\n    || println!(\"{}\", T::default().to_string())\n}\n\nstruct S;\n\nimpl S {\n    fn unused_ty_impl(&self) {\n        //~^ extra_unused_type_parameters\n        unimplemented!()\n    }\n}\n\n// Don't lint on trait methods\ntrait Foo {\n    fn bar<T>(&self);\n}\n\nimpl Foo for S {\n    fn bar<T>(&self) {}\n}\n\nfn skip_index<A, Iter>(iter: Iter, index: usize) -> impl Iterator<Item = A>\nwhere\n    Iter: Iterator<Item = A>,\n{\n    iter.enumerate()\n        .filter_map(move |(i, a)| if i == index { None } else { Some(a) })\n}\n\nfn unused_opaque(dummy: impl Default) {\n    //~^ extra_unused_type_parameters\n    unimplemented!()\n}\n\nmod unexported_trait_bounds {\n    mod private {\n        pub trait Private {}\n    }\n\n    fn priv_trait_bound<T: private::Private>() {\n        unimplemented!();\n    }\n\n    fn unused_with_priv_trait_bound<T: private::Private>() {\n        //~^ extra_unused_type_parameters\n        unimplemented!();\n    }\n}\n\nmod issue10319 {\n    fn assert_send<T: Send>() {}\n\n    fn assert_send_where<T>()\n    where\n        T: Send,\n    {\n    }\n}\n\nwith_span!(\n    span\n\n    fn should_not_lint<T>(x: u8) {\n        unimplemented!()\n    }\n);\n\nmod issue11302 {\n    use std::fmt::Debug;\n    use std::marker::PhantomData;\n\n    #[derive(Debug)]\n    struct Wrapper<T>(PhantomData<T>);\n\n    fn store<T: 'static>(v: &mut Vec<Box<dyn Debug>>)\n    where\n        Wrapper<T>: Debug,\n    {\n        v.push(Box::new(Wrapper(PhantomData)));\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extra_unused_type_parameters.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![allow(unused, clippy::needless_lifetimes)]\n#![warn(clippy::extra_unused_type_parameters)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nfn unused_ty<T>(x: u8) {\n    //~^ extra_unused_type_parameters\n    unimplemented!()\n}\n\nfn unused_multi<T, U>(x: u8) {\n    //~^ extra_unused_type_parameters\n    unimplemented!()\n}\n\nfn unused_with_lt<'a, T>(x: &'a u8) {\n    //~^ extra_unused_type_parameters\n    unimplemented!()\n}\n\nfn used_ty<T>(x: T, y: u8) {}\n\nfn used_ref<'a, T>(x: &'a T) {}\n\nfn used_ret<T: Default>(x: u8) -> T {\n    T::default()\n}\n\nfn unused_bounded<T: Default, U, V: Default>(x: U) {\n    //~^ extra_unused_type_parameters\n    unimplemented!();\n}\n\nfn some_unused<A, B, C, D: Iterator<Item = (B, C)>, E>(b: B, c: C) {\n    //~^ extra_unused_type_parameters\n    unimplemented!();\n}\n\nfn used_opaque<A>(iter: impl Iterator<Item = A>) -> usize {\n    iter.count()\n}\n\nfn used_ret_opaque<A>() -> impl Iterator<Item = A> {\n    std::iter::empty()\n}\n\nfn used_vec_box<T>(x: Vec<Box<T>>) {}\n\nfn used_body<T: Default + ToString>() -> String {\n    T::default().to_string()\n}\n\nfn used_closure<T: Default + ToString>() -> impl Fn() {\n    || println!(\"{}\", T::default().to_string())\n}\n\nstruct S;\n\nimpl S {\n    fn unused_ty_impl<T>(&self) {\n        //~^ extra_unused_type_parameters\n        unimplemented!()\n    }\n}\n\n// Don't lint on trait methods\ntrait Foo {\n    fn bar<T>(&self);\n}\n\nimpl Foo for S {\n    fn bar<T>(&self) {}\n}\n\nfn skip_index<A, Iter>(iter: Iter, index: usize) -> impl Iterator<Item = A>\nwhere\n    Iter: Iterator<Item = A>,\n{\n    iter.enumerate()\n        .filter_map(move |(i, a)| if i == index { None } else { Some(a) })\n}\n\nfn unused_opaque<A, B>(dummy: impl Default) {\n    //~^ extra_unused_type_parameters\n    unimplemented!()\n}\n\nmod unexported_trait_bounds {\n    mod private {\n        pub trait Private {}\n    }\n\n    fn priv_trait_bound<T: private::Private>() {\n        unimplemented!();\n    }\n\n    fn unused_with_priv_trait_bound<T: private::Private, U>() {\n        //~^ extra_unused_type_parameters\n        unimplemented!();\n    }\n}\n\nmod issue10319 {\n    fn assert_send<T: Send>() {}\n\n    fn assert_send_where<T>()\n    where\n        T: Send,\n    {\n    }\n}\n\nwith_span!(\n    span\n\n    fn should_not_lint<T>(x: u8) {\n        unimplemented!()\n    }\n);\n\nmod issue11302 {\n    use std::fmt::Debug;\n    use std::marker::PhantomData;\n\n    #[derive(Debug)]\n    struct Wrapper<T>(PhantomData<T>);\n\n    fn store<T: 'static>(v: &mut Vec<Box<dyn Debug>>)\n    where\n        Wrapper<T>: Debug,\n    {\n        v.push(Box::new(Wrapper(PhantomData)));\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extra_unused_type_parameters.stderr",
    "content": "error: type parameter `T` goes unused in function definition\n  --> tests/ui/extra_unused_type_parameters.rs:9:13\n   |\nLL | fn unused_ty<T>(x: u8) {\n   |             ^^^\n   |\n   = note: `-D clippy::extra-unused-type-parameters` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::extra_unused_type_parameters)]`\nhelp: consider removing the parameter\n   |\nLL - fn unused_ty<T>(x: u8) {\nLL + fn unused_ty(x: u8) {\n   |\n\nerror: type parameters go unused in function definition: T, U\n  --> tests/ui/extra_unused_type_parameters.rs:14:16\n   |\nLL | fn unused_multi<T, U>(x: u8) {\n   |                ^^^^^^\n   |\nhelp: consider removing the parameters\n   |\nLL - fn unused_multi<T, U>(x: u8) {\nLL + fn unused_multi(x: u8) {\n   |\n\nerror: type parameter `T` goes unused in function definition\n  --> tests/ui/extra_unused_type_parameters.rs:19:21\n   |\nLL | fn unused_with_lt<'a, T>(x: &'a u8) {\n   |                     ^^^\n   |\nhelp: consider removing the parameter\n   |\nLL - fn unused_with_lt<'a, T>(x: &'a u8) {\nLL + fn unused_with_lt<'a>(x: &'a u8) {\n   |\n\nerror: type parameters go unused in function definition: T, V\n  --> tests/ui/extra_unused_type_parameters.rs:32:19\n   |\nLL | fn unused_bounded<T: Default, U, V: Default>(x: U) {\n   |                   ^^^^^^^^^^^^ ^^^^^^^^^^^^\n   |\nhelp: consider removing the parameters\n   |\nLL - fn unused_bounded<T: Default, U, V: Default>(x: U) {\nLL + fn unused_bounded<U>(x: U) {\n   |\n\nerror: type parameters go unused in function definition: A, D, E\n  --> tests/ui/extra_unused_type_parameters.rs:37:16\n   |\nLL | fn some_unused<A, B, C, D: Iterator<Item = (B, C)>, E>(b: B, c: C) {\n   |                ^^^    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the parameters\n   |\nLL - fn some_unused<A, B, C, D: Iterator<Item = (B, C)>, E>(b: B, c: C) {\nLL + fn some_unused<B, C>(b: B, c: C) {\n   |\n\nerror: type parameter `T` goes unused in function definition\n  --> tests/ui/extra_unused_type_parameters.rs:63:22\n   |\nLL |     fn unused_ty_impl<T>(&self) {\n   |                      ^^^\n   |\nhelp: consider removing the parameter\n   |\nLL -     fn unused_ty_impl<T>(&self) {\nLL +     fn unused_ty_impl(&self) {\n   |\n\nerror: type parameters go unused in function definition: A, B\n  --> tests/ui/extra_unused_type_parameters.rs:86:17\n   |\nLL | fn unused_opaque<A, B>(dummy: impl Default) {\n   |                 ^^^^^^\n   |\nhelp: consider removing the parameters\n   |\nLL - fn unused_opaque<A, B>(dummy: impl Default) {\nLL + fn unused_opaque(dummy: impl Default) {\n   |\n\nerror: type parameter `U` goes unused in function definition\n  --> tests/ui/extra_unused_type_parameters.rs:100:56\n   |\nLL |     fn unused_with_priv_trait_bound<T: private::Private, U>() {\n   |                                                        ^^^\n   |\nhelp: consider removing the parameter\n   |\nLL -     fn unused_with_priv_trait_bound<T: private::Private, U>() {\nLL +     fn unused_with_priv_trait_bound<T: private::Private>() {\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/extra_unused_type_parameters_unfixable.rs",
    "content": "#![warn(clippy::extra_unused_type_parameters)]\n\nfn unused_where_clause<T, U>(x: U)\n//~^ extra_unused_type_parameters\nwhere\n    T: Default,\n{\n    unimplemented!();\n}\n\nfn unused_multi_where_clause<T, U, V: Default>(x: U)\n//~^ extra_unused_type_parameters\nwhere\n    T: Default,\n{\n    unimplemented!();\n}\n\nfn unused_all_where_clause<T, U: Default, V: Default>()\n//~^ extra_unused_type_parameters\nwhere\n    T: Default,\n{\n    unimplemented!();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/extra_unused_type_parameters_unfixable.stderr",
    "content": "error: type parameter `T` goes unused in function definition\n  --> tests/ui/extra_unused_type_parameters_unfixable.rs:3:24\n   |\nLL | fn unused_where_clause<T, U>(x: U)\n   |                        ^\n   |\n   = help: consider removing the parameter\n   = note: `-D clippy::extra-unused-type-parameters` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::extra_unused_type_parameters)]`\n\nerror: type parameters go unused in function definition: T, V\n  --> tests/ui/extra_unused_type_parameters_unfixable.rs:11:30\n   |\nLL | fn unused_multi_where_clause<T, U, V: Default>(x: U)\n   |                              ^     ^^^^^^^^^^\n   |\n   = help: consider removing the parameters\n\nerror: type parameters go unused in function definition: T, U, V\n  --> tests/ui/extra_unused_type_parameters_unfixable.rs:19:28\n   |\nLL | fn unused_all_where_clause<T, U: Default, V: Default>()\n   |                            ^  ^^^^^^^^^^  ^^^^^^^^^^\n   |\n   = help: consider removing the parameters\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/fallible_impl_from.rs",
    "content": "#![deny(clippy::fallible_impl_from)]\n\n// docs example\nstruct Foo(i32);\nimpl From<String> for Foo {\n    //~^ fallible_impl_from\n\n    fn from(s: String) -> Self {\n        Foo(s.parse().unwrap())\n    }\n}\n\nstruct Valid(Vec<u8>);\n\nimpl<'a> From<&'a str> for Valid {\n    fn from(s: &'a str) -> Valid {\n        Valid(s.to_owned().into_bytes())\n    }\n}\nimpl From<usize> for Valid {\n    fn from(i: usize) -> Valid {\n        Valid(Vec::with_capacity(i))\n    }\n}\n\nstruct Invalid;\n\nimpl From<usize> for Invalid {\n    //~^ fallible_impl_from\n\n    fn from(i: usize) -> Invalid {\n        if i != 42 {\n            panic!();\n        }\n        Invalid\n    }\n}\n\nimpl From<Option<String>> for Invalid {\n    //~^ fallible_impl_from\n\n    fn from(s: Option<String>) -> Invalid {\n        let s = s.unwrap();\n        if !s.is_empty() {\n            panic!(\"42\");\n        } else if s.parse::<u32>().unwrap() != 42 {\n            panic!(\"{:?}\", s);\n        }\n        Invalid\n    }\n}\n\ntrait ProjStrTrait {\n    type ProjString;\n}\nimpl<T> ProjStrTrait for Box<T> {\n    type ProjString = String;\n}\nimpl<'a> From<&'a mut <Box<u32> as ProjStrTrait>::ProjString> for Invalid {\n    //~^ fallible_impl_from\n\n    fn from(s: &'a mut <Box<u32> as ProjStrTrait>::ProjString) -> Invalid {\n        if s.parse::<u32>().ok().unwrap() != 42 {\n            panic!(\"{s:?}\");\n        }\n        Invalid\n    }\n}\n\nstruct Unreachable;\n\nimpl From<String> for Unreachable {\n    fn from(s: String) -> Unreachable {\n        if s.is_empty() {\n            return Unreachable;\n        }\n        match s.chars().next() {\n            Some(_) => Unreachable,\n            None => unreachable!(), // do not lint the unreachable macro\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/fallible_impl_from.stderr",
    "content": "error: consider implementing `TryFrom` instead\n  --> tests/ui/fallible_impl_from.rs:5:1\n   |\nLL | / impl From<String> for Foo {\nLL | |\nLL | |\nLL | |     fn from(s: String) -> Self {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail\nnote: potential failure(s)\n  --> tests/ui/fallible_impl_from.rs:9:13\n   |\nLL |         Foo(s.parse().unwrap())\n   |             ^^^^^^^^^^^^^^^^^^\nnote: the lint level is defined here\n  --> tests/ui/fallible_impl_from.rs:1:9\n   |\nLL | #![deny(clippy::fallible_impl_from)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider implementing `TryFrom` instead\n  --> tests/ui/fallible_impl_from.rs:28:1\n   |\nLL | / impl From<usize> for Invalid {\nLL | |\nLL | |\nLL | |     fn from(i: usize) -> Invalid {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail\nnote: potential failure(s)\n  --> tests/ui/fallible_impl_from.rs:33:13\n   |\nLL |             panic!();\n   |             ^^^^^^^^\n\nerror: consider implementing `TryFrom` instead\n  --> tests/ui/fallible_impl_from.rs:39:1\n   |\nLL | / impl From<Option<String>> for Invalid {\nLL | |\nLL | |\nLL | |     fn from(s: Option<String>) -> Invalid {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail\nnote: potential failure(s)\n  --> tests/ui/fallible_impl_from.rs:43:17\n   |\nLL |         let s = s.unwrap();\n   |                 ^^^^^^^^^^\nLL |         if !s.is_empty() {\nLL |             panic!(\"42\");\n   |             ^^^^^^^^^^^^\nLL |         } else if s.parse::<u32>().unwrap() != 42 {\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |             panic!(\"{:?}\", s);\n   |             ^^^^^^^^^^^^^^^^^\n\nerror: consider implementing `TryFrom` instead\n  --> tests/ui/fallible_impl_from.rs:59:1\n   |\nLL | / impl<'a> From<&'a mut <Box<u32> as ProjStrTrait>::ProjString> for Invalid {\nLL | |\nLL | |\nLL | |     fn from(s: &'a mut <Box<u32> as ProjStrTrait>::ProjString) -> Invalid {\n...  |\nLL | | }\n   | |_^\n   |\n   = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail\nnote: potential failure(s)\n  --> tests/ui/fallible_impl_from.rs:63:12\n   |\nLL |         if s.parse::<u32>().ok().unwrap() != 42 {\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |             panic!(\"{s:?}\");\n   |             ^^^^^^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/field_reassign_with_default.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n//@aux-build:proc_macros.rs\n\n#![warn(clippy::field_reassign_with_default)]\n#![allow(clippy::assigning_clones)]\n\n#[macro_use]\nextern crate proc_macro_derive;\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n// Don't lint on derives that derive `Default`\n// See https://github.com/rust-lang/rust-clippy/issues/6545\n#[derive(FieldReassignWithDefault)]\nstruct DerivedStruct;\n\n#[derive(Default)]\nstruct A {\n    i: i32,\n    j: i64,\n}\n\nstruct B {\n    i: i32,\n    j: i64,\n}\n\n#[derive(Default)]\nstruct C {\n    i: Vec<i32>,\n    j: i64,\n}\n\n#[derive(Default)]\nstruct D {\n    a: Option<i32>,\n    b: Option<i32>,\n}\n\n/// Implements .next() that returns a different number each time.\nstruct SideEffect(i32);\n\nimpl SideEffect {\n    fn new() -> SideEffect {\n        SideEffect(0)\n    }\n    fn next(&mut self) -> i32 {\n        self.0 += 1;\n        self.0\n    }\n}\n\n#[inline_macros]\nfn main() {\n    // wrong, produces first error in stderr\n    let mut a: A = Default::default();\n    a.i = 42;\n    //~^ field_reassign_with_default\n\n    // right\n    let mut a: A = Default::default();\n\n    // right\n    let a = A {\n        i: 42,\n        ..Default::default()\n    };\n\n    // right\n    let mut a: A = Default::default();\n    if a.i == 0 {\n        a.j = 12;\n    }\n\n    // right\n    let mut a: A = Default::default();\n    let b = 5;\n\n    // right\n    let mut b = 32;\n    let mut a: A = Default::default();\n    b = 2;\n\n    // right\n    let b: B = B { i: 42, j: 24 };\n\n    // right\n    let mut b: B = B { i: 42, j: 24 };\n    b.i = 52;\n\n    // right\n    let mut b = B { i: 15, j: 16 };\n    let mut a: A = Default::default();\n    b.i = 2;\n\n    // wrong, produces second error in stderr\n    let mut a: A = Default::default();\n    a.j = 43;\n    //~^ field_reassign_with_default\n    a.i = 42;\n\n    // wrong, produces third error in stderr\n    let mut a: A = Default::default();\n    a.i = 42;\n    //~^ field_reassign_with_default\n    a.j = 43;\n    a.j = 44;\n\n    // wrong, produces fourth error in stderr\n    let mut a = A::default();\n    a.i = 42;\n    //~^ field_reassign_with_default\n\n    // wrong, but does not produce an error in stderr, because we can't produce a correct kind of\n    // suggestion with current implementation\n    let mut c: (i32, i32) = Default::default();\n    c.0 = 42;\n    c.1 = 21;\n\n    // wrong, produces the fifth error in stderr\n    let mut a: A = Default::default();\n    a.i = Default::default();\n    //~^ field_reassign_with_default\n\n    // wrong, produces the sixth error in stderr\n    let mut a: A = Default::default();\n    a.i = Default::default();\n    //~^ field_reassign_with_default\n    a.j = 45;\n\n    // right, because an assignment refers to another field\n    let mut x = A::default();\n    x.i = 42;\n    x.j = 21 + x.i as i64;\n\n    // right, we bail out if there's a reassignment to the same variable, since there is a risk of\n    // side-effects affecting the outcome\n    let mut x = A::default();\n    let mut side_effect = SideEffect::new();\n    x.i = side_effect.next();\n    x.j = 2;\n    x.i = side_effect.next();\n\n    // don't lint - some private fields\n    let mut x = m::F::default();\n    x.a = 1;\n\n    // don't expand macros in the suggestion (#6522)\n    let mut a: C = C::default();\n    a.i = vec![1];\n    //~^ field_reassign_with_default\n\n    // Don't lint in external macros\n    external! {\n        #[derive(Default)]\n        struct A {\n            pub i: i32,\n            pub j: i64,\n        }\n        fn lint() {\n            let mut a: A = Default::default();\n            a.i = 42;\n            a;\n        }\n    }\n\n    // be sure suggestion is correct with generics\n    let mut a: Wrapper<bool> = Default::default();\n    a.i = true;\n    //~^ field_reassign_with_default\n\n    let mut a: WrapperMulti<i32, i64> = Default::default();\n    a.i = 42;\n    //~^ field_reassign_with_default\n\n    // Don't lint in macros\n    inline!(\n        let mut data = $crate::D::default();\n        data.$a = Some($42);\n        data\n    );\n}\n\nmod m {\n    #[derive(Default)]\n    pub struct F {\n        pub a: u64,\n        b: u64,\n    }\n}\n\n#[derive(Default)]\nstruct Wrapper<T> {\n    i: T,\n}\n\n#[derive(Default)]\nstruct WrapperMulti<T, U> {\n    i: T,\n    j: U,\n}\n\nmod issue6312 {\n    use std::sync::Arc;\n    use std::sync::atomic::AtomicBool;\n\n    // do not lint: type implements `Drop` but not all fields are `Copy`\n    #[derive(Clone, Default)]\n    pub struct ImplDropNotAllCopy {\n        name: String,\n        delay_data_sync: Arc<AtomicBool>,\n    }\n\n    impl Drop for ImplDropNotAllCopy {\n        fn drop(&mut self) {\n            self.close()\n        }\n    }\n\n    impl ImplDropNotAllCopy {\n        fn new(name: &str) -> Self {\n            let mut f = ImplDropNotAllCopy::default();\n            f.name = name.to_owned();\n            f\n        }\n        fn close(&self) {}\n    }\n\n    // lint: type implements `Drop` and all fields are `Copy`\n    #[derive(Clone, Default)]\n    pub struct ImplDropAllCopy {\n        name: usize,\n        delay_data_sync: bool,\n    }\n\n    impl Drop for ImplDropAllCopy {\n        fn drop(&mut self) {\n            self.close()\n        }\n    }\n\n    impl ImplDropAllCopy {\n        fn new(name: &str) -> Self {\n            let mut f = ImplDropAllCopy::default();\n            f.name = name.len();\n            //~^ field_reassign_with_default\n            f\n        }\n        fn close(&self) {}\n    }\n\n    // lint: type does not implement `Drop` though all fields are `Copy`\n    #[derive(Clone, Default)]\n    pub struct NoDropAllCopy {\n        name: usize,\n        delay_data_sync: bool,\n    }\n\n    impl NoDropAllCopy {\n        fn new(name: &str) -> Self {\n            let mut f = NoDropAllCopy::default();\n            f.name = name.len();\n            //~^ field_reassign_with_default\n            f\n        }\n    }\n}\n\nstruct Collection {\n    items: Vec<i32>,\n    len: usize,\n}\n\nimpl Default for Collection {\n    fn default() -> Self {\n        Self {\n            items: vec![1, 2, 3],\n            len: 0,\n        }\n    }\n}\n\n#[allow(clippy::redundant_closure_call)]\nfn issue10136() {\n    let mut c = Collection::default();\n    // don't lint, since c.items was used to calculate this value\n    c.len = (|| c.items.len())();\n}\n"
  },
  {
    "path": "tests/ui/field_reassign_with_default.stderr",
    "content": "error: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:57:5\n   |\nLL |     a.i = 42;\n   |     ^^^^^^^^^\n   |\nnote: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:56:5\n   |\nLL |     let mut a: A = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::field-reassign-with-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::field_reassign_with_default)]`\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:98:5\n   |\nLL |     a.j = 43;\n   |     ^^^^^^^^^\n   |\nnote: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:97:5\n   |\nLL |     let mut a: A = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:104:5\n   |\nLL |     a.i = 42;\n   |     ^^^^^^^^^\n   |\nnote: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:103:5\n   |\nLL |     let mut a: A = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:111:5\n   |\nLL |     a.i = 42;\n   |     ^^^^^^^^^\n   |\nnote: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:110:5\n   |\nLL |     let mut a = A::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:122:5\n   |\nLL |     a.i = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:121:5\n   |\nLL |     let mut a: A = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:127:5\n   |\nLL |     a.i = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:126:5\n   |\nLL |     let mut a: A = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:150:5\n   |\nLL |     a.i = vec![1];\n   |     ^^^^^^^^^^^^^^\n   |\nnote: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:149:5\n   |\nLL |     let mut a: C = C::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:169:5\n   |\nLL |     a.i = true;\n   |     ^^^^^^^^^^^\n   |\nnote: consider initializing the variable with `Wrapper::<bool> { i: true }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:168:5\n   |\nLL |     let mut a: Wrapper<bool> = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:173:5\n   |\nLL |     a.i = 42;\n   |     ^^^^^^^^^\n   |\nnote: consider initializing the variable with `WrapperMulti::<i32, i64> { i: 42, ..Default::default() }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:172:5\n   |\nLL |     let mut a: WrapperMulti<i32, i64> = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:245:13\n   |\nLL |             f.name = name.len();\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider initializing the variable with `issue6312::ImplDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:244:13\n   |\nLL |             let mut f = ImplDropAllCopy::default();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: field assignment outside of initializer for an instance created with Default::default()\n  --> tests/ui/field_reassign_with_default.rs:262:13\n   |\nLL |             f.name = name.len();\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider initializing the variable with `issue6312::NoDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments\n  --> tests/ui/field_reassign_with_default.rs:261:13\n   |\nLL |             let mut f = NoDropAllCopy::default();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/field_scoped_visibility_modifiers.rs",
    "content": "#![warn(clippy::field_scoped_visibility_modifiers)]\n\npub mod pub_module {\n    pub(in crate::pub_module) mod pub_in_path_module {}\n    pub(super) mod pub_super_module {}\n    struct MyStruct {\n        private_field: bool,\n        pub pub_field: bool,\n        pub(crate) pub_crate_field: bool,\n        //~^ field_scoped_visibility_modifiers\n        pub(in crate::pub_module) pub_in_path_field: bool,\n        //~^ field_scoped_visibility_modifiers\n        pub(super) pub_super_field: bool,\n        //~^ field_scoped_visibility_modifiers\n        #[allow(clippy::needless_pub_self)]\n        pub(self) pub_self_field: bool,\n    }\n}\npub(crate) mod pub_crate_module {}\n\n#[allow(clippy::needless_pub_self)]\npub(self) mod pub_self_module {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/field_scoped_visibility_modifiers.stderr",
    "content": "error: scoped visibility modifier on a field\n  --> tests/ui/field_scoped_visibility_modifiers.rs:9:9\n   |\nLL |         pub(crate) pub_crate_field: bool,\n   |         ^^^^^^^^^^\n   |\n   = help: consider making the field private and adding a scoped visibility method for it\n   = note: `-D clippy::field-scoped-visibility-modifiers` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::field_scoped_visibility_modifiers)]`\n\nerror: scoped visibility modifier on a field\n  --> tests/ui/field_scoped_visibility_modifiers.rs:11:9\n   |\nLL |         pub(in crate::pub_module) pub_in_path_field: bool,\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider making the field private and adding a scoped visibility method for it\n\nerror: scoped visibility modifier on a field\n  --> tests/ui/field_scoped_visibility_modifiers.rs:13:9\n   |\nLL |         pub(super) pub_super_field: bool,\n   |         ^^^^^^^^^^\n   |\n   = help: consider making the field private and adding a scoped visibility method for it\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/filetype_is_file.rs",
    "content": "#![allow(clippy::needless_ifs)]\n#![warn(clippy::filetype_is_file)]\n\nfn main() -> std::io::Result<()> {\n    use std::fs;\n    use std::ops::BitOr;\n\n    // !filetype.is_dir()\n    if fs::metadata(\"foo.txt\")?.file_type().is_file() {\n        //~^ filetype_is_file\n\n        // read file\n    }\n\n    // positive of filetype.is_dir()\n    if !fs::metadata(\"foo.txt\")?.file_type().is_file() {\n        //~^ filetype_is_file\n\n        // handle dir\n    }\n\n    // false positive of filetype.is_dir()\n    if !fs::metadata(\"foo.txt\")?.file_type().is_file().bitor(true) {\n        //~^ filetype_is_file\n\n        // ...\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/filetype_is_file.stderr",
    "content": "error: `FileType::is_file()` only covers regular files\n  --> tests/ui/filetype_is_file.rs:9:8\n   |\nLL |     if fs::metadata(\"foo.txt\")?.file_type().is_file() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `!FileType::is_dir()` instead\n   = note: `-D clippy::filetype-is-file` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filetype_is_file)]`\n\nerror: `!FileType::is_file()` only denies regular files\n  --> tests/ui/filetype_is_file.rs:16:8\n   |\nLL |     if !fs::metadata(\"foo.txt\")?.file_type().is_file() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `FileType::is_dir()` instead\n\nerror: `FileType::is_file()` only covers regular files\n  --> tests/ui/filetype_is_file.rs:23:9\n   |\nLL |     if !fs::metadata(\"foo.txt\")?.file_type().is_file().bitor(true) {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `!FileType::is_dir()` instead\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/filter_map_bool_then.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    clippy::clone_on_copy,\n    clippy::map_identity,\n    clippy::unnecessary_lazy_evaluations,\n    clippy::unnecessary_filter_map,\n    unused\n)]\n#![warn(clippy::filter_map_bool_then)]\n\n#[macro_use]\nextern crate proc_macros;\n\n#[derive(Clone, PartialEq)]\nstruct NonCopy;\n\nfn main() {\n    let v = vec![1, 2, 3, 4, 5, 6];\n    v.clone().iter().filter(|&i| (i % 2 == 0)).map(|i| i + 1);\n    //~^ filter_map_bool_then\n    v.clone().into_iter().filter(|&i| (i % 2 == 0)).map(|i| i + 1);\n    //~^ filter_map_bool_then\n    v.clone()\n        .into_iter()\n        .filter(|&i| (i % 2 == 0)).map(|i| i + 1);\n    //~^ filter_map_bool_then\n    v.clone()\n        .into_iter()\n        .filter(|&i| i != 1000)\n        .filter(|&i| (i % 2 == 0)).map(|i| i + 1);\n    //~^ filter_map_bool_then\n    v.iter()\n        .copied()\n        .filter(|&i| i != 1000)\n        .filter(|&i| (i.clone() % 2 == 0)).map(|i| i + 1);\n    //~^ filter_map_bool_then\n    // Despite this is non-copy, `is_copy` still returns true (at least now) because it's `&NonCopy`,\n    // and any `&` is `Copy`. So since we can dereference it in `filter` (since it's then `&&NonCopy`),\n    // we can lint this and still get the same input type.\n    // See: <https://doc.rust-lang.org/std/primitive.reference.html#trait-implementations-1>\n    let v = vec![NonCopy, NonCopy];\n    v.clone().iter().filter(|&i| (i == &NonCopy)).map(|i| i);\n    //~^ filter_map_bool_then\n    // Do not lint\n    let v = vec![NonCopy, NonCopy];\n    v.clone().into_iter().filter_map(|i| (i == NonCopy).then(|| i));\n    // `&mut` is `!Copy`.\n    let v = vec![NonCopy, NonCopy];\n    v.clone().iter_mut().filter_map(|i| (i == &mut NonCopy).then(|| i));\n    external! {\n        let v = vec![1, 2, 3, 4, 5, 6];\n        v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));\n    }\n    with_span! {\n        span\n        let v = vec![1, 2, 3, 4, 5, 6];\n        v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));\n    }\n}\n\nfn issue11309<'a>(iter: impl Iterator<Item = (&'a str, &'a str)>) -> Vec<&'a str> {\n    iter.filter_map(|(_, s): (&str, _)| Some(s)).collect()\n}\n\nfn issue11503() {\n    let bools: &[bool] = &[true, false, false, true];\n    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| *b).map(|(i, b)| i).collect();\n    //~^ filter_map_bool_then\n\n    // Need to insert multiple derefs if there is more than one layer of references\n    let bools: &[&&bool] = &[&&true, &&false, &&false, &&true];\n    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ***b).map(|(i, b)| i).collect();\n    //~^ filter_map_bool_then\n\n    // Should also suggest derefs when going through a mutable reference\n    let bools: &[&mut bool] = &[&mut true];\n    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| **b).map(|(i, b)| i).collect();\n    //~^ filter_map_bool_then\n\n    // Should also suggest derefs when going through a custom deref\n    struct DerefToBool;\n    impl std::ops::Deref for DerefToBool {\n        type Target = bool;\n        fn deref(&self) -> &Self::Target {\n            &true\n        }\n    }\n    let bools: &[&&DerefToBool] = &[&&DerefToBool];\n    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ****b).map(|(i, b)| i).collect();\n    //~^ filter_map_bool_then\n}\n\nfn issue15047() {\n    #[derive(Clone, Copy)]\n    enum MyEnum {\n        A,\n        B,\n        C,\n    }\n\n    macro_rules! foo {\n        ($e:expr) => {\n            $e + 1\n        };\n    }\n\n    let x = 1;\n    let _ = [(MyEnum::A, \"foo\", 1i32)]\n        .iter()\n        .filter(|&(t, s, i)| matches!(t, MyEnum::A if s.starts_with(\"bar\"))).map(|(t, s, i)| foo!(x));\n    //~^ filter_map_bool_then\n}\n"
  },
  {
    "path": "tests/ui/filter_map_bool_then.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    clippy::clone_on_copy,\n    clippy::map_identity,\n    clippy::unnecessary_lazy_evaluations,\n    clippy::unnecessary_filter_map,\n    unused\n)]\n#![warn(clippy::filter_map_bool_then)]\n\n#[macro_use]\nextern crate proc_macros;\n\n#[derive(Clone, PartialEq)]\nstruct NonCopy;\n\nfn main() {\n    let v = vec![1, 2, 3, 4, 5, 6];\n    v.clone().iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));\n    //~^ filter_map_bool_then\n    v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));\n    //~^ filter_map_bool_then\n    v.clone()\n        .into_iter()\n        .filter_map(|i| -> Option<_> { (i % 2 == 0).then(|| i + 1) });\n    //~^ filter_map_bool_then\n    v.clone()\n        .into_iter()\n        .filter(|&i| i != 1000)\n        .filter_map(|i| (i % 2 == 0).then(|| i + 1));\n    //~^ filter_map_bool_then\n    v.iter()\n        .copied()\n        .filter(|&i| i != 1000)\n        .filter_map(|i| (i.clone() % 2 == 0).then(|| i + 1));\n    //~^ filter_map_bool_then\n    // Despite this is non-copy, `is_copy` still returns true (at least now) because it's `&NonCopy`,\n    // and any `&` is `Copy`. So since we can dereference it in `filter` (since it's then `&&NonCopy`),\n    // we can lint this and still get the same input type.\n    // See: <https://doc.rust-lang.org/std/primitive.reference.html#trait-implementations-1>\n    let v = vec![NonCopy, NonCopy];\n    v.clone().iter().filter_map(|i| (i == &NonCopy).then(|| i));\n    //~^ filter_map_bool_then\n    // Do not lint\n    let v = vec![NonCopy, NonCopy];\n    v.clone().into_iter().filter_map(|i| (i == NonCopy).then(|| i));\n    // `&mut` is `!Copy`.\n    let v = vec![NonCopy, NonCopy];\n    v.clone().iter_mut().filter_map(|i| (i == &mut NonCopy).then(|| i));\n    external! {\n        let v = vec![1, 2, 3, 4, 5, 6];\n        v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));\n    }\n    with_span! {\n        span\n        let v = vec![1, 2, 3, 4, 5, 6];\n        v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));\n    }\n}\n\nfn issue11309<'a>(iter: impl Iterator<Item = (&'a str, &'a str)>) -> Vec<&'a str> {\n    iter.filter_map(|(_, s): (&str, _)| Some(s)).collect()\n}\n\nfn issue11503() {\n    let bools: &[bool] = &[true, false, false, true];\n    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();\n    //~^ filter_map_bool_then\n\n    // Need to insert multiple derefs if there is more than one layer of references\n    let bools: &[&&bool] = &[&&true, &&false, &&false, &&true];\n    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();\n    //~^ filter_map_bool_then\n\n    // Should also suggest derefs when going through a mutable reference\n    let bools: &[&mut bool] = &[&mut true];\n    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();\n    //~^ filter_map_bool_then\n\n    // Should also suggest derefs when going through a custom deref\n    struct DerefToBool;\n    impl std::ops::Deref for DerefToBool {\n        type Target = bool;\n        fn deref(&self) -> &Self::Target {\n            &true\n        }\n    }\n    let bools: &[&&DerefToBool] = &[&&DerefToBool];\n    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();\n    //~^ filter_map_bool_then\n}\n\nfn issue15047() {\n    #[derive(Clone, Copy)]\n    enum MyEnum {\n        A,\n        B,\n        C,\n    }\n\n    macro_rules! foo {\n        ($e:expr) => {\n            $e + 1\n        };\n    }\n\n    let x = 1;\n    let _ = [(MyEnum::A, \"foo\", 1i32)]\n        .iter()\n        .filter_map(|(t, s, i)| matches!(t, MyEnum::A if s.starts_with(\"bar\")).then(|| foo!(x)));\n    //~^ filter_map_bool_then\n}\n"
  },
  {
    "path": "tests/ui/filter_map_bool_then.stderr",
    "content": "error: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:19:22\n   |\nLL |     v.clone().iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)`\n   |\n   = note: `-D clippy::filter-map-bool-then` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filter_map_bool_then)]`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:21:27\n   |\nLL |     v.clone().into_iter().filter_map(|i| (i % 2 == 0).then(|| i + 1));\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:25:10\n   |\nLL |         .filter_map(|i| -> Option<_> { (i % 2 == 0).then(|| i + 1) });\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:30:10\n   |\nLL |         .filter_map(|i| (i % 2 == 0).then(|| i + 1));\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i % 2 == 0)).map(|i| i + 1)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:35:10\n   |\nLL |         .filter_map(|i| (i.clone() % 2 == 0).then(|| i + 1));\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i.clone() % 2 == 0)).map(|i| i + 1)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:42:22\n   |\nLL |     v.clone().iter().filter_map(|i| (i == &NonCopy).then(|| i));\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i == &NonCopy)).map(|i| i)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:67:50\n   |\nLL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();\n   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| *b).map(|(i, b)| i)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:72:50\n   |\nLL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();\n   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ***b).map(|(i, b)| i)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:77:50\n   |\nLL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();\n   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| **b).map(|(i, b)| i)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:89:50\n   |\nLL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();\n   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ****b).map(|(i, b)| i)`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then.rs:110:10\n   |\nLL |         .filter_map(|(t, s, i)| matches!(t, MyEnum::A if s.starts_with(\"bar\")).then(|| foo!(x)));\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(t, s, i)| matches!(t, MyEnum::A if s.starts_with(\"bar\"))).map(|(t, s, i)| foo!(x))`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/filter_map_bool_then_unfixable.rs",
    "content": "#![allow(clippy::question_mark)]\n#![warn(clippy::filter_map_bool_then)]\n\nfn issue11617() {\n    let mut x: Vec<usize> = vec![0; 10];\n    let _ = (0..x.len()).zip(x.clone().iter()).filter_map(|(i, v)| {\n        //~^ filter_map_bool_then\n        (x[i] != *v).then(|| {\n            x[i] = i;\n            i\n        })\n    });\n}\n\nmod issue14368 {\n\n    fn do_something(_: ()) -> bool {\n        true\n    }\n\n    fn option_with_early_return(x: &[Option<bool>]) {\n        let _ = x.iter().filter_map(|&x| x?.then(|| do_something(())));\n        //~^ filter_map_bool_then\n        let _ = x\n            .iter()\n            .filter_map(|&x| if let Some(x) = x { x } else { return None }.then(|| do_something(())));\n        //~^ filter_map_bool_then\n        let _ = x.iter().filter_map(|&x| {\n            //~^ filter_map_bool_then\n            match x {\n                Some(x) => x,\n                None => return None,\n            }\n            .then(|| do_something(()))\n        });\n    }\n\n    #[derive(Copy, Clone)]\n    enum Foo {\n        One(bool),\n        Two,\n        Three(Option<i32>),\n    }\n\n    fn nested_type_with_early_return(x: &[Foo]) {\n        let _ = x.iter().filter_map(|&x| {\n            //~^ filter_map_bool_then\n            match x {\n                Foo::One(x) => x,\n                Foo::Two => return None,\n                Foo::Three(inner) => {\n                    if inner? == 0 {\n                        return Some(false);\n                    } else {\n                        true\n                    }\n                },\n            }\n            .then(|| do_something(()))\n        });\n    }\n}\n"
  },
  {
    "path": "tests/ui/filter_map_bool_then_unfixable.stderr",
    "content": "error: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then_unfixable.rs:6:48\n   |\nLL |       let _ = (0..x.len()).zip(x.clone().iter()).filter_map(|(i, v)| {\n   |  ________________________________________________^\nLL | |\nLL | |         (x[i] != *v).then(|| {\nLL | |             x[i] = i;\nLL | |             i\nLL | |         })\nLL | |     });\n   | |______^\n   |\n   = help: consider using `filter` then `map` instead\n   = note: `-D clippy::filter-map-bool-then` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filter_map_bool_then)]`\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then_unfixable.rs:22:26\n   |\nLL |         let _ = x.iter().filter_map(|&x| x?.then(|| do_something(())));\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `filter` then `map` instead\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then_unfixable.rs:26:14\n   |\nLL |             .filter_map(|&x| if let Some(x) = x { x } else { return None }.then(|| do_something(())));\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `filter` then `map` instead\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then_unfixable.rs:28:26\n   |\nLL |           let _ = x.iter().filter_map(|&x| {\n   |  __________________________^\nLL | |\nLL | |             match x {\nLL | |                 Some(x) => x,\n...  |\nLL | |             .then(|| do_something(()))\nLL | |         });\n   | |__________^\n   |\n   = help: consider using `filter` then `map` instead\n\nerror: usage of `bool::then` in `filter_map`\n  --> tests/ui/filter_map_bool_then_unfixable.rs:46:26\n   |\nLL |           let _ = x.iter().filter_map(|&x| {\n   |  __________________________^\nLL | |\nLL | |             match x {\nLL | |                 Foo::One(x) => x,\n...  |\nLL | |             .then(|| do_something(()))\nLL | |         });\n   | |__________^\n   |\n   = help: consider using `filter` then `map` instead\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/filter_map_identity.fixed",
    "content": "#![allow(unused_imports, clippy::needless_return, clippy::useless_vec)]\n#![warn(clippy::filter_map_identity)]\n#![feature(stmt_expr_attributes)]\n\nuse std::option::Option;\nstruct NonCopy;\nuse std::convert::identity;\n\nfn non_copy_vec() -> Vec<Option<NonCopy>> {\n    todo!()\n}\n\nfn copy_vec<T: Copy>() -> Vec<Option<T>> {\n    todo!()\n}\n\nfn copy_vec_non_inferred() -> Vec<Option<i32>> {\n    todo!()\n}\n\nfn opaque<T: Default>() -> impl IntoIterator<Item = Option<T>> {\n    vec![Some(T::default())]\n}\n\nfn main() {\n    {\n        // into_iter\n        copy_vec_non_inferred().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec_non_inferred().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec_non_inferred().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec_non_inferred().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec_non_inferred().into_iter().flatten();\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().flatten();\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().flatten();\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().flatten();\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().flatten();\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().flatten();\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        // we are forced to pass the type in the call.\n        copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        #[rustfmt::skip]\n            copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        #[rustfmt::skip]\n            copy_vec::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n\n        // note, the compiler requires that we pass the type to `opaque`. This is mostly for reference,\n        // it behaves the same as copy_vec.\n        opaque::<i32>().into_iter().flatten();\n        //~^ filter_map_identity\n    }\n}\n\nfn issue12653() -> impl Iterator<Item = u8> {\n    [].into_iter().filter_map(|x| x)\n    // No lint\n}\n"
  },
  {
    "path": "tests/ui/filter_map_identity.rs",
    "content": "#![allow(unused_imports, clippy::needless_return, clippy::useless_vec)]\n#![warn(clippy::filter_map_identity)]\n#![feature(stmt_expr_attributes)]\n\nuse std::option::Option;\nstruct NonCopy;\nuse std::convert::identity;\n\nfn non_copy_vec() -> Vec<Option<NonCopy>> {\n    todo!()\n}\n\nfn copy_vec<T: Copy>() -> Vec<Option<T>> {\n    todo!()\n}\n\nfn copy_vec_non_inferred() -> Vec<Option<i32>> {\n    todo!()\n}\n\nfn opaque<T: Default>() -> impl IntoIterator<Item = Option<T>> {\n    vec![Some(T::default())]\n}\n\nfn main() {\n    {\n        // into_iter\n        copy_vec_non_inferred().into_iter().filter_map(|x| x);\n        //~^ filter_map_identity\n\n        copy_vec_non_inferred().into_iter().filter_map(std::convert::identity);\n        //~^ filter_map_identity\n\n        copy_vec_non_inferred().into_iter().filter_map(identity);\n        //~^ filter_map_identity\n\n        copy_vec_non_inferred().into_iter().filter_map(|x| return x);\n        //~^ filter_map_identity\n\n        copy_vec_non_inferred().into_iter().filter_map(|x| return x);\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().filter_map(|x| x);\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().filter_map(|x| x);\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().filter_map(std::convert::identity);\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().filter_map(identity);\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().filter_map(|x| return x);\n        //~^ filter_map_identity\n\n        non_copy_vec().into_iter().filter_map(|x| return x);\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| x);\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| x);\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| return x);\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| return x);\n        //~^ filter_map_identity\n\n        // we are forced to pass the type in the call.\n        copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| x);\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| x);\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| return x);\n        //~^ filter_map_identity\n\n        copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| return x);\n        //~^ filter_map_identity\n\n        #[rustfmt::skip]\n            copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| -> Option<i32> {{ x }});\n        //~^ filter_map_identity\n\n        #[rustfmt::skip]\n            copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| -> Option<i32> {{ return x }});\n        //~^ filter_map_identity\n\n        // note, the compiler requires that we pass the type to `opaque`. This is mostly for reference,\n        // it behaves the same as copy_vec.\n        opaque::<i32>().into_iter().filter_map(|x| x);\n        //~^ filter_map_identity\n    }\n}\n\nfn issue12653() -> impl Iterator<Item = u8> {\n    [].into_iter().filter_map(|x| x)\n    // No lint\n}\n"
  },
  {
    "path": "tests/ui/filter_map_identity.stderr",
    "content": "error: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:28:45\n   |\nLL |         copy_vec_non_inferred().into_iter().filter_map(|x| x);\n   |                                             ^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n   |\n   = note: `-D clippy::filter-map-identity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filter_map_identity)]`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:31:45\n   |\nLL |         copy_vec_non_inferred().into_iter().filter_map(std::convert::identity);\n   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:34:45\n   |\nLL |         copy_vec_non_inferred().into_iter().filter_map(identity);\n   |                                             ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:37:45\n   |\nLL |         copy_vec_non_inferred().into_iter().filter_map(|x| return x);\n   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:40:45\n   |\nLL |         copy_vec_non_inferred().into_iter().filter_map(|x| return x);\n   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:43:36\n   |\nLL |         non_copy_vec().into_iter().filter_map(|x| x);\n   |                                    ^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:46:36\n   |\nLL |         non_copy_vec().into_iter().filter_map(|x| x);\n   |                                    ^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:49:36\n   |\nLL |         non_copy_vec().into_iter().filter_map(std::convert::identity);\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:52:36\n   |\nLL |         non_copy_vec().into_iter().filter_map(identity);\n   |                                    ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:55:36\n   |\nLL |         non_copy_vec().into_iter().filter_map(|x| return x);\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:58:36\n   |\nLL |         non_copy_vec().into_iter().filter_map(|x| return x);\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:61:39\n   |\nLL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| x);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:64:39\n   |\nLL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| x);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:67:39\n   |\nLL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| return x);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:70:39\n   |\nLL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| return x);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:74:39\n   |\nLL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| x);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:77:39\n   |\nLL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| x);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:80:39\n   |\nLL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| return x);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:83:39\n   |\nLL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| return x);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:87:43\n   |\nLL |             copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| -> Option<i32> {{ x }});\n   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:91:43\n   |\nLL |             copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| -> Option<i32> {{ return x }});\n   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `filter_map` with an identity function\n  --> tests/ui/filter_map_identity.rs:96:37\n   |\nLL |         opaque::<i32>().into_iter().filter_map(|x| x);\n   |                                     ^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: aborting due to 22 previous errors\n\n"
  },
  {
    "path": "tests/ui/filter_map_next.rs",
    "content": "#![warn(clippy::filter_map_next)]\n\nfn main() {\n    let a = [\"1\", \"lol\", \"3\", \"NaN\", \"5\"];\n\n    #[rustfmt::skip]\n    let _: Option<u32> = vec![1, 2, 3, 4, 5, 6]\n    //~^ filter_map_next\n\n\n        .into_iter()\n        .filter_map(|x| {\n            if x == 2 {\n                Some(x * 2)\n            } else {\n                None\n            }\n        })\n        .next();\n}\n"
  },
  {
    "path": "tests/ui/filter_map_next.stderr",
    "content": "error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead\n  --> tests/ui/filter_map_next.rs:7:26\n   |\nLL |       let _: Option<u32> = vec![1, 2, 3, 4, 5, 6]\n   |  __________________________^\n...  |\nLL | |         })\nLL | |         .next();\n   | |_______________^\n   |\n   = note: `-D clippy::filter-map-next` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filter_map_next)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/filter_map_next_fixable.fixed",
    "content": "#![warn(clippy::filter_map_next)]\n\nfn main() {\n    let a = [\"1\", \"lol\", \"3\", \"NaN\", \"5\"];\n\n    let element: Option<i32> = a.iter().find_map(|s| s.parse().ok());\n    //~^ filter_map_next\n    assert_eq!(element, Some(1));\n}\n\n#[clippy::msrv = \"1.29\"]\nfn msrv_1_29() {\n    let a = [\"1\", \"lol\", \"3\", \"NaN\", \"5\"];\n    let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();\n}\n\n#[clippy::msrv = \"1.30\"]\nfn msrv_1_30() {\n    let a = [\"1\", \"lol\", \"3\", \"NaN\", \"5\"];\n    let _: Option<i32> = a.iter().find_map(|s| s.parse().ok());\n    //~^ filter_map_next\n}\n"
  },
  {
    "path": "tests/ui/filter_map_next_fixable.rs",
    "content": "#![warn(clippy::filter_map_next)]\n\nfn main() {\n    let a = [\"1\", \"lol\", \"3\", \"NaN\", \"5\"];\n\n    let element: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();\n    //~^ filter_map_next\n    assert_eq!(element, Some(1));\n}\n\n#[clippy::msrv = \"1.29\"]\nfn msrv_1_29() {\n    let a = [\"1\", \"lol\", \"3\", \"NaN\", \"5\"];\n    let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();\n}\n\n#[clippy::msrv = \"1.30\"]\nfn msrv_1_30() {\n    let a = [\"1\", \"lol\", \"3\", \"NaN\", \"5\"];\n    let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();\n    //~^ filter_map_next\n}\n"
  },
  {
    "path": "tests/ui/filter_map_next_fixable.stderr",
    "content": "error: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead\n  --> tests/ui/filter_map_next_fixable.rs:6:32\n   |\nLL |     let element: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.iter().find_map(|s| s.parse().ok())`\n   |\n   = note: `-D clippy::filter-map-next` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filter_map_next)]`\n\nerror: called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find_map(..)` instead\n  --> tests/ui/filter_map_next_fixable.rs:20:26\n   |\nLL |     let _: Option<i32> = a.iter().filter_map(|s| s.parse().ok()).next();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.iter().find_map(|s| s.parse().ok())`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/find_map.rs",
    "content": "//@ check-pass\n\n#![allow(clippy::useless_vec)]\n\n#[derive(Debug, Copy, Clone)]\nenum Flavor {\n    Chocolate,\n}\n\n#[derive(Debug, Copy, Clone)]\nenum Dessert {\n    Banana,\n    Pudding,\n    Cake(Flavor),\n}\n\nfn main() {\n    let desserts_of_the_week = vec![Dessert::Banana, Dessert::Cake(Flavor::Chocolate), Dessert::Pudding];\n\n    let a = [\"lol\", \"NaN\", \"2\", \"5\", \"Xunda\"];\n\n    let _: Option<i32> = a.iter().find(|s| s.parse::<i32>().is_ok()).map(|s| s.parse().unwrap());\n\n    #[allow(clippy::match_like_matches_macro)]\n    let _: Option<Flavor> = desserts_of_the_week\n        .iter()\n        .find(|dessert| match *dessert {\n            Dessert::Cake(_) => true,\n            _ => false,\n        })\n        .map(|dessert| match *dessert {\n            Dessert::Cake(ref flavor) => *flavor,\n            _ => unreachable!(),\n        });\n}\n"
  },
  {
    "path": "tests/ui/flat_map_identity.fixed",
    "content": "#![allow(unused_imports, clippy::needless_return)]\n#![warn(clippy::flat_map_identity)]\n\nuse std::convert;\n\nfn main() {\n    let iterator = [[0, 1], [2, 3], [4, 5]].iter();\n    let _ = iterator.flatten();\n    //~^ flat_map_identity\n\n    let iterator = [[0, 1], [2, 3], [4, 5]].iter();\n    let _ = iterator.flatten();\n    //~^ flat_map_identity\n\n    let iterator = [[0, 1], [2, 3], [4, 5]].iter();\n    let _ = iterator.flatten();\n    //~^ flat_map_identity\n}\n\nfn issue15198() {\n    let x = [[1, 2], [3, 4]];\n    // don't lint: this is an `Iterator<Item = &[i32, i32]>`\n    // match ergonomics makes the binding patterns into references\n    // so that its type changes to `Iterator<Item = [&i32, &i32]>`\n    let _ = x.iter().flat_map(|[x, y]| [x, y]);\n    let _ = x.iter().flat_map(|x| [x[0]]);\n\n    // no match ergonomics for `[i32, i32]`\n    let _ = x.iter().copied().flatten();\n    //~^ flat_map_identity\n}\n"
  },
  {
    "path": "tests/ui/flat_map_identity.rs",
    "content": "#![allow(unused_imports, clippy::needless_return)]\n#![warn(clippy::flat_map_identity)]\n\nuse std::convert;\n\nfn main() {\n    let iterator = [[0, 1], [2, 3], [4, 5]].iter();\n    let _ = iterator.flat_map(|x| x);\n    //~^ flat_map_identity\n\n    let iterator = [[0, 1], [2, 3], [4, 5]].iter();\n    let _ = iterator.flat_map(convert::identity);\n    //~^ flat_map_identity\n\n    let iterator = [[0, 1], [2, 3], [4, 5]].iter();\n    let _ = iterator.flat_map(|x| return x);\n    //~^ flat_map_identity\n}\n\nfn issue15198() {\n    let x = [[1, 2], [3, 4]];\n    // don't lint: this is an `Iterator<Item = &[i32, i32]>`\n    // match ergonomics makes the binding patterns into references\n    // so that its type changes to `Iterator<Item = [&i32, &i32]>`\n    let _ = x.iter().flat_map(|[x, y]| [x, y]);\n    let _ = x.iter().flat_map(|x| [x[0]]);\n\n    // no match ergonomics for `[i32, i32]`\n    let _ = x.iter().copied().flat_map(|[x, y]| [x, y]);\n    //~^ flat_map_identity\n}\n"
  },
  {
    "path": "tests/ui/flat_map_identity.stderr",
    "content": "error: use of `flat_map` with an identity function\n  --> tests/ui/flat_map_identity.rs:8:22\n   |\nLL |     let _ = iterator.flat_map(|x| x);\n   |                      ^^^^^^^^^^^^^^^ help: try: `flatten()`\n   |\n   = note: `-D clippy::flat-map-identity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::flat_map_identity)]`\n\nerror: use of `flat_map` with an identity function\n  --> tests/ui/flat_map_identity.rs:12:22\n   |\nLL |     let _ = iterator.flat_map(convert::identity);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `flat_map` with an identity function\n  --> tests/ui/flat_map_identity.rs:16:22\n   |\nLL |     let _ = iterator.flat_map(|x| return x);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: use of `flat_map` with an identity function\n  --> tests/ui/flat_map_identity.rs:29:31\n   |\nLL |     let _ = x.iter().copied().flat_map(|[x, y]| [x, y]);\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/flat_map_option.fixed",
    "content": "#![warn(clippy::flat_map_option)]\n#![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)]\n\nfn main() {\n    // yay\n    let c = |x| Some(x);\n    let _ = [1].iter().filter_map(c);\n    //~^ flat_map_option\n    let _ = [1].iter().filter_map(Some);\n    //~^ flat_map_option\n\n    // nay\n    let _ = [1].iter().flat_map(|_| &Some(1));\n}\n"
  },
  {
    "path": "tests/ui/flat_map_option.rs",
    "content": "#![warn(clippy::flat_map_option)]\n#![allow(clippy::redundant_closure, clippy::unnecessary_filter_map)]\n\nfn main() {\n    // yay\n    let c = |x| Some(x);\n    let _ = [1].iter().flat_map(c);\n    //~^ flat_map_option\n    let _ = [1].iter().flat_map(Some);\n    //~^ flat_map_option\n\n    // nay\n    let _ = [1].iter().flat_map(|_| &Some(1));\n}\n"
  },
  {
    "path": "tests/ui/flat_map_option.stderr",
    "content": "error: used `flat_map` where `filter_map` could be used instead\n  --> tests/ui/flat_map_option.rs:7:24\n   |\nLL |     let _ = [1].iter().flat_map(c);\n   |                        ^^^^^^^^ help: try: `filter_map`\n   |\n   = note: `-D clippy::flat-map-option` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::flat_map_option)]`\n\nerror: used `flat_map` where `filter_map` could be used instead\n  --> tests/ui/flat_map_option.rs:9:24\n   |\nLL |     let _ = [1].iter().flat_map(Some);\n   |                        ^^^^^^^^ help: try: `filter_map`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/float_arithmetic.rs",
    "content": "#![warn(clippy::arithmetic_side_effects, clippy::float_arithmetic)]\n#![allow(\n    unused,\n    clippy::shadow_reuse,\n    clippy::shadow_unrelated,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::op_ref\n)]\n\n#[rustfmt::skip]\nfn main() {\n    let mut f = 1.0f32;\n\n    f * 2.0;\n    //~^ float_arithmetic\n\n\n\n    1.0 + f;\n    //~^ float_arithmetic\n\n    f * 2.0;\n    //~^ float_arithmetic\n\n    f / 2.0;\n    //~^ float_arithmetic\n\n    f - 2.0 * 4.2;\n    //~^ float_arithmetic\n\n    -f;\n    //~^ float_arithmetic\n\n\n    f += 1.0;\n    //~^ float_arithmetic\n\n    f -= 1.0;\n    //~^ float_arithmetic\n\n    f *= 2.0;\n    //~^ float_arithmetic\n\n    f /= 2.0;\n    //~^ float_arithmetic\n\n}\n\n// also warn about floating point arith with references involved\n\npub fn float_arith_ref() {\n    3.1_f32 + &1.2_f32;\n    //~^ float_arithmetic\n\n    &3.4_f32 + 1.5_f32;\n    //~^ float_arithmetic\n\n    &3.5_f32 + &1.3_f32;\n    //~^ float_arithmetic\n}\n\npub fn float_foo(f: &f32) -> f32 {\n    let a = 5.1;\n    a + f\n    //~^ float_arithmetic\n}\n\npub fn float_bar(f1: &f32, f2: &f32) -> f32 {\n    f1 + f2\n    //~^ float_arithmetic\n}\n\npub fn float_baz(f1: f32, f2: &f32) -> f32 {\n    f1 + f2\n    //~^ float_arithmetic\n}\n\npub fn float_qux(f1: f32, f2: f32) -> f32 {\n    (&f1 + &f2)\n    //~^ float_arithmetic\n}\n"
  },
  {
    "path": "tests/ui/float_arithmetic.stderr",
    "content": "error: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:15:5\n   |\nLL |     f * 2.0;\n   |     ^^^^^^^\n   |\n   = note: `-D clippy::float-arithmetic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::float_arithmetic)]`\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:20:5\n   |\nLL |     1.0 + f;\n   |     ^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:23:5\n   |\nLL |     f * 2.0;\n   |     ^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:26:5\n   |\nLL |     f / 2.0;\n   |     ^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:29:5\n   |\nLL |     f - 2.0 * 4.2;\n   |     ^^^^^^^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:32:5\n   |\nLL |     -f;\n   |     ^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:36:5\n   |\nLL |     f += 1.0;\n   |     ^^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:39:5\n   |\nLL |     f -= 1.0;\n   |     ^^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:42:5\n   |\nLL |     f *= 2.0;\n   |     ^^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:45:5\n   |\nLL |     f /= 2.0;\n   |     ^^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:53:5\n   |\nLL |     3.1_f32 + &1.2_f32;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:56:5\n   |\nLL |     &3.4_f32 + 1.5_f32;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:59:5\n   |\nLL |     &3.5_f32 + &1.3_f32;\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:65:5\n   |\nLL |     a + f\n   |     ^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:70:5\n   |\nLL |     f1 + f2\n   |     ^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:75:5\n   |\nLL |     f1 + f2\n   |     ^^^^^^^\n\nerror: floating-point arithmetic detected\n  --> tests/ui/float_arithmetic.rs:80:5\n   |\nLL |     (&f1 + &f2)\n   |     ^^^^^^^^^^^\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/float_cmp.rs",
    "content": "// FIXME(f16_f128): const casting is not yet supported for these types. Add when available.\n\n#![warn(clippy::float_cmp)]\n#![allow(\n    unused,\n    clippy::no_effect,\n    clippy::op_ref,\n    clippy::unnecessary_operation,\n    clippy::cast_lossless\n)]\n//@no-rustfix: suggestions have an error margin placeholder\nuse std::ops::Add;\n\nconst ZERO: f32 = 0.0;\nconst ONE: f32 = ZERO + 1.0;\n\nfn twice<T>(x: T) -> T\nwhere\n    T: Add<T, Output = T> + Copy,\n{\n    x + x\n}\n\nfn eq_fl(x: f32, y: f32) -> bool {\n    if x.is_nan() { y.is_nan() } else { x == y } // no error, inside \"eq\" fn\n}\n\nfn fl_eq(x: f32, y: f32) -> bool {\n    if x.is_nan() { y.is_nan() } else { x == y } // no error, inside \"eq\" fn\n}\n\nstruct X {\n    val: f32,\n}\n\nimpl PartialEq for X {\n    fn eq(&self, o: &X) -> bool {\n        if self.val.is_nan() {\n            o.val.is_nan()\n        } else {\n            self.val == o.val // no error, inside \"eq\" fn\n        }\n    }\n}\n\nimpl PartialEq<f32> for X {\n    fn eq(&self, o: &f32) -> bool {\n        if self.val.is_nan() {\n            o.is_nan()\n        } else {\n            self.val == *o // no error, inside \"eq\" fn\n        }\n    }\n}\n\nfn main() {\n    ZERO == 0f32; //no error, comparison with zero is ok\n    1.0f32 != f32::INFINITY; // also comparison with infinity\n    1.0f32 != f32::NEG_INFINITY; // and negative infinity\n    ZERO == 0.0; //no error, comparison with zero is ok\n    ZERO + ZERO != 1.0; //no error, comparison with zero is ok\n\n    let x = X { val: 1.0 };\n    x == 1.0; // no error, custom type that implement PartialOrder for float is not checked\n\n    ONE == 1f32;\n    ONE == 1.0 + 0.0;\n    ONE + ONE == ZERO + ONE + ONE;\n    ONE != 2.0;\n    ONE != 0.0; // no error, comparison with zero is ok\n    twice(ONE) != ONE;\n    ONE as f64 != 2.0;\n    //~^ float_cmp\n\n    ONE as f64 != 0.0; // no error, comparison with zero is ok\n\n    let x: f64 = 1.0;\n\n    x == 1.0;\n    //~^ float_cmp\n\n    x != 0f64; // no error, comparison with zero is ok\n\n    twice(x) != twice(ONE as f64);\n    //~^ float_cmp\n\n    x < 0.0; // no errors, lower or greater comparisons need no fuzzyness\n    x > 0.0;\n    x <= 0.0;\n    x >= 0.0;\n\n    let xs: [f32; 1] = [0.0];\n    let a: *const f32 = xs.as_ptr();\n    let b: *const f32 = xs.as_ptr();\n\n    assert_eq!(a, b); // no errors\n\n    const ZERO_ARRAY: [f32; 2] = [0.0, 0.0];\n    const NON_ZERO_ARRAY: [f32; 2] = [0.0, 0.1];\n\n    let i = 0;\n    let j = 1;\n\n    ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; // ok, because lhs is zero regardless of i\n    NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j];\n    //~^ float_cmp\n\n    let a1: [f32; 1] = [0.0];\n    let a2: [f32; 1] = [1.1];\n\n    a1 == a2;\n    //~^ float_cmp\n\n    a1[0] == a2[0];\n    //~^ float_cmp\n\n    // no errors - comparing signums is ok\n    let x32 = 3.21f32;\n    1.23f32.signum() == x32.signum();\n    1.23f32.signum() == -(x32.signum());\n    1.23f32.signum() == 3.21f32.signum();\n\n    1.23f32.signum() != x32.signum();\n    1.23f32.signum() != -(x32.signum());\n    1.23f32.signum() != 3.21f32.signum();\n\n    let x64 = 3.21f64;\n    1.23f64.signum() == x64.signum();\n    1.23f64.signum() == -(x64.signum());\n    1.23f64.signum() == 3.21f64.signum();\n\n    1.23f64.signum() != x64.signum();\n    1.23f64.signum() != -(x64.signum());\n    1.23f64.signum() != 3.21f64.signum();\n\n    // the comparison should also look through references\n    &0.0 == &ZERO;\n    &&&&0.0 == &&&&ZERO;\n}\n"
  },
  {
    "path": "tests/ui/float_cmp.stderr",
    "content": "error: strict comparison of `f32` or `f64`\n  --> tests/ui/float_cmp.rs:72:5\n   |\nLL |     ONE as f64 != 2.0;\n   |     ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin`\n   |\n   = note: `-D clippy::float-cmp` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::float_cmp)]`\n\nerror: strict comparison of `f32` or `f64`\n  --> tests/ui/float_cmp.rs:79:5\n   |\nLL |     x == 1.0;\n   |     ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin`\n\nerror: strict comparison of `f32` or `f64`\n  --> tests/ui/float_cmp.rs:84:5\n   |\nLL |     twice(x) != twice(ONE as f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin`\n\nerror: strict comparison of `f32` or `f64`\n  --> tests/ui/float_cmp.rs:105:5\n   |\nLL |     NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin`\n\nerror: strict comparison of `f32` or `f64` arrays\n  --> tests/ui/float_cmp.rs:111:5\n   |\nLL |     a1 == a2;\n   |     ^^^^^^^^\n\nerror: strict comparison of `f32` or `f64`\n  --> tests/ui/float_cmp.rs:114:5\n   |\nLL |     a1[0] == a2[0];\n   |     ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/float_cmp_const.rs",
    "content": "//@no-rustfix: suggestions have an error margin placeholder\n#![warn(clippy::float_cmp_const)]\n#![allow(clippy::float_cmp)]\n#![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]\n\nconst ONE: f32 = 1.0;\nconst TWO: f32 = 2.0;\n\nfn eq_one(x: f32) -> bool {\n    if x.is_nan() { false } else { x == ONE } // no error, inside \"eq\" fn\n}\n\nfn main() {\n    // has errors\n    1f32 == ONE;\n    //~^ float_cmp_const\n\n    TWO == ONE;\n    //~^ float_cmp_const\n\n    TWO != ONE;\n    //~^ float_cmp_const\n\n    ONE + ONE == TWO;\n    //~^ float_cmp_const\n\n    let x = 1;\n    x as f32 == ONE;\n    //~^ float_cmp_const\n\n    let v = 0.9;\n    v == ONE;\n    //~^ float_cmp_const\n\n    v != ONE;\n    //~^ float_cmp_const\n\n    // no errors, lower than or greater than comparisons\n    v < ONE;\n    v > ONE;\n    v <= ONE;\n    v >= ONE;\n\n    // no errors, zero and infinity values\n    ONE != 0f32;\n    TWO == 0f32;\n    ONE != f32::INFINITY;\n    ONE == f32::NEG_INFINITY;\n\n    // no errors, but will warn clippy::float_cmp if '#![allow(float_cmp)]' above is removed\n    let w = 1.1;\n    v == w;\n    v != w;\n    v == 1.0;\n    v != 1.0;\n\n    const ZERO_ARRAY: [f32; 3] = [0.0, 0.0, 0.0];\n    const ZERO_INF_ARRAY: [f32; 3] = [0.0, f32::INFINITY, f32::NEG_INFINITY];\n    const NON_ZERO_ARRAY: [f32; 3] = [0.0, 0.1, 0.2];\n    const NON_ZERO_ARRAY2: [f32; 3] = [0.2, 0.1, 0.0];\n\n    // no errors, zero and infinity values\n    NON_ZERO_ARRAY[0] == NON_ZERO_ARRAY2[1]; // lhs is 0.0\n    ZERO_ARRAY == NON_ZERO_ARRAY; // lhs is all zeros\n    ZERO_INF_ARRAY == NON_ZERO_ARRAY; // lhs is all zeros or infinities\n\n    // has errors\n    NON_ZERO_ARRAY == NON_ZERO_ARRAY2;\n    //~^ float_cmp_const\n}\n"
  },
  {
    "path": "tests/ui/float_cmp_const.stderr",
    "content": "error: strict comparison of `f32` or `f64` constant\n  --> tests/ui/float_cmp_const.rs:15:5\n   |\nLL |     1f32 == ONE;\n   |     ^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1f32 - ONE).abs() < error_margin`\n   |\n   = note: `-D clippy::float-cmp-const` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::float_cmp_const)]`\n\nerror: strict comparison of `f32` or `f64` constant\n  --> tests/ui/float_cmp_const.rs:18:5\n   |\nLL |     TWO == ONE;\n   |     ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() < error_margin`\n\nerror: strict comparison of `f32` or `f64` constant\n  --> tests/ui/float_cmp_const.rs:21:5\n   |\nLL |     TWO != ONE;\n   |     ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() > error_margin`\n\nerror: strict comparison of `f32` or `f64` constant\n  --> tests/ui/float_cmp_const.rs:24:5\n   |\nLL |     ONE + ONE == TWO;\n   |     ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE + ONE - TWO).abs() < error_margin`\n\nerror: strict comparison of `f32` or `f64` constant\n  --> tests/ui/float_cmp_const.rs:28:5\n   |\nLL |     x as f32 == ONE;\n   |     ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin`\n\nerror: strict comparison of `f32` or `f64` constant\n  --> tests/ui/float_cmp_const.rs:32:5\n   |\nLL |     v == ONE;\n   |     ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin`\n\nerror: strict comparison of `f32` or `f64` constant\n  --> tests/ui/float_cmp_const.rs:35:5\n   |\nLL |     v != ONE;\n   |     ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin`\n\nerror: strict comparison of `f32` or `f64` constant arrays\n  --> tests/ui/float_cmp_const.rs:68:5\n   |\nLL |     NON_ZERO_ARRAY == NON_ZERO_ARRAY2;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/float_equality_without_abs.rs",
    "content": "#![feature(f128)]\n#![feature(f16)]\n#![warn(clippy::float_equality_without_abs)]\n//@no-rustfix: suggestions cause type ambiguity\n\npub fn is_roughly_equal(a: f32, b: f32) -> bool {\n    (a - b) < f32::EPSILON\n    //~^ float_equality_without_abs\n}\n\npub fn main() {\n    // all errors\n    is_roughly_equal(1.0, 2.0);\n    let a = 0.05;\n    let b = 0.0500001;\n\n    let _ = (a - b) < f32::EPSILON;\n    //~^ float_equality_without_abs\n\n    let _ = a - b < f32::EPSILON;\n    //~^ float_equality_without_abs\n\n    let _ = a - b.abs() < f32::EPSILON;\n    //~^ float_equality_without_abs\n\n    let _ = (a as f64 - b as f64) < f64::EPSILON;\n    //~^ float_equality_without_abs\n\n    let _ = 1.0 - 2.0 < f32::EPSILON;\n    //~^ float_equality_without_abs\n\n    let _ = f32::EPSILON > (a - b);\n    //~^ float_equality_without_abs\n\n    let _ = f32::EPSILON > a - b;\n    //~^ float_equality_without_abs\n\n    let _ = f32::EPSILON > a - b.abs();\n    //~^ float_equality_without_abs\n\n    let _ = f64::EPSILON > (a as f64 - b as f64);\n    //~^ float_equality_without_abs\n\n    let _ = f32::EPSILON > 1.0 - 2.0;\n    //~^ float_equality_without_abs\n\n    let _ = (a as f16 - b as f16) < f16::EPSILON;\n    //~^ float_equality_without_abs\n\n    let _ = (a as f128 - b as f128) < f128::EPSILON;\n    //~^ float_equality_without_abs\n\n    // those are correct\n    let _ = (a as f16 - b as f16).abs() < f16::EPSILON;\n    let _ = (a - b).abs() < f32::EPSILON;\n    let _ = (a as f64 - b as f64).abs() < f64::EPSILON;\n    let _ = (a as f128 - b as f128).abs() < f128::EPSILON;\n\n    let _ = f16::EPSILON > (a as f16 - b as f16).abs();\n    let _ = f32::EPSILON > (a - b).abs();\n    let _ = f64::EPSILON > (a as f64 - b as f64).abs();\n    let _ = f128::EPSILON > (a as f128 - b as f128).abs();\n}\n"
  },
  {
    "path": "tests/ui/float_equality_without_abs.stderr",
    "content": "error: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:7:5\n   |\nLL |     (a - b) < f32::EPSILON\n   |     -------^^^^^^^^^^^^^^^\n   |     |\n   |     help: add `.abs()`: `(a - b).abs()`\n   |\n   = note: `-D clippy::float-equality-without-abs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::float_equality_without_abs)]`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:17:13\n   |\nLL |     let _ = (a - b) < f32::EPSILON;\n   |             -------^^^^^^^^^^^^^^^\n   |             |\n   |             help: add `.abs()`: `(a - b).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:20:13\n   |\nLL |     let _ = a - b < f32::EPSILON;\n   |             -----^^^^^^^^^^^^^^^\n   |             |\n   |             help: add `.abs()`: `(a - b).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:23:13\n   |\nLL |     let _ = a - b.abs() < f32::EPSILON;\n   |             -----------^^^^^^^^^^^^^^^\n   |             |\n   |             help: add `.abs()`: `(a - b.abs()).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:26:13\n   |\nLL |     let _ = (a as f64 - b as f64) < f64::EPSILON;\n   |             ---------------------^^^^^^^^^^^^^^^\n   |             |\n   |             help: add `.abs()`: `(a as f64 - b as f64).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:29:13\n   |\nLL |     let _ = 1.0 - 2.0 < f32::EPSILON;\n   |             ---------^^^^^^^^^^^^^^^\n   |             |\n   |             help: add `.abs()`: `(1.0 - 2.0).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:32:13\n   |\nLL |     let _ = f32::EPSILON > (a - b);\n   |             ^^^^^^^^^^^^^^^-------\n   |                            |\n   |                            help: add `.abs()`: `(a - b).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:35:13\n   |\nLL |     let _ = f32::EPSILON > a - b;\n   |             ^^^^^^^^^^^^^^^-----\n   |                            |\n   |                            help: add `.abs()`: `(a - b).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:38:13\n   |\nLL |     let _ = f32::EPSILON > a - b.abs();\n   |             ^^^^^^^^^^^^^^^-----------\n   |                            |\n   |                            help: add `.abs()`: `(a - b.abs()).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:41:13\n   |\nLL |     let _ = f64::EPSILON > (a as f64 - b as f64);\n   |             ^^^^^^^^^^^^^^^---------------------\n   |                            |\n   |                            help: add `.abs()`: `(a as f64 - b as f64).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:44:13\n   |\nLL |     let _ = f32::EPSILON > 1.0 - 2.0;\n   |             ^^^^^^^^^^^^^^^---------\n   |                            |\n   |                            help: add `.abs()`: `(1.0 - 2.0).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:47:13\n   |\nLL |     let _ = (a as f16 - b as f16) < f16::EPSILON;\n   |             ---------------------^^^^^^^^^^^^^^^\n   |             |\n   |             help: add `.abs()`: `(a as f16 - b as f16).abs()`\n\nerror: float equality check without `.abs()`\n  --> tests/ui/float_equality_without_abs.rs:50:13\n   |\nLL |     let _ = (a as f128 - b as f128) < f128::EPSILON;\n   |             -----------------------^^^^^^^^^^^^^^^^\n   |             |\n   |             help: add `.abs()`: `(a as f128 - b as f128).abs()`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_abs.fixed",
    "content": "#![warn(clippy::suboptimal_flops)]\n\n/// Allow suboptimal ops in constant context\npub const fn in_const_context(num: f64) -> f64 {\n    if num >= 0.0 { num } else { -num }\n}\n\nstruct A {\n    a: f64,\n    b: f64,\n}\n\nfn fake_abs1(num: f64) -> f64 {\n    num.abs()\n    //~^ suboptimal_flops\n}\n\nfn fake_abs2(num: f64) -> f64 {\n    num.abs()\n    //~^ suboptimal_flops\n}\n\nfn fake_abs3(a: A) -> f64 {\n    a.a.abs()\n    //~^ suboptimal_flops\n}\n\nfn fake_abs4(num: f64) -> f64 {\n    num.abs()\n    //~^ suboptimal_flops\n}\n\nfn fake_abs5(a: A) -> f64 {\n    a.a.abs()\n    //~^ suboptimal_flops\n}\n\nfn fake_nabs1(num: f64) -> f64 {\n    -num.abs()\n    //~^ suboptimal_flops\n}\n\nfn fake_nabs2(num: f64) -> f64 {\n    -num.abs()\n    //~^ suboptimal_flops\n}\n\nfn fake_nabs3(a: A) -> A {\n    A {\n        a: -a.a.abs(),\n        //~^ suboptimal_flops\n        b: a.b,\n    }\n}\n\nfn not_fake_abs1(num: f64) -> f64 {\n    if num > 0.0 { num } else { -num - 1f64 }\n}\n\nfn not_fake_abs2(num: f64) -> f64 {\n    if num > 0.0 { num + 1.0 } else { -(num + 1.0) }\n}\n\nfn not_fake_abs3(num1: f64, num2: f64) -> f64 {\n    if num1 > 0.0 { num2 } else { -num2 }\n}\n\nfn not_fake_abs4(a: A) -> f64 {\n    if a.a > 0.0 { a.b } else { -a.b }\n}\n\nfn not_fake_abs5(a: A) -> f64 {\n    if a.a > 0.0 { a.a } else { -a.b }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/floating_point_abs.rs",
    "content": "#![warn(clippy::suboptimal_flops)]\n\n/// Allow suboptimal ops in constant context\npub const fn in_const_context(num: f64) -> f64 {\n    if num >= 0.0 { num } else { -num }\n}\n\nstruct A {\n    a: f64,\n    b: f64,\n}\n\nfn fake_abs1(num: f64) -> f64 {\n    if num >= 0.0 { num } else { -num }\n    //~^ suboptimal_flops\n}\n\nfn fake_abs2(num: f64) -> f64 {\n    if 0.0 < num { num } else { -num }\n    //~^ suboptimal_flops\n}\n\nfn fake_abs3(a: A) -> f64 {\n    if a.a > 0.0 { a.a } else { -a.a }\n    //~^ suboptimal_flops\n}\n\nfn fake_abs4(num: f64) -> f64 {\n    if 0.0 >= num { -num } else { num }\n    //~^ suboptimal_flops\n}\n\nfn fake_abs5(a: A) -> f64 {\n    if a.a < 0.0 { -a.a } else { a.a }\n    //~^ suboptimal_flops\n}\n\nfn fake_nabs1(num: f64) -> f64 {\n    if num < 0.0 { num } else { -num }\n    //~^ suboptimal_flops\n}\n\nfn fake_nabs2(num: f64) -> f64 {\n    if 0.0 >= num { num } else { -num }\n    //~^ suboptimal_flops\n}\n\nfn fake_nabs3(a: A) -> A {\n    A {\n        a: if a.a >= 0.0 { -a.a } else { a.a },\n        //~^ suboptimal_flops\n        b: a.b,\n    }\n}\n\nfn not_fake_abs1(num: f64) -> f64 {\n    if num > 0.0 { num } else { -num - 1f64 }\n}\n\nfn not_fake_abs2(num: f64) -> f64 {\n    if num > 0.0 { num + 1.0 } else { -(num + 1.0) }\n}\n\nfn not_fake_abs3(num1: f64, num2: f64) -> f64 {\n    if num1 > 0.0 { num2 } else { -num2 }\n}\n\nfn not_fake_abs4(a: A) -> f64 {\n    if a.a > 0.0 { a.b } else { -a.b }\n}\n\nfn not_fake_abs5(a: A) -> f64 {\n    if a.a > 0.0 { a.a } else { -a.b }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/floating_point_abs.stderr",
    "content": "error: manual implementation of `abs` method\n  --> tests/ui/floating_point_abs.rs:14:5\n   |\nLL |     if num >= 0.0 { num } else { -num }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`\n   |\n   = note: `-D clippy::suboptimal-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`\n\nerror: manual implementation of `abs` method\n  --> tests/ui/floating_point_abs.rs:19:5\n   |\nLL |     if 0.0 < num { num } else { -num }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`\n\nerror: manual implementation of `abs` method\n  --> tests/ui/floating_point_abs.rs:24:5\n   |\nLL |     if a.a > 0.0 { a.a } else { -a.a }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`\n\nerror: manual implementation of `abs` method\n  --> tests/ui/floating_point_abs.rs:29:5\n   |\nLL |     if 0.0 >= num { -num } else { num }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.abs()`\n\nerror: manual implementation of `abs` method\n  --> tests/ui/floating_point_abs.rs:34:5\n   |\nLL |     if a.a < 0.0 { -a.a } else { a.a }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.a.abs()`\n\nerror: manual implementation of negation of `abs` method\n  --> tests/ui/floating_point_abs.rs:39:5\n   |\nLL |     if num < 0.0 { num } else { -num }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`\n\nerror: manual implementation of negation of `abs` method\n  --> tests/ui/floating_point_abs.rs:44:5\n   |\nLL |     if 0.0 >= num { num } else { -num }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-num.abs()`\n\nerror: manual implementation of negation of `abs` method\n  --> tests/ui/floating_point_abs.rs:50:12\n   |\nLL |         a: if a.a >= 0.0 { -a.a } else { a.a },\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-a.a.abs()`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_arithmetic_nostd.rs",
    "content": "//@ check-pass\n\n#![crate_type = \"lib\"]\n#![warn(clippy::imprecise_flops)]\n#![warn(clippy::suboptimal_flops)]\n#![no_std]\n\n// The following should not lint, as the suggested methods `{f16,f32,f64,f128}.mul_add()`\n// and `{f16,f32,f64,f128}::abs()` are not available in no_std\n\npub fn mul_add() {\n    let a: f64 = 1234.567;\n    let b: f64 = 45.67834;\n    let c: f64 = 0.0004;\n    let _ = a * b + c;\n}\n\nfn fake_abs1(num: f64) -> f64 {\n    if num >= 0.0 { num } else { -num }\n}\n\npub fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    0\n}\n"
  },
  {
    "path": "tests/ui/floating_point_exp.fixed",
    "content": "// FIXME(f16_f128): add tests when exp is available\n\n#![warn(clippy::imprecise_flops)]\n#![allow(clippy::unnecessary_cast)]\n\nfn main() {\n    let x = 2f32;\n    let _ = x.exp_m1();\n    //~^ imprecise_flops\n    let _ = x.exp_m1() + 2.0;\n    //~^ imprecise_flops\n    let _ = (x as f32).exp_m1() + 2.0;\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    let _ = x.exp() - 2.0;\n    let _ = x.exp() - 1.0 * 2.0;\n\n    let x = 2f64;\n    let _ = x.exp_m1();\n    //~^ imprecise_flops\n    let _ = x.exp_m1() + 2.0;\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    let _ = x.exp() - 2.0;\n    let _ = x.exp() - 1.0 * 2.0;\n}\n"
  },
  {
    "path": "tests/ui/floating_point_exp.rs",
    "content": "// FIXME(f16_f128): add tests when exp is available\n\n#![warn(clippy::imprecise_flops)]\n#![allow(clippy::unnecessary_cast)]\n\nfn main() {\n    let x = 2f32;\n    let _ = x.exp() - 1.0;\n    //~^ imprecise_flops\n    let _ = x.exp() - 1.0 + 2.0;\n    //~^ imprecise_flops\n    let _ = (x as f32).exp() - 1.0 + 2.0;\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    let _ = x.exp() - 2.0;\n    let _ = x.exp() - 1.0 * 2.0;\n\n    let x = 2f64;\n    let _ = x.exp() - 1.0;\n    //~^ imprecise_flops\n    let _ = x.exp() - 1.0 + 2.0;\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    let _ = x.exp() - 2.0;\n    let _ = x.exp() - 1.0 * 2.0;\n}\n"
  },
  {
    "path": "tests/ui/floating_point_exp.stderr",
    "content": "error: (e.pow(x) - 1) can be computed more accurately\n  --> tests/ui/floating_point_exp.rs:8:13\n   |\nLL |     let _ = x.exp() - 1.0;\n   |             ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`\n   |\n   = note: `-D clippy::imprecise-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]`\n\nerror: (e.pow(x) - 1) can be computed more accurately\n  --> tests/ui/floating_point_exp.rs:10:13\n   |\nLL |     let _ = x.exp() - 1.0 + 2.0;\n   |             ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`\n\nerror: (e.pow(x) - 1) can be computed more accurately\n  --> tests/ui/floating_point_exp.rs:12:13\n   |\nLL |     let _ = (x as f32).exp() - 1.0 + 2.0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).exp_m1()`\n\nerror: (e.pow(x) - 1) can be computed more accurately\n  --> tests/ui/floating_point_exp.rs:19:13\n   |\nLL |     let _ = x.exp() - 1.0;\n   |             ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`\n\nerror: (e.pow(x) - 1) can be computed more accurately\n  --> tests/ui/floating_point_exp.rs:21:13\n   |\nLL |     let _ = x.exp() - 1.0 + 2.0;\n   |             ^^^^^^^^^^^^^ help: consider using: `x.exp_m1()`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_hypot.fixed",
    "content": "#![warn(clippy::imprecise_flops)]\n\nfn main() {\n    let x = 3f32;\n    let y = 4f32;\n    let _ = x.hypot(y);\n    //~^ imprecise_flops\n    let _ = (x + 1f32).hypot(y);\n    //~^ imprecise_flops\n    let _ = x.hypot(y);\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    // TODO: linting this adds some complexity, but could be done\n    let _ = x.mul_add(x, y * y).sqrt();\n    let _ = (x * 4f32 + y * y).sqrt();\n}\n"
  },
  {
    "path": "tests/ui/floating_point_hypot.rs",
    "content": "#![warn(clippy::imprecise_flops)]\n\nfn main() {\n    let x = 3f32;\n    let y = 4f32;\n    let _ = (x * x + y * y).sqrt();\n    //~^ imprecise_flops\n    let _ = ((x + 1f32) * (x + 1f32) + y * y).sqrt();\n    //~^ imprecise_flops\n    let _ = (x.powi(2) + y.powi(2)).sqrt();\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    // TODO: linting this adds some complexity, but could be done\n    let _ = x.mul_add(x, y * y).sqrt();\n    let _ = (x * 4f32 + y * y).sqrt();\n}\n"
  },
  {
    "path": "tests/ui/floating_point_hypot.stderr",
    "content": "error: hypotenuse can be computed more accurately\n  --> tests/ui/floating_point_hypot.rs:6:13\n   |\nLL |     let _ = (x * x + y * y).sqrt();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)`\n   |\n   = note: `-D clippy::imprecise-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]`\n\nerror: hypotenuse can be computed more accurately\n  --> tests/ui/floating_point_hypot.rs:8:13\n   |\nLL |     let _ = ((x + 1f32) * (x + 1f32) + y * y).sqrt();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 1f32).hypot(y)`\n\nerror: hypotenuse can be computed more accurately\n  --> tests/ui/floating_point_hypot.rs:10:13\n   |\nLL |     let _ = (x.powi(2) + y.powi(2)).sqrt();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.hypot(y)`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_log.fixed",
    "content": "#![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)]\n#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]\n\n// FIXME(f16_f128): add tests for these types once math functions are available\n\nconst TWO: f32 = 2.0;\nconst E: f32 = std::f32::consts::E;\n\nfn check_log_base() {\n    let x = 1f32;\n    let _ = x.log2();\n    //~^ suboptimal_flops\n    let _ = x.log10();\n    //~^ suboptimal_flops\n    let _ = x.ln();\n    //~^ suboptimal_flops\n    let _ = x.log(TWO);\n    let _ = x.log(E);\n    let _ = (x as f32).log2();\n    //~^ suboptimal_flops\n\n    let x = 1f64;\n    let _ = x.log2();\n    //~^ suboptimal_flops\n    let _ = x.log10();\n    //~^ suboptimal_flops\n    let _ = x.ln();\n    //~^ suboptimal_flops\n}\n\nfn check_ln1p() {\n    let x = 1f32;\n    let _ = 2.0f32.ln_1p();\n    //~^ imprecise_flops\n    let _ = 2.0f32.ln_1p();\n    //~^ imprecise_flops\n    let _ = x.ln_1p();\n    //~^ imprecise_flops\n    let _ = (x / 2.0).ln_1p();\n    //~^ imprecise_flops\n    let _ = x.powi(3).ln_1p();\n    //~^ imprecise_flops\n    let _ = (x.powi(3) / 2.0).ln_1p();\n    //~^ imprecise_flops\n    let _ = (std::f32::consts::E - 1.0).ln_1p();\n    //~^ imprecise_flops\n    let _ = x.ln_1p();\n    //~^ imprecise_flops\n    let _ = x.powi(3).ln_1p();\n    //~^ imprecise_flops\n    let _ = (x + 2.0).ln_1p();\n    //~^ imprecise_flops\n    let _ = (x / 2.0).ln_1p();\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    let _ = (1.0 + x + 2.0).ln();\n    let _ = (x + 1.0 + 2.0).ln();\n    let _ = (x + 1.0 / 2.0).ln();\n    let _ = (1.0 + x - 2.0).ln();\n\n    let x = 1f64;\n    let _ = 2.0f64.ln_1p();\n    //~^ imprecise_flops\n    let _ = 2.0f64.ln_1p();\n    //~^ imprecise_flops\n    let _ = x.ln_1p();\n    //~^ imprecise_flops\n    let _ = (x / 2.0).ln_1p();\n    //~^ imprecise_flops\n    let _ = x.powi(3).ln_1p();\n    //~^ imprecise_flops\n    let _ = x.ln_1p();\n    //~^ imprecise_flops\n    let _ = x.powi(3).ln_1p();\n    //~^ imprecise_flops\n    let _ = (x + 2.0).ln_1p();\n    //~^ imprecise_flops\n    let _ = (x / 2.0).ln_1p();\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    let _ = (1.0 + x + 2.0).ln();\n    let _ = (x + 1.0 + 2.0).ln();\n    let _ = (x + 1.0 / 2.0).ln();\n    let _ = (1.0 + x - 2.0).ln();\n}\n\nfn issue12881() {\n    pub trait MyLog {\n        fn log(&self) -> Self;\n    }\n\n    impl MyLog for f32 {\n        fn log(&self) -> Self {\n            4.\n        }\n    }\n\n    let x = 2.0;\n    x.log();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/floating_point_log.rs",
    "content": "#![allow(dead_code, clippy::double_parens, clippy::unnecessary_cast)]\n#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]\n\n// FIXME(f16_f128): add tests for these types once math functions are available\n\nconst TWO: f32 = 2.0;\nconst E: f32 = std::f32::consts::E;\n\nfn check_log_base() {\n    let x = 1f32;\n    let _ = x.log(2f32);\n    //~^ suboptimal_flops\n    let _ = x.log(10f32);\n    //~^ suboptimal_flops\n    let _ = x.log(std::f32::consts::E);\n    //~^ suboptimal_flops\n    let _ = x.log(TWO);\n    let _ = x.log(E);\n    let _ = (x as f32).log(2f32);\n    //~^ suboptimal_flops\n\n    let x = 1f64;\n    let _ = x.log(2f64);\n    //~^ suboptimal_flops\n    let _ = x.log(10f64);\n    //~^ suboptimal_flops\n    let _ = x.log(std::f64::consts::E);\n    //~^ suboptimal_flops\n}\n\nfn check_ln1p() {\n    let x = 1f32;\n    let _ = (1f32 + 2.).ln();\n    //~^ imprecise_flops\n    let _ = (1f32 + 2.0).ln();\n    //~^ imprecise_flops\n    let _ = (1.0 + x).ln();\n    //~^ imprecise_flops\n    let _ = (1.0 + x / 2.0).ln();\n    //~^ imprecise_flops\n    let _ = (1.0 + x.powi(3)).ln();\n    //~^ imprecise_flops\n    let _ = (1.0 + x.powi(3) / 2.0).ln();\n    //~^ imprecise_flops\n    let _ = (1.0 + (std::f32::consts::E - 1.0)).ln();\n    //~^ imprecise_flops\n    let _ = (x + 1.0).ln();\n    //~^ imprecise_flops\n    let _ = (x.powi(3) + 1.0).ln();\n    //~^ imprecise_flops\n    let _ = (x + 2.0 + 1.0).ln();\n    //~^ imprecise_flops\n    let _ = (x / 2.0 + 1.0).ln();\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    let _ = (1.0 + x + 2.0).ln();\n    let _ = (x + 1.0 + 2.0).ln();\n    let _ = (x + 1.0 / 2.0).ln();\n    let _ = (1.0 + x - 2.0).ln();\n\n    let x = 1f64;\n    let _ = (1f64 + 2.).ln();\n    //~^ imprecise_flops\n    let _ = (1f64 + 2.0).ln();\n    //~^ imprecise_flops\n    let _ = (1.0 + x).ln();\n    //~^ imprecise_flops\n    let _ = (1.0 + x / 2.0).ln();\n    //~^ imprecise_flops\n    let _ = (1.0 + x.powi(3)).ln();\n    //~^ imprecise_flops\n    let _ = (x + 1.0).ln();\n    //~^ imprecise_flops\n    let _ = (x.powi(3) + 1.0).ln();\n    //~^ imprecise_flops\n    let _ = (x + 2.0 + 1.0).ln();\n    //~^ imprecise_flops\n    let _ = (x / 2.0 + 1.0).ln();\n    //~^ imprecise_flops\n    // Cases where the lint shouldn't be applied\n    let _ = (1.0 + x + 2.0).ln();\n    let _ = (x + 1.0 + 2.0).ln();\n    let _ = (x + 1.0 / 2.0).ln();\n    let _ = (1.0 + x - 2.0).ln();\n}\n\nfn issue12881() {\n    pub trait MyLog {\n        fn log(&self) -> Self;\n    }\n\n    impl MyLog for f32 {\n        fn log(&self) -> Self {\n            4.\n        }\n    }\n\n    let x = 2.0;\n    x.log();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/floating_point_log.stderr",
    "content": "error: logarithm for bases 2, 10 and e can be computed more accurately\n  --> tests/ui/floating_point_log.rs:11:13\n   |\nLL |     let _ = x.log(2f32);\n   |             ^^^^^^^^^^^ help: consider using: `x.log2()`\n   |\n   = note: `-D clippy::suboptimal-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`\n\nerror: logarithm for bases 2, 10 and e can be computed more accurately\n  --> tests/ui/floating_point_log.rs:13:13\n   |\nLL |     let _ = x.log(10f32);\n   |             ^^^^^^^^^^^^ help: consider using: `x.log10()`\n\nerror: logarithm for bases 2, 10 and e can be computed more accurately\n  --> tests/ui/floating_point_log.rs:15:13\n   |\nLL |     let _ = x.log(std::f32::consts::E);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()`\n\nerror: logarithm for bases 2, 10 and e can be computed more accurately\n  --> tests/ui/floating_point_log.rs:19:13\n   |\nLL |     let _ = (x as f32).log(2f32);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log2()`\n\nerror: logarithm for bases 2, 10 and e can be computed more accurately\n  --> tests/ui/floating_point_log.rs:23:13\n   |\nLL |     let _ = x.log(2f64);\n   |             ^^^^^^^^^^^ help: consider using: `x.log2()`\n\nerror: logarithm for bases 2, 10 and e can be computed more accurately\n  --> tests/ui/floating_point_log.rs:25:13\n   |\nLL |     let _ = x.log(10f64);\n   |             ^^^^^^^^^^^^ help: consider using: `x.log10()`\n\nerror: logarithm for bases 2, 10 and e can be computed more accurately\n  --> tests/ui/floating_point_log.rs:27:13\n   |\nLL |     let _ = x.log(std::f64::consts::E);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.ln()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:33:13\n   |\nLL |     let _ = (1f32 + 2.).ln();\n   |             ^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()`\n   |\n   = note: `-D clippy::imprecise-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:35:13\n   |\nLL |     let _ = (1f32 + 2.0).ln();\n   |             ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f32.ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:37:13\n   |\nLL |     let _ = (1.0 + x).ln();\n   |             ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:39:13\n   |\nLL |     let _ = (1.0 + x / 2.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:41:13\n   |\nLL |     let _ = (1.0 + x.powi(3)).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:43:13\n   |\nLL |     let _ = (1.0 + x.powi(3) / 2.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x.powi(3) / 2.0).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:45:13\n   |\nLL |     let _ = (1.0 + (std::f32::consts::E - 1.0)).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(std::f32::consts::E - 1.0).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:47:13\n   |\nLL |     let _ = (x + 1.0).ln();\n   |             ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:49:13\n   |\nLL |     let _ = (x.powi(3) + 1.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:51:13\n   |\nLL |     let _ = (x + 2.0 + 1.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:53:13\n   |\nLL |     let _ = (x / 2.0 + 1.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:62:13\n   |\nLL |     let _ = (1f64 + 2.).ln();\n   |             ^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:64:13\n   |\nLL |     let _ = (1f64 + 2.0).ln();\n   |             ^^^^^^^^^^^^^^^^^ help: consider using: `2.0f64.ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:66:13\n   |\nLL |     let _ = (1.0 + x).ln();\n   |             ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:68:13\n   |\nLL |     let _ = (1.0 + x / 2.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:70:13\n   |\nLL |     let _ = (1.0 + x.powi(3)).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:72:13\n   |\nLL |     let _ = (x + 1.0).ln();\n   |             ^^^^^^^^^^^^^^ help: consider using: `x.ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:74:13\n   |\nLL |     let _ = (x.powi(3) + 1.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(3).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:76:13\n   |\nLL |     let _ = (x + 2.0 + 1.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x + 2.0).ln_1p()`\n\nerror: ln(1 + x) can be computed more accurately\n  --> tests/ui/floating_point_log.rs:78:13\n   |\nLL |     let _ = (x / 2.0 + 1.0).ln();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x / 2.0).ln_1p()`\n\nerror: aborting due to 27 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_logbase.fixed",
    "content": "#![warn(clippy::suboptimal_flops)]\n#![allow(clippy::unnecessary_cast)]\n\nfn main() {\n    let x = 3f32;\n    let y = 5f32;\n    let _ = x.log(y);\n    //~^ suboptimal_flops\n    let _ = (x as f32).log(y);\n    //~^ suboptimal_flops\n    let _ = x.log(y);\n    //~^ suboptimal_flops\n    let _ = x.log(y);\n    //~^ suboptimal_flops\n    let _ = x.log(y);\n    //~^ suboptimal_flops\n    // Cases where the lint shouldn't be applied\n    let _ = x.ln() / y.powf(3.2);\n    let _ = x.powf(3.2) / y.powf(3.2);\n    let _ = x.powf(3.2) / y.ln();\n    let _ = x.log(5f32) / y.log(7f32);\n}\n"
  },
  {
    "path": "tests/ui/floating_point_logbase.rs",
    "content": "#![warn(clippy::suboptimal_flops)]\n#![allow(clippy::unnecessary_cast)]\n\nfn main() {\n    let x = 3f32;\n    let y = 5f32;\n    let _ = x.ln() / y.ln();\n    //~^ suboptimal_flops\n    let _ = (x as f32).ln() / y.ln();\n    //~^ suboptimal_flops\n    let _ = x.log2() / y.log2();\n    //~^ suboptimal_flops\n    let _ = x.log10() / y.log10();\n    //~^ suboptimal_flops\n    let _ = x.log(5f32) / y.log(5f32);\n    //~^ suboptimal_flops\n    // Cases where the lint shouldn't be applied\n    let _ = x.ln() / y.powf(3.2);\n    let _ = x.powf(3.2) / y.powf(3.2);\n    let _ = x.powf(3.2) / y.ln();\n    let _ = x.log(5f32) / y.log(7f32);\n}\n"
  },
  {
    "path": "tests/ui/floating_point_logbase.stderr",
    "content": "error: log base can be expressed more clearly\n  --> tests/ui/floating_point_logbase.rs:7:13\n   |\nLL |     let _ = x.ln() / y.ln();\n   |             ^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`\n   |\n   = note: `-D clippy::suboptimal-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`\n\nerror: log base can be expressed more clearly\n  --> tests/ui/floating_point_logbase.rs:9:13\n   |\nLL |     let _ = (x as f32).ln() / y.ln();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).log(y)`\n\nerror: log base can be expressed more clearly\n  --> tests/ui/floating_point_logbase.rs:11:13\n   |\nLL |     let _ = x.log2() / y.log2();\n   |             ^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`\n\nerror: log base can be expressed more clearly\n  --> tests/ui/floating_point_logbase.rs:13:13\n   |\nLL |     let _ = x.log10() / y.log10();\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`\n\nerror: log base can be expressed more clearly\n  --> tests/ui/floating_point_logbase.rs:15:13\n   |\nLL |     let _ = x.log(5f32) / y.log(5f32);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.log(y)`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_mul_add.fixed",
    "content": "#![warn(clippy::suboptimal_flops)]\n\n/// Allow suboptimal_ops in constant context\npub const fn in_const_context() {\n    let a: f64 = 1234.567;\n    let b: f64 = 45.67834;\n    let c: f64 = 0.0004;\n\n    let _ = a * b + c;\n    let _ = c + a * b;\n}\n\nfn main() {\n    let a: f64 = 1234.567;\n    let b: f64 = 45.67834;\n    let c: f64 = 0.0004;\n    let d: f64 = 0.0001;\n\n    let _ = a.mul_add(b, c);\n    //~^ suboptimal_flops\n    let _ = a.mul_add(b, -c);\n    //~^ suboptimal_flops\n    let _ = a.mul_add(b, c);\n    //~^ suboptimal_flops\n    let _ = a.mul_add(-b, c);\n    //~^ suboptimal_flops\n    let _ = 2.0f64.mul_add(4.0, a);\n    //~^ suboptimal_flops\n    let _ = 2.0f64.mul_add(4., a);\n    //~^ suboptimal_flops\n\n    let _ = a.mul_add(b, c);\n    //~^ suboptimal_flops\n    let _ = a.mul_add(b, c);\n    //~^ suboptimal_flops\n    let _ = (a * b).mul_add(c, d);\n    //~^ suboptimal_flops\n\n    let _ = a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c)) + c;\n    //~^ suboptimal_flops\n    let _ = 1234.567_f64.mul_add(45.67834_f64, 0.0004_f64);\n    //~^ suboptimal_flops\n\n    let _ = a.mul_add(a, b).sqrt();\n    //~^ suboptimal_flops\n\n    let u = 1usize;\n    let _ = b.mul_add(-(u as f64), a);\n    //~^ suboptimal_flops\n\n    // Cases where the lint shouldn't be applied\n    let _ = (a * a + b * b).sqrt();\n}\n\nfn _issue11831() {\n    struct NotAFloat;\n\n    impl std::ops::Add<f64> for NotAFloat {\n        type Output = Self;\n\n        fn add(self, _: f64) -> Self {\n            NotAFloat\n        }\n    }\n\n    let a = NotAFloat;\n    let b = 1.0_f64;\n    let c = 1.0;\n\n    let _ = a + b * c;\n}\n\nfn _issue14897() {\n    let x = 1.0;\n    let _ = x * 2.0 + 0.5; // should not suggest mul_add\n    let _ = 0.5 + x * 2.0; // should not suggest mul_add\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n    let _ = 1.2 + x * 1.2; // should not suggest mul_add\n\n    let x = -1.0;\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let x = { 4.0 };\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let x = if 1 > 2 { 1.0 } else { 2.0 };\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let x = 2.4 + 1.2;\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let f = || 4.0;\n    let x = f();\n    let _ = 0.5 + f() * 1.2; // should not suggest mul_add\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let x = 0.1;\n    let y = x;\n    let z = y;\n    let _ = 0.5 + z * 1.2; // should not suggest mul_add\n\n    let _ = 2.0f64.mul_add(x, 0.5);\n    //~^ suboptimal_flops\n    let _ = 2.0f64.mul_add(x, 0.5);\n    //~^ suboptimal_flops\n\n    let _ = 2.0f64.mul_add(4.0, x);\n    //~^ suboptimal_flops\n\n    let y: f64 = 1.0;\n    let _ = y.mul_add(2.0, 0.5);\n    //~^ suboptimal_flops\n    let _ = 1.0f64.mul_add(2.0, 0.5);\n    //~^ suboptimal_flops\n}\n\nfn issue16573() {\n    let mut a = 3.0_f32;\n    let b = 4.0_f32;\n    let c = 7.0_f32;\n\n    a = b.mul_add(c, a);\n    //~^ suboptimal_flops\n\n    a = b.mul_add(-c, a);\n    //~^ suboptimal_flops\n}\n"
  },
  {
    "path": "tests/ui/floating_point_mul_add.rs",
    "content": "#![warn(clippy::suboptimal_flops)]\n\n/// Allow suboptimal_ops in constant context\npub const fn in_const_context() {\n    let a: f64 = 1234.567;\n    let b: f64 = 45.67834;\n    let c: f64 = 0.0004;\n\n    let _ = a * b + c;\n    let _ = c + a * b;\n}\n\nfn main() {\n    let a: f64 = 1234.567;\n    let b: f64 = 45.67834;\n    let c: f64 = 0.0004;\n    let d: f64 = 0.0001;\n\n    let _ = a * b + c;\n    //~^ suboptimal_flops\n    let _ = a * b - c;\n    //~^ suboptimal_flops\n    let _ = c + a * b;\n    //~^ suboptimal_flops\n    let _ = c - a * b;\n    //~^ suboptimal_flops\n    let _ = a + 2.0 * 4.0;\n    //~^ suboptimal_flops\n    let _ = a + 2. * 4.;\n    //~^ suboptimal_flops\n\n    let _ = (a * b) + c;\n    //~^ suboptimal_flops\n    let _ = c + (a * b);\n    //~^ suboptimal_flops\n    let _ = a * b * c + d;\n    //~^ suboptimal_flops\n\n    let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c;\n    //~^ suboptimal_flops\n    let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64;\n    //~^ suboptimal_flops\n\n    let _ = (a * a + b).sqrt();\n    //~^ suboptimal_flops\n\n    let u = 1usize;\n    let _ = a - (b * u as f64);\n    //~^ suboptimal_flops\n\n    // Cases where the lint shouldn't be applied\n    let _ = (a * a + b * b).sqrt();\n}\n\nfn _issue11831() {\n    struct NotAFloat;\n\n    impl std::ops::Add<f64> for NotAFloat {\n        type Output = Self;\n\n        fn add(self, _: f64) -> Self {\n            NotAFloat\n        }\n    }\n\n    let a = NotAFloat;\n    let b = 1.0_f64;\n    let c = 1.0;\n\n    let _ = a + b * c;\n}\n\nfn _issue14897() {\n    let x = 1.0;\n    let _ = x * 2.0 + 0.5; // should not suggest mul_add\n    let _ = 0.5 + x * 2.0; // should not suggest mul_add\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n    let _ = 1.2 + x * 1.2; // should not suggest mul_add\n\n    let x = -1.0;\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let x = { 4.0 };\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let x = if 1 > 2 { 1.0 } else { 2.0 };\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let x = 2.4 + 1.2;\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let f = || 4.0;\n    let x = f();\n    let _ = 0.5 + f() * 1.2; // should not suggest mul_add\n    let _ = 0.5 + x * 1.2; // should not suggest mul_add\n\n    let x = 0.1;\n    let y = x;\n    let z = y;\n    let _ = 0.5 + z * 1.2; // should not suggest mul_add\n\n    let _ = 0.5 + 2.0 * x;\n    //~^ suboptimal_flops\n    let _ = 2.0 * x + 0.5;\n    //~^ suboptimal_flops\n\n    let _ = x + 2.0 * 4.0;\n    //~^ suboptimal_flops\n\n    let y: f64 = 1.0;\n    let _ = y * 2.0 + 0.5;\n    //~^ suboptimal_flops\n    let _ = 1.0 * 2.0 + 0.5;\n    //~^ suboptimal_flops\n}\n\nfn issue16573() {\n    let mut a = 3.0_f32;\n    let b = 4.0_f32;\n    let c = 7.0_f32;\n\n    a += b * c;\n    //~^ suboptimal_flops\n\n    a -= b * c;\n    //~^ suboptimal_flops\n}\n"
  },
  {
    "path": "tests/ui/floating_point_mul_add.stderr",
    "content": "error: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:19:13\n   |\nLL |     let _ = a * b + c;\n   |             ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`\n   |\n   = note: `-D clippy::suboptimal-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:21:13\n   |\nLL |     let _ = a * b - c;\n   |             ^^^^^^^^^ help: consider using: `a.mul_add(b, -c)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:23:13\n   |\nLL |     let _ = c + a * b;\n   |             ^^^^^^^^^ help: consider using: `a.mul_add(b, c)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:25:13\n   |\nLL |     let _ = c - a * b;\n   |             ^^^^^^^^^ help: consider using: `a.mul_add(-b, c)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:27:13\n   |\nLL |     let _ = a + 2.0 * 4.0;\n   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, a)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:29:13\n   |\nLL |     let _ = a + 2. * 4.;\n   |             ^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4., a)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:32:13\n   |\nLL |     let _ = (a * b) + c;\n   |             ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:34:13\n   |\nLL |     let _ = c + (a * b);\n   |             ^^^^^^^^^^^ help: consider using: `a.mul_add(b, c)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:36:13\n   |\nLL |     let _ = a * b * c + d;\n   |             ^^^^^^^^^^^^^ help: consider using: `(a * b).mul_add(c, d)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:39:13\n   |\nLL |     let _ = a.mul_add(b, c) * a.mul_add(b, c) + a.mul_add(b, c) + c;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `a.mul_add(b, c).mul_add(a.mul_add(b, c), a.mul_add(b, c))`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:41:13\n   |\nLL |     let _ = 1234.567_f64 * 45.67834_f64 + 0.0004_f64;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1234.567_f64.mul_add(45.67834_f64, 0.0004_f64)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:44:13\n   |\nLL |     let _ = (a * a + b).sqrt();\n   |             ^^^^^^^^^^^ help: consider using: `a.mul_add(a, b)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:48:13\n   |\nLL |     let _ = a - (b * u as f64);\n   |             ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:102:13\n   |\nLL |     let _ = 0.5 + 2.0 * x;\n   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(x, 0.5)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:104:13\n   |\nLL |     let _ = 2.0 * x + 0.5;\n   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(x, 0.5)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:107:13\n   |\nLL |     let _ = x + 2.0 * 4.0;\n   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, x)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:111:13\n   |\nLL |     let _ = y * 2.0 + 0.5;\n   |             ^^^^^^^^^^^^^ help: consider using: `y.mul_add(2.0, 0.5)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:113:13\n   |\nLL |     let _ = 1.0 * 2.0 + 0.5;\n   |             ^^^^^^^^^^^^^^^ help: consider using: `1.0f64.mul_add(2.0, 0.5)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:122:5\n   |\nLL |     a += b * c;\n   |     ^^^^^^^^^^ help: consider using: `a = b.mul_add(c, a)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_mul_add.rs:125:5\n   |\nLL |     a -= b * c;\n   |     ^^^^^^^^^^ help: consider using: `a = b.mul_add(-c, a)`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_powf.fixed",
    "content": "#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]\n#![allow(clippy::unnecessary_cast)]\n\n// FIXME(f16_f128): add tests for these types when `powf` is available\n\nfn main() {\n    let x = 3f32;\n    let _ = x.exp2();\n    //~^ suboptimal_flops\n    let _ = 3.1f32.exp2();\n    //~^ suboptimal_flops\n    let _ = (-3.1f32).exp2();\n    //~^ suboptimal_flops\n    let _ = x.exp();\n    //~^ suboptimal_flops\n    let _ = 3.1f32.exp();\n    //~^ suboptimal_flops\n    let _ = (-3.1f32).exp();\n    //~^ suboptimal_flops\n    let _ = x.sqrt();\n    //~^ suboptimal_flops\n    let _ = x.cbrt();\n    //~^ imprecise_flops\n    let _ = (x as f32).cbrt();\n    //~^ imprecise_flops\n    let _ = x.powi(3);\n    //~^ suboptimal_flops\n    let _ = x.powi(-2);\n    //~^ suboptimal_flops\n    let _ = x.powi(16_777_215);\n    //~^ suboptimal_flops\n    let _ = x.powi(-16_777_215);\n    //~^ suboptimal_flops\n    let _ = (x as f32).powi(-16_777_215);\n    //~^ suboptimal_flops\n    let _ = (x as f32).powi(3);\n    //~^ suboptimal_flops\n    let _ = (1.5_f32 + 1.0).cbrt();\n    //~^ imprecise_flops\n    let _ = 1.5_f64.cbrt();\n    //~^ imprecise_flops\n    let _ = 1.5_f64.sqrt();\n    //~^ suboptimal_flops\n    let _ = 1.5_f64.powi(3);\n    //~^ suboptimal_flops\n\n    macro_rules! m {\n        ($e:expr) => {\n            5.5 - $e\n        };\n    }\n\n    let _ = (1f32 + m!(2.0)).exp2();\n    //~^ suboptimal_flops\n\n    // Cases where the lint shouldn't be applied\n    let _ = x.powf(2.1);\n    let _ = x.powf(-2.1);\n    let _ = x.powf(16_777_216.0);\n    let _ = x.powf(-16_777_216.0);\n\n    let x = 3f64;\n    let _ = x.exp2();\n    //~^ suboptimal_flops\n    let _ = 3.1f64.exp2();\n    //~^ suboptimal_flops\n    let _ = (-3.1f64).exp2();\n    //~^ suboptimal_flops\n    let _ = x.exp();\n    //~^ suboptimal_flops\n    let _ = 3.1f64.exp();\n    //~^ suboptimal_flops\n    let _ = (-3.1f64).exp();\n    //~^ suboptimal_flops\n    let _ = x.sqrt();\n    //~^ suboptimal_flops\n    let _ = x.cbrt();\n    //~^ imprecise_flops\n    let _ = x.powi(3);\n    //~^ suboptimal_flops\n    let _ = x.powi(-2);\n    //~^ suboptimal_flops\n    let _ = x.powi(-2_147_483_648);\n    //~^ suboptimal_flops\n    let _ = x.powi(2_147_483_647);\n    //~^ suboptimal_flops\n    // Cases where the lint shouldn't be applied\n    let _ = x.powf(2.1);\n    let _ = x.powf(-2.1);\n    let _ = x.powf(-2_147_483_649.0);\n    let _ = x.powf(2_147_483_648.0);\n}\n"
  },
  {
    "path": "tests/ui/floating_point_powf.rs",
    "content": "#![warn(clippy::suboptimal_flops, clippy::imprecise_flops)]\n#![allow(clippy::unnecessary_cast)]\n\n// FIXME(f16_f128): add tests for these types when `powf` is available\n\nfn main() {\n    let x = 3f32;\n    let _ = 2f32.powf(x);\n    //~^ suboptimal_flops\n    let _ = 2f32.powf(3.1);\n    //~^ suboptimal_flops\n    let _ = 2f32.powf(-3.1);\n    //~^ suboptimal_flops\n    let _ = std::f32::consts::E.powf(x);\n    //~^ suboptimal_flops\n    let _ = std::f32::consts::E.powf(3.1);\n    //~^ suboptimal_flops\n    let _ = std::f32::consts::E.powf(-3.1);\n    //~^ suboptimal_flops\n    let _ = x.powf(1.0 / 2.0);\n    //~^ suboptimal_flops\n    let _ = x.powf(1.0 / 3.0);\n    //~^ imprecise_flops\n    let _ = (x as f32).powf(1.0 / 3.0);\n    //~^ imprecise_flops\n    let _ = x.powf(3.0);\n    //~^ suboptimal_flops\n    let _ = x.powf(-2.0);\n    //~^ suboptimal_flops\n    let _ = x.powf(16_777_215.0);\n    //~^ suboptimal_flops\n    let _ = x.powf(-16_777_215.0);\n    //~^ suboptimal_flops\n    let _ = (x as f32).powf(-16_777_215.0);\n    //~^ suboptimal_flops\n    let _ = (x as f32).powf(3.0);\n    //~^ suboptimal_flops\n    let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0);\n    //~^ imprecise_flops\n    let _ = 1.5_f64.powf(1.0 / 3.0);\n    //~^ imprecise_flops\n    let _ = 1.5_f64.powf(1.0 / 2.0);\n    //~^ suboptimal_flops\n    let _ = 1.5_f64.powf(3.0);\n    //~^ suboptimal_flops\n\n    macro_rules! m {\n        ($e:expr) => {\n            5.5 - $e\n        };\n    }\n\n    let _ = 2f32.powf(1f32 + m!(2.0));\n    //~^ suboptimal_flops\n\n    // Cases where the lint shouldn't be applied\n    let _ = x.powf(2.1);\n    let _ = x.powf(-2.1);\n    let _ = x.powf(16_777_216.0);\n    let _ = x.powf(-16_777_216.0);\n\n    let x = 3f64;\n    let _ = 2f64.powf(x);\n    //~^ suboptimal_flops\n    let _ = 2f64.powf(3.1);\n    //~^ suboptimal_flops\n    let _ = 2f64.powf(-3.1);\n    //~^ suboptimal_flops\n    let _ = std::f64::consts::E.powf(x);\n    //~^ suboptimal_flops\n    let _ = std::f64::consts::E.powf(3.1);\n    //~^ suboptimal_flops\n    let _ = std::f64::consts::E.powf(-3.1);\n    //~^ suboptimal_flops\n    let _ = x.powf(1.0 / 2.0);\n    //~^ suboptimal_flops\n    let _ = x.powf(1.0 / 3.0);\n    //~^ imprecise_flops\n    let _ = x.powf(3.0);\n    //~^ suboptimal_flops\n    let _ = x.powf(-2.0);\n    //~^ suboptimal_flops\n    let _ = x.powf(-2_147_483_648.0);\n    //~^ suboptimal_flops\n    let _ = x.powf(2_147_483_647.0);\n    //~^ suboptimal_flops\n    // Cases where the lint shouldn't be applied\n    let _ = x.powf(2.1);\n    let _ = x.powf(-2.1);\n    let _ = x.powf(-2_147_483_649.0);\n    let _ = x.powf(2_147_483_648.0);\n}\n"
  },
  {
    "path": "tests/ui/floating_point_powf.stderr",
    "content": "error: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:8:13\n   |\nLL |     let _ = 2f32.powf(x);\n   |             ^^^^^^^^^^^^ help: consider using: `x.exp2()`\n   |\n   = note: `-D clippy::suboptimal-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:10:13\n   |\nLL |     let _ = 2f32.powf(3.1);\n   |             ^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp2()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:12:13\n   |\nLL |     let _ = 2f32.powf(-3.1);\n   |             ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp2()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:14:13\n   |\nLL |     let _ = std::f32::consts::E.powf(x);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:16:13\n   |\nLL |     let _ = std::f32::consts::E.powf(3.1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f32.exp()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:18:13\n   |\nLL |     let _ = std::f32::consts::E.powf(-3.1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f32).exp()`\n\nerror: square-root of a number can be computed more efficiently and accurately\n  --> tests/ui/floating_point_powf.rs:20:13\n   |\nLL |     let _ = x.powf(1.0 / 2.0);\n   |             ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()`\n\nerror: cube-root of a number can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:22:13\n   |\nLL |     let _ = x.powf(1.0 / 3.0);\n   |             ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()`\n   |\n   = note: `-D clippy::imprecise-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::imprecise_flops)]`\n\nerror: cube-root of a number can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:24:13\n   |\nLL |     let _ = (x as f32).powf(1.0 / 3.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).cbrt()`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:26:13\n   |\nLL |     let _ = x.powf(3.0);\n   |             ^^^^^^^^^^^ help: consider using: `x.powi(3)`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:28:13\n   |\nLL |     let _ = x.powf(-2.0);\n   |             ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:30:13\n   |\nLL |     let _ = x.powf(16_777_215.0);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(16_777_215)`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:32:13\n   |\nLL |     let _ = x.powf(-16_777_215.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-16_777_215)`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:34:13\n   |\nLL |     let _ = (x as f32).powf(-16_777_215.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(-16_777_215)`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:36:13\n   |\nLL |     let _ = (x as f32).powf(3.0);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x as f32).powi(3)`\n\nerror: cube-root of a number can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:38:13\n   |\nLL |     let _ = (1.5_f32 + 1.0).powf(1.0 / 3.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1.5_f32 + 1.0).cbrt()`\n\nerror: cube-root of a number can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:40:13\n   |\nLL |     let _ = 1.5_f64.powf(1.0 / 3.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.cbrt()`\n\nerror: square-root of a number can be computed more efficiently and accurately\n  --> tests/ui/floating_point_powf.rs:42:13\n   |\nLL |     let _ = 1.5_f64.powf(1.0 / 2.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.sqrt()`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:44:13\n   |\nLL |     let _ = 1.5_f64.powf(3.0);\n   |             ^^^^^^^^^^^^^^^^^ help: consider using: `1.5_f64.powi(3)`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:53:13\n   |\nLL |     let _ = 2f32.powf(1f32 + m!(2.0));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(1f32 + m!(2.0)).exp2()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:63:13\n   |\nLL |     let _ = 2f64.powf(x);\n   |             ^^^^^^^^^^^^ help: consider using: `x.exp2()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:65:13\n   |\nLL |     let _ = 2f64.powf(3.1);\n   |             ^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp2()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:67:13\n   |\nLL |     let _ = 2f64.powf(-3.1);\n   |             ^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp2()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:69:13\n   |\nLL |     let _ = std::f64::consts::E.powf(x);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.exp()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:71:13\n   |\nLL |     let _ = std::f64::consts::E.powf(3.1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `3.1f64.exp()`\n\nerror: exponent for bases 2 and e can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:73:13\n   |\nLL |     let _ = std::f64::consts::E.powf(-3.1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-3.1f64).exp()`\n\nerror: square-root of a number can be computed more efficiently and accurately\n  --> tests/ui/floating_point_powf.rs:75:13\n   |\nLL |     let _ = x.powf(1.0 / 2.0);\n   |             ^^^^^^^^^^^^^^^^^ help: consider using: `x.sqrt()`\n\nerror: cube-root of a number can be computed more accurately\n  --> tests/ui/floating_point_powf.rs:77:13\n   |\nLL |     let _ = x.powf(1.0 / 3.0);\n   |             ^^^^^^^^^^^^^^^^^ help: consider using: `x.cbrt()`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:79:13\n   |\nLL |     let _ = x.powf(3.0);\n   |             ^^^^^^^^^^^ help: consider using: `x.powi(3)`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:81:13\n   |\nLL |     let _ = x.powf(-2.0);\n   |             ^^^^^^^^^^^^ help: consider using: `x.powi(-2)`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:83:13\n   |\nLL |     let _ = x.powf(-2_147_483_648.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(-2_147_483_648)`\n\nerror: exponentiation with integer powers can be computed more efficiently\n  --> tests/ui/floating_point_powf.rs:85:13\n   |\nLL |     let _ = x.powf(2_147_483_647.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.powi(2_147_483_647)`\n\nerror: aborting due to 32 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_powi.fixed",
    "content": "#![warn(clippy::suboptimal_flops)]\n#![allow(clippy::unnecessary_cast)]\n\nfn main() {\n    let one = 1;\n    let x = 3f32;\n\n    let y = 4f32;\n    let _ = x.mul_add(x, y);\n    //~^ suboptimal_flops\n    let _ = x.mul_add(x, -y);\n    //~^ suboptimal_flops\n    let _ = y.mul_add(y, x);\n    //~^ suboptimal_flops\n    let _ = y.mul_add(-y, x);\n    //~^ suboptimal_flops\n    let _ = (y as f32).mul_add(y as f32, x);\n    //~^ suboptimal_flops\n    let _ = x.mul_add(x, y).sqrt();\n    //~^ suboptimal_flops\n    let _ = y.mul_add(y, x).sqrt();\n    //~^ suboptimal_flops\n\n    let _ = (x - 1.0).mul_add(x - 1.0, -y);\n    //~^ suboptimal_flops\n    let _ = (x - 1.0).mul_add(x - 1.0, -y) + 3.0;\n    //~^ suboptimal_flops\n    let _ = (x - 1.0).mul_add(x - 1.0, -(y + 3.0));\n    //~^ suboptimal_flops\n    let _ = (y + 1.0).mul_add(-(y + 1.0), x);\n    //~^ suboptimal_flops\n    let _ = (3.0 * y).mul_add(-(3.0 * y), x);\n    //~^ suboptimal_flops\n    let _ = (y + 1.0 + x).mul_add(-(y + 1.0 + x), x);\n    //~^ suboptimal_flops\n    let _ = (y + 1.0 + 2.0).mul_add(-(y + 1.0 + 2.0), x);\n    //~^ suboptimal_flops\n\n    // Cases where the lint shouldn't be applied\n    let _ = x.powi(2);\n    let _ = x.powi(1 + 1);\n    let _ = x.powi(3);\n    let _ = x.powi(4) + y;\n    let _ = x.powi(one + 1);\n    let _ = (x.powi(2) + y.powi(2)).sqrt();\n}\n"
  },
  {
    "path": "tests/ui/floating_point_powi.rs",
    "content": "#![warn(clippy::suboptimal_flops)]\n#![allow(clippy::unnecessary_cast)]\n\nfn main() {\n    let one = 1;\n    let x = 3f32;\n\n    let y = 4f32;\n    let _ = x.powi(2) + y;\n    //~^ suboptimal_flops\n    let _ = x.powi(2) - y;\n    //~^ suboptimal_flops\n    let _ = x + y.powi(2);\n    //~^ suboptimal_flops\n    let _ = x - y.powi(2);\n    //~^ suboptimal_flops\n    let _ = x + (y as f32).powi(2);\n    //~^ suboptimal_flops\n    let _ = (x.powi(2) + y).sqrt();\n    //~^ suboptimal_flops\n    let _ = (x + y.powi(2)).sqrt();\n    //~^ suboptimal_flops\n\n    let _ = (x - 1.0).powi(2) - y;\n    //~^ suboptimal_flops\n    let _ = (x - 1.0).powi(2) - y + 3.0;\n    //~^ suboptimal_flops\n    let _ = (x - 1.0).powi(2) - (y + 3.0);\n    //~^ suboptimal_flops\n    let _ = x - (y + 1.0).powi(2);\n    //~^ suboptimal_flops\n    let _ = x - (3.0 * y).powi(2);\n    //~^ suboptimal_flops\n    let _ = x - (y + 1.0 + x).powi(2);\n    //~^ suboptimal_flops\n    let _ = x - (y + 1.0 + 2.0).powi(2);\n    //~^ suboptimal_flops\n\n    // Cases where the lint shouldn't be applied\n    let _ = x.powi(2);\n    let _ = x.powi(1 + 1);\n    let _ = x.powi(3);\n    let _ = x.powi(4) + y;\n    let _ = x.powi(one + 1);\n    let _ = (x.powi(2) + y.powi(2)).sqrt();\n}\n"
  },
  {
    "path": "tests/ui/floating_point_powi.stderr",
    "content": "error: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:9:13\n   |\nLL |     let _ = x.powi(2) + y;\n   |             ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`\n   |\n   = note: `-D clippy::suboptimal-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:11:13\n   |\nLL |     let _ = x.powi(2) - y;\n   |             ^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, -y)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:13:13\n   |\nLL |     let _ = x + y.powi(2);\n   |             ^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:15:13\n   |\nLL |     let _ = x - y.powi(2);\n   |             ^^^^^^^^^^^^^ help: consider using: `y.mul_add(-y, x)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:17:13\n   |\nLL |     let _ = x + (y as f32).powi(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y as f32).mul_add(y as f32, x)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:19:13\n   |\nLL |     let _ = (x.powi(2) + y).sqrt();\n   |             ^^^^^^^^^^^^^^^ help: consider using: `x.mul_add(x, y)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:21:13\n   |\nLL |     let _ = (x + y.powi(2)).sqrt();\n   |             ^^^^^^^^^^^^^^^ help: consider using: `y.mul_add(y, x)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:24:13\n   |\nLL |     let _ = (x - 1.0).powi(2) - y;\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -y)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:26:13\n   |\nLL |     let _ = (x - 1.0).powi(2) - y + 3.0;\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -y)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:28:13\n   |\nLL |     let _ = (x - 1.0).powi(2) - (y + 3.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(x - 1.0).mul_add(x - 1.0, -(y + 3.0))`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:30:13\n   |\nLL |     let _ = x - (y + 1.0).powi(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0).mul_add(-(y + 1.0), x)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:32:13\n   |\nLL |     let _ = x - (3.0 * y).powi(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(3.0 * y).mul_add(-(3.0 * y), x)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:34:13\n   |\nLL |     let _ = x - (y + 1.0 + x).powi(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0 + x).mul_add(-(y + 1.0 + x), x)`\n\nerror: multiply and add expressions can be calculated more efficiently and accurately\n  --> tests/ui/floating_point_powi.rs:36:13\n   |\nLL |     let _ = x - (y + 1.0 + 2.0).powi(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(y + 1.0 + 2.0).mul_add(-(y + 1.0 + 2.0), x)`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/floating_point_rad.fixed",
    "content": "#![warn(clippy::suboptimal_flops)]\n\n/// Allow suboptimal_flops in constant context\npub const fn const_context() {\n    let x = 3f32;\n    let _ = x * 180f32 / std::f32::consts::PI;\n}\n\npub fn issue9391(degrees: i64) {\n    let _ = (degrees as f64).to_radians();\n    //~^ suboptimal_flops\n    let _ = (degrees as f64).to_degrees();\n    //~^ suboptimal_flops\n}\n\nfn main() {\n    let x = 3f32;\n    let _ = x.to_degrees();\n    //~^ suboptimal_flops\n    let _ = 90.0_f64.to_degrees();\n    //~^ suboptimal_flops\n    let _ = 90.5_f64.to_degrees();\n    //~^ suboptimal_flops\n    let _ = x.to_radians();\n    //~^ suboptimal_flops\n    let _ = 90.0_f64.to_radians();\n    //~^ suboptimal_flops\n    let _ = 90.5_f64.to_radians();\n    //~^ suboptimal_flops\n    // let _ = 90.5 * 80. * std::f32::consts::PI / 180f32;\n    // Cases where the lint shouldn't be applied\n    let _ = x * 90f32 / std::f32::consts::PI;\n    let _ = x * std::f32::consts::PI / 90f32;\n    let _ = x * 180f32 / std::f32::consts::E;\n    let _ = x * std::f32::consts::E / 180f32;\n}\n"
  },
  {
    "path": "tests/ui/floating_point_rad.rs",
    "content": "#![warn(clippy::suboptimal_flops)]\n\n/// Allow suboptimal_flops in constant context\npub const fn const_context() {\n    let x = 3f32;\n    let _ = x * 180f32 / std::f32::consts::PI;\n}\n\npub fn issue9391(degrees: i64) {\n    let _ = degrees as f64 * std::f64::consts::PI / 180.0;\n    //~^ suboptimal_flops\n    let _ = degrees as f64 * 180.0 / std::f64::consts::PI;\n    //~^ suboptimal_flops\n}\n\nfn main() {\n    let x = 3f32;\n    let _ = x * 180f32 / std::f32::consts::PI;\n    //~^ suboptimal_flops\n    let _ = 90. * 180f64 / std::f64::consts::PI;\n    //~^ suboptimal_flops\n    let _ = 90.5 * 180f64 / std::f64::consts::PI;\n    //~^ suboptimal_flops\n    let _ = x * std::f32::consts::PI / 180f32;\n    //~^ suboptimal_flops\n    let _ = 90. * std::f32::consts::PI / 180f32;\n    //~^ suboptimal_flops\n    let _ = 90.5 * std::f32::consts::PI / 180f32;\n    //~^ suboptimal_flops\n    // let _ = 90.5 * 80. * std::f32::consts::PI / 180f32;\n    // Cases where the lint shouldn't be applied\n    let _ = x * 90f32 / std::f32::consts::PI;\n    let _ = x * std::f32::consts::PI / 90f32;\n    let _ = x * 180f32 / std::f32::consts::E;\n    let _ = x * std::f32::consts::E / 180f32;\n}\n"
  },
  {
    "path": "tests/ui/floating_point_rad.stderr",
    "content": "error: conversion to radians can be done more accurately\n  --> tests/ui/floating_point_rad.rs:10:13\n   |\nLL |     let _ = degrees as f64 * std::f64::consts::PI / 180.0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_radians()`\n   |\n   = note: `-D clippy::suboptimal-flops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suboptimal_flops)]`\n\nerror: conversion to degrees can be done more accurately\n  --> tests/ui/floating_point_rad.rs:12:13\n   |\nLL |     let _ = degrees as f64 * 180.0 / std::f64::consts::PI;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(degrees as f64).to_degrees()`\n\nerror: conversion to degrees can be done more accurately\n  --> tests/ui/floating_point_rad.rs:18:13\n   |\nLL |     let _ = x * 180f32 / std::f32::consts::PI;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_degrees()`\n\nerror: conversion to degrees can be done more accurately\n  --> tests/ui/floating_point_rad.rs:20:13\n   |\nLL |     let _ = 90. * 180f64 / std::f64::consts::PI;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_degrees()`\n\nerror: conversion to degrees can be done more accurately\n  --> tests/ui/floating_point_rad.rs:22:13\n   |\nLL |     let _ = 90.5 * 180f64 / std::f64::consts::PI;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_degrees()`\n\nerror: conversion to radians can be done more accurately\n  --> tests/ui/floating_point_rad.rs:24:13\n   |\nLL |     let _ = x * std::f32::consts::PI / 180f32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `x.to_radians()`\n\nerror: conversion to radians can be done more accurately\n  --> tests/ui/floating_point_rad.rs:26:13\n   |\nLL |     let _ = 90. * std::f32::consts::PI / 180f32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.0_f64.to_radians()`\n\nerror: conversion to radians can be done more accurately\n  --> tests/ui/floating_point_rad.rs:28:13\n   |\nLL |     let _ = 90.5 * std::f32::consts::PI / 180f32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `90.5_f64.to_radians()`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/fn_params_excessive_bools.rs",
    "content": "#![warn(clippy::fn_params_excessive_bools)]\n#![allow(clippy::too_many_arguments)]\n\nunsafe extern \"C\" {\n    // Should not lint, most of the time users have no control over extern function signatures\n    fn f(_: bool, _: bool, _: bool, _: bool);\n}\n\nmacro_rules! foo {\n    () => {\n        fn fff(_: bool, _: bool, _: bool, _: bool) {}\n    };\n}\n\nfoo!();\n\n#[unsafe(no_mangle)]\nunsafe extern \"C\" fn k(_: bool, _: bool, _: bool, _: bool) {}\nfn g(_: bool, _: bool, _: bool, _: bool) {}\n//~^ ERROR: more than 3 bools in function parameters\nfn h(_: bool, _: bool, _: bool) {}\nfn e(_: S, _: S, _: Box<S>, _: Vec<u32>) {}\nfn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool) {}\n//~^ ERROR: more than 3 bools in function parameters\n\nstruct S;\ntrait Trait {\n    // should warn for trait functions with and without body\n    fn f(_: bool, _: bool, _: bool, _: bool);\n    //~^ ERROR: more than 3 bools in function parameters\n    fn g(_: bool, _: bool, _: bool, _: Vec<u32>);\n    #[allow(clippy::fn_params_excessive_bools)]\n    fn h(_: bool, _: bool, _: bool, _: bool, _: bool, _: bool);\n    fn i(_: bool, _: bool, _: bool, _: bool) {}\n    //~^ ERROR: more than 3 bools in function parameters\n}\n\nimpl S {\n    fn f(&self, _: bool, _: bool, _: bool, _: bool) {}\n    //~^ ERROR: more than 3 bools in function parameters\n    fn g(&self, _: bool, _: bool, _: bool) {}\n    #[unsafe(no_mangle)]\n    unsafe extern \"C\" fn h(_: bool, _: bool, _: bool, _: bool) {}\n}\n\nimpl Trait for S {\n    // Should not lint because the trait might not be changeable by the user\n    // We only lint in the trait definition\n    fn f(_: bool, _: bool, _: bool, _: bool) {}\n    fn g(_: bool, _: bool, _: bool, _: Vec<u32>) {}\n    fn h(_: bool, _: bool, _: bool, _: bool, _: bool, _: bool) {}\n}\n\nfn main() {\n    fn n(_: bool, _: u32, _: bool, _: Box<u32>, _: bool, _: bool) {\n        //~^ ERROR: more than 3 bools in function parameters\n        fn nn(_: bool, _: bool, _: bool, _: bool) {}\n        //~^ ERROR: more than 3 bools in function parameters\n    }\n}\n"
  },
  {
    "path": "tests/ui/fn_params_excessive_bools.stderr",
    "content": "error: more than 3 bools in function parameters\n  --> tests/ui/fn_params_excessive_bools.rs:19:1\n   |\nLL | fn g(_: bool, _: bool, _: bool, _: bool) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider refactoring bools into two-variant enums\n   = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::fn_params_excessive_bools)]`\n\nerror: more than 3 bools in function parameters\n  --> tests/ui/fn_params_excessive_bools.rs:23:1\n   |\nLL | fn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider refactoring bools into two-variant enums\n\nerror: more than 3 bools in function parameters\n  --> tests/ui/fn_params_excessive_bools.rs:29:5\n   |\nLL |     fn f(_: bool, _: bool, _: bool, _: bool);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider refactoring bools into two-variant enums\n\nerror: more than 3 bools in function parameters\n  --> tests/ui/fn_params_excessive_bools.rs:34:5\n   |\nLL |     fn i(_: bool, _: bool, _: bool, _: bool) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider refactoring bools into two-variant enums\n\nerror: more than 3 bools in function parameters\n  --> tests/ui/fn_params_excessive_bools.rs:39:5\n   |\nLL |     fn f(&self, _: bool, _: bool, _: bool, _: bool) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider refactoring bools into two-variant enums\n\nerror: more than 3 bools in function parameters\n  --> tests/ui/fn_params_excessive_bools.rs:55:5\n   |\nLL | /     fn n(_: bool, _: u32, _: bool, _: Box<u32>, _: bool, _: bool) {\nLL | |\nLL | |         fn nn(_: bool, _: bool, _: bool, _: bool) {}\nLL | |\nLL | |     }\n   | |_____^\n   |\n   = help: consider refactoring bools into two-variant enums\n\nerror: more than 3 bools in function parameters\n  --> tests/ui/fn_params_excessive_bools.rs:57:9\n   |\nLL |         fn nn(_: bool, _: bool, _: bool, _: bool) {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider refactoring bools into two-variant enums\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/fn_to_numeric_cast.r32bit.stderr",
    "content": "error: casting function pointer `foo` to `i8`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:13:13\n   |\nLL |     let _ = foo as i8;\n   |             ^^^^^^^^^ help: try: `foo as usize`\n   |\n   = note: `-D clippy::fn-to-numeric-cast-with-truncation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]`\n\nerror: casting function pointer `foo` to `i16`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:15:13\n   |\nLL |     let _ = foo as i16;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `i32`\n  --> tests/ui/fn_to_numeric_cast.rs:17:13\n   |\nLL |     let _ = foo as i32;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n   |\n   = note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]`\n\nerror: casting function pointer `foo` to `i64`\n  --> tests/ui/fn_to_numeric_cast.rs:20:13\n   |\nLL |     let _ = foo as i64;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `i128`\n  --> tests/ui/fn_to_numeric_cast.rs:22:13\n   |\nLL |     let _ = foo as i128;\n   |             ^^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `isize`\n  --> tests/ui/fn_to_numeric_cast.rs:24:13\n   |\nLL |     let _ = foo as isize;\n   |             ^^^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u8`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:27:13\n   |\nLL |     let _ = foo as u8;\n   |             ^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u16`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:29:13\n   |\nLL |     let _ = foo as u16;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u32`\n  --> tests/ui/fn_to_numeric_cast.rs:31:13\n   |\nLL |     let _ = foo as u32;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u64`\n  --> tests/ui/fn_to_numeric_cast.rs:34:13\n   |\nLL |     let _ = foo as u64;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u128`\n  --> tests/ui/fn_to_numeric_cast.rs:36:13\n   |\nLL |     let _ = foo as u128;\n   |             ^^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `abc` to `i8`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:50:13\n   |\nLL |     let _ = abc as i8;\n   |             ^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `i16`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:52:13\n   |\nLL |     let _ = abc as i16;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `i32`\n  --> tests/ui/fn_to_numeric_cast.rs:54:13\n   |\nLL |     let _ = abc as i32;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `i64`\n  --> tests/ui/fn_to_numeric_cast.rs:57:13\n   |\nLL |     let _ = abc as i64;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `i128`\n  --> tests/ui/fn_to_numeric_cast.rs:59:13\n   |\nLL |     let _ = abc as i128;\n   |             ^^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `isize`\n  --> tests/ui/fn_to_numeric_cast.rs:61:13\n   |\nLL |     let _ = abc as isize;\n   |             ^^^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u8`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:64:13\n   |\nLL |     let _ = abc as u8;\n   |             ^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u16`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:66:13\n   |\nLL |     let _ = abc as u16;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u32`\n  --> tests/ui/fn_to_numeric_cast.rs:68:13\n   |\nLL |     let _ = abc as u32;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u64`\n  --> tests/ui/fn_to_numeric_cast.rs:71:13\n   |\nLL |     let _ = abc as u64;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u128`\n  --> tests/ui/fn_to_numeric_cast.rs:73:13\n   |\nLL |     let _ = abc as u128;\n   |             ^^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `f` to `i32`\n  --> tests/ui/fn_to_numeric_cast.rs:81:5\n   |\nLL |     f as i32\n   |     ^^^^^^^^ help: try: `f as usize`\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/fn_to_numeric_cast.r64bit.stderr",
    "content": "error: casting function pointer `foo` to `i8`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:13:13\n   |\nLL |     let _ = foo as i8;\n   |             ^^^^^^^^^ help: try: `foo as usize`\n   |\n   = note: `-D clippy::fn-to-numeric-cast-with-truncation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_with_truncation)]`\n\nerror: casting function pointer `foo` to `i16`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:15:13\n   |\nLL |     let _ = foo as i16;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `i32`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:17:13\n   |\nLL |     let _ = foo as i32;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `i64`\n  --> tests/ui/fn_to_numeric_cast.rs:20:13\n   |\nLL |     let _ = foo as i64;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n   |\n   = note: `-D clippy::fn-to-numeric-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast)]`\n\nerror: casting function pointer `foo` to `i128`\n  --> tests/ui/fn_to_numeric_cast.rs:22:13\n   |\nLL |     let _ = foo as i128;\n   |             ^^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `isize`\n  --> tests/ui/fn_to_numeric_cast.rs:24:13\n   |\nLL |     let _ = foo as isize;\n   |             ^^^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u8`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:27:13\n   |\nLL |     let _ = foo as u8;\n   |             ^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u16`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:29:13\n   |\nLL |     let _ = foo as u16;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u32`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:31:13\n   |\nLL |     let _ = foo as u32;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u64`\n  --> tests/ui/fn_to_numeric_cast.rs:34:13\n   |\nLL |     let _ = foo as u64;\n   |             ^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `foo` to `u128`\n  --> tests/ui/fn_to_numeric_cast.rs:36:13\n   |\nLL |     let _ = foo as u128;\n   |             ^^^^^^^^^^^ help: try: `foo as usize`\n\nerror: casting function pointer `abc` to `i8`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:50:13\n   |\nLL |     let _ = abc as i8;\n   |             ^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `i16`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:52:13\n   |\nLL |     let _ = abc as i16;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `i32`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:54:13\n   |\nLL |     let _ = abc as i32;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `i64`\n  --> tests/ui/fn_to_numeric_cast.rs:57:13\n   |\nLL |     let _ = abc as i64;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `i128`\n  --> tests/ui/fn_to_numeric_cast.rs:59:13\n   |\nLL |     let _ = abc as i128;\n   |             ^^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `isize`\n  --> tests/ui/fn_to_numeric_cast.rs:61:13\n   |\nLL |     let _ = abc as isize;\n   |             ^^^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u8`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:64:13\n   |\nLL |     let _ = abc as u8;\n   |             ^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u16`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:66:13\n   |\nLL |     let _ = abc as u16;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u32`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:68:13\n   |\nLL |     let _ = abc as u32;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u64`\n  --> tests/ui/fn_to_numeric_cast.rs:71:13\n   |\nLL |     let _ = abc as u64;\n   |             ^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `abc` to `u128`\n  --> tests/ui/fn_to_numeric_cast.rs:73:13\n   |\nLL |     let _ = abc as u128;\n   |             ^^^^^^^^^^^ help: try: `abc as usize`\n\nerror: casting function pointer `f` to `i32`, which truncates the value\n  --> tests/ui/fn_to_numeric_cast.rs:81:5\n   |\nLL |     f as i32\n   |     ^^^^^^^^ help: try: `f as usize`\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/fn_to_numeric_cast.rs",
    "content": "//@revisions: r32bit r64bit\n//@[r32bit]ignore-bitwidth: 64\n//@[r64bit]ignore-bitwidth: 32\n//@no-rustfix\n#![warn(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)]\n#![allow(function_casts_as_integer)]\n\nfn foo() -> String {\n    String::new()\n}\n\nfn test_function_to_numeric_cast() {\n    let _ = foo as i8;\n    //~^ fn_to_numeric_cast_with_truncation\n    let _ = foo as i16;\n    //~^ fn_to_numeric_cast_with_truncation\n    let _ = foo as i32;\n    //~[r64bit]^ fn_to_numeric_cast_with_truncation\n    //~[r32bit]^^ fn_to_numeric_cast\n    let _ = foo as i64;\n    //~^ fn_to_numeric_cast\n    let _ = foo as i128;\n    //~^ fn_to_numeric_cast\n    let _ = foo as isize;\n    //~^ fn_to_numeric_cast\n\n    let _ = foo as u8;\n    //~^ fn_to_numeric_cast_with_truncation\n    let _ = foo as u16;\n    //~^ fn_to_numeric_cast_with_truncation\n    let _ = foo as u32;\n    //~[r64bit]^ fn_to_numeric_cast_with_truncation\n    //~[r32bit]^^ fn_to_numeric_cast\n    let _ = foo as u64;\n    //~^ fn_to_numeric_cast\n    let _ = foo as u128;\n    //~^ fn_to_numeric_cast\n\n    // Casting to usize is OK and should not warn\n    let _ = foo as usize;\n\n    // Cast `f` (a `FnDef`) to `fn()` should not warn\n    fn f() {}\n    let _ = f as fn();\n}\n\nfn test_function_var_to_numeric_cast() {\n    let abc: fn() -> String = foo;\n\n    let _ = abc as i8;\n    //~^ fn_to_numeric_cast_with_truncation\n    let _ = abc as i16;\n    //~^ fn_to_numeric_cast_with_truncation\n    let _ = abc as i32;\n    //~[r64bit]^ fn_to_numeric_cast_with_truncation\n    //~[r32bit]^^ fn_to_numeric_cast\n    let _ = abc as i64;\n    //~^ fn_to_numeric_cast\n    let _ = abc as i128;\n    //~^ fn_to_numeric_cast\n    let _ = abc as isize;\n    //~^ fn_to_numeric_cast\n\n    let _ = abc as u8;\n    //~^ fn_to_numeric_cast_with_truncation\n    let _ = abc as u16;\n    //~^ fn_to_numeric_cast_with_truncation\n    let _ = abc as u32;\n    //~[r64bit]^ fn_to_numeric_cast_with_truncation\n    //~[r32bit]^^ fn_to_numeric_cast\n    let _ = abc as u64;\n    //~^ fn_to_numeric_cast\n    let _ = abc as u128;\n    //~^ fn_to_numeric_cast\n\n    // Casting to usize is OK and should not warn\n    let _ = abc as usize;\n}\n\nfn fn_with_fn_args(f: fn(i32) -> i32) -> i32 {\n    f as i32\n    //~[r64bit]^ fn_to_numeric_cast_with_truncation\n    //~[r32bit]^^ fn_to_numeric_cast\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/fn_to_numeric_cast_any.rs",
    "content": "#![warn(clippy::fn_to_numeric_cast_any)]\n#![allow(clippy::fn_to_numeric_cast, clippy::fn_to_numeric_cast_with_truncation)]\n#![allow(function_casts_as_integer)]\n//@no-rustfix\nfn foo() -> u8 {\n    0\n}\n\nfn generic_foo<T>(x: T) -> T {\n    x\n}\n\ntrait Trait {\n    fn static_method() -> u32 {\n        2\n    }\n}\n\nstruct Struct;\n\nimpl Trait for Struct {}\n\nfn fn_pointer_to_integer() {\n    let _ = foo as i8;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as i16;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as i32;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as i64;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as i128;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as isize;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as u8;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as u16;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as u32;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as u64;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as u128;\n    //~^ fn_to_numeric_cast_any\n\n    let _ = foo as usize;\n    //~^ fn_to_numeric_cast_any\n}\n\nfn static_method_to_integer() {\n    let _ = Struct::static_method as usize;\n    //~^ fn_to_numeric_cast_any\n}\n\nfn fn_with_fn_arg(f: fn(i32) -> u32) -> usize {\n    f as usize\n    //~^ fn_to_numeric_cast_any\n}\n\nfn fn_with_generic_static_trait_method<T: Trait>() -> usize {\n    T::static_method as usize\n    //~^ fn_to_numeric_cast_any\n}\n\nfn closure_to_fn_to_integer() {\n    let clos = |x| x * 2_u32;\n\n    let _ = (clos as fn(u32) -> u32) as usize;\n    //~^ fn_to_numeric_cast_any\n}\n\nfn fn_to_raw_ptr() {\n    let _ = foo as *const ();\n    //~^ fn_to_numeric_cast_any\n}\n\nfn cast_fn_to_self() {\n    // Casting to the same function pointer type should be permitted.\n    let _ = foo as fn() -> u8;\n}\n\nfn cast_generic_to_concrete() {\n    // Casting to a more concrete function pointer type should be permitted.\n    let _ = generic_foo as fn(usize) -> usize;\n}\n\nfn cast_closure_to_fn() {\n    // Casting a closure to a function pointer should be permitted.\n    let id = |x| x;\n    let _ = id as fn(usize) -> usize;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/fn_to_numeric_cast_any.stderr",
    "content": "error: casting function pointer `foo` to `i8`\n  --> tests/ui/fn_to_numeric_cast_any.rs:24:13\n   |\nLL |     let _ = foo as i8;\n   |             ^^^^^^^^^\n   |\n   = note: `-D clippy::fn-to-numeric-cast-any` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]`\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as i8;\n   |                ++\n\nerror: casting function pointer `foo` to `i16`\n  --> tests/ui/fn_to_numeric_cast_any.rs:27:13\n   |\nLL |     let _ = foo as i16;\n   |             ^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as i16;\n   |                ++\n\nerror: casting function pointer `foo` to `i32`\n  --> tests/ui/fn_to_numeric_cast_any.rs:30:13\n   |\nLL |     let _ = foo as i32;\n   |             ^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as i32;\n   |                ++\n\nerror: casting function pointer `foo` to `i64`\n  --> tests/ui/fn_to_numeric_cast_any.rs:33:13\n   |\nLL |     let _ = foo as i64;\n   |             ^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as i64;\n   |                ++\n\nerror: casting function pointer `foo` to `i128`\n  --> tests/ui/fn_to_numeric_cast_any.rs:36:13\n   |\nLL |     let _ = foo as i128;\n   |             ^^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as i128;\n   |                ++\n\nerror: casting function pointer `foo` to `isize`\n  --> tests/ui/fn_to_numeric_cast_any.rs:39:13\n   |\nLL |     let _ = foo as isize;\n   |             ^^^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as isize;\n   |                ++\n\nerror: casting function pointer `foo` to `u8`\n  --> tests/ui/fn_to_numeric_cast_any.rs:42:13\n   |\nLL |     let _ = foo as u8;\n   |             ^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as u8;\n   |                ++\n\nerror: casting function pointer `foo` to `u16`\n  --> tests/ui/fn_to_numeric_cast_any.rs:45:13\n   |\nLL |     let _ = foo as u16;\n   |             ^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as u16;\n   |                ++\n\nerror: casting function pointer `foo` to `u32`\n  --> tests/ui/fn_to_numeric_cast_any.rs:48:13\n   |\nLL |     let _ = foo as u32;\n   |             ^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as u32;\n   |                ++\n\nerror: casting function pointer `foo` to `u64`\n  --> tests/ui/fn_to_numeric_cast_any.rs:51:13\n   |\nLL |     let _ = foo as u64;\n   |             ^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as u64;\n   |                ++\n\nerror: casting function pointer `foo` to `u128`\n  --> tests/ui/fn_to_numeric_cast_any.rs:54:13\n   |\nLL |     let _ = foo as u128;\n   |             ^^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as u128;\n   |                ++\n\nerror: casting function pointer `foo` to `usize`\n  --> tests/ui/fn_to_numeric_cast_any.rs:57:13\n   |\nLL |     let _ = foo as usize;\n   |             ^^^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as usize;\n   |                ++\n\nerror: casting function pointer `Struct::static_method` to `usize`\n  --> tests/ui/fn_to_numeric_cast_any.rs:62:13\n   |\nLL |     let _ = Struct::static_method as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = Struct::static_method() as usize;\n   |                                  ++\n\nerror: casting function pointer `f` to `usize`\n  --> tests/ui/fn_to_numeric_cast_any.rs:67:5\n   |\nLL |     f as usize\n   |     ^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     f() as usize\n   |      ++\n\nerror: casting function pointer `T::static_method` to `usize`\n  --> tests/ui/fn_to_numeric_cast_any.rs:72:5\n   |\nLL |     T::static_method as usize\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     T::static_method() as usize\n   |                     ++\n\nerror: casting function pointer `(clos as fn(u32) -> u32)` to `usize`\n  --> tests/ui/fn_to_numeric_cast_any.rs:79:13\n   |\nLL |     let _ = (clos as fn(u32) -> u32) as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = (clos as fn(u32) -> u32)() as usize;\n   |                                     ++\n\nerror: casting function pointer `foo` to `*const ()`\n  --> tests/ui/fn_to_numeric_cast_any.rs:84:13\n   |\nLL |     let _ = foo as *const ();\n   |             ^^^^^^^^^^^^^^^^\n   |\nhelp: did you mean to invoke the function?\n   |\nLL |     let _ = foo() as *const ();\n   |                ++\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/for_kv_map.fixed",
    "content": "#![warn(clippy::for_kv_map)]\n#![allow(clippy::used_underscore_binding)]\n\nuse std::collections::*;\nuse std::rc::Rc;\n\nfn main() {\n    let m: HashMap<u64, u64> = HashMap::new();\n    for v in m.values() {\n        //~^ for_kv_map\n\n        let _v = v;\n    }\n\n    let m: Rc<HashMap<u64, u64>> = Rc::new(HashMap::new());\n    for v in (*m).values() {\n        //~^ for_kv_map\n\n        let _v = v;\n        // Here the `*` is not actually necessary, but the test tests that we don't\n        // suggest\n        // `in *m.values()` as we used to\n    }\n\n    let mut m: HashMap<u64, u64> = HashMap::new();\n    for v in m.values_mut() {\n        //~^ for_kv_map\n\n        let _v = v;\n    }\n\n    let m: &mut HashMap<u64, u64> = &mut HashMap::new();\n    for v in (*m).values_mut() {\n        //~^ for_kv_map\n\n        let _v = v;\n    }\n\n    let m: HashMap<u64, u64> = HashMap::new();\n    let rm = &m;\n    for k in rm.keys() {\n        //~^ for_kv_map\n\n        let _k = k;\n    }\n\n    let m: HashMap<u64, u64> = HashMap::new();\n    let rm = &m;\n    'label: for k in rm.keys() {\n        //~^ for_kv_map\n\n        let _k = k;\n        if *k == 0u64 {\n            break 'label;\n        }\n    }\n\n    // The following should not produce warnings.\n\n    let m: HashMap<u64, u64> = HashMap::new();\n    // No error, _value is actually used\n    for (k, _value) in &m {\n        let _ = _value;\n        let _k = k;\n    }\n\n    let m: HashMap<u64, String> = Default::default();\n    for (_, v) in m {\n        let _v = v;\n    }\n}\n\nfn wrongly_unmangled_macros() {\n    use std::collections::HashMap;\n\n    macro_rules! test_map {\n        ($val:expr) => {\n            &*$val\n        };\n    }\n\n    let m: HashMap<u64, u64> = HashMap::new();\n    let wrapped = Rc::new(m);\n    for v in test_map!(wrapped).values() {\n        //~^ for_kv_map\n        let _v = v;\n    }\n}\n"
  },
  {
    "path": "tests/ui/for_kv_map.rs",
    "content": "#![warn(clippy::for_kv_map)]\n#![allow(clippy::used_underscore_binding)]\n\nuse std::collections::*;\nuse std::rc::Rc;\n\nfn main() {\n    let m: HashMap<u64, u64> = HashMap::new();\n    for (_, v) in &m {\n        //~^ for_kv_map\n\n        let _v = v;\n    }\n\n    let m: Rc<HashMap<u64, u64>> = Rc::new(HashMap::new());\n    for (_, v) in &*m {\n        //~^ for_kv_map\n\n        let _v = v;\n        // Here the `*` is not actually necessary, but the test tests that we don't\n        // suggest\n        // `in *m.values()` as we used to\n    }\n\n    let mut m: HashMap<u64, u64> = HashMap::new();\n    for (_, v) in &mut m {\n        //~^ for_kv_map\n\n        let _v = v;\n    }\n\n    let m: &mut HashMap<u64, u64> = &mut HashMap::new();\n    for (_, v) in &mut *m {\n        //~^ for_kv_map\n\n        let _v = v;\n    }\n\n    let m: HashMap<u64, u64> = HashMap::new();\n    let rm = &m;\n    for (k, _value) in rm {\n        //~^ for_kv_map\n\n        let _k = k;\n    }\n\n    let m: HashMap<u64, u64> = HashMap::new();\n    let rm = &m;\n    'label: for (k, _value) in rm {\n        //~^ for_kv_map\n\n        let _k = k;\n        if *k == 0u64 {\n            break 'label;\n        }\n    }\n\n    // The following should not produce warnings.\n\n    let m: HashMap<u64, u64> = HashMap::new();\n    // No error, _value is actually used\n    for (k, _value) in &m {\n        let _ = _value;\n        let _k = k;\n    }\n\n    let m: HashMap<u64, String> = Default::default();\n    for (_, v) in m {\n        let _v = v;\n    }\n}\n\nfn wrongly_unmangled_macros() {\n    use std::collections::HashMap;\n\n    macro_rules! test_map {\n        ($val:expr) => {\n            &*$val\n        };\n    }\n\n    let m: HashMap<u64, u64> = HashMap::new();\n    let wrapped = Rc::new(m);\n    for (_, v) in test_map!(wrapped) {\n        //~^ for_kv_map\n        let _v = v;\n    }\n}\n"
  },
  {
    "path": "tests/ui/for_kv_map.stderr",
    "content": "error: you seem to want to iterate on a map's values\n  --> tests/ui/for_kv_map.rs:9:19\n   |\nLL |     for (_, v) in &m {\n   |                   ^^\n   |\n   = note: `-D clippy::for-kv-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::for_kv_map)]`\nhelp: use the corresponding method\n   |\nLL -     for (_, v) in &m {\nLL +     for v in m.values() {\n   |\n\nerror: you seem to want to iterate on a map's values\n  --> tests/ui/for_kv_map.rs:16:19\n   |\nLL |     for (_, v) in &*m {\n   |                   ^^^\n   |\nhelp: use the corresponding method\n   |\nLL -     for (_, v) in &*m {\nLL +     for v in (*m).values() {\n   |\n\nerror: you seem to want to iterate on a map's values\n  --> tests/ui/for_kv_map.rs:26:19\n   |\nLL |     for (_, v) in &mut m {\n   |                   ^^^^^^\n   |\nhelp: use the corresponding method\n   |\nLL -     for (_, v) in &mut m {\nLL +     for v in m.values_mut() {\n   |\n\nerror: you seem to want to iterate on a map's values\n  --> tests/ui/for_kv_map.rs:33:19\n   |\nLL |     for (_, v) in &mut *m {\n   |                   ^^^^^^^\n   |\nhelp: use the corresponding method\n   |\nLL -     for (_, v) in &mut *m {\nLL +     for v in (*m).values_mut() {\n   |\n\nerror: you seem to want to iterate on a map's keys\n  --> tests/ui/for_kv_map.rs:41:24\n   |\nLL |     for (k, _value) in rm {\n   |                        ^^\n   |\nhelp: use the corresponding method\n   |\nLL -     for (k, _value) in rm {\nLL +     for k in rm.keys() {\n   |\n\nerror: you seem to want to iterate on a map's keys\n  --> tests/ui/for_kv_map.rs:49:32\n   |\nLL |     'label: for (k, _value) in rm {\n   |                                ^^\n   |\nhelp: use the corresponding method\n   |\nLL -     'label: for (k, _value) in rm {\nLL +     'label: for k in rm.keys() {\n   |\n\nerror: you seem to want to iterate on a map's values\n  --> tests/ui/for_kv_map.rs:84:19\n   |\nLL |     for (_, v) in test_map!(wrapped) {\n   |                   ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the corresponding method\n   |\nLL -     for (_, v) in test_map!(wrapped) {\nLL +     for v in test_map!(wrapped).values() {\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/forget_non_drop.rs",
    "content": "#![warn(clippy::forget_non_drop)]\n\nuse core::mem::forget;\n\nfn forget_generic<T>(t: T) {\n    // Don't lint\n    forget(t)\n}\n\nfn main() {\n    struct Foo;\n    // Lint\n    forget(Foo);\n    //~^ forget_non_drop\n\n    struct Bar;\n    impl Drop for Bar {\n        fn drop(&mut self) {}\n    }\n    // Don't lint\n    forget(Bar);\n\n    struct Baz<T>(T);\n    // Lint\n    forget(Baz(Foo));\n    //~^ forget_non_drop\n\n    // Don't lint\n    forget(Baz(Bar));\n}\n"
  },
  {
    "path": "tests/ui/forget_non_drop.stderr",
    "content": "error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it\n  --> tests/ui/forget_non_drop.rs:13:5\n   |\nLL |     forget(Foo);\n   |     ^^^^^^^^^^^\n   |\nnote: argument has type `main::Foo`\n  --> tests/ui/forget_non_drop.rs:13:12\n   |\nLL |     forget(Foo);\n   |            ^^^\n   = note: `-D clippy::forget-non-drop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::forget_non_drop)]`\n\nerror: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it\n  --> tests/ui/forget_non_drop.rs:25:5\n   |\nLL |     forget(Baz(Foo));\n   |     ^^^^^^^^^^^^^^^^\n   |\nnote: argument has type `main::Baz<main::Foo>`\n  --> tests/ui/forget_non_drop.rs:25:12\n   |\nLL |     forget(Baz(Foo));\n   |            ^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/format.fixed",
    "content": "#![warn(clippy::useless_format)]\n#![allow(\n    clippy::print_literal,\n    clippy::redundant_clone,\n    clippy::to_string_in_format_args,\n    clippy::needless_borrow,\n    clippy::uninlined_format_args,\n    clippy::needless_raw_string_hashes,\n    clippy::useless_vec,\n    clippy::literal_string_with_formatting_args\n)]\n\nstruct Foo(pub String);\n\nmacro_rules! foo {\n    ($($t:tt)*) => (Foo(format!($($t)*)))\n}\n\nfn main() {\n    \"foo\".to_string();\n    //~^ useless_format\n    \"{}\".to_string();\n    //~^ useless_format\n    \"{} abc {}\".to_string();\n    //~^ useless_format\n    r##\"foo {}\n\" bar\"##.to_string();\n\n    let _ = String::new();\n    //~^ useless_format\n\n    \"foo\".to_string();\n    //~^ useless_format\n    format!(\"{:?}\", \"foo\"); // Don't warn about `Debug`.\n    format!(\"{:8}\", \"foo\");\n    format!(\"{:width$}\", \"foo\", width = 8);\n    format!(\"foo {}\", \"bar\");\n    format!(\"{} bar\", \"foo\");\n\n    let arg = String::new();\n    arg.to_string();\n    //~^ useless_format\n    format!(\"{:?}\", arg); // Don't warn about debug.\n    format!(\"{:8}\", arg);\n    format!(\"{:width$}\", arg, width = 8);\n    format!(\"foo {}\", arg);\n    format!(\"{} bar\", arg);\n\n    // We don’t want to warn for non-string args; see issue #697.\n    format!(\"{}\", 42);\n    format!(\"{:?}\", 42);\n    format!(\"{:+}\", 42);\n    format!(\"foo {}\", 42);\n    format!(\"{} bar\", 42);\n\n    // We only want to warn about `format!` itself.\n    println!(\"foo\");\n    println!(\"{}\", \"foo\");\n    println!(\"foo {}\", \"foo\");\n    println!(\"{}\", 42);\n    println!(\"foo {}\", 42);\n\n    // A `format!` inside a macro should not trigger a warning.\n    foo!(\"should not warn\");\n\n    // Precision on string means slicing without panicking on size.\n    format!(\"{:.1}\", \"foo\"); // Could be `\"foo\"[..1]`\n    format!(\"{:.10}\", \"foo\"); // Could not be `\"foo\"[..10]`\n    format!(\"{:.prec$}\", \"foo\", prec = 1);\n    format!(\"{:.prec$}\", \"foo\", prec = 10);\n\n    42.to_string();\n    //~^ useless_format\n    let x = std::path::PathBuf::from(\"/bar/foo/qux\");\n    x.display().to_string();\n    //~^ useless_format\n\n    // False positive\n    let a = \"foo\".to_string();\n    let _ = Some(a + \"bar\");\n    //~^ useless_format\n\n    // Wrap it with braces\n    let v: Vec<String> = vec![\"foo\".to_string(), \"bar\".to_string()];\n    let _s: String = (&*v.join(\"\\n\")).to_string();\n    //~^ useless_format\n\n    format!(\"prepend {:+}\", \"s\");\n\n    // Issue #8290\n    let x = \"foo\";\n    let _ = x.to_string();\n    //~^ useless_format\n    let _ = format!(\"{x:?}\"); // Don't lint on debug\n    let _ = x.to_string();\n    //~^ useless_format\n\n    // Issue #9234\n    let abc = \"abc\";\n    let _ = abc.to_string();\n    //~^ useless_format\n    let xx = \"xx\";\n    let _ = xx.to_string();\n    //~^ useless_format\n}\n"
  },
  {
    "path": "tests/ui/format.rs",
    "content": "#![warn(clippy::useless_format)]\n#![allow(\n    clippy::print_literal,\n    clippy::redundant_clone,\n    clippy::to_string_in_format_args,\n    clippy::needless_borrow,\n    clippy::uninlined_format_args,\n    clippy::needless_raw_string_hashes,\n    clippy::useless_vec,\n    clippy::literal_string_with_formatting_args\n)]\n\nstruct Foo(pub String);\n\nmacro_rules! foo {\n    ($($t:tt)*) => (Foo(format!($($t)*)))\n}\n\nfn main() {\n    format!(\"foo\");\n    //~^ useless_format\n    format!(\"{{}}\");\n    //~^ useless_format\n    format!(\"{{}} abc {{}}\");\n    //~^ useless_format\n    format!(\n        //~^ useless_format\n        r##\"foo {{}}\n\" bar\"##\n    );\n\n    let _ = format!(\"\");\n    //~^ useless_format\n\n    format!(\"{}\", \"foo\");\n    //~^ useless_format\n    format!(\"{:?}\", \"foo\"); // Don't warn about `Debug`.\n    format!(\"{:8}\", \"foo\");\n    format!(\"{:width$}\", \"foo\", width = 8);\n    format!(\"foo {}\", \"bar\");\n    format!(\"{} bar\", \"foo\");\n\n    let arg = String::new();\n    format!(\"{}\", arg);\n    //~^ useless_format\n    format!(\"{:?}\", arg); // Don't warn about debug.\n    format!(\"{:8}\", arg);\n    format!(\"{:width$}\", arg, width = 8);\n    format!(\"foo {}\", arg);\n    format!(\"{} bar\", arg);\n\n    // We don’t want to warn for non-string args; see issue #697.\n    format!(\"{}\", 42);\n    format!(\"{:?}\", 42);\n    format!(\"{:+}\", 42);\n    format!(\"foo {}\", 42);\n    format!(\"{} bar\", 42);\n\n    // We only want to warn about `format!` itself.\n    println!(\"foo\");\n    println!(\"{}\", \"foo\");\n    println!(\"foo {}\", \"foo\");\n    println!(\"{}\", 42);\n    println!(\"foo {}\", 42);\n\n    // A `format!` inside a macro should not trigger a warning.\n    foo!(\"should not warn\");\n\n    // Precision on string means slicing without panicking on size.\n    format!(\"{:.1}\", \"foo\"); // Could be `\"foo\"[..1]`\n    format!(\"{:.10}\", \"foo\"); // Could not be `\"foo\"[..10]`\n    format!(\"{:.prec$}\", \"foo\", prec = 1);\n    format!(\"{:.prec$}\", \"foo\", prec = 10);\n\n    format!(\"{}\", 42.to_string());\n    //~^ useless_format\n    let x = std::path::PathBuf::from(\"/bar/foo/qux\");\n    format!(\"{}\", x.display().to_string());\n    //~^ useless_format\n\n    // False positive\n    let a = \"foo\".to_string();\n    let _ = Some(format!(\"{}\", a + \"bar\"));\n    //~^ useless_format\n\n    // Wrap it with braces\n    let v: Vec<String> = vec![\"foo\".to_string(), \"bar\".to_string()];\n    let _s: String = format!(\"{}\", &*v.join(\"\\n\"));\n    //~^ useless_format\n\n    format!(\"prepend {:+}\", \"s\");\n\n    // Issue #8290\n    let x = \"foo\";\n    let _ = format!(\"{x}\");\n    //~^ useless_format\n    let _ = format!(\"{x:?}\"); // Don't lint on debug\n    let _ = format!(\"{y}\", y = x);\n    //~^ useless_format\n\n    // Issue #9234\n    let abc = \"abc\";\n    let _ = format!(\"{abc}\");\n    //~^ useless_format\n    let xx = \"xx\";\n    let _ = format!(\"{xx}\");\n    //~^ useless_format\n}\n"
  },
  {
    "path": "tests/ui/format.stderr",
    "content": "error: useless use of `format!`\n  --> tests/ui/format.rs:20:5\n   |\nLL |     format!(\"foo\");\n   |     ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `\"foo\".to_string()`\n   |\n   = note: `-D clippy::useless-format` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_format)]`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:22:5\n   |\nLL |     format!(\"{{}}\");\n   |     ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `\"{}\".to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:24:5\n   |\nLL |     format!(\"{{}} abc {{}}\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `\"{} abc {}\".to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:26:5\n   |\nLL | /     format!(\nLL | |\nLL | |         r##\"foo {{}}\nLL | | \" bar\"##\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `.to_string()`\n   |\nLL ~     r##\"foo {}\nLL ~ \" bar\"##.to_string();\n   |\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:32:13\n   |\nLL |     let _ = format!(\"\");\n   |             ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:35:5\n   |\nLL |     format!(\"{}\", \"foo\");\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `\"foo\".to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:44:5\n   |\nLL |     format!(\"{}\", arg);\n   |     ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:75:5\n   |\nLL |     format!(\"{}\", 42.to_string());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:78:5\n   |\nLL |     format!(\"{}\", x.display().to_string());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:83:18\n   |\nLL |     let _ = Some(format!(\"{}\", a + \"bar\"));\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + \"bar\"`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:88:22\n   |\nLL |     let _s: String = format!(\"{}\", &*v.join(\"\\n\"));\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join(\"\\n\")).to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:95:13\n   |\nLL |     let _ = format!(\"{x}\");\n   |             ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:98:13\n   |\nLL |     let _ = format!(\"{y}\", y = x);\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:103:13\n   |\nLL |     let _ = format!(\"{abc}\");\n   |             ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()`\n\nerror: useless use of `format!`\n  --> tests/ui/format.rs:106:13\n   |\nLL |     let _ = format!(\"{xx}\");\n   |             ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/format_args.fixed",
    "content": "#![warn(clippy::to_string_in_format_args)]\n#![allow(unused)]\n#![allow(\n    clippy::assertions_on_constants,\n    clippy::double_parens,\n    clippy::eq_op,\n    clippy::print_literal,\n    clippy::uninlined_format_args\n)]\n\nuse std::io::{Write, stdout};\nuse std::ops::Deref;\nuse std::panic::Location;\n\nstruct Somewhere;\n\n#[allow(clippy::to_string_trait_impl)]\nimpl ToString for Somewhere {\n    fn to_string(&self) -> String {\n        String::from(\"somewhere\")\n    }\n}\n\nstruct X(u32);\n\nimpl Deref for X {\n    type Target = u32;\n\n    fn deref(&self) -> &u32 {\n        &self.0\n    }\n}\n\nstruct Y<'a>(&'a X);\n\nimpl<'a> Deref for Y<'a> {\n    type Target = &'a X;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nstruct Z(u32);\n\nimpl Deref for Z {\n    type Target = u32;\n\n    fn deref(&self) -> &u32 {\n        &self.0\n    }\n}\n\nimpl std::fmt::Display for Z {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"Z\")\n    }\n}\n\nmacro_rules! my_macro {\n    () => {\n        // here be dragons, do not enter (or lint)\n        println!(\"error: something failed at {}\", Location::caller().to_string());\n    };\n}\n\nmacro_rules! my_other_macro {\n    () => {\n        Location::caller().to_string()\n    };\n}\n\nfn main() {\n    let x = &X(1);\n    let x_ref = &x;\n\n    let _ = format!(\"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    let _ = write!(\n        stdout(),\n        \"error: something failed at {}\",\n        Location::caller(),\n        //~^ to_string_in_format_args\n    );\n    let _ = writeln!(\n        stdout(),\n        \"error: something failed at {}\",\n        Location::caller(),\n        //~^ to_string_in_format_args\n    );\n    print!(\"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    println!(\"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    eprint!(\"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    eprintln!(\"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    let _ = format_args!(\"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    assert!(true, \"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    assert_eq!(0, 0, \"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    assert_ne!(0, 0, \"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    panic!(\"error: something failed at {}\", Location::caller());\n    //~^ to_string_in_format_args\n    println!(\"{}\", *X(1));\n    //~^ to_string_in_format_args\n    println!(\"{}\", ***Y(&X(1)));\n    //~^ to_string_in_format_args\n    println!(\"{}\", Z(1));\n    //~^ to_string_in_format_args\n    println!(\"{}\", **x);\n    //~^ to_string_in_format_args\n    println!(\"{}\", ***x_ref);\n    //~^ to_string_in_format_args\n    // https://github.com/rust-lang/rust-clippy/issues/7903\n    println!(\"{foo}{bar}\", foo = \"foo\", bar = \"bar\");\n    //~^ to_string_in_format_args\n    println!(\"{foo}{bar}\", foo = \"foo\", bar = \"bar\");\n    //~^ to_string_in_format_args\n    println!(\"{foo}{bar}\", bar = \"bar\", foo = \"foo\");\n    //~^ to_string_in_format_args\n    println!(\"{foo}{bar}\", bar = \"bar\", foo = \"foo\");\n    //~^ to_string_in_format_args\n    println!(\"{}\", my_other_macro!());\n    //~^ to_string_in_format_args\n\n    // negative tests\n    println!(\"error: something failed at {}\", Somewhere.to_string());\n    // The next two tests are negative because caching the string might be faster than calling `<X as\n    // Display>::fmt` twice.\n    println!(\"{} and again {0}\", x.to_string());\n    println!(\"{foo}{foo}\", foo = \"foo\".to_string());\n    my_macro!();\n    println!(\"error: something failed at {}\", my_other_macro!());\n    // https://github.com/rust-lang/rust-clippy/issues/7903\n    println!(\"{foo}{foo:?}\", foo = \"foo\".to_string());\n    print!(\"{}\", (Location::caller()));\n    //~^ to_string_in_format_args\n    print!(\"{}\", ((Location::caller())));\n    //~^ to_string_in_format_args\n}\n\nfn issue8643(vendor_id: usize, product_id: usize, name: &str) {\n    println!(\n        \"{:<9}  {:<10}  {}\",\n        format!(\"0x{:x}\", vendor_id),\n        format!(\"0x{:x}\", product_id),\n        name\n    );\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/8855\nmod issue_8855 {\n    #![allow(dead_code)]\n\n    struct A {}\n\n    impl std::fmt::Display for A {\n        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n            write!(f, \"test\")\n        }\n    }\n\n    fn main() {\n        let a = A {};\n        let b = A {};\n\n        let x = format!(\"{} {}\", a, b);\n        //~^ to_string_in_format_args\n        dbg!(x);\n\n        let x = format!(\"{:>6} {:>6}\", a, b.to_string());\n        dbg!(x);\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/9256\nmod issue_9256 {\n    #![allow(dead_code)]\n\n    fn print_substring(original: &str) {\n        assert!(original.len() > 10);\n        println!(\"{}\", &original[..10]);\n        //~^ to_string_in_format_args\n    }\n\n    fn main() {\n        print_substring(\"Hello, world!\");\n    }\n}\n\nmod issue14952 {\n    use std::path::Path;\n    struct Foo(Path);\n    impl std::fmt::Debug for Foo {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            write!(f, \"{:?}\", &self.0)\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/format_args.rs",
    "content": "#![warn(clippy::to_string_in_format_args)]\n#![allow(unused)]\n#![allow(\n    clippy::assertions_on_constants,\n    clippy::double_parens,\n    clippy::eq_op,\n    clippy::print_literal,\n    clippy::uninlined_format_args\n)]\n\nuse std::io::{Write, stdout};\nuse std::ops::Deref;\nuse std::panic::Location;\n\nstruct Somewhere;\n\n#[allow(clippy::to_string_trait_impl)]\nimpl ToString for Somewhere {\n    fn to_string(&self) -> String {\n        String::from(\"somewhere\")\n    }\n}\n\nstruct X(u32);\n\nimpl Deref for X {\n    type Target = u32;\n\n    fn deref(&self) -> &u32 {\n        &self.0\n    }\n}\n\nstruct Y<'a>(&'a X);\n\nimpl<'a> Deref for Y<'a> {\n    type Target = &'a X;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nstruct Z(u32);\n\nimpl Deref for Z {\n    type Target = u32;\n\n    fn deref(&self) -> &u32 {\n        &self.0\n    }\n}\n\nimpl std::fmt::Display for Z {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"Z\")\n    }\n}\n\nmacro_rules! my_macro {\n    () => {\n        // here be dragons, do not enter (or lint)\n        println!(\"error: something failed at {}\", Location::caller().to_string());\n    };\n}\n\nmacro_rules! my_other_macro {\n    () => {\n        Location::caller().to_string()\n    };\n}\n\nfn main() {\n    let x = &X(1);\n    let x_ref = &x;\n\n    let _ = format!(\"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    let _ = write!(\n        stdout(),\n        \"error: something failed at {}\",\n        Location::caller().to_string(),\n        //~^ to_string_in_format_args\n    );\n    let _ = writeln!(\n        stdout(),\n        \"error: something failed at {}\",\n        Location::caller().to_string(),\n        //~^ to_string_in_format_args\n    );\n    print!(\"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    println!(\"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    eprint!(\"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    eprintln!(\"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    let _ = format_args!(\"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    assert!(true, \"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    assert_eq!(0, 0, \"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    assert_ne!(0, 0, \"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    panic!(\"error: something failed at {}\", Location::caller().to_string());\n    //~^ to_string_in_format_args\n    println!(\"{}\", X(1).to_string());\n    //~^ to_string_in_format_args\n    println!(\"{}\", Y(&X(1)).to_string());\n    //~^ to_string_in_format_args\n    println!(\"{}\", Z(1).to_string());\n    //~^ to_string_in_format_args\n    println!(\"{}\", x.to_string());\n    //~^ to_string_in_format_args\n    println!(\"{}\", x_ref.to_string());\n    //~^ to_string_in_format_args\n    // https://github.com/rust-lang/rust-clippy/issues/7903\n    println!(\"{foo}{bar}\", foo = \"foo\".to_string(), bar = \"bar\");\n    //~^ to_string_in_format_args\n    println!(\"{foo}{bar}\", foo = \"foo\", bar = \"bar\".to_string());\n    //~^ to_string_in_format_args\n    println!(\"{foo}{bar}\", bar = \"bar\".to_string(), foo = \"foo\");\n    //~^ to_string_in_format_args\n    println!(\"{foo}{bar}\", bar = \"bar\", foo = \"foo\".to_string());\n    //~^ to_string_in_format_args\n    println!(\"{}\", my_other_macro!().to_string());\n    //~^ to_string_in_format_args\n\n    // negative tests\n    println!(\"error: something failed at {}\", Somewhere.to_string());\n    // The next two tests are negative because caching the string might be faster than calling `<X as\n    // Display>::fmt` twice.\n    println!(\"{} and again {0}\", x.to_string());\n    println!(\"{foo}{foo}\", foo = \"foo\".to_string());\n    my_macro!();\n    println!(\"error: something failed at {}\", my_other_macro!());\n    // https://github.com/rust-lang/rust-clippy/issues/7903\n    println!(\"{foo}{foo:?}\", foo = \"foo\".to_string());\n    print!(\"{}\", (Location::caller().to_string()));\n    //~^ to_string_in_format_args\n    print!(\"{}\", ((Location::caller()).to_string()));\n    //~^ to_string_in_format_args\n}\n\nfn issue8643(vendor_id: usize, product_id: usize, name: &str) {\n    println!(\n        \"{:<9}  {:<10}  {}\",\n        format!(\"0x{:x}\", vendor_id),\n        format!(\"0x{:x}\", product_id),\n        name\n    );\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/8855\nmod issue_8855 {\n    #![allow(dead_code)]\n\n    struct A {}\n\n    impl std::fmt::Display for A {\n        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n            write!(f, \"test\")\n        }\n    }\n\n    fn main() {\n        let a = A {};\n        let b = A {};\n\n        let x = format!(\"{} {}\", a, b.to_string());\n        //~^ to_string_in_format_args\n        dbg!(x);\n\n        let x = format!(\"{:>6} {:>6}\", a, b.to_string());\n        dbg!(x);\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/9256\nmod issue_9256 {\n    #![allow(dead_code)]\n\n    fn print_substring(original: &str) {\n        assert!(original.len() > 10);\n        println!(\"{}\", original[..10].to_string());\n        //~^ to_string_in_format_args\n    }\n\n    fn main() {\n        print_substring(\"Hello, world!\");\n    }\n}\n\nmod issue14952 {\n    use std::path::Path;\n    struct Foo(Path);\n    impl std::fmt::Debug for Foo {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            write!(f, \"{:?}\", &self.0)\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/format_args.stderr",
    "content": "error: `to_string` applied to a type that implements `Display` in `format!` args\n  --> tests/ui/format_args.rs:77:72\n   |\nLL |     let _ = format!(\"error: something failed at {}\", Location::caller().to_string());\n   |                                                                        ^^^^^^^^^^^^ help: remove this\n   |\n   = note: `-D clippy::to-string-in-format-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::to_string_in_format_args)]`\n\nerror: `to_string` applied to a type that implements `Display` in `write!` args\n  --> tests/ui/format_args.rs:82:27\n   |\nLL |         Location::caller().to_string(),\n   |                           ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `writeln!` args\n  --> tests/ui/format_args.rs:88:27\n   |\nLL |         Location::caller().to_string(),\n   |                           ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `print!` args\n  --> tests/ui/format_args.rs:91:63\n   |\nLL |     print!(\"error: something failed at {}\", Location::caller().to_string());\n   |                                                               ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:93:65\n   |\nLL |     println!(\"error: something failed at {}\", Location::caller().to_string());\n   |                                                                 ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `eprint!` args\n  --> tests/ui/format_args.rs:95:64\n   |\nLL |     eprint!(\"error: something failed at {}\", Location::caller().to_string());\n   |                                                                ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `eprintln!` args\n  --> tests/ui/format_args.rs:97:66\n   |\nLL |     eprintln!(\"error: something failed at {}\", Location::caller().to_string());\n   |                                                                  ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `format_args!` args\n  --> tests/ui/format_args.rs:99:77\n   |\nLL |     let _ = format_args!(\"error: something failed at {}\", Location::caller().to_string());\n   |                                                                             ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `assert!` args\n  --> tests/ui/format_args.rs:101:70\n   |\nLL |     assert!(true, \"error: something failed at {}\", Location::caller().to_string());\n   |                                                                      ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `assert_eq!` args\n  --> tests/ui/format_args.rs:103:73\n   |\nLL |     assert_eq!(0, 0, \"error: something failed at {}\", Location::caller().to_string());\n   |                                                                         ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `assert_ne!` args\n  --> tests/ui/format_args.rs:105:73\n   |\nLL |     assert_ne!(0, 0, \"error: something failed at {}\", Location::caller().to_string());\n   |                                                                         ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `panic!` args\n  --> tests/ui/format_args.rs:107:63\n   |\nLL |     panic!(\"error: something failed at {}\", Location::caller().to_string());\n   |                                                               ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:109:20\n   |\nLL |     println!(\"{}\", X(1).to_string());\n   |                    ^^^^^^^^^^^^^^^^ help: use this: `*X(1)`\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:111:20\n   |\nLL |     println!(\"{}\", Y(&X(1)).to_string());\n   |                    ^^^^^^^^^^^^^^^^^^^^ help: use this: `***Y(&X(1))`\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:113:24\n   |\nLL |     println!(\"{}\", Z(1).to_string());\n   |                        ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:115:20\n   |\nLL |     println!(\"{}\", x.to_string());\n   |                    ^^^^^^^^^^^^^ help: use this: `**x`\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:117:20\n   |\nLL |     println!(\"{}\", x_ref.to_string());\n   |                    ^^^^^^^^^^^^^^^^^ help: use this: `***x_ref`\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:120:39\n   |\nLL |     println!(\"{foo}{bar}\", foo = \"foo\".to_string(), bar = \"bar\");\n   |                                       ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:122:52\n   |\nLL |     println!(\"{foo}{bar}\", foo = \"foo\", bar = \"bar\".to_string());\n   |                                                    ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:124:39\n   |\nLL |     println!(\"{foo}{bar}\", bar = \"bar\".to_string(), foo = \"foo\");\n   |                                       ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:126:52\n   |\nLL |     println!(\"{foo}{bar}\", bar = \"bar\", foo = \"foo\".to_string());\n   |                                                    ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:128:37\n   |\nLL |     println!(\"{}\", my_other_macro!().to_string());\n   |                                     ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `print!` args\n  --> tests/ui/format_args.rs:141:37\n   |\nLL |     print!(\"{}\", (Location::caller().to_string()));\n   |                                     ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `print!` args\n  --> tests/ui/format_args.rs:143:39\n   |\nLL |     print!(\"{}\", ((Location::caller()).to_string()));\n   |                                       ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `format!` args\n  --> tests/ui/format_args.rs:172:38\n   |\nLL |         let x = format!(\"{} {}\", a, b.to_string());\n   |                                      ^^^^^^^^^^^^ help: remove this\n\nerror: `to_string` applied to a type that implements `Display` in `println!` args\n  --> tests/ui/format_args.rs:187:24\n   |\nLL |         println!(\"{}\", original[..10].to_string());\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]`\n\nerror: aborting due to 26 previous errors\n\n"
  },
  {
    "path": "tests/ui/format_args_unfixable.rs",
    "content": "#![warn(clippy::format_in_format_args, clippy::to_string_in_format_args)]\n#![allow(unused)]\n#![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::uninlined_format_args)]\n\nuse std::io::{Error, Write, stdout};\nuse std::ops::Deref;\nuse std::panic::Location;\n\nmacro_rules! my_macro {\n    () => {\n        // here be dragons, do not enter (or lint)\n        println!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    };\n}\n\nmacro_rules! my_other_macro {\n    () => {\n        format!(\"something failed at {}\", Location::caller())\n    };\n}\n\nfn main() {\n    let error = Error::other(\"bad thing\");\n    let x = 'x';\n\n    println!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    println!(\"{}: {}\", error, format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    println!(\"{:?}: {}\", error, format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    println!(\"{{}}: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    println!(r#\"error: \"{}\"\"#, format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    println!(\"error: {}\", format!(r#\"something failed at \"{}\"\"#, Location::caller()));\n    //~^ format_in_format_args\n\n    println!(\"error: {}\", format!(\"something failed at {} {0}\", Location::caller()));\n    //~^ format_in_format_args\n\n    let _ = format!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    let _ = write!(\n        //~^ format_in_format_args\n        stdout(),\n        \"error: {}\",\n        format!(\"something failed at {}\", Location::caller())\n    );\n    let _ = writeln!(\n        //~^ format_in_format_args\n        stdout(),\n        \"error: {}\",\n        format!(\"something failed at {}\", Location::caller())\n    );\n    print!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    eprint!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    eprintln!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    let _ = format_args!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    assert!(true, \"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    assert_eq!(0, 0, \"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    assert_ne!(0, 0, \"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    panic!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    // negative tests\n    println!(\"error: {}\", format_args!(\"something failed at {}\", Location::caller()));\n    println!(\"error: {:>70}\", format!(\"something failed at {}\", Location::caller()));\n    println!(\"error: {} {0}\", format!(\"something failed at {}\", Location::caller()));\n    println!(\"{} and again {0}\", format!(\"hi {}\", x));\n    my_macro!();\n    println!(\"error: {}\", my_other_macro!());\n}\n\nmacro_rules! _internal {\n    ($($args:tt)*) => {\n        println!(\"{}\", format_args!($($args)*))\n    };\n}\n\nmacro_rules! my_println2 {\n   ($target:expr, $($args:tt)+) => {{\n       if $target {\n           _internal!($($args)+)\n       }\n    }};\n}\n\nmacro_rules! my_println2_args {\n    ($target:expr, $($args:tt)+) => {{\n       if $target {\n           _internal!(\"foo: {}\", format_args!($($args)+))\n       }\n    }};\n}\n\nfn test2() {\n    let error = Error::other(\"bad thing\");\n\n    // None of these should be linted without the config change\n    my_println2!(true, \"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    my_println2!(\n        true,\n        \"{}: {}\",\n        error,\n        format!(\"something failed at {}\", Location::caller())\n    );\n\n    my_println2_args!(true, \"error: {}\", format!(\"something failed at {}\", Location::caller()));\n    my_println2_args!(\n        true,\n        \"{}: {}\",\n        error,\n        format!(\"something failed at {}\", Location::caller())\n    );\n}\n\n#[clippy::format_args]\nmacro_rules! usr_println {\n    ($target:expr, $($args:tt)*) => {{\n        if $target {\n            println!($($args)*)\n        }\n    }};\n}\n\nfn user_format() {\n    let error = Error::other(\"bad thing\");\n    let x = 'x';\n\n    usr_println!(true, \"error: {}\", format!(\"boom at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    usr_println!(true, \"{}: {}\", error, format!(\"boom at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    usr_println!(true, \"{:?}: {}\", error, format!(\"boom at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    usr_println!(true, \"{{}}: {}\", format!(\"boom at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    usr_println!(true, r#\"error: \"{}\"\"#, format!(\"boom at {}\", Location::caller()));\n    //~^ format_in_format_args\n\n    usr_println!(true, \"error: {}\", format!(r#\"boom at \"{}\"\"#, Location::caller()));\n    //~^ format_in_format_args\n\n    usr_println!(true, \"error: {}\", format!(\"boom at {} {0}\", Location::caller()));\n    //~^ format_in_format_args\n}\n"
  },
  {
    "path": "tests/ui/format_args_unfixable.stderr",
    "content": "error: `format!` in `println!` args\n  --> tests/ui/format_args_unfixable.rs:26:5\n   |\nLL |     println!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n   = note: `-D clippy::format-in-format-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::format_in_format_args)]`\n\nerror: `format!` in `println!` args\n  --> tests/ui/format_args_unfixable.rs:29:5\n   |\nLL |     println!(\"{}: {}\", error, format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `println!` args\n  --> tests/ui/format_args_unfixable.rs:32:5\n   |\nLL |     println!(\"{:?}: {}\", error, format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `println!` args\n  --> tests/ui/format_args_unfixable.rs:35:5\n   |\nLL |     println!(\"{{}}: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `println!` args\n  --> tests/ui/format_args_unfixable.rs:38:5\n   |\nLL |     println!(r#\"error: \"{}\"\"#, format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `println!` args\n  --> tests/ui/format_args_unfixable.rs:41:5\n   |\nLL |     println!(\"error: {}\", format!(r#\"something failed at \"{}\"\"#, Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `println!` args\n  --> tests/ui/format_args_unfixable.rs:44:5\n   |\nLL |     println!(\"error: {}\", format!(\"something failed at {} {0}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `format!` args\n  --> tests/ui/format_args_unfixable.rs:47:13\n   |\nLL |     let _ = format!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `format!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `write!` args\n  --> tests/ui/format_args_unfixable.rs:50:13\n   |\nLL |       let _ = write!(\n   |  _____________^\nLL | |\nLL | |         stdout(),\nLL | |         \"error: {}\",\nLL | |         format!(\"something failed at {}\", Location::caller())\nLL | |     );\n   | |_____^\n   |\n   = help: combine the `format!(..)` arguments with the outer `write!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `writeln!` args\n  --> tests/ui/format_args_unfixable.rs:56:13\n   |\nLL |       let _ = writeln!(\n   |  _____________^\nLL | |\nLL | |         stdout(),\nLL | |         \"error: {}\",\nLL | |         format!(\"something failed at {}\", Location::caller())\nLL | |     );\n   | |_____^\n   |\n   = help: combine the `format!(..)` arguments with the outer `writeln!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `print!` args\n  --> tests/ui/format_args_unfixable.rs:62:5\n   |\nLL |     print!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `print!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `eprint!` args\n  --> tests/ui/format_args_unfixable.rs:65:5\n   |\nLL |     eprint!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `eprint!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `eprintln!` args\n  --> tests/ui/format_args_unfixable.rs:68:5\n   |\nLL |     eprintln!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `eprintln!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `format_args!` args\n  --> tests/ui/format_args_unfixable.rs:71:13\n   |\nLL |     let _ = format_args!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `format_args!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `assert!` args\n  --> tests/ui/format_args_unfixable.rs:74:5\n   |\nLL |     assert!(true, \"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `assert!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `assert_eq!` args\n  --> tests/ui/format_args_unfixable.rs:77:5\n   |\nLL |     assert_eq!(0, 0, \"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `assert_eq!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `assert_ne!` args\n  --> tests/ui/format_args_unfixable.rs:80:5\n   |\nLL |     assert_ne!(0, 0, \"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `assert_ne!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `panic!` args\n  --> tests/ui/format_args_unfixable.rs:83:5\n   |\nLL |     panic!(\"error: {}\", format!(\"something failed at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `panic!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `usr_println!` args\n  --> tests/ui/format_args_unfixable.rs:151:5\n   |\nLL |     usr_println!(true, \"error: {}\", format!(\"boom at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `usr_println!` args\n  --> tests/ui/format_args_unfixable.rs:154:5\n   |\nLL |     usr_println!(true, \"{}: {}\", error, format!(\"boom at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `usr_println!` args\n  --> tests/ui/format_args_unfixable.rs:157:5\n   |\nLL |     usr_println!(true, \"{:?}: {}\", error, format!(\"boom at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `usr_println!` args\n  --> tests/ui/format_args_unfixable.rs:160:5\n   |\nLL |     usr_println!(true, \"{{}}: {}\", format!(\"boom at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `usr_println!` args\n  --> tests/ui/format_args_unfixable.rs:163:5\n   |\nLL |     usr_println!(true, r#\"error: \"{}\"\"#, format!(\"boom at {}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `usr_println!` args\n  --> tests/ui/format_args_unfixable.rs:166:5\n   |\nLL |     usr_println!(true, \"error: {}\", format!(r#\"boom at \"{}\"\"#, Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: `format!` in `usr_println!` args\n  --> tests/ui/format_args_unfixable.rs:169:5\n   |\nLL |     usr_println!(true, \"error: {}\", format!(\"boom at {} {0}\", Location::caller()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: combine the `format!(..)` arguments with the outer `usr_println!(..)` call\n   = help: or consider changing `format!` to `format_args!`\n\nerror: aborting due to 25 previous errors\n\n"
  },
  {
    "path": "tests/ui/format_collect.rs",
    "content": "#![allow(unused, dead_code)]\n#![warn(clippy::format_collect)]\n\nfn hex_encode(bytes: &[u8]) -> String {\n    bytes.iter().map(|b| format!(\"{b:02X}\")).collect()\n    //~^ format_collect\n}\n\n#[rustfmt::skip]\nfn hex_encode_deep(bytes: &[u8]) -> String {\n    bytes.iter().map(|b| {{{{{ format!(\"{b:02X}\") }}}}}).collect()\n    //~^ format_collect\n\n}\n\nmacro_rules! fmt {\n    ($x:ident) => {\n        format!(\"{x:02X}\", x = $x)\n    };\n}\n\nfn from_macro(bytes: &[u8]) -> String {\n    bytes.iter().map(|x| fmt!(x)).collect()\n}\n\nfn with_block() -> String {\n    (1..10)\n        //~^ format_collect\n        .map(|s| {\n            let y = 1;\n            format!(\"{s} {y}\")\n        })\n        .collect()\n}\nfn main() {}\n"
  },
  {
    "path": "tests/ui/format_collect.stderr",
    "content": "error: use of `format!` to build up a string from an iterator\n  --> tests/ui/format_collect.rs:5:5\n   |\nLL |     bytes.iter().map(|b| format!(\"{b:02X}\")).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: call `fold` instead\n  --> tests/ui/format_collect.rs:5:18\n   |\nLL |     bytes.iter().map(|b| format!(\"{b:02X}\")).collect()\n   |                  ^^^\nhelp: ... and use the `write!` macro here\n  --> tests/ui/format_collect.rs:5:26\n   |\nLL |     bytes.iter().map(|b| format!(\"{b:02X}\")).collect()\n   |                          ^^^^^^^^^^^^^^^^^^\n   = note: this can be written more efficiently by appending to a `String` directly\n   = note: `-D clippy::format-collect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::format_collect)]`\n\nerror: use of `format!` to build up a string from an iterator\n  --> tests/ui/format_collect.rs:11:5\n   |\nLL |     bytes.iter().map(|b| {{{{{ format!(\"{b:02X}\") }}}}}).collect()\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: call `fold` instead\n  --> tests/ui/format_collect.rs:11:18\n   |\nLL |     bytes.iter().map(|b| {{{{{ format!(\"{b:02X}\") }}}}}).collect()\n   |                  ^^^\nhelp: ... and use the `write!` macro here\n  --> tests/ui/format_collect.rs:11:32\n   |\nLL |     bytes.iter().map(|b| {{{{{ format!(\"{b:02X}\") }}}}}).collect()\n   |                                ^^^^^^^^^^^^^^^^^^\n   = note: this can be written more efficiently by appending to a `String` directly\n\nerror: use of `format!` to build up a string from an iterator\n  --> tests/ui/format_collect.rs:27:5\n   |\nLL | /     (1..10)\nLL | |\nLL | |         .map(|s| {\nLL | |             let y = 1;\nLL | |             format!(\"{s} {y}\")\nLL | |         })\nLL | |         .collect()\n   | |__________________^\n   |\nhelp: call `fold` instead\n  --> tests/ui/format_collect.rs:29:10\n   |\nLL |         .map(|s| {\n   |          ^^^\nhelp: ... and use the `write!` macro here\n  --> tests/ui/format_collect.rs:31:13\n   |\nLL |             format!(\"{s} {y}\")\n   |             ^^^^^^^^^^^^^^^^^^\n   = note: this can be written more efficiently by appending to a `String` directly\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/format_push_string.fixed",
    "content": "#![warn(clippy::format_push_string)]\n\nfn main() {\n    use std::fmt::Write;\n\n    let mut string = String::new();\n    let _ = write!(string, \"{:?}\", 1234);\n    //~^ format_push_string\n\n    let _ = write!(string, \"{:?}\", 5678);\n    //~^ format_push_string\n\n    macro_rules! string {\n        () => {\n            String::new()\n        };\n    }\n    let _ = write!(string!(), \"{:?}\", 5678);\n    //~^ format_push_string\n}\n\n// TODO: recognize the already imported `fmt::Write`, and don't add a note suggesting to import it\n// again\nmod import_write {\n    mod push_str {\n        mod imported_anonymously {\n            fn main(string: &mut String) {\n                use std::fmt::Write as _;\n\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n\n        mod imported {\n            fn main(string: &mut String) {\n                use std::fmt::Write;\n\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_anonymously_in_module {\n            use std::fmt::Write as _;\n\n            fn main(string: &mut String) {\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_in_module {\n            use std::fmt::Write;\n\n            fn main(string: &mut String) {\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_and_imported {\n            fn foo(string: &mut String) {\n                use std::fmt::Write;\n\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                use std::fmt::Write;\n\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n    }\n\n    mod add_assign {\n        mod imported_anonymously {\n            fn main(string: &mut String) {\n                use std::fmt::Write as _;\n\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n\n        mod imported {\n            fn main(string: &mut String) {\n                use std::fmt::Write;\n\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_anonymously_in_module {\n            use std::fmt::Write as _;\n\n            fn main(string: &mut String) {\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_in_module {\n            use std::fmt::Write;\n\n            fn main(string: &mut String) {\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_and_imported {\n            fn foo(string: &mut String) {\n                use std::fmt::Write;\n\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                use std::fmt::Write;\n\n                let _ = write!(string, \"{:?}\", 1234);\n                //~^ format_push_string\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/format_push_string.rs",
    "content": "#![warn(clippy::format_push_string)]\n\nfn main() {\n    use std::fmt::Write;\n\n    let mut string = String::new();\n    string += &format!(\"{:?}\", 1234);\n    //~^ format_push_string\n\n    string.push_str(&format!(\"{:?}\", 5678));\n    //~^ format_push_string\n\n    macro_rules! string {\n        () => {\n            String::new()\n        };\n    }\n    string!().push_str(&format!(\"{:?}\", 5678));\n    //~^ format_push_string\n}\n\n// TODO: recognize the already imported `fmt::Write`, and don't add a note suggesting to import it\n// again\nmod import_write {\n    mod push_str {\n        mod imported_anonymously {\n            fn main(string: &mut String) {\n                use std::fmt::Write as _;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        mod imported {\n            fn main(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_anonymously_in_module {\n            use std::fmt::Write as _;\n\n            fn main(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_in_module {\n            use std::fmt::Write;\n\n            fn main(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_and_imported {\n            fn foo(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n    }\n\n    mod add_assign {\n        mod imported_anonymously {\n            fn main(string: &mut String) {\n                use std::fmt::Write as _;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        mod imported {\n            fn main(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_anonymously_in_module {\n            use std::fmt::Write as _;\n\n            fn main(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_in_module {\n            use std::fmt::Write;\n\n            fn main(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        mod imported_and_imported {\n            fn foo(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/format_push_string.stderr",
    "content": "error: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:7:5\n   |\nLL |     string += &format!(\"{:?}\", 1234);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\n   = note: `-D clippy::format-push-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]`\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -     string += &format!(\"{:?}\", 1234);\nLL +     let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:10:5\n   |\nLL |     string.push_str(&format!(\"{:?}\", 5678));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -     string.push_str(&format!(\"{:?}\", 5678));\nLL +     let _ = write!(string, \"{:?}\", 5678);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:18:5\n   |\nLL |     string!().push_str(&format!(\"{:?}\", 5678));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -     string!().push_str(&format!(\"{:?}\", 5678));\nLL +     let _ = write!(string!(), \"{:?}\", 5678);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:30:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:39:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:48:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:57:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:66:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:73:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:84:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:93:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:102:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:111:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:120:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string.rs:127:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/format_push_string_no_core.rs",
    "content": "//@check-pass\n#![warn(clippy::format_push_string)]\n#![no_std]\n#![feature(no_core)]\n#![no_core]\n\nextern crate alloc;\n\nuse alloc::format;\nuse alloc::string::String;\n\nfn foo(string: &mut String) {\n    // can't suggest even `core::fmt::Write` because of `#![no_core]`\n    string.push_str(&format!(\"{:?}\", 1234));\n}\n"
  },
  {
    "path": "tests/ui/format_push_string_no_std.fixed",
    "content": "#![warn(clippy::format_push_string)]\n#![no_std]\n\nextern crate alloc;\n\nuse alloc::format;\nuse alloc::string::String;\n\nfn foo(string: &mut String) {\n    use core::fmt::Write;\n\n    // TODO: recognize the already imported `fmt::Write`, and don't suggest importing it again\n    let _ = write!(string, \"{:?}\", 1234);\n    //~^ format_push_string\n}\n"
  },
  {
    "path": "tests/ui/format_push_string_no_std.rs",
    "content": "#![warn(clippy::format_push_string)]\n#![no_std]\n\nextern crate alloc;\n\nuse alloc::format;\nuse alloc::string::String;\n\nfn foo(string: &mut String) {\n    use core::fmt::Write;\n\n    // TODO: recognize the already imported `fmt::Write`, and don't suggest importing it again\n    string.push_str(&format!(\"{:?}\", 1234));\n    //~^ format_push_string\n}\n"
  },
  {
    "path": "tests/ui/format_push_string_no_std.stderr",
    "content": "error: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_no_std.rs:13:5\n   |\nLL |     string.push_str(&format!(\"{:?}\", 1234));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `core::fmt::Write` trait\n   = note: `-D clippy::format-push-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]`\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -     string.push_str(&format!(\"{:?}\", 1234));\nLL +     let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/format_push_string_no_std_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::format_push_string)]\n#![no_std]\n\nextern crate alloc;\n\nuse alloc::format;\nuse alloc::string::String;\n\nfn foo(string: &mut String) {\n    string.push_str(&format!(\"{:?}\", 1234));\n    //~^ format_push_string\n}\n"
  },
  {
    "path": "tests/ui/format_push_string_no_std_unfixable.stderr",
    "content": "error: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_no_std_unfixable.rs:11:5\n   |\nLL |     string.push_str(&format!(\"{:?}\", 1234));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `core::fmt::Write` trait\n   = note: `-D clippy::format-push-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]`\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -     string.push_str(&format!(\"{:?}\", 1234));\nLL +     let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/format_push_string_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::format_push_string)]\n\nmod issue9493 {\n    pub fn u8vec_to_hex(vector: &Vec<u8>, upper: bool) -> String {\n        let mut hex = String::with_capacity(vector.len() * 2);\n        for byte in vector {\n            hex += &(if upper {\n                format!(\"{byte:02X}\")\n                //~^ format_push_string\n            } else {\n                format!(\"{byte:02x}\")\n            });\n        }\n        hex\n    }\n\n    pub fn other_cases() {\n        let mut s = String::new();\n        // if let\n        s += &(if let Some(_a) = Some(1234) {\n            format!(\"{}\", 1234)\n            //~^ format_push_string\n        } else {\n            format!(\"{}\", 1234)\n        });\n        // match\n        s += &(match Some(1234) {\n            Some(_) => format!(\"{}\", 1234),\n            //~^ format_push_string\n            None => format!(\"{}\", 1234),\n        });\n    }\n}\n\nmod import_write {\n    mod push_str {\n        // TODO: suggest importing `std::fmt::Write`;\n        mod not_imported {\n            fn main(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        // TODO: suggest importing the first time, but not again\n        mod not_imported_and_not_imported {\n            fn foo(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        // TODO: suggest importing the first time, but not again\n        mod not_imported_and_imported {\n            fn foo(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        // TODO: suggest importing, but only for `bar`\n        mod imported_and_not_imported {\n            fn foo(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n    }\n\n    mod add_assign {\n        // TODO: suggest importing `std::fmt::Write`;\n        mod not_imported {\n            fn main(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        // TODO: suggest importing the first time, but not again\n        mod not_imported_and_not_imported {\n            fn foo(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        // TODO: suggest importing the first time, but not again\n        mod not_imported_and_imported {\n            fn foo(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n\n        // TODO: suggest importing, but only for `bar`\n        mod imported_and_not_imported {\n            fn foo(string: &mut String) {\n                use std::fmt::Write;\n\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n\n            fn bar(string: &mut String) {\n                string.push_str(&format!(\"{:?}\", 1234));\n                //~^ format_push_string\n            }\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/format_push_string_unfixable.stderr",
    "content": "error: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:8:13\n   |\nLL | /             hex += &(if upper {\nLL | |                 format!(\"{byte:02X}\")\n   | |                 --------------------- `format!` used here\nLL | |\nLL | |             } else {\nLL | |                 format!(\"{byte:02x}\")\n   | |                 --------------------- `format!` used here\nLL | |             });\n   | |______________^\n   |\n   = help: consider using `write!` to avoid the extra allocation\n   = note: you may need to import the `std::fmt::Write` trait\n   = note: `-D clippy::format-push-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::format_push_string)]`\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:21:9\n   |\nLL | /         s += &(if let Some(_a) = Some(1234) {\nLL | |             format!(\"{}\", 1234)\n   | |             ------------------- `format!` used here\nLL | |\nLL | |         } else {\nLL | |             format!(\"{}\", 1234)\n   | |             ------------------- `format!` used here\nLL | |         });\n   | |__________^\n   |\n   = help: consider using `write!` to avoid the extra allocation\n   = note: you may need to import the `std::fmt::Write` trait\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:28:9\n   |\nLL | /         s += &(match Some(1234) {\nLL | |             Some(_) => format!(\"{}\", 1234),\n   | |                        ------------------- `format!` used here\nLL | |\nLL | |             None => format!(\"{}\", 1234),\n   | |                     ------------------- `format!` used here\nLL | |         });\n   | |__________^\n   |\n   = help: consider using `write!` to avoid the extra allocation\n   = note: you may need to import the `std::fmt::Write` trait\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:41:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:49:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:54:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:62:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:69:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:79:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:84:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:94:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:102:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:107:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:115:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:122:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:132:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: `format!(..)` appended to existing `String`\n  --> tests/ui/format_push_string_unfixable.rs:137:17\n   |\nLL |                 string.push_str(&format!(\"{:?}\", 1234));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may need to import the `std::fmt::Write` trait\nhelp: consider using `write!` to avoid the extra allocation\n   |\nLL -                 string.push_str(&format!(\"{:?}\", 1234));\nLL +                 let _ = write!(string, \"{:?}\", 1234);\n   |\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/formatting.rs",
    "content": "#![allow(clippy::if_same_then_else)]\n#![allow(clippy::deref_addrof)]\n#![allow(clippy::nonminimal_bool)]\n\nfn foo() -> bool {\n    true\n}\n\n#[rustfmt::skip]\nfn main() {\n    // weird op_eq formatting:\n    let mut a = 42;\n    a =- 35;\n    //~^ suspicious_assignment_formatting\n\n\n    a =* &191;\n    //~^ suspicious_assignment_formatting\n\n\n\n    let mut b = true;\n    b =! false;\n    //~^ suspicious_assignment_formatting\n\n\n\n    // those are ok:\n    a = -35;\n    a = *&191;\n    b = !false;\n\n    // possible missing comma in an array\n    let _ = &[\n        -1, -2, -3 // <= no comma here\n        //~^ possible_missing_comma\n\n\n        -4, -5, -6\n    ];\n    let _ = &[\n        -1, -2, -3 // <= no comma here\n        //~^ possible_missing_comma\n\n\n        *4, -5, -6\n    ];\n\n    // those are ok:\n    let _ = &[\n        -1, -2, -3,\n        -4, -5, -6\n    ];\n    let _ = &[\n        -1, -2, -3,\n        -4, -5, -6,\n    ];\n    let _ = &[\n        1 + 2, 3 +\n        4, 5 + 6,\n    ];\n\n    // don't lint for bin op without unary equiv\n    // issue 3244\n    vec![\n        1\n        / 2,\n    ];\n    // issue 3396\n    vec![\n        true\n        | false,\n    ];\n\n    // don't lint if the indentation suggests not to\n    let _ = &[\n        1 + 2, 3\n                - 4, 5\n    ];\n    // lint if it doesn't\n    let _ = &[\n        -1\n        //~^ possible_missing_comma\n\n\n        -4,\n    ];\n}\n"
  },
  {
    "path": "tests/ui/formatting.stderr",
    "content": "error: this looks like you are trying to use `.. -= ..`, but you really are doing `.. = (- ..)`\n  --> tests/ui/formatting.rs:13:6\n   |\nLL |     a =- 35;\n   |      ^^^^\n   |\n   = note: to remove this lint, use either `-=` or `= -`\n   = note: `-D clippy::suspicious-assignment-formatting` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_assignment_formatting)]`\n\nerror: this looks like you are trying to use `.. *= ..`, but you really are doing `.. = (* ..)`\n  --> tests/ui/formatting.rs:17:6\n   |\nLL |     a =* &191;\n   |      ^^^^\n   |\n   = note: to remove this lint, use either `*=` or `= *`\n\nerror: this looks like you are trying to use `.. != ..`, but you really are doing `.. = (! ..)`\n  --> tests/ui/formatting.rs:23:6\n   |\nLL |     b =! false;\n   |      ^^^^\n   |\n   = note: to remove this lint, use either `!=` or `= !`\n\nerror: possibly missing a comma here\n  --> tests/ui/formatting.rs:35:19\n   |\nLL |         -1, -2, -3 // <= no comma here\n   |                   ^\n   |\n   = note: to remove this lint, add a comma or write the expr in a single line\n   = note: `#[deny(clippy::possible_missing_comma)]` on by default\n\nerror: possibly missing a comma here\n  --> tests/ui/formatting.rs:42:19\n   |\nLL |         -1, -2, -3 // <= no comma here\n   |                   ^\n   |\n   = note: to remove this lint, add a comma or write the expr in a single line\n\nerror: possibly missing a comma here\n  --> tests/ui/formatting.rs:82:11\n   |\nLL |         -1\n   |           ^\n   |\n   = note: to remove this lint, add a comma or write the expr in a single line\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/four_forward_slashes.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![feature(custom_inner_attributes)]\n#![allow(unused)]\n#![warn(clippy::four_forward_slashes)]\n#![no_main]\n#![rustfmt::skip]\n\n#[macro_use]\nextern crate proc_macros;\n\n/// whoops\n//~^ four_forward_slashes\nfn a() {}\n\n/// whoops\n//~^ four_forward_slashes\n#[allow(dead_code)]\nfn b() {}\n\n/// whoops\n/// two borked comments!\n//~^^ four_forward_slashes\n#[track_caller]\nfn c() {}\n\nfn d() {}\n\n#[test]\n/// between attributes\n//~^ four_forward_slashes\n#[allow(dead_code)]\nfn g() {}\n\n/// not very start of contents\n    //~^ four_forward_slashes\nfn h() {}\n\nfn i() {\n    //// don't lint me bozo\n    todo!()\n}\n\nexternal! {\n    //// don't lint me bozo\n    fn e() {}\n}\n\nwith_span! {\n    span\n    //// don't lint me bozo\n    fn f() {}\n}\n"
  },
  {
    "path": "tests/ui/four_forward_slashes.rs",
    "content": "//@aux-build:proc_macros.rs\n#![feature(custom_inner_attributes)]\n#![allow(unused)]\n#![warn(clippy::four_forward_slashes)]\n#![no_main]\n#![rustfmt::skip]\n\n#[macro_use]\nextern crate proc_macros;\n\n//// whoops\n//~^ four_forward_slashes\nfn a() {}\n\n//// whoops\n//~^ four_forward_slashes\n#[allow(dead_code)]\nfn b() {}\n\n//// whoops\n//// two borked comments!\n//~^^ four_forward_slashes\n#[track_caller]\nfn c() {}\n\nfn d() {}\n\n#[test]\n//// between attributes\n//~^ four_forward_slashes\n#[allow(dead_code)]\nfn g() {}\n\n    //// not very start of contents\n    //~^ four_forward_slashes\nfn h() {}\n\nfn i() {\n    //// don't lint me bozo\n    todo!()\n}\n\nexternal! {\n    //// don't lint me bozo\n    fn e() {}\n}\n\nwith_span! {\n    span\n    //// don't lint me bozo\n    fn f() {}\n}\n"
  },
  {
    "path": "tests/ui/four_forward_slashes.stderr",
    "content": "error: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't\n  --> tests/ui/four_forward_slashes.rs:11:1\n   |\nLL | / //// whoops\nLL | |\nLL | | fn a() {}\n   | |_^\n   |\n   = note: `-D clippy::four-forward-slashes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`\nhelp: make this a doc comment by removing one `/`\n   |\nLL - //// whoops\nLL -\nLL + /// whoops\n   |\n\nerror: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't\n  --> tests/ui/four_forward_slashes.rs:15:1\n   |\nLL | / //// whoops\nLL | |\nLL | | #[allow(dead_code)]\nLL | | fn b() {}\n   | |_^\n   |\nhelp: make this a doc comment by removing one `/`\n   |\nLL - //// whoops\nLL -\nLL + /// whoops\n   |\n\nerror: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't\n  --> tests/ui/four_forward_slashes.rs:20:1\n   |\nLL | / //// whoops\nLL | | //// two borked comments!\nLL | |\nLL | | #[track_caller]\nLL | | fn c() {}\n   | |_^\n   |\nhelp: turn these into doc comments by removing one `/`\n   |\nLL + /// whoops\nLL ~ /// two borked comments!\n   |\n\nerror: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't\n  --> tests/ui/four_forward_slashes.rs:29:1\n   |\nLL | / //// between attributes\nLL | |\nLL | | #[allow(dead_code)]\nLL | | fn g() {}\n   | |_^\n   |\nhelp: make this a doc comment by removing one `/`\n   |\nLL - //// between attributes\nLL -\nLL + /// between attributes\n   |\n\nerror: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't\n  --> tests/ui/four_forward_slashes.rs:34:1\n   |\nLL | /     //// not very start of contents\nLL | |\nLL | | fn h() {}\n   | |_^\n   |\nhelp: make this a doc comment by removing one `/`\n   |\nLL -     //// not very start of contents\nLL -\nLL + /// not very start of contents\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/four_forward_slashes_bare_cr.rs",
    "content": "#![warn(clippy::four_forward_slashes)]\n\n//~v four_forward_slashes\n//// nondoc comment with bare CR: '\r'\nfn main() {}\n"
  },
  {
    "path": "tests/ui/four_forward_slashes_bare_cr.stderr",
    "content": "error: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't\n  --> tests/ui/four_forward_slashes_bare_cr.rs:4:1\n   |\nLL | / //// nondoc comment with bare CR: '␍'\nLL | | fn main() {}\n   | |_^\n   |\n   = help: make this a doc comment by removing one `/`\n   = note: bare CR characters are not allowed in doc comments\n   = note: `-D clippy::four-forward-slashes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/four_forward_slashes_first_line.fixed",
    "content": "/// borked doc comment on the first line. doesn't combust!\n//~^ four_forward_slashes\nfn a() {}\n\n// This test's entire purpose is to make sure we don't panic if the comment with four slashes\n// extends to the first line of the file. This is likely pretty rare in production, but an ICE is an\n// ICE.\n"
  },
  {
    "path": "tests/ui/four_forward_slashes_first_line.rs",
    "content": "//// borked doc comment on the first line. doesn't combust!\n//~^ four_forward_slashes\nfn a() {}\n\n// This test's entire purpose is to make sure we don't panic if the comment with four slashes\n// extends to the first line of the file. This is likely pretty rare in production, but an ICE is an\n// ICE.\n"
  },
  {
    "path": "tests/ui/four_forward_slashes_first_line.stderr",
    "content": "error: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't\n  --> tests/ui/four_forward_slashes_first_line.rs:1:1\n   |\nLL | / //// borked doc comment on the first line. doesn't combust!\nLL | |\nLL | | fn a() {}\n   | |_^\n   |\n   = note: `-D clippy::four-forward-slashes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`\nhelp: make this a doc comment by removing one `/`\n   |\nLL - //// borked doc comment on the first line. doesn't combust!\nLL -\nLL + /// borked doc comment on the first line. doesn't combust!\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/from_iter_instead_of_collect.fixed",
    "content": "#![warn(clippy::from_iter_instead_of_collect)]\n#![allow(unused_imports)]\n#![allow(clippy::useless_vec, clippy::manual_repeat_n)]\n\nuse std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};\n\nstruct Foo(Vec<bool>);\n\nimpl FromIterator<bool> for Foo {\n    fn from_iter<T: IntoIterator<Item = bool>>(_: T) -> Self {\n        todo!()\n    }\n}\n\nimpl<'a> FromIterator<&'a bool> for Foo {\n    fn from_iter<T: IntoIterator<Item = &'a bool>>(iter: T) -> Self {\n        iter.into_iter().copied().collect::<Self>()\n        //~^ from_iter_instead_of_collect\n    }\n}\n\nfn main() {\n    let iter_expr = std::iter::repeat(5).take(5);\n    let _ = iter_expr.collect::<Vec<_>>();\n    //~^ from_iter_instead_of_collect\n\n    let _ = vec![5, 5, 5, 5].iter().enumerate().collect::<HashMap<usize, &i8>>();\n    //~^ from_iter_instead_of_collect\n\n    Vec::from_iter(vec![42u32]);\n\n    let a = vec![0, 1, 2];\n    assert_eq!(a, (0..3).collect::<Vec<_>>());\n    //~^ from_iter_instead_of_collect\n    assert_eq!(a, (0..3).collect::<Vec<i32>>());\n    //~^ from_iter_instead_of_collect\n\n    let mut b = (0..3).collect::<VecDeque<_>>();\n    //~^ from_iter_instead_of_collect\n    b.push_back(4);\n\n    let mut b = (0..3).collect::<VecDeque<i32>>();\n    //~^ from_iter_instead_of_collect\n    b.push_back(4);\n\n    {\n        use std::collections;\n        let mut b = (0..3).collect::<collections::VecDeque<i32>>();\n        //~^ from_iter_instead_of_collect\n        b.push_back(4);\n    }\n\n    let values = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')];\n    let bm = values.iter().cloned().collect::<BTreeMap<_, _>>();\n    //~^ from_iter_instead_of_collect\n    let mut bar = bm.range(0..2).collect::<BTreeMap<_, _>>();\n    //~^ from_iter_instead_of_collect\n    bar.insert(&4, &'e');\n\n    let mut bts = (0..3).collect::<BTreeSet<_>>();\n    //~^ from_iter_instead_of_collect\n    bts.insert(2);\n    {\n        use std::collections;\n        let _ = (0..3).collect::<collections::BTreeSet<_>>();\n        //~^ from_iter_instead_of_collect\n        let _ = (0..3).collect::<collections::BTreeSet<u32>>();\n        //~^ from_iter_instead_of_collect\n    }\n\n    for _i in [1, 2, 3].iter().collect::<Vec<_>>() {}\n    //~^ from_iter_instead_of_collect\n    for _i in [1, 2, 3].iter().collect::<Vec<&i32>>() {}\n    //~^ from_iter_instead_of_collect\n}\n\nfn issue14581() {\n    let nums = [0, 1, 2];\n    let _ = &nums.iter().map(|&num| char::from_u32(num).unwrap()).collect::<String>();\n    //~^ from_iter_instead_of_collect\n}\n\nfn test_implicit_generic_args(iter: impl Iterator<Item = &'static i32> + Copy) {\n    struct S<'l, T = i32, const A: usize = 3, const B: usize = 3> {\n        a: [&'l T; A],\n        b: [&'l T; B],\n    }\n\n    impl<'l, T, const A: usize, const B: usize> FromIterator<&'l T> for S<'l, T, A, B> {\n        fn from_iter<I: IntoIterator<Item = &'l T>>(_: I) -> Self {\n            todo!()\n        }\n    }\n\n    let _ = iter.collect::<S<'static, i32, 7>>();\n    //~^ from_iter_instead_of_collect\n\n    let _ = iter.collect::<S<'static, i32>>();\n    //~^ from_iter_instead_of_collect\n\n    let _ = iter.collect::<S<'static, _, 7>>();\n    //~^ from_iter_instead_of_collect\n\n    let _ = iter.collect::<S<'static, _, 7, 8>>();\n    //~^ from_iter_instead_of_collect\n\n    let _ = iter.collect::<S<_, 7, 8>>();\n    //~^ from_iter_instead_of_collect\n\n    let _ = iter.collect::<S<i32>>();\n    //~^ from_iter_instead_of_collect\n\n    let _ = iter.collect::<S<i32>>();\n    //~^ from_iter_instead_of_collect\n\n    let _ = iter.collect::<S>();\n    //~^ from_iter_instead_of_collect\n}\n"
  },
  {
    "path": "tests/ui/from_iter_instead_of_collect.rs",
    "content": "#![warn(clippy::from_iter_instead_of_collect)]\n#![allow(unused_imports)]\n#![allow(clippy::useless_vec, clippy::manual_repeat_n)]\n\nuse std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};\n\nstruct Foo(Vec<bool>);\n\nimpl FromIterator<bool> for Foo {\n    fn from_iter<T: IntoIterator<Item = bool>>(_: T) -> Self {\n        todo!()\n    }\n}\n\nimpl<'a> FromIterator<&'a bool> for Foo {\n    fn from_iter<T: IntoIterator<Item = &'a bool>>(iter: T) -> Self {\n        <Self as FromIterator<bool>>::from_iter(iter.into_iter().copied())\n        //~^ from_iter_instead_of_collect\n    }\n}\n\nfn main() {\n    let iter_expr = std::iter::repeat(5).take(5);\n    let _ = Vec::from_iter(iter_expr);\n    //~^ from_iter_instead_of_collect\n\n    let _ = HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate());\n    //~^ from_iter_instead_of_collect\n\n    Vec::from_iter(vec![42u32]);\n\n    let a = vec![0, 1, 2];\n    assert_eq!(a, Vec::from_iter(0..3));\n    //~^ from_iter_instead_of_collect\n    assert_eq!(a, Vec::<i32>::from_iter(0..3));\n    //~^ from_iter_instead_of_collect\n\n    let mut b = VecDeque::from_iter(0..3);\n    //~^ from_iter_instead_of_collect\n    b.push_back(4);\n\n    let mut b = VecDeque::<i32>::from_iter(0..3);\n    //~^ from_iter_instead_of_collect\n    b.push_back(4);\n\n    {\n        use std::collections;\n        let mut b = collections::VecDeque::<i32>::from_iter(0..3);\n        //~^ from_iter_instead_of_collect\n        b.push_back(4);\n    }\n\n    let values = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')];\n    let bm = BTreeMap::from_iter(values.iter().cloned());\n    //~^ from_iter_instead_of_collect\n    let mut bar = BTreeMap::from_iter(bm.range(0..2));\n    //~^ from_iter_instead_of_collect\n    bar.insert(&4, &'e');\n\n    let mut bts = BTreeSet::from_iter(0..3);\n    //~^ from_iter_instead_of_collect\n    bts.insert(2);\n    {\n        use std::collections;\n        let _ = collections::BTreeSet::from_iter(0..3);\n        //~^ from_iter_instead_of_collect\n        let _ = collections::BTreeSet::<u32>::from_iter(0..3);\n        //~^ from_iter_instead_of_collect\n    }\n\n    for _i in Vec::from_iter([1, 2, 3].iter()) {}\n    //~^ from_iter_instead_of_collect\n    for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {}\n    //~^ from_iter_instead_of_collect\n}\n\nfn issue14581() {\n    let nums = [0, 1, 2];\n    let _ = &String::from_iter(nums.iter().map(|&num| char::from_u32(num).unwrap()));\n    //~^ from_iter_instead_of_collect\n}\n\nfn test_implicit_generic_args(iter: impl Iterator<Item = &'static i32> + Copy) {\n    struct S<'l, T = i32, const A: usize = 3, const B: usize = 3> {\n        a: [&'l T; A],\n        b: [&'l T; B],\n    }\n\n    impl<'l, T, const A: usize, const B: usize> FromIterator<&'l T> for S<'l, T, A, B> {\n        fn from_iter<I: IntoIterator<Item = &'l T>>(_: I) -> Self {\n            todo!()\n        }\n    }\n\n    let _ = <S<'static, i32, 7>>::from_iter(iter);\n    //~^ from_iter_instead_of_collect\n\n    let _ = <S<'static, i32>>::from_iter(iter);\n    //~^ from_iter_instead_of_collect\n\n    let _ = <S<'static, _, 7>>::from_iter(iter);\n    //~^ from_iter_instead_of_collect\n\n    let _ = <S<'static, _, 7, 8>>::from_iter(iter);\n    //~^ from_iter_instead_of_collect\n\n    let _ = <S<'_, _, 7, 8>>::from_iter(iter);\n    //~^ from_iter_instead_of_collect\n\n    let _ = <S<i32>>::from_iter(iter);\n    //~^ from_iter_instead_of_collect\n\n    let _ = <S<'_, i32>>::from_iter(iter);\n    //~^ from_iter_instead_of_collect\n\n    let _ = <S>::from_iter(iter);\n    //~^ from_iter_instead_of_collect\n}\n"
  },
  {
    "path": "tests/ui/from_iter_instead_of_collect.stderr",
    "content": "error: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:17:9\n   |\nLL |         <Self as FromIterator<bool>>::from_iter(iter.into_iter().copied())\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.into_iter().copied().collect::<Self>()`\n   |\n   = note: `-D clippy::from-iter-instead-of-collect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::from_iter_instead_of_collect)]`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:24:13\n   |\nLL |     let _ = Vec::from_iter(iter_expr);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter_expr.collect::<Vec<_>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:27:13\n   |\nLL |     let _ = HashMap::<usize, &i8>::from_iter(vec![5, 5, 5, 5].iter().enumerate());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `vec![5, 5, 5, 5].iter().enumerate().collect::<HashMap<usize, &i8>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:33:19\n   |\nLL |     assert_eq!(a, Vec::from_iter(0..3));\n   |                   ^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<_>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:35:19\n   |\nLL |     assert_eq!(a, Vec::<i32>::from_iter(0..3));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<Vec<i32>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:38:17\n   |\nLL |     let mut b = VecDeque::from_iter(0..3);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<_>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:42:17\n   |\nLL |     let mut b = VecDeque::<i32>::from_iter(0..3);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<VecDeque<i32>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:48:21\n   |\nLL |         let mut b = collections::VecDeque::<i32>::from_iter(0..3);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::VecDeque<i32>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:54:14\n   |\nLL |     let bm = BTreeMap::from_iter(values.iter().cloned());\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `values.iter().cloned().collect::<BTreeMap<_, _>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:56:19\n   |\nLL |     let mut bar = BTreeMap::from_iter(bm.range(0..2));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `bm.range(0..2).collect::<BTreeMap<_, _>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:60:19\n   |\nLL |     let mut bts = BTreeSet::from_iter(0..3);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<BTreeSet<_>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:65:17\n   |\nLL |         let _ = collections::BTreeSet::from_iter(0..3);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<_>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:67:17\n   |\nLL |         let _ = collections::BTreeSet::<u32>::from_iter(0..3);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `(0..3).collect::<collections::BTreeSet<u32>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:71:15\n   |\nLL |     for _i in Vec::from_iter([1, 2, 3].iter()) {}\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<_>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:73:15\n   |\nLL |     for _i in Vec::<&i32>::from_iter([1, 2, 3].iter()) {}\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `[1, 2, 3].iter().collect::<Vec<&i32>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:79:14\n   |\nLL |     let _ = &String::from_iter(nums.iter().map(|&num| char::from_u32(num).unwrap()));\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `nums.iter().map(|&num| char::from_u32(num).unwrap()).collect::<String>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:95:13\n   |\nLL |     let _ = <S<'static, i32, 7>>::from_iter(iter);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.collect::<S<'static, i32, 7>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:98:13\n   |\nLL |     let _ = <S<'static, i32>>::from_iter(iter);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.collect::<S<'static, i32>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:101:13\n   |\nLL |     let _ = <S<'static, _, 7>>::from_iter(iter);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.collect::<S<'static, _, 7>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:104:13\n   |\nLL |     let _ = <S<'static, _, 7, 8>>::from_iter(iter);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.collect::<S<'static, _, 7, 8>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:107:13\n   |\nLL |     let _ = <S<'_, _, 7, 8>>::from_iter(iter);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.collect::<S<_, 7, 8>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:110:13\n   |\nLL |     let _ = <S<i32>>::from_iter(iter);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.collect::<S<i32>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:113:13\n   |\nLL |     let _ = <S<'_, i32>>::from_iter(iter);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.collect::<S<i32>>()`\n\nerror: usage of `FromIterator::from_iter`\n  --> tests/ui/from_iter_instead_of_collect.rs:116:13\n   |\nLL |     let _ = <S>::from_iter(iter);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: use `.collect()` instead of `::from_iter()`: `iter.collect::<S>()`\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/from_over_into.fixed",
    "content": "#![feature(type_alias_impl_trait)]\n#![warn(clippy::from_over_into)]\n#![allow(non_local_definitions)]\n#![allow(unused)]\n\n// this should throw an error\nstruct StringWrapper(String);\n\nimpl From<String> for StringWrapper {\n    //~^ from_over_into\n    fn from(val: String) -> Self {\n        StringWrapper(val)\n    }\n}\n\nstruct SelfType(String);\n\nimpl From<String> for SelfType {\n    //~^ from_over_into\n    fn from(val: String) -> Self {\n        SelfType(String::new())\n    }\n}\n\n#[derive(Default)]\nstruct X;\n\nimpl X {\n    const FOO: &'static str = \"a\";\n}\n\nstruct SelfKeywords;\n\nimpl From<X> for SelfKeywords {\n    //~^ from_over_into\n    fn from(val: X) -> Self {\n        let _ = X;\n        let _ = X::FOO;\n        let _: X = val;\n\n        SelfKeywords\n    }\n}\n\nstruct ExplicitPaths(bool);\n\nimpl core::convert::From<crate::ExplicitPaths> for bool {\n    //~^ from_over_into\n    fn from(mut val: crate::ExplicitPaths) -> Self {\n        let in_closure = || val.0;\n\n        val.0 = false;\n        val.0\n    }\n}\n\n// this is fine\nstruct A(String);\n\nimpl From<String> for A {\n    fn from(s: String) -> A {\n        A(s)\n    }\n}\n\nstruct PathInExpansion;\n\nimpl From<PathInExpansion> for String {\n    //~^ from_over_into\n    fn from(val: PathInExpansion) -> Self {\n        // non self/Self paths in expansions are fine\n        panic!()\n    }\n}\n\n#[clippy::msrv = \"1.40\"]\nfn msrv_1_40() {\n    struct FromOverInto<T>(Vec<T>);\n\n    impl<T> Into<FromOverInto<T>> for Vec<T> {\n        fn into(self) -> FromOverInto<T> {\n            FromOverInto(self)\n        }\n    }\n}\n\n#[clippy::msrv = \"1.41\"]\nfn msrv_1_41() {\n    struct FromOverInto<T>(Vec<T>);\n\n    impl<T> From<Vec<T>> for FromOverInto<T> {\n        //~^ from_over_into\n        fn from(val: Vec<T>) -> Self {\n            FromOverInto(val)\n        }\n    }\n}\n\nfn issue_12138() {\n    struct Hello;\n\n    impl From<Hello> for () {\n        //~^ from_over_into\n        fn from(val: Hello) {}\n    }\n}\n\nfn issue_112502() {\n    struct MyInt(i64);\n\n    impl From<MyInt> for i64 {\n        //~^ from_over_into\n        fn from(val: MyInt) -> Self {\n            val.0\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/from_over_into.rs",
    "content": "#![feature(type_alias_impl_trait)]\n#![warn(clippy::from_over_into)]\n#![allow(non_local_definitions)]\n#![allow(unused)]\n\n// this should throw an error\nstruct StringWrapper(String);\n\nimpl Into<StringWrapper> for String {\n    //~^ from_over_into\n    fn into(self) -> StringWrapper {\n        StringWrapper(self)\n    }\n}\n\nstruct SelfType(String);\n\nimpl Into<SelfType> for String {\n    //~^ from_over_into\n    fn into(self) -> SelfType {\n        SelfType(Self::new())\n    }\n}\n\n#[derive(Default)]\nstruct X;\n\nimpl X {\n    const FOO: &'static str = \"a\";\n}\n\nstruct SelfKeywords;\n\nimpl Into<SelfKeywords> for X {\n    //~^ from_over_into\n    fn into(self) -> SelfKeywords {\n        let _ = Self;\n        let _ = Self::FOO;\n        let _: Self = self;\n\n        SelfKeywords\n    }\n}\n\nstruct ExplicitPaths(bool);\n\nimpl core::convert::Into<bool> for crate::ExplicitPaths {\n    //~^ from_over_into\n    fn into(mut self) -> bool {\n        let in_closure = || self.0;\n\n        self.0 = false;\n        self.0\n    }\n}\n\n// this is fine\nstruct A(String);\n\nimpl From<String> for A {\n    fn from(s: String) -> A {\n        A(s)\n    }\n}\n\nstruct PathInExpansion;\n\nimpl Into<String> for PathInExpansion {\n    //~^ from_over_into\n    fn into(self) -> String {\n        // non self/Self paths in expansions are fine\n        panic!()\n    }\n}\n\n#[clippy::msrv = \"1.40\"]\nfn msrv_1_40() {\n    struct FromOverInto<T>(Vec<T>);\n\n    impl<T> Into<FromOverInto<T>> for Vec<T> {\n        fn into(self) -> FromOverInto<T> {\n            FromOverInto(self)\n        }\n    }\n}\n\n#[clippy::msrv = \"1.41\"]\nfn msrv_1_41() {\n    struct FromOverInto<T>(Vec<T>);\n\n    impl<T> Into<FromOverInto<T>> for Vec<T> {\n        //~^ from_over_into\n        fn into(self) -> FromOverInto<T> {\n            FromOverInto(self)\n        }\n    }\n}\n\nfn issue_12138() {\n    struct Hello;\n\n    impl Into<()> for Hello {\n        //~^ from_over_into\n        fn into(self) {}\n    }\n}\n\nfn issue_112502() {\n    struct MyInt(i64);\n\n    impl Into<i64> for MyInt {\n        //~^ from_over_into\n        fn into(self: MyInt) -> i64 {\n            self.0\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/from_over_into.stderr",
    "content": "error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into.rs:9:1\n   |\nLL | impl Into<StringWrapper> for String {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::from-over-into` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::from_over_into)]`\nhelp: replace the `Into` implementation with `From<std::string::String>`\n   |\nLL ~ impl From<String> for StringWrapper {\nLL |\nLL ~     fn from(val: String) -> Self {\nLL ~         StringWrapper(val)\n   |\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into.rs:18:1\n   |\nLL | impl Into<SelfType> for String {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace the `Into` implementation with `From<std::string::String>`\n   |\nLL ~ impl From<String> for SelfType {\nLL |\nLL ~     fn from(val: String) -> Self {\nLL ~         SelfType(String::new())\n   |\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into.rs:34:1\n   |\nLL | impl Into<SelfKeywords> for X {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace the `Into` implementation with `From<X>`\n   |\nLL ~ impl From<X> for SelfKeywords {\nLL |\nLL ~     fn from(val: X) -> Self {\nLL ~         let _ = X;\nLL ~         let _ = X::FOO;\nLL ~         let _: X = val;\n   |\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into.rs:47:1\n   |\nLL | impl core::convert::Into<bool> for crate::ExplicitPaths {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence\nhelp: replace the `Into` implementation with `From<ExplicitPaths>`\n   |\nLL ~ impl core::convert::From<crate::ExplicitPaths> for bool {\nLL |\nLL ~     fn from(mut val: crate::ExplicitPaths) -> Self {\nLL ~         let in_closure = || val.0;\nLL |\nLL ~         val.0 = false;\nLL ~         val.0\n   |\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into.rs:68:1\n   |\nLL | impl Into<String> for PathInExpansion {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence\nhelp: replace the `Into` implementation with `From<PathInExpansion>`\n   |\nLL ~ impl From<PathInExpansion> for String {\nLL |\nLL ~     fn from(val: PathInExpansion) -> Self {\n   |\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into.rs:91:5\n   |\nLL |     impl<T> Into<FromOverInto<T>> for Vec<T> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace the `Into` implementation with `From<std::vec::Vec<T>>`\n   |\nLL ~     impl<T> From<Vec<T>> for FromOverInto<T> {\nLL |\nLL ~         fn from(val: Vec<T>) -> Self {\nLL ~             FromOverInto(val)\n   |\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into.rs:102:5\n   |\nLL |     impl Into<()> for Hello {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence\nhelp: replace the `Into` implementation with `From<issue_12138::Hello>`\n   |\nLL ~     impl From<Hello> for () {\nLL |\nLL ~         fn from(val: Hello) {}\n   |\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into.rs:111:5\n   |\nLL |     impl Into<i64> for MyInt {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence\nhelp: replace the `Into` implementation with `From<issue_112502::MyInt>`\n   |\nLL ~     impl From<MyInt> for i64 {\nLL |\nLL ~         fn from(val: MyInt) -> Self {\nLL ~             val.0\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/from_over_into_unfixable.rs",
    "content": "#![warn(clippy::from_over_into)]\n\nstruct InMacro(String);\n\nmacro_rules! in_macro {\n    () => {\n        Self::new()\n    };\n}\n\nimpl Into<InMacro> for String {\n    //~^ from_over_into\n\n    fn into(self) -> InMacro {\n        InMacro(in_macro!())\n    }\n}\n\nstruct WeirdUpperSelf;\n\nimpl Into<WeirdUpperSelf> for &'static [u8] {\n    //~^ from_over_into\n\n    fn into(self) -> WeirdUpperSelf {\n        let _ = Self::default();\n        WeirdUpperSelf\n    }\n}\n\nstruct ContainsVal;\n\nimpl Into<u8> for ContainsVal {\n    //~^ from_over_into\n\n    fn into(self) -> u8 {\n        let val = 1;\n        val + 1\n    }\n}\n\npub struct Lval<T>(T);\n\npub struct Rval<T>(T);\n\nimpl<T> Into<Rval<Self>> for Lval<T> {\n    //~^ from_over_into\n\n    fn into(self) -> Rval<Self> {\n        Rval(self)\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/from_over_into_unfixable.stderr",
    "content": "error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into_unfixable.rs:11:1\n   |\nLL | impl Into<InMacro> for String {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: replace the `Into` implementation with `From<std::string::String>`\n   = note: `-D clippy::from-over-into` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::from_over_into)]`\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into_unfixable.rs:21:1\n   |\nLL | impl Into<WeirdUpperSelf> for &'static [u8] {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: replace the `Into` implementation with `From<&'static [u8]>`\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into_unfixable.rs:32:1\n   |\nLL | impl Into<u8> for ContainsVal {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see\n           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence\n   = help: replace the `Into` implementation with `From<ContainsVal>`\n\nerror: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true\n  --> tests/ui/from_over_into_unfixable.rs:45:1\n   |\nLL | impl<T> Into<Rval<Self>> for Lval<T> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: replace the `Into` implementation with `From<Lval<T>>`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/from_raw_with_void_ptr.rs",
    "content": "#![warn(clippy::from_raw_with_void_ptr)]\n#![allow(clippy::unnecessary_cast)]\n\nuse std::ffi::c_void;\nuse std::rc::Rc;\nuse std::sync::Arc;\n\nfn main() {\n    // must lint\n    let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;\n    let _ = unsafe { Box::from_raw(ptr) };\n    //~^ from_raw_with_void_ptr\n\n    // shouldn't be linted\n    let _ = unsafe { Box::from_raw(ptr as *mut usize) };\n\n    // shouldn't be linted\n    let should_not_lint_ptr = Box::into_raw(Box::new(12u8)) as *mut u8;\n    let _ = unsafe { Box::from_raw(should_not_lint_ptr as *mut u8) };\n\n    // must lint\n    let ptr = Rc::into_raw(Rc::new(42usize)) as *mut c_void;\n    let _ = unsafe { Rc::from_raw(ptr) };\n    //~^ from_raw_with_void_ptr\n\n    // must lint\n    let ptr = Arc::into_raw(Arc::new(42usize)) as *mut c_void;\n    let _ = unsafe { Arc::from_raw(ptr) };\n    //~^ from_raw_with_void_ptr\n\n    // must lint\n    let ptr = std::rc::Weak::into_raw(Rc::downgrade(&Rc::new(42usize))) as *mut c_void;\n    let _ = unsafe { std::rc::Weak::from_raw(ptr) };\n    //~^ from_raw_with_void_ptr\n\n    // must lint\n    let ptr = std::sync::Weak::into_raw(Arc::downgrade(&Arc::new(42usize))) as *mut c_void;\n    let _ = unsafe { std::sync::Weak::from_raw(ptr) };\n    //~^ from_raw_with_void_ptr\n}\n"
  },
  {
    "path": "tests/ui/from_raw_with_void_ptr.stderr",
    "content": "error: creating a `Box` from a void raw pointer\n  --> tests/ui/from_raw_with_void_ptr.rs:11:22\n   |\nLL |     let _ = unsafe { Box::from_raw(ptr) };\n   |                      ^^^^^^^^^^^^^^^^^^\n   |\nhelp: cast this to a pointer of the appropriate type\n  --> tests/ui/from_raw_with_void_ptr.rs:11:36\n   |\nLL |     let _ = unsafe { Box::from_raw(ptr) };\n   |                                    ^^^\n   = note: `-D clippy::from-raw-with-void-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::from_raw_with_void_ptr)]`\n\nerror: creating a `Rc` from a void raw pointer\n  --> tests/ui/from_raw_with_void_ptr.rs:23:22\n   |\nLL |     let _ = unsafe { Rc::from_raw(ptr) };\n   |                      ^^^^^^^^^^^^^^^^^\n   |\nhelp: cast this to a pointer of the appropriate type\n  --> tests/ui/from_raw_with_void_ptr.rs:23:35\n   |\nLL |     let _ = unsafe { Rc::from_raw(ptr) };\n   |                                   ^^^\n\nerror: creating a `Arc` from a void raw pointer\n  --> tests/ui/from_raw_with_void_ptr.rs:28:22\n   |\nLL |     let _ = unsafe { Arc::from_raw(ptr) };\n   |                      ^^^^^^^^^^^^^^^^^^\n   |\nhelp: cast this to a pointer of the appropriate type\n  --> tests/ui/from_raw_with_void_ptr.rs:28:36\n   |\nLL |     let _ = unsafe { Arc::from_raw(ptr) };\n   |                                    ^^^\n\nerror: creating a `Weak` from a void raw pointer\n  --> tests/ui/from_raw_with_void_ptr.rs:33:22\n   |\nLL |     let _ = unsafe { std::rc::Weak::from_raw(ptr) };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: cast this to a pointer of the appropriate type\n  --> tests/ui/from_raw_with_void_ptr.rs:33:46\n   |\nLL |     let _ = unsafe { std::rc::Weak::from_raw(ptr) };\n   |                                              ^^^\n\nerror: creating a `Weak` from a void raw pointer\n  --> tests/ui/from_raw_with_void_ptr.rs:38:22\n   |\nLL |     let _ = unsafe { std::sync::Weak::from_raw(ptr) };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: cast this to a pointer of the appropriate type\n  --> tests/ui/from_raw_with_void_ptr.rs:38:48\n   |\nLL |     let _ = unsafe { std::sync::Weak::from_raw(ptr) };\n   |                                                ^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/from_str_radix_10.fixed",
    "content": "#![warn(clippy::from_str_radix_10)]\n\nmod some_mod {\n    // fake function that shouldn't trigger the lint\n    pub fn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> {\n        unimplemented!()\n    }\n}\n\n// fake function that shouldn't trigger the lint\nfn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> {\n    unimplemented!()\n}\n\n// to test parenthesis addition\nstruct Test;\n\nimpl std::ops::Add<Test> for Test {\n    type Output = &'static str;\n\n    fn add(self, _: Self) -> Self::Output {\n        \"304\"\n    }\n}\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    // all of these should trigger the lint\n    \"30\".parse::<u32>()?;\n    //~^ from_str_radix_10\n\n    \"24\".parse::<i64>()?;\n    //~^ from_str_radix_10\n\n    \"100\".parse::<isize>()?;\n    //~^ from_str_radix_10\n\n    \"7\".parse::<u8>()?;\n    //~^ from_str_radix_10\n\n    (\"10\".to_owned() + \"5\").parse::<u16>()?;\n    //~^ from_str_radix_10\n\n    (Test + Test).parse::<i128>()?;\n    //~^ from_str_radix_10\n\n    let string = \"300\";\n    string.parse::<i32>()?;\n    //~^ from_str_radix_10\n\n    let stringier = \"400\".to_string();\n    stringier.parse::<i32>()?;\n    //~^ from_str_radix_10\n\n    // none of these should trigger the lint\n    u16::from_str_radix(\"20\", 3)?;\n    i32::from_str_radix(\"45\", 12)?;\n    usize::from_str_radix(\"10\", 16)?;\n    i128::from_str_radix(\"10\", 13)?;\n    some_mod::from_str_radix(\"50\", 10)?;\n    some_mod::from_str_radix(\"50\", 6)?;\n    from_str_radix(\"50\", 10)?;\n    from_str_radix(\"50\", 6)?;\n\n    Ok(())\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/12731\nfn issue_12731() {\n    const A: Result<u32, std::num::ParseIntError> = u32::from_str_radix(\"123\", 10);\n    const B: () = {\n        let _ = u32::from_str_radix(\"123\", 10);\n    };\n    const fn foo() {\n        let _ = u32::from_str_radix(\"123\", 10);\n    }\n}\n\nfn fix_str_ref_check() {\n    #![allow(clippy::needless_borrow)]\n    let s = \"1\";\n    let _ = s.parse::<u32>().unwrap();\n    //~^ from_str_radix_10\n    let s_ref = &s;\n    let _ = s_ref.parse::<u32>().unwrap();\n    //~^ from_str_radix_10\n}\n"
  },
  {
    "path": "tests/ui/from_str_radix_10.rs",
    "content": "#![warn(clippy::from_str_radix_10)]\n\nmod some_mod {\n    // fake function that shouldn't trigger the lint\n    pub fn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> {\n        unimplemented!()\n    }\n}\n\n// fake function that shouldn't trigger the lint\nfn from_str_radix(_: &str, _: u32) -> Result<(), std::num::ParseIntError> {\n    unimplemented!()\n}\n\n// to test parenthesis addition\nstruct Test;\n\nimpl std::ops::Add<Test> for Test {\n    type Output = &'static str;\n\n    fn add(self, _: Self) -> Self::Output {\n        \"304\"\n    }\n}\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    // all of these should trigger the lint\n    u32::from_str_radix(\"30\", 10)?;\n    //~^ from_str_radix_10\n\n    i64::from_str_radix(\"24\", 10)?;\n    //~^ from_str_radix_10\n\n    isize::from_str_radix(\"100\", 10)?;\n    //~^ from_str_radix_10\n\n    u8::from_str_radix(\"7\", 10)?;\n    //~^ from_str_radix_10\n\n    u16::from_str_radix(&(\"10\".to_owned() + \"5\"), 10)?;\n    //~^ from_str_radix_10\n\n    i128::from_str_radix(Test + Test, 10)?;\n    //~^ from_str_radix_10\n\n    let string = \"300\";\n    i32::from_str_radix(string, 10)?;\n    //~^ from_str_radix_10\n\n    let stringier = \"400\".to_string();\n    i32::from_str_radix(&stringier, 10)?;\n    //~^ from_str_radix_10\n\n    // none of these should trigger the lint\n    u16::from_str_radix(\"20\", 3)?;\n    i32::from_str_radix(\"45\", 12)?;\n    usize::from_str_radix(\"10\", 16)?;\n    i128::from_str_radix(\"10\", 13)?;\n    some_mod::from_str_radix(\"50\", 10)?;\n    some_mod::from_str_radix(\"50\", 6)?;\n    from_str_radix(\"50\", 10)?;\n    from_str_radix(\"50\", 6)?;\n\n    Ok(())\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/12731\nfn issue_12731() {\n    const A: Result<u32, std::num::ParseIntError> = u32::from_str_radix(\"123\", 10);\n    const B: () = {\n        let _ = u32::from_str_radix(\"123\", 10);\n    };\n    const fn foo() {\n        let _ = u32::from_str_radix(\"123\", 10);\n    }\n}\n\nfn fix_str_ref_check() {\n    #![allow(clippy::needless_borrow)]\n    let s = \"1\";\n    let _ = u32::from_str_radix(&s, 10).unwrap();\n    //~^ from_str_radix_10\n    let s_ref = &s;\n    let _ = u32::from_str_radix(&s_ref, 10).unwrap();\n    //~^ from_str_radix_10\n}\n"
  },
  {
    "path": "tests/ui/from_str_radix_10.stderr",
    "content": "error: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:28:5\n   |\nLL |     u32::from_str_radix(\"30\", 10)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"30\".parse::<u32>()`\n   |\n   = note: `-D clippy::from-str-radix-10` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::from_str_radix_10)]`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:31:5\n   |\nLL |     i64::from_str_radix(\"24\", 10)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"24\".parse::<i64>()`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:34:5\n   |\nLL |     isize::from_str_radix(\"100\", 10)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"100\".parse::<isize>()`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:37:5\n   |\nLL |     u8::from_str_radix(\"7\", 10)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"7\".parse::<u8>()`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:40:5\n   |\nLL |     u16::from_str_radix(&(\"10\".to_owned() + \"5\"), 10)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(\"10\".to_owned() + \"5\").parse::<u16>()`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:43:5\n   |\nLL |     i128::from_str_radix(Test + Test, 10)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(Test + Test).parse::<i128>()`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:47:5\n   |\nLL |     i32::from_str_radix(string, 10)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.parse::<i32>()`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:51:5\n   |\nLL |     i32::from_str_radix(&stringier, 10)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `stringier.parse::<i32>()`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:81:13\n   |\nLL |     let _ = u32::from_str_radix(&s, 10).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.parse::<u32>()`\n\nerror: this call to `from_str_radix` can be replaced with a call to `str::parse`\n  --> tests/ui/from_str_radix_10.rs:84:13\n   |\nLL |     let _ = u32::from_str_radix(&s_ref, 10).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s_ref.parse::<u32>()`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/functions.rs",
    "content": "#![allow(clippy::missing_safety_doc, clippy::uninlined_format_args)]\n\n// TOO_MANY_ARGUMENTS\nfn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {}\n\nfn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}\n//~^ too_many_arguments\n\n#[rustfmt::skip]\nfn bad_multiline(\n//~^ too_many_arguments\n\n    one: u32,\n    two: u32,\n    three: &str,\n    four: bool,\n    five: f32,\n    six: f32,\n    seven: bool,\n    eight: ()\n) {\n    let _one = one;\n    let _two = two;\n    let _three = three;\n    let _four = four;\n    let _five = five;\n    let _six = six;\n    let _seven = seven;\n}\n\n// don't lint extern fns\nextern \"C\" fn extern_fn(\n    _one: u32,\n    _two: u32,\n    _three: *const u8,\n    _four: bool,\n    _five: f32,\n    _six: f32,\n    _seven: bool,\n    _eight: *const std::ffi::c_void,\n) {\n}\n\npub trait Foo {\n    fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool);\n    fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ());\n    //~^ too_many_arguments\n\n    fn ptr(p: *const u8);\n}\n\npub struct Bar;\n\nimpl Bar {\n    fn good_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {}\n    fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}\n    //~^ too_many_arguments\n}\n\n// ok, we don’t want to warn implementations\nimpl Foo for Bar {\n    fn good(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool) {}\n    fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}\n\n    fn ptr(p: *const u8) {\n        println!(\"{}\", unsafe { *p });\n        //~^ not_unsafe_ptr_arg_deref\n\n        println!(\"{:?}\", unsafe { p.as_ref() });\n        //~^ not_unsafe_ptr_arg_deref\n\n        unsafe { std::ptr::read(p) };\n        //~^ not_unsafe_ptr_arg_deref\n    }\n}\n\n// NOT_UNSAFE_PTR_ARG_DEREF\n\nfn private(p: *const u8) {\n    println!(\"{}\", unsafe { *p });\n}\n\npub fn public(p: *const u8) {\n    println!(\"{}\", unsafe { *p });\n    //~^ not_unsafe_ptr_arg_deref\n\n    println!(\"{:?}\", unsafe { p.as_ref() });\n    //~^ not_unsafe_ptr_arg_deref\n\n    unsafe { std::ptr::read(p) };\n    //~^ not_unsafe_ptr_arg_deref\n}\n\ntype Alias = *const u8;\n\npub fn type_alias(p: Alias) {\n    println!(\"{}\", unsafe { *p });\n    //~^ not_unsafe_ptr_arg_deref\n\n    println!(\"{:?}\", unsafe { p.as_ref() });\n    //~^ not_unsafe_ptr_arg_deref\n\n    unsafe { std::ptr::read(p) };\n    //~^ not_unsafe_ptr_arg_deref\n}\n\nimpl Bar {\n    fn private(self, p: *const u8) {\n        println!(\"{}\", unsafe { *p });\n    }\n\n    pub fn public(self, p: *const u8) {\n        println!(\"{}\", unsafe { *p });\n        //~^ not_unsafe_ptr_arg_deref\n\n        println!(\"{:?}\", unsafe { p.as_ref() });\n        //~^ not_unsafe_ptr_arg_deref\n\n        unsafe { std::ptr::read(p) };\n        //~^ not_unsafe_ptr_arg_deref\n    }\n\n    pub fn public_ok(self, p: *const u8) {\n        if !p.is_null() {\n            println!(\"{:p}\", p);\n        }\n    }\n\n    pub unsafe fn public_unsafe(self, p: *const u8) {\n        println!(\"{}\", unsafe { *p });\n        println!(\"{:?}\", unsafe { p.as_ref() });\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/functions.stderr",
    "content": "error: this function has too many arguments (8/7)\n  --> tests/ui/functions.rs:6:1\n   |\nLL | fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::too-many-arguments` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]`\n\nerror: this function has too many arguments (8/7)\n  --> tests/ui/functions.rs:10:1\n   |\nLL | / fn bad_multiline(\nLL | |\nLL | |\nLL | |     one: u32,\n...  |\nLL | |     eight: ()\nLL | | ) {\n   | |_^\n\nerror: this function has too many arguments (8/7)\n  --> tests/ui/functions.rs:46:5\n   |\nLL |     fn bad(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this function has too many arguments (8/7)\n  --> tests/ui/functions.rs:56:5\n   |\nLL |     fn bad_method(_one: u32, _two: u32, _three: &str, _four: bool, _five: f32, _six: f32, _seven: bool, _eight: ()) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:66:34\n   |\nLL |         println!(\"{}\", unsafe { *p });\n   |                                  ^\n   |\n   = note: `#[deny(clippy::not_unsafe_ptr_arg_deref)]` on by default\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:69:35\n   |\nLL |         println!(\"{:?}\", unsafe { p.as_ref() });\n   |                                   ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:72:33\n   |\nLL |         unsafe { std::ptr::read(p) };\n   |                                 ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:84:30\n   |\nLL |     println!(\"{}\", unsafe { *p });\n   |                              ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:87:31\n   |\nLL |     println!(\"{:?}\", unsafe { p.as_ref() });\n   |                               ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:90:29\n   |\nLL |     unsafe { std::ptr::read(p) };\n   |                             ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:97:30\n   |\nLL |     println!(\"{}\", unsafe { *p });\n   |                              ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:100:31\n   |\nLL |     println!(\"{:?}\", unsafe { p.as_ref() });\n   |                               ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:103:29\n   |\nLL |     unsafe { std::ptr::read(p) };\n   |                             ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:113:34\n   |\nLL |         println!(\"{}\", unsafe { *p });\n   |                                  ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:116:35\n   |\nLL |         println!(\"{:?}\", unsafe { p.as_ref() });\n   |                                   ^\n\nerror: this public function might dereference a raw pointer but is not marked `unsafe`\n  --> tests/ui/functions.rs:119:33\n   |\nLL |         unsafe { std::ptr::read(p) };\n   |                                 ^\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/functions_maxlines.rs",
    "content": "#![allow(clippy::unused_unit, clippy::missing_safety_doc)]\n#![warn(clippy::too_many_lines)]\n\nfn good_lines() {\n    /* println!(\"This is good.\"); */\n    // println!(\"This is good.\");\n    /* */ // println!(\"This is good.\");\n    /* */ // println!(\"This is good.\");\n    /* */ // println!(\"This is good.\");\n    /* */ // println!(\"This is good.\");\n    /* println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\"); */\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\");\n}\n\n#[allow(unused)] // the attr shouldn't get included in the highlight\npub async unsafe extern \"Rust\" fn bad_lines() -> () {\n    //~^ too_many_lines\n\n    println!(\"Dont get confused by braces: {{}}\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n}\n\nstruct Foo;\nimpl Foo {\n    #[allow(unused)] // the attr shouldn't get included in the highlight\n    pub async unsafe extern \"Rust\" fn bad_lines() -> () {\n        //~^ too_many_lines\n\n        println!(\"Dont get confused by braces: {{}}\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/functions_maxlines.stderr",
    "content": "error: this function has too many lines (104/100)\n  --> tests/ui/functions_maxlines.rs:60:1\n   |\nLL | pub async unsafe extern \"Rust\" fn bad_lines() -> () {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::too-many-lines` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::too_many_lines)]`\n\nerror: this function has too many lines (104/100)\n  --> tests/ui/functions_maxlines.rs:170:5\n   |\nLL |     pub async unsafe extern \"Rust\" fn bad_lines() -> () {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/future_not_send.rs",
    "content": "#![warn(clippy::future_not_send)]\n\nuse std::cell::Cell;\nuse std::future::Future;\nuse std::rc::Rc;\nuse std::sync::Arc;\n\nasync fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {\n    //~^ future_not_send\n\n    async { true }.await\n}\n\npub async fn public_future(rc: Rc<[u8]>) {\n    //~^ future_not_send\n\n    async { true }.await;\n}\n\npub async fn public_send(arc: Arc<[u8]>) -> bool {\n    async { false }.await\n}\n\nasync fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {\n    //~^ future_not_send\n\n    true\n}\n\npub async fn public_future2(rc: Rc<[u8]>) {}\n//~^ future_not_send\n\npub async fn public_send2(arc: Arc<[u8]>) -> bool {\n    false\n}\n\nstruct Dummy {\n    rc: Rc<[u8]>,\n}\n\nimpl Dummy {\n    async fn private_future(&self) -> usize {\n        //~^ future_not_send\n\n        async { true }.await;\n        self.rc.len()\n    }\n\n    pub async fn public_future(&self) {\n        //~^ future_not_send\n\n        self.private_future().await;\n    }\n\n    #[allow(clippy::manual_async_fn)]\n    pub fn public_send(&self) -> impl std::future::Future<Output = bool> {\n        async { false }\n    }\n}\n\nasync fn generic_future<T>(t: T) -> T\n//~^ future_not_send\nwhere\n    T: Send,\n{\n    let rt = &t;\n    async { true }.await;\n    let _ = rt;\n    t\n}\n\nasync fn maybe_send_generic_future<T>(t: T) -> T {\n    async { true }.await;\n    t\n}\n\nasync fn maybe_send_generic_future2<F: Fn() -> Fut, Fut: Future>(f: F) {\n    async { true }.await;\n    let res = f();\n    async { true }.await;\n}\n\nasync fn generic_future_always_unsend<T>(_: Rc<T>) {\n    //~^ future_not_send\n\n    async { true }.await;\n}\n\nasync fn generic_future_send<T>(t: T)\nwhere\n    T: Send,\n{\n    async { true }.await;\n}\n\nasync fn unclear_future<T>(t: T) {}\n\nfn main() {\n    let rc = Rc::new([1, 2, 3]);\n    private_future(rc.clone(), &Cell::new(42));\n    public_future(rc.clone());\n    let arc = Arc::new([4, 5, 6]);\n    public_send(arc);\n    generic_future(42);\n    generic_future_send(42);\n\n    let dummy = Dummy { rc };\n    dummy.public_future();\n    dummy.public_send();\n}\n"
  },
  {
    "path": "tests/ui/future_not_send.stderr",
    "content": "error: future cannot be sent between threads safely\n  --> tests/ui/future_not_send.rs:8:62\n   |\nLL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {\n   |                                                              ^^^^ future returned by `private_future` is not `Send`\n   |\nnote: future is not `Send` as this value is used across an await\n  --> tests/ui/future_not_send.rs:11:20\n   |\nLL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {\n   |                         -- has type `std::rc::Rc<[u8]>` which is not `Send`\n...\nLL |     async { true }.await\n   |                    ^^^^^ await occurs here, with `rc` maybe used later\n   = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`\nnote: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`\n  --> tests/ui/future_not_send.rs:8:39\n   |\nLL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {\n   |                                       ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`\n   = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`\n   = note: `-D clippy::future-not-send` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]`\n\nerror: future cannot be sent between threads safely\n  --> tests/ui/future_not_send.rs:14:41\n   |\nLL | pub async fn public_future(rc: Rc<[u8]>) {\n   |                                         ^ future returned by `public_future` is not `Send`\n   |\nnote: future is not `Send` as this value is used across an await\n  --> tests/ui/future_not_send.rs:17:20\n   |\nLL | pub async fn public_future(rc: Rc<[u8]>) {\n   |                            -- has type `std::rc::Rc<[u8]>` which is not `Send`\n...\nLL |     async { true }.await;\n   |                    ^^^^^ await occurs here, with `rc` maybe used later\n   = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`\n\nerror: future cannot be sent between threads safely\n  --> tests/ui/future_not_send.rs:24:63\n   |\nLL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {\n   |                                                               ^^^^ future returned by `private_future2` is not `Send`\n   |\nnote: captured value is not `Send`\n  --> tests/ui/future_not_send.rs:24:26\n   |\nLL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {\n   |                          ^^ has type `std::rc::Rc<[u8]>` which is not `Send`\n   = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`\nnote: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`\n  --> tests/ui/future_not_send.rs:24:40\n   |\nLL | async fn private_future2(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {\n   |                                        ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`\n   = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`\n\nerror: future cannot be sent between threads safely\n  --> tests/ui/future_not_send.rs:30:42\n   |\nLL | pub async fn public_future2(rc: Rc<[u8]>) {}\n   |                                          ^ future returned by `public_future2` is not `Send`\n   |\nnote: captured value is not `Send`\n  --> tests/ui/future_not_send.rs:30:29\n   |\nLL | pub async fn public_future2(rc: Rc<[u8]>) {}\n   |                             ^^ has type `std::rc::Rc<[u8]>` which is not `Send`\n   = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`\n\nerror: future cannot be sent between threads safely\n  --> tests/ui/future_not_send.rs:42:39\n   |\nLL |     async fn private_future(&self) -> usize {\n   |                                       ^^^^^ future returned by `private_future` is not `Send`\n   |\nnote: future is not `Send` as this value is used across an await\n  --> tests/ui/future_not_send.rs:45:24\n   |\nLL |     async fn private_future(&self) -> usize {\n   |                             ----- has type `&Dummy` which is not `Send`\n...\nLL |         async { true }.await;\n   |                        ^^^^^ await occurs here, with `&self` maybe used later\n   = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`\n\nerror: future cannot be sent between threads safely\n  --> tests/ui/future_not_send.rs:49:38\n   |\nLL |     pub async fn public_future(&self) {\n   |                                      ^ future returned by `public_future` is not `Send`\n   |\nnote: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`\n  --> tests/ui/future_not_send.rs:49:32\n   |\nLL |     pub async fn public_future(&self) {\n   |                                ^^^^^ has type `&Dummy` which is not `Send`, because `Dummy` is not `Sync`\n   = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`\n\nerror: future cannot be sent between threads safely\n  --> tests/ui/future_not_send.rs:61:37\n   |\nLL | async fn generic_future<T>(t: T) -> T\n   |                                     ^ future returned by `generic_future` is not `Send`\n   |\nnote: future is not `Send` as this value is used across an await\n  --> tests/ui/future_not_send.rs:67:20\n   |\nLL |     let rt = &t;\n   |         -- has type `&T` which is not `Send`\nLL |     async { true }.await;\n   |                    ^^^^^ await occurs here, with `rt` maybe used later\n   = note: `T` doesn't implement `std::marker::Sync`\n\nerror: future cannot be sent between threads safely\n  --> tests/ui/future_not_send.rs:83:51\n   |\nLL | async fn generic_future_always_unsend<T>(_: Rc<T>) {\n   |                                                   ^ future returned by `generic_future_always_unsend` is not `Send`\n   |\nnote: future is not `Send` as this value is used across an await\n  --> tests/ui/future_not_send.rs:86:20\n   |\nLL | async fn generic_future_always_unsend<T>(_: Rc<T>) {\n   |                                          - has type `std::rc::Rc<T>` which is not `Send`\n...\nLL |     async { true }.await;\n   |                    ^^^^^ await occurs here, with `_` maybe used later\n   = note: `std::rc::Rc<T>` doesn't implement `std::marker::Send`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/get_first.fixed",
    "content": "#![warn(clippy::get_first)]\n#![allow(clippy::useless_vec)]\nuse std::collections::{BTreeMap, HashMap, VecDeque};\n\nstruct Bar {\n    arr: [u32; 3],\n}\n\nimpl Bar {\n    fn get(&self, pos: usize) -> Option<&u32> {\n        self.arr.get(pos)\n    }\n}\n\nfn main() {\n    let x = vec![2, 3, 5];\n    let _ = x.first();\n    //~^ get_first\n\n    let _ = x.get(1);\n    let _ = x[0];\n\n    let y = [2, 3, 5];\n    let _ = y.first();\n    //~^ get_first\n\n    let _ = y.get(1);\n    let _ = y[0];\n\n    let z = &[2, 3, 5];\n    let _ = z.first();\n    //~^ get_first\n\n    let _ = z.get(1);\n    let _ = z[0];\n\n    let vecdeque: VecDeque<_> = x.iter().cloned().collect();\n    let _ = vecdeque.front();\n    //~^ get_first\n\n    let _ = vecdeque.get(1);\n\n    let hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]);\n    let btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]);\n    let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice.\n    let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice.\n\n    let bar = Bar { arr: [0, 1, 2] };\n    let _ = bar.get(0); // Do not lint, because Bar is struct.\n\n    let non_primitives = [vec![1, 2], vec![3, 4]];\n    let _ = non_primitives.first();\n    //~^ get_first\n}\n"
  },
  {
    "path": "tests/ui/get_first.rs",
    "content": "#![warn(clippy::get_first)]\n#![allow(clippy::useless_vec)]\nuse std::collections::{BTreeMap, HashMap, VecDeque};\n\nstruct Bar {\n    arr: [u32; 3],\n}\n\nimpl Bar {\n    fn get(&self, pos: usize) -> Option<&u32> {\n        self.arr.get(pos)\n    }\n}\n\nfn main() {\n    let x = vec![2, 3, 5];\n    let _ = x.get(0);\n    //~^ get_first\n\n    let _ = x.get(1);\n    let _ = x[0];\n\n    let y = [2, 3, 5];\n    let _ = y.get(0);\n    //~^ get_first\n\n    let _ = y.get(1);\n    let _ = y[0];\n\n    let z = &[2, 3, 5];\n    let _ = z.get(0);\n    //~^ get_first\n\n    let _ = z.get(1);\n    let _ = z[0];\n\n    let vecdeque: VecDeque<_> = x.iter().cloned().collect();\n    let _ = vecdeque.get(0);\n    //~^ get_first\n\n    let _ = vecdeque.get(1);\n\n    let hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(0, 'a'), (1, 'b')]);\n    let btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(0, 'a'), (1, 'b')]);\n    let _ = hashmap.get(&0); // Do not lint, because HashMap is not slice.\n    let _ = btreemap.get(&0); // Do not lint, because BTreeMap is not slice.\n\n    let bar = Bar { arr: [0, 1, 2] };\n    let _ = bar.get(0); // Do not lint, because Bar is struct.\n\n    let non_primitives = [vec![1, 2], vec![3, 4]];\n    let _ = non_primitives.get(0);\n    //~^ get_first\n}\n"
  },
  {
    "path": "tests/ui/get_first.stderr",
    "content": "error: accessing first element with `x.get(0)`\n  --> tests/ui/get_first.rs:17:13\n   |\nLL |     let _ = x.get(0);\n   |             ^^^^^^^^ help: try: `x.first()`\n   |\n   = note: `-D clippy::get-first` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::get_first)]`\n\nerror: accessing first element with `y.get(0)`\n  --> tests/ui/get_first.rs:24:13\n   |\nLL |     let _ = y.get(0);\n   |             ^^^^^^^^ help: try: `y.first()`\n\nerror: accessing first element with `z.get(0)`\n  --> tests/ui/get_first.rs:31:13\n   |\nLL |     let _ = z.get(0);\n   |             ^^^^^^^^ help: try: `z.first()`\n\nerror: accessing first element with `vecdeque.get(0)`\n  --> tests/ui/get_first.rs:38:13\n   |\nLL |     let _ = vecdeque.get(0);\n   |             ^^^^^^^^^^^^^^^ help: try: `vecdeque.front()`\n\nerror: accessing first element with `non_primitives.get(0)`\n  --> tests/ui/get_first.rs:52:13\n   |\nLL |     let _ = non_primitives.get(0);\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `non_primitives.first()`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/get_last_with_len.fixed",
    "content": "#![warn(clippy::get_last_with_len)]\n#![allow(unused, clippy::useless_vec)]\n\nuse std::collections::VecDeque;\n\nfn dont_use_last() {\n    let x = vec![2, 3, 5];\n    let _ = x.last();\n    //~^ get_last_with_len\n}\n\nfn indexing_two_from_end() {\n    let x = vec![2, 3, 5];\n    let _ = x.get(x.len() - 2);\n}\n\nfn index_into_last() {\n    let x = vec![2, 3, 5];\n    let _ = x[x.len() - 1];\n}\n\nfn use_last_with_different_vec_length() {\n    let x = vec![2, 3, 5];\n    let y = vec!['a', 'b', 'c'];\n    let _ = x.get(y.len() - 1);\n}\n\nstruct S {\n    field: Vec<usize>,\n}\n\nfn in_field(s: &S) {\n    let _ = s.field.last();\n    //~^ get_last_with_len\n}\n\nfn main() {\n    let slice = &[1, 2, 3];\n    let _ = slice.last();\n    //~^ get_last_with_len\n\n    let array = [4, 5, 6];\n    let _ = array.last();\n    //~^ get_last_with_len\n\n    let deq = VecDeque::from([7, 8, 9]);\n    let _ = deq.back();\n    //~^ get_last_with_len\n\n    let nested = [[1]];\n    let _ = nested[0].last();\n    //~^ get_last_with_len\n}\n"
  },
  {
    "path": "tests/ui/get_last_with_len.rs",
    "content": "#![warn(clippy::get_last_with_len)]\n#![allow(unused, clippy::useless_vec)]\n\nuse std::collections::VecDeque;\n\nfn dont_use_last() {\n    let x = vec![2, 3, 5];\n    let _ = x.get(x.len() - 1);\n    //~^ get_last_with_len\n}\n\nfn indexing_two_from_end() {\n    let x = vec![2, 3, 5];\n    let _ = x.get(x.len() - 2);\n}\n\nfn index_into_last() {\n    let x = vec![2, 3, 5];\n    let _ = x[x.len() - 1];\n}\n\nfn use_last_with_different_vec_length() {\n    let x = vec![2, 3, 5];\n    let y = vec!['a', 'b', 'c'];\n    let _ = x.get(y.len() - 1);\n}\n\nstruct S {\n    field: Vec<usize>,\n}\n\nfn in_field(s: &S) {\n    let _ = s.field.get(s.field.len() - 1);\n    //~^ get_last_with_len\n}\n\nfn main() {\n    let slice = &[1, 2, 3];\n    let _ = slice.get(slice.len() - 1);\n    //~^ get_last_with_len\n\n    let array = [4, 5, 6];\n    let _ = array.get(array.len() - 1);\n    //~^ get_last_with_len\n\n    let deq = VecDeque::from([7, 8, 9]);\n    let _ = deq.get(deq.len() - 1);\n    //~^ get_last_with_len\n\n    let nested = [[1]];\n    let _ = nested[0].get(nested[0].len() - 1);\n    //~^ get_last_with_len\n}\n"
  },
  {
    "path": "tests/ui/get_last_with_len.stderr",
    "content": "error: accessing last element with `x.get(x.len() - 1)`\n  --> tests/ui/get_last_with_len.rs:8:13\n   |\nLL |     let _ = x.get(x.len() - 1);\n   |             ^^^^^^^^^^^^^^^^^^ help: try: `x.last()`\n   |\n   = note: `-D clippy::get-last-with-len` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::get_last_with_len)]`\n\nerror: accessing last element with `s.field.get(s.field.len() - 1)`\n  --> tests/ui/get_last_with_len.rs:33:13\n   |\nLL |     let _ = s.field.get(s.field.len() - 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.field.last()`\n\nerror: accessing last element with `slice.get(slice.len() - 1)`\n  --> tests/ui/get_last_with_len.rs:39:13\n   |\nLL |     let _ = slice.get(slice.len() - 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `slice.last()`\n\nerror: accessing last element with `array.get(array.len() - 1)`\n  --> tests/ui/get_last_with_len.rs:43:13\n   |\nLL |     let _ = array.get(array.len() - 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `array.last()`\n\nerror: accessing last element with `deq.get(deq.len() - 1)`\n  --> tests/ui/get_last_with_len.rs:47:13\n   |\nLL |     let _ = deq.get(deq.len() - 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try: `deq.back()`\n\nerror: accessing last element with `nested[0].get(nested[0].len() - 1)`\n  --> tests/ui/get_last_with_len.rs:51:13\n   |\nLL |     let _ = nested[0].get(nested[0].len() - 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `nested[0].last()`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/get_unwrap.fixed",
    "content": "#![allow(\n    unused_mut,\n    clippy::from_iter_instead_of_collect,\n    clippy::get_first,\n    clippy::useless_vec,\n    clippy::out_of_bounds_indexing\n)]\n#![warn(clippy::unwrap_used)]\n#![deny(clippy::get_unwrap)]\n\nuse std::collections::{BTreeMap, HashMap, VecDeque};\n\nstruct GetFalsePositive {\n    arr: [u32; 3],\n}\n\nimpl GetFalsePositive {\n    fn get(&self, pos: usize) -> Option<&u32> {\n        self.arr.get(pos)\n    }\n    fn get_mut(&mut self, pos: usize) -> Option<&mut u32> {\n        self.arr.get_mut(pos)\n    }\n}\n\nfn main() {\n    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let mut some_slice = &mut [0, 1, 2, 3];\n    let mut some_vec = vec![0, 1, 2, 3];\n    let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect();\n    let mut some_hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(1, 'a'), (2, 'b')]);\n    let mut some_btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(1, 'a'), (2, 'b')]);\n    let mut false_positive = GetFalsePositive { arr: [0, 1, 2] };\n\n    {\n        // Test `get().unwrap()`\n        let _ = &boxed_slice[1];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_slice[0];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_vec[0];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_vecdeque[0];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_hashmap[&1];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_btreemap[&1];\n        //~^ get_unwrap\n        //~| unwrap_used\n        #[allow(clippy::unwrap_used)]\n        let _ = false_positive.get(0).unwrap();\n        // Test with deref\n        let _: u8 = boxed_slice[1];\n        //~^ get_unwrap\n        //~| unwrap_used\n    }\n\n    {\n        // Test `get_mut().unwrap()`\n        boxed_slice[0] = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        some_slice[0] = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        some_vec[0] = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        some_vecdeque[0] = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        // Check false positives\n        #[allow(clippy::unwrap_used)]\n        {\n            *some_hashmap.get_mut(&1).unwrap() = 'b';\n            *some_btreemap.get_mut(&1).unwrap() = 'b';\n            *false_positive.get_mut(0).unwrap() = 1;\n        }\n    }\n\n    {\n        // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()`\n        let _ = some_vec[0..1].to_vec();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_vec[0..1].to_vec();\n        //~^ get_unwrap\n        //~| unwrap_used\n    }\n}\nmod issue9909 {\n    #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]\n\n    #[allow(unconditional_panic)]\n    fn reduced() {\n        let f = &[1, 2, 3];\n\n        // include a borrow in the suggestion, even if the argument is not just a numeric literal\n        let _x: &i32 = &f[1 + 2];\n        //~^ get_unwrap\n\n        // don't include a borrow here\n        let _x = f[1 + 2].to_string();\n        //~^ get_unwrap\n\n        // don't include a borrow here\n        let _x = f[1 + 2].abs();\n        //~^ get_unwrap\n    }\n\n    // original code:\n    fn linidx(row: usize, col: usize) -> usize {\n        row * 1 + col * 3\n    }\n\n    fn main_() {\n        let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0];\n\n        for i in 0..2 {\n            for j in i + 1..3 {\n                if mat[linidx(j, 3)] > mat[linidx(i, 3)] {\n                    for k in 0..4 {\n                        let (x, rest) = mat.split_at_mut(linidx(i, k) + 1);\n                        let a = x.last_mut().unwrap();\n                        let b = &mut rest[linidx(j, k) - linidx(i, k) - 1];\n                        //~^ get_unwrap\n                        ::std::mem::swap(a, b);\n                    }\n                }\n            }\n        }\n        assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat);\n    }\n}\n"
  },
  {
    "path": "tests/ui/get_unwrap.rs",
    "content": "#![allow(\n    unused_mut,\n    clippy::from_iter_instead_of_collect,\n    clippy::get_first,\n    clippy::useless_vec,\n    clippy::out_of_bounds_indexing\n)]\n#![warn(clippy::unwrap_used)]\n#![deny(clippy::get_unwrap)]\n\nuse std::collections::{BTreeMap, HashMap, VecDeque};\n\nstruct GetFalsePositive {\n    arr: [u32; 3],\n}\n\nimpl GetFalsePositive {\n    fn get(&self, pos: usize) -> Option<&u32> {\n        self.arr.get(pos)\n    }\n    fn get_mut(&mut self, pos: usize) -> Option<&mut u32> {\n        self.arr.get_mut(pos)\n    }\n}\n\nfn main() {\n    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let mut some_slice = &mut [0, 1, 2, 3];\n    let mut some_vec = vec![0, 1, 2, 3];\n    let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect();\n    let mut some_hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(1, 'a'), (2, 'b')]);\n    let mut some_btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(1, 'a'), (2, 'b')]);\n    let mut false_positive = GetFalsePositive { arr: [0, 1, 2] };\n\n    {\n        // Test `get().unwrap()`\n        let _ = boxed_slice.get(1).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_slice.get(0).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_vec.get(0).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_vecdeque.get(0).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_hashmap.get(&1).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_btreemap.get(&1).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        #[allow(clippy::unwrap_used)]\n        let _ = false_positive.get(0).unwrap();\n        // Test with deref\n        let _: u8 = *boxed_slice.get(1).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n    }\n\n    {\n        // Test `get_mut().unwrap()`\n        *boxed_slice.get_mut(0).unwrap() = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        *some_slice.get_mut(0).unwrap() = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        *some_vec.get_mut(0).unwrap() = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        *some_vecdeque.get_mut(0).unwrap() = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        // Check false positives\n        #[allow(clippy::unwrap_used)]\n        {\n            *some_hashmap.get_mut(&1).unwrap() = 'b';\n            *some_btreemap.get_mut(&1).unwrap() = 'b';\n            *false_positive.get_mut(0).unwrap() = 1;\n        }\n    }\n\n    {\n        // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()`\n        let _ = some_vec.get(0..1).unwrap().to_vec();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_vec.get_mut(0..1).unwrap().to_vec();\n        //~^ get_unwrap\n        //~| unwrap_used\n    }\n}\nmod issue9909 {\n    #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]\n\n    #[allow(unconditional_panic)]\n    fn reduced() {\n        let f = &[1, 2, 3];\n\n        // include a borrow in the suggestion, even if the argument is not just a numeric literal\n        let _x: &i32 = f.get(1 + 2).unwrap();\n        //~^ get_unwrap\n\n        // don't include a borrow here\n        let _x = f.get(1 + 2).unwrap().to_string();\n        //~^ get_unwrap\n\n        // don't include a borrow here\n        let _x = f.get(1 + 2).unwrap().abs();\n        //~^ get_unwrap\n    }\n\n    // original code:\n    fn linidx(row: usize, col: usize) -> usize {\n        row * 1 + col * 3\n    }\n\n    fn main_() {\n        let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0];\n\n        for i in 0..2 {\n            for j in i + 1..3 {\n                if mat[linidx(j, 3)] > mat[linidx(i, 3)] {\n                    for k in 0..4 {\n                        let (x, rest) = mat.split_at_mut(linidx(i, k) + 1);\n                        let a = x.last_mut().unwrap();\n                        let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();\n                        //~^ get_unwrap\n                        ::std::mem::swap(a, b);\n                    }\n                }\n            }\n        }\n        assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat);\n    }\n}\n"
  },
  {
    "path": "tests/ui/get_unwrap.stderr",
    "content": "error: called `.get().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:37:17\n   |\nLL |         let _ = boxed_slice.get(1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/get_unwrap.rs:9:9\n   |\nLL | #![deny(clippy::get_unwrap)]\n   |         ^^^^^^^^^^^^^^^^^^\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = boxed_slice.get(1).unwrap();\nLL +         let _ = &boxed_slice[1];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:37:17\n   |\nLL |         let _ = boxed_slice.get(1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n   = note: `-D clippy::unwrap-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:40:17\n   |\nLL |         let _ = some_slice.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_slice.get(0).unwrap();\nLL +         let _ = &some_slice[0];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:40:17\n   |\nLL |         let _ = some_slice.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a Vec\n  --> tests/ui/get_unwrap.rs:43:17\n   |\nLL |         let _ = some_vec.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_vec.get(0).unwrap();\nLL +         let _ = &some_vec[0];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:43:17\n   |\nLL |         let _ = some_vec.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a VecDeque\n  --> tests/ui/get_unwrap.rs:46:17\n   |\nLL |         let _ = some_vecdeque.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_vecdeque.get(0).unwrap();\nLL +         let _ = &some_vecdeque[0];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:46:17\n   |\nLL |         let _ = some_vecdeque.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a HashMap\n  --> tests/ui/get_unwrap.rs:49:17\n   |\nLL |         let _ = some_hashmap.get(&1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_hashmap.get(&1).unwrap();\nLL +         let _ = &some_hashmap[&1];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:49:17\n   |\nLL |         let _ = some_hashmap.get(&1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a BTreeMap\n  --> tests/ui/get_unwrap.rs:52:17\n   |\nLL |         let _ = some_btreemap.get(&1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_btreemap.get(&1).unwrap();\nLL +         let _ = &some_btreemap[&1];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:52:17\n   |\nLL |         let _ = some_btreemap.get(&1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:58:21\n   |\nLL |         let _: u8 = *boxed_slice.get(1).unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _: u8 = *boxed_slice.get(1).unwrap();\nLL +         let _: u8 = boxed_slice[1];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:58:22\n   |\nLL |         let _: u8 = *boxed_slice.get(1).unwrap();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:65:9\n   |\nLL |         *boxed_slice.get_mut(0).unwrap() = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         *boxed_slice.get_mut(0).unwrap() = 1;\nLL +         boxed_slice[0] = 1;\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:65:10\n   |\nLL |         *boxed_slice.get_mut(0).unwrap() = 1;\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:68:9\n   |\nLL |         *some_slice.get_mut(0).unwrap() = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         *some_slice.get_mut(0).unwrap() = 1;\nLL +         some_slice[0] = 1;\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:68:10\n   |\nLL |         *some_slice.get_mut(0).unwrap() = 1;\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a Vec\n  --> tests/ui/get_unwrap.rs:71:9\n   |\nLL |         *some_vec.get_mut(0).unwrap() = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         *some_vec.get_mut(0).unwrap() = 1;\nLL +         some_vec[0] = 1;\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:71:10\n   |\nLL |         *some_vec.get_mut(0).unwrap() = 1;\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a VecDeque\n  --> tests/ui/get_unwrap.rs:74:9\n   |\nLL |         *some_vecdeque.get_mut(0).unwrap() = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         *some_vecdeque.get_mut(0).unwrap() = 1;\nLL +         some_vecdeque[0] = 1;\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:74:10\n   |\nLL |         *some_vecdeque.get_mut(0).unwrap() = 1;\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a Vec\n  --> tests/ui/get_unwrap.rs:88:17\n   |\nLL |         let _ = some_vec.get(0..1).unwrap().to_vec();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_vec.get(0..1).unwrap().to_vec();\nLL +         let _ = some_vec[0..1].to_vec();\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:88:17\n   |\nLL |         let _ = some_vec.get(0..1).unwrap().to_vec();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a Vec\n  --> tests/ui/get_unwrap.rs:91:17\n   |\nLL |         let _ = some_vec.get_mut(0..1).unwrap().to_vec();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_vec.get_mut(0..1).unwrap().to_vec();\nLL +         let _ = some_vec[0..1].to_vec();\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/get_unwrap.rs:91:17\n   |\nLL |         let _ = some_vec.get_mut(0..1).unwrap().to_vec();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:104:24\n   |\nLL |         let _x: &i32 = f.get(1 + 2).unwrap();\n   |                        ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _x: &i32 = f.get(1 + 2).unwrap();\nLL +         let _x: &i32 = &f[1 + 2];\n   |\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:108:18\n   |\nLL |         let _x = f.get(1 + 2).unwrap().to_string();\n   |                  ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _x = f.get(1 + 2).unwrap().to_string();\nLL +         let _x = f[1 + 2].to_string();\n   |\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:112:18\n   |\nLL |         let _x = f.get(1 + 2).unwrap().abs();\n   |                  ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _x = f.get(1 + 2).unwrap().abs();\nLL +         let _x = f[1 + 2].abs();\n   |\n\nerror: called `.get_mut().unwrap()` on a slice\n  --> tests/ui/get_unwrap.rs:130:33\n   |\nLL |                         let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -                         let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();\nLL +                         let b = &mut rest[linidx(j, k) - linidx(i, k) - 1];\n   |\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/identity_op.fixed",
    "content": "#![warn(clippy::identity_op)]\n#![allow(unused)]\n#![allow(\n    clippy::eq_op,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::op_ref,\n    clippy::double_parens,\n    clippy::uninlined_format_args,\n    clippy::borrow_deref_ref,\n    clippy::deref_addrof\n)]\n\nuse std::fmt::Write as _;\n\nconst ONE: i64 = 1;\nconst NEG_ONE: i64 = -1;\nconst ZERO: i64 = 0;\n\nstruct A(String);\n\nimpl std::ops::Shl<i32> for A {\n    type Output = A;\n    fn shl(mut self, other: i32) -> Self {\n        let _ = write!(self.0, \"{}\", other);\n        self\n    }\n}\n\nstruct Length(u8);\nstruct Meter;\n\nimpl core::ops::Mul<Meter> for u8 {\n    type Output = Length;\n    fn mul(self, _: Meter) -> Length {\n        Length(self)\n    }\n}\n\n#[rustfmt::skip]\nfn main() {\n    let x = 0;\n\n    x;\n    //~^ identity_op\n\n    x;\n    //~^ identity_op\n\n    x + 1;\n    x;\n    //~^ identity_op\n\n    1 + x;\n    x - ZERO; //no error, as we skip lookups (for now)\n    x;\n    //~^ identity_op\n\n    ((ZERO)) | x; //no error, as we skip lookups (for now)\n\n    x;\n    //~^ identity_op\n\n    x;\n    //~^ identity_op\n\n    x / ONE; //no error, as we skip lookups (for now)\n\n    x / 2; //no false positive\n\n    x & NEG_ONE; //no error, as we skip lookups (for now)\n    x;\n    //~^ identity_op\n\n\n    let u: u8 = 0;\n    u;\n    //~^ identity_op\n\n\n    1 << 0; // no error, this case is allowed, see issue 3430\n    42;\n    //~^ identity_op\n\n    1;\n    //~^ identity_op\n\n    42;\n    //~^ identity_op\n\n    x;\n    //~^ identity_op\n\n    x;\n    //~^ identity_op\n\n\n    let mut a = A(String::new());\n    let b = a << 0; // no error: non-integer\n\n    1 * Meter; // no error: non-integer\n\n    2;\n    //~^ identity_op\n\n    -2;\n    //~^ identity_op\n\n    2 + x;\n    //~^ identity_op\n\n    -2 + x;\n    //~^ identity_op\n\n    x + 1;\n    //~^ identity_op\n\n    (x + 1) % 3; // no error\n    4 % 3; // no error\n    4 % -3; // no error\n\n    // See #8724\n    let a = 0;\n    let b = true;\n    (if b { 1 } else { 2 });\n    //~^ identity_op\n\n    (if b { 1 } else { 2 }) + if b { 3 } else { 4 };\n    //~^ identity_op\n\n    (match a { 0 => 10, _ => 20 });\n    //~^ identity_op\n\n    (match a { 0 => 10, _ => 20 }) + match a { 0 => 30, _ => 40 };\n    //~^ identity_op\n\n    (if b { 1 } else { 2 }) + match a { 0 => 30, _ => 40 };\n    //~^ identity_op\n\n    (match a { 0 => 10, _ => 20 }) + if b { 3 } else { 4 };\n    //~^ identity_op\n\n    ((if b { 1 } else { 2 }));\n    //~^ identity_op\n\n\n    ({ a }) + 3;\n    //~^ identity_op\n\n    ({ a } * 2);\n    //~^ identity_op\n\n    (loop { let mut c = 0; if c == 10 { break c; } c += 1; }) + { a * 2 };\n    //~^ identity_op\n\n\n    fn f(_: i32) {\n        todo!();\n    }\n\n    f(a + { 8 * 5 });\n    //~^ identity_op\n\n    f(if b { 1 } else { 2 } + 3);\n    //~^ identity_op\n\n\n    const _: i32 = { 2 * 4 } + 3;\n    //~^ identity_op\n\n    const _: i32 = { 1 + 2 * 3 } + 3;\n    //~^ identity_op\n\n\n    a as usize;\n    //~^ identity_op\n\n    let _ = a as usize;\n    //~^ identity_op\n\n    ({ a } as usize);\n    //~^ identity_op\n\n\n    2 * { a };\n    //~^ identity_op\n\n    (({ a } + 4));\n    //~^ identity_op\n\n    1;\n    //~^ identity_op\n\n\n    // Issue #9904\n    let x = 0i32;\n    let _: i32 = x;\n    //~^ identity_op\n\n}\n\npub fn decide(a: bool, b: bool) -> u32 {\n    (if a { 1 } else { 2 }) + if b { 3 } else { 5 }\n    //~^ identity_op\n}\n\n/// The following tests are from / for issue #12050\n/// In short, the lint didn't work for coerced references,\n/// e.g. let x = &0; let y = x + 0;\n/// because the suggested fix was `let y = x;` but\n/// it should have been `let y = *x;`\nfn issue_12050() {\n    {\n        let x = &0i32;\n        let _: i32 = *x;\n        //~^ identity_op\n\n        let _: i32 = *x;\n        //~^ identity_op\n    }\n    {\n        let x = &&0i32;\n        let _: i32 = **x;\n        //~^ identity_op\n\n        let x = &&0i32;\n        let _: i32 = **x;\n        //~^ identity_op\n    }\n    {\n        // this is just silly\n        let x = &&&0i32;\n        let _: i32 = ***x;\n        //~^ identity_op\n\n        let _: i32 = ***x;\n        //~^ identity_op\n\n        let x = 0i32;\n        let _: i32 = *&x;\n        //~^ identity_op\n\n        let _: i32 = **&&x;\n        //~^ identity_op\n\n        let _: i32 = *&*&x;\n        //~^ identity_op\n\n        let _: i32 = **&&*&x;\n        //~^ identity_op\n    }\n    {\n        // this is getting ridiculous, but we should still see the same\n        // error message so let's just keep going\n        let x = &0i32;\n        let _: i32 = ***&&*&x;\n        //~^ identity_op\n\n        let _: i32 = ***&&*&x;\n        //~^ identity_op\n    }\n}\n\nfn issue_13470() {\n    let x = 1i32;\n    let y = 1i32;\n    // Removes the + 0i32 while keeping the parentheses around x + y so the cast operation works\n    let _: u64 = (x + y) as u64;\n    //~^ identity_op\n\n    // both of the next two lines should look the same after rustfix\n    let _: u64 = 1u64 & (x + y) as u64;\n    //~^ identity_op\n\n    // Same as above, but with extra redundant parenthesis\n    let _: u64 = 1u64 & ((x + y)) as u64;\n    //~^ identity_op\n\n    // Should maintain parenthesis even if the surrounding expr has the same precedence\n    let _: u64 = 5u64 + ((x + y)) as u64;\n    //~^ identity_op\n\n    // If we don't maintain the parens here, the behavior changes\n    let _ = -(x + y);\n    //~^ identity_op\n\n    // Similarly, we need to maintain parens here\n    let _ = -(x / y);\n    //~^ identity_op\n\n    // Maintain parenthesis if the parent expr is of higher precedence\n    let _ = 2i32 * (x + y);\n    //~^ identity_op\n\n    // Maintain parenthesis if the parent expr is the same precedence\n    // as not all operations are associative\n    let _ = 2i32 - (x - y);\n    //~^ identity_op\n\n    // But make sure that inner parens still exist\n    let z = 1i32;\n    let _ = 2 + (x + (y * z));\n    //~^ identity_op\n\n    // Maintain parenthesis if the parent expr is of lower precedence\n    // This is for clarity, and clippy will not warn on these being unnecessary\n    let _ = 2i32 + (x * y);\n    //~^ identity_op\n\n    let x = 1i16;\n    let y = 1i16;\n    let _: u64 = 1u64 + ((x as i32 + y as i32) as u64);\n    //~^ identity_op\n}\n\nfn issue_14932() {\n    let _ = 0usize + &Default::default(); // no error\n\n    0usize + &Default::default(); // no error\n\n    <usize as Default>::default();\n    //~^ identity_op\n\n    let _ = usize::default();\n    //~^ identity_op\n\n    let _n: usize = Default::default();\n    //~^ identity_op\n}\n\n// Expr's type can be inferred by the function's return type\nfn issue_14932_2() -> usize {\n    Default::default()\n    //~^ identity_op\n}\n\ntrait Def {\n    fn def() -> Self;\n}\n\nimpl Def for usize {\n    fn def() -> Self {\n        0\n    }\n}\n\nfn issue_14932_3() {\n    let _ = 0usize + &Def::def(); // no error\n\n    0usize + &Def::def(); // no error\n\n    <usize as Def>::def();\n    //~^ identity_op\n\n    let _ = usize::def();\n    //~^ identity_op\n\n    let _n: usize = Def::def();\n    //~^ identity_op\n}\n"
  },
  {
    "path": "tests/ui/identity_op.rs",
    "content": "#![warn(clippy::identity_op)]\n#![allow(unused)]\n#![allow(\n    clippy::eq_op,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::op_ref,\n    clippy::double_parens,\n    clippy::uninlined_format_args,\n    clippy::borrow_deref_ref,\n    clippy::deref_addrof\n)]\n\nuse std::fmt::Write as _;\n\nconst ONE: i64 = 1;\nconst NEG_ONE: i64 = -1;\nconst ZERO: i64 = 0;\n\nstruct A(String);\n\nimpl std::ops::Shl<i32> for A {\n    type Output = A;\n    fn shl(mut self, other: i32) -> Self {\n        let _ = write!(self.0, \"{}\", other);\n        self\n    }\n}\n\nstruct Length(u8);\nstruct Meter;\n\nimpl core::ops::Mul<Meter> for u8 {\n    type Output = Length;\n    fn mul(self, _: Meter) -> Length {\n        Length(self)\n    }\n}\n\n#[rustfmt::skip]\nfn main() {\n    let x = 0;\n\n    x + 0;\n    //~^ identity_op\n\n    x + (1 - 1);\n    //~^ identity_op\n\n    x + 1;\n    0 + x;\n    //~^ identity_op\n\n    1 + x;\n    x - ZERO; //no error, as we skip lookups (for now)\n    x | (0);\n    //~^ identity_op\n\n    ((ZERO)) | x; //no error, as we skip lookups (for now)\n\n    x * 1;\n    //~^ identity_op\n\n    1 * x;\n    //~^ identity_op\n\n    x / ONE; //no error, as we skip lookups (for now)\n\n    x / 2; //no false positive\n\n    x & NEG_ONE; //no error, as we skip lookups (for now)\n    -1 & x;\n    //~^ identity_op\n\n\n    let u: u8 = 0;\n    u & 255;\n    //~^ identity_op\n\n\n    1 << 0; // no error, this case is allowed, see issue 3430\n    42 << 0;\n    //~^ identity_op\n\n    1 >> 0;\n    //~^ identity_op\n\n    42 >> 0;\n    //~^ identity_op\n\n    &x >> 0;\n    //~^ identity_op\n\n    x >> &0;\n    //~^ identity_op\n\n\n    let mut a = A(String::new());\n    let b = a << 0; // no error: non-integer\n\n    1 * Meter; // no error: non-integer\n\n    2 % 3;\n    //~^ identity_op\n\n    -2 % 3;\n    //~^ identity_op\n\n    2 % -3 + x;\n    //~^ identity_op\n\n    -2 % -3 + x;\n    //~^ identity_op\n\n    x + 1 % 3;\n    //~^ identity_op\n\n    (x + 1) % 3; // no error\n    4 % 3; // no error\n    4 % -3; // no error\n\n    // See #8724\n    let a = 0;\n    let b = true;\n    0 + if b { 1 } else { 2 };\n    //~^ identity_op\n\n    0 + if b { 1 } else { 2 } + if b { 3 } else { 4 };\n    //~^ identity_op\n\n    0 + match a { 0 => 10, _ => 20 };\n    //~^ identity_op\n\n    0 + match a { 0 => 10, _ => 20 } + match a { 0 => 30, _ => 40 };\n    //~^ identity_op\n\n    0 + if b { 1 } else { 2 } + match a { 0 => 30, _ => 40 };\n    //~^ identity_op\n\n    0 + match a { 0 => 10, _ => 20 } + if b { 3 } else { 4 };\n    //~^ identity_op\n\n    (if b { 1 } else { 2 }) + 0;\n    //~^ identity_op\n\n\n    0 + { a } + 3;\n    //~^ identity_op\n\n    0 + { a } * 2;\n    //~^ identity_op\n\n    0 + loop { let mut c = 0; if c == 10 { break c; } c += 1; } + { a * 2 };\n    //~^ identity_op\n\n\n    fn f(_: i32) {\n        todo!();\n    }\n\n    f(1 * a + { 8 * 5 });\n    //~^ identity_op\n\n    f(0 + if b { 1 } else { 2 } + 3);\n    //~^ identity_op\n\n\n    const _: i32 = { 2 * 4 } + 0 + 3;\n    //~^ identity_op\n\n    const _: i32 = 0 + { 1 + 2 * 3 } + 3;\n    //~^ identity_op\n\n\n    0 + a as usize;\n    //~^ identity_op\n\n    let _ = 0 + a as usize;\n    //~^ identity_op\n\n    0 + { a } as usize;\n    //~^ identity_op\n\n\n    2 * (0 + { a });\n    //~^ identity_op\n\n    1 * ({ a } + 4);\n    //~^ identity_op\n\n    1 * 1;\n    //~^ identity_op\n\n\n    // Issue #9904\n    let x = 0i32;\n    let _: i32 = &x + 0;\n    //~^ identity_op\n\n}\n\npub fn decide(a: bool, b: bool) -> u32 {\n    0 + if a { 1 } else { 2 } + if b { 3 } else { 5 }\n    //~^ identity_op\n}\n\n/// The following tests are from / for issue #12050\n/// In short, the lint didn't work for coerced references,\n/// e.g. let x = &0; let y = x + 0;\n/// because the suggested fix was `let y = x;` but\n/// it should have been `let y = *x;`\nfn issue_12050() {\n    {\n        let x = &0i32;\n        let _: i32 = *x + 0;\n        //~^ identity_op\n\n        let _: i32 = x + 0;\n        //~^ identity_op\n    }\n    {\n        let x = &&0i32;\n        let _: i32 = **x + 0;\n        //~^ identity_op\n\n        let x = &&0i32;\n        let _: i32 = *x + 0;\n        //~^ identity_op\n    }\n    {\n        // this is just silly\n        let x = &&&0i32;\n        let _: i32 = ***x + 0;\n        //~^ identity_op\n\n        let _: i32 = **x + 0;\n        //~^ identity_op\n\n        let x = 0i32;\n        let _: i32 = *&x + 0;\n        //~^ identity_op\n\n        let _: i32 = **&&x + 0;\n        //~^ identity_op\n\n        let _: i32 = *&*&x + 0;\n        //~^ identity_op\n\n        let _: i32 = **&&*&x + 0;\n        //~^ identity_op\n    }\n    {\n        // this is getting ridiculous, but we should still see the same\n        // error message so let's just keep going\n        let x = &0i32;\n        let _: i32 = **&&*&x + 0;\n        //~^ identity_op\n\n        let _: i32 = **&&*&x + 0;\n        //~^ identity_op\n    }\n}\n\nfn issue_13470() {\n    let x = 1i32;\n    let y = 1i32;\n    // Removes the + 0i32 while keeping the parentheses around x + y so the cast operation works\n    let _: u64 = (x + y + 0i32) as u64;\n    //~^ identity_op\n\n    // both of the next two lines should look the same after rustfix\n    let _: u64 = 1u64 & (x + y + 0i32) as u64;\n    //~^ identity_op\n\n    // Same as above, but with extra redundant parenthesis\n    let _: u64 = 1u64 & ((x + y) + 0i32) as u64;\n    //~^ identity_op\n\n    // Should maintain parenthesis even if the surrounding expr has the same precedence\n    let _: u64 = 5u64 + ((x + y) + 0i32) as u64;\n    //~^ identity_op\n\n    // If we don't maintain the parens here, the behavior changes\n    let _ = -(x + y + 0i32);\n    //~^ identity_op\n\n    // Similarly, we need to maintain parens here\n    let _ = -(x / y / 1i32);\n    //~^ identity_op\n\n    // Maintain parenthesis if the parent expr is of higher precedence\n    let _ = 2i32 * (x + y + 0i32);\n    //~^ identity_op\n\n    // Maintain parenthesis if the parent expr is the same precedence\n    // as not all operations are associative\n    let _ = 2i32 - (x - y - 0i32);\n    //~^ identity_op\n\n    // But make sure that inner parens still exist\n    let z = 1i32;\n    let _ = 2 + (x + (y * z) + 0);\n    //~^ identity_op\n\n    // Maintain parenthesis if the parent expr is of lower precedence\n    // This is for clarity, and clippy will not warn on these being unnecessary\n    let _ = 2i32 + (x * y * 1i32);\n    //~^ identity_op\n\n    let x = 1i16;\n    let y = 1i16;\n    let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64);\n    //~^ identity_op\n}\n\nfn issue_14932() {\n    let _ = 0usize + &Default::default(); // no error\n\n    0usize + &Default::default(); // no error\n\n    0usize + &<usize as Default>::default();\n    //~^ identity_op\n\n    let _ = 0usize + &usize::default();\n    //~^ identity_op\n\n    let _n: usize = 0usize + &Default::default();\n    //~^ identity_op\n}\n\n// Expr's type can be inferred by the function's return type\nfn issue_14932_2() -> usize {\n    0usize + &Default::default()\n    //~^ identity_op\n}\n\ntrait Def {\n    fn def() -> Self;\n}\n\nimpl Def for usize {\n    fn def() -> Self {\n        0\n    }\n}\n\nfn issue_14932_3() {\n    let _ = 0usize + &Def::def(); // no error\n\n    0usize + &Def::def(); // no error\n\n    0usize + &<usize as Def>::def();\n    //~^ identity_op\n\n    let _ = 0usize + &usize::def();\n    //~^ identity_op\n\n    let _n: usize = 0usize + &Def::def();\n    //~^ identity_op\n}\n"
  },
  {
    "path": "tests/ui/identity_op.stderr",
    "content": "error: this operation has no effect\n  --> tests/ui/identity_op.rs:44:5\n   |\nLL |     x + 0;\n   |     ^^^^^ help: consider reducing it to: `x`\n   |\n   = note: `-D clippy::identity-op` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::identity_op)]`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:47:5\n   |\nLL |     x + (1 - 1);\n   |     ^^^^^^^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:51:5\n   |\nLL |     0 + x;\n   |     ^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:56:5\n   |\nLL |     x | (0);\n   |     ^^^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:61:5\n   |\nLL |     x * 1;\n   |     ^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:64:5\n   |\nLL |     1 * x;\n   |     ^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:72:5\n   |\nLL |     -1 & x;\n   |     ^^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:77:5\n   |\nLL |     u & 255;\n   |     ^^^^^^^ help: consider reducing it to: `u`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:82:5\n   |\nLL |     42 << 0;\n   |     ^^^^^^^ help: consider reducing it to: `42`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:85:5\n   |\nLL |     1 >> 0;\n   |     ^^^^^^ help: consider reducing it to: `1`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:88:5\n   |\nLL |     42 >> 0;\n   |     ^^^^^^^ help: consider reducing it to: `42`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:91:5\n   |\nLL |     &x >> 0;\n   |     ^^^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:94:5\n   |\nLL |     x >> &0;\n   |     ^^^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:103:5\n   |\nLL |     2 % 3;\n   |     ^^^^^ help: consider reducing it to: `2`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:106:5\n   |\nLL |     -2 % 3;\n   |     ^^^^^^ help: consider reducing it to: `-2`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:109:5\n   |\nLL |     2 % -3 + x;\n   |     ^^^^^^ help: consider reducing it to: `2`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:112:5\n   |\nLL |     -2 % -3 + x;\n   |     ^^^^^^^ help: consider reducing it to: `-2`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:115:9\n   |\nLL |     x + 1 % 3;\n   |         ^^^^^ help: consider reducing it to: `1`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:125:5\n   |\nLL |     0 + if b { 1 } else { 2 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:128:5\n   |\nLL |     0 + if b { 1 } else { 2 } + if b { 3 } else { 4 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:131:5\n   |\nLL |     0 + match a { 0 => 10, _ => 20 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:134:5\n   |\nLL |     0 + match a { 0 => 10, _ => 20 } + match a { 0 => 30, _ => 40 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:137:5\n   |\nLL |     0 + if b { 1 } else { 2 } + match a { 0 => 30, _ => 40 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if b { 1 } else { 2 })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:140:5\n   |\nLL |     0 + match a { 0 => 10, _ => 20 } + if b { 3 } else { 4 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(match a { 0 => 10, _ => 20 })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:143:5\n   |\nLL |     (if b { 1 } else { 2 }) + 0;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `((if b { 1 } else { 2 }))`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:147:5\n   |\nLL |     0 + { a } + 3;\n   |     ^^^^^^^^^ help: consider reducing it to: `({ a })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:150:5\n   |\nLL |     0 + { a } * 2;\n   |     ^^^^^^^^^^^^^ help: consider reducing it to: `({ a } * 2)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:153:5\n   |\nLL |     0 + loop { let mut c = 0; if c == 10 { break c; } c += 1; } + { a * 2 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(loop { let mut c = 0; if c == 10 { break c; } c += 1; })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:161:7\n   |\nLL |     f(1 * a + { 8 * 5 });\n   |       ^^^^^ help: consider reducing it to: `a`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:164:7\n   |\nLL |     f(0 + if b { 1 } else { 2 } + 3);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `if b { 1 } else { 2 }`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:168:20\n   |\nLL |     const _: i32 = { 2 * 4 } + 0 + 3;\n   |                    ^^^^^^^^^^^^^ help: consider reducing it to: `{ 2 * 4 }`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:171:20\n   |\nLL |     const _: i32 = 0 + { 1 + 2 * 3 } + 3;\n   |                    ^^^^^^^^^^^^^^^^^ help: consider reducing it to: `{ 1 + 2 * 3 }`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:175:5\n   |\nLL |     0 + a as usize;\n   |     ^^^^^^^^^^^^^^ help: consider reducing it to: `a as usize`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:178:13\n   |\nLL |     let _ = 0 + a as usize;\n   |             ^^^^^^^^^^^^^^ help: consider reducing it to: `a as usize`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:181:5\n   |\nLL |     0 + { a } as usize;\n   |     ^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `({ a } as usize)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:185:9\n   |\nLL |     2 * (0 + { a });\n   |         ^^^^^^^^^^^ help: consider reducing it to: `{ a }`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:188:5\n   |\nLL |     1 * ({ a } + 4);\n   |     ^^^^^^^^^^^^^^^ help: consider reducing it to: `(({ a } + 4))`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:191:5\n   |\nLL |     1 * 1;\n   |     ^^^^^ help: consider reducing it to: `1`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:197:18\n   |\nLL |     let _: i32 = &x + 0;\n   |                  ^^^^^^ help: consider reducing it to: `x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:203:5\n   |\nLL |     0 + if a { 1 } else { 2 } + if b { 3 } else { 5 }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(if a { 1 } else { 2 })`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:215:22\n   |\nLL |         let _: i32 = *x + 0;\n   |                      ^^^^^^ help: consider reducing it to: `*x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:218:22\n   |\nLL |         let _: i32 = x + 0;\n   |                      ^^^^^ help: consider reducing it to: `*x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:223:22\n   |\nLL |         let _: i32 = **x + 0;\n   |                      ^^^^^^^ help: consider reducing it to: `**x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:227:22\n   |\nLL |         let _: i32 = *x + 0;\n   |                      ^^^^^^ help: consider reducing it to: `**x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:233:22\n   |\nLL |         let _: i32 = ***x + 0;\n   |                      ^^^^^^^^ help: consider reducing it to: `***x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:236:22\n   |\nLL |         let _: i32 = **x + 0;\n   |                      ^^^^^^^ help: consider reducing it to: `***x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:240:22\n   |\nLL |         let _: i32 = *&x + 0;\n   |                      ^^^^^^^ help: consider reducing it to: `*&x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:243:22\n   |\nLL |         let _: i32 = **&&x + 0;\n   |                      ^^^^^^^^^ help: consider reducing it to: `**&&x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:246:22\n   |\nLL |         let _: i32 = *&*&x + 0;\n   |                      ^^^^^^^^^ help: consider reducing it to: `*&*&x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:249:22\n   |\nLL |         let _: i32 = **&&*&x + 0;\n   |                      ^^^^^^^^^^^ help: consider reducing it to: `**&&*&x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:256:22\n   |\nLL |         let _: i32 = **&&*&x + 0;\n   |                      ^^^^^^^^^^^ help: consider reducing it to: `***&&*&x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:259:22\n   |\nLL |         let _: i32 = **&&*&x + 0;\n   |                      ^^^^^^^^^^^ help: consider reducing it to: `***&&*&x`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:268:18\n   |\nLL |     let _: u64 = (x + y + 0i32) as u64;\n   |                  ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:272:25\n   |\nLL |     let _: u64 = 1u64 & (x + y + 0i32) as u64;\n   |                         ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:276:25\n   |\nLL |     let _: u64 = 1u64 & ((x + y) + 0i32) as u64;\n   |                         ^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x + y))`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:280:25\n   |\nLL |     let _: u64 = 5u64 + ((x + y) + 0i32) as u64;\n   |                         ^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x + y))`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:284:14\n   |\nLL |     let _ = -(x + y + 0i32);\n   |              ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:288:14\n   |\nLL |     let _ = -(x / y / 1i32);\n   |              ^^^^^^^^^^^^^^ help: consider reducing it to: `(x / y)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:292:20\n   |\nLL |     let _ = 2i32 * (x + y + 0i32);\n   |                    ^^^^^^^^^^^^^^ help: consider reducing it to: `(x + y)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:297:20\n   |\nLL |     let _ = 2i32 - (x - y - 0i32);\n   |                    ^^^^^^^^^^^^^^ help: consider reducing it to: `(x - y)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:302:17\n   |\nLL |     let _ = 2 + (x + (y * z) + 0);\n   |                 ^^^^^^^^^^^^^^^^^ help: consider reducing it to: `(x + (y * z))`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:307:20\n   |\nLL |     let _ = 2i32 + (x * y * 1i32);\n   |                    ^^^^^^^^^^^^^^ help: consider reducing it to: `(x * y)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:312:25\n   |\nLL |     let _: u64 = 1u64 + ((x as i32 + y as i32) as u64 + 0u64);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `((x as i32 + y as i32) as u64)`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:321:5\n   |\nLL |     0usize + &<usize as Default>::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `<usize as Default>::default()`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:324:13\n   |\nLL |     let _ = 0usize + &usize::default();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `usize::default()`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:327:21\n   |\nLL |     let _n: usize = 0usize + &Default::default();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `Default::default()`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:333:5\n   |\nLL |     0usize + &Default::default()\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `Default::default()`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:352:5\n   |\nLL |     0usize + &<usize as Def>::def();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `<usize as Def>::def()`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:355:13\n   |\nLL |     let _ = 0usize + &usize::def();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `usize::def()`\n\nerror: this operation has no effect\n  --> tests/ui/identity_op.rs:358:21\n   |\nLL |     let _n: usize = 0usize + &Def::def();\n   |                     ^^^^^^^^^^^^^^^^^^^^ help: consider reducing it to: `Def::def()`\n\nerror: aborting due to 70 previous errors\n\n"
  },
  {
    "path": "tests/ui/if_let_mutex.edition2021.stderr",
    "content": "error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock\n  --> tests/ui/if_let_mutex.rs:17:5\n   |\nLL |       if let Err(locked) = m.lock() {\n   |       ^                    - this Mutex will remain locked for the entire `if let`-block...\n   |  _____|\n   | |\nLL | |\nLL | |         do_stuff(locked);\nLL | |     } else {\nLL | |         let lock = m.lock().unwrap();\n   | |                    - ... and is tried to lock again here, which will always deadlock.\nLL | |         do_stuff(lock);\nLL | |     };\n   | |_____^\n   |\n   = help: move the lock call outside of the `if let ...` expression\n   = note: `-D clippy::if-let-mutex` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::if_let_mutex)]`\n\nerror: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock\n  --> tests/ui/if_let_mutex.rs:30:5\n   |\nLL |       if let Some(locked) = m.lock().unwrap().deref() {\n   |       ^                     - this Mutex will remain locked for the entire `if let`-block...\n   |  _____|\n   | |\nLL | |\nLL | |         do_stuff(locked);\nLL | |     } else {\nLL | |         let lock = m.lock().unwrap();\n   | |                    - ... and is tried to lock again here, which will always deadlock.\nLL | |         do_stuff(lock);\nLL | |     };\n   | |_____^\n   |\n   = help: move the lock call outside of the `if let ...` expression\n\nerror: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock\n  --> tests/ui/if_let_mutex.rs:52:5\n   |\nLL |       if let Ok(i) = mutex.lock() {\n   |       ^              ----- this Mutex will remain locked for the entire `if let`-block...\n   |  _____|\n   | |\nLL | |\nLL | |         do_stuff(i);\nLL | |     } else {\nLL | |         let _x = mutex.lock();\n   | |                  ----- ... and is tried to lock again here, which will always deadlock.\nLL | |     };\n   | |_____^\n   |\n   = help: move the lock call outside of the `if let ...` expression\n\nerror: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock\n  --> tests/ui/if_let_mutex.rs:61:5\n   |\nLL |       if let Ok(_) = m1.lock() {\n   |       ^              -- this Mutex will remain locked for the entire `if let`-block...\n   |  _____|\n   | |\nLL | |         m2.lock();\nLL | |     } else {\nLL | |         m1.lock();\n   | |         -- ... and is tried to lock again here, which will always deadlock.\nLL | |     }\n   | |_____^\n   |\n   = help: move the lock call outside of the `if let ...` expression\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/if_let_mutex.rs",
    "content": "//@ compile-flags: -Zunstable-options\n\n//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n//@[edition2024] check-pass\n#![warn(clippy::if_let_mutex)]\n#![allow(clippy::redundant_pattern_matching)]\n\nuse std::ops::Deref;\nuse std::sync::Mutex;\n\nfn do_stuff<T>(_: T) {}\n\nfn if_let() {\n    let m = Mutex::new(1_u8);\n    if let Err(locked) = m.lock() {\n        //~[edition2021]^ if_let_mutex\n        do_stuff(locked);\n    } else {\n        let lock = m.lock().unwrap();\n        do_stuff(lock);\n    };\n}\n\n// This is the most common case as the above case is pretty\n// contrived.\nfn if_let_option() {\n    let m = Mutex::new(Some(0_u8));\n    if let Some(locked) = m.lock().unwrap().deref() {\n        //~[edition2021]^ if_let_mutex\n        do_stuff(locked);\n    } else {\n        let lock = m.lock().unwrap();\n        do_stuff(lock);\n    };\n}\n\n// When mutexes are different don't warn\nfn if_let_different_mutex() {\n    let m = Mutex::new(Some(0_u8));\n    let other = Mutex::new(None::<u8>);\n    if let Some(locked) = m.lock().unwrap().deref() {\n        do_stuff(locked);\n    } else {\n        let lock = other.lock().unwrap();\n        do_stuff(lock);\n    };\n}\n\nfn mutex_ref(mutex: &Mutex<i32>) {\n    if let Ok(i) = mutex.lock() {\n        //~[edition2021]^ if_let_mutex\n        do_stuff(i);\n    } else {\n        let _x = mutex.lock();\n    };\n}\n\nfn multiple_mutexes(m1: &Mutex<()>, m2: &Mutex<()>) {\n    if let Ok(_) = m1.lock() {\n        m2.lock();\n    } else {\n        m1.lock();\n    }\n    //~[edition2021]^^^^^ if_let_mutex\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/if_not_else.fixed",
    "content": "#![warn(clippy::if_not_else)]\n\nfn foo() -> bool {\n    unimplemented!()\n}\nfn bla() -> bool {\n    unimplemented!()\n}\n\nfn main() {\n    if bla() {\n        println!(\"Bunny\");\n    } else {\n        //~^ if_not_else\n\n        println!(\"Bugs\");\n    }\n    if 4 == 5 {\n        println!(\"Bunny\");\n    } else {\n        //~^ if_not_else\n\n        println!(\"Bugs\");\n    }\n    if !foo() {\n        println!(\"Foo\");\n    } else if !bla() {\n        println!(\"Bugs\");\n    } else {\n        println!(\"Bunny\");\n    }\n\n    if (foo() && bla()) {\n        println!(\"both true\");\n    } else {\n        //~^ if_not_else\n        #[cfg(not(debug_assertions))]\n        println!(\"not debug\");\n        #[cfg(debug_assertions)]\n        println!(\"debug\");\n        if foo() {\n            println!(\"foo\");\n        } else if bla() {\n            println!(\"bla\");\n        } else {\n            println!(\"both false\");\n        }\n    }\n}\n\nfn with_comments() {\n    if foo() {\n        println!(\"foo\"); /* foo */\n    } else {\n        //~^ if_not_else\n        /* foo is false */\n        println!(\"foo is false\");\n    }\n\n    if bla() {\n        println!(\"bla\"); // bla\n    } else {\n        //~^ if_not_else\n        // bla is false\n        println!(\"bla\");\n    }\n}\n\nfn with_annotations() {\n    #[cfg(debug_assertions)]\n    if foo() {\n        println!(\"foo\"); /* foo */\n    } else {\n        //~^ if_not_else\n        /* foo is false */\n        println!(\"foo is false\");\n    }\n}\n\nfn issue15924() {\n    let x = 0;\n    if matches!(x, 0..10) {\n        println!(\":(\");\n    } else {\n        //~^ if_not_else\n        println!(\":)\");\n    }\n\n    if dbg!(x) == 1 {\n        println!(\":(\");\n    } else {\n        //~^ if_not_else\n        println!(\":)\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/if_not_else.rs",
    "content": "#![warn(clippy::if_not_else)]\n\nfn foo() -> bool {\n    unimplemented!()\n}\nfn bla() -> bool {\n    unimplemented!()\n}\n\nfn main() {\n    if !bla() {\n        //~^ if_not_else\n\n        println!(\"Bugs\");\n    } else {\n        println!(\"Bunny\");\n    }\n    if 4 != 5 {\n        //~^ if_not_else\n\n        println!(\"Bugs\");\n    } else {\n        println!(\"Bunny\");\n    }\n    if !foo() {\n        println!(\"Foo\");\n    } else if !bla() {\n        println!(\"Bugs\");\n    } else {\n        println!(\"Bunny\");\n    }\n\n    if !(foo() && bla()) {\n        //~^ if_not_else\n        #[cfg(not(debug_assertions))]\n        println!(\"not debug\");\n        #[cfg(debug_assertions)]\n        println!(\"debug\");\n        if foo() {\n            println!(\"foo\");\n        } else if bla() {\n            println!(\"bla\");\n        } else {\n            println!(\"both false\");\n        }\n    } else {\n        println!(\"both true\");\n    }\n}\n\nfn with_comments() {\n    if !foo() {\n        //~^ if_not_else\n        /* foo is false */\n        println!(\"foo is false\");\n    } else {\n        println!(\"foo\"); /* foo */\n    }\n\n    if !bla() {\n        //~^ if_not_else\n        // bla is false\n        println!(\"bla\");\n    } else {\n        println!(\"bla\"); // bla\n    }\n}\n\nfn with_annotations() {\n    #[cfg(debug_assertions)]\n    if !foo() {\n        //~^ if_not_else\n        /* foo is false */\n        println!(\"foo is false\");\n    } else {\n        println!(\"foo\"); /* foo */\n    }\n}\n\nfn issue15924() {\n    let x = 0;\n    if !matches!(x, 0..10) {\n        //~^ if_not_else\n        println!(\":)\");\n    } else {\n        println!(\":(\");\n    }\n\n    if dbg!(x) != 1 {\n        //~^ if_not_else\n        println!(\":)\");\n    } else {\n        println!(\":(\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/if_not_else.stderr",
    "content": "error: unnecessary boolean `not` operation\n  --> tests/ui/if_not_else.rs:11:5\n   |\nLL | /     if !bla() {\nLL | |\nLL | |\nLL | |         println!(\"Bugs\");\nLL | |     } else {\nLL | |         println!(\"Bunny\");\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::if-not-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::if_not_else)]`\nhelp: try\n   |\nLL ~     if bla() {\nLL +         println!(\"Bunny\");\nLL +     } else {\nLL +\nLL + \nLL +         println!(\"Bugs\");\nLL +     }\n   |\n\nerror: unnecessary `!=` operation\n  --> tests/ui/if_not_else.rs:18:5\n   |\nLL | /     if 4 != 5 {\nLL | |\nLL | |\nLL | |         println!(\"Bugs\");\nLL | |     } else {\nLL | |         println!(\"Bunny\");\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if 4 == 5 {\nLL +         println!(\"Bunny\");\nLL +     } else {\nLL +\nLL + \nLL +         println!(\"Bugs\");\nLL +     }\n   |\n\nerror: unnecessary boolean `not` operation\n  --> tests/ui/if_not_else.rs:33:5\n   |\nLL | /     if !(foo() && bla()) {\nLL | |\nLL | |         #[cfg(not(debug_assertions))]\nLL | |         println!(\"not debug\");\n...  |\nLL | |         println!(\"both true\");\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if (foo() && bla()) {\nLL +         println!(\"both true\");\nLL +     } else {\nLL +\nLL +         #[cfg(not(debug_assertions))]\nLL +         println!(\"not debug\");\nLL +         #[cfg(debug_assertions)]\nLL +         println!(\"debug\");\nLL +         if foo() {\nLL +             println!(\"foo\");\nLL +         } else if bla() {\nLL +             println!(\"bla\");\nLL +         } else {\nLL +             println!(\"both false\");\nLL +         }\nLL +     }\n   |\n\nerror: unnecessary boolean `not` operation\n  --> tests/ui/if_not_else.rs:52:5\n   |\nLL | /     if !foo() {\nLL | |\nLL | |         /* foo is false */\nLL | |         println!(\"foo is false\");\nLL | |     } else {\nLL | |         println!(\"foo\"); /* foo */\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if foo() {\nLL +         println!(\"foo\"); /* foo */\nLL +     } else {\nLL +\nLL +         /* foo is false */\nLL +         println!(\"foo is false\");\nLL +     }\n   |\n\nerror: unnecessary boolean `not` operation\n  --> tests/ui/if_not_else.rs:60:5\n   |\nLL | /     if !bla() {\nLL | |\nLL | |         // bla is false\nLL | |         println!(\"bla\");\nLL | |     } else {\nLL | |         println!(\"bla\"); // bla\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if bla() {\nLL +         println!(\"bla\"); // bla\nLL +     } else {\nLL +\nLL +         // bla is false\nLL +         println!(\"bla\");\nLL +     }\n   |\n\nerror: unnecessary boolean `not` operation\n  --> tests/ui/if_not_else.rs:71:5\n   |\nLL | /     if !foo() {\nLL | |\nLL | |         /* foo is false */\nLL | |         println!(\"foo is false\");\nLL | |     } else {\nLL | |         println!(\"foo\"); /* foo */\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if foo() {\nLL +         println!(\"foo\"); /* foo */\nLL +     } else {\nLL +\nLL +         /* foo is false */\nLL +         println!(\"foo is false\");\nLL +     }\n   |\n\nerror: unnecessary boolean `not` operation\n  --> tests/ui/if_not_else.rs:82:5\n   |\nLL | /     if !matches!(x, 0..10) {\nLL | |\nLL | |         println!(\":)\");\nLL | |     } else {\nLL | |         println!(\":(\");\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if matches!(x, 0..10) {\nLL +         println!(\":(\");\nLL +     } else {\nLL +\nLL +         println!(\":)\");\nLL +     }\n   |\n\nerror: unnecessary `!=` operation\n  --> tests/ui/if_not_else.rs:89:5\n   |\nLL | /     if dbg!(x) != 1 {\nLL | |\nLL | |         println!(\":)\");\nLL | |     } else {\nLL | |         println!(\":(\");\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if dbg!(x) == 1 {\nLL +         println!(\":(\");\nLL +     } else {\nLL +\nLL +         println!(\":)\");\nLL +     }\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/if_not_else_bittest.rs",
    "content": "//@ check-pass\n\n#![deny(clippy::if_not_else)]\n\nfn show_permissions(flags: u32) {\n    if flags & 0x0F00 != 0 {\n        println!(\"Has the 0x0F00 permission.\");\n    } else {\n        println!(\"The 0x0F00 permission is missing.\");\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/if_same_then_else.rs",
    "content": "#![warn(clippy::if_same_then_else)]\n#![allow(\n    clippy::disallowed_names,\n    clippy::eq_op,\n    clippy::never_loop,\n    clippy::no_effect,\n    clippy::unused_unit,\n    clippy::zero_divided_by_zero,\n    clippy::branches_sharing_code,\n    dead_code,\n    unreachable_code\n)]\n\nuse std::ops::*;\n\nstruct Foo {\n    bar: u8,\n}\n\nfn foo() -> bool {\n    unimplemented!()\n}\n\nfn if_same_then_else() {\n    if true {\n        Foo { bar: 42 };\n        0..10;\n        ..;\n        0..;\n        ..10;\n        0..=10;\n        foo();\n    } else {\n        Foo { bar: 42 };\n        0..10;\n        ..;\n        0..;\n        ..10;\n        0..=10;\n        foo();\n    }\n    //~^^^^^^^^^^^^^^^^^ if_same_then_else\n\n    if true {\n        Foo { bar: 42 };\n    } else {\n        Foo { bar: 43 };\n    }\n\n    if true {\n        ();\n    } else {\n        ()\n    }\n\n    if true {\n        0..10;\n    } else {\n        0..=10;\n    }\n\n    if true {\n        foo();\n        foo();\n    } else {\n        foo();\n    }\n\n    let _ = if true { 0.0 } else { 0.0 };\n    //~^ if_same_then_else\n\n    let _ = if true { -0.0 } else { -0.0 };\n    //~^ if_same_then_else\n\n    let _ = if true { 0.0 } else { -0.0 };\n\n    // Different NaNs\n    let _ = if true { 0.0 / 0.0 } else { f32::NAN };\n\n    if true {\n        foo();\n    }\n\n    let _ = if true { 42 } else { 42 };\n    //~^ if_same_then_else\n\n    if true {\n        let bar = if true { 42 } else { 43 };\n\n        while foo() {\n            break;\n        }\n        bar + 1;\n    } else {\n        let bar = if true { 42 } else { 43 };\n\n        while foo() {\n            break;\n        }\n        bar + 1;\n    }\n    //~^^^^^^^^^^^^^^^ if_same_then_else\n\n    if true {\n        let _ = match 42 {\n            42 => 1,\n            a if a > 0 => 2,\n            10..=15 => 3,\n            _ => 4,\n        };\n    } else if false {\n        foo();\n    } else if foo() {\n        let _ = match 42 {\n            42 => 1,\n            a if a > 0 => 2,\n            10..=15 => 3,\n            _ => 4,\n        };\n    }\n}\n\n// Issue #2423. This was causing an ICE.\nfn func() {\n    if true {\n        f(&[0; 62]);\n        f(&[0; 4]);\n        f(&[0; 3]);\n    } else {\n        f(&[0; 62]);\n        f(&[0; 6]);\n        f(&[0; 6]);\n    }\n}\n\nfn f(val: &[u8]) {}\n\nmod issue_8836 {\n    fn do_not_lint() {\n        if true {\n            todo!()\n        } else {\n            todo!()\n        }\n        if true {\n            todo!();\n        } else {\n            todo!();\n        }\n        if true {\n            unimplemented!()\n        } else {\n            unimplemented!()\n        }\n        if true {\n            unimplemented!();\n        } else {\n            unimplemented!();\n        }\n\n        if true {\n            println!(\"FOO\");\n            todo!();\n        } else {\n            println!(\"FOO\");\n            todo!();\n        }\n\n        if true {\n            println!(\"FOO\");\n            unimplemented!();\n        } else {\n            println!(\"FOO\");\n            unimplemented!();\n        }\n\n        if true {\n            println!(\"FOO\");\n            todo!()\n        } else {\n            println!(\"FOO\");\n            todo!()\n        }\n\n        if true {\n            println!(\"FOO\");\n            unimplemented!()\n        } else {\n            println!(\"FOO\");\n            unimplemented!()\n        }\n    }\n}\n\nmod issue_11213 {\n    fn reproducer(x: bool) -> bool {\n        if x {\n            0_u8.is_power_of_two()\n        } else {\n            0_u16.is_power_of_two()\n        }\n    }\n\n    // a more obvious reproducer that shows\n    // why the code above is problematic:\n    fn v2(x: bool) -> bool {\n        trait Helper {\n            fn is_u8(&self) -> bool;\n        }\n        impl Helper for u8 {\n            fn is_u8(&self) -> bool {\n                true\n            }\n        }\n        impl Helper for u16 {\n            fn is_u8(&self) -> bool {\n                false\n            }\n        }\n\n        // this is certainly not the same code in both branches\n        // it returns a different bool depending on the branch.\n        if x { 0_u8.is_u8() } else { 0_u16.is_u8() }\n    }\n\n    fn do_lint(x: bool) -> bool {\n        // but do lint if the type of the literal is the same\n        if x {\n            0_u8.is_power_of_two()\n        } else {\n            0_u8.is_power_of_two()\n        }\n        //~^^^^^ if_same_then_else\n    }\n}\n\nfn main() {}\n\nfn issue16416<T>(x: bool, a: T, b: T)\nwhere\n    T: Add + Sub + Mul + Div + Rem + BitAnd + BitOr + BitXor + PartialEq + Eq + PartialOrd + Ord + Shr + Shl + Copy,\n{\n    // Non-guaranteed-commutative operators\n    _ = if x { a * b } else { b * a };\n    _ = if x { a + b } else { b + a };\n    _ = if x { a - b } else { b - a };\n    _ = if x { a / b } else { b / a };\n    _ = if x { a % b } else { b % a };\n    _ = if x { a << b } else { b << a };\n    _ = if x { a >> b } else { b >> a };\n    _ = if x { a & b } else { b & a };\n    _ = if x { a ^ b } else { b ^ a };\n    _ = if x { a | b } else { b | a };\n\n    // Guaranteed commutative operators\n    //~v if_same_then_else\n    _ = if x { a == b } else { b == a };\n    //~v if_same_then_else\n    _ = if x { a != b } else { b != a };\n\n    // Symetric operators\n    //~v if_same_then_else\n    _ = if x { a < b } else { b > a };\n    //~v if_same_then_else\n    _ = if x { a <= b } else { b >= a };\n    //~v if_same_then_else\n    _ = if x { a > b } else { b < a };\n    //~v if_same_then_else\n    _ = if x { a >= b } else { b <= a };\n}\n\nfn issue16416_prim(x: bool, a: u32, b: u32) {\n    // Non-commutative operators\n    _ = if x { a - b } else { b - a };\n    _ = if x { a / b } else { b / a };\n    _ = if x { a % b } else { b % a };\n    _ = if x { a << b } else { b << a };\n    _ = if x { a >> b } else { b >> a };\n\n    // Commutative operators on primitive types\n    //~v if_same_then_else\n    _ = if x { a * b } else { b * a };\n    //~v if_same_then_else\n    _ = if x { a + b } else { b + a };\n    //~v if_same_then_else\n    _ = if x { a & b } else { b & a };\n    //~v if_same_then_else\n    _ = if x { a ^ b } else { b ^ a };\n    //~v if_same_then_else\n    _ = if x { a | b } else { b | a };\n\n    // Always commutative operators\n    //~v if_same_then_else\n    _ = if x { a == b } else { b == a };\n    //~v if_same_then_else\n    _ = if x { a != b } else { b != a };\n\n    // Symetric operators\n    //~v if_same_then_else\n    _ = if x { a < b } else { b > a };\n    //~v if_same_then_else\n    _ = if x { a <= b } else { b >= a };\n    //~v if_same_then_else\n    _ = if x { a > b } else { b < a };\n    //~v if_same_then_else\n    _ = if x { a >= b } else { b <= a };\n}\n\nmod issue16505 {\n    macro_rules! foo {\n        (< $hi:literal : $lo:literal > | $N:tt bits) => {{\n            const NEW_N_: usize = $hi - $lo + 1;\n            NEW_N_\n        }};\n    }\n\n    fn bar(x: bool) {\n        _ = if x {\n            foo!(<2:0> | 3 bits) == foo!(<3:1> | 3 bits)\n        } else {\n            foo!(<3:1> | 3 bits) == foo!(<2:0> | 3 bits)\n        };\n    }\n}\n"
  },
  {
    "path": "tests/ui/if_same_then_else.stderr",
    "content": "error: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:25:13\n   |\nLL |       if true {\n   |  _____________^\nLL | |         Foo { bar: 42 };\nLL | |         0..10;\nLL | |         ..;\n...  |\nLL | |         foo();\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:33:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         Foo { bar: 42 };\nLL | |         0..10;\nLL | |         ..;\n...  |\nLL | |         foo();\nLL | |     }\n   | |_____^\n   = note: `-D clippy::if-same-then-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]`\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:69:21\n   |\nLL |     let _ = if true { 0.0 } else { 0.0 };\n   |                     ^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:69:34\n   |\nLL |     let _ = if true { 0.0 } else { 0.0 };\n   |                                  ^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:72:21\n   |\nLL |     let _ = if true { -0.0 } else { -0.0 };\n   |                     ^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:72:35\n   |\nLL |     let _ = if true { -0.0 } else { -0.0 };\n   |                                   ^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:84:21\n   |\nLL |     let _ = if true { 42 } else { 42 };\n   |                     ^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:84:33\n   |\nLL |     let _ = if true { 42 } else { 42 };\n   |                                 ^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:87:13\n   |\nLL |       if true {\n   |  _____________^\nLL | |         let bar = if true { 42 } else { 43 };\nLL | |\nLL | |         while foo() {\n...  |\nLL | |         bar + 1;\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:94:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         let bar = if true { 42 } else { 43 };\nLL | |\nLL | |         while foo() {\n...  |\nLL | |         bar + 1;\nLL | |     }\n   | |_____^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:228:14\n   |\nLL |           if x {\n   |  ______________^\nLL | |             0_u8.is_power_of_two()\nLL | |         } else {\n   | |_________^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:230:16\n   |\nLL |           } else {\n   |  ________________^\nLL | |             0_u8.is_power_of_two()\nLL | |         }\n   | |_________^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:257:14\n   |\nLL |     _ = if x { a == b } else { b == a };\n   |              ^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:257:30\n   |\nLL |     _ = if x { a == b } else { b == a };\n   |                              ^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:259:14\n   |\nLL |     _ = if x { a != b } else { b != a };\n   |              ^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:259:30\n   |\nLL |     _ = if x { a != b } else { b != a };\n   |                              ^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:263:14\n   |\nLL |     _ = if x { a < b } else { b > a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:263:29\n   |\nLL |     _ = if x { a < b } else { b > a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:265:14\n   |\nLL |     _ = if x { a <= b } else { b >= a };\n   |              ^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:265:30\n   |\nLL |     _ = if x { a <= b } else { b >= a };\n   |                              ^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:267:14\n   |\nLL |     _ = if x { a > b } else { b < a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:267:29\n   |\nLL |     _ = if x { a > b } else { b < a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:269:14\n   |\nLL |     _ = if x { a >= b } else { b <= a };\n   |              ^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:269:30\n   |\nLL |     _ = if x { a >= b } else { b <= a };\n   |                              ^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:282:14\n   |\nLL |     _ = if x { a * b } else { b * a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:282:29\n   |\nLL |     _ = if x { a * b } else { b * a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:284:14\n   |\nLL |     _ = if x { a + b } else { b + a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:284:29\n   |\nLL |     _ = if x { a + b } else { b + a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:286:14\n   |\nLL |     _ = if x { a & b } else { b & a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:286:29\n   |\nLL |     _ = if x { a & b } else { b & a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:288:14\n   |\nLL |     _ = if x { a ^ b } else { b ^ a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:288:29\n   |\nLL |     _ = if x { a ^ b } else { b ^ a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:290:14\n   |\nLL |     _ = if x { a | b } else { b | a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:290:29\n   |\nLL |     _ = if x { a | b } else { b | a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:294:14\n   |\nLL |     _ = if x { a == b } else { b == a };\n   |              ^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:294:30\n   |\nLL |     _ = if x { a == b } else { b == a };\n   |                              ^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:296:14\n   |\nLL |     _ = if x { a != b } else { b != a };\n   |              ^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:296:30\n   |\nLL |     _ = if x { a != b } else { b != a };\n   |                              ^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:300:14\n   |\nLL |     _ = if x { a < b } else { b > a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:300:29\n   |\nLL |     _ = if x { a < b } else { b > a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:302:14\n   |\nLL |     _ = if x { a <= b } else { b >= a };\n   |              ^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:302:30\n   |\nLL |     _ = if x { a <= b } else { b >= a };\n   |                              ^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:304:14\n   |\nLL |     _ = if x { a > b } else { b < a };\n   |              ^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:304:29\n   |\nLL |     _ = if x { a > b } else { b < a };\n   |                             ^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else.rs:306:14\n   |\nLL |     _ = if x { a >= b } else { b <= a };\n   |              ^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else.rs:306:30\n   |\nLL |     _ = if x { a >= b } else { b <= a };\n   |                              ^^^^^^^^^^\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/if_same_then_else2.rs",
    "content": "#![warn(clippy::if_same_then_else)]\n#![allow(\n    clippy::disallowed_names,\n    clippy::collapsible_else_if,\n    clippy::equatable_if_let,\n    clippy::collapsible_if,\n    clippy::ifs_same_cond,\n    clippy::needless_ifs,\n    clippy::needless_return,\n    clippy::single_element_loop,\n    clippy::branches_sharing_code\n)]\n\nfn if_same_then_else2() -> Result<&'static str, ()> {\n    if true {\n        for _ in &[42] {\n            let foo: &Option<_> = &Some::<u8>(42);\n            if foo.is_some() {\n                break;\n            } else {\n                continue;\n            }\n        }\n    } else {\n        for _ in &[42] {\n            let bar: &Option<_> = &Some::<u8>(42);\n            if bar.is_some() {\n                break;\n            } else {\n                continue;\n            }\n        }\n    }\n    //~^^^^^^^^^^^^^^^^^^^ if_same_then_else\n\n    if true {\n        if let Some(a) = Some(42) {}\n    } else {\n        if let Some(a) = Some(42) {}\n    }\n    //~^^^^^ if_same_then_else\n\n    if true {\n        if let (1, .., 3) = (1, 2, 3) {}\n    } else {\n        if let (1, .., 3) = (1, 2, 3) {}\n    }\n    //~^^^^^ if_same_then_else\n\n    if true {\n        if let (1, .., 3) = (1, 2, 3) {}\n    } else {\n        if let (.., 3) = (1, 2, 3) {}\n    }\n\n    if true {\n        if let (1, .., 3) = (1, 2, 3) {}\n    } else {\n        if let (.., 4) = (1, 2, 3) {}\n    }\n\n    if true {\n        if let (1, .., 3) = (1, 2, 3) {}\n    } else {\n        if let (.., 1, 3) = (1, 2, 3) {}\n    }\n\n    if true {\n        if let Some(42) = None {}\n    } else {\n        if let Option::Some(42) = None {}\n    }\n\n    if true {\n        if let Some(42) = None::<u8> {}\n    } else {\n        if let Some(42) = None {}\n    }\n\n    if true {\n        if let Some(42) = None::<u8> {}\n    } else {\n        if let Some(42) = None::<u32> {}\n    }\n\n    if true {\n        if let Some(a) = Some(42) {}\n    } else {\n        if let Some(a) = Some(43) {}\n    }\n\n    // Same NaNs\n    let _ = if true { f32::NAN } else { f32::NAN };\n    //~^ if_same_then_else\n\n    if true {\n        Ok(\"foo\")?;\n    } else {\n        Ok(\"foo\")?;\n    }\n    //~^^^^^ if_same_then_else\n\n    if true {\n        let foo = \"\";\n        return Ok(&foo[0..]);\n    } else if false {\n        let foo = \"bar\";\n        return Ok(&foo[0..]);\n    } else {\n        let foo = \"\";\n        return Ok(&foo[0..]);\n    }\n\n    if true {\n        let foo = \"\";\n        return Ok(&foo[0..]);\n    } else if false {\n        let foo = \"bar\";\n        return Ok(&foo[0..]);\n    } else if true {\n        let foo = \"\";\n        return Ok(&foo[0..]);\n    } else {\n        let foo = \"\";\n        return Ok(&foo[0..]);\n    }\n    //~^^^^^^^ if_same_then_else\n\n    // False positive `if_same_then_else`: `let (x, y)` vs. `let (y, x)`; see issue #3559.\n    if true {\n        let foo = \"\";\n        let (x, y) = (1, 2);\n        return Ok(&foo[x..y]);\n    } else {\n        let foo = \"\";\n        let (y, x) = (1, 2);\n        return Ok(&foo[x..y]);\n    }\n\n    // Issue #7579\n    let _ = if let Some(0) = None { 0 } else { 0 };\n\n    if true {\n        return Err(());\n    } else if let Some(0) = None {\n        return Err(());\n    }\n\n    let _ = if let Some(0) = None {\n        0\n    } else if let Some(1) = None {\n        0\n    } else {\n        0\n    };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/if_same_then_else2.stderr",
    "content": "error: this `if` has identical blocks\n  --> tests/ui/if_same_then_else2.rs:15:13\n   |\nLL |       if true {\n   |  _____________^\nLL | |         for _ in &[42] {\nLL | |             let foo: &Option<_> = &Some::<u8>(42);\nLL | |             if foo.is_some() {\n...  |\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else2.rs:24:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         for _ in &[42] {\nLL | |             let bar: &Option<_> = &Some::<u8>(42);\nLL | |             if bar.is_some() {\n...  |\nLL | |     }\n   | |_____^\n   = note: `-D clippy::if-same-then-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]`\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else2.rs:36:13\n   |\nLL |       if true {\n   |  _____________^\nLL | |         if let Some(a) = Some(42) {}\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else2.rs:38:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if let Some(a) = Some(42) {}\nLL | |     }\n   | |_____^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else2.rs:43:13\n   |\nLL |       if true {\n   |  _____________^\nLL | |         if let (1, .., 3) = (1, 2, 3) {}\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else2.rs:45:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         if let (1, .., 3) = (1, 2, 3) {}\nLL | |     }\n   | |_____^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else2.rs:93:21\n   |\nLL |     let _ = if true { f32::NAN } else { f32::NAN };\n   |                     ^^^^^^^^^^^^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else2.rs:93:39\n   |\nLL |     let _ = if true { f32::NAN } else { f32::NAN };\n   |                                       ^^^^^^^^^^^^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else2.rs:96:13\n   |\nLL |       if true {\n   |  _____________^\nLL | |         Ok(\"foo\")?;\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else2.rs:98:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         Ok(\"foo\")?;\nLL | |     }\n   | |_____^\n\nerror: this `if` has identical blocks\n  --> tests/ui/if_same_then_else2.rs:120:20\n   |\nLL |       } else if true {\n   |  ____________________^\nLL | |         let foo = \"\";\nLL | |         return Ok(&foo[0..]);\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/if_same_then_else2.rs:123:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         let foo = \"\";\nLL | |         return Ok(&foo[0..]);\nLL | |     }\n   | |_____^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/if_then_some_else_none.fixed",
    "content": "#![warn(clippy::if_then_some_else_none)]\n#![allow(clippy::redundant_pattern_matching, clippy::unnecessary_lazy_evaluations)]\n\nfn main() {\n    // Should issue an error.\n    let _ = foo().then(|| {\n        //~^ if_then_some_else_none\n\n        println!(\"true!\");\n        \"foo\"\n    });\n\n    // Should issue an error when macros are used.\n    let _ = matches!(true, true).then(|| {\n        //~^ if_then_some_else_none\n\n        println!(\"true!\");\n        matches!(true, false)\n    });\n\n    // Should issue an error. Binary expression `o < 32` should be parenthesized.\n    let x = Some(5);\n    let _ = x.and_then(|o| (o < 32).then_some(o));\n    //~^ if_then_some_else_none\n\n    // Should issue an error. Unary expression `!x` should be parenthesized.\n    let x = true;\n    let _ = (!x).then_some(0);\n    //~^ if_then_some_else_none\n\n    // Should not issue an error since the `else` block has a statement besides `None`.\n    let _ = if foo() {\n        println!(\"true!\");\n        Some(\"foo\")\n    } else {\n        eprintln!(\"false...\");\n        None\n    };\n\n    // Should not issue an error since there are more than 2 blocks in the if-else chain.\n    let _ = if foo() {\n        println!(\"foo true!\");\n        Some(\"foo\")\n    } else if bar() {\n        println!(\"bar true!\");\n        Some(\"bar\")\n    } else {\n        None\n    };\n\n    let _ = if foo() {\n        println!(\"foo true!\");\n        Some(\"foo\")\n    } else {\n        bar().then(|| {\n            println!(\"bar true!\");\n            \"bar\"\n        })\n    };\n\n    // Should not issue an error since the `then` block has `None`, not `Some`.\n    let _ = if foo() { None } else { Some(\"foo is false\") };\n\n    // Should not issue an error since the `else` block doesn't use `None` directly.\n    let _ = if foo() { Some(\"foo is true\") } else { into_none() };\n\n    // Should not issue an error since the `then` block doesn't use `Some` directly.\n    let _ = if foo() { into_some(\"foo\") } else { None };\n}\n\n#[clippy::msrv = \"1.49\"]\nfn _msrv_1_49() {\n    // `bool::then` was stabilized in 1.50. Do not lint this\n    let _ = if foo() {\n        println!(\"true!\");\n        Some(149)\n    } else {\n        None\n    };\n}\n\n#[clippy::msrv = \"1.50\"]\nfn _msrv_1_50() {\n    let _ = foo().then(|| {\n        //~^ if_then_some_else_none\n\n        println!(\"true!\");\n        150\n    });\n}\n\nfn foo() -> bool {\n    unimplemented!()\n}\n\nfn bar() -> bool {\n    unimplemented!()\n}\n\nfn into_some<T>(v: T) -> Option<T> {\n    Some(v)\n}\n\nfn into_none<T>() -> Option<T> {\n    None\n}\n\n// Should not warn\nfn f(b: bool, v: Option<()>) -> Option<()> {\n    if b {\n        v?; // This is a potential early return, is not equivalent with `bool::then`\n\n        Some(())\n    } else {\n        None\n    }\n}\n\nfn issue11394(b: bool, v: Result<(), ()>) -> Result<(), ()> {\n    let x = if b {\n        #[allow(clippy::let_unit_value)]\n        let _ = v?;\n        Some(())\n    } else {\n        None\n    };\n\n    Ok(())\n}\n\nfn issue13407(s: &str) -> Option<bool> {\n    (s == \"1\").then(|| true)\n    //~^ if_then_some_else_none\n}\n\nconst fn issue12103(x: u32) -> Option<u32> {\n    // Should not issue an error in `const` context\n    if x > 42 { Some(150) } else { None }\n}\n\nmod issue15257 {\n    struct Range {\n        start: u8,\n        end: u8,\n    }\n\n    fn can_be_safely_rewrite(rs: &[&Range]) -> Option<Vec<u8>> {\n        (rs.len() == 1 && rs[0].start == rs[0].end).then(|| vec![rs[0].start])\n    }\n\n    fn reborrow_as_ptr(i: *mut i32) -> Option<*const i32> {\n        let modulo = unsafe { *i % 2 };\n        (modulo == 0).then_some(i)\n    }\n\n    fn reborrow_as_fn_ptr(i: i32) {\n        fn do_something(fn_: Option<fn(i32)>) {\n            todo!()\n        }\n\n        fn item_fn(i: i32) {\n            todo!()\n        }\n\n        do_something((i % 2 == 0).then_some(item_fn));\n    }\n\n    fn reborrow_as_fn_unsafe(i: i32) {\n        fn do_something(fn_: Option<unsafe fn(i32)>) {\n            todo!()\n        }\n\n        fn item_fn(i: i32) {\n            todo!()\n        }\n\n        do_something((i % 2 == 0).then_some(item_fn));\n\n        let closure_fn = |i: i32| {};\n        do_something((i % 2 == 0).then_some(closure_fn));\n    }\n}\n\nfn issue15005() {\n    struct Counter {\n        count: u32,\n    }\n\n    impl Counter {\n        fn new() -> Counter {\n            Counter { count: 0 }\n        }\n    }\n\n    impl Iterator for Counter {\n        type Item = u32;\n\n        fn next(&mut self) -> Option<Self::Item> {\n            //~v if_then_some_else_none\n            (self.count < 5).then(|| {\n                self.count += 1;\n                self.count\n            })\n        }\n    }\n}\n\nfn statements_from_macro() {\n    macro_rules! mac {\n        () => {\n            println!(\"foo\");\n            println!(\"bar\");\n        };\n    }\n    //~v if_then_some_else_none\n    let _ = true.then(|| {\n        mac!();\n        42\n    });\n}\n\nfn dont_lint_inside_macros() {\n    macro_rules! mac {\n        ($cond:expr, $res:expr) => {\n            if $cond { Some($res) } else { None }\n        };\n    }\n    let _: Option<u32> = mac!(true, 42);\n}\n\nmod issue15770 {\n    fn maybe_error() -> Result<u32, &'static str> {\n        Err(\"error!\")\n    }\n\n    pub fn trying(b: bool) -> Result<(), &'static str> {\n        let _x: Option<u32> = if b { Some(maybe_error()?) } else { None };\n        // Process _x locally\n        Ok(())\n    }\n}\n\nmod issue16176 {\n    pub async fn foo() -> u32 {\n        todo!()\n    }\n\n    pub async fn bar(cond: bool) -> Option<u32> {\n        if cond { Some(foo().await) } else { None } // OK\n    }\n}\n\nfn issue16269() -> Option<i32> {\n    use std::cell::UnsafeCell;\n\n    //~v if_then_some_else_none\n    (1 <= 3).then(|| {\n        let a = UnsafeCell::new(1);\n        // SAFETY: `bytes` bytes starting at `new_end` were just reserved.\n        unsafe { *a.get() }\n    })\n}\n"
  },
  {
    "path": "tests/ui/if_then_some_else_none.rs",
    "content": "#![warn(clippy::if_then_some_else_none)]\n#![allow(clippy::redundant_pattern_matching, clippy::unnecessary_lazy_evaluations)]\n\nfn main() {\n    // Should issue an error.\n    let _ = if foo() {\n        //~^ if_then_some_else_none\n\n        println!(\"true!\");\n        Some(\"foo\")\n    } else {\n        None\n    };\n\n    // Should issue an error when macros are used.\n    let _ = if matches!(true, true) {\n        //~^ if_then_some_else_none\n\n        println!(\"true!\");\n        Some(matches!(true, false))\n    } else {\n        None\n    };\n\n    // Should issue an error. Binary expression `o < 32` should be parenthesized.\n    let x = Some(5);\n    let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });\n    //~^ if_then_some_else_none\n\n    // Should issue an error. Unary expression `!x` should be parenthesized.\n    let x = true;\n    let _ = if !x { Some(0) } else { None };\n    //~^ if_then_some_else_none\n\n    // Should not issue an error since the `else` block has a statement besides `None`.\n    let _ = if foo() {\n        println!(\"true!\");\n        Some(\"foo\")\n    } else {\n        eprintln!(\"false...\");\n        None\n    };\n\n    // Should not issue an error since there are more than 2 blocks in the if-else chain.\n    let _ = if foo() {\n        println!(\"foo true!\");\n        Some(\"foo\")\n    } else if bar() {\n        println!(\"bar true!\");\n        Some(\"bar\")\n    } else {\n        None\n    };\n\n    let _ = if foo() {\n        println!(\"foo true!\");\n        Some(\"foo\")\n    } else {\n        bar().then(|| {\n            println!(\"bar true!\");\n            \"bar\"\n        })\n    };\n\n    // Should not issue an error since the `then` block has `None`, not `Some`.\n    let _ = if foo() { None } else { Some(\"foo is false\") };\n\n    // Should not issue an error since the `else` block doesn't use `None` directly.\n    let _ = if foo() { Some(\"foo is true\") } else { into_none() };\n\n    // Should not issue an error since the `then` block doesn't use `Some` directly.\n    let _ = if foo() { into_some(\"foo\") } else { None };\n}\n\n#[clippy::msrv = \"1.49\"]\nfn _msrv_1_49() {\n    // `bool::then` was stabilized in 1.50. Do not lint this\n    let _ = if foo() {\n        println!(\"true!\");\n        Some(149)\n    } else {\n        None\n    };\n}\n\n#[clippy::msrv = \"1.50\"]\nfn _msrv_1_50() {\n    let _ = if foo() {\n        //~^ if_then_some_else_none\n\n        println!(\"true!\");\n        Some(150)\n    } else {\n        None\n    };\n}\n\nfn foo() -> bool {\n    unimplemented!()\n}\n\nfn bar() -> bool {\n    unimplemented!()\n}\n\nfn into_some<T>(v: T) -> Option<T> {\n    Some(v)\n}\n\nfn into_none<T>() -> Option<T> {\n    None\n}\n\n// Should not warn\nfn f(b: bool, v: Option<()>) -> Option<()> {\n    if b {\n        v?; // This is a potential early return, is not equivalent with `bool::then`\n\n        Some(())\n    } else {\n        None\n    }\n}\n\nfn issue11394(b: bool, v: Result<(), ()>) -> Result<(), ()> {\n    let x = if b {\n        #[allow(clippy::let_unit_value)]\n        let _ = v?;\n        Some(())\n    } else {\n        None\n    };\n\n    Ok(())\n}\n\nfn issue13407(s: &str) -> Option<bool> {\n    if s == \"1\" { Some(true) } else { None }\n    //~^ if_then_some_else_none\n}\n\nconst fn issue12103(x: u32) -> Option<u32> {\n    // Should not issue an error in `const` context\n    if x > 42 { Some(150) } else { None }\n}\n\nmod issue15257 {\n    struct Range {\n        start: u8,\n        end: u8,\n    }\n\n    fn can_be_safely_rewrite(rs: &[&Range]) -> Option<Vec<u8>> {\n        if rs.len() == 1 && rs[0].start == rs[0].end {\n            //~^ if_then_some_else_none\n            Some(vec![rs[0].start])\n        } else {\n            None\n        }\n    }\n\n    fn reborrow_as_ptr(i: *mut i32) -> Option<*const i32> {\n        let modulo = unsafe { *i % 2 };\n        if modulo == 0 {\n            //~^ if_then_some_else_none\n            Some(i)\n        } else {\n            None\n        }\n    }\n\n    fn reborrow_as_fn_ptr(i: i32) {\n        fn do_something(fn_: Option<fn(i32)>) {\n            todo!()\n        }\n\n        fn item_fn(i: i32) {\n            todo!()\n        }\n\n        do_something(if i % 2 == 0 {\n            //~^ if_then_some_else_none\n            Some(item_fn)\n        } else {\n            None\n        });\n    }\n\n    fn reborrow_as_fn_unsafe(i: i32) {\n        fn do_something(fn_: Option<unsafe fn(i32)>) {\n            todo!()\n        }\n\n        fn item_fn(i: i32) {\n            todo!()\n        }\n\n        do_something(if i % 2 == 0 {\n            //~^ if_then_some_else_none\n            Some(item_fn)\n        } else {\n            None\n        });\n\n        let closure_fn = |i: i32| {};\n        do_something(if i % 2 == 0 {\n            //~^ if_then_some_else_none\n            Some(closure_fn)\n        } else {\n            None\n        });\n    }\n}\n\nfn issue15005() {\n    struct Counter {\n        count: u32,\n    }\n\n    impl Counter {\n        fn new() -> Counter {\n            Counter { count: 0 }\n        }\n    }\n\n    impl Iterator for Counter {\n        type Item = u32;\n\n        fn next(&mut self) -> Option<Self::Item> {\n            //~v if_then_some_else_none\n            if self.count < 5 {\n                self.count += 1;\n                Some(self.count)\n            } else {\n                None\n            }\n        }\n    }\n}\n\nfn statements_from_macro() {\n    macro_rules! mac {\n        () => {\n            println!(\"foo\");\n            println!(\"bar\");\n        };\n    }\n    //~v if_then_some_else_none\n    let _ = if true {\n        mac!();\n        Some(42)\n    } else {\n        None\n    };\n}\n\nfn dont_lint_inside_macros() {\n    macro_rules! mac {\n        ($cond:expr, $res:expr) => {\n            if $cond { Some($res) } else { None }\n        };\n    }\n    let _: Option<u32> = mac!(true, 42);\n}\n\nmod issue15770 {\n    fn maybe_error() -> Result<u32, &'static str> {\n        Err(\"error!\")\n    }\n\n    pub fn trying(b: bool) -> Result<(), &'static str> {\n        let _x: Option<u32> = if b { Some(maybe_error()?) } else { None };\n        // Process _x locally\n        Ok(())\n    }\n}\n\nmod issue16176 {\n    pub async fn foo() -> u32 {\n        todo!()\n    }\n\n    pub async fn bar(cond: bool) -> Option<u32> {\n        if cond { Some(foo().await) } else { None } // OK\n    }\n}\n\nfn issue16269() -> Option<i32> {\n    use std::cell::UnsafeCell;\n\n    //~v if_then_some_else_none\n    if 1 <= 3 {\n        let a = UnsafeCell::new(1);\n        // SAFETY: `bytes` bytes starting at `new_end` were just reserved.\n        Some(unsafe { *a.get() })\n    } else {\n        None\n    }\n}\n"
  },
  {
    "path": "tests/ui/if_then_some_else_none.stderr",
    "content": "error: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none.rs:6:13\n   |\nLL |       let _ = if foo() {\n   |  _____________^\nLL | |\nLL | |\nLL | |         println!(\"true!\");\n...  |\nLL | |         None\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::if-then-some-else-none` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]`\nhelp: try\n   |\nLL ~     let _ = foo().then(|| {\nLL +\nLL + \nLL +         println!(\"true!\");\nLL +         \"foo\"\nLL ~     });\n   |\n\nerror: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none.rs:16:13\n   |\nLL |       let _ = if matches!(true, true) {\n   |  _____________^\nLL | |\nLL | |\nLL | |         println!(\"true!\");\n...  |\nLL | |         None\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = matches!(true, true).then(|| {\nLL +\nLL + \nLL +         println!(\"true!\");\nLL +         matches!(true, false)\nLL ~     });\n   |\n\nerror: this could be simplified with `bool::then_some`\n  --> tests/ui/if_then_some_else_none.rs:27:28\n   |\nLL |     let _ = x.and_then(|o| if o < 32 { Some(o) } else { None });\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(o < 32).then_some(o)`\n\nerror: this could be simplified with `bool::then_some`\n  --> tests/ui/if_then_some_else_none.rs:32:13\n   |\nLL |     let _ = if !x { Some(0) } else { None };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(!x).then_some(0)`\n\nerror: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none.rs:88:13\n   |\nLL |       let _ = if foo() {\n   |  _____________^\nLL | |\nLL | |\nLL | |         println!(\"true!\");\n...  |\nLL | |         None\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = foo().then(|| {\nLL +\nLL + \nLL +         println!(\"true!\");\nLL +         150\nLL ~     });\n   |\n\nerror: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none.rs:138:5\n   |\nLL |     if s == \"1\" { Some(true) } else { None }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(s == \"1\").then(|| true)`\n\nerror: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none.rs:154:9\n   |\nLL | /         if rs.len() == 1 && rs[0].start == rs[0].end {\nLL | |\nLL | |             Some(vec![rs[0].start])\nLL | |         } else {\nLL | |             None\nLL | |         }\n   | |_________^ help: try: `(rs.len() == 1 && rs[0].start == rs[0].end).then(|| vec![rs[0].start])`\n\nerror: this could be simplified with `bool::then_some`\n  --> tests/ui/if_then_some_else_none.rs:164:9\n   |\nLL | /         if modulo == 0 {\nLL | |\nLL | |             Some(i)\nLL | |         } else {\nLL | |             None\nLL | |         }\n   | |_________^ help: try: `(modulo == 0).then_some(i)`\n\nerror: this could be simplified with `bool::then_some`\n  --> tests/ui/if_then_some_else_none.rs:181:22\n   |\nLL |           do_something(if i % 2 == 0 {\n   |  ______________________^\nLL | |\nLL | |             Some(item_fn)\nLL | |         } else {\nLL | |             None\nLL | |         });\n   | |_________^ help: try: `(i % 2 == 0).then_some(item_fn)`\n\nerror: this could be simplified with `bool::then_some`\n  --> tests/ui/if_then_some_else_none.rs:198:22\n   |\nLL |           do_something(if i % 2 == 0 {\n   |  ______________________^\nLL | |\nLL | |             Some(item_fn)\nLL | |         } else {\nLL | |             None\nLL | |         });\n   | |_________^ help: try: `(i % 2 == 0).then_some(item_fn)`\n\nerror: this could be simplified with `bool::then_some`\n  --> tests/ui/if_then_some_else_none.rs:206:22\n   |\nLL |           do_something(if i % 2 == 0 {\n   |  ______________________^\nLL | |\nLL | |             Some(closure_fn)\nLL | |         } else {\nLL | |             None\nLL | |         });\n   | |_________^ help: try: `(i % 2 == 0).then_some(closure_fn)`\n\nerror: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none.rs:231:13\n   |\nLL | /             if self.count < 5 {\nLL | |                 self.count += 1;\nLL | |                 Some(self.count)\nLL | |             } else {\nLL | |                 None\nLL | |             }\n   | |_____________^\n   |\nhelp: try\n   |\nLL ~             (self.count < 5).then(|| {\nLL +                 self.count += 1;\nLL +                 self.count\nLL +             })\n   |\n\nerror: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none.rs:249:13\n   |\nLL |       let _ = if true {\n   |  _____________^\nLL | |         mac!();\nLL | |         Some(42)\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = true.then(|| {\nLL +         mac!();\nLL +         42\nLL ~     });\n   |\n\nerror: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none.rs:292:5\n   |\nLL | /     if 1 <= 3 {\nLL | |         let a = UnsafeCell::new(1);\nLL | |         // SAFETY: `bytes` bytes starting at `new_end` were just reserved.\nLL | |         Some(unsafe { *a.get() })\nLL | |     } else {\nLL | |         None\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     (1 <= 3).then(|| {\nLL +         let a = UnsafeCell::new(1);\nLL +         // SAFETY: `bytes` bytes starting at `new_end` were just reserved.\nLL +         unsafe { *a.get() }\nLL +     })\n   |\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/if_then_some_else_none_unfixable.rs",
    "content": "#![warn(clippy::if_then_some_else_none)]\n#![allow(clippy::manual_is_multiple_of)]\n\nmod issue15257 {\n    use std::pin::Pin;\n\n    #[derive(Default)]\n    pub struct Foo {}\n    pub trait Bar {}\n    impl Bar for Foo {}\n\n    fn pointer_unsized_coercion(i: u32) -> Option<Box<dyn Bar>> {\n        if i % 2 == 0 {\n            //~^ if_then_some_else_none\n            Some(Box::new(Foo::default()))\n        } else {\n            None\n        }\n    }\n\n    fn reborrow_as_pin(i: Pin<&mut i32>) {\n        use std::ops::Rem;\n\n        fn do_something(i: Option<&i32>) {\n            todo!()\n        }\n\n        do_something(if i.rem(2) == 0 {\n            //~^ if_then_some_else_none\n            Some(&i)\n        } else {\n            None\n        });\n    }\n}\n"
  },
  {
    "path": "tests/ui/if_then_some_else_none_unfixable.stderr",
    "content": "error: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none_unfixable.rs:13:9\n   |\nLL | /         if i % 2 == 0 {\nLL | |\nLL | |             Some(Box::new(Foo::default()))\nLL | |         } else {\nLL | |             None\nLL | |         }\n   | |_________^\n   |\n   = note: `-D clippy::if-then-some-else-none` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]`\n\nerror: this could be simplified with `bool::then`\n  --> tests/ui/if_then_some_else_none_unfixable.rs:28:22\n   |\nLL |           do_something(if i.rem(2) == 0 {\n   |  ______________________^\nLL | |\nLL | |             Some(&i)\nLL | |         } else {\nLL | |             None\nLL | |         });\n   | |_________^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/ifs_same_cond.rs",
    "content": "#![warn(clippy::ifs_same_cond)]\n#![allow(clippy::if_same_then_else, clippy::needless_ifs, clippy::needless_else)] // all empty blocks\n\nfn ifs_same_cond() {\n    let a = 0;\n    let b = false;\n\n    if b {\n        //~^ ifs_same_cond\n    } else if b {\n    }\n\n    if b {\n        //~^ ifs_same_cond\n    } else if b {\n    } else if b {\n    }\n\n    if a == 1 {\n        //~^ ifs_same_cond\n    } else if a == 1 {\n    }\n\n    if 2 * a == 1 {\n        //~^ ifs_same_cond\n    } else if 2 * a == 2 {\n    } else if 2 * a == 1 {\n    } else if a == 1 {\n    }\n\n    // See #659\n    if cfg!(feature = \"feature1-659\") {\n        1\n    } else if cfg!(feature = \"feature2-659\") {\n        2\n    } else {\n        3\n    };\n\n    let mut v = vec![1];\n    if v.pop().is_none() {\n        // ok, functions\n    } else if v.pop().is_none() {\n    }\n\n    if v.len() == 42 {\n        // ok, functions\n    } else if v.len() == 42 {\n    }\n\n    if let Some(env1) = option_env!(\"ENV1\") {\n    } else if let Some(env2) = option_env!(\"ENV2\") {\n    }\n}\n\nfn issue10272() {\n    let a = String::from(\"ha\");\n    if a.contains(\"ah\") {\n        //~^ ifs_same_cond\n    } else if a.contains(\"ah\") {\n\n        // Trigger this lint\n    } else if a.contains(\"ha\") {\n    } else if a == \"wow\" {\n    }\n\n    let p: *mut i8 = std::ptr::null_mut();\n    if p.is_null() {\n    } else if p.align_offset(0) == 0 {\n    } else if p.is_null() {\n        // ok, p is mutable pointer\n    } else {\n    }\n\n    let x = std::cell::Cell::new(true);\n    if x.get() {\n    } else if !x.take() {\n    } else if x.get() {\n        // ok, x is interior mutable type\n    } else {\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/ifs_same_cond.stderr",
    "content": "error: these `if` branches have the same condition\n  --> tests/ui/ifs_same_cond.rs:8:8\n   |\nLL |     if b {\n   |        ^\nLL |\nLL |     } else if b {\n   |               ^\n   |\n   = note: `-D clippy::ifs-same-cond` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]`\n\nerror: these `if` branches have the same condition\n  --> tests/ui/ifs_same_cond.rs:13:8\n   |\nLL |     if b {\n   |        ^\nLL |\nLL |     } else if b {\n   |               ^\nLL |     } else if b {\n   |               ^\n\nerror: these `if` branches have the same condition\n  --> tests/ui/ifs_same_cond.rs:19:8\n   |\nLL |     if a == 1 {\n   |        ^^^^^^\nLL |\nLL |     } else if a == 1 {\n   |               ^^^^^^\n\nerror: these `if` branches have the same condition\n  --> tests/ui/ifs_same_cond.rs:24:8\n   |\nLL |     if 2 * a == 1 {\n   |        ^^^^^^^^^^\n...\nLL |     } else if 2 * a == 1 {\n   |               ^^^^^^^^^^\n\nerror: these `if` branches have the same condition\n  --> tests/ui/ifs_same_cond.rs:58:8\n   |\nLL |     if a.contains(\"ah\") {\n   |        ^^^^^^^^^^^^^^^^\nLL |\nLL |     } else if a.contains(\"ah\") {\n   |               ^^^^^^^^^^^^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/ignore_without_reason.rs",
    "content": "#![warn(clippy::ignore_without_reason)]\n\nfn main() {}\n\n#[test]\nfn unignored_test() {}\n\n#[test]\n#[ignore = \"Some good reason\"]\nfn ignored_with_reason() {}\n\n#[test]\n#[ignore] //~ ignore_without_reason\nfn ignored_without_reason() {}\n"
  },
  {
    "path": "tests/ui/ignore_without_reason.stderr",
    "content": "error: `#[ignore]` without reason\n  --> tests/ui/ignore_without_reason.rs:13:1\n   |\nLL | #[ignore]\n   | ^^^^^^^^^\n   |\n   = help: add a reason with `= \"..\"`\n   = note: `-D clippy::ignore-without-reason` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ignore_without_reason)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/ignored_unit_patterns.fixed",
    "content": "//@aux-build:proc_macro_derive.rs\n#![warn(clippy::ignored_unit_patterns)]\n#![allow(\n    clippy::let_unit_value,\n    clippy::redundant_pattern_matching,\n    clippy::single_match,\n    clippy::needless_borrow\n)]\n\nfn foo() -> Result<(), ()> {\n    unimplemented!()\n}\n\nfn main() {\n    match foo() {\n        Ok(()) => {},  //~ ERROR: matching over `()` is more explicit\n        Err(()) => {}, //~ ERROR: matching over `()` is more explicit\n    }\n    if let Ok(()) = foo() {}\n    //~^ ERROR: matching over `()` is more explicit\n    let _ = foo().map_err(|()| todo!());\n    //~^ ERROR: matching over `()` is more explicit\n\n    println!(\n        \"{:?}\",\n        match foo() {\n            Ok(()) => {},\n            //~^ ERROR: matching over `()` is more explicit\n            Err(()) => {},\n            //~^ ERROR: matching over `()` is more explicit\n        }\n    );\n}\n\n// ignored_unit_patterns in derive macro should be ok\n#[derive(proc_macro_derive::StructIgnoredUnitPattern)]\npub struct B;\n\n#[allow(unused)]\npub fn moo(_: ()) {\n    let () = foo().unwrap();\n    //~^ ERROR: matching over `()` is more explicit\n    let _: () = foo().unwrap();\n    let _: () = ();\n}\n\nfn test_unit_ref_1() {\n    let x: (usize, &&&&&()) = (1, &&&&&&());\n    match x {\n        (1, ()) => unimplemented!(),\n        //~^ ERROR: matching over `()` is more explicit\n        _ => unimplemented!(),\n    };\n}\n\nfn test_unit_ref_2(v: &[(usize, ())]) {\n    for (x, ()) in v {\n        //~^ ERROR: matching over `()` is more explicit\n        let _ = x;\n    }\n}\n"
  },
  {
    "path": "tests/ui/ignored_unit_patterns.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n#![warn(clippy::ignored_unit_patterns)]\n#![allow(\n    clippy::let_unit_value,\n    clippy::redundant_pattern_matching,\n    clippy::single_match,\n    clippy::needless_borrow\n)]\n\nfn foo() -> Result<(), ()> {\n    unimplemented!()\n}\n\nfn main() {\n    match foo() {\n        Ok(_) => {},  //~ ERROR: matching over `()` is more explicit\n        Err(_) => {}, //~ ERROR: matching over `()` is more explicit\n    }\n    if let Ok(_) = foo() {}\n    //~^ ERROR: matching over `()` is more explicit\n    let _ = foo().map_err(|_| todo!());\n    //~^ ERROR: matching over `()` is more explicit\n\n    println!(\n        \"{:?}\",\n        match foo() {\n            Ok(_) => {},\n            //~^ ERROR: matching over `()` is more explicit\n            Err(_) => {},\n            //~^ ERROR: matching over `()` is more explicit\n        }\n    );\n}\n\n// ignored_unit_patterns in derive macro should be ok\n#[derive(proc_macro_derive::StructIgnoredUnitPattern)]\npub struct B;\n\n#[allow(unused)]\npub fn moo(_: ()) {\n    let _ = foo().unwrap();\n    //~^ ERROR: matching over `()` is more explicit\n    let _: () = foo().unwrap();\n    let _: () = ();\n}\n\nfn test_unit_ref_1() {\n    let x: (usize, &&&&&()) = (1, &&&&&&());\n    match x {\n        (1, _) => unimplemented!(),\n        //~^ ERROR: matching over `()` is more explicit\n        _ => unimplemented!(),\n    };\n}\n\nfn test_unit_ref_2(v: &[(usize, ())]) {\n    for (x, _) in v {\n        //~^ ERROR: matching over `()` is more explicit\n        let _ = x;\n    }\n}\n"
  },
  {
    "path": "tests/ui/ignored_unit_patterns.stderr",
    "content": "error: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:16:12\n   |\nLL |         Ok(_) => {},\n   |            ^ help: use `()` instead of `_`: `()`\n   |\n   = note: `-D clippy::ignored-unit-patterns` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ignored_unit_patterns)]`\n\nerror: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:17:13\n   |\nLL |         Err(_) => {},\n   |             ^ help: use `()` instead of `_`: `()`\n\nerror: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:19:15\n   |\nLL |     if let Ok(_) = foo() {}\n   |               ^ help: use `()` instead of `_`: `()`\n\nerror: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:21:28\n   |\nLL |     let _ = foo().map_err(|_| todo!());\n   |                            ^ help: use `()` instead of `_`: `()`\n\nerror: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:27:16\n   |\nLL |             Ok(_) => {},\n   |                ^ help: use `()` instead of `_`: `()`\n\nerror: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:29:17\n   |\nLL |             Err(_) => {},\n   |                 ^ help: use `()` instead of `_`: `()`\n\nerror: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:41:9\n   |\nLL |     let _ = foo().unwrap();\n   |         ^ help: use `()` instead of `_`: `()`\n\nerror: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:50:13\n   |\nLL |         (1, _) => unimplemented!(),\n   |             ^ help: use `()` instead of `_`: `()`\n\nerror: matching over `()` is more explicit\n  --> tests/ui/ignored_unit_patterns.rs:57:13\n   |\nLL |     for (x, _) in v {\n   |             ^ help: use `()` instead of `_`: `()`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/impl.rs",
    "content": "#![allow(dead_code, clippy::extra_unused_lifetimes)]\n#![warn(clippy::multiple_inherent_impl)]\n\nstruct MyStruct;\n\nimpl MyStruct {\n    fn first() {}\n}\n\nimpl MyStruct {\n    //~^ multiple_inherent_impl\n\n    fn second() {}\n}\n\nimpl<'a> MyStruct {\n    //~^ multiple_inherent_impl\n    fn lifetimed() {}\n}\n\nmod submod {\n    struct MyStruct;\n    impl MyStruct {\n        fn other() {}\n    }\n\n    impl super::MyStruct {\n        //~^ multiple_inherent_impl\n\n        fn third() {}\n    }\n}\n\nuse std::fmt;\nimpl fmt::Debug for MyStruct {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"MyStruct {{ }}\")\n    }\n}\n\n// issue #5772\nstruct WithArgs<T>(T);\nimpl WithArgs<u32> {\n    fn f1() {}\n}\nimpl WithArgs<u64> {\n    fn f2() {}\n}\nimpl WithArgs<u64> {\n    //~^ multiple_inherent_impl\n\n    fn f3() {}\n}\n\n// Ok, the struct is allowed to have multiple impls.\n#[allow(clippy::multiple_inherent_impl)]\nstruct Allowed;\nimpl Allowed {}\nimpl Allowed {}\nimpl Allowed {}\n\nstruct AllowedImpl;\n#[allow(clippy::multiple_inherent_impl)]\nimpl AllowedImpl {}\n// Ok, the first block is skipped by this lint.\nimpl AllowedImpl {}\n\nstruct OneAllowedImpl;\nimpl OneAllowedImpl {}\n#[allow(clippy::multiple_inherent_impl)]\nimpl OneAllowedImpl {}\nimpl OneAllowedImpl {}\n//~^ multiple_inherent_impl\n\n#[expect(clippy::multiple_inherent_impl)]\nstruct ExpectedFulfilled;\n\nimpl ExpectedFulfilled {}\nimpl ExpectedFulfilled {}\n\nstruct OneExpected;\nimpl OneExpected {}\n#[expect(clippy::multiple_inherent_impl)]\nimpl OneExpected {}\nimpl OneExpected {}\n//~^ multiple_inherent_impl\n\n// issue #8714\nstruct Lifetime<'s> {\n    s: &'s str,\n}\n\nimpl Lifetime<'_> {}\nimpl Lifetime<'_> {}\n//~^ multiple_inherent_impl\n\nimpl<'a> Lifetime<'a> {}\nimpl<'a> Lifetime<'a> {}\n//~^ multiple_inherent_impl\n\nimpl<'b> Lifetime<'b> {} // false negative?\n\nimpl Lifetime<'static> {}\n\nstruct Generic<G> {\n    g: Vec<G>,\n}\n\nimpl<G> Generic<G> {}\nimpl<G> Generic<G> {}\n//~^ multiple_inherent_impl\n\nuse std::fmt::Debug;\n\n#[derive(Debug)]\nstruct GenericWithBounds<T: Debug>(T);\n\nimpl<T: Debug> GenericWithBounds<T> {\n    fn make_one(_one: T) -> Self {\n        todo!()\n    }\n}\n\nimpl<T: Debug> GenericWithBounds<T> {\n    //~^ multiple_inherent_impl\n    fn make_two(_two: T) -> Self {\n        todo!()\n    }\n}\n\nstruct MultipleTraitBounds<T>(T);\n\nimpl<T: Debug> MultipleTraitBounds<T> {\n    fn debug_fn() {}\n}\n\nimpl<T: Clone> MultipleTraitBounds<T> {\n    fn clone_fn() {}\n}\n\nimpl<T: Debug + Clone> MultipleTraitBounds<T> {\n    fn debug_clone_fn() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/impl.stderr",
    "content": "error: multiple implementations of this structure\n  --> tests/ui/impl.rs:10:1\n   |\nLL | / impl MyStruct {\nLL | |\nLL | |\nLL | |     fn second() {}\nLL | | }\n   | |_^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:6:1\n   |\nLL | / impl MyStruct {\nLL | |     fn first() {}\nLL | | }\n   | |_^\n   = note: `-D clippy::multiple-inherent-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::multiple_inherent_impl)]`\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:16:1\n   |\nLL | / impl<'a> MyStruct {\nLL | |\nLL | |     fn lifetimed() {}\nLL | | }\n   | |_^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:6:1\n   |\nLL | / impl MyStruct {\nLL | |     fn first() {}\nLL | | }\n   | |_^\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:27:5\n   |\nLL | /     impl super::MyStruct {\nLL | |\nLL | |\nLL | |         fn third() {}\nLL | |     }\n   | |_____^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:6:1\n   |\nLL | / impl MyStruct {\nLL | |     fn first() {}\nLL | | }\n   | |_^\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:49:1\n   |\nLL | / impl WithArgs<u64> {\nLL | |\nLL | |\nLL | |     fn f3() {}\nLL | | }\n   | |_^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:46:1\n   |\nLL | / impl WithArgs<u64> {\nLL | |     fn f2() {}\nLL | | }\n   | |_^\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:72:1\n   |\nLL | impl OneAllowedImpl {}\n   | ^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:69:1\n   |\nLL | impl OneAllowedImpl {}\n   | ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:85:1\n   |\nLL | impl OneExpected {}\n   | ^^^^^^^^^^^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:82:1\n   |\nLL | impl OneExpected {}\n   | ^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:94:1\n   |\nLL | impl Lifetime<'_> {}\n   | ^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:93:1\n   |\nLL | impl Lifetime<'_> {}\n   | ^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:98:1\n   |\nLL | impl<'a> Lifetime<'a> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:97:1\n   |\nLL | impl<'a> Lifetime<'a> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:110:1\n   |\nLL | impl<G> Generic<G> {}\n   | ^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:109:1\n   |\nLL | impl<G> Generic<G> {}\n   | ^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/impl.rs:124:1\n   |\nLL | / impl<T: Debug> GenericWithBounds<T> {\nLL | |\nLL | |     fn make_two(_two: T) -> Self {\nLL | |         todo!()\nLL | |     }\nLL | | }\n   | |_^\n   |\nnote: first implementation here\n  --> tests/ui/impl.rs:118:1\n   |\nLL | / impl<T: Debug> GenericWithBounds<T> {\nLL | |     fn make_one(_one: T) -> Self {\nLL | |         todo!()\nLL | |     }\nLL | | }\n   | |_^\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/impl_hash_with_borrow_str_and_bytes.rs",
    "content": "#![warn(clippy::impl_hash_borrow_with_str_and_bytes)]\n\nuse std::borrow::Borrow;\nuse std::hash::{Hash, Hasher};\n\nstruct ExampleType {\n    data: String,\n}\n\nimpl Hash for ExampleType {\n    //~^ ERROR: can't\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        self.data.hash(state);\n    }\n}\n\nimpl Borrow<str> for ExampleType {\n    fn borrow(&self) -> &str {\n        &self.data\n    }\n}\n\nimpl Borrow<[u8]> for ExampleType {\n    fn borrow(&self) -> &[u8] {\n        self.data.as_bytes()\n    }\n}\n\nstruct ShouldNotRaiseForHash {}\nimpl Hash for ShouldNotRaiseForHash {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        todo!();\n    }\n}\n\nstruct ShouldNotRaiseForBorrow {}\nimpl Borrow<str> for ShouldNotRaiseForBorrow {\n    fn borrow(&self) -> &str {\n        todo!();\n    }\n}\nimpl Borrow<[u8]> for ShouldNotRaiseForBorrow {\n    fn borrow(&self) -> &[u8] {\n        todo!();\n    }\n}\n\nstruct ShouldNotRaiseForHashBorrowStr {}\nimpl Hash for ShouldNotRaiseForHashBorrowStr {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        todo!();\n    }\n}\nimpl Borrow<str> for ShouldNotRaiseForHashBorrowStr {\n    fn borrow(&self) -> &str {\n        todo!();\n    }\n}\n\nstruct ShouldNotRaiseForHashBorrowSlice {}\nimpl Hash for ShouldNotRaiseForHashBorrowSlice {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        todo!();\n    }\n}\n\nimpl Borrow<[u8]> for ShouldNotRaiseForHashBorrowSlice {\n    fn borrow(&self) -> &[u8] {\n        todo!();\n    }\n}\n\n#[derive(Hash)]\n//~^ ERROR: can't\nstruct Derived {\n    data: String,\n}\n\nimpl Borrow<str> for Derived {\n    fn borrow(&self) -> &str {\n        self.data.as_str()\n    }\n}\n\nimpl Borrow<[u8]> for Derived {\n    fn borrow(&self) -> &[u8] {\n        self.data.as_bytes()\n    }\n}\n\nstruct GenericExampleType<T> {\n    data: T,\n}\n\nimpl<T: Hash> Hash for GenericExampleType<T> {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        self.data.hash(state);\n    }\n}\n\nimpl Borrow<str> for GenericExampleType<String> {\n    fn borrow(&self) -> &str {\n        &self.data\n    }\n}\n\nimpl Borrow<[u8]> for GenericExampleType<&'static [u8]> {\n    fn borrow(&self) -> &[u8] {\n        self.data\n    }\n}\n\nstruct GenericExampleType2<T> {\n    data: T,\n}\n\nimpl Hash for GenericExampleType2<String> {\n    //~^ ERROR: can't\n    // this is correctly throwing an error for generic with concrete impl\n    // for all 3 types\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        self.data.hash(state);\n    }\n}\n\nimpl Borrow<str> for GenericExampleType2<String> {\n    fn borrow(&self) -> &str {\n        &self.data\n    }\n}\n\nimpl Borrow<[u8]> for GenericExampleType2<String> {\n    fn borrow(&self) -> &[u8] {\n        self.data.as_bytes()\n    }\n}\n"
  },
  {
    "path": "tests/ui/impl_hash_with_borrow_str_and_bytes.stderr",
    "content": "error: the semantics of `Borrow<T>` around `Hash` can't be satisfied when both `Borrow<str>` and `Borrow<[u8]>` are implemented\n  --> tests/ui/impl_hash_with_borrow_str_and_bytes.rs:10:6\n   |\nLL | impl Hash for ExampleType {\n   |      ^^^^\n   |\n   = note: the `Borrow` semantics require that `Hash` must behave the same for all implementations of Borrow<T>\n   = note: however, the hash implementations of a string (`str`) and the bytes of a string `[u8]` do not behave the same ...\n   = note: ... as (`hash(\"abc\") != hash(\"abc\".as_bytes())`\n   = help: consider either removing one of the  `Borrow` implementations (`Borrow<str>` or `Borrow<[u8]>`) ...\n   = help: ... or not implementing `Hash` for this type\n   = note: `-D clippy::impl-hash-borrow-with-str-and-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::impl_hash_borrow_with_str_and_bytes)]`\n\nerror: the semantics of `Borrow<T>` around `Hash` can't be satisfied when both `Borrow<str>` and `Borrow<[u8]>` are implemented\n  --> tests/ui/impl_hash_with_borrow_str_and_bytes.rs:73:10\n   |\nLL | #[derive(Hash)]\n   |          ^^^^\n   |\n   = note: the `Borrow` semantics require that `Hash` must behave the same for all implementations of Borrow<T>\n   = note: however, the hash implementations of a string (`str`) and the bytes of a string `[u8]` do not behave the same ...\n   = note: ... as (`hash(\"abc\") != hash(\"abc\".as_bytes())`\n   = help: consider either removing one of the  `Borrow` implementations (`Borrow<str>` or `Borrow<[u8]>`) ...\n   = help: ... or not implementing `Hash` for this type\n\nerror: the semantics of `Borrow<T>` around `Hash` can't be satisfied when both `Borrow<str>` and `Borrow<[u8]>` are implemented\n  --> tests/ui/impl_hash_with_borrow_str_and_bytes.rs:117:6\n   |\nLL | impl Hash for GenericExampleType2<String> {\n   |      ^^^^\n   |\n   = note: the `Borrow` semantics require that `Hash` must behave the same for all implementations of Borrow<T>\n   = note: however, the hash implementations of a string (`str`) and the bytes of a string `[u8]` do not behave the same ...\n   = note: ... as (`hash(\"abc\") != hash(\"abc\".as_bytes())`\n   = help: consider either removing one of the  `Borrow` implementations (`Borrow<str>` or `Borrow<[u8]>`) ...\n   = help: ... or not implementing `Hash` for this type\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/impl_trait_in_params.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::impl_trait_in_params)]\n\n//@no-rustfix: has placeholders\npub trait Trait {}\npub trait AnotherTrait<T> {}\n\n// Should warn\npub fn a(_: impl Trait) {}\n//~^ impl_trait_in_params\n\npub fn c<C: Trait>(_: C, _: impl Trait) {}\n//~^ impl_trait_in_params\n\n// Shouldn't warn\n\npub fn b<B: Trait>(_: B) {}\nfn e<T: AnotherTrait<u32>>(_: T) {}\nfn d(_: impl AnotherTrait<u32>) {}\n\n//------ IMPLS\n\npub trait Public {\n    // See test in ui-toml for a case where avoid-breaking-exported-api is set to false\n    fn t(_: impl Trait);\n    fn tt<T: Trait>(_: T) {}\n}\n\ntrait Private {\n    // This shouldn't lint\n    fn t(_: impl Trait);\n    fn tt<T: Trait>(_: T) {}\n}\n\nstruct S;\nimpl S {\n    pub fn h(_: impl Trait) {}\n    //~^ impl_trait_in_params\n    fn i(_: impl Trait) {}\n    pub fn j<J: Trait>(_: J) {}\n    pub fn k<K: AnotherTrait<u32>>(_: K, _: impl AnotherTrait<u32>) {}\n    //~^ impl_trait_in_params\n}\n\n// Trying with traits\nimpl Public for S {\n    fn t(_: impl Trait) {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/impl_trait_in_params.stderr",
    "content": "error: `impl Trait` used as a function parameter\n  --> tests/ui/impl_trait_in_params.rs:9:13\n   |\nLL | pub fn a(_: impl Trait) {}\n   |             ^^^^^^^^^^\n   |\n   = note: `-D clippy::impl-trait-in-params` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::impl_trait_in_params)]`\nhelp: add a type parameter\n   |\nLL | pub fn a<{ /* Generic name */ }: Trait>(_: impl Trait) {}\n   |         +++++++++++++++++++++++++++++++\n\nerror: `impl Trait` used as a function parameter\n  --> tests/ui/impl_trait_in_params.rs:12:29\n   |\nLL | pub fn c<C: Trait>(_: C, _: impl Trait) {}\n   |                             ^^^^^^^^^^\n   |\nhelp: add a type parameter\n   |\nLL | pub fn c<C: Trait, { /* Generic name */ }: Trait>(_: C, _: impl Trait) {}\n   |                  +++++++++++++++++++++++++++++++\n\nerror: `impl Trait` used as a function parameter\n  --> tests/ui/impl_trait_in_params.rs:37:17\n   |\nLL |     pub fn h(_: impl Trait) {}\n   |                 ^^^^^^^^^^\n   |\nhelp: add a type parameter\n   |\nLL |     pub fn h<{ /* Generic name */ }: Trait>(_: impl Trait) {}\n   |             +++++++++++++++++++++++++++++++\n\nerror: `impl Trait` used as a function parameter\n  --> tests/ui/impl_trait_in_params.rs:41:45\n   |\nLL |     pub fn k<K: AnotherTrait<u32>>(_: K, _: impl AnotherTrait<u32>) {}\n   |                                             ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: add a type parameter\n   |\nLL |     pub fn k<K: AnotherTrait<u32>, { /* Generic name */ }: AnotherTrait<u32>>(_: K, _: impl AnotherTrait<u32>) {}\n   |                                  +++++++++++++++++++++++++++++++++++++++++++\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/implicit_clone.fixed",
    "content": "#![warn(clippy::implicit_clone)]\n#![allow(clippy::clone_on_copy, clippy::redundant_clone)]\nuse std::borrow::Borrow;\nuse std::ffi::{OsStr, OsString};\nuse std::path::PathBuf;\n\nfn return_owned_from_slice(slice: &[u32]) -> Vec<u32> {\n    slice.to_owned()\n}\n\npub fn own_same<T>(v: T) -> T\nwhere\n    T: ToOwned<Owned = T>,\n{\n    v.to_owned()\n}\n\npub fn own_same_from_ref<T>(v: &T) -> T\nwhere\n    T: ToOwned<Owned = T>,\n{\n    v.to_owned()\n}\n\npub fn own_different<T, U>(v: T) -> U\nwhere\n    T: ToOwned<Owned = U>,\n{\n    v.to_owned()\n}\n\n#[derive(Copy, Clone)]\nstruct Kitten;\nimpl Kitten {\n    // badly named method\n    fn to_vec(self) -> Kitten {\n        Kitten {}\n    }\n}\nimpl Borrow<BorrowedKitten> for Kitten {\n    fn borrow(&self) -> &BorrowedKitten {\n        static VALUE: BorrowedKitten = BorrowedKitten {};\n        &VALUE\n    }\n}\n\nstruct BorrowedKitten;\nimpl ToOwned for BorrowedKitten {\n    type Owned = Kitten;\n    fn to_owned(&self) -> Kitten {\n        Kitten {}\n    }\n}\n\nmod weird {\n    #[allow(clippy::ptr_arg)]\n    pub fn to_vec(v: &Vec<u32>) -> Vec<u32> {\n        v.clone()\n    }\n}\n\nfn main() {\n    let vec = vec![5];\n    let _ = return_owned_from_slice(&vec);\n    let _ = vec.clone();\n    //~^ implicit_clone\n    let _ = vec.clone();\n    //~^ implicit_clone\n\n    let vec_ref = &vec;\n    let _ = return_owned_from_slice(vec_ref);\n    let _ = vec_ref.to_owned();\n    let _ = vec_ref.clone();\n    //~^ implicit_clone\n\n    // we expect no lint for this\n    let _ = weird::to_vec(&vec);\n\n    // we expect no lints for this\n    let slice: &[u32] = &[1, 2, 3, 4, 5];\n    let _ = return_owned_from_slice(slice);\n    let _ = slice.to_owned();\n    let _ = slice.to_vec();\n\n    let str = \"hello world\".to_string();\n    let _ = str.clone();\n    //~^ implicit_clone\n\n    // testing w/ an arbitrary type\n    let kitten = Kitten {};\n    let _ = kitten.clone();\n    //~^ implicit_clone\n    let _ = own_same_from_ref(&kitten);\n    // this shouldn't lint\n    let _ = kitten.to_vec();\n\n    // we expect no lints for this\n    let borrowed = BorrowedKitten {};\n    let _ = borrowed.to_owned();\n\n    let pathbuf = PathBuf::new();\n    let _ = pathbuf.clone();\n    //~^ implicit_clone\n    let _ = pathbuf.clone();\n    //~^ implicit_clone\n\n    let os_string = OsString::from(\"foo\");\n    let _ = os_string.clone();\n    //~^ implicit_clone\n    let _ = os_string.clone();\n    //~^ implicit_clone\n\n    // we expect no lints for this\n    let os_str = OsStr::new(\"foo\");\n    let _ = os_str.to_owned();\n    let _ = os_str.to_os_string();\n\n    // issue #8227\n    let pathbuf_ref = &pathbuf;\n    let pathbuf_ref = &pathbuf_ref;\n    let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&PathBuf`\n    let _ = (*pathbuf_ref).clone();\n    //~^ implicit_clone\n    let pathbuf_ref = &pathbuf_ref;\n    let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&&PathBuf`\n    let _ = (**pathbuf_ref).clone();\n    //~^ implicit_clone\n\n    struct NoClone;\n    impl ToOwned for NoClone {\n        type Owned = Self;\n        fn to_owned(&self) -> Self {\n            NoClone\n        }\n    }\n    let no_clone = &NoClone;\n    let _ = no_clone.to_owned();\n\n    let s = String::from(\"foo\");\n    let _ = s.clone();\n    //~^ implicit_clone\n    let _ = s.clone();\n    //~^ implicit_clone\n}\n"
  },
  {
    "path": "tests/ui/implicit_clone.rs",
    "content": "#![warn(clippy::implicit_clone)]\n#![allow(clippy::clone_on_copy, clippy::redundant_clone)]\nuse std::borrow::Borrow;\nuse std::ffi::{OsStr, OsString};\nuse std::path::PathBuf;\n\nfn return_owned_from_slice(slice: &[u32]) -> Vec<u32> {\n    slice.to_owned()\n}\n\npub fn own_same<T>(v: T) -> T\nwhere\n    T: ToOwned<Owned = T>,\n{\n    v.to_owned()\n}\n\npub fn own_same_from_ref<T>(v: &T) -> T\nwhere\n    T: ToOwned<Owned = T>,\n{\n    v.to_owned()\n}\n\npub fn own_different<T, U>(v: T) -> U\nwhere\n    T: ToOwned<Owned = U>,\n{\n    v.to_owned()\n}\n\n#[derive(Copy, Clone)]\nstruct Kitten;\nimpl Kitten {\n    // badly named method\n    fn to_vec(self) -> Kitten {\n        Kitten {}\n    }\n}\nimpl Borrow<BorrowedKitten> for Kitten {\n    fn borrow(&self) -> &BorrowedKitten {\n        static VALUE: BorrowedKitten = BorrowedKitten {};\n        &VALUE\n    }\n}\n\nstruct BorrowedKitten;\nimpl ToOwned for BorrowedKitten {\n    type Owned = Kitten;\n    fn to_owned(&self) -> Kitten {\n        Kitten {}\n    }\n}\n\nmod weird {\n    #[allow(clippy::ptr_arg)]\n    pub fn to_vec(v: &Vec<u32>) -> Vec<u32> {\n        v.clone()\n    }\n}\n\nfn main() {\n    let vec = vec![5];\n    let _ = return_owned_from_slice(&vec);\n    let _ = vec.to_owned();\n    //~^ implicit_clone\n    let _ = vec.to_vec();\n    //~^ implicit_clone\n\n    let vec_ref = &vec;\n    let _ = return_owned_from_slice(vec_ref);\n    let _ = vec_ref.to_owned();\n    let _ = vec_ref.to_vec();\n    //~^ implicit_clone\n\n    // we expect no lint for this\n    let _ = weird::to_vec(&vec);\n\n    // we expect no lints for this\n    let slice: &[u32] = &[1, 2, 3, 4, 5];\n    let _ = return_owned_from_slice(slice);\n    let _ = slice.to_owned();\n    let _ = slice.to_vec();\n\n    let str = \"hello world\".to_string();\n    let _ = str.to_owned();\n    //~^ implicit_clone\n\n    // testing w/ an arbitrary type\n    let kitten = Kitten {};\n    let _ = kitten.to_owned();\n    //~^ implicit_clone\n    let _ = own_same_from_ref(&kitten);\n    // this shouldn't lint\n    let _ = kitten.to_vec();\n\n    // we expect no lints for this\n    let borrowed = BorrowedKitten {};\n    let _ = borrowed.to_owned();\n\n    let pathbuf = PathBuf::new();\n    let _ = pathbuf.to_owned();\n    //~^ implicit_clone\n    let _ = pathbuf.to_path_buf();\n    //~^ implicit_clone\n\n    let os_string = OsString::from(\"foo\");\n    let _ = os_string.to_owned();\n    //~^ implicit_clone\n    let _ = os_string.to_os_string();\n    //~^ implicit_clone\n\n    // we expect no lints for this\n    let os_str = OsStr::new(\"foo\");\n    let _ = os_str.to_owned();\n    let _ = os_str.to_os_string();\n\n    // issue #8227\n    let pathbuf_ref = &pathbuf;\n    let pathbuf_ref = &pathbuf_ref;\n    let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&PathBuf`\n    let _ = pathbuf_ref.to_path_buf();\n    //~^ implicit_clone\n    let pathbuf_ref = &pathbuf_ref;\n    let _ = pathbuf_ref.to_owned(); // Don't lint. Returns `&&PathBuf`\n    let _ = pathbuf_ref.to_path_buf();\n    //~^ implicit_clone\n\n    struct NoClone;\n    impl ToOwned for NoClone {\n        type Owned = Self;\n        fn to_owned(&self) -> Self {\n            NoClone\n        }\n    }\n    let no_clone = &NoClone;\n    let _ = no_clone.to_owned();\n\n    let s = String::from(\"foo\");\n    let _ = s.to_owned();\n    //~^ implicit_clone\n    let _ = s.to_string();\n    //~^ implicit_clone\n}\n"
  },
  {
    "path": "tests/ui/implicit_clone.stderr",
    "content": "error: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:65:13\n   |\nLL |     let _ = vec.to_owned();\n   |             ^^^^^^^^^^^^^^ help: consider using: `vec.clone()`\n   |\n   = note: `-D clippy::implicit-clone` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]`\n\nerror: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:67:13\n   |\nLL |     let _ = vec.to_vec();\n   |             ^^^^^^^^^^^^ help: consider using: `vec.clone()`\n\nerror: implicitly cloning a `Vec` by calling `to_vec` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:73:13\n   |\nLL |     let _ = vec_ref.to_vec();\n   |             ^^^^^^^^^^^^^^^^ help: consider using: `vec_ref.clone()`\n\nerror: implicitly cloning a `String` by calling `to_owned` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:86:13\n   |\nLL |     let _ = str.to_owned();\n   |             ^^^^^^^^^^^^^^ help: consider using: `str.clone()`\n\nerror: implicitly cloning a `Kitten` by calling `to_owned` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:91:13\n   |\nLL |     let _ = kitten.to_owned();\n   |             ^^^^^^^^^^^^^^^^^ help: consider using: `kitten.clone()`\n\nerror: implicitly cloning a `PathBuf` by calling `to_owned` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:102:13\n   |\nLL |     let _ = pathbuf.to_owned();\n   |             ^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()`\n\nerror: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:104:13\n   |\nLL |     let _ = pathbuf.to_path_buf();\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `pathbuf.clone()`\n\nerror: implicitly cloning a `OsString` by calling `to_owned` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:108:13\n   |\nLL |     let _ = os_string.to_owned();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()`\n\nerror: implicitly cloning a `OsString` by calling `to_os_string` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:110:13\n   |\nLL |     let _ = os_string.to_os_string();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `os_string.clone()`\n\nerror: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:122:13\n   |\nLL |     let _ = pathbuf_ref.to_path_buf();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(*pathbuf_ref).clone()`\n\nerror: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:126:13\n   |\nLL |     let _ = pathbuf_ref.to_path_buf();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(**pathbuf_ref).clone()`\n\nerror: implicitly cloning a `String` by calling `to_owned` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:140:13\n   |\nLL |     let _ = s.to_owned();\n   |             ^^^^^^^^^^^^ help: consider using: `s.clone()`\n\nerror: implicitly cloning a `String` by calling `to_string` on its dereferenced type\n  --> tests/ui/implicit_clone.rs:142:13\n   |\nLL |     let _ = s.to_string();\n   |             ^^^^^^^^^^^^^ help: consider using: `s.clone()`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/implicit_hasher.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![deny(clippy::implicit_hasher)]\n\n#[macro_use]\nextern crate proc_macros;\n\nuse std::cmp::Eq;\nuse std::collections::{HashMap, HashSet};\nuse std::hash::{BuildHasher, Hash};\n\npub trait Foo<T>: Sized {\n    fn make() -> (Self, Self);\n}\n\nimpl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashMap<K, V, S> {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        // OK, don't suggest to modify these\n        let _: HashMap<i32, i32> = HashMap::new();\n        let _: HashSet<i32> = HashSet::new();\n\n        (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))\n    }\n}\nimpl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for (HashMap<K, V, S>,) {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),))\n    }\n}\nimpl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashMap<String, String, S> {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))\n    }\n}\n\nimpl<K: Hash + Eq, V, S: BuildHasher + Default> Foo<i32> for HashMap<K, V, S> {\n    fn make() -> (Self, Self) {\n        (HashMap::default(), HashMap::with_capacity_and_hasher(10, S::default()))\n    }\n}\nimpl<S: BuildHasher + Default> Foo<i64> for HashMap<String, String, S> {\n    fn make() -> (Self, Self) {\n        (HashMap::default(), HashMap::with_capacity_and_hasher(10, S::default()))\n    }\n}\n\nimpl<T: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashSet<T, S> {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))\n    }\n}\nimpl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashSet<String, S> {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))\n    }\n}\n\nimpl<T: Hash + Eq, S: BuildHasher + Default> Foo<i32> for HashSet<T, S> {\n    fn make() -> (Self, Self) {\n        (HashSet::default(), HashSet::with_capacity_and_hasher(10, S::default()))\n    }\n}\nimpl<S: BuildHasher + Default> Foo<i64> for HashSet<String, S> {\n    fn make() -> (Self, Self) {\n        (HashSet::default(), HashSet::with_capacity_and_hasher(10, S::default()))\n    }\n}\n\npub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {}\n//~^ implicit_hasher\n\npub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {}\n//~^ implicit_hasher\n\n#[inline_macros]\npub mod gen_ {\n    use super::*;\n    inline! {\n        impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {\n        //~^ implicit_hasher\n            fn make() -> (Self, Self) {\n                (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))\n            }\n        }\n\n        pub fn bar(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}\n    }\n}\n\n// When the macro is in a different file, the suggestion spans can't be combined properly\n// and should not cause an ICE\n// See #2707\n#[macro_use]\n#[path = \"auxiliary/test_macro.rs\"]\npub mod test_macro;\n__implicit_hasher_test_macro!(impl<K, V> for HashMap<K, V> where V: test_macro::A);\n\n// #4260\nexternal! {\n    pub fn f(input: &HashMap<u32, u32>) {}\n}\n\n// #7712\npub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}\n//~^ implicit_hasher\n\nfn main() {}\n\nmod issue16128 {\n    use super::*;\n\n    macro_rules! times_ten {\n        ($num:expr) => {\n            $num * 10\n        };\n    }\n\n    impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashMap<K, V, S> {\n        //~^ implicit_hasher\n        fn make() -> (Self, Self) {\n            (HashMap::default(), HashMap::with_capacity_and_hasher(times_ten!(5), Default::default()))\n        }\n    }\n\n    impl<V: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashSet<V, S> {\n        //~^ implicit_hasher\n        fn make() -> (Self, Self) {\n            (HashSet::default(), HashSet::with_capacity_and_hasher(times_ten!(5), Default::default()))\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/implicit_hasher.rs",
    "content": "//@aux-build:proc_macros.rs\n#![deny(clippy::implicit_hasher)]\n\n#[macro_use]\nextern crate proc_macros;\n\nuse std::cmp::Eq;\nuse std::collections::{HashMap, HashSet};\nuse std::hash::{BuildHasher, Hash};\n\npub trait Foo<T>: Sized {\n    fn make() -> (Self, Self);\n}\n\nimpl<K: Hash + Eq, V> Foo<i8> for HashMap<K, V> {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        // OK, don't suggest to modify these\n        let _: HashMap<i32, i32> = HashMap::new();\n        let _: HashSet<i32> = HashSet::new();\n\n        (HashMap::new(), HashMap::with_capacity(10))\n    }\n}\nimpl<K: Hash + Eq, V> Foo<i8> for (HashMap<K, V>,) {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        ((HashMap::new(),), (HashMap::with_capacity(10),))\n    }\n}\nimpl Foo<i16> for HashMap<String, String> {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        (HashMap::new(), HashMap::with_capacity(10))\n    }\n}\n\nimpl<K: Hash + Eq, V, S: BuildHasher + Default> Foo<i32> for HashMap<K, V, S> {\n    fn make() -> (Self, Self) {\n        (HashMap::default(), HashMap::with_capacity_and_hasher(10, S::default()))\n    }\n}\nimpl<S: BuildHasher + Default> Foo<i64> for HashMap<String, String, S> {\n    fn make() -> (Self, Self) {\n        (HashMap::default(), HashMap::with_capacity_and_hasher(10, S::default()))\n    }\n}\n\nimpl<T: Hash + Eq> Foo<i8> for HashSet<T> {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        (HashSet::new(), HashSet::with_capacity(10))\n    }\n}\nimpl Foo<i16> for HashSet<String> {\n    //~^ implicit_hasher\n    fn make() -> (Self, Self) {\n        (HashSet::new(), HashSet::with_capacity(10))\n    }\n}\n\nimpl<T: Hash + Eq, S: BuildHasher + Default> Foo<i32> for HashSet<T, S> {\n    fn make() -> (Self, Self) {\n        (HashSet::default(), HashSet::with_capacity_and_hasher(10, S::default()))\n    }\n}\nimpl<S: BuildHasher + Default> Foo<i64> for HashSet<String, S> {\n    fn make() -> (Self, Self) {\n        (HashSet::default(), HashSet::with_capacity_and_hasher(10, S::default()))\n    }\n}\n\npub fn map(map: &mut HashMap<i32, i32>) {}\n//~^ implicit_hasher\n\npub fn set(set: &mut HashSet<i32>) {}\n//~^ implicit_hasher\n\n#[inline_macros]\npub mod gen_ {\n    use super::*;\n    inline! {\n        impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {\n        //~^ implicit_hasher\n            fn make() -> (Self, Self) {\n                (HashMap::new(), HashMap::with_capacity(10))\n            }\n        }\n\n        pub fn bar(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}\n    }\n}\n\n// When the macro is in a different file, the suggestion spans can't be combined properly\n// and should not cause an ICE\n// See #2707\n#[macro_use]\n#[path = \"auxiliary/test_macro.rs\"]\npub mod test_macro;\n__implicit_hasher_test_macro!(impl<K, V> for HashMap<K, V> where V: test_macro::A);\n\n// #4260\nexternal! {\n    pub fn f(input: &HashMap<u32, u32>) {}\n}\n\n// #7712\npub async fn election_vote(_data: HashMap<i32, i32>) {}\n//~^ implicit_hasher\n\nfn main() {}\n\nmod issue16128 {\n    use super::*;\n\n    macro_rules! times_ten {\n        ($num:expr) => {\n            $num * 10\n        };\n    }\n\n    impl<K: Hash + Eq, V> Foo<u64> for HashMap<K, V> {\n        //~^ implicit_hasher\n        fn make() -> (Self, Self) {\n            (HashMap::new(), HashMap::with_capacity(times_ten!(5)))\n        }\n    }\n\n    impl<V: Hash + Eq> Foo<u64> for HashSet<V> {\n        //~^ implicit_hasher\n        fn make() -> (Self, Self) {\n            (HashSet::new(), HashSet::with_capacity(times_ten!(5)))\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/implicit_hasher.stderr",
    "content": "error: impl for `HashMap` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:15:35\n   |\nLL | impl<K: Hash + Eq, V> Foo<i8> for HashMap<K, V> {\n   |                                   ^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/implicit_hasher.rs:2:9\n   |\nLL | #![deny(clippy::implicit_hasher)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~ impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashMap<K, V, S> {\nLL |\n...\nLL |\nLL ~         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))\n   |\n\nerror: impl for `HashMap` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:25:36\n   |\nLL | impl<K: Hash + Eq, V> Foo<i8> for (HashMap<K, V>,) {\n   |                                    ^^^^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~ impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<i8> for (HashMap<K, V, S>,) {\nLL |\nLL |     fn make() -> (Self, Self) {\nLL ~         ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Default::default()),))\n   |\n\nerror: impl for `HashMap` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:31:19\n   |\nLL | impl Foo<i16> for HashMap<String, String> {\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~ impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashMap<String, String, S> {\nLL |\nLL |     fn make() -> (Self, Self) {\nLL ~         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))\n   |\n\nerror: impl for `HashSet` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:49:32\n   |\nLL | impl<T: Hash + Eq> Foo<i8> for HashSet<T> {\n   |                                ^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~ impl<T: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<i8> for HashSet<T, S> {\nLL |\nLL |     fn make() -> (Self, Self) {\nLL ~         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))\n   |\n\nerror: impl for `HashSet` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:55:19\n   |\nLL | impl Foo<i16> for HashSet<String> {\n   |                   ^^^^^^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~ impl<S: ::std::hash::BuildHasher + Default> Foo<i16> for HashSet<String, S> {\nLL |\nLL |     fn make() -> (Self, Self) {\nLL ~         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default::default()))\n   |\n\nerror: parameter of type `HashMap` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:73:22\n   |\nLL | pub fn map(map: &mut HashMap<i32, i32>) {}\n   |                      ^^^^^^^^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL | pub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {}\n   |           +++++++++++++++++++++++++++++                           +++\n\nerror: parameter of type `HashSet` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:76:22\n   |\nLL | pub fn set(set: &mut HashSet<i32>) {}\n   |                      ^^^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL | pub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {}\n   |           +++++++++++++++++++++++++++++                      +++\n\nerror: impl for `HashMap` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:83:43\n   |\nLL |         impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {\n   |                                           ^^^^^^^^^^^^^\n   |\n   = note: this error originates in the macro `__inline_mac_mod_gen_` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~         impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {\nLL |\nLL |             fn make() -> (Self, Self) {\nLL ~                 (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default::default()))\n   |\n\nerror: parameter of type `HashMap` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:108:35\n   |\nLL | pub async fn election_vote(_data: HashMap<i32, i32>) {}\n   |                                   ^^^^^^^^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL | pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}\n   |                           +++++++++++++++++++++++++++++                        +++\n\nerror: impl for `HashMap` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:122:40\n   |\nLL |     impl<K: Hash + Eq, V> Foo<u64> for HashMap<K, V> {\n   |                                        ^^^^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~     impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashMap<K, V, S> {\nLL |\nLL |         fn make() -> (Self, Self) {\nLL ~             (HashMap::default(), HashMap::with_capacity_and_hasher(times_ten!(5), Default::default()))\n   |\n\nerror: impl for `HashSet` should be generalized over different hashers\n  --> tests/ui/implicit_hasher.rs:129:37\n   |\nLL |     impl<V: Hash + Eq> Foo<u64> for HashSet<V> {\n   |                                     ^^^^^^^^^^\n   |\nhelp: add a type parameter for `BuildHasher`\n   |\nLL ~     impl<V: Hash + Eq, S: ::std::hash::BuildHasher + Default> Foo<u64> for HashSet<V, S> {\nLL |\nLL |         fn make() -> (Self, Self) {\nLL ~             (HashSet::default(), HashSet::with_capacity_and_hasher(times_ten!(5), Default::default()))\n   |\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/implicit_return.fixed",
    "content": "//@aux-build: proc_macros.rs\n\n#![warn(clippy::implicit_return)]\n#![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nfn test_end_of_fn() -> bool {\n    if true {\n        // no error!\n        return true;\n    }\n\n    return true\n    //~^ implicit_return\n}\n\nfn test_if_block() -> bool {\n    if true { return true } else { return false }\n    //~^ implicit_return\n    //~| implicit_return\n}\n\n#[rustfmt::skip]\nfn test_match(x: bool) -> bool {\n    match x {\n        true => return false,\n        //~^ implicit_return\n        false => { return true },\n        //~^ implicit_return\n    }\n}\n\nfn test_match_with_unreachable(x: bool) -> bool {\n    match x {\n        true => return false,\n        false => unreachable!(),\n    }\n}\n\nfn test_loop() -> bool {\n    loop {\n        return true;\n        //~^ implicit_return\n    }\n}\n\nfn test_loop_with_block() -> bool {\n    loop {\n        {\n            return true;\n            //~^ implicit_return\n        }\n    }\n}\n\nfn test_loop_with_nests() -> bool {\n    loop {\n        if true {\n            return true;\n            //~^ implicit_return\n        } else {\n            let _ = true;\n        }\n    }\n}\n\n#[allow(clippy::redundant_pattern_matching)]\nfn test_loop_with_if_let() -> bool {\n    loop {\n        if let Some(x) = Some(true) {\n            return x;\n        }\n    }\n}\n\nfn test_closure() {\n    #[rustfmt::skip]\n    let _ = || { return true };\n    //~^ implicit_return\n    let _ = || return true;\n    //~^ implicit_return\n}\n\nfn test_panic() -> bool {\n    panic!()\n}\n\nfn test_return_macro() -> String {\n    return format!(\"test {}\", \"test\")\n    //~^ implicit_return\n}\n\nfn macro_branch_test() -> bool {\n    macro_rules! m {\n        ($t:expr, $f:expr) => {\n            if true { $t } else { $f }\n        };\n    }\n    return m!(true, false)\n    //~^ implicit_return\n}\n\nfn loop_test() -> bool {\n    'outer: loop {\n        if true {\n            return true;\n            //~^ implicit_return\n        }\n\n        let _ = loop {\n            if false {\n                return false;\n                //~^ implicit_return\n            }\n            if true {\n                break true;\n            }\n        };\n    }\n}\n\nfn loop_macro_test() -> bool {\n    macro_rules! m {\n        ($e:expr) => {\n            break $e\n        };\n    }\n    return loop {\n        m!(true);\n    }\n}\n//~^^^^ implicit_return\n\nfn divergent_test() -> bool {\n    fn diverge() -> ! {\n        panic!()\n    }\n    diverge()\n}\n\n// issue #6940\nasync fn foo() -> bool {\n    return true\n    //~^ implicit_return\n}\n\nfn main() {}\n\nfn check_expect() -> bool {\n    if true {\n        // no error!\n        return true;\n    }\n\n    #[expect(clippy::implicit_return)]\n    true\n}\n\nwith_span!(\n    span\n\n    fn dont_lint_proc_macro(x: usize) -> usize{\n        x\n    }\n);\n\nfn desugared_closure_14446() {\n    let _ = async || return 0;\n    //~^ implicit_return\n    #[rustfmt::skip]\n    let _ = async || -> i32 { return 0 };\n    //~^ implicit_return\n    let _ = async |a: i32| return a;\n    //~^ implicit_return\n    #[rustfmt::skip]\n    let _ = async |a: i32| { return a };\n    //~^ implicit_return\n\n    let _ = async || return 0;\n    let _ = async || -> i32 { return 0 };\n    let _ = async |a: i32| return a;\n    #[rustfmt::skip]\n    let _ = async |a: i32| { return a; };\n\n    let _ = async || return foo().await;\n    //~^ implicit_return\n    let _ = async || {\n        foo().await;\n        return foo().await\n    };\n    //~^^ implicit_return\n    #[rustfmt::skip]\n    let _ = async || { return foo().await };\n    //~^ implicit_return\n    let _ = async || -> bool { return foo().await };\n    //~^ implicit_return\n\n    let _ = async || return foo().await;\n    let _ = async || {\n        foo().await;\n        return foo().await;\n    };\n    #[rustfmt::skip]\n    let _ = async || { return foo().await; };\n    let _ = async || -> bool {\n        return foo().await;\n    };\n}\n"
  },
  {
    "path": "tests/ui/implicit_return.rs",
    "content": "//@aux-build: proc_macros.rs\n\n#![warn(clippy::implicit_return)]\n#![allow(clippy::needless_return, clippy::needless_bool, unused, clippy::never_loop)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nfn test_end_of_fn() -> bool {\n    if true {\n        // no error!\n        return true;\n    }\n\n    true\n    //~^ implicit_return\n}\n\nfn test_if_block() -> bool {\n    if true { true } else { false }\n    //~^ implicit_return\n    //~| implicit_return\n}\n\n#[rustfmt::skip]\nfn test_match(x: bool) -> bool {\n    match x {\n        true => false,\n        //~^ implicit_return\n        false => { true },\n        //~^ implicit_return\n    }\n}\n\nfn test_match_with_unreachable(x: bool) -> bool {\n    match x {\n        true => return false,\n        false => unreachable!(),\n    }\n}\n\nfn test_loop() -> bool {\n    loop {\n        break true;\n        //~^ implicit_return\n    }\n}\n\nfn test_loop_with_block() -> bool {\n    loop {\n        {\n            break true;\n            //~^ implicit_return\n        }\n    }\n}\n\nfn test_loop_with_nests() -> bool {\n    loop {\n        if true {\n            break true;\n            //~^ implicit_return\n        } else {\n            let _ = true;\n        }\n    }\n}\n\n#[allow(clippy::redundant_pattern_matching)]\nfn test_loop_with_if_let() -> bool {\n    loop {\n        if let Some(x) = Some(true) {\n            return x;\n        }\n    }\n}\n\nfn test_closure() {\n    #[rustfmt::skip]\n    let _ = || { true };\n    //~^ implicit_return\n    let _ = || true;\n    //~^ implicit_return\n}\n\nfn test_panic() -> bool {\n    panic!()\n}\n\nfn test_return_macro() -> String {\n    format!(\"test {}\", \"test\")\n    //~^ implicit_return\n}\n\nfn macro_branch_test() -> bool {\n    macro_rules! m {\n        ($t:expr, $f:expr) => {\n            if true { $t } else { $f }\n        };\n    }\n    m!(true, false)\n    //~^ implicit_return\n}\n\nfn loop_test() -> bool {\n    'outer: loop {\n        if true {\n            break true;\n            //~^ implicit_return\n        }\n\n        let _ = loop {\n            if false {\n                break 'outer false;\n                //~^ implicit_return\n            }\n            if true {\n                break true;\n            }\n        };\n    }\n}\n\nfn loop_macro_test() -> bool {\n    macro_rules! m {\n        ($e:expr) => {\n            break $e\n        };\n    }\n    loop {\n        m!(true);\n    }\n}\n//~^^^^ implicit_return\n\nfn divergent_test() -> bool {\n    fn diverge() -> ! {\n        panic!()\n    }\n    diverge()\n}\n\n// issue #6940\nasync fn foo() -> bool {\n    true\n    //~^ implicit_return\n}\n\nfn main() {}\n\nfn check_expect() -> bool {\n    if true {\n        // no error!\n        return true;\n    }\n\n    #[expect(clippy::implicit_return)]\n    true\n}\n\nwith_span!(\n    span\n\n    fn dont_lint_proc_macro(x: usize) -> usize{\n        x\n    }\n);\n\nfn desugared_closure_14446() {\n    let _ = async || 0;\n    //~^ implicit_return\n    #[rustfmt::skip]\n    let _ = async || -> i32 { 0 };\n    //~^ implicit_return\n    let _ = async |a: i32| a;\n    //~^ implicit_return\n    #[rustfmt::skip]\n    let _ = async |a: i32| { a };\n    //~^ implicit_return\n\n    let _ = async || return 0;\n    let _ = async || -> i32 { return 0 };\n    let _ = async |a: i32| return a;\n    #[rustfmt::skip]\n    let _ = async |a: i32| { return a; };\n\n    let _ = async || foo().await;\n    //~^ implicit_return\n    let _ = async || {\n        foo().await;\n        foo().await\n    };\n    //~^^ implicit_return\n    #[rustfmt::skip]\n    let _ = async || { foo().await };\n    //~^ implicit_return\n    let _ = async || -> bool { foo().await };\n    //~^ implicit_return\n\n    let _ = async || return foo().await;\n    let _ = async || {\n        foo().await;\n        return foo().await;\n    };\n    #[rustfmt::skip]\n    let _ = async || { return foo().await; };\n    let _ = async || -> bool {\n        return foo().await;\n    };\n}\n"
  },
  {
    "path": "tests/ui/implicit_return.stderr",
    "content": "error: missing `return` statement\n  --> tests/ui/implicit_return.rs:15:5\n   |\nLL |     true\n   |     ^^^^\n   |\n   = note: `-D clippy::implicit-return` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::implicit_return)]`\nhelp: add `return` as shown\n   |\nLL |     return true\n   |     ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:20:15\n   |\nLL |     if true { true } else { false }\n   |               ^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     if true { return true } else { false }\n   |               ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:20:29\n   |\nLL |     if true { true } else { false }\n   |                             ^^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     if true { true } else { return false }\n   |                             ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:28:17\n   |\nLL |         true => false,\n   |                 ^^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |         true => return false,\n   |                 ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:30:20\n   |\nLL |         false => { true },\n   |                    ^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |         false => { return true },\n   |                    ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:44:9\n   |\nLL |         break true;\n   |         ^^^^^^^^^^\n   |\nhelp: change `break` to `return` as shown\n   |\nLL -         break true;\nLL +         return true;\n   |\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:52:13\n   |\nLL |             break true;\n   |             ^^^^^^^^^^\n   |\nhelp: change `break` to `return` as shown\n   |\nLL -             break true;\nLL +             return true;\n   |\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:61:13\n   |\nLL |             break true;\n   |             ^^^^^^^^^^\n   |\nhelp: change `break` to `return` as shown\n   |\nLL -             break true;\nLL +             return true;\n   |\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:80:18\n   |\nLL |     let _ = || { true };\n   |                  ^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = || { return true };\n   |                  ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:82:16\n   |\nLL |     let _ = || true;\n   |                ^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = || return true;\n   |                ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:91:5\n   |\nLL |     format!(\"test {}\", \"test\")\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     return format!(\"test {}\", \"test\")\n   |     ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:101:5\n   |\nLL |     m!(true, false)\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     return m!(true, false)\n   |     ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:108:13\n   |\nLL |             break true;\n   |             ^^^^^^^^^^\n   |\nhelp: change `break` to `return` as shown\n   |\nLL -             break true;\nLL +             return true;\n   |\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:114:17\n   |\nLL |                 break 'outer false;\n   |                 ^^^^^^^^^^^^^^^^^^\n   |\nhelp: change `break` to `return` as shown\n   |\nLL -                 break 'outer false;\nLL +                 return false;\n   |\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:130:5\n   |\nLL | /     loop {\nLL | |         m!(true);\nLL | |     }\n   | |_____^\n   |\nhelp: add `return` as shown\n   |\nLL |     return loop {\n   |     ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:145:5\n   |\nLL |     true\n   |     ^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     return true\n   |     ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:170:22\n   |\nLL |     let _ = async || 0;\n   |                      ^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = async || return 0;\n   |                      ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:173:31\n   |\nLL |     let _ = async || -> i32 { 0 };\n   |                               ^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = async || -> i32 { return 0 };\n   |                               ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:175:28\n   |\nLL |     let _ = async |a: i32| a;\n   |                            ^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = async |a: i32| return a;\n   |                            ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:178:30\n   |\nLL |     let _ = async |a: i32| { a };\n   |                              ^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = async |a: i32| { return a };\n   |                              ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:187:22\n   |\nLL |     let _ = async || foo().await;\n   |                      ^^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = async || return foo().await;\n   |                      ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:191:9\n   |\nLL |         foo().await\n   |         ^^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |         return foo().await\n   |         ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:195:24\n   |\nLL |     let _ = async || { foo().await };\n   |                        ^^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = async || { return foo().await };\n   |                        ++++++\n\nerror: missing `return` statement\n  --> tests/ui/implicit_return.rs:197:32\n   |\nLL |     let _ = async || -> bool { foo().await };\n   |                                ^^^^^\n   |\nhelp: add `return` as shown\n   |\nLL |     let _ = async || -> bool { return foo().await };\n   |                                ++++++\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/implicit_saturating_add.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::implicit_saturating_add)]\n\nfn main() {\n    let mut u_8: u8 = 255;\n    let mut u_16: u16 = 500;\n    let mut u_32: u32 = 7000;\n    let mut u_64: u64 = 7000;\n    let mut i_8: i8 = 30;\n    let mut i_16: i16 = 500;\n    let mut i_32: i32 = 7000;\n    let mut i_64: i64 = 7000;\n\n    if i_8 < 42 {\n        i_8 += 1;\n    }\n    if i_8 != 42 {\n        i_8 += 1;\n    }\n\n    u_8 = u_8.saturating_add(1);\n\n    u_8 = u_8.saturating_add(1);\n\n    if u_8 < 15 {\n        u_8 += 1;\n    }\n\n    u_16 = u_16.saturating_add(1);\n\n    u_16 = u_16.saturating_add(1);\n\n    u_16 = u_16.saturating_add(1);\n\n    u_32 = u_32.saturating_add(1);\n\n    u_32 = u_32.saturating_add(1);\n\n    u_32 = u_32.saturating_add(1);\n\n    u_64 = u_64.saturating_add(1);\n\n    u_64 = u_64.saturating_add(1);\n\n    u_64 = u_64.saturating_add(1);\n\n    i_8 = i_8.saturating_add(1);\n\n    i_8 = i_8.saturating_add(1);\n\n    i_8 = i_8.saturating_add(1);\n\n    i_16 = i_16.saturating_add(1);\n\n    i_16 = i_16.saturating_add(1);\n\n    i_16 = i_16.saturating_add(1);\n\n    i_32 = i_32.saturating_add(1);\n\n    i_32 = i_32.saturating_add(1);\n\n    i_32 = i_32.saturating_add(1);\n\n    i_64 = i_64.saturating_add(1);\n\n    i_64 = i_64.saturating_add(1);\n\n    i_64 = i_64.saturating_add(1);\n\n    if i_64 < 42 {\n        i_64 += 1;\n    }\n\n    if 42 > i_64 {\n        i_64 += 1;\n    }\n\n    let a = 12;\n    let mut b = 8;\n\n    if a < u8::MAX {\n        b += 1;\n    }\n\n    if u8::MAX > a {\n        b += 1;\n    }\n\n    if u_32 < u32::MAX {\n        u_32 += 1;\n    } else {\n        println!(\"don't lint this\");\n    }\n\n    if u_32 < u32::MAX {\n        println!(\"don't lint this\");\n        u_32 += 1;\n    }\n\n    if u_32 < 42 {\n        println!(\"brace yourself!\");\n    } else {u_32 = u_32.saturating_add(1); }\n}\n"
  },
  {
    "path": "tests/ui/implicit_saturating_add.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::implicit_saturating_add)]\n\nfn main() {\n    let mut u_8: u8 = 255;\n    let mut u_16: u16 = 500;\n    let mut u_32: u32 = 7000;\n    let mut u_64: u64 = 7000;\n    let mut i_8: i8 = 30;\n    let mut i_16: i16 = 500;\n    let mut i_32: i32 = 7000;\n    let mut i_64: i64 = 7000;\n\n    if i_8 < 42 {\n        i_8 += 1;\n    }\n    if i_8 != 42 {\n        i_8 += 1;\n    }\n\n    if u_8 != u8::MAX {\n        //~^ implicit_saturating_add\n        u_8 += 1;\n    }\n\n    if u_8 < u8::MAX {\n        //~^ implicit_saturating_add\n        u_8 += 1;\n    }\n\n    if u_8 < 15 {\n        u_8 += 1;\n    }\n\n    if u_16 != u16::MAX {\n        //~^ implicit_saturating_add\n        u_16 += 1;\n    }\n\n    if u_16 < u16::MAX {\n        //~^ implicit_saturating_add\n        u_16 += 1;\n    }\n\n    if u16::MAX > u_16 {\n        //~^ implicit_saturating_add\n        u_16 += 1;\n    }\n\n    if u_32 != u32::MAX {\n        //~^ implicit_saturating_add\n        u_32 += 1;\n    }\n\n    if u_32 < u32::MAX {\n        //~^ implicit_saturating_add\n        u_32 += 1;\n    }\n\n    if u32::MAX > u_32 {\n        //~^ implicit_saturating_add\n        u_32 += 1;\n    }\n\n    if u_64 != u64::MAX {\n        //~^ implicit_saturating_add\n        u_64 += 1;\n    }\n\n    if u_64 < u64::MAX {\n        //~^ implicit_saturating_add\n        u_64 += 1;\n    }\n\n    if u64::MAX > u_64 {\n        //~^ implicit_saturating_add\n        u_64 += 1;\n    }\n\n    if i_8 != i8::MAX {\n        //~^ implicit_saturating_add\n        i_8 += 1;\n    }\n\n    if i_8 < i8::MAX {\n        //~^ implicit_saturating_add\n        i_8 += 1;\n    }\n\n    if i8::MAX > i_8 {\n        //~^ implicit_saturating_add\n        i_8 += 1;\n    }\n\n    if i_16 != i16::MAX {\n        //~^ implicit_saturating_add\n        i_16 += 1;\n    }\n\n    if i_16 < i16::MAX {\n        //~^ implicit_saturating_add\n        i_16 += 1;\n    }\n\n    if i16::MAX > i_16 {\n        //~^ implicit_saturating_add\n        i_16 += 1;\n    }\n\n    if i_32 != i32::MAX {\n        //~^ implicit_saturating_add\n        i_32 += 1;\n    }\n\n    if i_32 < i32::MAX {\n        //~^ implicit_saturating_add\n        i_32 += 1;\n    }\n\n    if i32::MAX > i_32 {\n        //~^ implicit_saturating_add\n        i_32 += 1;\n    }\n\n    if i_64 != i64::MAX {\n        //~^ implicit_saturating_add\n        i_64 += 1;\n    }\n\n    if i_64 < i64::MAX {\n        //~^ implicit_saturating_add\n        i_64 += 1;\n    }\n\n    if i64::MAX > i_64 {\n        //~^ implicit_saturating_add\n        i_64 += 1;\n    }\n\n    if i_64 < 42 {\n        i_64 += 1;\n    }\n\n    if 42 > i_64 {\n        i_64 += 1;\n    }\n\n    let a = 12;\n    let mut b = 8;\n\n    if a < u8::MAX {\n        b += 1;\n    }\n\n    if u8::MAX > a {\n        b += 1;\n    }\n\n    if u_32 < u32::MAX {\n        u_32 += 1;\n    } else {\n        println!(\"don't lint this\");\n    }\n\n    if u_32 < u32::MAX {\n        println!(\"don't lint this\");\n        u_32 += 1;\n    }\n\n    if u_32 < 42 {\n        println!(\"brace yourself!\");\n    } else if u_32 < u32::MAX {\n        //~^ implicit_saturating_add\n        u_32 += 1;\n    }\n}\n"
  },
  {
    "path": "tests/ui/implicit_saturating_add.stderr",
    "content": "error: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:21:5\n   |\nLL | /     if u_8 != u8::MAX {\nLL | |\nLL | |         u_8 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_8 = u_8.saturating_add(1);`\n   |\n   = note: `-D clippy::implicit-saturating-add` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_add)]`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:26:5\n   |\nLL | /     if u_8 < u8::MAX {\nLL | |\nLL | |         u_8 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_8 = u_8.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:35:5\n   |\nLL | /     if u_16 != u16::MAX {\nLL | |\nLL | |         u_16 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:40:5\n   |\nLL | /     if u_16 < u16::MAX {\nLL | |\nLL | |         u_16 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:45:5\n   |\nLL | /     if u16::MAX > u_16 {\nLL | |\nLL | |         u_16 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_16 = u_16.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:50:5\n   |\nLL | /     if u_32 != u32::MAX {\nLL | |\nLL | |         u_32 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:55:5\n   |\nLL | /     if u_32 < u32::MAX {\nLL | |\nLL | |         u_32 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:60:5\n   |\nLL | /     if u32::MAX > u_32 {\nLL | |\nLL | |         u_32 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_32 = u_32.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:65:5\n   |\nLL | /     if u_64 != u64::MAX {\nLL | |\nLL | |         u_64 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:70:5\n   |\nLL | /     if u_64 < u64::MAX {\nLL | |\nLL | |         u_64 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:75:5\n   |\nLL | /     if u64::MAX > u_64 {\nLL | |\nLL | |         u_64 += 1;\nLL | |     }\n   | |_____^ help: use instead: `u_64 = u_64.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:80:5\n   |\nLL | /     if i_8 != i8::MAX {\nLL | |\nLL | |         i_8 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:85:5\n   |\nLL | /     if i_8 < i8::MAX {\nLL | |\nLL | |         i_8 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:90:5\n   |\nLL | /     if i8::MAX > i_8 {\nLL | |\nLL | |         i_8 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_8 = i_8.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:95:5\n   |\nLL | /     if i_16 != i16::MAX {\nLL | |\nLL | |         i_16 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:100:5\n   |\nLL | /     if i_16 < i16::MAX {\nLL | |\nLL | |         i_16 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:105:5\n   |\nLL | /     if i16::MAX > i_16 {\nLL | |\nLL | |         i_16 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_16 = i_16.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:110:5\n   |\nLL | /     if i_32 != i32::MAX {\nLL | |\nLL | |         i_32 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:115:5\n   |\nLL | /     if i_32 < i32::MAX {\nLL | |\nLL | |         i_32 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:120:5\n   |\nLL | /     if i32::MAX > i_32 {\nLL | |\nLL | |         i_32 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_32 = i_32.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:125:5\n   |\nLL | /     if i_64 != i64::MAX {\nLL | |\nLL | |         i_64 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:130:5\n   |\nLL | /     if i_64 < i64::MAX {\nLL | |\nLL | |         i_64 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:135:5\n   |\nLL | /     if i64::MAX > i_64 {\nLL | |\nLL | |         i_64 += 1;\nLL | |     }\n   | |_____^ help: use instead: `i_64 = i_64.saturating_add(1);`\n\nerror: manual saturating add detected\n  --> tests/ui/implicit_saturating_add.rs:172:12\n   |\nLL |       } else if u_32 < u32::MAX {\n   |  ____________^\nLL | |\nLL | |         u_32 += 1;\nLL | |     }\n   | |_____^ help: use instead: `{u_32 = u_32.saturating_add(1); }`\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/implicit_saturating_sub.fixed",
    "content": "#![allow(unused_assignments, unused_mut, clippy::assign_op_pattern)]\n#![warn(clippy::implicit_saturating_sub)]\n\nuse std::cmp::PartialEq;\nuse std::ops::SubAssign;\n// Mock type\nstruct Mock;\n\nimpl PartialEq<u32> for Mock {\n    fn eq(&self, _: &u32) -> bool {\n        true\n    }\n}\n\nimpl SubAssign<u32> for Mock {\n    fn sub_assign(&mut self, _: u32) {}\n}\n\nfn main() {\n    // Tests for unsigned integers\n\n    let end_8: u8 = 10;\n    let start_8: u8 = 5;\n    let mut u_8: u8 = end_8 - start_8;\n\n    // Lint\n    u_8 = u_8.saturating_sub(1);\n\n    match end_8 {\n        10 => {\n            // Lint\n            u_8 = u_8.saturating_sub(1);\n        },\n        11 => u_8 += 1,\n        _ => u_8 = 0,\n    }\n\n    let end_16: u16 = 40;\n    let start_16: u16 = 35;\n\n    let mut u_16: u16 = end_16 - start_16;\n\n    // Lint\n    u_16 = u_16.saturating_sub(1);\n\n    let mut end_32: u32 = 7010;\n    let mut start_32: u32 = 7000;\n\n    let mut u_32: u32 = end_32 - start_32;\n\n    // Lint\n    u_32 = u_32.saturating_sub(1);\n\n    // No Lint\n    if u_32 > 0 {\n        u_16 += 1;\n    }\n\n    // No Lint\n    if u_32 != 0 {\n        end_32 -= 1;\n        start_32 += 1;\n    }\n\n    let mut end_64: u64 = 75001;\n    let mut start_64: u64 = 75000;\n\n    let mut u_64: u64 = end_64 - start_64;\n\n    // Lint\n    u_64 = u_64.saturating_sub(1);\n\n    // Lint\n    u_64 = u_64.saturating_sub(1);\n\n    // Lint\n    u_64 = u_64.saturating_sub(1);\n\n    // No Lint\n    if u_64 >= 1 {\n        u_64 -= 1;\n    }\n\n    // No Lint\n    if u_64 > 0 {\n        end_64 -= 1;\n    }\n\n    // Tests for usize\n    let end_usize: usize = 8054;\n    let start_usize: usize = 8050;\n\n    let mut u_usize: usize = end_usize - start_usize;\n\n    // Lint\n    u_usize = u_usize.saturating_sub(1);\n\n    // Tests for signed integers\n\n    let endi_8: i8 = 10;\n    let starti_8: i8 = 50;\n\n    let mut i_8: i8 = endi_8 - starti_8;\n\n    // Lint\n    i_8 = i_8.saturating_sub(1);\n\n    // Lint\n    i_8 = i_8.saturating_sub(1);\n\n    // Lint\n    i_8 = i_8.saturating_sub(1);\n\n    // Lint\n    i_8 = i_8.saturating_sub(1);\n\n    let endi_16: i16 = 45;\n    let starti_16: i16 = 44;\n\n    let mut i_16: i16 = endi_16 - starti_16;\n\n    // Lint\n    i_16 = i_16.saturating_sub(1);\n\n    // Lint\n    i_16 = i_16.saturating_sub(1);\n\n    // Lint\n    i_16 = i_16.saturating_sub(1);\n\n    // Lint\n    i_16 = i_16.saturating_sub(1);\n\n    let endi_32: i32 = 45;\n    let starti_32: i32 = 44;\n\n    let mut i_32: i32 = endi_32 - starti_32;\n\n    // Lint\n    i_32 = i_32.saturating_sub(1);\n\n    // Lint\n    i_32 = i_32.saturating_sub(1);\n\n    // Lint\n    i_32 = i_32.saturating_sub(1);\n\n    // Lint\n    i_32 = i_32.saturating_sub(1);\n\n    let endi_64: i64 = 45;\n    let starti_64: i64 = 44;\n\n    let mut i_64: i64 = endi_64 - starti_64;\n\n    // Lint\n    i_64 = i_64.saturating_sub(1);\n\n    // Lint\n    i_64 = i_64.saturating_sub(1);\n\n    // Lint\n    i_64 = i_64.saturating_sub(1);\n\n    // No Lint\n    if i_64 > 0 {\n        i_64 -= 1;\n    }\n\n    // No Lint\n    if i_64 != 0 {\n        i_64 -= 1;\n    }\n\n    // issue #7831\n    // No Lint\n    if u_32 > 0 {\n        u_32 -= 1;\n    } else {\n        println!(\"side effect\");\n    }\n\n    // Extended tests\n    let mut m = Mock;\n    let mut u_32 = 3000;\n    let a = 200;\n    let mut b = 8;\n\n    if m != 0 {\n        m -= 1;\n    }\n\n    if a > 0 {\n        b -= 1;\n    }\n\n    if 0 > a {\n        b -= 1;\n    }\n\n    if u_32 > 0 {\n        u_32 -= 1;\n    } else {\n        println!(\"don't lint this\");\n    }\n\n    if u_32 > 0 {\n        println!(\"don't lint this\");\n        u_32 -= 1;\n    }\n\n    if u_32 > 42 {\n        println!(\"brace yourself!\");\n    } else if u_32 > 0 {\n        u_32 -= 1;\n    }\n\n    let result = if a < b {\n        println!(\"we shouldn't remove this\");\n        0\n    } else {\n        a - b\n    };\n}\n\nfn regression_13524(a: usize, b: usize, c: bool) -> usize {\n    if c {\n        123\n    } else { b.saturating_sub(a) }\n}\n\nfn with_side_effect(a: u64) -> u64 {\n    println!(\"a = {a}\");\n    a\n}\n\nfn arbitrary_expression() {\n    let (a, b) = (15u64, 20u64);\n\n    let _ = (a * 2).saturating_sub(b);\n    //~^ implicit_saturating_sub\n\n    let _ = a.saturating_sub(b * 2);\n    //~^ implicit_saturating_sub\n\n    let _ = a.saturating_sub(b * 2);\n    //~^ implicit_saturating_sub\n\n    let _ = if with_side_effect(a) > a {\n        with_side_effect(a) - a\n    } else {\n        0\n    };\n}\n\nfn issue16307() {\n    let x: u8 = 100;\n    let y = 100_u8.saturating_sub(x);\n    //~^ implicit_saturating_sub\n\n    println!(\"{y}\");\n}\n"
  },
  {
    "path": "tests/ui/implicit_saturating_sub.rs",
    "content": "#![allow(unused_assignments, unused_mut, clippy::assign_op_pattern)]\n#![warn(clippy::implicit_saturating_sub)]\n\nuse std::cmp::PartialEq;\nuse std::ops::SubAssign;\n// Mock type\nstruct Mock;\n\nimpl PartialEq<u32> for Mock {\n    fn eq(&self, _: &u32) -> bool {\n        true\n    }\n}\n\nimpl SubAssign<u32> for Mock {\n    fn sub_assign(&mut self, _: u32) {}\n}\n\nfn main() {\n    // Tests for unsigned integers\n\n    let end_8: u8 = 10;\n    let start_8: u8 = 5;\n    let mut u_8: u8 = end_8 - start_8;\n\n    // Lint\n    if u_8 > 0 {\n        //~^ implicit_saturating_sub\n        u_8 = u_8 - 1;\n    }\n\n    match end_8 {\n        10 => {\n            // Lint\n            if u_8 > 0 {\n                //~^ implicit_saturating_sub\n                u_8 -= 1;\n            }\n        },\n        11 => u_8 += 1,\n        _ => u_8 = 0,\n    }\n\n    let end_16: u16 = 40;\n    let start_16: u16 = 35;\n\n    let mut u_16: u16 = end_16 - start_16;\n\n    // Lint\n    if u_16 > 0 {\n        //~^ implicit_saturating_sub\n        u_16 -= 1;\n    }\n\n    let mut end_32: u32 = 7010;\n    let mut start_32: u32 = 7000;\n\n    let mut u_32: u32 = end_32 - start_32;\n\n    // Lint\n    if u_32 != 0 {\n        //~^ implicit_saturating_sub\n        u_32 -= 1;\n    }\n\n    // No Lint\n    if u_32 > 0 {\n        u_16 += 1;\n    }\n\n    // No Lint\n    if u_32 != 0 {\n        end_32 -= 1;\n        start_32 += 1;\n    }\n\n    let mut end_64: u64 = 75001;\n    let mut start_64: u64 = 75000;\n\n    let mut u_64: u64 = end_64 - start_64;\n\n    // Lint\n    if u_64 > 0 {\n        //~^ implicit_saturating_sub\n        u_64 -= 1;\n    }\n\n    // Lint\n    if 0 < u_64 {\n        //~^ implicit_saturating_sub\n        u_64 -= 1;\n    }\n\n    // Lint\n    if 0 != u_64 {\n        //~^ implicit_saturating_sub\n        u_64 -= 1;\n    }\n\n    // No Lint\n    if u_64 >= 1 {\n        u_64 -= 1;\n    }\n\n    // No Lint\n    if u_64 > 0 {\n        end_64 -= 1;\n    }\n\n    // Tests for usize\n    let end_usize: usize = 8054;\n    let start_usize: usize = 8050;\n\n    let mut u_usize: usize = end_usize - start_usize;\n\n    // Lint\n    if u_usize > 0 {\n        //~^ implicit_saturating_sub\n        u_usize -= 1;\n    }\n\n    // Tests for signed integers\n\n    let endi_8: i8 = 10;\n    let starti_8: i8 = 50;\n\n    let mut i_8: i8 = endi_8 - starti_8;\n\n    // Lint\n    if i_8 > i8::MIN {\n        //~^ implicit_saturating_sub\n        i_8 -= 1;\n    }\n\n    // Lint\n    if i_8 > i8::MIN {\n        //~^ implicit_saturating_sub\n        i_8 -= 1;\n    }\n\n    // Lint\n    if i_8 != i8::MIN {\n        //~^ implicit_saturating_sub\n        i_8 -= 1;\n    }\n\n    // Lint\n    if i_8 != i8::MIN {\n        //~^ implicit_saturating_sub\n        i_8 -= 1;\n    }\n\n    let endi_16: i16 = 45;\n    let starti_16: i16 = 44;\n\n    let mut i_16: i16 = endi_16 - starti_16;\n\n    // Lint\n    if i_16 > i16::MIN {\n        //~^ implicit_saturating_sub\n        i_16 -= 1;\n    }\n\n    // Lint\n    if i_16 > i16::MIN {\n        //~^ implicit_saturating_sub\n        i_16 -= 1;\n    }\n\n    // Lint\n    if i_16 != i16::MIN {\n        //~^ implicit_saturating_sub\n        i_16 -= 1;\n    }\n\n    // Lint\n    if i_16 != i16::MIN {\n        //~^ implicit_saturating_sub\n        i_16 -= 1;\n    }\n\n    let endi_32: i32 = 45;\n    let starti_32: i32 = 44;\n\n    let mut i_32: i32 = endi_32 - starti_32;\n\n    // Lint\n    if i_32 > i32::MIN {\n        //~^ implicit_saturating_sub\n        i_32 -= 1;\n    }\n\n    // Lint\n    if i_32 > i32::MIN {\n        //~^ implicit_saturating_sub\n        i_32 -= 1;\n    }\n\n    // Lint\n    if i_32 != i32::MIN {\n        //~^ implicit_saturating_sub\n        i_32 -= 1;\n    }\n\n    // Lint\n    if i_32 != i32::MIN {\n        //~^ implicit_saturating_sub\n        i_32 -= 1;\n    }\n\n    let endi_64: i64 = 45;\n    let starti_64: i64 = 44;\n\n    let mut i_64: i64 = endi_64 - starti_64;\n\n    // Lint\n    if i64::MIN < i_64 {\n        //~^ implicit_saturating_sub\n        i_64 -= 1;\n    }\n\n    // Lint\n    if i64::MIN != i_64 {\n        //~^ implicit_saturating_sub\n        i_64 -= 1;\n    }\n\n    // Lint\n    if i64::MIN < i_64 {\n        //~^ implicit_saturating_sub\n        i_64 -= 1;\n    }\n\n    // No Lint\n    if i_64 > 0 {\n        i_64 -= 1;\n    }\n\n    // No Lint\n    if i_64 != 0 {\n        i_64 -= 1;\n    }\n\n    // issue #7831\n    // No Lint\n    if u_32 > 0 {\n        u_32 -= 1;\n    } else {\n        println!(\"side effect\");\n    }\n\n    // Extended tests\n    let mut m = Mock;\n    let mut u_32 = 3000;\n    let a = 200;\n    let mut b = 8;\n\n    if m != 0 {\n        m -= 1;\n    }\n\n    if a > 0 {\n        b -= 1;\n    }\n\n    if 0 > a {\n        b -= 1;\n    }\n\n    if u_32 > 0 {\n        u_32 -= 1;\n    } else {\n        println!(\"don't lint this\");\n    }\n\n    if u_32 > 0 {\n        println!(\"don't lint this\");\n        u_32 -= 1;\n    }\n\n    if u_32 > 42 {\n        println!(\"brace yourself!\");\n    } else if u_32 > 0 {\n        u_32 -= 1;\n    }\n\n    let result = if a < b {\n        println!(\"we shouldn't remove this\");\n        0\n    } else {\n        a - b\n    };\n}\n\nfn regression_13524(a: usize, b: usize, c: bool) -> usize {\n    if c {\n        123\n    } else if a >= b {\n        //~^ implicit_saturating_sub\n        0\n    } else {\n        b - a\n    }\n}\n\nfn with_side_effect(a: u64) -> u64 {\n    println!(\"a = {a}\");\n    a\n}\n\nfn arbitrary_expression() {\n    let (a, b) = (15u64, 20u64);\n\n    let _ = if a * 2 > b { a * 2 - b } else { 0 };\n    //~^ implicit_saturating_sub\n\n    let _ = if a > b * 2 { a - b * 2 } else { 0 };\n    //~^ implicit_saturating_sub\n\n    let _ = if a < b * 2 { 0 } else { a - b * 2 };\n    //~^ implicit_saturating_sub\n\n    let _ = if with_side_effect(a) > a {\n        with_side_effect(a) - a\n    } else {\n        0\n    };\n}\n\nfn issue16307() {\n    let x: u8 = 100;\n    let y = if x >= 100 { 0 } else { 100 - x };\n    //~^ implicit_saturating_sub\n\n    println!(\"{y}\");\n}\n"
  },
  {
    "path": "tests/ui/implicit_saturating_sub.stderr",
    "content": "error: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:27:5\n   |\nLL | /     if u_8 > 0 {\nLL | |\nLL | |         u_8 = u_8 - 1;\nLL | |     }\n   | |_____^ help: try: `u_8 = u_8.saturating_sub(1);`\n   |\n   = note: `-D clippy::implicit-saturating-sub` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_sub)]`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:35:13\n   |\nLL | /             if u_8 > 0 {\nLL | |\nLL | |                 u_8 -= 1;\nLL | |             }\n   | |_____________^ help: try: `u_8 = u_8.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:50:5\n   |\nLL | /     if u_16 > 0 {\nLL | |\nLL | |         u_16 -= 1;\nLL | |     }\n   | |_____^ help: try: `u_16 = u_16.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:61:5\n   |\nLL | /     if u_32 != 0 {\nLL | |\nLL | |         u_32 -= 1;\nLL | |     }\n   | |_____^ help: try: `u_32 = u_32.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:83:5\n   |\nLL | /     if u_64 > 0 {\nLL | |\nLL | |         u_64 -= 1;\nLL | |     }\n   | |_____^ help: try: `u_64 = u_64.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:89:5\n   |\nLL | /     if 0 < u_64 {\nLL | |\nLL | |         u_64 -= 1;\nLL | |     }\n   | |_____^ help: try: `u_64 = u_64.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:95:5\n   |\nLL | /     if 0 != u_64 {\nLL | |\nLL | |         u_64 -= 1;\nLL | |     }\n   | |_____^ help: try: `u_64 = u_64.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:117:5\n   |\nLL | /     if u_usize > 0 {\nLL | |\nLL | |         u_usize -= 1;\nLL | |     }\n   | |_____^ help: try: `u_usize = u_usize.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:130:5\n   |\nLL | /     if i_8 > i8::MIN {\nLL | |\nLL | |         i_8 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_8 = i_8.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:136:5\n   |\nLL | /     if i_8 > i8::MIN {\nLL | |\nLL | |         i_8 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_8 = i_8.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:142:5\n   |\nLL | /     if i_8 != i8::MIN {\nLL | |\nLL | |         i_8 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_8 = i_8.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:148:5\n   |\nLL | /     if i_8 != i8::MIN {\nLL | |\nLL | |         i_8 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_8 = i_8.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:159:5\n   |\nLL | /     if i_16 > i16::MIN {\nLL | |\nLL | |         i_16 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_16 = i_16.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:165:5\n   |\nLL | /     if i_16 > i16::MIN {\nLL | |\nLL | |         i_16 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_16 = i_16.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:171:5\n   |\nLL | /     if i_16 != i16::MIN {\nLL | |\nLL | |         i_16 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_16 = i_16.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:177:5\n   |\nLL | /     if i_16 != i16::MIN {\nLL | |\nLL | |         i_16 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_16 = i_16.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:188:5\n   |\nLL | /     if i_32 > i32::MIN {\nLL | |\nLL | |         i_32 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_32 = i_32.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:194:5\n   |\nLL | /     if i_32 > i32::MIN {\nLL | |\nLL | |         i_32 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_32 = i_32.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:200:5\n   |\nLL | /     if i_32 != i32::MIN {\nLL | |\nLL | |         i_32 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_32 = i_32.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:206:5\n   |\nLL | /     if i_32 != i32::MIN {\nLL | |\nLL | |         i_32 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_32 = i_32.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:217:5\n   |\nLL | /     if i64::MIN < i_64 {\nLL | |\nLL | |         i_64 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_64 = i_64.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:223:5\n   |\nLL | /     if i64::MIN != i_64 {\nLL | |\nLL | |         i_64 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_64 = i_64.saturating_sub(1);`\n\nerror: implicitly performing saturating subtraction\n  --> tests/ui/implicit_saturating_sub.rs:229:5\n   |\nLL | /     if i64::MIN < i_64 {\nLL | |\nLL | |         i_64 -= 1;\nLL | |     }\n   | |_____^ help: try: `i_64 = i_64.saturating_sub(1);`\n\nerror: manual arithmetic check found\n  --> tests/ui/implicit_saturating_sub.rs:298:12\n   |\nLL |       } else if a >= b {\n   |  ____________^\nLL | |\nLL | |         0\nLL | |     } else {\nLL | |         b - a\nLL | |     }\n   | |_____^ help: replace it with: `{ b.saturating_sub(a) }`\n\nerror: manual arithmetic check found\n  --> tests/ui/implicit_saturating_sub.rs:314:13\n   |\nLL |     let _ = if a * 2 > b { a * 2 - b } else { 0 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `(a * 2).saturating_sub(b)`\n\nerror: manual arithmetic check found\n  --> tests/ui/implicit_saturating_sub.rs:317:13\n   |\nLL |     let _ = if a > b * 2 { a - b * 2 } else { 0 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b * 2)`\n\nerror: manual arithmetic check found\n  --> tests/ui/implicit_saturating_sub.rs:320:13\n   |\nLL |     let _ = if a < b * 2 { 0 } else { a - b * 2 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b * 2)`\n\nerror: manual arithmetic check found\n  --> tests/ui/implicit_saturating_sub.rs:332:13\n   |\nLL |     let y = if x >= 100 { 0 } else { 100 - x };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `100_u8.saturating_sub(x)`\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui/implied_bounds_in_impls.fixed",
    "content": "#![warn(clippy::implied_bounds_in_impls)]\n#![allow(dead_code)]\n#![feature(impl_trait_in_assoc_type, type_alias_impl_trait)]\n\nuse std::ops::{Deref, DerefMut};\n\n// Only one bound, nothing to lint.\nfn normal_deref<T>(x: T) -> impl Deref<Target = T> {\n    Box::new(x)\n}\n\n// Deref implied by DerefMut\nfn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> {\n    //~^ implied_bounds_in_impls\n    Box::new(x)\n}\n\ntrait GenericTrait<T> {}\ntrait GenericTrait2<V> {}\n// U is intentionally at a different \"index\" in GenericSubtrait than `T` is in GenericTrait,\n// so this can be a good test to make sure that the calculations are right (no off-by-one errors,\n// ...)\ntrait GenericSubtrait<T, U, V>: GenericTrait<U> + GenericTrait2<V> {}\n\nimpl GenericTrait<i32> for () {}\nimpl GenericTrait<i64> for () {}\nimpl<V> GenericTrait2<V> for () {}\nimpl<V> GenericSubtrait<(), i32, V> for () {}\nimpl<V> GenericSubtrait<(), i64, V> for () {}\n\nfn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U>\n//~^ implied_bounds_in_impls\nwhere\n    (): GenericSubtrait<U, W, U>,\n{\n}\n\nfn generics_implied_multi<V>() -> impl GenericSubtrait<(), i32, V> {}\n//~^ implied_bounds_in_impls\n//~| implied_bounds_in_impls\n\nfn generics_implied_multi2<T, V>() -> impl GenericSubtrait<(), T, V>\n//~^ implied_bounds_in_impls\n//~| implied_bounds_in_impls\nwhere\n    (): GenericSubtrait<(), T, V> + GenericTrait<T>,\n{\n}\n\n// i32 != i64, GenericSubtrait<_, i64, _> does not imply GenericTrait<i32>, don't lint\nfn generics_different() -> impl GenericTrait<i32> + GenericSubtrait<(), i64, ()> {}\n\n// i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait<i32>, lint\nfn generics_same() -> impl GenericSubtrait<(), i32, ()> {}\n//~^ implied_bounds_in_impls\n\ntrait SomeTrait {\n    // Check that it works in trait declarations.\n    fn f() -> impl DerefMut<Target = u8>;\n    //~^ implied_bounds_in_impls\n}\nstruct SomeStruct;\nimpl SomeStruct {\n    // Check that it works in inherent impl blocks.\n    fn f() -> impl DerefMut<Target = u8> {\n        //~^ implied_bounds_in_impls\n        Box::new(123)\n    }\n}\nimpl SomeTrait for SomeStruct {\n    // Check that it works in trait impls.\n    fn f() -> impl DerefMut<Target = u8> {\n        //~^ implied_bounds_in_impls\n        Box::new(42)\n    }\n}\n\nmod issue11422 {\n    use core::fmt::Debug;\n    // Some additional tests that would cause ICEs:\n\n    // `PartialOrd` has a default generic parameter and does not need to be explicitly specified.\n    // This needs special handling.\n    fn default_generic_param1() -> impl PartialOrd + Debug {}\n    //~^ implied_bounds_in_impls\n    fn default_generic_param2() -> impl PartialOrd + Debug {}\n    //~^ implied_bounds_in_impls\n\n    // Referring to `Self` in the supertrait clause needs special handling.\n    trait Trait1<X: ?Sized> {}\n    trait Trait2: Trait1<Self> {}\n    impl Trait1<()> for () {}\n    impl Trait2 for () {}\n\n    fn f() -> impl Trait1<()> + Trait2 {}\n}\n\nmod issue11435 {\n    // Associated type needs to be included on DoubleEndedIterator in the suggestion\n    fn my_iter() -> impl DoubleEndedIterator<Item = u32> {\n        //~^ implied_bounds_in_impls\n        0..5\n    }\n\n    // Removing the `Clone` bound should include the `+` behind it in its remove suggestion\n    fn f() -> impl Copy {\n        //~^ implied_bounds_in_impls\n        1\n    }\n\n    trait Trait1<T> {\n        type U;\n    }\n    impl Trait1<i32> for () {\n        type U = i64;\n    }\n    trait Trait2<T>: Trait1<T> {}\n    impl Trait2<i32> for () {}\n\n    // When the other trait has generics, it shouldn't add another pair of `<>`\n    fn f2() -> impl Trait2<i32, U = i64> {}\n    //~^ implied_bounds_in_impls\n\n    trait Trait3<T, U, V> {\n        type X;\n        type Y;\n    }\n    trait Trait4<T>: Trait3<T, i16, i64> {}\n    impl Trait3<i8, i16, i64> for () {\n        type X = i32;\n        type Y = i128;\n    }\n    impl Trait4<i8> for () {}\n\n    // Associated type `X` is specified, but `Y` is not, so only that associated type should be moved\n    // over\n    fn f3() -> impl Trait4<i8, X = i32, Y = i128> {}\n    //~^ implied_bounds_in_impls\n}\n\nfn issue11880() {\n    trait X {\n        type T;\n        type U;\n    }\n    trait Y: X {\n        type T;\n        type V;\n    }\n    impl X for () {\n        type T = i32;\n        type U = String;\n    }\n    impl Y for () {\n        type T = u32;\n        type V = Vec<u8>;\n    }\n\n    // Can't constrain `X::T` through `Y`\n    fn f() -> impl X<T = i32> + Y {}\n    fn f2() -> impl X<T = i32> + Y<T = u32> {}\n\n    // X::T is never constrained in the first place, so it can be omitted\n    // and left unconstrained\n    fn f3() -> impl Y {}\n    //~^ implied_bounds_in_impls\n    fn f4() -> impl Y<T = u32> {}\n    //~^ implied_bounds_in_impls\n    fn f5() -> impl Y<T = u32, U = String> {}\n    //~^ implied_bounds_in_impls\n}\n\nfn apit(_: impl DerefMut) {}\n//~^ implied_bounds_in_impls\n\ntrait Rpitit {\n    fn f() -> impl DerefMut;\n    //~^ implied_bounds_in_impls\n}\n\ntrait Atpit {\n    type Assoc;\n    fn define() -> Self::Assoc;\n}\nimpl Atpit for () {\n    type Assoc = impl DerefMut;\n    //~^ implied_bounds_in_impls\n    fn define() -> Self::Assoc {\n        &mut [] as &mut [()]\n    }\n}\n\ntype Tait = impl DerefMut;\n//~^ implied_bounds_in_impls\n#[define_opaque(Tait)]\nfn define() -> Tait {\n    &mut [] as &mut [()]\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/implied_bounds_in_impls.rs",
    "content": "#![warn(clippy::implied_bounds_in_impls)]\n#![allow(dead_code)]\n#![feature(impl_trait_in_assoc_type, type_alias_impl_trait)]\n\nuse std::ops::{Deref, DerefMut};\n\n// Only one bound, nothing to lint.\nfn normal_deref<T>(x: T) -> impl Deref<Target = T> {\n    Box::new(x)\n}\n\n// Deref implied by DerefMut\nfn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> {\n    //~^ implied_bounds_in_impls\n    Box::new(x)\n}\n\ntrait GenericTrait<T> {}\ntrait GenericTrait2<V> {}\n// U is intentionally at a different \"index\" in GenericSubtrait than `T` is in GenericTrait,\n// so this can be a good test to make sure that the calculations are right (no off-by-one errors,\n// ...)\ntrait GenericSubtrait<T, U, V>: GenericTrait<U> + GenericTrait2<V> {}\n\nimpl GenericTrait<i32> for () {}\nimpl GenericTrait<i64> for () {}\nimpl<V> GenericTrait2<V> for () {}\nimpl<V> GenericSubtrait<(), i32, V> for () {}\nimpl<V> GenericSubtrait<(), i64, V> for () {}\n\nfn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U>\n//~^ implied_bounds_in_impls\nwhere\n    (): GenericSubtrait<U, W, U>,\n{\n}\n\nfn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}\n//~^ implied_bounds_in_impls\n//~| implied_bounds_in_impls\n\nfn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>\n//~^ implied_bounds_in_impls\n//~| implied_bounds_in_impls\nwhere\n    (): GenericSubtrait<(), T, V> + GenericTrait<T>,\n{\n}\n\n// i32 != i64, GenericSubtrait<_, i64, _> does not imply GenericTrait<i32>, don't lint\nfn generics_different() -> impl GenericTrait<i32> + GenericSubtrait<(), i64, ()> {}\n\n// i32 == i32, GenericSubtrait<_, i32, _> does imply GenericTrait<i32>, lint\nfn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}\n//~^ implied_bounds_in_impls\n\ntrait SomeTrait {\n    // Check that it works in trait declarations.\n    fn f() -> impl Deref + DerefMut<Target = u8>;\n    //~^ implied_bounds_in_impls\n}\nstruct SomeStruct;\nimpl SomeStruct {\n    // Check that it works in inherent impl blocks.\n    fn f() -> impl Deref + DerefMut<Target = u8> {\n        //~^ implied_bounds_in_impls\n        Box::new(123)\n    }\n}\nimpl SomeTrait for SomeStruct {\n    // Check that it works in trait impls.\n    fn f() -> impl Deref + DerefMut<Target = u8> {\n        //~^ implied_bounds_in_impls\n        Box::new(42)\n    }\n}\n\nmod issue11422 {\n    use core::fmt::Debug;\n    // Some additional tests that would cause ICEs:\n\n    // `PartialOrd` has a default generic parameter and does not need to be explicitly specified.\n    // This needs special handling.\n    fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {}\n    //~^ implied_bounds_in_impls\n    fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {}\n    //~^ implied_bounds_in_impls\n\n    // Referring to `Self` in the supertrait clause needs special handling.\n    trait Trait1<X: ?Sized> {}\n    trait Trait2: Trait1<Self> {}\n    impl Trait1<()> for () {}\n    impl Trait2 for () {}\n\n    fn f() -> impl Trait1<()> + Trait2 {}\n}\n\nmod issue11435 {\n    // Associated type needs to be included on DoubleEndedIterator in the suggestion\n    fn my_iter() -> impl Iterator<Item = u32> + DoubleEndedIterator {\n        //~^ implied_bounds_in_impls\n        0..5\n    }\n\n    // Removing the `Clone` bound should include the `+` behind it in its remove suggestion\n    fn f() -> impl Copy + Clone {\n        //~^ implied_bounds_in_impls\n        1\n    }\n\n    trait Trait1<T> {\n        type U;\n    }\n    impl Trait1<i32> for () {\n        type U = i64;\n    }\n    trait Trait2<T>: Trait1<T> {}\n    impl Trait2<i32> for () {}\n\n    // When the other trait has generics, it shouldn't add another pair of `<>`\n    fn f2() -> impl Trait1<i32, U = i64> + Trait2<i32> {}\n    //~^ implied_bounds_in_impls\n\n    trait Trait3<T, U, V> {\n        type X;\n        type Y;\n    }\n    trait Trait4<T>: Trait3<T, i16, i64> {}\n    impl Trait3<i8, i16, i64> for () {\n        type X = i32;\n        type Y = i128;\n    }\n    impl Trait4<i8> for () {}\n\n    // Associated type `X` is specified, but `Y` is not, so only that associated type should be moved\n    // over\n    fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {}\n    //~^ implied_bounds_in_impls\n}\n\nfn issue11880() {\n    trait X {\n        type T;\n        type U;\n    }\n    trait Y: X {\n        type T;\n        type V;\n    }\n    impl X for () {\n        type T = i32;\n        type U = String;\n    }\n    impl Y for () {\n        type T = u32;\n        type V = Vec<u8>;\n    }\n\n    // Can't constrain `X::T` through `Y`\n    fn f() -> impl X<T = i32> + Y {}\n    fn f2() -> impl X<T = i32> + Y<T = u32> {}\n\n    // X::T is never constrained in the first place, so it can be omitted\n    // and left unconstrained\n    fn f3() -> impl X + Y {}\n    //~^ implied_bounds_in_impls\n    fn f4() -> impl X + Y<T = u32> {}\n    //~^ implied_bounds_in_impls\n    fn f5() -> impl X<U = String> + Y<T = u32> {}\n    //~^ implied_bounds_in_impls\n}\n\nfn apit(_: impl Deref + DerefMut) {}\n//~^ implied_bounds_in_impls\n\ntrait Rpitit {\n    fn f() -> impl Deref + DerefMut;\n    //~^ implied_bounds_in_impls\n}\n\ntrait Atpit {\n    type Assoc;\n    fn define() -> Self::Assoc;\n}\nimpl Atpit for () {\n    type Assoc = impl Deref + DerefMut;\n    //~^ implied_bounds_in_impls\n    fn define() -> Self::Assoc {\n        &mut [] as &mut [()]\n    }\n}\n\ntype Tait = impl Deref + DerefMut;\n//~^ implied_bounds_in_impls\n#[define_opaque(Tait)]\nfn define() -> Tait {\n    &mut [] as &mut [()]\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/implied_bounds_in_impls.stderr",
    "content": "error: this bound is already specified as the supertrait of `DerefMut<Target = T>`\n  --> tests/ui/implied_bounds_in_impls.rs:13:36\n   |\nLL | fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> {\n   |                                    ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::implied-bounds-in-impls` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::implied_bounds_in_impls)]`\nhelp: try removing this bound\n   |\nLL - fn deref_derefmut<T>(x: T) -> impl Deref<Target = T> + DerefMut<Target = T> {\nLL + fn deref_derefmut<T>(x: T) -> impl DerefMut<Target = T> {\n   |\n\nerror: this bound is already specified as the supertrait of `GenericSubtrait<U, W, U>`\n  --> tests/ui/implied_bounds_in_impls.rs:31:37\n   |\nLL | fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U>\n   |                                     ^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL - fn generics_implied<U, W>() -> impl GenericTrait<W> + GenericSubtrait<U, W, U>\nLL + fn generics_implied<U, W>() -> impl GenericSubtrait<U, W, U>\n   |\n\nerror: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>`\n  --> tests/ui/implied_bounds_in_impls.rs:38:40\n   |\nLL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}\n   |                                        ^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL - fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}\nLL + fn generics_implied_multi<V>() -> impl GenericTrait2<V> + GenericSubtrait<(), i32, V> {}\n   |\n\nerror: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, V>`\n  --> tests/ui/implied_bounds_in_impls.rs:38:60\n   |\nLL | fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}\n   |                                                            ^^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL - fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericTrait2<V> + GenericSubtrait<(), i32, V> {}\nLL + fn generics_implied_multi<V>() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, V> {}\n   |\n\nerror: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>`\n  --> tests/ui/implied_bounds_in_impls.rs:42:44\n   |\nLL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>\n   |                                            ^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL - fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>\nLL + fn generics_implied_multi2<T, V>() -> impl GenericTrait2<V> + GenericSubtrait<(), T, V>\n   |\n\nerror: this bound is already specified as the supertrait of `GenericSubtrait<(), T, V>`\n  --> tests/ui/implied_bounds_in_impls.rs:42:62\n   |\nLL | fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>\n   |                                                              ^^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL - fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericTrait2<V> + GenericSubtrait<(), T, V>\nLL + fn generics_implied_multi2<T, V>() -> impl GenericTrait<T> + GenericSubtrait<(), T, V>\n   |\n\nerror: this bound is already specified as the supertrait of `GenericSubtrait<(), i32, ()>`\n  --> tests/ui/implied_bounds_in_impls.rs:54:28\n   |\nLL | fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}\n   |                            ^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL - fn generics_same() -> impl GenericTrait<i32> + GenericSubtrait<(), i32, ()> {}\nLL + fn generics_same() -> impl GenericSubtrait<(), i32, ()> {}\n   |\n\nerror: this bound is already specified as the supertrait of `DerefMut<Target = u8>`\n  --> tests/ui/implied_bounds_in_impls.rs:59:20\n   |\nLL |     fn f() -> impl Deref + DerefMut<Target = u8>;\n   |                    ^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f() -> impl Deref + DerefMut<Target = u8>;\nLL +     fn f() -> impl DerefMut<Target = u8>;\n   |\n\nerror: this bound is already specified as the supertrait of `DerefMut<Target = u8>`\n  --> tests/ui/implied_bounds_in_impls.rs:65:20\n   |\nLL |     fn f() -> impl Deref + DerefMut<Target = u8> {\n   |                    ^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f() -> impl Deref + DerefMut<Target = u8> {\nLL +     fn f() -> impl DerefMut<Target = u8> {\n   |\n\nerror: this bound is already specified as the supertrait of `DerefMut<Target = u8>`\n  --> tests/ui/implied_bounds_in_impls.rs:72:20\n   |\nLL |     fn f() -> impl Deref + DerefMut<Target = u8> {\n   |                    ^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f() -> impl Deref + DerefMut<Target = u8> {\nLL +     fn f() -> impl DerefMut<Target = u8> {\n   |\n\nerror: this bound is already specified as the supertrait of `PartialOrd`\n  --> tests/ui/implied_bounds_in_impls.rs:84:41\n   |\nLL |     fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {}\n   |                                         ^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn default_generic_param1() -> impl PartialEq + PartialOrd + Debug {}\nLL +     fn default_generic_param1() -> impl PartialOrd + Debug {}\n   |\n\nerror: this bound is already specified as the supertrait of `PartialOrd`\n  --> tests/ui/implied_bounds_in_impls.rs:86:54\n   |\nLL |     fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {}\n   |                                                      ^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn default_generic_param2() -> impl PartialOrd + PartialEq + Debug {}\nLL +     fn default_generic_param2() -> impl PartialOrd + Debug {}\n   |\n\nerror: this bound is already specified as the supertrait of `DoubleEndedIterator`\n  --> tests/ui/implied_bounds_in_impls.rs:100:26\n   |\nLL |     fn my_iter() -> impl Iterator<Item = u32> + DoubleEndedIterator {\n   |                          ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn my_iter() -> impl Iterator<Item = u32> + DoubleEndedIterator {\nLL +     fn my_iter() -> impl DoubleEndedIterator<Item = u32> {\n   |\n\nerror: this bound is already specified as the supertrait of `Copy`\n  --> tests/ui/implied_bounds_in_impls.rs:106:27\n   |\nLL |     fn f() -> impl Copy + Clone {\n   |                           ^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f() -> impl Copy + Clone {\nLL +     fn f() -> impl Copy {\n   |\n\nerror: this bound is already specified as the supertrait of `Trait2<i32>`\n  --> tests/ui/implied_bounds_in_impls.rs:121:21\n   |\nLL |     fn f2() -> impl Trait1<i32, U = i64> + Trait2<i32> {}\n   |                     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f2() -> impl Trait1<i32, U = i64> + Trait2<i32> {}\nLL +     fn f2() -> impl Trait2<i32, U = i64> {}\n   |\n\nerror: this bound is already specified as the supertrait of `Trait4<i8, X = i32>`\n  --> tests/ui/implied_bounds_in_impls.rs:137:21\n   |\nLL |     fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {}\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f3() -> impl Trait3<i8, i16, i64, X = i32, Y = i128> + Trait4<i8, X = i32> {}\nLL +     fn f3() -> impl Trait4<i8, X = i32, Y = i128> {}\n   |\n\nerror: this bound is already specified as the supertrait of `Y`\n  --> tests/ui/implied_bounds_in_impls.rs:165:21\n   |\nLL |     fn f3() -> impl X + Y {}\n   |                     ^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f3() -> impl X + Y {}\nLL +     fn f3() -> impl Y {}\n   |\n\nerror: this bound is already specified as the supertrait of `Y<T = u32>`\n  --> tests/ui/implied_bounds_in_impls.rs:167:21\n   |\nLL |     fn f4() -> impl X + Y<T = u32> {}\n   |                     ^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f4() -> impl X + Y<T = u32> {}\nLL +     fn f4() -> impl Y<T = u32> {}\n   |\n\nerror: this bound is already specified as the supertrait of `Y<T = u32>`\n  --> tests/ui/implied_bounds_in_impls.rs:169:21\n   |\nLL |     fn f5() -> impl X<U = String> + Y<T = u32> {}\n   |                     ^^^^^^^^^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f5() -> impl X<U = String> + Y<T = u32> {}\nLL +     fn f5() -> impl Y<T = u32, U = String> {}\n   |\n\nerror: this bound is already specified as the supertrait of `DerefMut`\n  --> tests/ui/implied_bounds_in_impls.rs:173:17\n   |\nLL | fn apit(_: impl Deref + DerefMut) {}\n   |                 ^^^^^\n   |\nhelp: try removing this bound\n   |\nLL - fn apit(_: impl Deref + DerefMut) {}\nLL + fn apit(_: impl DerefMut) {}\n   |\n\nerror: this bound is already specified as the supertrait of `DerefMut`\n  --> tests/ui/implied_bounds_in_impls.rs:177:20\n   |\nLL |     fn f() -> impl Deref + DerefMut;\n   |                    ^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     fn f() -> impl Deref + DerefMut;\nLL +     fn f() -> impl DerefMut;\n   |\n\nerror: this bound is already specified as the supertrait of `DerefMut`\n  --> tests/ui/implied_bounds_in_impls.rs:186:23\n   |\nLL |     type Assoc = impl Deref + DerefMut;\n   |                       ^^^^^\n   |\nhelp: try removing this bound\n   |\nLL -     type Assoc = impl Deref + DerefMut;\nLL +     type Assoc = impl DerefMut;\n   |\n\nerror: this bound is already specified as the supertrait of `DerefMut`\n  --> tests/ui/implied_bounds_in_impls.rs:193:18\n   |\nLL | type Tait = impl Deref + DerefMut;\n   |                  ^^^^^\n   |\nhelp: try removing this bound\n   |\nLL - type Tait = impl Deref + DerefMut;\nLL + type Tait = impl DerefMut;\n   |\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/incompatible_msrv.rs",
    "content": "#![warn(clippy::incompatible_msrv)]\n#![feature(custom_inner_attributes)]\n#![allow(stable_features)]\n#![feature(strict_provenance)] // For use in test\n#![clippy::msrv = \"1.3.0\"]\n\nuse std::cell::Cell;\nuse std::collections::HashMap;\nuse std::collections::hash_map::Entry;\nuse std::future::Future;\nuse std::thread::sleep;\nuse std::time::Duration;\n\nfn foo() {\n    let mut map: HashMap<&str, u32> = HashMap::new();\n    assert_eq!(map.entry(\"poneyland\").key(), &\"poneyland\");\n    //~^ incompatible_msrv\n    //~| NOTE: `-D clippy::incompatible-msrv` implied by `-D warnings`\n    //~| HELP: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`\n\n    if let Entry::Vacant(v) = map.entry(\"poneyland\") {\n        v.into_key();\n        //~^ incompatible_msrv\n    }\n    // Should warn for `sleep` but not for `Duration` (which was added in `1.3.0`).\n    sleep(Duration::new(1, 0));\n    //~^ incompatible_msrv\n}\n\n#[clippy::msrv = \"1.2.0\"]\nstatic NO_BODY_BAD_MSRV: Option<Duration> = None;\n//~^ incompatible_msrv\n\nstatic NO_BODY_GOOD_MSRV: Option<Duration> = None;\n\n#[clippy::msrv = \"1.2.0\"]\nfn bad_type_msrv() {\n    let _: Option<Duration> = None;\n    //~^ incompatible_msrv\n}\n\n#[test]\nfn test() {\n    sleep(Duration::new(1, 0));\n}\n\n#[clippy::msrv = \"1.63.0\"]\nasync fn issue12273(v: impl Future<Output = ()>) {\n    // `.await` desugaring has a call to `IntoFuture::into_future` marked #[stable(since = \"1.64.0\")],\n    // but its stability is ignored\n    v.await;\n}\n\nfn core_special_treatment(p: bool) {\n    // Do not lint code coming from `core` macros expanding into `core` function calls\n    if p {\n        panic!(\"foo\"); // Do not lint\n    }\n\n    // But still lint code calling `core` functions directly\n    if p {\n        let _ = core::iter::once_with(|| 0);\n        //~^ incompatible_msrv\n    }\n\n    // Lint code calling `core` from non-`core` macros\n    macro_rules! my_panic {\n        ($msg:expr) => {\n            let _ = core::iter::once_with(|| $msg);\n            //~^ incompatible_msrv\n        };\n    }\n    my_panic!(\"foo\");\n\n    // Lint even when the macro comes from `core` and calls `core` functions\n    assert!(core::iter::once_with(|| 0).next().is_some());\n    //~^ incompatible_msrv\n}\n\n#[clippy::msrv = \"1.26.0\"]\nfn lang_items() {\n    // Do not lint lang items. `..=` will expand into `RangeInclusive::new()`, which was introduced\n    // in Rust 1.27.0.\n    let _ = 1..=3;\n}\n\n#[clippy::msrv = \"1.80.0\"]\nfn issue14212() {\n    let _ = std::iter::repeat_n((), 5);\n    //~^ incompatible_msrv\n}\n\n#[clippy::msrv = \"1.0.0\"]\nfn cstr_and_cstring_ok() {\n    let _: Option<&'static std::ffi::CStr> = None;\n    let _: Option<std::ffi::CString> = None;\n}\n\nfn local_msrv_change_suggestion() {\n    let _ = std::iter::repeat_n((), 5);\n    //~^ incompatible_msrv\n\n    #[cfg(any(test, not(test)))]\n    {\n        let _ = std::iter::repeat_n((), 5);\n        //~^ incompatible_msrv\n        //~| NOTE: you may want to conditionally increase the MSRV\n\n        // Emit the additional note only once\n        let _ = std::iter::repeat_n((), 5);\n        //~^ incompatible_msrv\n    }\n}\n\n#[clippy::msrv = \"1.78.0\"]\nfn feature_enable_14425(ptr: *const u8) -> usize {\n    // Do not warn, because it is enabled through a feature even though\n    // it is stabilized only since Rust 1.84.0.\n    let r = ptr.addr();\n\n    // Warn about this which has been introduced in the same Rust version\n    // but is not allowed through a feature.\n    r.isqrt()\n    //~^ incompatible_msrv\n}\n\nfn non_fn_items() {\n    let _ = std::io::ErrorKind::CrossesDevices;\n    //~^ incompatible_msrv\n}\n\n#[clippy::msrv = \"1.87.0\"]\nfn msrv_non_ok_in_const() {\n    {\n        let c = Cell::new(42);\n        _ = c.get();\n    }\n    const {\n        let c = Cell::new(42);\n        _ = c.get();\n        //~^ incompatible_msrv\n    }\n}\n\n#[clippy::msrv = \"1.88.0\"]\nfn msrv_ok_in_const() {\n    {\n        let c = Cell::new(42);\n        _ = c.get();\n    }\n    const {\n        let c = Cell::new(42);\n        _ = c.get();\n    }\n}\n\n#[clippy::msrv = \"1.86.0\"]\nfn enum_variant_not_ok() {\n    let _ = std::io::ErrorKind::InvalidFilename;\n    //~^ incompatible_msrv\n    let _ = const { std::io::ErrorKind::InvalidFilename };\n    //~^ incompatible_msrv\n}\n\n#[clippy::msrv = \"1.87.0\"]\nfn enum_variant_ok() {\n    let _ = std::io::ErrorKind::InvalidFilename;\n    let _ = const { std::io::ErrorKind::InvalidFilename };\n}\n\n#[clippy::msrv = \"1.38.0\"]\nconst fn uncalled_len() {\n    let _ = Vec::<usize>::len;\n    let x = str::len;\n    let _ = x(\"\");\n    //~^ incompatible_msrv\n    let _ = \"\".len();\n    //~^ incompatible_msrv\n}\n\n#[clippy::msrv = \"1.0.0\"]\nfn vec_macro() {\n    let _: Vec<u32> = vec![];\n    let _: Vec<u32> = vec![1; 3];\n    let _: Vec<u32> = vec![1, 2];\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/incompatible_msrv.stderr",
    "content": "error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.10.0`\n  --> tests/ui/incompatible_msrv.rs:16:39\n   |\nLL |     assert_eq!(map.entry(\"poneyland\").key(), &\"poneyland\");\n   |                                       ^^^^^\n   |\n   = note: `-D clippy::incompatible-msrv` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.12.0`\n  --> tests/ui/incompatible_msrv.rs:22:11\n   |\nLL |         v.into_key();\n   |           ^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`\n  --> tests/ui/incompatible_msrv.rs:26:5\n   |\nLL |     sleep(Duration::new(1, 0));\n   |     ^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.2.0` but this item is stable since `1.3.0`\n  --> tests/ui/incompatible_msrv.rs:31:33\n   |\nLL | static NO_BODY_BAD_MSRV: Option<Duration> = None;\n   |                                 ^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.2.0` but this item is stable since `1.3.0`\n  --> tests/ui/incompatible_msrv.rs:38:19\n   |\nLL |     let _: Option<Duration> = None;\n   |                   ^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.43.0`\n  --> tests/ui/incompatible_msrv.rs:62:17\n   |\nLL |         let _ = core::iter::once_with(|| 0);\n   |                 ^^^^^^^^^^^^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.43.0`\n  --> tests/ui/incompatible_msrv.rs:69:21\n   |\nLL |             let _ = core::iter::once_with(|| $msg);\n   |                     ^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     my_panic!(\"foo\");\n   |     ---------------- in this macro invocation\n   |\n   = note: this error originates in the macro `my_panic` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.43.0`\n  --> tests/ui/incompatible_msrv.rs:76:13\n   |\nLL |     assert!(core::iter::once_with(|| 0).next().is_some());\n   |             ^^^^^^^^^^^^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.80.0` but this item is stable since `1.82.0`\n  --> tests/ui/incompatible_msrv.rs:89:13\n   |\nLL |     let _ = std::iter::repeat_n((), 5);\n   |             ^^^^^^^^^^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`\n  --> tests/ui/incompatible_msrv.rs:100:13\n   |\nLL |     let _ = std::iter::repeat_n((), 5);\n   |             ^^^^^^^^^^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`\n  --> tests/ui/incompatible_msrv.rs:105:17\n   |\nLL |         let _ = std::iter::repeat_n((), 5);\n   |                 ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`\n  --> tests/ui/incompatible_msrv.rs:110:17\n   |\nLL |         let _ = std::iter::repeat_n((), 5);\n   |                 ^^^^^^^^^^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.78.0` but this item is stable since `1.84.0`\n  --> tests/ui/incompatible_msrv.rs:123:7\n   |\nLL |     r.isqrt()\n   |       ^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.85.0`\n  --> tests/ui/incompatible_msrv.rs:128:13\n   |\nLL |     let _ = std::io::ErrorKind::CrossesDevices;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.87.0` but this item is stable in a `const` context since `1.88.0`\n  --> tests/ui/incompatible_msrv.rs:140:15\n   |\nLL |         _ = c.get();\n   |               ^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.86.0` but this item is stable since `1.87.0`\n  --> tests/ui/incompatible_msrv.rs:159:13\n   |\nLL |     let _ = std::io::ErrorKind::InvalidFilename;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.86.0` but this item is stable since `1.87.0`\n  --> tests/ui/incompatible_msrv.rs:161:21\n   |\nLL |     let _ = const { std::io::ErrorKind::InvalidFilename };\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.38.0` but this item is stable in a `const` context since `1.39.0`\n  --> tests/ui/incompatible_msrv.rs:175:13\n   |\nLL |     let _ = x(\"\");\n   |             ^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.38.0` but this item is stable in a `const` context since `1.39.0`\n  --> tests/ui/incompatible_msrv.rs:177:16\n   |\nLL |     let _ = \"\".len();\n   |                ^^^^^\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/inconsistent_digit_grouping.fixed",
    "content": "#[warn(clippy::inconsistent_digit_grouping)]\n#[deny(clippy::unreadable_literal)]\n#[allow(unused_variables, clippy::excessive_precision)]\nfn main() {\n    macro_rules! mac1 {\n        () => {\n            1_23_456\n        };\n    }\n    macro_rules! mac2 {\n        () => {\n            1_234.5678_f32\n        };\n    }\n\n    let good = (\n        123,\n        1_234,\n        1_2345_6789,\n        123_f32,\n        1_234.12_f32,\n        1_234.123_4_f32,\n        1.123_456_7_f32,\n    );\n    let bad = (123_456, 12_345_678, 1_234_567, 1_234.567_8_f32, 1.234_567_8_f32);\n    //~^ inconsistent_digit_grouping\n    //~| inconsistent_digit_grouping\n    //~| inconsistent_digit_grouping\n    //~| inconsistent_digit_grouping\n    //~| inconsistent_digit_grouping\n\n    // Test padding\n    let _ = 0x0010_0000;\n    //~^ unreadable_literal\n    let _ = 0x0100_0000;\n    //~^ unreadable_literal\n    let _ = 0x1000_0000;\n    //~^ unreadable_literal\n    let _ = 0x0001_0000_0000_u64;\n    //~^ unreadable_literal\n\n    // Test suggestion when fraction has no digits\n    let _: f32 = 123_456.;\n    //~^ inconsistent_digit_grouping\n\n    // Test UUID formatted literal\n    let _: u128 = 0x12345678_1234_1234_1234_123456789012;\n\n    // Ignore literals in macros\n    let _ = mac1!();\n    let _ = mac2!();\n\n    // Issue #6096\n    // Allow separating exponent with '_'\n    let _ = 1.025_011_10_E0;\n}\n"
  },
  {
    "path": "tests/ui/inconsistent_digit_grouping.rs",
    "content": "#[warn(clippy::inconsistent_digit_grouping)]\n#[deny(clippy::unreadable_literal)]\n#[allow(unused_variables, clippy::excessive_precision)]\nfn main() {\n    macro_rules! mac1 {\n        () => {\n            1_23_456\n        };\n    }\n    macro_rules! mac2 {\n        () => {\n            1_234.5678_f32\n        };\n    }\n\n    let good = (\n        123,\n        1_234,\n        1_2345_6789,\n        123_f32,\n        1_234.12_f32,\n        1_234.123_4_f32,\n        1.123_456_7_f32,\n    );\n    let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);\n    //~^ inconsistent_digit_grouping\n    //~| inconsistent_digit_grouping\n    //~| inconsistent_digit_grouping\n    //~| inconsistent_digit_grouping\n    //~| inconsistent_digit_grouping\n\n    // Test padding\n    let _ = 0x100000;\n    //~^ unreadable_literal\n    let _ = 0x1000000;\n    //~^ unreadable_literal\n    let _ = 0x10000000;\n    //~^ unreadable_literal\n    let _ = 0x100000000_u64;\n    //~^ unreadable_literal\n\n    // Test suggestion when fraction has no digits\n    let _: f32 = 1_23_456.;\n    //~^ inconsistent_digit_grouping\n\n    // Test UUID formatted literal\n    let _: u128 = 0x12345678_1234_1234_1234_123456789012;\n\n    // Ignore literals in macros\n    let _ = mac1!();\n    let _ = mac2!();\n\n    // Issue #6096\n    // Allow separating exponent with '_'\n    let _ = 1.025_011_10_E0;\n}\n"
  },
  {
    "path": "tests/ui/inconsistent_digit_grouping.stderr",
    "content": "error: digits grouped inconsistently by underscores\n  --> tests/ui/inconsistent_digit_grouping.rs:25:16\n   |\nLL |     let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);\n   |                ^^^^^^^^ help: consider: `123_456`\n   |\n   = note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]`\n\nerror: digits grouped inconsistently by underscores\n  --> tests/ui/inconsistent_digit_grouping.rs:25:26\n   |\nLL |     let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);\n   |                          ^^^^^^^^^^ help: consider: `12_345_678`\n\nerror: digits grouped inconsistently by underscores\n  --> tests/ui/inconsistent_digit_grouping.rs:25:38\n   |\nLL |     let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);\n   |                                      ^^^^^^^^ help: consider: `1_234_567`\n\nerror: digits grouped inconsistently by underscores\n  --> tests/ui/inconsistent_digit_grouping.rs:25:48\n   |\nLL |     let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);\n   |                                                ^^^^^^^^^^^^^^ help: consider: `1_234.567_8_f32`\n\nerror: digits grouped inconsistently by underscores\n  --> tests/ui/inconsistent_digit_grouping.rs:25:64\n   |\nLL |     let bad = (1_23_456, 1_234_5678, 1234_567, 1_234.5678_f32, 1.234_5678_f32);\n   |                                                                ^^^^^^^^^^^^^^ help: consider: `1.234_567_8_f32`\n\nerror: long literal lacking separators\n  --> tests/ui/inconsistent_digit_grouping.rs:33:13\n   |\nLL |     let _ = 0x100000;\n   |             ^^^^^^^^ help: consider: `0x0010_0000`\n   |\nnote: the lint level is defined here\n  --> tests/ui/inconsistent_digit_grouping.rs:2:8\n   |\nLL | #[deny(clippy::unreadable_literal)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: long literal lacking separators\n  --> tests/ui/inconsistent_digit_grouping.rs:35:13\n   |\nLL |     let _ = 0x1000000;\n   |             ^^^^^^^^^ help: consider: `0x0100_0000`\n\nerror: long literal lacking separators\n  --> tests/ui/inconsistent_digit_grouping.rs:37:13\n   |\nLL |     let _ = 0x10000000;\n   |             ^^^^^^^^^^ help: consider: `0x1000_0000`\n\nerror: long literal lacking separators\n  --> tests/ui/inconsistent_digit_grouping.rs:39:13\n   |\nLL |     let _ = 0x100000000_u64;\n   |             ^^^^^^^^^^^^^^^ help: consider: `0x0001_0000_0000_u64`\n\nerror: digits grouped inconsistently by underscores\n  --> tests/ui/inconsistent_digit_grouping.rs:43:18\n   |\nLL |     let _: f32 = 1_23_456.;\n   |                  ^^^^^^^^^ help: consider: `123_456.`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/inconsistent_struct_constructor.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::inconsistent_struct_constructor)]\n#![allow(clippy::redundant_field_names)]\n#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::no_effect)]\n#![allow(dead_code)]\n\nextern crate proc_macros;\n\n#[derive(Default)]\nstruct Foo {\n    x: i32,\n    y: i32,\n    z: i32,\n}\n\n#[derive(Default)]\n#[allow(clippy::inconsistent_struct_constructor)]\nstruct Bar {\n    x: i32,\n    y: i32,\n    z: i32,\n}\n\nmod without_base {\n    use super::Foo;\n\n    #[proc_macros::inline_macros]\n    fn test() {\n        let x = 1;\n        let y = 1;\n        let z = 1;\n\n        // Should lint.\n        Foo { x, y, z };\n        //~^ inconsistent_struct_constructor\n\n        // Should NOT lint.\n        // issue #7069.\n        inline!({\n            let x = 1;\n            let y = 1;\n            let z = 1;\n            Foo { y, x, z }\n        });\n\n        // Should NOT lint because the order is the same as in the definition.\n        Foo { x, y, z };\n\n        // Should NOT lint because z is not a shorthand init.\n        Foo { y, x, z: z };\n    }\n}\n\nmod with_base {\n    use super::Foo;\n\n    fn test() {\n        let x = 1;\n        let z = 1;\n\n        // Should lint.\n        Foo {\n            x,\n            z,\n            ..Default::default()\n        };\n        //~^^^^ inconsistent_struct_constructor\n\n        // Should NOT lint because the order is consistent with the definition.\n        Foo {\n            x,\n            z,\n            ..Default::default()\n        };\n\n        // Should NOT lint because z is not a shorthand init.\n        Foo {\n            z: z,\n            x,\n            ..Default::default()\n        };\n    }\n}\n\nmod with_allow_ty_def {\n    use super::Bar;\n\n    fn test() {\n        let x = 1;\n        let y = 1;\n        let z = 1;\n\n        // Should NOT lint because `Bar` is defined with `#[allow(clippy::inconsistent_struct_constructor)]`\n        Bar { y, x, z };\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/inconsistent_struct_constructor.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::inconsistent_struct_constructor)]\n#![allow(clippy::redundant_field_names)]\n#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::no_effect)]\n#![allow(dead_code)]\n\nextern crate proc_macros;\n\n#[derive(Default)]\nstruct Foo {\n    x: i32,\n    y: i32,\n    z: i32,\n}\n\n#[derive(Default)]\n#[allow(clippy::inconsistent_struct_constructor)]\nstruct Bar {\n    x: i32,\n    y: i32,\n    z: i32,\n}\n\nmod without_base {\n    use super::Foo;\n\n    #[proc_macros::inline_macros]\n    fn test() {\n        let x = 1;\n        let y = 1;\n        let z = 1;\n\n        // Should lint.\n        Foo { y, x, z };\n        //~^ inconsistent_struct_constructor\n\n        // Should NOT lint.\n        // issue #7069.\n        inline!({\n            let x = 1;\n            let y = 1;\n            let z = 1;\n            Foo { y, x, z }\n        });\n\n        // Should NOT lint because the order is the same as in the definition.\n        Foo { x, y, z };\n\n        // Should NOT lint because z is not a shorthand init.\n        Foo { y, x, z: z };\n    }\n}\n\nmod with_base {\n    use super::Foo;\n\n    fn test() {\n        let x = 1;\n        let z = 1;\n\n        // Should lint.\n        Foo {\n            z,\n            x,\n            ..Default::default()\n        };\n        //~^^^^ inconsistent_struct_constructor\n\n        // Should NOT lint because the order is consistent with the definition.\n        Foo {\n            x,\n            z,\n            ..Default::default()\n        };\n\n        // Should NOT lint because z is not a shorthand init.\n        Foo {\n            z: z,\n            x,\n            ..Default::default()\n        };\n    }\n}\n\nmod with_allow_ty_def {\n    use super::Bar;\n\n    fn test() {\n        let x = 1;\n        let y = 1;\n        let z = 1;\n\n        // Should NOT lint because `Bar` is defined with `#[allow(clippy::inconsistent_struct_constructor)]`\n        Bar { y, x, z };\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/inconsistent_struct_constructor.stderr",
    "content": "error: struct constructor field order is inconsistent with struct definition field order\n  --> tests/ui/inconsistent_struct_constructor.rs:36:15\n   |\nLL |         Foo { y, x, z };\n   |               ^^^^^^^ help: try: `x, y, z`\n   |\n   = note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inconsistent_struct_constructor)]`\n\nerror: struct constructor field order is inconsistent with struct definition field order\n  --> tests/ui/inconsistent_struct_constructor.rs:65:13\n   |\nLL | /             z,\nLL | |             x,\n   | |_____________^\n   |\nhelp: try\n   |\nLL ~             x,\nLL ~             z,\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/index_refutable_slice/if_let_slice_binding.fixed",
    "content": "#![deny(clippy::index_refutable_slice)]\n#![allow(clippy::needless_lifetimes, clippy::collapsible_if)]\n\nenum SomeEnum<T> {\n    One(T),\n    Two(T),\n    Three(T),\n    Four(T),\n}\n\nfn lintable_examples() {\n    // Try with reference\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some([slice_0, ..]) = slice {\n        //~^ index_refutable_slice\n\n        println!(\"{}\", slice_0);\n    }\n\n    // Try with copy\n    let slice: Option<[u32; 3]> = Some([1, 2, 3]);\n    if let Some([slice_0, ..]) = slice {\n        //~^ index_refutable_slice\n\n        println!(\"{}\", slice_0);\n    }\n\n    // Try with long slice and small indices\n    let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]);\n    if let Some([slice_0, _, slice_2, ..]) = slice {\n        //~^ index_refutable_slice\n\n        println!(\"{}\", slice_2);\n        println!(\"{}\", slice_0);\n    }\n\n    // Multiple bindings\n    let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]);\n    if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {\n        //~^ index_refutable_slice\n\n        println!(\"{}\", slice_0);\n    }\n\n    // Two lintable slices in one if let\n    let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]);\n    let b_wrapped: Option<[u32; 2]> = Some([4, 6]);\n    if let (SomeEnum::Three([_, _, a_2, ..]), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {\n        //~^ index_refutable_slice\n        //~| index_refutable_slice\n\n        println!(\"{} -> {}\", a_2, b_1);\n    }\n\n    // This requires the slice values to be borrowed as the slice values can only be\n    // borrowed and `String` doesn't implement copy\n    let slice: Option<[String; 2]> = Some([String::from(\"1\"), String::from(\"2\")]);\n    if let Some([_, ref slice_1, ..]) = slice {\n        //~^ index_refutable_slice\n\n        println!(\"{:?}\", slice_1);\n    }\n    println!(\"{slice:?}\");\n\n    // This should not suggest using the `ref` keyword as the scrutinee is already\n    // a reference\n    let slice: Option<[String; 2]> = Some([String::from(\"1\"), String::from(\"2\")]);\n    if let Some([slice_0, ..]) = &slice {\n        //~^ index_refutable_slice\n\n        println!(\"{:?}\", slice_0);\n    }\n    println!(\"{slice:?}\");\n}\n\nfn slice_index_above_limit() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n\n    if let Some(slice) = slice {\n        // Would cause a panic, IDK\n        println!(\"{}\", slice[7]);\n    }\n}\n\nfn slice_is_used() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        println!(\"{:?}\", slice.len());\n    }\n\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        println!(\"{:?}\", slice.to_vec());\n    }\n\n    let opt: Option<[String; 2]> = Some([String::from(\"Hello\"), String::from(\"world\")]);\n    if let Some(slice) = opt {\n        if !slice.is_empty() {\n            println!(\"first: {}\", slice[0]);\n        }\n    }\n}\n\n/// The slice is used by an external function and should therefore not be linted\nfn check_slice_as_arg() {\n    fn is_interesting<T>(slice: &[T; 2]) -> bool {\n        !slice.is_empty()\n    }\n\n    let slice_wrapped: Option<[String; 2]> = Some([String::from(\"Hello\"), String::from(\"world\")]);\n    if let Some(slice) = &slice_wrapped {\n        if is_interesting(slice) {\n            println!(\"This is interesting {}\", slice[0]);\n        }\n    }\n    println!(\"{slice_wrapped:?}\");\n}\n\nfn check_slice_in_struct() {\n    #[derive(Debug)]\n    struct Wrapper<'a> {\n        inner: Option<&'a [String]>,\n        is_awesome: bool,\n    }\n\n    impl<'a> Wrapper<'a> {\n        fn is_super_awesome(&self) -> bool {\n            self.is_awesome\n        }\n    }\n\n    let inner = &[String::from(\"New\"), String::from(\"World\")];\n    let wrap = Wrapper {\n        inner: Some(inner),\n        is_awesome: true,\n    };\n\n    // Test 1: Field access\n    if let Some([slice_0, ..]) = wrap.inner {\n        //~^ index_refutable_slice\n\n        if wrap.is_awesome {\n            println!(\"This is awesome! {}\", slice_0);\n        }\n    }\n\n    // Test 2: function access\n    if let Some([slice_0, ..]) = wrap.inner {\n        //~^ index_refutable_slice\n\n        if wrap.is_super_awesome() {\n            println!(\"This is super awesome! {}\", slice_0);\n        }\n    }\n    println!(\"Complete wrap: {wrap:?}\");\n}\n\n/// This would be a nice additional feature to have in the future, but adding it\n/// now would make the PR too large. This is therefore only a test that we don't\n/// lint cases we can't make a reasonable suggestion for\nfn mutable_slice_index() {\n    // Mut access\n    let mut slice: Option<[String; 1]> = Some([String::from(\"Penguin\")]);\n    if let Some(ref mut slice) = slice {\n        slice[0] = String::from(\"Mr. Penguin\");\n    }\n    println!(\"Use after modification: {slice:?}\");\n\n    // Mut access on reference\n    let mut slice: Option<[String; 1]> = Some([String::from(\"Cat\")]);\n    if let Some(slice) = &mut slice {\n        slice[0] = String::from(\"Lord Meow Meow\");\n    }\n    println!(\"Use after modification: {slice:?}\");\n}\n\n/// The lint will ignore bindings with sub patterns as it would be hard\n/// to build correct suggestions for these instances :)\nfn binding_with_sub_pattern() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice @ [_, _, _]) = slice {\n        println!(\"{:?}\", slice[2]);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/index_refutable_slice/if_let_slice_binding.rs",
    "content": "#![deny(clippy::index_refutable_slice)]\n#![allow(clippy::needless_lifetimes, clippy::collapsible_if)]\n\nenum SomeEnum<T> {\n    One(T),\n    Two(T),\n    Three(T),\n    Four(T),\n}\n\nfn lintable_examples() {\n    // Try with reference\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        //~^ index_refutable_slice\n\n        println!(\"{}\", slice[0]);\n    }\n\n    // Try with copy\n    let slice: Option<[u32; 3]> = Some([1, 2, 3]);\n    if let Some(slice) = slice {\n        //~^ index_refutable_slice\n\n        println!(\"{}\", slice[0]);\n    }\n\n    // Try with long slice and small indices\n    let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]);\n    if let Some(slice) = slice {\n        //~^ index_refutable_slice\n\n        println!(\"{}\", slice[2]);\n        println!(\"{}\", slice[0]);\n    }\n\n    // Multiple bindings\n    let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]);\n    if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {\n        //~^ index_refutable_slice\n\n        println!(\"{}\", slice[0]);\n    }\n\n    // Two lintable slices in one if let\n    let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]);\n    let b_wrapped: Option<[u32; 2]> = Some([4, 6]);\n    if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {\n        //~^ index_refutable_slice\n        //~| index_refutable_slice\n\n        println!(\"{} -> {}\", a[2], b[1]);\n    }\n\n    // This requires the slice values to be borrowed as the slice values can only be\n    // borrowed and `String` doesn't implement copy\n    let slice: Option<[String; 2]> = Some([String::from(\"1\"), String::from(\"2\")]);\n    if let Some(ref slice) = slice {\n        //~^ index_refutable_slice\n\n        println!(\"{:?}\", slice[1]);\n    }\n    println!(\"{slice:?}\");\n\n    // This should not suggest using the `ref` keyword as the scrutinee is already\n    // a reference\n    let slice: Option<[String; 2]> = Some([String::from(\"1\"), String::from(\"2\")]);\n    if let Some(slice) = &slice {\n        //~^ index_refutable_slice\n\n        println!(\"{:?}\", slice[0]);\n    }\n    println!(\"{slice:?}\");\n}\n\nfn slice_index_above_limit() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n\n    if let Some(slice) = slice {\n        // Would cause a panic, IDK\n        println!(\"{}\", slice[7]);\n    }\n}\n\nfn slice_is_used() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        println!(\"{:?}\", slice.len());\n    }\n\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        println!(\"{:?}\", slice.to_vec());\n    }\n\n    let opt: Option<[String; 2]> = Some([String::from(\"Hello\"), String::from(\"world\")]);\n    if let Some(slice) = opt {\n        if !slice.is_empty() {\n            println!(\"first: {}\", slice[0]);\n        }\n    }\n}\n\n/// The slice is used by an external function and should therefore not be linted\nfn check_slice_as_arg() {\n    fn is_interesting<T>(slice: &[T; 2]) -> bool {\n        !slice.is_empty()\n    }\n\n    let slice_wrapped: Option<[String; 2]> = Some([String::from(\"Hello\"), String::from(\"world\")]);\n    if let Some(slice) = &slice_wrapped {\n        if is_interesting(slice) {\n            println!(\"This is interesting {}\", slice[0]);\n        }\n    }\n    println!(\"{slice_wrapped:?}\");\n}\n\nfn check_slice_in_struct() {\n    #[derive(Debug)]\n    struct Wrapper<'a> {\n        inner: Option<&'a [String]>,\n        is_awesome: bool,\n    }\n\n    impl<'a> Wrapper<'a> {\n        fn is_super_awesome(&self) -> bool {\n            self.is_awesome\n        }\n    }\n\n    let inner = &[String::from(\"New\"), String::from(\"World\")];\n    let wrap = Wrapper {\n        inner: Some(inner),\n        is_awesome: true,\n    };\n\n    // Test 1: Field access\n    if let Some(slice) = wrap.inner {\n        //~^ index_refutable_slice\n\n        if wrap.is_awesome {\n            println!(\"This is awesome! {}\", slice[0]);\n        }\n    }\n\n    // Test 2: function access\n    if let Some(slice) = wrap.inner {\n        //~^ index_refutable_slice\n\n        if wrap.is_super_awesome() {\n            println!(\"This is super awesome! {}\", slice[0]);\n        }\n    }\n    println!(\"Complete wrap: {wrap:?}\");\n}\n\n/// This would be a nice additional feature to have in the future, but adding it\n/// now would make the PR too large. This is therefore only a test that we don't\n/// lint cases we can't make a reasonable suggestion for\nfn mutable_slice_index() {\n    // Mut access\n    let mut slice: Option<[String; 1]> = Some([String::from(\"Penguin\")]);\n    if let Some(ref mut slice) = slice {\n        slice[0] = String::from(\"Mr. Penguin\");\n    }\n    println!(\"Use after modification: {slice:?}\");\n\n    // Mut access on reference\n    let mut slice: Option<[String; 1]> = Some([String::from(\"Cat\")]);\n    if let Some(slice) = &mut slice {\n        slice[0] = String::from(\"Lord Meow Meow\");\n    }\n    println!(\"Use after modification: {slice:?}\");\n}\n\n/// The lint will ignore bindings with sub patterns as it would be hard\n/// to build correct suggestions for these instances :)\nfn binding_with_sub_pattern() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice @ [_, _, _]) = slice {\n        println!(\"{:?}\", slice[2]);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/index_refutable_slice/if_let_slice_binding.stderr",
    "content": "error: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:14:17\n   |\nLL |     if let Some(slice) = slice {\n   |                 ^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:1:9\n   |\nLL | #![deny(clippy::index_refutable_slice)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([slice_0, ..]) = slice {\nLL |\nLL |\nLL ~         println!(\"{}\", slice_0);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:22:17\n   |\nLL |     if let Some(slice) = slice {\n   |                 ^^^^^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([slice_0, ..]) = slice {\nLL |\nLL |\nLL ~         println!(\"{}\", slice_0);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:30:17\n   |\nLL |     if let Some(slice) = slice {\n   |                 ^^^^^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([slice_0, _, slice_2, ..]) = slice {\nLL |\nLL |\nLL ~         println!(\"{}\", slice_2);\nLL ~         println!(\"{}\", slice_0);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:39:26\n   |\nLL |     if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {\n   |                          ^^^^^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {\nLL |\nLL |\nLL ~         println!(\"{}\", slice_0);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:48:29\n   |\nLL |     if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {\n   |                             ^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let (SomeEnum::Three([_, _, a_2, ..]), Some(b)) = (a_wrapped, b_wrapped) {\nLL |\nLL |\nLL |\nLL ~         println!(\"{} -> {}\", a_2, b[1]);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:48:38\n   |\nLL |     if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {\n   |                                      ^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let (SomeEnum::Three(a), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {\nLL |\nLL |\nLL |\nLL ~         println!(\"{} -> {}\", a[2], b_1);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:58:21\n   |\nLL |     if let Some(ref slice) = slice {\n   |                     ^^^^^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([_, ref slice_1, ..]) = slice {\nLL |\nLL |\nLL ~         println!(\"{:?}\", slice_1);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:68:17\n   |\nLL |     if let Some(slice) = &slice {\n   |                 ^^^^^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([slice_0, ..]) = &slice {\nLL |\nLL |\nLL ~         println!(\"{:?}\", slice_0);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:139:17\n   |\nLL |     if let Some(slice) = wrap.inner {\n   |                 ^^^^^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([slice_0, ..]) = wrap.inner {\nLL |\nLL |\nLL |         if wrap.is_awesome {\nLL ~             println!(\"This is awesome! {}\", slice_0);\n   |\n\nerror: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:148:17\n   |\nLL |     if let Some(slice) = wrap.inner {\n   |                 ^^^^^\n   |\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([slice_0, ..]) = wrap.inner {\nLL |\nLL |\nLL |         if wrap.is_super_awesome() {\nLL ~             println!(\"This is super awesome! {}\", slice_0);\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed",
    "content": "#![deny(clippy::index_refutable_slice)]\n\nmacro_rules! if_let_slice_macro {\n    () => {\n        // This would normally be linted\n        let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n        if let Some(slice) = slice {\n            println!(\"{}\", slice[0]);\n        }\n    };\n}\n\nfn main() {\n    // Don't lint this\n    if_let_slice_macro!();\n\n    // Do lint this\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some([slice_0, ..]) = slice {\n        //~^ ERROR: this binding can be a slice pattern to avoid indexing\n        println!(\"{}\", slice_0);\n    }\n}\n"
  },
  {
    "path": "tests/ui/index_refutable_slice/slice_indexing_in_macro.rs",
    "content": "#![deny(clippy::index_refutable_slice)]\n\nmacro_rules! if_let_slice_macro {\n    () => {\n        // This would normally be linted\n        let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n        if let Some(slice) = slice {\n            println!(\"{}\", slice[0]);\n        }\n    };\n}\n\nfn main() {\n    // Don't lint this\n    if_let_slice_macro!();\n\n    // Do lint this\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        //~^ ERROR: this binding can be a slice pattern to avoid indexing\n        println!(\"{}\", slice[0]);\n    }\n}\n"
  },
  {
    "path": "tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr",
    "content": "error: this binding can be a slice pattern to avoid indexing\n  --> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:19:17\n   |\nLL |     if let Some(slice) = slice {\n   |                 ^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:1:9\n   |\nLL | #![deny(clippy::index_refutable_slice)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([slice_0, ..]) = slice {\nLL |\nLL ~         println!(\"{}\", slice_0);\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/indexing_slicing_index.rs",
    "content": "//@compile-flags: -Zdeduplicate-diagnostics=yes\n//@aux-build: proc_macros.rs\n\n#![warn(clippy::indexing_slicing)]\n// We also check the out_of_bounds_indexing lint here, because it lints similar things and\n// we want to avoid false positives.\n#![warn(clippy::out_of_bounds_indexing)]\n#![allow(\n    unconditional_panic,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::useless_vec\n)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nconst ARR: [i32; 2] = [1, 2];\nconst REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false.\n//~^ ERROR: indexing may panic\n\nconst fn idx() -> usize {\n    1\n}\nconst fn idx4() -> usize {\n    4\n}\n\nwith_span!(\n    span\n\n    fn dont_lint_proc_macro_array() {\n        let x = [1, 2, 3, 4];\n        let index: usize = 1;\n        x[index];\n        x[10];\n\n        let x = vec![0; 5];\n        let index: usize = 1;\n        x[index];\n        x[10];\n    }\n);\n\nfn main() {\n    let x = [1, 2, 3, 4];\n    let index: usize = 1;\n    x[index];\n    //~^ ERROR: indexing may panic\n    // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.\n    x[4];\n    //~^ out_of_bounds_indexing\n    // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.\n    x[1 << 3];\n    //~^ out_of_bounds_indexing\n\n    // Ok, should not produce stderr.\n    x[0];\n    // Ok, should not produce stderr.\n    x[3];\n    // Ok, should not produce stderr.\n    x[const { idx() }];\n    // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.\n    x[const { idx4() }];\n    // This should be linted, since `suppress-restriction-lint-in-const` default is false.\n    const { &ARR[idx()] };\n    //~^ ERROR: indexing may panic\n    // This should be linted, since `suppress-restriction-lint-in-const` default is false.\n    const { &ARR[idx4()] };\n    //~^ ERROR: indexing may panic\n\n    let y = &x;\n    // Ok, referencing shouldn't affect this lint. See the issue 6021\n    y[0];\n    // Ok, rustc will handle references too.\n    y[4];\n    //~^ out_of_bounds_indexing\n\n    let v = vec![0; 5];\n    v[0];\n    //~^ ERROR: indexing may panic\n    v[10];\n    //~^ ERROR: indexing may panic\n    v[1 << 3];\n    //~^ ERROR: indexing may panic\n\n    // Out of bounds\n    const N: usize = 15;\n    // In bounds\n    const M: usize = 3;\n    // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.\n    x[N];\n    //~^ out_of_bounds_indexing\n    // Ok, should not produce stderr.\n    x[M];\n    v[N];\n    //~^ ERROR: indexing may panic\n    v[M];\n    //~^ ERROR: indexing may panic\n\n    let slice = &x;\n    let _ = x[4];\n    //~^ out_of_bounds_indexing\n}\n"
  },
  {
    "path": "tests/ui/indexing_slicing_index.stderr",
    "content": "error: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:19:20\n   |\nLL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false.\n   |                    ^^^^^^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n   = note: the suggestion might not be applicable in constant blocks\n   = note: `-D clippy::indexing-slicing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:48:5\n   |\nLL |     x[index];\n   |     ^^^^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: index is out of bounds\n  --> tests/ui/indexing_slicing_index.rs:51:5\n   |\nLL |     x[4];\n   |     ^^^^\n   |\n   = note: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`\n\nerror: index is out of bounds\n  --> tests/ui/indexing_slicing_index.rs:54:5\n   |\nLL |     x[1 << 3];\n   |     ^^^^^^^^^\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:66:14\n   |\nLL |     const { &ARR[idx()] };\n   |              ^^^^^^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n   = note: the suggestion might not be applicable in constant blocks\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:69:14\n   |\nLL |     const { &ARR[idx4()] };\n   |              ^^^^^^^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n   = note: the suggestion might not be applicable in constant blocks\n\nerror: index is out of bounds\n  --> tests/ui/indexing_slicing_index.rs:76:5\n   |\nLL |     y[4];\n   |     ^^^^\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:80:5\n   |\nLL |     v[0];\n   |     ^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:82:5\n   |\nLL |     v[10];\n   |     ^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:84:5\n   |\nLL |     v[1 << 3];\n   |     ^^^^^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: index is out of bounds\n  --> tests/ui/indexing_slicing_index.rs:92:5\n   |\nLL |     x[N];\n   |     ^^^^\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:96:5\n   |\nLL |     v[N];\n   |     ^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_index.rs:98:5\n   |\nLL |     v[M];\n   |     ^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: index is out of bounds\n  --> tests/ui/indexing_slicing_index.rs:102:13\n   |\nLL |     let _ = x[4];\n   |             ^^^^\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/indexing_slicing_slice.rs",
    "content": "//@aux-build: proc_macros.rs\n\n// We also check the out_of_bounds_indexing lint here, because it lints similar things and\n// we want to avoid false positives.\n#![warn(clippy::out_of_bounds_indexing)]\n#![allow(\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::useless_vec,\n    unused_must_use,\n    unused\n)]\n#![warn(clippy::indexing_slicing)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nuse std::ops::Index;\n\nstruct BoolMap<T> {\n    false_value: T,\n    true_value: T,\n}\n\nimpl<T> Index<bool> for BoolMap<T> {\n    type Output = T;\n    fn index(&self, index: bool) -> &T {\n        if index { &self.true_value } else { &self.false_value }\n    }\n}\n\nstruct BoolMapWithGet<T> {\n    false_value: T,\n    true_value: T,\n}\n\nimpl<T> Index<bool> for BoolMapWithGet<T> {\n    type Output = T;\n    fn index(&self, index: bool) -> &Self::Output {\n        if index { &self.true_value } else { &self.false_value }\n    }\n}\n\nimpl<T> BoolMapWithGet<T> {\n    fn get(&self, index: bool) -> Option<&T> {\n        if index {\n            Some(&self.true_value)\n        } else {\n            Some(&self.false_value)\n        }\n    }\n}\n\nstruct S<T>(T);\nimpl S<i32> {\n    fn get() -> Option<i32> {\n        unimplemented!()\n    }\n}\nimpl<T> Index<i32> for S<T> {\n    type Output = T;\n    fn index(&self, _index: i32) -> &Self::Output {\n        &self.0\n    }\n}\n\nstruct Y<T>(T);\nimpl Y<i32> {\n    fn get<U>() -> Option<U> {\n        unimplemented!()\n    }\n}\nimpl<T> Index<i32> for Y<T> {\n    type Output = T;\n    fn index(&self, _index: i32) -> &Self::Output {\n        &self.0\n    }\n}\n\nstruct Z<T>(T);\nimpl<T> Z<T> {\n    fn get<T2>() -> T2 {\n        unimplemented!()\n    }\n}\nimpl<T> Index<i32> for Z<T> {\n    type Output = T;\n    fn index(&self, _index: i32) -> &Self::Output {\n        &self.0\n    }\n}\n\nwith_span!(\n    span\n\n    fn dont_lint_proc_macro() {\n        let x = [1, 2, 3, 4];\n        let index: usize = 1;\n        &x[index..];\n        &x[..10];\n\n        let x = vec![0; 5];\n        let index: usize = 1;\n        &x[index..];\n        &x[..10];\n    }\n);\n\nfn main() {\n    let x = [1, 2, 3, 4];\n    let index: usize = 1;\n    let index_from: usize = 2;\n    let index_to: usize = 3;\n    &x[index..];\n    //~^ indexing_slicing\n    &x[..index];\n    //~^ indexing_slicing\n    &x[index_from..index_to];\n    //~^ indexing_slicing\n    &x[index_from..][..index_to];\n    //~^ indexing_slicing\n    //~| indexing_slicing\n    &x[5..][..10];\n    //~^ indexing_slicing\n    //~| out_of_bounds_indexing\n    &x[0..][..3];\n    //~^ indexing_slicing\n    &x[1..][..5];\n    //~^ indexing_slicing\n\n    &x[0..].get(..3); // Ok, should not produce stderr.\n    &x[0..3]; // Ok, should not produce stderr.\n\n    let y = &x;\n    &y[1..2];\n    &y[0..=4];\n    //~^ out_of_bounds_indexing\n    &y[..=4];\n    //~^ out_of_bounds_indexing\n\n    &y[..]; // Ok, should not produce stderr.\n\n    let v = vec![0; 5];\n    &v[10..100];\n    //~^ indexing_slicing\n    &x[10..][..100];\n    //~^ indexing_slicing\n    //~| out_of_bounds_indexing\n    &v[10..];\n    //~^ indexing_slicing\n    &v[..100];\n    //~^ indexing_slicing\n\n    &v[..]; // Ok, should not produce stderr.\n\n    let map = BoolMap {\n        false_value: 2,\n        true_value: 4,\n    };\n\n    map[true]; // Ok, because `get` does not exist (custom indexing)\n\n    let map_with_get = BoolMapWithGet {\n        false_value: 2,\n        true_value: 4,\n    };\n\n    // Lint on this, because `get` does exist with same signature\n    map_with_get[true];\n    //~^ indexing_slicing\n\n    let s = S::<i32>(1);\n    s[0];\n    //~^ indexing_slicing\n\n    let y = Y::<i32>(1);\n    y[0];\n    //~^ indexing_slicing\n\n    let z = Z::<i32>(1);\n    z[0];\n}\n"
  },
  {
    "path": "tests/ui/indexing_slicing_slice.stderr",
    "content": "error: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:114:6\n   |\nLL |     &x[index..];\n   |      ^^^^^^^^^^\n   |\n   = help: consider using `.get(n..)` or .get_mut(n..)` instead\n   = note: `-D clippy::indexing-slicing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:116:6\n   |\nLL |     &x[..index];\n   |      ^^^^^^^^^^\n   |\n   = help: consider using `.get(..n)`or `.get_mut(..n)` instead\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:118:6\n   |\nLL |     &x[index_from..index_to];\n   |      ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:120:6\n   |\nLL |     &x[index_from..][..index_to];\n   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `.get(..n)`or `.get_mut(..n)` instead\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:120:6\n   |\nLL |     &x[index_from..][..index_to];\n   |      ^^^^^^^^^^^^^^^\n   |\n   = help: consider using `.get(n..)` or .get_mut(n..)` instead\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:123:6\n   |\nLL |     &x[5..][..10];\n   |      ^^^^^^^^^^^^\n   |\n   = help: consider using `.get(..n)`or `.get_mut(..n)` instead\n\nerror: range is out of bounds\n  --> tests/ui/indexing_slicing_slice.rs:123:8\n   |\nLL |     &x[5..][..10];\n   |        ^\n   |\n   = note: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:126:6\n   |\nLL |     &x[0..][..3];\n   |      ^^^^^^^^^^^\n   |\n   = help: consider using `.get(..n)`or `.get_mut(..n)` instead\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:128:6\n   |\nLL |     &x[1..][..5];\n   |      ^^^^^^^^^^^\n   |\n   = help: consider using `.get(..n)`or `.get_mut(..n)` instead\n\nerror: range is out of bounds\n  --> tests/ui/indexing_slicing_slice.rs:136:12\n   |\nLL |     &y[0..=4];\n   |            ^\n\nerror: range is out of bounds\n  --> tests/ui/indexing_slicing_slice.rs:138:11\n   |\nLL |     &y[..=4];\n   |           ^\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:144:6\n   |\nLL |     &v[10..100];\n   |      ^^^^^^^^^^\n   |\n   = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:146:6\n   |\nLL |     &x[10..][..100];\n   |      ^^^^^^^^^^^^^^\n   |\n   = help: consider using `.get(..n)`or `.get_mut(..n)` instead\n\nerror: range is out of bounds\n  --> tests/ui/indexing_slicing_slice.rs:146:8\n   |\nLL |     &x[10..][..100];\n   |        ^^\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:149:6\n   |\nLL |     &v[10..];\n   |      ^^^^^^^\n   |\n   = help: consider using `.get(n..)` or .get_mut(n..)` instead\n\nerror: slicing may panic\n  --> tests/ui/indexing_slicing_slice.rs:151:6\n   |\nLL |     &v[..100];\n   |      ^^^^^^^^\n   |\n   = help: consider using `.get(..n)`or `.get_mut(..n)` instead\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_slice.rs:169:5\n   |\nLL |     map_with_get[true];\n   |     ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_slice.rs:173:5\n   |\nLL |     s[0];\n   |     ^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui/indexing_slicing_slice.rs:177:5\n   |\nLL |     y[0];\n   |     ^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/ineffective_open_options.fixed",
    "content": "#![warn(clippy::ineffective_open_options)]\n\nuse std::fs::OpenOptions;\n\nfn main() {\n    let file = OpenOptions::new()\n        .create(true)\n        \n        //~^ ineffective_open_options\n        .append(true)\n        .open(\"dump.json\")\n        .unwrap();\n\n    let file = OpenOptions::new()\n        .create(true)\n        .append(true)\n        \n        //~^ ineffective_open_options\n        .open(\"dump.json\")\n        .unwrap();\n\n    // All the next calls are ok.\n    let file = OpenOptions::new()\n        .create(true)\n        .write(false)\n        .append(true)\n        .open(\"dump.json\")\n        .unwrap();\n    let file = OpenOptions::new()\n        .create(true)\n        .truncate(true)\n        .write(true)\n        .append(false)\n        .open(\"dump.json\")\n        .unwrap();\n    let file = OpenOptions::new()\n        .create(true)\n        .truncate(true)\n        .write(false)\n        .append(false)\n        .open(\"dump.json\")\n        .unwrap();\n    let file = OpenOptions::new().create(true).append(true).open(\"dump.json\").unwrap();\n    let file = OpenOptions::new()\n        .create(true)\n        .truncate(true)\n        .write(true)\n        .open(\"dump.json\")\n        .unwrap();\n}\n"
  },
  {
    "path": "tests/ui/ineffective_open_options.rs",
    "content": "#![warn(clippy::ineffective_open_options)]\n\nuse std::fs::OpenOptions;\n\nfn main() {\n    let file = OpenOptions::new()\n        .create(true)\n        .write(true)\n        //~^ ineffective_open_options\n        .append(true)\n        .open(\"dump.json\")\n        .unwrap();\n\n    let file = OpenOptions::new()\n        .create(true)\n        .append(true)\n        .write(true)\n        //~^ ineffective_open_options\n        .open(\"dump.json\")\n        .unwrap();\n\n    // All the next calls are ok.\n    let file = OpenOptions::new()\n        .create(true)\n        .write(false)\n        .append(true)\n        .open(\"dump.json\")\n        .unwrap();\n    let file = OpenOptions::new()\n        .create(true)\n        .truncate(true)\n        .write(true)\n        .append(false)\n        .open(\"dump.json\")\n        .unwrap();\n    let file = OpenOptions::new()\n        .create(true)\n        .truncate(true)\n        .write(false)\n        .append(false)\n        .open(\"dump.json\")\n        .unwrap();\n    let file = OpenOptions::new().create(true).append(true).open(\"dump.json\").unwrap();\n    let file = OpenOptions::new()\n        .create(true)\n        .truncate(true)\n        .write(true)\n        .open(\"dump.json\")\n        .unwrap();\n}\n"
  },
  {
    "path": "tests/ui/ineffective_open_options.stderr",
    "content": "error: unnecessary use of `.write(true)` because there is `.append(true)`\n  --> tests/ui/ineffective_open_options.rs:8:9\n   |\nLL |         .write(true)\n   |         ^^^^^^^^^^^^ help: remove `.write(true)`\n   |\n   = note: `-D clippy::ineffective-open-options` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ineffective_open_options)]`\n\nerror: unnecessary use of `.write(true)` because there is `.append(true)`\n  --> tests/ui/ineffective_open_options.rs:17:9\n   |\nLL |         .write(true)\n   |         ^^^^^^^^^^^^ help: remove `.write(true)`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/inefficient_to_string.fixed",
    "content": "#![deny(clippy::inefficient_to_string)]\n\nuse std::borrow::Cow;\n\n#[clippy::msrv = \"1.81\"]\nfn main() {\n    let rstr: &str = \"hello\";\n    let rrstr: &&str = &rstr;\n    let rrrstr: &&&str = &rrstr;\n    let _: String = rstr.to_string();\n    let _: String = (*rrstr).to_string();\n    //~^ inefficient_to_string\n    let _: String = (**rrrstr).to_string();\n    //~^ inefficient_to_string\n\n    let string: String = String::from(\"hello\");\n    let rstring: &String = &string;\n    let rrstring: &&String = &rstring;\n    let rrrstring: &&&String = &rrstring;\n    let _: String = string.to_string();\n    let _: String = rstring.to_string();\n    let _: String = (*rrstring).to_string();\n    //~^ inefficient_to_string\n    let _: String = (**rrrstring).to_string();\n    //~^ inefficient_to_string\n\n    let cow: Cow<'_, str> = Cow::Borrowed(\"hello\");\n    let rcow: &Cow<'_, str> = &cow;\n    let rrcow: &&Cow<'_, str> = &rcow;\n    let rrrcow: &&&Cow<'_, str> = &rrcow;\n    let _: String = cow.to_string();\n    let _: String = rcow.to_string();\n    let _: String = (*rrcow).to_string();\n    //~^ inefficient_to_string\n    let _: String = (**rrrcow).to_string();\n    //~^ inefficient_to_string\n}\n\n#[clippy::msrv = \"1.82\"]\nfn sufficient_msrv() {\n    let rstr: &str = \"hello\";\n    let rrstr: &&str = &rstr;\n    let _: String = rrstr.to_string();\n}\n"
  },
  {
    "path": "tests/ui/inefficient_to_string.rs",
    "content": "#![deny(clippy::inefficient_to_string)]\n\nuse std::borrow::Cow;\n\n#[clippy::msrv = \"1.81\"]\nfn main() {\n    let rstr: &str = \"hello\";\n    let rrstr: &&str = &rstr;\n    let rrrstr: &&&str = &rrstr;\n    let _: String = rstr.to_string();\n    let _: String = rrstr.to_string();\n    //~^ inefficient_to_string\n    let _: String = rrrstr.to_string();\n    //~^ inefficient_to_string\n\n    let string: String = String::from(\"hello\");\n    let rstring: &String = &string;\n    let rrstring: &&String = &rstring;\n    let rrrstring: &&&String = &rrstring;\n    let _: String = string.to_string();\n    let _: String = rstring.to_string();\n    let _: String = rrstring.to_string();\n    //~^ inefficient_to_string\n    let _: String = rrrstring.to_string();\n    //~^ inefficient_to_string\n\n    let cow: Cow<'_, str> = Cow::Borrowed(\"hello\");\n    let rcow: &Cow<'_, str> = &cow;\n    let rrcow: &&Cow<'_, str> = &rcow;\n    let rrrcow: &&&Cow<'_, str> = &rrcow;\n    let _: String = cow.to_string();\n    let _: String = rcow.to_string();\n    let _: String = rrcow.to_string();\n    //~^ inefficient_to_string\n    let _: String = rrrcow.to_string();\n    //~^ inefficient_to_string\n}\n\n#[clippy::msrv = \"1.82\"]\nfn sufficient_msrv() {\n    let rstr: &str = \"hello\";\n    let rrstr: &&str = &rstr;\n    let _: String = rrstr.to_string();\n}\n"
  },
  {
    "path": "tests/ui/inefficient_to_string.stderr",
    "content": "error: calling `to_string` on `&&str`\n  --> tests/ui/inefficient_to_string.rs:11:21\n   |\nLL |     let _: String = rrstr.to_string();\n   |                     ^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrstr).to_string()`\n   |\n   = help: `&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString`\nnote: the lint level is defined here\n  --> tests/ui/inefficient_to_string.rs:1:9\n   |\nLL | #![deny(clippy::inefficient_to_string)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: calling `to_string` on `&&&str`\n  --> tests/ui/inefficient_to_string.rs:13:21\n   |\nLL |     let _: String = rrrstr.to_string();\n   |                     ^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrstr).to_string()`\n   |\n   = help: `&&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString`\n\nerror: calling `to_string` on `&&std::string::String`\n  --> tests/ui/inefficient_to_string.rs:22:21\n   |\nLL |     let _: String = rrstring.to_string();\n   |                     ^^^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrstring).to_string()`\n   |\n   = help: `&std::string::String` implements `ToString` through a slower blanket impl, but `std::string::String` has a fast specialization of `ToString`\n\nerror: calling `to_string` on `&&&std::string::String`\n  --> tests/ui/inefficient_to_string.rs:24:21\n   |\nLL |     let _: String = rrrstring.to_string();\n   |                     ^^^^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrstring).to_string()`\n   |\n   = help: `&&std::string::String` implements `ToString` through a slower blanket impl, but `std::string::String` has a fast specialization of `ToString`\n\nerror: calling `to_string` on `&&std::borrow::Cow<'_, str>`\n  --> tests/ui/inefficient_to_string.rs:33:21\n   |\nLL |     let _: String = rrcow.to_string();\n   |                     ^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrcow).to_string()`\n   |\n   = help: `&std::borrow::Cow<'_, str>` implements `ToString` through a slower blanket impl, but `std::borrow::Cow<'_, str>` has a fast specialization of `ToString`\n\nerror: calling `to_string` on `&&&std::borrow::Cow<'_, str>`\n  --> tests/ui/inefficient_to_string.rs:35:21\n   |\nLL |     let _: String = rrrcow.to_string();\n   |                     ^^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(**rrrcow).to_string()`\n   |\n   = help: `&&std::borrow::Cow<'_, str>` implements `ToString` through a slower blanket impl, but `std::borrow::Cow<'_, str>` has a fast specialization of `ToString`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/infallible_destructuring_match.fixed",
    "content": "#![feature(exhaustive_patterns, never_type)]\n#![allow(dead_code, unreachable_code, unused_variables)]\n#![allow(clippy::let_and_return, clippy::uninhabited_references)]\n\nenum SingleVariantEnum {\n    Variant(i32),\n}\n\nstruct TupleStruct(i32);\n\nstruct NonCopy;\nstruct TupleStructWithNonCopy(NonCopy);\n\nenum EmptyEnum {}\n\nmacro_rules! match_enum {\n    ($param:expr) => {\n        let data = match $param {\n            SingleVariantEnum::Variant(i) => i,\n        };\n    };\n}\n\nfn infallible_destructuring_match_enum() {\n    let wrapper = SingleVariantEnum::Variant(0);\n\n    // This should lint!\n    let SingleVariantEnum::Variant(data) = wrapper;\n\n    // This shouldn't (inside macro)\n    match_enum!(wrapper);\n\n    // This shouldn't!\n    let data = match wrapper {\n        SingleVariantEnum::Variant(_) => -1,\n    };\n\n    // Neither should this!\n    let data = match wrapper {\n        SingleVariantEnum::Variant(i) => -1,\n    };\n\n    let SingleVariantEnum::Variant(data) = wrapper;\n}\n\nmacro_rules! match_struct {\n    ($param:expr) => {\n        let data = match $param {\n            TupleStruct(i) => i,\n        };\n    };\n}\n\nfn infallible_destructuring_match_struct() {\n    let wrapper = TupleStruct(0);\n\n    // This should lint!\n    let TupleStruct(data) = wrapper;\n\n    // This shouldn't (inside macro)\n    match_struct!(wrapper);\n\n    // This shouldn't!\n    let data = match wrapper {\n        TupleStruct(_) => -1,\n    };\n\n    // Neither should this!\n    let data = match wrapper {\n        TupleStruct(i) => -1,\n    };\n\n    let TupleStruct(data) = wrapper;\n}\n\nfn infallible_destructuring_match_struct_with_noncopy() {\n    let wrapper = TupleStructWithNonCopy(NonCopy);\n\n    // This should lint! (keeping `ref` in the suggestion)\n    let TupleStructWithNonCopy(ref data) = wrapper;\n\n    let TupleStructWithNonCopy(ref data) = wrapper;\n}\n\nmacro_rules! match_never_enum {\n    ($param:expr) => {\n        let data = match $param {\n            Ok(i) => i,\n        };\n    };\n}\n\nfn never_enum() {\n    let wrapper: Result<i32, !> = Ok(23);\n\n    // This should lint!\n    let Ok(data) = wrapper;\n\n    // This shouldn't (inside macro)\n    match_never_enum!(wrapper);\n\n    // This shouldn't!\n    let data = match wrapper {\n        Ok(_) => -1,\n    };\n\n    // Neither should this!\n    let data = match wrapper {\n        Ok(i) => -1,\n    };\n\n    let Ok(data) = wrapper;\n}\n\nimpl EmptyEnum {\n    fn match_on(&self) -> ! {\n        // The lint shouldn't pick this up, as `let` won't work here!\n        let data = match *self {};\n        data\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/infallible_destructuring_match.rs",
    "content": "#![feature(exhaustive_patterns, never_type)]\n#![allow(dead_code, unreachable_code, unused_variables)]\n#![allow(clippy::let_and_return, clippy::uninhabited_references)]\n\nenum SingleVariantEnum {\n    Variant(i32),\n}\n\nstruct TupleStruct(i32);\n\nstruct NonCopy;\nstruct TupleStructWithNonCopy(NonCopy);\n\nenum EmptyEnum {}\n\nmacro_rules! match_enum {\n    ($param:expr) => {\n        let data = match $param {\n            SingleVariantEnum::Variant(i) => i,\n        };\n    };\n}\n\nfn infallible_destructuring_match_enum() {\n    let wrapper = SingleVariantEnum::Variant(0);\n\n    // This should lint!\n    let data = match wrapper {\n        //~^ infallible_destructuring_match\n        SingleVariantEnum::Variant(i) => i,\n    };\n\n    // This shouldn't (inside macro)\n    match_enum!(wrapper);\n\n    // This shouldn't!\n    let data = match wrapper {\n        SingleVariantEnum::Variant(_) => -1,\n    };\n\n    // Neither should this!\n    let data = match wrapper {\n        SingleVariantEnum::Variant(i) => -1,\n    };\n\n    let SingleVariantEnum::Variant(data) = wrapper;\n}\n\nmacro_rules! match_struct {\n    ($param:expr) => {\n        let data = match $param {\n            TupleStruct(i) => i,\n        };\n    };\n}\n\nfn infallible_destructuring_match_struct() {\n    let wrapper = TupleStruct(0);\n\n    // This should lint!\n    let data = match wrapper {\n        //~^ infallible_destructuring_match\n        TupleStruct(i) => i,\n    };\n\n    // This shouldn't (inside macro)\n    match_struct!(wrapper);\n\n    // This shouldn't!\n    let data = match wrapper {\n        TupleStruct(_) => -1,\n    };\n\n    // Neither should this!\n    let data = match wrapper {\n        TupleStruct(i) => -1,\n    };\n\n    let TupleStruct(data) = wrapper;\n}\n\nfn infallible_destructuring_match_struct_with_noncopy() {\n    let wrapper = TupleStructWithNonCopy(NonCopy);\n\n    // This should lint! (keeping `ref` in the suggestion)\n    let data = match wrapper {\n        //~^ infallible_destructuring_match\n        TupleStructWithNonCopy(ref n) => n,\n    };\n\n    let TupleStructWithNonCopy(ref data) = wrapper;\n}\n\nmacro_rules! match_never_enum {\n    ($param:expr) => {\n        let data = match $param {\n            Ok(i) => i,\n        };\n    };\n}\n\nfn never_enum() {\n    let wrapper: Result<i32, !> = Ok(23);\n\n    // This should lint!\n    let data = match wrapper {\n        //~^ infallible_destructuring_match\n        Ok(i) => i,\n    };\n\n    // This shouldn't (inside macro)\n    match_never_enum!(wrapper);\n\n    // This shouldn't!\n    let data = match wrapper {\n        Ok(_) => -1,\n    };\n\n    // Neither should this!\n    let data = match wrapper {\n        Ok(i) => -1,\n    };\n\n    let Ok(data) = wrapper;\n}\n\nimpl EmptyEnum {\n    fn match_on(&self) -> ! {\n        // The lint shouldn't pick this up, as `let` won't work here!\n        let data = match *self {};\n        data\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/infallible_destructuring_match.stderr",
    "content": "error: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`\n  --> tests/ui/infallible_destructuring_match.rs:28:5\n   |\nLL | /     let data = match wrapper {\nLL | |\nLL | |         SingleVariantEnum::Variant(i) => i,\nLL | |     };\n   | |______^ help: try: `let SingleVariantEnum::Variant(data) = wrapper;`\n   |\n   = note: `-D clippy::infallible-destructuring-match` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::infallible_destructuring_match)]`\n\nerror: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`\n  --> tests/ui/infallible_destructuring_match.rs:61:5\n   |\nLL | /     let data = match wrapper {\nLL | |\nLL | |         TupleStruct(i) => i,\nLL | |     };\n   | |______^ help: try: `let TupleStruct(data) = wrapper;`\n\nerror: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`\n  --> tests/ui/infallible_destructuring_match.rs:86:5\n   |\nLL | /     let data = match wrapper {\nLL | |\nLL | |         TupleStructWithNonCopy(ref n) => n,\nLL | |     };\n   | |______^ help: try: `let TupleStructWithNonCopy(ref data) = wrapper;`\n\nerror: you seem to be trying to use `match` to destructure a single infallible pattern. Consider using `let`\n  --> tests/ui/infallible_destructuring_match.rs:106:5\n   |\nLL | /     let data = match wrapper {\nLL | |\nLL | |         Ok(i) => i,\nLL | |     };\n   | |______^ help: try: `let Ok(data) = wrapper;`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/infallible_try_from.rs",
    "content": "#![feature(never_type)]\n#![warn(clippy::infallible_try_from)]\n\nuse std::convert::Infallible;\n\nstruct MyStruct(i32);\n\nimpl TryFrom<i8> for MyStruct {\n    //~^ infallible_try_from\n    type Error = !;\n    fn try_from(other: i8) -> Result<Self, !> {\n        Ok(Self(other.into()))\n    }\n}\n\nimpl TryFrom<i16> for MyStruct {\n    //~^ infallible_try_from\n    type Error = Infallible;\n    fn try_from(other: i16) -> Result<Self, Infallible> {\n        Ok(Self(other.into()))\n    }\n}\n\nimpl TryFrom<i64> for MyStruct {\n    type Error = i64;\n    fn try_from(other: i64) -> Result<Self, i64> {\n        Ok(Self(i32::try_from(other).map_err(|_| other)?))\n    }\n}\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/infallible_try_from.stderr",
    "content": "error: infallible TryFrom impl; consider implementing From instead\n  --> tests/ui/infallible_try_from.rs:8:1\n   |\nLL | impl TryFrom<i8> for MyStruct {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |     type Error = !;\n   |                  - infallible error type\n   |\n   = note: `-D clippy::infallible-try-from` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::infallible_try_from)]`\n\nerror: infallible TryFrom impl; consider implementing From instead\n  --> tests/ui/infallible_try_from.rs:16:1\n   |\nLL | impl TryFrom<i16> for MyStruct {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |     type Error = Infallible;\n   |                  ---------- infallible error type\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/infinite_iter.rs",
    "content": "#![allow(clippy::double_ended_iterator_last)]\n\nuse std::iter::repeat;\nfn square_is_lower_64(x: &u32) -> bool {\n    x * x < 64\n}\n\n#[allow(clippy::maybe_infinite_iter)]\n#[deny(clippy::infinite_iter)]\nfn infinite_iters() {\n    repeat(0_u8).collect::<Vec<_>>();\n    //~^ infinite_iter\n\n    // infinite iter\n    (0..8_u32).take_while(square_is_lower_64).cycle().count();\n    //~^ infinite_iter\n\n    // infinite iter\n    (0..8_u64).chain(0..).max();\n    //~^ infinite_iter\n\n    // infinite iter\n    (0_usize..)\n        .chain([0usize, 1, 2].iter().cloned())\n        .skip_while(|x| *x != 42)\n        .min();\n    // infinite iter\n    (0..8_u32)\n        //~^ infinite_iter\n        .rev()\n        .cycle()\n        .map(|x| x + 1_u32)\n        .for_each(|x| println!(\"{x}\"));\n    // infinite iter\n    (0..3_u32).flat_map(|x| x..).sum::<u32>();\n    // infinite iter\n    (0_usize..).flat_map(|x| 0..x).product::<usize>();\n    //~^ infinite_iter\n\n    // infinite iter\n    (0_u64..).filter(|x| x.is_multiple_of(2)).last();\n    //~^ infinite_iter\n\n    // not an infinite, because ranges are double-ended\n    (0..42_u64).by_ref().last();\n    // iterator is not exhausted\n    (0..).next();\n}\n\n#[deny(clippy::maybe_infinite_iter)]\nfn potential_infinite_iters() {\n    // maybe infinite iter\n    (0..).zip((0..).take_while(square_is_lower_64)).count();\n    //~^ maybe_infinite_iter\n\n    // maybe infinite iter\n    repeat(42).take_while(|x| *x == 42).chain(0..42).max();\n    //~^ maybe_infinite_iter\n\n    // maybe infinite iter\n    (1..)\n        //~^ maybe_infinite_iter\n        .scan(0, |state, x| {\n            *state += x;\n            Some(*state)\n        })\n        .min();\n    // maybe infinite iter\n    (0..).find(|x| *x == 24);\n    //~^ maybe_infinite_iter\n\n    // maybe infinite iter\n    (0..).position(|x| x == 24);\n    //~^ maybe_infinite_iter\n\n    // maybe infinite iter\n    (0..).any(|x| x == 24);\n    //~^ maybe_infinite_iter\n\n    // maybe infinite iter\n    (0..).all(|x| x == 24);\n    //~^ maybe_infinite_iter\n\n    // not infinite\n    (0..).zip(0..42).take_while(|&(x, _)| x != 42).count();\n    // iterator is not exhausted\n    repeat(42).take_while(|x| *x == 42).next();\n}\n\nfn main() {}\n\nmod finite_collect {\n    use std::collections::HashSet;\n\n    struct C;\n    impl FromIterator<i32> for C {\n        fn from_iter<I: IntoIterator<Item = i32>>(iter: I) -> Self {\n            C\n        }\n    }\n\n    fn check_collect() {\n        // Infinite iter\n        let _: HashSet<i32> = (0..).collect();\n        //~^ infinite_iter\n\n        // Some data structures don't collect infinitely, such as `ArrayVec`\n        let _: C = (0..).collect();\n    }\n}\n"
  },
  {
    "path": "tests/ui/infinite_iter.stderr",
    "content": "error: infinite iteration detected\n  --> tests/ui/infinite_iter.rs:11:5\n   |\nLL |     repeat(0_u8).collect::<Vec<_>>();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/infinite_iter.rs:9:8\n   |\nLL | #[deny(clippy::infinite_iter)]\n   |        ^^^^^^^^^^^^^^^^^^^^^\n\nerror: infinite iteration detected\n  --> tests/ui/infinite_iter.rs:15:5\n   |\nLL |     (0..8_u32).take_while(square_is_lower_64).cycle().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: infinite iteration detected\n  --> tests/ui/infinite_iter.rs:19:5\n   |\nLL |     (0..8_u64).chain(0..).max();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: infinite iteration detected\n  --> tests/ui/infinite_iter.rs:28:5\n   |\nLL | /     (0..8_u32)\nLL | |\nLL | |         .rev()\nLL | |         .cycle()\nLL | |         .map(|x| x + 1_u32)\nLL | |         .for_each(|x| println!(\"{x}\"));\n   | |______________________________________^\n\nerror: infinite iteration detected\n  --> tests/ui/infinite_iter.rs:37:5\n   |\nLL |     (0_usize..).flat_map(|x| 0..x).product::<usize>();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: infinite iteration detected\n  --> tests/ui/infinite_iter.rs:41:5\n   |\nLL |     (0_u64..).filter(|x| x.is_multiple_of(2)).last();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: possible infinite iteration detected\n  --> tests/ui/infinite_iter.rs:53:5\n   |\nLL |     (0..).zip((0..).take_while(square_is_lower_64)).count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/infinite_iter.rs:50:8\n   |\nLL | #[deny(clippy::maybe_infinite_iter)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: possible infinite iteration detected\n  --> tests/ui/infinite_iter.rs:57:5\n   |\nLL |     repeat(42).take_while(|x| *x == 42).chain(0..42).max();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: possible infinite iteration detected\n  --> tests/ui/infinite_iter.rs:61:5\n   |\nLL | /     (1..)\nLL | |\nLL | |         .scan(0, |state, x| {\nLL | |             *state += x;\nLL | |             Some(*state)\nLL | |         })\nLL | |         .min();\n   | |______________^\n\nerror: possible infinite iteration detected\n  --> tests/ui/infinite_iter.rs:69:5\n   |\nLL |     (0..).find(|x| *x == 24);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: possible infinite iteration detected\n  --> tests/ui/infinite_iter.rs:73:5\n   |\nLL |     (0..).position(|x| x == 24);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: possible infinite iteration detected\n  --> tests/ui/infinite_iter.rs:77:5\n   |\nLL |     (0..).any(|x| x == 24);\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: possible infinite iteration detected\n  --> tests/ui/infinite_iter.rs:81:5\n   |\nLL |     (0..).all(|x| x == 24);\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: infinite iteration detected\n  --> tests/ui/infinite_iter.rs:104:31\n   |\nLL |         let _: HashSet<i32> = (0..).collect();\n   |                               ^^^^^^^^^^^^^^^\n   |\n   = note: `#[deny(clippy::infinite_iter)]` on by default\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/infinite_loops.rs",
    "content": "//@no-rustfix: multiple suggestions add `-> !` to the same fn\n//@aux-build:proc_macros.rs\n\n#![allow(clippy::never_loop, clippy::while_let_loop)]\n#![warn(clippy::infinite_loop)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nfn do_something() {}\n\nfn no_break() {\n    loop {\n        //~^ infinite_loop\n        do_something();\n    }\n}\n\nfn all_inf() {\n    loop {\n        //~^ infinite_loop\n        loop {\n            //~^ infinite_loop\n            loop {\n                //~^ infinite_loop\n                do_something();\n            }\n        }\n        do_something();\n    }\n}\n\nfn no_break_return_some_ty() -> Option<u8> {\n    loop {\n        do_something();\n        return None;\n    }\n    loop {\n        //~^ infinite_loop\n        do_something();\n    }\n}\n\nfn no_break_never_ret() -> ! {\n    loop {\n        do_something();\n    }\n}\n\nfn no_break_never_ret_noise() {\n    loop {\n        //~^ infinite_loop\n        fn inner_fn() -> ! {\n            std::process::exit(0);\n        }\n        do_something();\n    }\n}\n\nfn has_direct_break_1() {\n    loop {\n        do_something();\n        break;\n    }\n}\n\nfn has_direct_break_2() {\n    'outer: loop {\n        do_something();\n        break 'outer;\n    }\n}\n\nfn has_indirect_break_1(cond: bool) {\n    'outer: loop {\n        loop {\n            if cond {\n                break 'outer;\n            }\n        }\n    }\n}\n\nfn has_indirect_break_2(stop_num: i32) {\n    'outer: loop {\n        for x in 0..5 {\n            if x == stop_num {\n                break 'outer;\n            }\n        }\n    }\n}\n\nfn break_inner_but_not_outer_1(cond: bool) {\n    loop {\n        //~^ infinite_loop\n        loop {\n            if cond {\n                break;\n            }\n        }\n    }\n}\n\nfn break_inner_but_not_outer_2(cond: bool) {\n    loop {\n        //~^ infinite_loop\n        'inner: loop {\n            loop {\n                if cond {\n                    break 'inner;\n                }\n            }\n        }\n    }\n}\n\nfn break_outer_but_not_inner() {\n    loop {\n        loop {\n            //~^ infinite_loop\n            do_something();\n        }\n        break;\n    }\n}\n\nfn can_break_both_inner_and_outer(cond: bool) {\n    'outer: loop {\n        loop {\n            if cond {\n                break 'outer;\n            } else {\n                break;\n            }\n        }\n    }\n}\n\nfn break_wrong_loop(cond: bool) {\n    // 'inner has statement to break 'outer loop, but it was broken out of early by a labeled child loop\n    'outer: loop {\n        loop {\n            //~^ infinite_loop\n            'inner: loop {\n                loop {\n                    loop {\n                        break 'inner;\n                    }\n                    break 'outer;\n                }\n            }\n        }\n    }\n}\n\nfn has_direct_return(cond: bool) {\n    loop {\n        if cond {\n            return;\n        }\n    }\n}\n\nfn ret_in_inner(cond: bool) {\n    loop {\n        loop {\n            if cond {\n                return;\n            }\n        }\n    }\n}\n\nenum Foo {\n    A,\n    B,\n    C,\n}\n\nfn match_like() {\n    let opt: Option<u8> = Some(1);\n    loop {\n        //~^ infinite_loop\n        match opt {\n            Some(v) => {\n                println!(\"{v}\");\n            },\n            None => {\n                do_something();\n            },\n        }\n    }\n\n    loop {\n        match opt {\n            Some(v) => {\n                println!(\"{v}\");\n            },\n            None => {\n                do_something();\n                break;\n            },\n        }\n    }\n\n    let result: Result<u8, u16> = Ok(1);\n    loop {\n        let _val = match result {\n            Ok(1) => 1 + 1,\n            Ok(v) => v / 2,\n            Err(_) => return,\n        };\n    }\n\n    loop {\n        let Ok(_val) = result else { return };\n    }\n\n    loop {\n        let Ok(_val) = result.map(|v| 10) else { break };\n    }\n\n    loop {\n        //~^ infinite_loop\n        let _x = matches!(result, Ok(v) if v != 0).then_some(0);\n    }\n\n    loop {\n        //~^ infinite_loop\n        // This `return` does not return the function, so it doesn't count\n        let _x = matches!(result, Ok(v) if v != 0).then(|| {\n            if true {\n                return;\n            }\n            do_something();\n        });\n    }\n\n    let mut val = 0;\n    let mut fooc = Foo::C;\n\n    loop {\n        val = match fooc {\n            Foo::A => 0,\n            Foo::B => {\n                fooc = Foo::C;\n                1\n            },\n            Foo::C => break,\n        };\n    }\n\n    loop {\n        val = match fooc {\n            Foo::A => 0,\n            Foo::B => 1,\n            Foo::C => {\n                break;\n            },\n        };\n    }\n}\n\nmacro_rules! set_or_ret {\n    ($opt:expr, $a:expr) => {{\n        match $opt {\n            Some(val) => $a = val,\n            None => return,\n        }\n    }};\n}\n\nfn ret_in_macro(opt: Option<u8>) {\n    let opt: Option<u8> = Some(1);\n    let mut a: u8 = 0;\n    loop {\n        set_or_ret!(opt, a);\n    }\n\n    let res: Result<bool, u8> = Ok(true);\n    loop {\n        match res {\n            Ok(true) => set_or_ret!(opt, a),\n            _ => do_something(),\n        }\n    }\n}\n\nfn panic_like_macros_1() {\n    loop {\n        do_something();\n        panic!();\n    }\n}\n\nfn panic_like_macros_2() {\n    let mut x = 0;\n\n    loop {\n        do_something();\n        if true {\n            todo!();\n        }\n    }\n    loop {\n        do_something();\n        x += 1;\n        assert_eq!(x, 0);\n    }\n    loop {\n        do_something();\n        assert!(x % 2 == 0);\n    }\n    loop {\n        do_something();\n        match Some(1) {\n            Some(n) => println!(\"{n}\"),\n            None => unreachable!(\"It won't happen\"),\n        }\n    }\n}\n\nfn exit_directly(cond: bool) {\n    loop {\n        if cond {\n            std::process::exit(0);\n        }\n    }\n}\n\ntrait MyTrait {\n    fn problematic_trait_method() {\n        loop {\n            //~^ infinite_loop\n            do_something();\n        }\n    }\n    fn could_be_problematic();\n}\n\nimpl MyTrait for String {\n    fn could_be_problematic() {\n        loop {\n            //~^ infinite_loop\n            do_something();\n        }\n    }\n}\n\nfn inf_loop_in_closure() {\n    let _loop_forever = || {\n        loop {\n            //~^ infinite_loop\n            do_something();\n        }\n    };\n\n    let _somehow_ok = || -> ! {\n        loop {\n            do_something();\n        }\n    };\n}\n\nfn inf_loop_in_res() -> Result<(), i32> {\n    Ok(loop {\n        //~^ infinite_loop\n        do_something()\n    })\n}\n\nwith_span! { span\n    fn no_loop() {}\n}\n\nwith_span! { span\n    fn with_loop() {\n        loop {\n            do_nothing();\n        }\n    }\n}\n\nfn do_nothing() {}\n\nfn span_inside_fn() {\n    with_span! { span\n        loop {\n            do_nothing();\n        }\n    }\n}\n\nfn continue_outer() {\n    // Should not lint (issue #13511)\n    let mut count = 0;\n    'outer: loop {\n        if count != 0 {\n            break;\n        }\n\n        loop {\n            count += 1;\n            continue 'outer;\n        }\n    }\n\n    // This should lint as we continue the loop itself\n    'infinite: loop {\n        //~^ infinite_loop\n        loop {\n            continue 'infinite;\n        }\n    }\n    // This should lint as we continue an inner loop\n    loop {\n        //~^ infinite_loop\n        'inner: loop {\n            //~^ infinite_loop\n            loop {\n                continue 'inner;\n            }\n        }\n    }\n\n    // This should lint as we continue the loop itself\n    loop {\n        //~^ infinite_loop\n        continue;\n    }\n}\n\n// don't suggest adding `-> !` to async fn/closure that already returning `-> !`\nmod issue_12338 {\n    use super::do_something;\n\n    async fn foo() -> ! {\n        loop {\n            do_something();\n        }\n    }\n\n    fn bar() {\n        let _ = async || -> ! {\n            loop {\n                do_something();\n            }\n        };\n    }\n}\n\n#[allow(clippy::let_underscore_future, clippy::empty_loop)]\nmod issue_14000 {\n    use super::do_something;\n\n    async fn foo() {\n        let _ = async move {\n            loop {\n                //~^ infinite_loop\n                do_something();\n            }\n        }\n        .await;\n        let _ = async move {\n            loop {\n                //~^ infinite_loop\n                continue;\n            }\n        }\n        .await;\n    }\n\n    fn bar() {\n        let _ = async move {\n            loop {\n                do_something();\n            }\n        };\n\n        let _ = async move {\n            loop {\n                continue;\n            }\n        };\n    }\n}\n\n#[allow(clippy::let_underscore_future)]\nmod tokio_spawn_test {\n    use super::do_something;\n\n    fn install_ticker() {\n        // This should NOT trigger the lint because the async block is spawned, not awaited\n        std::thread::spawn(move || {\n            async move {\n                loop {\n                    // This loop should not trigger infinite_loop lint\n                    do_something();\n                }\n            }\n        });\n    }\n\n    fn spawn_async_block() {\n        // This should NOT trigger the lint because the async block is not awaited\n        let _handle = async move {\n            loop {\n                do_something();\n            }\n        };\n    }\n\n    fn await_async_block() {\n        // This SHOULD trigger the lint because the async block is awaited\n        let _ = async move {\n            loop {\n                do_something();\n            }\n        };\n    }\n}\n\nmod issue15541 {\n    async fn good() -> ! {\n        loop {\n            std::future::pending().await\n        }\n    }\n\n    async fn bad() {\n        //~v infinite_loop\n        loop {\n            std::future::pending().await\n        }\n    }\n}\n\nmod issue16155 {\n    #![allow(clippy::empty_loop)]\n\n    use super::do_something;\n\n    fn let_then_else(cond: bool) {\n        let true = cond else { loop {} };\n        //~^ infinite_loop\n    }\n\n    fn loop_in_one_if_branch(cond: bool) {\n        if cond {\n            loop {}\n            //~^ infinite_loop\n        }\n    }\n\n    fn loop_in_one_match_arm(x: Option<i32>) {\n        match x {\n            Some(_) => {},\n            None => loop {},\n            //~^ infinite_loop\n        }\n    }\n\n    fn loop_in_if_let_else(x: Option<i32>) {\n        if let Some(_val) = x {\n            do_something();\n        } else {\n            loop {}\n            //~^ infinite_loop\n        }\n    }\n\n    #[expect(clippy::if_same_then_else)]\n    fn all_branches_diverge_if(cond: bool) {\n        if cond {\n            loop {}\n            //~^ infinite_loop\n        } else {\n            loop {}\n            //~^ infinite_loop\n        }\n    }\n\n    fn all_branches_diverge_match(x: Option<i32>) {\n        match x {\n            Some(_) => loop {}, //~ infinite_loop\n            None => loop {},    //~ infinite_loop\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/infinite_loops.stderr",
    "content": "error: infinite loop detected\n  --> tests/ui/infinite_loops.rs:13:5\n   |\nLL | /     loop {\nLL | |\nLL | |         do_something();\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n   = note: `-D clippy::infinite-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::infinite_loop)]`\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn no_break() -> ! {\n   |               ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:20:5\n   |\nLL | /     loop {\nLL | |\nLL | |         loop {\n...  |\nLL | |         do_something();\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn all_inf() -> ! {\n   |              ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:22:9\n   |\nLL | /         loop {\nLL | |\nLL | |             loop {\n...  |\nLL | |         }\n   | |_________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn all_inf() -> ! {\n   |              ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:24:13\n   |\nLL | /             loop {\nLL | |\nLL | |                 do_something();\nLL | |             }\n   | |_____________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn all_inf() -> ! {\n   |              ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:38:5\n   |\nLL | /     loop {\nLL | |\nLL | |         do_something();\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:51:5\n   |\nLL | /     loop {\nLL | |\nLL | |         fn inner_fn() -> ! {\nLL | |             std::process::exit(0);\nLL | |         }\nLL | |         do_something();\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn no_break_never_ret_noise() -> ! {\n   |                               ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:95:5\n   |\nLL | /     loop {\nLL | |\nLL | |         loop {\nLL | |             if cond {\n...  |\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn break_inner_but_not_outer_1(cond: bool) -> ! {\n   |                                            ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:106:5\n   |\nLL | /     loop {\nLL | |\nLL | |         'inner: loop {\nLL | |             loop {\n...  |\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn break_inner_but_not_outer_2(cond: bool) -> ! {\n   |                                            ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:120:9\n   |\nLL | /         loop {\nLL | |\nLL | |             do_something();\nLL | |         }\n   | |_________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:143:9\n   |\nLL | /         loop {\nLL | |\nLL | |             'inner: loop {\nLL | |                 loop {\n...  |\nLL | |         }\n   | |_________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:183:5\n   |\nLL | /     loop {\nLL | |\nLL | |         match opt {\nLL | |             Some(v) => {\n...  |\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:224:5\n   |\nLL | /     loop {\nLL | |\nLL | |         let _x = matches!(result, Ok(v) if v != 0).then_some(0);\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:229:5\n   |\nLL | /     loop {\nLL | |\nLL | |         // This `return` does not return the function, so it doesn't count\nLL | |         let _x = matches!(result, Ok(v) if v != 0).then(|| {\n...  |\nLL | |         });\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:334:9\n   |\nLL | /         loop {\nLL | |\nLL | |             do_something();\nLL | |         }\n   | |_________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL |     fn problematic_trait_method() -> ! {\n   |                                   ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:344:9\n   |\nLL | /         loop {\nLL | |\nLL | |             do_something();\nLL | |         }\n   | |_________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL |     fn could_be_problematic() -> ! {\n   |                               ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:353:9\n   |\nLL | /         loop {\nLL | |\nLL | |             do_something();\nLL | |         }\n   | |_________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL |     let _loop_forever = || -> ! {\n   |                            ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:367:8\n   |\nLL |       Ok(loop {\n   |  ________^\nLL | |\nLL | |         do_something()\nLL | |     })\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:410:5\n   |\nLL | /     'infinite: loop {\nLL | |\nLL | |         loop {\nLL | |             continue 'infinite;\nLL | |         }\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn continue_outer() -> ! {\n   |                     ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:417:5\n   |\nLL | /     loop {\nLL | |\nLL | |         'inner: loop {\n...  |\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn continue_outer() -> ! {\n   |                     ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:419:9\n   |\nLL | /         'inner: loop {\nLL | |\nLL | |             loop {\nLL | |                 continue 'inner;\nLL | |             }\nLL | |         }\n   | |_________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn continue_outer() -> ! {\n   |                     ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:428:5\n   |\nLL | /     loop {\nLL | |\nLL | |         continue;\nLL | |     }\n   | |_____^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL | fn continue_outer() -> ! {\n   |                     ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:459:13\n   |\nLL | /             loop {\nLL | |\nLL | |                 do_something();\nLL | |             }\n   | |_____________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:466:13\n   |\nLL | /             loop {\nLL | |\nLL | |                 continue;\nLL | |             }\n   | |_____________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:533:9\n   |\nLL | /         loop {\nLL | |             std::future::pending().await\nLL | |         }\n   | |_________^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:545:32\n   |\nLL |         let true = cond else { loop {} };\n   |                                ^^^^^^^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:551:13\n   |\nLL |             loop {}\n   |             ^^^^^^^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:559:21\n   |\nLL |             None => loop {},\n   |                     ^^^^^^^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:568:13\n   |\nLL |             loop {}\n   |             ^^^^^^^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:576:13\n   |\nLL |             loop {}\n   |             ^^^^^^^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL |     fn all_branches_diverge_if(cond: bool) -> ! {\n   |                                            ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:579:13\n   |\nLL |             loop {}\n   |             ^^^^^^^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL |     fn all_branches_diverge_if(cond: bool) -> ! {\n   |                                            ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:586:24\n   |\nLL |             Some(_) => loop {},\n   |                        ^^^^^^^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL |     fn all_branches_diverge_match(x: Option<i32>) -> ! {\n   |                                                   ++++\n\nerror: infinite loop detected\n  --> tests/ui/infinite_loops.rs:587:21\n   |\nLL |             None => loop {},\n   |                     ^^^^^^^\n   |\n   = help: if this is not intended, try adding a `break` or `return` to the loop\nhelp: if this is intentional, consider specifying `!` as function return\n   |\nLL |     fn all_branches_diverge_match(x: Option<i32>) -> ! {\n   |                                                   ++++\n\nerror: aborting due to 32 previous errors\n\n"
  },
  {
    "path": "tests/ui/inherent_to_string.rs",
    "content": "#![allow(improper_ctypes_definitions)]\n\nuse std::fmt;\n\ntrait FalsePositive {\n    fn to_string(&self) -> String;\n}\n\nstruct A;\nstruct B;\nstruct C;\nstruct D;\nstruct E;\nstruct F;\nstruct G;\nstruct H;\nstruct I;\nstruct J;\n\nimpl A {\n    // Should be detected; emit warning\n    fn to_string(&self) -> String {\n        //~^ inherent_to_string\n\n        \"A.to_string()\".to_string()\n    }\n\n    // Should not be detected as it does not match the function signature\n    fn to_str(&self) -> String {\n        \"A.to_str()\".to_string()\n    }\n}\n\n// Should not be detected as it is a free function\nfn to_string() -> String {\n    \"free to_string()\".to_string()\n}\n\nimpl B {\n    // Should not be detected, wrong return type\n    fn to_string(&self) -> i32 {\n        42\n    }\n}\n\nimpl C {\n    // Should be detected and emit error as C also implements Display\n    fn to_string(&self) -> String {\n        //~^ inherent_to_string_shadow_display\n\n        \"C.to_string()\".to_string()\n    }\n}\n\nimpl fmt::Display for C {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"impl Display for C\")\n    }\n}\n\nimpl FalsePositive for D {\n    // Should not be detected, as it is a trait function\n    fn to_string(&self) -> String {\n        \"impl FalsePositive for D\".to_string()\n    }\n}\n\nimpl E {\n    // Should not be detected, as it is not bound to an instance\n    fn to_string() -> String {\n        \"E::to_string()\".to_string()\n    }\n}\n\nimpl F {\n    // Should not be detected, as it does not match the function signature\n    fn to_string(&self, _i: i32) -> String {\n        \"F.to_string()\".to_string()\n    }\n}\n\nimpl G {\n    // Should not be detected, as it does not match the function signature\n    fn to_string<const _N: usize>(&self) -> String {\n        \"G.to_string()\".to_string()\n    }\n}\n\n// Issue #11201\n\nimpl H {\n    unsafe fn to_string(&self) -> String {\n        \"G.to_string()\".to_string()\n    }\n}\n\nimpl I {\n    extern \"C\" fn to_string(&self) -> String {\n        \"G.to_string()\".to_string()\n    }\n}\n\nimpl J {\n    unsafe extern \"C\" fn to_string(&self) -> String {\n        \"G.to_string()\".to_string()\n    }\n}\n\nfn main() {\n    let a = A;\n    a.to_string();\n    a.to_str();\n\n    to_string();\n\n    let b = B;\n    b.to_string();\n\n    let c = C;\n    C.to_string();\n\n    let d = D;\n    d.to_string();\n\n    E::to_string();\n\n    let f = F;\n    f.to_string(1);\n\n    let g = G;\n    g.to_string::<1>();\n}\n"
  },
  {
    "path": "tests/ui/inherent_to_string.stderr",
    "content": "error: implementation of inherent method `to_string(&self) -> String` for type `A`\n  --> tests/ui/inherent_to_string.rs:22:5\n   |\nLL | /     fn to_string(&self) -> String {\nLL | |\nLL | |\nLL | |         \"A.to_string()\".to_string()\nLL | |     }\n   | |_____^\n   |\n   = help: implement trait `Display` for type `A` instead\n   = note: `-D clippy::inherent-to-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inherent_to_string)]`\n\nerror: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display`\n  --> tests/ui/inherent_to_string.rs:48:5\n   |\nLL | /     fn to_string(&self) -> String {\nLL | |\nLL | |\nLL | |         \"C.to_string()\".to_string()\nLL | |     }\n   | |_____^\n   |\n   = help: remove the inherent method from type `C`\n   = note: `#[deny(clippy::inherent_to_string_shadow_display)]` on by default\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/init_numbered_fields.fixed",
    "content": "#![warn(clippy::init_numbered_fields)]\n\n#[derive(Default)]\nstruct TupleStruct(u32, u32, u8);\n\n// This shouldn't lint because it's in a macro\nmacro_rules! tuple_struct_init {\n    () => {\n        TupleStruct { 0: 0, 1: 1, 2: 2 }\n    };\n}\n\nfn main() {\n    let tuple_struct = TupleStruct::default();\n\n    // This should lint\n    let _ = TupleStruct(1u32, 42, 23u8);\n\n    // This should also lint and order the fields correctly\n    let _ = TupleStruct(1u32, 3u32, 2u8);\n\n    // Ok because of default initializer\n    let _ = TupleStruct { 0: 42, ..tuple_struct };\n\n    let _ = TupleStruct {\n        1: 23,\n        ..TupleStruct::default()\n    };\n\n    // Ok because it's in macro\n    let _ = tuple_struct_init!();\n\n    type Alias = TupleStruct;\n\n    // Aliases can't be tuple constructed #8638\n    let _ = Alias { 0: 0, 1: 1, 2: 2 };\n\n    // Issue #12367\n    struct TupleStructVec(Vec<usize>);\n\n    let _ = TupleStructVec(vec![0, 1, 2, 3]);\n    //~^ init_numbered_fields\n\n    {\n        struct S(i32, i32);\n        let mut iter = [1i32, 1i32].into_iter();\n        let _ = S {\n            1: iter.next().unwrap(),\n            0: iter.next().unwrap(),\n        };\n    }\n}\n"
  },
  {
    "path": "tests/ui/init_numbered_fields.rs",
    "content": "#![warn(clippy::init_numbered_fields)]\n\n#[derive(Default)]\nstruct TupleStruct(u32, u32, u8);\n\n// This shouldn't lint because it's in a macro\nmacro_rules! tuple_struct_init {\n    () => {\n        TupleStruct { 0: 0, 1: 1, 2: 2 }\n    };\n}\n\nfn main() {\n    let tuple_struct = TupleStruct::default();\n\n    // This should lint\n    let _ = TupleStruct {\n        //~^ init_numbered_fields\n        0: 1u32,\n        1: 42,\n        2: 23u8,\n    };\n\n    // This should also lint and order the fields correctly\n    let _ = TupleStruct {\n        //~^ init_numbered_fields\n        0: 1u32,\n        2: 2u8,\n        1: 3u32,\n    };\n\n    // Ok because of default initializer\n    let _ = TupleStruct { 0: 42, ..tuple_struct };\n\n    let _ = TupleStruct {\n        1: 23,\n        ..TupleStruct::default()\n    };\n\n    // Ok because it's in macro\n    let _ = tuple_struct_init!();\n\n    type Alias = TupleStruct;\n\n    // Aliases can't be tuple constructed #8638\n    let _ = Alias { 0: 0, 1: 1, 2: 2 };\n\n    // Issue #12367\n    struct TupleStructVec(Vec<usize>);\n\n    let _ = TupleStructVec { 0: vec![0, 1, 2, 3] };\n    //~^ init_numbered_fields\n\n    {\n        struct S(i32, i32);\n        let mut iter = [1i32, 1i32].into_iter();\n        let _ = S {\n            1: iter.next().unwrap(),\n            0: iter.next().unwrap(),\n        };\n    }\n}\n"
  },
  {
    "path": "tests/ui/init_numbered_fields.stderr",
    "content": "error: used a field initializer for a tuple struct\n  --> tests/ui/init_numbered_fields.rs:17:13\n   |\nLL |       let _ = TupleStruct {\n   |  _____________^\nLL | |\nLL | |         0: 1u32,\nLL | |         1: 42,\nLL | |         2: 23u8,\nLL | |     };\n   | |_____^ help: use tuple initialization: `TupleStruct(1u32, 42, 23u8)`\n   |\n   = note: `-D clippy::init-numbered-fields` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::init_numbered_fields)]`\n\nerror: used a field initializer for a tuple struct\n  --> tests/ui/init_numbered_fields.rs:25:13\n   |\nLL |       let _ = TupleStruct {\n   |  _____________^\nLL | |\nLL | |         0: 1u32,\nLL | |         2: 2u8,\nLL | |         1: 3u32,\nLL | |     };\n   | |_____^ help: use tuple initialization: `TupleStruct(1u32, 3u32, 2u8)`\n\nerror: used a field initializer for a tuple struct\n  --> tests/ui/init_numbered_fields.rs:51:13\n   |\nLL |     let _ = TupleStructVec { 0: vec![0, 1, 2, 3] };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use tuple initialization: `TupleStructVec(vec![0, 1, 2, 3])`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/inline_fn_without_body.fixed",
    "content": "#![warn(clippy::inline_fn_without_body)]\n#![allow(clippy::inline_always)]\n\ntrait Foo {\n    //~^ inline_fn_without_body\n    fn default_inline();\n\n    //~^ inline_fn_without_body\n    fn always_inline();\n\n    //~^ inline_fn_without_body\n    fn never_inline();\n\n    #[inline]\n    fn has_body() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/inline_fn_without_body.rs",
    "content": "#![warn(clippy::inline_fn_without_body)]\n#![allow(clippy::inline_always)]\n\ntrait Foo {\n    #[inline]\n    //~^ inline_fn_without_body\n    fn default_inline();\n\n    #[inline(always)]\n    //~^ inline_fn_without_body\n    fn always_inline();\n\n    #[inline(never)]\n    //~^ inline_fn_without_body\n    fn never_inline();\n\n    #[inline]\n    fn has_body() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/inline_fn_without_body.stderr",
    "content": "error: use of `#[inline]` on trait method `default_inline` which has no body\n  --> tests/ui/inline_fn_without_body.rs:5:5\n   |\nLL |       #[inline]\n   |  _____-^^^^^^^^\nLL | |\n   | |____- help: remove\n   |\n   = note: `-D clippy::inline-fn-without-body` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inline_fn_without_body)]`\n\nerror: use of `#[inline]` on trait method `always_inline` which has no body\n  --> tests/ui/inline_fn_without_body.rs:9:5\n   |\nLL |       #[inline(always)]\n   |  _____-^^^^^^^^^^^^^^^^\nLL | |\n   | |____- help: remove\n\nerror: use of `#[inline]` on trait method `never_inline` which has no body\n  --> tests/ui/inline_fn_without_body.rs:13:5\n   |\nLL |       #[inline(never)]\n   |  _____-^^^^^^^^^^^^^^^\nLL | |\n   | |____- help: remove\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/inspect_for_each.rs",
    "content": "#![warn(clippy::inspect_for_each)]\n\nfn main() {\n    let a: Vec<usize> = vec![1, 2, 3, 4, 5];\n\n    let mut b: Vec<usize> = Vec::new();\n    a.into_iter().inspect(|x| assert!(*x > 0)).for_each(|x| {\n        //~^ inspect_for_each\n\n        let y = do_some(x);\n        let z = do_more(y);\n        b.push(z);\n    });\n\n    assert_eq!(b, vec![4, 5, 6, 7, 8]);\n}\n\nfn do_some(a: usize) -> usize {\n    a + 1\n}\n\nfn do_more(a: usize) -> usize {\n    a + 2\n}\n"
  },
  {
    "path": "tests/ui/inspect_for_each.stderr",
    "content": "error: called `inspect(..).for_each(..)` on an `Iterator`\n  --> tests/ui/inspect_for_each.rs:7:19\n   |\nLL |       a.into_iter().inspect(|x| assert!(*x > 0)).for_each(|x| {\n   |  ___________________^\nLL | |\nLL | |\nLL | |         let y = do_some(x);\nLL | |         let z = do_more(y);\nLL | |         b.push(z);\nLL | |     });\n   | |______^\n   |\n   = help: move the code from `inspect(..)` to `for_each(..)` and remove the `inspect(..)`\n   = note: `-D clippy::inspect-for-each` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inspect_for_each)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/int_plus_one.fixed",
    "content": "#[allow(clippy::no_effect, clippy::unnecessary_operation)]\n#[warn(clippy::int_plus_one)]\nfn main() {\n    let x = 1i32;\n    let y = 0i32;\n\n    let _ = x > y; //~ int_plus_one\n    let _ = x > y; //~ int_plus_one\n    let _ = y < x; //~ int_plus_one\n    let _ = y < x; //~ int_plus_one\n\n    let _ = x > y; //~ int_plus_one\n    let _ = x > y; //~ int_plus_one\n    let _ = y < x; //~ int_plus_one\n    let _ = y < x; //~ int_plus_one\n\n    let _ = x > y; // should be ok\n    let _ = y < x; // should be ok\n}\n"
  },
  {
    "path": "tests/ui/int_plus_one.rs",
    "content": "#[allow(clippy::no_effect, clippy::unnecessary_operation)]\n#[warn(clippy::int_plus_one)]\nfn main() {\n    let x = 1i32;\n    let y = 0i32;\n\n    let _ = x >= y + 1; //~ int_plus_one\n    let _ = x >= 1 + y; //~ int_plus_one\n    let _ = y + 1 <= x; //~ int_plus_one\n    let _ = 1 + y <= x; //~ int_plus_one\n\n    let _ = x - 1 >= y; //~ int_plus_one\n    let _ = -1 + x >= y; //~ int_plus_one\n    let _ = y <= x - 1; //~ int_plus_one\n    let _ = y <= -1 + x; //~ int_plus_one\n\n    let _ = x > y; // should be ok\n    let _ = y < x; // should be ok\n}\n"
  },
  {
    "path": "tests/ui/int_plus_one.stderr",
    "content": "error: unnecessary `>= y + 1` or `x - 1 >=`\n  --> tests/ui/int_plus_one.rs:7:13\n   |\nLL |     let _ = x >= y + 1;\n   |             ^^^^^^^^^^ help: change it to: `x > y`\n   |\n   = note: `-D clippy::int-plus-one` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::int_plus_one)]`\n\nerror: unnecessary `>= y + 1` or `x - 1 >=`\n  --> tests/ui/int_plus_one.rs:8:13\n   |\nLL |     let _ = x >= 1 + y;\n   |             ^^^^^^^^^^ help: change it to: `x > y`\n\nerror: unnecessary `>= y + 1` or `x - 1 >=`\n  --> tests/ui/int_plus_one.rs:9:13\n   |\nLL |     let _ = y + 1 <= x;\n   |             ^^^^^^^^^^ help: change it to: `y < x`\n\nerror: unnecessary `>= y + 1` or `x - 1 >=`\n  --> tests/ui/int_plus_one.rs:10:13\n   |\nLL |     let _ = 1 + y <= x;\n   |             ^^^^^^^^^^ help: change it to: `y < x`\n\nerror: unnecessary `>= y + 1` or `x - 1 >=`\n  --> tests/ui/int_plus_one.rs:12:13\n   |\nLL |     let _ = x - 1 >= y;\n   |             ^^^^^^^^^^ help: change it to: `x > y`\n\nerror: unnecessary `>= y + 1` or `x - 1 >=`\n  --> tests/ui/int_plus_one.rs:13:13\n   |\nLL |     let _ = -1 + x >= y;\n   |             ^^^^^^^^^^^ help: change it to: `x > y`\n\nerror: unnecessary `>= y + 1` or `x - 1 >=`\n  --> tests/ui/int_plus_one.rs:14:13\n   |\nLL |     let _ = y <= x - 1;\n   |             ^^^^^^^^^^ help: change it to: `y < x`\n\nerror: unnecessary `>= y + 1` or `x - 1 >=`\n  --> tests/ui/int_plus_one.rs:15:13\n   |\nLL |     let _ = y <= -1 + x;\n   |             ^^^^^^^^^^^ help: change it to: `y < x`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/integer_division.rs",
    "content": "#![warn(clippy::integer_division)]\n\nuse std::num::NonZeroU32;\n\nconst TWO: NonZeroU32 = NonZeroU32::new(2).unwrap();\n\nfn main() {\n    let two = 2;\n    let n = 1 / 2;\n    //~^ integer_division\n\n    let o = 1 / two;\n    //~^ integer_division\n\n    let p = two / 4;\n    //~^ integer_division\n\n    let x = 1. / 2.0;\n\n    let a = 1;\n    let s = a / TWO;\n    //~^ integer_division\n}\n"
  },
  {
    "path": "tests/ui/integer_division.stderr",
    "content": "error: integer division\n  --> tests/ui/integer_division.rs:9:13\n   |\nLL |     let n = 1 / 2;\n   |             ^^^^^\n   |\n   = help: division of integers may cause loss of precision. consider using floats\n   = note: `-D clippy::integer-division` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::integer_division)]`\n\nerror: integer division\n  --> tests/ui/integer_division.rs:12:13\n   |\nLL |     let o = 1 / two;\n   |             ^^^^^^^\n   |\n   = help: division of integers may cause loss of precision. consider using floats\n\nerror: integer division\n  --> tests/ui/integer_division.rs:15:13\n   |\nLL |     let p = two / 4;\n   |             ^^^^^^^\n   |\n   = help: division of integers may cause loss of precision. consider using floats\n\nerror: integer division\n  --> tests/ui/integer_division.rs:21:13\n   |\nLL |     let s = a / TWO;\n   |             ^^^^^^^\n   |\n   = help: division of integers may cause loss of precision. consider using floats\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/integer_division_remainder_used.rs",
    "content": "#![warn(clippy::integer_division_remainder_used)]\n#![allow(unused_variables)]\n#![allow(clippy::op_ref)]\n\nstruct CustomOps(pub i32);\nimpl std::ops::Div for CustomOps {\n    type Output = Self;\n\n    fn div(self, rhs: Self) -> Self::Output {\n        Self(self.0 / rhs.0)\n        //~^ integer_division_remainder_used\n    }\n}\nimpl std::ops::Rem for CustomOps {\n    type Output = Self;\n\n    fn rem(self, rhs: Self) -> Self::Output {\n        Self(self.0 % rhs.0)\n        //~^ integer_division_remainder_used\n    }\n}\n\nfn main() {\n    // should trigger\n    let a = 10;\n    let b = 5;\n    let c = a / b;\n    //~^ integer_division_remainder_used\n    let d = a % b;\n    //~^ integer_division_remainder_used\n    let e = &a / b;\n    //~^ integer_division_remainder_used\n    let f = a % &b;\n    //~^ integer_division_remainder_used\n    let g = &a / &b;\n    //~^ integer_division_remainder_used\n    let h = &10 % b;\n    //~^ integer_division_remainder_used\n    let i = a / &4;\n    //~^ integer_division_remainder_used\n\n    // should not trigger on custom Div and Rem\n    let w = CustomOps(3);\n    let x = CustomOps(4);\n    let y = w / x;\n\n    let w = CustomOps(3);\n    let x = CustomOps(4);\n    let z = w % x;\n}\n"
  },
  {
    "path": "tests/ui/integer_division_remainder_used.stderr",
    "content": "error: use of `/` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:10:14\n   |\nLL |         Self(self.0 / rhs.0)\n   |              ^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::integer-division-remainder-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::integer_division_remainder_used)]`\n\nerror: use of `%` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:18:14\n   |\nLL |         Self(self.0 % rhs.0)\n   |              ^^^^^^^^^^^^^^\n\nerror: use of `/` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:27:13\n   |\nLL |     let c = a / b;\n   |             ^^^^^\n\nerror: use of `%` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:29:13\n   |\nLL |     let d = a % b;\n   |             ^^^^^\n\nerror: use of `/` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:31:13\n   |\nLL |     let e = &a / b;\n   |             ^^^^^^\n\nerror: use of `%` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:33:13\n   |\nLL |     let f = a % &b;\n   |             ^^^^^^\n\nerror: use of `/` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:35:13\n   |\nLL |     let g = &a / &b;\n   |             ^^^^^^^\n\nerror: use of `%` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:37:13\n   |\nLL |     let h = &10 % b;\n   |             ^^^^^^^\n\nerror: use of `/` has been disallowed in this context\n  --> tests/ui/integer_division_remainder_used.rs:39:13\n   |\nLL |     let i = a / &4;\n   |             ^^^^^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/into_iter_on_ref.fixed",
    "content": "#![allow(clippy::useless_vec, clippy::needless_borrow)]\n#![warn(clippy::into_iter_on_ref)]\n\nstruct X;\nuse std::collections::*;\n\nfn main() {\n    for _ in &[1, 2, 3] {}\n    for _ in vec![X, X] {}\n    for _ in &vec![X, X] {}\n\n    let _ = vec![1, 2, 3].into_iter();\n    let _ = (&vec![1, 2, 3]).iter();\n    //~^ into_iter_on_ref\n    let _ = std::rc::Rc::from(&[X][..]).iter();\n    //~^ into_iter_on_ref\n    let _ = std::sync::Arc::from(&[X][..]).iter();\n    //~^ into_iter_on_ref\n\n    let _ = (&&&&&&&[1, 2, 3]).iter();\n    //~^ into_iter_on_ref\n    let _ = (&&&&mut &&&[1, 2, 3]).iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut &mut &mut [1, 2, 3]).iter_mut();\n    //~^ into_iter_on_ref\n\n    let _ = (&Some(4)).iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut Some(5)).iter_mut();\n    //~^ into_iter_on_ref\n    let _ = (&Ok::<_, i32>(6)).iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut Err::<i32, _>(7)).iter_mut();\n    //~^ into_iter_on_ref\n    let _ = (&Vec::<i32>::new()).iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut Vec::<i32>::new()).iter_mut();\n    //~^ into_iter_on_ref\n    let _ = (&BTreeMap::<i32, u64>::new()).iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut BTreeMap::<i32, u64>::new()).iter_mut();\n    //~^ into_iter_on_ref\n    let _ = (&VecDeque::<i32>::new()).iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut VecDeque::<i32>::new()).iter_mut();\n    //~^ into_iter_on_ref\n    let _ = (&LinkedList::<i32>::new()).iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut LinkedList::<i32>::new()).iter_mut();\n    //~^ into_iter_on_ref\n    let _ = (&HashMap::<i32, u64>::new()).iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut HashMap::<i32, u64>::new()).iter_mut();\n    //~^ into_iter_on_ref\n\n    let _ = (&BTreeSet::<i32>::new()).iter();\n    //~^ into_iter_on_ref\n    let _ = (&BinaryHeap::<i32>::new()).iter();\n    //~^ into_iter_on_ref\n    let _ = (&HashSet::<i32>::new()).iter();\n    //~^ into_iter_on_ref\n    let _ = std::path::Path::new(\"12/34\").iter();\n    //~^ into_iter_on_ref\n    let _ = std::path::PathBuf::from(\"12/34\").iter();\n    //~^ into_iter_on_ref\n\n    let _ = (&[1, 2, 3]).iter().next();\n    //~^ into_iter_on_ref\n}\n"
  },
  {
    "path": "tests/ui/into_iter_on_ref.rs",
    "content": "#![allow(clippy::useless_vec, clippy::needless_borrow)]\n#![warn(clippy::into_iter_on_ref)]\n\nstruct X;\nuse std::collections::*;\n\nfn main() {\n    for _ in &[1, 2, 3] {}\n    for _ in vec![X, X] {}\n    for _ in &vec![X, X] {}\n\n    let _ = vec![1, 2, 3].into_iter();\n    let _ = (&vec![1, 2, 3]).into_iter();\n    //~^ into_iter_on_ref\n    let _ = std::rc::Rc::from(&[X][..]).into_iter();\n    //~^ into_iter_on_ref\n    let _ = std::sync::Arc::from(&[X][..]).into_iter();\n    //~^ into_iter_on_ref\n\n    let _ = (&&&&&&&[1, 2, 3]).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&&&&mut &&&[1, 2, 3]).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut &mut &mut [1, 2, 3]).into_iter();\n    //~^ into_iter_on_ref\n\n    let _ = (&Some(4)).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut Some(5)).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&Ok::<_, i32>(6)).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut Err::<i32, _>(7)).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&Vec::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut Vec::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&BTreeMap::<i32, u64>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut BTreeMap::<i32, u64>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&VecDeque::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut VecDeque::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&LinkedList::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut LinkedList::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&HashMap::<i32, u64>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&mut HashMap::<i32, u64>::new()).into_iter();\n    //~^ into_iter_on_ref\n\n    let _ = (&BTreeSet::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&BinaryHeap::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = (&HashSet::<i32>::new()).into_iter();\n    //~^ into_iter_on_ref\n    let _ = std::path::Path::new(\"12/34\").into_iter();\n    //~^ into_iter_on_ref\n    let _ = std::path::PathBuf::from(\"12/34\").into_iter();\n    //~^ into_iter_on_ref\n\n    let _ = (&[1, 2, 3]).into_iter().next();\n    //~^ into_iter_on_ref\n}\n"
  },
  {
    "path": "tests/ui/into_iter_on_ref.stderr",
    "content": "error: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec`\n  --> tests/ui/into_iter_on_ref.rs:13:30\n   |\nLL |     let _ = (&vec![1, 2, 3]).into_iter();\n   |                              ^^^^^^^^^ help: call directly: `iter`\n   |\n   = note: `-D clippy::into-iter-on-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::into_iter_on_ref)]`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`\n  --> tests/ui/into_iter_on_ref.rs:15:41\n   |\nLL |     let _ = std::rc::Rc::from(&[X][..]).into_iter();\n   |                                         ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `slice`\n  --> tests/ui/into_iter_on_ref.rs:17:44\n   |\nLL |     let _ = std::sync::Arc::from(&[X][..]).into_iter();\n   |                                            ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`\n  --> tests/ui/into_iter_on_ref.rs:20:32\n   |\nLL |     let _ = (&&&&&&&[1, 2, 3]).into_iter();\n   |                                ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`\n  --> tests/ui/into_iter_on_ref.rs:22:36\n   |\nLL |     let _ = (&&&&mut &&&[1, 2, 3]).into_iter();\n   |                                    ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `array`\n  --> tests/ui/into_iter_on_ref.rs:24:40\n   |\nLL |     let _ = (&mut &mut &mut [1, 2, 3]).into_iter();\n   |                                        ^^^^^^^^^ help: call directly: `iter_mut`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Option`\n  --> tests/ui/into_iter_on_ref.rs:27:24\n   |\nLL |     let _ = (&Some(4)).into_iter();\n   |                        ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Option`\n  --> tests/ui/into_iter_on_ref.rs:29:28\n   |\nLL |     let _ = (&mut Some(5)).into_iter();\n   |                            ^^^^^^^^^ help: call directly: `iter_mut`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Result`\n  --> tests/ui/into_iter_on_ref.rs:31:32\n   |\nLL |     let _ = (&Ok::<_, i32>(6)).into_iter();\n   |                                ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Result`\n  --> tests/ui/into_iter_on_ref.rs:33:37\n   |\nLL |     let _ = (&mut Err::<i32, _>(7)).into_iter();\n   |                                     ^^^^^^^^^ help: call directly: `iter_mut`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Vec`\n  --> tests/ui/into_iter_on_ref.rs:35:34\n   |\nLL |     let _ = (&Vec::<i32>::new()).into_iter();\n   |                                  ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `Vec`\n  --> tests/ui/into_iter_on_ref.rs:37:38\n   |\nLL |     let _ = (&mut Vec::<i32>::new()).into_iter();\n   |                                      ^^^^^^^^^ help: call directly: `iter_mut`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeMap`\n  --> tests/ui/into_iter_on_ref.rs:39:44\n   |\nLL |     let _ = (&BTreeMap::<i32, u64>::new()).into_iter();\n   |                                            ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `BTreeMap`\n  --> tests/ui/into_iter_on_ref.rs:41:48\n   |\nLL |     let _ = (&mut BTreeMap::<i32, u64>::new()).into_iter();\n   |                                                ^^^^^^^^^ help: call directly: `iter_mut`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `VecDeque`\n  --> tests/ui/into_iter_on_ref.rs:43:39\n   |\nLL |     let _ = (&VecDeque::<i32>::new()).into_iter();\n   |                                       ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `VecDeque`\n  --> tests/ui/into_iter_on_ref.rs:45:43\n   |\nLL |     let _ = (&mut VecDeque::<i32>::new()).into_iter();\n   |                                           ^^^^^^^^^ help: call directly: `iter_mut`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `LinkedList`\n  --> tests/ui/into_iter_on_ref.rs:47:41\n   |\nLL |     let _ = (&LinkedList::<i32>::new()).into_iter();\n   |                                         ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `LinkedList`\n  --> tests/ui/into_iter_on_ref.rs:49:45\n   |\nLL |     let _ = (&mut LinkedList::<i32>::new()).into_iter();\n   |                                             ^^^^^^^^^ help: call directly: `iter_mut`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashMap`\n  --> tests/ui/into_iter_on_ref.rs:51:43\n   |\nLL |     let _ = (&HashMap::<i32, u64>::new()).into_iter();\n   |                                           ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter_mut()` and will not consume the `HashMap`\n  --> tests/ui/into_iter_on_ref.rs:53:47\n   |\nLL |     let _ = (&mut HashMap::<i32, u64>::new()).into_iter();\n   |                                               ^^^^^^^^^ help: call directly: `iter_mut`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BTreeSet`\n  --> tests/ui/into_iter_on_ref.rs:56:39\n   |\nLL |     let _ = (&BTreeSet::<i32>::new()).into_iter();\n   |                                       ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `BinaryHeap`\n  --> tests/ui/into_iter_on_ref.rs:58:41\n   |\nLL |     let _ = (&BinaryHeap::<i32>::new()).into_iter();\n   |                                         ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `HashSet`\n  --> tests/ui/into_iter_on_ref.rs:60:38\n   |\nLL |     let _ = (&HashSet::<i32>::new()).into_iter();\n   |                                      ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `Path`\n  --> tests/ui/into_iter_on_ref.rs:62:43\n   |\nLL |     let _ = std::path::Path::new(\"12/34\").into_iter();\n   |                                           ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `PathBuf`\n  --> tests/ui/into_iter_on_ref.rs:64:47\n   |\nLL |     let _ = std::path::PathBuf::from(\"12/34\").into_iter();\n   |                                               ^^^^^^^^^ help: call directly: `iter`\n\nerror: this `.into_iter()` call is equivalent to `.iter()` and will not consume the `array`\n  --> tests/ui/into_iter_on_ref.rs:67:26\n   |\nLL |     let _ = (&[1, 2, 3]).into_iter().next();\n   |                          ^^^^^^^^^ help: call directly: `iter`\n\nerror: aborting due to 26 previous errors\n\n"
  },
  {
    "path": "tests/ui/into_iter_without_iter.rs",
    "content": "//@no-rustfix: suggestions reference out of scope lifetimes/types\n//@aux-build:proc_macros.rs\n#![warn(clippy::into_iter_without_iter)]\nextern crate proc_macros;\n\nuse std::iter::IntoIterator;\n\npub struct S1;\nimpl<'a> IntoIterator for &'a S1 {\n    //~^ into_iter_without_iter\n    type IntoIter = std::slice::Iter<'a, u8>;\n    type Item = &'a u8;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\nimpl<'a> IntoIterator for &'a mut S1 {\n    //~^ into_iter_without_iter\n    type IntoIter = std::slice::IterMut<'a, u8>;\n    type Item = &'a mut u8;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\npub struct S2<T>(T);\nimpl<'a, T> IntoIterator for &'a S2<T> {\n    //~^ into_iter_without_iter\n    type IntoIter = std::slice::Iter<'a, T>;\n    type Item = &'a T;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\nimpl<'a, T> IntoIterator for &'a mut S2<T> {\n    //~^ into_iter_without_iter\n    type IntoIter = std::slice::IterMut<'a, T>;\n    type Item = &'a mut T;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\n// Both iter and iter_mut methods exist, don't lint\npub struct S3<'a, T>(&'a T);\nimpl<'a, T> S3<'a, T> {\n    fn iter(&self) -> std::slice::Iter<'a, T> {\n        todo!()\n    }\n    fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {\n        todo!()\n    }\n}\nimpl<'a, T> IntoIterator for &S3<'a, T> {\n    type IntoIter = std::slice::Iter<'a, T>;\n    type Item = &'a T;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\nimpl<'a, T> IntoIterator for &mut S3<'a, T> {\n    type IntoIter = std::slice::IterMut<'a, T>;\n    type Item = &'a mut T;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\n// Only `iter` exists, no `iter_mut`\npub struct S4<'a, T>(&'a T);\n\nimpl<'a, T> S4<'a, T> {\n    fn iter(&self) -> std::slice::Iter<'a, T> {\n        todo!()\n    }\n}\n\nimpl<'a, T> IntoIterator for &S4<'a, T> {\n    type IntoIter = std::slice::Iter<'a, T>;\n    type Item = &'a T;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\nimpl<'a, T> IntoIterator for &mut S4<'a, T> {\n    //~^ into_iter_without_iter\n    type IntoIter = std::slice::IterMut<'a, T>;\n    type Item = &'a mut T;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\n// `iter` exists, but `IntoIterator` is implemented for an alias. inherent_impls doesn't \"normalize\"\n// aliases so that `inherent_impls(Alias)` where `type Alias = S` returns nothing, so this can lead\n// to fun FPs. Make sure it doesn't happen here (we're using type_of, which should skip the alias).\npub struct S5;\n\nimpl S5 {\n    fn iter(&self) -> std::slice::Iter<'static, u8> {\n        todo!()\n    }\n}\n\npub type Alias = S5;\n\nimpl IntoIterator for &Alias {\n    type IntoIter = std::slice::Iter<'static, u8>;\n    type Item = &'static u8;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\n// Fine to lint, the impls comes from a local macro.\npub struct Issue12037;\nmacro_rules! generate_impl {\n    () => {\n        impl<'a> IntoIterator for &'a Issue12037 {\n            //~^ into_iter_without_iter\n            type IntoIter = std::slice::Iter<'a, u8>;\n            type Item = &'a u8;\n            fn into_iter(self) -> Self::IntoIter {\n                todo!()\n            }\n        }\n    };\n}\ngenerate_impl!();\n\n// Impl comes from an external crate\nproc_macros::external! {\n    pub struct ImplWithForeignSpan;\n    impl<'a> IntoIterator for &'a ImplWithForeignSpan {\n        type IntoIter = std::slice::Iter<'a, u8>;\n        type Item = &'a u8;\n        fn into_iter(self) -> Self::IntoIter {\n            todo!()\n        }\n    }\n}\n\npub struct Allowed;\n#[allow(clippy::into_iter_without_iter)]\nimpl<'a> IntoIterator for &'a Allowed {\n    type IntoIter = std::slice::Iter<'a, u8>;\n    type Item = &'a u8;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\nfn main() {}\n\npub mod issue11635 {\n    // A little more involved than the original repro in the issue, but this tests that it correctly\n    // works for more than one deref step\n\n    use std::ops::Deref;\n\n    pub struct Thing(Vec<u8>);\n    pub struct Thing2(Thing);\n\n    impl Deref for Thing {\n        type Target = [u8];\n\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n\n    impl Deref for Thing2 {\n        type Target = Thing;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n\n    impl<'a> IntoIterator for &'a Thing2 {\n        type Item = &'a u8;\n        type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;\n\n        fn into_iter(self) -> Self::IntoIter {\n            self.0.iter()\n        }\n    }\n}\n\npub mod issue12964 {\n    pub struct MyIter<'a, T: 'a> {\n        iter: std::slice::Iter<'a, T>,\n    }\n\n    impl<'a, T> Iterator for MyIter<'a, T> {\n        type Item = &'a T;\n\n        fn next(&mut self) -> Option<Self::Item> {\n            self.iter.next()\n        }\n    }\n\n    pub struct MyContainer<T> {\n        inner: Vec<T>,\n    }\n\n    impl<T> MyContainer<T> {}\n\n    impl<T> MyContainer<T> {\n        #[must_use]\n        pub fn iter(&self) -> MyIter<'_, T> {\n            <&Self as IntoIterator>::into_iter(self)\n        }\n    }\n\n    impl<'a, T> IntoIterator for &'a MyContainer<T> {\n        type Item = &'a T;\n\n        type IntoIter = MyIter<'a, T>;\n\n        fn into_iter(self) -> Self::IntoIter {\n            Self::IntoIter {\n                iter: self.inner.as_slice().iter(),\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/into_iter_without_iter.stderr",
    "content": "error: `IntoIterator` implemented for a reference type without an `iter` method\n  --> tests/ui/into_iter_without_iter.rs:9:1\n   |\nLL | / impl<'a> IntoIterator for &'a S1 {\nLL | |\nLL | |     type IntoIter = std::slice::Iter<'a, u8>;\nLL | |     type Item = &'a u8;\n...  |\nLL | | }\n   | |_^\n   |\n   = note: `-D clippy::into-iter-without-iter` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::into_iter_without_iter)]`\nhelp: consider implementing `iter`\n   |\nLL + \nLL + impl S1 {\nLL +     fn iter(&self) -> std::slice::Iter<'a, u8> {\nLL +         <&Self as IntoIterator>::into_iter(self)\nLL +     }\nLL + }\n   |\n\nerror: `IntoIterator` implemented for a reference type without an `iter_mut` method\n  --> tests/ui/into_iter_without_iter.rs:17:1\n   |\nLL | / impl<'a> IntoIterator for &'a mut S1 {\nLL | |\nLL | |     type IntoIter = std::slice::IterMut<'a, u8>;\nLL | |     type Item = &'a mut u8;\n...  |\nLL | | }\n   | |_^\n   |\nhelp: consider implementing `iter_mut`\n   |\nLL + \nLL + impl S1 {\nLL +     fn iter_mut(&mut self) -> std::slice::IterMut<'a, u8> {\nLL +         <&mut Self as IntoIterator>::into_iter(self)\nLL +     }\nLL + }\n   |\n\nerror: `IntoIterator` implemented for a reference type without an `iter` method\n  --> tests/ui/into_iter_without_iter.rs:27:1\n   |\nLL | / impl<'a, T> IntoIterator for &'a S2<T> {\nLL | |\nLL | |     type IntoIter = std::slice::Iter<'a, T>;\nLL | |     type Item = &'a T;\n...  |\nLL | | }\n   | |_^\n   |\nhelp: consider implementing `iter`\n   |\nLL + \nLL + impl S2<T> {\nLL +     fn iter(&self) -> std::slice::Iter<'a, T> {\nLL +         <&Self as IntoIterator>::into_iter(self)\nLL +     }\nLL + }\n   |\n\nerror: `IntoIterator` implemented for a reference type without an `iter_mut` method\n  --> tests/ui/into_iter_without_iter.rs:35:1\n   |\nLL | / impl<'a, T> IntoIterator for &'a mut S2<T> {\nLL | |\nLL | |     type IntoIter = std::slice::IterMut<'a, T>;\nLL | |     type Item = &'a mut T;\n...  |\nLL | | }\n   | |_^\n   |\nhelp: consider implementing `iter_mut`\n   |\nLL + \nLL + impl S2<T> {\nLL +     fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {\nLL +         <&mut Self as IntoIterator>::into_iter(self)\nLL +     }\nLL + }\n   |\n\nerror: `IntoIterator` implemented for a reference type without an `iter_mut` method\n  --> tests/ui/into_iter_without_iter.rs:86:1\n   |\nLL | / impl<'a, T> IntoIterator for &mut S4<'a, T> {\nLL | |\nLL | |     type IntoIter = std::slice::IterMut<'a, T>;\nLL | |     type Item = &'a mut T;\n...  |\nLL | | }\n   | |_^\n   |\nhelp: consider implementing `iter_mut`\n   |\nLL + \nLL + impl S4<'a, T> {\nLL +     fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {\nLL +         <&mut Self as IntoIterator>::into_iter(self)\nLL +     }\nLL + }\n   |\n\nerror: `IntoIterator` implemented for a reference type without an `iter` method\n  --> tests/ui/into_iter_without_iter.rs:120:9\n   |\nLL | /         impl<'a> IntoIterator for &'a Issue12037 {\nLL | |\nLL | |             type IntoIter = std::slice::Iter<'a, u8>;\nLL | |             type Item = &'a u8;\n...  |\nLL | |         }\n   | |_________^\n...\nLL |   generate_impl!();\n   |   ---------------- in this macro invocation\n   |\n   = note: this error originates in the macro `generate_impl` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: consider implementing `iter`\n   |\nLL ~         \nLL + impl Issue12037 {\nLL +     fn iter(&self) -> std::slice::Iter<'a, u8> {\nLL +         <&Self as IntoIterator>::into_iter(self)\nLL +     }\nLL + }\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/invalid_upcast_comparisons.rs",
    "content": "#![warn(clippy::invalid_upcast_comparisons)]\n#![allow(\n    unused,\n    clippy::eq_op,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::cast_lossless\n)]\n\nfn mk_value<T>() -> T {\n    unimplemented!()\n}\n\nfn main() {\n    let u32: u32 = mk_value();\n    let u8: u8 = mk_value();\n    let i32: i32 = mk_value();\n    let i8: i8 = mk_value();\n\n    // always false, since no u8 can be > 300\n    (u8 as u32) > 300;\n    //~^ invalid_upcast_comparisons\n\n    (u8 as i32) > 300;\n    //~^ invalid_upcast_comparisons\n\n    (u8 as u32) == 300;\n    //~^ invalid_upcast_comparisons\n\n    (u8 as i32) == 300;\n    //~^ invalid_upcast_comparisons\n\n    300 < (u8 as u32);\n    //~^ invalid_upcast_comparisons\n\n    300 < (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    300 == (u8 as u32);\n    //~^ invalid_upcast_comparisons\n\n    300 == (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    // inverted of the above\n    (u8 as u32) <= 300;\n    //~^ invalid_upcast_comparisons\n\n    (u8 as i32) <= 300;\n    //~^ invalid_upcast_comparisons\n\n    (u8 as u32) != 300;\n    //~^ invalid_upcast_comparisons\n\n    (u8 as i32) != 300;\n    //~^ invalid_upcast_comparisons\n\n    300 >= (u8 as u32);\n    //~^ invalid_upcast_comparisons\n\n    300 >= (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    300 != (u8 as u32);\n    //~^ invalid_upcast_comparisons\n\n    300 != (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    // always false, since u8 -> i32 doesn't wrap\n    (u8 as i32) < 0;\n    //~^ invalid_upcast_comparisons\n\n    -5 != (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    // inverted of the above\n    (u8 as i32) >= 0;\n    //~^ invalid_upcast_comparisons\n\n    -5 == (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    // always false, since no u8 can be 1337\n    1337 == (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    1337 == (u8 as u32);\n    //~^ invalid_upcast_comparisons\n\n    // inverted of the above\n    1337 != (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    1337 != (u8 as u32);\n    //~^ invalid_upcast_comparisons\n\n    // Those are Ok:\n    (u8 as u32) > 20;\n    42 == (u8 as i32);\n    42 != (u8 as i32);\n    42 > (u8 as i32);\n    (u8 as i32) == 42;\n    (u8 as i32) != 42;\n    (u8 as i32) > 42;\n    (u8 as i32) < 42;\n\n    (u8 as i8) == -1;\n    (u8 as i8) != -1;\n    (u8 as i32) > -1;\n    //~^ invalid_upcast_comparisons\n\n    (u8 as i32) < -1;\n    //~^ invalid_upcast_comparisons\n\n    (u32 as i32) < -5;\n    (u32 as i32) < 10;\n\n    (i8 as u8) == 1;\n    (i8 as u8) != 1;\n    (i8 as u8) < 1;\n    (i8 as u8) > 1;\n    (i32 as u32) < 5;\n    (i32 as u32) < 10;\n\n    -5 < (u32 as i32);\n    0 <= (u32 as i32);\n    0 < (u32 as i32);\n\n    -5 > (u32 as i32);\n    -5 >= (u8 as i32);\n    //~^ invalid_upcast_comparisons\n\n    -5 == (u32 as i32);\n}\n\nfn issue15662() {\n    macro_rules! add_one {\n        ($x:expr) => {\n            $x + 1\n        };\n    }\n\n    let x: u8 = 1;\n    (add_one!(x) as u32) > 300;\n    //~^ invalid_upcast_comparisons\n}\n"
  },
  {
    "path": "tests/ui/invalid_upcast_comparisons.stderr",
    "content": "error: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:21:5\n   |\nLL |     (u8 as u32) > 300;\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::invalid-upcast-comparisons` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::invalid_upcast_comparisons)]`\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:24:5\n   |\nLL |     (u8 as i32) > 300;\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:27:5\n   |\nLL |     (u8 as u32) == 300;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:30:5\n   |\nLL |     (u8 as i32) == 300;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:33:5\n   |\nLL |     300 < (u8 as u32);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:36:5\n   |\nLL |     300 < (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:39:5\n   |\nLL |     300 == (u8 as u32);\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:42:5\n   |\nLL |     300 == (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:46:5\n   |\nLL |     (u8 as u32) <= 300;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:49:5\n   |\nLL |     (u8 as i32) <= 300;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:52:5\n   |\nLL |     (u8 as u32) != 300;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:55:5\n   |\nLL |     (u8 as i32) != 300;\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:58:5\n   |\nLL |     300 >= (u8 as u32);\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:61:5\n   |\nLL |     300 >= (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:64:5\n   |\nLL |     300 != (u8 as u32);\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:67:5\n   |\nLL |     300 != (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:71:5\n   |\nLL |     (u8 as i32) < 0;\n   |     ^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:74:5\n   |\nLL |     -5 != (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:78:5\n   |\nLL |     (u8 as i32) >= 0;\n   |     ^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:81:5\n   |\nLL |     -5 == (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:85:5\n   |\nLL |     1337 == (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:88:5\n   |\nLL |     1337 == (u8 as u32);\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:92:5\n   |\nLL |     1337 != (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:95:5\n   |\nLL |     1337 != (u8 as u32);\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always true\n  --> tests/ui/invalid_upcast_comparisons.rs:110:5\n   |\nLL |     (u8 as i32) > -1;\n   |     ^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:113:5\n   |\nLL |     (u8 as i32) < -1;\n   |     ^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `u8` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:131:5\n   |\nLL |     -5 >= (u8 as i32);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: because of the numeric bounds on `add_one!(x)` prior to casting, this expression is always false\n  --> tests/ui/invalid_upcast_comparisons.rs:145:5\n   |\nLL |     (add_one!(x) as u32) > 300;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui/io_other_error.fixed",
    "content": "#![warn(clippy::io_other_error)]\nuse std::fmt;\n\n#[derive(Debug)]\nstruct E;\n\nimpl std::error::Error for E {}\nimpl fmt::Display for E {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.write_str(\"E\")\n    }\n}\n\nmacro_rules! o {\n    {} => { std::io::ErrorKind::Other };\n}\n\nmacro_rules! e {\n    { $kind:expr } => { std::io::Error::new($kind, E) };\n}\n\nfn main() {\n    let _err = std::io::Error::other(E);\n    //~^ ERROR: this can be `std::io::Error::other(_)`\n    let other = std::io::ErrorKind::Other;\n    let _err = std::io::Error::other(E);\n    //~^ ERROR: this can be `std::io::Error::other(_)`\n\n    // not other\n    let _err = std::io::Error::new(std::io::ErrorKind::TimedOut, E);\n\n    // from expansion\n    let _err = e!(other);\n    let _err = std::io::Error::new(o!(), E);\n    let _err = e!(o!());\n\n    paths::short();\n    under_msrv();\n}\n\nmod paths {\n    use std::io::{self, Error, ErrorKind};\n\n    pub fn short() {\n        let _err = Error::other(super::E);\n        //~^ ERROR: this can be `std::io::Error::other(_)`\n        let _err = io::Error::other(super::E);\n        //~^ ERROR: this can be `std::io::Error::other(_)`\n    }\n}\n\n#[clippy::msrv = \"1.73\"]\nfn under_msrv() {\n    let _err = std::io::Error::new(std::io::ErrorKind::Other, E);\n}\n\npub fn issue14346(x: i32) -> std::io::Error {\n    std::io::Error::other(format!(\"{x}\"))\n    //~^ ERROR: this can be `std::io::Error::other(_)`\n}\n"
  },
  {
    "path": "tests/ui/io_other_error.rs",
    "content": "#![warn(clippy::io_other_error)]\nuse std::fmt;\n\n#[derive(Debug)]\nstruct E;\n\nimpl std::error::Error for E {}\nimpl fmt::Display for E {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        f.write_str(\"E\")\n    }\n}\n\nmacro_rules! o {\n    {} => { std::io::ErrorKind::Other };\n}\n\nmacro_rules! e {\n    { $kind:expr } => { std::io::Error::new($kind, E) };\n}\n\nfn main() {\n    let _err = std::io::Error::new(std::io::ErrorKind::Other, E);\n    //~^ ERROR: this can be `std::io::Error::other(_)`\n    let other = std::io::ErrorKind::Other;\n    let _err = std::io::Error::new(other, E);\n    //~^ ERROR: this can be `std::io::Error::other(_)`\n\n    // not other\n    let _err = std::io::Error::new(std::io::ErrorKind::TimedOut, E);\n\n    // from expansion\n    let _err = e!(other);\n    let _err = std::io::Error::new(o!(), E);\n    let _err = e!(o!());\n\n    paths::short();\n    under_msrv();\n}\n\nmod paths {\n    use std::io::{self, Error, ErrorKind};\n\n    pub fn short() {\n        let _err = Error::new(ErrorKind::Other, super::E);\n        //~^ ERROR: this can be `std::io::Error::other(_)`\n        let _err = io::Error::new(io::ErrorKind::Other, super::E);\n        //~^ ERROR: this can be `std::io::Error::other(_)`\n    }\n}\n\n#[clippy::msrv = \"1.73\"]\nfn under_msrv() {\n    let _err = std::io::Error::new(std::io::ErrorKind::Other, E);\n}\n\npub fn issue14346(x: i32) -> std::io::Error {\n    std::io::Error::new(std::io::ErrorKind::Other, format!(\"{x}\"))\n    //~^ ERROR: this can be `std::io::Error::other(_)`\n}\n"
  },
  {
    "path": "tests/ui/io_other_error.stderr",
    "content": "error: this can be `std::io::Error::other(_)`\n  --> tests/ui/io_other_error.rs:23:16\n   |\nLL |     let _err = std::io::Error::new(std::io::ErrorKind::Other, E);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::io-other-error` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::io_other_error)]`\nhelp: use `std::io::Error::other`\n   |\nLL -     let _err = std::io::Error::new(std::io::ErrorKind::Other, E);\nLL +     let _err = std::io::Error::other(E);\n   |\n\nerror: this can be `std::io::Error::other(_)`\n  --> tests/ui/io_other_error.rs:26:16\n   |\nLL |     let _err = std::io::Error::new(other, E);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `std::io::Error::other`\n   |\nLL -     let _err = std::io::Error::new(other, E);\nLL +     let _err = std::io::Error::other(E);\n   |\n\nerror: this can be `std::io::Error::other(_)`\n  --> tests/ui/io_other_error.rs:45:20\n   |\nLL |         let _err = Error::new(ErrorKind::Other, super::E);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `std::io::Error::other`\n   |\nLL -         let _err = Error::new(ErrorKind::Other, super::E);\nLL +         let _err = Error::other(super::E);\n   |\n\nerror: this can be `std::io::Error::other(_)`\n  --> tests/ui/io_other_error.rs:47:20\n   |\nLL |         let _err = io::Error::new(io::ErrorKind::Other, super::E);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `std::io::Error::other`\n   |\nLL -         let _err = io::Error::new(io::ErrorKind::Other, super::E);\nLL +         let _err = io::Error::other(super::E);\n   |\n\nerror: this can be `std::io::Error::other(_)`\n  --> tests/ui/io_other_error.rs:58:5\n   |\nLL |     std::io::Error::new(std::io::ErrorKind::Other, format!(\"{x}\"))\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `std::io::Error::other`\n   |\nLL -     std::io::Error::new(std::io::ErrorKind::Other, format!(\"{x}\"))\nLL +     std::io::Error::other(format!(\"{x}\"))\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/ip_constant.fixed",
    "content": "#![warn(clippy::ip_constant)]\n#![allow(dead_code)]\n#![allow(clippy::identity_op)]\n#![allow(clippy::eq_op)]\n\nfn literal_test1() {\n    use std::net::Ipv4Addr;\n    let _ = Ipv4Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = Ipv4Addr::BROADCAST;\n    //~^ ip_constant\n    let _ = Ipv4Addr::UNSPECIFIED;\n    //~^ ip_constant\n\n    use std::net::Ipv6Addr;\n    let _ = Ipv6Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = Ipv6Addr::UNSPECIFIED;\n    //~^ ip_constant\n}\n\nfn literal_test2() {\n    use std::net;\n    let _ = net::Ipv4Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = net::Ipv4Addr::BROADCAST;\n    //~^ ip_constant\n    let _ = net::Ipv4Addr::UNSPECIFIED;\n    //~^ ip_constant\n\n    let _ = net::Ipv6Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = net::Ipv6Addr::UNSPECIFIED;\n    //~^ ip_constant\n}\n\nfn literal_test3() {\n    let _ = std::net::Ipv4Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = std::net::Ipv4Addr::BROADCAST;\n    //~^ ip_constant\n    let _ = std::net::Ipv4Addr::UNSPECIFIED;\n    //~^ ip_constant\n\n    let _ = std::net::Ipv6Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = std::net::Ipv6Addr::UNSPECIFIED;\n    //~^ ip_constant\n}\n\nfn wrapped_in_parens() {\n    let _ = std::net::Ipv4Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = std::net::Ipv4Addr::BROADCAST;\n    //~^ ip_constant\n    let _ = std::net::Ipv4Addr::UNSPECIFIED;\n    //~^ ip_constant\n\n    let _ = std::net::Ipv6Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = std::net::Ipv6Addr::UNSPECIFIED;\n    //~^ ip_constant\n}\n\nconst CONST_U8_0: u8 = 0;\nconst CONST_U8_1: u8 = 1;\nconst CONST_U8_127: u8 = 127;\nconst CONST_U8_255: u8 = 255;\n\nconst CONST_U16_0: u16 = 0;\nconst CONST_U16_1: u16 = 1;\n\nfn const_test1() {\n    use std::net::Ipv4Addr;\n    let _ = Ipv4Addr::new(CONST_U8_127, CONST_U8_0, CONST_U8_0, CONST_U8_1);\n    let _ = Ipv4Addr::new(CONST_U8_255, CONST_U8_255, CONST_U8_255, CONST_U8_255);\n    let _ = Ipv4Addr::new(CONST_U8_0, CONST_U8_0, CONST_U8_0, CONST_U8_0);\n\n    use std::net::Ipv6Addr;\n    let _ = Ipv6Addr::new(\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_1,\n    );\n\n    let _ = Ipv6Addr::new(\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n    );\n}\n\nfn const_test2() {\n    use std::net::Ipv4Addr;\n    let _ = Ipv4Addr::LOCALHOST;\n    //~^ ip_constant\n    let _ = Ipv4Addr::new(254 + CONST_U8_1, 255, { 255 - CONST_U8_0 }, CONST_U8_255);\n    let _ = Ipv4Addr::new(0, CONST_U8_255 - 255, 0, { 1 + 0 - 1 });\n\n    use std::net::Ipv6Addr;\n    let _ = Ipv6Addr::new(0 + CONST_U16_0, 0, 0, 0, 0, 0, 0, 1);\n    let _ = Ipv6Addr::new(0 + 0, 0, 0, 0, 0, { 2 - 1 - CONST_U16_1 }, 0, 1);\n}\n\nmacro_rules! ipv4_new {\n    ($a:expr, $b:expr, $c:expr, $d:expr) => {\n        std::net::Ipv4Addr::new($a, $b, $c, $d)\n    };\n}\n\nfn macro_test() {\n    let _ = ipv4_new!(127, 0, 0, 1);\n    // no lint\n    let _ = ipv4_new!(255, 255, 255, 255);\n    // no lint\n    let _ = ipv4_new!(0, 0, 0, 0);\n    // no lint\n}\n\nfn main() {\n    // UI Test\n}\n"
  },
  {
    "path": "tests/ui/ip_constant.rs",
    "content": "#![warn(clippy::ip_constant)]\n#![allow(dead_code)]\n#![allow(clippy::identity_op)]\n#![allow(clippy::eq_op)]\n\nfn literal_test1() {\n    use std::net::Ipv4Addr;\n    let _ = Ipv4Addr::new(127, 0, 0, 1);\n    //~^ ip_constant\n    let _ = Ipv4Addr::new(255, 255, 255, 255);\n    //~^ ip_constant\n    let _ = Ipv4Addr::new(0, 0, 0, 0);\n    //~^ ip_constant\n\n    use std::net::Ipv6Addr;\n    let _ = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\n    //~^ ip_constant\n    let _ = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\n    //~^ ip_constant\n}\n\nfn literal_test2() {\n    use std::net;\n    let _ = net::Ipv4Addr::new(127, 0, 0, 1);\n    //~^ ip_constant\n    let _ = net::Ipv4Addr::new(255, 255, 255, 255);\n    //~^ ip_constant\n    let _ = net::Ipv4Addr::new(0, 0, 0, 0);\n    //~^ ip_constant\n\n    let _ = net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\n    //~^ ip_constant\n    let _ = net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\n    //~^ ip_constant\n}\n\nfn literal_test3() {\n    let _ = std::net::Ipv4Addr::new(127, 0, 0, 1);\n    //~^ ip_constant\n    let _ = std::net::Ipv4Addr::new(255, 255, 255, 255);\n    //~^ ip_constant\n    let _ = std::net::Ipv4Addr::new(0, 0, 0, 0);\n    //~^ ip_constant\n\n    let _ = std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\n    //~^ ip_constant\n    let _ = std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\n    //~^ ip_constant\n}\n\nfn wrapped_in_parens() {\n    let _ = (std::net::Ipv4Addr::new(127, 0, 0, 1));\n    //~^ ip_constant\n    let _ = (std::net::Ipv4Addr::new(255, 255, 255, 255));\n    //~^ ip_constant\n    let _ = (std::net::Ipv4Addr::new(0, 0, 0, 0));\n    //~^ ip_constant\n\n    let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));\n    //~^ ip_constant\n    let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));\n    //~^ ip_constant\n}\n\nconst CONST_U8_0: u8 = 0;\nconst CONST_U8_1: u8 = 1;\nconst CONST_U8_127: u8 = 127;\nconst CONST_U8_255: u8 = 255;\n\nconst CONST_U16_0: u16 = 0;\nconst CONST_U16_1: u16 = 1;\n\nfn const_test1() {\n    use std::net::Ipv4Addr;\n    let _ = Ipv4Addr::new(CONST_U8_127, CONST_U8_0, CONST_U8_0, CONST_U8_1);\n    let _ = Ipv4Addr::new(CONST_U8_255, CONST_U8_255, CONST_U8_255, CONST_U8_255);\n    let _ = Ipv4Addr::new(CONST_U8_0, CONST_U8_0, CONST_U8_0, CONST_U8_0);\n\n    use std::net::Ipv6Addr;\n    let _ = Ipv6Addr::new(\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_1,\n    );\n\n    let _ = Ipv6Addr::new(\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n        CONST_U16_0,\n    );\n}\n\nfn const_test2() {\n    use std::net::Ipv4Addr;\n    let _ = Ipv4Addr::new(126 + 1, 0, 0, 1);\n    //~^ ip_constant\n    let _ = Ipv4Addr::new(254 + CONST_U8_1, 255, { 255 - CONST_U8_0 }, CONST_U8_255);\n    let _ = Ipv4Addr::new(0, CONST_U8_255 - 255, 0, { 1 + 0 - 1 });\n\n    use std::net::Ipv6Addr;\n    let _ = Ipv6Addr::new(0 + CONST_U16_0, 0, 0, 0, 0, 0, 0, 1);\n    let _ = Ipv6Addr::new(0 + 0, 0, 0, 0, 0, { 2 - 1 - CONST_U16_1 }, 0, 1);\n}\n\nmacro_rules! ipv4_new {\n    ($a:expr, $b:expr, $c:expr, $d:expr) => {\n        std::net::Ipv4Addr::new($a, $b, $c, $d)\n    };\n}\n\nfn macro_test() {\n    let _ = ipv4_new!(127, 0, 0, 1);\n    // no lint\n    let _ = ipv4_new!(255, 255, 255, 255);\n    // no lint\n    let _ = ipv4_new!(0, 0, 0, 0);\n    // no lint\n}\n\nfn main() {\n    // UI Test\n}\n"
  },
  {
    "path": "tests/ui/ip_constant.stderr",
    "content": "error: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:8:13\n   |\nLL |     let _ = Ipv4Addr::new(127, 0, 0, 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::ip-constant` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ip_constant)]`\nhelp: use\n   |\nLL -     let _ = Ipv4Addr::new(127, 0, 0, 1);\nLL +     let _ = Ipv4Addr::LOCALHOST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:10:13\n   |\nLL |     let _ = Ipv4Addr::new(255, 255, 255, 255);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = Ipv4Addr::new(255, 255, 255, 255);\nLL +     let _ = Ipv4Addr::BROADCAST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:12:13\n   |\nLL |     let _ = Ipv4Addr::new(0, 0, 0, 0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = Ipv4Addr::new(0, 0, 0, 0);\nLL +     let _ = Ipv4Addr::UNSPECIFIED;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:16:13\n   |\nLL |     let _ = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\nLL +     let _ = Ipv6Addr::LOCALHOST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:18:13\n   |\nLL |     let _ = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\nLL +     let _ = Ipv6Addr::UNSPECIFIED;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:24:13\n   |\nLL |     let _ = net::Ipv4Addr::new(127, 0, 0, 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = net::Ipv4Addr::new(127, 0, 0, 1);\nLL +     let _ = net::Ipv4Addr::LOCALHOST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:26:13\n   |\nLL |     let _ = net::Ipv4Addr::new(255, 255, 255, 255);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = net::Ipv4Addr::new(255, 255, 255, 255);\nLL +     let _ = net::Ipv4Addr::BROADCAST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:28:13\n   |\nLL |     let _ = net::Ipv4Addr::new(0, 0, 0, 0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = net::Ipv4Addr::new(0, 0, 0, 0);\nLL +     let _ = net::Ipv4Addr::UNSPECIFIED;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:31:13\n   |\nLL |     let _ = net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\nLL +     let _ = net::Ipv6Addr::LOCALHOST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:33:13\n   |\nLL |     let _ = net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\nLL +     let _ = net::Ipv6Addr::UNSPECIFIED;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:38:13\n   |\nLL |     let _ = std::net::Ipv4Addr::new(127, 0, 0, 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = std::net::Ipv4Addr::new(127, 0, 0, 1);\nLL +     let _ = std::net::Ipv4Addr::LOCALHOST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:40:13\n   |\nLL |     let _ = std::net::Ipv4Addr::new(255, 255, 255, 255);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = std::net::Ipv4Addr::new(255, 255, 255, 255);\nLL +     let _ = std::net::Ipv4Addr::BROADCAST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:42:13\n   |\nLL |     let _ = std::net::Ipv4Addr::new(0, 0, 0, 0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = std::net::Ipv4Addr::new(0, 0, 0, 0);\nLL +     let _ = std::net::Ipv4Addr::UNSPECIFIED;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:45:13\n   |\nLL |     let _ = std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);\nLL +     let _ = std::net::Ipv6Addr::LOCALHOST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:47:13\n   |\nLL |     let _ = std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);\nLL +     let _ = std::net::Ipv6Addr::UNSPECIFIED;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:52:13\n   |\nLL |     let _ = (std::net::Ipv4Addr::new(127, 0, 0, 1));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = (std::net::Ipv4Addr::new(127, 0, 0, 1));\nLL +     let _ = std::net::Ipv4Addr::LOCALHOST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:54:13\n   |\nLL |     let _ = (std::net::Ipv4Addr::new(255, 255, 255, 255));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = (std::net::Ipv4Addr::new(255, 255, 255, 255));\nLL +     let _ = std::net::Ipv4Addr::BROADCAST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:56:13\n   |\nLL |     let _ = (std::net::Ipv4Addr::new(0, 0, 0, 0));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = (std::net::Ipv4Addr::new(0, 0, 0, 0));\nLL +     let _ = std::net::Ipv4Addr::UNSPECIFIED;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:59:13\n   |\nLL |     let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));\nLL +     let _ = std::net::Ipv6Addr::LOCALHOST;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:61:13\n   |\nLL |     let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));\nLL +     let _ = std::net::Ipv6Addr::UNSPECIFIED;\n   |\n\nerror: hand-coded well-known IP address\n  --> tests/ui/ip_constant.rs:105:13\n   |\nLL |     let _ = Ipv4Addr::new(126 + 1, 0, 0, 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     let _ = Ipv4Addr::new(126 + 1, 0, 0, 1);\nLL +     let _ = Ipv4Addr::LOCALHOST;\n   |\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/ip_constant_from_external.rs",
    "content": "//@error-in-other-file: hand-coded well-known IP address\n//@no-rustfix\n#![warn(clippy::ip_constant)]\n\nfn external_constant_test() {\n    let _ = include!(\"localhost.txt\");\n    // lint in external file `localhost.txt`\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/ip_constant_from_external.stderr",
    "content": "error: hand-coded well-known IP address\n  --> tests/ui/localhost.txt:1:1\n   |\nLL | std::net::Ipv4Addr::new(127, 0, 0, 1)\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::ip-constant` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ip_constant)]`\nhelp: use\n   |\nLL - std::net::Ipv4Addr::new(127, 0, 0, 1)\nLL + std::net::Ipv4Addr::LOCALHOST\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/is_digit_ascii_radix.fixed",
    "content": "#![warn(clippy::is_digit_ascii_radix)]\n\nconst TEN: u32 = 10;\n\nfn main() {\n    let c: char = '6';\n\n    // Should trigger the lint.\n    let _ = c.is_ascii_digit();\n    //~^ is_digit_ascii_radix\n    let _ = c.is_ascii_hexdigit();\n    //~^ is_digit_ascii_radix\n    let _ = c.is_ascii_hexdigit();\n    //~^ is_digit_ascii_radix\n\n    // Should not trigger the lint.\n    let _ = c.is_digit(11);\n    let _ = c.is_digit(TEN);\n}\n"
  },
  {
    "path": "tests/ui/is_digit_ascii_radix.rs",
    "content": "#![warn(clippy::is_digit_ascii_radix)]\n\nconst TEN: u32 = 10;\n\nfn main() {\n    let c: char = '6';\n\n    // Should trigger the lint.\n    let _ = c.is_digit(10);\n    //~^ is_digit_ascii_radix\n    let _ = c.is_digit(16);\n    //~^ is_digit_ascii_radix\n    let _ = c.is_digit(0x10);\n    //~^ is_digit_ascii_radix\n\n    // Should not trigger the lint.\n    let _ = c.is_digit(11);\n    let _ = c.is_digit(TEN);\n}\n"
  },
  {
    "path": "tests/ui/is_digit_ascii_radix.stderr",
    "content": "error: use of `char::is_digit` with literal radix of 10\n  --> tests/ui/is_digit_ascii_radix.rs:9:13\n   |\nLL |     let _ = c.is_digit(10);\n   |             ^^^^^^^^^^^^^^ help: try: `c.is_ascii_digit()`\n   |\n   = note: `-D clippy::is-digit-ascii-radix` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::is_digit_ascii_radix)]`\n\nerror: use of `char::is_digit` with literal radix of 16\n  --> tests/ui/is_digit_ascii_radix.rs:11:13\n   |\nLL |     let _ = c.is_digit(16);\n   |             ^^^^^^^^^^^^^^ help: try: `c.is_ascii_hexdigit()`\n\nerror: use of `char::is_digit` with literal radix of 16\n  --> tests/ui/is_digit_ascii_radix.rs:13:13\n   |\nLL |     let _ = c.is_digit(0x10);\n   |             ^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_hexdigit()`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/issue-111399.rs",
    "content": "//@ check-pass\n\n#![feature(inherent_associated_types)]\n#![allow(incomplete_features)]\n\n// Check that rustc doesn't crash on the trait bound `Self::Ty: std::marker::Freeze`.\n\npub struct Struct;\n\nimpl Struct {\n    pub type Ty = usize;\n    pub const CT: Self::Ty = 42;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/issue-3145.rs",
    "content": "fn main() {\n    println!(\"{}\" a); //~ERROR: expected `,`, found `a`\n}\n"
  },
  {
    "path": "tests/ui/issue-3145.stderr",
    "content": "error: expected `,`, found `a`\n  --> tests/ui/issue-3145.rs:2:19\n   |\nLL |     println!(\"{}\" a);\n   |                   ^ expected `,`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/issue-7447.rs",
    "content": "use std::borrow::Cow;\nuse std::collections::BTreeMap;\nuse std::marker::PhantomData;\nuse std::sync::Arc;\n\nfn byte_view<'a>(s: &'a ByteView<'_>) -> BTreeMap<&'a str, ByteView<'a>> {\n    panic!()\n}\n\nfn group_entries(s: &()) -> BTreeMap<Cow<'_, str>, Vec<Cow<'_, str>>> {\n    todo!()\n}\n\nstruct Mmap;\n\nenum ByteViewBacking<'a> {\n    Buf(Cow<'a, [u8]>),\n    Mmap(Mmap),\n}\n\npub struct ByteView<'a> {\n    backing: Arc<ByteViewBacking<'a>>,\n}\n\nfn main() {\n    byte_view(panic!());\n    //~^ diverging_sub_expression\n\n    group_entries(panic!());\n    //~^ diverging_sub_expression\n}\n"
  },
  {
    "path": "tests/ui/issue-7447.stderr",
    "content": "error: sub-expression diverges\n  --> tests/ui/issue-7447.rs:26:15\n   |\nLL |     byte_view(panic!());\n   |               ^^^^^^^^\n   |\n   = note: `-D clippy::diverging-sub-expression` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]`\n\nerror: sub-expression diverges\n  --> tests/ui/issue-7447.rs:29:19\n   |\nLL |     group_entries(panic!());\n   |                   ^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/issue_2356.fixed",
    "content": "#![deny(clippy::while_let_on_iterator)]\n#![allow(unused_mut)]\n\nuse std::iter::Iterator;\n\nstruct Foo;\n\nimpl Foo {\n    fn foo1<I: Iterator<Item = usize>>(mut it: I) {\n        while let Some(_) = it.next() {\n            println!(\"{:?}\", it.size_hint());\n        }\n    }\n\n    fn foo2<I: Iterator<Item = usize>>(mut it: I) {\n        for e in it {\n            //~^ while_let_on_iterator\n            println!(\"{e:?}\");\n        }\n    }\n}\n\nfn main() {\n    Foo::foo1(vec![].into_iter());\n    Foo::foo2(vec![].into_iter());\n}\n"
  },
  {
    "path": "tests/ui/issue_2356.rs",
    "content": "#![deny(clippy::while_let_on_iterator)]\n#![allow(unused_mut)]\n\nuse std::iter::Iterator;\n\nstruct Foo;\n\nimpl Foo {\n    fn foo1<I: Iterator<Item = usize>>(mut it: I) {\n        while let Some(_) = it.next() {\n            println!(\"{:?}\", it.size_hint());\n        }\n    }\n\n    fn foo2<I: Iterator<Item = usize>>(mut it: I) {\n        while let Some(e) = it.next() {\n            //~^ while_let_on_iterator\n            println!(\"{e:?}\");\n        }\n    }\n}\n\nfn main() {\n    Foo::foo1(vec![].into_iter());\n    Foo::foo2(vec![].into_iter());\n}\n"
  },
  {
    "path": "tests/ui/issue_2356.stderr",
    "content": "error: this loop could be written as a `for` loop\n  --> tests/ui/issue_2356.rs:16:9\n   |\nLL |         while let Some(e) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for e in it`\n   |\nnote: the lint level is defined here\n  --> tests/ui/issue_2356.rs:1:9\n   |\nLL | #![deny(clippy::while_let_on_iterator)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/issue_4266.rs",
    "content": "#![allow(dead_code)]\n\nasync fn sink1<'a>(_: &'a str) {} // lint\n//~^ needless_lifetimes\n\nasync fn sink1_elided(_: &str) {} // ok\n\n// lint\nasync fn one_to_one<'a>(s: &'a str) -> &'a str {\n    //~^ needless_lifetimes\n\n    s\n}\n\n// ok\nasync fn one_to_one_elided(s: &str) -> &str {\n    s\n}\n\n// ok\nasync fn all_to_one<'a>(a: &'a str, _b: &'a str) -> &'a str {\n    a\n}\n\n// async fn unrelated(_: &str, _: &str) {} // Not allowed in async fn\n\n// #3988\nstruct Foo;\nimpl Foo {\n    // ok\n    pub async fn new(&mut self) -> Self {\n        //~^ wrong_self_convention\n\n        Foo {}\n    }\n}\n\n// rust-lang/rust#61115\n// ok\nasync fn print(s: &str) {\n    println!(\"{s}\");\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/issue_4266.stderr",
    "content": "error: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/issue_4266.rs:3:16\n   |\nLL | async fn sink1<'a>(_: &'a str) {} // lint\n   |                ^^      ^^\n   |\n   = note: `-D clippy::needless-lifetimes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]`\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/issue_4266.rs:9:21\n   |\nLL | async fn one_to_one<'a>(s: &'a str) -> &'a str {\n   |                     ^^      ^^          ^^\n\nerror: methods called `new` usually take no `self`\n  --> tests/ui/issue_4266.rs:31:22\n   |\nLL |     pub async fn new(&mut self) -> Self {\n   |                      ^^^^^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/items_after_statement.rs",
    "content": "#![warn(clippy::items_after_statements)]\n#![allow(clippy::uninlined_format_args)]\n\nfn ok() {\n    fn foo() {\n        println!(\"foo\");\n    }\n    foo();\n}\n\nfn last() {\n    foo();\n    fn foo() {\n        //~^ items_after_statements\n\n        println!(\"foo\");\n    }\n}\n\nfn main() {\n    foo();\n    fn foo() {\n        //~^ items_after_statements\n\n        println!(\"foo\");\n    }\n    foo();\n}\n\nfn mac() {\n    let mut a = 5;\n    println!(\"{}\", a);\n    // do not lint this, because it needs to be after `a`\n    macro_rules! b {\n        () => {{\n            a = 6;\n            fn say_something() {\n                //~^ items_after_statements\n                println!(\"something\");\n            }\n        }};\n    }\n    b!();\n    println!(\"{}\", a);\n}\n\nfn semicolon() {\n    struct S {\n        a: u32,\n    };\n    impl S {\n        fn new(a: u32) -> Self {\n            Self { a }\n        }\n    }\n\n    let _ = S::new(3);\n}\n\nfn item_from_macro() {\n    macro_rules! static_assert_size {\n        ($ty:ty, $size:expr) => {\n            const _: [(); $size] = [(); ::std::mem::size_of::<$ty>()];\n        };\n    }\n\n    let _ = 1;\n    static_assert_size!(u32, 4);\n}\n\nfn allow_attribute() {\n    let _ = 1;\n    #[allow(clippy::items_after_statements)]\n    const _: usize = 1;\n}\n"
  },
  {
    "path": "tests/ui/items_after_statement.stderr",
    "content": "error: adding items after statements is confusing, since items exist from the start of the scope\n  --> tests/ui/items_after_statement.rs:13:5\n   |\nLL | /     fn foo() {\nLL | |\nLL | |\nLL | |         println!(\"foo\");\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::items-after-statements` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::items_after_statements)]`\n\nerror: adding items after statements is confusing, since items exist from the start of the scope\n  --> tests/ui/items_after_statement.rs:22:5\n   |\nLL | /     fn foo() {\nLL | |\nLL | |\nLL | |         println!(\"foo\");\nLL | |     }\n   | |_____^\n\nerror: adding items after statements is confusing, since items exist from the start of the scope\n  --> tests/ui/items_after_statement.rs:37:13\n   |\nLL | /             fn say_something() {\nLL | |\nLL | |                 println!(\"something\");\nLL | |             }\n   | |_____________^\n...\nLL |       b!();\n   |       ---- in this macro invocation\n   |\n   = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/items_after_test_module/after_proc_macros.rs",
    "content": "//@ check-pass\n//@aux-build:../auxiliary/proc_macros.rs\nextern crate proc_macros;\n\nproc_macros::with_span! {\n    span\n    #[cfg(test)]\n    mod tests {}\n}\n\n#[test]\nfn f() {}\n"
  },
  {
    "path": "tests/ui/items_after_test_module/auxiliary/submodule.rs",
    "content": "#[cfg(test)]\nmod tests {}\n\nfn in_submodule() {}\n"
  },
  {
    "path": "tests/ui/items_after_test_module/auxiliary/tests.rs",
    "content": "fn main() {}\n"
  },
  {
    "path": "tests/ui/items_after_test_module/imported_module.rs",
    "content": "//@ check-pass\n//@compile-flags: --test\n#![allow(unused)]\n#![warn(clippy::items_after_test_module)]\n\n// Nothing here should lint, as `tests` is an imported module (that has no body).\n\nfn main() {}\n\nfn should_not_lint() {}\n\n#[path = \"auxiliary/tests.rs\"]\n#[cfg(test)]\nmod tests; // Should not lint\n\nfn should_not_lint2() {}\n\nconst SHOULD_ALSO_NOT_LINT: usize = 1;\nmacro_rules! should_not_lint {\n    () => {};\n}\n"
  },
  {
    "path": "tests/ui/items_after_test_module/in_submodule.rs",
    "content": "//@error-in-other-file:\n#[path = \"auxiliary/submodule.rs\"]\nmod submodule;\n\n#[cfg(test)]\nmod tests {\n    #[test]\n    fn t() {}\n}\n"
  },
  {
    "path": "tests/ui/items_after_test_module/in_submodule.stderr",
    "content": "error: items after a test module\n  --> tests/ui/items_after_test_module/auxiliary/submodule.rs:2:1\n   |\nLL | mod tests {}\n   | ^^^^^^^^^\nLL |\nLL | fn in_submodule() {}\n   | ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::items-after-test-module` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::items_after_test_module)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/items_after_test_module/multiple_modules.rs",
    "content": "//@ check-pass\n\n#[cfg(test)]\nmod tests {\n    #[test]\n    fn f() {}\n}\n\n#[cfg(test)]\nmod more_tests {\n    #[test]\n    fn g() {}\n}\n"
  },
  {
    "path": "tests/ui/items_after_test_module/root_module.fixed",
    "content": "#![warn(clippy::items_after_test_module)]\n\nfn main() {}\n\nfn should_not_lint() {}\n\nfn should_lint() {}\n\nconst SHOULD_ALSO_LINT: usize = 1;\nmacro_rules! should_lint {\n    () => {};\n}\n\n#[allow(dead_code)]\n#[allow(unused)] // Some attributes to check that span replacement is good enough\n#[allow(clippy::allow_attributes)]\n#[cfg(test)]\nmod tests {\n    //~^ items_after_test_module\n    #[test]\n    fn hi() {}\n}\n"
  },
  {
    "path": "tests/ui/items_after_test_module/root_module.rs",
    "content": "#![warn(clippy::items_after_test_module)]\n\nfn main() {}\n\nfn should_not_lint() {}\n\n#[allow(dead_code)]\n#[allow(unused)] // Some attributes to check that span replacement is good enough\n#[allow(clippy::allow_attributes)]\n#[cfg(test)]\nmod tests {\n    //~^ items_after_test_module\n    #[test]\n    fn hi() {}\n}\n\nfn should_lint() {}\n\nconst SHOULD_ALSO_LINT: usize = 1;\nmacro_rules! should_lint {\n    () => {};\n}\n"
  },
  {
    "path": "tests/ui/items_after_test_module/root_module.stderr",
    "content": "error: items after a test module\n  --> tests/ui/items_after_test_module/root_module.rs:11:1\n   |\nLL | mod tests {\n   | ^^^^^^^^^\n...\nLL | fn should_lint() {}\n   | ^^^^^^^^^^^^^^^^\nLL |\nLL | const SHOULD_ALSO_LINT: usize = 1;\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL | macro_rules! should_lint {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::items-after-test-module` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::items_after_test_module)]`\n   = help: move the items to before the test module was defined\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/iter_cloned_collect.fixed",
    "content": "#![allow(unused)]\n#![allow(clippy::useless_vec)]\n\nuse std::collections::{HashSet, VecDeque};\n\nfn main() {\n    let v = [1, 2, 3, 4, 5];\n    let v2: Vec<isize> = v.to_vec();\n    //~^ iter_cloned_collect\n    let v3: HashSet<isize> = v.iter().cloned().collect();\n    let v4: VecDeque<isize> = v.iter().cloned().collect();\n\n    // Handle macro expansion in suggestion\n    let _: Vec<isize> = vec![1, 2, 3].to_vec();\n    //~^ iter_cloned_collect\n\n    // Issue #3704\n    unsafe {\n        let _: Vec<u8> = std::ffi::CStr::from_ptr(std::ptr::null())\n            .to_bytes().to_vec();\n    }\n\n    // Issue #6808\n    let arr: [u8; 64] = [0; 64];\n    let _: Vec<_> = arr.to_vec();\n    //~^ iter_cloned_collect\n\n    // Issue #6703\n    let _: Vec<isize> = v.to_vec();\n    //~^ iter_cloned_collect\n}\n\nmod issue9119 {\n\n    use std::iter;\n\n    #[derive(Clone)]\n    struct Example(u16);\n\n    impl iter::FromIterator<Example> for Vec<u8> {\n        fn from_iter<T>(iter: T) -> Self\n        where\n            T: IntoIterator<Item = Example>,\n        {\n            iter.into_iter().flat_map(|e| e.0.to_le_bytes()).collect()\n        }\n    }\n\n    fn foo() {\n        let examples = [Example(1), Example(0x1234)];\n        let encoded: Vec<u8> = examples.iter().cloned().collect();\n        assert_eq!(encoded, vec![0x01, 0x00, 0x34, 0x12]);\n\n        let a = [&&String::new()];\n        let v: Vec<&&String> = a.to_vec();\n        //~^ iter_cloned_collect\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_cloned_collect.rs",
    "content": "#![allow(unused)]\n#![allow(clippy::useless_vec)]\n\nuse std::collections::{HashSet, VecDeque};\n\nfn main() {\n    let v = [1, 2, 3, 4, 5];\n    let v2: Vec<isize> = v.iter().cloned().collect();\n    //~^ iter_cloned_collect\n    let v3: HashSet<isize> = v.iter().cloned().collect();\n    let v4: VecDeque<isize> = v.iter().cloned().collect();\n\n    // Handle macro expansion in suggestion\n    let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();\n    //~^ iter_cloned_collect\n\n    // Issue #3704\n    unsafe {\n        let _: Vec<u8> = std::ffi::CStr::from_ptr(std::ptr::null())\n            .to_bytes()\n            //~^ iter_cloned_collect\n            .iter()\n            .cloned()\n            .collect();\n    }\n\n    // Issue #6808\n    let arr: [u8; 64] = [0; 64];\n    let _: Vec<_> = arr.iter().cloned().collect();\n    //~^ iter_cloned_collect\n\n    // Issue #6703\n    let _: Vec<isize> = v.iter().copied().collect();\n    //~^ iter_cloned_collect\n}\n\nmod issue9119 {\n\n    use std::iter;\n\n    #[derive(Clone)]\n    struct Example(u16);\n\n    impl iter::FromIterator<Example> for Vec<u8> {\n        fn from_iter<T>(iter: T) -> Self\n        where\n            T: IntoIterator<Item = Example>,\n        {\n            iter.into_iter().flat_map(|e| e.0.to_le_bytes()).collect()\n        }\n    }\n\n    fn foo() {\n        let examples = [Example(1), Example(0x1234)];\n        let encoded: Vec<u8> = examples.iter().cloned().collect();\n        assert_eq!(encoded, vec![0x01, 0x00, 0x34, 0x12]);\n\n        let a = [&&String::new()];\n        let v: Vec<&&String> = a.iter().cloned().collect();\n        //~^ iter_cloned_collect\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_cloned_collect.stderr",
    "content": "error: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable\n  --> tests/ui/iter_cloned_collect.rs:8:27\n   |\nLL |     let v2: Vec<isize> = v.iter().cloned().collect();\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`\n   |\n   = note: `-D clippy::iter-cloned-collect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_cloned_collect)]`\n\nerror: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable\n  --> tests/ui/iter_cloned_collect.rs:14:38\n   |\nLL |     let _: Vec<isize> = vec![1, 2, 3].iter().cloned().collect();\n   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`\n\nerror: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable\n  --> tests/ui/iter_cloned_collect.rs:20:24\n   |\nLL |               .to_bytes()\n   |  ________________________^\nLL | |\nLL | |             .iter()\nLL | |             .cloned()\nLL | |             .collect();\n   | |______________________^ help: try: `.to_vec()`\n\nerror: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable\n  --> tests/ui/iter_cloned_collect.rs:29:24\n   |\nLL |     let _: Vec<_> = arr.iter().cloned().collect();\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`\n\nerror: called `iter().copied().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable\n  --> tests/ui/iter_cloned_collect.rs:33:26\n   |\nLL |     let _: Vec<isize> = v.iter().copied().collect();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`\n\nerror: called `iter().cloned().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and more readable\n  --> tests/ui/iter_cloned_collect.rs:59:33\n   |\nLL |         let v: Vec<&&String> = a.iter().cloned().collect();\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.to_vec()`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_count.fixed",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::iter_count)]\n#![allow(\n    unused_variables,\n    array_into_iter,\n    unused_mut,\n    clippy::into_iter_on_ref,\n    clippy::unnecessary_operation,\n    clippy::useless_vec\n)]\n\nextern crate option_helpers;\n\nuse option_helpers::IteratorFalsePositives;\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};\n\n/// Struct to generate false positives for things with `.iter()`.\n#[derive(Copy, Clone)]\nstruct HasIter;\n\nimpl HasIter {\n    fn iter(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n\n    fn iter_mut(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n\n    fn into_iter(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n}\n\n#[allow(unused_must_use)]\nfn main() {\n    let mut vec = vec![0, 1, 2, 3];\n    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect();\n    let mut hash_set = HashSet::new();\n    let mut hash_map = HashMap::new();\n    let mut b_tree_map = BTreeMap::new();\n    let mut b_tree_set = BTreeSet::new();\n    let mut linked_list = LinkedList::new();\n    let mut binary_heap = BinaryHeap::new();\n    hash_set.insert(1);\n    hash_map.insert(1, 2);\n    b_tree_map.insert(1, 2);\n    b_tree_set.insert(1);\n    linked_list.push_back(1);\n    binary_heap.push(1);\n\n    &vec[..].len();\n    //~^ iter_count\n    vec.len();\n    //~^ iter_count\n    boxed_slice.len();\n    //~^ iter_count\n    vec_deque.len();\n    //~^ iter_count\n    hash_set.len();\n    //~^ iter_count\n    hash_map.len();\n    //~^ iter_count\n    b_tree_map.len();\n    //~^ iter_count\n    b_tree_set.len();\n    //~^ iter_count\n    linked_list.len();\n    //~^ iter_count\n    binary_heap.len();\n    //~^ iter_count\n\n    vec.len();\n    //~^ iter_count\n    &vec[..].len();\n    //~^ iter_count\n    vec_deque.len();\n    //~^ iter_count\n    hash_map.len();\n    //~^ iter_count\n    b_tree_map.len();\n    //~^ iter_count\n    linked_list.len();\n    //~^ iter_count\n\n    &vec[..].len();\n    //~^ iter_count\n    vec.len();\n    //~^ iter_count\n    vec_deque.len();\n    //~^ iter_count\n    hash_set.len();\n    //~^ iter_count\n    hash_map.len();\n    //~^ iter_count\n    b_tree_map.len();\n    //~^ iter_count\n    b_tree_set.len();\n    //~^ iter_count\n    linked_list.len();\n    //~^ iter_count\n    binary_heap.len();\n    //~^ iter_count\n\n    // Make sure we don't lint for non-relevant types.\n    let false_positive = HasIter;\n    false_positive.iter().count();\n    false_positive.iter_mut().count();\n    false_positive.into_iter().count();\n}\n"
  },
  {
    "path": "tests/ui/iter_count.rs",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::iter_count)]\n#![allow(\n    unused_variables,\n    array_into_iter,\n    unused_mut,\n    clippy::into_iter_on_ref,\n    clippy::unnecessary_operation,\n    clippy::useless_vec\n)]\n\nextern crate option_helpers;\n\nuse option_helpers::IteratorFalsePositives;\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};\n\n/// Struct to generate false positives for things with `.iter()`.\n#[derive(Copy, Clone)]\nstruct HasIter;\n\nimpl HasIter {\n    fn iter(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n\n    fn iter_mut(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n\n    fn into_iter(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n}\n\n#[allow(unused_must_use)]\nfn main() {\n    let mut vec = vec![0, 1, 2, 3];\n    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect();\n    let mut hash_set = HashSet::new();\n    let mut hash_map = HashMap::new();\n    let mut b_tree_map = BTreeMap::new();\n    let mut b_tree_set = BTreeSet::new();\n    let mut linked_list = LinkedList::new();\n    let mut binary_heap = BinaryHeap::new();\n    hash_set.insert(1);\n    hash_map.insert(1, 2);\n    b_tree_map.insert(1, 2);\n    b_tree_set.insert(1);\n    linked_list.push_back(1);\n    binary_heap.push(1);\n\n    &vec[..].iter().count();\n    //~^ iter_count\n    vec.iter().count();\n    //~^ iter_count\n    boxed_slice.iter().count();\n    //~^ iter_count\n    vec_deque.iter().count();\n    //~^ iter_count\n    hash_set.iter().count();\n    //~^ iter_count\n    hash_map.iter().count();\n    //~^ iter_count\n    b_tree_map.iter().count();\n    //~^ iter_count\n    b_tree_set.iter().count();\n    //~^ iter_count\n    linked_list.iter().count();\n    //~^ iter_count\n    binary_heap.iter().count();\n    //~^ iter_count\n\n    vec.iter_mut().count();\n    //~^ iter_count\n    &vec[..].iter_mut().count();\n    //~^ iter_count\n    vec_deque.iter_mut().count();\n    //~^ iter_count\n    hash_map.iter_mut().count();\n    //~^ iter_count\n    b_tree_map.iter_mut().count();\n    //~^ iter_count\n    linked_list.iter_mut().count();\n    //~^ iter_count\n\n    &vec[..].into_iter().count();\n    //~^ iter_count\n    vec.into_iter().count();\n    //~^ iter_count\n    vec_deque.into_iter().count();\n    //~^ iter_count\n    hash_set.into_iter().count();\n    //~^ iter_count\n    hash_map.into_iter().count();\n    //~^ iter_count\n    b_tree_map.into_iter().count();\n    //~^ iter_count\n    b_tree_set.into_iter().count();\n    //~^ iter_count\n    linked_list.into_iter().count();\n    //~^ iter_count\n    binary_heap.into_iter().count();\n    //~^ iter_count\n\n    // Make sure we don't lint for non-relevant types.\n    let false_positive = HasIter;\n    false_positive.iter().count();\n    false_positive.iter_mut().count();\n    false_positive.into_iter().count();\n}\n"
  },
  {
    "path": "tests/ui/iter_count.stderr",
    "content": "error: called `.iter().count()` on a `slice`\n  --> tests/ui/iter_count.rs:54:6\n   |\nLL |     &vec[..].iter().count();\n   |      ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`\n   |\n   = note: `-D clippy::iter-count` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_count)]`\n\nerror: called `.iter().count()` on a `Vec`\n  --> tests/ui/iter_count.rs:56:5\n   |\nLL |     vec.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`\n\nerror: called `.iter().count()` on a `slice`\n  --> tests/ui/iter_count.rs:58:5\n   |\nLL |     boxed_slice.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()`\n\nerror: called `.iter().count()` on a `VecDeque`\n  --> tests/ui/iter_count.rs:60:5\n   |\nLL |     vec_deque.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`\n\nerror: called `.iter().count()` on a `HashSet`\n  --> tests/ui/iter_count.rs:62:5\n   |\nLL |     hash_set.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()`\n\nerror: called `.iter().count()` on a `HashMap`\n  --> tests/ui/iter_count.rs:64:5\n   |\nLL |     hash_map.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()`\n\nerror: called `.iter().count()` on a `BTreeMap`\n  --> tests/ui/iter_count.rs:66:5\n   |\nLL |     b_tree_map.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()`\n\nerror: called `.iter().count()` on a `BTreeSet`\n  --> tests/ui/iter_count.rs:68:5\n   |\nLL |     b_tree_set.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()`\n\nerror: called `.iter().count()` on a `LinkedList`\n  --> tests/ui/iter_count.rs:70:5\n   |\nLL |     linked_list.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()`\n\nerror: called `.iter().count()` on a `BinaryHeap`\n  --> tests/ui/iter_count.rs:72:5\n   |\nLL |     binary_heap.iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()`\n\nerror: called `.iter_mut().count()` on a `Vec`\n  --> tests/ui/iter_count.rs:75:5\n   |\nLL |     vec.iter_mut().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`\n\nerror: called `.iter_mut().count()` on a `slice`\n  --> tests/ui/iter_count.rs:77:6\n   |\nLL |     &vec[..].iter_mut().count();\n   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`\n\nerror: called `.iter_mut().count()` on a `VecDeque`\n  --> tests/ui/iter_count.rs:79:5\n   |\nLL |     vec_deque.iter_mut().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`\n\nerror: called `.iter_mut().count()` on a `HashMap`\n  --> tests/ui/iter_count.rs:81:5\n   |\nLL |     hash_map.iter_mut().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()`\n\nerror: called `.iter_mut().count()` on a `BTreeMap`\n  --> tests/ui/iter_count.rs:83:5\n   |\nLL |     b_tree_map.iter_mut().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()`\n\nerror: called `.iter_mut().count()` on a `LinkedList`\n  --> tests/ui/iter_count.rs:85:5\n   |\nLL |     linked_list.iter_mut().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()`\n\nerror: called `.into_iter().count()` on a `slice`\n  --> tests/ui/iter_count.rs:88:6\n   |\nLL |     &vec[..].into_iter().count();\n   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`\n\nerror: called `.into_iter().count()` on a `Vec`\n  --> tests/ui/iter_count.rs:90:5\n   |\nLL |     vec.into_iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`\n\nerror: called `.into_iter().count()` on a `VecDeque`\n  --> tests/ui/iter_count.rs:92:5\n   |\nLL |     vec_deque.into_iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`\n\nerror: called `.into_iter().count()` on a `HashSet`\n  --> tests/ui/iter_count.rs:94:5\n   |\nLL |     hash_set.into_iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()`\n\nerror: called `.into_iter().count()` on a `HashMap`\n  --> tests/ui/iter_count.rs:96:5\n   |\nLL |     hash_map.into_iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.len()`\n\nerror: called `.into_iter().count()` on a `BTreeMap`\n  --> tests/ui/iter_count.rs:98:5\n   |\nLL |     b_tree_map.into_iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_map.len()`\n\nerror: called `.into_iter().count()` on a `BTreeSet`\n  --> tests/ui/iter_count.rs:100:5\n   |\nLL |     b_tree_set.into_iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `b_tree_set.len()`\n\nerror: called `.into_iter().count()` on a `LinkedList`\n  --> tests/ui/iter_count.rs:102:5\n   |\nLL |     linked_list.into_iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `linked_list.len()`\n\nerror: called `.into_iter().count()` on a `BinaryHeap`\n  --> tests/ui/iter_count.rs:104:5\n   |\nLL |     binary_heap.into_iter().count();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `binary_heap.len()`\n\nerror: aborting due to 25 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_filter_is_ok.fixed",
    "content": "#![warn(clippy::iter_filter_is_ok)]\n#![allow(\n    clippy::map_identity,\n    clippy::result_filter_map,\n    clippy::needless_borrow,\n    clippy::redundant_closure\n)]\n\nfn main() {\n    {\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n\n        #[rustfmt::skip]\n        let _ = vec![Ok(1), Err(2)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n    }\n\n    {\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n\n        #[rustfmt::skip]\n        let _ = vec![Ok(1), Err(2)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n    }\n\n    {\n        let _ = vec![Ok(1), Err(2), Ok(3)]\n            .into_iter()\n            .flatten();\n        //~^ iter_filter_is_ok\n\n        let _ = vec![Ok(1), Err(2), Ok(3)]\n            .into_iter()\n            .flatten();\n        //~^ iter_filter_is_ok\n\n        #[rustfmt::skip]\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n    }\n\n    {\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n\n        #[rustfmt::skip]\n        let _ = vec![Ok(1), Err(2)].into_iter().flatten();\n        //~^ iter_filter_is_ok\n    }\n}\n\nfn avoid_linting_when_filter_has_side_effects() {\n    // Don't lint below\n    let mut counter = 0;\n    let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| {\n        counter += 1;\n        o.is_ok()\n    });\n}\n\nfn avoid_linting_when_commented() {\n    let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| {\n        // Roses are red,\n        // Violets are blue,\n        // `Err` is not an `Option`,\n        // and this doesn't ryme\n        o.is_ok()\n    });\n}\n\nfn ice_12058() {\n    // check that checking the parent node doesn't cause an ICE\n    // by indexing the parameters of a closure without parameters\n    Some(1).or_else(|| {\n        vec![Ok(1), Err(())].into_iter().filter(|z| *z != Ok(2));\n        None\n    });\n}\n\nfn avoid_linting_map() {\n    // should not lint\n    let _ = vec![Ok(1), Err(())]\n        .into_iter()\n        .filter(|o| o.is_ok())\n        .map(|o| o.unwrap());\n\n    // should not lint\n    let _ = vec![Ok(1), Err(())].into_iter().filter(|o| o.is_ok()).map(|o| o);\n}\n\nfn avoid_false_positive_due_to_is_ok_and_iterator_impl() {\n    #[derive(Default, Clone)]\n    struct Foo {}\n\n    impl Foo {\n        fn is_ok(&self) -> bool {\n            true\n        }\n    }\n\n    impl Iterator for Foo {\n        type Item = Foo;\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(Foo::default())\n        }\n    }\n\n    let data = vec![Foo::default()];\n    // should not lint\n    let _ = data.clone().into_iter().filter(Foo::is_ok);\n    // should not lint\n    let _ = data.clone().into_iter().filter(|f| f.is_ok());\n}\n\nfn avoid_false_positive_due_to_is_ok_and_into_iterator_impl() {\n    #[derive(Default, Clone)]\n    struct Foo {}\n\n    impl Foo {\n        fn is_ok(&self) -> bool {\n            true\n        }\n    }\n\n    let data = vec![Foo::default()];\n    // should not lint\n    let _ = data.clone().into_iter().filter(Foo::is_ok);\n    // should not lint\n    let _ = data.clone().into_iter().filter(|f| f.is_ok());\n}\n\nfn avoid_fp_for_trivial() {\n    let _ = vec![Ok(1), Err(()), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| (Err(()) as Result<i32, ()>).is_ok());\n}\n\nfn avoid_false_positive_due_to_method_name() {\n    fn is_ok(x: &Result<i32, i32>) -> bool {\n        x.is_ok()\n    }\n\n    vec![Ok(1), Err(2), Ok(3)].into_iter().filter(is_ok);\n    // should not lint\n}\n\nfn avoid_fp_due_to_trait_type() {\n    struct Foo {\n        bar: i32,\n    }\n    impl Foo {\n        fn is_ok(obj: &Result<i32, i32>) -> bool {\n            obj.is_ok()\n        }\n    }\n    vec![Ok(1), Err(2), Ok(3)].into_iter().filter(Foo::is_ok);\n    // should not lint\n}\n\nfn avoid_fp_with_call_to_outside_var() {\n    let outside: Result<i32, ()> = Ok(1);\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| outside.is_ok());\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Result::is_ok(&outside));\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| std::result::Result::is_ok(&outside));\n}\n\nfn avoid_fp_with_call_to_outside_var_mix_match_types() {\n    let outside = Some(1);\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| outside.is_some());\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Option::is_some(&outside));\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| std::option::Option::is_some(&outside));\n}\n"
  },
  {
    "path": "tests/ui/iter_filter_is_ok.rs",
    "content": "#![warn(clippy::iter_filter_is_ok)]\n#![allow(\n    clippy::map_identity,\n    clippy::result_filter_map,\n    clippy::needless_borrow,\n    clippy::redundant_closure\n)]\n\nfn main() {\n    {\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(Result::is_ok);\n        //~^ iter_filter_is_ok\n\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| a.is_ok());\n        //~^ iter_filter_is_ok\n\n        #[rustfmt::skip]\n        let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| { o.is_ok() });\n        //~^ iter_filter_is_ok\n    }\n\n    {\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok());\n        //~^ iter_filter_is_ok\n\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok());\n        //~^ iter_filter_is_ok\n\n        #[rustfmt::skip]\n        let _ = vec![Ok(1), Err(2)].into_iter().filter(|&o| { o.is_ok() });\n        //~^ iter_filter_is_ok\n    }\n\n    {\n        let _ = vec![Ok(1), Err(2), Ok(3)]\n            .into_iter()\n            .filter(std::result::Result::is_ok);\n        //~^ iter_filter_is_ok\n\n        let _ = vec![Ok(1), Err(2), Ok(3)]\n            .into_iter()\n            .filter(|a| std::result::Result::is_ok(a));\n        //~^ iter_filter_is_ok\n\n        #[rustfmt::skip]\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| { std::result::Result::is_ok(a) });\n        //~^ iter_filter_is_ok\n    }\n\n    {\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok());\n        //~^ iter_filter_is_ok\n\n        let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok());\n        //~^ iter_filter_is_ok\n\n        #[rustfmt::skip]\n        let _ = vec![Ok(1), Err(2)].into_iter().filter(|ref o| { o.is_ok() });\n        //~^ iter_filter_is_ok\n    }\n}\n\nfn avoid_linting_when_filter_has_side_effects() {\n    // Don't lint below\n    let mut counter = 0;\n    let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| {\n        counter += 1;\n        o.is_ok()\n    });\n}\n\nfn avoid_linting_when_commented() {\n    let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| {\n        // Roses are red,\n        // Violets are blue,\n        // `Err` is not an `Option`,\n        // and this doesn't ryme\n        o.is_ok()\n    });\n}\n\nfn ice_12058() {\n    // check that checking the parent node doesn't cause an ICE\n    // by indexing the parameters of a closure without parameters\n    Some(1).or_else(|| {\n        vec![Ok(1), Err(())].into_iter().filter(|z| *z != Ok(2));\n        None\n    });\n}\n\nfn avoid_linting_map() {\n    // should not lint\n    let _ = vec![Ok(1), Err(())]\n        .into_iter()\n        .filter(|o| o.is_ok())\n        .map(|o| o.unwrap());\n\n    // should not lint\n    let _ = vec![Ok(1), Err(())].into_iter().filter(|o| o.is_ok()).map(|o| o);\n}\n\nfn avoid_false_positive_due_to_is_ok_and_iterator_impl() {\n    #[derive(Default, Clone)]\n    struct Foo {}\n\n    impl Foo {\n        fn is_ok(&self) -> bool {\n            true\n        }\n    }\n\n    impl Iterator for Foo {\n        type Item = Foo;\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(Foo::default())\n        }\n    }\n\n    let data = vec![Foo::default()];\n    // should not lint\n    let _ = data.clone().into_iter().filter(Foo::is_ok);\n    // should not lint\n    let _ = data.clone().into_iter().filter(|f| f.is_ok());\n}\n\nfn avoid_false_positive_due_to_is_ok_and_into_iterator_impl() {\n    #[derive(Default, Clone)]\n    struct Foo {}\n\n    impl Foo {\n        fn is_ok(&self) -> bool {\n            true\n        }\n    }\n\n    let data = vec![Foo::default()];\n    // should not lint\n    let _ = data.clone().into_iter().filter(Foo::is_ok);\n    // should not lint\n    let _ = data.clone().into_iter().filter(|f| f.is_ok());\n}\n\nfn avoid_fp_for_trivial() {\n    let _ = vec![Ok(1), Err(()), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| (Err(()) as Result<i32, ()>).is_ok());\n}\n\nfn avoid_false_positive_due_to_method_name() {\n    fn is_ok(x: &Result<i32, i32>) -> bool {\n        x.is_ok()\n    }\n\n    vec![Ok(1), Err(2), Ok(3)].into_iter().filter(is_ok);\n    // should not lint\n}\n\nfn avoid_fp_due_to_trait_type() {\n    struct Foo {\n        bar: i32,\n    }\n    impl Foo {\n        fn is_ok(obj: &Result<i32, i32>) -> bool {\n            obj.is_ok()\n        }\n    }\n    vec![Ok(1), Err(2), Ok(3)].into_iter().filter(Foo::is_ok);\n    // should not lint\n}\n\nfn avoid_fp_with_call_to_outside_var() {\n    let outside: Result<i32, ()> = Ok(1);\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| outside.is_ok());\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Result::is_ok(&outside));\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| std::result::Result::is_ok(&outside));\n}\n\nfn avoid_fp_with_call_to_outside_var_mix_match_types() {\n    let outside = Some(1);\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| outside.is_some());\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Option::is_some(&outside));\n\n    let _ = vec![Ok(1), Err(2), Ok(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| std::option::Option::is_some(&outside));\n}\n"
  },
  {
    "path": "tests/ui/iter_filter_is_ok.stderr",
    "content": "error: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:11:56\n   |\nLL |         let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(Result::is_ok);\n   |                                                        ^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n   |\n   = note: `-D clippy::iter-filter-is-ok` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_filter_is_ok)]`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:14:56\n   |\nLL |         let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| a.is_ok());\n   |                                                        ^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:18:49\n   |\nLL |         let _ = vec![Ok(1), Err(2)].into_iter().filter(|o| { o.is_ok() });\n   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:23:56\n   |\nLL |         let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok());\n   |                                                        ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:26:56\n   |\nLL |         let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|&a| a.is_ok());\n   |                                                        ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:30:49\n   |\nLL |         let _ = vec![Ok(1), Err(2)].into_iter().filter(|&o| { o.is_ok() });\n   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:37:14\n   |\nLL |             .filter(std::result::Result::is_ok);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:42:14\n   |\nLL |             .filter(|a| std::result::Result::is_ok(a));\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:46:56\n   |\nLL |         let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|a| { std::result::Result::is_ok(a) });\n   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:51:56\n   |\nLL |         let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok());\n   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:54:56\n   |\nLL |         let _ = vec![Ok(1), Err(2), Ok(3)].into_iter().filter(|ref a| a.is_ok());\n   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_ok` on iterator over `Result`s\n  --> tests/ui/iter_filter_is_ok.rs:58:49\n   |\nLL |         let _ = vec![Ok(1), Err(2)].into_iter().filter(|ref o| { o.is_ok() });\n   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_filter_is_some.fixed",
    "content": "#![warn(clippy::iter_filter_is_some)]\n#![allow(\n    clippy::map_identity,\n    clippy::result_filter_map,\n    clippy::needless_borrow,\n    clippy::option_filter_map,\n    clippy::redundant_closure,\n    clippy::unnecessary_get_then_check\n)]\n\nuse std::collections::HashMap;\n\nfn main() {\n    {\n        let _ = vec![Some(1), None, Some(3)].into_iter().flatten();\n        //~^ iter_filter_is_some\n\n        let _ = vec![Some(1), None, Some(3)].into_iter().flatten();\n        //~^ iter_filter_is_some\n\n        #[rustfmt::skip]\n        let _ = vec![Some(1), None, Some(3)].into_iter().flatten();\n        //~^ iter_filter_is_some\n    }\n\n    {\n        let _ = vec![Some(1), None, Some(3)]\n            .into_iter()\n            .flatten();\n        //~^ iter_filter_is_some\n\n        let _ = vec![Some(1), None, Some(3)]\n            .into_iter()\n            .flatten();\n        //~^ iter_filter_is_some\n\n        #[rustfmt::skip]\n        let _ = vec![Some(1), None, Some(3)].into_iter().flatten();\n        //~^ iter_filter_is_some\n    }\n\n    {\n        let _ = vec![Some(1), None, Some(3)].into_iter().flatten();\n        //~^ iter_filter_is_some\n\n        #[rustfmt::skip]\n        let _ = vec![Some(1), None, Some(3)].into_iter().flatten();\n        //~^ iter_filter_is_some\n    }\n\n    {\n        let _ = vec![Some(1), None, Some(3)].into_iter().flatten();\n        //~^ iter_filter_is_some\n\n        #[rustfmt::skip]\n        let _ = vec![Some(1), None, Some(3)].into_iter().flatten();\n        //~^ iter_filter_is_some\n    }\n}\n\nfn avoid_linting_when_filter_has_side_effects() {\n    // Don't lint below\n    let mut counter = 0;\n    let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| {\n        counter += 1;\n        o.is_some()\n    });\n}\n\nfn avoid_linting_when_commented() {\n    let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| {\n        // Roses are red,\n        // Violets are blue,\n        // `Err` is not an `Option`,\n        // and this doesn't ryme\n        o.is_some()\n    });\n}\n\nfn ice_12058() {\n    // check that checking the parent node doesn't cause an ICE\n    // by indexing the parameters of a closure without parameters\n    Some(1).or_else(|| {\n        vec![Some(1), None, Some(3)].into_iter().filter(|z| *z != Some(2));\n        None\n    });\n}\n\nfn avoid_linting_map() {\n    // should not lint\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        .filter(|o| o.is_some())\n        .map(|o| o.unwrap());\n\n    // should not lint\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        .filter(|o| o.is_some())\n        .map(|o| o);\n}\n\nfn avoid_false_positive_due_to_is_some_and_iterator_impl() {\n    #[derive(Default, Clone)]\n    struct Foo {}\n\n    impl Foo {\n        fn is_some(&self) -> bool {\n            true\n        }\n    }\n\n    impl Iterator for Foo {\n        type Item = Foo;\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(Foo::default())\n        }\n    }\n\n    let data = vec![Foo::default()];\n    // should not lint\n    let _ = data.clone().into_iter().filter(Foo::is_some);\n    // should not lint\n    let _ = data.clone().into_iter().filter(|f| f.is_some());\n}\n\nfn avoid_false_positive_due_to_is_some_and_into_iterator_impl() {\n    #[derive(Default, Clone)]\n    struct Foo {}\n\n    impl Foo {\n        fn is_some(&self) -> bool {\n            true\n        }\n    }\n\n    let data = vec![Foo::default()];\n    // should not lint\n    let _ = data.clone().into_iter().filter(Foo::is_some);\n    // should not lint\n    let _ = data.clone().into_iter().filter(|f| f.is_some());\n}\n\nfn avoid_unpack_fp() {\n    let _ = vec![(Some(1), None), (None, Some(3))]\n        .into_iter()\n        // should not lint\n        .filter(|(a, _)| a.is_some());\n    let _ = vec![(Some(1), None), (None, Some(3))]\n        .into_iter()\n        // should not lint\n        .filter(|(a, _)| a.is_some())\n        .collect::<Vec<_>>();\n\n    let m = HashMap::from([(1, 1)]);\n    let _ = vec![1, 2, 4].into_iter().filter(|a| m.get(a).is_some());\n    // should not lint\n}\n\nfn avoid_fp_for_external() {\n    let value = HashMap::from([(1, 1)]);\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| value.get(&1).is_some());\n\n    let value = Option::Some(1);\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| value.is_some());\n}\n\nfn avoid_fp_for_trivial() {\n    let value = HashMap::from([(1, 1)]);\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Some(1).is_some());\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| None::<i32>.is_some());\n}\n\nfn avoid_false_positive_due_to_method_name() {\n    fn is_some(x: &Option<i32>) -> bool {\n        x.is_some()\n    }\n\n    vec![Some(1), None, Some(3)].into_iter().filter(is_some);\n    // should not lint\n}\n\nfn avoid_fp_due_to_trait_type() {\n    struct Foo {\n        bar: i32,\n    }\n    impl Foo {\n        fn is_some(obj: &Option<i32>) -> bool {\n            obj.is_some()\n        }\n    }\n    vec![Some(1), None, Some(3)].into_iter().filter(Foo::is_some);\n    // should not lint\n}\n\nfn avoid_fp_with_call_to_outside_var() {\n    let outside = Some(1);\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| outside.is_some());\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Option::is_some(&outside));\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| std::option::Option::is_some(&outside));\n}\n\nfn avoid_fp_with_call_to_outside_var_mix_match_types() {\n    let outside: Result<i32, ()> = Ok(1);\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| outside.is_ok());\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Result::is_ok(&outside));\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| std::result::Result::is_ok(&outside));\n}\n"
  },
  {
    "path": "tests/ui/iter_filter_is_some.rs",
    "content": "#![warn(clippy::iter_filter_is_some)]\n#![allow(\n    clippy::map_identity,\n    clippy::result_filter_map,\n    clippy::needless_borrow,\n    clippy::option_filter_map,\n    clippy::redundant_closure,\n    clippy::unnecessary_get_then_check\n)]\n\nuse std::collections::HashMap;\n\nfn main() {\n    {\n        let _ = vec![Some(1), None, Some(3)].into_iter().filter(Option::is_some);\n        //~^ iter_filter_is_some\n\n        let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| a.is_some());\n        //~^ iter_filter_is_some\n\n        #[rustfmt::skip]\n        let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| { o.is_some() });\n        //~^ iter_filter_is_some\n    }\n\n    {\n        let _ = vec![Some(1), None, Some(3)]\n            .into_iter()\n            .filter(std::option::Option::is_some);\n        //~^ iter_filter_is_some\n\n        let _ = vec![Some(1), None, Some(3)]\n            .into_iter()\n            .filter(|a| std::option::Option::is_some(a));\n        //~^ iter_filter_is_some\n\n        #[rustfmt::skip]\n        let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| { std::option::Option::is_some(a) });\n        //~^ iter_filter_is_some\n    }\n\n    {\n        let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&a| a.is_some());\n        //~^ iter_filter_is_some\n\n        #[rustfmt::skip]\n        let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&o| { o.is_some() });\n        //~^ iter_filter_is_some\n    }\n\n    {\n        let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref a| a.is_some());\n        //~^ iter_filter_is_some\n\n        #[rustfmt::skip]\n        let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref o| { o.is_some() });\n        //~^ iter_filter_is_some\n    }\n}\n\nfn avoid_linting_when_filter_has_side_effects() {\n    // Don't lint below\n    let mut counter = 0;\n    let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| {\n        counter += 1;\n        o.is_some()\n    });\n}\n\nfn avoid_linting_when_commented() {\n    let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| {\n        // Roses are red,\n        // Violets are blue,\n        // `Err` is not an `Option`,\n        // and this doesn't ryme\n        o.is_some()\n    });\n}\n\nfn ice_12058() {\n    // check that checking the parent node doesn't cause an ICE\n    // by indexing the parameters of a closure without parameters\n    Some(1).or_else(|| {\n        vec![Some(1), None, Some(3)].into_iter().filter(|z| *z != Some(2));\n        None\n    });\n}\n\nfn avoid_linting_map() {\n    // should not lint\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        .filter(|o| o.is_some())\n        .map(|o| o.unwrap());\n\n    // should not lint\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        .filter(|o| o.is_some())\n        .map(|o| o);\n}\n\nfn avoid_false_positive_due_to_is_some_and_iterator_impl() {\n    #[derive(Default, Clone)]\n    struct Foo {}\n\n    impl Foo {\n        fn is_some(&self) -> bool {\n            true\n        }\n    }\n\n    impl Iterator for Foo {\n        type Item = Foo;\n        fn next(&mut self) -> Option<Self::Item> {\n            Some(Foo::default())\n        }\n    }\n\n    let data = vec![Foo::default()];\n    // should not lint\n    let _ = data.clone().into_iter().filter(Foo::is_some);\n    // should not lint\n    let _ = data.clone().into_iter().filter(|f| f.is_some());\n}\n\nfn avoid_false_positive_due_to_is_some_and_into_iterator_impl() {\n    #[derive(Default, Clone)]\n    struct Foo {}\n\n    impl Foo {\n        fn is_some(&self) -> bool {\n            true\n        }\n    }\n\n    let data = vec![Foo::default()];\n    // should not lint\n    let _ = data.clone().into_iter().filter(Foo::is_some);\n    // should not lint\n    let _ = data.clone().into_iter().filter(|f| f.is_some());\n}\n\nfn avoid_unpack_fp() {\n    let _ = vec![(Some(1), None), (None, Some(3))]\n        .into_iter()\n        // should not lint\n        .filter(|(a, _)| a.is_some());\n    let _ = vec![(Some(1), None), (None, Some(3))]\n        .into_iter()\n        // should not lint\n        .filter(|(a, _)| a.is_some())\n        .collect::<Vec<_>>();\n\n    let m = HashMap::from([(1, 1)]);\n    let _ = vec![1, 2, 4].into_iter().filter(|a| m.get(a).is_some());\n    // should not lint\n}\n\nfn avoid_fp_for_external() {\n    let value = HashMap::from([(1, 1)]);\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| value.get(&1).is_some());\n\n    let value = Option::Some(1);\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| value.is_some());\n}\n\nfn avoid_fp_for_trivial() {\n    let value = HashMap::from([(1, 1)]);\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Some(1).is_some());\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| None::<i32>.is_some());\n}\n\nfn avoid_false_positive_due_to_method_name() {\n    fn is_some(x: &Option<i32>) -> bool {\n        x.is_some()\n    }\n\n    vec![Some(1), None, Some(3)].into_iter().filter(is_some);\n    // should not lint\n}\n\nfn avoid_fp_due_to_trait_type() {\n    struct Foo {\n        bar: i32,\n    }\n    impl Foo {\n        fn is_some(obj: &Option<i32>) -> bool {\n            obj.is_some()\n        }\n    }\n    vec![Some(1), None, Some(3)].into_iter().filter(Foo::is_some);\n    // should not lint\n}\n\nfn avoid_fp_with_call_to_outside_var() {\n    let outside = Some(1);\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| outside.is_some());\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Option::is_some(&outside));\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| std::option::Option::is_some(&outside));\n}\n\nfn avoid_fp_with_call_to_outside_var_mix_match_types() {\n    let outside: Result<i32, ()> = Ok(1);\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| outside.is_ok());\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| Result::is_ok(&outside));\n\n    let _ = vec![Some(1), None, Some(3)]\n        .into_iter()\n        // should not lint\n        .filter(|o| std::result::Result::is_ok(&outside));\n}\n"
  },
  {
    "path": "tests/ui/iter_filter_is_some.stderr",
    "content": "error: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:15:58\n   |\nLL |         let _ = vec![Some(1), None, Some(3)].into_iter().filter(Option::is_some);\n   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n   |\n   = note: `-D clippy::iter-filter-is-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_filter_is_some)]`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:18:58\n   |\nLL |         let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| a.is_some());\n   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:22:58\n   |\nLL |         let _ = vec![Some(1), None, Some(3)].into_iter().filter(|o| { o.is_some() });\n   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:29:14\n   |\nLL |             .filter(std::option::Option::is_some);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:34:14\n   |\nLL |             .filter(|a| std::option::Option::is_some(a));\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:38:58\n   |\nLL |         let _ = vec![Some(1), None, Some(3)].into_iter().filter(|a| { std::option::Option::is_some(a) });\n   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:43:58\n   |\nLL |         let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&a| a.is_some());\n   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:47:58\n   |\nLL |         let _ = vec![Some(1), None, Some(3)].into_iter().filter(|&o| { o.is_some() });\n   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:52:58\n   |\nLL |         let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref a| a.is_some());\n   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `is_some` on iterator over `Option`\n  --> tests/ui/iter_filter_is_some.rs:56:58\n   |\nLL |         let _ = vec![Some(1), None, Some(3)].into_iter().filter(|ref o| { o.is_some() });\n   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_kv_map.fixed",
    "content": "#![warn(clippy::iter_kv_map)]\n#![allow(\n    unused_mut,\n    clippy::redundant_clone,\n    clippy::redundant_closure,\n    clippy::suspicious_map,\n    clippy::map_identity\n)]\n\nuse std::collections::{BTreeMap, HashMap};\n\nfn main() {\n    let get_key = |(key, _val)| key;\n    fn ref_acceptor(v: &u32) -> u32 {\n        *v\n    }\n\n    let map: HashMap<u32, u32> = HashMap::new();\n\n    let _ = map.keys().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.values().map(|v| v + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_keys().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.clone().into_keys().map(|key| key + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.clone().into_values().map(|val| val + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.keys().filter(|x| x.is_multiple_of(2)).count();\n    //~^ iter_kv_map\n\n    // Don't lint\n    let _ = map\n        .iter()\n        .filter(|(_, val)| val.is_multiple_of(2))\n        .map(|(key, _)| key)\n        .count();\n    let _ = map.iter().map(get_key).collect::<Vec<_>>();\n\n    // Linting the following could be an improvement to the lint\n    // map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count();\n\n    // Lint\n    let _ = map.keys().map(|key| key * 9).count();\n    //~^ iter_kv_map\n    let _ = map.values().map(|value| value * 17).count();\n    //~^ iter_kv_map\n\n    // Preserve the ref in the fix.\n    let _ = map.clone().into_values().map(|ref val| ref_acceptor(val)).count();\n    //~^ iter_kv_map\n\n    // Preserve the mut in the fix.\n    let _ = map\n        //~^ iter_kv_map\n        .clone().into_values().map(|mut val| {\n            val += 2;\n            val\n        })\n        .count();\n\n    // Don't let a mut interfere.\n    let _ = map.clone().into_values().count();\n    //~^ iter_kv_map\n\n    let map: BTreeMap<u32, u32> = BTreeMap::new();\n\n    let _ = map.keys().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.values().map(|v| v + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_keys().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.clone().into_keys().map(|key| key + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.clone().into_values().map(|val| val + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.keys().filter(|x| x.is_multiple_of(2)).count();\n    //~^ iter_kv_map\n\n    // Don't lint\n    let _ = map\n        .iter()\n        .filter(|(_, val)| val.is_multiple_of(2))\n        .map(|(key, _)| key)\n        .count();\n    let _ = map.iter().map(get_key).collect::<Vec<_>>();\n\n    // Linting the following could be an improvement to the lint\n    // map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count();\n\n    // Lint\n    let _ = map.keys().map(|key| key * 9).count();\n    //~^ iter_kv_map\n    let _ = map.values().map(|value| value * 17).count();\n    //~^ iter_kv_map\n\n    // Preserve the ref in the fix.\n    let _ = map.clone().into_values().map(|ref val| ref_acceptor(val)).count();\n    //~^ iter_kv_map\n\n    // Preserve the mut in the fix.\n    let _ = map\n        //~^ iter_kv_map\n        .clone().into_values().map(|mut val| {\n            val += 2;\n            val\n        })\n        .count();\n\n    // Don't let a mut interfere.\n    let _ = map.clone().into_values().count();\n    //~^ iter_kv_map\n}\n\n#[clippy::msrv = \"1.53\"]\nfn msrv_1_53() {\n    let map: HashMap<u32, u32> = HashMap::new();\n\n    // Don't lint because into_iter is not supported\n    let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();\n    let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();\n\n    let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();\n    let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();\n\n    // Lint\n    let _ = map.keys().collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.values().map(|v| v + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n}\n\n#[clippy::msrv = \"1.54\"]\nfn msrv_1_54() {\n    // Lint all\n    let map: HashMap<u32, u32> = HashMap::new();\n\n    let _ = map.clone().into_keys().collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_keys().map(|key| key + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_values().map(|val| val + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.keys().collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.values().collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.values().map(|v| v + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n}\n\nfn issue14595() {\n    pub struct Foo(BTreeMap<String, i32>);\n\n    impl AsRef<BTreeMap<String, i32>> for Foo {\n        fn as_ref(&self) -> &BTreeMap<String, i32> {\n            &self.0\n        }\n    }\n\n    let map = Foo(BTreeMap::default());\n\n    let _ = map.as_ref().values().copied().collect::<Vec<_>>();\n    //~^ iter_kv_map\n}\n\nfn issue16340() {\n    let hm: HashMap<&str, &str> = HashMap::new();\n    let _ = hm.keys().map(|key| vec![key]);\n    //~^ iter_kv_map\n}\n\nfn issue16515() {\n    let hash_map: HashMap<u32, u32> = HashMap::new();\n    hash_map.keys().flat_map(|k| Some(*k));\n    //~^ iter_kv_map\n\n    hash_map.values().flat_map(|v| Some(*v));\n    //~^ iter_kv_map\n\n    hash_map.keys().filter_map(|k| (k > &0).then_some(1));\n    //~^ iter_kv_map\n\n    hash_map.values().filter_map(|v| (v > &0).then_some(1));\n    //~^ iter_kv_map\n\n    hash_map.into_keys().flat_map(|k| Some(k));\n    //~^ iter_kv_map\n\n    let hash_map: HashMap<u32, u32> = HashMap::new();\n    hash_map.into_values().flat_map(|v| Some(v));\n    //~^ iter_kv_map\n\n    let hash_map: HashMap<u32, u32> = HashMap::new();\n    hash_map.into_keys().filter_map(|k| (k > 0).then_some(1));\n    //~^ iter_kv_map\n\n    let hash_map: HashMap<u32, u32> = HashMap::new();\n    hash_map.into_values().filter_map(|v| (v > 0).then_some(1));\n    //~^ iter_kv_map\n}\n"
  },
  {
    "path": "tests/ui/iter_kv_map.rs",
    "content": "#![warn(clippy::iter_kv_map)]\n#![allow(\n    unused_mut,\n    clippy::redundant_clone,\n    clippy::redundant_closure,\n    clippy::suspicious_map,\n    clippy::map_identity\n)]\n\nuse std::collections::{BTreeMap, HashMap};\n\nfn main() {\n    let get_key = |(key, _val)| key;\n    fn ref_acceptor(v: &u32) -> u32 {\n        *v\n    }\n\n    let map: HashMap<u32, u32> = HashMap::new();\n\n    let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count();\n    //~^ iter_kv_map\n\n    // Don't lint\n    let _ = map\n        .iter()\n        .filter(|(_, val)| val.is_multiple_of(2))\n        .map(|(key, _)| key)\n        .count();\n    let _ = map.iter().map(get_key).collect::<Vec<_>>();\n\n    // Linting the following could be an improvement to the lint\n    // map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count();\n\n    // Lint\n    let _ = map.iter().map(|(key, _value)| key * 9).count();\n    //~^ iter_kv_map\n    let _ = map.iter().map(|(_key, value)| value * 17).count();\n    //~^ iter_kv_map\n\n    // Preserve the ref in the fix.\n    let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count();\n    //~^ iter_kv_map\n\n    // Preserve the mut in the fix.\n    let _ = map\n        //~^ iter_kv_map\n        .clone()\n        .into_iter()\n        .map(|(_, mut val)| {\n            val += 2;\n            val\n        })\n        .count();\n\n    // Don't let a mut interfere.\n    let _ = map.clone().into_iter().map(|(_, mut val)| val).count();\n    //~^ iter_kv_map\n\n    let map: BTreeMap<u32, u32> = BTreeMap::new();\n\n    let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();\n    //~^ iter_kv_map\n    let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count();\n    //~^ iter_kv_map\n\n    // Don't lint\n    let _ = map\n        .iter()\n        .filter(|(_, val)| val.is_multiple_of(2))\n        .map(|(key, _)| key)\n        .count();\n    let _ = map.iter().map(get_key).collect::<Vec<_>>();\n\n    // Linting the following could be an improvement to the lint\n    // map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count();\n\n    // Lint\n    let _ = map.iter().map(|(key, _value)| key * 9).count();\n    //~^ iter_kv_map\n    let _ = map.iter().map(|(_key, value)| value * 17).count();\n    //~^ iter_kv_map\n\n    // Preserve the ref in the fix.\n    let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count();\n    //~^ iter_kv_map\n\n    // Preserve the mut in the fix.\n    let _ = map\n        //~^ iter_kv_map\n        .clone()\n        .into_iter()\n        .map(|(_, mut val)| {\n            val += 2;\n            val\n        })\n        .count();\n\n    // Don't let a mut interfere.\n    let _ = map.clone().into_iter().map(|(_, mut val)| val).count();\n    //~^ iter_kv_map\n}\n\n#[clippy::msrv = \"1.53\"]\nfn msrv_1_53() {\n    let map: HashMap<u32, u32> = HashMap::new();\n\n    // Don't lint because into_iter is not supported\n    let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();\n    let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();\n\n    let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();\n    let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();\n\n    // Lint\n    let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n}\n\n#[clippy::msrv = \"1.54\"]\nfn msrv_1_54() {\n    // Lint all\n    let map: HashMap<u32, u32> = HashMap::new();\n\n    let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n    //~^ iter_kv_map\n\n    let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();\n    //~^ iter_kv_map\n}\n\nfn issue14595() {\n    pub struct Foo(BTreeMap<String, i32>);\n\n    impl AsRef<BTreeMap<String, i32>> for Foo {\n        fn as_ref(&self) -> &BTreeMap<String, i32> {\n            &self.0\n        }\n    }\n\n    let map = Foo(BTreeMap::default());\n\n    let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::<Vec<_>>();\n    //~^ iter_kv_map\n}\n\nfn issue16340() {\n    let hm: HashMap<&str, &str> = HashMap::new();\n    let _ = hm.iter().map(|(key, _)| vec![key]);\n    //~^ iter_kv_map\n}\n\nfn issue16515() {\n    let hash_map: HashMap<u32, u32> = HashMap::new();\n    hash_map.iter().flat_map(|(k, _)| Some(*k));\n    //~^ iter_kv_map\n\n    hash_map.iter().flat_map(|(_, v)| Some(*v));\n    //~^ iter_kv_map\n\n    hash_map.iter().filter_map(|(k, _)| (k > &0).then_some(1));\n    //~^ iter_kv_map\n\n    hash_map.iter().filter_map(|(_, v)| (v > &0).then_some(1));\n    //~^ iter_kv_map\n\n    hash_map.into_iter().flat_map(|(k, _)| Some(k));\n    //~^ iter_kv_map\n\n    let hash_map: HashMap<u32, u32> = HashMap::new();\n    hash_map.into_iter().flat_map(|(_, v)| Some(v));\n    //~^ iter_kv_map\n\n    let hash_map: HashMap<u32, u32> = HashMap::new();\n    hash_map.into_iter().filter_map(|(k, _)| (k > 0).then_some(1));\n    //~^ iter_kv_map\n\n    let hash_map: HashMap<u32, u32> = HashMap::new();\n    hash_map.into_iter().filter_map(|(_, v)| (v > 0).then_some(1));\n    //~^ iter_kv_map\n}\n"
  },
  {
    "path": "tests/ui/iter_kv_map.stderr",
    "content": "error: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:20:13\n   |\nLL |     let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`\n   |\n   = note: `-D clippy::iter-kv-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_kv_map)]`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:22:13\n   |\nLL |     let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:24:13\n   |\nLL |     let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:27:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:29:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:32:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:34:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:37:13\n   |\nLL |     let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:39:13\n   |\nLL |     let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:54:13\n   |\nLL |     let _ = map.iter().map(|(key, _value)| key * 9).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:56:13\n   |\nLL |     let _ = map.iter().map(|(_key, value)| value * 17).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:60:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:64:13\n   |\nLL |       let _ = map\n   |  _____________^\nLL | |\nLL | |         .clone()\nLL | |         .into_iter()\n...  |\nLL | |             val\nLL | |         })\n   | |__________^\n   |\nhelp: try\n   |\nLL ~     let _ = map\nLL +\nLL +         .clone().into_values().map(|mut val| {\nLL +             val += 2;\nLL +             val\nLL +         })\n   |\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:75:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, mut val)| val).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:80:13\n   |\nLL |     let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:82:13\n   |\nLL |     let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:84:13\n   |\nLL |     let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:87:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:89:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:92:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:94:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:97:13\n   |\nLL |     let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:99:13\n   |\nLL |     let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:114:13\n   |\nLL |     let _ = map.iter().map(|(key, _value)| key * 9).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:116:13\n   |\nLL |     let _ = map.iter().map(|(_key, value)| value * 17).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:120:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:124:13\n   |\nLL |       let _ = map\n   |  _____________^\nLL | |\nLL | |         .clone()\nLL | |         .into_iter()\n...  |\nLL | |             val\nLL | |         })\n   | |__________^\n   |\nhelp: try\n   |\nLL ~     let _ = map\nLL +\nLL +         .clone().into_values().map(|mut val| {\nLL +             val += 2;\nLL +             val\nLL +         })\n   |\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:135:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, mut val)| val).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:151:13\n   |\nLL |     let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:154:13\n   |\nLL |     let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:157:13\n   |\nLL |     let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:166:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:169:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:172:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:175:13\n   |\nLL |     let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:178:13\n   |\nLL |     let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:181:13\n   |\nLL |     let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:184:13\n   |\nLL |     let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:199:13\n   |\nLL |     let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::<Vec<_>>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.as_ref().values()`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:205:13\n   |\nLL |     let _ = hm.iter().map(|(key, _)| vec![key]);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hm.keys().map(|key| vec![key])`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:211:5\n   |\nLL |     hash_map.iter().flat_map(|(k, _)| Some(*k));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.keys().flat_map(|k| Some(*k))`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:214:5\n   |\nLL |     hash_map.iter().flat_map(|(_, v)| Some(*v));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.values().flat_map(|v| Some(*v))`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:217:5\n   |\nLL |     hash_map.iter().filter_map(|(k, _)| (k > &0).then_some(1));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.keys().filter_map(|k| (k > &0).then_some(1))`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:220:5\n   |\nLL |     hash_map.iter().filter_map(|(_, v)| (v > &0).then_some(1));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.values().filter_map(|v| (v > &0).then_some(1))`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:223:5\n   |\nLL |     hash_map.into_iter().flat_map(|(k, _)| Some(k));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.into_keys().flat_map(|k| Some(k))`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:227:5\n   |\nLL |     hash_map.into_iter().flat_map(|(_, v)| Some(v));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.into_values().flat_map(|v| Some(v))`\n\nerror: iterating on a map's keys\n  --> tests/ui/iter_kv_map.rs:231:5\n   |\nLL |     hash_map.into_iter().filter_map(|(k, _)| (k > 0).then_some(1));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.into_keys().filter_map(|k| (k > 0).then_some(1))`\n\nerror: iterating on a map's values\n  --> tests/ui/iter_kv_map.rs:235:5\n   |\nLL |     hash_map.into_iter().filter_map(|(_, v)| (v > 0).then_some(1));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_map.into_values().filter_map(|v| (v > 0).then_some(1))`\n\nerror: aborting due to 48 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_next_loop.rs",
    "content": "#![allow(dead_code, unused, for_loops_over_fallibles)]\n#![warn(clippy::iter_next_loop)]\n\nfn main() {\n    let x = [1, 2, 3, 4];\n    for _ in x.iter().next() {}\n    //~^ iter_next_loop\n\n    struct Unrelated(&'static [u8]);\n    impl Unrelated {\n        fn next(&self) -> std::slice::Iter<'_, u8> {\n            self.0.iter()\n        }\n    }\n    let u = Unrelated(&[0]);\n    for _v in u.next() {} // no error\n}\n\nfn issue14630() {\n    macro_rules! mac {\n        (next $e:expr) => {\n            $e.iter().next()\n        };\n    }\n\n    for _ in dbg!([1, 2].iter()).next() {}\n    //~^ iter_next_loop\n\n    for _ in mac!(next [1, 2]) {}\n}\n"
  },
  {
    "path": "tests/ui/iter_next_loop.stderr",
    "content": "error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want\n  --> tests/ui/iter_next_loop.rs:6:14\n   |\nLL |     for _ in x.iter().next() {}\n   |              ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::iter-next-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_next_loop)]`\n\nerror: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want\n  --> tests/ui/iter_next_loop.rs:26:14\n   |\nLL |     for _ in dbg!([1, 2].iter()).next() {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_next_slice.fixed",
    "content": "#![warn(clippy::iter_next_slice)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    // test code goes here\n    let s = [1, 2, 3];\n    let v = vec![1, 2, 3];\n\n    let _ = s.first();\n    //~^ iter_next_slice\n    // Should be replaced by s.first()\n\n    let _ = s.get(2);\n    //~^ iter_next_slice\n    // Should be replaced by s.get(2)\n\n    let _ = v.get(5);\n    //~^ iter_next_slice\n    // Should be replaced by v.get(5)\n\n    let _ = v.first();\n    //~^ iter_next_slice\n    // Should be replaced by v.first()\n\n    let o = Some(5);\n    o.iter().next();\n    // Shouldn't be linted since this is not a Slice or an Array\n}\n"
  },
  {
    "path": "tests/ui/iter_next_slice.rs",
    "content": "#![warn(clippy::iter_next_slice)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    // test code goes here\n    let s = [1, 2, 3];\n    let v = vec![1, 2, 3];\n\n    let _ = s.iter().next();\n    //~^ iter_next_slice\n    // Should be replaced by s.first()\n\n    let _ = s[2..].iter().next();\n    //~^ iter_next_slice\n    // Should be replaced by s.get(2)\n\n    let _ = v[5..].iter().next();\n    //~^ iter_next_slice\n    // Should be replaced by v.get(5)\n\n    let _ = v.iter().next();\n    //~^ iter_next_slice\n    // Should be replaced by v.first()\n\n    let o = Some(5);\n    o.iter().next();\n    // Shouldn't be linted since this is not a Slice or an Array\n}\n"
  },
  {
    "path": "tests/ui/iter_next_slice.stderr",
    "content": "error: using `.iter().next()` on an array\n  --> tests/ui/iter_next_slice.rs:9:13\n   |\nLL |     let _ = s.iter().next();\n   |             ^^^^^^^^^^^^^^^ help: try calling: `s.first()`\n   |\n   = note: `-D clippy::iter-next-slice` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_next_slice)]`\n\nerror: using `.iter().next()` on a Slice without end index\n  --> tests/ui/iter_next_slice.rs:13:13\n   |\nLL |     let _ = s[2..].iter().next();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: try calling: `s.get(2)`\n\nerror: using `.iter().next()` on a Slice without end index\n  --> tests/ui/iter_next_slice.rs:17:13\n   |\nLL |     let _ = v[5..].iter().next();\n   |             ^^^^^^^^^^^^^^^^^^^^ help: try calling: `v.get(5)`\n\nerror: using `.iter().next()` on an array\n  --> tests/ui/iter_next_slice.rs:21:13\n   |\nLL |     let _ = v.iter().next();\n   |             ^^^^^^^^^^^^^^^ help: try calling: `v.first()`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_not_returning_iterator.rs",
    "content": "#![warn(clippy::iter_not_returning_iterator)]\n\nstruct Data {\n    begin: u32,\n}\n\nstruct Counter {\n    count: u32,\n}\n\nimpl Data {\n    fn iter(&self) -> Counter {\n        todo!()\n    }\n\n    fn iter_mut(&self) -> Counter {\n        todo!()\n    }\n}\n\nstruct Data2 {\n    begin: u32,\n}\n\nstruct Counter2 {\n    count: u32,\n}\n\nimpl Data2 {\n    fn iter(&self) -> Counter2 {\n        //~^ iter_not_returning_iterator\n\n        todo!()\n    }\n\n    fn iter_mut(&self) -> Counter2 {\n        //~^ iter_not_returning_iterator\n\n        todo!()\n    }\n}\n\nimpl Iterator for Counter {\n    type Item = u32;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        todo!()\n    }\n}\n\n// Issue #8225\ntrait Iter {\n    type I;\n    fn iter(&self) -> Self::I;\n    //~^ iter_not_returning_iterator\n}\n\nimpl Iter for () {\n    type I = core::slice::Iter<'static, ()>;\n    fn iter(&self) -> Self::I {\n        [].iter()\n    }\n}\n\nstruct S;\nimpl S {\n    fn iter(&self) -> <() as Iter>::I {\n        ().iter()\n    }\n}\n\nstruct S2([u8]);\nimpl S2 {\n    fn iter(&self) -> core::slice::Iter<'_, u8> {\n        self.0.iter()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/iter_not_returning_iterator.stderr",
    "content": "error: this method is named `iter` but its return type does not implement `Iterator`\n  --> tests/ui/iter_not_returning_iterator.rs:30:5\n   |\nLL |     fn iter(&self) -> Counter2 {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::iter-not-returning-iterator` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_not_returning_iterator)]`\n\nerror: this method is named `iter_mut` but its return type does not implement `Iterator`\n  --> tests/ui/iter_not_returning_iterator.rs:36:5\n   |\nLL |     fn iter_mut(&self) -> Counter2 {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this method is named `iter` but its return type does not implement `Iterator`\n  --> tests/ui/iter_not_returning_iterator.rs:54:5\n   |\nLL |     fn iter(&self) -> Self::I;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_nth.fixed",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::iter_nth)]\n#![allow(clippy::useless_vec)]\n\n#[macro_use]\nextern crate option_helpers;\n\nuse option_helpers::IteratorFalsePositives;\nuse std::collections::VecDeque;\n\n/// Struct to generate false positives for things with `.iter()`.\n#[derive(Copy, Clone)]\nstruct HasIter;\n\nimpl HasIter {\n    fn iter(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n\n    fn iter_mut(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n}\n\n/// Checks implementation of `ITER_NTH` lint.\nfn iter_nth() {\n    let mut some_vec = vec![0, 1, 2, 3];\n    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect();\n\n    {\n        // Make sure we lint `.iter()` for relevant types.\n        let bad_vec = some_vec.get(3);\n        //~^ iter_nth\n        let bad_slice = &some_vec[..].get(3);\n        //~^ iter_nth\n        let bad_boxed_slice = boxed_slice.get(3);\n        //~^ iter_nth\n        let bad_vec_deque = some_vec_deque.get(3);\n        //~^ iter_nth\n    }\n\n    {\n        // Make sure we lint `.iter_mut()` for relevant types.\n        let bad_vec = some_vec.get_mut(3);\n        //~^ iter_nth\n    }\n    {\n        let bad_slice = &some_vec[..].get_mut(3);\n        //~^ iter_nth\n    }\n    {\n        let bad_vec_deque = some_vec_deque.get_mut(3);\n        //~^ iter_nth\n    }\n\n    let vec_ref = &Vec::<String>::new();\n    vec_ref.get(3);\n    //~^ iter_nth\n\n    // Make sure we don't lint for non-relevant types.\n    let false_positive = HasIter;\n    let ok = false_positive.iter().nth(3);\n    let ok_mut = false_positive.iter_mut().nth(3);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/iter_nth.rs",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::iter_nth)]\n#![allow(clippy::useless_vec)]\n\n#[macro_use]\nextern crate option_helpers;\n\nuse option_helpers::IteratorFalsePositives;\nuse std::collections::VecDeque;\n\n/// Struct to generate false positives for things with `.iter()`.\n#[derive(Copy, Clone)]\nstruct HasIter;\n\nimpl HasIter {\n    fn iter(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n\n    fn iter_mut(self) -> IteratorFalsePositives {\n        IteratorFalsePositives { foo: 0 }\n    }\n}\n\n/// Checks implementation of `ITER_NTH` lint.\nfn iter_nth() {\n    let mut some_vec = vec![0, 1, 2, 3];\n    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect();\n\n    {\n        // Make sure we lint `.iter()` for relevant types.\n        let bad_vec = some_vec.iter().nth(3);\n        //~^ iter_nth\n        let bad_slice = &some_vec[..].iter().nth(3);\n        //~^ iter_nth\n        let bad_boxed_slice = boxed_slice.iter().nth(3);\n        //~^ iter_nth\n        let bad_vec_deque = some_vec_deque.iter().nth(3);\n        //~^ iter_nth\n    }\n\n    {\n        // Make sure we lint `.iter_mut()` for relevant types.\n        let bad_vec = some_vec.iter_mut().nth(3);\n        //~^ iter_nth\n    }\n    {\n        let bad_slice = &some_vec[..].iter_mut().nth(3);\n        //~^ iter_nth\n    }\n    {\n        let bad_vec_deque = some_vec_deque.iter_mut().nth(3);\n        //~^ iter_nth\n    }\n\n    let vec_ref = &Vec::<String>::new();\n    vec_ref.iter().nth(3);\n    //~^ iter_nth\n\n    // Make sure we don't lint for non-relevant types.\n    let false_positive = HasIter;\n    let ok = false_positive.iter().nth(3);\n    let ok_mut = false_positive.iter_mut().nth(3);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/iter_nth.stderr",
    "content": "error: called `.iter().nth()` on a `Vec`\n  --> tests/ui/iter_nth.rs:34:23\n   |\nLL |         let bad_vec = some_vec.iter().nth(3);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::iter-nth` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_nth)]`\nhelp: `get` is equivalent but more concise\n   |\nLL -         let bad_vec = some_vec.iter().nth(3);\nLL +         let bad_vec = some_vec.get(3);\n   |\n\nerror: called `.iter().nth()` on a slice\n  --> tests/ui/iter_nth.rs:36:26\n   |\nLL |         let bad_slice = &some_vec[..].iter().nth(3);\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: `get` is equivalent but more concise\n   |\nLL -         let bad_slice = &some_vec[..].iter().nth(3);\nLL +         let bad_slice = &some_vec[..].get(3);\n   |\n\nerror: called `.iter().nth()` on a slice\n  --> tests/ui/iter_nth.rs:38:31\n   |\nLL |         let bad_boxed_slice = boxed_slice.iter().nth(3);\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: `get` is equivalent but more concise\n   |\nLL -         let bad_boxed_slice = boxed_slice.iter().nth(3);\nLL +         let bad_boxed_slice = boxed_slice.get(3);\n   |\n\nerror: called `.iter().nth()` on a `VecDeque`\n  --> tests/ui/iter_nth.rs:40:29\n   |\nLL |         let bad_vec_deque = some_vec_deque.iter().nth(3);\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: `get` is equivalent but more concise\n   |\nLL -         let bad_vec_deque = some_vec_deque.iter().nth(3);\nLL +         let bad_vec_deque = some_vec_deque.get(3);\n   |\n\nerror: called `.iter_mut().nth()` on a `Vec`\n  --> tests/ui/iter_nth.rs:46:23\n   |\nLL |         let bad_vec = some_vec.iter_mut().nth(3);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: `get_mut` is equivalent but more concise\n   |\nLL -         let bad_vec = some_vec.iter_mut().nth(3);\nLL +         let bad_vec = some_vec.get_mut(3);\n   |\n\nerror: called `.iter_mut().nth()` on a slice\n  --> tests/ui/iter_nth.rs:50:26\n   |\nLL |         let bad_slice = &some_vec[..].iter_mut().nth(3);\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: `get_mut` is equivalent but more concise\n   |\nLL -         let bad_slice = &some_vec[..].iter_mut().nth(3);\nLL +         let bad_slice = &some_vec[..].get_mut(3);\n   |\n\nerror: called `.iter_mut().nth()` on a `VecDeque`\n  --> tests/ui/iter_nth.rs:54:29\n   |\nLL |         let bad_vec_deque = some_vec_deque.iter_mut().nth(3);\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: `get_mut` is equivalent but more concise\n   |\nLL -         let bad_vec_deque = some_vec_deque.iter_mut().nth(3);\nLL +         let bad_vec_deque = some_vec_deque.get_mut(3);\n   |\n\nerror: called `.iter().nth()` on a `Vec`\n  --> tests/ui/iter_nth.rs:59:5\n   |\nLL |     vec_ref.iter().nth(3);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: `get` is equivalent but more concise\n   |\nLL -     vec_ref.iter().nth(3);\nLL +     vec_ref.get(3);\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_nth_zero.fixed",
    "content": "#![warn(clippy::iter_nth_zero)]\nuse std::collections::HashSet;\n\nstruct Foo;\n\nimpl Foo {\n    fn nth(&self, index: usize) -> usize {\n        index + 1\n    }\n}\n\nfn main() {\n    let f = Foo {};\n    f.nth(0); // lint does not apply here\n\n    let mut s = HashSet::new();\n    s.insert(1);\n    let _x = s.iter().next();\n    //~^ iter_nth_zero\n\n    let mut s2 = HashSet::new();\n    s2.insert(2);\n    let mut iter = s2.iter();\n    let _y = iter.next();\n    //~^ iter_nth_zero\n\n    let mut s3 = HashSet::new();\n    s3.insert(3);\n    let mut iter2 = s3.iter();\n    let _unwrapped = iter2.next().unwrap();\n    //~^ iter_nth_zero\n}\n\nstruct Issue9820;\n\nimpl Iterator for Issue9820 {\n    type Item = ();\n\n    fn nth(&mut self, _n: usize) -> Option<Self::Item> {\n        todo!()\n    }\n\n    // Don't lint in implementations of `next`, as calling `next` in `next` is incorrect\n    fn next(&mut self) -> Option<Self::Item> {\n        self.nth(0)\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_nth_zero.rs",
    "content": "#![warn(clippy::iter_nth_zero)]\nuse std::collections::HashSet;\n\nstruct Foo;\n\nimpl Foo {\n    fn nth(&self, index: usize) -> usize {\n        index + 1\n    }\n}\n\nfn main() {\n    let f = Foo {};\n    f.nth(0); // lint does not apply here\n\n    let mut s = HashSet::new();\n    s.insert(1);\n    let _x = s.iter().nth(0);\n    //~^ iter_nth_zero\n\n    let mut s2 = HashSet::new();\n    s2.insert(2);\n    let mut iter = s2.iter();\n    let _y = iter.nth(0);\n    //~^ iter_nth_zero\n\n    let mut s3 = HashSet::new();\n    s3.insert(3);\n    let mut iter2 = s3.iter();\n    let _unwrapped = iter2.nth(0).unwrap();\n    //~^ iter_nth_zero\n}\n\nstruct Issue9820;\n\nimpl Iterator for Issue9820 {\n    type Item = ();\n\n    fn nth(&mut self, _n: usize) -> Option<Self::Item> {\n        todo!()\n    }\n\n    // Don't lint in implementations of `next`, as calling `next` in `next` is incorrect\n    fn next(&mut self) -> Option<Self::Item> {\n        self.nth(0)\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_nth_zero.stderr",
    "content": "error: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent\n  --> tests/ui/iter_nth_zero.rs:18:14\n   |\nLL |     let _x = s.iter().nth(0);\n   |              ^^^^^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `s.iter().next()`\n   |\n   = note: `-D clippy::iter-nth-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_nth_zero)]`\n\nerror: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent\n  --> tests/ui/iter_nth_zero.rs:24:14\n   |\nLL |     let _y = iter.nth(0);\n   |              ^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter.next()`\n\nerror: called `.nth(0)` on a `std::iter::Iterator`, when `.next()` is equivalent\n  --> tests/ui/iter_nth_zero.rs:30:22\n   |\nLL |     let _unwrapped = iter2.nth(0).unwrap();\n   |                      ^^^^^^^^^^^^ help: try calling `.next()` instead of `.nth(0)`: `iter2.next()`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_on_empty_collections.fixed",
    "content": "#![warn(clippy::iter_on_empty_collections)]\n#![allow(clippy::iter_next_slice, clippy::redundant_clone)]\n\nfn array() {\n    assert_eq!(std::iter::empty().next(), Option::<i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!(std::iter::empty().next(), Option::<&i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!(std::iter::empty().next(), Option::<i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!(std::iter::empty().next(), Option::<&mut i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!(std::iter::empty().next(), Option::<&i32>::None);\n    //~^ iter_on_empty_collections\n\n    // Don't trigger on non-iter methods\n    let _: Option<String> = None.clone();\n    let _: [String; 0] = [].clone();\n\n    // Don't trigger on match or if branches\n    let _ = match 123 {\n        123 => [].iter(),\n        _ => [\"test\"].iter(),\n    };\n\n    let _ = if false { [\"test\"].iter() } else { [].iter() };\n\n    let smth = Some(vec![1, 2, 3]);\n\n    // Don't trigger when the empty collection iter is relied upon for its concrete type\n    // But do trigger if it is just an iterator, despite being an argument to a method\n    for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain(std::iter::empty()) {\n        //~^ iter_on_empty_collections\n        println!(\"{i}\");\n    }\n\n    // Same as above, but for empty collection iters with extra layers\n    for i in smth.as_ref().map_or({ [].iter() }, |s| s.iter()) {\n        println!(\"{y}\", y = i + 1);\n    }\n\n    // Same as above, but for regular function calls\n    for i in Option::map_or(smth.as_ref(), [].iter(), |s| s.iter()) {\n        println!(\"{i}\");\n    }\n\n    // Same as above, but when there are no predicates that mention the collection iter type.\n    let mut iter = [34, 228, 35].iter();\n    let _ = std::mem::replace(&mut iter, [].iter());\n}\n\nmacro_rules! in_macros {\n    () => {\n        assert_eq!([].into_iter().next(), Option::<i32>::None);\n        assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);\n        assert_eq!([].iter().next(), Option::<&i32>::None);\n        assert_eq!(None.into_iter().next(), Option::<i32>::None);\n        assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);\n        assert_eq!(None.iter().next(), Option::<&i32>::None);\n    };\n}\n\n// Don't trigger on a `None` that isn't std's option\nmod custom_option {\n    #[allow(unused)]\n    enum CustomOption {\n        Some(i32),\n        None,\n    }\n\n    impl CustomOption {\n        fn iter(&self) {}\n        fn iter_mut(&mut self) {}\n        fn into_iter(self) {}\n    }\n    use CustomOption::*;\n\n    pub fn custom_option() {\n        None.iter();\n        None.iter_mut();\n        None.into_iter();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/iter_on_empty_collections.rs",
    "content": "#![warn(clippy::iter_on_empty_collections)]\n#![allow(clippy::iter_next_slice, clippy::redundant_clone)]\n\nfn array() {\n    assert_eq!([].into_iter().next(), Option::<i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!([].iter().next(), Option::<&i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!(None.into_iter().next(), Option::<i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);\n    //~^ iter_on_empty_collections\n    assert_eq!(None.iter().next(), Option::<&i32>::None);\n    //~^ iter_on_empty_collections\n\n    // Don't trigger on non-iter methods\n    let _: Option<String> = None.clone();\n    let _: [String; 0] = [].clone();\n\n    // Don't trigger on match or if branches\n    let _ = match 123 {\n        123 => [].iter(),\n        _ => [\"test\"].iter(),\n    };\n\n    let _ = if false { [\"test\"].iter() } else { [].iter() };\n\n    let smth = Some(vec![1, 2, 3]);\n\n    // Don't trigger when the empty collection iter is relied upon for its concrete type\n    // But do trigger if it is just an iterator, despite being an argument to a method\n    for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) {\n        //~^ iter_on_empty_collections\n        println!(\"{i}\");\n    }\n\n    // Same as above, but for empty collection iters with extra layers\n    for i in smth.as_ref().map_or({ [].iter() }, |s| s.iter()) {\n        println!(\"{y}\", y = i + 1);\n    }\n\n    // Same as above, but for regular function calls\n    for i in Option::map_or(smth.as_ref(), [].iter(), |s| s.iter()) {\n        println!(\"{i}\");\n    }\n\n    // Same as above, but when there are no predicates that mention the collection iter type.\n    let mut iter = [34, 228, 35].iter();\n    let _ = std::mem::replace(&mut iter, [].iter());\n}\n\nmacro_rules! in_macros {\n    () => {\n        assert_eq!([].into_iter().next(), Option::<i32>::None);\n        assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);\n        assert_eq!([].iter().next(), Option::<&i32>::None);\n        assert_eq!(None.into_iter().next(), Option::<i32>::None);\n        assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);\n        assert_eq!(None.iter().next(), Option::<&i32>::None);\n    };\n}\n\n// Don't trigger on a `None` that isn't std's option\nmod custom_option {\n    #[allow(unused)]\n    enum CustomOption {\n        Some(i32),\n        None,\n    }\n\n    impl CustomOption {\n        fn iter(&self) {}\n        fn iter_mut(&mut self) {}\n        fn into_iter(self) {}\n    }\n    use CustomOption::*;\n\n    pub fn custom_option() {\n        None.iter();\n        None.iter_mut();\n        None.into_iter();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/iter_on_empty_collections.stderr",
    "content": "error: `into_iter` call on an empty collection\n  --> tests/ui/iter_on_empty_collections.rs:5:16\n   |\nLL |     assert_eq!([].into_iter().next(), Option::<i32>::None);\n   |                ^^^^^^^^^^^^^^ help: try: `std::iter::empty()`\n   |\n   = note: `-D clippy::iter-on-empty-collections` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_on_empty_collections)]`\n\nerror: `iter_mut` call on an empty collection\n  --> tests/ui/iter_on_empty_collections.rs:7:16\n   |\nLL |     assert_eq!([].iter_mut().next(), Option::<&mut i32>::None);\n   |                ^^^^^^^^^^^^^ help: try: `std::iter::empty()`\n\nerror: `iter` call on an empty collection\n  --> tests/ui/iter_on_empty_collections.rs:9:16\n   |\nLL |     assert_eq!([].iter().next(), Option::<&i32>::None);\n   |                ^^^^^^^^^ help: try: `std::iter::empty()`\n\nerror: `into_iter` call on an empty collection\n  --> tests/ui/iter_on_empty_collections.rs:11:16\n   |\nLL |     assert_eq!(None.into_iter().next(), Option::<i32>::None);\n   |                ^^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`\n\nerror: `iter_mut` call on an empty collection\n  --> tests/ui/iter_on_empty_collections.rs:13:16\n   |\nLL |     assert_eq!(None.iter_mut().next(), Option::<&mut i32>::None);\n   |                ^^^^^^^^^^^^^^^ help: try: `std::iter::empty()`\n\nerror: `iter` call on an empty collection\n  --> tests/ui/iter_on_empty_collections.rs:15:16\n   |\nLL |     assert_eq!(None.iter().next(), Option::<&i32>::None);\n   |                ^^^^^^^^^^^ help: try: `std::iter::empty()`\n\nerror: `iter` call on an empty collection\n  --> tests/ui/iter_on_empty_collections.rs:34:66\n   |\nLL |     for i in smth.as_ref().map_or([].iter(), |s| s.iter()).chain([].iter()) {\n   |                                                                  ^^^^^^^^^ help: try: `std::iter::empty()`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_on_single_items.fixed",
    "content": "#![warn(clippy::iter_on_single_items)]\n#![allow(clippy::iter_next_slice, clippy::redundant_clone)]\n\nfn array() {\n    assert_eq!(std::iter::once(123).next(), Some(123));\n    //~^ iter_on_single_items\n    assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123));\n    //~^ iter_on_single_items\n    assert_eq!(std::iter::once(&123).next(), Some(&123));\n    //~^ iter_on_single_items\n    assert_eq!(std::iter::once(123).next(), Some(123));\n    //~^ iter_on_single_items\n    assert_eq!(std::iter::once(&mut 123).next(), Some(&mut 123));\n    //~^ iter_on_single_items\n    assert_eq!(std::iter::once(&123).next(), Some(&123));\n    //~^ iter_on_single_items\n\n    // Don't trigger on non-iter methods\n    let _: Option<String> = Some(\"test\".to_string()).clone();\n    let _: [String; 1] = [\"test\".to_string()].clone();\n\n    // Don't trigger on match or if branches\n    let _ = match 123 {\n        123 => [].iter(),\n        _ => [\"test\"].iter(),\n    };\n\n    let _ = if false { [\"test\"].iter() } else { [].iter() };\n}\n\nmacro_rules! in_macros {\n    () => {\n        assert_eq!([123].into_iter().next(), Some(123));\n        assert_eq!([123].iter_mut().next(), Some(&mut 123));\n        assert_eq!([123].iter().next(), Some(&123));\n        assert_eq!(Some(123).into_iter().next(), Some(123));\n        assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));\n        assert_eq!(Some(123).iter().next(), Some(&123));\n    };\n}\n\n// Don't trigger on a `Some` that isn't std's option\nmod custom_option {\n    #[allow(unused)]\n    enum CustomOption {\n        Some(i32),\n        None,\n    }\n\n    impl CustomOption {\n        fn iter(&self) {}\n        fn iter_mut(&mut self) {}\n        fn into_iter(self) {}\n    }\n    use CustomOption::*;\n\n    pub fn custom_option() {\n        Some(3).iter();\n        Some(3).iter_mut();\n        Some(3).into_iter();\n    }\n}\n\nfn main() {}\n\nmod issue14981 {\n    use std::option::IntoIter;\n    fn takes_into_iter(_: impl IntoIterator<Item = i32>) {}\n\n    fn let_stmt() {\n        macro_rules! x {\n            ($e:expr) => {\n                let _: IntoIter<i32> = $e;\n            };\n        }\n        x!(Some(5).into_iter());\n    }\n\n    fn fn_ptr() {\n        fn some_func(_: IntoIter<i32>) -> IntoIter<i32> {\n            todo!()\n        }\n        some_func(Some(5).into_iter());\n\n        const C: fn(IntoIter<i32>) -> IntoIter<i32> = <IntoIter<i32> as IntoIterator>::into_iter;\n        C(Some(5).into_iter());\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_on_single_items.rs",
    "content": "#![warn(clippy::iter_on_single_items)]\n#![allow(clippy::iter_next_slice, clippy::redundant_clone)]\n\nfn array() {\n    assert_eq!([123].into_iter().next(), Some(123));\n    //~^ iter_on_single_items\n    assert_eq!([123].iter_mut().next(), Some(&mut 123));\n    //~^ iter_on_single_items\n    assert_eq!([123].iter().next(), Some(&123));\n    //~^ iter_on_single_items\n    assert_eq!(Some(123).into_iter().next(), Some(123));\n    //~^ iter_on_single_items\n    assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));\n    //~^ iter_on_single_items\n    assert_eq!(Some(123).iter().next(), Some(&123));\n    //~^ iter_on_single_items\n\n    // Don't trigger on non-iter methods\n    let _: Option<String> = Some(\"test\".to_string()).clone();\n    let _: [String; 1] = [\"test\".to_string()].clone();\n\n    // Don't trigger on match or if branches\n    let _ = match 123 {\n        123 => [].iter(),\n        _ => [\"test\"].iter(),\n    };\n\n    let _ = if false { [\"test\"].iter() } else { [].iter() };\n}\n\nmacro_rules! in_macros {\n    () => {\n        assert_eq!([123].into_iter().next(), Some(123));\n        assert_eq!([123].iter_mut().next(), Some(&mut 123));\n        assert_eq!([123].iter().next(), Some(&123));\n        assert_eq!(Some(123).into_iter().next(), Some(123));\n        assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));\n        assert_eq!(Some(123).iter().next(), Some(&123));\n    };\n}\n\n// Don't trigger on a `Some` that isn't std's option\nmod custom_option {\n    #[allow(unused)]\n    enum CustomOption {\n        Some(i32),\n        None,\n    }\n\n    impl CustomOption {\n        fn iter(&self) {}\n        fn iter_mut(&mut self) {}\n        fn into_iter(self) {}\n    }\n    use CustomOption::*;\n\n    pub fn custom_option() {\n        Some(3).iter();\n        Some(3).iter_mut();\n        Some(3).into_iter();\n    }\n}\n\nfn main() {}\n\nmod issue14981 {\n    use std::option::IntoIter;\n    fn takes_into_iter(_: impl IntoIterator<Item = i32>) {}\n\n    fn let_stmt() {\n        macro_rules! x {\n            ($e:expr) => {\n                let _: IntoIter<i32> = $e;\n            };\n        }\n        x!(Some(5).into_iter());\n    }\n\n    fn fn_ptr() {\n        fn some_func(_: IntoIter<i32>) -> IntoIter<i32> {\n            todo!()\n        }\n        some_func(Some(5).into_iter());\n\n        const C: fn(IntoIter<i32>) -> IntoIter<i32> = <IntoIter<i32> as IntoIterator>::into_iter;\n        C(Some(5).into_iter());\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_on_single_items.stderr",
    "content": "error: `into_iter` call on a collection with only one item\n  --> tests/ui/iter_on_single_items.rs:5:16\n   |\nLL |     assert_eq!([123].into_iter().next(), Some(123));\n   |                ^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`\n   |\n   = note: `-D clippy::iter-on-single-items` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_on_single_items)]`\n\nerror: `iter_mut` call on a collection with only one item\n  --> tests/ui/iter_on_single_items.rs:7:16\n   |\nLL |     assert_eq!([123].iter_mut().next(), Some(&mut 123));\n   |                ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`\n\nerror: `iter` call on a collection with only one item\n  --> tests/ui/iter_on_single_items.rs:9:16\n   |\nLL |     assert_eq!([123].iter().next(), Some(&123));\n   |                ^^^^^^^^^^^^ help: try: `std::iter::once(&123)`\n\nerror: `into_iter` call on a collection with only one item\n  --> tests/ui/iter_on_single_items.rs:11:16\n   |\nLL |     assert_eq!(Some(123).into_iter().next(), Some(123));\n   |                ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(123)`\n\nerror: `iter_mut` call on a collection with only one item\n  --> tests/ui/iter_on_single_items.rs:13:16\n   |\nLL |     assert_eq!(Some(123).iter_mut().next(), Some(&mut 123));\n   |                ^^^^^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&mut 123)`\n\nerror: `iter` call on a collection with only one item\n  --> tests/ui/iter_on_single_items.rs:15:16\n   |\nLL |     assert_eq!(Some(123).iter().next(), Some(&123));\n   |                ^^^^^^^^^^^^^^^^ help: try: `std::iter::once(&123)`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_out_of_bounds.rs",
    "content": "#![deny(clippy::iter_out_of_bounds)]\n#![allow(clippy::useless_vec)]\n\nfn opaque_empty_iter() -> impl Iterator<Item = ()> {\n    std::iter::empty()\n}\n\nfn main() {\n    #[allow(clippy::never_loop)]\n    for _ in [1, 2, 3].iter().skip(4) {\n        //~^ iter_out_of_bounds\n\n        unreachable!();\n    }\n    for (i, _) in [1, 2, 3].iter().take(4).enumerate() {\n        //~^ iter_out_of_bounds\n\n        assert!(i <= 2);\n    }\n\n    #[allow(clippy::needless_borrow)]\n    for _ in (&&&&&&[1, 2, 3]).iter().take(4) {}\n    //~^ iter_out_of_bounds\n\n    for _ in [1, 2, 3].iter().skip(4) {}\n    //~^ iter_out_of_bounds\n\n    for _ in [1; 3].iter().skip(4) {}\n    //~^ iter_out_of_bounds\n\n    // Should not lint\n    for _ in opaque_empty_iter().skip(1) {}\n\n    for _ in vec![1, 2, 3].iter().skip(4) {}\n    //~^ iter_out_of_bounds\n\n    for _ in vec![1; 3].iter().skip(4) {}\n    //~^ iter_out_of_bounds\n\n    let x = [1, 2, 3];\n    for _ in x.iter().skip(4) {}\n    //~^ iter_out_of_bounds\n\n    let n = 4;\n    for _ in x.iter().skip(n) {}\n    //~^ iter_out_of_bounds\n\n    let empty = std::iter::empty::<i8>;\n\n    for _ in empty().skip(1) {}\n    //~^ iter_out_of_bounds\n\n    for _ in empty().take(1) {}\n    //~^ iter_out_of_bounds\n\n    for _ in std::iter::once(1).skip(2) {}\n    //~^ iter_out_of_bounds\n\n    for _ in std::iter::once(1).take(2) {}\n    //~^ iter_out_of_bounds\n\n    for x in [].iter().take(1) {\n        //~^ iter_out_of_bounds\n\n        let _: &i32 = x;\n    }\n\n    // ok, not out of bounds\n    for _ in [1].iter().take(1) {}\n    for _ in [1, 2, 3].iter().take(2) {}\n    for _ in [1, 2, 3].iter().skip(2) {}\n}\n"
  },
  {
    "path": "tests/ui/iter_out_of_bounds.stderr",
    "content": "error: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:10:14\n   |\nLL |     for _ in [1, 2, 3].iter().skip(4) {\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\nnote: the lint level is defined here\n  --> tests/ui/iter_out_of_bounds.rs:1:9\n   |\nLL | #![deny(clippy::iter_out_of_bounds)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `.take()` call takes more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:15:19\n   |\nLL |     for (i, _) in [1, 2, 3].iter().take(4).enumerate() {\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and the returned iterator will simply yield the same items\n\nerror: this `.take()` call takes more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:22:14\n   |\nLL |     for _ in (&&&&&&[1, 2, 3]).iter().take(4) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and the returned iterator will simply yield the same items\n\nerror: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:25:14\n   |\nLL |     for _ in [1, 2, 3].iter().skip(4) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\n\nerror: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:28:14\n   |\nLL |     for _ in [1; 3].iter().skip(4) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\n\nerror: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:34:14\n   |\nLL |     for _ in vec![1, 2, 3].iter().skip(4) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\n\nerror: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:37:14\n   |\nLL |     for _ in vec![1; 3].iter().skip(4) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\n\nerror: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:41:14\n   |\nLL |     for _ in x.iter().skip(4) {}\n   |              ^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\n\nerror: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:45:14\n   |\nLL |     for _ in x.iter().skip(n) {}\n   |              ^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\n\nerror: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:50:14\n   |\nLL |     for _ in empty().skip(1) {}\n   |              ^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\n\nerror: this `.take()` call takes more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:53:14\n   |\nLL |     for _ in empty().take(1) {}\n   |              ^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and the returned iterator will simply yield the same items\n\nerror: this `.skip()` call skips more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:56:14\n   |\nLL |     for _ in std::iter::once(1).skip(2) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and will create an empty iterator\n\nerror: this `.take()` call takes more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:59:14\n   |\nLL |     for _ in std::iter::once(1).take(2) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and the returned iterator will simply yield the same items\n\nerror: this `.take()` call takes more items than the iterator will produce\n  --> tests/ui/iter_out_of_bounds.rs:62:14\n   |\nLL |     for x in [].iter().take(1) {\n   |              ^^^^^^^^^^^^^^^^^\n   |\n   = note: this operation is useless and the returned iterator will simply yield the same items\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_over_hash_type.rs",
    "content": "//@aux-build:proc_macros.rs\n#![feature(rustc_private)]\n#![warn(clippy::iter_over_hash_type)]\nuse std::collections::{HashMap, HashSet};\n\nextern crate proc_macros;\n\n// Ensure it also works via type aliases (this isn't really the Fx hasher but that does not matter).\ntype FxBuildHasher = std::collections::hash_map::RandomState;\ntype FxHashMap<K, V> = HashMap<K, V, FxBuildHasher>;\ntype FxHashSet<K> = HashSet<K, FxBuildHasher>;\n\nfn main() {\n    let mut hash_set = HashSet::<i32>::new();\n    let mut hash_map = HashMap::<i32, i32>::new();\n    let mut fx_hash_map = FxHashMap::<i32, i32>::default();\n    let mut fx_hash_set = FxHashSet::<i32>::default();\n    let vec = Vec::<i32>::new();\n\n    // test hashset\n    for x in &hash_set {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n    for x in hash_set.iter() {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n    for x in hash_set.clone() {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n    for x in hash_set.drain() {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n\n    // test hashmap\n    for (x, y) in &hash_map {\n        //~^ iter_over_hash_type\n        let _ = (x, y);\n    }\n    for x in hash_map.keys() {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n    for x in hash_map.values() {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n    for x in hash_map.values_mut() {\n        //~^ iter_over_hash_type\n        *x += 1;\n    }\n    for x in hash_map.iter() {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n    for x in hash_map.clone() {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n    for x in hash_map.drain() {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n\n    // test type-aliased hashers\n    for x in fx_hash_set {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n    for x in fx_hash_map {\n        //~^ iter_over_hash_type\n        let _ = x;\n    }\n\n    // shouldn't fire\n    for x in &vec {\n        let _ = x;\n    }\n    for x in vec {\n        let _ = x;\n    }\n\n    // should not lint, this comes from an external crate\n    proc_macros::external! {\n      for _ in HashMap::<i32, i32>::new() {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_over_hash_type.stderr",
    "content": "error: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:21:5\n   |\nLL | /     for x in &hash_set {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::iter-over-hash-type` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_over_hash_type)]`\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:25:5\n   |\nLL | /     for x in hash_set.iter() {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:29:5\n   |\nLL | /     for x in hash_set.clone() {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:33:5\n   |\nLL | /     for x in hash_set.drain() {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:39:5\n   |\nLL | /     for (x, y) in &hash_map {\nLL | |\nLL | |         let _ = (x, y);\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:43:5\n   |\nLL | /     for x in hash_map.keys() {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:47:5\n   |\nLL | /     for x in hash_map.values() {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:51:5\n   |\nLL | /     for x in hash_map.values_mut() {\nLL | |\nLL | |         *x += 1;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:55:5\n   |\nLL | /     for x in hash_map.iter() {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:59:5\n   |\nLL | /     for x in hash_map.clone() {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:63:5\n   |\nLL | /     for x in hash_map.drain() {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:69:5\n   |\nLL | /     for x in fx_hash_set {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: iteration over unordered hash-based type\n  --> tests/ui/iter_over_hash_type.rs:73:5\n   |\nLL | /     for x in fx_hash_map {\nLL | |\nLL | |         let _ = x;\nLL | |     }\n   | |_____^\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_overeager_cloned.fixed",
    "content": "#![warn(clippy::iter_overeager_cloned, clippy::redundant_iter_cloned, clippy::filter_next)]\n#![allow(\n    dead_code,\n    clippy::let_unit_value,\n    clippy::useless_vec,\n    clippy::double_ended_iterator_last\n)]\n\nfn main() {\n    let vec = vec![\"1\".to_string(), \"2\".to_string(), \"3\".to_string()];\n\n    let _: Option<String> = vec.iter().last().cloned();\n    //~^ iter_overeager_cloned\n\n    let _: Option<String> = vec.iter().chain(vec.iter()).next().cloned();\n    //~^ iter_overeager_cloned\n\n    let _: usize = vec.iter().filter(|x| x == &\"2\").count();\n    //~^ redundant_iter_cloned\n\n    let _: Vec<_> = vec.iter().take(2).cloned().collect();\n    //~^ iter_overeager_cloned\n\n    let _: Vec<_> = vec.iter().skip(2).cloned().collect();\n    //~^ iter_overeager_cloned\n\n    let _ = vec.iter().filter(|x| x == &\"2\").nth(2).cloned();\n    //~^ iter_overeager_cloned\n\n    let _ = [Some(Some(\"str\".to_string())), Some(Some(\"str\".to_string()))]\n        //~^ iter_overeager_cloned\n        .iter()\n        .flatten().cloned();\n\n    let _ = vec.iter().filter(|&x| x.starts_with('2')).cloned();\n    //~^ iter_overeager_cloned\n\n    let _ = vec.iter().find(|&x| x == \"2\").cloned();\n    //~^ iter_overeager_cloned\n\n    {\n        let f = |x: &String| x.starts_with('2');\n        let _ = vec.iter().filter(|&x| f(x)).cloned();\n        //~^ iter_overeager_cloned\n        let _ = vec.iter().find(|&x| f(x)).cloned();\n        //~^ iter_overeager_cloned\n    }\n\n    {\n        let vec: Vec<(String, String)> = vec![];\n        let f = move |x: &(String, String)| x.0.starts_with('2');\n        let _ = vec.iter().filter(|&x| f(x)).cloned();\n        //~^ iter_overeager_cloned\n        let _ = vec.iter().find(|&x| f(x)).cloned();\n        //~^ iter_overeager_cloned\n    }\n\n    fn test_move<'a>(\n        iter: impl Iterator<Item = &'a (&'a u32, String)> + 'a,\n        target: String,\n    ) -> impl Iterator<Item = (&'a u32, String)> + 'a {\n        iter.filter(move |&&(&a, ref b)| a == 1 && b == &target).cloned()\n        //~^ iter_overeager_cloned\n    }\n\n    {\n        #[derive(Clone)]\n        struct S<'a> {\n            a: &'a u32,\n            b: String,\n        }\n\n        fn bar<'a>(iter: impl Iterator<Item = &'a S<'a>> + 'a, target: String) -> impl Iterator<Item = S<'a>> + 'a {\n            iter.filter(move |&S { a, b }| **a == 1 && b == &target).cloned()\n            //~^ iter_overeager_cloned\n        }\n    }\n\n    let _ = vec.iter().map(|x| x.len());\n    //~^ redundant_iter_cloned\n\n    // This would fail if changed.\n    let _ = vec.iter().cloned().map(|x| x + \"2\");\n\n    let _ = vec.iter().for_each(|x| assert!(!x.is_empty()));\n    //~^ redundant_iter_cloned\n\n    let _ = vec.iter().all(|x| x.len() == 1);\n    //~^ redundant_iter_cloned\n\n    let _ = vec.iter().any(|x| x.len() == 1);\n    //~^ redundant_iter_cloned\n\n    // Should probably stay as it is.\n    let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);\n\n    // `&Range<_>` doesn't implement `IntoIterator`\n    let _ = [0..1, 2..5].iter().cloned().flatten();\n}\n\n// #8527\nfn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {\n    x.cloned().flatten()\n}\n\nmod issue_16428 {\n    #[derive(Clone)]\n    struct Foo;\n\n    impl Foo {\n        async fn do_async(&self) {}\n    }\n\n    fn async_move_map() -> Vec<impl std::future::Future<Output = ()>> {\n        let map: std::collections::HashMap<(), Foo> = std::collections::HashMap::new();\n\n        // Should NOT lint: async move block captures `item` by value\n        map.values()\n            .cloned()\n            .map(|item| async move { item.do_async().await })\n            .collect::<Vec<_>>()\n    }\n\n    fn async_move_for_each() {\n        let map: std::collections::HashMap<(), Foo> = std::collections::HashMap::new();\n\n        // Should NOT lint: async move block captures `item` by value\n        map.values()\n            .cloned()\n            .for_each(|item| drop(async move { item.do_async().await }));\n    }\n\n    fn move_closure() {\n        let vec = vec![\"1\".to_string(), \"2\".to_string()];\n\n        // Should NOT lint: move closure captures `x` by value\n        let _: Vec<_> = vec.iter().cloned().map(|x| move || x.len()).collect();\n    }\n\n    fn async_move_not_capturing_param() {\n        let vec = vec![\"1\".to_string(), \"2\".to_string()];\n\n        // Should lint: async move captures `y`, not `x`\n        let _ = vec.iter().map(|x| {\n            //~^ redundant_iter_cloned\n            let y = x.len();\n            async move { y }\n        });\n    }\n\n    fn move_closure_not_capturing_param() {\n        let vec = vec![\"1\".to_string(), \"2\".to_string()];\n\n        // Should lint: move closure captures `y`, not `x`\n        let _: Vec<_> = vec\n            //~^ redundant_iter_cloned\n            .iter()\n            .map(|x| {\n                let y = x.len();\n                move || y\n            })\n            .collect();\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_overeager_cloned.rs",
    "content": "#![warn(clippy::iter_overeager_cloned, clippy::redundant_iter_cloned, clippy::filter_next)]\n#![allow(\n    dead_code,\n    clippy::let_unit_value,\n    clippy::useless_vec,\n    clippy::double_ended_iterator_last\n)]\n\nfn main() {\n    let vec = vec![\"1\".to_string(), \"2\".to_string(), \"3\".to_string()];\n\n    let _: Option<String> = vec.iter().cloned().last();\n    //~^ iter_overeager_cloned\n\n    let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();\n    //~^ iter_overeager_cloned\n\n    let _: usize = vec.iter().filter(|x| x == &\"2\").cloned().count();\n    //~^ redundant_iter_cloned\n\n    let _: Vec<_> = vec.iter().cloned().take(2).collect();\n    //~^ iter_overeager_cloned\n\n    let _: Vec<_> = vec.iter().cloned().skip(2).collect();\n    //~^ iter_overeager_cloned\n\n    let _ = vec.iter().filter(|x| x == &\"2\").cloned().nth(2);\n    //~^ iter_overeager_cloned\n\n    let _ = [Some(Some(\"str\".to_string())), Some(Some(\"str\".to_string()))]\n        //~^ iter_overeager_cloned\n        .iter()\n        .cloned()\n        .flatten();\n\n    let _ = vec.iter().cloned().filter(|x| x.starts_with('2'));\n    //~^ iter_overeager_cloned\n\n    let _ = vec.iter().cloned().find(|x| x == \"2\");\n    //~^ iter_overeager_cloned\n\n    {\n        let f = |x: &String| x.starts_with('2');\n        let _ = vec.iter().cloned().filter(f);\n        //~^ iter_overeager_cloned\n        let _ = vec.iter().cloned().find(f);\n        //~^ iter_overeager_cloned\n    }\n\n    {\n        let vec: Vec<(String, String)> = vec![];\n        let f = move |x: &(String, String)| x.0.starts_with('2');\n        let _ = vec.iter().cloned().filter(f);\n        //~^ iter_overeager_cloned\n        let _ = vec.iter().cloned().find(f);\n        //~^ iter_overeager_cloned\n    }\n\n    fn test_move<'a>(\n        iter: impl Iterator<Item = &'a (&'a u32, String)> + 'a,\n        target: String,\n    ) -> impl Iterator<Item = (&'a u32, String)> + 'a {\n        iter.cloned().filter(move |&(&a, ref b)| a == 1 && b == &target)\n        //~^ iter_overeager_cloned\n    }\n\n    {\n        #[derive(Clone)]\n        struct S<'a> {\n            a: &'a u32,\n            b: String,\n        }\n\n        fn bar<'a>(iter: impl Iterator<Item = &'a S<'a>> + 'a, target: String) -> impl Iterator<Item = S<'a>> + 'a {\n            iter.cloned().filter(move |S { a, b }| **a == 1 && b == &target)\n            //~^ iter_overeager_cloned\n        }\n    }\n\n    let _ = vec.iter().cloned().map(|x| x.len());\n    //~^ redundant_iter_cloned\n\n    // This would fail if changed.\n    let _ = vec.iter().cloned().map(|x| x + \"2\");\n\n    let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty()));\n    //~^ redundant_iter_cloned\n\n    let _ = vec.iter().cloned().all(|x| x.len() == 1);\n    //~^ redundant_iter_cloned\n\n    let _ = vec.iter().cloned().any(|x| x.len() == 1);\n    //~^ redundant_iter_cloned\n\n    // Should probably stay as it is.\n    let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);\n\n    // `&Range<_>` doesn't implement `IntoIterator`\n    let _ = [0..1, 2..5].iter().cloned().flatten();\n}\n\n// #8527\nfn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {\n    x.cloned().flatten()\n}\n\nmod issue_16428 {\n    #[derive(Clone)]\n    struct Foo;\n\n    impl Foo {\n        async fn do_async(&self) {}\n    }\n\n    fn async_move_map() -> Vec<impl std::future::Future<Output = ()>> {\n        let map: std::collections::HashMap<(), Foo> = std::collections::HashMap::new();\n\n        // Should NOT lint: async move block captures `item` by value\n        map.values()\n            .cloned()\n            .map(|item| async move { item.do_async().await })\n            .collect::<Vec<_>>()\n    }\n\n    fn async_move_for_each() {\n        let map: std::collections::HashMap<(), Foo> = std::collections::HashMap::new();\n\n        // Should NOT lint: async move block captures `item` by value\n        map.values()\n            .cloned()\n            .for_each(|item| drop(async move { item.do_async().await }));\n    }\n\n    fn move_closure() {\n        let vec = vec![\"1\".to_string(), \"2\".to_string()];\n\n        // Should NOT lint: move closure captures `x` by value\n        let _: Vec<_> = vec.iter().cloned().map(|x| move || x.len()).collect();\n    }\n\n    fn async_move_not_capturing_param() {\n        let vec = vec![\"1\".to_string(), \"2\".to_string()];\n\n        // Should lint: async move captures `y`, not `x`\n        let _ = vec.iter().cloned().map(|x| {\n            //~^ redundant_iter_cloned\n            let y = x.len();\n            async move { y }\n        });\n    }\n\n    fn move_closure_not_capturing_param() {\n        let vec = vec![\"1\".to_string(), \"2\".to_string()];\n\n        // Should lint: move closure captures `y`, not `x`\n        let _: Vec<_> = vec\n            //~^ redundant_iter_cloned\n            .iter()\n            .cloned()\n            .map(|x| {\n                let y = x.len();\n                move || y\n            })\n            .collect();\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_overeager_cloned.stderr",
    "content": "error: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:12:29\n   |\nLL |     let _: Option<String> = vec.iter().cloned().last();\n   |                             ^^^^^^^^^^----------------\n   |                                       |\n   |                                       help: try: `.last().cloned()`\n   |\n   = note: `-D clippy::iter-overeager-cloned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_overeager_cloned)]`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:15:29\n   |\nLL |     let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------\n   |                                                         |\n   |                                                         help: try: `.next().cloned()`\n\nerror: unneeded cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:18:20\n   |\nLL |     let _: usize = vec.iter().filter(|x| x == &\"2\").cloned().count();\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------\n   |                                                    |\n   |                                                    help: try: `.count()`\n   |\n   = note: `-D clippy::redundant-iter-cloned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_iter_cloned)]`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:21:21\n   |\nLL |     let _: Vec<_> = vec.iter().cloned().take(2).collect();\n   |                     ^^^^^^^^^^-----------------\n   |                               |\n   |                               help: try: `.take(2).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:24:21\n   |\nLL |     let _: Vec<_> = vec.iter().cloned().skip(2).collect();\n   |                     ^^^^^^^^^^-----------------\n   |                               |\n   |                               help: try: `.skip(2).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:27:13\n   |\nLL |     let _ = vec.iter().filter(|x| x == &\"2\").cloned().nth(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------\n   |                                             |\n   |                                             help: try: `.nth(2).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:30:13\n   |\nLL |       let _ = [Some(Some(\"str\".to_string())), Some(Some(\"str\".to_string()))]\n   |  _____________^\nLL | |\nLL | |         .iter()\nLL | |         .cloned()\nLL | |         .flatten();\n   | |__________________^\n   |\nhelp: try\n   |\nLL ~         .iter()\nLL ~         .flatten().cloned();\n   |\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:36:13\n   |\nLL |     let _ = vec.iter().cloned().filter(|x| x.starts_with('2'));\n   |             ^^^^^^^^^^----------------------------------------\n   |                       |\n   |                       help: try: `.filter(|&x| x.starts_with('2')).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:39:13\n   |\nLL |     let _ = vec.iter().cloned().find(|x| x == \"2\");\n   |             ^^^^^^^^^^----------------------------\n   |                       |\n   |                       help: try: `.find(|&x| x == \"2\").cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:44:17\n   |\nLL |         let _ = vec.iter().cloned().filter(f);\n   |                 ^^^^^^^^^^-------------------\n   |                           |\n   |                           help: try: `.filter(|&x| f(x)).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:46:17\n   |\nLL |         let _ = vec.iter().cloned().find(f);\n   |                 ^^^^^^^^^^-----------------\n   |                           |\n   |                           help: try: `.find(|&x| f(x)).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:53:17\n   |\nLL |         let _ = vec.iter().cloned().filter(f);\n   |                 ^^^^^^^^^^-------------------\n   |                           |\n   |                           help: try: `.filter(|&x| f(x)).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:55:17\n   |\nLL |         let _ = vec.iter().cloned().find(f);\n   |                 ^^^^^^^^^^-----------------\n   |                           |\n   |                           help: try: `.find(|&x| f(x)).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:63:9\n   |\nLL |         iter.cloned().filter(move |&(&a, ref b)| a == 1 && b == &target)\n   |         ^^^^------------------------------------------------------------\n   |             |\n   |             help: try: `.filter(move |&&(&a, ref b)| a == 1 && b == &target).cloned()`\n\nerror: unnecessarily eager cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:75:13\n   |\nLL |             iter.cloned().filter(move |S { a, b }| **a == 1 && b == &target)\n   |             ^^^^------------------------------------------------------------\n   |                 |\n   |                 help: try: `.filter(move |&S { a, b }| **a == 1 && b == &target).cloned()`\n\nerror: unneeded cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:80:13\n   |\nLL |     let _ = vec.iter().cloned().map(|x| x.len());\n   |             ^^^^^^^^^^--------------------------\n   |                       |\n   |                       help: try: `.map(|x| x.len())`\n\nerror: unneeded cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:86:13\n   |\nLL |     let _ = vec.iter().cloned().for_each(|x| assert!(!x.is_empty()));\n   |             ^^^^^^^^^^----------------------------------------------\n   |                       |\n   |                       help: try: `.for_each(|x| assert!(!x.is_empty()))`\n\nerror: unneeded cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:89:13\n   |\nLL |     let _ = vec.iter().cloned().all(|x| x.len() == 1);\n   |             ^^^^^^^^^^-------------------------------\n   |                       |\n   |                       help: try: `.all(|x| x.len() == 1)`\n\nerror: unneeded cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:92:13\n   |\nLL |     let _ = vec.iter().cloned().any(|x| x.len() == 1);\n   |             ^^^^^^^^^^-------------------------------\n   |                       |\n   |                       help: try: `.any(|x| x.len() == 1)`\n\nerror: unneeded cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:145:17\n   |\nLL |           let _ = vec.iter().cloned().map(|x| {\n   |  _________________^\nLL | |\nLL | |             let y = x.len();\nLL | |             async move { y }\nLL | |         });\n   | |__________^\n   |\nhelp: try\n   |\nLL ~         let _ = vec.iter().map(|x| {\nLL +\nLL +             let y = x.len();\nLL +             async move { y }\nLL ~         });\n   |\n\nerror: unneeded cloning of iterator items\n  --> tests/ui/iter_overeager_cloned.rs:156:25\n   |\nLL |           let _: Vec<_> = vec\n   |  _________________________^\nLL | |\nLL | |             .iter()\nLL | |             .cloned()\n...  |\nLL | |                 move || y\nLL | |             })\n   | |______________^\n   |\nhelp: try\n   |\nLL ~             .iter()\nLL +             .map(|x| {\nLL +                 let y = x.len();\nLL +                 move || y\nLL +             })\n   |\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_skip_next.fixed",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::iter_skip_next)]\n#![allow(clippy::disallowed_names)]\n#![allow(clippy::iter_nth)]\n#![allow(clippy::useless_vec)]\n#![allow(clippy::iter_out_of_bounds)]\n#![allow(unused_mut, dead_code)]\n\nextern crate option_helpers;\n\nuse option_helpers::IteratorFalsePositives;\n\n/// Checks implementation of `ITER_SKIP_NEXT` lint\nfn main() {\n    let some_vec = vec![0, 1, 2, 3];\n    let _ = some_vec.iter().nth(42);\n    //~^ iter_skip_next\n    let _ = some_vec.iter().cycle().nth(42);\n    //~^ iter_skip_next\n    let _ = (1..10).nth(10);\n    //~^ iter_skip_next\n    let _ = &some_vec[..].iter().nth(3);\n    //~^ iter_skip_next\n    let foo = IteratorFalsePositives { foo: 0 };\n    let _ = foo.skip(42).next();\n    let _ = foo.filter().skip(42).next();\n\n    // fix #8128\n    let test_string = \"1|1 2\";\n    let mut sp = test_string.split('|').map(|s| s.trim());\n    let _: Vec<&str> = sp.nth(1).unwrap().split(' ').collect();\n    //~^ iter_skip_next\n    if let Some(mut s) = Some(test_string.split('|').map(|s| s.trim())) {\n        let _: Vec<&str> = s.nth(1).unwrap().split(' ').collect();\n        //~^ iter_skip_next\n    };\n    fn check<T>(mut s: T)\n    where\n        T: Iterator<Item = String>,\n    {\n        let _: Vec<&str> = s.nth(1).unwrap().split(' ').collect();\n        //~^ iter_skip_next\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_skip_next.rs",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::iter_skip_next)]\n#![allow(clippy::disallowed_names)]\n#![allow(clippy::iter_nth)]\n#![allow(clippy::useless_vec)]\n#![allow(clippy::iter_out_of_bounds)]\n#![allow(unused_mut, dead_code)]\n\nextern crate option_helpers;\n\nuse option_helpers::IteratorFalsePositives;\n\n/// Checks implementation of `ITER_SKIP_NEXT` lint\nfn main() {\n    let some_vec = vec![0, 1, 2, 3];\n    let _ = some_vec.iter().skip(42).next();\n    //~^ iter_skip_next\n    let _ = some_vec.iter().cycle().skip(42).next();\n    //~^ iter_skip_next\n    let _ = (1..10).skip(10).next();\n    //~^ iter_skip_next\n    let _ = &some_vec[..].iter().skip(3).next();\n    //~^ iter_skip_next\n    let foo = IteratorFalsePositives { foo: 0 };\n    let _ = foo.skip(42).next();\n    let _ = foo.filter().skip(42).next();\n\n    // fix #8128\n    let test_string = \"1|1 2\";\n    let mut sp = test_string.split('|').map(|s| s.trim());\n    let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect();\n    //~^ iter_skip_next\n    if let Some(mut s) = Some(test_string.split('|').map(|s| s.trim())) {\n        let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();\n        //~^ iter_skip_next\n    };\n    fn check<T>(mut s: T)\n    where\n        T: Iterator<Item = String>,\n    {\n        let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();\n        //~^ iter_skip_next\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_skip_next.stderr",
    "content": "error: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next.rs:17:28\n   |\nLL |     let _ = some_vec.iter().skip(42).next();\n   |                            ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(42)`\n   |\n   = note: `-D clippy::iter-skip-next` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_skip_next)]`\n\nerror: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next.rs:19:36\n   |\nLL |     let _ = some_vec.iter().cycle().skip(42).next();\n   |                                    ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(42)`\n\nerror: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next.rs:21:20\n   |\nLL |     let _ = (1..10).skip(10).next();\n   |                    ^^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(10)`\n\nerror: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next.rs:23:33\n   |\nLL |     let _ = &some_vec[..].iter().skip(3).next();\n   |                                 ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(3)`\n\nerror: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next.rs:32:26\n   |\nLL |     let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect();\n   |                          ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`\n\nerror: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next.rs:35:29\n   |\nLL |         let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();\n   |                             ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`\n\nerror: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next.rs:42:29\n   |\nLL |         let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();\n   |                             ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_skip_next_unfixable.rs",
    "content": "#![warn(clippy::iter_skip_next)]\n#![allow(dead_code, clippy::iter_out_of_bounds)]\n//@no-rustfix\n/// Checks implementation of `ITER_SKIP_NEXT` lint\nfn main() {\n    // fix #8128\n    let test_string = \"1|1 2\";\n    let sp = test_string.split('|').map(|s| s.trim());\n    let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect();\n    //~^ iter_skip_next\n\n    if let Some(s) = Some(test_string.split('|').map(|s| s.trim())) {\n        let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();\n        //~^ iter_skip_next\n    };\n    fn check<T>(s: T)\n    where\n        T: Iterator<Item = String>,\n    {\n        let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();\n        //~^ iter_skip_next\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_skip_next_unfixable.stderr",
    "content": "error: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next_unfixable.rs:9:26\n   |\nLL |     let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect();\n   |                          ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`\n   |\nhelp: for this change `sp` has to be mutable\n  --> tests/ui/iter_skip_next_unfixable.rs:8:9\n   |\nLL |     let sp = test_string.split('|').map(|s| s.trim());\n   |         ^^\n   = note: `-D clippy::iter-skip-next` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_skip_next)]`\n\nerror: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next_unfixable.rs:13:29\n   |\nLL |         let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();\n   |                             ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`\n   |\nhelp: for this change `s` has to be mutable\n  --> tests/ui/iter_skip_next_unfixable.rs:12:17\n   |\nLL |     if let Some(s) = Some(test_string.split('|').map(|s| s.trim())) {\n   |                 ^\n\nerror: called `skip(..).next()` on an iterator\n  --> tests/ui/iter_skip_next_unfixable.rs:20:29\n   |\nLL |         let _: Vec<&str> = s.skip(1).next().unwrap().split(' ').collect();\n   |                             ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)`\n   |\nhelp: for this change `s` has to be mutable\n  --> tests/ui/iter_skip_next_unfixable.rs:16:17\n   |\nLL |     fn check<T>(s: T)\n   |                 ^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_skip_zero.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::useless_vec, clippy::iter_out_of_bounds, unused)]\n#![warn(clippy::iter_skip_zero)]\n\n#[macro_use]\nextern crate proc_macros;\n\nuse std::iter::once;\n\nfn main() {\n    let _ = [1, 2, 3].iter().skip(1);\n    //~^ iter_skip_zero\n    let _ = vec![1, 2, 3].iter().skip(1);\n    //~^ iter_skip_zero\n    let _ = once([1, 2, 3]).skip(1);\n    //~^ iter_skip_zero\n    let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(1)).skip(1);\n    //~^ iter_skip_zero\n    //~| iter_skip_zero\n    // Don't lint\n    let _ = [1, 2, 3].iter().skip(1);\n    let _ = vec![1, 2, 3].iter().skip(1);\n    external! {\n        let _ = [1, 2, 3].iter().skip(0);\n    }\n    with_span! {\n        let _ = [1, 2, 3].iter().skip(0);\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_skip_zero.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::useless_vec, clippy::iter_out_of_bounds, unused)]\n#![warn(clippy::iter_skip_zero)]\n\n#[macro_use]\nextern crate proc_macros;\n\nuse std::iter::once;\n\nfn main() {\n    let _ = [1, 2, 3].iter().skip(0);\n    //~^ iter_skip_zero\n    let _ = vec![1, 2, 3].iter().skip(0);\n    //~^ iter_skip_zero\n    let _ = once([1, 2, 3]).skip(0);\n    //~^ iter_skip_zero\n    let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0);\n    //~^ iter_skip_zero\n    //~| iter_skip_zero\n    // Don't lint\n    let _ = [1, 2, 3].iter().skip(1);\n    let _ = vec![1, 2, 3].iter().skip(1);\n    external! {\n        let _ = [1, 2, 3].iter().skip(0);\n    }\n    with_span! {\n        let _ = [1, 2, 3].iter().skip(0);\n    }\n}\n"
  },
  {
    "path": "tests/ui/iter_skip_zero.stderr",
    "content": "error: usage of `.skip(0)`\n  --> tests/ui/iter_skip_zero.rs:11:35\n   |\nLL |     let _ = [1, 2, 3].iter().skip(0);\n   |                                   ^ help: if you meant to skip the first element, use: `1`\n   |\n   = note: this call to `skip` does nothing and is useless; remove it\n   = note: `-D clippy::iter-skip-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_skip_zero)]`\n\nerror: usage of `.skip(0)`\n  --> tests/ui/iter_skip_zero.rs:13:39\n   |\nLL |     let _ = vec![1, 2, 3].iter().skip(0);\n   |                                       ^ help: if you meant to skip the first element, use: `1`\n   |\n   = note: this call to `skip` does nothing and is useless; remove it\n\nerror: usage of `.skip(0)`\n  --> tests/ui/iter_skip_zero.rs:15:34\n   |\nLL |     let _ = once([1, 2, 3]).skip(0);\n   |                                  ^ help: if you meant to skip the first element, use: `1`\n   |\n   = note: this call to `skip` does nothing and is useless; remove it\n\nerror: usage of `.skip(0)`\n  --> tests/ui/iter_skip_zero.rs:17:71\n   |\nLL |     let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0);\n   |                                                                       ^ help: if you meant to skip the first element, use: `1`\n   |\n   = note: this call to `skip` does nothing and is useless; remove it\n\nerror: usage of `.skip(0)`\n  --> tests/ui/iter_skip_zero.rs:17:62\n   |\nLL |     let _ = vec![1, 2, 3].iter().chain([1, 2, 3].iter().skip(0)).skip(0);\n   |                                                              ^ help: if you meant to skip the first element, use: `1`\n   |\n   = note: this call to `skip` does nothing and is useless; remove it\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_with_drain.fixed",
    "content": "// will emits unused mut warnings after fixing\n#![allow(unused_mut)]\n// will emits needless collect warnings after fixing\n#![allow(clippy::needless_collect, clippy::drain_collect)]\n#![warn(clippy::iter_with_drain)]\nuse std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};\n\nfn full() {\n    let mut a = vec![\"aaa\".to_string(), \"bbb\".to_string()];\n    let mut a: BinaryHeap<_> = a.into_iter().collect();\n    //~^ iter_with_drain\n    let mut a: HashSet<_> = a.drain().collect();\n    let mut a: VecDeque<_> = a.drain().collect();\n    let mut a: Vec<_> = a.into_iter().collect();\n    //~^ iter_with_drain\n    let mut a: HashMap<_, _> = a.into_iter().map(|x| (x.clone(), x)).collect();\n    //~^ iter_with_drain\n    let _: Vec<(String, String)> = a.drain().collect();\n}\n\nfn closed() {\n    let mut a = vec![\"aaa\".to_string(), \"bbb\".to_string()];\n    let mut a: BinaryHeap<_> = a.into_iter().collect();\n    //~^ iter_with_drain\n    let mut a: HashSet<_> = a.drain().collect();\n    let mut a: VecDeque<_> = a.drain().collect();\n    let mut a: Vec<_> = a.into_iter().collect();\n    //~^ iter_with_drain\n    let mut a: HashMap<_, _> = a.into_iter().map(|x| (x.clone(), x)).collect();\n    //~^ iter_with_drain\n    let _: Vec<(String, String)> = a.drain().collect();\n}\n\nfn should_not_help() {\n    let mut a = vec![\"aaa\".to_string(), \"bbb\".to_string()];\n    let mut a: BinaryHeap<_> = a.drain(1..).collect();\n    let mut a: HashSet<_> = a.drain().collect();\n    let mut a: VecDeque<_> = a.drain().collect();\n    let mut a: Vec<_> = a.drain(..a.len() - 1).collect();\n    let mut a: HashMap<_, _> = a.drain(1..a.len() - 1).map(|x| (x.clone(), x)).collect();\n    let _: Vec<(String, String)> = a.drain().collect();\n\n    let mut b = vec![\"aaa\".to_string(), \"bbb\".to_string()];\n    let _: Vec<_> = b.drain(0..a.len()).collect();\n}\n\nfn _closed_range(mut x: Vec<String>) {\n    let _: Vec<String> = x.drain(0..=x.len()).collect();\n}\n\nfn _with_mut(x: &mut Vec<String>, y: &mut VecDeque<String>) {\n    let _: Vec<String> = x.drain(..).collect();\n    let _: Vec<String> = y.drain(..).collect();\n}\n\n#[derive(Default)]\nstruct Bomb {\n    fire: Vec<u8>,\n}\n\nfn should_not_help_0(bomb: &mut Bomb) {\n    let _: Vec<u8> = bomb.fire.drain(..).collect();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/iter_with_drain.rs",
    "content": "// will emits unused mut warnings after fixing\n#![allow(unused_mut)]\n// will emits needless collect warnings after fixing\n#![allow(clippy::needless_collect, clippy::drain_collect)]\n#![warn(clippy::iter_with_drain)]\nuse std::collections::{BinaryHeap, HashMap, HashSet, VecDeque};\n\nfn full() {\n    let mut a = vec![\"aaa\".to_string(), \"bbb\".to_string()];\n    let mut a: BinaryHeap<_> = a.drain(..).collect();\n    //~^ iter_with_drain\n    let mut a: HashSet<_> = a.drain().collect();\n    let mut a: VecDeque<_> = a.drain().collect();\n    let mut a: Vec<_> = a.drain(..).collect();\n    //~^ iter_with_drain\n    let mut a: HashMap<_, _> = a.drain(..).map(|x| (x.clone(), x)).collect();\n    //~^ iter_with_drain\n    let _: Vec<(String, String)> = a.drain().collect();\n}\n\nfn closed() {\n    let mut a = vec![\"aaa\".to_string(), \"bbb\".to_string()];\n    let mut a: BinaryHeap<_> = a.drain(0..).collect();\n    //~^ iter_with_drain\n    let mut a: HashSet<_> = a.drain().collect();\n    let mut a: VecDeque<_> = a.drain().collect();\n    let mut a: Vec<_> = a.drain(..a.len()).collect();\n    //~^ iter_with_drain\n    let mut a: HashMap<_, _> = a.drain(0..a.len()).map(|x| (x.clone(), x)).collect();\n    //~^ iter_with_drain\n    let _: Vec<(String, String)> = a.drain().collect();\n}\n\nfn should_not_help() {\n    let mut a = vec![\"aaa\".to_string(), \"bbb\".to_string()];\n    let mut a: BinaryHeap<_> = a.drain(1..).collect();\n    let mut a: HashSet<_> = a.drain().collect();\n    let mut a: VecDeque<_> = a.drain().collect();\n    let mut a: Vec<_> = a.drain(..a.len() - 1).collect();\n    let mut a: HashMap<_, _> = a.drain(1..a.len() - 1).map(|x| (x.clone(), x)).collect();\n    let _: Vec<(String, String)> = a.drain().collect();\n\n    let mut b = vec![\"aaa\".to_string(), \"bbb\".to_string()];\n    let _: Vec<_> = b.drain(0..a.len()).collect();\n}\n\nfn _closed_range(mut x: Vec<String>) {\n    let _: Vec<String> = x.drain(0..=x.len()).collect();\n}\n\nfn _with_mut(x: &mut Vec<String>, y: &mut VecDeque<String>) {\n    let _: Vec<String> = x.drain(..).collect();\n    let _: Vec<String> = y.drain(..).collect();\n}\n\n#[derive(Default)]\nstruct Bomb {\n    fire: Vec<u8>,\n}\n\nfn should_not_help_0(bomb: &mut Bomb) {\n    let _: Vec<u8> = bomb.fire.drain(..).collect();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/iter_with_drain.stderr",
    "content": "error: `drain(..)` used on a `Vec`\n  --> tests/ui/iter_with_drain.rs:10:34\n   |\nLL |     let mut a: BinaryHeap<_> = a.drain(..).collect();\n   |                                  ^^^^^^^^^ help: try: `into_iter()`\n   |\n   = note: `-D clippy::iter-with-drain` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_with_drain)]`\n\nerror: `drain(..)` used on a `VecDeque`\n  --> tests/ui/iter_with_drain.rs:14:27\n   |\nLL |     let mut a: Vec<_> = a.drain(..).collect();\n   |                           ^^^^^^^^^ help: try: `into_iter()`\n\nerror: `drain(..)` used on a `Vec`\n  --> tests/ui/iter_with_drain.rs:16:34\n   |\nLL |     let mut a: HashMap<_, _> = a.drain(..).map(|x| (x.clone(), x)).collect();\n   |                                  ^^^^^^^^^ help: try: `into_iter()`\n\nerror: `drain(..)` used on a `Vec`\n  --> tests/ui/iter_with_drain.rs:23:34\n   |\nLL |     let mut a: BinaryHeap<_> = a.drain(0..).collect();\n   |                                  ^^^^^^^^^^ help: try: `into_iter()`\n\nerror: `drain(..)` used on a `VecDeque`\n  --> tests/ui/iter_with_drain.rs:27:27\n   |\nLL |     let mut a: Vec<_> = a.drain(..a.len()).collect();\n   |                           ^^^^^^^^^^^^^^^^ help: try: `into_iter()`\n\nerror: `drain(..)` used on a `Vec`\n  --> tests/ui/iter_with_drain.rs:29:34\n   |\nLL |     let mut a: HashMap<_, _> = a.drain(0..a.len()).map(|x| (x.clone(), x)).collect();\n   |                                  ^^^^^^^^^^^^^^^^^ help: try: `into_iter()`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/iter_without_into_iter.rs",
    "content": "//@no-rustfix\n//@aux-build:proc_macros.rs\n#![warn(clippy::iter_without_into_iter)]\n#![allow(clippy::needless_lifetimes)]\nextern crate proc_macros;\n\npub struct S1;\nimpl S1 {\n    pub fn iter(&self) -> std::slice::Iter<'_, u8> {\n        //~^ iter_without_into_iter\n        [].iter()\n    }\n    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {\n        //~^ iter_without_into_iter\n        [].iter_mut()\n    }\n}\n\npub struct S2;\nimpl S2 {\n    pub fn iter(&self) -> impl Iterator<Item = &u8> {\n        // RPITIT is not stable, so we can't generally suggest it here yet\n        [].iter()\n    }\n}\n\npub struct S3<'a>(&'a mut [u8]);\nimpl<'a> S3<'a> {\n    pub fn iter(&self) -> std::slice::Iter<'_, u8> {\n        //~^ iter_without_into_iter\n        self.0.iter()\n    }\n    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {\n        //~^ iter_without_into_iter\n        self.0.iter_mut()\n    }\n}\n\n// Incompatible signatures\npub struct S4;\nimpl S4 {\n    pub fn iter(self) -> std::slice::Iter<'static, u8> {\n        todo!()\n    }\n}\n\npub struct S5;\nimpl S5 {\n    pub async fn iter(&self) -> std::slice::Iter<'static, u8> {\n        todo!()\n    }\n}\n\npub struct S6;\nimpl S6 {\n    pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> {\n        todo!()\n    }\n}\n\npub struct S7<T>(T);\nimpl<T> S7<T> {\n    pub fn iter<U>(&self) -> std::slice::Iter<'static, (T, U)> {\n        todo!()\n    }\n}\n\npub struct S8<T>(T);\nimpl<T> S8<T> {\n    pub fn iter(&self) -> std::slice::Iter<'static, T> {\n        //~^ iter_without_into_iter\n        todo!()\n    }\n}\n\n// ===========================\npub struct S9<T>(T);\nimpl<T> S9<T> {\n    pub fn iter(&self) -> std::slice::Iter<'_, T> {\n        //~^ iter_without_into_iter\n        todo!()\n    }\n    pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {\n        //~^ iter_without_into_iter\n        todo!()\n    }\n}\n\npub struct S10<T>(T);\nimpl<T> S10<T> {\n    pub fn iter(&self) -> std::slice::Iter<'_, T> {\n        // Don't lint, there's an existing (wrong) IntoIterator impl\n        todo!()\n    }\n}\n\nimpl<'a, T> IntoIterator for &'a S10<T> {\n    type Item = &'a String;\n    type IntoIter = std::slice::Iter<'a, String>;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\npub struct S11<T>(T);\nimpl<T> S11<T> {\n    pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> {\n        // Don't lint, there's an existing (wrong) IntoIterator impl\n        todo!()\n    }\n}\nimpl<'a, T> IntoIterator for &'a mut S11<T> {\n    type Item = &'a mut String;\n    type IntoIter = std::slice::IterMut<'a, String>;\n    fn into_iter(self) -> Self::IntoIter {\n        todo!()\n    }\n}\n\n// Private type not exported: don't lint\nstruct S12;\nimpl S12 {\n    fn iter(&self) -> std::slice::Iter<'_, u8> {\n        todo!()\n    }\n}\n\npub struct Issue12037;\nmacro_rules! generate_impl {\n    () => {\n        impl Issue12037 {\n            fn iter(&self) -> std::slice::Iter<'_, u8> {\n                //~^ iter_without_into_iter\n                todo!()\n            }\n        }\n    };\n}\ngenerate_impl!();\n\nproc_macros::external! {\n    pub struct ImplWithForeignSpan;\n    impl ImplWithForeignSpan {\n        fn iter(&self) -> std::slice::Iter<'_, u8> {\n            todo!()\n        }\n    }\n}\n\npub struct Allowed;\nimpl Allowed {\n    #[allow(clippy::iter_without_into_iter)]\n    pub fn iter(&self) -> std::slice::Iter<'_, u8> {\n        todo!()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/iter_without_into_iter.stderr",
    "content": "error: `iter` method without an `IntoIterator` impl for `&S1`\n  --> tests/ui/iter_without_into_iter.rs:9:5\n   |\nLL | /     pub fn iter(&self) -> std::slice::Iter<'_, u8> {\nLL | |\nLL | |         [].iter()\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::iter-without-into-iter` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iter_without_into_iter)]`\nhelp: consider implementing `IntoIterator` for `&S1`\n   |\nLL + \nLL + impl IntoIterator for &S1 {\nLL +     type Item = &u8;\nLL +     type IntoIter = std::slice::Iter<'_, u8>;\nLL +     fn into_iter(self) -> Self::IntoIter {\nLL +         self.iter()\nLL +     }\nLL + }\n   |\n\nerror: `iter_mut` method without an `IntoIterator` impl for `&mut S1`\n  --> tests/ui/iter_without_into_iter.rs:13:5\n   |\nLL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {\nLL | |\nLL | |         [].iter_mut()\nLL | |     }\n   | |_____^\n   |\nhelp: consider implementing `IntoIterator` for `&mut S1`\n   |\nLL + \nLL + impl IntoIterator for &mut S1 {\nLL +     type Item = &mut u8;\nLL +     type IntoIter = std::slice::IterMut<'_, u8>;\nLL +     fn into_iter(self) -> Self::IntoIter {\nLL +         self.iter()\nLL +     }\nLL + }\n   |\n\nerror: `iter` method without an `IntoIterator` impl for `&S3<'a>`\n  --> tests/ui/iter_without_into_iter.rs:29:5\n   |\nLL | /     pub fn iter(&self) -> std::slice::Iter<'_, u8> {\nLL | |\nLL | |         self.0.iter()\nLL | |     }\n   | |_____^\n   |\nhelp: consider implementing `IntoIterator` for `&S3<'a>`\n   |\nLL + \nLL + impl IntoIterator for &S3<'a> {\nLL +     type Item = &u8;\nLL +     type IntoIter = std::slice::Iter<'_, u8>;\nLL +     fn into_iter(self) -> Self::IntoIter {\nLL +         self.iter()\nLL +     }\nLL + }\n   |\n\nerror: `iter_mut` method without an `IntoIterator` impl for `&mut S3<'a>`\n  --> tests/ui/iter_without_into_iter.rs:33:5\n   |\nLL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {\nLL | |\nLL | |         self.0.iter_mut()\nLL | |     }\n   | |_____^\n   |\nhelp: consider implementing `IntoIterator` for `&mut S3<'a>`\n   |\nLL + \nLL + impl IntoIterator for &mut S3<'a> {\nLL +     type Item = &mut u8;\nLL +     type IntoIter = std::slice::IterMut<'_, u8>;\nLL +     fn into_iter(self) -> Self::IntoIter {\nLL +         self.iter()\nLL +     }\nLL + }\n   |\n\nerror: `iter` method without an `IntoIterator` impl for `&S8<T>`\n  --> tests/ui/iter_without_into_iter.rs:70:5\n   |\nLL | /     pub fn iter(&self) -> std::slice::Iter<'static, T> {\nLL | |\nLL | |         todo!()\nLL | |     }\n   | |_____^\n   |\nhelp: consider implementing `IntoIterator` for `&S8<T>`\n   |\nLL + \nLL + impl IntoIterator for &S8<T> {\nLL +     type Item = &T;\nLL +     type IntoIter = std::slice::Iter<'static, T>;\nLL +     fn into_iter(self) -> Self::IntoIter {\nLL +         self.iter()\nLL +     }\nLL + }\n   |\n\nerror: `iter` method without an `IntoIterator` impl for `&S9<T>`\n  --> tests/ui/iter_without_into_iter.rs:79:5\n   |\nLL | /     pub fn iter(&self) -> std::slice::Iter<'_, T> {\nLL | |\nLL | |         todo!()\nLL | |     }\n   | |_____^\n   |\nhelp: consider implementing `IntoIterator` for `&S9<T>`\n   |\nLL + \nLL + impl IntoIterator for &S9<T> {\nLL +     type Item = &T;\nLL +     type IntoIter = std::slice::Iter<'_, T>;\nLL +     fn into_iter(self) -> Self::IntoIter {\nLL +         self.iter()\nLL +     }\nLL + }\n   |\n\nerror: `iter_mut` method without an `IntoIterator` impl for `&mut S9<T>`\n  --> tests/ui/iter_without_into_iter.rs:83:5\n   |\nLL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {\nLL | |\nLL | |         todo!()\nLL | |     }\n   | |_____^\n   |\nhelp: consider implementing `IntoIterator` for `&mut S9<T>`\n   |\nLL + \nLL + impl IntoIterator for &mut S9<T> {\nLL +     type Item = &mut T;\nLL +     type IntoIter = std::slice::IterMut<'_, T>;\nLL +     fn into_iter(self) -> Self::IntoIter {\nLL +         self.iter()\nLL +     }\nLL + }\n   |\n\nerror: `iter` method without an `IntoIterator` impl for `&Issue12037`\n  --> tests/ui/iter_without_into_iter.rs:132:13\n   |\nLL | /             fn iter(&self) -> std::slice::Iter<'_, u8> {\nLL | |\nLL | |                 todo!()\nLL | |             }\n   | |_____________^\n...\nLL |   generate_impl!();\n   |   ---------------- in this macro invocation\n   |\n   = note: this error originates in the macro `generate_impl` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: consider implementing `IntoIterator` for `&Issue12037`\n   |\nLL ~         \nLL + impl IntoIterator for &Issue12037 {\nLL +     type Item = &u8;\nLL +     type IntoIter = std::slice::Iter<'_, u8>;\nLL +     fn into_iter(self) -> Self::IntoIter {\nLL +         self.iter()\nLL +     }\nLL + }\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/iterator_step_by_zero.rs",
    "content": "#![allow(clippy::useless_vec)]\n#[warn(clippy::iterator_step_by_zero)]\nfn main() {\n    let _ = vec![\"A\", \"B\", \"B\"].iter().step_by(0);\n    //~^ iterator_step_by_zero\n\n    let _ = \"XXX\".chars().step_by(0);\n    //~^ iterator_step_by_zero\n\n    let _ = (0..1).step_by(0);\n    //~^ iterator_step_by_zero\n\n    // No error, not an iterator.\n    let y = NotIterator;\n    y.step_by(0);\n\n    // No warning for non-zero step\n    let _ = (0..1).step_by(1);\n\n    let _ = (1..).step_by(0);\n    //~^ iterator_step_by_zero\n\n    let _ = (1..=2).step_by(0);\n    //~^ iterator_step_by_zero\n\n    let x = 0..1;\n    let _ = x.step_by(0);\n    //~^ iterator_step_by_zero\n\n    // check const eval\n    let v1 = vec![1, 2, 3];\n    let _ = v1.iter().step_by(2 / 3);\n    //~^ iterator_step_by_zero\n}\n\nstruct NotIterator;\nimpl NotIterator {\n    fn step_by(&self, _: u32) {}\n}\n"
  },
  {
    "path": "tests/ui/iterator_step_by_zero.stderr",
    "content": "error: `Iterator::step_by(0)` will panic at runtime\n  --> tests/ui/iterator_step_by_zero.rs:4:13\n   |\nLL |     let _ = vec![\"A\", \"B\", \"B\"].iter().step_by(0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::iterator-step-by-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::iterator_step_by_zero)]`\n\nerror: `Iterator::step_by(0)` will panic at runtime\n  --> tests/ui/iterator_step_by_zero.rs:7:13\n   |\nLL |     let _ = \"XXX\".chars().step_by(0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `Iterator::step_by(0)` will panic at runtime\n  --> tests/ui/iterator_step_by_zero.rs:10:13\n   |\nLL |     let _ = (0..1).step_by(0);\n   |             ^^^^^^^^^^^^^^^^^\n\nerror: `Iterator::step_by(0)` will panic at runtime\n  --> tests/ui/iterator_step_by_zero.rs:20:13\n   |\nLL |     let _ = (1..).step_by(0);\n   |             ^^^^^^^^^^^^^^^^\n\nerror: `Iterator::step_by(0)` will panic at runtime\n  --> tests/ui/iterator_step_by_zero.rs:23:13\n   |\nLL |     let _ = (1..=2).step_by(0);\n   |             ^^^^^^^^^^^^^^^^^^\n\nerror: `Iterator::step_by(0)` will panic at runtime\n  --> tests/ui/iterator_step_by_zero.rs:27:13\n   |\nLL |     let _ = x.step_by(0);\n   |             ^^^^^^^^^^^^\n\nerror: `Iterator::step_by(0)` will panic at runtime\n  --> tests/ui/iterator_step_by_zero.rs:32:13\n   |\nLL |     let _ = v1.iter().step_by(2 / 3);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/join_absolute_paths.1.fixed",
    "content": "#![allow(clippy::needless_raw_string_hashes)]\n#![warn(clippy::join_absolute_paths)]\n\nuse std::path::{Path, PathBuf};\n\nfn main() {\n    let path = Path::new(\"/bin\");\n    path.join(\"sh\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"/bin\");\n    path.join(\"sh\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"/bin\");\n    path.join(r#\"sh\"#);\n    //~^ join_absolute_paths\n\n    let path = Path::new(\"C:\\\\Users\");\n    path.join(\"user\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"C:\\\\Users\");\n    path.join(\"user\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"C:\\\\Users\");\n    path.join(r#\"user\"#);\n    //~^ join_absolute_paths\n\n    let path: &[&str] = &[\"/bin\"];\n    path.join(\"/sh\");\n\n    let path = Path::new(\"/bin\");\n    path.join(\"sh\");\n}\n"
  },
  {
    "path": "tests/ui/join_absolute_paths.2.fixed",
    "content": "#![allow(clippy::needless_raw_string_hashes)]\n#![warn(clippy::join_absolute_paths)]\n\nuse std::path::{Path, PathBuf};\n\nfn main() {\n    let path = Path::new(\"/bin\");\n    PathBuf::from(\"/sh\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"/bin\");\n    PathBuf::from(\"/sh\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"/bin\");\n    PathBuf::from(r#\"/sh\"#);\n    //~^ join_absolute_paths\n\n    let path = Path::new(\"C:\\\\Users\");\n    PathBuf::from(\"\\\\user\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"C:\\\\Users\");\n    PathBuf::from(\"\\\\user\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"C:\\\\Users\");\n    PathBuf::from(r#\"\\user\"#);\n    //~^ join_absolute_paths\n\n    let path: &[&str] = &[\"/bin\"];\n    path.join(\"/sh\");\n\n    let path = Path::new(\"/bin\");\n    path.join(\"sh\");\n}\n"
  },
  {
    "path": "tests/ui/join_absolute_paths.rs",
    "content": "#![allow(clippy::needless_raw_string_hashes)]\n#![warn(clippy::join_absolute_paths)]\n\nuse std::path::{Path, PathBuf};\n\nfn main() {\n    let path = Path::new(\"/bin\");\n    path.join(\"/sh\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"/bin\");\n    path.join(\"/sh\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"/bin\");\n    path.join(r#\"/sh\"#);\n    //~^ join_absolute_paths\n\n    let path = Path::new(\"C:\\\\Users\");\n    path.join(\"\\\\user\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"C:\\\\Users\");\n    path.join(\"\\\\user\");\n    //~^ join_absolute_paths\n\n    let path = PathBuf::from(\"C:\\\\Users\");\n    path.join(r#\"\\user\"#);\n    //~^ join_absolute_paths\n\n    let path: &[&str] = &[\"/bin\"];\n    path.join(\"/sh\");\n\n    let path = Path::new(\"/bin\");\n    path.join(\"sh\");\n}\n"
  },
  {
    "path": "tests/ui/join_absolute_paths.stderr",
    "content": "error: argument to `Path::join` starts with a path separator\n  --> tests/ui/join_absolute_paths.rs:8:15\n   |\nLL |     path.join(\"/sh\");\n   |               ^^^^^\n   |\n   = note: joining a path starting with separator will replace the path instead\n   = note: `-D clippy::join-absolute-paths` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::join_absolute_paths)]`\nhelp: if this is unintentional, try removing the starting separator\n   |\nLL -     path.join(\"/sh\");\nLL +     path.join(\"sh\");\n   |\nhelp: if this is intentional, consider using `Path::new`\n   |\nLL -     path.join(\"/sh\");\nLL +     PathBuf::from(\"/sh\");\n   |\n\nerror: argument to `Path::join` starts with a path separator\n  --> tests/ui/join_absolute_paths.rs:12:15\n   |\nLL |     path.join(\"/sh\");\n   |               ^^^^^\n   |\n   = note: joining a path starting with separator will replace the path instead\nhelp: if this is unintentional, try removing the starting separator\n   |\nLL -     path.join(\"/sh\");\nLL +     path.join(\"sh\");\n   |\nhelp: if this is intentional, consider using `Path::new`\n   |\nLL -     path.join(\"/sh\");\nLL +     PathBuf::from(\"/sh\");\n   |\n\nerror: argument to `Path::join` starts with a path separator\n  --> tests/ui/join_absolute_paths.rs:16:15\n   |\nLL |     path.join(r#\"/sh\"#);\n   |               ^^^^^^^^\n   |\n   = note: joining a path starting with separator will replace the path instead\nhelp: if this is unintentional, try removing the starting separator\n   |\nLL -     path.join(r#\"/sh\"#);\nLL +     path.join(r#\"sh\"#);\n   |\nhelp: if this is intentional, consider using `Path::new`\n   |\nLL -     path.join(r#\"/sh\"#);\nLL +     PathBuf::from(r#\"/sh\"#);\n   |\n\nerror: argument to `Path::join` starts with a path separator\n  --> tests/ui/join_absolute_paths.rs:20:15\n   |\nLL |     path.join(\"\\\\user\");\n   |               ^^^^^^^^\n   |\n   = note: joining a path starting with separator will replace the path instead\nhelp: if this is unintentional, try removing the starting separator\n   |\nLL -     path.join(\"\\\\user\");\nLL +     path.join(\"user\");\n   |\nhelp: if this is intentional, consider using `Path::new`\n   |\nLL -     path.join(\"\\\\user\");\nLL +     PathBuf::from(\"\\\\user\");\n   |\n\nerror: argument to `Path::join` starts with a path separator\n  --> tests/ui/join_absolute_paths.rs:24:15\n   |\nLL |     path.join(\"\\\\user\");\n   |               ^^^^^^^^\n   |\n   = note: joining a path starting with separator will replace the path instead\nhelp: if this is unintentional, try removing the starting separator\n   |\nLL -     path.join(\"\\\\user\");\nLL +     path.join(\"user\");\n   |\nhelp: if this is intentional, consider using `Path::new`\n   |\nLL -     path.join(\"\\\\user\");\nLL +     PathBuf::from(\"\\\\user\");\n   |\n\nerror: argument to `Path::join` starts with a path separator\n  --> tests/ui/join_absolute_paths.rs:28:15\n   |\nLL |     path.join(r#\"\\user\"#);\n   |               ^^^^^^^^^^\n   |\n   = note: joining a path starting with separator will replace the path instead\nhelp: if this is unintentional, try removing the starting separator\n   |\nLL -     path.join(r#\"\\user\"#);\nLL +     path.join(r#\"user\"#);\n   |\nhelp: if this is intentional, consider using `Path::new`\n   |\nLL -     path.join(r#\"\\user\"#);\nLL +     PathBuf::from(r#\"\\user\"#);\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/large_const_arrays.fixed",
    "content": "#![warn(clippy::large_const_arrays)]\n#![allow(dead_code)]\n\n#[derive(Clone, Copy)]\npub struct S {\n    pub data: [u64; 32],\n}\n\n// Should lint\npub(crate) static FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];\n//~^ large_const_arrays\npub static FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];\n//~^ large_const_arrays\nstatic FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];\n//~^ large_const_arrays\nstatic FOO: [u32; 1_000_000] = [0u32; 1_000_000];\n//~^ large_const_arrays\n\n// Good\npub(crate) const G_FOO_PUB_CRATE: [u32; 250] = [0u32; 250];\npub const G_FOO_PUB: [u32; 250] = [0u32; 250];\nconst G_FOO_COMPUTED: [u32; 25 * 10] = [0u32; 25 * 10];\nconst G_FOO: [u32; 250] = [0u32; 250];\n\nfn main() {\n    // Should lint\n    pub static BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];\n    //~^ large_const_arrays\n    static BAR: [u32; 1_000_000] = [0u32; 1_000_000];\n    //~^ large_const_arrays\n    pub static BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];\n    //~^ large_const_arrays\n    static BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];\n    //~^ large_const_arrays\n    pub static BAR_S_PUB: [Option<&str>; 200_000] = [Some(\"str\"); 200_000];\n    //~^ large_const_arrays\n    static BAR_S: [Option<&str>; 200_000] = [Some(\"str\"); 200_000];\n    //~^ large_const_arrays\n\n    // Good\n    pub const G_BAR_PUB: [u32; 250] = [0u32; 250];\n    const G_BAR: [u32; 250] = [0u32; 250];\n    pub const G_BAR_STRUCT_PUB: [S; 4] = [S { data: [0; 32] }; 4];\n    const G_BAR_STRUCT: [S; 4] = [S { data: [0; 32] }; 4];\n    pub const G_BAR_S_PUB: [Option<&str>; 50] = [Some(\"str\"); 50];\n    const G_BAR_S: [Option<&str>; 50] = [Some(\"str\"); 50];\n}\n"
  },
  {
    "path": "tests/ui/large_const_arrays.rs",
    "content": "#![warn(clippy::large_const_arrays)]\n#![allow(dead_code)]\n\n#[derive(Clone, Copy)]\npub struct S {\n    pub data: [u64; 32],\n}\n\n// Should lint\npub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];\n//~^ large_const_arrays\npub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];\n//~^ large_const_arrays\nconst FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];\n//~^ large_const_arrays\nconst FOO: [u32; 1_000_000] = [0u32; 1_000_000];\n//~^ large_const_arrays\n\n// Good\npub(crate) const G_FOO_PUB_CRATE: [u32; 250] = [0u32; 250];\npub const G_FOO_PUB: [u32; 250] = [0u32; 250];\nconst G_FOO_COMPUTED: [u32; 25 * 10] = [0u32; 25 * 10];\nconst G_FOO: [u32; 250] = [0u32; 250];\n\nfn main() {\n    // Should lint\n    pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];\n    //~^ large_const_arrays\n    const BAR: [u32; 1_000_000] = [0u32; 1_000_000];\n    //~^ large_const_arrays\n    pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];\n    //~^ large_const_arrays\n    const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];\n    //~^ large_const_arrays\n    pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some(\"str\"); 200_000];\n    //~^ large_const_arrays\n    const BAR_S: [Option<&str>; 200_000] = [Some(\"str\"); 200_000];\n    //~^ large_const_arrays\n\n    // Good\n    pub const G_BAR_PUB: [u32; 250] = [0u32; 250];\n    const G_BAR: [u32; 250] = [0u32; 250];\n    pub const G_BAR_STRUCT_PUB: [S; 4] = [S { data: [0; 32] }; 4];\n    const G_BAR_STRUCT: [S; 4] = [S { data: [0; 32] }; 4];\n    pub const G_BAR_S_PUB: [Option<&str>; 50] = [Some(\"str\"); 50];\n    const G_BAR_S: [Option<&str>; 50] = [Some(\"str\"); 50];\n}\n"
  },
  {
    "path": "tests/ui/large_const_arrays.stderr",
    "content": "error: large array defined as const\n  --> tests/ui/large_const_arrays.rs:10:1\n   |\nLL | pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];\n   | ^^^^^^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |            |\n   |            help: make this a static item: `static`\n   |\n   = note: `-D clippy::large-const-arrays` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_const_arrays)]`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:12:1\n   |\nLL | pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];\n   | ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |     |\n   |     help: make this a static item: `static`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:14:1\n   |\nLL | const FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];\n   | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   | |\n   | help: make this a static item: `static`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:16:1\n   |\nLL | const FOO: [u32; 1_000_000] = [0u32; 1_000_000];\n   | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   | |\n   | help: make this a static item: `static`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:27:5\n   |\nLL |     pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];\n   |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |         |\n   |         help: make this a static item: `static`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:29:5\n   |\nLL |     const BAR: [u32; 1_000_000] = [0u32; 1_000_000];\n   |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |     |\n   |     help: make this a static item: `static`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:31:5\n   |\nLL |     pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];\n   |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |         |\n   |         help: make this a static item: `static`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:33:5\n   |\nLL |     const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];\n   |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |     |\n   |     help: make this a static item: `static`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:35:5\n   |\nLL |     pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some(\"str\"); 200_000];\n   |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |         |\n   |         help: make this a static item: `static`\n\nerror: large array defined as const\n  --> tests/ui/large_const_arrays.rs:37:5\n   |\nLL |     const BAR_S: [Option<&str>; 200_000] = [Some(\"str\"); 200_000];\n   |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |     |\n   |     help: make this a static item: `static`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/large_digit_groups.fixed",
    "content": "#![warn(clippy::large_digit_groups)]\n\nfn main() {\n    macro_rules! mac {\n        () => {\n            0b1_10110_i64\n        };\n    }\n\n    let _good = (\n        0b1011_i64,\n        0o1_234_u32,\n        0x1_234_567,\n        1_2345_6789,\n        1234_f32,\n        1_234.12_f32,\n        1_234.123_f32,\n        1.123_4_f32,\n    );\n    let _bad = (\n        0b1_10110_i64,\n        0xdead_beef_usize,\n        //~^ unusual_byte_groupings\n        123_456_f32,\n        //~^ large_digit_groups\n        123_456.12_f32,\n        //~^ large_digit_groups\n        123_456.123_45_f64,\n        //~^ large_digit_groups\n        123_456.123_456_f64,\n        //~^ large_digit_groups\n    );\n    // Ignore literals in macros\n    let _ = mac!();\n}\n"
  },
  {
    "path": "tests/ui/large_digit_groups.rs",
    "content": "#![warn(clippy::large_digit_groups)]\n\nfn main() {\n    macro_rules! mac {\n        () => {\n            0b1_10110_i64\n        };\n    }\n\n    let _good = (\n        0b1011_i64,\n        0o1_234_u32,\n        0x1_234_567,\n        1_2345_6789,\n        1234_f32,\n        1_234.12_f32,\n        1_234.123_f32,\n        1.123_4_f32,\n    );\n    let _bad = (\n        0b1_10110_i64,\n        0xd_e_adbee_f_usize,\n        //~^ unusual_byte_groupings\n        1_23456_f32,\n        //~^ large_digit_groups\n        1_23456.12_f32,\n        //~^ large_digit_groups\n        1_23456.12345_f64,\n        //~^ large_digit_groups\n        1_23456.12345_6_f64,\n        //~^ large_digit_groups\n    );\n    // Ignore literals in macros\n    let _ = mac!();\n}\n"
  },
  {
    "path": "tests/ui/large_digit_groups.stderr",
    "content": "error: digits of hex, binary or octal literal not in groups of equal size\n  --> tests/ui/large_digit_groups.rs:22:9\n   |\nLL |         0xd_e_adbee_f_usize,\n   |         ^^^^^^^^^^^^^^^^^^^ help: consider: `0xdead_beef_usize`\n   |\n   = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]`\n\nerror: digit groups should be smaller\n  --> tests/ui/large_digit_groups.rs:24:9\n   |\nLL |         1_23456_f32,\n   |         ^^^^^^^^^^^ help: consider: `123_456_f32`\n   |\n   = note: `-D clippy::large-digit-groups` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_digit_groups)]`\n\nerror: digit groups should be smaller\n  --> tests/ui/large_digit_groups.rs:26:9\n   |\nLL |         1_23456.12_f32,\n   |         ^^^^^^^^^^^^^^ help: consider: `123_456.12_f32`\n\nerror: digit groups should be smaller\n  --> tests/ui/large_digit_groups.rs:28:9\n   |\nLL |         1_23456.12345_f64,\n   |         ^^^^^^^^^^^^^^^^^ help: consider: `123_456.123_45_f64`\n\nerror: digit groups should be smaller\n  --> tests/ui/large_digit_groups.rs:30:9\n   |\nLL |         1_23456.12345_6_f64,\n   |         ^^^^^^^^^^^^^^^^^^^ help: consider: `123_456.123_456_f64`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/large_enum_variant.r32bit.stderr",
    "content": "error: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:13:1\n   |\nLL | / enum LargeEnum {\nLL | |\nLL | |     A(i32),\n   | |     ------ the second-largest variant contains at least 4 bytes\nLL | |     B([i32; 8000]),\n   | |     -------------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\n   = note: `-D clippy::large-enum-variant` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B([i32; 8000]),\nLL +     B(Box<[i32; 8000]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:38:1\n   |\nLL | / enum LargeEnum2 {\nLL | |\nLL | |     VariantOk(i32, u32),\n   | |     ------------------- the second-largest variant contains at least 8 bytes\nLL | |     ContainingLargeEnum(LargeEnum),\n   | |     ------------------------------ the largest variant contains at least 32004 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     ContainingLargeEnum(LargeEnum),\nLL +     ContainingLargeEnum(Box<LargeEnum>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:44:1\n   |\nLL | / enum LargeEnum3 {\nLL | |\nLL | |     ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),\n   | |     --------------------------------------------------------- the largest variant contains at least 70004 bytes\nLL | |     VoidVariant,\nLL | |     StructLikeLittle { x: i32, y: i32 },\n   | |     ----------------------------------- the second-largest variant contains at least 8 bytes\nLL | | }\n   | |_^ the entire enum is at least 70008 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),\nLL +     ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:51:1\n   |\nLL | / enum LargeEnum4 {\nLL | |\nLL | |     VariantOk(i32, u32),\n   | |     ------------------- the second-largest variant contains at least 8 bytes\nLL | |     StructLikeLarge { x: [i32; 8000], y: i32 },\n   | |     ------------------------------------------ the largest variant contains at least 32004 bytes\nLL | | }\n   | |_^ the entire enum is at least 32008 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     StructLikeLarge { x: [i32; 8000], y: i32 },\nLL +     StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:57:1\n   |\nLL | / enum LargeEnum5 {\nLL | |\nLL | |     VariantOk(i32, u32),\n   | |     ------------------- the second-largest variant contains at least 8 bytes\nLL | |     StructLikeLarge2 { x: [i32; 8000] },\n   | |     ----------------------------------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     StructLikeLarge2 { x: [i32; 8000] },\nLL +     StructLikeLarge2 { x: Box<[i32; 8000]> },\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:74:1\n   |\nLL | / enum LargeEnum7 {\nLL | |\nLL | |     A,\nLL | |     B([u8; 1255]),\n   | |     ------------- the largest variant contains at least 1255 bytes\nLL | |     C([u8; 200]),\n   | |     ------------ the second-largest variant contains at least 200 bytes\nLL | | }\n   | |_^ the entire enum is at least 1256 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B([u8; 1255]),\nLL +     B(Box<[u8; 1255]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:81:1\n   |\nLL | / enum LargeEnum8 {\nLL | |\nLL | |     VariantOk(i32, u32),\n   | |     ------------------- the second-largest variant contains at least 8 bytes\nLL | |     ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),\n   | |     ------------------------------------------------------------------------- the largest variant contains at least 70128 bytes\nLL | | }\n   | |_^ the entire enum is at least 70132 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),\nLL +     ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:87:1\n   |\nLL | / enum LargeEnum9 {\nLL | |\nLL | |     A(Struct<()>),\n   | |     ------------- the second-largest variant contains at least 4 bytes\nLL | |     B(Struct2),\n   | |     ---------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B(Struct2),\nLL +     B(Box<Struct2>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:93:1\n   |\nLL | / enum LargeEnumOk2<T> {\nLL | |\nLL | |     A(T),\n   | |     ---- the second-largest variant contains at least 0 bytes\nLL | |     B(Struct2),\n   | |     ---------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32000 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B(Struct2),\nLL +     B(Box<Struct2>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:99:1\n   |\nLL | / enum LargeEnumOk3<T> {\nLL | |\nLL | |     A(Struct<T>),\n   | |     ------------ the second-largest variant contains at least 4 bytes\nLL | |     B(Struct2),\n   | |     ---------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32000 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B(Struct2),\nLL +     B(Box<Struct2>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:115:1\n   |\nLL | / enum CopyableLargeEnum {\nLL | |\nLL | |     A(bool),\n   | |     ------- the second-largest variant contains at least 1 bytes\nLL | |     B([u64; 8000]),\n   | |     -------------- the largest variant contains at least 64000 bytes\nLL | | }\n   | |_^ the entire enum is at least 64004 bytes\n   |\nnote: boxing a variant would require the type no longer be `Copy`\n  --> tests/ui/large_enum_variant.rs:115:6\n   |\nLL | enum CopyableLargeEnum {\n   |      ^^^^^^^^^^^^^^^^^\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n  --> tests/ui/large_enum_variant.rs:118:5\n   |\nLL |     B([u64; 8000]),\n   |     ^^^^^^^^^^^^^^\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:121:1\n   |\nLL | / enum ManuallyCopyLargeEnum {\nLL | |\nLL | |     A(bool),\n   | |     ------- the second-largest variant contains at least 1 bytes\nLL | |     B([u64; 8000]),\n   | |     -------------- the largest variant contains at least 64000 bytes\nLL | | }\n   | |_^ the entire enum is at least 64004 bytes\n   |\nnote: boxing a variant would require the type no longer be `Copy`\n  --> tests/ui/large_enum_variant.rs:121:6\n   |\nLL | enum ManuallyCopyLargeEnum {\n   |      ^^^^^^^^^^^^^^^^^^^^^\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n  --> tests/ui/large_enum_variant.rs:124:5\n   |\nLL |     B([u64; 8000]),\n   |     ^^^^^^^^^^^^^^\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:135:1\n   |\nLL | / enum SomeGenericPossiblyCopyEnum<T> {\nLL | |\nLL | |     A(bool, std::marker::PhantomData<T>),\n   | |     ------------------------------------ the second-largest variant contains at least 1 bytes\nLL | |     B([u64; 4000]),\n   | |     -------------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\nnote: boxing a variant would require the type no longer be `Copy`\n  --> tests/ui/large_enum_variant.rs:135:6\n   |\nLL | enum SomeGenericPossiblyCopyEnum<T> {\n   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n  --> tests/ui/large_enum_variant.rs:138:5\n   |\nLL |     B([u64; 4000]),\n   |     ^^^^^^^^^^^^^^\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:149:1\n   |\nLL | / enum LargeEnumWithGenerics<T> {\nLL | |\nLL | |     Small,\n   | |     ----- the second-largest variant carries no data at all\nLL | |     Large((T, [u8; 512])),\n   | |     --------------------- the largest variant contains at least 512 bytes\nLL | | }\n   | |_^ the entire enum is at least 512 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Large((T, [u8; 512])),\nLL +     Large(Box<(T, [u8; 512])>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:159:1\n   |\nLL | / enum WithGenerics {\nLL | |\nLL | |     Large([Foo<u64>; 64]),\n   | |     --------------------- the largest variant contains at least 512 bytes\nLL | |     Small(u8),\n   | |     --------- the second-largest variant contains at least 1 bytes\nLL | | }\n   | |_^ the entire enum is at least 516 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Large([Foo<u64>; 64]),\nLL +     Large(Box<[Foo<u64>; 64]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:170:1\n   |\nLL | / enum LargeEnumOfConst {\nLL | |\nLL | |     Ok,\n   | |     -- the second-largest variant carries no data at all\nLL | |     Error(PossiblyLargeEnumWithConst<256>),\n   | |     -------------------------------------- the largest variant contains at least 514 bytes\nLL | | }\n   | |_^ the entire enum is at least 514 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Error(PossiblyLargeEnumWithConst<256>),\nLL +     Error(Box<PossiblyLargeEnumWithConst<256>>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:176:1\n   |\nLL | / enum WithRecursion {\nLL | |\nLL | |     Large([u64; 64]),\n   | |     ---------------- the largest variant contains at least 512 bytes\nLL | |     Recursive(Box<WithRecursion>),\n   | |     ----------------------------- the second-largest variant contains at least 4 bytes\nLL | | }\n   | |_^ the entire enum is at least 516 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Large([u64; 64]),\nLL +     Large(Box<[u64; 64]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:187:1\n   |\nLL | / enum LargeEnumWithGenericsAndRecursive {\nLL | |\nLL | |     Ok(),\n   | |     ---- the second-largest variant carries no data at all\nLL | |     Error(WithRecursionAndGenerics<u64>),\n   | |     ------------------------------------ the largest variant contains at least 516 bytes\nLL | | }\n   | |_^ the entire enum is at least 516 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Error(WithRecursionAndGenerics<u64>),\nLL +     Error(Box<WithRecursionAndGenerics<u64>>),\n   |\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/large_enum_variant.r64bit.stderr",
    "content": "error: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:13:1\n   |\nLL | / enum LargeEnum {\nLL | |\nLL | |     A(i32),\n   | |     ------ the second-largest variant contains at least 4 bytes\nLL | |     B([i32; 8000]),\n   | |     -------------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\n   = note: `-D clippy::large-enum-variant` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B([i32; 8000]),\nLL +     B(Box<[i32; 8000]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:38:1\n   |\nLL | / enum LargeEnum2 {\nLL | |\nLL | |     VariantOk(i32, u32),\n   | |     ------------------- the second-largest variant contains at least 8 bytes\nLL | |     ContainingLargeEnum(LargeEnum),\n   | |     ------------------------------ the largest variant contains at least 32004 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     ContainingLargeEnum(LargeEnum),\nLL +     ContainingLargeEnum(Box<LargeEnum>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:44:1\n   |\nLL | / enum LargeEnum3 {\nLL | |\nLL | |     ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),\n   | |     --------------------------------------------------------- the largest variant contains at least 70004 bytes\nLL | |     VoidVariant,\nLL | |     StructLikeLittle { x: i32, y: i32 },\n   | |     ----------------------------------- the second-largest variant contains at least 8 bytes\nLL | | }\n   | |_^ the entire enum is at least 70008 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),\nLL +     ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:51:1\n   |\nLL | / enum LargeEnum4 {\nLL | |\nLL | |     VariantOk(i32, u32),\n   | |     ------------------- the second-largest variant contains at least 8 bytes\nLL | |     StructLikeLarge { x: [i32; 8000], y: i32 },\n   | |     ------------------------------------------ the largest variant contains at least 32004 bytes\nLL | | }\n   | |_^ the entire enum is at least 32008 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     StructLikeLarge { x: [i32; 8000], y: i32 },\nLL +     StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:57:1\n   |\nLL | / enum LargeEnum5 {\nLL | |\nLL | |     VariantOk(i32, u32),\n   | |     ------------------- the second-largest variant contains at least 8 bytes\nLL | |     StructLikeLarge2 { x: [i32; 8000] },\n   | |     ----------------------------------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     StructLikeLarge2 { x: [i32; 8000] },\nLL +     StructLikeLarge2 { x: Box<[i32; 8000]> },\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:74:1\n   |\nLL | / enum LargeEnum7 {\nLL | |\nLL | |     A,\nLL | |     B([u8; 1255]),\n   | |     ------------- the largest variant contains at least 1255 bytes\nLL | |     C([u8; 200]),\n   | |     ------------ the second-largest variant contains at least 200 bytes\nLL | | }\n   | |_^ the entire enum is at least 1256 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B([u8; 1255]),\nLL +     B(Box<[u8; 1255]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:81:1\n   |\nLL | / enum LargeEnum8 {\nLL | |\nLL | |     VariantOk(i32, u32),\n   | |     ------------------- the second-largest variant contains at least 8 bytes\nLL | |     ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),\n   | |     ------------------------------------------------------------------------- the largest variant contains at least 70128 bytes\nLL | | }\n   | |_^ the entire enum is at least 70132 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),\nLL +     ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:87:1\n   |\nLL | / enum LargeEnum9 {\nLL | |\nLL | |     A(Struct<()>),\n   | |     ------------- the second-largest variant contains at least 4 bytes\nLL | |     B(Struct2),\n   | |     ---------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32004 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B(Struct2),\nLL +     B(Box<Struct2>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:93:1\n   |\nLL | / enum LargeEnumOk2<T> {\nLL | |\nLL | |     A(T),\n   | |     ---- the second-largest variant contains at least 0 bytes\nLL | |     B(Struct2),\n   | |     ---------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32000 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B(Struct2),\nLL +     B(Box<Struct2>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:99:1\n   |\nLL | / enum LargeEnumOk3<T> {\nLL | |\nLL | |     A(Struct<T>),\n   | |     ------------ the second-largest variant contains at least 4 bytes\nLL | |     B(Struct2),\n   | |     ---------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32000 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B(Struct2),\nLL +     B(Box<Struct2>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:115:1\n   |\nLL | / enum CopyableLargeEnum {\nLL | |\nLL | |     A(bool),\n   | |     ------- the second-largest variant contains at least 1 bytes\nLL | |     B([u64; 8000]),\n   | |     -------------- the largest variant contains at least 64000 bytes\nLL | | }\n   | |_^ the entire enum is at least 64008 bytes\n   |\nnote: boxing a variant would require the type no longer be `Copy`\n  --> tests/ui/large_enum_variant.rs:115:6\n   |\nLL | enum CopyableLargeEnum {\n   |      ^^^^^^^^^^^^^^^^^\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n  --> tests/ui/large_enum_variant.rs:118:5\n   |\nLL |     B([u64; 8000]),\n   |     ^^^^^^^^^^^^^^\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:121:1\n   |\nLL | / enum ManuallyCopyLargeEnum {\nLL | |\nLL | |     A(bool),\n   | |     ------- the second-largest variant contains at least 1 bytes\nLL | |     B([u64; 8000]),\n   | |     -------------- the largest variant contains at least 64000 bytes\nLL | | }\n   | |_^ the entire enum is at least 64008 bytes\n   |\nnote: boxing a variant would require the type no longer be `Copy`\n  --> tests/ui/large_enum_variant.rs:121:6\n   |\nLL | enum ManuallyCopyLargeEnum {\n   |      ^^^^^^^^^^^^^^^^^^^^^\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n  --> tests/ui/large_enum_variant.rs:124:5\n   |\nLL |     B([u64; 8000]),\n   |     ^^^^^^^^^^^^^^\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:135:1\n   |\nLL | / enum SomeGenericPossiblyCopyEnum<T> {\nLL | |\nLL | |     A(bool, std::marker::PhantomData<T>),\n   | |     ------------------------------------ the second-largest variant contains at least 1 bytes\nLL | |     B([u64; 4000]),\n   | |     -------------- the largest variant contains at least 32000 bytes\nLL | | }\n   | |_^ the entire enum is at least 32008 bytes\n   |\nnote: boxing a variant would require the type no longer be `Copy`\n  --> tests/ui/large_enum_variant.rs:135:6\n   |\nLL | enum SomeGenericPossiblyCopyEnum<T> {\n   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n  --> tests/ui/large_enum_variant.rs:138:5\n   |\nLL |     B([u64; 4000]),\n   |     ^^^^^^^^^^^^^^\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:149:1\n   |\nLL | / enum LargeEnumWithGenerics<T> {\nLL | |\nLL | |     Small,\n   | |     ----- the second-largest variant carries no data at all\nLL | |     Large((T, [u8; 512])),\n   | |     --------------------- the largest variant contains at least 512 bytes\nLL | | }\n   | |_^ the entire enum is at least 512 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Large((T, [u8; 512])),\nLL +     Large(Box<(T, [u8; 512])>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:159:1\n   |\nLL | / enum WithGenerics {\nLL | |\nLL | |     Large([Foo<u64>; 64]),\n   | |     --------------------- the largest variant contains at least 512 bytes\nLL | |     Small(u8),\n   | |     --------- the second-largest variant contains at least 1 bytes\nLL | | }\n   | |_^ the entire enum is at least 520 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Large([Foo<u64>; 64]),\nLL +     Large(Box<[Foo<u64>; 64]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:170:1\n   |\nLL | / enum LargeEnumOfConst {\nLL | |\nLL | |     Ok,\n   | |     -- the second-largest variant carries no data at all\nLL | |     Error(PossiblyLargeEnumWithConst<256>),\n   | |     -------------------------------------- the largest variant contains at least 514 bytes\nLL | | }\n   | |_^ the entire enum is at least 514 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Error(PossiblyLargeEnumWithConst<256>),\nLL +     Error(Box<PossiblyLargeEnumWithConst<256>>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:176:1\n   |\nLL | / enum WithRecursion {\nLL | |\nLL | |     Large([u64; 64]),\n   | |     ---------------- the largest variant contains at least 512 bytes\nLL | |     Recursive(Box<WithRecursion>),\n   | |     ----------------------------- the second-largest variant contains at least 8 bytes\nLL | | }\n   | |_^ the entire enum is at least 520 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Large([u64; 64]),\nLL +     Large(Box<[u64; 64]>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:187:1\n   |\nLL | / enum LargeEnumWithGenericsAndRecursive {\nLL | |\nLL | |     Ok(),\n   | |     ---- the second-largest variant carries no data at all\nLL | |     Error(WithRecursionAndGenerics<u64>),\n   | |     ------------------------------------ the largest variant contains at least 520 bytes\nLL | | }\n   | |_^ the entire enum is at least 520 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     Error(WithRecursionAndGenerics<u64>),\nLL +     Error(Box<WithRecursionAndGenerics<u64>>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:223:5\n   |\nLL | /     enum NoWarnings {\nLL | |\nLL | |         BigBoi(PublishWithBytes),\n   | |         ------------------------ the largest variant contains at least 296 bytes\nLL | |         _SmallBoi(u8),\n   | |         ------------- the second-largest variant contains at least 1 bytes\nLL | |     }\n   | |_____^ the entire enum is at least 296 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -         BigBoi(PublishWithBytes),\nLL +         BigBoi(Box<PublishWithBytes>),\n   |\n\nerror: large size difference between variants\n  --> tests/ui/large_enum_variant.rs:229:5\n   |\nLL | /     enum MakesClippyAngry {\nLL | |\nLL | |         BigBoi(PublishWithVec),\n   | |         ---------------------- the largest variant contains at least 224 bytes\nLL | |         _SmallBoi(u8),\n   | |         ------------- the second-largest variant contains at least 1 bytes\nLL | |     }\n   | |_____^ the entire enum is at least 224 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -         BigBoi(PublishWithVec),\nLL +         BigBoi(Box<PublishWithVec>),\n   |\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/large_enum_variant.rs",
    "content": "//@revisions: r32bit r64bit\n//@aux-build:proc_macros.rs\n//@no-rustfix\n//@[r32bit]ignore-bitwidth: 64\n//@[r64bit]ignore-bitwidth: 32\n#![allow(dead_code)]\n#![allow(unused_variables)]\n#![warn(clippy::large_enum_variant)]\n\nextern crate proc_macros;\nuse proc_macros::external;\n\nenum LargeEnum {\n    //~^ large_enum_variant\n    A(i32),\n    B([i32; 8000]),\n}\n\nenum GenericEnumOk<T> {\n    A(i32),\n    B([T; 8000]),\n}\n\nenum GenericEnum2<T> {\n    A(i32),\n    B([i32; 8000]),\n    C(T, [i32; 8000]),\n}\n\ntrait SomeTrait {\n    type Item;\n}\n\nenum LargeEnumGeneric<A: SomeTrait> {\n    Var(A::Item),\n}\n\nenum LargeEnum2 {\n    //~^ large_enum_variant\n    VariantOk(i32, u32),\n    ContainingLargeEnum(LargeEnum),\n}\n\nenum LargeEnum3 {\n    //~^ large_enum_variant\n    ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),\n    VoidVariant,\n    StructLikeLittle { x: i32, y: i32 },\n}\n\nenum LargeEnum4 {\n    //~^ large_enum_variant\n    VariantOk(i32, u32),\n    StructLikeLarge { x: [i32; 8000], y: i32 },\n}\n\nenum LargeEnum5 {\n    //~^ large_enum_variant\n    VariantOk(i32, u32),\n    StructLikeLarge2 { x: [i32; 8000] },\n}\n\nenum LargeEnumOk {\n    LargeA([i32; 8000]),\n    LargeB([i32; 8001]),\n}\n\nenum LargeEnum6 {\n    A,\n    B([u8; 255]),\n    C([u8; 200]),\n}\n\nenum LargeEnum7 {\n    //~^ large_enum_variant\n    A,\n    B([u8; 1255]),\n    C([u8; 200]),\n}\n\nenum LargeEnum8 {\n    //~^ large_enum_variant\n    VariantOk(i32, u32),\n    ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),\n}\n\nenum LargeEnum9 {\n    //~^ large_enum_variant\n    A(Struct<()>),\n    B(Struct2),\n}\n\nenum LargeEnumOk2<T> {\n    //~^ large_enum_variant\n    A(T),\n    B(Struct2),\n}\n\nenum LargeEnumOk3<T> {\n    //~^ large_enum_variant\n    A(Struct<T>),\n    B(Struct2),\n}\n\nstruct Struct<T> {\n    a: i32,\n    t: T,\n}\n\nstruct Struct2 {\n    a: [i32; 8000],\n}\n\n#[derive(Copy, Clone)]\nenum CopyableLargeEnum {\n    //~^ large_enum_variant\n    A(bool),\n    B([u64; 8000]),\n}\n\nenum ManuallyCopyLargeEnum {\n    //~^ large_enum_variant\n    A(bool),\n    B([u64; 8000]),\n}\n\nimpl Clone for ManuallyCopyLargeEnum {\n    fn clone(&self) -> Self {\n        *self\n    }\n}\n\nimpl Copy for ManuallyCopyLargeEnum {}\n\nenum SomeGenericPossiblyCopyEnum<T> {\n    //~^ large_enum_variant\n    A(bool, std::marker::PhantomData<T>),\n    B([u64; 4000]),\n}\n\nimpl<T: Copy> Clone for SomeGenericPossiblyCopyEnum<T> {\n    fn clone(&self) -> Self {\n        *self\n    }\n}\n\nimpl<T: Copy> Copy for SomeGenericPossiblyCopyEnum<T> {}\n\nenum LargeEnumWithGenerics<T> {\n    //~^ large_enum_variant\n    Small,\n    Large((T, [u8; 512])),\n}\n\nstruct Foo<T> {\n    foo: T,\n}\n\nenum WithGenerics {\n    //~^ large_enum_variant\n    Large([Foo<u64>; 64]),\n    Small(u8),\n}\n\nenum PossiblyLargeEnumWithConst<const U: usize> {\n    SmallBuffer([u8; 4]),\n    MightyBuffer([u16; U]),\n}\n\nenum LargeEnumOfConst {\n    //~^ large_enum_variant\n    Ok,\n    Error(PossiblyLargeEnumWithConst<256>),\n}\n\nenum WithRecursion {\n    //~^ large_enum_variant\n    Large([u64; 64]),\n    Recursive(Box<WithRecursion>),\n}\n\nenum WithRecursionAndGenerics<T> {\n    Large([T; 64]),\n    Recursive(Box<WithRecursionAndGenerics<T>>),\n}\n\nenum LargeEnumWithGenericsAndRecursive {\n    //~^ large_enum_variant\n    Ok(),\n    Error(WithRecursionAndGenerics<u64>),\n}\n\nfn main() {\n    external!(\n        enum LargeEnumInMacro {\n            A(i32),\n            B([i32; 8000]),\n        }\n    );\n}\n\nmod issue11915 {\n    use std::sync::atomic::AtomicPtr;\n\n    pub struct Bytes {\n        ptr: *const u8,\n        len: usize,\n        // inlined \"trait object\"\n        data: AtomicPtr<()>,\n        vtable: &'static Vtable,\n    }\n    pub(crate) struct Vtable {\n        /// fn(data, ptr, len)\n        pub clone: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Bytes,\n        /// fn(data, ptr, len)\n        ///\n        /// takes `Bytes` to value\n        pub to_vec: unsafe fn(&AtomicPtr<()>, *const u8, usize) -> Vec<u8>,\n        /// fn(data, ptr, len)\n        pub drop: unsafe fn(&mut AtomicPtr<()>, *const u8, usize),\n    }\n\n    enum NoWarnings {\n        //~[r64bit]^ large_enum_variant\n        BigBoi(PublishWithBytes),\n        _SmallBoi(u8),\n    }\n\n    enum MakesClippyAngry {\n        //~[r64bit]^ large_enum_variant\n        BigBoi(PublishWithVec),\n        _SmallBoi(u8),\n    }\n\n    struct PublishWithBytes {\n        _dup: bool,\n        _retain: bool,\n        _topic: Bytes,\n        __topic: Bytes,\n        ___topic: Bytes,\n        ____topic: Bytes,\n        _pkid: u16,\n        _payload: Bytes,\n        __payload: Bytes,\n        ___payload: Bytes,\n        ____payload: Bytes,\n        _____payload: Bytes,\n    }\n\n    struct PublishWithVec {\n        _dup: bool,\n        _retain: bool,\n        _topic: Vec<u8>,\n        __topic: Vec<u8>,\n        ___topic: Vec<u8>,\n        ____topic: Vec<u8>,\n        _pkid: u16,\n        _payload: Vec<u8>,\n        __payload: Vec<u8>,\n        ___payload: Vec<u8>,\n        ____payload: Vec<u8>,\n        _____payload: Vec<u8>,\n    }\n}\n"
  },
  {
    "path": "tests/ui/large_enum_variant_no_std.rs",
    "content": "#![no_std]\n#![warn(clippy::large_enum_variant)]\n\nenum Myenum {\n    //~^ ERROR: large size difference between variants\n    Small(u8),\n    Large([u8; 1024]),\n}\n"
  },
  {
    "path": "tests/ui/large_enum_variant_no_std.stderr",
    "content": "error: large size difference between variants\n  --> tests/ui/large_enum_variant_no_std.rs:4:1\n   |\nLL | / enum Myenum {\nLL | |\nLL | |     Small(u8),\n   | |     --------- the second-largest variant contains at least 1 bytes\nLL | |     Large([u8; 1024]),\n   | |     ----------------- the largest variant contains at least 1024 bytes\nLL | | }\n   | |_^ the entire enum is at least 1025 bytes\n   |\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n  --> tests/ui/large_enum_variant_no_std.rs:7:5\n   |\nLL |     Large([u8; 1024]),\n   |     ^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::large-enum-variant` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/large_futures.fixed",
    "content": "#![allow(\n    clippy::future_not_send,\n    clippy::manual_async_fn,\n    clippy::never_loop,\n    clippy::uninlined_format_args\n)]\n#![warn(clippy::large_futures)]\n\nasync fn big_fut(_arg: [u8; 1024 * 16]) {}\n\nasync fn wait() {\n    let f = async {\n        Box::pin(big_fut([0u8; 1024 * 16])).await;\n        //~^ large_futures\n    };\n    Box::pin(f).await\n    //~^ large_futures\n}\nasync fn calls_fut(fut: impl std::future::Future<Output = ()>) {\n    loop {\n        Box::pin(wait()).await;\n        //~^ large_futures\n\n        if true {\n            return fut.await;\n        } else {\n            Box::pin(wait()).await;\n            //~^ large_futures\n        }\n    }\n}\n\npub async fn test() {\n    let fut = big_fut([0u8; 1024 * 16]);\n    Box::pin(foo()).await;\n    //~^ large_futures\n\n    Box::pin(calls_fut(fut)).await;\n    //~^ large_futures\n}\n\npub fn foo() -> impl std::future::Future<Output = ()> {\n    async {\n        let x = [0i32; 1024 * 16];\n        async {}.await;\n        dbg!(x);\n    }\n}\n\npub async fn lines() {\n    Box::pin(async {\n        //~^ large_futures\n\n        let x = [0i32; 1024 * 16];\n        async {}.await;\n        println!(\"{:?}\", x);\n    })\n    .await;\n}\n\npub async fn macro_expn() {\n    macro_rules! macro_ {\n        () => {\n            Box::pin(async {\n                //~^ large_futures\n                let x = [0i32; 1024 * 16];\n                async {}.await;\n                println!(\"macro: {:?}\", x);\n            })\n        };\n    }\n    macro_!().await\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/large_futures.rs",
    "content": "#![allow(\n    clippy::future_not_send,\n    clippy::manual_async_fn,\n    clippy::never_loop,\n    clippy::uninlined_format_args\n)]\n#![warn(clippy::large_futures)]\n\nasync fn big_fut(_arg: [u8; 1024 * 16]) {}\n\nasync fn wait() {\n    let f = async {\n        big_fut([0u8; 1024 * 16]).await;\n        //~^ large_futures\n    };\n    f.await\n    //~^ large_futures\n}\nasync fn calls_fut(fut: impl std::future::Future<Output = ()>) {\n    loop {\n        wait().await;\n        //~^ large_futures\n\n        if true {\n            return fut.await;\n        } else {\n            wait().await;\n            //~^ large_futures\n        }\n    }\n}\n\npub async fn test() {\n    let fut = big_fut([0u8; 1024 * 16]);\n    foo().await;\n    //~^ large_futures\n\n    calls_fut(fut).await;\n    //~^ large_futures\n}\n\npub fn foo() -> impl std::future::Future<Output = ()> {\n    async {\n        let x = [0i32; 1024 * 16];\n        async {}.await;\n        dbg!(x);\n    }\n}\n\npub async fn lines() {\n    async {\n        //~^ large_futures\n\n        let x = [0i32; 1024 * 16];\n        async {}.await;\n        println!(\"{:?}\", x);\n    }\n    .await;\n}\n\npub async fn macro_expn() {\n    macro_rules! macro_ {\n        () => {\n            async {\n                //~^ large_futures\n                let x = [0i32; 1024 * 16];\n                async {}.await;\n                println!(\"macro: {:?}\", x);\n            }\n        };\n    }\n    macro_!().await\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/large_futures.stderr",
    "content": "error: large future with a size of 16385 bytes\n  --> tests/ui/large_futures.rs:13:9\n   |\nLL |         big_fut([0u8; 1024 * 16]).await;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(big_fut([0u8; 1024 * 16]))`\n   |\n   = note: `-D clippy::large-futures` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_futures)]`\n\nerror: large future with a size of 16386 bytes\n  --> tests/ui/large_futures.rs:16:5\n   |\nLL |     f.await\n   |     ^ help: consider `Box::pin` on it: `Box::pin(f)`\n\nerror: large future with a size of 16387 bytes\n  --> tests/ui/large_futures.rs:21:9\n   |\nLL |         wait().await;\n   |         ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())`\n\nerror: large future with a size of 16387 bytes\n  --> tests/ui/large_futures.rs:27:13\n   |\nLL |             wait().await;\n   |             ^^^^^^ help: consider `Box::pin` on it: `Box::pin(wait())`\n\nerror: large future with a size of 65540 bytes\n  --> tests/ui/large_futures.rs:35:5\n   |\nLL |     foo().await;\n   |     ^^^^^ help: consider `Box::pin` on it: `Box::pin(foo())`\n\nerror: large future with a size of 49159 bytes\n  --> tests/ui/large_futures.rs:38:5\n   |\nLL |     calls_fut(fut).await;\n   |     ^^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(calls_fut(fut))`\n\nerror: large future with a size of 65540 bytes\n  --> tests/ui/large_futures.rs:51:5\n   |\nLL | /     async {\nLL | |\nLL | |\nLL | |         let x = [0i32; 1024 * 16];\nLL | |         async {}.await;\nLL | |         println!(\"{:?}\", x);\nLL | |     }\n   | |_____^\n   |\nhelp: consider `Box::pin` on it\n   |\nLL ~     Box::pin(async {\nLL +\nLL + \nLL +         let x = [0i32; 1024 * 16];\nLL +         async {}.await;\nLL +         println!(\"{:?}\", x);\nLL +     })\n   |\n\nerror: large future with a size of 65540 bytes\n  --> tests/ui/large_futures.rs:64:13\n   |\nLL | /             async {\nLL | |\nLL | |                 let x = [0i32; 1024 * 16];\nLL | |                 async {}.await;\nLL | |                 println!(\"macro: {:?}\", x);\nLL | |             }\n   | |_____________^\n...\nLL |       macro_!().await\n   |       --------- in this macro invocation\n   |\n   = note: this error originates in the macro `macro_` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: consider `Box::pin` on it\n   |\nLL ~             Box::pin(async {\nLL +\nLL +                 let x = [0i32; 1024 * 16];\nLL +                 async {}.await;\nLL +                 println!(\"macro: {:?}\", x);\nLL +             })\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/large_stack_arrays.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::large_stack_arrays)]\n#![allow(clippy::large_enum_variant)]\n\nextern crate proc_macros;\n\n#[derive(Clone, Copy)]\nstruct S {\n    pub data: [u64; 32],\n}\n\n#[derive(Clone, Copy)]\nenum E {\n    S(S),\n    T(u32),\n}\n\nconst STATIC_PROMOTED_LARGE_ARRAY: &[u8; 512001] = &[0; 512001];\nconst STATIC_PROMOTED_LARGE_ARRAY_WITH_NESTED: &[u8; 512001] = {\n    const NESTED: () = ();\n    &[0; 512001]\n};\n\npub static DOESNOTLINT: [u8; 512_001] = [0; 512_001];\npub static DOESNOTLINT2: [u8; 512_001] = {\n    let x = 0;\n    [x; 512_001]\n};\n\nfn issue_10741() {\n    #[derive(Copy, Clone)]\n    struct Large([u32; 2048]);\n\n    fn build() -> Large {\n        Large([0; 2048])\n    }\n\n    let _x = [build(); 3];\n    //~^ ERROR: allocating a local array larger than 16384 bytes\n\n    let _y = [build(), build(), build()];\n    //~^ ERROR: allocating a local array larger than 16384 bytes\n}\n\nfn main() {\n    let bad = (\n        [0u32; 20_000_000],\n        //~^ ERROR: allocating a local array larger than 16384 bytes\n        [S { data: [0; 32] }; 5000],\n        //~^ ERROR: allocating a local array larger than 16384 bytes\n        [Some(\"\"); 20_000_000],\n        //~^ ERROR: allocating a local array larger than 16384 bytes\n        [E::T(0); 5000],\n        //~^ ERROR: allocating a local array larger than 16384 bytes\n        [0u8; usize::MAX],\n        //~^ ERROR: allocating a local array larger than 16384 bytes\n    );\n\n    let good = (\n        [0u32; 50],\n        [S { data: [0; 32] }; 4],\n        [Some(\"\"); 50],\n        [E::T(0); 2],\n        [(); 20_000_000],\n    );\n}\n\n#[allow(clippy::useless_vec)]\nfn issue_12586() {\n    macro_rules! dummy {\n        ($n:expr) => {\n            $n\n        };\n        // Weird rule to test help messages.\n        ($a:expr => $b:expr) => {\n            [$a, $b, $a, $b]\n            //~^ ERROR: allocating a local array larger than 16384 bytes\n        };\n        ($id:ident; $n:literal) => {\n            dummy!(::std::vec![$id;$n])\n        };\n        ($($id:expr),+ $(,)?) => {\n            ::std::vec![$($id),*]\n        }\n    }\n    macro_rules! create_then_move {\n        ($id:ident; $n:literal) => {{\n            let _x_ = [$id; $n];\n            //~^ ERROR: allocating a local array larger than 16384 bytes\n            _x_\n        }};\n    }\n\n    let x = [0u32; 4096];\n    let y = vec![x, x, x, x, x];\n    let y = vec![dummy![x, x, x, x, x]];\n    let y = vec![dummy![[x, x, x, x, x]]];\n    let y = dummy![x, x, x, x, x];\n    let y = [x, x, dummy!(x), x, x];\n    //~^ ERROR: allocating a local array larger than 16384 bytes\n    let y = dummy![x => x];\n    let y = dummy![x;5];\n    let y = dummy!(vec![dummy![x, x, x, x, x]]);\n    let y = dummy![[x, x, x, x, x]];\n    //~^ ERROR: allocating a local array larger than 16384 bytes\n\n    let y = proc_macros::make_it_big!([x; 1]);\n    //~^ ERROR: allocating a local array larger than 16384 bytes\n    let y = vec![proc_macros::make_it_big!([x; 10])];\n    let y = vec![create_then_move![x; 5]; 5];\n}\n"
  },
  {
    "path": "tests/ui/large_stack_arrays.stderr",
    "content": "error: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:38:14\n   |\nLL |     let _x = [build(); 3];\n   |              ^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![build(); 3].into_boxed_slice()`\n   = note: `-D clippy::large-stack-arrays` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_stack_arrays)]`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:41:14\n   |\nLL |     let _y = [build(), build(), build()];\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![build(), build(), build()].into_boxed_slice()`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:47:9\n   |\nLL |         [0u32; 20_000_000],\n   |         ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![0u32; 20_000_000].into_boxed_slice()`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:49:9\n   |\nLL |         [S { data: [0; 32] }; 5000],\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![S { data: [0; 32] }; 5000].into_boxed_slice()`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:51:9\n   |\nLL |         [Some(\"\"); 20_000_000],\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![Some(\"\"); 20_000_000].into_boxed_slice()`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:53:9\n   |\nLL |         [E::T(0); 5000],\n   |         ^^^^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![E::T(0); 5000].into_boxed_slice()`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:55:9\n   |\nLL |         [0u8; usize::MAX],\n   |         ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![0u8; usize::MAX].into_boxed_slice()`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:99:13\n   |\nLL |     let y = [x, x, dummy!(x), x, x];\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![x, x, dummy!(x), x, x].into_boxed_slice()`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:76:13\n   |\nLL |             [$a, $b, $a, $b]\n   |             ^^^^^^^^^^^^^^^^\n...\nLL |     let y = dummy![x => x];\n   |             -------------- in this macro invocation\n   |\n   = note: this error originates in the macro `dummy` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:104:20\n   |\nLL |     let y = dummy![[x, x, x, x, x]];\n   |                    ^^^^^^^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![x, x, x, x, x].into_boxed_slice()`\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:107:39\n   |\nLL |     let y = proc_macros::make_it_big!([x; 1]);\n   |                                       ^^^^^^\n\nerror: allocating a local array larger than 16384 bytes\n  --> tests/ui/large_stack_arrays.rs:88:23\n   |\nLL |             let _x_ = [$id; $n];\n   |                       ^^^^^^^^^\n...\nLL |     let y = vec![create_then_move![x; 5]; 5];\n   |                  ----------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `create_then_move` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/large_stack_frames.rs",
    "content": "//@ normalize-stderr-test: \"\\b10000(08|16|32)\\b\" -> \"100$$PTR\"\n//@ normalize-stderr-test: \"\\b2500(060|120)\\b\" -> \"250$$PTR\"\n#![allow(unused)]\n#![warn(clippy::large_stack_frames)]\n\nuse std::hint::black_box;\n\nfn generic<T: Default>() {\n    let x = T::default();\n    black_box(&x);\n}\n\nstruct ArrayDefault<const N: usize>([u8; N]);\n\nimpl<const N: usize> Default for ArrayDefault<N> {\n    fn default() -> Self {\n        Self([0; N])\n    }\n}\n\nfn many_small_arrays() {\n    //~^ large_stack_frames\n\n    let x = [0u8; 500_000];\n    let x2 = [0u8; 500_000];\n    let x3 = [0u8; 500_000];\n    let x4 = [0u8; 500_000];\n    let x5 = [0u8; 500_000];\n    black_box((&x, &x2, &x3, &x4, &x5));\n}\n\nfn large_return_value() -> ArrayDefault<1_000_000> {\n    //~^ large_stack_frames\n\n    Default::default()\n}\n\nfn large_fn_arg(x: ArrayDefault<1_000_000>) {\n    //~^ large_stack_frames\n\n    black_box(&x);\n}\n\nfn has_large_closure() {\n    let f = || black_box(&[0u8; 1_000_000]);\n    //~^ large_stack_frames\n\n    f();\n}\n\nfn main() {\n    generic::<ArrayDefault<1_000_000>>();\n}\n"
  },
  {
    "path": "tests/ui/large_stack_frames.stderr",
    "content": "error: this function may allocate 250$PTR bytes on the stack\n  --> tests/ui/large_stack_frames.rs:21:4\n   |\nLL | fn many_small_arrays() {\n   |    ^^^^^^^^^^^^^^^^^\n...\nLL |     let x5 = [0u8; 500_000];\n   |         -- `x5` is the largest part, at 500000 bytes for type `[u8; 500000]`\n   |\n   = note: 250$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000\n   = note: allocating large amounts of stack space can overflow the stack and cause the program to abort\n   = note: `-D clippy::large-stack-frames` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`\n\nerror: this function may allocate 1000000 bytes on the stack\n  --> tests/ui/large_stack_frames.rs:32:4\n   |\nLL | fn large_return_value() -> ArrayDefault<1_000_000> {\n   |    ^^^^^^^^^^^^^^^^^^      ----------------------- this is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`\n   |\n   = note: 1000000 bytes is larger than Clippy's configured `stack-size-threshold` of 512000\n\nerror: this function may allocate 100$PTR bytes on the stack\n  --> tests/ui/large_stack_frames.rs:38:4\n   |\nLL | fn large_fn_arg(x: ArrayDefault<1_000_000>) {\n   |    ^^^^^^^^^^^^ - `x` is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`\n   |\n   = note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000\n\nerror: this function may allocate 100$PTR bytes on the stack\n  --> tests/ui/large_stack_frames.rs:45:13\n   |\nLL |     let f = || black_box(&[0u8; 1_000_000]);\n   |             ^^^^^^^^^^^^^^----------------^\n   |                           |\n   |                           this is the largest part, at 1000000 bytes for type `[u8; 1000000]`\n   |\n   = note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/large_types_passed_by_value.rs",
    "content": "//@normalize-stderr-test: \"\\(\\d+ byte\\)\" -> \"(N byte)\"\n//@normalize-stderr-test: \"\\(limit: \\d+ byte\\)\" -> \"(limit: N byte)\"\n//@no-rustfix\n#![warn(clippy::large_types_passed_by_value)]\n\npub struct Large([u8; 2048]);\n\n#[derive(Clone, Copy)]\npub struct LargeAndCopy([u8; 2048]);\n\npub struct Small([u8; 4]);\n\n#[derive(Clone, Copy)]\npub struct SmallAndCopy([u8; 4]);\n\nfn small(a: Small, b: SmallAndCopy) {}\nfn not_copy(a: Large) {}\nfn by_ref(a: &Large, b: &LargeAndCopy) {}\nfn mutable(mut a: LargeAndCopy) {}\nfn bad(a: LargeAndCopy) {}\n//~^ large_types_passed_by_value\npub fn bad_but_pub(a: LargeAndCopy) {}\n\nimpl LargeAndCopy {\n    fn self_is_ok(self) {}\n    fn other_is_not_ok(self, other: LargeAndCopy) {}\n    //~^ large_types_passed_by_value\n    fn unless_other_can_change(self, mut other: LargeAndCopy) {}\n    pub fn or_were_in_public(self, other: LargeAndCopy) {}\n}\n\ntrait LargeTypeDevourer {\n    fn devoure_array(&self, array: [u8; 6666]);\n    //~^ large_types_passed_by_value\n    fn devoure_tuple(&self, tup: (LargeAndCopy, LargeAndCopy));\n    //~^ large_types_passed_by_value\n    fn devoure_array_and_tuple_wow(&self, array: [u8; 6666], tup: (LargeAndCopy, LargeAndCopy));\n    //~^ large_types_passed_by_value\n    //~| large_types_passed_by_value\n}\n\npub trait PubLargeTypeDevourer {\n    fn devoure_array_in_public(&self, array: [u8; 6666]);\n}\n\nstruct S;\nimpl LargeTypeDevourer for S {\n    fn devoure_array(&self, array: [u8; 6666]) {\n        todo!();\n    }\n    fn devoure_tuple(&self, tup: (LargeAndCopy, LargeAndCopy)) {\n        todo!();\n    }\n    fn devoure_array_and_tuple_wow(&self, array: [u8; 6666], tup: (LargeAndCopy, LargeAndCopy)) {\n        todo!();\n    }\n}\n\n#[inline(always)]\nfn foo_always(x: LargeAndCopy) {\n    todo!();\n}\n#[inline(never)]\nfn foo_never(x: LargeAndCopy) {\n    //~^ large_types_passed_by_value\n    todo!();\n}\n#[inline]\nfn foo(x: LargeAndCopy) {\n    //~^ large_types_passed_by_value\n    todo!();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/large_types_passed_by_value.stderr",
    "content": "error: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)\n  --> tests/ui/large_types_passed_by_value.rs:20:11\n   |\nLL | fn bad(a: LargeAndCopy) {}\n   |           ^^^^^^^^^^^^ help: consider passing by reference instead: `&LargeAndCopy`\n   |\n   = note: `-D clippy::large-types-passed-by-value` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_types_passed_by_value)]`\n\nerror: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)\n  --> tests/ui/large_types_passed_by_value.rs:26:37\n   |\nLL |     fn other_is_not_ok(self, other: LargeAndCopy) {}\n   |                                     ^^^^^^^^^^^^ help: consider passing by reference instead: `&LargeAndCopy`\n\nerror: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)\n  --> tests/ui/large_types_passed_by_value.rs:33:36\n   |\nLL |     fn devoure_array(&self, array: [u8; 6666]);\n   |                                    ^^^^^^^^^^ help: consider passing by reference instead: `&[u8; 6666]`\n\nerror: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)\n  --> tests/ui/large_types_passed_by_value.rs:35:34\n   |\nLL |     fn devoure_tuple(&self, tup: (LargeAndCopy, LargeAndCopy));\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider passing by reference instead: `&(LargeAndCopy, LargeAndCopy)`\n\nerror: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)\n  --> tests/ui/large_types_passed_by_value.rs:37:50\n   |\nLL |     fn devoure_array_and_tuple_wow(&self, array: [u8; 6666], tup: (LargeAndCopy, LargeAndCopy));\n   |                                                  ^^^^^^^^^^ help: consider passing by reference instead: `&[u8; 6666]`\n\nerror: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)\n  --> tests/ui/large_types_passed_by_value.rs:37:67\n   |\nLL |     fn devoure_array_and_tuple_wow(&self, array: [u8; 6666], tup: (LargeAndCopy, LargeAndCopy));\n   |                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider passing by reference instead: `&(LargeAndCopy, LargeAndCopy)`\n\nerror: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)\n  --> tests/ui/large_types_passed_by_value.rs:64:17\n   |\nLL | fn foo_never(x: LargeAndCopy) {\n   |                 ^^^^^^^^^^^^ help: consider passing by reference instead: `&LargeAndCopy`\n\nerror: this argument (N byte) is passed by value, but might be more efficient if passed by reference (limit: N byte)\n  --> tests/ui/large_types_passed_by_value.rs:69:11\n   |\nLL | fn foo(x: LargeAndCopy) {\n   |           ^^^^^^^^^^^^ help: consider passing by reference instead: `&LargeAndCopy`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/legacy_numeric_constants.fixed",
    "content": "//@aux-build:proc_macros.rs\n//@require-annotations-for-level: WARN\n#![allow(clippy::no_effect, deprecated, unused)]\n#![allow(clippy::legacy_numeric_constants)] // For imports.\n\n#[macro_use]\nextern crate proc_macros;\n\npub mod a {\n    pub use std::u128;\n}\n\nmacro_rules! b {\n    () => {\n        mod b {\n            #[warn(clippy::legacy_numeric_constants)]\n            fn b() {\n                let x = u64::MAX;\n                //~^ ERROR: usage of a legacy numeric constant\n                //~| HELP: use the associated constant instead\n            }\n        }\n    };\n}\n\nuse std::u8::MIN;\nuse std::u32::MAX;\nuse std::{f64, u32};\n\n#[warn(clippy::legacy_numeric_constants)]\nfn main() {\n    f32::EPSILON;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    u8::MIN;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    usize::MIN;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    u32::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    u32::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    u32::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    i32::MAX;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    u8::MAX;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    u8::MIN;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    u8::MIN;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    ::std::primitive::u8::MIN;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    std::primitive::i32::MAX;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    u128::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    u32::MAX;\n    u128::MAX;\n    f32::EPSILON;\n    ::std::primitive::u8::MIN;\n    std::f32::consts::E;\n    f64::consts::E;\n    u8::MIN;\n    std::f32::consts::E;\n    f64::consts::E;\n    b!();\n\n    std::primitive::i32::MAX;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    [(0, \"\", i128::MAX)];\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    i32::MAX;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    assert_eq!(0, -i32::MAX);\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    i128::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    u32::MAX;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    i32::MAX;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    type Ω = i32;\n    Ω::MAX;\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n}\n\n#[warn(clippy::legacy_numeric_constants)]\nfn ext() {\n    external! {\n        ::std::primitive::u8::MIN;\n        ::std::u8::MIN;\n        ::std::primitive::u8::min_value();\n        use std::u64;\n        use std::u8::MIN;\n    }\n}\n\n#[allow(clippy::legacy_numeric_constants)]\nfn allow() {\n    ::std::primitive::u8::MIN;\n    ::std::u8::MIN;\n    ::std::primitive::u8::min_value();\n    use std::u8::MIN;\n    use std::u64;\n}\n\n#[warn(clippy::legacy_numeric_constants)]\n#[clippy::msrv = \"1.42.0\"]\nfn msrv_too_low() {\n    std::u32::MAX;\n}\n\n#[warn(clippy::legacy_numeric_constants)]\n#[clippy::msrv = \"1.43.0\"]\nfn msrv_juust_right() {\n    u32::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n}\n"
  },
  {
    "path": "tests/ui/legacy_numeric_constants.rs",
    "content": "//@aux-build:proc_macros.rs\n//@require-annotations-for-level: WARN\n#![allow(clippy::no_effect, deprecated, unused)]\n#![allow(clippy::legacy_numeric_constants)] // For imports.\n\n#[macro_use]\nextern crate proc_macros;\n\npub mod a {\n    pub use std::u128;\n}\n\nmacro_rules! b {\n    () => {\n        mod b {\n            #[warn(clippy::legacy_numeric_constants)]\n            fn b() {\n                let x = std::u64::MAX;\n                //~^ ERROR: usage of a legacy numeric constant\n                //~| HELP: use the associated constant instead\n            }\n        }\n    };\n}\n\nuse std::u8::MIN;\nuse std::u32::MAX;\nuse std::{f64, u32};\n\n#[warn(clippy::legacy_numeric_constants)]\nfn main() {\n    std::f32::EPSILON;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    std::u8::MIN;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    std::usize::MIN;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    std::u32::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    core::u32::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    i32::max_value();\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    u8::max_value();\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    u8::min_value();\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    ::std::u8::MIN;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    ::std::primitive::u8::min_value();\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    std::primitive::i32::max_value();\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    self::a::u128::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    u32::MAX;\n    u128::MAX;\n    f32::EPSILON;\n    ::std::primitive::u8::MIN;\n    std::f32::consts::E;\n    f64::consts::E;\n    u8::MIN;\n    std::f32::consts::E;\n    f64::consts::E;\n    b!();\n\n    <std::primitive::i32>::max_value();\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    [(0, \"\", std::i128::MAX)];\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    (i32::max_value());\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    assert_eq!(0, -(i32::max_value()));\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    (std::i128::MAX);\n    //~^ ERROR: usage of a legacy numeric constant\n    //~| HELP: use the associated constant instead\n    (<u32>::max_value());\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    ((i32::max_value)());\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n    type Ω = i32;\n    Ω::max_value();\n    //~^ ERROR: usage of a legacy numeric method\n    //~| HELP: use the associated constant instead\n}\n\n#[warn(clippy::legacy_numeric_constants)]\nfn ext() {\n    external! {\n        ::std::primitive::u8::MIN;\n        ::std::u8::MIN;\n        ::std::primitive::u8::min_value();\n        use std::u64;\n        use std::u8::MIN;\n    }\n}\n\n#[allow(clippy::legacy_numeric_constants)]\nfn allow() {\n    ::std::primitive::u8::MIN;\n    ::std::u8::MIN;\n    ::std::primitive::u8::min_value();\n    use std::u8::MIN;\n    use std::u64;\n}\n\n#[warn(clippy::legacy_numeric_constants)]\n#[clippy::msrv = \"1.42.0\"]\nfn msrv_too_low() {\n    std::u32::MAX;\n}\n\n#[warn(clippy::legacy_numeric_constants)]\n#[clippy::msrv = \"1.43.0\"]\nfn msrv_juust_right() {\n    std::u32::MAX;\n    //~^ ERROR: usage of a legacy numeric constant\n}\n"
  },
  {
    "path": "tests/ui/legacy_numeric_constants.stderr",
    "content": "error: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:32:5\n   |\nLL |     std::f32::EPSILON;\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::legacy_numeric_constants)]`\nhelp: use the associated constant instead\n   |\nLL -     std::f32::EPSILON;\nLL +     f32::EPSILON;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:35:5\n   |\nLL |     std::u8::MIN;\n   |     ^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     std::u8::MIN;\nLL +     u8::MIN;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:38:5\n   |\nLL |     std::usize::MIN;\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     std::usize::MIN;\nLL +     usize::MIN;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:41:5\n   |\nLL |     std::u32::MAX;\n   |     ^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     std::u32::MAX;\nLL +     u32::MAX;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:44:5\n   |\nLL |     core::u32::MAX;\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     core::u32::MAX;\nLL +     u32::MAX;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:47:5\n   |\nLL |     MAX;\n   |     ^^^\n   |\nhelp: use the associated constant instead\n   |\nLL |     u32::MAX;\n   |     +++++\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:50:5\n   |\nLL |     i32::max_value();\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     i32::max_value();\nLL +     i32::MAX;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:53:5\n   |\nLL |     u8::max_value();\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     u8::max_value();\nLL +     u8::MAX;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:56:5\n   |\nLL |     u8::min_value();\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     u8::min_value();\nLL +     u8::MIN;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:59:5\n   |\nLL |     ::std::u8::MIN;\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     ::std::u8::MIN;\nLL +     u8::MIN;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:62:5\n   |\nLL |     ::std::primitive::u8::min_value();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     ::std::primitive::u8::min_value();\nLL +     ::std::primitive::u8::MIN;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:65:5\n   |\nLL |     std::primitive::i32::max_value();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     std::primitive::i32::max_value();\nLL +     std::primitive::i32::MAX;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:68:5\n   |\nLL |     self::a::u128::MAX;\n   |     ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     self::a::u128::MAX;\nLL +     u128::MAX;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:18:25\n   |\nLL |                 let x = std::u64::MAX;\n   |                         ^^^^^^^^^^^^^\n...\nLL |     b!();\n   |     ---- in this macro invocation\n   |\n   = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: use the associated constant instead\n   |\nLL -                 let x = std::u64::MAX;\nLL +                 let x = u64::MAX;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:82:5\n   |\nLL |     <std::primitive::i32>::max_value();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     <std::primitive::i32>::max_value();\nLL +     std::primitive::i32::MAX;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:85:14\n   |\nLL |     [(0, \"\", std::i128::MAX)];\n   |              ^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     [(0, \"\", std::i128::MAX)];\nLL +     [(0, \"\", i128::MAX)];\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:88:5\n   |\nLL |     (i32::max_value());\n   |     ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     (i32::max_value());\nLL +     i32::MAX;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:91:20\n   |\nLL |     assert_eq!(0, -(i32::max_value()));\n   |                    ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     assert_eq!(0, -(i32::max_value()));\nLL +     assert_eq!(0, -i32::MAX);\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:94:5\n   |\nLL |     (std::i128::MAX);\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     (std::i128::MAX);\nLL +     i128::MAX;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:97:5\n   |\nLL |     (<u32>::max_value());\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     (<u32>::max_value());\nLL +     u32::MAX;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:100:5\n   |\nLL |     ((i32::max_value)());\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     ((i32::max_value)());\nLL +     i32::MAX;\n   |\n\nerror: usage of a legacy numeric method\n  --> tests/ui/legacy_numeric_constants.rs:104:5\n   |\nLL |     Ω::max_value();\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     Ω::max_value();\nLL +     Ω::MAX;\n   |\n\nerror: usage of a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants.rs:138:5\n   |\nLL |     std::u32::MAX;\n   |     ^^^^^^^^^^^^^\n   |\nhelp: use the associated constant instead\n   |\nLL -     std::u32::MAX;\nLL +     u32::MAX;\n   |\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/legacy_numeric_constants_unfixable.rs",
    "content": "//@no-rustfix\n//@require-annotations-for-level: WARN\n//@aux-build:proc_macros.rs\n#![allow(clippy::no_effect, deprecated, unused)]\n#![warn(clippy::legacy_numeric_constants)]\n\n#[macro_use]\nextern crate proc_macros;\n\nuse std::u128 as _;\n//~^ ERROR: importing legacy numeric constants\n//~| HELP: remove this import\npub mod a {\n    pub use std::{mem, u128};\n    //~^ ERROR: importing legacy numeric constants\n    //~| HELP: remove this import\n}\n\nmacro_rules! b {\n    () => {\n        mod b {\n            use std::u32;\n            //~^ ERROR: importing legacy numeric constants\n            //~| HELP: remove this import\n        }\n    };\n}\n\nfn main() {\n    use std::u32::MAX;\n    //~^ ERROR: importing a legacy numeric constant\n    //~| HELP: remove this import and use the associated constant `u32::MAX`\n    use std::u8::MIN;\n    //~^ ERROR: importing a legacy numeric constant\n    //~| HELP: remove this import and use the associated constant `u8::MIN`\n    f64::MAX;\n    use std::u32;\n    //~^ ERROR: importing legacy numeric constants\n    //~| HELP: remove this import\n    u32::MAX;\n    use std::f32::MIN_POSITIVE;\n    //~^ ERROR: importing a legacy numeric constant\n    //~| HELP: remove this import and use the associated constant `f32::MIN_POSITIVE`\n    use std::f64;\n    use std::i16::*;\n    //~^ ERROR: importing legacy numeric constants\n    //~| HELP: remove this import and use associated constants `i16::<CONST>`\n    u128::MAX;\n    f32::EPSILON;\n    f64::EPSILON;\n    ::std::primitive::u8::MIN;\n    std::f32::consts::E;\n    f64::consts::E;\n    u8::MIN;\n    std::f32::consts::E;\n    f64::consts::E;\n    b!();\n}\n\nfn ext() {\n    external! {\n        ::std::primitive::u8::MIN;\n        ::std::u8::MIN;\n        ::std::primitive::u8::min_value();\n        use std::u64;\n        use std::u8::MIN;\n    }\n}\n\n#[clippy::msrv = \"1.42.0\"]\nfn msrv_too_low() {\n    use std::u32::MAX;\n}\n\n#[clippy::msrv = \"1.43.0\"]\nfn msrv_juust_right() {\n    use std::u32::MAX;\n    //~^ ERROR: importing a legacy numeric constant\n}\n\nmacro_rules! foo {\n    ($a: ty) => {\n        let _ = <$a>::max_value();\n        let _ = (<$a>::max_value)();\n    };\n}\n\nfn issue15805() {\n    foo!(u8);\n}\n"
  },
  {
    "path": "tests/ui/legacy_numeric_constants_unfixable.stderr",
    "content": "error: importing legacy numeric constants\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:10:5\n   |\nLL | use std::u128 as _;\n   |     ^^^^^^^^^\n   |\n   = help: remove this import\n   = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::legacy_numeric_constants)]`\n\nerror: importing legacy numeric constants\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:14:24\n   |\nLL |     pub use std::{mem, u128};\n   |                        ^^^^\n   |\n   = help: remove this import\n   = note: then `u128::<CONST>` will resolve to the respective associated constant\n\nerror: importing a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:30:9\n   |\nLL |     use std::u32::MAX;\n   |         ^^^^^^^^^^^^^\n   |\n   = help: remove this import and use the associated constant `u32::MAX` from the primitive type instead\n\nerror: importing a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:33:9\n   |\nLL |     use std::u8::MIN;\n   |         ^^^^^^^^^^^^\n   |\n   = help: remove this import and use the associated constant `u8::MIN` from the primitive type instead\n\nerror: importing legacy numeric constants\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:37:9\n   |\nLL |     use std::u32;\n   |         ^^^^^^^^\n   |\n   = help: remove this import\n   = note: then `u32::<CONST>` will resolve to the respective associated constant\n\nerror: importing a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:41:9\n   |\nLL |     use std::f32::MIN_POSITIVE;\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove this import and use the associated constant `f32::MIN_POSITIVE` from the primitive type instead\n\nerror: importing legacy numeric constants\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:45:9\n   |\nLL |     use std::i16::*;\n   |         ^^^^^^^^\n   |\n   = help: remove this import and use associated constants `i16::<CONST>` from the primitive type instead\n\nerror: importing legacy numeric constants\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:22:17\n   |\nLL |             use std::u32;\n   |                 ^^^^^^^^\n...\nLL |     b!();\n   |     ---- in this macro invocation\n   |\n   = help: remove this import\n   = note: then `u32::<CONST>` will resolve to the respective associated constant\n   = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: importing a legacy numeric constant\n  --> tests/ui/legacy_numeric_constants_unfixable.rs:77:9\n   |\nLL |     use std::u32::MAX;\n   |         ^^^^^^^^^^^^^\n   |\n   = help: remove this import and use the associated constant `u32::MAX` from the primitive type instead\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/len_without_is_empty.rs",
    "content": "#![warn(clippy::len_without_is_empty)]\n#![allow(dead_code, unused)]\n\npub struct PubOne;\n\nimpl PubOne {\n    pub fn len(&self) -> isize {\n        //~^ len_without_is_empty\n\n        1\n    }\n}\n\nimpl PubOne {\n    // A second impl for this struct -- the error span shouldn't mention this.\n    pub fn irrelevant(&self) -> bool {\n        false\n    }\n}\n\n// Identical to `PubOne`, but with an `allow` attribute on the impl complaining `len`.\npub struct PubAllowed;\n\n#[allow(clippy::len_without_is_empty)]\nimpl PubAllowed {\n    pub fn len(&self) -> isize {\n        1\n    }\n}\n\n// No `allow` attribute on this impl block, but that doesn't matter -- we only require one on the\n// impl containing `len`.\nimpl PubAllowed {\n    pub fn irrelevant(&self) -> bool {\n        false\n    }\n}\n\npub struct PubAllowedFn;\n\nimpl PubAllowedFn {\n    #[allow(clippy::len_without_is_empty)]\n    pub fn len(&self) -> isize {\n        1\n    }\n}\n\n#[allow(clippy::len_without_is_empty)]\npub struct PubAllowedStruct;\n\nimpl PubAllowedStruct {\n    pub fn len(&self) -> isize {\n        1\n    }\n}\n\npub trait PubTraitsToo {\n    //~^ len_without_is_empty\n\n    fn len(&self) -> isize;\n}\n\nimpl PubTraitsToo for One {\n    fn len(&self) -> isize {\n        0\n    }\n}\n\npub struct HasIsEmpty;\n\nimpl HasIsEmpty {\n    pub fn len(&self) -> isize {\n        //~^ len_without_is_empty\n\n        1\n    }\n\n    fn is_empty(&self) -> bool {\n        false\n    }\n}\n\npub struct HasWrongIsEmpty;\n\nimpl HasWrongIsEmpty {\n    pub fn len(&self) -> isize {\n        //~^ len_without_is_empty\n\n        1\n    }\n\n    pub fn is_empty(&self, x: u32) -> bool {\n        false\n    }\n}\n\npub struct MismatchedSelf;\n\nimpl MismatchedSelf {\n    pub fn len(self) -> isize {\n        //~^ len_without_is_empty\n\n        1\n    }\n\n    pub fn is_empty(&self) -> bool {\n        false\n    }\n}\n\nstruct NotPubOne;\n\nimpl NotPubOne {\n    pub fn len(&self) -> isize {\n        // No error; `len` is pub but `NotPubOne` is not exported anyway.\n        1\n    }\n}\n\nstruct One;\n\nimpl One {\n    fn len(&self) -> isize {\n        // No error; `len` is private; see issue #1085.\n        1\n    }\n}\n\ntrait TraitsToo {\n    fn len(&self) -> isize;\n    // No error; `len` is private; see issue #1085.\n}\n\nimpl TraitsToo for One {\n    fn len(&self) -> isize {\n        0\n    }\n}\n\nstruct HasPrivateIsEmpty;\n\nimpl HasPrivateIsEmpty {\n    pub fn len(&self) -> isize {\n        1\n    }\n\n    fn is_empty(&self) -> bool {\n        false\n    }\n}\n\nstruct Wither;\n\npub trait WithIsEmpty {\n    fn len(&self) -> isize;\n    fn is_empty(&self) -> bool;\n}\n\nimpl WithIsEmpty for Wither {\n    fn len(&self) -> isize {\n        1\n    }\n\n    fn is_empty(&self) -> bool {\n        false\n    }\n}\n\npub trait Empty {\n    fn is_empty(&self) -> bool;\n}\n\npub trait InheritingEmpty: Empty {\n    // Must not trigger `LEN_WITHOUT_IS_EMPTY`.\n    fn len(&self) -> isize;\n}\n\n// This used to ICE.\npub trait Foo: Sized {}\n\npub trait DependsOnFoo: Foo {\n    //~^ len_without_is_empty\n\n    fn len(&mut self) -> usize;\n}\n\n// issue #1562\npub struct MultipleImpls;\n\nimpl MultipleImpls {\n    pub fn len(&self) -> usize {\n        1\n    }\n}\n\nimpl MultipleImpls {\n    pub fn is_empty(&self) -> bool {\n        false\n    }\n}\n\n// issue #6958\npub struct OptionalLen;\n\nimpl OptionalLen {\n    pub fn len(&self) -> Option<usize> {\n        Some(0)\n    }\n\n    pub fn is_empty(&self) -> Option<bool> {\n        Some(true)\n    }\n}\n\npub struct OptionalLen2;\nimpl OptionalLen2 {\n    pub fn len(&self) -> Option<usize> {\n        Some(0)\n    }\n\n    pub fn is_empty(&self) -> bool {\n        true\n    }\n}\n\npub struct OptionalLen3;\nimpl OptionalLen3 {\n    pub fn len(&self) -> usize {\n        //~^ len_without_is_empty\n\n        0\n    }\n\n    // should lint, len is not an option\n    pub fn is_empty(&self) -> Option<bool> {\n        None\n    }\n}\n\npub struct ResultLen;\nimpl ResultLen {\n    pub fn len(&self) -> Result<usize, ()> {\n        //~^ len_without_is_empty\n        //~| result_unit_err\n\n        Ok(0)\n    }\n\n    // Differing result types\n    pub fn is_empty(&self) -> Option<bool> {\n        Some(true)\n    }\n}\n\npub struct ResultLen2;\nimpl ResultLen2 {\n    pub fn len(&self) -> Result<usize, ()> {\n        //~^ result_unit_err\n\n        Ok(0)\n    }\n\n    pub fn is_empty(&self) -> Result<bool, ()> {\n        //~^ result_unit_err\n\n        Ok(true)\n    }\n}\n\npub struct ResultLen3;\nimpl ResultLen3 {\n    pub fn len(&self) -> Result<usize, ()> {\n        //~^ result_unit_err\n\n        Ok(0)\n    }\n\n    // Non-fallible result is ok.\n    pub fn is_empty(&self) -> bool {\n        true\n    }\n}\n\npub struct OddLenSig;\nimpl OddLenSig {\n    // don't lint\n    pub fn len(&self) -> bool {\n        true\n    }\n}\n\n// issue #6958\npub struct AsyncLen;\nimpl AsyncLen {\n    async fn async_task(&self) -> bool {\n        true\n    }\n\n    pub async fn len(&self) -> usize {\n        usize::from(!self.async_task().await)\n    }\n\n    pub async fn is_empty(&self) -> bool {\n        self.len().await == 0\n    }\n}\n\n// issue #7232\npub struct AsyncLenWithoutIsEmpty;\nimpl AsyncLenWithoutIsEmpty {\n    pub async fn async_task(&self) -> bool {\n        true\n    }\n\n    pub async fn len(&self) -> usize {\n        //~^ len_without_is_empty\n\n        usize::from(!self.async_task().await)\n    }\n}\n\n// issue #7232\npub struct AsyncOptionLenWithoutIsEmpty;\nimpl AsyncOptionLenWithoutIsEmpty {\n    async fn async_task(&self) -> bool {\n        true\n    }\n\n    pub async fn len(&self) -> Option<usize> {\n        //~^ len_without_is_empty\n\n        None\n    }\n}\n\n// issue #7232\npub struct AsyncOptionLenNonIntegral;\nimpl AsyncOptionLenNonIntegral {\n    // don't lint\n    pub async fn len(&self) -> Option<String> {\n        None\n    }\n}\n\n// issue #7232\npub struct AsyncResultLenWithoutIsEmpty;\nimpl AsyncResultLenWithoutIsEmpty {\n    async fn async_task(&self) -> bool {\n        true\n    }\n\n    pub async fn len(&self) -> Result<usize, ()> {\n        //~^ len_without_is_empty\n\n        Err(())\n    }\n}\n\n// issue #7232\npub struct AsyncOptionLen;\nimpl AsyncOptionLen {\n    async fn async_task(&self) -> bool {\n        true\n    }\n\n    pub async fn len(&self) -> Result<usize, ()> {\n        Err(())\n    }\n\n    pub async fn is_empty(&self) -> bool {\n        true\n    }\n}\n\npub struct AsyncLenSyncIsEmpty;\nimpl AsyncLenSyncIsEmpty {\n    pub async fn len(&self) -> u32 {\n        0\n    }\n\n    pub fn is_empty(&self) -> bool {\n        true\n    }\n}\n\n// issue #9520\npub struct NonStandardLen;\nimpl NonStandardLen {\n    // don't lint\n    pub fn len(&self, something: usize) -> usize {\n        something\n    }\n}\n\n// issue #9520\npub struct NonStandardLenAndIsEmptySignature;\nimpl NonStandardLenAndIsEmptySignature {\n    // don't lint\n    pub fn len(&self, something: usize) -> usize {\n        something\n    }\n\n    pub fn is_empty(&self, something: usize) -> bool {\n        something == 0\n    }\n}\n\n// test case for #9520 with generics in the function signature\npub trait TestResource {\n    type NonStandardSignatureWithGenerics: Copy;\n    fn lookup_content(&self, item: Self::NonStandardSignatureWithGenerics) -> Result<Option<&[u8]>, String>;\n}\npub struct NonStandardSignatureWithGenerics(u32);\nimpl NonStandardSignatureWithGenerics {\n    pub fn is_empty<T, U>(self, resource: &T) -> bool\n    where\n        T: TestResource<NonStandardSignatureWithGenerics = U>,\n        U: Copy + From<NonStandardSignatureWithGenerics>,\n    {\n        if let Ok(Some(content)) = resource.lookup_content(self.into()) {\n            content.is_empty()\n        } else {\n            true\n        }\n    }\n\n    // test case for #9520 with generics in the function signature\n    pub fn len<T, U>(self, resource: &T) -> usize\n    where\n        T: TestResource<NonStandardSignatureWithGenerics = U>,\n        U: Copy + From<NonStandardSignatureWithGenerics>,\n    {\n        if let Ok(Some(content)) = resource.lookup_content(self.into()) {\n            content.len()\n        } else {\n            0_usize\n        }\n    }\n}\n\npub struct DifferingErrors;\nimpl DifferingErrors {\n    pub fn len(&self) -> Result<usize, u8> {\n        Ok(0)\n    }\n\n    pub fn is_empty(&self) -> Result<bool, u16> {\n        Ok(true)\n    }\n}\n\n// Issue #11165\npub struct Aliased1;\npub type Alias1 = Aliased1;\n\nimpl Alias1 {\n    pub fn len(&self) -> usize {\n        todo!()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        todo!()\n    }\n}\n\npub struct Aliased2;\npub type Alias2 = Aliased2;\nimpl Alias2 {\n    pub fn len(&self) -> usize {\n        //~^ len_without_is_empty\n\n        todo!()\n    }\n}\n\n// Issue #16190\npub struct RefMutLenButRefIsEmpty;\nimpl RefMutLenButRefIsEmpty {\n    pub fn len(&mut self) -> usize {\n        todo!()\n    }\n\n    pub fn is_empty(&self) -> bool {\n        todo!()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/len_without_is_empty.stderr",
    "content": "error: struct `PubOne` has a public `len` method, but no `is_empty` method\n  --> tests/ui/len_without_is_empty.rs:7:5\n   |\nLL |     pub fn len(&self) -> isize {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::len-without-is-empty` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::len_without_is_empty)]`\n\nerror: trait `PubTraitsToo` has a `len` method but no (possibly inherited) `is_empty` method\n  --> tests/ui/len_without_is_empty.rs:57:1\n   |\nLL | / pub trait PubTraitsToo {\nLL | |\nLL | |\nLL | |     fn len(&self) -> isize;\nLL | | }\n   | |_^\n\nerror: struct `HasIsEmpty` has a public `len` method, but a private `is_empty` method\n  --> tests/ui/len_without_is_empty.rs:72:5\n   |\nLL |     pub fn len(&self) -> isize {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `is_empty` defined here\n  --> tests/ui/len_without_is_empty.rs:78:5\n   |\nLL |     fn is_empty(&self) -> bool {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: struct `HasWrongIsEmpty` has a public `len` method, but the `is_empty` method has an unexpected signature\n  --> tests/ui/len_without_is_empty.rs:86:5\n   |\nLL |     pub fn len(&self) -> isize {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `is_empty` defined here\n  --> tests/ui/len_without_is_empty.rs:92:5\n   |\nLL |     pub fn is_empty(&self, x: u32) -> bool {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: expected signature: `(&self) -> bool`\n\nerror: struct `MismatchedSelf` has a public `len` method, but the `is_empty` method has an unexpected signature\n  --> tests/ui/len_without_is_empty.rs:100:5\n   |\nLL |     pub fn len(self) -> isize {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `is_empty` defined here\n  --> tests/ui/len_without_is_empty.rs:106:5\n   |\nLL |     pub fn is_empty(&self) -> bool {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: expected signature: `(self) -> bool`\n\nerror: trait `DependsOnFoo` has a `len` method but no (possibly inherited) `is_empty` method\n  --> tests/ui/len_without_is_empty.rs:181:1\n   |\nLL | / pub trait DependsOnFoo: Foo {\nLL | |\nLL | |\nLL | |     fn len(&mut self) -> usize;\nLL | | }\n   | |_^\n\nerror: struct `OptionalLen3` has a public `len` method, but the `is_empty` method has an unexpected signature\n  --> tests/ui/len_without_is_empty.rs:228:5\n   |\nLL |     pub fn len(&self) -> usize {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `is_empty` defined here\n  --> tests/ui/len_without_is_empty.rs:235:5\n   |\nLL |     pub fn is_empty(&self) -> Option<bool> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: expected signature: `(&self) -> bool`\n\nerror: struct `ResultLen` has a public `len` method, but the `is_empty` method has an unexpected signature\n  --> tests/ui/len_without_is_empty.rs:242:5\n   |\nLL |     pub fn len(&self) -> Result<usize, ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `is_empty` defined here\n  --> tests/ui/len_without_is_empty.rs:250:5\n   |\nLL |     pub fn is_empty(&self) -> Option<bool> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: expected signature: `(&self) -> bool` or `(&self) -> Result<bool>\n\nerror: this returns a `Result<_, ()>`\n  --> tests/ui/len_without_is_empty.rs:242:5\n   |\nLL |     pub fn len(&self) -> Result<usize, ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n   = note: `-D clippy::result-unit-err` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]`\n\nerror: this returns a `Result<_, ()>`\n  --> tests/ui/len_without_is_empty.rs:257:5\n   |\nLL |     pub fn len(&self) -> Result<usize, ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n\nerror: this returns a `Result<_, ()>`\n  --> tests/ui/len_without_is_empty.rs:263:5\n   |\nLL |     pub fn is_empty(&self) -> Result<bool, ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n\nerror: this returns a `Result<_, ()>`\n  --> tests/ui/len_without_is_empty.rs:272:5\n   |\nLL |     pub fn len(&self) -> Result<usize, ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n\nerror: struct `AsyncLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method\n  --> tests/ui/len_without_is_empty.rs:315:5\n   |\nLL |     pub async fn len(&self) -> usize {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: struct `AsyncOptionLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method\n  --> tests/ui/len_without_is_empty.rs:329:5\n   |\nLL |     pub async fn len(&self) -> Option<usize> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method\n  --> tests/ui/len_without_is_empty.rs:352:5\n   |\nLL |     pub async fn len(&self) -> Result<usize, ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `Alias2` has a public `len` method, but no `is_empty` method\n  --> tests/ui/len_without_is_empty.rs:469:5\n   |\nLL |     pub fn len(&self) -> usize {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/len_without_is_empty_expect.rs",
    "content": "#![allow(clippy::len_without_is_empty)]\n\n// Check that the lint expectation is fulfilled even if the lint is allowed at the type level.\npub struct Empty;\n\nimpl Empty {\n    #[expect(clippy::len_without_is_empty)]\n    pub fn len(&self) -> usize {\n        0\n    }\n}\n\n// Check that the lint expectation is not triggered if it should not\npub struct Empty2;\n\nimpl Empty2 {\n    #[expect(clippy::len_without_is_empty)] //~ ERROR: this lint expectation is unfulfilled\n    pub fn len(&self) -> usize {\n        0\n    }\n\n    pub fn is_empty(&self) -> bool {\n        false\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/len_without_is_empty_expect.stderr",
    "content": "error: this lint expectation is unfulfilled\n  --> tests/ui/len_without_is_empty_expect.rs:17:14\n   |\nLL |     #[expect(clippy::len_without_is_empty)]\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D unfulfilled-lint-expectations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(unfulfilled_lint_expectations)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/len_zero.fixed",
    "content": "#![warn(clippy::len_zero)]\n#![allow(\n    dead_code,\n    unused,\n    clippy::needless_ifs,\n    clippy::len_without_is_empty,\n    clippy::const_is_empty\n)]\n\nextern crate core;\nuse core::ops::Deref;\n\npub struct One;\nstruct Wither;\n\ntrait TraitsToo {\n    fn len(&self) -> isize;\n    // No error; `len` is private; see issue #1085.\n}\n\nimpl TraitsToo for One {\n    fn len(&self) -> isize {\n        0\n    }\n}\n\npub struct HasIsEmpty;\n\nimpl HasIsEmpty {\n    pub fn len(&self) -> isize {\n        1\n    }\n\n    fn is_empty(&self) -> bool {\n        false\n    }\n}\n\npub struct HasWrongIsEmpty;\n\nimpl HasWrongIsEmpty {\n    pub fn len(&self) -> isize {\n        1\n    }\n\n    pub fn is_empty(&self, x: u32) -> bool {\n        false\n    }\n}\n\npub trait WithIsEmpty {\n    fn len(&self) -> isize;\n    fn is_empty(&self) -> bool;\n}\n\nimpl WithIsEmpty for Wither {\n    fn len(&self) -> isize {\n        1\n    }\n\n    fn is_empty(&self) -> bool {\n        false\n    }\n}\n\nstruct DerefToDerefToString;\n\nimpl Deref for DerefToDerefToString {\n    type Target = DerefToString;\n\n    fn deref(&self) -> &Self::Target {\n        &DerefToString {}\n    }\n}\n\nstruct DerefToString;\n\nimpl Deref for DerefToString {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"Hello, world!\"\n    }\n}\n\nfn main() {\n    let x = [1, 2];\n    if x.is_empty() {\n        //~^ len_zero\n        println!(\"This should not happen!\");\n    }\n\n    if \"\".is_empty() {}\n    //~^ len_zero\n\n    let s = \"Hello, world!\";\n    let s1 = &s;\n    let s2 = &s1;\n    let s3 = &s2;\n    let s4 = &s3;\n    let s5 = &s4;\n    let s6 = &s5;\n    println!(\"{}\", s1.is_empty());\n    //~^ comparison_to_empty\n    println!(\"{}\", s2.is_empty());\n    //~^ comparison_to_empty\n    println!(\"{}\", s3.is_empty());\n    //~^ comparison_to_empty\n    println!(\"{}\", s4.is_empty());\n    //~^ comparison_to_empty\n    println!(\"{}\", s5.is_empty());\n    //~^ comparison_to_empty\n    println!(\"{}\", (s6).is_empty());\n    //~^ comparison_to_empty\n\n    let d2s = DerefToDerefToString {};\n    println!(\"{}\", (**d2s).is_empty());\n    //~^ comparison_to_empty\n\n    println!(\"{}\", std::borrow::Cow::Borrowed(\"\").is_empty());\n    //~^ comparison_to_empty\n\n    let y = One;\n    if y.len() == 0 {\n        // No error; `One` does not have `.is_empty()`.\n        println!(\"This should not happen either!\");\n    }\n\n    let z: &dyn TraitsToo = &y;\n    if z.len() > 0 {\n        // No error; `TraitsToo` has no `.is_empty()` method.\n        println!(\"Nor should this!\");\n    }\n\n    let has_is_empty = HasIsEmpty;\n    if has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if !has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if !has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if !has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if has_is_empty.len() > 1 {\n        // No error.\n        println!(\"This can happen.\");\n    }\n    if has_is_empty.len() <= 1 {\n        // No error.\n        println!(\"This can happen.\");\n    }\n    if has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if !has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if !has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if !has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if has_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if 1 < has_is_empty.len() {\n        // No error.\n        println!(\"This can happen.\");\n    }\n    if 1 >= has_is_empty.len() {\n        // No error.\n        println!(\"This can happen.\");\n    }\n    assert!(!has_is_empty.is_empty());\n\n    let with_is_empty: &dyn WithIsEmpty = &Wither;\n    if with_is_empty.is_empty() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    assert!(!with_is_empty.is_empty());\n\n    let has_wrong_is_empty = HasWrongIsEmpty;\n    if has_wrong_is_empty.len() == 0 {\n        // No error; `HasWrongIsEmpty` does not have `.is_empty()`.\n        println!(\"Or this!\");\n    }\n\n    // issue #10529\n    (!has_is_empty.is_empty()).then(|| println!(\"This can happen.\"));\n    //~^ len_zero\n    (has_is_empty.is_empty()).then(|| println!(\"Or this!\"));\n    //~^ len_zero\n}\n\nfn test_slice(b: &[u8]) {\n    if !b.is_empty() {}\n    //~^ len_zero\n}\n\n// issue #11992\nfn binop_with_macros() {\n    macro_rules! len {\n        ($seq:ident) => {\n            $seq.len()\n        };\n    }\n\n    macro_rules! compare_to {\n        ($val:literal) => {\n            $val\n        };\n        ($val:expr) => {{ $val }};\n    }\n\n    macro_rules! zero {\n        () => {\n            0\n        };\n    }\n\n    let has_is_empty = HasIsEmpty;\n    // Don't lint, suggesting changes might break macro compatibility.\n    (len!(has_is_empty) > 0).then(|| println!(\"This can happen.\"));\n    // Don't lint, suggesting changes might break macro compatibility.\n    if len!(has_is_empty) == 0 {}\n    // Don't lint\n    if has_is_empty.len() == compare_to!(if true { 0 } else { 1 }) {}\n    // This is fine\n    if has_is_empty.len() == compare_to!(1) {}\n\n    if has_is_empty.is_empty() {}\n    //~^ len_zero\n    if has_is_empty.is_empty() {}\n    //~^ len_zero\n\n    (!has_is_empty.is_empty()).then(|| println!(\"This can happen.\"));\n    //~^ len_zero\n}\n\nfn no_infinite_recursion() -> bool {\n    struct S;\n\n    impl Deref for S {\n        type Target = Self;\n        fn deref(&self) -> &Self::Target {\n            self\n        }\n    }\n\n    impl PartialEq<&'static str> for S {\n        fn eq(&self, _other: &&'static str) -> bool {\n            false\n        }\n    }\n\n    // Do not crash while checking if S implements `.is_empty()`\n    S == \"\"\n}\n\nfn issue15890(vertices: &mut dyn ExactSizeIterator<Item = u8>) -> bool {\n    vertices.len() == 0\n}\n"
  },
  {
    "path": "tests/ui/len_zero.rs",
    "content": "#![warn(clippy::len_zero)]\n#![allow(\n    dead_code,\n    unused,\n    clippy::needless_ifs,\n    clippy::len_without_is_empty,\n    clippy::const_is_empty\n)]\n\nextern crate core;\nuse core::ops::Deref;\n\npub struct One;\nstruct Wither;\n\ntrait TraitsToo {\n    fn len(&self) -> isize;\n    // No error; `len` is private; see issue #1085.\n}\n\nimpl TraitsToo for One {\n    fn len(&self) -> isize {\n        0\n    }\n}\n\npub struct HasIsEmpty;\n\nimpl HasIsEmpty {\n    pub fn len(&self) -> isize {\n        1\n    }\n\n    fn is_empty(&self) -> bool {\n        false\n    }\n}\n\npub struct HasWrongIsEmpty;\n\nimpl HasWrongIsEmpty {\n    pub fn len(&self) -> isize {\n        1\n    }\n\n    pub fn is_empty(&self, x: u32) -> bool {\n        false\n    }\n}\n\npub trait WithIsEmpty {\n    fn len(&self) -> isize;\n    fn is_empty(&self) -> bool;\n}\n\nimpl WithIsEmpty for Wither {\n    fn len(&self) -> isize {\n        1\n    }\n\n    fn is_empty(&self) -> bool {\n        false\n    }\n}\n\nstruct DerefToDerefToString;\n\nimpl Deref for DerefToDerefToString {\n    type Target = DerefToString;\n\n    fn deref(&self) -> &Self::Target {\n        &DerefToString {}\n    }\n}\n\nstruct DerefToString;\n\nimpl Deref for DerefToString {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"Hello, world!\"\n    }\n}\n\nfn main() {\n    let x = [1, 2];\n    if x.len() == 0 {\n        //~^ len_zero\n        println!(\"This should not happen!\");\n    }\n\n    if \"\".len() == 0 {}\n    //~^ len_zero\n\n    let s = \"Hello, world!\";\n    let s1 = &s;\n    let s2 = &s1;\n    let s3 = &s2;\n    let s4 = &s3;\n    let s5 = &s4;\n    let s6 = &s5;\n    println!(\"{}\", *s1 == \"\");\n    //~^ comparison_to_empty\n    println!(\"{}\", **s2 == \"\");\n    //~^ comparison_to_empty\n    println!(\"{}\", ***s3 == \"\");\n    //~^ comparison_to_empty\n    println!(\"{}\", ****s4 == \"\");\n    //~^ comparison_to_empty\n    println!(\"{}\", *****s5 == \"\");\n    //~^ comparison_to_empty\n    println!(\"{}\", ******(s6) == \"\");\n    //~^ comparison_to_empty\n\n    let d2s = DerefToDerefToString {};\n    println!(\"{}\", &**d2s == \"\");\n    //~^ comparison_to_empty\n\n    println!(\"{}\", std::borrow::Cow::Borrowed(\"\") == \"\");\n    //~^ comparison_to_empty\n\n    let y = One;\n    if y.len() == 0 {\n        // No error; `One` does not have `.is_empty()`.\n        println!(\"This should not happen either!\");\n    }\n\n    let z: &dyn TraitsToo = &y;\n    if z.len() > 0 {\n        // No error; `TraitsToo` has no `.is_empty()` method.\n        println!(\"Nor should this!\");\n    }\n\n    let has_is_empty = HasIsEmpty;\n    if has_is_empty.len() == 0 {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if has_is_empty.len() != 0 {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if has_is_empty.len() > 0 {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if has_is_empty.len() < 1 {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if has_is_empty.len() >= 1 {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if has_is_empty.len() > 1 {\n        // No error.\n        println!(\"This can happen.\");\n    }\n    if has_is_empty.len() <= 1 {\n        // No error.\n        println!(\"This can happen.\");\n    }\n    if 0 == has_is_empty.len() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if 0 != has_is_empty.len() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if 0 < has_is_empty.len() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if 1 <= has_is_empty.len() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if 1 > has_is_empty.len() {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    if 1 < has_is_empty.len() {\n        // No error.\n        println!(\"This can happen.\");\n    }\n    if 1 >= has_is_empty.len() {\n        // No error.\n        println!(\"This can happen.\");\n    }\n    assert!(!has_is_empty.is_empty());\n\n    let with_is_empty: &dyn WithIsEmpty = &Wither;\n    if with_is_empty.len() == 0 {\n        //~^ len_zero\n        println!(\"Or this!\");\n    }\n    assert!(!with_is_empty.is_empty());\n\n    let has_wrong_is_empty = HasWrongIsEmpty;\n    if has_wrong_is_empty.len() == 0 {\n        // No error; `HasWrongIsEmpty` does not have `.is_empty()`.\n        println!(\"Or this!\");\n    }\n\n    // issue #10529\n    (has_is_empty.len() > 0).then(|| println!(\"This can happen.\"));\n    //~^ len_zero\n    (has_is_empty.len() == 0).then(|| println!(\"Or this!\"));\n    //~^ len_zero\n}\n\nfn test_slice(b: &[u8]) {\n    if b.len() != 0 {}\n    //~^ len_zero\n}\n\n// issue #11992\nfn binop_with_macros() {\n    macro_rules! len {\n        ($seq:ident) => {\n            $seq.len()\n        };\n    }\n\n    macro_rules! compare_to {\n        ($val:literal) => {\n            $val\n        };\n        ($val:expr) => {{ $val }};\n    }\n\n    macro_rules! zero {\n        () => {\n            0\n        };\n    }\n\n    let has_is_empty = HasIsEmpty;\n    // Don't lint, suggesting changes might break macro compatibility.\n    (len!(has_is_empty) > 0).then(|| println!(\"This can happen.\"));\n    // Don't lint, suggesting changes might break macro compatibility.\n    if len!(has_is_empty) == 0 {}\n    // Don't lint\n    if has_is_empty.len() == compare_to!(if true { 0 } else { 1 }) {}\n    // This is fine\n    if has_is_empty.len() == compare_to!(1) {}\n\n    if has_is_empty.len() == compare_to!(0) {}\n    //~^ len_zero\n    if has_is_empty.len() == zero!() {}\n    //~^ len_zero\n\n    (compare_to!(0) < has_is_empty.len()).then(|| println!(\"This can happen.\"));\n    //~^ len_zero\n}\n\nfn no_infinite_recursion() -> bool {\n    struct S;\n\n    impl Deref for S {\n        type Target = Self;\n        fn deref(&self) -> &Self::Target {\n            self\n        }\n    }\n\n    impl PartialEq<&'static str> for S {\n        fn eq(&self, _other: &&'static str) -> bool {\n            false\n        }\n    }\n\n    // Do not crash while checking if S implements `.is_empty()`\n    S == \"\"\n}\n\nfn issue15890(vertices: &mut dyn ExactSizeIterator<Item = u8>) -> bool {\n    vertices.len() == 0\n}\n"
  },
  {
    "path": "tests/ui/len_zero.stderr",
    "content": "error: length comparison to zero\n  --> tests/ui/len_zero.rs:88:8\n   |\nLL |     if x.len() == 0 {\n   |        ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `x.is_empty()`\n   |\n   = note: `-D clippy::len-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::len_zero)]`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:93:8\n   |\nLL |     if \"\".len() == 0 {}\n   |        ^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `\"\".is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/len_zero.rs:103:20\n   |\nLL |     println!(\"{}\", *s1 == \"\");\n   |                    ^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s1.is_empty()`\n   |\n   = note: `-D clippy::comparison-to-empty` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::comparison_to_empty)]`\n\nerror: comparison to empty slice\n  --> tests/ui/len_zero.rs:105:20\n   |\nLL |     println!(\"{}\", **s2 == \"\");\n   |                    ^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s2.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/len_zero.rs:107:20\n   |\nLL |     println!(\"{}\", ***s3 == \"\");\n   |                    ^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s3.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/len_zero.rs:109:20\n   |\nLL |     println!(\"{}\", ****s4 == \"\");\n   |                    ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s4.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/len_zero.rs:111:20\n   |\nLL |     println!(\"{}\", *****s5 == \"\");\n   |                    ^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s5.is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/len_zero.rs:113:20\n   |\nLL |     println!(\"{}\", ******(s6) == \"\");\n   |                    ^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(s6).is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/len_zero.rs:117:20\n   |\nLL |     println!(\"{}\", &**d2s == \"\");\n   |                    ^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(**d2s).is_empty()`\n\nerror: comparison to empty slice\n  --> tests/ui/len_zero.rs:120:20\n   |\nLL |     println!(\"{}\", std::borrow::Cow::Borrowed(\"\") == \"\");\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `std::borrow::Cow::Borrowed(\"\").is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:136:8\n   |\nLL |     if has_is_empty.len() == 0 {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:140:8\n   |\nLL |     if has_is_empty.len() != 0 {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:144:8\n   |\nLL |     if has_is_empty.len() > 0 {\n   |        ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`\n\nerror: length comparison to one\n  --> tests/ui/len_zero.rs:148:8\n   |\nLL |     if has_is_empty.len() < 1 {\n   |        ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`\n\nerror: length comparison to one\n  --> tests/ui/len_zero.rs:152:8\n   |\nLL |     if has_is_empty.len() >= 1 {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:164:8\n   |\nLL |     if 0 == has_is_empty.len() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:168:8\n   |\nLL |     if 0 != has_is_empty.len() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:172:8\n   |\nLL |     if 0 < has_is_empty.len() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`\n\nerror: length comparison to one\n  --> tests/ui/len_zero.rs:176:8\n   |\nLL |     if 1 <= has_is_empty.len() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`\n\nerror: length comparison to one\n  --> tests/ui/len_zero.rs:180:8\n   |\nLL |     if 1 > has_is_empty.len() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:195:8\n   |\nLL |     if with_is_empty.len() == 0 {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `with_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:208:6\n   |\nLL |     (has_is_empty.len() > 0).then(|| println!(\"This can happen.\"));\n   |      ^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:210:6\n   |\nLL |     (has_is_empty.len() == 0).then(|| println!(\"Or this!\"));\n   |      ^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:215:8\n   |\nLL |     if b.len() != 0 {}\n   |        ^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!b.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:250:8\n   |\nLL |     if has_is_empty.len() == compare_to!(0) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:252:8\n   |\nLL |     if has_is_empty.len() == zero!() {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero.rs:255:6\n   |\nLL |     (compare_to!(0) < has_is_empty.len()).then(|| println!(\"This can happen.\"));\n   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`\n\nerror: aborting due to 27 previous errors\n\n"
  },
  {
    "path": "tests/ui/len_zero_ranges.fixed",
    "content": "#![warn(clippy::len_zero)]\n#![allow(unused)]\n\n// Now that `Range(Inclusive)::is_empty` is stable (1.47), we can always suggest this\nmod issue_3807 {\n    fn suggestion_is_fine_range() {\n        let _ = (0..42).is_empty();\n        //~^ len_zero\n    }\n\n    fn suggestion_is_fine_range_inclusive() {\n        let _ = (0_u8..=42).is_empty();\n        //~^ len_zero\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/len_zero_ranges.rs",
    "content": "#![warn(clippy::len_zero)]\n#![allow(unused)]\n\n// Now that `Range(Inclusive)::is_empty` is stable (1.47), we can always suggest this\nmod issue_3807 {\n    fn suggestion_is_fine_range() {\n        let _ = (0..42).len() == 0;\n        //~^ len_zero\n    }\n\n    fn suggestion_is_fine_range_inclusive() {\n        let _ = (0_u8..=42).len() == 0;\n        //~^ len_zero\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/len_zero_ranges.stderr",
    "content": "error: length comparison to zero\n  --> tests/ui/len_zero_ranges.rs:7:17\n   |\nLL |         let _ = (0..42).len() == 0;\n   |                 ^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(0..42).is_empty()`\n   |\n   = note: `-D clippy::len-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::len_zero)]`\n\nerror: length comparison to zero\n  --> tests/ui/len_zero_ranges.rs:12:17\n   |\nLL |         let _ = (0_u8..=42).len() == 0;\n   |                 ^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `(0_u8..=42).is_empty()`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/len_zero_unstable.fixed",
    "content": "#![warn(clippy::len_zero)]\n#![feature(exact_size_is_empty)]\n\nfn issue15890(vertices: &mut dyn ExactSizeIterator<Item = u8>) -> bool {\n    vertices.is_empty()\n    //~^ len_zero\n}\n"
  },
  {
    "path": "tests/ui/len_zero_unstable.rs",
    "content": "#![warn(clippy::len_zero)]\n#![feature(exact_size_is_empty)]\n\nfn issue15890(vertices: &mut dyn ExactSizeIterator<Item = u8>) -> bool {\n    vertices.len() == 0\n    //~^ len_zero\n}\n"
  },
  {
    "path": "tests/ui/len_zero_unstable.stderr",
    "content": "error: length comparison to zero\n  --> tests/ui/len_zero_unstable.rs:5:5\n   |\nLL |     vertices.len() == 0\n   |     ^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `vertices.is_empty()`\n   |\n   = note: `-D clippy::len-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::len_zero)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/let_and_return.edition2021.fixed",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![allow(unused)]\n#![warn(clippy::let_and_return)]\n\nuse std::cell::RefCell;\n\nfn test() -> i32 {\n    let _y = 0; // no warning\n    \n    5\n    //~^ let_and_return\n}\n\nfn test_inner() -> i32 {\n    if true {\n        \n        5\n        //~^ let_and_return\n    } else {\n        0\n    }\n}\n\nfn test_nowarn_1() -> i32 {\n    let mut x = 5;\n    x += 1;\n    x\n}\n\nfn test_nowarn_2() -> i32 {\n    let x = 5;\n    x + 1\n}\n\nfn test_nowarn_3() -> (i32, i32) {\n    // this should technically warn, but we do not compare complex patterns\n    let (x, y) = (5, 9);\n    (x, y)\n}\n\nfn test_nowarn_4() -> i32 {\n    // this should technically warn, but not b/c of clippy::let_and_return, but b/c of useless type\n    let x: i32 = 5;\n    x\n}\n\nfn test_nowarn_5(x: i16) -> u16 {\n    #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]\n    let x = x as u16;\n    x\n}\n\n// False positive example\ntrait Decode {\n    fn decode<D: std::io::Read>(d: D) -> Result<Self, ()>\n    where\n        Self: Sized;\n}\n\nmacro_rules! tuple_encode {\n    ($($x:ident),*) => (\n        impl<$($x: Decode),*> Decode for ($($x),*) {\n            #[inline]\n            #[allow(non_snake_case)]\n            fn decode<D: std::io::Read>(mut d: D) -> Result<Self, ()> {\n                // Shouldn't trigger lint\n                Ok(($({let $x = Decode::decode(&mut d)?; $x }),*))\n            }\n        }\n    );\n}\n\nfn issue_3792() -> String {\n    use std::io::{self, BufRead, Stdin};\n\n    let stdin = io::stdin();\n    // `Stdin::lock` returns `StdinLock<'static>` so `line` doesn't borrow from `stdin`\n    // https://github.com/rust-lang/rust/pull/93965\n    \n    stdin.lock().lines().next().unwrap().unwrap()\n    //~^ let_and_return\n}\n\ntuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);\n\nmod no_lint_if_stmt_borrows {\n    use std::cell::RefCell;\n    use std::rc::{Rc, Weak};\n    struct Bar;\n\n    impl Bar {\n        fn new() -> Self {\n            Bar {}\n        }\n        fn baz(&self) -> u32 {\n            0\n        }\n    }\n\n    fn issue_3324(value: Weak<RefCell<Bar>>) -> u32 {\n        let value = value.upgrade().unwrap();\n        let ret = value.borrow().baz();\n        ret\n        //~[edition2024]^ let_and_return\n    }\n\n    fn borrows_in_closure(value: Weak<RefCell<Bar>>) -> u32 {\n        fn f(mut x: impl FnMut() -> u32) -> impl FnMut() -> u32 {\n            x\n        }\n\n        let value = value.upgrade().unwrap();\n        let ret = f(|| value.borrow().baz())();\n        ret\n        //~[edition2024]^ let_and_return\n    }\n\n    mod free_function {\n        struct Inner;\n\n        struct Foo<'a> {\n            inner: &'a Inner,\n        }\n\n        impl Drop for Foo<'_> {\n            fn drop(&mut self) {}\n        }\n\n        impl<'a> Foo<'a> {\n            fn new(inner: &'a Inner) -> Self {\n                Self { inner }\n            }\n\n            fn value(&self) -> i32 {\n                42\n            }\n        }\n\n        fn some_foo(inner: &Inner) -> Foo<'_> {\n            Foo { inner }\n        }\n\n        fn test() -> i32 {\n            let x = Inner {};\n            let value = some_foo(&x).value();\n            value\n            //~[edition2024]^ let_and_return\n        }\n\n        fn test2() -> i32 {\n            let x = Inner {};\n            let value = Foo::new(&x).value();\n            value\n            //~[edition2024]^ let_and_return\n        }\n    }\n}\n\nmod issue_5729 {\n    use std::sync::Arc;\n\n    trait Foo {}\n\n    trait FooStorage {\n        fn foo_cloned(&self) -> Arc<dyn Foo>;\n    }\n\n    struct FooStorageImpl<T: Foo> {\n        foo: Arc<T>,\n    }\n\n    impl<T: Foo + 'static> FooStorage for FooStorageImpl<T> {\n        fn foo_cloned(&self) -> Arc<dyn Foo> {\n            \n            (Arc::clone(&self.foo)) as _\n            //~^ let_and_return\n        }\n    }\n}\n\nmod issue_11335 {\n    pub enum E<T> {\n        A(T),\n        B(T),\n    }\n\n    impl<T> E<T> {\n        pub fn inner(&self) -> &T {\n            \n\n            (match self {\n                E::A(x) => x,\n                E::B(x) => x,\n            }) as _\n            //~^ let_and_return\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/11167\nmacro_rules! fn_in_macro {\n    ($b:block) => {\n        fn f() -> usize $b\n    }\n}\nfn_in_macro!({\n    return 1;\n});\n\nfn issue9150() -> usize {\n    let x = 1;\n    #[cfg(any())]\n    panic!(\"can't see me\");\n    x\n}\n\nfn issue12801() {\n    fn left_is_if() -> String {\n        \n        (if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\")\n        //~^ let_and_return\n    }\n\n    fn no_par_needed() -> String {\n        \n        \"c\".to_string() + if true { \"a\" } else { \"b\" }\n        //~^ let_and_return\n    }\n\n    fn conjunctive_blocks() -> String {\n        \n        ({ \"a\".to_string() } + \"b\" + { \"c\" } + \"d\")\n        //~^ let_and_return\n    }\n\n    #[allow(clippy::overly_complex_bool_expr)]\n    fn other_ops() {\n        let _ = || {\n            \n            (if true { 2 } else { 3 } << 4)\n            //~^ let_and_return\n        };\n        let _ = || {\n            \n            ({ true } || { false } && { 2 <= 3 })\n            //~^ let_and_return\n        };\n    }\n}\n\nfn issue14164() -> Result<u32, ()> {\n    let v = std::cell::RefCell::new(Some(vec![1]));\n    let r = match &*v.borrow() {\n        Some(v) => Ok(Ok(v[0])),\n        None => Ok(Ok(0)),\n    }?;\n    r\n    //~[edition2024]^ let_and_return\n}\n\nfn issue15987() -> i32 {\n    macro_rules! sample {\n        ( $( $args:expr ),+ ) => {};\n    }\n\n    let r = 5;\n    sample!(r);\n    r\n}\n\nfn has_comment() -> Vec<usize> {\n    let v = Vec::new();\n\n    // TODO: stuff\n\n    v\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/let_and_return.edition2021.stderr",
    "content": "error: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:13:5\n   |\nLL |     let x = 5;\n   |     ---------- unnecessary `let` binding\nLL |     x\n   |     ^\n   |\n   = note: `-D clippy::let-and-return` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     5\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:20:9\n   |\nLL |         let x = 5;\n   |         ---------- unnecessary `let` binding\nLL |         x\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         5\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:83:5\n   |\nLL |     let line = stdin.lock().lines().next().unwrap().unwrap();\n   |     --------------------------------------------------------- unnecessary `let` binding\nLL |     line\n   |     ^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     stdin.lock().lines().next().unwrap().unwrap()\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:178:13\n   |\nLL |             let clone = Arc::clone(&self.foo);\n   |             ---------------------------------- unnecessary `let` binding\nLL |             clone\n   |             ^^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             (Arc::clone(&self.foo)) as _\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:197:13\n   |\nLL | /             let result = match self {\nLL | |                 E::A(x) => x,\nLL | |                 E::B(x) => x,\nLL | |             };\n   | |______________- unnecessary `let` binding\nLL |\nLL |               result\n   |               ^^^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL |\nLL ~             (match self {\nLL +                 E::A(x) => x,\nLL +                 E::B(x) => x,\nLL +             }) as _\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:223:9\n   |\nLL |         let s = if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\";\n   |         ------------------------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         (if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\")\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:229:9\n   |\nLL |         let s = \"c\".to_string() + if true { \"a\" } else { \"b\" };\n   |         ------------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         \"c\".to_string() + if true { \"a\" } else { \"b\" }\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:235:9\n   |\nLL |         let s = { \"a\".to_string() } + \"b\" + { \"c\" } + \"d\";\n   |         -------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         ({ \"a\".to_string() } + \"b\" + { \"c\" } + \"d\")\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:243:13\n   |\nLL |             let s = if true { 2 } else { 3 } << 4;\n   |             -------------------------------------- unnecessary `let` binding\nLL |             s\n   |             ^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             (if true { 2 } else { 3 } << 4)\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:248:13\n   |\nLL |             let s = { true } || { false } && { 2 <= 3 };\n   |             -------------------------------------------- unnecessary `let` binding\nLL |             s\n   |             ^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             ({ true } || { false } && { 2 <= 3 })\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_and_return.edition2024.fixed",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![allow(unused)]\n#![warn(clippy::let_and_return)]\n\nuse std::cell::RefCell;\n\nfn test() -> i32 {\n    let _y = 0; // no warning\n    \n    5\n    //~^ let_and_return\n}\n\nfn test_inner() -> i32 {\n    if true {\n        \n        5\n        //~^ let_and_return\n    } else {\n        0\n    }\n}\n\nfn test_nowarn_1() -> i32 {\n    let mut x = 5;\n    x += 1;\n    x\n}\n\nfn test_nowarn_2() -> i32 {\n    let x = 5;\n    x + 1\n}\n\nfn test_nowarn_3() -> (i32, i32) {\n    // this should technically warn, but we do not compare complex patterns\n    let (x, y) = (5, 9);\n    (x, y)\n}\n\nfn test_nowarn_4() -> i32 {\n    // this should technically warn, but not b/c of clippy::let_and_return, but b/c of useless type\n    let x: i32 = 5;\n    x\n}\n\nfn test_nowarn_5(x: i16) -> u16 {\n    #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]\n    let x = x as u16;\n    x\n}\n\n// False positive example\ntrait Decode {\n    fn decode<D: std::io::Read>(d: D) -> Result<Self, ()>\n    where\n        Self: Sized;\n}\n\nmacro_rules! tuple_encode {\n    ($($x:ident),*) => (\n        impl<$($x: Decode),*> Decode for ($($x),*) {\n            #[inline]\n            #[allow(non_snake_case)]\n            fn decode<D: std::io::Read>(mut d: D) -> Result<Self, ()> {\n                // Shouldn't trigger lint\n                Ok(($({let $x = Decode::decode(&mut d)?; $x }),*))\n            }\n        }\n    );\n}\n\nfn issue_3792() -> String {\n    use std::io::{self, BufRead, Stdin};\n\n    let stdin = io::stdin();\n    // `Stdin::lock` returns `StdinLock<'static>` so `line` doesn't borrow from `stdin`\n    // https://github.com/rust-lang/rust/pull/93965\n    \n    stdin.lock().lines().next().unwrap().unwrap()\n    //~^ let_and_return\n}\n\ntuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);\n\nmod no_lint_if_stmt_borrows {\n    use std::cell::RefCell;\n    use std::rc::{Rc, Weak};\n    struct Bar;\n\n    impl Bar {\n        fn new() -> Self {\n            Bar {}\n        }\n        fn baz(&self) -> u32 {\n            0\n        }\n    }\n\n    fn issue_3324(value: Weak<RefCell<Bar>>) -> u32 {\n        let value = value.upgrade().unwrap();\n        \n        value.borrow().baz()\n        //~[edition2024]^ let_and_return\n    }\n\n    fn borrows_in_closure(value: Weak<RefCell<Bar>>) -> u32 {\n        fn f(mut x: impl FnMut() -> u32) -> impl FnMut() -> u32 {\n            x\n        }\n\n        let value = value.upgrade().unwrap();\n        \n        f(|| value.borrow().baz())()\n        //~[edition2024]^ let_and_return\n    }\n\n    mod free_function {\n        struct Inner;\n\n        struct Foo<'a> {\n            inner: &'a Inner,\n        }\n\n        impl Drop for Foo<'_> {\n            fn drop(&mut self) {}\n        }\n\n        impl<'a> Foo<'a> {\n            fn new(inner: &'a Inner) -> Self {\n                Self { inner }\n            }\n\n            fn value(&self) -> i32 {\n                42\n            }\n        }\n\n        fn some_foo(inner: &Inner) -> Foo<'_> {\n            Foo { inner }\n        }\n\n        fn test() -> i32 {\n            let x = Inner {};\n            \n            some_foo(&x).value()\n            //~[edition2024]^ let_and_return\n        }\n\n        fn test2() -> i32 {\n            let x = Inner {};\n            \n            Foo::new(&x).value()\n            //~[edition2024]^ let_and_return\n        }\n    }\n}\n\nmod issue_5729 {\n    use std::sync::Arc;\n\n    trait Foo {}\n\n    trait FooStorage {\n        fn foo_cloned(&self) -> Arc<dyn Foo>;\n    }\n\n    struct FooStorageImpl<T: Foo> {\n        foo: Arc<T>,\n    }\n\n    impl<T: Foo + 'static> FooStorage for FooStorageImpl<T> {\n        fn foo_cloned(&self) -> Arc<dyn Foo> {\n            \n            (Arc::clone(&self.foo)) as _\n            //~^ let_and_return\n        }\n    }\n}\n\nmod issue_11335 {\n    pub enum E<T> {\n        A(T),\n        B(T),\n    }\n\n    impl<T> E<T> {\n        pub fn inner(&self) -> &T {\n            \n\n            (match self {\n                E::A(x) => x,\n                E::B(x) => x,\n            }) as _\n            //~^ let_and_return\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/11167\nmacro_rules! fn_in_macro {\n    ($b:block) => {\n        fn f() -> usize $b\n    }\n}\nfn_in_macro!({\n    return 1;\n});\n\nfn issue9150() -> usize {\n    let x = 1;\n    #[cfg(any())]\n    panic!(\"can't see me\");\n    x\n}\n\nfn issue12801() {\n    fn left_is_if() -> String {\n        \n        (if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\")\n        //~^ let_and_return\n    }\n\n    fn no_par_needed() -> String {\n        \n        \"c\".to_string() + if true { \"a\" } else { \"b\" }\n        //~^ let_and_return\n    }\n\n    fn conjunctive_blocks() -> String {\n        \n        ({ \"a\".to_string() } + \"b\" + { \"c\" } + \"d\")\n        //~^ let_and_return\n    }\n\n    #[allow(clippy::overly_complex_bool_expr)]\n    fn other_ops() {\n        let _ = || {\n            \n            (if true { 2 } else { 3 } << 4)\n            //~^ let_and_return\n        };\n        let _ = || {\n            \n            ({ true } || { false } && { 2 <= 3 })\n            //~^ let_and_return\n        };\n    }\n}\n\nfn issue14164() -> Result<u32, ()> {\n    let v = std::cell::RefCell::new(Some(vec![1]));\n    \n    match &*v.borrow() {\n        Some(v) => Ok(Ok(v[0])),\n        None => Ok(Ok(0)),\n    }?\n    //~[edition2024]^ let_and_return\n}\n\nfn issue15987() -> i32 {\n    macro_rules! sample {\n        ( $( $args:expr ),+ ) => {};\n    }\n\n    let r = 5;\n    sample!(r);\n    r\n}\n\nfn has_comment() -> Vec<usize> {\n    let v = Vec::new();\n\n    // TODO: stuff\n\n    v\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/let_and_return.edition2024.stderr",
    "content": "error: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:13:5\n   |\nLL |     let x = 5;\n   |     ---------- unnecessary `let` binding\nLL |     x\n   |     ^\n   |\n   = note: `-D clippy::let-and-return` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     5\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:20:9\n   |\nLL |         let x = 5;\n   |         ---------- unnecessary `let` binding\nLL |         x\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         5\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:83:5\n   |\nLL |     let line = stdin.lock().lines().next().unwrap().unwrap();\n   |     --------------------------------------------------------- unnecessary `let` binding\nLL |     line\n   |     ^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     stdin.lock().lines().next().unwrap().unwrap()\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:106:9\n   |\nLL |         let ret = value.borrow().baz();\n   |         ------------------------------- unnecessary `let` binding\nLL |         ret\n   |         ^^^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         value.borrow().baz()\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:117:9\n   |\nLL |         let ret = f(|| value.borrow().baz())();\n   |         --------------------------------------- unnecessary `let` binding\nLL |         ret\n   |         ^^^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         f(|| value.borrow().baz())()\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:149:13\n   |\nLL |             let value = some_foo(&x).value();\n   |             --------------------------------- unnecessary `let` binding\nLL |             value\n   |             ^^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             some_foo(&x).value()\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:156:13\n   |\nLL |             let value = Foo::new(&x).value();\n   |             --------------------------------- unnecessary `let` binding\nLL |             value\n   |             ^^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             Foo::new(&x).value()\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:178:13\n   |\nLL |             let clone = Arc::clone(&self.foo);\n   |             ---------------------------------- unnecessary `let` binding\nLL |             clone\n   |             ^^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             (Arc::clone(&self.foo)) as _\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:197:13\n   |\nLL | /             let result = match self {\nLL | |                 E::A(x) => x,\nLL | |                 E::B(x) => x,\nLL | |             };\n   | |______________- unnecessary `let` binding\nLL |\nLL |               result\n   |               ^^^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL |\nLL ~             (match self {\nLL +                 E::A(x) => x,\nLL +                 E::B(x) => x,\nLL +             }) as _\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:223:9\n   |\nLL |         let s = if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\";\n   |         ------------------------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         (if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\")\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:229:9\n   |\nLL |         let s = \"c\".to_string() + if true { \"a\" } else { \"b\" };\n   |         ------------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         \"c\".to_string() + if true { \"a\" } else { \"b\" }\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:235:9\n   |\nLL |         let s = { \"a\".to_string() } + \"b\" + { \"c\" } + \"d\";\n   |         -------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         ({ \"a\".to_string() } + \"b\" + { \"c\" } + \"d\")\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:243:13\n   |\nLL |             let s = if true { 2 } else { 3 } << 4;\n   |             -------------------------------------- unnecessary `let` binding\nLL |             s\n   |             ^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             (if true { 2 } else { 3 } << 4)\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:248:13\n   |\nLL |             let s = { true } || { false } && { 2 <= 3 };\n   |             -------------------------------------------- unnecessary `let` binding\nLL |             s\n   |             ^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             ({ true } || { false } && { 2 <= 3 })\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:260:5\n   |\nLL | /     let r = match &*v.borrow() {\nLL | |         Some(v) => Ok(Ok(v[0])),\nLL | |         None => Ok(Ok(0)),\nLL | |     }?;\n   | |_______- unnecessary `let` binding\nLL |       r\n   |       ^\n   |\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     match &*v.borrow() {\nLL +         Some(v) => Ok(Ok(v[0])),\nLL +         None => Ok(Ok(0)),\nLL +     }?\n   |\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_and_return.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::let_and_return)]\n\nuse std::cell::RefCell;\n\nfn test() -> i32 {\n    let _y = 0; // no warning\n    \n    5\n    //~^ ERROR: returning the result of a `let` binding from a block\n    //~| NOTE: `-D clippy::let-and-return` implied by `-D warnings`\n}\n\nfn test_inner() -> i32 {\n    if true {\n        \n        5\n        //~^ ERROR: returning the result of a `let` binding from a block\n    } else {\n        0\n    }\n}\n\nfn test_nowarn_1() -> i32 {\n    let mut x = 5;\n    x += 1;\n    x\n}\n\nfn test_nowarn_2() -> i32 {\n    let x = 5;\n    x + 1\n}\n\nfn test_nowarn_3() -> (i32, i32) {\n    // this should technically warn, but we do not compare complex patterns\n    let (x, y) = (5, 9);\n    (x, y)\n}\n\nfn test_nowarn_4() -> i32 {\n    // this should technically warn, but not b/c of clippy::let_and_return, but b/c of useless type\n    let x: i32 = 5;\n    x\n}\n\nfn test_nowarn_5(x: i16) -> u16 {\n    #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]\n    let x = x as u16;\n    x\n}\n\n// False positive example\ntrait Decode {\n    fn decode<D: std::io::Read>(d: D) -> Result<Self, ()>\n    where\n        Self: Sized;\n}\n\nmacro_rules! tuple_encode {\n    ($($x:ident),*) => (\n        impl<$($x: Decode),*> Decode for ($($x),*) {\n            #[inline]\n            #[allow(non_snake_case)]\n            fn decode<D: std::io::Read>(mut d: D) -> Result<Self, ()> {\n                // Shouldn't trigger lint\n                Ok(($({let $x = Decode::decode(&mut d)?; $x }),*))\n            }\n        }\n    );\n}\n\nfn issue_3792() -> String {\n    use std::io::{self, BufRead, Stdin};\n\n    let stdin = io::stdin();\n    // `Stdin::lock` returns `StdinLock<'static>` so `line` doesn't borrow from `stdin`\n    // https://github.com/rust-lang/rust/pull/93965\n    \n    stdin.lock().lines().next().unwrap().unwrap()\n    //~^ ERROR: returning the result of a `let` binding from a block\n}\n\ntuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);\n\nmod no_lint_if_stmt_borrows {\n    use std::cell::RefCell;\n    use std::rc::{Rc, Weak};\n    struct Bar;\n\n    impl Bar {\n        fn new() -> Self {\n            Bar {}\n        }\n        fn baz(&self) -> u32 {\n            0\n        }\n    }\n\n    fn issue_3324(value: Weak<RefCell<Bar>>) -> u32 {\n        let value = value.upgrade().unwrap();\n        let ret = value.borrow().baz();\n        ret\n    }\n\n    fn borrows_in_closure(value: Weak<RefCell<Bar>>) -> u32 {\n        fn f(mut x: impl FnMut() -> u32) -> impl FnMut() -> u32 {\n            x\n        }\n\n        let value = value.upgrade().unwrap();\n        let ret = f(|| value.borrow().baz())();\n        ret\n    }\n\n    mod free_function {\n        struct Inner;\n\n        struct Foo<'a> {\n            inner: &'a Inner,\n        }\n\n        impl Drop for Foo<'_> {\n            fn drop(&mut self) {}\n        }\n\n        impl<'a> Foo<'a> {\n            fn new(inner: &'a Inner) -> Self {\n                Self { inner }\n            }\n\n            fn value(&self) -> i32 {\n                42\n            }\n        }\n\n        fn some_foo(inner: &Inner) -> Foo<'_> {\n            Foo { inner }\n        }\n\n        fn test() -> i32 {\n            let x = Inner {};\n            let value = some_foo(&x).value();\n            value\n        }\n\n        fn test2() -> i32 {\n            let x = Inner {};\n            let value = Foo::new(&x).value();\n            value\n        }\n    }\n}\n\nmod issue_5729 {\n    use std::sync::Arc;\n\n    trait Foo {}\n\n    trait FooStorage {\n        fn foo_cloned(&self) -> Arc<dyn Foo>;\n    }\n\n    struct FooStorageImpl<T: Foo> {\n        foo: Arc<T>,\n    }\n\n    impl<T: Foo + 'static> FooStorage for FooStorageImpl<T> {\n        fn foo_cloned(&self) -> Arc<dyn Foo> {\n            \n            (Arc::clone(&self.foo)) as _\n            //~^ ERROR: returning the result of a `let` binding from a block\n        }\n    }\n}\n\nmod issue_11335 {\n    pub enum E<T> {\n        A(T),\n        B(T),\n    }\n\n    impl<T> E<T> {\n        pub fn inner(&self) -> &T {\n            \n\n            (match self {\n                E::A(x) => x,\n                E::B(x) => x,\n            }) as _\n            //~^ ERROR: returning the result of a `let` binding from a block\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/11167\nmacro_rules! fn_in_macro {\n    ($b:block) => {\n        fn f() -> usize $b\n    }\n}\nfn_in_macro!({\n    return 1;\n});\n\nfn issue9150() -> usize {\n    let x = 1;\n    #[cfg(any())]\n    panic!(\"can't see me\");\n    x\n}\n\nfn issue12801() {\n    fn left_is_if() -> String {\n        \n        (if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\")\n        //~^ ERROR: returning the result of a `let` binding from a block\n    }\n\n    fn no_par_needed() -> String {\n        \n        \"c\".to_string() + if true { \"a\" } else { \"b\" }\n        //~^ ERROR: returning the result of a `let` binding from a block\n    }\n\n    fn conjunctive_blocks() -> String {\n        \n        ({ \"a\".to_string() } + \"b\" + { \"c\" } + \"d\")\n        //~^ ERROR: returning the result of a `let` binding from a block\n    }\n\n    #[allow(clippy::overly_complex_bool_expr)]\n    fn other_ops() {\n        let _ = || {\n            \n            (if true { 2 } else { 3 } << 4)\n            //~^ ERROR: returning the result of a `let` binding from a block\n        };\n        let _ = || {\n            \n            ({ true } || { false } && { 2 <= 3 })\n            //~^ ERROR: returning the result of a `let` binding from a block\n        };\n    }\n}\n\n// Do not lint\nfn issue14164() -> Result<u32, ()> {\n    let v = std::cell::RefCell::new(Some(vec![1]));\n    let r = match &*v.borrow() {\n        Some(v) => Ok(Ok(v[0])),\n        None => Ok(Ok(0)),\n    }?;\n    r\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/let_and_return.rs",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![allow(unused)]\n#![warn(clippy::let_and_return)]\n\nuse std::cell::RefCell;\n\nfn test() -> i32 {\n    let _y = 0; // no warning\n    let x = 5;\n    x\n    //~^ let_and_return\n}\n\nfn test_inner() -> i32 {\n    if true {\n        let x = 5;\n        x\n        //~^ let_and_return\n    } else {\n        0\n    }\n}\n\nfn test_nowarn_1() -> i32 {\n    let mut x = 5;\n    x += 1;\n    x\n}\n\nfn test_nowarn_2() -> i32 {\n    let x = 5;\n    x + 1\n}\n\nfn test_nowarn_3() -> (i32, i32) {\n    // this should technically warn, but we do not compare complex patterns\n    let (x, y) = (5, 9);\n    (x, y)\n}\n\nfn test_nowarn_4() -> i32 {\n    // this should technically warn, but not b/c of clippy::let_and_return, but b/c of useless type\n    let x: i32 = 5;\n    x\n}\n\nfn test_nowarn_5(x: i16) -> u16 {\n    #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]\n    let x = x as u16;\n    x\n}\n\n// False positive example\ntrait Decode {\n    fn decode<D: std::io::Read>(d: D) -> Result<Self, ()>\n    where\n        Self: Sized;\n}\n\nmacro_rules! tuple_encode {\n    ($($x:ident),*) => (\n        impl<$($x: Decode),*> Decode for ($($x),*) {\n            #[inline]\n            #[allow(non_snake_case)]\n            fn decode<D: std::io::Read>(mut d: D) -> Result<Self, ()> {\n                // Shouldn't trigger lint\n                Ok(($({let $x = Decode::decode(&mut d)?; $x }),*))\n            }\n        }\n    );\n}\n\nfn issue_3792() -> String {\n    use std::io::{self, BufRead, Stdin};\n\n    let stdin = io::stdin();\n    // `Stdin::lock` returns `StdinLock<'static>` so `line` doesn't borrow from `stdin`\n    // https://github.com/rust-lang/rust/pull/93965\n    let line = stdin.lock().lines().next().unwrap().unwrap();\n    line\n    //~^ let_and_return\n}\n\ntuple_encode!(T0, T1, T2, T3, T4, T5, T6, T7);\n\nmod no_lint_if_stmt_borrows {\n    use std::cell::RefCell;\n    use std::rc::{Rc, Weak};\n    struct Bar;\n\n    impl Bar {\n        fn new() -> Self {\n            Bar {}\n        }\n        fn baz(&self) -> u32 {\n            0\n        }\n    }\n\n    fn issue_3324(value: Weak<RefCell<Bar>>) -> u32 {\n        let value = value.upgrade().unwrap();\n        let ret = value.borrow().baz();\n        ret\n        //~[edition2024]^ let_and_return\n    }\n\n    fn borrows_in_closure(value: Weak<RefCell<Bar>>) -> u32 {\n        fn f(mut x: impl FnMut() -> u32) -> impl FnMut() -> u32 {\n            x\n        }\n\n        let value = value.upgrade().unwrap();\n        let ret = f(|| value.borrow().baz())();\n        ret\n        //~[edition2024]^ let_and_return\n    }\n\n    mod free_function {\n        struct Inner;\n\n        struct Foo<'a> {\n            inner: &'a Inner,\n        }\n\n        impl Drop for Foo<'_> {\n            fn drop(&mut self) {}\n        }\n\n        impl<'a> Foo<'a> {\n            fn new(inner: &'a Inner) -> Self {\n                Self { inner }\n            }\n\n            fn value(&self) -> i32 {\n                42\n            }\n        }\n\n        fn some_foo(inner: &Inner) -> Foo<'_> {\n            Foo { inner }\n        }\n\n        fn test() -> i32 {\n            let x = Inner {};\n            let value = some_foo(&x).value();\n            value\n            //~[edition2024]^ let_and_return\n        }\n\n        fn test2() -> i32 {\n            let x = Inner {};\n            let value = Foo::new(&x).value();\n            value\n            //~[edition2024]^ let_and_return\n        }\n    }\n}\n\nmod issue_5729 {\n    use std::sync::Arc;\n\n    trait Foo {}\n\n    trait FooStorage {\n        fn foo_cloned(&self) -> Arc<dyn Foo>;\n    }\n\n    struct FooStorageImpl<T: Foo> {\n        foo: Arc<T>,\n    }\n\n    impl<T: Foo + 'static> FooStorage for FooStorageImpl<T> {\n        fn foo_cloned(&self) -> Arc<dyn Foo> {\n            let clone = Arc::clone(&self.foo);\n            clone\n            //~^ let_and_return\n        }\n    }\n}\n\nmod issue_11335 {\n    pub enum E<T> {\n        A(T),\n        B(T),\n    }\n\n    impl<T> E<T> {\n        pub fn inner(&self) -> &T {\n            let result = match self {\n                E::A(x) => x,\n                E::B(x) => x,\n            };\n\n            result\n            //~^ let_and_return\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/11167\nmacro_rules! fn_in_macro {\n    ($b:block) => {\n        fn f() -> usize $b\n    }\n}\nfn_in_macro!({\n    return 1;\n});\n\nfn issue9150() -> usize {\n    let x = 1;\n    #[cfg(any())]\n    panic!(\"can't see me\");\n    x\n}\n\nfn issue12801() {\n    fn left_is_if() -> String {\n        let s = if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\";\n        s\n        //~^ let_and_return\n    }\n\n    fn no_par_needed() -> String {\n        let s = \"c\".to_string() + if true { \"a\" } else { \"b\" };\n        s\n        //~^ let_and_return\n    }\n\n    fn conjunctive_blocks() -> String {\n        let s = { \"a\".to_string() } + \"b\" + { \"c\" } + \"d\";\n        s\n        //~^ let_and_return\n    }\n\n    #[allow(clippy::overly_complex_bool_expr)]\n    fn other_ops() {\n        let _ = || {\n            let s = if true { 2 } else { 3 } << 4;\n            s\n            //~^ let_and_return\n        };\n        let _ = || {\n            let s = { true } || { false } && { 2 <= 3 };\n            s\n            //~^ let_and_return\n        };\n    }\n}\n\nfn issue14164() -> Result<u32, ()> {\n    let v = std::cell::RefCell::new(Some(vec![1]));\n    let r = match &*v.borrow() {\n        Some(v) => Ok(Ok(v[0])),\n        None => Ok(Ok(0)),\n    }?;\n    r\n    //~[edition2024]^ let_and_return\n}\n\nfn issue15987() -> i32 {\n    macro_rules! sample {\n        ( $( $args:expr ),+ ) => {};\n    }\n\n    let r = 5;\n    sample!(r);\n    r\n}\n\nfn has_comment() -> Vec<usize> {\n    let v = Vec::new();\n\n    // TODO: stuff\n\n    v\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/let_and_return.stderr",
    "content": "error: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:9:5\n   |\nLL |     let x = 5;\n   |     ---------- unnecessary `let` binding\nLL |     x\n   |     ^\n   |\n   = note: `-D clippy::let-and-return` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     5\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:17:9\n   |\nLL |         let x = 5;\n   |         ---------- unnecessary `let` binding\nLL |         x\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         5\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:80:5\n   |\nLL |     let line = stdin.lock().lines().next().unwrap().unwrap();\n   |     --------------------------------------------------------- unnecessary `let` binding\nLL |     line\n   |     ^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~     \nLL ~     stdin.lock().lines().next().unwrap().unwrap()\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:171:13\n   |\nLL |             let clone = Arc::clone(&self.foo);\n   |             ---------------------------------- unnecessary `let` binding\nLL |             clone\n   |             ^^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             (Arc::clone(&self.foo)) as _\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:190:13\n   |\nLL | /             let result = match self {\nLL | |                 E::A(x) => x,\nLL | |                 E::B(x) => x,\nLL | |             };\n   | |______________- unnecessary `let` binding\nLL |\nLL |               result\n   |               ^^^^^^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL |\nLL ~             (match self {\nLL +                 E::A(x) => x,\nLL +                 E::B(x) => x,\nLL +             }) as _\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:216:9\n   |\nLL |         let s = if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\";\n   |         ------------------------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         (if true { \"a\".to_string() } else { \"b\".to_string() } + \"c\")\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:222:9\n   |\nLL |         let s = \"c\".to_string() + if true { \"a\" } else { \"b\" };\n   |         ------------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         \"c\".to_string() + if true { \"a\" } else { \"b\" }\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:228:9\n   |\nLL |         let s = { \"a\".to_string() } + \"b\" + { \"c\" } + \"d\";\n   |         -------------------------------------------------- unnecessary `let` binding\nLL |         s\n   |         ^\n   |\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         ({ \"a\".to_string() } + \"b\" + { \"c\" } + \"d\")\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:236:13\n   |\nLL |             let s = if true { 2 } else { 3 } << 4;\n   |             -------------------------------------- unnecessary `let` binding\nLL |             s\n   |             ^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             (if true { 2 } else { 3 } << 4)\n   |\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/let_and_return.rs:241:13\n   |\nLL |             let s = { true } || { false } && { 2 <= 3 };\n   |             -------------------------------------------- unnecessary `let` binding\nLL |             s\n   |             ^\n   |\nhelp: return the expression directly\n   |\nLL ~             \nLL ~             ({ true } || { false } && { 2 <= 3 })\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_if_seq.rs",
    "content": "#![allow(\n    unused_variables,\n    unused_assignments,\n    clippy::similar_names,\n    clippy::disallowed_names,\n    clippy::branches_sharing_code,\n    clippy::needless_late_init\n)]\n#![warn(clippy::useless_let_if_seq)]\n//@no-rustfix\nfn f() -> bool {\n    true\n}\nfn g(x: i32) -> i32 {\n    x + 1\n}\n\nfn issue985() -> i32 {\n    let mut x = 42;\n    if f() {\n        x = g(x);\n    }\n\n    x\n}\n\nfn issue985_alt() -> i32 {\n    let mut x = 42;\n    if f() {\n        f();\n    } else {\n        x = g(x);\n    }\n\n    x\n}\n\n#[allow(clippy::manual_strip)]\nfn issue975() -> String {\n    let mut udn = \"dummy\".to_string();\n    if udn.starts_with(\"uuid:\") {\n        udn = String::from(&udn[5..]);\n    }\n    udn\n}\n\nfn early_return() -> u8 {\n    // FIXME: we could extend the lint to include such cases:\n    let foo;\n\n    if f() {\n        return 42;\n    } else {\n        foo = 0;\n    }\n\n    foo\n}\n\nfn allow_works() -> i32 {\n    #[allow(clippy::useless_let_if_seq)]\n    let x;\n    if true {\n        x = 1;\n    } else {\n        x = 2;\n    }\n    x\n}\n\nfn main() {\n    let mut foo = 0;\n    //~^ useless_let_if_seq\n\n    if f() {\n        foo = 42;\n    }\n\n    let mut bar = 0;\n    //~^ useless_let_if_seq\n\n    if f() {\n        f();\n        bar = 42;\n    } else {\n        f();\n    }\n\n    let quz;\n    //~^ useless_let_if_seq\n\n    if f() {\n        quz = 42;\n    } else {\n        quz = 0;\n    }\n\n    // `toto` is used several times\n    let mut toto;\n    if f() {\n        toto = 42;\n    } else {\n        for i in &[1, 2] {\n            toto = *i;\n        }\n\n        toto = 2;\n    }\n\n    // found in libcore, the inner if is not a statement but the block's expr\n    let mut ch = b'x';\n    if f() {\n        ch = b'*';\n        if f() {\n            ch = b'?';\n        }\n    }\n\n    // baz needs to be mut\n    let mut baz = 0;\n    //~^ useless_let_if_seq\n\n    if f() {\n        baz = 42;\n    }\n\n    baz = 1337;\n\n    // issue 3043 - types with interior mutability should not trigger this lint\n    use std::cell::Cell;\n    let mut val = Cell::new(1);\n    if true {\n        val = Cell::new(2);\n    }\n    println!(\"{}\", val.get());\n}\n\nfn issue16062(bar: fn() -> bool) {\n    let foo;\n    //~^ useless_let_if_seq\n    if bar() {\n        foo = 42;\n    } else {\n        foo = 0;\n    }\n}\n\nfn issue16064(bar: fn() -> bool) {\n    macro_rules! mac {\n        ($e:expr) => {\n            $e()\n        };\n        ($base:expr, $lit:expr) => {\n            $lit * $base + 2\n        };\n    }\n\n    let foo;\n    //~^ useless_let_if_seq\n    if mac!(bar) {\n        foo = mac!(10, 4);\n    } else {\n        foo = 0;\n    }\n\n    let bar = 1;\n}\n"
  },
  {
    "path": "tests/ui/let_if_seq.stderr",
    "content": "error: `if _ { .. } else { .. }` is an expression\n  --> tests/ui/let_if_seq.rs:72:5\n   |\nLL | /     let mut foo = 0;\nLL | |\nLL | |\nLL | |     if f() {\nLL | |         foo = 42;\nLL | |     }\n   | |_____^ help: it is more idiomatic to write: `let <mut> foo = if f() { 42 } else { 0 };`\n   |\n   = note: you might not need `mut` at all\n   = note: `-D clippy::useless-let-if-seq` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_let_if_seq)]`\n\nerror: `if _ { .. } else { .. }` is an expression\n  --> tests/ui/let_if_seq.rs:79:5\n   |\nLL | /     let mut bar = 0;\nLL | |\nLL | |\nLL | |     if f() {\n...  |\nLL | |         f();\nLL | |     }\n   | |_____^ help: it is more idiomatic to write: `let <mut> bar = if f() { ..; 42 } else { ..; 0 };`\n   |\n   = note: you might not need `mut` at all\n\nerror: `if _ { .. } else { .. }` is an expression\n  --> tests/ui/let_if_seq.rs:89:5\n   |\nLL | /     let quz;\nLL | |\nLL | |\nLL | |     if f() {\n...  |\nLL | |         quz = 0;\nLL | |     }\n   | |_____^ help: it is more idiomatic to write: `let quz = if f() { 42 } else { 0 };`\n\nerror: `if _ { .. } else { .. }` is an expression\n  --> tests/ui/let_if_seq.rs:120:5\n   |\nLL | /     let mut baz = 0;\nLL | |\nLL | |\nLL | |     if f() {\nLL | |         baz = 42;\nLL | |     }\n   | |_____^ help: it is more idiomatic to write: `let <mut> baz = if f() { 42 } else { 0 };`\n   |\n   = note: you might not need `mut` at all\n\nerror: `if _ { .. } else { .. }` is an expression\n  --> tests/ui/let_if_seq.rs:139:5\n   |\nLL | /     let foo;\nLL | |\nLL | |     if bar() {\nLL | |         foo = 42;\nLL | |     } else {\nLL | |         foo = 0;\nLL | |     }\n   | |_____^ help: it is more idiomatic to write: `let foo = if bar() { 42 } else { 0 };`\n\nerror: `if _ { .. } else { .. }` is an expression\n  --> tests/ui/let_if_seq.rs:158:5\n   |\nLL | /     let foo;\nLL | |\nLL | |     if mac!(bar) {\nLL | |         foo = mac!(10, 4);\nLL | |     } else {\nLL | |         foo = 0;\nLL | |     }\n   | |_____^ help: it is more idiomatic to write: `let foo = if mac!(bar) { mac!(10, 4) } else { 0 };`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_underscore_future.rs",
    "content": "use std::future::Future;\n\nasync fn some_async_fn() {}\n\nfn sync_side_effects() {}\nfn custom() -> impl Future<Output = ()> {\n    sync_side_effects();\n    async {}\n}\n\nfn do_something_to_future(future: &mut impl Future<Output = ()>) {}\n\nfn main() {\n    let _ = some_async_fn();\n    //~^ let_underscore_future\n\n    let _ = custom();\n    //~^ let_underscore_future\n\n    let mut future = some_async_fn();\n    do_something_to_future(&mut future);\n    let _ = future;\n    //~^ let_underscore_future\n}\n"
  },
  {
    "path": "tests/ui/let_underscore_future.stderr",
    "content": "error: non-binding `let` on a future\n  --> tests/ui/let_underscore_future.rs:14:5\n   |\nLL |     let _ = some_async_fn();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider awaiting the future or dropping explicitly with `std::mem::drop`\n   = note: `-D clippy::let-underscore-future` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_underscore_future)]`\n\nerror: non-binding `let` on a future\n  --> tests/ui/let_underscore_future.rs:17:5\n   |\nLL |     let _ = custom();\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider awaiting the future or dropping explicitly with `std::mem::drop`\n\nerror: non-binding `let` on a future\n  --> tests/ui/let_underscore_future.rs:22:5\n   |\nLL |     let _ = future;\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: consider awaiting the future or dropping explicitly with `std::mem::drop`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_underscore_lock.rs",
    "content": "#![warn(clippy::let_underscore_lock)]\n\nextern crate parking_lot;\n\nfn main() {\n    use parking_lot::lock_api::RawMutex;\n    use parking_lot::{Mutex, RwLock};\n\n    let p_m: Mutex<()> = Mutex::const_new(RawMutex::INIT, ());\n    let _ = p_m.lock();\n    //~^ ERROR: non-binding `let` on a synchronization lock\n\n    let p_m1 = Mutex::new(0);\n    let _ = p_m1.lock();\n    //~^ ERROR: non-binding `let` on a synchronization lock\n\n    let p_rw = RwLock::new(0);\n    let _ = p_rw.read();\n    //~^ ERROR: non-binding `let` on a synchronization lock\n    let _ = p_rw.write();\n    //~^ ERROR: non-binding `let` on a synchronization lock\n\n    // These shouldn't throw an error.\n    let _ = p_m;\n    let _ = p_m1;\n    let _ = p_rw;\n}\n\n#[allow(let_underscore_lock)]\nfn uplifted() {\n    // shouldn't lint std locks as they were uplifted as rustc's `let_underscore_lock`\n\n    let m = std::sync::Mutex::new(());\n    let rw = std::sync::RwLock::new(());\n\n    let _ = m.lock();\n    let _ = rw.read();\n    let _ = rw.write();\n    let _ = m.try_lock();\n    let _ = rw.try_read();\n    let _ = rw.try_write();\n\n    let _ = m;\n    let _ = rw;\n}\n"
  },
  {
    "path": "tests/ui/let_underscore_lock.stderr",
    "content": "error: non-binding `let` on a synchronization lock\n  --> tests/ui/let_underscore_lock.rs:10:5\n   |\nLL |     let _ = p_m.lock();\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`\n   = note: `-D clippy::let-underscore-lock` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_underscore_lock)]`\n\nerror: non-binding `let` on a synchronization lock\n  --> tests/ui/let_underscore_lock.rs:14:5\n   |\nLL |     let _ = p_m1.lock();\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`\n\nerror: non-binding `let` on a synchronization lock\n  --> tests/ui/let_underscore_lock.rs:18:5\n   |\nLL |     let _ = p_rw.read();\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`\n\nerror: non-binding `let` on a synchronization lock\n  --> tests/ui/let_underscore_lock.rs:20:5\n   |\nLL |     let _ = p_rw.write();\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_underscore_must_use.rs",
    "content": "#![warn(clippy::let_underscore_must_use)]\n#![allow(clippy::unnecessary_wraps)]\n\n// Debug implementations can fire this lint,\n// so we shouldn't lint external macros\n#[derive(Debug)]\nstruct Foo {\n    field: i32,\n}\n\n#[must_use]\nfn f() -> u32 {\n    0\n}\n\nfn g() -> Result<u32, u32> {\n    Ok(0)\n}\n\n#[must_use]\nfn l<T>(x: T) -> T {\n    x\n}\n\nfn h() -> u32 {\n    0\n}\n\nstruct S;\n\nimpl S {\n    #[must_use]\n    pub fn f(&self) -> u32 {\n        0\n    }\n\n    pub fn g(&self) -> Result<u32, u32> {\n        Ok(0)\n    }\n\n    fn k(&self) -> u32 {\n        0\n    }\n\n    #[must_use]\n    fn h() -> u32 {\n        0\n    }\n\n    fn p() -> Result<u32, u32> {\n        Ok(0)\n    }\n}\n\ntrait Trait {\n    #[must_use]\n    fn a() -> u32;\n}\n\nimpl Trait for S {\n    fn a() -> u32 {\n        0\n    }\n}\n\nfn main() {\n    let _ = f();\n    //~^ let_underscore_must_use\n\n    let _ = g();\n    //~^ let_underscore_must_use\n\n    let _ = h();\n    let _ = l(0_u32);\n    //~^ let_underscore_must_use\n\n    let s = S {};\n\n    let _ = s.f();\n    //~^ let_underscore_must_use\n\n    let _ = s.g();\n    //~^ let_underscore_must_use\n\n    let _ = s.k();\n\n    let _ = S::h();\n    //~^ let_underscore_must_use\n\n    let _ = S::p();\n    //~^ let_underscore_must_use\n\n    let _ = S::a();\n    //~^ let_underscore_must_use\n\n    let _ = if true { Ok(()) } else { Err(()) };\n    //~^ let_underscore_must_use\n\n    let a = Result::<(), ()>::Ok(());\n\n    let _ = a.is_ok();\n    //~^ let_underscore_must_use\n\n    let _ = a.map(|_| ());\n    //~^ let_underscore_must_use\n\n    let _ = a;\n    //~^ let_underscore_must_use\n\n    #[allow(clippy::let_underscore_must_use)]\n    let _ = a;\n\n    // No lint because this type should behave as `()`\n    let _ = Result::<_, std::convert::Infallible>::Ok(());\n\n    #[must_use]\n    struct T;\n\n    // Lint because this type should behave as `T`\n    let _ = Result::<_, std::convert::Infallible>::Ok(T);\n    //~^ let_underscore_must_use\n}\n"
  },
  {
    "path": "tests/ui/let_underscore_must_use.stderr",
    "content": "error: non-binding `let` on a result of a `#[must_use]` function\n  --> tests/ui/let_underscore_must_use.rs:67:5\n   |\nLL |     let _ = f();\n   |     ^^^^^^^^^^^^\n   |\n   = help: consider explicitly using function result\n   = note: `-D clippy::let-underscore-must-use` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_underscore_must_use)]`\n\nerror: non-binding `let` on an expression with `#[must_use]` type\n  --> tests/ui/let_underscore_must_use.rs:70:5\n   |\nLL |     let _ = g();\n   |     ^^^^^^^^^^^^\n   |\n   = help: consider explicitly using expression value\n\nerror: non-binding `let` on a result of a `#[must_use]` function\n  --> tests/ui/let_underscore_must_use.rs:74:5\n   |\nLL |     let _ = l(0_u32);\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using function result\n\nerror: non-binding `let` on a result of a `#[must_use]` function\n  --> tests/ui/let_underscore_must_use.rs:79:5\n   |\nLL |     let _ = s.f();\n   |     ^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using function result\n\nerror: non-binding `let` on an expression with `#[must_use]` type\n  --> tests/ui/let_underscore_must_use.rs:82:5\n   |\nLL |     let _ = s.g();\n   |     ^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using expression value\n\nerror: non-binding `let` on a result of a `#[must_use]` function\n  --> tests/ui/let_underscore_must_use.rs:87:5\n   |\nLL |     let _ = S::h();\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using function result\n\nerror: non-binding `let` on an expression with `#[must_use]` type\n  --> tests/ui/let_underscore_must_use.rs:90:5\n   |\nLL |     let _ = S::p();\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using expression value\n\nerror: non-binding `let` on a result of a `#[must_use]` function\n  --> tests/ui/let_underscore_must_use.rs:93:5\n   |\nLL |     let _ = S::a();\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using function result\n\nerror: non-binding `let` on an expression with `#[must_use]` type\n  --> tests/ui/let_underscore_must_use.rs:96:5\n   |\nLL |     let _ = if true { Ok(()) } else { Err(()) };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using expression value\n\nerror: non-binding `let` on a result of a `#[must_use]` function\n  --> tests/ui/let_underscore_must_use.rs:101:5\n   |\nLL |     let _ = a.is_ok();\n   |     ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using function result\n\nerror: non-binding `let` on an expression with `#[must_use]` type\n  --> tests/ui/let_underscore_must_use.rs:104:5\n   |\nLL |     let _ = a.map(|_| ());\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using expression value\n\nerror: non-binding `let` on an expression with `#[must_use]` type\n  --> tests/ui/let_underscore_must_use.rs:107:5\n   |\nLL |     let _ = a;\n   |     ^^^^^^^^^^\n   |\n   = help: consider explicitly using expression value\n\nerror: non-binding `let` on an expression with `#[must_use]` type\n  --> tests/ui/let_underscore_must_use.rs:120:5\n   |\nLL |     let _ = Result::<_, std::convert::Infallible>::Ok(T);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider explicitly using expression value\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_underscore_untyped.rs",
    "content": "//@aux-build: proc_macros.rs\n\n#![allow(unused)]\n#![warn(clippy::let_underscore_untyped)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nuse std::boxed::Box;\nuse std::fmt::Display;\nuse std::future::Future;\n\nfn a() -> u32 {\n    1\n}\n\nfn b<T>(x: T) -> T {\n    x\n}\n\nfn c() -> impl Display {\n    1\n}\n\nfn d(x: &u32) -> &u32 {\n    x\n}\n\nfn e() -> Result<u32, ()> {\n    Ok(1)\n}\n\nfn f() -> Box<dyn Display> {\n    Box::new(1)\n}\n\nfn g() -> impl Fn() {\n    || {}\n}\n\nwith_span!(\n    span\n\n    fn dont_lint_proc_macro() {\n        let _ = a();\n    }\n);\n\nfn main() {\n    let _ = a();\n    //~^ let_underscore_untyped\n    let _ = b(1);\n    //~^ let_underscore_untyped\n    let _ = c();\n    let _ = d(&1);\n    //~^ let_underscore_untyped\n    let _ = e();\n    //~^ let_underscore_untyped\n    let _ = f();\n    //~^ let_underscore_untyped\n    let _ = g();\n    let closure = || {};\n\n    _ = a();\n    _ = b(1);\n    _ = c();\n    _ = d(&1);\n    _ = e();\n    _ = f();\n\n    let _: u32 = a();\n    let _: u32 = b(1);\n    let _: &u32 = d(&1);\n    let _: Result<_, _> = e();\n    let _: Box<_> = f();\n\n    #[allow(clippy::let_underscore_untyped)]\n    let _ = a();\n}\n\nasync fn dont_lint_async_prototype(_: u8) {}\n"
  },
  {
    "path": "tests/ui/let_underscore_untyped.stderr",
    "content": "error: non-binding `let` without a type annotation\n  --> tests/ui/let_underscore_untyped.rs:50:5\n   |\nLL |     let _ = a();\n   |     ^^^^^^^^^^^^\n   |\nhelp: consider adding a type annotation\n  --> tests/ui/let_underscore_untyped.rs:50:10\n   |\nLL |     let _ = a();\n   |          ^\n   = note: `-D clippy::let-underscore-untyped` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_underscore_untyped)]`\n\nerror: non-binding `let` without a type annotation\n  --> tests/ui/let_underscore_untyped.rs:52:5\n   |\nLL |     let _ = b(1);\n   |     ^^^^^^^^^^^^^\n   |\nhelp: consider adding a type annotation\n  --> tests/ui/let_underscore_untyped.rs:52:10\n   |\nLL |     let _ = b(1);\n   |          ^\n\nerror: non-binding `let` without a type annotation\n  --> tests/ui/let_underscore_untyped.rs:55:5\n   |\nLL |     let _ = d(&1);\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: consider adding a type annotation\n  --> tests/ui/let_underscore_untyped.rs:55:10\n   |\nLL |     let _ = d(&1);\n   |          ^\n\nerror: non-binding `let` without a type annotation\n  --> tests/ui/let_underscore_untyped.rs:57:5\n   |\nLL |     let _ = e();\n   |     ^^^^^^^^^^^^\n   |\nhelp: consider adding a type annotation\n  --> tests/ui/let_underscore_untyped.rs:57:10\n   |\nLL |     let _ = e();\n   |          ^\n\nerror: non-binding `let` without a type annotation\n  --> tests/ui/let_underscore_untyped.rs:59:5\n   |\nLL |     let _ = f();\n   |     ^^^^^^^^^^^^\n   |\nhelp: consider adding a type annotation\n  --> tests/ui/let_underscore_untyped.rs:59:10\n   |\nLL |     let _ = f();\n   |          ^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_unit.fixed",
    "content": "#![warn(clippy::let_unit_value)]\n#![allow(\n    clippy::no_effect,\n    clippy::needless_late_init,\n    path_statements,\n    clippy::match_single_binding\n)]\n\nmacro_rules! let_and_return {\n    ($n:expr) => {{\n        let ret = $n;\n    }};\n}\n\nfn main() {\n    println!(\"x\");\n    //~^ let_unit_value\n    let _y = 1; // this is fine\n    let _z = ((), 1); // this as well\n    if true {\n        // do not lint this, since () is explicit\n        let _a = ();\n        let () = returns_unit();\n        let () = ();\n        () = returns_unit();\n        () = ();\n        let _a: () = ();\n        let _a: () = returns_unit();\n    }\n\n    consume_units_with_for_loop(); // should be fine as well\n\n    multiline_sugg();\n\n    let_and_return!(()) // should be fine\n}\n\nfn returns_unit() {}\n\n// Related to issue #1964\nfn consume_units_with_for_loop() {\n    // `for_let_unit` lint should not be triggered by consuming them using for loop.\n    let v = vec![(), (), ()];\n    let mut count = 0;\n    for _ in v {\n        count += 1;\n    }\n    assert_eq!(count, 3);\n\n    // Same for consuming from some other Iterator<Item = ()>.\n    let (tx, rx) = ::std::sync::mpsc::channel();\n    tx.send(()).unwrap();\n    drop(tx);\n\n    count = 0;\n    for _ in rx.iter() {\n        count += 1;\n    }\n    assert_eq!(count, 1);\n}\n\nfn multiline_sugg() {\n    let v: Vec<u8> = vec![2];\n\n    v\n        //~^ let_unit_value\n        .into_iter()\n        .map(|i| i * 2)\n        .filter(|i| i.is_multiple_of(2))\n        .map(|_| ())\n        .next()\n        .unwrap();\n}\n\n#[derive(Copy, Clone)]\npub struct ContainsUnit(()); // should be fine\n\nfn _returns_generic() {\n    fn f<T>() -> T {\n        unimplemented!()\n    }\n    fn f2<T, U>(_: T) -> U {\n        unimplemented!()\n    }\n    fn f3<T>(x: T) -> T {\n        x\n    }\n    fn f5<T: Default>(x: bool) -> Option<T> {\n        x.then(|| T::default())\n    }\n\n    let _: () = f();\n    let x: () = f();\n\n    let _: () = f2(0i32);\n    let x: () = f2(0i32);\n\n    let _: () = f3(());\n    let x: () = f3(());\n\n    fn f4<T>(mut x: Vec<T>) -> T {\n        x.pop().unwrap()\n    }\n    let _: () = f4(vec![()]);\n    let x: () = f4(vec![()]);\n\n    let _: () = {\n        let x = 5;\n        f2(x)\n    };\n\n    let _: () = if true { f() } else { f2(0) };\n    let x: () = if true { f() } else { f2(0) };\n\n    match Some(0) {\n        //~^ let_unit_value\n        None => f2(1),\n        Some(0) => f(),\n        Some(1) => f2(3),\n        Some(_) => (),\n    };\n\n    let _: () = f5(true).unwrap();\n\n    #[allow(clippy::let_unit_value)]\n    {\n        let x = f();\n        let y;\n        let z;\n        match 0 {\n            0 => {\n                y = f();\n                z = f();\n            },\n            1 => {\n                println!(\"test\");\n                y = f();\n                z = f3(());\n            },\n            _ => panic!(),\n        }\n\n        let x1;\n        let x2;\n        if true {\n            x1 = f();\n            x2 = x1;\n        } else {\n            x2 = f();\n            x1 = x2;\n        }\n\n        let opt;\n        match f5(true) {\n            Some(x) => opt = x,\n            None => panic!(),\n        };\n\n        #[warn(clippy::let_unit_value)]\n        {\n            let _: () = x;\n            let _: () = y;\n            let _: () = z;\n            let _: () = x1;\n            let _: () = x2;\n            let _: () = opt;\n        }\n    }\n\n    let () = f();\n}\n\nfn attributes() {\n    fn f() {}\n\n    #[allow(clippy::let_unit_value)]\n    let _ = f();\n    #[expect(clippy::let_unit_value)]\n    let _ = f();\n}\n\nasync fn issue10433() {\n    let _pending: () = std::future::pending().await;\n}\n\npub async fn issue11502(a: ()) {}\n\npub fn issue12594() {\n    fn returns_result<T>(res: T) -> Result<T, ()> {\n        Ok(res)\n    }\n\n    fn actual_test() {\n        // create first a unit value'd value\n        returns_unit();\n        //~^ let_unit_value\n        returns_result(()).unwrap();\n        returns_result(()).unwrap();\n        // make sure we replace only the first variable\n        let res = 1;\n        returns_result(res).unwrap();\n    }\n}\n\nfn takes_unit(x: ()) {}\n\nfn issue15061() {\n    let res = ();\n    returns_unit();\n    //~^ let_unit_value\n    takes_unit(());\n    println!(\"{res:?}\");\n}\n\nfn issue15771() {\n    match \"Example String\" {\n        _ => returns_unit(),\n        //~^ let_unit_value\n    }\n\n    if true {}\n    //~^ let_unit_value\n}\n\nfn issue_15784() {\n    let res = ();\n    eprintln!(\"I return unit\");\n    //~^ let_unit_value\n    takes_unit(());\n    println!(\"{res:?}\");\n}\n\nfn issue15789() {\n    struct Foo {\n        value: (),\n    }\n    println!();\n    //~^ let_unit_value\n\n    Foo { value: () };\n}\n"
  },
  {
    "path": "tests/ui/let_unit.rs",
    "content": "#![warn(clippy::let_unit_value)]\n#![allow(\n    clippy::no_effect,\n    clippy::needless_late_init,\n    path_statements,\n    clippy::match_single_binding\n)]\n\nmacro_rules! let_and_return {\n    ($n:expr) => {{\n        let ret = $n;\n    }};\n}\n\nfn main() {\n    let _x = println!(\"x\");\n    //~^ let_unit_value\n    let _y = 1; // this is fine\n    let _z = ((), 1); // this as well\n    if true {\n        // do not lint this, since () is explicit\n        let _a = ();\n        let () = returns_unit();\n        let () = ();\n        () = returns_unit();\n        () = ();\n        let _a: () = ();\n        let _a: () = returns_unit();\n    }\n\n    consume_units_with_for_loop(); // should be fine as well\n\n    multiline_sugg();\n\n    let_and_return!(()) // should be fine\n}\n\nfn returns_unit() {}\n\n// Related to issue #1964\nfn consume_units_with_for_loop() {\n    // `for_let_unit` lint should not be triggered by consuming them using for loop.\n    let v = vec![(), (), ()];\n    let mut count = 0;\n    for _ in v {\n        count += 1;\n    }\n    assert_eq!(count, 3);\n\n    // Same for consuming from some other Iterator<Item = ()>.\n    let (tx, rx) = ::std::sync::mpsc::channel();\n    tx.send(()).unwrap();\n    drop(tx);\n\n    count = 0;\n    for _ in rx.iter() {\n        count += 1;\n    }\n    assert_eq!(count, 1);\n}\n\nfn multiline_sugg() {\n    let v: Vec<u8> = vec![2];\n\n    let _ = v\n        //~^ let_unit_value\n        .into_iter()\n        .map(|i| i * 2)\n        .filter(|i| i.is_multiple_of(2))\n        .map(|_| ())\n        .next()\n        .unwrap();\n}\n\n#[derive(Copy, Clone)]\npub struct ContainsUnit(()); // should be fine\n\nfn _returns_generic() {\n    fn f<T>() -> T {\n        unimplemented!()\n    }\n    fn f2<T, U>(_: T) -> U {\n        unimplemented!()\n    }\n    fn f3<T>(x: T) -> T {\n        x\n    }\n    fn f5<T: Default>(x: bool) -> Option<T> {\n        x.then(|| T::default())\n    }\n\n    let _: () = f();\n    let x: () = f();\n\n    let _: () = f2(0i32);\n    let x: () = f2(0i32);\n\n    let _: () = f3(());\n    let x: () = f3(());\n\n    fn f4<T>(mut x: Vec<T>) -> T {\n        x.pop().unwrap()\n    }\n    let _: () = f4(vec![()]);\n    let x: () = f4(vec![()]);\n\n    let _: () = {\n        let x = 5;\n        f2(x)\n    };\n\n    let _: () = if true { f() } else { f2(0) };\n    let x: () = if true { f() } else { f2(0) };\n\n    let x = match Some(0) {\n        //~^ let_unit_value\n        None => f2(1),\n        Some(0) => f(),\n        Some(1) => f2(3),\n        Some(_) => (),\n    };\n\n    let _: () = f5(true).unwrap();\n\n    #[allow(clippy::let_unit_value)]\n    {\n        let x = f();\n        let y;\n        let z;\n        match 0 {\n            0 => {\n                y = f();\n                z = f();\n            },\n            1 => {\n                println!(\"test\");\n                y = f();\n                z = f3(());\n            },\n            _ => panic!(),\n        }\n\n        let x1;\n        let x2;\n        if true {\n            x1 = f();\n            x2 = x1;\n        } else {\n            x2 = f();\n            x1 = x2;\n        }\n\n        let opt;\n        match f5(true) {\n            Some(x) => opt = x,\n            None => panic!(),\n        };\n\n        #[warn(clippy::let_unit_value)]\n        {\n            let _: () = x;\n            let _: () = y;\n            let _: () = z;\n            let _: () = x1;\n            let _: () = x2;\n            let _: () = opt;\n        }\n    }\n\n    let () = f();\n}\n\nfn attributes() {\n    fn f() {}\n\n    #[allow(clippy::let_unit_value)]\n    let _ = f();\n    #[expect(clippy::let_unit_value)]\n    let _ = f();\n}\n\nasync fn issue10433() {\n    let _pending: () = std::future::pending().await;\n}\n\npub async fn issue11502(a: ()) {}\n\npub fn issue12594() {\n    fn returns_result<T>(res: T) -> Result<T, ()> {\n        Ok(res)\n    }\n\n    fn actual_test() {\n        // create first a unit value'd value\n        let res = returns_unit();\n        //~^ let_unit_value\n        returns_result(res).unwrap();\n        returns_result(res).unwrap();\n        // make sure we replace only the first variable\n        let res = 1;\n        returns_result(res).unwrap();\n    }\n}\n\nfn takes_unit(x: ()) {}\n\nfn issue15061() {\n    let res = returns_unit();\n    //~^ let_unit_value\n    takes_unit(res);\n    println!(\"{res:?}\");\n}\n\nfn issue15771() {\n    match \"Example String\" {\n        _ => _ = returns_unit(),\n        //~^ let_unit_value\n    }\n\n    _ = if true {}\n    //~^ let_unit_value\n}\n\nfn issue_15784() {\n    let res = eprintln!(\"I return unit\");\n    //~^ let_unit_value\n    takes_unit(res);\n    println!(\"{res:?}\");\n}\n\nfn issue15789() {\n    struct Foo {\n        value: (),\n    }\n    let value = println!();\n    //~^ let_unit_value\n\n    Foo { value };\n}\n"
  },
  {
    "path": "tests/ui/let_unit.stderr",
    "content": "error: this let-binding has unit value\n  --> tests/ui/let_unit.rs:16:5\n   |\nLL |     let _x = println!(\"x\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::let-unit-value` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]`\nhelp: omit the `let` binding\n   |\nLL -     let _x = println!(\"x\");\nLL +     println!(\"x\");\n   |\n\nerror: this let-binding has unit value\n  --> tests/ui/let_unit.rs:65:5\n   |\nLL | /     let _ = v\nLL | |\nLL | |         .into_iter()\nLL | |         .map(|i| i * 2)\n...  |\nLL | |         .next()\nLL | |         .unwrap();\n   | |__________________^\n   |\nhelp: omit the `let` binding\n   |\nLL -     let _ = v\nLL +     v\n   |\n\nerror: this let-binding has unit value\n  --> tests/ui/let_unit.rs:115:5\n   |\nLL | /     let x = match Some(0) {\nLL | |\nLL | |         None => f2(1),\nLL | |         Some(0) => f(),\nLL | |         Some(1) => f2(3),\nLL | |         Some(_) => (),\nLL | |     };\n   | |______^\n   |\nhelp: omit the `let` binding\n   |\nLL -     let x = match Some(0) {\nLL +     match Some(0) {\n   |\n\nerror: this let-binding has unit value\n  --> tests/ui/let_unit.rs:195:9\n   |\nLL |         let res = returns_unit();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: omit the `let` binding and replace variable usages with `()`\n   |\nLL ~         returns_unit();\nLL |\nLL ~         returns_result(()).unwrap();\nLL ~         returns_result(()).unwrap();\n   |\n\nerror: this let-binding has unit value\n  --> tests/ui/let_unit.rs:208:5\n   |\nLL |     let res = returns_unit();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace variable usages with `()`\n   |\nLL ~     let res = ();\nLL ~     returns_unit();\nLL |\nLL ~     takes_unit(());\n   |\n\nerror: this let-binding has unit value\n  --> tests/ui/let_unit.rs:216:14\n   |\nLL |         _ => _ = returns_unit(),\n   |              ^^^^^^^^^^^^^^^^^^\n   |\nhelp: omit the `let` binding\n   |\nLL -         _ => _ = returns_unit(),\nLL +         _ => returns_unit(),\n   |\n\nerror: this let-binding has unit value\n  --> tests/ui/let_unit.rs:220:5\n   |\nLL |     _ = if true {}\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: omit the `let` binding\n   |\nLL -     _ = if true {}\nLL +     if true {}\n   |\n\nerror: this let-binding has unit value\n  --> tests/ui/let_unit.rs:225:5\n   |\nLL |     let res = eprintln!(\"I return unit\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: replace variable usages with `()`\n   |\nLL ~     let res = ();\nLL ~     eprintln!(\"I return unit\");\nLL |\nLL ~     takes_unit(());\n   |\n\nerror: this let-binding has unit value\n  --> tests/ui/let_unit.rs:235:5\n   |\nLL |     let value = println!();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: omit the `let` binding and replace variable usages with `()`\n   |\nLL ~     println!();\nLL |\nLL |\nLL ~     Foo { value: () };\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/let_with_type_underscore.fixed",
    "content": "//@aux-build: proc_macros.rs\n#![allow(unused)]\n#![warn(clippy::let_with_type_underscore)]\n#![allow(clippy::let_unit_value, clippy::needless_late_init)]\n\nextern crate proc_macros;\n\nfn func() -> &'static str {\n    \"\"\n}\n\n#[rustfmt::skip]\nfn main() {\n    // Will lint\n    let x = 1;\n    //~^ let_with_type_underscore\n    let _ = 2;\n    //~^ let_with_type_underscore\n    let x = func();\n    //~^ let_with_type_underscore\n    let x;\n    //~^ let_with_type_underscore\n    x = ();\n\n    let x = 1; // Will not lint, Rust infers this to an integer before Clippy\n    let x = func();\n    let x: Vec<_> = Vec::<u32>::new();\n    let x: [_; 1] = [1];\n    let x = 1;\n    //~^ let_with_type_underscore\n\n    // Do not lint from procedural macros\n    proc_macros::with_span! {\n        span\n        let x: _ = ();\n        // Late initialization\n        let x: _;\n        x = ();\n        // Ensure weird formatting will not break it (hopefully)\n        let x : _ = 1;\n        let x\n: _ = 1;\n        let                   x :              \n        _;\n        x = ();\n    };\n}\n\nfn issue15377() {\n    let (a) = 0;\n    //~^ let_with_type_underscore\n    let ((a)) = 0;\n    //~^ let_with_type_underscore\n    let ((a,)) = (0,);\n    //~^ let_with_type_underscore\n    #[rustfmt::skip]\n    let (   (a   )   ) = 0;\n    //~^ let_with_type_underscore\n}\n"
  },
  {
    "path": "tests/ui/let_with_type_underscore.rs",
    "content": "//@aux-build: proc_macros.rs\n#![allow(unused)]\n#![warn(clippy::let_with_type_underscore)]\n#![allow(clippy::let_unit_value, clippy::needless_late_init)]\n\nextern crate proc_macros;\n\nfn func() -> &'static str {\n    \"\"\n}\n\n#[rustfmt::skip]\nfn main() {\n    // Will lint\n    let x: _ = 1;\n    //~^ let_with_type_underscore\n    let _: _ = 2;\n    //~^ let_with_type_underscore\n    let x: _ = func();\n    //~^ let_with_type_underscore\n    let x: _;\n    //~^ let_with_type_underscore\n    x = ();\n\n    let x = 1; // Will not lint, Rust infers this to an integer before Clippy\n    let x = func();\n    let x: Vec<_> = Vec::<u32>::new();\n    let x: [_; 1] = [1];\n    let x : _ = 1;\n    //~^ let_with_type_underscore\n\n    // Do not lint from procedural macros\n    proc_macros::with_span! {\n        span\n        let x: _ = ();\n        // Late initialization\n        let x: _;\n        x = ();\n        // Ensure weird formatting will not break it (hopefully)\n        let x : _ = 1;\n        let x\n: _ = 1;\n        let                   x :              \n        _;\n        x = ();\n    };\n}\n\nfn issue15377() {\n    let (a): _ = 0;\n    //~^ let_with_type_underscore\n    let ((a)): _ = 0;\n    //~^ let_with_type_underscore\n    let ((a,)): _ = (0,);\n    //~^ let_with_type_underscore\n    #[rustfmt::skip]\n    let (   (a   )   ):  _ = 0;\n    //~^ let_with_type_underscore\n}\n"
  },
  {
    "path": "tests/ui/let_with_type_underscore.stderr",
    "content": "error: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:15:5\n   |\nLL |     let x: _ = 1;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::let-with-type-underscore` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_with_type_underscore)]`\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let x: _ = 1;\nLL +     let x = 1;\n   |\n\nerror: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:17:5\n   |\nLL |     let _: _ = 2;\n   |     ^^^^^^^^^^^^^\n   |\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let _: _ = 2;\nLL +     let _ = 2;\n   |\n\nerror: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:19:5\n   |\nLL |     let x: _ = func();\n   |     ^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let x: _ = func();\nLL +     let x = func();\n   |\n\nerror: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:21:5\n   |\nLL |     let x: _;\n   |     ^^^^^^^^^\n   |\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let x: _;\nLL +     let x;\n   |\n\nerror: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:29:5\n   |\nLL |     let x : _ = 1;\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let x : _ = 1;\nLL +     let x = 1;\n   |\n\nerror: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:50:5\n   |\nLL |     let (a): _ = 0;\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let (a): _ = 0;\nLL +     let (a) = 0;\n   |\n\nerror: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:52:5\n   |\nLL |     let ((a)): _ = 0;\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let ((a)): _ = 0;\nLL +     let ((a)) = 0;\n   |\n\nerror: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:54:5\n   |\nLL |     let ((a,)): _ = (0,);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let ((a,)): _ = (0,);\nLL +     let ((a,)) = (0,);\n   |\n\nerror: variable declared with type underscore\n  --> tests/ui/let_with_type_underscore.rs:57:5\n   |\nLL |     let (   (a   )   ):  _ = 0;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit type `_` declaration\n   |\nLL -     let (   (a   )   ):  _ = 0;\nLL +     let (   (a   )   ) = 0;\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/lines_filter_map_ok.fixed",
    "content": "#![allow(clippy::map_identity)]\n#![warn(clippy::lines_filter_map_ok)]\n\nuse std::io::{self, BufRead, BufReader};\n\nfn main() -> io::Result<()> {\n    // Lint:\n\n    let f = std::fs::File::open(\"/\")?;\n    BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n    let f = std::fs::File::open(\"/\")?;\n    BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n    let f = std::fs::File::open(\"/\")?;\n    BufReader::new(f).lines().map_while(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n\n    io::stdin().lines().map_while(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n    io::stdin().lines().map_while(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n    io::stdin().lines().map_while(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n\n    // Do not lint:\n\n    // not a `Lines` iterator\n    io::stdin()\n        .lines()\n        .map(std::convert::identity)\n        .filter_map(|x| x.ok())\n        .for_each(|_| ());\n    // not a `Result::ok()` extractor\n    io::stdin().lines().filter_map(|x| x.err()).for_each(|_| ());\n    Ok(())\n}\n\n#[clippy::msrv = \"1.56\"]\nfn msrv_check() {\n    let _lines = BufReader::new(std::fs::File::open(\"some-path\").unwrap())\n        .lines()\n        .filter_map(Result::ok);\n}\n"
  },
  {
    "path": "tests/ui/lines_filter_map_ok.rs",
    "content": "#![allow(clippy::map_identity)]\n#![warn(clippy::lines_filter_map_ok)]\n\nuse std::io::{self, BufRead, BufReader};\n\nfn main() -> io::Result<()> {\n    // Lint:\n\n    let f = std::fs::File::open(\"/\")?;\n    BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n    let f = std::fs::File::open(\"/\")?;\n    BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n    let f = std::fs::File::open(\"/\")?;\n    BufReader::new(f).lines().flatten().for_each(|_| ());\n    //~^ lines_filter_map_ok\n\n    io::stdin().lines().filter_map(Result::ok).for_each(|_| ());\n    //~^ lines_filter_map_ok\n    io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ());\n    //~^ lines_filter_map_ok\n    io::stdin().lines().flatten().for_each(|_| ());\n    //~^ lines_filter_map_ok\n\n    // Do not lint:\n\n    // not a `Lines` iterator\n    io::stdin()\n        .lines()\n        .map(std::convert::identity)\n        .filter_map(|x| x.ok())\n        .for_each(|_| ());\n    // not a `Result::ok()` extractor\n    io::stdin().lines().filter_map(|x| x.err()).for_each(|_| ());\n    Ok(())\n}\n\n#[clippy::msrv = \"1.56\"]\nfn msrv_check() {\n    let _lines = BufReader::new(std::fs::File::open(\"some-path\").unwrap())\n        .lines()\n        .filter_map(Result::ok);\n}\n"
  },
  {
    "path": "tests/ui/lines_filter_map_ok.stderr",
    "content": "error: `filter_map()` will run forever if the iterator repeatedly produces an `Err`\n  --> tests/ui/lines_filter_map_ok.rs:10:31\n   |\nLL |     BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)`\n   |\nnote: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error\n  --> tests/ui/lines_filter_map_ok.rs:10:5\n   |\nLL |     BufReader::new(f).lines().filter_map(Result::ok).for_each(|_| ());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::lines-filter-map-ok` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::lines_filter_map_ok)]`\n\nerror: `flat_map()` will run forever if the iterator repeatedly produces an `Err`\n  --> tests/ui/lines_filter_map_ok.rs:13:31\n   |\nLL |     BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ());\n   |                               ^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)`\n   |\nnote: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error\n  --> tests/ui/lines_filter_map_ok.rs:13:5\n   |\nLL |     BufReader::new(f).lines().flat_map(Result::ok).for_each(|_| ());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `flatten()` will run forever if the iterator repeatedly produces an `Err`\n  --> tests/ui/lines_filter_map_ok.rs:16:31\n   |\nLL |     BufReader::new(f).lines().flatten().for_each(|_| ());\n   |                               ^^^^^^^^^ help: replace with: `map_while(Result::ok)`\n   |\nnote: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error\n  --> tests/ui/lines_filter_map_ok.rs:16:5\n   |\nLL |     BufReader::new(f).lines().flatten().for_each(|_| ());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `filter_map()` will run forever if the iterator repeatedly produces an `Err`\n  --> tests/ui/lines_filter_map_ok.rs:19:25\n   |\nLL |     io::stdin().lines().filter_map(Result::ok).for_each(|_| ());\n   |                         ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)`\n   |\nnote: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error\n  --> tests/ui/lines_filter_map_ok.rs:19:5\n   |\nLL |     io::stdin().lines().filter_map(Result::ok).for_each(|_| ());\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: `filter_map()` will run forever if the iterator repeatedly produces an `Err`\n  --> tests/ui/lines_filter_map_ok.rs:21:25\n   |\nLL |     io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ());\n   |                         ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `map_while(Result::ok)`\n   |\nnote: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error\n  --> tests/ui/lines_filter_map_ok.rs:21:5\n   |\nLL |     io::stdin().lines().filter_map(|x| x.ok()).for_each(|_| ());\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: `flatten()` will run forever if the iterator repeatedly produces an `Err`\n  --> tests/ui/lines_filter_map_ok.rs:23:25\n   |\nLL |     io::stdin().lines().flatten().for_each(|_| ());\n   |                         ^^^^^^^^^ help: replace with: `map_while(Result::ok)`\n   |\nnote: this expression returning a `std::io::Lines` may produce an infinite number of `Err` in case of a read error\n  --> tests/ui/lines_filter_map_ok.rs:23:5\n   |\nLL |     io::stdin().lines().flatten().for_each(|_| ());\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/linkedlist.rs",
    "content": "#![feature(associated_type_defaults)]\n#![warn(clippy::linkedlist)]\n#![allow(unused, dead_code, clippy::needless_pass_by_value)]\n\nextern crate alloc;\nuse alloc::collections::linked_list::LinkedList;\n\nconst C: LinkedList<i32> = LinkedList::new();\n//~^ linkedlist\n\nstatic S: LinkedList<i32> = LinkedList::new();\n//~^ linkedlist\n\ntrait Foo {\n    type Baz = LinkedList<u8>;\n    //~^ linkedlist\n\n    fn foo(_: LinkedList<u8>);\n    //~^ linkedlist\n\n    const BAR: Option<LinkedList<u8>>;\n    //~^ linkedlist\n}\n\n// Ok, we don’t want to warn for implementations; see issue #605.\nimpl Foo for LinkedList<u8> {\n    fn foo(_: LinkedList<u8>) {}\n    const BAR: Option<LinkedList<u8>> = None;\n}\n\npub struct Bar {\n    priv_linked_list_field: LinkedList<u8>,\n    //~^ linkedlist\n    pub pub_linked_list_field: LinkedList<u8>,\n}\nimpl Bar {\n    fn foo(_: LinkedList<u8>) {}\n    //~^ linkedlist\n}\n\n// All of these test should be trigger the lint because they are not\n// part of the public api\nfn test(my_favorite_linked_list: LinkedList<u8>) {}\n//~^ linkedlist\n\nfn test_ret() -> Option<LinkedList<u8>> {\n    //~^ linkedlist\n\n    None\n}\nfn test_local_not_linted() {\n    let _: LinkedList<u8>;\n}\n\n// All of these test should be allowed because they are part of the\n// public api and `avoid_breaking_exported_api` is `false` by default.\npub fn pub_test(the_most_awesome_linked_list: LinkedList<u8>) {}\npub fn pub_test_ret() -> Option<LinkedList<u8>> {\n    None\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/linkedlist.stderr",
    "content": "error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:8:10\n   |\nLL | const C: LinkedList<i32> = LinkedList::new();\n   |          ^^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n   = note: `-D clippy::linkedlist` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::linkedlist)]`\n\nerror: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:11:11\n   |\nLL | static S: LinkedList<i32> = LinkedList::new();\n   |           ^^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n\nerror: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:15:16\n   |\nLL |     type Baz = LinkedList<u8>;\n   |                ^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n\nerror: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:18:15\n   |\nLL |     fn foo(_: LinkedList<u8>);\n   |               ^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n\nerror: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:21:23\n   |\nLL |     const BAR: Option<LinkedList<u8>>;\n   |                       ^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n\nerror: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:32:29\n   |\nLL |     priv_linked_list_field: LinkedList<u8>,\n   |                             ^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n\nerror: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:37:15\n   |\nLL |     fn foo(_: LinkedList<u8>) {}\n   |               ^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n\nerror: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:43:34\n   |\nLL | fn test(my_favorite_linked_list: LinkedList<u8>) {}\n   |                                  ^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n\nerror: you seem to be using a `LinkedList`! Perhaps you meant some other data structure?\n  --> tests/ui/linkedlist.rs:46:25\n   |\nLL | fn test_ret() -> Option<LinkedList<u8>> {\n   |                         ^^^^^^^^^^^^^^\n   |\n   = help: a `VecDeque` might work\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/literal_string_with_formatting_arg.rs",
    "content": "#![warn(clippy::literal_string_with_formatting_args)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\n// Regression test for <https://github.com/rust-lang/rust-clippy/issues/13885>.\n// It's not supposed to emit the lint in this case (in `assert!` expansion).\nfn compiler_macro() {\n    fn parse(_: &str) -> Result<(), i32> {\n        unimplemented!()\n    }\n\n    assert!(\n        parse(\n            #[allow(clippy::literal_string_with_formatting_args)]\n            \"foo {:}\"\n        )\n        .is_err()\n    );\n    let value = 0;\n    assert!(format!(\"{value}\").is_ascii());\n}\n\n// Regression test for <https://github.com/rust-lang/rust-clippy/issues/14007>.\nfn regression_14007() {\n    let s = \"{и}\";\n    let ш = 12;\n    let s = \"{ш}\"; //~ literal_string_with_formatting_args\n}\n\nfn main() {\n    let x: Option<usize> = None;\n    let y = \"hello\";\n    x.expect(\"{y} {}\"); //~ literal_string_with_formatting_args\n    x.expect(\" {y} bla\"); //~ literal_string_with_formatting_args\n    x.expect(\"{:?}\"); //~ literal_string_with_formatting_args\n    x.expect(\"{y:?}\"); //~ literal_string_with_formatting_args\n    x.expect(\" {y:?} {y:?} \"); //~ literal_string_with_formatting_args\n    x.expect(\" {y:..} {y:?} \"); //~ literal_string_with_formatting_args\n    x.expect(r\"{y:?}  {y:?} \"); //~ literal_string_with_formatting_args\n    x.expect(r\"{y:?} y:?}\"); //~ literal_string_with_formatting_args\n    x.expect(r##\" {y:?} {y:?} \"##); //~ literal_string_with_formatting_args\n    assert!(\"{y}\".is_ascii()); //~ literal_string_with_formatting_args\n    // Ensure that it doesn't try to go in the middle of a unicode character.\n    x.expect(\"———{:?}\");\n    //~^ literal_string_with_formatting_args\n\n    // Should not lint!\n    format!(\"{y:?}\");\n    println!(\"{y:?}\");\n    x.expect(\" {} \"); // We ignore `{}` to limit false positives.\n    x.expect(\" {   } \"); // We ignore `{}` to limit false positives.\n    x.expect(\"{{y} {x\");\n    x.expect(\"{{y:?}\");\n    x.expect(\" {0}\"); // If it only contains an integer, we ignore it.\n    x.expect(r##\" {x:?} \"##); // `x` doesn't exist so we shoud not lint\n    //\n    //~^^ literal_string_with_formatting_args\n    x.expect(\"{y:...}\");\n    let _ = \"fn main {\\n\\\n    }\";\n    // Unicode characters escape should not lint either.\n    \"\\u{0052}\".to_string();\n\n    // Regression test for <https://github.com/rust-lang/rust-clippy/issues/13838>.\n    let x: Option<usize> = Some(0);\n    x.expect(\"{…}\");\n}\n"
  },
  {
    "path": "tests/ui/literal_string_with_formatting_arg.stderr",
    "content": "error: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:26:14\n   |\nLL |     let s = \"{ш}\";\n   |              ^^^\n   |\n   = note: `-D clippy::literal-string-with-formatting-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::literal_string_with_formatting_args)]`\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:32:15\n   |\nLL |     x.expect(\"{y} {}\");\n   |               ^^^\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:33:16\n   |\nLL |     x.expect(\" {y} bla\");\n   |                ^^^\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:34:15\n   |\nLL |     x.expect(\"{:?}\");\n   |               ^^^^\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:35:15\n   |\nLL |     x.expect(\"{y:?}\");\n   |               ^^^^^\n\nerror: these look like formatting arguments but are not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:36:16\n   |\nLL |     x.expect(\" {y:?} {y:?} \");\n   |                ^^^^^ ^^^^^\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:37:23\n   |\nLL |     x.expect(\" {y:..} {y:?} \");\n   |                       ^^^^^\n\nerror: these look like formatting arguments but are not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:38:16\n   |\nLL |     x.expect(r\"{y:?}  {y:?} \");\n   |                ^^^^^  ^^^^^\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:39:16\n   |\nLL |     x.expect(r\"{y:?} y:?}\");\n   |                ^^^^^\n\nerror: these look like formatting arguments but are not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:40:19\n   |\nLL |     x.expect(r##\" {y:?} {y:?} \"##);\n   |                   ^^^^^ ^^^^^\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:41:14\n   |\nLL |     assert!(\"{y}\".is_ascii());\n   |              ^^^\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:43:18\n   |\nLL |     x.expect(\"———{:?}\");\n   |                  ^^^^\n\nerror: this looks like a formatting argument but it is not part of a formatting macro\n  --> tests/ui/literal_string_with_formatting_arg.rs:54:19\n   |\nLL |     x.expect(r##\" {x:?} \"##); // `x` doesn't exist so we shoud not lint\n   |                   ^^^^^\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/literals.rs",
    "content": "//@no-rustfix: overlapping suggestions\n// does not test any rustfixable lints\n\n#![warn(clippy::mixed_case_hex_literals)]\n#![warn(clippy::zero_prefixed_literal)]\n#![warn(clippy::unseparated_literal_suffix)]\n#![warn(clippy::separated_literal_suffix)]\n#![allow(dead_code, overflowing_literals)]\n\nfn main() {\n    let ok1 = 0xABCD;\n    let ok3 = 0xab_cd;\n    let ok4 = 0xab_cd_i32;\n    //~^ separated_literal_suffix\n\n    let ok5 = 0xAB_CD_u32;\n    //~^ separated_literal_suffix\n\n    let ok5 = 0xAB_CD_isize;\n    //~^ separated_literal_suffix\n\n    let fail1 = 0xabCD;\n    //~^ mixed_case_hex_literals\n\n    let fail2 = 0xabCD_u32;\n    //~^ separated_literal_suffix\n    //~| mixed_case_hex_literals\n\n    let fail2 = 0xabCD_isize;\n    //~^ separated_literal_suffix\n    //~| mixed_case_hex_literals\n\n    let fail2 = 0xab_CD_isize;\n    //~^ separated_literal_suffix\n    //~| mixed_case_hex_literals\n\n    let fail_multi_zero = 000_123usize;\n    //~^ unseparated_literal_suffix\n    //~| zero_prefixed_literal\n\n    let ok9 = 0;\n    let ok10 = 0_i64;\n    //~^ separated_literal_suffix\n\n    let fail8 = 0123;\n    //~^ zero_prefixed_literal\n\n    let ok11 = 0o123;\n    let ok12 = 0b10_1010;\n\n    let ok13 = 0xab_abcd;\n    let ok14 = 0xBAFE_BAFE;\n    let ok15 = 0xab_cabc_abca_bcab_cabc;\n    let ok16 = 0xFE_BAFE_ABAB_ABCD;\n    let ok17 = 0x123_4567_8901_usize;\n    //~^ separated_literal_suffix\n\n    let ok18 = 0xF;\n\n    let fail19 = 12_3456_21;\n    //~^ inconsistent_digit_grouping\n\n    let fail22 = 3__4___23;\n    //~^ inconsistent_digit_grouping\n\n    let fail23 = 3__16___23;\n    //~^ inconsistent_digit_grouping\n\n    let fail24 = 0xAB_ABC_AB;\n    //~^ unusual_byte_groupings\n\n    let fail25 = 0b01_100_101;\n    let ok26 = 0x6_A0_BF;\n    let ok27 = 0b1_0010_0101;\n}\n\nfn issue9651() {\n    // lint but octal form is not possible here\n    let _ = 08;\n    //~^ zero_prefixed_literal\n\n    let _ = 09;\n    //~^ zero_prefixed_literal\n\n    let _ = 089;\n    //~^ zero_prefixed_literal\n}\n"
  },
  {
    "path": "tests/ui/literals.stderr",
    "content": "error: integer type suffix should not be separated by an underscore\n  --> tests/ui/literals.rs:13:15\n   |\nLL |     let ok4 = 0xab_cd_i32;\n   |               ^^^^^^^^^^^ help: remove the underscore: `0xab_cdi32`\n   |\n   = note: `-D clippy::separated-literal-suffix` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::separated_literal_suffix)]`\n\nerror: integer type suffix should not be separated by an underscore\n  --> tests/ui/literals.rs:16:15\n   |\nLL |     let ok5 = 0xAB_CD_u32;\n   |               ^^^^^^^^^^^ help: remove the underscore: `0xAB_CDu32`\n\nerror: integer type suffix should not be separated by an underscore\n  --> tests/ui/literals.rs:19:15\n   |\nLL |     let ok5 = 0xAB_CD_isize;\n   |               ^^^^^^^^^^^^^ help: remove the underscore: `0xAB_CDisize`\n\nerror: inconsistent casing in hexadecimal literal\n  --> tests/ui/literals.rs:22:17\n   |\nLL |     let fail1 = 0xabCD;\n   |                 ^^^^^^\n   |\n   = help: consider using `0xabcd` or `0xABCD`\n   = note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mixed_case_hex_literals)]`\n\nerror: integer type suffix should not be separated by an underscore\n  --> tests/ui/literals.rs:25:17\n   |\nLL |     let fail2 = 0xabCD_u32;\n   |                 ^^^^^^^^^^ help: remove the underscore: `0xabCDu32`\n\nerror: inconsistent casing in hexadecimal literal\n  --> tests/ui/literals.rs:25:17\n   |\nLL |     let fail2 = 0xabCD_u32;\n   |                 ^^^^^^^^^^\n   |\n   = help: consider using `0xabcd_u32` or `0xABCD_u32`\n\nerror: integer type suffix should not be separated by an underscore\n  --> tests/ui/literals.rs:29:17\n   |\nLL |     let fail2 = 0xabCD_isize;\n   |                 ^^^^^^^^^^^^ help: remove the underscore: `0xabCDisize`\n\nerror: inconsistent casing in hexadecimal literal\n  --> tests/ui/literals.rs:29:17\n   |\nLL |     let fail2 = 0xabCD_isize;\n   |                 ^^^^^^^^^^^^\n   |\n   = help: consider using `0xabcd_isize` or `0xABCD_isize`\n\nerror: integer type suffix should not be separated by an underscore\n  --> tests/ui/literals.rs:33:17\n   |\nLL |     let fail2 = 0xab_CD_isize;\n   |                 ^^^^^^^^^^^^^ help: remove the underscore: `0xab_CDisize`\n\nerror: inconsistent casing in hexadecimal literal\n  --> tests/ui/literals.rs:33:17\n   |\nLL |     let fail2 = 0xab_CD_isize;\n   |                 ^^^^^^^^^^^^^\n   |\n   = help: consider using `0xab_cd_isize` or `0xAB_CD_isize`\n\nerror: integer type suffix should be separated by an underscore\n  --> tests/ui/literals.rs:37:27\n   |\nLL |     let fail_multi_zero = 000_123usize;\n   |                           ^^^^^^^^^^^^ help: add an underscore: `000_123_usize`\n   |\n   = note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]`\n\nerror: this is a decimal constant\n  --> tests/ui/literals.rs:37:27\n   |\nLL |     let fail_multi_zero = 000_123usize;\n   |                           ^^^^^^^^^^^^\n   |\n   = note: `-D clippy::zero-prefixed-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zero_prefixed_literal)]`\nhelp: if you mean to use a decimal constant, remove the `0` to avoid confusion\n   |\nLL -     let fail_multi_zero = 000_123usize;\nLL +     let fail_multi_zero = 123usize;\n   |\nhelp: if you mean to use an octal constant, use `0o`\n   |\nLL -     let fail_multi_zero = 000_123usize;\nLL +     let fail_multi_zero = 0o123usize;\n   |\n\nerror: integer type suffix should not be separated by an underscore\n  --> tests/ui/literals.rs:42:16\n   |\nLL |     let ok10 = 0_i64;\n   |                ^^^^^ help: remove the underscore: `0i64`\n\nerror: this is a decimal constant\n  --> tests/ui/literals.rs:45:17\n   |\nLL |     let fail8 = 0123;\n   |                 ^^^^\n   |\nhelp: if you mean to use a decimal constant, remove the `0` to avoid confusion\n   |\nLL -     let fail8 = 0123;\nLL +     let fail8 = 123;\n   |\nhelp: if you mean to use an octal constant, use `0o`\n   |\nLL |     let fail8 = 0o123;\n   |                  +\n\nerror: integer type suffix should not be separated by an underscore\n  --> tests/ui/literals.rs:55:16\n   |\nLL |     let ok17 = 0x123_4567_8901_usize;\n   |                ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize`\n\nerror: digits grouped inconsistently by underscores\n  --> tests/ui/literals.rs:60:18\n   |\nLL |     let fail19 = 12_3456_21;\n   |                  ^^^^^^^^^^ help: consider: `12_345_621`\n   |\n   = note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]`\n\nerror: digits grouped inconsistently by underscores\n  --> tests/ui/literals.rs:63:18\n   |\nLL |     let fail22 = 3__4___23;\n   |                  ^^^^^^^^^ help: consider: `3_423`\n\nerror: digits grouped inconsistently by underscores\n  --> tests/ui/literals.rs:66:18\n   |\nLL |     let fail23 = 3__16___23;\n   |                  ^^^^^^^^^^ help: consider: `31_623`\n\nerror: digits of hex, binary or octal literal not in groups of equal size\n  --> tests/ui/literals.rs:69:18\n   |\nLL |     let fail24 = 0xAB_ABC_AB;\n   |                  ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`\n   |\n   = note: `-D clippy::unusual-byte-groupings` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]`\n\nerror: this is a decimal constant\n  --> tests/ui/literals.rs:79:13\n   |\nLL |     let _ = 08;\n   |             ^^\n   |\nhelp: if you mean to use a decimal constant, remove the `0` to avoid confusion\n   |\nLL -     let _ = 08;\nLL +     let _ = 8;\n   |\n\nerror: this is a decimal constant\n  --> tests/ui/literals.rs:82:13\n   |\nLL |     let _ = 09;\n   |             ^^\n   |\nhelp: if you mean to use a decimal constant, remove the `0` to avoid confusion\n   |\nLL -     let _ = 09;\nLL +     let _ = 9;\n   |\n\nerror: this is a decimal constant\n  --> tests/ui/literals.rs:85:13\n   |\nLL |     let _ = 089;\n   |             ^^^\n   |\nhelp: if you mean to use a decimal constant, remove the `0` to avoid confusion\n   |\nLL -     let _ = 089;\nLL +     let _ = 89;\n   |\n\nerror: aborting due to 22 previous errors\n\n"
  },
  {
    "path": "tests/ui/localhost.txt",
    "content": "std::net::Ipv4Addr::new(127, 0, 0, 1)"
  },
  {
    "path": "tests/ui/lossy_float_literal.fixed",
    "content": "#![warn(clippy::lossy_float_literal)]\n#![allow(overflowing_literals, unused)]\n#![feature(f128)]\n#![feature(f16)]\n\nfn main() {\n    // Lossy whole-number float literals\n    let _: f16 = 4_097.0;\n    let _: f16 = 4_097.;\n    let _: f16 = 4_097.000;\n    let _ = 4_097f16;\n    let _: f16 = -4_097.0;\n\n    let _: f32 = 16_777_216.0;\n    //~^ lossy_float_literal\n    let _: f32 = 16_777_220.0;\n    //~^ lossy_float_literal\n    let _: f32 = 16_777_220.0;\n    //~^ lossy_float_literal\n    let _: f32 = 16_777_220.0;\n    //~^ lossy_float_literal\n    let _ = 16_777_220_f32;\n    //~^ lossy_float_literal\n    let _: f32 = -16_777_220.0;\n    //~^ lossy_float_literal\n\n    let _: f64 = 9_007_199_254_740_992.0;\n    //~^ lossy_float_literal\n    let _: f64 = 9_007_199_254_740_992.0;\n    //~^ lossy_float_literal\n    let _: f64 = 9_007_199_254_740_992.0;\n    //~^ lossy_float_literal\n    let _ = 9_007_199_254_740_992_f64;\n    //~^ lossy_float_literal\n    let _: f64 = -9_007_199_254_740_992.0;\n    //~^ lossy_float_literal\n\n    let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.0;\n    let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.;\n    let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.00;\n    let _ = 10_384_593_717_069_655_257_060_992_658_440_193f128;\n    let _: f128 = -10_384_593_717_069_655_257_060_992_658_440_193.0;\n\n    // Lossless whole number float literals\n    let _: f16 = 4_096.0;\n    let _: f16 = -4_096.0;\n\n    let _: f32 = 16_777_216.0;\n    let _: f32 = 16_777_218.0;\n    let _: f32 = 16_777_220.0;\n    let _: f32 = -16_777_216.0;\n    let _: f32 = -16_777_220.0;\n\n    let _: f64 = 16_777_217.0;\n    let _: f64 = -16_777_217.0;\n    let _: f64 = 9_007_199_254_740_992.0;\n    let _: f64 = -9_007_199_254_740_992.0;\n\n    let _: f128 = 9_007_199_254_740_993.0;\n    let _: f128 = -9_007_199_254_740_993.0;\n    let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_192.0;\n    let _: f128 = -10_384_593_717_069_655_257_060_992_658_440_192.0;\n\n    // Ignored whole number float literals\n    let _: f32 = 1e25;\n    let _: f32 = 1E25;\n    let _: f64 = 1e99;\n    let _: f64 = 1E99;\n    let _: f32 = 0.1;\n\n    const INF1: f32 = 1000000000000000000000000000000000f32;\n    const NEG_INF1: f32 = -340282357000000000000000000000000000001_f32;\n}\n"
  },
  {
    "path": "tests/ui/lossy_float_literal.rs",
    "content": "#![warn(clippy::lossy_float_literal)]\n#![allow(overflowing_literals, unused)]\n#![feature(f128)]\n#![feature(f16)]\n\nfn main() {\n    // Lossy whole-number float literals\n    let _: f16 = 4_097.0;\n    let _: f16 = 4_097.;\n    let _: f16 = 4_097.000;\n    let _ = 4_097f16;\n    let _: f16 = -4_097.0;\n\n    let _: f32 = 16_777_217.0;\n    //~^ lossy_float_literal\n    let _: f32 = 16_777_219.0;\n    //~^ lossy_float_literal\n    let _: f32 = 16_777_219.;\n    //~^ lossy_float_literal\n    let _: f32 = 16_777_219.000;\n    //~^ lossy_float_literal\n    let _ = 16_777_219f32;\n    //~^ lossy_float_literal\n    let _: f32 = -16_777_219.0;\n    //~^ lossy_float_literal\n\n    let _: f64 = 9_007_199_254_740_993.0;\n    //~^ lossy_float_literal\n    let _: f64 = 9_007_199_254_740_993.;\n    //~^ lossy_float_literal\n    let _: f64 = 9_007_199_254_740_993.00;\n    //~^ lossy_float_literal\n    let _ = 9_007_199_254_740_993f64;\n    //~^ lossy_float_literal\n    let _: f64 = -9_007_199_254_740_993.0;\n    //~^ lossy_float_literal\n\n    let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.0;\n    let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.;\n    let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_193.00;\n    let _ = 10_384_593_717_069_655_257_060_992_658_440_193f128;\n    let _: f128 = -10_384_593_717_069_655_257_060_992_658_440_193.0;\n\n    // Lossless whole number float literals\n    let _: f16 = 4_096.0;\n    let _: f16 = -4_096.0;\n\n    let _: f32 = 16_777_216.0;\n    let _: f32 = 16_777_218.0;\n    let _: f32 = 16_777_220.0;\n    let _: f32 = -16_777_216.0;\n    let _: f32 = -16_777_220.0;\n\n    let _: f64 = 16_777_217.0;\n    let _: f64 = -16_777_217.0;\n    let _: f64 = 9_007_199_254_740_992.0;\n    let _: f64 = -9_007_199_254_740_992.0;\n\n    let _: f128 = 9_007_199_254_740_993.0;\n    let _: f128 = -9_007_199_254_740_993.0;\n    let _: f128 = 10_384_593_717_069_655_257_060_992_658_440_192.0;\n    let _: f128 = -10_384_593_717_069_655_257_060_992_658_440_192.0;\n\n    // Ignored whole number float literals\n    let _: f32 = 1e25;\n    let _: f32 = 1E25;\n    let _: f64 = 1e99;\n    let _: f64 = 1E99;\n    let _: f32 = 0.1;\n\n    const INF1: f32 = 1000000000000000000000000000000000f32;\n    const NEG_INF1: f32 = -340282357000000000000000000000000000001_f32;\n}\n"
  },
  {
    "path": "tests/ui/lossy_float_literal.stderr",
    "content": "error: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:14:18\n   |\nLL |     let _: f32 = 16_777_217.0;\n   |                  ^^^^^^^^^^^^\n   |\n   = note: `-D clippy::lossy-float-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::lossy_float_literal)]`\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f32 = 16_777_217.0;\nLL +     let _: f32 = 16_777_216.0;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:16:18\n   |\nLL |     let _: f32 = 16_777_219.0;\n   |                  ^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f32 = 16_777_219.0;\nLL +     let _: f32 = 16_777_220.0;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:18:18\n   |\nLL |     let _: f32 = 16_777_219.;\n   |                  ^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f32 = 16_777_219.;\nLL +     let _: f32 = 16_777_220.0;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:20:18\n   |\nLL |     let _: f32 = 16_777_219.000;\n   |                  ^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f32 = 16_777_219.000;\nLL +     let _: f32 = 16_777_220.0;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:22:13\n   |\nLL |     let _ = 16_777_219f32;\n   |             ^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _ = 16_777_219f32;\nLL +     let _ = 16_777_220_f32;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:24:19\n   |\nLL |     let _: f32 = -16_777_219.0;\n   |                   ^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f32 = -16_777_219.0;\nLL +     let _: f32 = -16_777_220.0;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:27:18\n   |\nLL |     let _: f64 = 9_007_199_254_740_993.0;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f64 = 9_007_199_254_740_993.0;\nLL +     let _: f64 = 9_007_199_254_740_992.0;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:29:18\n   |\nLL |     let _: f64 = 9_007_199_254_740_993.;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f64 = 9_007_199_254_740_993.;\nLL +     let _: f64 = 9_007_199_254_740_992.0;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:31:18\n   |\nLL |     let _: f64 = 9_007_199_254_740_993.00;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f64 = 9_007_199_254_740_993.00;\nLL +     let _: f64 = 9_007_199_254_740_992.0;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:33:13\n   |\nLL |     let _ = 9_007_199_254_740_993f64;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _ = 9_007_199_254_740_993f64;\nLL +     let _ = 9_007_199_254_740_992_f64;\n   |\n\nerror: literal cannot be represented as the underlying type without loss of precision\n  --> tests/ui/lossy_float_literal.rs:35:19\n   |\nLL |     let _: f64 = -9_007_199_254_740_993.0;\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the type or replacing it with\n   |\nLL -     let _: f64 = -9_007_199_254_740_993.0;\nLL +     let _: f64 = -9_007_199_254_740_992.0;\n   |\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/macro_use_imports.fixed",
    "content": "//@aux-build:macro_rules.rs\n//@aux-build:macro_use_helper.rs\n//@aux-build:proc_macro_derive.rs\n\n//@ignore-bitwidth: 32\n\n#![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]\n#![allow(clippy::single_component_path_imports)]\n#![warn(clippy::macro_use_imports)]\n\n#[macro_use]\nextern crate macro_use_helper as mac;\n\n#[macro_use]\nextern crate proc_macro_derive as mini_mac;\n\nmod a {\n    use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};\n    //~^ macro_use_imports\n    use mac;\n    use mini_mac::ClippyMiniMacroTest;\n    //~^ macro_use_imports\n    use mini_mac;\n    use mac::{inner::mut_mut, inner::try_err};\n    //~^ macro_use_imports\n    use mac::inner;\n    use mac::inner::nested::string_add;\n    //~^ macro_use_imports\n    use mac::inner::nested;\n\n    #[derive(ClippyMiniMacroTest)]\n    struct Test;\n\n    fn test() {\n        pub_macro!();\n        inner_mod_macro!();\n        pub_in_private_macro!(_var);\n        function_macro!();\n        let v: ty_macro!() = Vec::default();\n\n        inner::try_err!();\n        inner::mut_mut!();\n        nested::string_add!();\n    }\n}\n\n// issue #7015, ICE due to calling `module_children` with local `DefId`\n#[macro_use]\nuse a as b;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/macro_use_imports.rs",
    "content": "//@aux-build:macro_rules.rs\n//@aux-build:macro_use_helper.rs\n//@aux-build:proc_macro_derive.rs\n\n//@ignore-bitwidth: 32\n\n#![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]\n#![allow(clippy::single_component_path_imports)]\n#![warn(clippy::macro_use_imports)]\n\n#[macro_use]\nextern crate macro_use_helper as mac;\n\n#[macro_use]\nextern crate proc_macro_derive as mini_mac;\n\nmod a {\n    #[macro_use]\n    //~^ macro_use_imports\n    use mac;\n    #[macro_use]\n    //~^ macro_use_imports\n    use mini_mac;\n    #[macro_use]\n    //~^ macro_use_imports\n    use mac::inner;\n    #[macro_use]\n    //~^ macro_use_imports\n    use mac::inner::nested;\n\n    #[derive(ClippyMiniMacroTest)]\n    struct Test;\n\n    fn test() {\n        pub_macro!();\n        inner_mod_macro!();\n        pub_in_private_macro!(_var);\n        function_macro!();\n        let v: ty_macro!() = Vec::default();\n\n        inner::try_err!();\n        inner::mut_mut!();\n        nested::string_add!();\n    }\n}\n\n// issue #7015, ICE due to calling `module_children` with local `DefId`\n#[macro_use]\nuse a as b;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/macro_use_imports.stderr",
    "content": "error: `macro_use` attributes are no longer needed in the Rust 2018 edition\n  --> tests/ui/macro_use_imports.rs:18:5\n   |\nLL |     #[macro_use]\n   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{pub_macro, inner_mod_macro, function_macro, ty_macro, pub_in_private_macro};`\n   |\n   = note: `-D clippy::macro-use-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::macro_use_imports)]`\n\nerror: `macro_use` attributes are no longer needed in the Rust 2018 edition\n  --> tests/ui/macro_use_imports.rs:24:5\n   |\nLL |     #[macro_use]\n   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};`\n\nerror: `macro_use` attributes are no longer needed in the Rust 2018 edition\n  --> tests/ui/macro_use_imports.rs:27:5\n   |\nLL |     #[macro_use]\n   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::inner::nested::string_add;`\n\nerror: `macro_use` attributes are no longer needed in the Rust 2018 edition\n  --> tests/ui/macro_use_imports.rs:21:5\n   |\nLL |     #[macro_use]\n   |     ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mini_mac::ClippyMiniMacroTest;`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/macro_use_imports_expect.rs",
    "content": "//@ check-pass\n//@aux-build:macro_rules.rs\n//@aux-build:macro_use_helper.rs\n//@aux-build:proc_macro_derive.rs\n//@ignore-bitwidth: 32\n\n#![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]\n#![allow(clippy::single_component_path_imports)]\n#![warn(clippy::macro_use_imports)]\n\n#[macro_use]\nextern crate macro_use_helper as mac;\n\n#[macro_use]\nextern crate proc_macro_derive as mini_mac;\n\nmod a {\n    #[expect(clippy::macro_use_imports)]\n    #[macro_use]\n    use mac;\n    #[expect(clippy::macro_use_imports)]\n    #[macro_use]\n    use mini_mac;\n    #[expect(clippy::macro_use_imports)]\n    #[macro_use]\n    use mac::inner;\n    #[expect(clippy::macro_use_imports)]\n    #[macro_use]\n    use mac::inner::nested;\n\n    #[derive(ClippyMiniMacroTest)]\n    struct Test;\n\n    fn test() {\n        pub_macro!();\n        inner_mod_macro!();\n        pub_in_private_macro!(_var);\n        function_macro!();\n        let v: ty_macro!() = Vec::default();\n\n        inner::try_err!();\n        inner::mut_mut!();\n        nested::string_add!();\n    }\n}\n\n// issue #7015, ICE due to calling `module_children` with local `DefId`\n#[macro_use]\nuse a as b;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_abs_diff.fixed",
    "content": "#![warn(clippy::manual_abs_diff)]\n\nuse std::time::Duration;\n\nfn main() {\n    let a: usize = 5;\n    let b: usize = 3;\n    let c: usize = 8;\n    let d: usize = 11;\n\n    let _ = a.abs_diff(b);\n    //~^ manual_abs_diff\n    let _ = b.abs_diff(a);\n    //~^ manual_abs_diff\n\n    let _ = b.abs_diff(5);\n    //~^ manual_abs_diff\n    let _ = b.abs_diff(5);\n    //~^ manual_abs_diff\n\n    let _ = a.abs_diff(b);\n    //~^ manual_abs_diff\n    let _ = b.abs_diff(a);\n    //~^ manual_abs_diff\n\n    #[allow(arithmetic_overflow)]\n    {\n        let _ = if a > b { b - a } else { a - b };\n        let _ = if a < b { a - b } else { b - a };\n    }\n\n    let _ = (a + b).abs_diff(c + d);\n    let _ = (c + d).abs_diff(a + b);\n\n    const A: usize = 5;\n    const B: usize = 3;\n    // check const context\n    const _: usize = A.abs_diff(B);\n    //~^ manual_abs_diff\n\n    let a = Duration::from_secs(3);\n    let b = Duration::from_secs(5);\n    let _ = a.abs_diff(b);\n    //~^ manual_abs_diff\n\n    let a: i32 = 3;\n    let b: i32 = -5;\n    let _ = if a > b { a - b } else { b - a };\n    let _ = a.abs_diff(b);\n    //~^ manual_abs_diff\n}\n\n// FIXME: bunch of patterns that should be linted\nfn fixme() {\n    let a: usize = 5;\n    let b: usize = 3;\n    let c: usize = 8;\n    let d: usize = 11;\n\n    {\n        let out;\n        if a > b {\n            out = a - b;\n        } else {\n            out = b - a;\n        }\n    }\n\n    {\n        let mut out = 0;\n        if a > b {\n            out = a - b;\n        } else if a < b {\n            out = b - a;\n        }\n    }\n\n    #[allow(clippy::implicit_saturating_sub)]\n    let _ = if a > b {\n        a - b\n    } else if a < b {\n        b - a\n    } else {\n        0\n    };\n\n    let a: i32 = 3;\n    let b: i32 = 5;\n    let _: u32 = if a > b { a - b } else { b - a } as u32;\n}\n\nfn non_primitive_ty() {\n    #[derive(Eq, PartialEq, PartialOrd)]\n    struct S(i32);\n\n    impl std::ops::Sub for S {\n        type Output = S;\n\n        fn sub(self, rhs: Self) -> Self::Output {\n            Self(self.0 - rhs.0)\n        }\n    }\n\n    let (a, b) = (S(10), S(20));\n    let _ = if a < b { b - a } else { a - b };\n}\n\nfn issue15254(a: &usize, b: &usize) -> usize {\n    b.abs_diff(*a)\n}\n"
  },
  {
    "path": "tests/ui/manual_abs_diff.rs",
    "content": "#![warn(clippy::manual_abs_diff)]\n\nuse std::time::Duration;\n\nfn main() {\n    let a: usize = 5;\n    let b: usize = 3;\n    let c: usize = 8;\n    let d: usize = 11;\n\n    let _ = if a > b { a - b } else { b - a };\n    //~^ manual_abs_diff\n    let _ = if a < b { b - a } else { a - b };\n    //~^ manual_abs_diff\n\n    let _ = if 5 > b { 5 - b } else { b - 5 };\n    //~^ manual_abs_diff\n    let _ = if b > 5 { b - 5 } else { 5 - b };\n    //~^ manual_abs_diff\n\n    let _ = if a >= b { a - b } else { b - a };\n    //~^ manual_abs_diff\n    let _ = if a <= b { b - a } else { a - b };\n    //~^ manual_abs_diff\n\n    #[allow(arithmetic_overflow)]\n    {\n        let _ = if a > b { b - a } else { a - b };\n        let _ = if a < b { a - b } else { b - a };\n    }\n\n    let _ = if (a + b) > (c + d) {\n        //~^ manual_abs_diff\n        (a + b) - (c + d)\n    } else {\n        (c + d) - (a + b)\n    };\n    let _ = if (a + b) < (c + d) {\n        //~^ manual_abs_diff\n        (c + d) - (a + b)\n    } else {\n        (a + b) - (c + d)\n    };\n\n    const A: usize = 5;\n    const B: usize = 3;\n    // check const context\n    const _: usize = if A > B { A - B } else { B - A };\n    //~^ manual_abs_diff\n\n    let a = Duration::from_secs(3);\n    let b = Duration::from_secs(5);\n    let _ = if a > b { a - b } else { b - a };\n    //~^ manual_abs_diff\n\n    let a: i32 = 3;\n    let b: i32 = -5;\n    let _ = if a > b { a - b } else { b - a };\n    let _ = if a > b { (a - b) as u32 } else { (b - a) as u32 };\n    //~^ manual_abs_diff\n}\n\n// FIXME: bunch of patterns that should be linted\nfn fixme() {\n    let a: usize = 5;\n    let b: usize = 3;\n    let c: usize = 8;\n    let d: usize = 11;\n\n    {\n        let out;\n        if a > b {\n            out = a - b;\n        } else {\n            out = b - a;\n        }\n    }\n\n    {\n        let mut out = 0;\n        if a > b {\n            out = a - b;\n        } else if a < b {\n            out = b - a;\n        }\n    }\n\n    #[allow(clippy::implicit_saturating_sub)]\n    let _ = if a > b {\n        a - b\n    } else if a < b {\n        b - a\n    } else {\n        0\n    };\n\n    let a: i32 = 3;\n    let b: i32 = 5;\n    let _: u32 = if a > b { a - b } else { b - a } as u32;\n}\n\nfn non_primitive_ty() {\n    #[derive(Eq, PartialEq, PartialOrd)]\n    struct S(i32);\n\n    impl std::ops::Sub for S {\n        type Output = S;\n\n        fn sub(self, rhs: Self) -> Self::Output {\n            Self(self.0 - rhs.0)\n        }\n    }\n\n    let (a, b) = (S(10), S(20));\n    let _ = if a < b { b - a } else { a - b };\n}\n\nfn issue15254(a: &usize, b: &usize) -> usize {\n    if a < b {\n        //~^ manual_abs_diff\n        b - a\n    } else {\n        a - b\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_abs_diff.stderr",
    "content": "error: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:11:13\n   |\nLL |     let _ = if a > b { a - b } else { b - a };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `a.abs_diff(b)`\n   |\n   = note: `-D clippy::manual-abs-diff` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_abs_diff)]`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:13:13\n   |\nLL |     let _ = if a < b { b - a } else { a - b };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `b.abs_diff(a)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:16:13\n   |\nLL |     let _ = if 5 > b { 5 - b } else { b - 5 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `b.abs_diff(5)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:18:13\n   |\nLL |     let _ = if b > 5 { b - 5 } else { 5 - b };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `b.abs_diff(5)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:21:13\n   |\nLL |     let _ = if a >= b { a - b } else { b - a };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `a.abs_diff(b)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:23:13\n   |\nLL |     let _ = if a <= b { b - a } else { a - b };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `b.abs_diff(a)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:32:13\n   |\nLL |       let _ = if (a + b) > (c + d) {\n   |  _____________^\nLL | |\nLL | |         (a + b) - (c + d)\nLL | |     } else {\nLL | |         (c + d) - (a + b)\nLL | |     };\n   | |_____^ help: replace with `abs_diff`: `(a + b).abs_diff(c + d)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:38:13\n   |\nLL |       let _ = if (a + b) < (c + d) {\n   |  _____________^\nLL | |\nLL | |         (c + d) - (a + b)\nLL | |     } else {\nLL | |         (a + b) - (c + d)\nLL | |     };\n   | |_____^ help: replace with `abs_diff`: `(c + d).abs_diff(a + b)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:48:22\n   |\nLL |     const _: usize = if A > B { A - B } else { B - A };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `A.abs_diff(B)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:53:13\n   |\nLL |     let _ = if a > b { a - b } else { b - a };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `a.abs_diff(b)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:59:13\n   |\nLL |     let _ = if a > b { (a - b) as u32 } else { (b - a) as u32 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `a.abs_diff(b)`\n\nerror: manual absolute difference pattern without using `abs_diff`\n  --> tests/ui/manual_abs_diff.rs:119:5\n   |\nLL | /     if a < b {\nLL | |\nLL | |         b - a\nLL | |     } else {\nLL | |         a - b\nLL | |     }\n   | |_____^ help: replace with `abs_diff`: `b.abs_diff(*a)`\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_arithmetic_check-2.rs",
    "content": "//@no-rustfix\n#![warn(clippy::implicit_saturating_sub)]\n#![allow(arithmetic_overflow)]\n\nfn main() {\n    let a = 12u32;\n    let b = 13u32;\n\n    let result = if a > b { b - a } else { 0 };\n    //~^ inverted_saturating_sub\n\n    let result = if b < a { b - a } else { 0 };\n    //~^ inverted_saturating_sub\n\n    let result = if a > b { 0 } else { a - b };\n    //~^ inverted_saturating_sub\n\n    let result = if a >= b { 0 } else { a - b };\n    //~^ inverted_saturating_sub\n\n    let result = if b < a { 0 } else { a - b };\n    //~^ inverted_saturating_sub\n\n    let result = if b <= a { 0 } else { a - b };\n    //~^ inverted_saturating_sub\n\n    let result = if b * 2 <= a { 0 } else { a - b * 2 };\n    //~^ inverted_saturating_sub\n\n    let result = if b <= a * 2 { 0 } else { a * 2 - b };\n    //~^ inverted_saturating_sub\n\n    let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };\n    //~^ inverted_saturating_sub\n\n    let af = 12f32;\n    let bf = 13f32;\n    // Should not lint!\n    let result = if bf < af { 0. } else { af - bf };\n\n    // Should not lint!\n    let result = if a < b {\n        println!(\"we shouldn't remove this\");\n        0\n    } else {\n        a - b\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_arithmetic_check-2.stderr",
    "content": "error: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:9:23\n   |\nLL |     let result = if a > b { b - a } else { 0 };\n   |                       ^     ----- help: try replacing it with: `a - b`\n   |\nnote: this subtraction underflows when `b < a`\n  --> tests/ui/manual_arithmetic_check-2.rs:9:29\n   |\nLL |     let result = if a > b { b - a } else { 0 };\n   |                             ^^^^^\n   = note: `#[deny(clippy::inverted_saturating_sub)]` on by default\n\nerror: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:12:23\n   |\nLL |     let result = if b < a { b - a } else { 0 };\n   |                       ^     ----- help: try replacing it with: `a - b`\n   |\nnote: this subtraction underflows when `b < a`\n  --> tests/ui/manual_arithmetic_check-2.rs:12:29\n   |\nLL |     let result = if b < a { b - a } else { 0 };\n   |                             ^^^^^\n\nerror: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:15:23\n   |\nLL |     let result = if a > b { 0 } else { a - b };\n   |                       ^                ----- help: try replacing it with: `b - a`\n   |\nnote: this subtraction underflows when `a < b`\n  --> tests/ui/manual_arithmetic_check-2.rs:15:40\n   |\nLL |     let result = if a > b { 0 } else { a - b };\n   |                                        ^^^^^\n\nerror: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:18:23\n   |\nLL |     let result = if a >= b { 0 } else { a - b };\n   |                       ^^                ----- help: try replacing it with: `b - a`\n   |\nnote: this subtraction underflows when `a < b`\n  --> tests/ui/manual_arithmetic_check-2.rs:18:41\n   |\nLL |     let result = if a >= b { 0 } else { a - b };\n   |                                         ^^^^^\n\nerror: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:21:23\n   |\nLL |     let result = if b < a { 0 } else { a - b };\n   |                       ^                ----- help: try replacing it with: `b - a`\n   |\nnote: this subtraction underflows when `a < b`\n  --> tests/ui/manual_arithmetic_check-2.rs:21:40\n   |\nLL |     let result = if b < a { 0 } else { a - b };\n   |                                        ^^^^^\n\nerror: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:24:23\n   |\nLL |     let result = if b <= a { 0 } else { a - b };\n   |                       ^^                ----- help: try replacing it with: `b - a`\n   |\nnote: this subtraction underflows when `a < b`\n  --> tests/ui/manual_arithmetic_check-2.rs:24:41\n   |\nLL |     let result = if b <= a { 0 } else { a - b };\n   |                                         ^^^^^\n\nerror: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:27:27\n   |\nLL |     let result = if b * 2 <= a { 0 } else { a - b * 2 };\n   |                           ^^                --------- help: try replacing it with: `b * 2 - a`\n   |\nnote: this subtraction underflows when `a < b * 2`\n  --> tests/ui/manual_arithmetic_check-2.rs:27:45\n   |\nLL |     let result = if b * 2 <= a { 0 } else { a - b * 2 };\n   |                                             ^^^^^^^^^\n\nerror: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:30:23\n   |\nLL |     let result = if b <= a * 2 { 0 } else { a * 2 - b };\n   |                       ^^                    --------- help: try replacing it with: `b - a * 2`\n   |\nnote: this subtraction underflows when `a * 2 < b`\n  --> tests/ui/manual_arithmetic_check-2.rs:30:45\n   |\nLL |     let result = if b <= a * 2 { 0 } else { a * 2 - b };\n   |                                             ^^^^^^^^^\n\nerror: inverted arithmetic check before subtraction\n  --> tests/ui/manual_arithmetic_check-2.rs:33:27\n   |\nLL |     let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };\n   |                           ^^                    ----------------- help: try replacing it with: `b + 3 - (a + 2)`\n   |\nnote: this subtraction underflows when `a + 2 < b + 3`\n  --> tests/ui/manual_arithmetic_check-2.rs:33:49\n   |\nLL |     let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };\n   |                                                 ^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_arithmetic_check.fixed",
    "content": "#![warn(clippy::implicit_saturating_sub, clippy::inverted_saturating_sub)]\n#![allow(clippy::if_same_then_else)]\n\nfn main() {\n    let a = 12u32;\n    let b = 13u32;\n    let c = 8u32;\n\n    let result = a.saturating_sub(b);\n    //~^ implicit_saturating_sub\n\n    let result = a.saturating_sub(b);\n    //~^ implicit_saturating_sub\n\n    let result = a.saturating_sub(b);\n    //~^ implicit_saturating_sub\n\n    let result = a.saturating_sub(b);\n    //~^ implicit_saturating_sub\n\n    // Should not warn!\n    let result = if a > b { a - b } else { a - c };\n\n    // Just to check it won't break clippy.\n    let result = if b > a { 0 } else { 0 };\n}\n"
  },
  {
    "path": "tests/ui/manual_arithmetic_check.rs",
    "content": "#![warn(clippy::implicit_saturating_sub, clippy::inverted_saturating_sub)]\n#![allow(clippy::if_same_then_else)]\n\nfn main() {\n    let a = 12u32;\n    let b = 13u32;\n    let c = 8u32;\n\n    let result = if a > b { a - b } else { 0 };\n    //~^ implicit_saturating_sub\n\n    let result = if b < a { a - b } else { 0 };\n    //~^ implicit_saturating_sub\n\n    let result = if a < b { 0 } else { a - b };\n    //~^ implicit_saturating_sub\n\n    let result = if b > a { 0 } else { a - b };\n    //~^ implicit_saturating_sub\n\n    // Should not warn!\n    let result = if a > b { a - b } else { a - c };\n\n    // Just to check it won't break clippy.\n    let result = if b > a { 0 } else { 0 };\n}\n"
  },
  {
    "path": "tests/ui/manual_arithmetic_check.stderr",
    "content": "error: manual arithmetic check found\n  --> tests/ui/manual_arithmetic_check.rs:9:18\n   |\nLL |     let result = if a > b { a - b } else { 0 };\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`\n   |\n   = note: `-D clippy::implicit-saturating-sub` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_sub)]`\n\nerror: manual arithmetic check found\n  --> tests/ui/manual_arithmetic_check.rs:12:18\n   |\nLL |     let result = if b < a { a - b } else { 0 };\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`\n\nerror: manual arithmetic check found\n  --> tests/ui/manual_arithmetic_check.rs:15:18\n   |\nLL |     let result = if a < b { 0 } else { a - b };\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`\n\nerror: manual arithmetic check found\n  --> tests/ui/manual_arithmetic_check.rs:18:18\n   |\nLL |     let result = if b > a { 0 } else { a - b };\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_assert.edition2018.fixed",
    "content": "//@revisions: edition2018 edition2021\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n\n#![warn(clippy::manual_assert)]\n#![allow(dead_code, unused_doc_comments)]\n#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]\n\nmacro_rules! one {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    let a = vec![1, 2, 3];\n    let c = Some(2);\n    if !a.is_empty()\n        && a.len() == 3\n        && c.is_some()\n        && !a.is_empty()\n        && a.len() == 3\n        && !a.is_empty()\n        && a.len() == 3\n        && !a.is_empty()\n        && a.len() == 3\n    {\n        panic!(\"qaqaq{:?}\", a);\n    }\n    //~^ manual_assert\n    assert!(a.is_empty(), \"qaqaq{:?}\", a);\n    //~^ manual_assert\n    assert!(a.is_empty(), \"qwqwq\");\n    if a.len() == 3 {\n        println!(\"qwq\");\n        println!(\"qwq\");\n        println!(\"qwq\");\n    }\n    if let Some(b) = c {\n        panic!(\"orz {}\", b);\n    }\n    if a.len() == 3 {\n        panic!(\"qaqaq\");\n    } else {\n        println!(\"qwq\");\n    }\n    let b = vec![1, 2, 3];\n    //~^ manual_assert\n    assert!(!b.is_empty(), \"panic1\");\n    //~^ manual_assert\n    assert!(!(b.is_empty() && a.is_empty()), \"panic2\");\n    //~^ manual_assert\n    assert!(!(a.is_empty() && !b.is_empty()), \"panic3\");\n    //~^ manual_assert\n    assert!(!(b.is_empty() || a.is_empty()), \"panic4\");\n    //~^ manual_assert\n    assert!(!(a.is_empty() || !b.is_empty()), \"panic5\");\n    //~^ manual_assert\n    assert!(!a.is_empty(), \"with expansion {}\", one!());\n    if a.is_empty() {\n        let _ = 0;\n    } else if a.len() == 1 {\n        panic!(\"panic6\");\n    }\n}\n\nfn issue7730(a: u8) {\n    // Suggestion should preserve comment\n    //~^ manual_assert\n    // comment\n    /* this is a\n            multiline\n            comment */\n    /// Doc comment\n    // comment after `panic!`\n    assert!(a <= 2, \"panic with comment\");\n}\n\nfn issue12505() {\n    struct Foo<T, const N: usize>(T);\n\n    impl<T, const N: usize> Foo<T, N> {\n        const BAR: () = //~^ manual_assert\n        assert!(N != 0, );\n    }\n}\n\nfn issue15227(left: u64, right: u64) -> u64 {\n    macro_rules! is_x86_feature_detected {\n        ($feature:literal) => {\n            $feature.len() > 0 && $feature.starts_with(\"ss\")\n        };\n    }\n\n    //~^ manual_assert\n    assert!(is_x86_feature_detected!(\"ssse3\"), \"SSSE3 is not supported\");\n    unsafe { todo!() }\n}\n"
  },
  {
    "path": "tests/ui/manual_assert.edition2018.stderr",
    "content": "error: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:30:5\n   |\nLL | /     if !a.is_empty() {\nLL | |\nLL | |         panic!(\"qaqaq{:?}\", a);\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::manual-assert` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_assert)]`\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(a.is_empty(), \"qaqaq{:?}\", a);\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:34:5\n   |\nLL | /     if !a.is_empty() {\nLL | |\nLL | |         panic!(\"qwqwq\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(a.is_empty(), \"qwqwq\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:52:5\n   |\nLL | /     if b.is_empty() {\nLL | |\nLL | |         panic!(\"panic1\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!b.is_empty(), \"panic1\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:56:5\n   |\nLL | /     if b.is_empty() && a.is_empty() {\nLL | |\nLL | |         panic!(\"panic2\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!(b.is_empty() && a.is_empty()), \"panic2\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:60:5\n   |\nLL | /     if a.is_empty() && !b.is_empty() {\nLL | |\nLL | |         panic!(\"panic3\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!(a.is_empty() && !b.is_empty()), \"panic3\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:64:5\n   |\nLL | /     if b.is_empty() || a.is_empty() {\nLL | |\nLL | |         panic!(\"panic4\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!(b.is_empty() || a.is_empty()), \"panic4\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:68:5\n   |\nLL | /     if a.is_empty() || !b.is_empty() {\nLL | |\nLL | |         panic!(\"panic5\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!(a.is_empty() || !b.is_empty()), \"panic5\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:72:5\n   |\nLL | /     if a.is_empty() {\nLL | |\nLL | |         panic!(\"with expansion {}\", one!())\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!a.is_empty(), \"with expansion {}\", one!());\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:85:5\n   |\nLL | /     if a > 2 {\nLL | |\nLL | |         // comment\nLL | |         /* this is a\n...  |\nLL | |         panic!(\"panic with comment\") // comment after `panic!`\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     // comment\nLL +     /* this is a\nLL +             multiline\nLL +             comment */\nLL +     /// Doc comment\nLL +     // comment after `panic!`\nLL +     assert!(a <= 2, \"panic with comment\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:100:25\n   |\nLL |           const BAR: () = if N == 0 {\n   |  _________________________^\nLL | |\nLL | |             panic!()\nLL | |         };\n   | |_________^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~         const BAR: () =\nLL ~         assert!(N != 0, );\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:114:5\n   |\nLL | /     if !is_x86_feature_detected!(\"ssse3\") {\nLL | |\nLL | |         panic!(\"SSSE3 is not supported\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(is_x86_feature_detected!(\"ssse3\"), \"SSSE3 is not supported\");\n   |\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_assert.edition2021.fixed",
    "content": "//@revisions: edition2018 edition2021\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n\n#![warn(clippy::manual_assert)]\n#![allow(dead_code, unused_doc_comments)]\n#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]\n\nmacro_rules! one {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    let a = vec![1, 2, 3];\n    let c = Some(2);\n    if !a.is_empty()\n        && a.len() == 3\n        && c.is_some()\n        && !a.is_empty()\n        && a.len() == 3\n        && !a.is_empty()\n        && a.len() == 3\n        && !a.is_empty()\n        && a.len() == 3\n    {\n        panic!(\"qaqaq{:?}\", a);\n    }\n    //~^ manual_assert\n    assert!(a.is_empty(), \"qaqaq{:?}\", a);\n    //~^ manual_assert\n    assert!(a.is_empty(), \"qwqwq\");\n    if a.len() == 3 {\n        println!(\"qwq\");\n        println!(\"qwq\");\n        println!(\"qwq\");\n    }\n    if let Some(b) = c {\n        panic!(\"orz {}\", b);\n    }\n    if a.len() == 3 {\n        panic!(\"qaqaq\");\n    } else {\n        println!(\"qwq\");\n    }\n    let b = vec![1, 2, 3];\n    //~^ manual_assert\n    assert!(!b.is_empty(), \"panic1\");\n    //~^ manual_assert\n    assert!(!(b.is_empty() && a.is_empty()), \"panic2\");\n    //~^ manual_assert\n    assert!(!(a.is_empty() && !b.is_empty()), \"panic3\");\n    //~^ manual_assert\n    assert!(!(b.is_empty() || a.is_empty()), \"panic4\");\n    //~^ manual_assert\n    assert!(!(a.is_empty() || !b.is_empty()), \"panic5\");\n    //~^ manual_assert\n    assert!(!a.is_empty(), \"with expansion {}\", one!());\n    if a.is_empty() {\n        let _ = 0;\n    } else if a.len() == 1 {\n        panic!(\"panic6\");\n    }\n}\n\nfn issue7730(a: u8) {\n    // Suggestion should preserve comment\n    //~^ manual_assert\n    // comment\n    /* this is a\n            multiline\n            comment */\n    /// Doc comment\n    // comment after `panic!`\n    assert!(a <= 2, \"panic with comment\");\n}\n\nfn issue12505() {\n    struct Foo<T, const N: usize>(T);\n\n    impl<T, const N: usize> Foo<T, N> {\n        const BAR: () = //~^ manual_assert\n        assert!(N != 0, );\n    }\n}\n\nfn issue15227(left: u64, right: u64) -> u64 {\n    macro_rules! is_x86_feature_detected {\n        ($feature:literal) => {\n            $feature.len() > 0 && $feature.starts_with(\"ss\")\n        };\n    }\n\n    //~^ manual_assert\n    assert!(is_x86_feature_detected!(\"ssse3\"), \"SSSE3 is not supported\");\n    unsafe { todo!() }\n}\n"
  },
  {
    "path": "tests/ui/manual_assert.edition2021.stderr",
    "content": "error: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:30:5\n   |\nLL | /     if !a.is_empty() {\nLL | |\nLL | |         panic!(\"qaqaq{:?}\", a);\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::manual-assert` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_assert)]`\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(a.is_empty(), \"qaqaq{:?}\", a);\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:34:5\n   |\nLL | /     if !a.is_empty() {\nLL | |\nLL | |         panic!(\"qwqwq\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(a.is_empty(), \"qwqwq\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:52:5\n   |\nLL | /     if b.is_empty() {\nLL | |\nLL | |         panic!(\"panic1\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!b.is_empty(), \"panic1\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:56:5\n   |\nLL | /     if b.is_empty() && a.is_empty() {\nLL | |\nLL | |         panic!(\"panic2\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!(b.is_empty() && a.is_empty()), \"panic2\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:60:5\n   |\nLL | /     if a.is_empty() && !b.is_empty() {\nLL | |\nLL | |         panic!(\"panic3\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!(a.is_empty() && !b.is_empty()), \"panic3\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:64:5\n   |\nLL | /     if b.is_empty() || a.is_empty() {\nLL | |\nLL | |         panic!(\"panic4\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!(b.is_empty() || a.is_empty()), \"panic4\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:68:5\n   |\nLL | /     if a.is_empty() || !b.is_empty() {\nLL | |\nLL | |         panic!(\"panic5\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!(a.is_empty() || !b.is_empty()), \"panic5\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:72:5\n   |\nLL | /     if a.is_empty() {\nLL | |\nLL | |         panic!(\"with expansion {}\", one!())\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(!a.is_empty(), \"with expansion {}\", one!());\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:85:5\n   |\nLL | /     if a > 2 {\nLL | |\nLL | |         // comment\nLL | |         /* this is a\n...  |\nLL | |         panic!(\"panic with comment\") // comment after `panic!`\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     // comment\nLL +     /* this is a\nLL +             multiline\nLL +             comment */\nLL +     /// Doc comment\nLL +     // comment after `panic!`\nLL +     assert!(a <= 2, \"panic with comment\");\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:100:25\n   |\nLL |           const BAR: () = if N == 0 {\n   |  _________________________^\nLL | |\nLL | |             panic!()\nLL | |         };\n   | |_________^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~         const BAR: () =\nLL ~         assert!(N != 0, );\n   |\n\nerror: only a `panic!` in `if`-then statement\n  --> tests/ui/manual_assert.rs:114:5\n   |\nLL | /     if !is_x86_feature_detected!(\"ssse3\") {\nLL | |\nLL | |         panic!(\"SSSE3 is not supported\");\nLL | |     }\n   | |_____^\n   |\nhelp: replace `if`-then-`panic!` with `assert!`\n   |\nLL ~\nLL +     assert!(is_x86_feature_detected!(\"ssse3\"), \"SSSE3 is not supported\");\n   |\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_assert.rs",
    "content": "//@revisions: edition2018 edition2021\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n\n#![warn(clippy::manual_assert)]\n#![allow(dead_code, unused_doc_comments)]\n#![allow(clippy::nonminimal_bool, clippy::uninlined_format_args, clippy::useless_vec)]\n\nmacro_rules! one {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    let a = vec![1, 2, 3];\n    let c = Some(2);\n    if !a.is_empty()\n        && a.len() == 3\n        && c.is_some()\n        && !a.is_empty()\n        && a.len() == 3\n        && !a.is_empty()\n        && a.len() == 3\n        && !a.is_empty()\n        && a.len() == 3\n    {\n        panic!(\"qaqaq{:?}\", a);\n    }\n    if !a.is_empty() {\n        //~^ manual_assert\n        panic!(\"qaqaq{:?}\", a);\n    }\n    if !a.is_empty() {\n        //~^ manual_assert\n        panic!(\"qwqwq\");\n    }\n    if a.len() == 3 {\n        println!(\"qwq\");\n        println!(\"qwq\");\n        println!(\"qwq\");\n    }\n    if let Some(b) = c {\n        panic!(\"orz {}\", b);\n    }\n    if a.len() == 3 {\n        panic!(\"qaqaq\");\n    } else {\n        println!(\"qwq\");\n    }\n    let b = vec![1, 2, 3];\n    if b.is_empty() {\n        //~^ manual_assert\n        panic!(\"panic1\");\n    }\n    if b.is_empty() && a.is_empty() {\n        //~^ manual_assert\n        panic!(\"panic2\");\n    }\n    if a.is_empty() && !b.is_empty() {\n        //~^ manual_assert\n        panic!(\"panic3\");\n    }\n    if b.is_empty() || a.is_empty() {\n        //~^ manual_assert\n        panic!(\"panic4\");\n    }\n    if a.is_empty() || !b.is_empty() {\n        //~^ manual_assert\n        panic!(\"panic5\");\n    }\n    if a.is_empty() {\n        //~^ manual_assert\n        panic!(\"with expansion {}\", one!())\n    }\n    if a.is_empty() {\n        let _ = 0;\n    } else if a.len() == 1 {\n        panic!(\"panic6\");\n    }\n}\n\nfn issue7730(a: u8) {\n    // Suggestion should preserve comment\n    if a > 2 {\n        //~^ manual_assert\n        // comment\n        /* this is a\n        multiline\n        comment */\n        /// Doc comment\n        panic!(\"panic with comment\") // comment after `panic!`\n    }\n}\n\nfn issue12505() {\n    struct Foo<T, const N: usize>(T);\n\n    impl<T, const N: usize> Foo<T, N> {\n        const BAR: () = if N == 0 {\n            //~^ manual_assert\n            panic!()\n        };\n    }\n}\n\nfn issue15227(left: u64, right: u64) -> u64 {\n    macro_rules! is_x86_feature_detected {\n        ($feature:literal) => {\n            $feature.len() > 0 && $feature.starts_with(\"ss\")\n        };\n    }\n\n    if !is_x86_feature_detected!(\"ssse3\") {\n        //~^ manual_assert\n        panic!(\"SSSE3 is not supported\");\n    }\n    unsafe { todo!() }\n}\n"
  },
  {
    "path": "tests/ui/manual_async_fn.fixed",
    "content": "#![warn(clippy::manual_async_fn)]\n#![allow(clippy::needless_pub_self, unused)]\n\nuse std::future::Future;\n\nasync fn fut() -> i32 { 42 }\n\n#[rustfmt::skip]\nasync fn fut2() -> i32 { 42 }\n\n#[rustfmt::skip]\nasync fn fut3() -> i32 { 42 }\n\nasync fn empty_fut() {}\n\n#[rustfmt::skip]\nasync fn empty_fut2() {}\n\n#[rustfmt::skip]\nasync fn empty_fut3() {}\n\nasync fn core_fut() -> i32 { 42 }\n\n// should be ignored\nfn has_other_stmts() -> impl core::future::Future<Output = i32> {\n    let _ = 42;\n    async move { 42 }\n}\n\n// should be ignored\nfn not_fut() -> i32 {\n    42\n}\n\n// should be ignored\nasync fn already_async() -> impl Future<Output = i32> {\n    async { 42 }\n}\n\nstruct S;\nimpl S {\n    async fn inh_fut() -> i32 {\n        // NOTE: this code is here just to check that the indentation is correct in the suggested fix\n        let a = 42;\n        let b = 21;\n        if a < b {\n            let c = 21;\n            let d = 42;\n            if c < d {\n                let _ = 42;\n            }\n        }\n        42\n    }\n\n    // should be ignored\n    fn not_fut(&self) -> i32 {\n        42\n    }\n\n    // should be ignored\n    fn has_other_stmts() -> impl core::future::Future<Output = i32> {\n        let _ = 42;\n        async move { 42 }\n    }\n\n    // should be ignored\n    async fn already_async(&self) -> impl Future<Output = i32> {\n        async { 42 }\n    }\n}\n\n// Tests related to lifetime capture\n\nasync fn elided(_: &i32) -> i32 { 42 }\n\n// should be ignored\nfn elided_not_bound(_: &i32) -> impl Future<Output = i32> + use<> {\n    async { 42 }\n}\n\n#[allow(clippy::needless_lifetimes)]\nasync fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }\n\n// should be ignored\n#[allow(clippy::needless_lifetimes)]\nfn explicit_not_bound<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + use<> {\n    async { 42 }\n}\n\n// should be ignored\nmod issue_5765 {\n    use std::future::Future;\n\n    struct A;\n    impl A {\n        fn f(&self) -> impl Future<Output = ()> + use<> {\n            async {}\n        }\n    }\n\n    fn test() {\n        let _future = {\n            let a = A;\n            a.f()\n        };\n    }\n}\n\npub async fn issue_10450() -> i32 { 42 }\n\npub(crate) async fn issue_10450_2() -> i32 { 42 }\n\npub(self) async fn issue_10450_3() -> i32 { 42 }\n\nmacro_rules! issue_12407 {\n    (\n        $(\n            $(#[$m:meta])*\n            $v:vis $(override($($overrides:tt),* $(,)?))? fn $name:ident $([$($params:tt)*])? (\n                $($arg_name:ident: $arg_typ:ty),* $(,)?\n            ) $(-> $ret_ty:ty)? = $e:expr;\n        )*\n    ) => {\n        $(\n            $(#[$m])*\n            $v $($($overrides)*)? fn $name$(<$($params)*>)?(\n                $($arg_name: $arg_typ),*\n            ) $(-> $ret_ty)? {\n                $e\n            }\n        )*\n    };\n}\n\nissue_12407! {\n    fn _hello() -> impl Future<Output = ()> = async {};\n    fn non_async() = println!(\"hello\");\n    fn foo() = non_async();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_async_fn.rs",
    "content": "#![warn(clippy::manual_async_fn)]\n#![allow(clippy::needless_pub_self, unused)]\n\nuse std::future::Future;\n\nfn fut() -> impl Future<Output = i32> {\n    //~^ manual_async_fn\n    async { 42 }\n}\n\n#[rustfmt::skip]\nfn fut2() ->impl Future<Output = i32> {\n//~^ manual_async_fn\n    async { 42 }\n}\n\n#[rustfmt::skip]\nfn fut3()-> impl Future<Output = i32> {\n//~^ manual_async_fn\n    async { 42 }\n}\n\nfn empty_fut() -> impl Future<Output = ()> {\n    //~^ manual_async_fn\n    async {}\n}\n\n#[rustfmt::skip]\nfn empty_fut2() ->impl Future<Output = ()> {\n//~^ manual_async_fn\n    async {}\n}\n\n#[rustfmt::skip]\nfn empty_fut3()-> impl Future<Output = ()> {\n//~^ manual_async_fn\n    async {}\n}\n\nfn core_fut() -> impl core::future::Future<Output = i32> {\n    //~^ manual_async_fn\n    async move { 42 }\n}\n\n// should be ignored\nfn has_other_stmts() -> impl core::future::Future<Output = i32> {\n    let _ = 42;\n    async move { 42 }\n}\n\n// should be ignored\nfn not_fut() -> i32 {\n    42\n}\n\n// should be ignored\nasync fn already_async() -> impl Future<Output = i32> {\n    async { 42 }\n}\n\nstruct S;\nimpl S {\n    fn inh_fut() -> impl Future<Output = i32> {\n        //~^ manual_async_fn\n        async {\n            // NOTE: this code is here just to check that the indentation is correct in the suggested fix\n            let a = 42;\n            let b = 21;\n            if a < b {\n                let c = 21;\n                let d = 42;\n                if c < d {\n                    let _ = 42;\n                }\n            }\n            42\n        }\n    }\n\n    // should be ignored\n    fn not_fut(&self) -> i32 {\n        42\n    }\n\n    // should be ignored\n    fn has_other_stmts() -> impl core::future::Future<Output = i32> {\n        let _ = 42;\n        async move { 42 }\n    }\n\n    // should be ignored\n    async fn already_async(&self) -> impl Future<Output = i32> {\n        async { 42 }\n    }\n}\n\n// Tests related to lifetime capture\n\nfn elided(_: &i32) -> impl Future<Output = i32> + '_ {\n    //~^ manual_async_fn\n    async { 42 }\n}\n\n// should be ignored\nfn elided_not_bound(_: &i32) -> impl Future<Output = i32> + use<> {\n    async { 42 }\n}\n\n#[allow(clippy::needless_lifetimes)]\nfn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {\n    //~^ manual_async_fn\n    async { 42 }\n}\n\n// should be ignored\n#[allow(clippy::needless_lifetimes)]\nfn explicit_not_bound<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + use<> {\n    async { 42 }\n}\n\n// should be ignored\nmod issue_5765 {\n    use std::future::Future;\n\n    struct A;\n    impl A {\n        fn f(&self) -> impl Future<Output = ()> + use<> {\n            async {}\n        }\n    }\n\n    fn test() {\n        let _future = {\n            let a = A;\n            a.f()\n        };\n    }\n}\n\npub fn issue_10450() -> impl Future<Output = i32> {\n    //~^ manual_async_fn\n    async { 42 }\n}\n\npub(crate) fn issue_10450_2() -> impl Future<Output = i32> {\n    //~^ manual_async_fn\n    async { 42 }\n}\n\npub(self) fn issue_10450_3() -> impl Future<Output = i32> {\n    //~^ manual_async_fn\n    async { 42 }\n}\n\nmacro_rules! issue_12407 {\n    (\n        $(\n            $(#[$m:meta])*\n            $v:vis $(override($($overrides:tt),* $(,)?))? fn $name:ident $([$($params:tt)*])? (\n                $($arg_name:ident: $arg_typ:ty),* $(,)?\n            ) $(-> $ret_ty:ty)? = $e:expr;\n        )*\n    ) => {\n        $(\n            $(#[$m])*\n            $v $($($overrides)*)? fn $name$(<$($params)*>)?(\n                $($arg_name: $arg_typ),*\n            ) $(-> $ret_ty)? {\n                $e\n            }\n        )*\n    };\n}\n\nissue_12407! {\n    fn _hello() -> impl Future<Output = ()> = async {};\n    fn non_async() = println!(\"hello\");\n    fn foo() = non_async();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_async_fn.stderr",
    "content": "error: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:6:1\n   |\nLL | fn fut() -> impl Future<Output = i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::manual-async-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_async_fn)]`\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn fut() -> impl Future<Output = i32> {\nLL -\nLL -     async { 42 }\nLL - }\nLL + async fn fut() -> i32 { 42 }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:12:1\n   |\nLL | fn fut2() ->impl Future<Output = i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn fut2() ->impl Future<Output = i32> {\nLL -\nLL -     async { 42 }\nLL - }\nLL + async fn fut2() -> i32 { 42 }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:18:1\n   |\nLL | fn fut3()-> impl Future<Output = i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn fut3()-> impl Future<Output = i32> {\nLL -\nLL -     async { 42 }\nLL - }\nLL + async fn fut3() -> i32 { 42 }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:23:1\n   |\nLL | fn empty_fut() -> impl Future<Output = ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn empty_fut() -> impl Future<Output = ()> {\nLL -\nLL -     async {}\nLL - }\nLL + async fn empty_fut() {}\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:29:1\n   |\nLL | fn empty_fut2() ->impl Future<Output = ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn empty_fut2() ->impl Future<Output = ()> {\nLL -\nLL -     async {}\nLL - }\nLL + async fn empty_fut2() {}\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:35:1\n   |\nLL | fn empty_fut3()-> impl Future<Output = ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn empty_fut3()-> impl Future<Output = ()> {\nLL -\nLL -     async {}\nLL - }\nLL + async fn empty_fut3() {}\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:40:1\n   |\nLL | fn core_fut() -> impl core::future::Future<Output = i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn core_fut() -> impl core::future::Future<Output = i32> {\nLL -\nLL -     async move { 42 }\nLL - }\nLL + async fn core_fut() -> i32 { 42 }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:63:5\n   |\nLL |     fn inh_fut() -> impl Future<Output = i32> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL ~     async fn inh_fut() -> i32 {\nLL +         // NOTE: this code is here just to check that the indentation is correct in the suggested fix\nLL +         let a = 42;\nLL +         let b = 21;\nLL +         if a < b {\nLL +             let c = 21;\nLL +             let d = 42;\nLL +             if c < d {\nLL +                 let _ = 42;\nLL +             }\nLL +         }\nLL +         42\nLL +     }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:99:1\n   |\nLL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn elided(_: &i32) -> impl Future<Output = i32> + '_ {\nLL -\nLL -     async { 42 }\nLL - }\nLL + async fn elided(_: &i32) -> i32 { 42 }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:110:1\n   |\nLL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {\nLL -\nLL -     async { 42 }\nLL - }\nLL + async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:140:1\n   |\nLL | pub fn issue_10450() -> impl Future<Output = i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - pub fn issue_10450() -> impl Future<Output = i32> {\nLL -\nLL -     async { 42 }\nLL - }\nLL + pub async fn issue_10450() -> i32 { 42 }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:145:1\n   |\nLL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {\nLL -\nLL -     async { 42 }\nLL - }\nLL + pub(crate) async fn issue_10450_2() -> i32 { 42 }\n   |\n\nerror: this function can be simplified using the `async fn` syntax\n  --> tests/ui/manual_async_fn.rs:150:1\n   |\nLL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `async` and return the output of the future directly\n   |\nLL - pub(self) fn issue_10450_3() -> impl Future<Output = i32> {\nLL -\nLL -     async { 42 }\nLL - }\nLL + pub(self) async fn issue_10450_3() -> i32 { 42 }\n   |\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_bits.fixed",
    "content": "#![warn(clippy::manual_bits)]\n#![allow(\n    clippy::no_effect,\n    clippy::useless_conversion,\n    path_statements,\n    unused_must_use,\n    clippy::unnecessary_operation,\n    clippy::unnecessary_cast\n)]\n\nuse std::mem::{size_of, size_of_val};\n\nfn main() {\n    i8::BITS as usize;\n    //~^ manual_bits\n    i16::BITS as usize;\n    //~^ manual_bits\n    i32::BITS as usize;\n    //~^ manual_bits\n    i64::BITS as usize;\n    //~^ manual_bits\n    i128::BITS as usize;\n    //~^ manual_bits\n    isize::BITS as usize;\n    //~^ manual_bits\n\n    u8::BITS as usize;\n    //~^ manual_bits\n    u16::BITS as usize;\n    //~^ manual_bits\n    u32::BITS as usize;\n    //~^ manual_bits\n    u64::BITS as usize;\n    //~^ manual_bits\n    u128::BITS as usize;\n    //~^ manual_bits\n    usize::BITS as usize;\n    //~^ manual_bits\n\n    i8::BITS as usize;\n    //~^ manual_bits\n    i16::BITS as usize;\n    //~^ manual_bits\n    i32::BITS as usize;\n    //~^ manual_bits\n    i64::BITS as usize;\n    //~^ manual_bits\n    i128::BITS as usize;\n    //~^ manual_bits\n    isize::BITS as usize;\n    //~^ manual_bits\n\n    u8::BITS as usize;\n    //~^ manual_bits\n    u16::BITS as usize;\n    //~^ manual_bits\n    u32::BITS as usize;\n    //~^ manual_bits\n    u64::BITS as usize;\n    //~^ manual_bits\n    u128::BITS as usize;\n    //~^ manual_bits\n    usize::BITS as usize;\n    //~^ manual_bits\n\n    size_of::<usize>() * 4;\n    4 * size_of::<usize>();\n    size_of::<bool>() * 8;\n    8 * size_of::<bool>();\n\n    size_of_val(&0u32) * 8;\n\n    type Word = u32;\n    Word::BITS as usize;\n    //~^ manual_bits\n    type Bool = bool;\n    size_of::<Bool>() * 8;\n\n    let _: u32 = u128::BITS as u32;\n    //~^ manual_bits\n    let _: u32 = u128::BITS.try_into().unwrap();\n    //~^ manual_bits\n    let _ = (u128::BITS as usize).pow(5);\n    //~^ manual_bits\n    let _ = &(u128::BITS as usize);\n    //~^ manual_bits\n}\n\nfn should_not_lint() {\n    macro_rules! bits_via_macro {\n        ($T: ty) => {\n            size_of::<$T>() * 8;\n        };\n    }\n\n    bits_via_macro!(u8);\n    bits_via_macro!(String);\n}\n"
  },
  {
    "path": "tests/ui/manual_bits.rs",
    "content": "#![warn(clippy::manual_bits)]\n#![allow(\n    clippy::no_effect,\n    clippy::useless_conversion,\n    path_statements,\n    unused_must_use,\n    clippy::unnecessary_operation,\n    clippy::unnecessary_cast\n)]\n\nuse std::mem::{size_of, size_of_val};\n\nfn main() {\n    size_of::<i8>() * 8;\n    //~^ manual_bits\n    size_of::<i16>() * 8;\n    //~^ manual_bits\n    size_of::<i32>() * 8;\n    //~^ manual_bits\n    size_of::<i64>() * 8;\n    //~^ manual_bits\n    size_of::<i128>() * 8;\n    //~^ manual_bits\n    size_of::<isize>() * 8;\n    //~^ manual_bits\n\n    size_of::<u8>() * 8;\n    //~^ manual_bits\n    size_of::<u16>() * 8;\n    //~^ manual_bits\n    size_of::<u32>() * 8;\n    //~^ manual_bits\n    size_of::<u64>() * 8;\n    //~^ manual_bits\n    size_of::<u128>() * 8;\n    //~^ manual_bits\n    size_of::<usize>() * 8;\n    //~^ manual_bits\n\n    8 * size_of::<i8>();\n    //~^ manual_bits\n    8 * size_of::<i16>();\n    //~^ manual_bits\n    8 * size_of::<i32>();\n    //~^ manual_bits\n    8 * size_of::<i64>();\n    //~^ manual_bits\n    8 * size_of::<i128>();\n    //~^ manual_bits\n    8 * size_of::<isize>();\n    //~^ manual_bits\n\n    8 * size_of::<u8>();\n    //~^ manual_bits\n    8 * size_of::<u16>();\n    //~^ manual_bits\n    8 * size_of::<u32>();\n    //~^ manual_bits\n    8 * size_of::<u64>();\n    //~^ manual_bits\n    8 * size_of::<u128>();\n    //~^ manual_bits\n    8 * size_of::<usize>();\n    //~^ manual_bits\n\n    size_of::<usize>() * 4;\n    4 * size_of::<usize>();\n    size_of::<bool>() * 8;\n    8 * size_of::<bool>();\n\n    size_of_val(&0u32) * 8;\n\n    type Word = u32;\n    size_of::<Word>() * 8;\n    //~^ manual_bits\n    type Bool = bool;\n    size_of::<Bool>() * 8;\n\n    let _: u32 = (size_of::<u128>() * 8) as u32;\n    //~^ manual_bits\n    let _: u32 = (size_of::<u128>() * 8).try_into().unwrap();\n    //~^ manual_bits\n    let _ = (size_of::<u128>() * 8).pow(5);\n    //~^ manual_bits\n    let _ = &(size_of::<u128>() * 8);\n    //~^ manual_bits\n}\n\nfn should_not_lint() {\n    macro_rules! bits_via_macro {\n        ($T: ty) => {\n            size_of::<$T>() * 8;\n        };\n    }\n\n    bits_via_macro!(u8);\n    bits_via_macro!(String);\n}\n"
  },
  {
    "path": "tests/ui/manual_bits.stderr",
    "content": "error: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:14:5\n   |\nLL |     size_of::<i8>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`\n   |\n   = note: `-D clippy::manual-bits` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_bits)]`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:16:5\n   |\nLL |     size_of::<i16>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:18:5\n   |\nLL |     size_of::<i32>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:20:5\n   |\nLL |     size_of::<i64>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:22:5\n   |\nLL |     size_of::<i128>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:24:5\n   |\nLL |     size_of::<isize>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:27:5\n   |\nLL |     size_of::<u8>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:29:5\n   |\nLL |     size_of::<u16>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:31:5\n   |\nLL |     size_of::<u32>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:33:5\n   |\nLL |     size_of::<u64>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:35:5\n   |\nLL |     size_of::<u128>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:37:5\n   |\nLL |     size_of::<usize>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:40:5\n   |\nLL |     8 * size_of::<i8>();\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:42:5\n   |\nLL |     8 * size_of::<i16>();\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:44:5\n   |\nLL |     8 * size_of::<i32>();\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:46:5\n   |\nLL |     8 * size_of::<i64>();\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:48:5\n   |\nLL |     8 * size_of::<i128>();\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:50:5\n   |\nLL |     8 * size_of::<isize>();\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:53:5\n   |\nLL |     8 * size_of::<u8>();\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:55:5\n   |\nLL |     8 * size_of::<u16>();\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:57:5\n   |\nLL |     8 * size_of::<u32>();\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:59:5\n   |\nLL |     8 * size_of::<u64>();\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:61:5\n   |\nLL |     8 * size_of::<u128>();\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:63:5\n   |\nLL |     8 * size_of::<usize>();\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:74:5\n   |\nLL |     size_of::<Word>() * 8;\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS as usize`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:79:18\n   |\nLL |     let _: u32 = (size_of::<u128>() * 8) as u32;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:81:18\n   |\nLL |     let _: u32 = (size_of::<u128>() * 8).try_into().unwrap();\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:83:13\n   |\nLL |     let _ = (size_of::<u128>() * 8).pow(5);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`\n\nerror: usage of `size_of::<T>()` to obtain the size of `T` in bits\n  --> tests/ui/manual_bits.rs:85:14\n   |\nLL |     let _ = &(size_of::<u128>() * 8);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`\n\nerror: aborting due to 29 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_c_str_literals.edition2021.fixed",
    "content": "//@revisions: edition2018 edition2021\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n//@[edition2018] check-pass\n#![warn(clippy::manual_c_str_literals)]\n#![allow(clippy::no_effect)]\n\nuse std::ffi::CStr;\n\nmacro_rules! cstr {\n    ($s:literal) => {\n        CStr::from_bytes_with_nul(concat!($s, \"\\0\").as_bytes()).unwrap()\n    };\n}\n\nmacro_rules! macro_returns_c_str {\n    () => {\n        CStr::from_bytes_with_nul(b\"foo\\0\").unwrap();\n    };\n}\n\nmacro_rules! macro_returns_byte_string {\n    () => {\n        b\"foo\\0\"\n    };\n}\n\n#[clippy::msrv = \"1.76.0\"]\nfn pre_stabilization() {\n    CStr::from_bytes_with_nul(b\"foo\\0\");\n}\n\n#[clippy::msrv = \"1.77.0\"]\nfn post_stabilization() {\n    c\"foo\";\n    //~[edition2021]^ manual_c_str_literals\n}\n\nfn main() {\n    c\"foo\";\n    //~[edition2021]^ manual_c_str_literals\n    c\"foo\";\n    //~[edition2021]^ manual_c_str_literals\n    c\"foo\";\n    //~[edition2021]^ manual_c_str_literals\n    c\"foo\\\\0sdsd\";\n    //~[edition2021]^ manual_c_str_literals\n    CStr::from_bytes_with_nul(br\"foo\\\\0sdsd\\0\").unwrap();\n    CStr::from_bytes_with_nul(br\"foo\\x00\").unwrap();\n    CStr::from_bytes_with_nul(br##\"foo#a\\0\"##).unwrap();\n\n    unsafe { c\"foo\" };\n    //~[edition2021]^ manual_c_str_literals\n    unsafe { c\"foo\" };\n    //~[edition2021]^ manual_c_str_literals\n    let _: *const _ = c\"foo\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n    let _: *const _ = c\"foo\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n    let _: *const _ = \"foo\".as_ptr(); // not a C-string\n    let _: *const _ = \"\".as_ptr();\n    let _: *const _ = c\"foo\".as_ptr().cast::<i8>();\n    //~[edition2021]^ manual_c_str_literals\n    let _ = \"电脑\".as_ptr();\n    let _ = \"电脑\\\\\".as_ptr();\n    let _ = c\"电脑\\\\\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n    let _ = c\"电脑\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n    let _ = c\"电脑\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n\n    // Macro cases, don't lint:\n    cstr!(\"foo\");\n    macro_returns_c_str!();\n    CStr::from_bytes_with_nul(macro_returns_byte_string!()).unwrap();\n}\n"
  },
  {
    "path": "tests/ui/manual_c_str_literals.edition2021.stderr",
    "content": "error: calling `CStr::new` with a byte string literal\n  --> tests/ui/manual_c_str_literals.rs:35:5\n   |\nLL |     CStr::from_bytes_with_nul(b\"foo\\0\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n   |\n   = note: `-D clippy::manual-c-str-literals` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_c_str_literals)]`\n\nerror: calling `CStr::new` with a byte string literal\n  --> tests/ui/manual_c_str_literals.rs:40:5\n   |\nLL |     CStr::from_bytes_with_nul(b\"foo\\0\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n\nerror: calling `CStr::new` with a byte string literal\n  --> tests/ui/manual_c_str_literals.rs:42:5\n   |\nLL |     CStr::from_bytes_with_nul(b\"foo\\x00\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n\nerror: calling `CStr::new` with a byte string literal\n  --> tests/ui/manual_c_str_literals.rs:44:5\n   |\nLL |     CStr::from_bytes_with_nul(b\"foo\\0\").unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n\nerror: calling `CStr::new` with a byte string literal\n  --> tests/ui/manual_c_str_literals.rs:46:5\n   |\nLL |     CStr::from_bytes_with_nul(b\"foo\\\\0sdsd\\0\").unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\\\\0sdsd\"`\n\nerror: calling `CStr::from_ptr` with a byte string literal\n  --> tests/ui/manual_c_str_literals.rs:52:14\n   |\nLL |     unsafe { CStr::from_ptr(b\"foo\\0\".as_ptr().cast()) };\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n\nerror: calling `CStr::from_ptr` with a byte string literal\n  --> tests/ui/manual_c_str_literals.rs:54:14\n   |\nLL |     unsafe { CStr::from_ptr(b\"foo\\0\".as_ptr() as *const _) };\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n\nerror: manually constructing a nul-terminated string\n  --> tests/ui/manual_c_str_literals.rs:56:23\n   |\nLL |     let _: *const _ = b\"foo\\0\".as_ptr();\n   |                       ^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n\nerror: manually constructing a nul-terminated string\n  --> tests/ui/manual_c_str_literals.rs:58:23\n   |\nLL |     let _: *const _ = \"foo\\0\".as_ptr();\n   |                       ^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n\nerror: manually constructing a nul-terminated string\n  --> tests/ui/manual_c_str_literals.rs:62:23\n   |\nLL |     let _: *const _ = b\"foo\\0\".as_ptr().cast::<i8>();\n   |                       ^^^^^^^^ help: use a `c\"\"` literal: `c\"foo\"`\n\nerror: manually constructing a nul-terminated string\n  --> tests/ui/manual_c_str_literals.rs:66:13\n   |\nLL |     let _ = \"电脑\\\\\\0\".as_ptr();\n   |             ^^^^^^^^^^ help: use a `c\"\"` literal: `c\"电脑\\\\\"`\n\nerror: manually constructing a nul-terminated string\n  --> tests/ui/manual_c_str_literals.rs:68:13\n   |\nLL |     let _ = \"电脑\\0\".as_ptr();\n   |             ^^^^^^^^ help: use a `c\"\"` literal: `c\"电脑\"`\n\nerror: manually constructing a nul-terminated string\n  --> tests/ui/manual_c_str_literals.rs:70:13\n   |\nLL |     let _ = \"电脑\\x00\".as_ptr();\n   |             ^^^^^^^^^^ help: use a `c\"\"` literal: `c\"电脑\"`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_c_str_literals.rs",
    "content": "//@revisions: edition2018 edition2021\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n//@[edition2018] check-pass\n#![warn(clippy::manual_c_str_literals)]\n#![allow(clippy::no_effect)]\n\nuse std::ffi::CStr;\n\nmacro_rules! cstr {\n    ($s:literal) => {\n        CStr::from_bytes_with_nul(concat!($s, \"\\0\").as_bytes()).unwrap()\n    };\n}\n\nmacro_rules! macro_returns_c_str {\n    () => {\n        CStr::from_bytes_with_nul(b\"foo\\0\").unwrap();\n    };\n}\n\nmacro_rules! macro_returns_byte_string {\n    () => {\n        b\"foo\\0\"\n    };\n}\n\n#[clippy::msrv = \"1.76.0\"]\nfn pre_stabilization() {\n    CStr::from_bytes_with_nul(b\"foo\\0\");\n}\n\n#[clippy::msrv = \"1.77.0\"]\nfn post_stabilization() {\n    CStr::from_bytes_with_nul(b\"foo\\0\");\n    //~[edition2021]^ manual_c_str_literals\n}\n\nfn main() {\n    CStr::from_bytes_with_nul(b\"foo\\0\");\n    //~[edition2021]^ manual_c_str_literals\n    CStr::from_bytes_with_nul(b\"foo\\x00\");\n    //~[edition2021]^ manual_c_str_literals\n    CStr::from_bytes_with_nul(b\"foo\\0\").unwrap();\n    //~[edition2021]^ manual_c_str_literals\n    CStr::from_bytes_with_nul(b\"foo\\\\0sdsd\\0\").unwrap();\n    //~[edition2021]^ manual_c_str_literals\n    CStr::from_bytes_with_nul(br\"foo\\\\0sdsd\\0\").unwrap();\n    CStr::from_bytes_with_nul(br\"foo\\x00\").unwrap();\n    CStr::from_bytes_with_nul(br##\"foo#a\\0\"##).unwrap();\n\n    unsafe { CStr::from_ptr(b\"foo\\0\".as_ptr().cast()) };\n    //~[edition2021]^ manual_c_str_literals\n    unsafe { CStr::from_ptr(b\"foo\\0\".as_ptr() as *const _) };\n    //~[edition2021]^ manual_c_str_literals\n    let _: *const _ = b\"foo\\0\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n    let _: *const _ = \"foo\\0\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n    let _: *const _ = \"foo\".as_ptr(); // not a C-string\n    let _: *const _ = \"\".as_ptr();\n    let _: *const _ = b\"foo\\0\".as_ptr().cast::<i8>();\n    //~[edition2021]^ manual_c_str_literals\n    let _ = \"电脑\".as_ptr();\n    let _ = \"电脑\\\\\".as_ptr();\n    let _ = \"电脑\\\\\\0\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n    let _ = \"电脑\\0\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n    let _ = \"电脑\\x00\".as_ptr();\n    //~[edition2021]^ manual_c_str_literals\n\n    // Macro cases, don't lint:\n    cstr!(\"foo\");\n    macro_returns_c_str!();\n    CStr::from_bytes_with_nul(macro_returns_byte_string!()).unwrap();\n}\n"
  },
  {
    "path": "tests/ui/manual_checked_ops.rs",
    "content": "#![warn(clippy::manual_checked_ops)]\n\nfn main() {\n    let mut a = 10u32;\n    let mut b = 5u32;\n\n    // Should trigger lint\n    if b != 0 {\n        //~^ manual_checked_ops\n        let _result = a / b;\n        let _another = (a + 1) / b;\n    }\n\n    // Should trigger lint (compound assignment)\n    if b != 0 {\n        //~^ manual_checked_ops\n        a /= b;\n    }\n\n    if b > 0 {\n        //~^ manual_checked_ops\n        let _result = a / b;\n    }\n\n    if b == 0 {\n        //~^ manual_checked_ops\n        println!(\"zero\");\n    } else {\n        let _result = a / b;\n    }\n\n    // Should NOT trigger (already using checked_div)\n    if let Some(result) = b.checked_div(a) {\n        println!(\"{result}\");\n    }\n\n    // Should NOT trigger (signed integers are not linted)\n    let c = -5i32;\n    if c != 0 {\n        let _result = 10 / c;\n    }\n\n    // Should NOT trigger (side effects in divisor)\n    if counter() > 0 {\n        let _ = 32 / counter();\n    }\n\n    // Should NOT trigger (divisor used before division)\n    if b > 0 {\n        use_value(b);\n        let _ = a / b;\n    }\n\n    // Should NOT trigger (divisor may change during evaluation)\n    if b > 0 {\n        g(inc_and_return_value(&mut b), a / b);\n    }\n}\n\nfn counter() -> u32 {\n    println!(\"counter\");\n    1\n}\n\nfn use_value(_v: u32) {}\n\nfn inc_and_return_value(x: &mut u32) -> u32 {\n    *x += 1;\n    *x\n}\n\nfn g(_lhs: u32, _rhs: u32) {}\n"
  },
  {
    "path": "tests/ui/manual_checked_ops.stderr",
    "content": "error: manual checked division\n  --> tests/ui/manual_checked_ops.rs:8:8\n   |\nLL |     if b != 0 {\n   |        ^^^^^^ check performed here\nLL |\nLL |         let _result = a / b;\n   |                       ----- division performed here\nLL |         let _another = (a + 1) / b;\n   |                        ----------- ... and here\n   |\n   = help: consider using `checked_div`\n   = note: `-D clippy::manual-checked-ops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_checked_ops)]`\n\nerror: manual checked division\n  --> tests/ui/manual_checked_ops.rs:15:8\n   |\nLL |     if b != 0 {\n   |        ^^^^^^ check performed here\nLL |\nLL |         a /= b;\n   |         ------ division performed here\n   |\n   = help: consider using `checked_div`\n\nerror: manual checked division\n  --> tests/ui/manual_checked_ops.rs:20:8\n   |\nLL |     if b > 0 {\n   |        ^^^^^ check performed here\nLL |\nLL |         let _result = a / b;\n   |                       ----- division performed here\n   |\n   = help: consider using `checked_div`\n\nerror: manual checked division\n  --> tests/ui/manual_checked_ops.rs:25:8\n   |\nLL |     if b == 0 {\n   |        ^^^^^^ check performed here\n...\nLL |         let _result = a / b;\n   |                       ----- division performed here\n   |\n   = help: consider using `checked_div`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_clamp.fixed",
    "content": "#![warn(clippy::manual_clamp)]\n#![allow(\n    unused,\n    dead_code,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::if_same_then_else,\n    clippy::needless_match\n)]\n\nuse std::cmp::{max as cmp_max, min as cmp_min};\n\nconst CONST_MAX: i32 = 10;\nconst CONST_MIN: i32 = 4;\n\nconst CONST_F64_MAX: f64 = 10.0;\nconst CONST_F64_MIN: f64 = 4.0;\n\nfn main() {\n    let (input, min, max) = (0, -2, 3);\n    // Min and max are not const, so this shouldn't trigger the lint.\n    let x0 = if max < input {\n        max\n    } else if min > input {\n        min\n    } else {\n        input\n    };\n\n    let x1 = if input > max {\n        max\n    } else if input < min {\n        min\n    } else {\n        input\n    };\n\n    let x2 = if input < min {\n        min\n    } else if input > max {\n        max\n    } else {\n        input\n    };\n\n    let x3 = if min > input {\n        min\n    } else if max < input {\n        max\n    } else {\n        input\n    };\n\n    let x4 = input.max(min).min(max);\n\n    let x5 = input.min(max).max(min);\n\n    let x6 = match input {\n        x if x > max => max,\n        x if x < min => min,\n        x => x,\n    };\n\n    let x7 = match input {\n        x if x < min => min,\n        x if x > max => max,\n        x => x,\n    };\n\n    let x8 = match input {\n        x if max < x => max,\n        x if min > x => min,\n        x => x,\n    };\n\n    let mut x9 = input;\n    if x9 < min {\n        x9 = min;\n    }\n    if x9 > max {\n        x9 = max;\n    }\n\n    let x10 = match input {\n        x if min > x => min,\n        x if max < x => max,\n        x => x,\n    };\n\n    let mut x11 = input;\n    let _ = 1;\n    if x11 > max {\n        x11 = max;\n    }\n    if x11 < min {\n        x11 = min;\n    }\n\n    let mut x12 = input;\n    if min > x12 {\n        x12 = min;\n    }\n    if max < x12 {\n        x12 = max;\n    }\n\n    let mut x13 = input;\n    if max < x13 {\n        x13 = max;\n    }\n    if min > x13 {\n        x13 = min;\n    }\n\n    {\n        let (input, min, max) = (0.0f64, -2.0, 3.0);\n        let x14 = if input > max {\n            max\n        } else if input < min {\n            min\n        } else {\n            input\n        };\n    }\n    let mut x15 = input;\n    if x15 < min {\n        x15 = min;\n    } else if x15 > max {\n        x15 = max;\n    }\n\n    // It's important this be the last set of statements\n    let mut x16 = input;\n    if max < x16 {\n        x16 = max;\n    }\n    if min > x16 {\n        x16 = min;\n    }\n}\n\nfn const_main() {\n    let input = 0;\n    // Min and max are const, so this should trigger the lint.\n    let x0 = input.clamp(CONST_MIN, CONST_MAX);\n\n    let x1 = input.clamp(CONST_MIN, CONST_MAX);\n\n    let x2 = input.clamp(CONST_MIN, CONST_MAX);\n\n    let x3 = input.clamp(CONST_MIN, CONST_MAX);\n\n    let x4 = input.clamp(CONST_MIN, CONST_MAX);\n    //~^ manual_clamp\n\n    let x5 = input.clamp(CONST_MIN, CONST_MAX);\n    //~^ manual_clamp\n\n    let x6 = input.clamp(CONST_MIN, CONST_MAX);\n\n    let x7 = input.clamp(CONST_MIN, CONST_MAX);\n\n    let x8 = input.clamp(CONST_MIN, CONST_MAX);\n\n    let mut x9 = input;\n    x9 = x9.clamp(CONST_MIN, CONST_MAX);\n\n    let x10 = input.clamp(CONST_MIN, CONST_MAX);\n\n    let mut x11 = input;\n    let _ = 1;\n    x11 = x11.clamp(CONST_MIN, CONST_MAX);\n\n    let mut x12 = input;\n    x12 = x12.clamp(CONST_MIN, CONST_MAX);\n\n    let mut x13 = input;\n    x13 = x13.clamp(CONST_MIN, CONST_MAX);\n\n    let x14 = input.clamp(CONST_MIN, CONST_MAX);\n    {\n        let input = 0.0f64;\n        let x15 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n    }\n    {\n        let input: i32 = cmp_min_max(1);\n        // These can only be detected if exactly one of the arguments to the inner function is const.\n        let x16 = input.clamp(CONST_MIN, CONST_MAX);\n        //~^ manual_clamp\n\n        let x17 = input.clamp(CONST_MIN, CONST_MAX);\n        //~^ manual_clamp\n\n        let x18 = input.clamp(CONST_MIN, CONST_MAX);\n        //~^ manual_clamp\n\n        let x19 = input.clamp(CONST_MIN, CONST_MAX);\n        //~^ manual_clamp\n\n        let x20 = input.clamp(CONST_MIN, CONST_MAX);\n        //~^ manual_clamp\n\n        let x21 = input.clamp(CONST_MIN, CONST_MAX);\n        //~^ manual_clamp\n\n        let x22 = input.clamp(CONST_MIN, CONST_MAX);\n        //~^ manual_clamp\n\n        let x23 = input.clamp(CONST_MIN, CONST_MAX);\n        //~^ manual_clamp\n\n        let input: f64 = cmp_min_max(1) as f64;\n        let x24 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x25 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x26 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x27 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x28 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x29 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x30 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x31 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);\n        //~^ manual_clamp\n    }\n    let mut x32 = input;\n    x32 = x32.clamp(CONST_MIN, CONST_MAX);\n\n    // Flip the script, swap the places of min and max. Make sure this doesn't\n    // trigger when clamp would be guaranteed to panic.\n    let mut x33 = input;\n    if x33 < CONST_MAX {\n        x33 = CONST_MAX;\n    } else if x33 > CONST_MIN {\n        x33 = CONST_MIN;\n    }\n\n    // Do it again for NaN\n    #[allow(invalid_nan_comparisons)]\n    {\n        let mut x34 = input as f64;\n        if x34 < f64::NAN {\n            x34 = f64::NAN;\n        } else if x34 > CONST_F64_MAX {\n            x34 = CONST_F64_MAX;\n        }\n    }\n\n    // It's important this be the last set of statements\n    let mut x35 = input;\n    x35 = x35.clamp(CONST_MIN, CONST_MAX);\n}\n\n// This code intentionally nonsense.\nfn no_lint() {\n    let input = 0;\n    let x0 = if CONST_MAX < input {\n        CONST_MAX\n    } else if CONST_MIN > input {\n        CONST_MAX\n    } else {\n        CONST_MIN\n    };\n\n    let x1 = if input > CONST_MAX {\n        CONST_MAX\n    } else if input > CONST_MIN {\n        CONST_MIN\n    } else {\n        CONST_MAX\n    };\n\n    let x2 = if CONST_MAX < CONST_MIN {\n        CONST_MIN\n    } else if input > CONST_MAX {\n        input\n    } else {\n        input\n    };\n\n    let x3 = if CONST_MIN > input {\n        input\n    } else if CONST_MAX < input {\n        CONST_MAX\n    } else {\n        CONST_MAX\n    };\n\n    let x6 = match input {\n        x if x < CONST_MAX => x,\n        x if x < CONST_MIN => x,\n        x => x,\n    };\n\n    let x7 = match input {\n        x if x < CONST_MIN => CONST_MAX,\n        x if x > CONST_MAX => CONST_MIN,\n        x => x,\n    };\n\n    let x8 = match input {\n        x if CONST_MAX > x => CONST_MAX,\n        x if CONST_MIN > x => CONST_MIN,\n        x => x,\n    };\n\n    let mut x9 = input;\n    if x9 > CONST_MIN {\n        x9 = CONST_MIN;\n    }\n    if x9 > CONST_MAX {\n        x9 = CONST_MAX;\n    }\n\n    let x10 = match input {\n        x if CONST_MIN > x => CONST_MIN,\n        x if CONST_MAX < x => CONST_MAX,\n        x => CONST_MIN,\n    };\n\n    let mut x11 = input;\n    if x11 > CONST_MAX {\n        x11 = CONST_MIN;\n    }\n    if x11 < CONST_MIN {\n        x11 = CONST_MAX;\n    }\n\n    let mut x12 = input;\n    if CONST_MIN > x12 {\n        x12 = CONST_MAX * 3;\n    }\n    if CONST_MAX < x12 {\n        x12 = CONST_MIN;\n    }\n\n    let mut x13 = input;\n    if CONST_MAX < x13 {\n        let x13 = CONST_MAX;\n    }\n    if CONST_MIN > x13 {\n        x13 = CONST_MIN;\n    }\n    let mut x14 = input;\n    if x14 < CONST_MIN {\n        x14 = 3;\n    } else if x14 > CONST_MAX {\n        x14 = CONST_MAX;\n    }\n    {\n        let input: i32 = cmp_min_max(1);\n        // These can only be detected if exactly one of the arguments to the inner function is const.\n        let x16 = cmp_max(cmp_max(input, CONST_MAX), CONST_MIN);\n        let x17 = cmp_min(cmp_min(input, CONST_MIN), CONST_MAX);\n        let x18 = cmp_max(CONST_MIN, cmp_max(input, CONST_MAX));\n        let x19 = cmp_min(CONST_MAX, cmp_min(input, CONST_MIN));\n        let x20 = cmp_max(cmp_max(CONST_MAX, input), CONST_MIN);\n        let x21 = cmp_min(cmp_min(CONST_MIN, input), CONST_MAX);\n        let x22 = cmp_max(CONST_MIN, cmp_max(CONST_MAX, input));\n        let x23 = cmp_min(CONST_MAX, cmp_min(CONST_MIN, input));\n        let input: f64 = cmp_min_max(1) as f64;\n        let x24 = f64::max(f64::max(input, CONST_F64_MAX), CONST_F64_MIN);\n        let x25 = f64::min(f64::min(input, CONST_F64_MIN), CONST_F64_MAX);\n        let x26 = f64::max(CONST_F64_MIN, f64::max(input, CONST_F64_MAX));\n        let x27 = f64::min(CONST_F64_MAX, f64::min(input, CONST_F64_MIN));\n        let x28 = f64::max(f64::max(CONST_F64_MAX, input), CONST_F64_MIN);\n        let x29 = f64::min(f64::min(CONST_F64_MIN, input), CONST_F64_MAX);\n        let x30 = f64::max(CONST_F64_MIN, f64::max(CONST_F64_MAX, input));\n        let x31 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, input));\n        let x32 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, CONST_F64_MAX));\n    }\n}\n\nfn dont_tell_me_what_to_do() {\n    let (input, min, max) = (0, -2, 3);\n    let mut x_never = input;\n    #[allow(clippy::manual_clamp)]\n    if x_never < min {\n        x_never = min;\n    }\n    if x_never > max {\n        x_never = max;\n    }\n}\n\n/// Just to ensure this isn't const evaled\nfn cmp_min_max(input: i32) -> i32 {\n    input * 3\n}\n\n#[clippy::msrv = \"1.49\"]\nfn msrv_1_49() {\n    let (input, min, max) = (0, -1, 2);\n    let _ = if input < min {\n        min\n    } else if input > max {\n        max\n    } else {\n        input\n    };\n}\n\n#[clippy::msrv = \"1.50\"]\nfn msrv_1_50() {\n    let input = 0;\n    let _ = input.clamp(CONST_MIN, CONST_MAX);\n}\n\nconst fn _const() {\n    let (input, min, max) = (0, -1, 2);\n    let _ = if input < min {\n        min\n    } else if input > max {\n        max\n    } else {\n        input\n    };\n\n    let mut x = input;\n    if max < x {\n        let x = max;\n    }\n    if min > x {\n        x = min;\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_clamp.rs",
    "content": "#![warn(clippy::manual_clamp)]\n#![allow(\n    unused,\n    dead_code,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::if_same_then_else,\n    clippy::needless_match\n)]\n\nuse std::cmp::{max as cmp_max, min as cmp_min};\n\nconst CONST_MAX: i32 = 10;\nconst CONST_MIN: i32 = 4;\n\nconst CONST_F64_MAX: f64 = 10.0;\nconst CONST_F64_MIN: f64 = 4.0;\n\nfn main() {\n    let (input, min, max) = (0, -2, 3);\n    // Min and max are not const, so this shouldn't trigger the lint.\n    let x0 = if max < input {\n        max\n    } else if min > input {\n        min\n    } else {\n        input\n    };\n\n    let x1 = if input > max {\n        max\n    } else if input < min {\n        min\n    } else {\n        input\n    };\n\n    let x2 = if input < min {\n        min\n    } else if input > max {\n        max\n    } else {\n        input\n    };\n\n    let x3 = if min > input {\n        min\n    } else if max < input {\n        max\n    } else {\n        input\n    };\n\n    let x4 = input.max(min).min(max);\n\n    let x5 = input.min(max).max(min);\n\n    let x6 = match input {\n        x if x > max => max,\n        x if x < min => min,\n        x => x,\n    };\n\n    let x7 = match input {\n        x if x < min => min,\n        x if x > max => max,\n        x => x,\n    };\n\n    let x8 = match input {\n        x if max < x => max,\n        x if min > x => min,\n        x => x,\n    };\n\n    let mut x9 = input;\n    if x9 < min {\n        x9 = min;\n    }\n    if x9 > max {\n        x9 = max;\n    }\n\n    let x10 = match input {\n        x if min > x => min,\n        x if max < x => max,\n        x => x,\n    };\n\n    let mut x11 = input;\n    let _ = 1;\n    if x11 > max {\n        x11 = max;\n    }\n    if x11 < min {\n        x11 = min;\n    }\n\n    let mut x12 = input;\n    if min > x12 {\n        x12 = min;\n    }\n    if max < x12 {\n        x12 = max;\n    }\n\n    let mut x13 = input;\n    if max < x13 {\n        x13 = max;\n    }\n    if min > x13 {\n        x13 = min;\n    }\n\n    {\n        let (input, min, max) = (0.0f64, -2.0, 3.0);\n        let x14 = if input > max {\n            max\n        } else if input < min {\n            min\n        } else {\n            input\n        };\n    }\n    let mut x15 = input;\n    if x15 < min {\n        x15 = min;\n    } else if x15 > max {\n        x15 = max;\n    }\n\n    // It's important this be the last set of statements\n    let mut x16 = input;\n    if max < x16 {\n        x16 = max;\n    }\n    if min > x16 {\n        x16 = min;\n    }\n}\n\nfn const_main() {\n    let input = 0;\n    // Min and max are const, so this should trigger the lint.\n    let x0 = if CONST_MAX < input {\n        //~^ manual_clamp\n\n        CONST_MAX\n    } else if CONST_MIN > input {\n        CONST_MIN\n    } else {\n        input\n    };\n\n    let x1 = if input > CONST_MAX {\n        //~^ manual_clamp\n\n        CONST_MAX\n    } else if input < CONST_MIN {\n        CONST_MIN\n    } else {\n        input\n    };\n\n    let x2 = if input < CONST_MIN {\n        //~^ manual_clamp\n\n        CONST_MIN\n    } else if input > CONST_MAX {\n        CONST_MAX\n    } else {\n        input\n    };\n\n    let x3 = if CONST_MIN > input {\n        //~^ manual_clamp\n\n        CONST_MIN\n    } else if CONST_MAX < input {\n        CONST_MAX\n    } else {\n        input\n    };\n\n    let x4 = input.max(CONST_MIN).min(CONST_MAX);\n    //~^ manual_clamp\n\n    let x5 = input.min(CONST_MAX).max(CONST_MIN);\n    //~^ manual_clamp\n\n    let x6 = match input {\n        //~^ manual_clamp\n        x if x > CONST_MAX => CONST_MAX,\n        x if x < CONST_MIN => CONST_MIN,\n        x => x,\n    };\n\n    let x7 = match input {\n        //~^ manual_clamp\n        x if x < CONST_MIN => CONST_MIN,\n        x if x > CONST_MAX => CONST_MAX,\n        x => x,\n    };\n\n    let x8 = match input {\n        //~^ manual_clamp\n        x if CONST_MAX < x => CONST_MAX,\n        x if CONST_MIN > x => CONST_MIN,\n        x => x,\n    };\n\n    let mut x9 = input;\n    if x9 < CONST_MIN {\n        //~^ manual_clamp\n\n        x9 = CONST_MIN;\n    }\n    if x9 > CONST_MAX {\n        x9 = CONST_MAX;\n    }\n\n    let x10 = match input {\n        //~^ manual_clamp\n        x if CONST_MIN > x => CONST_MIN,\n        x if CONST_MAX < x => CONST_MAX,\n        x => x,\n    };\n\n    let mut x11 = input;\n    let _ = 1;\n    if x11 > CONST_MAX {\n        //~^ manual_clamp\n\n        x11 = CONST_MAX;\n    }\n    if x11 < CONST_MIN {\n        x11 = CONST_MIN;\n    }\n\n    let mut x12 = input;\n    if CONST_MIN > x12 {\n        //~^ manual_clamp\n\n        x12 = CONST_MIN;\n    }\n    if CONST_MAX < x12 {\n        x12 = CONST_MAX;\n    }\n\n    let mut x13 = input;\n    if CONST_MAX < x13 {\n        //~^ manual_clamp\n\n        x13 = CONST_MAX;\n    }\n    if CONST_MIN > x13 {\n        x13 = CONST_MIN;\n    }\n\n    let x14 = if input > CONST_MAX {\n        //~^ manual_clamp\n\n        CONST_MAX\n    } else if input < CONST_MIN {\n        CONST_MIN\n    } else {\n        input\n    };\n    {\n        let input = 0.0f64;\n        let x15 = if input > CONST_F64_MAX {\n            //~^ manual_clamp\n\n            CONST_F64_MAX\n        } else if input < CONST_F64_MIN {\n            CONST_F64_MIN\n        } else {\n            input\n        };\n    }\n    {\n        let input: i32 = cmp_min_max(1);\n        // These can only be detected if exactly one of the arguments to the inner function is const.\n        let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);\n        //~^ manual_clamp\n\n        let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);\n        //~^ manual_clamp\n\n        let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));\n        //~^ manual_clamp\n\n        let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));\n        //~^ manual_clamp\n\n        let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);\n        //~^ manual_clamp\n\n        let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);\n        //~^ manual_clamp\n\n        let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));\n        //~^ manual_clamp\n\n        let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));\n        //~^ manual_clamp\n\n        let input: f64 = cmp_min_max(1) as f64;\n        let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);\n        //~^ manual_clamp\n\n        let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));\n        //~^ manual_clamp\n\n        let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));\n        //~^ manual_clamp\n\n        let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);\n        //~^ manual_clamp\n\n        let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);\n        //~^ manual_clamp\n\n        let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));\n        //~^ manual_clamp\n\n        let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));\n        //~^ manual_clamp\n    }\n    let mut x32 = input;\n    if x32 < CONST_MIN {\n        //~^ manual_clamp\n\n        x32 = CONST_MIN;\n    } else if x32 > CONST_MAX {\n        x32 = CONST_MAX;\n    }\n\n    // Flip the script, swap the places of min and max. Make sure this doesn't\n    // trigger when clamp would be guaranteed to panic.\n    let mut x33 = input;\n    if x33 < CONST_MAX {\n        x33 = CONST_MAX;\n    } else if x33 > CONST_MIN {\n        x33 = CONST_MIN;\n    }\n\n    // Do it again for NaN\n    #[allow(invalid_nan_comparisons)]\n    {\n        let mut x34 = input as f64;\n        if x34 < f64::NAN {\n            x34 = f64::NAN;\n        } else if x34 > CONST_F64_MAX {\n            x34 = CONST_F64_MAX;\n        }\n    }\n\n    // It's important this be the last set of statements\n    let mut x35 = input;\n    if CONST_MAX < x35 {\n        //~^ manual_clamp\n\n        x35 = CONST_MAX;\n    }\n    if CONST_MIN > x35 {\n        x35 = CONST_MIN;\n    }\n}\n\n// This code intentionally nonsense.\nfn no_lint() {\n    let input = 0;\n    let x0 = if CONST_MAX < input {\n        CONST_MAX\n    } else if CONST_MIN > input {\n        CONST_MAX\n    } else {\n        CONST_MIN\n    };\n\n    let x1 = if input > CONST_MAX {\n        CONST_MAX\n    } else if input > CONST_MIN {\n        CONST_MIN\n    } else {\n        CONST_MAX\n    };\n\n    let x2 = if CONST_MAX < CONST_MIN {\n        CONST_MIN\n    } else if input > CONST_MAX {\n        input\n    } else {\n        input\n    };\n\n    let x3 = if CONST_MIN > input {\n        input\n    } else if CONST_MAX < input {\n        CONST_MAX\n    } else {\n        CONST_MAX\n    };\n\n    let x6 = match input {\n        x if x < CONST_MAX => x,\n        x if x < CONST_MIN => x,\n        x => x,\n    };\n\n    let x7 = match input {\n        x if x < CONST_MIN => CONST_MAX,\n        x if x > CONST_MAX => CONST_MIN,\n        x => x,\n    };\n\n    let x8 = match input {\n        x if CONST_MAX > x => CONST_MAX,\n        x if CONST_MIN > x => CONST_MIN,\n        x => x,\n    };\n\n    let mut x9 = input;\n    if x9 > CONST_MIN {\n        x9 = CONST_MIN;\n    }\n    if x9 > CONST_MAX {\n        x9 = CONST_MAX;\n    }\n\n    let x10 = match input {\n        x if CONST_MIN > x => CONST_MIN,\n        x if CONST_MAX < x => CONST_MAX,\n        x => CONST_MIN,\n    };\n\n    let mut x11 = input;\n    if x11 > CONST_MAX {\n        x11 = CONST_MIN;\n    }\n    if x11 < CONST_MIN {\n        x11 = CONST_MAX;\n    }\n\n    let mut x12 = input;\n    if CONST_MIN > x12 {\n        x12 = CONST_MAX * 3;\n    }\n    if CONST_MAX < x12 {\n        x12 = CONST_MIN;\n    }\n\n    let mut x13 = input;\n    if CONST_MAX < x13 {\n        let x13 = CONST_MAX;\n    }\n    if CONST_MIN > x13 {\n        x13 = CONST_MIN;\n    }\n    let mut x14 = input;\n    if x14 < CONST_MIN {\n        x14 = 3;\n    } else if x14 > CONST_MAX {\n        x14 = CONST_MAX;\n    }\n    {\n        let input: i32 = cmp_min_max(1);\n        // These can only be detected if exactly one of the arguments to the inner function is const.\n        let x16 = cmp_max(cmp_max(input, CONST_MAX), CONST_MIN);\n        let x17 = cmp_min(cmp_min(input, CONST_MIN), CONST_MAX);\n        let x18 = cmp_max(CONST_MIN, cmp_max(input, CONST_MAX));\n        let x19 = cmp_min(CONST_MAX, cmp_min(input, CONST_MIN));\n        let x20 = cmp_max(cmp_max(CONST_MAX, input), CONST_MIN);\n        let x21 = cmp_min(cmp_min(CONST_MIN, input), CONST_MAX);\n        let x22 = cmp_max(CONST_MIN, cmp_max(CONST_MAX, input));\n        let x23 = cmp_min(CONST_MAX, cmp_min(CONST_MIN, input));\n        let input: f64 = cmp_min_max(1) as f64;\n        let x24 = f64::max(f64::max(input, CONST_F64_MAX), CONST_F64_MIN);\n        let x25 = f64::min(f64::min(input, CONST_F64_MIN), CONST_F64_MAX);\n        let x26 = f64::max(CONST_F64_MIN, f64::max(input, CONST_F64_MAX));\n        let x27 = f64::min(CONST_F64_MAX, f64::min(input, CONST_F64_MIN));\n        let x28 = f64::max(f64::max(CONST_F64_MAX, input), CONST_F64_MIN);\n        let x29 = f64::min(f64::min(CONST_F64_MIN, input), CONST_F64_MAX);\n        let x30 = f64::max(CONST_F64_MIN, f64::max(CONST_F64_MAX, input));\n        let x31 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, input));\n        let x32 = f64::min(CONST_F64_MAX, f64::min(CONST_F64_MIN, CONST_F64_MAX));\n    }\n}\n\nfn dont_tell_me_what_to_do() {\n    let (input, min, max) = (0, -2, 3);\n    let mut x_never = input;\n    #[allow(clippy::manual_clamp)]\n    if x_never < min {\n        x_never = min;\n    }\n    if x_never > max {\n        x_never = max;\n    }\n}\n\n/// Just to ensure this isn't const evaled\nfn cmp_min_max(input: i32) -> i32 {\n    input * 3\n}\n\n#[clippy::msrv = \"1.49\"]\nfn msrv_1_49() {\n    let (input, min, max) = (0, -1, 2);\n    let _ = if input < min {\n        min\n    } else if input > max {\n        max\n    } else {\n        input\n    };\n}\n\n#[clippy::msrv = \"1.50\"]\nfn msrv_1_50() {\n    let input = 0;\n    let _ = if input > CONST_MAX {\n        //~^ manual_clamp\n\n        CONST_MAX\n    } else if input < CONST_MIN {\n        CONST_MIN\n    } else {\n        input\n    };\n}\n\nconst fn _const() {\n    let (input, min, max) = (0, -1, 2);\n    let _ = if input < min {\n        min\n    } else if input > max {\n        max\n    } else {\n        input\n    };\n\n    let mut x = input;\n    if max < x {\n        let x = max;\n    }\n    if min > x {\n        x = min;\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_clamp.stderr",
    "content": "error: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:213:5\n   |\nLL | /     if x9 < CONST_MIN {\nLL | |\nLL | |\nLL | |         x9 = CONST_MIN;\n...  |\nLL | |         x9 = CONST_MAX;\nLL | |     }\n   | |_____^ help: replace with clamp: `x9 = x9.clamp(CONST_MIN, CONST_MAX);`\n   |\n   = note: clamp will panic if max < min\n   = note: `-D clippy::manual-clamp` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_clamp)]`\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:231:5\n   |\nLL | /     if x11 > CONST_MAX {\nLL | |\nLL | |\nLL | |         x11 = CONST_MAX;\n...  |\nLL | |         x11 = CONST_MIN;\nLL | |     }\n   | |_____^ help: replace with clamp: `x11 = x11.clamp(CONST_MIN, CONST_MAX);`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:241:5\n   |\nLL | /     if CONST_MIN > x12 {\nLL | |\nLL | |\nLL | |         x12 = CONST_MIN;\n...  |\nLL | |         x12 = CONST_MAX;\nLL | |     }\n   | |_____^ help: replace with clamp: `x12 = x12.clamp(CONST_MIN, CONST_MAX);`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:251:5\n   |\nLL | /     if CONST_MAX < x13 {\nLL | |\nLL | |\nLL | |         x13 = CONST_MAX;\n...  |\nLL | |         x13 = CONST_MIN;\nLL | |     }\n   | |_____^ help: replace with clamp: `x13 = x13.clamp(CONST_MIN, CONST_MAX);`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:364:5\n   |\nLL | /     if CONST_MAX < x35 {\nLL | |\nLL | |\nLL | |         x35 = CONST_MAX;\n...  |\nLL | |         x35 = CONST_MIN;\nLL | |     }\n   | |_____^ help: replace with clamp: `x35 = x35.clamp(CONST_MIN, CONST_MAX);`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:145:14\n   |\nLL |       let x0 = if CONST_MAX < input {\n   |  ______________^\nLL | |\nLL | |\nLL | |         CONST_MAX\n...  |\nLL | |         input\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:155:14\n   |\nLL |       let x1 = if input > CONST_MAX {\n   |  ______________^\nLL | |\nLL | |\nLL | |         CONST_MAX\n...  |\nLL | |         input\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:165:14\n   |\nLL |       let x2 = if input < CONST_MIN {\n   |  ______________^\nLL | |\nLL | |\nLL | |         CONST_MIN\n...  |\nLL | |         input\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:175:14\n   |\nLL |       let x3 = if CONST_MIN > input {\n   |  ______________^\nLL | |\nLL | |\nLL | |         CONST_MIN\n...  |\nLL | |         input\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:185:14\n   |\nLL |     let x4 = input.max(CONST_MIN).min(CONST_MAX);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:188:14\n   |\nLL |     let x5 = input.min(CONST_MAX).max(CONST_MIN);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:191:14\n   |\nLL |       let x6 = match input {\n   |  ______________^\nLL | |\nLL | |         x if x > CONST_MAX => CONST_MAX,\nLL | |         x if x < CONST_MIN => CONST_MIN,\nLL | |         x => x,\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:198:14\n   |\nLL |       let x7 = match input {\n   |  ______________^\nLL | |\nLL | |         x if x < CONST_MIN => CONST_MIN,\nLL | |         x if x > CONST_MAX => CONST_MAX,\nLL | |         x => x,\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:205:14\n   |\nLL |       let x8 = match input {\n   |  ______________^\nLL | |\nLL | |         x if CONST_MAX < x => CONST_MAX,\nLL | |         x if CONST_MIN > x => CONST_MIN,\nLL | |         x => x,\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:222:15\n   |\nLL |       let x10 = match input {\n   |  _______________^\nLL | |\nLL | |         x if CONST_MIN > x => CONST_MIN,\nLL | |         x if CONST_MAX < x => CONST_MAX,\nLL | |         x => x,\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:260:15\n   |\nLL |       let x14 = if input > CONST_MAX {\n   |  _______________^\nLL | |\nLL | |\nLL | |         CONST_MAX\n...  |\nLL | |         input\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:271:19\n   |\nLL |           let x15 = if input > CONST_F64_MAX {\n   |  ___________________^\nLL | |\nLL | |\nLL | |             CONST_F64_MAX\n...  |\nLL | |             input\nLL | |         };\n   | |_________^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:284:19\n   |\nLL |         let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:287:19\n   |\nLL |         let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:290:19\n   |\nLL |         let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:293:19\n   |\nLL |         let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:296:19\n   |\nLL |         let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:299:19\n   |\nLL |         let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:302:19\n   |\nLL |         let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:305:19\n   |\nLL |         let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:309:19\n   |\nLL |         let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:312:19\n   |\nLL |         let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:315:19\n   |\nLL |         let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:318:19\n   |\nLL |         let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:321:19\n   |\nLL |         let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:324:19\n   |\nLL |         let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:327:19\n   |\nLL |         let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:330:19\n   |\nLL |         let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`\n   |\n   = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()\n   = note: clamp returns NaN if the input is NaN\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:334:5\n   |\nLL | /     if x32 < CONST_MIN {\nLL | |\nLL | |\nLL | |         x32 = CONST_MIN;\nLL | |     } else if x32 > CONST_MAX {\nLL | |         x32 = CONST_MAX;\nLL | |     }\n   | |_____^ help: replace with clamp: `x32 = x32.clamp(CONST_MIN, CONST_MAX);`\n   |\n   = note: clamp will panic if max < min\n\nerror: clamp-like pattern without using clamp function\n  --> tests/ui/manual_clamp.rs:526:13\n   |\nLL |       let _ = if input > CONST_MAX {\n   |  _____________^\nLL | |\nLL | |\nLL | |         CONST_MAX\n...  |\nLL | |         input\nLL | |     };\n   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`\n   |\n   = note: clamp will panic if max < min\n\nerror: aborting due to 35 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_contains.fixed",
    "content": "#![warn(clippy::manual_contains)]\n#![allow(clippy::eq_op, clippy::useless_vec)]\n\nfn should_lint() {\n    let vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.contains(&4);\n    //~^ manual_contains\n\n    let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.contains(&4);\n    //~^ manual_contains\n\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.contains(&10);\n    //~^ manual_contains\n\n    let num = 14;\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.contains(&num);\n    //~^ manual_contains\n\n    let num = 14;\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.contains(&num);\n    //~^ manual_contains\n\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.contains(&4);\n    //~^ manual_contains\n\n    let vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.contains(&4);\n    //~^ manual_contains\n\n    let vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let a = &4;\n    let _ = values.contains(a);\n    //~^ manual_contains\n\n    let vec = vec![\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"];\n    let values = &vec[..];\n    let _ = values.contains(&\"4\");\n    //~^ manual_contains\n\n    let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.contains(&(4 + 1));\n    //~^ manual_contains\n}\n\nfn should_not_lint() {\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.iter().any(|&v| v > 10);\n\n    let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.iter().any(|&v| v.is_multiple_of(2));\n    let _ = values.iter().any(|&v| v * 2 == 6);\n    let _ = values.iter().any(|&v| v == v);\n    let _ = values.iter().any(|&v| 4 == 4);\n    let _ = values.contains(&4);\n\n    let a = 1;\n    let b = 2;\n    let _ = values.iter().any(|&v| a == b);\n    let _ = values.iter().any(|&v| a == 4);\n\n    let vec: Vec<String> = vec![\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]\n        .iter()\n        .map(|&x| x.to_string())\n        .collect();\n    let values = &vec[..];\n    let _ = values.iter().any(|v| v == \"4\");\n\n    let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let mut counter = 0;\n    let mut count = || {\n        counter += 1;\n        counter\n    };\n    let _ = values.iter().any(|&v| v == count());\n    let _ = values.iter().any(|&v| v == v * 2);\n}\n\nfn foo(values: &[u8]) -> bool {\n    values.contains(&10)\n    //~^ manual_contains\n}\n\nfn bar(values: [u8; 3]) -> bool {\n    values.contains(&10)\n    //~^ manual_contains\n}\n"
  },
  {
    "path": "tests/ui/manual_contains.rs",
    "content": "#![warn(clippy::manual_contains)]\n#![allow(clippy::eq_op, clippy::useless_vec)]\n\nfn should_lint() {\n    let vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.iter().any(|&v| v == 4);\n    //~^ manual_contains\n\n    let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.iter().any(|&v| v == 4);\n    //~^ manual_contains\n\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.iter().any(|&v| v == 10);\n    //~^ manual_contains\n\n    let num = 14;\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.iter().any(|&v| v == num);\n    //~^ manual_contains\n\n    let num = 14;\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.iter().any(|&v| num == v);\n    //~^ manual_contains\n\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.iter().any(|v| *v == 4);\n    //~^ manual_contains\n\n    let vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.iter().any(|&v| 4 == v);\n    //~^ manual_contains\n\n    let vec: Vec<u8> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let a = &4;\n    let _ = values.iter().any(|v| *v == *a);\n    //~^ manual_contains\n\n    let vec = vec![\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"];\n    let values = &vec[..];\n    let _ = values.iter().any(|&v| v == \"4\");\n    //~^ manual_contains\n\n    let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.iter().any(|&v| v == 4 + 1);\n    //~^ manual_contains\n}\n\nfn should_not_lint() {\n    let values: [u8; 6] = [3, 14, 15, 92, 6, 5];\n    let _ = values.iter().any(|&v| v > 10);\n\n    let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let _ = values.iter().any(|&v| v.is_multiple_of(2));\n    let _ = values.iter().any(|&v| v * 2 == 6);\n    let _ = values.iter().any(|&v| v == v);\n    let _ = values.iter().any(|&v| 4 == 4);\n    let _ = values.contains(&4);\n\n    let a = 1;\n    let b = 2;\n    let _ = values.iter().any(|&v| a == b);\n    let _ = values.iter().any(|&v| a == 4);\n\n    let vec: Vec<String> = vec![\"1\", \"2\", \"3\", \"4\", \"5\", \"6\"]\n        .iter()\n        .map(|&x| x.to_string())\n        .collect();\n    let values = &vec[..];\n    let _ = values.iter().any(|v| v == \"4\");\n\n    let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];\n    let values = &vec[..];\n    let mut counter = 0;\n    let mut count = || {\n        counter += 1;\n        counter\n    };\n    let _ = values.iter().any(|&v| v == count());\n    let _ = values.iter().any(|&v| v == v * 2);\n}\n\nfn foo(values: &[u8]) -> bool {\n    values.iter().any(|&v| v == 10)\n    //~^ manual_contains\n}\n\nfn bar(values: [u8; 3]) -> bool {\n    values.iter().any(|&v| v == 10)\n    //~^ manual_contains\n}\n"
  },
  {
    "path": "tests/ui/manual_contains.stderr",
    "content": "error: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:7:13\n   |\nLL |     let _ = values.iter().any(|&v| v == 4);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&4)`\n   |\n   = note: `-D clippy::manual-contains` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_contains)]`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:12:13\n   |\nLL |     let _ = values.iter().any(|&v| v == 4);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&4)`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:16:13\n   |\nLL |     let _ = values.iter().any(|&v| v == 10);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&10)`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:21:13\n   |\nLL |     let _ = values.iter().any(|&v| v == num);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&num)`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:26:13\n   |\nLL |     let _ = values.iter().any(|&v| num == v);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&num)`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:30:13\n   |\nLL |     let _ = values.iter().any(|v| *v == 4);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&4)`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:35:13\n   |\nLL |     let _ = values.iter().any(|&v| 4 == v);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&4)`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:41:13\n   |\nLL |     let _ = values.iter().any(|v| *v == *a);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(a)`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:46:13\n   |\nLL |     let _ = values.iter().any(|&v| v == \"4\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&\"4\")`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:51:13\n   |\nLL |     let _ = values.iter().any(|&v| v == 4 + 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&(4 + 1))`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:91:5\n   |\nLL |     values.iter().any(|&v| v == 10)\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&10)`\n\nerror: using `contains()` instead of `iter().any()` is more efficient\n  --> tests/ui/manual_contains.rs:96:5\n   |\nLL |     values.iter().any(|&v| v == 10)\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `values.contains(&10)`\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_dangling_ptr.fixed",
    "content": "#![feature(extern_types)]\n#![warn(clippy::manual_dangling_ptr)]\nuse std::mem;\n\npub fn foo(_const: *const f32, _mut: *mut i32) {}\n\nfn main() {\n    let _: *const u8 = std::ptr::dangling();\n    //~^ manual_dangling_ptr\n    let _ = std::ptr::dangling::<u32>();\n    //~^ manual_dangling_ptr\n    let _ = std::ptr::dangling_mut::<f32>();\n    //~^ manual_dangling_ptr\n\n    let _ = std::ptr::dangling::<u8>();\n    //~^ manual_dangling_ptr\n    let _ = std::ptr::dangling::<u32>();\n    //~^ manual_dangling_ptr\n    let _ = std::ptr::dangling::<usize>();\n    //~^ manual_dangling_ptr\n\n    foo(std::ptr::dangling(), std::ptr::dangling_mut());\n    //~^ manual_dangling_ptr\n    //~| manual_dangling_ptr\n}\n\nfn should_not_lint() {\n    let _ = 0x10 as *mut i32;\n    let _ = mem::align_of::<u32>() as *const u8;\n\n    foo(0 as _, 0 as _);\n}\n\n#[clippy::msrv = \"1.83\"]\nfn _msrv_1_83() {\n    // `{core, std}::ptr::dangling` was stabilized in 1.84. Do not lint this\n    foo(4 as *const _, 4 as *mut _);\n}\n\n#[clippy::msrv = \"1.84\"]\nfn _msrv_1_84() {\n    foo(std::ptr::dangling(), std::ptr::dangling_mut());\n    //~^ manual_dangling_ptr\n    //~| manual_dangling_ptr\n}\n\nfn issue16459() {\n    unsafe extern \"C\" {\n        type Extern;\n    }\n    let _ = unsafe { &mut *(1 as *mut Extern) };\n\n    struct Empty;\n    let _ = unsafe { &mut *std::ptr::dangling_mut::<Empty>() };\n    //~^ manual_dangling_ptr\n}\n"
  },
  {
    "path": "tests/ui/manual_dangling_ptr.rs",
    "content": "#![feature(extern_types)]\n#![warn(clippy::manual_dangling_ptr)]\nuse std::mem;\n\npub fn foo(_const: *const f32, _mut: *mut i32) {}\n\nfn main() {\n    let _: *const u8 = 1 as *const _;\n    //~^ manual_dangling_ptr\n    let _ = 2 as *const u32;\n    //~^ manual_dangling_ptr\n    let _ = 4 as *mut f32;\n    //~^ manual_dangling_ptr\n\n    let _ = mem::align_of::<u8>() as *const u8;\n    //~^ manual_dangling_ptr\n    let _ = mem::align_of::<u32>() as *const u32;\n    //~^ manual_dangling_ptr\n    let _ = mem::align_of::<usize>() as *const usize;\n    //~^ manual_dangling_ptr\n\n    foo(4 as *const _, 4 as *mut _);\n    //~^ manual_dangling_ptr\n    //~| manual_dangling_ptr\n}\n\nfn should_not_lint() {\n    let _ = 0x10 as *mut i32;\n    let _ = mem::align_of::<u32>() as *const u8;\n\n    foo(0 as _, 0 as _);\n}\n\n#[clippy::msrv = \"1.83\"]\nfn _msrv_1_83() {\n    // `{core, std}::ptr::dangling` was stabilized in 1.84. Do not lint this\n    foo(4 as *const _, 4 as *mut _);\n}\n\n#[clippy::msrv = \"1.84\"]\nfn _msrv_1_84() {\n    foo(4 as *const _, 4 as *mut _);\n    //~^ manual_dangling_ptr\n    //~| manual_dangling_ptr\n}\n\nfn issue16459() {\n    unsafe extern \"C\" {\n        type Extern;\n    }\n    let _ = unsafe { &mut *(1 as *mut Extern) };\n\n    struct Empty;\n    let _ = unsafe { &mut *(1 as *mut Empty) };\n    //~^ manual_dangling_ptr\n}\n"
  },
  {
    "path": "tests/ui/manual_dangling_ptr.stderr",
    "content": "error: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:8:24\n   |\nLL |     let _: *const u8 = 1 as *const _;\n   |                        ^^^^^^^^^^^^^ help: use: `std::ptr::dangling()`\n   |\n   = note: `-D clippy::manual-dangling-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_dangling_ptr)]`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:10:13\n   |\nLL |     let _ = 2 as *const u32;\n   |             ^^^^^^^^^^^^^^^ help: use: `std::ptr::dangling::<u32>()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:12:13\n   |\nLL |     let _ = 4 as *mut f32;\n   |             ^^^^^^^^^^^^^ help: use: `std::ptr::dangling_mut::<f32>()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:15:13\n   |\nLL |     let _ = mem::align_of::<u8>() as *const u8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `std::ptr::dangling::<u8>()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:17:13\n   |\nLL |     let _ = mem::align_of::<u32>() as *const u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `std::ptr::dangling::<u32>()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:19:13\n   |\nLL |     let _ = mem::align_of::<usize>() as *const usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `std::ptr::dangling::<usize>()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:22:9\n   |\nLL |     foo(4 as *const _, 4 as *mut _);\n   |         ^^^^^^^^^^^^^ help: use: `std::ptr::dangling()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:22:24\n   |\nLL |     foo(4 as *const _, 4 as *mut _);\n   |                        ^^^^^^^^^^^ help: use: `std::ptr::dangling_mut()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:42:9\n   |\nLL |     foo(4 as *const _, 4 as *mut _);\n   |         ^^^^^^^^^^^^^ help: use: `std::ptr::dangling()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:42:24\n   |\nLL |     foo(4 as *const _, 4 as *mut _);\n   |                        ^^^^^^^^^^^ help: use: `std::ptr::dangling_mut()`\n\nerror: manual creation of a dangling pointer\n  --> tests/ui/manual_dangling_ptr.rs:54:28\n   |\nLL |     let _ = unsafe { &mut *(1 as *mut Empty) };\n   |                            ^^^^^^^^^^^^^^^^^ help: use: `std::ptr::dangling_mut::<Empty>()`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_div_ceil.fixed",
    "content": "#![warn(clippy::manual_div_ceil)]\n\nmacro_rules! y {\n    () => {\n        let x = 33u32;\n        let _ = x.div_ceil(8);\n        //~^ manual_div_ceil\n        let _ = x.div_ceil(8);\n        //~^ manual_div_ceil\n    };\n}\n\nmacro_rules! eight {\n    () => {\n        8\n    };\n}\n\nfn main() {\n    let x = 7_u32;\n    let y = 4_u32;\n    let z = 11_u32;\n\n    // Lint\n    let _ = x.div_ceil(y);\n    //~^ manual_div_ceil\n    let _ = x.div_ceil(y);\n    //~^ manual_div_ceil\n    let _ = x.div_ceil(y);\n    //~^ manual_div_ceil\n\n    let _ = 7_u32.div_ceil(4);\n    //~^ manual_div_ceil\n    let _ = (7_i32 as u32).div_ceil(4);\n    //~^ manual_div_ceil\n\n    // No lint\n    let _ = (x + (y - 2)) / y;\n    let _ = (x + (y + 1)) / y;\n\n    let _ = (x + (y - 1)) / z;\n\n    let x_i = 7_i32;\n    let y_i = 4_i32;\n    let z_i = 11_i32;\n\n    // No lint because `int_roundings` feature is not enabled.\n    let _ = (z as i32 + (y_i - 1)) / y_i;\n    let _ = (7_u32 as i32 + (y_i - 1)) / y_i;\n    let _ = (7_u32 as i32 + (4 - 1)) / 4;\n\n    // Test lint with macro\n    y!();\n\n    // Also test if RHS should be result of macro expansion\n    let _ = 33u32.div_ceil(eight!());\n    //~^ manual_div_ceil\n}\n\nfn issue_13843() {\n    let x = 3usize;\n    let _ = 2048_usize.div_ceil(x);\n    //~^ manual_div_ceil\n\n    let x = 5usize;\n    let _ = 2048usize.div_ceil(x);\n    //~^ manual_div_ceil\n\n    let x = 5usize;\n    let _ = 2048_usize.div_ceil(x);\n    //~^ manual_div_ceil\n\n    let x = 2048usize;\n    let _ = x.div_ceil(4);\n    //~^ manual_div_ceil\n\n    let _: u32 = 2048_u32.div_ceil(6);\n    //~^ manual_div_ceil\n    let _: usize = 2048_usize.div_ceil(6);\n    //~^ manual_div_ceil\n    let _: u32 = 0x2048_u32.div_ceil(0x6);\n    //~^ manual_div_ceil\n\n    let _ = 2048_u32.div_ceil(6u32);\n    //~^ manual_div_ceil\n\n    let _ = 1_000_000_u32.div_ceil(6u32);\n    //~^ manual_div_ceil\n}\n\nfn issue_13950() {\n    let x = 33u32;\n    let _ = x.div_ceil(8);\n    //~^ manual_div_ceil\n    let _ = x.div_ceil(8);\n    //~^ manual_div_ceil\n\n    let y = -33i32;\n    let _ = (y + -8) / -7;\n    let _ = (-8 + y) / -7;\n    let _ = (y - 8) / -7;\n}\n\nfn issue_15705(size: u64, c: &u64) {\n    let _ = size.div_ceil(*c);\n    //~^ manual_div_ceil\n}\n\nstruct MyStruct(u32);\nimpl MyStruct {\n    // Method matching name on different type should not trigger lint\n    fn next_multiple_of(self, y: u32) -> u32 {\n        self.0.next_multiple_of(y)\n    }\n}\n\nfn issue_16219() {\n    let x = 33u32;\n\n    // Lint.\n    let _ = x.div_ceil(8);\n    //~^ manual_div_ceil\n    let _ = x.div_ceil(8);\n    //~^ manual_div_ceil\n\n    let y = &x;\n    let _ = y.div_ceil(8);\n    //~^ manual_div_ceil\n\n    // No lint.\n    let _ = x.next_multiple_of(8) / 7;\n    let _ = x.next_multiple_of(7) / 8;\n\n    let z = MyStruct(x);\n    let _ = z.next_multiple_of(8) / 8;\n}\n"
  },
  {
    "path": "tests/ui/manual_div_ceil.rs",
    "content": "#![warn(clippy::manual_div_ceil)]\n\nmacro_rules! y {\n    () => {\n        let x = 33u32;\n        let _ = (x + 7) / 8;\n        //~^ manual_div_ceil\n        let _ = (7 + x) / 8;\n        //~^ manual_div_ceil\n    };\n}\n\nmacro_rules! eight {\n    () => {\n        8\n    };\n}\n\nfn main() {\n    let x = 7_u32;\n    let y = 4_u32;\n    let z = 11_u32;\n\n    // Lint\n    let _ = (x + (y - 1)) / y;\n    //~^ manual_div_ceil\n    let _ = ((y - 1) + x) / y;\n    //~^ manual_div_ceil\n    let _ = (x + y - 1) / y;\n    //~^ manual_div_ceil\n\n    let _ = (7_u32 + (4 - 1)) / 4;\n    //~^ manual_div_ceil\n    let _ = (7_i32 as u32 + (4 - 1)) / 4;\n    //~^ manual_div_ceil\n\n    // No lint\n    let _ = (x + (y - 2)) / y;\n    let _ = (x + (y + 1)) / y;\n\n    let _ = (x + (y - 1)) / z;\n\n    let x_i = 7_i32;\n    let y_i = 4_i32;\n    let z_i = 11_i32;\n\n    // No lint because `int_roundings` feature is not enabled.\n    let _ = (z as i32 + (y_i - 1)) / y_i;\n    let _ = (7_u32 as i32 + (y_i - 1)) / y_i;\n    let _ = (7_u32 as i32 + (4 - 1)) / 4;\n\n    // Test lint with macro\n    y!();\n\n    // Also test if RHS should be result of macro expansion\n    let _ = (33u32 + 7) / eight!();\n    //~^ manual_div_ceil\n}\n\nfn issue_13843() {\n    let x = 3usize;\n    let _ = (2048 + x - 1) / x;\n    //~^ manual_div_ceil\n\n    let x = 5usize;\n    let _ = (2048usize + x - 1) / x;\n    //~^ manual_div_ceil\n\n    let x = 5usize;\n    let _ = (2048_usize + x - 1) / x;\n    //~^ manual_div_ceil\n\n    let x = 2048usize;\n    let _ = (x + 4 - 1) / 4;\n    //~^ manual_div_ceil\n\n    let _: u32 = (2048 + 6 - 1) / 6;\n    //~^ manual_div_ceil\n    let _: usize = (2048 + 6 - 1) / 6;\n    //~^ manual_div_ceil\n    let _: u32 = (0x2048 + 0x6 - 1) / 0x6;\n    //~^ manual_div_ceil\n\n    let _ = (2048 + 6u32 - 1) / 6u32;\n    //~^ manual_div_ceil\n\n    let _ = (1_000_000 + 6u32 - 1) / 6u32;\n    //~^ manual_div_ceil\n}\n\nfn issue_13950() {\n    let x = 33u32;\n    let _ = (x + 7) / 8;\n    //~^ manual_div_ceil\n    let _ = (7 + x) / 8;\n    //~^ manual_div_ceil\n\n    let y = -33i32;\n    let _ = (y + -8) / -7;\n    let _ = (-8 + y) / -7;\n    let _ = (y - 8) / -7;\n}\n\nfn issue_15705(size: u64, c: &u64) {\n    let _ = (size + c - 1) / c;\n    //~^ manual_div_ceil\n}\n\nstruct MyStruct(u32);\nimpl MyStruct {\n    // Method matching name on different type should not trigger lint\n    fn next_multiple_of(self, y: u32) -> u32 {\n        self.0.next_multiple_of(y)\n    }\n}\n\nfn issue_16219() {\n    let x = 33u32;\n\n    // Lint.\n    let _ = x.next_multiple_of(8) / 8;\n    //~^ manual_div_ceil\n    let _ = u32::next_multiple_of(x, 8) / 8;\n    //~^ manual_div_ceil\n\n    let y = &x;\n    let _ = y.next_multiple_of(8) / 8;\n    //~^ manual_div_ceil\n\n    // No lint.\n    let _ = x.next_multiple_of(8) / 7;\n    let _ = x.next_multiple_of(7) / 8;\n\n    let z = MyStruct(x);\n    let _ = z.next_multiple_of(8) / 8;\n}\n"
  },
  {
    "path": "tests/ui/manual_div_ceil.stderr",
    "content": "error: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:25:13\n   |\nLL |     let _ = (x + (y - 1)) / y;\n   |             ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`\n   |\n   = note: `-D clippy::manual-div-ceil` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_div_ceil)]`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:27:13\n   |\nLL |     let _ = ((y - 1) + x) / y;\n   |             ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:29:13\n   |\nLL |     let _ = (x + y - 1) / y;\n   |             ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:32:13\n   |\nLL |     let _ = (7_u32 + (4 - 1)) / 4;\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_u32.div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:34:13\n   |\nLL |     let _ = (7_i32 as u32 + (4 - 1)) / 4;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:6:17\n   |\nLL |         let _ = (x + 7) / 8;\n   |                 ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n...\nLL |     y!();\n   |     ---- in this macro invocation\n   |\n   = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:8:17\n   |\nLL |         let _ = (7 + x) / 8;\n   |                 ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n...\nLL |     y!();\n   |     ---- in this macro invocation\n   |\n   = note: this error originates in the macro `y` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:56:13\n   |\nLL |     let _ = (33u32 + 7) / eight!();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `33u32.div_ceil(eight!())`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:62:13\n   |\nLL |     let _ = (2048 + x - 1) / x;\n   |             ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:66:13\n   |\nLL |     let _ = (2048usize + x - 1) / x;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048usize.div_ceil(x)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:70:13\n   |\nLL |     let _ = (2048_usize + x - 1) / x;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:74:13\n   |\nLL |     let _ = (x + 4 - 1) / 4;\n   |             ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:77:18\n   |\nLL |     let _: u32 = (2048 + 6 - 1) / 6;\n   |                  ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:79:20\n   |\nLL |     let _: usize = (2048 + 6 - 1) / 6;\n   |                    ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(6)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:81:18\n   |\nLL |     let _: u32 = (0x2048 + 0x6 - 1) / 0x6;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `0x2048_u32.div_ceil(0x6)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:84:13\n   |\nLL |     let _ = (2048 + 6u32 - 1) / 6u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6u32)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:87:13\n   |\nLL |     let _ = (1_000_000 + 6u32 - 1) / 6u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:93:13\n   |\nLL |     let _ = (x + 7) / 8;\n   |             ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:95:13\n   |\nLL |     let _ = (7 + x) / 8;\n   |             ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:105:13\n   |\nLL |     let _ = (size + c - 1) / c;\n   |             ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `size.div_ceil(*c)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:121:13\n   |\nLL |     let _ = x.next_multiple_of(8) / 8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:123:13\n   |\nLL |     let _ = u32::next_multiple_of(x, 8) / 8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil.rs:127:13\n   |\nLL |     let _ = y.next_multiple_of(8) / 8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(8)`\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_div_ceil_with_feature.fixed",
    "content": "#![warn(clippy::manual_div_ceil)]\n#![feature(int_roundings)]\n\nfn main() {\n    let x = 7_i32;\n    let y = 4_i32;\n    let z = 3_i32;\n    let z_u: u32 = 11;\n\n    // Lint.\n    let _ = x.div_ceil(y);\n    //~^ manual_div_ceil\n    let _ = x.div_ceil(y);\n    //~^ manual_div_ceil\n    let _ = x.div_ceil(y);\n    //~^ manual_div_ceil\n\n    let _ = 7_i32.div_ceil(4);\n    //~^ manual_div_ceil\n    let _ = (7_i32 as u32).div_ceil(4);\n    //~^ manual_div_ceil\n    let _ = (7_u32 as i32).div_ceil(4);\n    //~^ manual_div_ceil\n    let _ = z_u.div_ceil(4);\n    //~^ manual_div_ceil\n\n    // No lint.\n    let _ = (x + (y - 2)) / y;\n    let _ = (x + (y + 1)) / y;\n\n    let _ = (x + (y - 1)) / z;\n}\n\nfn issue_13843() {\n    let x = 3usize;\n    let _ = 2048_usize.div_ceil(x);\n    //~^ manual_div_ceil\n\n    let x = 5usize;\n    let _ = 2048usize.div_ceil(x);\n    //~^ manual_div_ceil\n\n    let x = 5usize;\n    let _ = 2048_usize.div_ceil(x);\n    //~^ manual_div_ceil\n\n    let x = 2048usize;\n    let _ = x.div_ceil(4);\n    //~^ manual_div_ceil\n\n    let _ = 2048_i32.div_ceil(4);\n    //~^ manual_div_ceil\n\n    let _: u32 = 2048_u32.div_ceil(6);\n    //~^ manual_div_ceil\n    let _: usize = 2048_usize.div_ceil(6);\n    //~^ manual_div_ceil\n    let _: u32 = 0x2048_u32.div_ceil(0x6);\n    //~^ manual_div_ceil\n\n    let _ = 2048_u32.div_ceil(6u32);\n    //~^ manual_div_ceil\n\n    let x = -2;\n    let _ = (-2048_i32).div_ceil(x);\n    //~^ manual_div_ceil\n\n    let _ = 1_000_000_u32.div_ceil(6u32);\n    //~^ manual_div_ceil\n}\n\nfn issue_13950() {\n    let x = 33u32;\n    let _ = x.div_ceil(8);\n    //~^ manual_div_ceil\n    let _ = x.div_ceil(8);\n    //~^ manual_div_ceil\n\n    let y = -33i32;\n    let _ = y.div_ceil(-7);\n    //~^ manual_div_ceil\n    let _ = y.div_ceil(-7);\n    //~^ manual_div_ceil\n    let _ = y.div_ceil(-7);\n    //~^ manual_div_ceil\n}\n\nstruct MyStruct(i32);\nimpl MyStruct {\n    // Method matching name on different type should not trigger lint\n    fn next_multiple_of(self, y: i32) -> i32 {\n        self.0.next_multiple_of(y)\n    }\n}\n\nfn issue_16219() {\n    let x = 33i32;\n\n    // Lint.\n    let _ = x.div_ceil(8);\n    //~^ manual_div_ceil\n    let _ = x.div_ceil(8);\n    //~^ manual_div_ceil\n\n    let y = &x;\n    let _ = y.div_ceil(8);\n    //~^ manual_div_ceil\n\n    // No lint.\n    let _ = x.next_multiple_of(8) / 7;\n    let _ = x.next_multiple_of(7) / 8;\n\n    let z = MyStruct(x);\n    let _ = z.next_multiple_of(8) / 8;\n}\n"
  },
  {
    "path": "tests/ui/manual_div_ceil_with_feature.rs",
    "content": "#![warn(clippy::manual_div_ceil)]\n#![feature(int_roundings)]\n\nfn main() {\n    let x = 7_i32;\n    let y = 4_i32;\n    let z = 3_i32;\n    let z_u: u32 = 11;\n\n    // Lint.\n    let _ = (x + (y - 1)) / y;\n    //~^ manual_div_ceil\n    let _ = ((y - 1) + x) / y;\n    //~^ manual_div_ceil\n    let _ = (x + y - 1) / y;\n    //~^ manual_div_ceil\n\n    let _ = (7_i32 + (4 - 1)) / 4;\n    //~^ manual_div_ceil\n    let _ = (7_i32 as u32 + (4 - 1)) / 4;\n    //~^ manual_div_ceil\n    let _ = (7_u32 as i32 + (4 - 1)) / 4;\n    //~^ manual_div_ceil\n    let _ = (z_u + (4 - 1)) / 4;\n    //~^ manual_div_ceil\n\n    // No lint.\n    let _ = (x + (y - 2)) / y;\n    let _ = (x + (y + 1)) / y;\n\n    let _ = (x + (y - 1)) / z;\n}\n\nfn issue_13843() {\n    let x = 3usize;\n    let _ = (2048 + x - 1) / x;\n    //~^ manual_div_ceil\n\n    let x = 5usize;\n    let _ = (2048usize + x - 1) / x;\n    //~^ manual_div_ceil\n\n    let x = 5usize;\n    let _ = (2048_usize + x - 1) / x;\n    //~^ manual_div_ceil\n\n    let x = 2048usize;\n    let _ = (x + 4 - 1) / 4;\n    //~^ manual_div_ceil\n\n    let _ = (2048 + 4 - 1) / 4;\n    //~^ manual_div_ceil\n\n    let _: u32 = (2048 + 6 - 1) / 6;\n    //~^ manual_div_ceil\n    let _: usize = (2048 + 6 - 1) / 6;\n    //~^ manual_div_ceil\n    let _: u32 = (0x2048 + 0x6 - 1) / 0x6;\n    //~^ manual_div_ceil\n\n    let _ = (2048 + 6u32 - 1) / 6u32;\n    //~^ manual_div_ceil\n\n    let x = -2;\n    let _ = (-2048 + x - 1) / x;\n    //~^ manual_div_ceil\n\n    let _ = (1_000_000 + 6u32 - 1) / 6u32;\n    //~^ manual_div_ceil\n}\n\nfn issue_13950() {\n    let x = 33u32;\n    let _ = (x + 7) / 8;\n    //~^ manual_div_ceil\n    let _ = (7 + x) / 8;\n    //~^ manual_div_ceil\n\n    let y = -33i32;\n    let _ = (y + -8) / -7;\n    //~^ manual_div_ceil\n    let _ = (-8 + y) / -7;\n    //~^ manual_div_ceil\n    let _ = (y - 8) / -7;\n    //~^ manual_div_ceil\n}\n\nstruct MyStruct(i32);\nimpl MyStruct {\n    // Method matching name on different type should not trigger lint\n    fn next_multiple_of(self, y: i32) -> i32 {\n        self.0.next_multiple_of(y)\n    }\n}\n\nfn issue_16219() {\n    let x = 33i32;\n\n    // Lint.\n    let _ = x.next_multiple_of(8) / 8;\n    //~^ manual_div_ceil\n    let _ = i32::next_multiple_of(x, 8) / 8;\n    //~^ manual_div_ceil\n\n    let y = &x;\n    let _ = y.next_multiple_of(8) / 8;\n    //~^ manual_div_ceil\n\n    // No lint.\n    let _ = x.next_multiple_of(8) / 7;\n    let _ = x.next_multiple_of(7) / 8;\n\n    let z = MyStruct(x);\n    let _ = z.next_multiple_of(8) / 8;\n}\n"
  },
  {
    "path": "tests/ui/manual_div_ceil_with_feature.stderr",
    "content": "error: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:11:13\n   |\nLL |     let _ = (x + (y - 1)) / y;\n   |             ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`\n   |\n   = note: `-D clippy::manual-div-ceil` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_div_ceil)]`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:13:13\n   |\nLL |     let _ = ((y - 1) + x) / y;\n   |             ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:15:13\n   |\nLL |     let _ = (x + y - 1) / y;\n   |             ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:18:13\n   |\nLL |     let _ = (7_i32 + (4 - 1)) / 4;\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_i32.div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:20:13\n   |\nLL |     let _ = (7_i32 as u32 + (4 - 1)) / 4;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:22:13\n   |\nLL |     let _ = (7_u32 as i32 + (4 - 1)) / 4;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_u32 as i32).div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:24:13\n   |\nLL |     let _ = (z_u + (4 - 1)) / 4;\n   |             ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `z_u.div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:36:13\n   |\nLL |     let _ = (2048 + x - 1) / x;\n   |             ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:40:13\n   |\nLL |     let _ = (2048usize + x - 1) / x;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048usize.div_ceil(x)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:44:13\n   |\nLL |     let _ = (2048_usize + x - 1) / x;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:48:13\n   |\nLL |     let _ = (x + 4 - 1) / 4;\n   |             ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:51:13\n   |\nLL |     let _ = (2048 + 4 - 1) / 4;\n   |             ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_i32.div_ceil(4)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:54:18\n   |\nLL |     let _: u32 = (2048 + 6 - 1) / 6;\n   |                  ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:56:20\n   |\nLL |     let _: usize = (2048 + 6 - 1) / 6;\n   |                    ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(6)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:58:18\n   |\nLL |     let _: u32 = (0x2048 + 0x6 - 1) / 0x6;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `0x2048_u32.div_ceil(0x6)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:61:13\n   |\nLL |     let _ = (2048 + 6u32 - 1) / 6u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6u32)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:65:13\n   |\nLL |     let _ = (-2048 + x - 1) / x;\n   |             ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(-2048_i32).div_ceil(x)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:68:13\n   |\nLL |     let _ = (1_000_000 + 6u32 - 1) / 6u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:74:13\n   |\nLL |     let _ = (x + 7) / 8;\n   |             ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:76:13\n   |\nLL |     let _ = (7 + x) / 8;\n   |             ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:80:13\n   |\nLL |     let _ = (y + -8) / -7;\n   |             ^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:82:13\n   |\nLL |     let _ = (-8 + y) / -7;\n   |             ^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:84:13\n   |\nLL |     let _ = (y - 8) / -7;\n   |             ^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:100:13\n   |\nLL |     let _ = x.next_multiple_of(8) / 8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:102:13\n   |\nLL |     let _ = i32::next_multiple_of(x, 8) / 8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`\n\nerror: manually reimplementing `div_ceil`\n  --> tests/ui/manual_div_ceil_with_feature.rs:106:13\n   |\nLL |     let _ = y.next_multiple_of(8) / 8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(8)`\n\nerror: aborting due to 26 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_filter.fixed",
    "content": "#![warn(clippy::manual_filter)]\n#![allow(unused_variables, dead_code, clippy::useless_vec)]\n\nfn main() {\n    Some(0).filter(|&x| x <= 0);\n\n    Some(1).filter(|&x| x <= 0);\n\n    Some(2).filter(|&x| x <= 0);\n\n    Some(3).filter(|&x| x > 0);\n\n    let y = Some(4);\n    y.filter(|&x| x <= 0);\n\n    Some(5).filter(|&x| x > 0);\n\n    Some(6).as_ref().filter(|&x| x > &0);\n\n    let external_cond = true;\n    Some(String::new()).filter(|x| external_cond);\n\n    Some(7).filter(|&x| external_cond);\n\n    Some(8).filter(|&x| x != 0);\n\n    Some(9).filter(|&x| x > 10 && x < 100);\n\n    const fn f1() {\n        // Don't lint, `.filter` is not const\n        match Some(10) {\n            Some(x) => {\n                if x > 10 && x < 100 {\n                    Some(x)\n                } else {\n                    None\n                }\n            },\n            None => None,\n        };\n    }\n\n    #[allow(clippy::blocks_in_conditions)]\n    Some(11).filter(|&x| {\n                println!(\"foo\");\n                x > 10 && x < 100\n            });\n\n    match Some(12) {\n        // Don't Lint, statement is lost by `.filter`\n        Some(x) => {\n            if x > 10 && x < 100 {\n                println!(\"foo\");\n                Some(x)\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    match Some(13) {\n        // Don't Lint, because of `None => Some(1)`\n        Some(x) => {\n            if x > 10 && x < 100 {\n                println!(\"foo\");\n                Some(x)\n            } else {\n                None\n            }\n        },\n        None => Some(1),\n    };\n\n    unsafe fn f(x: u32) -> bool {\n        true\n    }\n    let _ = Some(14).filter(|&x| unsafe { f(x) });\n    let _ = Some(15).filter(|&x| unsafe { f(x) });\n\n    #[allow(clippy::redundant_pattern_matching)]\n    if let Some(_) = Some(16) {\n        Some(16)\n    } else { Some(16).filter(|&x| x % 2 == 0) };\n\n    match Some((17, 17)) {\n        // Not linted for now could be\n        Some((x, y)) => {\n            if y != x {\n                Some((x, y))\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    struct NamedTuple {\n        pub x: u8,\n        pub y: (i32, u32),\n    }\n\n    match Some(NamedTuple {\n        // Not linted for now could be\n        x: 17,\n        y: (18, 19),\n    }) {\n        Some(NamedTuple { x, y }) => {\n            if y.1 != x as u32 {\n                Some(NamedTuple { x, y })\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    match Some(20) {\n        // Don't Lint, because `Some(3*x)` is not `None`\n        None => None,\n        Some(x) => {\n            if x > 0 {\n                Some(3 * x)\n            } else {\n                Some(x)\n            }\n        },\n    };\n\n    // Don't lint: https://github.com/rust-lang/rust-clippy/issues/10088\n    let result = if let Some(a) = maybe_some() {\n        if let Some(b) = maybe_some() {\n            Some(a + b)\n        } else {\n            Some(a)\n        }\n    } else {\n        None\n    };\n\n    let allowed_integers = vec![3, 4, 5, 6];\n    // Don't lint, since there's a side effect in the else branch\n    match Some(21) {\n        Some(x) => {\n            if allowed_integers.contains(&x) {\n                Some(x)\n            } else {\n                println!(\"Invalid integer: {x:?}\");\n                None\n            }\n        },\n        None => None,\n    };\n}\n\nfn maybe_some() -> Option<u32> {\n    Some(0)\n}\n"
  },
  {
    "path": "tests/ui/manual_filter.rs",
    "content": "#![warn(clippy::manual_filter)]\n#![allow(unused_variables, dead_code, clippy::useless_vec)]\n\nfn main() {\n    match Some(0) {\n        //~^ manual_filter\n        None => None,\n        Some(x) => {\n            if x > 0 {\n                None\n            } else {\n                Some(x)\n            }\n        },\n    };\n\n    match Some(1) {\n        //~^ manual_filter\n        Some(x) => {\n            if x > 0 {\n                None\n            } else {\n                Some(x)\n            }\n        },\n        None => None,\n    };\n\n    match Some(2) {\n        //~^ manual_filter\n        Some(x) => {\n            if x > 0 {\n                None\n            } else {\n                Some(x)\n            }\n        },\n        _ => None,\n    };\n\n    match Some(3) {\n        //~^ manual_filter\n        Some(x) => {\n            if x > 0 {\n                Some(x)\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    let y = Some(4);\n    match y {\n        //~^ manual_filter\n        // Some(4)\n        None => None,\n        Some(x) => {\n            if x > 0 {\n                None\n            } else {\n                Some(x)\n            }\n        },\n    };\n\n    match Some(5) {\n        //~^ manual_filter\n        Some(x) => {\n            if x > 0 {\n                Some(x)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    };\n\n    match Some(6) {\n        //~^ manual_filter\n        Some(ref x) => {\n            if x > &0 {\n                Some(x)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    };\n\n    let external_cond = true;\n    match Some(String::new()) {\n        //~^ manual_filter\n        Some(x) => {\n            if external_cond {\n                Some(x)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    };\n\n    if let Some(x) = Some(7) {\n        //~^ manual_filter\n        if external_cond { Some(x) } else { None }\n    } else {\n        None\n    };\n\n    match &Some(8) {\n        //~^ manual_filter\n        &Some(x) => {\n            if x != 0 {\n                Some(x)\n            } else {\n                None\n            }\n        },\n        _ => None,\n    };\n\n    match Some(9) {\n        //~^ manual_filter\n        Some(x) => {\n            if x > 10 && x < 100 {\n                Some(x)\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    const fn f1() {\n        // Don't lint, `.filter` is not const\n        match Some(10) {\n            Some(x) => {\n                if x > 10 && x < 100 {\n                    Some(x)\n                } else {\n                    None\n                }\n            },\n            None => None,\n        };\n    }\n\n    #[allow(clippy::blocks_in_conditions)]\n    match Some(11) {\n        //~^ manual_filter\n        // Lint, statement is preserved by `.filter`\n        Some(x) => {\n            if {\n                println!(\"foo\");\n                x > 10 && x < 100\n            } {\n                Some(x)\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    match Some(12) {\n        // Don't Lint, statement is lost by `.filter`\n        Some(x) => {\n            if x > 10 && x < 100 {\n                println!(\"foo\");\n                Some(x)\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    match Some(13) {\n        // Don't Lint, because of `None => Some(1)`\n        Some(x) => {\n            if x > 10 && x < 100 {\n                println!(\"foo\");\n                Some(x)\n            } else {\n                None\n            }\n        },\n        None => Some(1),\n    };\n\n    unsafe fn f(x: u32) -> bool {\n        true\n    }\n    let _ = match Some(14) {\n        //~^ manual_filter\n        Some(x) => {\n            if unsafe { f(x) } {\n                Some(x)\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n    let _ = match Some(15) {\n        //~^ manual_filter\n        Some(x) => unsafe { if f(x) { Some(x) } else { None } },\n        None => None,\n    };\n\n    #[allow(clippy::redundant_pattern_matching)]\n    if let Some(_) = Some(16) {\n        Some(16)\n    } else if let Some(x) = Some(16) {\n        //~^ manual_filter\n        // Lint starting from here\n        if x % 2 == 0 { Some(x) } else { None }\n    } else {\n        None\n    };\n\n    match Some((17, 17)) {\n        // Not linted for now could be\n        Some((x, y)) => {\n            if y != x {\n                Some((x, y))\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    struct NamedTuple {\n        pub x: u8,\n        pub y: (i32, u32),\n    }\n\n    match Some(NamedTuple {\n        // Not linted for now could be\n        x: 17,\n        y: (18, 19),\n    }) {\n        Some(NamedTuple { x, y }) => {\n            if y.1 != x as u32 {\n                Some(NamedTuple { x, y })\n            } else {\n                None\n            }\n        },\n        None => None,\n    };\n\n    match Some(20) {\n        // Don't Lint, because `Some(3*x)` is not `None`\n        None => None,\n        Some(x) => {\n            if x > 0 {\n                Some(3 * x)\n            } else {\n                Some(x)\n            }\n        },\n    };\n\n    // Don't lint: https://github.com/rust-lang/rust-clippy/issues/10088\n    let result = if let Some(a) = maybe_some() {\n        if let Some(b) = maybe_some() {\n            Some(a + b)\n        } else {\n            Some(a)\n        }\n    } else {\n        None\n    };\n\n    let allowed_integers = vec![3, 4, 5, 6];\n    // Don't lint, since there's a side effect in the else branch\n    match Some(21) {\n        Some(x) => {\n            if allowed_integers.contains(&x) {\n                Some(x)\n            } else {\n                println!(\"Invalid integer: {x:?}\");\n                None\n            }\n        },\n        None => None,\n    };\n}\n\nfn maybe_some() -> Option<u32> {\n    Some(0)\n}\n"
  },
  {
    "path": "tests/ui/manual_filter.stderr",
    "content": "error: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:5:5\n   |\nLL | /     match Some(0) {\nLL | |\nLL | |         None => None,\nLL | |         Some(x) => {\n...  |\nLL | |         },\nLL | |     };\n   | |_____^ help: try: `Some(0).filter(|&x| x <= 0)`\n   |\n   = note: `-D clippy::manual-filter` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_filter)]`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:17:5\n   |\nLL | /     match Some(1) {\nLL | |\nLL | |         Some(x) => {\nLL | |             if x > 0 {\n...  |\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(1).filter(|&x| x <= 0)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:29:5\n   |\nLL | /     match Some(2) {\nLL | |\nLL | |         Some(x) => {\nLL | |             if x > 0 {\n...  |\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(2).filter(|&x| x <= 0)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:41:5\n   |\nLL | /     match Some(3) {\nLL | |\nLL | |         Some(x) => {\nLL | |             if x > 0 {\n...  |\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(3).filter(|&x| x > 0)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:54:5\n   |\nLL | /     match y {\nLL | |\nLL | |         // Some(4)\nLL | |         None => None,\n...  |\nLL | |         },\nLL | |     };\n   | |_____^ help: try: `y.filter(|&x| x <= 0)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:67:5\n   |\nLL | /     match Some(5) {\nLL | |\nLL | |         Some(x) => {\nLL | |             if x > 0 {\n...  |\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(5).filter(|&x| x > 0)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:79:5\n   |\nLL | /     match Some(6) {\nLL | |\nLL | |         Some(ref x) => {\nLL | |             if x > &0 {\n...  |\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(6).as_ref().filter(|&x| x > &0)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:92:5\n   |\nLL | /     match Some(String::new()) {\nLL | |\nLL | |         Some(x) => {\nLL | |             if external_cond {\n...  |\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(String::new()).filter(|x| external_cond)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:104:5\n   |\nLL | /     if let Some(x) = Some(7) {\nLL | |\nLL | |         if external_cond { Some(x) } else { None }\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^ help: try: `Some(7).filter(|&x| external_cond)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:111:5\n   |\nLL | /     match &Some(8) {\nLL | |\nLL | |         &Some(x) => {\nLL | |             if x != 0 {\n...  |\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(8).filter(|&x| x != 0)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:123:5\n   |\nLL | /     match Some(9) {\nLL | |\nLL | |         Some(x) => {\nLL | |             if x > 10 && x < 100 {\n...  |\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(9).filter(|&x| x > 10 && x < 100)`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:150:5\n   |\nLL | /     match Some(11) {\nLL | |\nLL | |         // Lint, statement is preserved by `.filter`\nLL | |         Some(x) => {\n...  |\nLL | |         None => None,\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     Some(11).filter(|&x| {\nLL +                 println!(\"foo\");\nLL +                 x > 10 && x < 100\nLL ~             });\n   |\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:195:13\n   |\nLL |       let _ = match Some(14) {\n   |  _____________^\nLL | |\nLL | |         Some(x) => {\nLL | |             if unsafe { f(x) } {\n...  |\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(14).filter(|&x| unsafe { f(x) })`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:206:13\n   |\nLL |       let _ = match Some(15) {\n   |  _____________^\nLL | |\nLL | |         Some(x) => unsafe { if f(x) { Some(x) } else { None } },\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(15).filter(|&x| unsafe { f(x) })`\n\nerror: manual implementation of `Option::filter`\n  --> tests/ui/manual_filter.rs:215:12\n   |\nLL |       } else if let Some(x) = Some(16) {\n   |  ____________^\nLL | |\nLL | |         // Lint starting from here\nLL | |         if x % 2 == 0 { Some(x) } else { None }\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^ help: try: `{ Some(16).filter(|&x| x % 2 == 0) }`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_filter_map.fixed",
    "content": "#![allow(dead_code)]\n#![warn(clippy::manual_filter_map)]\n#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure\n#![allow(clippy::useless_vec)]\n#![allow(clippy::struct_field_names)]\n\nfn main() {\n    // is_some(), unwrap()\n    let _ = (0..).filter_map(|a| to_opt(a));\n    //~^ manual_filter_map\n\n    // ref pattern, expect()\n    let _ = (0..).filter_map(|a| to_opt(a));\n    //~^ manual_filter_map\n\n    // is_ok(), unwrap_or()\n    let _ = (0..).filter_map(|a| to_res(a).ok());\n    //~^ manual_filter_map\n\n    let _ = (1..5)\n        .filter_map(|y| *to_ref(to_opt(y)));\n    let _ = (1..5)\n        .filter_map(|y| *to_ref(to_opt(y)));\n\n    let _ = (1..5)\n        .filter_map(|y| to_ref(to_res(y)).ok());\n    let _ = (1..5)\n        .filter_map(|y| to_ref(to_res(y)).ok());\n}\n\n#[rustfmt::skip]\nfn simple_equal() {\n    iter::<Option<&u8>>().find_map(|x| x.cloned());\n    //~^ manual_find_map\n    iter::<&Option<&u8>>().find_map(|x| x.cloned());\n    //~^ manual_find_map\n    iter::<&Option<String>>().find_map(|x| x.as_deref());\n    //~^ manual_find_map\n    iter::<Option<&String>>().find_map(|y| to_ref(y).cloned());\n    //~^ manual_find_map\n\n    iter::<Result<u8, ()>>().find_map(|x| x.ok());\n    //~^ manual_find_map\n    iter::<&Result<u8, ()>>().find_map(|x| x.ok());\n    //~^ manual_find_map\n    iter::<&&Result<u8, ()>>().find_map(|x| x.ok());\n    //~^ manual_find_map\n    iter::<Result<&u8, ()>>().find_map(|x| x.cloned().ok());\n    //~^ manual_find_map\n    iter::<&Result<&u8, ()>>().find_map(|x| x.cloned().ok());\n    //~^ manual_find_map\n    iter::<&Result<String, ()>>().find_map(|x| x.as_deref().ok());\n    //~^ manual_find_map\n    iter::<Result<&String, ()>>().find_map(|y| to_ref(y).cloned().ok());\n    //~^ manual_find_map\n}\n\nfn no_lint() {\n    // no shared code\n    let _ = (0..).filter(|n| *n > 1).map(|n| n + 1);\n\n    // very close but different since filter() provides a reference\n    let _ = (0..).filter(|n| to_opt(n).is_some()).map(|a| to_opt(a).unwrap());\n\n    // similar but different\n    let _ = (0..).filter(|n| to_opt(n).is_some()).map(|n| to_res(n).unwrap());\n    let _ = (0..)\n        .filter(|n| to_opt(n).map(|n| n + 1).is_some())\n        .map(|a| to_opt(a).unwrap());\n}\n\nfn iter<T>() -> impl Iterator<Item = T> {\n    std::iter::empty()\n}\n\nfn to_opt<T>(_: T) -> Option<T> {\n    unimplemented!()\n}\n\nfn to_res<T>(_: T) -> Result<T, ()> {\n    unimplemented!()\n}\n\nfn to_ref<'a, T>(_: T) -> &'a T {\n    unimplemented!()\n}\n\nstruct Issue8920<'a> {\n    option_field: Option<String>,\n    result_field: Result<String, ()>,\n    ref_field: Option<&'a usize>,\n}\n\nfn issue_8920() {\n    let mut vec = vec![Issue8920 {\n        option_field: Some(String::from(\"str\")),\n        result_field: Ok(String::from(\"str\")),\n        ref_field: Some(&1),\n    }];\n\n    let _ = vec\n        .iter()\n        .filter_map(|f| f.option_field.clone());\n\n    let _ = vec\n        .iter()\n        .filter_map(|f| f.ref_field.cloned());\n\n    let _ = vec\n        .iter()\n        .filter_map(|f| f.ref_field.copied());\n\n    let _ = vec\n        .iter()\n        .filter_map(|f| f.result_field.clone().ok());\n\n    let _ = vec\n        .iter()\n        .filter_map(|f| f.result_field.as_ref().ok());\n\n    let _ = vec\n        .iter()\n        .filter_map(|f| f.result_field.as_deref().ok());\n\n    let _ = vec\n        .iter_mut()\n        .filter_map(|f| f.result_field.as_mut().ok());\n\n    let _ = vec\n        .iter_mut()\n        .filter_map(|f| f.result_field.as_deref_mut().ok());\n\n    let _ = vec\n        .iter()\n        .filter_map(|f| f.result_field.to_owned().ok());\n}\n\nfn issue8010() {\n    #[derive(Clone)]\n    enum Enum {\n        A(i32),\n        B,\n    }\n\n    let iter = [Enum::A(123), Enum::B].into_iter();\n\n    let _x = iter.clone().filter_map(|x| match x { Enum::A(s) => Some(s), _ => None });\n    let _x = iter.clone().filter(|x| matches!(x, Enum::B)).map(|x| match x {\n        Enum::A(s) => s,\n        _ => unreachable!(),\n    });\n    let _x = iter\n        .clone()\n        .filter_map(|x| match x { Enum::A(s) => Some(s), _ => None });\n    #[allow(clippy::unused_unit)]\n    let _x = iter\n        .clone()\n        .filter(|x| matches!(x, Enum::B))\n        .map(|x| if let Enum::B = x { () } else { unreachable!() });\n}\n"
  },
  {
    "path": "tests/ui/manual_filter_map.rs",
    "content": "#![allow(dead_code)]\n#![warn(clippy::manual_filter_map)]\n#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure\n#![allow(clippy::useless_vec)]\n#![allow(clippy::struct_field_names)]\n\nfn main() {\n    // is_some(), unwrap()\n    let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());\n    //~^ manual_filter_map\n\n    // ref pattern, expect()\n    let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect(\"hi\"));\n    //~^ manual_filter_map\n\n    // is_ok(), unwrap_or()\n    let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));\n    //~^ manual_filter_map\n\n    let _ = (1..5)\n        .filter(|&x| to_ref(to_opt(x)).is_some())\n        //~^ manual_filter_map\n        .map(|y| to_ref(to_opt(y)).unwrap());\n    let _ = (1..5)\n        .filter(|x| to_ref(to_opt(*x)).is_some())\n        //~^ manual_filter_map\n        .map(|y| to_ref(to_opt(y)).unwrap());\n\n    let _ = (1..5)\n        .filter(|&x| to_ref(to_res(x)).is_ok())\n        //~^ manual_filter_map\n        .map(|y| to_ref(to_res(y)).unwrap());\n    let _ = (1..5)\n        .filter(|x| to_ref(to_res(*x)).is_ok())\n        //~^ manual_filter_map\n        .map(|y| to_ref(to_res(y)).unwrap());\n}\n\n#[rustfmt::skip]\nfn simple_equal() {\n    iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());\n    //~^ manual_find_map\n    iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());\n    //~^ manual_find_map\n    iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap());\n    //~^ manual_find_map\n    iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());\n    //~^ manual_find_map\n\n    iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());\n    //~^ manual_find_map\n    iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());\n    //~^ manual_find_map\n    iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap());\n    //~^ manual_find_map\n    iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());\n    //~^ manual_find_map\n}\n\nfn no_lint() {\n    // no shared code\n    let _ = (0..).filter(|n| *n > 1).map(|n| n + 1);\n\n    // very close but different since filter() provides a reference\n    let _ = (0..).filter(|n| to_opt(n).is_some()).map(|a| to_opt(a).unwrap());\n\n    // similar but different\n    let _ = (0..).filter(|n| to_opt(n).is_some()).map(|n| to_res(n).unwrap());\n    let _ = (0..)\n        .filter(|n| to_opt(n).map(|n| n + 1).is_some())\n        .map(|a| to_opt(a).unwrap());\n}\n\nfn iter<T>() -> impl Iterator<Item = T> {\n    std::iter::empty()\n}\n\nfn to_opt<T>(_: T) -> Option<T> {\n    unimplemented!()\n}\n\nfn to_res<T>(_: T) -> Result<T, ()> {\n    unimplemented!()\n}\n\nfn to_ref<'a, T>(_: T) -> &'a T {\n    unimplemented!()\n}\n\nstruct Issue8920<'a> {\n    option_field: Option<String>,\n    result_field: Result<String, ()>,\n    ref_field: Option<&'a usize>,\n}\n\nfn issue_8920() {\n    let mut vec = vec![Issue8920 {\n        option_field: Some(String::from(\"str\")),\n        result_field: Ok(String::from(\"str\")),\n        ref_field: Some(&1),\n    }];\n\n    let _ = vec\n        .iter()\n        .filter(|f| f.option_field.is_some())\n        //~^ manual_filter_map\n        .map(|f| f.option_field.clone().unwrap());\n\n    let _ = vec\n        .iter()\n        .filter(|f| f.ref_field.is_some())\n        //~^ manual_filter_map\n        .map(|f| f.ref_field.cloned().unwrap());\n\n    let _ = vec\n        .iter()\n        .filter(|f| f.ref_field.is_some())\n        //~^ manual_filter_map\n        .map(|f| f.ref_field.copied().unwrap());\n\n    let _ = vec\n        .iter()\n        .filter(|f| f.result_field.is_ok())\n        //~^ manual_filter_map\n        .map(|f| f.result_field.clone().unwrap());\n\n    let _ = vec\n        .iter()\n        .filter(|f| f.result_field.is_ok())\n        //~^ manual_filter_map\n        .map(|f| f.result_field.as_ref().unwrap());\n\n    let _ = vec\n        .iter()\n        .filter(|f| f.result_field.is_ok())\n        //~^ manual_filter_map\n        .map(|f| f.result_field.as_deref().unwrap());\n\n    let _ = vec\n        .iter_mut()\n        .filter(|f| f.result_field.is_ok())\n        //~^ manual_filter_map\n        .map(|f| f.result_field.as_mut().unwrap());\n\n    let _ = vec\n        .iter_mut()\n        .filter(|f| f.result_field.is_ok())\n        //~^ manual_filter_map\n        .map(|f| f.result_field.as_deref_mut().unwrap());\n\n    let _ = vec\n        .iter()\n        .filter(|f| f.result_field.is_ok())\n        //~^ manual_filter_map\n        .map(|f| f.result_field.to_owned().unwrap());\n}\n\nfn issue8010() {\n    #[derive(Clone)]\n    enum Enum {\n        A(i32),\n        B,\n    }\n\n    let iter = [Enum::A(123), Enum::B].into_iter();\n\n    let _x = iter.clone().filter(|x| matches!(x, Enum::A(_))).map(|x| match x {\n        //~^ manual_filter_map\n        Enum::A(s) => s,\n        _ => unreachable!(),\n    });\n    let _x = iter.clone().filter(|x| matches!(x, Enum::B)).map(|x| match x {\n        Enum::A(s) => s,\n        _ => unreachable!(),\n    });\n    let _x = iter\n        .clone()\n        .filter(|x| matches!(x, Enum::A(_)))\n        //~^ manual_filter_map\n        .map(|x| if let Enum::A(s) = x { s } else { unreachable!() });\n    #[allow(clippy::unused_unit)]\n    let _x = iter\n        .clone()\n        .filter(|x| matches!(x, Enum::B))\n        .map(|x| if let Enum::B = x { () } else { unreachable!() });\n}\n"
  },
  {
    "path": "tests/ui/manual_filter_map.stderr",
    "content": "error: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:9:19\n   |\nLL |     let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:9:30\n   |\nLL |     let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());\n   |                              ^^^^^^^^^^\n   = note: `-D clippy::manual-filter-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_filter_map)]`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:13:19\n   |\nLL |     let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect(\"hi\"));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:13:31\n   |\nLL |     let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect(\"hi\"));\n   |                               ^^^^^^^^^\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:17:19\n   |\nLL |     let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:17:31\n   |\nLL |     let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));\n   |                               ^^^^^^^^^\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:21:10\n   |\nLL |           .filter(|&x| to_ref(to_opt(x)).is_some())\n   |  __________^\nLL | |\nLL | |         .map(|y| to_ref(to_opt(y)).unwrap());\n   | |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:21:22\n   |\nLL |         .filter(|&x| to_ref(to_opt(x)).is_some())\n   |                      ^^^^^^^^^^^^^^^^^\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:25:10\n   |\nLL |           .filter(|x| to_ref(to_opt(*x)).is_some())\n   |  __________^\nLL | |\nLL | |         .map(|y| to_ref(to_opt(y)).unwrap());\n   | |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:25:21\n   |\nLL |         .filter(|x| to_ref(to_opt(*x)).is_some())\n   |                     ^^^^^^^^^^^^^^^^^^\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:30:10\n   |\nLL |           .filter(|&x| to_ref(to_res(x)).is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|y| to_ref(to_res(y)).unwrap());\n   | |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:30:22\n   |\nLL |         .filter(|&x| to_ref(to_res(x)).is_ok())\n   |                      ^^^^^^^^^^^^^^^^^\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:34:10\n   |\nLL |           .filter(|x| to_ref(to_res(*x)).is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|y| to_ref(to_res(y)).unwrap());\n   | |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:34:21\n   |\nLL |         .filter(|x| to_ref(to_res(*x)).is_ok())\n   |                     ^^^^^^^^^^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:41:27\n   |\nLL |     iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`\n   |\n   = note: `-D clippy::manual-find-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:43:28\n   |\nLL |     iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:45:31\n   |\nLL |     iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:47:31\n   |\nLL |     iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:47:41\n   |\nLL |     iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());\n   |                                         ^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:50:30\n   |\nLL |     iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:52:31\n   |\nLL |     iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:54:32\n   |\nLL |     iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:56:31\n   |\nLL |     iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:58:32\n   |\nLL |     iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:60:35\n   |\nLL |     iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap());\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_filter_map.rs:62:35\n   |\nLL |     iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_filter_map.rs:62:45\n   |\nLL |     iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());\n   |                                             ^^^^^^^^^\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:111:10\n   |\nLL |           .filter(|f| f.option_field.is_some())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.option_field.clone().unwrap());\n   | |_________________________________________________^ help: try: `filter_map(|f| f.option_field.clone())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:117:10\n   |\nLL |           .filter(|f| f.ref_field.is_some())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.ref_field.cloned().unwrap());\n   | |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.cloned())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:123:10\n   |\nLL |           .filter(|f| f.ref_field.is_some())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.ref_field.copied().unwrap());\n   | |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.copied())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:129:10\n   |\nLL |           .filter(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.clone().unwrap());\n   | |_________________________________________________^ help: try: `filter_map(|f| f.result_field.clone().ok())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:135:10\n   |\nLL |           .filter(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.as_ref().unwrap());\n   | |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_ref().ok())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:141:10\n   |\nLL |           .filter(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.as_deref().unwrap());\n   | |____________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref().ok())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:147:10\n   |\nLL |           .filter(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.as_mut().unwrap());\n   | |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_mut().ok())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:153:10\n   |\nLL |           .filter(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.as_deref_mut().unwrap());\n   | |________________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref_mut().ok())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:159:10\n   |\nLL |           .filter(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.to_owned().unwrap());\n   | |____________________________________________________^ help: try: `filter_map(|f| f.result_field.to_owned().ok())`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:173:27\n   |\nLL |       let _x = iter.clone().filter(|x| matches!(x, Enum::A(_))).map(|x| match x {\n   |  ___________________________^\nLL | |\nLL | |         Enum::A(s) => s,\nLL | |         _ => unreachable!(),\nLL | |     });\n   | |______^ help: try: `filter_map(|x| match x { Enum::A(s) => Some(s), _ => None })`\n\nerror: `filter(..).map(..)` can be simplified as `filter_map(..)`\n  --> tests/ui/manual_filter_map.rs:184:10\n   |\nLL |           .filter(|x| matches!(x, Enum::A(_)))\n   |  __________^\nLL | |\nLL | |         .map(|x| if let Enum::A(s) = x { s } else { unreachable!() });\n   | |_____________________________________________________________________^ help: try: `filter_map(|x| match x { Enum::A(s) => Some(s), _ => None })`\n\nerror: aborting due to 29 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_find.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::manual_find)]\n//@no-rustfix\nfn vec_string(strings: Vec<String>) -> Option<String> {\n    for s in strings {\n        //~^ manual_find\n\n        if s == String::new() {\n            return Some(s);\n        }\n    }\n    None\n}\n\nfn tuple(arr: Vec<(String, i32)>) -> Option<String> {\n    for (s, _) in arr {\n        //~^ manual_find\n\n        if s == String::new() {\n            return Some(s);\n        }\n    }\n    None\n}\n\nmod issue9521 {\n    fn condition(x: u32, y: u32) -> Result<bool, ()> {\n        todo!()\n    }\n\n    fn find_with_early_return(v: Vec<u32>) -> Option<u32> {\n        for x in v {\n            if condition(x, 10).ok()? {\n                return Some(x);\n            }\n        }\n        None\n    }\n\n    fn find_with_early_break(v: Vec<u32>) -> Option<u32> {\n        for x in v {\n            if if x < 3 {\n                break;\n            } else {\n                x < 10\n            } {\n                return Some(x);\n            }\n        }\n        None\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_find.stderr",
    "content": "error: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find.rs:5:5\n   |\nLL | /     for s in strings {\nLL | |\nLL | |\nLL | |         if s == String::new() {\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `strings.into_iter().find(|s| s == String::new())`\n   |\n   = note: you may need to dereference some variables\n   = note: `-D clippy::manual-find` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_find)]`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find.rs:16:5\n   |\nLL | /     for (s, _) in arr {\nLL | |\nLL | |\nLL | |         if s == String::new() {\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `arr.into_iter().map(|(s, _)| s).find(|s| s == String::new())`\n   |\n   = note: you may need to dereference some variables\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_find_fixable.fixed",
    "content": "#![warn(clippy::manual_find)]\n#![allow(unused)]\n#![allow(clippy::needless_return, clippy::uninlined_format_args)]\n\nuse std::collections::HashMap;\n\nconst ARRAY: &[u32; 5] = &[2, 7, 1, 9, 3];\n\nfn lookup(n: u32) -> Option<u32> {\n    ARRAY.iter().find(|&&v| v == n).copied()\n}\n\nfn with_pat(arr: Vec<(u32, u32)>) -> Option<u32> {\n    arr.into_iter().map(|(a, _)| a).find(|&a| a.is_multiple_of(2))\n}\n\nstruct Data {\n    name: String,\n    is_true: bool,\n}\nfn with_struct(arr: Vec<Data>) -> Option<Data> {\n    arr.into_iter().find(|el| el.name.len() == 10)\n}\n\nstruct Tuple(usize, usize);\nfn with_tuple_struct(arr: Vec<Tuple>) -> Option<usize> {\n    arr.into_iter().map(|Tuple(a, _)| a).find(|&a| a >= 3)\n}\n\nstruct A;\nimpl A {\n    fn should_keep(&self) -> bool {\n        true\n    }\n}\nfn with_method_call(arr: Vec<A>) -> Option<A> {\n    arr.into_iter().find(|el| el.should_keep())\n}\n\nfn with_closure(arr: Vec<u32>) -> Option<u32> {\n    let f = |el: u32| -> u32 { el + 10 };\n    arr.into_iter().find(|&el| f(el) == 20)\n}\n\nfn with_closure2(arr: HashMap<String, i32>) -> Option<i32> {\n    let f = |el: i32| -> bool { el == 10 };\n    arr.values().find(|&&el| f(el)).copied()\n}\n\nfn with_bool(arr: Vec<Data>) -> Option<Data> {\n    arr.into_iter().find(|el| el.is_true)\n}\n\nfn with_side_effects(arr: Vec<u32>) -> Option<u32> {\n    for v in arr {\n        if v == 1 {\n            println!(\"side effect\");\n            return Some(v);\n        }\n    }\n    None\n}\n\nfn with_else(arr: Vec<u32>) -> Option<u32> {\n    for el in arr {\n        if el.is_multiple_of(2) {\n            return Some(el);\n        } else {\n            println!(\"{}\", el);\n        }\n    }\n    None\n}\n\nfn tuple_with_ref(v: [(u8, &u8); 3]) -> Option<u8> {\n    v.into_iter().map(|(_, &x)| x).find(|&x| x > 10)\n}\n\nfn ref_to_tuple_with_ref(v: &[(u8, &u8)]) -> Option<u8> {\n    v.iter().map(|&(_, &x)| x).find(|&x| x > 10)\n}\n\nfn explicit_ret(arr: Vec<i32>) -> Option<i32> {\n    arr.into_iter().find(|&x| x >= 5)\n}\n\nfn plus_one(a: i32) -> Option<i32> {\n    Some(a + 1)\n}\nfn fn_instead_of_some(a: &[i32]) -> Option<i32> {\n    for &x in a {\n        if x == 1 {\n            return plus_one(x);\n        }\n    }\n    None\n}\n\nfn for_in_condition(a: &[i32], b: bool) -> Option<i32> {\n    if b {\n        for &x in a {\n            if x == 1 {\n                return Some(x);\n            }\n        }\n    }\n    None\n}\n\nfn intermediate_statements(a: &[i32]) -> Option<i32> {\n    for &x in a {\n        if x == 1 {\n            return Some(x);\n        }\n    }\n\n    println!(\"side effect\");\n\n    None\n}\n\nfn mixed_binding_modes(arr: Vec<(i32, String)>) -> Option<i32> {\n    for (x, mut s) in arr {\n        if x == 1 && s.as_mut_str().len() == 2 {\n            return Some(x);\n        }\n    }\n    None\n}\n\nfn as_closure() {\n    #[rustfmt::skip]\n    let f = |arr: Vec<i32>| -> Option<i32> {\n        arr.into_iter().find(|&x| x < 1)\n    };\n}\n\nfn in_block(a: &[i32]) -> Option<i32> {\n    let should_be_none = {\n        for &x in a {\n            if x == 1 {\n                return Some(x);\n            }\n        }\n        None\n    };\n\n    assert!(should_be_none.is_none());\n\n    should_be_none\n}\n\n// Not handled yet\nfn mut_binding(v: Vec<String>) -> Option<String> {\n    for mut s in v {\n        if s.as_mut_str().len() > 1 {\n            return Some(s);\n        }\n    }\n    None\n}\n\nfn subpattern(v: Vec<[u32; 32]>) -> Option<[u32; 32]> {\n    for a @ [first, ..] in v {\n        if a[12] == first {\n            return Some(a);\n        }\n    }\n    None\n}\n\nfn two_bindings(v: Vec<(u8, u8)>) -> Option<u8> {\n    for (a, n) in v {\n        if a == n {\n            return Some(a);\n        }\n    }\n    None\n}\n\nfn main() {}\n\nmod issue14826 {\n    fn adjust_fixable(needle: &str) -> Option<&'static str> {\n        [\"foo\", \"bar\"].iter().find(|&candidate| candidate.eq_ignore_ascii_case(needle)).map(|v| v as _)\n    }\n\n    fn adjust_unfixable(needle: &str) -> Option<*const str> {\n        [\"foo\", \"bar\"].iter().find(|&&candidate| candidate.eq_ignore_ascii_case(needle)).copied().map(|v| v as _)\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_find_fixable.rs",
    "content": "#![warn(clippy::manual_find)]\n#![allow(unused)]\n#![allow(clippy::needless_return, clippy::uninlined_format_args)]\n\nuse std::collections::HashMap;\n\nconst ARRAY: &[u32; 5] = &[2, 7, 1, 9, 3];\n\nfn lookup(n: u32) -> Option<u32> {\n    for &v in ARRAY {\n        //~^ manual_find\n        if v == n {\n            return Some(v);\n        }\n    }\n    None\n}\n\nfn with_pat(arr: Vec<(u32, u32)>) -> Option<u32> {\n    for (a, _) in arr {\n        //~^ manual_find\n        if a.is_multiple_of(2) {\n            return Some(a);\n        }\n    }\n    None\n}\n\nstruct Data {\n    name: String,\n    is_true: bool,\n}\nfn with_struct(arr: Vec<Data>) -> Option<Data> {\n    for el in arr {\n        //~^ manual_find\n        if el.name.len() == 10 {\n            return Some(el);\n        }\n    }\n    None\n}\n\nstruct Tuple(usize, usize);\nfn with_tuple_struct(arr: Vec<Tuple>) -> Option<usize> {\n    for Tuple(a, _) in arr {\n        //~^ manual_find\n        if a >= 3 {\n            return Some(a);\n        }\n    }\n    None\n}\n\nstruct A;\nimpl A {\n    fn should_keep(&self) -> bool {\n        true\n    }\n}\nfn with_method_call(arr: Vec<A>) -> Option<A> {\n    for el in arr {\n        //~^ manual_find\n        if el.should_keep() {\n            return Some(el);\n        }\n    }\n    None\n}\n\nfn with_closure(arr: Vec<u32>) -> Option<u32> {\n    let f = |el: u32| -> u32 { el + 10 };\n    for el in arr {\n        //~^ manual_find\n        if f(el) == 20 {\n            return Some(el);\n        }\n    }\n    None\n}\n\nfn with_closure2(arr: HashMap<String, i32>) -> Option<i32> {\n    let f = |el: i32| -> bool { el == 10 };\n    for &el in arr.values() {\n        //~^ manual_find\n        if f(el) {\n            return Some(el);\n        }\n    }\n    None\n}\n\nfn with_bool(arr: Vec<Data>) -> Option<Data> {\n    for el in arr {\n        //~^ manual_find\n        if el.is_true {\n            return Some(el);\n        }\n    }\n    None\n}\n\nfn with_side_effects(arr: Vec<u32>) -> Option<u32> {\n    for v in arr {\n        if v == 1 {\n            println!(\"side effect\");\n            return Some(v);\n        }\n    }\n    None\n}\n\nfn with_else(arr: Vec<u32>) -> Option<u32> {\n    for el in arr {\n        if el.is_multiple_of(2) {\n            return Some(el);\n        } else {\n            println!(\"{}\", el);\n        }\n    }\n    None\n}\n\nfn tuple_with_ref(v: [(u8, &u8); 3]) -> Option<u8> {\n    for (_, &x) in v {\n        //~^ manual_find\n        if x > 10 {\n            return Some(x);\n        }\n    }\n    None\n}\n\nfn ref_to_tuple_with_ref(v: &[(u8, &u8)]) -> Option<u8> {\n    for &(_, &x) in v {\n        //~^ manual_find\n        if x > 10 {\n            return Some(x);\n        }\n    }\n    None\n}\n\nfn explicit_ret(arr: Vec<i32>) -> Option<i32> {\n    for x in arr {\n        //~^ manual_find\n        if x >= 5 {\n            return Some(x);\n        }\n    }\n    return None;\n}\n\nfn plus_one(a: i32) -> Option<i32> {\n    Some(a + 1)\n}\nfn fn_instead_of_some(a: &[i32]) -> Option<i32> {\n    for &x in a {\n        if x == 1 {\n            return plus_one(x);\n        }\n    }\n    None\n}\n\nfn for_in_condition(a: &[i32], b: bool) -> Option<i32> {\n    if b {\n        for &x in a {\n            if x == 1 {\n                return Some(x);\n            }\n        }\n    }\n    None\n}\n\nfn intermediate_statements(a: &[i32]) -> Option<i32> {\n    for &x in a {\n        if x == 1 {\n            return Some(x);\n        }\n    }\n\n    println!(\"side effect\");\n\n    None\n}\n\nfn mixed_binding_modes(arr: Vec<(i32, String)>) -> Option<i32> {\n    for (x, mut s) in arr {\n        if x == 1 && s.as_mut_str().len() == 2 {\n            return Some(x);\n        }\n    }\n    None\n}\n\nfn as_closure() {\n    #[rustfmt::skip]\n    let f = |arr: Vec<i32>| -> Option<i32> {\n        for x in arr {\n        //~^ manual_find\n            if x < 1 {\n                return Some(x);\n            }\n        }\n        None\n    };\n}\n\nfn in_block(a: &[i32]) -> Option<i32> {\n    let should_be_none = {\n        for &x in a {\n            if x == 1 {\n                return Some(x);\n            }\n        }\n        None\n    };\n\n    assert!(should_be_none.is_none());\n\n    should_be_none\n}\n\n// Not handled yet\nfn mut_binding(v: Vec<String>) -> Option<String> {\n    for mut s in v {\n        if s.as_mut_str().len() > 1 {\n            return Some(s);\n        }\n    }\n    None\n}\n\nfn subpattern(v: Vec<[u32; 32]>) -> Option<[u32; 32]> {\n    for a @ [first, ..] in v {\n        if a[12] == first {\n            return Some(a);\n        }\n    }\n    None\n}\n\nfn two_bindings(v: Vec<(u8, u8)>) -> Option<u8> {\n    for (a, n) in v {\n        if a == n {\n            return Some(a);\n        }\n    }\n    None\n}\n\nfn main() {}\n\nmod issue14826 {\n    fn adjust_fixable(needle: &str) -> Option<&'static str> {\n        for candidate in &[\"foo\", \"bar\"] {\n            //~^ manual_find\n            if candidate.eq_ignore_ascii_case(needle) {\n                return Some(candidate);\n            }\n        }\n        None\n    }\n\n    fn adjust_unfixable(needle: &str) -> Option<*const str> {\n        for &candidate in &[\"foo\", \"bar\"] {\n            //~^ manual_find\n            if candidate.eq_ignore_ascii_case(needle) {\n                return Some(candidate);\n            }\n        }\n        None\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_find_fixable.stderr",
    "content": "error: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:10:5\n   |\nLL | /     for &v in ARRAY {\nLL | |\nLL | |         if v == n {\nLL | |             return Some(v);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `ARRAY.iter().find(|&&v| v == n).copied()`\n   |\n   = note: `-D clippy::manual-find` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_find)]`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:20:5\n   |\nLL | /     for (a, _) in arr {\nLL | |\nLL | |         if a.is_multiple_of(2) {\nLL | |             return Some(a);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a.is_multiple_of(2))`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:34:5\n   |\nLL | /     for el in arr {\nLL | |\nLL | |         if el.name.len() == 10 {\nLL | |             return Some(el);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.name.len() == 10)`\n   |\n   = note: you may need to dereference some variables\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:45:5\n   |\nLL | /     for Tuple(a, _) in arr {\nLL | |\nLL | |         if a >= 3 {\nLL | |             return Some(a);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `arr.into_iter().map(|Tuple(a, _)| a).find(|&a| a >= 3)`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:61:5\n   |\nLL | /     for el in arr {\nLL | |\nLL | |         if el.should_keep() {\nLL | |             return Some(el);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.should_keep())`\n   |\n   = note: you may need to dereference some variables\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:72:5\n   |\nLL | /     for el in arr {\nLL | |\nLL | |         if f(el) == 20 {\nLL | |             return Some(el);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `arr.into_iter().find(|&el| f(el) == 20)`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:83:5\n   |\nLL | /     for &el in arr.values() {\nLL | |\nLL | |         if f(el) {\nLL | |             return Some(el);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `arr.values().find(|&&el| f(el)).copied()`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:93:5\n   |\nLL | /     for el in arr {\nLL | |\nLL | |         if el.is_true {\nLL | |             return Some(el);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `arr.into_iter().find(|el| el.is_true)`\n   |\n   = note: you may need to dereference some variables\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:124:5\n   |\nLL | /     for (_, &x) in v {\nLL | |\nLL | |         if x > 10 {\nLL | |             return Some(x);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `v.into_iter().map(|(_, &x)| x).find(|&x| x > 10)`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:134:5\n   |\nLL | /     for &(_, &x) in v {\nLL | |\nLL | |         if x > 10 {\nLL | |             return Some(x);\n...  |\nLL | |     None\n   | |________^ help: replace with an iterator: `v.iter().map(|&(_, &x)| x).find(|&x| x > 10)`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:144:5\n   |\nLL | /     for x in arr {\nLL | |\nLL | |         if x >= 5 {\nLL | |             return Some(x);\n...  |\nLL | |     return None;\n   | |________________^ help: replace with an iterator: `arr.into_iter().find(|&x| x >= 5)`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:200:9\n   |\nLL | /         for x in arr {\nLL | |\nLL | |             if x < 1 {\nLL | |                 return Some(x);\n...  |\nLL | |         None\n   | |____________^ help: replace with an iterator: `arr.into_iter().find(|&x| x < 1)`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:257:9\n   |\nLL | /         for candidate in &[\"foo\", \"bar\"] {\nLL | |\nLL | |             if candidate.eq_ignore_ascii_case(needle) {\nLL | |                 return Some(candidate);\n...  |\nLL | |         None\n   | |____________^ help: replace with an iterator: `[\"foo\", \"bar\"].iter().find(|&candidate| candidate.eq_ignore_ascii_case(needle)).map(|v| v as _)`\n\nerror: manual implementation of `Iterator::find`\n  --> tests/ui/manual_find_fixable.rs:267:9\n   |\nLL | /         for &candidate in &[\"foo\", \"bar\"] {\nLL | |\nLL | |             if candidate.eq_ignore_ascii_case(needle) {\nLL | |                 return Some(candidate);\n...  |\nLL | |         None\n   | |____________^ help: replace with an iterator: `[\"foo\", \"bar\"].iter().find(|&&candidate| candidate.eq_ignore_ascii_case(needle)).copied().map(|v| v as _)`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_find_map.fixed",
    "content": "#![allow(dead_code)]\n#![warn(clippy::manual_find_map)]\n#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure\n#![allow(clippy::useless_vec)]\n#![allow(clippy::struct_field_names)]\n\nfn main() {\n    // is_some(), unwrap()\n    let _ = (0..).find_map(|a| to_opt(a));\n    //~^ manual_find_map\n\n    // ref pattern, expect()\n    let _ = (0..).find_map(|a| to_opt(a));\n    //~^ manual_find_map\n\n    // is_ok(), unwrap_or()\n    let _ = (0..).find_map(|a| to_res(a).ok());\n    //~^ manual_find_map\n\n    let _ = (1..5)\n        .find_map(|y| *to_ref(to_opt(y)));\n    let _ = (1..5)\n        .find_map(|y| *to_ref(to_opt(y)));\n\n    let _ = (1..5)\n        .find_map(|y| to_ref(to_res(y)).ok());\n    let _ = (1..5)\n        .find_map(|y| to_ref(to_res(y)).ok());\n}\n\n#[rustfmt::skip]\nfn simple_equal() {\n    iter::<Option<u8>>().find_map(|x| x);\n    //~^ manual_find_map\n    iter::<&Option<u8>>().find_map(|x| *x);\n    //~^ manual_find_map\n    iter::<&&Option<u8>>().find_map(|x| **x);\n    //~^ manual_find_map\n    iter::<Option<&u8>>().find_map(|x| x.cloned());\n    //~^ manual_find_map\n    iter::<&Option<&u8>>().find_map(|x| x.cloned());\n    //~^ manual_find_map\n    iter::<&Option<String>>().find_map(|x| x.as_deref());\n    //~^ manual_find_map\n    iter::<Option<&String>>().find_map(|y| to_ref(y).cloned());\n    //~^ manual_find_map\n\n    iter::<Result<u8, ()>>().find_map(|x| x.ok());\n    //~^ manual_find_map\n    iter::<&Result<u8, ()>>().find_map(|x| x.ok());\n    //~^ manual_find_map\n    iter::<&&Result<u8, ()>>().find_map(|x| x.ok());\n    //~^ manual_find_map\n    iter::<Result<&u8, ()>>().find_map(|x| x.cloned().ok());\n    //~^ manual_find_map\n    iter::<&Result<&u8, ()>>().find_map(|x| x.cloned().ok());\n    //~^ manual_find_map\n    iter::<&Result<String, ()>>().find_map(|x| x.as_deref().ok());\n    //~^ manual_find_map\n    iter::<Result<&String, ()>>().find_map(|y| to_ref(y).cloned().ok());\n    //~^ manual_find_map\n}\n\nfn no_lint() {\n    // no shared code\n    let _ = (0..).filter(|n| *n > 1).map(|n| n + 1);\n\n    // very close but different since filter() provides a reference\n    let _ = (0..).find(|n| to_opt(n).is_some()).map(|a| to_opt(a).unwrap());\n\n    // similar but different\n    let _ = (0..).find(|n| to_opt(n).is_some()).map(|n| to_res(n).unwrap());\n    let _ = (0..)\n        .find(|n| to_opt(n).map(|n| n + 1).is_some())\n        .map(|a| to_opt(a).unwrap());\n}\n\nfn iter<T>() -> impl Iterator<Item = T> {\n    std::iter::empty()\n}\n\nfn to_opt<T>(_: T) -> Option<T> {\n    unimplemented!()\n}\n\nfn to_res<T>(_: T) -> Result<T, ()> {\n    unimplemented!()\n}\n\nfn to_ref<'a, T>(_: T) -> &'a T {\n    unimplemented!()\n}\n\nstruct Issue8920<'a> {\n    option_field: Option<String>,\n    result_field: Result<String, ()>,\n    ref_field: Option<&'a usize>,\n}\n\nfn issue_8920() {\n    let mut vec = vec![Issue8920 {\n        option_field: Some(String::from(\"str\")),\n        result_field: Ok(String::from(\"str\")),\n        ref_field: Some(&1),\n    }];\n\n    let _ = vec\n        .iter()\n        .find_map(|f| f.option_field.clone());\n\n    let _ = vec\n        .iter()\n        .find_map(|f| f.ref_field.cloned());\n\n    let _ = vec\n        .iter()\n        .find_map(|f| f.ref_field.copied());\n\n    let _ = vec\n        .iter()\n        .find_map(|f| f.result_field.clone().ok());\n\n    let _ = vec\n        .iter()\n        .find_map(|f| f.result_field.as_ref().ok());\n\n    let _ = vec\n        .iter()\n        .find_map(|f| f.result_field.as_deref().ok());\n\n    let _ = vec\n        .iter_mut()\n        .find_map(|f| f.result_field.as_mut().ok());\n\n    let _ = vec\n        .iter_mut()\n        .find_map(|f| f.result_field.as_deref_mut().ok());\n\n    let _ = vec\n        .iter()\n        .find_map(|f| f.result_field.to_owned().ok());\n}\n"
  },
  {
    "path": "tests/ui/manual_find_map.rs",
    "content": "#![allow(dead_code)]\n#![warn(clippy::manual_find_map)]\n#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure\n#![allow(clippy::useless_vec)]\n#![allow(clippy::struct_field_names)]\n\nfn main() {\n    // is_some(), unwrap()\n    let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());\n    //~^ manual_find_map\n\n    // ref pattern, expect()\n    let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect(\"hi\"));\n    //~^ manual_find_map\n\n    // is_ok(), unwrap_or()\n    let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));\n    //~^ manual_find_map\n\n    let _ = (1..5)\n        .find(|&x| to_ref(to_opt(x)).is_some())\n        //~^ manual_find_map\n        .map(|y| to_ref(to_opt(y)).unwrap());\n    let _ = (1..5)\n        .find(|x| to_ref(to_opt(*x)).is_some())\n        //~^ manual_find_map\n        .map(|y| to_ref(to_opt(y)).unwrap());\n\n    let _ = (1..5)\n        .find(|&x| to_ref(to_res(x)).is_ok())\n        //~^ manual_find_map\n        .map(|y| to_ref(to_res(y)).unwrap());\n    let _ = (1..5)\n        .find(|x| to_ref(to_res(*x)).is_ok())\n        //~^ manual_find_map\n        .map(|y| to_ref(to_res(y)).unwrap());\n}\n\n#[rustfmt::skip]\nfn simple_equal() {\n    iter::<Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<&&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());\n    //~^ manual_find_map\n    iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());\n    //~^ manual_find_map\n    iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap());\n    //~^ manual_find_map\n    iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());\n    //~^ manual_find_map\n\n    iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n    //~^ manual_find_map\n    iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());\n    //~^ manual_find_map\n    iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());\n    //~^ manual_find_map\n    iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap());\n    //~^ manual_find_map\n    iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());\n    //~^ manual_find_map\n}\n\nfn no_lint() {\n    // no shared code\n    let _ = (0..).filter(|n| *n > 1).map(|n| n + 1);\n\n    // very close but different since filter() provides a reference\n    let _ = (0..).find(|n| to_opt(n).is_some()).map(|a| to_opt(a).unwrap());\n\n    // similar but different\n    let _ = (0..).find(|n| to_opt(n).is_some()).map(|n| to_res(n).unwrap());\n    let _ = (0..)\n        .find(|n| to_opt(n).map(|n| n + 1).is_some())\n        .map(|a| to_opt(a).unwrap());\n}\n\nfn iter<T>() -> impl Iterator<Item = T> {\n    std::iter::empty()\n}\n\nfn to_opt<T>(_: T) -> Option<T> {\n    unimplemented!()\n}\n\nfn to_res<T>(_: T) -> Result<T, ()> {\n    unimplemented!()\n}\n\nfn to_ref<'a, T>(_: T) -> &'a T {\n    unimplemented!()\n}\n\nstruct Issue8920<'a> {\n    option_field: Option<String>,\n    result_field: Result<String, ()>,\n    ref_field: Option<&'a usize>,\n}\n\nfn issue_8920() {\n    let mut vec = vec![Issue8920 {\n        option_field: Some(String::from(\"str\")),\n        result_field: Ok(String::from(\"str\")),\n        ref_field: Some(&1),\n    }];\n\n    let _ = vec\n        .iter()\n        .find(|f| f.option_field.is_some())\n        //~^ manual_find_map\n        .map(|f| f.option_field.clone().unwrap());\n\n    let _ = vec\n        .iter()\n        .find(|f| f.ref_field.is_some())\n        //~^ manual_find_map\n        .map(|f| f.ref_field.cloned().unwrap());\n\n    let _ = vec\n        .iter()\n        .find(|f| f.ref_field.is_some())\n        //~^ manual_find_map\n        .map(|f| f.ref_field.copied().unwrap());\n\n    let _ = vec\n        .iter()\n        .find(|f| f.result_field.is_ok())\n        //~^ manual_find_map\n        .map(|f| f.result_field.clone().unwrap());\n\n    let _ = vec\n        .iter()\n        .find(|f| f.result_field.is_ok())\n        //~^ manual_find_map\n        .map(|f| f.result_field.as_ref().unwrap());\n\n    let _ = vec\n        .iter()\n        .find(|f| f.result_field.is_ok())\n        //~^ manual_find_map\n        .map(|f| f.result_field.as_deref().unwrap());\n\n    let _ = vec\n        .iter_mut()\n        .find(|f| f.result_field.is_ok())\n        //~^ manual_find_map\n        .map(|f| f.result_field.as_mut().unwrap());\n\n    let _ = vec\n        .iter_mut()\n        .find(|f| f.result_field.is_ok())\n        //~^ manual_find_map\n        .map(|f| f.result_field.as_deref_mut().unwrap());\n\n    let _ = vec\n        .iter()\n        .find(|f| f.result_field.is_ok())\n        //~^ manual_find_map\n        .map(|f| f.result_field.to_owned().unwrap());\n}\n"
  },
  {
    "path": "tests/ui/manual_find_map.stderr",
    "content": "error: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:9:19\n   |\nLL |     let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:9:28\n   |\nLL |     let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());\n   |                            ^^^^^^^^^^\n   = note: `-D clippy::manual-find-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:13:19\n   |\nLL |     let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect(\"hi\"));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:13:29\n   |\nLL |     let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect(\"hi\"));\n   |                             ^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:17:19\n   |\nLL |     let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_res(a).ok())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:17:29\n   |\nLL |     let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));\n   |                             ^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:21:10\n   |\nLL |           .find(|&x| to_ref(to_opt(x)).is_some())\n   |  __________^\nLL | |\nLL | |         .map(|y| to_ref(to_opt(y)).unwrap());\n   | |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:21:20\n   |\nLL |         .find(|&x| to_ref(to_opt(x)).is_some())\n   |                    ^^^^^^^^^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:25:10\n   |\nLL |           .find(|x| to_ref(to_opt(*x)).is_some())\n   |  __________^\nLL | |\nLL | |         .map(|y| to_ref(to_opt(y)).unwrap());\n   | |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:25:19\n   |\nLL |         .find(|x| to_ref(to_opt(*x)).is_some())\n   |                   ^^^^^^^^^^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:30:10\n   |\nLL |           .find(|&x| to_ref(to_res(x)).is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|y| to_ref(to_res(y)).unwrap());\n   | |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:30:20\n   |\nLL |         .find(|&x| to_ref(to_res(x)).is_ok())\n   |                    ^^^^^^^^^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:34:10\n   |\nLL |           .find(|x| to_ref(to_res(*x)).is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|y| to_ref(to_res(y)).unwrap());\n   | |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:34:19\n   |\nLL |         .find(|x| to_ref(to_res(*x)).is_ok())\n   |                   ^^^^^^^^^^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:41:26\n   |\nLL |     iter::<Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x)`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:43:27\n   |\nLL |     iter::<&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| *x)`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:45:28\n   |\nLL |     iter::<&&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| **x)`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:47:27\n   |\nLL |     iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:49:28\n   |\nLL |     iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:51:31\n   |\nLL |     iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:53:31\n   |\nLL |     iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:53:41\n   |\nLL |     iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());\n   |                                         ^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:56:30\n   |\nLL |     iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:58:31\n   |\nLL |     iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:60:32\n   |\nLL |     iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:62:31\n   |\nLL |     iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:64:32\n   |\nLL |     iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:66:35\n   |\nLL |     iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap());\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:68:35\n   |\nLL |     iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())`\n   |\nnote: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once\n  --> tests/ui/manual_find_map.rs:68:45\n   |\nLL |     iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());\n   |                                             ^^^^^^^^^\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:117:10\n   |\nLL |           .find(|f| f.option_field.is_some())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.option_field.clone().unwrap());\n   | |_________________________________________________^ help: try: `find_map(|f| f.option_field.clone())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:123:10\n   |\nLL |           .find(|f| f.ref_field.is_some())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.ref_field.cloned().unwrap());\n   | |_______________________________________________^ help: try: `find_map(|f| f.ref_field.cloned())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:129:10\n   |\nLL |           .find(|f| f.ref_field.is_some())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.ref_field.copied().unwrap());\n   | |_______________________________________________^ help: try: `find_map(|f| f.ref_field.copied())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:135:10\n   |\nLL |           .find(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.clone().unwrap());\n   | |_________________________________________________^ help: try: `find_map(|f| f.result_field.clone().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:141:10\n   |\nLL |           .find(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.as_ref().unwrap());\n   | |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_ref().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:147:10\n   |\nLL |           .find(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.as_deref().unwrap());\n   | |____________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:153:10\n   |\nLL |           .find(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.as_mut().unwrap());\n   | |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_mut().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:159:10\n   |\nLL |           .find(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.as_deref_mut().unwrap());\n   | |________________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref_mut().ok())`\n\nerror: `find(..).map(..)` can be simplified as `find_map(..)`\n  --> tests/ui/manual_find_map.rs:165:10\n   |\nLL |           .find(|f| f.result_field.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|f| f.result_field.to_owned().unwrap());\n   | |____________________________________________________^ help: try: `find_map(|f| f.result_field.to_owned().ok())`\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_flatten.fixed",
    "content": "#![warn(clippy::manual_flatten)]\n#![allow(clippy::useless_vec, clippy::uninlined_format_args)]\n\nfn main() {\n    // Test for loop over implicitly adjusted `Iterator` with `if let` expression\n    let x = vec![Some(1), Some(2), Some(3)];\n    for y in x.into_iter().flatten() {\n        println!(\"{}\", y);\n    }\n\n    // Test for loop over implicitly adjusted `Iterator` with `if let` statement\n    let y: Vec<Result<i32, i32>> = vec![];\n    for n in y.clone().into_iter().flatten() {\n        println!(\"{}\", n);\n    }\n\n    // Test for loop over by reference\n    for n in y.iter().flatten() {\n        println!(\"{}\", n);\n    }\n\n    // Test for loop over an implicit reference\n    let z = &y;\n    for n in z.iter().flatten() {\n        println!(\"{}\", n);\n    }\n\n    // Test for loop over `Iterator` with `if let` expression\n    let z = vec![Some(1), Some(2), Some(3)];\n    let z = z.iter();\n    for m in z.flatten() {\n        println!(\"{}\", m);\n    }\n\n    // Using the `None` variant should not trigger the lint\n    // Note: for an autofixable suggestion, the binding in the for loop has to take the\n    // name of the binding in the `if let`\n    let z = vec![Some(1), Some(2), Some(3)];\n    for n in z {\n        if n.is_none() {\n            println!(\"Nada.\");\n        }\n    }\n\n    // Using the `Err` variant should not trigger the lint\n    for n in y.clone() {\n        if let Err(e) = n {\n            println!(\"Oops: {}!\", e);\n        }\n    }\n\n    // Having an else clause should not trigger the lint\n    for n in y.clone() {\n        if let Ok(n) = n {\n            println!(\"{}\", n);\n        } else {\n            println!(\"Oops!\");\n        }\n    }\n\n    let vec_of_ref = vec![&Some(1)];\n    for n in vec_of_ref.iter().copied().flatten() {\n        println!(\"{:?}\", n);\n    }\n\n    let vec_of_ref = &vec_of_ref;\n    for n in vec_of_ref.iter().copied().flatten() {\n        println!(\"{:?}\", n);\n    }\n\n    let slice_of_ref = &[&Some(1)];\n    for n in slice_of_ref.iter().copied().flatten() {\n        println!(\"{:?}\", n);\n    }\n\n    struct Test {\n        a: usize,\n    }\n\n    let mut vec_of_struct = [Some(Test { a: 1 }), None];\n\n    // Usage of `if let` expression should not trigger lint\n    for n in vec_of_struct.iter_mut() {\n        if let Some(z) = n {\n            *n = None;\n        }\n    }\n\n    // Using manual flatten should not trigger the lint\n    for n in vec![Some(1), Some(2), Some(3)].iter().flatten() {\n        println!(\"{}\", n);\n    }\n\n    // Using nested `Some` pattern should not trigger the lint\n    for n in vec![Some((1, Some(2)))] {\n        if let Some((_, Some(n))) = n {\n            println!(\"{}\", n);\n        }\n    }\n\n    macro_rules! inner {\n        ($id:ident / $new:pat => $action:expr) => {\n            if let Some($new) = $id {\n                $action;\n            }\n        };\n    }\n\n    // Usage of `if let` expression with macro should not trigger lint\n    for ab in [Some((1, 2)), Some((3, 4))] {\n        inner!(ab / (c, d) => println!(\"{c}-{d}\"));\n    }\n\n    macro_rules! args {\n        ($($arg:expr),*) => {\n            vec![$(Some($arg)),*]\n        };\n    }\n\n    // Usage of `if let` expression with macro should not trigger lint\n    for n in args!(1, 2, 3) {\n        if let Some(n) = n {\n            println!(\"{:?}\", n);\n        }\n    }\n\n    // This should trigger the lint, but the applicability is `MaybeIncorrect`\n    let z = vec![Some(1), Some(2), Some(3)];\n    for n in z.into_iter().flatten() {\n        println!(\"{:?}\", n);\n    }\n\n    run_unformatted_tests();\n}\n\n#[rustfmt::skip]\nfn run_unformatted_tests() {\n    // Skip rustfmt here on purpose so the suggestion does not fit in one line\n    for n in vec![\n    //~^ manual_flatten\n\n        Some(1),\n        Some(2),\n        Some(3)\n    ].iter().flatten() {\n        println!(\"{:?}\", n);\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_flatten.rs",
    "content": "#![warn(clippy::manual_flatten)]\n#![allow(clippy::useless_vec, clippy::uninlined_format_args)]\n\nfn main() {\n    // Test for loop over implicitly adjusted `Iterator` with `if let` expression\n    let x = vec![Some(1), Some(2), Some(3)];\n    for n in x {\n        //~^ manual_flatten\n\n        if let Some(y) = n {\n            println!(\"{}\", y);\n        }\n    }\n\n    // Test for loop over implicitly adjusted `Iterator` with `if let` statement\n    let y: Vec<Result<i32, i32>> = vec![];\n    for n in y.clone() {\n        //~^ manual_flatten\n\n        if let Ok(n) = n {\n            println!(\"{}\", n);\n        };\n    }\n\n    // Test for loop over by reference\n    for n in &y {\n        //~^ manual_flatten\n\n        if let Ok(n) = n {\n            println!(\"{}\", n);\n        }\n    }\n\n    // Test for loop over an implicit reference\n    let z = &y;\n    for n in z {\n        //~^ manual_flatten\n\n        if let Ok(n) = n {\n            println!(\"{}\", n);\n        }\n    }\n\n    // Test for loop over `Iterator` with `if let` expression\n    let z = vec![Some(1), Some(2), Some(3)];\n    let z = z.iter();\n    for n in z {\n        //~^ manual_flatten\n\n        if let Some(m) = n {\n            println!(\"{}\", m);\n        }\n    }\n\n    // Using the `None` variant should not trigger the lint\n    // Note: for an autofixable suggestion, the binding in the for loop has to take the\n    // name of the binding in the `if let`\n    let z = vec![Some(1), Some(2), Some(3)];\n    for n in z {\n        if n.is_none() {\n            println!(\"Nada.\");\n        }\n    }\n\n    // Using the `Err` variant should not trigger the lint\n    for n in y.clone() {\n        if let Err(e) = n {\n            println!(\"Oops: {}!\", e);\n        }\n    }\n\n    // Having an else clause should not trigger the lint\n    for n in y.clone() {\n        if let Ok(n) = n {\n            println!(\"{}\", n);\n        } else {\n            println!(\"Oops!\");\n        }\n    }\n\n    let vec_of_ref = vec![&Some(1)];\n    for n in &vec_of_ref {\n        //~^ manual_flatten\n\n        if let Some(n) = n {\n            println!(\"{:?}\", n);\n        }\n    }\n\n    let vec_of_ref = &vec_of_ref;\n    for n in vec_of_ref {\n        //~^ manual_flatten\n\n        if let Some(n) = n {\n            println!(\"{:?}\", n);\n        }\n    }\n\n    let slice_of_ref = &[&Some(1)];\n    for n in slice_of_ref {\n        //~^ manual_flatten\n\n        if let Some(n) = n {\n            println!(\"{:?}\", n);\n        }\n    }\n\n    struct Test {\n        a: usize,\n    }\n\n    let mut vec_of_struct = [Some(Test { a: 1 }), None];\n\n    // Usage of `if let` expression should not trigger lint\n    for n in vec_of_struct.iter_mut() {\n        if let Some(z) = n {\n            *n = None;\n        }\n    }\n\n    // Using manual flatten should not trigger the lint\n    for n in vec![Some(1), Some(2), Some(3)].iter().flatten() {\n        println!(\"{}\", n);\n    }\n\n    // Using nested `Some` pattern should not trigger the lint\n    for n in vec![Some((1, Some(2)))] {\n        if let Some((_, Some(n))) = n {\n            println!(\"{}\", n);\n        }\n    }\n\n    macro_rules! inner {\n        ($id:ident / $new:pat => $action:expr) => {\n            if let Some($new) = $id {\n                $action;\n            }\n        };\n    }\n\n    // Usage of `if let` expression with macro should not trigger lint\n    for ab in [Some((1, 2)), Some((3, 4))] {\n        inner!(ab / (c, d) => println!(\"{c}-{d}\"));\n    }\n\n    macro_rules! args {\n        ($($arg:expr),*) => {\n            vec![$(Some($arg)),*]\n        };\n    }\n\n    // Usage of `if let` expression with macro should not trigger lint\n    for n in args!(1, 2, 3) {\n        if let Some(n) = n {\n            println!(\"{:?}\", n);\n        }\n    }\n\n    // This should trigger the lint, but the applicability is `MaybeIncorrect`\n    let z = vec![Some(1), Some(2), Some(3)];\n    for n in z {\n        //~^ manual_flatten\n\n        if let Some(n) = n {\n            println!(\"{:?}\", n);\n        }\n        // foo\n    }\n\n    run_unformatted_tests();\n}\n\n#[rustfmt::skip]\nfn run_unformatted_tests() {\n    // Skip rustfmt here on purpose so the suggestion does not fit in one line\n    for n in vec![\n    //~^ manual_flatten\n\n        Some(1),\n        Some(2),\n        Some(3)\n    ].iter() {\n        if let Some(n) = n {\n            println!(\"{:?}\", n);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_flatten.stderr",
    "content": "error: unnecessary `if let` since only the `Some` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:7:5\n   |\nLL | /     for n in x {\nLL | |\nLL | |\nLL | |         if let Some(y) = n {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:10:9\n   |\nLL | /         if let Some(y) = n {\nLL | |             println!(\"{}\", y);\nLL | |         }\n   | |_________^\n   = note: `-D clippy::manual-flatten` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_flatten)]`\nhelp: try\n   |\nLL ~     for y in x.into_iter().flatten() {\nLL +         println!(\"{}\", y);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Ok` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:17:5\n   |\nLL | /     for n in y.clone() {\nLL | |\nLL | |\nLL | |         if let Ok(n) = n {\nLL | |             println!(\"{}\", n);\nLL | |         };\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:20:9\n   |\nLL | /         if let Ok(n) = n {\nLL | |             println!(\"{}\", n);\nLL | |         };\n   | |_________^\nhelp: try\n   |\nLL ~     for n in y.clone().into_iter().flatten() {\nLL +         println!(\"{}\", n);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Ok` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:26:5\n   |\nLL | /     for n in &y {\nLL | |\nLL | |\nLL | |         if let Ok(n) = n {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:29:9\n   |\nLL | /         if let Ok(n) = n {\nLL | |             println!(\"{}\", n);\nLL | |         }\n   | |_________^\nhelp: try\n   |\nLL ~     for n in y.iter().flatten() {\nLL +         println!(\"{}\", n);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Ok` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:36:5\n   |\nLL | /     for n in z {\nLL | |\nLL | |\nLL | |         if let Ok(n) = n {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:39:9\n   |\nLL | /         if let Ok(n) = n {\nLL | |             println!(\"{}\", n);\nLL | |         }\n   | |_________^\nhelp: try\n   |\nLL ~     for n in z.iter().flatten() {\nLL +         println!(\"{}\", n);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Some` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:47:5\n   |\nLL | /     for n in z {\nLL | |\nLL | |\nLL | |         if let Some(m) = n {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:50:9\n   |\nLL | /         if let Some(m) = n {\nLL | |             println!(\"{}\", m);\nLL | |         }\n   | |_________^\nhelp: try\n   |\nLL ~     for m in z.flatten() {\nLL +         println!(\"{}\", m);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Some` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:82:5\n   |\nLL | /     for n in &vec_of_ref {\nLL | |\nLL | |\nLL | |         if let Some(n) = n {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:85:9\n   |\nLL | /         if let Some(n) = n {\nLL | |             println!(\"{:?}\", n);\nLL | |         }\n   | |_________^\nhelp: try\n   |\nLL ~     for n in vec_of_ref.iter().copied().flatten() {\nLL +         println!(\"{:?}\", n);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Some` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:91:5\n   |\nLL | /     for n in vec_of_ref {\nLL | |\nLL | |\nLL | |         if let Some(n) = n {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:94:9\n   |\nLL | /         if let Some(n) = n {\nLL | |             println!(\"{:?}\", n);\nLL | |         }\n   | |_________^\nhelp: try\n   |\nLL ~     for n in vec_of_ref.iter().copied().flatten() {\nLL +         println!(\"{:?}\", n);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Some` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:100:5\n   |\nLL | /     for n in slice_of_ref {\nLL | |\nLL | |\nLL | |         if let Some(n) = n {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:103:9\n   |\nLL | /         if let Some(n) = n {\nLL | |             println!(\"{:?}\", n);\nLL | |         }\n   | |_________^\nhelp: try\n   |\nLL ~     for n in slice_of_ref.iter().copied().flatten() {\nLL +         println!(\"{:?}\", n);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Some` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:161:5\n   |\nLL | /     for n in z {\nLL | |\nLL | |\nLL | |         if let Some(n) = n {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:164:9\n   |\nLL | /         if let Some(n) = n {\nLL | |             println!(\"{:?}\", n);\nLL | |         }\n   | |_________^\nhelp: try\n   |\nLL ~     for n in z.into_iter().flatten() {\nLL +         println!(\"{:?}\", n);\nLL +     }\n   |\n\nerror: unnecessary `if let` since only the `Some` variant of the iterator element is used\n  --> tests/ui/manual_flatten.rs:176:5\n   |\nLL | /     for n in vec![\nLL | |\nLL | |\nLL | |         Some(1),\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try `.flatten()` and remove the `if let` statement in the for loop\n  --> tests/ui/manual_flatten.rs:183:9\n   |\nLL | /         if let Some(n) = n {\nLL | |             println!(\"{:?}\", n);\nLL | |         }\n   | |_________^\nhelp: try\n   |\nLL |     for n in vec![\n...\nLL |         Some(3)\nLL ~     ].iter().flatten() {\nLL +         println!(\"{:?}\", n);\nLL +     }\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_float_methods.rs",
    "content": "//@no-rustfix: overlapping suggestions\n//@aux-build:proc_macros.rs\n#![allow(clippy::needless_ifs, unused)]\n#![warn(clippy::manual_is_infinite, clippy::manual_is_finite)]\n\n// FIXME(f16_f128): add tests for these types once constants are available\n\n#[macro_use]\nextern crate proc_macros;\n\nfn fn_test() -> f64 {\n    f64::NEG_INFINITY\n}\n\nfn fn_test_not_inf() -> f64 {\n    112.0\n}\n\nfn main() {\n    let x = 1.0f32;\n    if x == f32::INFINITY || x == f32::NEG_INFINITY {}\n    //~^ manual_is_infinite\n    if x != f32::INFINITY && x != f32::NEG_INFINITY {}\n    //~^ manual_is_finite\n    let x = 1.0f64;\n    if x == f64::INFINITY || x == f64::NEG_INFINITY {}\n    //~^ manual_is_infinite\n    if x != f64::INFINITY && x != f64::NEG_INFINITY {}\n    //~^ manual_is_finite\n    // Don't lint\n    if x.is_infinite() {}\n    if x.is_finite() {}\n    if x.abs() < f64::INFINITY {}\n    if f64::INFINITY > x.abs() {}\n    if f64::abs(x) < f64::INFINITY {}\n    if f64::INFINITY > f64::abs(x) {}\n    // Is not evaluated by `clippy_utils::constant`\n    if x != f64::INFINITY && x != fn_test() {}\n    // Not -inf\n    if x != f64::INFINITY && x != fn_test_not_inf() {}\n    const {\n        let x = 1.0f64;\n        if x == f64::INFINITY || x == f64::NEG_INFINITY {}\n        //~^ manual_is_infinite\n    }\n    const X: f64 = 1.0f64;\n    if const { X == f64::INFINITY || X == f64::NEG_INFINITY } {}\n    if const { X != f64::INFINITY && X != f64::NEG_INFINITY } {}\n    external! {\n        let x = 1.0;\n        if x == f32::INFINITY || x == f32::NEG_INFINITY {}\n        if x != f32::INFINITY && x != f32::NEG_INFINITY {}\n    }\n    with_span! {\n        span\n        let x = 1.0;\n        if x == f32::INFINITY || x == f32::NEG_INFINITY {}\n        if x != f32::INFINITY && x != f32::NEG_INFINITY {}\n    }\n\n    {\n        let x = 1.0f32;\n        const X: f32 = f32::INFINITY;\n        const Y: f32 = f32::NEG_INFINITY;\n        if x == X || x == Y {}\n        if x != X && x != Y {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_float_methods.stderr",
    "content": "error: manually checking if a float is infinite\n  --> tests/ui/manual_float_methods.rs:21:8\n   |\nLL |     if x == f32::INFINITY || x == f32::NEG_INFINITY {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`\n   |\n   = note: `-D clippy::manual-is-infinite` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_is_infinite)]`\n\nerror: manually checking if a float is finite\n  --> tests/ui/manual_float_methods.rs:23:8\n   |\nLL |     if x != f32::INFINITY && x != f32::NEG_INFINITY {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::manual-is-finite` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_is_finite)]`\nhelp: use the dedicated method instead\n   |\nLL -     if x != f32::INFINITY && x != f32::NEG_INFINITY {}\nLL +     if x.is_finite() {}\n   |\nhelp: this will alter how it handles NaN; if that is a problem, use instead\n   |\nLL -     if x != f32::INFINITY && x != f32::NEG_INFINITY {}\nLL +     if x.is_finite() || x.is_nan() {}\n   |\nhelp: or, for conciseness\n   |\nLL -     if x != f32::INFINITY && x != f32::NEG_INFINITY {}\nLL +     if !x.is_infinite() {}\n   |\n\nerror: manually checking if a float is infinite\n  --> tests/ui/manual_float_methods.rs:26:8\n   |\nLL |     if x == f64::INFINITY || x == f64::NEG_INFINITY {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`\n\nerror: manually checking if a float is finite\n  --> tests/ui/manual_float_methods.rs:28:8\n   |\nLL |     if x != f64::INFINITY && x != f64::NEG_INFINITY {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use the dedicated method instead\n   |\nLL -     if x != f64::INFINITY && x != f64::NEG_INFINITY {}\nLL +     if x.is_finite() {}\n   |\nhelp: this will alter how it handles NaN; if that is a problem, use instead\n   |\nLL -     if x != f64::INFINITY && x != f64::NEG_INFINITY {}\nLL +     if x.is_finite() || x.is_nan() {}\n   |\nhelp: or, for conciseness\n   |\nLL -     if x != f64::INFINITY && x != f64::NEG_INFINITY {}\nLL +     if !x.is_infinite() {}\n   |\n\nerror: manually checking if a float is infinite\n  --> tests/ui/manual_float_methods.rs:43:12\n   |\nLL |         if x == f64::INFINITY || x == f64::NEG_INFINITY {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the dedicated method instead: `x.is_infinite()`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_hash_one.fixed",
    "content": "#![warn(clippy::manual_hash_one)]\n#![allow(clippy::needless_borrows_for_generic_args)]\n\nuse std::hash::{BuildHasher, Hash, Hasher};\n\nfn returned(b: impl BuildHasher) -> u64 {\n    \n    \n    b.hash_one(&true)\n    //~^ manual_hash_one\n}\n\nfn unsized_receiver(b: impl BuildHasher, s: &str) {\n    \n    \n    let _ = b.hash_one(&s[4..10]);\n    //~^ manual_hash_one\n}\n\nfn owned_value(b: impl BuildHasher, v: Vec<u32>) -> Vec<u32> {\n    \n    \n    let _ = b.hash_one(&v);\n    //~^ manual_hash_one\n    v\n}\n\nfn reused_hasher(b: impl BuildHasher) {\n    let mut hasher = b.build_hasher();\n    true.hash(&mut hasher);\n    let _ = hasher.finish();\n    let _ = hasher.finish();\n}\n\nfn reused_hasher_in_return(b: impl BuildHasher) -> u64 {\n    let mut hasher = b.build_hasher();\n    true.hash(&mut hasher);\n    let _ = hasher.finish();\n    hasher.finish()\n}\n\nfn no_hash(b: impl BuildHasher) {\n    let mut hasher = b.build_hasher();\n    let _ = hasher.finish();\n}\n\nfn hash_twice(b: impl BuildHasher) {\n    let mut hasher = b.build_hasher();\n    true.hash(&mut hasher);\n    true.hash(&mut hasher);\n    let _ = hasher.finish();\n}\n\nfn other_hasher(b: impl BuildHasher) {\n    let mut other_hasher = b.build_hasher();\n\n    let mut hasher = b.build_hasher();\n    true.hash(&mut other_hasher);\n    let _ = hasher.finish();\n}\n\nfn finish_then_hash(b: impl BuildHasher) {\n    let mut hasher = b.build_hasher();\n    let _ = hasher.finish();\n    true.hash(&mut hasher);\n}\n\nfn in_macro(b: impl BuildHasher) {\n    macro_rules! m {\n        ($b:expr) => {{\n            let mut hasher = $b.build_hasher();\n            true.hash(&mut hasher);\n            let _ = hasher.finish();\n        }};\n    }\n\n    m!(b);\n}\n\n#[clippy::msrv = \"1.70\"]\nfn msrv_1_70(b: impl BuildHasher, v: impl Hash) {\n    let mut hasher = b.build_hasher();\n    v.hash(&mut hasher);\n    let _ = hasher.finish();\n}\n\n#[clippy::msrv = \"1.71\"]\nfn msrv_1_71(b: impl BuildHasher, v: impl Hash) {\n    \n    \n    let _ = b.hash_one(&v);\n    //~^ manual_hash_one\n}\n"
  },
  {
    "path": "tests/ui/manual_hash_one.rs",
    "content": "#![warn(clippy::manual_hash_one)]\n#![allow(clippy::needless_borrows_for_generic_args)]\n\nuse std::hash::{BuildHasher, Hash, Hasher};\n\nfn returned(b: impl BuildHasher) -> u64 {\n    let mut hasher = b.build_hasher();\n    true.hash(&mut hasher);\n    hasher.finish()\n    //~^ manual_hash_one\n}\n\nfn unsized_receiver(b: impl BuildHasher, s: &str) {\n    let mut hasher = b.build_hasher();\n    s[4..10].hash(&mut hasher);\n    let _ = hasher.finish();\n    //~^ manual_hash_one\n}\n\nfn owned_value(b: impl BuildHasher, v: Vec<u32>) -> Vec<u32> {\n    let mut hasher = b.build_hasher();\n    v.hash(&mut hasher);\n    let _ = hasher.finish();\n    //~^ manual_hash_one\n    v\n}\n\nfn reused_hasher(b: impl BuildHasher) {\n    let mut hasher = b.build_hasher();\n    true.hash(&mut hasher);\n    let _ = hasher.finish();\n    let _ = hasher.finish();\n}\n\nfn reused_hasher_in_return(b: impl BuildHasher) -> u64 {\n    let mut hasher = b.build_hasher();\n    true.hash(&mut hasher);\n    let _ = hasher.finish();\n    hasher.finish()\n}\n\nfn no_hash(b: impl BuildHasher) {\n    let mut hasher = b.build_hasher();\n    let _ = hasher.finish();\n}\n\nfn hash_twice(b: impl BuildHasher) {\n    let mut hasher = b.build_hasher();\n    true.hash(&mut hasher);\n    true.hash(&mut hasher);\n    let _ = hasher.finish();\n}\n\nfn other_hasher(b: impl BuildHasher) {\n    let mut other_hasher = b.build_hasher();\n\n    let mut hasher = b.build_hasher();\n    true.hash(&mut other_hasher);\n    let _ = hasher.finish();\n}\n\nfn finish_then_hash(b: impl BuildHasher) {\n    let mut hasher = b.build_hasher();\n    let _ = hasher.finish();\n    true.hash(&mut hasher);\n}\n\nfn in_macro(b: impl BuildHasher) {\n    macro_rules! m {\n        ($b:expr) => {{\n            let mut hasher = $b.build_hasher();\n            true.hash(&mut hasher);\n            let _ = hasher.finish();\n        }};\n    }\n\n    m!(b);\n}\n\n#[clippy::msrv = \"1.70\"]\nfn msrv_1_70(b: impl BuildHasher, v: impl Hash) {\n    let mut hasher = b.build_hasher();\n    v.hash(&mut hasher);\n    let _ = hasher.finish();\n}\n\n#[clippy::msrv = \"1.71\"]\nfn msrv_1_71(b: impl BuildHasher, v: impl Hash) {\n    let mut hasher = b.build_hasher();\n    v.hash(&mut hasher);\n    let _ = hasher.finish();\n    //~^ manual_hash_one\n}\n"
  },
  {
    "path": "tests/ui/manual_hash_one.stderr",
    "content": "error: manual implementation of `BuildHasher::hash_one`\n  --> tests/ui/manual_hash_one.rs:9:5\n   |\nLL |     hasher.finish()\n   |     ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::manual-hash-one` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_hash_one)]`\nhelp: try\n   |\nLL ~     \nLL ~     \nLL ~     b.hash_one(&true)\n   |\n\nerror: manual implementation of `BuildHasher::hash_one`\n  --> tests/ui/manual_hash_one.rs:16:13\n   |\nLL |     let _ = hasher.finish();\n   |             ^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~     \nLL ~     \nLL ~     let _ = b.hash_one(&s[4..10]);\n   |\n\nerror: manual implementation of `BuildHasher::hash_one`\n  --> tests/ui/manual_hash_one.rs:23:13\n   |\nLL |     let _ = hasher.finish();\n   |             ^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~     \nLL ~     \nLL ~     let _ = b.hash_one(&v);\n   |\n\nerror: manual implementation of `BuildHasher::hash_one`\n  --> tests/ui/manual_hash_one.rs:91:13\n   |\nLL |     let _ = hasher.finish();\n   |             ^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~     \nLL ~     \nLL ~     let _ = b.hash_one(&v);\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_ignore_case_cmp.fixed",
    "content": "#![warn(clippy::manual_ignore_case_cmp)]\n#![allow(\n    clippy::deref_addrof,\n    clippy::op_ref,\n    clippy::ptr_arg,\n    clippy::short_circuit_statement,\n    clippy::unnecessary_operation\n)]\n\nuse std::ffi::{OsStr, OsString};\n\nfn main() {}\n\nfn variants(a: &str, b: &str) {\n    if a.eq_ignore_ascii_case(b) {\n        //~^ manual_ignore_case_cmp\n        return;\n    }\n    if a.eq_ignore_ascii_case(b) {\n        //~^ manual_ignore_case_cmp\n        return;\n    }\n    let r = a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    let r = r || a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    r && a.eq_ignore_ascii_case(&b.to_uppercase());\n    //~^ manual_ignore_case_cmp\n    // !=\n    if !a.eq_ignore_ascii_case(b) {\n        //~^ manual_ignore_case_cmp\n        return;\n    }\n    if !a.eq_ignore_ascii_case(b) {\n        //~^ manual_ignore_case_cmp\n        return;\n    }\n    let r = !a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    let r = r || !a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    r && !a.eq_ignore_ascii_case(&b.to_uppercase());\n    //~^ manual_ignore_case_cmp\n}\n\nfn unsupported(a: char, b: char) {\n    // TODO:: these are rare, and might not be worth supporting\n    a.to_ascii_lowercase() == char::to_ascii_lowercase(&b);\n    char::to_ascii_lowercase(&a) == b.to_ascii_lowercase();\n    char::to_ascii_lowercase(&a) == char::to_ascii_lowercase(&b);\n}\n\nfn char(a: char, b: char) {\n    a.eq_ignore_ascii_case(&b);\n    //~^ manual_ignore_case_cmp\n    a.to_ascii_lowercase() == *&b.to_ascii_lowercase();\n    *&a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    a.eq_ignore_ascii_case(&'a');\n    //~^ manual_ignore_case_cmp\n    'a'.eq_ignore_ascii_case(&b);\n    //~^ manual_ignore_case_cmp\n}\nfn u8(a: u8, b: u8) {\n    a.eq_ignore_ascii_case(&b);\n    //~^ manual_ignore_case_cmp\n    a.eq_ignore_ascii_case(&b'a');\n    //~^ manual_ignore_case_cmp\n    b'a'.eq_ignore_ascii_case(&b);\n    //~^ manual_ignore_case_cmp\n}\nfn ref_str(a: &str, b: &str) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    a.to_uppercase().eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    a.eq_ignore_ascii_case(\"a\");\n    //~^ manual_ignore_case_cmp\n    \"a\".eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n}\nfn ref_ref_str(a: &&str, b: &&str) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    a.to_uppercase().eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    a.eq_ignore_ascii_case(\"a\");\n    //~^ manual_ignore_case_cmp\n    \"a\".eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n}\nfn string(a: String, b: String) {\n    a.eq_ignore_ascii_case(&b);\n    //~^ manual_ignore_case_cmp\n    a.eq_ignore_ascii_case(\"a\");\n    //~^ manual_ignore_case_cmp\n    \"a\".eq_ignore_ascii_case(&b);\n    //~^ manual_ignore_case_cmp\n    &a.to_ascii_lowercase() == &b.to_ascii_lowercase();\n    &&a.to_ascii_lowercase() == &&b.to_ascii_lowercase();\n    a.eq_ignore_ascii_case(\"a\");\n    //~^ manual_ignore_case_cmp\n    \"a\".eq_ignore_ascii_case(&b);\n    //~^ manual_ignore_case_cmp\n}\nfn ref_string(a: String, b: &String) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    a.eq_ignore_ascii_case(\"a\");\n    //~^ manual_ignore_case_cmp\n    \"a\".eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n\n    b.eq_ignore_ascii_case(&a);\n    //~^ manual_ignore_case_cmp\n    b.eq_ignore_ascii_case(\"a\");\n    //~^ manual_ignore_case_cmp\n    \"a\".eq_ignore_ascii_case(&a);\n    //~^ manual_ignore_case_cmp\n}\nfn string_ref_str(a: String, b: &str) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    a.eq_ignore_ascii_case(\"a\");\n    //~^ manual_ignore_case_cmp\n    \"a\".eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n\n    b.eq_ignore_ascii_case(&a);\n    //~^ manual_ignore_case_cmp\n    b.eq_ignore_ascii_case(\"a\");\n    //~^ manual_ignore_case_cmp\n    \"a\".eq_ignore_ascii_case(&a);\n    //~^ manual_ignore_case_cmp\n}\nfn ref_u8slice(a: &[u8], b: &[u8]) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n}\nfn u8vec(a: Vec<u8>, b: Vec<u8>) {\n    a.eq_ignore_ascii_case(&b);\n    //~^ manual_ignore_case_cmp\n}\nfn ref_u8vec(a: Vec<u8>, b: &Vec<u8>) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    b.eq_ignore_ascii_case(&a);\n    //~^ manual_ignore_case_cmp\n}\nfn ref_osstr(a: &OsStr, b: &OsStr) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n}\nfn osstring(a: OsString, b: OsString) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n}\nfn ref_osstring(a: OsString, b: &OsString) {\n    a.eq_ignore_ascii_case(b);\n    //~^ manual_ignore_case_cmp\n    b.eq_ignore_ascii_case(a);\n    //~^ manual_ignore_case_cmp\n}\n\nfn wrongly_unmangled_macros(a: &str, b: &str) -> bool {\n    struct S<'a> {\n        inner: &'a str,\n    }\n\n    let a = S { inner: a };\n    let b = S { inner: b };\n\n    macro_rules! dot_inner {\n        ($s:expr) => {\n            $s.inner\n        };\n    }\n\n    dot_inner!(a).eq_ignore_ascii_case(dot_inner!(b))\n    //~^ manual_ignore_case_cmp\n        || dot_inner!(a).eq_ignore_ascii_case(\"abc\")\n    //~^ manual_ignore_case_cmp\n}\n"
  },
  {
    "path": "tests/ui/manual_ignore_case_cmp.rs",
    "content": "#![warn(clippy::manual_ignore_case_cmp)]\n#![allow(\n    clippy::deref_addrof,\n    clippy::op_ref,\n    clippy::ptr_arg,\n    clippy::short_circuit_statement,\n    clippy::unnecessary_operation\n)]\n\nuse std::ffi::{OsStr, OsString};\n\nfn main() {}\n\nfn variants(a: &str, b: &str) {\n    if a.to_ascii_lowercase() == b.to_ascii_lowercase() {\n        //~^ manual_ignore_case_cmp\n        return;\n    }\n    if a.to_ascii_uppercase() == b.to_ascii_uppercase() {\n        //~^ manual_ignore_case_cmp\n        return;\n    }\n    let r = a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase();\n    //~^ manual_ignore_case_cmp\n    r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    // !=\n    if a.to_ascii_lowercase() != b.to_ascii_lowercase() {\n        //~^ manual_ignore_case_cmp\n        return;\n    }\n    if a.to_ascii_uppercase() != b.to_ascii_uppercase() {\n        //~^ manual_ignore_case_cmp\n        return;\n    }\n    let r = a.to_ascii_lowercase() != b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase();\n    //~^ manual_ignore_case_cmp\n    r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\n\nfn unsupported(a: char, b: char) {\n    // TODO:: these are rare, and might not be worth supporting\n    a.to_ascii_lowercase() == char::to_ascii_lowercase(&b);\n    char::to_ascii_lowercase(&a) == b.to_ascii_lowercase();\n    char::to_ascii_lowercase(&a) == char::to_ascii_lowercase(&b);\n}\n\nfn char(a: char, b: char) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_ascii_lowercase() == *&b.to_ascii_lowercase();\n    *&a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    a.to_ascii_lowercase() == 'a';\n    //~^ manual_ignore_case_cmp\n    'a' == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn u8(a: u8, b: u8) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_ascii_lowercase() == b'a';\n    //~^ manual_ignore_case_cmp\n    b'a' == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn ref_str(a: &str, b: &str) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_ascii_lowercase() == \"a\";\n    //~^ manual_ignore_case_cmp\n    \"a\" == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn ref_ref_str(a: &&str, b: &&str) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_ascii_lowercase() == \"a\";\n    //~^ manual_ignore_case_cmp\n    \"a\" == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn string(a: String, b: String) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_ascii_lowercase() == \"a\";\n    //~^ manual_ignore_case_cmp\n    \"a\" == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    &a.to_ascii_lowercase() == &b.to_ascii_lowercase();\n    &&a.to_ascii_lowercase() == &&b.to_ascii_lowercase();\n    a.to_ascii_lowercase() == \"a\";\n    //~^ manual_ignore_case_cmp\n    \"a\" == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn ref_string(a: String, b: &String) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_ascii_lowercase() == \"a\";\n    //~^ manual_ignore_case_cmp\n    \"a\" == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n\n    b.to_ascii_lowercase() == a.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    b.to_ascii_lowercase() == \"a\";\n    //~^ manual_ignore_case_cmp\n    \"a\" == a.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn string_ref_str(a: String, b: &str) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    a.to_ascii_lowercase() == \"a\";\n    //~^ manual_ignore_case_cmp\n    \"a\" == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n\n    b.to_ascii_lowercase() == a.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    b.to_ascii_lowercase() == \"a\";\n    //~^ manual_ignore_case_cmp\n    \"a\" == a.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn ref_u8slice(a: &[u8], b: &[u8]) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn u8vec(a: Vec<u8>, b: Vec<u8>) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn ref_u8vec(a: Vec<u8>, b: &Vec<u8>) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    b.to_ascii_lowercase() == a.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn ref_osstr(a: &OsStr, b: &OsStr) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn osstring(a: OsString, b: OsString) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\nfn ref_osstring(a: OsString, b: &OsString) {\n    a.to_ascii_lowercase() == b.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n    b.to_ascii_lowercase() == a.to_ascii_lowercase();\n    //~^ manual_ignore_case_cmp\n}\n\nfn wrongly_unmangled_macros(a: &str, b: &str) -> bool {\n    struct S<'a> {\n        inner: &'a str,\n    }\n\n    let a = S { inner: a };\n    let b = S { inner: b };\n\n    macro_rules! dot_inner {\n        ($s:expr) => {\n            $s.inner\n        };\n    }\n\n    dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase()\n    //~^ manual_ignore_case_cmp\n        || dot_inner!(a).to_ascii_lowercase() == \"abc\"\n    //~^ manual_ignore_case_cmp\n}\n"
  },
  {
    "path": "tests/ui/manual_ignore_case_cmp.stderr",
    "content": "error: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:15:8\n   |\nLL |     if a.to_ascii_lowercase() == b.to_ascii_lowercase() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::manual-ignore-case-cmp` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_ignore_case_cmp)]`\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     if a.to_ascii_lowercase() == b.to_ascii_lowercase() {\nLL +     if a.eq_ignore_ascii_case(b) {\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:19:8\n   |\nLL |     if a.to_ascii_uppercase() == b.to_ascii_uppercase() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     if a.to_ascii_uppercase() == b.to_ascii_uppercase() {\nLL +     if a.eq_ignore_ascii_case(b) {\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:23:13\n   |\nLL |     let r = a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     let r = a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     let r = a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:25:18\n   |\nLL |     let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase();\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase();\nLL +     let r = r || a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:27:10\n   |\nLL |     r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase();\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase();\nLL +     r && a.eq_ignore_ascii_case(&b.to_uppercase());\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:30:8\n   |\nLL |     if a.to_ascii_lowercase() != b.to_ascii_lowercase() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     if a.to_ascii_lowercase() != b.to_ascii_lowercase() {\nLL +     if !a.eq_ignore_ascii_case(b) {\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:34:8\n   |\nLL |     if a.to_ascii_uppercase() != b.to_ascii_uppercase() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     if a.to_ascii_uppercase() != b.to_ascii_uppercase() {\nLL +     if !a.eq_ignore_ascii_case(b) {\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:38:13\n   |\nLL |     let r = a.to_ascii_lowercase() != b.to_ascii_lowercase();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     let r = a.to_ascii_lowercase() != b.to_ascii_lowercase();\nLL +     let r = !a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:40:18\n   |\nLL |     let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase();\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase();\nLL +     let r = r || !a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:42:10\n   |\nLL |     r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase();\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase();\nLL +     r && !a.eq_ignore_ascii_case(&b.to_uppercase());\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:54:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(&b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:58:5\n   |\nLL |     a.to_ascii_lowercase() == 'a';\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == 'a';\nLL +     a.eq_ignore_ascii_case(&'a');\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:60:5\n   |\nLL |     'a' == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     'a' == b.to_ascii_lowercase();\nLL +     'a'.eq_ignore_ascii_case(&b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:64:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(&b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:66:5\n   |\nLL |     a.to_ascii_lowercase() == b'a';\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b'a';\nLL +     a.eq_ignore_ascii_case(&b'a');\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:68:5\n   |\nLL |     b'a' == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     b'a' == b.to_ascii_lowercase();\nLL +     b'a'.eq_ignore_ascii_case(&b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:72:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:74:5\n   |\nLL |     a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.to_uppercase().eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:76:5\n   |\nLL |     a.to_ascii_lowercase() == \"a\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == \"a\";\nLL +     a.eq_ignore_ascii_case(\"a\");\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:78:5\n   |\nLL |     \"a\" == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     \"a\" == b.to_ascii_lowercase();\nLL +     \"a\".eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:82:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:84:5\n   |\nLL |     a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.to_uppercase().eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:86:5\n   |\nLL |     a.to_ascii_lowercase() == \"a\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == \"a\";\nLL +     a.eq_ignore_ascii_case(\"a\");\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:88:5\n   |\nLL |     \"a\" == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     \"a\" == b.to_ascii_lowercase();\nLL +     \"a\".eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:92:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(&b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:94:5\n   |\nLL |     a.to_ascii_lowercase() == \"a\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == \"a\";\nLL +     a.eq_ignore_ascii_case(\"a\");\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:96:5\n   |\nLL |     \"a\" == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     \"a\" == b.to_ascii_lowercase();\nLL +     \"a\".eq_ignore_ascii_case(&b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:100:5\n   |\nLL |     a.to_ascii_lowercase() == \"a\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == \"a\";\nLL +     a.eq_ignore_ascii_case(\"a\");\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:102:5\n   |\nLL |     \"a\" == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     \"a\" == b.to_ascii_lowercase();\nLL +     \"a\".eq_ignore_ascii_case(&b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:106:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:108:5\n   |\nLL |     a.to_ascii_lowercase() == \"a\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == \"a\";\nLL +     a.eq_ignore_ascii_case(\"a\");\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:110:5\n   |\nLL |     \"a\" == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     \"a\" == b.to_ascii_lowercase();\nLL +     \"a\".eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:113:5\n   |\nLL |     b.to_ascii_lowercase() == a.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     b.to_ascii_lowercase() == a.to_ascii_lowercase();\nLL +     b.eq_ignore_ascii_case(&a);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:115:5\n   |\nLL |     b.to_ascii_lowercase() == \"a\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     b.to_ascii_lowercase() == \"a\";\nLL +     b.eq_ignore_ascii_case(\"a\");\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:117:5\n   |\nLL |     \"a\" == a.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     \"a\" == a.to_ascii_lowercase();\nLL +     \"a\".eq_ignore_ascii_case(&a);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:121:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:123:5\n   |\nLL |     a.to_ascii_lowercase() == \"a\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == \"a\";\nLL +     a.eq_ignore_ascii_case(\"a\");\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:125:5\n   |\nLL |     \"a\" == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     \"a\" == b.to_ascii_lowercase();\nLL +     \"a\".eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:128:5\n   |\nLL |     b.to_ascii_lowercase() == a.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     b.to_ascii_lowercase() == a.to_ascii_lowercase();\nLL +     b.eq_ignore_ascii_case(&a);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:130:5\n   |\nLL |     b.to_ascii_lowercase() == \"a\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     b.to_ascii_lowercase() == \"a\";\nLL +     b.eq_ignore_ascii_case(\"a\");\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:132:5\n   |\nLL |     \"a\" == a.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     \"a\" == a.to_ascii_lowercase();\nLL +     \"a\".eq_ignore_ascii_case(&a);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:136:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:140:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(&b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:144:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:146:5\n   |\nLL |     b.to_ascii_lowercase() == a.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     b.to_ascii_lowercase() == a.to_ascii_lowercase();\nLL +     b.eq_ignore_ascii_case(&a);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:150:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:154:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:158:5\n   |\nLL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();\nLL +     a.eq_ignore_ascii_case(b);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:160:5\n   |\nLL |     b.to_ascii_lowercase() == a.to_ascii_lowercase();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     b.to_ascii_lowercase() == a.to_ascii_lowercase();\nLL +     b.eq_ignore_ascii_case(a);\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:178:5\n   |\nLL |     dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase()\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -     dot_inner!(a).to_ascii_lowercase() == dot_inner!(b).to_ascii_lowercase()\nLL +     dot_inner!(a).eq_ignore_ascii_case(dot_inner!(b))\n   |\n\nerror: manual case-insensitive ASCII comparison\n  --> tests/ui/manual_ignore_case_cmp.rs:180:12\n   |\nLL |         || dot_inner!(a).to_ascii_lowercase() == \"abc\"\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `.eq_ignore_ascii_case()` instead\n   |\nLL -         || dot_inner!(a).to_ascii_lowercase() == \"abc\"\nLL +         || dot_inner!(a).eq_ignore_ascii_case(\"abc\")\n   |\n\nerror: aborting due to 51 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_ilog2.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::manual_ilog2)]\n#![allow(clippy::unnecessary_operation)]\n\nuse proc_macros::{external, with_span};\n\nfn foo(a: u32, b: u64) {\n    a.ilog2(); //~ manual_ilog2\n    a.ilog2(); //~ manual_ilog2\n\n    b.ilog2(); //~ manual_ilog2\n    64 - b.leading_zeros(); // No lint because manual ilog2 is `BIT_WIDTH - 1 - x.leading_zeros()`\n\n    // don't lint when macros are involved\n    macro_rules! two {\n        () => {\n            2\n        };\n    };\n\n    macro_rules! thirty_one {\n        () => {\n            31\n        };\n    };\n\n    a.ilog(two!());\n    thirty_one!() - a.leading_zeros();\n\n    external!($a.ilog(2));\n    with_span!(span; a.ilog(2));\n}\n\nfn wrongly_unmangled_macros() {\n    struct S {\n        inner: u32,\n    }\n\n    let x = S { inner: 42 };\n    macro_rules! access {\n        ($s:expr) => {\n            $s.inner\n        };\n    }\n    let log = access!(x).ilog2();\n    //~^ manual_ilog2\n    let log = access!(x).ilog2();\n    //~^ manual_ilog2\n}\n"
  },
  {
    "path": "tests/ui/manual_ilog2.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::manual_ilog2)]\n#![allow(clippy::unnecessary_operation)]\n\nuse proc_macros::{external, with_span};\n\nfn foo(a: u32, b: u64) {\n    31 - a.leading_zeros(); //~ manual_ilog2\n    a.ilog(2); //~ manual_ilog2\n\n    63 - b.leading_zeros(); //~ manual_ilog2\n    64 - b.leading_zeros(); // No lint because manual ilog2 is `BIT_WIDTH - 1 - x.leading_zeros()`\n\n    // don't lint when macros are involved\n    macro_rules! two {\n        () => {\n            2\n        };\n    };\n\n    macro_rules! thirty_one {\n        () => {\n            31\n        };\n    };\n\n    a.ilog(two!());\n    thirty_one!() - a.leading_zeros();\n\n    external!($a.ilog(2));\n    with_span!(span; a.ilog(2));\n}\n\nfn wrongly_unmangled_macros() {\n    struct S {\n        inner: u32,\n    }\n\n    let x = S { inner: 42 };\n    macro_rules! access {\n        ($s:expr) => {\n            $s.inner\n        };\n    }\n    let log = 31 - access!(x).leading_zeros();\n    //~^ manual_ilog2\n    let log = access!(x).ilog(2);\n    //~^ manual_ilog2\n}\n"
  },
  {
    "path": "tests/ui/manual_ilog2.stderr",
    "content": "error: manually reimplementing `ilog2`\n  --> tests/ui/manual_ilog2.rs:8:5\n   |\nLL |     31 - a.leading_zeros();\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.ilog2()`\n   |\n   = note: `-D clippy::manual-ilog2` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_ilog2)]`\n\nerror: manually reimplementing `ilog2`\n  --> tests/ui/manual_ilog2.rs:9:5\n   |\nLL |     a.ilog(2);\n   |     ^^^^^^^^^ help: try: `a.ilog2()`\n\nerror: manually reimplementing `ilog2`\n  --> tests/ui/manual_ilog2.rs:11:5\n   |\nLL |     63 - b.leading_zeros();\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `b.ilog2()`\n\nerror: manually reimplementing `ilog2`\n  --> tests/ui/manual_ilog2.rs:45:15\n   |\nLL |     let log = 31 - access!(x).leading_zeros();\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `access!(x).ilog2()`\n\nerror: manually reimplementing `ilog2`\n  --> tests/ui/manual_ilog2.rs:47:15\n   |\nLL |     let log = access!(x).ilog(2);\n   |               ^^^^^^^^^^^^^^^^^^ help: try: `access!(x).ilog2()`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_inspect.fixed",
    "content": "#![allow(clippy::no_effect, clippy::op_ref, clippy::uninlined_format_args)]\n#![warn(clippy::manual_inspect)]\n\nfn main() {\n    let _ = Some(0).inspect(|&x| {\n        //~^ manual_inspect\n        println!(\"{}\", x);\n    });\n\n    let _ = Some(0).inspect(|&x| {\n        //~^ manual_inspect\n        println!(\"{x}\");\n    });\n\n    let _ = Some(0).inspect(|&x| {\n        //~^ manual_inspect\n        println!(\"{}\", x * 5 + 1);\n    });\n\n    let _ = Some(0).inspect(|&x| {\n        //~^ manual_inspect\n        if x == 0 {\n            panic!();\n        }\n    });\n\n    let _ = Some(0).inspect(|&x| {\n        //~^ manual_inspect\n        if &x == &0 {\n            let _y = x;\n            panic!();\n        }\n    });\n\n    let _ = Some(0).map(|x| {\n        let y = x + 1;\n        if y > 5 {\n            return y;\n        }\n        x\n    });\n\n    {\n        #[derive(PartialEq)]\n        struct Foo(i32);\n\n        let _ = Some(Foo(0)).map(|x| {\n            if x == Foo(0) {\n                panic!();\n            }\n            x\n        });\n\n        let _ = Some(Foo(0)).map(|x| {\n            if &x == &Foo(0) {\n                let _y = x;\n                panic!();\n            }\n            x\n        });\n    }\n\n    {\n        macro_rules! maybe_ret {\n            ($e:expr) => {\n                if $e == 0 {\n                    return $e;\n                }\n            };\n        }\n\n        let _ = Some(0).map(|x| {\n            maybe_ret!(x);\n            x\n        });\n    }\n\n    let _ = Some((String::new(), 0u32)).inspect(|x| {\n        //~^ manual_inspect\n        if x.1 == 0 {\n            let _x = x.1;\n            panic!();\n        }\n    });\n\n    let _ = Some((String::new(), 0u32)).map(|x| {\n        if x.1 == 0 {\n            let _x = x.0;\n            panic!();\n        }\n        x\n    });\n\n    let _ = Some(String::new()).map(|x| {\n        if x.is_empty() {\n            let _ = || {\n                let _x = x;\n            };\n            panic!();\n        }\n        x\n    });\n\n    let _ = Some(String::new()).inspect(|x| {\n        //~^ manual_inspect\n        if x.is_empty() {\n            let _ = || {\n                let _x = x;\n            };\n            return;\n        }\n        println!(\"test\");\n    });\n\n    let _ = Some(0).inspect(|&x| {\n        //~^ manual_inspect\n        if x == 0 {\n            let _ = || {\n                let _x = x;\n            };\n            panic!();\n        }\n    });\n\n    {\n        use core::cell::Cell;\n        #[derive(Debug)]\n        struct Cell2(core::cell::Cell<u32>);\n\n        let _ = Some(Cell2(Cell::new(0u32))).inspect(|x| {\n            //~^ manual_inspect\n            x.0.set(1);\n        });\n\n        let _ = Some(Cell2(Cell::new(0u32))).map(|x| {\n            let y = &x;\n            if x.0.get() == 0 {\n                y.0.set(1)\n            } else {\n                println!(\"{x:?}\");\n            }\n            x\n        });\n    }\n\n    let _: Result<_, ()> = Ok(0).inspect(|&x| {\n        //~^ manual_inspect\n        println!(\"{}\", x);\n    });\n\n    let _: Result<(), _> = Err(0).inspect_err(|&x| {\n        //~^ manual_inspect\n        println!(\"{}\", x);\n    });\n\n    let _ = [0]\n        .into_iter()\n        .inspect(|&x| {\n            //~^ manual_inspect\n            println!(\"{}\", x);\n        })\n        .count();\n\n    {\n        struct S<T>(T);\n        impl<T> S<T> {\n            fn map<U>(self, f: impl FnOnce(T) -> U) -> S<U> {\n                S(f(self.0))\n            }\n\n            fn map_err<U>(self, f: impl FnOnce(T) -> U) -> S<U> {\n                S(f(self.0))\n            }\n        }\n\n        let _ = S(0).map(|x| {\n            println!(\"{}\", x);\n            x\n        });\n\n        let _ = S(0).map_err(|x| {\n            println!(\"{}\", x);\n            x\n        });\n    }\n}\n\n#[rustfmt::skip]\nfn layout_check() {\n    if let Some(x) = Some(1).inspect(|&x| { println!(\"{x}\"); //~ manual_inspect\n        // Do not collapse code into this comment\n         }) {\n        println!(\"{x}\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_inspect.rs",
    "content": "#![allow(clippy::no_effect, clippy::op_ref, clippy::uninlined_format_args)]\n#![warn(clippy::manual_inspect)]\n\nfn main() {\n    let _ = Some(0).map(|x| {\n        //~^ manual_inspect\n        println!(\"{}\", x);\n        x\n    });\n\n    let _ = Some(0).map(|x| {\n        //~^ manual_inspect\n        println!(\"{x}\");\n        x\n    });\n\n    let _ = Some(0).map(|x| {\n        //~^ manual_inspect\n        println!(\"{}\", x * 5 + 1);\n        x\n    });\n\n    let _ = Some(0).map(|x| {\n        //~^ manual_inspect\n        if x == 0 {\n            panic!();\n        }\n        x\n    });\n\n    let _ = Some(0).map(|x| {\n        //~^ manual_inspect\n        if &x == &0 {\n            let _y = x;\n            panic!();\n        }\n        x\n    });\n\n    let _ = Some(0).map(|x| {\n        let y = x + 1;\n        if y > 5 {\n            return y;\n        }\n        x\n    });\n\n    {\n        #[derive(PartialEq)]\n        struct Foo(i32);\n\n        let _ = Some(Foo(0)).map(|x| {\n            if x == Foo(0) {\n                panic!();\n            }\n            x\n        });\n\n        let _ = Some(Foo(0)).map(|x| {\n            if &x == &Foo(0) {\n                let _y = x;\n                panic!();\n            }\n            x\n        });\n    }\n\n    {\n        macro_rules! maybe_ret {\n            ($e:expr) => {\n                if $e == 0 {\n                    return $e;\n                }\n            };\n        }\n\n        let _ = Some(0).map(|x| {\n            maybe_ret!(x);\n            x\n        });\n    }\n\n    let _ = Some((String::new(), 0u32)).map(|x| {\n        //~^ manual_inspect\n        if x.1 == 0 {\n            let _x = x.1;\n            panic!();\n        }\n        x\n    });\n\n    let _ = Some((String::new(), 0u32)).map(|x| {\n        if x.1 == 0 {\n            let _x = x.0;\n            panic!();\n        }\n        x\n    });\n\n    let _ = Some(String::new()).map(|x| {\n        if x.is_empty() {\n            let _ = || {\n                let _x = x;\n            };\n            panic!();\n        }\n        x\n    });\n\n    let _ = Some(String::new()).map(|x| {\n        //~^ manual_inspect\n        if x.is_empty() {\n            let _ = || {\n                let _x = &x;\n            };\n            return x;\n        }\n        println!(\"test\");\n        x\n    });\n\n    let _ = Some(0).map(|x| {\n        //~^ manual_inspect\n        if x == 0 {\n            let _ = || {\n                let _x = x;\n            };\n            panic!();\n        }\n        x\n    });\n\n    {\n        use core::cell::Cell;\n        #[derive(Debug)]\n        struct Cell2(core::cell::Cell<u32>);\n\n        let _ = Some(Cell2(Cell::new(0u32))).map(|x| {\n            //~^ manual_inspect\n            x.0.set(1);\n            x\n        });\n\n        let _ = Some(Cell2(Cell::new(0u32))).map(|x| {\n            let y = &x;\n            if x.0.get() == 0 {\n                y.0.set(1)\n            } else {\n                println!(\"{x:?}\");\n            }\n            x\n        });\n    }\n\n    let _: Result<_, ()> = Ok(0).map(|x| {\n        //~^ manual_inspect\n        println!(\"{}\", x);\n        x\n    });\n\n    let _: Result<(), _> = Err(0).map_err(|x| {\n        //~^ manual_inspect\n        println!(\"{}\", x);\n        x\n    });\n\n    let _ = [0]\n        .into_iter()\n        .map(|x| {\n            //~^ manual_inspect\n            println!(\"{}\", x);\n            x\n        })\n        .count();\n\n    {\n        struct S<T>(T);\n        impl<T> S<T> {\n            fn map<U>(self, f: impl FnOnce(T) -> U) -> S<U> {\n                S(f(self.0))\n            }\n\n            fn map_err<U>(self, f: impl FnOnce(T) -> U) -> S<U> {\n                S(f(self.0))\n            }\n        }\n\n        let _ = S(0).map(|x| {\n            println!(\"{}\", x);\n            x\n        });\n\n        let _ = S(0).map_err(|x| {\n            println!(\"{}\", x);\n            x\n        });\n    }\n}\n\n#[rustfmt::skip]\nfn layout_check() {\n    if let Some(x) = Some(1).map(|x| { println!(\"{x}\"); //~ manual_inspect\n        // Do not collapse code into this comment\n        x }) {\n        println!(\"{x}\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_inspect.stderr",
    "content": "error: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:5:21\n   |\nLL |     let _ = Some(0).map(|x| {\n   |                     ^^^\n   |\n   = note: `-D clippy::manual-inspect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_inspect)]`\nhelp: try\n   |\nLL ~     let _ = Some(0).inspect(|&x| {\nLL |\nLL ~         println!(\"{}\", x);\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:11:21\n   |\nLL |     let _ = Some(0).map(|x| {\n   |                     ^^^\n   |\nhelp: try\n   |\nLL ~     let _ = Some(0).inspect(|&x| {\nLL |\nLL ~         println!(\"{x}\");\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:17:21\n   |\nLL |     let _ = Some(0).map(|x| {\n   |                     ^^^\n   |\nhelp: try\n   |\nLL ~     let _ = Some(0).inspect(|&x| {\nLL |\nLL ~         println!(\"{}\", x * 5 + 1);\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:23:21\n   |\nLL |     let _ = Some(0).map(|x| {\n   |                     ^^^\n   |\nhelp: try\n   |\nLL ~     let _ = Some(0).inspect(|&x| {\nLL |\nLL |         if x == 0 {\nLL |             panic!();\nLL ~         }\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:31:21\n   |\nLL |     let _ = Some(0).map(|x| {\n   |                     ^^^\n   |\nhelp: try\n   |\nLL ~     let _ = Some(0).inspect(|&x| {\nLL |\n...\nLL |             panic!();\nLL ~         }\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:83:41\n   |\nLL |     let _ = Some((String::new(), 0u32)).map(|x| {\n   |                                         ^^^\n   |\nhelp: try\n   |\nLL ~     let _ = Some((String::new(), 0u32)).inspect(|x| {\nLL |\n...\nLL |             panic!();\nLL ~         }\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:110:33\n   |\nLL |     let _ = Some(String::new()).map(|x| {\n   |                                 ^^^\n   |\nhelp: try\n   |\nLL ~     let _ = Some(String::new()).inspect(|x| {\nLL |\nLL |         if x.is_empty() {\nLL |             let _ = || {\nLL ~                 let _x = x;\nLL |             };\nLL ~             return;\nLL |         }\nLL ~         println!(\"test\");\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:122:21\n   |\nLL |     let _ = Some(0).map(|x| {\n   |                     ^^^\n   |\nhelp: try\n   |\nLL ~     let _ = Some(0).inspect(|&x| {\nLL |\n...\nLL |             panic!();\nLL ~         }\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:138:46\n   |\nLL |         let _ = Some(Cell2(Cell::new(0u32))).map(|x| {\n   |                                              ^^^\n   |\nhelp: try\n   |\nLL ~         let _ = Some(Cell2(Cell::new(0u32))).inspect(|x| {\nLL |\nLL ~             x.0.set(1);\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:155:34\n   |\nLL |     let _: Result<_, ()> = Ok(0).map(|x| {\n   |                                  ^^^\n   |\nhelp: try\n   |\nLL ~     let _: Result<_, ()> = Ok(0).inspect(|&x| {\nLL |\nLL ~         println!(\"{}\", x);\n   |\n\nerror: using `map_err` over `inspect_err`\n  --> tests/ui/manual_inspect.rs:161:35\n   |\nLL |     let _: Result<(), _> = Err(0).map_err(|x| {\n   |                                   ^^^^^^^\n   |\nhelp: try\n   |\nLL ~     let _: Result<(), _> = Err(0).inspect_err(|&x| {\nLL |\nLL ~         println!(\"{}\", x);\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:169:10\n   |\nLL |         .map(|x| {\n   |          ^^^\n   |\nhelp: try\n   |\nLL ~         .inspect(|&x| {\nLL |\nLL ~             println!(\"{}\", x);\n   |\n\nerror: using `map` over `inspect`\n  --> tests/ui/manual_inspect.rs:202:30\n   |\nLL |     if let Some(x) = Some(1).map(|x| { println!(\"{x}\");\n   |                              ^^^\n   |\nhelp: try\n   |\nLL ~     if let Some(x) = Some(1).inspect(|&x| { println!(\"{x}\");\nLL |         // Do not collapse code into this comment\nLL ~          }) {\n   |\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_instant_elapsed.fixed",
    "content": "#![warn(clippy::manual_instant_elapsed)]\n#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::unchecked_time_subtraction)]\n#![allow(unused_variables)]\n#![allow(unused_must_use)]\n\nuse std::time::Instant;\n\nfn main() {\n    let prev_instant = Instant::now();\n\n    {\n        // don't influence\n        let another_instant = Instant::now();\n    }\n\n    let duration = prev_instant.elapsed();\n    //~^ manual_instant_elapsed\n\n    // don't catch\n    let duration = prev_instant.elapsed();\n\n    Instant::now() - duration;\n\n    let ref_to_instant = &Instant::now();\n\n    (*ref_to_instant).elapsed(); // to ensure parens are added correctly\n    //\n    //~^^ manual_instant_elapsed\n}\n\nfn issue16236() {\n    use std::ops::Sub as _;\n    macro_rules! deref {\n        ($e:expr) => {\n            *$e\n        };\n    }\n\n    let start = &Instant::now();\n    let _ = deref!(start).elapsed();\n    //~^ manual_instant_elapsed\n\n    deref!(start).elapsed();\n    //~^ manual_instant_elapsed\n}\n"
  },
  {
    "path": "tests/ui/manual_instant_elapsed.rs",
    "content": "#![warn(clippy::manual_instant_elapsed)]\n#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::unchecked_time_subtraction)]\n#![allow(unused_variables)]\n#![allow(unused_must_use)]\n\nuse std::time::Instant;\n\nfn main() {\n    let prev_instant = Instant::now();\n\n    {\n        // don't influence\n        let another_instant = Instant::now();\n    }\n\n    let duration = Instant::now() - prev_instant;\n    //~^ manual_instant_elapsed\n\n    // don't catch\n    let duration = prev_instant.elapsed();\n\n    Instant::now() - duration;\n\n    let ref_to_instant = &Instant::now();\n\n    Instant::now() - *ref_to_instant; // to ensure parens are added correctly\n    //\n    //~^^ manual_instant_elapsed\n}\n\nfn issue16236() {\n    use std::ops::Sub as _;\n    macro_rules! deref {\n        ($e:expr) => {\n            *$e\n        };\n    }\n\n    let start = &Instant::now();\n    let _ = Instant::now().sub(deref!(start));\n    //~^ manual_instant_elapsed\n\n    Instant::now() - deref!(start);\n    //~^ manual_instant_elapsed\n}\n"
  },
  {
    "path": "tests/ui/manual_instant_elapsed.stderr",
    "content": "error: manual implementation of `Instant::elapsed`\n  --> tests/ui/manual_instant_elapsed.rs:17:20\n   |\nLL |     let duration = Instant::now() - prev_instant;\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `prev_instant.elapsed()`\n   |\n   = note: `-D clippy::manual-instant-elapsed` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_instant_elapsed)]`\n\nerror: manual implementation of `Instant::elapsed`\n  --> tests/ui/manual_instant_elapsed.rs:27:5\n   |\nLL |     Instant::now() - *ref_to_instant; // to ensure parens are added correctly\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*ref_to_instant).elapsed()`\n\nerror: manual implementation of `Instant::elapsed`\n  --> tests/ui/manual_instant_elapsed.rs:41:13\n   |\nLL |     let _ = Instant::now().sub(deref!(start));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `deref!(start).elapsed()`\n\nerror: manual implementation of `Instant::elapsed`\n  --> tests/ui/manual_instant_elapsed.rs:44:5\n   |\nLL |     Instant::now() - deref!(start);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `deref!(start).elapsed()`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_is_ascii_check.fixed",
    "content": "#![allow(unused, dead_code)]\n#![warn(clippy::manual_is_ascii_check)]\n\nfn main() {\n    assert!('x'.is_ascii_lowercase());\n    //~^ manual_is_ascii_check\n    assert!('X'.is_ascii_uppercase());\n    //~^ manual_is_ascii_check\n    assert!(b'x'.is_ascii_lowercase());\n    //~^ manual_is_ascii_check\n    assert!(b'X'.is_ascii_uppercase());\n    //~^ manual_is_ascii_check\n\n    let num = '2';\n    assert!(num.is_ascii_digit());\n    //~^ manual_is_ascii_check\n    assert!(b'1'.is_ascii_digit());\n    //~^ manual_is_ascii_check\n    assert!('x'.is_ascii_alphabetic());\n    //~^ manual_is_ascii_check\n\n    assert!(matches!('x', 'A'..='Z' | 'a'..='z' | '_'));\n\n    b'0'.is_ascii_digit();\n    //~^ manual_is_ascii_check\n    b'a'.is_ascii_lowercase();\n    //~^ manual_is_ascii_check\n    b'A'.is_ascii_uppercase();\n    //~^ manual_is_ascii_check\n\n    '0'.is_ascii_digit();\n    //~^ manual_is_ascii_check\n    'a'.is_ascii_lowercase();\n    //~^ manual_is_ascii_check\n    'A'.is_ascii_uppercase();\n    //~^ manual_is_ascii_check\n\n    let cool_letter = &'g';\n    cool_letter.is_ascii_digit();\n    //~^ manual_is_ascii_check\n    cool_letter.is_ascii_lowercase();\n    //~^ manual_is_ascii_check\n    cool_letter.is_ascii_uppercase();\n    //~^ manual_is_ascii_check\n}\n\n#[clippy::msrv = \"1.23\"]\nfn msrv_1_23() {\n    assert!(matches!(b'1', b'0'..=b'9'));\n    assert!(matches!('X', 'A'..='Z'));\n    assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\n    assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'));\n}\n\n#[clippy::msrv = \"1.24\"]\nfn msrv_1_24() {\n    assert!(b'1'.is_ascii_digit());\n    //~^ manual_is_ascii_check\n    assert!('X'.is_ascii_uppercase());\n    //~^ manual_is_ascii_check\n    assert!('x'.is_ascii_alphabetic());\n    //~^ manual_is_ascii_check\n    assert!('x'.is_ascii_hexdigit());\n    //~^ manual_is_ascii_check\n}\n\n#[clippy::msrv = \"1.46\"]\nfn msrv_1_46() {\n    const FOO: bool = matches!('x', '0'..='9');\n    const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F');\n}\n\n#[clippy::msrv = \"1.47\"]\nfn msrv_1_47() {\n    const FOO: bool = 'x'.is_ascii_digit();\n    //~^ manual_is_ascii_check\n    const BAR: bool = 'x'.is_ascii_hexdigit();\n    //~^ manual_is_ascii_check\n}\n\n#[allow(clippy::deref_addrof, clippy::needless_borrow)]\nfn with_refs() {\n    let cool_letter = &&'g';\n    cool_letter.is_ascii_digit();\n    //~^ manual_is_ascii_check\n    cool_letter.is_ascii_lowercase();\n    //~^ manual_is_ascii_check\n}\n\nfn generics() {\n    fn a<U>(u: &U) -> bool\n    where\n        char: PartialOrd<U>,\n        U: PartialOrd<char> + ?Sized,\n    {\n        ('A'..='Z').contains(u)\n    }\n\n    fn take_while<Item, F>(cond: F)\n    where\n        Item: Sized,\n        F: Fn(Item) -> bool,\n    {\n    }\n    take_while(|c: char| c.is_ascii_uppercase());\n    //~^ manual_is_ascii_check\n    take_while(|c: u8| c.is_ascii_uppercase());\n    //~^ manual_is_ascii_check\n    take_while(|c: char| c.is_ascii_uppercase());\n    //~^ manual_is_ascii_check\n    take_while(|c: char| c.is_ascii_uppercase());\n    //~^ manual_is_ascii_check\n}\n\nfn adds_type_reference() {\n    let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect();\n    //~^ manual_is_ascii_check\n    let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();\n    //~^ manual_is_ascii_check\n    let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();\n    //~^ manual_is_ascii_check\n}\n"
  },
  {
    "path": "tests/ui/manual_is_ascii_check.rs",
    "content": "#![allow(unused, dead_code)]\n#![warn(clippy::manual_is_ascii_check)]\n\nfn main() {\n    assert!(matches!('x', 'a'..='z'));\n    //~^ manual_is_ascii_check\n    assert!(matches!('X', 'A'..='Z'));\n    //~^ manual_is_ascii_check\n    assert!(matches!(b'x', b'a'..=b'z'));\n    //~^ manual_is_ascii_check\n    assert!(matches!(b'X', b'A'..=b'Z'));\n    //~^ manual_is_ascii_check\n\n    let num = '2';\n    assert!(matches!(num, '0'..='9'));\n    //~^ manual_is_ascii_check\n    assert!(matches!(b'1', b'0'..=b'9'));\n    //~^ manual_is_ascii_check\n    assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\n    //~^ manual_is_ascii_check\n\n    assert!(matches!('x', 'A'..='Z' | 'a'..='z' | '_'));\n\n    (b'0'..=b'9').contains(&b'0');\n    //~^ manual_is_ascii_check\n    (b'a'..=b'z').contains(&b'a');\n    //~^ manual_is_ascii_check\n    (b'A'..=b'Z').contains(&b'A');\n    //~^ manual_is_ascii_check\n\n    ('0'..='9').contains(&'0');\n    //~^ manual_is_ascii_check\n    ('a'..='z').contains(&'a');\n    //~^ manual_is_ascii_check\n    ('A'..='Z').contains(&'A');\n    //~^ manual_is_ascii_check\n\n    let cool_letter = &'g';\n    ('0'..='9').contains(cool_letter);\n    //~^ manual_is_ascii_check\n    ('a'..='z').contains(cool_letter);\n    //~^ manual_is_ascii_check\n    ('A'..='Z').contains(cool_letter);\n    //~^ manual_is_ascii_check\n}\n\n#[clippy::msrv = \"1.23\"]\nfn msrv_1_23() {\n    assert!(matches!(b'1', b'0'..=b'9'));\n    assert!(matches!('X', 'A'..='Z'));\n    assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\n    assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'));\n}\n\n#[clippy::msrv = \"1.24\"]\nfn msrv_1_24() {\n    assert!(matches!(b'1', b'0'..=b'9'));\n    //~^ manual_is_ascii_check\n    assert!(matches!('X', 'A'..='Z'));\n    //~^ manual_is_ascii_check\n    assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\n    //~^ manual_is_ascii_check\n    assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'));\n    //~^ manual_is_ascii_check\n}\n\n#[clippy::msrv = \"1.46\"]\nfn msrv_1_46() {\n    const FOO: bool = matches!('x', '0'..='9');\n    const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F');\n}\n\n#[clippy::msrv = \"1.47\"]\nfn msrv_1_47() {\n    const FOO: bool = matches!('x', '0'..='9');\n    //~^ manual_is_ascii_check\n    const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F');\n    //~^ manual_is_ascii_check\n}\n\n#[allow(clippy::deref_addrof, clippy::needless_borrow)]\nfn with_refs() {\n    let cool_letter = &&'g';\n    ('0'..='9').contains(&&cool_letter);\n    //~^ manual_is_ascii_check\n    ('a'..='z').contains(*cool_letter);\n    //~^ manual_is_ascii_check\n}\n\nfn generics() {\n    fn a<U>(u: &U) -> bool\n    where\n        char: PartialOrd<U>,\n        U: PartialOrd<char> + ?Sized,\n    {\n        ('A'..='Z').contains(u)\n    }\n\n    fn take_while<Item, F>(cond: F)\n    where\n        Item: Sized,\n        F: Fn(Item) -> bool,\n    {\n    }\n    take_while(|c| ('A'..='Z').contains(&c));\n    //~^ manual_is_ascii_check\n    take_while(|c| (b'A'..=b'Z').contains(&c));\n    //~^ manual_is_ascii_check\n    take_while(|c: char| ('A'..='Z').contains(&c));\n    //~^ manual_is_ascii_check\n    take_while(|c| matches!(c, 'A'..='Z'));\n    //~^ manual_is_ascii_check\n}\n\nfn adds_type_reference() {\n    let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect();\n    //~^ manual_is_ascii_check\n    let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect();\n    //~^ manual_is_ascii_check\n    let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();\n    //~^ manual_is_ascii_check\n}\n"
  },
  {
    "path": "tests/ui/manual_is_ascii_check.stderr",
    "content": "error: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:5:13\n   |\nLL |     assert!(matches!('x', 'a'..='z'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::manual-is-ascii-check` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_is_ascii_check)]`\nhelp: try\n   |\nLL -     assert!(matches!('x', 'a'..='z'));\nLL +     assert!('x'.is_ascii_lowercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:7:13\n   |\nLL |     assert!(matches!('X', 'A'..='Z'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!('X', 'A'..='Z'));\nLL +     assert!('X'.is_ascii_uppercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:9:13\n   |\nLL |     assert!(matches!(b'x', b'a'..=b'z'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!(b'x', b'a'..=b'z'));\nLL +     assert!(b'x'.is_ascii_lowercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:11:13\n   |\nLL |     assert!(matches!(b'X', b'A'..=b'Z'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!(b'X', b'A'..=b'Z'));\nLL +     assert!(b'X'.is_ascii_uppercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:15:13\n   |\nLL |     assert!(matches!(num, '0'..='9'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!(num, '0'..='9'));\nLL +     assert!(num.is_ascii_digit());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:17:13\n   |\nLL |     assert!(matches!(b'1', b'0'..=b'9'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!(b'1', b'0'..=b'9'));\nLL +     assert!(b'1'.is_ascii_digit());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:19:13\n   |\nLL |     assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\nLL +     assert!('x'.is_ascii_alphabetic());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:24:5\n   |\nLL |     (b'0'..=b'9').contains(&b'0');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     (b'0'..=b'9').contains(&b'0');\nLL +     b'0'.is_ascii_digit();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:26:5\n   |\nLL |     (b'a'..=b'z').contains(&b'a');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     (b'a'..=b'z').contains(&b'a');\nLL +     b'a'.is_ascii_lowercase();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:28:5\n   |\nLL |     (b'A'..=b'Z').contains(&b'A');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     (b'A'..=b'Z').contains(&b'A');\nLL +     b'A'.is_ascii_uppercase();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:31:5\n   |\nLL |     ('0'..='9').contains(&'0');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     ('0'..='9').contains(&'0');\nLL +     '0'.is_ascii_digit();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:33:5\n   |\nLL |     ('a'..='z').contains(&'a');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     ('a'..='z').contains(&'a');\nLL +     'a'.is_ascii_lowercase();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:35:5\n   |\nLL |     ('A'..='Z').contains(&'A');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     ('A'..='Z').contains(&'A');\nLL +     'A'.is_ascii_uppercase();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:39:5\n   |\nLL |     ('0'..='9').contains(cool_letter);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     ('0'..='9').contains(cool_letter);\nLL +     cool_letter.is_ascii_digit();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:41:5\n   |\nLL |     ('a'..='z').contains(cool_letter);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     ('a'..='z').contains(cool_letter);\nLL +     cool_letter.is_ascii_lowercase();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:43:5\n   |\nLL |     ('A'..='Z').contains(cool_letter);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     ('A'..='Z').contains(cool_letter);\nLL +     cool_letter.is_ascii_uppercase();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:57:13\n   |\nLL |     assert!(matches!(b'1', b'0'..=b'9'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!(b'1', b'0'..=b'9'));\nLL +     assert!(b'1'.is_ascii_digit());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:59:13\n   |\nLL |     assert!(matches!('X', 'A'..='Z'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!('X', 'A'..='Z'));\nLL +     assert!('X'.is_ascii_uppercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:61:13\n   |\nLL |     assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!('x', 'A'..='Z' | 'a'..='z'));\nLL +     assert!('x'.is_ascii_alphabetic());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:63:13\n   |\nLL |     assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     assert!(matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F'));\nLL +     assert!('x'.is_ascii_hexdigit());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:75:23\n   |\nLL |     const FOO: bool = matches!('x', '0'..='9');\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     const FOO: bool = matches!('x', '0'..='9');\nLL +     const FOO: bool = 'x'.is_ascii_digit();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:77:23\n   |\nLL |     const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F');\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     const BAR: bool = matches!('x', '0'..='9' | 'a'..='f' | 'A'..='F');\nLL +     const BAR: bool = 'x'.is_ascii_hexdigit();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:84:5\n   |\nLL |     ('0'..='9').contains(&&cool_letter);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     ('0'..='9').contains(&&cool_letter);\nLL +     cool_letter.is_ascii_digit();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:86:5\n   |\nLL |     ('a'..='z').contains(*cool_letter);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     ('a'..='z').contains(*cool_letter);\nLL +     cool_letter.is_ascii_lowercase();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:105:20\n   |\nLL |     take_while(|c| ('A'..='Z').contains(&c));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     take_while(|c| ('A'..='Z').contains(&c));\nLL +     take_while(|c: char| c.is_ascii_uppercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:107:20\n   |\nLL |     take_while(|c| (b'A'..=b'Z').contains(&c));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     take_while(|c| (b'A'..=b'Z').contains(&c));\nLL +     take_while(|c: u8| c.is_ascii_uppercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:109:26\n   |\nLL |     take_while(|c: char| ('A'..='Z').contains(&c));\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     take_while(|c: char| ('A'..='Z').contains(&c));\nLL +     take_while(|c: char| c.is_ascii_uppercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:111:20\n   |\nLL |     take_while(|c| matches!(c, 'A'..='Z'));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     take_while(|c| matches!(c, 'A'..='Z'));\nLL +     take_while(|c: char| c.is_ascii_uppercase());\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:116:63\n   |\nLL |     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect();\n   |                                                               ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect();\nLL +     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:118:71\n   |\nLL |     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect();\n   |                                                                       ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect();\nLL +     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();\n   |\n\nerror: manual check for common ascii range\n  --> tests/ui/manual_is_ascii_check.rs:120:71\n   |\nLL |     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();\n   |                                                                       ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();\nLL +     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();\n   |\n\nerror: aborting due to 31 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_is_multiple_of.fixed",
    "content": "//@aux-build: proc_macros.rs\n#![warn(clippy::manual_is_multiple_of)]\n\nfn main() {}\n\n#[clippy::msrv = \"1.87\"]\nfn f(a: u64, b: u64) {\n    let _ = a.is_multiple_of(b); //~ manual_is_multiple_of\n    let _ = (a + 1).is_multiple_of(b + 1); //~ manual_is_multiple_of\n    let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of\n    let _ = !(a + 1).is_multiple_of(b + 1); //~ manual_is_multiple_of\n\n    let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of\n    let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of\n\n    proc_macros::external! {\n        let a: u64 = 23424;\n        let _ = a % 4096 == 0;\n    }\n}\n\n#[clippy::msrv = \"1.86\"]\nfn g(a: u64, b: u64) {\n    let _ = a % b == 0;\n}\n\nfn needs_deref(a: &u64, b: &u64) {\n    let _ = a.is_multiple_of(*b); //~ manual_is_multiple_of\n}\n\nfn closures(a: u64, b: u64) {\n    // Do not lint, types are ambiguous at this point\n    let cl = |a, b| a % b == 0;\n    let _ = cl(a, b);\n\n    // Do not lint, types are ambiguous at this point\n    let cl = |a: _, b: _| a % b == 0;\n    let _ = cl(a, b);\n\n    // Type of `a` is enough\n    let cl = |a: u64, b| a.is_multiple_of(b); //~ manual_is_multiple_of\n    let _ = cl(a, b);\n\n    // Type of `a` is enough\n    let cl = |a: &u64, b| a.is_multiple_of(b); //~ manual_is_multiple_of\n    let _ = cl(&a, b);\n\n    // Type of `b` is not enough\n    let cl = |a, b: u64| a % b == 0;\n    let _ = cl(&a, b);\n}\n\nfn any_rem<T: std::ops::Rem<Output = u32>>(a: T, b: T) {\n    // An arbitrary `Rem` implementation should not lint\n    let _ = a % b == 0;\n}\n\nmod issue15103 {\n    fn foo() -> Option<u64> {\n        let mut n: u64 = 150_000_000;\n\n        (2..).find(|p| {\n            while n.is_multiple_of(*p) {\n                //~^ manual_is_multiple_of\n                n /= p;\n            }\n            n <= 1\n        })\n    }\n\n    const fn generate_primes<const N: usize>() -> [u64; N] {\n        let mut result = [0; N];\n        if N == 0 {\n            return result;\n        }\n        result[0] = 2;\n        if N == 1 {\n            return result;\n        }\n        let mut idx = 1;\n        let mut p = 3;\n        while idx < N {\n            let mut j = 0;\n            while j < idx && p % result[j] != 0 {\n                j += 1;\n            }\n            if j == idx {\n                result[idx] = p;\n                idx += 1;\n            }\n            p += 1;\n        }\n        result\n    }\n\n    fn bar() -> u32 {\n        let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n.is_multiple_of(*i)).sum() };\n        //~^ manual_is_multiple_of\n\n        let d = |n| (1..=n / 2).filter(|i| n % i == 0).sum();\n        (1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum()\n    }\n}\n\nfn wrongly_unmangled_macros(a: u32, b: u32) {\n    struct Wrapper(u32);\n    let a = Wrapper(a);\n    let b = Wrapper(b);\n    macro_rules! dot_0 {\n        ($x:expr) => {\n            $x.0\n        };\n    }\n\n    if dot_0!(a).is_multiple_of(dot_0!(b)) {\n        //~^ manual_is_multiple_of\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_is_multiple_of.rs",
    "content": "//@aux-build: proc_macros.rs\n#![warn(clippy::manual_is_multiple_of)]\n\nfn main() {}\n\n#[clippy::msrv = \"1.87\"]\nfn f(a: u64, b: u64) {\n    let _ = a % b == 0; //~ manual_is_multiple_of\n    let _ = (a + 1) % (b + 1) == 0; //~ manual_is_multiple_of\n    let _ = a % b != 0; //~ manual_is_multiple_of\n    let _ = (a + 1) % (b + 1) != 0; //~ manual_is_multiple_of\n\n    let _ = a % b > 0; //~ manual_is_multiple_of\n    let _ = 0 < a % b; //~ manual_is_multiple_of\n\n    proc_macros::external! {\n        let a: u64 = 23424;\n        let _ = a % 4096 == 0;\n    }\n}\n\n#[clippy::msrv = \"1.86\"]\nfn g(a: u64, b: u64) {\n    let _ = a % b == 0;\n}\n\nfn needs_deref(a: &u64, b: &u64) {\n    let _ = a % b == 0; //~ manual_is_multiple_of\n}\n\nfn closures(a: u64, b: u64) {\n    // Do not lint, types are ambiguous at this point\n    let cl = |a, b| a % b == 0;\n    let _ = cl(a, b);\n\n    // Do not lint, types are ambiguous at this point\n    let cl = |a: _, b: _| a % b == 0;\n    let _ = cl(a, b);\n\n    // Type of `a` is enough\n    let cl = |a: u64, b| a % b == 0; //~ manual_is_multiple_of\n    let _ = cl(a, b);\n\n    // Type of `a` is enough\n    let cl = |a: &u64, b| a % b == 0; //~ manual_is_multiple_of\n    let _ = cl(&a, b);\n\n    // Type of `b` is not enough\n    let cl = |a, b: u64| a % b == 0;\n    let _ = cl(&a, b);\n}\n\nfn any_rem<T: std::ops::Rem<Output = u32>>(a: T, b: T) {\n    // An arbitrary `Rem` implementation should not lint\n    let _ = a % b == 0;\n}\n\nmod issue15103 {\n    fn foo() -> Option<u64> {\n        let mut n: u64 = 150_000_000;\n\n        (2..).find(|p| {\n            while n % p == 0 {\n                //~^ manual_is_multiple_of\n                n /= p;\n            }\n            n <= 1\n        })\n    }\n\n    const fn generate_primes<const N: usize>() -> [u64; N] {\n        let mut result = [0; N];\n        if N == 0 {\n            return result;\n        }\n        result[0] = 2;\n        if N == 1 {\n            return result;\n        }\n        let mut idx = 1;\n        let mut p = 3;\n        while idx < N {\n            let mut j = 0;\n            while j < idx && p % result[j] != 0 {\n                j += 1;\n            }\n            if j == idx {\n                result[idx] = p;\n                idx += 1;\n            }\n            p += 1;\n        }\n        result\n    }\n\n    fn bar() -> u32 {\n        let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n % i == 0).sum() };\n        //~^ manual_is_multiple_of\n\n        let d = |n| (1..=n / 2).filter(|i| n % i == 0).sum();\n        (1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum()\n    }\n}\n\nfn wrongly_unmangled_macros(a: u32, b: u32) {\n    struct Wrapper(u32);\n    let a = Wrapper(a);\n    let b = Wrapper(b);\n    macro_rules! dot_0 {\n        ($x:expr) => {\n            $x.0\n        };\n    }\n\n    if dot_0!(a) % dot_0!(b) == 0 {\n        //~^ manual_is_multiple_of\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_is_multiple_of.stderr",
    "content": "error: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:8:13\n   |\nLL |     let _ = a % b == 0;\n   |             ^^^^^^^^^^ help: replace with: `a.is_multiple_of(b)`\n   |\n   = note: `-D clippy::manual-is-multiple-of` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_is_multiple_of)]`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:9:13\n   |\nLL |     let _ = (a + 1) % (b + 1) == 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `(a + 1).is_multiple_of(b + 1)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:10:13\n   |\nLL |     let _ = a % b != 0;\n   |             ^^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:11:13\n   |\nLL |     let _ = (a + 1) % (b + 1) != 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `!(a + 1).is_multiple_of(b + 1)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:13:13\n   |\nLL |     let _ = a % b > 0;\n   |             ^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:14:13\n   |\nLL |     let _ = 0 < a % b;\n   |             ^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:28:13\n   |\nLL |     let _ = a % b == 0;\n   |             ^^^^^^^^^^ help: replace with: `a.is_multiple_of(*b)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:41:26\n   |\nLL |     let cl = |a: u64, b| a % b == 0;\n   |                          ^^^^^^^^^^ help: replace with: `a.is_multiple_of(b)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:45:27\n   |\nLL |     let cl = |a: &u64, b| a % b == 0;\n   |                           ^^^^^^^^^^ help: replace with: `a.is_multiple_of(b)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:63:19\n   |\nLL |             while n % p == 0 {\n   |                   ^^^^^^^^^^ help: replace with: `n.is_multiple_of(*p)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:97:58\n   |\nLL |         let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n % i == 0).sum() };\n   |                                                          ^^^^^^^^^^ help: replace with: `n.is_multiple_of(*i)`\n\nerror: manual implementation of `.is_multiple_of()`\n  --> tests/ui/manual_is_multiple_of.rs:115:8\n   |\nLL |     if dot_0!(a) % dot_0!(b) == 0 {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `dot_0!(a).is_multiple_of(dot_0!(b))`\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_is_power_of_two.fixed",
    "content": "#![warn(clippy::manual_is_power_of_two)]\n#![allow(clippy::precedence)]\n\nmacro_rules! binop {\n    ($a: expr, equal, $b: expr) => {\n        $a == $b\n    };\n    ($a: expr, and, $b: expr) => {\n        $a & $b\n    };\n    ($a: expr, minus, $b: expr) => {\n        $a - $b\n    };\n}\n\nfn main() {\n    let a = 16_u64;\n\n    let _ = a.is_power_of_two();\n    //~^ manual_is_power_of_two\n    let _ = a.is_power_of_two();\n    //~^ manual_is_power_of_two\n    let _ = a.is_power_of_two();\n    //~^ manual_is_power_of_two\n\n    // Test different orders of expression\n    let _ = a.is_power_of_two();\n    //~^ manual_is_power_of_two\n    let _ = a.is_power_of_two();\n    //~^ manual_is_power_of_two\n    let _ = a.is_power_of_two();\n    //~^ manual_is_power_of_two\n    let _ = a.is_power_of_two();\n    //~^ manual_is_power_of_two\n\n    let b = 4_i64;\n\n    // is_power_of_two only works for unsigned integers\n    let _ = b.count_ones() == 1;\n    let _ = b & (b - 1) == 0;\n\n    let i: i32 = 3;\n    let _ = (i as u32).is_power_of_two();\n    //~^ manual_is_power_of_two\n\n    let _ = binop!(a.count_ones(), equal, 1);\n    let _ = binop!(a, and, a - 1) == 0;\n    let _ = a & binop!(a, minus, 1) == 0;\n}\n\n#[clippy::msrv = \"1.31\"]\nconst fn low_msrv(a: u32) -> bool {\n    a & (a - 1) == 0\n}\n\n#[clippy::msrv = \"1.32\"]\nconst fn high_msrv(a: u32) -> bool {\n    a.is_power_of_two()\n    //~^ manual_is_power_of_two\n}\n"
  },
  {
    "path": "tests/ui/manual_is_power_of_two.rs",
    "content": "#![warn(clippy::manual_is_power_of_two)]\n#![allow(clippy::precedence)]\n\nmacro_rules! binop {\n    ($a: expr, equal, $b: expr) => {\n        $a == $b\n    };\n    ($a: expr, and, $b: expr) => {\n        $a & $b\n    };\n    ($a: expr, minus, $b: expr) => {\n        $a - $b\n    };\n}\n\nfn main() {\n    let a = 16_u64;\n\n    let _ = a.count_ones() == 1;\n    //~^ manual_is_power_of_two\n    let _ = u64::count_ones(a) == 1;\n    //~^ manual_is_power_of_two\n    let _ = a & (a - 1) == 0;\n    //~^ manual_is_power_of_two\n\n    // Test different orders of expression\n    let _ = 1 == a.count_ones();\n    //~^ manual_is_power_of_two\n    let _ = (a - 1) & a == 0;\n    //~^ manual_is_power_of_two\n    let _ = 0 == a & (a - 1);\n    //~^ manual_is_power_of_two\n    let _ = 0 == (a - 1) & a;\n    //~^ manual_is_power_of_two\n\n    let b = 4_i64;\n\n    // is_power_of_two only works for unsigned integers\n    let _ = b.count_ones() == 1;\n    let _ = b & (b - 1) == 0;\n\n    let i: i32 = 3;\n    let _ = i as u32 & (i as u32 - 1) == 0;\n    //~^ manual_is_power_of_two\n\n    let _ = binop!(a.count_ones(), equal, 1);\n    let _ = binop!(a, and, a - 1) == 0;\n    let _ = a & binop!(a, minus, 1) == 0;\n}\n\n#[clippy::msrv = \"1.31\"]\nconst fn low_msrv(a: u32) -> bool {\n    a & (a - 1) == 0\n}\n\n#[clippy::msrv = \"1.32\"]\nconst fn high_msrv(a: u32) -> bool {\n    a & (a - 1) == 0\n    //~^ manual_is_power_of_two\n}\n"
  },
  {
    "path": "tests/ui/manual_is_power_of_two.stderr",
    "content": "error: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:19:13\n   |\nLL |     let _ = a.count_ones() == 1;\n   |             ^^^^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`\n   |\n   = note: `-D clippy::manual-is-power-of-two` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_is_power_of_two)]`\n\nerror: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:21:13\n   |\nLL |     let _ = u64::count_ones(a) == 1;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`\n\nerror: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:23:13\n   |\nLL |     let _ = a & (a - 1) == 0;\n   |             ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`\n\nerror: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:27:13\n   |\nLL |     let _ = 1 == a.count_ones();\n   |             ^^^^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`\n\nerror: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:29:13\n   |\nLL |     let _ = (a - 1) & a == 0;\n   |             ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`\n\nerror: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:31:13\n   |\nLL |     let _ = 0 == a & (a - 1);\n   |             ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`\n\nerror: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:33:13\n   |\nLL |     let _ = 0 == (a - 1) & a;\n   |             ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`\n\nerror: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:43:13\n   |\nLL |     let _ = i as u32 & (i as u32 - 1) == 0;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `(i as u32).is_power_of_two()`\n\nerror: manually reimplementing `is_power_of_two`\n  --> tests/ui/manual_is_power_of_two.rs:58:5\n   |\nLL |     a & (a - 1) == 0\n   |     ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_is_variant_and.fixed",
    "content": "//@aux-build:option_helpers.rs\n#![warn(clippy::manual_is_variant_and)]\n#![allow(clippy::redundant_closure)]\n\n#[macro_use]\nextern crate option_helpers;\n\nstruct Foo<T>(T);\n\nimpl<T> Foo<T> {\n    fn map<F: FnMut(T) -> bool>(self, mut f: F) -> Option<bool> {\n        Some(f(self.0))\n    }\n}\n\nfn foo() -> Option<bool> {\n    Some(true)\n}\n\nmacro_rules! some_true {\n    () => {\n        Some(true)\n    };\n}\nmacro_rules! some_false {\n    () => {\n        Some(false)\n    };\n}\n\nmacro_rules! mac {\n    (some $e:expr) => {\n        Some($e)\n    };\n    (some_map $e:expr) => {\n        Some($e).map(|x| x % 2 == 0)\n    };\n    (map $e:expr) => {\n        $e.map(|x| x % 2 == 0)\n    };\n    (eq $a:expr, $b:expr) => {\n        $a == $b\n    };\n}\n\n#[rustfmt::skip]\nfn option_methods() {\n    let opt = Some(1);\n\n    // Check for `option.map(_).unwrap_or_default()` use.\n    // Single line case.\n    let _ = opt.is_some_and(|x| x > 1);\n    // Multi-line cases.\n    let _ = opt.is_some_and(|x| {\n    //~^ manual_is_variant_and\n        x > 1\n    });\n    let _ = opt.is_some_and(|x| x > 1);\n    //~^ manual_is_variant_and\n    let _ = opt\n        .is_some_and(|x| x > 1);\n\n    let _ = Some(2).is_some_and(|x| x % 2 == 0);\n    //~^ manual_is_variant_and\n    let _ = Some(2).is_none_or(|x| x % 2 != 0);\n    //~^ manual_is_variant_and\n    let _ = Some(2).is_some_and(|x| x % 2 == 0);\n    //~^ manual_is_variant_and\n    let _ = Some(2).is_none_or(|x| x % 2 == 0);\n    //~^ manual_is_variant_and\n\n    // won't fix because the return type of the closure is not `bool`\n    let _ = opt.map(|x| x + 1).unwrap_or_default();\n\n    let opt2 = Some('a');\n    let _ = opt2.is_some_and(char::is_alphanumeric); // should lint\n    //~^ manual_is_variant_and\n    let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint\n\n    // Should not lint.\n    let _ = Foo::<u32>(0).map(|x| x.is_multiple_of(2)) == Some(true);\n    let _ = Some(2).map(|x| x % 2 == 0) != foo();\n    let _ = mac!(eq Some(2).map(|x| x % 2 == 0), Some(true));\n    let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true);\n    let _ = mac!(some_map 2) == Some(true);\n    let _ = mac!(map Some(2)) == Some(true);\n}\n\n#[rustfmt::skip]\nfn result_methods() {\n    let res: Result<i32, ()> = Ok(1);\n\n    // multi line cases\n    let _ = res.is_ok_and(|x| {\n    //~^ manual_is_variant_and\n        x > 1\n    });\n    let _ = res.is_ok_and(|x| x > 1);\n\n    let _ = Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2));\n    //~^ manual_is_variant_and\n    let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2));\n    //~^ manual_is_variant_and\n    let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2));\n    //~^ manual_is_variant_and\n\n    // won't fix because the return type of the closure is not `bool`\n    let _ = res.map(|x| x + 1).unwrap_or_default();\n\n    let res2: Result<char, ()> = Ok('a');\n    let _ = res2.is_ok_and(char::is_alphanumeric); // should lint\n    //~^ manual_is_variant_and\n    let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); // should not lint\n}\n\nfn main() {}\n\nfn issue15202() {\n    let xs = [None, Some(b'_'), Some(b'1')];\n    for x in xs {\n        let a1 = x.is_none_or(|b| !b.is_ascii_digit());\n        //~^ manual_is_variant_and\n        let a2 = x.is_none_or(|b| !b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.is_none_or(|b| b.is_ascii_digit());\n        //~^ manual_is_variant_and\n        let a2 = x.is_none_or(|b| b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.is_some_and(|b| b.is_ascii_digit());\n        //~^ manual_is_variant_and\n        let a2 = x.is_some_and(|b| b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.is_some_and(|b| !b.is_ascii_digit());\n        //~^ manual_is_variant_and\n        let a2 = x.is_some_and(|b| !b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    let xs = [Err(\"foo\"), Ok(b'_'), Ok(b'1')];\n    for x in xs {\n        let a1 = !x.is_ok_and(|b| b.is_ascii_digit());\n        //~^ manual_is_variant_and\n        let a2 = !x.is_ok_and(|b| b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = !x.is_ok_and(|b| !b.is_ascii_digit());\n        //~^ manual_is_variant_and\n        let a2 = !x.is_ok_and(|b| !b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.is_ok_and(|b| b.is_ascii_digit());\n        //~^ manual_is_variant_and\n        let a2 = x.is_ok_and(|b| b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.is_ok_and(|b| !b.is_ascii_digit());\n        //~^ manual_is_variant_and\n        let a2 = x.is_ok_and(|b| !b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n}\n\nmod with_func {\n    fn iad(b: u8) -> bool {\n        b.is_ascii_digit()\n    }\n\n    fn check_option(b: Option<u8>) {\n        let a1 = b.is_some_and(iad);\n        //~^ manual_is_variant_and\n        let a2 = b.is_some_and(iad);\n        assert_eq!(a1, a2);\n\n        let a1 = b.is_some_and(|x| !iad(x));\n        //~^ manual_is_variant_and\n        let a2 = b.is_some_and(|x| !iad(x));\n        assert_eq!(a1, a2);\n\n        let a1 = b.is_none_or(|x| !iad(x));\n        //~^ manual_is_variant_and\n        let a2 = b.is_none_or(|x| !iad(x));\n        assert_eq!(a1, a2);\n\n        let a1 = b.is_none_or(iad);\n        //~^ manual_is_variant_and\n        let a2 = b.is_none_or(iad);\n        assert_eq!(a1, a2);\n    }\n\n    fn check_result(b: Result<u8, ()>) {\n        let a1 = b.is_ok_and(iad);\n        //~^ manual_is_variant_and\n        let a2 = b.is_ok_and(iad);\n        assert_eq!(a1, a2);\n\n        let a1 = b.is_ok_and(|x| !iad(x));\n        //~^ manual_is_variant_and\n        let a2 = b.is_ok_and(|x| !iad(x));\n        assert_eq!(a1, a2);\n\n        let a1 = !b.is_ok_and(iad);\n        //~^ manual_is_variant_and\n        let a2 = !b.is_ok_and(iad);\n        assert_eq!(a1, a2);\n\n        let a1 = !b.is_ok_and(|x| !iad(x));\n        //~^ manual_is_variant_and\n        let a2 = !b.is_ok_and(|x| !iad(x));\n        assert_eq!(a1, a2);\n    }\n}\n\nfn issue16419() {\n    let then_fn = |s: &str| s.len() > 3;\n    let opt: Option<&str> = Some(\"test\");\n    let _ = opt.is_none_or(then_fn);\n    //~^ manual_is_variant_and\n\n    let _ = opt.is_none_or(then_fn);\n    //~^ manual_is_variant_and\n}\n\n#[clippy::msrv = \"1.75.0\"]\nfn issue16419_msrv() {\n    let then_fn = |s: &str| s.len() > 3;\n    let opt: Option<&str> = Some(\"test\");\n    let _ = opt.is_none() || opt.is_some_and(then_fn);\n\n    let _ = opt.is_some_and(then_fn) || opt.is_none();\n}\n\nfn issue16518(opt: Option<i32>) {\n    let condition = |x: &i32| *x > 10;\n\n    opt.as_ref().is_some_and(|x| condition(x));\n    //~^ manual_is_variant_and\n    opt.as_ref().is_none_or(|x| !condition(x));\n    //~^ manual_is_variant_and\n}\n\n#[clippy::msrv = \"1.75.0\"]\nfn issue16518_msrv(opt: Option<i32>) {\n    let condition = |x: &i32| *x > 10;\n\n    opt.filter(|x| condition(x)).is_none();\n}\n"
  },
  {
    "path": "tests/ui/manual_is_variant_and.rs",
    "content": "//@aux-build:option_helpers.rs\n#![warn(clippy::manual_is_variant_and)]\n#![allow(clippy::redundant_closure)]\n\n#[macro_use]\nextern crate option_helpers;\n\nstruct Foo<T>(T);\n\nimpl<T> Foo<T> {\n    fn map<F: FnMut(T) -> bool>(self, mut f: F) -> Option<bool> {\n        Some(f(self.0))\n    }\n}\n\nfn foo() -> Option<bool> {\n    Some(true)\n}\n\nmacro_rules! some_true {\n    () => {\n        Some(true)\n    };\n}\nmacro_rules! some_false {\n    () => {\n        Some(false)\n    };\n}\n\nmacro_rules! mac {\n    (some $e:expr) => {\n        Some($e)\n    };\n    (some_map $e:expr) => {\n        Some($e).map(|x| x % 2 == 0)\n    };\n    (map $e:expr) => {\n        $e.map(|x| x % 2 == 0)\n    };\n    (eq $a:expr, $b:expr) => {\n        $a == $b\n    };\n}\n\n#[rustfmt::skip]\nfn option_methods() {\n    let opt = Some(1);\n\n    // Check for `option.map(_).unwrap_or_default()` use.\n    // Single line case.\n    let _ = opt.map(|x| x > 1)\n    //~^ manual_is_variant_and\n        // Should lint even though this call is on a separate line.\n        .unwrap_or_default();\n    // Multi-line cases.\n    let _ = opt.map(|x| {\n    //~^ manual_is_variant_and\n        x > 1\n    }\n    ).unwrap_or_default();\n    let _ = opt.map(|x| x > 1).unwrap_or_default();\n    //~^ manual_is_variant_and\n    let _ = opt\n        .map(|x| x > 1)\n        //~^ manual_is_variant_and\n        .unwrap_or_default();\n\n    let _ = Some(2).map(|x| x % 2 == 0) == Some(true);\n    //~^ manual_is_variant_and\n    let _ = Some(2).map(|x| x % 2 == 0) != Some(true);\n    //~^ manual_is_variant_and\n    let _ = Some(2).map(|x| x % 2 == 0) == some_true!();\n    //~^ manual_is_variant_and\n    let _ = Some(2).map(|x| x % 2 == 0) != some_false!();\n    //~^ manual_is_variant_and\n\n    // won't fix because the return type of the closure is not `bool`\n    let _ = opt.map(|x| x + 1).unwrap_or_default();\n\n    let opt2 = Some('a');\n    let _ = opt2.map(char::is_alphanumeric).unwrap_or_default(); // should lint\n    //~^ manual_is_variant_and\n    let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint\n\n    // Should not lint.\n    let _ = Foo::<u32>(0).map(|x| x.is_multiple_of(2)) == Some(true);\n    let _ = Some(2).map(|x| x % 2 == 0) != foo();\n    let _ = mac!(eq Some(2).map(|x| x % 2 == 0), Some(true));\n    let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true);\n    let _ = mac!(some_map 2) == Some(true);\n    let _ = mac!(map Some(2)) == Some(true);\n}\n\n#[rustfmt::skip]\nfn result_methods() {\n    let res: Result<i32, ()> = Ok(1);\n\n    // multi line cases\n    let _ = res.map(|x| {\n    //~^ manual_is_variant_and\n        x > 1\n    }\n    ).unwrap_or_default();\n    let _ = res.map(|x| x > 1)\n    //~^ manual_is_variant_and\n        .unwrap_or_default();\n\n    let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) == Ok(true);\n    //~^ manual_is_variant_and\n    let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true);\n    //~^ manual_is_variant_and\n    let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true);\n    //~^ manual_is_variant_and\n\n    // won't fix because the return type of the closure is not `bool`\n    let _ = res.map(|x| x + 1).unwrap_or_default();\n\n    let res2: Result<char, ()> = Ok('a');\n    let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint\n    //~^ manual_is_variant_and\n    let _ = opt_map!(res2, |x| x == 'a').unwrap_or_default(); // should not lint\n}\n\nfn main() {}\n\nfn issue15202() {\n    let xs = [None, Some(b'_'), Some(b'1')];\n    for x in xs {\n        let a1 = x.map(|b| b.is_ascii_digit()) != Some(true);\n        //~^ manual_is_variant_and\n        let a2 = x.is_none_or(|b| !b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.map(|b| b.is_ascii_digit()) != Some(false);\n        //~^ manual_is_variant_and\n        let a2 = x.is_none_or(|b| b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.map(|b| b.is_ascii_digit()) == Some(true);\n        //~^ manual_is_variant_and\n        let a2 = x.is_some_and(|b| b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.map(|b| b.is_ascii_digit()) == Some(false);\n        //~^ manual_is_variant_and\n        let a2 = x.is_some_and(|b| !b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    let xs = [Err(\"foo\"), Ok(b'_'), Ok(b'1')];\n    for x in xs {\n        let a1 = x.map(|b| b.is_ascii_digit()) != Ok(true);\n        //~^ manual_is_variant_and\n        let a2 = !x.is_ok_and(|b| b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.map(|b| b.is_ascii_digit()) != Ok(false);\n        //~^ manual_is_variant_and\n        let a2 = !x.is_ok_and(|b| !b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.map(|b| b.is_ascii_digit()) == Ok(true);\n        //~^ manual_is_variant_and\n        let a2 = x.is_ok_and(|b| b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n\n    for x in xs {\n        let a1 = x.map(|b| b.is_ascii_digit()) == Ok(false);\n        //~^ manual_is_variant_and\n        let a2 = x.is_ok_and(|b| !b.is_ascii_digit());\n        assert_eq!(a1, a2);\n    }\n}\n\nmod with_func {\n    fn iad(b: u8) -> bool {\n        b.is_ascii_digit()\n    }\n\n    fn check_option(b: Option<u8>) {\n        let a1 = b.map(iad) == Some(true);\n        //~^ manual_is_variant_and\n        let a2 = b.is_some_and(iad);\n        assert_eq!(a1, a2);\n\n        let a1 = b.map(iad) == Some(false);\n        //~^ manual_is_variant_and\n        let a2 = b.is_some_and(|x| !iad(x));\n        assert_eq!(a1, a2);\n\n        let a1 = b.map(iad) != Some(true);\n        //~^ manual_is_variant_and\n        let a2 = b.is_none_or(|x| !iad(x));\n        assert_eq!(a1, a2);\n\n        let a1 = b.map(iad) != Some(false);\n        //~^ manual_is_variant_and\n        let a2 = b.is_none_or(iad);\n        assert_eq!(a1, a2);\n    }\n\n    fn check_result(b: Result<u8, ()>) {\n        let a1 = b.map(iad) == Ok(true);\n        //~^ manual_is_variant_and\n        let a2 = b.is_ok_and(iad);\n        assert_eq!(a1, a2);\n\n        let a1 = b.map(iad) == Ok(false);\n        //~^ manual_is_variant_and\n        let a2 = b.is_ok_and(|x| !iad(x));\n        assert_eq!(a1, a2);\n\n        let a1 = b.map(iad) != Ok(true);\n        //~^ manual_is_variant_and\n        let a2 = !b.is_ok_and(iad);\n        assert_eq!(a1, a2);\n\n        let a1 = b.map(iad) != Ok(false);\n        //~^ manual_is_variant_and\n        let a2 = !b.is_ok_and(|x| !iad(x));\n        assert_eq!(a1, a2);\n    }\n}\n\nfn issue16419() {\n    let then_fn = |s: &str| s.len() > 3;\n    let opt: Option<&str> = Some(\"test\");\n    let _ = opt.is_none() || opt.is_some_and(then_fn);\n    //~^ manual_is_variant_and\n\n    let _ = opt.is_some_and(then_fn) || opt.is_none();\n    //~^ manual_is_variant_and\n}\n\n#[clippy::msrv = \"1.75.0\"]\nfn issue16419_msrv() {\n    let then_fn = |s: &str| s.len() > 3;\n    let opt: Option<&str> = Some(\"test\");\n    let _ = opt.is_none() || opt.is_some_and(then_fn);\n\n    let _ = opt.is_some_and(then_fn) || opt.is_none();\n}\n\nfn issue16518(opt: Option<i32>) {\n    let condition = |x: &i32| *x > 10;\n\n    opt.filter(|x| condition(x)).is_some();\n    //~^ manual_is_variant_and\n    opt.filter(|x| condition(x)).is_none();\n    //~^ manual_is_variant_and\n}\n\n#[clippy::msrv = \"1.75.0\"]\nfn issue16518_msrv(opt: Option<i32>) {\n    let condition = |x: &i32| *x > 10;\n\n    opt.filter(|x| condition(x)).is_none();\n}\n"
  },
  {
    "path": "tests/ui/manual_is_variant_and.stderr",
    "content": "error: called `map(<f>).unwrap_or_default()` on an `Option` value\n  --> tests/ui/manual_is_variant_and.rs:52:17\n   |\nLL |       let _ = opt.map(|x| x > 1)\n   |  _________________^\n...  |\nLL | |         .unwrap_or_default();\n   | |____________________________^ help: use: `is_some_and(|x| x > 1)`\n   |\n   = note: `-D clippy::manual-is-variant-and` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_is_variant_and)]`\n\nerror: called `map(<f>).unwrap_or_default()` on an `Option` value\n  --> tests/ui/manual_is_variant_and.rs:57:17\n   |\nLL |       let _ = opt.map(|x| {\n   |  _________________^\nLL | |\nLL | |         x > 1\nLL | |     }\nLL | |     ).unwrap_or_default();\n   | |_________________________^\n   |\nhelp: use\n   |\nLL ~     let _ = opt.is_some_and(|x| {\nLL +\nLL +         x > 1\nLL ~     });\n   |\n\nerror: called `map(<f>).unwrap_or_default()` on an `Option` value\n  --> tests/ui/manual_is_variant_and.rs:62:17\n   |\nLL |     let _ = opt.map(|x| x > 1).unwrap_or_default();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(|x| x > 1)`\n\nerror: called `map(<f>).unwrap_or_default()` on an `Option` value\n  --> tests/ui/manual_is_variant_and.rs:65:10\n   |\nLL |           .map(|x| x > 1)\n   |  __________^\nLL | |\nLL | |         .unwrap_or_default();\n   | |____________________________^ help: use: `is_some_and(|x| x > 1)`\n\nerror: called `.map() == Some()`\n  --> tests/ui/manual_is_variant_and.rs:69:13\n   |\nLL |     let _ = Some(2).map(|x| x % 2 == 0) == Some(true);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_some_and(|x| x % 2 == 0)`\n\nerror: called `.map() != Some()`\n  --> tests/ui/manual_is_variant_and.rs:71:13\n   |\nLL |     let _ = Some(2).map(|x| x % 2 == 0) != Some(true);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 != 0)`\n\nerror: called `.map() == Some()`\n  --> tests/ui/manual_is_variant_and.rs:73:13\n   |\nLL |     let _ = Some(2).map(|x| x % 2 == 0) == some_true!();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_some_and(|x| x % 2 == 0)`\n\nerror: called `.map() != Some()`\n  --> tests/ui/manual_is_variant_and.rs:75:13\n   |\nLL |     let _ = Some(2).map(|x| x % 2 == 0) != some_false!();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 == 0)`\n\nerror: called `map(<f>).unwrap_or_default()` on an `Option` value\n  --> tests/ui/manual_is_variant_and.rs:82:18\n   |\nLL |     let _ = opt2.map(char::is_alphanumeric).unwrap_or_default(); // should lint\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_some_and(char::is_alphanumeric)`\n\nerror: called `map(<f>).unwrap_or_default()` on a `Result` value\n  --> tests/ui/manual_is_variant_and.rs:100:17\n   |\nLL |       let _ = res.map(|x| {\n   |  _________________^\nLL | |\nLL | |         x > 1\nLL | |     }\nLL | |     ).unwrap_or_default();\n   | |_________________________^\n   |\nhelp: use\n   |\nLL ~     let _ = res.is_ok_and(|x| {\nLL +\nLL +         x > 1\nLL ~     });\n   |\n\nerror: called `map(<f>).unwrap_or_default()` on a `Result` value\n  --> tests/ui/manual_is_variant_and.rs:105:17\n   |\nLL |       let _ = res.map(|x| x > 1)\n   |  _________________^\nLL | |\nLL | |         .unwrap_or_default();\n   | |____________________________^ help: use: `is_ok_and(|x| x > 1)`\n\nerror: called `.map() == Ok()`\n  --> tests/ui/manual_is_variant_and.rs:109:13\n   |\nLL |     let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) == Ok(true);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))`\n\nerror: called `.map() != Ok()`\n  --> tests/ui/manual_is_variant_and.rs:111:13\n   |\nLL |     let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))`\n\nerror: called `.map() != Ok()`\n  --> tests/ui/manual_is_variant_and.rs:113:13\n   |\nLL |     let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))`\n\nerror: called `map(<f>).unwrap_or_default()` on a `Result` value\n  --> tests/ui/manual_is_variant_and.rs:120:18\n   |\nLL |     let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_ok_and(char::is_alphanumeric)`\n\nerror: called `.map() != Some()`\n  --> tests/ui/manual_is_variant_and.rs:130:18\n   |\nLL |         let a1 = x.map(|b| b.is_ascii_digit()) != Some(true);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| !b.is_ascii_digit())`\n\nerror: called `.map() != Some()`\n  --> tests/ui/manual_is_variant_and.rs:137:18\n   |\nLL |         let a1 = x.map(|b| b.is_ascii_digit()) != Some(false);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| b.is_ascii_digit())`\n\nerror: called `.map() == Some()`\n  --> tests/ui/manual_is_variant_and.rs:144:18\n   |\nLL |         let a1 = x.map(|b| b.is_ascii_digit()) == Some(true);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| b.is_ascii_digit())`\n\nerror: called `.map() == Some()`\n  --> tests/ui/manual_is_variant_and.rs:151:18\n   |\nLL |         let a1 = x.map(|b| b.is_ascii_digit()) == Some(false);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| !b.is_ascii_digit())`\n\nerror: called `.map() != Ok()`\n  --> tests/ui/manual_is_variant_and.rs:159:18\n   |\nLL |         let a1 = x.map(|b| b.is_ascii_digit()) != Ok(true);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| b.is_ascii_digit())`\n\nerror: called `.map() != Ok()`\n  --> tests/ui/manual_is_variant_and.rs:166:18\n   |\nLL |         let a1 = x.map(|b| b.is_ascii_digit()) != Ok(false);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| !b.is_ascii_digit())`\n\nerror: called `.map() == Ok()`\n  --> tests/ui/manual_is_variant_and.rs:173:18\n   |\nLL |         let a1 = x.map(|b| b.is_ascii_digit()) == Ok(true);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| b.is_ascii_digit())`\n\nerror: called `.map() == Ok()`\n  --> tests/ui/manual_is_variant_and.rs:180:18\n   |\nLL |         let a1 = x.map(|b| b.is_ascii_digit()) == Ok(false);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| !b.is_ascii_digit())`\n\nerror: called `.map() == Some()`\n  --> tests/ui/manual_is_variant_and.rs:193:18\n   |\nLL |         let a1 = b.map(iad) == Some(true);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(iad)`\n\nerror: called `.map() == Some()`\n  --> tests/ui/manual_is_variant_and.rs:198:18\n   |\nLL |         let a1 = b.map(iad) == Some(false);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(|x| !iad(x))`\n\nerror: called `.map() != Some()`\n  --> tests/ui/manual_is_variant_and.rs:203:18\n   |\nLL |         let a1 = b.map(iad) != Some(true);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(|x| !iad(x))`\n\nerror: called `.map() != Some()`\n  --> tests/ui/manual_is_variant_and.rs:208:18\n   |\nLL |         let a1 = b.map(iad) != Some(false);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(iad)`\n\nerror: called `.map() == Ok()`\n  --> tests/ui/manual_is_variant_and.rs:215:18\n   |\nLL |         let a1 = b.map(iad) == Ok(true);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(iad)`\n\nerror: called `.map() == Ok()`\n  --> tests/ui/manual_is_variant_and.rs:220:18\n   |\nLL |         let a1 = b.map(iad) == Ok(false);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(|x| !iad(x))`\n\nerror: called `.map() != Ok()`\n  --> tests/ui/manual_is_variant_and.rs:225:18\n   |\nLL |         let a1 = b.map(iad) != Ok(true);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(iad)`\n\nerror: called `.map() != Ok()`\n  --> tests/ui/manual_is_variant_and.rs:230:18\n   |\nLL |         let a1 = b.map(iad) != Ok(false);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(|x| !iad(x))`\n\nerror: manual implementation of `Option::is_none_or`\n  --> tests/ui/manual_is_variant_and.rs:240:13\n   |\nLL |     let _ = opt.is_none() || opt.is_some_and(then_fn);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `opt.is_none_or(then_fn)`\n\nerror: manual implementation of `Option::is_none_or`\n  --> tests/ui/manual_is_variant_and.rs:243:13\n   |\nLL |     let _ = opt.is_some_and(then_fn) || opt.is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `opt.is_none_or(then_fn)`\n\nerror: manual implementation of `Option::is_some_and`\n  --> tests/ui/manual_is_variant_and.rs:259:5\n   |\nLL |     opt.filter(|x| condition(x)).is_some();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `opt.as_ref().is_some_and(|x| condition(x))`\n\nerror: manual implementation of `Option::is_none_or`\n  --> tests/ui/manual_is_variant_and.rs:261:5\n   |\nLL |     opt.filter(|x| condition(x)).is_none();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `opt.as_ref().is_none_or(|x| !condition(x))`\n\nerror: aborting due to 35 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_let_else.rs",
    "content": "#![feature(try_blocks)]\n#![allow(unused_braces, unused_variables, dead_code)]\n#![allow(\n    clippy::collapsible_else_if,\n    clippy::unused_unit,\n    clippy::let_unit_value,\n    clippy::match_single_binding,\n    clippy::never_loop,\n    clippy::needless_ifs,\n    clippy::diverging_sub_expression,\n    clippy::single_match,\n    clippy::manual_unwrap_or_default\n)]\n#![warn(clippy::manual_let_else)]\n//@no-rustfix\nenum Variant {\n    A(usize, usize),\n    B(usize),\n    C,\n}\n\nfn g() -> Option<()> {\n    None\n}\n\nfn main() {}\n\nfn fire() {\n    let v = if let Some(v_some) = g() { v_some } else { return };\n    //~^ manual_let_else\n\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        return;\n    };\n\n    let v = if let Some(v) = g() {\n        //~^ manual_let_else\n\n        // Blocks around the identity should have no impact\n        { { v } }\n    } else {\n        // Some computation should still make it fire\n        g();\n        return;\n    };\n\n    // continue and break diverge\n    loop {\n        let v = if let Some(v_some) = g() { v_some } else { continue };\n        //~^ manual_let_else\n\n        let v = if let Some(v_some) = g() { v_some } else { break };\n        //~^ manual_let_else\n    }\n\n    // panic also diverges\n    let v = if let Some(v_some) = g() { v_some } else { panic!() };\n    //~^ manual_let_else\n\n    // abort also diverges\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        std::process::abort()\n    };\n\n    // If whose two branches diverge also diverges\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        if true { return } else { panic!() }\n    };\n\n    // Diverging after an if still makes the block diverge:\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        if true {}\n        panic!();\n    };\n\n    // The final expression will need to be turned into a statement.\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        panic!();\n        ()\n    };\n\n    // Even if the result is buried multiple expressions deep.\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        panic!();\n        if true {\n            match 0 {\n                0 => (),\n                _ => (),\n            }\n        } else {\n            panic!()\n        }\n    };\n\n    // Or if a break gives the value.\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        loop {\n            panic!();\n            break ();\n        }\n    };\n\n    // Even if the break is in a weird position.\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        'a: loop {\n            panic!();\n            loop {\n                match 0 {\n                    0 if (return break 'a ()) => {},\n                    _ => {},\n                }\n            }\n        }\n    };\n\n    // A match diverges if all branches diverge:\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        match 0 {\n            0 if true => panic!(),\n            _ => panic!(),\n        };\n    };\n\n    // An if's expression can cause divergence:\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        if panic!() {};\n    };\n\n    // An expression of a match can cause divergence:\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        match panic!() {\n            _ => {},\n        };\n    };\n\n    // Top level else if\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else if true {\n        return;\n    } else {\n        panic!(\"diverge\");\n    };\n\n    // All match arms diverge\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        match (g(), g()) {\n            (Some(_), None) => return,\n            (None, Some(_)) => {\n                if true {\n                    return;\n                } else {\n                    panic!();\n                }\n            },\n            _ => return,\n        }\n    };\n\n    // Tuples supported for the declared variables\n    let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) {\n        //~^ manual_let_else\n\n        v_some\n    } else {\n        return;\n    };\n\n    // Tuples supported with multiple bindings\n    let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) {\n        //~^ manual_let_else\n\n        (w_some, v_some)\n    } else {\n        return;\n    };\n\n    // entirely inside macro lints\n    macro_rules! create_binding_if_some {\n        ($n:ident, $e:expr) => {\n            let $n = if let Some(v) = $e { v } else { return };\n            //~^ manual_let_else\n        };\n    }\n    create_binding_if_some!(w, g());\n\n    fn e() -> Variant {\n        Variant::A(0, 0)\n    }\n\n    let v = if let Variant::A(a, 0) = e() { a } else { return };\n    //~^ manual_let_else\n\n    // `mut v` is inserted into the pattern\n    let mut v = if let Variant::B(b) = e() { b } else { return };\n    //~^ manual_let_else\n\n    // Nesting works\n    let nested = Ok(Some(e()));\n    let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested {\n        //~^ manual_let_else\n\n        b\n    } else {\n        return;\n    };\n    // dot dot works\n    let v = if let Variant::A(.., a) = e() { a } else { return };\n    //~^ manual_let_else\n\n    // () is preserved: a bit of an edge case but make sure it stays around\n    let w = if let (Some(v), ()) = (g(), ()) { v } else { return };\n    //~^ manual_let_else\n\n    // Tuple structs work\n    let w = if let Some(S { v: x }) = Some(S { v: 0 }) {\n        //~^ manual_let_else\n\n        x\n    } else {\n        return;\n    };\n\n    // Field init shorthand is suggested\n    let v = if let Some(S { v: x }) = Some(S { v: 0 }) {\n        //~^ manual_let_else\n\n        x\n    } else {\n        return;\n    };\n\n    // Multi-field structs also work\n    let (x, S { v }, w) = if let Some(U { v, w, x }) = None::<U<S<()>>> {\n        //~^ manual_let_else\n\n        (x, v, w)\n    } else {\n        return;\n    };\n}\n\nfn not_fire() {\n    let v = if let Some(v_some) = g() {\n        // Nothing returned. Should not fire.\n    } else {\n        return;\n    };\n\n    let w = 0;\n    let v = if let Some(v_some) = g() {\n        // Different variable than v_some. Should not fire.\n        w\n    } else {\n        return;\n    };\n\n    let v = if let Some(v_some) = g() {\n        // Computation in then clause. Should not fire.\n        g();\n        v_some\n    } else {\n        return;\n    };\n\n    let v = if let Some(v_some) = g() {\n        v_some\n    } else {\n        if false {\n            return;\n        }\n        // This doesn't diverge. Should not fire.\n        ()\n    };\n\n    let v = if let Some(v_some) = g() {\n        v_some\n    } else {\n        // There is one match arm that doesn't diverge. Should not fire.\n        match (g(), g()) {\n            (Some(_), None) => return,\n            (None, Some(_)) => return,\n            (Some(_), Some(_)) => (),\n            _ => return,\n        }\n    };\n\n    let v = if let Some(v_some) = g() {\n        v_some\n    } else {\n        // loop with a break statement inside does not diverge.\n        loop {\n            break;\n        }\n    };\n\n    enum Uninhabited {}\n    fn un() -> Uninhabited {\n        panic!()\n    }\n    let v = if let Some(v_some) = None {\n        v_some\n    } else {\n        // Don't lint if the type is uninhabited but not !\n        un()\n    };\n\n    fn question_mark() -> Option<()> {\n        let v = if let Some(v) = g() {\n            v\n        } else {\n            // Question mark does not diverge\n            g()?\n        };\n        Some(v)\n    }\n\n    // Macro boundary inside let\n    macro_rules! some_or_return {\n        ($e:expr) => {\n            if let Some(v) = $e { v } else { return }\n        };\n    }\n    let v = some_or_return!(g());\n\n    // Also macro boundary inside let, but inside a macro\n    macro_rules! create_binding_if_some_nf {\n        ($n:ident, $e:expr) => {\n            let $n = some_or_return!($e);\n        };\n    }\n    create_binding_if_some_nf!(v, g());\n\n    // Already a let-else\n    let Some(a) = (if let Some(b) = Some(Some(())) { b } else { return }) else {\n        panic!()\n    };\n\n    // If a type annotation is present, don't lint as\n    // expressing the type might be too hard\n    let v: () = if let Some(v_some) = g() { v_some } else { panic!() };\n\n    // Issue 9940\n    // Suggestion should not expand macros\n    macro_rules! macro_call {\n        () => {\n            return ()\n        };\n    }\n\n    let ff = Some(1);\n    let _ = match ff {\n        //~^ manual_let_else\n        Some(value) => value,\n        _ => macro_call!(),\n    };\n\n    // Issue 10296\n    // The let/else block in the else part is not divergent despite the presence of return\n    let _x = if let Some(x) = Some(1) {\n        x\n    } else {\n        let Some(_z) = Some(3) else { return };\n        1\n    };\n\n    // This would require creation of a suggestion of the form\n    // let v @ (Some(_), _) = (...) else { return };\n    // Which is too advanced for our code, so we just bail.\n    let v = if let (Some(v_some), w_some) = (g(), 0) {\n        (w_some, v_some)\n    } else {\n        return;\n    };\n\n    // A break that skips the divergent statement will cause the expression to be non-divergent.\n    let _x = if let Some(x) = Some(0) {\n        x\n    } else {\n        'foo: loop {\n            break 'foo 0;\n            panic!();\n        }\n    };\n\n    // Even in inner loops.\n    let _x = if let Some(x) = Some(0) {\n        x\n    } else {\n        'foo: {\n            loop {\n                break 'foo 0;\n            }\n            panic!();\n        }\n    };\n\n    // But a break that can't ever be reached still affects divergence checking.\n    let _x = if let Some(x) = g() {\n        x\n    } else {\n        'foo: {\n            'bar: loop {\n                loop {\n                    break 'bar ();\n                }\n                break 'foo ();\n            }\n            panic!();\n        };\n    };\n}\n\nstruct S<T> {\n    v: T,\n}\n\nstruct U<T> {\n    v: T,\n    w: T,\n    x: T,\n}\n\nfn issue12337() {\n    // We want to generally silence question_mark lints within try blocks, since `?` has different\n    // behavior to `return`, and question_mark calls into manual_let_else logic, so make sure that\n    // we still emit a lint for manual_let_else\n    let _: Option<()> = try {\n        let v = if let Some(v_some) = g() { v_some } else { return };\n        //~^ manual_let_else\n    };\n}\n\nmod issue13768 {\n    enum Foo {\n        Str(String),\n        None,\n    }\n\n    fn foo(value: Foo) {\n        let signature = match value {\n            //~^ manual_let_else\n            Foo::Str(ref val) => val,\n            _ => {\n                println!(\"No signature found\");\n                return;\n            },\n        };\n    }\n\n    enum Bar {\n        Str { inner: String },\n        None,\n    }\n\n    fn bar(mut value: Bar) {\n        let signature = match value {\n            //~^ manual_let_else\n            Bar::Str { ref mut inner } => inner,\n            _ => {\n                println!(\"No signature found\");\n                return;\n            },\n        };\n    }\n}\n\nmod issue14598 {\n    fn bar() -> Result<bool, &'static str> {\n        let value = match foo() {\n            //~^ manual_let_else\n            Err(_) => return Err(\"abc\"),\n            Ok(value) => value,\n        };\n\n        let w = Some(0);\n        let v = match w {\n            //~^ manual_let_else\n            None => return Err(\"abc\"),\n            Some(x) => x,\n        };\n\n        enum Foo<T> {\n            Foo(T),\n        }\n\n        let v = match Foo::Foo(Some(())) {\n            Foo::Foo(Some(_)) => return Err(\"abc\"),\n            Foo::Foo(v) => v,\n        };\n\n        Ok(value == 42)\n    }\n\n    fn foo() -> Result<u32, &'static str> {\n        todo!()\n    }\n}\n\nmod issue15914 {\n    // https://github.com/rust-lang/rust-clippy/issues/15914\n    unsafe fn something_unsafe() -> Option<u32> {\n        None\n    }\n\n    fn foo() {\n        let value = if let Some(value) = unsafe { something_unsafe() } {\n            //~^ manual_let_else\n            value\n        } else {\n            return;\n        };\n\n        let some_flag = true;\n\n        let value = if let Some(value) = if some_flag { None } else { Some(3) } {\n            //~^ manual_let_else\n            value\n        } else {\n            return;\n        };\n    }\n}\n\nfn issue16602(i: Result<i32, i32>) {\n    //~v manual_let_else\n    _ = match i {\n        Ok(i) => i,\n        Err(_) => unsafe {\n            core::hint::unreachable_unchecked();\n        },\n    };\n\n    //~v manual_let_else\n    _ = match i {\n        Ok(i) => i,\n        Err(_) => 'useless_label: {\n            panic!();\n        },\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_let_else.stderr",
    "content": "error: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:29:5\n   |\nLL |     let v = if let Some(v_some) = g() { v_some } else { return };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`\n   |\n   = note: `-D clippy::manual-let-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:32:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\nLL | |     } else {\nLL | |         return;\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         return;\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:40:5\n   |\nLL | /     let v = if let Some(v) = g() {\n...  |\nLL | |         return;\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         // Some computation should still make it fire\nLL +         g();\nLL +         return;\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:53:9\n   |\nLL |         let v = if let Some(v_some) = g() { v_some } else { continue };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:56:9\n   |\nLL |         let v = if let Some(v_some) = g() { v_some } else { break };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:61:5\n   |\nLL |     let v = if let Some(v_some) = g() { v_some } else { panic!() };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:65:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\nLL | |     } else {\nLL | |         std::process::abort()\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         std::process::abort()\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:74:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\nLL | |     } else {\nLL | |         if true { return } else { panic!() }\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         if true { return } else { panic!() }\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:83:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |         panic!();\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         if true {}\nLL +         panic!();\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:93:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |         ()\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         panic!();\nLL +         ()\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:103:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         panic!();\nLL +         if true {\nLL +             match 0 {\nLL +                 0 => (),\nLL +                 _ => (),\nLL +             }\nLL +         } else {\nLL +             panic!()\nLL +         }\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:120:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         loop {\nLL +             panic!();\nLL +             break ();\nLL +         }\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:132:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         'a: loop {\nLL +             panic!();\nLL +             loop {\nLL +                 match 0 {\nLL +                     0 if (return break 'a ()) => {},\nLL +                     _ => {},\nLL +                 }\nLL +             }\nLL +         }\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:149:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |         };\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         match 0 {\nLL +             0 if true => panic!(),\nLL +             _ => panic!(),\nLL +         };\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:161:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\nLL | |     } else {\nLL | |         if panic!() {};\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         if panic!() {};\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:170:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |         };\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         match panic!() {\nLL +             _ => {},\nLL +         };\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:181:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |         panic!(\"diverge\");\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else { if true {\nLL +         return;\nLL +     } else {\nLL +         panic!(\"diverge\");\nLL +     } };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:192:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |\nLL | |         v_some\n...  |\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         match (g(), g()) {\nLL +             (Some(_), None) => return,\nLL +             (None, Some(_)) => {\nLL +                 if true {\nLL +                     return;\nLL +                 } else {\nLL +                     panic!();\nLL +                 }\nLL +             },\nLL +             _ => return,\nLL +         }\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:211:5\n   |\nLL | /     let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) {\nLL | |\nLL | |\nLL | |         v_some\nLL | |     } else {\nLL | |         return;\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some((v, w)) = g().map(|v| (v, 42)) else {\nLL +         return;\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:220:5\n   |\nLL | /     let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) {\nLL | |\nLL | |\nLL | |         (w_some, v_some)\nLL | |     } else {\nLL | |         return;\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let (Some(S { v }), w) = (g().map(|_| S { v: 0 }), 0) else {\nLL +         return;\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:231:13\n   |\nLL |             let $n = if let Some(v) = $e { v } else { return };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };`\n...\nLL |     create_binding_if_some!(w, g());\n   |     ------------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:241:5\n   |\nLL |     let v = if let Variant::A(a, 0) = e() { a } else { return };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:245:5\n   |\nLL |     let mut v = if let Variant::B(b) = e() { b } else { return };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:250:5\n   |\nLL | /     let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested {\nLL | |\nLL | |\nLL | |         b\nLL | |     } else {\nLL | |         return;\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let (Ok(Some(Variant::B(v))) | Err(Some(Variant::A(v, _)))) = nested else {\nLL +         return;\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:258:5\n   |\nLL |     let v = if let Variant::A(.., a) = e() { a } else { return };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:262:5\n   |\nLL |     let w = if let (Some(v), ()) = (g(), ()) { v } else { return };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:266:5\n   |\nLL | /     let w = if let Some(S { v: x }) = Some(S { v: 0 }) {\nLL | |\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         return;\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(S { v: w }) = Some(S { v: 0 }) else {\nLL +         return;\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:275:5\n   |\nLL | /     let v = if let Some(S { v: x }) = Some(S { v: 0 }) {\nLL | |\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         return;\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(S { v }) = Some(S { v: 0 }) else {\nLL +         return;\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:284:5\n   |\nLL | /     let (x, S { v }, w) = if let Some(U { v, w, x }) = None::<U<S<()>>> {\nLL | |\nLL | |\nLL | |         (x, v, w)\nLL | |     } else {\nLL | |         return;\nLL | |     };\n   | |______^\n   |\nhelp: consider writing\n   |\nLL ~     let Some(U { v: S { v }, w, x }) = None::<U<S<()>>> else {\nLL +         return;\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:402:5\n   |\nLL | /     let _ = match ff {\nLL | |\nLL | |         Some(value) => value,\nLL | |         _ => macro_call!(),\nLL | |     };\n   | |______^ help: consider writing: `let Some(_) = ff else { macro_call!() };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:479:9\n   |\nLL |         let v = if let Some(v_some) = g() { v_some } else { return };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:491:9\n   |\nLL | /         let signature = match value {\nLL | |\nLL | |             Foo::Str(ref val) => val,\nLL | |             _ => {\n...  |\nLL | |             },\nLL | |         };\n   | |__________^\n   |\nhelp: consider writing\n   |\nLL ~         let Foo::Str(ref signature) = value else {\nLL +                 println!(\"No signature found\");\nLL +                 return;\nLL +             };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:507:9\n   |\nLL | /         let signature = match value {\nLL | |\nLL | |             Bar::Str { ref mut inner } => inner,\nLL | |             _ => {\n...  |\nLL | |             },\nLL | |         };\n   | |__________^\n   |\nhelp: consider writing\n   |\nLL ~         let Bar::Str { inner: ref mut signature } = value else {\nLL +                 println!(\"No signature found\");\nLL +                 return;\nLL +             };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:520:9\n   |\nLL | /         let value = match foo() {\nLL | |\nLL | |             Err(_) => return Err(\"abc\"),\nLL | |             Ok(value) => value,\nLL | |         };\n   | |__________^ help: consider writing: `let Ok(value) = foo() else { return Err(\"abc\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:527:9\n   |\nLL | /         let v = match w {\nLL | |\nLL | |             None => return Err(\"abc\"),\nLL | |             Some(x) => x,\nLL | |         };\n   | |__________^ help: consider writing: `let Some(v) = w else { return Err(\"abc\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:557:9\n   |\nLL | /         let value = if let Some(value) = unsafe { something_unsafe() } {\nLL | |\nLL | |             value\nLL | |         } else {\nLL | |             return;\nLL | |         };\n   | |__________^\n   |\nhelp: consider writing\n   |\nLL ~         let Some(value) = (unsafe { something_unsafe() }) else {\nLL +             return;\nLL +         };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:566:9\n   |\nLL | /         let value = if let Some(value) = if some_flag { None } else { Some(3) } {\nLL | |\nLL | |             value\nLL | |         } else {\nLL | |             return;\nLL | |         };\n   | |__________^\n   |\nhelp: consider writing\n   |\nLL ~         let Some(value) = (if some_flag { None } else { Some(3) }) else {\nLL +             return;\nLL +         };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:577:5\n   |\nLL | /     _ = match i {\nLL | |         Ok(i) => i,\nLL | |         Err(_) => unsafe {\nLL | |             core::hint::unreachable_unchecked();\nLL | |         },\nLL | |     };\n   | |_____^\n   |\nhelp: consider writing\n   |\nLL ~     let Ok(_) = i else { unsafe {\nLL +             core::hint::unreachable_unchecked();\nLL ~         } };;\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else.rs:585:5\n   |\nLL | /     _ = match i {\nLL | |         Ok(i) => i,\nLL | |         Err(_) => 'useless_label: {\nLL | |             panic!();\nLL | |         },\nLL | |     };\n   | |_____^\n   |\nhelp: consider writing\n   |\nLL ~     let Ok(_) = i else { 'useless_label: {\nLL +             panic!();\nLL ~         } };;\n   |\n\nerror: aborting due to 39 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_let_else_match.fixed",
    "content": "#![allow(unused_braces, unused_variables, dead_code, irrefutable_let_patterns)]\n#![allow(\n    clippy::collapsible_else_if,\n    clippy::let_unit_value,\n    clippy::redundant_at_rest_pattern\n)]\n#![warn(clippy::manual_let_else)]\n// Ensure that we don't conflict with match -> if let lints\n#![warn(clippy::single_match_else, clippy::single_match)]\n\nfn f() -> Result<u32, u32> {\n    Ok(0)\n}\n\nfn g() -> Option<()> {\n    None\n}\n\nfn h() -> (Option<()>, Option<()>) {\n    (None, None)\n}\n\nenum Variant {\n    Foo,\n    Bar(u32),\n    Baz(u32),\n}\n\nfn build_enum() -> Variant {\n    Variant::Foo\n}\n\nfn main() {}\n\nfn fire() {\n    let Some(v) = g() else { return };\n\n    let Some(v) = g() else { return };\n\n    loop {\n        // More complex pattern for the identity arm and diverging arm\n        let ((Some(v), None) | (None, Some(v))) = h() else { continue };\n        // Custom enums are supported as long as the \"else\" arm is a simple _\n        let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };\n    }\n\n    // There is a _ in the diverging arm\n    // TODO also support unused bindings aka _v\n    let Ok(v) = f() else { return };\n\n    // Err(()) is an allowed pattern\n    let Ok(v) = f().map_err(|_| ()) else { return };\n\n    let f = Variant::Bar(1);\n\n    let (Variant::Bar(_value) | Variant::Baz(_value)) = f else { return };\n\n    let Some(Variant::Bar(_value) | Variant::Baz(_value)) = Some(build_enum()) else { return };\n\n    let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];\n    let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };\n}\n\nfn not_fire() {\n    // Multiple diverging arms\n    let v = match h() {\n        _ => panic!(),\n        (None, Some(_v)) => return,\n        (Some(v), None) => v,\n    };\n\n    // Multiple identity arms\n    let v = match h() {\n        _ => panic!(),\n        (None, Some(v)) => v,\n        (Some(v), None) => v,\n    };\n\n    // No diverging arm at all, only identity arms.\n    // This is no case for let else, but destructuring assignment.\n    let v = match f() {\n        Ok(v) => v,\n        Err(e) => e,\n    };\n\n    // The identity arm has a guard\n    let v = match g() {\n        Some(v) if g().is_none() => v,\n        _ => return,\n    };\n\n    // The diverging arm has a guard\n    let v = match f() {\n        Err(v) if v > 0 => panic!(),\n        Ok(v) | Err(v) => v,\n    };\n\n    // The diverging arm creates a binding\n    let v = match f() {\n        Ok(v) => v,\n        Err(e) => panic!(\"error: {e}\"),\n    };\n\n    // Custom enum where the diverging arm\n    // explicitly mentions the variant\n    let v = match build_enum() {\n        Variant::Foo => return,\n        Variant::Bar(v) | Variant::Baz(v) => v,\n    };\n\n    // The custom enum is surrounded by an Err()\n    let v = match Err(build_enum()) {\n        Ok(v) | Err(Variant::Bar(v) | Variant::Baz(v)) => v,\n        Err(Variant::Foo) => return,\n    };\n\n    // Issue 10241\n    // The non-divergent arm arrives in second position and\n    // may cover values already matched in the first arm.\n    let v = match h() {\n        (Some(_), Some(_)) | (None, None) => return,\n        (Some(v), _) | (None, Some(v)) => v,\n    };\n\n    let v = match build_enum() {\n        _ => return,\n        Variant::Bar(v) | Variant::Baz(v) => v,\n    };\n\n    let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];\n    let data = match data.as_slice() {\n        [] | [0, 0] => return,\n        [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data,\n    };\n}\n\nfn issue11579() {\n    let Some(msg) = Some(\"hi\") else { unreachable!(\"can't happen\") };\n}\n\n#[derive(Clone, Copy)]\nstruct Issue9939<T> {\n    avalanche: T,\n}\n\nfn issue9939() {\n    let issue = Some(Issue9939 { avalanche: 1 });\n    let Some(Issue9939 { avalanche: tornado }) = issue else { unreachable!(\"can't happen\") };\n    let issue = Some(Issue9939 { avalanche: true });\n    let Some(Issue9939 { avalanche: acid_rain }) = issue else { unreachable!(\"can't happen\") };\n    assert_eq!(tornado, 1);\n    assert!(acid_rain);\n\n    // without shadowing\n    let _x @ Some(Issue9939 { avalanche: _y }) = issue else { unreachable!(\"can't happen\") };\n\n    // with shadowing\n    let Some(Issue9939 { avalanche: _x }) = issue else { unreachable!(\"can't happen\") };\n}\n\n#[derive(Clone, Copy)]\nstruct Issue9939b<T, U> {\n    earthquake: T,\n    hurricane: U,\n}\n\nfn issue9939b() {\n    let issue = Some(Issue9939b {\n        earthquake: true,\n        hurricane: 1,\n    });\n    let issue @ Some(Issue9939b { earthquake: flood, hurricane: drought }) = issue else { unreachable!(\"can't happen\") };\n    assert_eq!(drought, 1);\n    assert!(flood);\n    assert!(issue.is_some());\n\n    // without shadowing\n    let _x @ Some(Issue9939b { earthquake: erosion, hurricane: _y }) = issue else { unreachable!(\"can't happen\") };\n    assert!(erosion);\n\n    // with shadowing\n    let Some(Issue9939b { earthquake: erosion, hurricane: _x }) = issue else { unreachable!(\"can't happen\") };\n    assert!(erosion);\n}\n\nmod issue16433 {\n    // https://github.com/rust-lang/rust-clippy/issues/16433\n    struct A {\n        a: u32,\n        b: u32,\n    }\n\n    fn foo() {\n        let a = A { a: 1, b: 1 };\n        let A { a: first_arg, .. } = a else { return };\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_let_else_match.rs",
    "content": "#![allow(unused_braces, unused_variables, dead_code, irrefutable_let_patterns)]\n#![allow(\n    clippy::collapsible_else_if,\n    clippy::let_unit_value,\n    clippy::redundant_at_rest_pattern\n)]\n#![warn(clippy::manual_let_else)]\n// Ensure that we don't conflict with match -> if let lints\n#![warn(clippy::single_match_else, clippy::single_match)]\n\nfn f() -> Result<u32, u32> {\n    Ok(0)\n}\n\nfn g() -> Option<()> {\n    None\n}\n\nfn h() -> (Option<()>, Option<()>) {\n    (None, None)\n}\n\nenum Variant {\n    Foo,\n    Bar(u32),\n    Baz(u32),\n}\n\nfn build_enum() -> Variant {\n    Variant::Foo\n}\n\nfn main() {}\n\nfn fire() {\n    let v = match g() {\n        //~^ manual_let_else\n        Some(v_some) => v_some,\n        None => return,\n    };\n\n    let v = match g() {\n        //~^ manual_let_else\n        Some(v_some) => v_some,\n        _ => return,\n    };\n\n    loop {\n        // More complex pattern for the identity arm and diverging arm\n        let v = match h() {\n            //~^ manual_let_else\n            (Some(v), None) | (None, Some(v)) => v,\n            (Some(_), Some(_)) | (None, None) => continue,\n        };\n        // Custom enums are supported as long as the \"else\" arm is a simple _\n        let v = match build_enum() {\n            //~^ manual_let_else\n            Variant::Bar(v) | Variant::Baz(v) => v,\n            _ => continue,\n        };\n    }\n\n    // There is a _ in the diverging arm\n    // TODO also support unused bindings aka _v\n    let v = match f() {\n        //~^ manual_let_else\n        Ok(v) => v,\n        Err(_) => return,\n    };\n\n    // Err(()) is an allowed pattern\n    let v = match f().map_err(|_| ()) {\n        //~^ manual_let_else\n        Ok(v) => v,\n        Err(()) => return,\n    };\n\n    let f = Variant::Bar(1);\n\n    let _value = match f {\n        //~^ manual_let_else\n        Variant::Bar(v) | Variant::Baz(v) => v,\n        _ => return,\n    };\n\n    let _value = match Some(build_enum()) {\n        //~^ manual_let_else\n        Some(Variant::Bar(v) | Variant::Baz(v)) => v,\n        _ => return,\n    };\n\n    let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];\n    let data = match data.as_slice() {\n        //~^ manual_let_else\n        [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data,\n        _ => return,\n    };\n}\n\nfn not_fire() {\n    // Multiple diverging arms\n    let v = match h() {\n        _ => panic!(),\n        (None, Some(_v)) => return,\n        (Some(v), None) => v,\n    };\n\n    // Multiple identity arms\n    let v = match h() {\n        _ => panic!(),\n        (None, Some(v)) => v,\n        (Some(v), None) => v,\n    };\n\n    // No diverging arm at all, only identity arms.\n    // This is no case for let else, but destructuring assignment.\n    let v = match f() {\n        Ok(v) => v,\n        Err(e) => e,\n    };\n\n    // The identity arm has a guard\n    let v = match g() {\n        Some(v) if g().is_none() => v,\n        _ => return,\n    };\n\n    // The diverging arm has a guard\n    let v = match f() {\n        Err(v) if v > 0 => panic!(),\n        Ok(v) | Err(v) => v,\n    };\n\n    // The diverging arm creates a binding\n    let v = match f() {\n        Ok(v) => v,\n        Err(e) => panic!(\"error: {e}\"),\n    };\n\n    // Custom enum where the diverging arm\n    // explicitly mentions the variant\n    let v = match build_enum() {\n        Variant::Foo => return,\n        Variant::Bar(v) | Variant::Baz(v) => v,\n    };\n\n    // The custom enum is surrounded by an Err()\n    let v = match Err(build_enum()) {\n        Ok(v) | Err(Variant::Bar(v) | Variant::Baz(v)) => v,\n        Err(Variant::Foo) => return,\n    };\n\n    // Issue 10241\n    // The non-divergent arm arrives in second position and\n    // may cover values already matched in the first arm.\n    let v = match h() {\n        (Some(_), Some(_)) | (None, None) => return,\n        (Some(v), _) | (None, Some(v)) => v,\n    };\n\n    let v = match build_enum() {\n        _ => return,\n        Variant::Bar(v) | Variant::Baz(v) => v,\n    };\n\n    let data = [1_u8, 2, 3, 4, 0, 0, 0, 0];\n    let data = match data.as_slice() {\n        [] | [0, 0] => return,\n        [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data,\n    };\n}\n\nfn issue11579() {\n    let msg = match Some(\"hi\") {\n        //~^ manual_let_else\n        Some(m) => m,\n        _ => unreachable!(\"can't happen\"),\n    };\n}\n\n#[derive(Clone, Copy)]\nstruct Issue9939<T> {\n    avalanche: T,\n}\n\nfn issue9939() {\n    let issue = Some(Issue9939 { avalanche: 1 });\n    let tornado = match issue {\n        //~^ manual_let_else\n        Some(Issue9939 { avalanche }) => avalanche,\n        _ => unreachable!(\"can't happen\"),\n    };\n    let issue = Some(Issue9939 { avalanche: true });\n    let acid_rain = match issue {\n        //~^ manual_let_else\n        Some(Issue9939 { avalanche: tornado }) => tornado,\n        _ => unreachable!(\"can't happen\"),\n    };\n    assert_eq!(tornado, 1);\n    assert!(acid_rain);\n\n    // without shadowing\n    let _y = match issue {\n        //~^ manual_let_else\n        _x @ Some(Issue9939 { avalanche }) => avalanche,\n        None => unreachable!(\"can't happen\"),\n    };\n\n    // with shadowing\n    let _x = match issue {\n        //~^ manual_let_else\n        _x @ Some(Issue9939 { avalanche }) => avalanche,\n        None => unreachable!(\"can't happen\"),\n    };\n}\n\n#[derive(Clone, Copy)]\nstruct Issue9939b<T, U> {\n    earthquake: T,\n    hurricane: U,\n}\n\nfn issue9939b() {\n    let issue = Some(Issue9939b {\n        earthquake: true,\n        hurricane: 1,\n    });\n    let (issue, drought, flood) = match issue {\n        //~^ manual_let_else\n        flood @ Some(Issue9939b { earthquake, hurricane }) => (flood, hurricane, earthquake),\n        None => unreachable!(\"can't happen\"),\n    };\n    assert_eq!(drought, 1);\n    assert!(flood);\n    assert!(issue.is_some());\n\n    // without shadowing\n    let (_y, erosion) = match issue {\n        //~^ manual_let_else\n        _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),\n        None => unreachable!(\"can't happen\"),\n    };\n    assert!(erosion);\n\n    // with shadowing\n    let (_x, erosion) = match issue {\n        //~^ manual_let_else\n        _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),\n        None => unreachable!(\"can't happen\"),\n    };\n    assert!(erosion);\n}\n\nmod issue16433 {\n    // https://github.com/rust-lang/rust-clippy/issues/16433\n    struct A {\n        a: u32,\n        b: u32,\n    }\n\n    fn foo() {\n        let a = A { a: 1, b: 1 };\n        let first_arg = match a {\n            //~^ manual_let_else\n            A { a, .. } => a,\n            _ => return,\n        };\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_let_else_match.stderr",
    "content": "error: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:36:5\n   |\nLL | /     let v = match g() {\nLL | |\nLL | |         Some(v_some) => v_some,\nLL | |         None => return,\nLL | |     };\n   | |______^ help: consider writing: `let Some(v) = g() else { return };`\n   |\n   = note: `-D clippy::manual-let-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:42:5\n   |\nLL | /     let v = match g() {\nLL | |\nLL | |         Some(v_some) => v_some,\nLL | |         _ => return,\nLL | |     };\n   | |______^ help: consider writing: `let Some(v) = g() else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:50:9\n   |\nLL | /         let v = match h() {\nLL | |\nLL | |             (Some(v), None) | (None, Some(v)) => v,\nLL | |             (Some(_), Some(_)) | (None, None) => continue,\nLL | |         };\n   | |__________^ help: consider writing: `let ((Some(v), None) | (None, Some(v))) = h() else { continue };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:56:9\n   |\nLL | /         let v = match build_enum() {\nLL | |\nLL | |             Variant::Bar(v) | Variant::Baz(v) => v,\nLL | |             _ => continue,\nLL | |         };\n   | |__________^ help: consider writing: `let (Variant::Bar(v) | Variant::Baz(v)) = build_enum() else { continue };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:65:5\n   |\nLL | /     let v = match f() {\nLL | |\nLL | |         Ok(v) => v,\nLL | |         Err(_) => return,\nLL | |     };\n   | |______^ help: consider writing: `let Ok(v) = f() else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:72:5\n   |\nLL | /     let v = match f().map_err(|_| ()) {\nLL | |\nLL | |         Ok(v) => v,\nLL | |         Err(()) => return,\nLL | |     };\n   | |______^ help: consider writing: `let Ok(v) = f().map_err(|_| ()) else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:80:5\n   |\nLL | /     let _value = match f {\nLL | |\nLL | |         Variant::Bar(v) | Variant::Baz(v) => v,\nLL | |         _ => return,\nLL | |     };\n   | |______^ help: consider writing: `let (Variant::Bar(_value) | Variant::Baz(_value)) = f else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:86:5\n   |\nLL | /     let _value = match Some(build_enum()) {\nLL | |\nLL | |         Some(Variant::Bar(v) | Variant::Baz(v)) => v,\nLL | |         _ => return,\nLL | |     };\n   | |______^ help: consider writing: `let Some(Variant::Bar(_value) | Variant::Baz(_value)) = Some(build_enum()) else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:93:5\n   |\nLL | /     let data = match data.as_slice() {\nLL | |\nLL | |         [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0] => data,\nLL | |         _ => return,\nLL | |     };\n   | |______^ help: consider writing: `let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:174:5\n   |\nLL | /     let msg = match Some(\"hi\") {\nLL | |\nLL | |         Some(m) => m,\nLL | |         _ => unreachable!(\"can't happen\"),\nLL | |     };\n   | |______^ help: consider writing: `let Some(msg) = Some(\"hi\") else { unreachable!(\"can't happen\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:188:5\n   |\nLL | /     let tornado = match issue {\nLL | |\nLL | |         Some(Issue9939 { avalanche }) => avalanche,\nLL | |         _ => unreachable!(\"can't happen\"),\nLL | |     };\n   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: tornado }) = issue else { unreachable!(\"can't happen\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:194:5\n   |\nLL | /     let acid_rain = match issue {\nLL | |\nLL | |         Some(Issue9939 { avalanche: tornado }) => tornado,\nLL | |         _ => unreachable!(\"can't happen\"),\nLL | |     };\n   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: acid_rain }) = issue else { unreachable!(\"can't happen\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:203:5\n   |\nLL | /     let _y = match issue {\nLL | |\nLL | |         _x @ Some(Issue9939 { avalanche }) => avalanche,\nLL | |         None => unreachable!(\"can't happen\"),\nLL | |     };\n   | |______^ help: consider writing: `let _x @ Some(Issue9939 { avalanche: _y }) = issue else { unreachable!(\"can't happen\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:210:5\n   |\nLL | /     let _x = match issue {\nLL | |\nLL | |         _x @ Some(Issue9939 { avalanche }) => avalanche,\nLL | |         None => unreachable!(\"can't happen\"),\nLL | |     };\n   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: _x }) = issue else { unreachable!(\"can't happen\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:228:5\n   |\nLL | /     let (issue, drought, flood) = match issue {\nLL | |\nLL | |         flood @ Some(Issue9939b { earthquake, hurricane }) => (flood, hurricane, earthquake),\nLL | |         None => unreachable!(\"can't happen\"),\nLL | |     };\n   | |______^ help: consider writing: `let issue @ Some(Issue9939b { earthquake: flood, hurricane: drought }) = issue else { unreachable!(\"can't happen\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:238:5\n   |\nLL | /     let (_y, erosion) = match issue {\nLL | |\nLL | |         _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),\nLL | |         None => unreachable!(\"can't happen\"),\nLL | |     };\n   | |______^ help: consider writing: `let _x @ Some(Issue9939b { earthquake: erosion, hurricane: _y }) = issue else { unreachable!(\"can't happen\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:246:5\n   |\nLL | /     let (_x, erosion) = match issue {\nLL | |\nLL | |         _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),\nLL | |         None => unreachable!(\"can't happen\"),\nLL | |     };\n   | |______^ help: consider writing: `let Some(Issue9939b { earthquake: erosion, hurricane: _x }) = issue else { unreachable!(\"can't happen\") };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_match.rs:263:9\n   |\nLL | /         let first_arg = match a {\nLL | |\nLL | |             A { a, .. } => a,\nLL | |             _ => return,\nLL | |         };\n   | |__________^ help: consider writing: `let A { a: first_arg, .. } = a else { return };`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_let_else_question_mark.fixed",
    "content": "#![allow(unused_braces, unused_variables, dead_code)]\n#![allow(\n    clippy::collapsible_else_if,\n    clippy::unused_unit,\n    clippy::let_unit_value,\n    clippy::match_single_binding,\n    clippy::never_loop\n)]\n#![warn(clippy::manual_let_else, clippy::question_mark)]\n\nenum Variant {\n    A(usize, usize),\n    B(usize),\n    C,\n}\n\nfn g() -> Option<(u8, u8)> {\n    None\n}\n\nfn e() -> Variant {\n    Variant::A(0, 0)\n}\n\nfn main() {}\n\nfn foo() -> Option<()> {\n    // Fire here, normal case\n    let v = g()?;\n    //~^ question_mark\n\n    // Don't fire here, the pattern is refutable\n    let Variant::A(v, w) = e() else { return None };\n\n    // Fire here, the pattern is irrefutable\n    let (v, w) = g()?;\n    //~^ question_mark\n\n    // Don't fire manual_let_else in this instance: question mark can be used instead.\n    let v = g()?;\n    //~^ question_mark\n\n    // Do fire manual_let_else in this instance: question mark cannot be used here due to the return\n    // body.\n    let Some(v) = g() else {\n        return Some(());\n    };\n\n    // Here we could also fire the question_mark lint, but we don't (as it's a match and not an if let).\n    // So we still emit manual_let_else here. For the *resulting* code, we *do* emit the question_mark\n    // lint, so for rustfix reasons, we allow the question_mark lint here.\n    #[allow(clippy::question_mark)]\n    {\n        let Some(v) = g() else { return None };\n    }\n\n    // This is a copy of the case above where we'd fire the question_mark lint, but here we have allowed\n    // it. Make sure that manual_let_else is fired as the fallback.\n    #[allow(clippy::question_mark)]\n    {\n        let Some(v) = g() else { return None };\n        //~^ manual_let_else\n    }\n\n    Some(())\n}\n\n// lint not just `return None`, but also `return None;` (note the semicolon)\nfn issue11993(y: Option<i32>) -> Option<i32> {\n    let x = y?;\n    //~^^^ question_mark\n\n    // don't lint: more than one statement in the else body\n    let Some(x) = y else {\n        todo!();\n        return None;\n    };\n\n    let Some(x) = y else {\n        // Roses are red,\n        // violets are blue,\n        // please keep this comment,\n        // it's art, you know?\n        return None;\n    };\n\n    None\n}\n"
  },
  {
    "path": "tests/ui/manual_let_else_question_mark.rs",
    "content": "#![allow(unused_braces, unused_variables, dead_code)]\n#![allow(\n    clippy::collapsible_else_if,\n    clippy::unused_unit,\n    clippy::let_unit_value,\n    clippy::match_single_binding,\n    clippy::never_loop\n)]\n#![warn(clippy::manual_let_else, clippy::question_mark)]\n\nenum Variant {\n    A(usize, usize),\n    B(usize),\n    C,\n}\n\nfn g() -> Option<(u8, u8)> {\n    None\n}\n\nfn e() -> Variant {\n    Variant::A(0, 0)\n}\n\nfn main() {}\n\nfn foo() -> Option<()> {\n    // Fire here, normal case\n    let Some(v) = g() else { return None };\n    //~^ question_mark\n\n    // Don't fire here, the pattern is refutable\n    let Variant::A(v, w) = e() else { return None };\n\n    // Fire here, the pattern is irrefutable\n    let Some((v, w)) = g() else { return None };\n    //~^ question_mark\n\n    // Don't fire manual_let_else in this instance: question mark can be used instead.\n    let v = if let Some(v_some) = g() { v_some } else { return None };\n    //~^ question_mark\n\n    // Do fire manual_let_else in this instance: question mark cannot be used here due to the return\n    // body.\n    let v = if let Some(v_some) = g() {\n        //~^ manual_let_else\n        v_some\n    } else {\n        return Some(());\n    };\n\n    // Here we could also fire the question_mark lint, but we don't (as it's a match and not an if let).\n    // So we still emit manual_let_else here. For the *resulting* code, we *do* emit the question_mark\n    // lint, so for rustfix reasons, we allow the question_mark lint here.\n    #[allow(clippy::question_mark)]\n    {\n        let v = match g() {\n            //~^ manual_let_else\n            Some(v_some) => v_some,\n            _ => return None,\n        };\n    }\n\n    // This is a copy of the case above where we'd fire the question_mark lint, but here we have allowed\n    // it. Make sure that manual_let_else is fired as the fallback.\n    #[allow(clippy::question_mark)]\n    {\n        let v = if let Some(v_some) = g() { v_some } else { return None };\n        //~^ manual_let_else\n    }\n\n    Some(())\n}\n\n// lint not just `return None`, but also `return None;` (note the semicolon)\nfn issue11993(y: Option<i32>) -> Option<i32> {\n    let Some(x) = y else {\n        return None;\n    };\n    //~^^^ question_mark\n\n    // don't lint: more than one statement in the else body\n    let Some(x) = y else {\n        todo!();\n        return None;\n    };\n\n    let Some(x) = y else {\n        // Roses are red,\n        // violets are blue,\n        // please keep this comment,\n        // it's art, you know?\n        return None;\n    };\n\n    None\n}\n"
  },
  {
    "path": "tests/ui/manual_let_else_question_mark.stderr",
    "content": "error: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/manual_let_else_question_mark.rs:29:5\n   |\nLL |     let Some(v) = g() else { return None };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `let v = g()?;`\n   |\n   = note: `-D clippy::question-mark` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::question_mark)]`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/manual_let_else_question_mark.rs:36:5\n   |\nLL |     let Some((v, w)) = g() else { return None };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `let (v, w) = g()?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/manual_let_else_question_mark.rs:40:13\n   |\nLL |     let v = if let Some(v_some) = g() { v_some } else { return None };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `g()?`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_question_mark.rs:45:5\n   |\nLL | /     let v = if let Some(v_some) = g() {\nLL | |\nLL | |         v_some\nLL | |     } else {\nLL | |         return Some(());\nLL | |     };\n   | |______^\n   |\n   = note: `-D clippy::manual-let-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`\nhelp: consider writing\n   |\nLL ~     let Some(v) = g() else {\nLL +         return Some(());\nLL +     };\n   |\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_question_mark.rs:57:9\n   |\nLL | /         let v = match g() {\nLL | |\nLL | |             Some(v_some) => v_some,\nLL | |             _ => return None,\nLL | |         };\n   | |__________^ help: consider writing: `let Some(v) = g() else { return None };`\n\nerror: this could be rewritten as `let...else`\n  --> tests/ui/manual_let_else_question_mark.rs:68:9\n   |\nLL |         let v = if let Some(v_some) = g() { v_some } else { return None };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return None };`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/manual_let_else_question_mark.rs:77:5\n   |\nLL | /     let Some(x) = y else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let x = y?;`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_main_separator_str.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::manual_main_separator_str)]\n\nuse std::path::MAIN_SEPARATOR;\n\nfn len(s: &str) -> usize {\n    s.len()\n}\n\nstruct U<'a> {\n    f: &'a str,\n    g: &'a String,\n}\n\nstruct V<T> {\n    f: T,\n}\n\nfn main() {\n    // Should lint\n    let _: &str = std::path::MAIN_SEPARATOR_STR;\n    //~^ manual_main_separator_str\n    let _ = len(std::path::MAIN_SEPARATOR_STR);\n    //~^ manual_main_separator_str\n    let _: Vec<u16> = std::path::MAIN_SEPARATOR_STR.encode_utf16().collect();\n    //~^ manual_main_separator_str\n\n    // Should lint for field `f` only\n    let _ = U {\n        f: std::path::MAIN_SEPARATOR_STR,\n        //~^ manual_main_separator_str\n        g: &MAIN_SEPARATOR.to_string(),\n    };\n\n    // Should not lint\n    let _: &String = &MAIN_SEPARATOR.to_string();\n    let _ = &MAIN_SEPARATOR.to_string();\n    let _ = V {\n        f: &MAIN_SEPARATOR.to_string(),\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_main_separator_str.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::manual_main_separator_str)]\n\nuse std::path::MAIN_SEPARATOR;\n\nfn len(s: &str) -> usize {\n    s.len()\n}\n\nstruct U<'a> {\n    f: &'a str,\n    g: &'a String,\n}\n\nstruct V<T> {\n    f: T,\n}\n\nfn main() {\n    // Should lint\n    let _: &str = &MAIN_SEPARATOR.to_string();\n    //~^ manual_main_separator_str\n    let _ = len(&MAIN_SEPARATOR.to_string());\n    //~^ manual_main_separator_str\n    let _: Vec<u16> = MAIN_SEPARATOR.to_string().encode_utf16().collect();\n    //~^ manual_main_separator_str\n\n    // Should lint for field `f` only\n    let _ = U {\n        f: &MAIN_SEPARATOR.to_string(),\n        //~^ manual_main_separator_str\n        g: &MAIN_SEPARATOR.to_string(),\n    };\n\n    // Should not lint\n    let _: &String = &MAIN_SEPARATOR.to_string();\n    let _ = &MAIN_SEPARATOR.to_string();\n    let _ = V {\n        f: &MAIN_SEPARATOR.to_string(),\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_main_separator_str.stderr",
    "content": "error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`\n  --> tests/ui/manual_main_separator_str.rs:21:19\n   |\nLL |     let _: &str = &MAIN_SEPARATOR.to_string();\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR`\n   |\n   = note: `-D clippy::manual-main-separator-str` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_main_separator_str)]`\n\nerror: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`\n  --> tests/ui/manual_main_separator_str.rs:23:17\n   |\nLL |     let _ = len(&MAIN_SEPARATOR.to_string());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR`\n\nerror: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`\n  --> tests/ui/manual_main_separator_str.rs:25:23\n   |\nLL |     let _: Vec<u16> = MAIN_SEPARATOR.to_string().encode_utf16().collect();\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR`\n\nerror: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`\n  --> tests/ui/manual_main_separator_str.rs:30:12\n   |\nLL |         f: &MAIN_SEPARATOR.to_string(),\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_map_option.fixed",
    "content": "#![warn(clippy::manual_map)]\n#![allow(\n    clippy::no_effect,\n    clippy::map_identity,\n    clippy::unit_arg,\n    clippy::match_ref_pats,\n    clippy::redundant_pattern_matching,\n    clippy::unnecessary_map_on_constructor,\n    for_loops_over_fallibles,\n    dead_code\n)]\n\nfn main() {\n    Some(0).map(|_| 2);\n\n    Some(0).map(|x| x + 1);\n\n    Some(\"\").map(|x| x.is_empty());\n\n    Some(0).map(|x| !x);\n\n    #[rustfmt::skip]\n    Some(0).map(std::convert::identity);\n\n    Some(&String::new()).map(|x| str::len(x));\n\n    match Some(0) {\n        Some(x) if false => Some(x + 1),\n        _ => None,\n    };\n\n    Some([0, 1]).as_ref().map(|x| x[0]);\n\n    Some(0).map(|x| x * 2);\n\n    Some(String::new()).as_ref().map(|x| x.is_empty());\n\n    Some(String::new()).as_ref().map(|x| x.len());\n\n    Some(0).map(|x| x + x);\n\n    #[warn(clippy::option_map_unit_fn)]\n    match &mut Some(String::new()) {\n        Some(x) => Some(x.push_str(\"\")),\n        None => None,\n    };\n\n    #[allow(clippy::option_map_unit_fn)]\n    {\n        Some(String::new()).as_mut().map(|x| x.push_str(\"\"));\n    }\n\n    Some(String::new()).as_ref().map(|x| x.len());\n\n    Some(String::new()).as_ref().map(|x| x.is_empty());\n\n    Some((0, 1, 2)).map(|(x, y, z)| x + y + z);\n\n    Some([1, 2, 3]).map(|[first, ..]| first);\n\n    Some((String::new(), \"test\")).as_ref().map(|(x, y)| (y, x));\n\n    match Some((String::new(), 0)) {\n        Some((ref x, y)) => Some((y, x)),\n        None => None,\n    };\n\n    match Some(Some(0)) {\n        Some(Some(_)) | Some(None) => Some(0),\n        None => None,\n    };\n\n    match Some(Some((0, 1))) {\n        Some(Some((x, 1))) => Some(x),\n        _ => None,\n    };\n\n    // #6795\n    fn f1() -> Result<(), ()> {\n        let _ = match Some(Ok(())) {\n            Some(x) => Some(x?),\n            None => None,\n        };\n        Ok(())\n    }\n\n    for &x in Some(Some(true)).iter() {\n        let _ = match x {\n            Some(x) => Some(if x { continue } else { x }),\n            None => None,\n        };\n    }\n\n    // #6797\n    let x1 = (Some(String::new()), 0);\n    let x2 = x1.0;\n    match x2 {\n        Some(x) => Some((x, x1.1)),\n        None => None,\n    };\n\n    struct S1 {\n        x: Option<String>,\n        y: u32,\n    }\n    impl S1 {\n        fn f(self) -> Option<(String, u32)> {\n            match self.x {\n                Some(x) => Some((x, self.y)),\n                None => None,\n            }\n        }\n    }\n\n    // #6811\n    Some(0).map(|x| vec![x]);\n\n    // Don't lint, coercion\n    let x: Option<Vec<&[u8]>> = match Some(()) {\n        Some(_) => Some(vec![b\"1234\"]),\n        None => None,\n    };\n\n    option_env!(\"\").map(String::from);\n\n    // #6819\n    async fn f2(x: u32) -> u32 {\n        x\n    }\n\n    async fn f3() {\n        match Some(0) {\n            Some(x) => Some(f2(x).await),\n            None => None,\n        };\n    }\n\n    // #6847\n    if let Some(_) = Some(0) {\n        Some(0)\n    } else { Some(0).map(|x| x + 1) };\n\n    if true {\n        Some(0)\n    } else { Some(0).map(|x| x + 1) };\n\n    // #6967\n    const fn f4() {\n        match Some(0) {\n            Some(x) => Some(x + 1),\n            None => None,\n        };\n    }\n\n    // #7077\n    let s = &String::new();\n    #[allow(clippy::needless_match)]\n    let _: Option<&str> = match Some(s) {\n        Some(s) => Some(s),\n        None => None,\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_map_option.rs",
    "content": "#![warn(clippy::manual_map)]\n#![allow(\n    clippy::no_effect,\n    clippy::map_identity,\n    clippy::unit_arg,\n    clippy::match_ref_pats,\n    clippy::redundant_pattern_matching,\n    clippy::unnecessary_map_on_constructor,\n    for_loops_over_fallibles,\n    dead_code\n)]\n\nfn main() {\n    match Some(0) {\n        //~^ manual_map\n        Some(_) => Some(2),\n        None::<u32> => None,\n    };\n\n    match Some(0) {\n        //~^ manual_map\n        Some(x) => Some(x + 1),\n        _ => None,\n    };\n\n    match Some(\"\") {\n        //~^ manual_map\n        Some(x) => Some(x.is_empty()),\n        None => None,\n    };\n\n    if let Some(x) = Some(0) {\n        //~^ manual_map\n        Some(!x)\n    } else {\n        None\n    };\n\n    #[rustfmt::skip]\n    match Some(0) {\n    //~^ manual_map\n        Some(x) => { Some(std::convert::identity(x)) }\n        None => { None }\n    };\n\n    match Some(&String::new()) {\n        //~^ manual_map\n        Some(x) => Some(str::len(x)),\n        None => None,\n    };\n\n    match Some(0) {\n        Some(x) if false => Some(x + 1),\n        _ => None,\n    };\n\n    match &Some([0, 1]) {\n        //~^ manual_map\n        Some(x) => Some(x[0]),\n        &None => None,\n    };\n\n    match &Some(0) {\n        //~^ manual_map\n        &Some(x) => Some(x * 2),\n        None => None,\n    };\n\n    match Some(String::new()) {\n        //~^ manual_map\n        Some(ref x) => Some(x.is_empty()),\n        _ => None,\n    };\n\n    match &&Some(String::new()) {\n        //~^ manual_map\n        Some(x) => Some(x.len()),\n        _ => None,\n    };\n\n    match &&Some(0) {\n        //~^ manual_map\n        &&Some(x) => Some(x + x),\n        &&_ => None,\n    };\n\n    #[warn(clippy::option_map_unit_fn)]\n    match &mut Some(String::new()) {\n        Some(x) => Some(x.push_str(\"\")),\n        None => None,\n    };\n\n    #[allow(clippy::option_map_unit_fn)]\n    {\n        match &mut Some(String::new()) {\n            //~^ manual_map\n            Some(x) => Some(x.push_str(\"\")),\n            None => None,\n        };\n    }\n\n    match &mut Some(String::new()) {\n        //~^ manual_map\n        &mut Some(ref x) => Some(x.len()),\n        None => None,\n    };\n\n    match &mut &Some(String::new()) {\n        //~^ manual_map\n        Some(x) => Some(x.is_empty()),\n        &mut _ => None,\n    };\n\n    match Some((0, 1, 2)) {\n        //~^ manual_map\n        Some((x, y, z)) => Some(x + y + z),\n        None => None,\n    };\n\n    match Some([1, 2, 3]) {\n        //~^ manual_map\n        Some([first, ..]) => Some(first),\n        None => None,\n    };\n\n    match &Some((String::new(), \"test\")) {\n        //~^ manual_map\n        Some((x, y)) => Some((y, x)),\n        None => None,\n    };\n\n    match Some((String::new(), 0)) {\n        Some((ref x, y)) => Some((y, x)),\n        None => None,\n    };\n\n    match Some(Some(0)) {\n        Some(Some(_)) | Some(None) => Some(0),\n        None => None,\n    };\n\n    match Some(Some((0, 1))) {\n        Some(Some((x, 1))) => Some(x),\n        _ => None,\n    };\n\n    // #6795\n    fn f1() -> Result<(), ()> {\n        let _ = match Some(Ok(())) {\n            Some(x) => Some(x?),\n            None => None,\n        };\n        Ok(())\n    }\n\n    for &x in Some(Some(true)).iter() {\n        let _ = match x {\n            Some(x) => Some(if x { continue } else { x }),\n            None => None,\n        };\n    }\n\n    // #6797\n    let x1 = (Some(String::new()), 0);\n    let x2 = x1.0;\n    match x2 {\n        Some(x) => Some((x, x1.1)),\n        None => None,\n    };\n\n    struct S1 {\n        x: Option<String>,\n        y: u32,\n    }\n    impl S1 {\n        fn f(self) -> Option<(String, u32)> {\n            match self.x {\n                Some(x) => Some((x, self.y)),\n                None => None,\n            }\n        }\n    }\n\n    // #6811\n    match Some(0) {\n        //~^ manual_map\n        Some(x) => Some(vec![x]),\n        None => None,\n    };\n\n    // Don't lint, coercion\n    let x: Option<Vec<&[u8]>> = match Some(()) {\n        Some(_) => Some(vec![b\"1234\"]),\n        None => None,\n    };\n\n    match option_env!(\"\") {\n        //~^ manual_map\n        Some(x) => Some(String::from(x)),\n        None => None,\n    };\n\n    // #6819\n    async fn f2(x: u32) -> u32 {\n        x\n    }\n\n    async fn f3() {\n        match Some(0) {\n            Some(x) => Some(f2(x).await),\n            None => None,\n        };\n    }\n\n    // #6847\n    if let Some(_) = Some(0) {\n        Some(0)\n    } else if let Some(x) = Some(0) {\n        //~^ manual_map\n        Some(x + 1)\n    } else {\n        None\n    };\n\n    if true {\n        Some(0)\n    } else if let Some(x) = Some(0) {\n        //~^ manual_map\n        Some(x + 1)\n    } else {\n        None\n    };\n\n    // #6967\n    const fn f4() {\n        match Some(0) {\n            Some(x) => Some(x + 1),\n            None => None,\n        };\n    }\n\n    // #7077\n    let s = &String::new();\n    #[allow(clippy::needless_match)]\n    let _: Option<&str> = match Some(s) {\n        Some(s) => Some(s),\n        None => None,\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_map_option.stderr",
    "content": "error: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:14:5\n   |\nLL | /     match Some(0) {\nLL | |\nLL | |         Some(_) => Some(2),\nLL | |         None::<u32> => None,\nLL | |     };\n   | |_____^ help: try: `Some(0).map(|_| 2)`\n   |\n   = note: `-D clippy::manual-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_map)]`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:20:5\n   |\nLL | /     match Some(0) {\nLL | |\nLL | |         Some(x) => Some(x + 1),\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(0).map(|x| x + 1)`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:26:5\n   |\nLL | /     match Some(\"\") {\nLL | |\nLL | |         Some(x) => Some(x.is_empty()),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(\"\").map(|x| x.is_empty())`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:32:5\n   |\nLL | /     if let Some(x) = Some(0) {\nLL | |\nLL | |         Some(!x)\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^ help: try: `Some(0).map(|x| !x)`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:40:5\n   |\nLL | /     match Some(0) {\nLL | |\nLL | |         Some(x) => { Some(std::convert::identity(x)) }\nLL | |         None => { None }\nLL | |     };\n   | |_____^ help: try: `Some(0).map(std::convert::identity)`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:46:5\n   |\nLL | /     match Some(&String::new()) {\nLL | |\nLL | |         Some(x) => Some(str::len(x)),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(&String::new()).map(|x| str::len(x))`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:57:5\n   |\nLL | /     match &Some([0, 1]) {\nLL | |\nLL | |         Some(x) => Some(x[0]),\nLL | |         &None => None,\nLL | |     };\n   | |_____^ help: try: `Some([0, 1]).as_ref().map(|x| x[0])`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:63:5\n   |\nLL | /     match &Some(0) {\nLL | |\nLL | |         &Some(x) => Some(x * 2),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(0).map(|x| x * 2)`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:69:5\n   |\nLL | /     match Some(String::new()) {\nLL | |\nLL | |         Some(ref x) => Some(x.is_empty()),\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:75:5\n   |\nLL | /     match &&Some(String::new()) {\nLL | |\nLL | |         Some(x) => Some(x.len()),\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:81:5\n   |\nLL | /     match &&Some(0) {\nLL | |\nLL | |         &&Some(x) => Some(x + x),\nLL | |         &&_ => None,\nLL | |     };\n   | |_____^ help: try: `Some(0).map(|x| x + x)`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:95:9\n   |\nLL | /         match &mut Some(String::new()) {\nLL | |\nLL | |             Some(x) => Some(x.push_str(\"\")),\nLL | |             None => None,\nLL | |         };\n   | |_________^ help: try: `Some(String::new()).as_mut().map(|x| x.push_str(\"\"))`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:102:5\n   |\nLL | /     match &mut Some(String::new()) {\nLL | |\nLL | |         &mut Some(ref x) => Some(x.len()),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:108:5\n   |\nLL | /     match &mut &Some(String::new()) {\nLL | |\nLL | |         Some(x) => Some(x.is_empty()),\nLL | |         &mut _ => None,\nLL | |     };\n   | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:114:5\n   |\nLL | /     match Some((0, 1, 2)) {\nLL | |\nLL | |         Some((x, y, z)) => Some(x + y + z),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:120:5\n   |\nLL | /     match Some([1, 2, 3]) {\nLL | |\nLL | |         Some([first, ..]) => Some(first),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some([1, 2, 3]).map(|[first, ..]| first)`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:126:5\n   |\nLL | /     match &Some((String::new(), \"test\")) {\nLL | |\nLL | |         Some((x, y)) => Some((y, x)),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some((String::new(), \"test\")).as_ref().map(|(x, y)| (y, x))`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:185:5\n   |\nLL | /     match Some(0) {\nLL | |\nLL | |         Some(x) => Some(vec![x]),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(0).map(|x| vec![x])`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:197:5\n   |\nLL | /     match option_env!(\"\") {\nLL | |\nLL | |         Some(x) => Some(String::from(x)),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `option_env!(\"\").map(String::from)`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:218:12\n   |\nLL |       } else if let Some(x) = Some(0) {\n   |  ____________^\nLL | |\nLL | |         Some(x + 1)\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^ help: try: `{ Some(0).map(|x| x + 1) }`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option.rs:227:12\n   |\nLL |       } else if let Some(x) = Some(0) {\n   |  ____________^\nLL | |\nLL | |         Some(x + 1)\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^ help: try: `{ Some(0).map(|x| x + 1) }`\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_map_option_2.fixed",
    "content": "#![warn(clippy::manual_map)]\n#![allow(clippy::toplevel_ref_arg)]\n\nfn main() {\n    // Lint. `y` is declared within the arm, so it isn't captured by the map closure\n    let _ = Some(0).map(|x| {\n            let y = (String::new(), String::new());\n            (x, y.0)\n        });\n\n    // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured by the map\n    // closure\n    let s = Some(String::new());\n    let _ = match &s {\n        Some(x) => Some((x.clone(), s)),\n        None => None,\n    };\n\n    // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured by the map\n    // closure\n    let s = Some(String::new());\n    let _ = match &s {\n        Some(x) => Some({\n            let clone = x.clone();\n            let s = || s;\n            (clone, s())\n        }),\n        None => None,\n    };\n\n    // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured as a mutable\n    // reference by the map closure\n    let mut s = Some(String::new());\n    let _ = match &s {\n        Some(x) => Some({\n            let clone = x.clone();\n            let ref mut s = s;\n            (clone, s)\n        }),\n        None => None,\n    };\n\n    let s = Some(String::new());\n    // Lint. `s` is captured by reference, so no lifetime issues.\n    let _ = s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } });\n    // Don't lint this, type of `s` is coercioned from `&String` to `&str`\n    let x: Option<(String, &str)> = match &s {\n        Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }),\n        None => None,\n    };\n\n    // Issue #7820\n    unsafe fn f(x: u32) -> u32 {\n        x\n    }\n    unsafe {\n        let _ = Some(0).map(|x| f(x));\n    }\n    let _ = Some(0).map(|x| unsafe { f(x) });\n    let _ = Some(0).map(|x| unsafe { f(x) });\n}\n\n// issue #12659\nmod with_type_coercion {\n    trait DummyTrait {}\n\n    fn foo<T: DummyTrait, F: Fn() -> Result<T, ()>>(f: F) {\n        // Don't lint\n        let _: Option<Result<Box<dyn DummyTrait>, ()>> = match Some(0) {\n            Some(_) => Some(match f() {\n                Ok(res) => Ok(Box::new(res)),\n                _ => Err(()),\n            }),\n            None => None,\n        };\n\n        let _: Option<Box<&[u8]>> = match Some(()) {\n            Some(_) => Some(Box::new(b\"1234\")),\n            None => None,\n        };\n\n        let x = String::new();\n        let _: Option<Box<&str>> = match Some(()) {\n            Some(_) => Some(Box::new(&x)),\n            None => None,\n        };\n\n        let _: Option<&str> = match Some(()) {\n            Some(_) => Some(&x),\n            None => None,\n        };\n\n        let _ = Some(0).map(|_| match f() {\n                Ok(res) => Ok(Box::new(res)),\n                _ => Err(()),\n            });\n    }\n\n    #[allow(clippy::redundant_allocation)]\n    fn bar() {\n        fn f(_: Option<Box<&[u8]>>) {}\n        fn g(b: &[u8]) -> Box<&[u8]> {\n            Box::new(b)\n        }\n\n        let x: &[u8; 4] = b\"1234\";\n        f(match Some(()) {\n            Some(_) => Some(Box::new(x)),\n            None => None,\n        });\n\n        let _: Option<Box<&[u8]>> = Some(0).map(|_| g(x));\n    }\n\n    fn with_fn_ret(s: &Option<String>) -> Option<(String, &str)> {\n        // Don't lint, `map` doesn't work as the return type is adjusted.\n        match s {\n            Some(x) => Some({ if let Some(s) = s { (x.clone(), s) } else { panic!() } }),\n            None => None,\n        }\n    }\n\n    fn with_fn_ret_2(s: &Option<String>) -> Option<(String, &str)> {\n        if true {\n            // Don't lint, `map` doesn't work as the return type is adjusted.\n            return match s {\n                Some(x) => Some({ if let Some(s) = s { (x.clone(), s) } else { panic!() } }),\n                None => None,\n            };\n        }\n        None\n    }\n\n    #[allow(clippy::needless_late_init)]\n    fn with_fn_ret_3<'a>(s: &'a Option<String>) -> Option<(String, &'a str)> {\n        let x: Option<(String, &'a str)>;\n        x = {\n            match s {\n                Some(x) => Some({ if let Some(s) = s { (x.clone(), s) } else { panic!() } }),\n                None => None,\n            }\n        };\n        x\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_map_option_2.rs",
    "content": "#![warn(clippy::manual_map)]\n#![allow(clippy::toplevel_ref_arg)]\n\nfn main() {\n    // Lint. `y` is declared within the arm, so it isn't captured by the map closure\n    let _ = match Some(0) {\n        //~^ manual_map\n        Some(x) => Some({\n            let y = (String::new(), String::new());\n            (x, y.0)\n        }),\n        None => None,\n    };\n\n    // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured by the map\n    // closure\n    let s = Some(String::new());\n    let _ = match &s {\n        Some(x) => Some((x.clone(), s)),\n        None => None,\n    };\n\n    // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured by the map\n    // closure\n    let s = Some(String::new());\n    let _ = match &s {\n        Some(x) => Some({\n            let clone = x.clone();\n            let s = || s;\n            (clone, s())\n        }),\n        None => None,\n    };\n\n    // Don't lint. `s` is borrowed until partway through the arm, but needs to be captured as a mutable\n    // reference by the map closure\n    let mut s = Some(String::new());\n    let _ = match &s {\n        Some(x) => Some({\n            let clone = x.clone();\n            let ref mut s = s;\n            (clone, s)\n        }),\n        None => None,\n    };\n\n    let s = Some(String::new());\n    // Lint. `s` is captured by reference, so no lifetime issues.\n    let _ = match &s {\n        //~^ manual_map\n        Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }),\n        None => None,\n    };\n    // Don't lint this, type of `s` is coercioned from `&String` to `&str`\n    let x: Option<(String, &str)> = match &s {\n        Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }),\n        None => None,\n    };\n\n    // Issue #7820\n    unsafe fn f(x: u32) -> u32 {\n        x\n    }\n    unsafe {\n        let _ = match Some(0) {\n            //~^ manual_map\n            Some(x) => Some(f(x)),\n            None => None,\n        };\n    }\n    let _ = match Some(0) {\n        //~^ manual_map\n        Some(x) => unsafe { Some(f(x)) },\n        None => None,\n    };\n    let _ = match Some(0) {\n        //~^ manual_map\n        Some(x) => Some(unsafe { f(x) }),\n        None => None,\n    };\n}\n\n// issue #12659\nmod with_type_coercion {\n    trait DummyTrait {}\n\n    fn foo<T: DummyTrait, F: Fn() -> Result<T, ()>>(f: F) {\n        // Don't lint\n        let _: Option<Result<Box<dyn DummyTrait>, ()>> = match Some(0) {\n            Some(_) => Some(match f() {\n                Ok(res) => Ok(Box::new(res)),\n                _ => Err(()),\n            }),\n            None => None,\n        };\n\n        let _: Option<Box<&[u8]>> = match Some(()) {\n            Some(_) => Some(Box::new(b\"1234\")),\n            None => None,\n        };\n\n        let x = String::new();\n        let _: Option<Box<&str>> = match Some(()) {\n            Some(_) => Some(Box::new(&x)),\n            None => None,\n        };\n\n        let _: Option<&str> = match Some(()) {\n            Some(_) => Some(&x),\n            None => None,\n        };\n\n        let _ = match Some(0) {\n            //~^ manual_map\n            Some(_) => Some(match f() {\n                Ok(res) => Ok(Box::new(res)),\n                _ => Err(()),\n            }),\n            None => None,\n        };\n    }\n\n    #[allow(clippy::redundant_allocation)]\n    fn bar() {\n        fn f(_: Option<Box<&[u8]>>) {}\n        fn g(b: &[u8]) -> Box<&[u8]> {\n            Box::new(b)\n        }\n\n        let x: &[u8; 4] = b\"1234\";\n        f(match Some(()) {\n            Some(_) => Some(Box::new(x)),\n            None => None,\n        });\n\n        let _: Option<Box<&[u8]>> = match Some(0) {\n            //~^ manual_map\n            Some(_) => Some(g(x)),\n            None => None,\n        };\n    }\n\n    fn with_fn_ret(s: &Option<String>) -> Option<(String, &str)> {\n        // Don't lint, `map` doesn't work as the return type is adjusted.\n        match s {\n            Some(x) => Some({ if let Some(s) = s { (x.clone(), s) } else { panic!() } }),\n            None => None,\n        }\n    }\n\n    fn with_fn_ret_2(s: &Option<String>) -> Option<(String, &str)> {\n        if true {\n            // Don't lint, `map` doesn't work as the return type is adjusted.\n            return match s {\n                Some(x) => Some({ if let Some(s) = s { (x.clone(), s) } else { panic!() } }),\n                None => None,\n            };\n        }\n        None\n    }\n\n    #[allow(clippy::needless_late_init)]\n    fn with_fn_ret_3<'a>(s: &'a Option<String>) -> Option<(String, &'a str)> {\n        let x: Option<(String, &'a str)>;\n        x = {\n            match s {\n                Some(x) => Some({ if let Some(s) = s { (x.clone(), s) } else { panic!() } }),\n                None => None,\n            }\n        };\n        x\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_map_option_2.stderr",
    "content": "error: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option_2.rs:6:13\n   |\nLL |       let _ = match Some(0) {\n   |  _____________^\nLL | |\nLL | |         Some(x) => Some({\nLL | |             let y = (String::new(), String::new());\n...  |\nLL | |         None => None,\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::manual-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_map)]`\nhelp: try\n   |\nLL ~     let _ = Some(0).map(|x| {\nLL +             let y = (String::new(), String::new());\nLL +             (x, y.0)\nLL ~         });\n   |\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option_2.rs:49:13\n   |\nLL |       let _ = match &s {\n   |  _____________^\nLL | |\nLL | |         Some(x) => Some({ if let Some(ref s) = s { (x.clone(), s) } else { panic!() } }),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `s.as_ref().map(|x| { if let Some(ref s) = s { (x.clone(), s) } else { panic!() } })`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option_2.rs:65:17\n   |\nLL |           let _ = match Some(0) {\n   |  _________________^\nLL | |\nLL | |             Some(x) => Some(f(x)),\nLL | |             None => None,\nLL | |         };\n   | |_________^ help: try: `Some(0).map(|x| f(x))`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option_2.rs:71:13\n   |\nLL |       let _ = match Some(0) {\n   |  _____________^\nLL | |\nLL | |         Some(x) => unsafe { Some(f(x)) },\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option_2.rs:76:13\n   |\nLL |       let _ = match Some(0) {\n   |  _____________^\nLL | |\nLL | |         Some(x) => Some(unsafe { f(x) }),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: try: `Some(0).map(|x| unsafe { f(x) })`\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option_2.rs:113:17\n   |\nLL |           let _ = match Some(0) {\n   |  _________________^\nLL | |\nLL | |             Some(_) => Some(match f() {\nLL | |                 Ok(res) => Ok(Box::new(res)),\n...  |\nLL | |             None => None,\nLL | |         };\n   | |_________^\n   |\nhelp: try\n   |\nLL ~         let _ = Some(0).map(|_| match f() {\nLL +                 Ok(res) => Ok(Box::new(res)),\nLL +                 _ => Err(()),\nLL ~             });\n   |\n\nerror: manual implementation of `Option::map`\n  --> tests/ui/manual_map_option_2.rs:136:37\n   |\nLL |           let _: Option<Box<&[u8]>> = match Some(0) {\n   |  _____________________________________^\nLL | |\nLL | |             Some(_) => Some(g(x)),\nLL | |             None => None,\nLL | |         };\n   | |_________^ help: try: `Some(0).map(|_| g(x))`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_memcpy/with_loop_counters.fixed",
    "content": "#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]\n#![allow(clippy::redundant_slicing, clippy::identity_op)]\n\npub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {\n    let mut count = 0;\n    dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);\n\n    let mut count = 0;\n    dst[..(src.len() - 3)].copy_from_slice(&src[3..]);\n\n    let mut count = 3;\n    dst[3..(src.len() + 3)].copy_from_slice(&src[..]);\n\n    let mut count = 3;\n    dst[..src.len()].copy_from_slice(&src[3..(src.len() + 3)]);\n\n    let mut count = 0;\n    dst[3..(3 + src.len())].copy_from_slice(&src[..(3 + src.len() - 3)]);\n\n    let mut count = 3;\n    dst[5..src.len()].copy_from_slice(&src[(3 - 2)..((src.len() - 2) + 3 - 5)]);\n\n    let mut count = 2;\n    dst.copy_from_slice(&src[2..(dst.len() + 2)]);\n\n    let mut count = 5;\n    dst[3..10].copy_from_slice(&src[5..(10 + 5 - 3)]);\n\n    let mut count = 3;\n    let mut count2 = 30;\n    dst[3..(src.len() + 3)].copy_from_slice(&src[..]);\n    dst2[30..(src.len() + 30)].copy_from_slice(&src[..]);\n\n    // make sure parentheses are added properly to bitwise operators, which have lower precedence than\n    // arithmetic ones\n    let mut count = 0 << 1;\n    dst[(0 << 1)..((1 << 1) + (0 << 1))].copy_from_slice(&src[2..((1 << 1) + 2)]);\n\n    // make sure incrementing expressions without semicolons at the end of loops are handled correctly.\n    let mut count = 0;\n    dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);\n\n    // make sure ones where the increment is not at the end of the loop.\n    // As a possible enhancement, one could adjust the offset in the suggestion according to\n    // the position. For example, if the increment is at the top of the loop;\n    // treating the loop counter as if it were initialized 1 greater than the original value.\n    let mut count = 0;\n    #[allow(clippy::needless_range_loop)]\n    for i in 0..src.len() {\n        count += 1;\n        dst[i] = src[count];\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_memcpy/with_loop_counters.rs",
    "content": "#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]\n#![allow(clippy::redundant_slicing, clippy::identity_op)]\n\npub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {\n    let mut count = 0;\n    for i in 3..src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[count];\n        count += 1;\n    }\n\n    let mut count = 0;\n    for i in 3..src.len() {\n        //~^ manual_memcpy\n\n        dst[count] = src[i];\n        count += 1;\n    }\n\n    let mut count = 3;\n    for i in 0..src.len() {\n        //~^ manual_memcpy\n\n        dst[count] = src[i];\n        count += 1;\n    }\n\n    let mut count = 3;\n    for i in 0..src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[count];\n        count += 1;\n    }\n\n    let mut count = 0;\n    for i in 3..(3 + src.len()) {\n        //~^ manual_memcpy\n\n        dst[i] = src[count];\n        count += 1;\n    }\n\n    let mut count = 3;\n    for i in 5..src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[count - 2];\n        count += 1;\n    }\n\n    let mut count = 2;\n    for i in 0..dst.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[count];\n        count += 1;\n    }\n\n    let mut count = 5;\n    for i in 3..10 {\n        //~^ manual_memcpy\n\n        dst[i] = src[count];\n        count += 1;\n    }\n\n    let mut count = 3;\n    let mut count2 = 30;\n    for i in 0..src.len() {\n        //~^ manual_memcpy\n\n        dst[count] = src[i];\n        dst2[count2] = src[i];\n        count += 1;\n        count2 += 1;\n    }\n\n    // make sure parentheses are added properly to bitwise operators, which have lower precedence than\n    // arithmetic ones\n    let mut count = 0 << 1;\n    for i in 0..1 << 1 {\n        //~^ manual_memcpy\n\n        dst[count] = src[i + 2];\n        count += 1;\n    }\n\n    // make sure incrementing expressions without semicolons at the end of loops are handled correctly.\n    let mut count = 0;\n    for i in 3..src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[count];\n        count += 1\n    }\n\n    // make sure ones where the increment is not at the end of the loop.\n    // As a possible enhancement, one could adjust the offset in the suggestion according to\n    // the position. For example, if the increment is at the top of the loop;\n    // treating the loop counter as if it were initialized 1 greater than the original value.\n    let mut count = 0;\n    #[allow(clippy::needless_range_loop)]\n    for i in 0..src.len() {\n        count += 1;\n        dst[i] = src[count];\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_memcpy/with_loop_counters.stderr",
    "content": "error: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:6:5\n   |\nLL | /     for i in 3..src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[count];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);`\n   |\n   = note: `-D clippy::manual-memcpy` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:14:5\n   |\nLL | /     for i in 3..src.len() {\nLL | |\nLL | |\nLL | |         dst[count] = src[i];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[..(src.len() - 3)].copy_from_slice(&src[3..]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:22:5\n   |\nLL | /     for i in 0..src.len() {\nLL | |\nLL | |\nLL | |         dst[count] = src[i];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[3..(src.len() + 3)].copy_from_slice(&src[..]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:30:5\n   |\nLL | /     for i in 0..src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[count];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[3..(src.len() + 3)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:38:5\n   |\nLL | /     for i in 3..(3 + src.len()) {\nLL | |\nLL | |\nLL | |         dst[i] = src[count];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[3..(3 + src.len())].copy_from_slice(&src[..(3 + src.len() - 3)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:46:5\n   |\nLL | /     for i in 5..src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[count - 2];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[5..src.len()].copy_from_slice(&src[(3 - 2)..((src.len() - 2) + 3 - 5)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:54:5\n   |\nLL | /     for i in 0..dst.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[count];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[2..(dst.len() + 2)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:62:5\n   |\nLL | /     for i in 3..10 {\nLL | |\nLL | |\nLL | |         dst[i] = src[count];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[3..10].copy_from_slice(&src[5..(10 + 5 - 3)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:71:5\n   |\nLL | /     for i in 0..src.len() {\nLL | |\nLL | |\nLL | |         dst[count] = src[i];\n...  |\nLL | |         count2 += 1;\nLL | |     }\n   | |_____^\n   |\nhelp: try replacing the loop by\n   |\nLL ~     dst[3..(src.len() + 3)].copy_from_slice(&src[..]);\nLL +     dst2[30..(src.len() + 30)].copy_from_slice(&src[..]);\n   |\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:83:5\n   |\nLL | /     for i in 0..1 << 1 {\nLL | |\nLL | |\nLL | |         dst[count] = src[i + 2];\nLL | |         count += 1;\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[(0 << 1)..((1 << 1) + (0 << 1))].copy_from_slice(&src[2..((1 << 1) + 2)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/with_loop_counters.rs:92:5\n   |\nLL | /     for i in 3..src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[count];\nLL | |         count += 1\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[3..src.len()].copy_from_slice(&src[..(src.len() - 3)]);`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_memcpy/without_loop_counters.fixed",
    "content": "#![warn(clippy::manual_memcpy)]\n#![allow(\n    clippy::assigning_clones,\n    clippy::useless_vec,\n    clippy::needless_range_loop,\n    clippy::manual_slice_fill,\n    clippy::redundant_slicing\n)]\n\nconst LOOP_OFFSET: usize = 5000;\n\npub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {\n    // plain manual memcpy\n    dst[..src.len()].copy_from_slice(&src[..]);\n\n    // dst offset memcpy\n    dst[10..(src.len() + 10)].copy_from_slice(&src[..]);\n\n    // src offset memcpy\n    dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);\n\n    // src offset memcpy\n    dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);\n\n    // overwrite entire dst\n    dst.copy_from_slice(&src[..dst.len()]);\n\n    // manual copy with branch - can't easily convert to memcpy!\n    for i in 0..src.len() {\n        dst[i] = src[i];\n        if dst[i] > 5 {\n            break;\n        }\n    }\n\n    // multiple copies - suggest two memcpy statements\n    dst[10..256].copy_from_slice(&src[(10 - 5)..(256 - 5)]);\n    dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]);\n\n    // this is a reversal - the copy lint shouldn't be triggered\n    for i in 10..LOOP_OFFSET {\n        dst[i + LOOP_OFFSET] = src[LOOP_OFFSET - i];\n    }\n\n    let some_var = 5;\n    // Offset in variable\n    dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);\n\n    // Non continuous copy - don't trigger lint\n    for i in 0..10 {\n        dst[i + i] = src[i];\n    }\n\n    let src_vec = vec![1, 2, 3, 4, 5];\n    let mut dst_vec = vec![0, 0, 0, 0, 0];\n\n    // make sure vectors are supported\n    dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);\n\n    // lint should not trigger when either\n    // source or destination type is not\n    // slice-like, like DummyStruct\n    struct DummyStruct(i32);\n\n    impl ::std::ops::Index<usize> for DummyStruct {\n        type Output = i32;\n\n        fn index(&self, _: usize) -> &i32 {\n            &self.0\n        }\n    }\n\n    let src = DummyStruct(5);\n    let mut dst_vec = vec![0; 10];\n\n    for i in 0..10 {\n        dst_vec[i] = src[i];\n    }\n\n    // Simplify suggestion (issue #3004)\n    let src = [0, 1, 2, 3, 4];\n    let mut dst = [0, 0, 0, 0, 0, 0];\n    let from = 1;\n\n    dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);\n\n    dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);\n\n    #[allow(clippy::identity_op)]\n    dst[..5].copy_from_slice(&src);\n\n    #[allow(clippy::reversed_empty_ranges)]\n    dst[..0].copy_from_slice(&src[..0]);\n\n    // `RangeTo` `for` loop - don't trigger lint\n    for i in 0.. {\n        dst[i] = src[i];\n    }\n\n    // VecDeque - ideally this would work, but would require something like `range_as_slices`\n    let mut dst = std::collections::VecDeque::from_iter([0; 5]);\n    let src = std::collections::VecDeque::from_iter([0, 1, 2, 3, 4]);\n    for i in 0..dst.len() {\n        dst[i] = src[i];\n    }\n    let src = vec![0, 1, 2, 3, 4];\n    for i in 0..dst.len() {\n        dst[i] = src[i];\n    }\n\n    // Range is equal to array length\n    let src = [0, 1, 2, 3, 4];\n    let mut dst = [0; 4];\n    dst.copy_from_slice(&src[..4]);\n\n    let mut dst = [0; 6];\n    dst[..5].copy_from_slice(&src);\n\n    let mut dst = [0; 5];\n    dst.copy_from_slice(&src);\n\n    // Don't trigger lint for following multi-dimensional arrays\n    let src = [[0; 5]; 5];\n    for i in 0..4 {\n        dst[i] = src[i + 1][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][3];\n    }\n\n    let src = [0; 5];\n    let mut dst = [[0; 5]; 5];\n    for i in 0..5 {\n        dst[i][i] = src[i];\n    }\n\n    let src = [[[0; 5]; 5]; 5];\n    let mut dst = [0; 5];\n    for i in 0..5 {\n        dst[i] = src[i][i][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][i][0];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][0][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[0][i][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[0][i][1];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][0][1];\n    }\n\n    // Trigger lint\n    let src = [[0; 5]; 5];\n    let mut dst = [0; 5];\n    dst.copy_from_slice(&src[0]);\n\n    let src = [[[0; 5]; 5]; 5];\n    dst.copy_from_slice(&src[0][1]);\n}\n\n#[warn(clippy::needless_range_loop, clippy::manual_memcpy)]\npub fn manual_clone(src: &[String], dst: &mut [String]) {\n    dst[..src.len()].clone_from_slice(&src[..]);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_memcpy/without_loop_counters.rs",
    "content": "#![warn(clippy::manual_memcpy)]\n#![allow(\n    clippy::assigning_clones,\n    clippy::useless_vec,\n    clippy::needless_range_loop,\n    clippy::manual_slice_fill,\n    clippy::redundant_slicing\n)]\n\nconst LOOP_OFFSET: usize = 5000;\n\npub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {\n    // plain manual memcpy\n    for i in 0..src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[i];\n    }\n\n    // dst offset memcpy\n    for i in 0..src.len() {\n        //~^ manual_memcpy\n\n        dst[i + 10] = src[i];\n    }\n\n    // src offset memcpy\n    for i in 0..src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[i + 10];\n    }\n\n    // src offset memcpy\n    for i in 11..src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[i - 10];\n    }\n\n    // overwrite entire dst\n    for i in 0..dst.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[i];\n    }\n\n    // manual copy with branch - can't easily convert to memcpy!\n    for i in 0..src.len() {\n        dst[i] = src[i];\n        if dst[i] > 5 {\n            break;\n        }\n    }\n\n    // multiple copies - suggest two memcpy statements\n    for i in 10..256 {\n        //~^ manual_memcpy\n\n        dst[i] = src[i - 5];\n        dst2[i + 500] = src[i]\n    }\n\n    // this is a reversal - the copy lint shouldn't be triggered\n    for i in 10..LOOP_OFFSET {\n        dst[i + LOOP_OFFSET] = src[LOOP_OFFSET - i];\n    }\n\n    let some_var = 5;\n    // Offset in variable\n    for i in 10..LOOP_OFFSET {\n        //~^ manual_memcpy\n\n        dst[i + LOOP_OFFSET] = src[i - some_var];\n    }\n\n    // Non continuous copy - don't trigger lint\n    for i in 0..10 {\n        dst[i + i] = src[i];\n    }\n\n    let src_vec = vec![1, 2, 3, 4, 5];\n    let mut dst_vec = vec![0, 0, 0, 0, 0];\n\n    // make sure vectors are supported\n    for i in 0..src_vec.len() {\n        //~^ manual_memcpy\n\n        dst_vec[i] = src_vec[i];\n    }\n\n    // lint should not trigger when either\n    // source or destination type is not\n    // slice-like, like DummyStruct\n    struct DummyStruct(i32);\n\n    impl ::std::ops::Index<usize> for DummyStruct {\n        type Output = i32;\n\n        fn index(&self, _: usize) -> &i32 {\n            &self.0\n        }\n    }\n\n    let src = DummyStruct(5);\n    let mut dst_vec = vec![0; 10];\n\n    for i in 0..10 {\n        dst_vec[i] = src[i];\n    }\n\n    // Simplify suggestion (issue #3004)\n    let src = [0, 1, 2, 3, 4];\n    let mut dst = [0, 0, 0, 0, 0, 0];\n    let from = 1;\n\n    for i in from..from + src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[i - from];\n    }\n\n    for i in from..from + 3 {\n        //~^ manual_memcpy\n\n        dst[i] = src[i - from];\n    }\n\n    #[allow(clippy::identity_op)]\n    for i in 0..5 {\n        //~^ manual_memcpy\n\n        dst[i - 0] = src[i];\n    }\n\n    #[allow(clippy::reversed_empty_ranges)]\n    for i in 0..0 {\n        //~^ manual_memcpy\n\n        dst[i] = src[i];\n    }\n\n    // `RangeTo` `for` loop - don't trigger lint\n    for i in 0.. {\n        dst[i] = src[i];\n    }\n\n    // VecDeque - ideally this would work, but would require something like `range_as_slices`\n    let mut dst = std::collections::VecDeque::from_iter([0; 5]);\n    let src = std::collections::VecDeque::from_iter([0, 1, 2, 3, 4]);\n    for i in 0..dst.len() {\n        dst[i] = src[i];\n    }\n    let src = vec![0, 1, 2, 3, 4];\n    for i in 0..dst.len() {\n        dst[i] = src[i];\n    }\n\n    // Range is equal to array length\n    let src = [0, 1, 2, 3, 4];\n    let mut dst = [0; 4];\n    for i in 0..4 {\n        //~^ manual_memcpy\n\n        dst[i] = src[i];\n    }\n\n    let mut dst = [0; 6];\n    for i in 0..5 {\n        //~^ manual_memcpy\n\n        dst[i] = src[i];\n    }\n\n    let mut dst = [0; 5];\n    for i in 0..5 {\n        //~^ manual_memcpy\n\n        dst[i] = src[i];\n    }\n\n    // Don't trigger lint for following multi-dimensional arrays\n    let src = [[0; 5]; 5];\n    for i in 0..4 {\n        dst[i] = src[i + 1][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][3];\n    }\n\n    let src = [0; 5];\n    let mut dst = [[0; 5]; 5];\n    for i in 0..5 {\n        dst[i][i] = src[i];\n    }\n\n    let src = [[[0; 5]; 5]; 5];\n    let mut dst = [0; 5];\n    for i in 0..5 {\n        dst[i] = src[i][i][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][i][0];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][0][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[0][i][i];\n    }\n    for i in 0..5 {\n        dst[i] = src[0][i][1];\n    }\n    for i in 0..5 {\n        dst[i] = src[i][0][1];\n    }\n\n    // Trigger lint\n    let src = [[0; 5]; 5];\n    let mut dst = [0; 5];\n    for i in 0..5 {\n        //~^ manual_memcpy\n\n        dst[i] = src[0][i];\n    }\n\n    let src = [[[0; 5]; 5]; 5];\n    for i in 0..5 {\n        //~^ manual_memcpy\n\n        dst[i] = src[0][1][i];\n    }\n}\n\n#[warn(clippy::needless_range_loop, clippy::manual_memcpy)]\npub fn manual_clone(src: &[String], dst: &mut [String]) {\n    for i in 0..src.len() {\n        //~^ manual_memcpy\n\n        dst[i] = src[i].clone();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_memcpy/without_loop_counters.stderr",
    "content": "error: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:14:5\n   |\nLL | /     for i in 0..src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[..]);`\n   |\n   = note: `-D clippy::manual-memcpy` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:21:5\n   |\nLL | /     for i in 0..src.len() {\nLL | |\nLL | |\nLL | |         dst[i + 10] = src[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:28:5\n   |\nLL | /     for i in 0..src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[i + 10];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:35:5\n   |\nLL | /     for i in 11..src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[i - 10];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:42:5\n   |\nLL | /     for i in 0..dst.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:57:5\n   |\nLL | /     for i in 10..256 {\nLL | |\nLL | |\nLL | |         dst[i] = src[i - 5];\nLL | |         dst2[i + 500] = src[i]\nLL | |     }\n   | |_____^\n   |\nhelp: try replacing the loop by\n   |\nLL ~     dst[10..256].copy_from_slice(&src[(10 - 5)..(256 - 5)]);\nLL +     dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]);\n   |\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:71:5\n   |\nLL | /     for i in 10..LOOP_OFFSET {\nLL | |\nLL | |\nLL | |         dst[i + LOOP_OFFSET] = src[i - some_var];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:86:5\n   |\nLL | /     for i in 0..src_vec.len() {\nLL | |\nLL | |\nLL | |         dst_vec[i] = src_vec[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:117:5\n   |\nLL | /     for i in from..from + src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[i - from];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:123:5\n   |\nLL | /     for i in from..from + 3 {\nLL | |\nLL | |\nLL | |         dst[i] = src[i - from];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:130:5\n   |\nLL | /     for i in 0..5 {\nLL | |\nLL | |\nLL | |         dst[i - 0] = src[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:137:5\n   |\nLL | /     for i in 0..0 {\nLL | |\nLL | |\nLL | |         dst[i] = src[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:162:5\n   |\nLL | /     for i in 0..4 {\nLL | |\nLL | |\nLL | |         dst[i] = src[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..4]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:169:5\n   |\nLL | /     for i in 0..5 {\nLL | |\nLL | |\nLL | |         dst[i] = src[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:176:5\n   |\nLL | /     for i in 0..5 {\nLL | |\nLL | |\nLL | |         dst[i] = src[i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:224:5\n   |\nLL | /     for i in 0..5 {\nLL | |\nLL | |\nLL | |         dst[i] = src[0][i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:231:5\n   |\nLL | /     for i in 0..5 {\nLL | |\nLL | |\nLL | |         dst[i] = src[0][1][i];\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0][1]);`\n\nerror: it looks like you're manually copying between slices\n  --> tests/ui/manual_memcpy/without_loop_counters.rs:240:5\n   |\nLL | /     for i in 0..src.len() {\nLL | |\nLL | |\nLL | |         dst[i] = src[i].clone();\nLL | |     }\n   | |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..]);`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_midpoint.fixed",
    "content": "#![warn(clippy::manual_midpoint)]\n\nmacro_rules! mac {\n    ($a: expr, $b: expr) => {\n        ($a + $b) / 2\n    };\n}\n\nmacro_rules! add {\n    ($a: expr, $b: expr) => {\n        ($a + $b)\n    };\n}\n\nmacro_rules! two {\n    () => {\n        2\n    };\n}\n\n#[clippy::msrv = \"1.84\"]\nfn older_msrv() {\n    let a: u32 = 10;\n    let _ = (a + 5) / 2;\n}\n\n#[clippy::msrv = \"1.85\"]\nfn main() {\n    let a: u32 = 10;\n    let _ = u32::midpoint(a, 5); //~ ERROR: manual implementation of `midpoint`\n\n    let f: f32 = 10.0;\n    let _ = f32::midpoint(f, 5.0); //~ ERROR: manual implementation of `midpoint`\n\n    let _: u32 = 5 + u32::midpoint(8, 8) + 2; //~ ERROR: manual implementation of `midpoint`\n    let _: u32 = const { u32::midpoint(8, 8) }; //~ ERROR: manual implementation of `midpoint`\n    let _: f64 = const { f64::midpoint(8.0f64, 8.) }; //~ ERROR: manual implementation of `midpoint`\n    let _: u32 = u32::midpoint(u32::default(), u32::default()); //~ ERROR: manual implementation of `midpoint`\n    let _: u32 = u32::midpoint(two!(), two!()); //~ ERROR: manual implementation of `midpoint`\n\n    // Do not lint in presence of an addition with more than 2 operands\n    let _: u32 = (10 + 20 + 30) / 2;\n\n    // Do not lint if whole or part is coming from a macro\n    let _ = mac!(10, 20);\n    let _: u32 = add!(10u32, 20u32) / 2;\n    let _: u32 = (10 + 20) / two!();\n\n    // Do not lint if a literal is not present\n    let _ = (f + 5.0) / (1.0 + 1.0);\n\n    // Do not lint on signed integer types\n    let i: i32 = 10;\n    let _ = (i + 5) / 2;\n\n    // Do not lint on (x+1)/2 or (1+x)/2 as this looks more like a `div_ceil()` operation\n    let _ = (i + 1) / 2;\n    let _ = (1 + i) / 2;\n\n    // But if we see (x+1.0)/2.0 or (x+1.0)/2.0, it is probably a midpoint operation\n    let _ = f32::midpoint(f, 1.0); //~ ERROR: manual implementation of `midpoint`\n    let _ = f32::midpoint(1.0, f); //~ ERROR: manual implementation of `midpoint`\n}\n\n#[clippy::msrv = \"1.86\"]\nfn older_signed_midpoint(i: i32) {\n    // Do not lint\n    let _ = (i + 10) / 2;\n}\n\n#[clippy::msrv = \"1.87\"]\nfn signed_midpoint(i: i32) {\n    let _ = i32::midpoint(i, 10); //~ ERROR: manual implementation of `midpoint`\n}\n"
  },
  {
    "path": "tests/ui/manual_midpoint.rs",
    "content": "#![warn(clippy::manual_midpoint)]\n\nmacro_rules! mac {\n    ($a: expr, $b: expr) => {\n        ($a + $b) / 2\n    };\n}\n\nmacro_rules! add {\n    ($a: expr, $b: expr) => {\n        ($a + $b)\n    };\n}\n\nmacro_rules! two {\n    () => {\n        2\n    };\n}\n\n#[clippy::msrv = \"1.84\"]\nfn older_msrv() {\n    let a: u32 = 10;\n    let _ = (a + 5) / 2;\n}\n\n#[clippy::msrv = \"1.85\"]\nfn main() {\n    let a: u32 = 10;\n    let _ = (a + 5) / 2; //~ ERROR: manual implementation of `midpoint`\n\n    let f: f32 = 10.0;\n    let _ = (f + 5.0) / 2.0; //~ ERROR: manual implementation of `midpoint`\n\n    let _: u32 = 5 + (8 + 8) / 2 + 2; //~ ERROR: manual implementation of `midpoint`\n    let _: u32 = const { (8 + 8) / 2 }; //~ ERROR: manual implementation of `midpoint`\n    let _: f64 = const { (8.0f64 + 8.) / 2. }; //~ ERROR: manual implementation of `midpoint`\n    let _: u32 = (u32::default() + u32::default()) / 2; //~ ERROR: manual implementation of `midpoint`\n    let _: u32 = (two!() + two!()) / 2; //~ ERROR: manual implementation of `midpoint`\n\n    // Do not lint in presence of an addition with more than 2 operands\n    let _: u32 = (10 + 20 + 30) / 2;\n\n    // Do not lint if whole or part is coming from a macro\n    let _ = mac!(10, 20);\n    let _: u32 = add!(10u32, 20u32) / 2;\n    let _: u32 = (10 + 20) / two!();\n\n    // Do not lint if a literal is not present\n    let _ = (f + 5.0) / (1.0 + 1.0);\n\n    // Do not lint on signed integer types\n    let i: i32 = 10;\n    let _ = (i + 5) / 2;\n\n    // Do not lint on (x+1)/2 or (1+x)/2 as this looks more like a `div_ceil()` operation\n    let _ = (i + 1) / 2;\n    let _ = (1 + i) / 2;\n\n    // But if we see (x+1.0)/2.0 or (x+1.0)/2.0, it is probably a midpoint operation\n    let _ = (f + 1.0) / 2.0; //~ ERROR: manual implementation of `midpoint`\n    let _ = (1.0 + f) / 2.0; //~ ERROR: manual implementation of `midpoint`\n}\n\n#[clippy::msrv = \"1.86\"]\nfn older_signed_midpoint(i: i32) {\n    // Do not lint\n    let _ = (i + 10) / 2;\n}\n\n#[clippy::msrv = \"1.87\"]\nfn signed_midpoint(i: i32) {\n    let _ = (i + 10) / 2; //~ ERROR: manual implementation of `midpoint`\n}\n"
  },
  {
    "path": "tests/ui/manual_midpoint.stderr",
    "content": "error: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:30:13\n   |\nLL |     let _ = (a + 5) / 2;\n   |             ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(a, 5)`\n   |\n   = note: `-D clippy::manual-midpoint` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_midpoint)]`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:33:13\n   |\nLL |     let _ = (f + 5.0) / 2.0;\n   |             ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(f, 5.0)`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:35:22\n   |\nLL |     let _: u32 = 5 + (8 + 8) / 2 + 2;\n   |                      ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(8, 8)`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:36:26\n   |\nLL |     let _: u32 = const { (8 + 8) / 2 };\n   |                          ^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(8, 8)`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:37:26\n   |\nLL |     let _: f64 = const { (8.0f64 + 8.) / 2. };\n   |                          ^^^^^^^^^^^^^^^^^^ help: use `f64::midpoint` instead: `f64::midpoint(8.0f64, 8.)`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:38:18\n   |\nLL |     let _: u32 = (u32::default() + u32::default()) / 2;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(u32::default(), u32::default())`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:39:18\n   |\nLL |     let _: u32 = (two!() + two!()) / 2;\n   |                  ^^^^^^^^^^^^^^^^^^^^^ help: use `u32::midpoint` instead: `u32::midpoint(two!(), two!())`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:61:13\n   |\nLL |     let _ = (f + 1.0) / 2.0;\n   |             ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(f, 1.0)`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:62:13\n   |\nLL |     let _ = (1.0 + f) / 2.0;\n   |             ^^^^^^^^^^^^^^^ help: use `f32::midpoint` instead: `f32::midpoint(1.0, f)`\n\nerror: manual implementation of `midpoint` which can overflow\n  --> tests/ui/manual_midpoint.rs:73:13\n   |\nLL |     let _ = (i + 10) / 2;\n   |             ^^^^^^^^^^^^ help: use `i32::midpoint` instead: `i32::midpoint(i, 10)`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_next_back.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::manual_next_back)]\n\nstruct FakeIter(std::ops::Range<i32>);\n\nimpl FakeIter {\n    fn rev(self) -> Self {\n        self\n    }\n\n    fn next(&self) {}\n}\n\nimpl DoubleEndedIterator for FakeIter {\n    fn next_back(&mut self) -> Option<Self::Item> {\n        self.0.next_back()\n    }\n}\n\nimpl Iterator for FakeIter {\n    type Item = i32;\n    fn next(&mut self) -> Option<Self::Item> {\n        self.0.next()\n    }\n}\n\nfn main() {\n    // should not lint\n    FakeIter(0..10).rev().next();\n\n    // should lint\n    let _ = (0..10).next_back().unwrap();\n    //~^ manual_next_back\n    let _ = \"something\".bytes().next_back();\n    //~^ manual_next_back\n}\n"
  },
  {
    "path": "tests/ui/manual_next_back.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::manual_next_back)]\n\nstruct FakeIter(std::ops::Range<i32>);\n\nimpl FakeIter {\n    fn rev(self) -> Self {\n        self\n    }\n\n    fn next(&self) {}\n}\n\nimpl DoubleEndedIterator for FakeIter {\n    fn next_back(&mut self) -> Option<Self::Item> {\n        self.0.next_back()\n    }\n}\n\nimpl Iterator for FakeIter {\n    type Item = i32;\n    fn next(&mut self) -> Option<Self::Item> {\n        self.0.next()\n    }\n}\n\nfn main() {\n    // should not lint\n    FakeIter(0..10).rev().next();\n\n    // should lint\n    let _ = (0..10).rev().next().unwrap();\n    //~^ manual_next_back\n    let _ = \"something\".bytes().rev().next();\n    //~^ manual_next_back\n}\n"
  },
  {
    "path": "tests/ui/manual_next_back.stderr",
    "content": "error: manual backwards iteration\n  --> tests/ui/manual_next_back.rs:32:20\n   |\nLL |     let _ = (0..10).rev().next().unwrap();\n   |                    ^^^^^^^^^^^^^ help: use: `.next_back()`\n   |\n   = note: `-D clippy::manual-next-back` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_next_back)]`\n\nerror: manual backwards iteration\n  --> tests/ui/manual_next_back.rs:34:32\n   |\nLL |     let _ = \"something\".bytes().rev().next();\n   |                                ^^^^^^^^^^^^^ help: use: `.next_back()`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_non_exhaustive_enum.rs",
    "content": "#![warn(clippy::manual_non_exhaustive)]\n#![allow(unused)]\n//@no-rustfix\npub enum E {\n    //~^ manual_non_exhaustive\n    A,\n    B,\n    #[doc(hidden)]\n    _C,\n}\n\n// if the user explicitly marks as nonexhaustive we shouldn't warn them\n#[non_exhaustive]\npub enum Ep {\n    A,\n    B,\n    #[doc(hidden)]\n    _C,\n}\n\n// marker variant does not have doc hidden attribute, should be ignored\npub enum NoDocHidden {\n    A,\n    B,\n    _C,\n}\n\n// name of variant with doc hidden does not start with underscore\npub enum NoUnderscore {\n    //~^ manual_non_exhaustive\n    A,\n    B,\n    #[doc(hidden)]\n    C,\n}\n\n// variant with doc hidden is not unit, should be ignored\npub enum NotUnit {\n    A,\n    B,\n    #[doc(hidden)]\n    _C(bool),\n}\n\n// variant with doc hidden is the only one, should be ignored\npub enum OnlyMarker {\n    #[doc(hidden)]\n    _A,\n}\n\n// variant with multiple markers, should be ignored\npub enum MultipleMarkers {\n    A,\n    #[doc(hidden)]\n    _B,\n    #[doc(hidden)]\n    _C,\n}\n\n// already non_exhaustive and no markers, should be ignored\n#[non_exhaustive]\npub enum NonExhaustive {\n    A,\n    B,\n}\n\n// marked is used, don't lint\npub enum UsedHidden {\n    #[doc(hidden)]\n    _A,\n    B,\n    C,\n}\nfn foo(x: &mut UsedHidden) {\n    if matches!(*x, UsedHidden::B) {\n        *x = UsedHidden::_A;\n    }\n}\n\n#[expect(clippy::manual_non_exhaustive)]\npub enum ExpectLint {\n    A,\n    B,\n    #[doc(hidden)]\n    _C,\n}\n"
  },
  {
    "path": "tests/ui/manual_non_exhaustive_enum.stderr",
    "content": "error: this seems like a manual implementation of the non-exhaustive pattern\n  --> tests/ui/manual_non_exhaustive_enum.rs:4:1\n   |\nLL | / pub enum E {\nLL | |\nLL | |     A,\nLL | |     B,\nLL | |     #[doc(hidden)]\nLL | |     _C,\nLL | | }\n   | |_^\n   |\nhelp: remove this variant\n  --> tests/ui/manual_non_exhaustive_enum.rs:9:5\n   |\nLL |     _C,\n   |     ^^\n   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]`\nhelp: use the `#[non_exhaustive]` attribute instead\n   |\nLL + #[non_exhaustive]\nLL | pub enum E {\n   |\n\nerror: this seems like a manual implementation of the non-exhaustive pattern\n  --> tests/ui/manual_non_exhaustive_enum.rs:29:1\n   |\nLL | / pub enum NoUnderscore {\nLL | |\nLL | |     A,\nLL | |     B,\nLL | |     #[doc(hidden)]\nLL | |     C,\nLL | | }\n   | |_^\n   |\nhelp: remove this variant\n  --> tests/ui/manual_non_exhaustive_enum.rs:34:5\n   |\nLL |     C,\n   |     ^\nhelp: use the `#[non_exhaustive]` attribute instead\n   |\nLL + #[non_exhaustive]\nLL | pub enum NoUnderscore {\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_non_exhaustive_struct.rs",
    "content": "#![warn(clippy::manual_non_exhaustive)]\n#![allow(unused)]\n//@no-rustfix\npub mod structs {\n    pub struct S {\n        //~^ manual_non_exhaustive\n        pub a: i32,\n        pub b: i32,\n        _c: (),\n    }\n\n    // user forgot to remove the private field\n    #[non_exhaustive]\n    pub struct Sp {\n        //~^ manual_non_exhaustive\n        pub a: i32,\n        pub b: i32,\n        _c: (),\n    }\n\n    // some other fields are private, should be ignored\n    pub struct PrivateFields {\n        a: i32,\n        pub b: i32,\n        _c: (),\n    }\n\n    pub struct NoUnderscore {\n        //~^ manual_non_exhaustive\n        pub a: i32,\n        pub b: i32,\n        c: (),\n    }\n\n    // private field is not unit type, should be ignored\n    pub struct NotUnit {\n        pub a: i32,\n        pub b: i32,\n        _c: i32,\n    }\n\n    // private field is the only field, should be ignored\n    pub struct OnlyMarker {\n        _a: (),\n    }\n\n    // already non exhaustive and no private fields, should be ignored\n    #[non_exhaustive]\n    pub struct NonExhaustive {\n        pub a: i32,\n        pub b: i32,\n    }\n}\n\npub mod tuple_structs {\n    pub struct T(pub i32, pub i32, ());\n    //~^ manual_non_exhaustive\n\n    // user forgot to remove the private field\n    #[non_exhaustive]\n    pub struct Tp(pub i32, pub i32, ());\n    //~^ manual_non_exhaustive\n\n    // some other fields are private, should be ignored\n    pub struct PrivateFields(pub i32, i32, ());\n\n    // private field is not unit type, should be ignored\n    pub struct NotUnit(pub i32, pub i32, i32);\n\n    // private field is the only field, should be ignored\n    pub struct OnlyMarker(());\n\n    // already non exhaustive and no private fields, should be ignored\n    #[non_exhaustive]\n    pub struct NonExhaustive(pub i32, pub i32);\n}\n\nmod private {\n    // Don't lint structs that are not actually public as `#[non_exhaustive]` only applies to\n    // external crates. The manual pattern can still be used to get module local non exhaustiveness\n    pub struct NotPublic {\n        pub a: i32,\n        pub b: i32,\n        _c: (),\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_non_exhaustive_struct.stderr",
    "content": "error: this seems like a manual implementation of the non-exhaustive pattern\n  --> tests/ui/manual_non_exhaustive_struct.rs:5:5\n   |\nLL | /     pub struct S {\nLL | |\nLL | |         pub a: i32,\nLL | |         pub b: i32,\nLL | |         _c: (),\nLL | |     }\n   | |_____^\n   |\nhelp: remove this field\n  --> tests/ui/manual_non_exhaustive_struct.rs:9:9\n   |\nLL |         _c: (),\n   |         ^^^^^^\n   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]`\nhelp: use the `#[non_exhaustive]` attribute instead\n   |\nLL ~     #[non_exhaustive]\nLL ~     pub struct S {\n   |\n\nerror: this seems like a manual implementation of the non-exhaustive pattern\n  --> tests/ui/manual_non_exhaustive_struct.rs:14:5\n   |\nLL | /     pub struct Sp {\nLL | |\nLL | |         pub a: i32,\nLL | |         pub b: i32,\nLL | |         _c: (),\nLL | |     }\n   | |_____^\n   |\nnote: the struct is already non-exhaustive\n  --> tests/ui/manual_non_exhaustive_struct.rs:13:5\n   |\nLL |     #[non_exhaustive]\n   |     ^^^^^^^^^^^^^^^^^\nhelp: remove this field\n  --> tests/ui/manual_non_exhaustive_struct.rs:18:9\n   |\nLL |         _c: (),\n   |         ^^^^^^\n\nerror: this seems like a manual implementation of the non-exhaustive pattern\n  --> tests/ui/manual_non_exhaustive_struct.rs:28:5\n   |\nLL | /     pub struct NoUnderscore {\nLL | |\nLL | |         pub a: i32,\nLL | |         pub b: i32,\nLL | |         c: (),\nLL | |     }\n   | |_____^\n   |\nhelp: remove this field\n  --> tests/ui/manual_non_exhaustive_struct.rs:32:9\n   |\nLL |         c: (),\n   |         ^^^^^\nhelp: use the `#[non_exhaustive]` attribute instead\n   |\nLL ~     #[non_exhaustive]\nLL ~     pub struct NoUnderscore {\n   |\n\nerror: this seems like a manual implementation of the non-exhaustive pattern\n  --> tests/ui/manual_non_exhaustive_struct.rs:56:5\n   |\nLL |     pub struct T(pub i32, pub i32, ());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove this field\n  --> tests/ui/manual_non_exhaustive_struct.rs:56:36\n   |\nLL |     pub struct T(pub i32, pub i32, ());\n   |                                    ^^\nhelp: use the `#[non_exhaustive]` attribute instead\n   |\nLL ~     #[non_exhaustive]\nLL ~     pub struct T(pub i32, pub i32, ());\n   |\n\nerror: this seems like a manual implementation of the non-exhaustive pattern\n  --> tests/ui/manual_non_exhaustive_struct.rs:61:5\n   |\nLL |     pub struct Tp(pub i32, pub i32, ());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the struct is already non-exhaustive\n  --> tests/ui/manual_non_exhaustive_struct.rs:60:5\n   |\nLL |     #[non_exhaustive]\n   |     ^^^^^^^^^^^^^^^^^\nhelp: remove this field\n  --> tests/ui/manual_non_exhaustive_struct.rs:61:37\n   |\nLL |     pub struct Tp(pub i32, pub i32, ());\n   |                                     ^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_ok_err.fixed",
    "content": "#![warn(clippy::manual_ok_err)]\n\nfn funcall() -> Result<u32, &'static str> {\n    todo!()\n}\n\nfn main() {\n    let _ = funcall().ok();\n\n    let _ = funcall().ok();\n\n    let _ = funcall().err();\n\n    let _ = funcall().err();\n\n    let _ = funcall().ok();\n\n    let _ = funcall().err();\n\n    #[allow(clippy::redundant_pattern)]\n    let _ = funcall().ok();\n\n    struct S;\n\n    impl std::ops::Neg for S {\n        type Output = Result<u32, &'static str>;\n\n        fn neg(self) -> Self::Output {\n            funcall()\n        }\n    }\n\n    // Suggestion should be properly parenthesized\n    let _ = (-S).ok();\n\n    no_lint();\n}\n\nfn no_lint() {\n    let _ = match funcall() {\n        Ok(v) if v > 3 => Some(v),\n        _ => None,\n    };\n\n    let _ = match funcall() {\n        Err(_) => None,\n        Ok(3) => None,\n        Ok(v) => Some(v),\n    };\n\n    let _ = match funcall() {\n        _ => None,\n        Ok(v) => Some(v),\n    };\n\n    let _ = match funcall() {\n        Err(_) | Ok(3) => None,\n        Ok(v) => Some(v),\n    };\n\n    #[expect(clippy::redundant_pattern)]\n    let _ = match funcall() {\n        _v @ _ => None,\n        Ok(v) => Some(v),\n    };\n\n    // Content of `Option` and matching content of `Result` do\n    // not have the same type.\n    let _: Option<&dyn std::any::Any> = match Ok::<_, ()>(&1) {\n        Ok(v) => Some(v),\n        _ => None,\n    };\n\n    let _ = match Ok::<_, ()>(&1) {\n        _x => None,\n        Ok(v) => Some(v),\n    };\n\n    let _ = match Ok::<_, std::convert::Infallible>(1) {\n        Ok(3) => None,\n        Ok(v) => Some(v),\n    };\n\n    let _ = match funcall() {\n        Ok(v @ 1..) => Some(v),\n        _ => None,\n    };\n}\n\nconst fn cf(x: Result<u32, &'static str>) -> Option<u32> {\n    // Do not lint in const code\n    match x {\n        Ok(v) => Some(v),\n        Err(_) => None,\n    }\n}\n\nfn issue14239() {\n    let _ = if false {\n        None\n    } else {\n        \"1\".parse::<u8>().ok()\n    };\n    //~^^^^^ manual_ok_err\n}\n\nmod issue15051 {\n    struct Container {\n        field: Result<bool, ()>,\n    }\n\n    #[allow(clippy::needless_borrow)]\n    fn with_addr_of(x: &Container) -> Option<&bool> {\n        (&x.field).as_ref().ok()\n    }\n\n    fn from_fn(x: &Container) -> Option<&bool> {\n        let result_with_ref = || &x.field;\n        result_with_ref().as_ref().ok()\n    }\n\n    fn result_with_ref_mut(x: &mut Container) -> &mut Result<bool, ()> {\n        &mut x.field\n    }\n\n    fn from_fn_mut(x: &mut Container) -> Option<&mut bool> {\n        result_with_ref_mut(x).as_mut().ok()\n    }\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            Ok::<i32, ()>($val)\n        };\n    }\n\n    let _ = test_expr!(42).ok();\n}\n"
  },
  {
    "path": "tests/ui/manual_ok_err.rs",
    "content": "#![warn(clippy::manual_ok_err)]\n\nfn funcall() -> Result<u32, &'static str> {\n    todo!()\n}\n\nfn main() {\n    let _ = match funcall() {\n        //~^ manual_ok_err\n        Ok(v) => Some(v),\n        Err(_) => None,\n    };\n\n    let _ = match funcall() {\n        //~^ manual_ok_err\n        Ok(v) => Some(v),\n        _v => None,\n    };\n\n    let _ = match funcall() {\n        //~^ manual_ok_err\n        Err(v) => Some(v),\n        Ok(_) => None,\n    };\n\n    let _ = match funcall() {\n        //~^ manual_ok_err\n        Err(v) => Some(v),\n        _v => None,\n    };\n\n    let _ = if let Ok(v) = funcall() {\n        //~^ manual_ok_err\n\n        Some(v)\n    } else {\n        None\n    };\n\n    let _ = if let Err(v) = funcall() {\n        //~^ manual_ok_err\n\n        Some(v)\n    } else {\n        None\n    };\n\n    #[allow(clippy::redundant_pattern)]\n    let _ = match funcall() {\n        //~^ manual_ok_err\n        Ok(v) => Some(v),\n        _v @ _ => None,\n    };\n\n    struct S;\n\n    impl std::ops::Neg for S {\n        type Output = Result<u32, &'static str>;\n\n        fn neg(self) -> Self::Output {\n            funcall()\n        }\n    }\n\n    // Suggestion should be properly parenthesized\n    let _ = match -S {\n        //~^ manual_ok_err\n        Ok(v) => Some(v),\n        _ => None,\n    };\n\n    no_lint();\n}\n\nfn no_lint() {\n    let _ = match funcall() {\n        Ok(v) if v > 3 => Some(v),\n        _ => None,\n    };\n\n    let _ = match funcall() {\n        Err(_) => None,\n        Ok(3) => None,\n        Ok(v) => Some(v),\n    };\n\n    let _ = match funcall() {\n        _ => None,\n        Ok(v) => Some(v),\n    };\n\n    let _ = match funcall() {\n        Err(_) | Ok(3) => None,\n        Ok(v) => Some(v),\n    };\n\n    #[expect(clippy::redundant_pattern)]\n    let _ = match funcall() {\n        _v @ _ => None,\n        Ok(v) => Some(v),\n    };\n\n    // Content of `Option` and matching content of `Result` do\n    // not have the same type.\n    let _: Option<&dyn std::any::Any> = match Ok::<_, ()>(&1) {\n        Ok(v) => Some(v),\n        _ => None,\n    };\n\n    let _ = match Ok::<_, ()>(&1) {\n        _x => None,\n        Ok(v) => Some(v),\n    };\n\n    let _ = match Ok::<_, std::convert::Infallible>(1) {\n        Ok(3) => None,\n        Ok(v) => Some(v),\n    };\n\n    let _ = match funcall() {\n        Ok(v @ 1..) => Some(v),\n        _ => None,\n    };\n}\n\nconst fn cf(x: Result<u32, &'static str>) -> Option<u32> {\n    // Do not lint in const code\n    match x {\n        Ok(v) => Some(v),\n        Err(_) => None,\n    }\n}\n\nfn issue14239() {\n    let _ = if false {\n        None\n    } else if let Ok(n) = \"1\".parse::<u8>() {\n        Some(n)\n    } else {\n        None\n    };\n    //~^^^^^ manual_ok_err\n}\n\nmod issue15051 {\n    struct Container {\n        field: Result<bool, ()>,\n    }\n\n    #[allow(clippy::needless_borrow)]\n    fn with_addr_of(x: &Container) -> Option<&bool> {\n        match &x.field {\n            //~^ manual_ok_err\n            Ok(panel) => Some(panel),\n            Err(_) => None,\n        }\n    }\n\n    fn from_fn(x: &Container) -> Option<&bool> {\n        let result_with_ref = || &x.field;\n        match result_with_ref() {\n            //~^ manual_ok_err\n            Ok(panel) => Some(panel),\n            Err(_) => None,\n        }\n    }\n\n    fn result_with_ref_mut(x: &mut Container) -> &mut Result<bool, ()> {\n        &mut x.field\n    }\n\n    fn from_fn_mut(x: &mut Container) -> Option<&mut bool> {\n        match result_with_ref_mut(x) {\n            //~^ manual_ok_err\n            Ok(panel) => Some(panel),\n            Err(_) => None,\n        }\n    }\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            Ok::<i32, ()>($val)\n        };\n    }\n\n    let _ = match test_expr!(42) {\n        //~^ manual_ok_err\n        Ok(v) => Some(v),\n        Err(_) => None,\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_ok_err.stderr",
    "content": "error: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:8:13\n   |\nLL |       let _ = match funcall() {\n   |  _____________^\nLL | |\nLL | |         Ok(v) => Some(v),\nLL | |         Err(_) => None,\nLL | |     };\n   | |_____^ help: replace with: `funcall().ok()`\n   |\n   = note: `-D clippy::manual-ok-err` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_ok_err)]`\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:14:13\n   |\nLL |       let _ = match funcall() {\n   |  _____________^\nLL | |\nLL | |         Ok(v) => Some(v),\nLL | |         _v => None,\nLL | |     };\n   | |_____^ help: replace with: `funcall().ok()`\n\nerror: manual implementation of `err`\n  --> tests/ui/manual_ok_err.rs:20:13\n   |\nLL |       let _ = match funcall() {\n   |  _____________^\nLL | |\nLL | |         Err(v) => Some(v),\nLL | |         Ok(_) => None,\nLL | |     };\n   | |_____^ help: replace with: `funcall().err()`\n\nerror: manual implementation of `err`\n  --> tests/ui/manual_ok_err.rs:26:13\n   |\nLL |       let _ = match funcall() {\n   |  _____________^\nLL | |\nLL | |         Err(v) => Some(v),\nLL | |         _v => None,\nLL | |     };\n   | |_____^ help: replace with: `funcall().err()`\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:32:13\n   |\nLL |       let _ = if let Ok(v) = funcall() {\n   |  _____________^\nLL | |\nLL | |\nLL | |         Some(v)\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^ help: replace with: `funcall().ok()`\n\nerror: manual implementation of `err`\n  --> tests/ui/manual_ok_err.rs:40:13\n   |\nLL |       let _ = if let Err(v) = funcall() {\n   |  _____________^\nLL | |\nLL | |\nLL | |         Some(v)\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^ help: replace with: `funcall().err()`\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:49:13\n   |\nLL |       let _ = match funcall() {\n   |  _____________^\nLL | |\nLL | |         Ok(v) => Some(v),\nLL | |         _v @ _ => None,\nLL | |     };\n   | |_____^ help: replace with: `funcall().ok()`\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:66:13\n   |\nLL |       let _ = match -S {\n   |  _____________^\nLL | |\nLL | |         Ok(v) => Some(v),\nLL | |         _ => None,\nLL | |     };\n   | |_____^ help: replace with: `(-S).ok()`\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:137:12\n   |\nLL |       } else if let Ok(n) = \"1\".parse::<u8>() {\n   |  ____________^\nLL | |         Some(n)\nLL | |     } else {\nLL | |         None\nLL | |     };\n   | |_____^\n   |\nhelp: replace with\n   |\nLL ~     } else {\nLL +         \"1\".parse::<u8>().ok()\nLL ~     };\n   |\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:152:9\n   |\nLL | /         match &x.field {\nLL | |\nLL | |             Ok(panel) => Some(panel),\nLL | |             Err(_) => None,\nLL | |         }\n   | |_________^ help: replace with: `(&x.field).as_ref().ok()`\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:161:9\n   |\nLL | /         match result_with_ref() {\nLL | |\nLL | |             Ok(panel) => Some(panel),\nLL | |             Err(_) => None,\nLL | |         }\n   | |_________^ help: replace with: `result_with_ref().as_ref().ok()`\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:173:9\n   |\nLL | /         match result_with_ref_mut(x) {\nLL | |\nLL | |             Ok(panel) => Some(panel),\nLL | |             Err(_) => None,\nLL | |         }\n   | |_________^ help: replace with: `result_with_ref_mut(x).as_mut().ok()`\n\nerror: manual implementation of `ok`\n  --> tests/ui/manual_ok_err.rs:188:13\n   |\nLL |       let _ = match test_expr!(42) {\n   |  _____________^\nLL | |\nLL | |         Ok(v) => Some(v),\nLL | |         Err(_) => None,\nLL | |     };\n   | |_____^ help: replace with: `test_expr!(42).ok()`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_ok_or.fixed",
    "content": "#![warn(clippy::manual_ok_or)]\n#![allow(clippy::or_fun_call)]\n#![allow(clippy::disallowed_names)]\n#![allow(clippy::redundant_closure)]\n#![allow(dead_code)]\n#![allow(unused_must_use)]\n\nfn main() {\n    // basic case\n    let foo: Option<i32> = None;\n    foo.ok_or(\"error\");\n    //~^ manual_ok_or\n\n    // eta expansion case\n    foo.ok_or(\"error\");\n    //~^ manual_ok_or\n\n    // turbo fish syntax\n    None::<i32>.ok_or(\"error\");\n    //~^ manual_ok_or\n\n    // multiline case\n    #[rustfmt::skip]\n    foo.ok_or(&format!(\n        \"{}{}{}{}{}{}{}\",\n        \"Alice\", \"Bob\", \"Sarah\", \"Marc\", \"Sandra\", \"Eric\", \"Jenifer\"));\n\n    // not applicable, closure isn't direct `Ok` wrapping\n    foo.map_or(Err(\"error\"), |v| Ok(v + 1));\n\n    // not applicable, or side isn't `Result::Err`\n    foo.map_or(Ok::<i32, &str>(1), |v| Ok(v));\n\n    // not applicable, expr is not a `Result` value\n    foo.map_or(42, |v| v);\n\n    // TODO patterns not covered yet\n    match foo {\n        Some(v) => Ok(v),\n        None => Err(\"error\"),\n    };\n    foo.map_or_else(|| Err(\"error\"), |v| Ok(v));\n}\n"
  },
  {
    "path": "tests/ui/manual_ok_or.rs",
    "content": "#![warn(clippy::manual_ok_or)]\n#![allow(clippy::or_fun_call)]\n#![allow(clippy::disallowed_names)]\n#![allow(clippy::redundant_closure)]\n#![allow(dead_code)]\n#![allow(unused_must_use)]\n\nfn main() {\n    // basic case\n    let foo: Option<i32> = None;\n    foo.map_or(Err(\"error\"), |v| Ok(v));\n    //~^ manual_ok_or\n\n    // eta expansion case\n    foo.map_or(Err(\"error\"), Ok);\n    //~^ manual_ok_or\n\n    // turbo fish syntax\n    None::<i32>.map_or(Err(\"error\"), |v| Ok(v));\n    //~^ manual_ok_or\n\n    // multiline case\n    #[rustfmt::skip]\n    foo.map_or(Err::<i32, &str>(\n    //~^ manual_ok_or\n        &format!(\n            \"{}{}{}{}{}{}{}\",\n            \"Alice\", \"Bob\", \"Sarah\", \"Marc\", \"Sandra\", \"Eric\", \"Jenifer\")\n        ),\n        |v| Ok(v),\n    );\n\n    // not applicable, closure isn't direct `Ok` wrapping\n    foo.map_or(Err(\"error\"), |v| Ok(v + 1));\n\n    // not applicable, or side isn't `Result::Err`\n    foo.map_or(Ok::<i32, &str>(1), |v| Ok(v));\n\n    // not applicable, expr is not a `Result` value\n    foo.map_or(42, |v| v);\n\n    // TODO patterns not covered yet\n    match foo {\n        Some(v) => Ok(v),\n        None => Err(\"error\"),\n    };\n    foo.map_or_else(|| Err(\"error\"), |v| Ok(v));\n}\n"
  },
  {
    "path": "tests/ui/manual_ok_or.stderr",
    "content": "error: this pattern reimplements `Option::ok_or`\n  --> tests/ui/manual_ok_or.rs:11:5\n   |\nLL |     foo.map_or(Err(\"error\"), |v| Ok(v));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or(\"error\")`\n   |\n   = note: `-D clippy::manual-ok-or` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_ok_or)]`\n\nerror: this pattern reimplements `Option::ok_or`\n  --> tests/ui/manual_ok_or.rs:15:5\n   |\nLL |     foo.map_or(Err(\"error\"), Ok);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `foo.ok_or(\"error\")`\n\nerror: this pattern reimplements `Option::ok_or`\n  --> tests/ui/manual_ok_or.rs:19:5\n   |\nLL |     None::<i32>.map_or(Err(\"error\"), |v| Ok(v));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `None::<i32>.ok_or(\"error\")`\n\nerror: this pattern reimplements `Option::ok_or`\n  --> tests/ui/manual_ok_or.rs:24:5\n   |\nLL | /     foo.map_or(Err::<i32, &str>(\nLL | |\nLL | |         &format!(\nLL | |             \"{}{}{}{}{}{}{}\",\n...  |\nLL | |         |v| Ok(v),\nLL | |     );\n   | |_____^\n   |\nhelp: replace with\n   |\nLL ~     foo.ok_or(&format!(\nLL +         \"{}{}{}{}{}{}{}\",\nLL ~         \"Alice\", \"Bob\", \"Sarah\", \"Marc\", \"Sandra\", \"Eric\", \"Jenifer\"));\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_option_as_slice.fixed",
    "content": "#![warn(clippy::manual_option_as_slice)]\n#![allow(clippy::redundant_closure, clippy::unwrap_or_default)]\n\nfn check(x: Option<u32>) {\n    _ = x.as_slice();\n\n    _ = x.as_slice();\n\n    _ = x.as_slice();\n    //~^ manual_option_as_slice\n\n    _ = x.as_slice();\n    //~^ manual_option_as_slice\n\n    _ = x.as_slice();\n    //~^ manual_option_as_slice\n\n    _ = x.as_slice();\n    //~^ manual_option_as_slice\n\n    {\n        use std::slice::from_ref;\n        _ = x.as_slice();\n        //~^ manual_option_as_slice\n    }\n\n    // possible false positives\n    let y = x.as_ref();\n    _ = match y {\n        // as_ref outside\n        Some(f) => &[f][..],\n        None => &[][..],\n    };\n    _ = match x.as_ref() {\n        Some(f) => std::slice::from_ref(f),\n        None => &[0],\n    };\n    _ = match x.as_ref() {\n        Some(42) => &[23],\n        Some(f) => std::slice::from_ref(f),\n        None => &[],\n    };\n    let b = &[42];\n    _ = if let Some(_f) = x.as_ref() {\n        std::slice::from_ref(b)\n    } else {\n        &[]\n    };\n    _ = x.as_ref().map_or(&[42][..], std::slice::from_ref);\n    _ = x.as_ref().map_or_else(|| &[42][..1], std::slice::from_ref);\n    _ = x.as_ref().map(|f| std::slice::from_ref(f)).unwrap_or_default();\n}\n\n#[clippy::msrv = \"1.74\"]\nfn check_msrv(x: Option<u32>) {\n    _ = x.as_ref().map_or(&[][..], std::slice::from_ref);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_option_as_slice.rs",
    "content": "#![warn(clippy::manual_option_as_slice)]\n#![allow(clippy::redundant_closure, clippy::unwrap_or_default)]\n\nfn check(x: Option<u32>) {\n    _ = match x.as_ref() {\n        //~^ manual_option_as_slice\n        Some(f) => std::slice::from_ref(f),\n        None => &[],\n    };\n\n    _ = if let Some(f) = x.as_ref() {\n        //~^ manual_option_as_slice\n\n        std::slice::from_ref(f)\n    } else {\n        &[]\n    };\n\n    _ = x.as_ref().map_or(&[][..], std::slice::from_ref);\n    //~^ manual_option_as_slice\n\n    _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref);\n    //~^ manual_option_as_slice\n\n    _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default();\n    //~^ manual_option_as_slice\n\n    _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref);\n    //~^ manual_option_as_slice\n\n    {\n        use std::slice::from_ref;\n        _ = x.as_ref().map_or_else(<&[_]>::default, from_ref);\n        //~^ manual_option_as_slice\n    }\n\n    // possible false positives\n    let y = x.as_ref();\n    _ = match y {\n        // as_ref outside\n        Some(f) => &[f][..],\n        None => &[][..],\n    };\n    _ = match x.as_ref() {\n        Some(f) => std::slice::from_ref(f),\n        None => &[0],\n    };\n    _ = match x.as_ref() {\n        Some(42) => &[23],\n        Some(f) => std::slice::from_ref(f),\n        None => &[],\n    };\n    let b = &[42];\n    _ = if let Some(_f) = x.as_ref() {\n        std::slice::from_ref(b)\n    } else {\n        &[]\n    };\n    _ = x.as_ref().map_or(&[42][..], std::slice::from_ref);\n    _ = x.as_ref().map_or_else(|| &[42][..1], std::slice::from_ref);\n    _ = x.as_ref().map(|f| std::slice::from_ref(f)).unwrap_or_default();\n}\n\n#[clippy::msrv = \"1.74\"]\nfn check_msrv(x: Option<u32>) {\n    _ = x.as_ref().map_or(&[][..], std::slice::from_ref);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_option_as_slice.stderr",
    "content": "error: manual implementation of `Option::as_slice`\n  --> tests/ui/manual_option_as_slice.rs:5:9\n   |\nLL |       _ = match x.as_ref() {\n   |  _________^\nLL | |\nLL | |         Some(f) => std::slice::from_ref(f),\nLL | |         None => &[],\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::manual-option-as-slice` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_option_as_slice)]`\nhelp: use `Option::as_slice` directly\n   |\nLL -     _ = match x.as_ref() {\nLL -\nLL -         Some(f) => std::slice::from_ref(f),\nLL -         None => &[],\nLL -     };\nLL +     _ = x.as_slice();\n   |\n\nerror: manual implementation of `Option::as_slice`\n  --> tests/ui/manual_option_as_slice.rs:11:9\n   |\nLL |       _ = if let Some(f) = x.as_ref() {\n   |  _________^\nLL | |\nLL | |\nLL | |         std::slice::from_ref(f)\nLL | |     } else {\nLL | |         &[]\nLL | |     };\n   | |_____^\n   |\nhelp: use `Option::as_slice` directly\n   |\nLL -     _ = if let Some(f) = x.as_ref() {\nLL -\nLL - \nLL -         std::slice::from_ref(f)\nLL -     } else {\nLL -         &[]\nLL -     };\nLL +     _ = x.as_slice();\n   |\n\nerror: manual implementation of `Option::as_slice`\n  --> tests/ui/manual_option_as_slice.rs:19:9\n   |\nLL |     _ = x.as_ref().map_or(&[][..], std::slice::from_ref);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `Option::as_slice` directly\n   |\nLL -     _ = x.as_ref().map_or(&[][..], std::slice::from_ref);\nLL +     _ = x.as_slice();\n   |\n\nerror: manual implementation of `Option::as_slice`\n  --> tests/ui/manual_option_as_slice.rs:22:9\n   |\nLL |     _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `Option::as_slice` directly\n   |\nLL -     _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref);\nLL +     _ = x.as_slice();\n   |\n\nerror: manual implementation of `Option::as_slice`\n  --> tests/ui/manual_option_as_slice.rs:25:9\n   |\nLL |     _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `Option::as_slice` directly\n   |\nLL -     _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default();\nLL +     _ = x.as_slice();\n   |\n\nerror: manual implementation of `Option::as_slice`\n  --> tests/ui/manual_option_as_slice.rs:28:9\n   |\nLL |     _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `Option::as_slice` directly\n   |\nLL -     _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref);\nLL +     _ = x.as_slice();\n   |\n\nerror: manual implementation of `Option::as_slice`\n  --> tests/ui/manual_option_as_slice.rs:33:13\n   |\nLL |         _ = x.as_ref().map_or_else(<&[_]>::default, from_ref);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `Option::as_slice` directly\n   |\nLL -         _ = x.as_ref().map_or_else(<&[_]>::default, from_ref);\nLL +         _ = x.as_slice();\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_pattern_char_comparison.fixed",
    "content": "#![warn(clippy::manual_pattern_char_comparison)]\n\nstruct NotStr;\n\nimpl NotStr {\n    fn find(&self, _: impl FnMut(char) -> bool) {}\n}\n\nfn main() {\n    let sentence = \"Hello, world!\";\n    sentence.trim_end_matches(['.', ',', '!', '?']);\n    //~^ manual_pattern_char_comparison\n    sentence.split(['\\n', 'X']);\n    //~^ manual_pattern_char_comparison\n    sentence.split(['\\n', 'X']);\n    //~^ manual_pattern_char_comparison\n    sentence.splitn(3, 'X');\n    //~^ manual_pattern_char_comparison\n    sentence.splitn(3, |c: char| c.is_whitespace() || c == 'X');\n    let char_compare = 'X';\n    sentence.splitn(3, char_compare);\n    //~^ manual_pattern_char_comparison\n    sentence.split(['\\n', 'X', 'Y']);\n    //~^ manual_pattern_char_comparison\n    sentence.splitn(3, 'X');\n    //~^ manual_pattern_char_comparison\n    sentence.splitn(3, ['X', 'W']);\n    //~^ manual_pattern_char_comparison\n    sentence.find('🎈');\n    //~^ manual_pattern_char_comparison\n\n    let not_str = NotStr;\n    not_str.find(|c: char| c == 'X');\n\n    \"\".find(|c| c == 'a' || c > 'z');\n\n    let x = true;\n    \"\".find(|c| c == 'a' || x || c == 'b');\n\n    let d = 'd';\n    \"\".find(|c| c == 'a' || d == 'b');\n\n    \"\".find(|c| match c {\n        'a' | 'b' => true,\n        _ => c.is_ascii(),\n    });\n\n    \"\".find(|c| matches!(c, 'a' | 'b' if false));\n\n    \"\".find(|c| matches!(c, 'a' | '1'..'4'));\n    \"\".find(|c| c == 'a' || matches!(c, '1'..'4'));\n    macro_rules! m {\n        ($e:expr) => {\n            $e == '?'\n        };\n    }\n    \"\".find(|c| m!(c));\n}\n\n#[clippy::msrv = \"1.57\"]\nfn msrv_1_57() {\n    let sentence = \"Hello, world!\";\n    sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?');\n}\n\n#[clippy::msrv = \"1.58\"]\nfn msrv_1_58() {\n    let sentence = \"Hello, world!\";\n    sentence.trim_end_matches(['.', ',', '!', '?']);\n    //~^ manual_pattern_char_comparison\n}\n"
  },
  {
    "path": "tests/ui/manual_pattern_char_comparison.rs",
    "content": "#![warn(clippy::manual_pattern_char_comparison)]\n\nstruct NotStr;\n\nimpl NotStr {\n    fn find(&self, _: impl FnMut(char) -> bool) {}\n}\n\nfn main() {\n    let sentence = \"Hello, world!\";\n    sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?');\n    //~^ manual_pattern_char_comparison\n    sentence.split(|c: char| c == '\\n' || c == 'X');\n    //~^ manual_pattern_char_comparison\n    sentence.split(|c| c == '\\n' || c == 'X');\n    //~^ manual_pattern_char_comparison\n    sentence.splitn(3, |c: char| c == 'X');\n    //~^ manual_pattern_char_comparison\n    sentence.splitn(3, |c: char| c.is_whitespace() || c == 'X');\n    let char_compare = 'X';\n    sentence.splitn(3, |c: char| c == char_compare);\n    //~^ manual_pattern_char_comparison\n    sentence.split(|c: char| matches!(c, '\\n' | 'X' | 'Y'));\n    //~^ manual_pattern_char_comparison\n    sentence.splitn(3, |c: char| matches!(c, 'X'));\n    //~^ manual_pattern_char_comparison\n    sentence.splitn(3, |c: char| matches!(c, 'X' | 'W'));\n    //~^ manual_pattern_char_comparison\n    sentence.find(|c| c == '🎈');\n    //~^ manual_pattern_char_comparison\n\n    let not_str = NotStr;\n    not_str.find(|c: char| c == 'X');\n\n    \"\".find(|c| c == 'a' || c > 'z');\n\n    let x = true;\n    \"\".find(|c| c == 'a' || x || c == 'b');\n\n    let d = 'd';\n    \"\".find(|c| c == 'a' || d == 'b');\n\n    \"\".find(|c| match c {\n        'a' | 'b' => true,\n        _ => c.is_ascii(),\n    });\n\n    \"\".find(|c| matches!(c, 'a' | 'b' if false));\n\n    \"\".find(|c| matches!(c, 'a' | '1'..'4'));\n    \"\".find(|c| c == 'a' || matches!(c, '1'..'4'));\n    macro_rules! m {\n        ($e:expr) => {\n            $e == '?'\n        };\n    }\n    \"\".find(|c| m!(c));\n}\n\n#[clippy::msrv = \"1.57\"]\nfn msrv_1_57() {\n    let sentence = \"Hello, world!\";\n    sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?');\n}\n\n#[clippy::msrv = \"1.58\"]\nfn msrv_1_58() {\n    let sentence = \"Hello, world!\";\n    sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?');\n    //~^ manual_pattern_char_comparison\n}\n"
  },
  {
    "path": "tests/ui/manual_pattern_char_comparison.stderr",
    "content": "error: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:11:31\n   |\nLL |     sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?');\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['.', ',', '!', '?']`\n   |\n   = note: `-D clippy::manual-pattern-char-comparison` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_pattern_char_comparison)]`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:13:20\n   |\nLL |     sentence.split(|c: char| c == '\\n' || c == 'X');\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\\n', 'X']`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:15:20\n   |\nLL |     sentence.split(|c| c == '\\n' || c == 'X');\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\\n', 'X']`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:17:24\n   |\nLL |     sentence.splitn(3, |c: char| c == 'X');\n   |                        ^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `'X'`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:21:24\n   |\nLL |     sentence.splitn(3, |c: char| c == char_compare);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `char_compare`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:23:20\n   |\nLL |     sentence.split(|c: char| matches!(c, '\\n' | 'X' | 'Y'));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\\n', 'X', 'Y']`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:25:24\n   |\nLL |     sentence.splitn(3, |c: char| matches!(c, 'X'));\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `'X'`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:27:24\n   |\nLL |     sentence.splitn(3, |c: char| matches!(c, 'X' | 'W'));\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['X', 'W']`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:29:19\n   |\nLL |     sentence.find(|c| c == '🎈');\n   |                   ^^^^^^^^^^^^^ help: consider using a `char`: `'🎈'`\n\nerror: this manual char comparison can be written more succinctly\n  --> tests/ui/manual_pattern_char_comparison.rs:69:31\n   |\nLL |     sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?');\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['.', ',', '!', '?']`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_pop_if.fixed",
    "content": "#![warn(clippy::manual_pop_if)]\n#![allow(clippy::collapsible_if, clippy::redundant_closure)]\n\nuse std::collections::VecDeque;\nuse std::marker::PhantomData;\n\n// FakeVec has the same methods as Vec but isn't actually a Vec\nstruct FakeVec<T>(PhantomData<T>);\n\nimpl<T> FakeVec<T> {\n    fn last(&self) -> Option<&T> {\n        None\n    }\n\n    fn pop(&mut self) -> Option<T> {\n        None\n    }\n}\n\nfn is_some_and_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    vec.pop_if(|x| *x > 2);\n\n    vec.pop_if(|x| *x > 2);\n\n    deque.pop_back_if(|x| *x > 2);\n\n    deque.pop_front_if(|x| *x > 2);\n}\n\nfn is_some_and_pattern_negative(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    // Do not lint, different vectors\n    let mut vec2 = vec![0];\n    if vec.last().is_some_and(|x| *x > 2) {\n        vec2.pop().unwrap();\n    }\n\n    // Do not lint, non-Vec type\n    let mut fake_vec: FakeVec<i32> = FakeVec(PhantomData);\n    if fake_vec.last().is_some_and(|x| *x > 2) {\n        fake_vec.pop().unwrap();\n    }\n\n    // Do not lint, else-if branch\n    if false {\n        // something\n    } else if vec.last().is_some_and(|x| *x > 2) {\n        vec.pop().unwrap();\n    }\n\n    // Do not lint, value used in let binding\n    if vec.last().is_some_and(|x| *x > 2) {\n        let _value = vec.pop().unwrap();\n        println!(\"Popped: {}\", _value);\n    }\n\n    // Do not lint, value used in expression\n    if vec.last().is_some_and(|x| *x > 2) {\n        println!(\"Popped: {}\", vec.pop().unwrap());\n    }\n\n    // Do not lint, else block\n    let _result = if vec.last().is_some_and(|x| *x > 2) {\n        vec.pop().unwrap()\n    } else {\n        0\n    };\n}\n\nfn if_let_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    vec.pop_if(|x| *x > 2);\n\n    vec.pop_if(|x| *x > 2);\n\n    deque.pop_back_if(|x| *x > 2);\n\n    deque.pop_front_if(|x| *x > 2);\n}\n\nfn if_let_pattern_negative(mut vec: Vec<i32>) {\n    // Do not lint, different vectors\n    let mut vec2 = vec![0];\n    if let Some(x) = vec.last() {\n        if *x > 2 {\n            vec2.pop().unwrap();\n        }\n    }\n\n    // Do not lint, intervening statements\n    if let Some(x) = vec.last() {\n        println!(\"Checking {}\", x);\n        if *x > 2 {\n            vec.pop().unwrap();\n        }\n    }\n\n    // Do not lint, bound variable not used in condition\n    if let Some(_x) = vec.last() {\n        if vec.len() > 2 {\n            vec.pop().unwrap();\n        }\n    }\n\n    // Do not lint, value used in let binding\n    if let Some(x) = vec.last() {\n        if *x > 2 {\n            let _val = vec.pop().unwrap();\n        }\n    }\n\n    // Do not lint, else block\n    let _result = if let Some(x) = vec.last() {\n        if *x > 2 { vec.pop().unwrap() } else { 0 }\n    } else {\n        0\n    };\n}\n\nfn let_chain_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    vec.pop_if(|x| *x > 2);\n\n    vec.pop_if(|x| *x > 2);\n\n    deque.pop_back_if(|x| *x > 2);\n\n    deque.pop_front_if(|x| *x > 2);\n}\n\nfn let_chain_pattern_negative(mut vec: Vec<i32>) {\n    // Do not lint, different vectors\n    let mut vec2 = vec![0];\n    if let Some(x) = vec.last()\n        && *x > 2\n    {\n        vec2.pop().unwrap();\n    }\n\n    // Do not lint, bound variable not used in condition\n    if let Some(_x) = vec.last()\n        && vec.len() > 2\n    {\n        vec.pop().unwrap();\n    }\n\n    // Do not lint, value used in let binding\n    if let Some(x) = vec.last()\n        && *x > 2\n    {\n        let _val = vec.pop().unwrap();\n    }\n\n    // Do not lint, value used in expression\n    if let Some(x) = vec.last()\n        && *x > 2\n    {\n        println!(\"Popped: {}\", vec.pop().unwrap());\n    }\n\n    // Do not lint, else block\n    let _result = if let Some(x) = vec.last()\n        && *x > 2\n    {\n        vec.pop().unwrap()\n    } else {\n        0\n    };\n}\n\nfn map_unwrap_or_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    vec.pop_if(|x| *x > 2);\n\n    vec.pop_if(|x| *x > 2);\n\n    deque.pop_back_if(|x| *x > 2);\n\n    deque.pop_front_if(|x| *x > 2);\n}\n\nfn map_unwrap_or_pattern_negative(mut vec: Vec<i32>) {\n    // Do not lint, unwrap_or(true) instead of false\n    if vec.last().map(|x| *x > 2).unwrap_or(true) {\n        vec.pop().unwrap();\n    }\n\n    // Do not lint, different vectors\n    let mut vec2 = vec![0];\n    if vec.last().map(|x| *x > 2).unwrap_or(false) {\n        vec2.pop().unwrap();\n    }\n\n    // Do not lint, non-Vec type\n    let mut fake_vec: FakeVec<i32> = FakeVec(PhantomData);\n    if fake_vec.last().map(|x| *x > 2).unwrap_or(false) {\n        fake_vec.pop().unwrap();\n    }\n\n    // Do not lint, map returns non-boolean\n    if vec.last().map(|x| x + 1).unwrap_or(0) > 2 {\n        vec.pop().unwrap();\n    }\n\n    // Do not lint, value used in let binding\n    if vec.last().map(|x| *x > 2).unwrap_or(false) {\n        let _val = vec.pop().unwrap();\n    }\n\n    // Do not lint, else block\n    let _result = if vec.last().map(|x| *x > 2).unwrap_or(false) {\n        vec.pop().unwrap()\n    } else {\n        0\n    };\n}\n\n// this makes sure we do not expand vec![] in the suggestion\nfn handle_macro_in_closure(mut vec: Vec<Vec<i32>>) {\n    vec.pop_if(|e| *e == vec![1]);\n}\n\n#[clippy::msrv = \"1.85.0\"]\nfn msrv_too_low_vec(mut vec: Vec<i32>) {\n    if vec.last().is_some_and(|x| *x > 2) {\n        vec.pop().unwrap();\n    }\n}\n\n#[clippy::msrv = \"1.92.0\"]\nfn msrv_too_low_vecdeque(mut deque: VecDeque<i32>) {\n    if deque.back().is_some_and(|x| *x > 2) {\n        deque.pop_back().unwrap();\n    }\n\n    if deque.front().is_some_and(|x| *x > 2) {\n        deque.pop_front().unwrap();\n    }\n}\n\n#[clippy::msrv = \"1.86.0\"]\nfn msrv_high_enough_vec(mut vec: Vec<i32>) {\n    vec.pop_if(|x| *x > 2);\n}\n\n#[clippy::msrv = \"1.93.0\"]\nfn msrv_high_enough_vecdeque(mut deque: VecDeque<i32>) {\n    deque.pop_back_if(|x| *x > 2);\n\n    deque.pop_front_if(|x| *x > 2);\n}\n"
  },
  {
    "path": "tests/ui/manual_pop_if.rs",
    "content": "#![warn(clippy::manual_pop_if)]\n#![allow(clippy::collapsible_if, clippy::redundant_closure)]\n\nuse std::collections::VecDeque;\nuse std::marker::PhantomData;\n\n// FakeVec has the same methods as Vec but isn't actually a Vec\nstruct FakeVec<T>(PhantomData<T>);\n\nimpl<T> FakeVec<T> {\n    fn last(&self) -> Option<&T> {\n        None\n    }\n\n    fn pop(&mut self) -> Option<T> {\n        None\n    }\n}\n\nfn is_some_and_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    if vec.last().is_some_and(|x| *x > 2) {\n        //~^ manual_pop_if\n        vec.pop().unwrap();\n    }\n\n    if vec.last().is_some_and(|x| *x > 2) {\n        //~^ manual_pop_if\n        vec.pop().expect(\"element\");\n    }\n\n    if deque.back().is_some_and(|x| *x > 2) {\n        //~^ manual_pop_if\n        deque.pop_back().unwrap();\n    }\n\n    if deque.front().is_some_and(|x| *x > 2) {\n        //~^ manual_pop_if\n        deque.pop_front().unwrap();\n    }\n}\n\nfn is_some_and_pattern_negative(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    // Do not lint, different vectors\n    let mut vec2 = vec![0];\n    if vec.last().is_some_and(|x| *x > 2) {\n        vec2.pop().unwrap();\n    }\n\n    // Do not lint, non-Vec type\n    let mut fake_vec: FakeVec<i32> = FakeVec(PhantomData);\n    if fake_vec.last().is_some_and(|x| *x > 2) {\n        fake_vec.pop().unwrap();\n    }\n\n    // Do not lint, else-if branch\n    if false {\n        // something\n    } else if vec.last().is_some_and(|x| *x > 2) {\n        vec.pop().unwrap();\n    }\n\n    // Do not lint, value used in let binding\n    if vec.last().is_some_and(|x| *x > 2) {\n        let _value = vec.pop().unwrap();\n        println!(\"Popped: {}\", _value);\n    }\n\n    // Do not lint, value used in expression\n    if vec.last().is_some_and(|x| *x > 2) {\n        println!(\"Popped: {}\", vec.pop().unwrap());\n    }\n\n    // Do not lint, else block\n    let _result = if vec.last().is_some_and(|x| *x > 2) {\n        vec.pop().unwrap()\n    } else {\n        0\n    };\n}\n\nfn if_let_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    if let Some(x) = vec.last() {\n        //~^ manual_pop_if\n        if *x > 2 {\n            vec.pop().unwrap();\n        }\n    }\n\n    if let Some(x) = vec.last() {\n        //~^ manual_pop_if\n        if *x > 2 {\n            vec.pop().expect(\"element\");\n        }\n    }\n\n    if let Some(x) = deque.back() {\n        //~^ manual_pop_if\n        if *x > 2 {\n            deque.pop_back().unwrap();\n        }\n    }\n\n    if let Some(x) = deque.front() {\n        //~^ manual_pop_if\n        if *x > 2 {\n            deque.pop_front().unwrap();\n        }\n    }\n}\n\nfn if_let_pattern_negative(mut vec: Vec<i32>) {\n    // Do not lint, different vectors\n    let mut vec2 = vec![0];\n    if let Some(x) = vec.last() {\n        if *x > 2 {\n            vec2.pop().unwrap();\n        }\n    }\n\n    // Do not lint, intervening statements\n    if let Some(x) = vec.last() {\n        println!(\"Checking {}\", x);\n        if *x > 2 {\n            vec.pop().unwrap();\n        }\n    }\n\n    // Do not lint, bound variable not used in condition\n    if let Some(_x) = vec.last() {\n        if vec.len() > 2 {\n            vec.pop().unwrap();\n        }\n    }\n\n    // Do not lint, value used in let binding\n    if let Some(x) = vec.last() {\n        if *x > 2 {\n            let _val = vec.pop().unwrap();\n        }\n    }\n\n    // Do not lint, else block\n    let _result = if let Some(x) = vec.last() {\n        if *x > 2 { vec.pop().unwrap() } else { 0 }\n    } else {\n        0\n    };\n}\n\nfn let_chain_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    if let Some(x) = vec.last() //~ manual_pop_if\n        && *x > 2\n    {\n        vec.pop().unwrap();\n    }\n\n    if let Some(x) = vec.last() //~ manual_pop_if\n        && *x > 2\n    {\n        vec.pop().expect(\"element\");\n    }\n\n    if let Some(x) = deque.back() //~ manual_pop_if\n        && *x > 2\n    {\n        deque.pop_back().unwrap();\n    }\n\n    if let Some(x) = deque.front() //~ manual_pop_if\n        && *x > 2\n    {\n        deque.pop_front().unwrap();\n    }\n}\n\nfn let_chain_pattern_negative(mut vec: Vec<i32>) {\n    // Do not lint, different vectors\n    let mut vec2 = vec![0];\n    if let Some(x) = vec.last()\n        && *x > 2\n    {\n        vec2.pop().unwrap();\n    }\n\n    // Do not lint, bound variable not used in condition\n    if let Some(_x) = vec.last()\n        && vec.len() > 2\n    {\n        vec.pop().unwrap();\n    }\n\n    // Do not lint, value used in let binding\n    if let Some(x) = vec.last()\n        && *x > 2\n    {\n        let _val = vec.pop().unwrap();\n    }\n\n    // Do not lint, value used in expression\n    if let Some(x) = vec.last()\n        && *x > 2\n    {\n        println!(\"Popped: {}\", vec.pop().unwrap());\n    }\n\n    // Do not lint, else block\n    let _result = if let Some(x) = vec.last()\n        && *x > 2\n    {\n        vec.pop().unwrap()\n    } else {\n        0\n    };\n}\n\nfn map_unwrap_or_pattern_positive(mut vec: Vec<i32>, mut deque: VecDeque<i32>) {\n    if vec.last().map(|x| *x > 2).unwrap_or(false) {\n        //~^ manual_pop_if\n        vec.pop().unwrap();\n    }\n\n    if vec.last().map(|x| *x > 2).unwrap_or(false) {\n        //~^ manual_pop_if\n        vec.pop().expect(\"element\");\n    }\n\n    if deque.back().map(|x| *x > 2).unwrap_or(false) {\n        //~^ manual_pop_if\n        deque.pop_back().unwrap();\n    }\n\n    if deque.front().map(|x| *x > 2).unwrap_or(false) {\n        //~^ manual_pop_if\n        deque.pop_front().unwrap();\n    }\n}\n\nfn map_unwrap_or_pattern_negative(mut vec: Vec<i32>) {\n    // Do not lint, unwrap_or(true) instead of false\n    if vec.last().map(|x| *x > 2).unwrap_or(true) {\n        vec.pop().unwrap();\n    }\n\n    // Do not lint, different vectors\n    let mut vec2 = vec![0];\n    if vec.last().map(|x| *x > 2).unwrap_or(false) {\n        vec2.pop().unwrap();\n    }\n\n    // Do not lint, non-Vec type\n    let mut fake_vec: FakeVec<i32> = FakeVec(PhantomData);\n    if fake_vec.last().map(|x| *x > 2).unwrap_or(false) {\n        fake_vec.pop().unwrap();\n    }\n\n    // Do not lint, map returns non-boolean\n    if vec.last().map(|x| x + 1).unwrap_or(0) > 2 {\n        vec.pop().unwrap();\n    }\n\n    // Do not lint, value used in let binding\n    if vec.last().map(|x| *x > 2).unwrap_or(false) {\n        let _val = vec.pop().unwrap();\n    }\n\n    // Do not lint, else block\n    let _result = if vec.last().map(|x| *x > 2).unwrap_or(false) {\n        vec.pop().unwrap()\n    } else {\n        0\n    };\n}\n\n// this makes sure we do not expand vec![] in the suggestion\nfn handle_macro_in_closure(mut vec: Vec<Vec<i32>>) {\n    if vec.last().is_some_and(|e| *e == vec![1]) {\n        //~^ manual_pop_if\n        vec.pop().unwrap();\n    }\n}\n\n#[clippy::msrv = \"1.85.0\"]\nfn msrv_too_low_vec(mut vec: Vec<i32>) {\n    if vec.last().is_some_and(|x| *x > 2) {\n        vec.pop().unwrap();\n    }\n}\n\n#[clippy::msrv = \"1.92.0\"]\nfn msrv_too_low_vecdeque(mut deque: VecDeque<i32>) {\n    if deque.back().is_some_and(|x| *x > 2) {\n        deque.pop_back().unwrap();\n    }\n\n    if deque.front().is_some_and(|x| *x > 2) {\n        deque.pop_front().unwrap();\n    }\n}\n\n#[clippy::msrv = \"1.86.0\"]\nfn msrv_high_enough_vec(mut vec: Vec<i32>) {\n    if vec.last().is_some_and(|x| *x > 2) {\n        //~^ manual_pop_if\n        vec.pop().unwrap();\n    }\n}\n\n#[clippy::msrv = \"1.93.0\"]\nfn msrv_high_enough_vecdeque(mut deque: VecDeque<i32>) {\n    if deque.back().is_some_and(|x| *x > 2) {\n        //~^ manual_pop_if\n        deque.pop_back().unwrap();\n    }\n\n    if deque.front().is_some_and(|x| *x > 2) {\n        //~^ manual_pop_if\n        deque.pop_front().unwrap();\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_pop_if.stderr",
    "content": "error: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:21:5\n   |\nLL | /     if vec.last().is_some_and(|x| *x > 2) {\nLL | |\nLL | |         vec.pop().unwrap();\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n   |\n   = note: `-D clippy::manual-pop-if` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_pop_if)]`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:26:5\n   |\nLL | /     if vec.last().is_some_and(|x| *x > 2) {\nLL | |\nLL | |         vec.pop().expect(\"element\");\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_back_if`\n  --> tests/ui/manual_pop_if.rs:31:5\n   |\nLL | /     if deque.back().is_some_and(|x| *x > 2) {\nLL | |\nLL | |         deque.pop_back().unwrap();\nLL | |     }\n   | |_____^ help: try: `deque.pop_back_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_front_if`\n  --> tests/ui/manual_pop_if.rs:36:5\n   |\nLL | /     if deque.front().is_some_and(|x| *x > 2) {\nLL | |\nLL | |         deque.pop_front().unwrap();\nLL | |     }\n   | |_____^ help: try: `deque.pop_front_if(|x| *x > 2);`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:82:5\n   |\nLL | /     if let Some(x) = vec.last() {\nLL | |\nLL | |         if *x > 2 {\nLL | |             vec.pop().unwrap();\nLL | |         }\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:89:5\n   |\nLL | /     if let Some(x) = vec.last() {\nLL | |\nLL | |         if *x > 2 {\nLL | |             vec.pop().expect(\"element\");\nLL | |         }\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_back_if`\n  --> tests/ui/manual_pop_if.rs:96:5\n   |\nLL | /     if let Some(x) = deque.back() {\nLL | |\nLL | |         if *x > 2 {\nLL | |             deque.pop_back().unwrap();\nLL | |         }\nLL | |     }\n   | |_____^ help: try: `deque.pop_back_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_front_if`\n  --> tests/ui/manual_pop_if.rs:103:5\n   |\nLL | /     if let Some(x) = deque.front() {\nLL | |\nLL | |         if *x > 2 {\nLL | |             deque.pop_front().unwrap();\nLL | |         }\nLL | |     }\n   | |_____^ help: try: `deque.pop_front_if(|x| *x > 2);`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:151:5\n   |\nLL | /     if let Some(x) = vec.last()\nLL | |         && *x > 2\nLL | |     {\nLL | |         vec.pop().unwrap();\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:157:5\n   |\nLL | /     if let Some(x) = vec.last()\nLL | |         && *x > 2\nLL | |     {\nLL | |         vec.pop().expect(\"element\");\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_back_if`\n  --> tests/ui/manual_pop_if.rs:163:5\n   |\nLL | /     if let Some(x) = deque.back()\nLL | |         && *x > 2\nLL | |     {\nLL | |         deque.pop_back().unwrap();\nLL | |     }\n   | |_____^ help: try: `deque.pop_back_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_front_if`\n  --> tests/ui/manual_pop_if.rs:169:5\n   |\nLL | /     if let Some(x) = deque.front()\nLL | |         && *x > 2\nLL | |     {\nLL | |         deque.pop_front().unwrap();\nLL | |     }\n   | |_____^ help: try: `deque.pop_front_if(|x| *x > 2);`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:217:5\n   |\nLL | /     if vec.last().map(|x| *x > 2).unwrap_or(false) {\nLL | |\nLL | |         vec.pop().unwrap();\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:222:5\n   |\nLL | /     if vec.last().map(|x| *x > 2).unwrap_or(false) {\nLL | |\nLL | |         vec.pop().expect(\"element\");\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_back_if`\n  --> tests/ui/manual_pop_if.rs:227:5\n   |\nLL | /     if deque.back().map(|x| *x > 2).unwrap_or(false) {\nLL | |\nLL | |         deque.pop_back().unwrap();\nLL | |     }\n   | |_____^ help: try: `deque.pop_back_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_front_if`\n  --> tests/ui/manual_pop_if.rs:232:5\n   |\nLL | /     if deque.front().map(|x| *x > 2).unwrap_or(false) {\nLL | |\nLL | |         deque.pop_front().unwrap();\nLL | |     }\n   | |_____^ help: try: `deque.pop_front_if(|x| *x > 2);`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:276:5\n   |\nLL | /     if vec.last().is_some_and(|e| *e == vec![1]) {\nLL | |\nLL | |         vec.pop().unwrap();\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|e| *e == vec![1]);`\n\nerror: manual implementation of `Vec::pop_if`\n  --> tests/ui/manual_pop_if.rs:302:5\n   |\nLL | /     if vec.last().is_some_and(|x| *x > 2) {\nLL | |\nLL | |         vec.pop().unwrap();\nLL | |     }\n   | |_____^ help: try: `vec.pop_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_back_if`\n  --> tests/ui/manual_pop_if.rs:310:5\n   |\nLL | /     if deque.back().is_some_and(|x| *x > 2) {\nLL | |\nLL | |         deque.pop_back().unwrap();\nLL | |     }\n   | |_____^ help: try: `deque.pop_back_if(|x| *x > 2);`\n\nerror: manual implementation of `VecDeque::pop_front_if`\n  --> tests/ui/manual_pop_if.rs:315:5\n   |\nLL | /     if deque.front().is_some_and(|x| *x > 2) {\nLL | |\nLL | |         deque.pop_front().unwrap();\nLL | |     }\n   | |_____^ help: try: `deque.pop_front_if(|x| *x > 2);`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_range_patterns.fixed",
    "content": "#![allow(unused)]\n#![allow(non_contiguous_range_endpoints)]\n#![warn(clippy::manual_range_patterns)]\n\nfn main() {\n    let f = 6;\n\n    let _ = matches!(f, 1..=10);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 1..=10);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 8 | 10); // 7 is missing\n    let _ = matches!(f, | 4);\n    let _ = matches!(f, 4 | 5);\n    let _ = matches!(f, 1 | 2147483647);\n    let _ = matches!(f, 0 | 2147483647);\n    let _ = matches!(f, -2147483647 | 2147483647);\n    let _ = matches!(f, 1..=4);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 1..4);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 1..=48324729);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 0..=48324730);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 0..=3);\n    //~^ manual_range_patterns\n    #[allow(clippy::match_like_matches_macro)]\n    let _ = match f {\n        1..=10 => true,\n        //~^ manual_range_patterns\n        _ => false,\n    };\n    let _ = matches!(f, -5..=3);\n    //~^ manual_range_patterns\n    let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing\n    let _ = matches!(f, -1_000_001..=1_000_001);\n    //~^ manual_range_patterns\n    let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002);\n\n    matches!(f, 0x00..=0x03);\n    //~^ manual_range_patterns\n    matches!(f, 0x00..=0x07);\n    //~^ manual_range_patterns\n    matches!(f, -0x09..=0x00);\n    //~^ manual_range_patterns\n\n    matches!(f, 0..=5);\n    //~^ manual_range_patterns\n    matches!(f, 0..5);\n    //~^ manual_range_patterns\n\n    matches!(f, 0..10);\n    //~^ manual_range_patterns\n    matches!(f, 0..=10);\n    //~^ manual_range_patterns\n    matches!(f, 0..=10);\n    //~^ manual_range_patterns\n\n    macro_rules! mac {\n        ($e:expr) => {\n            matches!($e, 1..=10)\n            //~^ manual_range_patterns\n        };\n    }\n    mac!(f);\n\n    #[rustfmt::skip]\n    let _ = match f {\n        | 2..=15 => 4,\n        | 241..=254 => 5,\n        | 255 => 6,\n        | _ => 7,\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_range_patterns.rs",
    "content": "#![allow(unused)]\n#![allow(non_contiguous_range_endpoints)]\n#![warn(clippy::manual_range_patterns)]\n\nfn main() {\n    let f = 6;\n\n    let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 7 | 8 | 10);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 8 | 10); // 7 is missing\n    let _ = matches!(f, | 4);\n    let _ = matches!(f, 4 | 5);\n    let _ = matches!(f, 1 | 2147483647);\n    let _ = matches!(f, 0 | 2147483647);\n    let _ = matches!(f, -2147483647 | 2147483647);\n    let _ = matches!(f, 1 | (2..=4));\n    //~^ manual_range_patterns\n    let _ = matches!(f, 1 | (2..4));\n    //~^ manual_range_patterns\n    let _ = matches!(f, (1..=10) | (2..=13) | (14..=48324728) | 48324729);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 0 | (1..=10) | 48324730 | (2..=13) | (14..=48324728) | 48324729);\n    //~^ manual_range_patterns\n    let _ = matches!(f, 0..=1 | 0..=2 | 0..=3);\n    //~^ manual_range_patterns\n    #[allow(clippy::match_like_matches_macro)]\n    let _ = match f {\n        1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true,\n        //~^ manual_range_patterns\n        _ => false,\n    };\n    let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2);\n    //~^ manual_range_patterns\n    let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing\n    let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001);\n    //~^ manual_range_patterns\n    let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002);\n\n    matches!(f, 0x00 | 0x01 | 0x02 | 0x03);\n    //~^ manual_range_patterns\n    matches!(f, 0x00..=0x05 | 0x06 | 0x07);\n    //~^ manual_range_patterns\n    matches!(f, -0x09 | -0x08 | -0x07..=0x00);\n    //~^ manual_range_patterns\n\n    matches!(f, 0..5 | 5);\n    //~^ manual_range_patterns\n    matches!(f, 0 | 1..5);\n    //~^ manual_range_patterns\n\n    matches!(f, 0..=5 | 6..10);\n    //~^ manual_range_patterns\n    matches!(f, 0..5 | 5..=10);\n    //~^ manual_range_patterns\n    matches!(f, 5..=10 | 0..5);\n    //~^ manual_range_patterns\n\n    macro_rules! mac {\n        ($e:expr) => {\n            matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10)\n            //~^ manual_range_patterns\n        };\n    }\n    mac!(f);\n\n    #[rustfmt::skip]\n    let _ = match f {\n        | 2..=15 => 4,\n        | 241..=254 => 5,\n        | 255 => 6,\n        | _ => 7,\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_range_patterns.stderr",
    "content": "error: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:8:25\n   |\nLL |     let _ = matches!(f, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`\n   |\n   = note: `-D clippy::manual-range-patterns` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_range_patterns)]`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:10:25\n   |\nLL |     let _ = matches!(f, 4 | 2 | 3 | 1 | 5 | 6 | 9 | 7 | 8 | 10);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:18:25\n   |\nLL |     let _ = matches!(f, 1 | (2..=4));\n   |                         ^^^^^^^^^^^ help: try: `1..=4`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:20:25\n   |\nLL |     let _ = matches!(f, 1 | (2..4));\n   |                         ^^^^^^^^^^ help: try: `1..4`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:22:25\n   |\nLL |     let _ = matches!(f, (1..=10) | (2..=13) | (14..=48324728) | 48324729);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=48324729`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:24:25\n   |\nLL |     let _ = matches!(f, 0 | (1..=10) | 48324730 | (2..=13) | (14..=48324728) | 48324729);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=48324730`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:26:25\n   |\nLL |     let _ = matches!(f, 0..=1 | 0..=2 | 0..=3);\n   |                         ^^^^^^^^^^^^^^^^^^^^^ help: try: `0..=3`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:30:9\n   |\nLL |         1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true,\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:34:25\n   |\nLL |     let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-5..=3`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:37:25\n   |\nLL |     let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-1_000_001..=1_000_001`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:41:17\n   |\nLL |     matches!(f, 0x00 | 0x01 | 0x02 | 0x03);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0x00..=0x03`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:43:17\n   |\nLL |     matches!(f, 0x00..=0x05 | 0x06 | 0x07);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `0x00..=0x07`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:45:17\n   |\nLL |     matches!(f, -0x09 | -0x08 | -0x07..=0x00);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-0x09..=0x00`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:48:17\n   |\nLL |     matches!(f, 0..5 | 5);\n   |                 ^^^^^^^^ help: try: `0..=5`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:50:17\n   |\nLL |     matches!(f, 0 | 1..5);\n   |                 ^^^^^^^^ help: try: `0..5`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:53:17\n   |\nLL |     matches!(f, 0..=5 | 6..10);\n   |                 ^^^^^^^^^^^^^ help: try: `0..10`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:55:17\n   |\nLL |     matches!(f, 0..5 | 5..=10);\n   |                 ^^^^^^^^^^^^^ help: try: `0..=10`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:57:17\n   |\nLL |     matches!(f, 5..=10 | 0..5);\n   |                 ^^^^^^^^^^^^^ help: try: `0..=10`\n\nerror: this OR pattern can be rewritten using a range\n  --> tests/ui/manual_range_patterns.rs:62:26\n   |\nLL |             matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10)\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`\n...\nLL |     mac!(f);\n   |     ------- in this macro invocation\n   |\n   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_rem_euclid.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::manual_rem_euclid)]\n#![allow(clippy::let_with_type_underscore)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n#[inline_macros]\nfn main() {\n    let value: i32 = 5;\n\n    let _: i32 = value.rem_euclid(4);\n    //~^ manual_rem_euclid\n    let _: i32 = value.rem_euclid(4);\n    //~^ manual_rem_euclid\n    let _: i32 = value.rem_euclid(4);\n    //~^ manual_rem_euclid\n    let _: i32 = value.rem_euclid(4);\n    //~^ manual_rem_euclid\n    let _: i32 = 1 + value.rem_euclid(4);\n    //~^ manual_rem_euclid\n\n    let _: i32 = (3 + value % 4) % 4;\n    let _: i32 = (-4 + value % -4) % -4;\n    let _: i32 = ((5 % 4) + 4) % 4;\n\n    // Make sure the lint does not trigger if it would cause an error, like with an ambiguous\n    // integer type\n    let not_annotated = 24;\n    let _ = ((not_annotated % 4) + 4) % 4;\n    let inferred: _ = 24;\n    let _ = ((inferred % 4) + 4) % 4;\n\n    // For lint to apply the constant must always be on the RHS of the previous value for %\n    let _: i32 = 4 % ((value % 4) + 4);\n    let _: i32 = ((4 % value) + 4) % 4;\n\n    // Lint in internal macros\n    inline!(\n        let value: i32 = 5;\n        let _: i32 = value.rem_euclid(4);\n        //~^ manual_rem_euclid\n    );\n\n    // Do not lint in external macros\n    external!(\n        let value: i32 = 5;\n        let _: i32 = ((value % 4) + 4) % 4;\n    );\n}\n\n// Should lint for params too\npub fn rem_euclid_4(num: i32) -> i32 {\n    num.rem_euclid(4)\n    //~^ manual_rem_euclid\n}\n\n// Constant version came later, should still lint\npub const fn const_rem_euclid_4(num: i32) -> i32 {\n    num.rem_euclid(4)\n    //~^ manual_rem_euclid\n}\n\n#[clippy::msrv = \"1.37\"]\npub fn msrv_1_37() {\n    let x: i32 = 10;\n    let _: i32 = ((x % 4) + 4) % 4;\n}\n\n#[clippy::msrv = \"1.38\"]\npub fn msrv_1_38() {\n    let x: i32 = 10;\n    let _: i32 = x.rem_euclid(4);\n    //~^ manual_rem_euclid\n}\n\n// For const fns:\n#[clippy::msrv = \"1.51\"]\npub const fn msrv_1_51() {\n    let x: i32 = 10;\n    let _: i32 = ((x % 4) + 4) % 4;\n}\n\n#[clippy::msrv = \"1.52\"]\npub const fn msrv_1_52() {\n    let x: i32 = 10;\n    let _: i32 = x.rem_euclid(4);\n    //~^ manual_rem_euclid\n}\n"
  },
  {
    "path": "tests/ui/manual_rem_euclid.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::manual_rem_euclid)]\n#![allow(clippy::let_with_type_underscore)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n#[inline_macros]\nfn main() {\n    let value: i32 = 5;\n\n    let _: i32 = ((value % 4) + 4) % 4;\n    //~^ manual_rem_euclid\n    let _: i32 = (4 + (value % 4)) % 4;\n    //~^ manual_rem_euclid\n    let _: i32 = (value % 4 + 4) % 4;\n    //~^ manual_rem_euclid\n    let _: i32 = (4 + value % 4) % 4;\n    //~^ manual_rem_euclid\n    let _: i32 = 1 + (4 + value % 4) % 4;\n    //~^ manual_rem_euclid\n\n    let _: i32 = (3 + value % 4) % 4;\n    let _: i32 = (-4 + value % -4) % -4;\n    let _: i32 = ((5 % 4) + 4) % 4;\n\n    // Make sure the lint does not trigger if it would cause an error, like with an ambiguous\n    // integer type\n    let not_annotated = 24;\n    let _ = ((not_annotated % 4) + 4) % 4;\n    let inferred: _ = 24;\n    let _ = ((inferred % 4) + 4) % 4;\n\n    // For lint to apply the constant must always be on the RHS of the previous value for %\n    let _: i32 = 4 % ((value % 4) + 4);\n    let _: i32 = ((4 % value) + 4) % 4;\n\n    // Lint in internal macros\n    inline!(\n        let value: i32 = 5;\n        let _: i32 = ((value % 4) + 4) % 4;\n        //~^ manual_rem_euclid\n    );\n\n    // Do not lint in external macros\n    external!(\n        let value: i32 = 5;\n        let _: i32 = ((value % 4) + 4) % 4;\n    );\n}\n\n// Should lint for params too\npub fn rem_euclid_4(num: i32) -> i32 {\n    ((num % 4) + 4) % 4\n    //~^ manual_rem_euclid\n}\n\n// Constant version came later, should still lint\npub const fn const_rem_euclid_4(num: i32) -> i32 {\n    ((num % 4) + 4) % 4\n    //~^ manual_rem_euclid\n}\n\n#[clippy::msrv = \"1.37\"]\npub fn msrv_1_37() {\n    let x: i32 = 10;\n    let _: i32 = ((x % 4) + 4) % 4;\n}\n\n#[clippy::msrv = \"1.38\"]\npub fn msrv_1_38() {\n    let x: i32 = 10;\n    let _: i32 = ((x % 4) + 4) % 4;\n    //~^ manual_rem_euclid\n}\n\n// For const fns:\n#[clippy::msrv = \"1.51\"]\npub const fn msrv_1_51() {\n    let x: i32 = 10;\n    let _: i32 = ((x % 4) + 4) % 4;\n}\n\n#[clippy::msrv = \"1.52\"]\npub const fn msrv_1_52() {\n    let x: i32 = 10;\n    let _: i32 = ((x % 4) + 4) % 4;\n    //~^ manual_rem_euclid\n}\n"
  },
  {
    "path": "tests/ui/manual_rem_euclid.stderr",
    "content": "error: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:13:18\n   |\nLL |     let _: i32 = ((value % 4) + 4) % 4;\n   |                  ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`\n   |\n   = note: `-D clippy::manual-rem-euclid` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_rem_euclid)]`\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:15:18\n   |\nLL |     let _: i32 = (4 + (value % 4)) % 4;\n   |                  ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:17:18\n   |\nLL |     let _: i32 = (value % 4 + 4) % 4;\n   |                  ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:19:18\n   |\nLL |     let _: i32 = (4 + value % 4) % 4;\n   |                  ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:21:22\n   |\nLL |     let _: i32 = 1 + (4 + value % 4) % 4;\n   |                      ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:42:22\n   |\nLL |         let _: i32 = ((value % 4) + 4) % 4;\n   |                      ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:55:5\n   |\nLL |     ((num % 4) + 4) % 4\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)`\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:61:5\n   |\nLL |     ((num % 4) + 4) % 4\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)`\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:74:18\n   |\nLL |     let _: i32 = ((x % 4) + 4) % 4;\n   |                  ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)`\n\nerror: manual `rem_euclid` implementation\n  --> tests/ui/manual_rem_euclid.rs:88:18\n   |\nLL |     let _: i32 = ((x % 4) + 4) % 4;\n   |                  ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_repeat_n.fixed",
    "content": "#![warn(clippy::manual_repeat_n)]\n\nuse std::iter::repeat;\n\nfn main() {\n    let _ = std::iter::repeat_n(10, 3);\n    //~^ manual_repeat_n\n\n    let _ = std::iter::repeat_n(String::from(\"foo\"), 4);\n    //~^ manual_repeat_n\n\n    for value in std::iter::repeat_n(5, 3) {}\n    //~^ manual_repeat_n\n\n    let _: Vec<_> = std::iter::repeat_n(String::from(\"bar\"), 10).collect();\n    //~^ manual_repeat_n\n\n    let _ = std::iter::repeat_n(vec![1, 2], 2);\n    //~^ manual_repeat_n\n}\n\nmod foo_lib {\n    pub fn iter() -> std::iter::Take<std::iter::Repeat<&'static [u8]>> {\n        todo!()\n    }\n}\n\nfn foo() {\n    let _ = match 1 {\n        1 => foo_lib::iter(),\n        // Shouldn't lint because `external_lib::iter` doesn't return `std::iter::RepeatN`.\n        2 => std::iter::repeat([1, 2].as_slice()).take(2),\n        _ => todo!(),\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_repeat_n.rs",
    "content": "#![warn(clippy::manual_repeat_n)]\n\nuse std::iter::repeat;\n\nfn main() {\n    let _ = repeat(10).take(3);\n    //~^ manual_repeat_n\n\n    let _ = repeat(String::from(\"foo\")).take(4);\n    //~^ manual_repeat_n\n\n    for value in std::iter::repeat(5).take(3) {}\n    //~^ manual_repeat_n\n\n    let _: Vec<_> = std::iter::repeat(String::from(\"bar\")).take(10).collect();\n    //~^ manual_repeat_n\n\n    let _ = repeat(vec![1, 2]).take(2);\n    //~^ manual_repeat_n\n}\n\nmod foo_lib {\n    pub fn iter() -> std::iter::Take<std::iter::Repeat<&'static [u8]>> {\n        todo!()\n    }\n}\n\nfn foo() {\n    let _ = match 1 {\n        1 => foo_lib::iter(),\n        // Shouldn't lint because `external_lib::iter` doesn't return `std::iter::RepeatN`.\n        2 => std::iter::repeat([1, 2].as_slice()).take(2),\n        _ => todo!(),\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_repeat_n.stderr",
    "content": "error: this `repeat().take()` can be written more concisely\n  --> tests/ui/manual_repeat_n.rs:6:13\n   |\nLL |     let _ = repeat(10).take(3);\n   |             ^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(10, 3)`\n   |\n   = note: `-D clippy::manual-repeat-n` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_repeat_n)]`\n\nerror: this `repeat().take()` can be written more concisely\n  --> tests/ui/manual_repeat_n.rs:9:13\n   |\nLL |     let _ = repeat(String::from(\"foo\")).take(4);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(String::from(\"foo\"), 4)`\n\nerror: this `repeat().take()` can be written more concisely\n  --> tests/ui/manual_repeat_n.rs:12:18\n   |\nLL |     for value in std::iter::repeat(5).take(3) {}\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(5, 3)`\n\nerror: this `repeat().take()` can be written more concisely\n  --> tests/ui/manual_repeat_n.rs:15:21\n   |\nLL |     let _: Vec<_> = std::iter::repeat(String::from(\"bar\")).take(10).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(String::from(\"bar\"), 10)`\n\nerror: this `repeat().take()` can be written more concisely\n  --> tests/ui/manual_repeat_n.rs:18:13\n   |\nLL |     let _ = repeat(vec![1, 2]).take(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(vec![1, 2], 2)`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_retain.fixed",
    "content": "#![warn(clippy::manual_retain)]\n#![allow(unused, clippy::needless_borrowed_reference, clippy::redundant_clone)]\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};\n\nfn main() {}\n\nfn binary_heap_retain() {\n    let mut binary_heap = BinaryHeap::from([1, 2, 3]);\n    // Do lint.\n    binary_heap.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    binary_heap.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    binary_heap.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n\n    // Do lint, because we use pattern matching\n    let mut tuples = BinaryHeap::from([(0, 1), (1, 2), (2, 3)]);\n    tuples.retain(|&(ref x, ref y)| *x == 0);\n    //~^ manual_retain\n    tuples.retain(|(x, y)| *x == 0);\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    binary_heap = binary_heap\n        .into_iter()\n        .filter(|x| x % 2 == 0)\n        .collect::<BinaryHeap<i8>>();\n    binary_heap = binary_heap\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .copied()\n        .collect::<BinaryHeap<i8>>();\n    binary_heap = binary_heap\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .cloned()\n        .collect::<BinaryHeap<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: BinaryHeap<i8> = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut foobar: BinaryHeap<i8> = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\nfn btree_map_retain() {\n    let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();\n    // Do lint.\n    btree_map.retain(|k, _| k % 2 == 0);\n    //~^ manual_retain\n    btree_map.retain(|_, &mut v| v % 2 == 0);\n    //~^ manual_retain\n    btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));\n\n    // Do not lint, because the parameters are not matched in tuple pattern\n    btree_map = btree_map.into_iter().filter(|t| t.0 % 2 == 0).collect();\n\n    // Do not lint.\n    btree_map = btree_map\n        .into_iter()\n        .filter(|(x, _)| x % 2 == 0)\n        .collect::<BTreeMap<i8, i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut foobar: BTreeMap<i8, i8> = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    btree_map = foobar.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n}\n\nfn btree_set_retain() {\n    let mut btree_set = BTreeSet::from([1, 2, 3, 4, 5, 6]);\n\n    // Do lint.\n    btree_set.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    btree_set.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    btree_set.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n\n    // Do lint, because we use pattern matching\n    let mut tuples = BTreeSet::from([(0, 1), (1, 2), (2, 3)]);\n    tuples.retain(|&(ref x, ref y)| *x == 0);\n    //~^ manual_retain\n    tuples.retain(|(x, y)| *x == 0);\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    btree_set = btree_set\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .copied()\n        .collect::<BTreeSet<i8>>();\n\n    btree_set = btree_set\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .cloned()\n        .collect::<BTreeSet<i8>>();\n\n    btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect::<BTreeSet<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut foobar: BTreeSet<i8> = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut bar: BTreeSet<i8> = btree_set.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\nfn hash_map_retain() {\n    let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();\n    // Do lint.\n    hash_map.retain(|k, _| k % 2 == 0);\n    //~^ manual_retain\n    hash_map.retain(|_, &mut v| v % 2 == 0);\n    //~^ manual_retain\n    hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));\n\n    // Do not lint, because the parameters are not matched in tuple pattern\n    hash_map = hash_map.into_iter().filter(|t| t.0 % 2 == 0).collect();\n\n    // Do not lint.\n    hash_map = hash_map\n        .into_iter()\n        .filter(|(x, _)| x % 2 == 0)\n        .collect::<HashMap<i8, i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut foobar: HashMap<i8, i8> = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    hash_map = foobar.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n}\n\nfn hash_set_retain() {\n    let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);\n    // Do lint.\n    hash_set.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    hash_set.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    hash_set.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n\n    // Do lint, because we use pattern matching\n    let mut tuples = HashSet::from([(0, 1), (1, 2), (2, 3)]);\n    tuples.retain(|&(ref x, ref y)| *x == 0);\n    //~^ manual_retain\n    tuples.retain(|(x, y)| *x == 0);\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();\n    hash_set = hash_set\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .copied()\n        .collect::<HashSet<i8>>();\n\n    hash_set = hash_set\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .cloned()\n        .collect::<HashSet<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: HashSet<i8> = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut foobar: HashSet<i8> = hash_set.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    bar = foobar.into_iter().filter(|&x| x % 2 == 0).collect();\n}\n\nfn string_retain() {\n    let mut s = String::from(\"foobar\");\n    // Do lint.\n    s.retain(|c| c != 'o');\n    //~^ manual_retain\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    s = bar.chars().filter(|&c| c != 'o').to_owned().collect();\n}\n\nfn vec_retain() {\n    let mut vec = vec![0, 1, 2];\n    // Do lint.\n    vec.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    vec.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    vec.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n\n    // Do lint, because we use pattern matching\n    let mut tuples = vec![(0, 1), (1, 2), (2, 3)];\n    tuples.retain(|&(ref x, ref y)| *x == 0);\n    //~^ manual_retain\n    tuples.retain(|(x, y)| *x == 0);\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();\n    vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();\n    vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect::<Vec<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: Vec<i8> = vec.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut foobar: Vec<i8> = vec.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\nfn vec_deque_retain() {\n    let mut vec_deque = VecDeque::new();\n    vec_deque.extend(1..5);\n\n    // Do lint.\n    vec_deque.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    vec_deque.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n    vec_deque.retain(|x| x % 2 == 0);\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    vec_deque = vec_deque\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .copied()\n        .collect::<VecDeque<i8>>();\n    vec_deque = vec_deque\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .cloned()\n        .collect::<VecDeque<i8>>();\n    vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect::<VecDeque<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: VecDeque<i8> = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut foobar: VecDeque<i8> = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\n#[clippy::msrv = \"1.69\"]\nfn _msrv_169() {\n    let mut binary_heap = BinaryHeap::from([1, 2, 3]);\n    binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\n#[clippy::msrv = \"1.52\"]\nfn _msrv_153() {\n    let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();\n    btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n\n    let mut btree_set = BTreeSet::from([1, 2, 3, 4, 5, 6]);\n    btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n}\n\n#[clippy::msrv = \"1.25\"]\nfn _msrv_126() {\n    let mut s = String::from(\"foobar\");\n    s = s.chars().filter(|&c| c != 'o').to_owned().collect();\n}\n\n#[clippy::msrv = \"1.17\"]\nfn _msrv_118() {\n    let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);\n    hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();\n    let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();\n    hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n}\n\nfn issue_10393() {\n    // Do lint\n    let mut vec = vec![(0, 1), (1, 2), (2, 3)];\n    vec.retain(|(x, y)| *x == 0);\n    //~^ manual_retain\n\n    // Do lint\n    let mut tuples = vec![(true, -2), (false, 3)];\n    tuples.retain(|(_, n)| *n > 0);\n    //~^ manual_retain\n}\n\nfn issue_11457() {\n    // Do not lint, as we need to modify the closure\n    let mut vals = vec![1, 2, 3, 4];\n    vals = vals.iter().filter(|v| **v != 1).cloned().collect();\n\n    // Do not lint, as we need to modify the closure\n    let mut s = String::from(\"foobar\");\n    s = s.chars().filter(|c| *c != 'o').to_owned().collect();\n}\n\nfn issue_12081() {\n    let mut vec = vec![0, 1, 2];\n\n    // Do lint\n    vec.retain(|&x| x == 0);\n    //~^ manual_retain\n    vec.retain(|&x| x == 0);\n    //~^ manual_retain\n    vec.retain(|&x| x == 0);\n    //~^ manual_retain\n\n    // Do lint\n    vec.retain(|x| *x == 0);\n    //~^ manual_retain\n    vec.retain(|x| *x == 0);\n    //~^ manual_retain\n    vec.retain(|x| *x == 0);\n    //~^ manual_retain\n}\n"
  },
  {
    "path": "tests/ui/manual_retain.rs",
    "content": "#![warn(clippy::manual_retain)]\n#![allow(unused, clippy::needless_borrowed_reference, clippy::redundant_clone)]\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};\n\nfn main() {}\n\nfn binary_heap_retain() {\n    let mut binary_heap = BinaryHeap::from([1, 2, 3]);\n    // Do lint.\n    binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();\n    //~^ manual_retain\n    binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();\n    //~^ manual_retain\n    binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    //~^ manual_retain\n\n    // Do lint, because we use pattern matching\n    let mut tuples = BinaryHeap::from([(0, 1), (1, 2), (2, 3)]);\n    tuples = tuples.iter().filter(|&&(ref x, ref y)| *x == 0).copied().collect();\n    //~^ manual_retain\n    tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    binary_heap = binary_heap\n        .into_iter()\n        .filter(|x| x % 2 == 0)\n        .collect::<BinaryHeap<i8>>();\n    binary_heap = binary_heap\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .copied()\n        .collect::<BinaryHeap<i8>>();\n    binary_heap = binary_heap\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .cloned()\n        .collect::<BinaryHeap<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: BinaryHeap<i8> = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut foobar: BinaryHeap<i8> = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\nfn btree_map_retain() {\n    let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();\n    // Do lint.\n    btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n    //~^ manual_retain\n    btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();\n    //~^ manual_retain\n    btree_map = btree_map\n        //~^ manual_retain\n        .into_iter()\n        .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))\n        .collect();\n\n    // Do not lint, because the parameters are not matched in tuple pattern\n    btree_map = btree_map.into_iter().filter(|t| t.0 % 2 == 0).collect();\n\n    // Do not lint.\n    btree_map = btree_map\n        .into_iter()\n        .filter(|(x, _)| x % 2 == 0)\n        .collect::<BTreeMap<i8, i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut foobar: BTreeMap<i8, i8> = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    btree_map = foobar.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n}\n\nfn btree_set_retain() {\n    let mut btree_set = BTreeSet::from([1, 2, 3, 4, 5, 6]);\n\n    // Do lint.\n    btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n    //~^ manual_retain\n    btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    //~^ manual_retain\n    btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();\n    //~^ manual_retain\n\n    // Do lint, because we use pattern matching\n    let mut tuples = BTreeSet::from([(0, 1), (1, 2), (2, 3)]);\n    tuples = tuples.iter().filter(|&&(ref x, ref y)| *x == 0).copied().collect();\n    //~^ manual_retain\n    tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    btree_set = btree_set\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .copied()\n        .collect::<BTreeSet<i8>>();\n\n    btree_set = btree_set\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .cloned()\n        .collect::<BTreeSet<i8>>();\n\n    btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect::<BTreeSet<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut foobar: BTreeSet<i8> = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut bar: BTreeSet<i8> = btree_set.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\nfn hash_map_retain() {\n    let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();\n    // Do lint.\n    hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n    //~^ manual_retain\n    hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();\n    //~^ manual_retain\n    hash_map = hash_map\n        //~^ manual_retain\n        .into_iter()\n        .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))\n        .collect();\n\n    // Do not lint, because the parameters are not matched in tuple pattern\n    hash_map = hash_map.into_iter().filter(|t| t.0 % 2 == 0).collect();\n\n    // Do not lint.\n    hash_map = hash_map\n        .into_iter()\n        .filter(|(x, _)| x % 2 == 0)\n        .collect::<HashMap<i8, i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut foobar: HashMap<i8, i8> = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    hash_map = foobar.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n}\n\nfn hash_set_retain() {\n    let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);\n    // Do lint.\n    hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();\n    //~^ manual_retain\n    hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n    //~^ manual_retain\n    hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    //~^ manual_retain\n\n    // Do lint, because we use pattern matching\n    let mut tuples = HashSet::from([(0, 1), (1, 2), (2, 3)]);\n    tuples = tuples.iter().filter(|&&(ref x, ref y)| *x == 0).copied().collect();\n    //~^ manual_retain\n    tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();\n    hash_set = hash_set\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .copied()\n        .collect::<HashSet<i8>>();\n\n    hash_set = hash_set\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .cloned()\n        .collect::<HashSet<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: HashSet<i8> = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut foobar: HashSet<i8> = hash_set.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    bar = foobar.into_iter().filter(|&x| x % 2 == 0).collect();\n}\n\nfn string_retain() {\n    let mut s = String::from(\"foobar\");\n    // Do lint.\n    s = s.chars().filter(|&c| c != 'o').to_owned().collect();\n    //~^ manual_retain\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: String = s.chars().filter(|&c| c != 'o').to_owned().collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    s = bar.chars().filter(|&c| c != 'o').to_owned().collect();\n}\n\nfn vec_retain() {\n    let mut vec = vec![0, 1, 2];\n    // Do lint.\n    vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();\n    //~^ manual_retain\n    vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    //~^ manual_retain\n    vec = vec.into_iter().filter(|x| x % 2 == 0).collect();\n    //~^ manual_retain\n\n    // Do lint, because we use pattern matching\n    let mut tuples = vec![(0, 1), (1, 2), (2, 3)];\n    tuples = tuples.iter().filter(|&&(ref x, ref y)| *x == 0).copied().collect();\n    //~^ manual_retain\n    tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();\n    vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();\n    vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect::<Vec<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: Vec<i8> = vec.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut foobar: Vec<i8> = vec.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\nfn vec_deque_retain() {\n    let mut vec_deque = VecDeque::new();\n    vec_deque.extend(1..5);\n\n    // Do lint.\n    vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();\n    //~^ manual_retain\n    vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    //~^ manual_retain\n    vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();\n    //~^ manual_retain\n\n    // Do not lint, because type conversion is performed\n    vec_deque = vec_deque\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .copied()\n        .collect::<VecDeque<i8>>();\n    vec_deque = vec_deque\n        .iter()\n        .filter(|&x| x % 2 == 0)\n        .cloned()\n        .collect::<VecDeque<i8>>();\n    vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect::<VecDeque<i8>>();\n\n    // Do not lint, because this expression is not assign.\n    let mut bar: VecDeque<i8> = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();\n    let mut foobar: VecDeque<i8> = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();\n\n    // Do not lint, because it is an assignment to a different variable.\n    bar = foobar.iter().filter(|&x| x % 2 == 0).copied().collect();\n    bar = foobar.iter().filter(|&x| x % 2 == 0).cloned().collect();\n    bar = foobar.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\n#[clippy::msrv = \"1.69\"]\nfn _msrv_169() {\n    let mut binary_heap = BinaryHeap::from([1, 2, 3]);\n    binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();\n}\n\n#[clippy::msrv = \"1.52\"]\nfn _msrv_153() {\n    let mut btree_map: BTreeMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();\n    btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n\n    let mut btree_set = BTreeSet::from([1, 2, 3, 4, 5, 6]);\n    btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n}\n\n#[clippy::msrv = \"1.25\"]\nfn _msrv_126() {\n    let mut s = String::from(\"foobar\");\n    s = s.chars().filter(|&c| c != 'o').to_owned().collect();\n}\n\n#[clippy::msrv = \"1.17\"]\nfn _msrv_118() {\n    let mut hash_set = HashSet::from([1, 2, 3, 4, 5, 6]);\n    hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();\n    let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();\n    hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n}\n\nfn issue_10393() {\n    // Do lint\n    let mut vec = vec![(0, 1), (1, 2), (2, 3)];\n    vec = vec.into_iter().filter(|(x, y)| *x == 0).collect();\n    //~^ manual_retain\n\n    // Do lint\n    let mut tuples = vec![(true, -2), (false, 3)];\n    tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect();\n    //~^ manual_retain\n}\n\nfn issue_11457() {\n    // Do not lint, as we need to modify the closure\n    let mut vals = vec![1, 2, 3, 4];\n    vals = vals.iter().filter(|v| **v != 1).cloned().collect();\n\n    // Do not lint, as we need to modify the closure\n    let mut s = String::from(\"foobar\");\n    s = s.chars().filter(|c| *c != 'o').to_owned().collect();\n}\n\nfn issue_12081() {\n    let mut vec = vec![0, 1, 2];\n\n    // Do lint\n    vec = vec.iter().filter(|&&x| x == 0).copied().collect();\n    //~^ manual_retain\n    vec = vec.iter().filter(|&&x| x == 0).cloned().collect();\n    //~^ manual_retain\n    vec = vec.into_iter().filter(|&x| x == 0).collect();\n    //~^ manual_retain\n\n    // Do lint\n    vec = vec.iter().filter(|&x| *x == 0).copied().collect();\n    //~^ manual_retain\n    vec = vec.iter().filter(|&x| *x == 0).cloned().collect();\n    //~^ manual_retain\n    vec = vec.into_iter().filter(|x| *x == 0).collect();\n    //~^ manual_retain\n}\n"
  },
  {
    "path": "tests/ui/manual_retain.stderr",
    "content": "error: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:10:5\n   |\nLL |     binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`\n   |\n   = note: `-D clippy::manual-retain` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_retain)]`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:12:5\n   |\nLL |     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:14:5\n   |\nLL |     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:19:5\n   |\nLL |     tuples = tuples.iter().filter(|&&(ref x, ref y)| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|&(ref x, ref y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:21:5\n   |\nLL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:52:5\n   |\nLL |     btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:54:5\n   |\nLL |     btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:56:5\n   |\nLL | /     btree_map = btree_map\nLL | |\nLL | |         .into_iter()\nLL | |         .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))\nLL | |         .collect();\n   | |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:82:5\n   |\nLL |     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:84:5\n   |\nLL |     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:86:5\n   |\nLL |     btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:91:5\n   |\nLL |     tuples = tuples.iter().filter(|&&(ref x, ref y)| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|&(ref x, ref y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:93:5\n   |\nLL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:124:5\n   |\nLL |     hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:126:5\n   |\nLL |     hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:128:5\n   |\nLL | /     hash_map = hash_map\nLL | |\nLL | |         .into_iter()\nLL | |         .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))\nLL | |         .collect();\n   | |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:153:5\n   |\nLL |     hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:155:5\n   |\nLL |     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:157:5\n   |\nLL |     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:162:5\n   |\nLL |     tuples = tuples.iter().filter(|&&(ref x, ref y)| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|&(ref x, ref y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:164:5\n   |\nLL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:194:5\n   |\nLL |     s = s.chars().filter(|&c| c != 'o').to_owned().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:207:5\n   |\nLL |     vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:209:5\n   |\nLL |     vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:211:5\n   |\nLL |     vec = vec.into_iter().filter(|x| x % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:216:5\n   |\nLL |     tuples = tuples.iter().filter(|&&(ref x, ref y)| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|&(ref x, ref y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:218:5\n   |\nLL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:241:5\n   |\nLL |     vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:243:5\n   |\nLL |     vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:245:5\n   |\nLL |     vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:303:5\n   |\nLL |     vec = vec.into_iter().filter(|(x, y)| *x == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|(x, y)| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:308:5\n   |\nLL |     tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(_, n)| *n > 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:326:5\n   |\nLL |     vec = vec.iter().filter(|&&x| x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:328:5\n   |\nLL |     vec = vec.iter().filter(|&&x| x == 0).cloned().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:330:5\n   |\nLL |     vec = vec.into_iter().filter(|&x| x == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:334:5\n   |\nLL |     vec = vec.iter().filter(|&x| *x == 0).copied().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:336:5\n   |\nLL |     vec = vec.iter().filter(|&x| *x == 0).cloned().collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`\n\nerror: this expression can be written more simply using `.retain()`\n  --> tests/ui/manual_retain.rs:338:5\n   |\nLL |     vec = vec.into_iter().filter(|x| *x == 0).collect();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`\n\nerror: aborting due to 38 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_rotate.fixed",
    "content": "#![warn(clippy::manual_rotate)]\n#![allow(unused)]\nfn main() {\n    let (x_u8, x_u16, x_u32, x_u64) = (1u8, 1u16, 1u32, 1u64);\n    let (x_i8, x_i16, x_i32, x_i64) = (1i8, 1i16, 1i32, 1i64);\n    let a_u32 = 1u32;\n    const N: u32 = 5;\n    // True positives\n    let y_u8 = x_u8.rotate_right(3);\n    //~^ manual_rotate\n    let y_u16 = x_u16.rotate_right(7);\n    //~^ manual_rotate\n    let y_u32 = x_u32.rotate_right(8);\n    //~^ manual_rotate\n    let y_u64 = x_u64.rotate_right(9);\n    //~^ manual_rotate\n    let y_i8 = x_i8.rotate_right(3);\n    //~^ manual_rotate\n    let y_i16 = x_i16.rotate_right(7);\n    //~^ manual_rotate\n    let y_i32 = x_i32.rotate_right(8);\n    //~^ manual_rotate\n    let y_i64 = x_i64.rotate_right(9);\n    //~^ manual_rotate\n    // Plus also works instead of |\n    let y_u32_plus = x_u32.rotate_right(8);\n    //~^ manual_rotate\n    // Complex expression\n    let y_u32_complex = (x_u32 | 3256).rotate_right(8);\n    //~^ manual_rotate\n    let y_u64_as = (x_u32 as u64).rotate_right(8);\n    //~^ manual_rotate\n    // shift by a const\n    let _ = x_i64.rotate_right(N);\n    //~^ manual_rotate\n\n    // False positives - can't be replaced with a rotation\n    let y_u8_false = (x_u8 >> 6) | (x_u8 << 3);\n    let y_u32_false = (x_u32 >> 8) | (x_u32 >> 24);\n    let y_u64_false2 = (x_u64 >> 9) & (x_u64 << 55);\n    // Variable mismatch\n    let y_u32_wrong_vars = (x_u32 >> 8) | (a_u32 << 24);\n    // Has side effects and therefore should not be matched\n    let mut l = vec![12_u8, 34];\n    let y = (l.pop().unwrap() << 3) + (l.pop().unwrap() >> 5);\n}\n\nfn issue13028() {\n    let s = 5;\n    let u = 5;\n    let x: u32 = 123456;\n\n    let _ = x.rotate_left(s);\n    //~^ manual_rotate\n    let _ = x.rotate_left(s);\n    //~^ manual_rotate\n    // still works with consts\n    let _ = x.rotate_right(9);\n    //~^ manual_rotate\n\n    // don't lint, because `s` and `u` are different variables, albeit with the same value\n    let _ = (x << s) | (x >> (32 - u));\n}\n"
  },
  {
    "path": "tests/ui/manual_rotate.rs",
    "content": "#![warn(clippy::manual_rotate)]\n#![allow(unused)]\nfn main() {\n    let (x_u8, x_u16, x_u32, x_u64) = (1u8, 1u16, 1u32, 1u64);\n    let (x_i8, x_i16, x_i32, x_i64) = (1i8, 1i16, 1i32, 1i64);\n    let a_u32 = 1u32;\n    const N: u32 = 5;\n    // True positives\n    let y_u8 = (x_u8 >> 3) | (x_u8 << 5);\n    //~^ manual_rotate\n    let y_u16 = (x_u16 >> 7) | (x_u16 << 9);\n    //~^ manual_rotate\n    let y_u32 = (x_u32 >> 8) | (x_u32 << 24);\n    //~^ manual_rotate\n    let y_u64 = (x_u64 >> 9) | (x_u64 << 55);\n    //~^ manual_rotate\n    let y_i8 = (x_i8 >> 3) | (x_i8 << 5);\n    //~^ manual_rotate\n    let y_i16 = (x_i16 >> 7) | (x_i16 << 9);\n    //~^ manual_rotate\n    let y_i32 = (x_i32 >> 8) | (x_i32 << 24);\n    //~^ manual_rotate\n    let y_i64 = (x_i64 >> 9) | (x_i64 << 55);\n    //~^ manual_rotate\n    // Plus also works instead of |\n    let y_u32_plus = (x_u32 >> 8) + (x_u32 << 24);\n    //~^ manual_rotate\n    // Complex expression\n    let y_u32_complex = ((x_u32 | 3256) >> 8) | ((x_u32 | 3256) << 24);\n    //~^ manual_rotate\n    let y_u64_as = (x_u32 as u64 >> 8) | ((x_u32 as u64) << 56);\n    //~^ manual_rotate\n    // shift by a const\n    let _ = (x_i64 >> N) | (x_i64 << (64 - N));\n    //~^ manual_rotate\n\n    // False positives - can't be replaced with a rotation\n    let y_u8_false = (x_u8 >> 6) | (x_u8 << 3);\n    let y_u32_false = (x_u32 >> 8) | (x_u32 >> 24);\n    let y_u64_false2 = (x_u64 >> 9) & (x_u64 << 55);\n    // Variable mismatch\n    let y_u32_wrong_vars = (x_u32 >> 8) | (a_u32 << 24);\n    // Has side effects and therefore should not be matched\n    let mut l = vec![12_u8, 34];\n    let y = (l.pop().unwrap() << 3) + (l.pop().unwrap() >> 5);\n}\n\nfn issue13028() {\n    let s = 5;\n    let u = 5;\n    let x: u32 = 123456;\n\n    let _ = (x << s) | (x >> (32 - s));\n    //~^ manual_rotate\n    let _ = (x << s) | (x >> (31 ^ s));\n    //~^ manual_rotate\n    // still works with consts\n    let _ = (x >> 9) | (x << (32 - 9));\n    //~^ manual_rotate\n\n    // don't lint, because `s` and `u` are different variables, albeit with the same value\n    let _ = (x << s) | (x >> (32 - u));\n}\n"
  },
  {
    "path": "tests/ui/manual_rotate.stderr",
    "content": "error: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:9:16\n   |\nLL |     let y_u8 = (x_u8 >> 3) | (x_u8 << 5);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u8.rotate_right(3)`\n   |\n   = note: `-D clippy::manual-rotate` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_rotate)]`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:11:17\n   |\nLL |     let y_u16 = (x_u16 >> 7) | (x_u16 << 9);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u16.rotate_right(7)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:13:17\n   |\nLL |     let y_u32 = (x_u32 >> 8) | (x_u32 << 24);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u32.rotate_right(8)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:15:17\n   |\nLL |     let y_u64 = (x_u64 >> 9) | (x_u64 << 55);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u64.rotate_right(9)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:17:16\n   |\nLL |     let y_i8 = (x_i8 >> 3) | (x_i8 << 5);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i8.rotate_right(3)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:19:17\n   |\nLL |     let y_i16 = (x_i16 >> 7) | (x_i16 << 9);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i16.rotate_right(7)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:21:17\n   |\nLL |     let y_i32 = (x_i32 >> 8) | (x_i32 << 24);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i32.rotate_right(8)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:23:17\n   |\nLL |     let y_i64 = (x_i64 >> 9) | (x_i64 << 55);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i64.rotate_right(9)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:26:22\n   |\nLL |     let y_u32_plus = (x_u32 >> 8) + (x_u32 << 24);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_u32.rotate_right(8)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:29:25\n   |\nLL |     let y_u32_complex = ((x_u32 | 3256) >> 8) | ((x_u32 | 3256) << 24);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `(x_u32 | 3256).rotate_right(8)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:31:20\n   |\nLL |     let y_u64_as = (x_u32 as u64 >> 8) | ((x_u32 as u64) << 56);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `(x_u32 as u64).rotate_right(8)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:34:13\n   |\nLL |     let _ = (x_i64 >> N) | (x_i64 << (64 - N));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x_i64.rotate_right(N)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:53:13\n   |\nLL |     let _ = (x << s) | (x >> (32 - s));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x.rotate_left(s)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:55:13\n   |\nLL |     let _ = (x << s) | (x >> (31 ^ s));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x.rotate_left(s)`\n\nerror: there is no need to manually implement bit rotation\n  --> tests/ui/manual_rotate.rs:58:13\n   |\nLL |     let _ = (x >> 9) | (x << (32 - 9));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: this expression can be rewritten as: `x.rotate_right(9)`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_saturating_arithmetic.fixed",
    "content": "#![allow(clippy::legacy_numeric_constants, unused_imports)]\n\nfn main() {\n    let _ = 1u32.saturating_add(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u32.saturating_add(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u8.saturating_add(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u128.saturating_add(1);\n    let _ = 1u32.checked_add(1).unwrap_or(1234); // ok\n    let _ = 1u8.checked_add(1).unwrap_or(0); // ok\n    let _ = 1u32.saturating_mul(1);\n    //~^ manual_saturating_arithmetic\n\n    let _ = 1u32.saturating_sub(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u32.saturating_sub(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u8.saturating_sub(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u32.checked_sub(1).unwrap_or(1234); // ok\n    let _ = 1u8.checked_sub(1).unwrap_or(255); // ok\n\n    let _ = 1i32.saturating_add(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i32.saturating_add(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i8.saturating_add(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i128.saturating_add(1);\n    let _ = 1i32.saturating_add(-1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i32.saturating_add(-1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i8.saturating_add(-1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i128.saturating_add(-1);\n    let _ = 1i32.checked_add(1).unwrap_or(1234); // ok\n    let _ = 1i8.checked_add(1).unwrap_or(-128); // ok\n    let _ = 1i8.checked_add(-1).unwrap_or(127); // ok\n\n    let _ = 1i32.saturating_sub(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i32.saturating_sub(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i8.saturating_sub(1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i128.saturating_sub(1);\n    let _ = 1i32.saturating_sub(-1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i32.saturating_sub(-1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i8.saturating_sub(-1);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i128.saturating_sub(-1);\n    let _ = 1i32.checked_sub(1).unwrap_or(1234); // ok\n    let _ = 1i8.checked_sub(1).unwrap_or(127); // ok\n    let _ = 1i8.checked_sub(-1).unwrap_or(-128); // ok\n}\n\nfn issue15655() {\n    let _ = 5u32.saturating_sub(1u32); //~ manual_saturating_arithmetic\n    let _ = 5u32.checked_add(1u32).unwrap_or_default(); // ok\n    let _ = 5u32.checked_mul(1u32).unwrap_or_default(); // ok\n\n    let _ = 5i32.checked_sub(1i32).unwrap_or_default(); // ok\n    let _ = 5i32.checked_add(1i32).unwrap_or_default(); // ok\n    let _ = 5i32.checked_mul(1i32).unwrap_or_default(); // ok\n}\n"
  },
  {
    "path": "tests/ui/manual_saturating_arithmetic.rs",
    "content": "#![allow(clippy::legacy_numeric_constants, unused_imports)]\n\nfn main() {\n    let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());\n    //~^ manual_saturating_arithmetic\n    let _ = 1u32.checked_add(1).unwrap_or(u32::MAX);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u8.checked_add(1).unwrap_or(255);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u128\n        //~^ manual_saturating_arithmetic\n        .checked_add(1)\n        .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455);\n    let _ = 1u32.checked_add(1).unwrap_or(1234); // ok\n    let _ = 1u8.checked_add(1).unwrap_or(0); // ok\n    let _ = 1u32.checked_mul(1).unwrap_or(u32::MAX);\n    //~^ manual_saturating_arithmetic\n\n    let _ = 1u32.checked_sub(1).unwrap_or(u32::min_value());\n    //~^ manual_saturating_arithmetic\n    let _ = 1u32.checked_sub(1).unwrap_or(u32::MIN);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u8.checked_sub(1).unwrap_or(0);\n    //~^ manual_saturating_arithmetic\n    let _ = 1u32.checked_sub(1).unwrap_or(1234); // ok\n    let _ = 1u8.checked_sub(1).unwrap_or(255); // ok\n\n    let _ = 1i32.checked_add(1).unwrap_or(i32::max_value());\n    //~^ manual_saturating_arithmetic\n    let _ = 1i32.checked_add(1).unwrap_or(i32::MAX);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i8.checked_add(1).unwrap_or(127);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i128\n        //~^ manual_saturating_arithmetic\n        .checked_add(1)\n        .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);\n    let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value());\n    //~^ manual_saturating_arithmetic\n    let _ = 1i32.checked_add(-1).unwrap_or(i32::MIN);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i8.checked_add(-1).unwrap_or(-128);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i128\n        //~^ manual_saturating_arithmetic\n        .checked_add(-1)\n        .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);\n    let _ = 1i32.checked_add(1).unwrap_or(1234); // ok\n    let _ = 1i8.checked_add(1).unwrap_or(-128); // ok\n    let _ = 1i8.checked_add(-1).unwrap_or(127); // ok\n\n    let _ = 1i32.checked_sub(1).unwrap_or(i32::min_value());\n    //~^ manual_saturating_arithmetic\n    let _ = 1i32.checked_sub(1).unwrap_or(i32::MIN);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i8.checked_sub(1).unwrap_or(-128);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i128\n        //~^ manual_saturating_arithmetic\n        .checked_sub(1)\n        .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);\n    let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value());\n    //~^ manual_saturating_arithmetic\n    let _ = 1i32.checked_sub(-1).unwrap_or(i32::MAX);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i8.checked_sub(-1).unwrap_or(127);\n    //~^ manual_saturating_arithmetic\n    let _ = 1i128\n        //~^ manual_saturating_arithmetic\n        .checked_sub(-1)\n        .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);\n    let _ = 1i32.checked_sub(1).unwrap_or(1234); // ok\n    let _ = 1i8.checked_sub(1).unwrap_or(127); // ok\n    let _ = 1i8.checked_sub(-1).unwrap_or(-128); // ok\n}\n\nfn issue15655() {\n    let _ = 5u32.checked_sub(1u32).unwrap_or_default(); //~ manual_saturating_arithmetic\n    let _ = 5u32.checked_add(1u32).unwrap_or_default(); // ok\n    let _ = 5u32.checked_mul(1u32).unwrap_or_default(); // ok\n\n    let _ = 5i32.checked_sub(1i32).unwrap_or_default(); // ok\n    let _ = 5i32.checked_add(1i32).unwrap_or_default(); // ok\n    let _ = 5i32.checked_mul(1i32).unwrap_or_default(); // ok\n}\n"
  },
  {
    "path": "tests/ui/manual_saturating_arithmetic.stderr",
    "content": "error: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:4:13\n   |\nLL |     let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)`\n   |\n   = note: `-D clippy::manual-saturating-arithmetic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_saturating_arithmetic)]`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:6:13\n   |\nLL |     let _ = 1u32.checked_add(1).unwrap_or(u32::MAX);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:8:13\n   |\nLL |     let _ = 1u8.checked_add(1).unwrap_or(255);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u8.saturating_add(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:10:13\n   |\nLL |       let _ = 1u128\n   |  _____________^\nLL | |\nLL | |         .checked_add(1)\nLL | |         .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455);\n   | |_______________________________________________________________________^ help: consider using `saturating_add`: `1u128.saturating_add(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:16:13\n   |\nLL |     let _ = 1u32.checked_mul(1).unwrap_or(u32::MAX);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_mul`: `1u32.saturating_mul(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:19:13\n   |\nLL |     let _ = 1u32.checked_sub(1).unwrap_or(u32::min_value());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:21:13\n   |\nLL |     let _ = 1u32.checked_sub(1).unwrap_or(u32::MIN);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:23:13\n   |\nLL |     let _ = 1u8.checked_sub(1).unwrap_or(0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u8.saturating_sub(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:28:13\n   |\nLL |     let _ = 1i32.checked_add(1).unwrap_or(i32::max_value());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:30:13\n   |\nLL |     let _ = 1i32.checked_add(1).unwrap_or(i32::MAX);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:32:13\n   |\nLL |     let _ = 1i8.checked_add(1).unwrap_or(127);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:34:13\n   |\nLL |       let _ = 1i128\n   |  _____________^\nLL | |\nLL | |         .checked_add(1)\nLL | |         .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);\n   | |_______________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:38:13\n   |\nLL |     let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:40:13\n   |\nLL |     let _ = 1i32.checked_add(-1).unwrap_or(i32::MIN);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:42:13\n   |\nLL |     let _ = 1i8.checked_add(-1).unwrap_or(-128);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(-1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:44:13\n   |\nLL |       let _ = 1i128\n   |  _____________^\nLL | |\nLL | |         .checked_add(-1)\nLL | |         .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);\n   | |________________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(-1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:52:13\n   |\nLL |     let _ = 1i32.checked_sub(1).unwrap_or(i32::min_value());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:54:13\n   |\nLL |     let _ = 1i32.checked_sub(1).unwrap_or(i32::MIN);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:56:13\n   |\nLL |     let _ = 1i8.checked_sub(1).unwrap_or(-128);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:58:13\n   |\nLL |       let _ = 1i128\n   |  _____________^\nLL | |\nLL | |         .checked_sub(1)\nLL | |         .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);\n   | |________________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:62:13\n   |\nLL |     let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:64:13\n   |\nLL |     let _ = 1i32.checked_sub(-1).unwrap_or(i32::MAX);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:66:13\n   |\nLL |     let _ = 1i8.checked_sub(-1).unwrap_or(127);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(-1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:68:13\n   |\nLL |       let _ = 1i128\n   |  _____________^\nLL | |\nLL | |         .checked_sub(-1)\nLL | |         .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);\n   | |_______________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(-1)`\n\nerror: manual saturating arithmetic\n  --> tests/ui/manual_saturating_arithmetic.rs:78:13\n   |\nLL |     let _ = 5u32.checked_sub(1u32).unwrap_or_default();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `5u32.saturating_sub(1u32)`\n\nerror: aborting due to 25 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_slice_fill.fixed",
    "content": "#![warn(clippy::manual_slice_fill)]\n#![allow(clippy::needless_range_loop, clippy::useless_vec)]\n\nmacro_rules! assign_element {\n    ($slice:ident, $index:expr) => {\n        $slice[$index] = 0;\n    };\n}\n\nmacro_rules! assign_element_2 {\n    ($i:expr) => {\n        $i = 0;\n    };\n}\n\nstruct NoClone;\n\nfn num() -> usize {\n    5\n}\n\nfn should_lint() {\n    let mut some_slice = [1, 2, 3, 4, 5];\n\n    some_slice.fill(0);\n\n    let x = 5;\n    some_slice.fill(x);\n\n    some_slice.fill(0);\n\n    // This should trigger `manual_slice_fill`, but the applicability is `MaybeIncorrect` since comments\n    // within the loop might be purely informational.\n    some_slice.fill(0);\n}\n\nfn should_not_lint() {\n    let mut some_slice = [1, 2, 3, 4, 5];\n\n    // Should not lint because we can't determine if the scope of the loop is intended to access all the\n    // elements of the slice.\n    for i in 0..5 {\n        some_slice[i] = 0;\n    }\n\n    // Should not lint, as using a function to assign values to elements might be\n    // intentional. For example, the contents of `num()` could be temporary and subject to change\n    // later.\n    for i in 0..some_slice.len() {\n        some_slice[i] = num();\n    }\n\n    // Should not lint because this loop isn't equivalent to `fill`.\n    for i in 0..some_slice.len() {\n        some_slice[i] = 0;\n        println!(\"foo\");\n    }\n\n    // Should not lint because it may be intentional to use a macro to perform an operation equivalent\n    // to `fill`.\n    for i in 0..some_slice.len() {\n        assign_element!(some_slice, i);\n    }\n\n    let another_slice = [1, 2, 3];\n    // Should not lint because the range is not for `some_slice`.\n    for i in 0..another_slice.len() {\n        some_slice[i] = 0;\n    }\n\n    let mut vec: Vec<Option<NoClone>> = Vec::with_capacity(5);\n    // Should not lint because `NoClone` does not have `Clone` trait.\n    for i in 0..vec.len() {\n        vec[i] = None;\n    }\n\n    // Should not lint, as using a function to assign values to elements might be\n    // intentional. For example, the contents of `num()` could be temporary and subject to change\n    // later.\n    for i in &mut some_slice {\n        *i = num();\n    }\n\n    // Should not lint because this loop isn't equivalent to `fill`.\n    for i in &mut some_slice {\n        *i = 0;\n        println!(\"foo\");\n    }\n\n    // Should not lint because it may be intentional to use a macro to perform an operation equivalent\n    // to `fill`.\n    for i in &mut some_slice {\n        assign_element_2!(*i);\n    }\n\n    let mut vec: Vec<Option<NoClone>> = Vec::with_capacity(5);\n    // Should not lint because `NoClone` does not have `Clone` trait.\n    for i in &mut vec {\n        *i = None;\n    }\n}\n\nfn issue_14192() {\n    let mut tmp = vec![0; 3];\n\n    for i in 0..tmp.len() {\n        tmp[i] = i;\n    }\n\n    for i in 0..tmp.len() {\n        tmp[i] = 2 + i;\n    }\n\n    for i in 0..tmp.len() {\n        tmp[0] = i;\n    }\n}\n\nfn issue14189() {\n    // Should not lint because `!*b` is not constant\n    let mut tmp = vec![1, 2, 3];\n    for b in &mut tmp {\n        *b = !*b;\n    }\n}\n\nmod issue14685 {\n    use std::ops::{Index, IndexMut};\n\n    #[derive(Clone)]\n    struct ZipList<T>(T);\n\n    impl<T> ZipList<T> {\n        fn len(&self) -> usize {\n            todo!()\n        }\n\n        fn is_empty(&self) -> bool {\n            todo!()\n        }\n    }\n\n    impl<T> Index<usize> for ZipList<T> {\n        type Output = T;\n\n        fn index(&self, _: usize) -> &Self::Output {\n            todo!()\n        }\n    }\n\n    impl<T> IndexMut<usize> for ZipList<T> {\n        fn index_mut(&mut self, _: usize) -> &mut Self::Output {\n            todo!()\n        }\n    }\n\n    fn index_mut(mut zl: ZipList<usize>) {\n        for i in 0..zl.len() {\n            zl[i] = 6;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_slice_fill.rs",
    "content": "#![warn(clippy::manual_slice_fill)]\n#![allow(clippy::needless_range_loop, clippy::useless_vec)]\n\nmacro_rules! assign_element {\n    ($slice:ident, $index:expr) => {\n        $slice[$index] = 0;\n    };\n}\n\nmacro_rules! assign_element_2 {\n    ($i:expr) => {\n        $i = 0;\n    };\n}\n\nstruct NoClone;\n\nfn num() -> usize {\n    5\n}\n\nfn should_lint() {\n    let mut some_slice = [1, 2, 3, 4, 5];\n\n    for i in 0..some_slice.len() {\n        //~^ manual_slice_fill\n        some_slice[i] = 0;\n    }\n\n    let x = 5;\n    for i in 0..some_slice.len() {\n        //~^ manual_slice_fill\n        some_slice[i] = x;\n    }\n\n    for i in &mut some_slice {\n        //~^ manual_slice_fill\n        *i = 0;\n    }\n\n    // This should trigger `manual_slice_fill`, but the applicability is `MaybeIncorrect` since comments\n    // within the loop might be purely informational.\n    for i in 0..some_slice.len() {\n        //~^ manual_slice_fill\n        some_slice[i] = 0;\n        // foo\n    }\n}\n\nfn should_not_lint() {\n    let mut some_slice = [1, 2, 3, 4, 5];\n\n    // Should not lint because we can't determine if the scope of the loop is intended to access all the\n    // elements of the slice.\n    for i in 0..5 {\n        some_slice[i] = 0;\n    }\n\n    // Should not lint, as using a function to assign values to elements might be\n    // intentional. For example, the contents of `num()` could be temporary and subject to change\n    // later.\n    for i in 0..some_slice.len() {\n        some_slice[i] = num();\n    }\n\n    // Should not lint because this loop isn't equivalent to `fill`.\n    for i in 0..some_slice.len() {\n        some_slice[i] = 0;\n        println!(\"foo\");\n    }\n\n    // Should not lint because it may be intentional to use a macro to perform an operation equivalent\n    // to `fill`.\n    for i in 0..some_slice.len() {\n        assign_element!(some_slice, i);\n    }\n\n    let another_slice = [1, 2, 3];\n    // Should not lint because the range is not for `some_slice`.\n    for i in 0..another_slice.len() {\n        some_slice[i] = 0;\n    }\n\n    let mut vec: Vec<Option<NoClone>> = Vec::with_capacity(5);\n    // Should not lint because `NoClone` does not have `Clone` trait.\n    for i in 0..vec.len() {\n        vec[i] = None;\n    }\n\n    // Should not lint, as using a function to assign values to elements might be\n    // intentional. For example, the contents of `num()` could be temporary and subject to change\n    // later.\n    for i in &mut some_slice {\n        *i = num();\n    }\n\n    // Should not lint because this loop isn't equivalent to `fill`.\n    for i in &mut some_slice {\n        *i = 0;\n        println!(\"foo\");\n    }\n\n    // Should not lint because it may be intentional to use a macro to perform an operation equivalent\n    // to `fill`.\n    for i in &mut some_slice {\n        assign_element_2!(*i);\n    }\n\n    let mut vec: Vec<Option<NoClone>> = Vec::with_capacity(5);\n    // Should not lint because `NoClone` does not have `Clone` trait.\n    for i in &mut vec {\n        *i = None;\n    }\n}\n\nfn issue_14192() {\n    let mut tmp = vec![0; 3];\n\n    for i in 0..tmp.len() {\n        tmp[i] = i;\n    }\n\n    for i in 0..tmp.len() {\n        tmp[i] = 2 + i;\n    }\n\n    for i in 0..tmp.len() {\n        tmp[0] = i;\n    }\n}\n\nfn issue14189() {\n    // Should not lint because `!*b` is not constant\n    let mut tmp = vec![1, 2, 3];\n    for b in &mut tmp {\n        *b = !*b;\n    }\n}\n\nmod issue14685 {\n    use std::ops::{Index, IndexMut};\n\n    #[derive(Clone)]\n    struct ZipList<T>(T);\n\n    impl<T> ZipList<T> {\n        fn len(&self) -> usize {\n            todo!()\n        }\n\n        fn is_empty(&self) -> bool {\n            todo!()\n        }\n    }\n\n    impl<T> Index<usize> for ZipList<T> {\n        type Output = T;\n\n        fn index(&self, _: usize) -> &Self::Output {\n            todo!()\n        }\n    }\n\n    impl<T> IndexMut<usize> for ZipList<T> {\n        fn index_mut(&mut self, _: usize) -> &mut Self::Output {\n            todo!()\n        }\n    }\n\n    fn index_mut(mut zl: ZipList<usize>) {\n        for i in 0..zl.len() {\n            zl[i] = 6;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_slice_fill.stderr",
    "content": "error: manually filling a slice\n  --> tests/ui/manual_slice_fill.rs:25:5\n   |\nLL | /     for i in 0..some_slice.len() {\nLL | |\nLL | |         some_slice[i] = 0;\nLL | |     }\n   | |_____^ help: try: `some_slice.fill(0);`\n   |\n   = note: `-D clippy::manual-slice-fill` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_slice_fill)]`\n\nerror: manually filling a slice\n  --> tests/ui/manual_slice_fill.rs:31:5\n   |\nLL | /     for i in 0..some_slice.len() {\nLL | |\nLL | |         some_slice[i] = x;\nLL | |     }\n   | |_____^ help: try: `some_slice.fill(x);`\n\nerror: manually filling a slice\n  --> tests/ui/manual_slice_fill.rs:36:5\n   |\nLL | /     for i in &mut some_slice {\nLL | |\nLL | |         *i = 0;\nLL | |     }\n   | |_____^ help: try: `some_slice.fill(0);`\n\nerror: manually filling a slice\n  --> tests/ui/manual_slice_fill.rs:43:5\n   |\nLL | /     for i in 0..some_slice.len() {\nLL | |\nLL | |         some_slice[i] = 0;\nLL | |         // foo\nLL | |     }\n   | |_____^ help: try: `some_slice.fill(0);`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_slice_size_calculation.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(unused)]\n#![warn(clippy::manual_slice_size_calculation)]\n\nextern crate proc_macros;\n\nuse core::mem::{align_of, size_of};\nuse proc_macros::external;\n\nfn main() {\n    let v_i32 = Vec::<i32>::new();\n    let s_i32 = v_i32.as_slice();\n    let s_i32_ref = &s_i32;\n    let s_i32_ref_ref = &s_i32_ref;\n\n    // True positives:\n    let _ = std::mem::size_of_val(s_i32); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = std::mem::size_of_val(s_i32); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = std::mem::size_of_val(s_i32) * 5; // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = std::mem::size_of_val(*s_i32_ref); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = std::mem::size_of_val(**s_i32_ref_ref); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n\n    let len = s_i32.len();\n    let size = size_of::<i32>();\n    let _ = std::mem::size_of_val(s_i32); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = std::mem::size_of_val(s_i32); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = std::mem::size_of_val(s_i32); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n\n    let _ = std::mem::size_of_val(external!(&[1u64][..]));\n    //~^ manual_slice_size_calculation\n\n    // True negatives:\n    let _ = size_of::<i32>() + s_i32.len(); // Ok, not a multiplication\n    let _ = size_of::<i32>() * s_i32.partition_point(|_| true); // Ok, not len()\n    let _ = size_of::<i32>() * v_i32.len(); // Ok, not a slice\n    let _ = align_of::<i32>() * s_i32.len(); // Ok, not size_of()\n    let _ = size_of::<u32>() * s_i32.len(); // Ok, different types\n\n    let _ = external!($s_i32.len() * size_of::<i32>());\n    let _ = external!($s_i32.len()) * size_of::<i32>();\n\n    // False negatives:\n    let _ = 5 * size_of::<i32>() * s_i32.len(); // Ok (MISSED OPPORTUNITY)\n    let _ = size_of::<i32>() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY)\n}\n\n#[clippy::msrv = \"1.85\"]\nconst fn const_ok(s_i32: &[i32]) {\n    let _ = std::mem::size_of_val(s_i32);\n    //~^ manual_slice_size_calculation\n}\n\n#[clippy::msrv = \"1.84\"]\nconst fn const_before_msrv(s_i32: &[i32]) {\n    let _ = s_i32.len() * size_of::<i32>();\n}\n\nfn issue_14802() {\n    struct IcedSlice {\n        dst: [u8],\n    }\n\n    impl IcedSlice {\n        fn get_len(&self) -> usize {\n            std::mem::size_of_val(&self.dst)\n            //~^ manual_slice_size_calculation\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_slice_size_calculation.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(unused)]\n#![warn(clippy::manual_slice_size_calculation)]\n\nextern crate proc_macros;\n\nuse core::mem::{align_of, size_of};\nuse proc_macros::external;\n\nfn main() {\n    let v_i32 = Vec::<i32>::new();\n    let s_i32 = v_i32.as_slice();\n    let s_i32_ref = &s_i32;\n    let s_i32_ref_ref = &s_i32_ref;\n\n    // True positives:\n    let _ = s_i32.len() * size_of::<i32>(); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = size_of::<i32>() * s_i32.len(); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = size_of::<i32>() * s_i32.len() * 5; // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = size_of::<i32>() * s_i32_ref.len(); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = size_of::<i32>() * s_i32_ref_ref.len(); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n\n    let len = s_i32.len();\n    let size = size_of::<i32>();\n    let _ = len * size_of::<i32>(); // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = s_i32.len() * size; // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n    let _ = len * size; // WARNING\n    //\n    //~^^ manual_slice_size_calculation\n\n    let _ = external!(&[1u64][..]).len() * size_of::<u64>();\n    //~^ manual_slice_size_calculation\n\n    // True negatives:\n    let _ = size_of::<i32>() + s_i32.len(); // Ok, not a multiplication\n    let _ = size_of::<i32>() * s_i32.partition_point(|_| true); // Ok, not len()\n    let _ = size_of::<i32>() * v_i32.len(); // Ok, not a slice\n    let _ = align_of::<i32>() * s_i32.len(); // Ok, not size_of()\n    let _ = size_of::<u32>() * s_i32.len(); // Ok, different types\n\n    let _ = external!($s_i32.len() * size_of::<i32>());\n    let _ = external!($s_i32.len()) * size_of::<i32>();\n\n    // False negatives:\n    let _ = 5 * size_of::<i32>() * s_i32.len(); // Ok (MISSED OPPORTUNITY)\n    let _ = size_of::<i32>() * 5 * s_i32.len(); // Ok (MISSED OPPORTUNITY)\n}\n\n#[clippy::msrv = \"1.85\"]\nconst fn const_ok(s_i32: &[i32]) {\n    let _ = s_i32.len() * size_of::<i32>();\n    //~^ manual_slice_size_calculation\n}\n\n#[clippy::msrv = \"1.84\"]\nconst fn const_before_msrv(s_i32: &[i32]) {\n    let _ = s_i32.len() * size_of::<i32>();\n}\n\nfn issue_14802() {\n    struct IcedSlice {\n        dst: [u8],\n    }\n\n    impl IcedSlice {\n        fn get_len(&self) -> usize {\n            self.dst.len() * size_of::<u8>()\n            //~^ manual_slice_size_calculation\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_slice_size_calculation.stderr",
    "content": "error: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:17:13\n   |\nLL |     let _ = s_i32.len() * size_of::<i32>(); // WARNING\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`\n   |\n   = note: `-D clippy::manual-slice-size-calculation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_slice_size_calculation)]`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:20:13\n   |\nLL |     let _ = size_of::<i32>() * s_i32.len(); // WARNING\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:23:13\n   |\nLL |     let _ = size_of::<i32>() * s_i32.len() * 5; // WARNING\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:26:13\n   |\nLL |     let _ = size_of::<i32>() * s_i32_ref.len(); // WARNING\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(*s_i32_ref)`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:29:13\n   |\nLL |     let _ = size_of::<i32>() * s_i32_ref_ref.len(); // WARNING\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(**s_i32_ref_ref)`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:35:13\n   |\nLL |     let _ = len * size_of::<i32>(); // WARNING\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:38:13\n   |\nLL |     let _ = s_i32.len() * size; // WARNING\n   |             ^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:41:13\n   |\nLL |     let _ = len * size; // WARNING\n   |             ^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:45:13\n   |\nLL |     let _ = external!(&[1u64][..]).len() * size_of::<u64>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(external!(&[1u64][..]))`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:65:13\n   |\nLL |     let _ = s_i32.len() * size_of::<i32>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(s_i32)`\n\nerror: manual slice size calculation\n  --> tests/ui/manual_slice_size_calculation.rs:81:13\n   |\nLL |             self.dst.len() * size_of::<u8>()\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::mem::size_of_val(&self.dst)`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_split_once.fixed",
    "content": "#![warn(clippy::manual_split_once)]\n#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]\n\nextern crate itertools;\n\n#[allow(unused_imports)]\nuse itertools::Itertools;\n\nfn main() {\n    let _ = \"key=value\".splitn(2, '=').nth(2);\n    let _ = \"key=value\".split_once('=').unwrap().1;\n    //~^ manual_split_once\n    let _ = \"key=value\".split_once('=').unwrap().1;\n    //~^ manual_split_once\n    let (_, _) = \"key=value\".split_once('=').unwrap();\n    //~^ manual_split_once\n\n    let s = String::from(\"key=value\");\n    let _ = s.split_once('=').unwrap().1;\n    //~^ manual_split_once\n\n    let s = Box::<str>::from(\"key=value\");\n    let _ = s.split_once('=').unwrap().1;\n    //~^ manual_split_once\n\n    let s = &\"key=value\";\n    let _ = s.split_once('=').unwrap().1;\n    //~^ manual_split_once\n\n    fn _f(s: &str) -> Option<&str> {\n        let _ = s.split_once('=')?.1;\n        //~^ manual_split_once\n        let _ = s.split_once('=')?.1;\n        //~^ manual_split_once\n        let _ = s.rsplit_once('=')?.0;\n        //~^ manual_split_once\n        let _ = s.rsplit_once('=')?.0;\n        //~^ manual_split_once\n        None\n    }\n\n    // Don't lint, slices don't have `split_once`\n    let _ = [0, 1, 2].splitn(2, |&x| x == 1).nth(1).unwrap();\n\n    // `rsplitn` gives the results in the reverse order of `rsplit_once`\n    let _ = \"key=value\".rsplit_once('=').unwrap().0;\n    //~^ manual_split_once\n    let (_, _) = \"key=value\".rsplit_once('=').map(|(x, y)| (y, x)).unwrap();\n    //~^ manual_split_once\n    let _ = s.rsplit_once('=').map(|x| x.0);\n    //~^ manual_split_once\n}\n\nfn indirect() -> Option<()> {\n    let (l, r) = \"a.b.c\".split_once('.').unwrap();\n    //~^ manual_split_once\n    \n    \n\n    let (l, r) = \"a.b.c\".split_once('.')?;\n    //~^ manual_split_once\n    \n    \n\n    let (l, r) = \"a.b.c\".rsplit_once('.').unwrap();\n    //~^ manual_split_once\n    \n    \n\n    let (l, r) = \"a.b.c\".rsplit_once('.')?;\n    //~^ manual_split_once\n    \n    \n\n    // could lint, currently doesn't\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let other = 1;\n    let l = iter.next()?;\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let mut mut_binding = iter.next()?;\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let tuple = (iter.next()?, iter.next()?);\n\n    // should not lint\n\n    let mut missing_unwrap = \"a.b.c\".splitn(2, '.');\n    let l = missing_unwrap.next();\n    let r = missing_unwrap.next();\n\n    let mut mixed_unrap = \"a.b.c\".splitn(2, '.');\n    let unwrap = mixed_unrap.next().unwrap();\n    let question_mark = mixed_unrap.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let same_name = iter.next()?;\n    let same_name = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let shadows_existing = \"d\";\n    let shadows_existing = iter.next()?;\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let becomes_shadowed = iter.next()?;\n    let becomes_shadowed = \"d\";\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let l = iter.next()?;\n    let r = iter.next()?;\n    let third_usage = iter.next()?;\n\n    let mut n_three = \"a.b.c\".splitn(3, '.');\n    let l = n_three.next()?;\n    let r = n_three.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    {\n        let in_block = iter.next()?;\n    }\n    let r = iter.next()?;\n\n    let mut lacks_binding = \"a.b.c\".splitn(2, '.');\n    let _ = lacks_binding.next()?;\n    let r = lacks_binding.next()?;\n\n    let mut mapped = \"a.b.c\".splitn(2, '.').map(|_| \"~\");\n    let l = iter.next()?;\n    let r = iter.next()?;\n\n    let mut assigned = \"\";\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let l = iter.next()?;\n    assigned = iter.next()?;\n\n    None\n}\n\n#[clippy::msrv = \"1.51\"]\nfn _msrv_1_51() {\n    // `str::split_once` was stabilized in 1.52. Do not lint this\n    let _ = \"key=value\".splitn(2, '=').nth(1).unwrap();\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let a = iter.next().unwrap();\n    let b = iter.next().unwrap();\n}\n\n#[clippy::msrv = \"1.52\"]\nfn _msrv_1_52() {\n    let _ = \"key=value\".split_once('=').unwrap().1;\n    //~^ manual_split_once\n\n    let (a, b) = \"a.b.c\".split_once('.').unwrap();\n    //~^ manual_split_once\n    \n    \n}\n"
  },
  {
    "path": "tests/ui/manual_split_once.rs",
    "content": "#![warn(clippy::manual_split_once)]\n#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]\n\nextern crate itertools;\n\n#[allow(unused_imports)]\nuse itertools::Itertools;\n\nfn main() {\n    let _ = \"key=value\".splitn(2, '=').nth(2);\n    let _ = \"key=value\".splitn(2, '=').nth(1).unwrap();\n    //~^ manual_split_once\n    let _ = \"key=value\".splitn(2, '=').skip(1).next().unwrap();\n    //~^ manual_split_once\n    let (_, _) = \"key=value\".splitn(2, '=').next_tuple().unwrap();\n    //~^ manual_split_once\n\n    let s = String::from(\"key=value\");\n    let _ = s.splitn(2, '=').nth(1).unwrap();\n    //~^ manual_split_once\n\n    let s = Box::<str>::from(\"key=value\");\n    let _ = s.splitn(2, '=').nth(1).unwrap();\n    //~^ manual_split_once\n\n    let s = &\"key=value\";\n    let _ = s.splitn(2, '=').skip(1).next().unwrap();\n    //~^ manual_split_once\n\n    fn _f(s: &str) -> Option<&str> {\n        let _ = s.splitn(2, '=').nth(1)?;\n        //~^ manual_split_once\n        let _ = s.splitn(2, '=').skip(1).next()?;\n        //~^ manual_split_once\n        let _ = s.rsplitn(2, '=').nth(1)?;\n        //~^ manual_split_once\n        let _ = s.rsplitn(2, '=').skip(1).next()?;\n        //~^ manual_split_once\n        None\n    }\n\n    // Don't lint, slices don't have `split_once`\n    let _ = [0, 1, 2].splitn(2, |&x| x == 1).nth(1).unwrap();\n\n    // `rsplitn` gives the results in the reverse order of `rsplit_once`\n    let _ = \"key=value\".rsplitn(2, '=').nth(1).unwrap();\n    //~^ manual_split_once\n    let (_, _) = \"key=value\".rsplitn(2, '=').next_tuple().unwrap();\n    //~^ manual_split_once\n    let _ = s.rsplitn(2, '=').nth(1);\n    //~^ manual_split_once\n}\n\nfn indirect() -> Option<()> {\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    //~^ manual_split_once\n    let l = iter.next().unwrap();\n    let r = iter.next().unwrap();\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    //~^ manual_split_once\n    let l = iter.next()?;\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".rsplitn(2, '.');\n    //~^ manual_split_once\n    let r = iter.next().unwrap();\n    let l = iter.next().unwrap();\n\n    let mut iter = \"a.b.c\".rsplitn(2, '.');\n    //~^ manual_split_once\n    let r = iter.next()?;\n    let l = iter.next()?;\n\n    // could lint, currently doesn't\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let other = 1;\n    let l = iter.next()?;\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let mut mut_binding = iter.next()?;\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let tuple = (iter.next()?, iter.next()?);\n\n    // should not lint\n\n    let mut missing_unwrap = \"a.b.c\".splitn(2, '.');\n    let l = missing_unwrap.next();\n    let r = missing_unwrap.next();\n\n    let mut mixed_unrap = \"a.b.c\".splitn(2, '.');\n    let unwrap = mixed_unrap.next().unwrap();\n    let question_mark = mixed_unrap.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let same_name = iter.next()?;\n    let same_name = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let shadows_existing = \"d\";\n    let shadows_existing = iter.next()?;\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let becomes_shadowed = iter.next()?;\n    let becomes_shadowed = \"d\";\n    let r = iter.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let l = iter.next()?;\n    let r = iter.next()?;\n    let third_usage = iter.next()?;\n\n    let mut n_three = \"a.b.c\".splitn(3, '.');\n    let l = n_three.next()?;\n    let r = n_three.next()?;\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    {\n        let in_block = iter.next()?;\n    }\n    let r = iter.next()?;\n\n    let mut lacks_binding = \"a.b.c\".splitn(2, '.');\n    let _ = lacks_binding.next()?;\n    let r = lacks_binding.next()?;\n\n    let mut mapped = \"a.b.c\".splitn(2, '.').map(|_| \"~\");\n    let l = iter.next()?;\n    let r = iter.next()?;\n\n    let mut assigned = \"\";\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let l = iter.next()?;\n    assigned = iter.next()?;\n\n    None\n}\n\n#[clippy::msrv = \"1.51\"]\nfn _msrv_1_51() {\n    // `str::split_once` was stabilized in 1.52. Do not lint this\n    let _ = \"key=value\".splitn(2, '=').nth(1).unwrap();\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    let a = iter.next().unwrap();\n    let b = iter.next().unwrap();\n}\n\n#[clippy::msrv = \"1.52\"]\nfn _msrv_1_52() {\n    let _ = \"key=value\".splitn(2, '=').nth(1).unwrap();\n    //~^ manual_split_once\n\n    let mut iter = \"a.b.c\".splitn(2, '.');\n    //~^ manual_split_once\n    let a = iter.next().unwrap();\n    let b = iter.next().unwrap();\n}\n"
  },
  {
    "path": "tests/ui/manual_split_once.stderr",
    "content": "error: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:11:13\n   |\nLL |     let _ = \"key=value\".splitn(2, '=').nth(1).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"key=value\".split_once('=').unwrap().1`\n   |\n   = note: `-D clippy::manual-split-once` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_split_once)]`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:13:13\n   |\nLL |     let _ = \"key=value\".splitn(2, '=').skip(1).next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"key=value\".split_once('=').unwrap().1`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:15:18\n   |\nLL |     let (_, _) = \"key=value\".splitn(2, '=').next_tuple().unwrap();\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"key=value\".split_once('=')`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:19:13\n   |\nLL |     let _ = s.splitn(2, '=').nth(1).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:23:13\n   |\nLL |     let _ = s.splitn(2, '=').nth(1).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:27:13\n   |\nLL |     let _ = s.splitn(2, '=').skip(1).next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:31:17\n   |\nLL |         let _ = s.splitn(2, '=').nth(1)?;\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:33:17\n   |\nLL |         let _ = s.splitn(2, '=').skip(1).next()?;\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`\n\nerror: manual implementation of `rsplit_once`\n  --> tests/ui/manual_split_once.rs:35:17\n   |\nLL |         let _ = s.rsplitn(2, '=').nth(1)?;\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`\n\nerror: manual implementation of `rsplit_once`\n  --> tests/ui/manual_split_once.rs:37:17\n   |\nLL |         let _ = s.rsplitn(2, '=').skip(1).next()?;\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`\n\nerror: manual implementation of `rsplit_once`\n  --> tests/ui/manual_split_once.rs:46:13\n   |\nLL |     let _ = \"key=value\".rsplitn(2, '=').nth(1).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"key=value\".rsplit_once('=').unwrap().0`\n\nerror: manual implementation of `rsplit_once`\n  --> tests/ui/manual_split_once.rs:48:18\n   |\nLL |     let (_, _) = \"key=value\".rsplitn(2, '=').next_tuple().unwrap();\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"key=value\".rsplit_once('=').map(|(x, y)| (y, x))`\n\nerror: manual implementation of `rsplit_once`\n  --> tests/ui/manual_split_once.rs:50:13\n   |\nLL |     let _ = s.rsplitn(2, '=').nth(1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=').map(|x| x.0)`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:55:5\n   |\nLL |     let mut iter = \"a.b.c\".splitn(2, '.');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |     let l = iter.next().unwrap();\n   |     ----------------------------- first usage here\nLL |     let r = iter.next().unwrap();\n   |     ----------------------------- second usage here\n   |\nhelp: replace with `split_once`\n   |\nLL ~     let (l, r) = \"a.b.c\".split_once('.').unwrap();\nLL |\nLL ~     \nLL ~     \n   |\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:60:5\n   |\nLL |     let mut iter = \"a.b.c\".splitn(2, '.');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |     let l = iter.next()?;\n   |     --------------------- first usage here\nLL |     let r = iter.next()?;\n   |     --------------------- second usage here\n   |\nhelp: replace with `split_once`\n   |\nLL ~     let (l, r) = \"a.b.c\".split_once('.')?;\nLL |\nLL ~     \nLL ~     \n   |\n\nerror: manual implementation of `rsplit_once`\n  --> tests/ui/manual_split_once.rs:65:5\n   |\nLL |     let mut iter = \"a.b.c\".rsplitn(2, '.');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |     let r = iter.next().unwrap();\n   |     ----------------------------- first usage here\nLL |     let l = iter.next().unwrap();\n   |     ----------------------------- second usage here\n   |\nhelp: replace with `rsplit_once`\n   |\nLL ~     let (l, r) = \"a.b.c\".rsplit_once('.').unwrap();\nLL |\nLL ~     \nLL ~     \n   |\n\nerror: manual implementation of `rsplit_once`\n  --> tests/ui/manual_split_once.rs:70:5\n   |\nLL |     let mut iter = \"a.b.c\".rsplitn(2, '.');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |     let r = iter.next()?;\n   |     --------------------- first usage here\nLL |     let l = iter.next()?;\n   |     --------------------- second usage here\n   |\nhelp: replace with `rsplit_once`\n   |\nLL ~     let (l, r) = \"a.b.c\".rsplit_once('.')?;\nLL |\nLL ~     \nLL ~     \n   |\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:156:13\n   |\nLL |     let _ = \"key=value\".splitn(2, '=').nth(1).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"key=value\".split_once('=').unwrap().1`\n\nerror: manual implementation of `split_once`\n  --> tests/ui/manual_split_once.rs:159:5\n   |\nLL |     let mut iter = \"a.b.c\".splitn(2, '.');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |     let a = iter.next().unwrap();\n   |     ----------------------------- first usage here\nLL |     let b = iter.next().unwrap();\n   |     ----------------------------- second usage here\n   |\nhelp: replace with `split_once`\n   |\nLL ~     let (a, b) = \"a.b.c\".split_once('.').unwrap();\nLL |\nLL ~     \nLL ~     \n   |\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_str_repeat.fixed",
    "content": "#![allow(non_local_definitions, clippy::manual_repeat_n)]\n#![warn(clippy::manual_str_repeat)]\n\nuse std::borrow::Cow;\nuse std::iter::repeat;\n\nfn main() {\n    let _: String = \"test\".repeat(10);\n    //~^ manual_str_repeat\n    let _: String = \"x\".repeat(10);\n    //~^ manual_str_repeat\n    let _: String = \"'\".repeat(10);\n    //~^ manual_str_repeat\n    let _: String = \"\\\"\".repeat(10);\n    //~^ manual_str_repeat\n\n    let x = \"test\";\n    let count = 10;\n    let _ = x.repeat(count + 2);\n    //~^ manual_str_repeat\n\n    macro_rules! m {\n        ($e:expr) => {{ $e }};\n    }\n    // FIXME: macro args are fine\n    let _: String = repeat(m!(\"test\")).take(m!(count)).collect();\n\n    let x = &x;\n    let _: String = (*x).repeat(count);\n    //~^ manual_str_repeat\n\n    macro_rules! repeat_m {\n        ($e:expr) => {{ repeat($e) }};\n    }\n    // Don't lint, repeat is from a macro.\n    let _: String = repeat_m!(\"test\").take(count).collect();\n\n    let x: Box<str> = Box::from(\"test\");\n    let _: String = x.repeat(count);\n    //~^ manual_str_repeat\n\n    #[derive(Clone)]\n    struct S;\n    impl FromIterator<Box<S>> for String {\n        fn from_iter<T: IntoIterator<Item = Box<S>>>(_: T) -> Self {\n            Self::new()\n        }\n    }\n    // Don't lint, wrong box type\n    let _: String = repeat(Box::new(S)).take(count).collect();\n\n    let _: String = Cow::Borrowed(\"test\").repeat(count);\n    //~^ manual_str_repeat\n\n    let x = \"x\".to_owned();\n    let _: String = x.repeat(count);\n    //~^ manual_str_repeat\n\n    let x = 'x';\n    // Don't lint, not char literal\n    let _: String = repeat(x).take(count).collect();\n}\n\n#[clippy::msrv = \"1.15\"]\nfn _msrv_1_15() {\n    // `str::repeat` was stabilized in 1.16. Do not lint this\n    let _: String = std::iter::repeat(\"test\").take(10).collect();\n}\n\n#[clippy::msrv = \"1.16\"]\nfn _msrv_1_16() {\n    let _: String = \"test\".repeat(10);\n    //~^ manual_str_repeat\n}\n"
  },
  {
    "path": "tests/ui/manual_str_repeat.rs",
    "content": "#![allow(non_local_definitions, clippy::manual_repeat_n)]\n#![warn(clippy::manual_str_repeat)]\n\nuse std::borrow::Cow;\nuse std::iter::repeat;\n\nfn main() {\n    let _: String = std::iter::repeat(\"test\").take(10).collect();\n    //~^ manual_str_repeat\n    let _: String = std::iter::repeat('x').take(10).collect();\n    //~^ manual_str_repeat\n    let _: String = std::iter::repeat('\\'').take(10).collect();\n    //~^ manual_str_repeat\n    let _: String = std::iter::repeat('\"').take(10).collect();\n    //~^ manual_str_repeat\n\n    let x = \"test\";\n    let count = 10;\n    let _ = repeat(x).take(count + 2).collect::<String>();\n    //~^ manual_str_repeat\n\n    macro_rules! m {\n        ($e:expr) => {{ $e }};\n    }\n    // FIXME: macro args are fine\n    let _: String = repeat(m!(\"test\")).take(m!(count)).collect();\n\n    let x = &x;\n    let _: String = repeat(*x).take(count).collect();\n    //~^ manual_str_repeat\n\n    macro_rules! repeat_m {\n        ($e:expr) => {{ repeat($e) }};\n    }\n    // Don't lint, repeat is from a macro.\n    let _: String = repeat_m!(\"test\").take(count).collect();\n\n    let x: Box<str> = Box::from(\"test\");\n    let _: String = repeat(x).take(count).collect();\n    //~^ manual_str_repeat\n\n    #[derive(Clone)]\n    struct S;\n    impl FromIterator<Box<S>> for String {\n        fn from_iter<T: IntoIterator<Item = Box<S>>>(_: T) -> Self {\n            Self::new()\n        }\n    }\n    // Don't lint, wrong box type\n    let _: String = repeat(Box::new(S)).take(count).collect();\n\n    let _: String = repeat(Cow::Borrowed(\"test\")).take(count).collect();\n    //~^ manual_str_repeat\n\n    let x = \"x\".to_owned();\n    let _: String = repeat(x).take(count).collect();\n    //~^ manual_str_repeat\n\n    let x = 'x';\n    // Don't lint, not char literal\n    let _: String = repeat(x).take(count).collect();\n}\n\n#[clippy::msrv = \"1.15\"]\nfn _msrv_1_15() {\n    // `str::repeat` was stabilized in 1.16. Do not lint this\n    let _: String = std::iter::repeat(\"test\").take(10).collect();\n}\n\n#[clippy::msrv = \"1.16\"]\nfn _msrv_1_16() {\n    let _: String = std::iter::repeat(\"test\").take(10).collect();\n    //~^ manual_str_repeat\n}\n"
  },
  {
    "path": "tests/ui/manual_str_repeat.stderr",
    "content": "error: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:8:21\n   |\nLL |     let _: String = std::iter::repeat(\"test\").take(10).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"test\".repeat(10)`\n   |\n   = note: `-D clippy::manual-str-repeat` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_str_repeat)]`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:10:21\n   |\nLL |     let _: String = std::iter::repeat('x').take(10).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"x\".repeat(10)`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:12:21\n   |\nLL |     let _: String = std::iter::repeat('\\'').take(10).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"'\".repeat(10)`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:14:21\n   |\nLL |     let _: String = std::iter::repeat('\"').take(10).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"\\\"\".repeat(10)`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:19:13\n   |\nLL |     let _ = repeat(x).take(count + 2).collect::<String>();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count + 2)`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:29:21\n   |\nLL |     let _: String = repeat(*x).take(count).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*x).repeat(count)`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:39:21\n   |\nLL |     let _: String = repeat(x).take(count).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:52:21\n   |\nLL |     let _: String = repeat(Cow::Borrowed(\"test\")).take(count).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Cow::Borrowed(\"test\").repeat(count)`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:56:21\n   |\nLL |     let _: String = repeat(x).take(count).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.repeat(count)`\n\nerror: manual implementation of `str::repeat` using iterators\n  --> tests/ui/manual_str_repeat.rs:72:21\n   |\nLL |     let _: String = std::iter::repeat(\"test\").take(10).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"test\".repeat(10)`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_string_new.fixed",
    "content": "#![warn(clippy::manual_string_new)]\n#![allow(clippy::unnecessary_fallible_conversions)]\n\nmacro_rules! create_strings_from_macro {\n    // When inside a macro, nothing should warn to prevent false positives.\n    ($some_str:expr) => {\n        let _: String = $some_str.into();\n        let _ = $some_str.to_string();\n    };\n}\n\nfn main() {\n    // Method calls\n    let _ = String::new();\n    //~^ manual_string_new\n    let _ = \"no warning\".to_string();\n\n    let _ = String::new();\n    //~^ manual_string_new\n    let _ = \"no warning\".to_owned();\n\n    let _: String = String::new();\n    //~^ manual_string_new\n    let _: String = \"no warning\".into();\n\n    let _: SomeOtherStruct = \"no warning\".into();\n    let _: SomeOtherStruct = \"\".into(); // No warning too. We are not converting into String.\n\n    // Calls\n    let _ = String::new();\n    //~^ manual_string_new\n    let _ = String::new();\n    //~^ manual_string_new\n    let _ = String::from(\"no warning\");\n    let _ = SomeOtherStruct::from(\"no warning\");\n    let _ = SomeOtherStruct::from(\"\"); // Again: no warning.\n\n    let _ = String::new();\n    //~^ manual_string_new\n    let _ = String::try_from(\"no warning\").unwrap();\n    let _ = String::try_from(\"no warning\").expect(\"this should not warn\");\n    let _ = SomeOtherStruct::try_from(\"no warning\").unwrap();\n    let _ = SomeOtherStruct::try_from(\"\").unwrap(); // Again: no warning.\n\n    let _: String = String::new();\n    //~^ manual_string_new\n    let _: String = From::from(\"no warning\");\n    let _: SomeOtherStruct = From::from(\"no warning\");\n    let _: SomeOtherStruct = From::from(\"\"); // Again: no warning.\n\n    let _: String = String::new();\n    //~^ manual_string_new\n    let _: String = TryFrom::try_from(\"no warning\").unwrap();\n    let _: String = TryFrom::try_from(\"no warning\").expect(\"this should not warn\");\n    let _: String = String::new();\n    //~^ manual_string_new\n    let _: SomeOtherStruct = TryFrom::try_from(\"no_warning\").unwrap();\n    let _: SomeOtherStruct = TryFrom::try_from(\"\").unwrap(); // Again: no warning.\n\n    // Macros (never warn)\n    create_strings_from_macro!(\"\");\n    create_strings_from_macro!(\"Hey\");\n}\n\nstruct SomeOtherStruct {}\n\nimpl From<&str> for SomeOtherStruct {\n    fn from(_value: &str) -> Self {\n        Self {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_string_new.rs",
    "content": "#![warn(clippy::manual_string_new)]\n#![allow(clippy::unnecessary_fallible_conversions)]\n\nmacro_rules! create_strings_from_macro {\n    // When inside a macro, nothing should warn to prevent false positives.\n    ($some_str:expr) => {\n        let _: String = $some_str.into();\n        let _ = $some_str.to_string();\n    };\n}\n\nfn main() {\n    // Method calls\n    let _ = \"\".to_string();\n    //~^ manual_string_new\n    let _ = \"no warning\".to_string();\n\n    let _ = \"\".to_owned();\n    //~^ manual_string_new\n    let _ = \"no warning\".to_owned();\n\n    let _: String = \"\".into();\n    //~^ manual_string_new\n    let _: String = \"no warning\".into();\n\n    let _: SomeOtherStruct = \"no warning\".into();\n    let _: SomeOtherStruct = \"\".into(); // No warning too. We are not converting into String.\n\n    // Calls\n    let _ = String::from(\"\");\n    //~^ manual_string_new\n    let _ = <String>::from(\"\");\n    //~^ manual_string_new\n    let _ = String::from(\"no warning\");\n    let _ = SomeOtherStruct::from(\"no warning\");\n    let _ = SomeOtherStruct::from(\"\"); // Again: no warning.\n\n    let _ = String::try_from(\"\").unwrap();\n    //~^ manual_string_new\n    let _ = String::try_from(\"no warning\").unwrap();\n    let _ = String::try_from(\"no warning\").expect(\"this should not warn\");\n    let _ = SomeOtherStruct::try_from(\"no warning\").unwrap();\n    let _ = SomeOtherStruct::try_from(\"\").unwrap(); // Again: no warning.\n\n    let _: String = From::from(\"\");\n    //~^ manual_string_new\n    let _: String = From::from(\"no warning\");\n    let _: SomeOtherStruct = From::from(\"no warning\");\n    let _: SomeOtherStruct = From::from(\"\"); // Again: no warning.\n\n    let _: String = TryFrom::try_from(\"\").unwrap();\n    //~^ manual_string_new\n    let _: String = TryFrom::try_from(\"no warning\").unwrap();\n    let _: String = TryFrom::try_from(\"no warning\").expect(\"this should not warn\");\n    let _: String = TryFrom::try_from(\"\").expect(\"this should warn\");\n    //~^ manual_string_new\n    let _: SomeOtherStruct = TryFrom::try_from(\"no_warning\").unwrap();\n    let _: SomeOtherStruct = TryFrom::try_from(\"\").unwrap(); // Again: no warning.\n\n    // Macros (never warn)\n    create_strings_from_macro!(\"\");\n    create_strings_from_macro!(\"Hey\");\n}\n\nstruct SomeOtherStruct {}\n\nimpl From<&str> for SomeOtherStruct {\n    fn from(_value: &str) -> Self {\n        Self {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_string_new.stderr",
    "content": "error: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:14:13\n   |\nLL |     let _ = \"\".to_string();\n   |             ^^^^^^^^^^^^^^ help: consider using: `String::new()`\n   |\n   = note: `-D clippy::manual-string-new` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_string_new)]`\n\nerror: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:18:13\n   |\nLL |     let _ = \"\".to_owned();\n   |             ^^^^^^^^^^^^^ help: consider using: `String::new()`\n\nerror: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:22:21\n   |\nLL |     let _: String = \"\".into();\n   |                     ^^^^^^^^^ help: consider using: `String::new()`\n\nerror: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:30:13\n   |\nLL |     let _ = String::from(\"\");\n   |             ^^^^^^^^^^^^^^^^ help: consider using: `String::new()`\n\nerror: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:32:13\n   |\nLL |     let _ = <String>::from(\"\");\n   |             ^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`\n\nerror: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:38:13\n   |\nLL |     let _ = String::try_from(\"\").unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`\n\nerror: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:45:21\n   |\nLL |     let _: String = From::from(\"\");\n   |                     ^^^^^^^^^^^^^^ help: consider using: `String::new()`\n\nerror: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:51:21\n   |\nLL |     let _: String = TryFrom::try_from(\"\").unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`\n\nerror: empty String is being created manually\n  --> tests/ui/manual_string_new.rs:55:21\n   |\nLL |     let _: String = TryFrom::try_from(\"\").expect(\"this should warn\");\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::new()`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_strip.rs",
    "content": "#![warn(clippy::manual_strip)]\n//@no-rustfix\nfn main() {\n    let s = \"abc\";\n\n    if s.starts_with(\"ab\") {\n        str::to_string(&s[\"ab\".len()..]);\n        //~^ manual_strip\n\n        s[\"ab\".len()..].to_string();\n\n        str::to_string(&s[2..]);\n        s[2..].to_string();\n    }\n\n    if s.ends_with(\"bc\") {\n        str::to_string(&s[..s.len() - \"bc\".len()]);\n        //~^ manual_strip\n\n        s[..s.len() - \"bc\".len()].to_string();\n\n        str::to_string(&s[..s.len() - 2]);\n        s[..s.len() - 2].to_string();\n    }\n\n    // Character patterns\n    if s.starts_with('a') {\n        str::to_string(&s[1..]);\n        //~^ manual_strip\n\n        s[1..].to_string();\n    }\n\n    // Variable prefix\n    let prefix = \"ab\";\n    if s.starts_with(prefix) {\n        str::to_string(&s[prefix.len()..]);\n        //~^ manual_strip\n    }\n\n    // Constant prefix\n    const PREFIX: &str = \"ab\";\n    if s.starts_with(PREFIX) {\n        str::to_string(&s[PREFIX.len()..]);\n        //~^ manual_strip\n\n        str::to_string(&s[2..]);\n    }\n\n    // Constant target\n    const TARGET: &str = \"abc\";\n    if TARGET.starts_with(prefix) {\n        str::to_string(&TARGET[prefix.len()..]);\n        //~^ manual_strip\n    }\n\n    // String target - not mutated.\n    let s1: String = \"abc\".into();\n    if s1.starts_with(\"ab\") {\n        s1[2..].to_uppercase();\n        //~^ manual_strip\n    }\n\n    // String target - mutated. (Don't lint.)\n    let mut s2: String = \"abc\".into();\n    if s2.starts_with(\"ab\") {\n        s2.push('d');\n        s2[2..].to_uppercase();\n    }\n\n    // Target not stripped. (Don't lint.)\n    let s3 = String::from(\"abcd\");\n    let s4 = String::from(\"efgh\");\n    if s3.starts_with(\"ab\") {\n        s4[2..].to_string();\n    }\n\n    // Don't propose to reuse the `stripped` identifier as it is overridden\n    if s.starts_with(\"ab\") {\n        let stripped = &s[\"ab\".len()..];\n        //~^ ERROR: stripping a prefix manually\n        let stripped = format!(\"{stripped}-\");\n        println!(\"{stripped}{}\", &s[\"ab\".len()..]);\n    }\n\n    // Don't propose to reuse the `stripped` identifier as it is mutable\n    if s.starts_with(\"ab\") {\n        let mut stripped = &s[\"ab\".len()..];\n        //~^ ERROR: stripping a prefix manually\n        stripped = \"\";\n        let stripped = format!(\"{stripped}-\");\n        println!(\"{stripped}{}\", &s[\"ab\".len()..]);\n    }\n}\n\n#[clippy::msrv = \"1.44\"]\nfn msrv_1_44() {\n    let s = \"abc\";\n    if s.starts_with('a') {\n        s[1..].to_string();\n    }\n}\n\n#[clippy::msrv = \"1.45\"]\nfn msrv_1_45() {\n    let s = \"abc\";\n    if s.starts_with('a') {\n        s[1..].to_string();\n        //~^ manual_strip\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_strip.stderr",
    "content": "error: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:7:24\n   |\nLL |         str::to_string(&s[\"ab\".len()..]);\n   |                        ^^^^^^^^^^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:6:5\n   |\nLL |     if s.starts_with(\"ab\") {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::manual-strip` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_strip)]`\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = s.strip_prefix(\"ab\") {\nLL ~         str::to_string(<stripped>);\nLL |\nLL |\nLL ~         <stripped>.to_string();\nLL |\nLL ~         str::to_string(<stripped>);\nLL ~         <stripped>.to_string();\n   |\n\nerror: stripping a suffix manually\n  --> tests/ui/manual_strip.rs:17:24\n   |\nLL |         str::to_string(&s[..s.len() - \"bc\".len()]);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the suffix was tested here\n  --> tests/ui/manual_strip.rs:16:5\n   |\nLL |     if s.ends_with(\"bc\") {\n   |     ^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_suffix` method\n   |\nLL ~     if let Some(<stripped>) = s.strip_suffix(\"bc\") {\nLL ~         str::to_string(<stripped>);\nLL |\nLL |\nLL ~         <stripped>.to_string();\nLL |\nLL ~         str::to_string(<stripped>);\nLL ~         <stripped>.to_string();\n   |\n\nerror: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:28:24\n   |\nLL |         str::to_string(&s[1..]);\n   |                        ^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:27:5\n   |\nLL |     if s.starts_with('a') {\n   |     ^^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = s.strip_prefix('a') {\nLL ~         str::to_string(<stripped>);\nLL |\nLL |\nLL ~         <stripped>.to_string();\n   |\n\nerror: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:37:24\n   |\nLL |         str::to_string(&s[prefix.len()..]);\n   |                        ^^^^^^^^^^^^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:36:5\n   |\nLL |     if s.starts_with(prefix) {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = s.strip_prefix(prefix) {\nLL ~         str::to_string(<stripped>);\n   |\n\nerror: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:44:24\n   |\nLL |         str::to_string(&s[PREFIX.len()..]);\n   |                        ^^^^^^^^^^^^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:43:5\n   |\nLL |     if s.starts_with(PREFIX) {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = s.strip_prefix(PREFIX) {\nLL ~         str::to_string(<stripped>);\n   |\n\nerror: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:53:24\n   |\nLL |         str::to_string(&TARGET[prefix.len()..]);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:52:5\n   |\nLL |     if TARGET.starts_with(prefix) {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = TARGET.strip_prefix(prefix) {\nLL ~         str::to_string(<stripped>);\n   |\n\nerror: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:60:9\n   |\nLL |         s1[2..].to_uppercase();\n   |         ^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:59:5\n   |\nLL |     if s1.starts_with(\"ab\") {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = s1.strip_prefix(\"ab\") {\nLL ~         <stripped>.to_uppercase();\n   |\n\nerror: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:80:24\n   |\nLL |         let stripped = &s[\"ab\".len()..];\n   |                        ^^^^^^^^^^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:79:5\n   |\nLL |     if s.starts_with(\"ab\") {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = s.strip_prefix(\"ab\") {\nLL ~         let stripped = <stripped>;\nLL |\nLL |         let stripped = format!(\"{stripped}-\");\nLL ~         println!(\"{stripped}{}\", <stripped>);\n   |\n\nerror: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:88:28\n   |\nLL |         let mut stripped = &s[\"ab\".len()..];\n   |                            ^^^^^^^^^^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:87:5\n   |\nLL |     if s.starts_with(\"ab\") {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = s.strip_prefix(\"ab\") {\nLL ~         let mut stripped = <stripped>;\nLL |\nLL |         stripped = \"\";\nLL |         let stripped = format!(\"{stripped}-\");\nLL ~         println!(\"{stripped}{}\", <stripped>);\n   |\n\nerror: stripping a prefix manually\n  --> tests/ui/manual_strip.rs:108:9\n   |\nLL |         s[1..].to_string();\n   |         ^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip.rs:107:5\n   |\nLL |     if s.starts_with('a') {\n   |     ^^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(<stripped>) = s.strip_prefix('a') {\nLL ~         <stripped>.to_string();\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_strip_fixable.fixed",
    "content": "#![warn(clippy::manual_strip)]\n#![allow(clippy::uninlined_format_args)]\n\nfn main() {\n    let s = \"abc\";\n\n    if let Some(stripped) = s.strip_prefix(\"ab\") {\n        //~^ ERROR: stripping a prefix manually\n        println!(\"{stripped}{}\", stripped);\n    }\n\n    if let Some(stripped) = s.strip_suffix(\"bc\") {\n        //~^ ERROR: stripping a suffix manually\n        println!(\"{stripped}{}\", stripped);\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_strip_fixable.rs",
    "content": "#![warn(clippy::manual_strip)]\n#![allow(clippy::uninlined_format_args)]\n\nfn main() {\n    let s = \"abc\";\n\n    if s.starts_with(\"ab\") {\n        let stripped = &s[\"ab\".len()..];\n        //~^ ERROR: stripping a prefix manually\n        println!(\"{stripped}{}\", &s[\"ab\".len()..]);\n    }\n\n    if s.ends_with(\"bc\") {\n        let stripped = &s[..s.len() - \"bc\".len()];\n        //~^ ERROR: stripping a suffix manually\n        println!(\"{stripped}{}\", &s[..s.len() - \"bc\".len()]);\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_strip_fixable.stderr",
    "content": "error: stripping a prefix manually\n  --> tests/ui/manual_strip_fixable.rs:8:24\n   |\nLL |         let stripped = &s[\"ab\".len()..];\n   |                        ^^^^^^^^^^^^^^^^\n   |\nnote: the prefix was tested here\n  --> tests/ui/manual_strip_fixable.rs:7:5\n   |\nLL |     if s.starts_with(\"ab\") {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::manual-strip` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_strip)]`\nhelp: try using the `strip_prefix` method\n   |\nLL ~     if let Some(stripped) = s.strip_prefix(\"ab\") {\nLL ~\nLL ~         println!(\"{stripped}{}\", stripped);\n   |\n\nerror: stripping a suffix manually\n  --> tests/ui/manual_strip_fixable.rs:14:24\n   |\nLL |         let stripped = &s[..s.len() - \"bc\".len()];\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the suffix was tested here\n  --> tests/ui/manual_strip_fixable.rs:13:5\n   |\nLL |     if s.ends_with(\"bc\") {\n   |     ^^^^^^^^^^^^^^^^^^^^^\nhelp: try using the `strip_suffix` method\n   |\nLL ~     if let Some(stripped) = s.strip_suffix(\"bc\") {\nLL ~\nLL ~         println!(\"{stripped}{}\", stripped);\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_swap_auto_fix.fixed",
    "content": "#![warn(clippy::manual_swap)]\n#![no_main]\n\nfn swap1() {\n    let mut v = [3, 2, 1, 0];\n    let index = v[0];\n    v.swap(0, index);\n}\n\nfn swap2() {\n    let mut v = [3, 2, 1, 0];\n    let tmp = v[0];\n    v.swap(0, 1);\n    // check not found in this scope.\n    let _ = tmp;\n}\n\nfn swap3() {\n    let mut v = [3, 2];\n    let i1 = 0;\n    let i2 = 1;\n    v.swap(i1, i2);\n}\n\nfn swap4() {\n    let mut v = [3, 2, 1];\n    let i1 = 0;\n    let i2 = 1;\n    v.swap(i1, i2 + 1);\n}\n\nfn swap5() {\n    let mut v = [0, 1, 2, 3];\n    let i1 = 0;\n    let i2 = 1;\n    v.swap(i1, i2 + 1);\n}\n\nfn swap6() {\n    let mut v = [0, 1, 2, 3];\n    let index = v[0];\n    v.swap(0, index + 1);\n}\n\nfn swap7() {\n    let mut v = [0, 1, 2, 3];\n    let i1 = 0;\n    let i2 = 6;\n    v.swap(i1 * 3, i2 / 2);\n}\n\nfn swap8() {\n    let mut v = [1, 2, 3, 4];\n    let i1 = 1;\n    let i2 = 1;\n    v.swap(i1 + i2, i2);\n}\n\nfn issue_14931() {\n    let mut v = [1, 2, 3, 4];\n\n    let mut i1 = 0;\n    for i2 in 0..4 {\n        v.swap(i1, i2);\n\n        i1 += 2;\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_swap_auto_fix.rs",
    "content": "#![warn(clippy::manual_swap)]\n#![no_main]\n\nfn swap1() {\n    let mut v = [3, 2, 1, 0];\n    let index = v[0];\n    //~^ manual_swap\n\n    v[0] = v[index];\n    v[index] = index;\n}\n\nfn swap2() {\n    let mut v = [3, 2, 1, 0];\n    let tmp = v[0];\n    //~^ manual_swap\n    v[0] = v[1];\n    v[1] = tmp;\n    // check not found in this scope.\n    let _ = tmp;\n}\n\nfn swap3() {\n    let mut v = [3, 2];\n    let i1 = 0;\n    let i2 = 1;\n    let temp = v[i1];\n    //~^ manual_swap\n    v[i1] = v[i2];\n    v[i2] = temp;\n}\n\nfn swap4() {\n    let mut v = [3, 2, 1];\n    let i1 = 0;\n    let i2 = 1;\n    let temp = v[i1];\n    //~^ manual_swap\n    v[i1] = v[i2 + 1];\n    v[i2 + 1] = temp;\n}\n\nfn swap5() {\n    let mut v = [0, 1, 2, 3];\n    let i1 = 0;\n    let i2 = 1;\n    let temp = v[i1];\n    //~^ manual_swap\n    v[i1] = v[i2 + 1];\n    v[i2 + 1] = temp;\n}\n\nfn swap6() {\n    let mut v = [0, 1, 2, 3];\n    let index = v[0];\n    //~^ manual_swap\n\n    v[0] = v[index + 1];\n    v[index + 1] = index;\n}\n\nfn swap7() {\n    let mut v = [0, 1, 2, 3];\n    let i1 = 0;\n    let i2 = 6;\n    let tmp = v[i1 * 3];\n    //~^ manual_swap\n    v[i1 * 3] = v[i2 / 2];\n    v[i2 / 2] = tmp;\n}\n\nfn swap8() {\n    let mut v = [1, 2, 3, 4];\n    let i1 = 1;\n    let i2 = 1;\n    let tmp = v[i1 + i2];\n    //~^ manual_swap\n    v[i1 + i2] = v[i2];\n    v[i2] = tmp;\n}\n\nfn issue_14931() {\n    let mut v = [1, 2, 3, 4];\n\n    let mut i1 = 0;\n    for i2 in 0..4 {\n        let tmp = v[i1];\n        //~^ manual_swap\n        v[i1] = v[i2];\n        v[i2] = tmp;\n\n        i1 += 2;\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_swap_auto_fix.stderr",
    "content": "error: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:6:5\n   |\nLL | /     let index = v[0];\nLL | |\nLL | |\nLL | |     v[0] = v[index];\nLL | |     v[index] = index;\n   | |_____________________^\n   |\n   = note: `-D clippy::manual-swap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_swap)]`\nhelp: try\n   |\nLL ~     let index = v[0];\nLL +     v.swap(0, index);\n   |\n\nerror: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:15:5\n   |\nLL | /     let tmp = v[0];\nLL | |\nLL | |     v[0] = v[1];\nLL | |     v[1] = tmp;\n   | |_______________^\n   |\nhelp: try\n   |\nLL ~     let tmp = v[0];\nLL +     v.swap(0, 1);\n   |\n\nerror: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:27:5\n   |\nLL | /     let temp = v[i1];\nLL | |\nLL | |     v[i1] = v[i2];\nLL | |     v[i2] = temp;\n   | |_________________^ help: try: `v.swap(i1, i2);`\n\nerror: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:37:5\n   |\nLL | /     let temp = v[i1];\nLL | |\nLL | |     v[i1] = v[i2 + 1];\nLL | |     v[i2 + 1] = temp;\n   | |_____________________^ help: try: `v.swap(i1, i2 + 1);`\n\nerror: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:47:5\n   |\nLL | /     let temp = v[i1];\nLL | |\nLL | |     v[i1] = v[i2 + 1];\nLL | |     v[i2 + 1] = temp;\n   | |_____________________^ help: try: `v.swap(i1, i2 + 1);`\n\nerror: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:55:5\n   |\nLL | /     let index = v[0];\nLL | |\nLL | |\nLL | |     v[0] = v[index + 1];\nLL | |     v[index + 1] = index;\n   | |_________________________^\n   |\nhelp: try\n   |\nLL ~     let index = v[0];\nLL +     v.swap(0, index + 1);\n   |\n\nerror: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:66:5\n   |\nLL | /     let tmp = v[i1 * 3];\nLL | |\nLL | |     v[i1 * 3] = v[i2 / 2];\nLL | |     v[i2 / 2] = tmp;\n   | |____________________^ help: try: `v.swap(i1 * 3, i2 / 2);`\n\nerror: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:76:5\n   |\nLL | /     let tmp = v[i1 + i2];\nLL | |\nLL | |     v[i1 + i2] = v[i2];\nLL | |     v[i2] = tmp;\n   | |________________^ help: try: `v.swap(i1 + i2, i2);`\n\nerror: this looks like you are swapping elements of `v` manually\n  --> tests/ui/manual_swap_auto_fix.rs:87:9\n   |\nLL | /         let tmp = v[i1];\nLL | |\nLL | |         v[i1] = v[i2];\nLL | |         v[i2] = tmp;\n   | |____________________^ help: try: `v.swap(i1, i2);`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_take.fixed",
    "content": "#![warn(clippy::manual_take)]\n\nfn main() {\n    let mut x = true;\n    let mut y = false;\n\n    let _lint_negated = !std::mem::take(&mut x);\n\n    let _ = if x {\n        y = false;\n        true\n    } else {\n        false\n    };\n\n    let _ = if x {\n        x = true;\n        true\n    } else {\n        false\n    };\n\n    let _ = if x {\n        x = false;\n        y = true;\n        false\n    } else {\n        true\n    };\n\n    let _ = if x {\n        x = false;\n        false\n    } else {\n        y = true;\n        true\n    };\n}\n\n#[clippy::msrv = \"1.39.0\"]\nfn msrv_1_39() -> bool {\n    let mut x = true;\n    if x {\n        x = false;\n        true\n    } else {\n        false\n    }\n}\n\n#[clippy::msrv = \"1.40.0\"]\nfn msrv_1_40() -> bool {\n    let mut x = true;\n    std::mem::take(&mut x)\n}\n"
  },
  {
    "path": "tests/ui/manual_take.rs",
    "content": "#![warn(clippy::manual_take)]\n\nfn main() {\n    let mut x = true;\n    let mut y = false;\n\n    let _lint_negated = if x {\n        //~^ manual_take\n        x = false;\n        false\n    } else {\n        true\n    };\n\n    let _ = if x {\n        y = false;\n        true\n    } else {\n        false\n    };\n\n    let _ = if x {\n        x = true;\n        true\n    } else {\n        false\n    };\n\n    let _ = if x {\n        x = false;\n        y = true;\n        false\n    } else {\n        true\n    };\n\n    let _ = if x {\n        x = false;\n        false\n    } else {\n        y = true;\n        true\n    };\n}\n\n#[clippy::msrv = \"1.39.0\"]\nfn msrv_1_39() -> bool {\n    let mut x = true;\n    if x {\n        x = false;\n        true\n    } else {\n        false\n    }\n}\n\n#[clippy::msrv = \"1.40.0\"]\nfn msrv_1_40() -> bool {\n    let mut x = true;\n    if x {\n        //~^ manual_take\n        x = false;\n        true\n    } else {\n        false\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_take.stderr",
    "content": "error: manual implementation of `mem::take`\n  --> tests/ui/manual_take.rs:7:25\n   |\nLL |       let _lint_negated = if x {\n   |  _________________________^\nLL | |\nLL | |         x = false;\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::manual-take` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_take)]`\nhelp: use\n   |\nLL -     let _lint_negated = if x {\nLL -\nLL -         x = false;\nLL -         false\nLL -     } else {\nLL -         true\nLL -     };\nLL +     let _lint_negated = !std::mem::take(&mut x);\n   |\n\nerror: manual implementation of `mem::take`\n  --> tests/ui/manual_take.rs:60:5\n   |\nLL | /     if x {\nLL | |\nLL | |         x = false;\nLL | |         true\nLL | |     } else {\nLL | |         false\nLL | |     }\n   | |_____^\n   |\nhelp: use\n   |\nLL -     if x {\nLL -\nLL -         x = false;\nLL -         true\nLL -     } else {\nLL -         false\nLL -     }\nLL +     std::mem::take(&mut x)\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_take_nocore.rs",
    "content": "//@ check-pass\n#![feature(no_core, lang_items)]\n#![no_core]\n#![allow(clippy::missing_safety_doc)]\n#![warn(clippy::manual_take)]\n\n#[link(name = \"c\")]\nunsafe extern \"C\" {}\n\n#[lang = \"pointee_sized\"]\npub trait PointeeSized {}\n\n#[lang = \"meta_sized\"]\npub trait MetaSized: PointeeSized {}\n\n#[lang = \"sized\"]\npub trait Sized: MetaSized {}\n#[lang = \"copy\"]\npub trait Copy {}\n#[lang = \"freeze\"]\npub unsafe trait Freeze {}\n\n#[lang = \"start\"]\nfn start<T>(_main: fn() -> T, _argc: isize, _argv: *const *const u8, _sigpipe: u8) -> isize {\n    0\n}\n\nfn main() {\n    let mut x = true;\n    // this should not lint because we don't have std nor core\n    let _manual_take = if x {\n        x = false;\n        true\n    } else {\n        false\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_take_nostd.fixed",
    "content": "#![no_std]\n#![warn(clippy::manual_take)]\n\npub fn manual_mem_take_should_reference_core() {\n    let mut x = true;\n\n    let _lint_negated = !core::mem::take(&mut x);\n\n    let _lint = core::mem::take(&mut x);\n}\n"
  },
  {
    "path": "tests/ui/manual_take_nostd.rs",
    "content": "#![no_std]\n#![warn(clippy::manual_take)]\n\npub fn manual_mem_take_should_reference_core() {\n    let mut x = true;\n\n    let _lint_negated = if x {\n        //~^ manual_take\n        x = false;\n        false\n    } else {\n        true\n    };\n\n    let _lint = if x {\n        //~^ manual_take\n        x = false;\n        true\n    } else {\n        false\n    };\n}\n"
  },
  {
    "path": "tests/ui/manual_take_nostd.stderr",
    "content": "error: manual implementation of `mem::take`\n  --> tests/ui/manual_take_nostd.rs:7:25\n   |\nLL |       let _lint_negated = if x {\n   |  _________________________^\nLL | |\nLL | |         x = false;\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::manual-take` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_take)]`\nhelp: use\n   |\nLL -     let _lint_negated = if x {\nLL -\nLL -         x = false;\nLL -         false\nLL -     } else {\nLL -         true\nLL -     };\nLL +     let _lint_negated = !core::mem::take(&mut x);\n   |\n\nerror: manual implementation of `mem::take`\n  --> tests/ui/manual_take_nostd.rs:15:17\n   |\nLL |       let _lint = if x {\n   |  _________________^\nLL | |\nLL | |         x = false;\nLL | |         true\nLL | |     } else {\nLL | |         false\nLL | |     };\n   | |_____^\n   |\nhelp: use\n   |\nLL -     let _lint = if x {\nLL -\nLL -         x = false;\nLL -         true\nLL -     } else {\nLL -         false\nLL -     };\nLL +     let _lint = core::mem::take(&mut x);\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_try_fold.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::unnecessary_fold, unused)]\n#![warn(clippy::manual_try_fold)]\n#![feature(try_trait_v2)]\n//@no-rustfix\nuse std::ops::{ControlFlow, FromResidual, Try};\n\n#[macro_use]\nextern crate proc_macros;\n\n// Test custom `Try` with more than 1 argument\nstruct NotOption(i32, i32);\n\nimpl<R> FromResidual<R> for NotOption {\n    fn from_residual(_: R) -> Self {\n        todo!()\n    }\n}\n\nimpl Try for NotOption {\n    type Output = ();\n    type Residual = ();\n\n    fn from_output(_: Self::Output) -> Self {\n        todo!()\n    }\n\n    fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {\n        todo!()\n    }\n}\n\n// Test custom `Try` with only 1 argument\n#[derive(Default)]\nstruct NotOptionButWorse(i32);\n\nimpl<R> FromResidual<R> for NotOptionButWorse {\n    fn from_residual(_: R) -> Self {\n        todo!()\n    }\n}\n\nimpl Try for NotOptionButWorse {\n    type Output = ();\n    type Residual = ();\n\n    fn from_output(_: Self::Output) -> Self {\n        todo!()\n    }\n\n    fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {\n        todo!()\n    }\n}\n\nfn main() {\n    [1, 2, 3]\n        .iter()\n        .fold(Some(0i32), |sum, i| sum?.checked_add(*i))\n        //~^ manual_try_fold\n        .unwrap();\n    [1, 2, 3]\n        .iter()\n        .fold(NotOption(0i32, 0i32), |sum, i| NotOption(0i32, 0i32));\n    //~^ manual_try_fold\n    [1, 2, 3]\n        .iter()\n        .fold(NotOptionButWorse(0i32), |sum, i| NotOptionButWorse(0i32));\n    //~^ manual_try_fold\n    // Do not lint\n    [1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)).unwrap();\n    [1, 2, 3].iter().fold(0i32, |sum, i| sum + i);\n    [1, 2, 3]\n        .iter()\n        .fold(NotOptionButWorse::default(), |sum, i| NotOptionButWorse::default());\n    external! {\n        [1, 2, 3].iter().fold(Some(0i32), |sum, i| sum?.checked_add(*i)).unwrap();\n        [1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)).unwrap();\n    }\n    with_span! {\n        span\n        [1, 2, 3].iter().fold(Some(0i32), |sum, i| sum?.checked_add(*i)).unwrap();\n        [1, 2, 3].iter().try_fold(0i32, |sum, i| sum.checked_add(*i)).unwrap();\n    }\n}\n\n#[clippy::msrv = \"1.26.0\"]\nfn msrv_too_low() {\n    [1, 2, 3]\n        .iter()\n        .fold(Some(0i32), |sum, i| sum?.checked_add(*i))\n        .unwrap();\n}\n\n#[clippy::msrv = \"1.27.0\"]\nfn msrv_juust_right() {\n    [1, 2, 3]\n        .iter()\n        .fold(Some(0i32), |sum, i| sum?.checked_add(*i))\n        //~^ manual_try_fold\n        .unwrap();\n}\n\nmod issue11876 {\n    struct Foo;\n\n    impl Bar for Foo {\n        type Output = u32;\n    }\n\n    trait Bar: Sized {\n        type Output;\n        fn fold<A, F>(self, init: A, func: F) -> Fold<Self, A, F>\n        where\n            A: Clone,\n            F: Fn(A, Self::Output) -> A,\n        {\n            Fold { this: self, init, func }\n        }\n    }\n\n    #[allow(dead_code)]\n    struct Fold<S, A, F> {\n        this: S,\n        init: A,\n        func: F,\n    }\n\n    fn main() {\n        Foo.fold(Some(0), |acc, entry| Some(acc? + entry));\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_try_fold.stderr",
    "content": "error: usage of `Iterator::fold` on a type that implements `Try`\n  --> tests/ui/manual_try_fold.rs:59:10\n   |\nLL |         .fold(Some(0i32), |sum, i| sum?.checked_add(*i))\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)`\n   |\n   = note: `-D clippy::manual-try-fold` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_try_fold)]`\n\nerror: usage of `Iterator::fold` on a type that implements `Try`\n  --> tests/ui/manual_try_fold.rs:64:10\n   |\nLL |         .fold(NotOption(0i32, 0i32), |sum, i| NotOption(0i32, 0i32));\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(..., |sum, i| ...)`\n\nerror: usage of `Iterator::fold` on a type that implements `Try`\n  --> tests/ui/manual_try_fold.rs:68:10\n   |\nLL |         .fold(NotOptionButWorse(0i32), |sum, i| NotOptionButWorse(0i32));\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)`\n\nerror: usage of `Iterator::fold` on a type that implements `Try`\n  --> tests/ui/manual_try_fold.rs:99:10\n   |\nLL |         .fold(Some(0i32), |sum, i| sum?.checked_add(*i))\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `try_fold` instead: `try_fold(0i32, |sum, i| ...)`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_unwrap_or.fixed",
    "content": "#![allow(dead_code)]\n#![allow(\n    unused_variables,\n    clippy::unnecessary_wraps,\n    clippy::unnecessary_literal_unwrap,\n    clippy::manual_unwrap_or_default\n)]\n\nfn option_unwrap_or() {\n    // int case\n    Some(1).unwrap_or(42);\n\n    // int case reversed\n    Some(1).unwrap_or(42);\n\n    // richer none expr\n    Some(1).unwrap_or(1 + 42);\n\n    // multiline case\n    #[rustfmt::skip]\n    Some(1).unwrap_or(42 + 42\n    + 42 + 42 + 42\n    + 42 + 42 + 42);\n\n    // string case\n    Some(\"Bob\").unwrap_or(\"Alice\");\n\n    // don't lint\n    match Some(1) {\n        Some(i) => i + 2,\n        None => 42,\n    };\n    match Some(1) {\n        Some(i) => i,\n        None => return,\n    };\n    for j in 0..4 {\n        match Some(j) {\n            Some(i) => i,\n            None => continue,\n        };\n        match Some(j) {\n            Some(i) => i,\n            None => break,\n        };\n    }\n\n    // cases where the none arm isn't a constant expression\n    // are not linted due to potential ownership issues\n\n    // ownership issue example, don't lint\n    struct NonCopyable;\n    let mut option: Option<NonCopyable> = None;\n    match option {\n        Some(x) => x,\n        None => {\n            option = Some(NonCopyable);\n            // some more code ...\n            option.unwrap()\n        },\n    };\n\n    // ownership issue example, don't lint\n    let option: Option<&str> = None;\n    match option {\n        Some(s) => s,\n        None => &format!(\"{} {}!\", \"hello\", \"world\"),\n    };\n\n    Some(1).unwrap_or(42);\n\n    //don't lint\n    if let Some(x) = Some(1) {\n        x + 1\n    } else {\n        42\n    };\n    if let Some(x) = Some(1) {\n        x\n    } else {\n        return;\n    };\n    for j in 0..4 {\n        if let Some(x) = Some(j) {\n            x\n        } else {\n            continue;\n        };\n        if let Some(x) = Some(j) {\n            x\n        } else {\n            break;\n        };\n    }\n}\n\nfn result_unwrap_or() {\n    // int case\n    Ok::<i32, &str>(1).unwrap_or(42);\n\n    // int case, scrutinee is a binding\n    let a = Ok::<i32, &str>(1);\n    a.unwrap_or(42);\n\n    // int case, suggestion must surround Result expr with parentheses\n    (Ok(1) as Result<i32, &str>).unwrap_or(42);\n\n    // method call case, suggestion must not surround Result expr `s.method()` with parentheses\n    struct S;\n    impl S {\n        fn method(self) -> Option<i32> {\n            Some(42)\n        }\n    }\n    let s = S {};\n    s.method().unwrap_or(42);\n\n    // int case reversed\n    Ok::<i32, &str>(1).unwrap_or(42);\n\n    // richer none expr\n    Ok::<i32, &str>(1).unwrap_or(1 + 42);\n\n    // multiline case\n    #[rustfmt::skip]\n    Ok::<i32, &str>(1).unwrap_or(42 + 42\n    + 42 + 42 + 42\n    + 42 + 42 + 42);\n\n    // string case\n    Ok::<&str, &str>(\"Bob\").unwrap_or(\"Alice\");\n\n    // don't lint\n    match Ok::<i32, &str>(1) {\n        Ok(i) => i + 2,\n        Err(_) => 42,\n    };\n    match Ok::<i32, &str>(1) {\n        Ok(i) => i,\n        Err(_) => return,\n    };\n    for j in 0..4 {\n        match Ok::<i32, &str>(j) {\n            Ok(i) => i,\n            Err(_) => continue,\n        };\n        match Ok::<i32, &str>(j) {\n            Ok(i) => i,\n            Err(_) => break,\n        };\n    }\n\n    // don't lint, Err value is used\n    match Ok::<&str, &str>(\"Alice\") {\n        Ok(s) => s,\n        Err(s) => s,\n    };\n    Ok::<&str, &str>(\"Alice\").unwrap_or(\"Bob\");\n\n    Ok::<i32, i32>(1).unwrap_or(42);\n\n    //don't lint\n    if let Ok(x) = Ok::<i32, i32>(1) {\n        x + 1\n    } else {\n        42\n    };\n    if let Ok(x) = Ok::<i32, i32>(1) {\n        x\n    } else {\n        return;\n    };\n    for j in 0..4 {\n        if let Ok(x) = Ok::<i32, i32>(j) {\n            x\n        } else {\n            continue;\n        };\n        if let Ok(x) = Ok::<i32, i32>(j) {\n            x\n        } else {\n            break;\n        };\n    }\n}\n\n// don't lint in const fn\nconst fn const_fn_option_unwrap_or() {\n    match Some(1) {\n        Some(s) => s,\n        None => 0,\n    };\n}\n\nconst fn const_fn_result_unwrap_or() {\n    match Ok::<&str, &str>(\"Alice\") {\n        Ok(s) => s,\n        Err(_) => \"Bob\",\n    };\n}\n\nmod issue6965 {\n    macro_rules! some_macro {\n        () => {\n            if 1 > 2 { Some(1) } else { None }\n        };\n    }\n\n    fn test() {\n        let _ = some_macro!().unwrap_or(0);\n    }\n}\n\nuse std::rc::Rc;\nfn format_name(name: Option<&Rc<str>>) -> &str {\n    match name {\n        None => \"<anon>\",\n        Some(name) => name,\n    }\n}\n\nfn implicit_deref_ref() {\n    let _: &str = match Some(&\"bye\") {\n        None => \"hi\",\n        Some(s) => s,\n    };\n}\n\nmod issue_13018 {\n    use std::collections::HashMap;\n\n    type RefName = i32;\n    pub fn get(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {\n        if let Some(names) = index.get(&id) { names } else { &[] }\n    }\n\n    pub fn get_match(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {\n        match index.get(&id) {\n            Some(names) => names,\n            None => &[],\n        }\n    }\n}\n\nfn implicit_deref(v: Vec<String>) {\n    let _ = if let Some(s) = v.first() { s } else { \"\" };\n}\n\nfn allowed_manual_unwrap_or_zero() -> u32 {\n    Some(42).unwrap_or(0)\n}\n\nfn issue_15807() {\n    let uncopyable_res: Result<usize, String> = Ok(1);\n    let _ = if let Ok(v) = uncopyable_res { v } else { 2 };\n\n    let x = uncopyable_res;\n    let _ = x.unwrap_or(2);\n    //~^ manual_unwrap_or\n\n    let copyable_res: Result<usize, ()> = Ok(1);\n    let _ = copyable_res.unwrap_or(2);\n    //~^ manual_unwrap_or\n    let _ = copyable_res;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_unwrap_or.rs",
    "content": "#![allow(dead_code)]\n#![allow(\n    unused_variables,\n    clippy::unnecessary_wraps,\n    clippy::unnecessary_literal_unwrap,\n    clippy::manual_unwrap_or_default\n)]\n\nfn option_unwrap_or() {\n    // int case\n    match Some(1) {\n        //~^ manual_unwrap_or\n        Some(i) => i,\n        None => 42,\n    };\n\n    // int case reversed\n    match Some(1) {\n        //~^ manual_unwrap_or\n        None => 42,\n        Some(i) => i,\n    };\n\n    // richer none expr\n    match Some(1) {\n        //~^ manual_unwrap_or\n        Some(i) => i,\n        None => 1 + 42,\n    };\n\n    // multiline case\n    #[rustfmt::skip]\n    match Some(1) {\n    //~^ manual_unwrap_or\n        Some(i) => i,\n        None => {\n            42 + 42\n                + 42 + 42 + 42\n                + 42 + 42 + 42\n        }\n    };\n\n    // string case\n    match Some(\"Bob\") {\n        //~^ manual_unwrap_or\n        Some(i) => i,\n        None => \"Alice\",\n    };\n\n    // don't lint\n    match Some(1) {\n        Some(i) => i + 2,\n        None => 42,\n    };\n    match Some(1) {\n        Some(i) => i,\n        None => return,\n    };\n    for j in 0..4 {\n        match Some(j) {\n            Some(i) => i,\n            None => continue,\n        };\n        match Some(j) {\n            Some(i) => i,\n            None => break,\n        };\n    }\n\n    // cases where the none arm isn't a constant expression\n    // are not linted due to potential ownership issues\n\n    // ownership issue example, don't lint\n    struct NonCopyable;\n    let mut option: Option<NonCopyable> = None;\n    match option {\n        Some(x) => x,\n        None => {\n            option = Some(NonCopyable);\n            // some more code ...\n            option.unwrap()\n        },\n    };\n\n    // ownership issue example, don't lint\n    let option: Option<&str> = None;\n    match option {\n        Some(s) => s,\n        None => &format!(\"{} {}!\", \"hello\", \"world\"),\n    };\n\n    if let Some(x) = Some(1) {\n        //~^ manual_unwrap_or\n        x\n    } else {\n        42\n    };\n\n    //don't lint\n    if let Some(x) = Some(1) {\n        x + 1\n    } else {\n        42\n    };\n    if let Some(x) = Some(1) {\n        x\n    } else {\n        return;\n    };\n    for j in 0..4 {\n        if let Some(x) = Some(j) {\n            x\n        } else {\n            continue;\n        };\n        if let Some(x) = Some(j) {\n            x\n        } else {\n            break;\n        };\n    }\n}\n\nfn result_unwrap_or() {\n    // int case\n    match Ok::<i32, &str>(1) {\n        //~^ manual_unwrap_or\n        Ok(i) => i,\n        Err(_) => 42,\n    };\n\n    // int case, scrutinee is a binding\n    let a = Ok::<i32, &str>(1);\n    match a {\n        //~^ manual_unwrap_or\n        Ok(i) => i,\n        Err(_) => 42,\n    };\n\n    // int case, suggestion must surround Result expr with parentheses\n    match Ok(1) as Result<i32, &str> {\n        //~^ manual_unwrap_or\n        Ok(i) => i,\n        Err(_) => 42,\n    };\n\n    // method call case, suggestion must not surround Result expr `s.method()` with parentheses\n    struct S;\n    impl S {\n        fn method(self) -> Option<i32> {\n            Some(42)\n        }\n    }\n    let s = S {};\n    match s.method() {\n        //~^ manual_unwrap_or\n        Some(i) => i,\n        None => 42,\n    };\n\n    // int case reversed\n    match Ok::<i32, &str>(1) {\n        //~^ manual_unwrap_or\n        Err(_) => 42,\n        Ok(i) => i,\n    };\n\n    // richer none expr\n    match Ok::<i32, &str>(1) {\n        //~^ manual_unwrap_or\n        Ok(i) => i,\n        Err(_) => 1 + 42,\n    };\n\n    // multiline case\n    #[rustfmt::skip]\n    match Ok::<i32, &str>(1) {\n    //~^ manual_unwrap_or\n        Ok(i) => i,\n        Err(_) => {\n            42 + 42\n                + 42 + 42 + 42\n                + 42 + 42 + 42\n        }\n    };\n\n    // string case\n    match Ok::<&str, &str>(\"Bob\") {\n        //~^ manual_unwrap_or\n        Ok(i) => i,\n        Err(_) => \"Alice\",\n    };\n\n    // don't lint\n    match Ok::<i32, &str>(1) {\n        Ok(i) => i + 2,\n        Err(_) => 42,\n    };\n    match Ok::<i32, &str>(1) {\n        Ok(i) => i,\n        Err(_) => return,\n    };\n    for j in 0..4 {\n        match Ok::<i32, &str>(j) {\n            Ok(i) => i,\n            Err(_) => continue,\n        };\n        match Ok::<i32, &str>(j) {\n            Ok(i) => i,\n            Err(_) => break,\n        };\n    }\n\n    // don't lint, Err value is used\n    match Ok::<&str, &str>(\"Alice\") {\n        Ok(s) => s,\n        Err(s) => s,\n    };\n    match Ok::<&str, &str>(\"Alice\") {\n        //~^ manual_unwrap_or\n        Ok(s) => s,\n        Err(s) => \"Bob\",\n    };\n\n    if let Ok(x) = Ok::<i32, i32>(1) {\n        //~^ manual_unwrap_or\n        x\n    } else {\n        42\n    };\n\n    //don't lint\n    if let Ok(x) = Ok::<i32, i32>(1) {\n        x + 1\n    } else {\n        42\n    };\n    if let Ok(x) = Ok::<i32, i32>(1) {\n        x\n    } else {\n        return;\n    };\n    for j in 0..4 {\n        if let Ok(x) = Ok::<i32, i32>(j) {\n            x\n        } else {\n            continue;\n        };\n        if let Ok(x) = Ok::<i32, i32>(j) {\n            x\n        } else {\n            break;\n        };\n    }\n}\n\n// don't lint in const fn\nconst fn const_fn_option_unwrap_or() {\n    match Some(1) {\n        Some(s) => s,\n        None => 0,\n    };\n}\n\nconst fn const_fn_result_unwrap_or() {\n    match Ok::<&str, &str>(\"Alice\") {\n        Ok(s) => s,\n        Err(_) => \"Bob\",\n    };\n}\n\nmod issue6965 {\n    macro_rules! some_macro {\n        () => {\n            if 1 > 2 { Some(1) } else { None }\n        };\n    }\n\n    fn test() {\n        let _ = match some_macro!() {\n            //~^ manual_unwrap_or\n            Some(val) => val,\n            None => 0,\n        };\n    }\n}\n\nuse std::rc::Rc;\nfn format_name(name: Option<&Rc<str>>) -> &str {\n    match name {\n        None => \"<anon>\",\n        Some(name) => name,\n    }\n}\n\nfn implicit_deref_ref() {\n    let _: &str = match Some(&\"bye\") {\n        None => \"hi\",\n        Some(s) => s,\n    };\n}\n\nmod issue_13018 {\n    use std::collections::HashMap;\n\n    type RefName = i32;\n    pub fn get(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {\n        if let Some(names) = index.get(&id) { names } else { &[] }\n    }\n\n    pub fn get_match(index: &HashMap<usize, Vec<RefName>>, id: usize) -> &[RefName] {\n        match index.get(&id) {\n            Some(names) => names,\n            None => &[],\n        }\n    }\n}\n\nfn implicit_deref(v: Vec<String>) {\n    let _ = if let Some(s) = v.first() { s } else { \"\" };\n}\n\nfn allowed_manual_unwrap_or_zero() -> u32 {\n    if let Some(x) = Some(42) {\n        //~^ manual_unwrap_or\n        x\n    } else {\n        0\n    }\n}\n\nfn issue_15807() {\n    let uncopyable_res: Result<usize, String> = Ok(1);\n    let _ = if let Ok(v) = uncopyable_res { v } else { 2 };\n\n    let x = uncopyable_res;\n    let _ = if let Ok(v) = x { v } else { 2 };\n    //~^ manual_unwrap_or\n\n    let copyable_res: Result<usize, ()> = Ok(1);\n    let _ = if let Ok(v) = copyable_res { v } else { 2 };\n    //~^ manual_unwrap_or\n    let _ = copyable_res;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/manual_unwrap_or.stderr",
    "content": "error: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:11:5\n   |\nLL | /     match Some(1) {\nLL | |\nLL | |         Some(i) => i,\nLL | |         None => 42,\nLL | |     };\n   | |_____^ help: replace with: `Some(1).unwrap_or(42)`\n   |\n   = note: `-D clippy::manual-unwrap-or` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or)]`\n\nerror: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:18:5\n   |\nLL | /     match Some(1) {\nLL | |\nLL | |         None => 42,\nLL | |         Some(i) => i,\nLL | |     };\n   | |_____^ help: replace with: `Some(1).unwrap_or(42)`\n\nerror: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:25:5\n   |\nLL | /     match Some(1) {\nLL | |\nLL | |         Some(i) => i,\nLL | |         None => 1 + 42,\nLL | |     };\n   | |_____^ help: replace with: `Some(1).unwrap_or(1 + 42)`\n\nerror: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:33:5\n   |\nLL | /     match Some(1) {\nLL | |\nLL | |         Some(i) => i,\nLL | |         None => {\n...  |\nLL | |     };\n   | |_____^\n   |\nhelp: replace with\n   |\nLL ~     Some(1).unwrap_or(42 + 42\nLL +     + 42 + 42 + 42\nLL ~     + 42 + 42 + 42);\n   |\n\nerror: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:44:5\n   |\nLL | /     match Some(\"Bob\") {\nLL | |\nLL | |         Some(i) => i,\nLL | |         None => \"Alice\",\nLL | |     };\n   | |_____^ help: replace with: `Some(\"Bob\").unwrap_or(\"Alice\")`\n\nerror: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:92:5\n   |\nLL | /     if let Some(x) = Some(1) {\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         42\nLL | |     };\n   | |_____^ help: replace with: `Some(1).unwrap_or(42)`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:126:5\n   |\nLL | /     match Ok::<i32, &str>(1) {\nLL | |\nLL | |         Ok(i) => i,\nLL | |         Err(_) => 42,\nLL | |     };\n   | |_____^ help: replace with: `Ok::<i32, &str>(1).unwrap_or(42)`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:134:5\n   |\nLL | /     match a {\nLL | |\nLL | |         Ok(i) => i,\nLL | |         Err(_) => 42,\nLL | |     };\n   | |_____^ help: replace with: `a.unwrap_or(42)`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:141:5\n   |\nLL | /     match Ok(1) as Result<i32, &str> {\nLL | |\nLL | |         Ok(i) => i,\nLL | |         Err(_) => 42,\nLL | |     };\n   | |_____^ help: replace with: `(Ok(1) as Result<i32, &str>).unwrap_or(42)`\n\nerror: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:155:5\n   |\nLL | /     match s.method() {\nLL | |\nLL | |         Some(i) => i,\nLL | |         None => 42,\nLL | |     };\n   | |_____^ help: replace with: `s.method().unwrap_or(42)`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:162:5\n   |\nLL | /     match Ok::<i32, &str>(1) {\nLL | |\nLL | |         Err(_) => 42,\nLL | |         Ok(i) => i,\nLL | |     };\n   | |_____^ help: replace with: `Ok::<i32, &str>(1).unwrap_or(42)`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:169:5\n   |\nLL | /     match Ok::<i32, &str>(1) {\nLL | |\nLL | |         Ok(i) => i,\nLL | |         Err(_) => 1 + 42,\nLL | |     };\n   | |_____^ help: replace with: `Ok::<i32, &str>(1).unwrap_or(1 + 42)`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:177:5\n   |\nLL | /     match Ok::<i32, &str>(1) {\nLL | |\nLL | |         Ok(i) => i,\nLL | |         Err(_) => {\n...  |\nLL | |     };\n   | |_____^\n   |\nhelp: replace with\n   |\nLL ~     Ok::<i32, &str>(1).unwrap_or(42 + 42\nLL +     + 42 + 42 + 42\nLL ~     + 42 + 42 + 42);\n   |\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:188:5\n   |\nLL | /     match Ok::<&str, &str>(\"Bob\") {\nLL | |\nLL | |         Ok(i) => i,\nLL | |         Err(_) => \"Alice\",\nLL | |     };\n   | |_____^ help: replace with: `Ok::<&str, &str>(\"Bob\").unwrap_or(\"Alice\")`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:219:5\n   |\nLL | /     match Ok::<&str, &str>(\"Alice\") {\nLL | |\nLL | |         Ok(s) => s,\nLL | |         Err(s) => \"Bob\",\nLL | |     };\n   | |_____^ help: replace with: `Ok::<&str, &str>(\"Alice\").unwrap_or(\"Bob\")`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:225:5\n   |\nLL | /     if let Ok(x) = Ok::<i32, i32>(1) {\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         42\nLL | |     };\n   | |_____^ help: replace with: `Ok::<i32, i32>(1).unwrap_or(42)`\n\nerror: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:280:17\n   |\nLL |           let _ = match some_macro!() {\n   |  _________________^\nLL | |\nLL | |             Some(val) => val,\nLL | |             None => 0,\nLL | |         };\n   | |_________^ help: replace with: `some_macro!().unwrap_or(0)`\n\nerror: this pattern reimplements `Option::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:324:5\n   |\nLL | /     if let Some(x) = Some(42) {\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         0\nLL | |     }\n   | |_____^ help: replace with: `Some(42).unwrap_or(0)`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:337:13\n   |\nLL |     let _ = if let Ok(v) = x { v } else { 2 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `x.unwrap_or(2)`\n\nerror: this pattern reimplements `Result::unwrap_or`\n  --> tests/ui/manual_unwrap_or.rs:341:13\n   |\nLL |     let _ = if let Ok(v) = copyable_res { v } else { 2 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `copyable_res.unwrap_or(2)`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_unwrap_or_default.fixed",
    "content": "#![warn(clippy::manual_unwrap_or_default)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nfn main() {\n    let x: Option<Vec<String>> = None;\n    x.unwrap_or_default();\n\n    let x: Option<Vec<String>> = None;\n    x.unwrap_or_default();\n\n    let x: Option<String> = None;\n    x.unwrap_or_default();\n\n    let x: Option<Vec<String>> = None;\n    x.unwrap_or_default();\n\n    let x: Option<Vec<String>> = None;\n    x.unwrap_or_default();\n\n    // Issue #12564\n    // No error as &Vec<_> doesn't implement std::default::Default\n    let mut map = std::collections::HashMap::from([(0, vec![0; 3]), (1, vec![1; 3]), (2, vec![2])]);\n    let x: &[_] = if let Some(x) = map.get(&0) { x } else { &[] };\n    // Same code as above written using match.\n    let x: &[_] = match map.get(&0) {\n        Some(x) => x,\n        None => &[],\n    };\n\n    let x: Result<String, i64> = Ok(String::new());\n    x.unwrap_or_default();\n\n    let x: Result<String, i64> = Ok(String::new());\n    x.unwrap_or_default();\n\n    // edge case\n    // because the `Some(bizarro)` pattern is not actually reachable,\n    // changing this match to `unwrap_or_default` would have side effects\n    let bizarro = Some(String::new());\n    match bizarro {\n        _ => String::new(),\n        Some(bizarro) => bizarro,\n    };\n}\n\n// Issue #12531\nunsafe fn no_deref_ptr(a: Option<i32>, b: *const Option<i32>) -> i32 {\n    unsafe {\n        match a {\n            // `*b` being correct depends on `a == Some(_)`\n            Some(_) => (*b).unwrap_or_default(),\n            _ => 0,\n        }\n    }\n}\n\nconst fn issue_12568(opt: Option<bool>) -> bool {\n    match opt {\n        Some(s) => s,\n        None => false,\n    }\n}\n\nfn issue_12569() {\n    let match_none_se = match 1u32.checked_div(0) {\n        Some(v) => v,\n        None => {\n            println!(\"important\");\n            0\n        },\n    };\n    let match_some_se = match 1u32.checked_div(0) {\n        Some(v) => {\n            println!(\"important\");\n            v\n        },\n        None => 0,\n    };\n    let iflet_else_se = if let Some(v) = 1u32.checked_div(0) {\n        v\n    } else {\n        println!(\"important\");\n        0\n    };\n    let iflet_then_se = if let Some(v) = 1u32.checked_div(0) {\n        println!(\"important\");\n        v\n    } else {\n        0\n    };\n}\n\n// Should not warn!\nfn issue_12928() {\n    let x = Some((1, 2));\n    let y = if let Some((a, _)) = x { a } else { 0 };\n    let y = if let Some((a, ..)) = x { a } else { 0 };\n    let x = Some([1, 2]);\n    let y = if let Some([a, _]) = x { a } else { 0 };\n    let y = if let Some([a, ..]) = x { a } else { 0 };\n\n    struct X {\n        a: u8,\n        b: u8,\n    }\n    let x = Some(X { a: 0, b: 0 });\n    let y = if let Some(X { a, .. }) = x { a } else { 0 };\n    struct Y(u8, u8);\n    let x = Some(Y(0, 0));\n    let y = if let Some(Y(a, _)) = x { a } else { 0 };\n    let y = if let Some(Y(a, ..)) = x { a } else { 0 };\n}\n\n// For symmetry with `manual_unwrap_or` test\nfn allowed_manual_unwrap_or_zero() -> u32 {\n    Some(42).unwrap_or_default()\n}\n\nmod issue14716 {\n    struct Foo {\n        name: Option<String>,\n    }\n\n    fn bar(project: &Foo) {\n        let _name = match project.name {\n            Some(ref x) => x,\n            None => \"\",\n        };\n    }\n}\n\nfn issue_15807() {\n    let uncopyable_res: Result<usize, String> = Ok(1);\n    let _ = if let Ok(v) = uncopyable_res { v } else { 0 };\n\n    let x = uncopyable_res;\n    let _ = x.unwrap_or_default();\n    //~^ manual_unwrap_or_default\n\n    let copyable_res: Result<usize, ()> = Ok(1);\n    let _ = copyable_res.unwrap_or_default();\n    //~^ manual_unwrap_or_default\n    let _ = copyable_res;\n}\n"
  },
  {
    "path": "tests/ui/manual_unwrap_or_default.rs",
    "content": "#![warn(clippy::manual_unwrap_or_default)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nfn main() {\n    let x: Option<Vec<String>> = None;\n    match x {\n        //~^ manual_unwrap_or_default\n        Some(v) => v,\n        None => Vec::default(),\n    };\n\n    let x: Option<Vec<String>> = None;\n    match x {\n        //~^ manual_unwrap_or_default\n        Some(v) => v,\n        _ => Vec::default(),\n    };\n\n    let x: Option<String> = None;\n    match x {\n        //~^ manual_unwrap_or_default\n        Some(v) => v,\n        None => String::new(),\n    };\n\n    let x: Option<Vec<String>> = None;\n    match x {\n        //~^ manual_unwrap_or_default\n        None => Vec::default(),\n        Some(v) => v,\n    };\n\n    let x: Option<Vec<String>> = None;\n    if let Some(v) = x {\n        //~^ manual_unwrap_or_default\n\n        v\n    } else {\n        Vec::default()\n    };\n\n    // Issue #12564\n    // No error as &Vec<_> doesn't implement std::default::Default\n    let mut map = std::collections::HashMap::from([(0, vec![0; 3]), (1, vec![1; 3]), (2, vec![2])]);\n    let x: &[_] = if let Some(x) = map.get(&0) { x } else { &[] };\n    // Same code as above written using match.\n    let x: &[_] = match map.get(&0) {\n        Some(x) => x,\n        None => &[],\n    };\n\n    let x: Result<String, i64> = Ok(String::new());\n    match x {\n        //~^ manual_unwrap_or_default\n        Ok(v) => v,\n        Err(_) => String::new(),\n    };\n\n    let x: Result<String, i64> = Ok(String::new());\n    if let Ok(v) = x {\n        //~^ manual_unwrap_or_default\n\n        v\n    } else {\n        String::new()\n    };\n\n    // edge case\n    // because the `Some(bizarro)` pattern is not actually reachable,\n    // changing this match to `unwrap_or_default` would have side effects\n    let bizarro = Some(String::new());\n    match bizarro {\n        _ => String::new(),\n        Some(bizarro) => bizarro,\n    };\n}\n\n// Issue #12531\nunsafe fn no_deref_ptr(a: Option<i32>, b: *const Option<i32>) -> i32 {\n    unsafe {\n        match a {\n            // `*b` being correct depends on `a == Some(_)`\n            Some(_) => match *b {\n                //~^ manual_unwrap_or_default\n                Some(v) => v,\n                _ => 0,\n            },\n            _ => 0,\n        }\n    }\n}\n\nconst fn issue_12568(opt: Option<bool>) -> bool {\n    match opt {\n        Some(s) => s,\n        None => false,\n    }\n}\n\nfn issue_12569() {\n    let match_none_se = match 1u32.checked_div(0) {\n        Some(v) => v,\n        None => {\n            println!(\"important\");\n            0\n        },\n    };\n    let match_some_se = match 1u32.checked_div(0) {\n        Some(v) => {\n            println!(\"important\");\n            v\n        },\n        None => 0,\n    };\n    let iflet_else_se = if let Some(v) = 1u32.checked_div(0) {\n        v\n    } else {\n        println!(\"important\");\n        0\n    };\n    let iflet_then_se = if let Some(v) = 1u32.checked_div(0) {\n        println!(\"important\");\n        v\n    } else {\n        0\n    };\n}\n\n// Should not warn!\nfn issue_12928() {\n    let x = Some((1, 2));\n    let y = if let Some((a, _)) = x { a } else { 0 };\n    let y = if let Some((a, ..)) = x { a } else { 0 };\n    let x = Some([1, 2]);\n    let y = if let Some([a, _]) = x { a } else { 0 };\n    let y = if let Some([a, ..]) = x { a } else { 0 };\n\n    struct X {\n        a: u8,\n        b: u8,\n    }\n    let x = Some(X { a: 0, b: 0 });\n    let y = if let Some(X { a, .. }) = x { a } else { 0 };\n    struct Y(u8, u8);\n    let x = Some(Y(0, 0));\n    let y = if let Some(Y(a, _)) = x { a } else { 0 };\n    let y = if let Some(Y(a, ..)) = x { a } else { 0 };\n}\n\n// For symmetry with `manual_unwrap_or` test\nfn allowed_manual_unwrap_or_zero() -> u32 {\n    if let Some(x) = Some(42) {\n        //~^ manual_unwrap_or_default\n        x\n    } else {\n        0\n    }\n}\n\nmod issue14716 {\n    struct Foo {\n        name: Option<String>,\n    }\n\n    fn bar(project: &Foo) {\n        let _name = match project.name {\n            Some(ref x) => x,\n            None => \"\",\n        };\n    }\n}\n\nfn issue_15807() {\n    let uncopyable_res: Result<usize, String> = Ok(1);\n    let _ = if let Ok(v) = uncopyable_res { v } else { 0 };\n\n    let x = uncopyable_res;\n    let _ = if let Ok(v) = x { v } else { 0 };\n    //~^ manual_unwrap_or_default\n\n    let copyable_res: Result<usize, ()> = Ok(1);\n    let _ = if let Ok(v) = copyable_res { v } else { 0 };\n    //~^ manual_unwrap_or_default\n    let _ = copyable_res;\n}\n"
  },
  {
    "path": "tests/ui/manual_unwrap_or_default.stderr",
    "content": "error: match can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:6:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Some(v) => v,\nLL | |         None => Vec::default(),\nLL | |     };\n   | |_____^ help: replace it with: `x.unwrap_or_default()`\n   |\n   = note: `-D clippy::manual-unwrap-or-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or_default)]`\n\nerror: match can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:13:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Some(v) => v,\nLL | |         _ => Vec::default(),\nLL | |     };\n   | |_____^ help: replace it with: `x.unwrap_or_default()`\n\nerror: match can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:20:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Some(v) => v,\nLL | |         None => String::new(),\nLL | |     };\n   | |_____^ help: replace it with: `x.unwrap_or_default()`\n\nerror: match can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:27:5\n   |\nLL | /     match x {\nLL | |\nLL | |         None => Vec::default(),\nLL | |         Some(v) => v,\nLL | |     };\n   | |_____^ help: replace it with: `x.unwrap_or_default()`\n\nerror: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:34:5\n   |\nLL | /     if let Some(v) = x {\nLL | |\nLL | |\nLL | |         v\nLL | |     } else {\nLL | |         Vec::default()\nLL | |     };\n   | |_____^ help: replace it with: `x.unwrap_or_default()`\n\nerror: match can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:53:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Ok(v) => v,\nLL | |         Err(_) => String::new(),\nLL | |     };\n   | |_____^ help: replace it with: `x.unwrap_or_default()`\n\nerror: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:60:5\n   |\nLL | /     if let Ok(v) = x {\nLL | |\nLL | |\nLL | |         v\nLL | |     } else {\nLL | |         String::new()\nLL | |     };\n   | |_____^ help: replace it with: `x.unwrap_or_default()`\n\nerror: match can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:83:24\n   |\nLL |               Some(_) => match *b {\n   |  ________________________^\nLL | |\nLL | |                 Some(v) => v,\nLL | |                 _ => 0,\nLL | |             },\n   | |_____________^ help: replace it with: `(*b).unwrap_or_default()`\n\nerror: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:152:5\n   |\nLL | /     if let Some(x) = Some(42) {\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         0\nLL | |     }\n   | |_____^ help: replace it with: `Some(42).unwrap_or_default()`\n\nerror: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:178:13\n   |\nLL |     let _ = if let Ok(v) = x { v } else { 0 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x.unwrap_or_default()`\n\nerror: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default.rs:182:13\n   |\nLL |     let _ = if let Ok(v) = copyable_res { v } else { 0 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `copyable_res.unwrap_or_default()`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_unwrap_or_default_unfixable.rs",
    "content": "//@no-rustfix\nfn issue_12670() {\n    // no auto: type not found\n    #[allow(clippy::match_result_ok)]\n    let _ = if let Some(x) = \"1\".parse().ok() {\n        //~^ manual_unwrap_or_default\n        x\n    } else {\n        i32::default()\n    };\n    let _ = if let Some(x) = None { x } else { i32::default() };\n    //~^ manual_unwrap_or_default\n    // auto fix with unwrap_or_default\n    let a: Option<i32> = None;\n    let _ = if let Some(x) = a { x } else { i32::default() };\n    //~^ manual_unwrap_or_default\n    let _ = if let Some(x) = Some(99) { x } else { i32::default() };\n    //~^ manual_unwrap_or_default\n}\n"
  },
  {
    "path": "tests/ui/manual_unwrap_or_default_unfixable.stderr",
    "content": "error: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default_unfixable.rs:5:13\n   |\nLL |       let _ = if let Some(x) = \"1\".parse().ok() {\n   |  _____________^\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         i32::default()\nLL | |     };\n   | |_____^ help: ascribe the type i32 and replace your expression with: `\"1\".parse().ok().unwrap_or_default()`\n   |\n   = note: `-D clippy::manual-unwrap-or-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or_default)]`\n\nerror: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default_unfixable.rs:11:13\n   |\nLL |     let _ = if let Some(x) = None { x } else { i32::default() };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `None::<i32>.unwrap_or_default()`\n\nerror: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default_unfixable.rs:15:13\n   |\nLL |     let _ = if let Some(x) = a { x } else { i32::default() };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.unwrap_or_default()`\n\nerror: if let can be simplified with `.unwrap_or_default()`\n  --> tests/ui/manual_unwrap_or_default_unfixable.rs:17:13\n   |\nLL |     let _ = if let Some(x) = Some(99) { x } else { i32::default() };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(99).unwrap_or_default()`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/manual_while_let_some.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::manual_while_let_some)]\n\nstruct VecInStruct {\n    numbers: Vec<i32>,\n    unrelated: String,\n}\n\nstruct Foo {\n    a: i32,\n    b: i32,\n}\n\nfn accept_i32(_: i32) {}\nfn accept_optional_i32(_: Option<i32>) {}\nfn accept_i32_tuple(_: (i32, i32)) {}\n\nfn main() {\n    let mut numbers = vec![1, 2, 3, 4, 5];\n    while let Some(number) = numbers.pop() {\n        \n        //~^ manual_while_let_some\n    }\n\n    let mut val = VecInStruct {\n        numbers: vec![1, 2, 3, 4, 5],\n        unrelated: String::new(),\n    };\n    while let Some(number) = val.numbers.pop() {\n        \n        //~^ manual_while_let_some\n    }\n\n    while let Some(element) = numbers.pop() {\n        accept_i32(element);\n        //~^ manual_while_let_some\n    }\n\n    while let Some(element) = numbers.pop() {\n        accept_i32(element);\n        //~^ manual_while_let_some\n    }\n\n    // This should not warn. It \"conditionally\" pops elements.\n    while !numbers.is_empty() {\n        if true {\n            accept_i32(numbers.pop().unwrap());\n        }\n    }\n\n    // This should also not warn. It conditionally pops elements.\n    while !numbers.is_empty() {\n        if false {\n            continue;\n        }\n        accept_i32(numbers.pop().unwrap());\n    }\n\n    // This should not warn. It pops elements, but does not unwrap it.\n    // Might handle the Option in some other arbitrary way.\n    while !numbers.is_empty() {\n        accept_optional_i32(numbers.pop());\n    }\n\n    let unrelated_vec: Vec<String> = Vec::new();\n    // This should not warn. It pops elements from a different vector.\n    while !unrelated_vec.is_empty() {\n        accept_i32(numbers.pop().unwrap());\n    }\n\n    macro_rules! generate_loop {\n        () => {\n            while !numbers.is_empty() {\n                accept_i32(numbers.pop().unwrap());\n            }\n        };\n    }\n    // Do not warn if the loop comes from a macro.\n    generate_loop!();\n\n    // Try other kinds of patterns\n    let mut numbers = vec![(0, 0), (1, 1), (2, 2)];\n    while let Some((a, b)) = numbers.pop() {\n        \n        //~^ manual_while_let_some\n    }\n\n    while let Some(element) = numbers.pop() {\n        accept_i32_tuple(element);\n        //~^ manual_while_let_some\n    }\n\n    let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }];\n    while let Some(Foo { a, b }) = results.pop() {\n        \n        //~^ manual_while_let_some\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_while_let_some.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::manual_while_let_some)]\n\nstruct VecInStruct {\n    numbers: Vec<i32>,\n    unrelated: String,\n}\n\nstruct Foo {\n    a: i32,\n    b: i32,\n}\n\nfn accept_i32(_: i32) {}\nfn accept_optional_i32(_: Option<i32>) {}\nfn accept_i32_tuple(_: (i32, i32)) {}\n\nfn main() {\n    let mut numbers = vec![1, 2, 3, 4, 5];\n    while !numbers.is_empty() {\n        let number = numbers.pop().unwrap();\n        //~^ manual_while_let_some\n    }\n\n    let mut val = VecInStruct {\n        numbers: vec![1, 2, 3, 4, 5],\n        unrelated: String::new(),\n    };\n    while !val.numbers.is_empty() {\n        let number = val.numbers.pop().unwrap();\n        //~^ manual_while_let_some\n    }\n\n    while !numbers.is_empty() {\n        accept_i32(numbers.pop().unwrap());\n        //~^ manual_while_let_some\n    }\n\n    while !numbers.is_empty() {\n        accept_i32(numbers.pop().expect(\"\"));\n        //~^ manual_while_let_some\n    }\n\n    // This should not warn. It \"conditionally\" pops elements.\n    while !numbers.is_empty() {\n        if true {\n            accept_i32(numbers.pop().unwrap());\n        }\n    }\n\n    // This should also not warn. It conditionally pops elements.\n    while !numbers.is_empty() {\n        if false {\n            continue;\n        }\n        accept_i32(numbers.pop().unwrap());\n    }\n\n    // This should not warn. It pops elements, but does not unwrap it.\n    // Might handle the Option in some other arbitrary way.\n    while !numbers.is_empty() {\n        accept_optional_i32(numbers.pop());\n    }\n\n    let unrelated_vec: Vec<String> = Vec::new();\n    // This should not warn. It pops elements from a different vector.\n    while !unrelated_vec.is_empty() {\n        accept_i32(numbers.pop().unwrap());\n    }\n\n    macro_rules! generate_loop {\n        () => {\n            while !numbers.is_empty() {\n                accept_i32(numbers.pop().unwrap());\n            }\n        };\n    }\n    // Do not warn if the loop comes from a macro.\n    generate_loop!();\n\n    // Try other kinds of patterns\n    let mut numbers = vec![(0, 0), (1, 1), (2, 2)];\n    while !numbers.is_empty() {\n        let (a, b) = numbers.pop().unwrap();\n        //~^ manual_while_let_some\n    }\n\n    while !numbers.is_empty() {\n        accept_i32_tuple(numbers.pop().unwrap());\n        //~^ manual_while_let_some\n    }\n\n    let mut results = vec![Foo { a: 1, b: 2 }, Foo { a: 3, b: 4 }];\n    while !results.is_empty() {\n        let Foo { a, b } = results.pop().unwrap();\n        //~^ manual_while_let_some\n    }\n}\n"
  },
  {
    "path": "tests/ui/manual_while_let_some.stderr",
    "content": "error: you seem to be trying to pop elements from a `Vec` in a loop\n  --> tests/ui/manual_while_let_some.rs:21:9\n   |\nLL |         let number = numbers.pop().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::manual-while-let-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_while_let_some)]`\nhelp: consider using a `while..let` loop\n   |\nLL ~     while let Some(number) = numbers.pop() {\nLL ~         \n   |\n\nerror: you seem to be trying to pop elements from a `Vec` in a loop\n  --> tests/ui/manual_while_let_some.rs:30:9\n   |\nLL |         let number = val.numbers.pop().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using a `while..let` loop\n   |\nLL ~     while let Some(number) = val.numbers.pop() {\nLL ~         \n   |\n\nerror: you seem to be trying to pop elements from a `Vec` in a loop\n  --> tests/ui/manual_while_let_some.rs:35:20\n   |\nLL |         accept_i32(numbers.pop().unwrap());\n   |                    ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using a `while..let` loop\n   |\nLL ~     while let Some(element) = numbers.pop() {\nLL ~         accept_i32(element);\n   |\n\nerror: you seem to be trying to pop elements from a `Vec` in a loop\n  --> tests/ui/manual_while_let_some.rs:40:20\n   |\nLL |         accept_i32(numbers.pop().expect(\"\"));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using a `while..let` loop\n   |\nLL ~     while let Some(element) = numbers.pop() {\nLL ~         accept_i32(element);\n   |\n\nerror: you seem to be trying to pop elements from a `Vec` in a loop\n  --> tests/ui/manual_while_let_some.rs:84:9\n   |\nLL |         let (a, b) = numbers.pop().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using a `while..let` loop\n   |\nLL ~     while let Some((a, b)) = numbers.pop() {\nLL ~         \n   |\n\nerror: you seem to be trying to pop elements from a `Vec` in a loop\n  --> tests/ui/manual_while_let_some.rs:89:26\n   |\nLL |         accept_i32_tuple(numbers.pop().unwrap());\n   |                          ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using a `while..let` loop\n   |\nLL ~     while let Some(element) = numbers.pop() {\nLL ~         accept_i32_tuple(element);\n   |\n\nerror: you seem to be trying to pop elements from a `Vec` in a loop\n  --> tests/ui/manual_while_let_some.rs:95:9\n   |\nLL |         let Foo { a, b } = results.pop().unwrap();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using a `while..let` loop\n   |\nLL ~     while let Some(Foo { a, b }) = results.pop() {\nLL ~         \n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/many_single_char_names.rs",
    "content": "#![allow(clippy::too_many_arguments, clippy::diverging_sub_expression)]\n#![warn(clippy::many_single_char_names)]\n\nfn bla() {\n    let a: i32;\n    //~^ many_single_char_names\n    //~| many_single_char_names\n    //~| many_single_char_names\n\n    let (b, c, d): (i32, i64, i16);\n    {\n        {\n            let cdefg: i32;\n            let blar: i32;\n        }\n        {\n            let e: i32;\n        }\n        {\n            let e: i32;\n            let f: i32;\n        }\n        match 5 {\n            1 => println!(),\n            e => panic!(),\n        }\n        match 5 {\n            1 => println!(),\n            _ => panic!(),\n        }\n    }\n}\n\nfn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}\n//~^ many_single_char_names\n\nfn bindings2() {\n    let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();\n    //~^ many_single_char_names\n}\n\nfn shadowing() {\n    let a = 0i32;\n    let a = 0i32;\n    let a = 0i32;\n    let a = 0i32;\n    let a = 0i32;\n    let a = 0i32;\n    {\n        let a = 0i32;\n    }\n}\n\nfn patterns() {\n    enum Z {\n        A(i32),\n        B(i32),\n        C(i32),\n        D(i32),\n        E(i32),\n        F(i32),\n    }\n\n    // These should not trigger a warning, since the pattern bindings are a new scope.\n    match Z::A(0) {\n        Z::A(a) => {},\n        Z::B(b) => {},\n        Z::C(c) => {},\n        Z::D(d) => {},\n        Z::E(e) => {},\n        Z::F(f) => {},\n    }\n}\n\n#[allow(clippy::many_single_char_names)]\nfn issue_3198_allow_works() {\n    let (a, b, c, d, e) = (0, 0, 0, 0, 0);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/many_single_char_names.stderr",
    "content": "error: 5 bindings with single-character names in scope\n  --> tests/ui/many_single_char_names.rs:5:9\n   |\nLL |     let a: i32;\n   |         ^\n...\nLL |     let (b, c, d): (i32, i64, i16);\n   |          ^  ^  ^\n...\nLL |             let e: i32;\n   |                 ^\n   |\n   = note: `-D clippy::many-single-char-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::many_single_char_names)]`\n\nerror: 6 bindings with single-character names in scope\n  --> tests/ui/many_single_char_names.rs:5:9\n   |\nLL |     let a: i32;\n   |         ^\n...\nLL |     let (b, c, d): (i32, i64, i16);\n   |          ^  ^  ^\n...\nLL |             let e: i32;\n   |                 ^\nLL |             let f: i32;\n   |                 ^\n\nerror: 5 bindings with single-character names in scope\n  --> tests/ui/many_single_char_names.rs:5:9\n   |\nLL |     let a: i32;\n   |         ^\n...\nLL |     let (b, c, d): (i32, i64, i16);\n   |          ^  ^  ^\n...\nLL |             e => panic!(),\n   |             ^\n\nerror: 8 bindings with single-character names in scope\n  --> tests/ui/many_single_char_names.rs:34:13\n   |\nLL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}\n   |             ^       ^       ^       ^       ^       ^       ^       ^\n\nerror: 8 bindings with single-character names in scope\n  --> tests/ui/many_single_char_names.rs:38:10\n   |\nLL |     let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();\n   |          ^  ^  ^  ^  ^  ^  ^  ^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_all_any_identity.fixed",
    "content": "#![warn(clippy::map_all_any_identity)]\n\nfn main() {\n    let _ = [\"foo\"].into_iter().any(|s| s == \"foo\");\n    //~^ map_all_any_identity\n\n    let _ = [\"foo\"].into_iter().all(|s| s == \"foo\");\n    //~^ map_all_any_identity\n\n    //\n    // Do not lint\n    //\n    // Not identity\n    let _ = [\"foo\"].into_iter().map(|s| s.len()).any(|n| n > 0);\n    // Macro\n    macro_rules! map {\n        ($x:expr) => {\n            $x.into_iter().map(|s| s == \"foo\")\n        };\n    }\n    map!([\"foo\"]).any(|a| a);\n}\n"
  },
  {
    "path": "tests/ui/map_all_any_identity.rs",
    "content": "#![warn(clippy::map_all_any_identity)]\n\nfn main() {\n    let _ = [\"foo\"].into_iter().map(|s| s == \"foo\").any(|a| a);\n    //~^ map_all_any_identity\n\n    let _ = [\"foo\"].into_iter().map(|s| s == \"foo\").all(std::convert::identity);\n    //~^ map_all_any_identity\n\n    //\n    // Do not lint\n    //\n    // Not identity\n    let _ = [\"foo\"].into_iter().map(|s| s.len()).any(|n| n > 0);\n    // Macro\n    macro_rules! map {\n        ($x:expr) => {\n            $x.into_iter().map(|s| s == \"foo\")\n        };\n    }\n    map!([\"foo\"]).any(|a| a);\n}\n"
  },
  {
    "path": "tests/ui/map_all_any_identity.stderr",
    "content": "error: usage of `.map(...).any(identity)`\n  --> tests/ui/map_all_any_identity.rs:4:33\n   |\nLL |     let _ = [\"foo\"].into_iter().map(|s| s == \"foo\").any(|a| a);\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::map-all-any-identity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_all_any_identity)]`\nhelp: use `.any(...)` instead\n   |\nLL -     let _ = [\"foo\"].into_iter().map(|s| s == \"foo\").any(|a| a);\nLL +     let _ = [\"foo\"].into_iter().any(|s| s == \"foo\");\n   |\n\nerror: usage of `.map(...).all(identity)`\n  --> tests/ui/map_all_any_identity.rs:7:33\n   |\nLL |     let _ = [\"foo\"].into_iter().map(|s| s == \"foo\").all(std::convert::identity);\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `.all(...)` instead\n   |\nLL -     let _ = [\"foo\"].into_iter().map(|s| s == \"foo\").all(std::convert::identity);\nLL +     let _ = [\"foo\"].into_iter().all(|s| s == \"foo\");\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_clone.fixed",
    "content": "#![warn(clippy::map_clone)]\n#![allow(\n    clippy::clone_on_copy,\n    clippy::iter_cloned_collect,\n    clippy::many_single_char_names,\n    clippy::redundant_clone,\n    clippy::redundant_closure,\n    clippy::useless_asref,\n    clippy::useless_vec,\n    clippy::empty_loop\n)]\n\nfn main() {\n    let _: Vec<i8> = vec![5_i8; 6].iter().copied().collect();\n    //~^ map_clone\n    let _: Vec<String> = vec![String::new()].iter().cloned().collect();\n    //~^ map_clone\n    let _: Vec<u32> = vec![42, 43].iter().copied().collect();\n    //~^ map_clone\n    let _: Option<u64> = Some(Box::new(16)).map(|b| *b);\n    let _: Option<u64> = Some(&16).copied();\n    //~^ map_clone\n    let _: Option<u8> = Some(&1).copied();\n    //~^ map_clone\n\n    // Don't lint these\n    let v = vec![5_i8; 6];\n    let a = 0;\n    let b = &a;\n    let _ = v.iter().map(|_x| *b);\n    let _ = v.iter().map(|_x| a.clone());\n    let _ = v.iter().map(|&_x| a);\n\n    // Issue #498\n    let _ = std::env::args();\n    //~^ map_clone\n\n    // Issue #4824 item types that aren't references\n    {\n        use std::rc::Rc;\n\n        let o: Option<Rc<u32>> = Some(Rc::new(0_u32));\n        let _: Option<u32> = o.map(|x| *x);\n        let v: Vec<Rc<u32>> = vec![Rc::new(0_u32)];\n        let _: Vec<u32> = v.into_iter().map(|x| *x).collect();\n    }\n\n    // Issue #5524 mutable references\n    {\n        let mut c = 42;\n        let v = vec![&mut c];\n        let _: Vec<u32> = v.into_iter().map(|x| *x).collect();\n        let mut d = 21;\n        let v = vec![&mut d];\n        let _: Vec<u32> = v.into_iter().map(|&mut x| x).collect();\n    }\n\n    // Issue #6299\n    {\n        let mut aa = 5;\n        let mut bb = 3;\n        let items = vec![&mut aa, &mut bb];\n        let _: Vec<_> = items.into_iter().map(|x| x.clone()).collect();\n    }\n\n    // Issue #6239 deref coercion and clone deref\n    {\n        use std::cell::RefCell;\n\n        let _ = Some(RefCell::new(String::new()).borrow()).map(|s| s.clone());\n    }\n\n    let x = Some(String::new());\n    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.\n    let y = x.cloned();\n    //~^ map_clone\n\n    let y = x.cloned();\n    //~^ map_clone\n\n    let y = x.cloned();\n    //~^ map_clone\n\n    let x: Option<u32> = Some(0);\n    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.\n    let y = x.copied();\n    //~^ map_clone\n\n    let y = x.copied();\n    //~^ map_clone\n\n    // Should not suggest `copied` or `cloned` here since `T` is not a reference.\n    let x: Option<u32> = Some(0);\n    let y = x.map(|x| u32::clone(&x));\n    let y = x.map(|x| Clone::clone(&x));\n\n    // Testing with `Result` now.\n    let x: Result<String, ()> = Ok(String::new());\n    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.\n    let y = x.cloned();\n    //~^ map_clone\n\n    let y = x.cloned();\n    //~^ map_clone\n\n    let x: Result<u32, ()> = Ok(0);\n    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.\n    let y = x.copied();\n    //~^ map_clone\n\n    let y = x.copied();\n    //~^ map_clone\n\n    // Should not suggest `copied` or `cloned` here since `T` is not a reference.\n    let x: Result<u32, ()> = Ok(0);\n    let y = x.map(|x| u32::clone(&x));\n    let y = x.map(|x| Clone::clone(&x));\n\n    // We ensure that no warning is emitted here because `useless_asref` is taking over.\n    let x = Some(String::new());\n    let y = x.as_ref().map(|x| String::clone(x));\n    let x: Result<String, ()> = Ok(String::new());\n    let y = x.as_ref().map(|x| String::clone(x));\n\n    // Issue #12271\n    {\n        // Don't lint these\n        let x: Option<&u8> = None;\n        let y = x.map(|x| String::clone(loop {}));\n        let x: Option<&u8> = None;\n        let y = x.map(|x| u8::clone(loop {}));\n        let x: Vec<&u8> = vec![];\n        let y = x.into_iter().map(|x| String::clone(loop {}));\n        let x: Vec<&u8> = vec![];\n        let y = x.into_iter().map(|x| u8::clone(loop {}));\n    }\n\n    // Issue #12528\n    {\n        // Don't lint these\n        use std::rc::{Rc, Weak as RcWeak};\n        use std::sync::{Arc, Weak as ArcWeak};\n        struct Foo;\n\n        let x = Arc::new(Foo);\n        let y = Some(&x);\n        let _z = y.map(Arc::clone);\n\n        let x = Rc::new(Foo);\n        let y = Some(&x);\n        let _z = y.map(Rc::clone);\n\n        let x = Arc::downgrade(&Arc::new(Foo));\n        let y = Some(&x);\n        let _z = y.map(ArcWeak::clone);\n\n        let x = Rc::downgrade(&Rc::new(Foo));\n        let y = Some(&x);\n        let _z = y.map(RcWeak::clone);\n    }\n}\n"
  },
  {
    "path": "tests/ui/map_clone.rs",
    "content": "#![warn(clippy::map_clone)]\n#![allow(\n    clippy::clone_on_copy,\n    clippy::iter_cloned_collect,\n    clippy::many_single_char_names,\n    clippy::redundant_clone,\n    clippy::redundant_closure,\n    clippy::useless_asref,\n    clippy::useless_vec,\n    clippy::empty_loop\n)]\n\nfn main() {\n    let _: Vec<i8> = vec![5_i8; 6].iter().map(|x| *x).collect();\n    //~^ map_clone\n    let _: Vec<String> = vec![String::new()].iter().map(|x| x.clone()).collect();\n    //~^ map_clone\n    let _: Vec<u32> = vec![42, 43].iter().map(|&x| x).collect();\n    //~^ map_clone\n    let _: Option<u64> = Some(Box::new(16)).map(|b| *b);\n    let _: Option<u64> = Some(&16).map(|b| *b);\n    //~^ map_clone\n    let _: Option<u8> = Some(&1).map(|x| x.clone());\n    //~^ map_clone\n\n    // Don't lint these\n    let v = vec![5_i8; 6];\n    let a = 0;\n    let b = &a;\n    let _ = v.iter().map(|_x| *b);\n    let _ = v.iter().map(|_x| a.clone());\n    let _ = v.iter().map(|&_x| a);\n\n    // Issue #498\n    let _ = std::env::args().map(|v| v.clone());\n    //~^ map_clone\n\n    // Issue #4824 item types that aren't references\n    {\n        use std::rc::Rc;\n\n        let o: Option<Rc<u32>> = Some(Rc::new(0_u32));\n        let _: Option<u32> = o.map(|x| *x);\n        let v: Vec<Rc<u32>> = vec![Rc::new(0_u32)];\n        let _: Vec<u32> = v.into_iter().map(|x| *x).collect();\n    }\n\n    // Issue #5524 mutable references\n    {\n        let mut c = 42;\n        let v = vec![&mut c];\n        let _: Vec<u32> = v.into_iter().map(|x| *x).collect();\n        let mut d = 21;\n        let v = vec![&mut d];\n        let _: Vec<u32> = v.into_iter().map(|&mut x| x).collect();\n    }\n\n    // Issue #6299\n    {\n        let mut aa = 5;\n        let mut bb = 3;\n        let items = vec![&mut aa, &mut bb];\n        let _: Vec<_> = items.into_iter().map(|x| x.clone()).collect();\n    }\n\n    // Issue #6239 deref coercion and clone deref\n    {\n        use std::cell::RefCell;\n\n        let _ = Some(RefCell::new(String::new()).borrow()).map(|s| s.clone());\n    }\n\n    let x = Some(String::new());\n    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.\n    let y = x.map(|x| String::clone(x));\n    //~^ map_clone\n\n    let y = x.map(Clone::clone);\n    //~^ map_clone\n\n    let y = x.map(String::clone);\n    //~^ map_clone\n\n    let x: Option<u32> = Some(0);\n    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.\n    let y = x.map(|x| u32::clone(x));\n    //~^ map_clone\n\n    let y = x.map(|x| Clone::clone(x));\n    //~^ map_clone\n\n    // Should not suggest `copied` or `cloned` here since `T` is not a reference.\n    let x: Option<u32> = Some(0);\n    let y = x.map(|x| u32::clone(&x));\n    let y = x.map(|x| Clone::clone(&x));\n\n    // Testing with `Result` now.\n    let x: Result<String, ()> = Ok(String::new());\n    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.\n    let y = x.map(|x| String::clone(x));\n    //~^ map_clone\n\n    let y = x.map(|x| Clone::clone(x));\n    //~^ map_clone\n\n    let x: Result<u32, ()> = Ok(0);\n    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.\n    let y = x.map(|x| u32::clone(x));\n    //~^ map_clone\n\n    let y = x.map(|x| Clone::clone(x));\n    //~^ map_clone\n\n    // Should not suggest `copied` or `cloned` here since `T` is not a reference.\n    let x: Result<u32, ()> = Ok(0);\n    let y = x.map(|x| u32::clone(&x));\n    let y = x.map(|x| Clone::clone(&x));\n\n    // We ensure that no warning is emitted here because `useless_asref` is taking over.\n    let x = Some(String::new());\n    let y = x.as_ref().map(|x| String::clone(x));\n    let x: Result<String, ()> = Ok(String::new());\n    let y = x.as_ref().map(|x| String::clone(x));\n\n    // Issue #12271\n    {\n        // Don't lint these\n        let x: Option<&u8> = None;\n        let y = x.map(|x| String::clone(loop {}));\n        let x: Option<&u8> = None;\n        let y = x.map(|x| u8::clone(loop {}));\n        let x: Vec<&u8> = vec![];\n        let y = x.into_iter().map(|x| String::clone(loop {}));\n        let x: Vec<&u8> = vec![];\n        let y = x.into_iter().map(|x| u8::clone(loop {}));\n    }\n\n    // Issue #12528\n    {\n        // Don't lint these\n        use std::rc::{Rc, Weak as RcWeak};\n        use std::sync::{Arc, Weak as ArcWeak};\n        struct Foo;\n\n        let x = Arc::new(Foo);\n        let y = Some(&x);\n        let _z = y.map(Arc::clone);\n\n        let x = Rc::new(Foo);\n        let y = Some(&x);\n        let _z = y.map(Rc::clone);\n\n        let x = Arc::downgrade(&Arc::new(Foo));\n        let y = Some(&x);\n        let _z = y.map(ArcWeak::clone);\n\n        let x = Rc::downgrade(&Rc::new(Foo));\n        let y = Some(&x);\n        let _z = y.map(RcWeak::clone);\n    }\n}\n"
  },
  {
    "path": "tests/ui/map_clone.stderr",
    "content": "error: you are using an explicit closure for copying elements\n  --> tests/ui/map_clone.rs:14:22\n   |\nLL |     let _: Vec<i8> = vec![5_i8; 6].iter().map(|x| *x).collect();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![5_i8; 6].iter().copied()`\n   |\n   = note: `-D clippy::map-clone` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_clone)]`\n\nerror: you are using an explicit closure for cloning elements\n  --> tests/ui/map_clone.rs:16:26\n   |\nLL |     let _: Vec<String> = vec![String::new()].iter().map(|x| x.clone()).collect();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `vec![String::new()].iter().cloned()`\n\nerror: you are using an explicit closure for copying elements\n  --> tests/ui/map_clone.rs:18:23\n   |\nLL |     let _: Vec<u32> = vec![42, 43].iter().map(|&x| x).collect();\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `vec![42, 43].iter().copied()`\n\nerror: you are using an explicit closure for copying elements\n  --> tests/ui/map_clone.rs:21:26\n   |\nLL |     let _: Option<u64> = Some(&16).map(|b| *b);\n   |                          ^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&16).copied()`\n\nerror: you are using an explicit closure for copying elements\n  --> tests/ui/map_clone.rs:23:25\n   |\nLL |     let _: Option<u8> = Some(&1).map(|x| x.clone());\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `Some(&1).copied()`\n\nerror: you are needlessly cloning iterator elements\n  --> tests/ui/map_clone.rs:35:29\n   |\nLL |     let _ = std::env::args().map(|v| v.clone());\n   |                             ^^^^^^^^^^^^^^^^^^^ help: remove the `map` call\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:75:13\n   |\nLL |     let y = x.map(|x| String::clone(x));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:78:13\n   |\nLL |     let y = x.map(Clone::clone);\n   |             ^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:81:13\n   |\nLL |     let y = x.map(String::clone);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:86:13\n   |\nLL |     let y = x.map(|x| u32::clone(x));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:89:13\n   |\nLL |     let y = x.map(|x| Clone::clone(x));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:100:13\n   |\nLL |     let y = x.map(|x| String::clone(x));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:103:13\n   |\nLL |     let y = x.map(|x| Clone::clone(x));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:108:13\n   |\nLL |     let y = x.map(|x| u32::clone(x));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`\n\nerror: you are explicitly cloning with `.map()`\n  --> tests/ui/map_clone.rs:111:13\n   |\nLL |     let y = x.map(|x| Clone::clone(x));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_collect_result_unit.fixed",
    "content": "#![warn(clippy::map_collect_result_unit)]\n\nfn main() {\n    {\n        let _ = (0..3).try_for_each(|t| Err(t + 1));\n        //~^ map_collect_result_unit\n        let _: Result<(), _> = (0..3).try_for_each(|t| Err(t + 1));\n        //~^ map_collect_result_unit\n\n        let _ = (0..3).try_for_each(|t| Err(t + 1));\n    }\n}\n\nfn _ignore() {\n    let _ = (0..3).map(|t| Err(t + 1)).collect::<Result<Vec<i32>, _>>();\n    let _ = (0..3).map(|t| Err(t + 1)).collect::<Vec<Result<(), _>>>();\n}\n"
  },
  {
    "path": "tests/ui/map_collect_result_unit.rs",
    "content": "#![warn(clippy::map_collect_result_unit)]\n\nfn main() {\n    {\n        let _ = (0..3).map(|t| Err(t + 1)).collect::<Result<(), _>>();\n        //~^ map_collect_result_unit\n        let _: Result<(), _> = (0..3).map(|t| Err(t + 1)).collect();\n        //~^ map_collect_result_unit\n\n        let _ = (0..3).try_for_each(|t| Err(t + 1));\n    }\n}\n\nfn _ignore() {\n    let _ = (0..3).map(|t| Err(t + 1)).collect::<Result<Vec<i32>, _>>();\n    let _ = (0..3).map(|t| Err(t + 1)).collect::<Vec<Result<(), _>>>();\n}\n"
  },
  {
    "path": "tests/ui/map_collect_result_unit.stderr",
    "content": "error: `.map().collect()` can be replaced with `.try_for_each()`\n  --> tests/ui/map_collect_result_unit.rs:5:17\n   |\nLL |         let _ = (0..3).map(|t| Err(t + 1)).collect::<Result<(), _>>();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(0..3).try_for_each(|t| Err(t + 1))`\n   |\n   = note: `-D clippy::map-collect-result-unit` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_collect_result_unit)]`\n\nerror: `.map().collect()` can be replaced with `.try_for_each()`\n  --> tests/ui/map_collect_result_unit.rs:7:32\n   |\nLL |         let _: Result<(), _> = (0..3).map(|t| Err(t + 1)).collect();\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(0..3).try_for_each(|t| Err(t + 1))`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_err.rs",
    "content": "#![warn(clippy::map_err_ignore)]\n#![allow(clippy::unnecessary_wraps)]\nuse std::error::Error;\nuse std::fmt;\n\n#[derive(Debug)]\nenum Errors {\n    Ignored,\n}\n\nimpl Error for Errors {}\n\nimpl fmt::Display for Errors {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"Error\")\n    }\n}\n\nfn main() -> Result<(), Errors> {\n    let x = u32::try_from(-123_i32);\n\n    println!(\"{:?}\", x.map_err(|_| Errors::Ignored));\n    //~^ map_err_ignore\n\n    // Should not warn you because you explicitly ignore the parameter\n    // using a named wildcard value\n    println!(\"{:?}\", x.map_err(|_foo| Errors::Ignored));\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/map_err.stderr",
    "content": "error: `map_err(|_|...` wildcard pattern discards the original error\n  --> tests/ui/map_err.rs:22:32\n   |\nLL |     println!(\"{:?}\", x.map_err(|_| Errors::Ignored));\n   |                                ^^^\n   |\n   = help: consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`)\n   = note: `-D clippy::map-err-ignore` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_err_ignore)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/map_flatten.fixed",
    "content": "#![warn(clippy::map_flatten)]\n#![allow(clippy::unnecessary_filter_map)]\n\n// issue #8506, multi-line\n#[rustfmt::skip]\nfn long_span() {\n    let _: Option<i32> = Some(1)\n        .and_then(|x| {\n        //~^ map_flatten\n\n\n            if x <= 5 {\n                Some(x)\n            } else {\n                None\n            }\n        });\n\n    let _: Result<i32, i32> = Ok(1)\n        .and_then(|x| {\n        //~^ map_flatten\n\n            if x == 1 {\n                Ok(x)\n            } else {\n                Err(0)\n            }\n        });\n\n    let result: Result<i32, i32> = Ok(2);\n    fn do_something() { }\n    let _: Result<i32, i32> = result\n        .and_then(|res| {\n        //~^ map_flatten\n\n            if res > 0 {\n                do_something();\n                Ok(res)\n            } else {\n                Err(0)\n            }\n        });\n\n    let _: Vec<_> = vec![5_i8; 6]\n        .into_iter()\n        .filter_map(|some_value| {\n        //~^ map_flatten\n\n            if some_value > 3 {\n                Some(some_value)\n            } else {\n                None\n            }\n        })\n        .collect();\n}\n\n#[allow(clippy::useless_vec)]\nfn no_suggestion_if_comments_present() {\n    let vec = vec![vec![1, 2, 3]];\n    let _ = vec\n        .iter()\n        // a lovely comment explaining the code in very detail\n        .flat_map(|x| x.iter());\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/map_flatten.rs",
    "content": "#![warn(clippy::map_flatten)]\n#![allow(clippy::unnecessary_filter_map)]\n\n// issue #8506, multi-line\n#[rustfmt::skip]\nfn long_span() {\n    let _: Option<i32> = Some(1)\n        .map(|x| {\n        //~^ map_flatten\n\n\n            if x <= 5 {\n                Some(x)\n            } else {\n                None\n            }\n        })\n        .flatten();\n\n    let _: Result<i32, i32> = Ok(1)\n        .map(|x| {\n        //~^ map_flatten\n\n            if x == 1 {\n                Ok(x)\n            } else {\n                Err(0)\n            }\n        })\n        .flatten();\n\n    let result: Result<i32, i32> = Ok(2);\n    fn do_something() { }\n    let _: Result<i32, i32> = result\n        .map(|res| {\n        //~^ map_flatten\n\n            if res > 0 {\n                do_something();\n                Ok(res)\n            } else {\n                Err(0)\n            }\n        })\n        .flatten();\n\n    let _: Vec<_> = vec![5_i8; 6]\n        .into_iter()\n        .map(|some_value| {\n        //~^ map_flatten\n\n            if some_value > 3 {\n                Some(some_value)\n            } else {\n                None\n            }\n        })\n        .flatten()\n        .collect();\n}\n\n#[allow(clippy::useless_vec)]\nfn no_suggestion_if_comments_present() {\n    let vec = vec![vec![1, 2, 3]];\n    let _ = vec\n        .iter()\n        // a lovely comment explaining the code in very detail\n        .map(|x| x.iter())\n        //~^ map_flatten\n        // the answer to life, the universe and everything could be here\n        .flatten();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/map_flatten.stderr",
    "content": "error: called `map(..).flatten()` on `Option`\n  --> tests/ui/map_flatten.rs:8:10\n   |\nLL |           .map(|x| {\n   |  __________^\n...  |\nLL | |         })\nLL | |         .flatten();\n   | |__________________^\n   |\n   = note: `-D clippy::map-flatten` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_flatten)]`\nhelp: try replacing `map` with `and_then` and remove the `.flatten()`\n   |\nLL ~         .and_then(|x| {\nLL +\nLL + \nLL + \nLL +             if x <= 5 {\nLL +                 Some(x)\nLL +             } else {\nLL +                 None\nLL +             }\nLL ~         });\n   |\n\nerror: called `map(..).flatten()` on `Result`\n  --> tests/ui/map_flatten.rs:21:10\n   |\nLL |           .map(|x| {\n   |  __________^\nLL | |\nLL | |\nLL | |             if x == 1 {\n...  |\nLL | |         })\nLL | |         .flatten();\n   | |__________________^\n   |\nhelp: try replacing `map` with `and_then` and remove the `.flatten()`\n   |\nLL ~         .and_then(|x| {\nLL +\nLL + \nLL +             if x == 1 {\nLL +                 Ok(x)\nLL +             } else {\nLL +                 Err(0)\nLL +             }\nLL ~         });\n   |\n\nerror: called `map(..).flatten()` on `Result`\n  --> tests/ui/map_flatten.rs:35:10\n   |\nLL |           .map(|res| {\n   |  __________^\nLL | |\nLL | |\nLL | |             if res > 0 {\n...  |\nLL | |         })\nLL | |         .flatten();\n   | |__________________^\n   |\nhelp: try replacing `map` with `and_then` and remove the `.flatten()`\n   |\nLL ~         .and_then(|res| {\nLL +\nLL + \nLL +             if res > 0 {\nLL +                 do_something();\nLL +                 Ok(res)\nLL +             } else {\nLL +                 Err(0)\nLL +             }\nLL ~         });\n   |\n\nerror: called `map(..).flatten()` on `Iterator`\n  --> tests/ui/map_flatten.rs:49:10\n   |\nLL |           .map(|some_value| {\n   |  __________^\nLL | |\nLL | |\nLL | |             if some_value > 3 {\n...  |\nLL | |         })\nLL | |         .flatten()\n   | |__________________^\n   |\nhelp: try replacing `map` with `filter_map` and remove the `.flatten()`\n   |\nLL ~         .filter_map(|some_value| {\nLL +\nLL + \nLL +             if some_value > 3 {\nLL +                 Some(some_value)\nLL +             } else {\nLL +                 None\nLL +             }\nLL +         })\n   |\n\nerror: called `map(..).flatten()` on `Iterator`\n  --> tests/ui/map_flatten.rs:68:10\n   |\nLL |           .map(|x| x.iter())\n   |  __________^\n...  |\nLL | |         .flatten();\n   | |__________________^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| x.iter())`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_flatten_fixable.fixed",
    "content": "#![allow(\n    clippy::let_underscore_untyped,\n    clippy::missing_docs_in_private_items,\n    clippy::map_identity,\n    clippy::redundant_closure,\n    clippy::unnecessary_wraps\n)]\n\nfn main() {\n    // mapping to Option on Iterator\n    fn option_id(x: i8) -> Option<i8> {\n        Some(x)\n    }\n    let option_id_ref: fn(i8) -> Option<i8> = option_id;\n    let option_id_closure = |x| Some(x);\n    let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id).collect();\n    //~^ map_flatten\n    let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id_ref).collect();\n    //~^ map_flatten\n    let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(option_id_closure).collect();\n    //~^ map_flatten\n    let _: Vec<_> = vec![5_i8; 6].into_iter().filter_map(|x| x.checked_add(1)).collect();\n    //~^ map_flatten\n\n    // mapping to Iterator on Iterator\n    let _: Vec<_> = vec![5_i8; 6].into_iter().flat_map(|x| 0..x).collect();\n    //~^ map_flatten\n\n    // mapping to Option on Option\n    let _: Option<_> = (Some(Some(1))).and_then(|x| x);\n    //~^ map_flatten\n\n    // mapping to Result on Result\n    let _: Result<_, &str> = (Ok(Ok(1))).and_then(|x| x);\n    //~^ map_flatten\n\n    issue8734();\n    issue8878();\n}\n\nfn issue8734() {\n    let _ = [0u8, 1, 2, 3]\n        .into_iter()\n        .flat_map(|n| match n {\n            //~^ map_flatten\n            1 => [n\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)],\n            n => [n],\n        });\n}\n\n#[allow(clippy::bind_instead_of_map)] // map + flatten will be suggested to `and_then`, but afterwards `map` is suggested again\n#[rustfmt::skip] // whitespace is important for this one\nfn issue8878() {\n    std::collections::HashMap::<u32, u32>::new()\n        .get(&0)\n        .and_then(|_| {\n        //~^ map_flatten\n// we need some newlines\n// so that the span is big enough\n// for a split output of the diagnostic\n            Some(\"\")\n // whitespace beforehand is important as well\n        });\n}\n"
  },
  {
    "path": "tests/ui/map_flatten_fixable.rs",
    "content": "#![allow(\n    clippy::let_underscore_untyped,\n    clippy::missing_docs_in_private_items,\n    clippy::map_identity,\n    clippy::redundant_closure,\n    clippy::unnecessary_wraps\n)]\n\nfn main() {\n    // mapping to Option on Iterator\n    fn option_id(x: i8) -> Option<i8> {\n        Some(x)\n    }\n    let option_id_ref: fn(i8) -> Option<i8> = option_id;\n    let option_id_closure = |x| Some(x);\n    let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().collect();\n    //~^ map_flatten\n    let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect();\n    //~^ map_flatten\n    let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect();\n    //~^ map_flatten\n    let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect();\n    //~^ map_flatten\n\n    // mapping to Iterator on Iterator\n    let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();\n    //~^ map_flatten\n\n    // mapping to Option on Option\n    let _: Option<_> = (Some(Some(1))).map(|x| x).flatten();\n    //~^ map_flatten\n\n    // mapping to Result on Result\n    let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten();\n    //~^ map_flatten\n\n    issue8734();\n    issue8878();\n}\n\nfn issue8734() {\n    let _ = [0u8, 1, 2, 3]\n        .into_iter()\n        .map(|n| match n {\n            //~^ map_flatten\n            1 => [n\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)\n                .saturating_add(1)],\n            n => [n],\n        })\n        .flatten();\n}\n\n#[allow(clippy::bind_instead_of_map)] // map + flatten will be suggested to `and_then`, but afterwards `map` is suggested again\n#[rustfmt::skip] // whitespace is important for this one\nfn issue8878() {\n    std::collections::HashMap::<u32, u32>::new()\n        .get(&0)\n        .map(|_| {\n        //~^ map_flatten\n// we need some newlines\n// so that the span is big enough\n// for a split output of the diagnostic\n            Some(\"\")\n // whitespace beforehand is important as well\n        })\n        .flatten();\n}\n"
  },
  {
    "path": "tests/ui/map_flatten_fixable.stderr",
    "content": "error: called `map(..).flatten()` on `Iterator`\n  --> tests/ui/map_flatten_fixable.rs:16:47\n   |\nLL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id).flatten().collect();\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id)`\n   |\n   = note: `-D clippy::map-flatten` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_flatten)]`\n\nerror: called `map(..).flatten()` on `Iterator`\n  --> tests/ui/map_flatten_fixable.rs:18:47\n   |\nLL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_ref).flatten().collect();\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_ref)`\n\nerror: called `map(..).flatten()` on `Iterator`\n  --> tests/ui/map_flatten_fixable.rs:20:47\n   |\nLL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(option_id_closure).flatten().collect();\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(option_id_closure)`\n\nerror: called `map(..).flatten()` on `Iterator`\n  --> tests/ui/map_flatten_fixable.rs:22:47\n   |\nLL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| x.checked_add(1)).flatten().collect();\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `filter_map` and remove the `.flatten()`: `filter_map(|x| x.checked_add(1))`\n\nerror: called `map(..).flatten()` on `Iterator`\n  --> tests/ui/map_flatten_fixable.rs:26:47\n   |\nLL |     let _: Vec<_> = vec![5_i8; 6].into_iter().map(|x| 0..x).flatten().collect();\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `flat_map` and remove the `.flatten()`: `flat_map(|x| 0..x)`\n\nerror: called `map(..).flatten()` on `Option`\n  --> tests/ui/map_flatten_fixable.rs:30:40\n   |\nLL |     let _: Option<_> = (Some(Some(1))).map(|x| x).flatten();\n   |                                        ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)`\n\nerror: called `map(..).flatten()` on `Result`\n  --> tests/ui/map_flatten_fixable.rs:34:42\n   |\nLL |     let _: Result<_, &str> = (Ok(Ok(1))).map(|x| x).flatten();\n   |                                          ^^^^^^^^^^^^^^^^^^^^ help: try replacing `map` with `and_then` and remove the `.flatten()`: `and_then(|x| x)`\n\nerror: called `map(..).flatten()` on `Iterator`\n  --> tests/ui/map_flatten_fixable.rs:44:10\n   |\nLL |           .map(|n| match n {\n   |  __________^\nLL | |\nLL | |             1 => [n\nLL | |                 .saturating_add(1)\n...  |\nLL | |         })\nLL | |         .flatten();\n   | |__________________^\n   |\nhelp: try replacing `map` with `flat_map` and remove the `.flatten()`\n   |\nLL ~         .flat_map(|n| match n {\nLL +\nLL +             1 => [n\nLL +                 .saturating_add(1)\nLL +                 .saturating_add(1)\nLL +                 .saturating_add(1)\nLL +                 .saturating_add(1)\nLL +                 .saturating_add(1)\nLL +                 .saturating_add(1)\nLL +                 .saturating_add(1)\nLL +                 .saturating_add(1)],\nLL +             n => [n],\nLL ~         });\n   |\n\nerror: called `map(..).flatten()` on `Option`\n  --> tests/ui/map_flatten_fixable.rs:65:10\n   |\nLL |           .map(|_| {\n   |  __________^\n...  |\nLL | |         })\nLL | |         .flatten();\n   | |__________________^\n   |\nhelp: try replacing `map` with `and_then` and remove the `.flatten()`\n   |\nLL ~         .and_then(|_| {\nLL +\nLL + // we need some newlines\nLL + // so that the span is big enough\nLL + // for a split output of the diagnostic\nLL +             Some(\"\")\nLL +  // whitespace beforehand is important as well\nLL ~         });\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_identity.fixed",
    "content": "//@require-annotations-for-level: ERROR\n#![warn(clippy::map_identity)]\n#![allow(clippy::needless_return, clippy::disallowed_names)]\n\nfn main() {\n    let x: [u16; 3] = [1, 2, 3];\n    // should lint\n    let _: Vec<_> = x.iter().map(not_identity).collect();\n    //~^ map_identity\n    let _: Vec<_> = x.iter().collect();\n    //~^ map_identity\n    //~| map_identity\n    let _: Option<u8> = Some(3);\n    //~^ map_identity\n    let _: Result<i8, f32> = Ok(-3);\n    // should not lint\n    let _: Vec<_> = x.iter().map(|x| 2 * x).collect();\n    let _: Vec<_> = x.iter().map(not_identity).map(|x| return x - 4).collect();\n    let _: Option<u8> = None.map(|x: u8| x - 1);\n    let _: Result<i8, f32> = Err(2.3).map(|x: i8| {\n        return x + 3;\n    });\n    let _: Result<u32, u32> = Ok(1);\n    //~^ map_identity\n    let _: Result<u32, u32> = Ok(1).map_err(|a: u32| a * 42);\n    // : u32 guides type inference\n    let _ = Ok(1).map_err(|a: u32| a);\n    let _ = Ok(1).map_err(std::convert::identity::<u32>);\n}\n\nfn issue7189() {\n    // should lint\n    let x = [(1, 2), (3, 4)].iter().copied();\n    let _ = x.clone();\n    //~^ map_identity\n    let _ = x.clone();\n    let _ = x.clone();\n    //~^ map_identity\n\n    let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))].iter().copied();\n    let _ = y.clone();\n    //~^ map_identity\n\n    // should not lint\n    let _ = x.clone().map(|(x, y)| (x, y, y));\n    let _ = x.clone().map(|(x, _y)| (x,));\n    let _ = x.clone().map(|(x, _)| (x,));\n    let _ = x.clone().map(|(x, ..)| (x,));\n    let _ = y.clone().map(|(x, y, (z, _))| (x, y, (z, z)));\n    let _ = y\n        .clone()\n        .map(|(x, y, (z, _)): (i32, i32, (i32, (i32,)))| (x, y, (z, z)));\n    let _ = y\n        .clone()\n        .map(|(x, y, (z, (w,))): (i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));\n}\n\nfn not_identity(x: &u16) -> u16 {\n    *x\n}\n\nfn issue11764() {\n    let x = [(1, 2), (3, 4)];\n    // don't lint: this is an `Iterator<Item = &(i32, i32)>`\n    // match ergonomics makes the binding patterns into references\n    // so that its type changes to `Iterator<Item = (&i32, &i32)>`\n    let _ = x.iter().map(|(x, y)| (x, y));\n    let _ = x.iter().map(|x| (x.0,)).map(|(x,)| x);\n\n    // no match ergonomics for `(i32, i32)`\n    let _ = x.iter().copied();\n    //~^ map_identity\n}\n\nfn issue13904() {\n    // lint, but there's a catch:\n    // when we remove the `.map()`, `it.next()` would require `it` to be mutable\n    // therefore, include that in the suggestion as well\n    let mut it = [1, 2, 3].into_iter();\n    let _ = it.next();\n    //~^ map_identity\n    //~| HELP: remove the call to `map`, and make `it` mutable\n\n    // lint\n    let mut index = [1, 2, 3].into_iter();\n    let mut subindex = (index.by_ref().take(3), 42);\n    let _ = subindex.0.next();\n    //~^ map_identity\n    //~| HELP: remove the call to `map`, and make `subindex` mutable\n\n    // lint\n    #[allow(unused_mut)]\n    let mut it = [1, 2, 3].into_iter();\n    let _ = it.next();\n    //~^ map_identity\n    //~| HELP: remove the call to `map`\n\n    // lint\n    let it = [1, 2, 3].into_iter();\n    let _ = { it }.next();\n    //~^ map_identity\n    //~| HELP: remove the call to `map`\n}\n\n// same as `issue11764`, but for arrays\nfn issue15198() {\n    let x = [[1, 2], [3, 4]];\n    // don't lint: `&[i32; 2]` becomes `[&i32; 2]`\n    let _ = x.iter().map(|[x, y]| [x, y]);\n    let _ = x.iter().map(|x| [x[0]]).map(|[x]| x);\n\n    // no match ergonomics for `[i32, i32]`\n    let _ = x.iter().copied();\n    //~^ map_identity\n}\n\nmod foo {\n    #[derive(Clone, Copy)]\n    pub struct Foo {\n        pub foo: u8,\n        pub bar: u8,\n    }\n\n    #[derive(Clone, Copy)]\n    pub struct Foo2(pub u8, pub u8);\n}\nuse foo::{Foo, Foo2};\n\nstruct Bar {\n    foo: u8,\n    bar: u8,\n}\n\nstruct Bar2(u8, u8);\n\nfn structs() {\n    let x = [Foo { foo: 0, bar: 0 }];\n\n    let _ = x.into_iter();\n    //~^ map_identity\n\n    // still lint when different paths are used for the same struct\n    let _ = x.into_iter();\n    //~^ map_identity\n\n    // don't lint: same fields but different structs\n    let _ = x.into_iter().map(|Foo { foo, bar }| Bar { foo, bar });\n\n    // still lint with redundant field names\n    #[allow(clippy::redundant_field_names)]\n    let _ = x.into_iter();\n    //~^ map_identity\n\n    // still lint with field order change\n    let _ = x.into_iter();\n    //~^ map_identity\n\n    // don't lint: switched field assignment\n    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: bar, bar: foo });\n}\n\nfn tuple_structs() {\n    let x = [Foo2(0, 0)];\n\n    let _ = x.into_iter();\n    //~^ map_identity\n\n    // still lint when different paths are used for the same struct\n    let _ = x.into_iter();\n    //~^ map_identity\n\n    // don't lint: same fields but different structs\n    let _ = x.into_iter().map(|Foo2(foo, bar)| Bar2(foo, bar));\n\n    // don't lint: switched field assignment\n    let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(bar, foo));\n}\n"
  },
  {
    "path": "tests/ui/map_identity.rs",
    "content": "//@require-annotations-for-level: ERROR\n#![warn(clippy::map_identity)]\n#![allow(clippy::needless_return, clippy::disallowed_names)]\n\nfn main() {\n    let x: [u16; 3] = [1, 2, 3];\n    // should lint\n    let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect();\n    //~^ map_identity\n    let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect();\n    //~^ map_identity\n    //~| map_identity\n    let _: Option<u8> = Some(3).map(|x| x);\n    //~^ map_identity\n    let _: Result<i8, f32> = Ok(-3).map(|x| {\n        //~^ map_identity\n        return x;\n    });\n    // should not lint\n    let _: Vec<_> = x.iter().map(|x| 2 * x).collect();\n    let _: Vec<_> = x.iter().map(not_identity).map(|x| return x - 4).collect();\n    let _: Option<u8> = None.map(|x: u8| x - 1);\n    let _: Result<i8, f32> = Err(2.3).map(|x: i8| {\n        return x + 3;\n    });\n    let _: Result<u32, u32> = Ok(1).map_err(|a| a);\n    //~^ map_identity\n    let _: Result<u32, u32> = Ok(1).map_err(|a: u32| a * 42);\n    // : u32 guides type inference\n    let _ = Ok(1).map_err(|a: u32| a);\n    let _ = Ok(1).map_err(std::convert::identity::<u32>);\n}\n\nfn issue7189() {\n    // should lint\n    let x = [(1, 2), (3, 4)].iter().copied();\n    let _ = x.clone().map(|(x, y)| (x, y));\n    //~^ map_identity\n    let _ = x.clone().map(|(x, y)| {\n        //~^ map_identity\n        return (x, y);\n    });\n    let _ = x.clone().map(|(x, y)| return (x, y));\n    //~^ map_identity\n\n    let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))].iter().copied();\n    let _ = y.clone().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));\n    //~^ map_identity\n\n    // should not lint\n    let _ = x.clone().map(|(x, y)| (x, y, y));\n    let _ = x.clone().map(|(x, _y)| (x,));\n    let _ = x.clone().map(|(x, _)| (x,));\n    let _ = x.clone().map(|(x, ..)| (x,));\n    let _ = y.clone().map(|(x, y, (z, _))| (x, y, (z, z)));\n    let _ = y\n        .clone()\n        .map(|(x, y, (z, _)): (i32, i32, (i32, (i32,)))| (x, y, (z, z)));\n    let _ = y\n        .clone()\n        .map(|(x, y, (z, (w,))): (i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));\n}\n\nfn not_identity(x: &u16) -> u16 {\n    *x\n}\n\nfn issue11764() {\n    let x = [(1, 2), (3, 4)];\n    // don't lint: this is an `Iterator<Item = &(i32, i32)>`\n    // match ergonomics makes the binding patterns into references\n    // so that its type changes to `Iterator<Item = (&i32, &i32)>`\n    let _ = x.iter().map(|(x, y)| (x, y));\n    let _ = x.iter().map(|x| (x.0,)).map(|(x,)| x);\n\n    // no match ergonomics for `(i32, i32)`\n    let _ = x.iter().copied().map(|(x, y)| (x, y));\n    //~^ map_identity\n}\n\nfn issue13904() {\n    // lint, but there's a catch:\n    // when we remove the `.map()`, `it.next()` would require `it` to be mutable\n    // therefore, include that in the suggestion as well\n    let it = [1, 2, 3].into_iter();\n    let _ = it.map(|x| x).next();\n    //~^ map_identity\n    //~| HELP: remove the call to `map`, and make `it` mutable\n\n    // lint\n    let mut index = [1, 2, 3].into_iter();\n    let subindex = (index.by_ref().take(3), 42);\n    let _ = subindex.0.map(|n| n).next();\n    //~^ map_identity\n    //~| HELP: remove the call to `map`, and make `subindex` mutable\n\n    // lint\n    #[allow(unused_mut)]\n    let mut it = [1, 2, 3].into_iter();\n    let _ = it.map(|x| x).next();\n    //~^ map_identity\n    //~| HELP: remove the call to `map`\n\n    // lint\n    let it = [1, 2, 3].into_iter();\n    let _ = { it }.map(|x| x).next();\n    //~^ map_identity\n    //~| HELP: remove the call to `map`\n}\n\n// same as `issue11764`, but for arrays\nfn issue15198() {\n    let x = [[1, 2], [3, 4]];\n    // don't lint: `&[i32; 2]` becomes `[&i32; 2]`\n    let _ = x.iter().map(|[x, y]| [x, y]);\n    let _ = x.iter().map(|x| [x[0]]).map(|[x]| x);\n\n    // no match ergonomics for `[i32, i32]`\n    let _ = x.iter().copied().map(|[x, y]| [x, y]);\n    //~^ map_identity\n}\n\nmod foo {\n    #[derive(Clone, Copy)]\n    pub struct Foo {\n        pub foo: u8,\n        pub bar: u8,\n    }\n\n    #[derive(Clone, Copy)]\n    pub struct Foo2(pub u8, pub u8);\n}\nuse foo::{Foo, Foo2};\n\nstruct Bar {\n    foo: u8,\n    bar: u8,\n}\n\nstruct Bar2(u8, u8);\n\nfn structs() {\n    let x = [Foo { foo: 0, bar: 0 }];\n\n    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo, bar });\n    //~^ map_identity\n\n    // still lint when different paths are used for the same struct\n    let _ = x.into_iter().map(|Foo { foo, bar }| foo::Foo { foo, bar });\n    //~^ map_identity\n\n    // don't lint: same fields but different structs\n    let _ = x.into_iter().map(|Foo { foo, bar }| Bar { foo, bar });\n\n    // still lint with redundant field names\n    #[allow(clippy::redundant_field_names)]\n    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: foo, bar: bar });\n    //~^ map_identity\n\n    // still lint with field order change\n    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { bar, foo });\n    //~^ map_identity\n\n    // don't lint: switched field assignment\n    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: bar, bar: foo });\n}\n\nfn tuple_structs() {\n    let x = [Foo2(0, 0)];\n\n    let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(foo, bar));\n    //~^ map_identity\n\n    // still lint when different paths are used for the same struct\n    let _ = x.into_iter().map(|Foo2(foo, bar)| foo::Foo2(foo, bar));\n    //~^ map_identity\n\n    // don't lint: same fields but different structs\n    let _ = x.into_iter().map(|Foo2(foo, bar)| Bar2(foo, bar));\n\n    // don't lint: switched field assignment\n    let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(bar, foo));\n}\n"
  },
  {
    "path": "tests/ui/map_identity.stderr",
    "content": "error: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:8:47\n   |\nLL |     let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect();\n   |                                               ^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n   |\n   = note: `-D clippy::map-identity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_identity)]`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:10:57\n   |\nLL |     let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect();\n   |                                                         ^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:10:29\n   |\nLL |     let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:13:32\n   |\nLL |     let _: Option<u8> = Some(3).map(|x| x);\n   |                                ^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:15:36\n   |\nLL |       let _: Result<i8, f32> = Ok(-3).map(|x| {\n   |  ____________________________________^\nLL | |\nLL | |         return x;\nLL | |     });\n   | |______^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:26:36\n   |\nLL |     let _: Result<u32, u32> = Ok(1).map_err(|a| a);\n   |                                    ^^^^^^^^^^^^^^^ help: remove the call to `map_err`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:37:22\n   |\nLL |     let _ = x.clone().map(|(x, y)| (x, y));\n   |                      ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:39:22\n   |\nLL |       let _ = x.clone().map(|(x, y)| {\n   |  ______________________^\nLL | |\nLL | |         return (x, y);\nLL | |     });\n   | |______^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:43:22\n   |\nLL |     let _ = x.clone().map(|(x, y)| return (x, y));\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:47:22\n   |\nLL |     let _ = y.clone().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:77:30\n   |\nLL |     let _ = x.iter().copied().map(|(x, y)| (x, y));\n   |                              ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:86:15\n   |\nLL |     let _ = it.map(|x| x).next();\n   |               ^^^^^^^^^^^\n   |\nhelp: remove the call to `map`, and make `it` mutable\n   |\nLL ~     let mut it = [1, 2, 3].into_iter();\nLL ~     let _ = it.next();\n   |\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:93:23\n   |\nLL |     let _ = subindex.0.map(|n| n).next();\n   |                       ^^^^^^^^^^^\n   |\nhelp: remove the call to `map`, and make `subindex` mutable\n   |\nLL ~     let mut subindex = (index.by_ref().take(3), 42);\nLL ~     let _ = subindex.0.next();\n   |\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:100:15\n   |\nLL |     let _ = it.map(|x| x).next();\n   |               ^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:106:19\n   |\nLL |     let _ = { it }.map(|x| x).next();\n   |                   ^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:119:30\n   |\nLL |     let _ = x.iter().copied().map(|[x, y]| [x, y]);\n   |                              ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:145:26\n   |\nLL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo, bar });\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:149:26\n   |\nLL |     let _ = x.into_iter().map(|Foo { foo, bar }| foo::Foo { foo, bar });\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:157:26\n   |\nLL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: foo, bar: bar });\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:161:26\n   |\nLL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { bar, foo });\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:171:26\n   |\nLL |     let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(foo, bar));\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: unnecessary map of the identity function\n  --> tests/ui/map_identity.rs:175:26\n   |\nLL |     let _ = x.into_iter().map(|Foo2(foo, bar)| foo::Foo2(foo, bar));\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`\n\nerror: aborting due to 22 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_unit_fn.rs",
    "content": "//@ check-pass\n\n#![allow(unused)]\nstruct Mappable;\n\nimpl Mappable {\n    pub fn map(&self) {}\n}\n\nfn main() {\n    let m = Mappable {};\n    m.map();\n}\n"
  },
  {
    "path": "tests/ui/map_unwrap_or.rs",
    "content": "//@aux-build:option_helpers.rs\n//@no-rustfix\n#![warn(clippy::map_unwrap_or)]\n#![allow(clippy::uninlined_format_args, clippy::unnecessary_lazy_evaluations)]\n\n#[macro_use]\nextern crate option_helpers;\n\nuse std::collections::HashMap;\n\n#[rustfmt::skip]\nfn option_methods() {\n    let opt = Some(1);\n\n    // Check for `option.map(_).unwrap_or(_)` use.\n    // Single line case.\n    let _ = opt.map(|x| x + 1)\n    //~^ map_unwrap_or\n        // Should lint even though this call is on a separate line.\n        .unwrap_or(0);\n    // Multi-line cases.\n    let _ = opt.map(|x| {\n    //~^ map_unwrap_or\n        x + 1\n    }\n    ).unwrap_or(0);\n    let _ = opt.map(|x| x + 1)\n    //~^ map_unwrap_or\n        .unwrap_or({\n            0\n        });\n    // Single line `map(f).unwrap_or(None)` case.\n    let _ = opt.map(|x| Some(x + 1)).unwrap_or(None);\n    //~^ map_unwrap_or\n    // Multi-line `map(f).unwrap_or(None)` cases.\n    let _ = opt.map(|x| {\n    //~^ map_unwrap_or\n        Some(x + 1)\n    }\n    ).unwrap_or(None);\n    let _ = opt\n    //~^ map_unwrap_or\n        .map(|x| Some(x + 1))\n        .unwrap_or(None);\n    // macro case\n    let _ = opt_map!(opt, |x| x + 1).unwrap_or(0); // should not lint\n\n    // Should not lint if not copyable\n    let id: String = \"identifier\".to_string();\n    let _ = Some(\"prefix\").map(|p| format!(\"{}.{}\", p, id)).unwrap_or(id);\n    // ...but DO lint if the `unwrap_or` argument is not used in the `map`\n    let id: String = \"identifier\".to_string();\n    let _ = Some(\"prefix\").map(|p| format!(\"{}.\", p)).unwrap_or(id);\n    //~^ map_unwrap_or\n\n    // Check for `option.map(_).unwrap_or_else(_)` use.\n    // Multi-line cases.\n    let _ = opt.map(|x| {\n    //~^ map_unwrap_or\n        x + 1\n    }\n    ).unwrap_or_else(|| 0);\n    let _ = opt.map(|x| x + 1)\n    //~^ map_unwrap_or\n        .unwrap_or_else(||\n            0\n        );\n\n    // Check for `map(f).unwrap_or(false)` use.\n    let _ = opt.map(|x| x > 5).unwrap_or(false);\n    //~^ map_unwrap_or\n\n}\n\n#[rustfmt::skip]\nfn result_methods() {\n    let res: Result<i32, ()> = Ok(1);\n\n    // Check for `result.map(_).unwrap_or_else(_)` use.\n    // multi line cases\n    let _ = res.map(|x| {\n    //~^ map_unwrap_or\n        x + 1\n    }\n    ).unwrap_or_else(|_e| 0);\n    let _ = res.map(|x| x + 1)\n    //~^ map_unwrap_or\n        .unwrap_or_else(|_e| {\n            0\n        });\n    // macro case\n    let _ = opt_map!(res, |x| x + 1).unwrap_or_else(|_e| 0); // should not lint\n}\n\nfn main() {}\n\n#[clippy::msrv = \"1.40\"]\nfn msrv_1_40() {\n    let res: Result<i32, ()> = Ok(1);\n\n    let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0);\n}\n\n#[clippy::msrv = \"1.41\"]\nfn msrv_1_41() {\n    let res: Result<i32, ()> = Ok(1);\n\n    let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0);\n    //~^ map_unwrap_or\n}\n\n#[clippy::msrv = \"1.69\"]\nfn msrv_1_69() {\n    let opt: Option<i32> = Some(1);\n\n    let _ = opt.map(|x| x > 5).unwrap_or(false);\n    //~^ map_unwrap_or\n}\n\n#[clippy::msrv = \"1.70\"]\nfn msrv_1_70() {\n    let opt: Option<i32> = Some(1);\n\n    let _ = opt.map(|x| x > 5).unwrap_or(false);\n    //~^ map_unwrap_or\n}\n\nmod issue_10579 {\n    // Different variations of the same issue.\n    fn v1() {\n        let x = vec![1, 2, 3, 0];\n        let y = x.strip_suffix(&[0]).map(|s| s.to_vec()).unwrap_or(x);\n        println!(\"{y:?}\");\n    }\n    fn v2() {\n        let x = vec![1, 2, 3, 0];\n        let y = Some(()).map(|_| x.to_vec()).unwrap_or(x);\n        println!(\"{y:?}\");\n    }\n    fn v3() {\n        let x = vec![1, 2, 3, 0];\n        let xref = &x;\n        let y = Some(()).map(|_| xref.to_vec()).unwrap_or(x);\n        println!(\"{y:?}\");\n    }\n    fn v4() {\n        struct VecInStruct {\n            v: Vec<u8>,\n        }\n        let s = VecInStruct { v: vec![1, 2, 3, 0] };\n\n        let y = Some(()).map(|_| s.v.clone()).unwrap_or(s.v);\n        println!(\"{y:?}\");\n    }\n}\n\nfn issue15752() {\n    struct Foo<'a>(&'a [u32]);\n\n    let x = Some(Foo(&[1, 2, 3]));\n    x.map(|y| y.0).unwrap_or(&[]);\n    //~^ map_unwrap_or\n}\n"
  },
  {
    "path": "tests/ui/map_unwrap_or.stderr",
    "content": "error: called `map(<f>).unwrap_or(<a>)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:17:13\n   |\nLL |       let _ = opt.map(|x| x + 1)\n   |  _____________^\n...  |\nLL | |         .unwrap_or(0);\n   | |_____________________^\n   |\n   = note: `-D clippy::map-unwrap-or` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_unwrap_or)]`\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL -     let _ = opt.map(|x| x + 1)\nLL -\nLL -         // Should lint even though this call is on a separate line.\nLL -         .unwrap_or(0);\nLL +     let _ = opt.map_or(0, |x| x + 1);\n   |\n\nerror: called `map(<f>).unwrap_or(<a>)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:22:13\n   |\nLL |       let _ = opt.map(|x| {\n   |  _____________^\nLL | |\nLL | |         x + 1\nLL | |     }\nLL | |     ).unwrap_or(0);\n   | |__________________^\n   |\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL ~     let _ = opt.map_or(0, |x| {\nLL |\nLL |         x + 1\nLL |     }\nLL ~     );\n   |\n\nerror: called `map(<f>).unwrap_or(<a>)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:27:13\n   |\nLL |       let _ = opt.map(|x| x + 1)\n   |  _____________^\nLL | |\nLL | |         .unwrap_or({\nLL | |             0\nLL | |         });\n   | |__________^\n   |\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL ~     let _ = opt.map_or({\nLL +             0\nLL ~         }, |x| x + 1);\n   |\n\nerror: called `map(<f>).unwrap_or(None)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:33:13\n   |\nLL |     let _ = opt.map(|x| Some(x + 1)).unwrap_or(None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `and_then(<f>)` instead\n   |\nLL -     let _ = opt.map(|x| Some(x + 1)).unwrap_or(None);\nLL +     let _ = opt.and_then(|x| Some(x + 1));\n   |\n\nerror: called `map(<f>).unwrap_or(None)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:36:13\n   |\nLL |       let _ = opt.map(|x| {\n   |  _____________^\nLL | |\nLL | |         Some(x + 1)\nLL | |     }\nLL | |     ).unwrap_or(None);\n   | |_____________________^\n   |\nhelp: use `and_then(<f>)` instead\n   |\nLL ~     let _ = opt.and_then(|x| {\nLL |\nLL |         Some(x + 1)\nLL |     }\nLL ~     );\n   |\n\nerror: called `map(<f>).unwrap_or(None)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:41:13\n   |\nLL |       let _ = opt\n   |  _____________^\nLL | |\nLL | |         .map(|x| Some(x + 1))\nLL | |         .unwrap_or(None);\n   | |________________________^\n   |\nhelp: use `and_then(<f>)` instead\n   |\nLL -         .map(|x| Some(x + 1))\nLL -         .unwrap_or(None);\nLL +         .and_then(|x| Some(x + 1));\n   |\n\nerror: called `map(<f>).unwrap_or(<a>)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:53:13\n   |\nLL |     let _ = Some(\"prefix\").map(|p| format!(\"{}.\", p)).unwrap_or(id);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL -     let _ = Some(\"prefix\").map(|p| format!(\"{}.\", p)).unwrap_or(id);\nLL +     let _ = Some(\"prefix\").map_or(id, |p| format!(\"{}.\", p));\n   |\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:58:13\n   |\nLL |       let _ = opt.map(|x| {\n   |  _____________^\nLL | |\nLL | |         x + 1\nLL | |     }\nLL | |     ).unwrap_or_else(|| 0);\n   | |__________________________^\n   |\nhelp: try\n   |\nLL ~     let _ = opt.map_or_else(|| 0, |x| {\nLL +\nLL +         x + 1\nLL ~     });\n   |\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:63:13\n   |\nLL |       let _ = opt.map(|x| x + 1)\n   |  _____________^\nLL | |\nLL | |         .unwrap_or_else(||\nLL | |             0\nLL | |         );\n   | |_________^\n   |\nhelp: try\n   |\nLL ~     let _ = opt.map_or_else(||\nLL ~             0, |x| x + 1);\n   |\n\nerror: called `map(<f>).unwrap_or(false)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:70:13\n   |\nLL |     let _ = opt.map(|x| x > 5).unwrap_or(false);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and(<f>)` instead\n   |\nLL -     let _ = opt.map(|x| x > 5).unwrap_or(false);\nLL +     let _ = opt.is_some_and(|x| x > 5);\n   |\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value\n  --> tests/ui/map_unwrap_or.rs:81:13\n   |\nLL |       let _ = res.map(|x| {\n   |  _____________^\nLL | |\nLL | |         x + 1\nLL | |     }\nLL | |     ).unwrap_or_else(|_e| 0);\n   | |____________________________^\n   |\nhelp: try\n   |\nLL ~     let _ = res.map_or_else(|_e| 0, |x| {\nLL +\nLL +         x + 1\nLL ~     });\n   |\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value\n  --> tests/ui/map_unwrap_or.rs:86:13\n   |\nLL |       let _ = res.map(|x| x + 1)\n   |  _____________^\nLL | |\nLL | |         .unwrap_or_else(|_e| {\nLL | |             0\nLL | |         });\n   | |__________^\n   |\nhelp: try\n   |\nLL ~     let _ = res.map_or_else(|_e| {\nLL +             0\nLL ~         }, |x| x + 1);\n   |\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value\n  --> tests/ui/map_unwrap_or.rs:108:13\n   |\nLL |     let _ = res.map(|x| x + 1).unwrap_or_else(|_e| 0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)`\n\nerror: called `map(<f>).unwrap_or(<a>)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:116:13\n   |\nLL |     let _ = opt.map(|x| x > 5).unwrap_or(false);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL -     let _ = opt.map(|x| x > 5).unwrap_or(false);\nLL +     let _ = opt.map_or(false, |x| x > 5);\n   |\n\nerror: called `map(<f>).unwrap_or(false)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:124:13\n   |\nLL |     let _ = opt.map(|x| x > 5).unwrap_or(false);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and(<f>)` instead\n   |\nLL -     let _ = opt.map(|x| x > 5).unwrap_or(false);\nLL +     let _ = opt.is_some_and(|x| x > 5);\n   |\n\nerror: called `map(<f>).unwrap_or(<a>)` on an `Option` value\n  --> tests/ui/map_unwrap_or.rs:161:5\n   |\nLL |     x.map(|y| y.0).unwrap_or(&[]);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_unwrap_or_fixable.fixed",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::map_unwrap_or)]\n#![allow(\n    clippy::unnecessary_lazy_evaluations,\n    clippy::manual_is_variant_and,\n    clippy::unnecessary_map_or\n)]\n\n#[macro_use]\nextern crate option_helpers;\n\nuse std::collections::HashMap;\n\n#[rustfmt::skip]\nfn option_methods() {\n    let opt = Some(1);\n\n    // Check for `option.map(_).unwrap_or_else(_)` use.\n    // single line case\n    let _ = opt.map_or_else(|| 0, |x| x + 1);\n\n    // Macro case.\n    // Should not lint.\n    let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0);\n\n    // Issue #4144\n    {\n        let mut frequencies = HashMap::new();\n        let word = \"foo\";\n\n        frequencies\n            .get_mut(word)\n            .map(|count| {\n                *count += 1;\n            })\n            .unwrap_or_else(|| {\n                frequencies.insert(word.to_owned(), 1);\n            });\n    }\n}\n\n#[rustfmt::skip]\nfn result_methods() {\n    let res: Result<i32, ()> = Ok(1);\n\n    // Check for `result.map(_).unwrap_or_else(_)` use.\n    // single line case\n    let _ = res.map_or_else(|_e| 0, |x| x + 1);\n\n    // macro case\n    let _ = opt_map!(res, |x| x + 1).unwrap_or_else(|_e| 0); // should not lint\n}\n\nfn main() {}\n\nfn issue15714() {\n    let o: Option<i32> = Some(3);\n    let r: Result<i32, ()> = Ok(3);\n    println!(\"{}\", o.map_or(3, |y| y + 1));\n    //~^ map_unwrap_or\n    println!(\"{}\", o.map_or_else(|| 3, |y| y + 1));\n    //~^ map_unwrap_or\n    println!(\"{}\", r.map_or(3, |y| y + 1));\n    //~^ map_unwrap_or\n    println!(\"{}\", r.map_or_else(|()| 3, |y| y + 1));\n    //~^ map_unwrap_or\n\n    println!(\"{}\", r.is_ok_and(|y| y == 1));\n    //~^ map_unwrap_or\n}\n\nfn issue15713() {\n    let x = &Some(3);\n    println!(\"{}\", x.map_or(3, |y| y + 1));\n    //~^ map_unwrap_or\n\n    let x: &Result<i32, ()> = &Ok(3);\n    println!(\"{}\", x.map_or(3, |y| y + 1));\n    //~^ map_unwrap_or\n\n    let x = &Some(3);\n    println!(\"{}\", x.map_or_else(|| 3, |y| y + 1));\n    //~^ map_unwrap_or\n\n    let x: &Result<i32, ()> = &Ok(3);\n    println!(\"{}\", x.map_or_else(|_| 3, |y| y + 1));\n    //~^ map_unwrap_or\n}\n"
  },
  {
    "path": "tests/ui/map_unwrap_or_fixable.rs",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::map_unwrap_or)]\n#![allow(\n    clippy::unnecessary_lazy_evaluations,\n    clippy::manual_is_variant_and,\n    clippy::unnecessary_map_or\n)]\n\n#[macro_use]\nextern crate option_helpers;\n\nuse std::collections::HashMap;\n\n#[rustfmt::skip]\nfn option_methods() {\n    let opt = Some(1);\n\n    // Check for `option.map(_).unwrap_or_else(_)` use.\n    // single line case\n    let _ = opt.map(|x| x + 1)\n    //~^ map_unwrap_or\n        // Should lint even though this call is on a separate line.\n        .unwrap_or_else(|| 0);\n\n    // Macro case.\n    // Should not lint.\n    let _ = opt_map!(opt, |x| x + 1).unwrap_or_else(|| 0);\n\n    // Issue #4144\n    {\n        let mut frequencies = HashMap::new();\n        let word = \"foo\";\n\n        frequencies\n            .get_mut(word)\n            .map(|count| {\n                *count += 1;\n            })\n            .unwrap_or_else(|| {\n                frequencies.insert(word.to_owned(), 1);\n            });\n    }\n}\n\n#[rustfmt::skip]\nfn result_methods() {\n    let res: Result<i32, ()> = Ok(1);\n\n    // Check for `result.map(_).unwrap_or_else(_)` use.\n    // single line case\n    let _ = res.map(|x| x + 1)\n    //~^ map_unwrap_or\n        // should lint even though this call is on a separate line\n        .unwrap_or_else(|_e| 0);\n\n    // macro case\n    let _ = opt_map!(res, |x| x + 1).unwrap_or_else(|_e| 0); // should not lint\n}\n\nfn main() {}\n\nfn issue15714() {\n    let o: Option<i32> = Some(3);\n    let r: Result<i32, ()> = Ok(3);\n    println!(\"{}\", o.map(|y| y + 1).unwrap_or(3));\n    //~^ map_unwrap_or\n    println!(\"{}\", o.map(|y| y + 1).unwrap_or_else(|| 3));\n    //~^ map_unwrap_or\n    println!(\"{}\", r.map(|y| y + 1).unwrap_or(3));\n    //~^ map_unwrap_or\n    println!(\"{}\", r.map(|y| y + 1).unwrap_or_else(|()| 3));\n    //~^ map_unwrap_or\n\n    println!(\"{}\", r.map(|y| y == 1).unwrap_or(false));\n    //~^ map_unwrap_or\n}\n\nfn issue15713() {\n    let x = &Some(3);\n    println!(\"{}\", x.map(|y| y + 1).unwrap_or(3));\n    //~^ map_unwrap_or\n\n    let x: &Result<i32, ()> = &Ok(3);\n    println!(\"{}\", x.map(|y| y + 1).unwrap_or(3));\n    //~^ map_unwrap_or\n\n    let x = &Some(3);\n    println!(\"{}\", x.map(|y| y + 1).unwrap_or_else(|| 3));\n    //~^ map_unwrap_or\n\n    let x: &Result<i32, ()> = &Ok(3);\n    println!(\"{}\", x.map(|y| y + 1).unwrap_or_else(|_| 3));\n    //~^ map_unwrap_or\n}\n"
  },
  {
    "path": "tests/ui/map_unwrap_or_fixable.stderr",
    "content": "error: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value\n  --> tests/ui/map_unwrap_or_fixable.rs:21:13\n   |\nLL |       let _ = opt.map(|x| x + 1)\n   |  _____________^\n...  |\nLL | |         .unwrap_or_else(|| 0);\n   | |_____________________________^ help: try: `opt.map_or_else(|| 0, |x| x + 1)`\n   |\n   = note: `-D clippy::map-unwrap-or` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_unwrap_or)]`\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value\n  --> tests/ui/map_unwrap_or_fixable.rs:52:13\n   |\nLL |       let _ = res.map(|x| x + 1)\n   |  _____________^\n...  |\nLL | |         .unwrap_or_else(|_e| 0);\n   | |_______________________________^ help: try: `res.map_or_else(|_e| 0, |x| x + 1)`\n\nerror: called `map(<f>).unwrap_or(<a>)` on an `Option` value\n  --> tests/ui/map_unwrap_or_fixable.rs:66:20\n   |\nLL |     println!(\"{}\", o.map(|y| y + 1).unwrap_or(3));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL -     println!(\"{}\", o.map(|y| y + 1).unwrap_or(3));\nLL +     println!(\"{}\", o.map_or(3, |y| y + 1));\n   |\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value\n  --> tests/ui/map_unwrap_or_fixable.rs:68:20\n   |\nLL |     println!(\"{}\", o.map(|y| y + 1).unwrap_or_else(|| 3));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `o.map_or_else(|| 3, |y| y + 1)`\n\nerror: called `map(<f>).unwrap_or(<a>)` on a `Result` value\n  --> tests/ui/map_unwrap_or_fixable.rs:70:20\n   |\nLL |     println!(\"{}\", r.map(|y| y + 1).unwrap_or(3));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL -     println!(\"{}\", r.map(|y| y + 1).unwrap_or(3));\nLL +     println!(\"{}\", r.map_or(3, |y| y + 1));\n   |\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value\n  --> tests/ui/map_unwrap_or_fixable.rs:72:20\n   |\nLL |     println!(\"{}\", r.map(|y| y + 1).unwrap_or_else(|()| 3));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `r.map_or_else(|()| 3, |y| y + 1)`\n\nerror: called `map(<f>).unwrap_or(false)` on a `Result` value\n  --> tests/ui/map_unwrap_or_fixable.rs:75:20\n   |\nLL |     println!(\"{}\", r.map(|y| y == 1).unwrap_or(false));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_ok_and(<f>)` instead\n   |\nLL -     println!(\"{}\", r.map(|y| y == 1).unwrap_or(false));\nLL +     println!(\"{}\", r.is_ok_and(|y| y == 1));\n   |\n\nerror: called `map(<f>).unwrap_or(<a>)` on an `Option` value\n  --> tests/ui/map_unwrap_or_fixable.rs:81:20\n   |\nLL |     println!(\"{}\", x.map(|y| y + 1).unwrap_or(3));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL -     println!(\"{}\", x.map(|y| y + 1).unwrap_or(3));\nLL +     println!(\"{}\", x.map_or(3, |y| y + 1));\n   |\n\nerror: called `map(<f>).unwrap_or(<a>)` on a `Result` value\n  --> tests/ui/map_unwrap_or_fixable.rs:85:20\n   |\nLL |     println!(\"{}\", x.map(|y| y + 1).unwrap_or(3));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `map_or(<a>, <f>)` instead\n   |\nLL -     println!(\"{}\", x.map(|y| y + 1).unwrap_or(3));\nLL +     println!(\"{}\", x.map_or(3, |y| y + 1));\n   |\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on an `Option` value\n  --> tests/ui/map_unwrap_or_fixable.rs:89:20\n   |\nLL |     println!(\"{}\", x.map(|y| y + 1).unwrap_or_else(|| 3));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map_or_else(|| 3, |y| y + 1)`\n\nerror: called `map(<f>).unwrap_or_else(<g>)` on a `Result` value\n  --> tests/ui/map_unwrap_or_fixable.rs:93:20\n   |\nLL |     println!(\"{}\", x.map(|y| y + 1).unwrap_or_else(|_| 3));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.map_or_else(|_| 3, |y| y + 1)`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_with_unused_argument_over_ranges.fixed",
    "content": "#![allow(\n    unused,\n    clippy::redundant_closure,\n    clippy::reversed_empty_ranges,\n    clippy::identity_op\n)]\n#![warn(clippy::map_with_unused_argument_over_ranges)]\n\nfn do_something() -> usize {\n    todo!()\n}\n\nfn do_something_interesting(x: usize, y: usize) -> usize {\n    todo!()\n}\n\nmacro_rules! r#gen {\n    () => {\n        (0..10).map(|_| do_something());\n    };\n}\n\nfn main() {\n    // These should be raised\n    std::iter::repeat_with(|| do_something()).take(10);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take(10);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take(11);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take(7);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take(8);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_n(3, 10);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| {\n        //~^ map_with_unused_argument_over_ranges\n        let x = 3;\n        x + 2\n    }).take(10);\n    std::iter::repeat_with(|| do_something()).take(10).collect::<Vec<_>>();\n    //~^ map_with_unused_argument_over_ranges\n    let upper = 4;\n    std::iter::repeat_with(|| do_something()).take(upper);\n    //~^ map_with_unused_argument_over_ranges\n    let upper_fn = || 4;\n    std::iter::repeat_with(|| do_something()).take(upper_fn());\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take(upper_fn() + 1);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take(upper_fn() - 2);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take(upper_fn() - 1);\n    //~^ map_with_unused_argument_over_ranges\n    (-3..9).map(|_| do_something());\n    std::iter::repeat_with(|| do_something()).take(0);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take(1);\n    //~^ map_with_unused_argument_over_ranges\n    std::iter::repeat_with(|| do_something()).take((1 << 4) - 0);\n    //~^ map_with_unused_argument_over_ranges\n    // These should not be raised\n    r#gen!();\n    let lower = 2;\n    let lower_fn = || 2;\n    (lower..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled\n    (lower_fn()..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled\n    (lower_fn()..=upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled\n    (0..10).map(|x| do_something_interesting(x, 4)); // Actual map over range\n    \"Foobar\".chars().map(|_| do_something()); // Not a map over range\n    // i128::MAX == 340282366920938463463374607431768211455\n    (0..=340282366920938463463374607431768211455).map(|_: u128| do_something()); // Can't be replaced due to overflow\n}\n\n#[clippy::msrv = \"1.27\"]\nfn msrv_1_27() {\n    (0..10).map(|_| do_something());\n}\n\n#[clippy::msrv = \"1.28\"]\nfn msrv_1_28() {\n    std::iter::repeat_with(|| do_something()).take(10);\n    //~^ map_with_unused_argument_over_ranges\n}\n\n#[clippy::msrv = \"1.81\"]\nfn msrv_1_82() {\n    std::iter::repeat(3).take(10);\n    //~^ map_with_unused_argument_over_ranges\n}\n"
  },
  {
    "path": "tests/ui/map_with_unused_argument_over_ranges.rs",
    "content": "#![allow(\n    unused,\n    clippy::redundant_closure,\n    clippy::reversed_empty_ranges,\n    clippy::identity_op\n)]\n#![warn(clippy::map_with_unused_argument_over_ranges)]\n\nfn do_something() -> usize {\n    todo!()\n}\n\nfn do_something_interesting(x: usize, y: usize) -> usize {\n    todo!()\n}\n\nmacro_rules! r#gen {\n    () => {\n        (0..10).map(|_| do_something());\n    };\n}\n\nfn main() {\n    // These should be raised\n    (0..10).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (0..10).map(|_foo| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (0..=10).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (3..10).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (3..=10).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (0..10).map(|_| 3);\n    //~^ map_with_unused_argument_over_ranges\n    (0..10).map(|_| {\n        //~^ map_with_unused_argument_over_ranges\n        let x = 3;\n        x + 2\n    });\n    (0..10).map(|_| do_something()).collect::<Vec<_>>();\n    //~^ map_with_unused_argument_over_ranges\n    let upper = 4;\n    (0..upper).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    let upper_fn = || 4;\n    (0..upper_fn()).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (0..=upper_fn()).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (2..upper_fn()).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (2..=upper_fn()).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (-3..9).map(|_| do_something());\n    (9..3).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (9..=9).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    (1..=1 << 4).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n    // These should not be raised\n    r#gen!();\n    let lower = 2;\n    let lower_fn = || 2;\n    (lower..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled\n    (lower_fn()..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled\n    (lower_fn()..=upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled\n    (0..10).map(|x| do_something_interesting(x, 4)); // Actual map over range\n    \"Foobar\".chars().map(|_| do_something()); // Not a map over range\n    // i128::MAX == 340282366920938463463374607431768211455\n    (0..=340282366920938463463374607431768211455).map(|_: u128| do_something()); // Can't be replaced due to overflow\n}\n\n#[clippy::msrv = \"1.27\"]\nfn msrv_1_27() {\n    (0..10).map(|_| do_something());\n}\n\n#[clippy::msrv = \"1.28\"]\nfn msrv_1_28() {\n    (0..10).map(|_| do_something());\n    //~^ map_with_unused_argument_over_ranges\n}\n\n#[clippy::msrv = \"1.81\"]\nfn msrv_1_82() {\n    (0..10).map(|_| 3);\n    //~^ map_with_unused_argument_over_ranges\n}\n"
  },
  {
    "path": "tests/ui/map_with_unused_argument_over_ranges.stderr",
    "content": "error: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:25:5\n   |\nLL |     (0..10).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::map-with-unused-argument-over-ranges` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_with_unused_argument_over_ranges)]`\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (0..10).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(10);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:27:5\n   |\nLL |     (0..10).map(|_foo| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (0..10).map(|_foo| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(10);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:29:5\n   |\nLL |     (0..=10).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (0..=10).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(11);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:31:5\n   |\nLL |     (3..10).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (3..10).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(7);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:33:5\n   |\nLL |     (3..=10).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (3..=10).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(8);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:35:5\n   |\nLL |     (0..10).map(|_| 3);\n   |     ^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_n`\n   |\nLL -     (0..10).map(|_| 3);\nLL +     std::iter::repeat_n(3, 10);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:37:5\n   |\nLL | /     (0..10).map(|_| {\nLL | |\nLL | |         let x = 3;\nLL | |         x + 2\nLL | |     });\n   | |______^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL ~     std::iter::repeat_with(|| {\nLL |\nLL |         let x = 3;\nLL |         x + 2\nLL ~     }).take(10);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:42:5\n   |\nLL |     (0..10).map(|_| do_something()).collect::<Vec<_>>();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (0..10).map(|_| do_something()).collect::<Vec<_>>();\nLL +     std::iter::repeat_with(|| do_something()).take(10).collect::<Vec<_>>();\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:45:5\n   |\nLL |     (0..upper).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (0..upper).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(upper);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:48:5\n   |\nLL |     (0..upper_fn()).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (0..upper_fn()).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(upper_fn());\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:50:5\n   |\nLL |     (0..=upper_fn()).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (0..=upper_fn()).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(upper_fn() + 1);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:52:5\n   |\nLL |     (2..upper_fn()).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (2..upper_fn()).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(upper_fn() - 2);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:54:5\n   |\nLL |     (2..=upper_fn()).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (2..=upper_fn()).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(upper_fn() - 1);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:57:5\n   |\nLL |     (9..3).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (9..3).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(0);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:59:5\n   |\nLL |     (9..=9).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (9..=9).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(1);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:61:5\n   |\nLL |     (1..=1 << 4).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (1..=1 << 4).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take((1 << 4) - 0);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:83:5\n   |\nLL |     (0..10).map(|_| do_something());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat_with` and `take`\n   |\nLL -     (0..10).map(|_| do_something());\nLL +     std::iter::repeat_with(|| do_something()).take(10);\n   |\n\nerror: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges.rs:89:5\n   |\nLL |     (0..10).map(|_| 3);\n   |     ^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the explicit range and use `repeat` and `take`\n   |\nLL -     (0..10).map(|_| 3);\nLL +     std::iter::repeat(3).take(10);\n   |\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/map_with_unused_argument_over_ranges_nostd.fixed",
    "content": "#![warn(clippy::map_with_unused_argument_over_ranges)]\n#![no_std]\nextern crate alloc;\nuse alloc::vec::Vec;\n\nfn nostd(v: &mut [i32]) {\n    let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect();\n    //~^ map_with_unused_argument_over_ranges\n}\n"
  },
  {
    "path": "tests/ui/map_with_unused_argument_over_ranges_nostd.rs",
    "content": "#![warn(clippy::map_with_unused_argument_over_ranges)]\n#![no_std]\nextern crate alloc;\nuse alloc::vec::Vec;\n\nfn nostd(v: &mut [i32]) {\n    let _: Vec<_> = (0..10).map(|_| 3 + 1).collect();\n    //~^ map_with_unused_argument_over_ranges\n}\n"
  },
  {
    "path": "tests/ui/map_with_unused_argument_over_ranges_nostd.stderr",
    "content": "error: map of a closure that does not depend on its parameter over a range\n  --> tests/ui/map_with_unused_argument_over_ranges_nostd.rs:7:21\n   |\nLL |     let _: Vec<_> = (0..10).map(|_| 3 + 1).collect();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::map-with-unused-argument-over-ranges` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_with_unused_argument_over_ranges)]`\nhelp: remove the explicit range and use `repeat_n`\n   |\nLL -     let _: Vec<_> = (0..10).map(|_| 3 + 1).collect();\nLL +     let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect();\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/match_as_ref.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::match_as_ref)]\n\nfn match_as_ref() {\n    let owned: Option<()> = None;\n    let borrowed: Option<&()> = owned.as_ref();\n\n    let mut mut_owned: Option<()> = None;\n    let borrow_mut: Option<&mut ()> = mut_owned.as_mut();\n}\n\nmod issue4437 {\n    use std::error::Error;\n    use std::fmt;\n    use std::num::ParseIntError;\n\n    #[derive(Debug)]\n    struct E {\n        source: Option<ParseIntError>,\n    }\n\n    impl Error for E {\n        fn source(&self) -> Option<&(dyn Error + 'static)> {\n            self.source.as_ref().map(|x| x as _)\n        }\n    }\n\n    impl fmt::Display for E {\n        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n            unimplemented!()\n        }\n    }\n}\n\nfn main() {\n    // Don't lint\n    let _ = match Some(0) {\n        #[cfg(feature = \"foo\")]\n        Some(ref x) if *x > 50 => None,\n        Some(ref x) => Some(x),\n        None => None,\n    };\n}\n\nmod issue15691 {\n    use std::ops::{Deref, DerefMut};\n\n    struct A(B);\n    struct B;\n\n    impl Deref for A {\n        type Target = B;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n\n    impl DerefMut for A {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    fn func() {\n        let mut a = Some(A(B));\n        let mut b = Some(B);\n        // Do not lint, we don't have `None => None`\n        let _ = match b {\n            Some(ref mut x) => Some(x),\n            None => a.as_deref_mut(),\n        };\n    }\n}\n\nfn recv_requiring_parens() {\n    struct S;\n\n    impl std::ops::Not for S {\n        type Output = Option<u64>;\n        fn not(self) -> Self::Output {\n            None\n        }\n    }\n\n    let _ = (!S).as_ref();\n}\n\nfn issue15932() {\n    let _: Option<&u32> = Some(0).as_ref();\n\n    let _: Option<&dyn std::fmt::Debug> = Some(0).as_ref().map(|x| x as _);\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            Some($val)\n        };\n    }\n\n    let _: Option<&u32> = test_expr!(42).as_ref();\n}\n"
  },
  {
    "path": "tests/ui/match_as_ref.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::match_as_ref)]\n\nfn match_as_ref() {\n    let owned: Option<()> = None;\n    let borrowed: Option<&()> = match owned {\n        //~^ match_as_ref\n        None => None,\n        Some(ref v) => Some(v),\n    };\n\n    let mut mut_owned: Option<()> = None;\n    let borrow_mut: Option<&mut ()> = match mut_owned {\n        //~^ match_as_ref\n        None => None,\n        Some(ref mut v) => Some(v),\n    };\n}\n\nmod issue4437 {\n    use std::error::Error;\n    use std::fmt;\n    use std::num::ParseIntError;\n\n    #[derive(Debug)]\n    struct E {\n        source: Option<ParseIntError>,\n    }\n\n    impl Error for E {\n        fn source(&self) -> Option<&(dyn Error + 'static)> {\n            match self.source {\n                //~^ match_as_ref\n                Some(ref s) => Some(s),\n                None => None,\n            }\n        }\n    }\n\n    impl fmt::Display for E {\n        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n            unimplemented!()\n        }\n    }\n}\n\nfn main() {\n    // Don't lint\n    let _ = match Some(0) {\n        #[cfg(feature = \"foo\")]\n        Some(ref x) if *x > 50 => None,\n        Some(ref x) => Some(x),\n        None => None,\n    };\n}\n\nmod issue15691 {\n    use std::ops::{Deref, DerefMut};\n\n    struct A(B);\n    struct B;\n\n    impl Deref for A {\n        type Target = B;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n\n    impl DerefMut for A {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    fn func() {\n        let mut a = Some(A(B));\n        let mut b = Some(B);\n        // Do not lint, we don't have `None => None`\n        let _ = match b {\n            Some(ref mut x) => Some(x),\n            None => a.as_deref_mut(),\n        };\n    }\n}\n\nfn recv_requiring_parens() {\n    struct S;\n\n    impl std::ops::Not for S {\n        type Output = Option<u64>;\n        fn not(self) -> Self::Output {\n            None\n        }\n    }\n\n    let _ = match !S {\n        //~^ match_as_ref\n        None => None,\n        Some(ref v) => Some(v),\n    };\n}\n\nfn issue15932() {\n    let _: Option<&u32> = match Some(0) {\n        //~^ match_as_ref\n        None => None,\n        Some(ref mut v) => Some(v),\n    };\n\n    let _: Option<&dyn std::fmt::Debug> = match Some(0) {\n        //~^ match_as_ref\n        None => None,\n        Some(ref mut v) => Some(v),\n    };\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            Some($val)\n        };\n    }\n\n    let _: Option<&u32> = match test_expr!(42) {\n        //~^ match_as_ref\n        None => None,\n        Some(ref v) => Some(v),\n    };\n}\n"
  },
  {
    "path": "tests/ui/match_as_ref.stderr",
    "content": "error: manual implementation of `Option::as_ref`\n  --> tests/ui/match_as_ref.rs:6:33\n   |\nLL |       let borrowed: Option<&()> = match owned {\n   |  _________________________________^\nLL | |\nLL | |         None => None,\nLL | |         Some(ref v) => Some(v),\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::match-as-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_as_ref)]`\nhelp: use `Option::as_ref()` directly\n   |\nLL -     let borrowed: Option<&()> = match owned {\nLL -\nLL -         None => None,\nLL -         Some(ref v) => Some(v),\nLL -     };\nLL +     let borrowed: Option<&()> = owned.as_ref();\n   |\n\nerror: manual implementation of `Option::as_mut`\n  --> tests/ui/match_as_ref.rs:13:39\n   |\nLL |       let borrow_mut: Option<&mut ()> = match mut_owned {\n   |  _______________________________________^\nLL | |\nLL | |         None => None,\nLL | |         Some(ref mut v) => Some(v),\nLL | |     };\n   | |_____^\n   |\nhelp: use `Option::as_mut()` directly\n   |\nLL -     let borrow_mut: Option<&mut ()> = match mut_owned {\nLL -\nLL -         None => None,\nLL -         Some(ref mut v) => Some(v),\nLL -     };\nLL +     let borrow_mut: Option<&mut ()> = mut_owned.as_mut();\n   |\n\nerror: manual implementation of `Option::as_ref`\n  --> tests/ui/match_as_ref.rs:32:13\n   |\nLL | /             match self.source {\nLL | |\nLL | |                 Some(ref s) => Some(s),\nLL | |                 None => None,\nLL | |             }\n   | |_____________^\n   |\nhelp: use `Option::as_ref()` directly\n   |\nLL -             match self.source {\nLL -\nLL -                 Some(ref s) => Some(s),\nLL -                 None => None,\nLL -             }\nLL +             self.source.as_ref().map(|x| x as _)\n   |\n\nerror: manual implementation of `Option::as_ref`\n  --> tests/ui/match_as_ref.rs:97:13\n   |\nLL |       let _ = match !S {\n   |  _____________^\nLL | |\nLL | |         None => None,\nLL | |         Some(ref v) => Some(v),\nLL | |     };\n   | |_____^\n   |\nhelp: use `Option::as_ref()` directly\n   |\nLL -     let _ = match !S {\nLL -\nLL -         None => None,\nLL -         Some(ref v) => Some(v),\nLL -     };\nLL +     let _ = (!S).as_ref();\n   |\n\nerror: manual implementation of `Option::as_mut`\n  --> tests/ui/match_as_ref.rs:105:27\n   |\nLL |       let _: Option<&u32> = match Some(0) {\n   |  ___________________________^\nLL | |\nLL | |         None => None,\nLL | |         Some(ref mut v) => Some(v),\nLL | |     };\n   | |_____^\n   |\n   = note: but the type is coerced to a non-mutable reference, and so `as_ref` can used instead\nhelp: use `Option::as_ref()`\n   |\nLL -     let _: Option<&u32> = match Some(0) {\nLL -\nLL -         None => None,\nLL -         Some(ref mut v) => Some(v),\nLL -     };\nLL +     let _: Option<&u32> = Some(0).as_ref();\n   |\n\nerror: manual implementation of `Option::as_mut`\n  --> tests/ui/match_as_ref.rs:111:43\n   |\nLL |       let _: Option<&dyn std::fmt::Debug> = match Some(0) {\n   |  ___________________________________________^\nLL | |\nLL | |         None => None,\nLL | |         Some(ref mut v) => Some(v),\nLL | |     };\n   | |_____^\n   |\n   = note: but the type is coerced to a non-mutable reference, and so `as_ref` can used instead\nhelp: use `Option::as_ref()`\n   |\nLL -     let _: Option<&dyn std::fmt::Debug> = match Some(0) {\nLL -\nLL -         None => None,\nLL -         Some(ref mut v) => Some(v),\nLL -     };\nLL +     let _: Option<&dyn std::fmt::Debug> = Some(0).as_ref().map(|x| x as _);\n   |\n\nerror: manual implementation of `Option::as_ref`\n  --> tests/ui/match_as_ref.rs:125:27\n   |\nLL |       let _: Option<&u32> = match test_expr!(42) {\n   |  ___________________________^\nLL | |\nLL | |         None => None,\nLL | |         Some(ref v) => Some(v),\nLL | |     };\n   | |_____^\n   |\nhelp: use `Option::as_ref()` directly\n   |\nLL -     let _: Option<&u32> = match test_expr!(42) {\nLL -\nLL -         None => None,\nLL -         Some(ref v) => Some(v),\nLL -     };\nLL +     let _: Option<&u32> = test_expr!(42).as_ref();\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_bool.fixed",
    "content": "#![deny(clippy::match_bool)]\n#![allow(clippy::nonminimal_bool, clippy::eq_op)]\n\nfn match_bool() {\n    let test: bool = true;\n\n    if test { 0 } else { 42 };\n\n    let option = 1;\n    if option == 1 { 1 } else { 0 };\n\n    if !test {\n        println!(\"Noooo!\");\n    };\n\n    if !test {\n        println!(\"Noooo!\");\n    };\n\n    if !(test && test) {\n        println!(\"Noooo!\");\n    };\n\n    if !test {\n        println!(\"Noooo!\");\n    } else {\n        println!(\"Yes!\");\n    };\n\n    // Not linted\n    match option {\n        1..=10 => 1,\n        11..=20 => 2,\n        _ => 3,\n    };\n\n    // Don't lint\n    let _ = match test {\n        #[cfg(feature = \"foo\")]\n        true if option == 5 => 10,\n        true => 0,\n        false => 1,\n    };\n\n    let _ = if test && option == 5 { 10 } else { 1 };\n\n    let _ = if !test && option == 5 { 10 } else { 1 };\n\n    if test && option == 5 { println!(\"Hello\") };\n\n    if !(test && option == 5) { println!(\"Hello\") };\n\n    if !test && option == 5 { println!(\"Hello\") };\n\n    if !(!test && option == 5) { println!(\"Hello\") };\n}\n\nfn issue14099() {\n    if true { 'a: {\n        break 'a;\n    } }\n}\n\nfn issue15351() {\n    let mut d = false;\n    match d {\n        false => println!(\"foo\"),\n        ref mut d => *d = false,\n    }\n\n    match d {\n        false => println!(\"foo\"),\n        e => println!(\"{e}\"),\n    }\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            ($val + 1) > 0\n        };\n    }\n\n    let x = 5;\n    if test_expr!(x) { 1 } else { 0 };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_bool.rs",
    "content": "#![deny(clippy::match_bool)]\n#![allow(clippy::nonminimal_bool, clippy::eq_op)]\n\nfn match_bool() {\n    let test: bool = true;\n\n    match test {\n        //~^ match_bool\n        true => 0,\n        false => 42,\n    };\n\n    let option = 1;\n    match option == 1 {\n        //~^ match_bool\n        true => 1,\n        false => 0,\n    };\n\n    match test {\n        //~^ match_bool\n        true => (),\n        false => {\n            println!(\"Noooo!\");\n        },\n    };\n\n    match test {\n        //~^ match_bool\n        false => {\n            println!(\"Noooo!\");\n        },\n        _ => (),\n    };\n\n    match test && test {\n        //~^ match_bool\n        false => {\n            println!(\"Noooo!\");\n        },\n        _ => (),\n    };\n\n    match test {\n        //~^ match_bool\n        false => {\n            println!(\"Noooo!\");\n        },\n        true => {\n            println!(\"Yes!\");\n        },\n    };\n\n    // Not linted\n    match option {\n        1..=10 => 1,\n        11..=20 => 2,\n        _ => 3,\n    };\n\n    // Don't lint\n    let _ = match test {\n        #[cfg(feature = \"foo\")]\n        true if option == 5 => 10,\n        true => 0,\n        false => 1,\n    };\n\n    let _ = match test {\n        //~^ match_bool\n        true if option == 5 => 10,\n        _ => 1,\n    };\n\n    let _ = match test {\n        //~^ match_bool\n        false if option == 5 => 10,\n        _ => 1,\n    };\n\n    match test {\n        //~^ match_bool\n        true if option == 5 => println!(\"Hello\"),\n        _ => (),\n    };\n\n    match test {\n        //~^ match_bool\n        true if option == 5 => (),\n        _ => println!(\"Hello\"),\n    };\n\n    match test {\n        //~^ match_bool\n        false if option == 5 => println!(\"Hello\"),\n        _ => (),\n    };\n\n    match test {\n        //~^ match_bool\n        false if option == 5 => (),\n        _ => println!(\"Hello\"),\n    };\n}\n\nfn issue14099() {\n    match true {\n        //~^ match_bool\n        true => 'a: {\n            break 'a;\n        },\n        _ => (),\n    }\n}\n\nfn issue15351() {\n    let mut d = false;\n    match d {\n        false => println!(\"foo\"),\n        ref mut d => *d = false,\n    }\n\n    match d {\n        false => println!(\"foo\"),\n        e => println!(\"{e}\"),\n    }\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            ($val + 1) > 0\n        };\n    }\n\n    let x = 5;\n    match test_expr!(x) {\n        //~^ match_bool\n        true => 1,\n        false => 0,\n    };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_bool.stderr",
    "content": "error: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:7:5\n   |\nLL | /     match test {\nLL | |\nLL | |         true => 0,\nLL | |         false => 42,\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if test { 0 } else { 42 }`\n   |\nnote: the lint level is defined here\n  --> tests/ui/match_bool.rs:1:9\n   |\nLL | #![deny(clippy::match_bool)]\n   |         ^^^^^^^^^^^^^^^^^^\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:14:5\n   |\nLL | /     match option == 1 {\nLL | |\nLL | |         true => 1,\nLL | |         false => 0,\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if option == 1 { 1 } else { 0 }`\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:20:5\n   |\nLL | /     match test {\nLL | |\nLL | |         true => (),\nLL | |         false => {\nLL | |             println!(\"Noooo!\");\nLL | |         },\nLL | |     };\n   | |_____^\n   |\nhelp: consider using an `if`/`else` expression\n   |\nLL ~     if !test {\nLL +         println!(\"Noooo!\");\nLL ~     };\n   |\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:28:5\n   |\nLL | /     match test {\nLL | |\nLL | |         false => {\nLL | |             println!(\"Noooo!\");\nLL | |         },\nLL | |         _ => (),\nLL | |     };\n   | |_____^\n   |\nhelp: consider using an `if`/`else` expression\n   |\nLL ~     if !test {\nLL +         println!(\"Noooo!\");\nLL ~     };\n   |\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:36:5\n   |\nLL | /     match test && test {\nLL | |\nLL | |         false => {\nLL | |             println!(\"Noooo!\");\nLL | |         },\nLL | |         _ => (),\nLL | |     };\n   | |_____^\n   |\nhelp: consider using an `if`/`else` expression\n   |\nLL ~     if !(test && test) {\nLL +         println!(\"Noooo!\");\nLL ~     };\n   |\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:44:5\n   |\nLL | /     match test {\nLL | |\nLL | |         false => {\nLL | |             println!(\"Noooo!\");\n...  |\nLL | |         },\nLL | |     };\n   | |_____^\n   |\nhelp: consider using an `if`/`else` expression\n   |\nLL ~     if !test {\nLL +         println!(\"Noooo!\");\nLL +     } else {\nLL +         println!(\"Yes!\");\nLL ~     };\n   |\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:69:13\n   |\nLL |       let _ = match test {\n   |  _____________^\nLL | |\nLL | |         true if option == 5 => 10,\nLL | |         _ => 1,\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if test && option == 5 { 10 } else { 1 }`\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:75:13\n   |\nLL |       let _ = match test {\n   |  _____________^\nLL | |\nLL | |         false if option == 5 => 10,\nLL | |         _ => 1,\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if !test && option == 5 { 10 } else { 1 }`\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:81:5\n   |\nLL | /     match test {\nLL | |\nLL | |         true if option == 5 => println!(\"Hello\"),\nLL | |         _ => (),\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if test && option == 5 { println!(\"Hello\") }`\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:87:5\n   |\nLL | /     match test {\nLL | |\nLL | |         true if option == 5 => (),\nLL | |         _ => println!(\"Hello\"),\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if !(test && option == 5) { println!(\"Hello\") }`\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:93:5\n   |\nLL | /     match test {\nLL | |\nLL | |         false if option == 5 => println!(\"Hello\"),\nLL | |         _ => (),\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if !test && option == 5 { println!(\"Hello\") }`\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:99:5\n   |\nLL | /     match test {\nLL | |\nLL | |         false if option == 5 => (),\nLL | |         _ => println!(\"Hello\"),\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if !(!test && option == 5) { println!(\"Hello\") }`\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:107:5\n   |\nLL | /     match true {\nLL | |\nLL | |         true => 'a: {\nLL | |             break 'a;\nLL | |         },\nLL | |         _ => (),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using an `if`/`else` expression\n   |\nLL ~     if true { 'a: {\nLL +         break 'a;\nLL +     } }\n   |\n\nerror: `match` on a boolean expression\n  --> tests/ui/match_bool.rs:137:5\n   |\nLL | /     match test_expr!(x) {\nLL | |\nLL | |         true => 1,\nLL | |         false => 0,\nLL | |     };\n   | |_____^ help: consider using an `if`/`else` expression: `if test_expr!(x) { 1 } else { 0 }`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_like_matches_macro.fixed",
    "content": "#![warn(clippy::match_like_matches_macro)]\n#![allow(\n    unreachable_patterns,\n    irrefutable_let_patterns,\n    clippy::equatable_if_let,\n    clippy::needless_borrowed_reference,\n    clippy::redundant_guards\n)]\n\nfn main() {\n    let x = Some(5);\n\n    // Lint\n    let _y = matches!(x, Some(0));\n    //~^^^^ match_like_matches_macro\n\n    // No lint: covered by `redundant_pattern_matching`\n    let _w = x.is_some();\n    //~^^^^ redundant_pattern_matching\n\n    // No lint: covered by `redundant_pattern_matching`\n    let _z = x.is_none();\n    //~^^^^ redundant_pattern_matching\n\n    // Lint\n    let _zz = !matches!(x, Some(r) if r == 0);\n    //~^^^^ match_like_matches_macro\n\n    // Lint\n    let _zzz = matches!(x, Some(5));\n    //~^ match_like_matches_macro\n\n    // No lint\n    let _a = match x {\n        Some(_) => false,\n        _ => false,\n    };\n\n    // No lint\n    let _ab = match x {\n        Some(0) => false,\n        _ => true,\n        None => false,\n    };\n\n    enum E {\n        A(u32),\n        B(i32),\n        C,\n        D,\n    }\n    let x = E::A(2);\n    {\n        // lint\n        let _ans = matches!(x, E::A(_) | E::B(_));\n        //~^^^^^ match_like_matches_macro\n    }\n    {\n        // lint\n        // skip rustfmt to prevent removing block for first pattern\n        #[rustfmt::skip]\n        let _ans = matches!(x, E::A(_) | E::B(_));\n        //~^^^^^^^ match_like_matches_macro\n    }\n    {\n        // lint\n        let _ans = !matches!(x, E::B(_) | E::C);\n        //~^^^^^ match_like_matches_macro\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(_) => false,\n            E::B(_) => false,\n            E::C => true,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(_) => true,\n            E::B(_) => false,\n            E::C => false,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(a) if a < 10 => false,\n            E::B(a) if a < 10 => false,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(_) => false,\n            E::B(a) if a < 10 => false,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(a) => a == 10,\n            E::B(_) => false,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(_) => false,\n            E::B(_) => true,\n            _ => false,\n        };\n    }\n\n    {\n        // should print \"z\" in suggestion (#6503)\n        let z = &Some(3);\n        let _z = matches!(z, Some(3));\n        //~^^^^ match_like_matches_macro\n    }\n\n    {\n        // this could also print \"z\" in suggestion..?\n        let z = Some(3);\n        let _z = matches!(&z, Some(3));\n        //~^^^^ match_like_matches_macro\n    }\n\n    {\n        enum AnEnum {\n            X,\n            Y,\n        }\n\n        fn foo(_x: AnEnum) {}\n\n        fn main() {\n            let z = AnEnum::X;\n            // we can't remove the reference here!\n            let _ = matches!(&z, AnEnum::X);\n            //~^^^^ match_like_matches_macro\n            foo(z);\n        }\n    }\n\n    {\n        struct S(i32);\n\n        fn fun(_val: Option<S>) {}\n        let val = Some(S(42));\n        // we need the reference here because later val is consumed by fun()\n        let _res = matches!(&val, &Some(ref _a));\n        //~^^^^ match_like_matches_macro\n        fun(val);\n    }\n\n    {\n        struct S(i32);\n\n        fn fun(_val: Option<S>) {}\n        let val = Some(S(42));\n        let _res = matches!(&val, &Some(ref _a));\n        //~^^^^ match_like_matches_macro\n        fun(val);\n    }\n\n    {\n        enum E {\n            A,\n            B,\n            C,\n        }\n\n        let _ = match E::A {\n            E::B => true,\n            #[cfg(feature = \"foo\")]\n            E::A => true,\n            _ => false,\n        };\n    }\n\n    let x = ' ';\n    // ignore if match block contains comment\n    let _line_comments = match x {\n        // numbers are bad!\n        '1' | '2' | '3' => true,\n        // spaces are very important to be true.\n        ' ' => true,\n        // as are dots\n        '.' => true,\n        _ => false,\n    };\n\n    let _block_comments = match x {\n        /* numbers are bad!\n         */\n        '1' | '2' | '3' => true,\n        /* spaces are very important to be true.\n         */\n        ' ' => true,\n        /* as are dots\n         */\n        '.' => true,\n        _ => false,\n    };\n}\n\n#[clippy::msrv = \"1.41\"]\nfn msrv_1_41() {\n    let _y = match Some(5) {\n        Some(0) => true,\n        _ => false,\n    };\n}\n\n#[clippy::msrv = \"1.42\"]\nfn msrv_1_42() {\n    let _y = matches!(Some(5), Some(0));\n    //~^^^^ match_like_matches_macro\n}\n\n#[expect(clippy::option_option)]\nfn issue15841(opt: Option<Option<Option<i32>>>, value: i32) {\n    // Lint: no if-let _in the guard_\n    let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() }));\n    //~^^^^ match_like_matches_macro\n}\n\nfn issue16015<T: 'static, U: 'static>() -> bool {\n    use std::any::{TypeId, type_name};\n    pub struct GetTypeId<T>(T);\n\n    impl<T: 'static> GetTypeId<T> {\n        pub const VALUE: TypeId = TypeId::of::<T>();\n    }\n\n    macro_rules! typeid {\n        ($t:ty) => {\n            GetTypeId::<$t>::VALUE\n        };\n    }\n\n    matches!(typeid!(T), _);\n    //~^^^^ match_like_matches_macro\n\n    matches!(typeid!(U), _)\n    //~^ match_like_matches_macro\n}\n"
  },
  {
    "path": "tests/ui/match_like_matches_macro.rs",
    "content": "#![warn(clippy::match_like_matches_macro)]\n#![allow(\n    unreachable_patterns,\n    irrefutable_let_patterns,\n    clippy::equatable_if_let,\n    clippy::needless_borrowed_reference,\n    clippy::redundant_guards\n)]\n\nfn main() {\n    let x = Some(5);\n\n    // Lint\n    let _y = match x {\n        Some(0) => true,\n        _ => false,\n    };\n    //~^^^^ match_like_matches_macro\n\n    // No lint: covered by `redundant_pattern_matching`\n    let _w = match x {\n        Some(_) => true,\n        _ => false,\n    };\n    //~^^^^ redundant_pattern_matching\n\n    // No lint: covered by `redundant_pattern_matching`\n    let _z = match x {\n        Some(_) => false,\n        None => true,\n    };\n    //~^^^^ redundant_pattern_matching\n\n    // Lint\n    let _zz = match x {\n        Some(r) if r == 0 => false,\n        _ => true,\n    };\n    //~^^^^ match_like_matches_macro\n\n    // Lint\n    let _zzz = if let Some(5) = x { true } else { false };\n    //~^ match_like_matches_macro\n\n    // No lint\n    let _a = match x {\n        Some(_) => false,\n        _ => false,\n    };\n\n    // No lint\n    let _ab = match x {\n        Some(0) => false,\n        _ => true,\n        None => false,\n    };\n\n    enum E {\n        A(u32),\n        B(i32),\n        C,\n        D,\n    }\n    let x = E::A(2);\n    {\n        // lint\n        let _ans = match x {\n            E::A(_) => true,\n            E::B(_) => true,\n            _ => false,\n        };\n        //~^^^^^ match_like_matches_macro\n    }\n    {\n        // lint\n        // skip rustfmt to prevent removing block for first pattern\n        #[rustfmt::skip]\n        let _ans = match x {\n            E::A(_) => {\n                true\n            }\n            E::B(_) => true,\n            _ => false,\n        };\n        //~^^^^^^^ match_like_matches_macro\n    }\n    {\n        // lint\n        let _ans = match x {\n            E::B(_) => false,\n            E::C => false,\n            _ => true,\n        };\n        //~^^^^^ match_like_matches_macro\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(_) => false,\n            E::B(_) => false,\n            E::C => true,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(_) => true,\n            E::B(_) => false,\n            E::C => false,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(a) if a < 10 => false,\n            E::B(a) if a < 10 => false,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(_) => false,\n            E::B(a) if a < 10 => false,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(a) => a == 10,\n            E::B(_) => false,\n            _ => true,\n        };\n    }\n    {\n        // no lint\n        let _ans = match x {\n            E::A(_) => false,\n            E::B(_) => true,\n            _ => false,\n        };\n    }\n\n    {\n        // should print \"z\" in suggestion (#6503)\n        let z = &Some(3);\n        let _z = match &z {\n            Some(3) => true,\n            _ => false,\n        };\n        //~^^^^ match_like_matches_macro\n    }\n\n    {\n        // this could also print \"z\" in suggestion..?\n        let z = Some(3);\n        let _z = match &z {\n            Some(3) => true,\n            _ => false,\n        };\n        //~^^^^ match_like_matches_macro\n    }\n\n    {\n        enum AnEnum {\n            X,\n            Y,\n        }\n\n        fn foo(_x: AnEnum) {}\n\n        fn main() {\n            let z = AnEnum::X;\n            // we can't remove the reference here!\n            let _ = match &z {\n                AnEnum::X => true,\n                _ => false,\n            };\n            //~^^^^ match_like_matches_macro\n            foo(z);\n        }\n    }\n\n    {\n        struct S(i32);\n\n        fn fun(_val: Option<S>) {}\n        let val = Some(S(42));\n        // we need the reference here because later val is consumed by fun()\n        let _res = match &val {\n            &Some(ref _a) => true,\n            _ => false,\n        };\n        //~^^^^ match_like_matches_macro\n        fun(val);\n    }\n\n    {\n        struct S(i32);\n\n        fn fun(_val: Option<S>) {}\n        let val = Some(S(42));\n        let _res = match &val {\n            &Some(ref _a) => true,\n            _ => false,\n        };\n        //~^^^^ match_like_matches_macro\n        fun(val);\n    }\n\n    {\n        enum E {\n            A,\n            B,\n            C,\n        }\n\n        let _ = match E::A {\n            E::B => true,\n            #[cfg(feature = \"foo\")]\n            E::A => true,\n            _ => false,\n        };\n    }\n\n    let x = ' ';\n    // ignore if match block contains comment\n    let _line_comments = match x {\n        // numbers are bad!\n        '1' | '2' | '3' => true,\n        // spaces are very important to be true.\n        ' ' => true,\n        // as are dots\n        '.' => true,\n        _ => false,\n    };\n\n    let _block_comments = match x {\n        /* numbers are bad!\n         */\n        '1' | '2' | '3' => true,\n        /* spaces are very important to be true.\n         */\n        ' ' => true,\n        /* as are dots\n         */\n        '.' => true,\n        _ => false,\n    };\n}\n\n#[clippy::msrv = \"1.41\"]\nfn msrv_1_41() {\n    let _y = match Some(5) {\n        Some(0) => true,\n        _ => false,\n    };\n}\n\n#[clippy::msrv = \"1.42\"]\nfn msrv_1_42() {\n    let _y = match Some(5) {\n        Some(0) => true,\n        _ => false,\n    };\n    //~^^^^ match_like_matches_macro\n}\n\n#[expect(clippy::option_option)]\nfn issue15841(opt: Option<Option<Option<i32>>>, value: i32) {\n    // Lint: no if-let _in the guard_\n    let _ = match opt {\n        Some(first) if (if let Some(second) = first { true } else { todo!() }) => true,\n        _ => false,\n    };\n    //~^^^^ match_like_matches_macro\n}\n\nfn issue16015<T: 'static, U: 'static>() -> bool {\n    use std::any::{TypeId, type_name};\n    pub struct GetTypeId<T>(T);\n\n    impl<T: 'static> GetTypeId<T> {\n        pub const VALUE: TypeId = TypeId::of::<T>();\n    }\n\n    macro_rules! typeid {\n        ($t:ty) => {\n            GetTypeId::<$t>::VALUE\n        };\n    }\n\n    match typeid!(T) {\n        _ => true,\n        _ => false,\n    };\n    //~^^^^ match_like_matches_macro\n\n    if let _ = typeid!(U) { true } else { false }\n    //~^ match_like_matches_macro\n}\n"
  },
  {
    "path": "tests/ui/match_like_matches_macro.stderr",
    "content": "error: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:14:14\n   |\nLL |       let _y = match x {\n   |  ______________^\nLL | |         Some(0) => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::match-like-matches-macro` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_like_matches_macro)]`\nhelp: use `matches!` directly\n   |\nLL -     let _y = match x {\nLL -         Some(0) => true,\nLL -         _ => false,\nLL -     };\nLL +     let _y = matches!(x, Some(0));\n   |\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/match_like_matches_macro.rs:21:14\n   |\nLL |       let _w = match x {\n   |  ______________^\nLL | |         Some(_) => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^ help: try: `x.is_some()`\n   |\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/match_like_matches_macro.rs:28:14\n   |\nLL |       let _z = match x {\n   |  ______________^\nLL | |         Some(_) => false,\nLL | |         None => true,\nLL | |     };\n   | |_____^ help: try: `x.is_none()`\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:35:15\n   |\nLL |       let _zz = match x {\n   |  _______________^\nLL | |         Some(r) if r == 0 => false,\nLL | |         _ => true,\nLL | |     };\n   | |_____^\n   |\nhelp: use `matches!` directly\n   |\nLL -     let _zz = match x {\nLL -         Some(r) if r == 0 => false,\nLL -         _ => true,\nLL -     };\nLL +     let _zz = !matches!(x, Some(r) if r == 0);\n   |\n\nerror: `if let .. else` expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:42:16\n   |\nLL |     let _zzz = if let Some(5) = x { true } else { false };\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `matches!` directly\n   |\nLL -     let _zzz = if let Some(5) = x { true } else { false };\nLL +     let _zzz = matches!(x, Some(5));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:67:20\n   |\nLL |           let _ans = match x {\n   |  ____________________^\nLL | |             E::A(_) => true,\nLL | |             E::B(_) => true,\nLL | |             _ => false,\nLL | |         };\n   | |_________^\n   |\nhelp: use `matches!` directly\n   |\nLL -         let _ans = match x {\nLL -             E::A(_) => true,\nLL -             E::B(_) => true,\nLL -             _ => false,\nLL -         };\nLL +         let _ans = matches!(x, E::A(_) | E::B(_));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:78:20\n   |\nLL |           let _ans = match x {\n   |  ____________________^\nLL | |             E::A(_) => {\nLL | |                 true\n...  |\nLL | |             _ => false,\nLL | |         };\n   | |_________^\n   |\nhelp: use `matches!` directly\n   |\nLL -         let _ans = match x {\nLL -             E::A(_) => {\nLL -                 true\nLL -             }\nLL -             E::B(_) => true,\nLL -             _ => false,\nLL -         };\nLL +         let _ans = matches!(x, E::A(_) | E::B(_));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:89:20\n   |\nLL |           let _ans = match x {\n   |  ____________________^\nLL | |             E::B(_) => false,\nLL | |             E::C => false,\nLL | |             _ => true,\nLL | |         };\n   | |_________^\n   |\nhelp: use `matches!` directly\n   |\nLL -         let _ans = match x {\nLL -             E::B(_) => false,\nLL -             E::C => false,\nLL -             _ => true,\nLL -         };\nLL +         let _ans = !matches!(x, E::B(_) | E::C);\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:150:18\n   |\nLL |           let _z = match &z {\n   |  __________________^\nLL | |             Some(3) => true,\nLL | |             _ => false,\nLL | |         };\n   | |_________^\n   |\nhelp: use `matches!` directly\n   |\nLL -         let _z = match &z {\nLL -             Some(3) => true,\nLL -             _ => false,\nLL -         };\nLL +         let _z = matches!(z, Some(3));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:160:18\n   |\nLL |           let _z = match &z {\n   |  __________________^\nLL | |             Some(3) => true,\nLL | |             _ => false,\nLL | |         };\n   | |_________^\n   |\nhelp: use `matches!` directly\n   |\nLL -         let _z = match &z {\nLL -             Some(3) => true,\nLL -             _ => false,\nLL -         };\nLL +         let _z = matches!(&z, Some(3));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:178:21\n   |\nLL |               let _ = match &z {\n   |  _____________________^\nLL | |                 AnEnum::X => true,\nLL | |                 _ => false,\nLL | |             };\n   | |_____________^\n   |\nhelp: use `matches!` directly\n   |\nLL -             let _ = match &z {\nLL -                 AnEnum::X => true,\nLL -                 _ => false,\nLL -             };\nLL +             let _ = matches!(&z, AnEnum::X);\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:193:20\n   |\nLL |           let _res = match &val {\n   |  ____________________^\nLL | |             &Some(ref _a) => true,\nLL | |             _ => false,\nLL | |         };\n   | |_________^\n   |\nhelp: use `matches!` directly\n   |\nLL -         let _res = match &val {\nLL -             &Some(ref _a) => true,\nLL -             _ => false,\nLL -         };\nLL +         let _res = matches!(&val, &Some(ref _a));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:206:20\n   |\nLL |           let _res = match &val {\n   |  ____________________^\nLL | |             &Some(ref _a) => true,\nLL | |             _ => false,\nLL | |         };\n   | |_________^\n   |\nhelp: use `matches!` directly\n   |\nLL -         let _res = match &val {\nLL -             &Some(ref _a) => true,\nLL -             _ => false,\nLL -         };\nLL +         let _res = matches!(&val, &Some(ref _a));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:265:14\n   |\nLL |       let _y = match Some(5) {\n   |  ______________^\nLL | |         Some(0) => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^\n   |\nhelp: use `matches!` directly\n   |\nLL -     let _y = match Some(5) {\nLL -         Some(0) => true,\nLL -         _ => false,\nLL -     };\nLL +     let _y = matches!(Some(5), Some(0));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:275:13\n   |\nLL |       let _ = match opt {\n   |  _____________^\nLL | |         Some(first) if (if let Some(second) = first { true } else { todo!() }) => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^\n   |\nhelp: use `matches!` directly\n   |\nLL -     let _ = match opt {\nLL -         Some(first) if (if let Some(second) = first { true } else { todo!() }) => true,\nLL -         _ => false,\nLL -     };\nLL +     let _ = matches!(opt, Some(first) if (if let Some(second) = first { true } else { todo!() }));\n   |\n\nerror: match expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:296:5\n   |\nLL | /     match typeid!(T) {\nLL | |         _ => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^\n   |\nhelp: use `matches!` directly\n   |\nLL -     match typeid!(T) {\nLL -         _ => true,\nLL -         _ => false,\nLL -     };\nLL +     matches!(typeid!(T), _);\n   |\n\nerror: `if let .. else` expression looks like `matches!` macro\n  --> tests/ui/match_like_matches_macro.rs:302:5\n   |\nLL |     if let _ = typeid!(U) { true } else { false }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `matches!` directly\n   |\nLL -     if let _ = typeid!(U) { true } else { false }\nLL +     matches!(typeid!(U), _)\n   |\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_like_matches_macro_if_let_guard.rs",
    "content": "//@check-pass\n#![warn(clippy::match_like_matches_macro)]\n\n#[expect(clippy::option_option)]\nfn issue15841(opt: Option<Option<Option<i32>>>, value: i32) {\n    let _ = match opt {\n        Some(first)\n            if let Some(second) = first\n                && let Some(third) = second\n                && third == value =>\n        {\n            true\n        },\n        _ => false,\n    };\n\n    // if-let is the second if\n    let _ = match opt {\n        Some(first)\n            if first.is_some()\n                && let Some(second) = first =>\n        {\n            true\n        },\n        _ => false,\n    };\n\n    // if-let is the third if\n    let _ = match opt {\n        Some(first)\n            if first.is_some()\n                && first.is_none()\n                && let Some(second) = first =>\n        {\n            true\n        },\n        _ => false,\n    };\n\n    // don't get confused by `or`s\n    let _ = match opt {\n        Some(first)\n            if (first.is_some() || first.is_none())\n                && let Some(second) = first =>\n        {\n            true\n        },\n        _ => false,\n    };\n}\n"
  },
  {
    "path": "tests/ui/match_overlapping_arm.rs",
    "content": "#![warn(clippy::match_overlapping_arm)]\n#![allow(clippy::redundant_pattern_matching)]\n#![allow(clippy::if_same_then_else, clippy::equatable_if_let, clippy::needless_ifs)]\n\nfn overlapping() {\n    const FOO: u64 = 2;\n\n    match 42 {\n        0..=10 => println!(\"0..=10\"),\n        //~^ match_overlapping_arm\n        0..=11 => println!(\"0..=11\"),\n        _ => (),\n    }\n\n    match 42 {\n        0..=5 => println!(\"0..=5\"),\n        //~^ match_overlapping_arm\n        6..=7 => println!(\"6..=7\"),\n        FOO..=11 => println!(\"FOO..=11\"),\n        _ => (),\n    }\n\n    match 42 {\n        2 => println!(\"2\"),\n        0..=5 => println!(\"0..=5\"),\n        _ => (),\n    }\n\n    match 42 {\n        2 => println!(\"2\"),\n        0..=2 => println!(\"0..=2\"),\n        _ => (),\n    }\n\n    match 42 {\n        0..=10 => println!(\"0..=10\"),\n        11..=50 => println!(\"11..=50\"),\n        _ => (),\n    }\n\n    match 42 {\n        2 => println!(\"2\"),\n        0..2 => println!(\"0..2\"),\n        _ => (),\n    }\n\n    match 42 {\n        0..10 => println!(\"0..10\"),\n        10..50 => println!(\"10..50\"),\n        _ => (),\n    }\n\n    match 42 {\n        0..11 => println!(\"0..11\"),\n        //~^ match_overlapping_arm\n        0..=11 => println!(\"0..=11\"),\n        _ => (),\n    }\n\n    match 42 {\n        5..7 => println!(\"5..7\"),\n        0..10 => println!(\"0..10\"),\n        _ => (),\n    }\n\n    match 42 {\n        5..10 => println!(\"5..10\"),\n        0..=10 => println!(\"0..=10\"),\n        _ => (),\n    }\n\n    match 42 {\n        0..14 => println!(\"0..14\"),\n        5..10 => println!(\"5..10\"),\n        _ => (),\n    }\n\n    match 42 {\n        5..14 => println!(\"5..14\"),\n        0..=10 => println!(\"0..=10\"),\n        //~^ match_overlapping_arm\n        _ => (),\n    }\n\n    match 42 {\n        0..7 => println!(\"0..7\"),\n        //~^ match_overlapping_arm\n        0..=10 => println!(\"0..=10\"),\n        _ => (),\n    }\n\n    match 42 {\n        3.. => println!(\"3..\"),\n        0.. => println!(\"0..\"),\n        _ => (),\n    }\n\n    match 42 {\n        ..=23 => println!(\"..=23\"),\n        //~^ match_overlapping_arm\n        ..26 => println!(\"..26\"),\n        _ => (),\n    }\n\n    // Issue #7816 - overlap after included range\n    match 42 {\n        5..=10 => (),\n        0..=20 => (),\n        21..=30 => (),\n        //~^ match_overlapping_arm\n        21..=40 => (),\n        _ => (),\n    }\n\n    // Issue #7829\n    match 0 {\n        -1..=1 => (),\n        -2..=2 => (),\n        _ => (),\n    }\n\n    // Only warn about the first if there are multiple overlaps\n    match 42u128 {\n        0..=0x0000_0000_0000_00ff => (),\n        //~^ match_overlapping_arm\n        0..=0x0000_0000_0000_ffff => (),\n        0..=0x0000_0000_ffff_ffff => (),\n        0..=0xffff_ffff_ffff_ffff => (),\n        _ => (),\n    }\n\n    if let None = Some(42) {\n        // nothing\n    } else if let None = Some(42) {\n        // another nothing :-)\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_overlapping_arm.stderr",
    "content": "error: some ranges overlap\n  --> tests/ui/match_overlapping_arm.rs:9:9\n   |\nLL |         0..=10 => println!(\"0..=10\"),\n   |         ^^^^^^\n   |\nnote: overlaps with this\n  --> tests/ui/match_overlapping_arm.rs:11:9\n   |\nLL |         0..=11 => println!(\"0..=11\"),\n   |         ^^^^^^\n   = note: `-D clippy::match-overlapping-arm` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_overlapping_arm)]`\n\nerror: some ranges overlap\n  --> tests/ui/match_overlapping_arm.rs:16:9\n   |\nLL |         0..=5 => println!(\"0..=5\"),\n   |         ^^^^^\n   |\nnote: overlaps with this\n  --> tests/ui/match_overlapping_arm.rs:19:9\n   |\nLL |         FOO..=11 => println!(\"FOO..=11\"),\n   |         ^^^^^^^^\n\nerror: some ranges overlap\n  --> tests/ui/match_overlapping_arm.rs:54:9\n   |\nLL |         0..11 => println!(\"0..11\"),\n   |         ^^^^^\n   |\nnote: overlaps with this\n  --> tests/ui/match_overlapping_arm.rs:56:9\n   |\nLL |         0..=11 => println!(\"0..=11\"),\n   |         ^^^^^^\n\nerror: some ranges overlap\n  --> tests/ui/match_overlapping_arm.rs:80:9\n   |\nLL |         0..=10 => println!(\"0..=10\"),\n   |         ^^^^^^\n   |\nnote: overlaps with this\n  --> tests/ui/match_overlapping_arm.rs:79:9\n   |\nLL |         5..14 => println!(\"5..14\"),\n   |         ^^^^^\n\nerror: some ranges overlap\n  --> tests/ui/match_overlapping_arm.rs:86:9\n   |\nLL |         0..7 => println!(\"0..7\"),\n   |         ^^^^\n   |\nnote: overlaps with this\n  --> tests/ui/match_overlapping_arm.rs:88:9\n   |\nLL |         0..=10 => println!(\"0..=10\"),\n   |         ^^^^^^\n\nerror: some ranges overlap\n  --> tests/ui/match_overlapping_arm.rs:99:9\n   |\nLL |         ..=23 => println!(\"..=23\"),\n   |         ^^^^^\n   |\nnote: overlaps with this\n  --> tests/ui/match_overlapping_arm.rs:101:9\n   |\nLL |         ..26 => println!(\"..26\"),\n   |         ^^^^\n\nerror: some ranges overlap\n  --> tests/ui/match_overlapping_arm.rs:109:9\n   |\nLL |         21..=30 => (),\n   |         ^^^^^^^\n   |\nnote: overlaps with this\n  --> tests/ui/match_overlapping_arm.rs:111:9\n   |\nLL |         21..=40 => (),\n   |         ^^^^^^^\n\nerror: some ranges overlap\n  --> tests/ui/match_overlapping_arm.rs:124:9\n   |\nLL |         0..=0x0000_0000_0000_00ff => (),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: overlaps with this\n  --> tests/ui/match_overlapping_arm.rs:126:9\n   |\nLL |         0..=0x0000_0000_0000_ffff => (),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_ref_pats.fixed",
    "content": "#![warn(clippy::match_ref_pats)]\n#![allow(dead_code, unused_variables)]\n#![allow(\n    clippy::enum_variant_names,\n    clippy::equatable_if_let,\n    clippy::uninlined_format_args,\n    clippy::empty_loop,\n    clippy::diverging_sub_expression\n)]\n\nfn ref_pats() {\n    {\n        let v = &Some(0);\n        match *v {\n            //~^ match_ref_pats\n            Some(v) => println!(\"{:?}\", v),\n            None => println!(\"none\"),\n        }\n        match v {\n            // This doesn't trigger; we have a different pattern.\n            &Some(v) => println!(\"some\"),\n            other => println!(\"other\"),\n        }\n    }\n    let tup = &(1, 2);\n    match tup {\n        &(v, 1) => println!(\"{}\", v),\n        _ => println!(\"none\"),\n    }\n    // Special case: using `&` both in expr and pats.\n    let w = Some(0);\n    match w {\n        //~^ match_ref_pats\n        Some(v) => println!(\"{:?}\", v),\n        None => println!(\"none\"),\n    }\n    // False positive: only wildcard pattern.\n    let w = Some(0);\n    #[allow(clippy::match_single_binding)]\n    match w {\n        _ => println!(\"none\"),\n    }\n\n    let a = &Some(0);\n    if a.is_none() {\n        //~^ redundant_pattern_matching\n        println!(\"none\");\n    }\n\n    let b = Some(0);\n    if b.is_none() {\n        //~^ redundant_pattern_matching\n        println!(\"none\");\n    }\n}\n\nmod ice_3719 {\n    macro_rules! foo_variant(\n        ($idx:expr) => (Foo::get($idx).unwrap())\n    );\n\n    enum Foo {\n        A,\n        B,\n    }\n\n    impl Foo {\n        fn get(idx: u8) -> Option<&'static Self> {\n            match idx {\n                0 => Some(&Foo::A),\n                1 => Some(&Foo::B),\n                _ => None,\n            }\n        }\n    }\n\n    fn ice_3719() {\n        // ICE #3719\n        match foo_variant!(0) {\n            &Foo::A => println!(\"A\"),\n            _ => println!(\"Wild\"),\n        }\n    }\n}\n\nmod issue_7740 {\n    macro_rules! foobar_variant(\n        ($idx:expr) => (FooBar::get($idx).unwrap())\n    );\n\n    enum FooBar {\n        Foo,\n        Bar,\n        FooBar,\n        BarFoo,\n    }\n\n    impl FooBar {\n        fn get(idx: u8) -> Option<&'static Self> {\n            match idx {\n                0 => Some(&FooBar::Foo),\n                1 => Some(&FooBar::Bar),\n                2 => Some(&FooBar::FooBar),\n                3 => Some(&FooBar::BarFoo),\n                _ => None,\n            }\n        }\n    }\n\n    fn issue_7740() {\n        // Issue #7740\n        match *foobar_variant!(0) {\n            //~^ match_ref_pats\n            FooBar::Foo => println!(\"Foo\"),\n            FooBar::Bar => println!(\"Bar\"),\n            FooBar::FooBar => println!(\"FooBar\"),\n            _ => println!(\"Wild\"),\n        }\n\n        // This shouldn't trigger\n        if let &FooBar::BarFoo = foobar_variant!(3) {\n            println!(\"BarFoo\");\n        } else {\n            println!(\"Wild\");\n        }\n    }\n}\n\nmod issue15378 {\n    fn never_in_match() {\n        match unimplemented!() {\n            &_ => {},\n            &&&42 => {\n                todo!()\n            },\n            _ => {},\n        }\n\n        match panic!() {\n            &_ => {},\n            &&&42 => {\n                todo!()\n            },\n            _ => {},\n        }\n\n        match loop {} {\n            &_ => {},\n            &&&42 => {\n                todo!()\n            },\n            _ => {},\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_ref_pats.rs",
    "content": "#![warn(clippy::match_ref_pats)]\n#![allow(dead_code, unused_variables)]\n#![allow(\n    clippy::enum_variant_names,\n    clippy::equatable_if_let,\n    clippy::uninlined_format_args,\n    clippy::empty_loop,\n    clippy::diverging_sub_expression\n)]\n\nfn ref_pats() {\n    {\n        let v = &Some(0);\n        match v {\n            //~^ match_ref_pats\n            &Some(v) => println!(\"{:?}\", v),\n            &None => println!(\"none\"),\n        }\n        match v {\n            // This doesn't trigger; we have a different pattern.\n            &Some(v) => println!(\"some\"),\n            other => println!(\"other\"),\n        }\n    }\n    let tup = &(1, 2);\n    match tup {\n        &(v, 1) => println!(\"{}\", v),\n        _ => println!(\"none\"),\n    }\n    // Special case: using `&` both in expr and pats.\n    let w = Some(0);\n    match &w {\n        //~^ match_ref_pats\n        &Some(v) => println!(\"{:?}\", v),\n        &None => println!(\"none\"),\n    }\n    // False positive: only wildcard pattern.\n    let w = Some(0);\n    #[allow(clippy::match_single_binding)]\n    match w {\n        _ => println!(\"none\"),\n    }\n\n    let a = &Some(0);\n    if let &None = a {\n        //~^ redundant_pattern_matching\n        println!(\"none\");\n    }\n\n    let b = Some(0);\n    if let &None = &b {\n        //~^ redundant_pattern_matching\n        println!(\"none\");\n    }\n}\n\nmod ice_3719 {\n    macro_rules! foo_variant(\n        ($idx:expr) => (Foo::get($idx).unwrap())\n    );\n\n    enum Foo {\n        A,\n        B,\n    }\n\n    impl Foo {\n        fn get(idx: u8) -> Option<&'static Self> {\n            match idx {\n                0 => Some(&Foo::A),\n                1 => Some(&Foo::B),\n                _ => None,\n            }\n        }\n    }\n\n    fn ice_3719() {\n        // ICE #3719\n        match foo_variant!(0) {\n            &Foo::A => println!(\"A\"),\n            _ => println!(\"Wild\"),\n        }\n    }\n}\n\nmod issue_7740 {\n    macro_rules! foobar_variant(\n        ($idx:expr) => (FooBar::get($idx).unwrap())\n    );\n\n    enum FooBar {\n        Foo,\n        Bar,\n        FooBar,\n        BarFoo,\n    }\n\n    impl FooBar {\n        fn get(idx: u8) -> Option<&'static Self> {\n            match idx {\n                0 => Some(&FooBar::Foo),\n                1 => Some(&FooBar::Bar),\n                2 => Some(&FooBar::FooBar),\n                3 => Some(&FooBar::BarFoo),\n                _ => None,\n            }\n        }\n    }\n\n    fn issue_7740() {\n        // Issue #7740\n        match foobar_variant!(0) {\n            //~^ match_ref_pats\n            &FooBar::Foo => println!(\"Foo\"),\n            &FooBar::Bar => println!(\"Bar\"),\n            &FooBar::FooBar => println!(\"FooBar\"),\n            _ => println!(\"Wild\"),\n        }\n\n        // This shouldn't trigger\n        if let &FooBar::BarFoo = foobar_variant!(3) {\n            println!(\"BarFoo\");\n        } else {\n            println!(\"Wild\");\n        }\n    }\n}\n\nmod issue15378 {\n    fn never_in_match() {\n        match unimplemented!() {\n            &_ => {},\n            &&&42 => {\n                todo!()\n            },\n            _ => {},\n        }\n\n        match panic!() {\n            &_ => {},\n            &&&42 => {\n                todo!()\n            },\n            _ => {},\n        }\n\n        match loop {} {\n            &_ => {},\n            &&&42 => {\n                todo!()\n            },\n            _ => {},\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_ref_pats.stderr",
    "content": "error: you don't need to add `&` to all patterns\n  --> tests/ui/match_ref_pats.rs:14:9\n   |\nLL | /         match v {\nLL | |\nLL | |             &Some(v) => println!(\"{:?}\", v),\nLL | |             &None => println!(\"none\"),\nLL | |         }\n   | |_________^\n   |\n   = note: `-D clippy::match-ref-pats` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_ref_pats)]`\nhelp: instead of prefixing all patterns with `&`, you can dereference the expression\n   |\nLL ~         match *v {\nLL |\nLL ~             Some(v) => println!(\"{:?}\", v),\nLL ~             None => println!(\"none\"),\n   |\n\nerror: you don't need to add `&` to both the expression and the patterns\n  --> tests/ui/match_ref_pats.rs:32:5\n   |\nLL | /     match &w {\nLL | |\nLL | |         &Some(v) => println!(\"{:?}\", v),\nLL | |         &None => println!(\"none\"),\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     match w {\nLL |\nLL ~         Some(v) => println!(\"{:?}\", v),\nLL ~         None => println!(\"none\"),\n   |\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/match_ref_pats.rs:45:12\n   |\nLL |     if let &None = a {\n   |     -------^^^^^---- help: try: `if a.is_none()`\n   |\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/match_ref_pats.rs:51:12\n   |\nLL |     if let &None = &b {\n   |     -------^^^^^----- help: try: `if b.is_none()`\n\nerror: you don't need to add `&` to all patterns\n  --> tests/ui/match_ref_pats.rs:112:9\n   |\nLL | /         match foobar_variant!(0) {\nLL | |\nLL | |             &FooBar::Foo => println!(\"Foo\"),\nLL | |             &FooBar::Bar => println!(\"Bar\"),\nLL | |             &FooBar::FooBar => println!(\"FooBar\"),\nLL | |             _ => println!(\"Wild\"),\nLL | |         }\n   | |_________^\n   |\nhelp: instead of prefixing all patterns with `&`, you can dereference the expression\n   |\nLL ~         match *foobar_variant!(0) {\nLL |\nLL ~             FooBar::Foo => println!(\"Foo\"),\nLL ~             FooBar::Bar => println!(\"Bar\"),\nLL ~             FooBar::FooBar => println!(\"FooBar\"),\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_result_ok.fixed",
    "content": "#![warn(clippy::match_result_ok)]\n#![allow(dead_code)]\n#![allow(\n    clippy::boxed_local,\n    clippy::uninlined_format_args,\n    clippy::manual_unwrap_or_default,\n    clippy::manual_unwrap_or\n)]\n\n// Checking `if` cases\n\nfn str_to_int(x: &str) -> i32 {\n    if let Ok(y) = x.parse() { y } else { 0 }\n    //~^ match_result_ok\n}\n\nfn str_to_int_ok(x: &str) -> i32 {\n    if let Ok(y) = x.parse() { y } else { 0 }\n}\n\n#[rustfmt::skip]\nfn strange_some_no_else(x: &str) -> i32 {\n    {\n        if let Ok(y) = x   .   parse()    {\n        //~^ match_result_ok\n            return y;\n        };\n        0\n    }\n}\n\n// Checking `while` cases\n\nstruct Wat {\n    counter: i32,\n}\n\nimpl Wat {\n    fn next(&mut self) -> Result<i32, &str> {\n        self.counter += 1;\n        if self.counter < 5 {\n            Ok(self.counter)\n        } else {\n            Err(\"Oh no\")\n        }\n    }\n}\n\nfn base_1(x: i32) {\n    let mut wat = Wat { counter: x };\n    while let Ok(a) = wat.next() {\n        //~^ match_result_ok\n        println!(\"{}\", a);\n    }\n}\n\nfn base_2(x: i32) {\n    let mut wat = Wat { counter: x };\n    while let Ok(a) = wat.next() {\n        println!(\"{}\", a);\n    }\n}\n\nfn base_3(test_func: Box<Result<i32, &str>>) {\n    // Expected to stay as is\n    while let Some(_b) = test_func.ok() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_result_ok.rs",
    "content": "#![warn(clippy::match_result_ok)]\n#![allow(dead_code)]\n#![allow(\n    clippy::boxed_local,\n    clippy::uninlined_format_args,\n    clippy::manual_unwrap_or_default,\n    clippy::manual_unwrap_or\n)]\n\n// Checking `if` cases\n\nfn str_to_int(x: &str) -> i32 {\n    if let Some(y) = x.parse().ok() { y } else { 0 }\n    //~^ match_result_ok\n}\n\nfn str_to_int_ok(x: &str) -> i32 {\n    if let Ok(y) = x.parse() { y } else { 0 }\n}\n\n#[rustfmt::skip]\nfn strange_some_no_else(x: &str) -> i32 {\n    {\n        if let Some(y) = x   .   parse()   .   ok   ()    {\n        //~^ match_result_ok\n            return y;\n        };\n        0\n    }\n}\n\n// Checking `while` cases\n\nstruct Wat {\n    counter: i32,\n}\n\nimpl Wat {\n    fn next(&mut self) -> Result<i32, &str> {\n        self.counter += 1;\n        if self.counter < 5 {\n            Ok(self.counter)\n        } else {\n            Err(\"Oh no\")\n        }\n    }\n}\n\nfn base_1(x: i32) {\n    let mut wat = Wat { counter: x };\n    while let Some(a) = wat.next().ok() {\n        //~^ match_result_ok\n        println!(\"{}\", a);\n    }\n}\n\nfn base_2(x: i32) {\n    let mut wat = Wat { counter: x };\n    while let Ok(a) = wat.next() {\n        println!(\"{}\", a);\n    }\n}\n\nfn base_3(test_func: Box<Result<i32, &str>>) {\n    // Expected to stay as is\n    while let Some(_b) = test_func.ok() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_result_ok.stderr",
    "content": "error: matching on `Some` with `ok()` is redundant\n  --> tests/ui/match_result_ok.rs:13:5\n   |\nLL |     if let Some(y) = x.parse().ok() { y } else { 0 }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::match-result-ok` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_result_ok)]`\nhelp: consider matching on `Ok(y)` and removing the call to `ok` instead\n   |\nLL -     if let Some(y) = x.parse().ok() { y } else { 0 }\nLL +     if let Ok(y) = x.parse() { y } else { 0 }\n   |\n\nerror: matching on `Some` with `ok()` is redundant\n  --> tests/ui/match_result_ok.rs:24:9\n   |\nLL |         if let Some(y) = x   .   parse()   .   ok   ()    {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider matching on `Ok(y)` and removing the call to `ok` instead\n   |\nLL -         if let Some(y) = x   .   parse()   .   ok   ()    {\nLL +         if let Ok(y) = x   .   parse()    {\n   |\n\nerror: matching on `Some` with `ok()` is redundant\n  --> tests/ui/match_result_ok.rs:51:5\n   |\nLL |     while let Some(a) = wat.next().ok() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider matching on `Ok(a)` and removing the call to `ok` instead\n   |\nLL -     while let Some(a) = wat.next().ok() {\nLL +     while let Ok(a) = wat.next() {\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_same_arms.fixed",
    "content": "#![allow(clippy::manual_range_patterns)]\n#![warn(clippy::match_same_arms)]\n\npub enum Abc {\n    A,\n    B,\n    C,\n}\n\nfn match_same_arms() {\n    let _ = match Abc::A {\n        Abc::B => 1,\n        _ => 0,\n        //~^ match_same_arms\n    };\n\n    match 0 {\n        1 => 'a',\n        _ => 'b',\n        //~^ match_same_arms\n    };\n\n    match (1, 2, 3) {\n        (1, .., 3) | (.., 3) => 42,\n        //~^ match_same_arms\n        _ => 0,\n    };\n\n    let _ = match 42 {\n        //~^ match_same_arms\n        42 | 51 => 1,\n        41 | 52 => 2,\n        //~^ match_same_arms\n        _ => 0,\n    };\n\n    let _ = match 42 {\n        //~^ match_same_arms\n        1 | 2 | 3 => 2,\n        4 => 3,\n        _ => 0,\n    };\n}\n\nmod issue4244 {\n    #[derive(PartialEq, PartialOrd, Eq, Ord)]\n    pub enum CommandInfo {\n        BuiltIn { name: String, about: Option<String> },\n        External { name: String, path: std::path::PathBuf },\n    }\n\n    impl CommandInfo {\n        pub fn name(&self) -> String {\n            match self {\n                //~^ match_same_arms\n                CommandInfo::BuiltIn { name, .. } | CommandInfo::External { name, .. } => name.to_string(),\n            }\n        }\n    }\n}\n\nmacro_rules! m {\n    (foo) => {};\n    (bar) => {};\n}\nmacro_rules! foo {\n    () => {\n        1\n    };\n}\nmacro_rules! bar {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    let x = 0;\n    let _ = match 0 {\n        0 => {\n            m!(foo);\n            x\n        },\n        1 => {\n            m!(bar);\n            x\n        },\n        _ => 1,\n    };\n\n    let _ = match 0 {\n        0 => {\n            m!(foo);\n            0\n        },\n        1 => {\n            m!(bar);\n            0\n        },\n        _ => 1,\n    };\n\n    let _ = match 0 {\n        0 => {\n            let mut x = 0;\n            #[cfg(not_enabled)]\n            {\n                x = 5;\n            }\n            #[cfg(not(not_enabled))]\n            {\n                x = 6;\n            }\n            x\n        },\n        1 => {\n            let mut x = 0;\n            #[cfg(also_not_enabled)]\n            {\n                x = 5;\n            }\n            #[cfg(not(also_not_enabled))]\n            {\n                x = 6;\n            }\n            x\n        },\n        _ => 0,\n    };\n\n    let _ = match 0 {\n        0 => foo!(),\n        1 => bar!(),\n        _ => 1,\n    };\n\n    let _ = match 0 {\n        0 => cfg!(not_enabled),\n        1 => cfg!(also_not_enabled),\n        _ => false,\n    };\n}\n\nfn issue16678() {\n    // ICE in Rust 1.94.0\n    match true {\n        true => {\n            fn wrapper(_arg: ()) {\n                _arg;\n            }\n        },\n        false => {\n            fn wrapper(_arg: ()) {\n                _arg;\n            }\n        },\n    }\n}\n\nfn issue16698() {\n    trait Foo {\n        const X: u8;\n    }\n    impl Foo for u8 {\n        const X: u8 = 2;\n    }\n    impl Foo for i8 {\n        const X: u8 = 2;\n    }\n    match true {\n        false => u8::X,\n        true => i8::X,\n    };\n}\n"
  },
  {
    "path": "tests/ui/match_same_arms.rs",
    "content": "#![allow(clippy::manual_range_patterns)]\n#![warn(clippy::match_same_arms)]\n\npub enum Abc {\n    A,\n    B,\n    C,\n}\n\nfn match_same_arms() {\n    let _ = match Abc::A {\n        Abc::A => 0,\n        Abc::B => 1,\n        _ => 0,\n        //~^ match_same_arms\n    };\n\n    match 0 {\n        1 => 'a',\n        2 => 'b',\n        3 => 'b',\n        _ => 'b',\n        //~^ match_same_arms\n    };\n\n    match (1, 2, 3) {\n        (1, .., 3) => 42,\n        //~^ match_same_arms\n        (.., 3) => 42,\n        _ => 0,\n    };\n\n    let _ = match 42 {\n        42 => 1,\n        //~^ match_same_arms\n        51 => 1,\n        41 => 2,\n        //~^ match_same_arms\n        52 => 2,\n        _ => 0,\n    };\n\n    let _ = match 42 {\n        1 => 2,\n        //~^ match_same_arms\n        2 => 2,\n        3 => 2,\n        4 => 3,\n        _ => 0,\n    };\n}\n\nmod issue4244 {\n    #[derive(PartialEq, PartialOrd, Eq, Ord)]\n    pub enum CommandInfo {\n        BuiltIn { name: String, about: Option<String> },\n        External { name: String, path: std::path::PathBuf },\n    }\n\n    impl CommandInfo {\n        pub fn name(&self) -> String {\n            match self {\n                CommandInfo::BuiltIn { name, .. } => name.to_string(),\n                //~^ match_same_arms\n                CommandInfo::External { name, .. } => name.to_string(),\n            }\n        }\n    }\n}\n\nmacro_rules! m {\n    (foo) => {};\n    (bar) => {};\n}\nmacro_rules! foo {\n    () => {\n        1\n    };\n}\nmacro_rules! bar {\n    () => {\n        1\n    };\n}\n\nfn main() {\n    let x = 0;\n    let _ = match 0 {\n        0 => {\n            m!(foo);\n            x\n        },\n        1 => {\n            m!(bar);\n            x\n        },\n        _ => 1,\n    };\n\n    let _ = match 0 {\n        0 => {\n            m!(foo);\n            0\n        },\n        1 => {\n            m!(bar);\n            0\n        },\n        _ => 1,\n    };\n\n    let _ = match 0 {\n        0 => {\n            let mut x = 0;\n            #[cfg(not_enabled)]\n            {\n                x = 5;\n            }\n            #[cfg(not(not_enabled))]\n            {\n                x = 6;\n            }\n            x\n        },\n        1 => {\n            let mut x = 0;\n            #[cfg(also_not_enabled)]\n            {\n                x = 5;\n            }\n            #[cfg(not(also_not_enabled))]\n            {\n                x = 6;\n            }\n            x\n        },\n        _ => 0,\n    };\n\n    let _ = match 0 {\n        0 => foo!(),\n        1 => bar!(),\n        _ => 1,\n    };\n\n    let _ = match 0 {\n        0 => cfg!(not_enabled),\n        1 => cfg!(also_not_enabled),\n        _ => false,\n    };\n}\n\nfn issue16678() {\n    // ICE in Rust 1.94.0\n    match true {\n        true => {\n            fn wrapper(_arg: ()) {\n                _arg;\n            }\n        },\n        false => {\n            fn wrapper(_arg: ()) {\n                _arg;\n            }\n        },\n    }\n}\n\nfn issue16698() {\n    trait Foo {\n        const X: u8;\n    }\n    impl Foo for u8 {\n        const X: u8 = 2;\n    }\n    impl Foo for i8 {\n        const X: u8 = 2;\n    }\n    match true {\n        false => u8::X,\n        true => i8::X,\n    };\n}\n"
  },
  {
    "path": "tests/ui/match_same_arms.stderr",
    "content": "error: these match arms have identical bodies\n  --> tests/ui/match_same_arms.rs:12:9\n   |\nLL |         Abc::A => 0,\n   |         ^^^^^^^^^^^\nLL |         Abc::B => 1,\nLL |         _ => 0,\n   |         ^^^^^^ the wildcard arm\n   |\n   = help: if this is unintentional make the arms return different values\n   = note: `-D clippy::match-same-arms` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`\nhelp: otherwise remove the non-wildcard arm\n   |\nLL -         Abc::A => 0,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms.rs:20:9\n   |\nLL |         2 => 'b',\n   |         ^^^^^^^^\nLL |         3 => 'b',\n   |         ^^^^^^^^\nLL |         _ => 'b',\n   |         ^^^^^^^^ the wildcard arm\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise remove the non-wildcard arms\n   |\nLL -         2 => 'b',\nLL -         3 => 'b',\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms.rs:27:9\n   |\nLL |         (1, .., 3) => 42,\n   |         ^^^^^^^^^^^^^^^^\nLL |\nLL |         (.., 3) => 42,\n   |         ^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~         (1, .., 3) | (.., 3) => 42,\nLL |\nLL ~         _ => 0,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms.rs:34:9\n   |\nLL |         42 => 1,\n   |         ^^^^^^^\nLL |\nLL |         51 => 1,\n   |         ^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         42 | 51 => 1,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms.rs:37:9\n   |\nLL |         41 => 2,\n   |         ^^^^^^^\nLL |\nLL |         52 => 2,\n   |         ^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~         41 | 52 => 2,\nLL |\nLL ~         _ => 0,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms.rs:44:9\n   |\nLL |         1 => 2,\n   |         ^^^^^^\nLL |\nLL |         2 => 2,\n   |         ^^^^^^\nLL |         3 => 2,\n   |         ^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         1 | 2 | 3 => 2,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms.rs:63:17\n   |\nLL |                 CommandInfo::BuiltIn { name, .. } => name.to_string(),\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |                 CommandInfo::External { name, .. } => name.to_string(),\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~                 CommandInfo::BuiltIn { name, .. } | CommandInfo::External { name, .. } => name.to_string(),\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_same_arms2.fixed",
    "content": "#![warn(clippy::match_same_arms)]\n#![allow(\n    clippy::disallowed_names,\n    clippy::diverging_sub_expression,\n    clippy::uninlined_format_args,\n    clippy::match_single_binding,\n    clippy::match_like_matches_macro\n)]\n\nfn bar<T>(_: T) {}\nfn foo() -> bool {\n    unimplemented!()\n}\n\nfn match_same_arms() {\n    let _ = match 42 {\n        //~v match_same_arms\n        _ => {\n            foo();\n            let mut a = 42 + [23].len() as i32;\n            if true {\n                a += 7;\n            }\n            a = -31 - a;\n            a\n        },\n    };\n\n    let _ = match 42 {\n        //~^ match_same_arms\n        42 | 51 => foo(),\n        _ => true,\n    };\n\n    let _ = match Some(42) {\n        //~^ match_same_arms\n        Some(_) | None => 24,\n    };\n\n    let _ = match Some(42) {\n        Some(foo) => 24,\n        None => 24,\n    };\n\n    let _ = match Some(42) {\n        Some(42) => 24,\n        Some(a) => 24, // bindings are different\n        None => 0,\n    };\n\n    let _ = match Some(42) {\n        Some(a) if a > 0 => 24,\n        Some(a) => 24, // one arm has a guard\n        None => 0,\n    };\n\n    match (Some(42), Some(42)) {\n        //~^ match_same_arms\n        (Some(a), None) | (None, Some(a)) => bar(a),\n        _ => (),\n    }\n\n    // No warning because guards are different\n    let _ = match Some(42) {\n        Some(a) if a == 42 => a,\n        Some(a) if a == 24 => a,\n        Some(_) => 24,\n        None => 0,\n    };\n\n    let _ = match (Some(42), Some(42)) {\n        //~^ match_same_arms\n        (Some(a), None) | (None, Some(a)) if a == 42 => a,\n        _ => 0,\n    };\n\n    match (Some(42), Some(42)) {\n        (Some(a), ..) | (.., Some(a)) => bar(a),\n        //~^ match_same_arms\n        _ => (),\n    }\n\n    let _ = match Some(()) {\n        Some(()) => 0.0,\n        None => -0.0,\n    };\n\n    match (Some(42), Some(\"\")) {\n        (Some(a), None) => bar(a),\n        (None, Some(a)) => bar(a), // bindings have different types\n        _ => (),\n    }\n\n    let x: Result<i32, &str> = Ok(3);\n\n    // No warning because of the guard.\n    match x {\n        Ok(x) if x * x == 64 => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => println!(\"err\"),\n    }\n\n    // This used to be a false positive; see issue #1996.\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(x) if x * x == 64 => println!(\"ok 64\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => println!(\"err\"),\n    }\n\n    match (x, Some(1i32)) {\n        (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!(\"ok {}\", x),\n        //~^ match_same_arms\n        _ => println!(\"err\"),\n    }\n\n    // No warning; different types for `x`.\n    match (x, Some(1.0f64)) {\n        (Ok(x), Some(_)) => println!(\"ok {}\", x),\n        (Ok(_), Some(x)) => println!(\"ok {}\", x),\n        _ => println!(\"err\"),\n    }\n\n    // False negative #2251.\n    match x {\n        Ok(_tmp) => println!(\"ok\"),\n        //~^ match_same_arms\n        Ok(3) | Ok(_) => println!(\"ok\"),\n        Err(_) => {\n            unreachable!();\n        },\n    }\n\n    // False positive #1390\n    macro_rules! empty {\n        ($e:expr) => {};\n    }\n    match 0 {\n        0 => {\n            empty!(0);\n        },\n        1 => {\n            empty!(1);\n        },\n        x => {\n            empty!(x);\n        },\n    };\n\n    // still lint if the tokens are the same\n    match 0 {\n        //~^^^ match_same_arms\n        0 | 1 => {\n            empty!(0);\n        },\n        x => {\n            empty!(x);\n        },\n    }\n\n    match_expr_like_matches_macro_priority();\n}\n\nfn match_expr_like_matches_macro_priority() {\n    enum E {\n        A,\n        B,\n        C,\n    }\n    let x = E::A;\n    let _ans = match x {\n        E::A => false,\n        E::B => false,\n        _ => true,\n    };\n}\n\nfn main() {\n    let _ = match Some(0) {\n        Some(0) => 0,\n        Some(1) => 1,\n        #[cfg(feature = \"foo\")]\n        Some(2) => 2,\n        _ => 1,\n    };\n\n    enum Foo {\n        X(u32),\n        Y(u32),\n        Z(u32),\n    }\n\n    // Don't lint. `Foo::X(0)` and `Foo::Z(_)` overlap with the arm in between.\n    let _ = match Foo::X(0) {\n        Foo::X(0) => 1,\n        Foo::X(_) | Foo::Y(_) | Foo::Z(0) => 2,\n        Foo::Z(_) => 1,\n        _ => 0,\n    };\n\n    // Suggest moving `Foo::Z(_)` up.\n    let _ = match Foo::X(0) {\n        Foo::X(0) | Foo::Z(_) => 1,\n        //~^ match_same_arms\n        Foo::X(_) | Foo::Y(_) => 2,\n        _ => 0,\n    };\n\n    // Suggest moving `Foo::X(0)` down.\n    let _ = match Foo::X(0) {\n        //~^ match_same_arms\n        Foo::Y(_) | Foo::Z(0) => 2,\n        Foo::X(0) | Foo::Z(_) => 1,\n        _ => 0,\n    };\n\n    // Don't lint.\n    let _ = match 0 {\n        -2 => 1,\n        -5..=50 => 2,\n        -150..=88 => 1,\n        _ => 3,\n    };\n\n    struct Bar {\n        x: u32,\n        y: u32,\n        z: u32,\n    }\n\n    // Lint.\n    let _ = match None {\n        //~^ match_same_arms\n        Some(Bar { y: 10, z: 0, .. }) => 2,\n        None => 50,\n        Some(Bar { x: 0, y: 5, .. }) | Some(Bar { y: 0, x: 5, .. }) => 1,\n        _ => 200,\n    };\n\n    let _ = match 0 {\n        0 => todo!(),\n        1 => todo!(),\n        2 => core::convert::identity::<u32>(todo!()),\n        3 => core::convert::identity::<u32>(todo!()),\n        _ => 5,\n    };\n\n    let _ = match 0 {\n        //~^ match_same_arms\n        0 | 1 => cfg!(not_enable),\n        _ => false,\n    };\n}\n\n// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312\nmod with_lifetime {\n    enum MaybeStaticStr<'a> {\n        Static(&'static str),\n        Borrowed(&'a str),\n    }\n\n    impl<'a> MaybeStaticStr<'a> {\n        fn get(&self) -> &'a str {\n            match *self {\n                //~^ match_same_arms\n                MaybeStaticStr::Static(s) | MaybeStaticStr::Borrowed(s) => s,\n            }\n        }\n    }\n}\n\nfn lint_levels() {\n    match 1 {\n        0 => \"a\",\n        1 => \"b\",\n        #[expect(clippy::match_same_arms)]\n        _ => \"b\",\n    };\n\n    match 2 {\n        0 => \"a\",\n        1 | 2 => \"b\",\n        //~^ match_same_arms\n        #[allow(clippy::match_same_arms)]\n        _ => \"b\",\n    };\n\n    match 3 {\n        0 => \"a\",\n        1 | 2 => \"b\",\n        //~^ match_same_arms\n        #[expect(clippy::match_same_arms)]\n        _ => \"b\",\n    };\n}\n"
  },
  {
    "path": "tests/ui/match_same_arms2.rs",
    "content": "#![warn(clippy::match_same_arms)]\n#![allow(\n    clippy::disallowed_names,\n    clippy::diverging_sub_expression,\n    clippy::uninlined_format_args,\n    clippy::match_single_binding,\n    clippy::match_like_matches_macro\n)]\n\nfn bar<T>(_: T) {}\nfn foo() -> bool {\n    unimplemented!()\n}\n\nfn match_same_arms() {\n    let _ = match 42 {\n        42 => {\n            foo();\n            let mut a = 42 + [23].len() as i32;\n            if true {\n                a += 7;\n            }\n            a = -31 - a;\n            a\n        },\n        //~v match_same_arms\n        _ => {\n            foo();\n            let mut a = 42 + [23].len() as i32;\n            if true {\n                a += 7;\n            }\n            a = -31 - a;\n            a\n        },\n    };\n\n    let _ = match 42 {\n        42 => foo(),\n        //~^ match_same_arms\n        51 => foo(),\n        _ => true,\n    };\n\n    let _ = match Some(42) {\n        Some(_) => 24,\n        //~^ match_same_arms\n        None => 24,\n    };\n\n    let _ = match Some(42) {\n        Some(foo) => 24,\n        None => 24,\n    };\n\n    let _ = match Some(42) {\n        Some(42) => 24,\n        Some(a) => 24, // bindings are different\n        None => 0,\n    };\n\n    let _ = match Some(42) {\n        Some(a) if a > 0 => 24,\n        Some(a) => 24, // one arm has a guard\n        None => 0,\n    };\n\n    match (Some(42), Some(42)) {\n        (Some(a), None) => bar(a),\n        //~^ match_same_arms\n        (None, Some(a)) => bar(a),\n        _ => (),\n    }\n\n    // No warning because guards are different\n    let _ = match Some(42) {\n        Some(a) if a == 42 => a,\n        Some(a) if a == 24 => a,\n        Some(_) => 24,\n        None => 0,\n    };\n\n    let _ = match (Some(42), Some(42)) {\n        (Some(a), None) if a == 42 => a,\n        //~^ match_same_arms\n        (None, Some(a)) if a == 42 => a,\n        _ => 0,\n    };\n\n    match (Some(42), Some(42)) {\n        (Some(a), ..) => bar(a),\n        //~^ match_same_arms\n        (.., Some(a)) => bar(a),\n        _ => (),\n    }\n\n    let _ = match Some(()) {\n        Some(()) => 0.0,\n        None => -0.0,\n    };\n\n    match (Some(42), Some(\"\")) {\n        (Some(a), None) => bar(a),\n        (None, Some(a)) => bar(a), // bindings have different types\n        _ => (),\n    }\n\n    let x: Result<i32, &str> = Ok(3);\n\n    // No warning because of the guard.\n    match x {\n        Ok(x) if x * x == 64 => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => println!(\"err\"),\n    }\n\n    // This used to be a false positive; see issue #1996.\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(x) if x * x == 64 => println!(\"ok 64\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => println!(\"err\"),\n    }\n\n    match (x, Some(1i32)) {\n        (Ok(x), Some(_)) => println!(\"ok {}\", x),\n        //~^ match_same_arms\n        (Ok(_), Some(x)) => println!(\"ok {}\", x),\n        _ => println!(\"err\"),\n    }\n\n    // No warning; different types for `x`.\n    match (x, Some(1.0f64)) {\n        (Ok(x), Some(_)) => println!(\"ok {}\", x),\n        (Ok(_), Some(x)) => println!(\"ok {}\", x),\n        _ => println!(\"err\"),\n    }\n\n    // False negative #2251.\n    match x {\n        Ok(_tmp) => println!(\"ok\"),\n        Ok(3) => println!(\"ok\"),\n        //~^ match_same_arms\n        Ok(_) => println!(\"ok\"),\n        Err(_) => {\n            unreachable!();\n        },\n    }\n\n    // False positive #1390\n    macro_rules! empty {\n        ($e:expr) => {};\n    }\n    match 0 {\n        0 => {\n            empty!(0);\n        },\n        1 => {\n            empty!(1);\n        },\n        x => {\n            empty!(x);\n        },\n    };\n\n    // still lint if the tokens are the same\n    match 0 {\n        0 => {\n            empty!(0);\n        },\n        //~^^^ match_same_arms\n        1 => {\n            empty!(0);\n        },\n        x => {\n            empty!(x);\n        },\n    }\n\n    match_expr_like_matches_macro_priority();\n}\n\nfn match_expr_like_matches_macro_priority() {\n    enum E {\n        A,\n        B,\n        C,\n    }\n    let x = E::A;\n    let _ans = match x {\n        E::A => false,\n        E::B => false,\n        _ => true,\n    };\n}\n\nfn main() {\n    let _ = match Some(0) {\n        Some(0) => 0,\n        Some(1) => 1,\n        #[cfg(feature = \"foo\")]\n        Some(2) => 2,\n        _ => 1,\n    };\n\n    enum Foo {\n        X(u32),\n        Y(u32),\n        Z(u32),\n    }\n\n    // Don't lint. `Foo::X(0)` and `Foo::Z(_)` overlap with the arm in between.\n    let _ = match Foo::X(0) {\n        Foo::X(0) => 1,\n        Foo::X(_) | Foo::Y(_) | Foo::Z(0) => 2,\n        Foo::Z(_) => 1,\n        _ => 0,\n    };\n\n    // Suggest moving `Foo::Z(_)` up.\n    let _ = match Foo::X(0) {\n        Foo::X(0) => 1,\n        //~^ match_same_arms\n        Foo::X(_) | Foo::Y(_) => 2,\n        Foo::Z(_) => 1,\n        _ => 0,\n    };\n\n    // Suggest moving `Foo::X(0)` down.\n    let _ = match Foo::X(0) {\n        Foo::X(0) => 1,\n        //~^ match_same_arms\n        Foo::Y(_) | Foo::Z(0) => 2,\n        Foo::Z(_) => 1,\n        _ => 0,\n    };\n\n    // Don't lint.\n    let _ = match 0 {\n        -2 => 1,\n        -5..=50 => 2,\n        -150..=88 => 1,\n        _ => 3,\n    };\n\n    struct Bar {\n        x: u32,\n        y: u32,\n        z: u32,\n    }\n\n    // Lint.\n    let _ = match None {\n        Some(Bar { x: 0, y: 5, .. }) => 1,\n        //~^ match_same_arms\n        Some(Bar { y: 10, z: 0, .. }) => 2,\n        None => 50,\n        Some(Bar { y: 0, x: 5, .. }) => 1,\n        _ => 200,\n    };\n\n    let _ = match 0 {\n        0 => todo!(),\n        1 => todo!(),\n        2 => core::convert::identity::<u32>(todo!()),\n        3 => core::convert::identity::<u32>(todo!()),\n        _ => 5,\n    };\n\n    let _ = match 0 {\n        0 => cfg!(not_enable),\n        //~^ match_same_arms\n        1 => cfg!(not_enable),\n        _ => false,\n    };\n}\n\n// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312\nmod with_lifetime {\n    enum MaybeStaticStr<'a> {\n        Static(&'static str),\n        Borrowed(&'a str),\n    }\n\n    impl<'a> MaybeStaticStr<'a> {\n        fn get(&self) -> &'a str {\n            match *self {\n                MaybeStaticStr::Static(s) => s,\n                //~^ match_same_arms\n                MaybeStaticStr::Borrowed(s) => s,\n            }\n        }\n    }\n}\n\nfn lint_levels() {\n    match 1 {\n        0 => \"a\",\n        1 => \"b\",\n        #[expect(clippy::match_same_arms)]\n        _ => \"b\",\n    };\n\n    match 2 {\n        0 => \"a\",\n        1 => \"b\",\n        //~^ match_same_arms\n        2 => \"b\",\n        #[allow(clippy::match_same_arms)]\n        _ => \"b\",\n    };\n\n    match 3 {\n        0 => \"a\",\n        1 => \"b\",\n        //~^ match_same_arms\n        2 => \"b\",\n        #[expect(clippy::match_same_arms)]\n        _ => \"b\",\n    };\n}\n"
  },
  {
    "path": "tests/ui/match_same_arms2.stderr",
    "content": "error: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:17:9\n   |\nLL | /         42 => {\nLL | |             foo();\nLL | |             let mut a = 42 + [23].len() as i32;\nLL | |             if true {\n...  |\nLL | |             a\nLL | |         },\n   | |_________^\nLL |\nLL | /         _ => {\nLL | |             foo();\nLL | |             let mut a = 42 + [23].len() as i32;\nLL | |             if true {\n...  |\nLL | |             a\nLL | |         },\n   | |_________^ the wildcard arm\n   |\n   = help: if this is unintentional make the arms return different values\n   = note: `-D clippy::match-same-arms` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`\nhelp: otherwise remove the non-wildcard arm\n   |\nLL -         42 => {\nLL -             foo();\nLL -             let mut a = 42 + [23].len() as i32;\nLL -             if true {\nLL -                 a += 7;\nLL -             }\nLL -             a = -31 - a;\nLL -             a\nLL -         },\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:39:9\n   |\nLL |         42 => foo(),\n   |         ^^^^^^^^^^^\nLL |\nLL |         51 => foo(),\n   |         ^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         42 | 51 => foo(),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:46:9\n   |\nLL |         Some(_) => 24,\n   |         ^^^^^^^^^^^^^\nLL |\nLL |         None => 24,\n   |         ^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         Some(_) | None => 24,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:69:9\n   |\nLL |         (Some(a), None) => bar(a),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         (None, Some(a)) => bar(a),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         (Some(a), None) | (None, Some(a)) => bar(a),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:84:9\n   |\nLL |         (Some(a), None) if a == 42 => a,\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         (None, Some(a)) if a == 42 => a,\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         (Some(a), None) | (None, Some(a)) if a == 42 => a,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:91:9\n   |\nLL |         (Some(a), ..) => bar(a),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         (.., Some(a)) => bar(a),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~         (Some(a), ..) | (.., Some(a)) => bar(a),\nLL |\nLL ~         _ => (),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:126:9\n   |\nLL |         (Ok(x), Some(_)) => println!(\"ok {}\", x),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         (Ok(_), Some(x)) => println!(\"ok {}\", x),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~         (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!(\"ok {}\", x),\nLL |\nLL ~         _ => println!(\"err\"),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:142:9\n   |\nLL |         Ok(3) => println!(\"ok\"),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         Ok(_) => println!(\"ok\"),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         Ok(3) | Ok(_) => println!(\"ok\"),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:168:9\n   |\nLL | /         0 => {\nLL | |             empty!(0);\nLL | |         },\n   | |_________^\nLL |\nLL | /         1 => {\nLL | |             empty!(0);\nLL | |         },\n   | |_________^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         0 | 1 => {\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:222:9\n   |\nLL |         Foo::X(0) => 1,\n   |         ^^^^^^^^^^^^^^\n...\nLL |         Foo::Z(_) => 1,\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~         Foo::X(0) | Foo::Z(_) => 1,\nLL |\nLL |         Foo::X(_) | Foo::Y(_) => 2,\nLL ~         _ => 0,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:231:9\n   |\nLL |         Foo::X(0) => 1,\n   |         ^^^^^^^^^^^^^^\n...\nLL |         Foo::Z(_) => 1,\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL |         Foo::Y(_) | Foo::Z(0) => 2,\nLL ~         Foo::X(0) | Foo::Z(_) => 1,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:254:9\n   |\nLL |         Some(Bar { x: 0, y: 5, .. }) => 1,\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         Some(Bar { y: 0, x: 5, .. }) => 1,\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL |         Some(Bar { y: 10, z: 0, .. }) => 2,\nLL |         None => 50,\nLL ~         Some(Bar { x: 0, y: 5, .. }) | Some(Bar { y: 0, x: 5, .. }) => 1,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:271:9\n   |\nLL |         0 => cfg!(not_enable),\n   |         ^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         1 => cfg!(not_enable),\n   |         ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         0 | 1 => cfg!(not_enable),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:288:17\n   |\nLL |                 MaybeStaticStr::Static(s) => s,\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |                 MaybeStaticStr::Borrowed(s) => s,\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~                 MaybeStaticStr::Static(s) | MaybeStaticStr::Borrowed(s) => s,\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:306:9\n   |\nLL |         1 => \"b\",\n   |         ^^^^^^^^\nLL |\nLL |         2 => \"b\",\n   |         ^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~         1 | 2 => \"b\",\nLL |\nLL ~         #[allow(clippy::match_same_arms)]\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms2.rs:315:9\n   |\nLL |         1 => \"b\",\n   |         ^^^^^^^^\nLL |\nLL |         2 => \"b\",\n   |         ^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~         1 | 2 => \"b\",\nLL |\nLL ~         #[expect(clippy::match_same_arms)]\n   |\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_same_arms_non_exhaustive.fixed",
    "content": "#![feature(non_exhaustive_omitted_patterns_lint)]\n#![warn(clippy::match_same_arms)]\n#![no_main]\nuse std::sync::atomic::Ordering; // #[non_exhaustive] enum\n\nfn repeat() -> ! {\n    panic!()\n}\n\n#[deny(non_exhaustive_omitted_patterns)]\npub fn f(x: Ordering) {\n    match x {\n        Ordering::Relaxed => println!(\"relaxed\"),\n        Ordering::Release => println!(\"release\"),\n        Ordering::Acquire => println!(\"acquire\"),\n        //~^ match_same_arms\n        Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),\n    }\n\n    match x {\n        Ordering::Relaxed => println!(\"relaxed\"),\n        Ordering::Release => println!(\"release\"),\n        Ordering::Acquire => println!(\"acquire\"),\n        //~^ match_same_arms\n        Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),\n    }\n}\n\nmod f {\n    #![deny(non_exhaustive_omitted_patterns)]\n\n    use super::*;\n\n    pub fn f(x: Ordering) {\n        match x {\n            Ordering::Relaxed => println!(\"relaxed\"),\n            Ordering::Release => println!(\"release\"),\n            Ordering::Acquire => println!(\"acquire\"),\n            //~^ match_same_arms\n            Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),\n        }\n    }\n}\n\n// Below can still suggest removing the other patterns\n\npub fn g(x: Ordering) {\n    match x {\n        Ordering::Relaxed => println!(\"relaxed\"),\n        Ordering::Release => println!(\"release\"),\n        Ordering::Acquire => println!(\"acquire\"),\n        _ => repeat(),\n        //~^ match_same_arms\n    }\n}\n\nmod g {\n    use super::*;\n\n    pub fn g(x: Ordering) {\n        match x {\n            Ordering::Relaxed => println!(\"relaxed\"),\n            Ordering::Release => println!(\"release\"),\n            Ordering::Acquire => println!(\"acquire\"),\n            _ => repeat(),\n            //~^ match_same_arms\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/match_same_arms_non_exhaustive.rs",
    "content": "#![feature(non_exhaustive_omitted_patterns_lint)]\n#![warn(clippy::match_same_arms)]\n#![no_main]\nuse std::sync::atomic::Ordering; // #[non_exhaustive] enum\n\nfn repeat() -> ! {\n    panic!()\n}\n\n#[deny(non_exhaustive_omitted_patterns)]\npub fn f(x: Ordering) {\n    match x {\n        Ordering::Relaxed => println!(\"relaxed\"),\n        Ordering::Release => println!(\"release\"),\n        Ordering::Acquire => println!(\"acquire\"),\n        Ordering::AcqRel | Ordering::SeqCst => repeat(),\n        //~^ match_same_arms\n        _ => repeat(),\n    }\n\n    match x {\n        Ordering::Relaxed => println!(\"relaxed\"),\n        Ordering::Release => println!(\"release\"),\n        Ordering::Acquire => println!(\"acquire\"),\n        Ordering::AcqRel => repeat(),\n        //~^ match_same_arms\n        Ordering::SeqCst | _ => repeat(),\n    }\n}\n\nmod f {\n    #![deny(non_exhaustive_omitted_patterns)]\n\n    use super::*;\n\n    pub fn f(x: Ordering) {\n        match x {\n            Ordering::Relaxed => println!(\"relaxed\"),\n            Ordering::Release => println!(\"release\"),\n            Ordering::Acquire => println!(\"acquire\"),\n            Ordering::AcqRel | Ordering::SeqCst => repeat(),\n            //~^ match_same_arms\n            _ => repeat(),\n        }\n    }\n}\n\n// Below can still suggest removing the other patterns\n\npub fn g(x: Ordering) {\n    match x {\n        Ordering::Relaxed => println!(\"relaxed\"),\n        Ordering::Release => println!(\"release\"),\n        Ordering::Acquire => println!(\"acquire\"),\n        Ordering::AcqRel | Ordering::SeqCst => repeat(),\n        _ => repeat(),\n        //~^ match_same_arms\n    }\n}\n\nmod g {\n    use super::*;\n\n    pub fn g(x: Ordering) {\n        match x {\n            Ordering::Relaxed => println!(\"relaxed\"),\n            Ordering::Release => println!(\"release\"),\n            Ordering::Acquire => println!(\"acquire\"),\n            Ordering::AcqRel | Ordering::SeqCst => repeat(),\n            _ => repeat(),\n            //~^ match_same_arms\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/match_same_arms_non_exhaustive.stderr",
    "content": "error: these match arms have identical bodies\n  --> tests/ui/match_same_arms_non_exhaustive.rs:16:9\n   |\nLL |         Ordering::AcqRel | Ordering::SeqCst => repeat(),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         _ => repeat(),\n   |         ^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\n   = note: `-D clippy::match-same-arms` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms_non_exhaustive.rs:25:9\n   |\nLL |         Ordering::AcqRel => repeat(),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         Ordering::SeqCst | _ => repeat(),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~         Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms_non_exhaustive.rs:41:13\n   |\nLL |             Ordering::AcqRel | Ordering::SeqCst => repeat(),\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |             _ => repeat(),\n   |             ^^^^^^^^^^^^^\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise merge the patterns into a single arm\n   |\nLL ~\nLL ~             Ordering::AcqRel | Ordering::SeqCst | _ => repeat(),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms_non_exhaustive.rs:55:9\n   |\nLL |         Ordering::AcqRel | Ordering::SeqCst => repeat(),\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |         _ => repeat(),\n   |         ^^^^^^^^^^^^^ the wildcard arm\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise remove the non-wildcard arm\n   |\nLL -         Ordering::AcqRel | Ordering::SeqCst => repeat(),\n   |\n\nerror: these match arms have identical bodies\n  --> tests/ui/match_same_arms_non_exhaustive.rs:69:13\n   |\nLL |             Ordering::AcqRel | Ordering::SeqCst => repeat(),\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |             _ => repeat(),\n   |             ^^^^^^^^^^^^^ the wildcard arm\n   |\n   = help: if this is unintentional make the arms return different values\nhelp: otherwise remove the non-wildcard arm\n   |\nLL -             Ordering::AcqRel | Ordering::SeqCst => repeat(),\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_single_binding.fixed",
    "content": "#![warn(clippy::match_single_binding)]\n#![allow(\n    unused,\n    clippy::let_unit_value,\n    clippy::no_effect,\n    clippy::toplevel_ref_arg,\n    clippy::useless_vec\n)]\n\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nfn coords() -> Point {\n    Point { x: 1, y: 2 }\n}\n\nmacro_rules! foo {\n    ($param:expr) => {\n        match $param {\n            _ => println!(\"whatever\"),\n        }\n    };\n}\n\nfn main() {\n    let a = 1;\n    let b = 2;\n    let c = 3;\n    // Lint\n    let (x, y, z) = (a, b, c);\n    {\n        println!(\"{x} {y} {z}\");\n    }\n    // Lint\n    let (x, y, z) = (a, b, c);\n    println!(\"{x} {y} {z}\");\n    // Ok\n    foo!(a);\n    // Ok\n    match a {\n        2 => println!(\"2\"),\n        _ => println!(\"Not 2\"),\n    }\n    // Ok\n    let d = Some(5);\n    match d {\n        Some(d) => println!(\"{d}\"),\n        _ => println!(\"None\"),\n    }\n    // Lint\n    println!(\"whatever\");\n    // Lint\n    {\n        let x = 29;\n        println!(\"x has a value of {x}\");\n    }\n    // Lint\n    {\n        let e = 5 * a;\n        if e >= 5 {\n            println!(\"e is superior to 5\");\n        }\n    }\n    // Lint\n    let p = Point { x: 0, y: 7 };\n    let Point { x, y } = p;\n    println!(\"Coords: ({x}, {y})\");\n    // Lint\n    let Point { x: x1, y: y1 } = p;\n    println!(\"Coords: ({x1}, {y1})\");\n    // Lint\n    let x = 5;\n    let ref r = x;\n    println!(\"Got a reference to {r}\");\n    // Lint\n    let mut x = 5;\n    let ref mut mr = x;\n    println!(\"Got a mutable reference to {mr}\");\n    // Lint\n    let Point { x, y } = coords();\n    let product = x * y;\n    // Lint\n    let v = vec![Some(1), Some(2), Some(3), Some(4)];\n    #[allow(clippy::let_and_return)]\n    let _ = v\n        .iter()\n        .map(|i| {\n            let unwrapped = i.unwrap();\n            unwrapped\n        })\n        .collect::<Vec<u8>>();\n    // Ok\n    let x = 1;\n    match x {\n        #[cfg(disabled_feature)]\n        0 => println!(\"Disabled branch\"),\n        _ => println!(\"Enabled branch\"),\n    }\n\n    // Ok\n    let x = 1;\n    let y = 1;\n    match match y {\n        0 => 1,\n        _ => 2,\n    } {\n        #[cfg(disabled_feature)]\n        0 => println!(\"Array index start\"),\n        _ => println!(\"Not an array index start\"),\n    }\n\n    // Lint\n    let x = 1;\n    println!(\"Not an array index start\")\n}\n\nfn issue_8723() {\n    let (mut val, idx) = (\"a b\", 1);\n\n    let (pre, suf) = val.split_at(idx);\n    val = {\n        println!(\"{pre}\");\n        suf\n    };\n\n    let _ = val;\n}\n\nfn side_effects() {}\n\nfn issue_9575() {\n    let _ = || {\n        side_effects();\n        println!(\"Needs curlies\")\n    };\n}\n\nfn issue_9725(r: Option<u32>) {\n    let x = r;\n    match x {\n        Some(_) => {\n            println!(\"Some\");\n        },\n        None => {\n            println!(\"None\");\n        },\n    };\n}\n\nfn issue_10447() -> usize {\n    ();\n\n    let a = ();\n\n    side_effects();\n\n    let b = side_effects();\n\n    println!(\"1\");\n\n    let c = println!(\"1\");\n\n    let in_expr = [\n        (),\n        side_effects(),\n        println!(\"1\"),\n    ];\n\n    2\n}\n\nfn issue14634() {\n    macro_rules! id {\n        ($i:ident) => {\n            $i\n        };\n    }\n    dbg!(3);\n    println!(\"here\");\n    //~^^^ match_single_binding\n    let id!(a) = dbg!(3);\n    println!(\"found {a}\");\n    //~^^^ match_single_binding\n    let id!(b) = dbg!(3);\n    let id!(_a) = dbg!(b + 1);\n    //~^^^ match_single_binding\n}\n\nmod issue14991 {\n    struct AnnoConstWOBlock {\n        inner: [(); {\n            let _n = 1;\n            42\n        }],\n    }\n\n    struct AnnoConstWBlock {\n        inner: [(); {\n            let _n = 1;\n            42\n        }],\n    }\n}\n\nmod issue15018 {\n    fn used_later(a: i32, b: i32, c: i32) {\n        let x = 1;\n        {\n            let (x, y, z) = (a, b, c);\n            println!(\"{x} {y} {z}\");\n        }\n        println!(\"x = {x}\");\n    }\n\n    fn not_used_later(a: i32, b: i32, c: i32) {\n        let (x, y, z) = (a, b, c);\n        println!(\"{x} {y} {z}\")\n    }\n\n    #[allow(irrefutable_let_patterns)]\n    fn not_used_later_but_shadowed(a: i32, b: i32, c: i32) {\n        let (x, y, z) = (a, b, c);\n        println!(\"{x} {y} {z}\");\n        let x = 1;\n        println!(\"x = {x}\");\n    }\n\n    #[allow(irrefutable_let_patterns)]\n    fn not_used_later_but_shadowed_nested(a: i32, b: i32, c: i32) {\n        let (x, y, z) = (a, b, c);\n        println!(\"{x} {x} {y}\");\n        if let (x, y, z) = (a, b, c) {\n            println!(\"{x} {y} {z}\")\n        }\n\n        {\n            let x: i32 = 1;\n            {\n                let (x, y, z) = (a, b, c);\n                println!(\"{x} {y} {z}\");\n            }\n            if let (x, y, z) = (a, x, c) {\n                println!(\"{x} {y} {z}\")\n            }\n        }\n\n        {\n            let (x, y, z) = (a, b, c);\n            println!(\"{x} {y} {z}\");\n            let fn_ = |y| {\n                println!(\"{a} {b} {y}\");\n            };\n            fn_(c);\n        }\n    }\n}\n\n#[allow(clippy::short_circuit_statement)]\nfn issue15269(a: usize, b: usize, c: usize) -> bool {\n    a < b\n        && b < c;\n\n    a < b\n        && b < c\n}\n\n#[allow(\n    irrefutable_let_patterns,\n    clippy::blocks_in_conditions,\n    clippy::unused_unit,\n    clippy::let_unit_value,\n    clippy::unit_arg,\n    clippy::unnecessary_operation\n)]\nfn issue15537(a: i32) -> ((), (), ()) {\n    let y = (\n        { todo!() },\n        {\n            { a };\n            ()\n        },\n        (),\n    );\n\n    let y = [\n        { todo!() },\n        {\n            { a };\n            ()\n        },\n        (),\n    ];\n\n    fn call(x: (), y: (), z: ()) {}\n    let y = call(\n        { todo!() },\n        {\n            { a };\n            ()\n        },\n        (),\n    );\n\n    struct Foo;\n    impl Foo {\n        fn method(&self, x: (), y: (), z: ()) {}\n    }\n    let x = Foo;\n    x.method(\n        { todo!() },\n        {\n            { a };\n            ()\n        },\n        (),\n    );\n\n    -{\n        { a };\n        1\n    };\n\n    _ = { a };\n    1;\n\n    if let x = {\n        { a };\n        1\n    } {}\n\n    if {\n        { a };\n        true\n    } {\n        todo!()\n    }\n\n    [1, 2, 3][{\n        { a };\n        1usize\n    }];\n\n    todo!()\n}\n"
  },
  {
    "path": "tests/ui/match_single_binding.rs",
    "content": "#![warn(clippy::match_single_binding)]\n#![allow(\n    unused,\n    clippy::let_unit_value,\n    clippy::no_effect,\n    clippy::toplevel_ref_arg,\n    clippy::useless_vec\n)]\n\nstruct Point {\n    x: i32,\n    y: i32,\n}\n\nfn coords() -> Point {\n    Point { x: 1, y: 2 }\n}\n\nmacro_rules! foo {\n    ($param:expr) => {\n        match $param {\n            _ => println!(\"whatever\"),\n        }\n    };\n}\n\nfn main() {\n    let a = 1;\n    let b = 2;\n    let c = 3;\n    // Lint\n    match (a, b, c) {\n        //~^ match_single_binding\n        (x, y, z) => {\n            println!(\"{x} {y} {z}\");\n        },\n    }\n    // Lint\n    match (a, b, c) {\n        //~^ match_single_binding\n        (x, y, z) => println!(\"{x} {y} {z}\"),\n    }\n    // Ok\n    foo!(a);\n    // Ok\n    match a {\n        2 => println!(\"2\"),\n        _ => println!(\"Not 2\"),\n    }\n    // Ok\n    let d = Some(5);\n    match d {\n        Some(d) => println!(\"{d}\"),\n        _ => println!(\"None\"),\n    }\n    // Lint\n    match a {\n        //~^ match_single_binding\n        _ => println!(\"whatever\"),\n    }\n    // Lint\n    match a {\n        //~^ match_single_binding\n        _ => {\n            let x = 29;\n            println!(\"x has a value of {x}\");\n        },\n    }\n    // Lint\n    match a {\n        //~^ match_single_binding\n        _ => {\n            let e = 5 * a;\n            if e >= 5 {\n                println!(\"e is superior to 5\");\n            }\n        },\n    }\n    // Lint\n    let p = Point { x: 0, y: 7 };\n    match p {\n        //~^ match_single_binding\n        Point { x, y } => println!(\"Coords: ({x}, {y})\"),\n    }\n    // Lint\n    match p {\n        //~^ match_single_binding\n        Point { x: x1, y: y1 } => println!(\"Coords: ({x1}, {y1})\"),\n    }\n    // Lint\n    let x = 5;\n    match x {\n        //~^ match_single_binding\n        ref r => println!(\"Got a reference to {r}\"),\n    }\n    // Lint\n    let mut x = 5;\n    match x {\n        //~^ match_single_binding\n        ref mut mr => println!(\"Got a mutable reference to {mr}\"),\n    }\n    // Lint\n    let product = match coords() {\n        //~^ match_single_binding\n        Point { x, y } => x * y,\n    };\n    // Lint\n    let v = vec![Some(1), Some(2), Some(3), Some(4)];\n    #[allow(clippy::let_and_return)]\n    let _ = v\n        .iter()\n        .map(|i| match i.unwrap() {\n            //~^ match_single_binding\n            unwrapped => unwrapped,\n        })\n        .collect::<Vec<u8>>();\n    // Ok\n    let x = 1;\n    match x {\n        #[cfg(disabled_feature)]\n        0 => println!(\"Disabled branch\"),\n        _ => println!(\"Enabled branch\"),\n    }\n\n    // Ok\n    let x = 1;\n    let y = 1;\n    match match y {\n        0 => 1,\n        _ => 2,\n    } {\n        #[cfg(disabled_feature)]\n        0 => println!(\"Array index start\"),\n        _ => println!(\"Not an array index start\"),\n    }\n\n    // Lint\n    let x = 1;\n    match x {\n        //~^ match_single_binding\n        // =>\n        _ => println!(\"Not an array index start\"),\n    }\n}\n\nfn issue_8723() {\n    let (mut val, idx) = (\"a b\", 1);\n\n    val = match val.split_at(idx) {\n        //~^ match_single_binding\n        (pre, suf) => {\n            println!(\"{pre}\");\n            suf\n        },\n    };\n\n    let _ = val;\n}\n\nfn side_effects() {}\n\nfn issue_9575() {\n    let _ = || match side_effects() {\n        //~^ match_single_binding\n        _ => println!(\"Needs curlies\"),\n    };\n}\n\nfn issue_9725(r: Option<u32>) {\n    match r {\n        //~^ match_single_binding\n        x => match x {\n            Some(_) => {\n                println!(\"Some\");\n            },\n            None => {\n                println!(\"None\");\n            },\n        },\n    };\n}\n\nfn issue_10447() -> usize {\n    match 1 {\n        //~^ match_single_binding\n        _ => (),\n    }\n\n    let a = match 1 {\n        //~^ match_single_binding\n        _ => (),\n    };\n\n    match 1 {\n        //~^ match_single_binding\n        _ => side_effects(),\n    }\n\n    let b = match 1 {\n        //~^ match_single_binding\n        _ => side_effects(),\n    };\n\n    match 1 {\n        //~^ match_single_binding\n        _ => println!(\"1\"),\n    }\n\n    let c = match 1 {\n        //~^ match_single_binding\n        _ => println!(\"1\"),\n    };\n\n    let in_expr = [\n        match 1 {\n            //~^ match_single_binding\n            _ => (),\n        },\n        match 1 {\n            //~^ match_single_binding\n            _ => side_effects(),\n        },\n        match 1 {\n            //~^ match_single_binding\n            _ => println!(\"1\"),\n        },\n    ];\n\n    2\n}\n\nfn issue14634() {\n    macro_rules! id {\n        ($i:ident) => {\n            $i\n        };\n    }\n    match dbg!(3) {\n        _ => println!(\"here\"),\n    }\n    //~^^^ match_single_binding\n    match dbg!(3) {\n        id!(a) => println!(\"found {a}\"),\n    }\n    //~^^^ match_single_binding\n    let id!(_a) = match dbg!(3) {\n        id!(b) => dbg!(b + 1),\n    };\n    //~^^^ match_single_binding\n}\n\nmod issue14991 {\n    struct AnnoConstWOBlock {\n        inner: [(); match 1 {\n            //~^ match_single_binding\n            _n => 42,\n        }],\n    }\n\n    struct AnnoConstWBlock {\n        inner: [(); {\n            match 1 {\n                //~^ match_single_binding\n                _n => 42,\n            }\n        }],\n    }\n}\n\nmod issue15018 {\n    fn used_later(a: i32, b: i32, c: i32) {\n        let x = 1;\n        match (a, b, c) {\n            //~^ match_single_binding\n            (x, y, z) => println!(\"{x} {y} {z}\"),\n        }\n        println!(\"x = {x}\");\n    }\n\n    fn not_used_later(a: i32, b: i32, c: i32) {\n        match (a, b, c) {\n            //~^ match_single_binding\n            (x, y, z) => println!(\"{x} {y} {z}\"),\n        }\n    }\n\n    #[allow(irrefutable_let_patterns)]\n    fn not_used_later_but_shadowed(a: i32, b: i32, c: i32) {\n        match (a, b, c) {\n            //~^ match_single_binding\n            (x, y, z) => println!(\"{x} {y} {z}\"),\n        }\n        let x = 1;\n        println!(\"x = {x}\");\n    }\n\n    #[allow(irrefutable_let_patterns)]\n    fn not_used_later_but_shadowed_nested(a: i32, b: i32, c: i32) {\n        match (a, b, c) {\n            //~^ match_single_binding\n            (x, y, z) => println!(\"{x} {x} {y}\"),\n        }\n        if let (x, y, z) = (a, b, c) {\n            println!(\"{x} {y} {z}\")\n        }\n\n        {\n            let x: i32 = 1;\n            match (a, b, c) {\n                //~^ match_single_binding\n                (x, y, z) => println!(\"{x} {y} {z}\"),\n            }\n            if let (x, y, z) = (a, x, c) {\n                println!(\"{x} {y} {z}\")\n            }\n        }\n\n        {\n            match (a, b, c) {\n                //~^ match_single_binding\n                (x, y, z) => println!(\"{x} {y} {z}\"),\n            }\n            let fn_ = |y| {\n                println!(\"{a} {b} {y}\");\n            };\n            fn_(c);\n        }\n    }\n}\n\n#[allow(clippy::short_circuit_statement)]\nfn issue15269(a: usize, b: usize, c: usize) -> bool {\n    a < b\n        && match b {\n            //~^ match_single_binding\n            b => b < c,\n        };\n\n    a < b\n        && match (a, b) {\n            //~^ match_single_binding\n            (a, b) => b < c,\n        }\n}\n\n#[allow(\n    irrefutable_let_patterns,\n    clippy::blocks_in_conditions,\n    clippy::unused_unit,\n    clippy::let_unit_value,\n    clippy::unit_arg,\n    clippy::unnecessary_operation\n)]\nfn issue15537(a: i32) -> ((), (), ()) {\n    let y = (\n        { todo!() },\n        match { a } {\n            //~^ match_single_binding\n            _ => (),\n        },\n        (),\n    );\n\n    let y = [\n        { todo!() },\n        match { a } {\n            //~^ match_single_binding\n            _ => (),\n        },\n        (),\n    ];\n\n    fn call(x: (), y: (), z: ()) {}\n    let y = call(\n        { todo!() },\n        match { a } {\n            //~^ match_single_binding\n            _ => (),\n        },\n        (),\n    );\n\n    struct Foo;\n    impl Foo {\n        fn method(&self, x: (), y: (), z: ()) {}\n    }\n    let x = Foo;\n    x.method(\n        { todo!() },\n        match { a } {\n            //~^ match_single_binding\n            _ => (),\n        },\n        (),\n    );\n\n    -match { a } {\n        //~^ match_single_binding\n        _ => 1,\n    };\n\n    _ = match { a } {\n        //~^ match_single_binding\n        _ => 1,\n    };\n\n    if let x = match { a } {\n        //~^ match_single_binding\n        _ => 1,\n    } {}\n\n    if match { a } {\n        //~^ match_single_binding\n        _ => true,\n    } {\n        todo!()\n    }\n\n    [1, 2, 3][match { a } {\n        //~^ match_single_binding\n        _ => 1usize,\n    }];\n\n    todo!()\n}\n"
  },
  {
    "path": "tests/ui/match_single_binding.stderr",
    "content": "error: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:32:5\n   |\nLL | /     match (a, b, c) {\nLL | |\nLL | |         (x, y, z) => {\nLL | |             println!(\"{x} {y} {z}\");\nLL | |         },\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::match-single-binding` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_single_binding)]`\nhelp: consider using a `let` statement\n   |\nLL ~     let (x, y, z) = (a, b, c);\nLL +     {\nLL +         println!(\"{x} {y} {z}\");\nLL +     }\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:39:5\n   |\nLL | /     match (a, b, c) {\nLL | |\nLL | |         (x, y, z) => println!(\"{x} {y} {z}\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let (x, y, z) = (a, b, c);\nLL +     println!(\"{x} {y} {z}\");\n   |\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:57:5\n   |\nLL | /     match a {\nLL | |\nLL | |         _ => println!(\"whatever\"),\nLL | |     }\n   | |_____^ help: consider using the match body instead: `println!(\"whatever\");`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:62:5\n   |\nLL | /     match a {\nLL | |\nLL | |         _ => {\nLL | |             let x = 29;\nLL | |             println!(\"x has a value of {x}\");\nLL | |         },\nLL | |     }\n   | |_____^\n   |\nhelp: consider using the match body instead\n   |\nLL ~     {\nLL +         let x = 29;\nLL +         println!(\"x has a value of {x}\");\nLL +     }\n   |\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:70:5\n   |\nLL | /     match a {\nLL | |\nLL | |         _ => {\nLL | |             let e = 5 * a;\n...  |\nLL | |         },\nLL | |     }\n   | |_____^\n   |\nhelp: consider using the match body instead\n   |\nLL ~     {\nLL +         let e = 5 * a;\nLL +         if e >= 5 {\nLL +             println!(\"e is superior to 5\");\nLL +         }\nLL +     }\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:81:5\n   |\nLL | /     match p {\nLL | |\nLL | |         Point { x, y } => println!(\"Coords: ({x}, {y})\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let Point { x, y } = p;\nLL +     println!(\"Coords: ({x}, {y})\");\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:86:5\n   |\nLL | /     match p {\nLL | |\nLL | |         Point { x: x1, y: y1 } => println!(\"Coords: ({x1}, {y1})\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let Point { x: x1, y: y1 } = p;\nLL +     println!(\"Coords: ({x1}, {y1})\");\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:92:5\n   |\nLL | /     match x {\nLL | |\nLL | |         ref r => println!(\"Got a reference to {r}\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let ref r = x;\nLL +     println!(\"Got a reference to {r}\");\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:98:5\n   |\nLL | /     match x {\nLL | |\nLL | |         ref mut mr => println!(\"Got a mutable reference to {mr}\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let ref mut mr = x;\nLL +     println!(\"Got a mutable reference to {mr}\");\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:103:5\n   |\nLL | /     let product = match coords() {\nLL | |\nLL | |         Point { x, y } => x * y,\nLL | |     };\n   | |______^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let Point { x, y } = coords();\nLL +     let product = x * y;\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:112:18\n   |\nLL |           .map(|i| match i.unwrap() {\n   |  __________________^\nLL | |\nLL | |             unwrapped => unwrapped,\nLL | |         })\n   | |_________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~         .map(|i| {\nLL +             let unwrapped = i.unwrap();\nLL +             unwrapped\nLL ~         })\n   |\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:139:5\n   |\nLL | /     match x {\nLL | |\nLL | |         // =>\nLL | |         _ => println!(\"Not an array index start\"),\nLL | |     }\n   | |_____^ help: consider using the match body instead: `println!(\"Not an array index start\")`\n\nerror: this assignment could be simplified\n  --> tests/ui/match_single_binding.rs:149:5\n   |\nLL | /     val = match val.split_at(idx) {\nLL | |\nLL | |         (pre, suf) => {\nLL | |             println!(\"{pre}\");\nLL | |             suf\nLL | |         },\nLL | |     };\n   | |_____^\n   |\nhelp: consider removing the `match` expression\n   |\nLL ~     let (pre, suf) = val.split_at(idx);\nLL +     val = {\nLL +         println!(\"{pre}\");\nLL +         suf\nLL ~     };\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:163:16\n   |\nLL |       let _ = || match side_effects() {\n   |  ________________^\nLL | |\nLL | |         _ => println!(\"Needs curlies\"),\nLL | |     };\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     let _ = || {\nLL +         side_effects();\nLL +         println!(\"Needs curlies\")\nLL ~     };\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:170:5\n   |\nLL | /     match r {\nLL | |\nLL | |         x => match x {\nLL | |             Some(_) => {\n...  |\nLL | |         },\nLL | |     };\n   | |_____^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let x = r;\nLL +     match x {\nLL +         Some(_) => {\nLL +             println!(\"Some\");\nLL +         },\nLL +         None => {\nLL +             println!(\"None\");\nLL +         },\nLL ~     };\n   |\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:184:5\n   |\nLL | /     match 1 {\nLL | |\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: consider using the match body instead: `();`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:189:13\n   |\nLL |       let a = match 1 {\n   |  _____________^\nLL | |\nLL | |         _ => (),\nLL | |     };\n   | |_____^ help: consider using the match body instead: `()`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:194:5\n   |\nLL | /     match 1 {\nLL | |\nLL | |         _ => side_effects(),\nLL | |     }\n   | |_____^ help: consider using the match body instead: `side_effects();`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:199:13\n   |\nLL |       let b = match 1 {\n   |  _____________^\nLL | |\nLL | |         _ => side_effects(),\nLL | |     };\n   | |_____^ help: consider using the match body instead: `side_effects()`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:204:5\n   |\nLL | /     match 1 {\nLL | |\nLL | |         _ => println!(\"1\"),\nLL | |     }\n   | |_____^ help: consider using the match body instead: `println!(\"1\");`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:209:13\n   |\nLL |       let c = match 1 {\n   |  _____________^\nLL | |\nLL | |         _ => println!(\"1\"),\nLL | |     };\n   | |_____^ help: consider using the match body instead: `println!(\"1\")`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:215:9\n   |\nLL | /         match 1 {\nLL | |\nLL | |             _ => (),\nLL | |         },\n   | |_________^ help: consider using the match body instead: `()`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:219:9\n   |\nLL | /         match 1 {\nLL | |\nLL | |             _ => side_effects(),\nLL | |         },\n   | |_________^ help: consider using the match body instead: `side_effects()`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:223:9\n   |\nLL | /         match 1 {\nLL | |\nLL | |             _ => println!(\"1\"),\nLL | |         },\n   | |_________^ help: consider using the match body instead: `println!(\"1\")`\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:238:5\n   |\nLL | /     match dbg!(3) {\nLL | |         _ => println!(\"here\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     dbg!(3);\nLL +     println!(\"here\");\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:242:5\n   |\nLL | /     match dbg!(3) {\nLL | |         id!(a) => println!(\"found {a}\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let id!(a) = dbg!(3);\nLL +     println!(\"found {a}\");\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:246:5\n   |\nLL | /     let id!(_a) = match dbg!(3) {\nLL | |         id!(b) => dbg!(b + 1),\nLL | |     };\n   | |______^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~     let id!(b) = dbg!(3);\nLL +     let id!(_a) = dbg!(b + 1);\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:254:21\n   |\nLL |           inner: [(); match 1 {\n   |  _____________________^\nLL | |\nLL | |             _n => 42,\nLL | |         }],\n   | |_________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~         inner: [(); {\nLL +             let _n = 1;\nLL +             42\nLL ~         }],\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:262:13\n   |\nLL | /             match 1 {\nLL | |\nLL | |                 _n => 42,\nLL | |             }\n   | |_____________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~             let _n = 1;\nLL +             42\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:273:9\n   |\nLL | /         match (a, b, c) {\nLL | |\nLL | |             (x, y, z) => println!(\"{x} {y} {z}\"),\nLL | |         }\n   | |_________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~         {\nLL +             let (x, y, z) = (a, b, c);\nLL +             println!(\"{x} {y} {z}\");\nLL +         }\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:281:9\n   |\nLL | /         match (a, b, c) {\nLL | |\nLL | |             (x, y, z) => println!(\"{x} {y} {z}\"),\nLL | |         }\n   | |_________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~         let (x, y, z) = (a, b, c);\nLL +         println!(\"{x} {y} {z}\")\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:289:9\n   |\nLL | /         match (a, b, c) {\nLL | |\nLL | |             (x, y, z) => println!(\"{x} {y} {z}\"),\nLL | |         }\n   | |_________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~         let (x, y, z) = (a, b, c);\nLL +         println!(\"{x} {y} {z}\");\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:299:9\n   |\nLL | /         match (a, b, c) {\nLL | |\nLL | |             (x, y, z) => println!(\"{x} {x} {y}\"),\nLL | |         }\n   | |_________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~         let (x, y, z) = (a, b, c);\nLL +         println!(\"{x} {x} {y}\");\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:309:13\n   |\nLL | /             match (a, b, c) {\nLL | |\nLL | |                 (x, y, z) => println!(\"{x} {y} {z}\"),\nLL | |             }\n   | |_____________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~             {\nLL +                 let (x, y, z) = (a, b, c);\nLL +                 println!(\"{x} {y} {z}\");\nLL +             }\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding.rs:319:13\n   |\nLL | /             match (a, b, c) {\nLL | |\nLL | |                 (x, y, z) => println!(\"{x} {y} {z}\"),\nLL | |             }\n   | |_____________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~             let (x, y, z) = (a, b, c);\nLL +             println!(\"{x} {y} {z}\");\n   |\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:334:12\n   |\nLL |           && match b {\n   |  ____________^\nLL | |\nLL | |             b => b < c,\nLL | |         };\n   | |_________^ help: consider using the match body instead: `b < c`\n\nerror: this match could be replaced by its body itself\n  --> tests/ui/match_single_binding.rs:340:12\n   |\nLL |           && match (a, b) {\n   |  ____________^\nLL | |\nLL | |             (a, b) => b < c,\nLL | |         }\n   | |_________^ help: consider using the match body instead: `b < c`\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:357:9\n   |\nLL | /         match { a } {\nLL | |\nLL | |             _ => (),\nLL | |         },\n   | |_________^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~         {\nLL +             { a };\nLL +             ()\nLL ~         },\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:366:9\n   |\nLL | /         match { a } {\nLL | |\nLL | |             _ => (),\nLL | |         },\n   | |_________^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~         {\nLL +             { a };\nLL +             ()\nLL ~         },\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:376:9\n   |\nLL | /         match { a } {\nLL | |\nLL | |             _ => (),\nLL | |         },\n   | |_________^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~         {\nLL +             { a };\nLL +             ()\nLL ~         },\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:390:9\n   |\nLL | /         match { a } {\nLL | |\nLL | |             _ => (),\nLL | |         },\n   | |_________^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~         {\nLL +             { a };\nLL +             ()\nLL ~         },\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:397:6\n   |\nLL |       -match { a } {\n   |  ______^\nLL | |\nLL | |         _ => 1,\nLL | |     };\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     -{\nLL +         { a };\nLL +         1\nLL ~     };\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:402:9\n   |\nLL |       _ = match { a } {\n   |  _________^\nLL | |\nLL | |         _ => 1,\nLL | |     };\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     _ = { a };\nLL ~     1;\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:407:16\n   |\nLL |       if let x = match { a } {\n   |  ________________^\nLL | |\nLL | |         _ => 1,\nLL | |     } {}\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     if let x = {\nLL +         { a };\nLL +         1\nLL ~     } {}\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:412:8\n   |\nLL |       if match { a } {\n   |  ________^\nLL | |\nLL | |         _ => true,\nLL | |     } {\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     if {\nLL +         { a };\nLL +         true\nLL ~     } {\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding.rs:419:15\n   |\nLL |       [1, 2, 3][match { a } {\n   |  _______________^\nLL | |\nLL | |         _ => 1usize,\nLL | |     }];\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     [1, 2, 3][{\nLL +         { a };\nLL +         1usize\nLL ~     }];\n   |\n\nerror: aborting due to 46 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_single_binding2.fixed",
    "content": "#![warn(clippy::match_single_binding)]\n#![allow(unused_variables)]\n\nfn main() {\n    // Lint (additional curly braces needed, see #6572)\n    struct AppendIter<I>\n    where\n        I: Iterator,\n    {\n        inner: Option<(I, <I as Iterator>::Item)>,\n    }\n\n    #[allow(dead_code)]\n    fn size_hint<I: Iterator>(iter: &AppendIter<I>) -> (usize, Option<usize>) {\n        match &iter.inner {\n            Some((iter, _item)) => {\n                let (min, max) = iter.size_hint();\n                (min.saturating_add(1), max.and_then(|max| max.checked_add(1)))\n            },\n            None => (0, Some(0)),\n        }\n    }\n\n    // Lint (no additional curly braces needed)\n    let opt = Some((5, 2));\n    let get_tup = || -> (i32, i32) { (1, 2) };\n    match opt {\n        #[rustfmt::skip]\n        Some((first, _second)) => {\n            let (a, b) = get_tup();\n            println!(\"a {a:?} and b {b:?}\")\n        },\n        None => println!(\"nothing\"),\n    }\n\n    fn side_effects() {}\n\n    // Lint (scrutinee has side effects)\n    // issue #7094\n    side_effects();\n    println!(\"Side effects\");\n\n    // Lint (scrutinee has side effects)\n    // issue #7094\n    let x = 1;\n    match x {\n        //~^ match_single_binding\n        0 => 1,\n        _ => 2,\n    };\n    println!(\"Single branch\")\n}\n"
  },
  {
    "path": "tests/ui/match_single_binding2.rs",
    "content": "#![warn(clippy::match_single_binding)]\n#![allow(unused_variables)]\n\nfn main() {\n    // Lint (additional curly braces needed, see #6572)\n    struct AppendIter<I>\n    where\n        I: Iterator,\n    {\n        inner: Option<(I, <I as Iterator>::Item)>,\n    }\n\n    #[allow(dead_code)]\n    fn size_hint<I: Iterator>(iter: &AppendIter<I>) -> (usize, Option<usize>) {\n        match &iter.inner {\n            Some((iter, _item)) => match iter.size_hint() {\n                //~^ match_single_binding\n                (min, max) => (min.saturating_add(1), max.and_then(|max| max.checked_add(1))),\n            },\n            None => (0, Some(0)),\n        }\n    }\n\n    // Lint (no additional curly braces needed)\n    let opt = Some((5, 2));\n    let get_tup = || -> (i32, i32) { (1, 2) };\n    match opt {\n        #[rustfmt::skip]\n        Some((first, _second)) => {\n            match get_tup() {\n            //~^ match_single_binding\n                (a, b) => println!(\"a {a:?} and b {b:?}\"),\n            }\n        },\n        None => println!(\"nothing\"),\n    }\n\n    fn side_effects() {}\n\n    // Lint (scrutinee has side effects)\n    // issue #7094\n    match side_effects() {\n        //~^ match_single_binding\n        _ => println!(\"Side effects\"),\n    }\n\n    // Lint (scrutinee has side effects)\n    // issue #7094\n    let x = 1;\n    match match x {\n        //~^ match_single_binding\n        0 => 1,\n        _ => 2,\n    } {\n        _ => println!(\"Single branch\"),\n    }\n}\n"
  },
  {
    "path": "tests/ui/match_single_binding2.stderr",
    "content": "error: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding2.rs:16:36\n   |\nLL |               Some((iter, _item)) => match iter.size_hint() {\n   |  ____________________________________^\nLL | |\nLL | |                 (min, max) => (min.saturating_add(1), max.and_then(|max| max.checked_add(1))),\nLL | |             },\n   | |_____________^\n   |\n   = note: `-D clippy::match-single-binding` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_single_binding)]`\nhelp: consider using a `let` statement\n   |\nLL ~             Some((iter, _item)) => {\nLL +                 let (min, max) = iter.size_hint();\nLL +                 (min.saturating_add(1), max.and_then(|max| max.checked_add(1)))\nLL ~             },\n   |\n\nerror: this match could be written as a `let` statement\n  --> tests/ui/match_single_binding2.rs:30:13\n   |\nLL | /             match get_tup() {\nLL | |\nLL | |                 (a, b) => println!(\"a {a:?} and b {b:?}\"),\nLL | |             }\n   | |_____________^\n   |\nhelp: consider using a `let` statement\n   |\nLL ~             let (a, b) = get_tup();\nLL +             println!(\"a {a:?} and b {b:?}\")\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding2.rs:42:5\n   |\nLL | /     match side_effects() {\nLL | |\nLL | |         _ => println!(\"Side effects\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     side_effects();\nLL +     println!(\"Side effects\");\n   |\n\nerror: this match could be replaced by its scrutinee and body\n  --> tests/ui/match_single_binding2.rs:50:5\n   |\nLL | /     match match x {\nLL | |\nLL | |         0 => 1,\nLL | |         _ => 2,\nLL | |     } {\nLL | |         _ => println!(\"Single branch\"),\nLL | |     }\n   | |_____^\n   |\nhelp: consider using the scrutinee and body instead\n   |\nLL ~     match x {\nLL +\nLL +         0 => 1,\nLL +         _ => 2,\nLL +     };\nLL +     println!(\"Single branch\")\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_str_case_mismatch.fixed",
    "content": "#![warn(clippy::match_str_case_mismatch)]\n#![allow(dead_code)]\n\n// Valid\n\nfn as_str_match() {\n    let var = \"BAR\";\n\n    match var.to_ascii_lowercase().as_str() {\n        \"foo\" => {},\n        \"bar\" => {},\n        _ => {},\n    }\n}\n\nfn non_alphabetic() {\n    let var = \"~!@#$%^&*()-_=+FOO\";\n\n    match var.to_ascii_lowercase().as_str() {\n        \"1234567890\" => {},\n        \"~!@#$%^&*()-_=+foo\" => {},\n        \"\\n\\r\\t\\x7F\" => {},\n        _ => {},\n    }\n}\n\nfn unicode_cased() {\n    let var = \"ВОДЫ\";\n\n    match var.to_lowercase().as_str() {\n        \"水\" => {},\n        \"νερό\" => {},\n        \"воды\" => {},\n        \"물\" => {},\n        _ => {},\n    }\n}\n\nfn titlecase() {\n    let var = \"Barǲ\";\n\n    match var.to_lowercase().as_str() {\n        \"fooǉ\" => {},\n        \"barǳ\" => {},\n        _ => {},\n    }\n}\n\nfn no_case_equivalent() {\n    let var = \"barʁ\";\n\n    match var.to_uppercase().as_str() {\n        \"FOOɕ\" => {},\n        \"BARʁ\" => {},\n        _ => {},\n    }\n}\n\nfn addrof_unary_match() {\n    let var = \"BAR\";\n\n    match &*var.to_ascii_lowercase() {\n        \"foo\" => {},\n        \"bar\" => {},\n        _ => {},\n    }\n}\n\nfn alternating_chain() {\n    let var = \"BAR\";\n\n    match &*var\n        .to_ascii_lowercase()\n        .to_uppercase()\n        .to_lowercase()\n        .to_ascii_uppercase()\n    {\n        \"FOO\" => {},\n        \"BAR\" => {},\n        _ => {},\n    }\n}\n\nfn unrelated_method() {\n    struct Item {\n        a: String,\n    }\n\n    impl Item {\n        #[allow(clippy::wrong_self_convention)]\n        fn to_lowercase(self) -> String {\n            self.a\n        }\n    }\n\n    let item = Item { a: String::from(\"BAR\") };\n\n    match &*item.to_lowercase() {\n        \"FOO\" => {},\n        \"BAR\" => {},\n        _ => {},\n    }\n}\n\n// Invalid\n\nfn as_str_match_mismatch() {\n    let var = \"BAR\";\n\n    match var.to_ascii_lowercase().as_str() {\n        \"foo\" => {},\n        \"bar\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn non_alphabetic_mismatch() {\n    let var = \"~!@#$%^&*()-_=+FOO\";\n\n    match var.to_ascii_lowercase().as_str() {\n        \"1234567890\" => {},\n        \"~!@#$%^&*()-_=+foo\" => {},\n        //~^ match_str_case_mismatch\n        \"\\n\\r\\t\\x7F\" => {},\n        _ => {},\n    }\n}\n\nfn unicode_cased_mismatch() {\n    let var = \"ВОДЫ\";\n\n    match var.to_lowercase().as_str() {\n        \"水\" => {},\n        \"νερό\" => {},\n        \"воды\" => {},\n        //~^ match_str_case_mismatch\n        \"물\" => {},\n        _ => {},\n    }\n}\n\nfn titlecase_mismatch() {\n    let var = \"Barǲ\";\n\n    match var.to_lowercase().as_str() {\n        \"fooǉ\" => {},\n        \"barǳ\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn no_case_equivalent_mismatch() {\n    let var = \"barʁ\";\n\n    match var.to_uppercase().as_str() {\n        \"FOOɕ\" => {},\n        \"BARʁ\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn addrof_unary_match_mismatch() {\n    let var = \"BAR\";\n\n    match &*var.to_ascii_lowercase() {\n        \"foo\" => {},\n        \"bar\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn alternating_chain_mismatch() {\n    let var = \"BAR\";\n\n    match &*var\n        .to_ascii_lowercase()\n        .to_uppercase()\n        .to_lowercase()\n        .to_ascii_uppercase()\n    {\n        \"FOO\" => {},\n        \"BAR\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_str_case_mismatch.rs",
    "content": "#![warn(clippy::match_str_case_mismatch)]\n#![allow(dead_code)]\n\n// Valid\n\nfn as_str_match() {\n    let var = \"BAR\";\n\n    match var.to_ascii_lowercase().as_str() {\n        \"foo\" => {},\n        \"bar\" => {},\n        _ => {},\n    }\n}\n\nfn non_alphabetic() {\n    let var = \"~!@#$%^&*()-_=+FOO\";\n\n    match var.to_ascii_lowercase().as_str() {\n        \"1234567890\" => {},\n        \"~!@#$%^&*()-_=+foo\" => {},\n        \"\\n\\r\\t\\x7F\" => {},\n        _ => {},\n    }\n}\n\nfn unicode_cased() {\n    let var = \"ВОДЫ\";\n\n    match var.to_lowercase().as_str() {\n        \"水\" => {},\n        \"νερό\" => {},\n        \"воды\" => {},\n        \"물\" => {},\n        _ => {},\n    }\n}\n\nfn titlecase() {\n    let var = \"Barǲ\";\n\n    match var.to_lowercase().as_str() {\n        \"fooǉ\" => {},\n        \"barǳ\" => {},\n        _ => {},\n    }\n}\n\nfn no_case_equivalent() {\n    let var = \"barʁ\";\n\n    match var.to_uppercase().as_str() {\n        \"FOOɕ\" => {},\n        \"BARʁ\" => {},\n        _ => {},\n    }\n}\n\nfn addrof_unary_match() {\n    let var = \"BAR\";\n\n    match &*var.to_ascii_lowercase() {\n        \"foo\" => {},\n        \"bar\" => {},\n        _ => {},\n    }\n}\n\nfn alternating_chain() {\n    let var = \"BAR\";\n\n    match &*var\n        .to_ascii_lowercase()\n        .to_uppercase()\n        .to_lowercase()\n        .to_ascii_uppercase()\n    {\n        \"FOO\" => {},\n        \"BAR\" => {},\n        _ => {},\n    }\n}\n\nfn unrelated_method() {\n    struct Item {\n        a: String,\n    }\n\n    impl Item {\n        #[allow(clippy::wrong_self_convention)]\n        fn to_lowercase(self) -> String {\n            self.a\n        }\n    }\n\n    let item = Item { a: String::from(\"BAR\") };\n\n    match &*item.to_lowercase() {\n        \"FOO\" => {},\n        \"BAR\" => {},\n        _ => {},\n    }\n}\n\n// Invalid\n\nfn as_str_match_mismatch() {\n    let var = \"BAR\";\n\n    match var.to_ascii_lowercase().as_str() {\n        \"foo\" => {},\n        \"Bar\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn non_alphabetic_mismatch() {\n    let var = \"~!@#$%^&*()-_=+FOO\";\n\n    match var.to_ascii_lowercase().as_str() {\n        \"1234567890\" => {},\n        \"~!@#$%^&*()-_=+Foo\" => {},\n        //~^ match_str_case_mismatch\n        \"\\n\\r\\t\\x7F\" => {},\n        _ => {},\n    }\n}\n\nfn unicode_cased_mismatch() {\n    let var = \"ВОДЫ\";\n\n    match var.to_lowercase().as_str() {\n        \"水\" => {},\n        \"νερό\" => {},\n        \"Воды\" => {},\n        //~^ match_str_case_mismatch\n        \"물\" => {},\n        _ => {},\n    }\n}\n\nfn titlecase_mismatch() {\n    let var = \"Barǲ\";\n\n    match var.to_lowercase().as_str() {\n        \"fooǉ\" => {},\n        \"barǲ\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn no_case_equivalent_mismatch() {\n    let var = \"barʁ\";\n\n    match var.to_uppercase().as_str() {\n        \"FOOɕ\" => {},\n        \"bARʁ\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn addrof_unary_match_mismatch() {\n    let var = \"BAR\";\n\n    match &*var.to_ascii_lowercase() {\n        \"foo\" => {},\n        \"Bar\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn alternating_chain_mismatch() {\n    let var = \"BAR\";\n\n    match &*var\n        .to_ascii_lowercase()\n        .to_uppercase()\n        .to_lowercase()\n        .to_ascii_uppercase()\n    {\n        \"FOO\" => {},\n        \"bAR\" => {},\n        //~^ match_str_case_mismatch\n        _ => {},\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_str_case_mismatch.stderr",
    "content": "error: this `match` arm has a differing case than its expression\n  --> tests/ui/match_str_case_mismatch.rs:112:9\n   |\nLL |         \"Bar\" => {},\n   |         ^^^^^\n   |\n   = note: `-D clippy::match-str-case-mismatch` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_str_case_mismatch)]`\nhelp: consider changing the case of this arm to respect `to_ascii_lowercase`\n   |\nLL -         \"Bar\" => {},\nLL +         \"bar\" => {},\n   |\n\nerror: this `match` arm has a differing case than its expression\n  --> tests/ui/match_str_case_mismatch.rs:123:9\n   |\nLL |         \"~!@#$%^&*()-_=+Foo\" => {},\n   |         ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization)\n   |\nLL -         \"~!@#$%^&*()-_=+Foo\" => {},\nLL +         \"~!@#$%^&*()-_=+foo\" => {},\n   |\n\nerror: this `match` arm has a differing case than its expression\n  --> tests/ui/match_str_case_mismatch.rs:136:9\n   |\nLL |         \"Воды\" => {},\n   |         ^^^^^^\n   |\nhelp: consider changing the case of this arm to respect `to_lowercase`\n   |\nLL -         \"Воды\" => {},\nLL +         \"воды\" => {},\n   |\n\nerror: this `match` arm has a differing case than its expression\n  --> tests/ui/match_str_case_mismatch.rs:148:9\n   |\nLL |         \"barǲ\" => {},\n   |         ^^^^^^\n   |\nhelp: consider changing the case of this arm to respect `to_lowercase`\n   |\nLL -         \"barǲ\" => {},\nLL +         \"barǳ\" => {},\n   |\n\nerror: this `match` arm has a differing case than its expression\n  --> tests/ui/match_str_case_mismatch.rs:159:9\n   |\nLL |         \"bARʁ\" => {},\n   |         ^^^^^^\n   |\nhelp: consider changing the case of this arm to respect `to_uppercase`\n   |\nLL -         \"bARʁ\" => {},\nLL +         \"BARʁ\" => {},\n   |\n\nerror: this `match` arm has a differing case than its expression\n  --> tests/ui/match_str_case_mismatch.rs:170:9\n   |\nLL |         \"Bar\" => {},\n   |         ^^^^^\n   |\nhelp: consider changing the case of this arm to respect `to_ascii_lowercase`\n   |\nLL -         \"Bar\" => {},\nLL +         \"bar\" => {},\n   |\n\nerror: this `match` arm has a differing case than its expression\n  --> tests/ui/match_str_case_mismatch.rs:186:9\n   |\nLL |         \"bAR\" => {},\n   |         ^^^^^\n   |\nhelp: consider changing the case of this arm to respect `to_ascii_uppercase`\n   |\nLL -         \"bAR\" => {},\nLL +         \"BAR\" => {},\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_wild_err_arm.rs",
    "content": "#![allow(clippy::match_same_arms, dead_code)]\n#![warn(clippy::match_wild_err_arm)]\n\nfn issue_10635() {\n    enum Error {\n        A,\n        B,\n    }\n\n    // Don't trigger in const contexts. Const unwrap is not yet stable\n    const X: () = match Ok::<_, Error>(()) {\n        Ok(x) => x,\n        Err(_) => panic!(),\n    };\n}\n\nfn match_wild_err_arm() {\n    let x: Result<i32, &str> = Ok(3);\n\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => panic!(\"err\"),\n        //~^ match_wild_err_arm\n    }\n\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => panic!(),\n        //~^ match_wild_err_arm\n    }\n\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => {\n            //~^ match_wild_err_arm\n\n            panic!();\n        },\n    }\n\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_e) => panic!(),\n        //~^ match_wild_err_arm\n    }\n\n    // Allowed when used in `panic!`.\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_e) => panic!(\"{}\", _e),\n    }\n\n    // Allowed when not with `panic!` block.\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => println!(\"err\"),\n    }\n\n    // Allowed when used with `unreachable!`.\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => unreachable!(),\n    }\n\n    // Allowed when used with `unreachable!`.\n    match x {\n        Ok(3) => println!(\"ok\"),\n        Ok(_) => println!(\"ok\"),\n        Err(_) => {\n            unreachable!();\n        },\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/match_wild_err_arm.stderr",
    "content": "error: `Err(_)` matches all errors\n  --> tests/ui/match_wild_err_arm.rs:23:9\n   |\nLL |         Err(_) => panic!(\"err\"),\n   |         ^^^^^^\n   |\n   = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable\n   = note: `-D clippy::match-wild-err-arm` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_wild_err_arm)]`\n\nerror: `Err(_)` matches all errors\n  --> tests/ui/match_wild_err_arm.rs:30:9\n   |\nLL |         Err(_) => panic!(),\n   |         ^^^^^^\n   |\n   = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable\n\nerror: `Err(_)` matches all errors\n  --> tests/ui/match_wild_err_arm.rs:37:9\n   |\nLL |         Err(_) => {\n   |         ^^^^^^\n   |\n   = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable\n\nerror: `Err(_e)` matches all errors\n  --> tests/ui/match_wild_err_arm.rs:47:9\n   |\nLL |         Err(_e) => panic!(),\n   |         ^^^^^^^\n   |\n   = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/match_wildcard_for_single_variants.fixed",
    "content": "#![warn(clippy::match_wildcard_for_single_variants)]\n#![allow(dead_code)]\n\nenum Foo {\n    A,\n    B,\n    C,\n}\n\nenum Color {\n    Red,\n    Green,\n    Blue,\n    Rgb(u8, u8, u8),\n}\nimpl Color {\n    fn f(self) {\n        match self {\n            Self::Red => (),\n            Self::Green => (),\n            Self::Blue => (),\n            Self::Rgb(..) => (),\n            //~^ match_wildcard_for_single_variants\n        };\n    }\n}\n\nfn main() {\n    let f = Foo::A;\n    match f {\n        Foo::A => {},\n        Foo::B => {},\n        Foo::C => {},\n        //~^ match_wildcard_for_single_variants\n    }\n\n    let color = Color::Red;\n\n    // check exhaustive bindings\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Rgb(_r, _g, _b) => {},\n        Color::Blue => {},\n        //~^ match_wildcard_for_single_variants\n    }\n\n    // check exhaustive wild\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Rgb(..) => {},\n        Color::Blue => {},\n        //~^ match_wildcard_for_single_variants\n    }\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Rgb(_, _, _) => {},\n        Color::Blue => {},\n        //~^ match_wildcard_for_single_variants\n    }\n\n    // shouldn't lint as there is one missing variant\n    // and one that isn't exhaustively covered\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Rgb(255, _, _) => {},\n        _ => {},\n    }\n\n    // References shouldn't change anything\n    match &color {\n        &Color::Red => (),\n        Color::Green => (),\n        &Color::Rgb(..) => (),\n        Color::Blue => (),\n        //~^ match_wildcard_for_single_variants\n    }\n\n    use self::Color as C;\n\n    match color {\n        C::Red => (),\n        C::Green => (),\n        C::Rgb(..) => (),\n        C::Blue => (),\n        //~^ match_wildcard_for_single_variants\n    }\n\n    match color {\n        C::Red => (),\n        Color::Green => (),\n        Color::Rgb(..) => (),\n        Color::Blue => (),\n        //~^ match_wildcard_for_single_variants\n    }\n\n    match Some(0) {\n        Some(0) => 0,\n        Some(_) => 1,\n        _ => 2,\n    };\n\n    #[non_exhaustive]\n    enum Bar {\n        A,\n        B,\n        C,\n    }\n    match Bar::A {\n        Bar::A => (),\n        Bar::B => (),\n        _ => (),\n    };\n\n    //#6984\n    {\n        #![allow(clippy::manual_non_exhaustive)]\n        pub enum Enum {\n            A,\n            B,\n            C,\n            #[doc(hidden)]\n            __Private,\n        }\n        match Enum::A {\n            Enum::A => (),\n            Enum::B => (),\n            Enum::C => (),\n            Enum::__Private => (),\n            //~^ match_wildcard_for_single_variants\n        }\n        match Enum::A {\n            Enum::A => (),\n            Enum::B => (),\n            _ => (),\n        }\n    }\n}\n\nmod issue9993 {\n    enum Foo {\n        A(bool),\n        B,\n    }\n\n    fn test() {\n        let _ = match Foo::A(true) {\n            _ if false => 0,\n            Foo::A(true) => 1,\n            Foo::A(false) => 2,\n            Foo::B => 3,\n        };\n\n        let _ = match Foo::B {\n            _ if false => 0,\n            Foo::A(_) => 1,\n            Foo::B => 2,\n            //~^ match_wildcard_for_single_variants\n        };\n    }\n}\n"
  },
  {
    "path": "tests/ui/match_wildcard_for_single_variants.rs",
    "content": "#![warn(clippy::match_wildcard_for_single_variants)]\n#![allow(dead_code)]\n\nenum Foo {\n    A,\n    B,\n    C,\n}\n\nenum Color {\n    Red,\n    Green,\n    Blue,\n    Rgb(u8, u8, u8),\n}\nimpl Color {\n    fn f(self) {\n        match self {\n            Self::Red => (),\n            Self::Green => (),\n            Self::Blue => (),\n            _ => (),\n            //~^ match_wildcard_for_single_variants\n        };\n    }\n}\n\nfn main() {\n    let f = Foo::A;\n    match f {\n        Foo::A => {},\n        Foo::B => {},\n        _ => {},\n        //~^ match_wildcard_for_single_variants\n    }\n\n    let color = Color::Red;\n\n    // check exhaustive bindings\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Rgb(_r, _g, _b) => {},\n        _ => {},\n        //~^ match_wildcard_for_single_variants\n    }\n\n    // check exhaustive wild\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Rgb(..) => {},\n        _ => {},\n        //~^ match_wildcard_for_single_variants\n    }\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Rgb(_, _, _) => {},\n        _ => {},\n        //~^ match_wildcard_for_single_variants\n    }\n\n    // shouldn't lint as there is one missing variant\n    // and one that isn't exhaustively covered\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Rgb(255, _, _) => {},\n        _ => {},\n    }\n\n    // References shouldn't change anything\n    match &color {\n        &Color::Red => (),\n        Color::Green => (),\n        &Color::Rgb(..) => (),\n        &_ => (),\n        //~^ match_wildcard_for_single_variants\n    }\n\n    use self::Color as C;\n\n    match color {\n        C::Red => (),\n        C::Green => (),\n        C::Rgb(..) => (),\n        _ => (),\n        //~^ match_wildcard_for_single_variants\n    }\n\n    match color {\n        C::Red => (),\n        Color::Green => (),\n        Color::Rgb(..) => (),\n        _ => (),\n        //~^ match_wildcard_for_single_variants\n    }\n\n    match Some(0) {\n        Some(0) => 0,\n        Some(_) => 1,\n        _ => 2,\n    };\n\n    #[non_exhaustive]\n    enum Bar {\n        A,\n        B,\n        C,\n    }\n    match Bar::A {\n        Bar::A => (),\n        Bar::B => (),\n        _ => (),\n    };\n\n    //#6984\n    {\n        #![allow(clippy::manual_non_exhaustive)]\n        pub enum Enum {\n            A,\n            B,\n            C,\n            #[doc(hidden)]\n            __Private,\n        }\n        match Enum::A {\n            Enum::A => (),\n            Enum::B => (),\n            Enum::C => (),\n            _ => (),\n            //~^ match_wildcard_for_single_variants\n        }\n        match Enum::A {\n            Enum::A => (),\n            Enum::B => (),\n            _ => (),\n        }\n    }\n}\n\nmod issue9993 {\n    enum Foo {\n        A(bool),\n        B,\n    }\n\n    fn test() {\n        let _ = match Foo::A(true) {\n            _ if false => 0,\n            Foo::A(true) => 1,\n            Foo::A(false) => 2,\n            Foo::B => 3,\n        };\n\n        let _ = match Foo::B {\n            _ if false => 0,\n            Foo::A(_) => 1,\n            _ => 2,\n            //~^ match_wildcard_for_single_variants\n        };\n    }\n}\n"
  },
  {
    "path": "tests/ui/match_wildcard_for_single_variants.stderr",
    "content": "error: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:22:13\n   |\nLL |             _ => (),\n   |             ^ help: try: `Self::Rgb(..)`\n   |\n   = note: `-D clippy::match-wildcard-for-single-variants` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::match_wildcard_for_single_variants)]`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:33:9\n   |\nLL |         _ => {},\n   |         ^ help: try: `Foo::C`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:44:9\n   |\nLL |         _ => {},\n   |         ^ help: try: `Color::Blue`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:53:9\n   |\nLL |         _ => {},\n   |         ^ help: try: `Color::Blue`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:60:9\n   |\nLL |         _ => {},\n   |         ^ help: try: `Color::Blue`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:78:9\n   |\nLL |         &_ => (),\n   |         ^^ help: try: `Color::Blue`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:88:9\n   |\nLL |         _ => (),\n   |         ^ help: try: `C::Blue`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:96:9\n   |\nLL |         _ => (),\n   |         ^ help: try: `Color::Blue`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:132:13\n   |\nLL |             _ => (),\n   |             ^ help: try: `Enum::__Private`\n\nerror: wildcard matches only a single variant and will also match any future added variants\n  --> tests/ui/match_wildcard_for_single_variants.rs:160:13\n   |\nLL |             _ => 2,\n   |             ^ help: try: `Foo::B`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/mem_forget.rs",
    "content": "use std::rc::Rc;\nuse std::sync::Arc;\n\nuse std::mem as memstuff;\nuse std::mem::forget as forgetSomething;\n\n#[warn(clippy::mem_forget)]\n#[allow(forgetting_copy_types)]\nfn main() {\n    let five: i32 = 5;\n    forgetSomething(five);\n\n    let six: Arc<i32> = Arc::new(6);\n    memstuff::forget(six);\n    //~^ mem_forget\n\n    let seven: Rc<i32> = Rc::new(7);\n    std::mem::forget(seven);\n    //~^ mem_forget\n\n    let eight: Vec<i32> = vec![8];\n    forgetSomething(eight);\n    //~^ mem_forget\n\n    let string = String::new();\n    std::mem::forget(string);\n    //~^ mem_forget\n\n    std::mem::forget(7);\n}\n"
  },
  {
    "path": "tests/ui/mem_forget.stderr",
    "content": "error: usage of `mem::forget` on `Drop` type\n  --> tests/ui/mem_forget.rs:14:5\n   |\nLL |     memstuff::forget(six);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: argument has type `std::sync::Arc<i32>`\n   = note: `-D clippy::mem-forget` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mem_forget)]`\n\nerror: usage of `mem::forget` on `Drop` type\n  --> tests/ui/mem_forget.rs:18:5\n   |\nLL |     std::mem::forget(seven);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: argument has type `std::rc::Rc<i32>`\n\nerror: usage of `mem::forget` on `Drop` type\n  --> tests/ui/mem_forget.rs:22:5\n   |\nLL |     forgetSomething(eight);\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: argument has type `std::vec::Vec<i32>`\n\nerror: usage of `mem::forget` on type with `Drop` fields\n  --> tests/ui/mem_forget.rs:26:5\n   |\nLL |     std::mem::forget(string);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: argument has type `std::string::String`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/mem_replace.fixed",
    "content": "#![allow(unused, clippy::needless_lifetimes)]\n#![warn(\n    clippy::style,\n    clippy::mem_replace_option_with_none,\n    clippy::mem_replace_with_default\n)]\n\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};\nuse std::mem;\n\nfn replace_option_with_none() {\n    let mut an_option = Some(1);\n    let _ = an_option.take();\n    //~^ mem_replace_option_with_none\n    let an_option = &mut Some(1);\n    let _ = an_option.take();\n    //~^ mem_replace_option_with_none\n}\n\nfn replace_with_default() {\n    let mut s = String::from(\"foo\");\n    let _ = std::mem::take(&mut s);\n    //~^ mem_replace_with_default\n    let _ = std::mem::take(&mut s);\n    //~^ mem_replace_with_default\n\n    let s = &mut String::from(\"foo\");\n    let _ = std::mem::take(s);\n    //~^ mem_replace_with_default\n    let _ = std::mem::take(s);\n    //~^ mem_replace_with_default\n    let _ = std::mem::take(s);\n    //~^ mem_replace_with_default\n\n    let mut v = vec![123];\n    let _ = std::mem::take(&mut v);\n    //~^ mem_replace_with_default\n    let _ = std::mem::take(&mut v);\n    //~^ mem_replace_with_default\n    let _ = std::mem::take(&mut v);\n    //~^ mem_replace_with_default\n    let _ = std::mem::take(&mut v);\n    //~^ mem_replace_with_default\n\n    let mut hash_map: HashMap<i32, i32> = HashMap::new();\n    let _ = std::mem::take(&mut hash_map);\n    //~^ mem_replace_with_default\n\n    let mut btree_map: BTreeMap<i32, i32> = BTreeMap::new();\n    let _ = std::mem::take(&mut btree_map);\n    //~^ mem_replace_with_default\n\n    let mut vd: VecDeque<i32> = VecDeque::new();\n    let _ = std::mem::take(&mut vd);\n    //~^ mem_replace_with_default\n\n    let mut hash_set: HashSet<&str> = HashSet::new();\n    let _ = std::mem::take(&mut hash_set);\n    //~^ mem_replace_with_default\n\n    let mut btree_set: BTreeSet<&str> = BTreeSet::new();\n    let _ = std::mem::take(&mut btree_set);\n    //~^ mem_replace_with_default\n\n    let mut list: LinkedList<i32> = LinkedList::new();\n    let _ = std::mem::take(&mut list);\n    //~^ mem_replace_with_default\n\n    let mut binary_heap: BinaryHeap<i32> = BinaryHeap::new();\n    let _ = std::mem::take(&mut binary_heap);\n    //~^ mem_replace_with_default\n\n    let mut tuple = (vec![1, 2], BinaryHeap::<i32>::new());\n    let _ = std::mem::take(&mut tuple);\n    //~^ mem_replace_with_default\n\n    let mut refstr = \"hello\";\n    let _ = std::mem::take(&mut refstr);\n    //~^ mem_replace_with_default\n\n    let mut slice: &[i32] = &[1, 2, 3];\n    let _ = std::mem::take(&mut slice);\n    //~^ mem_replace_with_default\n}\n\n// lint is disabled for primitives because in this case `take`\n// has no clear benefit over `replace` and sometimes is harder to read\nfn dont_lint_primitive() {\n    let mut pbool = true;\n    let _ = std::mem::replace(&mut pbool, false);\n\n    let mut pint = 5;\n    let _ = std::mem::replace(&mut pint, 0);\n}\n\n// lint is disabled for expressions that are not used because changing to `take` is not the\n// recommended fix. Additionally, the `replace` is #[must_use], so that lint will provide\n// the correct suggestion\nfn dont_lint_not_used() {\n    let mut s = String::from(\"foo\");\n    std::mem::replace(&mut s, String::default());\n}\n\nfn main() {}\n\n#[clippy::msrv = \"1.39\"]\nfn msrv_1_39() {\n    let mut s = String::from(\"foo\");\n    let _ = std::mem::replace(&mut s, String::default());\n}\n\n#[clippy::msrv = \"1.40\"]\nfn msrv_1_40() {\n    let mut s = String::from(\"foo\");\n    let _ = std::mem::take(&mut s);\n    //~^ mem_replace_with_default\n}\n\nfn issue9824() {\n    struct Foo<'a>(Option<&'a str>);\n    impl<'a> std::ops::Deref for Foo<'a> {\n        type Target = Option<&'a str>;\n\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<'a> std::ops::DerefMut for Foo<'a> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    struct Bar {\n        opt: Option<u8>,\n        val: String,\n    }\n\n    let mut f = Foo(Some(\"foo\"));\n    let mut b = Bar {\n        opt: Some(1),\n        val: String::from(\"bar\"),\n    };\n\n    // replace option with none\n    let _ = f.0.take();\n    //~^ mem_replace_option_with_none\n    let _ = (*f).take();\n    //~^ mem_replace_option_with_none\n    let _ = b.opt.take();\n    //~^ mem_replace_option_with_none\n    // replace with default\n    let _ = std::mem::take(&mut b.val);\n    //~^ mem_replace_with_default\n}\n\n#[clippy::msrv = \"1.31\"]\nfn mem_replace_option_with_some() {\n    let mut an_option = Some(0);\n    let replaced = an_option.replace(1);\n    //~^ ERROR: replacing an `Option` with `Some(..)`\n\n    let mut an_option = &mut Some(0);\n    let replaced = an_option.replace(1);\n    //~^ ERROR: replacing an `Option` with `Some(..)`\n\n    let (mut opt1, mut opt2) = (Some(0), Some(0));\n    let b = true;\n    let replaced = (if b { &mut opt1 } else { &mut opt2 }).replace(1);\n    //~^ ERROR: replacing an `Option` with `Some(..)`\n}\n\n#[clippy::msrv = \"1.30\"]\nfn mem_replace_option_with_some_bad_msrv() {\n    let mut an_option = Some(0);\n    let replaced = mem::replace(&mut an_option, Some(1));\n}\n\nfn issue15785() {\n    let mut text = String::from(\"foo\");\n    let replaced = std::mem::take(dbg!(&mut text));\n    //~^ mem_replace_with_default\n}\n"
  },
  {
    "path": "tests/ui/mem_replace.rs",
    "content": "#![allow(unused, clippy::needless_lifetimes)]\n#![warn(\n    clippy::style,\n    clippy::mem_replace_option_with_none,\n    clippy::mem_replace_with_default\n)]\n\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};\nuse std::mem;\n\nfn replace_option_with_none() {\n    let mut an_option = Some(1);\n    let _ = mem::replace(&mut an_option, None);\n    //~^ mem_replace_option_with_none\n    let an_option = &mut Some(1);\n    let _ = mem::replace(an_option, None);\n    //~^ mem_replace_option_with_none\n}\n\nfn replace_with_default() {\n    let mut s = String::from(\"foo\");\n    let _ = std::mem::replace(&mut s, String::default());\n    //~^ mem_replace_with_default\n    let _ = std::mem::replace(&mut s, String::new());\n    //~^ mem_replace_with_default\n\n    let s = &mut String::from(\"foo\");\n    let _ = std::mem::replace(s, String::default());\n    //~^ mem_replace_with_default\n    let _ = std::mem::replace(s, String::new());\n    //~^ mem_replace_with_default\n    let _ = std::mem::replace(s, Default::default());\n    //~^ mem_replace_with_default\n\n    let mut v = vec![123];\n    let _ = std::mem::replace(&mut v, Vec::default());\n    //~^ mem_replace_with_default\n    let _ = std::mem::replace(&mut v, Default::default());\n    //~^ mem_replace_with_default\n    let _ = std::mem::replace(&mut v, Vec::new());\n    //~^ mem_replace_with_default\n    let _ = std::mem::replace(&mut v, vec![]);\n    //~^ mem_replace_with_default\n\n    let mut hash_map: HashMap<i32, i32> = HashMap::new();\n    let _ = std::mem::replace(&mut hash_map, HashMap::new());\n    //~^ mem_replace_with_default\n\n    let mut btree_map: BTreeMap<i32, i32> = BTreeMap::new();\n    let _ = std::mem::replace(&mut btree_map, BTreeMap::new());\n    //~^ mem_replace_with_default\n\n    let mut vd: VecDeque<i32> = VecDeque::new();\n    let _ = std::mem::replace(&mut vd, VecDeque::new());\n    //~^ mem_replace_with_default\n\n    let mut hash_set: HashSet<&str> = HashSet::new();\n    let _ = std::mem::replace(&mut hash_set, HashSet::new());\n    //~^ mem_replace_with_default\n\n    let mut btree_set: BTreeSet<&str> = BTreeSet::new();\n    let _ = std::mem::replace(&mut btree_set, BTreeSet::new());\n    //~^ mem_replace_with_default\n\n    let mut list: LinkedList<i32> = LinkedList::new();\n    let _ = std::mem::replace(&mut list, LinkedList::new());\n    //~^ mem_replace_with_default\n\n    let mut binary_heap: BinaryHeap<i32> = BinaryHeap::new();\n    let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new());\n    //~^ mem_replace_with_default\n\n    let mut tuple = (vec![1, 2], BinaryHeap::<i32>::new());\n    let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new()));\n    //~^ mem_replace_with_default\n\n    let mut refstr = \"hello\";\n    let _ = std::mem::replace(&mut refstr, \"\");\n    //~^ mem_replace_with_default\n\n    let mut slice: &[i32] = &[1, 2, 3];\n    let _ = std::mem::replace(&mut slice, &[]);\n    //~^ mem_replace_with_default\n}\n\n// lint is disabled for primitives because in this case `take`\n// has no clear benefit over `replace` and sometimes is harder to read\nfn dont_lint_primitive() {\n    let mut pbool = true;\n    let _ = std::mem::replace(&mut pbool, false);\n\n    let mut pint = 5;\n    let _ = std::mem::replace(&mut pint, 0);\n}\n\n// lint is disabled for expressions that are not used because changing to `take` is not the\n// recommended fix. Additionally, the `replace` is #[must_use], so that lint will provide\n// the correct suggestion\nfn dont_lint_not_used() {\n    let mut s = String::from(\"foo\");\n    std::mem::replace(&mut s, String::default());\n}\n\nfn main() {}\n\n#[clippy::msrv = \"1.39\"]\nfn msrv_1_39() {\n    let mut s = String::from(\"foo\");\n    let _ = std::mem::replace(&mut s, String::default());\n}\n\n#[clippy::msrv = \"1.40\"]\nfn msrv_1_40() {\n    let mut s = String::from(\"foo\");\n    let _ = std::mem::replace(&mut s, String::default());\n    //~^ mem_replace_with_default\n}\n\nfn issue9824() {\n    struct Foo<'a>(Option<&'a str>);\n    impl<'a> std::ops::Deref for Foo<'a> {\n        type Target = Option<&'a str>;\n\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<'a> std::ops::DerefMut for Foo<'a> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    struct Bar {\n        opt: Option<u8>,\n        val: String,\n    }\n\n    let mut f = Foo(Some(\"foo\"));\n    let mut b = Bar {\n        opt: Some(1),\n        val: String::from(\"bar\"),\n    };\n\n    // replace option with none\n    let _ = std::mem::replace(&mut f.0, None);\n    //~^ mem_replace_option_with_none\n    let _ = std::mem::replace(&mut *f, None);\n    //~^ mem_replace_option_with_none\n    let _ = std::mem::replace(&mut b.opt, None);\n    //~^ mem_replace_option_with_none\n    // replace with default\n    let _ = std::mem::replace(&mut b.val, String::default());\n    //~^ mem_replace_with_default\n}\n\n#[clippy::msrv = \"1.31\"]\nfn mem_replace_option_with_some() {\n    let mut an_option = Some(0);\n    let replaced = mem::replace(&mut an_option, Some(1));\n    //~^ ERROR: replacing an `Option` with `Some(..)`\n\n    let mut an_option = &mut Some(0);\n    let replaced = mem::replace(an_option, Some(1));\n    //~^ ERROR: replacing an `Option` with `Some(..)`\n\n    let (mut opt1, mut opt2) = (Some(0), Some(0));\n    let b = true;\n    let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1));\n    //~^ ERROR: replacing an `Option` with `Some(..)`\n}\n\n#[clippy::msrv = \"1.30\"]\nfn mem_replace_option_with_some_bad_msrv() {\n    let mut an_option = Some(0);\n    let replaced = mem::replace(&mut an_option, Some(1));\n}\n\nfn issue15785() {\n    let mut text = String::from(\"foo\");\n    let replaced = std::mem::replace(dbg!(&mut text), String::default());\n    //~^ mem_replace_with_default\n}\n"
  },
  {
    "path": "tests/ui/mem_replace.stderr",
    "content": "error: replacing an `Option` with `None`\n  --> tests/ui/mem_replace.rs:13:13\n   |\nLL |     let _ = mem::replace(&mut an_option, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`\n   |\n   = note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`\n\nerror: replacing an `Option` with `None`\n  --> tests/ui/mem_replace.rs:16:13\n   |\nLL |     let _ = mem::replace(an_option, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:22:13\n   |\nLL |     let _ = std::mem::replace(&mut s, String::default());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`\n   |\n   = note: `-D clippy::mem-replace-with-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:24:13\n   |\nLL |     let _ = std::mem::replace(&mut s, String::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:28:13\n   |\nLL |     let _ = std::mem::replace(s, String::default());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:30:13\n   |\nLL |     let _ = std::mem::replace(s, String::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:32:13\n   |\nLL |     let _ = std::mem::replace(s, Default::default());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:36:13\n   |\nLL |     let _ = std::mem::replace(&mut v, Vec::default());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:38:13\n   |\nLL |     let _ = std::mem::replace(&mut v, Default::default());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:40:13\n   |\nLL |     let _ = std::mem::replace(&mut v, Vec::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:42:13\n   |\nLL |     let _ = std::mem::replace(&mut v, vec![]);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:46:13\n   |\nLL |     let _ = std::mem::replace(&mut hash_map, HashMap::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_map)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:50:13\n   |\nLL |     let _ = std::mem::replace(&mut btree_map, BTreeMap::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_map)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:54:13\n   |\nLL |     let _ = std::mem::replace(&mut vd, VecDeque::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut vd)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:58:13\n   |\nLL |     let _ = std::mem::replace(&mut hash_set, HashSet::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_set)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:62:13\n   |\nLL |     let _ = std::mem::replace(&mut btree_set, BTreeSet::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_set)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:66:13\n   |\nLL |     let _ = std::mem::replace(&mut list, LinkedList::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut list)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:70:13\n   |\nLL |     let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut binary_heap)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:74:13\n   |\nLL |     let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new()));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut tuple)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:78:13\n   |\nLL |     let _ = std::mem::replace(&mut refstr, \"\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut refstr)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:82:13\n   |\nLL |     let _ = std::mem::replace(&mut slice, &[]);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut slice)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:115:13\n   |\nLL |     let _ = std::mem::replace(&mut s, String::default());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`\n\nerror: replacing an `Option` with `None`\n  --> tests/ui/mem_replace.rs:146:13\n   |\nLL |     let _ = std::mem::replace(&mut f.0, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`\n\nerror: replacing an `Option` with `None`\n  --> tests/ui/mem_replace.rs:148:13\n   |\nLL |     let _ = std::mem::replace(&mut *f, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`\n\nerror: replacing an `Option` with `None`\n  --> tests/ui/mem_replace.rs:150:13\n   |\nLL |     let _ = std::mem::replace(&mut b.opt, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:153:13\n   |\nLL |     let _ = std::mem::replace(&mut b.val, String::default());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)`\n\nerror: replacing an `Option` with `Some(..)`\n  --> tests/ui/mem_replace.rs:160:20\n   |\nLL |     let replaced = mem::replace(&mut an_option, Some(1));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `an_option.replace(1)`\n   |\n   = note: `-D clippy::mem-replace-option-with-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_some)]`\n\nerror: replacing an `Option` with `Some(..)`\n  --> tests/ui/mem_replace.rs:164:20\n   |\nLL |     let replaced = mem::replace(an_option, Some(1));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `an_option.replace(1)`\n\nerror: replacing an `Option` with `Some(..)`\n  --> tests/ui/mem_replace.rs:169:20\n   |\nLL |     let replaced = mem::replace(if b { &mut opt1 } else { &mut opt2 }, Some(1));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::replace()` instead: `(if b { &mut opt1 } else { &mut opt2 }).replace(1)`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace.rs:181:20\n   |\nLL |     let replaced = std::mem::replace(dbg!(&mut text), String::default());\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(dbg!(&mut text))`\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/mem_replace_macro.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::mem_replace_with_default)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n#[inline_macros]\nfn main() {\n    let s = &mut String::from(\"foo\");\n    let _ = inline!(std::mem::replace($s, Default::default()));\n    //~^ mem_replace_with_default\n    let _ = external!(std::mem::replace($s, Default::default()));\n}\n"
  },
  {
    "path": "tests/ui/mem_replace_macro.stderr",
    "content": "error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`\n  --> tests/ui/mem_replace_macro.rs:10:21\n   |\nLL |     let _ = inline!(std::mem::replace($s, Default::default()));\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::mem-replace-with-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/mem_replace_no_std.fixed",
    "content": "#![allow(unused, clippy::needless_lifetimes)]\n#![warn(\n    clippy::style,\n    clippy::mem_replace_option_with_none,\n    clippy::mem_replace_with_default\n)]\n#![feature(lang_items)]\n#![no_std]\n\nuse core::mem;\nuse core::panic::PanicInfo;\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n\n#[panic_handler]\nfn panic(info: &PanicInfo) -> ! {\n    loop {}\n}\n\nfn replace_option_with_none() {\n    let mut an_option = Some(1);\n    let _ = an_option.take();\n    //~^ mem_replace_option_with_none\n    let an_option = &mut Some(1);\n    let _ = an_option.take();\n    //~^ mem_replace_option_with_none\n}\n\nfn replace_with_default() {\n    let mut refstr = \"hello\";\n    let _ = core::mem::take(&mut refstr);\n    //~^ mem_replace_with_default\n\n    let mut slice: &[i32] = &[1, 2, 3];\n    let _ = core::mem::take(&mut slice);\n    //~^ mem_replace_with_default\n}\n\n// lint is disabled for primitives because in this case `take`\n// has no clear benefit over `replace` and sometimes is harder to read\nfn dont_lint_primitive() {\n    let mut pbool = true;\n    let _ = mem::replace(&mut pbool, false);\n\n    let mut pint = 5;\n    let _ = mem::replace(&mut pint, 0);\n}\n\nfn main() {}\n\nfn issue9824() {\n    struct Foo<'a>(Option<&'a str>);\n    impl<'a> core::ops::Deref for Foo<'a> {\n        type Target = Option<&'a str>;\n\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<'a> core::ops::DerefMut for Foo<'a> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    struct Bar {\n        opt: Option<u8>,\n        val: u8,\n    }\n\n    let mut f = Foo(Some(\"foo\"));\n    let mut b = Bar { opt: Some(1), val: 12 };\n\n    // replace option with none\n    let _ = f.0.take();\n    //~^ mem_replace_option_with_none\n    let _ = (*f).take();\n    //~^ mem_replace_option_with_none\n    let _ = b.opt.take();\n    //~^ mem_replace_option_with_none\n    // replace with default\n    let _ = mem::replace(&mut b.val, u8::default());\n}\n"
  },
  {
    "path": "tests/ui/mem_replace_no_std.rs",
    "content": "#![allow(unused, clippy::needless_lifetimes)]\n#![warn(\n    clippy::style,\n    clippy::mem_replace_option_with_none,\n    clippy::mem_replace_with_default\n)]\n#![feature(lang_items)]\n#![no_std]\n\nuse core::mem;\nuse core::panic::PanicInfo;\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n\n#[panic_handler]\nfn panic(info: &PanicInfo) -> ! {\n    loop {}\n}\n\nfn replace_option_with_none() {\n    let mut an_option = Some(1);\n    let _ = mem::replace(&mut an_option, None);\n    //~^ mem_replace_option_with_none\n    let an_option = &mut Some(1);\n    let _ = mem::replace(an_option, None);\n    //~^ mem_replace_option_with_none\n}\n\nfn replace_with_default() {\n    let mut refstr = \"hello\";\n    let _ = mem::replace(&mut refstr, \"\");\n    //~^ mem_replace_with_default\n\n    let mut slice: &[i32] = &[1, 2, 3];\n    let _ = mem::replace(&mut slice, &[]);\n    //~^ mem_replace_with_default\n}\n\n// lint is disabled for primitives because in this case `take`\n// has no clear benefit over `replace` and sometimes is harder to read\nfn dont_lint_primitive() {\n    let mut pbool = true;\n    let _ = mem::replace(&mut pbool, false);\n\n    let mut pint = 5;\n    let _ = mem::replace(&mut pint, 0);\n}\n\nfn main() {}\n\nfn issue9824() {\n    struct Foo<'a>(Option<&'a str>);\n    impl<'a> core::ops::Deref for Foo<'a> {\n        type Target = Option<&'a str>;\n\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<'a> core::ops::DerefMut for Foo<'a> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    struct Bar {\n        opt: Option<u8>,\n        val: u8,\n    }\n\n    let mut f = Foo(Some(\"foo\"));\n    let mut b = Bar { opt: Some(1), val: 12 };\n\n    // replace option with none\n    let _ = mem::replace(&mut f.0, None);\n    //~^ mem_replace_option_with_none\n    let _ = mem::replace(&mut *f, None);\n    //~^ mem_replace_option_with_none\n    let _ = mem::replace(&mut b.opt, None);\n    //~^ mem_replace_option_with_none\n    // replace with default\n    let _ = mem::replace(&mut b.val, u8::default());\n}\n"
  },
  {
    "path": "tests/ui/mem_replace_no_std.stderr",
    "content": "error: replacing an `Option` with `None`\n  --> tests/ui/mem_replace_no_std.rs:23:13\n   |\nLL |     let _ = mem::replace(&mut an_option, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`\n   |\n   = note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`\n\nerror: replacing an `Option` with `None`\n  --> tests/ui/mem_replace_no_std.rs:26:13\n   |\nLL |     let _ = mem::replace(an_option, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`\n  --> tests/ui/mem_replace_no_std.rs:32:13\n   |\nLL |     let _ = mem::replace(&mut refstr, \"\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut refstr)`\n   |\n   = note: `-D clippy::mem-replace-with-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`\n\nerror: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`\n  --> tests/ui/mem_replace_no_std.rs:36:13\n   |\nLL |     let _ = mem::replace(&mut slice, &[]);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut slice)`\n\nerror: replacing an `Option` with `None`\n  --> tests/ui/mem_replace_no_std.rs:76:13\n   |\nLL |     let _ = mem::replace(&mut f.0, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`\n\nerror: replacing an `Option` with `None`\n  --> tests/ui/mem_replace_no_std.rs:78:13\n   |\nLL |     let _ = mem::replace(&mut *f, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`\n\nerror: replacing an `Option` with `None`\n  --> tests/ui/mem_replace_no_std.rs:80:13\n   |\nLL |     let _ = mem::replace(&mut b.opt, None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/methods.rs",
    "content": "//@aux-build:option_helpers.rs\n\n#![allow(\n    clippy::disallowed_names,\n    clippy::default_trait_access,\n    clippy::let_underscore_untyped,\n    clippy::missing_docs_in_private_items,\n    clippy::missing_safety_doc,\n    clippy::non_ascii_literal,\n    clippy::new_without_default,\n    clippy::needless_pass_by_value,\n    clippy::needless_lifetimes,\n    clippy::elidable_lifetime_names,\n    clippy::print_stdout,\n    clippy::must_use_candidate,\n    clippy::use_self,\n    clippy::useless_format,\n    clippy::wrong_self_convention,\n    clippy::unused_async,\n    clippy::unused_self,\n    clippy::useless_vec\n)]\n\n#[macro_use]\nextern crate option_helpers;\n\nuse std::collections::{BTreeMap, HashMap, HashSet, VecDeque};\nuse std::ops::Mul;\nuse std::rc::{self, Rc};\nuse std::sync::{self, Arc};\n\nuse option_helpers::{IteratorFalsePositives, IteratorMethodFalsePositives};\n\nstruct Lt<'a> {\n    foo: &'a u32,\n}\n\nimpl<'a> Lt<'a> {\n    // The lifetime is different, but that’s irrelevant; see issue #734.\n    #[allow(clippy::needless_lifetimes)]\n    pub fn new<'b>(s: &'b str) -> Lt<'b> {\n        unimplemented!()\n    }\n}\n\nstruct Lt2<'a> {\n    foo: &'a u32,\n}\n\nimpl<'a> Lt2<'a> {\n    // The lifetime is different, but that’s irrelevant; see issue #734.\n    pub fn new(s: &str) -> Lt2<'_> {\n        unimplemented!()\n    }\n}\n\nstruct Lt3<'a> {\n    foo: &'a u32,\n}\n\nimpl<'a> Lt3<'a> {\n    // The lifetime is different, but that’s irrelevant; see issue #734.\n    pub fn new() -> Lt3<'static> {\n        unimplemented!()\n    }\n}\n\n#[derive(Clone, Copy)]\nstruct U;\n\nimpl U {\n    fn new() -> Self {\n        U\n    }\n    // Ok because `U` is `Copy`.\n    fn to_something(self) -> u32 {\n        0\n    }\n}\n\nstruct V<T> {\n    _dummy: T,\n}\n\nimpl<T> V<T> {\n    fn new() -> Option<V<T>> {\n        None\n    }\n}\n\nstruct AsyncNew;\n\nimpl AsyncNew {\n    async fn new() -> Option<Self> {\n        None\n    }\n}\n\nstruct BadNew;\n\nimpl BadNew {\n    fn new() -> i32 {\n        //~^ new_ret_no_self\n        0\n    }\n}\n\nstruct T;\n\nimpl Mul<T> for T {\n    type Output = T;\n    // No error, obviously.\n    fn mul(self, other: T) -> T {\n        self\n    }\n}\n\n/// Checks implementation of `FILTER_NEXT` lint.\n#[rustfmt::skip]\nfn filter_next() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n\n    // Multi-line case.\n    let _ = v.iter().filter(|&x| {\n    //~^ filter_next\n                                *x < 0\n                            }\n                   ).next();\n\n    // Check that we don't lint if the caller is not an `Iterator`.\n    let foo = IteratorFalsePositives { foo: 0 };\n    let _ = foo.filter().next();\n\n    let foo = IteratorMethodFalsePositives {};\n    let _ = foo.filter(42).next();\n}\n\n#[rustfmt::skip]\nfn filter_next_back() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n\n    // Multi-line case.\n    let _ = v.iter().filter(|&x| {\n    //~^ filter_next\n                                *x < 0\n                            }\n                   ).next_back();\n\n    // Check that we don't lint if the caller is not an `Iterator`.\n    let foo = IteratorFalsePositives { foo: 0 };\n    let _ = foo.filter().next_back();\n\n    let foo = IteratorMethodFalsePositives {};\n    let _ = foo.filter(42).next_back();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/methods.stderr",
    "content": "error: methods called `new` usually return `Self`\n  --> tests/ui/methods.rs:102:5\n   |\nLL | /     fn new() -> i32 {\nLL | |\nLL | |         0\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::new-ret-no-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]`\n\nerror: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead\n  --> tests/ui/methods.rs:124:13\n   |\nLL |       let _ = v.iter().filter(|&x| {\n   |  _____________^\nLL | |\nLL | |                                 *x < 0\nLL | |                             }\nLL | |                    ).next();\n   | |___________________________^\n   |\n   = note: `-D clippy::filter-next` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filter_next)]`\n\nerror: called `filter(..).next_back()` on an `DoubleEndedIterator`. This is more succinctly expressed by calling `.rfind(..)` instead\n  --> tests/ui/methods.rs:143:13\n   |\nLL |       let _ = v.iter().filter(|&x| {\n   |  _____________^\nLL | |\nLL | |                                 *x < 0\nLL | |                             }\nLL | |                    ).next_back();\n   | |________________________________^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/methods_fixable.fixed",
    "content": "#![warn(clippy::filter_next)]\n#![allow(clippy::useless_vec)]\n\n/// Checks implementation of `FILTER_NEXT` lint.\nfn main() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n\n    // Single-line case.\n    let _ = v.iter().find(|&x| *x < 0);\n    //~^ filter_next\n\n    let _ = v.iter().rfind(|&x| *x < 0);\n    //~^ filter_next\n}\n\n#[clippy::msrv = \"1.27\"]\nfn msrv_1_27() {\n    let _ = vec![1].into_iter().rfind(|&x| x < 0);\n    //~^ filter_next\n}\n\n#[clippy::msrv = \"1.26\"]\nfn msrv_1_26() {\n    let _ = vec![1].into_iter().filter(|&x| x < 0).next_back();\n}\n"
  },
  {
    "path": "tests/ui/methods_fixable.rs",
    "content": "#![warn(clippy::filter_next)]\n#![allow(clippy::useless_vec)]\n\n/// Checks implementation of `FILTER_NEXT` lint.\nfn main() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n\n    // Single-line case.\n    let _ = v.iter().filter(|&x| *x < 0).next();\n    //~^ filter_next\n\n    let _ = v.iter().filter(|&x| *x < 0).next_back();\n    //~^ filter_next\n}\n\n#[clippy::msrv = \"1.27\"]\nfn msrv_1_27() {\n    let _ = vec![1].into_iter().filter(|&x| x < 0).next_back();\n    //~^ filter_next\n}\n\n#[clippy::msrv = \"1.26\"]\nfn msrv_1_26() {\n    let _ = vec![1].into_iter().filter(|&x| x < 0).next_back();\n}\n"
  },
  {
    "path": "tests/ui/methods_fixable.stderr",
    "content": "error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead\n  --> tests/ui/methods_fixable.rs:9:13\n   |\nLL |     let _ = v.iter().filter(|&x| *x < 0).next();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.iter().find(|&x| *x < 0)`\n   |\n   = note: `-D clippy::filter-next` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filter_next)]`\n\nerror: called `filter(..).next_back()` on an `DoubleEndedIterator`. This is more succinctly expressed by calling `.rfind(..)` instead\n  --> tests/ui/methods_fixable.rs:12:13\n   |\nLL |     let _ = v.iter().filter(|&x| *x < 0).next_back();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `v.iter().rfind(|&x| *x < 0)`\n\nerror: called `filter(..).next_back()` on an `DoubleEndedIterator`. This is more succinctly expressed by calling `.rfind(..)` instead\n  --> tests/ui/methods_fixable.rs:18:13\n   |\nLL |     let _ = vec![1].into_iter().filter(|&x| x < 0).next_back();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec![1].into_iter().rfind(|&x| x < 0)`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/methods_unfixable.rs",
    "content": "#![warn(clippy::filter_next)]\n//@no-rustfix\nfn main() {}\n\npub fn issue10029() {\n    let iter = (0..10);\n    let _ = iter.filter(|_| true).next();\n    //~^ filter_next\n}\n"
  },
  {
    "path": "tests/ui/methods_unfixable.stderr",
    "content": "error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead\n  --> tests/ui/methods_unfixable.rs:7:13\n   |\nLL |     let _ = iter.filter(|_| true).next();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `iter.find(|_| true)`\n   |\nhelp: you will also need to make `iter` mutable, because `find` takes `&mut self`\n  --> tests/ui/methods_unfixable.rs:6:9\n   |\nLL |     let iter = (0..10);\n   |         ^^^^\n   = note: `-D clippy::filter-next` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::filter_next)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/min_ident_chars.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(irrefutable_let_patterns, nonstandard_style, unused)]\n#![allow(clippy::struct_field_names)]\n#![warn(clippy::min_ident_chars)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nstruct A {\n    //~^ min_ident_chars\n    a: u32,\n    //~^ min_ident_chars\n    i: u32,\n    A: u32,\n    //~^ min_ident_chars\n    I: u32,\n    //~^ min_ident_chars\n}\n\nstruct B(u32);\n//~^ min_ident_chars\n\nstruct O {\n    //~^ min_ident_chars\n    o: u32,\n    //~^ min_ident_chars\n}\n\nstruct i;\n\nenum C {\n    //~^ min_ident_chars\n    D,\n    //~^ min_ident_chars\n    E,\n    //~^ min_ident_chars\n    F,\n    //~^ min_ident_chars\n    j,\n}\n\nstruct Vec4 {\n    x: u32,\n    y: u32,\n    z: u32,\n    w: u32,\n}\n\nstruct AA<T, E>(T, E);\n\ntrait Trait {\n    const A: u32 = 0;\n    //~^ min_ident_chars\n    type A;\n    //~^ min_ident_chars\n    fn a() {}\n    //~^ min_ident_chars\n}\n\nfn main() {\n    // Allowed idents\n    let w = 1;\n    // Ok, not this one\n    // let i = 1;\n    let j = 1;\n    let n = 1;\n    let z = 1;\n    let y = 1;\n    let z = 1;\n    // Implicitly disallowed idents\n    let h = 1;\n    //~^ min_ident_chars\n    let e = 2;\n    //~^ min_ident_chars\n    let l = 3;\n    //~^ min_ident_chars\n    let l = 4;\n    //~^ min_ident_chars\n    let o = 6;\n    //~^ min_ident_chars\n    // 2 len does not lint\n    let hi = 0;\n    // Lint\n    let (h, o, w) = (1, 2, 3);\n    //~^ min_ident_chars\n    //~| min_ident_chars\n    for (a, (r, e)) in (0..1000).enumerate().enumerate() {}\n    //~^ min_ident_chars\n    //~| min_ident_chars\n    //~| min_ident_chars\n    let you = Vec4 { x: 1, y: 2, z: 3, w: 4 };\n    while let (d, o, _i, n, g) = (true, true, false, false, true) {}\n    //~^ min_ident_chars\n    //~| min_ident_chars\n    //~| min_ident_chars\n    let today = true;\n    // Ideally this wouldn't lint, but this would (likely) require global analysis, outta scope\n    // of this lint regardless\n    let o = 1;\n    //~^ min_ident_chars\n    let o = O { o };\n    //~^ min_ident_chars\n\n    for j in 0..1000 {}\n    for _ in 0..10 {}\n\n    // Do not lint code from external macros\n    external! { for j in 0..1000 {} }\n    // Do not lint code from procedural macros\n    with_span! {\n        span\n        for j in 0..1000 {}\n    }\n}\n\nfn b() {}\n//~^ min_ident_chars\nfn wrong_pythagoras(a: f32, b: f32) -> f32 {\n    //~^ min_ident_chars\n    //~| min_ident_chars\n    a * a + a * b\n}\n\nmod issue_11163 {\n    struct Array<T, const N: usize>([T; N]);\n}\n\nstruct Issue13396;\n\nimpl core::fmt::Display for Issue13396 {\n    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        write!(f, \"Issue13396\")\n    }\n}\n\nimpl core::fmt::Debug for Issue13396 {\n    fn fmt(&self, g: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n        //~^ min_ident_chars\n        write!(g, \"Issue13396\")\n    }\n}\n\nfn issue13396() {\n    let a = |f: i8| f;\n    //~^ min_ident_chars\n    //~| min_ident_chars\n}\n\ntrait D {\n    //~^ min_ident_chars\n    fn f(g: i32);\n    //~^ min_ident_chars\n    //~| min_ident_chars\n    fn long(long: i32);\n\n    fn g(arg: i8) {\n        //~^ min_ident_chars\n        fn c(d: u8) {}\n        //~^ min_ident_chars\n        //~| min_ident_chars\n    }\n}\n\nimpl D for Issue13396 {\n    fn f(g: i32) {\n        fn h() {}\n        //~^ min_ident_chars\n        fn inner(a: i32) {}\n        //~^ min_ident_chars\n        let a = |f: String| f;\n        //~^ min_ident_chars\n        //~| min_ident_chars\n    }\n    fn long(long: i32) {}\n}\n"
  },
  {
    "path": "tests/ui/min_ident_chars.stderr",
    "content": "error: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:9:8\n   |\nLL | struct A {\n   |        ^\n   |\n   = note: `-D clippy::min-ident-chars` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::min_ident_chars)]`\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:11:5\n   |\nLL |     a: u32,\n   |     ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:14:5\n   |\nLL |     A: u32,\n   |     ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:16:5\n   |\nLL |     I: u32,\n   |     ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:20:8\n   |\nLL | struct B(u32);\n   |        ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:23:8\n   |\nLL | struct O {\n   |        ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:25:5\n   |\nLL |     o: u32,\n   |     ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:31:6\n   |\nLL | enum C {\n   |      ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:33:5\n   |\nLL |     D,\n   |     ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:35:5\n   |\nLL |     E,\n   |     ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:37:5\n   |\nLL |     F,\n   |     ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:52:11\n   |\nLL |     const A: u32 = 0;\n   |           ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:54:10\n   |\nLL |     type A;\n   |          ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:56:8\n   |\nLL |     fn a() {}\n   |        ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:71:9\n   |\nLL |     let h = 1;\n   |         ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:73:9\n   |\nLL |     let e = 2;\n   |         ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:75:9\n   |\nLL |     let l = 3;\n   |         ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:77:9\n   |\nLL |     let l = 4;\n   |         ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:79:9\n   |\nLL |     let o = 6;\n   |         ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:84:10\n   |\nLL |     let (h, o, w) = (1, 2, 3);\n   |          ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:84:13\n   |\nLL |     let (h, o, w) = (1, 2, 3);\n   |             ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:87:10\n   |\nLL |     for (a, (r, e)) in (0..1000).enumerate().enumerate() {}\n   |          ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:87:14\n   |\nLL |     for (a, (r, e)) in (0..1000).enumerate().enumerate() {}\n   |              ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:87:17\n   |\nLL |     for (a, (r, e)) in (0..1000).enumerate().enumerate() {}\n   |                 ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:92:16\n   |\nLL |     while let (d, o, _i, n, g) = (true, true, false, false, true) {}\n   |                ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:92:19\n   |\nLL |     while let (d, o, _i, n, g) = (true, true, false, false, true) {}\n   |                   ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:92:29\n   |\nLL |     while let (d, o, _i, n, g) = (true, true, false, false, true) {}\n   |                             ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:99:9\n   |\nLL |     let o = 1;\n   |         ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:101:9\n   |\nLL |     let o = O { o };\n   |         ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:116:4\n   |\nLL | fn b() {}\n   |    ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:118:21\n   |\nLL | fn wrong_pythagoras(a: f32, b: f32) -> f32 {\n   |                     ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:118:29\n   |\nLL | fn wrong_pythagoras(a: f32, b: f32) -> f32 {\n   |                             ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:137:19\n   |\nLL |     fn fmt(&self, g: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n   |                   ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:144:14\n   |\nLL |     let a = |f: i8| f;\n   |              ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:144:9\n   |\nLL |     let a = |f: i8| f;\n   |         ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:149:7\n   |\nLL | trait D {\n   |       ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:151:10\n   |\nLL |     fn f(g: i32);\n   |          ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:151:8\n   |\nLL |     fn f(g: i32);\n   |        ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:156:8\n   |\nLL |     fn g(arg: i8) {\n   |        ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:158:12\n   |\nLL |         fn c(d: u8) {}\n   |            ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:158:14\n   |\nLL |         fn c(d: u8) {}\n   |              ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:166:12\n   |\nLL |         fn h() {}\n   |            ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:168:18\n   |\nLL |         fn inner(a: i32) {}\n   |                  ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:170:18\n   |\nLL |         let a = |f: String| f;\n   |                  ^\n\nerror: this ident consists of a single char\n  --> tests/ui/min_ident_chars.rs:170:13\n   |\nLL |         let a = |f: String| f;\n   |             ^\n\nerror: aborting due to 45 previous errors\n\n"
  },
  {
    "path": "tests/ui/min_max.rs",
    "content": "#![allow(clippy::manual_clamp)]\n\nuse std::cmp::{max as my_max, max, min as my_min, min};\n\nconst LARGE: usize = 3;\n\nstruct NotOrd(u64);\n\nimpl NotOrd {\n    fn min(self, x: u64) -> NotOrd {\n        NotOrd(x)\n    }\n\n    fn max(self, x: u64) -> NotOrd {\n        NotOrd(x)\n    }\n}\n\nfn main() {\n    let x = 2usize;\n    min(1, max(3, x));\n    //~^ min_max\n\n    min(max(3, x), 1);\n    //~^ min_max\n\n    max(min(x, 1), 3);\n    //~^ min_max\n\n    max(3, min(x, 1));\n    //~^ min_max\n\n    my_max(3, my_min(x, 1));\n    //~^ min_max\n\n    min(3, max(1, x)); // ok, could be 1, 2 or 3 depending on x\n\n    min(1, max(LARGE, x)); // no error, we don't lookup consts here\n\n    let y = 2isize;\n    min(max(y, -1), 3);\n\n    let s = \"Hello\";\n    min(\"Apple\", max(\"Zoo\", s));\n    //~^ min_max\n\n    max(min(s, \"Apple\"), \"Zoo\");\n    //~^ min_max\n\n    max(\"Apple\", min(s, \"Zoo\")); // ok\n\n    let f = 3f32;\n    x.min(1).max(3);\n    //~^ min_max\n\n    x.max(3).min(1);\n    //~^ min_max\n\n    f.max(3f32).min(1f32);\n    //~^ min_max\n\n    x.max(1).min(3); // ok\n    x.min(3).max(1); // ok\n    f.min(3f32).max(1f32); // ok\n\n    max(x.min(1), 3);\n    //~^ min_max\n\n    min(x.max(1), 3); // ok\n\n    s.max(\"Zoo\").min(\"Apple\");\n    //~^ min_max\n\n    s.min(\"Apple\").max(\"Zoo\");\n    //~^ min_max\n\n    s.min(\"Zoo\").max(\"Apple\"); // ok\n\n    let not_ord = NotOrd(1);\n    not_ord.min(1).max(3); // ok\n}\n"
  },
  {
    "path": "tests/ui/min_max.stderr",
    "content": "error: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:21:5\n   |\nLL |     min(1, max(3, x));\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: `#[deny(clippy::min_max)]` on by default\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:24:5\n   |\nLL |     min(max(3, x), 1);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:27:5\n   |\nLL |     max(min(x, 1), 3);\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:30:5\n   |\nLL |     max(3, min(x, 1));\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:33:5\n   |\nLL |     my_max(3, my_min(x, 1));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:44:5\n   |\nLL |     min(\"Apple\", max(\"Zoo\", s));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:47:5\n   |\nLL |     max(min(s, \"Apple\"), \"Zoo\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:53:5\n   |\nLL |     x.min(1).max(3);\n   |     ^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:56:5\n   |\nLL |     x.max(3).min(1);\n   |     ^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:59:5\n   |\nLL |     f.max(3f32).min(1f32);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:66:5\n   |\nLL |     max(x.min(1), 3);\n   |     ^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:71:5\n   |\nLL |     s.max(\"Zoo\").min(\"Apple\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `min`/`max` combination leads to constant result\n  --> tests/ui/min_max.rs:74:5\n   |\nLL |     s.min(\"Apple\").max(\"Zoo\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/min_rust_version_attr.rs",
    "content": "#![allow(clippy::redundant_clone)]\n#![feature(custom_inner_attributes)]\n\nfn main() {}\n\n#[clippy::msrv = \"1.42.0\"]\nfn just_under_msrv() {\n    let log2_10 = 3.321928094887362;\n}\n\n#[clippy::msrv = \"1.43.0\"]\nfn meets_msrv() {\n    let log2_10 = 3.321928094887362;\n    //~^ approx_constant\n}\n\n#[clippy::msrv = \"1.44.0\"]\nfn just_above_msrv() {\n    let log2_10 = 3.321928094887362;\n    //~^ approx_constant\n}\n\n#[clippy::msrv = \"1.42\"]\nfn no_patch_under() {\n    let log2_10 = 3.321928094887362;\n}\n\n#[clippy::msrv = \"1.43\"]\nfn no_patch_meets() {\n    let log2_10 = 3.321928094887362;\n    //~^ approx_constant\n}\n\nfn inner_attr_under() {\n    #![clippy::msrv = \"1.42\"]\n    let log2_10 = 3.321928094887362;\n}\n\nfn inner_attr_meets() {\n    #![clippy::msrv = \"1.43\"]\n    let log2_10 = 3.321928094887362;\n    //~^ approx_constant\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/6920\nfn scoping() {\n    mod m {\n        #![clippy::msrv = \"1.42.0\"]\n    }\n\n    // Should warn\n    let log2_10 = 3.321928094887362;\n    //~^ approx_constant\n\n    mod a {\n        #![clippy::msrv = \"1.42.0\"]\n\n        fn should_warn() {\n            #![clippy::msrv = \"1.43.0\"]\n            let log2_10 = 3.321928094887362;\n            //~^ approx_constant\n        }\n\n        fn should_not_warn() {\n            let log2_10 = 3.321928094887362;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/min_rust_version_attr.stderr",
    "content": "error: approximate value of `f{32, 64}::consts::LOG2_10` found\n  --> tests/ui/min_rust_version_attr.rs:13:19\n   |\nLL |     let log2_10 = 3.321928094887362;\n   |                   ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n   = note: `#[deny(clippy::approx_constant)]` on by default\n\nerror: approximate value of `f{32, 64}::consts::LOG2_10` found\n  --> tests/ui/min_rust_version_attr.rs:19:19\n   |\nLL |     let log2_10 = 3.321928094887362;\n   |                   ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LOG2_10` found\n  --> tests/ui/min_rust_version_attr.rs:30:19\n   |\nLL |     let log2_10 = 3.321928094887362;\n   |                   ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LOG2_10` found\n  --> tests/ui/min_rust_version_attr.rs:41:19\n   |\nLL |     let log2_10 = 3.321928094887362;\n   |                   ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LOG2_10` found\n  --> tests/ui/min_rust_version_attr.rs:52:19\n   |\nLL |     let log2_10 = 3.321928094887362;\n   |                   ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: approximate value of `f{32, 64}::consts::LOG2_10` found\n  --> tests/ui/min_rust_version_attr.rs:60:27\n   |\nLL |             let log2_10 = 3.321928094887362;\n   |                           ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the constant directly\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/min_rust_version_invalid_attr.rs",
    "content": "//@compile-flags: -Zdeduplicate-diagnostics=yes\n\n#![feature(custom_inner_attributes)]\n#![clippy::msrv = \"invalid.version\"]\n//~^ ERROR: `invalid.version` is not a valid Rust version\n\nfn main() {}\n\n#[clippy::msrv = \"invalid.version\"]\n//~^ ERROR: `invalid.version` is not a valid Rust version\nfn outer_attr() {}\n\nmod multiple {\n    #![clippy::msrv = \"1.40\"]\n    #![clippy::msrv = \"=1.35.0\"]\n    #![clippy::msrv = \"1.10.1\"]\n    //~^ ERROR: `clippy::msrv` is defined multiple times\n\n    mod foo {\n        #![clippy::msrv = \"1.0\"]\n        #![clippy::msrv = \"1.0.0\"]\n        //~^ ERROR: `clippy::msrv` is defined multiple times\n    }\n}\n"
  },
  {
    "path": "tests/ui/min_rust_version_invalid_attr.stderr",
    "content": "error: `invalid.version` is not a valid Rust version\n  --> tests/ui/min_rust_version_invalid_attr.rs:4:1\n   |\nLL | #![clippy::msrv = \"invalid.version\"]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `invalid.version` is not a valid Rust version\n  --> tests/ui/min_rust_version_invalid_attr.rs:9:1\n   |\nLL | #[clippy::msrv = \"invalid.version\"]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `clippy::msrv` is defined multiple times\n  --> tests/ui/min_rust_version_invalid_attr.rs:16:5\n   |\nLL |     #![clippy::msrv = \"1.10.1\"]\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first definition found here\n  --> tests/ui/min_rust_version_invalid_attr.rs:14:5\n   |\nLL |     #![clippy::msrv = \"1.40\"]\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `clippy::msrv` is defined multiple times\n  --> tests/ui/min_rust_version_invalid_attr.rs:21:9\n   |\nLL |         #![clippy::msrv = \"1.0.0\"]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first definition found here\n  --> tests/ui/min_rust_version_invalid_attr.rs:20:9\n   |\nLL |         #![clippy::msrv = \"1.0\"]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/mismatching_type_param_order.rs",
    "content": "#![warn(clippy::mismatching_type_param_order)]\n#![allow(clippy::disallowed_names, clippy::needless_lifetimes)]\n\nfn main() {\n    struct Foo<A, B> {\n        x: A,\n        y: B,\n    }\n\n    // lint on both params\n    impl<B, A> Foo<B, A> {}\n    //~^ mismatching_type_param_order\n    //~| mismatching_type_param_order\n\n    // lint on the 2nd param\n    impl<C, A> Foo<C, A> {}\n    //~^ mismatching_type_param_order\n\n    // should not lint\n    impl<A, B> Foo<A, B> {}\n\n    struct FooLifetime<'l, 'm, A, B> {\n        x: &'l A,\n        y: &'m B,\n    }\n\n    // should not lint on lifetimes\n    impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {}\n    //~^ mismatching_type_param_order\n    //~| mismatching_type_param_order\n\n    struct Bar {\n        x: i32,\n    }\n\n    // should not lint\n    impl Bar {}\n\n    // also works for enums\n    enum FooEnum<A, B, C> {\n        X(A),\n        Y(B),\n        Z(C),\n    }\n\n    impl<C, A, B> FooEnum<C, A, B> {}\n    //~^ mismatching_type_param_order\n    //~| mismatching_type_param_order\n    //~| mismatching_type_param_order\n\n    // also works for unions\n    union FooUnion<A: Copy, B>\n    where\n        B: Copy,\n    {\n        x: A,\n        y: B,\n    }\n\n    impl<B: Copy, A> FooUnion<B, A> where A: Copy {}\n    //~^ mismatching_type_param_order\n    //~| mismatching_type_param_order\n\n    impl<A, B> FooUnion<A, B>\n    where\n        A: Copy,\n        B: Copy,\n    {\n    }\n\n    // if the types are complicated, do not lint\n    impl<K, V, B> Foo<(K, V), B> {}\n    impl<K, V, A> Foo<(K, V), A> {}\n}\n"
  },
  {
    "path": "tests/ui/mismatching_type_param_order.stderr",
    "content": "error: `Foo` has a similarly named generic type parameter `B` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:11:20\n   |\nLL |     impl<B, A> Foo<B, A> {}\n   |                    ^\n   |\n   = help: try `A`, or a name that does not conflict with `Foo`'s generic params\n   = note: `-D clippy::mismatching-type-param-order` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mismatching_type_param_order)]`\n\nerror: `Foo` has a similarly named generic type parameter `A` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:11:23\n   |\nLL |     impl<B, A> Foo<B, A> {}\n   |                       ^\n   |\n   = help: try `B`, or a name that does not conflict with `Foo`'s generic params\n\nerror: `Foo` has a similarly named generic type parameter `A` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:16:23\n   |\nLL |     impl<C, A> Foo<C, A> {}\n   |                       ^\n   |\n   = help: try `B`, or a name that does not conflict with `Foo`'s generic params\n\nerror: `FooLifetime` has a similarly named generic type parameter `B` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:28:44\n   |\nLL |     impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {}\n   |                                            ^\n   |\n   = help: try `A`, or a name that does not conflict with `FooLifetime`'s generic params\n\nerror: `FooLifetime` has a similarly named generic type parameter `A` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:28:47\n   |\nLL |     impl<'m, 'l, B, A> FooLifetime<'m, 'l, B, A> {}\n   |                                               ^\n   |\n   = help: try `B`, or a name that does not conflict with `FooLifetime`'s generic params\n\nerror: `FooEnum` has a similarly named generic type parameter `C` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:46:27\n   |\nLL |     impl<C, A, B> FooEnum<C, A, B> {}\n   |                           ^\n   |\n   = help: try `A`, or a name that does not conflict with `FooEnum`'s generic params\n\nerror: `FooEnum` has a similarly named generic type parameter `A` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:46:30\n   |\nLL |     impl<C, A, B> FooEnum<C, A, B> {}\n   |                              ^\n   |\n   = help: try `B`, or a name that does not conflict with `FooEnum`'s generic params\n\nerror: `FooEnum` has a similarly named generic type parameter `B` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:46:33\n   |\nLL |     impl<C, A, B> FooEnum<C, A, B> {}\n   |                                 ^\n   |\n   = help: try `C`, or a name that does not conflict with `FooEnum`'s generic params\n\nerror: `FooUnion` has a similarly named generic type parameter `B` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:60:31\n   |\nLL |     impl<B: Copy, A> FooUnion<B, A> where A: Copy {}\n   |                               ^\n   |\n   = help: try `A`, or a name that does not conflict with `FooUnion`'s generic params\n\nerror: `FooUnion` has a similarly named generic type parameter `A` in its declaration, but in a different order\n  --> tests/ui/mismatching_type_param_order.rs:60:34\n   |\nLL |     impl<B: Copy, A> FooUnion<B, A> where A: Copy {}\n   |                                  ^\n   |\n   = help: try `B`, or a name that does not conflict with `FooUnion`'s generic params\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/misnamed_getters.fixed",
    "content": "#![allow(unused)]\n#![allow(clippy::struct_field_names)]\n#![warn(clippy::misnamed_getters)]\n\nstruct A {\n    a: u8,\n    b: u8,\n    c: u8,\n}\n\nimpl A {\n    fn a(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.a\n    }\n    fn a_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.a\n    }\n\n    fn b(self) -> u8 {\n        //~^ misnamed_getters\n\n        self.b\n    }\n\n    fn b_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.b\n    }\n\n    fn c(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.c\n    }\n\n    fn c_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.c\n    }\n}\n\nunion B {\n    a: u8,\n    b: u8,\n}\n\nimpl B {\n    unsafe fn a(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        unsafe { &self.a }\n    }\n    unsafe fn a_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        unsafe { &mut self.a }\n    }\n\n    unsafe fn b(self) -> u8 {\n        //~^ misnamed_getters\n\n        unsafe { self.b }\n    }\n\n    unsafe fn b_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        unsafe { &mut self.b }\n    }\n\n    unsafe fn c(&self) -> &u8 {\n        unsafe { &self.b }\n    }\n\n    unsafe fn c_mut(&mut self) -> &mut u8 {\n        unsafe { &mut self.a }\n    }\n\n    unsafe fn a_unchecked(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        unsafe { &self.a }\n    }\n    unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        unsafe { &mut self.a }\n    }\n\n    unsafe fn b_unchecked(self) -> u8 {\n        //~^ misnamed_getters\n\n        unsafe { self.b }\n    }\n\n    unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        unsafe { &mut self.b }\n    }\n\n    unsafe fn c_unchecked(&self) -> &u8 {\n        unsafe { &self.b }\n    }\n\n    unsafe fn c_unchecked_mut(&mut self) -> &mut u8 {\n        unsafe { &mut self.a }\n    }\n}\n\nstruct D {\n    d: u8,\n    inner: A,\n}\n\nimpl core::ops::Deref for D {\n    type Target = A;\n    fn deref(&self) -> &A {\n        &self.inner\n    }\n}\n\nimpl core::ops::DerefMut for D {\n    fn deref_mut(&mut self) -> &mut A {\n        &mut self.inner\n    }\n}\n\nimpl D {\n    fn a(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.a\n    }\n    fn a_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.a\n    }\n\n    fn d(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.d\n    }\n    fn d_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.d\n    }\n}\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/misnamed_getters.rs",
    "content": "#![allow(unused)]\n#![allow(clippy::struct_field_names)]\n#![warn(clippy::misnamed_getters)]\n\nstruct A {\n    a: u8,\n    b: u8,\n    c: u8,\n}\n\nimpl A {\n    fn a(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.b\n    }\n    fn a_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.b\n    }\n\n    fn b(self) -> u8 {\n        //~^ misnamed_getters\n\n        self.a\n    }\n\n    fn b_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.a\n    }\n\n    fn c(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.b\n    }\n\n    fn c_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.a\n    }\n}\n\nunion B {\n    a: u8,\n    b: u8,\n}\n\nimpl B {\n    unsafe fn a(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        unsafe { &self.b }\n    }\n    unsafe fn a_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        unsafe { &mut self.b }\n    }\n\n    unsafe fn b(self) -> u8 {\n        //~^ misnamed_getters\n\n        unsafe { self.a }\n    }\n\n    unsafe fn b_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        unsafe { &mut self.a }\n    }\n\n    unsafe fn c(&self) -> &u8 {\n        unsafe { &self.b }\n    }\n\n    unsafe fn c_mut(&mut self) -> &mut u8 {\n        unsafe { &mut self.a }\n    }\n\n    unsafe fn a_unchecked(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        unsafe { &self.b }\n    }\n    unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        unsafe { &mut self.b }\n    }\n\n    unsafe fn b_unchecked(self) -> u8 {\n        //~^ misnamed_getters\n\n        unsafe { self.a }\n    }\n\n    unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        unsafe { &mut self.a }\n    }\n\n    unsafe fn c_unchecked(&self) -> &u8 {\n        unsafe { &self.b }\n    }\n\n    unsafe fn c_unchecked_mut(&mut self) -> &mut u8 {\n        unsafe { &mut self.a }\n    }\n}\n\nstruct D {\n    d: u8,\n    inner: A,\n}\n\nimpl core::ops::Deref for D {\n    type Target = A;\n    fn deref(&self) -> &A {\n        &self.inner\n    }\n}\n\nimpl core::ops::DerefMut for D {\n    fn deref_mut(&mut self) -> &mut A {\n        &mut self.inner\n    }\n}\n\nimpl D {\n    fn a(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.b\n    }\n    fn a_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.b\n    }\n\n    fn d(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.b\n    }\n    fn d_mut(&mut self) -> &mut u8 {\n        //~^ misnamed_getters\n\n        &mut self.b\n    }\n}\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/misnamed_getters.stderr",
    "content": "error: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:12:5\n   |\nLL | /     fn a(&self) -> &u8 {\nLL | |\nLL | |\nLL | |         &self.b\n   | |         ------- help: consider using: `&self.a`\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::misnamed-getters` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::misnamed_getters)]`\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:17:5\n   |\nLL | /     fn a_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         &mut self.b\n   | |         ----------- help: consider using: `&mut self.a`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:23:5\n   |\nLL | /     fn b(self) -> u8 {\nLL | |\nLL | |\nLL | |         self.a\n   | |         ------ help: consider using: `self.b`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:29:5\n   |\nLL | /     fn b_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         &mut self.a\n   | |         ----------- help: consider using: `&mut self.b`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:35:5\n   |\nLL | /     fn c(&self) -> &u8 {\nLL | |\nLL | |\nLL | |         &self.b\n   | |         ------- help: consider using: `&self.c`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:41:5\n   |\nLL | /     fn c_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         &mut self.a\n   | |         ----------- help: consider using: `&mut self.c`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:54:5\n   |\nLL | /     unsafe fn a(&self) -> &u8 {\nLL | |\nLL | |\nLL | |         unsafe { &self.b }\n   | |                  ------- help: consider using: `&self.a`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:59:5\n   |\nLL | /     unsafe fn a_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         unsafe { &mut self.b }\n   | |                  ----------- help: consider using: `&mut self.a`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:65:5\n   |\nLL | /     unsafe fn b(self) -> u8 {\nLL | |\nLL | |\nLL | |         unsafe { self.a }\n   | |                  ------ help: consider using: `self.b`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:71:5\n   |\nLL | /     unsafe fn b_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         unsafe { &mut self.a }\n   | |                  ----------- help: consider using: `&mut self.b`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:85:5\n   |\nLL | /     unsafe fn a_unchecked(&self) -> &u8 {\nLL | |\nLL | |\nLL | |         unsafe { &self.b }\n   | |                  ------- help: consider using: `&self.a`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:90:5\n   |\nLL | /     unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         unsafe { &mut self.b }\n   | |                  ----------- help: consider using: `&mut self.a`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:96:5\n   |\nLL | /     unsafe fn b_unchecked(self) -> u8 {\nLL | |\nLL | |\nLL | |         unsafe { self.a }\n   | |                  ------ help: consider using: `self.b`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:102:5\n   |\nLL | /     unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         unsafe { &mut self.a }\n   | |                  ----------- help: consider using: `&mut self.b`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:136:5\n   |\nLL | /     fn a(&self) -> &u8 {\nLL | |\nLL | |\nLL | |         &self.b\n   | |         ------- help: consider using: `&self.a`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:141:5\n   |\nLL | /     fn a_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         &mut self.b\n   | |         ----------- help: consider using: `&mut self.a`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:147:5\n   |\nLL | /     fn d(&self) -> &u8 {\nLL | |\nLL | |\nLL | |         &self.b\n   | |         ------- help: consider using: `&self.d`\nLL | |     }\n   | |_____^\n\nerror: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters.rs:152:5\n   |\nLL | /     fn d_mut(&mut self) -> &mut u8 {\nLL | |\nLL | |\nLL | |         &mut self.b\n   | |         ----------- help: consider using: `&mut self.d`\nLL | |     }\n   | |_____^\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/misnamed_getters_2021.fixed",
    "content": "//@edition: 2021\n#![allow(unused)]\n#![allow(clippy::struct_field_names)]\n#![warn(clippy::misnamed_getters)]\n\n// Edition 2021 specific check, where `unsafe` blocks are not required\n// inside `unsafe fn`.\n\nunion B {\n    a: u8,\n    b: u8,\n}\n\nimpl B {\n    unsafe fn a(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.a\n    }\n}\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/misnamed_getters_2021.rs",
    "content": "//@edition: 2021\n#![allow(unused)]\n#![allow(clippy::struct_field_names)]\n#![warn(clippy::misnamed_getters)]\n\n// Edition 2021 specific check, where `unsafe` blocks are not required\n// inside `unsafe fn`.\n\nunion B {\n    a: u8,\n    b: u8,\n}\n\nimpl B {\n    unsafe fn a(&self) -> &u8 {\n        //~^ misnamed_getters\n\n        &self.b\n    }\n}\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/misnamed_getters_2021.stderr",
    "content": "error: getter function appears to return the wrong field\n  --> tests/ui/misnamed_getters_2021.rs:15:5\n   |\nLL | /     unsafe fn a(&self) -> &u8 {\nLL | |\nLL | |\nLL | |         &self.b\n   | |         ------- help: consider using: `&self.a`\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::misnamed-getters` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::misnamed_getters)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/misrefactored_assign_op.1.fixed",
    "content": "#![allow(clippy::eq_op)]\n#![warn(clippy::misrefactored_assign_op, clippy::assign_op_pattern)]\n\nfn main() {\n    let mut a = 5;\n    a += 1;\n    //~^ misrefactored_assign_op\n\n    a += 1;\n    //~^ misrefactored_assign_op\n\n    a -= 1;\n    //~^ misrefactored_assign_op\n\n    a *= 99;\n    //~^ misrefactored_assign_op\n\n    a *= 42;\n    //~^ misrefactored_assign_op\n\n    a /= 2;\n    //~^ misrefactored_assign_op\n\n    a %= 5;\n    //~^ misrefactored_assign_op\n\n    a &= 1;\n    //~^ misrefactored_assign_op\n\n    a *= a;\n    //~^ misrefactored_assign_op\n\n    a = a * a * a;\n    a = a * 42 * a;\n    a = a * 2 + a;\n    a -= 1 - a;\n    a /= 5 / a;\n    a %= 42 % a;\n    a <<= 6 << a;\n}\n"
  },
  {
    "path": "tests/ui/misrefactored_assign_op.2.fixed",
    "content": "#![allow(clippy::eq_op)]\n#![warn(clippy::misrefactored_assign_op, clippy::assign_op_pattern)]\n\nfn main() {\n    let mut a = 5;\n    a = a + a + 1;\n    //~^ misrefactored_assign_op\n\n    a = a + 1 + a;\n    //~^ misrefactored_assign_op\n\n    a = a - (a - 1);\n    //~^ misrefactored_assign_op\n\n    a = a * a * 99;\n    //~^ misrefactored_assign_op\n\n    a = a * 42 * a;\n    //~^ misrefactored_assign_op\n\n    a = a / (a / 2);\n    //~^ misrefactored_assign_op\n\n    a = a % (a % 5);\n    //~^ misrefactored_assign_op\n\n    a = a & a & 1;\n    //~^ misrefactored_assign_op\n\n    a = a * a * a;\n    //~^ misrefactored_assign_op\n\n    a = a * a * a;\n    a = a * 42 * a;\n    a = a * 2 + a;\n    a -= 1 - a;\n    a /= 5 / a;\n    a %= 42 % a;\n    a <<= 6 << a;\n}\n"
  },
  {
    "path": "tests/ui/misrefactored_assign_op.rs",
    "content": "#![allow(clippy::eq_op)]\n#![warn(clippy::misrefactored_assign_op, clippy::assign_op_pattern)]\n\nfn main() {\n    let mut a = 5;\n    a += a + 1;\n    //~^ misrefactored_assign_op\n\n    a += 1 + a;\n    //~^ misrefactored_assign_op\n\n    a -= a - 1;\n    //~^ misrefactored_assign_op\n\n    a *= a * 99;\n    //~^ misrefactored_assign_op\n\n    a *= 42 * a;\n    //~^ misrefactored_assign_op\n\n    a /= a / 2;\n    //~^ misrefactored_assign_op\n\n    a %= a % 5;\n    //~^ misrefactored_assign_op\n\n    a &= a & 1;\n    //~^ misrefactored_assign_op\n\n    a *= a * a;\n    //~^ misrefactored_assign_op\n\n    a = a * a * a;\n    a = a * 42 * a;\n    a = a * 2 + a;\n    a -= 1 - a;\n    a /= 5 / a;\n    a %= 42 % a;\n    a <<= 6 << a;\n}\n"
  },
  {
    "path": "tests/ui/misrefactored_assign_op.stderr",
    "content": "error: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:6:5\n   |\nLL |     a += a + 1;\n   |     ^^^^^^^^^^\n   |\n   = note: `-D clippy::misrefactored-assign-op` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::misrefactored_assign_op)]`\nhelp: did you mean `a = a + 1` or `a = a + a + 1`? Consider replacing it with\n   |\nLL -     a += a + 1;\nLL +     a += 1;\n   |\nhelp: or\n   |\nLL -     a += a + 1;\nLL +     a = a + a + 1;\n   |\n\nerror: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:9:5\n   |\nLL |     a += 1 + a;\n   |     ^^^^^^^^^^\n   |\nhelp: did you mean `a = a + 1` or `a = a + 1 + a`? Consider replacing it with\n   |\nLL -     a += 1 + a;\nLL +     a += 1;\n   |\nhelp: or\n   |\nLL -     a += 1 + a;\nLL +     a = a + 1 + a;\n   |\n\nerror: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:12:5\n   |\nLL |     a -= a - 1;\n   |     ^^^^^^^^^^\n   |\nhelp: did you mean `a = a - 1` or `a = a - (a - 1)`? Consider replacing it with\n   |\nLL -     a -= a - 1;\nLL +     a -= 1;\n   |\nhelp: or\n   |\nLL -     a -= a - 1;\nLL +     a = a - (a - 1);\n   |\n\nerror: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:15:5\n   |\nLL |     a *= a * 99;\n   |     ^^^^^^^^^^^\n   |\nhelp: did you mean `a = a * 99` or `a = a * a * 99`? Consider replacing it with\n   |\nLL -     a *= a * 99;\nLL +     a *= 99;\n   |\nhelp: or\n   |\nLL -     a *= a * 99;\nLL +     a = a * a * 99;\n   |\n\nerror: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:18:5\n   |\nLL |     a *= 42 * a;\n   |     ^^^^^^^^^^^\n   |\nhelp: did you mean `a = a * 42` or `a = a * 42 * a`? Consider replacing it with\n   |\nLL -     a *= 42 * a;\nLL +     a *= 42;\n   |\nhelp: or\n   |\nLL -     a *= 42 * a;\nLL +     a = a * 42 * a;\n   |\n\nerror: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:21:5\n   |\nLL |     a /= a / 2;\n   |     ^^^^^^^^^^\n   |\nhelp: did you mean `a = a / 2` or `a = a / (a / 2)`? Consider replacing it with\n   |\nLL -     a /= a / 2;\nLL +     a /= 2;\n   |\nhelp: or\n   |\nLL -     a /= a / 2;\nLL +     a = a / (a / 2);\n   |\n\nerror: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:24:5\n   |\nLL |     a %= a % 5;\n   |     ^^^^^^^^^^\n   |\nhelp: did you mean `a = a % 5` or `a = a % (a % 5)`? Consider replacing it with\n   |\nLL -     a %= a % 5;\nLL +     a %= 5;\n   |\nhelp: or\n   |\nLL -     a %= a % 5;\nLL +     a = a % (a % 5);\n   |\n\nerror: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:27:5\n   |\nLL |     a &= a & 1;\n   |     ^^^^^^^^^^\n   |\nhelp: did you mean `a = a & 1` or `a = a & a & 1`? Consider replacing it with\n   |\nLL -     a &= a & 1;\nLL +     a &= 1;\n   |\nhelp: or\n   |\nLL -     a &= a & 1;\nLL +     a = a & a & 1;\n   |\n\nerror: variable appears on both sides of an assignment operation\n  --> tests/ui/misrefactored_assign_op.rs:30:5\n   |\nLL |     a *= a * a;\n   |     ^^^^^^^^^^\n   |\nhelp: did you mean `a = a * a` or `a = a * a * a`? Consider replacing it with\n   |\nLL -     a *= a * a;\nLL +     a *= a;\n   |\nhelp: or\n   |\nLL -     a *= a * a;\nLL +     a = a * a * a;\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_assert_message.edition2015.stderr",
    "content": "error: assert without any message\n  --> tests/ui/missing_assert_message.rs:15:5\n   |\nLL |     assert!(foo());\n   |     ^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n   = note: `-D clippy::missing-assert-message` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_assert_message)]`\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:17:5\n   |\nLL |     assert_eq!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:19:5\n   |\nLL |     assert_ne!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:21:5\n   |\nLL |     debug_assert!(foo());\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:23:5\n   |\nLL |     debug_assert_eq!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:25:5\n   |\nLL |     debug_assert_ne!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:31:5\n   |\nLL |     assert!(bar!(true));\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:33:5\n   |\nLL |     assert!(bar!(true, false));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:35:5\n   |\nLL |     assert_eq!(bar!(true), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:37:5\n   |\nLL |     assert_ne!(bar!(true, true), bar!(true));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:43:5\n   |\nLL |     assert!(foo(),);\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:45:5\n   |\nLL |     assert_eq!(foo(), foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:47:5\n   |\nLL |     assert_ne!(foo(), foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:49:5\n   |\nLL |     debug_assert!(foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:51:5\n   |\nLL |     debug_assert_eq!(foo(), foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:53:5\n   |\nLL |     debug_assert_ne!(foo(), foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_assert_message.edition2021.stderr",
    "content": "error: assert without any message\n  --> tests/ui/missing_assert_message.rs:15:5\n   |\nLL |     assert!(foo());\n   |     ^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n   = note: `-D clippy::missing-assert-message` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_assert_message)]`\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:17:5\n   |\nLL |     assert_eq!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:19:5\n   |\nLL |     assert_ne!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:21:5\n   |\nLL |     debug_assert!(foo());\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:23:5\n   |\nLL |     debug_assert_eq!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:25:5\n   |\nLL |     debug_assert_ne!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:31:5\n   |\nLL |     assert!(bar!(true));\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:33:5\n   |\nLL |     assert!(bar!(true, false));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:35:5\n   |\nLL |     assert_eq!(bar!(true), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:37:5\n   |\nLL |     assert_ne!(bar!(true, true), bar!(true));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:43:5\n   |\nLL |     assert!(foo(),);\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:45:5\n   |\nLL |     assert_eq!(foo(), foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:47:5\n   |\nLL |     assert_ne!(foo(), foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:49:5\n   |\nLL |     debug_assert!(foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:51:5\n   |\nLL |     debug_assert_eq!(foo(), foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: assert without any message\n  --> tests/ui/missing_assert_message.rs:53:5\n   |\nLL |     debug_assert_ne!(foo(), foo(),);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider describing why the failing assert is problematic\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_assert_message.rs",
    "content": "//@revisions: edition2015 edition2021\n//@[edition2015] edition:2015\n//@[edition2021] edition:2021\n\n#![warn(clippy::missing_assert_message)]\n\nmacro_rules! bar {\n    ($( $x:expr ),*) => {\n        foo()\n    };\n}\n\n// Should trigger warning\nfn asserts_without_message() {\n    assert!(foo());\n    //~^ ERROR: assert without any message\n    assert_eq!(foo(), foo());\n    //~^ ERROR: assert without any message\n    assert_ne!(foo(), foo());\n    //~^ ERROR: assert without any message\n    debug_assert!(foo());\n    //~^ ERROR: assert without any message\n    debug_assert_eq!(foo(), foo());\n    //~^ ERROR: assert without any message\n    debug_assert_ne!(foo(), foo());\n    //~^ ERROR: assert without any message\n}\n\n// Should trigger warning\nfn asserts_without_message_but_with_macro_calls() {\n    assert!(bar!(true));\n    //~^ ERROR: assert without any message\n    assert!(bar!(true, false));\n    //~^ ERROR: assert without any message\n    assert_eq!(bar!(true), foo());\n    //~^ ERROR: assert without any message\n    assert_ne!(bar!(true, true), bar!(true));\n    //~^ ERROR: assert without any message\n}\n\n// Should trigger warning\nfn asserts_with_trailing_commas() {\n    assert!(foo(),);\n    //~^ ERROR: assert without any message\n    assert_eq!(foo(), foo(),);\n    //~^ ERROR: assert without any message\n    assert_ne!(foo(), foo(),);\n    //~^ ERROR: assert without any message\n    debug_assert!(foo(),);\n    //~^ ERROR: assert without any message\n    debug_assert_eq!(foo(), foo(),);\n    //~^ ERROR: assert without any message\n    debug_assert_ne!(foo(), foo(),);\n    //~^ ERROR: assert without any message\n}\n\n// Should not trigger warning\nfn asserts_with_message_and_with_macro_calls() {\n    assert!(bar!(true), \"msg\");\n    assert!(bar!(true, false), \"msg\");\n    assert_eq!(bar!(true), foo(), \"msg\");\n    assert_ne!(bar!(true, true), bar!(true), \"msg\");\n}\n\n// Should not trigger warning\nfn asserts_with_message() {\n    assert!(foo(), \"msg\");\n    assert_eq!(foo(), foo(), \"msg\");\n    assert_ne!(foo(), foo(), \"msg\");\n    debug_assert!(foo(), \"msg\");\n    debug_assert_eq!(foo(), foo(), \"msg\");\n    debug_assert_ne!(foo(), foo(), \"msg\");\n}\n\n// Should not trigger warning\n#[test]\nfn asserts_without_message_but_inside_a_test_function() {\n    assert!(foo());\n    assert_eq!(foo(), foo());\n    assert_ne!(foo(), foo());\n    debug_assert!(foo());\n    debug_assert_eq!(foo(), foo());\n    debug_assert_ne!(foo(), foo());\n}\n\nfn foo() -> bool {\n    true\n}\n\n// Should not trigger warning\n#[cfg(test)]\nmod tests {\n    use super::foo;\n    fn asserts_without_message_but_inside_a_test_module() {\n        assert!(foo());\n        assert_eq!(foo(), foo());\n        assert_ne!(foo(), foo());\n        debug_assert!(foo());\n        debug_assert_eq!(foo(), foo());\n        debug_assert_ne!(foo(), foo());\n    }\n}\n"
  },
  {
    "path": "tests/ui/missing_asserts_for_indexing.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::missing_asserts_for_indexing)]\n\n// ok\nfn sum_with_assert(v: &[u8]) -> u8 {\n    assert!(v.len() > 4);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n}\n\n// ok\nfn sum_with_assert_other_way(v: &[u8]) -> u8 {\n    assert!(5 <= v.len());\n    v[0] + v[1] + v[2] + v[3] + v[4]\n}\n\n// ok\nfn sum_with_assert_ge(v: &[u8]) -> u8 {\n    assert!(v.len() >= 5);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n}\n\n// ok\nfn sum_with_assert_ge_other_way(v: &[u8]) -> u8 {\n    assert!(4 < v.len());\n    v[0] + v[1] + v[2] + v[3] + v[4]\n}\n\nfn sum_with_assert_lt(v: &[u8]) -> u8 {\n    assert!(v.len() > 4);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\nfn sum_with_assert_le(v: &[u8]) -> u8 {\n    assert!(v.len() > 4);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\nfn sum_with_incorrect_assert_len(v: &[u8]) -> u8 {\n    assert!(v.len() > 4);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\nfn sum_with_incorrect_assert_len2(v: &[u8]) -> u8 {\n    assert!(v.len() > 4);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\n// ok, don't lint for single array access\nfn single_access(v: &[u8]) -> u8 {\n    v[0]\n}\n\n// ok\nfn subslice_ok(v: &[u8]) {\n    assert!(v.len() > 3);\n    let _ = v[0];\n    let _ = v[1..4];\n}\n\nfn subslice_bad(v: &[u8]) {\n    assert!(v.len() > 3);\n    let _ = v[0];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v[1..4];\n}\n\n// ok\nfn subslice_inclusive_ok(v: &[u8]) {\n    assert!(v.len() > 4);\n    let _ = v[0];\n    let _ = v[1..=4];\n}\n\nfn subslice_inclusive_bad(v: &[u8]) {\n    assert!(v.len() > 4);\n    let _ = v[0];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v[1..=4];\n}\n\nfn index_different_slices_ok(v1: &[u8], v2: &[u8]) {\n    assert!(v1.len() > 12);\n    assert!(v2.len() > 15);\n    let _ = v1[0] + v1[12];\n    let _ = v2[5] + v2[15];\n}\n\nfn index_different_slices_wrong_len(v1: &[u8], v2: &[u8]) {\n    assert!(v1.len() > 12);\n    assert!(v2.len() > 15);\n    let _ = v1[0] + v1[12];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v2[5] + v2[15];\n    //~^ missing_asserts_for_indexing\n}\nfn index_different_slices_one_wrong_len(v1: &[u8], v2: &[u8]) {\n    assert!(v1.len() > 12);\n    assert!(v2.len() > 15);\n    let _ = v1[0] + v1[12];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v2[5] + v2[15];\n}\n\nfn side_effect() -> &'static [u8] {\n    &[]\n}\n\nfn index_side_effect_expr() {\n    let _ = side_effect()[0] + side_effect()[1];\n}\n\n// ok, single access for different slices\nfn index_different_slice_in_same_expr(v1: &[u8], v2: &[u8]) {\n    let _ = v1[0] + v2[1];\n}\n\nfn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {\n    assert!(v1.len() == 3);\n    assert!(v2.len() == 4);\n    assert!(v3.len() == 3);\n    assert!(4 == v4.len());\n\n    let _ = v1[0] + v1[1] + v1[2];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v2[0] + v2[1] + v2[2];\n\n    let _ = v3[0] + v3[1] + v3[2];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v4[0] + v4[1] + v4[2];\n}\n\n// ok\nfn same_index_multiple_times(v1: &[u8]) {\n    let _ = v1[0] + v1[0];\n}\n\n// ok\nfn highest_index_first(v1: &[u8]) {\n    let _ = v1[2] + v1[1] + v1[0];\n}\n\nfn issue14255(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {\n    assert_eq!(v1.len(), 3);\n    assert_eq!(v2.len(), 4);\n    assert_eq!(v3.len(), 3);\n    assert_eq!(4, v4.len());\n\n    let _ = v1[0] + v1[1] + v1[2];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v2[0] + v2[1] + v2[2];\n\n    let _ = v3[0] + v3[1] + v3[2];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v4[0] + v4[1] + v4[2];\n}\n\nmod issue15988 {\n    fn assert_eq_len(v: &[i32]) {\n        assert_eq!(v.len(), 3);\n        let _ = v[0] + v[1] + v[2];\n        //~^ missing_asserts_for_indexing\n    }\n\n    fn debug_assert_eq_len(v: &[i32]) {\n        debug_assert_eq!(v.len(), 3);\n        let _ = v[0] + v[1] + v[2];\n        //~^ missing_asserts_for_indexing\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/missing_asserts_for_indexing.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::missing_asserts_for_indexing)]\n\n// ok\nfn sum_with_assert(v: &[u8]) -> u8 {\n    assert!(v.len() > 4);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n}\n\n// ok\nfn sum_with_assert_other_way(v: &[u8]) -> u8 {\n    assert!(5 <= v.len());\n    v[0] + v[1] + v[2] + v[3] + v[4]\n}\n\n// ok\nfn sum_with_assert_ge(v: &[u8]) -> u8 {\n    assert!(v.len() >= 5);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n}\n\n// ok\nfn sum_with_assert_ge_other_way(v: &[u8]) -> u8 {\n    assert!(4 < v.len());\n    v[0] + v[1] + v[2] + v[3] + v[4]\n}\n\nfn sum_with_assert_lt(v: &[u8]) -> u8 {\n    assert!(v.len() < 5);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\nfn sum_with_assert_le(v: &[u8]) -> u8 {\n    assert!(v.len() <= 5);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\nfn sum_with_incorrect_assert_len(v: &[u8]) -> u8 {\n    assert!(v.len() > 3);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\nfn sum_with_incorrect_assert_len2(v: &[u8]) -> u8 {\n    assert!(v.len() >= 4);\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\n// ok, don't lint for single array access\nfn single_access(v: &[u8]) -> u8 {\n    v[0]\n}\n\n// ok\nfn subslice_ok(v: &[u8]) {\n    assert!(v.len() > 3);\n    let _ = v[0];\n    let _ = v[1..4];\n}\n\nfn subslice_bad(v: &[u8]) {\n    assert!(v.len() >= 3);\n    let _ = v[0];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v[1..4];\n}\n\n// ok\nfn subslice_inclusive_ok(v: &[u8]) {\n    assert!(v.len() > 4);\n    let _ = v[0];\n    let _ = v[1..=4];\n}\n\nfn subslice_inclusive_bad(v: &[u8]) {\n    assert!(v.len() >= 4);\n    let _ = v[0];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v[1..=4];\n}\n\nfn index_different_slices_ok(v1: &[u8], v2: &[u8]) {\n    assert!(v1.len() > 12);\n    assert!(v2.len() > 15);\n    let _ = v1[0] + v1[12];\n    let _ = v2[5] + v2[15];\n}\n\nfn index_different_slices_wrong_len(v1: &[u8], v2: &[u8]) {\n    assert!(v1.len() >= 12);\n    assert!(v2.len() >= 15);\n    let _ = v1[0] + v1[12];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v2[5] + v2[15];\n    //~^ missing_asserts_for_indexing\n}\nfn index_different_slices_one_wrong_len(v1: &[u8], v2: &[u8]) {\n    assert!(v1.len() >= 12);\n    assert!(v2.len() > 15);\n    let _ = v1[0] + v1[12];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v2[5] + v2[15];\n}\n\nfn side_effect() -> &'static [u8] {\n    &[]\n}\n\nfn index_side_effect_expr() {\n    let _ = side_effect()[0] + side_effect()[1];\n}\n\n// ok, single access for different slices\nfn index_different_slice_in_same_expr(v1: &[u8], v2: &[u8]) {\n    let _ = v1[0] + v2[1];\n}\n\nfn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {\n    assert!(v1.len() == 2);\n    assert!(v2.len() == 4);\n    assert!(2 == v3.len());\n    assert!(4 == v4.len());\n\n    let _ = v1[0] + v1[1] + v1[2];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v2[0] + v2[1] + v2[2];\n\n    let _ = v3[0] + v3[1] + v3[2];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v4[0] + v4[1] + v4[2];\n}\n\n// ok\nfn same_index_multiple_times(v1: &[u8]) {\n    let _ = v1[0] + v1[0];\n}\n\n// ok\nfn highest_index_first(v1: &[u8]) {\n    let _ = v1[2] + v1[1] + v1[0];\n}\n\nfn issue14255(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {\n    assert_eq!(v1.len(), 2);\n    assert_eq!(v2.len(), 4);\n    assert_eq!(2, v3.len());\n    assert_eq!(4, v4.len());\n\n    let _ = v1[0] + v1[1] + v1[2];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v2[0] + v2[1] + v2[2];\n\n    let _ = v3[0] + v3[1] + v3[2];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v4[0] + v4[1] + v4[2];\n}\n\nmod issue15988 {\n    fn assert_eq_len(v: &[i32]) {\n        assert_eq!(v.len(), 2);\n        let _ = v[0] + v[1] + v[2];\n        //~^ missing_asserts_for_indexing\n    }\n\n    fn debug_assert_eq_len(v: &[i32]) {\n        debug_assert_eq!(v.len(), 2);\n        let _ = v[0] + v[1] + v[2];\n        //~^ missing_asserts_for_indexing\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/missing_asserts_for_indexing.stderr",
    "content": "error: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:30:5\n   |\nLL |     v[0] + v[1] + v[2] + v[3] + v[4]\n   |     ^^^^   ^^^^   ^^^^   ^^^^   ^^^^\n   |\n   = note: asserting the length before indexing will elide bounds checks\n   = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]`\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v.len() < 5);\nLL +     assert!(v.len() > 4);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:36:5\n   |\nLL |     v[0] + v[1] + v[2] + v[3] + v[4]\n   |     ^^^^   ^^^^   ^^^^   ^^^^   ^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v.len() <= 5);\nLL +     assert!(v.len() > 4);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:42:5\n   |\nLL |     v[0] + v[1] + v[2] + v[3] + v[4]\n   |     ^^^^   ^^^^   ^^^^   ^^^^   ^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v.len() > 3);\nLL +     assert!(v.len() > 4);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:48:5\n   |\nLL |     v[0] + v[1] + v[2] + v[3] + v[4]\n   |     ^^^^   ^^^^   ^^^^   ^^^^   ^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v.len() >= 4);\nLL +     assert!(v.len() > 4);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:66:13\n   |\nLL |     let _ = v[0];\n   |             ^^^^\n...\nLL |     let _ = v[1..4];\n   |             ^^^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v.len() >= 3);\nLL +     assert!(v.len() > 3);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:81:13\n   |\nLL |     let _ = v[0];\n   |             ^^^^\n...\nLL |     let _ = v[1..=4];\n   |             ^^^^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v.len() >= 4);\nLL +     assert!(v.len() > 4);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:97:13\n   |\nLL |     let _ = v1[0] + v1[12];\n   |             ^^^^^   ^^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v1.len() >= 12);\nLL +     assert!(v1.len() > 12);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:100:13\n   |\nLL |     let _ = v2[5] + v2[15];\n   |             ^^^^^   ^^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v2.len() >= 15);\nLL +     assert!(v2.len() > 15);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:106:13\n   |\nLL |     let _ = v1[0] + v1[12];\n   |             ^^^^^   ^^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v1.len() >= 12);\nLL +     assert!(v1.len() > 12);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:131:13\n   |\nLL |     let _ = v1[0] + v1[1] + v1[2];\n   |             ^^^^^   ^^^^^   ^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(v1.len() == 2);\nLL +     assert!(v1.len() == 3);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:136:13\n   |\nLL |     let _ = v3[0] + v3[1] + v3[2];\n   |             ^^^^^   ^^^^^   ^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert!(2 == v3.len());\nLL +     assert!(v3.len() == 3);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:158:13\n   |\nLL |     let _ = v1[0] + v1[1] + v1[2];\n   |             ^^^^^   ^^^^^   ^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert_eq!(v1.len(), 2);\nLL +     assert_eq!(v1.len(), 3);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:163:13\n   |\nLL |     let _ = v3[0] + v3[1] + v3[2];\n   |             ^^^^^   ^^^^^   ^^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -     assert_eq!(2, v3.len());\nLL +     assert_eq!(v3.len(), 3);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:172:17\n   |\nLL |         let _ = v[0] + v[1] + v[2];\n   |                 ^^^^   ^^^^   ^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -         assert_eq!(v.len(), 2);\nLL +         assert_eq!(v.len(), 3);\n   |\n\nerror: indexing into a slice multiple times with an `assert` that does not cover the highest index\n  --> tests/ui/missing_asserts_for_indexing.rs:178:17\n   |\nLL |         let _ = v[0] + v[1] + v[2];\n   |                 ^^^^   ^^^^   ^^^^\n   |\nhelp: provide the highest index that is indexed with\n   |\nLL -         debug_assert_eq!(v.len(), 2);\nLL +         debug_assert_eq!(v.len(), 3);\n   |\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_asserts_for_indexing_unfixable.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::missing_asserts_for_indexing)]\n\nfn sum(v: &[u8]) -> u8 {\n    v[0] + v[1] + v[2] + v[3] + v[4]\n    //~^ missing_asserts_for_indexing\n}\n\nfn subslice(v: &[u8]) {\n    let _ = v[0];\n    //~^ missing_asserts_for_indexing\n\n    let _ = v[1..4];\n}\n\nfn variables(v: &[u8]) -> u8 {\n    let a = v[0];\n    //~^ missing_asserts_for_indexing\n\n    let b = v[1];\n    let c = v[2];\n    a + b + c\n}\n\nfn index_different_slices(v1: &[u8], v2: &[u8]) {\n    let _ = v1[0] + v1[12];\n    //~^ missing_asserts_for_indexing\n    let _ = v2[5] + v2[15];\n    //~^ missing_asserts_for_indexing\n}\n\nfn index_different_slices2(v1: &[u8], v2: &[u8]) {\n    assert!(v1.len() > 12);\n    let _ = v1[0] + v1[12];\n    let _ = v2[5] + v2[15];\n    //~^ missing_asserts_for_indexing\n}\n\nstruct Foo<'a> {\n    v: &'a [u8],\n    v2: &'a [u8],\n}\n\nfn index_struct_field(f: &Foo<'_>) {\n    let _ = f.v[0] + f.v[1];\n    //~^ missing_asserts_for_indexing\n}\n\nfn index_struct_different_fields(f: &Foo<'_>) {\n    // ok, different fields\n    let _ = f.v[0] + f.v2[1];\n}\n\nfn shadowing() {\n    let x: &[i32] = &[1];\n    assert!(x.len() > 1);\n\n    let x: &[i32] = &[1];\n    let _ = x[0] + x[1];\n    //~^ missing_asserts_for_indexing\n}\n\npub fn issue11856(values: &[i32]) -> usize {\n    let mut ascending = Vec::new();\n    for w in values.windows(2) {\n        assert!(w.len() > 1);\n        if w[0] < w[1] {\n            ascending.push((w[0], w[1]));\n        } else {\n            ascending.push((w[1], w[0]));\n        }\n    }\n    ascending.len()\n}\n\nfn assert_after_indexing(v1: &[u8]) {\n    let _ = v1[1] + v1[2];\n    //~^ ERROR: indexing into a slice multiple times without an `assert`\n    assert!(v1.len() > 2);\n}\n\nfn issue14255(v1: &[u8]) {\n    assert_ne!(v1.len(), 2);\n\n    let _ = v1[0] + v1[1] + v1[2];\n    //~^ missing_asserts_for_indexing\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/missing_asserts_for_indexing_unfixable.stderr",
    "content": "error: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:5:5\n   |\nLL |     v[0] + v[1] + v[2] + v[3] + v[4]\n   |     ^^^^   ^^^^   ^^^^   ^^^^   ^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(v.len() > 4);`\n   = note: asserting the length before indexing will elide bounds checks\n   = note: `-D clippy::missing-asserts-for-indexing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_asserts_for_indexing)]`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:10:13\n   |\nLL |     let _ = v[0];\n   |             ^^^^\n...\nLL |     let _ = v[1..4];\n   |             ^^^^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(v.len() > 3);`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:17:13\n   |\nLL |     let a = v[0];\n   |             ^^^^\n...\nLL |     let b = v[1];\n   |             ^^^^\nLL |     let c = v[2];\n   |             ^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(v.len() > 2);`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:26:13\n   |\nLL |     let _ = v1[0] + v1[12];\n   |             ^^^^^   ^^^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(v1.len() > 12);`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:28:13\n   |\nLL |     let _ = v2[5] + v2[15];\n   |             ^^^^^   ^^^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(v2.len() > 15);`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:35:13\n   |\nLL |     let _ = v2[5] + v2[15];\n   |             ^^^^^   ^^^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(v2.len() > 15);`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:45:13\n   |\nLL |     let _ = f.v[0] + f.v[1];\n   |             ^^^^^^   ^^^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(f.v.len() > 1);`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:59:13\n   |\nLL |     let _ = x[0] + x[1];\n   |             ^^^^   ^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(x.len() > 1);`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:77:13\n   |\nLL |     let _ = v1[1] + v1[2];\n   |             ^^^^^   ^^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(v1.len() > 2);`\n\nerror: indexing into a slice multiple times without an `assert`\n  --> tests/ui/missing_asserts_for_indexing_unfixable.rs:85:13\n   |\nLL |     let _ = v1[0] + v1[1] + v1[2];\n   |             ^^^^^   ^^^^^   ^^^^^\n   |\n   = help: consider asserting the length before indexing: `assert!(v1.len() > 2);`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_const_for_fn/auxiliary/helper.rs",
    "content": "// This file provides a const function that is unstably const forever.\n\n#![feature(staged_api)]\n#![stable(feature = \"clippytest\", since = \"1.0.0\")]\n\n#[stable(feature = \"clippytest\", since = \"1.0.0\")]\n#[rustc_const_unstable(feature = \"foo\", issue = \"none\")]\npub const fn unstably_const_fn() {}\n"
  },
  {
    "path": "tests/ui/missing_const_for_fn/cant_be_const.rs",
    "content": "//@ check-pass\n//! False-positive tests to ensure we don't suggest `const` for things where it would cause a\n//! compilation error.\n//! The .stderr output of this test should be empty. Otherwise it's a bug somewhere.\n\n//@aux-build:helper.rs\n//@aux-build:../auxiliary/proc_macros.rs\n\n#![warn(clippy::missing_const_for_fn)]\n#![feature(type_alias_impl_trait)]\n\nextern crate helper;\nextern crate proc_macros;\n\nuse proc_macros::with_span;\n\nstruct Game; // You just lost.\n\n// This should not be linted because it's already const\nconst fn already_const() -> i32 {\n    32\n}\n\nimpl Game {\n    // This should not be linted because it's already const\n    pub const fn already_const() -> i32 {\n        32\n    }\n}\n\n// Allowing on this function, because it would lint, which we don't want in this case.\n#[allow(clippy::missing_const_for_fn)]\nfn random() -> u32 {\n    42\n}\n\n// We should not suggest to make this function `const` because `random()` is non-const\nfn random_caller() -> u32 {\n    random()\n}\n\nstatic Y: u32 = 0;\n\n// We should not suggest to make this function `const` because const functions are not allowed to\n// refer to a static variable\nfn get_y() -> u32 {\n    Y\n}\n\n#[cfg(test)]\nmod with_test_fn {\n    #[derive(Clone, Copy)]\n    pub struct Foo {\n        pub n: u32,\n    }\n\n    impl Foo {\n        #[must_use]\n        pub const fn new(n: u32) -> Foo {\n            Foo { n }\n        }\n    }\n\n    #[test]\n    fn foo_is_copy() {\n        let foo = Foo::new(42);\n        let one = foo;\n        let two = foo;\n        _ = one;\n        _ = two;\n    }\n}\n\ntrait Foo {\n    // This should not be suggested to be made const\n    // (rustc doesn't allow const trait methods)\n    fn f() -> u32;\n\n    // This should not be suggested to be made const either\n    fn g() -> u32 {\n        33\n    }\n}\n\n// Don't lint in external macros (derive)\n#[derive(PartialEq, Eq)]\nstruct Point(isize, isize);\n\nimpl std::ops::Add for Point {\n    type Output = Self;\n\n    // Don't lint in trait impls of derived methods\n    fn add(self, other: Self) -> Self {\n        Point(self.0 + other.0, self.1 + other.1)\n    }\n}\n\nmod with_drop {\n    pub struct A;\n    pub struct B;\n    impl Drop for A {\n        fn drop(&mut self) {}\n    }\n\n    impl A {\n        // This can not be const because the type implements `Drop`.\n        pub fn b(self) -> B {\n            B\n        }\n    }\n\n    impl B {\n        // This can not be const because `a` implements `Drop`.\n        pub fn a(self, a: A) -> B {\n            B\n        }\n    }\n}\n\nfn const_generic_params<T, const N: usize>(t: &[T; N]) -> &[T; N] {\n    t\n}\n\nfn const_generic_return<T, const N: usize>(t: &[T]) -> &[T; N] {\n    let p = t.as_ptr() as *const [T; N];\n\n    unsafe { &*p }\n}\n\n// Do not lint this because it calls a function whose constness is unstable.\nfn unstably_const_fn() {\n    helper::unstably_const_fn()\n}\n\n#[clippy::msrv = \"1.46.0\"]\nmod const_fn_stabilized_after_msrv {\n    // Do not lint this because `u8::is_ascii_digit` is stabilized as a const function in 1.47.0.\n    fn const_fn_stabilized_after_msrv(byte: u8) {\n        byte.is_ascii_digit();\n    }\n}\n\nwith_span! {\n    span\n    fn dont_check_in_proc_macro() {}\n}\n\n// Do not lint `String` has `Vec<u8>`, which cannot be dropped in const contexts\nfn a(this: String) {}\n\nenum A {\n    F(String),\n    N,\n}\n\n// Same here.\nfn b(this: A) {}\n\n// Minimized version of `a`.\nfn c(this: Vec<u16>) {}\n\nstruct F(A);\n\n// Do not lint\nfn f(this: F) {}\n\n// Do not lint\nfn g<T>(this: T) {}\n\nstruct Issue10617(String);\n\nimpl Issue10617 {\n    // Do not lint\n    pub fn name(self) -> String {\n        self.0\n    }\n}\n\nunion U {\n    f: u32,\n}\n\n// Do not lint because accessing union fields from const functions is unstable in 1.55\n#[clippy::msrv = \"1.55\"]\nfn h(u: U) -> u32 {\n    unsafe { u.f }\n}\n\nmod msrv {\n    struct Foo(*const u8, *mut u8);\n\n    impl Foo {\n        #[clippy::msrv = \"1.57\"]\n        fn deref_ptr_cannot_be_const(self) -> usize {\n            unsafe { *self.0 as usize }\n        }\n        #[clippy::msrv = \"1.58\"]\n        fn deref_mut_ptr_cannot_be_const(self) -> usize {\n            unsafe { *self.1 as usize }\n        }\n    }\n\n    #[clippy::msrv = \"1.61\"]\n    extern \"C\" fn c() {}\n}\n\nmod with_ty_alias {\n    type Foo = impl std::fmt::Debug;\n\n    #[define_opaque(Foo)]\n    fn foo(_: Foo) {\n        let _: Foo = 1;\n    }\n}\n\n// Do not lint because mutable references in const functions are unstable in 1.82\n#[clippy::msrv = \"1.82\"]\nfn mut_add(x: &mut i32) {\n    *x += 1;\n}\n\n#[clippy::msrv = \"1.87\"]\nmod issue14020 {\n    use std::ops::Add;\n\n    fn f<T: Add>(a: T, b: T) -> <T as Add>::Output {\n        a + b\n    }\n}\n\n#[clippy::msrv = \"1.87\"]\nmod issue14290 {\n    use std::ops::{Deref, DerefMut};\n\n    struct Wrapper<T> {\n        t: T,\n    }\n\n    impl<T> Deref for Wrapper<T> {\n        type Target = T;\n\n        fn deref(&self) -> &Self::Target {\n            &self.t\n        }\n    }\n    impl<T> DerefMut for Wrapper<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.t\n        }\n    }\n\n    struct Example(bool);\n\n    fn do_something(mut a: Wrapper<Example>) {\n        a.0 = !a.0;\n    }\n\n    pub struct Stream(Vec<u8>);\n\n    impl Stream {\n        pub fn bytes(&self) -> &[u8] {\n            &self.0\n        }\n    }\n}\n\n#[clippy::msrv = \"1.87\"]\nmod issue14091 {\n    use std::mem::ManuallyDrop;\n\n    struct BucketSlotGuard<'a> {\n        id: u32,\n        free_list: &'a mut Vec<u32>,\n    }\n\n    impl BucketSlotGuard<'_> {\n        fn into_inner(self) -> u32 {\n            let this = ManuallyDrop::new(self);\n            this.id\n        }\n    }\n\n    use std::ops::{Deref, DerefMut};\n\n    struct Wrap<T>(T);\n\n    impl<T> Deref for Wrap<T> {\n        type Target = T;\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n\n    impl<T> DerefMut for Wrap<T> {\n        fn deref_mut(&mut self) -> &mut T {\n            &mut self.0\n        }\n    }\n\n    fn smart_two_field(v: &mut Wrap<(i32, i32)>) {\n        let _a = &mut v.0;\n        let _b = &mut v.1;\n    }\n\n    fn smart_destructure(v: &mut Wrap<(i32, i32)>) {\n        let (ref mut _head, ref mut _tail) = **v;\n    }\n}\n"
  },
  {
    "path": "tests/ui/missing_const_for_fn/const_trait.fixed",
    "content": "#![feature(const_trait_impl)]\n#![warn(clippy::missing_const_for_fn)]\n\n// Reduced test case from https://github.com/rust-lang/rust-clippy/issues/14658\n\nconst trait ConstTrait {\n    fn method(self);\n}\n\nimpl ConstTrait for u32 {\n    fn method(self) {}\n}\n\nimpl const ConstTrait for u64 {\n    fn method(self) {}\n}\n\nfn cannot_be_const() {\n    0u32.method();\n}\n\n//~v missing_const_for_fn\nconst fn can_be_const() {\n    0u64.method();\n}\n\n// False negative, see FIXME comment in `clippy_utils::qualify_min_const_fn`\nfn could_be_const_but_does_not_trigger<T>(t: T)\nwhere\n    T: const ConstTrait,\n{\n    t.method();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/missing_const_for_fn/const_trait.rs",
    "content": "#![feature(const_trait_impl)]\n#![warn(clippy::missing_const_for_fn)]\n\n// Reduced test case from https://github.com/rust-lang/rust-clippy/issues/14658\n\nconst trait ConstTrait {\n    fn method(self);\n}\n\nimpl ConstTrait for u32 {\n    fn method(self) {}\n}\n\nimpl const ConstTrait for u64 {\n    fn method(self) {}\n}\n\nfn cannot_be_const() {\n    0u32.method();\n}\n\n//~v missing_const_for_fn\nfn can_be_const() {\n    0u64.method();\n}\n\n// False negative, see FIXME comment in `clippy_utils::qualify_min_const_fn`\nfn could_be_const_but_does_not_trigger<T>(t: T)\nwhere\n    T: const ConstTrait,\n{\n    t.method();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/missing_const_for_fn/const_trait.stderr",
    "content": "error: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/const_trait.rs:23:1\n   |\nLL | / fn can_be_const() {\nLL | |     0u64.method();\nLL | | }\n   | |_^\n   |\n   = note: `-D clippy::missing-const-for-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_const_for_fn)]`\nhelp: make the function `const`\n   |\nLL | const fn can_be_const() {\n   | +++++\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/missing_const_for_fn/could_be_const.fixed",
    "content": "#![warn(clippy::missing_const_for_fn)]\n#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]\n#![feature(const_trait_impl)]\n\nuse std::mem::transmute;\n\nstruct Game {\n    guess: i32,\n}\n\nimpl Game {\n    // Could be const\n    pub const fn new() -> Self {\n        //~^ missing_const_for_fn\n        Self { guess: 42 }\n    }\n\n    const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {\n        //~^ missing_const_for_fn\n        b\n    }\n}\n\n// Could be const\nconst fn one() -> i32 {\n    //~^ missing_const_for_fn\n    1\n}\n\n// Could also be const\nconst fn two() -> i32 {\n    //~^ missing_const_for_fn\n    let abc = 2;\n    abc\n}\n\n// Could be const (since Rust 1.39)\nconst fn string() -> String {\n    //~^ missing_const_for_fn\n    String::new()\n}\n\n// Could be const\nconst unsafe fn four() -> i32 {\n    //~^ missing_const_for_fn\n    4\n}\n\n// Could also be const\nconst fn generic<T>(t: T) -> T {\n    //~^ missing_const_for_fn\n    t\n}\n\nfn sub(x: u32) -> usize {\n    unsafe { transmute(&x) }\n}\n\nconst fn generic_arr<T: Copy>(t: [T; 1]) -> T {\n    //~^ missing_const_for_fn\n    t[0]\n}\n\nmod with_drop {\n    pub struct A;\n    pub struct B;\n    impl Drop for A {\n        fn drop(&mut self) {}\n    }\n\n    impl B {\n        // This can be const, because `a` is passed by reference\n        pub const fn b(self, a: &A) -> B {\n            //~^ missing_const_for_fn\n            B\n        }\n    }\n}\n\n#[clippy::msrv = \"1.47.0\"]\nmod const_fn_stabilized_before_msrv {\n    // This could be const because `u8::is_ascii_digit` is a stable const function in 1.47.\n    const fn const_fn_stabilized_before_msrv(byte: u8) {\n        //~^ missing_const_for_fn\n        byte.is_ascii_digit();\n    }\n}\n\n#[clippy::msrv = \"1.45\"]\nfn msrv_1_45() -> i32 {\n    45\n}\n\n#[clippy::msrv = \"1.46\"]\nconst fn msrv_1_46() -> i32 {\n    //~^ missing_const_for_fn\n    46\n}\n\n// Should not be const\nfn main() {}\n\nstruct D;\n\n/* FIXME(const_trait_impl)\nimpl const Drop for D {\n    fn drop(&mut self) {\n        todo!();\n    }\n}\n*/\n\n// Lint this, since it can be dropped in const contexts\n// FIXME(const_trait_impl)\nconst fn d(this: D) {}\n//~^ missing_const_for_fn\n\nmod msrv {\n    struct Foo(*const u8, &'static u8);\n\n    impl Foo {\n        #[clippy::msrv = \"1.58\"]\n        const fn deref_ptr_can_be_const(self) -> usize {\n            //~^ missing_const_for_fn\n            unsafe { *self.0 as usize }\n        }\n\n        const fn deref_copied_val(self) -> usize {\n            //~^ missing_const_for_fn\n            *self.1 as usize\n        }\n    }\n\n    union Bar {\n        val: u8,\n    }\n\n    #[clippy::msrv = \"1.56\"]\n    const fn union_access_can_be_const() {\n        //~^ missing_const_for_fn\n        let bar = Bar { val: 1 };\n        let _ = unsafe { bar.val };\n    }\n\n    #[clippy::msrv = \"1.62\"]\n    mod with_extern {\n        const unsafe extern \"C\" fn c() {}\n        //~^ missing_const_for_fn\n\n        #[rustfmt::skip]\n        #[allow(missing_abi)]\n        const extern fn implicit_c() {}\n        //~^ missing_const_for_fn\n\n        // any item functions in extern block won't trigger this lint\n        unsafe extern \"C\" {\n            fn c_in_block();\n        }\n    }\n}\n\nmod issue12677 {\n    pub struct Wrapper {\n        pub strings: Vec<String>,\n    }\n\n    impl Wrapper {\n        #[must_use]\n        pub const fn new(strings: Vec<String>) -> Self {\n            //~^ missing_const_for_fn\n            Self { strings }\n        }\n\n        #[must_use]\n        pub const fn empty() -> Self {\n            //~^ missing_const_for_fn\n            Self { strings: Vec::new() }\n        }\n    }\n\n    pub struct Other {\n        pub text: String,\n        pub vec: Vec<String>,\n    }\n\n    impl Other {\n        pub const fn new(text: String) -> Self {\n            //~^ missing_const_for_fn\n            let vec = Vec::new();\n            Self { text, vec }\n        }\n    }\n}\n\nmod with_ty_alias {\n    trait FooTrait {\n        type Foo: std::fmt::Debug;\n        fn bar(_: Self::Foo) {}\n    }\n    impl FooTrait for () {\n        type Foo = i32;\n    }\n    // NOTE: When checking the type of a function param, make sure it is not an alias with\n    // `AliasTyKind::Projection` before calling `TyCtxt::type_of` to find out what the actual type\n    // is. Because the associate ty could have no default, therefore would cause ICE, as demonstrated\n    // in this test.\n    const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}\n    //~^ missing_const_for_fn\n}\n\nmod extern_fn {\n    const extern \"C-unwind\" fn c_unwind() {}\n    //~^ missing_const_for_fn\n    const extern \"system\" fn system() {}\n    //~^ missing_const_for_fn\n    const extern \"system-unwind\" fn system_unwind() {}\n    //~^ missing_const_for_fn\n}\n\nconst fn mut_add(x: &mut i32) {\n    //~^ missing_const_for_fn\n    *x += 1;\n}\n\nmod issue_15079 {\n    pub trait Trait {}\n\n    pub struct Struct<T: Trait> {\n        _t: Option<T>,\n    }\n\n    impl<T: Trait> Struct<T> {\n        #[clippy::msrv = \"1.60\"]\n        pub fn new_1_60() -> Self {\n            Self { _t: None }\n        }\n\n        #[clippy::msrv = \"1.61\"]\n        pub const fn new_1_61() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n    }\n\n    pub struct S2<T> {\n        _t: Option<T>,\n    }\n\n    impl<T> S2<T> {\n        #[clippy::msrv = \"1.60\"]\n        pub const fn new_1_60() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n\n        #[clippy::msrv = \"1.61\"]\n        pub const fn new_1_61() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n    }\n\n    pub struct S3<T: ?Sized + 'static> {\n        _t: Option<&'static T>,\n    }\n\n    impl<T: ?Sized + 'static> S3<T> {\n        #[clippy::msrv = \"1.60\"]\n        pub const fn new_1_60() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n\n        #[clippy::msrv = \"1.61\"]\n        pub const fn new_1_61() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/missing_const_for_fn/could_be_const.rs",
    "content": "#![warn(clippy::missing_const_for_fn)]\n#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]\n#![feature(const_trait_impl)]\n\nuse std::mem::transmute;\n\nstruct Game {\n    guess: i32,\n}\n\nimpl Game {\n    // Could be const\n    pub fn new() -> Self {\n        //~^ missing_const_for_fn\n        Self { guess: 42 }\n    }\n\n    fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {\n        //~^ missing_const_for_fn\n        b\n    }\n}\n\n// Could be const\nfn one() -> i32 {\n    //~^ missing_const_for_fn\n    1\n}\n\n// Could also be const\nfn two() -> i32 {\n    //~^ missing_const_for_fn\n    let abc = 2;\n    abc\n}\n\n// Could be const (since Rust 1.39)\nfn string() -> String {\n    //~^ missing_const_for_fn\n    String::new()\n}\n\n// Could be const\nunsafe fn four() -> i32 {\n    //~^ missing_const_for_fn\n    4\n}\n\n// Could also be const\nfn generic<T>(t: T) -> T {\n    //~^ missing_const_for_fn\n    t\n}\n\nfn sub(x: u32) -> usize {\n    unsafe { transmute(&x) }\n}\n\nfn generic_arr<T: Copy>(t: [T; 1]) -> T {\n    //~^ missing_const_for_fn\n    t[0]\n}\n\nmod with_drop {\n    pub struct A;\n    pub struct B;\n    impl Drop for A {\n        fn drop(&mut self) {}\n    }\n\n    impl B {\n        // This can be const, because `a` is passed by reference\n        pub fn b(self, a: &A) -> B {\n            //~^ missing_const_for_fn\n            B\n        }\n    }\n}\n\n#[clippy::msrv = \"1.47.0\"]\nmod const_fn_stabilized_before_msrv {\n    // This could be const because `u8::is_ascii_digit` is a stable const function in 1.47.\n    fn const_fn_stabilized_before_msrv(byte: u8) {\n        //~^ missing_const_for_fn\n        byte.is_ascii_digit();\n    }\n}\n\n#[clippy::msrv = \"1.45\"]\nfn msrv_1_45() -> i32 {\n    45\n}\n\n#[clippy::msrv = \"1.46\"]\nfn msrv_1_46() -> i32 {\n    //~^ missing_const_for_fn\n    46\n}\n\n// Should not be const\nfn main() {}\n\nstruct D;\n\n/* FIXME(const_trait_impl)\nimpl const Drop for D {\n    fn drop(&mut self) {\n        todo!();\n    }\n}\n*/\n\n// Lint this, since it can be dropped in const contexts\n// FIXME(const_trait_impl)\nfn d(this: D) {}\n//~^ missing_const_for_fn\n\nmod msrv {\n    struct Foo(*const u8, &'static u8);\n\n    impl Foo {\n        #[clippy::msrv = \"1.58\"]\n        fn deref_ptr_can_be_const(self) -> usize {\n            //~^ missing_const_for_fn\n            unsafe { *self.0 as usize }\n        }\n\n        fn deref_copied_val(self) -> usize {\n            //~^ missing_const_for_fn\n            *self.1 as usize\n        }\n    }\n\n    union Bar {\n        val: u8,\n    }\n\n    #[clippy::msrv = \"1.56\"]\n    fn union_access_can_be_const() {\n        //~^ missing_const_for_fn\n        let bar = Bar { val: 1 };\n        let _ = unsafe { bar.val };\n    }\n\n    #[clippy::msrv = \"1.62\"]\n    mod with_extern {\n        unsafe extern \"C\" fn c() {}\n        //~^ missing_const_for_fn\n\n        #[rustfmt::skip]\n        #[allow(missing_abi)]\n        extern fn implicit_c() {}\n        //~^ missing_const_for_fn\n\n        // any item functions in extern block won't trigger this lint\n        unsafe extern \"C\" {\n            fn c_in_block();\n        }\n    }\n}\n\nmod issue12677 {\n    pub struct Wrapper {\n        pub strings: Vec<String>,\n    }\n\n    impl Wrapper {\n        #[must_use]\n        pub fn new(strings: Vec<String>) -> Self {\n            //~^ missing_const_for_fn\n            Self { strings }\n        }\n\n        #[must_use]\n        pub fn empty() -> Self {\n            //~^ missing_const_for_fn\n            Self { strings: Vec::new() }\n        }\n    }\n\n    pub struct Other {\n        pub text: String,\n        pub vec: Vec<String>,\n    }\n\n    impl Other {\n        pub fn new(text: String) -> Self {\n            //~^ missing_const_for_fn\n            let vec = Vec::new();\n            Self { text, vec }\n        }\n    }\n}\n\nmod with_ty_alias {\n    trait FooTrait {\n        type Foo: std::fmt::Debug;\n        fn bar(_: Self::Foo) {}\n    }\n    impl FooTrait for () {\n        type Foo = i32;\n    }\n    // NOTE: When checking the type of a function param, make sure it is not an alias with\n    // `AliasTyKind::Projection` before calling `TyCtxt::type_of` to find out what the actual type\n    // is. Because the associate ty could have no default, therefore would cause ICE, as demonstrated\n    // in this test.\n    fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}\n    //~^ missing_const_for_fn\n}\n\nmod extern_fn {\n    extern \"C-unwind\" fn c_unwind() {}\n    //~^ missing_const_for_fn\n    extern \"system\" fn system() {}\n    //~^ missing_const_for_fn\n    extern \"system-unwind\" fn system_unwind() {}\n    //~^ missing_const_for_fn\n}\n\nfn mut_add(x: &mut i32) {\n    //~^ missing_const_for_fn\n    *x += 1;\n}\n\nmod issue_15079 {\n    pub trait Trait {}\n\n    pub struct Struct<T: Trait> {\n        _t: Option<T>,\n    }\n\n    impl<T: Trait> Struct<T> {\n        #[clippy::msrv = \"1.60\"]\n        pub fn new_1_60() -> Self {\n            Self { _t: None }\n        }\n\n        #[clippy::msrv = \"1.61\"]\n        pub fn new_1_61() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n    }\n\n    pub struct S2<T> {\n        _t: Option<T>,\n    }\n\n    impl<T> S2<T> {\n        #[clippy::msrv = \"1.60\"]\n        pub fn new_1_60() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n\n        #[clippy::msrv = \"1.61\"]\n        pub fn new_1_61() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n    }\n\n    pub struct S3<T: ?Sized + 'static> {\n        _t: Option<&'static T>,\n    }\n\n    impl<T: ?Sized + 'static> S3<T> {\n        #[clippy::msrv = \"1.60\"]\n        pub fn new_1_60() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n\n        #[clippy::msrv = \"1.61\"]\n        pub fn new_1_61() -> Self {\n            //~^ missing_const_for_fn\n            Self { _t: None }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/missing_const_for_fn/could_be_const.stderr",
    "content": "error: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:13:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |         Self { guess: 42 }\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::missing-const-for-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_const_for_fn)]`\nhelp: make the function `const`\n   |\nLL |     pub const fn new() -> Self {\n   |         +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:18:5\n   |\nLL | /     fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {\nLL | |\nLL | |         b\nLL | |     }\n   | |_____^\n   |\nhelp: make the function `const`\n   |\nLL |     const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {\n   |     +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:25:1\n   |\nLL | / fn one() -> i32 {\nLL | |\nLL | |     1\nLL | | }\n   | |_^\n   |\nhelp: make the function `const`\n   |\nLL | const fn one() -> i32 {\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:31:1\n   |\nLL | / fn two() -> i32 {\nLL | |\nLL | |     let abc = 2;\nLL | |     abc\nLL | | }\n   | |_^\n   |\nhelp: make the function `const`\n   |\nLL | const fn two() -> i32 {\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:38:1\n   |\nLL | / fn string() -> String {\nLL | |\nLL | |     String::new()\nLL | | }\n   | |_^\n   |\nhelp: make the function `const`\n   |\nLL | const fn string() -> String {\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:44:1\n   |\nLL | / unsafe fn four() -> i32 {\nLL | |\nLL | |     4\nLL | | }\n   | |_^\n   |\nhelp: make the function `const`\n   |\nLL | const unsafe fn four() -> i32 {\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:50:1\n   |\nLL | / fn generic<T>(t: T) -> T {\nLL | |\nLL | |     t\nLL | | }\n   | |_^\n   |\nhelp: make the function `const`\n   |\nLL | const fn generic<T>(t: T) -> T {\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:59:1\n   |\nLL | / fn generic_arr<T: Copy>(t: [T; 1]) -> T {\nLL | |\nLL | |     t[0]\nLL | | }\n   | |_^\n   |\nhelp: make the function `const`\n   |\nLL | const fn generic_arr<T: Copy>(t: [T; 1]) -> T {\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:73:9\n   |\nLL | /         pub fn b(self, a: &A) -> B {\nLL | |\nLL | |             B\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn b(self, a: &A) -> B {\n   |             +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:83:5\n   |\nLL | /     fn const_fn_stabilized_before_msrv(byte: u8) {\nLL | |\nLL | |         byte.is_ascii_digit();\nLL | |     }\n   | |_____^\n   |\nhelp: make the function `const`\n   |\nLL |     const fn const_fn_stabilized_before_msrv(byte: u8) {\n   |     +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:95:1\n   |\nLL | / fn msrv_1_46() -> i32 {\nLL | |\nLL | |     46\nLL | | }\n   | |_^\n   |\nhelp: make the function `const`\n   |\nLL | const fn msrv_1_46() -> i32 {\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:115:1\n   |\nLL | fn d(this: D) {}\n   | ^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `const`\n   |\nLL | const fn d(this: D) {}\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:123:9\n   |\nLL | /         fn deref_ptr_can_be_const(self) -> usize {\nLL | |\nLL | |             unsafe { *self.0 as usize }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         const fn deref_ptr_can_be_const(self) -> usize {\n   |         +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:128:9\n   |\nLL | /         fn deref_copied_val(self) -> usize {\nLL | |\nLL | |             *self.1 as usize\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         const fn deref_copied_val(self) -> usize {\n   |         +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:139:5\n   |\nLL | /     fn union_access_can_be_const() {\nLL | |\nLL | |         let bar = Bar { val: 1 };\nLL | |         let _ = unsafe { bar.val };\nLL | |     }\n   | |_____^\n   |\nhelp: make the function `const`\n   |\nLL |     const fn union_access_can_be_const() {\n   |     +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:147:9\n   |\nLL |         unsafe extern \"C\" fn c() {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `const`\n   |\nLL |         const unsafe extern \"C\" fn c() {}\n   |         +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9\n   |\nLL |         extern fn implicit_c() {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `const`\n   |\nLL |         const extern fn implicit_c() {}\n   |         +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:169:9\n   |\nLL | /         pub fn new(strings: Vec<String>) -> Self {\nLL | |\nLL | |             Self { strings }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn new(strings: Vec<String>) -> Self {\n   |             +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:175:9\n   |\nLL | /         pub fn empty() -> Self {\nLL | |\nLL | |             Self { strings: Vec::new() }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn empty() -> Self {\n   |             +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:187:9\n   |\nLL | /         pub fn new(text: String) -> Self {\nLL | |\nLL | |             let vec = Vec::new();\nLL | |             Self { text, vec }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn new(text: String) -> Self {\n   |             +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:207:5\n   |\nLL |     fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `const`\n   |\nLL |     const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}\n   |     +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:212:5\n   |\nLL |     extern \"C-unwind\" fn c_unwind() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `const`\n   |\nLL |     const extern \"C-unwind\" fn c_unwind() {}\n   |     +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:214:5\n   |\nLL |     extern \"system\" fn system() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `const`\n   |\nLL |     const extern \"system\" fn system() {}\n   |     +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:216:5\n   |\nLL |     extern \"system-unwind\" fn system_unwind() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: make the function `const`\n   |\nLL |     const extern \"system-unwind\" fn system_unwind() {}\n   |     +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:220:1\n   |\nLL | / fn mut_add(x: &mut i32) {\nLL | |\nLL | |     *x += 1;\nLL | | }\n   | |_^\n   |\nhelp: make the function `const`\n   |\nLL | const fn mut_add(x: &mut i32) {\n   | +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:239:9\n   |\nLL | /         pub fn new_1_61() -> Self {\nLL | |\nLL | |             Self { _t: None }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn new_1_61() -> Self {\n   |             +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:251:9\n   |\nLL | /         pub fn new_1_60() -> Self {\nLL | |\nLL | |             Self { _t: None }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn new_1_60() -> Self {\n   |             +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:257:9\n   |\nLL | /         pub fn new_1_61() -> Self {\nLL | |\nLL | |             Self { _t: None }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn new_1_61() -> Self {\n   |             +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:269:9\n   |\nLL | /         pub fn new_1_60() -> Self {\nLL | |\nLL | |             Self { _t: None }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn new_1_60() -> Self {\n   |             +++++\n\nerror: this could be a `const fn`\n  --> tests/ui/missing_const_for_fn/could_be_const.rs:275:9\n   |\nLL | /         pub fn new_1_61() -> Self {\nLL | |\nLL | |             Self { _t: None }\nLL | |         }\n   | |_________^\n   |\nhelp: make the function `const`\n   |\nLL |         pub const fn new_1_61() -> Self {\n   |             +++++\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_const_for_thread_local.fixed",
    "content": "#![warn(clippy::missing_const_for_thread_local)]\n\nuse std::cell::{Cell, RefCell};\n\nfn main() {\n    // lint and suggest const\n    thread_local! {\n        static BUF_1: RefCell<String> = const { RefCell::new(String::new()) };\n        //~^ missing_const_for_thread_local\n    }\n\n    // don't lint\n    thread_local! {\n        static BUF_2: RefCell<String> = const { RefCell::new(String::new()) };\n    }\n\n    thread_local! {\n        static SIMPLE:i32 = const { 1 };\n        //~^ missing_const_for_thread_local\n    }\n\n    // lint and suggest const for all non const items\n    thread_local! {\n        static BUF_3_CAN_BE_MADE_CONST: RefCell<String> = const { RefCell::new(String::new()) };\n        //~^ missing_const_for_thread_local\n        static CONST_MIXED_WITH:i32 = const { 1 };\n        static BUF_4_CAN_BE_MADE_CONST: RefCell<String> = const { RefCell::new(String::new()) };\n        //~^ missing_const_for_thread_local\n    }\n\n    thread_local! {\n        static PEEL_ME: i32 = const { 1 };\n        //~^ missing_const_for_thread_local\n\n        static PEEL_ME_MANY: i32 = const { { let x = 1; x * x } };\n        //~^ missing_const_for_thread_local\n\n    }\n}\n\nfn issue_12637() {\n    /// The set methods on LocalKey<Cell<T>> and LocalKey<RefCell<T>> are\n    /// guaranteed to bypass the thread_local's initialization expression.\n    /// See rust-lang/rust#92122. Thus, = panic!() is a useful idiom for\n    /// forcing the use of set on each thread before it accesses the thread local in any other\n    /// manner.\n    thread_local! {\n        static STATE_12637_PANIC: Cell<usize> = panic!();\n    }\n    STATE_12637_PANIC.set(9);\n    println!(\"{}\", STATE_12637_PANIC.get());\n\n    thread_local! {\n        static STATE_12637_TODO: Cell<usize> = todo!();\n    }\n    STATE_12637_TODO.set(9);\n    println!(\"{}\", STATE_12637_TODO.get());\n\n    thread_local! {\n        static STATE_12637_UNIMPLEMENTED: Cell<usize> = unimplemented!();\n    }\n    STATE_12637_UNIMPLEMENTED.set(9);\n    println!(\"{}\", STATE_12637_UNIMPLEMENTED.get());\n\n    thread_local! {\n        static STATE_12637_UNREACHABLE: Cell<usize> = unreachable!();\n    }\n    STATE_12637_UNREACHABLE.set(9);\n    println!(\"{}\", STATE_12637_UNREACHABLE.get());\n}\n\n#[clippy::msrv = \"1.58\"]\nfn f() {\n    thread_local! {\n        static TLS: i32 = 1;\n    }\n}\n"
  },
  {
    "path": "tests/ui/missing_const_for_thread_local.rs",
    "content": "#![warn(clippy::missing_const_for_thread_local)]\n\nuse std::cell::{Cell, RefCell};\n\nfn main() {\n    // lint and suggest const\n    thread_local! {\n        static BUF_1: RefCell<String> = RefCell::new(String::new());\n        //~^ missing_const_for_thread_local\n    }\n\n    // don't lint\n    thread_local! {\n        static BUF_2: RefCell<String> = const { RefCell::new(String::new()) };\n    }\n\n    thread_local! {\n        static SIMPLE:i32 = 1;\n        //~^ missing_const_for_thread_local\n    }\n\n    // lint and suggest const for all non const items\n    thread_local! {\n        static BUF_3_CAN_BE_MADE_CONST: RefCell<String> = RefCell::new(String::new());\n        //~^ missing_const_for_thread_local\n        static CONST_MIXED_WITH:i32 = const { 1 };\n        static BUF_4_CAN_BE_MADE_CONST: RefCell<String> = RefCell::new(String::new());\n        //~^ missing_const_for_thread_local\n    }\n\n    thread_local! {\n        static PEEL_ME: i32 = { 1 };\n        //~^ missing_const_for_thread_local\n\n        static PEEL_ME_MANY: i32 = { let x = 1; x * x };\n        //~^ missing_const_for_thread_local\n\n    }\n}\n\nfn issue_12637() {\n    /// The set methods on LocalKey<Cell<T>> and LocalKey<RefCell<T>> are\n    /// guaranteed to bypass the thread_local's initialization expression.\n    /// See rust-lang/rust#92122. Thus, = panic!() is a useful idiom for\n    /// forcing the use of set on each thread before it accesses the thread local in any other\n    /// manner.\n    thread_local! {\n        static STATE_12637_PANIC: Cell<usize> = panic!();\n    }\n    STATE_12637_PANIC.set(9);\n    println!(\"{}\", STATE_12637_PANIC.get());\n\n    thread_local! {\n        static STATE_12637_TODO: Cell<usize> = todo!();\n    }\n    STATE_12637_TODO.set(9);\n    println!(\"{}\", STATE_12637_TODO.get());\n\n    thread_local! {\n        static STATE_12637_UNIMPLEMENTED: Cell<usize> = unimplemented!();\n    }\n    STATE_12637_UNIMPLEMENTED.set(9);\n    println!(\"{}\", STATE_12637_UNIMPLEMENTED.get());\n\n    thread_local! {\n        static STATE_12637_UNREACHABLE: Cell<usize> = unreachable!();\n    }\n    STATE_12637_UNREACHABLE.set(9);\n    println!(\"{}\", STATE_12637_UNREACHABLE.get());\n}\n\n#[clippy::msrv = \"1.58\"]\nfn f() {\n    thread_local! {\n        static TLS: i32 = 1;\n    }\n}\n"
  },
  {
    "path": "tests/ui/missing_const_for_thread_local.stderr",
    "content": "error: initializer for `thread_local` value can be made `const`\n  --> tests/ui/missing_const_for_thread_local.rs:8:41\n   |\nLL |         static BUF_1: RefCell<String> = RefCell::new(String::new());\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }`\n   |\n   = note: `-D clippy::missing-const-for-thread-local` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_const_for_thread_local)]`\n\nerror: initializer for `thread_local` value can be made `const`\n  --> tests/ui/missing_const_for_thread_local.rs:18:29\n   |\nLL |         static SIMPLE:i32 = 1;\n   |                             ^ help: replace with: `const { 1 }`\n\nerror: initializer for `thread_local` value can be made `const`\n  --> tests/ui/missing_const_for_thread_local.rs:24:59\n   |\nLL |         static BUF_3_CAN_BE_MADE_CONST: RefCell<String> = RefCell::new(String::new());\n   |                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }`\n\nerror: initializer for `thread_local` value can be made `const`\n  --> tests/ui/missing_const_for_thread_local.rs:27:59\n   |\nLL |         static BUF_4_CAN_BE_MADE_CONST: RefCell<String> = RefCell::new(String::new());\n   |                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }`\n\nerror: initializer for `thread_local` value can be made `const`\n  --> tests/ui/missing_const_for_thread_local.rs:32:31\n   |\nLL |         static PEEL_ME: i32 = { 1 };\n   |                               ^^^^^ help: replace with: `const { 1 }`\n\nerror: initializer for `thread_local` value can be made `const`\n  --> tests/ui/missing_const_for_thread_local.rs:35:36\n   |\nLL |         static PEEL_ME_MANY: i32 = { let x = 1; x * x };\n   |                                    ^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { { let x = 1; x * x } }`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_fields_in_debug.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::missing_fields_in_debug)]\n\nuse std::fmt;\nuse std::marker::PhantomData;\nuse std::ops::Deref;\nuse std::thread::LocalKey;\n\nstruct NamedStruct1Ignored {\n    data: u8,\n    hidden: u32,\n}\n\nimpl fmt::Debug for NamedStruct1Ignored {\n    //~^ missing_fields_in_debug\n\n    // unused field: hidden\n    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n        formatter\n            .debug_struct(\"NamedStruct1Ignored\")\n            .field(\"data\", &self.data)\n            .finish()\n    }\n}\n\nstruct NamedStructMultipleIgnored {\n    data: u8,\n    hidden: u32,\n    hidden2: String,\n    hidden3: Vec<Vec<i32>>,\n    hidden4: ((((u8), u16), u32), u64),\n}\n\nimpl fmt::Debug for NamedStructMultipleIgnored {\n    //~^ missing_fields_in_debug\n\n    // unused fields: hidden, hidden2, hidden4\n    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n        formatter\n            .debug_struct(\"NamedStructMultipleIgnored\")\n            .field(\"data\", &self.data)\n            .field(\"hidden3\", &self.hidden3)\n            .finish()\n    }\n}\n\nstruct Unit;\n\n// ok\nimpl fmt::Debug for Unit {\n    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n        formatter.debug_struct(\"Unit\").finish()\n    }\n}\n\nstruct UnnamedStruct1Ignored(String);\n\nimpl fmt::Debug for UnnamedStruct1Ignored {\n    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n        formatter.debug_tuple(\"UnnamedStruct1Ignored\").finish()\n    }\n}\n\nstruct UnnamedStructMultipleIgnored(String, Vec<u8>, i32);\n\n// tuple structs are not linted\nimpl fmt::Debug for UnnamedStructMultipleIgnored {\n    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n        formatter\n            .debug_tuple(\"UnnamedStructMultipleIgnored\")\n            .field(&self.1)\n            .finish()\n    }\n}\n\nstruct NamedStructNonExhaustive {\n    a: u8,\n    b: String,\n}\n\n// ok\nimpl fmt::Debug for NamedStructNonExhaustive {\n    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n        formatter\n            .debug_struct(\"NamedStructNonExhaustive\")\n            .field(\"a\", &self.a)\n            .finish_non_exhaustive() // should not warn here\n    }\n}\n\nstruct MultiExprDebugImpl {\n    a: u8,\n    b: String,\n}\n\n// ok\nimpl fmt::Debug for MultiExprDebugImpl {\n    //~^ missing_fields_in_debug\n\n    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n        let mut f = formatter.debug_struct(\"MultiExprDebugImpl\");\n        f.field(\"a\", &self.a);\n        f.finish()\n    }\n}\n\n#[derive(Debug)]\nstruct DerivedStruct {\n    a: u8,\n    b: i32,\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/10616#discussion_r1166846953\n\nstruct Inner {\n    a: usize,\n    b: usize,\n}\n\nstruct HasInner {\n    inner: Inner,\n}\n\nimpl HasInner {\n    fn get(&self) -> &Inner {\n        &self.inner\n    }\n}\n\nimpl fmt::Debug for HasInner {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        let inner = self.get();\n\n        f.debug_struct(\"HasInner\")\n            .field(\"a\", &inner.a)\n            .field(\"b\", &inner.b)\n            .finish()\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/10616#discussion_r1170306053\nstruct Foo {\n    a: u8,\n    b: u8,\n}\n\nimpl fmt::Debug for Foo {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Foo\").field(\"a\", &self.a).field(\"b\", &()).finish()\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/10616#discussion_r1175473620\nmod comment1175473620 {\n    use super::*;\n\n    struct Inner {\n        a: usize,\n        b: usize,\n    }\n    struct Wrapper(Inner);\n\n    impl Deref for Wrapper {\n        type Target = Inner;\n\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n\n    impl fmt::Debug for Wrapper {\n        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n            f.debug_struct(\"Wrapper\")\n                .field(\"a\", &self.a)\n                .field(\"b\", &self.b)\n                .finish()\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/10616#discussion_r1175488757\n// PhantomData is an exception and does not need to be included\nstruct WithPD {\n    a: u8,\n    b: u8,\n    c: PhantomData<String>,\n}\n\nimpl fmt::Debug for WithPD {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"WithPD\")\n            .field(\"a\", &self.a)\n            .field(\"b\", &self.b)\n            .finish()\n    }\n}\n\nstruct InClosure {\n    a: u8,\n    b: String,\n}\n\nimpl fmt::Debug for InClosure {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        let mut d = f.debug_struct(\"InClosure\");\n        d.field(\"a\", &self.a);\n        let mut c = || {\n            d.field(\"b\", &self.b);\n        };\n        c();\n        d.finish()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/missing_fields_in_debug.stderr",
    "content": "error: manual `Debug` impl does not include all fields\n  --> tests/ui/missing_fields_in_debug.rs:14:1\n   |\nLL | / impl fmt::Debug for NamedStruct1Ignored {\n...  |\nLL | | }\n   | |_^\n   |\nnote: this field is unused\n  --> tests/ui/missing_fields_in_debug.rs:11:5\n   |\nLL |     hidden: u32,\n   |     ^^^^^^^^^^^\n   = help: consider including all fields in this `Debug` impl\n   = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields\n   = note: `-D clippy::missing-fields-in-debug` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_fields_in_debug)]`\n\nerror: manual `Debug` impl does not include all fields\n  --> tests/ui/missing_fields_in_debug.rs:34:1\n   |\nLL | / impl fmt::Debug for NamedStructMultipleIgnored {\n...  |\nLL | | }\n   | |_^\n   |\nnote: this field is unused\n  --> tests/ui/missing_fields_in_debug.rs:28:5\n   |\nLL |     hidden: u32,\n   |     ^^^^^^^^^^^\nnote: this field is unused\n  --> tests/ui/missing_fields_in_debug.rs:29:5\n   |\nLL |     hidden2: String,\n   |     ^^^^^^^^^^^^^^^\nnote: this field is unused\n  --> tests/ui/missing_fields_in_debug.rs:31:5\n   |\nLL |     hidden4: ((((u8), u16), u32), u64),\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: consider including all fields in this `Debug` impl\n   = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields\n\nerror: manual `Debug` impl does not include all fields\n  --> tests/ui/missing_fields_in_debug.rs:97:1\n   |\nLL | / impl fmt::Debug for MultiExprDebugImpl {\nLL | |\nLL | |\nLL | |     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {\n...  |\nLL | | }\n   | |_^\n   |\nnote: this field is unused\n  --> tests/ui/missing_fields_in_debug.rs:93:5\n   |\nLL |     b: String,\n   |     ^^^^^^^^^\n   = help: consider including all fields in this `Debug` impl\n   = help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_inline.rs",
    "content": "#![warn(clippy::missing_inline_in_public_items)]\n#![crate_type = \"dylib\"]\n// When denying at the crate level, be sure to not get random warnings from the\n// injected intrinsics by the compiler.\n#![allow(dead_code, non_snake_case)]\n\ntype Typedef = String;\npub type PubTypedef = String;\n\nstruct Foo; // ok\npub struct PubFoo; // ok\nenum FooE {} // ok\npub enum PubFooE {} // ok\n\nmod module {} // ok\npub mod pub_module {} // ok\n\nfn foo() {}\n// missing #[inline]\npub fn pub_foo() {}\n//~^ missing_inline_in_public_items\n\n#[inline]\npub fn pub_foo_inline() {} // ok\n#[inline(always)]\npub fn pub_foo_inline_always() {} // ok\n\n#[allow(clippy::missing_inline_in_public_items)]\npub fn pub_foo_no_inline() {}\n\ntrait Bar {\n    fn Bar_a(); // ok\n    fn Bar_b() {} // ok\n}\n\npub trait PubBar {\n    fn PubBar_a(); // ok\n    // missing #[inline]\n    fn PubBar_b() {}\n    //~^ missing_inline_in_public_items\n\n    #[inline]\n    fn PubBar_c() {} // ok\n}\n\n// none of these need inline because Foo is not exported\nimpl PubBar for Foo {\n    fn PubBar_a() {} // ok\n    fn PubBar_b() {} // ok\n    fn PubBar_c() {} // ok\n}\n\n// all of these need inline because PubFoo is exported\nimpl PubBar for PubFoo {\n    // missing #[inline]\n    fn PubBar_a() {}\n    //~^ missing_inline_in_public_items\n\n    // missing #[inline]\n    fn PubBar_b() {}\n    //~^ missing_inline_in_public_items\n\n    // missing #[inline]\n    fn PubBar_c() {}\n    //~^ missing_inline_in_public_items\n}\n\n// do not need inline because Foo is not exported\nimpl Foo {\n    fn FooImpl() {} // ok\n}\n\n// need inline because PubFoo is exported\nimpl PubFoo {\n    // missing #[inline]\n    pub fn PubFooImpl() {}\n    //~^ missing_inline_in_public_items\n}\n\n// do not lint this since users cannot control the external code\n#[derive(Debug)]\npub struct S;\n\npub mod issue15301 {\n    #[unsafe(no_mangle)]\n    pub extern \"C\" fn call_from_c() {\n        println!(\"Just called a Rust function from C!\");\n    }\n\n    #[unsafe(no_mangle)]\n    pub extern \"Rust\" fn call_from_rust() {\n        println!(\"Just called a Rust function from Rust!\");\n    }\n\n    #[unsafe(no_mangle)]\n    pub fn call_from_rust_no_extern() {\n        println!(\"Just called a Rust function from Rust!\");\n    }\n}\n\npub mod issue15491 {\n    pub trait Foo {\n        #[allow(clippy::missing_inline_in_public_items)]\n        fn foo(&self) {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/missing_inline.stderr",
    "content": "error: missing `#[inline]` for a function\n  --> tests/ui/missing_inline.rs:20:1\n   |\nLL | pub fn pub_foo() {}\n   | ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::missing-inline-in-public-items` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_inline_in_public_items)]`\n\nerror: missing `#[inline]` for a default trait method\n  --> tests/ui/missing_inline.rs:39:5\n   |\nLL |     fn PubBar_b() {}\n   |     ^^^^^^^^^^^^^^^^\n\nerror: missing `#[inline]` for a method\n  --> tests/ui/missing_inline.rs:56:5\n   |\nLL |     fn PubBar_a() {}\n   |     ^^^^^^^^^^^^^^^^\n\nerror: missing `#[inline]` for a method\n  --> tests/ui/missing_inline.rs:60:5\n   |\nLL |     fn PubBar_b() {}\n   |     ^^^^^^^^^^^^^^^^\n\nerror: missing `#[inline]` for a method\n  --> tests/ui/missing_inline.rs:64:5\n   |\nLL |     fn PubBar_c() {}\n   |     ^^^^^^^^^^^^^^^^\n\nerror: missing `#[inline]` for a method\n  --> tests/ui/missing_inline.rs:76:5\n   |\nLL |     pub fn PubFooImpl() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_inline_executable.rs",
    "content": "#![warn(clippy::missing_inline_in_public_items)]\n\npub fn foo() {}\n//~^ missing_inline_in_public_items\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/missing_inline_executable.stderr",
    "content": "error: missing `#[inline]` for a function\n  --> tests/ui/missing_inline_executable.rs:3:1\n   |\nLL | pub fn foo() {}\n   | ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::missing-inline-in-public-items` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_inline_in_public_items)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/missing_inline_proc_macro.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::missing_inline_in_public_items)]\n\nextern crate proc_macro;\n\nuse proc_macro::TokenStream;\n\nfn _foo() {}\n\n#[proc_macro]\npub fn function_like(_: TokenStream) -> TokenStream {\n    TokenStream::new()\n}\n\n#[proc_macro_attribute]\npub fn attribute(_: TokenStream, _: TokenStream) -> TokenStream {\n    TokenStream::new()\n}\n\n#[proc_macro_derive(Derive)]\npub fn derive(_: TokenStream) -> TokenStream {\n    TokenStream::new()\n}\n"
  },
  {
    "path": "tests/ui/missing_inline_test_crate.rs",
    "content": "//@compile-flags: --test\n//@check-pass\n#![warn(clippy::missing_inline_in_public_items)]\n\n#[expect(clippy::missing_inline_in_public_items)]\npub fn foo() -> u32 {\n    0\n}\n\nfn private_function() {}\n"
  },
  {
    "path": "tests/ui/missing_panics_doc.rs",
    "content": "//@aux-build:macro_rules.rs\n#![warn(clippy::missing_panics_doc)]\n#![allow(clippy::option_map_unit_fn, clippy::unnecessary_literal_unwrap)]\n\n#[macro_use]\nextern crate macro_rules;\n\nuse macro_rules::macro_with_panic;\n\nfn main() {}\n\n/// This needs to be documented\npub fn unwrap() {\n    //~^ missing_panics_doc\n    let result = Err(\"Hi\");\n    result.unwrap()\n}\n\n/// This needs to be documented\npub fn panic() {\n    //~^ missing_panics_doc\n    panic!(\"This function panics\")\n}\n\n/// This needs to be documented\npub fn inner_body(opt: Option<u32>) {\n    //~^ missing_panics_doc\n    opt.map(|x| {\n        if x == 10 {\n            panic!()\n        }\n    });\n}\n\n/// This needs to be documented\npub fn unreachable_and_panic() {\n    //~^ missing_panics_doc\n    if true { unreachable!() } else { panic!() }\n}\n\n/// This needs to be documented\npub fn assert_eq() {\n    //~^ missing_panics_doc\n    let x = 0;\n    assert_eq!(x, 0);\n}\n\n/// This needs to be documented\npub fn assert_ne() {\n    //~^ missing_panics_doc\n    let x = 0;\n    assert_ne!(x, 0);\n}\n\n/// This is documented\n///\n/// # Panics\n///\n/// Panics if `result` if an error\npub fn unwrap_documented() {\n    let result = Err(\"Hi\");\n    result.unwrap()\n}\n\n/// This is documented\n///\n/// # Panics\n///\n/// Panics just because\npub fn panic_documented() {\n    panic!(\"This function panics\")\n}\n\n/// This is documented\n///\n/// # Panics\n///\n/// Panics if `opt` is Just(10)\npub fn inner_body_documented(opt: Option<u32>) {\n    opt.map(|x| {\n        if x == 10 {\n            panic!()\n        }\n    });\n}\n\n/// This is documented\n///\n/// # Panics\n///\n/// We still need to do this part\npub fn unreachable_amd_panic_documented() {\n    if true { unreachable!() } else { panic!() }\n}\n\n/// This is documented\n///\n/// # Panics\n///\n/// Panics if `x` is not 0.\npub fn assert_eq_documented() {\n    let x = 0;\n    assert_eq!(x, 0);\n}\n\n/// This is documented\n///\n/// # Panics\n///\n/// Panics if `x` is 0.\npub fn assert_ne_documented() {\n    let x = 0;\n    assert_ne!(x, 0);\n}\n\n/// `todo!()` is fine\npub fn todo() {\n    todo!()\n}\n\n/// This is okay because it is private\nfn unwrap_private() {\n    let result = Err(\"Hi\");\n    result.unwrap()\n}\n\n/// This is okay because it is private\nfn panic_private() {\n    panic!(\"This function panics\")\n}\n\n/// This is okay because it is private\nfn inner_body_private(opt: Option<u32>) {\n    opt.map(|x| {\n        if x == 10 {\n            panic!()\n        }\n    });\n}\n\n/// This is okay because unreachable\npub fn unreachable() {\n    unreachable!(\"This function panics\")\n}\n\n/// #6970.\n/// This is okay because it is expansion of `debug_assert` family.\npub fn debug_assertions() {\n    debug_assert!(false);\n    debug_assert_eq!(1, 2);\n    debug_assert_ne!(1, 2);\n}\n\npub fn partially_const<const N: usize>(n: usize) {\n    //~^ missing_panics_doc\n\n    const {\n        assert!(N > 5);\n    }\n\n    assert!(N > n);\n}\n\npub fn expect_allow(i: Option<isize>) {\n    #[expect(clippy::missing_panics_doc)]\n    i.unwrap();\n\n    #[allow(clippy::missing_panics_doc)]\n    i.unwrap();\n}\n\npub fn expect_allow_with_error(i: Option<isize>) {\n    //~^ missing_panics_doc\n\n    #[expect(clippy::missing_panics_doc)]\n    i.unwrap();\n\n    #[allow(clippy::missing_panics_doc)]\n    i.unwrap();\n\n    i.unwrap();\n}\n\npub fn expect_after_error(x: Option<u32>, y: Option<u32>) {\n    //~^ missing_panics_doc\n\n    let x = x.unwrap();\n\n    #[expect(clippy::missing_panics_doc)]\n    let y = y.unwrap();\n}\n\n// all function must be triggered the lint.\n// `pub` is required, because the lint does not consider unreachable items\npub mod issue10240 {\n    pub fn option_unwrap<T>(v: &[T]) -> &T {\n        //~^ missing_panics_doc\n        let o: Option<&T> = v.last();\n        o.unwrap()\n    }\n\n    pub fn option_expect<T>(v: &[T]) -> &T {\n        //~^ missing_panics_doc\n        let o: Option<&T> = v.last();\n        o.expect(\"passed an empty thing\")\n    }\n\n    pub fn result_unwrap<T>(v: &[T]) -> &T {\n        //~^ missing_panics_doc\n        let res: Result<&T, &str> = v.last().ok_or(\"oh noes\");\n        res.unwrap()\n    }\n\n    pub fn result_expect<T>(v: &[T]) -> &T {\n        //~^ missing_panics_doc\n        let res: Result<&T, &str> = v.last().ok_or(\"oh noes\");\n        res.expect(\"passed an empty thing\")\n    }\n\n    pub fn last_unwrap(v: &[u32]) -> u32 {\n        //~^ missing_panics_doc\n        *v.last().unwrap()\n    }\n\n    pub fn last_expect(v: &[u32]) -> u32 {\n        //~^ missing_panics_doc\n        *v.last().expect(\"passed an empty thing\")\n    }\n}\n\nfn from_external_macro_should_not_lint() {\n    macro_with_panic!()\n}\n\nmacro_rules! some_macro_that_panics {\n    () => {\n        panic!()\n    };\n}\n\nfn from_declared_macro_should_lint_at_macrosite() {\n    // Not here.\n    some_macro_that_panics!()\n}\n\npub fn issue_12760<const N: usize>() {\n    const {\n        if N == 0 {\n            panic!();\n        }\n    }\n}\n\n/// This needs documenting\npub fn unwrap_expect_etc_in_const() {\n    let a = const { std::num::NonZeroUsize::new(1).unwrap() };\n    // This should still pass the lint even if it is guaranteed to panic at compile-time\n    let b = const { std::num::NonZeroUsize::new(0).unwrap() };\n}\n\n/// This needs documenting\npub const fn unwrap_expect_etc_in_const_fn_fails() {\n    //~^ missing_panics_doc\n    let a = std::num::NonZeroUsize::new(1).unwrap();\n}\n\n/// This needs documenting\npub const fn assert_in_const_fn_fails() {\n    //~^ missing_panics_doc\n    let x = 0;\n    if x == 0 {\n        panic!();\n    }\n}\n\n/// This needs documenting\npub const fn in_const_fn<const N: usize>(n: usize) {\n    //~^ missing_panics_doc\n    assert!(N > n);\n}\n"
  },
  {
    "path": "tests/ui/missing_panics_doc.stderr",
    "content": "error: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:13:1\n   |\nLL | pub fn unwrap() {\n   | ^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:16:5\n   |\nLL |     result.unwrap()\n   |     ^^^^^^^^^^^^^^^\n   = note: `-D clippy::missing-panics-doc` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_panics_doc)]`\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:20:1\n   |\nLL | pub fn panic() {\n   | ^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:22:5\n   |\nLL |     panic!(\"This function panics\")\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:26:1\n   |\nLL | pub fn inner_body(opt: Option<u32>) {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:30:13\n   |\nLL |             panic!()\n   |             ^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:36:1\n   |\nLL | pub fn unreachable_and_panic() {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:38:39\n   |\nLL |     if true { unreachable!() } else { panic!() }\n   |                                       ^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:42:1\n   |\nLL | pub fn assert_eq() {\n   | ^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:45:5\n   |\nLL |     assert_eq!(x, 0);\n   |     ^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:49:1\n   |\nLL | pub fn assert_ne() {\n   | ^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:52:5\n   |\nLL |     assert_ne!(x, 0);\n   |     ^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:154:1\n   |\nLL | pub fn partially_const<const N: usize>(n: usize) {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:161:5\n   |\nLL |     assert!(N > n);\n   |     ^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:172:1\n   |\nLL | pub fn expect_allow_with_error(i: Option<isize>) {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:181:5\n   |\nLL |     i.unwrap();\n   |     ^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:184:1\n   |\nLL | pub fn expect_after_error(x: Option<u32>, y: Option<u32>) {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:187:13\n   |\nLL |     let x = x.unwrap();\n   |             ^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:196:5\n   |\nLL |     pub fn option_unwrap<T>(v: &[T]) -> &T {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:199:9\n   |\nLL |         o.unwrap()\n   |         ^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:202:5\n   |\nLL |     pub fn option_expect<T>(v: &[T]) -> &T {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:205:9\n   |\nLL |         o.expect(\"passed an empty thing\")\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:208:5\n   |\nLL |     pub fn result_unwrap<T>(v: &[T]) -> &T {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:211:9\n   |\nLL |         res.unwrap()\n   |         ^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:214:5\n   |\nLL |     pub fn result_expect<T>(v: &[T]) -> &T {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:217:9\n   |\nLL |         res.expect(\"passed an empty thing\")\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:220:5\n   |\nLL |     pub fn last_unwrap(v: &[u32]) -> u32 {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:222:10\n   |\nLL |         *v.last().unwrap()\n   |          ^^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:225:5\n   |\nLL |     pub fn last_expect(v: &[u32]) -> u32 {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:227:10\n   |\nLL |         *v.last().expect(\"passed an empty thing\")\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:262:1\n   |\nLL | pub const fn unwrap_expect_etc_in_const_fn_fails() {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:264:13\n   |\nLL |     let a = std::num::NonZeroUsize::new(1).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:268:1\n   |\nLL | pub const fn assert_in_const_fn_fails() {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:272:9\n   |\nLL |         panic!();\n   |         ^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui/missing_panics_doc.rs:277:1\n   |\nLL | pub const fn in_const_fn<const N: usize>(n: usize) {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui/missing_panics_doc.rs:279:5\n   |\nLL |     assert!(N > n);\n   |     ^^^^^^^^^^^^^^\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_spin_loop.fixed",
    "content": "#![warn(clippy::missing_spin_loop)]\n#![allow(clippy::bool_comparison)]\n#![allow(unused_braces)]\n\nuse core::sync::atomic::{AtomicBool, Ordering};\n\nfn main() {\n    let b = AtomicBool::new(true);\n    // Those should lint\n    while b.load(Ordering::Acquire) { std::hint::spin_loop() }\n    //~^ missing_spin_loop\n\n    while !b.load(Ordering::SeqCst) { std::hint::spin_loop() }\n    //~^ missing_spin_loop\n\n    while b.load(Ordering::Acquire) == false { std::hint::spin_loop() }\n    //~^ missing_spin_loop\n\n    while { true == b.load(Ordering::Acquire) } { std::hint::spin_loop() }\n    //~^ missing_spin_loop\n\n    while b.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed) != Ok(true) { std::hint::spin_loop() }\n    //~^ missing_spin_loop\n\n    while Ok(false) != b.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) { std::hint::spin_loop() }\n    //~^ missing_spin_loop\n\n    // This is OK, as the body is not empty\n    while b.load(Ordering::Acquire) {\n        std::hint::spin_loop()\n    }\n    // TODO: also match on loop+match or while let\n}\n"
  },
  {
    "path": "tests/ui/missing_spin_loop.rs",
    "content": "#![warn(clippy::missing_spin_loop)]\n#![allow(clippy::bool_comparison)]\n#![allow(unused_braces)]\n\nuse core::sync::atomic::{AtomicBool, Ordering};\n\nfn main() {\n    let b = AtomicBool::new(true);\n    // Those should lint\n    while b.load(Ordering::Acquire) {}\n    //~^ missing_spin_loop\n\n    while !b.load(Ordering::SeqCst) {}\n    //~^ missing_spin_loop\n\n    while b.load(Ordering::Acquire) == false {}\n    //~^ missing_spin_loop\n\n    while { true == b.load(Ordering::Acquire) } {}\n    //~^ missing_spin_loop\n\n    while b.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed) != Ok(true) {}\n    //~^ missing_spin_loop\n\n    while Ok(false) != b.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) {}\n    //~^ missing_spin_loop\n\n    // This is OK, as the body is not empty\n    while b.load(Ordering::Acquire) {\n        std::hint::spin_loop()\n    }\n    // TODO: also match on loop+match or while let\n}\n"
  },
  {
    "path": "tests/ui/missing_spin_loop.stderr",
    "content": "error: busy-waiting loop should at least have a spin loop hint\n  --> tests/ui/missing_spin_loop.rs:10:37\n   |\nLL |     while b.load(Ordering::Acquire) {}\n   |                                     ^^ help: try: `{ std::hint::spin_loop() }`\n   |\n   = note: `-D clippy::missing-spin-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_spin_loop)]`\n\nerror: busy-waiting loop should at least have a spin loop hint\n  --> tests/ui/missing_spin_loop.rs:13:37\n   |\nLL |     while !b.load(Ordering::SeqCst) {}\n   |                                     ^^ help: try: `{ std::hint::spin_loop() }`\n\nerror: busy-waiting loop should at least have a spin loop hint\n  --> tests/ui/missing_spin_loop.rs:16:46\n   |\nLL |     while b.load(Ordering::Acquire) == false {}\n   |                                              ^^ help: try: `{ std::hint::spin_loop() }`\n\nerror: busy-waiting loop should at least have a spin loop hint\n  --> tests/ui/missing_spin_loop.rs:19:49\n   |\nLL |     while { true == b.load(Ordering::Acquire) } {}\n   |                                                 ^^ help: try: `{ std::hint::spin_loop() }`\n\nerror: busy-waiting loop should at least have a spin loop hint\n  --> tests/ui/missing_spin_loop.rs:22:93\n   |\nLL |     while b.compare_exchange(true, false, Ordering::Acquire, Ordering::Relaxed) != Ok(true) {}\n   |                                                                                             ^^ help: try: `{ std::hint::spin_loop() }`\n\nerror: busy-waiting loop should at least have a spin loop hint\n  --> tests/ui/missing_spin_loop.rs:25:94\n   |\nLL |     while Ok(false) != b.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) {}\n   |                                                                                              ^^ help: try: `{ std::hint::spin_loop() }`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_spin_loop_no_std.fixed",
    "content": "#![warn(clippy::missing_spin_loop)]\n#![crate_type = \"lib\"]\n#![no_std]\n\nuse core::sync::atomic::{AtomicBool, Ordering};\n\npub fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    // This should trigger the lint\n    let b = AtomicBool::new(true);\n    // This should lint with `core::hint::spin_loop()`\n    while b.load(Ordering::Acquire) { core::hint::spin_loop() }\n    //~^ missing_spin_loop\n    0\n}\n"
  },
  {
    "path": "tests/ui/missing_spin_loop_no_std.rs",
    "content": "#![warn(clippy::missing_spin_loop)]\n#![crate_type = \"lib\"]\n#![no_std]\n\nuse core::sync::atomic::{AtomicBool, Ordering};\n\npub fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    // This should trigger the lint\n    let b = AtomicBool::new(true);\n    // This should lint with `core::hint::spin_loop()`\n    while b.load(Ordering::Acquire) {}\n    //~^ missing_spin_loop\n    0\n}\n"
  },
  {
    "path": "tests/ui/missing_spin_loop_no_std.stderr",
    "content": "error: busy-waiting loop should at least have a spin loop hint\n  --> tests/ui/missing_spin_loop_no_std.rs:11:37\n   |\nLL |     while b.load(Ordering::Acquire) {}\n   |                                     ^^ help: try: `{ core::hint::spin_loop() }`\n   |\n   = note: `-D clippy::missing-spin-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_spin_loop)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/missing_trait_methods.rs",
    "content": "#![allow(unused, clippy::needless_lifetimes)]\n#![warn(clippy::missing_trait_methods)]\n\ntrait A {\n    fn provided() {}\n}\n\ntrait B {\n    fn required();\n\n    fn a(_: usize) -> usize {\n        1\n    }\n\n    fn b<'a, T: AsRef<[u8]>>(a: &'a T) -> &'a [u8] {\n        a.as_ref()\n    }\n}\n\nstruct Partial;\n\nimpl A for Partial {}\n//~^ missing_trait_methods\n\nimpl B for Partial {\n    //~^ missing_trait_methods\n\n    fn required() {}\n\n    fn a(_: usize) -> usize {\n        2\n    }\n}\n\nstruct Complete;\n\nimpl A for Complete {\n    fn provided() {}\n}\n\nimpl B for Complete {\n    fn required() {}\n\n    fn a(_: usize) -> usize {\n        2\n    }\n\n    fn b<T: AsRef<[u8]>>(a: &T) -> &[u8] {\n        a.as_ref()\n    }\n}\n\ntrait MissingMultiple {\n    fn one() {}\n    fn two() {}\n    fn three() {}\n}\n\nimpl MissingMultiple for Partial {}\n//~^ missing_trait_methods\n//~| missing_trait_methods\n//~| missing_trait_methods\n\nfn main() {}\n\n//~v missing_trait_methods\nimpl PartialEq<Partial> for Partial {\n    fn eq(&self, other: &Partial) -> bool {\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/missing_trait_methods.stderr",
    "content": "error: missing trait method provided by default: `provided`\n  --> tests/ui/missing_trait_methods.rs:22:1\n   |\nLL | impl A for Partial {}\n   | ^^^^^^^^^^^^^^^^^^\n   |\nhelp: implement the method\n  --> tests/ui/missing_trait_methods.rs:5:5\n   |\nLL |     fn provided() {}\n   |     ^^^^^^^^^^^^^\n   = note: `-D clippy::missing-trait-methods` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_trait_methods)]`\n\nerror: missing trait method provided by default: `b`\n  --> tests/ui/missing_trait_methods.rs:25:1\n   |\nLL | impl B for Partial {\n   | ^^^^^^^^^^^^^^^^^^\n   |\nhelp: implement the method\n  --> tests/ui/missing_trait_methods.rs:15:5\n   |\nLL |     fn b<'a, T: AsRef<[u8]>>(a: &'a T) -> &'a [u8] {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: missing trait method provided by default: `one`\n  --> tests/ui/missing_trait_methods.rs:59:1\n   |\nLL | impl MissingMultiple for Partial {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: implement the method\n  --> tests/ui/missing_trait_methods.rs:54:5\n   |\nLL |     fn one() {}\n   |     ^^^^^^^^\n\nerror: missing trait method provided by default: `two`\n  --> tests/ui/missing_trait_methods.rs:59:1\n   |\nLL | impl MissingMultiple for Partial {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: implement the method\n  --> tests/ui/missing_trait_methods.rs:55:5\n   |\nLL |     fn two() {}\n   |     ^^^^^^^^\n\nerror: missing trait method provided by default: `three`\n  --> tests/ui/missing_trait_methods.rs:59:1\n   |\nLL | impl MissingMultiple for Partial {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: implement the method\n  --> tests/ui/missing_trait_methods.rs:56:5\n   |\nLL |     fn three() {}\n   |     ^^^^^^^^^^\n\nerror: missing trait method provided by default: `ne`\n  --> tests/ui/missing_trait_methods.rs:67:1\n   |\nLL | impl PartialEq<Partial> for Partial {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: implement the missing `ne` method of the `PartialEq<Partial>` trait\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_transmute_annotations.fixed",
    "content": "//@aux-build:macro_rules.rs\n\n#![warn(clippy::missing_transmute_annotations)]\n#![allow(clippy::let_with_type_underscore)]\n\n#[macro_use]\nextern crate macro_rules;\n\nmacro_rules! local_bad_transmute {\n    ($e:expr) => {\n        std::mem::transmute::<[u16; 2], i32>($e)\n        //~^ ERROR: transmute used without annotations\n    };\n}\n\nfn bar(x: i32) -> i32 {\n    x\n}\n\nunsafe fn foo1() -> i32 {\n    unsafe {\n        // Should not warn!\n        std::mem::transmute([1u16, 2u16])\n    }\n}\n\n// Should not warn!\nconst _: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };\n\n#[repr(i32)]\nenum Foo {\n    A = 0,\n}\n\nunsafe fn foo2() -> i32 {\n    unsafe {\n        let mut i: i32 = 0;\n        i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n        i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n        i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n        i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n\n        let x: i32 = bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]));\n        //~^ ERROR: transmute used without annotations\n        bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]));\n        //~^ ERROR: transmute used without annotations\n\n        i = local_bad_transmute!([1u16, 2u16]);\n\n        // Should not warn.\n        i = bad_transmute!([1u16, 2u16]);\n\n        i = std::mem::transmute::<[i16; 2], i32>([0i16, 0i16]);\n        //~^ ERROR: transmute used without annotations\n\n        i = std::mem::transmute::<Foo, i32>(Foo::A);\n        //~^ ERROR: transmute used without annotations\n\n        i\n    }\n}\n\nfn main() {\n    let x: _ = unsafe { std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]) };\n    //~^ ERROR: transmute used without annotations\n    unsafe {\n        let x: _ = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n\n        // Should not warn.\n        std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        let x: i32 = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);\n        let x: i32 = std::mem::transmute::<_, i32>([1u16, 2u16]);\n        let x: i32 = std::mem::transmute([1u16, 2u16]);\n    }\n    let x: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };\n}\n"
  },
  {
    "path": "tests/ui/missing_transmute_annotations.rs",
    "content": "//@aux-build:macro_rules.rs\n\n#![warn(clippy::missing_transmute_annotations)]\n#![allow(clippy::let_with_type_underscore)]\n\n#[macro_use]\nextern crate macro_rules;\n\nmacro_rules! local_bad_transmute {\n    ($e:expr) => {\n        std::mem::transmute($e)\n        //~^ ERROR: transmute used without annotations\n    };\n}\n\nfn bar(x: i32) -> i32 {\n    x\n}\n\nunsafe fn foo1() -> i32 {\n    unsafe {\n        // Should not warn!\n        std::mem::transmute([1u16, 2u16])\n    }\n}\n\n// Should not warn!\nconst _: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };\n\n#[repr(i32)]\nenum Foo {\n    A = 0,\n}\n\nunsafe fn foo2() -> i32 {\n    unsafe {\n        let mut i: i32 = 0;\n        i = std::mem::transmute([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n        i = std::mem::transmute::<_, _>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n        i = std::mem::transmute::<_, i32>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n        i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n\n        let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));\n        //~^ ERROR: transmute used without annotations\n        bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));\n        //~^ ERROR: transmute used without annotations\n\n        i = local_bad_transmute!([1u16, 2u16]);\n\n        // Should not warn.\n        i = bad_transmute!([1u16, 2u16]);\n\n        i = std::mem::transmute([0i16, 0i16]);\n        //~^ ERROR: transmute used without annotations\n\n        i = std::mem::transmute(Foo::A);\n        //~^ ERROR: transmute used without annotations\n\n        i\n    }\n}\n\nfn main() {\n    let x: _ = unsafe { std::mem::transmute::<_, i32>([1u16, 2u16]) };\n    //~^ ERROR: transmute used without annotations\n    unsafe {\n        let x: _ = std::mem::transmute::<_, i32>([1u16, 2u16]);\n        //~^ ERROR: transmute used without annotations\n\n        // Should not warn.\n        std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);\n        let x: i32 = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);\n        let x: i32 = std::mem::transmute::<_, i32>([1u16, 2u16]);\n        let x: i32 = std::mem::transmute([1u16, 2u16]);\n    }\n    let x: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };\n}\n"
  },
  {
    "path": "tests/ui/missing_transmute_annotations.stderr",
    "content": "error: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:38:23\n   |\nLL |         i = std::mem::transmute([1u16, 2u16]);\n   |                       ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n   |\n   = note: `-D clippy::missing-transmute-annotations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:40:23\n   |\nLL |         i = std::mem::transmute::<_, _>([1u16, 2u16]);\n   |                       ^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:42:23\n   |\nLL |         i = std::mem::transmute::<_, i32>([1u16, 2u16]);\n   |                       ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:44:23\n   |\nLL |         i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:47:36\n   |\nLL |         let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:49:23\n   |\nLL |         bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:11:19\n   |\nLL |         std::mem::transmute($e)\n   |                   ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n...\nLL |         i = local_bad_transmute!([1u16, 2u16]);\n   |             ---------------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `local_bad_transmute` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:57:23\n   |\nLL |         i = std::mem::transmute([0i16, 0i16]);\n   |                       ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[i16; 2], i32>`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:60:23\n   |\nLL |         i = std::mem::transmute(Foo::A);\n   |                       ^^^^^^^^^ help: consider adding missing annotations: `transmute::<Foo, i32>`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:68:35\n   |\nLL |     let x: _ = unsafe { std::mem::transmute::<_, i32>([1u16, 2u16]) };\n   |                                   ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations.rs:71:30\n   |\nLL |         let x: _ = std::mem::transmute::<_, i32>([1u16, 2u16]);\n   |                              ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/missing_transmute_annotations_unfixable.rs",
    "content": "//@no-rustfix\n\nfn issue14984() {\n    async fn e() {}\n    async fn x() -> u32 {\n        0\n    }\n    async fn y() -> f32 {\n        0.0\n    };\n    let mut yy = unsafe { std::ptr::read(&y()) };\n    yy = unsafe { std::mem::transmute(std::ptr::read(&x())) };\n    //~^ missing_transmute_annotations\n\n    let mut zz = 0u8;\n    zz = unsafe { std::mem::transmute(std::ptr::read(&x())) };\n    //~^ missing_transmute_annotations\n\n    yy = unsafe { std::mem::transmute(zz) };\n    //~^ missing_transmute_annotations\n\n    fn a() -> impl Sized {\n        0u32\n    }\n\n    let mut b: f32 = 0.0;\n    b = unsafe { std::mem::transmute(a()) };\n    //~^ missing_transmute_annotations\n}\n"
  },
  {
    "path": "tests/ui/missing_transmute_annotations_unfixable.stderr",
    "content": "error: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations_unfixable.rs:12:29\n   |\nLL |     yy = unsafe { std::mem::transmute(std::ptr::read(&x())) };\n   |                             ^^^^^^^^^\n   |\n   = help: consider giving the source and destination types a name, and adding missing type annotations\n   = note: `-D clippy::missing-transmute-annotations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]`\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations_unfixable.rs:16:29\n   |\nLL |     zz = unsafe { std::mem::transmute(std::ptr::read(&x())) };\n   |                             ^^^^^^^^^\n   |\n   = help: consider giving the origin type a name, and adding missing type annotations\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations_unfixable.rs:19:29\n   |\nLL |     yy = unsafe { std::mem::transmute(zz) };\n   |                             ^^^^^^^^^\n   |\n   = help: consider giving the destination type a name, and adding missing type annotations\n\nerror: transmute used without annotations\n  --> tests/ui/missing_transmute_annotations_unfixable.rs:27:28\n   |\nLL |     b = unsafe { std::mem::transmute(a()) };\n   |                            ^^^^^^^^^\n   |\n   = help: consider giving `a()`'s type a name, and adding missing type annotations\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/mistyped_literal_suffix.fixed",
    "content": "//@aux-build: proc_macros.rs\n\n#![allow(\n    dead_code,\n    unused_variables,\n    overflowing_literals,\n    clippy::excessive_precision,\n    clippy::inconsistent_digit_grouping,\n    clippy::unusual_byte_groupings\n)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nfn main() {\n    let fail14 = 2_i32;\n    //~^ mistyped_literal_suffixes\n    let fail15 = 4_i64;\n    //~^ mistyped_literal_suffixes\n    let fail16 = 7_i8; //\n    //\n    //~^^ mistyped_literal_suffixes\n    let fail17 = 23_i16; //\n    //\n    //~^^ mistyped_literal_suffixes\n    let ok18 = 23_128;\n\n    let fail20 = 2_i8; //\n    //\n    //~^^ mistyped_literal_suffixes\n    let fail21 = 4_i16; //\n    //\n    //~^^ mistyped_literal_suffixes\n\n    let ok24 = 12.34_64;\n    let fail25 = 1E2_f32;\n    //~^ mistyped_literal_suffixes\n    let fail26 = 43E7_f64;\n    //~^ mistyped_literal_suffixes\n    let fail27 = 243E17_f32;\n    //~^ mistyped_literal_suffixes\n    let fail28 = 241_251_235E723_f64;\n    //~^ mistyped_literal_suffixes\n    let ok29 = 42279.911_32;\n\n    // testing that the suggestion actually fits in its type\n    let fail30 = 127_i8; // should be i8\n    //\n    //~^^ mistyped_literal_suffixes\n    let fail31 = 240_u8; // should be u8\n    //\n    //~^^ mistyped_literal_suffixes\n    let ok32 = 360_8; // doesn't fit in either, should be ignored\n    let fail33 = 0x1234_i16;\n    //~^ mistyped_literal_suffixes\n    let fail34 = 0xABCD_u16;\n    //~^ mistyped_literal_suffixes\n    let ok35 = 0x12345_16;\n    let fail36 = 0xFFFF_FFFF_FFFF_FFFF_u64; // u64\n    //\n    //~^^ mistyped_literal_suffixes\n\n    // issue #6129\n    let ok37 = 123_32.123;\n    let ok38 = 124_64.0;\n\n    let _ = 1.123_45E1_f32;\n    //~^ mistyped_literal_suffixes\n\n    let _ = with_span!(1 2_u32);\n}\n"
  },
  {
    "path": "tests/ui/mistyped_literal_suffix.rs",
    "content": "//@aux-build: proc_macros.rs\n\n#![allow(\n    dead_code,\n    unused_variables,\n    overflowing_literals,\n    clippy::excessive_precision,\n    clippy::inconsistent_digit_grouping,\n    clippy::unusual_byte_groupings\n)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nfn main() {\n    let fail14 = 2_32;\n    //~^ mistyped_literal_suffixes\n    let fail15 = 4_64;\n    //~^ mistyped_literal_suffixes\n    let fail16 = 7_8; //\n    //\n    //~^^ mistyped_literal_suffixes\n    let fail17 = 23_16; //\n    //\n    //~^^ mistyped_literal_suffixes\n    let ok18 = 23_128;\n\n    let fail20 = 2__8; //\n    //\n    //~^^ mistyped_literal_suffixes\n    let fail21 = 4___16; //\n    //\n    //~^^ mistyped_literal_suffixes\n\n    let ok24 = 12.34_64;\n    let fail25 = 1E2_32;\n    //~^ mistyped_literal_suffixes\n    let fail26 = 43E7_64;\n    //~^ mistyped_literal_suffixes\n    let fail27 = 243E17_32;\n    //~^ mistyped_literal_suffixes\n    let fail28 = 241251235E723_64;\n    //~^ mistyped_literal_suffixes\n    let ok29 = 42279.911_32;\n\n    // testing that the suggestion actually fits in its type\n    let fail30 = 127_8; // should be i8\n    //\n    //~^^ mistyped_literal_suffixes\n    let fail31 = 240_8; // should be u8\n    //\n    //~^^ mistyped_literal_suffixes\n    let ok32 = 360_8; // doesn't fit in either, should be ignored\n    let fail33 = 0x1234_16;\n    //~^ mistyped_literal_suffixes\n    let fail34 = 0xABCD_16;\n    //~^ mistyped_literal_suffixes\n    let ok35 = 0x12345_16;\n    let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64\n    //\n    //~^^ mistyped_literal_suffixes\n\n    // issue #6129\n    let ok37 = 123_32.123;\n    let ok38 = 124_64.0;\n\n    let _ = 1.12345E1_32;\n    //~^ mistyped_literal_suffixes\n\n    let _ = with_span!(1 2_u32);\n}\n"
  },
  {
    "path": "tests/ui/mistyped_literal_suffix.stderr",
    "content": "error: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:16:18\n   |\nLL |     let fail14 = 2_32;\n   |                  ^^^^ help: did you mean to write: `2_i32`\n   |\n   = note: `#[deny(clippy::mistyped_literal_suffixes)]` on by default\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:18:18\n   |\nLL |     let fail15 = 4_64;\n   |                  ^^^^ help: did you mean to write: `4_i64`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:20:18\n   |\nLL |     let fail16 = 7_8; //\n   |                  ^^^ help: did you mean to write: `7_i8`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:23:18\n   |\nLL |     let fail17 = 23_16; //\n   |                  ^^^^^ help: did you mean to write: `23_i16`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:28:18\n   |\nLL |     let fail20 = 2__8; //\n   |                  ^^^^ help: did you mean to write: `2_i8`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:31:18\n   |\nLL |     let fail21 = 4___16; //\n   |                  ^^^^^^ help: did you mean to write: `4_i16`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:36:18\n   |\nLL |     let fail25 = 1E2_32;\n   |                  ^^^^^^ help: did you mean to write: `1E2_f32`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:38:18\n   |\nLL |     let fail26 = 43E7_64;\n   |                  ^^^^^^^ help: did you mean to write: `43E7_f64`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:40:18\n   |\nLL |     let fail27 = 243E17_32;\n   |                  ^^^^^^^^^ help: did you mean to write: `243E17_f32`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:42:18\n   |\nLL |     let fail28 = 241251235E723_64;\n   |                  ^^^^^^^^^^^^^^^^ help: did you mean to write: `241_251_235E723_f64`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:47:18\n   |\nLL |     let fail30 = 127_8; // should be i8\n   |                  ^^^^^ help: did you mean to write: `127_i8`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:50:18\n   |\nLL |     let fail31 = 240_8; // should be u8\n   |                  ^^^^^ help: did you mean to write: `240_u8`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:54:18\n   |\nLL |     let fail33 = 0x1234_16;\n   |                  ^^^^^^^^^ help: did you mean to write: `0x1234_i16`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:56:18\n   |\nLL |     let fail34 = 0xABCD_16;\n   |                  ^^^^^^^^^ help: did you mean to write: `0xABCD_u16`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:59:18\n   |\nLL |     let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `0xFFFF_FFFF_FFFF_FFFF_u64`\n\nerror: mistyped literal suffix\n  --> tests/ui/mistyped_literal_suffix.rs:67:13\n   |\nLL |     let _ = 1.12345E1_32;\n   |             ^^^^^^^^^^^^ help: did you mean to write: `1.123_45E1_f32`\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/mixed_attributes_style/auxiliary/submodule.rs",
    "content": "//! Module level doc\n\n#![allow(dead_code)]\n\n#[allow(unused)]\nmod foo {\n    #![allow(dead_code)]\n}\n"
  },
  {
    "path": "tests/ui/mixed_attributes_style/global_allow.rs",
    "content": "// https://github.com/rust-lang/rust-clippy/issues/12436\n//@check-pass\n#![allow(clippy::mixed_attributes_style)]\n\n#[path = \"auxiliary/submodule.rs\"]\nmod submodule;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/mixed_attributes_style/mod_declaration.rs",
    "content": "//@error-in-other-file: item has both inner and outer attributes\n\n#[path = \"auxiliary/submodule.rs\"] // don't lint.\n/// This doc comment should not lint, it could be used to add context to the original module doc\nmod submodule;\n"
  },
  {
    "path": "tests/ui/mixed_attributes_style/mod_declaration.stderr",
    "content": "error: item has both inner and outer attributes\n  --> tests/ui/mixed_attributes_style/auxiliary/submodule.rs:5:1\n   |\nLL | / #[allow(unused)]\nLL | | mod foo {\nLL | |     #![allow(dead_code)]\n   | |________________________^\n   |\n   = note: `-D clippy::mixed-attributes-style` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mixed_attributes_style)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/mixed_attributes_style.rs",
    "content": "//@aux-build:proc_macro_attr.rs\n//@compile-flags: --test --cfg dummy_cfg\n#![feature(custom_inner_attributes)]\n#![warn(clippy::mixed_attributes_style)]\n#![allow(clippy::duplicated_attributes)]\n\n#[macro_use]\nextern crate proc_macro_attr;\n\n#[allow(unused)] //~ ERROR: item has both inner and outer attributes\nfn foo1() {\n    #![allow(unused)]\n}\n\n#[allow(unused)]\n#[allow(unused)]\nfn foo2() {}\n\nfn foo3() {\n    #![allow(unused)]\n    #![allow(unused)]\n}\n\n/// linux\n//~^ ERROR: item has both inner and outer attributes\nfn foo4() {\n    //! windows\n}\n\n/// linux\n/// windows\nfn foo5() {}\n\nfn foo6() {\n    //! linux\n    //! windows\n}\n\n#[allow(unused)] //~ ERROR: item has both inner and outer attributes\nmod bar {\n    #![allow(unused)]\n}\n\nfn main() {\n    // test code goes here\n}\n\n// issue #12435\n#[cfg(test)]\nmod tests {\n    //! Module doc, don't lint\n}\n#[allow(unused)]\nmod baz {\n    //! Module doc, don't lint\n    const FOO: u8 = 0;\n}\n/// Module doc, don't lint\nmod quz {\n    #![allow(unused)]\n}\n\nmod issue_12530 {\n    // don't lint different attributes entirely\n    #[cfg(test)]\n    mod tests {\n        #![allow(clippy::unreadable_literal)]\n\n        #[allow(dead_code)] //~ ERROR: item has both inner and outer attributes\n        mod inner_mod {\n            #![allow(dead_code)]\n        }\n    }\n    #[cfg(dummy_cfg)]\n    mod another_mod {\n        #![allow(clippy::question_mark)]\n    }\n    /// Nested mod\n    mod nested_mod {\n        #[allow(dead_code)] //~ ERROR: item has both inner and outer attributes\n        mod inner_mod {\n            #![allow(dead_code)]\n        }\n    }\n    /// Nested mod\n    //~^ ERROR: item has both inner and outer attributes\n    #[allow(unused)]\n    mod nest_mod_2 {\n        #![allow(unused)]\n\n        #[allow(dead_code)] //~ ERROR: item has both inner and outer attributes\n        mod inner_mod {\n            #![allow(dead_code)]\n        }\n    }\n    // Different path symbols - Known FN\n    #[dummy]\n    fn use_dummy() {\n        #![proc_macro_attr::dummy]\n    }\n}\n"
  },
  {
    "path": "tests/ui/mixed_attributes_style.stderr",
    "content": "error: item has both inner and outer attributes\n  --> tests/ui/mixed_attributes_style.rs:10:1\n   |\nLL | / #[allow(unused)]\nLL | | fn foo1() {\nLL | |     #![allow(unused)]\n   | |_____________________^\n   |\n   = note: `-D clippy::mixed-attributes-style` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mixed_attributes_style)]`\n\nerror: item has both inner and outer attributes\n  --> tests/ui/mixed_attributes_style.rs:24:1\n   |\nLL | / /// linux\nLL | |\nLL | | fn foo4() {\nLL | |     //! windows\n   | |_______________^\n\nerror: item has both inner and outer attributes\n  --> tests/ui/mixed_attributes_style.rs:39:1\n   |\nLL | / #[allow(unused)]\nLL | | mod bar {\nLL | |     #![allow(unused)]\n   | |_____________________^\n\nerror: item has both inner and outer attributes\n  --> tests/ui/mixed_attributes_style.rs:69:9\n   |\nLL | /         #[allow(dead_code)]\nLL | |         mod inner_mod {\nLL | |             #![allow(dead_code)]\n   | |________________________________^\n\nerror: item has both inner and outer attributes\n  --> tests/ui/mixed_attributes_style.rs:80:9\n   |\nLL | /         #[allow(dead_code)]\nLL | |         mod inner_mod {\nLL | |             #![allow(dead_code)]\n   | |________________________________^\n\nerror: item has both inner and outer attributes\n  --> tests/ui/mixed_attributes_style.rs:85:5\n   |\nLL | /     /// Nested mod\nLL | |\nLL | |     #[allow(unused)]\nLL | |     mod nest_mod_2 {\nLL | |         #![allow(unused)]\n   | |_________________________^\n\nerror: item has both inner and outer attributes\n  --> tests/ui/mixed_attributes_style.rs:91:9\n   |\nLL | /         #[allow(dead_code)]\nLL | |         mod inner_mod {\nLL | |             #![allow(dead_code)]\n   | |________________________________^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/mixed_read_write_in_expression.rs",
    "content": "#[warn(clippy::mixed_read_write_in_expression)]\n#[allow(\n    unused_assignments,\n    unused_variables,\n    clippy::no_effect,\n    dead_code,\n    clippy::disallowed_names\n)]\nfn main() {\n    let mut x = 0;\n    let a = {\n        x = 1;\n        1\n    } + x;\n    //~^ mixed_read_write_in_expression\n\n    // Example from iss#277\n    x += {\n        //~^ mixed_read_write_in_expression\n\n        x = 20;\n        2\n    };\n\n    // Does it work in weird places?\n    // ...in the base for a struct expression?\n    struct Foo {\n        a: i32,\n        b: i32,\n    };\n    let base = Foo { a: 4, b: 5 };\n    let foo = Foo {\n        a: x,\n        //~^ mixed_read_write_in_expression\n        ..{\n            x = 6;\n            base\n        }\n    };\n    // ...inside a closure?\n    let closure = || {\n        let mut x = 0;\n        x += {\n            //~^ mixed_read_write_in_expression\n\n            x = 20;\n            2\n        };\n    };\n    // ...not across a closure?\n    let mut y = 0;\n    let b = (y, || y = 1);\n\n    // && and || evaluate left-to-right.\n    let a = {\n        x = 1;\n        true\n    } && (x == 3);\n    let a = {\n        x = 1;\n        true\n    } || (x == 3);\n\n    // Make sure we don't get confused by alpha conversion.\n    let a = {\n        let mut x = 1;\n        x = 2;\n        1\n    } + x;\n\n    // No warning if we don't read the variable...\n    x = {\n        x = 20;\n        2\n    };\n    // ...if the assignment is in a closure...\n    let b = {\n        || {\n            x = 1;\n        };\n        1\n    } + x;\n    // ... or the access is under an address.\n    let b = (\n        {\n            let p = &x;\n            1\n        },\n        {\n            x = 1;\n            x\n        },\n    );\n\n    // Limitation: l-values other than simple variables don't trigger\n    // the warning.\n    let mut tup = (0, 0);\n    let c = {\n        tup.0 = 1;\n        1\n    } + tup.0;\n    // Limitation: you can get away with a read under address-of.\n    let mut z = 0;\n    let b = (\n        &{\n            z = x;\n            x\n        },\n        {\n            x = 3;\n            x\n        },\n    );\n}\n\nasync fn issue_6925() {\n    let _ = vec![async { true }.await, async { false }.await];\n}\n"
  },
  {
    "path": "tests/ui/mixed_read_write_in_expression.stderr",
    "content": "error: unsequenced read of `x`\n  --> tests/ui/mixed_read_write_in_expression.rs:14:9\n   |\nLL |     } + x;\n   |         ^\n   |\nnote: whether read occurs before this write depends on evaluation order\n  --> tests/ui/mixed_read_write_in_expression.rs:12:9\n   |\nLL |         x = 1;\n   |         ^^^^^\n   = note: `-D clippy::mixed-read-write-in-expression` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mixed_read_write_in_expression)]`\n\nerror: unsequenced read of `x`\n  --> tests/ui/mixed_read_write_in_expression.rs:18:5\n   |\nLL |     x += {\n   |     ^\n   |\nnote: whether read occurs before this write depends on evaluation order\n  --> tests/ui/mixed_read_write_in_expression.rs:21:9\n   |\nLL |         x = 20;\n   |         ^^^^^^\n\nerror: unsequenced read of `x`\n  --> tests/ui/mixed_read_write_in_expression.rs:33:12\n   |\nLL |         a: x,\n   |            ^\n   |\nnote: whether read occurs before this write depends on evaluation order\n  --> tests/ui/mixed_read_write_in_expression.rs:36:13\n   |\nLL |             x = 6;\n   |             ^^^^^\n\nerror: unsequenced read of `x`\n  --> tests/ui/mixed_read_write_in_expression.rs:43:9\n   |\nLL |         x += {\n   |         ^\n   |\nnote: whether read occurs before this write depends on evaluation order\n  --> tests/ui/mixed_read_write_in_expression.rs:46:13\n   |\nLL |             x = 20;\n   |             ^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/module_inception.rs",
    "content": "#![warn(clippy::module_inception)]\n\npub mod foo2 {\n    pub mod bar2 {\n        pub mod bar2 {\n            //~^ module_inception\n\n            pub mod foo2 {}\n        }\n        pub mod foo2 {}\n    }\n    pub mod foo2 {\n        //~^ module_inception\n\n        pub mod bar2 {}\n    }\n}\n\nmod foo {\n    mod bar {\n        mod bar {\n            //~^ module_inception\n\n            mod foo {}\n        }\n        mod foo {}\n    }\n    mod foo {\n        //~^ module_inception\n\n        mod bar {}\n    }\n}\n\n// No warning. See <https://github.com/rust-lang/rust-clippy/issues/1220>.\nmod bar {\n    #[allow(clippy::module_inception)]\n    mod bar {}\n}\n\nmod with_inner_impl {\n    struct S;\n    impl S {\n        fn f() {\n            mod with_inner_impl {}\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/module_inception.stderr",
    "content": "error: module has the same name as its containing module\n  --> tests/ui/module_inception.rs:5:9\n   |\nLL | /         pub mod bar2 {\nLL | |\nLL | |\nLL | |             pub mod foo2 {}\nLL | |         }\n   | |_________^\n   |\n   = note: `-D clippy::module-inception` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::module_inception)]`\n\nerror: module has the same name as its containing module\n  --> tests/ui/module_inception.rs:12:5\n   |\nLL | /     pub mod foo2 {\nLL | |\nLL | |\nLL | |         pub mod bar2 {}\nLL | |     }\n   | |_____^\n\nerror: module has the same name as its containing module\n  --> tests/ui/module_inception.rs:21:9\n   |\nLL | /         mod bar {\nLL | |\nLL | |\nLL | |             mod foo {}\nLL | |         }\n   | |_________^\n\nerror: module has the same name as its containing module\n  --> tests/ui/module_inception.rs:28:5\n   |\nLL | /     mod foo {\nLL | |\nLL | |\nLL | |         mod bar {}\nLL | |     }\n   | |_____^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/module_name_repetitions.rs",
    "content": "//@compile-flags: --test\n\n#![warn(clippy::module_name_repetitions)]\n#![allow(dead_code)]\n\npub mod foo {\n    pub fn foo() {}\n    pub fn foo_bar() {}\n    //~^ module_name_repetitions\n\n    pub fn bar_foo() {}\n    //~^ module_name_repetitions\n\n    pub struct FooCake;\n    //~^ module_name_repetitions\n\n    pub enum CakeFoo {}\n    //~^ module_name_repetitions\n\n    pub struct Foo7Bar;\n    //~^ module_name_repetitions\n\n    // Should not warn\n    pub struct Foobar;\n\n    // #8524 - shouldn't warn when item is declared in a private module...\n    mod error {\n        pub struct Error;\n        pub struct FooError;\n    }\n    pub use error::Error;\n    // ... but should still warn when the item is reexported to create a *public* path with repetition.\n    pub use error::FooError;\n    //~^ module_name_repetitions\n\n    // FIXME: This should also warn because it creates the public path `foo::FooIter`.\n    mod iter {\n        pub struct FooIter;\n    }\n    pub use iter::*;\n\n    // #12544 - shouldn't warn if item name consists only of an allowed prefix and a module name.\n    pub fn to_foo() {}\n    pub fn into_foo() {}\n    pub fn as_foo() {}\n    pub fn from_foo() {}\n    pub fn try_into_foo() {}\n    pub fn try_from_foo() {}\n    pub trait IntoFoo {}\n    pub trait ToFoo {}\n    pub trait AsFoo {}\n    pub trait FromFoo {}\n    pub trait TryIntoFoo {}\n    pub trait TryFromFoo {}\n}\n\nfn main() {}\n\npub mod issue14095 {\n    pub mod widget {\n        #[macro_export]\n        macro_rules! define_widget {\n            ($id:ident) => {\n                /* ... */\n            };\n        }\n\n        #[macro_export]\n        macro_rules! widget_impl {\n            ($id:ident) => {\n                /* ... */\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/module_name_repetitions.stderr",
    "content": "error: item name starts with its containing module's name\n  --> tests/ui/module_name_repetitions.rs:8:12\n   |\nLL |     pub fn foo_bar() {}\n   |            ^^^^^^^\n   |\n   = note: `-D clippy::module-name-repetitions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]`\n\nerror: item name ends with its containing module's name\n  --> tests/ui/module_name_repetitions.rs:11:12\n   |\nLL |     pub fn bar_foo() {}\n   |            ^^^^^^^\n\nerror: item name starts with its containing module's name\n  --> tests/ui/module_name_repetitions.rs:14:16\n   |\nLL |     pub struct FooCake;\n   |                ^^^^^^^\n\nerror: item name ends with its containing module's name\n  --> tests/ui/module_name_repetitions.rs:17:14\n   |\nLL |     pub enum CakeFoo {}\n   |              ^^^^^^^\n\nerror: item name starts with its containing module's name\n  --> tests/ui/module_name_repetitions.rs:20:16\n   |\nLL |     pub struct Foo7Bar;\n   |                ^^^^^^^\n\nerror: item name starts with its containing module's name\n  --> tests/ui/module_name_repetitions.rs:33:20\n   |\nLL |     pub use error::FooError;\n   |                    ^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/modulo_arithmetic_float.rs",
    "content": "#![feature(f128)]\n#![feature(f16)]\n#![warn(clippy::modulo_arithmetic)]\n#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)]\n\nfn main() {\n    // Lint when both sides are const and of the opposite sign\n    -1.6 % 2.1;\n    //~^ modulo_arithmetic\n\n    1.6 % -2.1;\n    //~^ modulo_arithmetic\n\n    (1.1 - 2.3) % (1.1 + 2.3);\n    //~^ modulo_arithmetic\n\n    (1.1 + 2.3) % (1.1 - 2.3);\n    //~^ modulo_arithmetic\n\n    // Lint on floating point numbers\n    let a_f16: f16 = -1.6;\n    let mut b_f16: f16 = 2.1;\n    a_f16 % b_f16;\n    //~^ modulo_arithmetic\n\n    b_f16 % a_f16;\n    //~^ modulo_arithmetic\n\n    b_f16 %= a_f16;\n    //~^ modulo_arithmetic\n\n    // Lint on floating point numbers\n    let a_f32: f32 = -1.6;\n    let mut b_f32: f32 = 2.1;\n    a_f32 % b_f32;\n    //~^ modulo_arithmetic\n\n    b_f32 % a_f32;\n    //~^ modulo_arithmetic\n\n    b_f32 %= a_f32;\n    //~^ modulo_arithmetic\n\n    let a_f64: f64 = -1.6;\n    let mut b_f64: f64 = 2.1;\n    a_f64 % b_f64;\n    //~^ modulo_arithmetic\n\n    b_f64 % a_f64;\n    //~^ modulo_arithmetic\n\n    b_f64 %= a_f64;\n    //~^ modulo_arithmetic\n\n    let a_f128: f128 = -1.6;\n    let mut b_f128: f128 = 2.1;\n    a_f128 % b_f128;\n    //~^ modulo_arithmetic\n\n    b_f128 % a_f128;\n    //~^ modulo_arithmetic\n\n    b_f128 %= a_f128;\n    //~^ modulo_arithmetic\n\n    // No lint when both sides are const and of the same sign\n    1.6 % 2.1;\n    -1.6 % -2.1;\n    (1.1 + 2.3) % (-1.1 + 2.3);\n    (-1.1 - 2.3) % (1.1 - 2.3);\n}\n"
  },
  {
    "path": "tests/ui/modulo_arithmetic_float.stderr",
    "content": "error: you are using modulo operator on constants with different signs: `-1.600 % 2.100`\n  --> tests/ui/modulo_arithmetic_float.rs:8:5\n   |\nLL |     -1.6 % 2.1;\n   |     ^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`\n\nerror: you are using modulo operator on constants with different signs: `1.600 % -2.100`\n  --> tests/ui/modulo_arithmetic_float.rs:11:5\n   |\nLL |     1.6 % -2.1;\n   |     ^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on constants with different signs: `-1.200 % 3.400`\n  --> tests/ui/modulo_arithmetic_float.rs:14:5\n   |\nLL |     (1.1 - 2.3) % (1.1 + 2.3);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on constants with different signs: `3.400 % -1.200`\n  --> tests/ui/modulo_arithmetic_float.rs:17:5\n   |\nLL |     (1.1 + 2.3) % (1.1 - 2.3);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:23:5\n   |\nLL |     a_f16 % b_f16;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:26:5\n   |\nLL |     b_f16 % a_f16;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:29:5\n   |\nLL |     b_f16 %= a_f16;\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:35:5\n   |\nLL |     a_f32 % b_f32;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:38:5\n   |\nLL |     b_f32 % a_f32;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:41:5\n   |\nLL |     b_f32 %= a_f32;\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:46:5\n   |\nLL |     a_f64 % b_f64;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:49:5\n   |\nLL |     b_f64 % a_f64;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:52:5\n   |\nLL |     b_f64 %= a_f64;\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:57:5\n   |\nLL |     a_f128 % b_f128;\n   |     ^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:60:5\n   |\nLL |     b_f128 % a_f128;\n   |     ^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_float.rs:63:5\n   |\nLL |     b_f128 %= a_f128;\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/modulo_arithmetic_integral.rs",
    "content": "#![warn(clippy::modulo_arithmetic)]\n#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)]\n\nfn main() {\n    // Lint on signed integral numbers\n    let a = -1;\n    let mut b = 2;\n    a % b;\n    //~^ modulo_arithmetic\n\n    b % a;\n    //~^ modulo_arithmetic\n\n    b %= a;\n    //~^ modulo_arithmetic\n\n    let a_i8: i8 = 1;\n    let mut b_i8: i8 = 2;\n    a_i8 % b_i8;\n    //~^ modulo_arithmetic\n\n    b_i8 %= a_i8;\n    //~^ modulo_arithmetic\n\n    let a_i16: i16 = 1;\n    let mut b_i16: i16 = 2;\n    a_i16 % b_i16;\n    //~^ modulo_arithmetic\n\n    b_i16 %= a_i16;\n    //~^ modulo_arithmetic\n\n    let a_i32: i32 = 1;\n    let mut b_i32: i32 = 2;\n    a_i32 % b_i32;\n    //~^ modulo_arithmetic\n\n    b_i32 %= a_i32;\n    //~^ modulo_arithmetic\n\n    let a_i64: i64 = 1;\n    let mut b_i64: i64 = 2;\n    a_i64 % b_i64;\n    //~^ modulo_arithmetic\n\n    b_i64 %= a_i64;\n    //~^ modulo_arithmetic\n\n    let a_i128: i128 = 1;\n    let mut b_i128: i128 = 2;\n    a_i128 % b_i128;\n    //~^ modulo_arithmetic\n\n    b_i128 %= a_i128;\n    //~^ modulo_arithmetic\n\n    let a_isize: isize = 1;\n    let mut b_isize: isize = 2;\n    a_isize % b_isize;\n    //~^ modulo_arithmetic\n\n    b_isize %= a_isize;\n    //~^ modulo_arithmetic\n\n    let a = 1;\n    let mut b = 2;\n    a % b;\n    //~^ modulo_arithmetic\n\n    b %= a;\n    //~^ modulo_arithmetic\n\n    // No lint on unsigned integral value\n    let a_u8: u8 = 17;\n    let b_u8: u8 = 3;\n    a_u8 % b_u8;\n    let mut a_u8: u8 = 1;\n    a_u8 %= 2;\n\n    let a_u16: u16 = 17;\n    let b_u16: u16 = 3;\n    a_u16 % b_u16;\n    let mut a_u16: u16 = 1;\n    a_u16 %= 2;\n\n    let a_u32: u32 = 17;\n    let b_u32: u32 = 3;\n    a_u32 % b_u32;\n    let mut a_u32: u32 = 1;\n    a_u32 %= 2;\n\n    let a_u64: u64 = 17;\n    let b_u64: u64 = 3;\n    a_u64 % b_u64;\n    let mut a_u64: u64 = 1;\n    a_u64 %= 2;\n\n    let a_u128: u128 = 17;\n    let b_u128: u128 = 3;\n    a_u128 % b_u128;\n    let mut a_u128: u128 = 1;\n    a_u128 %= 2;\n\n    let a_usize: usize = 17;\n    let b_usize: usize = 3;\n    a_usize % b_usize;\n    let mut a_usize: usize = 1;\n    a_usize %= 2;\n\n    // No lint when comparing to zero\n    let a = -1;\n    let mut b = 2;\n    let c = a % b == 0;\n    let c = 0 == a % b;\n    let c = a % b != 0;\n    let c = 0 != a % b;\n}\n"
  },
  {
    "path": "tests/ui/modulo_arithmetic_integral.stderr",
    "content": "error: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:8:5\n   |\nLL |     a % b;\n   |     ^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:11:5\n   |\nLL |     b % a;\n   |     ^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:14:5\n   |\nLL |     b %= a;\n   |     ^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:19:5\n   |\nLL |     a_i8 % b_i8;\n   |     ^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:22:5\n   |\nLL |     b_i8 %= a_i8;\n   |     ^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:27:5\n   |\nLL |     a_i16 % b_i16;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:30:5\n   |\nLL |     b_i16 %= a_i16;\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:35:5\n   |\nLL |     a_i32 % b_i32;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:38:5\n   |\nLL |     b_i32 %= a_i32;\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:43:5\n   |\nLL |     a_i64 % b_i64;\n   |     ^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:46:5\n   |\nLL |     b_i64 %= a_i64;\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:51:5\n   |\nLL |     a_i128 % b_i128;\n   |     ^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:54:5\n   |\nLL |     b_i128 %= a_i128;\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:59:5\n   |\nLL |     a_isize % b_isize;\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:62:5\n   |\nLL |     b_isize %= a_isize;\n   |     ^^^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:67:5\n   |\nLL |     a % b;\n   |     ^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui/modulo_arithmetic_integral.rs:70:5\n   |\nLL |     b %= a;\n   |     ^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/modulo_arithmetic_integral_const.rs",
    "content": "#![warn(clippy::modulo_arithmetic)]\n#![allow(\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::modulo_one,\n    clippy::identity_op\n)]\n\nfn main() {\n    // Lint when both sides are const and of the opposite sign\n    -1 % 2;\n    //~^ modulo_arithmetic\n\n    1 % -2;\n    //~^ modulo_arithmetic\n\n    (1 - 2) % (1 + 2);\n    //~^ modulo_arithmetic\n\n    (1 + 2) % (1 - 2);\n    //~^ modulo_arithmetic\n\n    35 * (7 - 4 * 2) % (-500 * -600);\n    //~^ modulo_arithmetic\n\n    -1i8 % 2i8;\n    //~^ modulo_arithmetic\n\n    1i8 % -2i8;\n    //~^ modulo_arithmetic\n\n    -1i16 % 2i16;\n    //~^ modulo_arithmetic\n\n    1i16 % -2i16;\n    //~^ modulo_arithmetic\n\n    -1i32 % 2i32;\n    //~^ modulo_arithmetic\n\n    1i32 % -2i32;\n    //~^ modulo_arithmetic\n\n    -1i64 % 2i64;\n    //~^ modulo_arithmetic\n\n    1i64 % -2i64;\n    //~^ modulo_arithmetic\n\n    -1i128 % 2i128;\n    //~^ modulo_arithmetic\n\n    1i128 % -2i128;\n    //~^ modulo_arithmetic\n\n    -1isize % 2isize;\n    //~^ modulo_arithmetic\n\n    1isize % -2isize;\n    //~^ modulo_arithmetic\n\n    // No lint when both sides are const and of the same sign\n    1 % 2;\n    -1 % -2;\n    (1 + 2) % (-1 + 2);\n    (-1 - 2) % (1 - 2);\n\n    1u8 % 2u8;\n    1u16 % 2u16;\n    1u32 % 2u32;\n    1u64 % 2u64;\n    1u128 % 2u128;\n    1usize % 2usize;\n}\n"
  },
  {
    "path": "tests/ui/modulo_arithmetic_integral_const.stderr",
    "content": "error: you are using modulo operator on constants with different signs: `-1 % 2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:11:5\n   |\nLL |     -1 % 2;\n   |     ^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`\n\nerror: you are using modulo operator on constants with different signs: `1 % -2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:14:5\n   |\nLL |     1 % -2;\n   |     ^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `-1 % 3`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:17:5\n   |\nLL |     (1 - 2) % (1 + 2);\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `3 % -1`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:20:5\n   |\nLL |     (1 + 2) % (1 - 2);\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `-35 % 300000`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:23:5\n   |\nLL |     35 * (7 - 4 * 2) % (-500 * -600);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `-1 % 2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:26:5\n   |\nLL |     -1i8 % 2i8;\n   |     ^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `1 % -2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:29:5\n   |\nLL |     1i8 % -2i8;\n   |     ^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `-1 % 2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:32:5\n   |\nLL |     -1i16 % 2i16;\n   |     ^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `1 % -2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:35:5\n   |\nLL |     1i16 % -2i16;\n   |     ^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `-1 % 2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:38:5\n   |\nLL |     -1i32 % 2i32;\n   |     ^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `1 % -2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:41:5\n   |\nLL |     1i32 % -2i32;\n   |     ^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `-1 % 2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:44:5\n   |\nLL |     -1i64 % 2i64;\n   |     ^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `1 % -2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:47:5\n   |\nLL |     1i64 % -2i64;\n   |     ^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `-1 % 2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:50:5\n   |\nLL |     -1i128 % 2i128;\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `1 % -2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:53:5\n   |\nLL |     1i128 % -2i128;\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `-1 % 2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:56:5\n   |\nLL |     -1isize % 2isize;\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on constants with different signs: `1 % -2`\n  --> tests/ui/modulo_arithmetic_integral_const.rs:59:5\n   |\nLL |     1isize % -2isize;\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/modulo_one.rs",
    "content": "#![warn(clippy::modulo_one)]\n#![allow(unconditional_panic)]\n#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::identity_op)]\n\nstatic STATIC_ONE: usize = 2 - 1;\nstatic STATIC_NEG_ONE: i64 = 1 - 2;\n\nfn main() {\n    10 % 1;\n    //~^ modulo_one\n\n    10 % -1;\n    //~^ modulo_one\n\n    10 % 2;\n    // also caught by rustc\n    i32::MIN % (-1);\n    //~^ modulo_one\n\n    const ONE: u32 = 1 * 1;\n    const NEG_ONE: i64 = 1 - 2;\n    const INT_MIN: i64 = i64::MIN;\n\n    2 % ONE;\n    //~^ modulo_one\n\n    // NOT caught by lint\n    5 % STATIC_ONE;\n    2 % NEG_ONE;\n    //~^ modulo_one\n\n    // NOT caught by lint\n    5 % STATIC_NEG_ONE;\n    // also caught by rustc\n    INT_MIN % NEG_ONE;\n    //~^ modulo_one\n\n    // Not caught by lint, we don't look into static items, even if entirely immutable.\n    INT_MIN % STATIC_NEG_ONE;\n}\n"
  },
  {
    "path": "tests/ui/modulo_one.stderr",
    "content": "error: any number modulo 1 will be 0\n  --> tests/ui/modulo_one.rs:9:5\n   |\nLL |     10 % 1;\n   |     ^^^^^^\n   |\n   = note: `-D clippy::modulo-one` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::modulo_one)]`\n\nerror: any number modulo -1 will panic/overflow or result in 0\n  --> tests/ui/modulo_one.rs:12:5\n   |\nLL |     10 % -1;\n   |     ^^^^^^^\n\nerror: any number modulo -1 will panic/overflow or result in 0\n  --> tests/ui/modulo_one.rs:17:5\n   |\nLL |     i32::MIN % (-1);\n   |     ^^^^^^^^^^^^^^^\n\nerror: any number modulo 1 will be 0\n  --> tests/ui/modulo_one.rs:24:5\n   |\nLL |     2 % ONE;\n   |     ^^^^^^^\n\nerror: any number modulo -1 will panic/overflow or result in 0\n  --> tests/ui/modulo_one.rs:29:5\n   |\nLL |     2 % NEG_ONE;\n   |     ^^^^^^^^^^^\n\nerror: any number modulo -1 will panic/overflow or result in 0\n  --> tests/ui/modulo_one.rs:35:5\n   |\nLL |     INT_MIN % NEG_ONE;\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/msrv_attributes_without_early_lints.rs",
    "content": "//@check-pass\n\n#![allow(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)]\n#![forbid(clippy::ptr_as_ptr)]\n\n/// MSRV checking in late passes skips checking the parent nodes if no early pass sees a\n/// `#[clippy::msrv]` attribute\n///\n/// Here we ensure that even if all early passes are allowed (above) the attribute is still detected\n/// in late lints such as `clippy::ptr_as_ptr`\n#[clippy::msrv = \"1.37\"]\nfn f(p: *const i32) {\n    let _ = p as *const i64;\n}\n"
  },
  {
    "path": "tests/ui/multi_assignments.rs",
    "content": "#![warn(clippy::multi_assignments)]\nfn main() {\n    let (mut a, mut b, mut c, mut d) = ((), (), (), ());\n    a = b = c;\n    //~^ multi_assignments\n\n    a = b = c = d;\n    //~^ multi_assignments\n    //~| multi_assignments\n\n    a = b = { c };\n    //~^ multi_assignments\n\n    a = { b = c };\n    //~^ multi_assignments\n\n    a = (b = c);\n    //~^ multi_assignments\n}\n"
  },
  {
    "path": "tests/ui/multi_assignments.stderr",
    "content": "error: assignments don't nest intuitively\n  --> tests/ui/multi_assignments.rs:4:5\n   |\nLL |     a = b = c;\n   |     ^^^^^^^^^\n   |\n   = note: `-D clippy::multi-assignments` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::multi_assignments)]`\n\nerror: assignments don't nest intuitively\n  --> tests/ui/multi_assignments.rs:7:5\n   |\nLL |     a = b = c = d;\n   |     ^^^^^^^^^^^^^\n\nerror: assignments don't nest intuitively\n  --> tests/ui/multi_assignments.rs:7:9\n   |\nLL |     a = b = c = d;\n   |         ^^^^^^^^^\n\nerror: assignments don't nest intuitively\n  --> tests/ui/multi_assignments.rs:11:5\n   |\nLL |     a = b = { c };\n   |     ^^^^^^^^^^^^^\n\nerror: assignments don't nest intuitively\n  --> tests/ui/multi_assignments.rs:14:5\n   |\nLL |     a = { b = c };\n   |     ^^^^^^^^^^^^^\n\nerror: assignments don't nest intuitively\n  --> tests/ui/multi_assignments.rs:17:5\n   |\nLL |     a = (b = c);\n   |     ^^^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/multiple_bound_locations.rs",
    "content": "#![warn(clippy::multiple_bound_locations)]\n\nfn ty<F: std::fmt::Debug>(a: F)\n//~^ multiple_bound_locations\nwhere\n    F: Sized,\n{\n}\n\nfn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str)\n//~^ multiple_bound_locations\nwhere\n    'b: 'c,\n{\n}\n\nfn ty_pred<F: Sized>()\n//~^ multiple_bound_locations\nwhere\n    for<'a> F: Send + 'a,\n{\n}\n\nstruct B;\n\nimpl B {\n    fn ty<F: std::fmt::Debug>(a: F)\n    //~^ multiple_bound_locations\n    where\n        F: Sized,\n    {\n    }\n\n    fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str)\n    //~^ multiple_bound_locations\n    where\n        'b: 'c,\n    {\n    }\n\n    fn ty_pred<F: Sized>()\n    //~^ multiple_bound_locations\n    where\n        for<'a> F: Send + 'a,\n    {\n    }\n}\n\nstruct C<F>(F);\n\nimpl<F> C<F> {\n    fn foo(_f: F) -> Self\n    where\n        F: std::fmt::Display,\n    {\n        todo!()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/multiple_bound_locations.stderr",
    "content": "error: bound is defined in more than one place\n  --> tests/ui/multiple_bound_locations.rs:3:7\n   |\nLL | fn ty<F: std::fmt::Debug>(a: F)\n   |       ^\n...\nLL |     F: Sized,\n   |     ^\n   |\n   = note: `-D clippy::multiple-bound-locations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::multiple_bound_locations)]`\n\nerror: bound is defined in more than one place\n  --> tests/ui/multiple_bound_locations.rs:10:17\n   |\nLL | fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str)\n   |                 ^^\n...\nLL |     'b: 'c,\n   |     ^^\n\nerror: bound is defined in more than one place\n  --> tests/ui/multiple_bound_locations.rs:17:12\n   |\nLL | fn ty_pred<F: Sized>()\n   |            ^\n...\nLL |     for<'a> F: Send + 'a,\n   |             ^\n\nerror: bound is defined in more than one place\n  --> tests/ui/multiple_bound_locations.rs:27:11\n   |\nLL |     fn ty<F: std::fmt::Debug>(a: F)\n   |           ^\n...\nLL |         F: Sized,\n   |         ^\n\nerror: bound is defined in more than one place\n  --> tests/ui/multiple_bound_locations.rs:34:21\n   |\nLL |     fn lifetime<'a, 'b: 'a, 'c>(a: &'b str, b: &'a str, c: &'c str)\n   |                     ^^\n...\nLL |         'b: 'c,\n   |         ^^\n\nerror: bound is defined in more than one place\n  --> tests/ui/multiple_bound_locations.rs:41:16\n   |\nLL |     fn ty_pred<F: Sized>()\n   |                ^\n...\nLL |         for<'a> F: Send + 'a,\n   |                 ^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/multiple_inherent_impl_cfg.normal.stderr",
    "content": "error: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:11:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:10:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\nnote: the lint level is defined here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:3:9\n   |\nLL | #![deny(clippy::multiple_inherent_impl)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:25:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:21:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/multiple_inherent_impl_cfg.rs",
    "content": "//@compile-flags: --cfg test\n#![deny(clippy::multiple_inherent_impl)]\n\n// issue #13040\n\nfn main() {}\n\nstruct A;\n\nimpl A {}\n\nimpl A {}\n//~^ multiple_inherent_impl\n\n#[cfg(test)]\nimpl A {}\n\n#[cfg(test)]\nimpl A {}\n//~^ multiple_inherent_impl\n\nstruct B;\n\nimpl B {}\n\n#[cfg(test)]\nimpl B {}\n\nimpl B {}\n//~^ multiple_inherent_impl\n\n#[cfg(test)]\nimpl B {}\n//~^ multiple_inherent_impl\n\n#[cfg(test)]\nstruct C;\n\n#[cfg(test)]\nimpl C {}\n\n#[cfg(test)]\nimpl C {}\n//~^ multiple_inherent_impl\n"
  },
  {
    "path": "tests/ui/multiple_inherent_impl_cfg.stderr",
    "content": "error: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:12:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:10:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\nnote: the lint level is defined here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:2:9\n   |\nLL | #![deny(clippy::multiple_inherent_impl)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:19:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:16:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:29:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:24:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:33:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:27:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:43:1\n   |\nLL | impl C {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:40:1\n   |\nLL | impl C {}\n   | ^^^^^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/multiple_inherent_impl_cfg.withtest.stderr",
    "content": "error: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:11:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:10:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\nnote: the lint level is defined here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:3:9\n   |\nLL | #![deny(clippy::multiple_inherent_impl)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:14:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:10:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:17:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:10:1\n   |\nLL | impl A {}\n   | ^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:23:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:21:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:25:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:21:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:28:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:21:1\n   |\nLL | impl B {}\n   | ^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> tests/ui/multiple_inherent_impl_cfg.rs:36:1\n   |\nLL | impl C {}\n   | ^^^^^^^^^\n   |\nnote: first implementation here\n  --> tests/ui/multiple_inherent_impl_cfg.rs:34:1\n   |\nLL | impl C {}\n   | ^^^^^^^^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/multiple_unsafe_ops_per_block.rs",
    "content": "//@needs-asm-support\n//@aux-build:proc_macros.rs\n#![expect(\n    dropping_copy_types,\n    clippy::unnecessary_operation,\n    clippy::unnecessary_literal_unwrap\n)]\n#![warn(clippy::multiple_unsafe_ops_per_block)]\n\nextern crate proc_macros;\nuse proc_macros::external;\n\nuse core::arch::asm;\n\nfn raw_ptr() -> *const () {\n    core::ptr::null()\n}\n\nunsafe fn not_very_safe() {}\n\nstruct Sample;\n\nimpl Sample {\n    unsafe fn not_very_safe(&self) {}\n}\n\n#[allow(non_upper_case_globals)]\nconst sample: Sample = Sample;\n\nunion U {\n    i: i32,\n    u: u32,\n}\n\nstatic mut STATIC: i32 = 0;\n\nfn test1() {\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        STATIC += 1;\n        not_very_safe();\n    }\n}\n\nfn test2() {\n    let u = U { i: 0 };\n\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        drop(u.u);\n        *raw_ptr();\n    }\n}\n\nfn test3() {\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        asm!(\"nop\");\n        sample.not_very_safe();\n        STATIC = 0;\n    }\n}\n\nfn test_all() {\n    let u = U { i: 0 };\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        drop(u.u);\n        drop(STATIC);\n        sample.not_very_safe();\n        not_very_safe();\n        *raw_ptr();\n        asm!(\"nop\");\n    }\n}\n\n// no lint\nfn correct1() {\n    unsafe {\n        STATIC += 1;\n    }\n}\n\n// no lint\nfn correct2() {\n    unsafe {\n        STATIC += 1;\n    }\n\n    unsafe {\n        *raw_ptr();\n    }\n}\n\n// no lint\nfn correct3() {\n    let u = U { u: 0 };\n\n    unsafe {\n        not_very_safe();\n    }\n\n    unsafe {\n        drop(u.i);\n    }\n}\n\nfn with_adjustment(f: &unsafe fn()) {\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        f();\n        f();\n    }\n}\n\nfn issue10064() {\n    unsafe fn read_char_bad(ptr: *const u8) -> char {\n        unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }\n        //~^ multiple_unsafe_ops_per_block\n    }\n\n    // no lint\n    unsafe fn read_char_good(ptr: *const u8) -> char {\n        let int_value = unsafe { *ptr.cast::<u32>() };\n        unsafe { core::char::from_u32_unchecked(int_value) }\n    }\n}\n\n// no lint\nfn issue10259() {\n    external!(unsafe {\n        *core::ptr::null::<()>();\n        *core::ptr::null::<()>();\n    });\n}\n\nfn issue10367() {\n    fn fn_ptr(x: unsafe fn()) {\n        unsafe {\n            //~^ multiple_unsafe_ops_per_block\n            x();\n            x();\n        }\n    }\n\n    fn assoc_const() {\n        trait X {\n            const X: unsafe fn();\n        }\n        fn _f<T: X>() {\n            unsafe {\n                //~^ multiple_unsafe_ops_per_block\n                T::X();\n                T::X();\n            }\n        }\n    }\n\n    fn field_fn_ptr(x: unsafe fn()) {\n        struct X(unsafe fn());\n        let x = X(x);\n        unsafe {\n            //~^ multiple_unsafe_ops_per_block\n            x.0();\n            x.0();\n        }\n    }\n}\n\n// await expands to an unsafe block with several operations, but this is fine.\nasync fn issue11312() {\n    async fn helper() {}\n\n    helper().await;\n}\n\nasync fn issue13879() {\n    async fn foo() {}\n\n    // no lint: nothing unsafe beyond the `await` which we ignore\n    unsafe {\n        foo().await;\n    }\n\n    // no lint: only one unsafe call beyond the `await`\n    unsafe {\n        not_very_safe();\n        foo().await;\n    }\n\n    // lint: two unsafe calls beyond the `await`\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        not_very_safe();\n        STATIC += 1;\n        foo().await;\n    }\n\n    async unsafe fn foo_unchecked() {}\n\n    // no lint: only one unsafe call in the `await`ed expr\n    unsafe {\n        foo_unchecked().await;\n    }\n\n    // lint: one unsafe call in the `await`ed expr, and one outside\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        not_very_safe();\n        foo_unchecked().await;\n    }\n\n    // lint: two unsafe calls in the `await`ed expr\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        Some(foo_unchecked()).unwrap_unchecked().await;\n    }\n}\n\nfn issue16076() {\n    #[derive(Clone, Copy)]\n    union U {\n        i: u32,\n        f: f32,\n    }\n\n    let u = U { i: 0 };\n\n    // Taking a raw pointer to a place is safe since Rust 1.92\n    unsafe {\n        _ = &raw const u.i;\n        _ = &raw const u.i;\n    }\n\n    // Taking a reference to a union field is not safe\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        _ = &u.i;\n        _ = &u.i;\n    }\n\n    // Check that we still check and lint the prefix of the raw pointer to a field access\n    #[expect(clippy::deref_addrof)]\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        _ = &raw const (*&raw const u).i;\n        _ = &raw const (*&raw const u).i;\n    }\n\n    union V {\n        u: U,\n    }\n\n    // Taking a raw pointer to a union field of an union field (etc.) is safe\n    let v = V { u };\n    unsafe {\n        _ = &raw const v.u.i;\n        _ = &raw const v.u.i;\n    }\n\n    // Check that unions in structs work properly as well\n    struct T {\n        u: U,\n    }\n    let t = T { u };\n    unsafe {\n        _ = &raw const t.u.i;\n        _ = &raw const t.u.i;\n    }\n\n    // As well as structs in unions\n    #[derive(Clone, Copy)]\n    struct X {\n        i: i32,\n    }\n    union Z {\n        x: X,\n    }\n    let z = Z { x: X { i: 0 } };\n    unsafe {\n        _ = &raw const z.x.i;\n        _ = &raw const z.x.i;\n    }\n\n    // If a field needs to be adjusted then it is accessed\n    struct S {\n        i: i32,\n    }\n    union W<'a> {\n        s: &'a S,\n    }\n    let s = S { i: 0 };\n    let w = W { s: &s };\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        _ = &raw const w.s.i;\n        _ = &raw const w.s.i;\n    }\n}\n\nfn check_closures() {\n    unsafe fn apply(f: impl Fn()) {\n        todo!()\n    }\n    unsafe fn f(_x: i32) {\n        todo!()\n    }\n\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        apply(|| f(0));\n    }\n}\n\nfn issue16116() {\n    unsafe fn foo() -> u32 {\n        0\n    }\n\n    // Do not lint even though `format!` expansion\n    // contains unsafe calls.\n    unsafe {\n        let _ = format!(\"{}\", foo());\n    }\n\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        let _ = format!(\"{}\", foo());\n        let _ = format!(\"{}\", foo());\n    }\n\n    // Do not lint: only one `assert!()` argument is unsafe\n    unsafe {\n        assert_eq!(foo(), 0, \"{}\", 1 + 2);\n    }\n\n    // Each argument of a macro call may count as an unsafe operation.\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        assert_eq!(foo(), 0, \"{}\", foo()); // One unsafe operation\n    }\n\n    macro_rules! twice {\n        ($e:expr) => {{\n            $e;\n            $e;\n        }};\n    }\n\n    // Do not lint, a repeated argument used twice by a macro counts\n    // as at most one unsafe operation.\n    unsafe {\n        twice!(foo());\n    }\n\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        twice!(foo());\n        twice!(foo());\n    }\n\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        assert_eq!(foo(), 0, \"{}\", 1 + 2);\n        assert_eq!(foo(), 0, \"{}\", 1 + 2);\n    }\n\n    macro_rules! unsafe_twice {\n        ($e:expr) => {\n            unsafe {\n                $e;\n                $e;\n            }\n        };\n    };\n\n    // A macro whose expansion contains unsafe blocks will not\n    // check inside the blocks.\n    unsafe {\n        unsafe_twice!(foo());\n    }\n\n    macro_rules! double_non_arg_unsafe {\n        () => {{\n            _ = str::from_utf8_unchecked(&[]);\n            _ = str::from_utf8_unchecked(&[]);\n        }};\n    }\n\n    // Do not lint: each unsafe expression contained in the\n    // macro expansion will count towards the macro call.\n    unsafe {\n        double_non_arg_unsafe!();\n    }\n\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        double_non_arg_unsafe!();\n        double_non_arg_unsafe!();\n    }\n\n    // Do not lint: the inner macro call counts as one unsafe op.\n    unsafe {\n        assert_eq!(double_non_arg_unsafe!(), ());\n    }\n\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        assert_eq!(double_non_arg_unsafe!(), ());\n        assert_eq!(double_non_arg_unsafe!(), ());\n    }\n\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ()));\n    }\n\n    macro_rules! unsafe_with_arg {\n        ($e:expr) => {{\n            _ = str::from_utf8_unchecked(&[]);\n            $e;\n        }};\n    }\n\n    // A confusing situation: the macro call counts towards two unsafe calls,\n    // one coming from inside the macro itself, and one coming from its argument.\n    // The error message may seem a bit strange as both the macro call and its\n    // argument will be marked as counting as unsafe ops, but a short investigation\n    // in those rare situations should sort it out easily.\n    unsafe {\n        //~^ multiple_unsafe_ops_per_block\n        unsafe_with_arg!(foo());\n    }\n\n    macro_rules! ignore {\n        ($e: expr) => {};\n    }\n\n    // Another surprising case is when the macro argument is not\n    // used in the expansion, but in this case we won't see the\n    // unsafe operation at all.\n    unsafe {\n        ignore!(foo());\n        ignore!(foo());\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/multiple_unsafe_ops_per_block.stderr",
    "content": "error: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:38:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         STATIC += 1;\nLL | |         not_very_safe();\nLL | |     }\n   | |_____^\n   |\nnote: modification of a mutable static occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:40:9\n   |\nLL |         STATIC += 1;\n   |         ^^^^^^^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:41:9\n   |\nLL |         not_very_safe();\n   |         ^^^^^^^^^^^^^^^\n   = note: `-D clippy::multiple-unsafe-ops-per-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::multiple_unsafe_ops_per_block)]`\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:48:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         drop(u.u);\nLL | |         *raw_ptr();\nLL | |     }\n   | |_____^\n   |\nnote: raw pointer dereference occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:51:9\n   |\nLL |         *raw_ptr();\n   |         ^^^^^^^^^^\nnote: union field access occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:50:14\n   |\nLL |         drop(u.u);\n   |              ^^^\n\nerror: this `unsafe` block contains 3 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:56:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         asm!(\"nop\");\nLL | |         sample.not_very_safe();\nLL | |         STATIC = 0;\nLL | |     }\n   | |_____^\n   |\nnote: inline assembly used here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:58:9\n   |\nLL |         asm!(\"nop\");\n   |         ^^^^^^^^^^^\nnote: modification of a mutable static occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:60:9\n   |\nLL |         STATIC = 0;\n   |         ^^^^^^^^^^\nnote: unsafe method call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:59:9\n   |\nLL |         sample.not_very_safe();\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 6 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:66:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         drop(u.u);\nLL | |         drop(STATIC);\n...  |\nLL | |         asm!(\"nop\");\nLL | |     }\n   | |_____^\n   |\nnote: access of a mutable static occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:69:14\n   |\nLL |         drop(STATIC);\n   |              ^^^^^^\nnote: inline assembly used here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:73:9\n   |\nLL |         asm!(\"nop\");\n   |         ^^^^^^^^^^^\nnote: raw pointer dereference occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:72:9\n   |\nLL |         *raw_ptr();\n   |         ^^^^^^^^^^\nnote: union field access occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:68:14\n   |\nLL |         drop(u.u);\n   |              ^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:71:9\n   |\nLL |         not_very_safe();\n   |         ^^^^^^^^^^^^^^^\nnote: unsafe method call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:70:9\n   |\nLL |         sample.not_very_safe();\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:109:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         f();\nLL | |         f();\nLL | |     }\n   | |_____^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:111:9\n   |\nLL |         f();\n   |         ^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:112:9\n   |\nLL |         f();\n   |         ^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:118:9\n   |\nLL |         unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: raw pointer dereference occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:118:43\n   |\nLL |         unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }\n   |                                           ^^^^^^^^^^^^^^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:118:18\n   |\nLL |         unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:139:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             x();\nLL | |             x();\nLL | |         }\n   | |_________^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:141:13\n   |\nLL |             x();\n   |             ^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:142:13\n   |\nLL |             x();\n   |             ^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:151:13\n   |\nLL | /             unsafe {\nLL | |\nLL | |                 T::X();\nLL | |                 T::X();\nLL | |             }\n   | |_____________^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:153:17\n   |\nLL |                 T::X();\n   |                 ^^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:154:17\n   |\nLL |                 T::X();\n   |                 ^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:162:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             x.0();\nLL | |             x.0();\nLL | |         }\n   | |_________^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:164:13\n   |\nLL |             x.0();\n   |             ^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:165:13\n   |\nLL |             x.0();\n   |             ^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:192:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         not_very_safe();\nLL | |         STATIC += 1;\nLL | |         foo().await;\nLL | |     }\n   | |_____^\n   |\nnote: modification of a mutable static occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:195:9\n   |\nLL |         STATIC += 1;\n   |         ^^^^^^^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:194:9\n   |\nLL |         not_very_safe();\n   |         ^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:207:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         not_very_safe();\nLL | |         foo_unchecked().await;\nLL | |     }\n   | |_____^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:209:9\n   |\nLL |         not_very_safe();\n   |         ^^^^^^^^^^^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:210:9\n   |\nLL |         foo_unchecked().await;\n   |         ^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:214:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         Some(foo_unchecked()).unwrap_unchecked().await;\nLL | |     }\n   | |_____^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:216:14\n   |\nLL |         Some(foo_unchecked()).unwrap_unchecked().await;\n   |              ^^^^^^^^^^^^^^^\nnote: unsafe method call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:216:9\n   |\nLL |         Some(foo_unchecked()).unwrap_unchecked().await;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:236:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         _ = &u.i;\nLL | |         _ = &u.i;\nLL | |     }\n   | |_____^\n   |\nnote: union field access occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:238:14\n   |\nLL |         _ = &u.i;\n   |              ^^^\nnote: union field access occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:239:14\n   |\nLL |         _ = &u.i;\n   |              ^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:244:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         _ = &raw const (*&raw const u).i;\nLL | |         _ = &raw const (*&raw const u).i;\nLL | |     }\n   | |_____^\n   |\nnote: raw pointer dereference occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:246:24\n   |\nLL |         _ = &raw const (*&raw const u).i;\n   |                        ^^^^^^^^^^^^^^^\nnote: raw pointer dereference occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:247:24\n   |\nLL |         _ = &raw const (*&raw const u).i;\n   |                        ^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:294:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         _ = &raw const w.s.i;\nLL | |         _ = &raw const w.s.i;\nLL | |     }\n   | |_____^\n   |\nnote: union field access occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:296:24\n   |\nLL |         _ = &raw const w.s.i;\n   |                        ^^^\nnote: union field access occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:297:24\n   |\nLL |         _ = &raw const w.s.i;\n   |                        ^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:309:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         apply(|| f(0));\nLL | |     }\n   | |_____^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:311:9\n   |\nLL |         apply(|| f(0));\n   |         ^^^^^^^^^^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:311:18\n   |\nLL |         apply(|| f(0));\n   |                  ^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:326:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         let _ = format!(\"{}\", foo());\nLL | |         let _ = format!(\"{}\", foo());\nLL | |     }\n   | |_____^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:328:31\n   |\nLL |         let _ = format!(\"{}\", foo());\n   |                               ^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:329:31\n   |\nLL |         let _ = format!(\"{}\", foo());\n   |                               ^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:338:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         assert_eq!(foo(), 0, \"{}\", foo()); // One unsafe operation\nLL | |     }\n   | |_____^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:340:20\n   |\nLL |         assert_eq!(foo(), 0, \"{}\", foo()); // One unsafe operation\n   |                    ^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:340:36\n   |\nLL |         assert_eq!(foo(), 0, \"{}\", foo()); // One unsafe operation\n   |                                    ^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:356:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         twice!(foo());\nLL | |         twice!(foo());\nLL | |     }\n   | |_____^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:358:16\n   |\nLL |         twice!(foo());\n   |                ^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:359:16\n   |\nLL |         twice!(foo());\n   |                ^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:362:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         assert_eq!(foo(), 0, \"{}\", 1 + 2);\nLL | |         assert_eq!(foo(), 0, \"{}\", 1 + 2);\nLL | |     }\n   | |_____^\n   |\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:364:20\n   |\nLL |         assert_eq!(foo(), 0, \"{}\", 1 + 2);\n   |                    ^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:365:20\n   |\nLL |         assert_eq!(foo(), 0, \"{}\", 1 + 2);\n   |                    ^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:396:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         double_non_arg_unsafe!();\nLL | |         double_non_arg_unsafe!();\nLL | |     }\n   | |_____^\n   |\nnote: this macro call expands into one or more unsafe operations\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:398:9\n   |\nLL |         double_non_arg_unsafe!();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\nnote: this macro call expands into one or more unsafe operations\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:399:9\n   |\nLL |         double_non_arg_unsafe!();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:407:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         assert_eq!(double_non_arg_unsafe!(), ());\nLL | |         assert_eq!(double_non_arg_unsafe!(), ());\nLL | |     }\n   | |_____^\n   |\nnote: this macro call expands into one or more unsafe operations\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:409:20\n   |\nLL |         assert_eq!(double_non_arg_unsafe!(), ());\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^\nnote: this macro call expands into one or more unsafe operations\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:410:20\n   |\nLL |         assert_eq!(double_non_arg_unsafe!(), ());\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:413:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ()));\nLL | |     }\n   | |_____^\n   |\nnote: this macro call expands into one or more unsafe operations\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:415:21\n   |\nLL |         assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ()));\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^\nnote: this macro call expands into one or more unsafe operations\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:415:47\n   |\nLL |         assert_eq!((double_non_arg_unsafe!(), double_non_arg_unsafe!()), ((), ()));\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `unsafe` block contains 2 unsafe operations, expected only one\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:430:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         unsafe_with_arg!(foo());\nLL | |     }\n   | |_____^\n   |\nnote: this macro call expands into one or more unsafe operations\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:432:9\n   |\nLL |         unsafe_with_arg!(foo());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\nnote: unsafe function call occurs here\n  --> tests/ui/multiple_unsafe_ops_per_block.rs:432:26\n   |\nLL |         unsafe_with_arg!(foo());\n   |                          ^^^^^\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/must_use_candidates.fixed",
    "content": "#![feature(never_type)]\n#![allow(\n    unused_mut,\n    clippy::redundant_allocation,\n    clippy::needless_pass_by_ref_mut,\n    static_mut_refs\n)]\n#![warn(clippy::must_use_candidate)]\nuse std::rc::Rc;\nuse std::sync::Arc;\nuse std::sync::atomic::{AtomicBool, Ordering};\n\npub struct MyAtomic(AtomicBool);\npub struct MyPure;\n\n#[must_use]\npub fn pure(i: u8) -> u8 {\n    //~^ must_use_candidate\n    i\n}\n\nimpl MyPure {\n    #[must_use]\n    pub fn inherent_pure(&self) -> u8 {\n        //~^ must_use_candidate\n        0\n    }\n}\n\npub trait MyPureTrait {\n    fn trait_pure(&self, i: u32) -> u32 {\n        self.trait_impl_pure(i) + 1\n    }\n\n    fn trait_impl_pure(&self, i: u32) -> u32;\n}\n\nimpl MyPureTrait for MyPure {\n    fn trait_impl_pure(&self, i: u32) -> u32 {\n        i\n    }\n}\n\npub fn without_result() {\n    // OK\n}\n\npub fn impure_primitive(i: &mut u8) -> u8 {\n    *i\n}\n\npub fn with_callback<F: Fn(u32) -> bool>(f: &F) -> bool {\n    f(0)\n}\n\n#[must_use]\npub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {\n    //~^ must_use_candidate\n    true\n}\n\npub fn quoth_the_raven(_more: !) -> u32 {\n    unimplemented!();\n}\n\npub fn atomics(b: &AtomicBool) -> bool {\n    b.load(Ordering::SeqCst)\n}\n\n#[must_use]\npub fn rcd(_x: Rc<u32>) -> bool {\n    //~^ must_use_candidate\n    true\n}\n\npub fn rcmut(_x: Rc<&mut u32>) -> bool {\n    true\n}\n\n#[must_use]\npub fn arcd(_x: Arc<u32>) -> bool {\n    //~^ must_use_candidate\n    false\n}\n\npub fn inner_types(_m: &MyAtomic) -> bool {\n    true\n}\n\nstatic mut COUNTER: usize = 0;\n\n/// # Safety\n///\n/// Don't ever call this from multiple threads\npub unsafe fn mutates_static() -> usize {\n    unsafe {\n        COUNTER += 1;\n        COUNTER\n    }\n}\n\n#[unsafe(no_mangle)]\npub extern \"C\" fn unmangled(i: bool) -> bool {\n    !i\n}\n\npub fn main() -> std::process::ExitCode {\n    assert_eq!(1, pure(1));\n    std::process::ExitCode::SUCCESS\n}\n\n//~v must_use_candidate\n#[must_use]\npub fn result_uninhabited() -> Result<i32, std::convert::Infallible> {\n    todo!()\n}\n\n//~v must_use_candidate\n#[must_use]\npub fn controlflow_uninhabited() -> std::ops::ControlFlow<std::convert::Infallible, i32> {\n    todo!()\n}\n"
  },
  {
    "path": "tests/ui/must_use_candidates.rs",
    "content": "#![feature(never_type)]\n#![allow(\n    unused_mut,\n    clippy::redundant_allocation,\n    clippy::needless_pass_by_ref_mut,\n    static_mut_refs\n)]\n#![warn(clippy::must_use_candidate)]\nuse std::rc::Rc;\nuse std::sync::Arc;\nuse std::sync::atomic::{AtomicBool, Ordering};\n\npub struct MyAtomic(AtomicBool);\npub struct MyPure;\n\npub fn pure(i: u8) -> u8 {\n    //~^ must_use_candidate\n    i\n}\n\nimpl MyPure {\n    pub fn inherent_pure(&self) -> u8 {\n        //~^ must_use_candidate\n        0\n    }\n}\n\npub trait MyPureTrait {\n    fn trait_pure(&self, i: u32) -> u32 {\n        self.trait_impl_pure(i) + 1\n    }\n\n    fn trait_impl_pure(&self, i: u32) -> u32;\n}\n\nimpl MyPureTrait for MyPure {\n    fn trait_impl_pure(&self, i: u32) -> u32 {\n        i\n    }\n}\n\npub fn without_result() {\n    // OK\n}\n\npub fn impure_primitive(i: &mut u8) -> u8 {\n    *i\n}\n\npub fn with_callback<F: Fn(u32) -> bool>(f: &F) -> bool {\n    f(0)\n}\n\npub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {\n    //~^ must_use_candidate\n    true\n}\n\npub fn quoth_the_raven(_more: !) -> u32 {\n    unimplemented!();\n}\n\npub fn atomics(b: &AtomicBool) -> bool {\n    b.load(Ordering::SeqCst)\n}\n\npub fn rcd(_x: Rc<u32>) -> bool {\n    //~^ must_use_candidate\n    true\n}\n\npub fn rcmut(_x: Rc<&mut u32>) -> bool {\n    true\n}\n\npub fn arcd(_x: Arc<u32>) -> bool {\n    //~^ must_use_candidate\n    false\n}\n\npub fn inner_types(_m: &MyAtomic) -> bool {\n    true\n}\n\nstatic mut COUNTER: usize = 0;\n\n/// # Safety\n///\n/// Don't ever call this from multiple threads\npub unsafe fn mutates_static() -> usize {\n    unsafe {\n        COUNTER += 1;\n        COUNTER\n    }\n}\n\n#[unsafe(no_mangle)]\npub extern \"C\" fn unmangled(i: bool) -> bool {\n    !i\n}\n\npub fn main() -> std::process::ExitCode {\n    assert_eq!(1, pure(1));\n    std::process::ExitCode::SUCCESS\n}\n\n//~v must_use_candidate\npub fn result_uninhabited() -> Result<i32, std::convert::Infallible> {\n    todo!()\n}\n\n//~v must_use_candidate\npub fn controlflow_uninhabited() -> std::ops::ControlFlow<std::convert::Infallible, i32> {\n    todo!()\n}\n"
  },
  {
    "path": "tests/ui/must_use_candidates.stderr",
    "content": "error: this function could have a `#[must_use]` attribute\n  --> tests/ui/must_use_candidates.rs:16:8\n   |\nLL | pub fn pure(i: u8) -> u8 {\n   |        ^^^^\n   |\n   = note: `-D clippy::must-use-candidate` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::must_use_candidate)]`\nhelp: add the attribute\n   |\nLL + #[must_use]\nLL | pub fn pure(i: u8) -> u8 {\n   |\n\nerror: this method could have a `#[must_use]` attribute\n  --> tests/ui/must_use_candidates.rs:22:12\n   |\nLL |     pub fn inherent_pure(&self) -> u8 {\n   |            ^^^^^^^^^^^^^\n   |\nhelp: add the attribute\n   |\nLL ~     #[must_use]\nLL ~     pub fn inherent_pure(&self) -> u8 {\n   |\n\nerror: this function could have a `#[must_use]` attribute\n  --> tests/ui/must_use_candidates.rs:54:8\n   |\nLL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {\n   |        ^^^^^^^^^^^\n   |\nhelp: add the attribute\n   |\nLL + #[must_use]\nLL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {\n   |\n\nerror: this function could have a `#[must_use]` attribute\n  --> tests/ui/must_use_candidates.rs:67:8\n   |\nLL | pub fn rcd(_x: Rc<u32>) -> bool {\n   |        ^^^\n   |\nhelp: add the attribute\n   |\nLL + #[must_use]\nLL | pub fn rcd(_x: Rc<u32>) -> bool {\n   |\n\nerror: this function could have a `#[must_use]` attribute\n  --> tests/ui/must_use_candidates.rs:76:8\n   |\nLL | pub fn arcd(_x: Arc<u32>) -> bool {\n   |        ^^^^\n   |\nhelp: add the attribute\n   |\nLL + #[must_use]\nLL | pub fn arcd(_x: Arc<u32>) -> bool {\n   |\n\nerror: this function could have a `#[must_use]` attribute\n  --> tests/ui/must_use_candidates.rs:108:8\n   |\nLL | pub fn result_uninhabited() -> Result<i32, std::convert::Infallible> {\n   |        ^^^^^^^^^^^^^^^^^^\n   |\n   = note: a future version of Rust will treat `Result<T, E>` as `T` when `E` is uninhabited wrt `#[must_use]`\nhelp: add the attribute\n   |\nLL + #[must_use]\nLL | pub fn result_uninhabited() -> Result<i32, std::convert::Infallible> {\n   |\n\nerror: this function could have a `#[must_use]` attribute\n  --> tests/ui/must_use_candidates.rs:113:8\n   |\nLL | pub fn controlflow_uninhabited() -> std::ops::ControlFlow<std::convert::Infallible, i32> {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: a future version of Rust will treat `ControlFlow<B, C>` as `C` when `B` is uninhabited wrt `#[must_use]`\nhelp: add the attribute\n   |\nLL + #[must_use]\nLL | pub fn controlflow_uninhabited() -> std::ops::ControlFlow<std::convert::Infallible, i32> {\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/must_use_unit.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::must_use_unit)]\n#![allow(clippy::unused_unit)]\n\nextern crate proc_macros;\nuse proc_macros::external;\n\npub fn must_use_default() {}\n//~^ must_use_unit\n\npub fn must_use_unit() -> () {}\n//~^ must_use_unit\n\npub fn must_use_with_note() {}\n//~^ must_use_unit\n\n// We should not lint in external macros\nexternal!(\n    #[must_use]\n    fn foo() {}\n);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/must_use_unit.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::must_use_unit)]\n#![allow(clippy::unused_unit)]\n\nextern crate proc_macros;\nuse proc_macros::external;\n\n#[must_use]\npub fn must_use_default() {}\n//~^ must_use_unit\n\n#[must_use]\npub fn must_use_unit() -> () {}\n//~^ must_use_unit\n\n#[must_use = \"With note\"]\npub fn must_use_with_note() {}\n//~^ must_use_unit\n\n// We should not lint in external macros\nexternal!(\n    #[must_use]\n    fn foo() {}\n);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/must_use_unit.stderr",
    "content": "error: this unit-returning function has a `#[must_use]` attribute\n  --> tests/ui/must_use_unit.rs:10:1\n   |\nLL | #[must_use]\n   | ----------- help: remove the attribute\nLL | pub fn must_use_default() {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::must-use-unit` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]`\n\nerror: this unit-returning function has a `#[must_use]` attribute\n  --> tests/ui/must_use_unit.rs:14:1\n   |\nLL | #[must_use]\n   | ----------- help: remove the attribute\nLL | pub fn must_use_unit() -> () {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this unit-returning function has a `#[must_use]` attribute\n  --> tests/ui/must_use_unit.rs:18:1\n   |\nLL | #[must_use = \"With note\"]\n   | ------------------------- help: remove the attribute\nLL | pub fn must_use_with_note() {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/must_use_unit_unfixable.rs",
    "content": "#[cfg_attr(all(), must_use, deprecated)]\nfn issue_12320() {}\n//~^ must_use_unit\n\n#[cfg_attr(all(), deprecated, doc = \"foo\", must_use)]\nfn issue_12320_2() {}\n//~^ must_use_unit\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/must_use_unit_unfixable.stderr",
    "content": "error: this unit-returning function has a `#[must_use]` attribute\n  --> tests/ui/must_use_unit_unfixable.rs:2:1\n   |\nLL | fn issue_12320() {}\n   | ^^^^^^^^^^^^^^^^\n   |\nhelp: remove `must_use`\n  --> tests/ui/must_use_unit_unfixable.rs:1:19\n   |\nLL | #[cfg_attr(all(), must_use, deprecated)]\n   |                   ^^^^^^^^\n   = note: `-D clippy::must-use-unit` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::must_use_unit)]`\n\nerror: this unit-returning function has a `#[must_use]` attribute\n  --> tests/ui/must_use_unit_unfixable.rs:6:1\n   |\nLL | fn issue_12320_2() {}\n   | ^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `must_use`\n  --> tests/ui/must_use_unit_unfixable.rs:5:44\n   |\nLL | #[cfg_attr(all(), deprecated, doc = \"foo\", must_use)]\n   |                                            ^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/mut_from_ref.rs",
    "content": "#![allow(\n    unused,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_ref_mut,\n    clippy::redundant_allocation,\n    clippy::boxed_local\n)]\n#![warn(clippy::mut_from_ref)]\n\nstruct Foo;\n\nimpl Foo {\n    fn this_wont_hurt_a_bit(&self) -> &mut Foo {\n        //~^ mut_from_ref\n\n        unsafe { unimplemented!() }\n    }\n}\n\ntrait Ouch {\n    fn ouch(x: &Foo) -> &mut Foo;\n    //~^ mut_from_ref\n}\n\nimpl Ouch for Foo {\n    fn ouch(x: &Foo) -> &mut Foo {\n        unsafe { unimplemented!() }\n    }\n}\n\nfn fail(x: &u32) -> &mut u16 {\n    //~^ mut_from_ref\n\n    unsafe { unimplemented!() }\n}\n\nfn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {\n    //~^ mut_from_ref\n\n    unsafe { unimplemented!() }\n}\n\nfn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {\n    //~^ mut_from_ref\n\n    unsafe { unimplemented!() }\n}\n\nfn fail_tuples<'a>(x: (&'a u32, &'a u32)) -> &'a mut u32 {\n    //~^ mut_from_ref\n\n    unsafe { unimplemented!() }\n}\n\nfn fail_box<'a>(x: Box<&'a u32>) -> &'a mut u32 {\n    //~^ mut_from_ref\n\n    unsafe { unimplemented!() }\n}\n\n// this is OK, because the result borrows y\nfn works<'a>(x: &u32, y: &'a mut u32) -> &'a mut u32 {\n    unsafe { unimplemented!() }\n}\n\n// this is also OK, because the result could borrow y\nfn also_works<'a>(x: &'a u32, y: &'a mut u32) -> &'a mut u32 {\n    unsafe { unimplemented!() }\n}\n\nfn works_tuples<'a>(x: (&'a u32, &'a mut u32)) -> &'a mut u32 {\n    unsafe { unimplemented!() }\n}\n\nfn works_box<'a>(x: &'a u32, y: Box<&'a mut u32>) -> &'a mut u32 {\n    unsafe { unimplemented!() }\n}\n\nstruct RefMut<'a>(&'a mut u32);\n\nfn works_parameter<'a>(x: &'a u32, y: RefMut<'a>) -> &'a mut u32 {\n    unsafe { unimplemented!() }\n}\n\nunsafe fn also_broken(x: &u32) -> &mut u32 {\n    //~^ mut_from_ref\n\n    unimplemented!()\n}\n\nfn without_unsafe(x: &u32) -> &mut u32 {\n    unimplemented!()\n}\n\nfn main() {\n    //TODO\n}\n"
  },
  {
    "path": "tests/ui/mut_from_ref.stderr",
    "content": "error: mutable borrow from immutable input(s)\n  --> tests/ui/mut_from_ref.rs:13:39\n   |\nLL |     fn this_wont_hurt_a_bit(&self) -> &mut Foo {\n   |                                       ^^^^^^^^\n   |\nnote: immutable borrow here\n  --> tests/ui/mut_from_ref.rs:13:29\n   |\nLL |     fn this_wont_hurt_a_bit(&self) -> &mut Foo {\n   |                             ^^^^^\n   = note: `-D clippy::mut-from-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mut_from_ref)]`\n\nerror: mutable borrow from immutable input(s)\n  --> tests/ui/mut_from_ref.rs:21:25\n   |\nLL |     fn ouch(x: &Foo) -> &mut Foo;\n   |                         ^^^^^^^^\n   |\nnote: immutable borrow here\n  --> tests/ui/mut_from_ref.rs:21:16\n   |\nLL |     fn ouch(x: &Foo) -> &mut Foo;\n   |                ^^^^\n\nerror: mutable borrow from immutable input(s)\n  --> tests/ui/mut_from_ref.rs:31:21\n   |\nLL | fn fail(x: &u32) -> &mut u16 {\n   |                     ^^^^^^^^\n   |\nnote: immutable borrow here\n  --> tests/ui/mut_from_ref.rs:31:12\n   |\nLL | fn fail(x: &u32) -> &mut u16 {\n   |            ^^^^\n\nerror: mutable borrow from immutable input(s)\n  --> tests/ui/mut_from_ref.rs:37:50\n   |\nLL | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {\n   |                                                  ^^^^^^^^^^^\n   |\nnote: immutable borrow here\n  --> tests/ui/mut_from_ref.rs:37:25\n   |\nLL | fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {\n   |                         ^^^^^^^\n\nerror: mutable borrow from immutable input(s)\n  --> tests/ui/mut_from_ref.rs:43:67\n   |\nLL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {\n   |                                                                   ^^^^^^^^^^^\n   |\nnote: immutable borrow here\n  --> tests/ui/mut_from_ref.rs:43:27\n   |\nLL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {\n   |                           ^^^^^^^     ^^^^^^^\n\nerror: mutable borrow from immutable input(s)\n  --> tests/ui/mut_from_ref.rs:49:46\n   |\nLL | fn fail_tuples<'a>(x: (&'a u32, &'a u32)) -> &'a mut u32 {\n   |                                              ^^^^^^^^^^^\n   |\nnote: immutable borrow here\n  --> tests/ui/mut_from_ref.rs:49:24\n   |\nLL | fn fail_tuples<'a>(x: (&'a u32, &'a u32)) -> &'a mut u32 {\n   |                        ^^^^^^^  ^^^^^^^\n\nerror: mutable borrow from immutable input(s)\n  --> tests/ui/mut_from_ref.rs:55:37\n   |\nLL | fn fail_box<'a>(x: Box<&'a u32>) -> &'a mut u32 {\n   |                                     ^^^^^^^^^^^\n   |\nnote: immutable borrow here\n  --> tests/ui/mut_from_ref.rs:55:24\n   |\nLL | fn fail_box<'a>(x: Box<&'a u32>) -> &'a mut u32 {\n   |                        ^^^^^^^\n\nerror: mutable borrow from immutable input(s)\n  --> tests/ui/mut_from_ref.rs:85:35\n   |\nLL | unsafe fn also_broken(x: &u32) -> &mut u32 {\n   |                                   ^^^^^^^^\n   |\nnote: immutable borrow here\n  --> tests/ui/mut_from_ref.rs:85:26\n   |\nLL | unsafe fn also_broken(x: &u32) -> &mut u32 {\n   |                          ^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/mut_key.rs",
    "content": "use std::cell::Cell;\nuse std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};\nuse std::hash::{Hash, Hasher};\nuse std::rc::Rc;\nuse std::sync::Arc;\nuse std::sync::atomic::AtomicUsize;\nuse std::sync::atomic::Ordering::Relaxed;\n\nstruct Key(AtomicUsize);\n\nimpl Clone for Key {\n    fn clone(&self) -> Self {\n        Key(AtomicUsize::new(self.0.load(Relaxed)))\n    }\n}\n\nimpl PartialEq for Key {\n    fn eq(&self, other: &Self) -> bool {\n        self.0.load(Relaxed) == other.0.load(Relaxed)\n    }\n}\n\nimpl Eq for Key {}\n\nimpl Hash for Key {\n    fn hash<H: Hasher>(&self, h: &mut H) {\n        self.0.load(Relaxed).hash(h);\n    }\n}\n\nfn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<Key> {\n    //~^ mutable_key_type\n    //~| mutable_key_type\n\n    let _other: HashMap<Key, bool> = HashMap::new();\n    //~^ mutable_key_type\n\n    m.keys().cloned().collect()\n}\n\nfn this_is_ok(_m: &mut HashMap<usize, Key>) {}\n\n// Raw pointers are hashed by the address they point to, so it doesn't matter if they point to a\n// type with interior mutability.  See:\n// - clippy issue: https://github.com/rust-lang/rust-clippy/issues/6745\n// - std lib: https://github.com/rust-lang/rust/blob/1.54.0/library/core/src/hash/mod.rs#L717-L736\n// So these are OK:\nfn raw_ptr_is_ok(_m: &mut HashMap<*const Key, ()>) {}\nfn raw_mut_ptr_is_ok(_m: &mut HashMap<*mut Key, ()>) {}\n\n#[allow(unused)]\ntrait Trait {\n    type AssociatedType;\n\n    fn trait_fn(&self, set: HashSet<Self::AssociatedType>);\n}\n\nfn generics_are_ok_too<K>(_m: &mut HashSet<K>) {\n    // nothing to see here, move along\n}\n\nfn tuples<U>(_m: &mut HashMap<((), U), ()>) {}\n\nfn tuples_bad<U>(_m: &mut HashMap<(Key, U), bool>) {}\n//~^ mutable_key_type\n\nfn main() {\n    let _ = should_not_take_this_arg(&mut HashMap::new(), 1);\n    this_is_ok(&mut HashMap::new());\n    tuples::<Key>(&mut HashMap::new());\n    tuples::<()>(&mut HashMap::new());\n    tuples_bad::<()>(&mut HashMap::new());\n\n    raw_ptr_is_ok(&mut HashMap::new());\n    raw_mut_ptr_is_ok(&mut HashMap::new());\n\n    let _map = HashMap::<Cell<usize>, usize>::new();\n    //~^ mutable_key_type\n\n    let _map = HashMap::<&mut Cell<usize>, usize>::new();\n    //~^ mutable_key_type\n\n    // Collection types from `std` who's impl of `Hash` or `Ord` delegate their type parameters\n    let _map = HashMap::<Vec<Cell<usize>>, usize>::new();\n    //~^ mutable_key_type\n\n    let _map = HashMap::<BTreeMap<Cell<usize>, ()>, usize>::new();\n    //~^ mutable_key_type\n\n    let _map = HashMap::<BTreeMap<(), Cell<usize>>, usize>::new();\n    //~^ mutable_key_type\n\n    let _map = HashMap::<BTreeSet<Cell<usize>>, usize>::new();\n    //~^ mutable_key_type\n\n    let _map = HashMap::<Option<Cell<usize>>, usize>::new();\n    //~^ mutable_key_type\n\n    let _map = HashMap::<Option<Vec<Cell<usize>>>, usize>::new();\n    //~^ mutable_key_type\n\n    // Smart pointers from `std` who's impl of `Hash` or `Ord` delegate their type parameters\n    let _map = HashMap::<Box<Cell<usize>>, usize>::new();\n    //~^ mutable_key_type\n\n    let _map = HashMap::<Rc<Cell<usize>>, usize>::new();\n    //~^ mutable_key_type\n\n    let _map = HashMap::<Arc<Cell<usize>>, usize>::new();\n    //~^ mutable_key_type\n\n    // Not interior mutability\n    let _map = HashMap::<&mut usize, usize>::new();\n    let _map = HashMap::<Result<&mut usize, ()>, usize>::new();\n}\n"
  },
  {
    "path": "tests/ui/mut_key.stderr",
    "content": "error: mutable key type\n  --> tests/ui/mut_key.rs:31:32\n   |\nLL | fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<Key> {\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Key`, which has interior mutability\n   = note: ... because it contains `Atomic<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<<usize as AtomicPrimitive>::Storage>`, which has interior mutability\n   = note: `-D clippy::mutable-key-type` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mutable_key_type)]`\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:31:72\n   |\nLL | fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<Key> {\n   |                                                                        ^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Key`, which has interior mutability\n   = note: ... because it contains `Atomic<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<<usize as AtomicPrimitive>::Storage>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:35:5\n   |\nLL |     let _other: HashMap<Key, bool> = HashMap::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Key`, which has interior mutability\n   = note: ... because it contains `Atomic<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<<usize as AtomicPrimitive>::Storage>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:64:22\n   |\nLL | fn tuples_bad<U>(_m: &mut HashMap<(Key, U), bool>) {}\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `(Key, U)`, which has interior mutability\n   = note: ... because it contains `Key`, which has interior mutability\n   = note: ... because it contains `Atomic<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<<usize as AtomicPrimitive>::Storage>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:77:5\n   |\nLL |     let _map = HashMap::<Cell<usize>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:80:5\n   |\nLL |     let _map = HashMap::<&mut Cell<usize>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `&mut Cell<usize>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:84:5\n   |\nLL |     let _map = HashMap::<Vec<Cell<usize>>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Vec<Cell<usize>>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:87:5\n   |\nLL |     let _map = HashMap::<BTreeMap<Cell<usize>, ()>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `BTreeMap<Cell<usize>, ()>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:90:5\n   |\nLL |     let _map = HashMap::<BTreeMap<(), Cell<usize>>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `BTreeMap<(), Cell<usize>>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:93:5\n   |\nLL |     let _map = HashMap::<BTreeSet<Cell<usize>>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `BTreeSet<Cell<usize>>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:96:5\n   |\nLL |     let _map = HashMap::<Option<Cell<usize>>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Option<Cell<usize>>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:99:5\n   |\nLL |     let _map = HashMap::<Option<Vec<Cell<usize>>>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Option<Vec<Cell<usize>>>`, which has interior mutability\n   = note: ... because it contains `Vec<Cell<usize>>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:103:5\n   |\nLL |     let _map = HashMap::<Box<Cell<usize>>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Box<Cell<usize>>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:106:5\n   |\nLL |     let _map = HashMap::<Rc<Cell<usize>>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Rc<Cell<usize>>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: mutable key type\n  --> tests/ui/mut_key.rs:109:5\n   |\nLL |     let _map = HashMap::<Arc<Cell<usize>>, usize>::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: ... because it contains `Arc<Cell<usize>>`, which has interior mutability\n   = note: ... because it contains `Cell<usize>`, which has interior mutability\n   = note: ... because it contains `UnsafeCell<usize>`, which has interior mutability\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/mut_mut.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::mut_mut)]\n#![allow(unused)]\n#![allow(\n    clippy::no_effect,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_operation,\n    clippy::needless_pass_by_ref_mut\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nfn fun(x: &mut u32) {\n    //~^ mut_mut\n}\n\nfn less_fun(x: *mut *mut u32) {\n    let y = x;\n}\n\nmacro_rules! mut_ptr {\n    ($p:expr) => {\n        &mut $p\n    };\n}\n\n#[allow(unused_mut, unused_variables)]\n#[inline_macros]\nfn main() {\n    let mut x = &mut 1u32;\n    //~^ mut_mut\n    {\n        let mut y = &mut *x;\n        //~^ mut_mut\n    }\n\n    {\n        let y: &mut u32 = &mut 2;\n        //~^ mut_mut\n        //~| mut_mut\n    }\n\n    {\n        let y: &mut u32 = &mut 2;\n        //~^ mut_mut\n        //~| mut_mut\n    }\n\n    let mut z = inline!(&mut $(&mut 3u32));\n}\n\nfn issue939() {\n    let array = [5, 6, 7, 8, 9];\n    let mut args = array.iter().skip(2);\n    for &arg in &mut args {\n        println!(\"{}\", arg);\n    }\n\n    let args = &mut args;\n    for arg in args {\n        println!(\":{}\", arg);\n    }\n}\n\nfn issue6922() {\n    // do not lint from an external macro\n    external!(let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32;);\n}\n\nmod issue9035 {\n    use std::fmt::Display;\n\n    struct Foo<'a> {\n        inner: &'a mut dyn Display,\n    }\n\n    impl Foo<'_> {\n        fn foo(&mut self) {\n            let hlp = &mut self.inner;\n            bar(hlp);\n        }\n    }\n\n    fn bar(_: &mut impl Display) {}\n}\n\nfn allow_works() {\n    #[allow(clippy::mut_mut)]\n    let _ = &mut &mut 1;\n}\n"
  },
  {
    "path": "tests/ui/mut_mut.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::mut_mut)]\n#![allow(unused)]\n#![allow(\n    clippy::no_effect,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_operation,\n    clippy::needless_pass_by_ref_mut\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nfn fun(x: &mut &mut u32) {\n    //~^ mut_mut\n}\n\nfn less_fun(x: *mut *mut u32) {\n    let y = x;\n}\n\nmacro_rules! mut_ptr {\n    ($p:expr) => {\n        &mut $p\n    };\n}\n\n#[allow(unused_mut, unused_variables)]\n#[inline_macros]\nfn main() {\n    let mut x = &mut &mut 1u32;\n    //~^ mut_mut\n    {\n        let mut y = &mut x;\n        //~^ mut_mut\n    }\n\n    {\n        let y: &mut &mut u32 = &mut &mut 2;\n        //~^ mut_mut\n        //~| mut_mut\n    }\n\n    {\n        let y: &mut &mut &mut u32 = &mut &mut &mut 2;\n        //~^ mut_mut\n        //~| mut_mut\n    }\n\n    let mut z = inline!(&mut $(&mut 3u32));\n}\n\nfn issue939() {\n    let array = [5, 6, 7, 8, 9];\n    let mut args = array.iter().skip(2);\n    for &arg in &mut args {\n        println!(\"{}\", arg);\n    }\n\n    let args = &mut args;\n    for arg in args {\n        println!(\":{}\", arg);\n    }\n}\n\nfn issue6922() {\n    // do not lint from an external macro\n    external!(let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32;);\n}\n\nmod issue9035 {\n    use std::fmt::Display;\n\n    struct Foo<'a> {\n        inner: &'a mut dyn Display,\n    }\n\n    impl Foo<'_> {\n        fn foo(&mut self) {\n            let hlp = &mut self.inner;\n            bar(hlp);\n        }\n    }\n\n    fn bar(_: &mut impl Display) {}\n}\n\nfn allow_works() {\n    #[allow(clippy::mut_mut)]\n    let _ = &mut &mut 1;\n}\n"
  },
  {
    "path": "tests/ui/mut_mut.stderr",
    "content": "error: a type of form `&mut &mut _`\n  --> tests/ui/mut_mut.rs:15:11\n   |\nLL | fn fun(x: &mut &mut u32) {\n   |           ^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut u32`\n   |\n   = note: `-D clippy::mut-mut` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mut_mut)]`\n\nerror: an expression of form `&mut &mut _`\n  --> tests/ui/mut_mut.rs:32:17\n   |\nLL |     let mut x = &mut &mut 1u32;\n   |                 ^^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut 1u32`\n\nerror: this expression mutably borrows a mutable reference\n  --> tests/ui/mut_mut.rs:35:21\n   |\nLL |         let mut y = &mut x;\n   |                     ^^^^^^ help: reborrow instead: `&mut *x`\n\nerror: an expression of form `&mut &mut _`\n  --> tests/ui/mut_mut.rs:40:32\n   |\nLL |         let y: &mut &mut u32 = &mut &mut 2;\n   |                                ^^^^^^^^^^^ help: remove the extra `&mut`: `&mut 2`\n\nerror: a type of form `&mut &mut _`\n  --> tests/ui/mut_mut.rs:40:16\n   |\nLL |         let y: &mut &mut u32 = &mut &mut 2;\n   |                ^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut u32`\n\nerror: an expression of form `&mut &mut _`\n  --> tests/ui/mut_mut.rs:46:37\n   |\nLL |         let y: &mut &mut &mut u32 = &mut &mut &mut 2;\n   |                                     ^^^^^^^^^^^^^^^^ help: remove the extra `&mut`s: `&mut 2`\n\nerror: a type of form `&mut &mut _`\n  --> tests/ui/mut_mut.rs:46:16\n   |\nLL |         let y: &mut &mut &mut u32 = &mut &mut &mut 2;\n   |                ^^^^^^^^^^^^^^^^^^ help: remove the extra `&mut`s: `&mut u32`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/mut_mut_unfixable.rs",
    "content": "//@no-rustfix\n\n#![warn(clippy::mut_mut)]\n#![allow(unused)]\n#![expect(clippy::no_effect)]\n\n//! removing the extra `&mut`s will break the derefs\n\nfn fun(x: &mut &mut u32) -> bool {\n    //~^ mut_mut\n    **x > 0\n}\n\nfn main() {\n    let mut x = &mut &mut 1u32;\n    //~^ mut_mut\n    {\n        let mut y = &mut x;\n        //~^ mut_mut\n        ***y + **x;\n    }\n\n    if fun(x) {\n        let y = &mut &mut 2;\n        //~^ mut_mut\n        **y + **x;\n    }\n\n    if fun(x) {\n        let y = &mut &mut &mut 2;\n        //~^ mut_mut\n        ***y + **x;\n    }\n\n    if fun(x) {\n        // The lint will remove the extra `&mut`, but the result will still be a `&mut` of an expr\n        // of type `&mut _` (x), so the lint will fire again. That's because we've decided that\n        // doing both fixes in one run is not worth it, given how improbable code like this is.\n        let y = &mut &mut x;\n        //~^ mut_mut\n    }\n}\n"
  },
  {
    "path": "tests/ui/mut_mut_unfixable.stderr",
    "content": "error: a type of form `&mut &mut _`\n  --> tests/ui/mut_mut_unfixable.rs:9:11\n   |\nLL | fn fun(x: &mut &mut u32) -> bool {\n   |           ^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut u32`\n   |\n   = note: `-D clippy::mut-mut` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mut_mut)]`\n\nerror: an expression of form `&mut &mut _`\n  --> tests/ui/mut_mut_unfixable.rs:15:17\n   |\nLL |     let mut x = &mut &mut 1u32;\n   |                 ^^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut 1u32`\n\nerror: this expression mutably borrows a mutable reference\n  --> tests/ui/mut_mut_unfixable.rs:18:21\n   |\nLL |         let mut y = &mut x;\n   |                     ^^^^^^ help: reborrow instead: `&mut *x`\n\nerror: an expression of form `&mut &mut _`\n  --> tests/ui/mut_mut_unfixable.rs:24:17\n   |\nLL |         let y = &mut &mut 2;\n   |                 ^^^^^^^^^^^ help: remove the extra `&mut`: `&mut 2`\n\nerror: an expression of form `&mut &mut _`\n  --> tests/ui/mut_mut_unfixable.rs:30:17\n   |\nLL |         let y = &mut &mut &mut 2;\n   |                 ^^^^^^^^^^^^^^^^ help: remove the extra `&mut`s: `&mut 2`\n\nerror: an expression of form `&mut &mut _`\n  --> tests/ui/mut_mut_unfixable.rs:39:17\n   |\nLL |         let y = &mut &mut x;\n   |                 ^^^^^^^^^^^ help: remove the extra `&mut`: `&mut x`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/mut_mutex_lock.fixed",
    "content": "#![allow(dead_code, unused_mut)]\n#![warn(clippy::mut_mutex_lock)]\n\nuse std::sync::{Arc, Mutex};\n\nfn mut_mutex_lock() {\n    let mut value_rc = Arc::new(Mutex::new(42_u8));\n    let value_mutex = Arc::get_mut(&mut value_rc).unwrap();\n\n    let mut value = value_mutex.get_mut().unwrap();\n    //~^ mut_mutex_lock\n    *value += 1;\n\n    let mut value_mutex = Mutex::new(42_u8);\n    let mut_ref_mut_ref_mutex = &mut &mut value_mutex;\n    let mut value = mut_ref_mut_ref_mutex.get_mut().unwrap();\n    //~^ mut_mutex_lock\n    *value += 1;\n}\n\nfn no_owned_mutex_lock() {\n    let mut value_rc = Arc::new(Mutex::new(42_u8));\n    let mut value = value_rc.lock().unwrap();\n    *value += 1;\n}\n\nfn issue9415() {\n    let mut arc_mutex = Arc::new(Mutex::new(42_u8));\n    let arc_mutex: &mut Arc<Mutex<u8>> = &mut arc_mutex;\n    let mut guard = arc_mutex.lock().unwrap();\n    *guard += 1;\n}\n\nfn mut_ref_ref_mutex_lock() {\n    let mutex = Mutex::new(42_u8);\n    let mut_ref_ref_mutex = &mut &mutex;\n    let mut guard = mut_ref_ref_mutex.lock().unwrap();\n    *guard += 1;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/mut_mutex_lock.rs",
    "content": "#![allow(dead_code, unused_mut)]\n#![warn(clippy::mut_mutex_lock)]\n\nuse std::sync::{Arc, Mutex};\n\nfn mut_mutex_lock() {\n    let mut value_rc = Arc::new(Mutex::new(42_u8));\n    let value_mutex = Arc::get_mut(&mut value_rc).unwrap();\n\n    let mut value = value_mutex.lock().unwrap();\n    //~^ mut_mutex_lock\n    *value += 1;\n\n    let mut value_mutex = Mutex::new(42_u8);\n    let mut_ref_mut_ref_mutex = &mut &mut value_mutex;\n    let mut value = mut_ref_mut_ref_mutex.lock().unwrap();\n    //~^ mut_mutex_lock\n    *value += 1;\n}\n\nfn no_owned_mutex_lock() {\n    let mut value_rc = Arc::new(Mutex::new(42_u8));\n    let mut value = value_rc.lock().unwrap();\n    *value += 1;\n}\n\nfn issue9415() {\n    let mut arc_mutex = Arc::new(Mutex::new(42_u8));\n    let arc_mutex: &mut Arc<Mutex<u8>> = &mut arc_mutex;\n    let mut guard = arc_mutex.lock().unwrap();\n    *guard += 1;\n}\n\nfn mut_ref_ref_mutex_lock() {\n    let mutex = Mutex::new(42_u8);\n    let mut_ref_ref_mutex = &mut &mutex;\n    let mut guard = mut_ref_ref_mutex.lock().unwrap();\n    *guard += 1;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/mut_mutex_lock.stderr",
    "content": "error: calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference\n  --> tests/ui/mut_mutex_lock.rs:10:33\n   |\nLL |     let mut value = value_mutex.lock().unwrap();\n   |                                 ^^^^ help: change this to: `get_mut`\n   |\n   = note: `-D clippy::mut-mutex-lock` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mut_mutex_lock)]`\n\nerror: calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference\n  --> tests/ui/mut_mutex_lock.rs:16:43\n   |\nLL |     let mut value = mut_ref_mut_ref_mutex.lock().unwrap();\n   |                                           ^^^^ help: change this to: `get_mut`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/mut_range_bound.rs",
    "content": "#![allow(unused)]\n\nfn main() {}\n\nfn mut_range_bound_upper() {\n    let mut m = 4;\n    for i in 0..m {\n        m = 5;\n        //~^ mut_range_bound\n    }\n}\n\nfn mut_range_bound_lower() {\n    let mut m = 4;\n    for i in m..10 {\n        m *= 2;\n        //~^ mut_range_bound\n    }\n}\n\nfn mut_range_bound_both() {\n    let mut m = 4;\n    let mut n = 6;\n    for i in m..n {\n        m = 5;\n        //~^ mut_range_bound\n\n        n = 7;\n        //~^ mut_range_bound\n    }\n}\n\nfn mut_range_bound_no_mutation() {\n    let mut m = 4;\n    for i in 0..m {\n        continue;\n    } // no warning\n}\n\nfn mut_borrow_range_bound() {\n    let mut m = 4;\n    for i in 0..m {\n        let n = &mut m;\n        //~^ mut_range_bound\n\n        *n += 1;\n    }\n}\n\nfn immut_borrow_range_bound() {\n    let mut m = 4;\n    for i in 0..m {\n        let n = &m;\n    }\n}\n\nfn immut_range_bound() {\n    let m = 4;\n    for i in 0..m {\n        continue;\n    } // no warning\n}\n\nfn mut_range_bound_break() {\n    let mut m = 4;\n    for i in 0..m {\n        if m == 4 {\n            m = 5; // no warning because of immediate break\n            break;\n        }\n    }\n}\n\nfn mut_range_bound_no_immediate_break() {\n    let mut m = 4;\n    for i in 0..m {\n        // warning because it is not immediately followed by break\n        m = 2;\n        //~^ mut_range_bound\n\n        if m == 4 {\n            break;\n        }\n    }\n\n    let mut n = 3;\n    for i in n..10 {\n        if n == 4 {\n            // FIXME: warning because it is not immediately followed by break\n            n = 1;\n            //~^ mut_range_bound\n\n            let _ = 2;\n            break;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/mut_range_bound.stderr",
    "content": "error: attempt to mutate range bound within loop\n  --> tests/ui/mut_range_bound.rs:8:9\n   |\nLL |         m = 5;\n   |         ^\n   |\n   = note: the range of the loop is unchanged\n   = note: `-D clippy::mut-range-bound` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mut_range_bound)]`\n\nerror: attempt to mutate range bound within loop\n  --> tests/ui/mut_range_bound.rs:16:9\n   |\nLL |         m *= 2;\n   |         ^\n   |\n   = note: the range of the loop is unchanged\n\nerror: attempt to mutate range bound within loop\n  --> tests/ui/mut_range_bound.rs:25:9\n   |\nLL |         m = 5;\n   |         ^\n   |\n   = note: the range of the loop is unchanged\n\nerror: attempt to mutate range bound within loop\n  --> tests/ui/mut_range_bound.rs:28:9\n   |\nLL |         n = 7;\n   |         ^\n   |\n   = note: the range of the loop is unchanged\n\nerror: attempt to mutate range bound within loop\n  --> tests/ui/mut_range_bound.rs:43:22\n   |\nLL |         let n = &mut m;\n   |                      ^\n   |\n   = note: the range of the loop is unchanged\n\nerror: attempt to mutate range bound within loop\n  --> tests/ui/mut_range_bound.rs:78:9\n   |\nLL |         m = 2;\n   |         ^\n   |\n   = note: the range of the loop is unchanged\n\nerror: attempt to mutate range bound within loop\n  --> tests/ui/mut_range_bound.rs:90:13\n   |\nLL |             n = 1;\n   |             ^\n   |\n   = note: the range of the loop is unchanged\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/mutex_atomic.fixed",
    "content": "#![warn(clippy::mutex_integer)]\n#![warn(clippy::mutex_atomic)]\n#![allow(clippy::borrow_as_ptr)]\n\nuse std::sync::Mutex;\n\nfn main() {\n    let _ = std::sync::atomic::AtomicBool::new(true);\n    //~^ mutex_atomic\n\n    let _ = std::sync::atomic::AtomicUsize::new(5usize);\n    //~^ mutex_atomic\n\n    let _ = std::sync::atomic::AtomicIsize::new(9isize);\n    //~^ mutex_atomic\n\n    let mut x = 4u32;\n    // `AtomicPtr` only accepts `*mut T`, so this should not lint\n    let _ = Mutex::new(&x as *const u32);\n\n    let _ = std::sync::atomic::AtomicPtr::new(&mut x as *mut u32);\n    //~^ mutex_atomic\n\n    let _ = std::sync::atomic::AtomicU32::new(0u32);\n    //~^ mutex_integer\n\n    let _ = std::sync::atomic::AtomicI32::new(0i32);\n    //~^ mutex_integer\n\n    let _ = Mutex::new(0f32); // there are no float atomics, so this should not lint\n    let _ = std::sync::atomic::AtomicU8::new(0u8);\n    //~^ mutex_integer\n\n    let _ = std::sync::atomic::AtomicI16::new(0i16);\n    //~^ mutex_integer\n\n    let _x = std::sync::atomic::AtomicI8::new(0);\n    //~^ mutex_integer\n\n    const X: i64 = 0;\n    let _ = std::sync::atomic::AtomicI64::new(X);\n    //~^ mutex_integer\n\n    // there are no 128 atomics, so these two should not lint\n    {\n        let _ = Mutex::new(0u128);\n        let _x: Mutex<i128> = Mutex::new(0);\n    }\n}\n\n// don't lint on _use_, only declaration\nfn issue13378() {\n    static MTX: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);\n    //~^ mutex_integer\n\n    let mtx = std::sync::atomic::AtomicI32::new(0);\n    //~^ mutex_integer\n    // This will still lint, since we're reassigning the mutex to a variable -- oh well.\n    // But realistically something like this won't really come up.\n    let reassigned = mtx;\n    //~^ mutex_integer\n\n    // don't eat the `)` when removing the type ascription -- see\n    // https://github.com/rust-lang/rust-clippy/issues/15377\n    let (funky_mtx) = std::sync::atomic::AtomicU64::new(0);\n    //~^ mutex_integer\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            ($val > 0 && true)\n        };\n    }\n\n    let _ = std::sync::atomic::AtomicBool::new(test_expr!(1));\n    //~^ mutex_atomic\n    // The suggestion should preserve the macro call: `AtomicBool::new(test_expr!(true))`\n}\n"
  },
  {
    "path": "tests/ui/mutex_atomic.rs",
    "content": "#![warn(clippy::mutex_integer)]\n#![warn(clippy::mutex_atomic)]\n#![allow(clippy::borrow_as_ptr)]\n\nuse std::sync::Mutex;\n\nfn main() {\n    let _ = Mutex::new(true);\n    //~^ mutex_atomic\n\n    let _ = Mutex::new(5usize);\n    //~^ mutex_atomic\n\n    let _ = Mutex::new(9isize);\n    //~^ mutex_atomic\n\n    let mut x = 4u32;\n    // `AtomicPtr` only accepts `*mut T`, so this should not lint\n    let _ = Mutex::new(&x as *const u32);\n\n    let _ = Mutex::new(&mut x as *mut u32);\n    //~^ mutex_atomic\n\n    let _ = Mutex::new(0u32);\n    //~^ mutex_integer\n\n    let _ = Mutex::new(0i32);\n    //~^ mutex_integer\n\n    let _ = Mutex::new(0f32); // there are no float atomics, so this should not lint\n    let _ = Mutex::new(0u8);\n    //~^ mutex_integer\n\n    let _ = Mutex::new(0i16);\n    //~^ mutex_integer\n\n    let _x: Mutex<i8> = Mutex::new(0);\n    //~^ mutex_integer\n\n    const X: i64 = 0;\n    let _ = Mutex::new(X);\n    //~^ mutex_integer\n\n    // there are no 128 atomics, so these two should not lint\n    {\n        let _ = Mutex::new(0u128);\n        let _x: Mutex<i128> = Mutex::new(0);\n    }\n}\n\n// don't lint on _use_, only declaration\nfn issue13378() {\n    static MTX: Mutex<u32> = Mutex::new(0);\n    //~^ mutex_integer\n\n    let mtx = Mutex::new(0);\n    //~^ mutex_integer\n    // This will still lint, since we're reassigning the mutex to a variable -- oh well.\n    // But realistically something like this won't really come up.\n    let reassigned = mtx;\n    //~^ mutex_integer\n\n    // don't eat the `)` when removing the type ascription -- see\n    // https://github.com/rust-lang/rust-clippy/issues/15377\n    let (funky_mtx): Mutex<u64> = Mutex::new(0);\n    //~^ mutex_integer\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            ($val > 0 && true)\n        };\n    }\n\n    let _ = Mutex::new(test_expr!(1));\n    //~^ mutex_atomic\n    // The suggestion should preserve the macro call: `AtomicBool::new(test_expr!(true))`\n}\n"
  },
  {
    "path": "tests/ui/mutex_atomic.stderr",
    "content": "error: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:8:13\n   |\nLL |     let _ = Mutex::new(true);\n   |             ^^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\n   = note: `-D clippy::mutex-atomic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mutex_atomic)]`\nhelp: try\n   |\nLL -     let _ = Mutex::new(true);\nLL +     let _ = std::sync::atomic::AtomicBool::new(true);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:11:13\n   |\nLL |     let _ = Mutex::new(5usize);\n   |             ^^^^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _ = Mutex::new(5usize);\nLL +     let _ = std::sync::atomic::AtomicUsize::new(5usize);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:14:13\n   |\nLL |     let _ = Mutex::new(9isize);\n   |             ^^^^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _ = Mutex::new(9isize);\nLL +     let _ = std::sync::atomic::AtomicIsize::new(9isize);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:21:13\n   |\nLL |     let _ = Mutex::new(&mut x as *mut u32);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _ = Mutex::new(&mut x as *mut u32);\nLL +     let _ = std::sync::atomic::AtomicPtr::new(&mut x as *mut u32);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:24:13\n   |\nLL |     let _ = Mutex::new(0u32);\n   |             ^^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\n   = note: `-D clippy::mutex-integer` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mutex_integer)]`\nhelp: try\n   |\nLL -     let _ = Mutex::new(0u32);\nLL +     let _ = std::sync::atomic::AtomicU32::new(0u32);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:27:13\n   |\nLL |     let _ = Mutex::new(0i32);\n   |             ^^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _ = Mutex::new(0i32);\nLL +     let _ = std::sync::atomic::AtomicI32::new(0i32);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:31:13\n   |\nLL |     let _ = Mutex::new(0u8);\n   |             ^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _ = Mutex::new(0u8);\nLL +     let _ = std::sync::atomic::AtomicU8::new(0u8);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:34:13\n   |\nLL |     let _ = Mutex::new(0i16);\n   |             ^^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _ = Mutex::new(0i16);\nLL +     let _ = std::sync::atomic::AtomicI16::new(0i16);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:37:25\n   |\nLL |     let _x: Mutex<i8> = Mutex::new(0);\n   |                         ^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _x: Mutex<i8> = Mutex::new(0);\nLL +     let _x = std::sync::atomic::AtomicI8::new(0);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:41:13\n   |\nLL |     let _ = Mutex::new(X);\n   |             ^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _ = Mutex::new(X);\nLL +     let _ = std::sync::atomic::AtomicI64::new(X);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:53:30\n   |\nLL |     static MTX: Mutex<u32> = Mutex::new(0);\n   |                              ^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     static MTX: Mutex<u32> = Mutex::new(0);\nLL +     static MTX: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:56:15\n   |\nLL |     let mtx = Mutex::new(0);\n   |               ^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let mtx = Mutex::new(0);\nLL +     let mtx = std::sync::atomic::AtomicI32::new(0);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:60:22\n   |\nLL |     let reassigned = mtx;\n   |                      ^^^\n   |\n   = help: consider using an `AtomicI32` instead\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:65:35\n   |\nLL |     let (funky_mtx): Mutex<u64> = Mutex::new(0);\n   |                                   ^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let (funky_mtx): Mutex<u64> = Mutex::new(0);\nLL +     let (funky_mtx) = std::sync::atomic::AtomicU64::new(0);\n   |\n\nerror: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic.rs:76:13\n   |\nLL |     let _ = Mutex::new(test_expr!(1));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\nhelp: try\n   |\nLL -     let _ = Mutex::new(test_expr!(1));\nLL +     let _ = std::sync::atomic::AtomicBool::new(test_expr!(1));\n   |\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/mutex_atomic_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::mutex_atomic, clippy::mutex_integer)]\n\nuse std::sync::Mutex;\n\nfn issue13378() {\n    static MTX: Mutex<u32> = Mutex::new(0);\n    //~^ mutex_integer\n\n    // unfixable because we don't fix this `lock`\n    let mut guard = MTX.lock().unwrap();\n    *guard += 1;\n}\n"
  },
  {
    "path": "tests/ui/mutex_atomic_unfixable.stderr",
    "content": "error: using a `Mutex` where an atomic would do\n  --> tests/ui/mutex_atomic_unfixable.rs:7:30\n   |\nLL |     static MTX: Mutex<u32> = Mutex::new(0);\n   |                              ^^^^^^^^^^^^^\n   |\n   = help: if you just want the locking behavior and not the internal type, consider using `Mutex<()>`\n   = note: `-D clippy::mutex-integer` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mutex_integer)]`\nhelp: try\n   |\nLL -     static MTX: Mutex<u32> = Mutex::new(0);\nLL +     static MTX: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/needless_arbitrary_self_type.fixed",
    "content": "#![warn(clippy::needless_arbitrary_self_type)]\n#![allow(unused_mut, clippy::needless_lifetimes)]\n\npub enum ValType {\n    A,\n    B,\n}\n\nimpl ValType {\n    pub fn bad(self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn good(self) {\n        unimplemented!();\n    }\n\n    pub fn mut_bad(mut self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn mut_good(mut self) {\n        unimplemented!();\n    }\n\n    pub fn ref_bad(&self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn ref_good(&self) {\n        unimplemented!();\n    }\n\n    pub fn ref_bad_with_lifetime<'a>(&'a self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn ref_good_with_lifetime<'a>(&'a self) {\n        unimplemented!();\n    }\n\n    pub fn mut_ref_bad(&mut self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn mut_ref_good(&mut self) {\n        unimplemented!();\n    }\n\n    pub fn mut_ref_bad_with_lifetime<'a>(&'a mut self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn mut_ref_good_with_lifetime<'a>(&'a mut self) {\n        unimplemented!();\n    }\n\n    pub fn mut_ref_mut_good(mut self: &mut Self) {\n        unimplemented!();\n    }\n\n    pub fn mut_ref_mut_ref_good(self: &&mut &mut Self) {\n        unimplemented!();\n    }\n}\n\ntrait Foo<'r#struct> {\n    fn f1(&'r#struct self) {}\n    //~^ needless_arbitrary_self_type\n    fn f2(&'r#struct mut self) {}\n    //~^ needless_arbitrary_self_type\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_arbitrary_self_type.rs",
    "content": "#![warn(clippy::needless_arbitrary_self_type)]\n#![allow(unused_mut, clippy::needless_lifetimes)]\n\npub enum ValType {\n    A,\n    B,\n}\n\nimpl ValType {\n    pub fn bad(self: Self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn good(self) {\n        unimplemented!();\n    }\n\n    pub fn mut_bad(mut self: Self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn mut_good(mut self) {\n        unimplemented!();\n    }\n\n    pub fn ref_bad(self: &Self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn ref_good(&self) {\n        unimplemented!();\n    }\n\n    pub fn ref_bad_with_lifetime<'a>(self: &'a Self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn ref_good_with_lifetime<'a>(&'a self) {\n        unimplemented!();\n    }\n\n    pub fn mut_ref_bad(self: &mut Self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn mut_ref_good(&mut self) {\n        unimplemented!();\n    }\n\n    pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) {\n        //~^ needless_arbitrary_self_type\n        unimplemented!();\n    }\n\n    pub fn mut_ref_good_with_lifetime<'a>(&'a mut self) {\n        unimplemented!();\n    }\n\n    pub fn mut_ref_mut_good(mut self: &mut Self) {\n        unimplemented!();\n    }\n\n    pub fn mut_ref_mut_ref_good(self: &&mut &mut Self) {\n        unimplemented!();\n    }\n}\n\ntrait Foo<'r#struct> {\n    fn f1(self: &'r#struct Self) {}\n    //~^ needless_arbitrary_self_type\n    fn f2(self: &'r#struct mut Self) {}\n    //~^ needless_arbitrary_self_type\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_arbitrary_self_type.stderr",
    "content": "error: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type.rs:10:16\n   |\nLL |     pub fn bad(self: Self) {\n   |                ^^^^^^^^^^\n   |\n   = note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_arbitrary_self_type)]`\nhelp: remove the type\n   |\nLL -     pub fn bad(self: Self) {\nLL +     pub fn bad(self) {\n   |\n\nerror: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type.rs:19:20\n   |\nLL |     pub fn mut_bad(mut self: Self) {\n   |                    ^^^^^^^^^^^^^^\n   |\nhelp: remove the type\n   |\nLL -     pub fn mut_bad(mut self: Self) {\nLL +     pub fn mut_bad(mut self) {\n   |\n\nerror: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type.rs:28:20\n   |\nLL |     pub fn ref_bad(self: &Self) {\n   |                    ^^^^^^^^^^^\n   |\nhelp: remove the type\n   |\nLL -     pub fn ref_bad(self: &Self) {\nLL +     pub fn ref_bad(&self) {\n   |\n\nerror: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type.rs:37:38\n   |\nLL |     pub fn ref_bad_with_lifetime<'a>(self: &'a Self) {\n   |                                      ^^^^^^^^^^^^^^\n   |\nhelp: remove the type\n   |\nLL -     pub fn ref_bad_with_lifetime<'a>(self: &'a Self) {\nLL +     pub fn ref_bad_with_lifetime<'a>(&'a self) {\n   |\n\nerror: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type.rs:46:24\n   |\nLL |     pub fn mut_ref_bad(self: &mut Self) {\n   |                        ^^^^^^^^^^^^^^^\n   |\nhelp: remove the type\n   |\nLL -     pub fn mut_ref_bad(self: &mut Self) {\nLL +     pub fn mut_ref_bad(&mut self) {\n   |\n\nerror: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type.rs:55:42\n   |\nLL |     pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) {\n   |                                          ^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the type\n   |\nLL -     pub fn mut_ref_bad_with_lifetime<'a>(self: &'a mut Self) {\nLL +     pub fn mut_ref_bad_with_lifetime<'a>(&'a mut self) {\n   |\n\nerror: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type.rs:74:11\n   |\nLL |     fn f1(self: &'r#struct Self) {}\n   |           ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the type\n   |\nLL -     fn f1(self: &'r#struct Self) {}\nLL +     fn f1(&'r#struct self) {}\n   |\n\nerror: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type.rs:76:11\n   |\nLL |     fn f2(self: &'r#struct mut Self) {}\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the type\n   |\nLL -     fn f2(self: &'r#struct mut Self) {}\nLL +     fn f2(&'r#struct mut self) {}\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_arbitrary_self_type_unfixable.fixed",
    "content": "//@aux-build:proc_macro_attr.rs\n\n#![warn(clippy::needless_arbitrary_self_type)]\n\n#[macro_use]\nextern crate proc_macro_attr;\n\nmod issue_6089 {\n    // Check that we don't lint if the `self` parameter comes from expansion\n\n    macro_rules! test_from_expansion {\n        () => {\n            trait T1 {\n                fn test(self: &Self);\n            }\n\n            struct S1;\n\n            impl T1 for S1 {\n                fn test(self: &Self) {}\n            }\n        };\n    }\n\n    test_from_expansion!();\n\n    // If only the lifetime name comes from expansion we will lint, but the suggestion will have\n    // placeholders and will not be applied automatically, as we can't reliably know the original name.\n    // This specific case happened with async_trait.\n\n    trait T2 {\n        fn call_with_mut_self(&mut self);\n    }\n\n    struct S2;\n\n    // The method's signature will be expanded to:\n    //  fn call_with_mut_self<'life0>(self: &'life0 mut Self) {}\n    #[rename_my_lifetimes]\n    impl T2 for S2 {\n        #[allow(clippy::needless_lifetimes)]\n        fn call_with_mut_self(&mut self) {}\n        //~^ needless_arbitrary_self_type\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_arbitrary_self_type_unfixable.rs",
    "content": "//@aux-build:proc_macro_attr.rs\n\n#![warn(clippy::needless_arbitrary_self_type)]\n\n#[macro_use]\nextern crate proc_macro_attr;\n\nmod issue_6089 {\n    // Check that we don't lint if the `self` parameter comes from expansion\n\n    macro_rules! test_from_expansion {\n        () => {\n            trait T1 {\n                fn test(self: &Self);\n            }\n\n            struct S1;\n\n            impl T1 for S1 {\n                fn test(self: &Self) {}\n            }\n        };\n    }\n\n    test_from_expansion!();\n\n    // If only the lifetime name comes from expansion we will lint, but the suggestion will have\n    // placeholders and will not be applied automatically, as we can't reliably know the original name.\n    // This specific case happened with async_trait.\n\n    trait T2 {\n        fn call_with_mut_self(&mut self);\n    }\n\n    struct S2;\n\n    // The method's signature will be expanded to:\n    //  fn call_with_mut_self<'life0>(self: &'life0 mut Self) {}\n    #[rename_my_lifetimes]\n    impl T2 for S2 {\n        #[allow(clippy::needless_lifetimes)]\n        fn call_with_mut_self(self: &mut Self) {}\n        //~^ needless_arbitrary_self_type\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_arbitrary_self_type_unfixable.stderr",
    "content": "error: the type of the `self` parameter does not need to be arbitrary\n  --> tests/ui/needless_arbitrary_self_type_unfixable.rs:42:31\n   |\nLL |         fn call_with_mut_self(self: &mut Self) {}\n   |                               ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_arbitrary_self_type)]`\nhelp: remove the type\n   |\nLL -         fn call_with_mut_self(self: &mut Self) {}\nLL +         fn call_with_mut_self(&mut self) {}\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/needless_as_bytes.fixed",
    "content": "#![warn(clippy::needless_as_bytes)]\n#![allow(clippy::const_is_empty)]\n#![feature(exact_size_is_empty)]\n\nstruct S;\n\nimpl S {\n    fn as_bytes(&self) -> &[u8] {\n        &[]\n    }\n    fn bytes(&self) -> &[u8] {\n        &[]\n    }\n}\n\nfn main() {\n    if \"some string\".is_empty() {\n        //~^ needless_as_bytes\n\n        println!(\"len = {}\", \"some string\".len());\n        //~^ needless_as_bytes\n    }\n    if \"some string\".is_empty() {\n        //~^ needless_as_bytes\n\n        println!(\"len = {}\", \"some string\".len());\n        //~^ needless_as_bytes\n    }\n\n    let s = String::from(\"yet another string\");\n    if s.is_empty() {\n        //~^ needless_as_bytes\n\n        println!(\"len = {}\", s.len());\n        //~^ needless_as_bytes\n    }\n    if s.is_empty() {\n        //~^ needless_as_bytes\n\n        println!(\"len = {}\", s.len());\n        //~^ needless_as_bytes\n    }\n\n    // Do not lint\n    let _ = S.as_bytes().is_empty();\n    let _ = S.as_bytes().len();\n    let _ = (&String::new() as &dyn AsBytes).as_bytes().len();\n    macro_rules! m {\n        (1) => {\n            \"\"\n        };\n        (2) => {\n            \"\".as_bytes()\n        };\n    }\n    m!(1).as_bytes().len();\n    let _ = S.bytes().is_empty();\n    let _ = S.bytes().len();\n    let _ = (&String::new() as &dyn Bytes).bytes().len();\n    macro_rules! m {\n        (1) => {\n            \"\"\n        };\n        (2) => {\n            \"\".bytes()\n        };\n    }\n    m!(1).bytes().len();\n    m!(2).len();\n}\n\npub trait AsBytes {\n    fn as_bytes(&self) -> &[u8];\n}\n\nimpl AsBytes for String {\n    fn as_bytes(&self) -> &[u8] {\n        &[]\n    }\n}\n\npub trait Bytes {\n    fn bytes(&self) -> &[u8];\n}\n\nimpl Bytes for String {\n    fn bytes(&self) -> &[u8] {\n        &[]\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_as_bytes.rs",
    "content": "#![warn(clippy::needless_as_bytes)]\n#![allow(clippy::const_is_empty)]\n#![feature(exact_size_is_empty)]\n\nstruct S;\n\nimpl S {\n    fn as_bytes(&self) -> &[u8] {\n        &[]\n    }\n    fn bytes(&self) -> &[u8] {\n        &[]\n    }\n}\n\nfn main() {\n    if \"some string\".as_bytes().is_empty() {\n        //~^ needless_as_bytes\n\n        println!(\"len = {}\", \"some string\".as_bytes().len());\n        //~^ needless_as_bytes\n    }\n    if \"some string\".bytes().is_empty() {\n        //~^ needless_as_bytes\n\n        println!(\"len = {}\", \"some string\".bytes().len());\n        //~^ needless_as_bytes\n    }\n\n    let s = String::from(\"yet another string\");\n    if s.as_bytes().is_empty() {\n        //~^ needless_as_bytes\n\n        println!(\"len = {}\", s.as_bytes().len());\n        //~^ needless_as_bytes\n    }\n    if s.bytes().is_empty() {\n        //~^ needless_as_bytes\n\n        println!(\"len = {}\", s.bytes().len());\n        //~^ needless_as_bytes\n    }\n\n    // Do not lint\n    let _ = S.as_bytes().is_empty();\n    let _ = S.as_bytes().len();\n    let _ = (&String::new() as &dyn AsBytes).as_bytes().len();\n    macro_rules! m {\n        (1) => {\n            \"\"\n        };\n        (2) => {\n            \"\".as_bytes()\n        };\n    }\n    m!(1).as_bytes().len();\n    let _ = S.bytes().is_empty();\n    let _ = S.bytes().len();\n    let _ = (&String::new() as &dyn Bytes).bytes().len();\n    macro_rules! m {\n        (1) => {\n            \"\"\n        };\n        (2) => {\n            \"\".bytes()\n        };\n    }\n    m!(1).bytes().len();\n    m!(2).len();\n}\n\npub trait AsBytes {\n    fn as_bytes(&self) -> &[u8];\n}\n\nimpl AsBytes for String {\n    fn as_bytes(&self) -> &[u8] {\n        &[]\n    }\n}\n\npub trait Bytes {\n    fn bytes(&self) -> &[u8];\n}\n\nimpl Bytes for String {\n    fn bytes(&self) -> &[u8] {\n        &[]\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_as_bytes.stderr",
    "content": "error: needless call to `as_bytes`\n  --> tests/ui/needless_as_bytes.rs:17:8\n   |\nLL |     if \"some string\".as_bytes().is_empty() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `\"some string\".is_empty()`\n   |\n   = note: `-D clippy::needless-as-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_as_bytes)]`\n\nerror: needless call to `as_bytes`\n  --> tests/ui/needless_as_bytes.rs:20:30\n   |\nLL |         println!(\"len = {}\", \"some string\".as_bytes().len());\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `\"some string\".len()`\n\nerror: needless call to `bytes`\n  --> tests/ui/needless_as_bytes.rs:23:8\n   |\nLL |     if \"some string\".bytes().is_empty() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `\"some string\".is_empty()`\n\nerror: needless call to `bytes`\n  --> tests/ui/needless_as_bytes.rs:26:30\n   |\nLL |         println!(\"len = {}\", \"some string\".bytes().len());\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `\"some string\".len()`\n\nerror: needless call to `as_bytes`\n  --> tests/ui/needless_as_bytes.rs:31:8\n   |\nLL |     if s.as_bytes().is_empty() {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()`\n\nerror: needless call to `as_bytes`\n  --> tests/ui/needless_as_bytes.rs:34:30\n   |\nLL |         println!(\"len = {}\", s.as_bytes().len());\n   |                              ^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()`\n\nerror: needless call to `bytes`\n  --> tests/ui/needless_as_bytes.rs:37:8\n   |\nLL |     if s.bytes().is_empty() {\n   |        ^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()`\n\nerror: needless call to `bytes`\n  --> tests/ui/needless_as_bytes.rs:40:30\n   |\nLL |         println!(\"len = {}\", s.bytes().len());\n   |                              ^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_bitwise_bool.fixed",
    "content": "#![warn(clippy::needless_bitwise_bool)]\n#![allow(clippy::const_is_empty)]\n\nfn returns_bool() -> bool {\n    true\n}\n\nconst fn const_returns_bool() -> bool {\n    false\n}\n\nfn main() {\n    let (x, y) = (false, true);\n    if x & y {\n        println!(\"true\")\n    }\n    if returns_bool() & x {\n        println!(\"true\")\n    }\n    if !returns_bool() & returns_bool() {\n        println!(\"true\")\n    }\n    if y && !x {\n        //~^ needless_bitwise_bool\n        println!(\"true\")\n    }\n\n    // BELOW: lints we hope to catch as `Expr::can_have_side_effects` improves.\n    if y & !const_returns_bool() {\n        println!(\"true\") // This is a const function, in an UnOp\n    }\n\n    if y & \"abcD\".is_empty() {\n        println!(\"true\") // This is a const method call\n    }\n\n    // Resolved\n    if y && (0 < 1) {\n        //~^ needless_bitwise_bool\n        println!(\"true\") // This is a BinOp with no side effects\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_bitwise_bool.rs",
    "content": "#![warn(clippy::needless_bitwise_bool)]\n#![allow(clippy::const_is_empty)]\n\nfn returns_bool() -> bool {\n    true\n}\n\nconst fn const_returns_bool() -> bool {\n    false\n}\n\nfn main() {\n    let (x, y) = (false, true);\n    if x & y {\n        println!(\"true\")\n    }\n    if returns_bool() & x {\n        println!(\"true\")\n    }\n    if !returns_bool() & returns_bool() {\n        println!(\"true\")\n    }\n    if y & !x {\n        //~^ needless_bitwise_bool\n        println!(\"true\")\n    }\n\n    // BELOW: lints we hope to catch as `Expr::can_have_side_effects` improves.\n    if y & !const_returns_bool() {\n        println!(\"true\") // This is a const function, in an UnOp\n    }\n\n    if y & \"abcD\".is_empty() {\n        println!(\"true\") // This is a const method call\n    }\n\n    // Resolved\n    if y & (0 < 1) {\n        //~^ needless_bitwise_bool\n        println!(\"true\") // This is a BinOp with no side effects\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_bitwise_bool.stderr",
    "content": "error: use of bitwise operator instead of lazy operator between booleans\n  --> tests/ui/needless_bitwise_bool.rs:23:8\n   |\nLL |     if y & !x {\n   |        ^^^^^^ help: try: `y && !x`\n   |\n   = note: `-D clippy::needless-bitwise-bool` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_bitwise_bool)]`\n\nerror: use of bitwise operator instead of lazy operator between booleans\n  --> tests/ui/needless_bitwise_bool.rs:38:8\n   |\nLL |     if y & (0 < 1) {\n   |        ^^^^^^^^^^^ help: try: `y && (0 < 1)`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_bool/fixable.fixed",
    "content": "#![warn(clippy::needless_bool)]\n#![allow(\n    unused,\n    dead_code,\n    clippy::no_effect,\n    clippy::if_same_then_else,\n    clippy::equatable_if_let,\n    clippy::needless_ifs,\n    clippy::needless_return,\n    clippy::self_named_constructors,\n    clippy::struct_field_names\n)]\n\nuse std::cell::Cell;\n\nmacro_rules! bool_comparison_trigger {\n    ($($i:ident: $def:expr, $stb:expr );+  $(;)*) => (\n\n        #[derive(Clone)]\n        pub struct Trigger {\n            $($i: (Cell<bool>, bool, bool)),+\n        }\n\n        #[allow(dead_code)]\n        impl Trigger {\n            pub fn trigger(&self, key: &str) -> bool {\n                $(\n                    if let stringify!($i) = key {\n                        return self.$i.1 && self.$i.2 == $def;\n                    }\n                 )+\n                false\n            }\n        }\n    )\n}\n\nfn main() {\n    let x = true;\n    let y = false;\n    x;\n    //~^^^^^ needless_bool\n    !x;\n    //~^^^^^ needless_bool\n    !(x && y);\n    //~^^^^^ needless_bool\n    let a = 0;\n    let b = 1;\n\n    a != b;\n    //~^^^^^ needless_bool\n    a == b;\n    //~^^^^^ needless_bool\n    a >= b;\n    //~^^^^^ needless_bool\n    a > b;\n    //~^^^^^ needless_bool\n    a <= b;\n    //~^^^^^ needless_bool\n    a < b;\n    //~^^^^^ needless_bool\n    if x {\n        x\n    } else {\n        false\n    }; // would also be questionable, but we don't catch this yet\n    bool_ret3(x);\n    bool_ret4(x);\n    bool_ret5(x, x);\n    bool_ret6(x, x);\n    needless_bool(x);\n    needless_bool2(x);\n    needless_bool3(x);\n    needless_bool_condition();\n\n    if a == b {\n        true\n    } else {\n        // Do not lint as this comment might be important\n        false\n    };\n}\n\nfn bool_ret3(x: bool) -> bool {\n    return x;\n    //~^^^^^ needless_bool\n}\n\nfn bool_ret4(x: bool) -> bool {\n    return !x;\n    //~^^^^^ needless_bool\n}\n\nfn bool_ret5(x: bool, y: bool) -> bool {\n    return x && y;\n    //~^^^^^ needless_bool\n}\n\nfn bool_ret6(x: bool, y: bool) -> bool {\n    return !(x && y);\n    //~^^^^^ needless_bool\n}\n\nfn needless_bool(x: bool) {\n    if x {};\n    //~^ bool_comparison\n}\n\nfn needless_bool2(x: bool) {\n    if !x {};\n    //~^ bool_comparison\n}\n\nfn needless_bool3(x: bool) {\n    bool_comparison_trigger! {\n        test_one:   false, false;\n        test_three: false, false;\n        test_two:   true, true;\n    }\n\n    if x {};\n    //~^ bool_comparison\n    if !x {};\n    //~^ bool_comparison\n}\n\nfn needless_bool_in_the_suggestion_wraps_the_predicate_of_if_else_statement_in_brackets() {\n    let b = false;\n    let returns_bool = || false;\n\n    let x = if b {\n        true\n    } else { !returns_bool() };\n    //~^^^^^ needless_bool\n}\n\nunsafe fn no(v: u8) -> u8 {\n    v\n}\n\n#[allow(clippy::unnecessary_operation)]\nfn needless_bool_condition() -> bool {\n    (unsafe { no(4) } & 1 != 0);\n    //~^^^^^ needless_bool\n    let _brackets_unneeded = unsafe { no(4) } & 1 != 0;\n    //~^ needless_bool\n    fn foo() -> bool {\n        // parentheses are needed here\n        (unsafe { no(4) } & 1 != 0)\n        //~^ needless_bool\n    }\n\n    foo()\n}\n\nfn issue12846() {\n    let a = true;\n    let b = false;\n\n    // parentheses are needed here\n    let _x = (a && b).then(|| todo!());\n    //~^ needless_bool\n    let _x = (a && b) as u8;\n    //~^ needless_bool\n\n    // parentheses are not needed here\n    let _x = a.then(|| todo!());\n    //~^ needless_bool\n}\n"
  },
  {
    "path": "tests/ui/needless_bool/fixable.rs",
    "content": "#![warn(clippy::needless_bool)]\n#![allow(\n    unused,\n    dead_code,\n    clippy::no_effect,\n    clippy::if_same_then_else,\n    clippy::equatable_if_let,\n    clippy::needless_ifs,\n    clippy::needless_return,\n    clippy::self_named_constructors,\n    clippy::struct_field_names\n)]\n\nuse std::cell::Cell;\n\nmacro_rules! bool_comparison_trigger {\n    ($($i:ident: $def:expr, $stb:expr );+  $(;)*) => (\n\n        #[derive(Clone)]\n        pub struct Trigger {\n            $($i: (Cell<bool>, bool, bool)),+\n        }\n\n        #[allow(dead_code)]\n        impl Trigger {\n            pub fn trigger(&self, key: &str) -> bool {\n                $(\n                    if let stringify!($i) = key {\n                        return self.$i.1 && self.$i.2 == $def;\n                    }\n                 )+\n                false\n            }\n        }\n    )\n}\n\nfn main() {\n    let x = true;\n    let y = false;\n    if x {\n        true\n    } else {\n        false\n    };\n    //~^^^^^ needless_bool\n    if x {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    if x && y {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    let a = 0;\n    let b = 1;\n\n    if a == b {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    if a != b {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    if a < b {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    if a <= b {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    if a > b {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    if a >= b {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    if x {\n        x\n    } else {\n        false\n    }; // would also be questionable, but we don't catch this yet\n    bool_ret3(x);\n    bool_ret4(x);\n    bool_ret5(x, x);\n    bool_ret6(x, x);\n    needless_bool(x);\n    needless_bool2(x);\n    needless_bool3(x);\n    needless_bool_condition();\n\n    if a == b {\n        true\n    } else {\n        // Do not lint as this comment might be important\n        false\n    };\n}\n\nfn bool_ret3(x: bool) -> bool {\n    if x {\n        return true;\n    } else {\n        return false;\n    };\n    //~^^^^^ needless_bool\n}\n\nfn bool_ret4(x: bool) -> bool {\n    if x {\n        return false;\n    } else {\n        return true;\n    };\n    //~^^^^^ needless_bool\n}\n\nfn bool_ret5(x: bool, y: bool) -> bool {\n    if x && y {\n        return true;\n    } else {\n        return false;\n    };\n    //~^^^^^ needless_bool\n}\n\nfn bool_ret6(x: bool, y: bool) -> bool {\n    if x && y {\n        return false;\n    } else {\n        return true;\n    };\n    //~^^^^^ needless_bool\n}\n\nfn needless_bool(x: bool) {\n    if x == true {};\n    //~^ bool_comparison\n}\n\nfn needless_bool2(x: bool) {\n    if x == false {};\n    //~^ bool_comparison\n}\n\nfn needless_bool3(x: bool) {\n    bool_comparison_trigger! {\n        test_one:   false, false;\n        test_three: false, false;\n        test_two:   true, true;\n    }\n\n    if x == true {};\n    //~^ bool_comparison\n    if x == false {};\n    //~^ bool_comparison\n}\n\nfn needless_bool_in_the_suggestion_wraps_the_predicate_of_if_else_statement_in_brackets() {\n    let b = false;\n    let returns_bool = || false;\n\n    let x = if b {\n        true\n    } else if returns_bool() {\n        false\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n}\n\nunsafe fn no(v: u8) -> u8 {\n    v\n}\n\n#[allow(clippy::unnecessary_operation)]\nfn needless_bool_condition() -> bool {\n    if unsafe { no(4) } & 1 != 0 {\n        true\n    } else {\n        false\n    };\n    //~^^^^^ needless_bool\n    let _brackets_unneeded = if unsafe { no(4) } & 1 != 0 { true } else { false };\n    //~^ needless_bool\n    fn foo() -> bool {\n        // parentheses are needed here\n        if unsafe { no(4) } & 1 != 0 { true } else { false }\n        //~^ needless_bool\n    }\n\n    foo()\n}\n\nfn issue12846() {\n    let a = true;\n    let b = false;\n\n    // parentheses are needed here\n    let _x = if a && b { true } else { false }.then(|| todo!());\n    //~^ needless_bool\n    let _x = if a && b { true } else { false } as u8;\n    //~^ needless_bool\n\n    // parentheses are not needed here\n    let _x = if a { true } else { false }.then(|| todo!());\n    //~^ needless_bool\n}\n"
  },
  {
    "path": "tests/ui/needless_bool/fixable.stderr",
    "content": "error: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:41:5\n   |\nLL | /     if x {\nLL | |         true\nLL | |     } else {\nLL | |         false\nLL | |     };\n   | |_____^ help: you can reduce it to: `x`\n   |\n   = note: `-D clippy::needless-bool` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:47:5\n   |\nLL | /     if x {\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `!x`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:53:5\n   |\nLL | /     if x && y {\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `!(x && y)`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:62:5\n   |\nLL | /     if a == b {\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `a != b`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:68:5\n   |\nLL | /     if a != b {\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `a == b`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:74:5\n   |\nLL | /     if a < b {\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `a >= b`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:80:5\n   |\nLL | /     if a <= b {\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `a > b`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:86:5\n   |\nLL | /     if a > b {\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `a <= b`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:92:5\n   |\nLL | /     if a >= b {\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `a < b`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:121:5\n   |\nLL | /     if x {\nLL | |         return true;\nLL | |     } else {\nLL | |         return false;\nLL | |     };\n   | |_____^ help: you can reduce it to: `return x`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:130:5\n   |\nLL | /     if x {\nLL | |         return false;\nLL | |     } else {\nLL | |         return true;\nLL | |     };\n   | |_____^ help: you can reduce it to: `return !x`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:139:5\n   |\nLL | /     if x && y {\nLL | |         return true;\nLL | |     } else {\nLL | |         return false;\nLL | |     };\n   | |_____^ help: you can reduce it to: `return x && y`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:148:5\n   |\nLL | /     if x && y {\nLL | |         return false;\nLL | |     } else {\nLL | |         return true;\nLL | |     };\n   | |_____^ help: you can reduce it to: `return !(x && y)`\n\nerror: equality checks against true are unnecessary\n  --> tests/ui/needless_bool/fixable.rs:157:8\n   |\nLL |     if x == true {};\n   |        ^^^^^^^^^ help: try: `x`\n   |\n   = note: `-D clippy::bool-comparison` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`\n\nerror: equality checks against false can be replaced by a negation\n  --> tests/ui/needless_bool/fixable.rs:162:8\n   |\nLL |     if x == false {};\n   |        ^^^^^^^^^^ help: try: `!x`\n\nerror: equality checks against true are unnecessary\n  --> tests/ui/needless_bool/fixable.rs:173:8\n   |\nLL |     if x == true {};\n   |        ^^^^^^^^^ help: try: `x`\n\nerror: equality checks against false can be replaced by a negation\n  --> tests/ui/needless_bool/fixable.rs:175:8\n   |\nLL |     if x == false {};\n   |        ^^^^^^^^^^ help: try: `!x`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:185:12\n   |\nLL |       } else if returns_bool() {\n   |  ____________^\nLL | |         false\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^ help: you can reduce it to: `{ !returns_bool() }`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:199:5\n   |\nLL | /     if unsafe { no(4) } & 1 != 0 {\nLL | |         true\nLL | |     } else {\nLL | |         false\nLL | |     };\n   | |_____^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:205:30\n   |\nLL |     let _brackets_unneeded = if unsafe { no(4) } & 1 != 0 { true } else { false };\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `unsafe { no(4) } & 1 != 0`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:209:9\n   |\nLL |         if unsafe { no(4) } & 1 != 0 { true } else { false }\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:221:14\n   |\nLL |     let _x = if a && b { true } else { false }.then(|| todo!());\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:223:14\n   |\nLL |     let _x = if a && b { true } else { false } as u8;\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)`\n\nerror: this if-then-else expression returns a bool literal\n  --> tests/ui/needless_bool/fixable.rs:227:14\n   |\nLL |     let _x = if a { true } else { false }.then(|| todo!());\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `a`\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_bool/simple.rs",
    "content": "#![warn(clippy::needless_bool)]\n#![allow(\n    unused,\n    dead_code,\n    clippy::no_effect,\n    clippy::if_same_then_else,\n    clippy::needless_return,\n    clippy::branches_sharing_code\n)]\n\nfn main() {\n    let x = true;\n    let y = false;\n    if x {\n        true\n    } else {\n        true\n    };\n    //~^^^^^ needless_bool\n    if x {\n        false\n    } else {\n        false\n    };\n    //~^^^^^ needless_bool\n    if x {\n        x\n    } else {\n        false\n    }; // would also be questionable, but we don't catch this yet\n    bool_ret(x);\n    bool_ret2(x);\n}\n\nfn bool_ret(x: bool) -> bool {\n    if x {\n        return true;\n    } else {\n        return true;\n    };\n    //~^^^^^ needless_bool\n}\n\nfn bool_ret2(x: bool) -> bool {\n    if x {\n        return false;\n    } else {\n        return false;\n    };\n    //~^^^^^ needless_bool\n}\n"
  },
  {
    "path": "tests/ui/needless_bool/simple.stderr",
    "content": "error: this if-then-else expression will always return true\n  --> tests/ui/needless_bool/simple.rs:14:5\n   |\nLL | /     if x {\nLL | |         true\nLL | |     } else {\nLL | |         true\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::needless-bool` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_bool)]`\n\nerror: this if-then-else expression will always return false\n  --> tests/ui/needless_bool/simple.rs:20:5\n   |\nLL | /     if x {\nLL | |         false\nLL | |     } else {\nLL | |         false\nLL | |     };\n   | |_____^\n\nerror: this if-then-else expression will always return true\n  --> tests/ui/needless_bool/simple.rs:36:5\n   |\nLL | /     if x {\nLL | |         return true;\nLL | |     } else {\nLL | |         return true;\nLL | |     };\n   | |_____^\n\nerror: this if-then-else expression will always return false\n  --> tests/ui/needless_bool/simple.rs:45:5\n   |\nLL | /     if x {\nLL | |         return false;\nLL | |     } else {\nLL | |         return false;\nLL | |     };\n   | |_____^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_bool_assign.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::needless_bool_assign)]\n\nfn random() -> bool {\n    true\n}\n\nfn main() {\n    struct Data {\n        field: bool,\n    };\n    let mut a = Data { field: false };\n    a.field = random() && random();\n    //~^^^^^ needless_bool_assign\n    a.field = !(random() && random());\n    //~^^^^^ needless_bool_assign\n    // Do not lint…\n    if random() {\n        a.field = false;\n    } else {\n        // …to avoid losing this comment\n        a.field = true\n    }\n    // This one also triggers lint `clippy::if_same_then_else`\n    // which does not suggest a rewrite.\n    random(); a.field = true;\n    //~^^^^^ if_same_then_else\n    //~| needless_bool_assign\n    let mut b = false;\n    if random() {\n        a.field = false;\n    } else {\n        b = true;\n    }\n}\n\nfn issue15063(x: bool, y: bool) {\n    let mut z = false;\n\n    if x && y {\n        todo!()\n    } else { z = x || y; }\n    //~^^^^^ needless_bool_assign\n}\n\nfn wrongly_unmangled_macros(must_keep: fn(usize, usize) -> bool, x: usize, y: usize) {\n    struct Wrapper<T>(T);\n    let mut skip = Wrapper(false);\n\n    macro_rules! invoke {\n        ($func:expr, $a:expr, $b:expr) => {\n            $func($a, $b)\n        };\n    }\n    macro_rules! dot_0 {\n        ($w:expr) => {\n            $w.0\n        };\n    }\n\n    dot_0!(skip) = !invoke!(must_keep, x, y);\n    //~^^^^^ needless_bool_assign\n}\n"
  },
  {
    "path": "tests/ui/needless_bool_assign.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::needless_bool_assign)]\n\nfn random() -> bool {\n    true\n}\n\nfn main() {\n    struct Data {\n        field: bool,\n    };\n    let mut a = Data { field: false };\n    if random() && random() {\n        a.field = true;\n    } else {\n        a.field = false\n    }\n    //~^^^^^ needless_bool_assign\n    if random() && random() {\n        a.field = false;\n    } else {\n        a.field = true\n    }\n    //~^^^^^ needless_bool_assign\n    // Do not lint…\n    if random() {\n        a.field = false;\n    } else {\n        // …to avoid losing this comment\n        a.field = true\n    }\n    // This one also triggers lint `clippy::if_same_then_else`\n    // which does not suggest a rewrite.\n    if random() {\n        a.field = true;\n    } else {\n        a.field = true;\n    }\n    //~^^^^^ if_same_then_else\n    //~| needless_bool_assign\n    let mut b = false;\n    if random() {\n        a.field = false;\n    } else {\n        b = true;\n    }\n}\n\nfn issue15063(x: bool, y: bool) {\n    let mut z = false;\n\n    if x && y {\n        todo!()\n    } else if x || y {\n        z = true;\n    } else {\n        z = false;\n    }\n    //~^^^^^ needless_bool_assign\n}\n\nfn wrongly_unmangled_macros(must_keep: fn(usize, usize) -> bool, x: usize, y: usize) {\n    struct Wrapper<T>(T);\n    let mut skip = Wrapper(false);\n\n    macro_rules! invoke {\n        ($func:expr, $a:expr, $b:expr) => {\n            $func($a, $b)\n        };\n    }\n    macro_rules! dot_0 {\n        ($w:expr) => {\n            $w.0\n        };\n    }\n\n    if invoke!(must_keep, x, y) {\n        dot_0!(skip) = false;\n    } else {\n        dot_0!(skip) = true;\n    }\n    //~^^^^^ needless_bool_assign\n}\n"
  },
  {
    "path": "tests/ui/needless_bool_assign.stderr",
    "content": "error: this if-then-else expression assigns a bool literal\n  --> tests/ui/needless_bool_assign.rs:13:5\n   |\nLL | /     if random() && random() {\nLL | |         a.field = true;\nLL | |     } else {\nLL | |         a.field = false\nLL | |     }\n   | |_____^ help: you can reduce it to: `a.field = random() && random();`\n   |\n   = note: `-D clippy::needless-bool-assign` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_bool_assign)]`\n\nerror: this if-then-else expression assigns a bool literal\n  --> tests/ui/needless_bool_assign.rs:19:5\n   |\nLL | /     if random() && random() {\nLL | |         a.field = false;\nLL | |     } else {\nLL | |         a.field = true\nLL | |     }\n   | |_____^ help: you can reduce it to: `a.field = !(random() && random());`\n\nerror: this if-then-else expression assigns a bool literal\n  --> tests/ui/needless_bool_assign.rs:34:5\n   |\nLL | /     if random() {\nLL | |         a.field = true;\nLL | |     } else {\nLL | |         a.field = true;\nLL | |     }\n   | |_____^ help: you can reduce it to: `random(); a.field = true;`\n\nerror: this `if` has identical blocks\n  --> tests/ui/needless_bool_assign.rs:34:17\n   |\nLL |       if random() {\n   |  _________________^\nLL | |         a.field = true;\nLL | |     } else {\n   | |_____^\n   |\nnote: same as this\n  --> tests/ui/needless_bool_assign.rs:36:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         a.field = true;\nLL | |     }\n   | |_____^\n   = note: `-D clippy::if-same-then-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]`\n\nerror: this if-then-else expression assigns a bool literal\n  --> tests/ui/needless_bool_assign.rs:54:12\n   |\nLL |       } else if x || y {\n   |  ____________^\nLL | |         z = true;\nLL | |     } else {\nLL | |         z = false;\nLL | |     }\n   | |_____^ help: you can reduce it to: `{ z = x || y; }`\n\nerror: this if-then-else expression assigns a bool literal\n  --> tests/ui/needless_bool_assign.rs:77:5\n   |\nLL | /     if invoke!(must_keep, x, y) {\nLL | |         dot_0!(skip) = false;\nLL | |     } else {\nLL | |         dot_0!(skip) = true;\nLL | |     }\n   | |_____^ help: you can reduce it to: `dot_0!(skip) = !invoke!(must_keep, x, y);`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_borrow.fixed",
    "content": "#![allow(\n    unused,\n    non_local_definitions,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_mut_passed,\n    clippy::unnecessary_to_owned,\n    clippy::unnecessary_literal_unwrap,\n    clippy::needless_lifetimes\n)]\n#![warn(clippy::needless_borrow)]\n\nfn main() {\n    let a = 5;\n    let ref_a = &a;\n    let _ = x(&a); // no warning\n    let _ = x(&a); // warn\n    //\n    //~^^ needless_borrow\n\n    let mut b = 5;\n    mut_ref(&mut b); // no warning\n    mut_ref(&mut b); // warn\n    //\n    //~^^ needless_borrow\n\n    let s = &String::from(\"hi\");\n    let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not\n    let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]`\n    let vec = Vec::new();\n    let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]`\n    h(&\"foo\"); // should not error, because the `&&str` is required, due to `&Trait`\n    let garbl = match 42 {\n        44 => &a,\n        45 => {\n            println!(\"foo\");\n            &a\n            //~^ needless_borrow\n        },\n        46 => &a,\n        //~^ needless_borrow\n        47 => {\n            println!(\"foo\");\n            loop {\n                println!(\"{}\", a);\n                if a == 25 {\n                    break ref_a;\n                    //~^ needless_borrow\n                }\n            }\n        },\n        _ => panic!(),\n    };\n\n    let _ = x(&a);\n    //~^ needless_borrow\n    let _ = x(&a);\n    //~^ needless_borrow\n    let _ = x(&mut b);\n    //~^ needless_borrow\n    let _ = x(ref_a);\n    //~^ needless_borrow\n    {\n        let b = &mut b;\n        x(b);\n        //~^ needless_borrow\n    }\n\n    // Issue #8191\n    let mut x = 5;\n    let mut x = &mut x;\n\n    mut_ref(x);\n    //~^ needless_borrow\n    mut_ref(x);\n    //~^ needless_borrow\n    let y: &mut i32 = x;\n    //~^ needless_borrow\n    let y: &mut i32 = x;\n    //~^ needless_borrow\n\n    let y = match 0 {\n        // Don't lint. Removing the borrow would move 'x'\n        0 => &mut x,\n        _ => &mut *x,\n    };\n    let y: &mut i32 = match 0 {\n        // Lint here. The type given above triggers auto-borrow.\n        0 => x,\n        //~^ needless_borrow\n        _ => &mut *x,\n    };\n    fn ref_mut_i32(_: &mut i32) {}\n    ref_mut_i32(match 0 {\n        // Lint here. The type given above triggers auto-borrow.\n        0 => x,\n        //~^ needless_borrow\n        _ => &mut *x,\n    });\n    // use 'x' after to make sure it's still usable in the fixed code.\n    *x = 5;\n\n    let s = String::new();\n    // let _ = (&s).len();\n    // let _ = (&s).capacity();\n    // let _ = (&&s).capacity();\n\n    let x = (1, 2);\n    let _ = x.0;\n    //~^ needless_borrow\n\n    // Issue #8367\n    trait Foo {\n        fn foo(self);\n    }\n    impl Foo for &'_ () {\n        fn foo(self) {}\n    }\n    (&()).foo(); // Don't lint. `()` doesn't implement `Foo`\n    (&()).foo();\n    //~^ needless_borrow\n\n    impl Foo for i32 {\n        fn foo(self) {}\n    }\n    impl Foo for &'_ i32 {\n        fn foo(self) {}\n    }\n    (&5).foo(); // Don't lint. `5` will call `<i32 as Foo>::foo`\n    (&5).foo();\n    //~^ needless_borrow\n\n    trait FooRef {\n        fn foo_ref(&self);\n    }\n    impl FooRef for () {\n        fn foo_ref(&self) {}\n    }\n    impl FooRef for &'_ () {\n        fn foo_ref(&self) {}\n    }\n    (&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref`\n\n    struct S;\n    impl From<S> for u32 {\n        fn from(s: S) -> Self {\n            (&s).into()\n        }\n    }\n    impl From<&S> for u32 {\n        fn from(s: &S) -> Self {\n            0\n        }\n    }\n\n    // issue #11786\n    let x: (&str,) = (\"\",);\n    //~^ needless_borrow\n}\n\n#[allow(clippy::needless_borrowed_reference)]\nfn x(y: &i32) -> i32 {\n    *y\n}\n\nfn mut_ref(y: &mut i32) {\n    *y = 5;\n}\n\nfn f<T: Copy>(y: &T) -> T {\n    *y\n}\n\nfn g(y: &[u8]) -> u8 {\n    y[0]\n}\n\ntrait Trait {}\n\nimpl<'a> Trait for &'a str {}\n\nfn h(_: &dyn Trait) {}\n\nfn check_expect_suppression() {\n    let a = 5;\n    #[expect(clippy::needless_borrow)]\n    let _ = x(&&a);\n}\n\nmod issue9160 {\n    pub struct S<F> {\n        f: F,\n    }\n\n    impl<T, F> S<F>\n    where\n        F: Fn() -> T,\n    {\n        fn calls_field(&self) -> T {\n            (self.f)()\n            //~^ needless_borrow\n        }\n    }\n\n    impl<T, F> S<F>\n    where\n        F: FnMut() -> T,\n    {\n        fn calls_mut_field(&mut self) -> T {\n            (self.f)()\n            //~^ needless_borrow\n        }\n    }\n}\n\nfn issue9383() {\n    // Should not lint because unions need explicit deref when accessing field\n    use std::mem::ManuallyDrop;\n\n    #[derive(Clone, Copy)]\n    struct Wrap<T>(T);\n    impl<T> core::ops::Deref for Wrap<T> {\n        type Target = T;\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for Wrap<T> {\n        fn deref_mut(&mut self) -> &mut T {\n            &mut self.0\n        }\n    }\n\n    union U<T: Copy> {\n        u: T,\n    }\n\n    #[derive(Clone, Copy)]\n    struct Foo {\n        x: u32,\n    }\n\n    unsafe {\n        let mut x = U {\n            u: ManuallyDrop::new(Foo { x: 0 }),\n        };\n        let _ = &mut (&mut x.u).x;\n        let _ = &mut { x.u }.x;\n        //~^ needless_borrow\n        let _ = &mut ({ &mut x.u }).x;\n\n        let mut x = U {\n            u: Wrap(ManuallyDrop::new(Foo { x: 0 })),\n        };\n        let _ = &mut (&mut x.u).x;\n        let _ = &mut { x.u }.x;\n        //~^ needless_borrow\n        let _ = &mut ({ &mut x.u }).x;\n\n        let mut x = U { u: Wrap(Foo { x: 0 }) };\n        let _ = &mut x.u.x;\n        //~^ needless_borrow\n        let _ = &mut { x.u }.x;\n        //~^ needless_borrow\n        let _ = &mut ({ &mut x.u }).x;\n    }\n}\n\nmod issue_10253 {\n    struct S;\n    trait X {\n        fn f<T>(&self);\n    }\n    impl X for &S {\n        fn f<T>(&self) {}\n    }\n    fn f() {\n        (&S).f::<()>();\n    }\n}\n\nfn issue_12268() {\n    let option = Some((&1,));\n    let x = (&1,);\n    option.unwrap_or((x.0,));\n    //~^ needless_borrow\n\n    // compiler\n}\n\nfn issue_14743<T>(slice: &[T]) {\n    let _ = slice.len();\n    //~^ needless_borrow\n\n    let slice = slice as *const [T];\n    let _ = unsafe { (&*slice).len() };\n\n    // Check that rustc would actually warn if Clippy had suggested removing the reference\n    #[expect(dangerous_implicit_autorefs)]\n    let _ = unsafe { (*slice).len() };\n}\n"
  },
  {
    "path": "tests/ui/needless_borrow.rs",
    "content": "#![allow(\n    unused,\n    non_local_definitions,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_mut_passed,\n    clippy::unnecessary_to_owned,\n    clippy::unnecessary_literal_unwrap,\n    clippy::needless_lifetimes\n)]\n#![warn(clippy::needless_borrow)]\n\nfn main() {\n    let a = 5;\n    let ref_a = &a;\n    let _ = x(&a); // no warning\n    let _ = x(&&a); // warn\n    //\n    //~^^ needless_borrow\n\n    let mut b = 5;\n    mut_ref(&mut b); // no warning\n    mut_ref(&mut &mut b); // warn\n    //\n    //~^^ needless_borrow\n\n    let s = &String::from(\"hi\");\n    let s_ident = f(&s); // should not error, because `&String` implements Copy, but `String` does not\n    let g_val = g(&Vec::new()); // should not error, because `&Vec<T>` derefs to `&[T]`\n    let vec = Vec::new();\n    let vec_val = g(&vec); // should not error, because `&Vec<T>` derefs to `&[T]`\n    h(&\"foo\"); // should not error, because the `&&str` is required, due to `&Trait`\n    let garbl = match 42 {\n        44 => &a,\n        45 => {\n            println!(\"foo\");\n            &&a\n            //~^ needless_borrow\n        },\n        46 => &&a,\n        //~^ needless_borrow\n        47 => {\n            println!(\"foo\");\n            loop {\n                println!(\"{}\", a);\n                if a == 25 {\n                    break &ref_a;\n                    //~^ needless_borrow\n                }\n            }\n        },\n        _ => panic!(),\n    };\n\n    let _ = x(&&&a);\n    //~^ needless_borrow\n    let _ = x(&mut &&a);\n    //~^ needless_borrow\n    let _ = x(&&&mut b);\n    //~^ needless_borrow\n    let _ = x(&&ref_a);\n    //~^ needless_borrow\n    {\n        let b = &mut b;\n        x(&b);\n        //~^ needless_borrow\n    }\n\n    // Issue #8191\n    let mut x = 5;\n    let mut x = &mut x;\n\n    mut_ref(&mut x);\n    //~^ needless_borrow\n    mut_ref(&mut &mut x);\n    //~^ needless_borrow\n    let y: &mut i32 = &mut x;\n    //~^ needless_borrow\n    let y: &mut i32 = &mut &mut x;\n    //~^ needless_borrow\n\n    let y = match 0 {\n        // Don't lint. Removing the borrow would move 'x'\n        0 => &mut x,\n        _ => &mut *x,\n    };\n    let y: &mut i32 = match 0 {\n        // Lint here. The type given above triggers auto-borrow.\n        0 => &mut x,\n        //~^ needless_borrow\n        _ => &mut *x,\n    };\n    fn ref_mut_i32(_: &mut i32) {}\n    ref_mut_i32(match 0 {\n        // Lint here. The type given above triggers auto-borrow.\n        0 => &mut x,\n        //~^ needless_borrow\n        _ => &mut *x,\n    });\n    // use 'x' after to make sure it's still usable in the fixed code.\n    *x = 5;\n\n    let s = String::new();\n    // let _ = (&s).len();\n    // let _ = (&s).capacity();\n    // let _ = (&&s).capacity();\n\n    let x = (1, 2);\n    let _ = (&x).0;\n    //~^ needless_borrow\n\n    // Issue #8367\n    trait Foo {\n        fn foo(self);\n    }\n    impl Foo for &'_ () {\n        fn foo(self) {}\n    }\n    (&()).foo(); // Don't lint. `()` doesn't implement `Foo`\n    (&&()).foo();\n    //~^ needless_borrow\n\n    impl Foo for i32 {\n        fn foo(self) {}\n    }\n    impl Foo for &'_ i32 {\n        fn foo(self) {}\n    }\n    (&5).foo(); // Don't lint. `5` will call `<i32 as Foo>::foo`\n    (&&5).foo();\n    //~^ needless_borrow\n\n    trait FooRef {\n        fn foo_ref(&self);\n    }\n    impl FooRef for () {\n        fn foo_ref(&self) {}\n    }\n    impl FooRef for &'_ () {\n        fn foo_ref(&self) {}\n    }\n    (&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref`\n\n    struct S;\n    impl From<S> for u32 {\n        fn from(s: S) -> Self {\n            (&s).into()\n        }\n    }\n    impl From<&S> for u32 {\n        fn from(s: &S) -> Self {\n            0\n        }\n    }\n\n    // issue #11786\n    let x: (&str,) = (&\"\",);\n    //~^ needless_borrow\n}\n\n#[allow(clippy::needless_borrowed_reference)]\nfn x(y: &i32) -> i32 {\n    *y\n}\n\nfn mut_ref(y: &mut i32) {\n    *y = 5;\n}\n\nfn f<T: Copy>(y: &T) -> T {\n    *y\n}\n\nfn g(y: &[u8]) -> u8 {\n    y[0]\n}\n\ntrait Trait {}\n\nimpl<'a> Trait for &'a str {}\n\nfn h(_: &dyn Trait) {}\n\nfn check_expect_suppression() {\n    let a = 5;\n    #[expect(clippy::needless_borrow)]\n    let _ = x(&&a);\n}\n\nmod issue9160 {\n    pub struct S<F> {\n        f: F,\n    }\n\n    impl<T, F> S<F>\n    where\n        F: Fn() -> T,\n    {\n        fn calls_field(&self) -> T {\n            (&self.f)()\n            //~^ needless_borrow\n        }\n    }\n\n    impl<T, F> S<F>\n    where\n        F: FnMut() -> T,\n    {\n        fn calls_mut_field(&mut self) -> T {\n            (&mut self.f)()\n            //~^ needless_borrow\n        }\n    }\n}\n\nfn issue9383() {\n    // Should not lint because unions need explicit deref when accessing field\n    use std::mem::ManuallyDrop;\n\n    #[derive(Clone, Copy)]\n    struct Wrap<T>(T);\n    impl<T> core::ops::Deref for Wrap<T> {\n        type Target = T;\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for Wrap<T> {\n        fn deref_mut(&mut self) -> &mut T {\n            &mut self.0\n        }\n    }\n\n    union U<T: Copy> {\n        u: T,\n    }\n\n    #[derive(Clone, Copy)]\n    struct Foo {\n        x: u32,\n    }\n\n    unsafe {\n        let mut x = U {\n            u: ManuallyDrop::new(Foo { x: 0 }),\n        };\n        let _ = &mut (&mut x.u).x;\n        let _ = &mut (&mut { x.u }).x;\n        //~^ needless_borrow\n        let _ = &mut ({ &mut x.u }).x;\n\n        let mut x = U {\n            u: Wrap(ManuallyDrop::new(Foo { x: 0 })),\n        };\n        let _ = &mut (&mut x.u).x;\n        let _ = &mut (&mut { x.u }).x;\n        //~^ needless_borrow\n        let _ = &mut ({ &mut x.u }).x;\n\n        let mut x = U { u: Wrap(Foo { x: 0 }) };\n        let _ = &mut (&mut x.u).x;\n        //~^ needless_borrow\n        let _ = &mut (&mut { x.u }).x;\n        //~^ needless_borrow\n        let _ = &mut ({ &mut x.u }).x;\n    }\n}\n\nmod issue_10253 {\n    struct S;\n    trait X {\n        fn f<T>(&self);\n    }\n    impl X for &S {\n        fn f<T>(&self) {}\n    }\n    fn f() {\n        (&S).f::<()>();\n    }\n}\n\nfn issue_12268() {\n    let option = Some((&1,));\n    let x = (&1,);\n    option.unwrap_or((&x.0,));\n    //~^ needless_borrow\n\n    // compiler\n}\n\nfn issue_14743<T>(slice: &[T]) {\n    let _ = (&slice).len();\n    //~^ needless_borrow\n\n    let slice = slice as *const [T];\n    let _ = unsafe { (&*slice).len() };\n\n    // Check that rustc would actually warn if Clippy had suggested removing the reference\n    #[expect(dangerous_implicit_autorefs)]\n    let _ = unsafe { (*slice).len() };\n}\n"
  },
  {
    "path": "tests/ui/needless_borrow.stderr",
    "content": "error: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:16:15\n   |\nLL |     let _ = x(&&a); // warn\n   |               ^^^ help: change this to: `&a`\n   |\n   = note: `-D clippy::needless-borrow` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:22:13\n   |\nLL |     mut_ref(&mut &mut b); // warn\n   |             ^^^^^^^^^^^ help: change this to: `&mut b`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:36:13\n   |\nLL |             &&a\n   |             ^^^ help: change this to: `&a`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:39:15\n   |\nLL |         46 => &&a,\n   |               ^^^ help: change this to: `&a`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:46:27\n   |\nLL |                     break &ref_a;\n   |                           ^^^^^^ help: change this to: `ref_a`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:54:15\n   |\nLL |     let _ = x(&&&a);\n   |               ^^^^ help: change this to: `&a`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:56:15\n   |\nLL |     let _ = x(&mut &&a);\n   |               ^^^^^^^^ help: change this to: `&a`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:58:15\n   |\nLL |     let _ = x(&&&mut b);\n   |               ^^^^^^^^ help: change this to: `&mut b`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:60:15\n   |\nLL |     let _ = x(&&ref_a);\n   |               ^^^^^^^ help: change this to: `ref_a`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:64:11\n   |\nLL |         x(&b);\n   |           ^^ help: change this to: `b`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:72:13\n   |\nLL |     mut_ref(&mut x);\n   |             ^^^^^^ help: change this to: `x`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:74:13\n   |\nLL |     mut_ref(&mut &mut x);\n   |             ^^^^^^^^^^^ help: change this to: `x`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:76:23\n   |\nLL |     let y: &mut i32 = &mut x;\n   |                       ^^^^^^ help: change this to: `x`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:78:23\n   |\nLL |     let y: &mut i32 = &mut &mut x;\n   |                       ^^^^^^^^^^^ help: change this to: `x`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:88:14\n   |\nLL |         0 => &mut x,\n   |              ^^^^^^ help: change this to: `x`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:95:14\n   |\nLL |         0 => &mut x,\n   |              ^^^^^^ help: change this to: `x`\n\nerror: this expression borrows a value the compiler would automatically borrow\n  --> tests/ui/needless_borrow.rs:108:13\n   |\nLL |     let _ = (&x).0;\n   |             ^^^^ help: change this to: `x`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:119:5\n   |\nLL |     (&&()).foo();\n   |     ^^^^^^ help: change this to: `(&())`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:129:5\n   |\nLL |     (&&5).foo();\n   |     ^^^^^ help: change this to: `(&5)`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:156:23\n   |\nLL |     let x: (&str,) = (&\"\",);\n   |                       ^^^ help: change this to: `\"\"`\n\nerror: this expression borrows a value the compiler would automatically borrow\n  --> tests/ui/needless_borrow.rs:199:13\n   |\nLL |             (&self.f)()\n   |             ^^^^^^^^^ help: change this to: `(self.f)`\n\nerror: this expression borrows a value the compiler would automatically borrow\n  --> tests/ui/needless_borrow.rs:209:13\n   |\nLL |             (&mut self.f)()\n   |             ^^^^^^^^^^^^^ help: change this to: `(self.f)`\n\nerror: this expression borrows a value the compiler would automatically borrow\n  --> tests/ui/needless_borrow.rs:247:22\n   |\nLL |         let _ = &mut (&mut { x.u }).x;\n   |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`\n\nerror: this expression borrows a value the compiler would automatically borrow\n  --> tests/ui/needless_borrow.rs:255:22\n   |\nLL |         let _ = &mut (&mut { x.u }).x;\n   |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`\n\nerror: this expression borrows a value the compiler would automatically borrow\n  --> tests/ui/needless_borrow.rs:260:22\n   |\nLL |         let _ = &mut (&mut x.u).x;\n   |                      ^^^^^^^^^^ help: change this to: `x.u`\n\nerror: this expression borrows a value the compiler would automatically borrow\n  --> tests/ui/needless_borrow.rs:262:22\n   |\nLL |         let _ = &mut (&mut { x.u }).x;\n   |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:284:23\n   |\nLL |     option.unwrap_or((&x.0,));\n   |                       ^^^^ help: change this to: `x.0`\n\nerror: this expression creates a reference which is immediately dereferenced by the compiler\n  --> tests/ui/needless_borrow.rs:291:13\n   |\nLL |     let _ = (&slice).len();\n   |             ^^^^^^^^ help: change this to: `slice`\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_borrow_pat.fixed",
    "content": "#![warn(clippy::needless_borrow)]\n#![allow(clippy::needless_borrowed_reference, clippy::explicit_auto_deref)]\n\nfn f1(_: &str) {}\nmacro_rules! m1 {\n    ($e:expr) => {\n        f1($e)\n    };\n}\nmacro_rules! m3 {\n    ($i:ident) => {\n        Some(ref $i)\n    };\n}\nmacro_rules! if_chain {\n    (if $e:expr; $($rest:tt)*) => {\n        if $e {\n            if_chain!($($rest)*)\n        }\n    };\n\n    (if let $p:pat = $e:expr; $($rest:tt)*) => {\n        if let $p = $e {\n            if_chain!($($rest)*)\n        }\n    };\n\n    (then $b:block) => {\n        $b\n    };\n}\n\n#[allow(dead_code)]\nfn main() {\n    let x = String::new();\n\n    // Ok, reference to a String.\n    let _: &String = match Some(x.clone()) {\n        Some(ref x) => x,\n        None => return,\n    };\n\n    // Ok, reference to a &mut String\n    let _: &&mut String = match Some(&mut x.clone()) {\n        Some(ref x) => x,\n        None => return,\n    };\n\n    // Ok, the pattern is from a macro\n    let _: &String = match Some(&x) {\n        m3!(x) => x,\n        None => return,\n    };\n\n    // Err, reference to a &String\n    let _: &String = match Some(&x) {\n        Some(x) => x,\n        //~^ needless_borrow\n        None => return,\n    };\n\n    // Err, reference to a &String.\n    let _: &String = match Some(&x) {\n        Some(x) => x,\n        //~^ needless_borrow\n        None => return,\n    };\n\n    // Err, reference to a &String\n    let _: &String = match Some(&x) {\n        Some(x) => {\n            //~^ needless_borrow\n\n            f1(x);\n            f1(x);\n            x\n        },\n        None => return,\n    };\n\n    // Err, reference to a &String\n    match Some(&x) {\n        Some(x) => m1!(x),\n        //~^ needless_borrow\n        None => return,\n    };\n\n    // Err, reference to a &String\n    let _ = |&x: &&String| {\n        //~^ needless_borrow\n\n        let _: &String = x;\n    };\n\n    // Err, reference to a &String\n    let (y,) = (&x,);\n    //~^ needless_borrow\n\n    let _: &String = y;\n\n    let y = &&x;\n    // Ok, different y\n    let _: &String = *y;\n\n    let x = (0, 0);\n    // Err, reference to a &u32. Don't suggest adding a reference to the field access.\n    let _: u32 = match Some(&x) {\n        Some(x) => x.0,\n        //~^ needless_borrow\n        None => return,\n    };\n\n    enum E {\n        A(&'static u32),\n        B(&'static u32),\n    }\n    // Err, reference to &u32.\n    let _: &u32 = match E::A(&0) {\n        E::A(x) | E::B(x) => x,\n        //~^ needless_borrow\n    };\n\n    // Err, reference to &String.\n    if_chain! {\n        if true;\n        if let Some(x) = Some(&String::new());\n        //~^ needless_borrow\n\n        then {\n            f1(x);\n        }\n    }\n}\n\n// Err, reference to a &String\nfn f2<'a>(&x: &&'a String) -> &'a String {\n    //~^ needless_borrow\n\n    let _: &String = x;\n    x\n}\n\ntrait T1 {\n    // Err, reference to a &String\n    fn f(&x: &&String) {\n        //~^ needless_borrow\n\n        let _: &String = x;\n    }\n}\n\nstruct S;\nimpl T1 for S {\n    // Err, reference to a &String\n    fn f(&x: &&String) {\n        //~^ needless_borrow\n\n        let _: &String = x;\n    }\n}\n\n// Ok - used to error due to rustc bug\n#[allow(dead_code)]\n#[derive(Debug)]\nenum Foo<'a> {\n    Str(&'a str),\n}\n"
  },
  {
    "path": "tests/ui/needless_borrow_pat.rs",
    "content": "#![warn(clippy::needless_borrow)]\n#![allow(clippy::needless_borrowed_reference, clippy::explicit_auto_deref)]\n\nfn f1(_: &str) {}\nmacro_rules! m1 {\n    ($e:expr) => {\n        f1($e)\n    };\n}\nmacro_rules! m3 {\n    ($i:ident) => {\n        Some(ref $i)\n    };\n}\nmacro_rules! if_chain {\n    (if $e:expr; $($rest:tt)*) => {\n        if $e {\n            if_chain!($($rest)*)\n        }\n    };\n\n    (if let $p:pat = $e:expr; $($rest:tt)*) => {\n        if let $p = $e {\n            if_chain!($($rest)*)\n        }\n    };\n\n    (then $b:block) => {\n        $b\n    };\n}\n\n#[allow(dead_code)]\nfn main() {\n    let x = String::new();\n\n    // Ok, reference to a String.\n    let _: &String = match Some(x.clone()) {\n        Some(ref x) => x,\n        None => return,\n    };\n\n    // Ok, reference to a &mut String\n    let _: &&mut String = match Some(&mut x.clone()) {\n        Some(ref x) => x,\n        None => return,\n    };\n\n    // Ok, the pattern is from a macro\n    let _: &String = match Some(&x) {\n        m3!(x) => x,\n        None => return,\n    };\n\n    // Err, reference to a &String\n    let _: &String = match Some(&x) {\n        Some(ref x) => x,\n        //~^ needless_borrow\n        None => return,\n    };\n\n    // Err, reference to a &String.\n    let _: &String = match Some(&x) {\n        Some(ref x) => *x,\n        //~^ needless_borrow\n        None => return,\n    };\n\n    // Err, reference to a &String\n    let _: &String = match Some(&x) {\n        Some(ref x) => {\n            //~^ needless_borrow\n\n            f1(x);\n            f1(*x);\n            x\n        },\n        None => return,\n    };\n\n    // Err, reference to a &String\n    match Some(&x) {\n        Some(ref x) => m1!(x),\n        //~^ needless_borrow\n        None => return,\n    };\n\n    // Err, reference to a &String\n    let _ = |&ref x: &&String| {\n        //~^ needless_borrow\n\n        let _: &String = x;\n    };\n\n    // Err, reference to a &String\n    let (ref y,) = (&x,);\n    //~^ needless_borrow\n\n    let _: &String = *y;\n\n    let y = &&x;\n    // Ok, different y\n    let _: &String = *y;\n\n    let x = (0, 0);\n    // Err, reference to a &u32. Don't suggest adding a reference to the field access.\n    let _: u32 = match Some(&x) {\n        Some(ref x) => x.0,\n        //~^ needless_borrow\n        None => return,\n    };\n\n    enum E {\n        A(&'static u32),\n        B(&'static u32),\n    }\n    // Err, reference to &u32.\n    let _: &u32 = match E::A(&0) {\n        E::A(ref x) | E::B(ref x) => *x,\n        //~^ needless_borrow\n    };\n\n    // Err, reference to &String.\n    if_chain! {\n        if true;\n        if let Some(ref x) = Some(&String::new());\n        //~^ needless_borrow\n\n        then {\n            f1(x);\n        }\n    }\n}\n\n// Err, reference to a &String\nfn f2<'a>(&ref x: &&'a String) -> &'a String {\n    //~^ needless_borrow\n\n    let _: &String = x;\n    *x\n}\n\ntrait T1 {\n    // Err, reference to a &String\n    fn f(&ref x: &&String) {\n        //~^ needless_borrow\n\n        let _: &String = x;\n    }\n}\n\nstruct S;\nimpl T1 for S {\n    // Err, reference to a &String\n    fn f(&ref x: &&String) {\n        //~^ needless_borrow\n\n        let _: &String = *x;\n    }\n}\n\n// Ok - used to error due to rustc bug\n#[allow(dead_code)]\n#[derive(Debug)]\nenum Foo<'a> {\n    Str(&'a str),\n}\n"
  },
  {
    "path": "tests/ui/needless_borrow_pat.stderr",
    "content": "error: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:57:14\n   |\nLL |         Some(ref x) => x,\n   |              ^^^^^\n   |\n   = note: `-D clippy::needless-borrow` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`\nhelp: try\n   |\nLL -         Some(ref x) => x,\nLL +         Some(x) => x,\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:64:14\n   |\nLL |         Some(ref x) => *x,\n   |              ^^^^^\n   |\nhelp: try\n   |\nLL -         Some(ref x) => *x,\nLL +         Some(x) => x,\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:71:14\n   |\nLL |         Some(ref x) => {\n   |              ^^^^^\n   |\nhelp: try\n   |\nLL ~         Some(x) => {\nLL |\nLL |\nLL |             f1(x);\nLL ~             f1(x);\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:83:14\n   |\nLL |         Some(ref x) => m1!(x),\n   |              ^^^^^\n   |\nhelp: try\n   |\nLL -         Some(ref x) => m1!(x),\nLL +         Some(x) => m1!(x),\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:89:15\n   |\nLL |     let _ = |&ref x: &&String| {\n   |               ^^^^^\n   |\nhelp: try\n   |\nLL -     let _ = |&ref x: &&String| {\nLL +     let _ = |&x: &&String| {\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:96:10\n   |\nLL |     let (ref y,) = (&x,);\n   |          ^^^^^\n   |\nhelp: try\n   |\nLL ~     let (y,) = (&x,);\nLL |\nLL |\nLL ~     let _: &String = y;\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:108:14\n   |\nLL |         Some(ref x) => x.0,\n   |              ^^^^^\n   |\nhelp: try\n   |\nLL -         Some(ref x) => x.0,\nLL +         Some(x) => x.0,\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:119:14\n   |\nLL |         E::A(ref x) | E::B(ref x) => *x,\n   |              ^^^^^         ^^^^^\n   |\nhelp: try\n   |\nLL -         E::A(ref x) | E::B(ref x) => *x,\nLL +         E::A(x) | E::B(x) => x,\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:126:21\n   |\nLL |         if let Some(ref x) = Some(&String::new());\n   |                     ^^^^^\n   |\nhelp: try\n   |\nLL -         if let Some(ref x) = Some(&String::new());\nLL +         if let Some(x) = Some(&String::new());\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:136:12\n   |\nLL | fn f2<'a>(&ref x: &&'a String) -> &'a String {\n   |            ^^^^^\n   |\nhelp: try\n   |\nLL ~ fn f2<'a>(&x: &&'a String) -> &'a String {\nLL |\nLL |\nLL |     let _: &String = x;\nLL ~     x\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:145:11\n   |\nLL |     fn f(&ref x: &&String) {\n   |           ^^^^^\n   |\nhelp: try\n   |\nLL -     fn f(&ref x: &&String) {\nLL +     fn f(&x: &&String) {\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/needless_borrow_pat.rs:155:11\n   |\nLL |     fn f(&ref x: &&String) {\n   |           ^^^^^\n   |\nhelp: try\n   |\nLL ~     fn f(&x: &&String) {\nLL |\nLL |\nLL ~         let _: &String = x;\n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_borrowed_ref.fixed",
    "content": "#![warn(clippy::needless_borrowed_reference)]\n#![allow(\n    unused,\n    irrefutable_let_patterns,\n    non_shorthand_field_patterns,\n    clippy::needless_borrow,\n    clippy::needless_ifs\n)]\n\nfn main() {}\n\nstruct Struct {\n    a: usize,\n    b: usize,\n    c: usize,\n}\n\nstruct TupleStruct(u8, u8, u8);\n\nfn should_lint(\n    array: [u8; 4],\n    slice: &[u8],\n    slice_of_refs: &[&u8],\n    vec: Vec<u8>,\n    tuple: (u8, u8, u8),\n    tuple_struct: TupleStruct,\n    s: Struct,\n) {\n    let mut v = Vec::<String>::new();\n    let _ = v.iter_mut().filter(|a| a.is_empty());\n    //~^ needless_borrowed_reference\n\n    let var = 3;\n    let thingy = Some(&var);\n    if let Some(v) = thingy {}\n    //~^ needless_borrowed_reference\n\n    if let &[a, ref b] = slice_of_refs {}\n    //~^ needless_borrowed_reference\n\n    let [a, ..] = &array;\n    //~^ needless_borrowed_reference\n    let [a, b, ..] = &array;\n    //~^ needless_borrowed_reference\n\n    if let [a, b] = slice {}\n    //~^ needless_borrowed_reference\n    if let [a, b] = &vec[..] {}\n    //~^ needless_borrowed_reference\n\n    if let [a, b, ..] = slice {}\n    //~^ needless_borrowed_reference\n    if let [a, .., b] = slice {}\n    //~^ needless_borrowed_reference\n    if let [.., a, b] = slice {}\n    //~^ needless_borrowed_reference\n\n    if let [a, _] = slice {}\n    //~^ needless_borrowed_reference\n\n    if let (a, b, c) = &tuple {}\n    //~^ needless_borrowed_reference\n    if let (a, _, c) = &tuple {}\n    //~^ needless_borrowed_reference\n    if let (a, ..) = &tuple {}\n    //~^ needless_borrowed_reference\n\n    if let TupleStruct(a, ..) = &tuple_struct {}\n    //~^ needless_borrowed_reference\n\n    if let Struct {\n        //~^ needless_borrowed_reference\n        a,\n        b: b,\n        c: renamed,\n    } = &s\n    {}\n\n    if let Struct { a, b: _, .. } = &s {}\n    //~^ needless_borrowed_reference\n}\n\nfn should_not_lint(\n    array: [u8; 4],\n    slice: &[u8],\n    slice_of_refs: &[&u8],\n    vec: Vec<u8>,\n    tuple: (u8, u8, u8),\n    tuple_struct: TupleStruct,\n    s: Struct,\n) {\n    if let [a] = slice {}\n    if let &[ref a, b] = slice {}\n    if let &[ref a, .., b] = slice {}\n\n    if let &(ref a, b, ..) = &tuple {}\n    if let &TupleStruct(ref a, b, ..) = &tuple_struct {}\n    if let &Struct { ref a, b, .. } = &s {}\n\n    // must not be removed as variables must be bound consistently across | patterns\n    if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}\n\n    // the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match\n    // the lint name\n    if let &[] = slice {}\n    if let &[_] = slice {}\n    if let &[..] = slice {}\n    if let &(..) = &tuple {}\n    if let &TupleStruct(..) = &tuple_struct {}\n    if let &Struct { .. } = &s {}\n\n    let mut var2 = 5;\n    let thingy2 = Some(&mut var2);\n    if let Some(&mut ref mut v) = thingy2 {\n        //          ^ should **not** be linted\n        // v is borrowed as mutable.\n        *v = 10;\n    }\n    if let Some(&mut ref v) = thingy2 {\n        //          ^ should **not** be linted\n        // here, v is borrowed as immutable.\n        // can't do that:\n        //*v = 15;\n    }\n}\n\nenum Animal {\n    Cat(u64),\n    Dog(u64),\n}\n\nfn foo(a: &Animal, b: &Animal) {\n    match (a, b) {\n        // lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63\n        (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),\n        //                  ^    and   ^ should **not** be linted\n        (Animal::Dog(a), &Animal::Dog(_)) => (),\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_borrowed_ref.rs",
    "content": "#![warn(clippy::needless_borrowed_reference)]\n#![allow(\n    unused,\n    irrefutable_let_patterns,\n    non_shorthand_field_patterns,\n    clippy::needless_borrow,\n    clippy::needless_ifs\n)]\n\nfn main() {}\n\nstruct Struct {\n    a: usize,\n    b: usize,\n    c: usize,\n}\n\nstruct TupleStruct(u8, u8, u8);\n\nfn should_lint(\n    array: [u8; 4],\n    slice: &[u8],\n    slice_of_refs: &[&u8],\n    vec: Vec<u8>,\n    tuple: (u8, u8, u8),\n    tuple_struct: TupleStruct,\n    s: Struct,\n) {\n    let mut v = Vec::<String>::new();\n    let _ = v.iter_mut().filter(|&ref a| a.is_empty());\n    //~^ needless_borrowed_reference\n\n    let var = 3;\n    let thingy = Some(&var);\n    if let Some(&ref v) = thingy {}\n    //~^ needless_borrowed_reference\n\n    if let &[&ref a, ref b] = slice_of_refs {}\n    //~^ needless_borrowed_reference\n\n    let &[ref a, ..] = &array;\n    //~^ needless_borrowed_reference\n    let &[ref a, ref b, ..] = &array;\n    //~^ needless_borrowed_reference\n\n    if let &[ref a, ref b] = slice {}\n    //~^ needless_borrowed_reference\n    if let &[ref a, ref b] = &vec[..] {}\n    //~^ needless_borrowed_reference\n\n    if let &[ref a, ref b, ..] = slice {}\n    //~^ needless_borrowed_reference\n    if let &[ref a, .., ref b] = slice {}\n    //~^ needless_borrowed_reference\n    if let &[.., ref a, ref b] = slice {}\n    //~^ needless_borrowed_reference\n\n    if let &[ref a, _] = slice {}\n    //~^ needless_borrowed_reference\n\n    if let &(ref a, ref b, ref c) = &tuple {}\n    //~^ needless_borrowed_reference\n    if let &(ref a, _, ref c) = &tuple {}\n    //~^ needless_borrowed_reference\n    if let &(ref a, ..) = &tuple {}\n    //~^ needless_borrowed_reference\n\n    if let &TupleStruct(ref a, ..) = &tuple_struct {}\n    //~^ needless_borrowed_reference\n\n    if let &Struct {\n        //~^ needless_borrowed_reference\n        ref a,\n        b: ref b,\n        c: ref renamed,\n    } = &s\n    {}\n\n    if let &Struct { ref a, b: _, .. } = &s {}\n    //~^ needless_borrowed_reference\n}\n\nfn should_not_lint(\n    array: [u8; 4],\n    slice: &[u8],\n    slice_of_refs: &[&u8],\n    vec: Vec<u8>,\n    tuple: (u8, u8, u8),\n    tuple_struct: TupleStruct,\n    s: Struct,\n) {\n    if let [a] = slice {}\n    if let &[ref a, b] = slice {}\n    if let &[ref a, .., b] = slice {}\n\n    if let &(ref a, b, ..) = &tuple {}\n    if let &TupleStruct(ref a, b, ..) = &tuple_struct {}\n    if let &Struct { ref a, b, .. } = &s {}\n\n    // must not be removed as variables must be bound consistently across | patterns\n    if let (&[ref a], _) | ([], ref a) = (slice_of_refs, &1u8) {}\n\n    // the `&`s here technically could be removed, but it'd be noisy and without a `ref` doesn't match\n    // the lint name\n    if let &[] = slice {}\n    if let &[_] = slice {}\n    if let &[..] = slice {}\n    if let &(..) = &tuple {}\n    if let &TupleStruct(..) = &tuple_struct {}\n    if let &Struct { .. } = &s {}\n\n    let mut var2 = 5;\n    let thingy2 = Some(&mut var2);\n    if let Some(&mut ref mut v) = thingy2 {\n        //          ^ should **not** be linted\n        // v is borrowed as mutable.\n        *v = 10;\n    }\n    if let Some(&mut ref v) = thingy2 {\n        //          ^ should **not** be linted\n        // here, v is borrowed as immutable.\n        // can't do that:\n        //*v = 15;\n    }\n}\n\nenum Animal {\n    Cat(u64),\n    Dog(u64),\n}\n\nfn foo(a: &Animal, b: &Animal) {\n    match (a, b) {\n        // lifetime mismatch error if there is no '&ref' before `feature(nll)` stabilization in 1.63\n        (&Animal::Cat(v), &ref k) | (&ref k, &Animal::Cat(v)) => (),\n        //                  ^    and   ^ should **not** be linted\n        (Animal::Dog(a), &Animal::Dog(_)) => (),\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_borrowed_ref.stderr",
    "content": "error: this pattern takes a reference on something that is being dereferenced\n  --> tests/ui/needless_borrowed_ref.rs:30:34\n   |\nLL |     let _ = v.iter_mut().filter(|&ref a| a.is_empty());\n   |                                  ^^^^^^\n   |\n   = note: `-D clippy::needless-borrowed-reference` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_borrowed_reference)]`\nhelp: try removing the `&ref` part\n   |\nLL -     let _ = v.iter_mut().filter(|&ref a| a.is_empty());\nLL +     let _ = v.iter_mut().filter(|a| a.is_empty());\n   |\n\nerror: this pattern takes a reference on something that is being dereferenced\n  --> tests/ui/needless_borrowed_ref.rs:35:17\n   |\nLL |     if let Some(&ref v) = thingy {}\n   |                 ^^^^^^\n   |\nhelp: try removing the `&ref` part\n   |\nLL -     if let Some(&ref v) = thingy {}\nLL +     if let Some(v) = thingy {}\n   |\n\nerror: this pattern takes a reference on something that is being dereferenced\n  --> tests/ui/needless_borrowed_ref.rs:38:14\n   |\nLL |     if let &[&ref a, ref b] = slice_of_refs {}\n   |              ^^^^^^\n   |\nhelp: try removing the `&ref` part\n   |\nLL -     if let &[&ref a, ref b] = slice_of_refs {}\nLL +     if let &[a, ref b] = slice_of_refs {}\n   |\n\nerror: dereferencing a slice pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:41:9\n   |\nLL |     let &[ref a, ..] = &array;\n   |         ^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     let &[ref a, ..] = &array;\nLL +     let [a, ..] = &array;\n   |\n\nerror: dereferencing a slice pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:43:9\n   |\nLL |     let &[ref a, ref b, ..] = &array;\n   |         ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     let &[ref a, ref b, ..] = &array;\nLL +     let [a, b, ..] = &array;\n   |\n\nerror: dereferencing a slice pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:46:12\n   |\nLL |     if let &[ref a, ref b] = slice {}\n   |            ^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &[ref a, ref b] = slice {}\nLL +     if let [a, b] = slice {}\n   |\n\nerror: dereferencing a slice pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:48:12\n   |\nLL |     if let &[ref a, ref b] = &vec[..] {}\n   |            ^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &[ref a, ref b] = &vec[..] {}\nLL +     if let [a, b] = &vec[..] {}\n   |\n\nerror: dereferencing a slice pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:51:12\n   |\nLL |     if let &[ref a, ref b, ..] = slice {}\n   |            ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &[ref a, ref b, ..] = slice {}\nLL +     if let [a, b, ..] = slice {}\n   |\n\nerror: dereferencing a slice pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:53:12\n   |\nLL |     if let &[ref a, .., ref b] = slice {}\n   |            ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &[ref a, .., ref b] = slice {}\nLL +     if let [a, .., b] = slice {}\n   |\n\nerror: dereferencing a slice pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:55:12\n   |\nLL |     if let &[.., ref a, ref b] = slice {}\n   |            ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &[.., ref a, ref b] = slice {}\nLL +     if let [.., a, b] = slice {}\n   |\n\nerror: dereferencing a slice pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:58:12\n   |\nLL |     if let &[ref a, _] = slice {}\n   |            ^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &[ref a, _] = slice {}\nLL +     if let [a, _] = slice {}\n   |\n\nerror: dereferencing a tuple pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:61:12\n   |\nLL |     if let &(ref a, ref b, ref c) = &tuple {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &(ref a, ref b, ref c) = &tuple {}\nLL +     if let (a, b, c) = &tuple {}\n   |\n\nerror: dereferencing a tuple pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:63:12\n   |\nLL |     if let &(ref a, _, ref c) = &tuple {}\n   |            ^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &(ref a, _, ref c) = &tuple {}\nLL +     if let (a, _, c) = &tuple {}\n   |\n\nerror: dereferencing a tuple pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:65:12\n   |\nLL |     if let &(ref a, ..) = &tuple {}\n   |            ^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &(ref a, ..) = &tuple {}\nLL +     if let (a, ..) = &tuple {}\n   |\n\nerror: dereferencing a tuple pattern where every element takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:68:12\n   |\nLL |     if let &TupleStruct(ref a, ..) = &tuple_struct {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &TupleStruct(ref a, ..) = &tuple_struct {}\nLL +     if let TupleStruct(a, ..) = &tuple_struct {}\n   |\n\nerror: dereferencing a struct pattern where every field's pattern takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:71:12\n   |\nLL |       if let &Struct {\n   |  ____________^\nLL | |\nLL | |         ref a,\nLL | |         b: ref b,\nLL | |         c: ref renamed,\nLL | |     } = &s\n   | |_____^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL ~     if let Struct {\nLL |\nLL ~         a,\nLL ~         b: b,\nLL ~         c: renamed,\n   |\n\nerror: dereferencing a struct pattern where every field's pattern takes a reference\n  --> tests/ui/needless_borrowed_ref.rs:79:12\n   |\nLL |     if let &Struct { ref a, b: _, .. } = &s {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try removing the `&` and `ref` parts\n   |\nLL -     if let &Struct { ref a, b: _, .. } = &s {}\nLL +     if let Struct { a, b: _, .. } = &s {}\n   |\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_borrows_for_generic_args.fixed",
    "content": "#![warn(clippy::needless_borrows_for_generic_args)]\n#![allow(\n    clippy::unnecessary_to_owned,\n    clippy::unnecessary_literal_unwrap,\n    clippy::needless_borrow\n)]\n\nuse core::ops::Deref;\nuse std::any::Any;\nuse std::ffi::OsStr;\nuse std::fmt::{Debug, Display};\nuse std::path::Path;\nuse std::process::Command;\n\nfn main() {\n    let _ = Command::new(\"ls\").args([\"-a\", \"-l\"]).status().unwrap();\n    //~^ needless_borrows_for_generic_args\n    let _ = Path::new(\".\").join(\".\");\n    //~^ needless_borrows_for_generic_args\n    let _ = Any::type_id(&\"\"); // Don't lint. `Any` is only bound\n    let _ = Box::new(&\"\"); // Don't lint. Type parameter appears in return type\n    let _ = Some(\"\").unwrap_or(&\"\");\n    let _ = std::fs::write(\"x\", \"\".to_string());\n    //~^ needless_borrows_for_generic_args\n\n    {\n        #[derive(Clone, Copy)]\n        struct X;\n\n        impl Deref for X {\n            type Target = X;\n            fn deref(&self) -> &Self::Target {\n                self\n            }\n        }\n\n        fn deref_target_is_x<T: Deref<Target = X>>(_: T) {}\n\n        deref_target_is_x(X);\n        //~^ needless_borrows_for_generic_args\n    }\n    {\n        fn multiple_constraints<T, U, V, X, Y>(_: T)\n        where\n            T: IntoIterator<Item = U> + IntoIterator<Item = X>,\n            U: IntoIterator<Item = V>,\n            V: AsRef<str>,\n            X: IntoIterator<Item = Y>,\n            Y: AsRef<OsStr>,\n        {\n        }\n\n        multiple_constraints([[\"\"]]);\n        //~^ needless_borrows_for_generic_args\n    }\n    {\n        #[derive(Clone, Copy)]\n        struct X;\n\n        impl Deref for X {\n            type Target = X;\n            fn deref(&self) -> &Self::Target {\n                self\n            }\n        }\n\n        fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)\n        where\n            T: Deref<Target = U>,\n            U: Deref<Target = V>,\n        {\n        }\n\n        multiple_constraints_normalizes_to_same(X, X);\n        //~^ needless_borrows_for_generic_args\n    }\n    {\n        fn only_sized<T>(_: T) {}\n        only_sized(&\"\"); // Don't lint. `Sized` is only bound\n    }\n    {\n        fn ref_as_ref_path<T: 'static>(_: &'static T)\n        where\n            &'static T: AsRef<Path>,\n        {\n        }\n\n        ref_as_ref_path(&\"\"); // Don't lint. Argument type is not a type parameter\n    }\n    {\n        trait RefsOnly {\n            type Referent;\n        }\n\n        impl<T> RefsOnly for &T {\n            type Referent = T;\n        }\n\n        fn refs_only<T, U>(_: T)\n        where\n            T: RefsOnly<Referent = U>,\n        {\n        }\n\n        refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't\n    }\n    {\n        fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)\n        where\n            T: IntoIterator<Item = U>,\n            U: IntoIterator<Item = V>,\n            V: AsRef<str>,\n        {\n        }\n        multiple_constraints_normalizes_to_different(&[[\"\"]], &[\"\"]); // Don't lint. Projected type appears in arguments\n    }\n    // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321\n    {\n        #[derive(Clone, Copy)]\n        struct Iter;\n        impl Iterator for Iter {\n            type Item = ();\n            fn next(&mut self) -> Option<Self::Item> {\n                None\n            }\n        }\n        fn takes_iter(_: impl Iterator) {}\n        fn dont_warn(mut x: Iter) {\n            takes_iter(&mut x);\n        }\n        #[allow(unused_mut)]\n        fn warn(mut x: &mut Iter) {\n            takes_iter(x)\n            //~^ needless_borrows_for_generic_args\n        }\n    }\n    #[clippy::msrv = \"1.52.0\"]\n    {\n        let _ = Command::new(\"ls\").args(&[\"-a\", \"-l\"]).status().unwrap();\n    };\n    #[clippy::msrv = \"1.53.0\"]\n    {\n        let _ = Command::new(\"ls\").args([\"-a\", \"-l\"]).status().unwrap();\n        //~^ needless_borrows_for_generic_args\n    };\n    {\n        let env = \"env\".to_owned();\n        let arg = \"arg\".to_owned();\n        let f = |arg| {\n            let loc = \"loc\".to_owned();\n            let _ = std::fs::write(\"x\", &env); // Don't lint. In environment\n            let _ = std::fs::write(\"x\", &arg);\n            let _ = std::fs::write(\"x\", &loc);\n        };\n        let _ = std::fs::write(\"x\", &env); // Don't lint. Borrowed by `f`\n        f(arg);\n    }\n    {\n        #[derive(Debug)]\n        struct X;\n\n        impl Drop for X {\n            fn drop(&mut self) {}\n        }\n\n        fn f(_: impl Debug) {}\n\n        let x = X;\n        f(&x); // Don't lint, not copy, passed by a reference to a variable\n    }\n    {\n        fn f(_: impl AsRef<str>) {}\n\n        let x = String::new();\n        f(&x);\n    }\n    {\n        fn f(_: impl AsRef<str>) {}\n        fn f2(_: impl AsRef<str>) {}\n\n        let x = String::new();\n        f(&x);\n        f2(&x);\n    }\n    // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280\n    // issue 9111\n    {\n        struct A;\n\n        impl Extend<u8> for A {\n            fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {\n                unimplemented!()\n            }\n        }\n\n        impl<'a> Extend<&'a u8> for A {\n            fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {\n                unimplemented!()\n            }\n        }\n\n        let mut a = A;\n        a.extend(&[]); // vs a.extend([]);\n    }\n    // issue 9710\n    {\n        fn f(_: impl AsRef<str>) {}\n\n        let x = String::new();\n        for _ in 0..10 {\n            f(&x);\n        }\n    }\n    // issue 9739\n    {\n        fn foo<D: Display>(_it: impl IntoIterator<Item = D>) {}\n        foo(if std::env::var_os(\"HI\").is_some() {\n            &[0]\n        } else {\n            &[] as &[u32]\n        });\n    }\n    {\n        struct S;\n\n        impl S {\n            fn foo<D: Display>(&self, _it: impl IntoIterator<Item = D>) {}\n        }\n\n        S.foo(if std::env::var_os(\"HI\").is_some() {\n            &[0]\n        } else {\n            &[] as &[u32]\n        });\n    }\n    // issue 9782\n    {\n        fn foo<T: AsRef<[u8]>>(t: T) {\n            println!(\"{}\", std::mem::size_of::<T>());\n            let _t: &[u8] = t.as_ref();\n        }\n\n        let a: [u8; 100] = [0u8; 100];\n\n        // 100\n        foo::<[u8; 100]>(a);\n        foo(a);\n\n        // 16\n        foo::<&[u8]>(&a);\n        foo(a.as_slice());\n\n        // 8\n        foo::<&[u8; 100]>(&a);\n        foo(a);\n        //~^ needless_borrows_for_generic_args\n    }\n    {\n        struct S;\n\n        impl S {\n            fn foo<T: AsRef<[u8]>>(t: T) {\n                println!(\"{}\", std::mem::size_of::<T>());\n                let _t: &[u8] = t.as_ref();\n            }\n        }\n\n        let a: [u8; 100] = [0u8; 100];\n        S::foo::<&[u8; 100]>(&a);\n    }\n    {\n        struct S;\n\n        impl S {\n            fn foo<T: AsRef<[u8]>>(&self, t: T) {\n                println!(\"{}\", std::mem::size_of::<T>());\n                let _t: &[u8] = t.as_ref();\n            }\n        }\n\n        let a: [u8; 100] = [0u8; 100];\n        S.foo::<&[u8; 100]>(&a);\n    }\n    // issue 10535\n    {\n        static SOME_STATIC: String = String::new();\n\n        static UNIT: () = compute(&SOME_STATIC);\n\n        pub const fn compute<T>(_: T)\n        where\n            T: Copy,\n        {\n        }\n    }\n    // address of field when operand impl Drop\n    {\n        struct CustomDrop(String);\n\n        impl Drop for CustomDrop {\n            fn drop(&mut self) {}\n        }\n\n        fn check_str<P: AsRef<str>>(_to: P) {}\n\n        fn test() {\n            let owner = CustomDrop(String::default());\n            check_str(&owner.0); // Don't lint. `owner` can't be partially moved because it impl Drop\n        }\n    }\n    {\n        #[derive(Debug)]\n        struct X(Vec<u8>);\n\n        fn f(_: impl Debug) {}\n\n        let x = X(vec![]);\n        f(&x); // Don't lint, makes x unavailable later\n    }\n    {\n        #[derive(Debug)]\n        struct X;\n\n        impl Drop for X {\n            fn drop(&mut self) {}\n        }\n\n        fn f(_: impl Debug) {}\n\n        #[derive(Debug)]\n        struct Y(X);\n\n        let y = Y(X);\n        f(&y); // Don't lint. Not copy, passed by a reference to value\n    }\n    {\n        fn f(_: impl AsRef<str>) {}\n        let x = String::new();\n        f(&x); // Don't lint, not a copy, makes it unavailable later\n        f(String::new()); // Lint, makes no difference\n        //\n        //~^^ needless_borrows_for_generic_args\n        let y = \"\".to_owned();\n        f(&y); // Don't lint\n        f(\"\".to_owned()); // Lint\n        //\n        //~^^ needless_borrows_for_generic_args\n    }\n    {\n        fn takes_writer<T: std::io::Write>(_: T) {}\n\n        fn issue_12856(mut buffer: &mut Vec<u8>) {\n            takes_writer(&mut buffer); // Don't lint, would make buffer unavailable later\n            buffer.extend(b\"\\n\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_borrows_for_generic_args.rs",
    "content": "#![warn(clippy::needless_borrows_for_generic_args)]\n#![allow(\n    clippy::unnecessary_to_owned,\n    clippy::unnecessary_literal_unwrap,\n    clippy::needless_borrow\n)]\n\nuse core::ops::Deref;\nuse std::any::Any;\nuse std::ffi::OsStr;\nuse std::fmt::{Debug, Display};\nuse std::path::Path;\nuse std::process::Command;\n\nfn main() {\n    let _ = Command::new(\"ls\").args(&[\"-a\", \"-l\"]).status().unwrap();\n    //~^ needless_borrows_for_generic_args\n    let _ = Path::new(\".\").join(&&\".\");\n    //~^ needless_borrows_for_generic_args\n    let _ = Any::type_id(&\"\"); // Don't lint. `Any` is only bound\n    let _ = Box::new(&\"\"); // Don't lint. Type parameter appears in return type\n    let _ = Some(\"\").unwrap_or(&\"\");\n    let _ = std::fs::write(\"x\", &\"\".to_string());\n    //~^ needless_borrows_for_generic_args\n\n    {\n        #[derive(Clone, Copy)]\n        struct X;\n\n        impl Deref for X {\n            type Target = X;\n            fn deref(&self) -> &Self::Target {\n                self\n            }\n        }\n\n        fn deref_target_is_x<T: Deref<Target = X>>(_: T) {}\n\n        deref_target_is_x(&X);\n        //~^ needless_borrows_for_generic_args\n    }\n    {\n        fn multiple_constraints<T, U, V, X, Y>(_: T)\n        where\n            T: IntoIterator<Item = U> + IntoIterator<Item = X>,\n            U: IntoIterator<Item = V>,\n            V: AsRef<str>,\n            X: IntoIterator<Item = Y>,\n            Y: AsRef<OsStr>,\n        {\n        }\n\n        multiple_constraints(&[[\"\"]]);\n        //~^ needless_borrows_for_generic_args\n    }\n    {\n        #[derive(Clone, Copy)]\n        struct X;\n\n        impl Deref for X {\n            type Target = X;\n            fn deref(&self) -> &Self::Target {\n                self\n            }\n        }\n\n        fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)\n        where\n            T: Deref<Target = U>,\n            U: Deref<Target = V>,\n        {\n        }\n\n        multiple_constraints_normalizes_to_same(&X, X);\n        //~^ needless_borrows_for_generic_args\n    }\n    {\n        fn only_sized<T>(_: T) {}\n        only_sized(&\"\"); // Don't lint. `Sized` is only bound\n    }\n    {\n        fn ref_as_ref_path<T: 'static>(_: &'static T)\n        where\n            &'static T: AsRef<Path>,\n        {\n        }\n\n        ref_as_ref_path(&\"\"); // Don't lint. Argument type is not a type parameter\n    }\n    {\n        trait RefsOnly {\n            type Referent;\n        }\n\n        impl<T> RefsOnly for &T {\n            type Referent = T;\n        }\n\n        fn refs_only<T, U>(_: T)\n        where\n            T: RefsOnly<Referent = U>,\n        {\n        }\n\n        refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't\n    }\n    {\n        fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)\n        where\n            T: IntoIterator<Item = U>,\n            U: IntoIterator<Item = V>,\n            V: AsRef<str>,\n        {\n        }\n        multiple_constraints_normalizes_to_different(&[[\"\"]], &[\"\"]); // Don't lint. Projected type appears in arguments\n    }\n    // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321\n    {\n        #[derive(Clone, Copy)]\n        struct Iter;\n        impl Iterator for Iter {\n            type Item = ();\n            fn next(&mut self) -> Option<Self::Item> {\n                None\n            }\n        }\n        fn takes_iter(_: impl Iterator) {}\n        fn dont_warn(mut x: Iter) {\n            takes_iter(&mut x);\n        }\n        #[allow(unused_mut)]\n        fn warn(mut x: &mut Iter) {\n            takes_iter(&mut x)\n            //~^ needless_borrows_for_generic_args\n        }\n    }\n    #[clippy::msrv = \"1.52.0\"]\n    {\n        let _ = Command::new(\"ls\").args(&[\"-a\", \"-l\"]).status().unwrap();\n    };\n    #[clippy::msrv = \"1.53.0\"]\n    {\n        let _ = Command::new(\"ls\").args(&[\"-a\", \"-l\"]).status().unwrap();\n        //~^ needless_borrows_for_generic_args\n    };\n    {\n        let env = \"env\".to_owned();\n        let arg = \"arg\".to_owned();\n        let f = |arg| {\n            let loc = \"loc\".to_owned();\n            let _ = std::fs::write(\"x\", &env); // Don't lint. In environment\n            let _ = std::fs::write(\"x\", &arg);\n            let _ = std::fs::write(\"x\", &loc);\n        };\n        let _ = std::fs::write(\"x\", &env); // Don't lint. Borrowed by `f`\n        f(arg);\n    }\n    {\n        #[derive(Debug)]\n        struct X;\n\n        impl Drop for X {\n            fn drop(&mut self) {}\n        }\n\n        fn f(_: impl Debug) {}\n\n        let x = X;\n        f(&x); // Don't lint, not copy, passed by a reference to a variable\n    }\n    {\n        fn f(_: impl AsRef<str>) {}\n\n        let x = String::new();\n        f(&x);\n    }\n    {\n        fn f(_: impl AsRef<str>) {}\n        fn f2(_: impl AsRef<str>) {}\n\n        let x = String::new();\n        f(&x);\n        f2(&x);\n    }\n    // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280\n    // issue 9111\n    {\n        struct A;\n\n        impl Extend<u8> for A {\n            fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {\n                unimplemented!()\n            }\n        }\n\n        impl<'a> Extend<&'a u8> for A {\n            fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {\n                unimplemented!()\n            }\n        }\n\n        let mut a = A;\n        a.extend(&[]); // vs a.extend([]);\n    }\n    // issue 9710\n    {\n        fn f(_: impl AsRef<str>) {}\n\n        let x = String::new();\n        for _ in 0..10 {\n            f(&x);\n        }\n    }\n    // issue 9739\n    {\n        fn foo<D: Display>(_it: impl IntoIterator<Item = D>) {}\n        foo(if std::env::var_os(\"HI\").is_some() {\n            &[0]\n        } else {\n            &[] as &[u32]\n        });\n    }\n    {\n        struct S;\n\n        impl S {\n            fn foo<D: Display>(&self, _it: impl IntoIterator<Item = D>) {}\n        }\n\n        S.foo(if std::env::var_os(\"HI\").is_some() {\n            &[0]\n        } else {\n            &[] as &[u32]\n        });\n    }\n    // issue 9782\n    {\n        fn foo<T: AsRef<[u8]>>(t: T) {\n            println!(\"{}\", std::mem::size_of::<T>());\n            let _t: &[u8] = t.as_ref();\n        }\n\n        let a: [u8; 100] = [0u8; 100];\n\n        // 100\n        foo::<[u8; 100]>(a);\n        foo(a);\n\n        // 16\n        foo::<&[u8]>(&a);\n        foo(a.as_slice());\n\n        // 8\n        foo::<&[u8; 100]>(&a);\n        foo(&a);\n        //~^ needless_borrows_for_generic_args\n    }\n    {\n        struct S;\n\n        impl S {\n            fn foo<T: AsRef<[u8]>>(t: T) {\n                println!(\"{}\", std::mem::size_of::<T>());\n                let _t: &[u8] = t.as_ref();\n            }\n        }\n\n        let a: [u8; 100] = [0u8; 100];\n        S::foo::<&[u8; 100]>(&a);\n    }\n    {\n        struct S;\n\n        impl S {\n            fn foo<T: AsRef<[u8]>>(&self, t: T) {\n                println!(\"{}\", std::mem::size_of::<T>());\n                let _t: &[u8] = t.as_ref();\n            }\n        }\n\n        let a: [u8; 100] = [0u8; 100];\n        S.foo::<&[u8; 100]>(&a);\n    }\n    // issue 10535\n    {\n        static SOME_STATIC: String = String::new();\n\n        static UNIT: () = compute(&SOME_STATIC);\n\n        pub const fn compute<T>(_: T)\n        where\n            T: Copy,\n        {\n        }\n    }\n    // address of field when operand impl Drop\n    {\n        struct CustomDrop(String);\n\n        impl Drop for CustomDrop {\n            fn drop(&mut self) {}\n        }\n\n        fn check_str<P: AsRef<str>>(_to: P) {}\n\n        fn test() {\n            let owner = CustomDrop(String::default());\n            check_str(&owner.0); // Don't lint. `owner` can't be partially moved because it impl Drop\n        }\n    }\n    {\n        #[derive(Debug)]\n        struct X(Vec<u8>);\n\n        fn f(_: impl Debug) {}\n\n        let x = X(vec![]);\n        f(&x); // Don't lint, makes x unavailable later\n    }\n    {\n        #[derive(Debug)]\n        struct X;\n\n        impl Drop for X {\n            fn drop(&mut self) {}\n        }\n\n        fn f(_: impl Debug) {}\n\n        #[derive(Debug)]\n        struct Y(X);\n\n        let y = Y(X);\n        f(&y); // Don't lint. Not copy, passed by a reference to value\n    }\n    {\n        fn f(_: impl AsRef<str>) {}\n        let x = String::new();\n        f(&x); // Don't lint, not a copy, makes it unavailable later\n        f(&String::new()); // Lint, makes no difference\n        //\n        //~^^ needless_borrows_for_generic_args\n        let y = \"\".to_owned();\n        f(&y); // Don't lint\n        f(&\"\".to_owned()); // Lint\n        //\n        //~^^ needless_borrows_for_generic_args\n    }\n    {\n        fn takes_writer<T: std::io::Write>(_: T) {}\n\n        fn issue_12856(mut buffer: &mut Vec<u8>) {\n            takes_writer(&mut buffer); // Don't lint, would make buffer unavailable later\n            buffer.extend(b\"\\n\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_borrows_for_generic_args.stderr",
    "content": "error: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:16:37\n   |\nLL |     let _ = Command::new(\"ls\").args(&[\"-a\", \"-l\"]).status().unwrap();\n   |                                     ^^^^^^^^^^^^^ help: change this to: `[\"-a\", \"-l\"]`\n   |\n   = note: `-D clippy::needless-borrows-for-generic-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_borrows_for_generic_args)]`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:18:33\n   |\nLL |     let _ = Path::new(\".\").join(&&\".\");\n   |                                 ^^^^^ help: change this to: `\".\"`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:23:33\n   |\nLL |     let _ = std::fs::write(\"x\", &\"\".to_string());\n   |                                 ^^^^^^^^^^^^^^^ help: change this to: `\"\".to_string()`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:39:27\n   |\nLL |         deref_target_is_x(&X);\n   |                           ^^ help: change this to: `X`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:53:30\n   |\nLL |         multiple_constraints(&[[\"\"]]);\n   |                              ^^^^^^^ help: change this to: `[[\"\"]]`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:74:49\n   |\nLL |         multiple_constraints_normalizes_to_same(&X, X);\n   |                                                 ^^ help: change this to: `X`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:133:24\n   |\nLL |             takes_iter(&mut x)\n   |                        ^^^^^^ help: change this to: `x`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:143:41\n   |\nLL |         let _ = Command::new(\"ls\").args(&[\"-a\", \"-l\"]).status().unwrap();\n   |                                         ^^^^^^^^^^^^^ help: change this to: `[\"-a\", \"-l\"]`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:255:13\n   |\nLL |         foo(&a);\n   |             ^^ help: change this to: `a`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:340:11\n   |\nLL |         f(&String::new()); // Lint, makes no difference\n   |           ^^^^^^^^^^^^^^ help: change this to: `String::new()`\n\nerror: the borrowed expression implements the required traits\n  --> tests/ui/needless_borrows_for_generic_args.rs:345:11\n   |\nLL |         f(&\"\".to_owned()); // Lint\n   |           ^^^^^^^^^^^^^^ help: change this to: `\"\".to_owned()`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_character_iteration.fixed",
    "content": "#![warn(clippy::needless_character_iteration)]\n#![allow(clippy::map_identity, clippy::unnecessary_operation)]\n\n#[derive(Default)]\nstruct S {\n    field: &'static str,\n}\n\nimpl S {\n    fn field(&self) -> &str {\n        self.field\n    }\n}\n\nfn magic(_: char) {}\n\nfn main() {\n    \"foo\".is_ascii();\n    //~^ needless_character_iteration\n\n    !\"foo\".is_ascii();\n    //~^ needless_character_iteration\n\n    \"foo\".is_ascii();\n    //~^ needless_character_iteration\n\n    !\"foo\".is_ascii();\n    //~^ needless_character_iteration\n\n    let s = String::new();\n    s.is_ascii();\n    //~^ needless_character_iteration\n\n    !\"foo\".to_string().is_ascii();\n    //~^ needless_character_iteration\n\n    \"foo\".is_ascii();\n    !\"foo\".is_ascii();\n\n    S::default().field().is_ascii();\n    //~^ needless_character_iteration\n\n    // Should not lint!\n    \"foo\".chars().all(|c| {\n        let x = c;\n        magic(x);\n        x.is_ascii()\n    });\n\n    // Should not lint!\n    \"foo\".chars().all(|c| c.is_ascii() && c.is_alphabetic());\n\n    // Should not lint!\n    \"foo\".chars().map(|c| c).all(|c| !char::is_ascii(&c));\n\n    // Should not lint!\n    \"foo\".chars().all(|c| !c.is_ascii());\n\n    // Should not lint!\n    \"foo\".chars().any(|c| c.is_ascii());\n}\n"
  },
  {
    "path": "tests/ui/needless_character_iteration.rs",
    "content": "#![warn(clippy::needless_character_iteration)]\n#![allow(clippy::map_identity, clippy::unnecessary_operation)]\n\n#[derive(Default)]\nstruct S {\n    field: &'static str,\n}\n\nimpl S {\n    fn field(&self) -> &str {\n        self.field\n    }\n}\n\nfn magic(_: char) {}\n\nfn main() {\n    \"foo\".chars().all(|c| c.is_ascii());\n    //~^ needless_character_iteration\n\n    \"foo\".chars().any(|c| !c.is_ascii());\n    //~^ needless_character_iteration\n\n    \"foo\".chars().all(|c| char::is_ascii(&c));\n    //~^ needless_character_iteration\n\n    \"foo\".chars().any(|c| !char::is_ascii(&c));\n    //~^ needless_character_iteration\n\n    let s = String::new();\n    s.chars().all(|c| c.is_ascii());\n    //~^ needless_character_iteration\n\n    \"foo\".to_string().chars().any(|c| !c.is_ascii());\n    //~^ needless_character_iteration\n\n    \"foo\".chars().all(|c| {\n        //~^ needless_character_iteration\n\n        let x = c;\n        x.is_ascii()\n    });\n    \"foo\".chars().any(|c| {\n        //~^ needless_character_iteration\n\n        let x = c;\n        !x.is_ascii()\n    });\n\n    S::default().field().chars().all(|x| x.is_ascii());\n    //~^ needless_character_iteration\n\n    // Should not lint!\n    \"foo\".chars().all(|c| {\n        let x = c;\n        magic(x);\n        x.is_ascii()\n    });\n\n    // Should not lint!\n    \"foo\".chars().all(|c| c.is_ascii() && c.is_alphabetic());\n\n    // Should not lint!\n    \"foo\".chars().map(|c| c).all(|c| !char::is_ascii(&c));\n\n    // Should not lint!\n    \"foo\".chars().all(|c| !c.is_ascii());\n\n    // Should not lint!\n    \"foo\".chars().any(|c| c.is_ascii());\n}\n"
  },
  {
    "path": "tests/ui/needless_character_iteration.stderr",
    "content": "error: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:18:5\n   |\nLL |     \"foo\".chars().all(|c| c.is_ascii());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"foo\".is_ascii()`\n   |\n   = note: `-D clippy::needless-character-iteration` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_character_iteration)]`\n\nerror: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:21:5\n   |\nLL |     \"foo\".chars().any(|c| !c.is_ascii());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!\"foo\".is_ascii()`\n\nerror: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:24:5\n   |\nLL |     \"foo\".chars().all(|c| char::is_ascii(&c));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"foo\".is_ascii()`\n\nerror: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:27:5\n   |\nLL |     \"foo\".chars().any(|c| !char::is_ascii(&c));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!\"foo\".is_ascii()`\n\nerror: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:31:5\n   |\nLL |     s.chars().all(|c| c.is_ascii());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.is_ascii()`\n\nerror: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:34:5\n   |\nLL |     \"foo\".to_string().chars().any(|c| !c.is_ascii());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!\"foo\".to_string().is_ascii()`\n\nerror: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:37:5\n   |\nLL | /     \"foo\".chars().all(|c| {\nLL | |\nLL | |\nLL | |         let x = c;\nLL | |         x.is_ascii()\nLL | |     });\n   | |______^ help: try: `\"foo\".is_ascii()`\n\nerror: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:43:5\n   |\nLL | /     \"foo\".chars().any(|c| {\nLL | |\nLL | |\nLL | |         let x = c;\nLL | |         !x.is_ascii()\nLL | |     });\n   | |______^ help: try: `!\"foo\".is_ascii()`\n\nerror: checking if a string is ascii using iterators\n  --> tests/ui/needless_character_iteration.rs:50:5\n   |\nLL |     S::default().field().chars().all(|x| x.is_ascii());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `S::default().field().is_ascii()`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_collect.fixed",
    "content": "#![allow(\n    unused,\n    clippy::needless_ifs,\n    clippy::suspicious_map,\n    clippy::iter_count,\n    clippy::manual_contains\n)]\n\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList};\n\n#[warn(clippy::needless_collect)]\n#[allow(unused_variables, clippy::iter_cloned_collect, clippy::iter_next_slice)]\nfn main() {\n    let sample = [1; 5];\n    let len = sample.iter().count();\n    //~^ needless_collect\n    if sample.iter().next().is_none() {\n        //~^ needless_collect\n        // Empty\n    }\n    sample.iter().cloned().any(|x| x == 1);\n    //~^ needless_collect\n\n    let _ = sample.iter().cloned().nth(1).unwrap();\n    //~^ needless_collect\n\n    // #7164 HashMap's and BTreeMap's `len` usage should not be linted\n    sample.iter().map(|x| (x, x)).collect::<HashMap<_, _>>().len();\n    sample.iter().map(|x| (x, x)).collect::<BTreeMap<_, _>>().len();\n\n    sample.iter().map(|x| (x, x)).next().is_none();\n    //~^ needless_collect\n    sample.iter().map(|x| (x, x)).next().is_none();\n    //~^ needless_collect\n\n    // Notice the `HashSet`--this should not be linted\n    sample.iter().collect::<HashSet<_>>().len();\n    // Neither should this\n    sample.iter().collect::<BTreeSet<_>>().len();\n\n    sample.iter().count();\n    //~^ needless_collect\n    sample.iter().next().is_none();\n    //~^ needless_collect\n    sample.iter().cloned().any(|x| x == 1);\n    //~^ needless_collect\n    sample.iter().any(|x| x == &1);\n    //~^ needless_collect\n\n    // `BinaryHeap` doesn't have `contains` method\n    sample.iter().count();\n    //~^ needless_collect\n    sample.iter().next().is_none();\n    //~^ needless_collect\n\n    // Don't lint string from str\n    let _ = [\"\", \"\"].into_iter().collect::<String>().is_empty();\n\n    let _ = sample.iter().next().is_none();\n    //~^ needless_collect\n    let _ = sample.iter().any(|x| x == &0);\n    //~^ needless_collect\n\n    struct VecWrapper<T>(Vec<T>);\n    impl<T> core::ops::Deref for VecWrapper<T> {\n        type Target = Vec<T>;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T> IntoIterator for VecWrapper<T> {\n        type IntoIter = <Vec<T> as IntoIterator>::IntoIter;\n        type Item = <Vec<T> as IntoIterator>::Item;\n        fn into_iter(self) -> Self::IntoIter {\n            self.0.into_iter()\n        }\n    }\n    impl<T> FromIterator<T> for VecWrapper<T> {\n        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {\n            Self(Vec::from_iter(iter))\n        }\n    }\n\n    let _ = sample.iter().next().is_none();\n    //~^ needless_collect\n    let _ = sample.iter().any(|x| x == &0);\n    //~^ needless_collect\n\n    #[allow(clippy::double_parens)]\n    {\n        Vec::<u8>::new().extend((0..10));\n        //~^ needless_collect\n        foo((0..10));\n        //~^ needless_collect\n        bar((0..10).collect::<Vec<_>>(), (0..10));\n        //~^ needless_collect\n        baz((0..10), (), ('a'..='z'))\n        //~^ needless_collect\n    }\n\n    let values = [1, 2, 3, 4];\n    let mut out = vec![];\n    values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();\n    let _y = values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine\n\n    // Don't write a warning if we call `clone()` on the iterator\n    // https://github.com/rust-lang/rust-clippy/issues/13430\n    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n    let _cloned = my_collection.into_iter().clone();\n    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n    let my_iter = my_collection.into_iter();\n    let _cloned = my_iter.clone();\n    // Same for `as_slice()`, for same reason.\n    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n    let _sliced = my_collection.into_iter().as_slice();\n    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n    let my_iter = my_collection.into_iter();\n    let _sliced = my_iter.as_slice();\n    // Assignment outside of main scope\n    {\n        let x;\n        {\n            let xxx: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n            x = xxx.into_iter();\n            for i in x.as_slice() {}\n        }\n    }\n}\n\nfn foo(_: impl IntoIterator<Item = usize>) {}\nfn bar<I: IntoIterator<Item = usize>>(_: Vec<usize>, _: I) {}\nfn baz<I: IntoIterator<Item = usize>>(_: I, _: (), _: impl IntoIterator<Item = char>) {}\n\nmod issue9191 {\n    use std::cell::Cell;\n    use std::collections::HashSet;\n    use std::hash::Hash;\n    use std::marker::PhantomData;\n    use std::ops::Deref;\n\n    fn captures_ref_mut(xs: Vec<i32>, mut ys: HashSet<i32>) {\n        if xs.iter().map(|x| ys.remove(x)).collect::<Vec<_>>().contains(&true) {\n            todo!()\n        }\n    }\n\n    #[derive(Debug, Clone)]\n    struct MyRef<'a>(PhantomData<&'a mut Cell<HashSet<i32>>>, *mut Cell<HashSet<i32>>);\n\n    impl MyRef<'_> {\n        fn new(target: &mut Cell<HashSet<i32>>) -> Self {\n            MyRef(PhantomData, target)\n        }\n\n        fn get(&mut self) -> &mut Cell<HashSet<i32>> {\n            unsafe { &mut *self.1 }\n        }\n    }\n\n    fn captures_phantom(xs: Vec<i32>, mut ys: Cell<HashSet<i32>>) {\n        let mut ys_ref = MyRef::new(&mut ys);\n        if xs\n            .iter()\n            .map({\n                let mut ys_ref = ys_ref.clone();\n                move |x| ys_ref.get().get_mut().remove(x)\n            })\n            .collect::<Vec<_>>()\n            .contains(&true)\n        {\n            todo!()\n        }\n    }\n}\n\npub fn issue8055(v: impl IntoIterator<Item = i32>) -> Result<impl Iterator<Item = i32>, usize> {\n    let mut zeros = 0;\n\n    let res: Vec<_> = v\n        .into_iter()\n        .filter(|i| {\n            if *i == 0 {\n                zeros += 1\n            };\n            *i != 0\n        })\n        .collect();\n\n    if zeros != 0 {\n        return Err(zeros);\n    }\n    Ok(res.into_iter())\n}\n\nmod issue8055_regression {\n    struct Foo<T> {\n        inner: T,\n        marker: core::marker::PhantomData<Self>,\n    }\n\n    impl<T: Iterator> Iterator for Foo<T> {\n        type Item = T::Item;\n        fn next(&mut self) -> Option<Self::Item> {\n            self.inner.next()\n        }\n    }\n\n    fn foo() {\n        Foo {\n            inner: [].iter(),\n            marker: core::marker::PhantomData,\n        }\n        .collect::<Vec<&i32>>()\n        .len();\n    }\n}\n\nfn issue16270() {\n    // Do not lint, `..` implements `Index` but is not `usize`\n    _ = &(1..3).collect::<Vec<i32>>()[..];\n}\n\n#[warn(clippy::needless_collect)]\nmod collect_push_then_iter {\n    use std::collections::{BinaryHeap, LinkedList, VecDeque};\n\n    fn vec_push(iter: impl Iterator<Item = i32>) -> Vec<i32> {\n        \n        //~^ needless_collect\n        \n        iter.chain([1]).map(|x| x + 1).collect()\n    }\n\n    fn vec_push_no_iter(iter: impl Iterator<Item = i32>) {\n        let mut v = iter.collect::<Vec<_>>();\n        v.push(1);\n    }\n\n    fn vec_push_multiple(iter: impl Iterator<Item = i32>) -> Vec<i32> {\n        \n        //~^ needless_collect\n        \n        \n        iter.chain([1, 2]).map(|x| x + 1).collect()\n    }\n\n    fn linked_list_push(iter: impl Iterator<Item = i32>) -> LinkedList<i32> {\n        \n        //~^ needless_collect\n        \n        iter.chain([1]).map(|x| x + 1).collect()\n    }\n\n    fn binary_heap_push(iter: impl Iterator<Item = i32>) -> BinaryHeap<i32> {\n        let mut v = iter.collect::<BinaryHeap<_>>();\n        v.push(1);\n        v.into_iter().map(|x| x + 1).collect()\n    }\n\n    fn vec_push_mixed(iter: impl Iterator<Item = i32>) -> bool {\n        let mut v = iter.collect::<Vec<_>>();\n        let ok = v.contains(&1);\n        v.push(1);\n        ok\n    }\n\n    fn linked_list_extend(iter: impl Iterator<Item = i32>, s: Vec<i32>) -> LinkedList<i32> {\n        \n        //~^ needless_collect\n        \n        iter.chain(s).map(|x| x + 1).collect()\n    }\n\n    fn deque_push_front(iter: impl Iterator<Item = i32>) -> VecDeque<i32> {\n        \n        //~^ needless_collect\n        \n        \n        [1, 2].into_iter().chain(iter).map(|x| x + 1).collect()\n    }\n\n    fn linked_list_push_front_mixed(\n        iter: impl Iterator<Item = i32>,\n        iter2: impl Iterator<Item = i32>,\n    ) -> LinkedList<i32> {\n        \n        //~^ needless_collect\n        \n        \n        \n        \n        \n        \n        \n        [5].into_iter().chain([1, 3].into_iter().chain(iter).chain([2]).chain(iter2)).chain([4, 6]).map(|x| x + 1).collect()\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_collect.rs",
    "content": "#![allow(\n    unused,\n    clippy::needless_ifs,\n    clippy::suspicious_map,\n    clippy::iter_count,\n    clippy::manual_contains\n)]\n\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList};\n\n#[warn(clippy::needless_collect)]\n#[allow(unused_variables, clippy::iter_cloned_collect, clippy::iter_next_slice)]\nfn main() {\n    let sample = [1; 5];\n    let len = sample.iter().collect::<Vec<_>>().len();\n    //~^ needless_collect\n    if sample.iter().collect::<Vec<_>>().is_empty() {\n        //~^ needless_collect\n        // Empty\n    }\n    sample.iter().cloned().collect::<Vec<_>>().contains(&1);\n    //~^ needless_collect\n\n    let _ = sample.iter().cloned().collect::<Vec<_>>()[1];\n    //~^ needless_collect\n\n    // #7164 HashMap's and BTreeMap's `len` usage should not be linted\n    sample.iter().map(|x| (x, x)).collect::<HashMap<_, _>>().len();\n    sample.iter().map(|x| (x, x)).collect::<BTreeMap<_, _>>().len();\n\n    sample.iter().map(|x| (x, x)).collect::<HashMap<_, _>>().is_empty();\n    //~^ needless_collect\n    sample.iter().map(|x| (x, x)).collect::<BTreeMap<_, _>>().is_empty();\n    //~^ needless_collect\n\n    // Notice the `HashSet`--this should not be linted\n    sample.iter().collect::<HashSet<_>>().len();\n    // Neither should this\n    sample.iter().collect::<BTreeSet<_>>().len();\n\n    sample.iter().collect::<LinkedList<_>>().len();\n    //~^ needless_collect\n    sample.iter().collect::<LinkedList<_>>().is_empty();\n    //~^ needless_collect\n    sample.iter().cloned().collect::<LinkedList<_>>().contains(&1);\n    //~^ needless_collect\n    sample.iter().collect::<LinkedList<_>>().contains(&&1);\n    //~^ needless_collect\n\n    // `BinaryHeap` doesn't have `contains` method\n    sample.iter().collect::<BinaryHeap<_>>().len();\n    //~^ needless_collect\n    sample.iter().collect::<BinaryHeap<_>>().is_empty();\n    //~^ needless_collect\n\n    // Don't lint string from str\n    let _ = [\"\", \"\"].into_iter().collect::<String>().is_empty();\n\n    let _ = sample.iter().collect::<HashSet<_>>().is_empty();\n    //~^ needless_collect\n    let _ = sample.iter().collect::<HashSet<_>>().contains(&&0);\n    //~^ needless_collect\n\n    struct VecWrapper<T>(Vec<T>);\n    impl<T> core::ops::Deref for VecWrapper<T> {\n        type Target = Vec<T>;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T> IntoIterator for VecWrapper<T> {\n        type IntoIter = <Vec<T> as IntoIterator>::IntoIter;\n        type Item = <Vec<T> as IntoIterator>::Item;\n        fn into_iter(self) -> Self::IntoIter {\n            self.0.into_iter()\n        }\n    }\n    impl<T> FromIterator<T> for VecWrapper<T> {\n        fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {\n            Self(Vec::from_iter(iter))\n        }\n    }\n\n    let _ = sample.iter().collect::<VecWrapper<_>>().is_empty();\n    //~^ needless_collect\n    let _ = sample.iter().collect::<VecWrapper<_>>().contains(&&0);\n    //~^ needless_collect\n\n    #[allow(clippy::double_parens)]\n    {\n        Vec::<u8>::new().extend((0..10).collect::<Vec<_>>());\n        //~^ needless_collect\n        foo((0..10).collect::<Vec<_>>());\n        //~^ needless_collect\n        bar((0..10).collect::<Vec<_>>(), (0..10).collect::<Vec<_>>());\n        //~^ needless_collect\n        baz((0..10), (), ('a'..='z').collect::<Vec<_>>())\n        //~^ needless_collect\n    }\n\n    let values = [1, 2, 3, 4];\n    let mut out = vec![];\n    values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();\n    let _y = values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine\n\n    // Don't write a warning if we call `clone()` on the iterator\n    // https://github.com/rust-lang/rust-clippy/issues/13430\n    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n    let _cloned = my_collection.into_iter().clone();\n    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n    let my_iter = my_collection.into_iter();\n    let _cloned = my_iter.clone();\n    // Same for `as_slice()`, for same reason.\n    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n    let _sliced = my_collection.into_iter().as_slice();\n    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n    let my_iter = my_collection.into_iter();\n    let _sliced = my_iter.as_slice();\n    // Assignment outside of main scope\n    {\n        let x;\n        {\n            let xxx: Vec<()> = vec![()].into_iter().map(|()| {}).collect();\n            x = xxx.into_iter();\n            for i in x.as_slice() {}\n        }\n    }\n}\n\nfn foo(_: impl IntoIterator<Item = usize>) {}\nfn bar<I: IntoIterator<Item = usize>>(_: Vec<usize>, _: I) {}\nfn baz<I: IntoIterator<Item = usize>>(_: I, _: (), _: impl IntoIterator<Item = char>) {}\n\nmod issue9191 {\n    use std::cell::Cell;\n    use std::collections::HashSet;\n    use std::hash::Hash;\n    use std::marker::PhantomData;\n    use std::ops::Deref;\n\n    fn captures_ref_mut(xs: Vec<i32>, mut ys: HashSet<i32>) {\n        if xs.iter().map(|x| ys.remove(x)).collect::<Vec<_>>().contains(&true) {\n            todo!()\n        }\n    }\n\n    #[derive(Debug, Clone)]\n    struct MyRef<'a>(PhantomData<&'a mut Cell<HashSet<i32>>>, *mut Cell<HashSet<i32>>);\n\n    impl MyRef<'_> {\n        fn new(target: &mut Cell<HashSet<i32>>) -> Self {\n            MyRef(PhantomData, target)\n        }\n\n        fn get(&mut self) -> &mut Cell<HashSet<i32>> {\n            unsafe { &mut *self.1 }\n        }\n    }\n\n    fn captures_phantom(xs: Vec<i32>, mut ys: Cell<HashSet<i32>>) {\n        let mut ys_ref = MyRef::new(&mut ys);\n        if xs\n            .iter()\n            .map({\n                let mut ys_ref = ys_ref.clone();\n                move |x| ys_ref.get().get_mut().remove(x)\n            })\n            .collect::<Vec<_>>()\n            .contains(&true)\n        {\n            todo!()\n        }\n    }\n}\n\npub fn issue8055(v: impl IntoIterator<Item = i32>) -> Result<impl Iterator<Item = i32>, usize> {\n    let mut zeros = 0;\n\n    let res: Vec<_> = v\n        .into_iter()\n        .filter(|i| {\n            if *i == 0 {\n                zeros += 1\n            };\n            *i != 0\n        })\n        .collect();\n\n    if zeros != 0 {\n        return Err(zeros);\n    }\n    Ok(res.into_iter())\n}\n\nmod issue8055_regression {\n    struct Foo<T> {\n        inner: T,\n        marker: core::marker::PhantomData<Self>,\n    }\n\n    impl<T: Iterator> Iterator for Foo<T> {\n        type Item = T::Item;\n        fn next(&mut self) -> Option<Self::Item> {\n            self.inner.next()\n        }\n    }\n\n    fn foo() {\n        Foo {\n            inner: [].iter(),\n            marker: core::marker::PhantomData,\n        }\n        .collect::<Vec<&i32>>()\n        .len();\n    }\n}\n\nfn issue16270() {\n    // Do not lint, `..` implements `Index` but is not `usize`\n    _ = &(1..3).collect::<Vec<i32>>()[..];\n}\n\n#[warn(clippy::needless_collect)]\nmod collect_push_then_iter {\n    use std::collections::{BinaryHeap, LinkedList, VecDeque};\n\n    fn vec_push(iter: impl Iterator<Item = i32>) -> Vec<i32> {\n        let mut v = iter.collect::<Vec<_>>();\n        //~^ needless_collect\n        v.push(1);\n        v.into_iter().map(|x| x + 1).collect()\n    }\n\n    fn vec_push_no_iter(iter: impl Iterator<Item = i32>) {\n        let mut v = iter.collect::<Vec<_>>();\n        v.push(1);\n    }\n\n    fn vec_push_multiple(iter: impl Iterator<Item = i32>) -> Vec<i32> {\n        let mut v = iter.collect::<Vec<_>>();\n        //~^ needless_collect\n        v.push(1);\n        v.push(2);\n        v.into_iter().map(|x| x + 1).collect()\n    }\n\n    fn linked_list_push(iter: impl Iterator<Item = i32>) -> LinkedList<i32> {\n        let mut v = iter.collect::<LinkedList<_>>();\n        //~^ needless_collect\n        v.push_back(1);\n        v.into_iter().map(|x| x + 1).collect()\n    }\n\n    fn binary_heap_push(iter: impl Iterator<Item = i32>) -> BinaryHeap<i32> {\n        let mut v = iter.collect::<BinaryHeap<_>>();\n        v.push(1);\n        v.into_iter().map(|x| x + 1).collect()\n    }\n\n    fn vec_push_mixed(iter: impl Iterator<Item = i32>) -> bool {\n        let mut v = iter.collect::<Vec<_>>();\n        let ok = v.contains(&1);\n        v.push(1);\n        ok\n    }\n\n    fn linked_list_extend(iter: impl Iterator<Item = i32>, s: Vec<i32>) -> LinkedList<i32> {\n        let mut ll = iter.collect::<LinkedList<_>>();\n        //~^ needless_collect\n        ll.extend(s);\n        ll.into_iter().map(|x| x + 1).collect()\n    }\n\n    fn deque_push_front(iter: impl Iterator<Item = i32>) -> VecDeque<i32> {\n        let mut v = iter.collect::<VecDeque<_>>();\n        //~^ needless_collect\n        v.push_front(1);\n        v.push_front(2);\n        v.into_iter().map(|x| x + 1).collect()\n    }\n\n    fn linked_list_push_front_mixed(\n        iter: impl Iterator<Item = i32>,\n        iter2: impl Iterator<Item = i32>,\n    ) -> LinkedList<i32> {\n        let mut v = iter.collect::<LinkedList<_>>();\n        //~^ needless_collect\n        v.push_front(1);\n        v.push_back(2);\n        v.push_front(3);\n        v.extend(iter2);\n        v.push_back(4);\n        v.push_front(5);\n        v.push_back(6);\n        v.into_iter().map(|x| x + 1).collect()\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_collect.stderr",
    "content": "error: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:15:29\n   |\nLL |     let len = sample.iter().collect::<Vec<_>>().len();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()`\n   |\n   = note: `-D clippy::needless-collect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:17:22\n   |\nLL |     if sample.iter().collect::<Vec<_>>().is_empty() {\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:21:28\n   |\nLL |     sample.iter().cloned().collect::<Vec<_>>().contains(&1);\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:24:36\n   |\nLL |     let _ = sample.iter().cloned().collect::<Vec<_>>()[1];\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `nth(1).unwrap()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:31:35\n   |\nLL |     sample.iter().map(|x| (x, x)).collect::<HashMap<_, _>>().is_empty();\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:33:35\n   |\nLL |     sample.iter().map(|x| (x, x)).collect::<BTreeMap<_, _>>().is_empty();\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:41:19\n   |\nLL |     sample.iter().collect::<LinkedList<_>>().len();\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:43:19\n   |\nLL |     sample.iter().collect::<LinkedList<_>>().is_empty();\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:45:28\n   |\nLL |     sample.iter().cloned().collect::<LinkedList<_>>().contains(&1);\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:47:19\n   |\nLL |     sample.iter().collect::<LinkedList<_>>().contains(&&1);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &1)`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:51:19\n   |\nLL |     sample.iter().collect::<BinaryHeap<_>>().len();\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:53:19\n   |\nLL |     sample.iter().collect::<BinaryHeap<_>>().is_empty();\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:59:27\n   |\nLL |     let _ = sample.iter().collect::<HashSet<_>>().is_empty();\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:61:27\n   |\nLL |     let _ = sample.iter().collect::<HashSet<_>>().contains(&&0);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:84:27\n   |\nLL |     let _ = sample.iter().collect::<VecWrapper<_>>().is_empty();\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:86:27\n   |\nLL |     let _ = sample.iter().collect::<VecWrapper<_>>().contains(&&0);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)`\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:91:40\n   |\nLL |         Vec::<u8>::new().extend((0..10).collect::<Vec<_>>());\n   |                                        ^^^^^^^^^^^^^^^^^^^^ help: remove this call\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:93:20\n   |\nLL |         foo((0..10).collect::<Vec<_>>());\n   |                    ^^^^^^^^^^^^^^^^^^^^ help: remove this call\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:95:49\n   |\nLL |         bar((0..10).collect::<Vec<_>>(), (0..10).collect::<Vec<_>>());\n   |                                                 ^^^^^^^^^^^^^^^^^^^^ help: remove this call\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:97:37\n   |\nLL |         baz((0..10), (), ('a'..='z').collect::<Vec<_>>())\n   |                                     ^^^^^^^^^^^^^^^^^^^^ help: remove this call\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:228:26\n   |\nLL |         let mut v = iter.collect::<Vec<_>>();\n   |                          ^^^^^^^\n...\nLL |         v.into_iter().map(|x| x + 1).collect()\n   |         ------------- the iterator could be used here instead\n   |\nhelp: use the original Iterator instead of collecting it and then producing a new one\n   |\nLL ~         \nLL |\nLL ~         \nLL ~         iter.chain([1]).map(|x| x + 1).collect()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:240:26\n   |\nLL |         let mut v = iter.collect::<Vec<_>>();\n   |                          ^^^^^^^\n...\nLL |         v.into_iter().map(|x| x + 1).collect()\n   |         ------------- the iterator could be used here instead\n   |\nhelp: use the original Iterator instead of collecting it and then producing a new one\n   |\nLL ~         \nLL |\nLL ~         \nLL ~         \nLL ~         iter.chain([1, 2]).map(|x| x + 1).collect()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:248:26\n   |\nLL |         let mut v = iter.collect::<LinkedList<_>>();\n   |                          ^^^^^^^\n...\nLL |         v.into_iter().map(|x| x + 1).collect()\n   |         ------------- the iterator could be used here instead\n   |\nhelp: use the original Iterator instead of collecting it and then producing a new one\n   |\nLL ~         \nLL |\nLL ~         \nLL ~         iter.chain([1]).map(|x| x + 1).collect()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:268:27\n   |\nLL |         let mut ll = iter.collect::<LinkedList<_>>();\n   |                           ^^^^^^^\n...\nLL |         ll.into_iter().map(|x| x + 1).collect()\n   |         -------------- the iterator could be used here instead\n   |\nhelp: use the original Iterator instead of collecting it and then producing a new one\n   |\nLL ~         \nLL |\nLL ~         \nLL ~         iter.chain(s).map(|x| x + 1).collect()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:275:26\n   |\nLL |         let mut v = iter.collect::<VecDeque<_>>();\n   |                          ^^^^^^^\n...\nLL |         v.into_iter().map(|x| x + 1).collect()\n   |         ------------- the iterator could be used here instead\n   |\nhelp: use the original Iterator instead of collecting it and then producing a new one\n   |\nLL ~         \nLL |\nLL ~         \nLL ~         \nLL ~         [1, 2].into_iter().chain(iter).map(|x| x + 1).collect()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect.rs:286:26\n   |\nLL |         let mut v = iter.collect::<LinkedList<_>>();\n   |                          ^^^^^^^\n...\nLL |         v.into_iter().map(|x| x + 1).collect()\n   |         ------------- the iterator could be used here instead\n   |\nhelp: use the original Iterator instead of collecting it and then producing a new one\n   |\nLL ~         \nLL |\nLL ~         \nLL ~         \nLL ~         \nLL ~         \nLL ~         \nLL ~         \nLL ~         \nLL ~         [5].into_iter().chain([1, 3].into_iter().chain(iter).chain([2]).chain(iter2)).chain([4, 6]).map(|x| x + 1).collect()\n   |\n\nerror: aborting due to 26 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_collect_indirect.fixed",
    "content": "#![allow(\n    clippy::uninlined_format_args,\n    clippy::useless_vec,\n    clippy::needless_ifs,\n    clippy::iter_next_slice,\n    clippy::iter_count\n)]\n#![warn(clippy::needless_collect)]\n\nuse std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};\n\nfn main() {\n    let sample = [1; 5];\n    \n    //~^ needless_collect\n\n    sample.iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();\n    \n    //~^ needless_collect\n\n    sample.iter().count();\n    \n    //~^ needless_collect\n\n    sample.iter().next().is_none();\n    \n    //~^ needless_collect\n\n    sample.iter().any(|x| x == &5);\n    let indirect_negative = sample.iter().collect::<Vec<_>>();\n    indirect_negative.len();\n    indirect_negative\n        .into_iter()\n        .map(|x| (*x, *x + 1))\n        .collect::<HashMap<_, _>>();\n\n    // #6202\n    let a = \"a\".to_string();\n    let sample = vec![a.clone(), \"b\".to_string(), \"c\".to_string()];\n    \n    //~^ needless_collect\n\n    sample.into_iter().any(|x| x == a);\n\n    // Fix #5991\n    let vec_a = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    let vec_b = vec_a.iter().collect::<Vec<_>>();\n    if vec_b.len() > 3 {}\n    let other_vec = vec![1, 3, 12, 4, 16, 2];\n    let we_got_the_same_numbers = other_vec.iter().filter(|item| vec_b.contains(item)).collect::<Vec<_>>();\n\n    // Fix #6297\n    let sample = [1; 5];\n    let multiple_indirect = sample.iter().collect::<Vec<_>>();\n    let sample2 = vec![2, 3];\n    if multiple_indirect.is_empty() {\n        // do something\n    } else {\n        let found = sample2\n            .iter()\n            .filter(|i| multiple_indirect.iter().any(|s| **s % **i == 0))\n            .collect::<Vec<_>>();\n    }\n}\n\nmod issue7110 {\n    // #7110 - lint for type annotation cases\n    use super::*;\n\n    fn lint_vec(string: &str) -> usize {\n        \n        //~^ needless_collect\n\n        string.split('/').count()\n    }\n    fn lint_vec_deque() -> usize {\n        let sample = [1; 5];\n        \n        //~^ needless_collect\n\n        sample.iter().count()\n    }\n    fn lint_linked_list() -> usize {\n        let sample = [1; 5];\n        \n        //~^ needless_collect\n\n        sample.iter().count()\n    }\n    fn lint_binary_heap() -> usize {\n        let sample = [1; 5];\n        \n        //~^ needless_collect\n\n        sample.iter().count()\n    }\n    fn dont_lint(string: &str) -> usize {\n        let buffer: Vec<&str> = string.split('/').collect();\n        for buff in &buffer {\n            println!(\"{}\", buff);\n        }\n        buffer.len()\n    }\n}\n\nmod issue7975 {\n    use super::*;\n\n    fn direct_mapping_with_used_mutable_reference() -> Vec<()> {\n        let test_vec: Vec<()> = vec![];\n        let mut vec_2: Vec<()> = vec![];\n        let mut_ref = &mut vec_2;\n        let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();\n        collected_vec.into_iter().map(|_| mut_ref.push(())).collect()\n    }\n\n    fn indirectly_mapping_with_used_mutable_reference() -> Vec<()> {\n        let test_vec: Vec<()> = vec![];\n        let mut vec_2: Vec<()> = vec![];\n        let mut_ref = &mut vec_2;\n        let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();\n        let iter = collected_vec.into_iter();\n        iter.map(|_| mut_ref.push(())).collect()\n    }\n\n    fn indirect_collect_after_indirect_mapping_with_used_mutable_reference() -> Vec<()> {\n        let test_vec: Vec<()> = vec![];\n        let mut vec_2: Vec<()> = vec![];\n        let mut_ref = &mut vec_2;\n        let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();\n        let iter = collected_vec.into_iter();\n        let mapped_iter = iter.map(|_| mut_ref.push(()));\n        mapped_iter.collect()\n    }\n}\n\nfn allow_test() {\n    #[allow(clippy::needless_collect)]\n    let v = [1].iter().collect::<Vec<_>>();\n    v.into_iter().collect::<HashSet<_>>();\n}\n\nmod issue_8553 {\n    fn test_for() {\n        let vec = vec![1, 2];\n        let w: Vec<usize> = vec.iter().map(|i| i * i).collect();\n\n        for i in 0..2 {\n            // Do not lint, because this method call is in the loop\n            w.contains(&i);\n        }\n\n        for i in 0..2 {\n            \n            //~^ needless_collect\n\n            let z: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            // Do lint\n            vec.iter().map(|k| k * k).any(|x| x == i);\n            for j in 0..2 {\n                // Do not lint, because this method call is in the loop\n                z.contains(&j);\n            }\n        }\n\n        // Do not lint, because this variable is used.\n        w.contains(&0);\n    }\n\n    fn test_while() {\n        let vec = vec![1, 2];\n        let x: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut n = 0;\n        while n > 1 {\n            // Do not lint, because this method call is in the loop\n            x.contains(&n);\n            n += 1;\n        }\n\n        while n > 2 {\n            \n            //~^ needless_collect\n\n            let z: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            // Do lint\n            vec.iter().map(|k| k * k).any(|x| x == n);\n            n += 1;\n            while n > 4 {\n                // Do not lint, because this method call is in the loop\n                z.contains(&n);\n                n += 1;\n            }\n        }\n    }\n\n    fn test_loop() {\n        let vec = vec![1, 2];\n        let x: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut n = 0;\n        loop {\n            if n < 1 {\n                // Do not lint, because this method call is in the loop\n                x.contains(&n);\n                n += 1;\n            } else {\n                break;\n            }\n        }\n\n        loop {\n            if n < 2 {\n                \n                //~^ needless_collect\n\n                let z: Vec<usize> = vec.iter().map(|k| k * k).collect();\n                // Do lint\n                vec.iter().map(|k| k * k).any(|x| x == n);\n                n += 1;\n                loop {\n                    if n < 4 {\n                        // Do not lint, because this method call is in the loop\n                        z.contains(&n);\n                        n += 1;\n                    } else {\n                        break;\n                    }\n                }\n            } else {\n                break;\n            }\n        }\n    }\n\n    fn test_while_let() {\n        let vec = vec![1, 2];\n        let x: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let optional = Some(0);\n        let mut n = 0;\n        while let Some(value) = optional {\n            if n < 1 {\n                // Do not lint, because this method call is in the loop\n                x.contains(&n);\n                n += 1;\n            } else {\n                break;\n            }\n        }\n\n        while let Some(value) = optional {\n            \n            //~^ needless_collect\n\n            let z: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            if n < 2 {\n                // Do lint\n                vec.iter().map(|k| k * k).any(|x| x == n);\n                n += 1;\n            } else {\n                break;\n            }\n\n            while let Some(value) = optional {\n                if n < 4 {\n                    // Do not lint, because this method call is in the loop\n                    z.contains(&n);\n                    n += 1;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n\n    fn test_if_cond() {\n        let vec = vec![1, 2];\n        let v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        \n        //~^ needless_collect\n\n        // Do lint\n        for _ in 0..v.iter().count() {\n            todo!();\n        }\n    }\n\n    fn test_if_cond_false_case() {\n        let vec = vec![1, 2];\n        let v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let w = v.iter().collect::<Vec<_>>();\n        // Do not lint, because w is used.\n        for _ in 0..w.len() {\n            todo!();\n        }\n\n        w.len();\n    }\n\n    fn test_while_cond() {\n        let mut vec = vec![1, 2];\n        let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        \n        //~^ needless_collect\n\n        // Do lint\n        while 1 == v.iter().count() {\n            todo!();\n        }\n    }\n\n    fn test_while_cond_false_case() {\n        let mut vec = vec![1, 2];\n        let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut w = v.iter().collect::<Vec<_>>();\n        // Do not lint, because w is used.\n        while 1 == w.len() {\n            todo!();\n        }\n\n        w.len();\n    }\n\n    fn test_while_let_cond() {\n        let mut vec = vec![1, 2];\n        let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        \n        //~^ needless_collect\n\n        // Do lint\n        while let Some(i) = Some(v.iter().count()) {\n            todo!();\n        }\n    }\n\n    fn test_while_let_cond_false_case() {\n        let mut vec = vec![1, 2];\n        let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut w = v.iter().collect::<Vec<_>>();\n        // Do not lint, because w is used.\n        while let Some(i) = Some(w.len()) {\n            todo!();\n        }\n        w.len();\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_collect_indirect.rs",
    "content": "#![allow(\n    clippy::uninlined_format_args,\n    clippy::useless_vec,\n    clippy::needless_ifs,\n    clippy::iter_next_slice,\n    clippy::iter_count\n)]\n#![warn(clippy::needless_collect)]\n\nuse std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};\n\nfn main() {\n    let sample = [1; 5];\n    let indirect_iter = sample.iter().collect::<Vec<_>>();\n    //~^ needless_collect\n\n    indirect_iter.into_iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();\n    let indirect_len = sample.iter().collect::<VecDeque<_>>();\n    //~^ needless_collect\n\n    indirect_len.len();\n    let indirect_empty = sample.iter().collect::<VecDeque<_>>();\n    //~^ needless_collect\n\n    indirect_empty.is_empty();\n    let indirect_contains = sample.iter().collect::<VecDeque<_>>();\n    //~^ needless_collect\n\n    indirect_contains.contains(&&5);\n    let indirect_negative = sample.iter().collect::<Vec<_>>();\n    indirect_negative.len();\n    indirect_negative\n        .into_iter()\n        .map(|x| (*x, *x + 1))\n        .collect::<HashMap<_, _>>();\n\n    // #6202\n    let a = \"a\".to_string();\n    let sample = vec![a.clone(), \"b\".to_string(), \"c\".to_string()];\n    let non_copy_contains = sample.into_iter().collect::<Vec<_>>();\n    //~^ needless_collect\n\n    non_copy_contains.contains(&a);\n\n    // Fix #5991\n    let vec_a = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n    let vec_b = vec_a.iter().collect::<Vec<_>>();\n    if vec_b.len() > 3 {}\n    let other_vec = vec![1, 3, 12, 4, 16, 2];\n    let we_got_the_same_numbers = other_vec.iter().filter(|item| vec_b.contains(item)).collect::<Vec<_>>();\n\n    // Fix #6297\n    let sample = [1; 5];\n    let multiple_indirect = sample.iter().collect::<Vec<_>>();\n    let sample2 = vec![2, 3];\n    if multiple_indirect.is_empty() {\n        // do something\n    } else {\n        let found = sample2\n            .iter()\n            .filter(|i| multiple_indirect.iter().any(|s| **s % **i == 0))\n            .collect::<Vec<_>>();\n    }\n}\n\nmod issue7110 {\n    // #7110 - lint for type annotation cases\n    use super::*;\n\n    fn lint_vec(string: &str) -> usize {\n        let buffer: Vec<&str> = string.split('/').collect();\n        //~^ needless_collect\n\n        buffer.len()\n    }\n    fn lint_vec_deque() -> usize {\n        let sample = [1; 5];\n        let indirect_len: VecDeque<_> = sample.iter().collect();\n        //~^ needless_collect\n\n        indirect_len.len()\n    }\n    fn lint_linked_list() -> usize {\n        let sample = [1; 5];\n        let indirect_len: LinkedList<_> = sample.iter().collect();\n        //~^ needless_collect\n\n        indirect_len.len()\n    }\n    fn lint_binary_heap() -> usize {\n        let sample = [1; 5];\n        let indirect_len: BinaryHeap<_> = sample.iter().collect();\n        //~^ needless_collect\n\n        indirect_len.len()\n    }\n    fn dont_lint(string: &str) -> usize {\n        let buffer: Vec<&str> = string.split('/').collect();\n        for buff in &buffer {\n            println!(\"{}\", buff);\n        }\n        buffer.len()\n    }\n}\n\nmod issue7975 {\n    use super::*;\n\n    fn direct_mapping_with_used_mutable_reference() -> Vec<()> {\n        let test_vec: Vec<()> = vec![];\n        let mut vec_2: Vec<()> = vec![];\n        let mut_ref = &mut vec_2;\n        let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();\n        collected_vec.into_iter().map(|_| mut_ref.push(())).collect()\n    }\n\n    fn indirectly_mapping_with_used_mutable_reference() -> Vec<()> {\n        let test_vec: Vec<()> = vec![];\n        let mut vec_2: Vec<()> = vec![];\n        let mut_ref = &mut vec_2;\n        let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();\n        let iter = collected_vec.into_iter();\n        iter.map(|_| mut_ref.push(())).collect()\n    }\n\n    fn indirect_collect_after_indirect_mapping_with_used_mutable_reference() -> Vec<()> {\n        let test_vec: Vec<()> = vec![];\n        let mut vec_2: Vec<()> = vec![];\n        let mut_ref = &mut vec_2;\n        let collected_vec: Vec<_> = test_vec.into_iter().map(|_| mut_ref.push(())).collect();\n        let iter = collected_vec.into_iter();\n        let mapped_iter = iter.map(|_| mut_ref.push(()));\n        mapped_iter.collect()\n    }\n}\n\nfn allow_test() {\n    #[allow(clippy::needless_collect)]\n    let v = [1].iter().collect::<Vec<_>>();\n    v.into_iter().collect::<HashSet<_>>();\n}\n\nmod issue_8553 {\n    fn test_for() {\n        let vec = vec![1, 2];\n        let w: Vec<usize> = vec.iter().map(|i| i * i).collect();\n\n        for i in 0..2 {\n            // Do not lint, because this method call is in the loop\n            w.contains(&i);\n        }\n\n        for i in 0..2 {\n            let y: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            //~^ needless_collect\n\n            let z: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            // Do lint\n            y.contains(&i);\n            for j in 0..2 {\n                // Do not lint, because this method call is in the loop\n                z.contains(&j);\n            }\n        }\n\n        // Do not lint, because this variable is used.\n        w.contains(&0);\n    }\n\n    fn test_while() {\n        let vec = vec![1, 2];\n        let x: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut n = 0;\n        while n > 1 {\n            // Do not lint, because this method call is in the loop\n            x.contains(&n);\n            n += 1;\n        }\n\n        while n > 2 {\n            let y: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            //~^ needless_collect\n\n            let z: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            // Do lint\n            y.contains(&n);\n            n += 1;\n            while n > 4 {\n                // Do not lint, because this method call is in the loop\n                z.contains(&n);\n                n += 1;\n            }\n        }\n    }\n\n    fn test_loop() {\n        let vec = vec![1, 2];\n        let x: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut n = 0;\n        loop {\n            if n < 1 {\n                // Do not lint, because this method call is in the loop\n                x.contains(&n);\n                n += 1;\n            } else {\n                break;\n            }\n        }\n\n        loop {\n            if n < 2 {\n                let y: Vec<usize> = vec.iter().map(|k| k * k).collect();\n                //~^ needless_collect\n\n                let z: Vec<usize> = vec.iter().map(|k| k * k).collect();\n                // Do lint\n                y.contains(&n);\n                n += 1;\n                loop {\n                    if n < 4 {\n                        // Do not lint, because this method call is in the loop\n                        z.contains(&n);\n                        n += 1;\n                    } else {\n                        break;\n                    }\n                }\n            } else {\n                break;\n            }\n        }\n    }\n\n    fn test_while_let() {\n        let vec = vec![1, 2];\n        let x: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let optional = Some(0);\n        let mut n = 0;\n        while let Some(value) = optional {\n            if n < 1 {\n                // Do not lint, because this method call is in the loop\n                x.contains(&n);\n                n += 1;\n            } else {\n                break;\n            }\n        }\n\n        while let Some(value) = optional {\n            let y: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            //~^ needless_collect\n\n            let z: Vec<usize> = vec.iter().map(|k| k * k).collect();\n            if n < 2 {\n                // Do lint\n                y.contains(&n);\n                n += 1;\n            } else {\n                break;\n            }\n\n            while let Some(value) = optional {\n                if n < 4 {\n                    // Do not lint, because this method call is in the loop\n                    z.contains(&n);\n                    n += 1;\n                } else {\n                    break;\n                }\n            }\n        }\n    }\n\n    fn test_if_cond() {\n        let vec = vec![1, 2];\n        let v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let w = v.iter().collect::<Vec<_>>();\n        //~^ needless_collect\n\n        // Do lint\n        for _ in 0..w.len() {\n            todo!();\n        }\n    }\n\n    fn test_if_cond_false_case() {\n        let vec = vec![1, 2];\n        let v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let w = v.iter().collect::<Vec<_>>();\n        // Do not lint, because w is used.\n        for _ in 0..w.len() {\n            todo!();\n        }\n\n        w.len();\n    }\n\n    fn test_while_cond() {\n        let mut vec = vec![1, 2];\n        let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut w = v.iter().collect::<Vec<_>>();\n        //~^ needless_collect\n\n        // Do lint\n        while 1 == w.len() {\n            todo!();\n        }\n    }\n\n    fn test_while_cond_false_case() {\n        let mut vec = vec![1, 2];\n        let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut w = v.iter().collect::<Vec<_>>();\n        // Do not lint, because w is used.\n        while 1 == w.len() {\n            todo!();\n        }\n\n        w.len();\n    }\n\n    fn test_while_let_cond() {\n        let mut vec = vec![1, 2];\n        let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut w = v.iter().collect::<Vec<_>>();\n        //~^ needless_collect\n\n        // Do lint\n        while let Some(i) = Some(w.len()) {\n            todo!();\n        }\n    }\n\n    fn test_while_let_cond_false_case() {\n        let mut vec = vec![1, 2];\n        let mut v: Vec<usize> = vec.iter().map(|i| i * i).collect();\n        let mut w = v.iter().collect::<Vec<_>>();\n        // Do not lint, because w is used.\n        while let Some(i) = Some(w.len()) {\n            todo!();\n        }\n        w.len();\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_collect_indirect.stderr",
    "content": "error: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:14:39\n   |\nLL |     let indirect_iter = sample.iter().collect::<Vec<_>>();\n   |                                       ^^^^^^^\n...\nLL |     indirect_iter.into_iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();\n   |     ------------------------- the iterator could be used here instead\n   |\n   = note: `-D clippy::needless-collect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]`\nhelp: use the original Iterator instead of collecting it and then producing a new one\n   |\nLL ~     \nLL |\nLL |\nLL ~     sample.iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:18:38\n   |\nLL |     let indirect_len = sample.iter().collect::<VecDeque<_>>();\n   |                                      ^^^^^^^\n...\nLL |     indirect_len.len();\n   |     ------------------ the iterator could be used here instead\n   |\nhelp: take the original Iterator's count instead of collecting it and finding the length\n   |\nLL ~     \nLL |\nLL |\nLL ~     sample.iter().count();\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:22:40\n   |\nLL |     let indirect_empty = sample.iter().collect::<VecDeque<_>>();\n   |                                        ^^^^^^^\n...\nLL |     indirect_empty.is_empty();\n   |     ------------------------- the iterator could be used here instead\n   |\nhelp: check if the original Iterator has anything instead of collecting it and seeing if it's empty\n   |\nLL ~     \nLL |\nLL |\nLL ~     sample.iter().next().is_none();\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:26:43\n   |\nLL |     let indirect_contains = sample.iter().collect::<VecDeque<_>>();\n   |                                           ^^^^^^^\n...\nLL |     indirect_contains.contains(&&5);\n   |     ------------------------------- the iterator could be used here instead\n   |\nhelp: check if the original Iterator contains an element instead of collecting then checking\n   |\nLL ~     \nLL |\nLL |\nLL ~     sample.iter().any(|x| x == &5);\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:40:48\n   |\nLL |     let non_copy_contains = sample.into_iter().collect::<Vec<_>>();\n   |                                                ^^^^^^^\n...\nLL |     non_copy_contains.contains(&a);\n   |     ------------------------------ the iterator could be used here instead\n   |\nhelp: check if the original Iterator contains an element instead of collecting then checking\n   |\nLL ~     \nLL |\nLL |\nLL ~     sample.into_iter().any(|x| x == a);\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:71:51\n   |\nLL |         let buffer: Vec<&str> = string.split('/').collect();\n   |                                                   ^^^^^^^\n...\nLL |         buffer.len()\n   |         ------------ the iterator could be used here instead\n   |\nhelp: take the original Iterator's count instead of collecting it and finding the length\n   |\nLL ~         \nLL |\nLL |\nLL ~         string.split('/').count()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:78:55\n   |\nLL |         let indirect_len: VecDeque<_> = sample.iter().collect();\n   |                                                       ^^^^^^^\n...\nLL |         indirect_len.len()\n   |         ------------------ the iterator could be used here instead\n   |\nhelp: take the original Iterator's count instead of collecting it and finding the length\n   |\nLL ~         \nLL |\nLL |\nLL ~         sample.iter().count()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:85:57\n   |\nLL |         let indirect_len: LinkedList<_> = sample.iter().collect();\n   |                                                         ^^^^^^^\n...\nLL |         indirect_len.len()\n   |         ------------------ the iterator could be used here instead\n   |\nhelp: take the original Iterator's count instead of collecting it and finding the length\n   |\nLL ~         \nLL |\nLL |\nLL ~         sample.iter().count()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:92:57\n   |\nLL |         let indirect_len: BinaryHeap<_> = sample.iter().collect();\n   |                                                         ^^^^^^^\n...\nLL |         indirect_len.len()\n   |         ------------------ the iterator could be used here instead\n   |\nhelp: take the original Iterator's count instead of collecting it and finding the length\n   |\nLL ~         \nLL |\nLL |\nLL ~         sample.iter().count()\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:154:59\n   |\nLL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();\n   |                                                           ^^^^^^^\n...\nLL |             y.contains(&i);\n   |             -------------- the iterator could be used here instead\n   |\nhelp: check if the original Iterator contains an element instead of collecting then checking\n   |\nLL ~             \nLL |\n...\nLL |             // Do lint\nLL ~             vec.iter().map(|k| k * k).any(|x| x == i);\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:181:59\n   |\nLL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();\n   |                                                           ^^^^^^^\n...\nLL |             y.contains(&n);\n   |             -------------- the iterator could be used here instead\n   |\nhelp: check if the original Iterator contains an element instead of collecting then checking\n   |\nLL ~             \nLL |\n...\nLL |             // Do lint\nLL ~             vec.iter().map(|k| k * k).any(|x| x == n);\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:212:63\n   |\nLL |                 let y: Vec<usize> = vec.iter().map(|k| k * k).collect();\n   |                                                               ^^^^^^^\n...\nLL |                 y.contains(&n);\n   |                 -------------- the iterator could be used here instead\n   |\nhelp: check if the original Iterator contains an element instead of collecting then checking\n   |\nLL ~                 \nLL |\n...\nLL |                 // Do lint\nLL ~                 vec.iter().map(|k| k * k).any(|x| x == n);\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:250:59\n   |\nLL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();\n   |                                                           ^^^^^^^\n...\nLL |                 y.contains(&n);\n   |                 -------------- the iterator could be used here instead\n   |\nhelp: check if the original Iterator contains an element instead of collecting then checking\n   |\nLL ~             \nLL |\n...\nLL |                 // Do lint\nLL ~                 vec.iter().map(|k| k * k).any(|x| x == n);\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:277:26\n   |\nLL |         let w = v.iter().collect::<Vec<_>>();\n   |                          ^^^^^^^\n...\nLL |         for _ in 0..w.len() {\n   |                     ------- the iterator could be used here instead\n   |\nhelp: take the original Iterator's count instead of collecting it and finding the length\n   |\nLL ~         \nLL |\nLL |\nLL |         // Do lint\nLL ~         for _ in 0..v.iter().count() {\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:301:30\n   |\nLL |         let mut w = v.iter().collect::<Vec<_>>();\n   |                              ^^^^^^^\n...\nLL |         while 1 == w.len() {\n   |                    ------- the iterator could be used here instead\n   |\nhelp: take the original Iterator's count instead of collecting it and finding the length\n   |\nLL ~         \nLL |\nLL |\nLL |         // Do lint\nLL ~         while 1 == v.iter().count() {\n   |\n\nerror: avoid using `collect()` when not needed\n  --> tests/ui/needless_collect_indirect.rs:325:30\n   |\nLL |         let mut w = v.iter().collect::<Vec<_>>();\n   |                              ^^^^^^^\n...\nLL |         while let Some(i) = Some(w.len()) {\n   |                                  ------- the iterator could be used here instead\n   |\nhelp: take the original Iterator's count instead of collecting it and finding the length\n   |\nLL ~         \nLL |\nLL |\nLL |         // Do lint\nLL ~         while let Some(i) = Some(v.iter().count()) {\n   |\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_continue.rs",
    "content": "#![warn(clippy::needless_continue)]\n#![allow(clippy::uninlined_format_args)]\n\nmacro_rules! zero {\n    ($x:expr) => {\n        $x == 0\n    };\n}\n\nmacro_rules! nonzero {\n    ($x:expr) => {\n        !zero!($x)\n    };\n}\n\n#[allow(clippy::nonminimal_bool)]\nfn main() {\n    let mut i = 1;\n    while i < 10 {\n        i += 1;\n\n        if i % 2 == 0 && i % 3 == 0 {\n            println!(\"{}\", i);\n            println!(\"{}\", i + 1);\n            if i % 5 == 0 {\n                println!(\"{}\", i + 2);\n            }\n            let i = 0;\n            println!(\"bar {} \", i);\n        } else {\n            //~^ needless_continue\n\n            continue;\n        }\n\n        println!(\"bleh\");\n        {\n            println!(\"blah\");\n        }\n\n        // some comments that also should ideally be included in the\n        // output of the lint suggestion if possible.\n        if !(!(i == 2) || !(i == 5)) {\n            println!(\"lama\");\n        }\n\n        if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {\n            //~^ needless_continue\n\n            continue;\n        } else {\n            println!(\"Blabber\");\n            println!(\"Jabber\");\n        }\n\n        println!(\"bleh\");\n    }\n}\n\nfn simple_loop() {\n    loop {\n        continue;\n        //~^ needless_continue\n    }\n}\n\nfn simple_loop2() {\n    loop {\n        println!(\"bleh\");\n        continue;\n        //~^ needless_continue\n    }\n}\n\n#[rustfmt::skip]\nfn simple_loop3() {\n    loop {\n        continue\n        //~^ needless_continue\n\n    }\n}\n\n#[rustfmt::skip]\nfn simple_loop4() {\n    loop {\n        println!(\"bleh\");\n        continue\n        //~^ needless_continue\n\n    }\n}\n\nfn simple_loop5() {\n    loop {\n        println!(\"bleh\");\n        { continue }\n        //~^ needless_continue\n    }\n}\n\nmod issue_2329 {\n    fn condition() -> bool {\n        unimplemented!()\n    }\n    fn update_condition() {}\n\n    // only the outer loop has a label\n    fn foo() {\n        'outer: loop {\n            println!(\"Entry\");\n            while condition() {\n                update_condition();\n                if condition() {\n                    println!(\"foo-1\");\n                } else {\n                    continue 'outer; // should not lint here\n                }\n                println!(\"foo-2\");\n\n                update_condition();\n                if condition() {\n                    continue 'outer; // should not lint here\n                } else {\n                    println!(\"foo-3\");\n                }\n                println!(\"foo-4\");\n            }\n        }\n    }\n\n    // both loops have labels\n    fn bar() {\n        'outer: loop {\n            println!(\"Entry\");\n            'inner: while condition() {\n                update_condition();\n                if condition() {\n                    println!(\"bar-1\");\n                } else {\n                    continue 'outer; // should not lint here\n                }\n                println!(\"bar-2\");\n\n                update_condition();\n                if condition() {\n                    println!(\"bar-3\");\n                } else {\n                    //~^ needless_continue\n\n                    continue 'inner;\n                }\n                println!(\"bar-4\");\n\n                update_condition();\n                if condition() {\n                    //~^ needless_continue\n\n                    continue;\n                } else {\n                    println!(\"bar-5\");\n                }\n                println!(\"bar-6\");\n            }\n        }\n    }\n}\n\nfn issue_13641() {\n    'a: while std::hint::black_box(true) {\n        #[allow(clippy::never_loop)]\n        loop {\n            continue 'a;\n        }\n    }\n\n    #[allow(clippy::never_loop)]\n    while std::hint::black_box(true) {\n        'b: loop {\n            continue 'b;\n            //~^ needless_continue\n        }\n    }\n}\n\nmod issue_4077 {\n    fn main() {\n        'outer: loop {\n            'inner: loop {\n                do_something();\n                if some_expr() {\n                    println!(\"bar-7\");\n                    continue 'outer;\n                } else if !some_expr() {\n                    println!(\"bar-8\");\n                    continue 'inner;\n                    //~^ needless_continue\n                } else {\n                    println!(\"bar-9\");\n                    continue 'inner;\n                    //~^ needless_continue\n                }\n            }\n        }\n\n        for _ in 0..10 {\n            match \"foo\".parse::<i32>() {\n                Ok(_) => do_something(),\n                Err(_) => {\n                    println!(\"bar-10\");\n                    continue;\n                    //~^ needless_continue\n                },\n            }\n        }\n\n        loop {\n            if true {\n            } else {\n                //~^ needless_continue\n                // redundant `else`\n                continue; // redundant `continue`\n            }\n        }\n\n        loop {\n            if some_expr() {\n                //~^ needless_continue\n                continue;\n            } else {\n                do_something();\n            }\n        }\n    }\n\n    // The contents of these functions are irrelevant, the purpose of this file is\n    // shown in main.\n\n    fn do_something() {\n        std::process::exit(0);\n    }\n\n    fn some_expr() -> bool {\n        true\n    }\n}\n\n#[allow(clippy::let_unit_value)]\nmod issue14550 {\n    fn match_with_value(mut producer: impl Iterator<Item = Result<i32, u32>>) -> Result<u32, u32> {\n        let mut counter = 2;\n        loop {\n            match producer.next().unwrap() {\n                Ok(ok) => break Ok((ok + 1) as u32),\n                Err(12) => {\n                    counter -= 1;\n                    continue;\n                },\n                err => err?,\n            };\n        }\n    }\n\n    fn inside_macro() {\n        macro_rules! mac {\n            ($e:expr => $($rest:tt);*) => {\n                loop {\n                    match $e {\n                        1 => continue,\n                        2 => break,\n                        n => println!(\"{n}\"),\n                    }\n                    $($rest;)*\n                }\n            };\n        }\n\n        mac!(2 => );\n        mac!(1 => {println!(\"foobar\")});\n    }\n\n    mod partially_inside_macro {\n        macro_rules! select {\n            (\n                $expr:expr,\n                $( $pat:pat => $then:expr ),*\n            ) => {\n                fn foo() {\n                    loop {\n                        match $expr {\n                            $(\n                                $pat => $then,\n                            )*\n                        }\n                    }\n                }\n            };\n        }\n\n        select!(Some(1),\n            Some(1) => {\n                println!(\"one\");\n                continue;\n            },\n            Some(2) => {},\n            None => break,\n            _ => ()\n        );\n\n        macro_rules! choose {\n            (\n            $expr:expr,\n            $case:expr\n        ) => {\n                fn bar() {\n                    loop {\n                        match $expr {\n                            $case => {\n                                println!(\"matched\");\n                                continue;\n                            },\n                            _ => {\n                                println!(\"not matched\");\n                                break;\n                            },\n                        }\n                    }\n                }\n            };\n        }\n\n        choose!(todo!(), 5);\n    }\n}\n\nfn issue15548() {\n    loop {\n        if todo!() {\n        } else {\n            //~^ needless_continue\n            continue;\n        }\n    }\n}\n\nfn issue16256() {\n    fn some_condition() -> bool {\n        true\n    }\n    fn another_condition() -> bool {\n        true\n    }\n\n    for _ in 0..5 {\n        if some_condition() {\n            // ...\n            continue;\n        }\n\n        if another_condition() {\n            // ...\n            // \"this `continue` expression is redundant\" is posted on\n            // the `continue` node.\n            #[expect(clippy::needless_continue)]\n            continue;\n        }\n    }\n\n    for _ in 0..5 {\n        // \"This `else` block is redundant\" is posted on the\n        // `else` node.\n        #[expect(clippy::needless_continue)]\n        if some_condition() {\n            // ...\n        } else {\n            continue;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_continue.stderr",
    "content": "error: this `else` block is redundant\n  --> tests/ui/needless_continue.rs:30:16\n   |\nLL |           } else {\n   |  ________________^\nLL | |\nLL | |\nLL | |             continue;\nLL | |         }\n   | |_________^\n   |\n   = help: consider dropping the `else` clause and merging the code that follows (in the loop) with the `if` block\n                   if i % 2 == 0 && i % 3 == 0 {\n                       println!(\"{}\", i);\n                       println!(\"{}\", i + 1);\n                       if i % 5 == 0 {\n                           println!(\"{}\", i + 2);\n                       }\n                       let i = 0;\n                       println!(\"bar {} \", i);\n                       // merged code follows:\n                       println!(\"bleh\");\n                       {\n                           println!(\"blah\");\n                       }\n                       if !(!(i == 2) || !(i == 5)) {\n                           println!(\"lama\");\n                       }\n                       if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {\n\n                       \n                           continue;\n                       } else {\n                           println!(\"Blabber\");\n                           println!(\"Jabber\");\n                       }\n                       println!(\"bleh\");\n                   }\n   = note: `-D clippy::needless-continue` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_continue)]`\n\nerror: there is no need for an explicit `else` block for this `if` expression\n  --> tests/ui/needless_continue.rs:47:9\n   |\nLL | /         if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {\nLL | |\nLL | |\nLL | |             continue;\n...  |\nLL | |             println!(\"Jabber\");\nLL | |         }\n   | |_________^\n   |\n   = help: consider dropping the `else` clause\n                   if (zero!(i % 2) || nonzero!(i % 5)) && i % 3 != 0 {\n\n           \n                       continue;\n                   }\n                   {\n                       println!(\"Blabber\");\n                       println!(\"Jabber\");\n                   }\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:62:9\n   |\nLL |         continue;\n   |         ^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:70:9\n   |\nLL |         continue;\n   |         ^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:78:9\n   |\nLL |         continue\n   |         ^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:88:9\n   |\nLL |         continue\n   |         ^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:97:11\n   |\nLL |         { continue }\n   |           ^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `else` block is redundant\n  --> tests/ui/needless_continue.rs:148:24\n   |\nLL |                   } else {\n   |  ________________________^\nLL | |\nLL | |\nLL | |                     continue 'inner;\nLL | |                 }\n   | |_________________^\n   |\n   = help: consider dropping the `else` clause and merging the code that follows (in the loop) with the `if` block\n                           if condition() {\n                               println!(\"bar-3\");\n                               // merged code follows:\n                               println!(\"bar-4\");\n                               update_condition();\n                               if condition() {\n\n                               \n                                   continue;\n                               } else {\n                                   println!(\"bar-5\");\n                               }\n                               println!(\"bar-6\");\n                           }\n\nerror: there is no need for an explicit `else` block for this `if` expression\n  --> tests/ui/needless_continue.rs:156:17\n   |\nLL | /                 if condition() {\nLL | |\nLL | |\nLL | |                     continue;\nLL | |                 } else {\nLL | |                     println!(\"bar-5\");\nLL | |                 }\n   | |_________________^\n   |\n   = help: consider dropping the `else` clause\n                           if condition() {\n\n           \n                               continue;\n                           }\n                           {\n                               println!(\"bar-5\");\n                           }\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:180:13\n   |\nLL |             continue 'b;\n   |             ^^^^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:196:21\n   |\nLL |                     continue 'inner;\n   |                     ^^^^^^^^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:200:21\n   |\nLL |                     continue 'inner;\n   |                     ^^^^^^^^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `continue` expression is redundant\n  --> tests/ui/needless_continue.rs:211:21\n   |\nLL |                     continue;\n   |                     ^^^^^^^^\n   |\n   = help: consider dropping the `continue` expression\n\nerror: this `else` block is redundant\n  --> tests/ui/needless_continue.rs:219:20\n   |\nLL |               } else {\n   |  ____________________^\nLL | |\nLL | |                 // redundant `else`\nLL | |                 continue; // redundant `continue`\nLL | |             }\n   | |_____________^\n   |\n   = help: consider dropping the `else` clause and merging the code that follows (in the loop) with the `if` block\n                       if true {\n           // merged code follows:\n           \n                       }\n\nerror: there is no need for an explicit `else` block for this `if` expression\n  --> tests/ui/needless_continue.rs:227:13\n   |\nLL | /             if some_expr() {\nLL | |\nLL | |                 continue;\nLL | |             } else {\nLL | |                 do_something();\nLL | |             }\n   | |_____________^\n   |\n   = help: consider dropping the `else` clause\n                       if some_expr() {\n\n                           continue;\n                       }\n                       {\n                           do_something();\n                       }\n\nerror: this `else` block is redundant\n  --> tests/ui/needless_continue.rs:339:16\n   |\nLL |           } else {\n   |  ________________^\nLL | |\nLL | |             continue;\nLL | |         }\n   | |_________^\n   |\n   = help: consider dropping the `else` clause and merging the code that follows (in the loop) with the `if` block\n                   if todo!() {\n           // merged code follows:\n           \n                   }\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_doc_main.rs",
    "content": "/// This is a test for needless `fn main()` in doctests.\n///\n/// # Examples\n///\n/// This should lint\n/// ```\n/// fn main() {\n//~^ needless_doctest_main\n///     unimplemented!();\n/// }\n/// ```\n/// \n/// With an explicit return type it should lint too\n/// ```edition2015\n/// fn main() -> () {\n//~^ needless_doctest_main\n///     unimplemented!();\n/// }\n/// ```\n/// \n/// This should, too.\n/// ```rust\n/// fn main() {\n//~^ needless_doctest_main\n///     unimplemented!();\n/// }\n/// ```\n/// \n/// This one too.\n/// ```no_run\n/// // the fn is not always the first line\n/// fn main() {\n//~^ needless_doctest_main\n///     unimplemented!();\n/// }\n/// ```\nfn bad_doctests() {}\n\n/// # Examples\n///\n/// This shouldn't lint because main is async:\n/// ```edition2018\n/// async fn main() {\n///     assert_eq!(42, ANSWER);\n/// }\n/// ```\n///\n/// Same here, because the return type is not the unit type:\n/// ```\n/// fn main() -> Result<()> {\n///     Ok(())\n/// }\n/// ```\n///\n/// This shouldn't lint either, because there's a `static`:\n/// ```\n/// static ANSWER: i32 = 42;\n///\n/// fn main() {\n///     assert_eq!(42, ANSWER);\n/// }\n/// ```\n///\n/// This shouldn't lint either, because there's a `const`:\n/// ```\n/// fn main() {\n///     assert_eq!(42, ANSWER);\n/// }\n///\n/// const ANSWER: i32 = 42;\n/// ```\n///\n/// Neither should this lint because of `extern crate`:\n/// ```\n/// #![feature(test)]\n/// extern crate test;\n/// fn main() {\n///     assert_eq(1u8, test::black_box(1));\n/// }\n/// ```\n///\n/// Neither should this lint because it has an extern block:\n/// ```\n/// extern {}\n/// fn main() {\n///     unimplemented!();\n/// }\n/// ```\n///\n/// This should not lint because there is another function defined:\n/// ```\n/// fn fun() {}\n///\n/// fn main() {\n///     unimplemented!();\n/// }\n/// ```\n///\n/// We should not lint inside raw strings ...\n/// ```\n/// let string = r#\"\n/// fn main() {\n///     unimplemented!();\n/// }\n/// \"#;\n/// ```\n///\n/// ... or comments\n/// ```\n/// // fn main() {\n/// //     let _inception = 42;\n/// // }\n/// let _inception = 42;\n/// ```\n///\n/// We should not lint ignored examples:\n/// ```rust,ignore\n/// fn main() {\n///     unimplemented!();\n/// }\n/// ```\n///\n/// Or even non-rust examples:\n/// ```text\n/// fn main() {\n///     is what starts the program\n/// }\n/// ```\nfn no_false_positives() {}\n\n/// Yields a parse error when interpreted as rust code:\n/// ```\n/// r#\"hi\"\n/// ```\nfn issue_6022() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_doc_main.stderr",
    "content": "error: needless `fn main` in doctest\n  --> tests/ui/needless_doc_main.rs:7:5\n   |\nLL | /// fn main() {\n   |     ^^^^^^^\n   |\n   = note: `-D clippy::needless-doctest-main` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_doctest_main)]`\n\nerror: needless `fn main` in doctest\n  --> tests/ui/needless_doc_main.rs:15:5\n   |\nLL | /// fn main() -> () {\n   |     ^^^^^^^\n\nerror: needless `fn main` in doctest\n  --> tests/ui/needless_doc_main.rs:23:5\n   |\nLL | /// fn main() {\n   |     ^^^^^^^\n\nerror: needless `fn main` in doctest\n  --> tests/ui/needless_doc_main.rs:32:5\n   |\nLL | /// fn main() {\n   |     ^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_else.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::needless_else)]\n#![allow(clippy::suspicious_else_formatting)]\n\nmacro_rules! mac {\n    ($test:expr) => {\n        if $test {\n            println!(\"Test successful!\");\n        } else {\n        }\n    };\n}\n\nmacro_rules! empty_expansion {\n    () => {};\n}\n\nfn main() {\n    let b = std::hint::black_box(true);\n\n    if b {\n        println!(\"Foobar\");\n    } \n    //~^^ needless_else\n\n    if b {\n        println!(\"Foobar\");\n    } else {\n        // Do not lint because this comment might be important\n    }\n\n    if b {\n        println!(\"Foobar\");\n    } else\n    /* Do not lint because this comment might be important */\n    {\n    }\n\n    // Do not lint because of the expression\n    let _ = if b { 1 } else { 2 };\n\n    // Do not lint because inside a macro\n    mac!(b);\n\n    if b {\n        println!(\"Foobar\");\n    } else {\n        #[cfg(foo)]\n        \"Do not lint cfg'd out code\"\n    }\n\n    if b {\n        println!(\"Foobar\");\n    } else {\n        empty_expansion!();\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_else.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::needless_else)]\n#![allow(clippy::suspicious_else_formatting)]\n\nmacro_rules! mac {\n    ($test:expr) => {\n        if $test {\n            println!(\"Test successful!\");\n        } else {\n        }\n    };\n}\n\nmacro_rules! empty_expansion {\n    () => {};\n}\n\nfn main() {\n    let b = std::hint::black_box(true);\n\n    if b {\n        println!(\"Foobar\");\n    } else {\n    }\n    //~^^ needless_else\n\n    if b {\n        println!(\"Foobar\");\n    } else {\n        // Do not lint because this comment might be important\n    }\n\n    if b {\n        println!(\"Foobar\");\n    } else\n    /* Do not lint because this comment might be important */\n    {\n    }\n\n    // Do not lint because of the expression\n    let _ = if b { 1 } else { 2 };\n\n    // Do not lint because inside a macro\n    mac!(b);\n\n    if b {\n        println!(\"Foobar\");\n    } else {\n        #[cfg(foo)]\n        \"Do not lint cfg'd out code\"\n    }\n\n    if b {\n        println!(\"Foobar\");\n    } else {\n        empty_expansion!();\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_else.stderr",
    "content": "error: this `else` branch is empty\n  --> tests/ui/needless_else.rs:23:7\n   |\nLL |       } else {\n   |  _______^\nLL | |     }\n   | |_____^ help: you can remove it\n   |\n   = note: `-D clippy::needless-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_else)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/needless_for_each_fixable.fixed",
    "content": "#![warn(clippy::needless_for_each)]\n#![allow(unused)]\n#![allow(\n    clippy::let_unit_value,\n    clippy::match_single_binding,\n    clippy::needless_return,\n    clippy::uninlined_format_args\n)]\n\nuse std::collections::HashMap;\n\nfn should_lint() {\n    let v: Vec<i32> = Vec::new();\n    let mut acc = 0;\n    for elem in v.iter() {\n        //~^ needless_for_each\n        acc += elem;\n    }\n    for elem in v.into_iter() {\n        //~^ needless_for_each\n        acc += elem;\n    }\n\n    for elem in [1, 2, 3].iter() {\n        //~^ needless_for_each\n        acc += elem;\n    }\n\n    let mut hash_map: HashMap<i32, i32> = HashMap::new();\n    for (k, v) in hash_map.iter() {\n        //~^ needless_for_each\n        acc += k + v;\n    }\n    for (k, v) in hash_map.iter_mut() {\n        //~^ needless_for_each\n        acc += *k + *v;\n    }\n    for k in hash_map.keys() {\n        //~^ needless_for_each\n        acc += k;\n    }\n    for v in hash_map.values() {\n        //~^ needless_for_each\n        acc += v;\n    }\n\n    fn my_vec() -> Vec<i32> {\n        Vec::new()\n    }\n    for elem in my_vec().iter() {\n        //~^ needless_for_each\n        acc += elem;\n    }\n}\n\nfn should_not_lint() {\n    let v: Vec<i32> = Vec::new();\n    let mut acc = 0;\n\n    // `for_each` argument is not closure.\n    fn print(x: &i32) {\n        println!(\"{}\", x);\n    }\n    v.iter().for_each(print);\n\n    // User defined type.\n    struct MyStruct {\n        v: Vec<i32>,\n    }\n    impl MyStruct {\n        fn iter(&self) -> impl Iterator<Item = &i32> {\n            self.v.iter()\n        }\n    }\n    let s = MyStruct { v: Vec::new() };\n    s.iter().for_each(|elem| {\n        acc += elem;\n    });\n\n    // `for_each` follows long iterator chain.\n    v.iter().chain(v.iter()).for_each(|v| {\n        acc += v;\n    });\n    v.as_slice().iter().for_each(|v| {\n        acc += v;\n    });\n    s.v.iter().for_each(|v| {\n        acc += v;\n    });\n\n    // `return` is used in `Loop` of the closure.\n    v.iter().for_each(|v| {\n        for i in 0..*v {\n            if i == 10 {\n                return;\n            } else {\n                println!(\"{}\", v);\n            }\n        }\n        if *v == 20 {\n            return;\n        } else {\n            println!(\"{}\", v);\n        }\n    });\n\n    // Previously transformed iterator variable.\n    let it = v.iter();\n    it.chain(v.iter()).for_each(|elem| {\n        acc += elem;\n    });\n\n    // `for_each` is not directly in a statement.\n    match 1 {\n        _ => v.iter().for_each(|elem| {\n            acc += elem;\n        }),\n    }\n\n    // `for_each` is in a let binding.\n    let _ = v.iter().for_each(|elem| {\n        acc += elem;\n    });\n    // `for_each` has a closure with an unsafe block.\n    v.iter().for_each(|elem| unsafe {\n        acc += elem;\n    });\n}\n\nfn main() {}\n\nmod issue14734 {\n    fn let_desugar(rows: &[u8]) {\n        let mut v = vec![];\n        for x in rows.iter() { _ = v.push(x) }\n        //~^ needless_for_each\n    }\n\n    fn do_something(_: &u8, _: u8) {}\n\n    fn single_expr(rows: &[u8]) {\n        for x in rows.iter() { do_something(x, 1u8); }\n        //~^ needless_for_each\n    }\n}\n\nfn issue15256() {\n    let vec: Vec<i32> = Vec::new();\n    for v in vec.iter() { println!(\"{v}\"); }\n    //~^ needless_for_each\n}\n\nfn issue16294() {\n    let vec: Vec<i32> = Vec::new();\n    for elem in vec.iter() {\n        //~^ needless_for_each\n        println!(\"{elem}\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_for_each_fixable.rs",
    "content": "#![warn(clippy::needless_for_each)]\n#![allow(unused)]\n#![allow(\n    clippy::let_unit_value,\n    clippy::match_single_binding,\n    clippy::needless_return,\n    clippy::uninlined_format_args\n)]\n\nuse std::collections::HashMap;\n\nfn should_lint() {\n    let v: Vec<i32> = Vec::new();\n    let mut acc = 0;\n    v.iter().for_each(|elem| {\n        //~^ needless_for_each\n        acc += elem;\n    });\n    v.into_iter().for_each(|elem| {\n        //~^ needless_for_each\n        acc += elem;\n    });\n\n    [1, 2, 3].iter().for_each(|elem| {\n        //~^ needless_for_each\n        acc += elem;\n    });\n\n    let mut hash_map: HashMap<i32, i32> = HashMap::new();\n    hash_map.iter().for_each(|(k, v)| {\n        //~^ needless_for_each\n        acc += k + v;\n    });\n    hash_map.iter_mut().for_each(|(k, v)| {\n        //~^ needless_for_each\n        acc += *k + *v;\n    });\n    hash_map.keys().for_each(|k| {\n        //~^ needless_for_each\n        acc += k;\n    });\n    hash_map.values().for_each(|v| {\n        //~^ needless_for_each\n        acc += v;\n    });\n\n    fn my_vec() -> Vec<i32> {\n        Vec::new()\n    }\n    my_vec().iter().for_each(|elem| {\n        //~^ needless_for_each\n        acc += elem;\n    });\n}\n\nfn should_not_lint() {\n    let v: Vec<i32> = Vec::new();\n    let mut acc = 0;\n\n    // `for_each` argument is not closure.\n    fn print(x: &i32) {\n        println!(\"{}\", x);\n    }\n    v.iter().for_each(print);\n\n    // User defined type.\n    struct MyStruct {\n        v: Vec<i32>,\n    }\n    impl MyStruct {\n        fn iter(&self) -> impl Iterator<Item = &i32> {\n            self.v.iter()\n        }\n    }\n    let s = MyStruct { v: Vec::new() };\n    s.iter().for_each(|elem| {\n        acc += elem;\n    });\n\n    // `for_each` follows long iterator chain.\n    v.iter().chain(v.iter()).for_each(|v| {\n        acc += v;\n    });\n    v.as_slice().iter().for_each(|v| {\n        acc += v;\n    });\n    s.v.iter().for_each(|v| {\n        acc += v;\n    });\n\n    // `return` is used in `Loop` of the closure.\n    v.iter().for_each(|v| {\n        for i in 0..*v {\n            if i == 10 {\n                return;\n            } else {\n                println!(\"{}\", v);\n            }\n        }\n        if *v == 20 {\n            return;\n        } else {\n            println!(\"{}\", v);\n        }\n    });\n\n    // Previously transformed iterator variable.\n    let it = v.iter();\n    it.chain(v.iter()).for_each(|elem| {\n        acc += elem;\n    });\n\n    // `for_each` is not directly in a statement.\n    match 1 {\n        _ => v.iter().for_each(|elem| {\n            acc += elem;\n        }),\n    }\n\n    // `for_each` is in a let binding.\n    let _ = v.iter().for_each(|elem| {\n        acc += elem;\n    });\n    // `for_each` has a closure with an unsafe block.\n    v.iter().for_each(|elem| unsafe {\n        acc += elem;\n    });\n}\n\nfn main() {}\n\nmod issue14734 {\n    fn let_desugar(rows: &[u8]) {\n        let mut v = vec![];\n        rows.iter().for_each(|x| _ = v.push(x));\n        //~^ needless_for_each\n    }\n\n    fn do_something(_: &u8, _: u8) {}\n\n    fn single_expr(rows: &[u8]) {\n        rows.iter().for_each(|x| do_something(x, 1u8));\n        //~^ needless_for_each\n    }\n}\n\nfn issue15256() {\n    let vec: Vec<i32> = Vec::new();\n    vec.iter().for_each(|v| println!(\"{v}\"));\n    //~^ needless_for_each\n}\n\nfn issue16294() {\n    let vec: Vec<i32> = Vec::new();\n    vec.iter().for_each(|elem| {\n        //~^ needless_for_each\n        println!(\"{elem}\");\n    })\n}\n"
  },
  {
    "path": "tests/ui/needless_for_each_fixable.stderr",
    "content": "error: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:15:5\n   |\nLL | /     v.iter().for_each(|elem| {\nLL | |\nLL | |         acc += elem;\nLL | |     });\n   | |_______^\n   |\n   = note: `-D clippy::needless-for-each` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_for_each)]`\nhelp: try\n   |\nLL ~     for elem in v.iter() {\nLL +\nLL +         acc += elem;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:19:5\n   |\nLL | /     v.into_iter().for_each(|elem| {\nLL | |\nLL | |         acc += elem;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for elem in v.into_iter() {\nLL +\nLL +         acc += elem;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:24:5\n   |\nLL | /     [1, 2, 3].iter().for_each(|elem| {\nLL | |\nLL | |         acc += elem;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for elem in [1, 2, 3].iter() {\nLL +\nLL +         acc += elem;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:30:5\n   |\nLL | /     hash_map.iter().for_each(|(k, v)| {\nLL | |\nLL | |         acc += k + v;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for (k, v) in hash_map.iter() {\nLL +\nLL +         acc += k + v;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:34:5\n   |\nLL | /     hash_map.iter_mut().for_each(|(k, v)| {\nLL | |\nLL | |         acc += *k + *v;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for (k, v) in hash_map.iter_mut() {\nLL +\nLL +         acc += *k + *v;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:38:5\n   |\nLL | /     hash_map.keys().for_each(|k| {\nLL | |\nLL | |         acc += k;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for k in hash_map.keys() {\nLL +\nLL +         acc += k;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:42:5\n   |\nLL | /     hash_map.values().for_each(|v| {\nLL | |\nLL | |         acc += v;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for v in hash_map.values() {\nLL +\nLL +         acc += v;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:50:5\n   |\nLL | /     my_vec().iter().for_each(|elem| {\nLL | |\nLL | |         acc += elem;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for elem in my_vec().iter() {\nLL +\nLL +         acc += elem;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:135:9\n   |\nLL |         rows.iter().for_each(|x| _ = v.push(x));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in rows.iter() { _ = v.push(x) }`\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:142:9\n   |\nLL |         rows.iter().for_each(|x| do_something(x, 1u8));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in rows.iter() { do_something(x, 1u8); }`\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:149:5\n   |\nLL |     vec.iter().for_each(|v| println!(\"{v}\"));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec.iter() { println!(\"{v}\"); }`\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_fixable.rs:155:5\n   |\nLL | /     vec.iter().for_each(|elem| {\nLL | |\nLL | |         println!(\"{elem}\");\nLL | |     })\n   | |______^\n   |\nhelp: try\n   |\nLL ~     for elem in vec.iter() {\nLL +\nLL +         println!(\"{elem}\");\nLL +     }\n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_for_each_unfixable.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![warn(clippy::needless_for_each)]\n#![allow(clippy::needless_return)]\n\nfn main() {\n    let v: Vec<i32> = Vec::new();\n    // This is unfixable because the closure includes `return`.\n    v.iter().for_each(|v| {\n        //~^ needless_for_each\n\n        if *v == 10 {\n            return;\n        } else {\n            println!(\"{v}\");\n        }\n    });\n}\n\nfn issue9912() {\n    let mut i = 0;\n    // Changing this to a `for` loop would break type inference\n    [].iter().for_each(move |_: &i32| {\n        //~^ needless_for_each\n        i += 1;\n    });\n\n    // Changing this would actually be okay, but we still suggest `MaybeIncorrect`ly\n    [1i32].iter().for_each(move |_: &i32| {\n        //~^ needless_for_each\n        i += 1;\n    });\n}\n"
  },
  {
    "path": "tests/ui/needless_for_each_unfixable.stderr",
    "content": "error: needless use of `for_each`\n  --> tests/ui/needless_for_each_unfixable.rs:8:5\n   |\nLL | /     v.iter().for_each(|v| {\nLL | |\nLL | |\nLL | |         if *v == 10 {\n...  |\nLL | |     });\n   | |_______^\n   |\n   = note: `-D clippy::needless-for-each` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_for_each)]`\nhelp: try\n   |\nLL ~     for v in v.iter() {\nLL +\nLL + \nLL +         if *v == 10 {\nLL +             return;\nLL +         } else {\nLL +             println!(\"{v}\");\nLL +         }\nLL +     }\n   |\nhelp: ...and replace `return` with `continue`\n   |\nLL -             return;\nLL +             continue;\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_unfixable.rs:22:5\n   |\nLL | /     [].iter().for_each(move |_: &i32| {\nLL | |\nLL | |         i += 1;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for _ in [].iter() {\nLL +\nLL +         i += 1;\nLL +     }\n   |\n\nerror: needless use of `for_each`\n  --> tests/ui/needless_for_each_unfixable.rs:28:5\n   |\nLL | /     [1i32].iter().for_each(move |_: &i32| {\nLL | |\nLL | |         i += 1;\nLL | |     });\n   | |_______^\n   |\nhelp: try\n   |\nLL ~     for _ in [1i32].iter() {\nLL +\nLL +         i += 1;\nLL +     }\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_ifs.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    clippy::blocks_in_conditions,\n    clippy::if_same_then_else,\n    clippy::ifs_same_cond,\n    clippy::let_unit_value,\n    clippy::needless_else,\n    clippy::no_effect,\n    clippy::nonminimal_bool,\n    clippy::short_circuit_statement,\n    clippy::unnecessary_operation,\n    clippy::redundant_pattern_matching,\n    unused\n)]\n#![warn(clippy::needless_ifs)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nfn maybe_side_effect() -> bool {\n    true\n}\n\nfn main() {\n    // Lint\n    \n    //~^ needless_ifs\n    // Do not remove the condition\n    maybe_side_effect();\n    //~^ needless_ifs\n    // Do not lint\n    if (true) {\n    } else {\n    }\n    ({\n        //~^ needless_ifs\n        return;\n    });\n    // Do not lint if `else if` is present\n    if (true) {\n    } else if (true) {\n    }\n    // Do not lint `if let` or let chains\n    if let true = true {}\n    if let true = true\n        && true\n    {}\n    if true && let true = true {}\n    // Can lint nested `if let`s\n    ({\n        //~^ needless_ifs\n        if let true = true\n            && true\n        {\n            true\n        } else {\n            false\n        }\n    } && true);\n    external! { if (true) {} }\n    with_span! {\n        span\n        if (true) {}\n    }\n\n    if true {\n        // comment\n    }\n\n    if true {\n        #[cfg(any())]\n        foo;\n    }\n\n    macro_rules! empty_expansion {\n        () => {};\n    }\n\n    if true {\n        empty_expansion!();\n    }\n\n    macro_rules! empty_repetition {\n        ($($t:tt)*) => {\n            if true {\n                $($t)*\n            }\n        }\n    }\n\n    empty_repetition!();\n\n    // Must be placed into an expression context to not be interpreted as a block\n    ({ maybe_side_effect() });\n    //~^ needless_ifs\n    // Would be a block followed by `&&true` - a double reference to `true`\n    ({ maybe_side_effect() } && true);\n    //~^ needless_ifs\n\n    // Don't leave trailing attributes\n    #[allow(unused)]\n    true;\n    //~^ needless_ifs\n\n    let () = if maybe_side_effect() {};\n}\n\nfn issue15960() -> i32 {\n    matches!(2, 3);\n    //~^ needless_ifs\n    matches!(2, 3) == (2 * 2 == 5);\n    //~^ needless_ifs\n\n    1 // put something here so that `if` is a statement not an expression\n}\n"
  },
  {
    "path": "tests/ui/needless_ifs.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    clippy::blocks_in_conditions,\n    clippy::if_same_then_else,\n    clippy::ifs_same_cond,\n    clippy::let_unit_value,\n    clippy::needless_else,\n    clippy::no_effect,\n    clippy::nonminimal_bool,\n    clippy::short_circuit_statement,\n    clippy::unnecessary_operation,\n    clippy::redundant_pattern_matching,\n    unused\n)]\n#![warn(clippy::needless_ifs)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nfn maybe_side_effect() -> bool {\n    true\n}\n\nfn main() {\n    // Lint\n    if (true) {}\n    //~^ needless_ifs\n    // Do not remove the condition\n    if maybe_side_effect() {}\n    //~^ needless_ifs\n    // Do not lint\n    if (true) {\n    } else {\n    }\n    if {\n        //~^ needless_ifs\n        return;\n    } {}\n    // Do not lint if `else if` is present\n    if (true) {\n    } else if (true) {\n    }\n    // Do not lint `if let` or let chains\n    if let true = true {}\n    if let true = true\n        && true\n    {}\n    if true && let true = true {}\n    // Can lint nested `if let`s\n    if {\n        //~^ needless_ifs\n        if let true = true\n            && true\n        {\n            true\n        } else {\n            false\n        }\n    } && true\n    {}\n    external! { if (true) {} }\n    with_span! {\n        span\n        if (true) {}\n    }\n\n    if true {\n        // comment\n    }\n\n    if true {\n        #[cfg(any())]\n        foo;\n    }\n\n    macro_rules! empty_expansion {\n        () => {};\n    }\n\n    if true {\n        empty_expansion!();\n    }\n\n    macro_rules! empty_repetition {\n        ($($t:tt)*) => {\n            if true {\n                $($t)*\n            }\n        }\n    }\n\n    empty_repetition!();\n\n    // Must be placed into an expression context to not be interpreted as a block\n    if { maybe_side_effect() } {}\n    //~^ needless_ifs\n    // Would be a block followed by `&&true` - a double reference to `true`\n    if { maybe_side_effect() } && true {}\n    //~^ needless_ifs\n\n    // Don't leave trailing attributes\n    #[allow(unused)]\n    if true {}\n    //~^ needless_ifs\n\n    let () = if maybe_side_effect() {};\n}\n\nfn issue15960() -> i32 {\n    if matches!(2, 3) {}\n    //~^ needless_ifs\n    if matches!(2, 3) == (2 * 2 == 5) {}\n    //~^ needless_ifs\n\n    1 // put something here so that `if` is a statement not an expression\n}\n"
  },
  {
    "path": "tests/ui/needless_ifs.stderr",
    "content": "error: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:26:5\n   |\nLL |     if (true) {}\n   |     ^^^^^^^^^^^^ help: you can remove it\n   |\n   = note: `-D clippy::needless-ifs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_ifs)]`\n\nerror: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:29:5\n   |\nLL |     if maybe_side_effect() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `maybe_side_effect();`\n\nerror: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:35:5\n   |\nLL | /     if {\nLL | |\nLL | |         return;\nLL | |     } {}\n   | |________^\n   |\nhelp: you can remove it\n   |\nLL ~     ({\nLL +\nLL +         return;\nLL +     });\n   |\n\nerror: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:50:5\n   |\nLL | /     if {\nLL | |\nLL | |         if let true = true\nLL | |             && true\n...  |\nLL | |     } && true\nLL | |     {}\n   | |______^\n   |\nhelp: you can remove it\n   |\nLL ~     ({\nLL +\nLL +         if let true = true\nLL +             && true\nLL +         {\nLL +             true\nLL +         } else {\nLL +             false\nLL +         }\nLL +     } && true);\n   |\n\nerror: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:95:5\n   |\nLL |     if { maybe_side_effect() } {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() });`\n\nerror: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:98:5\n   |\nLL |     if { maybe_side_effect() } && true {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `({ maybe_side_effect() } && true);`\n\nerror: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:103:5\n   |\nLL |     if true {}\n   |     ^^^^^^^^^^ help: you can remove it: `true;`\n\nerror: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:110:5\n   |\nLL |     if matches!(2, 3) {}\n   |     ^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `matches!(2, 3);`\n\nerror: this `if` branch is empty\n  --> tests/ui/needless_ifs.rs:112:5\n   |\nLL |     if matches!(2, 3) == (2 * 2 == 5) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can remove it: `matches!(2, 3) == (2 * 2 == 5);`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_late_init.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    clippy::assign_op_pattern,\n    clippy::blocks_in_conditions,\n    clippy::let_and_return,\n    clippy::let_unit_value,\n    clippy::nonminimal_bool,\n    clippy::uninlined_format_args,\n    clippy::useless_vec\n)]\n\nextern crate proc_macros;\n\nuse std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};\nuse std::rc::Rc;\n\nstruct SignificantDrop;\nimpl std::ops::Drop for SignificantDrop {\n    fn drop(&mut self) {\n        println!(\"dropped\");\n    }\n}\n\nfn simple() {\n    \n    //~^ needless_late_init\n    let a = \"zero\";\n\n    \n    //~^ needless_late_init\n    \n    //~^ needless_late_init\n    let b = 1;\n    let c = 2;\n\n    \n    //~^ needless_late_init\n    let d: usize = 1;\n\n    \n    //~^ needless_late_init\n    let e = format!(\"{}\", d);\n}\n\nfn main() {\n    \n    //~^ needless_late_init\n    let n = 1;\n    let a = match n {\n        1 => \"one\",\n        _ => {\n            \"two\"\n        },\n    };\n\n    \n    //~^ needless_late_init\n    let b = if n == 3 {\n        \"four\"\n    } else {\n        \"five\"\n    };\n\n    \n    //~^ needless_late_init\n    let d = if true {\n        let temp = 5;\n        temp\n    } else {\n        15\n    };\n\n    \n    //~^ needless_late_init\n    let e = if true {\n        format!(\"{} {}\", a, b)\n    } else {\n        format!(\"{}\", n)\n    };\n\n    \n    //~^ needless_late_init\n    let f = match 1 {\n        1 => \"three\",\n        _ => return,\n    }; // has semi\n\n    \n    //~^ needless_late_init\n    let g: usize = if true {\n        5\n    } else {\n        panic!();\n    };\n\n    // Drop order only matters if both are significant\n    \n    //~^ needless_late_init\n    let y = SignificantDrop;\n    let x = 1;\n\n    \n    //~^ needless_late_init\n    let y = 1;\n    let x = SignificantDrop;\n\n    \n    //~^ needless_late_init\n    // types that should be considered insignificant\n    let y = 1;\n    let y = \"2\";\n    let y = String::new();\n    let y = vec![3.0];\n    let y = HashMap::<usize, usize>::new();\n    let y = BTreeMap::<usize, usize>::new();\n    let y = HashSet::<usize>::new();\n    let y = BTreeSet::<usize>::new();\n    let y = Box::new(4);\n    let x = SignificantDrop;\n}\n\nasync fn in_async() -> &'static str {\n    async fn f() -> &'static str {\n        \"one\"\n    }\n\n    \n    //~^ needless_late_init\n    let n = 1;\n    let a = match n {\n        1 => f().await,\n        _ => {\n            \"two\"\n        },\n    };\n\n    a\n}\n\nconst fn in_const() -> &'static str {\n    const fn f() -> &'static str {\n        \"one\"\n    }\n\n    \n    //~^ needless_late_init\n    let n = 1;\n    let a = match n {\n        1 => f(),\n        _ => {\n            \"two\"\n        },\n    };\n\n    a\n}\n\n#[proc_macros::inline_macros]\nfn does_not_lint() {\n    let z;\n    if false {\n        z = 1;\n    }\n\n    let x;\n    let y;\n    if true {\n        x = 1;\n    } else {\n        y = 1;\n    }\n\n    let mut x;\n    if true {\n        x = 5;\n        x = 10 / x;\n    } else {\n        x = 2;\n    }\n\n    let x;\n    let _ = match 1 {\n        1 => x = 10,\n        _ => x = 20,\n    };\n\n    // using tuples would be possible, but not always preferable\n    let x;\n    let y;\n    if true {\n        x = 1;\n        y = 2;\n    } else {\n        x = 3;\n        y = 4;\n    }\n\n    // could match with a smarter heuristic to avoid multiple assignments\n    let x;\n    if true {\n        let mut y = 5;\n        y = 6;\n        x = y;\n    } else {\n        x = 2;\n    }\n\n    let (x, y);\n    if true {\n        x = 1;\n    } else {\n        x = 2;\n    }\n    y = 3;\n\n    let x;\n    inline!($x = 1;);\n\n    let x;\n    if true {\n        inline!($x = 1;);\n    } else {\n        x = 2;\n    }\n\n    inline!({\n        let x;\n        x = 1;\n\n        let x;\n        if true {\n            x = 1;\n        } else {\n            x = 2;\n        }\n    });\n\n    // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613\n    let x;\n    if let Some(n) = Some(\"v\") {\n        x = 1;\n    } else {\n        x = 2;\n    }\n\n    let x;\n    if true && let Some(n) = Some(\"let chains too\") {\n        x = 1;\n    } else {\n        x = 2;\n    }\n\n    // ignore mut bindings\n    // https://github.com/shepmaster/twox-hash/blob/b169c16d86eb8ea4a296b0acb9d00ca7e3c3005f/src/sixty_four.rs#L88-L93\n    // https://github.com/dtolnay/thiserror/blob/21c26903e29cb92ba1a7ff11e82ae2001646b60d/tests/test_generics.rs#L91-L100\n    let mut x: usize;\n    x = 1;\n    x = 2;\n    x = 3;\n\n    // should not move the declaration if `x` has a significant drop, and there\n    // is another binding with a significant drop between it and the first usage\n    let x;\n    let y = SignificantDrop;\n    x = SignificantDrop;\n}\n\n#[rustfmt::skip]\nfn issue8911() -> u32 {\n    let x;\n    match 1 {\n        _ if { x = 1; false } => return 1,\n        _ => return 2,\n    }\n\n    let x;\n    if { x = 1; true } {\n        return 1;\n    } else {\n        return 2;\n    }\n\n    3\n}\n\nmacro_rules! issue13776_mac {\n    ($var:expr, $val:literal) => {\n        $var = $val;\n    };\n}\n\nfn issue13776() {\n    let x;\n    issue13776_mac!(x, 10); // should not lint\n}\n\nfn issue9895() {\n    \n    //~^ needless_late_init\n    let r = 5;\n}\n"
  },
  {
    "path": "tests/ui/needless_late_init.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    clippy::assign_op_pattern,\n    clippy::blocks_in_conditions,\n    clippy::let_and_return,\n    clippy::let_unit_value,\n    clippy::nonminimal_bool,\n    clippy::uninlined_format_args,\n    clippy::useless_vec\n)]\n\nextern crate proc_macros;\n\nuse std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};\nuse std::rc::Rc;\n\nstruct SignificantDrop;\nimpl std::ops::Drop for SignificantDrop {\n    fn drop(&mut self) {\n        println!(\"dropped\");\n    }\n}\n\nfn simple() {\n    let a;\n    //~^ needless_late_init\n    a = \"zero\";\n\n    let b;\n    //~^ needless_late_init\n    let c;\n    //~^ needless_late_init\n    b = 1;\n    c = 2;\n\n    let d: usize;\n    //~^ needless_late_init\n    d = 1;\n\n    let e;\n    //~^ needless_late_init\n    e = format!(\"{}\", d);\n}\n\nfn main() {\n    let a;\n    //~^ needless_late_init\n    let n = 1;\n    match n {\n        1 => a = \"one\",\n        _ => {\n            a = \"two\";\n        },\n    }\n\n    let b;\n    //~^ needless_late_init\n    if n == 3 {\n        b = \"four\";\n    } else {\n        b = \"five\"\n    }\n\n    let d;\n    //~^ needless_late_init\n    if true {\n        let temp = 5;\n        d = temp;\n    } else {\n        d = 15;\n    }\n\n    let e;\n    //~^ needless_late_init\n    if true {\n        e = format!(\"{} {}\", a, b);\n    } else {\n        e = format!(\"{}\", n);\n    }\n\n    let f;\n    //~^ needless_late_init\n    match 1 {\n        1 => f = \"three\",\n        _ => return,\n    }; // has semi\n\n    let g: usize;\n    //~^ needless_late_init\n    if true {\n        g = 5;\n    } else {\n        panic!();\n    }\n\n    // Drop order only matters if both are significant\n    let x;\n    //~^ needless_late_init\n    let y = SignificantDrop;\n    x = 1;\n\n    let x;\n    //~^ needless_late_init\n    let y = 1;\n    x = SignificantDrop;\n\n    let x;\n    //~^ needless_late_init\n    // types that should be considered insignificant\n    let y = 1;\n    let y = \"2\";\n    let y = String::new();\n    let y = vec![3.0];\n    let y = HashMap::<usize, usize>::new();\n    let y = BTreeMap::<usize, usize>::new();\n    let y = HashSet::<usize>::new();\n    let y = BTreeSet::<usize>::new();\n    let y = Box::new(4);\n    x = SignificantDrop;\n}\n\nasync fn in_async() -> &'static str {\n    async fn f() -> &'static str {\n        \"one\"\n    }\n\n    let a;\n    //~^ needless_late_init\n    let n = 1;\n    match n {\n        1 => a = f().await,\n        _ => {\n            a = \"two\";\n        },\n    }\n\n    a\n}\n\nconst fn in_const() -> &'static str {\n    const fn f() -> &'static str {\n        \"one\"\n    }\n\n    let a;\n    //~^ needless_late_init\n    let n = 1;\n    match n {\n        1 => a = f(),\n        _ => {\n            a = \"two\";\n        },\n    }\n\n    a\n}\n\n#[proc_macros::inline_macros]\nfn does_not_lint() {\n    let z;\n    if false {\n        z = 1;\n    }\n\n    let x;\n    let y;\n    if true {\n        x = 1;\n    } else {\n        y = 1;\n    }\n\n    let mut x;\n    if true {\n        x = 5;\n        x = 10 / x;\n    } else {\n        x = 2;\n    }\n\n    let x;\n    let _ = match 1 {\n        1 => x = 10,\n        _ => x = 20,\n    };\n\n    // using tuples would be possible, but not always preferable\n    let x;\n    let y;\n    if true {\n        x = 1;\n        y = 2;\n    } else {\n        x = 3;\n        y = 4;\n    }\n\n    // could match with a smarter heuristic to avoid multiple assignments\n    let x;\n    if true {\n        let mut y = 5;\n        y = 6;\n        x = y;\n    } else {\n        x = 2;\n    }\n\n    let (x, y);\n    if true {\n        x = 1;\n    } else {\n        x = 2;\n    }\n    y = 3;\n\n    let x;\n    inline!($x = 1;);\n\n    let x;\n    if true {\n        inline!($x = 1;);\n    } else {\n        x = 2;\n    }\n\n    inline!({\n        let x;\n        x = 1;\n\n        let x;\n        if true {\n            x = 1;\n        } else {\n            x = 2;\n        }\n    });\n\n    // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613\n    let x;\n    if let Some(n) = Some(\"v\") {\n        x = 1;\n    } else {\n        x = 2;\n    }\n\n    let x;\n    if true && let Some(n) = Some(\"let chains too\") {\n        x = 1;\n    } else {\n        x = 2;\n    }\n\n    // ignore mut bindings\n    // https://github.com/shepmaster/twox-hash/blob/b169c16d86eb8ea4a296b0acb9d00ca7e3c3005f/src/sixty_four.rs#L88-L93\n    // https://github.com/dtolnay/thiserror/blob/21c26903e29cb92ba1a7ff11e82ae2001646b60d/tests/test_generics.rs#L91-L100\n    let mut x: usize;\n    x = 1;\n    x = 2;\n    x = 3;\n\n    // should not move the declaration if `x` has a significant drop, and there\n    // is another binding with a significant drop between it and the first usage\n    let x;\n    let y = SignificantDrop;\n    x = SignificantDrop;\n}\n\n#[rustfmt::skip]\nfn issue8911() -> u32 {\n    let x;\n    match 1 {\n        _ if { x = 1; false } => return 1,\n        _ => return 2,\n    }\n\n    let x;\n    if { x = 1; true } {\n        return 1;\n    } else {\n        return 2;\n    }\n\n    3\n}\n\nmacro_rules! issue13776_mac {\n    ($var:expr, $val:literal) => {\n        $var = $val;\n    };\n}\n\nfn issue13776() {\n    let x;\n    issue13776_mac!(x, 10); // should not lint\n}\n\nfn issue9895() {\n    let r;\n    //~^ needless_late_init\n    (r = 5);\n}\n"
  },
  {
    "path": "tests/ui/needless_late_init.stderr",
    "content": "error: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:25:5\n   |\nLL |     let a;\n   |     ^^^^^^ created here\nLL |\nLL |     a = \"zero\";\n   |     ^^^^^^^^^^ initialised here\n   |\n   = note: `-D clippy::needless-late-init` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_late_init)]`\nhelp: move the declaration `a` here\n   |\nLL ~     \nLL |\nLL ~     let a = \"zero\";\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:29:5\n   |\nLL |     let b;\n   |     ^^^^^^ created here\n...\nLL |     b = 1;\n   |     ^^^^^ initialised here\n   |\nhelp: move the declaration `b` here\n   |\nLL ~     \nLL |\nLL |     let c;\nLL |\nLL ~     let b = 1;\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:31:5\n   |\nLL |     let c;\n   |     ^^^^^^ created here\n...\nLL |     c = 2;\n   |     ^^^^^ initialised here\n   |\nhelp: move the declaration `c` here\n   |\nLL ~     \nLL |\nLL |     b = 1;\nLL ~     let c = 2;\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:36:5\n   |\nLL |     let d: usize;\n   |     ^^^^^^^^^^^^^ created here\nLL |\nLL |     d = 1;\n   |     ^^^^^ initialised here\n   |\nhelp: move the declaration `d` here\n   |\nLL ~     \nLL |\nLL ~     let d: usize = 1;\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:40:5\n   |\nLL |     let e;\n   |     ^^^^^^ created here\nLL |\nLL |     e = format!(\"{}\", d);\n   |     ^^^^^^^^^^^^^^^^^^^^ initialised here\n   |\nhelp: move the declaration `e` here\n   |\nLL ~     \nLL |\nLL ~     let e = format!(\"{}\", d);\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:46:5\n   |\nLL |     let a;\n   |     ^^^^^^\n   |\nhelp: move the declaration `a` here and remove the assignments from the `match` arms\n   |\nLL ~     \nLL |\nLL |     let n = 1;\nLL ~     let a = match n {\nLL ~         1 => \"one\",\nLL |         _ => {\nLL ~             \"two\"\nLL |         },\nLL ~     };\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:56:5\n   |\nLL |     let b;\n   |     ^^^^^^\n   |\nhelp: move the declaration `b` here and remove the assignments from the branches\n   |\nLL ~     \nLL |\nLL ~     let b = if n == 3 {\nLL ~         \"four\"\nLL |     } else {\nLL ~         \"five\"\nLL ~     };\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:64:5\n   |\nLL |     let d;\n   |     ^^^^^^\n   |\nhelp: move the declaration `d` here and remove the assignments from the branches\n   |\nLL ~     \nLL |\nLL ~     let d = if true {\nLL |         let temp = 5;\nLL ~         temp\nLL |     } else {\nLL ~         15\nLL ~     };\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:73:5\n   |\nLL |     let e;\n   |     ^^^^^^\n   |\nhelp: move the declaration `e` here and remove the assignments from the branches\n   |\nLL ~     \nLL |\nLL ~     let e = if true {\nLL ~         format!(\"{} {}\", a, b)\nLL |     } else {\nLL ~         format!(\"{}\", n)\nLL ~     };\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:81:5\n   |\nLL |     let f;\n   |     ^^^^^^\n   |\nhelp: move the declaration `f` here and remove the assignments from the `match` arms\n   |\nLL ~     \nLL |\nLL ~     let f = match 1 {\nLL ~         1 => \"three\",\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:88:5\n   |\nLL |     let g: usize;\n   |     ^^^^^^^^^^^^^\n   |\nhelp: move the declaration `g` here and remove the assignments from the branches\n   |\nLL ~     \nLL |\nLL ~     let g: usize = if true {\nLL ~         5\nLL |     } else {\nLL |         panic!();\nLL ~     };\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:97:5\n   |\nLL |     let x;\n   |     ^^^^^^ created here\n...\nLL |     x = 1;\n   |     ^^^^^ initialised here\n   |\nhelp: move the declaration `x` here\n   |\nLL ~     \nLL |\nLL |     let y = SignificantDrop;\nLL ~     let x = 1;\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:102:5\n   |\nLL |     let x;\n   |     ^^^^^^ created here\n...\nLL |     x = SignificantDrop;\n   |     ^^^^^^^^^^^^^^^^^^^ initialised here\n   |\nhelp: move the declaration `x` here\n   |\nLL ~     \nLL |\nLL |     let y = 1;\nLL ~     let x = SignificantDrop;\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:107:5\n   |\nLL |     let x;\n   |     ^^^^^^ created here\n...\nLL |     x = SignificantDrop;\n   |     ^^^^^^^^^^^^^^^^^^^ initialised here\n   |\nhelp: move the declaration `x` here\n   |\nLL ~     \nLL |\n...\nLL |     let y = Box::new(4);\nLL ~     let x = SignificantDrop;\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:127:5\n   |\nLL |     let a;\n   |     ^^^^^^\n   |\nhelp: move the declaration `a` here and remove the assignments from the `match` arms\n   |\nLL ~     \nLL |\nLL |     let n = 1;\nLL ~     let a = match n {\nLL ~         1 => f().await,\nLL |         _ => {\nLL ~             \"two\"\nLL |         },\nLL ~     };\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:145:5\n   |\nLL |     let a;\n   |     ^^^^^^\n   |\nhelp: move the declaration `a` here and remove the assignments from the `match` arms\n   |\nLL ~     \nLL |\nLL |     let n = 1;\nLL ~     let a = match n {\nLL ~         1 => f(),\nLL |         _ => {\nLL ~             \"two\"\nLL |         },\nLL ~     };\n   |\n\nerror: unneeded late initialization\n  --> tests/ui/needless_late_init.rs:298:5\n   |\nLL |     let r;\n   |     ^^^^^^ created here\nLL |\nLL |     (r = 5);\n   |     ^^^^^^^ initialised here\n   |\nhelp: move the declaration `r` here\n   |\nLL ~     \nLL |\nLL ~     let r = 5;\n   |\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_lifetimes.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)]\n#![allow(\n    unused,\n    clippy::boxed_local,\n    clippy::extra_unused_type_parameters,\n    clippy::needless_pass_by_value,\n    clippy::redundant_allocation,\n    clippy::unnecessary_wraps,\n    dyn_drop,\n    clippy::get_first,\n    mismatched_lifetime_syntaxes\n)]\n\nextern crate proc_macros;\nuse proc_macros::inline_macros;\n\nfn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {}\n//~^ needless_lifetimes\n\nfn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {}\n//~^ needless_lifetimes\n\n// No error; same lifetime on two params.\nfn same_lifetime_on_input<'a>(_x: &'a u8, _y: &'a u8) {}\n\n// No error; static involved.\nfn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {}\n\nfn mut_and_static_input(_x: &mut u8, _y: &'static str) {}\n\nfn in_and_out(x: &u8, _y: u8) -> &u8 {\n    //~^ needless_lifetimes\n    x\n}\n\n// No error; multiple input refs.\nfn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 {\n    x\n}\n\n// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n//   fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8\n//                                                ^^^\nfn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 {\n    //~^ needless_lifetimes\n    x\n}\n\n// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n//   fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8\n//                                     ^^^\nfn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 {\n    //~^ needless_lifetimes\n    y\n}\n\n// No error; multiple input refs\nasync fn func<'a>(args: &[&'a str]) -> Option<&'a str> {\n    args.get(0).cloned()\n}\n\n// No error; static involved.\nfn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 {\n    x\n}\n\n// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n//   fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()>\n//                                           ^^^\nfn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> {\n    //~^ needless_lifetimes\n    Ok(x)\n}\n\n// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n//   fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()>\n//                                ^^^\nfn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> {\n    //~^ needless_lifetimes\n    Ok(y)\n}\n\n// No error; two input refs.\nfn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 {\n    x.unwrap()\n}\n\nfn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> {\n    //~^ needless_lifetimes\n    Ok(x)\n}\n\n// Where-clause, but without lifetimes.\nfn where_clause_without_lt<T>(x: &u8, _y: u8) -> Result<&u8, ()>\n//~^ needless_lifetimes\nwhere\n    T: Copy,\n{\n    Ok(x)\n}\n\n// No error; see below.\nfn fn_bound_3<'a, F: FnOnce(&'a i32)>(x: &'a i32, f: F) {\n    f(x);\n}\n\nfn fn_bound_3_cannot_elide() {\n    let x = 42;\n    let p = &x;\n    let mut q = &x;\n    // This will fail if we elide lifetimes of `fn_bound_3`.\n    fn_bound_3(p, |y| q = y);\n}\n\n// No error; multiple input refs.\nfn fn_bound_4<'a, F: FnOnce() -> &'a ()>(cond: bool, x: &'a (), f: F) -> &'a () {\n    if cond { x } else { f() }\n}\n\nstruct X {\n    x: u8,\n}\n\nimpl X {\n    fn self_and_out(&self) -> &u8 {\n        //~^ needless_lifetimes\n        &self.x\n    }\n\n    // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n    //   fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8\n    //                                          ^^^\n    fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 {\n        //~^ needless_lifetimes\n        &self.x\n    }\n\n    // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n    //   fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8\n    //                            ^^^^^\n    fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 {\n        //~^ needless_lifetimes\n        x\n    }\n\n    fn distinct_self_and_in(&self, _x: &u8) {}\n    //~^ needless_lifetimes\n\n    // No error; same lifetimes on two params.\n    fn self_and_same_in<'s>(&'s self, _x: &'s u8) {}\n}\n\nstruct Foo<'a>(&'a u8);\n\nimpl<'a> Foo<'a> {\n    // No error; lifetime `'a` not defined in method.\n    fn self_shared_lifetime(&self, _: &'a u8) {}\n    // No error; bounds exist.\n    fn self_bound_lifetime<'b: 'a>(&self, _: &'b u8) {}\n}\n\nfn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 {\n    unimplemented!()\n}\n\n// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is\n// valid:\n//   fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str\n//                                 ^^^^\nfn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\n\ntrait WithLifetime<'a> {}\n\ntype WithLifetimeAlias<'a> = dyn WithLifetime<'a>;\n\n// Should not warn because it won't build without the lifetime.\nfn trait_obj_elided<'a>(_arg: &'a dyn WithLifetime) -> &'a str {\n    unimplemented!()\n}\n\n// Should warn because there is no lifetime on `Drop`, so this would be\n// unambiguous if we elided the lifetime.\nfn trait_obj_elided2(_arg: &dyn Drop) -> &str {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\n\ntype FooAlias<'a> = Foo<'a>;\n\n// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is\n// valid:\n//   fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str\n//                                ^^^^^^^^^\nfn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\n\nfn named_input_elided_output(_arg: &str) -> &str {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\n\nfn elided_input_named_output<'a>(_arg: &str) -> &'a str {\n    unimplemented!()\n}\n\nfn trait_bound_ok<T: WithLifetime<'static>>(_: &u8, _: T) {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\nfn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) {\n    unimplemented!()\n}\n\n// Don't warn on these; see issue #292.\nfn trait_bound_bug<'a, T: WithLifetime<'a>>() {\n    unimplemented!()\n}\n\n// See issue #740.\nstruct Test {\n    vec: Vec<usize>,\n}\n\nimpl Test {\n    fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = usize> + 'a> {\n        unimplemented!()\n    }\n}\n\ntrait LintContext<'a> {}\n\nfn f<'a, T: LintContext<'a>>(_: &T) {}\n\nfn test<'a>(x: &'a [u8]) -> u8 {\n    let y: &'a u8 = &x[5];\n    *y\n}\n\n// Make sure we still warn on implementations\nmod issue4291 {\n    trait BadTrait {\n        fn needless_lt(x: &u8) {}\n        //~^ needless_lifetimes\n    }\n\n    impl BadTrait for () {\n        fn needless_lt(_x: &u8) {}\n        //~^ needless_lifetimes\n    }\n}\n\nmod nested_elision_sites {\n    // issue #issue2944\n\n    // closure trait bounds subject to nested elision\n    // don't lint because they refer to outer lifetimes\n    fn trait_fn<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {\n        move || i\n    }\n    fn trait_fn_mut<'a>(i: &'a i32) -> impl FnMut() -> &'a i32 {\n        move || i\n    }\n    fn trait_fn_once<'a>(i: &'a i32) -> impl FnOnce() -> &'a i32 {\n        move || i\n    }\n\n    // don't lint\n    fn impl_trait_in_input_position<'a>(f: impl Fn() -> &'a i32) -> &'a i32 {\n        f()\n    }\n    fn impl_trait_in_output_position<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {\n        move || i\n    }\n    // lint\n    fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 {\n        f(i)\n    }\n    fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&i32) -> &i32) -> &i32 {\n        //~^ needless_lifetimes\n        f(i)\n    }\n\n    // don't lint\n    fn generics_not_elidable<'a, T: Fn() -> &'a i32>(f: T) -> &'a i32 {\n        f()\n    }\n    // lint\n    fn generics_elidable<T: Fn(&i32) -> &i32>(i: &i32, f: T) -> &i32 {\n        //~^ needless_lifetimes\n        f(i)\n    }\n\n    // don't lint\n    fn where_clause_not_elidable<'a, T>(f: T) -> &'a i32\n    where\n        T: Fn() -> &'a i32,\n    {\n        f()\n    }\n    // lint\n    fn where_clause_elidable<T>(i: &i32, f: T) -> &i32\n    //~^ needless_lifetimes\n    where\n        T: Fn(&i32) -> &i32,\n    {\n        f(i)\n    }\n\n    // don't lint\n    fn pointer_fn_in_input_position<'a>(f: fn(&'a i32) -> &'a i32, i: &'a i32) -> &'a i32 {\n        f(i)\n    }\n    fn pointer_fn_in_output_position<'a>(_: &'a i32) -> fn(&'a i32) -> &'a i32 {\n        |i| i\n    }\n    // lint\n    fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 {\n        //~^ needless_lifetimes\n        f(i)\n    }\n\n    // don't lint\n    fn nested_fn_pointer_1<'a>(_: &'a i32) -> fn(fn(&'a i32) -> &'a i32) -> i32 {\n        |f| 42\n    }\n    fn nested_fn_pointer_2<'a>(_: &'a i32) -> impl Fn(fn(&'a i32)) {\n        |f| ()\n    }\n\n    // lint\n    fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 {\n        //~^ needless_lifetimes\n        |f| 42\n    }\n    fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) {\n        //~^ needless_lifetimes\n        |f| ()\n    }\n}\n\nmod issue6159 {\n    use std::ops::Deref;\n    pub fn apply_deref<'a, T, F, R>(x: &'a T, f: F) -> R\n    where\n        T: Deref,\n        F: FnOnce(&'a T::Target) -> R,\n    {\n        f(x.deref())\n    }\n}\n\nmod issue7296 {\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    struct Foo;\n    impl Foo {\n        fn implicit(&self) -> &() {\n            //~^ needless_lifetimes\n            &()\n        }\n        fn implicit_mut(&mut self) -> &() {\n            //~^ needless_lifetimes\n            &()\n        }\n        #[clippy::msrv = \"1.81\"]\n        fn explicit(self: &Arc<Self>) -> &() {\n            //~^ needless_lifetimes\n            &()\n        }\n        #[clippy::msrv = \"1.81\"]\n        fn explicit_mut(self: &mut Rc<Self>) -> &() {\n            //~^ needless_lifetimes\n            &()\n        }\n        #[clippy::msrv = \"1.80\"]\n        fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a () {\n            &()\n        }\n        #[clippy::msrv = \"1.80\"]\n        fn explicit_mut_older<'a>(self: &'a mut Rc<Self>) -> &'a () {\n            &()\n        }\n\n        fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &() {\n            //~^ needless_lifetimes\n            &()\n        }\n    }\n\n    trait Bar {\n        fn implicit(&self) -> &();\n        //~^ needless_lifetimes\n        fn implicit_provided(&self) -> &() {\n            //~^ needless_lifetimes\n            &()\n        }\n\n        #[clippy::msrv = \"1.81\"]\n        fn explicit(self: &Arc<Self>) -> &();\n        //~^ needless_lifetimes\n        #[clippy::msrv = \"1.81\"]\n        fn explicit_provided(self: &Arc<Self>) -> &() {\n            //~^ needless_lifetimes\n            &()\n        }\n        #[clippy::msrv = \"1.80\"]\n        fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a ();\n        #[clippy::msrv = \"1.80\"]\n        fn explicit_provided_older<'a>(self: &'a Arc<Self>) -> &'a () {\n            &()\n        }\n\n        fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &();\n        //~^ needless_lifetimes\n        fn lifetime_elsewhere_provided(self: Box<Self>, here: &()) -> &() {\n            //~^ needless_lifetimes\n            &()\n        }\n    }\n}\n\nmod pr_9743_false_negative_fix {\n    #![allow(unused)]\n\n    fn foo(x: &u8, y: &'_ u8) {}\n    //~^ needless_lifetimes\n\n    fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {}\n    //~^ needless_lifetimes\n}\n\nmod pr_9743_output_lifetime_checks {\n    #![allow(unused)]\n\n    // lint: only one input\n    fn one_input(x: &u8) -> &u8 {\n        //~^ needless_lifetimes\n        unimplemented!()\n    }\n\n    // lint: multiple inputs, output would not be elided\n    fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) -> &'b u8 {\n        //~^ needless_lifetimes\n        unimplemented!()\n    }\n\n    // don't lint: multiple inputs, output would be elided (which would create an ambiguity)\n    fn multiple_inputs_output_would_be_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'a u8 {\n        unimplemented!()\n    }\n}\n\n#[inline_macros]\nmod in_macro {\n    use proc_macros::external;\n\n    // lint local macro expands to function with needless lifetimes\n    inline! {\n        fn one_input(x: &u8) -> &u8 {\n        //~^ needless_lifetimes\n            unimplemented!()\n        }\n    }\n\n    // no lint on external macro (standalone function)\n    external! {\n        fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 {\n            unimplemented!()\n        }\n    }\n\n    // no lint on external macro (method in impl block)\n    external! {\n        struct ExternalStruct;\n\n        impl ExternalStruct {\n            fn needless_lifetime_method<'a>(x: &'a u8) -> &'a u8 {\n                unimplemented!()\n            }\n        }\n    }\n\n    // no lint on external macro (trait method)\n    external! {\n        trait ExternalTrait {\n            fn needless_lifetime_trait_method<'a>(x: &'a u8) -> &'a u8;\n        }\n    }\n\n    // no lint on external macro (extra unused lifetimes in function)\n    external! {\n        fn extra_unused_lifetime<'a>(x: u8) {}\n    }\n\n    inline! {\n        fn f<$'a>(arg: &$'a str) -> &$'a str {\n            arg\n        }\n    }\n}\n\nmod issue5787 {\n    use std::sync::MutexGuard;\n\n    struct Foo;\n\n    impl Foo {\n        // doesn't get linted without async\n        pub async fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> {\n            guard\n        }\n    }\n\n    async fn foo<'a>(_x: &i32, y: &'a str) -> &'a str {\n        y\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/13286#issuecomment-2374245772\nmod rayon {\n    trait ParallelIterator {\n        type Item;\n    }\n\n    struct Copied<I: ParallelIterator> {\n        base: I,\n    }\n\n    impl<'a, T, I> ParallelIterator for Copied<I>\n    where\n        I: ParallelIterator<Item = &'a T>,\n        T: 'a + Copy + Send + Sync,\n    {\n        type Item = T;\n    }\n}\n\nmod issue13749 {\n    pub struct Generic<T>(T);\n    // Non elidable lifetime\n    #[expect(clippy::extra_unused_lifetimes)]\n    impl<'a, T> Generic<T> where T: 'a {}\n}\n\nmod issue13749bis {\n    pub struct Generic<T>(T);\n    // Non elidable lifetime\n    #[expect(clippy::extra_unused_lifetimes)]\n    impl<'a, T: 'a> Generic<T> {}\n}\n\npub fn issue14607<'s>(x: &'s u8) {\n    #[expect(clippy::redundant_closure_call)]\n    (|| {\n        let _: &'s u8 = x;\n    })();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_lifetimes.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::needless_lifetimes, clippy::elidable_lifetime_names)]\n#![allow(\n    unused,\n    clippy::boxed_local,\n    clippy::extra_unused_type_parameters,\n    clippy::needless_pass_by_value,\n    clippy::redundant_allocation,\n    clippy::unnecessary_wraps,\n    dyn_drop,\n    clippy::get_first,\n    mismatched_lifetime_syntaxes\n)]\n\nextern crate proc_macros;\nuse proc_macros::inline_macros;\n\nfn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}\n//~^ needless_lifetimes\n\nfn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {}\n//~^ needless_lifetimes\n\n// No error; same lifetime on two params.\nfn same_lifetime_on_input<'a>(_x: &'a u8, _y: &'a u8) {}\n\n// No error; static involved.\nfn only_static_on_input(_x: &u8, _y: &u8, _z: &'static u8) {}\n\nfn mut_and_static_input(_x: &mut u8, _y: &'static str) {}\n\nfn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {\n    //~^ needless_lifetimes\n    x\n}\n\n// No error; multiple input refs.\nfn multiple_in_and_out_1<'a>(x: &'a u8, _y: &'a u8) -> &'a u8 {\n    x\n}\n\n// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n//   fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8\n//                                                ^^^\nfn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {\n    //~^ needless_lifetimes\n    x\n}\n\n// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n//   fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8\n//                                     ^^^\nfn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {\n    //~^ needless_lifetimes\n    y\n}\n\n// No error; multiple input refs\nasync fn func<'a>(args: &[&'a str]) -> Option<&'a str> {\n    args.get(0).cloned()\n}\n\n// No error; static involved.\nfn in_static_and_out<'a>(x: &'a u8, _y: &'static u8) -> &'a u8 {\n    x\n}\n\n// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n//   fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()>\n//                                           ^^^\nfn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {\n    //~^ needless_lifetimes\n    Ok(x)\n}\n\n// Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n//   fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()>\n//                                ^^^\nfn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {\n    //~^ needless_lifetimes\n    Ok(y)\n}\n\n// No error; two input refs.\nfn deep_reference_2<'a>(x: Result<&'a u8, &'a u8>) -> &'a u8 {\n    x.unwrap()\n}\n\nfn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {\n    //~^ needless_lifetimes\n    Ok(x)\n}\n\n// Where-clause, but without lifetimes.\nfn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>\n//~^ needless_lifetimes\nwhere\n    T: Copy,\n{\n    Ok(x)\n}\n\n// No error; see below.\nfn fn_bound_3<'a, F: FnOnce(&'a i32)>(x: &'a i32, f: F) {\n    f(x);\n}\n\nfn fn_bound_3_cannot_elide() {\n    let x = 42;\n    let p = &x;\n    let mut q = &x;\n    // This will fail if we elide lifetimes of `fn_bound_3`.\n    fn_bound_3(p, |y| q = y);\n}\n\n// No error; multiple input refs.\nfn fn_bound_4<'a, F: FnOnce() -> &'a ()>(cond: bool, x: &'a (), f: F) -> &'a () {\n    if cond { x } else { f() }\n}\n\nstruct X {\n    x: u8,\n}\n\nimpl X {\n    fn self_and_out<'s>(&'s self) -> &'s u8 {\n        //~^ needless_lifetimes\n        &self.x\n    }\n\n    // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n    //   fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8\n    //                                          ^^^\n    fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {\n        //~^ needless_lifetimes\n        &self.x\n    }\n\n    // Error; multiple input refs, but the output lifetime is not elided, i.e., the following is valid:\n    //   fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8\n    //                            ^^^^^\n    fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {\n        //~^ needless_lifetimes\n        x\n    }\n\n    fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}\n    //~^ needless_lifetimes\n\n    // No error; same lifetimes on two params.\n    fn self_and_same_in<'s>(&'s self, _x: &'s u8) {}\n}\n\nstruct Foo<'a>(&'a u8);\n\nimpl<'a> Foo<'a> {\n    // No error; lifetime `'a` not defined in method.\n    fn self_shared_lifetime(&self, _: &'a u8) {}\n    // No error; bounds exist.\n    fn self_bound_lifetime<'b: 'a>(&self, _: &'b u8) {}\n}\n\nfn already_elided<'a>(_: &u8, _: &'a u8) -> &'a u8 {\n    unimplemented!()\n}\n\n// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is\n// valid:\n//   fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str\n//                                 ^^^^\nfn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\n\ntrait WithLifetime<'a> {}\n\ntype WithLifetimeAlias<'a> = dyn WithLifetime<'a>;\n\n// Should not warn because it won't build without the lifetime.\nfn trait_obj_elided<'a>(_arg: &'a dyn WithLifetime) -> &'a str {\n    unimplemented!()\n}\n\n// Should warn because there is no lifetime on `Drop`, so this would be\n// unambiguous if we elided the lifetime.\nfn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\n\ntype FooAlias<'a> = Foo<'a>;\n\n// Warning; two input lifetimes, but the output lifetime is not elided, i.e., the following is\n// valid:\n//   fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str\n//                                ^^^^^^^^^\nfn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\n\nfn named_input_elided_output<'a>(_arg: &'a str) -> &str {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\n\nfn elided_input_named_output<'a>(_arg: &str) -> &'a str {\n    unimplemented!()\n}\n\nfn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {\n    //~^ needless_lifetimes\n    unimplemented!()\n}\nfn trait_bound<'a, T: WithLifetime<'a>>(_: &'a u8, _: T) {\n    unimplemented!()\n}\n\n// Don't warn on these; see issue #292.\nfn trait_bound_bug<'a, T: WithLifetime<'a>>() {\n    unimplemented!()\n}\n\n// See issue #740.\nstruct Test {\n    vec: Vec<usize>,\n}\n\nimpl Test {\n    fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = usize> + 'a> {\n        unimplemented!()\n    }\n}\n\ntrait LintContext<'a> {}\n\nfn f<'a, T: LintContext<'a>>(_: &T) {}\n\nfn test<'a>(x: &'a [u8]) -> u8 {\n    let y: &'a u8 = &x[5];\n    *y\n}\n\n// Make sure we still warn on implementations\nmod issue4291 {\n    trait BadTrait {\n        fn needless_lt<'a>(x: &'a u8) {}\n        //~^ needless_lifetimes\n    }\n\n    impl BadTrait for () {\n        fn needless_lt<'a>(_x: &'a u8) {}\n        //~^ needless_lifetimes\n    }\n}\n\nmod nested_elision_sites {\n    // issue #issue2944\n\n    // closure trait bounds subject to nested elision\n    // don't lint because they refer to outer lifetimes\n    fn trait_fn<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {\n        move || i\n    }\n    fn trait_fn_mut<'a>(i: &'a i32) -> impl FnMut() -> &'a i32 {\n        move || i\n    }\n    fn trait_fn_once<'a>(i: &'a i32) -> impl FnOnce() -> &'a i32 {\n        move || i\n    }\n\n    // don't lint\n    fn impl_trait_in_input_position<'a>(f: impl Fn() -> &'a i32) -> &'a i32 {\n        f()\n    }\n    fn impl_trait_in_output_position<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {\n        move || i\n    }\n    // lint\n    fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 {\n        f(i)\n    }\n    fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {\n        //~^ needless_lifetimes\n        f(i)\n    }\n\n    // don't lint\n    fn generics_not_elidable<'a, T: Fn() -> &'a i32>(f: T) -> &'a i32 {\n        f()\n    }\n    // lint\n    fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {\n        //~^ needless_lifetimes\n        f(i)\n    }\n\n    // don't lint\n    fn where_clause_not_elidable<'a, T>(f: T) -> &'a i32\n    where\n        T: Fn() -> &'a i32,\n    {\n        f()\n    }\n    // lint\n    fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32\n    //~^ needless_lifetimes\n    where\n        T: Fn(&i32) -> &i32,\n    {\n        f(i)\n    }\n\n    // don't lint\n    fn pointer_fn_in_input_position<'a>(f: fn(&'a i32) -> &'a i32, i: &'a i32) -> &'a i32 {\n        f(i)\n    }\n    fn pointer_fn_in_output_position<'a>(_: &'a i32) -> fn(&'a i32) -> &'a i32 {\n        |i| i\n    }\n    // lint\n    fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {\n        //~^ needless_lifetimes\n        f(i)\n    }\n\n    // don't lint\n    fn nested_fn_pointer_1<'a>(_: &'a i32) -> fn(fn(&'a i32) -> &'a i32) -> i32 {\n        |f| 42\n    }\n    fn nested_fn_pointer_2<'a>(_: &'a i32) -> impl Fn(fn(&'a i32)) {\n        |f| ()\n    }\n\n    // lint\n    fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {\n        //~^ needless_lifetimes\n        |f| 42\n    }\n    fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {\n        //~^ needless_lifetimes\n        |f| ()\n    }\n}\n\nmod issue6159 {\n    use std::ops::Deref;\n    pub fn apply_deref<'a, T, F, R>(x: &'a T, f: F) -> R\n    where\n        T: Deref,\n        F: FnOnce(&'a T::Target) -> R,\n    {\n        f(x.deref())\n    }\n}\n\nmod issue7296 {\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    struct Foo;\n    impl Foo {\n        fn implicit<'a>(&'a self) -> &'a () {\n            //~^ needless_lifetimes\n            &()\n        }\n        fn implicit_mut<'a>(&'a mut self) -> &'a () {\n            //~^ needless_lifetimes\n            &()\n        }\n        #[clippy::msrv = \"1.81\"]\n        fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {\n            //~^ needless_lifetimes\n            &()\n        }\n        #[clippy::msrv = \"1.81\"]\n        fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {\n            //~^ needless_lifetimes\n            &()\n        }\n        #[clippy::msrv = \"1.80\"]\n        fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a () {\n            &()\n        }\n        #[clippy::msrv = \"1.80\"]\n        fn explicit_mut_older<'a>(self: &'a mut Rc<Self>) -> &'a () {\n            &()\n        }\n\n        fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {\n            //~^ needless_lifetimes\n            &()\n        }\n    }\n\n    trait Bar {\n        fn implicit<'a>(&'a self) -> &'a ();\n        //~^ needless_lifetimes\n        fn implicit_provided<'a>(&'a self) -> &'a () {\n            //~^ needless_lifetimes\n            &()\n        }\n\n        #[clippy::msrv = \"1.81\"]\n        fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();\n        //~^ needless_lifetimes\n        #[clippy::msrv = \"1.81\"]\n        fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {\n            //~^ needless_lifetimes\n            &()\n        }\n        #[clippy::msrv = \"1.80\"]\n        fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a ();\n        #[clippy::msrv = \"1.80\"]\n        fn explicit_provided_older<'a>(self: &'a Arc<Self>) -> &'a () {\n            &()\n        }\n\n        fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();\n        //~^ needless_lifetimes\n        fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {\n            //~^ needless_lifetimes\n            &()\n        }\n    }\n}\n\nmod pr_9743_false_negative_fix {\n    #![allow(unused)]\n\n    fn foo<'a>(x: &'a u8, y: &'_ u8) {}\n    //~^ needless_lifetimes\n\n    fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}\n    //~^ needless_lifetimes\n}\n\nmod pr_9743_output_lifetime_checks {\n    #![allow(unused)]\n\n    // lint: only one input\n    fn one_input<'a>(x: &'a u8) -> &'a u8 {\n        //~^ needless_lifetimes\n        unimplemented!()\n    }\n\n    // lint: multiple inputs, output would not be elided\n    fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {\n        //~^ needless_lifetimes\n        unimplemented!()\n    }\n\n    // don't lint: multiple inputs, output would be elided (which would create an ambiguity)\n    fn multiple_inputs_output_would_be_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'a u8 {\n        unimplemented!()\n    }\n}\n\n#[inline_macros]\nmod in_macro {\n    use proc_macros::external;\n\n    // lint local macro expands to function with needless lifetimes\n    inline! {\n        fn one_input<'a>(x: &'a u8) -> &'a u8 {\n        //~^ needless_lifetimes\n            unimplemented!()\n        }\n    }\n\n    // no lint on external macro (standalone function)\n    external! {\n        fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 {\n            unimplemented!()\n        }\n    }\n\n    // no lint on external macro (method in impl block)\n    external! {\n        struct ExternalStruct;\n\n        impl ExternalStruct {\n            fn needless_lifetime_method<'a>(x: &'a u8) -> &'a u8 {\n                unimplemented!()\n            }\n        }\n    }\n\n    // no lint on external macro (trait method)\n    external! {\n        trait ExternalTrait {\n            fn needless_lifetime_trait_method<'a>(x: &'a u8) -> &'a u8;\n        }\n    }\n\n    // no lint on external macro (extra unused lifetimes in function)\n    external! {\n        fn extra_unused_lifetime<'a>(x: u8) {}\n    }\n\n    inline! {\n        fn f<$'a>(arg: &$'a str) -> &$'a str {\n            arg\n        }\n    }\n}\n\nmod issue5787 {\n    use std::sync::MutexGuard;\n\n    struct Foo;\n\n    impl Foo {\n        // doesn't get linted without async\n        pub async fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> {\n            guard\n        }\n    }\n\n    async fn foo<'a>(_x: &i32, y: &'a str) -> &'a str {\n        y\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/13286#issuecomment-2374245772\nmod rayon {\n    trait ParallelIterator {\n        type Item;\n    }\n\n    struct Copied<I: ParallelIterator> {\n        base: I,\n    }\n\n    impl<'a, T, I> ParallelIterator for Copied<I>\n    where\n        I: ParallelIterator<Item = &'a T>,\n        T: 'a + Copy + Send + Sync,\n    {\n        type Item = T;\n    }\n}\n\nmod issue13749 {\n    pub struct Generic<T>(T);\n    // Non elidable lifetime\n    #[expect(clippy::extra_unused_lifetimes)]\n    impl<'a, T> Generic<T> where T: 'a {}\n}\n\nmod issue13749bis {\n    pub struct Generic<T>(T);\n    // Non elidable lifetime\n    #[expect(clippy::extra_unused_lifetimes)]\n    impl<'a, T: 'a> Generic<T> {}\n}\n\npub fn issue14607<'s>(x: &'s u8) {\n    #[expect(clippy::redundant_closure_call)]\n    (|| {\n        let _: &'s u8 = x;\n    })();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_lifetimes.stderr",
    "content": "error: the following explicit lifetimes could be elided: 'a, 'b\n  --> tests/ui/needless_lifetimes.rs:19:23\n   |\nLL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}\n   |                       ^^  ^^       ^^          ^^\n   |\n   = note: `-D clippy::needless-lifetimes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_lifetimes)]`\nhelp: elide the lifetimes\n   |\nLL - fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}\nLL + fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a, 'b\n  --> tests/ui/needless_lifetimes.rs:22:24\n   |\nLL | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {}\n   |                        ^^  ^^       ^^          ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {}\nLL + fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:33:15\n   |\nLL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {\n   |               ^^      ^^                 ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {\nLL + fn in_and_out(x: &u8, _y: u8) -> &u8 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'b\n  --> tests/ui/needless_lifetimes.rs:46:31\n   |\nLL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {\n   |                               ^^                  ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {\nLL + fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:54:27\n   |\nLL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {\n   |                           ^^           ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {\nLL + fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'b\n  --> tests/ui/needless_lifetimes.rs:72:26\n   |\nLL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {\n   |                          ^^                  ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {\nLL + fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:80:22\n   |\nLL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {\n   |                      ^^           ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {\nLL + fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:90:21\n   |\nLL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {\n   |                     ^^      ^^                        ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {\nLL + fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:96:28\n   |\nLL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>\n   |                            ^^         ^^                        ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>\nLL + fn where_clause_without_lt<T>(x: &u8, _y: u8) -> Result<&u8, ()>\n   |\n\nerror: the following explicit lifetimes could be elided: 's\n  --> tests/ui/needless_lifetimes.rs:127:21\n   |\nLL |     fn self_and_out<'s>(&'s self) -> &'s u8 {\n   |                     ^^   ^^           ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn self_and_out<'s>(&'s self) -> &'s u8 {\nLL +     fn self_and_out(&self) -> &u8 {\n   |\n\nerror: the following explicit lifetimes could be elided: 't\n  --> tests/ui/needless_lifetimes.rs:135:30\n   |\nLL |     fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {\n   |                              ^^                 ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {\nLL +     fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 {\n   |\n\nerror: the following explicit lifetimes could be elided: 's\n  --> tests/ui/needless_lifetimes.rs:143:26\n   |\nLL |     fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {\n   |                          ^^       ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {\nLL +     fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 {\n   |\n\nerror: the following explicit lifetimes could be elided: 's, 't\n  --> tests/ui/needless_lifetimes.rs:148:29\n   |\nLL |     fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}\n   |                             ^^  ^^   ^^            ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}\nLL +     fn distinct_self_and_in(&self, _x: &u8) {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:172:21\n   |\nLL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {\n   |                     ^^             ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {\nLL + fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:188:22\n   |\nLL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {\n   |                      ^^         ^^               ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {\nLL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:199:20\n   |\nLL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {\n   |                    ^^             ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {\nLL + fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:204:30\n   |\nLL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {\n   |                              ^^         ^^          ^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn named_input_elided_output<'a>(_arg: &'a str) -> &str {\nLL + fn named_input_elided_output(_arg: &str) -> &str {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:213:19\n   |\nLL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {\n   |                   ^^                                ^^\n   |\nhelp: elide the lifetimes\n   |\nLL - fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {\nLL + fn trait_bound_ok<T: WithLifetime<'static>>(_: &u8, _: T) {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:249:24\n   |\nLL |         fn needless_lt<'a>(x: &'a u8) {}\n   |                        ^^      ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn needless_lt<'a>(x: &'a u8) {}\nLL +         fn needless_lt(x: &u8) {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:254:24\n   |\nLL |         fn needless_lt<'a>(_x: &'a u8) {}\n   |                        ^^       ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn needless_lt<'a>(_x: &'a u8) {}\nLL +         fn needless_lt(_x: &u8) {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:285:55\n   |\nLL |     fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {\n   |                                                       ^^      ^^                                    ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {\nLL +     fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&i32) -> &i32) -> &i32 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:295:26\n   |\nLL |     fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {\n   |                          ^^                           ^^                ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {\nLL +     fn generics_elidable<T: Fn(&i32) -> &i32>(i: &i32, f: T) -> &i32 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:308:30\n   |\nLL |     fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32\n   |                              ^^         ^^                ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32\nLL +     fn where_clause_elidable<T>(i: &i32, f: T) -> &i32\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:324:28\n   |\nLL |     fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {\n   |                            ^^      ^^                               ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {\nLL +     fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:338:28\n   |\nLL |     fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {\n   |                            ^^      ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {\nLL +     fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:342:28\n   |\nLL |     fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {\n   |                            ^^      ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {\nLL +     fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:365:21\n   |\nLL |         fn implicit<'a>(&'a self) -> &'a () {\n   |                     ^^   ^^           ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn implicit<'a>(&'a self) -> &'a () {\nLL +         fn implicit(&self) -> &() {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:369:25\n   |\nLL |         fn implicit_mut<'a>(&'a mut self) -> &'a () {\n   |                         ^^   ^^               ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn implicit_mut<'a>(&'a mut self) -> &'a () {\nLL +         fn implicit_mut(&mut self) -> &() {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:374:21\n   |\nLL |         fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {\n   |                     ^^         ^^                ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {\nLL +         fn explicit(self: &Arc<Self>) -> &() {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:379:25\n   |\nLL |         fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {\n   |                         ^^         ^^                   ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {\nLL +         fn explicit_mut(self: &mut Rc<Self>) -> &() {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:392:31\n   |\nLL |         fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {\n   |                               ^^                          ^^         ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {\nLL +         fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &() {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:399:21\n   |\nLL |         fn implicit<'a>(&'a self) -> &'a ();\n   |                     ^^   ^^           ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn implicit<'a>(&'a self) -> &'a ();\nLL +         fn implicit(&self) -> &();\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:401:30\n   |\nLL |         fn implicit_provided<'a>(&'a self) -> &'a () {\n   |                              ^^   ^^           ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn implicit_provided<'a>(&'a self) -> &'a () {\nLL +         fn implicit_provided(&self) -> &() {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:407:21\n   |\nLL |         fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();\n   |                     ^^         ^^                ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();\nLL +         fn explicit(self: &Arc<Self>) -> &();\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:410:30\n   |\nLL |         fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {\n   |                              ^^         ^^                ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {\nLL +         fn explicit_provided(self: &Arc<Self>) -> &() {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:421:31\n   |\nLL |         fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();\n   |                               ^^                          ^^         ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();\nLL +         fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &();\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:423:40\n   |\nLL |         fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {\n   |                                        ^^                          ^^         ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -         fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {\nLL +         fn lifetime_elsewhere_provided(self: Box<Self>, here: &()) -> &() {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:433:12\n   |\nLL |     fn foo<'a>(x: &'a u8, y: &'_ u8) {}\n   |            ^^      ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn foo<'a>(x: &'a u8, y: &'_ u8) {}\nLL +     fn foo(x: &u8, y: &'_ u8) {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:436:12\n   |\nLL |     fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}\n   |            ^^      ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}\nLL +     fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {}\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:444:18\n   |\nLL |     fn one_input<'a>(x: &'a u8) -> &'a u8 {\n   |                  ^^      ^^         ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn one_input<'a>(x: &'a u8) -> &'a u8 {\nLL +     fn one_input(x: &u8) -> &u8 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:450:42\n   |\nLL |     fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {\n   |                                          ^^          ^^\n   |\nhelp: elide the lifetimes\n   |\nLL -     fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {\nLL +     fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) -> &'b u8 {\n   |\n\nerror: the following explicit lifetimes could be elided: 'a\n  --> tests/ui/needless_lifetimes.rs:467:22\n   |\nLL |         fn one_input<'a>(x: &'a u8) -> &'a u8 {\n   |                      ^^      ^^         ^^\n   |\n   = note: this error originates in the macro `__inline_mac_mod_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: elide the lifetimes\n   |\nLL -         fn one_input<'a>(x: &'a u8) -> &'a u8 {\nLL +         fn one_input(x: &u8) -> &u8 {\n   |\n\nerror: aborting due to 42 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_match.fixed",
    "content": "#![warn(clippy::needless_match)]\n#![allow(clippy::manual_map)]\n#![allow(dead_code)]\n#![allow(unused)]\n#[derive(Clone, Copy)]\nenum Simple {\n    A,\n    B,\n    C,\n    D,\n}\n\nfn useless_match() {\n    let i = 10;\n    let _: i32 = i;\n    let s = \"test\";\n    let _: &str = s;\n}\n\nfn custom_type_match() {\n    let se = Simple::A;\n    let _: Simple = se;\n    // Don't trigger\n    let _: Simple = match se {\n        Simple::A => Simple::A,\n        Simple::B => Simple::B,\n        _ => Simple::C,\n    };\n    // Mingled, don't trigger\n    let _: Simple = match se {\n        Simple::A => Simple::B,\n        Simple::B => Simple::C,\n        Simple::C => Simple::D,\n        Simple::D => Simple::A,\n    };\n}\n\nfn option_match(x: Option<i32>) {\n    let _: Option<i32> = x;\n    // Don't trigger, this is the case for manual_map_option\n    let _: Option<i32> = match x {\n        Some(a) => Some(-a),\n        None => None,\n    };\n}\n\nfn func_ret_err<T>(err: T) -> Result<i32, T> {\n    Err(err)\n}\n\nfn result_match() {\n    let _: Result<i32, i32> = Ok(1);\n    let _: Result<i32, i32> = func_ret_err(0_i32);\n    // as ref, don't trigger\n    let res = &func_ret_err(0_i32);\n    let _: Result<&i32, &i32> = match *res {\n        Ok(ref x) => Ok(x),\n        Err(ref x) => Err(x),\n    };\n}\n\nfn if_let_option() {\n    let _ = Some(1);\n    //~^ needless_match\n\n    fn do_something() {}\n\n    // Don't trigger\n    let _ = if let Some(a) = Some(1) {\n        Some(a)\n    } else {\n        do_something();\n        None\n    };\n\n    // Don't trigger\n    let _ = if let Some(a) = Some(1) {\n        do_something();\n        Some(a)\n    } else {\n        None\n    };\n\n    // Don't trigger\n    let _ = if let Some(a) = Some(1) { Some(a) } else { Some(2) };\n}\n\nfn if_let_option_result() -> Result<(), ()> {\n    fn f(x: i32) -> Result<Option<i32>, ()> {\n        Ok(Some(x))\n    }\n    // Don't trigger\n    let _ = if let Some(v) = f(1)? { Some(v) } else { f(2)? };\n    Ok(())\n}\n\nfn if_let_result() {\n    let x: Result<i32, i32> = Ok(1);\n    let _: Result<i32, i32> = x;\n    //~^ needless_match\n    let _: Result<i32, i32> = x;\n    //~^ needless_match\n    // Input type mismatch, don't trigger\n    #[allow(clippy::question_mark)]\n    let _: Result<i32, i32> = if let Err(e) = Ok(1) { Err(e) } else { x };\n}\n\nfn if_let_custom_enum(x: Simple) {\n    let _: Simple = x;\n\n    // Don't trigger\n    let _: Simple = if let Simple::A = x {\n        Simple::A\n    } else if true {\n        Simple::B\n    } else {\n        x\n    };\n}\n\nmod issue8542 {\n    #[derive(Clone, Copy)]\n    enum E {\n        VariantA(u8, u8),\n        VariantB(u8, bool),\n    }\n\n    enum Complex {\n        A(u8),\n        B(u8, bool),\n        C(u8, i32, f64),\n        D(E, bool),\n    }\n\n    fn match_test() {\n        let ce = Complex::B(8, false);\n        let aa = 0_u8;\n        let bb = false;\n\n        let _: Complex = ce;\n\n        // Don't trigger\n        let _: Complex = match ce {\n            Complex::A(_) => Complex::A(aa),\n            Complex::B(_, b) => Complex::B(aa, b),\n            Complex::C(_, b, _) => Complex::C(aa, b, 64_f64),\n            Complex::D(e, b) => Complex::D(e, b),\n        };\n\n        // Don't trigger\n        let _: Complex = match ce {\n            Complex::A(a) => Complex::A(a),\n            Complex::B(a, _) => Complex::B(a, bb),\n            Complex::C(a, _, _) => Complex::C(a, 32_i32, 64_f64),\n            _ => ce,\n        };\n    }\n}\n\n/// Lint triggered when type coercions happen.\n/// Do NOT trigger on any of these.\nmod issue8551 {\n    trait Trait {}\n    struct Struct;\n    impl Trait for Struct {}\n\n    fn optmap(s: Option<&Struct>) -> Option<&dyn Trait> {\n        match s {\n            Some(s) => Some(s),\n            None => None,\n        }\n    }\n\n    fn lint_tests() {\n        let option: Option<&Struct> = None;\n        let _: Option<&dyn Trait> = match option {\n            Some(s) => Some(s),\n            None => None,\n        };\n\n        let _: Option<&dyn Trait> = if true {\n            match option {\n                Some(s) => Some(s),\n                None => None,\n            }\n        } else {\n            None\n        };\n\n        let result: Result<&Struct, i32> = Err(0);\n        let _: Result<&dyn Trait, i32> = match result {\n            Ok(s) => Ok(s),\n            Err(e) => Err(e),\n        };\n\n        let _: Option<&dyn Trait> = if let Some(s) = option { Some(s) } else { None };\n    }\n}\n\ntrait Tr {\n    fn as_mut(&mut self) -> Result<&mut i32, &mut i32>;\n}\nimpl Tr for Result<i32, i32> {\n    fn as_mut(&mut self) -> Result<&mut i32, &mut i32> {\n        match self {\n            Ok(x) => Ok(x),\n            Err(e) => Err(e),\n        }\n    }\n}\n\nmod issue9084 {\n    fn wildcard_if() {\n        let mut some_bool = true;\n        let e = Some(1);\n\n        // should lint\n        let _ = e;\n\n        // should lint\n        let _ = e;\n\n        // should not lint\n        let _ = match e {\n            _ if some_bool => e,\n            _ => Some(2),\n        };\n\n        // should not lint\n        let _ = match e {\n            Some(i) => Some(i + 1),\n            _ if some_bool => e,\n            _ => e,\n        };\n\n        // should not lint (guard has side effects)\n        let _ = match e {\n            Some(i) => Some(i),\n            _ if {\n                some_bool = false;\n                some_bool\n            } =>\n            {\n                e\n            },\n            _ => e,\n        };\n    }\n}\n\nfn a() -> Option<()> {\n    Some(())\n}\nfn b() -> Option<()> {\n    Some(())\n}\nfn c() -> Option<()> {\n    Some(())\n}\n\n#[allow(clippy::ifs_same_cond)]\npub fn issue13574() -> Option<()> {\n    // Do not lint.\n    // The right hand of all these arms are different functions.\n    let _ = {\n        if let Some(a) = a() {\n            Some(a)\n        } else if let Some(b) = b() {\n            Some(b)\n        } else if let Some(c) = c() {\n            Some(c)\n        } else {\n            None\n        }\n    };\n\n    const A: Option<()> = Some(());\n    const B: Option<()> = Some(());\n    const C: Option<()> = Some(());\n    const D: Option<()> = Some(());\n\n    let _ = {\n        if let Some(num) = A {\n            Some(num)\n        } else if let Some(num) = B {\n            Some(num)\n        } else if let Some(num) = C {\n            Some(num)\n        } else if let Some(num) = D {\n            Some(num)\n        } else {\n            None\n        }\n    };\n\n    // Same const, should lint\n    let _ = {\n        A\n    };\n\n    None\n}\n\nfn issue14754(t: Result<i32, &'static str>) -> Result<i32, &'static str> {\n    let _ = match t {\n        Ok(v) => Ok::<_, &'static str>(v),\n        err @ Err(_) => return err,\n    };\n    println!(\"Still here\");\n    let x = t;\n    //~^^^^ needless_match\n    println!(\"Still here\");\n    x\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_match.rs",
    "content": "#![warn(clippy::needless_match)]\n#![allow(clippy::manual_map)]\n#![allow(dead_code)]\n#![allow(unused)]\n#[derive(Clone, Copy)]\nenum Simple {\n    A,\n    B,\n    C,\n    D,\n}\n\nfn useless_match() {\n    let i = 10;\n    let _: i32 = match i {\n        //~^ needless_match\n        0 => 0,\n        1 => 1,\n        2 => 2,\n        _ => i,\n    };\n    let s = \"test\";\n    let _: &str = match s {\n        //~^ needless_match\n        \"a\" => \"a\",\n        \"b\" => \"b\",\n        s => s,\n    };\n}\n\nfn custom_type_match() {\n    let se = Simple::A;\n    let _: Simple = match se {\n        //~^ needless_match\n        Simple::A => Simple::A,\n        Simple::B => Simple::B,\n        Simple::C => Simple::C,\n        Simple::D => Simple::D,\n    };\n    // Don't trigger\n    let _: Simple = match se {\n        Simple::A => Simple::A,\n        Simple::B => Simple::B,\n        _ => Simple::C,\n    };\n    // Mingled, don't trigger\n    let _: Simple = match se {\n        Simple::A => Simple::B,\n        Simple::B => Simple::C,\n        Simple::C => Simple::D,\n        Simple::D => Simple::A,\n    };\n}\n\nfn option_match(x: Option<i32>) {\n    let _: Option<i32> = match x {\n        //~^ needless_match\n        Some(a) => Some(a),\n        None => None,\n    };\n    // Don't trigger, this is the case for manual_map_option\n    let _: Option<i32> = match x {\n        Some(a) => Some(-a),\n        None => None,\n    };\n}\n\nfn func_ret_err<T>(err: T) -> Result<i32, T> {\n    Err(err)\n}\n\nfn result_match() {\n    let _: Result<i32, i32> = match Ok(1) {\n        //~^ needless_match\n        Ok(a) => Ok(a),\n        Err(err) => Err(err),\n    };\n    let _: Result<i32, i32> = match func_ret_err(0_i32) {\n        //~^ needless_match\n        Err(err) => Err(err),\n        Ok(a) => Ok(a),\n    };\n    // as ref, don't trigger\n    let res = &func_ret_err(0_i32);\n    let _: Result<&i32, &i32> = match *res {\n        Ok(ref x) => Ok(x),\n        Err(ref x) => Err(x),\n    };\n}\n\nfn if_let_option() {\n    let _ = if let Some(a) = Some(1) { Some(a) } else { None };\n    //~^ needless_match\n\n    fn do_something() {}\n\n    // Don't trigger\n    let _ = if let Some(a) = Some(1) {\n        Some(a)\n    } else {\n        do_something();\n        None\n    };\n\n    // Don't trigger\n    let _ = if let Some(a) = Some(1) {\n        do_something();\n        Some(a)\n    } else {\n        None\n    };\n\n    // Don't trigger\n    let _ = if let Some(a) = Some(1) { Some(a) } else { Some(2) };\n}\n\nfn if_let_option_result() -> Result<(), ()> {\n    fn f(x: i32) -> Result<Option<i32>, ()> {\n        Ok(Some(x))\n    }\n    // Don't trigger\n    let _ = if let Some(v) = f(1)? { Some(v) } else { f(2)? };\n    Ok(())\n}\n\nfn if_let_result() {\n    let x: Result<i32, i32> = Ok(1);\n    let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };\n    //~^ needless_match\n    let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };\n    //~^ needless_match\n    // Input type mismatch, don't trigger\n    #[allow(clippy::question_mark)]\n    let _: Result<i32, i32> = if let Err(e) = Ok(1) { Err(e) } else { x };\n}\n\nfn if_let_custom_enum(x: Simple) {\n    let _: Simple = if let Simple::A = x {\n        //~^ needless_match\n        Simple::A\n    } else if let Simple::B = x {\n        Simple::B\n    } else if let Simple::C = x {\n        Simple::C\n    } else {\n        x\n    };\n\n    // Don't trigger\n    let _: Simple = if let Simple::A = x {\n        Simple::A\n    } else if true {\n        Simple::B\n    } else {\n        x\n    };\n}\n\nmod issue8542 {\n    #[derive(Clone, Copy)]\n    enum E {\n        VariantA(u8, u8),\n        VariantB(u8, bool),\n    }\n\n    enum Complex {\n        A(u8),\n        B(u8, bool),\n        C(u8, i32, f64),\n        D(E, bool),\n    }\n\n    fn match_test() {\n        let ce = Complex::B(8, false);\n        let aa = 0_u8;\n        let bb = false;\n\n        let _: Complex = match ce {\n            //~^ needless_match\n            Complex::A(a) => Complex::A(a),\n            Complex::B(a, b) => Complex::B(a, b),\n            Complex::C(a, b, c) => Complex::C(a, b, c),\n            Complex::D(E::VariantA(ea, eb), b) => Complex::D(E::VariantA(ea, eb), b),\n            Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(ea, eb), b),\n        };\n\n        // Don't trigger\n        let _: Complex = match ce {\n            Complex::A(_) => Complex::A(aa),\n            Complex::B(_, b) => Complex::B(aa, b),\n            Complex::C(_, b, _) => Complex::C(aa, b, 64_f64),\n            Complex::D(e, b) => Complex::D(e, b),\n        };\n\n        // Don't trigger\n        let _: Complex = match ce {\n            Complex::A(a) => Complex::A(a),\n            Complex::B(a, _) => Complex::B(a, bb),\n            Complex::C(a, _, _) => Complex::C(a, 32_i32, 64_f64),\n            _ => ce,\n        };\n    }\n}\n\n/// Lint triggered when type coercions happen.\n/// Do NOT trigger on any of these.\nmod issue8551 {\n    trait Trait {}\n    struct Struct;\n    impl Trait for Struct {}\n\n    fn optmap(s: Option<&Struct>) -> Option<&dyn Trait> {\n        match s {\n            Some(s) => Some(s),\n            None => None,\n        }\n    }\n\n    fn lint_tests() {\n        let option: Option<&Struct> = None;\n        let _: Option<&dyn Trait> = match option {\n            Some(s) => Some(s),\n            None => None,\n        };\n\n        let _: Option<&dyn Trait> = if true {\n            match option {\n                Some(s) => Some(s),\n                None => None,\n            }\n        } else {\n            None\n        };\n\n        let result: Result<&Struct, i32> = Err(0);\n        let _: Result<&dyn Trait, i32> = match result {\n            Ok(s) => Ok(s),\n            Err(e) => Err(e),\n        };\n\n        let _: Option<&dyn Trait> = if let Some(s) = option { Some(s) } else { None };\n    }\n}\n\ntrait Tr {\n    fn as_mut(&mut self) -> Result<&mut i32, &mut i32>;\n}\nimpl Tr for Result<i32, i32> {\n    fn as_mut(&mut self) -> Result<&mut i32, &mut i32> {\n        match self {\n            Ok(x) => Ok(x),\n            Err(e) => Err(e),\n        }\n    }\n}\n\nmod issue9084 {\n    fn wildcard_if() {\n        let mut some_bool = true;\n        let e = Some(1);\n\n        // should lint\n        let _ = match e {\n            //~^ needless_match\n            _ if some_bool => e,\n            _ => e,\n        };\n\n        // should lint\n        let _ = match e {\n            //~^ needless_match\n            Some(i) => Some(i),\n            _ if some_bool => e,\n            _ => e,\n        };\n\n        // should not lint\n        let _ = match e {\n            _ if some_bool => e,\n            _ => Some(2),\n        };\n\n        // should not lint\n        let _ = match e {\n            Some(i) => Some(i + 1),\n            _ if some_bool => e,\n            _ => e,\n        };\n\n        // should not lint (guard has side effects)\n        let _ = match e {\n            Some(i) => Some(i),\n            _ if {\n                some_bool = false;\n                some_bool\n            } =>\n            {\n                e\n            },\n            _ => e,\n        };\n    }\n}\n\nfn a() -> Option<()> {\n    Some(())\n}\nfn b() -> Option<()> {\n    Some(())\n}\nfn c() -> Option<()> {\n    Some(())\n}\n\n#[allow(clippy::ifs_same_cond)]\npub fn issue13574() -> Option<()> {\n    // Do not lint.\n    // The right hand of all these arms are different functions.\n    let _ = {\n        if let Some(a) = a() {\n            Some(a)\n        } else if let Some(b) = b() {\n            Some(b)\n        } else if let Some(c) = c() {\n            Some(c)\n        } else {\n            None\n        }\n    };\n\n    const A: Option<()> = Some(());\n    const B: Option<()> = Some(());\n    const C: Option<()> = Some(());\n    const D: Option<()> = Some(());\n\n    let _ = {\n        if let Some(num) = A {\n            Some(num)\n        } else if let Some(num) = B {\n            Some(num)\n        } else if let Some(num) = C {\n            Some(num)\n        } else if let Some(num) = D {\n            Some(num)\n        } else {\n            None\n        }\n    };\n\n    // Same const, should lint\n    let _ = {\n        if let Some(num) = A {\n            //~^ needless_match\n            Some(num)\n        } else if let Some(num) = A {\n            Some(num)\n        } else if let Some(num) = A {\n            Some(num)\n        } else {\n            None\n        }\n    };\n\n    None\n}\n\nfn issue14754(t: Result<i32, &'static str>) -> Result<i32, &'static str> {\n    let _ = match t {\n        Ok(v) => Ok::<_, &'static str>(v),\n        err @ Err(_) => return err,\n    };\n    println!(\"Still here\");\n    let x = match t {\n        Ok(v) => Ok::<_, &'static str>(v),\n        err @ Err(_) => err,\n    };\n    //~^^^^ needless_match\n    println!(\"Still here\");\n    x\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_match.stderr",
    "content": "error: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:15:18\n   |\nLL |       let _: i32 = match i {\n   |  __________________^\nLL | |\nLL | |         0 => 0,\nLL | |         1 => 1,\nLL | |         2 => 2,\nLL | |         _ => i,\nLL | |     };\n   | |_____^ help: replace it with: `i`\n   |\n   = note: `-D clippy::needless-match` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_match)]`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:23:19\n   |\nLL |       let _: &str = match s {\n   |  ___________________^\nLL | |\nLL | |         \"a\" => \"a\",\nLL | |         \"b\" => \"b\",\nLL | |         s => s,\nLL | |     };\n   | |_____^ help: replace it with: `s`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:33:21\n   |\nLL |       let _: Simple = match se {\n   |  _____________________^\nLL | |\nLL | |         Simple::A => Simple::A,\nLL | |         Simple::B => Simple::B,\nLL | |         Simple::C => Simple::C,\nLL | |         Simple::D => Simple::D,\nLL | |     };\n   | |_____^ help: replace it with: `se`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:56:26\n   |\nLL |       let _: Option<i32> = match x {\n   |  __________________________^\nLL | |\nLL | |         Some(a) => Some(a),\nLL | |         None => None,\nLL | |     };\n   | |_____^ help: replace it with: `x`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:73:31\n   |\nLL |       let _: Result<i32, i32> = match Ok(1) {\n   |  _______________________________^\nLL | |\nLL | |         Ok(a) => Ok(a),\nLL | |         Err(err) => Err(err),\nLL | |     };\n   | |_____^ help: replace it with: `Ok(1)`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:78:31\n   |\nLL |       let _: Result<i32, i32> = match func_ret_err(0_i32) {\n   |  _______________________________^\nLL | |\nLL | |         Err(err) => Err(err),\nLL | |         Ok(a) => Ok(a),\nLL | |     };\n   | |_____^ help: replace it with: `func_ret_err(0_i32)`\n\nerror: this if-let expression is unnecessary\n  --> tests/ui/needless_match.rs:92:13\n   |\nLL |     let _ = if let Some(a) = Some(1) { Some(a) } else { None };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`\n\nerror: this if-let expression is unnecessary\n  --> tests/ui/needless_match.rs:128:31\n   |\nLL |     let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`\n\nerror: this if-let expression is unnecessary\n  --> tests/ui/needless_match.rs:130:31\n   |\nLL |     let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`\n\nerror: this if-let expression is unnecessary\n  --> tests/ui/needless_match.rs:138:21\n   |\nLL |       let _: Simple = if let Simple::A = x {\n   |  _____________________^\nLL | |\nLL | |         Simple::A\nLL | |     } else if let Simple::B = x {\n...  |\nLL | |         x\nLL | |     };\n   | |_____^ help: replace it with: `x`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:178:26\n   |\nLL |           let _: Complex = match ce {\n   |  __________________________^\nLL | |\nLL | |             Complex::A(a) => Complex::A(a),\nLL | |             Complex::B(a, b) => Complex::B(a, b),\n...  |\nLL | |             Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(ea, eb), b),\nLL | |         };\n   | |_________^ help: replace it with: `ce`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:263:17\n   |\nLL |           let _ = match e {\n   |  _________________^\nLL | |\nLL | |             _ if some_bool => e,\nLL | |             _ => e,\nLL | |         };\n   | |_________^ help: replace it with: `e`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:270:17\n   |\nLL |           let _ = match e {\n   |  _________________^\nLL | |\nLL | |             Some(i) => Some(i),\nLL | |             _ if some_bool => e,\nLL | |             _ => e,\nLL | |         };\n   | |_________^ help: replace it with: `e`\n\nerror: this if-let expression is unnecessary\n  --> tests/ui/needless_match.rs:352:9\n   |\nLL | /         if let Some(num) = A {\nLL | |\nLL | |             Some(num)\nLL | |         } else if let Some(num) = A {\n...  |\nLL | |             None\nLL | |         }\n   | |_________^ help: replace it with: `A`\n\nerror: this match expression is unnecessary\n  --> tests/ui/needless_match.rs:373:13\n   |\nLL |       let x = match t {\n   |  _____________^\nLL | |         Ok(v) => Ok::<_, &'static str>(v),\nLL | |         err @ Err(_) => err,\nLL | |     };\n   | |_____^ help: replace it with: `t`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_maybe_sized.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![allow(unused, clippy::multiple_bound_locations)]\n#![warn(clippy::needless_maybe_sized)]\n\nextern crate proc_macros;\nuse proc_macros::external;\n\nfn directly<T: Sized>(t: &T) {}\n//~^ needless_maybe_sized\n\ntrait A: Sized {}\ntrait B: A {}\n\nfn depth_1<T: A>(t: &T) {}\n//~^ needless_maybe_sized\nfn depth_2<T: B>(t: &T) {}\n//~^ needless_maybe_sized\n\n// We only need to show one\nfn multiple_paths<T: A + B>(t: &T) {}\n//~^ needless_maybe_sized\n\nfn in_where<T>(t: &T)\nwhere\n    T: Sized,\n    //~^ needless_maybe_sized\n{\n}\n\nfn mixed_1<T: Sized>(t: &T)\n    //~^ needless_maybe_sized\n{\n}\n\nfn mixed_2<T>(t: &T)\n//~^ needless_maybe_sized\nwhere\n    T: Sized,\n{\n}\n\nfn mixed_3<T>(t: &T)\nwhere\n    T: Sized,\n    //~^ needless_maybe_sized\n{\n}\n\nstruct Struct<T: Sized>(T);\n//~^ needless_maybe_sized\n\nimpl<T: Sized> Struct<T> {\n    //~^ needless_maybe_sized\n    fn method<U: Sized>(&self) {}\n    //~^ needless_maybe_sized\n}\n\nenum Enum<T: Sized + 'static> {\n    //~^ needless_maybe_sized\n    Variant(&'static T),\n}\n\nunion Union<'a, T: Sized> {\n    //~^ needless_maybe_sized\n    a: &'a T,\n}\n\ntrait Trait<T: Sized> {\n    //~^ needless_maybe_sized\n    fn trait_method<U: Sized>() {}\n    //~^ needless_maybe_sized\n\n    type GAT<U: Sized>;\n    //~^ needless_maybe_sized\n\n    type Assoc: Sized + ?Sized; // False negative\n}\n\ntrait SecondInTrait: Send + Sized {}\nfn second_in_trait<T: SecondInTrait>() {}\n//~^ needless_maybe_sized\n\nfn impl_trait(_: &(impl Sized)) {}\n//~^ needless_maybe_sized\n\ntrait GenericTrait<T>: Sized {}\nfn in_generic_trait<T: GenericTrait<U>, U>() {}\n//~^ needless_maybe_sized\n\nmod larger_graph {\n    // C1  C2  Sized\n    //  \\  /\\  /\n    //   B1  B2\n    //    \\  /\n    //     A1\n\n    trait C1 {}\n    trait C2 {}\n    trait B1: C1 + C2 {}\n    trait B2: C2 + Sized {}\n    trait A1: B1 + B2 {}\n\n    fn larger_graph<T: A1>() {}\n    //~^ needless_maybe_sized\n}\n\n// Should not lint\n\nfn sized<T: Sized>() {}\nfn maybe_sized<T: ?Sized>() {}\n\nstruct SeparateBounds<T: ?Sized>(T);\nimpl<T: Sized> SeparateBounds<T> {}\n\ntrait P {}\ntrait Q: P {}\n\nfn ok_depth_1<T: P + ?Sized>() {}\nfn ok_depth_2<T: Q + ?Sized>() {}\n\nexternal! {\n    fn in_macro<T: Clone + ?Sized>(t: &T) {}\n\n    fn with_local_clone<T: $Clone + ?Sized>(t: &T) {}\n}\n\n#[derive(Clone)]\nstruct InDerive<T: ?Sized> {\n    t: T,\n}\n\nstruct Refined<T: ?Sized>(T);\nimpl<T: Sized> Refined<T> {}\n\n// in proc-macros\nfn issue13360() {\n    #[derive(serde::Serialize)]\n    #[serde(bound = \"T: A\")]\n    struct Foo<T: ?Sized> {\n        t: std::marker::PhantomData<T>,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_maybe_sized.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![allow(unused, clippy::multiple_bound_locations)]\n#![warn(clippy::needless_maybe_sized)]\n\nextern crate proc_macros;\nuse proc_macros::external;\n\nfn directly<T: Sized + ?Sized>(t: &T) {}\n//~^ needless_maybe_sized\n\ntrait A: Sized {}\ntrait B: A {}\n\nfn depth_1<T: A + ?Sized>(t: &T) {}\n//~^ needless_maybe_sized\nfn depth_2<T: B + ?Sized>(t: &T) {}\n//~^ needless_maybe_sized\n\n// We only need to show one\nfn multiple_paths<T: A + B + ?Sized>(t: &T) {}\n//~^ needless_maybe_sized\n\nfn in_where<T>(t: &T)\nwhere\n    T: Sized + ?Sized,\n    //~^ needless_maybe_sized\n{\n}\n\nfn mixed_1<T: Sized>(t: &T)\nwhere\n    T: ?Sized,\n    //~^ needless_maybe_sized\n{\n}\n\nfn mixed_2<T: ?Sized>(t: &T)\n//~^ needless_maybe_sized\nwhere\n    T: Sized,\n{\n}\n\nfn mixed_3<T>(t: &T)\nwhere\n    T: Sized,\n    T: ?Sized,\n    //~^ needless_maybe_sized\n{\n}\n\nstruct Struct<T: Sized + ?Sized>(T);\n//~^ needless_maybe_sized\n\nimpl<T: Sized + ?Sized> Struct<T> {\n    //~^ needless_maybe_sized\n    fn method<U: Sized + ?Sized>(&self) {}\n    //~^ needless_maybe_sized\n}\n\nenum Enum<T: Sized + ?Sized + 'static> {\n    //~^ needless_maybe_sized\n    Variant(&'static T),\n}\n\nunion Union<'a, T: Sized + ?Sized> {\n    //~^ needless_maybe_sized\n    a: &'a T,\n}\n\ntrait Trait<T: Sized + ?Sized> {\n    //~^ needless_maybe_sized\n    fn trait_method<U: Sized + ?Sized>() {}\n    //~^ needless_maybe_sized\n\n    type GAT<U: Sized + ?Sized>;\n    //~^ needless_maybe_sized\n\n    type Assoc: Sized + ?Sized; // False negative\n}\n\ntrait SecondInTrait: Send + Sized {}\nfn second_in_trait<T: ?Sized + SecondInTrait>() {}\n//~^ needless_maybe_sized\n\nfn impl_trait(_: &(impl Sized + ?Sized)) {}\n//~^ needless_maybe_sized\n\ntrait GenericTrait<T>: Sized {}\nfn in_generic_trait<T: GenericTrait<U> + ?Sized, U>() {}\n//~^ needless_maybe_sized\n\nmod larger_graph {\n    // C1  C2  Sized\n    //  \\  /\\  /\n    //   B1  B2\n    //    \\  /\n    //     A1\n\n    trait C1 {}\n    trait C2 {}\n    trait B1: C1 + C2 {}\n    trait B2: C2 + Sized {}\n    trait A1: B1 + B2 {}\n\n    fn larger_graph<T: A1 + ?Sized>() {}\n    //~^ needless_maybe_sized\n}\n\n// Should not lint\n\nfn sized<T: Sized>() {}\nfn maybe_sized<T: ?Sized>() {}\n\nstruct SeparateBounds<T: ?Sized>(T);\nimpl<T: Sized> SeparateBounds<T> {}\n\ntrait P {}\ntrait Q: P {}\n\nfn ok_depth_1<T: P + ?Sized>() {}\nfn ok_depth_2<T: Q + ?Sized>() {}\n\nexternal! {\n    fn in_macro<T: Clone + ?Sized>(t: &T) {}\n\n    fn with_local_clone<T: $Clone + ?Sized>(t: &T) {}\n}\n\n#[derive(Clone)]\nstruct InDerive<T: ?Sized> {\n    t: T,\n}\n\nstruct Refined<T: ?Sized>(T);\nimpl<T: Sized> Refined<T> {}\n\n// in proc-macros\nfn issue13360() {\n    #[derive(serde::Serialize)]\n    #[serde(bound = \"T: A\")]\n    struct Foo<T: ?Sized> {\n        t: std::marker::PhantomData<T>,\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/needless_maybe_sized.stderr",
    "content": "error: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:9:24\n   |\nLL | fn directly<T: Sized + ?Sized>(t: &T) {}\n   |                        ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:9:16\n   |\nLL | fn directly<T: Sized + ?Sized>(t: &T) {}\n   |                ^^^^^\n   = note: `-D clippy::needless-maybe-sized` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_maybe_sized)]`\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - fn directly<T: Sized + ?Sized>(t: &T) {}\nLL + fn directly<T: Sized>(t: &T) {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:15:19\n   |\nLL | fn depth_1<T: A + ?Sized>(t: &T) {}\n   |                   ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:15:15\n   |\nLL | fn depth_1<T: A + ?Sized>(t: &T) {}\n   |               ^\n   = note: ...because `A` has the bound `Sized`\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - fn depth_1<T: A + ?Sized>(t: &T) {}\nLL + fn depth_1<T: A>(t: &T) {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:17:19\n   |\nLL | fn depth_2<T: B + ?Sized>(t: &T) {}\n   |                   ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:17:15\n   |\nLL | fn depth_2<T: B + ?Sized>(t: &T) {}\n   |               ^\n   = note: ...because `B` has the bound `A`\n   = note: ...because `A` has the bound `Sized`\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - fn depth_2<T: B + ?Sized>(t: &T) {}\nLL + fn depth_2<T: B>(t: &T) {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:21:30\n   |\nLL | fn multiple_paths<T: A + B + ?Sized>(t: &T) {}\n   |                              ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:21:22\n   |\nLL | fn multiple_paths<T: A + B + ?Sized>(t: &T) {}\n   |                      ^\n   = note: ...because `A` has the bound `Sized`\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - fn multiple_paths<T: A + B + ?Sized>(t: &T) {}\nLL + fn multiple_paths<T: A + B>(t: &T) {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:26:16\n   |\nLL |     T: Sized + ?Sized,\n   |                ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:26:8\n   |\nLL |     T: Sized + ?Sized,\n   |        ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL -     T: Sized + ?Sized,\nLL +     T: Sized,\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:33:8\n   |\nLL |     T: ?Sized,\n   |        ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:31:15\n   |\nLL | fn mixed_1<T: Sized>(t: &T)\n   |               ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - where\nLL -     T: ?Sized,\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:38:15\n   |\nLL | fn mixed_2<T: ?Sized>(t: &T)\n   |               ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:41:8\n   |\nLL |     T: Sized,\n   |        ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - fn mixed_2<T: ?Sized>(t: &T)\nLL + fn mixed_2<T>(t: &T)\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:48:8\n   |\nLL |     T: ?Sized,\n   |        ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:47:8\n   |\nLL |     T: Sized,\n   |        ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL -     T: Sized,\nLL -     T: ?Sized,\nLL +     T: Sized,\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:53:26\n   |\nLL | struct Struct<T: Sized + ?Sized>(T);\n   |                          ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:53:18\n   |\nLL | struct Struct<T: Sized + ?Sized>(T);\n   |                  ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - struct Struct<T: Sized + ?Sized>(T);\nLL + struct Struct<T: Sized>(T);\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:56:17\n   |\nLL | impl<T: Sized + ?Sized> Struct<T> {\n   |                 ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:56:9\n   |\nLL | impl<T: Sized + ?Sized> Struct<T> {\n   |         ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - impl<T: Sized + ?Sized> Struct<T> {\nLL + impl<T: Sized> Struct<T> {\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:58:26\n   |\nLL |     fn method<U: Sized + ?Sized>(&self) {}\n   |                          ^^^^^^\n   |\nnote: `U` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:58:18\n   |\nLL |     fn method<U: Sized + ?Sized>(&self) {}\n   |                  ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL -     fn method<U: Sized + ?Sized>(&self) {}\nLL +     fn method<U: Sized>(&self) {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:62:22\n   |\nLL | enum Enum<T: Sized + ?Sized + 'static> {\n   |                      ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:62:14\n   |\nLL | enum Enum<T: Sized + ?Sized + 'static> {\n   |              ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - enum Enum<T: Sized + ?Sized + 'static> {\nLL + enum Enum<T: Sized + 'static> {\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:67:28\n   |\nLL | union Union<'a, T: Sized + ?Sized> {\n   |                            ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:67:20\n   |\nLL | union Union<'a, T: Sized + ?Sized> {\n   |                    ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - union Union<'a, T: Sized + ?Sized> {\nLL + union Union<'a, T: Sized> {\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:72:24\n   |\nLL | trait Trait<T: Sized + ?Sized> {\n   |                        ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:72:16\n   |\nLL | trait Trait<T: Sized + ?Sized> {\n   |                ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - trait Trait<T: Sized + ?Sized> {\nLL + trait Trait<T: Sized> {\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:74:32\n   |\nLL |     fn trait_method<U: Sized + ?Sized>() {}\n   |                                ^^^^^^\n   |\nnote: `U` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:74:24\n   |\nLL |     fn trait_method<U: Sized + ?Sized>() {}\n   |                        ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL -     fn trait_method<U: Sized + ?Sized>() {}\nLL +     fn trait_method<U: Sized>() {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:77:25\n   |\nLL |     type GAT<U: Sized + ?Sized>;\n   |                         ^^^^^^\n   |\nnote: `U` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:77:17\n   |\nLL |     type GAT<U: Sized + ?Sized>;\n   |                 ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL -     type GAT<U: Sized + ?Sized>;\nLL +     type GAT<U: Sized>;\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:84:23\n   |\nLL | fn second_in_trait<T: ?Sized + SecondInTrait>() {}\n   |                       ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:84:32\n   |\nLL | fn second_in_trait<T: ?Sized + SecondInTrait>() {}\n   |                                ^^^^^^^^^^^^^\n   = note: ...because `SecondInTrait` has the bound `Sized`\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - fn second_in_trait<T: ?Sized + SecondInTrait>() {}\nLL + fn second_in_trait<T: SecondInTrait>() {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:87:33\n   |\nLL | fn impl_trait(_: &(impl Sized + ?Sized)) {}\n   |                                 ^^^^^^\n   |\nnote: `impl Sized + ?Sized` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:87:25\n   |\nLL | fn impl_trait(_: &(impl Sized + ?Sized)) {}\n   |                         ^^^^^\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - fn impl_trait(_: &(impl Sized + ?Sized)) {}\nLL + fn impl_trait(_: &(impl Sized)) {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:91:42\n   |\nLL | fn in_generic_trait<T: GenericTrait<U> + ?Sized, U>() {}\n   |                                          ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:91:24\n   |\nLL | fn in_generic_trait<T: GenericTrait<U> + ?Sized, U>() {}\n   |                        ^^^^^^^^^^^^^^^\n   = note: ...because `GenericTrait` has the bound `Sized`\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL - fn in_generic_trait<T: GenericTrait<U> + ?Sized, U>() {}\nLL + fn in_generic_trait<T: GenericTrait<U>, U>() {}\n   |\n\nerror: `?Sized` bound is ignored because of a `Sized` requirement\n  --> tests/ui/needless_maybe_sized.rs:107:29\n   |\nLL |     fn larger_graph<T: A1 + ?Sized>() {}\n   |                             ^^^^^^\n   |\nnote: `T` cannot be unsized because of the bound\n  --> tests/ui/needless_maybe_sized.rs:107:24\n   |\nLL |     fn larger_graph<T: A1 + ?Sized>() {}\n   |                        ^^\n   = note: ...because `A1` has the bound `B2`\n   = note: ...because `B2` has the bound `Sized`\nhelp: change the bounds that require `Sized`, or remove the `?Sized` bound\n   |\nLL -     fn larger_graph<T: A1 + ?Sized>() {}\nLL +     fn larger_graph<T: A1>() {}\n   |\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_option_as_deref.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::needless_option_as_deref)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    // should lint\n    let _: Option<&usize> = Some(&1);\n    //~^ needless_option_as_deref\n    let _: Option<&mut usize> = Some(&mut 1);\n    //~^ needless_option_as_deref\n\n    let mut y = 0;\n    let mut x = Some(&mut y);\n    let _ = x;\n    //~^ needless_option_as_deref\n\n    // should not lint\n    let _ = Some(Box::new(1)).as_deref();\n    let _ = Some(Box::new(1)).as_deref_mut();\n\n    let mut y = 0;\n    let mut x = Some(&mut y);\n    for _ in 0..3 {\n        let _ = x.as_deref_mut();\n    }\n\n    let mut y = 0;\n    let mut x = Some(&mut y);\n    let mut closure = || {\n        let _ = x.as_deref_mut();\n    };\n    closure();\n    closure();\n\n    // #7846\n    let mut i = 0;\n    let mut opt_vec = vec![Some(&mut i)];\n    opt_vec[0].as_deref_mut().unwrap();\n\n    let mut i = 0;\n    let x = &mut Some(&mut i);\n    (*x).as_deref_mut();\n\n    // #8047\n    let mut y = 0;\n    let mut x = Some(&mut y);\n    x.as_deref_mut();\n    dbg!(x);\n}\n\nstruct S<'a> {\n    opt: Option<&'a mut usize>,\n}\n\nfn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {\n    s.opt.as_deref_mut()\n}\n\nmod issue_non_copy_13077 {\n    pub fn something(mut maybe_side_effect: Option<&mut String>) {\n        for _ in 0..10 {\n            let _ = S {\n                field: other(maybe_side_effect.as_deref_mut()),\n            };\n        }\n    }\n\n    fn other(_maybe_side_effect: Option<&mut String>) {\n        unimplemented!()\n    }\n\n    pub struct S {\n        pub field: (),\n    }\n}\n\nmod issue14148 {\n    pub trait SomeTrait {\n        fn something(&self, mut maybe_side_effect: Option<&mut String>) {\n            other(maybe_side_effect.as_deref_mut());\n            other(maybe_side_effect);\n        }\n    }\n\n    fn other(_maybe_side_effect: Option<&mut String>) {\n        unimplemented!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_option_as_deref.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::needless_option_as_deref)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    // should lint\n    let _: Option<&usize> = Some(&1).as_deref();\n    //~^ needless_option_as_deref\n    let _: Option<&mut usize> = Some(&mut 1).as_deref_mut();\n    //~^ needless_option_as_deref\n\n    let mut y = 0;\n    let mut x = Some(&mut y);\n    let _ = x.as_deref_mut();\n    //~^ needless_option_as_deref\n\n    // should not lint\n    let _ = Some(Box::new(1)).as_deref();\n    let _ = Some(Box::new(1)).as_deref_mut();\n\n    let mut y = 0;\n    let mut x = Some(&mut y);\n    for _ in 0..3 {\n        let _ = x.as_deref_mut();\n    }\n\n    let mut y = 0;\n    let mut x = Some(&mut y);\n    let mut closure = || {\n        let _ = x.as_deref_mut();\n    };\n    closure();\n    closure();\n\n    // #7846\n    let mut i = 0;\n    let mut opt_vec = vec![Some(&mut i)];\n    opt_vec[0].as_deref_mut().unwrap();\n\n    let mut i = 0;\n    let x = &mut Some(&mut i);\n    (*x).as_deref_mut();\n\n    // #8047\n    let mut y = 0;\n    let mut x = Some(&mut y);\n    x.as_deref_mut();\n    dbg!(x);\n}\n\nstruct S<'a> {\n    opt: Option<&'a mut usize>,\n}\n\nfn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {\n    s.opt.as_deref_mut()\n}\n\nmod issue_non_copy_13077 {\n    pub fn something(mut maybe_side_effect: Option<&mut String>) {\n        for _ in 0..10 {\n            let _ = S {\n                field: other(maybe_side_effect.as_deref_mut()),\n            };\n        }\n    }\n\n    fn other(_maybe_side_effect: Option<&mut String>) {\n        unimplemented!()\n    }\n\n    pub struct S {\n        pub field: (),\n    }\n}\n\nmod issue14148 {\n    pub trait SomeTrait {\n        fn something(&self, mut maybe_side_effect: Option<&mut String>) {\n            other(maybe_side_effect.as_deref_mut());\n            other(maybe_side_effect);\n        }\n    }\n\n    fn other(_maybe_side_effect: Option<&mut String>) {\n        unimplemented!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_option_as_deref.stderr",
    "content": "error: derefed type is same as origin\n  --> tests/ui/needless_option_as_deref.rs:7:29\n   |\nLL |     let _: Option<&usize> = Some(&1).as_deref();\n   |                             ^^^^^^^^^^^^^^^^^^^ help: try: `Some(&1)`\n   |\n   = note: `-D clippy::needless-option-as-deref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_option_as_deref)]`\n\nerror: derefed type is same as origin\n  --> tests/ui/needless_option_as_deref.rs:9:33\n   |\nLL |     let _: Option<&mut usize> = Some(&mut 1).as_deref_mut();\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&mut 1)`\n\nerror: derefed type is same as origin\n  --> tests/ui/needless_option_as_deref.rs:14:13\n   |\nLL |     let _ = x.as_deref_mut();\n   |             ^^^^^^^^^^^^^^^^ help: try: `x`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_option_take.fixed",
    "content": "struct MyStruct;\n\nimpl MyStruct {\n    pub fn get_option() -> Option<Self> {\n        todo!()\n    }\n}\n\nfn return_option() -> Option<i32> {\n    todo!()\n}\n\nfn main() {\n    println!(\"Testing non erroneous option_take_on_temporary\");\n    let mut option = Some(1);\n    let _ = Box::new(move || option.take().unwrap());\n\n    println!(\"Testing non erroneous option_take_on_temporary\");\n    let x = Some(3);\n    x.as_ref();\n\n    let x = Some(3);\n    x.as_ref();\n    //~^ needless_option_take\n\n    println!(\"Testing non erroneous option_take_on_temporary\");\n    let mut x = Some(3);\n    let y = x.as_mut();\n\n    let mut x = Some(3);\n    let y = x.as_mut();\n    //~^ needless_option_take\n\n    let y = x.replace(289);\n    //~^ needless_option_take\n\n    let y = Some(3).as_mut();\n    //~^ needless_option_take\n\n    let y = Option::as_mut(&mut x);\n    //~^ needless_option_take\n\n    let x = return_option();\n    let x = return_option();\n    //~^ needless_option_take\n\n    let x = MyStruct::get_option();\n    let x = MyStruct::get_option();\n    //~^ needless_option_take\n\n    let mut my_vec = vec![1, 2, 3];\n    my_vec.push(4);\n    let y = my_vec.first();\n    let y = my_vec.first();\n    //~^ needless_option_take\n\n    let y = my_vec.first();\n    //~^ needless_option_take\n}\n"
  },
  {
    "path": "tests/ui/needless_option_take.rs",
    "content": "struct MyStruct;\n\nimpl MyStruct {\n    pub fn get_option() -> Option<Self> {\n        todo!()\n    }\n}\n\nfn return_option() -> Option<i32> {\n    todo!()\n}\n\nfn main() {\n    println!(\"Testing non erroneous option_take_on_temporary\");\n    let mut option = Some(1);\n    let _ = Box::new(move || option.take().unwrap());\n\n    println!(\"Testing non erroneous option_take_on_temporary\");\n    let x = Some(3);\n    x.as_ref();\n\n    let x = Some(3);\n    x.as_ref().take();\n    //~^ needless_option_take\n\n    println!(\"Testing non erroneous option_take_on_temporary\");\n    let mut x = Some(3);\n    let y = x.as_mut();\n\n    let mut x = Some(3);\n    let y = x.as_mut().take();\n    //~^ needless_option_take\n\n    let y = x.replace(289).take();\n    //~^ needless_option_take\n\n    let y = Some(3).as_mut().take();\n    //~^ needless_option_take\n\n    let y = Option::as_mut(&mut x).take();\n    //~^ needless_option_take\n\n    let x = return_option();\n    let x = return_option().take();\n    //~^ needless_option_take\n\n    let x = MyStruct::get_option();\n    let x = MyStruct::get_option().take();\n    //~^ needless_option_take\n\n    let mut my_vec = vec![1, 2, 3];\n    my_vec.push(4);\n    let y = my_vec.first();\n    let y = my_vec.first().take();\n    //~^ needless_option_take\n\n    let y = my_vec.first().take();\n    //~^ needless_option_take\n}\n"
  },
  {
    "path": "tests/ui/needless_option_take.stderr",
    "content": "error: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:23:5\n   |\nLL |     x.as_ref().take();\n   |     ^^^^^^^^^^-------\n   |               |\n   |               help: remove\n   |\n   = note: `as_ref` creates a temporary value, so calling take() has no effect\n   = note: `-D clippy::needless-option-take` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_option_take)]`\n\nerror: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:31:13\n   |\nLL |     let y = x.as_mut().take();\n   |             ^^^^^^^^^^-------\n   |                       |\n   |                       help: remove\n   |\n   = note: `as_mut` creates a temporary value, so calling take() has no effect\n\nerror: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:34:13\n   |\nLL |     let y = x.replace(289).take();\n   |             ^^^^^^^^^^^^^^-------\n   |                           |\n   |                           help: remove\n   |\n   = note: `replace` creates a temporary value, so calling take() has no effect\n\nerror: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:37:13\n   |\nLL |     let y = Some(3).as_mut().take();\n   |             ^^^^^^^^^^^^^^^^-------\n   |                             |\n   |                             help: remove\n   |\n   = note: `as_mut` creates a temporary value, so calling take() has no effect\n\nerror: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:40:13\n   |\nLL |     let y = Option::as_mut(&mut x).take();\n   |             ^^^^^^^^^^^^^^^^^^^^^^-------\n   |                                   |\n   |                                   help: remove\n   |\n   = note: `as_mut` creates a temporary value, so calling take() has no effect\n\nerror: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:44:13\n   |\nLL |     let x = return_option().take();\n   |             ^^^^^^^^^^^^^^^-------\n   |                            |\n   |                            help: remove\n   |\n   = note: `return_option` creates a temporary value, so calling take() has no effect\n\nerror: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:48:13\n   |\nLL |     let x = MyStruct::get_option().take();\n   |             ^^^^^^^^^^^^^^^^^^^^^^-------\n   |                                   |\n   |                                   help: remove\n   |\n   = note: `get_option` creates a temporary value, so calling take() has no effect\n\nerror: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:54:13\n   |\nLL |     let y = my_vec.first().take();\n   |             ^^^^^^^^^^^^^^-------\n   |                           |\n   |                           help: remove\n   |\n   = note: `first` creates a temporary value, so calling take() has no effect\n\nerror: called `Option::take()` on a temporary value\n  --> tests/ui/needless_option_take.rs:57:13\n   |\nLL |     let y = my_vec.first().take();\n   |             ^^^^^^^^^^^^^^-------\n   |                           |\n   |                           help: remove\n   |\n   = note: `first` creates a temporary value, so calling take() has no effect\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_parens_on_range_literals.fixed",
    "content": "//@edition:2018\n\n#![warn(clippy::needless_parens_on_range_literals)]\n#![allow(clippy::almost_complete_range)]\n\nfn main() {\n    let _ = 'a'..='z';\n    //~^ needless_parens_on_range_literals\n    //~| needless_parens_on_range_literals\n    let _ = 'a'..'z';\n    //~^ needless_parens_on_range_literals\n    let _ = (1.)..2.;\n    let _ = (1.)..2.;\n    //~^ needless_parens_on_range_literals\n    let _ = 'a'..;\n    //~^ needless_parens_on_range_literals\n    let _ = ..'z';\n    //~^ needless_parens_on_range_literals\n}\n"
  },
  {
    "path": "tests/ui/needless_parens_on_range_literals.rs",
    "content": "//@edition:2018\n\n#![warn(clippy::needless_parens_on_range_literals)]\n#![allow(clippy::almost_complete_range)]\n\nfn main() {\n    let _ = ('a')..=('z');\n    //~^ needless_parens_on_range_literals\n    //~| needless_parens_on_range_literals\n    let _ = 'a'..('z');\n    //~^ needless_parens_on_range_literals\n    let _ = (1.)..2.;\n    let _ = (1.)..(2.);\n    //~^ needless_parens_on_range_literals\n    let _ = ('a')..;\n    //~^ needless_parens_on_range_literals\n    let _ = ..('z');\n    //~^ needless_parens_on_range_literals\n}\n"
  },
  {
    "path": "tests/ui/needless_parens_on_range_literals.stderr",
    "content": "error: needless parenthesis on range literals can be removed\n  --> tests/ui/needless_parens_on_range_literals.rs:7:13\n   |\nLL |     let _ = ('a')..=('z');\n   |             ^^^^^ help: try: `'a'`\n   |\n   = note: `-D clippy::needless-parens-on-range-literals` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_parens_on_range_literals)]`\n\nerror: needless parenthesis on range literals can be removed\n  --> tests/ui/needless_parens_on_range_literals.rs:7:21\n   |\nLL |     let _ = ('a')..=('z');\n   |                     ^^^^^ help: try: `'z'`\n\nerror: needless parenthesis on range literals can be removed\n  --> tests/ui/needless_parens_on_range_literals.rs:10:18\n   |\nLL |     let _ = 'a'..('z');\n   |                  ^^^^^ help: try: `'z'`\n\nerror: needless parenthesis on range literals can be removed\n  --> tests/ui/needless_parens_on_range_literals.rs:13:19\n   |\nLL |     let _ = (1.)..(2.);\n   |                   ^^^^ help: try: `2.`\n\nerror: needless parenthesis on range literals can be removed\n  --> tests/ui/needless_parens_on_range_literals.rs:15:13\n   |\nLL |     let _ = ('a')..;\n   |             ^^^^^ help: try: `'a'`\n\nerror: needless parenthesis on range literals can be removed\n  --> tests/ui/needless_parens_on_range_literals.rs:17:15\n   |\nLL |     let _ = ..('z');\n   |               ^^^^^ help: try: `'z'`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_pass_by_ref_mut.rs",
    "content": "#![allow(\n    clippy::if_same_then_else,\n    clippy::no_effect,\n    clippy::ptr_arg,\n    clippy::redundant_closure_call,\n    clippy::uninlined_format_args\n)]\n#![warn(clippy::needless_pass_by_ref_mut)]\n//@no-rustfix\nuse std::ptr::NonNull;\n\nfn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {\n    //~^ needless_pass_by_ref_mut\n\n    *x += *b + s.len() as u32;\n}\n\n// Should not warn.\nfn foo2(s: &mut Vec<u32>) {\n    s.push(8);\n}\n\n// Should not warn because we return it.\nfn foo3(s: &mut Vec<u32>) -> &mut Vec<u32> {\n    s\n}\n\n// Should not warn because `s` is used as mutable.\nfn foo4(s: &mut Vec<u32>) {\n    Vec::push(s, 4);\n}\n\n// Should not warn.\nfn foo5(s: &mut Vec<u32>) {\n    foo2(s);\n}\n\nfn foo6(s: &mut Vec<u32>) {\n    //~^ needless_pass_by_ref_mut\n\n    non_mut_ref(s);\n}\n\nfn non_mut_ref(_: &Vec<u32>) {}\n\nstruct Bar;\n\nimpl Bar {\n    fn bar(&mut self) {}\n    //~^ needless_pass_by_ref_mut\n\n    fn mushroom(&self, vec: &mut Vec<i32>) -> usize {\n        //~^ needless_pass_by_ref_mut\n\n        vec.len()\n    }\n}\n\ntrait Babar {\n    // Should not warn here since it's a trait method.\n    fn method(arg: &mut u32);\n}\n\nimpl Babar for Bar {\n    // Should not warn here since it's a trait method.\n    fn method(a: &mut u32) {}\n}\n\n// Should not warn (checking variable aliasing).\nfn alias_check(s: &mut Vec<u32>) {\n    let mut alias = s;\n    let mut alias2 = alias;\n    let mut alias3 = alias2;\n    alias3.push(0);\n}\n\n// Should not warn (checking variable aliasing).\nfn alias_check2(mut s: &mut Vec<u32>) {\n    let mut alias = &mut s;\n    alias.push(0);\n}\n\nstruct Mut<T> {\n    ptr: NonNull<T>,\n}\n\nimpl<T> Mut<T> {\n    // Should not warn because `NonNull::from` also accepts `&mut`.\n    fn new(ptr: &mut T) -> Self {\n        Mut {\n            ptr: NonNull::from(ptr),\n        }\n    }\n}\n\n// Should not warn.\nfn unused(_: &mut u32, _b: &mut u8) {}\n\n// Should not warn.\nasync fn f1(x: &mut i32) {\n    *x += 1;\n}\n// Should not warn.\nasync fn f2(x: &mut i32, y: String) {\n    *x += 1;\n}\n// Should not warn.\nasync fn f3(x: &mut i32, y: String, z: String) {\n    *x += 1;\n}\n// Should not warn.\nasync fn f4(x: &mut i32, y: i32) {\n    *x += 1;\n}\n// Should not warn.\nasync fn f5(x: i32, y: &mut i32) {\n    *y += 1;\n}\n// Should not warn.\nasync fn f6(x: i32, y: &mut i32, z: &mut i32) {\n    *y += 1;\n    *z += 1;\n}\n// Should not warn.\nasync fn f7(x: &mut i32, y: i32, z: &mut i32, a: i32) {\n    *x += 1;\n    *z += 1;\n}\n\nasync fn a1(x: &mut i32) {\n    //~^ needless_pass_by_ref_mut\n\n    println!(\"{:?}\", x);\n}\nasync fn a2(x: &mut i32, y: String) {\n    //~^ needless_pass_by_ref_mut\n\n    println!(\"{:?}\", x);\n}\nasync fn a3(x: &mut i32, y: String, z: String) {\n    //~^ needless_pass_by_ref_mut\n\n    println!(\"{:?}\", x);\n}\nasync fn a4(x: &mut i32, y: i32) {\n    //~^ needless_pass_by_ref_mut\n\n    println!(\"{:?}\", x);\n}\nasync fn a5(x: i32, y: &mut i32) {\n    //~^ needless_pass_by_ref_mut\n\n    println!(\"{:?}\", x);\n}\nasync fn a6(x: i32, y: &mut i32) {\n    //~^ needless_pass_by_ref_mut\n\n    println!(\"{:?}\", x);\n}\nasync fn a7(x: i32, y: i32, z: &mut i32) {\n    //~^ needless_pass_by_ref_mut\n\n    println!(\"{:?}\", z);\n}\nasync fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {\n    //~^ needless_pass_by_ref_mut\n    //~| needless_pass_by_ref_mut\n\n    println!(\"{:?}\", z);\n}\n\n// Should not warn (passed as closure which takes `&mut`).\nfn passed_as_closure(s: &mut u32) {}\n\n// Should not warn.\nfn passed_as_local(s: &mut u32) {}\n\n// Should not warn.\nfn ty_unify_1(s: &mut u32) {}\n\n// Should not warn.\nfn ty_unify_2(s: &mut u32) {}\n\n// Should not warn.\nfn passed_as_field(s: &mut u32) {}\n\nfn closure_takes_mut(s: fn(&mut u32)) {}\n\nstruct A {\n    s: fn(&mut u32),\n}\n\n// Should warn.\nfn used_as_path(s: &mut u32) {}\n\n// Make sure lint attributes work fine\n#[expect(clippy::needless_pass_by_ref_mut)]\nfn lint_attr(s: &mut u32) {}\n\n#[cfg(not(feature = \"a\"))]\nfn cfg_warn(s: &mut u32) {}\n//~^ needless_pass_by_ref_mut\n\n#[cfg(not(feature = \"a\"))]\nmod foo {\n    fn cfg_warn(s: &mut u32) {}\n    //~^ needless_pass_by_ref_mut\n}\n\n// Should not warn.\nasync fn inner_async(x: &mut i32, y: &mut u32) {\n    async {\n        *y += 1;\n        *x += 1;\n    }\n    .await;\n}\n\nasync fn inner_async2(x: &mut i32, y: &mut u32) {\n    //~^ needless_pass_by_ref_mut\n\n    async {\n        *x += 1;\n    }\n    .await;\n}\n\nasync fn inner_async3(x: &mut i32, y: &mut u32) {\n    //~^ needless_pass_by_ref_mut\n\n    async {\n        *y += 1;\n    }\n    .await;\n}\n\n// Should not warn.\nasync fn async_vec(b: &mut Vec<bool>) {\n    b.append(&mut vec![]);\n}\n\n// Should not warn.\nasync fn async_vec2(b: &mut Vec<bool>) {\n    b.push(true);\n}\nfn non_mut(n: &str) {}\n//Should warn\nasync fn call_in_closure1(n: &mut str) {\n    //~^ needless_pass_by_ref_mut\n    (|| non_mut(n))()\n}\nfn str_mut(str: &mut String) -> bool {\n    str.pop().is_some()\n}\n//Should not warn\nasync fn call_in_closure2(str: &mut String) {\n    (|| str_mut(str))();\n}\n\n// Should not warn.\nasync fn closure(n: &mut usize) -> impl '_ + FnMut() {\n    || {\n        *n += 1;\n    }\n}\n\n// Should warn.\nfn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {\n    //~^ needless_pass_by_ref_mut\n\n    || *n + 1\n}\n\n// Should not warn.\nasync fn closure3(n: &mut usize) {\n    (|| *n += 1)();\n}\n\n// Should warn.\nasync fn closure4(n: &mut usize) {\n    //~^ needless_pass_by_ref_mut\n\n    (|| {\n        let _x = *n + 1;\n    })();\n}\n\n// Should not warn: pub\npub fn pub_foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {\n    *x += *b + s.len() as u32;\n}\n\n// Should not warn.\nasync fn _f(v: &mut Vec<()>) {\n    let x = || v.pop();\n    _ = || || x;\n}\n\nstruct Data<T: ?Sized> {\n    value: T,\n}\n// Unsafe functions should not warn.\nunsafe fn get_mut_unchecked<T>(ptr: &mut NonNull<Data<T>>) -> &mut T {\n    unsafe { &mut (*ptr.as_ptr()).value }\n}\n// Unsafe blocks should not warn.\nfn get_mut_unchecked2<T>(ptr: &mut NonNull<Data<T>>) -> &mut T {\n    unsafe { &mut (*ptr.as_ptr()).value }\n}\n\nfn set_true(b: &mut bool) {\n    *b = true;\n}\n\n// Should not warn.\nfn true_setter(b: &mut bool) -> impl FnOnce() + '_ {\n    move || set_true(b)\n}\n\n// Should not warn.\nfn filter_copy<T: Copy>(predicate: &mut impl FnMut(T) -> bool) -> impl FnMut(&T) -> bool + '_ {\n    move |&item| predicate(item)\n}\n\ntrait MutSelfTrait {\n    // Should not warn since it's a trait method.\n    fn mut_self(&mut self);\n}\n\nstruct MutSelf {\n    a: u32,\n}\n\nimpl MutSelf {\n    fn bar(&mut self) {}\n    //~^ needless_pass_by_ref_mut\n\n    async fn foo(&mut self, u: &mut i32, v: &mut u32) {\n        //~^ needless_pass_by_ref_mut\n        //~| needless_pass_by_ref_mut\n\n        async {\n            *u += 1;\n        }\n        .await;\n    }\n    async fn foo2(&mut self, u: &mut i32, v: &mut u32) {\n        //~^ needless_pass_by_ref_mut\n\n        async {\n            self.a += 1;\n            *u += 1;\n        }\n        .await;\n    }\n}\n\nimpl MutSelfTrait for MutSelf {\n    // Should not warn since it's a trait method.\n    fn mut_self(&mut self) {}\n}\n\n// `is_from_proc_macro` stress tests\nfn _empty_tup(x: &mut (())) {}\n//~^ needless_pass_by_ref_mut\nfn _single_tup(x: &mut ((i32,))) {}\n//~^ needless_pass_by_ref_mut\nfn _multi_tup(x: &mut ((i32, u32))) {}\n//~^ needless_pass_by_ref_mut\nfn _fn(x: &mut (fn())) {}\n//~^ needless_pass_by_ref_mut\n#[rustfmt::skip]\nfn _extern_rust_fn(x: &mut extern \"Rust\" fn()) {}\n//~^ needless_pass_by_ref_mut\nfn _extern_c_fn(x: &mut extern \"C\" fn()) {}\n//~^ needless_pass_by_ref_mut\nfn _unsafe_fn(x: &mut unsafe fn()) {}\n//~^ needless_pass_by_ref_mut\nfn _unsafe_extern_fn(x: &mut unsafe extern \"C\" fn()) {}\n//~^ needless_pass_by_ref_mut\nfn _fn_with_arg(x: &mut unsafe extern \"C\" fn(i32)) {}\n//~^ needless_pass_by_ref_mut\nfn _fn_with_ret(x: &mut unsafe extern \"C\" fn() -> (i32)) {}\n//~^ needless_pass_by_ref_mut\n\nfn main() {\n    let mut u = 0;\n    let mut v = vec![0];\n    foo(&mut v, &0, &mut u);\n    foo2(&mut v);\n    foo3(&mut v);\n    foo4(&mut v);\n    foo5(&mut v);\n    alias_check(&mut v);\n    alias_check2(&mut v);\n    println!(\"{u}\");\n    closure_takes_mut(passed_as_closure);\n    A { s: passed_as_field };\n    used_as_path;\n    let _: fn(&mut u32) = passed_as_local;\n    let _ = if v[0] == 0 { ty_unify_1 } else { ty_unify_2 };\n    pub_foo(&mut v, &0, &mut u);\n}\n"
  },
  {
    "path": "tests/ui/needless_pass_by_ref_mut.stderr",
    "content": "error: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:12:11\n   |\nLL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {\n   |           ^----^^^^^^^^\n   |            |\n   |            help: consider removing this `mut`\n   |\n   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:38:12\n   |\nLL | fn foo6(s: &mut Vec<u32>) {\n   |            ^----^^^^^^^^\n   |             |\n   |             help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:49:12\n   |\nLL |     fn bar(&mut self) {}\n   |            ^----^^^^\n   |             |\n   |             help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:52:29\n   |\nLL |     fn mushroom(&self, vec: &mut Vec<i32>) -> usize {\n   |                             ^----^^^^^^^^\n   |                              |\n   |                              help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:130:16\n   |\nLL | async fn a1(x: &mut i32) {\n   |                ^----^^^\n   |                 |\n   |                 help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:135:16\n   |\nLL | async fn a2(x: &mut i32, y: String) {\n   |                ^----^^^\n   |                 |\n   |                 help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:140:16\n   |\nLL | async fn a3(x: &mut i32, y: String, z: String) {\n   |                ^----^^^\n   |                 |\n   |                 help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:145:16\n   |\nLL | async fn a4(x: &mut i32, y: i32) {\n   |                ^----^^^\n   |                 |\n   |                 help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:150:24\n   |\nLL | async fn a5(x: i32, y: &mut i32) {\n   |                        ^----^^^\n   |                         |\n   |                         help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:155:24\n   |\nLL | async fn a6(x: i32, y: &mut i32) {\n   |                        ^----^^^\n   |                         |\n   |                         help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:160:32\n   |\nLL | async fn a7(x: i32, y: i32, z: &mut i32) {\n   |                                ^----^^^\n   |                                 |\n   |                                 help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:165:24\n   |\nLL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {\n   |                        ^----^^^\n   |                         |\n   |                         help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:165:45\n   |\nLL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {\n   |                                             ^----^^^\n   |                                              |\n   |                                              help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:201:16\n   |\nLL | fn cfg_warn(s: &mut u32) {}\n   |                ^----^^^\n   |                 |\n   |                 help: consider removing this `mut`\n   |\n   = note: this is cfg-gated and may require further changes\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:206:20\n   |\nLL |     fn cfg_warn(s: &mut u32) {}\n   |                    ^----^^^\n   |                     |\n   |                     help: consider removing this `mut`\n   |\n   = note: this is cfg-gated and may require further changes\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:219:39\n   |\nLL | async fn inner_async2(x: &mut i32, y: &mut u32) {\n   |                                       ^----^^^\n   |                                        |\n   |                                        help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:228:26\n   |\nLL | async fn inner_async3(x: &mut i32, y: &mut u32) {\n   |                          ^----^^^\n   |                           |\n   |                           help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:248:30\n   |\nLL | async fn call_in_closure1(n: &mut str) {\n   |                              ^----^^^\n   |                               |\n   |                               help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:268:16\n   |\nLL | fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {\n   |                ^----^^^^^\n   |                 |\n   |                 help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:280:22\n   |\nLL | async fn closure4(n: &mut usize) {\n   |                      ^----^^^^^\n   |                       |\n   |                       help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:335:12\n   |\nLL |     fn bar(&mut self) {}\n   |            ^----^^^^\n   |             |\n   |             help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:338:18\n   |\nLL |     async fn foo(&mut self, u: &mut i32, v: &mut u32) {\n   |                  ^----^^^^\n   |                   |\n   |                   help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:338:45\n   |\nLL |     async fn foo(&mut self, u: &mut i32, v: &mut u32) {\n   |                                             ^----^^^\n   |                                              |\n   |                                              help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:347:46\n   |\nLL |     async fn foo2(&mut self, u: &mut i32, v: &mut u32) {\n   |                                              ^----^^^\n   |                                               |\n   |                                               help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:364:18\n   |\nLL | fn _empty_tup(x: &mut (())) {}\n   |                  ^^----^^^\n   |                    |\n   |                    help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:366:19\n   |\nLL | fn _single_tup(x: &mut ((i32,))) {}\n   |                   ^^----^^^^^^^\n   |                     |\n   |                     help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:368:18\n   |\nLL | fn _multi_tup(x: &mut ((i32, u32))) {}\n   |                  ^^----^^^^^^^^^^^\n   |                    |\n   |                    help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:370:11\n   |\nLL | fn _fn(x: &mut (fn())) {}\n   |           ^^----^^^^^\n   |             |\n   |             help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:373:23\n   |\nLL | fn _extern_rust_fn(x: &mut extern \"Rust\" fn()) {}\n   |                       ^----^^^^^^^^^^^^^^^^^^\n   |                        |\n   |                        help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:375:20\n   |\nLL | fn _extern_c_fn(x: &mut extern \"C\" fn()) {}\n   |                    ^----^^^^^^^^^^^^^^^\n   |                     |\n   |                     help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:377:18\n   |\nLL | fn _unsafe_fn(x: &mut unsafe fn()) {}\n   |                  ^----^^^^^^^^^^^\n   |                   |\n   |                   help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:379:25\n   |\nLL | fn _unsafe_extern_fn(x: &mut unsafe extern \"C\" fn()) {}\n   |                         ^----^^^^^^^^^^^^^^^^^^^^^^\n   |                          |\n   |                          help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:381:20\n   |\nLL | fn _fn_with_arg(x: &mut unsafe extern \"C\" fn(i32)) {}\n   |                    ^----^^^^^^^^^^^^^^^^^^^^^^^^^\n   |                     |\n   |                     help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut.rs:383:20\n   |\nLL | fn _fn_with_ret(x: &mut unsafe extern \"C\" fn() -> (i32)) {}\n   |                    ^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |                     |\n   |                     help: consider removing this `mut`\n\nerror: aborting due to 34 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_pass_by_ref_mut2.fixed",
    "content": "// If both `inner_async3` and `inner_async4` are present, aliases are declared after\n// they're used in `inner_async4` for some reasons... This test ensures that no\n// only `v` is marked as not used mutably in `inner_async4`.\n\n#![allow(clippy::redundant_closure_call)]\n#![warn(clippy::needless_pass_by_ref_mut)]\n\nasync fn inner_async3(x: &i32, y: &mut u32) {\n    //~^ needless_pass_by_ref_mut\n\n    async {\n        *y += 1;\n    }\n    .await;\n}\n\nasync fn inner_async4(u: &mut i32, v: &u32) {\n    //~^ needless_pass_by_ref_mut\n\n    async {\n        *u += 1;\n    }\n    .await;\n}\n\nfn main() {}\n\n//~v needless_pass_by_ref_mut\nfn issue16267<'a>(msg: &str, slice: &'a [i32]) -> &'a [i32] {\n    println!(\"{msg}\");\n    &slice[0..5]\n}\n"
  },
  {
    "path": "tests/ui/needless_pass_by_ref_mut2.rs",
    "content": "// If both `inner_async3` and `inner_async4` are present, aliases are declared after\n// they're used in `inner_async4` for some reasons... This test ensures that no\n// only `v` is marked as not used mutably in `inner_async4`.\n\n#![allow(clippy::redundant_closure_call)]\n#![warn(clippy::needless_pass_by_ref_mut)]\n\nasync fn inner_async3(x: &mut i32, y: &mut u32) {\n    //~^ needless_pass_by_ref_mut\n\n    async {\n        *y += 1;\n    }\n    .await;\n}\n\nasync fn inner_async4(u: &mut i32, v: &mut u32) {\n    //~^ needless_pass_by_ref_mut\n\n    async {\n        *u += 1;\n    }\n    .await;\n}\n\nfn main() {}\n\n//~v needless_pass_by_ref_mut\nfn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] {\n    println!(\"{msg}\");\n    &slice[0..5]\n}\n"
  },
  {
    "path": "tests/ui/needless_pass_by_ref_mut2.stderr",
    "content": "error: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut2.rs:8:26\n   |\nLL | async fn inner_async3(x: &mut i32, y: &mut u32) {\n   |                          ^----^^^\n   |                           |\n   |                           help: consider removing this `mut`\n   |\n   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut2.rs:17:39\n   |\nLL | async fn inner_async4(u: &mut i32, v: &mut u32) {\n   |                                       ^----^^^\n   |                                        |\n   |                                        help: consider removing this `mut`\n\nerror: this parameter is a mutable reference but is not used mutably\n  --> tests/ui/needless_pass_by_ref_mut2.rs:29:37\n   |\nLL | fn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] {\n   |                                     ^^^^----^^^^^\n   |                                         |\n   |                                         help: consider removing this `mut`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_pass_by_ref_mut_2021.rs",
    "content": "//@edition: 2021\n//@check-pass\n#![warn(clippy::needless_pass_by_ref_mut)]\n\nstruct Data<T: ?Sized> {\n    value: T,\n}\n\n// Unsafe functions should not warn.\nunsafe fn get_mut_unchecked<T>(ptr: &mut std::ptr::NonNull<Data<T>>) -> &mut T {\n    &mut (*ptr.as_ptr()).value\n}\n"
  },
  {
    "path": "tests/ui/needless_pass_by_value.rs",
    "content": "#![warn(clippy::needless_pass_by_value)]\n#![allow(dead_code)]\n#![allow(\n    clippy::option_option,\n    clippy::redundant_clone,\n    clippy::redundant_pattern_matching,\n    clippy::single_match,\n    clippy::uninlined_format_args,\n    clippy::needless_lifetimes\n)]\n//@no-rustfix\nuse std::borrow::Borrow;\nuse std::collections::HashSet;\nuse std::convert::AsRef;\nuse std::mem::MaybeUninit;\n\n// `v` should be warned\n// `w`, `x` and `y` are allowed (moved or mutated)\nfn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {\n    //~^ needless_pass_by_value\n\n    assert_eq!(v.len(), 42);\n\n    consume(w);\n\n    x.push(T::default());\n\n    y\n}\n\nfn consume<T>(_: T) {}\n\nstruct Wrapper(String);\n\nfn bar(x: String, y: Wrapper) {\n    //~^ needless_pass_by_value\n    //~| needless_pass_by_value\n\n    assert_eq!(x.len(), 42);\n    assert_eq!(y.0.len(), 42);\n}\n\n// V implements `Borrow<V>`, but should be warned correctly\nfn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {\n    //~^ needless_pass_by_value\n\n    println!(\"{}\", t.borrow());\n    println!(\"{}\", u.as_ref());\n    consume(&v);\n}\n\n// ok\nfn test_fn<F: Fn(i32) -> i32>(f: F) {\n    f(1);\n}\n\n// x should be warned, but y is ok\nfn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {\n    //~^ needless_pass_by_value\n\n    match x {\n        Some(Some(_)) => 1, // not moved\n        _ => 0,\n    };\n\n    match y {\n        Some(Some(s)) => consume(s), // moved\n        _ => (),\n    };\n}\n\n// x and y should be warned, but z is ok\nfn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {\n    //~^ needless_pass_by_value\n    //~| needless_pass_by_value\n\n    let Wrapper(s) = z; // moved\n    let Wrapper(ref t) = y; // not moved\n    let Wrapper(_) = y; // still not moved\n\n    assert_eq!(x.0.len(), s.len());\n    println!(\"{}\", t);\n}\n\ntrait Foo {}\n\n// `S: Serialize` is allowed to be passed by value, since a caller can pass `&S` instead\ntrait Serialize {}\nimpl<'a, T> Serialize for &'a T where T: Serialize {}\nimpl Serialize for i32 {}\n\nfn test_blanket_ref<T: Foo, S: Serialize>(vals: T, serializable: S) {}\n//~^ needless_pass_by_value\n\nfn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {\n    //~^ needless_pass_by_value\n    //~| needless_pass_by_value\n    //~| needless_pass_by_value\n    //~| needless_pass_by_value\n\n    s.capacity();\n    let _ = t.clone();\n    u.capacity();\n    let _ = v.clone();\n}\n\nstruct S<T, U>(T, U);\n\nimpl<T: Serialize, U> S<T, U> {\n    fn foo(\n        self,\n        // taking `self` by value is always allowed\n        s: String,\n        //~^ needless_pass_by_value\n        t: String,\n        //~^ needless_pass_by_value\n    ) -> usize {\n        s.len() + t.capacity()\n    }\n\n    fn bar(_t: T, // Ok, since `&T: Serialize` too\n    ) {\n    }\n\n    fn baz(&self, uu: U, ss: Self) {}\n    //~^ needless_pass_by_value\n    //~| needless_pass_by_value\n}\n\ntrait FalsePositive {\n    fn visit_str(s: &str);\n    fn visit_string(s: String) {\n        Self::visit_str(&s);\n    }\n}\n\n// shouldn't warn on extern funcs\nextern \"C\" fn ext(x: MaybeUninit<usize>) -> usize {\n    unsafe { x.assume_init() }\n}\n\n// exempt RangeArgument\nfn range<T: ::std::ops::RangeBounds<usize>>(range: T) {\n    let _ = range.start_bound();\n}\n\nstruct CopyWrapper(u32);\n\nfn bar_copy(x: u32, y: CopyWrapper) {\n    //~^ needless_pass_by_value\n\n    assert_eq!(x, 42);\n    assert_eq!(y.0, 42);\n}\n\n// x and y should be warned, but z is ok\nfn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {\n    //~^ needless_pass_by_value\n    //~| needless_pass_by_value\n    //~| needless_pass_by_value\n\n    let CopyWrapper(s) = z; // moved\n    let CopyWrapper(ref t) = y; // not moved\n    let CopyWrapper(_) = y; // still not moved\n\n    assert_eq!(x.0, s);\n    println!(\"{}\", t);\n}\n\n// The following 3 lines should not cause an ICE. See #2831\ntrait Bar<'a, A> {}\nimpl<'b, T> Bar<'b, T> for T {}\nfn some_fun<'b, S: Bar<'b, ()>>(items: S) {}\n//~^ needless_pass_by_value\n\n// Also this should not cause an ICE. See #2831\ntrait Club<'a, A> {}\nimpl<T> Club<'static, T> for T {}\nfn more_fun(items: impl Club<'static, i32>) {}\n//~^ needless_pass_by_value\n\nfn is_sync<T>(_: T)\nwhere\n    T: Sync,\n{\n}\n\nstruct Obj(String);\n\nfn prefix_test(_unused_with_prefix: Obj) {}\n\n// Regression test for <https://github.com/rust-lang/rust-clippy/issues/13744>.\n// It's more idiomatic to write `Option<&T>` rather than `&Option<T>`.\nfn option_inner_ref(x: Option<String>) {\n    //~^ ERROR: this argument is passed by value, but not consumed in the function body\n    assert!(x.is_some());\n}\n\nmod non_standard {\n    #[derive(Debug)]\n    pub struct Option<T>(T);\n}\n\nfn non_standard_option(x: non_standard::Option<String>) {\n    //~^ needless_pass_by_value\n    dbg!(&x);\n}\n\nfn option_by_name(x: Option<std::option::Option<core::option::Option<non_standard::Option<String>>>>) {\n    //~^ needless_pass_by_value\n    dbg!(&x);\n}\n\ntype OptStr = Option<String>;\n\nfn non_option(x: OptStr) {\n    //~^ needless_pass_by_value\n    dbg!(&x);\n}\n\ntype Opt<T> = Option<T>;\n\nfn non_option_either(x: Opt<String>) {\n    //~^ needless_pass_by_value\n    dbg!(&x);\n}\n\nfn main() {\n    // This should not cause an ICE either\n    // https://github.com/rust-lang/rust-clippy/issues/3144\n    is_sync(HashSet::<usize>::new());\n}\n"
  },
  {
    "path": "tests/ui/needless_pass_by_value.stderr",
    "content": "error: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:19:23\n   |\nLL | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {\n   |                       ^^^^^^ help: consider changing the type to: `&[T]`\n   |\n   = note: `-D clippy::needless-pass-by-value` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:35:11\n   |\nLL | fn bar(x: String, y: Wrapper) {\n   |           ^^^^^^ help: consider changing the type to: `&str`\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:35:22\n   |\nLL | fn bar(x: String, y: Wrapper) {\n   |                      ^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn bar(x: String, y: &Wrapper) {\n   |                      +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:44:71\n   |\nLL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {\n   |                                                                       ^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: &V) {\n   |                                                                       +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:58:18\n   |\nLL | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {\n   |                  ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn test_match(x: Option<Option<&String>>, y: Option<Option<String>>) {\n   |                                +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:73:24\n   |\nLL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {\n   |                        ^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn test_destructure(x: &Wrapper, y: Wrapper, z: Wrapper) {\n   |                        +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:73:36\n   |\nLL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {\n   |                                    ^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn test_destructure(x: Wrapper, y: &Wrapper, z: Wrapper) {\n   |                                    +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:92:49\n   |\nLL | fn test_blanket_ref<T: Foo, S: Serialize>(vals: T, serializable: S) {}\n   |                                                 ^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn test_blanket_ref<T: Foo, S: Serialize>(vals: &T, serializable: S) {}\n   |                                                 +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:95:18\n   |\nLL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {\n   |                  ^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn issue_2114(s: &String, t: String, u: Vec<i32>, v: Vec<i32>) {\n   |                  +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:95:29\n   |\nLL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {\n   |                             ^^^^^^\n   |\nhelp: consider changing the type to\n   |\nLL - fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {\nLL + fn issue_2114(s: String, t: &str, u: Vec<i32>, v: Vec<i32>) {\n   |\nhelp: change `t.clone()` to\n   |\nLL -     let _ = t.clone();\nLL +     let _ = t.to_string();\n   |\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:95:40\n   |\nLL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {\n   |                                        ^^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn issue_2114(s: String, t: String, u: &Vec<i32>, v: Vec<i32>) {\n   |                                        +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:95:53\n   |\nLL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {\n   |                                                     ^^^^^^^^\n   |\nhelp: consider changing the type to\n   |\nLL - fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {\nLL + fn issue_2114(s: String, t: String, u: Vec<i32>, v: &[i32]) {\n   |\nhelp: change `v.clone()` to\n   |\nLL -     let _ = v.clone();\nLL +     let _ = v.to_owned();\n   |\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:113:12\n   |\nLL |         s: String,\n   |            ^^^^^^ help: consider changing the type to: `&str`\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:115:12\n   |\nLL |         t: String,\n   |            ^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL |         t: &String,\n   |            +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:125:23\n   |\nLL |     fn baz(&self, uu: U, ss: Self) {}\n   |                       ^\n   |\nhelp: consider taking a reference instead\n   |\nLL |     fn baz(&self, uu: &U, ss: Self) {}\n   |                       +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:125:30\n   |\nLL |     fn baz(&self, uu: U, ss: Self) {}\n   |                              ^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL |     fn baz(&self, uu: U, ss: &Self) {}\n   |                              +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:149:24\n   |\nLL | fn bar_copy(x: u32, y: CopyWrapper) {\n   |                        ^^^^^^^^^^^\n   |\nhelp: or consider marking this type as `Copy`\n  --> tests/ui/needless_pass_by_value.rs:147:1\n   |\nLL | struct CopyWrapper(u32);\n   | ^^^^^^^^^^^^^^^^^^\nhelp: consider taking a reference instead\n   |\nLL | fn bar_copy(x: u32, y: &CopyWrapper) {\n   |                        +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:157:29\n   |\nLL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {\n   |                             ^^^^^^^^^^^\n   |\nhelp: or consider marking this type as `Copy`\n  --> tests/ui/needless_pass_by_value.rs:147:1\n   |\nLL | struct CopyWrapper(u32);\n   | ^^^^^^^^^^^^^^^^^^\nhelp: consider taking a reference instead\n   |\nLL | fn test_destructure_copy(x: &CopyWrapper, y: CopyWrapper, z: CopyWrapper) {\n   |                             +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:157:45\n   |\nLL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {\n   |                                             ^^^^^^^^^^^\n   |\nhelp: or consider marking this type as `Copy`\n  --> tests/ui/needless_pass_by_value.rs:147:1\n   |\nLL | struct CopyWrapper(u32);\n   | ^^^^^^^^^^^^^^^^^^\nhelp: consider taking a reference instead\n   |\nLL | fn test_destructure_copy(x: CopyWrapper, y: &CopyWrapper, z: CopyWrapper) {\n   |                                             +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:157:61\n   |\nLL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {\n   |                                                             ^^^^^^^^^^^\n   |\nhelp: or consider marking this type as `Copy`\n  --> tests/ui/needless_pass_by_value.rs:147:1\n   |\nLL | struct CopyWrapper(u32);\n   | ^^^^^^^^^^^^^^^^^^\nhelp: consider taking a reference instead\n   |\nLL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: &CopyWrapper) {\n   |                                                             +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:173:40\n   |\nLL | fn some_fun<'b, S: Bar<'b, ()>>(items: S) {}\n   |                                        ^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn some_fun<'b, S: Bar<'b, ()>>(items: &S) {}\n   |                                        +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:179:20\n   |\nLL | fn more_fun(items: impl Club<'static, i32>) {}\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn more_fun(items: &impl Club<'static, i32>) {}\n   |                    +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:194:24\n   |\nLL | fn option_inner_ref(x: Option<String>) {\n   |                        ^^^^^^^^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn option_inner_ref(x: Option<&String>) {\n   |                               +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:204:27\n   |\nLL | fn non_standard_option(x: non_standard::Option<String>) {\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn non_standard_option(x: &non_standard::Option<String>) {\n   |                           +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:209:22\n   |\nLL | fn option_by_name(x: Option<std::option::Option<core::option::Option<non_standard::Option<String>>>>) {\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn option_by_name(x: Option<std::option::Option<core::option::Option<&non_standard::Option<String>>>>) {\n   |                                                                      +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:216:18\n   |\nLL | fn non_option(x: OptStr) {\n   |                  ^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn non_option(x: &OptStr) {\n   |                  +\n\nerror: this argument is passed by value, but not consumed in the function body\n  --> tests/ui/needless_pass_by_value.rs:223:25\n   |\nLL | fn non_option_either(x: Opt<String>) {\n   |                         ^^^^^^^^^^^\n   |\nhelp: consider taking a reference instead\n   |\nLL | fn non_option_either(x: &Opt<String>) {\n   |                         +\n\nerror: aborting due to 27 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_pass_by_value_proc_macro.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::needless_pass_by_value)]\n\nextern crate proc_macro;\n\nuse proc_macro::TokenStream;\n\n#[proc_macro_derive(Foo)]\npub fn foo(_input: TokenStream) -> TokenStream {\n    unimplemented!()\n}\n\n#[proc_macro]\npub fn bar(_input: TokenStream) -> TokenStream {\n    unimplemented!()\n}\n\n#[proc_macro_attribute]\npub fn baz(_args: TokenStream, _input: TokenStream) -> TokenStream {\n    unimplemented!()\n}\n"
  },
  {
    "path": "tests/ui/needless_pub_self.fixed",
    "content": "\n//@aux-build:proc_macros.rs\n#![feature(custom_inner_attributes)]\n#![allow(unused)]\n#![warn(clippy::needless_pub_self)]\n#![no_main]\n#![rustfmt::skip] // rustfmt will remove `in`, understandable\n                  // but very annoying for our purposes!\n\n#[macro_use]\nextern crate proc_macros;\n\n fn a() {}\n//~^ needless_pub_self\n fn b() {}\n//~^ needless_pub_self\n\npub fn c() {}\nmod a {\n    pub(in super) fn d() {}\n    pub(super) fn e() {}\n     fn f() {}\n    //~^ needless_pub_self\n}\n\nexternal! {\n    pub(self) fn g() {}\n    pub(in self) fn h() {}\n}\nwith_span! {\n    span\n    pub(self) fn i() {}\n    pub(in self) fn j() {}\n}\n\n// not really anything more to test. just a really simple lint overall\n"
  },
  {
    "path": "tests/ui/needless_pub_self.rs",
    "content": "\n//@aux-build:proc_macros.rs\n#![feature(custom_inner_attributes)]\n#![allow(unused)]\n#![warn(clippy::needless_pub_self)]\n#![no_main]\n#![rustfmt::skip] // rustfmt will remove `in`, understandable\n                  // but very annoying for our purposes!\n\n#[macro_use]\nextern crate proc_macros;\n\npub(self) fn a() {}\n//~^ needless_pub_self\npub(in self) fn b() {}\n//~^ needless_pub_self\n\npub fn c() {}\nmod a {\n    pub(in super) fn d() {}\n    pub(super) fn e() {}\n    pub(self) fn f() {}\n    //~^ needless_pub_self\n}\n\nexternal! {\n    pub(self) fn g() {}\n    pub(in self) fn h() {}\n}\nwith_span! {\n    span\n    pub(self) fn i() {}\n    pub(in self) fn j() {}\n}\n\n// not really anything more to test. just a really simple lint overall\n"
  },
  {
    "path": "tests/ui/needless_pub_self.stderr",
    "content": "error: unnecessary `pub(self)`\n  --> tests/ui/needless_pub_self.rs:13:1\n   |\nLL | pub(self) fn a() {}\n   | ^^^^^^^^^\n   |\n   = note: `-D clippy::needless-pub-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_pub_self)]`\n   = help: remove it\n\nerror: unnecessary `pub(in self)`\n  --> tests/ui/needless_pub_self.rs:15:1\n   |\nLL | pub(in self) fn b() {}\n   | ^^^^^^^^^^^^\n   |\n   = help: remove it\n\nerror: unnecessary `pub(self)`\n  --> tests/ui/needless_pub_self.rs:22:5\n   |\nLL |     pub(self) fn f() {}\n   |     ^^^^^^^^^\n   |\n   = help: remove it\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_question_mark.fixed",
    "content": "#![warn(clippy::needless_question_mark)]\n#![allow(\n    clippy::needless_return,\n    clippy::unnecessary_unwrap,\n    clippy::upper_case_acronyms,\n    dead_code,\n    unused_must_use\n)]\n\nstruct TO {\n    magic: Option<usize>,\n}\n\nstruct TR {\n    magic: Result<usize, bool>,\n}\n\nfn simple_option_bad1(to: TO) -> Option<usize> {\n    // return as a statement\n    return to.magic;\n    //~^ needless_question_mark\n}\n\n// formatting will add a semi-colon, which would make\n// this identical to the test case above\n#[rustfmt::skip]\nfn simple_option_bad2(to: TO) -> Option<usize> {\n    // return as an expression\n    return to.magic\n    //~^ needless_question_mark\n}\n\nfn simple_option_bad3(to: TO) -> Option<usize> {\n    // block value \"return\"\n    to.magic\n    //~^ needless_question_mark\n}\n\nfn simple_option_bad4(to: Option<TO>) -> Option<usize> {\n    // single line closure\n    to.and_then(|t| t.magic)\n    //~^ needless_question_mark\n}\n\n// formatting this will remove the block brackets, making\n// this test identical to the one above\n#[rustfmt::skip]\nfn simple_option_bad5(to: Option<TO>) -> Option<usize> {\n    // closure with body\n    to.and_then(|t| {\n        t.magic\n        //~^ needless_question_mark\n    })\n}\n\nfn simple_result_bad1(tr: TR) -> Result<usize, bool> {\n    return tr.magic;\n    //~^ needless_question_mark\n}\n\n// formatting will add a semi-colon, which would make\n// this identical to the test case above\n#[rustfmt::skip]\nfn simple_result_bad2(tr: TR) -> Result<usize, bool> {\n    return tr.magic\n    //~^ needless_question_mark\n}\n\nfn simple_result_bad3(tr: TR) -> Result<usize, bool> {\n    tr.magic\n    //~^ needless_question_mark\n}\n\nfn simple_result_bad4(tr: Result<TR, bool>) -> Result<usize, bool> {\n    tr.and_then(|t| t.magic)\n    //~^ needless_question_mark\n}\n\n// formatting this will remove the block brackets, making\n// this test identical to the one above\n#[rustfmt::skip]\nfn simple_result_bad5(tr: Result<TR, bool>) -> Result<usize, bool> {\n    tr.and_then(|t| {\n        t.magic\n        //~^ needless_question_mark\n    })\n}\n\nfn also_bad(tr: Result<TR, bool>) -> Result<usize, bool> {\n    if tr.is_ok() {\n        let t = tr.unwrap();\n        return t.magic;\n        //~^ needless_question_mark\n    }\n    Err(false)\n}\n\nfn false_positive_test<U, T>(x: Result<(), U>) -> Result<(), T>\nwhere\n    T: From<U>,\n{\n    Ok(x?)\n}\n\n// not quite needless\nfn deref_ref(s: Option<&String>) -> Option<&str> {\n    Some(s?)\n}\n\nfn main() {}\n\n// #6921 if a macro wraps an expr in Some(  ) and the ? is in the macro use,\n// the suggestion fails to apply; do not lint\nmacro_rules! some_in_macro {\n    ($expr:expr) => {\n        || -> _ { Some($expr) }()\n    };\n}\n\npub fn test1() {\n    let x = Some(3);\n    let _x = some_in_macro!(x?);\n}\n\n// this one is ok because both the ? and the Some are both inside the macro def\nmacro_rules! some_and_qmark_in_macro {\n    ($expr:expr) => {\n        || -> Option<_> { Some($expr) }()\n        //~^ needless_question_mark\n    };\n}\n\npub fn test2() {\n    let x = Some(3);\n    let _x = some_and_qmark_in_macro!(x?);\n}\n\nasync fn async_option_bad(to: TO) -> Option<usize> {\n    let _ = Some(3);\n    to.magic\n    //~^ needless_question_mark\n}\n\nasync fn async_deref_ref(s: Option<&String>) -> Option<&str> {\n    Some(s?)\n}\n\nasync fn async_result_bad(s: TR) -> Result<usize, bool> {\n    s.magic\n    //~^ needless_question_mark\n}\n\nasync fn async_wrapped<T>(a: Option<T>) -> Option<T> {\n    { a }\n    //~^ needless_question_mark\n}\n"
  },
  {
    "path": "tests/ui/needless_question_mark.rs",
    "content": "#![warn(clippy::needless_question_mark)]\n#![allow(\n    clippy::needless_return,\n    clippy::unnecessary_unwrap,\n    clippy::upper_case_acronyms,\n    dead_code,\n    unused_must_use\n)]\n\nstruct TO {\n    magic: Option<usize>,\n}\n\nstruct TR {\n    magic: Result<usize, bool>,\n}\n\nfn simple_option_bad1(to: TO) -> Option<usize> {\n    // return as a statement\n    return Some(to.magic?);\n    //~^ needless_question_mark\n}\n\n// formatting will add a semi-colon, which would make\n// this identical to the test case above\n#[rustfmt::skip]\nfn simple_option_bad2(to: TO) -> Option<usize> {\n    // return as an expression\n    return Some(to.magic?)\n    //~^ needless_question_mark\n}\n\nfn simple_option_bad3(to: TO) -> Option<usize> {\n    // block value \"return\"\n    Some(to.magic?)\n    //~^ needless_question_mark\n}\n\nfn simple_option_bad4(to: Option<TO>) -> Option<usize> {\n    // single line closure\n    to.and_then(|t| Some(t.magic?))\n    //~^ needless_question_mark\n}\n\n// formatting this will remove the block brackets, making\n// this test identical to the one above\n#[rustfmt::skip]\nfn simple_option_bad5(to: Option<TO>) -> Option<usize> {\n    // closure with body\n    to.and_then(|t| {\n        Some(t.magic?)\n        //~^ needless_question_mark\n    })\n}\n\nfn simple_result_bad1(tr: TR) -> Result<usize, bool> {\n    return Ok(tr.magic?);\n    //~^ needless_question_mark\n}\n\n// formatting will add a semi-colon, which would make\n// this identical to the test case above\n#[rustfmt::skip]\nfn simple_result_bad2(tr: TR) -> Result<usize, bool> {\n    return Ok(tr.magic?)\n    //~^ needless_question_mark\n}\n\nfn simple_result_bad3(tr: TR) -> Result<usize, bool> {\n    Ok(tr.magic?)\n    //~^ needless_question_mark\n}\n\nfn simple_result_bad4(tr: Result<TR, bool>) -> Result<usize, bool> {\n    tr.and_then(|t| Ok(t.magic?))\n    //~^ needless_question_mark\n}\n\n// formatting this will remove the block brackets, making\n// this test identical to the one above\n#[rustfmt::skip]\nfn simple_result_bad5(tr: Result<TR, bool>) -> Result<usize, bool> {\n    tr.and_then(|t| {\n        Ok(t.magic?)\n        //~^ needless_question_mark\n    })\n}\n\nfn also_bad(tr: Result<TR, bool>) -> Result<usize, bool> {\n    if tr.is_ok() {\n        let t = tr.unwrap();\n        return Ok(t.magic?);\n        //~^ needless_question_mark\n    }\n    Err(false)\n}\n\nfn false_positive_test<U, T>(x: Result<(), U>) -> Result<(), T>\nwhere\n    T: From<U>,\n{\n    Ok(x?)\n}\n\n// not quite needless\nfn deref_ref(s: Option<&String>) -> Option<&str> {\n    Some(s?)\n}\n\nfn main() {}\n\n// #6921 if a macro wraps an expr in Some(  ) and the ? is in the macro use,\n// the suggestion fails to apply; do not lint\nmacro_rules! some_in_macro {\n    ($expr:expr) => {\n        || -> _ { Some($expr) }()\n    };\n}\n\npub fn test1() {\n    let x = Some(3);\n    let _x = some_in_macro!(x?);\n}\n\n// this one is ok because both the ? and the Some are both inside the macro def\nmacro_rules! some_and_qmark_in_macro {\n    ($expr:expr) => {\n        || -> Option<_> { Some(Some($expr)?) }()\n        //~^ needless_question_mark\n    };\n}\n\npub fn test2() {\n    let x = Some(3);\n    let _x = some_and_qmark_in_macro!(x?);\n}\n\nasync fn async_option_bad(to: TO) -> Option<usize> {\n    let _ = Some(3);\n    Some(to.magic?)\n    //~^ needless_question_mark\n}\n\nasync fn async_deref_ref(s: Option<&String>) -> Option<&str> {\n    Some(s?)\n}\n\nasync fn async_result_bad(s: TR) -> Result<usize, bool> {\n    Ok(s.magic?)\n    //~^ needless_question_mark\n}\n\nasync fn async_wrapped<T>(a: Option<T>) -> Option<T> {\n    { Some(a?) }\n    //~^ needless_question_mark\n}\n"
  },
  {
    "path": "tests/ui/needless_question_mark.stderr",
    "content": "error: enclosing `Some` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:20:12\n   |\nLL |     return Some(to.magic?);\n   |            ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::needless-question-mark` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_question_mark)]`\nhelp: remove the enclosing `Some` and `?` operator\n   |\nLL -     return Some(to.magic?);\nLL +     return to.magic;\n   |\n\nerror: enclosing `Some` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:29:12\n   |\nLL |     return Some(to.magic?)\n   |            ^^^^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Some` and `?` operator\n   |\nLL -     return Some(to.magic?)\nLL +     return to.magic\n   |\n\nerror: enclosing `Some` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:35:5\n   |\nLL |     Some(to.magic?)\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Some` and `?` operator\n   |\nLL -     Some(to.magic?)\nLL +     to.magic\n   |\n\nerror: enclosing `Some` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:41:21\n   |\nLL |     to.and_then(|t| Some(t.magic?))\n   |                     ^^^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Some` and `?` operator\n   |\nLL -     to.and_then(|t| Some(t.magic?))\nLL +     to.and_then(|t| t.magic)\n   |\n\nerror: enclosing `Some` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:51:9\n   |\nLL |         Some(t.magic?)\n   |         ^^^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Some` and `?` operator\n   |\nLL -         Some(t.magic?)\nLL +         t.magic\n   |\n\nerror: enclosing `Ok` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:57:12\n   |\nLL |     return Ok(tr.magic?);\n   |            ^^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Ok` and `?` operator\n   |\nLL -     return Ok(tr.magic?);\nLL +     return tr.magic;\n   |\n\nerror: enclosing `Ok` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:65:12\n   |\nLL |     return Ok(tr.magic?)\n   |            ^^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Ok` and `?` operator\n   |\nLL -     return Ok(tr.magic?)\nLL +     return tr.magic\n   |\n\nerror: enclosing `Ok` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:70:5\n   |\nLL |     Ok(tr.magic?)\n   |     ^^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Ok` and `?` operator\n   |\nLL -     Ok(tr.magic?)\nLL +     tr.magic\n   |\n\nerror: enclosing `Ok` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:75:21\n   |\nLL |     tr.and_then(|t| Ok(t.magic?))\n   |                     ^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Ok` and `?` operator\n   |\nLL -     tr.and_then(|t| Ok(t.magic?))\nLL +     tr.and_then(|t| t.magic)\n   |\n\nerror: enclosing `Ok` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:84:9\n   |\nLL |         Ok(t.magic?)\n   |         ^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Ok` and `?` operator\n   |\nLL -         Ok(t.magic?)\nLL +         t.magic\n   |\n\nerror: enclosing `Ok` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:92:16\n   |\nLL |         return Ok(t.magic?);\n   |                ^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Ok` and `?` operator\n   |\nLL -         return Ok(t.magic?);\nLL +         return t.magic;\n   |\n\nerror: enclosing `Some` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:128:27\n   |\nLL |         || -> Option<_> { Some(Some($expr)?) }()\n   |                           ^^^^^^^^^^^^^^^^^^\n...\nLL |     let _x = some_and_qmark_in_macro!(x?);\n   |              ---------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `some_and_qmark_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: remove the enclosing `Some` and `?` operator\n   |\nLL -         || -> Option<_> { Some(Some($expr)?) }()\nLL +         || -> Option<_> { Some($expr) }()\n   |\n\nerror: enclosing `Some` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:140:5\n   |\nLL |     Some(to.magic?)\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Some` and `?` operator\n   |\nLL -     Some(to.magic?)\nLL +     to.magic\n   |\n\nerror: enclosing `Ok` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:149:5\n   |\nLL |     Ok(s.magic?)\n   |     ^^^^^^^^^^^^\n   |\nhelp: remove the enclosing `Ok` and `?` operator\n   |\nLL -     Ok(s.magic?)\nLL +     s.magic\n   |\n\nerror: enclosing `Some` and `?` operator are unneeded\n  --> tests/ui/needless_question_mark.rs:154:7\n   |\nLL |     { Some(a?) }\n   |       ^^^^^^^^\n   |\nhelp: remove the enclosing `Some` and `?` operator\n   |\nLL -     { Some(a?) }\nLL +     { a }\n   |\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_range_loop.rs",
    "content": "#![warn(clippy::needless_range_loop)]\n#![allow(\n    clippy::uninlined_format_args,\n    clippy::unnecessary_literal_unwrap,\n    clippy::useless_vec,\n    clippy::manual_slice_fill\n)]\n//@no-rustfix\nstatic STATIC: [usize; 4] = [0, 1, 8, 16];\nconst CONST: [usize; 4] = [0, 1, 8, 16];\nconst MAX_LEN: usize = 42;\n\nfn main() {\n    let mut vec = vec![1, 2, 3, 4];\n    let vec2 = vec![1, 2, 3, 4];\n    for i in 0..vec.len() {\n        //~^ needless_range_loop\n\n        println!(\"{}\", vec[i]);\n    }\n\n    for i in 0..vec.len() {\n        let i = 42; // make a different `i`\n        println!(\"{}\", vec[i]); // ok, not the `i` of the for-loop\n    }\n\n    for i in 0..vec.len() {\n        //~^ needless_range_loop\n\n        let _ = vec[i];\n    }\n\n    // ICE #746\n    for j in 0..4 {\n        //~^ needless_range_loop\n\n        println!(\"{:?}\", STATIC[j]);\n    }\n\n    for j in 0..4 {\n        //~^ needless_range_loop\n\n        println!(\"{:?}\", CONST[j]);\n    }\n\n    for i in 0..vec.len() {\n        //~^ needless_range_loop\n\n        println!(\"{} {}\", vec[i], i);\n    }\n    for i in 0..vec.len() {\n        // not an error, indexing more than one variable\n        println!(\"{} {}\", vec[i], vec2[i]);\n    }\n\n    for i in 0..vec.len() {\n        //~^ needless_range_loop\n\n        println!(\"{}\", vec2[i]);\n    }\n\n    for i in 5..vec.len() {\n        //~^ needless_range_loop\n\n        println!(\"{}\", vec[i]);\n    }\n\n    for i in 0..MAX_LEN {\n        //~^ needless_range_loop\n\n        println!(\"{}\", vec[i]);\n    }\n\n    for i in 0..=MAX_LEN {\n        //~^ needless_range_loop\n\n        println!(\"{}\", vec[i]);\n    }\n\n    for i in 5..10 {\n        //~^ needless_range_loop\n\n        println!(\"{}\", vec[i]);\n    }\n\n    for i in 5..=10 {\n        //~^ needless_range_loop\n\n        println!(\"{}\", vec[i]);\n    }\n\n    for i in 5..vec.len() {\n        //~^ needless_range_loop\n\n        println!(\"{} {}\", vec[i], i);\n    }\n\n    for i in 5..10 {\n        //~^ needless_range_loop\n\n        println!(\"{} {}\", vec[i], i);\n    }\n\n    // #2542\n    for i in 0..vec.len() {\n        //~^ needless_range_loop\n\n        vec[i] = Some(1).unwrap_or_else(|| panic!(\"error on {}\", i));\n    }\n\n    // #3788\n    let test = Test {\n        inner: vec![1, 2, 3, 4],\n    };\n    for i in 0..2 {\n        println!(\"{}\", test[i]);\n    }\n\n    // See #601\n    for i in 0..10 {\n        // no error, id_col does not exist outside the loop\n        let mut id_col = [0f64; 10];\n        id_col[i] = 1f64;\n    }\n\n    fn f<T>(_: &T, _: &T) -> bool {\n        unimplemented!()\n    }\n    fn g<T>(_: &mut [T], _: usize, _: usize) {\n        unimplemented!()\n    }\n    for i in 1..vec.len() {\n        if f(&vec[i - 1], &vec[i]) {\n            g(&mut vec, i - 1, i);\n        }\n    }\n\n    for mid in 1..vec.len() {\n        let (_, _) = vec.split_at(mid);\n    }\n}\n\nstruct Test {\n    inner: Vec<usize>,\n}\n\nimpl std::ops::Index<usize> for Test {\n    type Output = usize;\n    fn index(&self, index: usize) -> &Self::Output {\n        &self.inner[index]\n    }\n}\n\nfn partition<T: PartialOrd + Send>(v: &mut [T]) -> usize {\n    let pivot = v.len() - 1;\n    let mut i = 0;\n    for j in 0..pivot {\n        if v[j] <= v[pivot] {\n            v.swap(i, j);\n            i += 1;\n        }\n    }\n    v.swap(i, pivot);\n    i\n}\n\npub fn manual_copy_same_destination(dst: &mut [i32], d: usize, s: usize) {\n    // Same source and destination - don't trigger lint\n    for i in 0..dst.len() {\n        dst[d + i] = dst[s + i];\n    }\n}\n\nmod issue_2496 {\n    pub trait Handle {\n        fn new_for_index(index: usize) -> Self;\n        fn index(&self) -> usize;\n    }\n\n    pub fn test<H: Handle>() -> H {\n        for x in 0..5 {\n            let next_handle = H::new_for_index(x);\n            println!(\"{}\", next_handle.index());\n        }\n        unimplemented!()\n    }\n}\n\nfn needless_loop() {\n    use std::hint::black_box;\n    let x = [0; 64];\n    for i in 0..64 {\n        let y = [0; 64];\n\n        black_box(x[i]);\n        black_box(y[i]);\n    }\n\n    for i in 0..64 {\n        black_box(x[i]);\n        black_box([0; 64][i]);\n    }\n\n    for i in 0..64 {\n        black_box(x[i]);\n        black_box([1, 2, 3, 4, 5, 6, 7, 8][i]);\n    }\n\n    for i in 0..64 {\n        black_box([1, 2, 3, 4, 5, 6, 7, 8][i]);\n    }\n}\n\nfn issue_15068() {\n    let a = vec![vec![0u8; MAX_LEN]; MAX_LEN];\n    let b = vec![0u8; MAX_LEN];\n\n    for i in 0..MAX_LEN {\n        // no error\n        let _ = a[0][i];\n        let _ = b[i];\n    }\n\n    for i in 0..MAX_LEN {\n        // no error\n        let _ = a[i][0];\n        let _ = b[i];\n    }\n\n    for i in 0..MAX_LEN {\n        // no error\n        let _ = a[i][b[i] as usize];\n    }\n\n    for i in 0..MAX_LEN {\n        //~^ needless_range_loop\n        let _ = a[i][i];\n    }\n\n    for i in 0..MAX_LEN {\n        //~^ needless_range_loop\n        let _ = a[0][i];\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_range_loop.stderr",
    "content": "error: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop.rs:16:14\n   |\nLL |     for i in 0..vec.len() {\n   |              ^^^^^^^^^^^^\n   |\n   = note: `-D clippy::needless-range-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]`\nhelp: consider using an iterator\n   |\nLL -     for i in 0..vec.len() {\nLL +     for <item> in &vec {\n   |\n\nerror: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop.rs:27:14\n   |\nLL |     for i in 0..vec.len() {\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..vec.len() {\nLL +     for <item> in &vec {\n   |\n\nerror: the loop variable `j` is only used to index `STATIC`\n  --> tests/ui/needless_range_loop.rs:34:14\n   |\nLL |     for j in 0..4 {\n   |              ^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for j in 0..4 {\nLL +     for <item> in &STATIC {\n   |\n\nerror: the loop variable `j` is only used to index `CONST`\n  --> tests/ui/needless_range_loop.rs:40:14\n   |\nLL |     for j in 0..4 {\n   |              ^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for j in 0..4 {\nLL +     for <item> in &CONST {\n   |\n\nerror: the loop variable `i` is used to index `vec`\n  --> tests/ui/needless_range_loop.rs:46:14\n   |\nLL |     for i in 0..vec.len() {\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider using an iterator and enumerate()\n   |\nLL -     for i in 0..vec.len() {\nLL +     for (i, <item>) in vec.iter().enumerate() {\n   |\n\nerror: the loop variable `i` is only used to index `vec2`\n  --> tests/ui/needless_range_loop.rs:56:14\n   |\nLL |     for i in 0..vec.len() {\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..vec.len() {\nLL +     for <item> in vec2.iter().take(vec.len()) {\n   |\n\nerror: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop.rs:62:14\n   |\nLL |     for i in 5..vec.len() {\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 5..vec.len() {\nLL +     for <item> in vec.iter().skip(5) {\n   |\n\nerror: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop.rs:68:14\n   |\nLL |     for i in 0..MAX_LEN {\n   |              ^^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..MAX_LEN {\nLL +     for <item> in vec.iter().take(MAX_LEN) {\n   |\n\nerror: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop.rs:74:14\n   |\nLL |     for i in 0..=MAX_LEN {\n   |              ^^^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..=MAX_LEN {\nLL +     for <item> in vec.iter().take(MAX_LEN + 1) {\n   |\n\nerror: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop.rs:80:14\n   |\nLL |     for i in 5..10 {\n   |              ^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 5..10 {\nLL +     for <item> in vec.iter().take(10).skip(5) {\n   |\n\nerror: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop.rs:86:14\n   |\nLL |     for i in 5..=10 {\n   |              ^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 5..=10 {\nLL +     for <item> in vec.iter().take(10 + 1).skip(5) {\n   |\n\nerror: the loop variable `i` is used to index `vec`\n  --> tests/ui/needless_range_loop.rs:92:14\n   |\nLL |     for i in 5..vec.len() {\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider using an iterator and enumerate()\n   |\nLL -     for i in 5..vec.len() {\nLL +     for (i, <item>) in vec.iter().enumerate().skip(5) {\n   |\n\nerror: the loop variable `i` is used to index `vec`\n  --> tests/ui/needless_range_loop.rs:98:14\n   |\nLL |     for i in 5..10 {\n   |              ^^^^^\n   |\nhelp: consider using an iterator and enumerate()\n   |\nLL -     for i in 5..10 {\nLL +     for (i, <item>) in vec.iter().enumerate().take(10).skip(5) {\n   |\n\nerror: the loop variable `i` is used to index `vec`\n  --> tests/ui/needless_range_loop.rs:105:14\n   |\nLL |     for i in 0..vec.len() {\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider using an iterator and enumerate()\n   |\nLL -     for i in 0..vec.len() {\nLL +     for (i, <item>) in vec.iter_mut().enumerate() {\n   |\n\nerror: the loop variable `i` is used to index `a`\n  --> tests/ui/needless_range_loop.rs:235:14\n   |\nLL |     for i in 0..MAX_LEN {\n   |              ^^^^^^^^^^\n   |\nhelp: consider using an iterator and enumerate()\n   |\nLL -     for i in 0..MAX_LEN {\nLL +     for (i, <item>) in a.iter().enumerate().take(MAX_LEN) {\n   |\n\nerror: the loop variable `i` is only used to index `a`\n  --> tests/ui/needless_range_loop.rs:240:14\n   |\nLL |     for i in 0..MAX_LEN {\n   |              ^^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..MAX_LEN {\nLL +     for <item> in a.iter().take(MAX_LEN) {\n   |\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_range_loop2.rs",
    "content": "#![warn(clippy::needless_range_loop)]\n#![allow(clippy::useless_vec)]\n//@no-rustfix\nfn calc_idx(i: usize) -> usize {\n    (i + i + 20) % 4\n}\n\nfn main() {\n    let ns = vec![2, 3, 5, 7];\n\n    for i in 3..10 {\n        //~^ needless_range_loop\n\n        println!(\"{}\", ns[i]);\n    }\n\n    for i in 3..10 {\n        println!(\"{}\", ns[i % 4]);\n    }\n\n    for i in 3..10 {\n        println!(\"{}\", ns[i % ns.len()]);\n    }\n\n    for i in 3..10 {\n        println!(\"{}\", ns[calc_idx(i)]);\n    }\n\n    for i in 3..10 {\n        println!(\"{}\", ns[calc_idx(i) % 4]);\n    }\n\n    let mut ms = vec![1, 2, 3, 4, 5, 6];\n    for i in 0..ms.len() {\n        //~^ needless_range_loop\n\n        ms[i] *= 2;\n    }\n    assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);\n\n    let mut ms = vec![1, 2, 3, 4, 5, 6];\n    for i in 0..ms.len() {\n        //~^ needless_range_loop\n\n        let x = &mut ms[i];\n        *x *= 2;\n    }\n    assert_eq!(ms, vec![2, 4, 6, 8, 10, 12]);\n\n    let g = vec![1, 2, 3, 4, 5, 6];\n    let glen = g.len();\n    for i in 0..glen {\n        let x: u32 = g[i + 1..].iter().sum();\n        println!(\"{}\", g[i] + x);\n    }\n    assert_eq!(g, vec![20, 18, 15, 11, 6, 0]);\n\n    let mut g = vec![1, 2, 3, 4, 5, 6];\n    let glen = g.len();\n    for i in 0..glen {\n        g[i] = g[i + 1..].iter().sum();\n    }\n    assert_eq!(g, vec![20, 18, 15, 11, 6, 0]);\n\n    let x = 5;\n    let mut vec = vec![0; 9];\n\n    for i in x..x + 4 {\n        //~^ needless_range_loop\n\n        vec[i] += 1;\n    }\n\n    let x = 5;\n    let mut vec = vec![0; 10];\n\n    for i in x..=x + 4 {\n        //~^ needless_range_loop\n\n        vec[i] += 1;\n    }\n\n    let arr = [1, 2, 3];\n\n    for i in 0..3 {\n        //~^ needless_range_loop\n\n        println!(\"{}\", arr[i]);\n    }\n\n    for i in 0..2 {\n        //~^ needless_range_loop\n\n        println!(\"{}\", arr[i]);\n    }\n\n    for i in 1..3 {\n        //~^ needless_range_loop\n\n        println!(\"{}\", arr[i]);\n    }\n\n    // Fix #5945\n    let mut vec = vec![1, 2, 3, 4];\n    for i in 0..vec.len() - 1 {\n        vec[i] += 1;\n    }\n    let mut vec = vec![1, 2, 3, 4];\n    for i in vec.len() - 3..vec.len() {\n        vec[i] += 1;\n    }\n    let mut vec = vec![1, 2, 3, 4];\n    for i in vec.len() - 3..vec.len() - 1 {\n        vec[i] += 1;\n    }\n}\n\nmod issue2277 {\n    pub fn example(list: &[[f64; 3]]) {\n        let mut x: [f64; 3] = [10.; 3];\n\n        for i in 0..3 {\n            x[i] = list.iter().map(|item| item[i]).sum::<f64>();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_range_loop2.stderr",
    "content": "error: the loop variable `i` is only used to index `ns`\n  --> tests/ui/needless_range_loop2.rs:11:14\n   |\nLL |     for i in 3..10 {\n   |              ^^^^^\n   |\n   = note: `-D clippy::needless-range-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]`\nhelp: consider using an iterator\n   |\nLL -     for i in 3..10 {\nLL +     for <item> in ns.iter().take(10).skip(3) {\n   |\n\nerror: the loop variable `i` is only used to index `ms`\n  --> tests/ui/needless_range_loop2.rs:34:14\n   |\nLL |     for i in 0..ms.len() {\n   |              ^^^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..ms.len() {\nLL +     for <item> in &mut ms {\n   |\n\nerror: the loop variable `i` is only used to index `ms`\n  --> tests/ui/needless_range_loop2.rs:42:14\n   |\nLL |     for i in 0..ms.len() {\n   |              ^^^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..ms.len() {\nLL +     for <item> in &mut ms {\n   |\n\nerror: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop2.rs:68:14\n   |\nLL |     for i in x..x + 4 {\n   |              ^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in x..x + 4 {\nLL +     for <item> in vec.iter_mut().skip(x).take(4) {\n   |\n\nerror: the loop variable `i` is only used to index `vec`\n  --> tests/ui/needless_range_loop2.rs:77:14\n   |\nLL |     for i in x..=x + 4 {\n   |              ^^^^^^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in x..=x + 4 {\nLL +     for <item> in vec.iter_mut().skip(x).take(4 + 1) {\n   |\n\nerror: the loop variable `i` is only used to index `arr`\n  --> tests/ui/needless_range_loop2.rs:85:14\n   |\nLL |     for i in 0..3 {\n   |              ^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..3 {\nLL +     for <item> in &arr {\n   |\n\nerror: the loop variable `i` is only used to index `arr`\n  --> tests/ui/needless_range_loop2.rs:91:14\n   |\nLL |     for i in 0..2 {\n   |              ^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 0..2 {\nLL +     for <item> in arr.iter().take(2) {\n   |\n\nerror: the loop variable `i` is only used to index `arr`\n  --> tests/ui/needless_range_loop2.rs:97:14\n   |\nLL |     for i in 1..3 {\n   |              ^^^^\n   |\nhelp: consider using an iterator\n   |\nLL -     for i in 1..3 {\nLL +     for <item> in arr.iter().skip(1) {\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_raw_string.fixed",
    "content": "#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]\n#![warn(clippy::needless_raw_strings)]\n\nfn main() {\n    \"aaa\";\n    //~^ needless_raw_strings\n    r#\"\"aaa\"\"#;\n    r#\"\\s\"#;\n    b\"aaa\";\n    //~^ needless_raw_strings\n    br#\"\"aaa\"\"#;\n    br#\"\\s\"#;\n    c\"aaa\";\n    //~^ needless_raw_strings\n    cr#\"\"aaa\"\"#;\n    cr#\"\\s\"#;\n\n    \"\n    //~^ needless_raw_strings\n        a\n        multiline\n        string\n    \";\n\n    \"no hashes\";\n    //~^ needless_raw_strings\n    b\"no hashes\";\n    //~^ needless_raw_strings\n    c\"no hashes\";\n    //~^ needless_raw_strings\n}\n\nfn issue_13503() {\n    println!(\"SELECT * FROM posts\");\n    //~^ needless_raw_strings\n    println!(\"SELECT * FROM posts\");\n    //~^ needless_raw_strings\n    println!(r##\"SELECT * FROM \"posts\"\"##);\n\n    // Test arguments as well\n    println!(\"{}\", \"foobar\".len());\n    //~^ needless_raw_strings\n}\n"
  },
  {
    "path": "tests/ui/needless_raw_string.rs",
    "content": "#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]\n#![warn(clippy::needless_raw_strings)]\n\nfn main() {\n    r#\"aaa\"#;\n    //~^ needless_raw_strings\n    r#\"\"aaa\"\"#;\n    r#\"\\s\"#;\n    br#\"aaa\"#;\n    //~^ needless_raw_strings\n    br#\"\"aaa\"\"#;\n    br#\"\\s\"#;\n    cr#\"aaa\"#;\n    //~^ needless_raw_strings\n    cr#\"\"aaa\"\"#;\n    cr#\"\\s\"#;\n\n    r#\"\n    //~^ needless_raw_strings\n        a\n        multiline\n        string\n    \"#;\n\n    r\"no hashes\";\n    //~^ needless_raw_strings\n    br\"no hashes\";\n    //~^ needless_raw_strings\n    cr\"no hashes\";\n    //~^ needless_raw_strings\n}\n\nfn issue_13503() {\n    println!(r\"SELECT * FROM posts\");\n    //~^ needless_raw_strings\n    println!(r#\"SELECT * FROM posts\"#);\n    //~^ needless_raw_strings\n    println!(r##\"SELECT * FROM \"posts\"\"##);\n\n    // Test arguments as well\n    println!(\"{}\", r\"foobar\".len());\n    //~^ needless_raw_strings\n}\n"
  },
  {
    "path": "tests/ui/needless_raw_string.stderr",
    "content": "error: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:5:5\n   |\nLL |     r#\"aaa\"#;\n   |     ^^^^^^^^\n   |\n   = note: `-D clippy::needless-raw-strings` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]`\nhelp: use a plain string literal instead\n   |\nLL -     r#\"aaa\"#;\nLL +     \"aaa\";\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:9:5\n   |\nLL |     br#\"aaa\"#;\n   |     ^^^^^^^^^\n   |\nhelp: use a plain byte string literal instead\n   |\nLL -     br#\"aaa\"#;\nLL +     b\"aaa\";\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:13:5\n   |\nLL |     cr#\"aaa\"#;\n   |     ^^^^^^^^^\n   |\nhelp: use a plain C string literal instead\n   |\nLL -     cr#\"aaa\"#;\nLL +     c\"aaa\";\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:18:5\n   |\nLL | /     r#\"\nLL | |\nLL | |         a\nLL | |         multiline\nLL | |         string\nLL | |     \"#;\n   | |______^\n   |\nhelp: use a plain string literal instead\n   |\nLL ~     \"\nLL |\n...\nLL |         string\nLL ~     \";\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:25:5\n   |\nLL |     r\"no hashes\";\n   |     ^^^^^^^^^^^^\n   |\nhelp: use a plain string literal instead\n   |\nLL -     r\"no hashes\";\nLL +     \"no hashes\";\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:27:5\n   |\nLL |     br\"no hashes\";\n   |     ^^^^^^^^^^^^^\n   |\nhelp: use a plain byte string literal instead\n   |\nLL -     br\"no hashes\";\nLL +     b\"no hashes\";\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:29:5\n   |\nLL |     cr\"no hashes\";\n   |     ^^^^^^^^^^^^^\n   |\nhelp: use a plain C string literal instead\n   |\nLL -     cr\"no hashes\";\nLL +     c\"no hashes\";\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:34:14\n   |\nLL |     println!(r\"SELECT * FROM posts\");\n   |              ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a plain string literal instead\n   |\nLL -     println!(r\"SELECT * FROM posts\");\nLL +     println!(\"SELECT * FROM posts\");\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:36:14\n   |\nLL |     println!(r#\"SELECT * FROM posts\"#);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a plain string literal instead\n   |\nLL -     println!(r#\"SELECT * FROM posts\"#);\nLL +     println!(\"SELECT * FROM posts\");\n   |\n\nerror: unnecessary raw string literal\n  --> tests/ui/needless_raw_string.rs:41:20\n   |\nLL |     println!(\"{}\", r\"foobar\".len());\n   |                    ^^^^^^^^^\n   |\nhelp: use a plain string literal instead\n   |\nLL -     println!(\"{}\", r\"foobar\".len());\nLL +     println!(\"{}\", \"foobar\".len());\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_raw_string_hashes.fixed",
    "content": "#![allow(clippy::no_effect, unused)]\n#![warn(clippy::needless_raw_string_hashes)]\n\nfn main() {\n    r\"\\aaa\";\n    //~^ needless_raw_string_hashes\n    r#\"Hello \"world\"!\"#;\n    //~^ needless_raw_string_hashes\n    r####\" \"### \"## \"# \"####;\n    //~^ needless_raw_string_hashes\n    r###\" \"aa\" \"# \"## \"###;\n    //~^ needless_raw_string_hashes\n    br\"\\aaa\";\n    //~^ needless_raw_string_hashes\n    br#\"Hello \"world\"!\"#;\n    //~^ needless_raw_string_hashes\n    br####\" \"### \"## \"# \"####;\n    //~^ needless_raw_string_hashes\n    br###\" \"aa\" \"# \"## \"###;\n    //~^ needless_raw_string_hashes\n    cr\"\\aaa\";\n    //~^ needless_raw_string_hashes\n    cr#\"Hello \"world\"!\"#;\n    //~^ needless_raw_string_hashes\n    cr####\" \"### \"## \"# \"####;\n    //~^ needless_raw_string_hashes\n    cr###\" \"aa\" \"# \"## \"###;\n    //~^ needless_raw_string_hashes\n\n    r\"\n    //~^ needless_raw_string_hashes\n        \\a\n        multiline\n        string\n    \";\n\n    r\"rust\";\n    //~^ needless_raw_string_hashes\n    r\"hello world\";\n    //~^ needless_raw_string_hashes\n}\n\nfn issue_13503() {\n    println!(r\"SELECT * FROM posts\");\n    println!(r\"SELECT * FROM posts\");\n    //~^ needless_raw_string_hashes\n    println!(r#\"SELECT * FROM \"posts\"\"#);\n    //~^ needless_raw_string_hashes\n    println!(r#\"SELECT * FROM \"posts\"\"#);\n    //~^ needless_raw_string_hashes\n\n    // Test arguments as well\n    println!(\"{}\", r\"foobar\".len());\n}\n"
  },
  {
    "path": "tests/ui/needless_raw_string_hashes.rs",
    "content": "#![allow(clippy::no_effect, unused)]\n#![warn(clippy::needless_raw_string_hashes)]\n\nfn main() {\n    r#\"\\aaa\"#;\n    //~^ needless_raw_string_hashes\n    r##\"Hello \"world\"!\"##;\n    //~^ needless_raw_string_hashes\n    r######\" \"### \"## \"# \"######;\n    //~^ needless_raw_string_hashes\n    r######\" \"aa\" \"# \"## \"######;\n    //~^ needless_raw_string_hashes\n    br#\"\\aaa\"#;\n    //~^ needless_raw_string_hashes\n    br##\"Hello \"world\"!\"##;\n    //~^ needless_raw_string_hashes\n    br######\" \"### \"## \"# \"######;\n    //~^ needless_raw_string_hashes\n    br######\" \"aa\" \"# \"## \"######;\n    //~^ needless_raw_string_hashes\n    cr#\"\\aaa\"#;\n    //~^ needless_raw_string_hashes\n    cr##\"Hello \"world\"!\"##;\n    //~^ needless_raw_string_hashes\n    cr######\" \"### \"## \"# \"######;\n    //~^ needless_raw_string_hashes\n    cr######\" \"aa\" \"# \"## \"######;\n    //~^ needless_raw_string_hashes\n\n    r#\"\n    //~^ needless_raw_string_hashes\n        \\a\n        multiline\n        string\n    \"#;\n\n    r###\"rust\"###;\n    //~^ needless_raw_string_hashes\n    r#\"hello world\"#;\n    //~^ needless_raw_string_hashes\n}\n\nfn issue_13503() {\n    println!(r\"SELECT * FROM posts\");\n    println!(r#\"SELECT * FROM posts\"#);\n    //~^ needless_raw_string_hashes\n    println!(r##\"SELECT * FROM \"posts\"\"##);\n    //~^ needless_raw_string_hashes\n    println!(r##\"SELECT * FROM \"posts\"\"##);\n    //~^ needless_raw_string_hashes\n\n    // Test arguments as well\n    println!(\"{}\", r\"foobar\".len());\n}\n"
  },
  {
    "path": "tests/ui/needless_raw_string_hashes.stderr",
    "content": "error: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:5:5\n   |\nLL |     r#\"\\aaa\"#;\n   |     ^^^^^^^^^\n   |\n   = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_raw_string_hashes)]`\nhelp: remove all the hashes around the string literal\n   |\nLL -     r#\"\\aaa\"#;\nLL +     r\"\\aaa\";\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:7:5\n   |\nLL |     r##\"Hello \"world\"!\"##;\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove one hash from both sides of the string literal\n   |\nLL -     r##\"Hello \"world\"!\"##;\nLL +     r#\"Hello \"world\"!\"#;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:9:5\n   |\nLL |     r######\" \"### \"## \"# \"######;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove 2 hashes from both sides of the string literal\n   |\nLL -     r######\" \"### \"## \"# \"######;\nLL +     r####\" \"### \"## \"# \"####;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:11:5\n   |\nLL |     r######\" \"aa\" \"# \"## \"######;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove 3 hashes from both sides of the string literal\n   |\nLL -     r######\" \"aa\" \"# \"## \"######;\nLL +     r###\" \"aa\" \"# \"## \"###;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:13:5\n   |\nLL |     br#\"\\aaa\"#;\n   |     ^^^^^^^^^^\n   |\nhelp: remove all the hashes around the byte string literal\n   |\nLL -     br#\"\\aaa\"#;\nLL +     br\"\\aaa\";\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:15:5\n   |\nLL |     br##\"Hello \"world\"!\"##;\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove one hash from both sides of the byte string literal\n   |\nLL -     br##\"Hello \"world\"!\"##;\nLL +     br#\"Hello \"world\"!\"#;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:17:5\n   |\nLL |     br######\" \"### \"## \"# \"######;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove 2 hashes from both sides of the byte string literal\n   |\nLL -     br######\" \"### \"## \"# \"######;\nLL +     br####\" \"### \"## \"# \"####;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:19:5\n   |\nLL |     br######\" \"aa\" \"# \"## \"######;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove 3 hashes from both sides of the byte string literal\n   |\nLL -     br######\" \"aa\" \"# \"## \"######;\nLL +     br###\" \"aa\" \"# \"## \"###;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:21:5\n   |\nLL |     cr#\"\\aaa\"#;\n   |     ^^^^^^^^^^\n   |\nhelp: remove all the hashes around the C string literal\n   |\nLL -     cr#\"\\aaa\"#;\nLL +     cr\"\\aaa\";\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:23:5\n   |\nLL |     cr##\"Hello \"world\"!\"##;\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove one hash from both sides of the C string literal\n   |\nLL -     cr##\"Hello \"world\"!\"##;\nLL +     cr#\"Hello \"world\"!\"#;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:25:5\n   |\nLL |     cr######\" \"### \"## \"# \"######;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove 2 hashes from both sides of the C string literal\n   |\nLL -     cr######\" \"### \"## \"# \"######;\nLL +     cr####\" \"### \"## \"# \"####;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:27:5\n   |\nLL |     cr######\" \"aa\" \"# \"## \"######;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove 3 hashes from both sides of the C string literal\n   |\nLL -     cr######\" \"aa\" \"# \"## \"######;\nLL +     cr###\" \"aa\" \"# \"## \"###;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:30:5\n   |\nLL | /     r#\"\nLL | |\nLL | |         \\a\nLL | |         multiline\nLL | |         string\nLL | |     \"#;\n   | |______^\n   |\nhelp: remove all the hashes around the string literal\n   |\nLL ~     r\"\nLL |\n...\nLL |         string\nLL ~     \";\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:37:5\n   |\nLL |     r###\"rust\"###;\n   |     ^^^^^^^^^^^^^\n   |\nhelp: remove all the hashes around the string literal\n   |\nLL -     r###\"rust\"###;\nLL +     r\"rust\";\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:39:5\n   |\nLL |     r#\"hello world\"#;\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: remove all the hashes around the string literal\n   |\nLL -     r#\"hello world\"#;\nLL +     r\"hello world\";\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:45:14\n   |\nLL |     println!(r#\"SELECT * FROM posts\"#);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove all the hashes around the string literal\n   |\nLL -     println!(r#\"SELECT * FROM posts\"#);\nLL +     println!(r\"SELECT * FROM posts\");\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:47:14\n   |\nLL |     println!(r##\"SELECT * FROM \"posts\"\"##);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove one hash from both sides of the string literal\n   |\nLL -     println!(r##\"SELECT * FROM \"posts\"\"##);\nLL +     println!(r#\"SELECT * FROM \"posts\"\"#);\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui/needless_raw_string_hashes.rs:49:14\n   |\nLL |     println!(r##\"SELECT * FROM \"posts\"\"##);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove one hash from both sides of the string literal\n   |\nLL -     println!(r##\"SELECT * FROM \"posts\"\"##);\nLL +     println!(r#\"SELECT * FROM \"posts\"\"#);\n   |\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_return.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![feature(yeet_expr)]\n#![allow(unused)]\n#![allow(\n    clippy::if_same_then_else,\n    clippy::single_match,\n    clippy::needless_bool,\n    clippy::equatable_if_let,\n    clippy::needless_else,\n    clippy::missing_safety_doc\n)]\n#![warn(clippy::needless_return)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nuse std::cell::RefCell;\n\nmacro_rules! the_answer {\n    () => {\n        42\n    };\n}\n\nfn test_end_of_fn() -> bool {\n    if true {\n        // no error!\n        return true;\n    }\n    true\n    //~^ needless_return\n}\n\nfn test_no_semicolon() -> bool {\n    true\n    //~^ needless_return\n}\n\n#[rustfmt::skip]\nfn test_multiple_semicolon() -> bool {\n    true\n    //~^ needless_return\n}\n\n#[rustfmt::skip]\nfn test_multiple_semicolon_with_spaces() -> bool {\n    true\n    //~^ needless_return\n}\n\nfn test_if_block() -> bool {\n    if true {\n        true\n        //~^ needless_return\n    } else {\n        false\n        //~^ needless_return\n    }\n}\n\nfn test_match(x: bool) -> bool {\n    match x {\n        true => false,\n        //~^ needless_return\n        false => {\n            true\n            //~^ needless_return\n        },\n    }\n}\n\nfn test_closure() {\n    let _ = || {\n        true\n        //~^ needless_return\n    };\n    let _ = || true;\n    //~^ needless_return\n}\n\nfn test_macro_call() -> i32 {\n    the_answer!()\n    //~^ needless_return\n}\n\nfn test_void_fun() {\n    //~^ needless_return\n}\n\nfn test_void_if_fun(b: bool) {\n    if b {\n        //~^ needless_return\n    } else {\n        //~^ needless_return\n    }\n}\n\nfn test_void_match(x: u32) {\n    match x {\n        0 => (),\n        _ => (),\n        //~^ needless_return\n    }\n}\n\nfn test_nested_match(x: u32) {\n    match x {\n        0 => (),\n        1 => {\n            let _ = 42;\n            //~^ needless_return\n        },\n        _ => (),\n        //~^ needless_return\n    }\n}\n\nfn temporary_outlives_local() -> String {\n    let x = RefCell::<String>::default();\n    return x.borrow().clone();\n}\n\nfn borrows_but_not_last(value: bool) -> String {\n    if value {\n        let x = RefCell::<String>::default();\n        let _a = x.borrow().clone();\n        String::from(\"test\")\n        //~^ needless_return\n    } else {\n        String::new()\n        //~^ needless_return\n    }\n}\n\nmacro_rules! needed_return {\n    ($e:expr) => {\n        if $e > 3 {\n            return;\n        }\n    };\n}\n\nfn test_return_in_macro() {\n    // This will return and the macro below won't be executed. Removing the `return` from the macro\n    // will change semantics.\n    needed_return!(10);\n    needed_return!(0);\n}\n\nmod issue6501 {\n    #[allow(clippy::unnecessary_lazy_evaluations)]\n    fn foo(bar: Result<(), ()>) {\n        bar.unwrap_or_else(|_| {})\n        //~^ needless_return\n    }\n\n    fn test_closure() {\n        let _ = || {\n            //~^ needless_return\n        };\n        let _ = || {};\n        //~^ needless_return\n    }\n\n    struct Foo;\n    #[allow(clippy::unnecessary_lazy_evaluations)]\n    fn bar(res: Result<Foo, u8>) -> Foo {\n        res.unwrap_or_else(|_| Foo)\n        //~^ needless_return\n    }\n}\n\nasync fn async_test_end_of_fn() -> bool {\n    if true {\n        // no error!\n        return true;\n    }\n    true\n    //~^ needless_return\n}\n\nasync fn async_test_no_semicolon() -> bool {\n    true\n    //~^ needless_return\n}\n\nasync fn async_test_if_block() -> bool {\n    if true {\n        true\n        //~^ needless_return\n    } else {\n        false\n        //~^ needless_return\n    }\n}\n\nasync fn async_test_match(x: bool) -> bool {\n    match x {\n        true => false,\n        //~^ needless_return\n        false => {\n            true\n            //~^ needless_return\n        },\n    }\n}\n\nasync fn async_test_closure() {\n    let _ = || {\n        true\n        //~^ needless_return\n    };\n    let _ = || true;\n    //~^ needless_return\n}\n\nasync fn async_test_macro_call() -> i32 {\n    the_answer!()\n    //~^ needless_return\n}\n\nasync fn async_test_void_fun() {\n    //~^ needless_return\n}\n\nasync fn async_test_void_if_fun(b: bool) {\n    if b {\n        //~^ needless_return\n    } else {\n        //~^ needless_return\n    }\n}\n\nasync fn async_test_void_match(x: u32) {\n    match x {\n        0 => (),\n        _ => (),\n        //~^ needless_return\n    }\n}\n\nasync fn async_temporary_outlives_local() -> String {\n    let x = RefCell::<String>::default();\n    return x.borrow().clone();\n}\n\nasync fn async_borrows_but_not_last(value: bool) -> String {\n    if value {\n        let x = RefCell::<String>::default();\n        let _a = x.borrow().clone();\n        String::from(\"test\")\n        //~^ needless_return\n    } else {\n        String::new()\n        //~^ needless_return\n    }\n}\n\nasync fn async_test_return_in_macro() {\n    needed_return!(10);\n    needed_return!(0);\n}\n\nfn let_else() {\n    let Some(1) = Some(1) else { return };\n}\n\nfn needless_return_macro() -> String {\n    let _ = \"foo\";\n    let _ = \"bar\";\n    format!(\"Hello {}\", \"world!\")\n    //~^ needless_return\n}\n\nfn issue_9361(n: i32) -> i32 {\n    #[expect(clippy::arithmetic_side_effects)]\n    return n + n;\n}\n\nmod issue_12998 {\n    fn expect_lint() -> i32 {\n        let x = 1;\n\n        #[expect(clippy::needless_return)]\n        return x;\n    }\n\n    fn expect_group() -> i32 {\n        let x = 1;\n\n        #[expect(clippy::style)]\n        return x;\n    }\n\n    fn expect_all() -> i32 {\n        let x = 1;\n\n        #[expect(clippy::all)]\n        return x;\n    }\n\n    fn expect_warnings() -> i32 {\n        let x = 1;\n\n        #[expect(warnings)]\n        return x;\n    }\n}\n\nfn issue8336(x: i32) -> bool {\n    if x > 0 {\n        println!(\"something\");\n        true\n        //~^ needless_return\n    } else {\n        false\n        //~^ needless_return\n    }\n}\n\nfn issue8156(x: u8) -> u64 {\n    match x {\n        80 => {\n            10\n            //~^ needless_return\n        },\n        _ => {\n            100\n            //~^ needless_return\n        },\n    }\n}\n\n// Ideally the compiler should throw `unused_braces` in this case\nfn issue9192() -> i32 {\n    {\n        0\n        //~^ needless_return\n    }\n}\n\nfn issue9503(x: usize) -> isize {\n    unsafe {\n        if x > 12 {\n            *(x as *const isize)\n            //~^ needless_return\n        } else {\n            !*(x as *const isize)\n            //~^ needless_return\n        }\n    }\n}\n\nmod issue9416 {\n    pub fn with_newline() {\n        let _ = 42;\n        //~^ needless_return\n    }\n\n    #[rustfmt::skip]\n    pub fn oneline() {\n        let _ = 42;\n        //~^ needless_return\n    }\n}\n\nfn issue9947() -> Result<(), String> {\n    do yeet \"hello\";\n}\n\n// without anyhow, but triggers the same bug I believe\n#[expect(clippy::useless_format)]\nfn issue10051() -> Result<String, String> {\n    if true {\n        Ok(format!(\"ok!\"))\n        //~^ needless_return\n    } else {\n        Err(format!(\"err!\"))\n        //~^ needless_return\n    }\n}\n\nmod issue10049 {\n    fn single() -> u32 {\n        if true { 1 } else { 2 }\n        //~^ needless_return\n    }\n\n    fn multiple(b1: bool, b2: bool, b3: bool) -> u32 {\n        (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 })\n        //~^ needless_return\n    }\n}\n\nfn test_match_as_stmt() {\n    let x = 9;\n    match x {\n        1 => 2,\n        2 => return,\n        _ => 0,\n    };\n}\n\nfn allow_works() -> i32 {\n    #[allow(clippy::needless_return, clippy::match_single_binding)]\n    match () {\n        () => return 42,\n    }\n}\n\nfn conjunctive_blocks() -> String {\n    ({ \"a\".to_string() } + \"b\" + { \"c\" })\n    //~^ needless_return\n}\n\nfn issue12907() -> String {\n    \"\".split(\"\").next().unwrap().to_string()\n    //~^ needless_return\n}\n\nfn issue13458() {\n    with_span!(span return);\n}\n\nfn main() {}\n\nfn a(x: Option<u8>) -> Option<u8> {\n    match x {\n        Some(_) => None,\n        None => {\n            #[expect(clippy::needless_return, reason = \"Use early return for errors.\")]\n            return None;\n        },\n    }\n}\n\nfn b(x: Option<u8>) -> Option<u8> {\n    match x {\n        Some(_) => None,\n        None => {\n            #[expect(clippy::needless_return)]\n            return None;\n        },\n    }\n}\n\nunsafe fn todo() -> *const u8 {\n    todo!()\n}\n\npub unsafe fn issue_12157() -> *const i32 {\n    (unsafe { todo() } as *const i32)\n    //~^ needless_return\n}\n\nmod else_ifs {\n    fn test1(a: i32) -> u32 {\n        if a == 0 {\n            1\n        //~^ needless_return\n        } else if a < 10 {\n            2\n        //~^ needless_return\n        } else {\n            3\n            //~^ needless_return\n        }\n    }\n\n    fn test2(a: i32) -> u32 {\n        if a == 0 {\n            1\n        //~^ needless_return\n        } else if a < 10 {\n            2\n        } else {\n            3\n            //~^ needless_return\n        }\n    }\n\n    fn test3(a: i32) -> u32 {\n        if a == 0 {\n            1\n        //~^ needless_return\n        } else if a < 10 {\n            2\n        } else {\n            3\n            //~^ needless_return\n        }\n    }\n\n    #[allow(clippy::match_single_binding, clippy::redundant_pattern)]\n    fn test4(a: i32) -> u32 {\n        if a == 0 {\n            1\n            //~^ needless_return\n        } else if if if a > 0x1_1 {\n            return 2;\n        } else {\n            return 5;\n        } {\n            true\n        } else {\n            true\n        } {\n            0xDEADC0DE\n        } else if match a {\n            b @ _ => {\n                return 1;\n            },\n        } {\n            0xDEADBEEF\n        } else {\n            1\n        }\n    }\n}\n\nfn issue14474() -> u64 {\n    return 456;\n\n    #[cfg(false)]\n    123\n}\n"
  },
  {
    "path": "tests/ui/needless_return.rs",
    "content": "//@aux-build:proc_macros.rs\n#![feature(yeet_expr)]\n#![allow(unused)]\n#![allow(\n    clippy::if_same_then_else,\n    clippy::single_match,\n    clippy::needless_bool,\n    clippy::equatable_if_let,\n    clippy::needless_else,\n    clippy::missing_safety_doc\n)]\n#![warn(clippy::needless_return)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nuse std::cell::RefCell;\n\nmacro_rules! the_answer {\n    () => {\n        42\n    };\n}\n\nfn test_end_of_fn() -> bool {\n    if true {\n        // no error!\n        return true;\n    }\n    return true;\n    //~^ needless_return\n}\n\nfn test_no_semicolon() -> bool {\n    return true;\n    //~^ needless_return\n}\n\n#[rustfmt::skip]\nfn test_multiple_semicolon() -> bool {\n    return true;;;\n    //~^ needless_return\n}\n\n#[rustfmt::skip]\nfn test_multiple_semicolon_with_spaces() -> bool {\n    return true;; ; ;\n    //~^ needless_return\n}\n\nfn test_if_block() -> bool {\n    if true {\n        return true;\n        //~^ needless_return\n    } else {\n        return false;\n        //~^ needless_return\n    }\n}\n\nfn test_match(x: bool) -> bool {\n    match x {\n        true => return false,\n        //~^ needless_return\n        false => {\n            return true;\n            //~^ needless_return\n        },\n    }\n}\n\nfn test_closure() {\n    let _ = || {\n        return true;\n        //~^ needless_return\n    };\n    let _ = || return true;\n    //~^ needless_return\n}\n\nfn test_macro_call() -> i32 {\n    return the_answer!();\n    //~^ needless_return\n}\n\nfn test_void_fun() {\n    return;\n    //~^ needless_return\n}\n\nfn test_void_if_fun(b: bool) {\n    if b {\n        return;\n        //~^ needless_return\n    } else {\n        return;\n        //~^ needless_return\n    }\n}\n\nfn test_void_match(x: u32) {\n    match x {\n        0 => (),\n        _ => return,\n        //~^ needless_return\n    }\n}\n\nfn test_nested_match(x: u32) {\n    match x {\n        0 => (),\n        1 => {\n            let _ = 42;\n            return;\n            //~^ needless_return\n        },\n        _ => return,\n        //~^ needless_return\n    }\n}\n\nfn temporary_outlives_local() -> String {\n    let x = RefCell::<String>::default();\n    return x.borrow().clone();\n}\n\nfn borrows_but_not_last(value: bool) -> String {\n    if value {\n        let x = RefCell::<String>::default();\n        let _a = x.borrow().clone();\n        return String::from(\"test\");\n        //~^ needless_return\n    } else {\n        return String::new();\n        //~^ needless_return\n    }\n}\n\nmacro_rules! needed_return {\n    ($e:expr) => {\n        if $e > 3 {\n            return;\n        }\n    };\n}\n\nfn test_return_in_macro() {\n    // This will return and the macro below won't be executed. Removing the `return` from the macro\n    // will change semantics.\n    needed_return!(10);\n    needed_return!(0);\n}\n\nmod issue6501 {\n    #[allow(clippy::unnecessary_lazy_evaluations)]\n    fn foo(bar: Result<(), ()>) {\n        bar.unwrap_or_else(|_| return)\n        //~^ needless_return\n    }\n\n    fn test_closure() {\n        let _ = || {\n            return;\n            //~^ needless_return\n        };\n        let _ = || return;\n        //~^ needless_return\n    }\n\n    struct Foo;\n    #[allow(clippy::unnecessary_lazy_evaluations)]\n    fn bar(res: Result<Foo, u8>) -> Foo {\n        res.unwrap_or_else(|_| return Foo)\n        //~^ needless_return\n    }\n}\n\nasync fn async_test_end_of_fn() -> bool {\n    if true {\n        // no error!\n        return true;\n    }\n    return true;\n    //~^ needless_return\n}\n\nasync fn async_test_no_semicolon() -> bool {\n    return true;\n    //~^ needless_return\n}\n\nasync fn async_test_if_block() -> bool {\n    if true {\n        return true;\n        //~^ needless_return\n    } else {\n        return false;\n        //~^ needless_return\n    }\n}\n\nasync fn async_test_match(x: bool) -> bool {\n    match x {\n        true => return false,\n        //~^ needless_return\n        false => {\n            return true;\n            //~^ needless_return\n        },\n    }\n}\n\nasync fn async_test_closure() {\n    let _ = || {\n        return true;\n        //~^ needless_return\n    };\n    let _ = || return true;\n    //~^ needless_return\n}\n\nasync fn async_test_macro_call() -> i32 {\n    return the_answer!();\n    //~^ needless_return\n}\n\nasync fn async_test_void_fun() {\n    return;\n    //~^ needless_return\n}\n\nasync fn async_test_void_if_fun(b: bool) {\n    if b {\n        return;\n        //~^ needless_return\n    } else {\n        return;\n        //~^ needless_return\n    }\n}\n\nasync fn async_test_void_match(x: u32) {\n    match x {\n        0 => (),\n        _ => return,\n        //~^ needless_return\n    }\n}\n\nasync fn async_temporary_outlives_local() -> String {\n    let x = RefCell::<String>::default();\n    return x.borrow().clone();\n}\n\nasync fn async_borrows_but_not_last(value: bool) -> String {\n    if value {\n        let x = RefCell::<String>::default();\n        let _a = x.borrow().clone();\n        return String::from(\"test\");\n        //~^ needless_return\n    } else {\n        return String::new();\n        //~^ needless_return\n    }\n}\n\nasync fn async_test_return_in_macro() {\n    needed_return!(10);\n    needed_return!(0);\n}\n\nfn let_else() {\n    let Some(1) = Some(1) else { return };\n}\n\nfn needless_return_macro() -> String {\n    let _ = \"foo\";\n    let _ = \"bar\";\n    return format!(\"Hello {}\", \"world!\");\n    //~^ needless_return\n}\n\nfn issue_9361(n: i32) -> i32 {\n    #[expect(clippy::arithmetic_side_effects)]\n    return n + n;\n}\n\nmod issue_12998 {\n    fn expect_lint() -> i32 {\n        let x = 1;\n\n        #[expect(clippy::needless_return)]\n        return x;\n    }\n\n    fn expect_group() -> i32 {\n        let x = 1;\n\n        #[expect(clippy::style)]\n        return x;\n    }\n\n    fn expect_all() -> i32 {\n        let x = 1;\n\n        #[expect(clippy::all)]\n        return x;\n    }\n\n    fn expect_warnings() -> i32 {\n        let x = 1;\n\n        #[expect(warnings)]\n        return x;\n    }\n}\n\nfn issue8336(x: i32) -> bool {\n    if x > 0 {\n        println!(\"something\");\n        return true;\n        //~^ needless_return\n    } else {\n        return false;\n        //~^ needless_return\n    };\n}\n\nfn issue8156(x: u8) -> u64 {\n    match x {\n        80 => {\n            return 10;\n            //~^ needless_return\n        },\n        _ => {\n            return 100;\n            //~^ needless_return\n        },\n    };\n}\n\n// Ideally the compiler should throw `unused_braces` in this case\nfn issue9192() -> i32 {\n    {\n        return 0;\n        //~^ needless_return\n    };\n}\n\nfn issue9503(x: usize) -> isize {\n    unsafe {\n        if x > 12 {\n            return *(x as *const isize);\n            //~^ needless_return\n        } else {\n            return !*(x as *const isize);\n            //~^ needless_return\n        };\n    };\n}\n\nmod issue9416 {\n    pub fn with_newline() {\n        let _ = 42;\n        return;\n        //~^ needless_return\n    }\n\n    #[rustfmt::skip]\n    pub fn oneline() {\n        let _ = 42; return;\n        //~^ needless_return\n    }\n}\n\nfn issue9947() -> Result<(), String> {\n    do yeet \"hello\";\n}\n\n// without anyhow, but triggers the same bug I believe\n#[expect(clippy::useless_format)]\nfn issue10051() -> Result<String, String> {\n    if true {\n        return Ok(format!(\"ok!\"));\n        //~^ needless_return\n    } else {\n        return Err(format!(\"err!\"));\n        //~^ needless_return\n    }\n}\n\nmod issue10049 {\n    fn single() -> u32 {\n        return if true { 1 } else { 2 };\n        //~^ needless_return\n    }\n\n    fn multiple(b1: bool, b2: bool, b3: bool) -> u32 {\n        return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };\n        //~^ needless_return\n    }\n}\n\nfn test_match_as_stmt() {\n    let x = 9;\n    match x {\n        1 => 2,\n        2 => return,\n        _ => 0,\n    };\n}\n\nfn allow_works() -> i32 {\n    #[allow(clippy::needless_return, clippy::match_single_binding)]\n    match () {\n        () => return 42,\n    }\n}\n\nfn conjunctive_blocks() -> String {\n    return { \"a\".to_string() } + \"b\" + { \"c\" };\n    //~^ needless_return\n}\n\nfn issue12907() -> String {\n    return \"\".split(\"\").next().unwrap().to_string();\n    //~^ needless_return\n}\n\nfn issue13458() {\n    with_span!(span return);\n}\n\nfn main() {}\n\nfn a(x: Option<u8>) -> Option<u8> {\n    match x {\n        Some(_) => None,\n        None => {\n            #[expect(clippy::needless_return, reason = \"Use early return for errors.\")]\n            return None;\n        },\n    }\n}\n\nfn b(x: Option<u8>) -> Option<u8> {\n    match x {\n        Some(_) => None,\n        None => {\n            #[expect(clippy::needless_return)]\n            return None;\n        },\n    }\n}\n\nunsafe fn todo() -> *const u8 {\n    todo!()\n}\n\npub unsafe fn issue_12157() -> *const i32 {\n    return unsafe { todo() } as *const i32;\n    //~^ needless_return\n}\n\nmod else_ifs {\n    fn test1(a: i32) -> u32 {\n        if a == 0 {\n            return 1;\n        //~^ needless_return\n        } else if a < 10 {\n            return 2;\n        //~^ needless_return\n        } else {\n            return 3;\n            //~^ needless_return\n        }\n    }\n\n    fn test2(a: i32) -> u32 {\n        if a == 0 {\n            return 1;\n        //~^ needless_return\n        } else if a < 10 {\n            2\n        } else {\n            return 3;\n            //~^ needless_return\n        }\n    }\n\n    fn test3(a: i32) -> u32 {\n        if a == 0 {\n            return 1;\n        //~^ needless_return\n        } else if a < 10 {\n            2\n        } else {\n            return 3;\n            //~^ needless_return\n        }\n    }\n\n    #[allow(clippy::match_single_binding, clippy::redundant_pattern)]\n    fn test4(a: i32) -> u32 {\n        if a == 0 {\n            return 1;\n            //~^ needless_return\n        } else if if if a > 0x1_1 {\n            return 2;\n        } else {\n            return 5;\n        } {\n            true\n        } else {\n            true\n        } {\n            0xDEADC0DE\n        } else if match a {\n            b @ _ => {\n                return 1;\n            },\n        } {\n            0xDEADBEEF\n        } else {\n            1\n        }\n    }\n}\n\nfn issue14474() -> u64 {\n    return 456;\n\n    #[cfg(false)]\n    123\n}\n"
  },
  {
    "path": "tests/ui/needless_return.stderr",
    "content": "error: unneeded `return` statement\n  --> tests/ui/needless_return.rs:30:5\n   |\nLL |     return true;\n   |     ^^^^^^^^^^^\n   |\n   = note: `-D clippy::needless-return` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_return)]`\nhelp: remove `return`\n   |\nLL -     return true;\nLL +     true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:35:5\n   |\nLL |     return true;\n   |     ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return true;\nLL +     true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:41:5\n   |\nLL |     return true;;;\n   |     ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return true;;;\nLL +     true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:47:5\n   |\nLL |     return true;; ; ;\n   |     ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return true;; ; ;\nLL +     true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:53:9\n   |\nLL |         return true;\n   |         ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return true;\nLL +         true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:56:9\n   |\nLL |         return false;\n   |         ^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return false;\nLL +         false\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:63:17\n   |\nLL |         true => return false,\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         true => return false,\nLL +         true => false,\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:66:13\n   |\nLL |             return true;\n   |             ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return true;\nLL +             true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:74:9\n   |\nLL |         return true;\n   |         ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return true;\nLL +         true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:77:16\n   |\nLL |     let _ = || return true;\n   |                ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     let _ = || return true;\nLL +     let _ = || true;\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:82:5\n   |\nLL |     return the_answer!();\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return the_answer!();\nLL +     the_answer!()\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:87:5\n   |\nLL |     return;\n   |     ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL - fn test_void_fun() {\nLL -     return;\nLL + fn test_void_fun() {\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:93:9\n   |\nLL |         return;\n   |         ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     if b {\nLL -         return;\nLL +     if b {\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:96:9\n   |\nLL |         return;\n   |         ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     } else {\nLL -         return;\nLL +     } else {\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:104:14\n   |\nLL |         _ => return,\n   |              ^^^^^^\n   |\nhelp: replace `return` with a unit value\n   |\nLL -         _ => return,\nLL +         _ => (),\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:114:13\n   |\nLL |             return;\n   |             ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             let _ = 42;\nLL -             return;\nLL +             let _ = 42;\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:117:14\n   |\nLL |         _ => return,\n   |              ^^^^^^\n   |\nhelp: replace `return` with a unit value\n   |\nLL -         _ => return,\nLL +         _ => (),\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:131:9\n   |\nLL |         return String::from(\"test\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return String::from(\"test\");\nLL +         String::from(\"test\")\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:134:9\n   |\nLL |         return String::new();\n   |         ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return String::new();\nLL +         String::new()\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:157:32\n   |\nLL |         bar.unwrap_or_else(|_| return)\n   |                                ^^^^^^\n   |\nhelp: replace `return` with an empty block\n   |\nLL -         bar.unwrap_or_else(|_| return)\nLL +         bar.unwrap_or_else(|_| {})\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:163:13\n   |\nLL |             return;\n   |             ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         let _ = || {\nLL -             return;\nLL +         let _ = || {\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:166:20\n   |\nLL |         let _ = || return;\n   |                    ^^^^^^\n   |\nhelp: replace `return` with an empty block\n   |\nLL -         let _ = || return;\nLL +         let _ = || {};\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:173:32\n   |\nLL |         res.unwrap_or_else(|_| return Foo)\n   |                                ^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         res.unwrap_or_else(|_| return Foo)\nLL +         res.unwrap_or_else(|_| Foo)\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:183:5\n   |\nLL |     return true;\n   |     ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return true;\nLL +     true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:188:5\n   |\nLL |     return true;\n   |     ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return true;\nLL +     true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:194:9\n   |\nLL |         return true;\n   |         ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return true;\nLL +         true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:197:9\n   |\nLL |         return false;\n   |         ^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return false;\nLL +         false\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:204:17\n   |\nLL |         true => return false,\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         true => return false,\nLL +         true => false,\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:207:13\n   |\nLL |             return true;\n   |             ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return true;\nLL +             true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:215:9\n   |\nLL |         return true;\n   |         ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return true;\nLL +         true\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:218:16\n   |\nLL |     let _ = || return true;\n   |                ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     let _ = || return true;\nLL +     let _ = || true;\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:223:5\n   |\nLL |     return the_answer!();\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return the_answer!();\nLL +     the_answer!()\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:228:5\n   |\nLL |     return;\n   |     ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL - async fn async_test_void_fun() {\nLL -     return;\nLL + async fn async_test_void_fun() {\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:234:9\n   |\nLL |         return;\n   |         ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     if b {\nLL -         return;\nLL +     if b {\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:237:9\n   |\nLL |         return;\n   |         ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     } else {\nLL -         return;\nLL +     } else {\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:245:14\n   |\nLL |         _ => return,\n   |              ^^^^^^\n   |\nhelp: replace `return` with a unit value\n   |\nLL -         _ => return,\nLL +         _ => (),\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:259:9\n   |\nLL |         return String::from(\"test\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return String::from(\"test\");\nLL +         String::from(\"test\")\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:262:9\n   |\nLL |         return String::new();\n   |         ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return String::new();\nLL +         String::new()\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:279:5\n   |\nLL |     return format!(\"Hello {}\", \"world!\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return format!(\"Hello {}\", \"world!\");\nLL +     format!(\"Hello {}\", \"world!\")\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:321:9\n   |\nLL |         return true;\n   |         ^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL ~         true\nLL |\n...\nLL |\nLL ~     }\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:324:9\n   |\nLL |         return false;\n   |         ^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL ~         false\nLL |\nLL ~     }\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:332:13\n   |\nLL |             return 10;\n   |             ^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL ~             10\nLL |\n...\nLL |         },\nLL ~     }\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:336:13\n   |\nLL |             return 100;\n   |             ^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL ~             100\nLL |\nLL |         },\nLL ~     }\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:345:9\n   |\nLL |         return 0;\n   |         ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL ~         0\nLL |\nLL ~     }\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:353:13\n   |\nLL |             return *(x as *const isize);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL ~             *(x as *const isize)\nLL |\n...\nLL |\nLL ~         }\nLL ~     }\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:356:13\n   |\nLL |             return !*(x as *const isize);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL ~             !*(x as *const isize)\nLL |\nLL ~         }\nLL ~     }\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:365:9\n   |\nLL |         return;\n   |         ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         let _ = 42;\nLL -         return;\nLL +         let _ = 42;\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:371:21\n   |\nLL |         let _ = 42; return;\n   |                     ^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         let _ = 42; return;\nLL +         let _ = 42;\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:384:9\n   |\nLL |         return Ok(format!(\"ok!\"));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return Ok(format!(\"ok!\"));\nLL +         Ok(format!(\"ok!\"))\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:387:9\n   |\nLL |         return Err(format!(\"err!\"));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return Err(format!(\"err!\"));\nLL +         Err(format!(\"err!\"))\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:394:9\n   |\nLL |         return if true { 1 } else { 2 };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -         return if true { 1 } else { 2 };\nLL +         if true { 1 } else { 2 }\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:399:9\n   |\nLL |         return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return` and wrap the sequence with parentheses\n   |\nLL -         return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };\nLL +         (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 })\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:421:5\n   |\nLL |     return { \"a\".to_string() } + \"b\" + { \"c\" };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return` and wrap the sequence with parentheses\n   |\nLL -     return { \"a\".to_string() } + \"b\" + { \"c\" };\nLL +     ({ \"a\".to_string() } + \"b\" + { \"c\" })\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:426:5\n   |\nLL |     return \"\".split(\"\").next().unwrap().to_string();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -     return \"\".split(\"\").next().unwrap().to_string();\nLL +     \"\".split(\"\").next().unwrap().to_string()\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:461:5\n   |\nLL |     return unsafe { todo() } as *const i32;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `return` and wrap the sequence with parentheses\n   |\nLL -     return unsafe { todo() } as *const i32;\nLL +     (unsafe { todo() } as *const i32)\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:468:13\n   |\nLL |             return 1;\n   |             ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return 1;\nLL +             1\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:471:13\n   |\nLL |             return 2;\n   |             ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return 2;\nLL +             2\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:474:13\n   |\nLL |             return 3;\n   |             ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return 3;\nLL +             3\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:481:13\n   |\nLL |             return 1;\n   |             ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return 1;\nLL +             1\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:486:13\n   |\nLL |             return 3;\n   |             ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return 3;\nLL +             3\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:493:13\n   |\nLL |             return 1;\n   |             ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return 1;\nLL +             1\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:498:13\n   |\nLL |             return 3;\n   |             ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return 3;\nLL +             3\n   |\n\nerror: unneeded `return` statement\n  --> tests/ui/needless_return.rs:506:13\n   |\nLL |             return 1;\n   |             ^^^^^^^^\n   |\nhelp: remove `return`\n   |\nLL -             return 1;\nLL +             1\n   |\n\nerror: aborting due to 63 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_return_with_question_mark.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    clippy::needless_return,\n    clippy::no_effect,\n    clippy::unit_arg,\n    clippy::useless_conversion,\n    clippy::diverging_sub_expression,\n    clippy::let_unit_value,\n    unused\n)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn a() -> u32 {\n    return 0;\n}\n\nfn b() -> Result<u32, u32> {\n    return Err(0);\n}\n\n// Do not lint\nfn c() -> Option<()> {\n    return None?;\n}\n\nfn main() -> Result<(), ()> {\n    Err(())?;\n    //~^ needless_return_with_question_mark\n    return Ok::<(), ()>(());\n    Err(())?;\n    Ok::<(), ()>(());\n    return Err(().into());\n    external! {\n        return Err(())?;\n    }\n    with_span! {\n        return Err(())?;\n    }\n\n    // Issue #11765\n    // Should not lint\n    let Some(s) = Some(\"\") else {\n        return Err(())?;\n    };\n\n    let Some(s) = Some(\"\") else {\n        let Some(s) = Some(\"\") else {\n            return Err(())?;\n        };\n\n        return Err(())?;\n    };\n\n    let Some(_): Option<()> = ({\n        return Err(())?;\n    }) else {\n        panic!();\n    };\n\n    Err(())\n}\n\nfn issue11616() -> Result<(), ()> {\n    let _x: String = {\n        return Err(())?;\n    };\n    let _x: () = {\n        Err(())?;\n        //~^ ERROR: unneeded `return` statement with `?` operator\n    };\n    let _x = match 1 {\n        1 => vec![1, 2],\n        _ => {\n            return Err(())?;\n        },\n    };\n    Ok(())\n}\n\nfn issue11982() {\n    mod bar {\n        pub struct Error;\n        pub fn foo(_: bool) -> Result<(), Error> {\n            Ok(())\n        }\n    }\n\n    pub struct Error;\n\n    impl From<bar::Error> for Error {\n        fn from(_: bar::Error) -> Self {\n            Error\n        }\n    }\n\n    fn foo(ok: bool) -> Result<(), Error> {\n        if !ok {\n            return bar::foo(ok).map(|_| Ok::<(), Error>(()))?;\n        };\n        Ok(())\n    }\n}\n\nfn issue11982_no_conversion() {\n    mod bar {\n        pub struct Error;\n        pub fn foo(_: bool) -> Result<(), Error> {\n            Ok(())\n        }\n    }\n\n    fn foo(ok: bool) -> Result<(), bar::Error> {\n        if !ok {\n            return bar::foo(ok).map(|_| Ok::<(), bar::Error>(()))?;\n        };\n        Ok(())\n    }\n}\n\nfn general_return() {\n    fn foo(ok: bool) -> Result<(), ()> {\n        let bar = Result::Ok(Result::<(), ()>::Ok(()));\n        if !ok {\n            return bar?;\n        };\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_return_with_question_mark.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(\n    clippy::needless_return,\n    clippy::no_effect,\n    clippy::unit_arg,\n    clippy::useless_conversion,\n    clippy::diverging_sub_expression,\n    clippy::let_unit_value,\n    unused\n)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn a() -> u32 {\n    return 0;\n}\n\nfn b() -> Result<u32, u32> {\n    return Err(0);\n}\n\n// Do not lint\nfn c() -> Option<()> {\n    return None?;\n}\n\nfn main() -> Result<(), ()> {\n    return Err(())?;\n    //~^ needless_return_with_question_mark\n    return Ok::<(), ()>(());\n    Err(())?;\n    Ok::<(), ()>(());\n    return Err(().into());\n    external! {\n        return Err(())?;\n    }\n    with_span! {\n        return Err(())?;\n    }\n\n    // Issue #11765\n    // Should not lint\n    let Some(s) = Some(\"\") else {\n        return Err(())?;\n    };\n\n    let Some(s) = Some(\"\") else {\n        let Some(s) = Some(\"\") else {\n            return Err(())?;\n        };\n\n        return Err(())?;\n    };\n\n    let Some(_): Option<()> = ({\n        return Err(())?;\n    }) else {\n        panic!();\n    };\n\n    Err(())\n}\n\nfn issue11616() -> Result<(), ()> {\n    let _x: String = {\n        return Err(())?;\n    };\n    let _x: () = {\n        return Err(())?;\n        //~^ ERROR: unneeded `return` statement with `?` operator\n    };\n    let _x = match 1 {\n        1 => vec![1, 2],\n        _ => {\n            return Err(())?;\n        },\n    };\n    Ok(())\n}\n\nfn issue11982() {\n    mod bar {\n        pub struct Error;\n        pub fn foo(_: bool) -> Result<(), Error> {\n            Ok(())\n        }\n    }\n\n    pub struct Error;\n\n    impl From<bar::Error> for Error {\n        fn from(_: bar::Error) -> Self {\n            Error\n        }\n    }\n\n    fn foo(ok: bool) -> Result<(), Error> {\n        if !ok {\n            return bar::foo(ok).map(|_| Ok::<(), Error>(()))?;\n        };\n        Ok(())\n    }\n}\n\nfn issue11982_no_conversion() {\n    mod bar {\n        pub struct Error;\n        pub fn foo(_: bool) -> Result<(), Error> {\n            Ok(())\n        }\n    }\n\n    fn foo(ok: bool) -> Result<(), bar::Error> {\n        if !ok {\n            return bar::foo(ok).map(|_| Ok::<(), bar::Error>(()))?;\n        };\n        Ok(())\n    }\n}\n\nfn general_return() {\n    fn foo(ok: bool) -> Result<(), ()> {\n        let bar = Result::Ok(Result::<(), ()>::Ok(()));\n        if !ok {\n            return bar?;\n        };\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "tests/ui/needless_return_with_question_mark.stderr",
    "content": "error: unneeded `return` statement with `?` operator\n  --> tests/ui/needless_return_with_question_mark.rs:29:5\n   |\nLL |     return Err(())?;\n   |     ^^^^^^^ help: remove it\n   |\n   = note: `-D clippy::needless-return-with-question-mark` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_return_with_question_mark)]`\n\nerror: unneeded `return` statement with `?` operator\n  --> tests/ui/needless_return_with_question_mark.rs:70:9\n   |\nLL |         return Err(())?;\n   |         ^^^^^^^ help: remove it\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_splitn.fixed",
    "content": "//@edition:2018\n\n#![warn(clippy::needless_splitn)]\n#![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::manual_split_once)]\n\nextern crate itertools;\n\n#[allow(unused_imports)]\nuse itertools::Itertools;\n\nfn main() {\n    let str = \"key=value=end\";\n    let _ = str.split('=').next();\n    //~^ needless_splitn\n    let _ = str.split('=').nth(0);\n    //~^ needless_splitn\n    let _ = str.splitn(2, '=').nth(1);\n    let (_, _) = str.splitn(2, '=').next_tuple().unwrap();\n    let (_, _) = str.split('=').next_tuple().unwrap();\n    //~^ needless_splitn\n    let _: Vec<&str> = str.splitn(3, '=').collect();\n\n    let _ = str.rsplit('=').next();\n    //~^ needless_splitn\n    let _ = str.rsplit('=').nth(0);\n    //~^ needless_splitn\n    let _ = str.rsplitn(2, '=').nth(1);\n    let (_, _) = str.rsplitn(2, '=').next_tuple().unwrap();\n    let (_, _) = str.rsplit('=').next_tuple().unwrap();\n    //~^ needless_splitn\n\n    let _ = str.split('=').next();\n    //~^ needless_splitn\n    let _ = str.split('=').nth(3);\n    //~^ needless_splitn\n    let _ = str.splitn(5, '=').nth(4);\n    let _ = str.splitn(5, '=').nth(5);\n}\n\nfn _question_mark(s: &str) -> Option<()> {\n    let _ = s.split('=').next()?;\n    //~^ needless_splitn\n    let _ = s.split('=').nth(0)?;\n    //~^ needless_splitn\n    let _ = s.rsplit('=').next()?;\n    //~^ needless_splitn\n    let _ = s.rsplit('=').nth(0)?;\n    //~^ needless_splitn\n\n    Some(())\n}\n\n#[clippy::msrv = \"1.51\"]\nfn _test_msrv() {\n    // `manual_split_once` MSRV shouldn't apply to `needless_splitn`\n    let _ = \"key=value\".split('=').nth(0).unwrap();\n    //~^ needless_splitn\n}\n"
  },
  {
    "path": "tests/ui/needless_splitn.rs",
    "content": "//@edition:2018\n\n#![warn(clippy::needless_splitn)]\n#![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::manual_split_once)]\n\nextern crate itertools;\n\n#[allow(unused_imports)]\nuse itertools::Itertools;\n\nfn main() {\n    let str = \"key=value=end\";\n    let _ = str.splitn(2, '=').next();\n    //~^ needless_splitn\n    let _ = str.splitn(2, '=').nth(0);\n    //~^ needless_splitn\n    let _ = str.splitn(2, '=').nth(1);\n    let (_, _) = str.splitn(2, '=').next_tuple().unwrap();\n    let (_, _) = str.splitn(3, '=').next_tuple().unwrap();\n    //~^ needless_splitn\n    let _: Vec<&str> = str.splitn(3, '=').collect();\n\n    let _ = str.rsplitn(2, '=').next();\n    //~^ needless_splitn\n    let _ = str.rsplitn(2, '=').nth(0);\n    //~^ needless_splitn\n    let _ = str.rsplitn(2, '=').nth(1);\n    let (_, _) = str.rsplitn(2, '=').next_tuple().unwrap();\n    let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap();\n    //~^ needless_splitn\n\n    let _ = str.splitn(5, '=').next();\n    //~^ needless_splitn\n    let _ = str.splitn(5, '=').nth(3);\n    //~^ needless_splitn\n    let _ = str.splitn(5, '=').nth(4);\n    let _ = str.splitn(5, '=').nth(5);\n}\n\nfn _question_mark(s: &str) -> Option<()> {\n    let _ = s.splitn(2, '=').next()?;\n    //~^ needless_splitn\n    let _ = s.splitn(2, '=').nth(0)?;\n    //~^ needless_splitn\n    let _ = s.rsplitn(2, '=').next()?;\n    //~^ needless_splitn\n    let _ = s.rsplitn(2, '=').nth(0)?;\n    //~^ needless_splitn\n\n    Some(())\n}\n\n#[clippy::msrv = \"1.51\"]\nfn _test_msrv() {\n    // `manual_split_once` MSRV shouldn't apply to `needless_splitn`\n    let _ = \"key=value\".splitn(2, '=').nth(0).unwrap();\n    //~^ needless_splitn\n}\n"
  },
  {
    "path": "tests/ui/needless_splitn.stderr",
    "content": "error: unnecessary use of `splitn`\n  --> tests/ui/needless_splitn.rs:13:13\n   |\nLL |     let _ = str.splitn(2, '=').next();\n   |             ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`\n   |\n   = note: `-D clippy::needless-splitn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_splitn)]`\n\nerror: unnecessary use of `splitn`\n  --> tests/ui/needless_splitn.rs:15:13\n   |\nLL |     let _ = str.splitn(2, '=').nth(0);\n   |             ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`\n\nerror: unnecessary use of `splitn`\n  --> tests/ui/needless_splitn.rs:19:18\n   |\nLL |     let (_, _) = str.splitn(3, '=').next_tuple().unwrap();\n   |                  ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`\n\nerror: unnecessary use of `rsplitn`\n  --> tests/ui/needless_splitn.rs:23:13\n   |\nLL |     let _ = str.rsplitn(2, '=').next();\n   |             ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')`\n\nerror: unnecessary use of `rsplitn`\n  --> tests/ui/needless_splitn.rs:25:13\n   |\nLL |     let _ = str.rsplitn(2, '=').nth(0);\n   |             ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')`\n\nerror: unnecessary use of `rsplitn`\n  --> tests/ui/needless_splitn.rs:29:18\n   |\nLL |     let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap();\n   |                  ^^^^^^^^^^^^^^^^^^^ help: try: `str.rsplit('=')`\n\nerror: unnecessary use of `splitn`\n  --> tests/ui/needless_splitn.rs:32:13\n   |\nLL |     let _ = str.splitn(5, '=').next();\n   |             ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`\n\nerror: unnecessary use of `splitn`\n  --> tests/ui/needless_splitn.rs:34:13\n   |\nLL |     let _ = str.splitn(5, '=').nth(3);\n   |             ^^^^^^^^^^^^^^^^^^ help: try: `str.split('=')`\n\nerror: unnecessary use of `splitn`\n  --> tests/ui/needless_splitn.rs:41:13\n   |\nLL |     let _ = s.splitn(2, '=').next()?;\n   |             ^^^^^^^^^^^^^^^^ help: try: `s.split('=')`\n\nerror: unnecessary use of `splitn`\n  --> tests/ui/needless_splitn.rs:43:13\n   |\nLL |     let _ = s.splitn(2, '=').nth(0)?;\n   |             ^^^^^^^^^^^^^^^^ help: try: `s.split('=')`\n\nerror: unnecessary use of `rsplitn`\n  --> tests/ui/needless_splitn.rs:45:13\n   |\nLL |     let _ = s.rsplitn(2, '=').next()?;\n   |             ^^^^^^^^^^^^^^^^^ help: try: `s.rsplit('=')`\n\nerror: unnecessary use of `rsplitn`\n  --> tests/ui/needless_splitn.rs:47:13\n   |\nLL |     let _ = s.rsplitn(2, '=').nth(0)?;\n   |             ^^^^^^^^^^^^^^^^^ help: try: `s.rsplit('=')`\n\nerror: unnecessary use of `splitn`\n  --> tests/ui/needless_splitn.rs:56:13\n   |\nLL |     let _ = \"key=value\".splitn(2, '=').nth(0).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"key=value\".split('=')`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_type_cast.fixed",
    "content": "#![warn(clippy::needless_type_cast)]\n#![allow(clippy::no_effect, clippy::unnecessary_cast, unused)]\n\nfn takes_i32(x: i32) -> i32 {\n    x\n}\n\nfn generic<T>(x: T) -> T {\n    x\n}\n\nfn returns_u8() -> u8 {\n    10\n}\n\nfn main() {\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    let _ = a as i32 + 5;\n    let _ = a as i32 * 2;\n\n    let b: u16 = 20;\n    let _ = b;\n    let _ = b as u32;\n\n    let c: u8 = 5;\n    let _ = c as u16;\n    let _ = c as u32;\n\n    let d: i32 = 100;\n    let _ = d + 1;\n\n    let e = 42u8;\n    let _ = e as i64;\n    let _ = e as i64 + 10;\n\n    let f: usize = 1;\n    //~^ needless_type_cast\n    let _ = f as usize;\n}\n\nfn test_function_call() {\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    let _ = takes_i32(a as i32);\n    let _ = takes_i32(a as i32);\n}\n\nfn test_generic_call() {\n    let a: u8 = 10;\n    let _ = generic(a as i32);\n    let _ = generic(a as i32);\n}\n\nfn test_method_on_cast() {\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    let _ = (a as i32).checked_add(5);\n    let _ = (a as i32).saturating_mul(2);\n}\n\nfn test_iterator_sum() {\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    let arr = [a as i32, a as i32];\n    let _: i32 = arr.iter().copied().sum();\n}\n\nfn test_closure() {\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    let _: i32 = [1i32, 2].iter().map(|x| x + a as i32).sum();\n}\n\nfn test_struct_field() {\n    struct S {\n        x: i32,\n        y: i32,\n    }\n\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    let _ = S {\n        x: a as i32,\n        y: a as i32,\n    };\n}\n\nfn test_option() {\n    let a: u8 = 10;\n    let _: Option<i32> = Some(a as i32);\n    let _: Option<i32> = Some(a as i32);\n}\n\nfn test_mixed_context() {\n    let a: u8 = 10;\n    let _ = takes_i32(a as i32);\n    let _ = generic(a as i32);\n}\n\nfn test_nested_block() {\n    if true {\n        let a: i32 = 10;\n        //~^ needless_type_cast\n        let _ = a as i32 + 1;\n        let _ = a as i32 * 2;\n    }\n}\n\nfn test_match_expr() {\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    let _ = match 1 {\n        1 => a as i32,\n        _ => a as i32,\n    };\n}\n\nfn test_return_expr() -> i32 {\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    a as i32\n}\n\nfn test_closure_always_cast() {\n    let a: i32 = 10;\n    //~^ needless_type_cast\n    let _ = [1, 2].iter().map(|_| a as i32).sum::<i32>();\n    let _ = a as i32;\n}\n\nfn test_closure_mixed_usage() {\n    let a: u8 = 10;\n    let _ = [1, 2].iter().map(|_| a as i32).sum::<i32>();\n    let _ = a + 1;\n}\n\nfn test_nested_generic_call() {\n    let a: u8 = 10;\n    let _ = generic(takes_i32(a as i32));\n    let _ = generic(takes_i32(a as i32));\n}\n\nfn test_generic_initializer() {\n    // Should not lint: changing type would affect what generic() returns\n    let a: u8 = generic(10u8);\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_unsafe_transmute() {\n    // Should not lint: initializer contains unsafe block\n    #[allow(clippy::useless_transmute)]\n    let x: u32 = unsafe { std::mem::transmute(0u32) };\n    let _ = x as u64;\n}\n\nfn test_if_with_generic() {\n    // Should not lint: one branch has generic return type\n    let x: u8 = if true { generic(1) } else { 2 };\n    let _ = x as i32;\n}\n\nfn test_match_with_generic() {\n    // Should not lint: one branch has generic return type\n    let x: u8 = match 1 {\n        1 => generic(1),\n        _ => 2,\n    };\n    let _ = x as i32;\n}\n\nfn test_default() {\n    // Should not lint: Default::default() has generic return type\n    let x: u8 = Default::default();\n    let _ = x as i32;\n}\n\nfn test_loop_with_generic() {\n    // Should not lint: loop break has generic return type\n    #[allow(clippy::never_loop)]\n    let x: u8 = loop {\n        break generic(1);\n    };\n    let _ = x as i32;\n}\n\nfn test_size_of_cast() {\n    use std::mem::size_of;\n    // Should lint: suggest casting the initializer\n    let size: u64 = size_of::<u32>() as u64;\n    //~^ needless_type_cast\n    let _ = size as u64;\n    let _ = size as u64;\n}\n\nfn test_suffixed_literal_cast() {\n    // Should lint: suggest casting the initializer\n    let a: i32 = 10u8 as i32;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_negative_literal() {\n    // Negative literal - should just change type, not add cast\n    let a: i32 = -10;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_suffixed_negative_literal() {\n    // Suffixed negative - needs cast\n    let a: i32 = -10i8 as i32;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_binary_op() {\n    // Binary op needs parens in cast\n    let a: i32 = 10 + 5;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_fn_return_as_init() {\n    let a: i32 = returns_u8() as i32;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_method_as_init() {\n    let a: i32 = 2u8.saturating_add(3) as i32;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_const_as_init() {\n    const X: u8 = 10;\n    let a: i32 = X as i32;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_single_use_fn_call() {\n    // Should not lint: only one use, and fixing would just move the cast\n    // to the initializer rather than eliminating it\n    let a: u8 = returns_u8();\n    let _ = a as i32;\n}\n\nfn test_single_use_suffixed_literal() {\n    // Should not lint: only one use with a suffixed literal\n    let a: u8 = 10u8;\n    let _ = a as i32;\n}\n\nfn test_single_use_binary_op() {\n    // Should lint: binary op of unsuffixed literals can be coerced\n    let a: i32 = 10 + 5;\n    //~^ needless_type_cast\n    let _ = a as i32;\n}\n"
  },
  {
    "path": "tests/ui/needless_type_cast.rs",
    "content": "#![warn(clippy::needless_type_cast)]\n#![allow(clippy::no_effect, clippy::unnecessary_cast, unused)]\n\nfn takes_i32(x: i32) -> i32 {\n    x\n}\n\nfn generic<T>(x: T) -> T {\n    x\n}\n\nfn returns_u8() -> u8 {\n    10\n}\n\nfn main() {\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    let _ = a as i32 + 5;\n    let _ = a as i32 * 2;\n\n    let b: u16 = 20;\n    let _ = b;\n    let _ = b as u32;\n\n    let c: u8 = 5;\n    let _ = c as u16;\n    let _ = c as u32;\n\n    let d: i32 = 100;\n    let _ = d + 1;\n\n    let e = 42u8;\n    let _ = e as i64;\n    let _ = e as i64 + 10;\n\n    let f: u8 = 1;\n    //~^ needless_type_cast\n    let _ = f as usize;\n}\n\nfn test_function_call() {\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    let _ = takes_i32(a as i32);\n    let _ = takes_i32(a as i32);\n}\n\nfn test_generic_call() {\n    let a: u8 = 10;\n    let _ = generic(a as i32);\n    let _ = generic(a as i32);\n}\n\nfn test_method_on_cast() {\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    let _ = (a as i32).checked_add(5);\n    let _ = (a as i32).saturating_mul(2);\n}\n\nfn test_iterator_sum() {\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    let arr = [a as i32, a as i32];\n    let _: i32 = arr.iter().copied().sum();\n}\n\nfn test_closure() {\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    let _: i32 = [1i32, 2].iter().map(|x| x + a as i32).sum();\n}\n\nfn test_struct_field() {\n    struct S {\n        x: i32,\n        y: i32,\n    }\n\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    let _ = S {\n        x: a as i32,\n        y: a as i32,\n    };\n}\n\nfn test_option() {\n    let a: u8 = 10;\n    let _: Option<i32> = Some(a as i32);\n    let _: Option<i32> = Some(a as i32);\n}\n\nfn test_mixed_context() {\n    let a: u8 = 10;\n    let _ = takes_i32(a as i32);\n    let _ = generic(a as i32);\n}\n\nfn test_nested_block() {\n    if true {\n        let a: u8 = 10;\n        //~^ needless_type_cast\n        let _ = a as i32 + 1;\n        let _ = a as i32 * 2;\n    }\n}\n\nfn test_match_expr() {\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    let _ = match 1 {\n        1 => a as i32,\n        _ => a as i32,\n    };\n}\n\nfn test_return_expr() -> i32 {\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    a as i32\n}\n\nfn test_closure_always_cast() {\n    let a: u8 = 10;\n    //~^ needless_type_cast\n    let _ = [1, 2].iter().map(|_| a as i32).sum::<i32>();\n    let _ = a as i32;\n}\n\nfn test_closure_mixed_usage() {\n    let a: u8 = 10;\n    let _ = [1, 2].iter().map(|_| a as i32).sum::<i32>();\n    let _ = a + 1;\n}\n\nfn test_nested_generic_call() {\n    let a: u8 = 10;\n    let _ = generic(takes_i32(a as i32));\n    let _ = generic(takes_i32(a as i32));\n}\n\nfn test_generic_initializer() {\n    // Should not lint: changing type would affect what generic() returns\n    let a: u8 = generic(10u8);\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_unsafe_transmute() {\n    // Should not lint: initializer contains unsafe block\n    #[allow(clippy::useless_transmute)]\n    let x: u32 = unsafe { std::mem::transmute(0u32) };\n    let _ = x as u64;\n}\n\nfn test_if_with_generic() {\n    // Should not lint: one branch has generic return type\n    let x: u8 = if true { generic(1) } else { 2 };\n    let _ = x as i32;\n}\n\nfn test_match_with_generic() {\n    // Should not lint: one branch has generic return type\n    let x: u8 = match 1 {\n        1 => generic(1),\n        _ => 2,\n    };\n    let _ = x as i32;\n}\n\nfn test_default() {\n    // Should not lint: Default::default() has generic return type\n    let x: u8 = Default::default();\n    let _ = x as i32;\n}\n\nfn test_loop_with_generic() {\n    // Should not lint: loop break has generic return type\n    #[allow(clippy::never_loop)]\n    let x: u8 = loop {\n        break generic(1);\n    };\n    let _ = x as i32;\n}\n\nfn test_size_of_cast() {\n    use std::mem::size_of;\n    // Should lint: suggest casting the initializer\n    let size: usize = size_of::<u32>();\n    //~^ needless_type_cast\n    let _ = size as u64;\n    let _ = size as u64;\n}\n\nfn test_suffixed_literal_cast() {\n    // Should lint: suggest casting the initializer\n    let a: u8 = 10u8;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_negative_literal() {\n    // Negative literal - should just change type, not add cast\n    let a: i8 = -10;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_suffixed_negative_literal() {\n    // Suffixed negative - needs cast\n    let a: i8 = -10i8;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_binary_op() {\n    // Binary op needs parens in cast\n    let a: u8 = 10 + 5;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_fn_return_as_init() {\n    let a: u8 = returns_u8();\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_method_as_init() {\n    let a: u8 = 2u8.saturating_add(3);\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_const_as_init() {\n    const X: u8 = 10;\n    let a: u8 = X;\n    //~^ needless_type_cast\n    let _ = a as i32;\n    let _ = a as i32;\n}\n\nfn test_single_use_fn_call() {\n    // Should not lint: only one use, and fixing would just move the cast\n    // to the initializer rather than eliminating it\n    let a: u8 = returns_u8();\n    let _ = a as i32;\n}\n\nfn test_single_use_suffixed_literal() {\n    // Should not lint: only one use with a suffixed literal\n    let a: u8 = 10u8;\n    let _ = a as i32;\n}\n\nfn test_single_use_binary_op() {\n    // Should lint: binary op of unsuffixed literals can be coerced\n    let a: u8 = 10 + 5;\n    //~^ needless_type_cast\n    let _ = a as i32;\n}\n"
  },
  {
    "path": "tests/ui/needless_type_cast.stderr",
    "content": "error: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:17:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n   |\n   = note: `-D clippy::needless-type-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_type_cast)]`\n\nerror: this binding is defined as `u8` but is always cast to `usize`\n  --> tests/ui/needless_type_cast.rs:37:12\n   |\nLL |     let f: u8 = 1;\n   |            ^^ help: consider defining it as: `usize`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:43:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:56:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:63:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:70:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:81:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:103:16\n   |\nLL |         let a: u8 = 10;\n   |                ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:111:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:120:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:126:12\n   |\nLL |     let a: u8 = 10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `usize` but is always cast to `u64`\n  --> tests/ui/needless_type_cast.rs:191:15\n   |\nLL |     let size: usize = size_of::<u32>();\n   |               ^^^^^\n   |\nhelp: consider defining it as `u64` and casting the initializer\n   |\nLL -     let size: usize = size_of::<u32>();\nLL +     let size: u64 = size_of::<u32>() as u64;\n   |\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:199:12\n   |\nLL |     let a: u8 = 10u8;\n   |            ^^\n   |\nhelp: consider defining it as `i32` and casting the initializer\n   |\nLL -     let a: u8 = 10u8;\nLL +     let a: i32 = 10u8 as i32;\n   |\n\nerror: this binding is defined as `i8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:207:12\n   |\nLL |     let a: i8 = -10;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `i8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:215:12\n   |\nLL |     let a: i8 = -10i8;\n   |            ^^\n   |\nhelp: consider defining it as `i32` and casting the initializer\n   |\nLL -     let a: i8 = -10i8;\nLL +     let a: i32 = -10i8 as i32;\n   |\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:223:12\n   |\nLL |     let a: u8 = 10 + 5;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:230:12\n   |\nLL |     let a: u8 = returns_u8();\n   |            ^^\n   |\nhelp: consider defining it as `i32` and casting the initializer\n   |\nLL -     let a: u8 = returns_u8();\nLL +     let a: i32 = returns_u8() as i32;\n   |\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:237:12\n   |\nLL |     let a: u8 = 2u8.saturating_add(3);\n   |            ^^\n   |\nhelp: consider defining it as `i32` and casting the initializer\n   |\nLL -     let a: u8 = 2u8.saturating_add(3);\nLL +     let a: i32 = 2u8.saturating_add(3) as i32;\n   |\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:245:12\n   |\nLL |     let a: u8 = X;\n   |            ^^\n   |\nhelp: consider defining it as `i32` and casting the initializer\n   |\nLL -     let a: u8 = X;\nLL +     let a: i32 = X as i32;\n   |\n\nerror: this binding is defined as `u8` but is always cast to `i32`\n  --> tests/ui/needless_type_cast.rs:266:12\n   |\nLL |     let a: u8 = 10 + 5;\n   |            ^^ help: consider defining it as: `i32`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_type_cast_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::needless_type_cast)]\n\nstruct Foo(*mut core::ffi::c_void);\n\nenum Bar {\n    Variant(*mut core::ffi::c_void),\n}\n\n// Suggestions will not compile directly, as `123` is a literal which\n// is not compatible with the suggested `*mut core::ffi::c_void` type\nfn issue_16243() {\n    let underlying: isize = 123;\n    //~^ needless_type_cast\n    let handle: Foo = Foo(underlying as _);\n\n    let underlying: isize = 123;\n    //~^ needless_type_cast\n    let handle: Bar = Bar::Variant(underlying as _);\n}\n"
  },
  {
    "path": "tests/ui/needless_type_cast_unfixable.stderr",
    "content": "error: this binding is defined as `isize` but is always cast to `*mut std::ffi::c_void`\n  --> tests/ui/needless_type_cast_unfixable.rs:13:21\n   |\nLL |     let underlying: isize = 123;\n   |                     ^^^^^ help: consider defining it as: `*mut std::ffi::c_void`\n   |\n   = note: `-D clippy::needless-type-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_type_cast)]`\n\nerror: this binding is defined as `isize` but is always cast to `*mut std::ffi::c_void`\n  --> tests/ui/needless_type_cast_unfixable.rs:17:21\n   |\nLL |     let underlying: isize = 123;\n   |                     ^^^^^ help: consider defining it as: `*mut std::ffi::c_void`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/needless_update.rs",
    "content": "#![warn(clippy::needless_update)]\n#![allow(clippy::no_effect, clippy::unnecessary_struct_initialization)]\n\nstruct S {\n    pub a: i32,\n    pub b: i32,\n}\n\n#[non_exhaustive]\nstruct T {\n    pub x: i32,\n    pub y: i32,\n}\n\nfn main() {\n    let base = S { a: 0, b: 0 };\n    S { ..base }; // no error\n    S { a: 1, ..base }; // no error\n    S { a: 1, b: 1, ..base };\n    //~^ needless_update\n\n    let base = T { x: 0, y: 0 };\n    T { ..base }; // no error\n    T { x: 1, ..base }; // no error\n    T { x: 1, y: 1, ..base }; // no error\n}\n"
  },
  {
    "path": "tests/ui/needless_update.stderr",
    "content": "error: struct update has no effect, all the fields in the struct have already been specified\n  --> tests/ui/needless_update.rs:19:23\n   |\nLL |     S { a: 1, b: 1, ..base };\n   |                       ^^^^\n   |\n   = note: `-D clippy::needless-update` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_update)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/neg_cmp_op_on_partial_ord.rs",
    "content": "//! This test case utilizes `f64` an easy example for `PartialOrd` only types\n//! but the lint itself actually validates any expression where the left\n//! operand implements `PartialOrd` but not `Ord`.\n\nuse std::cmp::Ordering;\n\n#[allow(clippy::unnested_or_patterns, clippy::match_like_matches_macro)]\n#[warn(clippy::neg_cmp_op_on_partial_ord)]\nfn main() {\n    let a_value = 1.0;\n    let another_value = 7.0;\n\n    // --- Bad ---\n\n    // Not Less but potentially Greater, Equal or Uncomparable.\n    let _not_less = !(a_value < another_value);\n    //~^ neg_cmp_op_on_partial_ord\n\n    // Not Less or Equal but potentially Greater or Uncomparable.\n    let _not_less_or_equal = !(a_value <= another_value);\n    //~^ neg_cmp_op_on_partial_ord\n\n    // Not Greater but potentially Less, Equal or Uncomparable.\n    let _not_greater = !(a_value > another_value);\n    //~^ neg_cmp_op_on_partial_ord\n\n    // Not Greater or Equal but potentially Less or Uncomparable.\n    let _not_greater_or_equal = !(a_value >= another_value);\n    //~^ neg_cmp_op_on_partial_ord\n\n    // --- Good ---\n\n    let _not_less = match a_value.partial_cmp(&another_value) {\n        None | Some(Ordering::Greater) | Some(Ordering::Equal) => true,\n        _ => false,\n    };\n    let _not_less_or_equal = match a_value.partial_cmp(&another_value) {\n        None | Some(Ordering::Greater) => true,\n        _ => false,\n    };\n    let _not_greater = match a_value.partial_cmp(&another_value) {\n        None | Some(Ordering::Less) | Some(Ordering::Equal) => true,\n        _ => false,\n    };\n    let _not_greater_or_equal = match a_value.partial_cmp(&another_value) {\n        None | Some(Ordering::Less) => true,\n        _ => false,\n    };\n\n    // --- Should not trigger ---\n\n    let _ = a_value < another_value;\n    let _ = a_value <= another_value;\n    let _ = a_value > another_value;\n    let _ = a_value >= another_value;\n\n    // --- regression tests ---\n\n    // Issue 2856: False positive on assert!()\n    //\n    // The macro always negates the result of the given comparison in its\n    // internal check which automatically triggered the lint. As it's an\n    // external macro there was no chance to do anything about it which led\n    // to an exempting of all external macros.\n    assert!(a_value < another_value);\n}\n"
  },
  {
    "path": "tests/ui/neg_cmp_op_on_partial_ord.stderr",
    "content": "error: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable\n  --> tests/ui/neg_cmp_op_on_partial_ord.rs:16:21\n   |\nLL |     let _not_less = !(a_value < another_value);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::neg-cmp-op-on-partial-ord` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::neg_cmp_op_on_partial_ord)]`\n\nerror: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable\n  --> tests/ui/neg_cmp_op_on_partial_ord.rs:20:30\n   |\nLL |     let _not_less_or_equal = !(a_value <= another_value);\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable\n  --> tests/ui/neg_cmp_op_on_partial_ord.rs:24:24\n   |\nLL |     let _not_greater = !(a_value > another_value);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: the use of negated comparison operators on partially ordered types produces code that is hard to read and refactor, please consider using the `partial_cmp` method instead, to make it clear that the two values could be incomparable\n  --> tests/ui/neg_cmp_op_on_partial_ord.rs:28:33\n   |\nLL |     let _not_greater_or_equal = !(a_value >= another_value);\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/neg_multiply.fixed",
    "content": "#![warn(clippy::neg_multiply)]\n#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::precedence)]\n#![allow(unused)]\n\nuse std::ops::Mul;\n\nstruct X;\n\nimpl Mul<isize> for X {\n    type Output = X;\n\n    fn mul(self, _r: isize) -> Self {\n        self\n    }\n}\n\nimpl Mul<X> for isize {\n    type Output = X;\n\n    fn mul(self, _r: X) -> X {\n        X\n    }\n}\n\nfn main() {\n    let x = 0;\n\n    -x;\n    //~^ neg_multiply\n\n    -x;\n    //~^ neg_multiply\n\n    100 + -x;\n    //~^ neg_multiply\n\n    -(100 + x);\n    //~^ neg_multiply\n\n    -17;\n    //~^ neg_multiply\n\n    0xcafe | -0xff00;\n    //~^ neg_multiply\n\n    -(3_usize as i32);\n    //~^ neg_multiply\n    -(3_usize as i32);\n    //~^ neg_multiply\n\n    -1 * -1; // should be ok\n\n    X * -1; // should be ok\n    -1 * X; // should also be ok\n}\n\nfn float() {\n    let x = 0.0;\n\n    -x;\n    //~^ neg_multiply\n\n    -x;\n    //~^ neg_multiply\n\n    100.0 + -x;\n    //~^ neg_multiply\n\n    -(100.0 + x);\n    //~^ neg_multiply\n\n    -17.0;\n    //~^ neg_multiply\n\n    0.0 + -0.0;\n    //~^ neg_multiply\n\n    -(3.0_f32 as f64);\n    //~^ neg_multiply\n    -(3.0_f32 as f64);\n    //~^ neg_multiply\n\n    -1.0 * -1.0; // should be ok\n}\n\nstruct Y {\n    delta: f64,\n}\n\nfn nested() {\n    let a = Y { delta: 1.0 };\n    let b = Y { delta: 1.0 };\n    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);\n    //~^ neg_multiply\n    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);\n}\n"
  },
  {
    "path": "tests/ui/neg_multiply.rs",
    "content": "#![warn(clippy::neg_multiply)]\n#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::precedence)]\n#![allow(unused)]\n\nuse std::ops::Mul;\n\nstruct X;\n\nimpl Mul<isize> for X {\n    type Output = X;\n\n    fn mul(self, _r: isize) -> Self {\n        self\n    }\n}\n\nimpl Mul<X> for isize {\n    type Output = X;\n\n    fn mul(self, _r: X) -> X {\n        X\n    }\n}\n\nfn main() {\n    let x = 0;\n\n    x * -1;\n    //~^ neg_multiply\n\n    -1 * x;\n    //~^ neg_multiply\n\n    100 + x * -1;\n    //~^ neg_multiply\n\n    (100 + x) * -1;\n    //~^ neg_multiply\n\n    -1 * 17;\n    //~^ neg_multiply\n\n    0xcafe | 0xff00 * -1;\n    //~^ neg_multiply\n\n    3_usize as i32 * -1;\n    //~^ neg_multiply\n    (3_usize as i32) * -1;\n    //~^ neg_multiply\n\n    -1 * -1; // should be ok\n\n    X * -1; // should be ok\n    -1 * X; // should also be ok\n}\n\nfn float() {\n    let x = 0.0;\n\n    x * -1.0;\n    //~^ neg_multiply\n\n    -1.0 * x;\n    //~^ neg_multiply\n\n    100.0 + x * -1.0;\n    //~^ neg_multiply\n\n    (100.0 + x) * -1.0;\n    //~^ neg_multiply\n\n    -1.0 * 17.0;\n    //~^ neg_multiply\n\n    0.0 + 0.0 * -1.0;\n    //~^ neg_multiply\n\n    3.0_f32 as f64 * -1.0;\n    //~^ neg_multiply\n    (3.0_f32 as f64) * -1.0;\n    //~^ neg_multiply\n\n    -1.0 * -1.0; // should be ok\n}\n\nstruct Y {\n    delta: f64,\n}\n\nfn nested() {\n    let a = Y { delta: 1.0 };\n    let b = Y { delta: 1.0 };\n    let _ = ((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0);\n    //~^ neg_multiply\n    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);\n}\n"
  },
  {
    "path": "tests/ui/neg_multiply.stderr",
    "content": "error: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:28:5\n   |\nLL |     x * -1;\n   |     ^^^^^^ help: consider using: `-x`\n   |\n   = note: `-D clippy::neg-multiply` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::neg_multiply)]`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:31:5\n   |\nLL |     -1 * x;\n   |     ^^^^^^ help: consider using: `-x`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:34:11\n   |\nLL |     100 + x * -1;\n   |           ^^^^^^ help: consider using: `-x`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:37:5\n   |\nLL |     (100 + x) * -1;\n   |     ^^^^^^^^^^^^^^ help: consider using: `-(100 + x)`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:40:5\n   |\nLL |     -1 * 17;\n   |     ^^^^^^^ help: consider using: `-17`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:43:14\n   |\nLL |     0xcafe | 0xff00 * -1;\n   |              ^^^^^^^^^^^ help: consider using: `-0xff00`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:46:5\n   |\nLL |     3_usize as i32 * -1;\n   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3_usize as i32)`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:48:5\n   |\nLL |     (3_usize as i32) * -1;\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3_usize as i32)`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:60:5\n   |\nLL |     x * -1.0;\n   |     ^^^^^^^^ help: consider using: `-x`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:63:5\n   |\nLL |     -1.0 * x;\n   |     ^^^^^^^^ help: consider using: `-x`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:66:13\n   |\nLL |     100.0 + x * -1.0;\n   |             ^^^^^^^^ help: consider using: `-x`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:69:5\n   |\nLL |     (100.0 + x) * -1.0;\n   |     ^^^^^^^^^^^^^^^^^^ help: consider using: `-(100.0 + x)`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:72:5\n   |\nLL |     -1.0 * 17.0;\n   |     ^^^^^^^^^^^ help: consider using: `-17.0`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:75:11\n   |\nLL |     0.0 + 0.0 * -1.0;\n   |           ^^^^^^^^^^ help: consider using: `-0.0`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:78:5\n   |\nLL |     3.0_f32 as f64 * -1.0;\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3.0_f32 as f64)`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:80:5\n   |\nLL |     (3.0_f32 as f64) * -1.0;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3.0_f32 as f64)`\n\nerror: this multiplication by -1 can be written more succinctly\n  --> tests/ui/neg_multiply.rs:93:13\n   |\nLL |     let _ = ((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-(a.delta - 0.5).abs())`\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/never_loop.rs",
    "content": "#![feature(try_blocks)]\n#![expect(clippy::eq_op, clippy::single_match, clippy::while_immutable_condition)]\n//@no-rustfix\n\nuse std::arch::asm;\n\nfn test1() {\n    let mut x = 0;\n    loop {\n        //~^ never_loop\n\n        // clippy::never_loop\n        x += 1;\n        if x == 1 {\n            return;\n        }\n        break;\n    }\n}\n\nfn test2() {\n    let mut x = 0;\n    loop {\n        x += 1;\n        if x == 1 {\n            break;\n        }\n    }\n}\n\nfn test3() {\n    let mut x = 0;\n    loop {\n        //~^ never_loop\n\n        // never loops\n        x += 1;\n        break;\n    }\n}\n\nfn test4() {\n    let mut x = 1;\n    loop {\n        x += 1;\n        match x {\n            5 => return,\n            _ => (),\n        }\n    }\n}\n\nfn test5() {\n    let i = 0;\n    loop {\n        //~^ never_loop\n\n        // never loops\n        while i == 0 {\n            //~^ never_loop\n\n            // never loops\n            break;\n        }\n        return;\n    }\n}\n\nfn test6() {\n    let mut x = 0;\n    'outer: loop {\n        x += 1;\n        loop {\n            //~^ never_loop\n\n            // never loops\n            if x == 5 {\n                break;\n            }\n            continue 'outer;\n        }\n        return;\n    }\n}\n\nfn test7() {\n    let mut x = 0;\n    loop {\n        x += 1;\n        match x {\n            1 => continue,\n            _ => (),\n        }\n        return;\n    }\n}\n\nfn test8() {\n    let mut x = 0;\n    loop {\n        x += 1;\n        match x {\n            5 => return,\n            _ => continue,\n        }\n    }\n}\n\nfn test9() {\n    let x = Some(1);\n    while let Some(y) = x {\n        //~^ never_loop\n\n        // never loops\n        return;\n    }\n}\n\nfn test10() {\n    for x in 0..10 {\n        //~^ never_loop\n\n        // never loops\n        match x {\n            1 => break,\n            _ => return,\n        }\n    }\n}\n\nfn test11<F: FnMut() -> i32>(mut f: F) {\n    loop {\n        return match f() {\n            1 => continue,\n            _ => (),\n        };\n    }\n}\n\npub fn test12(a: bool, b: bool) {\n    'label: loop {\n        loop {\n            if a {\n                continue 'label;\n            }\n            if b {\n                break;\n            }\n        }\n        break;\n    }\n}\n\npub fn test13() {\n    let mut a = true;\n    loop {\n        // infinite loop\n        while a {\n            if true {\n                a = false;\n                continue;\n            }\n            return;\n        }\n    }\n}\n\npub fn test14() {\n    let mut a = true;\n    'outer: while a {\n        //~^ never_loop\n\n        // never loops\n        while a {\n            if a {\n                a = false;\n                continue;\n            }\n        }\n        break 'outer;\n    }\n}\n\n// Issue #1991: the outer loop should not warn.\npub fn test15() {\n    'label: loop {\n        while false {\n            //~^ never_loop\n\n            break 'label;\n        }\n    }\n}\n\n// Issue #4058: `continue` in `break` expression\npub fn test16() {\n    let mut n = 1;\n    loop {\n        break if n != 5 {\n            n += 1;\n            continue;\n        };\n    }\n}\n\n// Issue #9001: `continue` in struct expression fields\npub fn test17() {\n    struct Foo {\n        f: (),\n    }\n\n    let mut n = 0;\n    let _ = loop {\n        break Foo {\n            f: if n < 5 {\n                n += 1;\n                continue;\n            },\n        };\n    };\n}\n\n// Issue #9356: `continue` in else branch of let..else\npub fn test18() {\n    let x = Some(0);\n    let y = 0;\n    // might loop\n    let _ = loop {\n        let Some(x) = x else {\n            if y > 0 {\n                continue;\n            } else {\n                return;\n            }\n        };\n\n        break x;\n    };\n    // never loops\n    let _ = loop {\n        //~^ never_loop\n\n        let Some(x) = x else {\n            return;\n        };\n\n        break x;\n    };\n}\n\n// Issue #9831: unconditional break to internal labeled block\npub fn test19() {\n    fn thing(iter: impl Iterator) {\n        for _ in iter {\n            'b: {\n                break 'b;\n            }\n        }\n    }\n}\n\npub fn test20() {\n    'a: loop {\n        //~^ never_loop\n\n        'b: {\n            break 'b 'c: {\n                break 'a;\n                //~^ diverging_sub_expression\n            };\n        }\n    }\n}\n\npub fn test21() {\n    loop {\n        'a: {\n            {}\n            break 'a;\n        }\n    }\n}\n\n// Issue 10304: code after break from block was not considered\n// unreachable code and was considered for further analysis of\n// whether the loop would ever be executed or not.\npub fn test22() {\n    for _ in 0..10 {\n        'block: {\n            break 'block;\n            return;\n        }\n        println!(\"looped\");\n    }\n}\n\npub fn test23() {\n    for _ in 0..10 {\n        'block: {\n            for _ in 0..20 {\n                //~^ never_loop\n\n                break 'block;\n            }\n        }\n        println!(\"looped\");\n    }\n}\n\npub fn test24() {\n    'a: for _ in 0..10 {\n        'b: {\n            let x = Some(1);\n            match x {\n                None => break 'a,\n                Some(_) => break 'b,\n            }\n        }\n    }\n}\n\n// Do not lint, we can evaluate `true` to always succeed thus can short-circuit before the `return`\npub fn test25() {\n    loop {\n        'label: {\n            if const { true } {\n                break 'label;\n            }\n            return;\n        }\n    }\n}\n\npub fn test26() {\n    loop {\n        'label: {\n            if 1 == 1 {\n                break 'label;\n            }\n            return;\n        }\n    }\n}\n\npub fn test27() {\n    loop {\n        'label: {\n            let x = true;\n            if x {\n                break 'label;\n            }\n            return;\n        }\n    }\n}\n\n// issue 11004\npub fn test29() {\n    loop {\n        'label: {\n            if true {\n                break 'label;\n            }\n            return;\n        }\n    }\n}\n\npub fn test30() {\n    'a: loop {\n        'b: {\n            for j in 0..2 {\n                if j == 1 {\n                    break 'b;\n                }\n            }\n            break 'a;\n        }\n    }\n}\n\npub fn test31(b: bool) {\n    'a: loop {\n        'b: {\n            'c: loop {\n                //~^ never_loop\n\n                if b { break 'c } else { break 'b }\n            }\n            continue 'a;\n        }\n        break 'a;\n    }\n}\n\npub fn test32() {\n    loop {\n        //~^ never_loop\n\n        panic!(\"oh no\");\n    }\n    loop {\n        //~^ never_loop\n\n        unimplemented!(\"not yet\");\n    }\n    loop {\n        // no error\n        todo!(\"maybe later\");\n    }\n}\n\npub fn issue12205() -> Option<()> {\n    loop {\n        let _: Option<_> = try {\n            None?;\n            return Some(());\n        };\n    }\n}\n\nfn stmt_after_return() {\n    for v in 0..10 {\n        //~^ never_loop\n        break;\n        println!(\"{v}\");\n    }\n}\n\nfn loop_label() {\n    'outer: for v in 0..10 {\n        //~^ never_loop\n        loop {\n            //~^ never_loop\n            break 'outer;\n        }\n        return;\n    }\n\n    for v in 0..10 {\n        //~^ never_loop\n        'inner: loop {\n            //~^ never_loop\n            break 'inner;\n        }\n        return;\n    }\n}\n\nfn main() {}\n\nfn issue15059() {\n    'a: for _ in 0..1 {\n        //~^ never_loop\n        break 'a;\n    }\n\n    let mut b = 1;\n    'a: for i in 0..1 {\n        //~^ never_loop\n        match i {\n            0 => {\n                b *= 2;\n                break 'a;\n            },\n            x => {\n                b += x;\n                break 'a;\n            },\n        }\n    }\n\n    #[allow(clippy::unused_unit)]\n    for v in 0..10 {\n        //~^ never_loop\n        break;\n        println!(\"{v}\");\n        // This is comment and should be kept\n        println!(\"This is a comment\");\n        ()\n    }\n}\n\nfn issue15350() {\n    'bar: for _ in 0..100 {\n        //~^ never_loop\n        loop {\n            //~^ never_loop\n            println!(\"This will still run\");\n            break 'bar;\n        }\n    }\n\n    'foo: for _ in 0..100 {\n        //~^ never_loop\n        loop {\n            //~^ never_loop\n            println!(\"This will still run\");\n            loop {\n                //~^ never_loop\n                println!(\"This will still run\");\n                break 'foo;\n            }\n        }\n    }\n}\n\nfn issue15673() {\n    loop {\n        unsafe {\n            // No lint since we don't analyze the inside of the asm\n            asm! {\n                \"/* {} */\",\n                label {\n                    break;\n                }\n            }\n        }\n    }\n\n    //~v never_loop\n    loop {\n        unsafe {\n            asm! {\n                \"/* {} */\",\n                label {\n                    break;\n                }\n            }\n        }\n        return;\n    }\n}\n\n#[expect(clippy::diverging_sub_expression, clippy::short_circuit_statement)]\nfn issue16462() {\n    let mut n = 10;\n    loop {\n        println!(\"{n}\");\n        n -= 1;\n        n >= 0 || break;\n    }\n}\n"
  },
  {
    "path": "tests/ui/never_loop.stderr",
    "content": "error: this loop never actually loops\n  --> tests/ui/never_loop.rs:9:5\n   |\nLL | /     loop {\n...  |\nLL | |         break;\nLL | |     }\n   | |_____^\n   |\n   = note: `#[deny(clippy::never_loop)]` on by default\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:33:5\n   |\nLL | /     loop {\n...  |\nLL | |         break;\nLL | |     }\n   | |_____^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:55:5\n   |\nLL | /     loop {\n...  |\nLL | |         return;\nLL | |     }\n   | |_____^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:59:9\n   |\nLL | /         while i == 0 {\n...  |\nLL | |         }\n   | |_________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:73:9\n   |\nLL | /         loop {\n...  |\nLL | |             continue 'outer;\nLL | |         }\n   | |_________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:111:5\n   |\nLL | /     while let Some(y) = x {\n...  |\nLL | |     }\n   | |_____^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:120:5\n   |\nLL | /     for x in 0..10 {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: if you need the first element of the iterator, try writing\n   |\nLL -     for x in 0..10 {\nLL +     if let Some(x) = (0..10).next() {\n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:170:5\n   |\nLL | /     'outer: while a {\n...  |\nLL | |         break 'outer;\nLL | |     }\n   | |_____^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:187:9\n   |\nLL | /         while false {\nLL | |\nLL | |\nLL | |             break 'label;\nLL | |         }\n   | |_________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:240:13\n   |\nLL |       let _ = loop {\n   |  _____________^\nLL | |\nLL | |\nLL | |         let Some(x) = x else {\n...  |\nLL | |         break x;\nLL | |     };\n   | |_____^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:263:5\n   |\nLL | /     'a: loop {\nLL | |\nLL | |\nLL | |         'b: {\n...  |\nLL | |     }\n   | |_____^\n\nerror: sub-expression diverges\n  --> tests/ui/never_loop.rs:268:17\n   |\nLL |                 break 'a;\n   |                 ^^^^^^^^\n   |\n   = note: `-D clippy::diverging-sub-expression` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::diverging_sub_expression)]`\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:300:13\n   |\nLL | /             for _ in 0..20 {\nLL | |\nLL | |\nLL | |                 break 'block;\nLL | |             }\n   | |_____________^\n   |\nhelp: if you need the first element of the iterator, try writing\n   |\nLL -             for _ in 0..20 {\nLL +             if let Some(_) = (0..20).next() {\n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:385:13\n   |\nLL | /             'c: loop {\nLL | |\nLL | |\nLL | |                 if b { break 'c } else { break 'b }\nLL | |             }\n   | |_____________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:397:5\n   |\nLL | /     loop {\nLL | |\nLL | |\nLL | |         panic!(\"oh no\");\nLL | |     }\n   | |_____^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:402:5\n   |\nLL | /     loop {\nLL | |\nLL | |\nLL | |         unimplemented!(\"not yet\");\nLL | |     }\n   | |_____^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:423:5\n   |\nLL | /     for v in 0..10 {\nLL | |\nLL | |         break;\nLL | |         println!(\"{v}\");\nLL | |     }\n   | |_____^\n   |\nhelp: if you need the first element of the iterator, try writing\n   |\nLL ~     if let Some(v) = (0..10).next() {\nLL |\nLL ~         \nLL ~         \n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:431:5\n   |\nLL | /     'outer: for v in 0..10 {\nLL | |\nLL | |         loop {\n...  |\nLL | |         return;\nLL | |     }\n   | |_____^\n   |\nhelp: this code is unreachable. Consider moving the reachable parts out\n  --> tests/ui/never_loop.rs:433:9\n   |\nLL | /         loop {\nLL | |\nLL | |             break 'outer;\nLL | |         }\n   | |_________^\nhelp: this code is unreachable. Consider moving the reachable parts out\n  --> tests/ui/never_loop.rs:437:9\n   |\nLL |         return;\n   |         ^^^^^^^\nhelp: if you need the first element of the iterator, try writing\n   |\nLL -     'outer: for v in 0..10 {\nLL +     if let Some(v) = (0..10).next() {\n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:433:9\n   |\nLL | /         loop {\nLL | |\nLL | |             break 'outer;\nLL | |         }\n   | |_________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:440:5\n   |\nLL | /     for v in 0..10 {\nLL | |\nLL | |         'inner: loop {\n...  |\nLL | |         return;\nLL | |     }\n   | |_____^\n   |\nhelp: if you need the first element of the iterator, try writing\n   |\nLL -     for v in 0..10 {\nLL +     if let Some(v) = (0..10).next() {\n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:442:9\n   |\nLL | /         'inner: loop {\nLL | |\nLL | |             break 'inner;\nLL | |         }\n   | |_________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:453:5\n   |\nLL | /     'a: for _ in 0..1 {\nLL | |\nLL | |         break 'a;\nLL | |     }\n   | |_____^\n   |\nhelp: if you need the first element of the iterator, try writing\n   |\nLL ~     if let Some(_) = (0..1).next() {\nLL |\nLL ~         \n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:459:5\n   |\nLL | /     'a: for i in 0..1 {\nLL | |\nLL | |         match i {\nLL | |             0 => {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: if you need the first element of the iterator, try writing\n   |\nLL ~     if let Some(i) = (0..1).next() {\nLL |\n...\nLL |                 b *= 2;\nLL ~                 \nLL |             },\nLL |             x => {\nLL |                 b += x;\nLL ~                 \n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:474:5\n   |\nLL | /     for v in 0..10 {\nLL | |\nLL | |         break;\nLL | |         println!(\"{v}\");\n...  |\nLL | |         ()\nLL | |     }\n   | |_____^\n   |\nhelp: if you need the first element of the iterator, try writing\n   |\nLL ~     if let Some(v) = (0..10).next() {\nLL |\nLL ~         \nLL ~         \nLL |         // This is comment and should be kept\nLL ~         \nLL ~         \n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:485:5\n   |\nLL | /     'bar: for _ in 0..100 {\nLL | |\nLL | |         loop {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: this code is unreachable. Consider moving the reachable parts out\n  --> tests/ui/never_loop.rs:487:9\n   |\nLL | /         loop {\nLL | |\nLL | |             println!(\"This will still run\");\nLL | |             break 'bar;\nLL | |         }\n   | |_________^\nhelp: if you need the first element of the iterator, try writing\n   |\nLL -     'bar: for _ in 0..100 {\nLL +     if let Some(_) = (0..100).next() {\n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:487:9\n   |\nLL | /         loop {\nLL | |\nLL | |             println!(\"This will still run\");\nLL | |             break 'bar;\nLL | |         }\n   | |_________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:494:5\n   |\nLL | /     'foo: for _ in 0..100 {\nLL | |\nLL | |         loop {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: this code is unreachable. Consider moving the reachable parts out\n  --> tests/ui/never_loop.rs:496:9\n   |\nLL | /         loop {\nLL | |\nLL | |             println!(\"This will still run\");\nLL | |             loop {\n...  |\nLL | |         }\n   | |_________^\nhelp: if you need the first element of the iterator, try writing\n   |\nLL -     'foo: for _ in 0..100 {\nLL +     if let Some(_) = (0..100).next() {\n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:496:9\n   |\nLL | /         loop {\nLL | |\nLL | |             println!(\"This will still run\");\nLL | |             loop {\n...  |\nLL | |         }\n   | |_________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:499:13\n   |\nLL | /             loop {\nLL | |\nLL | |                 println!(\"This will still run\");\nLL | |                 break 'foo;\nLL | |             }\n   | |_____________^\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop.rs:522:5\n   |\nLL | /     loop {\nLL | |         unsafe {\nLL | |             asm! {\nLL | |                 \"/* {} */\",\n...  |\nLL | |         return;\nLL | |     }\n   | |_____^\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/never_loop_fixable.fixed",
    "content": "#![allow(clippy::iter_next_slice, clippy::needless_return)]\n\nfn no_break_or_continue_loop() {\n    if let Some(i) = [1, 2, 3].iter().next() {\n        //~^ never_loop\n        return;\n    }\n}\n\nfn no_break_or_continue_loop_outer() {\n    if let Some(i) = [1, 2, 3].iter().next() {\n        //~^ never_loop\n        return;\n        loop {\n            if true {\n                continue;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/never_loop_fixable.rs",
    "content": "#![allow(clippy::iter_next_slice, clippy::needless_return)]\n\nfn no_break_or_continue_loop() {\n    for i in [1, 2, 3].iter() {\n        //~^ never_loop\n        return;\n    }\n}\n\nfn no_break_or_continue_loop_outer() {\n    for i in [1, 2, 3].iter() {\n        //~^ never_loop\n        return;\n        loop {\n            if true {\n                continue;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/never_loop_fixable.stderr",
    "content": "error: this loop never actually loops\n  --> tests/ui/never_loop_fixable.rs:4:5\n   |\nLL | /     for i in [1, 2, 3].iter() {\nLL | |\nLL | |         return;\nLL | |     }\n   | |_____^\n   |\n   = note: `#[deny(clippy::never_loop)]` on by default\nhelp: if you need the first element of the iterator, try writing\n   |\nLL -     for i in [1, 2, 3].iter() {\nLL +     if let Some(i) = [1, 2, 3].iter().next() {\n   |\n\nerror: this loop never actually loops\n  --> tests/ui/never_loop_fixable.rs:11:5\n   |\nLL | /     for i in [1, 2, 3].iter() {\nLL | |\nLL | |         return;\nLL | |         loop {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: if you need the first element of the iterator, try writing\n   |\nLL -     for i in [1, 2, 3].iter() {\nLL +     if let Some(i) = [1, 2, 3].iter().next() {\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/never_loop_iterator_reduction.rs",
    "content": "//@no-rustfix\n#![warn(clippy::never_loop)]\n#![expect(clippy::needless_return)]\n\nfn main() {\n    // diverging closure with no `return`: should trigger\n    [0, 1].into_iter().for_each(|x| {\n        //~^ never_loop\n\n        let _ = x;\n        panic!(\"boom\");\n    });\n\n    // benign closure: should NOT trigger\n    [0, 1].into_iter().for_each(|x| {\n        let _ = x + 1;\n    });\n\n    // `return` should NOT trigger even though it is diverging\n    [0, 1].into_iter().for_each(|x| {\n        println!(\"x = {x}\");\n        return;\n    });\n}\n"
  },
  {
    "path": "tests/ui/never_loop_iterator_reduction.stderr",
    "content": "error: this iterator reduction never loops (closure always diverges)\n  --> tests/ui/never_loop_iterator_reduction.rs:7:5\n   |\nLL | /     [0, 1].into_iter().for_each(|x| {\nLL | |\nLL | |\nLL | |         let _ = x;\nLL | |         panic!(\"boom\");\nLL | |     });\n   | |______^\n   |\n   = note: if you only need one element, `if let Some(x) = iter.next()` is clearer\n   = note: `-D clippy::never-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::never_loop)]`\nhelp: consider this pattern\n   |\nLL -     [0, 1].into_iter().for_each(|x| {\nLL -\nLL - \nLL -         let _ = x;\nLL -         panic!(\"boom\");\nLL -     });\nLL +     if let Some(x) = [0, 1].into_iter().next() { ... };\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/new_ret_no_self.rs",
    "content": "#![feature(type_alias_impl_trait)]\n#![warn(clippy::new_ret_no_self)]\n#![allow(dead_code)]\n\nfn main() {}\n\ntrait R {\n    type Item;\n}\n\ntrait Q {\n    type Item;\n    type Item2;\n}\n\nstruct S;\n\nimpl R for S {\n    type Item = Self;\n}\n\nimpl S {\n    // should not trigger the lint\n    pub fn new() -> impl R<Item = Self> {\n        S\n    }\n}\n\nstruct S2;\n\nimpl R for S2 {\n    type Item = Self;\n}\n\nimpl S2 {\n    // should not trigger the lint\n    pub fn new(_: String) -> impl R<Item = Self> {\n        S2\n    }\n}\n\nstruct S3;\n\nimpl R for S3 {\n    type Item = u32;\n}\n\nimpl S3 {\n    // should trigger the lint\n    pub fn new(_: String) -> impl R<Item = u32> {\n        //~^ new_ret_no_self\n\n        S3\n    }\n}\n\nstruct S4;\n\nimpl Q for S4 {\n    type Item = u32;\n    type Item2 = Self;\n}\n\nimpl S4 {\n    // should not trigger the lint\n    pub fn new(_: String) -> impl Q<Item = u32, Item2 = Self> {\n        S4\n    }\n}\n\nstruct T;\n\nimpl T {\n    // should not trigger lint\n    pub fn new() -> Self {\n        unimplemented!();\n    }\n}\n\nstruct U;\n\nimpl U {\n    // should trigger lint\n    pub fn new() -> u32 {\n        //~^ new_ret_no_self\n\n        unimplemented!();\n    }\n}\n\nstruct V;\n\nimpl V {\n    // should trigger lint\n    pub fn new(_: String) -> u32 {\n        //~^ new_ret_no_self\n\n        unimplemented!();\n    }\n}\n\nstruct TupleReturnerOk;\n\nimpl TupleReturnerOk {\n    // should not trigger lint\n    pub fn new() -> (Self, u32) {\n        unimplemented!();\n    }\n}\n\nstruct TupleReturnerOk2;\n\nimpl TupleReturnerOk2 {\n    // should not trigger lint (it doesn't matter which element in the tuple is Self)\n    pub fn new() -> (u32, Self) {\n        unimplemented!();\n    }\n}\n\nstruct TupleReturnerOk3;\n\nimpl TupleReturnerOk3 {\n    // should not trigger lint (tuple can contain multiple Self)\n    pub fn new() -> (Self, Self) {\n        unimplemented!();\n    }\n}\n\nstruct TupleReturnerBad;\n\nimpl TupleReturnerBad {\n    // should trigger lint\n    pub fn new() -> (u32, u32) {\n        //~^ new_ret_no_self\n\n        unimplemented!();\n    }\n}\n\nstruct MutPointerReturnerOk;\n\nimpl MutPointerReturnerOk {\n    // should not trigger lint\n    pub fn new() -> *mut Self {\n        unimplemented!();\n    }\n}\n\nstruct ConstPointerReturnerOk2;\n\nimpl ConstPointerReturnerOk2 {\n    // should not trigger lint\n    pub fn new() -> *const Self {\n        unimplemented!();\n    }\n}\n\nstruct MutPointerReturnerBad;\n\nimpl MutPointerReturnerBad {\n    // should trigger lint\n    pub fn new() -> *mut V {\n        //~^ new_ret_no_self\n\n        unimplemented!();\n    }\n}\n\nstruct GenericReturnerOk;\n\nimpl GenericReturnerOk {\n    // should not trigger lint\n    pub fn new() -> Option<Self> {\n        unimplemented!();\n    }\n}\n\nstruct GenericReturnerBad;\n\nimpl GenericReturnerBad {\n    // should trigger lint\n    pub fn new() -> Option<u32> {\n        //~^ new_ret_no_self\n\n        unimplemented!();\n    }\n}\n\nstruct NestedReturnerOk;\n\nimpl NestedReturnerOk {\n    // should not trigger lint\n    pub fn new() -> (Option<Self>, u32) {\n        unimplemented!();\n    }\n}\n\nstruct NestedReturnerOk2;\n\nimpl NestedReturnerOk2 {\n    // should not trigger lint\n    pub fn new() -> ((Self, u32), u32) {\n        unimplemented!();\n    }\n}\n\nstruct NestedReturnerOk3;\n\nimpl NestedReturnerOk3 {\n    // should not trigger lint\n    pub fn new() -> Option<(Self, u32)> {\n        unimplemented!();\n    }\n}\n\nstruct WithLifetime<'a> {\n    cat: &'a str,\n}\n\nimpl<'a> WithLifetime<'a> {\n    // should not trigger the lint, because the lifetimes are different\n    pub fn new<'b: 'a>(s: &'b str) -> WithLifetime<'b> {\n        unimplemented!();\n    }\n}\n\nmod issue5435 {\n    struct V;\n\n    pub trait TraitRetSelf {\n        // should not trigger lint\n        fn new() -> Self;\n    }\n\n    pub trait TraitRet {\n        // should trigger lint as we are in trait definition\n        fn new() -> String;\n        //~^ new_ret_no_self\n    }\n    pub struct StructRet;\n    impl TraitRet for StructRet {\n        // should not trigger lint as we are in the impl block\n        fn new() -> String {\n            unimplemented!();\n        }\n    }\n\n    pub trait TraitRet2 {\n        // should trigger lint\n        fn new(_: String) -> String;\n        //~^ new_ret_no_self\n    }\n\n    trait TupleReturnerOk {\n        // should not trigger lint\n        fn new() -> (Self, u32)\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n\n    trait TupleReturnerOk2 {\n        // should not trigger lint (it doesn't matter which element in the tuple is Self)\n        fn new() -> (u32, Self)\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n\n    trait TupleReturnerOk3 {\n        // should not trigger lint (tuple can contain multiple Self)\n        fn new() -> (Self, Self)\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n\n    trait TupleReturnerBad {\n        // should trigger lint\n        fn new() -> (u32, u32) {\n            //~^ new_ret_no_self\n\n            unimplemented!();\n        }\n    }\n\n    trait MutPointerReturnerOk {\n        // should not trigger lint\n        fn new() -> *mut Self\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n\n    trait ConstPointerReturnerOk2 {\n        // should not trigger lint\n        fn new() -> *const Self\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n\n    trait MutPointerReturnerBad {\n        // should trigger lint\n        fn new() -> *mut V {\n            //~^ new_ret_no_self\n\n            unimplemented!();\n        }\n    }\n\n    trait GenericReturnerOk {\n        // should not trigger lint\n        fn new() -> Option<Self>\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n\n    trait NestedReturnerOk {\n        // should not trigger lint\n        fn new() -> (Option<Self>, u32)\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n\n    trait NestedReturnerOk2 {\n        // should not trigger lint\n        fn new() -> ((Self, u32), u32)\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n\n    trait NestedReturnerOk3 {\n        // should not trigger lint\n        fn new() -> Option<(Self, u32)>\n        where\n            Self: Sized,\n        {\n            unimplemented!();\n        }\n    }\n}\n\n// issue #1724\nstruct RetOtherSelf<T>(T);\nstruct RetOtherSelfWrapper<T>(T);\n\nimpl RetOtherSelf<T> {\n    fn new(t: T) -> RetOtherSelf<RetOtherSelfWrapper<T>> {\n        RetOtherSelf(RetOtherSelfWrapper(t))\n    }\n}\n\nmod issue7344 {\n    struct RetImplTraitSelf<T>(T);\n\n    impl<T> RetImplTraitSelf<T> {\n        // should not trigger lint\n        fn new(t: T) -> impl Into<Self> {\n            Self(t)\n        }\n    }\n\n    struct RetImplTraitNoSelf<T>(T);\n\n    impl<T> RetImplTraitNoSelf<T> {\n        // should trigger lint\n        fn new(t: T) -> impl Into<i32> {\n            //~^ new_ret_no_self\n\n            1\n        }\n    }\n\n    trait Trait2<T, U> {}\n    impl<T, U> Trait2<T, U> for () {}\n\n    struct RetImplTraitSelf2<T>(T);\n\n    impl<T> RetImplTraitSelf2<T> {\n        // should not trigger lint\n        fn new(t: T) -> impl Trait2<(), Self> {}\n    }\n\n    struct RetImplTraitNoSelf2<T>(T);\n\n    impl<T> RetImplTraitNoSelf2<T> {\n        // should trigger lint\n        fn new(t: T) -> impl Trait2<(), i32> {\n            //~^ new_ret_no_self\n        }\n    }\n\n    struct RetImplTraitSelfAdt<'a>(&'a str);\n\n    impl<'a> RetImplTraitSelfAdt<'a> {\n        // should not trigger lint\n        fn new<'b: 'a>(s: &'b str) -> impl Into<RetImplTraitSelfAdt<'b>> {\n            RetImplTraitSelfAdt(s)\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/new_ret_no_self.stderr",
    "content": "error: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:50:5\n   |\nLL | /     pub fn new(_: String) -> impl R<Item = u32> {\nLL | |\nLL | |\nLL | |         S3\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::new-ret-no-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::new_ret_no_self)]`\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:84:5\n   |\nLL | /     pub fn new() -> u32 {\nLL | |\nLL | |\nLL | |         unimplemented!();\nLL | |     }\n   | |_____^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:95:5\n   |\nLL | /     pub fn new(_: String) -> u32 {\nLL | |\nLL | |\nLL | |         unimplemented!();\nLL | |     }\n   | |_____^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:133:5\n   |\nLL | /     pub fn new() -> (u32, u32) {\nLL | |\nLL | |\nLL | |         unimplemented!();\nLL | |     }\n   | |_____^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:162:5\n   |\nLL | /     pub fn new() -> *mut V {\nLL | |\nLL | |\nLL | |         unimplemented!();\nLL | |     }\n   | |_____^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:182:5\n   |\nLL | /     pub fn new() -> Option<u32> {\nLL | |\nLL | |\nLL | |         unimplemented!();\nLL | |     }\n   | |_____^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:237:9\n   |\nLL |         fn new() -> String;\n   |         ^^^^^^^^^^^^^^^^^^^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:250:9\n   |\nLL |         fn new(_: String) -> String;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:286:9\n   |\nLL | /         fn new() -> (u32, u32) {\nLL | |\nLL | |\nLL | |             unimplemented!();\nLL | |         }\n   | |_________^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:315:9\n   |\nLL | /         fn new() -> *mut V {\nLL | |\nLL | |\nLL | |             unimplemented!();\nLL | |         }\n   | |_________^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:387:9\n   |\nLL | /         fn new(t: T) -> impl Into<i32> {\nLL | |\nLL | |\nLL | |             1\nLL | |         }\n   | |_________^\n\nerror: methods called `new` usually return `Self`\n  --> tests/ui/new_ret_no_self.rs:408:9\n   |\nLL | /         fn new(t: T) -> impl Trait2<(), i32> {\nLL | |\nLL | |         }\n   | |_________^\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/new_ret_no_self_overflow.rs",
    "content": "#![feature(type_alias_impl_trait)]\n#![warn(clippy::new_ret_no_self)]\n\nmod issue10041 {\n    struct Bomb;\n\n    impl Bomb {\n        // Hidden <Rhs = Self> default generic parameter.\n        pub fn new() -> impl PartialOrd {\n            0i32\n        }\n    }\n\n    // TAIT with self-referencing bounds\n    type X = impl std::ops::Add<Output = X>;\n\n    struct Bomb2;\n\n    impl Bomb2 {\n        #[define_opaque(X)]\n        pub fn new() -> X {\n            //~^ ERROR: overflow evaluating the requirement\n            0i32\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/new_ret_no_self_overflow.stderr",
    "content": "error[E0275]: overflow evaluating the requirement `<i32 as std::ops::Add>::Output == issue10041::X`\n  --> tests/ui/new_ret_no_self_overflow.rs:21:25\n   |\nLL |         pub fn new() -> X {\n   |                         ^\n\nerror: aborting due to 1 previous error\n\nFor more information about this error, try `rustc --explain E0275`.\n"
  },
  {
    "path": "tests/ui/new_without_default.fixed",
    "content": "#![allow(\n    clippy::missing_safety_doc,\n    clippy::extra_unused_lifetimes,\n    clippy::extra_unused_type_parameters,\n    clippy::needless_lifetimes\n)]\n#![warn(clippy::new_without_default)]\n\npub struct Foo;\n\nimpl Default for Foo {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl Foo {\n    pub fn new() -> Foo {\n        //~^ new_without_default\n\n        Foo\n    }\n}\n\npub struct Bar;\n\nimpl Default for Bar {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl Bar {\n    pub fn new() -> Self {\n        //~^ new_without_default\n\n        Bar\n    }\n}\n\npub struct Ok;\n\nimpl Ok {\n    pub fn new() -> Self {\n        Ok\n    }\n}\n\nimpl Default for Ok {\n    fn default() -> Self {\n        Ok\n    }\n}\n\npub struct Params;\n\nimpl Params {\n    pub fn new(_: u32) -> Self {\n        Params\n    }\n}\n\npub struct GenericsOk<T> {\n    bar: T,\n}\n\nimpl<U> Default for GenericsOk<U> {\n    fn default() -> Self {\n        unimplemented!();\n    }\n}\n\nimpl<'c, V> GenericsOk<V> {\n    pub fn new() -> GenericsOk<V> {\n        unimplemented!()\n    }\n}\n\npub struct LtOk<'a> {\n    foo: &'a bool,\n}\n\nimpl<'b> Default for LtOk<'b> {\n    fn default() -> Self {\n        unimplemented!();\n    }\n}\n\nimpl<'c> LtOk<'c> {\n    pub fn new() -> LtOk<'c> {\n        unimplemented!()\n    }\n}\n\npub struct LtKo<'a> {\n    foo: &'a bool,\n}\n\nimpl<'c> Default for LtKo<'c> {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl<'c> LtKo<'c> {\n    pub fn new() -> LtKo<'c> {\n        //~^ new_without_default\n\n        unimplemented!()\n    }\n}\n\nstruct Private;\n\nimpl Private {\n    fn new() -> Private {\n        unimplemented!()\n    } // We don't lint private items\n}\n\nstruct PrivateStruct;\n\nimpl PrivateStruct {\n    pub fn new() -> PrivateStruct {\n        unimplemented!()\n    } // We don't lint public items on private structs\n}\n\npub struct PrivateItem;\n\nimpl PrivateItem {\n    fn new() -> PrivateItem {\n        unimplemented!()\n    } // We don't lint private items on public structs\n}\n\npub struct Const;\n\nimpl Default for Const {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl Const {\n    pub const fn new() -> Const {\n        //~^ new_without_default\n        Const\n    } // While Default is not const, it can still call const functions, so we should lint this\n}\n\npub struct IgnoreGenericNew;\n\nimpl IgnoreGenericNew {\n    pub fn new<T>() -> Self {\n        IgnoreGenericNew\n    } // the derived Default does not make sense here as the result depends on T\n}\n\npub trait TraitWithNew: Sized {\n    fn new() -> Self {\n        panic!()\n    }\n}\n\npub struct IgnoreUnsafeNew;\n\nimpl IgnoreUnsafeNew {\n    pub unsafe fn new() -> Self {\n        IgnoreUnsafeNew\n    }\n}\n\n#[derive(Default)]\npub struct OptionRefWrapper<'a, T>(Option<&'a T>);\n\nimpl<'a, T> OptionRefWrapper<'a, T> {\n    pub fn new() -> Self {\n        OptionRefWrapper(None)\n    }\n}\n\npub struct Allow(Foo);\n\nimpl Allow {\n    #[allow(clippy::new_without_default)]\n    pub fn new() -> Self {\n        unimplemented!()\n    }\n}\n\npub struct AllowDerive;\n\nimpl AllowDerive {\n    #[allow(clippy::new_without_default)]\n    pub fn new() -> Self {\n        unimplemented!()\n    }\n}\n\npub struct NewNotEqualToDerive {\n    foo: i32,\n}\n\nimpl Default for NewNotEqualToDerive {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl NewNotEqualToDerive {\n    // This `new` implementation is not equal to a derived `Default`, so do not suggest deriving.\n    pub fn new() -> Self {\n        //~^ new_without_default\n\n        NewNotEqualToDerive { foo: 1 }\n    }\n}\n\n// see #6933\npub struct FooGenerics<T>(std::marker::PhantomData<T>);\nimpl<T> Default for FooGenerics<T> {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl<T> FooGenerics<T> {\n    pub fn new() -> Self {\n        //~^ new_without_default\n\n        Self(Default::default())\n    }\n}\n\npub struct BarGenerics<T>(std::marker::PhantomData<T>);\nimpl<T: Copy> Default for BarGenerics<T> {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl<T: Copy> BarGenerics<T> {\n    pub fn new() -> Self {\n        //~^ new_without_default\n\n        Self(Default::default())\n    }\n}\n\npub mod issue7220 {\n    pub struct Foo<T> {\n        _bar: *mut T,\n    }\n\n    impl<T> Default for Foo<T> {\n        fn default() -> Self {\n            Self::new()\n        }\n    }\n\n    impl<T> Foo<T> {\n        pub fn new() -> Self {\n            //~^ new_without_default\n\n            todo!()\n        }\n    }\n}\n\n// see issue #8152\n// This should not create any lints\npub struct DocHidden;\nimpl DocHidden {\n    #[doc(hidden)]\n    pub fn new() -> Self {\n        DocHidden\n    }\n}\n\nfn main() {}\n\npub struct IgnoreConstGenericNew(usize);\nimpl IgnoreConstGenericNew {\n    pub fn new<const N: usize>() -> Self {\n        Self(N)\n    }\n}\n\npub struct IgnoreLifetimeNew;\nimpl IgnoreLifetimeNew {\n    pub fn new<'a>() -> Self {\n        Self\n    }\n}\n\n// From issue #11267\n\npub struct MyStruct<K, V>\nwhere\n    K: std::hash::Hash + Eq + PartialEq,\n{\n    _kv: Option<(K, V)>,\n}\n\nimpl<K, V> Default for MyStruct<K, V>\nwhere\n    K: std::hash::Hash + Eq + PartialEq,\n {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl<K, V> MyStruct<K, V>\nwhere\n    K: std::hash::Hash + Eq + PartialEq,\n{\n    pub fn new() -> Self {\n        //~^ new_without_default\n        Self { _kv: None }\n    }\n}\n\n// From issue #14552, but with `#[cfg]`s that are actually `true` in the uitest context\n\npub struct NewWithCfg;\n#[cfg(not(test))]\nimpl Default for NewWithCfg {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl NewWithCfg {\n    #[cfg(not(test))]\n    pub fn new() -> Self {\n        //~^ new_without_default\n        unimplemented!()\n    }\n}\n\npub struct NewWith2Cfgs;\n#[cfg(not(test))]\n#[cfg(panic = \"unwind\")]\nimpl Default for NewWith2Cfgs {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl NewWith2Cfgs {\n    #[cfg(not(test))]\n    #[cfg(panic = \"unwind\")]\n    pub fn new() -> Self {\n        //~^ new_without_default\n        unimplemented!()\n    }\n}\n\npub struct NewWithExtraneous;\nimpl Default for NewWithExtraneous {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl NewWithExtraneous {\n    #[inline]\n    pub fn new() -> Self {\n        //~^ new_without_default\n        unimplemented!()\n    }\n}\n\npub struct NewWithCfgAndExtraneous;\n#[cfg(not(test))]\nimpl Default for NewWithCfgAndExtraneous {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl NewWithCfgAndExtraneous {\n    #[cfg(not(test))]\n    #[inline]\n    pub fn new() -> Self {\n        //~^ new_without_default\n        unimplemented!()\n    }\n}\n\nmod issue15778 {\n    pub struct Foo(Vec<i32>);\n\n    impl Foo {\n        pub fn new() -> Self {\n            Self(Vec::new())\n        }\n    }\n\n    impl<'a> IntoIterator for &'a Foo {\n        type Item = &'a i32;\n\n        type IntoIter = std::slice::Iter<'a, i32>;\n\n        fn into_iter(self) -> Self::IntoIter {\n            self.0.as_slice().iter()\n        }\n    }\n}\n\npub mod issue16255 {\n    use std::fmt::Display;\n    use std::marker::PhantomData;\n\n    pub struct Foo<T> {\n        marker: PhantomData<T>,\n    }\n\n    impl<T> Default for Foo<T>\n    where\n        T: Display,\n        T: Clone,\n     {\n        fn default() -> Self {\n            Self::new()\n        }\n    }\n\n    impl<T> Foo<T>\n    where\n        T: Display,\n    {\n        pub fn new() -> Self\n        //~^ new_without_default\n        where\n            T: Clone,\n        {\n            Self { marker: PhantomData }\n        }\n    }\n\n    pub struct Bar<T> {\n        marker: PhantomData<T>,\n    }\n\n    impl<T> Default for Bar<T>\n    where\n        T: Clone,\n     {\n        fn default() -> Self {\n            Self::new()\n        }\n    }\n\n    impl<T> Bar<T> {\n        pub fn new() -> Self\n        //~^ new_without_default\n        where\n            T: Clone,\n        {\n            Self { marker: PhantomData }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/new_without_default.rs",
    "content": "#![allow(\n    clippy::missing_safety_doc,\n    clippy::extra_unused_lifetimes,\n    clippy::extra_unused_type_parameters,\n    clippy::needless_lifetimes\n)]\n#![warn(clippy::new_without_default)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn new() -> Foo {\n        //~^ new_without_default\n\n        Foo\n    }\n}\n\npub struct Bar;\n\nimpl Bar {\n    pub fn new() -> Self {\n        //~^ new_without_default\n\n        Bar\n    }\n}\n\npub struct Ok;\n\nimpl Ok {\n    pub fn new() -> Self {\n        Ok\n    }\n}\n\nimpl Default for Ok {\n    fn default() -> Self {\n        Ok\n    }\n}\n\npub struct Params;\n\nimpl Params {\n    pub fn new(_: u32) -> Self {\n        Params\n    }\n}\n\npub struct GenericsOk<T> {\n    bar: T,\n}\n\nimpl<U> Default for GenericsOk<U> {\n    fn default() -> Self {\n        unimplemented!();\n    }\n}\n\nimpl<'c, V> GenericsOk<V> {\n    pub fn new() -> GenericsOk<V> {\n        unimplemented!()\n    }\n}\n\npub struct LtOk<'a> {\n    foo: &'a bool,\n}\n\nimpl<'b> Default for LtOk<'b> {\n    fn default() -> Self {\n        unimplemented!();\n    }\n}\n\nimpl<'c> LtOk<'c> {\n    pub fn new() -> LtOk<'c> {\n        unimplemented!()\n    }\n}\n\npub struct LtKo<'a> {\n    foo: &'a bool,\n}\n\nimpl<'c> LtKo<'c> {\n    pub fn new() -> LtKo<'c> {\n        //~^ new_without_default\n\n        unimplemented!()\n    }\n}\n\nstruct Private;\n\nimpl Private {\n    fn new() -> Private {\n        unimplemented!()\n    } // We don't lint private items\n}\n\nstruct PrivateStruct;\n\nimpl PrivateStruct {\n    pub fn new() -> PrivateStruct {\n        unimplemented!()\n    } // We don't lint public items on private structs\n}\n\npub struct PrivateItem;\n\nimpl PrivateItem {\n    fn new() -> PrivateItem {\n        unimplemented!()\n    } // We don't lint private items on public structs\n}\n\npub struct Const;\n\nimpl Const {\n    pub const fn new() -> Const {\n        //~^ new_without_default\n        Const\n    } // While Default is not const, it can still call const functions, so we should lint this\n}\n\npub struct IgnoreGenericNew;\n\nimpl IgnoreGenericNew {\n    pub fn new<T>() -> Self {\n        IgnoreGenericNew\n    } // the derived Default does not make sense here as the result depends on T\n}\n\npub trait TraitWithNew: Sized {\n    fn new() -> Self {\n        panic!()\n    }\n}\n\npub struct IgnoreUnsafeNew;\n\nimpl IgnoreUnsafeNew {\n    pub unsafe fn new() -> Self {\n        IgnoreUnsafeNew\n    }\n}\n\n#[derive(Default)]\npub struct OptionRefWrapper<'a, T>(Option<&'a T>);\n\nimpl<'a, T> OptionRefWrapper<'a, T> {\n    pub fn new() -> Self {\n        OptionRefWrapper(None)\n    }\n}\n\npub struct Allow(Foo);\n\nimpl Allow {\n    #[allow(clippy::new_without_default)]\n    pub fn new() -> Self {\n        unimplemented!()\n    }\n}\n\npub struct AllowDerive;\n\nimpl AllowDerive {\n    #[allow(clippy::new_without_default)]\n    pub fn new() -> Self {\n        unimplemented!()\n    }\n}\n\npub struct NewNotEqualToDerive {\n    foo: i32,\n}\n\nimpl NewNotEqualToDerive {\n    // This `new` implementation is not equal to a derived `Default`, so do not suggest deriving.\n    pub fn new() -> Self {\n        //~^ new_without_default\n\n        NewNotEqualToDerive { foo: 1 }\n    }\n}\n\n// see #6933\npub struct FooGenerics<T>(std::marker::PhantomData<T>);\nimpl<T> FooGenerics<T> {\n    pub fn new() -> Self {\n        //~^ new_without_default\n\n        Self(Default::default())\n    }\n}\n\npub struct BarGenerics<T>(std::marker::PhantomData<T>);\nimpl<T: Copy> BarGenerics<T> {\n    pub fn new() -> Self {\n        //~^ new_without_default\n\n        Self(Default::default())\n    }\n}\n\npub mod issue7220 {\n    pub struct Foo<T> {\n        _bar: *mut T,\n    }\n\n    impl<T> Foo<T> {\n        pub fn new() -> Self {\n            //~^ new_without_default\n\n            todo!()\n        }\n    }\n}\n\n// see issue #8152\n// This should not create any lints\npub struct DocHidden;\nimpl DocHidden {\n    #[doc(hidden)]\n    pub fn new() -> Self {\n        DocHidden\n    }\n}\n\nfn main() {}\n\npub struct IgnoreConstGenericNew(usize);\nimpl IgnoreConstGenericNew {\n    pub fn new<const N: usize>() -> Self {\n        Self(N)\n    }\n}\n\npub struct IgnoreLifetimeNew;\nimpl IgnoreLifetimeNew {\n    pub fn new<'a>() -> Self {\n        Self\n    }\n}\n\n// From issue #11267\n\npub struct MyStruct<K, V>\nwhere\n    K: std::hash::Hash + Eq + PartialEq,\n{\n    _kv: Option<(K, V)>,\n}\n\nimpl<K, V> MyStruct<K, V>\nwhere\n    K: std::hash::Hash + Eq + PartialEq,\n{\n    pub fn new() -> Self {\n        //~^ new_without_default\n        Self { _kv: None }\n    }\n}\n\n// From issue #14552, but with `#[cfg]`s that are actually `true` in the uitest context\n\npub struct NewWithCfg;\nimpl NewWithCfg {\n    #[cfg(not(test))]\n    pub fn new() -> Self {\n        //~^ new_without_default\n        unimplemented!()\n    }\n}\n\npub struct NewWith2Cfgs;\nimpl NewWith2Cfgs {\n    #[cfg(not(test))]\n    #[cfg(panic = \"unwind\")]\n    pub fn new() -> Self {\n        //~^ new_without_default\n        unimplemented!()\n    }\n}\n\npub struct NewWithExtraneous;\nimpl NewWithExtraneous {\n    #[inline]\n    pub fn new() -> Self {\n        //~^ new_without_default\n        unimplemented!()\n    }\n}\n\npub struct NewWithCfgAndExtraneous;\nimpl NewWithCfgAndExtraneous {\n    #[cfg(not(test))]\n    #[inline]\n    pub fn new() -> Self {\n        //~^ new_without_default\n        unimplemented!()\n    }\n}\n\nmod issue15778 {\n    pub struct Foo(Vec<i32>);\n\n    impl Foo {\n        pub fn new() -> Self {\n            Self(Vec::new())\n        }\n    }\n\n    impl<'a> IntoIterator for &'a Foo {\n        type Item = &'a i32;\n\n        type IntoIter = std::slice::Iter<'a, i32>;\n\n        fn into_iter(self) -> Self::IntoIter {\n            self.0.as_slice().iter()\n        }\n    }\n}\n\npub mod issue16255 {\n    use std::fmt::Display;\n    use std::marker::PhantomData;\n\n    pub struct Foo<T> {\n        marker: PhantomData<T>,\n    }\n\n    impl<T> Foo<T>\n    where\n        T: Display,\n    {\n        pub fn new() -> Self\n        //~^ new_without_default\n        where\n            T: Clone,\n        {\n            Self { marker: PhantomData }\n        }\n    }\n\n    pub struct Bar<T> {\n        marker: PhantomData<T>,\n    }\n\n    impl<T> Bar<T> {\n        pub fn new() -> Self\n        //~^ new_without_default\n        where\n            T: Clone,\n        {\n            Self { marker: PhantomData }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/new_without_default.stderr",
    "content": "error: you should consider adding a `Default` implementation for `Foo`\n  --> tests/ui/new_without_default.rs:12:5\n   |\nLL | /     pub fn new() -> Foo {\nLL | |\nLL | |\nLL | |         Foo\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::new-without-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::new_without_default)]`\nhelp: try adding this\n   |\nLL + impl Default for Foo {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `Bar`\n  --> tests/ui/new_without_default.rs:22:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |\nLL | |         Bar\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + impl Default for Bar {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `LtKo<'c>`\n  --> tests/ui/new_without_default.rs:88:5\n   |\nLL | /     pub fn new() -> LtKo<'c> {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + impl<'c> Default for LtKo<'c> {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `Const`\n  --> tests/ui/new_without_default.rs:122:5\n   |\nLL | /     pub const fn new() -> Const {\nLL | |\nLL | |         Const\nLL | |     } // While Default is not const, it can still call const functions, so we should lint this\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + impl Default for Const {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `NewNotEqualToDerive`\n  --> tests/ui/new_without_default.rs:183:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |\nLL | |         NewNotEqualToDerive { foo: 1 }\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + impl Default for NewNotEqualToDerive {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `FooGenerics<T>`\n  --> tests/ui/new_without_default.rs:193:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |\nLL | |         Self(Default::default())\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + impl<T> Default for FooGenerics<T> {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `BarGenerics<T>`\n  --> tests/ui/new_without_default.rs:202:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |\nLL | |         Self(Default::default())\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + impl<T: Copy> Default for BarGenerics<T> {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `Foo<T>`\n  --> tests/ui/new_without_default.rs:215:9\n   |\nLL | /         pub fn new() -> Self {\nLL | |\nLL | |\nLL | |             todo!()\nLL | |         }\n   | |_________^\n   |\nhelp: try adding this\n   |\nLL ~     impl<T> Default for Foo<T> {\nLL +         fn default() -> Self {\nLL +             Self::new()\nLL +         }\nLL +     }\nLL + \nLL ~     impl<T> Foo<T> {\n   |\n\nerror: you should consider adding a `Default` implementation for `MyStruct<K, V>`\n  --> tests/ui/new_without_default.rs:262:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |         Self { _kv: None }\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + impl<K, V> Default for MyStruct<K, V>\nLL + where\nLL +     K: std::hash::Hash + Eq + PartialEq,\nLL +  {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `NewWithCfg`\n  --> tests/ui/new_without_default.rs:273:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + #[cfg(not(test))]\nLL + impl Default for NewWithCfg {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `NewWith2Cfgs`\n  --> tests/ui/new_without_default.rs:283:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + #[cfg(not(test))]\nLL + #[cfg(panic = \"unwind\")]\nLL + impl Default for NewWith2Cfgs {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `NewWithExtraneous`\n  --> tests/ui/new_without_default.rs:292:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + impl Default for NewWithExtraneous {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `NewWithCfgAndExtraneous`\n  --> tests/ui/new_without_default.rs:302:5\n   |\nLL | /     pub fn new() -> Self {\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\nhelp: try adding this\n   |\nLL + #[cfg(not(test))]\nLL + impl Default for NewWithCfgAndExtraneous {\nLL +     fn default() -> Self {\nLL +         Self::new()\nLL +     }\nLL + }\n   |\n\nerror: you should consider adding a `Default` implementation for `Foo<T>`\n  --> tests/ui/new_without_default.rs:340:9\n   |\nLL | /         pub fn new() -> Self\nLL | |\nLL | |         where\nLL | |             T: Clone,\nLL | |         {\nLL | |             Self { marker: PhantomData }\nLL | |         }\n   | |_________^\n   |\nhelp: try adding this\n   |\nLL ~     impl<T> Default for Foo<T>\nLL +     where\nLL +         T: Display,\nLL +         T: Clone,\nLL +      {\nLL +         fn default() -> Self {\nLL +             Self::new()\nLL +         }\nLL +     }\nLL + \nLL ~     impl<T> Foo<T>\n   |\n\nerror: you should consider adding a `Default` implementation for `Bar<T>`\n  --> tests/ui/new_without_default.rs:354:9\n   |\nLL | /         pub fn new() -> Self\nLL | |\nLL | |         where\nLL | |             T: Clone,\nLL | |         {\nLL | |             Self { marker: PhantomData }\nLL | |         }\n   | |_________^\n   |\nhelp: try adding this\n   |\nLL ~     impl<T> Default for Bar<T>\nLL +     where\nLL +         T: Clone,\nLL +      {\nLL +         fn default() -> Self {\nLL +             Self::new()\nLL +         }\nLL +     }\nLL + \nLL ~     impl<T> Bar<T> {\n   |\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/no_effect.rs",
    "content": "#![feature(fn_traits, unboxed_closures)]\n#![warn(clippy::no_effect_underscore_binding)]\n#![allow(\n    clippy::deref_addrof,\n    clippy::redundant_field_names,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_struct_initialization,\n    clippy::useless_vec\n)]\n\nuse std::fmt::Display;\nuse std::ops::{Neg, Shl};\n\nstruct Cout;\n\nimpl<T> Shl<T> for Cout\nwhere\n    T: Display,\n{\n    type Output = Self;\n    fn shl(self, rhs: T) -> Self::Output {\n        println!(\"{}\", rhs);\n        self\n    }\n}\n\nimpl Neg for Cout {\n    type Output = Self;\n    fn neg(self) -> Self::Output {\n        println!(\"hello world\");\n        self\n    }\n}\n\nstruct Tuple(i32);\nstruct Struct {\n    field: i32,\n}\nenum Enum {\n    Tuple(i32),\n    Struct { field: i32 },\n}\nstruct DropStruct {\n    field: i32,\n}\nimpl Drop for DropStruct {\n    fn drop(&mut self) {}\n}\nstruct DropTuple(i32);\nimpl Drop for DropTuple {\n    fn drop(&mut self) {}\n}\nenum DropEnum {\n    Tuple(i32),\n    Struct { field: i32 },\n}\nimpl Drop for DropEnum {\n    fn drop(&mut self) {}\n}\nstruct FooString {\n    s: String,\n}\nunion Union {\n    a: u8,\n    b: f64,\n}\n\nfn get_number() -> i32 {\n    0\n}\nfn get_struct() -> Struct {\n    Struct { field: 0 }\n}\nfn get_drop_struct() -> DropStruct {\n    DropStruct { field: 0 }\n}\n\nunsafe fn unsafe_fn() -> i32 {\n    0\n}\n\nstruct GreetStruct1;\n\nimpl FnOnce<(&str,)> for GreetStruct1 {\n    type Output = ();\n\n    extern \"rust-call\" fn call_once(self, (who,): (&str,)) -> Self::Output {\n        println!(\"hello {}\", who);\n    }\n}\n\nstruct GreetStruct2();\n\nimpl FnOnce<(&str,)> for GreetStruct2 {\n    type Output = ();\n\n    extern \"rust-call\" fn call_once(self, (who,): (&str,)) -> Self::Output {\n        println!(\"hello {}\", who);\n    }\n}\n\nstruct GreetStruct3;\n\nimpl FnOnce<(&str,)> for GreetStruct3 {\n    type Output = ();\n\n    extern \"rust-call\" fn call_once(self, (who,): (&str,)) -> Self::Output {\n        println!(\"hello {}\", who);\n    }\n}\n\nfn main() {\n    let s = get_struct();\n\n    0;\n    //~^ no_effect\n\n    Tuple(0);\n    //~^ no_effect\n\n    Struct { field: 0 };\n    //~^ no_effect\n\n    Struct { ..s };\n    //~^ no_effect\n\n    Union { a: 0 };\n    //~^ no_effect\n\n    Enum::Tuple(0);\n    //~^ no_effect\n\n    Enum::Struct { field: 0 };\n    //~^ no_effect\n\n    5 + 6;\n    //~^ no_effect\n\n    *&42;\n    //~^ no_effect\n\n    &6;\n    //~^ no_effect\n\n    (5, 6, 7);\n    //~^ no_effect\n\n    ..;\n    //~^ no_effect\n\n    5..;\n    //~^ no_effect\n\n    ..5;\n    //~^ no_effect\n\n    5..6;\n    //~^ no_effect\n\n    5..=6;\n    //~^ no_effect\n\n    [42, 55];\n    //~^ no_effect\n\n    [42, 55][1];\n    //~^ no_effect\n\n    (42, 55).1;\n    //~^ no_effect\n\n    [42; 55];\n    //~^ no_effect\n\n    [42; 55][13];\n    //~^ no_effect\n\n    let mut x = 0;\n    || x += 5;\n    //~^ no_effect\n\n    let s: String = \"foo\".into();\n    FooString { s: s };\n    //~^ no_effect\n\n    let _unused = 1;\n    //~^ no_effect_underscore_binding\n\n    let _penguin = || println!(\"Some helpful closure\");\n    //~^ no_effect_underscore_binding\n\n    let _duck = Struct { field: 0 };\n    //~^ no_effect_underscore_binding\n\n    let _cat = [2, 4, 6, 8][2];\n    //~^ no_effect_underscore_binding\n\n    let _issue_12166 = 42;\n    let underscore_variable_above_can_be_used_dont_lint = _issue_12166;\n\n    #[allow(clippy::no_effect)]\n    0;\n\n    // Do not warn\n    get_number();\n    unsafe { unsafe_fn() };\n    let _used = get_struct();\n    let _x = vec![1];\n    DropStruct { field: 0 };\n    DropTuple(0);\n    DropEnum::Tuple(0);\n    DropEnum::Struct { field: 0 };\n    GreetStruct1(\"world\");\n    GreetStruct2()(\"world\");\n    GreetStruct3 {}(\"world\");\n\n    fn n() -> i32 {\n        42\n    }\n\n    Cout << 142;\n    -Cout;\n}\n\nfn issue14592() {\n    struct MyStruct {\n        _inner: MyInner,\n    }\n    struct MyInner {}\n\n    impl Drop for MyInner {\n        fn drop(&mut self) {\n            println!(\"dropping\");\n        }\n    }\n\n    let x = MyStruct { _inner: MyInner {} };\n\n    let closure = || {\n        // Do not lint: dropping the assignment or assigning to `_` would\n        // change the output.\n        let _x = x;\n    };\n\n    println!(\"1\");\n    closure();\n    println!(\"2\");\n\n    struct Innocuous {\n        a: i32,\n    }\n\n    // Do not lint: one of the fields has a side effect.\n    let x = MyInner {};\n    let closure = || {\n        let _x = Innocuous {\n            a: {\n                x;\n                10\n            },\n        };\n    };\n\n    // Do not lint: the base has a side effect.\n    let x = MyInner {};\n    let closure = || {\n        let _x = Innocuous {\n            ..Innocuous {\n                a: {\n                    x;\n                    10\n                },\n            }\n        };\n    };\n}\n"
  },
  {
    "path": "tests/ui/no_effect.stderr",
    "content": "error: statement with no effect\n  --> tests/ui/no_effect.rs:115:5\n   |\nLL |     0;\n   |     ^^\n   |\n   = note: `-D clippy::no-effect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::no_effect)]`\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:118:5\n   |\nLL |     Tuple(0);\n   |     ^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:121:5\n   |\nLL |     Struct { field: 0 };\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:124:5\n   |\nLL |     Struct { ..s };\n   |     ^^^^^^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:127:5\n   |\nLL |     Union { a: 0 };\n   |     ^^^^^^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:130:5\n   |\nLL |     Enum::Tuple(0);\n   |     ^^^^^^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:133:5\n   |\nLL |     Enum::Struct { field: 0 };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:136:5\n   |\nLL |     5 + 6;\n   |     ^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:139:5\n   |\nLL |     *&42;\n   |     ^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:142:5\n   |\nLL |     &6;\n   |     ^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:145:5\n   |\nLL |     (5, 6, 7);\n   |     ^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:148:5\n   |\nLL |     ..;\n   |     ^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:151:5\n   |\nLL |     5..;\n   |     ^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:154:5\n   |\nLL |     ..5;\n   |     ^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:157:5\n   |\nLL |     5..6;\n   |     ^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:160:5\n   |\nLL |     5..=6;\n   |     ^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:163:5\n   |\nLL |     [42, 55];\n   |     ^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:166:5\n   |\nLL |     [42, 55][1];\n   |     ^^^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:169:5\n   |\nLL |     (42, 55).1;\n   |     ^^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:172:5\n   |\nLL |     [42; 55];\n   |     ^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:175:5\n   |\nLL |     [42; 55][13];\n   |     ^^^^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:179:5\n   |\nLL |     || x += 5;\n   |     ^^^^^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect.rs:183:5\n   |\nLL |     FooString { s: s };\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: binding to `_` prefixed variable with no side-effect\n  --> tests/ui/no_effect.rs:186:9\n   |\nLL |     let _unused = 1;\n   |         ^^^^^^^\n   |\n   = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]`\n\nerror: binding to `_` prefixed variable with no side-effect\n  --> tests/ui/no_effect.rs:189:9\n   |\nLL |     let _penguin = || println!(\"Some helpful closure\");\n   |         ^^^^^^^^\n\nerror: binding to `_` prefixed variable with no side-effect\n  --> tests/ui/no_effect.rs:192:9\n   |\nLL |     let _duck = Struct { field: 0 };\n   |         ^^^^^\n\nerror: binding to `_` prefixed variable with no side-effect\n  --> tests/ui/no_effect.rs:195:9\n   |\nLL |     let _cat = [2, 4, 6, 8][2];\n   |         ^^^^\n\nerror: aborting due to 27 previous errors\n\n"
  },
  {
    "path": "tests/ui/no_effect_async_fn.rs",
    "content": "#![warn(clippy::no_effect_underscore_binding)]\n#![no_main]\n\ntrait AsyncTrait {\n    async fn bar(i: u64);\n}\n\nstruct Bar;\n\nimpl AsyncTrait for Bar {\n    // Shouldn't lint `binding to `_` prefixed variable with no side-effect`\n    async fn bar(_i: u64) {\n        let _a = 0;\n        //~^ no_effect_underscore_binding\n\n        // Shouldn't lint `binding to `_` prefixed variable with no side-effect`\n        let _b = num();\n\n        let _ = async {\n            let _c = 0;\n            //~^ no_effect_underscore_binding\n\n            // Shouldn't lint `binding to `_` prefixed variable with no side-effect`\n            let _d = num();\n        }\n        .await;\n    }\n}\n\n// Shouldn't lint `binding to `_` prefixed variable with no side-effect`\nasync fn foo(_i: u64) {\n    let _a = 0;\n    //~^ no_effect_underscore_binding\n\n    // Shouldn't lint `binding to `_` prefixed variable with no side-effect`\n    let _b = num();\n\n    let _ = async {\n        let _c = 0;\n        //~^ no_effect_underscore_binding\n\n        // Shouldn't lint `binding to `_` prefixed variable with no side-effect`\n        let _d = num();\n    }\n    .await;\n}\n\nfn num() -> usize {\n    0\n}\n"
  },
  {
    "path": "tests/ui/no_effect_async_fn.stderr",
    "content": "error: binding to `_` prefixed variable with no side-effect\n  --> tests/ui/no_effect_async_fn.rs:20:17\n   |\nLL |             let _c = 0;\n   |                 ^^\n   |\n   = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]`\n\nerror: binding to `_` prefixed variable with no side-effect\n  --> tests/ui/no_effect_async_fn.rs:13:13\n   |\nLL |         let _a = 0;\n   |             ^^\n\nerror: binding to `_` prefixed variable with no side-effect\n  --> tests/ui/no_effect_async_fn.rs:39:13\n   |\nLL |         let _c = 0;\n   |             ^^\n\nerror: binding to `_` prefixed variable with no side-effect\n  --> tests/ui/no_effect_async_fn.rs:32:9\n   |\nLL |     let _a = 0;\n   |         ^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/no_effect_replace.rs",
    "content": "#![warn(clippy::no_effect_replace)]\n\nfn main() {\n    let _ = \"12345\".replace('1', \"1\");\n    //~^ no_effect_replace\n\n    let _ = \"12345\".replace(\"12\", \"12\");\n    //~^ no_effect_replace\n\n    let _ = String::new().replace(\"12\", \"12\");\n    //~^ no_effect_replace\n\n    let _ = \"12345\".replacen('1', \"1\", 1);\n    //~^ no_effect_replace\n\n    let _ = \"12345\".replacen(\"12\", \"12\", 1);\n    //~^ no_effect_replace\n\n    let _ = String::new().replacen(\"12\", \"12\", 1);\n    //~^ no_effect_replace\n\n    let _ = \"12345\".replace(\"12\", \"22\");\n    let _ = \"12345\".replacen(\"12\", \"22\", 1);\n\n    let mut x = X::default();\n    let _ = \"hello\".replace(&x.f(), &x.f());\n    //~^ no_effect_replace\n\n    let _ = \"hello\".replace(&x.f(), &x.ff());\n\n    let _ = \"hello\".replace(&y(), &y());\n    //~^ no_effect_replace\n\n    let _ = \"hello\".replace(&y(), &z());\n\n    let _ = Replaceme.replace(\"a\", \"a\");\n}\n\n#[derive(Default)]\nstruct X {}\n\nimpl X {\n    fn f(&mut self) -> String {\n        \"he\".to_string()\n    }\n\n    fn ff(&mut self) -> String {\n        \"hh\".to_string()\n    }\n}\n\nfn y() -> String {\n    \"he\".to_string()\n}\n\nfn z() -> String {\n    \"hh\".to_string()\n}\n\nstruct Replaceme;\nimpl Replaceme {\n    pub fn replace(&mut self, a: &str, b: &str) -> Self {\n        Self\n    }\n}\n"
  },
  {
    "path": "tests/ui/no_effect_replace.stderr",
    "content": "error: replacing text with itself\n  --> tests/ui/no_effect_replace.rs:4:13\n   |\nLL |     let _ = \"12345\".replace('1', \"1\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::no-effect-replace` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::no_effect_replace)]`\n\nerror: replacing text with itself\n  --> tests/ui/no_effect_replace.rs:7:13\n   |\nLL |     let _ = \"12345\".replace(\"12\", \"12\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: replacing text with itself\n  --> tests/ui/no_effect_replace.rs:10:13\n   |\nLL |     let _ = String::new().replace(\"12\", \"12\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: replacing text with itself\n  --> tests/ui/no_effect_replace.rs:13:13\n   |\nLL |     let _ = \"12345\".replacen('1', \"1\", 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: replacing text with itself\n  --> tests/ui/no_effect_replace.rs:16:13\n   |\nLL |     let _ = \"12345\".replacen(\"12\", \"12\", 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: replacing text with itself\n  --> tests/ui/no_effect_replace.rs:19:13\n   |\nLL |     let _ = String::new().replacen(\"12\", \"12\", 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: replacing text with itself\n  --> tests/ui/no_effect_replace.rs:26:13\n   |\nLL |     let _ = \"hello\".replace(&x.f(), &x.f());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: replacing text with itself\n  --> tests/ui/no_effect_replace.rs:31:13\n   |\nLL |     let _ = \"hello\".replace(&y(), &y());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/no_effect_return.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![allow(clippy::unused_unit, dead_code, unused)]\n#![no_main]\n\nuse std::ops::ControlFlow;\n\nfn a() -> u32 {\n    {\n        0u32;\n        //~^ no_effect\n    }\n    0\n}\n\nasync fn b() -> u32 {\n    {\n        0u32;\n        //~^ no_effect\n    }\n    0\n}\n\ntype C = i32;\nasync fn c() -> C {\n    {\n        0i32 as C;\n        //~^ no_effect\n    }\n    0\n}\n\nfn d() -> u128 {\n    {\n        // not last stmt\n        0u128;\n        //~^ no_effect\n\n        println!(\"lol\");\n    }\n    0\n}\n\nfn e() -> u32 {\n    {\n        // mismatched types\n        0u16;\n        //~^ no_effect\n    }\n    0\n}\n\nfn f() -> [u16; 1] {\n    {\n        [1u16];\n        //~^ no_effect\n    }\n    [1]\n}\n\nfn g() -> ControlFlow<()> {\n    {\n        ControlFlow::Break::<()>(());\n        //~^ no_effect\n    }\n    ControlFlow::Continue(())\n}\n\nfn h() -> Vec<u16> {\n    {\n        // function call, so this won't trigger `no_effect`. not an issue with this change, but the\n        // lint itself (but also not really.)\n        vec![0u16];\n    }\n    vec![]\n}\n\nfn i() -> () {\n    {\n        // does not suggest on function with explicit unit return type\n        ();\n        //~^ no_effect\n    }\n    ()\n}\n\nfn j() {\n    {\n        // does not suggest on function without explicit return type\n        ();\n        //~^ no_effect\n    }\n    ()\n}\n"
  },
  {
    "path": "tests/ui/no_effect_return.stderr",
    "content": "error: statement with no effect\n  --> tests/ui/no_effect_return.rs:9:9\n   |\nLL |         0u32;\n   |         -^^^^\n   |         |\n   |         help: did you mean to return it?: `return`\n   |\n   = note: `-D clippy::no-effect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::no_effect)]`\n\nerror: statement with no effect\n  --> tests/ui/no_effect_return.rs:17:9\n   |\nLL |         0u32;\n   |         -^^^^\n   |         |\n   |         help: did you mean to return it?: `return`\n\nerror: statement with no effect\n  --> tests/ui/no_effect_return.rs:26:9\n   |\nLL |         0i32 as C;\n   |         -^^^^^^^^^\n   |         |\n   |         help: did you mean to return it?: `return`\n\nerror: statement with no effect\n  --> tests/ui/no_effect_return.rs:35:9\n   |\nLL |         0u128;\n   |         ^^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect_return.rs:46:9\n   |\nLL |         0u16;\n   |         ^^^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect_return.rs:54:9\n   |\nLL |         [1u16];\n   |         -^^^^^^\n   |         |\n   |         help: did you mean to return it?: `return`\n\nerror: statement with no effect\n  --> tests/ui/no_effect_return.rs:62:9\n   |\nLL |         ControlFlow::Break::<()>(());\n   |         -^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |         |\n   |         help: did you mean to return it?: `return`\n\nerror: statement with no effect\n  --> tests/ui/no_effect_return.rs:80:9\n   |\nLL |         ();\n   |         ^^^\n\nerror: statement with no effect\n  --> tests/ui/no_effect_return.rs:89:9\n   |\nLL |         ();\n   |         ^^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/no_mangle_with_rust_abi.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![allow(unused)]\n#![warn(clippy::no_mangle_with_rust_abi)]\n\n#[unsafe(no_mangle)]\nfn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}\n//~^ no_mangle_with_rust_abi\n\n#[unsafe(no_mangle)]\npub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}\n//~^ no_mangle_with_rust_abi\n\n/// # Safety\n/// This function shouldn't be called unless the horsemen are ready\n#[unsafe(no_mangle)]\npub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}\n//~^ no_mangle_with_rust_abi\n\n/// # Safety\n/// This function shouldn't be called unless the horsemen are ready\n#[unsafe(no_mangle)]\nunsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}\n//~^ no_mangle_with_rust_abi\n\n#[unsafe(no_mangle)]\nfn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(\n    //~^ no_mangle_with_rust_abi\n    arg_one: u32,\n    arg_two: usize,\n) -> u32 {\n    0\n}\n\n// Must not run on functions that explicitly opt in to using the Rust ABI with `extern \"Rust\"`\n#[unsafe(no_mangle)]\n#[rustfmt::skip]\nextern \"Rust\" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {}\n\nfn rust_abi_fn_again(arg_one: u32, arg_two: usize) {}\n\n#[unsafe(no_mangle)]\nextern \"C\" fn c_abi_fn(arg_one: u32, arg_two: usize) {}\n\nextern \"C\" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {}\n\nunsafe extern \"C\" {\n    fn c_abi_in_block(arg_one: u32, arg_two: usize);\n}\n\nmod r#fn {\n    #[unsafe(no_mangle)]\n    pub(in super::r#fn) fn with_some_fn_around() {}\n    //~^ no_mangle_with_rust_abi\n}\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/no_mangle_with_rust_abi.stderr",
    "content": "error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi.rs:6:1\n   |\nLL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::no_mangle_with_rust_abi)]`\nhelp: set an ABI\n   |\nLL | extern \"C\" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}\n   | ++++++++++\nhelp: or explicitly set the default\n   |\nLL | extern \"Rust\" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}\n   | +++++++++++++\n\nerror: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi.rs:10:1\n   |\nLL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: set an ABI\n   |\nLL | pub extern \"C\" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}\n   |     ++++++++++\nhelp: or explicitly set the default\n   |\nLL | pub extern \"Rust\" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}\n   |     +++++++++++++\n\nerror: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi.rs:16:1\n   |\nLL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: set an ABI\n   |\nLL | pub unsafe extern \"C\" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}\n   |            ++++++++++\nhelp: or explicitly set the default\n   |\nLL | pub unsafe extern \"Rust\" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}\n   |            +++++++++++++\n\nerror: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi.rs:22:1\n   |\nLL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: set an ABI\n   |\nLL | unsafe extern \"C\" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}\n   |        ++++++++++\nhelp: or explicitly set the default\n   |\nLL | unsafe extern \"Rust\" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}\n   |        +++++++++++++\n\nerror: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi.rs:26:1\n   |\nLL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(\nLL | |\nLL | |     arg_one: u32,\nLL | |     arg_two: usize,\nLL | | ) -> u32 {\n   | |________^\n   |\nhelp: set an ABI\n   |\nLL | extern \"C\" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(\n   | ++++++++++\nhelp: or explicitly set the default\n   |\nLL | extern \"Rust\" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(\n   | +++++++++++++\n\nerror: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi.rs:52:5\n   |\nLL |     pub(in super::r#fn) fn with_some_fn_around() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: set an ABI\n   |\nLL |     pub(in super::r#fn) extern \"C\" fn with_some_fn_around() {}\n   |                         ++++++++++\nhelp: or explicitly set the default\n   |\nLL |     pub(in super::r#fn) extern \"Rust\" fn with_some_fn_around() {}\n   |                         +++++++++++++\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/no_mangle_with_rust_abi_2021.rs",
    "content": "//@edition:2021\n//\n// Edition 2024 requires the use of #[unsafe(no_mangle)]\n\n//@no-rustfix: overlapping suggestions\n#![allow(unused)]\n#![warn(clippy::no_mangle_with_rust_abi)]\n\n#[no_mangle]\nfn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}\n//~^ no_mangle_with_rust_abi\n\n#[no_mangle]\npub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}\n//~^ no_mangle_with_rust_abi\n\n/// # Safety\n/// This function shouldn't be called unless the horsemen are ready\n#[no_mangle]\npub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}\n//~^ no_mangle_with_rust_abi\n\n/// # Safety\n/// This function shouldn't be called unless the horsemen are ready\n#[no_mangle]\nunsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}\n//~^ no_mangle_with_rust_abi\n\n#[no_mangle]\nfn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(\n    //~^ no_mangle_with_rust_abi\n    arg_one: u32,\n    arg_two: usize,\n) -> u32 {\n    0\n}\n\n// Must not run on functions that explicitly opt in to using the Rust ABI with `extern \"Rust\"`\n#[no_mangle]\n#[rustfmt::skip]\nextern \"Rust\" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {}\n\nfn rust_abi_fn_again(arg_one: u32, arg_two: usize) {}\n\n#[no_mangle]\nextern \"C\" fn c_abi_fn(arg_one: u32, arg_two: usize) {}\n\nextern \"C\" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {}\n\nextern \"C\" {\n    fn c_abi_in_block(arg_one: u32, arg_two: usize);\n}\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/no_mangle_with_rust_abi_2021.stderr",
    "content": "error: `#[no_mangle]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi_2021.rs:10:1\n   |\nLL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::no_mangle_with_rust_abi)]`\nhelp: set an ABI\n   |\nLL | extern \"C\" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}\n   | ++++++++++\nhelp: or explicitly set the default\n   |\nLL | extern \"Rust\" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}\n   | +++++++++++++\n\nerror: `#[no_mangle]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi_2021.rs:14:1\n   |\nLL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: set an ABI\n   |\nLL | pub extern \"C\" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}\n   |     ++++++++++\nhelp: or explicitly set the default\n   |\nLL | pub extern \"Rust\" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}\n   |     +++++++++++++\n\nerror: `#[no_mangle]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi_2021.rs:20:1\n   |\nLL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: set an ABI\n   |\nLL | pub unsafe extern \"C\" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}\n   |            ++++++++++\nhelp: or explicitly set the default\n   |\nLL | pub unsafe extern \"Rust\" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}\n   |            +++++++++++++\n\nerror: `#[no_mangle]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi_2021.rs:26:1\n   |\nLL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: set an ABI\n   |\nLL | unsafe extern \"C\" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}\n   |        ++++++++++\nhelp: or explicitly set the default\n   |\nLL | unsafe extern \"Rust\" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}\n   |        +++++++++++++\n\nerror: `#[no_mangle]` set on a function with the default (`Rust`) ABI\n  --> tests/ui/no_mangle_with_rust_abi_2021.rs:30:1\n   |\nLL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(\nLL | |\nLL | |     arg_one: u32,\nLL | |     arg_two: usize,\nLL | | ) -> u32 {\n   | |________^\n   |\nhelp: set an ABI\n   |\nLL | extern \"C\" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(\n   | ++++++++++\nhelp: or explicitly set the default\n   |\nLL | extern \"Rust\" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(\n   | +++++++++++++\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_canonical_clone_impl.fixed",
    "content": "//@aux-build:proc_macro_derive.rs\n#![allow(clippy::clone_on_copy, unused)]\n#![allow(clippy::assigning_clones)]\n#![no_main]\n\nextern crate proc_macros;\nuse proc_macros::inline_macros;\n\n// lint\n\nstruct A(u32);\n\nimpl Clone for A {\n    fn clone(&self) -> Self { *self }\n\n    \n}\n\nimpl Copy for A {}\n\n// do not lint\n\nstruct B(u32);\n\nimpl Clone for B {\n    fn clone(&self) -> Self {\n        *self\n    }\n}\n\nimpl Copy for B {}\n\n// do not lint derived (clone's implementation is `*self` here anyway)\n\n#[derive(Clone, Copy)]\nstruct C(u32);\n\n// do not lint derived (fr this time)\n\nstruct D(u32);\n\n#[automatically_derived]\nimpl Clone for D {\n    fn clone(&self) -> Self {\n        Self(self.0)\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        source.clone();\n        *self = source.clone();\n    }\n}\n\nimpl Copy for D {}\n\n// do not lint if clone is not manually implemented\n\nstruct E(u32);\n\n#[automatically_derived]\nimpl Clone for E {\n    fn clone(&self) -> Self {\n        Self(self.0)\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        source.clone();\n        *self = source.clone();\n    }\n}\n\nimpl Copy for E {}\n\n// lint since clone is not derived\n\n#[derive(Copy)]\nstruct F(u32);\n\nimpl Clone for F {\n    fn clone(&self) -> Self { *self }\n\n    \n}\n\n// do not lint since copy has more restrictive bounds\n\n#[derive(Eq, PartialEq)]\nstruct Uwu<A: Copy>(A);\n\nimpl<A: Copy> Clone for Uwu<A> {\n    fn clone(&self) -> Self {\n        Self(self.0)\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        source.clone();\n        *self = source.clone();\n    }\n}\n\nimpl<A: std::fmt::Debug + Copy + Clone> Copy for Uwu<A> {}\n\n#[inline_macros]\nmod issue12788 {\n    use proc_macros::{external, with_span};\n\n    // lint -- not an external macro\n    inline!(\n        #[derive(Copy)]\n        pub struct A;\n\n        impl Clone for A {\n            fn clone(&self) -> Self { *self }\n        }\n    );\n\n    // do not lint -- should skip external macros\n    external!(\n        #[derive(Copy)]\n        pub struct B;\n\n        impl Clone for B {\n            fn clone(&self) -> Self {\n                todo!()\n            }\n        }\n    );\n\n    // do not lint -- should skip proc macros\n    #[derive(proc_macro_derive::NonCanonicalClone)]\n    pub struct C;\n\n    with_span!(\n        span\n\n        #[derive(Copy)]\n        struct D;\n        impl Clone for D {\n            fn clone(&self) -> Self {\n                todo!()\n            }\n        }\n    );\n}\n"
  },
  {
    "path": "tests/ui/non_canonical_clone_impl.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n#![allow(clippy::clone_on_copy, unused)]\n#![allow(clippy::assigning_clones)]\n#![no_main]\n\nextern crate proc_macros;\nuse proc_macros::inline_macros;\n\n// lint\n\nstruct A(u32);\n\nimpl Clone for A {\n    fn clone(&self) -> Self {\n        //~^ non_canonical_clone_impl\n        Self(self.0)\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        //~^ non_canonical_clone_impl\n        source.clone();\n        *self = source.clone();\n    }\n}\n\nimpl Copy for A {}\n\n// do not lint\n\nstruct B(u32);\n\nimpl Clone for B {\n    fn clone(&self) -> Self {\n        *self\n    }\n}\n\nimpl Copy for B {}\n\n// do not lint derived (clone's implementation is `*self` here anyway)\n\n#[derive(Clone, Copy)]\nstruct C(u32);\n\n// do not lint derived (fr this time)\n\nstruct D(u32);\n\n#[automatically_derived]\nimpl Clone for D {\n    fn clone(&self) -> Self {\n        Self(self.0)\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        source.clone();\n        *self = source.clone();\n    }\n}\n\nimpl Copy for D {}\n\n// do not lint if clone is not manually implemented\n\nstruct E(u32);\n\n#[automatically_derived]\nimpl Clone for E {\n    fn clone(&self) -> Self {\n        Self(self.0)\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        source.clone();\n        *self = source.clone();\n    }\n}\n\nimpl Copy for E {}\n\n// lint since clone is not derived\n\n#[derive(Copy)]\nstruct F(u32);\n\nimpl Clone for F {\n    fn clone(&self) -> Self {\n        //~^ non_canonical_clone_impl\n        Self(self.0)\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        //~^ non_canonical_clone_impl\n        source.clone();\n        *self = source.clone();\n    }\n}\n\n// do not lint since copy has more restrictive bounds\n\n#[derive(Eq, PartialEq)]\nstruct Uwu<A: Copy>(A);\n\nimpl<A: Copy> Clone for Uwu<A> {\n    fn clone(&self) -> Self {\n        Self(self.0)\n    }\n\n    fn clone_from(&mut self, source: &Self) {\n        source.clone();\n        *self = source.clone();\n    }\n}\n\nimpl<A: std::fmt::Debug + Copy + Clone> Copy for Uwu<A> {}\n\n#[inline_macros]\nmod issue12788 {\n    use proc_macros::{external, with_span};\n\n    // lint -- not an external macro\n    inline!(\n        #[derive(Copy)]\n        pub struct A;\n\n        impl Clone for A {\n            fn clone(&self) -> Self {\n                //~^ non_canonical_clone_impl\n                todo!()\n            }\n        }\n    );\n\n    // do not lint -- should skip external macros\n    external!(\n        #[derive(Copy)]\n        pub struct B;\n\n        impl Clone for B {\n            fn clone(&self) -> Self {\n                todo!()\n            }\n        }\n    );\n\n    // do not lint -- should skip proc macros\n    #[derive(proc_macro_derive::NonCanonicalClone)]\n    pub struct C;\n\n    with_span!(\n        span\n\n        #[derive(Copy)]\n        struct D;\n        impl Clone for D {\n            fn clone(&self) -> Self {\n                todo!()\n            }\n        }\n    );\n}\n"
  },
  {
    "path": "tests/ui/non_canonical_clone_impl.stderr",
    "content": "error: non-canonical implementation of `clone` on a `Copy` type\n  --> tests/ui/non_canonical_clone_impl.rs:14:29\n   |\nLL |       fn clone(&self) -> Self {\n   |  _____________________________^\nLL | |\nLL | |         Self(self.0)\nLL | |     }\n   | |_____^ help: change this to: `{ *self }`\n   |\n   = note: `-D clippy::non-canonical-clone-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_canonical_clone_impl)]`\n\nerror: unnecessary implementation of `clone_from` on a `Copy` type\n  --> tests/ui/non_canonical_clone_impl.rs:19:5\n   |\nLL | /     fn clone_from(&mut self, source: &Self) {\nLL | |\nLL | |         source.clone();\nLL | |         *self = source.clone();\nLL | |     }\n   | |_____^ help: remove it\n\nerror: non-canonical implementation of `clone` on a `Copy` type\n  --> tests/ui/non_canonical_clone_impl.rs:87:29\n   |\nLL |       fn clone(&self) -> Self {\n   |  _____________________________^\nLL | |\nLL | |         Self(self.0)\nLL | |     }\n   | |_____^ help: change this to: `{ *self }`\n\nerror: unnecessary implementation of `clone_from` on a `Copy` type\n  --> tests/ui/non_canonical_clone_impl.rs:92:5\n   |\nLL | /     fn clone_from(&mut self, source: &Self) {\nLL | |\nLL | |         source.clone();\nLL | |         *self = source.clone();\nLL | |     }\n   | |_____^ help: remove it\n\nerror: non-canonical implementation of `clone` on a `Copy` type\n  --> tests/ui/non_canonical_clone_impl.rs:127:37\n   |\nLL |               fn clone(&self) -> Self {\n   |  _____________________________________^\nLL | |\nLL | |                 todo!()\nLL | |             }\n   | |_____________^ help: change this to: `{ *self }`\n   |\n   = note: this error originates in the macro `__inline_mac_mod_issue12788` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_canonical_partial_ord_impl.fixed",
    "content": "//@aux-build:proc_macro_derive.rs\n#![no_main]\n\nextern crate proc_macros;\nuse proc_macros::inline_macros;\n\nuse std::cmp::Ordering;\n\n// lint\n\n#[derive(Eq, PartialEq)]\nstruct A(u32);\n\nimpl Ord for A {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for A {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n}\n\n// do not lint\n\n#[derive(Eq, PartialEq)]\nstruct B(u32);\n\nimpl Ord for B {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for B {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\n// lint, and give `_` a name\n\n#[derive(Eq, PartialEq)]\nstruct C(u32);\n\nimpl Ord for C {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for C {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n}\n\n// do not lint derived\n\n#[derive(Eq, Ord, PartialEq, PartialOrd)]\nstruct D(u32);\n\n// do not lint if ord is not manually implemented\n\n#[derive(Eq, PartialEq)]\nstruct E(u32);\n\nimpl PartialOrd for E {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        todo!();\n    }\n}\n\n// do not lint since ord has more restrictive bounds\n\n#[derive(Eq, PartialEq)]\nstruct Uwu<A>(A);\n\nimpl<A: std::fmt::Debug + Ord + PartialOrd> Ord for Uwu<A> {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl<A: Ord + PartialOrd> PartialOrd for Uwu<A> {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        todo!();\n    }\n}\n\n// do not lint since `Rhs` is not `Self`\n\n#[derive(Eq, PartialEq)]\nstruct F(u32);\n\nimpl Ord for F {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for F {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\nimpl PartialEq<u32> for F {\n    fn eq(&self, other: &u32) -> bool {\n        todo!();\n    }\n}\n\nimpl PartialOrd<u32> for F {\n    fn partial_cmp(&self, other: &u32) -> Option<Ordering> {\n        todo!();\n    }\n}\n\n// #11178, do not lint\n\n#[derive(Eq, PartialEq)]\nstruct G(u32);\n\nimpl Ord for G {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for G {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(Self::cmp(self, other))\n    }\n}\n\n#[derive(Eq, PartialEq)]\nstruct H(u32);\n\nimpl Ord for H {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for H {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(Ord::cmp(self, other))\n    }\n}\n\n// #12683, do not lint\n\n#[derive(Eq, PartialEq)]\nstruct I(u32);\n\nimpl Ord for I {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for I {\n    #[allow(clippy::needless_return)]\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        return Some(self.cmp(other));\n    }\n}\n\n#[inline_macros]\nmod issue12788 {\n    use std::cmp::Ordering;\n\n    use proc_macros::{external, with_span};\n\n    // lint -- not an external macro\n    inline!(\n        #[derive(PartialEq, Eq)]\n        pub struct A;\n\n        impl Ord for A {\n            fn cmp(&self, other: &Self) -> Ordering {\n                todo!();\n            }\n        }\n\n        impl PartialOrd for A {\n            //~^ non_canonical_partial_ord_impl\n            fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n        }\n    );\n\n    // do not lint -- should skip external macros\n    external!(\n        #[derive(PartialEq, Eq)]\n        pub struct B;\n\n        impl Ord for B {\n            fn cmp(&self, other: &Self) -> Ordering {\n                todo!();\n            }\n        }\n\n        impl PartialOrd for B {\n            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n                todo!();\n            }\n        }\n\n    );\n\n    // do not lint -- should skip proc macros\n    #[derive(proc_macro_derive::NonCanonicalClone)]\n    pub struct C;\n\n    with_span!(\n        span\n\n        #[derive(PartialEq, Eq)]\n        pub struct D;\n\n        impl Ord for D {\n            fn cmp(&self, other: &Self) -> Ordering {\n                todo!();\n            }\n        }\n\n        impl PartialOrd for D {\n            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n                todo!();\n            }\n        }\n\n    );\n}\n\n// #13640, do not lint\n\n#[derive(Eq, PartialEq)]\nstruct J(u32);\n\nimpl Ord for J {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for J {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        self.cmp(other).into()\n    }\n}\n\n// #13640, check that a simple `.into()` does not obliterate the lint\n\n#[derive(Eq, PartialEq)]\nstruct K(u32);\n\nimpl Ord for K {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for K {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n}\n\n// #14574, check that partial_cmp invokes other.cmp\n\n#[derive(Eq, PartialEq)]\nstruct L(u32);\n\nimpl Ord for L {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for L {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n}\n"
  },
  {
    "path": "tests/ui/non_canonical_partial_ord_impl.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n#![no_main]\n\nextern crate proc_macros;\nuse proc_macros::inline_macros;\n\nuse std::cmp::Ordering;\n\n// lint\n\n#[derive(Eq, PartialEq)]\nstruct A(u32);\n\nimpl Ord for A {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for A {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        todo!();\n    }\n}\n\n// do not lint\n\n#[derive(Eq, PartialEq)]\nstruct B(u32);\n\nimpl Ord for B {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for B {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\n// lint, and give `_` a name\n\n#[derive(Eq, PartialEq)]\nstruct C(u32);\n\nimpl Ord for C {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for C {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, _: &Self) -> Option<Ordering> {\n        todo!();\n    }\n}\n\n// do not lint derived\n\n#[derive(Eq, Ord, PartialEq, PartialOrd)]\nstruct D(u32);\n\n// do not lint if ord is not manually implemented\n\n#[derive(Eq, PartialEq)]\nstruct E(u32);\n\nimpl PartialOrd for E {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        todo!();\n    }\n}\n\n// do not lint since ord has more restrictive bounds\n\n#[derive(Eq, PartialEq)]\nstruct Uwu<A>(A);\n\nimpl<A: std::fmt::Debug + Ord + PartialOrd> Ord for Uwu<A> {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl<A: Ord + PartialOrd> PartialOrd for Uwu<A> {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        todo!();\n    }\n}\n\n// do not lint since `Rhs` is not `Self`\n\n#[derive(Eq, PartialEq)]\nstruct F(u32);\n\nimpl Ord for F {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for F {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(self.cmp(other))\n    }\n}\n\nimpl PartialEq<u32> for F {\n    fn eq(&self, other: &u32) -> bool {\n        todo!();\n    }\n}\n\nimpl PartialOrd<u32> for F {\n    fn partial_cmp(&self, other: &u32) -> Option<Ordering> {\n        todo!();\n    }\n}\n\n// #11178, do not lint\n\n#[derive(Eq, PartialEq)]\nstruct G(u32);\n\nimpl Ord for G {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for G {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(Self::cmp(self, other))\n    }\n}\n\n#[derive(Eq, PartialEq)]\nstruct H(u32);\n\nimpl Ord for H {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for H {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(Ord::cmp(self, other))\n    }\n}\n\n// #12683, do not lint\n\n#[derive(Eq, PartialEq)]\nstruct I(u32);\n\nimpl Ord for I {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for I {\n    #[allow(clippy::needless_return)]\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        return Some(self.cmp(other));\n    }\n}\n\n#[inline_macros]\nmod issue12788 {\n    use std::cmp::Ordering;\n\n    use proc_macros::{external, with_span};\n\n    // lint -- not an external macro\n    inline!(\n        #[derive(PartialEq, Eq)]\n        pub struct A;\n\n        impl Ord for A {\n            fn cmp(&self, other: &Self) -> Ordering {\n                todo!();\n            }\n        }\n\n        impl PartialOrd for A {\n            //~^ non_canonical_partial_ord_impl\n            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n                todo!();\n            }\n        }\n    );\n\n    // do not lint -- should skip external macros\n    external!(\n        #[derive(PartialEq, Eq)]\n        pub struct B;\n\n        impl Ord for B {\n            fn cmp(&self, other: &Self) -> Ordering {\n                todo!();\n            }\n        }\n\n        impl PartialOrd for B {\n            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n                todo!();\n            }\n        }\n\n    );\n\n    // do not lint -- should skip proc macros\n    #[derive(proc_macro_derive::NonCanonicalClone)]\n    pub struct C;\n\n    with_span!(\n        span\n\n        #[derive(PartialEq, Eq)]\n        pub struct D;\n\n        impl Ord for D {\n            fn cmp(&self, other: &Self) -> Ordering {\n                todo!();\n            }\n        }\n\n        impl PartialOrd for D {\n            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n                todo!();\n            }\n        }\n\n    );\n}\n\n// #13640, do not lint\n\n#[derive(Eq, PartialEq)]\nstruct J(u32);\n\nimpl Ord for J {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for J {\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        self.cmp(other).into()\n    }\n}\n\n// #13640, check that a simple `.into()` does not obliterate the lint\n\n#[derive(Eq, PartialEq)]\nstruct K(u32);\n\nimpl Ord for K {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for K {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Ordering::Greater.into()\n    }\n}\n\n// #14574, check that partial_cmp invokes other.cmp\n\n#[derive(Eq, PartialEq)]\nstruct L(u32);\n\nimpl Ord for L {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for L {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        Some(other.cmp(self))\n    }\n}\n"
  },
  {
    "path": "tests/ui/non_canonical_partial_ord_impl.stderr",
    "content": "error: non-canonical implementation of `partial_cmp` on an `Ord` type\n  --> tests/ui/non_canonical_partial_ord_impl.rs:20:1\n   |\nLL | / impl PartialOrd for A {\nLL | |\nLL | |     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL | |         todo!();\nLL | |     }\nLL | | }\n   | |_^\n   |\n   = note: `-D clippy::non-canonical-partial-ord-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_canonical_partial_ord_impl)]`\nhelp: change this to\n   |\nLL -     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL -         todo!();\nLL -     }\nLL +     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n   |\n\nerror: non-canonical implementation of `partial_cmp` on an `Ord` type\n  --> tests/ui/non_canonical_partial_ord_impl.rs:55:1\n   |\nLL | / impl PartialOrd for C {\nLL | |\nLL | |     fn partial_cmp(&self, _: &Self) -> Option<Ordering> {\nLL | |         todo!();\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL -     fn partial_cmp(&self, _: &Self) -> Option<Ordering> {\nLL -         todo!();\nLL -     }\nLL +     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n   |\n\nerror: non-canonical implementation of `partial_cmp` on an `Ord` type\n  --> tests/ui/non_canonical_partial_ord_impl.rs:191:9\n   |\nLL | /         impl PartialOrd for A {\nLL | |\nLL | |             fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL | |                 todo!();\nLL | |             }\nLL | |         }\n   | |_________^\n   |\n   = note: this error originates in the macro `__inline_mac_mod_issue12788` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: change this to\n   |\nLL -             fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL -                 todo!();\nLL -             }\nLL +             fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n   |\n\nerror: non-canonical implementation of `partial_cmp` on an `Ord` type\n  --> tests/ui/non_canonical_partial_ord_impl.rs:271:1\n   |\nLL | / impl PartialOrd for K {\nLL | |\nLL | |     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL | |         Ordering::Greater.into()\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL -     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL -         Ordering::Greater.into()\nLL -     }\nLL +     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n   |\n\nerror: non-canonical implementation of `partial_cmp` on an `Ord` type\n  --> tests/ui/non_canonical_partial_ord_impl.rs:289:1\n   |\nLL | / impl PartialOrd for L {\nLL | |\nLL | |     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL | |         Some(other.cmp(self))\nLL | |     }\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL -     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL -         Some(other.cmp(self))\nLL -     }\nLL +     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_canonical_partial_ord_impl_fully_qual.rs",
    "content": "// This test's filename is... a bit verbose. But it ensures we suggest the correct code when `Ord`\n// is not in scope.\n#![no_main]\n#![no_implicit_prelude]\n//@no-rustfix\nextern crate std;\n\nuse std::cmp::{self, Eq, Ordering, PartialEq, PartialOrd};\nuse std::option::Option::{self, Some};\nuse std::todo;\n\n// lint\n\n#[derive(Eq, PartialEq)]\nstruct A(u32);\n\nimpl cmp::Ord for A {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for A {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        // NOTE: This suggestion is wrong, as `Ord` is not in scope. But this should be fine as it isn't\n        // automatically applied\n        todo!();\n    }\n}\n\n#[derive(Eq, PartialEq)]\nstruct B(u32);\n\nimpl B {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl cmp::Ord for B {\n    fn cmp(&self, other: &Self) -> Ordering {\n        todo!();\n    }\n}\n\nimpl PartialOrd for B {\n    //~^ non_canonical_partial_ord_impl\n    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n        // This calls `B.cmp`, not `Ord::cmp`!\n        Some(self.cmp(other))\n    }\n}\n"
  },
  {
    "path": "tests/ui/non_canonical_partial_ord_impl_fully_qual.stderr",
    "content": "error: non-canonical implementation of `partial_cmp` on an `Ord` type\n  --> tests/ui/non_canonical_partial_ord_impl_fully_qual.rs:23:1\n   |\nLL | / impl PartialOrd for A {\nLL | |\nLL | |     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n...  |\nLL | | }\n   | |_^\n   |\n   = note: `-D clippy::non-canonical-partial-ord-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_canonical_partial_ord_impl)]`\nhelp: change this to\n   |\nLL -     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL -         // NOTE: This suggestion is wrong, as `Ord` is not in scope. But this should be fine as it isn't\nLL -         // automatically applied\nLL -         todo!();\nLL -     }\nLL +     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }\n   |\n\nerror: non-canonical implementation of `partial_cmp` on an `Ord` type\n  --> tests/ui/non_canonical_partial_ord_impl_fully_qual.rs:47:1\n   |\nLL | / impl PartialOrd for B {\nLL | |\nLL | |     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\n...  |\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL -     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {\nLL -         // This calls `B.cmp`, not `Ord::cmp`!\nLL -         Some(self.cmp(other))\nLL -     }\nLL +     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(std::cmp::Ord::cmp(self, other)) }\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_expressive_names.rs",
    "content": "#![allow(clippy::println_empty_string, non_snake_case, clippy::let_unit_value)]\n\n#[derive(Clone, Debug)]\nenum MaybeInst {\n    Split,\n    Split1(usize),\n    Split2(usize),\n}\n\nstruct InstSplit {\n    uiae: usize,\n}\n\nimpl MaybeInst {\n    fn fill(&mut self) {\n        #[allow(non_fmt_panics)]\n        let filled = match *self {\n            MaybeInst::Split1(goto1) => panic!(\"1\"),\n            MaybeInst::Split2(goto2) => panic!(\"2\"),\n            _ => unimplemented!(),\n        };\n        unimplemented!()\n    }\n}\n\nfn underscores_and_numbers() {\n    let _1 = 1;\n    //~^ just_underscores_and_digits\n    let ____1 = 1;\n    //~^ just_underscores_and_digits\n    let __1___2 = 12;\n    //~^ just_underscores_and_digits\n    let _1_ok = 1;\n}\n\nfn issue2927() {\n    let args = 1;\n    format!(\"{:?}\", 2);\n}\n\nfn issue3078() {\n    #[allow(clippy::single_match)]\n    match \"a\" {\n        stringify!(a) => {},\n        _ => {},\n    }\n}\n\nstruct Bar;\n\nimpl Bar {\n    fn bar() {\n        let _1 = 1;\n        //~^ just_underscores_and_digits\n        let ____1 = 1;\n        //~^ just_underscores_and_digits\n        let __1___2 = 12;\n        //~^ just_underscores_and_digits\n        let _1_ok = 1;\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/non_expressive_names.stderr",
    "content": "error: consider choosing a more descriptive name\n  --> tests/ui/non_expressive_names.rs:27:9\n   |\nLL |     let _1 = 1;\n   |         ^^\n   |\n   = note: `-D clippy::just-underscores-and-digits` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::just_underscores_and_digits)]`\n\nerror: consider choosing a more descriptive name\n  --> tests/ui/non_expressive_names.rs:29:9\n   |\nLL |     let ____1 = 1;\n   |         ^^^^^\n\nerror: consider choosing a more descriptive name\n  --> tests/ui/non_expressive_names.rs:31:9\n   |\nLL |     let __1___2 = 12;\n   |         ^^^^^^^\n\nerror: consider choosing a more descriptive name\n  --> tests/ui/non_expressive_names.rs:53:13\n   |\nLL |         let _1 = 1;\n   |             ^^\n\nerror: consider choosing a more descriptive name\n  --> tests/ui/non_expressive_names.rs:55:13\n   |\nLL |         let ____1 = 1;\n   |             ^^^^^\n\nerror: consider choosing a more descriptive name\n  --> tests/ui/non_expressive_names.rs:57:13\n   |\nLL |         let __1___2 = 12;\n   |             ^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_expressive_names_error_recovery.fixed",
    "content": "// https://github.com/rust-lang/rust-clippy/issues/12302\nuse std::marker::PhantomData;\n\npub struct Aa<T>(PhantomData<T>);\n\nfn aa(a: Aa<String>) {\n//~^ ERROR: expected one of\n\n}\n"
  },
  {
    "path": "tests/ui/non_expressive_names_error_recovery.rs",
    "content": "// https://github.com/rust-lang/rust-clippy/issues/12302\nuse std::marker::PhantomData;\n\npub struct Aa<T>(PhantomData<T>);\n\nfn aa(a: Aa<String) {\n//~^ ERROR: expected one of\n\n}\n"
  },
  {
    "path": "tests/ui/non_expressive_names_error_recovery.stderr",
    "content": "error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `)`\n  --> tests/ui/non_expressive_names_error_recovery.rs:6:19\n   |\nLL | fn aa(a: Aa<String) {\n   |                   ^ expected one of 7 possible tokens\n   |\nhelp: you might have meant to end the type parameters here\n   |\nLL | fn aa(a: Aa<String>) {\n   |                   +\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/non_minimal_cfg.fixed",
    "content": "#![allow(unused)]\n\n#[cfg(windows)]\n//~^ non_minimal_cfg\nfn hermit() {}\n\n#[cfg(windows)]\n//~^ non_minimal_cfg\nfn wasi() {}\n\n#[cfg(all(unix, not(windows)))]\n//~^ non_minimal_cfg\n//~| non_minimal_cfg\nfn the_end() {}\n\n#[cfg(any())]\nfn any() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/non_minimal_cfg.rs",
    "content": "#![allow(unused)]\n\n#[cfg(all(windows))]\n//~^ non_minimal_cfg\nfn hermit() {}\n\n#[cfg(any(windows))]\n//~^ non_minimal_cfg\nfn wasi() {}\n\n#[cfg(all(any(unix), all(not(windows))))]\n//~^ non_minimal_cfg\n//~| non_minimal_cfg\nfn the_end() {}\n\n#[cfg(any())]\nfn any() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/non_minimal_cfg.stderr",
    "content": "error: unneeded sub `cfg` when there is only one condition\n  --> tests/ui/non_minimal_cfg.rs:3:7\n   |\nLL | #[cfg(all(windows))]\n   |       ^^^^^^^^^^^^ help: try: `windows`\n   |\n   = note: `-D clippy::non-minimal-cfg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_minimal_cfg)]`\n\nerror: unneeded sub `cfg` when there is only one condition\n  --> tests/ui/non_minimal_cfg.rs:7:7\n   |\nLL | #[cfg(any(windows))]\n   |       ^^^^^^^^^^^^ help: try: `windows`\n\nerror: unneeded sub `cfg` when there is only one condition\n  --> tests/ui/non_minimal_cfg.rs:11:11\n   |\nLL | #[cfg(all(any(unix), all(not(windows))))]\n   |           ^^^^^^^^^ help: try: `unix`\n\nerror: unneeded sub `cfg` when there is only one condition\n  --> tests/ui/non_minimal_cfg.rs:11:22\n   |\nLL | #[cfg(all(any(unix), all(not(windows))))]\n   |                      ^^^^^^^^^^^^^^^^^ help: try: `not(windows)`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_minimal_cfg2.rs",
    "content": "//@require-annotations-for-level: WARN\n#![allow(unused)]\n\n#[cfg(all())]\n//~^ ERROR: unneeded sub `cfg` when there is no condition\n//~| NOTE: `-D clippy::non-minimal-cfg` implied by `-D warnings`\nfn all() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/non_minimal_cfg2.stderr",
    "content": "error: unneeded sub `cfg` when there is no condition\n  --> tests/ui/non_minimal_cfg2.rs:4:7\n   |\nLL | #[cfg(all())]\n   |       ^^^^^\n   |\n   = note: `-D clippy::non-minimal-cfg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_minimal_cfg)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/non_octal_unix_permissions.fixed",
    "content": "//@ignore-target: windows\n\n#![warn(clippy::non_octal_unix_permissions)]\nuse std::fs::{DirBuilder, File, OpenOptions, Permissions};\nuse std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt};\n\nfn main() {\n    let permissions = 0o760;\n\n    // OpenOptionsExt::mode\n    let mut options = OpenOptions::new();\n    options.mode(0o440);\n    //~^ non_octal_unix_permissions\n    options.mode(0o400);\n    options.mode(permissions);\n\n    // PermissionsExt::from_mode\n    let _permissions = Permissions::from_mode(0o647);\n    //~^ non_octal_unix_permissions\n    let _permissions = Permissions::from_mode(0o000);\n    let _permissions = Permissions::from_mode(permissions);\n\n    // PermissionsExt::set_mode\n    let f = File::create(\"foo.txt\").unwrap();\n    let metadata = f.metadata().unwrap();\n    let mut permissions = metadata.permissions();\n\n    permissions.set_mode(0o644);\n    //~^ non_octal_unix_permissions\n    permissions.set_mode(0o704);\n    // no error\n    permissions.set_mode(0b111_000_100);\n\n    // DirBuilderExt::mode\n    let mut builder = DirBuilder::new();\n    builder.mode(0o755);\n    //~^ non_octal_unix_permissions\n    builder.mode(0o406);\n    // no error\n    permissions.set_mode(0b111000100);\n}\n"
  },
  {
    "path": "tests/ui/non_octal_unix_permissions.rs",
    "content": "//@ignore-target: windows\n\n#![warn(clippy::non_octal_unix_permissions)]\nuse std::fs::{DirBuilder, File, OpenOptions, Permissions};\nuse std::os::unix::fs::{DirBuilderExt, OpenOptionsExt, PermissionsExt};\n\nfn main() {\n    let permissions = 0o760;\n\n    // OpenOptionsExt::mode\n    let mut options = OpenOptions::new();\n    options.mode(440);\n    //~^ non_octal_unix_permissions\n    options.mode(0o400);\n    options.mode(permissions);\n\n    // PermissionsExt::from_mode\n    let _permissions = Permissions::from_mode(647);\n    //~^ non_octal_unix_permissions\n    let _permissions = Permissions::from_mode(0o000);\n    let _permissions = Permissions::from_mode(permissions);\n\n    // PermissionsExt::set_mode\n    let f = File::create(\"foo.txt\").unwrap();\n    let metadata = f.metadata().unwrap();\n    let mut permissions = metadata.permissions();\n\n    permissions.set_mode(644);\n    //~^ non_octal_unix_permissions\n    permissions.set_mode(0o704);\n    // no error\n    permissions.set_mode(0b111_000_100);\n\n    // DirBuilderExt::mode\n    let mut builder = DirBuilder::new();\n    builder.mode(755);\n    //~^ non_octal_unix_permissions\n    builder.mode(0o406);\n    // no error\n    permissions.set_mode(0b111000100);\n}\n"
  },
  {
    "path": "tests/ui/non_octal_unix_permissions.stderr",
    "content": "error: using a non-octal value to set unix file permissions\n  --> tests/ui/non_octal_unix_permissions.rs:12:18\n   |\nLL |     options.mode(440);\n   |                  ^^^ help: consider using an octal literal instead: `0o440`\n   |\n   = note: `-D clippy::non-octal-unix-permissions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_octal_unix_permissions)]`\n\nerror: using a non-octal value to set unix file permissions\n  --> tests/ui/non_octal_unix_permissions.rs:18:47\n   |\nLL |     let _permissions = Permissions::from_mode(647);\n   |                                               ^^^ help: consider using an octal literal instead: `0o647`\n\nerror: using a non-octal value to set unix file permissions\n  --> tests/ui/non_octal_unix_permissions.rs:28:26\n   |\nLL |     permissions.set_mode(644);\n   |                          ^^^ help: consider using an octal literal instead: `0o644`\n\nerror: using a non-octal value to set unix file permissions\n  --> tests/ui/non_octal_unix_permissions.rs:36:18\n   |\nLL |     builder.mode(755);\n   |                  ^^^ help: consider using an octal literal instead: `0o755`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_send_fields_in_send_ty.rs",
    "content": "#![warn(clippy::non_send_fields_in_send_ty)]\n#![feature(extern_types)]\n\nuse std::cell::UnsafeCell;\nuse std::ptr::NonNull;\nuse std::rc::Rc;\nuse std::sync::{Arc, Mutex, MutexGuard};\n\n// disrustor / RUSTSEC-2020-0150\npub struct RingBuffer<T> {\n    data: Vec<UnsafeCell<T>>,\n    capacity: usize,\n    mask: usize,\n}\n\nunsafe impl<T> Send for RingBuffer<T> {}\n//~^ ERROR: some fields in `RingBuffer<T>` are not safe to be sent to another thread\n\n// noise_search / RUSTSEC-2020-0141\npub struct MvccRwLock<T> {\n    raw: *const T,\n    lock: Mutex<Box<T>>,\n}\n\nunsafe impl<T> Send for MvccRwLock<T> {}\n//~^ ERROR: some fields in `MvccRwLock<T>` are not safe to be sent to another thread\n\n// async-coap / RUSTSEC-2020-0124\npub struct ArcGuard<RC, T> {\n    inner: T,\n    head: Arc<RC>,\n}\n\nunsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}\n//~^ ERROR: some fields in `ArcGuard<RC, T>` are not safe to be sent to another thread\n\n// rusb / RUSTSEC-2020-0098\nunsafe extern \"C\" {\n    type libusb_device_handle;\n}\n\npub trait UsbContext {\n    // some user trait that does not guarantee `Send`\n}\n\npub struct DeviceHandle<T: UsbContext> {\n    context: T,\n    handle: NonNull<libusb_device_handle>,\n}\n\nunsafe impl<T: UsbContext> Send for DeviceHandle<T> {}\n//~^ ERROR: some fields in `DeviceHandle<T>` are not safe to be sent to another thread\n\n// Other basic tests\npub struct NoGeneric {\n    rc_is_not_send: Rc<String>,\n}\n\nunsafe impl Send for NoGeneric {}\n//~^ ERROR: some fields in `NoGeneric` are not safe to be sent to another thread\n\npub struct MultiField<T> {\n    field1: T,\n    field2: T,\n    field3: T,\n}\n\nunsafe impl<T> Send for MultiField<T> {}\n//~^ ERROR: some fields in `MultiField<T>` are not safe to be sent to another thread\n\npub enum MyOption<T> {\n    MySome(T),\n    MyNone,\n}\n\nunsafe impl<T> Send for MyOption<T> {}\n//~^ ERROR: some fields in `MyOption<T>` are not safe to be sent to another thread\n\n// Test types that contain `NonNull` instead of raw pointers (#8045)\npub struct WrappedNonNull(UnsafeCell<NonNull<()>>);\n\nunsafe impl Send for WrappedNonNull {}\n\n// Multiple type parameters\npub struct MultiParam<A, B> {\n    vec: Vec<(A, B)>,\n}\n\nunsafe impl<A, B> Send for MultiParam<A, B> {}\n//~^ ERROR: some fields in `MultiParam<A, B>` are not safe to be sent to another thread\n\n// Tests for raw pointer heuristic\nunsafe extern \"C\" {\n    type NonSend;\n}\n\npub struct HeuristicTest {\n    // raw pointers are allowed\n    field1: Vec<*const NonSend>,\n    field2: [*const NonSend; 3],\n    field3: (*const NonSend, *const NonSend, *const NonSend),\n    // not allowed when it contains concrete `!Send` field\n    field4: (*const NonSend, Rc<u8>),\n    // nested raw pointer is also allowed\n    field5: Vec<Vec<*const NonSend>>,\n}\n\nunsafe impl Send for HeuristicTest {}\n//~^ ERROR: some fields in `HeuristicTest` are not safe to be sent to another thread\n\n// Test attributes\n#[allow(clippy::non_send_fields_in_send_ty)]\npub struct AttrTest1<T>(T);\n\npub struct AttrTest2<T> {\n    #[allow(clippy::non_send_fields_in_send_ty)]\n    field: T,\n}\n\npub enum AttrTest3<T> {\n    #[allow(clippy::non_send_fields_in_send_ty)]\n    Enum1(T),\n    Enum2(T),\n}\n\nunsafe impl<T> Send for AttrTest1<T> {}\nunsafe impl<T> Send for AttrTest2<T> {}\nunsafe impl<T> Send for AttrTest3<T> {}\n//~^ ERROR: some fields in `AttrTest3<T>` are not safe to be sent to another thread\n\n// Multiple non-overlapping `Send` for a single type\npub struct Complex<A, B> {\n    field1: A,\n    field2: B,\n}\n\nunsafe impl<P> Send for Complex<P, u32> {}\n//~^ ERROR: some fields in `Complex<P, u32>` are not safe to be sent to another thread\n\n// `MutexGuard` is non-Send\nunsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}\n//~^ ERROR: some fields in `Complex<Q, MutexGuard<'static, bool>>` are not safe to be sent\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/non_send_fields_in_send_ty.stderr",
    "content": "error: some fields in `RingBuffer<T>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:16:1\n   |\nLL | unsafe impl<T> Send for RingBuffer<T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `data` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:11:5\n   |\nLL |     data: Vec<UnsafeCell<T>>,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: add bounds on type parameter `T` that satisfy `Vec<UnsafeCell<T>>: Send`\n   = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_send_fields_in_send_ty)]`\n\nerror: some fields in `MvccRwLock<T>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:25:1\n   |\nLL | unsafe impl<T> Send for MvccRwLock<T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `lock` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:22:5\n   |\nLL |     lock: Mutex<Box<T>>,\n   |     ^^^^^^^^^^^^^^^^^^^\n   = help: add bounds on type parameter `T` that satisfy `Mutex<Box<T>>: Send`\n\nerror: some fields in `ArcGuard<RC, T>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:34:1\n   |\nLL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `head` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:31:5\n   |\nLL |     head: Arc<RC>,\n   |     ^^^^^^^^^^^^^\n   = help: add bounds on type parameter `RC` that satisfy `Arc<RC>: Send`\n\nerror: some fields in `DeviceHandle<T>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:51:1\n   |\nLL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `context` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:47:5\n   |\nLL |     context: T,\n   |     ^^^^^^^^^^\n   = help: add `T: Send` bound in `Send` impl\n\nerror: some fields in `NoGeneric` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:59:1\n   |\nLL | unsafe impl Send for NoGeneric {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `rc_is_not_send` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:56:5\n   |\nLL |     rc_is_not_send: Rc<String>,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\n\nerror: some fields in `MultiField<T>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:68:1\n   |\nLL | unsafe impl<T> Send for MultiField<T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `field1` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:63:5\n   |\nLL |     field1: T,\n   |     ^^^^^^^^^\n   = help: add `T: Send` bound in `Send` impl\nnote: it is not safe to send field `field2` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:64:5\n   |\nLL |     field2: T,\n   |     ^^^^^^^^^\n   = help: add `T: Send` bound in `Send` impl\nnote: it is not safe to send field `field3` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:65:5\n   |\nLL |     field3: T,\n   |     ^^^^^^^^^\n   = help: add `T: Send` bound in `Send` impl\n\nerror: some fields in `MyOption<T>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:76:1\n   |\nLL | unsafe impl<T> Send for MyOption<T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `0` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:72:12\n   |\nLL |     MySome(T),\n   |            ^\n   = help: add `T: Send` bound in `Send` impl\n\nerror: some fields in `MultiParam<A, B>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:89:1\n   |\nLL | unsafe impl<A, B> Send for MultiParam<A, B> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `vec` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:86:5\n   |\nLL |     vec: Vec<(A, B)>,\n   |     ^^^^^^^^^^^^^^^^\n   = help: add bounds on type parameters `A, B` that satisfy `Vec<(A, B)>: Send`\n\nerror: some fields in `HeuristicTest` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:108:1\n   |\nLL | unsafe impl Send for HeuristicTest {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `field4` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:103:5\n   |\nLL |     field4: (*const NonSend, Rc<u8>),\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\n\nerror: some fields in `AttrTest3<T>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:128:1\n   |\nLL | unsafe impl<T> Send for AttrTest3<T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `0` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:123:11\n   |\nLL |     Enum2(T),\n   |           ^\n   = help: add `T: Send` bound in `Send` impl\n\nerror: some fields in `Complex<P, u32>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:137:1\n   |\nLL | unsafe impl<P> Send for Complex<P, u32> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `field1` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:133:5\n   |\nLL |     field1: A,\n   |     ^^^^^^^^^\n   = help: add `P: Send` bound in `Send` impl\n\nerror: some fields in `Complex<Q, MutexGuard<'static, bool>>` are not safe to be sent to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:141:1\n   |\nLL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `field2` to another thread\n  --> tests/ui/non_send_fields_in_send_ty.rs:134:5\n   |\nLL |     field2: B,\n   |     ^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/auxiliary/lazy_static.rs",
    "content": "//! **FAKE** lazy_static crate.\n\n#[macro_export]\nmacro_rules! lazy_static {\n    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {\n        static $N : &::core::marker::PhantomData<$T> = &::core::marker::PhantomData;\n\n        $crate::lazy_static! { $($t)* }\n    };\n    () => ()\n}\n\n#[macro_export]\nmacro_rules! external {\n    () => {\n        $crate::lazy_static! {\n            static ref LZ_DERP: u32 = 12;\n        }\n    };\n}\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/auxiliary/once_cell.rs",
    "content": "//! **FAKE** once_cell crate.\n\npub mod sync {\n    use std::marker::PhantomData;\n\n    pub struct Lazy<T, F = fn() -> T> {\n        cell: PhantomData<T>,\n        init: F,\n    }\n    unsafe impl<T, F: Send> Sync for Lazy<T, F> {}\n    impl<T, F> Lazy<T, F> {\n        pub const fn new(f: F) -> Lazy<T, F> {\n            Lazy {\n                cell: PhantomData,\n                init: f,\n            }\n        }\n\n        pub fn into_value(this: Lazy<T, F>) -> Result<T, F> {\n            unimplemented!()\n        }\n\n        pub fn force(_this: &Lazy<T, F>) -> &T {\n            unimplemented!()\n        }\n\n        pub fn force_mut(_this: &mut Lazy<T, F>) -> &mut T {\n            unimplemented!()\n        }\n\n        pub fn get(_this: &Lazy<T, F>) -> Option<&T> {\n            unimplemented!()\n        }\n\n        pub fn get_mut(_this: &mut Lazy<T, F>) -> Option<&mut T> {\n            unimplemented!()\n        }\n    }\n}\npub mod race {\n    pub struct OnceBox<T>(T);\n\n    impl<T> OnceBox<T> {\n        pub fn get(&self) -> Option<&T> {\n            Some(&self.0)\n        }\n    }\n}\n\n#[macro_export]\nmacro_rules! external {\n    () => {\n        static OC_DERP: $crate::sync::Lazy<u32> = $crate::sync::Lazy::new(|| 12);\n    };\n}\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.fixed",
    "content": "//@aux-build:once_cell.rs\n//@aux-build:lazy_static.rs\n\n#![warn(clippy::non_std_lazy_statics)]\n#![allow(static_mut_refs)]\n\nuse once_cell::sync::Lazy;\n\nfn main() {}\n\nstatic LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"foo\".to_uppercase());\n//~^ ERROR: this type has been superseded by `LazyLock` in the standard library\nstatic LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    let x = \"bar\";\n    x.to_uppercase()\n});\nstatic LAZY_BAZ: std::sync::LazyLock<String> = { std::sync::LazyLock::new(|| \"baz\".to_uppercase()) };\n//~^ ERROR: this type has been superseded by `LazyLock` in the standard library\nstatic LAZY_QUX: std::sync::LazyLock<String> = {\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    if \"qux\".len() == 3 {\n        std::sync::LazyLock::new(|| \"qux\".to_uppercase())\n    } else if \"qux\".is_ascii() {\n        std::sync::LazyLock::new(|| \"qux\".to_lowercase())\n    } else {\n        std::sync::LazyLock::new(|| \"qux\".to_string())\n    }\n};\n\nfn non_static() {\n    let _: Lazy<i32> = Lazy::new(|| 1);\n    let _: Lazy<String> = Lazy::new(|| String::from(\"hello\"));\n    #[allow(clippy::declare_interior_mutable_const)]\n    const DONT_DO_THIS: Lazy<i32> = Lazy::new(|| 1);\n}\n\nmod once_cell_lazy_with_fns {\n    use once_cell::sync::Lazy;\n\n    static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"foo\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"bar\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    static mut LAZY_BAZ: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"baz\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n\n    fn calling_replaceable_fns() {\n        let _ = std::sync::LazyLock::force(&LAZY_FOO);\n        let _ = std::sync::LazyLock::force(&LAZY_BAR);\n        unsafe {\n            let _ = std::sync::LazyLock::force(&LAZY_BAZ);\n        }\n    }\n}\n\n#[clippy::msrv = \"1.79\"]\nmod msrv_not_meet {\n    use lazy_static::lazy_static;\n    use once_cell::sync::Lazy;\n\n    static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n\n    lazy_static! {\n        static ref LAZY_BAZ: f64 = 12.159 * 548;\n    }\n}\n\nmod external_macros {\n    once_cell::external!();\n    lazy_static::external!();\n}\n\nmod issue14729 {\n    use once_cell::sync::Lazy;\n\n    #[expect(clippy::non_std_lazy_statics)]\n    static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n}\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs",
    "content": "//@aux-build:once_cell.rs\n//@aux-build:lazy_static.rs\n\n#![warn(clippy::non_std_lazy_statics)]\n#![allow(static_mut_refs)]\n\nuse once_cell::sync::Lazy;\n\nfn main() {}\n\nstatic LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n//~^ ERROR: this type has been superseded by `LazyLock` in the standard library\nstatic LAZY_BAR: Lazy<String> = Lazy::new(|| {\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    let x = \"bar\";\n    x.to_uppercase()\n});\nstatic LAZY_BAZ: Lazy<String> = { Lazy::new(|| \"baz\".to_uppercase()) };\n//~^ ERROR: this type has been superseded by `LazyLock` in the standard library\nstatic LAZY_QUX: Lazy<String> = {\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    if \"qux\".len() == 3 {\n        Lazy::new(|| \"qux\".to_uppercase())\n    } else if \"qux\".is_ascii() {\n        Lazy::new(|| \"qux\".to_lowercase())\n    } else {\n        Lazy::new(|| \"qux\".to_string())\n    }\n};\n\nfn non_static() {\n    let _: Lazy<i32> = Lazy::new(|| 1);\n    let _: Lazy<String> = Lazy::new(|| String::from(\"hello\"));\n    #[allow(clippy::declare_interior_mutable_const)]\n    const DONT_DO_THIS: Lazy<i32> = Lazy::new(|| 1);\n}\n\nmod once_cell_lazy_with_fns {\n    use once_cell::sync::Lazy;\n\n    static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    static LAZY_BAR: Lazy<String> = Lazy::new(|| \"bar\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| \"baz\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n\n    fn calling_replaceable_fns() {\n        let _ = Lazy::force(&LAZY_FOO);\n        let _ = Lazy::force(&LAZY_BAR);\n        unsafe {\n            let _ = Lazy::force(&LAZY_BAZ);\n        }\n    }\n}\n\n#[clippy::msrv = \"1.79\"]\nmod msrv_not_meet {\n    use lazy_static::lazy_static;\n    use once_cell::sync::Lazy;\n\n    static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n\n    lazy_static! {\n        static ref LAZY_BAZ: f64 = 12.159 * 548;\n    }\n}\n\nmod external_macros {\n    once_cell::external!();\n    lazy_static::external!();\n}\n\nmod issue14729 {\n    use once_cell::sync::Lazy;\n\n    #[expect(clippy::non_std_lazy_statics)]\n    static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n}\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr",
    "content": "error: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:11:18\n   |\nLL | static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n   |                  ^^^^\n   |\n   = note: `-D clippy::non-std-lazy-statics` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_std_lazy_statics)]`\nhelp: use `std::sync::LazyLock` instead\n   |\nLL - static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\nLL + static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"foo\".to_uppercase());\n   |\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:13:18\n   |\nLL | static LAZY_BAR: Lazy<String> = Lazy::new(|| {\n   |                  ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL - static LAZY_BAR: Lazy<String> = Lazy::new(|| {\nLL + static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {\n   |\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:18:18\n   |\nLL | static LAZY_BAZ: Lazy<String> = { Lazy::new(|| \"baz\".to_uppercase()) };\n   |                  ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL - static LAZY_BAZ: Lazy<String> = { Lazy::new(|| \"baz\".to_uppercase()) };\nLL + static LAZY_BAZ: std::sync::LazyLock<String> = { std::sync::LazyLock::new(|| \"baz\".to_uppercase()) };\n   |\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:20:18\n   |\nLL | static LAZY_QUX: Lazy<String> = {\n   |                  ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL ~ static LAZY_QUX: std::sync::LazyLock<String> = {\nLL |\nLL |     if \"qux\".len() == 3 {\nLL ~         std::sync::LazyLock::new(|| \"qux\".to_uppercase())\nLL |     } else if \"qux\".is_ascii() {\nLL ~         std::sync::LazyLock::new(|| \"qux\".to_lowercase())\nLL |     } else {\nLL ~         std::sync::LazyLock::new(|| \"qux\".to_string())\n   |\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:41:22\n   |\nLL |     static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n   |                      ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL ~     static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"foo\".to_uppercase());\nLL |\n...\nLL |     fn calling_replaceable_fns() {\nLL ~         let _ = std::sync::LazyLock::force(&LAZY_FOO);\n   |\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:43:22\n   |\nLL |     static LAZY_BAR: Lazy<String> = Lazy::new(|| \"bar\".to_uppercase());\n   |                      ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL ~     static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"bar\".to_uppercase());\nLL |\n...\nLL |         let _ = Lazy::force(&LAZY_FOO);\nLL ~         let _ = std::sync::LazyLock::force(&LAZY_BAR);\n   |\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:45:26\n   |\nLL |     static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| \"baz\".to_uppercase());\n   |                          ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL ~     static mut LAZY_BAZ: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"baz\".to_uppercase());\nLL |\n...\nLL |         unsafe {\nLL ~             let _ = std::sync::LazyLock::force(&LAZY_BAZ);\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs",
    "content": "//@ check-pass\n//@aux-build:once_cell.rs\n//@aux-build:lazy_static.rs\n\n#![warn(clippy::non_std_lazy_statics)]\n#![no_std]\n\nuse lazy_static::lazy_static;\nuse once_cell::sync::Lazy;\n\nfn main() {}\n\nstatic LAZY_FOO: Lazy<usize> = Lazy::new(|| 42);\nstatic LAZY_BAR: Lazy<i32> = Lazy::new(|| {\n    let x: i32 = 0;\n    x.saturating_add(100)\n});\n\nlazy_static! {\n    static ref LAZY_BAZ: f64 = 12.159 * 548;\n}\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs",
    "content": "//@ check-pass\n//@aux-build:once_cell.rs\n\n#![warn(clippy::non_std_lazy_statics)]\n\n// Should not error, since we used a type besides `sync::Lazy`\nfn use_once_cell_race(x: once_cell::race::OnceBox<String>) {\n    let _foo = x.get();\n}\n\nuse once_cell::sync::Lazy;\n\nstatic LAZY_BAZ: Lazy<String> = Lazy::new(|| \"baz\".to_uppercase());\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs",
    "content": "//@aux-build:once_cell.rs\n//@aux-build:lazy_static.rs\n//@no-rustfix\n\n#![warn(clippy::non_std_lazy_statics)]\n#![allow(static_mut_refs)]\n\nmod once_cell_lazy {\n    use once_cell::sync::Lazy;\n\n    static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    static mut LAZY_BAR: Lazy<String> = Lazy::new(|| \"bar\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n    static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| \"baz\".to_uppercase());\n    //~^ ERROR: this type has been superseded by `LazyLock` in the standard library\n\n    fn calling_irreplaceable_fns() {\n        let _ = Lazy::get(&LAZY_FOO);\n\n        unsafe {\n            let _ = Lazy::get_mut(&mut LAZY_BAR);\n            let _ = Lazy::force_mut(&mut LAZY_BAZ);\n        }\n    }\n}\n\nmod lazy_static_lazy_static {\n    use lazy_static::lazy_static;\n\n    lazy_static! {\n        static ref LAZY_FOO: String = \"foo\".to_uppercase();\n    }\n    //~^^^ ERROR: this macro has been superseded by `std::sync::LazyLock`\n    lazy_static! {\n        static ref LAZY_BAR: String = \"bar\".to_uppercase();\n        static ref LAZY_BAZ: String = \"baz\".to_uppercase();\n    }\n    //~^^^^ ERROR: this macro has been superseded by `std::sync::LazyLock`\n    //~| ERROR: this macro has been superseded by `std::sync::LazyLock`\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr",
    "content": "error: this macro has been superseded by `std::sync::LazyLock`\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:31:5\n   |\nLL | /     lazy_static! {\nLL | |         static ref LAZY_FOO: String = \"foo\".to_uppercase();\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::non-std-lazy-statics` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_std_lazy_statics)]`\n\nerror: this macro has been superseded by `std::sync::LazyLock`\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:35:5\n   |\nLL | /     lazy_static! {\nLL | |         static ref LAZY_BAR: String = \"bar\".to_uppercase();\nLL | |         static ref LAZY_BAZ: String = \"baz\".to_uppercase();\nLL | |     }\n   | |_____^\n\nerror: this macro has been superseded by `std::sync::LazyLock`\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:35:5\n   |\nLL | /     lazy_static! {\nLL | |         static ref LAZY_BAR: String = \"bar\".to_uppercase();\nLL | |         static ref LAZY_BAZ: String = \"baz\".to_uppercase();\nLL | |     }\n   | |_____^\n   |\n   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:11:22\n   |\nLL |     static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\n   |                      ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL -     static LAZY_FOO: Lazy<String> = Lazy::new(|| \"foo\".to_uppercase());\nLL +     static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"foo\".to_uppercase());\n   |\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:13:26\n   |\nLL |     static mut LAZY_BAR: Lazy<String> = Lazy::new(|| \"bar\".to_uppercase());\n   |                          ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL -     static mut LAZY_BAR: Lazy<String> = Lazy::new(|| \"bar\".to_uppercase());\nLL +     static mut LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"bar\".to_uppercase());\n   |\n\nerror: this type has been superseded by `LazyLock` in the standard library\n  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:15:26\n   |\nLL |     static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| \"baz\".to_uppercase());\n   |                          ^^^^\n   |\nhelp: use `std::sync::LazyLock` instead\n   |\nLL -     static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| \"baz\".to_uppercase());\nLL +     static mut LAZY_BAZ: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| \"baz\".to_uppercase());\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_zero_suggestions.fixed",
    "content": "#![warn(clippy::non_zero_suggestions)]\nuse std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};\n\nfn main() {\n    /// Positive test cases (lint should trigger)\n    // U32 -> U64\n    let x: u64 = 100;\n    let y = NonZeroU32::new(10).unwrap();\n    let r1 = x / NonZeroU64::from(y);\n    //~^ non_zero_suggestions\n\n    let r2 = x % NonZeroU64::from(y);\n    //~^ non_zero_suggestions\n\n    // U16 -> U32\n    let a: u32 = 50;\n    let b = NonZeroU16::new(5).unwrap();\n    let r3 = a / NonZeroU32::from(b);\n    //~^ non_zero_suggestions\n\n    let x = NonZeroU64::from(NonZeroU32::new(5).unwrap());\n    //~^ non_zero_suggestions\n\n    /// Negative test cases (lint should not trigger)\n    // Left hand side expressions should not be triggered\n    let c: u32 = 50;\n    let d = NonZeroU16::new(5).unwrap();\n    let r4 = u32::from(b.get()) / a;\n\n    // Should not trigger for any other operand other than `/` and `%`\n    let r5 = a + u32::from(b.get());\n    let r6 = a - u32::from(b.get());\n\n    // Same size types\n    let e: u32 = 200;\n    let f = NonZeroU32::new(20).unwrap();\n    let r7 = e / f.get();\n\n    // Smaller to larger, but not NonZero\n    let g: u64 = 1000;\n    let h: u32 = 50;\n    let r8 = g / u64::from(h);\n\n    // Using From correctly\n    let k: u64 = 300;\n    let l = NonZeroU32::new(15).unwrap();\n    let r9 = k / NonZeroU64::from(l);\n}\n\n// Additional function to test the lint in a different context\nfn divide_numbers(x: u64, y: NonZeroU32) -> u64 {\n    x / NonZeroU64::from(y)\n    //~^ non_zero_suggestions\n}\n\nstruct Calculator {\n    value: u64,\n}\n\nimpl Calculator {\n    fn divide(&self, divisor: NonZeroU32) -> u64 {\n        self.value / NonZeroU64::from(divisor)\n        //~^ non_zero_suggestions\n    }\n}\n"
  },
  {
    "path": "tests/ui/non_zero_suggestions.rs",
    "content": "#![warn(clippy::non_zero_suggestions)]\nuse std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};\n\nfn main() {\n    /// Positive test cases (lint should trigger)\n    // U32 -> U64\n    let x: u64 = 100;\n    let y = NonZeroU32::new(10).unwrap();\n    let r1 = x / u64::from(y.get());\n    //~^ non_zero_suggestions\n\n    let r2 = x % u64::from(y.get());\n    //~^ non_zero_suggestions\n\n    // U16 -> U32\n    let a: u32 = 50;\n    let b = NonZeroU16::new(5).unwrap();\n    let r3 = a / u32::from(b.get());\n    //~^ non_zero_suggestions\n\n    let x = u64::from(NonZeroU32::new(5).unwrap().get());\n    //~^ non_zero_suggestions\n\n    /// Negative test cases (lint should not trigger)\n    // Left hand side expressions should not be triggered\n    let c: u32 = 50;\n    let d = NonZeroU16::new(5).unwrap();\n    let r4 = u32::from(b.get()) / a;\n\n    // Should not trigger for any other operand other than `/` and `%`\n    let r5 = a + u32::from(b.get());\n    let r6 = a - u32::from(b.get());\n\n    // Same size types\n    let e: u32 = 200;\n    let f = NonZeroU32::new(20).unwrap();\n    let r7 = e / f.get();\n\n    // Smaller to larger, but not NonZero\n    let g: u64 = 1000;\n    let h: u32 = 50;\n    let r8 = g / u64::from(h);\n\n    // Using From correctly\n    let k: u64 = 300;\n    let l = NonZeroU32::new(15).unwrap();\n    let r9 = k / NonZeroU64::from(l);\n}\n\n// Additional function to test the lint in a different context\nfn divide_numbers(x: u64, y: NonZeroU32) -> u64 {\n    x / u64::from(y.get())\n    //~^ non_zero_suggestions\n}\n\nstruct Calculator {\n    value: u64,\n}\n\nimpl Calculator {\n    fn divide(&self, divisor: NonZeroU32) -> u64 {\n        self.value / u64::from(divisor.get())\n        //~^ non_zero_suggestions\n    }\n}\n"
  },
  {
    "path": "tests/ui/non_zero_suggestions.stderr",
    "content": "error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions.rs:9:18\n   |\nLL |     let r1 = x / u64::from(y.get());\n   |                  ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`\n   |\n   = note: `-D clippy::non-zero-suggestions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]`\n\nerror: consider using `NonZeroU64::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions.rs:12:18\n   |\nLL |     let r2 = x % u64::from(y.get());\n   |                  ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`\n\nerror: consider using `NonZeroU32::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions.rs:18:18\n   |\nLL |     let r3 = a / u32::from(b.get());\n   |                  ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU32::from(b)`\n\nerror: consider using `NonZeroU64::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions.rs:21:13\n   |\nLL |     let x = u64::from(NonZeroU32::new(5).unwrap().get());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(NonZeroU32::new(5).unwrap())`\n\nerror: consider using `NonZeroU64::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions.rs:52:9\n   |\nLL |     x / u64::from(y.get())\n   |         ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`\n\nerror: consider using `NonZeroU64::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions.rs:62:22\n   |\nLL |         self.value / u64::from(divisor.get())\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(divisor)`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/non_zero_suggestions_unfixable.rs",
    "content": "#![warn(clippy::non_zero_suggestions)]\n//@no-rustfix\nuse std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};\n\nfn main() {\n    let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get());\n    //~^ non_zero_suggestions\n\n    let n = NonZeroU32::new(20).unwrap();\n    let y = u64::from(n.get());\n    //~^ non_zero_suggestions\n\n    some_fn_that_only_takes_u64(y);\n\n    let m = NonZeroU32::try_from(1).unwrap();\n    let _z: NonZeroU64 = m.into();\n}\n\nfn return_non_zero(x: u64, y: NonZeroU32) -> u64 {\n    u64::from(y.get())\n    //~^ non_zero_suggestions\n}\n\nfn some_fn_that_only_takes_u64(_: u64) {}\n"
  },
  {
    "path": "tests/ui/non_zero_suggestions_unfixable.stderr",
    "content": "error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions_unfixable.rs:6:18\n   |\nLL |     let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get());\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(NonZeroU32::new(5).unwrap())`\n   |\n   = note: `-D clippy::non-zero-suggestions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]`\n\nerror: consider using `NonZeroU64::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions_unfixable.rs:10:13\n   |\nLL |     let y = u64::from(n.get());\n   |             ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(n)`\n\nerror: consider using `NonZeroU64::from()` for more efficient and type-safe conversion\n  --> tests/ui/non_zero_suggestions_unfixable.rs:20:5\n   |\nLL |     u64::from(y.get())\n   |     ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/nonminimal_bool.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![allow(\n    unused,\n    clippy::diverging_sub_expression,\n    clippy::needless_ifs,\n    clippy::redundant_pattern_matching\n)]\n#![warn(clippy::nonminimal_bool)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    let a: bool = unimplemented!();\n    let b: bool = unimplemented!();\n    let c: bool = unimplemented!();\n    let d: bool = unimplemented!();\n    let e: bool = unimplemented!();\n    let _ = !true;\n    //~^ nonminimal_bool\n\n    let _ = !false;\n    //~^ nonminimal_bool\n\n    let _ = !!a;\n    //~^ nonminimal_bool\n\n    let _ = false || a;\n    //~^ nonminimal_bool\n\n    // don't lint on cfgs\n    let _ = cfg!(you_shall_not_not_pass) && a;\n    let _ = a || !b || !c || !d || !e;\n    let _ = !(!a && b);\n    //~^ nonminimal_bool\n\n    let _ = !(!a || b);\n    //~^ nonminimal_bool\n\n    let _ = !a && !(b && c);\n    //~^ nonminimal_bool\n}\n\nfn equality_stuff() {\n    let a: i32 = unimplemented!();\n    let b: i32 = unimplemented!();\n    let c: i32 = unimplemented!();\n    let d: i32 = unimplemented!();\n    let _ = a == b && c == 5 && a == b;\n    //~^ nonminimal_bool\n\n    let _ = a == b || c == 5 || a == b;\n    //~^ nonminimal_bool\n\n    let _ = a == b && c == 5 && b == a;\n    //~^ nonminimal_bool\n\n    let _ = a != b || !(a != b || c == d);\n    //~^ nonminimal_bool\n\n    let _ = a != b && !(a != b && c == d);\n    //~^ nonminimal_bool\n}\n\nfn issue3847(a: u32, b: u32) -> bool {\n    const THRESHOLD: u32 = 1_000;\n\n    if a < THRESHOLD && b >= THRESHOLD || a >= THRESHOLD && b < THRESHOLD {\n        return false;\n    }\n    true\n}\n\nfn issue4548() {\n    fn f(_i: u32, _j: u32) -> u32 {\n        unimplemented!();\n    }\n\n    let i = 0;\n    let j = 0;\n\n    if i != j && f(i, j) != 0 || i == j && f(i, j) != 1 {}\n}\n\nfn check_expect() {\n    let a: bool = unimplemented!();\n    #[expect(clippy::nonminimal_bool)]\n    let _ = !!a;\n}\n\nfn issue9428() {\n    if matches!(true, true) && true {\n        //~^ nonminimal_bool\n\n        println!(\"foo\");\n    }\n}\n\nfn issue_10523() {\n    macro_rules! a {\n        ($v:expr) => {\n            $v.is_some()\n        };\n    }\n    let x: Option<u32> = None;\n    if !a!(x) {}\n}\n\nfn issue_10523_1() {\n    macro_rules! a {\n        ($v:expr) => {\n            !$v.is_some()\n        };\n    }\n    let x: Option<u32> = None;\n    if a!(x) {}\n}\n\nfn issue_10523_2() {\n    macro_rules! a {\n        () => {\n            !None::<u32>.is_some()\n        };\n    }\n    if a!() {}\n}\n\nfn issue_10435() {\n    let x = vec![0];\n    let y = vec![1];\n    let z = vec![2];\n\n    // vvv Should not lint\n    #[allow(clippy::nonminimal_bool)]\n    if !x.is_empty() && !(y.is_empty() || z.is_empty()) {\n        println!(\"{}\", line!());\n    }\n\n    // vvv Should not lint (#10435 talks about a bug where it lints)\n    #[allow(clippy::nonminimal_bool)]\n    if !(x == [0]) {\n        println!(\"{}\", line!());\n    }\n}\n\nfn issue10836() {\n    struct Foo(bool);\n    impl std::ops::Not for Foo {\n        type Output = bool;\n\n        fn not(self) -> Self::Output {\n            !self.0\n        }\n    }\n\n    // Should not lint\n    let _: bool = !!Foo(true);\n}\n\nfn issue11932() {\n    let x: i32 = unimplemented!();\n\n    #[allow(clippy::nonminimal_bool)]\n    let _ = x % 2 == 0 || {\n        // Should not lint\n        assert!(x > 0);\n        x % 3 == 0\n    };\n}\n\nfn issue_5794() {\n    let a = 0;\n    if !(12 == a) {}\n    //~^ nonminimal_bool\n    if !(a == 12) {}\n    //~^ nonminimal_bool\n    if !(12 != a) {}\n    //~^ nonminimal_bool\n    if !(a != 12) {}\n    //~^ nonminimal_bool\n\n    let b = true;\n    let c = false;\n    if !b == true {}\n    //~^ nonminimal_bool\n    //~| bool_comparison\n    if !b != true {}\n    //~^ nonminimal_bool\n    //~| bool_comparison\n    if true == !b {}\n    //~^ nonminimal_bool\n    //~| bool_comparison\n    if true != !b {}\n    //~^ nonminimal_bool\n    //~| bool_comparison\n    if !b == !c {}\n    //~^ nonminimal_bool\n    if !b != !c {}\n    //~^ nonminimal_bool\n}\n\nfn issue_12371(x: usize) -> bool {\n    // Should not warn!\n    !x != 0\n}\n\n// Not linted because it is slow to do so\n// https://github.com/rust-lang/rust-clippy/issues/13206\nfn many_ops(a: bool, b: bool, c: bool, d: bool, e: bool, f: bool) -> bool {\n    (a && c && f) || (!a && b && !d) || (!b && !c && !e) || (d && e && !f)\n}\n\nfn issue14184(a: f32, b: bool) {\n    if !(a < 2.0 && !b) {\n        //~^ nonminimal_bool\n        println!(\"Hi\");\n    }\n}\n\nmod issue14404 {\n    enum TyKind {\n        Ref(i32, i32, i32),\n        Other,\n    }\n\n    struct Expr;\n\n    fn is_mutable(expr: &Expr) -> bool {\n        todo!()\n    }\n\n    fn should_not_give_macro(ty: TyKind, expr: Expr) {\n        if !(matches!(ty, TyKind::Ref(_, _, _)) && !is_mutable(&expr)) {\n            //~^ nonminimal_bool\n            todo!()\n        }\n    }\n}\n\nfn dont_simplify_double_not_if_types_differ() {\n    struct S;\n\n    impl std::ops::Not for S {\n        type Output = bool;\n        fn not(self) -> bool {\n            true\n        }\n    }\n\n    // The lint must propose `if !!S`, not `if S`.\n    // FIXME: `bool_comparison` will propose to use `S == true`\n    // which is invalid.\n    if !S != true {}\n    //~^ nonminimal_bool\n    //~| bool_comparison\n}\n"
  },
  {
    "path": "tests/ui/nonminimal_bool.stderr",
    "content": "error: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:17:13\n   |\nLL |     let _ = !true;\n   |             ^^^^^ help: try: `false`\n   |\n   = note: `-D clippy::nonminimal-bool` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:20:13\n   |\nLL |     let _ = !false;\n   |             ^^^^^^ help: try: `true`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:23:13\n   |\nLL |     let _ = !!a;\n   |             ^^^ help: try: `a`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:26:13\n   |\nLL |     let _ = false || a;\n   |             ^^^^^^^^^^ help: try: `a`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:32:13\n   |\nLL |     let _ = !(!a && b);\n   |             ^^^^^^^^^^ help: try: `a || !b`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:35:13\n   |\nLL |     let _ = !(!a || b);\n   |             ^^^^^^^^^^ help: try: `a && !b`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:38:13\n   |\nLL |     let _ = !a && !(b && c);\n   |             ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:47:13\n   |\nLL |     let _ = a == b && c == 5 && a == b;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let _ = a == b && c == 5 && a == b;\nLL +     let _ = !(a != b || c != 5);\n   |\nLL -     let _ = a == b && c == 5 && a == b;\nLL +     let _ = a == b && c == 5;\n   |\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:50:13\n   |\nLL |     let _ = a == b || c == 5 || a == b;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let _ = a == b || c == 5 || a == b;\nLL +     let _ = !(a != b && c != 5);\n   |\nLL -     let _ = a == b || c == 5 || a == b;\nLL +     let _ = a == b || c == 5;\n   |\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:53:13\n   |\nLL |     let _ = a == b && c == 5 && b == a;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let _ = a == b && c == 5 && b == a;\nLL +     let _ = !(a != b || c != 5);\n   |\nLL -     let _ = a == b && c == 5 && b == a;\nLL +     let _ = a == b && c == 5;\n   |\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:56:13\n   |\nLL |     let _ = a != b || !(a != b || c == d);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let _ = a != b || !(a != b || c == d);\nLL +     let _ = !(a == b && c == d);\n   |\nLL -     let _ = a != b || !(a != b || c == d);\nLL +     let _ = a != b || c != d;\n   |\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:59:13\n   |\nLL |     let _ = a != b && !(a != b && c == d);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     let _ = a != b && !(a != b && c == d);\nLL +     let _ = !(a == b || c == d);\n   |\nLL -     let _ = a != b && !(a != b && c == d);\nLL +     let _ = a != b && c != d;\n   |\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:90:8\n   |\nLL |     if matches!(true, true) && true {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:171:8\n   |\nLL |     if !(12 == a) {}\n   |        ^^^^^^^^^^ help: try: `(12 != a)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:173:8\n   |\nLL |     if !(a == 12) {}\n   |        ^^^^^^^^^^ help: try: `(a != 12)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:175:8\n   |\nLL |     if !(12 != a) {}\n   |        ^^^^^^^^^^ help: try: `(12 == a)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:177:8\n   |\nLL |     if !(a != 12) {}\n   |        ^^^^^^^^^^ help: try: `(a == 12)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:182:8\n   |\nLL |     if !b == true {}\n   |        ^^^^^^^^^^ help: try: `b != true`\n\nerror: equality checks against true are unnecessary\n  --> tests/ui/nonminimal_bool.rs:182:8\n   |\nLL |     if !b == true {}\n   |        ^^^^^^^^^^ help: try: `!b`\n   |\n   = note: `-D clippy::bool-comparison` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:185:8\n   |\nLL |     if !b != true {}\n   |        ^^^^^^^^^^ help: try: `b == true`\n\nerror: inequality checks against true can be replaced by a negation\n  --> tests/ui/nonminimal_bool.rs:185:8\n   |\nLL |     if !b != true {}\n   |        ^^^^^^^^^^ help: try: `b`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:188:8\n   |\nLL |     if true == !b {}\n   |        ^^^^^^^^^^ help: try: `true != b`\n\nerror: equality checks against true are unnecessary\n  --> tests/ui/nonminimal_bool.rs:188:8\n   |\nLL |     if true == !b {}\n   |        ^^^^^^^^^^ help: try: `!b`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:191:8\n   |\nLL |     if true != !b {}\n   |        ^^^^^^^^^^ help: try: `true == b`\n\nerror: inequality checks against true can be replaced by a negation\n  --> tests/ui/nonminimal_bool.rs:191:8\n   |\nLL |     if true != !b {}\n   |        ^^^^^^^^^^ help: try: `b`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:194:8\n   |\nLL |     if !b == !c {}\n   |        ^^^^^^^^ help: try: `b == c`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:196:8\n   |\nLL |     if !b != !c {}\n   |        ^^^^^^^^ help: try: `b != c`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:212:8\n   |\nLL |     if !(a < 2.0 && !b) {\n   |        ^^^^^^^^^^^^^^^^ help: try: `a >= 2.0 || b`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:231:12\n   |\nLL |         if !(matches!(ty, TyKind::Ref(_, _, _)) && !is_mutable(&expr)) {\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!matches!(ty, TyKind::Ref(_, _, _)) || is_mutable(&expr)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool.rs:251:8\n   |\nLL |     if !S != true {}\n   |        ^^^^^^^^^^ help: try: `S == true`\n\nerror: inequality checks against true can be replaced by a negation\n  --> tests/ui/nonminimal_bool.rs:251:8\n   |\nLL |     if !S != true {}\n   |        ^^^^^^^^^^ help: try: `!!S`\n\nerror: aborting due to 31 previous errors\n\n"
  },
  {
    "path": "tests/ui/nonminimal_bool_methods.fixed",
    "content": "#![allow(unused, clippy::diverging_sub_expression, clippy::needless_ifs)]\n#![warn(clippy::nonminimal_bool)]\n\nfn methods_with_negation() {\n    let a: Option<i32> = unimplemented!();\n    let b: Result<i32, i32> = unimplemented!();\n    let _ = a.is_some();\n    let _ = a.is_none();\n    //~^ nonminimal_bool\n    let _ = a.is_none();\n    let _ = a.is_some();\n    //~^ nonminimal_bool\n    let _ = b.is_err();\n    let _ = b.is_ok();\n    //~^ nonminimal_bool\n    let _ = b.is_ok();\n    let _ = b.is_err();\n    //~^ nonminimal_bool\n    let c = false;\n    let _ = a.is_none() || c;\n    //~^ nonminimal_bool\n    let _ = a.is_none() && c;\n    //~^ nonminimal_bool\n    let _ = !(!c ^ c) || a.is_none();\n    //~^ nonminimal_bool\n    let _ = (!c ^ c) || a.is_none();\n    //~^ nonminimal_bool\n    let _ = !c ^ c || a.is_none();\n    //~^ nonminimal_bool\n}\n\n// Simplified versions of https://github.com/rust-lang/rust-clippy/issues/2638\n// clippy::nonminimal_bool should only check the built-in Result and Some type, not\n// any other types like the following.\nenum CustomResultOk<E> {\n    Ok,\n    Err(E),\n}\nenum CustomResultErr<E> {\n    Ok,\n    Err(E),\n}\nenum CustomSomeSome<T> {\n    Some(T),\n    None,\n}\nenum CustomSomeNone<T> {\n    Some(T),\n    None,\n}\n\nimpl<E> CustomResultOk<E> {\n    pub fn is_ok(&self) -> bool {\n        true\n    }\n}\n\nimpl<E> CustomResultErr<E> {\n    pub fn is_err(&self) -> bool {\n        true\n    }\n}\n\nimpl<T> CustomSomeSome<T> {\n    pub fn is_some(&self) -> bool {\n        true\n    }\n}\n\nimpl<T> CustomSomeNone<T> {\n    pub fn is_none(&self) -> bool {\n        true\n    }\n}\n\nfn dont_warn_for_custom_methods_with_negation() {\n    let res = CustomResultOk::Err(\"Error\");\n    // Should not warn and suggest 'is_err()' because the type does not\n    // implement is_err().\n    if !res.is_ok() {}\n\n    let res = CustomResultErr::Err(\"Error\");\n    // Should not warn and suggest 'is_ok()' because the type does not\n    // implement is_ok().\n    if !res.is_err() {}\n\n    let res = CustomSomeSome::Some(\"thing\");\n    // Should not warn and suggest 'is_none()' because the type does not\n    // implement is_none().\n    if !res.is_some() {}\n\n    let res = CustomSomeNone::Some(\"thing\");\n    // Should not warn and suggest 'is_some()' because the type does not\n    // implement is_some().\n    if !res.is_none() {}\n}\n\n// Only Built-in Result and Some types should suggest the negated alternative\nfn warn_for_built_in_methods_with_negation() {\n    let res: Result<usize, usize> = Ok(1);\n    if res.is_err() {}\n    //~^ nonminimal_bool\n    if res.is_ok() {}\n    //~^ nonminimal_bool\n\n    let res = Some(1);\n    if res.is_none() {}\n    //~^ nonminimal_bool\n    if res.is_some() {}\n    //~^ nonminimal_bool\n}\n\n#[allow(clippy::neg_cmp_op_on_partial_ord)]\nfn dont_warn_for_negated_partial_ord_comparison() {\n    let a: f64 = unimplemented!();\n    let b: f64 = unimplemented!();\n    let _ = !(a < b);\n    let _ = !(a <= b);\n    let _ = !(a > b);\n    let _ = !(a >= b);\n}\n\nfn issue_12625() {\n    let a = 0;\n    let b = 0;\n    if ((a as u64) < b) {}\n    //~^ nonminimal_bool\n    if ((a as u64) < b) {}\n    //~^ nonminimal_bool\n    if (a as u64 > b) {}\n    //~^ nonminimal_bool\n}\n\nfn issue_12761() {\n    let a = 0;\n    let b = 0;\n    let c = 0;\n    if (a < b) as i32 == c {}\n    //~^ nonminimal_bool\n    if (a < b) | (a > c) {}\n    //~^ nonminimal_bool\n    //~| nonminimal_bool\n    let opt: Option<usize> = Some(1);\n    let res: Result<usize, usize> = Ok(1);\n    if res.is_err() as i32 == c {}\n    //~^ nonminimal_bool\n    if res.is_err() | opt.is_some() {}\n    //~^ nonminimal_bool\n    //~| nonminimal_bool\n\n    fn a(a: bool) -> bool {\n        (4 <= 3).b()\n        //~^ nonminimal_bool\n    }\n\n    trait B {\n        fn b(&self) -> bool {\n            true\n        }\n    }\n\n    impl B for bool {}\n}\n\nfn issue_13436() {\n    fn not_zero(x: i32) -> bool {\n        x != 0\n    }\n\n    let opt = Some(500);\n    _ = opt.is_some_and(|x| x < 1000);\n    _ = opt.is_some_and(|x| x <= 1000);\n    _ = opt.is_some_and(|x| x > 1000);\n    _ = opt.is_some_and(|x| x >= 1000);\n    _ = opt.is_some_and(|x| x == 1000);\n    _ = opt.is_some_and(|x| x != 1000);\n    _ = opt.is_some_and(not_zero);\n    _ = opt.is_none_or(|x| x >= 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_none_or(|x| x > 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_none_or(|x| x <= 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_none_or(|x| x < 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_none_or(|x| x != 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_none_or(|x| x == 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_some_and(not_zero);\n    _ = opt.is_none_or(|x| x < 1000);\n    _ = opt.is_none_or(|x| x <= 1000);\n    _ = opt.is_none_or(|x| x > 1000);\n    _ = opt.is_none_or(|x| x >= 1000);\n    _ = opt.is_none_or(|x| x == 1000);\n    _ = opt.is_none_or(|x| x != 1000);\n    _ = opt.is_none_or(not_zero);\n    _ = opt.is_some_and(|x| x >= 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_some_and(|x| x > 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_some_and(|x| x <= 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_some_and(|x| x < 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_some_and(|x| x != 1000);\n    //~^ nonminimal_bool\n    _ = opt.is_some_and(|x| x == 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(not_zero);\n\n    let opt = Some(true);\n    _ = opt.is_some_and(|x| x);\n    _ = opt.is_some_and(|x| !x);\n    _ = !opt.is_some_and(|x| x);\n    _ = opt.is_none_or(|x| x);\n    //~^ nonminimal_bool\n    _ = opt.is_none_or(|x| x);\n    _ = opt.is_none_or(|x| !x);\n    _ = !opt.is_none_or(|x| x);\n    _ = opt.is_some_and(|x| x);\n    //~^ nonminimal_bool\n\n    let opt: Option<Result<i32, i32>> = Some(Ok(123));\n    _ = opt.is_some_and(|x| x.is_ok());\n    _ = opt.is_some_and(|x| x.is_err());\n    _ = opt.is_none_or(|x| x.is_ok());\n    _ = opt.is_none_or(|x| x.is_err());\n    _ = opt.is_none_or(|x| x.is_err());\n    //~^ nonminimal_bool\n    _ = opt.is_none_or(|x| x.is_ok());\n    //~^ nonminimal_bool\n    _ = opt.is_some_and(|x| x.is_err());\n    //~^ nonminimal_bool\n    _ = opt.is_some_and(|x| x.is_ok());\n    //~^ nonminimal_bool\n\n    #[clippy::msrv = \"1.81\"]\n    fn before_stabilization() {\n        let opt = Some(500);\n        _ = !opt.is_some_and(|x| x < 1000);\n    }\n}\n\nfn issue16014() {\n    (vec![1, 2, 3] > vec![1, 2, 3, 3]);\n    //~^ nonminimal_bool\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/nonminimal_bool_methods.rs",
    "content": "#![allow(unused, clippy::diverging_sub_expression, clippy::needless_ifs)]\n#![warn(clippy::nonminimal_bool)]\n\nfn methods_with_negation() {\n    let a: Option<i32> = unimplemented!();\n    let b: Result<i32, i32> = unimplemented!();\n    let _ = a.is_some();\n    let _ = !a.is_some();\n    //~^ nonminimal_bool\n    let _ = a.is_none();\n    let _ = !a.is_none();\n    //~^ nonminimal_bool\n    let _ = b.is_err();\n    let _ = !b.is_err();\n    //~^ nonminimal_bool\n    let _ = b.is_ok();\n    let _ = !b.is_ok();\n    //~^ nonminimal_bool\n    let c = false;\n    let _ = !(a.is_some() && !c);\n    //~^ nonminimal_bool\n    let _ = !(a.is_some() || !c);\n    //~^ nonminimal_bool\n    let _ = !(!c ^ c) || !a.is_some();\n    //~^ nonminimal_bool\n    let _ = (!c ^ c) || !a.is_some();\n    //~^ nonminimal_bool\n    let _ = !c ^ c || !a.is_some();\n    //~^ nonminimal_bool\n}\n\n// Simplified versions of https://github.com/rust-lang/rust-clippy/issues/2638\n// clippy::nonminimal_bool should only check the built-in Result and Some type, not\n// any other types like the following.\nenum CustomResultOk<E> {\n    Ok,\n    Err(E),\n}\nenum CustomResultErr<E> {\n    Ok,\n    Err(E),\n}\nenum CustomSomeSome<T> {\n    Some(T),\n    None,\n}\nenum CustomSomeNone<T> {\n    Some(T),\n    None,\n}\n\nimpl<E> CustomResultOk<E> {\n    pub fn is_ok(&self) -> bool {\n        true\n    }\n}\n\nimpl<E> CustomResultErr<E> {\n    pub fn is_err(&self) -> bool {\n        true\n    }\n}\n\nimpl<T> CustomSomeSome<T> {\n    pub fn is_some(&self) -> bool {\n        true\n    }\n}\n\nimpl<T> CustomSomeNone<T> {\n    pub fn is_none(&self) -> bool {\n        true\n    }\n}\n\nfn dont_warn_for_custom_methods_with_negation() {\n    let res = CustomResultOk::Err(\"Error\");\n    // Should not warn and suggest 'is_err()' because the type does not\n    // implement is_err().\n    if !res.is_ok() {}\n\n    let res = CustomResultErr::Err(\"Error\");\n    // Should not warn and suggest 'is_ok()' because the type does not\n    // implement is_ok().\n    if !res.is_err() {}\n\n    let res = CustomSomeSome::Some(\"thing\");\n    // Should not warn and suggest 'is_none()' because the type does not\n    // implement is_none().\n    if !res.is_some() {}\n\n    let res = CustomSomeNone::Some(\"thing\");\n    // Should not warn and suggest 'is_some()' because the type does not\n    // implement is_some().\n    if !res.is_none() {}\n}\n\n// Only Built-in Result and Some types should suggest the negated alternative\nfn warn_for_built_in_methods_with_negation() {\n    let res: Result<usize, usize> = Ok(1);\n    if !res.is_ok() {}\n    //~^ nonminimal_bool\n    if !res.is_err() {}\n    //~^ nonminimal_bool\n\n    let res = Some(1);\n    if !res.is_some() {}\n    //~^ nonminimal_bool\n    if !res.is_none() {}\n    //~^ nonminimal_bool\n}\n\n#[allow(clippy::neg_cmp_op_on_partial_ord)]\nfn dont_warn_for_negated_partial_ord_comparison() {\n    let a: f64 = unimplemented!();\n    let b: f64 = unimplemented!();\n    let _ = !(a < b);\n    let _ = !(a <= b);\n    let _ = !(a > b);\n    let _ = !(a >= b);\n}\n\nfn issue_12625() {\n    let a = 0;\n    let b = 0;\n    if !(a as u64 >= b) {}\n    //~^ nonminimal_bool\n    if !((a as u64) >= b) {}\n    //~^ nonminimal_bool\n    if !(a as u64 <= b) {}\n    //~^ nonminimal_bool\n}\n\nfn issue_12761() {\n    let a = 0;\n    let b = 0;\n    let c = 0;\n    if !(a >= b) as i32 == c {}\n    //~^ nonminimal_bool\n    if !(a >= b) | !(a <= c) {}\n    //~^ nonminimal_bool\n    //~| nonminimal_bool\n    let opt: Option<usize> = Some(1);\n    let res: Result<usize, usize> = Ok(1);\n    if !res.is_ok() as i32 == c {}\n    //~^ nonminimal_bool\n    if !res.is_ok() | !opt.is_none() {}\n    //~^ nonminimal_bool\n    //~| nonminimal_bool\n\n    fn a(a: bool) -> bool {\n        (!(4 > 3)).b()\n        //~^ nonminimal_bool\n    }\n\n    trait B {\n        fn b(&self) -> bool {\n            true\n        }\n    }\n\n    impl B for bool {}\n}\n\nfn issue_13436() {\n    fn not_zero(x: i32) -> bool {\n        x != 0\n    }\n\n    let opt = Some(500);\n    _ = opt.is_some_and(|x| x < 1000);\n    _ = opt.is_some_and(|x| x <= 1000);\n    _ = opt.is_some_and(|x| x > 1000);\n    _ = opt.is_some_and(|x| x >= 1000);\n    _ = opt.is_some_and(|x| x == 1000);\n    _ = opt.is_some_and(|x| x != 1000);\n    _ = opt.is_some_and(not_zero);\n    _ = !opt.is_some_and(|x| x < 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_some_and(|x| x <= 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_some_and(|x| x > 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_some_and(|x| x >= 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_some_and(|x| x == 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_some_and(|x| x != 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_some_and(not_zero);\n    _ = opt.is_none_or(|x| x < 1000);\n    _ = opt.is_none_or(|x| x <= 1000);\n    _ = opt.is_none_or(|x| x > 1000);\n    _ = opt.is_none_or(|x| x >= 1000);\n    _ = opt.is_none_or(|x| x == 1000);\n    _ = opt.is_none_or(|x| x != 1000);\n    _ = opt.is_none_or(not_zero);\n    _ = !opt.is_none_or(|x| x < 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(|x| x <= 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(|x| x > 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(|x| x >= 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(|x| x == 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(|x| x != 1000);\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(not_zero);\n\n    let opt = Some(true);\n    _ = opt.is_some_and(|x| x);\n    _ = opt.is_some_and(|x| !x);\n    _ = !opt.is_some_and(|x| x);\n    _ = !opt.is_some_and(|x| !x);\n    //~^ nonminimal_bool\n    _ = opt.is_none_or(|x| x);\n    _ = opt.is_none_or(|x| !x);\n    _ = !opt.is_none_or(|x| x);\n    _ = !opt.is_none_or(|x| !x);\n    //~^ nonminimal_bool\n\n    let opt: Option<Result<i32, i32>> = Some(Ok(123));\n    _ = opt.is_some_and(|x| x.is_ok());\n    _ = opt.is_some_and(|x| x.is_err());\n    _ = opt.is_none_or(|x| x.is_ok());\n    _ = opt.is_none_or(|x| x.is_err());\n    _ = !opt.is_some_and(|x| x.is_ok());\n    //~^ nonminimal_bool\n    _ = !opt.is_some_and(|x| x.is_err());\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(|x| x.is_ok());\n    //~^ nonminimal_bool\n    _ = !opt.is_none_or(|x| x.is_err());\n    //~^ nonminimal_bool\n\n    #[clippy::msrv = \"1.81\"]\n    fn before_stabilization() {\n        let opt = Some(500);\n        _ = !opt.is_some_and(|x| x < 1000);\n    }\n}\n\nfn issue16014() {\n    !(vec![1, 2, 3] <= vec![1, 2, 3, 3]);\n    //~^ nonminimal_bool\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/nonminimal_bool_methods.stderr",
    "content": "error: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:8:13\n   |\nLL |     let _ = !a.is_some();\n   |             ^^^^^^^^^^^^ help: try: `a.is_none()`\n   |\n   = note: `-D clippy::nonminimal-bool` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:11:13\n   |\nLL |     let _ = !a.is_none();\n   |             ^^^^^^^^^^^^ help: try: `a.is_some()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:14:13\n   |\nLL |     let _ = !b.is_err();\n   |             ^^^^^^^^^^^ help: try: `b.is_ok()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:17:13\n   |\nLL |     let _ = !b.is_ok();\n   |             ^^^^^^^^^^ help: try: `b.is_err()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:20:13\n   |\nLL |     let _ = !(a.is_some() && !c);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:22:13\n   |\nLL |     let _ = !(a.is_some() || !c);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:24:26\n   |\nLL |     let _ = !(!c ^ c) || !a.is_some();\n   |                          ^^^^^^^^^^^^ help: try: `a.is_none()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:26:25\n   |\nLL |     let _ = (!c ^ c) || !a.is_some();\n   |                         ^^^^^^^^^^^^ help: try: `a.is_none()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:28:23\n   |\nLL |     let _ = !c ^ c || !a.is_some();\n   |                       ^^^^^^^^^^^^ help: try: `a.is_none()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:101:8\n   |\nLL |     if !res.is_ok() {}\n   |        ^^^^^^^^^^^^ help: try: `res.is_err()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:103:8\n   |\nLL |     if !res.is_err() {}\n   |        ^^^^^^^^^^^^^ help: try: `res.is_ok()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:107:8\n   |\nLL |     if !res.is_some() {}\n   |        ^^^^^^^^^^^^^^ help: try: `res.is_none()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:109:8\n   |\nLL |     if !res.is_none() {}\n   |        ^^^^^^^^^^^^^^ help: try: `res.is_some()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:126:8\n   |\nLL |     if !(a as u64 >= b) {}\n   |        ^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:128:8\n   |\nLL |     if !((a as u64) >= b) {}\n   |        ^^^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:130:8\n   |\nLL |     if !(a as u64 <= b) {}\n   |        ^^^^^^^^^^^^^^^^ help: try: `(a as u64 > b)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:138:8\n   |\nLL |     if !(a >= b) as i32 == c {}\n   |        ^^^^^^^^^ help: try: `(a < b)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:140:8\n   |\nLL |     if !(a >= b) | !(a <= c) {}\n   |        ^^^^^^^^^ help: try: `(a < b)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:140:20\n   |\nLL |     if !(a >= b) | !(a <= c) {}\n   |                    ^^^^^^^^^ help: try: `(a > c)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:145:8\n   |\nLL |     if !res.is_ok() as i32 == c {}\n   |        ^^^^^^^^^^^^ help: try: `res.is_err()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:147:8\n   |\nLL |     if !res.is_ok() | !opt.is_none() {}\n   |        ^^^^^^^^^^^^ help: try: `res.is_err()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:147:23\n   |\nLL |     if !res.is_ok() | !opt.is_none() {}\n   |                       ^^^^^^^^^^^^^^ help: try: `opt.is_some()`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:152:9\n   |\nLL |         (!(4 > 3)).b()\n   |         ^^^^^^^^^^ help: try: `(4 <= 3)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:178:9\n   |\nLL |     _ = !opt.is_some_and(|x| x < 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x >= 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:180:9\n   |\nLL |     _ = !opt.is_some_and(|x| x <= 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x > 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:182:9\n   |\nLL |     _ = !opt.is_some_and(|x| x > 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x <= 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:184:9\n   |\nLL |     _ = !opt.is_some_and(|x| x >= 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x < 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:186:9\n   |\nLL |     _ = !opt.is_some_and(|x| x == 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x != 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:188:9\n   |\nLL |     _ = !opt.is_some_and(|x| x != 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x == 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:198:9\n   |\nLL |     _ = !opt.is_none_or(|x| x < 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x >= 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:200:9\n   |\nLL |     _ = !opt.is_none_or(|x| x <= 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x > 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:202:9\n   |\nLL |     _ = !opt.is_none_or(|x| x > 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x <= 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:204:9\n   |\nLL |     _ = !opt.is_none_or(|x| x >= 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x < 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:206:9\n   |\nLL |     _ = !opt.is_none_or(|x| x == 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x != 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:208:9\n   |\nLL |     _ = !opt.is_none_or(|x| x != 1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x == 1000)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:216:9\n   |\nLL |     _ = !opt.is_some_and(|x| !x);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:221:9\n   |\nLL |     _ = !opt.is_none_or(|x| !x);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x)`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:229:9\n   |\nLL |     _ = !opt.is_some_and(|x| x.is_ok());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_err())`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:231:9\n   |\nLL |     _ = !opt.is_some_and(|x| x.is_err());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_ok())`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:233:9\n   |\nLL |     _ = !opt.is_none_or(|x| x.is_ok());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_err())`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:235:9\n   |\nLL |     _ = !opt.is_none_or(|x| x.is_err());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_ok())`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods.rs:246:5\n   |\nLL |     !(vec![1, 2, 3] <= vec![1, 2, 3, 3]);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(vec![1, 2, 3] > vec![1, 2, 3, 3])`\n\nerror: aborting due to 42 previous errors\n\n"
  },
  {
    "path": "tests/ui/nonminimal_bool_methods_unfixable.rs",
    "content": "#![warn(clippy::nonminimal_bool)]\n//@no-rustfix\n\nfn issue_13436() {\n    let opt_opt = Some(Some(500));\n    _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000));\n    //~^ nonminimal_bool\n    //~| nonminimal_bool\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/nonminimal_bool_methods_unfixable.stderr",
    "content": "error: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:9\n   |\nLL |     _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt_opt.is_none_or(|x| x.is_some_and(|y| y != 1000))`\n   |\n   = note: `-D clippy::nonminimal-bool` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`\n\nerror: this boolean expression can be simplified\n  --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:34\n   |\nLL |     _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000));\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_none_or(|y| y == 1000)`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/obfuscated_if_else.fixed",
    "content": "#![warn(clippy::obfuscated_if_else)]\n#![allow(\n    clippy::unnecessary_lazy_evaluations,\n    clippy::unit_arg,\n    clippy::unused_unit,\n    clippy::unwrap_or_default\n)]\n\nfn main() {\n    if true { \"a\" } else { \"b\" };\n    //~^ obfuscated_if_else\n\n    if true { \"a\" } else { \"b\" };\n    //~^ obfuscated_if_else\n\n    let a = 1;\n    if a == 1 { \"a\" } else { \"b\" };\n    //~^ obfuscated_if_else\n\n    if a == 1 { \"a\" } else { \"b\" };\n    //~^ obfuscated_if_else\n\n    let partial = (a == 1).then_some(\"a\");\n    partial.unwrap_or(\"b\"); // not lint\n\n    let mut a = 0;\n    if true { a += 1 } else { () };\n    //~^ obfuscated_if_else\n\n    if true { () } else { a += 2 };\n    //~^ obfuscated_if_else\n\n    let mut n = 1;\n    if true { n = 1 } else { n = 2 };\n    //~^ obfuscated_if_else\n    if true { 1 } else { n * 2 };\n    //~^ obfuscated_if_else\n    if true { n += 1 } else { () };\n    //~^ obfuscated_if_else\n\n    let _ = if true { 1 } else { n * 2 };\n    //~^ obfuscated_if_else\n\n    if true { 1 } else { Default::default() };\n    //~^ obfuscated_if_else\n\n    let partial = true.then_some(1);\n    partial.unwrap_or_else(|| n * 2); // not lint\n\n    if true { () } else { Default::default() };\n    //~^ obfuscated_if_else\n\n    if true { () } else { Default::default() };\n    //~^ obfuscated_if_else\n\n    if true { 1 } else { Default::default() };\n    //~^ obfuscated_if_else\n\n    if true { 1 } else { Default::default() };\n    //~^ obfuscated_if_else\n}\n\nfn issue11141() {\n    // Parentheses are required around the left side of a binary expression\n    let _ = (if true { 40 } else { 17 }) | 2;\n    //~^ obfuscated_if_else\n\n    // Parentheses are required only for the leftmost expression\n    let _ = (if true { 30 } else { 17 }) | if true { 2 } else { 3 } | if true { 10 } else { 1 };\n    //~^ obfuscated_if_else\n    //~| obfuscated_if_else\n    //~| obfuscated_if_else\n\n    // Parentheses are not required around the right side of a binary expression\n    let _ = 2 | if true { 40 } else { 17 };\n    //~^ obfuscated_if_else\n\n    // Parentheses are not required for a cast\n    let _ = if true { 42 } else { 17 } as u8;\n    //~^ obfuscated_if_else\n\n    // Parentheses are not required for a deref\n    let _ = *if true { &42 } else { &17 };\n    //~^ obfuscated_if_else\n\n    // Parentheses are not required for a deref followed by a cast\n    let _ = *if true { &42 } else { &17 } as u8;\n    //~^ obfuscated_if_else\n}\n\n#[allow(clippy::useless_format)]\nfn issue16288() {\n    if true { format!(\"this is a test\") } else { Default::default() };\n    //~^ obfuscated_if_else\n}\n"
  },
  {
    "path": "tests/ui/obfuscated_if_else.rs",
    "content": "#![warn(clippy::obfuscated_if_else)]\n#![allow(\n    clippy::unnecessary_lazy_evaluations,\n    clippy::unit_arg,\n    clippy::unused_unit,\n    clippy::unwrap_or_default\n)]\n\nfn main() {\n    true.then_some(\"a\").unwrap_or(\"b\");\n    //~^ obfuscated_if_else\n\n    true.then(|| \"a\").unwrap_or(\"b\");\n    //~^ obfuscated_if_else\n\n    let a = 1;\n    (a == 1).then_some(\"a\").unwrap_or(\"b\");\n    //~^ obfuscated_if_else\n\n    (a == 1).then(|| \"a\").unwrap_or(\"b\");\n    //~^ obfuscated_if_else\n\n    let partial = (a == 1).then_some(\"a\");\n    partial.unwrap_or(\"b\"); // not lint\n\n    let mut a = 0;\n    true.then_some(a += 1).unwrap_or(());\n    //~^ obfuscated_if_else\n\n    true.then_some(()).unwrap_or(a += 2);\n    //~^ obfuscated_if_else\n\n    let mut n = 1;\n    true.then(|| n = 1).unwrap_or_else(|| n = 2);\n    //~^ obfuscated_if_else\n    true.then_some(1).unwrap_or_else(|| n * 2);\n    //~^ obfuscated_if_else\n    true.then_some(n += 1).unwrap_or_else(|| ());\n    //~^ obfuscated_if_else\n\n    let _ = true.then_some(1).unwrap_or_else(|| n * 2);\n    //~^ obfuscated_if_else\n\n    true.then_some(1).unwrap_or_else(Default::default);\n    //~^ obfuscated_if_else\n\n    let partial = true.then_some(1);\n    partial.unwrap_or_else(|| n * 2); // not lint\n\n    true.then_some(()).unwrap_or_default();\n    //~^ obfuscated_if_else\n\n    true.then(|| ()).unwrap_or_default();\n    //~^ obfuscated_if_else\n\n    true.then_some(1).unwrap_or_default();\n    //~^ obfuscated_if_else\n\n    true.then(|| 1).unwrap_or_default();\n    //~^ obfuscated_if_else\n}\n\nfn issue11141() {\n    // Parentheses are required around the left side of a binary expression\n    let _ = true.then_some(40).unwrap_or(17) | 2;\n    //~^ obfuscated_if_else\n\n    // Parentheses are required only for the leftmost expression\n    let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1);\n    //~^ obfuscated_if_else\n    //~| obfuscated_if_else\n    //~| obfuscated_if_else\n\n    // Parentheses are not required around the right side of a binary expression\n    let _ = 2 | true.then_some(40).unwrap_or(17);\n    //~^ obfuscated_if_else\n\n    // Parentheses are not required for a cast\n    let _ = true.then_some(42).unwrap_or(17) as u8;\n    //~^ obfuscated_if_else\n\n    // Parentheses are not required for a deref\n    let _ = *true.then_some(&42).unwrap_or(&17);\n    //~^ obfuscated_if_else\n\n    // Parentheses are not required for a deref followed by a cast\n    let _ = *true.then_some(&42).unwrap_or(&17) as u8;\n    //~^ obfuscated_if_else\n}\n\n#[allow(clippy::useless_format)]\nfn issue16288() {\n    true.then(|| format!(\"this is a test\")).unwrap_or_default();\n    //~^ obfuscated_if_else\n}\n"
  },
  {
    "path": "tests/ui/obfuscated_if_else.stderr",
    "content": "error: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:10:5\n   |\nLL |     true.then_some(\"a\").unwrap_or(\"b\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { \"a\" } else { \"b\" }`\n   |\n   = note: `-D clippy::obfuscated-if-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::obfuscated_if_else)]`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:13:5\n   |\nLL |     true.then(|| \"a\").unwrap_or(\"b\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { \"a\" } else { \"b\" }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:17:5\n   |\nLL |     (a == 1).then_some(\"a\").unwrap_or(\"b\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { \"a\" } else { \"b\" }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:20:5\n   |\nLL |     (a == 1).then(|| \"a\").unwrap_or(\"b\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { \"a\" } else { \"b\" }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:27:5\n   |\nLL |     true.then_some(a += 1).unwrap_or(());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { a += 1 } else { () }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:30:5\n   |\nLL |     true.then_some(()).unwrap_or(a += 2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { a += 2 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:34:5\n   |\nLL |     true.then(|| n = 1).unwrap_or_else(|| n = 2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { n = 1 } else { n = 2 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:36:5\n   |\nLL |     true.then_some(1).unwrap_or_else(|| n * 2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { n * 2 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:38:5\n   |\nLL |     true.then_some(n += 1).unwrap_or_else(|| ());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { n += 1 } else { () }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:41:13\n   |\nLL |     let _ = true.then_some(1).unwrap_or_else(|| n * 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { n * 2 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:44:5\n   |\nLL |     true.then_some(1).unwrap_or_else(Default::default);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { Default::default() }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:50:5\n   |\nLL |     true.then_some(()).unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { Default::default() }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:53:5\n   |\nLL |     true.then(|| ()).unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { Default::default() }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:56:5\n   |\nLL |     true.then_some(1).unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { Default::default() }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:59:5\n   |\nLL |     true.then(|| 1).unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 1 } else { Default::default() }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:65:13\n   |\nLL |     let _ = true.then_some(40).unwrap_or(17) | 2;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 40 } else { 17 })`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:69:13\n   |\nLL |     let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(if true { 30 } else { 17 })`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:69:48\n   |\nLL |     let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1);\n   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 2 } else { 3 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:69:81\n   |\nLL |     let _ = true.then_some(30).unwrap_or(17) | true.then_some(2).unwrap_or(3) | true.then_some(10).unwrap_or(1);\n   |                                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 10 } else { 1 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:75:17\n   |\nLL |     let _ = 2 | true.then_some(40).unwrap_or(17);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 40 } else { 17 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:79:13\n   |\nLL |     let _ = true.then_some(42).unwrap_or(17) as u8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { 42 } else { 17 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:83:14\n   |\nLL |     let _ = *true.then_some(&42).unwrap_or(&17);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:87:14\n   |\nLL |     let _ = *true.then_some(&42).unwrap_or(&17) as u8;\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { &42 } else { &17 }`\n\nerror: this method chain can be written more clearly with `if .. else ..`\n  --> tests/ui/obfuscated_if_else.rs:93:5\n   |\nLL |     true.then(|| format!(\"this is a test\")).unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { format!(\"this is a test\") } else { Default::default() }`\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/octal_escapes.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![warn(clippy::octal_escapes)]\n\nfn main() {\n    let _bad1 = \"\\033[0m\";\n    //~^ octal_escapes\n    let _bad2 = b\"\\033[0m\";\n    //~^ octal_escapes\n    let _bad3 = \"\\\\\\033[0m\";\n    //~^ octal_escapes\n    // maximum 3 digits (\\012 is the escape)\n    let _bad4 = \"\\01234567\";\n    //~^ octal_escapes\n    let _bad5 = \"\\0\\03\";\n    //~^ octal_escapes\n    let _bad6 = \"Text-\\055\\077-MoreText\";\n    //~^ octal_escapes\n    //~| octal_escapes\n\n    let _bad7 = \"EvenMoreText-\\01\\02-ShortEscapes\";\n    //~^ octal_escapes\n    //~| octal_escapes\n\n    let _bad8 = \"锈\\01锈\";\n    //~^ octal_escapes\n    let _bad9 = \"锈\\011锈\";\n    //~^ octal_escapes\n\n    let _good1 = \"\\\\033[0m\";\n    let _good2 = \"\\0\\\\0\";\n    let _good3 = \"\\0\\0\";\n    let _good4 = \"X\\0\\0X\";\n    let _good5 = \"锈\\0锈\";\n    let _good6 = \"\\0\\\\01\";\n}\n"
  },
  {
    "path": "tests/ui/octal_escapes.stderr",
    "content": "error: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:5:18\n   |\nLL |     let _bad1 = \"\\033[0m\";\n   |                  ^^^^\n   |\n   = help: octal escapes are not supported, `\\0` is always null\n   = note: `-D clippy::octal-escapes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::octal_escapes)]`\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL -     let _bad1 = \"\\033[0m\";\nLL +     let _bad1 = \"\\x1b[0m\";\n   |\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad1 = \"\\x0033[0m\";\n   |                   ++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:7:19\n   |\nLL |     let _bad2 = b\"\\033[0m\";\n   |                   ^^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL -     let _bad2 = b\"\\033[0m\";\nLL +     let _bad2 = b\"\\x1b[0m\";\n   |\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad2 = b\"\\x0033[0m\";\n   |                    ++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:9:20\n   |\nLL |     let _bad3 = \"\\\\\\033[0m\";\n   |                    ^^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL -     let _bad3 = \"\\\\\\033[0m\";\nLL +     let _bad3 = \"\\\\\\x1b[0m\";\n   |\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad3 = \"\\\\\\x0033[0m\";\n   |                     ++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:12:18\n   |\nLL |     let _bad4 = \"\\01234567\";\n   |                  ^^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL -     let _bad4 = \"\\01234567\";\nLL +     let _bad4 = \"\\x0a34567\";\n   |\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad4 = \"\\x001234567\";\n   |                   ++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:14:20\n   |\nLL |     let _bad5 = \"\\0\\03\";\n   |                    ^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL |     let _bad5 = \"\\0\\x03\";\n   |                     +\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad5 = \"\\0\\x0003\";\n   |                     +++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:16:23\n   |\nLL |     let _bad6 = \"Text-\\055\\077-MoreText\";\n   |                       ^^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL -     let _bad6 = \"Text-\\055\\077-MoreText\";\nLL +     let _bad6 = \"Text-\\x2d\\077-MoreText\";\n   |\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad6 = \"Text-\\x0055\\077-MoreText\";\n   |                        ++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:16:27\n   |\nLL |     let _bad6 = \"Text-\\055\\077-MoreText\";\n   |                           ^^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL -     let _bad6 = \"Text-\\055\\077-MoreText\";\nLL +     let _bad6 = \"Text-\\055\\x3f-MoreText\";\n   |\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad6 = \"Text-\\055\\x0077-MoreText\";\n   |                            ++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:20:31\n   |\nLL |     let _bad7 = \"EvenMoreText-\\01\\02-ShortEscapes\";\n   |                               ^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL |     let _bad7 = \"EvenMoreText-\\x01\\02-ShortEscapes\";\n   |                                +\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad7 = \"EvenMoreText-\\x0001\\02-ShortEscapes\";\n   |                                +++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:20:34\n   |\nLL |     let _bad7 = \"EvenMoreText-\\01\\02-ShortEscapes\";\n   |                                  ^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL |     let _bad7 = \"EvenMoreText-\\01\\x02-ShortEscapes\";\n   |                                   +\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad7 = \"EvenMoreText-\\01\\x0002-ShortEscapes\";\n   |                                   +++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:24:19\n   |\nLL |     let _bad8 = \"锈\\01锈\";\n   |                    ^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL |     let _bad8 = \"锈\\x01锈\";\n   |                     +\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad8 = \"锈\\x0001锈\";\n   |                     +++\n\nerror: octal-looking escape in a literal\n  --> tests/ui/octal_escapes.rs:26:19\n   |\nLL |     let _bad9 = \"锈\\011锈\";\n   |                    ^^^^\n   |\nhelp: if an octal escape is intended, use a hex escape instead\n   |\nLL -     let _bad9 = \"锈\\011锈\";\nLL +     let _bad9 = \"锈\\x09锈\";\n   |\nhelp: if a null escape is intended, disambiguate using\n   |\nLL |     let _bad9 = \"锈\\x0011锈\";\n   |                     ++\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/ok_expect.fixed",
    "content": "#![allow(clippy::unnecessary_literal_unwrap)]\n\nuse std::io;\n\nstruct MyError(()); // doesn't implement Debug\n\n#[derive(Debug)]\nstruct MyErrorWithParam<T> {\n    x: T,\n}\n\nfn main() {\n    let res: Result<i32, ()> = Ok(0);\n    let _ = res.unwrap();\n\n    res.expect(\"disaster!\");\n    //~^ ok_expect\n\n    res.expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\n    //~^^ ok_expect\n\n    let resres = res;\n    resres.expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\n    //~^^^ ok_expect\n\n    // this one has a suboptimal suggestion, but oh well\n    std::process::Command::new(\"rustc\")\n        .arg(\"-vV\")\n        .output().expect(\"failed to get rustc version\");\n    //~^^^^^ ok_expect\n\n    // the following should not warn, since `expect` isn't implemented unless\n    // the error type implements `Debug`\n    let res2: Result<i32, MyError> = Ok(0);\n    res2.ok().expect(\"oh noes!\");\n    let res3: Result<u32, MyErrorWithParam<u8>> = Ok(0);\n    res3.expect(\"whoof\");\n    //~^ ok_expect\n\n    let res4: Result<u32, io::Error> = Ok(0);\n    res4.expect(\"argh\");\n    //~^ ok_expect\n\n    let res5: io::Result<u32> = Ok(0);\n    res5.expect(\"oops\");\n    //~^ ok_expect\n\n    let res6: Result<u32, &str> = Ok(0);\n    res6.expect(\"meh\");\n    //~^ ok_expect\n}\n"
  },
  {
    "path": "tests/ui/ok_expect.rs",
    "content": "#![allow(clippy::unnecessary_literal_unwrap)]\n\nuse std::io;\n\nstruct MyError(()); // doesn't implement Debug\n\n#[derive(Debug)]\nstruct MyErrorWithParam<T> {\n    x: T,\n}\n\nfn main() {\n    let res: Result<i32, ()> = Ok(0);\n    let _ = res.unwrap();\n\n    res.ok().expect(\"disaster!\");\n    //~^ ok_expect\n\n    res.ok()\n        .expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\n    //~^^ ok_expect\n\n    let resres = res;\n    resres\n        .ok()\n        .expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\n    //~^^^ ok_expect\n\n    // this one has a suboptimal suggestion, but oh well\n    std::process::Command::new(\"rustc\")\n        .arg(\"-vV\")\n        .output()\n        .ok()\n        .expect(\"failed to get rustc version\");\n    //~^^^^^ ok_expect\n\n    // the following should not warn, since `expect` isn't implemented unless\n    // the error type implements `Debug`\n    let res2: Result<i32, MyError> = Ok(0);\n    res2.ok().expect(\"oh noes!\");\n    let res3: Result<u32, MyErrorWithParam<u8>> = Ok(0);\n    res3.ok().expect(\"whoof\");\n    //~^ ok_expect\n\n    let res4: Result<u32, io::Error> = Ok(0);\n    res4.ok().expect(\"argh\");\n    //~^ ok_expect\n\n    let res5: io::Result<u32> = Ok(0);\n    res5.ok().expect(\"oops\");\n    //~^ ok_expect\n\n    let res6: Result<u32, &str> = Ok(0);\n    res6.ok().expect(\"meh\");\n    //~^ ok_expect\n}\n"
  },
  {
    "path": "tests/ui/ok_expect.stderr",
    "content": "error: called `ok().expect()` on a `Result` value\n  --> tests/ui/ok_expect.rs:16:5\n   |\nLL |     res.ok().expect(\"disaster!\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::ok-expect` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ok_expect)]`\nhelp: call `expect()` directly on the `Result`\n   |\nLL -     res.ok().expect(\"disaster!\");\nLL +     res.expect(\"disaster!\");\n   |\n\nerror: called `ok().expect()` on a `Result` value\n  --> tests/ui/ok_expect.rs:19:5\n   |\nLL | /     res.ok()\nLL | |         .expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\n   | |___________________________________________________________________________^\n   |\nhelp: call `expect()` directly on the `Result`\n   |\nLL -     res.ok()\nLL -         .expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\nLL +     res.expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\n   |\n\nerror: called `ok().expect()` on a `Result` value\n  --> tests/ui/ok_expect.rs:24:5\n   |\nLL | /     resres\nLL | |         .ok()\nLL | |         .expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\n   | |___________________________________________________________________________^\n   |\nhelp: call `expect()` directly on the `Result`\n   |\nLL -     resres\nLL -         .ok()\nLL -         .expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\nLL +     resres.expect(\"longlonglonglonglonglonglonglonglonglonglonglonglonglong\");\n   |\n\nerror: called `ok().expect()` on a `Result` value\n  --> tests/ui/ok_expect.rs:30:5\n   |\nLL | /     std::process::Command::new(\"rustc\")\nLL | |         .arg(\"-vV\")\nLL | |         .output()\nLL | |         .ok()\nLL | |         .expect(\"failed to get rustc version\");\n   | |______________________________________________^\n   |\nhelp: call `expect()` directly on the `Result`\n   |\nLL -         .output()\nLL -         .ok()\nLL -         .expect(\"failed to get rustc version\");\nLL +         .output().expect(\"failed to get rustc version\");\n   |\n\nerror: called `ok().expect()` on a `Result` value\n  --> tests/ui/ok_expect.rs:42:5\n   |\nLL |     res3.ok().expect(\"whoof\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: call `expect()` directly on the `Result`\n   |\nLL -     res3.ok().expect(\"whoof\");\nLL +     res3.expect(\"whoof\");\n   |\n\nerror: called `ok().expect()` on a `Result` value\n  --> tests/ui/ok_expect.rs:46:5\n   |\nLL |     res4.ok().expect(\"argh\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: call `expect()` directly on the `Result`\n   |\nLL -     res4.ok().expect(\"argh\");\nLL +     res4.expect(\"argh\");\n   |\n\nerror: called `ok().expect()` on a `Result` value\n  --> tests/ui/ok_expect.rs:50:5\n   |\nLL |     res5.ok().expect(\"oops\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: call `expect()` directly on the `Result`\n   |\nLL -     res5.ok().expect(\"oops\");\nLL +     res5.expect(\"oops\");\n   |\n\nerror: called `ok().expect()` on a `Result` value\n  --> tests/ui/ok_expect.rs:54:5\n   |\nLL |     res6.ok().expect(\"meh\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: call `expect()` directly on the `Result`\n   |\nLL -     res6.ok().expect(\"meh\");\nLL +     res6.expect(\"meh\");\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/only_used_in_recursion.rs",
    "content": "#![warn(clippy::only_used_in_recursion)]\n#![warn(clippy::self_only_used_in_recursion)]\n//@no-rustfix\nfn _simple(x: u32) -> u32 {\n    x\n}\n\nfn _simple2(x: u32) -> u32 {\n    _simple(x)\n}\n\nfn _one_unused(flag: u32, a: usize) -> usize {\n    //~^ only_used_in_recursion\n\n    if flag == 0 { 0 } else { _one_unused(flag - 1, a) }\n}\n\nfn _two_unused(flag: u32, a: u32, b: i32) -> usize {\n    //~^ only_used_in_recursion\n    //~| only_used_in_recursion\n\n    if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }\n}\n\nfn _with_calc(flag: u32, a: i64) -> usize {\n    //~^ only_used_in_recursion\n\n    if flag == 0 {\n        0\n    } else {\n        _with_calc(flag - 1, (-a + 10) * 5)\n    }\n}\n\n// Don't lint\nfn _used_with_flag(flag: u32, a: u32) -> usize {\n    if flag == 0 { 0 } else { _used_with_flag(flag ^ a, a - 1) }\n}\n\nfn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {\n    //~^ only_used_in_recursion\n    //~| only_used_in_recursion\n\n    if flag == 0 {\n        0\n    } else {\n        _used_with_unused(flag - 1, -a, a + b)\n    }\n}\n\nfn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {\n    //~^ only_used_in_recursion\n    //~| only_used_in_recursion\n\n    if flag == 0 {\n        0\n    } else {\n        _codependent_unused(flag - 1, a * b, a + b)\n    }\n}\n\nfn _not_primitive(flag: u32, b: String) -> usize {\n    //~^ only_used_in_recursion\n\n    if flag == 0 { 0 } else { _not_primitive(flag - 1, b) }\n}\n\nstruct A;\n\nimpl A {\n    fn _method(flag: usize, a: usize) -> usize {\n        //~^ only_used_in_recursion\n\n        if flag == 0 { 0 } else { Self::_method(flag - 1, a) }\n    }\n\n    fn _method_self(&self, flag: usize, a: usize) -> usize {\n        //~^ self_only_used_in_recursion\n        //~| only_used_in_recursion\n\n        if flag == 0 { 0 } else { self._method_self(flag - 1, a) }\n    }\n}\n\ntrait B {\n    fn method(flag: u32, a: usize) -> usize;\n    fn method_self(&self, flag: u32, a: usize) -> usize;\n}\n\nimpl B for A {\n    fn method(flag: u32, a: usize) -> usize {\n        //~^ only_used_in_recursion\n\n        if flag == 0 { 0 } else { Self::method(flag - 1, a) }\n    }\n\n    fn method_self(&self, flag: u32, a: usize) -> usize {\n        //~^ only_used_in_recursion\n\n        if flag == 0 { 0 } else { self.method_self(flag - 1, a) }\n    }\n}\n\nimpl B for () {\n    fn method(flag: u32, a: usize) -> usize {\n        if flag == 0 { 0 } else { a }\n    }\n\n    fn method_self(&self, flag: u32, a: usize) -> usize {\n        if flag == 0 { 0 } else { a }\n    }\n}\n\nimpl B for u32 {\n    fn method(flag: u32, a: usize) -> usize {\n        if flag == 0 { 0 } else { <() as B>::method(flag, a) }\n    }\n\n    fn method_self(&self, flag: u32, a: usize) -> usize {\n        if flag == 0 { 0 } else { ().method_self(flag, a) }\n    }\n}\n\ntrait C {\n    fn method(flag: u32, a: usize) -> usize {\n        //~^ only_used_in_recursion\n\n        if flag == 0 { 0 } else { Self::method(flag - 1, a) }\n    }\n\n    fn method_self(&self, flag: u32, a: usize) -> usize {\n        //~^ only_used_in_recursion\n\n        if flag == 0 { 0 } else { self.method_self(flag - 1, a) }\n    }\n}\n\nfn _ignore(flag: usize, _a: usize) -> usize {\n    if flag == 0 { 0 } else { _ignore(flag - 1, _a) }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/only_used_in_recursion.stderr",
    "content": "error: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:12:27\n   |\nLL | fn _one_unused(flag: u32, a: usize) -> usize {\n   |                           ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:15:53\n   |\nLL |     if flag == 0 { 0 } else { _one_unused(flag - 1, a) }\n   |                                                     ^\n   = note: `-D clippy::only-used-in-recursion` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::only_used_in_recursion)]`\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:18:27\n   |\nLL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize {\n   |                           ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:22:53\n   |\nLL |     if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }\n   |                                                     ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:18:35\n   |\nLL | fn _two_unused(flag: u32, a: u32, b: i32) -> usize {\n   |                                   ^ help: if this is intentional, prefix it with an underscore: `_b`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:22:56\n   |\nLL |     if flag == 0 { 0 } else { _two_unused(flag - 1, a, b) }\n   |                                                        ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:25:26\n   |\nLL | fn _with_calc(flag: u32, a: i64) -> usize {\n   |                          ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:31:32\n   |\nLL |         _with_calc(flag - 1, (-a + 10) * 5)\n   |                                ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:40:33\n   |\nLL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {\n   |                                 ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:47:38\n   |\nLL |         _used_with_unused(flag - 1, -a, a + b)\n   |                                      ^  ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:40:41\n   |\nLL | fn _used_with_unused(flag: u32, a: i32, b: i32) -> usize {\n   |                                         ^ help: if this is intentional, prefix it with an underscore: `_b`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:47:45\n   |\nLL |         _used_with_unused(flag - 1, -a, a + b)\n   |                                             ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:51:35\n   |\nLL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {\n   |                                   ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:58:39\n   |\nLL |         _codependent_unused(flag - 1, a * b, a + b)\n   |                                       ^      ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:51:43\n   |\nLL | fn _codependent_unused(flag: u32, a: i32, b: i32) -> usize {\n   |                                           ^ help: if this is intentional, prefix it with an underscore: `_b`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:58:43\n   |\nLL |         _codependent_unused(flag - 1, a * b, a + b)\n   |                                           ^      ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:62:30\n   |\nLL | fn _not_primitive(flag: u32, b: String) -> usize {\n   |                              ^ help: if this is intentional, prefix it with an underscore: `_b`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:65:56\n   |\nLL |     if flag == 0 { 0 } else { _not_primitive(flag - 1, b) }\n   |                                                        ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:71:29\n   |\nLL |     fn _method(flag: usize, a: usize) -> usize {\n   |                             ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:74:59\n   |\nLL |         if flag == 0 { 0 } else { Self::_method(flag - 1, a) }\n   |                                                           ^\n\nerror: `self` is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:77:22\n   |\nLL |     fn _method_self(&self, flag: usize, a: usize) -> usize {\n   |                      ^^^^\n   |\nnote: `self` used here\n  --> tests/ui/only_used_in_recursion.rs:81:35\n   |\nLL |         if flag == 0 { 0 } else { self._method_self(flag - 1, a) }\n   |                                   ^^^^\n   = note: `-D clippy::self-only-used-in-recursion` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::self_only_used_in_recursion)]`\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:77:41\n   |\nLL |     fn _method_self(&self, flag: usize, a: usize) -> usize {\n   |                                         ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:81:63\n   |\nLL |         if flag == 0 { 0 } else { self._method_self(flag - 1, a) }\n   |                                                               ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:91:26\n   |\nLL |     fn method(flag: u32, a: usize) -> usize {\n   |                          ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:94:58\n   |\nLL |         if flag == 0 { 0 } else { Self::method(flag - 1, a) }\n   |                                                          ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:97:38\n   |\nLL |     fn method_self(&self, flag: u32, a: usize) -> usize {\n   |                                      ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:100:62\n   |\nLL |         if flag == 0 { 0 } else { self.method_self(flag - 1, a) }\n   |                                                              ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:125:26\n   |\nLL |     fn method(flag: u32, a: usize) -> usize {\n   |                          ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:128:58\n   |\nLL |         if flag == 0 { 0 } else { Self::method(flag - 1, a) }\n   |                                                          ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion.rs:131:38\n   |\nLL |     fn method_self(&self, flag: u32, a: usize) -> usize {\n   |                                      ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion.rs:134:62\n   |\nLL |         if flag == 0 { 0 } else { self.method_self(flag - 1, a) }\n   |                                                              ^\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/only_used_in_recursion2.rs",
    "content": "#![warn(clippy::only_used_in_recursion)]\n//@no-rustfix\nfn _with_inner(flag: u32, a: u32, b: u32) -> usize {\n    //~^ only_used_in_recursion\n\n    fn inner(flag: u32, a: u32) -> u32 {\n        //~^ only_used_in_recursion\n\n        if flag == 0 { 0 } else { inner(flag, a) }\n    }\n\n    let x = inner(flag, a);\n    if flag == 0 { 0 } else { _with_inner(flag, a, b + x) }\n}\n\nfn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 {\n    //~^ only_used_in_recursion\n\n    if let Some(x) = a.and_then(|x| f(x, x)) {\n        _with_closure(Some(x), b, f)\n    } else {\n        0\n    }\n}\n\n// Issue #8560\ntrait D {\n    fn foo(&mut self, arg: u32) -> u32;\n}\n\nmod m {\n    pub struct S(u32);\n    impl S {\n        pub fn foo(&mut self, arg: u32) -> u32 {\n            arg + self.0\n        }\n    }\n}\n\nimpl D for m::S {\n    fn foo(&mut self, arg: u32) -> u32 {\n        self.foo(arg)\n    }\n}\n\n// Issue #8782\nfn only_let(x: u32) {\n    let y = 10u32;\n    let _z = x * y;\n}\n\ntrait E<T: E<()>> {\n    fn method(flag: u32, a: usize) -> usize {\n        if flag == 0 {\n            0\n        } else {\n            <T as E<()>>::method(flag - 1, a)\n        }\n    }\n}\n\nimpl E<()> for () {\n    fn method(flag: u32, a: usize) -> usize {\n        if flag == 0 { 0 } else { a }\n    }\n}\n\nfn overwritten_param(flag: u32, mut a: usize) -> usize {\n    //~^ only_used_in_recursion\n\n    if flag == 0 {\n        return 0;\n    } else if flag > 5 {\n        a += flag as usize;\n    } else {\n        a = 5;\n    }\n    overwritten_param(flag, a)\n}\n\nfn field_direct(flag: u32, mut a: (usize,)) -> usize {\n    //~^ only_used_in_recursion\n\n    if flag == 0 {\n        0\n    } else {\n        a.0 += 5;\n        field_direct(flag - 1, a)\n    }\n}\n\nfn field_deref(flag: u32, a: &mut Box<(usize,)>) -> usize {\n    if flag == 0 {\n        0\n    } else {\n        a.0 += 5;\n        field_deref(flag - 1, a)\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/only_used_in_recursion2.stderr",
    "content": "error: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion2.rs:3:35\n   |\nLL | fn _with_inner(flag: u32, a: u32, b: u32) -> usize {\n   |                                   ^ help: if this is intentional, prefix it with an underscore: `_b`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion2.rs:13:52\n   |\nLL |     if flag == 0 { 0 } else { _with_inner(flag, a, b + x) }\n   |                                                    ^\n   = note: `-D clippy::only-used-in-recursion` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::only_used_in_recursion)]`\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion2.rs:6:25\n   |\nLL |     fn inner(flag: u32, a: u32) -> u32 {\n   |                         ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion2.rs:9:47\n   |\nLL |         if flag == 0 { 0 } else { inner(flag, a) }\n   |                                               ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion2.rs:16:34\n   |\nLL | fn _with_closure(a: Option<u32>, b: u32, f: impl Fn(u32, u32) -> Option<u32>) -> u32 {\n   |                                  ^ help: if this is intentional, prefix it with an underscore: `_b`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion2.rs:20:32\n   |\nLL |         _with_closure(Some(x), b, f)\n   |                                ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion2.rs:68:37\n   |\nLL | fn overwritten_param(flag: u32, mut a: usize) -> usize {\n   |                                     ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion2.rs:78:29\n   |\nLL |     overwritten_param(flag, a)\n   |                             ^\n\nerror: parameter is only used in recursion\n  --> tests/ui/only_used_in_recursion2.rs:81:32\n   |\nLL | fn field_direct(flag: u32, mut a: (usize,)) -> usize {\n   |                                ^ help: if this is intentional, prefix it with an underscore: `_a`\n   |\nnote: parameter used here\n  --> tests/ui/only_used_in_recursion2.rs:88:32\n   |\nLL |         field_direct(flag - 1, a)\n   |                                ^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/op_ref.fixed",
    "content": "#![allow(unused_variables, clippy::disallowed_names)]\n#![warn(clippy::op_ref)]\nuse std::collections::HashSet;\nuse std::ops::{BitAnd, Mul};\n\nfn main() {\n    let tracked_fds: HashSet<i32> = HashSet::new();\n    let new_fds = HashSet::new();\n    let unwanted = &tracked_fds - &new_fds;\n\n    let foo = 5 - 6;\n    //~^ op_ref\n\n    let bar = String::new();\n    let bar = \"foo\" == &bar;\n\n    let a = \"a\".to_string();\n    let b = \"a\";\n\n    if b < &a {\n        println!(\"OK\");\n    }\n\n    struct X(i32);\n    impl BitAnd for X {\n        type Output = X;\n        fn bitand(self, rhs: X) -> X {\n            X(self.0 & rhs.0)\n        }\n    }\n    impl<'a> BitAnd<&'a X> for X {\n        type Output = X;\n        fn bitand(self, rhs: &'a X) -> X {\n            X(self.0 & rhs.0)\n        }\n    }\n    let x = X(1);\n    let y = X(2);\n    let z = x & &y;\n\n    #[derive(Copy, Clone)]\n    struct Y(i32);\n    impl BitAnd for Y {\n        type Output = Y;\n        fn bitand(self, rhs: Y) -> Y {\n            Y(self.0 & rhs.0)\n        }\n    }\n    impl<'a> BitAnd<&'a Y> for Y {\n        type Output = Y;\n        fn bitand(self, rhs: &'a Y) -> Y {\n            Y(self.0 & rhs.0)\n        }\n    }\n    let x = Y(1);\n    let y = Y(2);\n    let z = x & y;\n    //~^ op_ref\n}\n\n#[derive(Clone, Copy)]\nstruct A(i32);\n#[derive(Clone, Copy)]\nstruct B(i32);\n\nimpl Mul<&A> for B {\n    type Output = i32;\n    fn mul(self, rhs: &A) -> Self::Output {\n        self.0 * rhs.0\n    }\n}\nimpl Mul<A> for B {\n    type Output = i32;\n    fn mul(self, rhs: A) -> Self::Output {\n        // Should not lint because removing the reference would lead to unconditional recursion\n        self * &rhs\n    }\n}\nimpl Mul<&A> for A {\n    type Output = i32;\n    fn mul(self, rhs: &A) -> Self::Output {\n        self.0 * rhs.0\n    }\n}\nimpl Mul<A> for A {\n    type Output = i32;\n    fn mul(self, rhs: A) -> Self::Output {\n        let one = B(1);\n        let two = 2;\n        let three = 3;\n        let _ = one * self;\n        //~^ op_ref\n\n        let _ = two + three;\n        //~^ op_ref\n\n        // Removing the reference would lead to unconditional recursion\n        self * &rhs\n    }\n}\n\nmod issue_2597 {\n    fn ex1() {\n        let a: &str = \"abc\";\n        let b: String = \"abc\".to_owned();\n        println!(\"{}\", a > &b);\n    }\n\n    pub fn ex2<T: Ord + PartialOrd>(array: &[T], val: &T, idx: usize) -> bool {\n        &array[idx] < val\n    }\n}\n\n#[allow(clippy::needless_ifs)]\nfn issue15063() {\n    use std::ops::BitAnd;\n\n    macro_rules! mac {\n        ($e:expr) => {\n            $e.clone()\n        };\n    }\n\n    let x = 1;\n    if x == mac!(1) {}\n    //~^ op_ref\n\n    #[derive(Copy, Clone)]\n    struct Y(i32);\n    impl BitAnd for Y {\n        type Output = Y;\n        fn bitand(self, rhs: Y) -> Y {\n            Y(self.0 & rhs.0)\n        }\n    }\n    impl<'a> BitAnd<&'a Y> for Y {\n        type Output = Y;\n        fn bitand(self, rhs: &'a Y) -> Y {\n            Y(self.0 & rhs.0)\n        }\n    }\n    let x = Y(1);\n    let y = Y(2);\n    let z = x & mac!(y);\n    //~^ op_ref\n}\n"
  },
  {
    "path": "tests/ui/op_ref.rs",
    "content": "#![allow(unused_variables, clippy::disallowed_names)]\n#![warn(clippy::op_ref)]\nuse std::collections::HashSet;\nuse std::ops::{BitAnd, Mul};\n\nfn main() {\n    let tracked_fds: HashSet<i32> = HashSet::new();\n    let new_fds = HashSet::new();\n    let unwanted = &tracked_fds - &new_fds;\n\n    let foo = &5 - &6;\n    //~^ op_ref\n\n    let bar = String::new();\n    let bar = \"foo\" == &bar;\n\n    let a = \"a\".to_string();\n    let b = \"a\";\n\n    if b < &a {\n        println!(\"OK\");\n    }\n\n    struct X(i32);\n    impl BitAnd for X {\n        type Output = X;\n        fn bitand(self, rhs: X) -> X {\n            X(self.0 & rhs.0)\n        }\n    }\n    impl<'a> BitAnd<&'a X> for X {\n        type Output = X;\n        fn bitand(self, rhs: &'a X) -> X {\n            X(self.0 & rhs.0)\n        }\n    }\n    let x = X(1);\n    let y = X(2);\n    let z = x & &y;\n\n    #[derive(Copy, Clone)]\n    struct Y(i32);\n    impl BitAnd for Y {\n        type Output = Y;\n        fn bitand(self, rhs: Y) -> Y {\n            Y(self.0 & rhs.0)\n        }\n    }\n    impl<'a> BitAnd<&'a Y> for Y {\n        type Output = Y;\n        fn bitand(self, rhs: &'a Y) -> Y {\n            Y(self.0 & rhs.0)\n        }\n    }\n    let x = Y(1);\n    let y = Y(2);\n    let z = x & &y;\n    //~^ op_ref\n}\n\n#[derive(Clone, Copy)]\nstruct A(i32);\n#[derive(Clone, Copy)]\nstruct B(i32);\n\nimpl Mul<&A> for B {\n    type Output = i32;\n    fn mul(self, rhs: &A) -> Self::Output {\n        self.0 * rhs.0\n    }\n}\nimpl Mul<A> for B {\n    type Output = i32;\n    fn mul(self, rhs: A) -> Self::Output {\n        // Should not lint because removing the reference would lead to unconditional recursion\n        self * &rhs\n    }\n}\nimpl Mul<&A> for A {\n    type Output = i32;\n    fn mul(self, rhs: &A) -> Self::Output {\n        self.0 * rhs.0\n    }\n}\nimpl Mul<A> for A {\n    type Output = i32;\n    fn mul(self, rhs: A) -> Self::Output {\n        let one = B(1);\n        let two = 2;\n        let three = 3;\n        let _ = one * &self;\n        //~^ op_ref\n\n        let _ = two + &three;\n        //~^ op_ref\n\n        // Removing the reference would lead to unconditional recursion\n        self * &rhs\n    }\n}\n\nmod issue_2597 {\n    fn ex1() {\n        let a: &str = \"abc\";\n        let b: String = \"abc\".to_owned();\n        println!(\"{}\", a > &b);\n    }\n\n    pub fn ex2<T: Ord + PartialOrd>(array: &[T], val: &T, idx: usize) -> bool {\n        &array[idx] < val\n    }\n}\n\n#[allow(clippy::needless_ifs)]\nfn issue15063() {\n    use std::ops::BitAnd;\n\n    macro_rules! mac {\n        ($e:expr) => {\n            $e.clone()\n        };\n    }\n\n    let x = 1;\n    if &x == &mac!(1) {}\n    //~^ op_ref\n\n    #[derive(Copy, Clone)]\n    struct Y(i32);\n    impl BitAnd for Y {\n        type Output = Y;\n        fn bitand(self, rhs: Y) -> Y {\n            Y(self.0 & rhs.0)\n        }\n    }\n    impl<'a> BitAnd<&'a Y> for Y {\n        type Output = Y;\n        fn bitand(self, rhs: &'a Y) -> Y {\n            Y(self.0 & rhs.0)\n        }\n    }\n    let x = Y(1);\n    let y = Y(2);\n    let z = x & &mac!(y);\n    //~^ op_ref\n}\n"
  },
  {
    "path": "tests/ui/op_ref.stderr",
    "content": "error: needlessly taken reference of both operands\n  --> tests/ui/op_ref.rs:11:15\n   |\nLL |     let foo = &5 - &6;\n   |               ^^^^^^^\n   |\n   = note: `-D clippy::op-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::op_ref)]`\nhelp: use the values directly\n   |\nLL -     let foo = &5 - &6;\nLL +     let foo = 5 - 6;\n   |\n\nerror: taken reference of right operand\n  --> tests/ui/op_ref.rs:57:13\n   |\nLL |     let z = x & &y;\n   |             ^^^^--\n   |                 |\n   |                 help: use the right value directly: `y`\n\nerror: taken reference of right operand\n  --> tests/ui/op_ref.rs:91:17\n   |\nLL |         let _ = one * &self;\n   |                 ^^^^^^-----\n   |                       |\n   |                       help: use the right value directly: `self`\n\nerror: taken reference of right operand\n  --> tests/ui/op_ref.rs:94:17\n   |\nLL |         let _ = two + &three;\n   |                 ^^^^^^------\n   |                       |\n   |                       help: use the right value directly: `three`\n\nerror: needlessly taken reference of both operands\n  --> tests/ui/op_ref.rs:125:8\n   |\nLL |     if &x == &mac!(1) {}\n   |        ^^^^^^^^^^^^^^\n   |\nhelp: use the values directly\n   |\nLL -     if &x == &mac!(1) {}\nLL +     if x == mac!(1) {}\n   |\n\nerror: taken reference of right operand\n  --> tests/ui/op_ref.rs:144:13\n   |\nLL |     let z = x & &mac!(y);\n   |             ^^^^--------\n   |                 |\n   |                 help: use the right value directly: `mac!(y)`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/open_options.rs",
    "content": "#![allow(unused_must_use)]\n#![warn(clippy::nonsensical_open_options)]\n\nuse std::fs::OpenOptions;\n\ntrait OpenOptionsExt {\n    fn truncate_write(&mut self, opt: bool) -> &mut Self;\n}\n\nimpl OpenOptionsExt for OpenOptions {\n    fn truncate_write(&mut self, opt: bool) -> &mut Self {\n        self.truncate(opt).write(opt)\n    }\n}\n\nfn main() {\n    OpenOptions::new().read(true).truncate(true).open(\"foo.txt\");\n    //~^ nonsensical_open_options\n\n    OpenOptions::new().append(true).truncate(true).open(\"foo.txt\");\n    //~^ nonsensical_open_options\n\n    OpenOptions::new().read(true).read(false).open(\"foo.txt\");\n    //~^ nonsensical_open_options\n\n    OpenOptions::new()\n        .create(true)\n        .truncate(true) // Ensure we don't trigger suspicious open options by having create without truncate\n        .create(false)\n        //~^ nonsensical_open_options\n        .open(\"foo.txt\");\n    OpenOptions::new().write(true).write(false).open(\"foo.txt\");\n    //~^ nonsensical_open_options\n\n    OpenOptions::new().append(true).append(false).open(\"foo.txt\");\n    //~^ nonsensical_open_options\n\n    OpenOptions::new().truncate(true).truncate(false).open(\"foo.txt\");\n    //~^ nonsensical_open_options\n\n    std::fs::File::options().read(true).read(false).open(\"foo.txt\");\n    //~^ nonsensical_open_options\n\n    let mut options = std::fs::OpenOptions::new();\n    options.read(true);\n    options.read(false);\n    // Possible future improvement: recognize open options method call chains across statements.\n    options.open(\"foo.txt\");\n\n    let mut options = std::fs::OpenOptions::new();\n    options.truncate(true);\n    options.create(true).open(\"foo.txt\");\n\n    OpenOptions::new().create(true).truncate_write(true).open(\"foo.txt\");\n}\n"
  },
  {
    "path": "tests/ui/open_options.stderr",
    "content": "error: file opened with `truncate` and `read`\n  --> tests/ui/open_options.rs:17:5\n   |\nLL |     OpenOptions::new().read(true).truncate(true).open(\"foo.txt\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::nonsensical-open-options` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::nonsensical_open_options)]`\n\nerror: file opened with `append` and `truncate`\n  --> tests/ui/open_options.rs:20:5\n   |\nLL |     OpenOptions::new().append(true).truncate(true).open(\"foo.txt\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: the method `read` is called more than once\n  --> tests/ui/open_options.rs:23:35\n   |\nLL |     OpenOptions::new().read(true).read(false).open(\"foo.txt\");\n   |                                   ^^^^^^^^^^^\n\nerror: the method `create` is called more than once\n  --> tests/ui/open_options.rs:29:10\n   |\nLL |         .create(false)\n   |          ^^^^^^^^^^^^^\n\nerror: the method `write` is called more than once\n  --> tests/ui/open_options.rs:32:36\n   |\nLL |     OpenOptions::new().write(true).write(false).open(\"foo.txt\");\n   |                                    ^^^^^^^^^^^^\n\nerror: the method `append` is called more than once\n  --> tests/ui/open_options.rs:35:37\n   |\nLL |     OpenOptions::new().append(true).append(false).open(\"foo.txt\");\n   |                                     ^^^^^^^^^^^^^\n\nerror: the method `truncate` is called more than once\n  --> tests/ui/open_options.rs:38:39\n   |\nLL |     OpenOptions::new().truncate(true).truncate(false).open(\"foo.txt\");\n   |                                       ^^^^^^^^^^^^^^^\n\nerror: the method `read` is called more than once\n  --> tests/ui/open_options.rs:41:41\n   |\nLL |     std::fs::File::options().read(true).read(false).open(\"foo.txt\");\n   |                                         ^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/open_options_fixable.fixed",
    "content": "use std::fs::OpenOptions;\n#[allow(unused_must_use)]\n#[warn(clippy::suspicious_open_options)]\nfn main() {\n    OpenOptions::new().create(true).truncate(true).open(\"foo.txt\");\n    //~^ suspicious_open_options\n}\n"
  },
  {
    "path": "tests/ui/open_options_fixable.rs",
    "content": "use std::fs::OpenOptions;\n#[allow(unused_must_use)]\n#[warn(clippy::suspicious_open_options)]\nfn main() {\n    OpenOptions::new().create(true).open(\"foo.txt\");\n    //~^ suspicious_open_options\n}\n"
  },
  {
    "path": "tests/ui/open_options_fixable.stderr",
    "content": "error: file opened with `create`, but `truncate` behavior not defined\n  --> tests/ui/open_options_fixable.rs:5:24\n   |\nLL |     OpenOptions::new().create(true).open(\"foo.txt\");\n   |                        ^^^^^^^^^^^^- help: add: `.truncate(true)`\n   |\n   = help: if you intend to overwrite an existing file entirely, call `.truncate(true)`\n   = help: if you instead know that you may want to keep some parts of the old file, call `.truncate(false)`\n   = help: alternatively, use `.append(true)` to append to the file instead of overwriting it\n   = note: `-D clippy::suspicious-open-options` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_open_options)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/option_as_ref_cloned.fixed",
    "content": "#![warn(clippy::option_as_ref_cloned)]\n#![allow(clippy::clone_on_copy)]\n\nfn main() {\n    let mut x = Some(String::new());\n\n    let _: Option<String> = x.clone();\n    //~^ option_as_ref_cloned\n    let _: Option<String> = x.clone();\n    //~^ option_as_ref_cloned\n\n    let y = x.as_ref();\n    let _: Option<&String> = y.clone();\n    //~^ option_as_ref_cloned\n\n    macro_rules! cloned_recv {\n        () => {\n            x.as_ref()\n        };\n    }\n\n    // Don't lint when part of the expression is from a macro\n    let _: Option<String> = cloned_recv!().cloned();\n}\n"
  },
  {
    "path": "tests/ui/option_as_ref_cloned.rs",
    "content": "#![warn(clippy::option_as_ref_cloned)]\n#![allow(clippy::clone_on_copy)]\n\nfn main() {\n    let mut x = Some(String::new());\n\n    let _: Option<String> = x.as_ref().cloned();\n    //~^ option_as_ref_cloned\n    let _: Option<String> = x.as_mut().cloned();\n    //~^ option_as_ref_cloned\n\n    let y = x.as_ref();\n    let _: Option<&String> = y.as_ref().cloned();\n    //~^ option_as_ref_cloned\n\n    macro_rules! cloned_recv {\n        () => {\n            x.as_ref()\n        };\n    }\n\n    // Don't lint when part of the expression is from a macro\n    let _: Option<String> = cloned_recv!().cloned();\n}\n"
  },
  {
    "path": "tests/ui/option_as_ref_cloned.stderr",
    "content": "error: cloning an `Option<_>` using `.as_ref().cloned()`\n  --> tests/ui/option_as_ref_cloned.rs:7:31\n   |\nLL |     let _: Option<String> = x.as_ref().cloned();\n   |                               ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::option-as-ref-cloned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_cloned)]`\nhelp: this can be written more concisely by cloning the `Option<_>` directly\n   |\nLL -     let _: Option<String> = x.as_ref().cloned();\nLL +     let _: Option<String> = x.clone();\n   |\n\nerror: cloning an `Option<_>` using `.as_mut().cloned()`\n  --> tests/ui/option_as_ref_cloned.rs:9:31\n   |\nLL |     let _: Option<String> = x.as_mut().cloned();\n   |                               ^^^^^^^^^^^^^^^\n   |\nhelp: this can be written more concisely by cloning the `Option<_>` directly\n   |\nLL -     let _: Option<String> = x.as_mut().cloned();\nLL +     let _: Option<String> = x.clone();\n   |\n\nerror: cloning an `Option<_>` using `.as_ref().cloned()`\n  --> tests/ui/option_as_ref_cloned.rs:13:32\n   |\nLL |     let _: Option<&String> = y.as_ref().cloned();\n   |                                ^^^^^^^^^^^^^^^\n   |\nhelp: this can be written more concisely by cloning the `Option<_>` directly\n   |\nLL -     let _: Option<&String> = y.as_ref().cloned();\nLL +     let _: Option<&String> = y.clone();\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/option_as_ref_deref.fixed",
    "content": "#![allow(unused, clippy::redundant_clone, clippy::useless_vec)]\n#![warn(clippy::option_as_ref_deref)]\n\nuse std::ffi::{CString, OsString};\nuse std::ops::{Deref, DerefMut};\nuse std::path::PathBuf;\n\nfn main() {\n    let mut opt = Some(String::from(\"123\"));\n\n    let _ = opt.clone().as_deref().map(str::len);\n    //~^ option_as_ref_deref\n\n    #[rustfmt::skip]\n    let _ = opt.clone().as_deref()\n        .map(str::len);\n\n    let _ = opt.as_deref_mut();\n    //~^ option_as_ref_deref\n\n    let _ = opt.as_deref();\n    //~^ option_as_ref_deref\n    let _ = opt.as_deref();\n    //~^ option_as_ref_deref\n    let _ = opt.as_deref_mut();\n    //~^ option_as_ref_deref\n    let _ = opt.as_deref_mut();\n    //~^ option_as_ref_deref\n    let _ = Some(CString::new(vec![]).unwrap()).as_deref();\n    //~^ option_as_ref_deref\n    let _ = Some(OsString::new()).as_deref();\n    //~^ option_as_ref_deref\n    let _ = Some(PathBuf::new()).as_deref();\n    //~^ option_as_ref_deref\n    let _ = Some(Vec::<()>::new()).as_deref();\n    //~^ option_as_ref_deref\n    let _ = Some(Vec::<()>::new()).as_deref_mut();\n    //~^ option_as_ref_deref\n\n    let _ = opt.as_deref();\n    //~^ option_as_ref_deref\n    let _ = opt.clone().as_deref_mut().map(|x| x.len());\n    //~^ option_as_ref_deref\n\n    let vc = vec![String::new()];\n    let _ = Some(1_usize).as_ref().map(|x| vc[*x].as_str()); // should not be linted\n\n    let _: Option<&str> = Some(&String::new()).as_ref().map(|x| x.as_str()); // should not be linted\n\n    let _ = opt.as_deref();\n    //~^ option_as_ref_deref\n    let _ = opt.as_deref_mut();\n    //~^ option_as_ref_deref\n\n    // Issue #5927\n    let _ = opt.as_deref();\n    //~^ option_as_ref_deref\n}\n\n#[clippy::msrv = \"1.39\"]\nfn msrv_1_39() {\n    let opt = Some(String::from(\"123\"));\n    let _ = opt.as_ref().map(String::as_str);\n}\n\n#[clippy::msrv = \"1.40\"]\nfn msrv_1_40() {\n    let opt = Some(String::from(\"123\"));\n    let _ = opt.as_deref();\n    //~^ option_as_ref_deref\n}\n"
  },
  {
    "path": "tests/ui/option_as_ref_deref.rs",
    "content": "#![allow(unused, clippy::redundant_clone, clippy::useless_vec)]\n#![warn(clippy::option_as_ref_deref)]\n\nuse std::ffi::{CString, OsString};\nuse std::ops::{Deref, DerefMut};\nuse std::path::PathBuf;\n\nfn main() {\n    let mut opt = Some(String::from(\"123\"));\n\n    let _ = opt.clone().as_ref().map(Deref::deref).map(str::len);\n    //~^ option_as_ref_deref\n\n    #[rustfmt::skip]\n    let _ = opt.clone()\n    //~^ option_as_ref_deref\n        .as_ref().map(\n            Deref::deref\n        )\n        .map(str::len);\n\n    let _ = opt.as_mut().map(DerefMut::deref_mut);\n    //~^ option_as_ref_deref\n\n    let _ = opt.as_ref().map(String::as_str);\n    //~^ option_as_ref_deref\n    let _ = opt.as_ref().map(|x| x.as_str());\n    //~^ option_as_ref_deref\n    let _ = opt.as_mut().map(String::as_mut_str);\n    //~^ option_as_ref_deref\n    let _ = opt.as_mut().map(|x| x.as_mut_str());\n    //~^ option_as_ref_deref\n    let _ = Some(CString::new(vec![]).unwrap()).as_ref().map(CString::as_c_str);\n    //~^ option_as_ref_deref\n    let _ = Some(OsString::new()).as_ref().map(OsString::as_os_str);\n    //~^ option_as_ref_deref\n    let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path);\n    //~^ option_as_ref_deref\n    let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice);\n    //~^ option_as_ref_deref\n    let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice);\n    //~^ option_as_ref_deref\n\n    let _ = opt.as_ref().map(|x| x.deref());\n    //~^ option_as_ref_deref\n    let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len());\n    //~^ option_as_ref_deref\n\n    let vc = vec![String::new()];\n    let _ = Some(1_usize).as_ref().map(|x| vc[*x].as_str()); // should not be linted\n\n    let _: Option<&str> = Some(&String::new()).as_ref().map(|x| x.as_str()); // should not be linted\n\n    let _ = opt.as_ref().map(|x| &**x);\n    //~^ option_as_ref_deref\n    let _ = opt.as_mut().map(|x| &mut **x);\n    //~^ option_as_ref_deref\n\n    // Issue #5927\n    let _ = opt.as_ref().map(std::ops::Deref::deref);\n    //~^ option_as_ref_deref\n}\n\n#[clippy::msrv = \"1.39\"]\nfn msrv_1_39() {\n    let opt = Some(String::from(\"123\"));\n    let _ = opt.as_ref().map(String::as_str);\n}\n\n#[clippy::msrv = \"1.40\"]\nfn msrv_1_40() {\n    let opt = Some(String::from(\"123\"));\n    let _ = opt.as_ref().map(String::as_str);\n    //~^ option_as_ref_deref\n}\n"
  },
  {
    "path": "tests/ui/option_as_ref_deref.stderr",
    "content": "error: called `.as_ref().map(Deref::deref)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:11:13\n   |\nLL |     let _ = opt.clone().as_ref().map(Deref::deref).map(str::len);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.clone().as_deref()`\n   |\n   = note: `-D clippy::option-as-ref-deref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_deref)]`\n\nerror: called `.as_ref().map(Deref::deref)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:15:13\n   |\nLL |       let _ = opt.clone()\n   |  _____________^\nLL | |\nLL | |         .as_ref().map(\nLL | |             Deref::deref\nLL | |         )\n   | |_________^ help: consider using as_deref: `opt.clone().as_deref()`\n\nerror: called `.as_mut().map(DerefMut::deref_mut)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:22:13\n   |\nLL |     let _ = opt.as_mut().map(DerefMut::deref_mut);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`\n\nerror: called `.as_ref().map(String::as_str)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:25:13\n   |\nLL |     let _ = opt.as_ref().map(String::as_str);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`\n\nerror: called `.as_ref().map(|x| x.as_str())` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:27:13\n   |\nLL |     let _ = opt.as_ref().map(|x| x.as_str());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`\n\nerror: called `.as_mut().map(String::as_mut_str)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:29:13\n   |\nLL |     let _ = opt.as_mut().map(String::as_mut_str);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`\n\nerror: called `.as_mut().map(|x| x.as_mut_str())` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:31:13\n   |\nLL |     let _ = opt.as_mut().map(|x| x.as_mut_str());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`\n\nerror: called `.as_ref().map(CString::as_c_str)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:33:13\n   |\nLL |     let _ = Some(CString::new(vec![]).unwrap()).as_ref().map(CString::as_c_str);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(CString::new(vec![]).unwrap()).as_deref()`\n\nerror: called `.as_ref().map(OsString::as_os_str)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:35:13\n   |\nLL |     let _ = Some(OsString::new()).as_ref().map(OsString::as_os_str);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(OsString::new()).as_deref()`\n\nerror: called `.as_ref().map(PathBuf::as_path)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:37:13\n   |\nLL |     let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(PathBuf::new()).as_deref()`\n\nerror: called `.as_ref().map(Vec::as_slice)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:39:13\n   |\nLL |     let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(Vec::<()>::new()).as_deref()`\n\nerror: called `.as_mut().map(Vec::as_mut_slice)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:41:13\n   |\nLL |     let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `Some(Vec::<()>::new()).as_deref_mut()`\n\nerror: called `.as_ref().map(|x| x.deref())` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:44:13\n   |\nLL |     let _ = opt.as_ref().map(|x| x.deref());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`\n\nerror: called `.as_mut().map(|x| x.deref_mut())` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:46:13\n   |\nLL |     let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.clone().as_deref_mut()`\n\nerror: called `.as_ref().map(|x| &**x)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:54:13\n   |\nLL |     let _ = opt.as_ref().map(|x| &**x);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`\n\nerror: called `.as_mut().map(|x| &mut **x)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:56:13\n   |\nLL |     let _ = opt.as_mut().map(|x| &mut **x);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`\n\nerror: called `.as_ref().map(std::ops::Deref::deref)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:60:13\n   |\nLL |     let _ = opt.as_ref().map(std::ops::Deref::deref);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`\n\nerror: called `.as_ref().map(String::as_str)` on an `Option` value\n  --> tests/ui/option_as_ref_deref.rs:73:13\n   |\nLL |     let _ = opt.as_ref().map(String::as_str);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/option_env_unwrap.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::option_env_unwrap)]\n#![allow(clippy::map_flatten)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n#[inline_macros]\nfn main() {\n    let _ = option_env!(\"PATH\").unwrap();\n    //~^ option_env_unwrap\n    let _ = option_env!(\"PATH\").expect(\"environment variable PATH isn't set\");\n    //~^ option_env_unwrap\n    let _ = option_env!(\"__Y__do_not_use\").unwrap(); // This test only works if you don't have a __Y__do_not_use env variable in your environment.\n    //\n    //~^^ option_env_unwrap\n    let _ = inline!(option_env!($\"PATH\").unwrap());\n    //~^ option_env_unwrap\n    let _ = inline!(option_env!($\"PATH\").expect($\"environment variable PATH isn't set\"));\n    //~^ option_env_unwrap\n    let _ = external!(option_env!($\"PATH\").unwrap());\n    //~^ option_env_unwrap\n    let _ = external!(option_env!($\"PATH\").expect($\"environment variable PATH isn't set\"));\n    //~^ option_env_unwrap\n}\n"
  },
  {
    "path": "tests/ui/option_env_unwrap.stderr",
    "content": "error: this will panic at run-time if the environment variable doesn't exist at compile-time\n  --> tests/ui/option_env_unwrap.rs:10:13\n   |\nLL |     let _ = option_env!(\"PATH\").unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the `env!` macro instead\n   = note: `-D clippy::option-env-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_env_unwrap)]`\n\nerror: this will panic at run-time if the environment variable doesn't exist at compile-time\n  --> tests/ui/option_env_unwrap.rs:12:13\n   |\nLL |     let _ = option_env!(\"PATH\").expect(\"environment variable PATH isn't set\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the `env!` macro instead\n\nerror: this will panic at run-time if the environment variable doesn't exist at compile-time\n  --> tests/ui/option_env_unwrap.rs:14:13\n   |\nLL |     let _ = option_env!(\"__Y__do_not_use\").unwrap(); // This test only works if you don't have a __Y__do_not_use env variable in you...\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the `env!` macro instead\n\nerror: this will panic at run-time if the environment variable doesn't exist at compile-time\n  --> tests/ui/option_env_unwrap.rs:17:21\n   |\nLL |     let _ = inline!(option_env!($\"PATH\").unwrap());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the `env!` macro instead\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this will panic at run-time if the environment variable doesn't exist at compile-time\n  --> tests/ui/option_env_unwrap.rs:19:21\n   |\nLL |     let _ = inline!(option_env!($\"PATH\").expect($\"environment variable PATH isn't set\"));\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the `env!` macro instead\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this will panic at run-time if the environment variable doesn't exist at compile-time\n  --> tests/ui/option_env_unwrap.rs:21:13\n   |\nLL |     let _ = external!(option_env!($\"PATH\").unwrap());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the `env!` macro instead\n   = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this will panic at run-time if the environment variable doesn't exist at compile-time\n  --> tests/ui/option_env_unwrap.rs:23:13\n   |\nLL |     let _ = external!(option_env!($\"PATH\").expect($\"environment variable PATH isn't set\"));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using the `env!` macro instead\n   = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/option_filter_map.fixed",
    "content": "#![warn(clippy::option_filter_map)]\n#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]\n\nfn main() {\n    let _ = Some(Some(1)).flatten();\n    //~^ option_filter_map\n\n    let _ = Some(Some(1)).flatten();\n    //~^ option_filter_map\n\n    let _ = Some(1).map(odds_out).flatten();\n    //~^ option_filter_map\n\n    let _ = Some(1).map(odds_out).flatten();\n    //~^ option_filter_map\n\n    let _ = vec![Some(1)].into_iter().flatten();\n    //~^ option_filter_map\n\n    let _ = vec![Some(1)].into_iter().flatten();\n    //~^ option_filter_map\n\n    let _ = vec![1]\n        .into_iter()\n        .map(odds_out)\n        .flatten();\n    let _ = vec![1]\n        .into_iter()\n        .map(odds_out)\n        .flatten();\n}\n\nfn odds_out(x: i32) -> Option<i32> {\n    if x % 2 == 0 { Some(x) } else { None }\n}\n"
  },
  {
    "path": "tests/ui/option_filter_map.rs",
    "content": "#![warn(clippy::option_filter_map)]\n#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]\n\nfn main() {\n    let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap);\n    //~^ option_filter_map\n\n    let _ = Some(Some(1)).filter(|o| o.is_some()).map(|o| o.unwrap());\n    //~^ option_filter_map\n\n    let _ = Some(1).map(odds_out).filter(Option::is_some).map(Option::unwrap);\n    //~^ option_filter_map\n\n    let _ = Some(1).map(odds_out).filter(|o| o.is_some()).map(|o| o.unwrap());\n    //~^ option_filter_map\n\n    let _ = vec![Some(1)].into_iter().filter(Option::is_some).map(Option::unwrap);\n    //~^ option_filter_map\n\n    let _ = vec![Some(1)].into_iter().filter(|o| o.is_some()).map(|o| o.unwrap());\n    //~^ option_filter_map\n\n    let _ = vec![1]\n        .into_iter()\n        .map(odds_out)\n        .filter(Option::is_some)\n        //~^ option_filter_map\n        .map(Option::unwrap);\n    let _ = vec![1]\n        .into_iter()\n        .map(odds_out)\n        .filter(|o| o.is_some())\n        //~^ option_filter_map\n        .map(|o| o.unwrap());\n}\n\nfn odds_out(x: i32) -> Option<i32> {\n    if x % 2 == 0 { Some(x) } else { None }\n}\n"
  },
  {
    "path": "tests/ui/option_filter_map.stderr",
    "content": "error: `filter` for `Some` followed by `unwrap`\n  --> tests/ui/option_filter_map.rs:5:27\n   |\nLL |     let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n   |\n   = note: `-D clippy::option-filter-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_filter_map)]`\n\nerror: `filter` for `Some` followed by `unwrap`\n  --> tests/ui/option_filter_map.rs:8:27\n   |\nLL |     let _ = Some(Some(1)).filter(|o| o.is_some()).map(|o| o.unwrap());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `Some` followed by `unwrap`\n  --> tests/ui/option_filter_map.rs:11:35\n   |\nLL |     let _ = Some(1).map(odds_out).filter(Option::is_some).map(Option::unwrap);\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `Some` followed by `unwrap`\n  --> tests/ui/option_filter_map.rs:14:35\n   |\nLL |     let _ = Some(1).map(odds_out).filter(|o| o.is_some()).map(|o| o.unwrap());\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `Some` followed by `unwrap`\n  --> tests/ui/option_filter_map.rs:17:39\n   |\nLL |     let _ = vec![Some(1)].into_iter().filter(Option::is_some).map(Option::unwrap);\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `Some` followed by `unwrap`\n  --> tests/ui/option_filter_map.rs:20:39\n   |\nLL |     let _ = vec![Some(1)].into_iter().filter(|o| o.is_some()).map(|o| o.unwrap());\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `Some` followed by `unwrap`\n  --> tests/ui/option_filter_map.rs:26:10\n   |\nLL |           .filter(Option::is_some)\n   |  __________^\nLL | |\nLL | |         .map(Option::unwrap);\n   | |____________________________^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `Some` followed by `unwrap`\n  --> tests/ui/option_filter_map.rs:32:10\n   |\nLL |           .filter(|o| o.is_some())\n   |  __________^\nLL | |\nLL | |         .map(|o| o.unwrap());\n   | |____________________________^ help: consider using `flatten` instead: `flatten()`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/option_if_let_else.fixed",
    "content": "#![warn(clippy::option_if_let_else)]\n#![allow(\n    clippy::ref_option_ref,\n    clippy::equatable_if_let,\n    clippy::let_unit_value,\n    clippy::redundant_locals,\n    clippy::manual_midpoint,\n    clippy::manual_unwrap_or_default,\n    clippy::manual_unwrap_or,\n    clippy::unnecessary_option_map_or_else\n)]\n\nfn bad1(string: Option<&str>) -> (bool, &str) {\n    string.map_or((false, \"hello\"), |x| (true, x))\n}\n\nfn else_if_option(string: Option<&str>) -> Option<(bool, &str)> {\n    if string.is_none() {\n        None\n    } else if let Some(x) = string {\n        Some((true, x))\n    } else {\n        Some((false, \"\"))\n    }\n}\n\nfn unop_bad(string: &Option<&str>, mut num: Option<i32>) {\n    let _ = string.map_or(0, |s| s.len());\n    //~^ option_if_let_else\n    let _ = num.as_ref().map_or(&0, |s| s);\n    //~^ option_if_let_else\n    let _ = num.as_mut().map_or(&0, |s| {\n        //~^ option_if_let_else\n        *s += 1;\n        s\n    });\n    let _ = num.as_ref().map_or(&0, |s| s);\n    //~^ option_if_let_else\n    let _ = num.map_or(0, |mut s| {\n        //~^ option_if_let_else\n        s += 1;\n        s\n    });\n    let _ = num.as_mut().map_or(&0, |s| {\n        //~^ option_if_let_else\n        *s += 1;\n        s\n    });\n}\n\nfn longer_body(arg: Option<u32>) -> u32 {\n    arg.map_or(13, |x| {\n        //~^ option_if_let_else\n        let y = x * x;\n        y * y\n    })\n}\n\nfn impure_else(arg: Option<i32>) {\n    let side_effect = || {\n        println!(\"return 1\");\n        1\n    };\n    let _ = arg.map_or_else(side_effect, |x| x);\n}\n\nfn test_map_or_else(arg: Option<u32>) {\n    let _ = arg.map_or_else(|| {\n        let mut y = 1;\n        y = (y + 2 / y) / 2;\n        y = (y + 2 / y) / 2;\n        y\n    }, |x| x * x * x * x);\n}\n\nfn negative_tests(arg: Option<u32>) -> u32 {\n    let _ = if let Some(13) = arg { \"unlucky\" } else { \"lucky\" };\n    for _ in 0..10 {\n        let _ = if let Some(x) = arg {\n            x\n        } else {\n            continue;\n        };\n    }\n    let _ = if let Some(x) = arg {\n        return x;\n    } else {\n        5\n    };\n    7\n}\n\n// #7973\nfn pattern_to_vec(pattern: &str) -> Vec<String> {\n    pattern\n        .trim_matches('/')\n        .split('/')\n        .flat_map(|s| {\n            s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])\n        })\n        .collect::<Vec<_>>()\n}\n\n// #10335\nfn test_result_impure_else(variable: Result<u32, &str>) -> bool {\n    variable.map_or_else(|_| {\n        println!(\"Err\");\n        false\n    }, |binding| {\n        //~^ option_if_let_else\n        println!(\"Ok {binding}\");\n        true\n    })\n}\n\nenum DummyEnum {\n    One(u8),\n    Two,\n}\n\n// should not warn since there is a complex subpat\n// see #7991\nfn complex_subpat() -> DummyEnum {\n    let x = Some(DummyEnum::One(1));\n    let _ = if let Some(_one @ DummyEnum::One(..)) = x { 1 } else { 2 };\n    DummyEnum::Two\n}\n\n// #10335\npub fn test_result_err_ignored_1(r: Result<&[u8], &[u8]>) -> Vec<u8> {\n    r.map_or_else(|_| Vec::new(), |s| s.to_owned())\n}\n\n// #10335\npub fn test_result_err_ignored_2(r: Result<&[u8], &[u8]>) -> Vec<u8> {\n    r.map_or_else(|_| Vec::new(), |s| s.to_owned())\n}\n\nfn main() {\n    let optional = Some(5);\n    let _ = optional.map_or(5, |x| x + 2);\n    //~^ option_if_let_else\n    let _ = bad1(None);\n    let _ = else_if_option(None);\n    unop_bad(&None, None);\n    let _ = longer_body(None);\n    test_map_or_else(None);\n    test_result_impure_else(Ok(42));\n    let _ = negative_tests(None);\n    let _ = impure_else(None);\n\n    let _ = Some(0).map_or(0, |x| loop {\n            if x == 0 {\n                break x;\n            }\n        });\n\n    // #7576\n    const fn _f(x: Option<u32>) -> u32 {\n        // Don't lint, `map_or` isn't const\n        if let Some(x) = x { x } else { 10 }\n    }\n\n    // #5822\n    let s = String::new();\n    // Don't lint, `Some` branch consumes `s`, but else branch uses `s`\n    let _ = if let Some(x) = Some(0) {\n        let s = s;\n        s.len() + x\n    } else {\n        s.len()\n    };\n\n    let s = String::new();\n    // Lint, both branches immutably borrow `s`.\n    let _ = Some(0).map_or(s.len(), |x| s.len() + x);\n    //~^ option_if_let_else\n\n    let s = String::new();\n    // Lint, `Some` branch consumes `s`, but else branch doesn't use `s`.\n    let _ = Some(0).map_or(1, |x| {\n        //~^ option_if_let_else\n        let s = s;\n        s.len() + x\n    });\n\n    let s = Some(String::new());\n    // Don't lint, `Some` branch borrows `s`, but else branch consumes `s`\n    let _ = if let Some(x) = &s {\n        x.len()\n    } else {\n        let _s = s;\n        10\n    };\n\n    let mut s = Some(String::new());\n    // Don't lint, `Some` branch mutably borrows `s`, but else branch also borrows  `s`\n    let _ = if let Some(x) = &mut s {\n        x.push_str(\"test\");\n        x.len()\n    } else {\n        let _s = &s;\n        10\n    };\n\n    async fn _f1(x: u32) -> u32 {\n        x\n    }\n\n    async fn _f2() {\n        // Don't lint. `await` can't be moved into a closure.\n        let _ = if let Some(x) = Some(0) { _f1(x).await } else { 0 };\n    }\n\n    let _ = pattern_to_vec(\"hello world\");\n    let _ = complex_subpat();\n\n    // issue #8492\n    let _ = s.map_or(1, |string| string.len());\n    let _ = Some(10).map_or(5, |a| a + 1);\n\n    let res: Result<i32, i32> = Ok(5);\n    let _ = res.map_or(1, |a| a + 1);\n    let _ = res.map_or(1, |a| a + 1);\n    let _ = res.map_or(5, |a| a + 1);\n    //~^ option_if_let_else\n}\n\n#[allow(dead_code)]\nfn issue9742() -> Option<&'static str> {\n    // should not lint because of guards\n    match Some(\"foo  \") {\n        Some(name) if name.starts_with(\"foo\") => Some(name.trim()),\n        _ => None,\n    }\n}\n\nmod issue10729 {\n    #![allow(clippy::unit_arg, dead_code)]\n\n    pub fn reproduce(initial: &Option<String>) {\n        // 👇 needs `.as_ref()` because initial is an `&Option<_>`\n        let _ = initial.as_ref().map_or(42, |value| do_something(value));\n    }\n\n    pub fn reproduce2(initial: &mut Option<String>) {\n        let _ = initial.as_mut().map_or(42, |value| do_something2(value));\n    }\n\n    fn do_something(_value: &str) -> u32 {\n        todo!()\n    }\n    fn do_something2(_value: &mut str) -> u32 {\n        todo!()\n    }\n}\n\nfn issue11429() {\n    use std::collections::HashMap;\n\n    macro_rules! new_map {\n        () => {{ HashMap::new() }};\n    }\n\n    let opt: Option<HashMap<u8, u8>> = None;\n\n    let mut _hashmap = opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone());\n\n    let mut _hm = opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone());\n    //~^ option_if_let_else\n}\n\nfn issue11893() {\n    use std::io::Write;\n    let mut output = std::io::stdout().lock();\n    if let Some(name) = Some(\"stuff\") {\n        writeln!(output, \"{name:?}\").unwrap();\n    } else {\n        panic!(\"Haven't thought about this condition.\");\n    }\n}\n\nmod issue13964 {\n    #[derive(Debug)]\n    struct A(Option<String>);\n\n    fn foo(a: A) {\n        let _ = match a.0 {\n            Some(x) => x,\n            None => panic!(\"{a:?} is invalid.\"),\n        };\n    }\n\n    fn bar(a: A) {\n        let _ = if let Some(x) = a.0 {\n            x\n        } else {\n            panic!(\"{a:?} is invalid.\")\n        };\n    }\n}\n\nmod issue11059 {\n    use std::fmt::Debug;\n\n    fn box_coercion_unsize(o: Option<i32>) -> Box<dyn Debug> {\n        if let Some(o) = o { Box::new(o) } else { Box::new(\"foo\") }\n    }\n\n    static S: String = String::new();\n\n    fn deref_with_overload(o: Option<&str>) -> &str {\n        if let Some(o) = o { o } else { &S }\n    }\n}\n\nfn issue15379() {\n    let opt = Some(0usize);\n    let opt_raw_ptr = &opt as *const Option<usize>;\n    let _ = unsafe { (*opt_raw_ptr).map_or(1, |o| o) };\n    //~^ option_if_let_else\n}\n\nfn issue15002() {\n    let res: Result<String, ()> = Ok(\"_\".to_string());\n    let _ = res.map_or_else(|_| String::new(), |s| s.clone());\n}\n"
  },
  {
    "path": "tests/ui/option_if_let_else.rs",
    "content": "#![warn(clippy::option_if_let_else)]\n#![allow(\n    clippy::ref_option_ref,\n    clippy::equatable_if_let,\n    clippy::let_unit_value,\n    clippy::redundant_locals,\n    clippy::manual_midpoint,\n    clippy::manual_unwrap_or_default,\n    clippy::manual_unwrap_or,\n    clippy::unnecessary_option_map_or_else\n)]\n\nfn bad1(string: Option<&str>) -> (bool, &str) {\n    if let Some(x) = string {\n        //~^ option_if_let_else\n        (true, x)\n    } else {\n        (false, \"hello\")\n    }\n}\n\nfn else_if_option(string: Option<&str>) -> Option<(bool, &str)> {\n    if string.is_none() {\n        None\n    } else if let Some(x) = string {\n        Some((true, x))\n    } else {\n        Some((false, \"\"))\n    }\n}\n\nfn unop_bad(string: &Option<&str>, mut num: Option<i32>) {\n    let _ = if let Some(s) = *string { s.len() } else { 0 };\n    //~^ option_if_let_else\n    let _ = if let Some(s) = &num { s } else { &0 };\n    //~^ option_if_let_else\n    let _ = if let Some(s) = &mut num {\n        //~^ option_if_let_else\n        *s += 1;\n        s\n    } else {\n        &0\n    };\n    let _ = if let Some(ref s) = num { s } else { &0 };\n    //~^ option_if_let_else\n    let _ = if let Some(mut s) = num {\n        //~^ option_if_let_else\n        s += 1;\n        s\n    } else {\n        0\n    };\n    let _ = if let Some(ref mut s) = num {\n        //~^ option_if_let_else\n        *s += 1;\n        s\n    } else {\n        &0\n    };\n}\n\nfn longer_body(arg: Option<u32>) -> u32 {\n    if let Some(x) = arg {\n        //~^ option_if_let_else\n        let y = x * x;\n        y * y\n    } else {\n        13\n    }\n}\n\nfn impure_else(arg: Option<i32>) {\n    let side_effect = || {\n        println!(\"return 1\");\n        1\n    };\n    let _ = if let Some(x) = arg {\n        //~^ option_if_let_else\n        x\n    } else {\n        // map_or_else must be suggested\n        side_effect()\n    };\n}\n\nfn test_map_or_else(arg: Option<u32>) {\n    let _ = if let Some(x) = arg {\n        //~^ option_if_let_else\n        x * x * x * x\n    } else {\n        let mut y = 1;\n        y = (y + 2 / y) / 2;\n        y = (y + 2 / y) / 2;\n        y\n    };\n}\n\nfn negative_tests(arg: Option<u32>) -> u32 {\n    let _ = if let Some(13) = arg { \"unlucky\" } else { \"lucky\" };\n    for _ in 0..10 {\n        let _ = if let Some(x) = arg {\n            x\n        } else {\n            continue;\n        };\n    }\n    let _ = if let Some(x) = arg {\n        return x;\n    } else {\n        5\n    };\n    7\n}\n\n// #7973\nfn pattern_to_vec(pattern: &str) -> Vec<String> {\n    pattern\n        .trim_matches('/')\n        .split('/')\n        .flat_map(|s| {\n            if let Some(idx) = s.find('.') {\n                //~^ option_if_let_else\n                vec![s[..idx].to_string(), s[idx..].to_string()]\n            } else {\n                vec![s.to_string()]\n            }\n        })\n        .collect::<Vec<_>>()\n}\n\n// #10335\nfn test_result_impure_else(variable: Result<u32, &str>) -> bool {\n    if let Ok(binding) = variable {\n        //~^ option_if_let_else\n        println!(\"Ok {binding}\");\n        true\n    } else {\n        println!(\"Err\");\n        false\n    }\n}\n\nenum DummyEnum {\n    One(u8),\n    Two,\n}\n\n// should not warn since there is a complex subpat\n// see #7991\nfn complex_subpat() -> DummyEnum {\n    let x = Some(DummyEnum::One(1));\n    let _ = if let Some(_one @ DummyEnum::One(..)) = x { 1 } else { 2 };\n    DummyEnum::Two\n}\n\n// #10335\npub fn test_result_err_ignored_1(r: Result<&[u8], &[u8]>) -> Vec<u8> {\n    match r {\n        //~^ option_if_let_else\n        Ok(s) => s.to_owned(),\n        Err(_) => Vec::new(),\n    }\n}\n\n// #10335\npub fn test_result_err_ignored_2(r: Result<&[u8], &[u8]>) -> Vec<u8> {\n    if let Ok(s) = r { s.to_owned() }\n    //~^ option_if_let_else\n    else { Vec::new() }\n}\n\nfn main() {\n    let optional = Some(5);\n    let _ = if let Some(x) = optional { x + 2 } else { 5 };\n    //~^ option_if_let_else\n    let _ = bad1(None);\n    let _ = else_if_option(None);\n    unop_bad(&None, None);\n    let _ = longer_body(None);\n    test_map_or_else(None);\n    test_result_impure_else(Ok(42));\n    let _ = negative_tests(None);\n    let _ = impure_else(None);\n\n    let _ = if let Some(x) = Some(0) {\n        //~^ option_if_let_else\n        loop {\n            if x == 0 {\n                break x;\n            }\n        }\n    } else {\n        0\n    };\n\n    // #7576\n    const fn _f(x: Option<u32>) -> u32 {\n        // Don't lint, `map_or` isn't const\n        if let Some(x) = x { x } else { 10 }\n    }\n\n    // #5822\n    let s = String::new();\n    // Don't lint, `Some` branch consumes `s`, but else branch uses `s`\n    let _ = if let Some(x) = Some(0) {\n        let s = s;\n        s.len() + x\n    } else {\n        s.len()\n    };\n\n    let s = String::new();\n    // Lint, both branches immutably borrow `s`.\n    let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };\n    //~^ option_if_let_else\n\n    let s = String::new();\n    // Lint, `Some` branch consumes `s`, but else branch doesn't use `s`.\n    let _ = if let Some(x) = Some(0) {\n        //~^ option_if_let_else\n        let s = s;\n        s.len() + x\n    } else {\n        1\n    };\n\n    let s = Some(String::new());\n    // Don't lint, `Some` branch borrows `s`, but else branch consumes `s`\n    let _ = if let Some(x) = &s {\n        x.len()\n    } else {\n        let _s = s;\n        10\n    };\n\n    let mut s = Some(String::new());\n    // Don't lint, `Some` branch mutably borrows `s`, but else branch also borrows  `s`\n    let _ = if let Some(x) = &mut s {\n        x.push_str(\"test\");\n        x.len()\n    } else {\n        let _s = &s;\n        10\n    };\n\n    async fn _f1(x: u32) -> u32 {\n        x\n    }\n\n    async fn _f2() {\n        // Don't lint. `await` can't be moved into a closure.\n        let _ = if let Some(x) = Some(0) { _f1(x).await } else { 0 };\n    }\n\n    let _ = pattern_to_vec(\"hello world\");\n    let _ = complex_subpat();\n\n    // issue #8492\n    let _ = match s {\n        //~^ option_if_let_else\n        Some(string) => string.len(),\n        None => 1,\n    };\n    let _ = match Some(10) {\n        //~^ option_if_let_else\n        Some(a) => a + 1,\n        None => 5,\n    };\n\n    let res: Result<i32, i32> = Ok(5);\n    let _ = match res {\n        //~^ option_if_let_else\n        Ok(a) => a + 1,\n        _ => 1,\n    };\n    let _ = match res {\n        //~^ option_if_let_else\n        Err(_) => 1,\n        Ok(a) => a + 1,\n    };\n    let _ = if let Ok(a) = res { a + 1 } else { 5 };\n    //~^ option_if_let_else\n}\n\n#[allow(dead_code)]\nfn issue9742() -> Option<&'static str> {\n    // should not lint because of guards\n    match Some(\"foo  \") {\n        Some(name) if name.starts_with(\"foo\") => Some(name.trim()),\n        _ => None,\n    }\n}\n\nmod issue10729 {\n    #![allow(clippy::unit_arg, dead_code)]\n\n    pub fn reproduce(initial: &Option<String>) {\n        // 👇 needs `.as_ref()` because initial is an `&Option<_>`\n        let _ = match initial {\n            //~^ option_if_let_else\n            Some(value) => do_something(value),\n            None => 42,\n        };\n    }\n\n    pub fn reproduce2(initial: &mut Option<String>) {\n        let _ = match initial {\n            //~^ option_if_let_else\n            Some(value) => do_something2(value),\n            None => 42,\n        };\n    }\n\n    fn do_something(_value: &str) -> u32 {\n        todo!()\n    }\n    fn do_something2(_value: &mut str) -> u32 {\n        todo!()\n    }\n}\n\nfn issue11429() {\n    use std::collections::HashMap;\n\n    macro_rules! new_map {\n        () => {{ HashMap::new() }};\n    }\n\n    let opt: Option<HashMap<u8, u8>> = None;\n\n    let mut _hashmap = if let Some(hm) = &opt {\n        //~^ option_if_let_else\n        hm.clone()\n    } else {\n        HashMap::new()\n    };\n\n    let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() };\n    //~^ option_if_let_else\n}\n\nfn issue11893() {\n    use std::io::Write;\n    let mut output = std::io::stdout().lock();\n    if let Some(name) = Some(\"stuff\") {\n        writeln!(output, \"{name:?}\").unwrap();\n    } else {\n        panic!(\"Haven't thought about this condition.\");\n    }\n}\n\nmod issue13964 {\n    #[derive(Debug)]\n    struct A(Option<String>);\n\n    fn foo(a: A) {\n        let _ = match a.0 {\n            Some(x) => x,\n            None => panic!(\"{a:?} is invalid.\"),\n        };\n    }\n\n    fn bar(a: A) {\n        let _ = if let Some(x) = a.0 {\n            x\n        } else {\n            panic!(\"{a:?} is invalid.\")\n        };\n    }\n}\n\nmod issue11059 {\n    use std::fmt::Debug;\n\n    fn box_coercion_unsize(o: Option<i32>) -> Box<dyn Debug> {\n        if let Some(o) = o { Box::new(o) } else { Box::new(\"foo\") }\n    }\n\n    static S: String = String::new();\n\n    fn deref_with_overload(o: Option<&str>) -> &str {\n        if let Some(o) = o { o } else { &S }\n    }\n}\n\nfn issue15379() {\n    let opt = Some(0usize);\n    let opt_raw_ptr = &opt as *const Option<usize>;\n    let _ = unsafe { if let Some(o) = *opt_raw_ptr { o } else { 1 } };\n    //~^ option_if_let_else\n}\n\nfn issue15002() {\n    let res: Result<String, ()> = Ok(\"_\".to_string());\n    let _ = match res {\n        //~^ option_if_let_else\n        Ok(s) => s.clone(),\n        Err(_) => String::new(),\n    };\n}\n"
  },
  {
    "path": "tests/ui/option_if_let_else.stderr",
    "content": "error: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:14:5\n   |\nLL | /     if let Some(x) = string {\nLL | |\nLL | |         (true, x)\nLL | |     } else {\nLL | |         (false, \"hello\")\nLL | |     }\n   | |_____^ help: try: `string.map_or((false, \"hello\"), |x| (true, x))`\n   |\n   = note: `-D clippy::option-if-let-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_if_let_else)]`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:33:13\n   |\nLL |     let _ = if let Some(s) = *string { s.len() } else { 0 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:35:13\n   |\nLL |     let _ = if let Some(s) = &num { s } else { &0 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:37:13\n   |\nLL |       let _ = if let Some(s) = &mut num {\n   |  _____________^\nLL | |\nLL | |         *s += 1;\nLL | |         s\nLL | |     } else {\nLL | |         &0\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = num.as_mut().map_or(&0, |s| {\nLL +\nLL +         *s += 1;\nLL +         s\nLL ~     });\n   |\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:44:13\n   |\nLL |     let _ = if let Some(ref s) = num { s } else { &0 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:46:13\n   |\nLL |       let _ = if let Some(mut s) = num {\n   |  _____________^\nLL | |\nLL | |         s += 1;\nLL | |         s\nLL | |     } else {\nLL | |         0\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = num.map_or(0, |mut s| {\nLL +\nLL +         s += 1;\nLL +         s\nLL ~     });\n   |\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:53:13\n   |\nLL |       let _ = if let Some(ref mut s) = num {\n   |  _____________^\nLL | |\nLL | |         *s += 1;\nLL | |         s\nLL | |     } else {\nLL | |         &0\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = num.as_mut().map_or(&0, |s| {\nLL +\nLL +         *s += 1;\nLL +         s\nLL ~     });\n   |\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:63:5\n   |\nLL | /     if let Some(x) = arg {\nLL | |\nLL | |         let y = x * x;\nLL | |         y * y\nLL | |     } else {\nLL | |         13\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     arg.map_or(13, |x| {\nLL +\nLL +         let y = x * x;\nLL +         y * y\nLL +     })\n   |\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:77:13\n   |\nLL |       let _ = if let Some(x) = arg {\n   |  _____________^\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         // map_or_else must be suggested\nLL | |         side_effect()\nLL | |     };\n   | |_____^ help: try: `arg.map_or_else(side_effect, |x| x)`\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:87:13\n   |\nLL |       let _ = if let Some(x) = arg {\n   |  _____________^\nLL | |\nLL | |         x * x * x * x\nLL | |     } else {\n...  |\nLL | |         y\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = arg.map_or_else(|| {\nLL +         let mut y = 1;\nLL +         y = (y + 2 / y) / 2;\nLL +         y = (y + 2 / y) / 2;\nLL +         y\nLL ~     }, |x| x * x * x * x);\n   |\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:121:13\n   |\nLL | /             if let Some(idx) = s.find('.') {\nLL | |\nLL | |                 vec![s[..idx].to_string(), s[idx..].to_string()]\nLL | |             } else {\nLL | |                 vec![s.to_string()]\nLL | |             }\n   | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:133:5\n   |\nLL | /     if let Ok(binding) = variable {\nLL | |\nLL | |         println!(\"Ok {binding}\");\nLL | |         true\n...  |\nLL | |         false\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     variable.map_or_else(|_| {\nLL +         println!(\"Err\");\nLL +         false\nLL +     }, |binding| {\nLL +\nLL +         println!(\"Ok {binding}\");\nLL +         true\nLL +     })\n   |\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:158:5\n   |\nLL | /     match r {\nLL | |\nLL | |         Ok(s) => s.to_owned(),\nLL | |         Err(_) => Vec::new(),\nLL | |     }\n   | |_____^ help: try: `r.map_or_else(|_| Vec::new(), |s| s.to_owned())`\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:167:5\n   |\nLL | /     if let Ok(s) = r { s.to_owned() }\nLL | |\nLL | |     else { Vec::new() }\n   | |_______________________^ help: try: `r.map_or_else(|_| Vec::new(), |s| s.to_owned())`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:174:13\n   |\nLL |     let _ = if let Some(x) = optional { x + 2 } else { 5 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:185:13\n   |\nLL |       let _ = if let Some(x) = Some(0) {\n   |  _____________^\nLL | |\nLL | |         loop {\nLL | |             if x == 0 {\n...  |\nLL | |         0\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = Some(0).map_or(0, |x| loop {\nLL +             if x == 0 {\nLL +                 break x;\nLL +             }\nLL ~         });\n   |\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:214:13\n   |\nLL |     let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:219:13\n   |\nLL |       let _ = if let Some(x) = Some(0) {\n   |  _____________^\nLL | |\nLL | |         let s = s;\nLL | |         s.len() + x\nLL | |     } else {\nLL | |         1\nLL | |     };\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     let _ = Some(0).map_or(1, |x| {\nLL +\nLL +         let s = s;\nLL +         s.len() + x\nLL ~     });\n   |\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:259:13\n   |\nLL |       let _ = match s {\n   |  _____________^\nLL | |\nLL | |         Some(string) => string.len(),\nLL | |         None => 1,\nLL | |     };\n   | |_____^ help: try: `s.map_or(1, |string| string.len())`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:264:13\n   |\nLL |       let _ = match Some(10) {\n   |  _____________^\nLL | |\nLL | |         Some(a) => a + 1,\nLL | |         None => 5,\nLL | |     };\n   | |_____^ help: try: `Some(10).map_or(5, |a| a + 1)`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:271:13\n   |\nLL |       let _ = match res {\n   |  _____________^\nLL | |\nLL | |         Ok(a) => a + 1,\nLL | |         _ => 1,\nLL | |     };\n   | |_____^ help: try: `res.map_or(1, |a| a + 1)`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:276:13\n   |\nLL |       let _ = match res {\n   |  _____________^\nLL | |\nLL | |         Err(_) => 1,\nLL | |         Ok(a) => a + 1,\nLL | |     };\n   | |_____^ help: try: `res.map_or(1, |a| a + 1)`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:281:13\n   |\nLL |     let _ = if let Ok(a) = res { a + 1 } else { 5 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:299:17\n   |\nLL |           let _ = match initial {\n   |  _________________^\nLL | |\nLL | |             Some(value) => do_something(value),\nLL | |             None => 42,\nLL | |         };\n   | |_________^ help: try: `initial.as_ref().map_or(42, |value| do_something(value))`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:307:17\n   |\nLL |           let _ = match initial {\n   |  _________________^\nLL | |\nLL | |             Some(value) => do_something2(value),\nLL | |             None => 42,\nLL | |         };\n   | |_________^ help: try: `initial.as_mut().map_or(42, |value| do_something2(value))`\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:331:24\n   |\nLL |       let mut _hashmap = if let Some(hm) = &opt {\n   |  ________________________^\nLL | |\nLL | |         hm.clone()\nLL | |     } else {\nLL | |         HashMap::new()\nLL | |     };\n   | |_____^ help: try: `opt.as_ref().map_or_else(HashMap::new, |hm| hm.clone())`\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:338:19\n   |\nLL |     let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() };\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())`\n\nerror: use Option::map_or instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:389:22\n   |\nLL |     let _ = unsafe { if let Some(o) = *opt_raw_ptr { o } else { 1 } };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*opt_raw_ptr).map_or(1, |o| o)`\n\nerror: use Option::map_or_else instead of an if let/else\n  --> tests/ui/option_if_let_else.rs:395:13\n   |\nLL |       let _ = match res {\n   |  _____________^\nLL | |\nLL | |         Ok(s) => s.clone(),\nLL | |         Err(_) => String::new(),\nLL | |     };\n   | |_____^ help: try: `res.map_or_else(|_| String::new(), |s| s.clone())`\n\nerror: aborting due to 29 previous errors\n\n"
  },
  {
    "path": "tests/ui/option_map_or_none.fixed",
    "content": "#![allow(clippy::bind_instead_of_map)]\n\nfn main() {\n    let opt = Some(1);\n    let r: Result<i32, i32> = Ok(1);\n    let bar = |_| Some(1);\n\n    // Check `OPTION_MAP_OR_NONE`.\n    // Single line case.\n    let _: Option<i32> = opt.map(|x| x + 1);\n    //~^ option_map_or_none\n    // Multi-line case.\n    #[rustfmt::skip]\n    let _: Option<i32> = opt.map(|x| x + 1);\n    // function returning `Option`\n    let _: Option<i32> = opt.and_then(bar);\n    //~^ option_map_or_none\n    let _: Option<i32> = opt.and_then(|x| {\n        //~^ option_map_or_none\n        let offset = 0;\n        let height = x;\n        Some(offset + height)\n    });\n\n    // Check `RESULT_MAP_OR_INTO_OPTION`.\n    let _: Option<i32> = r.ok();\n    //~^ result_map_or_into_option\n}\n"
  },
  {
    "path": "tests/ui/option_map_or_none.rs",
    "content": "#![allow(clippy::bind_instead_of_map)]\n\nfn main() {\n    let opt = Some(1);\n    let r: Result<i32, i32> = Ok(1);\n    let bar = |_| Some(1);\n\n    // Check `OPTION_MAP_OR_NONE`.\n    // Single line case.\n    let _: Option<i32> = opt.map_or(None, |x| Some(x + 1));\n    //~^ option_map_or_none\n    // Multi-line case.\n    #[rustfmt::skip]\n    let _: Option<i32> = opt.map_or(None, |x| {\n    //~^ option_map_or_none\n                        Some(x + 1)\n                       });\n    // function returning `Option`\n    let _: Option<i32> = opt.map_or(None, bar);\n    //~^ option_map_or_none\n    let _: Option<i32> = opt.map_or(None, |x| {\n        //~^ option_map_or_none\n        let offset = 0;\n        let height = x;\n        Some(offset + height)\n    });\n\n    // Check `RESULT_MAP_OR_INTO_OPTION`.\n    let _: Option<i32> = r.map_or(None, Some);\n    //~^ result_map_or_into_option\n}\n"
  },
  {
    "path": "tests/ui/option_map_or_none.stderr",
    "content": "error: called `map_or(None, ..)` on an `Option` value\n  --> tests/ui/option_map_or_none.rs:10:26\n   |\nLL |     let _: Option<i32> = opt.map_or(None, |x| Some(x + 1));\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `map`: `opt.map(|x| x + 1)`\n   |\n   = note: `-D clippy::option-map-or-none` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_map_or_none)]`\n\nerror: called `map_or(None, ..)` on an `Option` value\n  --> tests/ui/option_map_or_none.rs:14:26\n   |\nLL |       let _: Option<i32> = opt.map_or(None, |x| {\n   |  __________________________^\nLL | |\nLL | |                         Some(x + 1)\nLL | |                        });\n   | |_________________________^ help: consider using `map`: `opt.map(|x| x + 1)`\n\nerror: called `map_or(None, ..)` on an `Option` value\n  --> tests/ui/option_map_or_none.rs:19:26\n   |\nLL |     let _: Option<i32> = opt.map_or(None, bar);\n   |                          ^^^^^^^^^^^^^^^^^^^^^ help: consider using `and_then`: `opt.and_then(bar)`\n\nerror: called `map_or(None, ..)` on an `Option` value\n  --> tests/ui/option_map_or_none.rs:21:26\n   |\nLL |       let _: Option<i32> = opt.map_or(None, |x| {\n   |  __________________________^\nLL | |\nLL | |         let offset = 0;\nLL | |         let height = x;\nLL | |         Some(offset + height)\nLL | |     });\n   | |______^\n   |\nhelp: consider using `and_then`\n   |\nLL ~     let _: Option<i32> = opt.and_then(|x| {\nLL +\nLL +         let offset = 0;\nLL +         let height = x;\nLL +         Some(offset + height)\nLL ~     });\n   |\n\nerror: called `map_or(None, Some)` on a `Result` value\n  --> tests/ui/option_map_or_none.rs:29:26\n   |\nLL |     let _: Option<i32> = r.map_or(None, Some);\n   |                          ^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `r.ok()`\n   |\n   = note: `-D clippy::result-map-or-into-option` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/option_map_unit_fn_fixable.fixed",
    "content": "#![warn(clippy::option_map_unit_fn)]\n#![expect(clippy::unnecessary_wraps)]\n\nfn do_nothing<T>(_: T) {}\n\nfn diverge<T>(_: T) -> ! {\n    panic!()\n}\n\nfn plus_one(value: usize) -> usize {\n    value + 1\n}\n\nfn option() -> Option<usize> {\n    Some(10)\n}\n\nstruct HasOption {\n    field: Option<usize>,\n}\n\nimpl HasOption {\n    fn do_option_nothing(&self, value: usize) {}\n\n    fn do_option_plus_one(&self, value: usize) -> usize {\n        value + 1\n    }\n}\n#[rustfmt::skip]\nfn option_map_unit_fn() {\n    let x = HasOption { field: Some(10) };\n\n    x.field.map(plus_one);\n    let _ : Option<()> = x.field.map(do_nothing);\n\n    if let Some(x_field) = x.field { do_nothing(x_field) }\n    //~^ option_map_unit_fn\n\n    if let Some(x_field) = x.field { do_nothing(x_field) }\n    //~^ option_map_unit_fn\n\n    if let Some(x_field) = x.field { diverge(x_field) }\n    //~^ option_map_unit_fn\n\n    let captured = 10;\n    if let Some(value) = x.field { do_nothing(value + captured) };\n    let _ : Option<()> = x.field.map(|value| do_nothing(value + captured));\n\n    if let Some(value) = x.field { x.do_option_nothing(value + captured) }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { x.do_option_plus_one(value + captured); }\n    //~^ option_map_unit_fn\n\n\n    if let Some(value) = x.field { do_nothing(value + captured) }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { do_nothing(value + captured) }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { do_nothing(value + captured); }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { do_nothing(value + captured); }\n    //~^ option_map_unit_fn\n\n\n    if let Some(value) = x.field { diverge(value + captured) }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { diverge(value + captured) }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { diverge(value + captured); }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { diverge(value + captured); }\n    //~^ option_map_unit_fn\n\n\n    x.field.map(|value| plus_one(value + captured));\n    x.field.map(|value| { plus_one(value + captured) });\n    if let Some(value) = x.field { let y = plus_one(value + captured); }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { plus_one(value + captured); }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = x.field { plus_one(value + captured); }\n    //~^ option_map_unit_fn\n\n\n    if let Some(ref value) = x.field { do_nothing(value + captured) }\n    //~^ option_map_unit_fn\n\n    if let Some(a) = option() { do_nothing(a) }\n    //~^ option_map_unit_fn\n\n    if let Some(value) = option() { println!(\"{value:?}\") }\n    //~^ option_map_unit_fn\n}\n\nfn issue15568() {\n    unsafe fn f(_: u32) {}\n    let x = Some(3);\n    if let Some(x) = x { unsafe { f(x) } }\n    //~^ option_map_unit_fn\n    if let Some(x) = x { unsafe { f(x) } }\n    //~^ option_map_unit_fn\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/option_map_unit_fn_fixable.rs",
    "content": "#![warn(clippy::option_map_unit_fn)]\n#![expect(clippy::unnecessary_wraps)]\n\nfn do_nothing<T>(_: T) {}\n\nfn diverge<T>(_: T) -> ! {\n    panic!()\n}\n\nfn plus_one(value: usize) -> usize {\n    value + 1\n}\n\nfn option() -> Option<usize> {\n    Some(10)\n}\n\nstruct HasOption {\n    field: Option<usize>,\n}\n\nimpl HasOption {\n    fn do_option_nothing(&self, value: usize) {}\n\n    fn do_option_plus_one(&self, value: usize) -> usize {\n        value + 1\n    }\n}\n#[rustfmt::skip]\nfn option_map_unit_fn() {\n    let x = HasOption { field: Some(10) };\n\n    x.field.map(plus_one);\n    let _ : Option<()> = x.field.map(do_nothing);\n\n    x.field.map(do_nothing);\n    //~^ option_map_unit_fn\n\n    x.field.map(do_nothing);\n    //~^ option_map_unit_fn\n\n    x.field.map(diverge);\n    //~^ option_map_unit_fn\n\n    let captured = 10;\n    if let Some(value) = x.field { do_nothing(value + captured) };\n    let _ : Option<()> = x.field.map(|value| do_nothing(value + captured));\n\n    x.field.map(|value| x.do_option_nothing(value + captured));\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { x.do_option_plus_one(value + captured); });\n    //~^ option_map_unit_fn\n\n\n    x.field.map(|value| do_nothing(value + captured));\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { do_nothing(value + captured) });\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { do_nothing(value + captured); });\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { { do_nothing(value + captured); } });\n    //~^ option_map_unit_fn\n\n\n    x.field.map(|value| diverge(value + captured));\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { diverge(value + captured) });\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { diverge(value + captured); });\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { { diverge(value + captured); } });\n    //~^ option_map_unit_fn\n\n\n    x.field.map(|value| plus_one(value + captured));\n    x.field.map(|value| { plus_one(value + captured) });\n    x.field.map(|value| { let y = plus_one(value + captured); });\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { plus_one(value + captured); });\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| { { plus_one(value + captured); } });\n    //~^ option_map_unit_fn\n\n\n    x.field.map(|ref value| { do_nothing(value + captured) });\n    //~^ option_map_unit_fn\n\n    option().map(do_nothing);\n    //~^ option_map_unit_fn\n\n    option().map(|value| println!(\"{value:?}\"));\n    //~^ option_map_unit_fn\n}\n\nfn issue15568() {\n    unsafe fn f(_: u32) {}\n    let x = Some(3);\n    x.map(|x| unsafe { f(x) });\n    //~^ option_map_unit_fn\n    x.map(|x| unsafe { { f(x) } });\n    //~^ option_map_unit_fn\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/option_map_unit_fn_fixable.stderr",
    "content": "error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:36:5\n   |\nLL |     x.field.map(do_nothing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::option-map-unit-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_map_unit_fn)]`\nhelp: use `if let` instead\n   |\nLL -     x.field.map(do_nothing);\nLL +     if let Some(x_field) = x.field { do_nothing(x_field) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:39:5\n   |\nLL |     x.field.map(do_nothing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(do_nothing);\nLL +     if let Some(x_field) = x.field { do_nothing(x_field) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:42:5\n   |\nLL |     x.field.map(diverge);\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(diverge);\nLL +     if let Some(x_field) = x.field { diverge(x_field) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:49:5\n   |\nLL |     x.field.map(|value| x.do_option_nothing(value + captured));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| x.do_option_nothing(value + captured));\nLL +     if let Some(value) = x.field { x.do_option_nothing(value + captured) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:52:5\n   |\nLL |     x.field.map(|value| { x.do_option_plus_one(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { x.do_option_plus_one(value + captured); });\nLL +     if let Some(value) = x.field { x.do_option_plus_one(value + captured); }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:56:5\n   |\nLL |     x.field.map(|value| do_nothing(value + captured));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| do_nothing(value + captured));\nLL +     if let Some(value) = x.field { do_nothing(value + captured) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:59:5\n   |\nLL |     x.field.map(|value| { do_nothing(value + captured) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { do_nothing(value + captured) });\nLL +     if let Some(value) = x.field { do_nothing(value + captured) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:62:5\n   |\nLL |     x.field.map(|value| { do_nothing(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { do_nothing(value + captured); });\nLL +     if let Some(value) = x.field { do_nothing(value + captured); }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:65:5\n   |\nLL |     x.field.map(|value| { { do_nothing(value + captured); } });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { { do_nothing(value + captured); } });\nLL +     if let Some(value) = x.field { do_nothing(value + captured); }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:69:5\n   |\nLL |     x.field.map(|value| diverge(value + captured));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| diverge(value + captured));\nLL +     if let Some(value) = x.field { diverge(value + captured) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:72:5\n   |\nLL |     x.field.map(|value| { diverge(value + captured) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { diverge(value + captured) });\nLL +     if let Some(value) = x.field { diverge(value + captured) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:75:5\n   |\nLL |     x.field.map(|value| { diverge(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { diverge(value + captured); });\nLL +     if let Some(value) = x.field { diverge(value + captured); }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:78:5\n   |\nLL |     x.field.map(|value| { { diverge(value + captured); } });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { { diverge(value + captured); } });\nLL +     if let Some(value) = x.field { diverge(value + captured); }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:84:5\n   |\nLL |     x.field.map(|value| { let y = plus_one(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { let y = plus_one(value + captured); });\nLL +     if let Some(value) = x.field { let y = plus_one(value + captured); }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:87:5\n   |\nLL |     x.field.map(|value| { plus_one(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { plus_one(value + captured); });\nLL +     if let Some(value) = x.field { plus_one(value + captured); }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:90:5\n   |\nLL |     x.field.map(|value| { { plus_one(value + captured); } });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { { plus_one(value + captured); } });\nLL +     if let Some(value) = x.field { plus_one(value + captured); }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:94:5\n   |\nLL |     x.field.map(|ref value| { do_nothing(value + captured) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|ref value| { do_nothing(value + captured) });\nLL +     if let Some(ref value) = x.field { do_nothing(value + captured) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:97:5\n   |\nLL |     option().map(do_nothing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     option().map(do_nothing);\nLL +     if let Some(a) = option() { do_nothing(a) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:100:5\n   |\nLL |     option().map(|value| println!(\"{value:?}\"));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     option().map(|value| println!(\"{value:?}\"));\nLL +     if let Some(value) = option() { println!(\"{value:?}\") }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:107:5\n   |\nLL |     x.map(|x| unsafe { f(x) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.map(|x| unsafe { f(x) });\nLL +     if let Some(x) = x { unsafe { f(x) } }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_fixable.rs:109:5\n   |\nLL |     x.map(|x| unsafe { { f(x) } });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.map(|x| unsafe { { f(x) } });\nLL +     if let Some(x) = x { unsafe { f(x) } }\n   |\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/option_map_unit_fn_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::option_map_unit_fn)]\n#![allow(clippy::unnecessary_wraps, clippy::unnecessary_map_on_constructor)] // only fires before the fix\n\nfn do_nothing<T>(_: T) {}\n\nfn diverge<T>(_: T) -> ! {\n    panic!()\n}\n\nfn plus_one(value: usize) -> usize {\n    value + 1\n}\n\nstruct HasOption {\n    field: Option<usize>,\n}\n\n#[rustfmt::skip]\nfn option_map_unit_fn() {\n    let x = HasOption { field: Some(10) };\n\n    x.field.map(|value| { do_nothing(value); do_nothing(value) });\n    //~^ option_map_unit_fn\n\n    x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });\n    //~^ option_map_unit_fn\n\n    // Suggestion for the let block should be `{ ... }` as it's too difficult to build a\n    // proper suggestion for these cases\n    x.field.map(|value| {\n        do_nothing(value);\n        do_nothing(value)\n    });\n    //~^^^^ option_map_unit_fn\n    x.field.map(|value| { do_nothing(value); do_nothing(value); });\n    //~^ option_map_unit_fn\n\n    // The following should suggest `if let Some(_X) ...` as it's difficult to generate a proper let variable name for them\n    Some(42).map(diverge);\n    //~^ option_map_unit_fn\n    \"12\".parse::<i32>().ok().map(diverge);\n    //~^ option_map_unit_fn\n    Some(plus_one(1)).map(do_nothing);\n    //~^ option_map_unit_fn\n\n    // Should suggest `if let Some(_y) ...` to not override the existing foo variable\n    let y = Some(42);\n    y.map(do_nothing);\n    //~^ option_map_unit_fn\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/option_map_unit_fn_unfixable.stderr",
    "content": "error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_unfixable.rs:23:5\n   |\nLL |     x.field.map(|value| { do_nothing(value); do_nothing(value) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::option-map-unit-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_map_unit_fn)]`\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { do_nothing(value); do_nothing(value) });\nLL +     if let Some(value) = x.field { ... }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_unfixable.rs:26:5\n   |\nLL |     x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });\nLL +     if let Some(value) = x.field { ... }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_unfixable.rs:31:5\n   |\nLL | /     x.field.map(|value| {\nLL | |         do_nothing(value);\nLL | |         do_nothing(value)\nLL | |     });\n   | |______^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| {\nLL -         do_nothing(value);\nLL -         do_nothing(value)\nLL -     });\nLL +     if let Some(value) = x.field { ... }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_unfixable.rs:36:5\n   |\nLL |     x.field.map(|value| { do_nothing(value); do_nothing(value); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { do_nothing(value); do_nothing(value); });\nLL +     if let Some(value) = x.field { ... }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_unfixable.rs:40:5\n   |\nLL |     Some(42).map(diverge);\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     Some(42).map(diverge);\nLL +     if let Some(a) = Some(42) { diverge(a) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_unfixable.rs:42:5\n   |\nLL |     \"12\".parse::<i32>().ok().map(diverge);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     \"12\".parse::<i32>().ok().map(diverge);\nLL +     if let Some(a) = \"12\".parse::<i32>().ok() { diverge(a) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_unfixable.rs:44:5\n   |\nLL |     Some(plus_one(1)).map(do_nothing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     Some(plus_one(1)).map(do_nothing);\nLL +     if let Some(a) = Some(plus_one(1)) { do_nothing(a) }\n   |\n\nerror: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/option_map_unit_fn_unfixable.rs:49:5\n   |\nLL |     y.map(do_nothing);\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     y.map(do_nothing);\nLL +     if let Some(_y) = y { do_nothing(_y) }\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/option_option.rs",
    "content": "#![warn(clippy::option_option)]\n#![expect(clippy::unnecessary_wraps)]\n\nconst C: Option<Option<i32>> = None;\n//~^ option_option\nstatic S: Option<Option<i32>> = None;\n//~^ option_option\n\nfn input(_: Option<Option<u8>>) {}\n//~^ option_option\n\nfn output() -> Option<Option<u8>> {\n    //~^ option_option\n    None\n}\n\nfn output_nested() -> Vec<Option<Option<u8>>> {\n    //~^ option_option\n    vec![None]\n}\n\n// The lint only generates one warning for this\nfn output_nested_nested() -> Option<Option<Option<u8>>> {\n    //~^ option_option\n    None\n}\n\nstruct Struct {\n    x: Option<Option<u8>>,\n    //~^ option_option\n}\n\nimpl Struct {\n    fn struct_fn() -> Option<Option<u8>> {\n        //~^ option_option\n        None\n    }\n}\n\ntrait Trait {\n    fn trait_fn() -> Option<Option<u8>>;\n    //~^ option_option\n}\n\nenum Enum {\n    Tuple(Option<Option<u8>>),\n    //~^ option_option\n    Struct { x: Option<Option<u8>> },\n    //~^ option_option\n}\n\n// The lint allows this\ntype OptionOption = Option<Option<u32>>;\n\n// The lint allows this\nfn output_type_alias() -> OptionOption {\n    None\n}\n\n// The line allows this\nimpl Trait for Struct {\n    fn trait_fn() -> Option<Option<u8>> {\n        None\n    }\n}\n\nfn main() {\n    input(None);\n    output();\n    output_nested();\n\n    // The lint allows this\n    let local: Option<Option<u8>> = None;\n\n    // The lint allows this\n    let expr = Some(Some(true));\n}\n\nextern crate serde;\nmod issue_4298 {\n    use serde::{Deserialize, Deserializer, Serialize};\n    use std::borrow::Cow;\n\n    #[derive(Serialize, Deserialize)]\n    struct Foo<'a> {\n        #[serde(deserialize_with = \"func\")]\n        #[serde(skip_serializing_if = \"Option::is_none\")]\n        #[serde(default)]\n        #[serde(borrow)]\n        foo: Option<Option<Cow<'a, str>>>,\n        //~^ option_option\n    }\n\n    #[allow(clippy::option_option)]\n    fn func<'a, D>(_: D) -> Result<Option<Option<Cow<'a, str>>>, D::Error>\n    where\n        D: Deserializer<'a>,\n    {\n        Ok(Some(Some(Cow::Borrowed(\"hi\"))))\n    }\n}\n"
  },
  {
    "path": "tests/ui/option_option.stderr",
    "content": "error: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:4:10\n   |\nLL | const C: Option<Option<i32>> = None;\n   |          ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<i32>`, or a custom enum if you need to distinguish all 3 cases\n   = note: `-D clippy::option-option` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::option_option)]`\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:6:11\n   |\nLL | static S: Option<Option<i32>> = None;\n   |           ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<i32>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:9:13\n   |\nLL | fn input(_: Option<Option<u8>>) {}\n   |             ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<u8>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:12:16\n   |\nLL | fn output() -> Option<Option<u8>> {\n   |                ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<u8>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:17:27\n   |\nLL | fn output_nested() -> Vec<Option<Option<u8>>> {\n   |                           ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<u8>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:23:30\n   |\nLL | fn output_nested_nested() -> Option<Option<Option<u8>>> {\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<Option<u8>>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:29:8\n   |\nLL |     x: Option<Option<u8>>,\n   |        ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<u8>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:34:23\n   |\nLL |     fn struct_fn() -> Option<Option<u8>> {\n   |                       ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<u8>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:41:22\n   |\nLL |     fn trait_fn() -> Option<Option<u8>>;\n   |                      ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<u8>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:46:11\n   |\nLL |     Tuple(Option<Option<u8>>),\n   |           ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<u8>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:48:17\n   |\nLL |     Struct { x: Option<Option<u8>> },\n   |                 ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<u8>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: use of `Option<Option<T>>`\n  --> tests/ui/option_option.rs:90:14\n   |\nLL |         foo: Option<Option<Cow<'a, str>>>,\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Option<Cow<'a, str>>`, or a custom enum if you need to distinguish all 3 cases\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/or_fun_call.fixed",
    "content": "#![warn(clippy::or_fun_call)]\n#![allow(\n    clippy::borrow_as_ptr,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_wraps,\n    clippy::unnecessary_literal_unwrap,\n    clippy::unnecessary_result_map_or_else,\n    clippy::unnecessary_option_map_or_else,\n    clippy::useless_vec\n)]\n\nuse std::collections::{BTreeMap, HashMap};\nuse std::time::Duration;\n\n/// Checks implementation of the `OR_FUN_CALL` lint.\nfn or_fun_call() {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Foo {\n            Foo\n        }\n    }\n\n    struct FakeDefault;\n    impl FakeDefault {\n        fn default() -> Self {\n            FakeDefault\n        }\n    }\n\n    impl Default for FakeDefault {\n        fn default() -> Self {\n            FakeDefault\n        }\n    }\n\n    enum Enum {\n        A(i32),\n    }\n\n    fn make<T>() -> T {\n        unimplemented!();\n    }\n\n    let with_enum = Some(Enum::A(1));\n    with_enum.unwrap_or(Enum::A(5));\n\n    let with_const_fn = Some(Duration::from_secs(1));\n    with_const_fn.unwrap_or(Duration::from_secs(5));\n\n    let with_constructor = Some(vec![1]);\n    with_constructor.unwrap_or_else(make);\n    //~^ or_fun_call\n\n    let with_new: Option<Vec<i32>> = Some(vec![1]);\n    with_new.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let with_const_args = Some(vec![1]);\n    with_const_args.unwrap_or_else(|| Vec::with_capacity(12));\n    //~^ or_fun_call\n\n    let with_err: Result<_, ()> = Ok(vec![1]);\n    with_err.unwrap_or_else(|_| make());\n    //~^ or_fun_call\n\n    let with_err_args: Result<_, ()> = Ok(vec![1]);\n    with_err_args.unwrap_or_else(|_| Vec::with_capacity(12));\n    //~^ or_fun_call\n\n    let with_default_trait = Some(1);\n    with_default_trait.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let with_default_type = Some(1);\n    with_default_type.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let with_default_literal = Some(1);\n    with_default_literal.unwrap_or(0);\n    // Do not lint because `.unwrap_or_default()` wouldn't be simpler\n\n    let with_default_literal = Some(1.0);\n    with_default_literal.unwrap_or(0.0);\n    // Do not lint because `.unwrap_or_default()` wouldn't be simpler\n\n    let with_default_literal = Some(\"foo\");\n    with_default_literal.unwrap_or(\"\");\n    // Do not lint because `.unwrap_or_default()` wouldn't be simpler\n\n    let with_default_vec_macro = Some(vec![1, 2, 3]);\n    with_default_vec_macro.unwrap_or(vec![]);\n    // Do not lint because `.unwrap_or_default()` wouldn't be simpler\n\n    let self_default = None::<FakeDefault>;\n    self_default.unwrap_or_else(<FakeDefault>::default);\n    //~^ or_fun_call\n\n    let real_default = None::<FakeDefault>;\n    real_default.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let with_vec: Option<Vec<i32>> = Some(vec![1]);\n    with_vec.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let without_default = Some(Foo);\n    without_default.unwrap_or_else(Foo::new);\n    //~^ or_fun_call\n\n    let mut map = HashMap::<u64, String>::new();\n    map.entry(42).or_default();\n    //~^ unwrap_or_default\n\n    let mut map_vec = HashMap::<u64, Vec<i32>>::new();\n    map_vec.entry(42).or_default();\n    //~^ unwrap_or_default\n\n    let mut btree = BTreeMap::<u64, String>::new();\n    btree.entry(42).or_default();\n    //~^ unwrap_or_default\n\n    let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new();\n    btree_vec.entry(42).or_default();\n    //~^ unwrap_or_default\n\n    let stringy = Some(String::new());\n    let _ = stringy.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let opt = Some(1);\n    let hello = \"Hello\";\n    let _ = opt.ok_or_else(|| format!(\"{} world.\", hello));\n    //~^ or_fun_call\n\n    // index\n    let map = HashMap::<u64, u64>::new();\n    let _ = Some(1).unwrap_or_else(|| map[&1]);\n    //~^ or_fun_call\n    let map = BTreeMap::<u64, u64>::new();\n    let _ = Some(1).unwrap_or_else(|| map[&1]);\n    //~^ or_fun_call\n    // don't lint index vec\n    let vec = vec![1];\n    let _ = Some(1).unwrap_or(vec[1]);\n}\n\nstruct Foo(u8);\nstruct Bar(String, Duration);\n#[rustfmt::skip]\nfn test_or_with_ctors() {\n    let opt = Some(1);\n    let opt_opt = Some(Some(1));\n    // we also test for const promotion, this makes sure we don't hit that\n    let two = 2;\n\n    let _ = opt_opt.unwrap_or(Some(2));\n    let _ = opt_opt.unwrap_or(Some(two));\n    let _ = opt.ok_or(Some(2));\n    let _ = opt.ok_or(Some(two));\n    let _ = opt.ok_or(Foo(2));\n    let _ = opt.ok_or(Foo(two));\n    let _ = opt.or(Some(2));\n    let _ = opt.or(Some(two));\n\n    let _ = Some(\"a\".to_string()).or_else(|| Some(\"b\".to_string()));\n    //~^ or_fun_call\n\n    let b = \"b\".to_string();\n    let _ = Some(Bar(\"a\".to_string(), Duration::from_secs(1)))\n        .or(Some(Bar(b, Duration::from_secs(2))));\n\n    let vec = vec![\"foo\"];\n    let _ = opt.ok_or(vec.len());\n\n    let array = [\"foo\"];\n    let _ = opt.ok_or(array.len());\n\n    let slice = &[\"foo\"][..];\n    let _ = opt.ok_or(slice.len());\n\n    let string = \"foo\";\n    let _ = opt.ok_or(string.len());\n}\n\n// Issue 4514 - early return\nfn f() -> Option<()> {\n    let a = Some(1);\n    let b = 1i32;\n\n    let _ = a.unwrap_or(b.checked_mul(3)?.min(240));\n\n    Some(())\n}\n\nmod issue6675 {\n    unsafe fn ptr_to_ref<'a, T>(p: *const T) -> &'a T {\n        unsafe {\n            #[allow(unused)]\n            let x = vec![0; 1000]; // future-proofing, make this function expensive.\n            &*p\n        }\n    }\n\n    unsafe fn foo() {\n        unsafe {\n            let s = \"test\".to_owned();\n            let s = &s as *const _;\n            None.unwrap_or_else(|| ptr_to_ref(s));\n            //~^ or_fun_call\n        }\n    }\n\n    fn bar() {\n        let s = \"test\".to_owned();\n        let s = &s as *const _;\n        None.unwrap_or_else(|| unsafe { ptr_to_ref(s) });\n        //~^ or_fun_call\n        #[rustfmt::skip]\n        None.unwrap_or_else(|| unsafe { ptr_to_ref(s) });\n        //~^ or_fun_call\n    }\n}\n\nmod issue8239 {\n    fn more_than_max_suggestion_highest_lines_0() {\n        let frames = Vec::new();\n        frames\n            .iter()\n            .map(|f: &String| f.to_lowercase())\n            .reduce(|mut acc, f| {\n                acc.push_str(&f);\n                acc\n            })\n            .unwrap_or(String::new());\n    }\n\n    fn more_to_max_suggestion_highest_lines_1() {\n        let frames = Vec::new();\n        let iter = frames.iter();\n        iter.map(|f: &String| f.to_lowercase())\n            .reduce(|mut acc, f| {\n                let _ = \"\";\n                let _ = \"\";\n                acc.push_str(&f);\n                acc\n            })\n            .unwrap_or(String::new());\n    }\n\n    fn equal_to_max_suggestion_highest_lines() {\n        let frames = Vec::new();\n        let iter = frames.iter();\n        iter.map(|f: &String| f.to_lowercase())\n            .reduce(|mut acc, f| {\n                let _ = \"\";\n                acc.push_str(&f);\n                acc\n            })\n            .unwrap_or(String::new());\n    }\n\n    fn less_than_max_suggestion_highest_lines() {\n        let frames = Vec::new();\n        let iter = frames.iter();\n        let map = iter.map(|f: &String| f.to_lowercase());\n        map.reduce(|mut acc, f| {\n            acc.push_str(&f);\n            acc\n        })\n        .unwrap_or(String::new());\n    }\n}\n\nmod issue9608 {\n    fn sig_drop() {\n        enum X {\n            X(std::fs::File),\n            Y(u32),\n        }\n\n        let _ = None.unwrap_or(X::Y(0));\n    }\n}\n\nmod issue8993 {\n    fn g() -> i32 {\n        3\n    }\n\n    fn f(n: i32) -> i32 {\n        n\n    }\n\n    fn test_map_or() {\n        let _ = Some(4).map_or_else(g, |v| v);\n        //~^ or_fun_call\n        let _ = Some(4).map_or_else(g, f);\n        //~^ or_fun_call\n        let _ = Some(4).map_or(0, f);\n        let _ = Some(4).map_or_else(|| \"asd\".to_string().len() as i32, f);\n        //~^ or_fun_call\n    }\n}\n\nmod lazy {\n    use super::*;\n\n    fn foo() {\n        struct Foo;\n\n        impl Foo {\n            fn new() -> Foo {\n                Foo\n            }\n        }\n\n        struct FakeDefault;\n        impl FakeDefault {\n            fn default() -> Self {\n                FakeDefault\n            }\n        }\n\n        impl Default for FakeDefault {\n            fn default() -> Self {\n                FakeDefault\n            }\n        }\n\n        let with_new: Option<Vec<i32>> = Some(vec![1]);\n        with_new.unwrap_or_default();\n        //~^ unwrap_or_default\n\n        let with_default_trait = Some(1);\n        with_default_trait.unwrap_or_default();\n        //~^ unwrap_or_default\n\n        let with_default_type = Some(1);\n        with_default_type.unwrap_or_default();\n        //~^ unwrap_or_default\n\n        let real_default = None::<FakeDefault>;\n        real_default.unwrap_or_default();\n        //~^ unwrap_or_default\n\n        let mut map = HashMap::<u64, String>::new();\n        map.entry(42).or_default();\n        //~^ unwrap_or_default\n\n        let mut btree = BTreeMap::<u64, String>::new();\n        btree.entry(42).or_default();\n        //~^ unwrap_or_default\n\n        let stringy = Some(String::new());\n        let _ = stringy.unwrap_or_default();\n        //~^ unwrap_or_default\n\n        // negative tests\n        let self_default = None::<FakeDefault>;\n        self_default.unwrap_or_else(<FakeDefault>::default);\n\n        let without_default = Some(Foo);\n        without_default.unwrap_or_else(Foo::new);\n    }\n}\n\nfn host_effect() {\n    // #12877 - make sure we don't ICE in type_certainty\n    use std::ops::Add;\n\n    Add::<i32>::add(1, 1).add(i32::MIN);\n}\n\nmod issue_10228 {\n    struct Entry;\n\n    impl Entry {\n        fn or_insert(self, _default: i32) {}\n        fn or_default(self) {\n            // Don't lint, suggested code is an infinite recursion\n            self.or_insert(Default::default())\n        }\n    }\n}\n\n// issue #12973\nfn fn_call_in_nested_expr() {\n    struct Foo {\n        val: String,\n    }\n\n    fn f() -> i32 {\n        1\n    }\n    let opt: Option<i32> = Some(1);\n\n    let _ = opt.unwrap_or_else(f); // suggest `.unwrap_or_else(f)`\n    //\n    //~^^ or_fun_call\n    //\n\n    let _ = opt.unwrap_or_else(|| f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`\n    //\n    //~^^ or_fun_call\n    //\n\n    let _ = opt.unwrap_or_else(|| {\n        //~^ or_fun_call\n        let x = f();\n        x + 1\n    });\n\n    let _ = opt.map_or_else(|| f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`\n    //\n    //~^^ or_fun_call\n    //\n\n    let _ = opt.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let opt_foo = Some(Foo {\n        val: String::from(\"123\"),\n    });\n\n    let _ = opt_foo.unwrap_or_else(|| Foo { val: String::default() });\n    //~^ or_fun_call\n}\n\nmod result_map_or {\n    fn g() -> i32 {\n        3\n    }\n\n    fn f(n: i32) -> i32 {\n        n\n    }\n\n    fn test_map_or() {\n        let x: Result<i32, ()> = Ok(4);\n        let _ = x.map_or_else(|_| g(), |v| v);\n        //~^ or_fun_call\n        let _ = x.map_or_else(|_| g(), f);\n        //~^ or_fun_call\n        let _ = x.map_or(0, f);\n        let _ = x.map_or_else(|_| \"asd\".to_string().len() as i32, f);\n        //~^ or_fun_call\n    }\n}\n\nfn test_option_get_or_insert() {\n    // assume that this is slow call\n    fn g() -> u8 {\n        99\n    }\n    let mut x = Some(42_u8);\n    let _ = x.get_or_insert_with(g);\n    //~^ or_fun_call\n}\n\nfn test_option_and() {\n    // assume that this is slow call\n    fn g() -> Option<u8> {\n        Some(99)\n    }\n    let mut x = Some(42_u8);\n    let _ = x.and_then(|_| g());\n    //~^ or_fun_call\n}\n\nfn test_result_and() {\n    // assume that this is slow call\n    fn g() -> Result<u8, ()> {\n        Ok(99)\n    }\n    let mut x: Result<u8, ()> = Ok(42);\n    let _ = x.and_then(|_| g());\n    //~^ or_fun_call\n}\n\n#[clippy::msrv = \"1.15\"]\nfn below_msrv(opt: Option<i32>, res: Result<i32, ()>) {\n    let _ = opt.unwrap_or_default();\n    //~^ unwrap_or_default\n    let _ = res.unwrap_or_else(|_| Default::default());\n    //~^ or_fun_call\n}\n\n#[clippy::msrv = \"1.16\"]\nfn above_msrv(opt: Option<i32>, res: Result<i32, ()>) {\n    let _ = opt.unwrap_or_default();\n    //~^ unwrap_or_default\n    let _ = res.unwrap_or_default();\n    //~^ unwrap_or_default\n}\nfn main() {}\n"
  },
  {
    "path": "tests/ui/or_fun_call.rs",
    "content": "#![warn(clippy::or_fun_call)]\n#![allow(\n    clippy::borrow_as_ptr,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_wraps,\n    clippy::unnecessary_literal_unwrap,\n    clippy::unnecessary_result_map_or_else,\n    clippy::unnecessary_option_map_or_else,\n    clippy::useless_vec\n)]\n\nuse std::collections::{BTreeMap, HashMap};\nuse std::time::Duration;\n\n/// Checks implementation of the `OR_FUN_CALL` lint.\nfn or_fun_call() {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Foo {\n            Foo\n        }\n    }\n\n    struct FakeDefault;\n    impl FakeDefault {\n        fn default() -> Self {\n            FakeDefault\n        }\n    }\n\n    impl Default for FakeDefault {\n        fn default() -> Self {\n            FakeDefault\n        }\n    }\n\n    enum Enum {\n        A(i32),\n    }\n\n    fn make<T>() -> T {\n        unimplemented!();\n    }\n\n    let with_enum = Some(Enum::A(1));\n    with_enum.unwrap_or(Enum::A(5));\n\n    let with_const_fn = Some(Duration::from_secs(1));\n    with_const_fn.unwrap_or(Duration::from_secs(5));\n\n    let with_constructor = Some(vec![1]);\n    with_constructor.unwrap_or(make());\n    //~^ or_fun_call\n\n    let with_new: Option<Vec<i32>> = Some(vec![1]);\n    with_new.unwrap_or(Vec::new());\n    //~^ unwrap_or_default\n\n    let with_const_args = Some(vec![1]);\n    with_const_args.unwrap_or(Vec::with_capacity(12));\n    //~^ or_fun_call\n\n    let with_err: Result<_, ()> = Ok(vec![1]);\n    with_err.unwrap_or(make());\n    //~^ or_fun_call\n\n    let with_err_args: Result<_, ()> = Ok(vec![1]);\n    with_err_args.unwrap_or(Vec::with_capacity(12));\n    //~^ or_fun_call\n\n    let with_default_trait = Some(1);\n    with_default_trait.unwrap_or(Default::default());\n    //~^ unwrap_or_default\n\n    let with_default_type = Some(1);\n    with_default_type.unwrap_or(u64::default());\n    //~^ unwrap_or_default\n\n    let with_default_literal = Some(1);\n    with_default_literal.unwrap_or(0);\n    // Do not lint because `.unwrap_or_default()` wouldn't be simpler\n\n    let with_default_literal = Some(1.0);\n    with_default_literal.unwrap_or(0.0);\n    // Do not lint because `.unwrap_or_default()` wouldn't be simpler\n\n    let with_default_literal = Some(\"foo\");\n    with_default_literal.unwrap_or(\"\");\n    // Do not lint because `.unwrap_or_default()` wouldn't be simpler\n\n    let with_default_vec_macro = Some(vec![1, 2, 3]);\n    with_default_vec_macro.unwrap_or(vec![]);\n    // Do not lint because `.unwrap_or_default()` wouldn't be simpler\n\n    let self_default = None::<FakeDefault>;\n    self_default.unwrap_or(<FakeDefault>::default());\n    //~^ or_fun_call\n\n    let real_default = None::<FakeDefault>;\n    real_default.unwrap_or(<FakeDefault as Default>::default());\n    //~^ unwrap_or_default\n\n    let with_vec: Option<Vec<i32>> = Some(vec![1]);\n    with_vec.unwrap_or(Vec::new());\n    //~^ unwrap_or_default\n\n    let without_default = Some(Foo);\n    without_default.unwrap_or(Foo::new());\n    //~^ or_fun_call\n\n    let mut map = HashMap::<u64, String>::new();\n    map.entry(42).or_insert(String::new());\n    //~^ unwrap_or_default\n\n    let mut map_vec = HashMap::<u64, Vec<i32>>::new();\n    map_vec.entry(42).or_insert(Vec::new());\n    //~^ unwrap_or_default\n\n    let mut btree = BTreeMap::<u64, String>::new();\n    btree.entry(42).or_insert(String::new());\n    //~^ unwrap_or_default\n\n    let mut btree_vec = BTreeMap::<u64, Vec<i32>>::new();\n    btree_vec.entry(42).or_insert(Vec::new());\n    //~^ unwrap_or_default\n\n    let stringy = Some(String::new());\n    let _ = stringy.unwrap_or(String::new());\n    //~^ unwrap_or_default\n\n    let opt = Some(1);\n    let hello = \"Hello\";\n    let _ = opt.ok_or(format!(\"{} world.\", hello));\n    //~^ or_fun_call\n\n    // index\n    let map = HashMap::<u64, u64>::new();\n    let _ = Some(1).unwrap_or(map[&1]);\n    //~^ or_fun_call\n    let map = BTreeMap::<u64, u64>::new();\n    let _ = Some(1).unwrap_or(map[&1]);\n    //~^ or_fun_call\n    // don't lint index vec\n    let vec = vec![1];\n    let _ = Some(1).unwrap_or(vec[1]);\n}\n\nstruct Foo(u8);\nstruct Bar(String, Duration);\n#[rustfmt::skip]\nfn test_or_with_ctors() {\n    let opt = Some(1);\n    let opt_opt = Some(Some(1));\n    // we also test for const promotion, this makes sure we don't hit that\n    let two = 2;\n\n    let _ = opt_opt.unwrap_or(Some(2));\n    let _ = opt_opt.unwrap_or(Some(two));\n    let _ = opt.ok_or(Some(2));\n    let _ = opt.ok_or(Some(two));\n    let _ = opt.ok_or(Foo(2));\n    let _ = opt.ok_or(Foo(two));\n    let _ = opt.or(Some(2));\n    let _ = opt.or(Some(two));\n\n    let _ = Some(\"a\".to_string()).or(Some(\"b\".to_string()));\n    //~^ or_fun_call\n\n    let b = \"b\".to_string();\n    let _ = Some(Bar(\"a\".to_string(), Duration::from_secs(1)))\n        .or(Some(Bar(b, Duration::from_secs(2))));\n\n    let vec = vec![\"foo\"];\n    let _ = opt.ok_or(vec.len());\n\n    let array = [\"foo\"];\n    let _ = opt.ok_or(array.len());\n\n    let slice = &[\"foo\"][..];\n    let _ = opt.ok_or(slice.len());\n\n    let string = \"foo\";\n    let _ = opt.ok_or(string.len());\n}\n\n// Issue 4514 - early return\nfn f() -> Option<()> {\n    let a = Some(1);\n    let b = 1i32;\n\n    let _ = a.unwrap_or(b.checked_mul(3)?.min(240));\n\n    Some(())\n}\n\nmod issue6675 {\n    unsafe fn ptr_to_ref<'a, T>(p: *const T) -> &'a T {\n        unsafe {\n            #[allow(unused)]\n            let x = vec![0; 1000]; // future-proofing, make this function expensive.\n            &*p\n        }\n    }\n\n    unsafe fn foo() {\n        unsafe {\n            let s = \"test\".to_owned();\n            let s = &s as *const _;\n            None.unwrap_or(ptr_to_ref(s));\n            //~^ or_fun_call\n        }\n    }\n\n    fn bar() {\n        let s = \"test\".to_owned();\n        let s = &s as *const _;\n        None.unwrap_or(unsafe { ptr_to_ref(s) });\n        //~^ or_fun_call\n        #[rustfmt::skip]\n        None.unwrap_or( unsafe { ptr_to_ref(s) }    );\n        //~^ or_fun_call\n    }\n}\n\nmod issue8239 {\n    fn more_than_max_suggestion_highest_lines_0() {\n        let frames = Vec::new();\n        frames\n            .iter()\n            .map(|f: &String| f.to_lowercase())\n            .reduce(|mut acc, f| {\n                acc.push_str(&f);\n                acc\n            })\n            .unwrap_or(String::new());\n    }\n\n    fn more_to_max_suggestion_highest_lines_1() {\n        let frames = Vec::new();\n        let iter = frames.iter();\n        iter.map(|f: &String| f.to_lowercase())\n            .reduce(|mut acc, f| {\n                let _ = \"\";\n                let _ = \"\";\n                acc.push_str(&f);\n                acc\n            })\n            .unwrap_or(String::new());\n    }\n\n    fn equal_to_max_suggestion_highest_lines() {\n        let frames = Vec::new();\n        let iter = frames.iter();\n        iter.map(|f: &String| f.to_lowercase())\n            .reduce(|mut acc, f| {\n                let _ = \"\";\n                acc.push_str(&f);\n                acc\n            })\n            .unwrap_or(String::new());\n    }\n\n    fn less_than_max_suggestion_highest_lines() {\n        let frames = Vec::new();\n        let iter = frames.iter();\n        let map = iter.map(|f: &String| f.to_lowercase());\n        map.reduce(|mut acc, f| {\n            acc.push_str(&f);\n            acc\n        })\n        .unwrap_or(String::new());\n    }\n}\n\nmod issue9608 {\n    fn sig_drop() {\n        enum X {\n            X(std::fs::File),\n            Y(u32),\n        }\n\n        let _ = None.unwrap_or(X::Y(0));\n    }\n}\n\nmod issue8993 {\n    fn g() -> i32 {\n        3\n    }\n\n    fn f(n: i32) -> i32 {\n        n\n    }\n\n    fn test_map_or() {\n        let _ = Some(4).map_or(g(), |v| v);\n        //~^ or_fun_call\n        let _ = Some(4).map_or(g(), f);\n        //~^ or_fun_call\n        let _ = Some(4).map_or(0, f);\n        let _ = Some(4).map_or(\"asd\".to_string().len() as i32, f);\n        //~^ or_fun_call\n    }\n}\n\nmod lazy {\n    use super::*;\n\n    fn foo() {\n        struct Foo;\n\n        impl Foo {\n            fn new() -> Foo {\n                Foo\n            }\n        }\n\n        struct FakeDefault;\n        impl FakeDefault {\n            fn default() -> Self {\n                FakeDefault\n            }\n        }\n\n        impl Default for FakeDefault {\n            fn default() -> Self {\n                FakeDefault\n            }\n        }\n\n        let with_new: Option<Vec<i32>> = Some(vec![1]);\n        with_new.unwrap_or_else(Vec::new);\n        //~^ unwrap_or_default\n\n        let with_default_trait = Some(1);\n        with_default_trait.unwrap_or_else(Default::default);\n        //~^ unwrap_or_default\n\n        let with_default_type = Some(1);\n        with_default_type.unwrap_or_else(u64::default);\n        //~^ unwrap_or_default\n\n        let real_default = None::<FakeDefault>;\n        real_default.unwrap_or_else(<FakeDefault as Default>::default);\n        //~^ unwrap_or_default\n\n        let mut map = HashMap::<u64, String>::new();\n        map.entry(42).or_insert_with(String::new);\n        //~^ unwrap_or_default\n\n        let mut btree = BTreeMap::<u64, String>::new();\n        btree.entry(42).or_insert_with(String::new);\n        //~^ unwrap_or_default\n\n        let stringy = Some(String::new());\n        let _ = stringy.unwrap_or_else(String::new);\n        //~^ unwrap_or_default\n\n        // negative tests\n        let self_default = None::<FakeDefault>;\n        self_default.unwrap_or_else(<FakeDefault>::default);\n\n        let without_default = Some(Foo);\n        without_default.unwrap_or_else(Foo::new);\n    }\n}\n\nfn host_effect() {\n    // #12877 - make sure we don't ICE in type_certainty\n    use std::ops::Add;\n\n    Add::<i32>::add(1, 1).add(i32::MIN);\n}\n\nmod issue_10228 {\n    struct Entry;\n\n    impl Entry {\n        fn or_insert(self, _default: i32) {}\n        fn or_default(self) {\n            // Don't lint, suggested code is an infinite recursion\n            self.or_insert(Default::default())\n        }\n    }\n}\n\n// issue #12973\nfn fn_call_in_nested_expr() {\n    struct Foo {\n        val: String,\n    }\n\n    fn f() -> i32 {\n        1\n    }\n    let opt: Option<i32> = Some(1);\n\n    let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)`\n    //\n    //~^^ or_fun_call\n    //\n\n    let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`\n    //\n    //~^^ or_fun_call\n    //\n\n    let _ = opt.unwrap_or({\n        //~^ or_fun_call\n        let x = f();\n        x + 1\n    });\n\n    let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`\n    //\n    //~^^ or_fun_call\n    //\n\n    let _ = opt.unwrap_or({ i32::default() });\n    //~^ unwrap_or_default\n\n    let opt_foo = Some(Foo {\n        val: String::from(\"123\"),\n    });\n\n    let _ = opt_foo.unwrap_or(Foo { val: String::default() });\n    //~^ or_fun_call\n}\n\nmod result_map_or {\n    fn g() -> i32 {\n        3\n    }\n\n    fn f(n: i32) -> i32 {\n        n\n    }\n\n    fn test_map_or() {\n        let x: Result<i32, ()> = Ok(4);\n        let _ = x.map_or(g(), |v| v);\n        //~^ or_fun_call\n        let _ = x.map_or(g(), f);\n        //~^ or_fun_call\n        let _ = x.map_or(0, f);\n        let _ = x.map_or(\"asd\".to_string().len() as i32, f);\n        //~^ or_fun_call\n    }\n}\n\nfn test_option_get_or_insert() {\n    // assume that this is slow call\n    fn g() -> u8 {\n        99\n    }\n    let mut x = Some(42_u8);\n    let _ = x.get_or_insert(g());\n    //~^ or_fun_call\n}\n\nfn test_option_and() {\n    // assume that this is slow call\n    fn g() -> Option<u8> {\n        Some(99)\n    }\n    let mut x = Some(42_u8);\n    let _ = x.and(g());\n    //~^ or_fun_call\n}\n\nfn test_result_and() {\n    // assume that this is slow call\n    fn g() -> Result<u8, ()> {\n        Ok(99)\n    }\n    let mut x: Result<u8, ()> = Ok(42);\n    let _ = x.and(g());\n    //~^ or_fun_call\n}\n\n#[clippy::msrv = \"1.15\"]\nfn below_msrv(opt: Option<i32>, res: Result<i32, ()>) {\n    let _ = opt.unwrap_or(Default::default());\n    //~^ unwrap_or_default\n    let _ = res.unwrap_or(Default::default());\n    //~^ or_fun_call\n}\n\n#[clippy::msrv = \"1.16\"]\nfn above_msrv(opt: Option<i32>, res: Result<i32, ()>) {\n    let _ = opt.unwrap_or(Default::default());\n    //~^ unwrap_or_default\n    let _ = res.unwrap_or(Default::default());\n    //~^ unwrap_or_default\n}\nfn main() {}\n"
  },
  {
    "path": "tests/ui/or_fun_call.stderr",
    "content": "error: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:53:22\n   |\nLL |     with_constructor.unwrap_or(make());\n   |                      ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(make)`\n   |\n   = note: `-D clippy::or-fun-call` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:57:14\n   |\nLL |     with_new.unwrap_or(Vec::new());\n   |              ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n   |\n   = note: `-D clippy::unwrap-or-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unwrap_or_default)]`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:61:21\n   |\nLL |     with_const_args.unwrap_or(Vec::with_capacity(12));\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Vec::with_capacity(12))`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:65:14\n   |\nLL |     with_err.unwrap_or(make());\n   |              ^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| make())`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:69:19\n   |\nLL |     with_err_args.unwrap_or(Vec::with_capacity(12));\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Vec::with_capacity(12))`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:73:24\n   |\nLL |     with_default_trait.unwrap_or(Default::default());\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:77:23\n   |\nLL |     with_default_type.unwrap_or(u64::default());\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:97:18\n   |\nLL |     self_default.unwrap_or(<FakeDefault>::default());\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(<FakeDefault>::default)`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:101:18\n   |\nLL |     real_default.unwrap_or(<FakeDefault as Default>::default());\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:105:14\n   |\nLL |     with_vec.unwrap_or(Vec::new());\n   |              ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:109:21\n   |\nLL |     without_default.unwrap_or(Foo::new());\n   |                     ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(Foo::new)`\n\nerror: use of `or_insert` to construct default value\n  --> tests/ui/or_fun_call.rs:113:19\n   |\nLL |     map.entry(42).or_insert(String::new());\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`\n\nerror: use of `or_insert` to construct default value\n  --> tests/ui/or_fun_call.rs:117:23\n   |\nLL |     map_vec.entry(42).or_insert(Vec::new());\n   |                       ^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`\n\nerror: use of `or_insert` to construct default value\n  --> tests/ui/or_fun_call.rs:121:21\n   |\nLL |     btree.entry(42).or_insert(String::new());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`\n\nerror: use of `or_insert` to construct default value\n  --> tests/ui/or_fun_call.rs:125:25\n   |\nLL |     btree_vec.entry(42).or_insert(Vec::new());\n   |                         ^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:129:21\n   |\nLL |     let _ = stringy.unwrap_or(String::new());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: function call inside of `ok_or`\n  --> tests/ui/or_fun_call.rs:134:17\n   |\nLL |     let _ = opt.ok_or(format!(\"{} world.\", hello));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ok_or_else(|| format!(\"{} world.\", hello))`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:139:21\n   |\nLL |     let _ = Some(1).unwrap_or(map[&1]);\n   |                     ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:142:21\n   |\nLL |     let _ = Some(1).unwrap_or(map[&1]);\n   |                     ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| map[&1])`\n\nerror: function call inside of `or`\n  --> tests/ui/or_fun_call.rs:167:35\n   |\nLL |     let _ = Some(\"a\".to_string()).or(Some(\"b\".to_string()));\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_else(|| Some(\"b\".to_string()))`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:210:18\n   |\nLL |             None.unwrap_or(ptr_to_ref(s));\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| ptr_to_ref(s))`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:218:14\n   |\nLL |         None.unwrap_or(unsafe { ptr_to_ref(s) });\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:221:14\n   |\nLL |         None.unwrap_or( unsafe { ptr_to_ref(s) }    );\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| unsafe { ptr_to_ref(s) })`\n\nerror: function call inside of `map_or`\n  --> tests/ui/or_fun_call.rs:297:25\n   |\nLL |         let _ = Some(4).map_or(g(), |v| v);\n   |                         ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(g, |v| v)`\n\nerror: function call inside of `map_or`\n  --> tests/ui/or_fun_call.rs:299:25\n   |\nLL |         let _ = Some(4).map_or(g(), f);\n   |                         ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)`\n\nerror: function call inside of `map_or`\n  --> tests/ui/or_fun_call.rs:302:25\n   |\nLL |         let _ = Some(4).map_or(\"asd\".to_string().len() as i32, f);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| \"asd\".to_string().len() as i32, f)`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/or_fun_call.rs:333:18\n   |\nLL |         with_new.unwrap_or_else(Vec::new);\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/or_fun_call.rs:337:28\n   |\nLL |         with_default_trait.unwrap_or_else(Default::default);\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/or_fun_call.rs:341:27\n   |\nLL |         with_default_type.unwrap_or_else(u64::default);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/or_fun_call.rs:345:22\n   |\nLL |         real_default.unwrap_or_else(<FakeDefault as Default>::default);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `or_insert_with` to construct default value\n  --> tests/ui/or_fun_call.rs:349:23\n   |\nLL |         map.entry(42).or_insert_with(String::new);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`\n\nerror: use of `or_insert_with` to construct default value\n  --> tests/ui/or_fun_call.rs:353:25\n   |\nLL |         btree.entry(42).or_insert_with(String::new);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/or_fun_call.rs:357:25\n   |\nLL |         let _ = stringy.unwrap_or_else(String::new);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:399:17\n   |\nLL |     let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)`\n   |                 ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:404:17\n   |\nLL |     let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`\n   |                 ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:409:17\n   |\nLL |       let _ = opt.unwrap_or({\n   |  _________________^\nLL | |\nLL | |         let x = f();\nLL | |         x + 1\nLL | |     });\n   | |______^\n   |\nhelp: try\n   |\nLL ~     let _ = opt.unwrap_or_else(|| {\nLL +\nLL +         let x = f();\nLL +         x + 1\nLL ~     });\n   |\n\nerror: function call inside of `map_or`\n  --> tests/ui/or_fun_call.rs:415:17\n   |\nLL |     let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`\n   |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:420:17\n   |\nLL |     let _ = opt.unwrap_or({ i32::default() });\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:427:21\n   |\nLL |     let _ = opt_foo.unwrap_or(Foo { val: String::default() });\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })`\n\nerror: function call inside of `map_or`\n  --> tests/ui/or_fun_call.rs:442:19\n   |\nLL |         let _ = x.map_or(g(), |v| v);\n   |                   ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), |v| v)`\n\nerror: function call inside of `map_or`\n  --> tests/ui/or_fun_call.rs:444:19\n   |\nLL |         let _ = x.map_or(g(), f);\n   |                   ^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), f)`\n\nerror: function call inside of `map_or`\n  --> tests/ui/or_fun_call.rs:447:19\n   |\nLL |         let _ = x.map_or(\"asd\".to_string().len() as i32, f);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| \"asd\".to_string().len() as i32, f)`\n\nerror: function call inside of `get_or_insert`\n  --> tests/ui/or_fun_call.rs:458:15\n   |\nLL |     let _ = x.get_or_insert(g());\n   |               ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)`\n\nerror: function call inside of `and`\n  --> tests/ui/or_fun_call.rs:468:15\n   |\nLL |     let _ = x.and(g());\n   |               ^^^^^^^^ help: try: `and_then(|_| g())`\n\nerror: function call inside of `and`\n  --> tests/ui/or_fun_call.rs:478:15\n   |\nLL |     let _ = x.and(g());\n   |               ^^^^^^^^ help: try: `and_then(|_| g())`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:484:17\n   |\nLL |     let _ = opt.unwrap_or(Default::default());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/or_fun_call.rs:486:17\n   |\nLL |     let _ = res.unwrap_or(Default::default());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| Default::default())`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:492:17\n   |\nLL |     let _ = opt.unwrap_or(Default::default());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or` to construct default value\n  --> tests/ui/or_fun_call.rs:494:17\n   |\nLL |     let _ = res.unwrap_or(Default::default());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: aborting due to 49 previous errors\n\n"
  },
  {
    "path": "tests/ui/or_then_unwrap.fixed",
    "content": "#![warn(clippy::or_then_unwrap)]\n#![allow(clippy::map_identity, clippy::let_unit_value, clippy::unnecessary_literal_unwrap)]\n\nstruct SomeStruct;\nimpl SomeStruct {\n    fn or(self, _: Option<Self>) -> Self {\n        self\n    }\n    fn unwrap(&self) {}\n}\n\nstruct SomeOtherStruct;\nimpl SomeOtherStruct {\n    fn or(self) -> Self {\n        self\n    }\n    fn unwrap(&self) {}\n}\n\nfn main() {\n    let option: Option<&str> = None;\n    let _ = option.unwrap_or(\"fallback\"); // should trigger lint\n    //\n    //~^^ or_then_unwrap\n\n    let result: Result<&str, &str> = Err(\"Error\");\n    let _ = result.unwrap_or(\"fallback\"); // should trigger lint\n    //\n    //~^^ or_then_unwrap\n\n    // Call with macro should preserve the macro call rather than expand it\n    let option: Option<Vec<&str>> = None;\n    let _ = option.unwrap_or(vec![\"fallback\"]); // should trigger lint\n    //\n    //~^^ or_then_unwrap\n\n    // as part of a method chain\n    let option: Option<&str> = None;\n    let _ = option.map(|v| v).unwrap_or(\"fallback\").to_string().chars(); // should trigger lint\n    //\n    //~^^ or_then_unwrap\n\n    // Not Option/Result\n    let instance = SomeStruct {};\n    let _ = instance.or(Some(SomeStruct {})).unwrap(); // should not trigger lint\n\n    // or takes no argument\n    let instance = SomeOtherStruct {};\n    let _ = instance.or().unwrap(); // should not trigger lint and should not panic\n\n    // None in or\n    let option: Option<&str> = None;\n    let _ = option.or(None).unwrap(); // should not trigger lint\n\n    // Not Err in or\n    let result: Result<&str, &str> = Err(\"Error\");\n    let _ = result.or::<&str>(Err(\"Other Error\")).unwrap(); // should not trigger lint\n\n    // other function between\n    let option: Option<&str> = None;\n    let _ = option.or(Some(\"fallback\")).map(|v| v).unwrap(); // should not trigger lint\n}\n"
  },
  {
    "path": "tests/ui/or_then_unwrap.rs",
    "content": "#![warn(clippy::or_then_unwrap)]\n#![allow(clippy::map_identity, clippy::let_unit_value, clippy::unnecessary_literal_unwrap)]\n\nstruct SomeStruct;\nimpl SomeStruct {\n    fn or(self, _: Option<Self>) -> Self {\n        self\n    }\n    fn unwrap(&self) {}\n}\n\nstruct SomeOtherStruct;\nimpl SomeOtherStruct {\n    fn or(self) -> Self {\n        self\n    }\n    fn unwrap(&self) {}\n}\n\nfn main() {\n    let option: Option<&str> = None;\n    let _ = option.or(Some(\"fallback\")).unwrap(); // should trigger lint\n    //\n    //~^^ or_then_unwrap\n\n    let result: Result<&str, &str> = Err(\"Error\");\n    let _ = result.or::<&str>(Ok(\"fallback\")).unwrap(); // should trigger lint\n    //\n    //~^^ or_then_unwrap\n\n    // Call with macro should preserve the macro call rather than expand it\n    let option: Option<Vec<&str>> = None;\n    let _ = option.or(Some(vec![\"fallback\"])).unwrap(); // should trigger lint\n    //\n    //~^^ or_then_unwrap\n\n    // as part of a method chain\n    let option: Option<&str> = None;\n    let _ = option.map(|v| v).or(Some(\"fallback\")).unwrap().to_string().chars(); // should trigger lint\n    //\n    //~^^ or_then_unwrap\n\n    // Not Option/Result\n    let instance = SomeStruct {};\n    let _ = instance.or(Some(SomeStruct {})).unwrap(); // should not trigger lint\n\n    // or takes no argument\n    let instance = SomeOtherStruct {};\n    let _ = instance.or().unwrap(); // should not trigger lint and should not panic\n\n    // None in or\n    let option: Option<&str> = None;\n    let _ = option.or(None).unwrap(); // should not trigger lint\n\n    // Not Err in or\n    let result: Result<&str, &str> = Err(\"Error\");\n    let _ = result.or::<&str>(Err(\"Other Error\")).unwrap(); // should not trigger lint\n\n    // other function between\n    let option: Option<&str> = None;\n    let _ = option.or(Some(\"fallback\")).map(|v| v).unwrap(); // should not trigger lint\n}\n"
  },
  {
    "path": "tests/ui/or_then_unwrap.stderr",
    "content": "error: found `.or(Some(…)).unwrap()`\n  --> tests/ui/or_then_unwrap.rs:22:20\n   |\nLL |     let _ = option.or(Some(\"fallback\")).unwrap(); // should trigger lint\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or(\"fallback\")`\n   |\n   = note: `-D clippy::or-then-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::or_then_unwrap)]`\n\nerror: found `.or(Ok(…)).unwrap()`\n  --> tests/ui/or_then_unwrap.rs:27:20\n   |\nLL |     let _ = result.or::<&str>(Ok(\"fallback\")).unwrap(); // should trigger lint\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or(\"fallback\")`\n\nerror: found `.or(Some(…)).unwrap()`\n  --> tests/ui/or_then_unwrap.rs:33:20\n   |\nLL |     let _ = option.or(Some(vec![\"fallback\"])).unwrap(); // should trigger lint\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or(vec![\"fallback\"])`\n\nerror: found `.or(Some(…)).unwrap()`\n  --> tests/ui/or_then_unwrap.rs:39:31\n   |\nLL |     let _ = option.map(|v| v).or(Some(\"fallback\")).unwrap().to_string().chars(); // should trigger lint\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or(\"fallback\")`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/out_of_bounds_indexing/issue-3102.rs",
    "content": "#![warn(clippy::out_of_bounds_indexing)]\n#![allow(clippy::no_effect)]\n\nfn main() {\n    let x = [1, 2, 3, 4];\n\n    // issue 3102\n    let num = 1;\n    &x[num..10];\n    //~^ out_of_bounds_indexing\n\n    &x[10..num];\n    //~^ out_of_bounds_indexing\n}\n"
  },
  {
    "path": "tests/ui/out_of_bounds_indexing/issue-3102.stderr",
    "content": "error: range is out of bounds\n  --> tests/ui/out_of_bounds_indexing/issue-3102.rs:9:13\n   |\nLL |     &x[num..10];\n   |             ^^\n   |\n   = note: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`\n\nerror: range is out of bounds\n  --> tests/ui/out_of_bounds_indexing/issue-3102.rs:12:8\n   |\nLL |     &x[10..num];\n   |        ^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/out_of_bounds_indexing/simple.rs",
    "content": "#![warn(clippy::out_of_bounds_indexing)]\n#![allow(clippy::no_effect, clippy::unnecessary_operation)]\n\nfn main() {\n    let x = [1, 2, 3, 4];\n\n    &x[..=4];\n    //~^ out_of_bounds_indexing\n\n    &x[1..5];\n    //~^ out_of_bounds_indexing\n\n    &x[5..];\n    //~^ out_of_bounds_indexing\n\n    &x[..5];\n    //~^ out_of_bounds_indexing\n\n    &x[5..].iter().map(|x| 2 * x).collect::<Vec<i32>>();\n    //~^ out_of_bounds_indexing\n\n    &x[0..=4];\n    //~^ out_of_bounds_indexing\n\n    &x[4..]; // Ok, should not produce stderr.\n    &x[..4]; // Ok, should not produce stderr.\n    &x[..]; // Ok, should not produce stderr.\n    &x[1..]; // Ok, should not produce stderr.\n    &x[2..].iter().map(|x| 2 * x).collect::<Vec<i32>>(); // Ok, should not produce stderr.\n\n    &x[0..].get(..3); // Ok, should not produce stderr.\n    &x[0..3]; // Ok, should not produce stderr.\n}\n"
  },
  {
    "path": "tests/ui/out_of_bounds_indexing/simple.stderr",
    "content": "error: range is out of bounds\n  --> tests/ui/out_of_bounds_indexing/simple.rs:7:11\n   |\nLL |     &x[..=4];\n   |           ^\n   |\n   = note: `-D clippy::out-of-bounds-indexing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`\n\nerror: range is out of bounds\n  --> tests/ui/out_of_bounds_indexing/simple.rs:10:11\n   |\nLL |     &x[1..5];\n   |           ^\n\nerror: range is out of bounds\n  --> tests/ui/out_of_bounds_indexing/simple.rs:13:8\n   |\nLL |     &x[5..];\n   |        ^\n\nerror: range is out of bounds\n  --> tests/ui/out_of_bounds_indexing/simple.rs:16:10\n   |\nLL |     &x[..5];\n   |          ^\n\nerror: range is out of bounds\n  --> tests/ui/out_of_bounds_indexing/simple.rs:19:8\n   |\nLL |     &x[5..].iter().map(|x| 2 * x).collect::<Vec<i32>>();\n   |        ^\n\nerror: range is out of bounds\n  --> tests/ui/out_of_bounds_indexing/simple.rs:22:12\n   |\nLL |     &x[0..=4];\n   |            ^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/overly_complex_bool_expr.fixed",
    "content": "#![allow(unused, clippy::diverging_sub_expression)]\n#![warn(clippy::overly_complex_bool_expr)]\n\nfn main() {\n    let a: bool = unimplemented!();\n    let b: bool = unimplemented!();\n    let c: bool = unimplemented!();\n    let d: bool = unimplemented!();\n    let e: bool = unimplemented!();\n    let _ = a;\n    //~^ overly_complex_bool_expr\n\n    let _ = !(a && b);\n    let _ = false;\n    //~^ overly_complex_bool_expr\n\n    // don't lint on cfgs\n    let _ = cfg!(you_shall_not_not_pass) && a;\n    let _ = a || !b || !c || !d || !e;\n    let _ = !(a && b || c);\n}\n\nfn equality_stuff() {\n    let a: i32 = unimplemented!();\n    let b: i32 = unimplemented!();\n    let _ = false;\n    //~^ overly_complex_bool_expr\n\n    let _ = false;\n    //~^ overly_complex_bool_expr\n\n    let _ = false;\n    //~^ overly_complex_bool_expr\n\n    let _ = a > b && a == b;\n}\n\nfn check_expect() {\n    let a: i32 = unimplemented!();\n    let b: i32 = unimplemented!();\n    #[expect(clippy::overly_complex_bool_expr)]\n    let _ = a < b && a >= b;\n}\n\n#[allow(clippy::never_loop)]\nfn check_never_type() {\n    loop {\n        _ = (break) || true;\n    }\n    loop {\n        _ = (return) || true;\n    }\n}\n"
  },
  {
    "path": "tests/ui/overly_complex_bool_expr.rs",
    "content": "#![allow(unused, clippy::diverging_sub_expression)]\n#![warn(clippy::overly_complex_bool_expr)]\n\nfn main() {\n    let a: bool = unimplemented!();\n    let b: bool = unimplemented!();\n    let c: bool = unimplemented!();\n    let d: bool = unimplemented!();\n    let e: bool = unimplemented!();\n    let _ = a && b || a;\n    //~^ overly_complex_bool_expr\n\n    let _ = !(a && b);\n    let _ = false && a;\n    //~^ overly_complex_bool_expr\n\n    // don't lint on cfgs\n    let _ = cfg!(you_shall_not_not_pass) && a;\n    let _ = a || !b || !c || !d || !e;\n    let _ = !(a && b || c);\n}\n\nfn equality_stuff() {\n    let a: i32 = unimplemented!();\n    let b: i32 = unimplemented!();\n    let _ = a == b && a != b;\n    //~^ overly_complex_bool_expr\n\n    let _ = a < b && a >= b;\n    //~^ overly_complex_bool_expr\n\n    let _ = a > b && a <= b;\n    //~^ overly_complex_bool_expr\n\n    let _ = a > b && a == b;\n}\n\nfn check_expect() {\n    let a: i32 = unimplemented!();\n    let b: i32 = unimplemented!();\n    #[expect(clippy::overly_complex_bool_expr)]\n    let _ = a < b && a >= b;\n}\n\n#[allow(clippy::never_loop)]\nfn check_never_type() {\n    loop {\n        _ = (break) || true;\n    }\n    loop {\n        _ = (return) || true;\n    }\n}\n"
  },
  {
    "path": "tests/ui/overly_complex_bool_expr.stderr",
    "content": "error: this boolean expression contains a logic bug\n  --> tests/ui/overly_complex_bool_expr.rs:10:13\n   |\nLL |     let _ = a && b || a;\n   |             ^^^^^^^^^^^ help: it would look like the following: `a`\n   |\nhelp: this expression can be optimized out by applying boolean operations to the outer expression\n  --> tests/ui/overly_complex_bool_expr.rs:10:18\n   |\nLL |     let _ = a && b || a;\n   |                  ^\n   = note: `-D clippy::overly-complex-bool-expr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::overly_complex_bool_expr)]`\n\nerror: this boolean expression contains a logic bug\n  --> tests/ui/overly_complex_bool_expr.rs:14:13\n   |\nLL |     let _ = false && a;\n   |             ^^^^^^^^^^ help: it would look like the following: `false`\n   |\nhelp: this expression can be optimized out by applying boolean operations to the outer expression\n  --> tests/ui/overly_complex_bool_expr.rs:14:22\n   |\nLL |     let _ = false && a;\n   |                      ^\n\nerror: this boolean expression contains a logic bug\n  --> tests/ui/overly_complex_bool_expr.rs:26:13\n   |\nLL |     let _ = a == b && a != b;\n   |             ^^^^^^^^^^^^^^^^ help: it would look like the following: `false`\n   |\nhelp: this expression can be optimized out by applying boolean operations to the outer expression\n  --> tests/ui/overly_complex_bool_expr.rs:26:13\n   |\nLL |     let _ = a == b && a != b;\n   |             ^^^^^^\n\nerror: this boolean expression contains a logic bug\n  --> tests/ui/overly_complex_bool_expr.rs:29:13\n   |\nLL |     let _ = a < b && a >= b;\n   |             ^^^^^^^^^^^^^^^ help: it would look like the following: `false`\n   |\nhelp: this expression can be optimized out by applying boolean operations to the outer expression\n  --> tests/ui/overly_complex_bool_expr.rs:29:13\n   |\nLL |     let _ = a < b && a >= b;\n   |             ^^^^^\n\nerror: this boolean expression contains a logic bug\n  --> tests/ui/overly_complex_bool_expr.rs:32:13\n   |\nLL |     let _ = a > b && a <= b;\n   |             ^^^^^^^^^^^^^^^ help: it would look like the following: `false`\n   |\nhelp: this expression can be optimized out by applying boolean operations to the outer expression\n  --> tests/ui/overly_complex_bool_expr.rs:32:13\n   |\nLL |     let _ = a > b && a <= b;\n   |             ^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/owned_cow.fixed",
    "content": "#![warn(clippy::owned_cow)]\n\nuse std::borrow::Cow;\nuse std::ffi::{CString, OsString};\nuse std::path::PathBuf;\n\nfn main() {\n    let x: Cow<'static, str> = Cow::Owned(String::from(\"Hi!\"));\n    //~^ ERROR: needlessly owned Cow type\n    let y: Cow<'_, [u8]> = Cow::Owned(vec![]);\n    //~^ ERROR: needlessly owned Cow type\n    let z: Cow<'_, [_]> = Cow::Owned(vec![2_i32]);\n    //~^ ERROR: needlessly owned Cow type\n    let o: Cow<'_, std::ffi::OsStr> = Cow::Owned(OsString::new());\n    //~^ ERROR: needlessly owned Cow type\n    let c: Cow<'_, std::ffi::CStr> = Cow::Owned(CString::new(\"\").unwrap());\n    //~^ ERROR: needlessly owned Cow type\n    let p: Cow<'_, std::path::Path> = Cow::Owned(PathBuf::new());\n    //~^ ERROR: needlessly owned Cow type\n\n    // false positive: borrowed type\n    let b: Cow<'_, str> = Cow::Borrowed(\"Hi!\");\n}\n"
  },
  {
    "path": "tests/ui/owned_cow.rs",
    "content": "#![warn(clippy::owned_cow)]\n\nuse std::borrow::Cow;\nuse std::ffi::{CString, OsString};\nuse std::path::PathBuf;\n\nfn main() {\n    let x: Cow<'static, String> = Cow::Owned(String::from(\"Hi!\"));\n    //~^ ERROR: needlessly owned Cow type\n    let y: Cow<'_, Vec<u8>> = Cow::Owned(vec![]);\n    //~^ ERROR: needlessly owned Cow type\n    let z: Cow<'_, Vec<_>> = Cow::Owned(vec![2_i32]);\n    //~^ ERROR: needlessly owned Cow type\n    let o: Cow<'_, OsString> = Cow::Owned(OsString::new());\n    //~^ ERROR: needlessly owned Cow type\n    let c: Cow<'_, CString> = Cow::Owned(CString::new(\"\").unwrap());\n    //~^ ERROR: needlessly owned Cow type\n    let p: Cow<'_, PathBuf> = Cow::Owned(PathBuf::new());\n    //~^ ERROR: needlessly owned Cow type\n\n    // false positive: borrowed type\n    let b: Cow<'_, str> = Cow::Borrowed(\"Hi!\");\n}\n"
  },
  {
    "path": "tests/ui/owned_cow.stderr",
    "content": "error: needlessly owned Cow type\n  --> tests/ui/owned_cow.rs:8:25\n   |\nLL |     let x: Cow<'static, String> = Cow::Owned(String::from(\"Hi!\"));\n   |                         ^^^^^^ help: use: `str`\n   |\n   = note: `-D clippy::owned-cow` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::owned_cow)]`\n\nerror: needlessly owned Cow type\n  --> tests/ui/owned_cow.rs:10:20\n   |\nLL |     let y: Cow<'_, Vec<u8>> = Cow::Owned(vec![]);\n   |                    ^^^^^^^ help: use: `[u8]`\n\nerror: needlessly owned Cow type\n  --> tests/ui/owned_cow.rs:12:20\n   |\nLL |     let z: Cow<'_, Vec<_>> = Cow::Owned(vec![2_i32]);\n   |                    ^^^^^^ help: use: `[_]`\n\nerror: needlessly owned Cow type\n  --> tests/ui/owned_cow.rs:14:20\n   |\nLL |     let o: Cow<'_, OsString> = Cow::Owned(OsString::new());\n   |                    ^^^^^^^^ help: use: `std::ffi::OsStr`\n\nerror: needlessly owned Cow type\n  --> tests/ui/owned_cow.rs:16:20\n   |\nLL |     let c: Cow<'_, CString> = Cow::Owned(CString::new(\"\").unwrap());\n   |                    ^^^^^^^ help: use: `std::ffi::CStr`\n\nerror: needlessly owned Cow type\n  --> tests/ui/owned_cow.rs:18:20\n   |\nLL |     let p: Cow<'_, PathBuf> = Cow::Owned(PathBuf::new());\n   |                    ^^^^^^^ help: use: `std::path::Path`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/panic_in_result_fn.rs",
    "content": "#![warn(clippy::panic_in_result_fn)]\n#![allow(clippy::unnecessary_wraps)]\nstruct A;\n\nimpl A {\n    fn result_with_panic() -> Result<bool, String> // should emit lint\n    //~^ panic_in_result_fn\n    {\n        panic!(\"error\");\n    }\n\n    fn result_with_unimplemented() -> Result<bool, String> // should emit lint\n    {\n        unimplemented!();\n    }\n\n    fn result_with_unreachable() -> Result<bool, String> // should emit lint\n    {\n        unreachable!();\n    }\n\n    fn result_with_todo() -> Result<bool, String> // should emit lint\n    {\n        todo!(\"Finish this\");\n    }\n\n    fn other_with_panic() // should not emit lint\n    {\n        panic!(\"\");\n    }\n\n    fn other_with_unreachable() // should not emit lint\n    {\n        unreachable!();\n    }\n\n    fn other_with_unimplemented() // should not emit lint\n    {\n        unimplemented!();\n    }\n\n    fn other_with_todo() // should not emit lint\n    {\n        todo!(\"finish this\")\n    }\n\n    fn result_without_banned_functions() -> Result<bool, String> // should not emit lint\n    {\n        Ok(true)\n    }\n}\n\nfn function_result_with_panic() -> Result<bool, String> // should emit lint\n//~^ panic_in_result_fn\n{\n    panic!(\"error\");\n}\n\nfn in_closure() -> Result<bool, String> {\n    //~^ panic_in_result_fn\n    let c = || panic!();\n    c()\n}\n\nfn todo() {\n    println!(\"something\");\n}\n\nfn function_result_with_custom_todo() -> Result<bool, String> // should not emit lint\n{\n    todo();\n    Ok(true)\n}\n\nfn issue_13381<const N: usize>() -> Result<(), String> {\n    const {\n        if N == 0 {\n            panic!();\n        }\n    }\n    Ok(())\n}\n\nfn main() -> Result<(), String> {\n    todo!(\"finish main method\");\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/panic_in_result_fn.stderr",
    "content": "error: used `panic!()` or assertion in a function that returns `Result`\n  --> tests/ui/panic_in_result_fn.rs:6:5\n   |\nLL | /     fn result_with_panic() -> Result<bool, String> // should emit lint\nLL | |\nLL | |     {\nLL | |         panic!(\"error\");\nLL | |     }\n   | |_____^\n   |\n   = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing\nnote: return Err() instead of panicking\n  --> tests/ui/panic_in_result_fn.rs:9:9\n   |\nLL |         panic!(\"error\");\n   |         ^^^^^^^^^^^^^^^\n   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]`\n\nerror: used `panic!()` or assertion in a function that returns `Result`\n  --> tests/ui/panic_in_result_fn.rs:53:1\n   |\nLL | / fn function_result_with_panic() -> Result<bool, String> // should emit lint\nLL | |\nLL | | {\nLL | |     panic!(\"error\");\nLL | | }\n   | |_^\n   |\n   = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing\nnote: return Err() instead of panicking\n  --> tests/ui/panic_in_result_fn.rs:56:5\n   |\nLL |     panic!(\"error\");\n   |     ^^^^^^^^^^^^^^^\n\nerror: used `panic!()` or assertion in a function that returns `Result`\n  --> tests/ui/panic_in_result_fn.rs:59:1\n   |\nLL | / fn in_closure() -> Result<bool, String> {\nLL | |\nLL | |     let c = || panic!();\nLL | |     c()\nLL | | }\n   | |_^\n   |\n   = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing\nnote: return Err() instead of panicking\n  --> tests/ui/panic_in_result_fn.rs:61:16\n   |\nLL |     let c = || panic!();\n   |                ^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/panic_in_result_fn_assertions.rs",
    "content": "#![warn(clippy::panic_in_result_fn)]\n#![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)]\n\nstruct A;\n\nimpl A {\n    fn result_with_assert_with_message(x: i32) -> Result<bool, String> // should emit lint\n    //~^ panic_in_result_fn\n    {\n        assert!(x == 5, \"wrong argument\");\n        Ok(true)\n    }\n\n    fn result_with_assert_eq(x: i32) -> Result<bool, String> // should emit lint\n    //~^ panic_in_result_fn\n    {\n        assert_eq!(x, 5);\n        Ok(true)\n    }\n\n    fn result_with_assert_ne(x: i32) -> Result<bool, String> // should emit lint\n    //~^ panic_in_result_fn\n    {\n        assert_ne!(x, 1);\n        Ok(true)\n    }\n\n    fn other_with_assert_with_message(x: i32) // should not emit lint\n    {\n        assert!(x == 5, \"wrong argument\");\n    }\n\n    fn other_with_assert_eq(x: i32) // should not emit lint\n    {\n        assert_eq!(x, 5);\n    }\n\n    fn other_with_assert_ne(x: i32) // should not emit lint\n    {\n        assert_ne!(x, 1);\n    }\n\n    fn result_without_banned_functions() -> Result<bool, String> // should not emit lint\n    {\n        let assert = \"assert!\";\n        println!(\"No {}\", assert);\n        Ok(true)\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/panic_in_result_fn_assertions.stderr",
    "content": "error: used `panic!()` or assertion in a function that returns `Result`\n  --> tests/ui/panic_in_result_fn_assertions.rs:7:5\n   |\nLL | /     fn result_with_assert_with_message(x: i32) -> Result<bool, String> // should emit lint\nLL | |\nLL | |     {\nLL | |         assert!(x == 5, \"wrong argument\");\nLL | |         Ok(true)\nLL | |     }\n   | |_____^\n   |\n   = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing\nnote: return Err() instead of panicking\n  --> tests/ui/panic_in_result_fn_assertions.rs:10:9\n   |\nLL |         assert!(x == 5, \"wrong argument\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::panic-in-result-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::panic_in_result_fn)]`\n\nerror: used `panic!()` or assertion in a function that returns `Result`\n  --> tests/ui/panic_in_result_fn_assertions.rs:14:5\n   |\nLL | /     fn result_with_assert_eq(x: i32) -> Result<bool, String> // should emit lint\nLL | |\nLL | |     {\nLL | |         assert_eq!(x, 5);\nLL | |         Ok(true)\nLL | |     }\n   | |_____^\n   |\n   = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing\nnote: return Err() instead of panicking\n  --> tests/ui/panic_in_result_fn_assertions.rs:17:9\n   |\nLL |         assert_eq!(x, 5);\n   |         ^^^^^^^^^^^^^^^^\n\nerror: used `panic!()` or assertion in a function that returns `Result`\n  --> tests/ui/panic_in_result_fn_assertions.rs:21:5\n   |\nLL | /     fn result_with_assert_ne(x: i32) -> Result<bool, String> // should emit lint\nLL | |\nLL | |     {\nLL | |         assert_ne!(x, 1);\nLL | |         Ok(true)\nLL | |     }\n   | |_____^\n   |\n   = help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing\nnote: return Err() instead of panicking\n  --> tests/ui/panic_in_result_fn_assertions.rs:24:9\n   |\nLL |         assert_ne!(x, 1);\n   |         ^^^^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/panic_in_result_fn_debug_assertions.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::panic_in_result_fn)]\n#![allow(clippy::uninlined_format_args, clippy::unnecessary_wraps)]\n\n// debug_assert should never trigger the `panic_in_result_fn` lint\n\nstruct A;\n\nimpl A {\n    fn result_with_debug_assert_with_message(x: i32) -> Result<bool, String> {\n        debug_assert!(x == 5, \"wrong argument\");\n        Ok(true)\n    }\n\n    fn result_with_debug_assert_eq(x: i32) -> Result<bool, String> {\n        debug_assert_eq!(x, 5);\n        Ok(true)\n    }\n\n    fn result_with_debug_assert_ne(x: i32) -> Result<bool, String> {\n        debug_assert_ne!(x, 1);\n        Ok(true)\n    }\n\n    fn other_with_debug_assert_with_message(x: i32) {\n        debug_assert!(x == 5, \"wrong argument\");\n    }\n\n    fn other_with_debug_assert_eq(x: i32) {\n        debug_assert_eq!(x, 5);\n    }\n\n    fn other_with_debug_assert_ne(x: i32) {\n        debug_assert_ne!(x, 1);\n    }\n\n    fn result_without_banned_functions() -> Result<bool, String> {\n        let debug_assert = \"debug_assert!\";\n        println!(\"No {}\", debug_assert);\n        Ok(true)\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/panicking_macros.rs",
    "content": "#![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::let_unit_value)]\n#![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]\n\nextern crate core;\n\nconst _: () = {\n    if 1 == 0 {\n        panic!(\"A balanced diet means a cupcake in each hand\");\n    }\n};\n\nfn inline_const() {\n    let _ = const {\n        if 1 == 0 {\n            panic!(\"When nothing goes right, go left\")\n        }\n    };\n}\n\nfn panic() {\n    let a = 2;\n    panic!();\n    //~^ panic\n\n    panic!(\"message\");\n    //~^ panic\n\n    panic!(\"{} {}\", \"panic with\", \"multiple arguments\");\n    //~^ panic\n\n    let b = a + 2;\n}\n\nconst fn panic_const() {\n    let a = 2;\n    panic!();\n    //~^ panic\n\n    panic!(\"message\");\n    //~^ panic\n\n    panic!(\"{} {}\", \"panic with\", \"multiple arguments\");\n    //~^ panic\n\n    let b = a + 2;\n}\n\nfn todo() {\n    let a = 2;\n    todo!();\n    //~^ todo\n\n    todo!(\"message\");\n    //~^ todo\n\n    todo!(\"{} {}\", \"panic with\", \"multiple arguments\");\n    //~^ todo\n\n    let b = a + 2;\n}\n\nfn unimplemented() {\n    let a = 2;\n    unimplemented!();\n    //~^ unimplemented\n\n    unimplemented!(\"message\");\n    //~^ unimplemented\n\n    unimplemented!(\"{} {}\", \"panic with\", \"multiple arguments\");\n    //~^ unimplemented\n\n    let b = a + 2;\n}\n\nfn unreachable() {\n    let a = 2;\n    unreachable!();\n    //~^ unreachable\n\n    unreachable!(\"message\");\n    //~^ unreachable\n\n    unreachable!(\"{} {}\", \"panic with\", \"multiple arguments\");\n    //~^ unreachable\n\n    let b = a + 2;\n}\n\nfn core_versions() {\n    use core::{panic, todo, unimplemented, unreachable};\n    panic!();\n    //~^ panic\n\n    todo!();\n    //~^ todo\n\n    unimplemented!();\n    //~^ unimplemented\n\n    unreachable!();\n    //~^ unreachable\n}\n\nfn assert() {\n    assert!(true);\n    assert_eq!(true, true);\n    assert_ne!(true, false);\n}\n\nfn assert_msg() {\n    assert!(true, \"this should not panic\");\n    assert_eq!(true, true, \"this should not panic\");\n    assert_ne!(true, false, \"this should not panic\");\n}\n\nfn debug_assert() {\n    debug_assert!(true);\n    debug_assert_eq!(true, true);\n    debug_assert_ne!(true, false);\n}\n\nfn debug_assert_msg() {\n    debug_assert!(true, \"test\");\n    debug_assert_eq!(true, true, \"test\");\n    debug_assert_ne!(true, false, \"test\");\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/panicking_macros.stderr",
    "content": "error: `panic` should not be present in production code\n  --> tests/ui/panicking_macros.rs:22:5\n   |\nLL |     panic!();\n   |     ^^^^^^^^\n   |\n   = note: `-D clippy::panic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::panic)]`\n\nerror: `panic` should not be present in production code\n  --> tests/ui/panicking_macros.rs:25:5\n   |\nLL |     panic!(\"message\");\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: `panic` should not be present in production code\n  --> tests/ui/panicking_macros.rs:28:5\n   |\nLL |     panic!(\"{} {}\", \"panic with\", \"multiple arguments\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `panic` should not be present in production code\n  --> tests/ui/panicking_macros.rs:36:5\n   |\nLL |     panic!();\n   |     ^^^^^^^^\n\nerror: `panic` should not be present in production code\n  --> tests/ui/panicking_macros.rs:39:5\n   |\nLL |     panic!(\"message\");\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: `panic` should not be present in production code\n  --> tests/ui/panicking_macros.rs:42:5\n   |\nLL |     panic!(\"{} {}\", \"panic with\", \"multiple arguments\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `todo` should not be present in production code\n  --> tests/ui/panicking_macros.rs:50:5\n   |\nLL |     todo!();\n   |     ^^^^^^^\n   |\n   = note: `-D clippy::todo` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::todo)]`\n\nerror: `todo` should not be present in production code\n  --> tests/ui/panicking_macros.rs:53:5\n   |\nLL |     todo!(\"message\");\n   |     ^^^^^^^^^^^^^^^^\n\nerror: `todo` should not be present in production code\n  --> tests/ui/panicking_macros.rs:56:5\n   |\nLL |     todo!(\"{} {}\", \"panic with\", \"multiple arguments\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `unimplemented` should not be present in production code\n  --> tests/ui/panicking_macros.rs:64:5\n   |\nLL |     unimplemented!();\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unimplemented` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unimplemented)]`\n\nerror: `unimplemented` should not be present in production code\n  --> tests/ui/panicking_macros.rs:67:5\n   |\nLL |     unimplemented!(\"message\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `unimplemented` should not be present in production code\n  --> tests/ui/panicking_macros.rs:70:5\n   |\nLL |     unimplemented!(\"{} {}\", \"panic with\", \"multiple arguments\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: usage of the `unreachable!` macro\n  --> tests/ui/panicking_macros.rs:78:5\n   |\nLL |     unreachable!();\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unreachable` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unreachable)]`\n\nerror: usage of the `unreachable!` macro\n  --> tests/ui/panicking_macros.rs:81:5\n   |\nLL |     unreachable!(\"message\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: usage of the `unreachable!` macro\n  --> tests/ui/panicking_macros.rs:84:5\n   |\nLL |     unreachable!(\"{} {}\", \"panic with\", \"multiple arguments\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `panic` should not be present in production code\n  --> tests/ui/panicking_macros.rs:92:5\n   |\nLL |     panic!();\n   |     ^^^^^^^^\n\nerror: `todo` should not be present in production code\n  --> tests/ui/panicking_macros.rs:95:5\n   |\nLL |     todo!();\n   |     ^^^^^^^\n\nerror: `unimplemented` should not be present in production code\n  --> tests/ui/panicking_macros.rs:98:5\n   |\nLL |     unimplemented!();\n   |     ^^^^^^^^^^^^^^^^\n\nerror: usage of the `unreachable!` macro\n  --> tests/ui/panicking_macros.rs:101:5\n   |\nLL |     unreachable!();\n   |     ^^^^^^^^^^^^^^\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/panicking_overflow_checks.rs",
    "content": "#![warn(clippy::panicking_overflow_checks)]\n#![allow(clippy::needless_ifs)]\n\nfn test(a: u32, b: u32, c: u32) {\n    if a + b < a {}\n    //~^ panicking_overflow_checks\n    if a > a + b {}\n    //~^ panicking_overflow_checks\n    if a + b < b {}\n    //~^ panicking_overflow_checks\n    if b > a + b {}\n    //~^ panicking_overflow_checks\n    if a - b > b {}\n    if b < a - b {}\n    if a - b > a {}\n    //~^ panicking_overflow_checks\n    if a < a - b {}\n    //~^ panicking_overflow_checks\n    if a + b < c {}\n    if c > a + b {}\n    if a - b < c {}\n    if c > a - b {}\n    let i = 1.1;\n    let j = 2.2;\n    if i + j < i {}\n    if i - j < i {}\n    if i > i + j {}\n    if i - j < i {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/panicking_overflow_checks.stderr",
    "content": "error: you are trying to use classic C overflow conditions that will fail in Rust\n  --> tests/ui/panicking_overflow_checks.rs:5:8\n   |\nLL |     if a + b < a {}\n   |        ^^^^^^^^^\n   |\n   = note: `-D clippy::panicking-overflow-checks` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::panicking_overflow_checks)]`\n\nerror: you are trying to use classic C overflow conditions that will fail in Rust\n  --> tests/ui/panicking_overflow_checks.rs:7:8\n   |\nLL |     if a > a + b {}\n   |        ^^^^^^^^^\n\nerror: you are trying to use classic C overflow conditions that will fail in Rust\n  --> tests/ui/panicking_overflow_checks.rs:9:8\n   |\nLL |     if a + b < b {}\n   |        ^^^^^^^^^\n\nerror: you are trying to use classic C overflow conditions that will fail in Rust\n  --> tests/ui/panicking_overflow_checks.rs:11:8\n   |\nLL |     if b > a + b {}\n   |        ^^^^^^^^^\n\nerror: you are trying to use classic C overflow conditions that will fail in Rust\n  --> tests/ui/panicking_overflow_checks.rs:15:8\n   |\nLL |     if a - b > a {}\n   |        ^^^^^^^^^\n\nerror: you are trying to use classic C overflow conditions that will fail in Rust\n  --> tests/ui/panicking_overflow_checks.rs:17:8\n   |\nLL |     if a < a - b {}\n   |        ^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/partial_pub_fields.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::partial_pub_fields)]\n\nfn main() {\n    use std::collections::HashMap;\n\n    #[derive(Default)]\n    pub struct FileSet {\n        files: HashMap<String, u32>,\n        pub paths: HashMap<u32, String>,\n        //~^ partial_pub_fields\n    }\n\n    pub struct Color {\n        pub r: u8,\n        pub g: u8,\n        b: u8,\n        //~^ partial_pub_fields\n    }\n\n    pub struct Point(i32, pub i32);\n    //~^ partial_pub_fields\n\n    pub struct Visibility {\n        r#pub: bool,\n        pub pos: u32,\n        //~^ partial_pub_fields\n    }\n\n    // Don't lint on empty structs;\n    pub struct Empty1;\n    pub struct Empty2();\n    pub struct Empty3 {};\n\n    // Don't lint on structs with one field.\n    pub struct Single1(i32);\n    pub struct Single2(pub i32);\n    pub struct Single3 {\n        v1: i32,\n    }\n    pub struct Single4 {\n        pub v1: i32,\n    }\n}\n"
  },
  {
    "path": "tests/ui/partial_pub_fields.stderr",
    "content": "error: mixed usage of pub and non-pub fields\n  --> tests/ui/partial_pub_fields.rs:10:9\n   |\nLL |         pub paths: HashMap<u32, String>,\n   |         ^^^\n   |\n   = help: consider using private field here\n   = note: `-D clippy::partial-pub-fields` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::partial_pub_fields)]`\n\nerror: mixed usage of pub and non-pub fields\n  --> tests/ui/partial_pub_fields.rs:17:9\n   |\nLL |         b: u8,\n   |         ^\n   |\n   = help: consider using public field here\n\nerror: mixed usage of pub and non-pub fields\n  --> tests/ui/partial_pub_fields.rs:21:27\n   |\nLL |     pub struct Point(i32, pub i32);\n   |                           ^^^\n   |\n   = help: consider using private field here\n\nerror: mixed usage of pub and non-pub fields\n  --> tests/ui/partial_pub_fields.rs:26:9\n   |\nLL |         pub pos: u32,\n   |         ^^^\n   |\n   = help: consider using private field here\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/partialeq_ne_impl.rs",
    "content": "#![allow(dead_code)]\n\nstruct Foo;\n\nimpl PartialEq for Foo {\n    fn eq(&self, _: &Foo) -> bool {\n        true\n    }\n    fn ne(&self, _: &Foo) -> bool {\n        //~^ partialeq_ne_impl\n\n        false\n    }\n}\n\nstruct Bar;\n\nimpl PartialEq for Bar {\n    fn eq(&self, _: &Bar) -> bool {\n        true\n    }\n    #[allow(clippy::partialeq_ne_impl)]\n    fn ne(&self, _: &Bar) -> bool {\n        false\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/partialeq_ne_impl.stderr",
    "content": "error: re-implementing `PartialEq::ne` is unnecessary\n  --> tests/ui/partialeq_ne_impl.rs:9:5\n   |\nLL |     fn ne(&self, _: &Foo) -> bool {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::partialeq-ne-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::partialeq_ne_impl)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/partialeq_to_none.fixed",
    "content": "#![warn(clippy::partialeq_to_none)]\n#![allow(clippy::eq_op, clippy::needless_ifs)]\n\nstruct Foobar;\n\nimpl PartialEq<Option<()>> for Foobar {\n    fn eq(&self, _: &Option<()>) -> bool {\n        false\n    }\n}\n\n#[allow(dead_code)]\nfn foo(f: Option<u32>) -> &'static str {\n    if f.is_some() { \"yay\" } else { \"nay\" }\n    //~^ partialeq_to_none\n}\n\nfn foobar() -> Option<()> {\n    None\n}\n\nfn bar() -> Result<(), ()> {\n    Ok(())\n}\n\nfn optref() -> &'static &'static Option<()> {\n    &&None\n}\n\npub fn macro_expansion() {\n    macro_rules! foo {\n        () => {\n            None::<()>\n        };\n    }\n\n    let _ = foobar() == foo!();\n    let _ = foo!() == foobar();\n    let _ = foo!() == foo!();\n}\n\nfn main() {\n    let x = Some(0);\n\n    let _ = x.is_none();\n    //~^ partialeq_to_none\n    let _ = x.is_some();\n    //~^ partialeq_to_none\n    let _ = x.is_none();\n    //~^ partialeq_to_none\n    let _ = x.is_some();\n    //~^ partialeq_to_none\n\n    if foobar().is_none() {}\n    //~^ partialeq_to_none\n\n    if bar().ok().is_some() {}\n    //~^ partialeq_to_none\n\n    let _ = Some(1 + 2).is_some();\n    //~^ partialeq_to_none\n\n    let _ = { Some(0) }.is_none();\n    //~^ partialeq_to_none\n\n    let _ = {\n        //~^ partialeq_to_none\n        /*\n          This comment runs long\n        */\n        Some(1)\n    }.is_some();\n\n    // Should not trigger, as `Foobar` is not an `Option` and has no `is_none`\n    let _ = Foobar == None;\n\n    let _ = optref().is_none();\n    //~^ partialeq_to_none\n    let _ = optref().is_some();\n    //~^ partialeq_to_none\n    let _ = optref().is_none();\n    //~^ partialeq_to_none\n    let _ = optref().is_some();\n    //~^ partialeq_to_none\n\n    let x = Box::new(Option::<()>::None);\n    let _ = (*x).is_some();\n    //~^ partialeq_to_none\n}\n"
  },
  {
    "path": "tests/ui/partialeq_to_none.rs",
    "content": "#![warn(clippy::partialeq_to_none)]\n#![allow(clippy::eq_op, clippy::needless_ifs)]\n\nstruct Foobar;\n\nimpl PartialEq<Option<()>> for Foobar {\n    fn eq(&self, _: &Option<()>) -> bool {\n        false\n    }\n}\n\n#[allow(dead_code)]\nfn foo(f: Option<u32>) -> &'static str {\n    if f != None { \"yay\" } else { \"nay\" }\n    //~^ partialeq_to_none\n}\n\nfn foobar() -> Option<()> {\n    None\n}\n\nfn bar() -> Result<(), ()> {\n    Ok(())\n}\n\nfn optref() -> &'static &'static Option<()> {\n    &&None\n}\n\npub fn macro_expansion() {\n    macro_rules! foo {\n        () => {\n            None::<()>\n        };\n    }\n\n    let _ = foobar() == foo!();\n    let _ = foo!() == foobar();\n    let _ = foo!() == foo!();\n}\n\nfn main() {\n    let x = Some(0);\n\n    let _ = x == None;\n    //~^ partialeq_to_none\n    let _ = x != None;\n    //~^ partialeq_to_none\n    let _ = None == x;\n    //~^ partialeq_to_none\n    let _ = None != x;\n    //~^ partialeq_to_none\n\n    if foobar() == None {}\n    //~^ partialeq_to_none\n\n    if bar().ok() != None {}\n    //~^ partialeq_to_none\n\n    let _ = Some(1 + 2) != None;\n    //~^ partialeq_to_none\n\n    let _ = { Some(0) } == None;\n    //~^ partialeq_to_none\n\n    let _ = {\n        //~^ partialeq_to_none\n        /*\n          This comment runs long\n        */\n        Some(1)\n    } != None;\n\n    // Should not trigger, as `Foobar` is not an `Option` and has no `is_none`\n    let _ = Foobar == None;\n\n    let _ = optref() == &&None;\n    //~^ partialeq_to_none\n    let _ = &&None != optref();\n    //~^ partialeq_to_none\n    let _ = **optref() == None;\n    //~^ partialeq_to_none\n    let _ = &None != *optref();\n    //~^ partialeq_to_none\n\n    let x = Box::new(Option::<()>::None);\n    let _ = None != *x;\n    //~^ partialeq_to_none\n}\n"
  },
  {
    "path": "tests/ui/partialeq_to_none.stderr",
    "content": "error: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:14:8\n   |\nLL |     if f != None { \"yay\" } else { \"nay\" }\n   |        ^^^^^^^^^ help: use `Option::is_some()` instead: `f.is_some()`\n   |\n   = note: `-D clippy::partialeq-to-none` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::partialeq_to_none)]`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:45:13\n   |\nLL |     let _ = x == None;\n   |             ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:47:13\n   |\nLL |     let _ = x != None;\n   |             ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:49:13\n   |\nLL |     let _ = None == x;\n   |             ^^^^^^^^^ help: use `Option::is_none()` instead: `x.is_none()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:51:13\n   |\nLL |     let _ = None != x;\n   |             ^^^^^^^^^ help: use `Option::is_some()` instead: `x.is_some()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:54:8\n   |\nLL |     if foobar() == None {}\n   |        ^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `foobar().is_none()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:57:8\n   |\nLL |     if bar().ok() != None {}\n   |        ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `bar().ok().is_some()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:60:13\n   |\nLL |     let _ = Some(1 + 2) != None;\n   |             ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `Some(1 + 2).is_some()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:63:13\n   |\nLL |     let _ = { Some(0) } == None;\n   |             ^^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `{ Some(0) }.is_none()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:66:13\n   |\nLL |       let _ = {\n   |  _____________^\nLL | |\nLL | |         /*\nLL | |           This comment runs long\nLL | |         */\nLL | |         Some(1)\nLL | |     } != None;\n   | |_____________^\n   |\nhelp: use `Option::is_some()` instead\n   |\nLL ~     let _ = {\nLL +\nLL +         /*\nLL +           This comment runs long\nLL +         */\nLL +         Some(1)\nLL ~     }.is_some();\n   |\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:77:13\n   |\nLL |     let _ = optref() == &&None;\n   |             ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:79:13\n   |\nLL |     let _ = &&None != optref();\n   |             ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:81:13\n   |\nLL |     let _ = **optref() == None;\n   |             ^^^^^^^^^^^^^^^^^^ help: use `Option::is_none()` instead: `optref().is_none()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:83:13\n   |\nLL |     let _ = &None != *optref();\n   |             ^^^^^^^^^^^^^^^^^^ help: use `Option::is_some()` instead: `optref().is_some()`\n\nerror: binary comparison to literal `Option::None`\n  --> tests/ui/partialeq_to_none.rs:87:13\n   |\nLL |     let _ = None != *x;\n   |             ^^^^^^^^^^ help: use `Option::is_some()` instead: `(*x).is_some()`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/path_buf_push_overwrite.fixed",
    "content": "use std::path::PathBuf;\n\n#[warn(clippy::path_buf_push_overwrite)]\n#[allow(clippy::pathbuf_init_then_push)]\nfn main() {\n    let mut x = PathBuf::from(\"/foo\");\n    x.push(\"bar\");\n    //~^ path_buf_push_overwrite\n}\n"
  },
  {
    "path": "tests/ui/path_buf_push_overwrite.rs",
    "content": "use std::path::PathBuf;\n\n#[warn(clippy::path_buf_push_overwrite)]\n#[allow(clippy::pathbuf_init_then_push)]\nfn main() {\n    let mut x = PathBuf::from(\"/foo\");\n    x.push(\"/bar\");\n    //~^ path_buf_push_overwrite\n}\n"
  },
  {
    "path": "tests/ui/path_buf_push_overwrite.stderr",
    "content": "error: calling `push` with '/' or '\\' (file system root) will overwrite the previous path definition\n  --> tests/ui/path_buf_push_overwrite.rs:7:12\n   |\nLL |     x.push(\"/bar\");\n   |            ^^^^^^ help: try: `\"bar\"`\n   |\n   = note: `-D clippy::path-buf-push-overwrite` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::path_buf_push_overwrite)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/path_ends_with_ext.fixed",
    "content": "#![warn(clippy::path_ends_with_ext)]\nuse std::path::Path;\n\nmacro_rules! arg {\n    () => {\n        \".md\"\n    };\n}\n\nfn test(path: &Path) {\n    path.extension().is_some_and(|ext| ext == \"md\");\n    //~^ path_ends_with_ext\n\n    // some \"extensions\" are allowed by default\n    path.ends_with(\".git\");\n\n    // most legitimate \"dotfiles\" are longer than 3 chars, so we allow them as well\n    path.ends_with(\".bashrc\");\n\n    // argument from expn shouldn't trigger\n    path.ends_with(arg!());\n\n    path.ends_with(\"..\");\n    path.ends_with(\"./a\");\n    path.ends_with(\".\");\n    path.ends_with(\"\");\n}\n\n// is_some_and was stabilized in 1.70, so suggest map_or(false, ..) if under that\n#[clippy::msrv = \"1.69\"]\nfn under_msv(path: &Path) -> bool {\n    path.extension().map_or(false, |ext| ext == \"md\")\n    //~^ path_ends_with_ext\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/path_ends_with_ext.rs",
    "content": "#![warn(clippy::path_ends_with_ext)]\nuse std::path::Path;\n\nmacro_rules! arg {\n    () => {\n        \".md\"\n    };\n}\n\nfn test(path: &Path) {\n    path.ends_with(\".md\");\n    //~^ path_ends_with_ext\n\n    // some \"extensions\" are allowed by default\n    path.ends_with(\".git\");\n\n    // most legitimate \"dotfiles\" are longer than 3 chars, so we allow them as well\n    path.ends_with(\".bashrc\");\n\n    // argument from expn shouldn't trigger\n    path.ends_with(arg!());\n\n    path.ends_with(\"..\");\n    path.ends_with(\"./a\");\n    path.ends_with(\".\");\n    path.ends_with(\"\");\n}\n\n// is_some_and was stabilized in 1.70, so suggest map_or(false, ..) if under that\n#[clippy::msrv = \"1.69\"]\nfn under_msv(path: &Path) -> bool {\n    path.ends_with(\".md\")\n    //~^ path_ends_with_ext\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/path_ends_with_ext.stderr",
    "content": "error: this looks like a failed attempt at checking for the file extension\n  --> tests/ui/path_ends_with_ext.rs:11:5\n   |\nLL |     path.ends_with(\".md\");\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().is_some_and(|ext| ext == \"md\")`\n   |\n   = note: `-D clippy::path-ends-with-ext` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::path_ends_with_ext)]`\n\nerror: this looks like a failed attempt at checking for the file extension\n  --> tests/ui/path_ends_with_ext.rs:32:5\n   |\nLL |     path.ends_with(\".md\")\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().map_or(false, |ext| ext == \"md\")`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/pathbuf_init_then_push.fixed",
    "content": "#![warn(clippy::pathbuf_init_then_push)]\n\nuse std::path::PathBuf;\n\nfn main() {\n    let mut path_buf = PathBuf::from(\"foo\");\n\n    path_buf = PathBuf::from(\"foo\").join(\"bar\");\n\n    let bar = \"bar\";\n    path_buf = PathBuf::from(\"foo\").join(bar);\n\n    let mut path_buf = PathBuf::from(\"foo\").join(\"bar\").join(\"buz\");\n\n    let mut x = PathBuf::new();\n    println!(\"{}\", x.display());\n    x.push(\"Duck\");\n\n    let mut path_buf = PathBuf::new();\n    #[cfg(cats)]\n    path_buf.push(\"foo\");\n}\n"
  },
  {
    "path": "tests/ui/pathbuf_init_then_push.rs",
    "content": "#![warn(clippy::pathbuf_init_then_push)]\n\nuse std::path::PathBuf;\n\nfn main() {\n    let mut path_buf = PathBuf::new();\n    //~^ pathbuf_init_then_push\n    path_buf.push(\"foo\");\n\n    path_buf = PathBuf::from(\"foo\");\n    //~^ pathbuf_init_then_push\n    path_buf.push(\"bar\");\n\n    let bar = \"bar\";\n    path_buf = PathBuf::from(\"foo\");\n    //~^ pathbuf_init_then_push\n    path_buf.push(bar);\n\n    let mut path_buf = PathBuf::from(\"foo\").join(\"bar\");\n    //~^ pathbuf_init_then_push\n    path_buf.push(\"buz\");\n\n    let mut x = PathBuf::new();\n    println!(\"{}\", x.display());\n    x.push(\"Duck\");\n\n    let mut path_buf = PathBuf::new();\n    #[cfg(cats)]\n    path_buf.push(\"foo\");\n}\n"
  },
  {
    "path": "tests/ui/pathbuf_init_then_push.stderr",
    "content": "error: calls to `push` immediately after creation\n  --> tests/ui/pathbuf_init_then_push.rs:6:5\n   |\nLL | /     let mut path_buf = PathBuf::new();\nLL | |\nLL | |     path_buf.push(\"foo\");\n   | |_________________________^ help: consider using the `.join()`: `let mut path_buf = PathBuf::from(\"foo\");`\n   |\n   = note: `-D clippy::pathbuf-init-then-push` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pathbuf_init_then_push)]`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/pathbuf_init_then_push.rs:10:5\n   |\nLL | /     path_buf = PathBuf::from(\"foo\");\nLL | |\nLL | |     path_buf.push(\"bar\");\n   | |_________________________^ help: consider using the `.join()`: `path_buf = PathBuf::from(\"foo\").join(\"bar\");`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/pathbuf_init_then_push.rs:15:5\n   |\nLL | /     path_buf = PathBuf::from(\"foo\");\nLL | |\nLL | |     path_buf.push(bar);\n   | |_______________________^ help: consider using the `.join()`: `path_buf = PathBuf::from(\"foo\").join(bar);`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/pathbuf_init_then_push.rs:19:5\n   |\nLL | /     let mut path_buf = PathBuf::from(\"foo\").join(\"bar\");\nLL | |\nLL | |     path_buf.push(\"buz\");\n   | |_________________________^ help: consider using the `.join()`: `let mut path_buf = PathBuf::from(\"foo\").join(\"bar\").join(\"buz\");`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/auxiliary/external.rs",
    "content": "//! **FAKE** external macro crate.\n\n#[macro_export]\nmacro_rules! macro_with_match {\n    ( $p:pat ) => {\n        let something = ();\n\n        match &something {\n            $p => true,\n            _ => false,\n        }\n    };\n}\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/mutability.rs",
    "content": "#![warn(clippy::pattern_type_mismatch)]\n#![allow(clippy::single_match)]\n\nfn main() {}\n\nfn should_lint() {\n    let value = &Some(23);\n    match value {\n        Some(_) => (),\n        //~^ pattern_type_mismatch\n        _ => (),\n    }\n\n    let value = &mut Some(23);\n    match value {\n        Some(_) => (),\n        //~^ pattern_type_mismatch\n        _ => (),\n    }\n}\n\nfn should_not_lint() {\n    let value = &Some(23);\n    match value {\n        &Some(_) => (),\n        _ => (),\n    }\n    match *value {\n        Some(_) => (),\n        _ => (),\n    }\n\n    let value = &mut Some(23);\n    match value {\n        &mut Some(_) => (),\n        _ => (),\n    }\n    match *value {\n        Some(_) => (),\n        _ => (),\n    }\n\n    const FOO: &str = \"foo\";\n\n    fn foo(s: &str) -> i32 {\n        match s {\n            FOO => 1,\n            _ => 0,\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/mutability.stderr",
    "content": "error: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/mutability.rs:9:9\n   |\nLL |         Some(_) => (),\n   |         ^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/mutability.rs:16:9\n   |\nLL |         Some(_) => (),\n   |         ^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&mut _` pattern and adjust the enclosed variable bindings\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/pattern_alternatives.rs",
    "content": "#![warn(clippy::pattern_type_mismatch)]\n\nfn main() {}\n\nfn alternatives() {\n    enum Value<'a> {\n        Unused,\n        A(&'a Option<i32>),\n        B,\n    }\n    let ref_value = &Value::A(&Some(23));\n\n    // not ok\n    if let Value::B | Value::A(_) = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let &Value::B | &Value::A(Some(_)) = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let Value::B | Value::A(Some(_)) = *ref_value {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    if let &Value::B | &Value::A(_) = ref_value {}\n    if let Value::B | Value::A(_) = *ref_value {}\n    if let &Value::B | &Value::A(&Some(_)) = ref_value {}\n    if let Value::B | Value::A(&Some(_)) = *ref_value {}\n}\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/pattern_alternatives.stderr",
    "content": "error: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_alternatives.rs:14:12\n   |\nLL |     if let Value::B | Value::A(_) = ref_value {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_alternatives.rs:17:34\n   |\nLL |     if let &Value::B | &Value::A(Some(_)) = ref_value {}\n   |                                  ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_alternatives.rs:20:32\n   |\nLL |     if let Value::B | Value::A(Some(_)) = *ref_value {}\n   |                                ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/pattern_structs.rs",
    "content": "#![warn(clippy::pattern_type_mismatch)]\n\nfn main() {}\n\nfn struct_types() {\n    struct Struct<'a> {\n        ref_inner: &'a Option<i32>,\n    }\n    let ref_value = &Struct { ref_inner: &Some(42) };\n\n    // not ok\n    let Struct { .. } = ref_value;\n    //~^ pattern_type_mismatch\n\n    if let &Struct { ref_inner: Some(_) } = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let Struct { ref_inner: Some(_) } = *ref_value {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    let &Struct { .. } = ref_value;\n    let Struct { .. } = *ref_value;\n    if let &Struct { ref_inner: &Some(_) } = ref_value {}\n    if let Struct { ref_inner: &Some(_) } = *ref_value {}\n}\n\nfn struct_enum_variants() {\n    enum StructEnum<'a> {\n        Empty,\n        Var { inner_ref: &'a Option<i32> },\n    }\n    let ref_value = &StructEnum::Var { inner_ref: &Some(42) };\n\n    // not ok\n    if let StructEnum::Var { .. } = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let StructEnum::Var { inner_ref: Some(_) } = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let StructEnum::Empty = ref_value {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    if let &StructEnum::Var { .. } = ref_value {}\n    if let StructEnum::Var { .. } = *ref_value {}\n    if let &StructEnum::Var { inner_ref: &Some(_) } = ref_value {}\n    if let StructEnum::Var { inner_ref: &Some(_) } = *ref_value {}\n    if let &StructEnum::Empty = ref_value {}\n    if let StructEnum::Empty = *ref_value {}\n}\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/pattern_structs.stderr",
    "content": "error: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_structs.rs:12:9\n   |\nLL |     let Struct { .. } = ref_value;\n   |         ^^^^^^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_structs.rs:15:33\n   |\nLL |     if let &Struct { ref_inner: Some(_) } = ref_value {}\n   |                                 ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_structs.rs:18:32\n   |\nLL |     if let Struct { ref_inner: Some(_) } = *ref_value {}\n   |                                ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_structs.rs:36:12\n   |\nLL |     if let StructEnum::Var { .. } = ref_value {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_structs.rs:39:12\n   |\nLL |     if let StructEnum::Var { inner_ref: Some(_) } = ref_value {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_structs.rs:42:42\n   |\nLL |     if let &StructEnum::Var { inner_ref: Some(_) } = ref_value {}\n   |                                          ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_structs.rs:45:41\n   |\nLL |     if let StructEnum::Var { inner_ref: Some(_) } = *ref_value {}\n   |                                         ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_structs.rs:48:12\n   |\nLL |     if let StructEnum::Empty = ref_value {}\n   |            ^^^^^^^^^^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/pattern_tuples.rs",
    "content": "#![warn(clippy::pattern_type_mismatch)]\n\nfn main() {}\n\nfn tuple_types() {\n    struct TupleStruct<'a>(&'a Option<i32>);\n    let ref_value = &TupleStruct(&Some(42));\n\n    // not ok\n    let TupleStruct(_) = ref_value;\n    //~^ pattern_type_mismatch\n\n    if let &TupleStruct(Some(_)) = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let TupleStruct(Some(_)) = *ref_value {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    let &TupleStruct(_) = ref_value;\n    let TupleStruct(_) = *ref_value;\n    if let &TupleStruct(&Some(_)) = ref_value {}\n    if let TupleStruct(&Some(_)) = *ref_value {}\n}\n\nfn tuple_enum_variants() {\n    enum TupleEnum<'a> {\n        Empty,\n        Var(&'a Option<i32>),\n    }\n    let ref_value = &TupleEnum::Var(&Some(42));\n\n    // not ok\n    if let TupleEnum::Var(_) = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let &TupleEnum::Var(Some(_)) = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let TupleEnum::Var(Some(_)) = *ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let TupleEnum::Empty = ref_value {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    if let &TupleEnum::Var(_) = ref_value {}\n    if let TupleEnum::Var(_) = *ref_value {}\n    if let &TupleEnum::Var(&Some(_)) = ref_value {}\n    if let TupleEnum::Var(&Some(_)) = *ref_value {}\n    if let &TupleEnum::Empty = ref_value {}\n    if let TupleEnum::Empty = *ref_value {}\n}\n\nfn plain_tuples() {\n    let ref_value = &(&Some(23), &Some(42));\n\n    // not ok\n    let (_a, _b) = ref_value;\n    //~^ pattern_type_mismatch\n\n    if let &(_a, Some(_)) = ref_value {}\n    //~^ pattern_type_mismatch\n\n    if let (_a, Some(_)) = *ref_value {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    let &(_a, _b) = ref_value;\n    let (_a, _b) = *ref_value;\n    if let &(_a, &Some(_)) = ref_value {}\n    if let (_a, &Some(_)) = *ref_value {}\n}\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/pattern_tuples.stderr",
    "content": "error: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:10:9\n   |\nLL |     let TupleStruct(_) = ref_value;\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:13:25\n   |\nLL |     if let &TupleStruct(Some(_)) = ref_value {}\n   |                         ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:16:24\n   |\nLL |     if let TupleStruct(Some(_)) = *ref_value {}\n   |                        ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:34:12\n   |\nLL |     if let TupleEnum::Var(_) = ref_value {}\n   |            ^^^^^^^^^^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:37:28\n   |\nLL |     if let &TupleEnum::Var(Some(_)) = ref_value {}\n   |                            ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:40:27\n   |\nLL |     if let TupleEnum::Var(Some(_)) = *ref_value {}\n   |                           ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:43:12\n   |\nLL |     if let TupleEnum::Empty = ref_value {}\n   |            ^^^^^^^^^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:59:9\n   |\nLL |     let (_a, _b) = ref_value;\n   |         ^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:62:18\n   |\nLL |     if let &(_a, Some(_)) = ref_value {}\n   |                  ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/pattern_tuples.rs:65:17\n   |\nLL |     if let (_a, Some(_)) = *ref_value {}\n   |                 ^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/syntax.rs",
    "content": "#![warn(clippy::pattern_type_mismatch)]\n#![allow(\n    clippy::match_ref_pats,\n    clippy::never_loop,\n    clippy::redundant_pattern_matching,\n    clippy::single_match\n)]\n\n//@aux-build:external.rs\nuse external::macro_with_match;\n\nfn main() {}\n\nfn syntax_match() {\n    let ref_value = &Some(&Some(42));\n\n    // not ok\n    match ref_value {\n        Some(_) => (),\n        //~^ pattern_type_mismatch\n        None => (),\n    }\n\n    // ok\n    match ref_value {\n        &Some(_) => (),\n        &None => (),\n    }\n    match *ref_value {\n        Some(_) => (),\n        None => (),\n    }\n}\n\nfn syntax_if_let() {\n    let ref_value = &Some(42);\n\n    // not ok\n    if let Some(_) = ref_value {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    if let &Some(_) = ref_value {}\n    if let Some(_) = *ref_value {}\n}\n\nfn syntax_while_let() {\n    let ref_value = &Some(42);\n\n    // not ok\n    while let Some(_) = ref_value {\n        //~^ pattern_type_mismatch\n\n        break;\n    }\n\n    // ok\n    while let &Some(_) = ref_value {\n        break;\n    }\n    while let Some(_) = *ref_value {\n        break;\n    }\n}\n\nfn syntax_for() {\n    let ref_value = &Some(23);\n    let slice = &[(2, 3), (4, 2)];\n\n    // not ok\n    for (_a, _b) in slice.iter() {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    for &(_a, _b) in slice.iter() {}\n}\n\nfn syntax_let() {\n    let ref_value = &(2, 3);\n\n    // not ok\n    let (_n, _m) = ref_value;\n    //~^ pattern_type_mismatch\n\n    // ok\n    let &(_n, _m) = ref_value;\n    let (_n, _m) = *ref_value;\n}\n\nfn syntax_fn() {\n    // not ok\n    fn foo((_a, _b): &(i32, i32)) {}\n    //~^ pattern_type_mismatch\n\n    // ok\n    fn foo_ok_1(&(_a, _b): &(i32, i32)) {}\n}\n\nfn syntax_closure() {\n    fn foo<F>(f: F)\n    where\n        F: FnOnce(&(i32, i32)),\n    {\n    }\n\n    // not ok\n    foo(|(_a, _b)| ());\n    //~^ pattern_type_mismatch\n\n    // ok\n    foo(|&(_a, _b)| ());\n}\n\nfn macro_with_expression() {\n    macro_rules! matching_macro {\n        ($e:expr) => {\n            $e\n        };\n    }\n    let value = &Some(23);\n\n    // not ok\n    matching_macro!(match value {\n        Some(_) => (),\n        //~^ pattern_type_mismatch\n        _ => (),\n    });\n\n    // ok\n    matching_macro!(match value {\n        &Some(_) => (),\n        _ => (),\n    });\n    matching_macro!(match *value {\n        Some(_) => (),\n        _ => (),\n    });\n}\n\nfn macro_expansion() {\n    macro_rules! matching_macro {\n        ($e:expr) => {\n            // not ok\n            match $e {\n                Some(_) => (),\n                //~^ pattern_type_mismatch\n                _ => (),\n            }\n\n            // ok\n            match $e {\n                &Some(_) => (),\n                _ => (),\n            }\n            match *$e {\n                Some(_) => (),\n                _ => (),\n            }\n        };\n    }\n\n    let value = &Some(23);\n    matching_macro!(value);\n}\n\nfn external_macro_expansion() {\n    macro_with_match! {\n        ()\n    };\n}\n"
  },
  {
    "path": "tests/ui/pattern_type_mismatch/syntax.stderr",
    "content": "error: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:19:9\n   |\nLL |         Some(_) => (),\n   |         ^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n   = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:39:12\n   |\nLL |     if let Some(_) = ref_value {}\n   |            ^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:51:15\n   |\nLL |     while let Some(_) = ref_value {\n   |               ^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:71:9\n   |\nLL |     for (_a, _b) in slice.iter() {}\n   |         ^^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:82:9\n   |\nLL |     let (_n, _m) = ref_value;\n   |         ^^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:92:12\n   |\nLL |     fn foo((_a, _b): &(i32, i32)) {}\n   |            ^^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:107:10\n   |\nLL |     foo(|(_a, _b)| ());\n   |          ^^^^^^^^\n   |\n   = help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:124:9\n   |\nLL |         Some(_) => (),\n   |         ^^^^^^^\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n\nerror: type of pattern does not match the expression type\n  --> tests/ui/pattern_type_mismatch/syntax.rs:145:17\n   |\nLL |                 Some(_) => (),\n   |                 ^^^^^^^\n...\nLL |     matching_macro!(value);\n   |     ---------------------- in this macro invocation\n   |\n   = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings\n   = note: this error originates in the macro `matching_macro` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/patterns.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::uninlined_format_args, clippy::single_match)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    let v = Some(true);\n    let s = [0, 1, 2, 3, 4];\n    match v {\n        Some(x) => (),\n        y => (),\n        //~^ redundant_pattern\n    }\n    match v {\n        Some(x) => (),\n        y @ None => (), // no error\n    }\n    match s {\n        [x, inside @ .., y] => (), // no error\n        [..] => (),\n    }\n\n    let mut mutv = vec![1, 2, 3];\n\n    // required \"ref\" left out in suggestion: #5271\n    match mutv {\n        ref mut x => {\n            //~^ redundant_pattern\n            x.push(4);\n            println!(\"vec: {:?}\", x);\n        },\n        ref y if y == &vec![0] => (),\n    }\n\n    match mutv {\n        ref x => println!(\"vec: {:?}\", x),\n        //~^ redundant_pattern\n        ref y if y == &vec![0] => (),\n    }\n    external! {\n        let v = Some(true);\n        match v {\n            Some(x) => (),\n            y @ _ => (),\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/patterns.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::uninlined_format_args, clippy::single_match)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    let v = Some(true);\n    let s = [0, 1, 2, 3, 4];\n    match v {\n        Some(x) => (),\n        y @ _ => (),\n        //~^ redundant_pattern\n    }\n    match v {\n        Some(x) => (),\n        y @ None => (), // no error\n    }\n    match s {\n        [x, inside @ .., y] => (), // no error\n        [..] => (),\n    }\n\n    let mut mutv = vec![1, 2, 3];\n\n    // required \"ref\" left out in suggestion: #5271\n    match mutv {\n        ref mut x @ _ => {\n            //~^ redundant_pattern\n            x.push(4);\n            println!(\"vec: {:?}\", x);\n        },\n        ref y if y == &vec![0] => (),\n    }\n\n    match mutv {\n        ref x @ _ => println!(\"vec: {:?}\", x),\n        //~^ redundant_pattern\n        ref y if y == &vec![0] => (),\n    }\n    external! {\n        let v = Some(true);\n        match v {\n            Some(x) => (),\n            y @ _ => (),\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/patterns.stderr",
    "content": "error: the `y @ _` pattern can be written as just `y`\n  --> tests/ui/patterns.rs:12:9\n   |\nLL |         y @ _ => (),\n   |         ^^^^^ help: try: `y`\n   |\n   = note: `-D clippy::redundant-pattern` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern)]`\n\nerror: the `x @ _` pattern can be written as just `x`\n  --> tests/ui/patterns.rs:28:9\n   |\nLL |         ref mut x @ _ => {\n   |         ^^^^^^^^^^^^^ help: try: `ref mut x`\n\nerror: the `x @ _` pattern can be written as just `x`\n  --> tests/ui/patterns.rs:37:9\n   |\nLL |         ref x @ _ => println!(\"vec: {:?}\", x),\n   |         ^^^^^^^^^ help: try: `ref x`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/permissions_set_readonly_false.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::permissions_set_readonly_false)]\n\nuse std::fs::File;\n\nstruct A;\n\nimpl A {\n    pub fn set_readonly(&mut self, b: bool) {}\n}\n\nfn set_readonly(b: bool) {}\n\nfn main() {\n    let f = File::create(\"foo.txt\").unwrap();\n    let metadata = f.metadata().unwrap();\n    let mut permissions = metadata.permissions();\n    // lint here\n    permissions.set_readonly(false);\n    //~^ permissions_set_readonly_false\n\n    // no lint\n    permissions.set_readonly(true);\n\n    let mut a = A;\n    // no lint here - a is not of type std::fs::Permissions\n    a.set_readonly(false);\n\n    // no lint here - plain function\n    set_readonly(false);\n}\n"
  },
  {
    "path": "tests/ui/permissions_set_readonly_false.stderr",
    "content": "error: call to `set_readonly` with argument `false`\n  --> tests/ui/permissions_set_readonly_false.rs:19:5\n   |\nLL |     permissions.set_readonly(false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: on Unix platforms this results in the file being world writable\n   = help: you can set the desired permissions using `PermissionsExt`. For more information, see\n           https://doc.rust-lang.org/std/os/unix/fs/trait.PermissionsExt.html\n   = note: `-D clippy::permissions-set-readonly-false` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::permissions_set_readonly_false)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/pointer_format.rs",
    "content": "#![warn(clippy::pointer_format)]\n\nuse core::fmt::Debug;\nuse core::marker::PhantomData;\n\n#[derive(Debug)]\nstruct ContainsPointerDeep {\n    w: WithPointer,\n}\n\nstruct ManualDebug {\n    ptr: *const u8,\n}\n\n#[derive(Debug)]\nstruct WithPointer {\n    len: usize,\n    ptr: *const u8,\n}\n\nimpl std::fmt::Debug for ManualDebug {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        f.write_str(\"ManualDebug\")\n    }\n}\n\ntrait Foo {\n    type Assoc: Foo + Debug;\n}\n\n#[derive(Debug)]\nstruct S<T: Foo + 'static>(&'static S<T::Assoc>, PhantomData<T>);\n\n#[allow(unused)]\nfn unbounded<T: Foo + Debug + 'static>(s: &S<T>) {\n    format!(\"{s:?}\");\n}\n\nfn main() {\n    let m = &(main as fn());\n    let g = &0;\n    let o = &format!(\"{m:p}\");\n    //~^ pointer_format\n    let _ = format!(\"{m:?}\");\n    //~^ pointer_format\n    println!(\"{g:p}\");\n    //~^ pointer_format\n    panic!(\"{o:p}\");\n    //~^ pointer_format\n    let answer = 42;\n    let x = &raw const answer;\n    let arr = [0u8; 8];\n    let with_ptr = WithPointer { len: 8, ptr: &arr as _ };\n    let _ = format!(\"{x:?}\");\n    //~^ pointer_format\n    print!(\"{with_ptr:?}\");\n    //~^ pointer_format\n    let container = ContainsPointerDeep { w: with_ptr };\n    print!(\"{container:?}\");\n    //~^ pointer_format\n\n    let no_pointer = \"foo\";\n    println!(\"{no_pointer:?}\");\n    let manual_debug = ManualDebug { ptr: &arr as _ };\n    println!(\"{manual_debug:?}\");\n}\n"
  },
  {
    "path": "tests/ui/pointer_format.stderr",
    "content": "error: pointer formatting detected\n  --> tests/ui/pointer_format.rs:42:23\n   |\nLL |     let o = &format!(\"{m:p}\");\n   |                       ^^^^^\n   |\n   = note: `-D clippy::pointer-format` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pointer_format)]`\n\nerror: pointer formatting detected\n  --> tests/ui/pointer_format.rs:44:22\n   |\nLL |     let _ = format!(\"{m:?}\");\n   |                      ^^^^^\n\nerror: pointer formatting detected\n  --> tests/ui/pointer_format.rs:46:15\n   |\nLL |     println!(\"{g:p}\");\n   |               ^^^^^\n\nerror: pointer formatting detected\n  --> tests/ui/pointer_format.rs:48:13\n   |\nLL |     panic!(\"{o:p}\");\n   |             ^^^^^\n\nerror: pointer formatting detected\n  --> tests/ui/pointer_format.rs:54:22\n   |\nLL |     let _ = format!(\"{x:?}\");\n   |                      ^^^^^\n\nerror: pointer formatting detected\n  --> tests/ui/pointer_format.rs:56:13\n   |\nLL |     print!(\"{with_ptr:?}\");\n   |             ^^^^^^^^^^^^\n\nerror: pointer formatting detected\n  --> tests/ui/pointer_format.rs:59:13\n   |\nLL |     print!(\"{container:?}\");\n   |             ^^^^^^^^^^^^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/pointers_in_nomem_asm_block.rs",
    "content": "//@ needs-asm-support\n#![warn(clippy::pointers_in_nomem_asm_block)]\n#![crate_type = \"lib\"]\n#![no_std]\n\nuse core::arch::asm;\n\nunsafe fn nomem_bad(p: &i32) {\n    unsafe {\n        asm!(\n            \"asdf {p1}, {p2}, {p3}\",\n            p1 = in(reg) p,\n            //~^ pointers_in_nomem_asm_block\n\n            p2 = in(reg) p as *const _ as usize,\n            p3 = in(reg) p,\n            options(nomem, nostack, preserves_flags)\n        );\n    }\n}\n\nunsafe fn nomem_good(p: &i32) {\n    unsafe {\n        asm!(\"asdf {p}\", p = in(reg) p, options(readonly, nostack, preserves_flags));\n        let p = p as *const i32 as usize;\n        asm!(\"asdf {p}\", p = in(reg) p, options(nomem, nostack, preserves_flags));\n    }\n}\n\nunsafe fn nomem_bad2(p: &mut i32) {\n    unsafe {\n        asm!(\"asdf {p}\", p = in(reg) p, options(nomem, nostack, preserves_flags));\n        //~^ pointers_in_nomem_asm_block\n    }\n}\n\nunsafe fn nomem_fn(p: extern \"C\" fn()) {\n    unsafe {\n        asm!(\"call {p}\", p = in(reg) p, options(nomem));\n        //~^ pointers_in_nomem_asm_block\n    }\n}\n"
  },
  {
    "path": "tests/ui/pointers_in_nomem_asm_block.stderr",
    "content": "error: passing pointers to nomem asm block\n  --> tests/ui/pointers_in_nomem_asm_block.rs:12:13\n   |\nLL |             p1 = in(reg) p,\n   |             ^^^^^^^^^^^^^^\n...\nLL |             p3 = in(reg) p,\n   |             ^^^^^^^^^^^^^^\n   |\n   = note: `nomem` means that no memory write or read happens inside the asm! block\n   = note: if this is intentional and no pointers are read or written to, consider allowing the lint\n   = note: `-D clippy::pointers-in-nomem-asm-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pointers_in_nomem_asm_block)]`\n\nerror: passing pointers to nomem asm block\n  --> tests/ui/pointers_in_nomem_asm_block.rs:32:26\n   |\nLL |         asm!(\"asdf {p}\", p = in(reg) p, options(nomem, nostack, preserves_flags));\n   |                          ^^^^^^^^^^^^^\n   |\n   = note: `nomem` means that no memory write or read happens inside the asm! block\n   = note: if this is intentional and no pointers are read or written to, consider allowing the lint\n\nerror: passing pointers to nomem asm block\n  --> tests/ui/pointers_in_nomem_asm_block.rs:39:26\n   |\nLL |         asm!(\"call {p}\", p = in(reg) p, options(nomem));\n   |                          ^^^^^^^^^^^^^\n   |\n   = note: `nomem` means that no memory write or read happens inside the asm! block\n   = note: if this is intentional and no pointers are read or written to, consider allowing the lint\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/precedence.fixed",
    "content": "#![warn(clippy::precedence)]\n#![allow(\n    unused_must_use,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::clone_on_copy,\n    clippy::identity_op,\n    clippy::eq_op\n)]\n\nmacro_rules! trip {\n    ($a:expr) => {\n        match $a & 0b1111_1111u8 {\n            0 => println!(\"a is zero ({})\", $a),\n            _ => println!(\"a is {}\", $a),\n        }\n    };\n}\n\nfn main() {\n    1 << (2 + 3);\n    //~^ precedence\n    (1 + 2) << 3;\n    //~^ precedence\n    4 >> (1 + 1);\n    //~^ precedence\n    (1 + 3) >> 2;\n    //~^ precedence\n    1 ^ (1 - 1);\n    //~^ precedence\n    3 | (2 - 1);\n    //~^ precedence\n    3 & (5 - 2);\n    //~^ precedence\n    0x0F00 & 0x00F0 << 4;\n    0x0F00 & 0xF000 >> 4;\n    0x0F00 << 1 ^ 3;\n    0x0F00 << 1 | 2;\n\n    let b = 3;\n    trip!(b * 8);\n}\n\nstruct W(u8);\nimpl Clone for W {\n    fn clone(&self) -> Self {\n        W(1)\n    }\n}\n\nfn closure_method_call() {\n    // Do not lint when the method call is applied to the block, both inside the closure\n    let f = |x: W| { x }.clone();\n    assert!(matches!(f(W(0)), W(1)));\n\n    let f = (|x: W| -> _ { x }).clone();\n    assert!(matches!(f(W(0)), W(0)));\n    //~^^ precedence\n\n    let f = (move |x: W| -> _ { x }).clone();\n    assert!(matches!(f(W(0)), W(0)));\n    //~^^ precedence\n}\n"
  },
  {
    "path": "tests/ui/precedence.rs",
    "content": "#![warn(clippy::precedence)]\n#![allow(\n    unused_must_use,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::clone_on_copy,\n    clippy::identity_op,\n    clippy::eq_op\n)]\n\nmacro_rules! trip {\n    ($a:expr) => {\n        match $a & 0b1111_1111u8 {\n            0 => println!(\"a is zero ({})\", $a),\n            _ => println!(\"a is {}\", $a),\n        }\n    };\n}\n\nfn main() {\n    1 << 2 + 3;\n    //~^ precedence\n    1 + 2 << 3;\n    //~^ precedence\n    4 >> 1 + 1;\n    //~^ precedence\n    1 + 3 >> 2;\n    //~^ precedence\n    1 ^ 1 - 1;\n    //~^ precedence\n    3 | 2 - 1;\n    //~^ precedence\n    3 & 5 - 2;\n    //~^ precedence\n    0x0F00 & 0x00F0 << 4;\n    0x0F00 & 0xF000 >> 4;\n    0x0F00 << 1 ^ 3;\n    0x0F00 << 1 | 2;\n\n    let b = 3;\n    trip!(b * 8);\n}\n\nstruct W(u8);\nimpl Clone for W {\n    fn clone(&self) -> Self {\n        W(1)\n    }\n}\n\nfn closure_method_call() {\n    // Do not lint when the method call is applied to the block, both inside the closure\n    let f = |x: W| { x }.clone();\n    assert!(matches!(f(W(0)), W(1)));\n\n    let f = |x: W| -> _ { x }.clone();\n    assert!(matches!(f(W(0)), W(0)));\n    //~^^ precedence\n\n    let f = move |x: W| -> _ { x }.clone();\n    assert!(matches!(f(W(0)), W(0)));\n    //~^^ precedence\n}\n"
  },
  {
    "path": "tests/ui/precedence.stderr",
    "content": "error: operator precedence might not be obvious\n  --> tests/ui/precedence.rs:21:5\n   |\nLL |     1 << 2 + 3;\n   |     ^^^^^^^^^^ help: consider parenthesizing your expression: `1 << (2 + 3)`\n   |\n   = note: `-D clippy::precedence` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::precedence)]`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence.rs:23:5\n   |\nLL |     1 + 2 << 3;\n   |     ^^^^^^^^^^ help: consider parenthesizing your expression: `(1 + 2) << 3`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence.rs:25:5\n   |\nLL |     4 >> 1 + 1;\n   |     ^^^^^^^^^^ help: consider parenthesizing your expression: `4 >> (1 + 1)`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence.rs:27:5\n   |\nLL |     1 + 3 >> 2;\n   |     ^^^^^^^^^^ help: consider parenthesizing your expression: `(1 + 3) >> 2`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence.rs:29:5\n   |\nLL |     1 ^ 1 - 1;\n   |     ^^^^^^^^^ help: consider parenthesizing your expression: `1 ^ (1 - 1)`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence.rs:31:5\n   |\nLL |     3 | 2 - 1;\n   |     ^^^^^^^^^ help: consider parenthesizing your expression: `3 | (2 - 1)`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence.rs:33:5\n   |\nLL |     3 & 5 - 2;\n   |     ^^^^^^^^^ help: consider parenthesizing your expression: `3 & (5 - 2)`\n\nerror: precedence might not be obvious\n  --> tests/ui/precedence.rs:56:13\n   |\nLL |     let f = |x: W| -> _ { x }.clone();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider parenthesizing the closure\n   |\nLL |     let f = (|x: W| -> _ { x }).clone();\n   |             +                 +\n\nerror: precedence might not be obvious\n  --> tests/ui/precedence.rs:60:13\n   |\nLL |     let f = move |x: W| -> _ { x }.clone();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider parenthesizing the closure\n   |\nLL |     let f = (move |x: W| -> _ { x }).clone();\n   |             +                      +\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/precedence_bits.fixed",
    "content": "#![warn(clippy::precedence_bits)]\n#![allow(\n    unused_must_use,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::precedence\n)]\n#![allow(clippy::identity_op)]\n#![allow(clippy::eq_op)]\n\nmacro_rules! trip {\n    ($a:expr) => {\n        match $a & 0b1111_1111u8 {\n            0 => println!(\"a is zero ({})\", $a),\n            _ => println!(\"a is {}\", $a),\n        }\n    };\n}\n\nfn main() {\n    1 << 2 + 3;\n    1 + 2 << 3;\n    4 >> 1 + 1;\n    1 + 3 >> 2;\n    1 ^ 1 - 1;\n    3 | 2 - 1;\n    3 & 5 - 2;\n    0x0F00 & (0x00F0 << 4);\n    //~^ precedence_bits\n    0x0F00 & (0xF000 >> 4);\n    //~^ precedence_bits\n    (0x0F00 << 1) ^ 3;\n    //~^ precedence_bits\n    (0x0F00 << 1) | 2;\n    //~^ precedence_bits\n\n    let b = 3;\n    trip!(b * 8);\n}\n"
  },
  {
    "path": "tests/ui/precedence_bits.rs",
    "content": "#![warn(clippy::precedence_bits)]\n#![allow(\n    unused_must_use,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::precedence\n)]\n#![allow(clippy::identity_op)]\n#![allow(clippy::eq_op)]\n\nmacro_rules! trip {\n    ($a:expr) => {\n        match $a & 0b1111_1111u8 {\n            0 => println!(\"a is zero ({})\", $a),\n            _ => println!(\"a is {}\", $a),\n        }\n    };\n}\n\nfn main() {\n    1 << 2 + 3;\n    1 + 2 << 3;\n    4 >> 1 + 1;\n    1 + 3 >> 2;\n    1 ^ 1 - 1;\n    3 | 2 - 1;\n    3 & 5 - 2;\n    0x0F00 & 0x00F0 << 4;\n    //~^ precedence_bits\n    0x0F00 & 0xF000 >> 4;\n    //~^ precedence_bits\n    0x0F00 << 1 ^ 3;\n    //~^ precedence_bits\n    0x0F00 << 1 | 2;\n    //~^ precedence_bits\n\n    let b = 3;\n    trip!(b * 8);\n}\n"
  },
  {
    "path": "tests/ui/precedence_bits.stderr",
    "content": "error: operator precedence might not be obvious\n  --> tests/ui/precedence_bits.rs:28:5\n   |\nLL |     0x0F00 & 0x00F0 << 4;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0x00F0 << 4)`\n   |\n   = note: `-D clippy::precedence-bits` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::precedence_bits)]`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence_bits.rs:30:5\n   |\nLL |     0x0F00 & 0xF000 >> 4;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0xF000 >> 4)`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence_bits.rs:32:5\n   |\nLL |     0x0F00 << 1 ^ 3;\n   |     ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) ^ 3`\n\nerror: operator precedence might not be obvious\n  --> tests/ui/precedence_bits.rs:34:5\n   |\nLL |     0x0F00 << 1 | 2;\n   |     ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) | 2`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/print_in_format_impl.rs",
    "content": "#![allow(unused, clippy::print_literal, clippy::write_literal)]\n#![warn(clippy::print_in_format_impl)]\nuse std::fmt::{Debug, Display, Error, Formatter};\n//@no-rustfix\nmacro_rules! indirect {\n    () => {{ println!() }};\n}\n\nmacro_rules! nested {\n    ($($tt:tt)*) => {\n        $($tt)*\n    };\n}\n\nstruct Foo;\nimpl Debug for Foo {\n    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {\n        static WORKS_WITH_NESTED_ITEMS: bool = true;\n\n        print!(\"{}\", 1);\n        //~^ print_in_format_impl\n\n        println!(\"{}\", 2);\n        //~^ print_in_format_impl\n\n        eprint!(\"{}\", 3);\n        //~^ print_in_format_impl\n\n        eprintln!(\"{}\", 4);\n        //~^ print_in_format_impl\n\n        nested! {\n            println!(\"nested\");\n            //~^ print_in_format_impl\n\n        };\n\n        write!(f, \"{}\", 5);\n        writeln!(f, \"{}\", 6);\n        indirect!();\n\n        Ok(())\n    }\n}\n\nimpl Display for Foo {\n    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {\n        print!(\"Display\");\n        //~^ print_in_format_impl\n\n        write!(f, \"Display\");\n\n        Ok(())\n    }\n}\n\nstruct UnnamedFormatter;\nimpl Debug for UnnamedFormatter {\n    fn fmt(&self, _: &mut Formatter) -> Result<(), Error> {\n        println!(\"UnnamedFormatter\");\n        //~^ print_in_format_impl\n\n        Ok(())\n    }\n}\n\nfn main() {\n    print!(\"outside fmt\");\n    println!(\"outside fmt\");\n    eprint!(\"outside fmt\");\n    eprintln!(\"outside fmt\");\n}\n"
  },
  {
    "path": "tests/ui/print_in_format_impl.stderr",
    "content": "error: use of `print!` in `Debug` impl\n  --> tests/ui/print_in_format_impl.rs:20:9\n   |\nLL |         print!(\"{}\", 1);\n   |         ^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)`\n   |\n   = note: `-D clippy::print-in-format-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_in_format_impl)]`\n\nerror: use of `println!` in `Debug` impl\n  --> tests/ui/print_in_format_impl.rs:23:9\n   |\nLL |         println!(\"{}\", 2);\n   |         ^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)`\n\nerror: use of `eprint!` in `Debug` impl\n  --> tests/ui/print_in_format_impl.rs:26:9\n   |\nLL |         eprint!(\"{}\", 3);\n   |         ^^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)`\n\nerror: use of `eprintln!` in `Debug` impl\n  --> tests/ui/print_in_format_impl.rs:29:9\n   |\nLL |         eprintln!(\"{}\", 4);\n   |         ^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)`\n\nerror: use of `println!` in `Debug` impl\n  --> tests/ui/print_in_format_impl.rs:33:13\n   |\nLL |             println!(\"nested\");\n   |             ^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(f, ..)`\n\nerror: use of `print!` in `Display` impl\n  --> tests/ui/print_in_format_impl.rs:48:9\n   |\nLL |         print!(\"Display\");\n   |         ^^^^^^^^^^^^^^^^^ help: replace with: `write!(f, ..)`\n\nerror: use of `println!` in `Debug` impl\n  --> tests/ui/print_in_format_impl.rs:60:9\n   |\nLL |         println!(\"UnnamedFormatter\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `writeln!(..)`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/print_literal.fixed",
    "content": "#![warn(clippy::print_literal)]\n#![allow(clippy::uninlined_format_args, clippy::literal_string_with_formatting_args)]\n\nfn main() {\n    // these should be fine\n    print!(\"Hello\");\n    println!(\"Hello\");\n    let world = \"world\";\n    println!(\"Hello {}\", world);\n    println!(\"Hello {world}\", world = world);\n    println!(\"3 in hex is {:X}\", 3);\n    println!(\"2 + 1 = {:.4}\", 3);\n    println!(\"2 + 1 = {:5.4}\", 3);\n    println!(\"Debug test {:?}\", \"hello, world\");\n    println!(\"{0:8} {1:>8}\", \"hello\", \"world\");\n    println!(\"{1:8} {0:>8}\", \"hello\", \"world\");\n    println!(\"{foo:8} {bar:>8}\", foo = \"hello\", bar = \"world\");\n    println!(\"{bar:8} {foo:>8}\", foo = \"hello\", bar = \"world\");\n    println!(\"{number:>width$}\", number = 1, width = 6);\n    println!(\"{number:>0width$}\", number = 1, width = 6);\n    println!(\"{} of {:b} people know binary, the other half doesn't\", 1, 2);\n    println!(\"10 / 4 is {}\", 2.5);\n    println!(\"2 + 1 = {}\", 3);\n    println!(\"From expansion {}\", stringify!(not a string literal));\n\n    // these should throw warnings\n    print!(\"Hello world\");\n    //~^ print_literal\n\n    println!(\"Hello {} world\", world);\n    //~^ print_literal\n\n    println!(\"Hello world\");\n    //~^ print_literal\n\n    println!(\"a literal {:.4}\", 5);\n    //~^ print_literal\n\n    // positional args don't change the fact\n    // that we're using a literal -- this should\n    // throw a warning\n    println!(\"hello world\");\n    //~^ print_literal\n\n    println!(\"world hello\");\n    //~^ print_literal\n\n    // named args shouldn't change anything either\n    println!(\"hello world\");\n    //~^ print_literal\n\n    println!(\"world hello\");\n    //~^ print_literal\n\n    // The string literal from `file!()` has a callsite span that isn't marked as coming from an\n    // expansion\n    println!(\"file: {}\", file!());\n\n    // Braces in unicode escapes should not be escaped\n    println!(\"{{}} \\x00 \\u{ab123} \\\\\\u{ab123} {{:?}}\");\n    //~^ print_literal\n    println!(\"\\\\\\u{1234}\");\n    //~^ print_literal\n    // This does not lint because it would have to suggest unescaping the character\n    println!(r\"{}\", \"\\u{ab123}\");\n    // These are not unicode escapes\n    println!(\"\\\\u{{ab123}} \\\\u{{{{\");\n    //~^ print_literal\n    println!(r\"\\u{{ab123}} \\u{{{{\");\n    //~^ print_literal\n    println!(\"\\\\{{ab123}} \\\\u{{{{\");\n    //~^ print_literal\n    println!(\"\\\\u{{ab123}}\");\n    //~^ print_literal\n    println!(\"\\\\\\\\u{{1234}}\");\n    //~^ print_literal\n\n    println!(\"mixed: {{hello}} {world}\");\n    //~^ print_literal\n}\n\nfn issue_13959() {\n    println!(\"\\\"\");\n    //~^ print_literal\n    println!(\n        \"\n        //~^ print_literal\n        foo\n        \\\\\n        \\\\\\\\\n        \\\"\n        \\\\\\\"\n        bar\n\"\n    );\n}\n\nfn issue_14930() {\n    println!(\"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n    //~^ print_literal\n    println!(\"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n    //~^ print_literal\n    println!(\"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n    //~^ print_literal\n    println!(\"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n    //~^ print_literal\n}\n\nfn issue_15576() {\n    println!(\"Hello x is {1:.*}\", 5, 0.01);\n    //~^ print_literal\n\n    println!(\"Hello x is {:.p$}\", 0.01, p = 5);\n    //~^ print_literal\n\n    println!(\n        \"Hello name: x is {1:.*} (which {1} with {0} places)\", 5, 0.01\n    );\n    //~^^ print_literal\n}\n"
  },
  {
    "path": "tests/ui/print_literal.rs",
    "content": "#![warn(clippy::print_literal)]\n#![allow(clippy::uninlined_format_args, clippy::literal_string_with_formatting_args)]\n\nfn main() {\n    // these should be fine\n    print!(\"Hello\");\n    println!(\"Hello\");\n    let world = \"world\";\n    println!(\"Hello {}\", world);\n    println!(\"Hello {world}\", world = world);\n    println!(\"3 in hex is {:X}\", 3);\n    println!(\"2 + 1 = {:.4}\", 3);\n    println!(\"2 + 1 = {:5.4}\", 3);\n    println!(\"Debug test {:?}\", \"hello, world\");\n    println!(\"{0:8} {1:>8}\", \"hello\", \"world\");\n    println!(\"{1:8} {0:>8}\", \"hello\", \"world\");\n    println!(\"{foo:8} {bar:>8}\", foo = \"hello\", bar = \"world\");\n    println!(\"{bar:8} {foo:>8}\", foo = \"hello\", bar = \"world\");\n    println!(\"{number:>width$}\", number = 1, width = 6);\n    println!(\"{number:>0width$}\", number = 1, width = 6);\n    println!(\"{} of {:b} people know binary, the other half doesn't\", 1, 2);\n    println!(\"10 / 4 is {}\", 2.5);\n    println!(\"2 + 1 = {}\", 3);\n    println!(\"From expansion {}\", stringify!(not a string literal));\n\n    // these should throw warnings\n    print!(\"Hello {}\", \"world\");\n    //~^ print_literal\n\n    println!(\"Hello {} {}\", world, \"world\");\n    //~^ print_literal\n\n    println!(\"Hello {}\", \"world\");\n    //~^ print_literal\n\n    println!(\"{} {:.4}\", \"a literal\", 5);\n    //~^ print_literal\n\n    // positional args don't change the fact\n    // that we're using a literal -- this should\n    // throw a warning\n    println!(\"{0} {1}\", \"hello\", \"world\");\n    //~^ print_literal\n\n    println!(\"{1} {0}\", \"hello\", \"world\");\n    //~^ print_literal\n\n    // named args shouldn't change anything either\n    println!(\"{foo} {bar}\", foo = \"hello\", bar = \"world\");\n    //~^ print_literal\n\n    println!(\"{bar} {foo}\", foo = \"hello\", bar = \"world\");\n    //~^ print_literal\n\n    // The string literal from `file!()` has a callsite span that isn't marked as coming from an\n    // expansion\n    println!(\"file: {}\", file!());\n\n    // Braces in unicode escapes should not be escaped\n    println!(\"{}\", \"{} \\x00 \\u{ab123} \\\\\\u{ab123} {:?}\");\n    //~^ print_literal\n    println!(\"{}\", \"\\\\\\u{1234}\");\n    //~^ print_literal\n    // This does not lint because it would have to suggest unescaping the character\n    println!(r\"{}\", \"\\u{ab123}\");\n    // These are not unicode escapes\n    println!(\"{}\", r\"\\u{ab123} \\u{{\");\n    //~^ print_literal\n    println!(r\"{}\", r\"\\u{ab123} \\u{{\");\n    //~^ print_literal\n    println!(\"{}\", r\"\\{ab123} \\u{{\");\n    //~^ print_literal\n    println!(\"{}\", \"\\\\u{ab123}\");\n    //~^ print_literal\n    println!(\"{}\", \"\\\\\\\\u{1234}\");\n    //~^ print_literal\n\n    println!(\"mixed: {} {world}\", \"{hello}\");\n    //~^ print_literal\n}\n\nfn issue_13959() {\n    println!(\"{}\", r#\"\"\"#);\n    //~^ print_literal\n    println!(\n        \"{}\",\n        r#\"\n        //~^ print_literal\n        foo\n        \\\n        \\\\\n        \"\n        \\\"\n        bar\n\"#\n    );\n}\n\nfn issue_14930() {\n    println!(\"Hello {3} is {0:2$.1$}\", 0.01, 2, 3, \"x\");\n    //~^ print_literal\n    println!(\"Hello {2} is {0:3$.1$}\", 0.01, 2, \"x\", 3);\n    //~^ print_literal\n    println!(\"Hello {1} is {0:3$.2$}\", 0.01, \"x\", 2, 3);\n    //~^ print_literal\n    println!(\"Hello {0} is {1:3$.2$}\", \"x\", 0.01, 2, 3);\n    //~^ print_literal\n}\n\nfn issue_15576() {\n    println!(\"Hello {} is {2:.*}\", \"x\", 5, 0.01);\n    //~^ print_literal\n\n    println!(\"Hello {} is {:.p$}\", \"x\", 0.01, p = 5);\n    //~^ print_literal\n\n    println!(\n        \"Hello {}: {2} is {3:.*} (which {3} with {1} places)\",\n        \"name\", 5, \"x\", 0.01\n    );\n    //~^^ print_literal\n}\n"
  },
  {
    "path": "tests/ui/print_literal.stderr",
    "content": "error: literal with an empty format string\n  --> tests/ui/print_literal.rs:27:24\n   |\nLL |     print!(\"Hello {}\", \"world\");\n   |                        ^^^^^^^\n   |\n   = note: `-D clippy::print-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_literal)]`\nhelp: try\n   |\nLL -     print!(\"Hello {}\", \"world\");\nLL +     print!(\"Hello world\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:30:36\n   |\nLL |     println!(\"Hello {} {}\", world, \"world\");\n   |                                    ^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"Hello {} {}\", world, \"world\");\nLL +     println!(\"Hello {} world\", world);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:33:26\n   |\nLL |     println!(\"Hello {}\", \"world\");\n   |                          ^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"Hello {}\", \"world\");\nLL +     println!(\"Hello world\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:36:26\n   |\nLL |     println!(\"{} {:.4}\", \"a literal\", 5);\n   |                          ^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{} {:.4}\", \"a literal\", 5);\nLL +     println!(\"a literal {:.4}\", 5);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:42:25\n   |\nLL |     println!(\"{0} {1}\", \"hello\", \"world\");\n   |                         ^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{0} {1}\", \"hello\", \"world\");\nLL +     println!(\"hello world\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:45:25\n   |\nLL |     println!(\"{1} {0}\", \"hello\", \"world\");\n   |                         ^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{1} {0}\", \"hello\", \"world\");\nLL +     println!(\"world hello\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:49:35\n   |\nLL |     println!(\"{foo} {bar}\", foo = \"hello\", bar = \"world\");\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{foo} {bar}\", foo = \"hello\", bar = \"world\");\nLL +     println!(\"hello world\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:52:35\n   |\nLL |     println!(\"{bar} {foo}\", foo = \"hello\", bar = \"world\");\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{bar} {foo}\", foo = \"hello\", bar = \"world\");\nLL +     println!(\"world hello\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:60:20\n   |\nLL |     println!(\"{}\", \"{} \\x00 \\u{ab123} \\\\\\u{ab123} {:?}\");\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{}\", \"{} \\x00 \\u{ab123} \\\\\\u{ab123} {:?}\");\nLL +     println!(\"{{}} \\x00 \\u{ab123} \\\\\\u{ab123} {{:?}}\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:62:20\n   |\nLL |     println!(\"{}\", \"\\\\\\u{1234}\");\n   |                    ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{}\", \"\\\\\\u{1234}\");\nLL +     println!(\"\\\\\\u{1234}\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:67:20\n   |\nLL |     println!(\"{}\", r\"\\u{ab123} \\u{{\");\n   |                    ^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{}\", r\"\\u{ab123} \\u{{\");\nLL +     println!(\"\\\\u{{ab123}} \\\\u{{{{\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:69:21\n   |\nLL |     println!(r\"{}\", r\"\\u{ab123} \\u{{\");\n   |                     ^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(r\"{}\", r\"\\u{ab123} \\u{{\");\nLL +     println!(r\"\\u{{ab123}} \\u{{{{\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:71:20\n   |\nLL |     println!(\"{}\", r\"\\{ab123} \\u{{\");\n   |                    ^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{}\", r\"\\{ab123} \\u{{\");\nLL +     println!(\"\\\\{{ab123}} \\\\u{{{{\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:73:20\n   |\nLL |     println!(\"{}\", \"\\\\u{ab123}\");\n   |                    ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{}\", \"\\\\u{ab123}\");\nLL +     println!(\"\\\\u{{ab123}}\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:75:20\n   |\nLL |     println!(\"{}\", \"\\\\\\\\u{1234}\");\n   |                    ^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{}\", \"\\\\\\\\u{1234}\");\nLL +     println!(\"\\\\\\\\u{{1234}}\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:78:35\n   |\nLL |     println!(\"mixed: {} {world}\", \"{hello}\");\n   |                                   ^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"mixed: {} {world}\", \"{hello}\");\nLL +     println!(\"mixed: {{hello}} {world}\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:83:20\n   |\nLL |     println!(\"{}\", r#\"\"\"#);\n   |                    ^^^^^^\n   |\nhelp: try\n   |\nLL -     println!(\"{}\", r#\"\"\"#);\nLL +     println!(\"\\\"\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:87:9\n   |\nLL | /         r#\"\nLL | |\nLL | |         foo\nLL | |         \\\n...  |\nLL | |         bar\nLL | | \"#\n   | |__^\n   |\nhelp: try\n   |\nLL ~         \"\nLL +\nLL +         foo\nLL +         \\\\\nLL +         \\\\\\\\\nLL +         \\\"\nLL +         \\\\\\\"\nLL +         bar\nLL ~ \"\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:100:52\n   |\nLL |     println!(\"Hello {3} is {0:2$.1$}\", 0.01, 2, 3, \"x\");\n   |                                                    ^^^\n   |\nhelp: try\n   |\nLL -     println!(\"Hello {3} is {0:2$.1$}\", 0.01, 2, 3, \"x\");\nLL +     println!(\"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:102:49\n   |\nLL |     println!(\"Hello {2} is {0:3$.1$}\", 0.01, 2, \"x\", 3);\n   |                                                 ^^^\n   |\nhelp: try\n   |\nLL -     println!(\"Hello {2} is {0:3$.1$}\", 0.01, 2, \"x\", 3);\nLL +     println!(\"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:104:46\n   |\nLL |     println!(\"Hello {1} is {0:3$.2$}\", 0.01, \"x\", 2, 3);\n   |                                              ^^^\n   |\nhelp: try\n   |\nLL -     println!(\"Hello {1} is {0:3$.2$}\", 0.01, \"x\", 2, 3);\nLL +     println!(\"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:106:40\n   |\nLL |     println!(\"Hello {0} is {1:3$.2$}\", \"x\", 0.01, 2, 3);\n   |                                        ^^^\n   |\nhelp: try\n   |\nLL -     println!(\"Hello {0} is {1:3$.2$}\", \"x\", 0.01, 2, 3);\nLL +     println!(\"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:111:36\n   |\nLL |     println!(\"Hello {} is {2:.*}\", \"x\", 5, 0.01);\n   |                                    ^^^\n   |\nhelp: try\n   |\nLL -     println!(\"Hello {} is {2:.*}\", \"x\", 5, 0.01);\nLL +     println!(\"Hello x is {1:.*}\", 5, 0.01);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:114:36\n   |\nLL |     println!(\"Hello {} is {:.p$}\", \"x\", 0.01, p = 5);\n   |                                    ^^^\n   |\nhelp: try\n   |\nLL -     println!(\"Hello {} is {:.p$}\", \"x\", 0.01, p = 5);\nLL +     println!(\"Hello x is {:.p$}\", 0.01, p = 5);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/print_literal.rs:119:9\n   |\nLL |         \"name\", 5, \"x\", 0.01\n   |         ^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         \"Hello {}: {2} is {3:.*} (which {3} with {1} places)\",\nLL -         \"name\", 5, \"x\", 0.01\nLL +         \"Hello name: x is {1:.*} (which {1} with {0} places)\", 5, 0.01\n   |\n\nerror: aborting due to 25 previous errors\n\n"
  },
  {
    "path": "tests/ui/print_stderr.rs",
    "content": "#![warn(clippy::print_stderr)]\n\nfn main() {\n    eprintln!(\"Hello\");\n    //~^ print_stderr\n\n    println!(\"This should not do anything\");\n    eprint!(\"World\");\n    //~^ print_stderr\n\n    print!(\"Nor should this\");\n}\n"
  },
  {
    "path": "tests/ui/print_stderr.stderr",
    "content": "error: use of `eprintln!`\n  --> tests/ui/print_stderr.rs:4:5\n   |\nLL |     eprintln!(\"Hello\");\n   |     ^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::print-stderr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_stderr)]`\n\nerror: use of `eprint!`\n  --> tests/ui/print_stderr.rs:8:5\n   |\nLL |     eprint!(\"World\");\n   |     ^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/print_stdout.rs",
    "content": "#![expect(clippy::print_literal)]\n#![warn(clippy::print_stdout)]\n\nfn main() {\n    println!(\"Hello\");\n    //~^ print_stdout\n\n    print!(\"Hello\");\n    //~^ print_stdout\n\n    print!(\"Hello {}\", \"World\");\n    //~^ print_stdout\n\n    print!(\"Hello {:?}\", \"World\");\n    //~^ print_stdout\n\n    print!(\"Hello {:#?}\", \"#orld\");\n    //~^ print_stdout\n\n    assert_eq!(42, 1337);\n\n    vec![1, 2];\n}\n"
  },
  {
    "path": "tests/ui/print_stdout.stderr",
    "content": "error: use of `println!`\n  --> tests/ui/print_stdout.rs:5:5\n   |\nLL |     println!(\"Hello\");\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::print-stdout` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_stdout)]`\n\nerror: use of `print!`\n  --> tests/ui/print_stdout.rs:8:5\n   |\nLL |     print!(\"Hello\");\n   |     ^^^^^^^^^^^^^^^\n\nerror: use of `print!`\n  --> tests/ui/print_stdout.rs:11:5\n   |\nLL |     print!(\"Hello {}\", \"World\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of `print!`\n  --> tests/ui/print_stdout.rs:14:5\n   |\nLL |     print!(\"Hello {:?}\", \"World\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of `print!`\n  --> tests/ui/print_stdout.rs:17:5\n   |\nLL |     print!(\"Hello {:#?}\", \"#orld\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/print_stdout_build_script.rs",
    "content": "//@compile-flags: --crate-name=build_script_build\n//@ check-pass\n\n#![warn(clippy::print_stdout)]\n\nfn main() {\n    // Fix #6041\n    //\n    // The `print_stdout` lint shouldn't emit in `build.rs`\n    // as these methods are used for the build script.\n    println!(\"Hello\");\n    print!(\"Hello\");\n}\n"
  },
  {
    "path": "tests/ui/print_with_newline.fixed",
    "content": "// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934\n\n#![allow(clippy::print_literal)]\n#![warn(clippy::print_with_newline)]\n\nfn main() {\n    println!(\"Hello\");\n    //~^ print_with_newline\n\n    println!(\"Hello {}\", \"world\");\n    //~^ print_with_newline\n\n    println!(\"Hello {} {}\", \"world\", \"#2\");\n    //~^ print_with_newline\n\n    println!(\"{}\", 1265);\n    //~^ print_with_newline\n\n    println!();\n    //~^ print_with_newline\n\n    // these are all fine\n    print!(\"\");\n    print!(\"Hello\");\n    println!(\"Hello\");\n    println!(\"Hello\\n\");\n    println!(\"Hello {}\\n\", \"world\");\n    print!(\"Issue\\n{}\", 1265);\n    print!(\"{}\", 1265);\n    print!(\"\\n{}\", 1275);\n    print!(\"\\n\\n\");\n    print!(\"like eof\\n\\n\");\n    print!(\"Hello {} {}\\n\\n\", \"world\", \"#2\");\n    // #3126\n    println!(\"\\ndon't\\nwarn\\nfor\\nmultiple\\nnewlines\\n\");\n    // #3126\n    println!(\"\\nbla\\n\\n\");\n\n    // Escaping\n    // #3514\n    print!(\"\\\\n\");\n    println!(\"\\\\\");\n    //~^ print_with_newline\n\n    print!(\"\\\\\\\\n\");\n\n    // Raw strings\n    // #3778\n    print!(r\"\\n\");\n\n    // Literal newlines should also fail\n    println!(\n        //~^ print_with_newline\n        \n    );\n    println!(\n        //~^ print_with_newline\n        \n    );\n\n    // Don't warn on CRLF (#4208)\n    print!(\"\\r\\n\");\n    print!(\"foo\\r\\n\");\n    // should fail\n    println!(\"\\\\r\");\n    //~^ print_with_newline\n\n    print!(\"foo\\rbar\\n\");\n\n    // Ignore expanded format strings\n    macro_rules! newline {\n        () => {\n            \"\\n\"\n        };\n    }\n    print!(newline!());\n}\n"
  },
  {
    "path": "tests/ui/print_with_newline.rs",
    "content": "// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934\n\n#![allow(clippy::print_literal)]\n#![warn(clippy::print_with_newline)]\n\nfn main() {\n    print!(\"Hello\\n\");\n    //~^ print_with_newline\n\n    print!(\"Hello {}\\n\", \"world\");\n    //~^ print_with_newline\n\n    print!(\"Hello {} {}\\n\", \"world\", \"#2\");\n    //~^ print_with_newline\n\n    print!(\"{}\\n\", 1265);\n    //~^ print_with_newline\n\n    print!(\"\\n\");\n    //~^ print_with_newline\n\n    // these are all fine\n    print!(\"\");\n    print!(\"Hello\");\n    println!(\"Hello\");\n    println!(\"Hello\\n\");\n    println!(\"Hello {}\\n\", \"world\");\n    print!(\"Issue\\n{}\", 1265);\n    print!(\"{}\", 1265);\n    print!(\"\\n{}\", 1275);\n    print!(\"\\n\\n\");\n    print!(\"like eof\\n\\n\");\n    print!(\"Hello {} {}\\n\\n\", \"world\", \"#2\");\n    // #3126\n    println!(\"\\ndon't\\nwarn\\nfor\\nmultiple\\nnewlines\\n\");\n    // #3126\n    println!(\"\\nbla\\n\\n\");\n\n    // Escaping\n    // #3514\n    print!(\"\\\\n\");\n    print!(\"\\\\\\n\");\n    //~^ print_with_newline\n\n    print!(\"\\\\\\\\n\");\n\n    // Raw strings\n    // #3778\n    print!(r\"\\n\");\n\n    // Literal newlines should also fail\n    print!(\n        //~^ print_with_newline\n        \"\n\"\n    );\n    print!(\n        //~^ print_with_newline\n        r\"\n\"\n    );\n\n    // Don't warn on CRLF (#4208)\n    print!(\"\\r\\n\");\n    print!(\"foo\\r\\n\");\n    // should fail\n    print!(\"\\\\r\\n\");\n    //~^ print_with_newline\n\n    print!(\"foo\\rbar\\n\");\n\n    // Ignore expanded format strings\n    macro_rules! newline {\n        () => {\n            \"\\n\"\n        };\n    }\n    print!(newline!());\n}\n"
  },
  {
    "path": "tests/ui/print_with_newline.stderr",
    "content": "error: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:7:5\n   |\nLL |     print!(\"Hello\\n\");\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::print-with-newline` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_with_newline)]`\nhelp: use `println!` instead\n   |\nLL -     print!(\"Hello\\n\");\nLL +     println!(\"Hello\");\n   |\n\nerror: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:10:5\n   |\nLL |     print!(\"Hello {}\\n\", \"world\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `println!` instead\n   |\nLL -     print!(\"Hello {}\\n\", \"world\");\nLL +     println!(\"Hello {}\", \"world\");\n   |\n\nerror: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:13:5\n   |\nLL |     print!(\"Hello {} {}\\n\", \"world\", \"#2\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `println!` instead\n   |\nLL -     print!(\"Hello {} {}\\n\", \"world\", \"#2\");\nLL +     println!(\"Hello {} {}\", \"world\", \"#2\");\n   |\n\nerror: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:16:5\n   |\nLL |     print!(\"{}\\n\", 1265);\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `println!` instead\n   |\nLL -     print!(\"{}\\n\", 1265);\nLL +     println!(\"{}\", 1265);\n   |\n\nerror: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:19:5\n   |\nLL |     print!(\"\\n\");\n   |     ^^^^^^^^^^^^\n   |\nhelp: use `println!` instead\n   |\nLL -     print!(\"\\n\");\nLL +     println!();\n   |\n\nerror: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:42:5\n   |\nLL |     print!(\"\\\\\\n\");\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: use `println!` instead\n   |\nLL -     print!(\"\\\\\\n\");\nLL +     println!(\"\\\\\");\n   |\n\nerror: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:52:5\n   |\nLL | /     print!(\nLL | |\nLL | |         \"\nLL | | \"\nLL | |     );\n   | |_____^\n   |\nhelp: use `println!` instead\n   |\nLL ~     println!(\nLL |\nLL ~         \n   |\n\nerror: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:57:5\n   |\nLL | /     print!(\nLL | |\nLL | |         r\"\nLL | | \"\nLL | |     );\n   | |_____^\n   |\nhelp: use `println!` instead\n   |\nLL ~     println!(\nLL |\nLL ~         \n   |\n\nerror: using `print!()` with a format string that ends in a single newline\n  --> tests/ui/print_with_newline.rs:67:5\n   |\nLL |     print!(\"\\\\r\\n\");\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: use `println!` instead\n   |\nLL -     print!(\"\\\\r\\n\");\nLL +     println!(\"\\\\r\");\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/println_empty_string.fixed",
    "content": "#![allow(clippy::match_single_binding, clippy::unnecessary_trailing_comma)]\n\nfn main() {\n    println!();\n    println!();\n    //~^ println_empty_string\n\n    match \"a\" {\n        _ => println!(),\n        //~^ println_empty_string\n    }\n\n    eprintln!();\n    eprintln!();\n    //~^ println_empty_string\n\n    match \"a\" {\n        _ => eprintln!(),\n        //~^ println_empty_string\n    }\n}\n\n#[rustfmt::skip]\nfn issue_16167() {\n    //~v println_empty_string\n    println!(\n        );\n\n    match \"a\" {\n        _ => println!(), // there is a space between \"\" and comma\n        //~^ println_empty_string\n    }\n\n    eprintln!(); // there is a tab between \"\" and comma\n    //~^ println_empty_string\n\n    match \"a\" {\n        _ => eprintln!(), // tab and space between \"\" and comma\n        //~^ println_empty_string\n    }\n}\n"
  },
  {
    "path": "tests/ui/println_empty_string.rs",
    "content": "#![allow(clippy::match_single_binding, clippy::unnecessary_trailing_comma)]\n\nfn main() {\n    println!();\n    println!(\"\");\n    //~^ println_empty_string\n\n    match \"a\" {\n        _ => println!(\"\"),\n        //~^ println_empty_string\n    }\n\n    eprintln!();\n    eprintln!(\"\");\n    //~^ println_empty_string\n\n    match \"a\" {\n        _ => eprintln!(\"\"),\n        //~^ println_empty_string\n    }\n}\n\n#[rustfmt::skip]\nfn issue_16167() {\n    //~v println_empty_string\n    println!(\n        \"\\\n            \\\n            \"\n            ,\n    );\n\n    match \"a\" {\n        _ => println!(\"\" ,), // there is a space between \"\" and comma\n        //~^ println_empty_string\n    }\n\n    eprintln!(\"\"\t,); // there is a tab between \"\" and comma\n    //~^ println_empty_string\n\n    match \"a\" {\n        _ => eprintln!(\"\"\t ,), // tab and space between \"\" and comma\n        //~^ println_empty_string\n    }\n}\n"
  },
  {
    "path": "tests/ui/println_empty_string.stderr",
    "content": "error: empty string literal in `println!`\n  --> tests/ui/println_empty_string.rs:5:5\n   |\nLL |     println!(\"\");\n   |     ^^^^^^^^^--^\n   |              |\n   |              help: remove the empty string\n   |\n   = note: `-D clippy::println-empty-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]`\n\nerror: empty string literal in `println!`\n  --> tests/ui/println_empty_string.rs:9:14\n   |\nLL |         _ => println!(\"\"),\n   |              ^^^^^^^^^--^\n   |                       |\n   |                       help: remove the empty string\n\nerror: empty string literal in `eprintln!`\n  --> tests/ui/println_empty_string.rs:14:5\n   |\nLL |     eprintln!(\"\");\n   |     ^^^^^^^^^^--^\n   |               |\n   |               help: remove the empty string\n\nerror: empty string literal in `eprintln!`\n  --> tests/ui/println_empty_string.rs:18:14\n   |\nLL |         _ => eprintln!(\"\"),\n   |              ^^^^^^^^^^--^\n   |                        |\n   |                        help: remove the empty string\n\nerror: empty string literal in `println!`\n  --> tests/ui/println_empty_string.rs:26:5\n   |\nLL | /      println!(\nLL | |/         \"\\\nLL | ||             \\\nLL | ||             \"\nLL | ||             ,\nLL | ||     );\n   | ||____-^\n   |  |____|\n   |       help: remove the empty string\n\nerror: empty string literal in `println!`\n  --> tests/ui/println_empty_string.rs:34:14\n   |\nLL |         _ => println!(\"\" ,), // there is a space between \"\" and comma\n   |              ^^^^^^^^^----^\n   |                       |\n   |                       help: remove the empty string\n\nerror: empty string literal in `eprintln!`\n  --> tests/ui/println_empty_string.rs:38:5\n   |\nLL |     eprintln!(\"\"    ,); // there is a tab between \"\" and comma\n   |     ^^^^^^^^^^-------^\n   |               |\n   |               help: remove the empty string\n\nerror: empty string literal in `eprintln!`\n  --> tests/ui/println_empty_string.rs:42:14\n   |\nLL |         _ => eprintln!(\"\"     ,), // tab and space between \"\" and comma\n   |              ^^^^^^^^^^--------^\n   |                        |\n   |                        help: remove the empty string\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/println_empty_string_unfixable.rs",
    "content": "#![allow(clippy::match_single_binding)]\n\n// If there is a comment in the span of macro call, we don't provide an auto-fix suggestion.\n#[rustfmt::skip]\nfn issue_16167() {\n    //~v println_empty_string\n    println!(\"\" /* comment */);\n    //~v println_empty_string\n    eprintln!(\"\" /* comment */);\n\n    //~v println_empty_string\n    println!( // comment\n                \"\");\n    //~v println_empty_string\n    eprintln!( // comment\n                \"\");\n\n    //~v println_empty_string\n    println!(\"\", /* comment */);\n\n    //~v println_empty_string\n    println!(\n        \"\\\n            \\\n            \",\n\n    // there is a comment in the macro span regardless of its position\n\n    );\n}\n"
  },
  {
    "path": "tests/ui/println_empty_string_unfixable.stderr",
    "content": "error: empty string literal in `println!`\n  --> tests/ui/println_empty_string_unfixable.rs:7:5\n   |\nLL |     println!(\"\" /* comment */);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: remove the empty string\n  --> tests/ui/println_empty_string_unfixable.rs:7:14\n   |\nLL |     println!(\"\" /* comment */);\n   |              ^^\n   = note: `-D clippy::println-empty-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::println_empty_string)]`\n\nerror: empty string literal in `eprintln!`\n  --> tests/ui/println_empty_string_unfixable.rs:9:5\n   |\nLL |     eprintln!(\"\" /* comment */);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: remove the empty string\n  --> tests/ui/println_empty_string_unfixable.rs:9:15\n   |\nLL |     eprintln!(\"\" /* comment */);\n   |               ^^\n\nerror: empty string literal in `println!`\n  --> tests/ui/println_empty_string_unfixable.rs:12:5\n   |\nLL | /     println!( // comment\nLL | |                 \"\");\n   | |___________________^\n   |\nnote: remove the empty string\n  --> tests/ui/println_empty_string_unfixable.rs:13:17\n   |\nLL |                 \"\");\n   |                 ^^\n\nerror: empty string literal in `eprintln!`\n  --> tests/ui/println_empty_string_unfixable.rs:15:5\n   |\nLL | /     eprintln!( // comment\nLL | |                 \"\");\n   | |___________________^\n   |\nnote: remove the empty string\n  --> tests/ui/println_empty_string_unfixable.rs:16:17\n   |\nLL |                 \"\");\n   |                 ^^\n\nerror: empty string literal in `println!`\n  --> tests/ui/println_empty_string_unfixable.rs:19:5\n   |\nLL |     println!(\"\", /* comment */);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: remove the empty string\n  --> tests/ui/println_empty_string_unfixable.rs:19:14\n   |\nLL |     println!(\"\", /* comment */);\n   |              ^^\n\nerror: empty string literal in `println!`\n  --> tests/ui/println_empty_string_unfixable.rs:22:5\n   |\nLL | /     println!(\nLL | |         \"\\\nLL | |             \\\nLL | |             \",\n...  |\nLL | |     );\n   | |_____^\n   |\nnote: remove the empty string\n  --> tests/ui/println_empty_string_unfixable.rs:23:9\n   |\nLL | /         \"\\\nLL | |             \\\nLL | |             \",\n   | |_____________^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/proc_macro.rs",
    "content": "//! Check that we correctly lint procedural macros.\n\nextern crate proc_macro;\n\nuse proc_macro::TokenStream;\n\n#[allow(dead_code)]\nfn f() {\n    let _x = 3.14;\n    //~^ ERROR: approximate value of `f{32, 64}::consts::PI` found\n}\n\n#[proc_macro]\npub fn mybangmacro(t: TokenStream) -> TokenStream {\n    t\n}\n\n#[proc_macro_derive(MyDerivedTrait)]\npub fn myderive(t: TokenStream) -> TokenStream {\n    t\n}\n\n#[proc_macro_attribute]\npub fn myattribute(t: TokenStream, a: TokenStream) -> TokenStream {\n    t\n}\n"
  },
  {
    "path": "tests/ui/proc_macro.stderr",
    "content": "error: approximate value of `f{32, 64}::consts::PI` found\n  --> tests/ui/proc_macro.rs:9:14\n   |\nLL |     let _x = 3.14;\n   |              ^^^^\n   |\n   = help: consider using the constant directly\n   = note: `#[deny(clippy::approx_constant)]` on by default\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/ptr_arg.rs",
    "content": "#![allow(\n    unused,\n    clippy::many_single_char_names,\n    clippy::needless_lifetimes,\n    clippy::redundant_clone,\n    clippy::needless_pass_by_ref_mut\n)]\n#![warn(clippy::ptr_arg)]\n//@no-rustfix\nuse std::borrow::Cow;\nuse std::path::{Path, PathBuf};\n\nfn do_vec(x: &Vec<i64>) {\n    //~^ ptr_arg\n\n    //Nothing here\n}\n\nfn do_vec_mut(x: &mut Vec<i64>) {\n    //~^ ptr_arg\n\n    //Nothing here\n}\n\nfn do_vec_mut2(x: &mut Vec<i64>) {\n    //~^ ptr_arg\n\n    x.len();\n    x.is_empty();\n}\n\nfn do_str(x: &String) {\n    //~^ ptr_arg\n\n    //Nothing here either\n}\n\nfn do_str_mut(x: &mut String) {\n    //~^ ptr_arg\n\n    //Nothing here either\n}\n\nfn do_path(x: &PathBuf) {\n    //~^ ptr_arg\n\n    //Nothing here either\n}\n\nfn do_path_mut(x: &mut PathBuf) {\n    //~^ ptr_arg\n\n    //Nothing here either\n}\n\nfn main() {}\n\ntrait Foo {\n    type Item;\n    fn do_vec(x: &Vec<i64>);\n    //~^ ptr_arg\n\n    fn do_item(x: &Self::Item);\n}\n\nstruct Bar;\n\n// no error, in trait impl (#425)\nimpl Foo for Bar {\n    type Item = Vec<u8>;\n    fn do_vec(x: &Vec<i64>) {}\n    fn do_item(x: &Vec<u8>) {}\n}\n\nfn cloned(x: &Vec<u8>) -> Vec<u8> {\n    //~^ ptr_arg\n\n    let e = x.clone();\n    let f = e.clone(); // OK\n    let g = x;\n    let h = g.clone();\n    let i = (e).clone();\n    x.clone()\n}\n\nfn str_cloned(x: &String) -> String {\n    //~^ ptr_arg\n\n    let a = x.clone();\n    let b = x.clone();\n    let c = b.clone();\n    let d = a.clone().clone().clone();\n    x.clone()\n}\n\nfn path_cloned(x: &PathBuf) -> PathBuf {\n    //~^ ptr_arg\n\n    let a = x.clone();\n    let b = x.clone();\n    let c = b.clone();\n    let d = a.clone().clone().clone();\n    x.clone()\n}\n\nfn false_positive_capacity(x: &Vec<u8>, y: &String) {\n    //~^ ptr_arg\n\n    let a = x.capacity();\n    let b = y.clone();\n    let c = y.as_str();\n}\n\nfn false_positive_capacity_too(x: &String) -> String {\n    if x.capacity() > 1024 {\n        panic!(\"Too large!\");\n    }\n    x.clone()\n}\n\n#[allow(dead_code)]\nfn test_cow_with_ref(c: &Cow<[i32]>) {}\n//~^ ptr_arg\n\nfn test_cow(c: Cow<[i32]>) {\n    let d = c;\n}\n\ntrait Foo2 {\n    fn do_string(&self);\n}\n\n// no error for &self references where self is of type String (#2293)\nimpl Foo2 for String {\n    fn do_string(&self) {}\n}\n\n// Check that the allow attribute on parameters is honored\nmod issue_5644 {\n    use std::borrow::Cow;\n    use std::path::PathBuf;\n\n    fn allowed(\n        #[allow(clippy::ptr_arg)] v: &Vec<u32>,\n        #[allow(clippy::ptr_arg)] s: &String,\n        #[allow(clippy::ptr_arg)] p: &PathBuf,\n        #[allow(clippy::ptr_arg)] c: &Cow<[i32]>,\n        #[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,\n    ) {\n    }\n\n    fn some_allowed(#[allow(clippy::ptr_arg)] v: &Vec<u32>, s: &String) {}\n    //~^ ptr_arg\n\n    struct S;\n    impl S {\n        fn allowed(\n            #[allow(clippy::ptr_arg)] v: &Vec<u32>,\n            #[allow(clippy::ptr_arg)] s: &String,\n            #[allow(clippy::ptr_arg)] p: &PathBuf,\n            #[allow(clippy::ptr_arg)] c: &Cow<[i32]>,\n            #[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,\n        ) {\n        }\n    }\n\n    trait T {\n        fn allowed(\n            #[allow(clippy::ptr_arg)] v: &Vec<u32>,\n            #[allow(clippy::ptr_arg)] s: &String,\n            #[allow(clippy::ptr_arg)] p: &PathBuf,\n            #[allow(clippy::ptr_arg)] c: &Cow<[i32]>,\n            #[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,\n        ) {\n        }\n    }\n}\n\nmod issue6509 {\n    use std::path::PathBuf;\n\n    fn foo_vec(vec: &Vec<u8>) {\n        //~^ ptr_arg\n\n        let a = vec.clone().pop();\n        let b = vec.clone().clone();\n    }\n\n    fn foo_path(path: &PathBuf) {\n        //~^ ptr_arg\n\n        let c = path.clone().pop();\n        let d = path.clone().clone();\n    }\n\n    fn foo_str(str: &String) {\n        //~^ ptr_arg\n\n        let e = str.clone().pop();\n        let f = str.clone().clone();\n    }\n}\n\nfn mut_vec_slice_methods(v: &mut Vec<u32>) {\n    //~^ ptr_arg\n\n    v.copy_within(1..5, 10);\n}\n\nfn mut_vec_vec_methods(v: &mut Vec<u32>) {\n    v.clear();\n}\n\nfn vec_contains(v: &Vec<u32>) -> bool {\n    [vec![], vec![0]].as_slice().contains(v)\n}\n\nfn fn_requires_vec(v: &Vec<u32>) -> bool {\n    vec_contains(v)\n}\n\nfn impl_fn_requires_vec(v: &Vec<u32>, f: impl Fn(&Vec<u32>)) {\n    f(v);\n}\n\nfn dyn_fn_requires_vec(v: &Vec<u32>, f: &dyn Fn(&Vec<u32>)) {\n    f(v);\n}\n\n// No error for types behind an alias (#7699)\ntype A = Vec<u8>;\nfn aliased(a: &A) {}\n\n// Issue #8366\npub trait Trait {\n    fn f(v: &mut Vec<i32>);\n    fn f2(v: &mut Vec<i32>) {}\n}\n\n// Issue #8463\nfn two_vecs(a: &mut Vec<u32>, b: &mut Vec<u32>) {\n    a.push(0);\n    a.push(0);\n    a.push(0);\n    b.push(1);\n}\n\n// Issue #8495\nfn cow_conditional_to_mut(a: &mut Cow<str>) {\n    if a.is_empty() {\n        a.to_mut().push_str(\"foo\");\n    }\n}\n\n// Issue #9542\nfn dyn_trait_ok(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {\n    trait T {}\n    impl<U> T for Vec<U> {}\n    impl T for String {}\n    impl T for PathBuf {}\n    fn takes_dyn(_: &mut dyn T) {}\n\n    takes_dyn(a);\n    takes_dyn(b);\n    takes_dyn(c);\n}\n\nfn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {\n    //~^ ptr_arg\n    //~| ptr_arg\n    //~| ptr_arg\n\n    trait T {}\n    impl<U> T for Vec<U> {}\n    impl<U> T for [U] {}\n    impl T for String {}\n    impl T for str {}\n    impl T for PathBuf {}\n    impl T for Path {}\n    fn takes_dyn(_: &mut dyn T) {}\n\n    takes_dyn(a);\n    takes_dyn(b);\n    takes_dyn(c);\n}\n\nmod issue_9218 {\n    use std::borrow::Cow;\n\n    fn cow_non_elided_lifetime<'a>(input: &Cow<'a, str>) -> &'a str {\n        todo!()\n    }\n\n    // This one has an anonymous lifetime so it's not okay\n    fn cow_elided_lifetime<'a>(input: &'a Cow<str>) -> &'a str {\n        //~^ ptr_arg\n\n        todo!()\n    }\n\n    // These two's return types don't use 'a so it's not okay\n    fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str {\n        //~^ ptr_arg\n\n        todo!()\n    }\n    fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str {\n        //~^ ptr_arg\n\n        todo!()\n    }\n\n    // Inferred to be `&'a str`, afaik.\n    fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {\n        //~^ ERROR: eliding a lifetime that's named elsewhere is confusing\n        todo!()\n    }\n}\n\nmod issue_11181 {\n    extern \"C\" fn allowed(_v: &Vec<u32>) {}\n\n    struct S;\n    impl S {\n        extern \"C\" fn allowed(_v: &Vec<u32>) {}\n    }\n\n    trait T {\n        extern \"C\" fn allowed(_v: &Vec<u32>) {}\n    }\n}\n\nmod issue_13308 {\n    use std::ops::Deref;\n\n    fn repro(source: &str, destination: &mut String) {\n        source.clone_into(destination);\n    }\n    fn repro2(source: &str, destination: &mut String) {\n        ToOwned::clone_into(source, destination);\n    }\n\n    fn h1(x: &<String as Deref>::Target) {}\n    fn h2<T: Deref>(x: T, y: &T::Target) {}\n\n    // Other cases that are still ok to lint and ideally shouldn't regress\n    fn good(v1: &String, v2: &String) {\n        //~^ ptr_arg\n        //~| ptr_arg\n\n        h1(v1);\n        h2(String::new(), v2);\n    }\n}\n\nmod issue_13489_and_13728 {\n    // This is a no-lint from now on.\n    fn foo(_x: &Vec<i32>) {\n        todo!();\n    }\n\n    // But this still gives us a lint.\n    fn foo_used(x: &Vec<i32>) {\n        //~^ ptr_arg\n\n        todo!();\n    }\n\n    // This is also a no-lint from now on.\n    fn foo_local(x: &Vec<i32>) {\n        let _y = x;\n\n        todo!();\n    }\n\n    // But this still gives us a lint.\n    fn foo_local_used(x: &Vec<i32>) {\n        //~^ ptr_arg\n\n        let y = x;\n\n        todo!();\n    }\n\n    // This only lints once from now on.\n    fn foofoo(_x: &Vec<i32>, y: &String) {\n        //~^ ptr_arg\n\n        todo!();\n    }\n\n    // And this is also a no-lint from now on.\n    fn foofoo_local(_x: &Vec<i32>, y: &String) {\n        let _z = y;\n\n        todo!();\n    }\n}\n\nmod issue_13489_and_13728_mut {\n    // This is a no-lint from now on.\n    fn bar(_x: &mut Vec<u32>) {\n        todo!()\n    }\n\n    // But this still gives us a lint.\n    fn bar_used(x: &mut Vec<u32>) {\n        //~^ ptr_arg\n\n        todo!()\n    }\n\n    // This is also a no-lint from now on.\n    fn bar_local(x: &mut Vec<u32>) {\n        let _y = x;\n\n        todo!()\n    }\n\n    // But this still gives us a lint.\n    fn bar_local_used(x: &mut Vec<u32>) {\n        //~^ ptr_arg\n\n        let y = x;\n\n        todo!()\n    }\n\n    // This only lints once from now on.\n    fn barbar(_x: &mut Vec<u32>, y: &mut String) {\n        //~^ ptr_arg\n\n        todo!()\n    }\n\n    // And this is also a no-lint from now on.\n    fn barbar_local(_x: &mut Vec<u32>, y: &mut String) {\n        let _z = y;\n\n        todo!()\n    }\n}\n"
  },
  {
    "path": "tests/ui/ptr_arg.stderr",
    "content": "error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:13:14\n   |\nLL | fn do_vec(x: &Vec<i64>) {\n   |              ^^^^^^^^^\n   |\n   = note: `-D clippy::ptr-arg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ptr_arg)]`\nhelp: change this to\n   |\nLL - fn do_vec(x: &Vec<i64>) {\nLL + fn do_vec(x: &[i64]) {\n   |\n\nerror: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:19:18\n   |\nLL | fn do_vec_mut(x: &mut Vec<i64>) {\n   |                  ^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn do_vec_mut(x: &mut Vec<i64>) {\nLL + fn do_vec_mut(x: &mut [i64]) {\n   |\n\nerror: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:25:19\n   |\nLL | fn do_vec_mut2(x: &mut Vec<i64>) {\n   |                   ^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn do_vec_mut2(x: &mut Vec<i64>) {\nLL + fn do_vec_mut2(x: &mut [i64]) {\n   |\n\nerror: writing `&String` instead of `&str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:32:14\n   |\nLL | fn do_str(x: &String) {\n   |              ^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn do_str(x: &String) {\nLL + fn do_str(x: &str) {\n   |\n\nerror: writing `&mut String` instead of `&mut str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:38:18\n   |\nLL | fn do_str_mut(x: &mut String) {\n   |                  ^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn do_str_mut(x: &mut String) {\nLL + fn do_str_mut(x: &mut str) {\n   |\n\nerror: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:44:15\n   |\nLL | fn do_path(x: &PathBuf) {\n   |               ^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn do_path(x: &PathBuf) {\nLL + fn do_path(x: &Path) {\n   |\n\nerror: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:50:19\n   |\nLL | fn do_path_mut(x: &mut PathBuf) {\n   |                   ^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn do_path_mut(x: &mut PathBuf) {\nLL + fn do_path_mut(x: &mut Path) {\n   |\n\nerror: writing `&Vec` instead of `&[_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:60:18\n   |\nLL |     fn do_vec(x: &Vec<i64>);\n   |                  ^^^^^^^^^ help: change this to: `&[i64]`\n\nerror: writing `&Vec` instead of `&[_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:75:14\n   |\nLL | fn cloned(x: &Vec<u8>) -> Vec<u8> {\n   |              ^^^^^^^^\n   |\nhelp: change this to\n   |\nLL ~ fn cloned(x: &[u8]) -> Vec<u8> {\nLL |\nLL |\nLL ~     let e = x.to_owned();\nLL |     let f = e.clone(); // OK\nLL |     let g = x;\nLL ~     let h = g.to_owned();\nLL |     let i = (e).clone();\nLL ~     x.to_owned()\n   |\n\nerror: writing `&String` instead of `&str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:86:18\n   |\nLL | fn str_cloned(x: &String) -> String {\n   |                  ^^^^^^^\n   |\nhelp: change this to\n   |\nLL ~ fn str_cloned(x: &str) -> String {\nLL |\nLL |\nLL ~     let a = x.to_owned();\nLL ~     let b = x.to_owned();\nLL |     let c = b.clone();\nLL |     let d = a.clone().clone().clone();\nLL ~     x.to_owned()\n   |\n\nerror: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:96:19\n   |\nLL | fn path_cloned(x: &PathBuf) -> PathBuf {\n   |                   ^^^^^^^^\n   |\nhelp: change this to\n   |\nLL ~ fn path_cloned(x: &Path) -> PathBuf {\nLL |\nLL |\nLL ~     let a = x.to_path_buf();\nLL ~     let b = x.to_path_buf();\nLL |     let c = b.clone();\nLL |     let d = a.clone().clone().clone();\nLL ~     x.to_path_buf()\n   |\n\nerror: writing `&String` instead of `&str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:106:44\n   |\nLL | fn false_positive_capacity(x: &Vec<u8>, y: &String) {\n   |                                            ^^^^^^^\n   |\nhelp: change this to\n   |\nLL ~ fn false_positive_capacity(x: &Vec<u8>, y: &str) {\nLL |\nLL |\nLL |     let a = x.capacity();\nLL ~     let b = y.to_owned();\nLL ~     let c = y;\n   |\n\nerror: using a reference to `Cow` is not recommended\n  --> tests/ui/ptr_arg.rs:122:25\n   |\nLL | fn test_cow_with_ref(c: &Cow<[i32]>) {}\n   |                         ^^^^^^^^^^^ help: change this to: `&[i32]`\n\nerror: writing `&String` instead of `&str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:152:64\n   |\nLL |     fn some_allowed(#[allow(clippy::ptr_arg)] v: &Vec<u32>, s: &String) {}\n   |                                                                ^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn some_allowed(#[allow(clippy::ptr_arg)] v: &Vec<u32>, s: &String) {}\nLL +     fn some_allowed(#[allow(clippy::ptr_arg)] v: &Vec<u32>, s: &str) {}\n   |\n\nerror: writing `&Vec` instead of `&[_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:182:21\n   |\nLL |     fn foo_vec(vec: &Vec<u8>) {\n   |                     ^^^^^^^^\n   |\nhelp: change this to\n   |\nLL ~     fn foo_vec(vec: &[u8]) {\nLL |\nLL |\nLL ~         let a = vec.to_owned().pop();\nLL ~         let b = vec.to_owned().clone();\n   |\n\nerror: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:189:23\n   |\nLL |     fn foo_path(path: &PathBuf) {\n   |                       ^^^^^^^^\n   |\nhelp: change this to\n   |\nLL ~     fn foo_path(path: &Path) {\nLL |\nLL |\nLL ~         let c = path.to_path_buf().pop();\nLL ~         let d = path.to_path_buf().clone();\n   |\n\nerror: writing `&String` instead of `&str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:196:21\n   |\nLL |     fn foo_str(str: &String) {\n   |                     ^^^^^^^\n   |\nhelp: change this to\n   |\nLL ~     fn foo_str(str: &str) {\nLL |\nLL |\nLL ~         let e = str.to_owned().pop();\nLL ~         let f = str.to_owned().clone();\n   |\n\nerror: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:204:29\n   |\nLL | fn mut_vec_slice_methods(v: &mut Vec<u32>) {\n   |                             ^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn mut_vec_slice_methods(v: &mut Vec<u32>) {\nLL + fn mut_vec_slice_methods(v: &mut [u32]) {\n   |\n\nerror: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:268:17\n   |\nLL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {\n   |                 ^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {\nLL + fn dyn_trait(a: &mut [u32], b: &mut String, c: &mut PathBuf) {\n   |\n\nerror: writing `&mut String` instead of `&mut str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:268:35\n   |\nLL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {\n   |                                   ^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {\nLL + fn dyn_trait(a: &mut Vec<u32>, b: &mut str, c: &mut PathBuf) {\n   |\n\nerror: writing `&mut PathBuf` instead of `&mut Path` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:268:51\n   |\nLL | fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {\n   |                                                   ^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut PathBuf) {\nLL + fn dyn_trait(a: &mut Vec<u32>, b: &mut String, c: &mut Path) {\n   |\n\nerror: using a reference to `Cow` is not recommended\n  --> tests/ui/ptr_arg.rs:295:39\n   |\nLL |     fn cow_elided_lifetime<'a>(input: &'a Cow<str>) -> &'a str {\n   |                                       ^^^^^^^^^^^^ help: change this to: `&str`\n\nerror: using a reference to `Cow` is not recommended\n  --> tests/ui/ptr_arg.rs:302:36\n   |\nLL |     fn cow_bad_ret_ty_1<'a>(input: &'a Cow<'a, str>) -> &'static str {\n   |                                    ^^^^^^^^^^^^^^^^ help: change this to: `&str`\n\nerror: using a reference to `Cow` is not recommended\n  --> tests/ui/ptr_arg.rs:307:40\n   |\nLL |     fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str {\n   |                                        ^^^^^^^^^^^^^^^^ help: change this to: `&str`\n\nerror: writing `&String` instead of `&str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:347:17\n   |\nLL |     fn good(v1: &String, v2: &String) {\n   |                 ^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn good(v1: &String, v2: &String) {\nLL +     fn good(v1: &str, v2: &String) {\n   |\n\nerror: writing `&String` instead of `&str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:347:30\n   |\nLL |     fn good(v1: &String, v2: &String) {\n   |                              ^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn good(v1: &String, v2: &String) {\nLL +     fn good(v1: &String, v2: &str) {\n   |\n\nerror: writing `&Vec` instead of `&[_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:363:20\n   |\nLL |     fn foo_used(x: &Vec<i32>) {\n   |                    ^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn foo_used(x: &Vec<i32>) {\nLL +     fn foo_used(x: &[i32]) {\n   |\n\nerror: writing `&Vec` instead of `&[_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:377:26\n   |\nLL |     fn foo_local_used(x: &Vec<i32>) {\n   |                          ^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn foo_local_used(x: &Vec<i32>) {\nLL +     fn foo_local_used(x: &[i32]) {\n   |\n\nerror: writing `&String` instead of `&str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:386:33\n   |\nLL |     fn foofoo(_x: &Vec<i32>, y: &String) {\n   |                                 ^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn foofoo(_x: &Vec<i32>, y: &String) {\nLL +     fn foofoo(_x: &Vec<i32>, y: &str) {\n   |\n\nerror: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:407:20\n   |\nLL |     fn bar_used(x: &mut Vec<u32>) {\n   |                    ^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn bar_used(x: &mut Vec<u32>) {\nLL +     fn bar_used(x: &mut [u32]) {\n   |\n\nerror: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:421:26\n   |\nLL |     fn bar_local_used(x: &mut Vec<u32>) {\n   |                          ^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn bar_local_used(x: &mut Vec<u32>) {\nLL +     fn bar_local_used(x: &mut [u32]) {\n   |\n\nerror: writing `&mut String` instead of `&mut str` involves a new object where a slice will do\n  --> tests/ui/ptr_arg.rs:430:37\n   |\nLL |     fn barbar(_x: &mut Vec<u32>, y: &mut String) {\n   |                                     ^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn barbar(_x: &mut Vec<u32>, y: &mut String) {\nLL +     fn barbar(_x: &mut Vec<u32>, y: &mut str) {\n   |\n\nerror: eliding a lifetime that's named elsewhere is confusing\n  --> tests/ui/ptr_arg.rs:314:56\n   |\nLL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {\n   |                                    --     --           ^^^^ the same lifetime is elided here\n   |                                    |      |\n   |                                    |      the lifetime is named here\n   |                                    the lifetime is named here\n   |\n   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing\n   = note: `-D mismatched-lifetime-syntaxes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(mismatched_lifetime_syntaxes)]`\nhelp: consistently use `'a`\n   |\nLL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &'a str {\n   |                                                         ++\n\nerror: aborting due to 33 previous errors\n\n"
  },
  {
    "path": "tests/ui/ptr_as_ptr.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::ptr_as_ptr)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros, with_span};\n\nmod issue_11278_a {\n    #[derive(Debug)]\n    pub struct T<D: std::fmt::Debug + ?Sized> {\n        pub p: D,\n    }\n}\n\nmod issue_11278_b {\n    pub fn f(o: &mut super::issue_11278_a::T<dyn std::fmt::Debug>) -> super::issue_11278_a::T<String> {\n        // Retain `super`\n        *unsafe { Box::from_raw(Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()) }\n        //~^ ptr_as_ptr\n    }\n}\n\n#[inline_macros]\nfn main() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    let _ = ptr.cast::<i32>();\n    //~^ ptr_as_ptr\n    let _ = mut_ptr.cast::<i32>();\n    //~^ ptr_as_ptr\n\n    // Make sure the lint can handle the difference in their operator precedences.\n    unsafe {\n        let ptr_ptr: *const *const u32 = &ptr;\n        let _ = (*ptr_ptr).cast::<i32>();\n        //~^ ptr_as_ptr\n    }\n\n    // Changes in mutability. Do not lint this.\n    let _ = ptr as *mut i32;\n    let _ = mut_ptr as *const i32;\n\n    // `pointer::cast` cannot perform unsized coercions unlike `as`. Do not lint this.\n    let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4];\n    let _ = ptr_of_array as *const [u32];\n    let _ = ptr_of_array as *const dyn std::fmt::Debug;\n\n    // Ensure the lint doesn't produce unnecessary turbofish for inferred types.\n    let _: *const i32 = ptr.cast();\n    //~^ ptr_as_ptr\n    let _: *mut i32 = mut_ptr.cast();\n    //~^ ptr_as_ptr\n\n    // Make sure the lint is triggered inside a macro\n    // FIXME: `is_from_proc_macro` incorrectly stops the lint from firing here\n    let _ = inline!($ptr as *const i32);\n\n    // Do not lint inside macros from external crates\n    let _ = external!($ptr as *const i32);\n\n    let _ = with_span!(expr $ptr as *const i32);\n}\n\n#[clippy::msrv = \"1.37\"]\nfn _msrv_1_37() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    // `pointer::cast` was stabilized in 1.38. Do not lint this\n    let _ = ptr as *const i32;\n    let _ = mut_ptr as *mut i32;\n}\n\n#[clippy::msrv = \"1.38\"]\nfn _msrv_1_38() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    let _ = ptr.cast::<i32>();\n    //~^ ptr_as_ptr\n    let _ = mut_ptr.cast::<i32>();\n    //~^ ptr_as_ptr\n}\n\n#[allow(clippy::unnecessary_cast)]\nmod null {\n    fn use_path_mut() -> *mut u32 {\n        use std::ptr;\n        ptr::null_mut::<u32>()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path_mut() -> *mut u32 {\n        std::ptr::null_mut::<u32>()\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path_mut() -> *mut u32 {\n        use core::ptr;\n        ptr::null_mut::<u32>()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path_mut() -> *mut u32 {\n        core::ptr::null_mut::<u32>()\n        //~^ ptr_as_ptr\n    }\n\n    fn use_path() -> *const u32 {\n        use std::ptr;\n        ptr::null::<u32>()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path() -> *const u32 {\n        std::ptr::null::<u32>()\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path() -> *const u32 {\n        use core::ptr;\n        ptr::null::<u32>()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path() -> *const u32 {\n        core::ptr::null::<u32>()\n        //~^ ptr_as_ptr\n    }\n}\n\nmod null_ptr_infer {\n    fn use_path_mut() -> *mut u32 {\n        use std::ptr;\n        ptr::null_mut()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path_mut() -> *mut u32 {\n        std::ptr::null_mut()\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path_mut() -> *mut u32 {\n        use core::ptr;\n        ptr::null_mut()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path_mut() -> *mut u32 {\n        core::ptr::null_mut()\n        //~^ ptr_as_ptr\n    }\n\n    fn use_path() -> *const u32 {\n        use std::ptr;\n        ptr::null()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path() -> *const u32 {\n        std::ptr::null()\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path() -> *const u32 {\n        use core::ptr;\n        ptr::null()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path() -> *const u32 {\n        core::ptr::null()\n        //~^ ptr_as_ptr\n    }\n}\n\nmod null_entire_infer {\n    fn use_path_mut() -> *mut u32 {\n        use std::ptr;\n        ptr::null_mut()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path_mut() -> *mut u32 {\n        std::ptr::null_mut()\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path_mut() -> *mut u32 {\n        use core::ptr;\n        ptr::null_mut()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path_mut() -> *mut u32 {\n        core::ptr::null_mut()\n        //~^ ptr_as_ptr\n    }\n\n    fn use_path() -> *const u32 {\n        use std::ptr;\n        ptr::null()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path() -> *const u32 {\n        std::ptr::null()\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path() -> *const u32 {\n        use core::ptr;\n        ptr::null()\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path() -> *const u32 {\n        core::ptr::null()\n        //~^ ptr_as_ptr\n    }\n}\n\n#[allow(clippy::transmute_null_to_fn)]\nfn issue15283() {\n    unsafe {\n        let _: fn() = std::mem::transmute(std::ptr::null::<u8>());\n        //~^ ptr_as_ptr\n    }\n}\n\nfn issue15232() {\n    let mut b = Box::new(0i32);\n    let _ptr = std::ptr::addr_of_mut!(*b).cast::<()>();\n    //~^ ptr_as_ptr\n}\n"
  },
  {
    "path": "tests/ui/ptr_as_ptr.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::ptr_as_ptr)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros, with_span};\n\nmod issue_11278_a {\n    #[derive(Debug)]\n    pub struct T<D: std::fmt::Debug + ?Sized> {\n        pub p: D,\n    }\n}\n\nmod issue_11278_b {\n    pub fn f(o: &mut super::issue_11278_a::T<dyn std::fmt::Debug>) -> super::issue_11278_a::T<String> {\n        // Retain `super`\n        *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }\n        //~^ ptr_as_ptr\n    }\n}\n\n#[inline_macros]\nfn main() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    let _ = ptr as *const i32;\n    //~^ ptr_as_ptr\n    let _ = mut_ptr as *mut i32;\n    //~^ ptr_as_ptr\n\n    // Make sure the lint can handle the difference in their operator precedences.\n    unsafe {\n        let ptr_ptr: *const *const u32 = &ptr;\n        let _ = *ptr_ptr as *const i32;\n        //~^ ptr_as_ptr\n    }\n\n    // Changes in mutability. Do not lint this.\n    let _ = ptr as *mut i32;\n    let _ = mut_ptr as *const i32;\n\n    // `pointer::cast` cannot perform unsized coercions unlike `as`. Do not lint this.\n    let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4];\n    let _ = ptr_of_array as *const [u32];\n    let _ = ptr_of_array as *const dyn std::fmt::Debug;\n\n    // Ensure the lint doesn't produce unnecessary turbofish for inferred types.\n    let _: *const i32 = ptr as *const _;\n    //~^ ptr_as_ptr\n    let _: *mut i32 = mut_ptr as _;\n    //~^ ptr_as_ptr\n\n    // Make sure the lint is triggered inside a macro\n    // FIXME: `is_from_proc_macro` incorrectly stops the lint from firing here\n    let _ = inline!($ptr as *const i32);\n\n    // Do not lint inside macros from external crates\n    let _ = external!($ptr as *const i32);\n\n    let _ = with_span!(expr $ptr as *const i32);\n}\n\n#[clippy::msrv = \"1.37\"]\nfn _msrv_1_37() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    // `pointer::cast` was stabilized in 1.38. Do not lint this\n    let _ = ptr as *const i32;\n    let _ = mut_ptr as *mut i32;\n}\n\n#[clippy::msrv = \"1.38\"]\nfn _msrv_1_38() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    let _ = ptr as *const i32;\n    //~^ ptr_as_ptr\n    let _ = mut_ptr as *mut i32;\n    //~^ ptr_as_ptr\n}\n\n#[allow(clippy::unnecessary_cast)]\nmod null {\n    fn use_path_mut() -> *mut u32 {\n        use std::ptr;\n        ptr::null_mut() as *mut u32\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path_mut() -> *mut u32 {\n        std::ptr::null_mut() as *mut u32\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path_mut() -> *mut u32 {\n        use core::ptr;\n        ptr::null_mut() as *mut u32\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path_mut() -> *mut u32 {\n        core::ptr::null_mut() as *mut u32\n        //~^ ptr_as_ptr\n    }\n\n    fn use_path() -> *const u32 {\n        use std::ptr;\n        ptr::null() as *const u32\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path() -> *const u32 {\n        std::ptr::null() as *const u32\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path() -> *const u32 {\n        use core::ptr;\n        ptr::null() as *const u32\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path() -> *const u32 {\n        core::ptr::null() as *const u32\n        //~^ ptr_as_ptr\n    }\n}\n\nmod null_ptr_infer {\n    fn use_path_mut() -> *mut u32 {\n        use std::ptr;\n        ptr::null_mut() as *mut _\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path_mut() -> *mut u32 {\n        std::ptr::null_mut() as *mut _\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path_mut() -> *mut u32 {\n        use core::ptr;\n        ptr::null_mut() as *mut _\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path_mut() -> *mut u32 {\n        core::ptr::null_mut() as *mut _\n        //~^ ptr_as_ptr\n    }\n\n    fn use_path() -> *const u32 {\n        use std::ptr;\n        ptr::null() as *const _\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path() -> *const u32 {\n        std::ptr::null() as *const _\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path() -> *const u32 {\n        use core::ptr;\n        ptr::null() as *const _\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path() -> *const u32 {\n        core::ptr::null() as *const _\n        //~^ ptr_as_ptr\n    }\n}\n\nmod null_entire_infer {\n    fn use_path_mut() -> *mut u32 {\n        use std::ptr;\n        ptr::null_mut() as _\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path_mut() -> *mut u32 {\n        std::ptr::null_mut() as _\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path_mut() -> *mut u32 {\n        use core::ptr;\n        ptr::null_mut() as _\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path_mut() -> *mut u32 {\n        core::ptr::null_mut() as _\n        //~^ ptr_as_ptr\n    }\n\n    fn use_path() -> *const u32 {\n        use std::ptr;\n        ptr::null() as _\n        //~^ ptr_as_ptr\n    }\n\n    fn full_path() -> *const u32 {\n        std::ptr::null() as _\n        //~^ ptr_as_ptr\n    }\n\n    fn core_path() -> *const u32 {\n        use core::ptr;\n        ptr::null() as _\n        //~^ ptr_as_ptr\n    }\n\n    fn full_core_path() -> *const u32 {\n        core::ptr::null() as _\n        //~^ ptr_as_ptr\n    }\n}\n\n#[allow(clippy::transmute_null_to_fn)]\nfn issue15283() {\n    unsafe {\n        let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);\n        //~^ ptr_as_ptr\n    }\n}\n\nfn issue15232() {\n    let mut b = Box::new(0i32);\n    let _ptr = std::ptr::addr_of_mut!(*b) as *mut ();\n    //~^ ptr_as_ptr\n}\n"
  },
  {
    "path": "tests/ui/ptr_as_ptr.stderr",
    "content": "error: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:18:33\n   |\nLL |         *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()`\n   |\n   = note: `-D clippy::ptr-as-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:28:13\n   |\nLL |     let _ = ptr as *const i32;\n   |             ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:30:13\n   |\nLL |     let _ = mut_ptr as *mut i32;\n   |             ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:36:17\n   |\nLL |         let _ = *ptr_ptr as *const i32;\n   |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::<i32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:50:25\n   |\nLL |     let _: *const i32 = ptr as *const _;\n   |                         ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:52:23\n   |\nLL |     let _: *mut i32 = mut_ptr as _;\n   |                       ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:80:13\n   |\nLL |     let _ = ptr as *const i32;\n   |             ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:82:13\n   |\nLL |     let _ = mut_ptr as *mut i32;\n   |             ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:90:9\n   |\nLL |         ptr::null_mut() as *mut u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:95:9\n   |\nLL |         std::ptr::null_mut() as *mut u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::<u32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:101:9\n   |\nLL |         ptr::null_mut() as *mut u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:106:9\n   |\nLL |         core::ptr::null_mut() as *mut u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut::<u32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:112:9\n   |\nLL |         ptr::null() as *const u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:117:9\n   |\nLL |         std::ptr::null() as *const u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:123:9\n   |\nLL |         ptr::null() as *const u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:128:9\n   |\nLL |         core::ptr::null() as *const u32\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null::<u32>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:136:9\n   |\nLL |         ptr::null_mut() as *mut _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:141:9\n   |\nLL |         std::ptr::null_mut() as *mut _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:147:9\n   |\nLL |         ptr::null_mut() as *mut _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:152:9\n   |\nLL |         core::ptr::null_mut() as *mut _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:158:9\n   |\nLL |         ptr::null() as *const _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:163:9\n   |\nLL |         std::ptr::null() as *const _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:169:9\n   |\nLL |         ptr::null() as *const _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:174:9\n   |\nLL |         core::ptr::null() as *const _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:182:9\n   |\nLL |         ptr::null_mut() as _\n   |         ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:187:9\n   |\nLL |         std::ptr::null_mut() as _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:193:9\n   |\nLL |         ptr::null_mut() as _\n   |         ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:198:9\n   |\nLL |         core::ptr::null_mut() as _\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:204:9\n   |\nLL |         ptr::null() as _\n   |         ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:209:9\n   |\nLL |         std::ptr::null() as _\n   |         ^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:215:9\n   |\nLL |         ptr::null() as _\n   |         ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:220:9\n   |\nLL |         core::ptr::null() as _\n   |         ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:228:43\n   |\nLL |         let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);\n   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u8>()`\n\nerror: `as` casting between raw pointers without changing their constness\n  --> tests/ui/ptr_as_ptr.rs:235:16\n   |\nLL |     let _ptr = std::ptr::addr_of_mut!(*b) as *mut ();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `std::ptr::addr_of_mut!(*b).cast::<()>()`\n\nerror: aborting due to 34 previous errors\n\n"
  },
  {
    "path": "tests/ui/ptr_cast_constness.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::ptr_cast_constness)]\n#![allow(\n    clippy::transmute_ptr_to_ref,\n    clippy::unnecessary_cast,\n    unused,\n    clippy::missing_transmute_annotations\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nunsafe fn ptr_to_ref<T, U>(p: *const T, om: *mut U) {\n    unsafe {\n        let _: &mut T = std::mem::transmute(p.cast_mut());\n        //~^ ptr_cast_constness\n        let _ = &mut *p.cast_mut();\n        //~^ ptr_cast_constness\n        let _: &T = &*(om as *const T);\n    }\n}\n\n#[inline_macros]\nfn main() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    let _ = ptr as *const u32;\n    let _ = mut_ptr as *mut u32;\n\n    // Make sure the lint can handle the difference in their operator precedences.\n    unsafe {\n        let ptr_ptr: *const *const u32 = &ptr;\n        let _ = (*ptr_ptr).cast_mut();\n        //~^ ptr_cast_constness\n    }\n\n    let _ = ptr.cast_mut();\n    //~^ ptr_cast_constness\n    let _ = mut_ptr.cast_const();\n    //~^ ptr_cast_constness\n\n    // Lint this, since pointer::cast_mut and pointer::cast_const have ?Sized\n    let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4];\n    let _ = ptr_of_array as *const [u32];\n    let _ = ptr_of_array as *const dyn std::fmt::Debug;\n\n    // Make sure the lint is triggered inside a macro\n    let _ = inline!($ptr as *const u32);\n\n    // Do not lint inside macros from external crates\n    let _ = external!($ptr as *const u32);\n}\n\nfn lifetime_to_static(v: *mut &()) -> *const &'static () {\n    v as _\n}\n\n#[clippy::msrv = \"1.64\"]\nfn _msrv_1_64() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    // `pointer::cast_const` and `pointer::cast_mut` were stabilized in 1.65. Do not lint this\n    let _ = ptr as *mut u32;\n    let _ = mut_ptr as *const u32;\n}\n\n#[clippy::msrv = \"1.65\"]\nfn _msrv_1_65() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    let _ = ptr.cast_mut();\n    //~^ ptr_cast_constness\n    let _ = mut_ptr.cast_const();\n    //~^ ptr_cast_constness\n}\n\n#[inline_macros]\nfn null_pointers() {\n    use std::ptr;\n    let _ = std::ptr::null_mut::<String>();\n    //~^ ptr_cast_constness\n    let _ = std::ptr::null::<u32>();\n    //~^ ptr_cast_constness\n    let _ = std::ptr::null_mut::<u32>();\n    //~^ ptr_cast_constness\n    let _ = std::ptr::null::<u32>();\n    //~^ ptr_cast_constness\n\n    // Make sure the lint is triggered inside a macro\n    let _ = inline!(std::ptr::null_mut::<u32>());\n    //~^ ptr_cast_constness\n    let _ = inline!(std::ptr::null_mut::<u32>());\n    //~^ ptr_cast_constness\n\n    // Do not lint inside macros from external crates\n    let _ = external!(ptr::null::<u32>() as *mut u32);\n    let _ = external!(ptr::null::<u32>().cast_mut());\n}\n\nfn issue14621() {\n    let mut local = 4;\n    let _ = std::ptr::addr_of_mut!(local).cast_const();\n    //~^ ptr_cast_constness\n}\n\nfn issue11317() {\n    let r = &0_u32;\n    let _ptr: *mut u32 = (r as *const u32).cast_mut();\n    //~^ ptr_cast_constness\n}\n"
  },
  {
    "path": "tests/ui/ptr_cast_constness.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::ptr_cast_constness)]\n#![allow(\n    clippy::transmute_ptr_to_ref,\n    clippy::unnecessary_cast,\n    unused,\n    clippy::missing_transmute_annotations\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nunsafe fn ptr_to_ref<T, U>(p: *const T, om: *mut U) {\n    unsafe {\n        let _: &mut T = std::mem::transmute(p as *mut T);\n        //~^ ptr_cast_constness\n        let _ = &mut *(p as *mut T);\n        //~^ ptr_cast_constness\n        let _: &T = &*(om as *const T);\n    }\n}\n\n#[inline_macros]\nfn main() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    let _ = ptr as *const u32;\n    let _ = mut_ptr as *mut u32;\n\n    // Make sure the lint can handle the difference in their operator precedences.\n    unsafe {\n        let ptr_ptr: *const *const u32 = &ptr;\n        let _ = *ptr_ptr as *mut u32;\n        //~^ ptr_cast_constness\n    }\n\n    let _ = ptr as *mut u32;\n    //~^ ptr_cast_constness\n    let _ = mut_ptr as *const u32;\n    //~^ ptr_cast_constness\n\n    // Lint this, since pointer::cast_mut and pointer::cast_const have ?Sized\n    let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4];\n    let _ = ptr_of_array as *const [u32];\n    let _ = ptr_of_array as *const dyn std::fmt::Debug;\n\n    // Make sure the lint is triggered inside a macro\n    let _ = inline!($ptr as *const u32);\n\n    // Do not lint inside macros from external crates\n    let _ = external!($ptr as *const u32);\n}\n\nfn lifetime_to_static(v: *mut &()) -> *const &'static () {\n    v as _\n}\n\n#[clippy::msrv = \"1.64\"]\nfn _msrv_1_64() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    // `pointer::cast_const` and `pointer::cast_mut` were stabilized in 1.65. Do not lint this\n    let _ = ptr as *mut u32;\n    let _ = mut_ptr as *const u32;\n}\n\n#[clippy::msrv = \"1.65\"]\nfn _msrv_1_65() {\n    let ptr: *const u32 = &42_u32;\n    let mut_ptr: *mut u32 = &mut 42_u32;\n\n    let _ = ptr as *mut u32;\n    //~^ ptr_cast_constness\n    let _ = mut_ptr as *const u32;\n    //~^ ptr_cast_constness\n}\n\n#[inline_macros]\nfn null_pointers() {\n    use std::ptr;\n    let _ = ptr::null::<String>() as *mut String;\n    //~^ ptr_cast_constness\n    let _ = ptr::null_mut::<u32>() as *const u32;\n    //~^ ptr_cast_constness\n    let _ = ptr::null::<u32>().cast_mut();\n    //~^ ptr_cast_constness\n    let _ = ptr::null_mut::<u32>().cast_const();\n    //~^ ptr_cast_constness\n\n    // Make sure the lint is triggered inside a macro\n    let _ = inline!(ptr::null::<u32>() as *mut u32);\n    //~^ ptr_cast_constness\n    let _ = inline!(ptr::null::<u32>().cast_mut());\n    //~^ ptr_cast_constness\n\n    // Do not lint inside macros from external crates\n    let _ = external!(ptr::null::<u32>() as *mut u32);\n    let _ = external!(ptr::null::<u32>().cast_mut());\n}\n\nfn issue14621() {\n    let mut local = 4;\n    let _ = std::ptr::addr_of_mut!(local) as *const _;\n    //~^ ptr_cast_constness\n}\n\nfn issue11317() {\n    let r = &0_u32;\n    let _ptr: *mut u32 = r as *const _ as *mut _;\n    //~^ ptr_cast_constness\n}\n"
  },
  {
    "path": "tests/ui/ptr_cast_constness.stderr",
    "content": "error: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:16:45\n   |\nLL |         let _: &mut T = std::mem::transmute(p as *mut T);\n   |                                             ^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()`\n   |\n   = note: `-D clippy::ptr-cast-constness` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ptr_cast_constness)]`\n\nerror: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:18:23\n   |\nLL |         let _ = &mut *(p as *mut T);\n   |                       ^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()`\n\nerror: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:35:17\n   |\nLL |         let _ = *ptr_ptr as *mut u32;\n   |                 ^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(*ptr_ptr).cast_mut()`\n\nerror: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:39:13\n   |\nLL |     let _ = ptr as *mut u32;\n   |             ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`\n\nerror: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:41:13\n   |\nLL |     let _ = mut_ptr as *const u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`\n\nerror: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:75:13\n   |\nLL |     let _ = ptr as *mut u32;\n   |             ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`\n\nerror: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:77:13\n   |\nLL |     let _ = mut_ptr as *const u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`\n\nerror: `as` casting to make a const null pointer into a mutable null pointer\n  --> tests/ui/ptr_cast_constness.rs:84:13\n   |\nLL |     let _ = ptr::null::<String>() as *mut String;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::<String>()`\n\nerror: `as` casting to make a mutable null pointer into a const null pointer\n  --> tests/ui/ptr_cast_constness.rs:86:13\n   |\nLL |     let _ = ptr::null_mut::<u32>() as *const u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null()` directly instead: `std::ptr::null::<u32>()`\n\nerror: changing constness of a null pointer\n  --> tests/ui/ptr_cast_constness.rs:88:13\n   |\nLL |     let _ = ptr::null::<u32>().cast_mut();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::<u32>()`\n\nerror: changing constness of a null pointer\n  --> tests/ui/ptr_cast_constness.rs:90:13\n   |\nLL |     let _ = ptr::null_mut::<u32>().cast_const();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null()` directly instead: `std::ptr::null::<u32>()`\n\nerror: `as` casting to make a const null pointer into a mutable null pointer\n  --> tests/ui/ptr_cast_constness.rs:94:21\n   |\nLL |     let _ = inline!(ptr::null::<u32>() as *mut u32);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::<u32>()`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_null_pointers` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: changing constness of a null pointer\n  --> tests/ui/ptr_cast_constness.rs:96:21\n   |\nLL |     let _ = inline!(ptr::null::<u32>().cast_mut());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::<u32>()`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_null_pointers` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:106:13\n   |\nLL |     let _ = std::ptr::addr_of_mut!(local) as *const _;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `std::ptr::addr_of_mut!(local).cast_const()`\n\nerror: `as` casting between raw pointers while changing only its constness\n  --> tests/ui/ptr_cast_constness.rs:112:26\n   |\nLL |     let _ptr: *mut u32 = r as *const _ as *mut _;\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(r as *const u32).cast_mut()`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/ptr_eq.fixed",
    "content": "#![warn(clippy::ptr_eq)]\n#![allow(function_casts_as_integer)]\n\nmacro_rules! mac {\n    ($a:expr, $b:expr) => {\n        $a as *const _ as usize == $b as *const _ as usize\n    };\n    (cast $a:expr) => {\n        $a as *const [i32; 3]\n    };\n}\n\nmacro_rules! another_mac {\n    ($a:expr, $b:expr) => {\n        $a as *const _ == $b as *const _\n    };\n}\n\nfn main() {\n    let a = &[1, 2, 3];\n    let b = &[1, 2, 3];\n\n    let _ = std::ptr::eq(a, b);\n    //~^ ptr_eq\n    let _ = std::ptr::eq(a, b);\n    //~^ ptr_eq\n\n    // Do not lint: the rhs conversion is needed\n    let _ = a.as_ptr() == b as *const _;\n\n    // Do not lint: we have two raw pointers already\n    let _ = a.as_ptr() == b.as_ptr();\n\n    // Do not lint\n    let _ = mac!(a, b);\n    let _ = another_mac!(a, b);\n\n    let a = &mut [1, 2, 3];\n    let b = &mut [1, 2, 3];\n\n    // Do not lint: the rhs conversion is needed\n    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;\n\n    // Do not lint: we have two raw pointers already\n    let _ = a.as_mut_ptr() == b.as_mut_ptr();\n\n    let _ = a == b;\n    let _ = core::ptr::eq(a, b);\n\n    let (x, y) = (&0u32, &mut 1u32);\n    let _ = std::ptr::eq(x, y);\n    //~^ ptr_eq\n\n    let _ = !std::ptr::eq(x, y);\n    //~^ ptr_eq\n\n    #[expect(clippy::eq_op)]\n    // Do not lint: casts are needed to not change type\n    let _issue14337 = main as *const () == main as *const ();\n\n    // Do not peel the content of macros\n    let _ = std::ptr::eq(mac!(cast a), mac!(cast b));\n    //~^ ptr_eq\n\n    // Do not peel the content of macros\n    let _ = std::ptr::eq(mac!(cast a), mac!(cast b));\n    //~^ ptr_eq\n}\n"
  },
  {
    "path": "tests/ui/ptr_eq.rs",
    "content": "#![warn(clippy::ptr_eq)]\n#![allow(function_casts_as_integer)]\n\nmacro_rules! mac {\n    ($a:expr, $b:expr) => {\n        $a as *const _ as usize == $b as *const _ as usize\n    };\n    (cast $a:expr) => {\n        $a as *const [i32; 3]\n    };\n}\n\nmacro_rules! another_mac {\n    ($a:expr, $b:expr) => {\n        $a as *const _ == $b as *const _\n    };\n}\n\nfn main() {\n    let a = &[1, 2, 3];\n    let b = &[1, 2, 3];\n\n    let _ = a as *const _ as usize == b as *const _ as usize;\n    //~^ ptr_eq\n    let _ = a as *const _ == b as *const _;\n    //~^ ptr_eq\n\n    // Do not lint: the rhs conversion is needed\n    let _ = a.as_ptr() == b as *const _;\n\n    // Do not lint: we have two raw pointers already\n    let _ = a.as_ptr() == b.as_ptr();\n\n    // Do not lint\n    let _ = mac!(a, b);\n    let _ = another_mac!(a, b);\n\n    let a = &mut [1, 2, 3];\n    let b = &mut [1, 2, 3];\n\n    // Do not lint: the rhs conversion is needed\n    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;\n\n    // Do not lint: we have two raw pointers already\n    let _ = a.as_mut_ptr() == b.as_mut_ptr();\n\n    let _ = a == b;\n    let _ = core::ptr::eq(a, b);\n\n    let (x, y) = (&0u32, &mut 1u32);\n    let _ = x as *const u32 == y as *mut u32 as *const u32;\n    //~^ ptr_eq\n\n    let _ = x as *const u32 != y as *mut u32 as *const u32;\n    //~^ ptr_eq\n\n    #[expect(clippy::eq_op)]\n    // Do not lint: casts are needed to not change type\n    let _issue14337 = main as *const () == main as *const ();\n\n    // Do not peel the content of macros\n    let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _;\n    //~^ ptr_eq\n\n    // Do not peel the content of macros\n    let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _;\n    //~^ ptr_eq\n}\n"
  },
  {
    "path": "tests/ui/ptr_eq.stderr",
    "content": "error: use `std::ptr::eq` when comparing raw pointers\n  --> tests/ui/ptr_eq.rs:23:13\n   |\nLL |     let _ = a as *const _ as usize == b as *const _ as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`\n   |\n   = note: `-D clippy::ptr-eq` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]`\n\nerror: use `std::ptr::eq` when comparing raw pointers\n  --> tests/ui/ptr_eq.rs:25:13\n   |\nLL |     let _ = a as *const _ == b as *const _;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`\n\nerror: use `std::ptr::eq` when comparing raw pointers\n  --> tests/ui/ptr_eq.rs:51:13\n   |\nLL |     let _ = x as *const u32 == y as *mut u32 as *const u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(x, y)`\n\nerror: use `std::ptr::eq` when comparing raw pointers\n  --> tests/ui/ptr_eq.rs:54:13\n   |\nLL |     let _ = x as *const u32 != y as *mut u32 as *const u32;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!std::ptr::eq(x, y)`\n\nerror: use `std::ptr::eq` when comparing raw pointers\n  --> tests/ui/ptr_eq.rs:62:13\n   |\nLL |     let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(mac!(cast a), mac!(cast b))`\n\nerror: use `std::ptr::eq` when comparing raw pointers\n  --> tests/ui/ptr_eq.rs:66:13\n   |\nLL |     let _ = mac!(cast a) as *const _ == mac!(cast b) as *const _;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(mac!(cast a), mac!(cast b))`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/ptr_eq_no_std.fixed",
    "content": "#![warn(clippy::ptr_eq)]\n#![no_std]\n#![feature(lang_items)]\n\nuse core::panic::PanicInfo;\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n\n#[panic_handler]\nfn panic(info: &PanicInfo) -> ! {\n    loop {}\n}\n\nmacro_rules! mac {\n    ($a:expr, $b:expr) => {\n        $a as *const _ as usize == $b as *const _ as usize\n    };\n}\n\nmacro_rules! another_mac {\n    ($a:expr, $b:expr) => {\n        $a as *const _ == $b as *const _\n    };\n}\n\nfn main() {\n    let a = &[1, 2, 3];\n    let b = &[1, 2, 3];\n\n    let _ = core::ptr::eq(a, b);\n    //~^ ptr_eq\n    let _ = core::ptr::eq(a, b);\n    //~^ ptr_eq\n\n    // Do not lint: the rhs conversion is needed\n    let _ = a.as_ptr() == b as *const _;\n\n    // Do not lint: we have two raw pointers already\n    let _ = a.as_ptr() == b.as_ptr();\n\n    // Do not lint\n    let _ = mac!(a, b);\n    let _ = another_mac!(a, b);\n\n    let a = &mut [1, 2, 3];\n    let b = &mut [1, 2, 3];\n\n    // Do not lint: the rhs conversion is needed\n    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;\n\n    // Do not lint: we have two raw pointers already\n    let _ = a.as_mut_ptr() == b.as_mut_ptr();\n\n    let _ = a == b;\n    let _ = core::ptr::eq(a, b);\n}\n"
  },
  {
    "path": "tests/ui/ptr_eq_no_std.rs",
    "content": "#![warn(clippy::ptr_eq)]\n#![no_std]\n#![feature(lang_items)]\n\nuse core::panic::PanicInfo;\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n\n#[panic_handler]\nfn panic(info: &PanicInfo) -> ! {\n    loop {}\n}\n\nmacro_rules! mac {\n    ($a:expr, $b:expr) => {\n        $a as *const _ as usize == $b as *const _ as usize\n    };\n}\n\nmacro_rules! another_mac {\n    ($a:expr, $b:expr) => {\n        $a as *const _ == $b as *const _\n    };\n}\n\nfn main() {\n    let a = &[1, 2, 3];\n    let b = &[1, 2, 3];\n\n    let _ = a as *const _ as usize == b as *const _ as usize;\n    //~^ ptr_eq\n    let _ = a as *const _ == b as *const _;\n    //~^ ptr_eq\n\n    // Do not lint: the rhs conversion is needed\n    let _ = a.as_ptr() == b as *const _;\n\n    // Do not lint: we have two raw pointers already\n    let _ = a.as_ptr() == b.as_ptr();\n\n    // Do not lint\n    let _ = mac!(a, b);\n    let _ = another_mac!(a, b);\n\n    let a = &mut [1, 2, 3];\n    let b = &mut [1, 2, 3];\n\n    // Do not lint: the rhs conversion is needed\n    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;\n\n    // Do not lint: we have two raw pointers already\n    let _ = a.as_mut_ptr() == b.as_mut_ptr();\n\n    let _ = a == b;\n    let _ = core::ptr::eq(a, b);\n}\n"
  },
  {
    "path": "tests/ui/ptr_eq_no_std.stderr",
    "content": "error: use `core::ptr::eq` when comparing raw pointers\n  --> tests/ui/ptr_eq_no_std.rs:31:13\n   |\nLL |     let _ = a as *const _ as usize == b as *const _ as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`\n   |\n   = note: `-D clippy::ptr-eq` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]`\n\nerror: use `core::ptr::eq` when comparing raw pointers\n  --> tests/ui/ptr_eq_no_std.rs:33:13\n   |\nLL |     let _ = a as *const _ == b as *const _;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/ptr_offset_by_literal.fixed",
    "content": "#![warn(clippy::ptr_offset_by_literal)]\n#![allow(clippy::inconsistent_digit_grouping)]\n\nfn main() {\n    let arr = [b'a', b'b', b'c'];\n    let ptr = arr.as_ptr();\n\n    let var = 32;\n    const CONST: isize = 42;\n\n    unsafe {\n        let _ = ptr;\n        //~^ ptr_offset_by_literal\n        let _ = ptr;\n        //~^ ptr_offset_by_literal\n\n        let _ = ptr.add(5);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.sub(5);\n        //~^ ptr_offset_by_literal\n\n        let _ = ptr.offset(var);\n        let _ = ptr.offset(CONST);\n\n        let _ = ptr.wrapping_add(5);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.wrapping_sub(5);\n        //~^ ptr_offset_by_literal\n\n        let _ = ptr.sub(5);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.wrapping_sub(5);\n        //~^ ptr_offset_by_literal\n\n        // isize::MAX and isize::MIN on 32-bit systems.\n        let _ = ptr.add(2_147_483_647);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.sub(2_147_483_648);\n        //~^ ptr_offset_by_literal\n\n        let _ = ptr.add(5_0);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.sub(5_0);\n        //~^ ptr_offset_by_literal\n\n        macro_rules! offs { { $e:expr, $offs:expr } => { $e.offset($offs) }; }\n        offs!(ptr, 6);\n        offs!(ptr, var);\n    }\n}\n"
  },
  {
    "path": "tests/ui/ptr_offset_by_literal.rs",
    "content": "#![warn(clippy::ptr_offset_by_literal)]\n#![allow(clippy::inconsistent_digit_grouping)]\n\nfn main() {\n    let arr = [b'a', b'b', b'c'];\n    let ptr = arr.as_ptr();\n\n    let var = 32;\n    const CONST: isize = 42;\n\n    unsafe {\n        let _ = ptr.offset(0);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.offset(-0);\n        //~^ ptr_offset_by_literal\n\n        let _ = ptr.offset(5);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.offset(-5);\n        //~^ ptr_offset_by_literal\n\n        let _ = ptr.offset(var);\n        let _ = ptr.offset(CONST);\n\n        let _ = ptr.wrapping_offset(5isize);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.wrapping_offset(-5isize);\n        //~^ ptr_offset_by_literal\n\n        let _ = ptr.offset(-(5));\n        //~^ ptr_offset_by_literal\n        let _ = ptr.wrapping_offset(-(5));\n        //~^ ptr_offset_by_literal\n\n        // isize::MAX and isize::MIN on 32-bit systems.\n        let _ = ptr.offset(2_147_483_647isize);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.offset(-2_147_483_648isize);\n        //~^ ptr_offset_by_literal\n\n        let _ = ptr.offset(5_0__isize);\n        //~^ ptr_offset_by_literal\n        let _ = ptr.offset(-5_0__isize);\n        //~^ ptr_offset_by_literal\n\n        macro_rules! offs { { $e:expr, $offs:expr } => { $e.offset($offs) }; }\n        offs!(ptr, 6);\n        offs!(ptr, var);\n    }\n}\n"
  },
  {
    "path": "tests/ui/ptr_offset_by_literal.stderr",
    "content": "error: use of `offset` with zero\n  --> tests/ui/ptr_offset_by_literal.rs:12:17\n   |\nLL |         let _ = ptr.offset(0);\n   |                 ^^^----------\n   |                    |\n   |                    help: remove the call to `offset`\n   |\n   = note: `-D clippy::ptr-offset-by-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ptr_offset_by_literal)]`\n\nerror: use of `offset` with zero\n  --> tests/ui/ptr_offset_by_literal.rs:14:17\n   |\nLL |         let _ = ptr.offset(-0);\n   |                 ^^^-----------\n   |                    |\n   |                    help: remove the call to `offset`\n\nerror: use of `offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:17:17\n   |\nLL |         let _ = ptr.offset(5);\n   |                 ^^^^^^^^^^^^^\n   |\nhelp: use `add` instead\n   |\nLL -         let _ = ptr.offset(5);\nLL +         let _ = ptr.add(5);\n   |\n\nerror: use of `offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:19:17\n   |\nLL |         let _ = ptr.offset(-5);\n   |                 ^^^^^^^^^^^^^^\n   |\nhelp: use `sub` instead\n   |\nLL -         let _ = ptr.offset(-5);\nLL +         let _ = ptr.sub(5);\n   |\n\nerror: use of `wrapping_offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:25:17\n   |\nLL |         let _ = ptr.wrapping_offset(5isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `wrapping_add` instead\n   |\nLL -         let _ = ptr.wrapping_offset(5isize);\nLL +         let _ = ptr.wrapping_add(5);\n   |\n\nerror: use of `wrapping_offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:27:17\n   |\nLL |         let _ = ptr.wrapping_offset(-5isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `wrapping_sub` instead\n   |\nLL -         let _ = ptr.wrapping_offset(-5isize);\nLL +         let _ = ptr.wrapping_sub(5);\n   |\n\nerror: use of `offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:30:17\n   |\nLL |         let _ = ptr.offset(-(5));\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: use `sub` instead\n   |\nLL -         let _ = ptr.offset(-(5));\nLL +         let _ = ptr.sub(5);\n   |\n\nerror: use of `wrapping_offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:32:17\n   |\nLL |         let _ = ptr.wrapping_offset(-(5));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `wrapping_sub` instead\n   |\nLL -         let _ = ptr.wrapping_offset(-(5));\nLL +         let _ = ptr.wrapping_sub(5);\n   |\n\nerror: use of `offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:36:17\n   |\nLL |         let _ = ptr.offset(2_147_483_647isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `add` instead\n   |\nLL -         let _ = ptr.offset(2_147_483_647isize);\nLL +         let _ = ptr.add(2_147_483_647);\n   |\n\nerror: use of `offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:38:17\n   |\nLL |         let _ = ptr.offset(-2_147_483_648isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `sub` instead\n   |\nLL -         let _ = ptr.offset(-2_147_483_648isize);\nLL +         let _ = ptr.sub(2_147_483_648);\n   |\n\nerror: use of `offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:41:17\n   |\nLL |         let _ = ptr.offset(5_0__isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `add` instead\n   |\nLL -         let _ = ptr.offset(5_0__isize);\nLL +         let _ = ptr.add(5_0);\n   |\n\nerror: use of `offset` with a literal\n  --> tests/ui/ptr_offset_by_literal.rs:43:17\n   |\nLL |         let _ = ptr.offset(-5_0__isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `sub` instead\n   |\nLL -         let _ = ptr.offset(-5_0__isize);\nLL +         let _ = ptr.sub(5_0);\n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/ptr_offset_with_cast.fixed",
    "content": "#![expect(clippy::unnecessary_cast, clippy::useless_vec, clippy::needless_borrow)]\n\nfn main() {\n    let vec = vec![b'a', b'b', b'c'];\n    let ptr = vec.as_ptr();\n\n    let offset_u8 = 1_u8;\n    let offset_usize = 1_usize;\n    let offset_isize = 1_isize;\n\n    unsafe {\n        let _ = ptr.add(offset_usize);\n        //~^ ptr_offset_with_cast\n        let _ = ptr.offset(offset_isize as isize);\n        let _ = ptr.offset(offset_u8 as isize);\n\n        let _ = ptr.wrapping_add(offset_usize);\n        //~^ ptr_offset_with_cast\n        let _ = ptr.wrapping_offset(offset_isize as isize);\n        let _ = ptr.wrapping_offset(offset_u8 as isize);\n\n        let _ = S.offset(offset_usize as isize);\n        let _ = S.wrapping_offset(offset_usize as isize);\n\n        let _ = (&ptr).add(offset_usize);\n        //~^ ptr_offset_with_cast\n        let _ = (&ptr).wrapping_add(offset_usize);\n        //~^ ptr_offset_with_cast\n    }\n}\n\n#[derive(Clone, Copy)]\nstruct S;\n\nimpl S {\n    fn offset(self, _: isize) -> Self {\n        self\n    }\n    fn wrapping_offset(self, _: isize) -> Self {\n        self\n    }\n}\n"
  },
  {
    "path": "tests/ui/ptr_offset_with_cast.rs",
    "content": "#![expect(clippy::unnecessary_cast, clippy::useless_vec, clippy::needless_borrow)]\n\nfn main() {\n    let vec = vec![b'a', b'b', b'c'];\n    let ptr = vec.as_ptr();\n\n    let offset_u8 = 1_u8;\n    let offset_usize = 1_usize;\n    let offset_isize = 1_isize;\n\n    unsafe {\n        let _ = ptr.offset(offset_usize as isize);\n        //~^ ptr_offset_with_cast\n        let _ = ptr.offset(offset_isize as isize);\n        let _ = ptr.offset(offset_u8 as isize);\n\n        let _ = ptr.wrapping_offset(offset_usize as isize);\n        //~^ ptr_offset_with_cast\n        let _ = ptr.wrapping_offset(offset_isize as isize);\n        let _ = ptr.wrapping_offset(offset_u8 as isize);\n\n        let _ = S.offset(offset_usize as isize);\n        let _ = S.wrapping_offset(offset_usize as isize);\n\n        let _ = (&ptr).offset(offset_usize as isize);\n        //~^ ptr_offset_with_cast\n        let _ = (&ptr).wrapping_offset(offset_usize as isize);\n        //~^ ptr_offset_with_cast\n    }\n}\n\n#[derive(Clone, Copy)]\nstruct S;\n\nimpl S {\n    fn offset(self, _: isize) -> Self {\n        self\n    }\n    fn wrapping_offset(self, _: isize) -> Self {\n        self\n    }\n}\n"
  },
  {
    "path": "tests/ui/ptr_offset_with_cast.stderr",
    "content": "error: use of `offset` with a `usize` casted to an `isize`\n  --> tests/ui/ptr_offset_with_cast.rs:12:17\n   |\nLL |         let _ = ptr.offset(offset_usize as isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::ptr-offset-with-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ptr_offset_with_cast)]`\nhelp: use `add` instead\n   |\nLL -         let _ = ptr.offset(offset_usize as isize);\nLL +         let _ = ptr.add(offset_usize);\n   |\n\nerror: use of `wrapping_offset` with a `usize` casted to an `isize`\n  --> tests/ui/ptr_offset_with_cast.rs:17:17\n   |\nLL |         let _ = ptr.wrapping_offset(offset_usize as isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `wrapping_add` instead\n   |\nLL -         let _ = ptr.wrapping_offset(offset_usize as isize);\nLL +         let _ = ptr.wrapping_add(offset_usize);\n   |\n\nerror: use of `offset` with a `usize` casted to an `isize`\n  --> tests/ui/ptr_offset_with_cast.rs:25:17\n   |\nLL |         let _ = (&ptr).offset(offset_usize as isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `add` instead\n   |\nLL -         let _ = (&ptr).offset(offset_usize as isize);\nLL +         let _ = (&ptr).add(offset_usize);\n   |\n\nerror: use of `wrapping_offset` with a `usize` casted to an `isize`\n  --> tests/ui/ptr_offset_with_cast.rs:27:17\n   |\nLL |         let _ = (&ptr).wrapping_offset(offset_usize as isize);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `wrapping_add` instead\n   |\nLL -         let _ = (&ptr).wrapping_offset(offset_usize as isize);\nLL +         let _ = (&ptr).wrapping_add(offset_usize);\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/pub_use.rs",
    "content": "#![warn(clippy::pub_use)]\n#![allow(unused_imports)]\n#![no_main]\n\npub mod outer {\n    mod inner {\n        pub struct Test {}\n    }\n    // should be linted\n    pub use inner::Test;\n    //~^ pub_use\n}\n\n// should not be linted\nuse std::fmt;\n"
  },
  {
    "path": "tests/ui/pub_use.stderr",
    "content": "error: using `pub use`\n  --> tests/ui/pub_use.rs:10:5\n   |\nLL |     pub use inner::Test;\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: move the exported item to a public module instead\n   = note: `-D clippy::pub-use` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pub_use)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/pub_with_shorthand.fixed",
    "content": "\n//@aux-build:proc_macros.rs\n#![feature(custom_inner_attributes)]\n#![allow(clippy::needless_pub_self, unused)]\n#![warn(clippy::pub_with_shorthand)]\n#![no_main]\n#![rustfmt::skip] // rustfmt will remove `in`, understandable\n                  // but very annoying for our purposes!\n\n#[macro_use]\nextern crate proc_macros;\n\npub(in self) fn a() {}\n//~^ pub_with_shorthand\npub(in self) fn b() {}\n\npub fn c() {}\nmod a {\n    pub(in super) fn d() {}\n    pub(in super) fn e() {}\n    //~^ pub_with_shorthand\n    pub(in self) fn f() {}\n    //~^ pub_with_shorthand\n    pub(in crate) fn k() {}\n    //~^ pub_with_shorthand\n    pub(in crate) fn m() {}\n    mod b {\n        pub(in crate::a) fn l() {}\n    }\n}\n\nexternal! {\n    pub(self) fn g() {}\n    pub(in self) fn h() {}\n}\nwith_span! {\n    span\n    pub(self) fn i() {}\n    pub(in self) fn j() {}\n}\n\n// not really anything more to test. just a really simple lint overall\n"
  },
  {
    "path": "tests/ui/pub_with_shorthand.rs",
    "content": "\n//@aux-build:proc_macros.rs\n#![feature(custom_inner_attributes)]\n#![allow(clippy::needless_pub_self, unused)]\n#![warn(clippy::pub_with_shorthand)]\n#![no_main]\n#![rustfmt::skip] // rustfmt will remove `in`, understandable\n                  // but very annoying for our purposes!\n\n#[macro_use]\nextern crate proc_macros;\n\npub(self) fn a() {}\n//~^ pub_with_shorthand\npub(in self) fn b() {}\n\npub fn c() {}\nmod a {\n    pub(in super) fn d() {}\n    pub(super) fn e() {}\n    //~^ pub_with_shorthand\n    pub(self) fn f() {}\n    //~^ pub_with_shorthand\n    pub(crate) fn k() {}\n    //~^ pub_with_shorthand\n    pub(in crate) fn m() {}\n    mod b {\n        pub(in crate::a) fn l() {}\n    }\n}\n\nexternal! {\n    pub(self) fn g() {}\n    pub(in self) fn h() {}\n}\nwith_span! {\n    span\n    pub(self) fn i() {}\n    pub(in self) fn j() {}\n}\n\n// not really anything more to test. just a really simple lint overall\n"
  },
  {
    "path": "tests/ui/pub_with_shorthand.stderr",
    "content": "error: usage of `pub` without `in`\n  --> tests/ui/pub_with_shorthand.rs:13:1\n   |\nLL | pub(self) fn a() {}\n   | ^^^^^^^^^ help: add it: `pub(in self)`\n   |\n   = note: `-D clippy::pub-with-shorthand` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pub_with_shorthand)]`\n\nerror: usage of `pub` without `in`\n  --> tests/ui/pub_with_shorthand.rs:20:5\n   |\nLL |     pub(super) fn e() {}\n   |     ^^^^^^^^^^ help: add it: `pub(in super)`\n\nerror: usage of `pub` without `in`\n  --> tests/ui/pub_with_shorthand.rs:22:5\n   |\nLL |     pub(self) fn f() {}\n   |     ^^^^^^^^^ help: add it: `pub(in self)`\n\nerror: usage of `pub` without `in`\n  --> tests/ui/pub_with_shorthand.rs:24:5\n   |\nLL |     pub(crate) fn k() {}\n   |     ^^^^^^^^^^ help: add it: `pub(in crate)`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/pub_without_shorthand.fixed",
    "content": "\n//@aux-build:proc_macros.rs\n#![feature(custom_inner_attributes)]\n#![allow(clippy::needless_pub_self, unused)]\n#![warn(clippy::pub_without_shorthand)]\n#![no_main]\n#![rustfmt::skip] // rustfmt will remove `in`, understandable\n                  // but very annoying for our purposes!\n\n#[macro_use]\nextern crate proc_macros;\n\npub(self) fn a() {}\npub(self) fn b() {}\n//~^ pub_without_shorthand\n\npub fn c() {}\nmod a {\n    pub(super) fn d() {}\n    //~^ pub_without_shorthand\n    pub(super) fn e() {}\n    pub(self) fn f() {}\n    pub(crate) fn k() {}\n    pub(crate) fn m() {}\n    //~^ pub_without_shorthand\n    mod b {\n        pub(in crate::a) fn l() {}\n    }\n}\n\nexternal! {\n    pub(self) fn g() {}\n    pub(in self) fn h() {}\n}\nwith_span! {\n    span\n    pub(self) fn i() {}\n    pub(in self) fn j() {}\n}\n\n// not really anything more to test. just a really simple lint overall\n"
  },
  {
    "path": "tests/ui/pub_without_shorthand.rs",
    "content": "\n//@aux-build:proc_macros.rs\n#![feature(custom_inner_attributes)]\n#![allow(clippy::needless_pub_self, unused)]\n#![warn(clippy::pub_without_shorthand)]\n#![no_main]\n#![rustfmt::skip] // rustfmt will remove `in`, understandable\n                  // but very annoying for our purposes!\n\n#[macro_use]\nextern crate proc_macros;\n\npub(self) fn a() {}\npub(in self) fn b() {}\n//~^ pub_without_shorthand\n\npub fn c() {}\nmod a {\n    pub(in super) fn d() {}\n    //~^ pub_without_shorthand\n    pub(super) fn e() {}\n    pub(self) fn f() {}\n    pub(crate) fn k() {}\n    pub(in crate) fn m() {}\n    //~^ pub_without_shorthand\n    mod b {\n        pub(in crate::a) fn l() {}\n    }\n}\n\nexternal! {\n    pub(self) fn g() {}\n    pub(in self) fn h() {}\n}\nwith_span! {\n    span\n    pub(self) fn i() {}\n    pub(in self) fn j() {}\n}\n\n// not really anything more to test. just a really simple lint overall\n"
  },
  {
    "path": "tests/ui/pub_without_shorthand.stderr",
    "content": "error: usage of `pub` with `in`\n  --> tests/ui/pub_without_shorthand.rs:14:1\n   |\nLL | pub(in self) fn b() {}\n   | ^^^^^^^^^^^^ help: remove it: `pub(self)`\n   |\n   = note: `-D clippy::pub-without-shorthand` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pub_without_shorthand)]`\n\nerror: usage of `pub` with `in`\n  --> tests/ui/pub_without_shorthand.rs:19:5\n   |\nLL |     pub(in super) fn d() {}\n   |     ^^^^^^^^^^^^^ help: remove it: `pub(super)`\n\nerror: usage of `pub` with `in`\n  --> tests/ui/pub_without_shorthand.rs:24:5\n   |\nLL |     pub(in crate) fn m() {}\n   |     ^^^^^^^^^^^^^ help: remove it: `pub(crate)`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/question_mark.fixed",
    "content": "#![feature(try_blocks)]\n#![allow(clippy::unnecessary_wraps, clippy::no_effect)]\n\nuse std::sync::MutexGuard;\n\nfn some_func(a: Option<u32>) -> Option<u32> {\n    a?;\n\n    a\n}\n\nfn some_other_func(a: Option<u32>) -> Option<u32> {\n    if a.is_none() {\n        return None;\n    } else {\n        return Some(0);\n    }\n    unreachable!()\n}\n\npub enum SeemsOption<T> {\n    Some(T),\n    None,\n}\n\nimpl<T> SeemsOption<T> {\n    pub fn is_none(&self) -> bool {\n        match *self {\n            SeemsOption::None => true,\n            SeemsOption::Some(_) => false,\n        }\n    }\n}\n\nfn returns_something_similar_to_option(a: SeemsOption<u32>) -> SeemsOption<u32> {\n    if a.is_none() {\n        return SeemsOption::None;\n    }\n\n    a\n}\n\npub struct CopyStruct {\n    pub opt: Option<u32>,\n}\n\nimpl CopyStruct {\n    #[rustfmt::skip]\n    pub fn func(&self) -> Option<u32> {\n        (self.opt)?;\n\n        self.opt?;\n\n        let _ = Some(self.opt?);\n\n        let _ = self.opt?;\n\n        self.opt\n    }\n}\n\n#[derive(Clone)]\npub struct MoveStruct {\n    pub opt: Option<Vec<u32>>,\n}\n\nimpl MoveStruct {\n    pub fn ref_func(&self) -> Option<Vec<u32>> {\n        self.opt.as_ref()?;\n\n        self.opt.clone()\n    }\n\n    pub fn mov_func_reuse(self) -> Option<Vec<u32>> {\n        self.opt.as_ref()?;\n\n        self.opt\n    }\n\n    pub fn mov_func_no_use(self) -> Option<Vec<u32>> {\n        self.opt.as_ref()?;\n        Some(Vec::new())\n    }\n\n    pub fn if_let_ref_func(self) -> Option<Vec<u32>> {\n        let v: &Vec<_> = self.opt.as_ref()?;\n\n        Some(v.clone())\n    }\n\n    pub fn if_let_mov_func(self) -> Option<Vec<u32>> {\n        let v = self.opt?;\n\n        Some(v)\n    }\n}\n\nfn func() -> Option<i32> {\n    macro_rules! opt_none {\n        () => {\n            None\n        };\n    }\n\n    fn f() -> Option<String> {\n        Some(String::new())\n    }\n\n    f()?;\n\n    let _val = f()?;\n\n    let s: &str = match &Some(String::new()) {\n        Some(v) => v,\n        None => return None,\n    };\n\n    f()?;\n\n    opt_none!()?;\n\n    match f() {\n        Some(x) => x,\n        None => return opt_none!(),\n    };\n\n    match f() {\n        Some(val) => {\n            println!(\"{val}\");\n            val\n        },\n        None => return None,\n    };\n\n    Some(0)\n}\n\nfn func_returning_result() -> Result<i32, i32> {\n    Ok(1)\n}\n\nfn result_func(x: Result<i32, i32>) -> Result<i32, i32> {\n    let _ = x?;\n    //~^ question_mark\n\n    x?;\n\n    let _val = func_returning_result()?;\n\n    func_returning_result()?;\n\n    // No warning\n    let y = if let Ok(x) = x {\n        x\n    } else {\n        return Err(0);\n    };\n\n    // issue #7859\n    // no warning\n    let _ = if let Ok(x) = func_returning_result() {\n        x\n    } else {\n        return Err(0);\n    };\n\n    // no warning\n    if func_returning_result().is_err() {\n        return func_returning_result();\n    }\n\n    // no warning\n    let _ = if let Err(e) = x { Err(e) } else { Ok(0) };\n\n    // issue #11283\n    // no warning\n    #[warn(clippy::question_mark_used)]\n    {\n        if let Err(err) = Ok(()) {\n            return Err(err);\n        }\n\n        if Err::<i32, _>(0).is_err() {\n            return Err(0);\n        } else {\n            return Ok(0);\n        }\n\n        unreachable!()\n    }\n\n    Ok(y)\n}\n\nfn infer_check() {\n    let closure = |x: Result<u8, ()>| {\n        // `?` would fail here, as it expands to `Err(val.into())` which is not constrained.\n        let _val = match x {\n            Ok(val) => val,\n            Err(val) => return Err(val),\n        };\n\n        Ok(())\n    };\n\n    let closure = |x: Result<u8, ()>| -> Result<(), _> {\n        // `?` would fail here, as it expands to `Err(val.into())` which is not constrained.\n        let _val = match x {\n            Ok(val) => val,\n            Err(val) => return Err(val),\n        };\n\n        Ok(())\n    };\n}\n\n// see issue #8019\npub enum NotOption {\n    None,\n    First,\n    AfterFirst,\n}\n\nfn obj(_: i32) -> Result<(), NotOption> {\n    Err(NotOption::First)\n}\n\nfn f() -> NotOption {\n    if obj(2).is_err() {\n        return NotOption::None;\n    }\n    NotOption::First\n}\n\nfn do_something() {}\n\nfn err_immediate_return() -> Result<i32, i32> {\n    func_returning_result()?;\n    Ok(1)\n}\n\nfn err_immediate_return_and_do_something() -> Result<i32, i32> {\n    func_returning_result()?;\n    do_something();\n    Ok(1)\n}\n\n// No warning\nfn no_immediate_return() -> Result<i32, i32> {\n    if let Err(err) = func_returning_result() {\n        do_something();\n        return Err(err);\n    }\n    Ok(1)\n}\n\n// No warning\nfn mixed_result_and_option() -> Option<i32> {\n    if let Err(err) = func_returning_result() {\n        return Some(err);\n    }\n    None\n}\n\n// No warning\nfn else_if_check() -> Result<i32, i32> {\n    if true {\n        Ok(1)\n    } else if let Err(e) = func_returning_result() {\n        Err(e)\n    } else {\n        Err(-1)\n    }\n}\n\n// No warning\n#[allow(clippy::manual_map)]\n#[rustfmt::skip]\nfn option_map() -> Option<bool> {\n    if let Some(a) = Some(false) {\n        Some(!a)\n    } else {\n        None\n    }\n}\n\npub struct PatternedError {\n    flag: bool,\n}\n\n// No warning\nfn pattern() -> Result<(), PatternedError> {\n    let res = Ok(());\n\n    if let Err(err @ PatternedError { flag: true }) = res {\n        return Err(err);\n    }\n\n    res\n}\n\nfn expect_expr(a: Option<usize>) -> Option<usize> {\n    #[expect(clippy::needless_question_mark)]\n    Some(a?)\n}\n\nfn main() {}\n\n// `?` is not the same as `return None;` if inside of a try block\nfn issue8628(a: Option<u32>) -> Option<u32> {\n    let b: Option<u32> = try {\n        if a.is_none() {\n            return None;\n        }\n        32\n    };\n    b.or(Some(128))\n}\n\nfn issue6828_nested_body() -> Option<u32> {\n    try {\n        fn f2(a: Option<i32>) -> Option<i32> {\n            a?;\n            Some(32)\n        }\n        123\n    }\n}\n\n// should not lint, `?` operator not available in const context\nconst fn issue9175(option: Option<()>) -> Option<()> {\n    if option.is_none() {\n        return None;\n    }\n    //stuff\n    Some(())\n}\n\nfn issue12337() -> Option<i32> {\n    let _: Option<i32> = try {\n        let Some(_) = Some(42) else {\n            return None;\n        };\n        123\n    };\n    Some(42)\n}\n\nfn issue11983(option: &Option<String>) -> Option<()> {\n    // Don't lint, `&Option` dose not impl `Try`.\n    let Some(v) = option else { return None };\n\n    let opt = Some(String::new());\n    // Don't lint, `branch` method in `Try` takes ownership of `opt`,\n    // and `(&opt)?` also doesn't work since it's `&Option`.\n    let Some(v) = &opt else { return None };\n    let mov = opt;\n\n    Some(())\n}\n\nstruct Foo {\n    owned: Option<String>,\n}\nstruct Bar {\n    foo: Foo,\n}\n#[allow(clippy::disallowed_names)]\nfn issue12412(foo: &Foo, bar: &Bar) -> Option<()> {\n    // Don't lint, `owned` is behind a shared reference.\n    let Some(v) = &foo.owned else {\n        return None;\n    };\n    // Don't lint, `owned` is behind a shared reference.\n    let Some(v) = &bar.foo.owned else {\n        return None;\n    };\n    // lint\n    let v = bar.foo.owned.clone()?;\n    //~^^^ question_mark\n    Some(())\n}\n\nstruct StructWithOptionString {\n    opt_x: Option<String>,\n}\n\nstruct WrapperStructWithString(String);\n\n#[allow(clippy::disallowed_names)]\nfn issue_13417(foo: &mut StructWithOptionString) -> Option<String> {\n    let x = foo.opt_x.as_ref()?;\n    //~^^^ question_mark\n    let opt_y = Some(x.clone());\n    std::mem::replace(&mut foo.opt_x, opt_y)\n}\n\n#[allow(clippy::disallowed_names)]\nfn issue_13417_mut(foo: &mut StructWithOptionString) -> Option<String> {\n    let x = foo.opt_x.as_mut()?;\n    //~^^^ question_mark\n    let opt_y = Some(x.clone());\n    std::mem::replace(&mut foo.opt_x, opt_y)\n}\n\n#[allow(clippy::disallowed_names)]\n#[allow(unused)]\nfn issue_13417_weirder(foo: &mut StructWithOptionString, mut bar: Option<WrapperStructWithString>) -> Option<()> {\n    let x @ y = foo.opt_x.as_ref()?;\n    //~^^^ question_mark\n    let x @ &WrapperStructWithString(_) = bar.as_ref()?;\n    //~^^^ question_mark\n    let x @ &mut WrapperStructWithString(_) = bar.as_mut()?;\n    //~^^^ question_mark\n    Some(())\n}\n\n#[clippy::msrv = \"1.12\"]\nfn msrv_1_12(arg: Option<i32>) -> Option<i32> {\n    if arg.is_none() {\n        return None;\n    }\n    let val = match arg {\n        Some(val) => val,\n        None => return None,\n    };\n    println!(\"{}\", val);\n    Some(val)\n}\n\n#[clippy::msrv = \"1.13\"]\nfn msrv_1_13(arg: Option<i32>) -> Option<i32> {\n    arg?;\n    let val = arg?;\n    println!(\"{}\", val);\n    Some(val)\n}\n\nfn issue_14615(a: MutexGuard<Option<u32>>) -> Option<String> {\n    let a = (*a)?;\n    //~^^^ question_mark\n    Some(format!(\"{a}\"))\n}\n\nfn const_in_pattern(x: Option<(i32, i32)>) -> Option<()> {\n    const N: i32 = 0;\n\n    let Some((x, N)) = x else {\n        return None;\n    };\n\n    None\n}\n\nfn issue_13642(x: Option<i32>) -> Option<()> {\n    let Some(x) = x else {\n        #[cfg(false)]\n        panic!();\n\n        #[cfg(true)]\n        return None;\n    };\n\n    None\n}\n\nfn issue_15679() -> Result<i32, String> {\n    let some_result: Result<i32, &'static str> = todo!();\n\n    some_result?;\n\n    some_result?;\n\n    some_result?;\n\n    Ok(0)\n}\n\nmod issue14894 {\n    fn use_after_question_mark(do_something_else: impl Fn() -> Result<String, ()>) -> Result<(), ()> {\n        let result = do_something_else();\n        if let Err(reason) = result {\n            return Err(reason);\n        }\n        drop(result);\n\n        let result = do_something_else();\n        let x = result?;\n        drop(x);\n\n        Ok(())\n    }\n\n    #[expect(dropping_copy_types)]\n    fn use_after_question_mark_but_is_copy(do_something_else: impl Fn() -> Result<i32, ()>) -> Result<(), ()> {\n        let result = do_something_else();\n        result?;\n        drop(result);\n\n        Ok(())\n    }\n}\n\nfn wrongly_unmangled_macros() -> Option<i32> {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            Some($val)\n        };\n    }\n\n    let x = test_expr!(42)?;\n    //~^^^ question_mark\n    Some(x);\n\n    test_expr!(42)?;\n    test_expr!(42)\n}\n\nfn issue16429(b: i32) -> Option<i32> {\n    let a = Some(5);\n    let _ = if b == 1 {\n        b\n    } else { a? };\n\n    Some(0)\n}\n\nfn issue16654() -> Result<(), i32> {\n    let result = func_returning_result();\n\n    #[allow(clippy::collapsible_if)]\n    if true {\n        result?;\n    }\n\n    _ = [{ result?; }];\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/question_mark.rs",
    "content": "#![feature(try_blocks)]\n#![allow(clippy::unnecessary_wraps, clippy::no_effect)]\n\nuse std::sync::MutexGuard;\n\nfn some_func(a: Option<u32>) -> Option<u32> {\n    if a.is_none() {\n        //~^ question_mark\n        return None;\n    }\n\n    a\n}\n\nfn some_other_func(a: Option<u32>) -> Option<u32> {\n    if a.is_none() {\n        return None;\n    } else {\n        return Some(0);\n    }\n    unreachable!()\n}\n\npub enum SeemsOption<T> {\n    Some(T),\n    None,\n}\n\nimpl<T> SeemsOption<T> {\n    pub fn is_none(&self) -> bool {\n        match *self {\n            SeemsOption::None => true,\n            SeemsOption::Some(_) => false,\n        }\n    }\n}\n\nfn returns_something_similar_to_option(a: SeemsOption<u32>) -> SeemsOption<u32> {\n    if a.is_none() {\n        return SeemsOption::None;\n    }\n\n    a\n}\n\npub struct CopyStruct {\n    pub opt: Option<u32>,\n}\n\nimpl CopyStruct {\n    #[rustfmt::skip]\n    pub fn func(&self) -> Option<u32> {\n        if (self.opt).is_none() {\n        //~^ question_mark\n            return None;\n        }\n\n        if self.opt.is_none() {\n        //~^ question_mark\n            return None\n        }\n\n        let _ = if self.opt.is_none() {\n        //~^ question_mark\n            return None;\n        } else {\n            self.opt\n        };\n\n        let _ = if let Some(x) = self.opt {\n        //~^ question_mark\n            x\n        } else {\n            return None;\n        };\n\n        self.opt\n    }\n}\n\n#[derive(Clone)]\npub struct MoveStruct {\n    pub opt: Option<Vec<u32>>,\n}\n\nimpl MoveStruct {\n    pub fn ref_func(&self) -> Option<Vec<u32>> {\n        if self.opt.is_none() {\n            //~^ question_mark\n            return None;\n        }\n\n        self.opt.clone()\n    }\n\n    pub fn mov_func_reuse(self) -> Option<Vec<u32>> {\n        if self.opt.is_none() {\n            //~^ question_mark\n            return None;\n        }\n\n        self.opt\n    }\n\n    pub fn mov_func_no_use(self) -> Option<Vec<u32>> {\n        if self.opt.is_none() {\n            //~^ question_mark\n            return None;\n        }\n        Some(Vec::new())\n    }\n\n    pub fn if_let_ref_func(self) -> Option<Vec<u32>> {\n        let v: &Vec<_> = if let Some(ref v) = self.opt {\n            //~^ question_mark\n            v\n        } else {\n            return None;\n        };\n\n        Some(v.clone())\n    }\n\n    pub fn if_let_mov_func(self) -> Option<Vec<u32>> {\n        let v = if let Some(v) = self.opt {\n            //~^ question_mark\n            v\n        } else {\n            return None;\n        };\n\n        Some(v)\n    }\n}\n\nfn func() -> Option<i32> {\n    macro_rules! opt_none {\n        () => {\n            None\n        };\n    }\n\n    fn f() -> Option<String> {\n        Some(String::new())\n    }\n\n    if f().is_none() {\n        //~^ question_mark\n        return None;\n    }\n\n    let _val = match f() {\n        //~^ question_mark\n        Some(val) => val,\n        None => return None,\n    };\n\n    let s: &str = match &Some(String::new()) {\n        Some(v) => v,\n        None => return None,\n    };\n\n    match f() {\n        //~^ question_mark\n        Some(val) => val,\n        None => return None,\n    };\n\n    match opt_none!() {\n        //~^ question_mark\n        Some(x) => x,\n        None => return None,\n    };\n\n    match f() {\n        Some(x) => x,\n        None => return opt_none!(),\n    };\n\n    match f() {\n        Some(val) => {\n            println!(\"{val}\");\n            val\n        },\n        None => return None,\n    };\n\n    Some(0)\n}\n\nfn func_returning_result() -> Result<i32, i32> {\n    Ok(1)\n}\n\nfn result_func(x: Result<i32, i32>) -> Result<i32, i32> {\n    let _ = if let Ok(x) = x { x } else { return x };\n    //~^ question_mark\n\n    if x.is_err() {\n        //~^ question_mark\n        return x;\n    }\n\n    let _val = match func_returning_result() {\n        //~^ question_mark\n        Ok(val) => val,\n        Err(err) => return Err(err),\n    };\n\n    match func_returning_result() {\n        //~^ question_mark\n        Ok(val) => val,\n        Err(err) => return Err(err),\n    };\n\n    // No warning\n    let y = if let Ok(x) = x {\n        x\n    } else {\n        return Err(0);\n    };\n\n    // issue #7859\n    // no warning\n    let _ = if let Ok(x) = func_returning_result() {\n        x\n    } else {\n        return Err(0);\n    };\n\n    // no warning\n    if func_returning_result().is_err() {\n        return func_returning_result();\n    }\n\n    // no warning\n    let _ = if let Err(e) = x { Err(e) } else { Ok(0) };\n\n    // issue #11283\n    // no warning\n    #[warn(clippy::question_mark_used)]\n    {\n        if let Err(err) = Ok(()) {\n            return Err(err);\n        }\n\n        if Err::<i32, _>(0).is_err() {\n            return Err(0);\n        } else {\n            return Ok(0);\n        }\n\n        unreachable!()\n    }\n\n    Ok(y)\n}\n\nfn infer_check() {\n    let closure = |x: Result<u8, ()>| {\n        // `?` would fail here, as it expands to `Err(val.into())` which is not constrained.\n        let _val = match x {\n            Ok(val) => val,\n            Err(val) => return Err(val),\n        };\n\n        Ok(())\n    };\n\n    let closure = |x: Result<u8, ()>| -> Result<(), _> {\n        // `?` would fail here, as it expands to `Err(val.into())` which is not constrained.\n        let _val = match x {\n            Ok(val) => val,\n            Err(val) => return Err(val),\n        };\n\n        Ok(())\n    };\n}\n\n// see issue #8019\npub enum NotOption {\n    None,\n    First,\n    AfterFirst,\n}\n\nfn obj(_: i32) -> Result<(), NotOption> {\n    Err(NotOption::First)\n}\n\nfn f() -> NotOption {\n    if obj(2).is_err() {\n        return NotOption::None;\n    }\n    NotOption::First\n}\n\nfn do_something() {}\n\nfn err_immediate_return() -> Result<i32, i32> {\n    if let Err(err) = func_returning_result() {\n        //~^ question_mark\n        return Err(err);\n    }\n    Ok(1)\n}\n\nfn err_immediate_return_and_do_something() -> Result<i32, i32> {\n    if let Err(err) = func_returning_result() {\n        //~^ question_mark\n        return Err(err);\n    }\n    do_something();\n    Ok(1)\n}\n\n// No warning\nfn no_immediate_return() -> Result<i32, i32> {\n    if let Err(err) = func_returning_result() {\n        do_something();\n        return Err(err);\n    }\n    Ok(1)\n}\n\n// No warning\nfn mixed_result_and_option() -> Option<i32> {\n    if let Err(err) = func_returning_result() {\n        return Some(err);\n    }\n    None\n}\n\n// No warning\nfn else_if_check() -> Result<i32, i32> {\n    if true {\n        Ok(1)\n    } else if let Err(e) = func_returning_result() {\n        Err(e)\n    } else {\n        Err(-1)\n    }\n}\n\n// No warning\n#[allow(clippy::manual_map)]\n#[rustfmt::skip]\nfn option_map() -> Option<bool> {\n    if let Some(a) = Some(false) {\n        Some(!a)\n    } else {\n        None\n    }\n}\n\npub struct PatternedError {\n    flag: bool,\n}\n\n// No warning\nfn pattern() -> Result<(), PatternedError> {\n    let res = Ok(());\n\n    if let Err(err @ PatternedError { flag: true }) = res {\n        return Err(err);\n    }\n\n    res\n}\n\nfn expect_expr(a: Option<usize>) -> Option<usize> {\n    #[expect(clippy::needless_question_mark)]\n    Some(a?)\n}\n\nfn main() {}\n\n// `?` is not the same as `return None;` if inside of a try block\nfn issue8628(a: Option<u32>) -> Option<u32> {\n    let b: Option<u32> = try {\n        if a.is_none() {\n            return None;\n        }\n        32\n    };\n    b.or(Some(128))\n}\n\nfn issue6828_nested_body() -> Option<u32> {\n    try {\n        fn f2(a: Option<i32>) -> Option<i32> {\n            if a.is_none() {\n                //~^ question_mark\n                return None;\n                // do lint here, the outer `try` is not relevant here\n                // https://github.com/rust-lang/rust-clippy/pull/11001#issuecomment-1610636867\n            }\n            Some(32)\n        }\n        123\n    }\n}\n\n// should not lint, `?` operator not available in const context\nconst fn issue9175(option: Option<()>) -> Option<()> {\n    if option.is_none() {\n        return None;\n    }\n    //stuff\n    Some(())\n}\n\nfn issue12337() -> Option<i32> {\n    let _: Option<i32> = try {\n        let Some(_) = Some(42) else {\n            return None;\n        };\n        123\n    };\n    Some(42)\n}\n\nfn issue11983(option: &Option<String>) -> Option<()> {\n    // Don't lint, `&Option` dose not impl `Try`.\n    let Some(v) = option else { return None };\n\n    let opt = Some(String::new());\n    // Don't lint, `branch` method in `Try` takes ownership of `opt`,\n    // and `(&opt)?` also doesn't work since it's `&Option`.\n    let Some(v) = &opt else { return None };\n    let mov = opt;\n\n    Some(())\n}\n\nstruct Foo {\n    owned: Option<String>,\n}\nstruct Bar {\n    foo: Foo,\n}\n#[allow(clippy::disallowed_names)]\nfn issue12412(foo: &Foo, bar: &Bar) -> Option<()> {\n    // Don't lint, `owned` is behind a shared reference.\n    let Some(v) = &foo.owned else {\n        return None;\n    };\n    // Don't lint, `owned` is behind a shared reference.\n    let Some(v) = &bar.foo.owned else {\n        return None;\n    };\n    // lint\n    let Some(v) = bar.foo.owned.clone() else {\n        return None;\n    };\n    //~^^^ question_mark\n    Some(())\n}\n\nstruct StructWithOptionString {\n    opt_x: Option<String>,\n}\n\nstruct WrapperStructWithString(String);\n\n#[allow(clippy::disallowed_names)]\nfn issue_13417(foo: &mut StructWithOptionString) -> Option<String> {\n    let Some(ref x) = foo.opt_x else {\n        return None;\n    };\n    //~^^^ question_mark\n    let opt_y = Some(x.clone());\n    std::mem::replace(&mut foo.opt_x, opt_y)\n}\n\n#[allow(clippy::disallowed_names)]\nfn issue_13417_mut(foo: &mut StructWithOptionString) -> Option<String> {\n    let Some(ref mut x) = foo.opt_x else {\n        return None;\n    };\n    //~^^^ question_mark\n    let opt_y = Some(x.clone());\n    std::mem::replace(&mut foo.opt_x, opt_y)\n}\n\n#[allow(clippy::disallowed_names)]\n#[allow(unused)]\nfn issue_13417_weirder(foo: &mut StructWithOptionString, mut bar: Option<WrapperStructWithString>) -> Option<()> {\n    let Some(ref x @ ref y) = foo.opt_x else {\n        return None;\n    };\n    //~^^^ question_mark\n    let Some(ref x @ WrapperStructWithString(_)) = bar else {\n        return None;\n    };\n    //~^^^ question_mark\n    let Some(ref mut x @ WrapperStructWithString(_)) = bar else {\n        return None;\n    };\n    //~^^^ question_mark\n    Some(())\n}\n\n#[clippy::msrv = \"1.12\"]\nfn msrv_1_12(arg: Option<i32>) -> Option<i32> {\n    if arg.is_none() {\n        return None;\n    }\n    let val = match arg {\n        Some(val) => val,\n        None => return None,\n    };\n    println!(\"{}\", val);\n    Some(val)\n}\n\n#[clippy::msrv = \"1.13\"]\nfn msrv_1_13(arg: Option<i32>) -> Option<i32> {\n    if arg.is_none() {\n        //~^ question_mark\n        return None;\n    }\n    let val = match arg {\n        //~^ question_mark\n        Some(val) => val,\n        None => return None,\n    };\n    println!(\"{}\", val);\n    Some(val)\n}\n\nfn issue_14615(a: MutexGuard<Option<u32>>) -> Option<String> {\n    let Some(a) = *a else {\n        return None;\n    };\n    //~^^^ question_mark\n    Some(format!(\"{a}\"))\n}\n\nfn const_in_pattern(x: Option<(i32, i32)>) -> Option<()> {\n    const N: i32 = 0;\n\n    let Some((x, N)) = x else {\n        return None;\n    };\n\n    None\n}\n\nfn issue_13642(x: Option<i32>) -> Option<()> {\n    let Some(x) = x else {\n        #[cfg(false)]\n        panic!();\n\n        #[cfg(true)]\n        return None;\n    };\n\n    None\n}\n\nfn issue_15679() -> Result<i32, String> {\n    let some_result: Result<i32, &'static str> = todo!();\n\n    match some_result {\n        //~^ question_mark\n        Ok(val) => val,\n        Err(err) => return Err(err.into()),\n    };\n\n    match some_result {\n        //~^ question_mark\n        Ok(val) => val,\n        Err(err) => return Err(Into::into(err)),\n    };\n\n    match some_result {\n        //~^ question_mark\n        Ok(val) => val,\n        Err(err) => return Err(<&str as Into<String>>::into(err)),\n    };\n\n    Ok(0)\n}\n\nmod issue14894 {\n    fn use_after_question_mark(do_something_else: impl Fn() -> Result<String, ()>) -> Result<(), ()> {\n        let result = do_something_else();\n        if let Err(reason) = result {\n            return Err(reason);\n        }\n        drop(result);\n\n        let result = do_something_else();\n        let x = match result {\n            //~^ question_mark\n            Ok(v) => v,\n            Err(e) => return Err(e),\n        };\n        drop(x);\n\n        Ok(())\n    }\n\n    #[expect(dropping_copy_types)]\n    fn use_after_question_mark_but_is_copy(do_something_else: impl Fn() -> Result<i32, ()>) -> Result<(), ()> {\n        let result = do_something_else();\n        if let Err(reason) = result {\n            //~^ question_mark\n            return Err(reason);\n        }\n        drop(result);\n\n        Ok(())\n    }\n}\n\nfn wrongly_unmangled_macros() -> Option<i32> {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            Some($val)\n        };\n    }\n\n    let Some(x) = test_expr!(42) else {\n        return None;\n    };\n    //~^^^ question_mark\n    Some(x);\n\n    if test_expr!(42).is_none() {\n        //~^ question_mark\n        return None;\n    }\n    test_expr!(42)\n}\n\nfn issue16429(b: i32) -> Option<i32> {\n    let a = Some(5);\n    let _ = if b == 1 {\n        b\n    } else if let Some(x) = a {\n        //~^ question_mark\n        x\n    } else {\n        return None;\n    };\n\n    Some(0)\n}\n\nfn issue16654() -> Result<(), i32> {\n    let result = func_returning_result();\n\n    #[allow(clippy::collapsible_if)]\n    if true {\n        if let Err(err) = result {\n            //~^ question_mark\n            return Err(err);\n        }\n    }\n\n    _ = [if let Err(err) = result {\n        //~^ question_mark\n        return Err(err);\n    }];\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/question_mark.stderr",
    "content": "error: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:7:5\n   |\nLL | /     if a.is_none() {\nLL | |\nLL | |         return None;\nLL | |     }\n   | |_____^ help: replace it with: `a?;`\n   |\n   = note: `-D clippy::question-mark` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::question_mark)]`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:53:9\n   |\nLL | /         if (self.opt).is_none() {\nLL | |\nLL | |             return None;\nLL | |         }\n   | |_________^ help: replace it with: `(self.opt)?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:58:9\n   |\nLL | /         if self.opt.is_none() {\nLL | |\nLL | |             return None\nLL | |         }\n   | |_________^ help: replace it with: `self.opt?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:63:17\n   |\nLL |           let _ = if self.opt.is_none() {\n   |  _________________^\nLL | |\nLL | |             return None;\nLL | |         } else {\nLL | |             self.opt\nLL | |         };\n   | |_________^ help: replace it with: `Some(self.opt?)`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:70:17\n   |\nLL |           let _ = if let Some(x) = self.opt {\n   |  _________________^\nLL | |\nLL | |             x\nLL | |         } else {\nLL | |             return None;\nLL | |         };\n   | |_________^ help: replace it with: `self.opt?`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:88:9\n   |\nLL | /         if self.opt.is_none() {\nLL | |\nLL | |             return None;\nLL | |         }\n   | |_________^ help: replace it with: `self.opt.as_ref()?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:97:9\n   |\nLL | /         if self.opt.is_none() {\nLL | |\nLL | |             return None;\nLL | |         }\n   | |_________^ help: replace it with: `self.opt.as_ref()?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:106:9\n   |\nLL | /         if self.opt.is_none() {\nLL | |\nLL | |             return None;\nLL | |         }\n   | |_________^ help: replace it with: `self.opt.as_ref()?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:114:26\n   |\nLL |           let v: &Vec<_> = if let Some(ref v) = self.opt {\n   |  __________________________^\nLL | |\nLL | |             v\nLL | |         } else {\nLL | |             return None;\nLL | |         };\n   | |_________^ help: replace it with: `self.opt.as_ref()?`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:125:17\n   |\nLL |           let v = if let Some(v) = self.opt {\n   |  _________________^\nLL | |\nLL | |             v\nLL | |         } else {\nLL | |             return None;\nLL | |         };\n   | |_________^ help: replace it with: `self.opt?`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:147:5\n   |\nLL | /     if f().is_none() {\nLL | |\nLL | |         return None;\nLL | |     }\n   | |_____^ help: replace it with: `f()?;`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:152:16\n   |\nLL |       let _val = match f() {\n   |  ________________^\nLL | |\nLL | |         Some(val) => val,\nLL | |         None => return None,\nLL | |     };\n   | |_____^ help: try instead: `f()?`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:163:5\n   |\nLL | /     match f() {\nLL | |\nLL | |         Some(val) => val,\nLL | |         None => return None,\nLL | |     };\n   | |_____^ help: try instead: `f()?`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:169:5\n   |\nLL | /     match opt_none!() {\nLL | |\nLL | |         Some(x) => x,\nLL | |         None => return None,\nLL | |     };\n   | |_____^ help: try instead: `opt_none!()?`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:196:13\n   |\nLL |     let _ = if let Ok(x) = x { x } else { return x };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x?`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:199:5\n   |\nLL | /     if x.is_err() {\nLL | |\nLL | |         return x;\nLL | |     }\n   | |_____^ help: replace it with: `x?;`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:204:16\n   |\nLL |       let _val = match func_returning_result() {\n   |  ________________^\nLL | |\nLL | |         Ok(val) => val,\nLL | |         Err(err) => return Err(err),\nLL | |     };\n   | |_____^ help: try instead: `func_returning_result()?`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:210:5\n   |\nLL | /     match func_returning_result() {\nLL | |\nLL | |         Ok(val) => val,\nLL | |         Err(err) => return Err(err),\nLL | |     };\n   | |_____^ help: try instead: `func_returning_result()?`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:302:5\n   |\nLL | /     if let Err(err) = func_returning_result() {\nLL | |\nLL | |         return Err(err);\nLL | |     }\n   | |_____^ help: replace it with: `func_returning_result()?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:310:5\n   |\nLL | /     if let Err(err) = func_returning_result() {\nLL | |\nLL | |         return Err(err);\nLL | |     }\n   | |_____^ help: replace it with: `func_returning_result()?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:393:13\n   |\nLL | /             if a.is_none() {\nLL | |\nLL | |                 return None;\n...  |\nLL | |             }\n   | |_____________^ help: replace it with: `a?;`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:454:5\n   |\nLL | /     let Some(v) = bar.foo.owned.clone() else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let v = bar.foo.owned.clone()?;`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:469:5\n   |\nLL | /     let Some(ref x) = foo.opt_x else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let x = foo.opt_x.as_ref()?;`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:479:5\n   |\nLL | /     let Some(ref mut x) = foo.opt_x else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let x = foo.opt_x.as_mut()?;`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:490:5\n   |\nLL | /     let Some(ref x @ ref y) = foo.opt_x else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let x @ y = foo.opt_x.as_ref()?;`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:494:5\n   |\nLL | /     let Some(ref x @ WrapperStructWithString(_)) = bar else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let x @ &WrapperStructWithString(_) = bar.as_ref()?;`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:498:5\n   |\nLL | /     let Some(ref mut x @ WrapperStructWithString(_)) = bar else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let x @ &mut WrapperStructWithString(_) = bar.as_mut()?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:520:5\n   |\nLL | /     if arg.is_none() {\nLL | |\nLL | |         return None;\nLL | |     }\n   | |_____^ help: replace it with: `arg?;`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:524:15\n   |\nLL |       let val = match arg {\n   |  _______________^\nLL | |\nLL | |         Some(val) => val,\nLL | |         None => return None,\nLL | |     };\n   | |_____^ help: try instead: `arg?`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:534:5\n   |\nLL | /     let Some(a) = *a else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let a = (*a)?;`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:566:5\n   |\nLL | /     match some_result {\nLL | |\nLL | |         Ok(val) => val,\nLL | |         Err(err) => return Err(err.into()),\nLL | |     };\n   | |_____^ help: try instead: `some_result?`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:572:5\n   |\nLL | /     match some_result {\nLL | |\nLL | |         Ok(val) => val,\nLL | |         Err(err) => return Err(Into::into(err)),\nLL | |     };\n   | |_____^ help: try instead: `some_result?`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:578:5\n   |\nLL | /     match some_result {\nLL | |\nLL | |         Ok(val) => val,\nLL | |         Err(err) => return Err(<&str as Into<String>>::into(err)),\nLL | |     };\n   | |_____^ help: try instead: `some_result?`\n\nerror: this `match` expression can be replaced with `?`\n  --> tests/ui/question_mark.rs:596:17\n   |\nLL |           let x = match result {\n   |  _________________^\nLL | |\nLL | |             Ok(v) => v,\nLL | |             Err(e) => return Err(e),\nLL | |         };\n   | |_________^ help: try instead: `result?`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:609:9\n   |\nLL | /         if let Err(reason) = result {\nLL | |\nLL | |             return Err(reason);\nLL | |         }\n   | |_________^ help: replace it with: `result?;`\n\nerror: this `let...else` may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:626:5\n   |\nLL | /     let Some(x) = test_expr!(42) else {\nLL | |         return None;\nLL | |     };\n   | |______^ help: replace it with: `let x = test_expr!(42)?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:632:5\n   |\nLL | /     if test_expr!(42).is_none() {\nLL | |\nLL | |         return None;\nLL | |     }\n   | |_____^ help: replace it with: `test_expr!(42)?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:643:12\n   |\nLL |       } else if let Some(x) = a {\n   |  ____________^\nLL | |\nLL | |         x\nLL | |     } else {\nLL | |         return None;\nLL | |     };\n   | |_____^ help: replace it with: `{ a? }`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:658:9\n   |\nLL | /         if let Err(err) = result {\nLL | |\nLL | |             return Err(err);\nLL | |         }\n   | |_________^ help: replace it with: `result?;`\n\nerror: this block may be rewritten with the `?` operator\n  --> tests/ui/question_mark.rs:664:10\n   |\nLL |       _ = [if let Err(err) = result {\n   |  __________^\nLL | |\nLL | |         return Err(err);\nLL | |     }];\n   | |_____^ help: replace it with: `{ result?; }`\n\nerror: aborting due to 40 previous errors\n\n"
  },
  {
    "path": "tests/ui/question_mark_used.rs",
    "content": "// non rustfixable\n#![allow(unreachable_code)]\n#![allow(dead_code)]\n#![warn(clippy::question_mark_used)]\n\nfn other_function() -> Option<i32> {\n    Some(32)\n}\n\nfn my_function() -> Option<i32> {\n    other_function()?;\n    //~^ question_mark_used\n\n    None\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/question_mark_used.stderr",
    "content": "error: the `?` operator was used\n  --> tests/ui/question_mark_used.rs:11:5\n   |\nLL |     other_function()?;\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a custom macro or match expression\n   = note: `-D clippy::question-mark-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::question_mark_used)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/range.fixed",
    "content": "#![allow(clippy::useless_vec)]\n#[warn(clippy::range_zip_with_len)]\nfn main() {\n    let v1: Vec<u64> = vec![1, 2, 3];\n    let v2: Vec<u64> = vec![4, 5];\n    let _x = v1.iter().enumerate();\n    //~^ range_zip_with_len\n\n    //~v range_zip_with_len\n    for (i, e) in v1.iter().enumerate() {\n        let _: &u64 = e;\n        let _: usize = i;\n    }\n\n    //~v range_zip_with_len\n    v1.iter().enumerate().for_each(|(i, e)| {\n        let _: &u64 = e;\n        let _: usize = i;\n    });\n\n    let _y = v1.iter().zip(0..v2.len()); // No error\n}\n\n#[allow(unused)]\nfn no_panic_with_fake_range_types() {\n    struct Range {\n        foo: i32,\n    }\n\n    let _ = Range { foo: 0 };\n}\n"
  },
  {
    "path": "tests/ui/range.rs",
    "content": "#![allow(clippy::useless_vec)]\n#[warn(clippy::range_zip_with_len)]\nfn main() {\n    let v1: Vec<u64> = vec![1, 2, 3];\n    let v2: Vec<u64> = vec![4, 5];\n    let _x = v1.iter().zip(0..v1.len());\n    //~^ range_zip_with_len\n\n    //~v range_zip_with_len\n    for (e, i) in v1.iter().zip(0..v1.len()) {\n        let _: &u64 = e;\n        let _: usize = i;\n    }\n\n    //~v range_zip_with_len\n    v1.iter().zip(0..v1.len()).for_each(|(e, i)| {\n        let _: &u64 = e;\n        let _: usize = i;\n    });\n\n    let _y = v1.iter().zip(0..v2.len()); // No error\n}\n\n#[allow(unused)]\nfn no_panic_with_fake_range_types() {\n    struct Range {\n        foo: i32,\n    }\n\n    let _ = Range { foo: 0 };\n}\n"
  },
  {
    "path": "tests/ui/range.stderr",
    "content": "error: using `.zip()` with a range and `.len()`\n  --> tests/ui/range.rs:6:14\n   |\nLL |     let _x = v1.iter().zip(0..v1.len());\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the order of the element and the index will be swapped\n   = note: `-D clippy::range-zip-with-len` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::range_zip_with_len)]`\nhelp: use\n   |\nLL -     let _x = v1.iter().zip(0..v1.len());\nLL +     let _x = v1.iter().enumerate();\n   |\n\nerror: using `.zip()` with a range and `.len()`\n  --> tests/ui/range.rs:10:19\n   |\nLL |     for (e, i) in v1.iter().zip(0..v1.len()) {\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     for (e, i) in v1.iter().zip(0..v1.len()) {\nLL +     for (i, e) in v1.iter().enumerate() {\n   |\n\nerror: using `.zip()` with a range and `.len()`\n  --> tests/ui/range.rs:16:5\n   |\nLL |     v1.iter().zip(0..v1.len()).for_each(|(e, i)| {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use\n   |\nLL -     v1.iter().zip(0..v1.len()).for_each(|(e, i)| {\nLL +     v1.iter().enumerate().for_each(|(i, e)| {\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/range_contains.fixed",
    "content": "#![warn(clippy::manual_range_contains)]\n#![allow(unused)]\n#![allow(clippy::no_effect)]\n#![allow(clippy::short_circuit_statement)]\n#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::impossible_comparisons)]\n#![allow(clippy::redundant_comparisons)]\n\nfn main() {\n    let x = 9_i32;\n\n    // order shouldn't matter\n    (8..12).contains(&x);\n    //~^ manual_range_contains\n    (21..42).contains(&x);\n    //~^ manual_range_contains\n    (1..100).contains(&x);\n    //~^ manual_range_contains\n\n    // also with inclusive ranges\n    (9..=99).contains(&x);\n    //~^ manual_range_contains\n    (1..=33).contains(&x);\n    //~^ manual_range_contains\n    (1..=999).contains(&x);\n    //~^ manual_range_contains\n\n    // and the outside\n    !(8..12).contains(&x);\n    //~^ manual_range_contains\n    !(21..42).contains(&x);\n    //~^ manual_range_contains\n    !(1..100).contains(&x);\n    //~^ manual_range_contains\n\n    // also with the outside of inclusive ranges\n    !(9..=99).contains(&x);\n    //~^ manual_range_contains\n    !(1..=33).contains(&x);\n    //~^ manual_range_contains\n    !(1..=999).contains(&x);\n    //~^ manual_range_contains\n\n    // not a range.contains\n    x > 8 && x < 12; // lower bound not inclusive\n    x < 8 && x <= 12; // same direction\n    x >= 12 && 12 >= x; // same bounds\n    x < 8 && x > 12; // wrong direction\n\n    x <= 8 || x >= 12;\n    x >= 8 || x >= 12;\n    x < 12 || 12 < x;\n    x >= 8 || x <= 12;\n\n    // Fix #6315\n    let y = 3.;\n    (0. ..1.).contains(&y);\n    //~^ manual_range_contains\n    !(0. ..=1.).contains(&y);\n    //~^ manual_range_contains\n\n    // handle negatives #8721\n    (-10..=10).contains(&x);\n    //~^ manual_range_contains\n    x >= 10 && x <= -10;\n    (-3. ..=3.).contains(&y);\n    //~^ manual_range_contains\n    y >= 3. && y <= -3.;\n\n    // Fix #8745\n    let z = 42;\n    (0..=10).contains(&x) && (0..=10).contains(&z);\n    //~^ manual_range_contains\n    //~| manual_range_contains\n    !(0..10).contains(&x) || !(0..10).contains(&z);\n    //~^ manual_range_contains\n    //~| manual_range_contains\n    // Make sure operators in parens don't give a breaking suggestion\n    ((x % 2 == 0) || (x < 0)) || (x >= 10);\n}\n\n// Fix #6373\npub const fn in_range(a: i32) -> bool {\n    3 <= a && a <= 20\n}\n\n#[clippy::msrv = \"1.34\"]\nfn msrv_1_34() {\n    let x = 5;\n    x >= 8 && x < 34;\n}\n\n#[clippy::msrv = \"1.35\"]\nfn msrv_1_35() {\n    let x = 5;\n    (8..35).contains(&x);\n    //~^ manual_range_contains\n}\n"
  },
  {
    "path": "tests/ui/range_contains.rs",
    "content": "#![warn(clippy::manual_range_contains)]\n#![allow(unused)]\n#![allow(clippy::no_effect)]\n#![allow(clippy::short_circuit_statement)]\n#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::impossible_comparisons)]\n#![allow(clippy::redundant_comparisons)]\n\nfn main() {\n    let x = 9_i32;\n\n    // order shouldn't matter\n    x >= 8 && x < 12;\n    //~^ manual_range_contains\n    x < 42 && x >= 21;\n    //~^ manual_range_contains\n    100 > x && 1 <= x;\n    //~^ manual_range_contains\n\n    // also with inclusive ranges\n    x >= 9 && x <= 99;\n    //~^ manual_range_contains\n    x <= 33 && x >= 1;\n    //~^ manual_range_contains\n    999 >= x && 1 <= x;\n    //~^ manual_range_contains\n\n    // and the outside\n    x < 8 || x >= 12;\n    //~^ manual_range_contains\n    x >= 42 || x < 21;\n    //~^ manual_range_contains\n    100 <= x || 1 > x;\n    //~^ manual_range_contains\n\n    // also with the outside of inclusive ranges\n    x < 9 || x > 99;\n    //~^ manual_range_contains\n    x > 33 || x < 1;\n    //~^ manual_range_contains\n    999 < x || 1 > x;\n    //~^ manual_range_contains\n\n    // not a range.contains\n    x > 8 && x < 12; // lower bound not inclusive\n    x < 8 && x <= 12; // same direction\n    x >= 12 && 12 >= x; // same bounds\n    x < 8 && x > 12; // wrong direction\n\n    x <= 8 || x >= 12;\n    x >= 8 || x >= 12;\n    x < 12 || 12 < x;\n    x >= 8 || x <= 12;\n\n    // Fix #6315\n    let y = 3.;\n    y >= 0. && y < 1.;\n    //~^ manual_range_contains\n    y < 0. || y > 1.;\n    //~^ manual_range_contains\n\n    // handle negatives #8721\n    x >= -10 && x <= 10;\n    //~^ manual_range_contains\n    x >= 10 && x <= -10;\n    y >= -3. && y <= 3.;\n    //~^ manual_range_contains\n    y >= 3. && y <= -3.;\n\n    // Fix #8745\n    let z = 42;\n    (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);\n    //~^ manual_range_contains\n    //~| manual_range_contains\n    (x < 0) || (x >= 10) || (z < 0) || (z >= 10);\n    //~^ manual_range_contains\n    //~| manual_range_contains\n    // Make sure operators in parens don't give a breaking suggestion\n    ((x % 2 == 0) || (x < 0)) || (x >= 10);\n}\n\n// Fix #6373\npub const fn in_range(a: i32) -> bool {\n    3 <= a && a <= 20\n}\n\n#[clippy::msrv = \"1.34\"]\nfn msrv_1_34() {\n    let x = 5;\n    x >= 8 && x < 34;\n}\n\n#[clippy::msrv = \"1.35\"]\nfn msrv_1_35() {\n    let x = 5;\n    x >= 8 && x < 35;\n    //~^ manual_range_contains\n}\n"
  },
  {
    "path": "tests/ui/range_contains.stderr",
    "content": "error: manual `Range::contains` implementation\n  --> tests/ui/range_contains.rs:13:5\n   |\nLL |     x >= 8 && x < 12;\n   |     ^^^^^^^^^^^^^^^^ help: use: `(8..12).contains(&x)`\n   |\n   = note: `-D clippy::manual-range-contains` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_range_contains)]`\n\nerror: manual `Range::contains` implementation\n  --> tests/ui/range_contains.rs:15:5\n   |\nLL |     x < 42 && x >= 21;\n   |     ^^^^^^^^^^^^^^^^^ help: use: `(21..42).contains(&x)`\n\nerror: manual `Range::contains` implementation\n  --> tests/ui/range_contains.rs:17:5\n   |\nLL |     100 > x && 1 <= x;\n   |     ^^^^^^^^^^^^^^^^^ help: use: `(1..100).contains(&x)`\n\nerror: manual `RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:21:5\n   |\nLL |     x >= 9 && x <= 99;\n   |     ^^^^^^^^^^^^^^^^^ help: use: `(9..=99).contains(&x)`\n\nerror: manual `RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:23:5\n   |\nLL |     x <= 33 && x >= 1;\n   |     ^^^^^^^^^^^^^^^^^ help: use: `(1..=33).contains(&x)`\n\nerror: manual `RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:25:5\n   |\nLL |     999 >= x && 1 <= x;\n   |     ^^^^^^^^^^^^^^^^^^ help: use: `(1..=999).contains(&x)`\n\nerror: manual `!Range::contains` implementation\n  --> tests/ui/range_contains.rs:29:5\n   |\nLL |     x < 8 || x >= 12;\n   |     ^^^^^^^^^^^^^^^^ help: use: `!(8..12).contains(&x)`\n\nerror: manual `!Range::contains` implementation\n  --> tests/ui/range_contains.rs:31:5\n   |\nLL |     x >= 42 || x < 21;\n   |     ^^^^^^^^^^^^^^^^^ help: use: `!(21..42).contains(&x)`\n\nerror: manual `!Range::contains` implementation\n  --> tests/ui/range_contains.rs:33:5\n   |\nLL |     100 <= x || 1 > x;\n   |     ^^^^^^^^^^^^^^^^^ help: use: `!(1..100).contains(&x)`\n\nerror: manual `!RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:37:5\n   |\nLL |     x < 9 || x > 99;\n   |     ^^^^^^^^^^^^^^^ help: use: `!(9..=99).contains(&x)`\n\nerror: manual `!RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:39:5\n   |\nLL |     x > 33 || x < 1;\n   |     ^^^^^^^^^^^^^^^ help: use: `!(1..=33).contains(&x)`\n\nerror: manual `!RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:41:5\n   |\nLL |     999 < x || 1 > x;\n   |     ^^^^^^^^^^^^^^^^ help: use: `!(1..=999).contains(&x)`\n\nerror: manual `Range::contains` implementation\n  --> tests/ui/range_contains.rs:57:5\n   |\nLL |     y >= 0. && y < 1.;\n   |     ^^^^^^^^^^^^^^^^^ help: use: `(0. ..1.).contains(&y)`\n\nerror: manual `!RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:59:5\n   |\nLL |     y < 0. || y > 1.;\n   |     ^^^^^^^^^^^^^^^^ help: use: `!(0. ..=1.).contains(&y)`\n\nerror: manual `RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:63:5\n   |\nLL |     x >= -10 && x <= 10;\n   |     ^^^^^^^^^^^^^^^^^^^ help: use: `(-10..=10).contains(&x)`\n\nerror: manual `RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:66:5\n   |\nLL |     y >= -3. && y <= 3.;\n   |     ^^^^^^^^^^^^^^^^^^^ help: use: `(-3. ..=3.).contains(&y)`\n\nerror: manual `RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:72:30\n   |\nLL |     (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);\n   |                              ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&z)`\n\nerror: manual `RangeInclusive::contains` implementation\n  --> tests/ui/range_contains.rs:72:5\n   |\nLL |     (x >= 0) && (x <= 10) && (z >= 0) && (z <= 10);\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: use: `(0..=10).contains(&x)`\n\nerror: manual `!Range::contains` implementation\n  --> tests/ui/range_contains.rs:75:29\n   |\nLL |     (x < 0) || (x >= 10) || (z < 0) || (z >= 10);\n   |                             ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&z)`\n\nerror: manual `!Range::contains` implementation\n  --> tests/ui/range_contains.rs:75:5\n   |\nLL |     (x < 0) || (x >= 10) || (z < 0) || (z >= 10);\n   |     ^^^^^^^^^^^^^^^^^^^^ help: use: `!(0..10).contains(&x)`\n\nerror: manual `Range::contains` implementation\n  --> tests/ui/range_contains.rs:96:5\n   |\nLL |     x >= 8 && x < 35;\n   |     ^^^^^^^^^^^^^^^^ help: use: `(8..35).contains(&x)`\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/range_plus_minus_one.fixed",
    "content": "#![warn(clippy::range_minus_one, clippy::range_plus_one)]\n#![allow(unused_parens)]\n#![allow(clippy::iter_with_drain)]\n\nuse std::ops::{Index, IndexMut, Range, RangeBounds, RangeInclusive};\n\nfn f() -> usize {\n    42\n}\n\nmacro_rules! macro_plus_one {\n    ($m: literal) => {\n        for i in 0..$m + 1 {\n            println!(\"{}\", i);\n        }\n    };\n}\n\nmacro_rules! macro_minus_one {\n    ($m: literal) => {\n        for i in 0..=$m - 1 {\n            println!(\"{}\", i);\n        }\n    };\n}\n\nfn main() {\n    for _ in 0..2 {}\n    for _ in 0..=2 {}\n\n    for _ in 0..=3 {}\n    //~^ range_plus_one\n    for _ in 0..=3 + 1 {}\n\n    for _ in 0..=5 {}\n    //~^ range_plus_one\n    for _ in 0..=1 + 5 {}\n\n    for _ in 1..=1 {}\n    //~^ range_plus_one\n    for _ in 1..=1 + 1 {}\n\n    for _ in 0..13 + 13 {}\n    for _ in 0..=13 - 7 {}\n\n    for _ in 0..=f() {}\n    //~^ range_plus_one\n    for _ in 0..=(1 + f()) {}\n\n    // Those are not linted, as in the general case we cannot be sure that the exact type won't be\n    // important.\n    let _ = ..11 - 1;\n    let _ = ..=11 - 1;\n    let _ = ..=(11 - 1);\n    let _ = (1..11 + 1);\n    let _ = (f() + 1)..(f() + 1);\n\n    const ONE: usize = 1;\n    // integer consts are linted, too\n    for _ in 1..=ONE {}\n    //~^ range_plus_one\n\n    let mut vec: Vec<()> = std::vec::Vec::new();\n    vec.drain(..);\n\n    macro_plus_one!(5);\n    macro_minus_one!(5);\n\n    // As an instance of `Iterator`\n    (1..=10).for_each(|_| {});\n    //~^ range_plus_one\n\n    // As an instance of `IntoIterator`\n    #[allow(clippy::useless_conversion)]\n    (1..=10).into_iter().for_each(|_| {});\n    //~^ range_plus_one\n\n    // As an instance of `RangeBounds`\n    {\n        let _ = (1..=10).start_bound();\n        //~^ range_plus_one\n    }\n\n    // As a `SliceIndex`\n    let a = [10, 20, 30];\n    let _ = &a[1..=1];\n    //~^ range_plus_one\n\n    // As method call argument\n    vec.drain(2..=3);\n    //~^ range_plus_one\n\n    // As function call argument\n    take_arg(10..=20);\n    //~^ range_plus_one\n\n    // As function call argument inside a block\n    take_arg({ 10..=20 });\n    //~^ range_plus_one\n\n    // Do not lint in case types are unified\n    take_arg(if true { 10..20 } else { 10..20 + 1 });\n\n    // Do not lint, as the same type is used for both parameters\n    take_args(10..20 + 1, 10..21);\n\n    // Do not lint, as the range type is also used indirectly in second parameter\n    take_arg_and_struct(10..20 + 1, S { t: 1..2 });\n\n    // As target of `IndexMut`\n    let mut a = [10, 20, 30];\n    a[0..=2][0] = 1;\n    //~^ range_plus_one\n}\n\nfn take_arg<T: Iterator<Item = u32>>(_: T) {}\nfn take_args<T: Iterator<Item = u32>>(_: T, _: T) {}\n\nstruct S<T> {\n    t: T,\n}\nfn take_arg_and_struct<T: Iterator<Item = u32>>(_: T, _: S<T>) {}\n\nfn no_index_by_range_inclusive(a: usize) {\n    struct S;\n\n    impl Index<Range<usize>> for S {\n        type Output = [u32];\n        fn index(&self, _: Range<usize>) -> &Self::Output {\n            &[]\n        }\n    }\n\n    _ = &S[0..a + 1];\n}\n\nfn no_index_mut_with_switched_range(a: usize) {\n    struct S(u32);\n\n    impl Index<Range<usize>> for S {\n        type Output = u32;\n        fn index(&self, _: Range<usize>) -> &Self::Output {\n            &self.0\n        }\n    }\n\n    impl IndexMut<Range<usize>> for S {\n        fn index_mut(&mut self, _: Range<usize>) -> &mut Self::Output {\n            &mut self.0\n        }\n    }\n\n    impl Index<RangeInclusive<usize>> for S {\n        type Output = u32;\n        fn index(&self, _: RangeInclusive<usize>) -> &Self::Output {\n            &self.0\n        }\n    }\n\n    S(2)[0..a + 1] = 3;\n}\n\nfn issue9908() {\n    // Simplified test case\n    let _ = || 0..=1;\n\n    // Original test case\n    let full_length = 1024;\n    let range = {\n        // do some stuff, omit here\n        None\n    };\n\n    let range = range.map(|(s, t)| s..=t).unwrap_or(0..=(full_length - 1));\n\n    assert_eq!(range, 0..=1023);\n}\n\nfn issue9908_2(n: usize) -> usize {\n    (1..n).sum()\n    //~^ range_minus_one\n}\n"
  },
  {
    "path": "tests/ui/range_plus_minus_one.rs",
    "content": "#![warn(clippy::range_minus_one, clippy::range_plus_one)]\n#![allow(unused_parens)]\n#![allow(clippy::iter_with_drain)]\n\nuse std::ops::{Index, IndexMut, Range, RangeBounds, RangeInclusive};\n\nfn f() -> usize {\n    42\n}\n\nmacro_rules! macro_plus_one {\n    ($m: literal) => {\n        for i in 0..$m + 1 {\n            println!(\"{}\", i);\n        }\n    };\n}\n\nmacro_rules! macro_minus_one {\n    ($m: literal) => {\n        for i in 0..=$m - 1 {\n            println!(\"{}\", i);\n        }\n    };\n}\n\nfn main() {\n    for _ in 0..2 {}\n    for _ in 0..=2 {}\n\n    for _ in 0..3 + 1 {}\n    //~^ range_plus_one\n    for _ in 0..=3 + 1 {}\n\n    for _ in 0..1 + 5 {}\n    //~^ range_plus_one\n    for _ in 0..=1 + 5 {}\n\n    for _ in 1..1 + 1 {}\n    //~^ range_plus_one\n    for _ in 1..=1 + 1 {}\n\n    for _ in 0..13 + 13 {}\n    for _ in 0..=13 - 7 {}\n\n    for _ in 0..(1 + f()) {}\n    //~^ range_plus_one\n    for _ in 0..=(1 + f()) {}\n\n    // Those are not linted, as in the general case we cannot be sure that the exact type won't be\n    // important.\n    let _ = ..11 - 1;\n    let _ = ..=11 - 1;\n    let _ = ..=(11 - 1);\n    let _ = (1..11 + 1);\n    let _ = (f() + 1)..(f() + 1);\n\n    const ONE: usize = 1;\n    // integer consts are linted, too\n    for _ in 1..ONE + ONE {}\n    //~^ range_plus_one\n\n    let mut vec: Vec<()> = std::vec::Vec::new();\n    vec.drain(..);\n\n    macro_plus_one!(5);\n    macro_minus_one!(5);\n\n    // As an instance of `Iterator`\n    (1..10 + 1).for_each(|_| {});\n    //~^ range_plus_one\n\n    // As an instance of `IntoIterator`\n    #[allow(clippy::useless_conversion)]\n    (1..10 + 1).into_iter().for_each(|_| {});\n    //~^ range_plus_one\n\n    // As an instance of `RangeBounds`\n    {\n        let _ = (1..10 + 1).start_bound();\n        //~^ range_plus_one\n    }\n\n    // As a `SliceIndex`\n    let a = [10, 20, 30];\n    let _ = &a[1..1 + 1];\n    //~^ range_plus_one\n\n    // As method call argument\n    vec.drain(2..3 + 1);\n    //~^ range_plus_one\n\n    // As function call argument\n    take_arg(10..20 + 1);\n    //~^ range_plus_one\n\n    // As function call argument inside a block\n    take_arg({ 10..20 + 1 });\n    //~^ range_plus_one\n\n    // Do not lint in case types are unified\n    take_arg(if true { 10..20 } else { 10..20 + 1 });\n\n    // Do not lint, as the same type is used for both parameters\n    take_args(10..20 + 1, 10..21);\n\n    // Do not lint, as the range type is also used indirectly in second parameter\n    take_arg_and_struct(10..20 + 1, S { t: 1..2 });\n\n    // As target of `IndexMut`\n    let mut a = [10, 20, 30];\n    a[0..2 + 1][0] = 1;\n    //~^ range_plus_one\n}\n\nfn take_arg<T: Iterator<Item = u32>>(_: T) {}\nfn take_args<T: Iterator<Item = u32>>(_: T, _: T) {}\n\nstruct S<T> {\n    t: T,\n}\nfn take_arg_and_struct<T: Iterator<Item = u32>>(_: T, _: S<T>) {}\n\nfn no_index_by_range_inclusive(a: usize) {\n    struct S;\n\n    impl Index<Range<usize>> for S {\n        type Output = [u32];\n        fn index(&self, _: Range<usize>) -> &Self::Output {\n            &[]\n        }\n    }\n\n    _ = &S[0..a + 1];\n}\n\nfn no_index_mut_with_switched_range(a: usize) {\n    struct S(u32);\n\n    impl Index<Range<usize>> for S {\n        type Output = u32;\n        fn index(&self, _: Range<usize>) -> &Self::Output {\n            &self.0\n        }\n    }\n\n    impl IndexMut<Range<usize>> for S {\n        fn index_mut(&mut self, _: Range<usize>) -> &mut Self::Output {\n            &mut self.0\n        }\n    }\n\n    impl Index<RangeInclusive<usize>> for S {\n        type Output = u32;\n        fn index(&self, _: RangeInclusive<usize>) -> &Self::Output {\n            &self.0\n        }\n    }\n\n    S(2)[0..a + 1] = 3;\n}\n\nfn issue9908() {\n    // Simplified test case\n    let _ = || 0..=1;\n\n    // Original test case\n    let full_length = 1024;\n    let range = {\n        // do some stuff, omit here\n        None\n    };\n\n    let range = range.map(|(s, t)| s..=t).unwrap_or(0..=(full_length - 1));\n\n    assert_eq!(range, 0..=1023);\n}\n\nfn issue9908_2(n: usize) -> usize {\n    (1..=n - 1).sum()\n    //~^ range_minus_one\n}\n"
  },
  {
    "path": "tests/ui/range_plus_minus_one.stderr",
    "content": "error: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:31:14\n   |\nLL |     for _ in 0..3 + 1 {}\n   |              ^^^^^^^^ help: use: `0..=3`\n   |\n   = note: `-D clippy::range-plus-one` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::range_plus_one)]`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:35:14\n   |\nLL |     for _ in 0..1 + 5 {}\n   |              ^^^^^^^^ help: use: `0..=5`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:39:14\n   |\nLL |     for _ in 1..1 + 1 {}\n   |              ^^^^^^^^ help: use: `1..=1`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:46:14\n   |\nLL |     for _ in 0..(1 + f()) {}\n   |              ^^^^^^^^^^^^ help: use: `0..=f()`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:60:14\n   |\nLL |     for _ in 1..ONE + ONE {}\n   |              ^^^^^^^^^^^^ help: use: `1..=ONE`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:70:6\n   |\nLL |     (1..10 + 1).for_each(|_| {});\n   |      ^^^^^^^^^ help: use: `1..=10`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:75:6\n   |\nLL |     (1..10 + 1).into_iter().for_each(|_| {});\n   |      ^^^^^^^^^ help: use: `1..=10`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:80:18\n   |\nLL |         let _ = (1..10 + 1).start_bound();\n   |                  ^^^^^^^^^ help: use: `1..=10`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:86:16\n   |\nLL |     let _ = &a[1..1 + 1];\n   |                ^^^^^^^^ help: use: `1..=1`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:90:15\n   |\nLL |     vec.drain(2..3 + 1);\n   |               ^^^^^^^^ help: use: `2..=3`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:94:14\n   |\nLL |     take_arg(10..20 + 1);\n   |              ^^^^^^^^^^ help: use: `10..=20`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:98:16\n   |\nLL |     take_arg({ 10..20 + 1 });\n   |                ^^^^^^^^^^ help: use: `10..=20`\n\nerror: an inclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:112:7\n   |\nLL |     a[0..2 + 1][0] = 1;\n   |       ^^^^^^^^ help: use: `0..=2`\n\nerror: an exclusive range would be more readable\n  --> tests/ui/range_plus_minus_one.rs:180:6\n   |\nLL |     (1..=n - 1).sum()\n   |      ^^^^^^^^^ help: use: `1..n`\n   |\n   = note: `-D clippy::range-minus-one` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::range_minus_one)]`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/range_unfixable.rs",
    "content": "//@no-rustfix\n#![allow(clippy::useless_vec)]\n#[warn(clippy::range_zip_with_len)]\nfn main() {\n    let v1: Vec<u64> = vec![1, 2, 3];\n    let v2: Vec<u64> = vec![4, 5];\n\n    // Do not autofix, `filter()` would not consume the iterator.\n    //~v range_zip_with_len\n    v1.iter().zip(0..v1.len()).filter(|(_, i)| *i < 2).for_each(|(e, i)| {\n        let _: &u64 = e;\n        let _: usize = i;\n    });\n}\n"
  },
  {
    "path": "tests/ui/range_unfixable.stderr",
    "content": "error: using `.zip()` with a range and `.len()`\n  --> tests/ui/range_unfixable.rs:10:5\n   |\nLL |     v1.iter().zip(0..v1.len()).filter(|(_, i)| *i < 2).for_each(|(e, i)| {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the order of the element and the index will be swapped\n   = note: `-D clippy::range-zip-with-len` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::range_zip_with_len)]`\nhelp: use\n   |\nLL -     v1.iter().zip(0..v1.len()).filter(|(_, i)| *i < 2).for_each(|(e, i)| {\nLL +     v1.iter().enumerate().filter(|(_, i)| *i < 2).for_each(|(e, i)| {\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/rc_buffer.fixed",
    "content": "#![warn(clippy::rc_buffer)]\n\nuse std::cell::RefCell;\nuse std::ffi::OsString;\nuse std::path::PathBuf;\nuse std::rc::Rc;\n\nstruct S {\n    // triggers lint\n    bad1: Rc<str>,\n    //~^ rc_buffer\n    bad2: Rc<std::path::Path>,\n    //~^ rc_buffer\n    bad3: Rc<[u8]>,\n    //~^ rc_buffer\n    bad4: Rc<std::ffi::OsStr>,\n    //~^ rc_buffer\n    // does not trigger lint\n    good1: Rc<RefCell<String>>,\n}\n\n// triggers lint\nfn func_bad1(_: Rc<str>) {}\n//~^ rc_buffer\nfn func_bad2(_: Rc<std::path::Path>) {}\n//~^ rc_buffer\nfn func_bad3(_: Rc<[u8]>) {}\n//~^ rc_buffer\nfn func_bad4(_: Rc<std::ffi::OsStr>) {}\n//~^ rc_buffer\n// does not trigger lint\nfn func_good1(_: Rc<RefCell<String>>) {}\n\nmod issue_15802 {\n    fn foo(_: std::rc::Rc<[u8]>) {}\n    //~^ rc_buffer\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rc_buffer.rs",
    "content": "#![warn(clippy::rc_buffer)]\n\nuse std::cell::RefCell;\nuse std::ffi::OsString;\nuse std::path::PathBuf;\nuse std::rc::Rc;\n\nstruct S {\n    // triggers lint\n    bad1: Rc<String>,\n    //~^ rc_buffer\n    bad2: Rc<PathBuf>,\n    //~^ rc_buffer\n    bad3: Rc<Vec<u8>>,\n    //~^ rc_buffer\n    bad4: Rc<OsString>,\n    //~^ rc_buffer\n    // does not trigger lint\n    good1: Rc<RefCell<String>>,\n}\n\n// triggers lint\nfn func_bad1(_: Rc<String>) {}\n//~^ rc_buffer\nfn func_bad2(_: Rc<PathBuf>) {}\n//~^ rc_buffer\nfn func_bad3(_: Rc<Vec<u8>>) {}\n//~^ rc_buffer\nfn func_bad4(_: Rc<OsString>) {}\n//~^ rc_buffer\n// does not trigger lint\nfn func_good1(_: Rc<RefCell<String>>) {}\n\nmod issue_15802 {\n    fn foo(_: std::rc::Rc<Vec<u8>>) {}\n    //~^ rc_buffer\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rc_buffer.stderr",
    "content": "error: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:10:11\n   |\nLL |     bad1: Rc<String>,\n   |           ^^^^^^^^^^\n   |\n   = note: `-D clippy::rc-buffer` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::rc_buffer)]`\nhelp: try\n   |\nLL -     bad1: Rc<String>,\nLL +     bad1: Rc<str>,\n   |\n\nerror: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:12:11\n   |\nLL |     bad2: Rc<PathBuf>,\n   |           ^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     bad2: Rc<PathBuf>,\nLL +     bad2: Rc<std::path::Path>,\n   |\n\nerror: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:14:11\n   |\nLL |     bad3: Rc<Vec<u8>>,\n   |           ^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     bad3: Rc<Vec<u8>>,\nLL +     bad3: Rc<[u8]>,\n   |\n\nerror: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:16:11\n   |\nLL |     bad4: Rc<OsString>,\n   |           ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     bad4: Rc<OsString>,\nLL +     bad4: Rc<std::ffi::OsStr>,\n   |\n\nerror: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:23:17\n   |\nLL | fn func_bad1(_: Rc<String>) {}\n   |                 ^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - fn func_bad1(_: Rc<String>) {}\nLL + fn func_bad1(_: Rc<str>) {}\n   |\n\nerror: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:25:17\n   |\nLL | fn func_bad2(_: Rc<PathBuf>) {}\n   |                 ^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - fn func_bad2(_: Rc<PathBuf>) {}\nLL + fn func_bad2(_: Rc<std::path::Path>) {}\n   |\n\nerror: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:27:17\n   |\nLL | fn func_bad3(_: Rc<Vec<u8>>) {}\n   |                 ^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - fn func_bad3(_: Rc<Vec<u8>>) {}\nLL + fn func_bad3(_: Rc<[u8]>) {}\n   |\n\nerror: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:29:17\n   |\nLL | fn func_bad4(_: Rc<OsString>) {}\n   |                 ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - fn func_bad4(_: Rc<OsString>) {}\nLL + fn func_bad4(_: Rc<std::ffi::OsStr>) {}\n   |\n\nerror: usage of `Rc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer.rs:35:15\n   |\nLL |     fn foo(_: std::rc::Rc<Vec<u8>>) {}\n   |               ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     fn foo(_: std::rc::Rc<Vec<u8>>) {}\nLL +     fn foo(_: std::rc::Rc<[u8]>) {}\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/rc_buffer_arc.fixed",
    "content": "#![warn(clippy::rc_buffer)]\n\nuse std::ffi::OsString;\nuse std::path::PathBuf;\nuse std::sync::{Arc, Mutex};\n\nstruct S {\n    // triggers lint\n    bad1: Arc<str>,\n    //~^ rc_buffer\n    bad2: Arc<std::path::Path>,\n    //~^ rc_buffer\n    bad3: Arc<[u8]>,\n    //~^ rc_buffer\n    bad4: Arc<std::ffi::OsStr>,\n    //~^ rc_buffer\n    // does not trigger lint\n    good1: Arc<Mutex<String>>,\n}\n\n// triggers lint\nfn func_bad1(_: Arc<str>) {}\n//~^ rc_buffer\nfn func_bad2(_: Arc<std::path::Path>) {}\n//~^ rc_buffer\nfn func_bad3(_: Arc<[u8]>) {}\n//~^ rc_buffer\nfn func_bad4(_: Arc<std::ffi::OsStr>) {}\n//~^ rc_buffer\n// does not trigger lint\nfn func_good1(_: Arc<Mutex<String>>) {}\n\nmod issue_15802 {\n    fn foo(_: std::sync::Arc<[u8]>) {}\n    //~^ rc_buffer\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rc_buffer_arc.rs",
    "content": "#![warn(clippy::rc_buffer)]\n\nuse std::ffi::OsString;\nuse std::path::PathBuf;\nuse std::sync::{Arc, Mutex};\n\nstruct S {\n    // triggers lint\n    bad1: Arc<String>,\n    //~^ rc_buffer\n    bad2: Arc<PathBuf>,\n    //~^ rc_buffer\n    bad3: Arc<Vec<u8>>,\n    //~^ rc_buffer\n    bad4: Arc<OsString>,\n    //~^ rc_buffer\n    // does not trigger lint\n    good1: Arc<Mutex<String>>,\n}\n\n// triggers lint\nfn func_bad1(_: Arc<String>) {}\n//~^ rc_buffer\nfn func_bad2(_: Arc<PathBuf>) {}\n//~^ rc_buffer\nfn func_bad3(_: Arc<Vec<u8>>) {}\n//~^ rc_buffer\nfn func_bad4(_: Arc<OsString>) {}\n//~^ rc_buffer\n// does not trigger lint\nfn func_good1(_: Arc<Mutex<String>>) {}\n\nmod issue_15802 {\n    fn foo(_: std::sync::Arc<Vec<u8>>) {}\n    //~^ rc_buffer\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rc_buffer_arc.stderr",
    "content": "error: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:9:11\n   |\nLL |     bad1: Arc<String>,\n   |           ^^^^^^^^^^^\n   |\n   = note: `-D clippy::rc-buffer` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::rc_buffer)]`\nhelp: try\n   |\nLL -     bad1: Arc<String>,\nLL +     bad1: Arc<str>,\n   |\n\nerror: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:11:11\n   |\nLL |     bad2: Arc<PathBuf>,\n   |           ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     bad2: Arc<PathBuf>,\nLL +     bad2: Arc<std::path::Path>,\n   |\n\nerror: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:13:11\n   |\nLL |     bad3: Arc<Vec<u8>>,\n   |           ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     bad3: Arc<Vec<u8>>,\nLL +     bad3: Arc<[u8]>,\n   |\n\nerror: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:15:11\n   |\nLL |     bad4: Arc<OsString>,\n   |           ^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     bad4: Arc<OsString>,\nLL +     bad4: Arc<std::ffi::OsStr>,\n   |\n\nerror: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:22:17\n   |\nLL | fn func_bad1(_: Arc<String>) {}\n   |                 ^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - fn func_bad1(_: Arc<String>) {}\nLL + fn func_bad1(_: Arc<str>) {}\n   |\n\nerror: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:24:17\n   |\nLL | fn func_bad2(_: Arc<PathBuf>) {}\n   |                 ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - fn func_bad2(_: Arc<PathBuf>) {}\nLL + fn func_bad2(_: Arc<std::path::Path>) {}\n   |\n\nerror: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:26:17\n   |\nLL | fn func_bad3(_: Arc<Vec<u8>>) {}\n   |                 ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - fn func_bad3(_: Arc<Vec<u8>>) {}\nLL + fn func_bad3(_: Arc<[u8]>) {}\n   |\n\nerror: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:28:17\n   |\nLL | fn func_bad4(_: Arc<OsString>) {}\n   |                 ^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - fn func_bad4(_: Arc<OsString>) {}\nLL + fn func_bad4(_: Arc<std::ffi::OsStr>) {}\n   |\n\nerror: usage of `Arc<T>` when `T` is a buffer type\n  --> tests/ui/rc_buffer_arc.rs:34:15\n   |\nLL |     fn foo(_: std::sync::Arc<Vec<u8>>) {}\n   |               ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     fn foo(_: std::sync::Arc<Vec<u8>>) {}\nLL +     fn foo(_: std::sync::Arc<[u8]>) {}\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/rc_buffer_redefined_string.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::rc_buffer)]\n\nuse std::rc::Rc;\n\nstruct String;\n\nstruct S {\n    // does not trigger lint\n    good1: Rc<String>,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rc_clone_in_vec_init/arc.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![warn(clippy::rc_clone_in_vec_init)]\n#![allow(clippy::useless_vec)]\nuse std::sync::{Arc, Mutex};\n\nfn main() {}\n\nfn should_warn_simple_case() {\n    let v = vec![Arc::new(\"x\".to_string()); 2];\n    //~^ rc_clone_in_vec_init\n}\n\nfn should_warn_simple_case_with_big_indentation() {\n    if true {\n        let k = 1;\n        dbg!(k);\n        if true {\n            let v = vec![Arc::new(\"x\".to_string()); 2];\n            //~^ rc_clone_in_vec_init\n        }\n    }\n}\n\nfn should_warn_complex_case() {\n    let v = vec![\n    //~^ rc_clone_in_vec_init\n\n\n        std::sync::Arc::new(Mutex::new({\n            let x = 1;\n            dbg!(x);\n            x\n        }));\n        2\n    ];\n\n    let v1 = vec![\n    //~^ rc_clone_in_vec_init\n\n\n        Arc::new(Mutex::new({\n            let x = 1;\n            dbg!(x);\n            x\n        }));\n        2\n    ];\n}\n\nfn should_not_warn_custom_arc() {\n    #[derive(Clone)]\n    struct Arc;\n\n    impl Arc {\n        fn new() -> Self {\n            Arc\n        }\n    }\n\n    let v = vec![Arc::new(); 2];\n}\n\nfn should_not_warn_vec_from_elem_but_not_arc() {\n    let v = vec![String::new(); 2];\n    let v1 = vec![1; 2];\n    let v2 = vec![\n        Box::new(std::sync::Arc::new({\n            let y = 3;\n            dbg!(y);\n            y\n        }));\n        2\n    ];\n}\n\nfn should_not_warn_vec_macro_but_not_from_elem() {\n    let v = vec![Arc::new(\"x\".to_string())];\n}\n"
  },
  {
    "path": "tests/ui/rc_clone_in_vec_init/arc.stderr",
    "content": "error: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/arc.rs:9:13\n   |\nLL |     let v = vec![Arc::new(\"x\".to_string()); 2];\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Arc` instance\n   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::rc_clone_in_vec_init)]`\nhelp: consider initializing each `Arc` element individually\n   |\nLL ~     let v = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(Arc::new(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Arc` initialization to a variable\n   |\nLL ~     let v = {\nLL +         let data = Arc::new(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/arc.rs:18:21\n   |\nLL |             let v = vec![Arc::new(\"x\".to_string()); 2];\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Arc` instance\nhelp: consider initializing each `Arc` element individually\n   |\nLL ~             let v = {\nLL +                 let mut v = Vec::with_capacity(2);\nLL +                 (0..2).for_each(|_| v.push(Arc::new(..)));\nLL +                 v\nLL ~             };\n   |\nhelp: or if this is intentional, consider extracting the `Arc` initialization to a variable\n   |\nLL ~             let v = {\nLL +                 let data = Arc::new(..);\nLL +                 vec![data; 2]\nLL ~             };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/arc.rs:25:13\n   |\nLL |       let v = vec![\n   |  _____________^\n...  |\nLL | |         2\nLL | |     ];\n   | |_____^\n   |\n   = note: each element will point to the same `Arc` instance\nhelp: consider initializing each `Arc` element individually\n   |\nLL ~     let v = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(std::sync::Arc::new(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Arc` initialization to a variable\n   |\nLL ~     let v = {\nLL +         let data = std::sync::Arc::new(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/arc.rs:37:14\n   |\nLL |       let v1 = vec![\n   |  ______________^\n...  |\nLL | |         2\nLL | |     ];\n   | |_____^\n   |\n   = note: each element will point to the same `Arc` instance\nhelp: consider initializing each `Arc` element individually\n   |\nLL ~     let v1 = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(Arc::new(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Arc` initialization to a variable\n   |\nLL ~     let v1 = {\nLL +         let data = Arc::new(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/rc_clone_in_vec_init/rc.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![warn(clippy::rc_clone_in_vec_init)]\n#![allow(clippy::useless_vec)]\nuse std::rc::Rc;\nuse std::sync::Mutex;\n\nfn main() {}\n\nfn should_warn_simple_case() {\n    let v = vec![Rc::new(\"x\".to_string()); 2];\n    //~^ rc_clone_in_vec_init\n}\n\nfn should_warn_simple_case_with_big_indentation() {\n    if true {\n        let k = 1;\n        dbg!(k);\n        if true {\n            let v = vec![Rc::new(\"x\".to_string()); 2];\n            //~^ rc_clone_in_vec_init\n        }\n    }\n}\n\nfn should_warn_complex_case() {\n    let v = vec![\n    //~^ rc_clone_in_vec_init\n\n\n        std::rc::Rc::new(Mutex::new({\n            let x = 1;\n            dbg!(x);\n            x\n        }));\n        2\n    ];\n\n    let v1 = vec![\n    //~^ rc_clone_in_vec_init\n\n\n        Rc::new(Mutex::new({\n            let x = 1;\n            dbg!(x);\n            x\n        }));\n        2\n    ];\n}\n\nfn should_not_warn_custom_arc() {\n    #[derive(Clone)]\n    struct Rc;\n\n    impl Rc {\n        fn new() -> Self {\n            Rc\n        }\n    }\n\n    let v = vec![Rc::new(); 2];\n}\n\nfn should_not_warn_vec_from_elem_but_not_rc() {\n    let v = vec![String::new(); 2];\n    let v1 = vec![1; 2];\n    let v2 = vec![\n        Box::new(std::rc::Rc::new({\n            let y = 3;\n            dbg!(y);\n            y\n        }));\n        2\n    ];\n}\n\nfn should_not_warn_vec_macro_but_not_from_elem() {\n    let v = vec![Rc::new(\"x\".to_string())];\n}\n"
  },
  {
    "path": "tests/ui/rc_clone_in_vec_init/rc.stderr",
    "content": "error: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/rc.rs:10:13\n   |\nLL |     let v = vec![Rc::new(\"x\".to_string()); 2];\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Rc` instance\n   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::rc_clone_in_vec_init)]`\nhelp: consider initializing each `Rc` element individually\n   |\nLL ~     let v = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(Rc::new(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Rc` initialization to a variable\n   |\nLL ~     let v = {\nLL +         let data = Rc::new(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/rc.rs:19:21\n   |\nLL |             let v = vec![Rc::new(\"x\".to_string()); 2];\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Rc` instance\nhelp: consider initializing each `Rc` element individually\n   |\nLL ~             let v = {\nLL +                 let mut v = Vec::with_capacity(2);\nLL +                 (0..2).for_each(|_| v.push(Rc::new(..)));\nLL +                 v\nLL ~             };\n   |\nhelp: or if this is intentional, consider extracting the `Rc` initialization to a variable\n   |\nLL ~             let v = {\nLL +                 let data = Rc::new(..);\nLL +                 vec![data; 2]\nLL ~             };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/rc.rs:26:13\n   |\nLL |       let v = vec![\n   |  _____________^\n...  |\nLL | |         2\nLL | |     ];\n   | |_____^\n   |\n   = note: each element will point to the same `Rc` instance\nhelp: consider initializing each `Rc` element individually\n   |\nLL ~     let v = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(std::rc::Rc::new(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Rc` initialization to a variable\n   |\nLL ~     let v = {\nLL +         let data = std::rc::Rc::new(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/rc.rs:38:14\n   |\nLL |       let v1 = vec![\n   |  ______________^\n...  |\nLL | |         2\nLL | |     ];\n   | |_____^\n   |\n   = note: each element will point to the same `Rc` instance\nhelp: consider initializing each `Rc` element individually\n   |\nLL ~     let v1 = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(Rc::new(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Rc` initialization to a variable\n   |\nLL ~     let v1 = {\nLL +         let data = Rc::new(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/rc_clone_in_vec_init/weak.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![warn(clippy::rc_clone_in_vec_init)]\n#![allow(clippy::useless_vec)]\nuse std::rc::{Rc, Weak as UnSyncWeak};\nuse std::sync::{Arc, Mutex, Weak as SyncWeak};\n\nfn main() {}\n\nfn should_warn_simple_case() {\n    let v = vec![SyncWeak::<u32>::new(); 2];\n    //~^ rc_clone_in_vec_init\n\n    let v2 = vec![UnSyncWeak::<u32>::new(); 2];\n    //~^ rc_clone_in_vec_init\n\n    let v = vec![Rc::downgrade(&Rc::new(\"x\".to_string())); 2];\n    //~^ rc_clone_in_vec_init\n\n    let v = vec![Arc::downgrade(&Arc::new(\"x\".to_string())); 2];\n    //~^ rc_clone_in_vec_init\n}\n\nfn should_warn_simple_case_with_big_indentation() {\n    if true {\n        let k = 1;\n        dbg!(k);\n        if true {\n            let v = vec![Arc::downgrade(&Arc::new(\"x\".to_string())); 2];\n            //~^ rc_clone_in_vec_init\n\n            let v2 = vec![Rc::downgrade(&Rc::new(\"x\".to_string())); 2];\n            //~^ rc_clone_in_vec_init\n        }\n    }\n}\n\nfn should_warn_complex_case() {\n    let v = vec![\n    //~^ rc_clone_in_vec_init\n\n\n        Arc::downgrade(&Arc::new(Mutex::new({\n            let x = 1;\n            dbg!(x);\n            x\n        })));\n        2\n    ];\n\n    let v1 = vec![\n    //~^ rc_clone_in_vec_init\n\n\n        Rc::downgrade(&Rc::new(Mutex::new({\n            let x = 1;\n            dbg!(x);\n            x\n        })));\n        2\n    ];\n}\n\nfn should_not_warn_custom_weak() {\n    #[derive(Clone)]\n    struct Weak;\n\n    impl Weak {\n        fn new() -> Self {\n            Weak\n        }\n    }\n\n    let v = vec![Weak::new(); 2];\n}\n\nfn should_not_warn_vec_from_elem_but_not_weak() {\n    let v = vec![String::new(); 2];\n    let v1 = vec![1; 2];\n    let v2 = vec![\n        Box::new(Arc::downgrade(&Arc::new({\n            let y = 3;\n            dbg!(y);\n            y\n        })));\n        2\n    ];\n    let v3 = vec![\n        Box::new(Rc::downgrade(&Rc::new({\n            let y = 3;\n            dbg!(y);\n            y\n        })));\n        2\n    ];\n}\n\nfn should_not_warn_vec_macro_but_not_from_elem() {\n    let v = vec![Arc::downgrade(&Arc::new(\"x\".to_string()))];\n    let v = vec![Rc::downgrade(&Rc::new(\"x\".to_string()))];\n}\n"
  },
  {
    "path": "tests/ui/rc_clone_in_vec_init/weak.stderr",
    "content": "error: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/weak.rs:10:13\n   |\nLL |     let v = vec![SyncWeak::<u32>::new(); 2];\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Weak` instance\n   = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::rc_clone_in_vec_init)]`\nhelp: consider initializing each `Weak` element individually\n   |\nLL ~     let v = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(SyncWeak::<u32>::new(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Weak` initialization to a variable\n   |\nLL ~     let v = {\nLL +         let data = SyncWeak::<u32>::new(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/weak.rs:13:14\n   |\nLL |     let v2 = vec![UnSyncWeak::<u32>::new(); 2];\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Weak` instance\nhelp: consider initializing each `Weak` element individually\n   |\nLL ~     let v2 = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(UnSyncWeak::<u32>::new(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Weak` initialization to a variable\n   |\nLL ~     let v2 = {\nLL +         let data = UnSyncWeak::<u32>::new(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/weak.rs:16:13\n   |\nLL |     let v = vec![Rc::downgrade(&Rc::new(\"x\".to_string())); 2];\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Weak` instance\nhelp: consider initializing each `Weak` element individually\n   |\nLL ~     let v = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(Rc::downgrade(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Weak` initialization to a variable\n   |\nLL ~     let v = {\nLL +         let data = Rc::downgrade(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/weak.rs:19:13\n   |\nLL |     let v = vec![Arc::downgrade(&Arc::new(\"x\".to_string())); 2];\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Weak` instance\nhelp: consider initializing each `Weak` element individually\n   |\nLL ~     let v = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(Arc::downgrade(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Weak` initialization to a variable\n   |\nLL ~     let v = {\nLL +         let data = Arc::downgrade(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/weak.rs:28:21\n   |\nLL |             let v = vec![Arc::downgrade(&Arc::new(\"x\".to_string())); 2];\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Weak` instance\nhelp: consider initializing each `Weak` element individually\n   |\nLL ~             let v = {\nLL +                 let mut v = Vec::with_capacity(2);\nLL +                 (0..2).for_each(|_| v.push(Arc::downgrade(..)));\nLL +                 v\nLL ~             };\n   |\nhelp: or if this is intentional, consider extracting the `Weak` initialization to a variable\n   |\nLL ~             let v = {\nLL +                 let data = Arc::downgrade(..);\nLL +                 vec![data; 2]\nLL ~             };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/weak.rs:31:22\n   |\nLL |             let v2 = vec![Rc::downgrade(&Rc::new(\"x\".to_string())); 2];\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each element will point to the same `Weak` instance\nhelp: consider initializing each `Weak` element individually\n   |\nLL ~             let v2 = {\nLL +                 let mut v = Vec::with_capacity(2);\nLL +                 (0..2).for_each(|_| v.push(Rc::downgrade(..)));\nLL +                 v\nLL ~             };\n   |\nhelp: or if this is intentional, consider extracting the `Weak` initialization to a variable\n   |\nLL ~             let v2 = {\nLL +                 let data = Rc::downgrade(..);\nLL +                 vec![data; 2]\nLL ~             };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/weak.rs:38:13\n   |\nLL |       let v = vec![\n   |  _____________^\n...  |\nLL | |         2\nLL | |     ];\n   | |_____^\n   |\n   = note: each element will point to the same `Weak` instance\nhelp: consider initializing each `Weak` element individually\n   |\nLL ~     let v = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(Arc::downgrade(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Weak` initialization to a variable\n   |\nLL ~     let v = {\nLL +         let data = Arc::downgrade(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: initializing a reference-counted pointer in `vec![elem; len]`\n  --> tests/ui/rc_clone_in_vec_init/weak.rs:50:14\n   |\nLL |       let v1 = vec![\n   |  ______________^\n...  |\nLL | |         2\nLL | |     ];\n   | |_____^\n   |\n   = note: each element will point to the same `Weak` instance\nhelp: consider initializing each `Weak` element individually\n   |\nLL ~     let v1 = {\nLL +         let mut v = Vec::with_capacity(2);\nLL +         (0..2).for_each(|_| v.push(Rc::downgrade(..)));\nLL +         v\nLL ~     };\n   |\nhelp: or if this is intentional, consider extracting the `Weak` initialization to a variable\n   |\nLL ~     let v1 = {\nLL +         let data = Rc::downgrade(..);\nLL +         vec![data; 2]\nLL ~     };\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/rc_mutex.rs",
    "content": "#![warn(clippy::rc_mutex)]\n#![allow(unused, clippy::disallowed_names)]\n\nuse std::rc::Rc;\nuse std::sync::Mutex;\n\npub struct MyStructWithPrivItem {\n    foo: Rc<Mutex<i32>>,\n    //~^ rc_mutex\n}\n\npub struct MyStructWithPubItem {\n    pub foo: Rc<Mutex<i32>>,\n}\n\npub struct SubT<T> {\n    foo: T,\n}\n\npub enum MyEnum {\n    One,\n    Two,\n}\n\n// All of these test should be trigger the lint because they are not\n// part of the public api\nfn test1<T>(foo: Rc<Mutex<T>>) {}\n//~^ rc_mutex\n\nfn test2(foo: Rc<Mutex<MyEnum>>) {}\n//~^ rc_mutex\n\nfn test3(foo: Rc<Mutex<SubT<usize>>>) {}\n//~^ rc_mutex\n\n// All of these test should be allowed because they are part of the\n// public api and `avoid_breaking_exported_api` is `false` by default.\npub fn pub_test1<T>(foo: Rc<Mutex<T>>) {}\npub fn pub_test2(foo: Rc<Mutex<MyEnum>>) {}\npub fn pub_test3(foo: Rc<Mutex<SubT<usize>>>) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rc_mutex.stderr",
    "content": "error: usage of `Rc<Mutex<_>>`\n  --> tests/ui/rc_mutex.rs:8:10\n   |\nLL |     foo: Rc<Mutex<i32>>,\n   |          ^^^^^^^^^^^^^^\n   |\n   = help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead\n   = note: `-D clippy::rc-mutex` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::rc_mutex)]`\n\nerror: usage of `Rc<Mutex<_>>`\n  --> tests/ui/rc_mutex.rs:27:18\n   |\nLL | fn test1<T>(foo: Rc<Mutex<T>>) {}\n   |                  ^^^^^^^^^^^^\n   |\n   = help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead\n\nerror: usage of `Rc<Mutex<_>>`\n  --> tests/ui/rc_mutex.rs:30:15\n   |\nLL | fn test2(foo: Rc<Mutex<MyEnum>>) {}\n   |               ^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead\n\nerror: usage of `Rc<Mutex<_>>`\n  --> tests/ui/rc_mutex.rs:33:15\n   |\nLL | fn test3(foo: Rc<Mutex<SubT<usize>>>) {}\n   |               ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/read_line_without_trim.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::read_line_without_trim)]\n\nfn main() {\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    input.pop();\n    let _x: i32 = input.parse().unwrap(); // don't trigger here, newline character is popped\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x: i32 = input.trim_end().parse().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x = input.trim_end().parse::<i32>().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x = input.trim_end().parse::<u32>().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x = input.trim_end().parse::<f32>().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x = input.trim_end().parse::<bool>().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    // this is actually ok, so don't lint here\n    let _x = input.parse::<String>().unwrap();\n\n    // comparing with string literals\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    if input.trim_end() == \"foo\" {\n        //~^ read_line_without_trim\n        println!(\"This will never ever execute!\");\n    }\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    if input.trim_end().ends_with(\"foo\") {\n        //~^ read_line_without_trim\n        println!(\"Neither will this\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/read_line_without_trim.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::read_line_without_trim)]\n\nfn main() {\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    input.pop();\n    let _x: i32 = input.parse().unwrap(); // don't trigger here, newline character is popped\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x: i32 = input.parse().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x = input.parse::<i32>().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x = input.parse::<u32>().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x = input.parse::<f32>().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    let _x = input.parse::<bool>().unwrap();\n    //~^ read_line_without_trim\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    // this is actually ok, so don't lint here\n    let _x = input.parse::<String>().unwrap();\n\n    // comparing with string literals\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    if input == \"foo\" {\n        //~^ read_line_without_trim\n        println!(\"This will never ever execute!\");\n    }\n\n    let mut input = String::new();\n    std::io::stdin().read_line(&mut input).unwrap();\n    if input.ends_with(\"foo\") {\n        //~^ read_line_without_trim\n        println!(\"Neither will this\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/read_line_without_trim.stderr",
    "content": "error: calling `.parse()` on a string without trimming the trailing newline character\n  --> tests/ui/read_line_without_trim.rs:12:25\n   |\nLL |     let _x: i32 = input.parse().unwrap();\n   |                   ----- ^^^^^^^\n   |                   |\n   |                   help: try: `input.trim_end()`\n   |\nnote: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail\n  --> tests/ui/read_line_without_trim.rs:11:5\n   |\nLL |     std::io::stdin().read_line(&mut input).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::read-line-without-trim` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::read_line_without_trim)]`\n\nerror: calling `.parse()` on a string without trimming the trailing newline character\n  --> tests/ui/read_line_without_trim.rs:17:20\n   |\nLL |     let _x = input.parse::<i32>().unwrap();\n   |              ----- ^^^^^^^^^^^^^^\n   |              |\n   |              help: try: `input.trim_end()`\n   |\nnote: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail\n  --> tests/ui/read_line_without_trim.rs:16:5\n   |\nLL |     std::io::stdin().read_line(&mut input).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: calling `.parse()` on a string without trimming the trailing newline character\n  --> tests/ui/read_line_without_trim.rs:22:20\n   |\nLL |     let _x = input.parse::<u32>().unwrap();\n   |              ----- ^^^^^^^^^^^^^^\n   |              |\n   |              help: try: `input.trim_end()`\n   |\nnote: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail\n  --> tests/ui/read_line_without_trim.rs:21:5\n   |\nLL |     std::io::stdin().read_line(&mut input).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: calling `.parse()` on a string without trimming the trailing newline character\n  --> tests/ui/read_line_without_trim.rs:27:20\n   |\nLL |     let _x = input.parse::<f32>().unwrap();\n   |              ----- ^^^^^^^^^^^^^^\n   |              |\n   |              help: try: `input.trim_end()`\n   |\nnote: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail\n  --> tests/ui/read_line_without_trim.rs:26:5\n   |\nLL |     std::io::stdin().read_line(&mut input).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: calling `.parse()` on a string without trimming the trailing newline character\n  --> tests/ui/read_line_without_trim.rs:32:20\n   |\nLL |     let _x = input.parse::<bool>().unwrap();\n   |              ----- ^^^^^^^^^^^^^^^\n   |              |\n   |              help: try: `input.trim_end()`\n   |\nnote: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the checking to always fail\n  --> tests/ui/read_line_without_trim.rs:31:5\n   |\nLL |     std::io::stdin().read_line(&mut input).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: comparing a string literal without trimming the trailing newline character\n  --> tests/ui/read_line_without_trim.rs:43:8\n   |\nLL |     if input == \"foo\" {\n   |        -----^^^^^^^^^\n   |        |\n   |        help: try: `input.trim_end()`\n   |\nnote: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the comparison to always fail\n  --> tests/ui/read_line_without_trim.rs:42:5\n   |\nLL |     std::io::stdin().read_line(&mut input).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: checking the end of a string without trimming the trailing newline character\n  --> tests/ui/read_line_without_trim.rs:50:8\n   |\nLL |     if input.ends_with(\"foo\") {\n   |        -----^^^^^^^^^^^^^^^^^\n   |        |\n   |        help: try: `input.trim_end()`\n   |\nnote: call to `.read_line()` here, which leaves a trailing newline character in the buffer, which in turn will cause the parsing to always fail\n  --> tests/ui/read_line_without_trim.rs:49:5\n   |\nLL |     std::io::stdin().read_line(&mut input).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/read_zero_byte_vec.rs",
    "content": "#![warn(clippy::read_zero_byte_vec)]\n#![allow(\n    clippy::unused_io_amount,\n    clippy::needless_pass_by_ref_mut,\n    clippy::slow_vector_initialization\n)]\nuse std::fs::File;\nuse std::io;\nuse std::io::prelude::*;\n//@no-rustfix\n//@require-annotations-for-level: WARN\nextern crate futures;\nuse futures::io::{AsyncRead, AsyncReadExt};\nuse tokio::io::{AsyncRead as TokioAsyncRead, AsyncReadExt as _, AsyncWrite as TokioAsyncWrite, AsyncWriteExt as _};\n\nfn test() -> io::Result<()> {\n    let cap = 1000;\n    let mut f = File::open(\"foo.txt\").unwrap();\n\n    // should lint\n    let mut data = Vec::with_capacity(20);\n    f.read_exact(&mut data).unwrap();\n    //~^ ERROR: reading zero byte data to `Vec`\n    //~| NOTE: `-D clippy::read-zero-byte-vec` implied by `-D warnings`\n\n    // should lint\n    let mut data2 = Vec::with_capacity(cap);\n    f.read_exact(&mut data2)?;\n    //~^ ERROR: reading zero byte data to `Vec`\n\n    // should lint\n    let mut data3 = Vec::new();\n    f.read_exact(&mut data3)?;\n    //~^ ERROR: reading zero byte data to `Vec`\n\n    // should lint\n    let mut data4 = vec![];\n    let _ = f.read(&mut data4)?;\n    //~^ ERROR: reading zero byte data to `Vec`\n\n    // should lint\n    let _ = {\n        let mut data5 = Vec::new();\n        f.read(&mut data5)\n        //~^ ERROR: reading zero byte data to `Vec`\n    };\n\n    // should lint\n    let _ = {\n        let mut data6: Vec<u8> = Default::default();\n        f.read(&mut data6)\n        //~^ ERROR: reading zero byte data to `Vec`\n    };\n\n    // should not lint\n    let mut buf = [0u8; 100];\n    f.read(&mut buf)?;\n\n    // should not lint\n    let mut data8 = Vec::new();\n    data8.resize(100, 0);\n    f.read_exact(&mut data8)?;\n\n    // should not lint\n    let mut data9 = vec![1, 2, 3];\n    f.read_exact(&mut data9)?;\n\n    Ok(())\n}\n\nfn test_nested() -> io::Result<()> {\n    let cap = 1000;\n    let mut f = File::open(\"foo.txt\").unwrap();\n\n    // Issue #9274\n    // Should not lint\n    let mut v = Vec::new();\n    {\n        v.resize(10, 0);\n        f.read(&mut v)?;\n    }\n\n    let mut v = Vec::new();\n    {\n        f.read(&mut v)?;\n        //~^ ERROR: reading zero byte data to `Vec`\n    }\n\n    Ok(())\n}\n\nasync fn test_futures<R: AsyncRead + Unpin>(r: &mut R) {\n    // should lint\n    let mut data = Vec::new();\n    r.read(&mut data).await.unwrap();\n    //~^ ERROR: reading zero byte data to `Vec`\n\n    // should lint\n    let mut data2 = Vec::new();\n    r.read_exact(&mut data2).await.unwrap();\n    //~^ ERROR: reading zero byte data to `Vec`\n}\n\nasync fn test_tokio<R: TokioAsyncRead + Unpin>(r: &mut R) {\n    // should lint\n    let mut data = Vec::new();\n    r.read(&mut data).await.unwrap();\n    //~^ ERROR: reading zero byte data to `Vec`\n\n    // should lint\n    let mut data2 = Vec::new();\n    r.read_exact(&mut data2).await.unwrap();\n    //~^ ERROR: reading zero byte data to `Vec`\n}\n\nfn allow_works<F: std::io::Read>(mut f: F) {\n    let mut data = Vec::with_capacity(100);\n    #[allow(clippy::read_zero_byte_vec)]\n    f.read(&mut data).unwrap();\n}\n\nfn main() {}\n\nfn issue15575() -> usize {\n    use std::io::Read;\n    use std::net::TcpListener;\n\n    let listener = TcpListener::bind(\"127.0.0.1:9010\").unwrap();\n    let mut stream_and_addr = listener.accept().unwrap();\n    let mut buf = Vec::with_capacity(32);\n    let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();\n    //~^ read_zero_byte_vec\n\n    let cap = 1000;\n    let mut buf = Vec::with_capacity(cap);\n    let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();\n    //~^ read_zero_byte_vec\n\n    let cap = 1000;\n    let mut buf = Vec::with_capacity(cap);\n    let num_bytes_received = { stream_and_addr.0.read(&mut buf) }.unwrap();\n    //~^ read_zero_byte_vec\n\n    use std::fs::File;\n    let mut f = File::open(\"foo.txt\").unwrap();\n    let mut data = Vec::with_capacity(100);\n    f.read(&mut data).unwrap()\n    //~^ read_zero_byte_vec\n}\n"
  },
  {
    "path": "tests/ui/read_zero_byte_vec.stderr",
    "content": "error: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:22:5\n   |\nLL |     f.read_exact(&mut data).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::read-zero-byte-vec` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::read_zero_byte_vec)]`\nhelp: try\n   |\nLL ~     data.resize(20, 0);\nLL ~     f.read_exact(&mut data).unwrap();\n   |\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:28:5\n   |\nLL |     f.read_exact(&mut data2)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~     data2.resize(cap, 0);\nLL ~     f.read_exact(&mut data2)?;\n   |\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:33:5\n   |\nLL |     f.read_exact(&mut data3)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:38:13\n   |\nLL |     let _ = f.read(&mut data4)?;\n   |             ^^^^^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:44:9\n   |\nLL |         f.read(&mut data5)\n   |         ^^^^^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:51:9\n   |\nLL |         f.read(&mut data6)\n   |         ^^^^^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:85:9\n   |\nLL |         f.read(&mut v)?;\n   |         ^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:95:5\n   |\nLL |     r.read(&mut data).await.unwrap();\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:100:5\n   |\nLL |     r.read_exact(&mut data2).await.unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:107:5\n   |\nLL |     r.read(&mut data).await.unwrap();\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:112:5\n   |\nLL |     r.read_exact(&mut data2).await.unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:131:30\n   |\nLL |     let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~     buf.resize(32, 0);\nLL ~     let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();\n   |\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:136:30\n   |\nLL |     let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~     buf.resize(cap, 0);\nLL ~     let num_bytes_received = stream_and_addr.0.read(&mut buf).unwrap();\n   |\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:141:32\n   |\nLL |     let num_bytes_received = { stream_and_addr.0.read(&mut buf) }.unwrap();\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~     buf.resize(cap, 0);\nLL ~     let num_bytes_received = { stream_and_addr.0.read(&mut buf) }.unwrap();\n   |\n\nerror: reading zero byte data to `Vec`\n  --> tests/ui/read_zero_byte_vec.rs:147:5\n   |\nLL |     f.read(&mut data).unwrap()\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~     data.resize(100, 0);\nLL ~     f.read(&mut data).unwrap()\n   |\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/readonly_write_lock.fixed",
    "content": "#![warn(clippy::readonly_write_lock)]\n\nuse std::sync::RwLock;\n\nfn mutate_i32(x: &mut i32) {\n    *x += 1;\n}\n\nfn accept_i32(_: i32) {}\n\nfn main() {\n    let lock = RwLock::new(42);\n    let lock2 = RwLock::new(1234);\n\n    {\n        let writer = lock.read().unwrap();\n        //~^ readonly_write_lock\n\n        dbg!(&writer);\n    }\n\n    {\n        let writer = lock.read().unwrap();\n        //~^ readonly_write_lock\n\n        accept_i32(*writer);\n    }\n\n    {\n        let mut writer = lock.write().unwrap();\n        mutate_i32(&mut writer);\n        dbg!(&writer);\n    }\n\n    {\n        let mut writer = lock.write().unwrap();\n        *writer += 1;\n    }\n\n    {\n        let mut writer1 = lock.write().unwrap();\n        let mut writer2 = lock2.write().unwrap();\n        *writer2 += 1;\n        *writer1 = *writer2;\n    }\n}\n\nfn issue12733(rw: &RwLock<()>) {\n    let _write_guard = rw.write().unwrap();\n}\n"
  },
  {
    "path": "tests/ui/readonly_write_lock.rs",
    "content": "#![warn(clippy::readonly_write_lock)]\n\nuse std::sync::RwLock;\n\nfn mutate_i32(x: &mut i32) {\n    *x += 1;\n}\n\nfn accept_i32(_: i32) {}\n\nfn main() {\n    let lock = RwLock::new(42);\n    let lock2 = RwLock::new(1234);\n\n    {\n        let writer = lock.write().unwrap();\n        //~^ readonly_write_lock\n\n        dbg!(&writer);\n    }\n\n    {\n        let writer = lock.write().unwrap();\n        //~^ readonly_write_lock\n\n        accept_i32(*writer);\n    }\n\n    {\n        let mut writer = lock.write().unwrap();\n        mutate_i32(&mut writer);\n        dbg!(&writer);\n    }\n\n    {\n        let mut writer = lock.write().unwrap();\n        *writer += 1;\n    }\n\n    {\n        let mut writer1 = lock.write().unwrap();\n        let mut writer2 = lock2.write().unwrap();\n        *writer2 += 1;\n        *writer1 = *writer2;\n    }\n}\n\nfn issue12733(rw: &RwLock<()>) {\n    let _write_guard = rw.write().unwrap();\n}\n"
  },
  {
    "path": "tests/ui/readonly_write_lock.stderr",
    "content": "error: this write lock is used only for reading\n  --> tests/ui/readonly_write_lock.rs:16:22\n   |\nLL |         let writer = lock.write().unwrap();\n   |                      ^^^^^^^^^^^^ help: consider using a read lock instead: `lock.read()`\n   |\n   = note: `-D clippy::readonly-write-lock` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::readonly_write_lock)]`\n\nerror: this write lock is used only for reading\n  --> tests/ui/readonly_write_lock.rs:23:22\n   |\nLL |         let writer = lock.write().unwrap();\n   |                      ^^^^^^^^^^^^ help: consider using a read lock instead: `lock.read()`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/recursive_format_impl.rs",
    "content": "#![warn(clippy::recursive_format_impl)]\n#![allow(\n    clippy::borrow_deref_ref,\n    clippy::deref_addrof,\n    clippy::inherent_to_string_shadow_display,\n    clippy::to_string_in_format_args,\n    clippy::uninlined_format_args\n)]\n\nuse std::fmt;\n\nstruct A;\nimpl A {\n    fn fmt(&self) {\n        self.to_string();\n    }\n}\n\ntrait B {\n    fn fmt(&self) {}\n}\n\nimpl B for A {\n    fn fmt(&self) {\n        self.to_string();\n    }\n}\n\nimpl fmt::Display for A {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"{}\", self.to_string())\n        //~^ recursive_format_impl\n    }\n}\n\nfn fmt(a: A) {\n    a.to_string();\n}\n\nstruct C;\n\nimpl C {\n    // Doesn't trigger if to_string defined separately\n    // i.e. not using ToString trait (from Display)\n    fn to_string(&self) -> String {\n        String::from(\"I am C\")\n    }\n}\n\nimpl fmt::Display for C {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"{}\", self.to_string())\n    }\n}\n\nenum D {\n    E(String),\n    F,\n}\n\nimpl std::fmt::Display for D {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match &self {\n            Self::E(string) => write!(f, \"E {}\", string.to_string()),\n            Self::F => write!(f, \"F\"),\n        }\n    }\n}\n\n// Check for use of self as Display, in Display impl\n// Triggers on direct use of self\nstruct G;\n\nimpl std::fmt::Display for G {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self)\n        //~^ recursive_format_impl\n    }\n}\n\n// Triggers on reference to self\nstruct H;\n\nimpl std::fmt::Display for H {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", &self)\n        //~^ recursive_format_impl\n    }\n}\n\nimpl std::fmt::Debug for H {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{:?}\", &self)\n        //~^ recursive_format_impl\n    }\n}\n\n// Triggers on multiple reference to self\nstruct H2;\n\nimpl std::fmt::Display for H2 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", &&&self)\n        //~^ recursive_format_impl\n    }\n}\n\n// Doesn't trigger on correct deref\nstruct I;\n\nimpl std::ops::Deref for I {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"test\"\n    }\n}\n\nimpl std::fmt::Display for I {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{}\", &**self)\n    }\n}\n\nimpl std::fmt::Debug for I {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{:?}\", &**self)\n    }\n}\n\n// Doesn't trigger on multiple correct deref\nstruct I2;\n\nimpl std::ops::Deref for I2 {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"test\"\n    }\n}\n\nimpl std::fmt::Display for I2 {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{}\", **&&&**self)\n    }\n}\n\n// Doesn't trigger on multiple correct deref\nstruct I3;\n\nimpl std::ops::Deref for I3 {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"test\"\n    }\n}\n\nimpl std::fmt::Display for I3 {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{}\", &&**&&&**self)\n    }\n}\n\n// Does trigger when deref resolves to self\nstruct J;\n\nimpl std::ops::Deref for J {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"test\"\n    }\n}\n\nimpl std::fmt::Display for J {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{}\", &*self)\n        //~^ recursive_format_impl\n    }\n}\n\nimpl std::fmt::Debug for J {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{:?}\", &*self)\n        //~^ recursive_format_impl\n    }\n}\n\nstruct J2;\n\nimpl std::ops::Deref for J2 {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"test\"\n    }\n}\n\nimpl std::fmt::Display for J2 {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{}\", *self)\n        //~^ recursive_format_impl\n    }\n}\n\nstruct J3;\n\nimpl std::ops::Deref for J3 {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"test\"\n    }\n}\n\nimpl std::fmt::Display for J3 {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{}\", **&&*self)\n        //~^ recursive_format_impl\n    }\n}\n\nstruct J4;\n\nimpl std::ops::Deref for J4 {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        \"test\"\n    }\n}\n\nimpl std::fmt::Display for J4 {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{}\", &&**&&*self)\n        //~^ recursive_format_impl\n    }\n}\n\n// Doesn't trigger on Debug from Display\nstruct K;\n\nimpl std::fmt::Debug for K {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"test\")\n    }\n}\n\nimpl std::fmt::Display for K {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{:?}\", self)\n    }\n}\n\n// Doesn't trigger on Display from Debug\nstruct K2;\n\nimpl std::fmt::Debug for K2 {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{}\", self)\n    }\n}\n\nimpl std::fmt::Display for K2 {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"test\")\n    }\n}\n\n// Doesn't trigger on struct fields\nstruct L {\n    field1: u32,\n    field2: i32,\n}\n\nimpl std::fmt::Display for L {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{},{}\", self.field1, self.field2)\n    }\n}\n\nimpl std::fmt::Debug for L {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{:?},{:?}\", self.field1, self.field2)\n    }\n}\n\n// Doesn't trigger on nested enum matching\nenum Tree {\n    Leaf,\n    Node(Vec<Tree>),\n}\n\nimpl std::fmt::Display for Tree {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match self {\n            Tree::Leaf => write!(f, \"*\"),\n            Tree::Node(children) => {\n                write!(f, \"(\")?;\n                for child in children.iter() {\n                    write!(f, \"{},\", child)?;\n                }\n                write!(f, \")\")\n            },\n        }\n    }\n}\n\nimpl std::fmt::Debug for Tree {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match self {\n            Tree::Leaf => write!(f, \"*\"),\n            Tree::Node(children) => {\n                write!(f, \"(\")?;\n                for child in children.iter() {\n                    write!(f, \"{:?},\", child)?;\n                }\n                write!(f, \")\")\n            },\n        }\n    }\n}\n\nfn main() {\n    let a = A;\n    a.to_string();\n    a.fmt();\n    fmt(a);\n\n    let c = C;\n    c.to_string();\n}\n"
  },
  {
    "path": "tests/ui/recursive_format_impl.stderr",
    "content": "error: using `self.to_string` in `fmt::Display` implementation will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:31:25\n   |\nLL |         write!(f, \"{}\", self.to_string())\n   |                         ^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::recursive-format-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::recursive_format_impl)]`\n\nerror: using `self` as `Display` in `impl Display` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:76:9\n   |\nLL |         write!(f, \"{}\", self)\n   |         ^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `self` as `Display` in `impl Display` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:86:9\n   |\nLL |         write!(f, \"{}\", &self)\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `self` as `Debug` in `impl Debug` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:93:9\n   |\nLL |         write!(f, \"{:?}\", &self)\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `self` as `Display` in `impl Display` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:103:9\n   |\nLL |         write!(f, \"{}\", &&&self)\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `self` as `Display` in `impl Display` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:178:9\n   |\nLL |         write!(f, \"{}\", &*self)\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `self` as `Debug` in `impl Debug` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:185:9\n   |\nLL |         write!(f, \"{:?}\", &*self)\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `self` as `Display` in `impl Display` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:202:9\n   |\nLL |         write!(f, \"{}\", *self)\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `self` as `Display` in `impl Display` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:219:9\n   |\nLL |         write!(f, \"{}\", **&&*self)\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: using `self` as `Display` in `impl Display` will cause infinite recursion\n  --> tests/ui/recursive_format_impl.rs:236:9\n   |\nLL |         write!(f, \"{}\", &&**&&*self)\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_allocation.rs",
    "content": "#![allow(clippy::boxed_local, clippy::disallowed_names)]\n\npub struct MyStruct;\n\npub struct SubT<T> {\n    foo: T,\n}\n\nmod outer_box {\n    use crate::{MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn box_test6<T>(foo: Box<Rc<T>>) {}\n    //~^ redundant_allocation\n\n    pub fn box_test7<T>(foo: Box<Arc<T>>) {}\n    //~^ redundant_allocation\n\n    pub fn box_test8() -> Box<Rc<SubT<usize>>> {\n        //~^ redundant_allocation\n\n        unimplemented!();\n    }\n\n    pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {\n        //~^ redundant_allocation\n        //~| redundant_allocation\n\n        unimplemented!();\n    }\n}\n\nmod outer_rc {\n    use crate::{MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn rc_test5(a: Rc<Box<bool>>) {}\n    //~^ redundant_allocation\n\n    pub fn rc_test7(a: Rc<Arc<bool>>) {}\n    //~^ redundant_allocation\n\n    pub fn rc_test8() -> Rc<Box<SubT<usize>>> {\n        //~^ redundant_allocation\n\n        unimplemented!();\n    }\n\n    pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {\n        //~^ redundant_allocation\n        //~| redundant_allocation\n\n        unimplemented!();\n    }\n}\n\nmod outer_arc {\n    use crate::{MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn arc_test5(a: Arc<Box<bool>>) {}\n    //~^ redundant_allocation\n\n    pub fn arc_test6(a: Arc<Rc<bool>>) {}\n    //~^ redundant_allocation\n\n    pub fn arc_test8() -> Arc<Box<SubT<usize>>> {\n        //~^ redundant_allocation\n\n        unimplemented!();\n    }\n\n    pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {\n        //~^ redundant_allocation\n        //~| redundant_allocation\n\n        unimplemented!();\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7487\nmod box_dyn {\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub trait T {}\n\n    struct S {\n        a: Box<Box<dyn T>>,\n        b: Rc<Box<dyn T>>,\n        c: Arc<Box<dyn T>>,\n    }\n\n    pub fn test_box(_: Box<Box<dyn T>>) {}\n    pub fn test_rc(_: Rc<Box<dyn T>>) {}\n    pub fn test_arc(_: Arc<Box<dyn T>>) {}\n    pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {}\n    //~^ redundant_allocation\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/8604\nmod box_fat_ptr {\n    use std::boxed::Box;\n    use std::path::Path;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub struct DynSized {\n        foo: [usize],\n    }\n\n    struct S {\n        a: Box<Box<str>>,\n        b: Rc<Box<str>>,\n        c: Arc<Box<str>>,\n\n        e: Box<Box<[usize]>>,\n        f: Box<Box<Path>>,\n        g: Box<Box<DynSized>>,\n    }\n\n    pub fn test_box_str(_: Box<Box<str>>) {}\n    pub fn test_rc_str(_: Rc<Box<str>>) {}\n    pub fn test_arc_str(_: Arc<Box<str>>) {}\n\n    pub fn test_box_slice(_: Box<Box<[usize]>>) {}\n    pub fn test_box_path(_: Box<Box<Path>>) {}\n    pub fn test_box_custom(_: Box<Box<DynSized>>) {}\n\n    pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {}\n    //~^ redundant_allocation\n\n    pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {}\n    //~^ redundant_allocation\n\n    pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {}\n    //~^ redundant_allocation\n\n    pub fn test_rc_box_custom(_: Rc<Box<Box<DynSized>>>) {}\n    //~^ redundant_allocation\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/11417\nfn type_in_closure() {\n    let _ = |_: &mut Box<Box<dyn ToString>>| {};\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/redundant_allocation.stderr",
    "content": "error: usage of `Box<Rc<T>>`\n  --> tests/ui/redundant_allocation.rs:15:30\n   |\nLL |     pub fn box_test6<T>(foo: Box<Rc<T>>) {}\n   |                              ^^^^^^^^^^\n   |\n   = note: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation\n   = help: consider using just `Box<T>` or `Rc<T>`\n   = note: `-D clippy::redundant-allocation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_allocation)]`\n\nerror: usage of `Box<Arc<T>>`\n  --> tests/ui/redundant_allocation.rs:18:30\n   |\nLL |     pub fn box_test7<T>(foo: Box<Arc<T>>) {}\n   |                              ^^^^^^^^^^^\n   |\n   = note: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation\n   = help: consider using just `Box<T>` or `Arc<T>`\n\nerror: usage of `Box<Rc<SubT<usize>>>`\n  --> tests/ui/redundant_allocation.rs:21:27\n   |\nLL |     pub fn box_test8() -> Box<Rc<SubT<usize>>> {\n   |                           ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Rc<SubT<usize>>` is already on the heap, `Box<Rc<SubT<usize>>>` makes an extra allocation\n   = help: consider using just `Box<SubT<usize>>` or `Rc<SubT<usize>>`\n\nerror: usage of `Box<Arc<T>>`\n  --> tests/ui/redundant_allocation.rs:27:30\n   |\nLL |     pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {\n   |                              ^^^^^^^^^^^\n   |\n   = note: `Arc<T>` is already on the heap, `Box<Arc<T>>` makes an extra allocation\n   = help: consider using just `Box<T>` or `Arc<T>`\n\nerror: usage of `Box<Arc<SubT<T>>>`\n  --> tests/ui/redundant_allocation.rs:27:46\n   |\nLL |     pub fn box_test9<T>(foo: Box<Arc<T>>) -> Box<Arc<SubT<T>>> {\n   |                                              ^^^^^^^^^^^^^^^^^\n   |\n   = note: `Arc<SubT<T>>` is already on the heap, `Box<Arc<SubT<T>>>` makes an extra allocation\n   = help: consider using just `Box<SubT<T>>` or `Arc<SubT<T>>`\n\nerror: usage of `Rc<Box<bool>>`\n  --> tests/ui/redundant_allocation.rs:41:24\n   |\nLL |     pub fn rc_test5(a: Rc<Box<bool>>) {}\n   |                        ^^^^^^^^^^^^^\n   |\n   = note: `Box<bool>` is already on the heap, `Rc<Box<bool>>` makes an extra allocation\n   = help: consider using just `Rc<bool>` or `Box<bool>`\n\nerror: usage of `Rc<Arc<bool>>`\n  --> tests/ui/redundant_allocation.rs:44:24\n   |\nLL |     pub fn rc_test7(a: Rc<Arc<bool>>) {}\n   |                        ^^^^^^^^^^^^^\n   |\n   = note: `Arc<bool>` is already on the heap, `Rc<Arc<bool>>` makes an extra allocation\n   = help: consider using just `Rc<bool>` or `Arc<bool>`\n\nerror: usage of `Rc<Box<SubT<usize>>>`\n  --> tests/ui/redundant_allocation.rs:47:26\n   |\nLL |     pub fn rc_test8() -> Rc<Box<SubT<usize>>> {\n   |                          ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Box<SubT<usize>>` is already on the heap, `Rc<Box<SubT<usize>>>` makes an extra allocation\n   = help: consider using just `Rc<SubT<usize>>` or `Box<SubT<usize>>`\n\nerror: usage of `Rc<Arc<T>>`\n  --> tests/ui/redundant_allocation.rs:53:29\n   |\nLL |     pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {\n   |                             ^^^^^^^^^^\n   |\n   = note: `Arc<T>` is already on the heap, `Rc<Arc<T>>` makes an extra allocation\n   = help: consider using just `Rc<T>` or `Arc<T>`\n\nerror: usage of `Rc<Arc<SubT<T>>>`\n  --> tests/ui/redundant_allocation.rs:53:44\n   |\nLL |     pub fn rc_test9<T>(foo: Rc<Arc<T>>) -> Rc<Arc<SubT<T>>> {\n   |                                            ^^^^^^^^^^^^^^^^\n   |\n   = note: `Arc<SubT<T>>` is already on the heap, `Rc<Arc<SubT<T>>>` makes an extra allocation\n   = help: consider using just `Rc<SubT<T>>` or `Arc<SubT<T>>`\n\nerror: usage of `Arc<Box<bool>>`\n  --> tests/ui/redundant_allocation.rs:67:25\n   |\nLL |     pub fn arc_test5(a: Arc<Box<bool>>) {}\n   |                         ^^^^^^^^^^^^^^\n   |\n   = note: `Box<bool>` is already on the heap, `Arc<Box<bool>>` makes an extra allocation\n   = help: consider using just `Arc<bool>` or `Box<bool>`\n\nerror: usage of `Arc<Rc<bool>>`\n  --> tests/ui/redundant_allocation.rs:70:25\n   |\nLL |     pub fn arc_test6(a: Arc<Rc<bool>>) {}\n   |                         ^^^^^^^^^^^^^\n   |\n   = note: `Rc<bool>` is already on the heap, `Arc<Rc<bool>>` makes an extra allocation\n   = help: consider using just `Arc<bool>` or `Rc<bool>`\n\nerror: usage of `Arc<Box<SubT<usize>>>`\n  --> tests/ui/redundant_allocation.rs:73:27\n   |\nLL |     pub fn arc_test8() -> Arc<Box<SubT<usize>>> {\n   |                           ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Box<SubT<usize>>` is already on the heap, `Arc<Box<SubT<usize>>>` makes an extra allocation\n   = help: consider using just `Arc<SubT<usize>>` or `Box<SubT<usize>>`\n\nerror: usage of `Arc<Rc<T>>`\n  --> tests/ui/redundant_allocation.rs:79:30\n   |\nLL |     pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {\n   |                              ^^^^^^^^^^\n   |\n   = note: `Rc<T>` is already on the heap, `Arc<Rc<T>>` makes an extra allocation\n   = help: consider using just `Arc<T>` or `Rc<T>`\n\nerror: usage of `Arc<Rc<SubT<T>>>`\n  --> tests/ui/redundant_allocation.rs:79:45\n   |\nLL |     pub fn arc_test9<T>(foo: Arc<Rc<T>>) -> Arc<Rc<SubT<T>>> {\n   |                                             ^^^^^^^^^^^^^^^^\n   |\n   = note: `Rc<SubT<T>>` is already on the heap, `Arc<Rc<SubT<T>>>` makes an extra allocation\n   = help: consider using just `Arc<SubT<T>>` or `Rc<SubT<T>>`\n\nerror: usage of `Rc<Box<Box<dyn T>>>`\n  --> tests/ui/redundant_allocation.rs:104:27\n   |\nLL |     pub fn test_rc_box(_: Rc<Box<Box<dyn T>>>) {}\n   |                           ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Box<Box<dyn T>>` is already on the heap, `Rc<Box<Box<dyn T>>>` makes an extra allocation\n   = help: consider using just `Rc<Box<dyn T>>` or `Box<Box<dyn T>>`\n\nerror: usage of `Rc<Box<Box<str>>>`\n  --> tests/ui/redundant_allocation.rs:137:31\n   |\nLL |     pub fn test_rc_box_str(_: Rc<Box<Box<str>>>) {}\n   |                               ^^^^^^^^^^^^^^^^^\n   |\n   = note: `Box<Box<str>>` is already on the heap, `Rc<Box<Box<str>>>` makes an extra allocation\n   = help: consider using just `Rc<Box<str>>` or `Box<Box<str>>`\n\nerror: usage of `Rc<Box<Box<[usize]>>>`\n  --> tests/ui/redundant_allocation.rs:140:33\n   |\nLL |     pub fn test_rc_box_slice(_: Rc<Box<Box<[usize]>>>) {}\n   |                                 ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Box<Box<[usize]>>` is already on the heap, `Rc<Box<Box<[usize]>>>` makes an extra allocation\n   = help: consider using just `Rc<Box<[usize]>>` or `Box<Box<[usize]>>`\n\nerror: usage of `Rc<Box<Box<Path>>>`\n  --> tests/ui/redundant_allocation.rs:143:32\n   |\nLL |     pub fn test_rc_box_path(_: Rc<Box<Box<Path>>>) {}\n   |                                ^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Box<Box<Path>>` is already on the heap, `Rc<Box<Box<Path>>>` makes an extra allocation\n   = help: consider using just `Rc<Box<Path>>` or `Box<Box<Path>>`\n\nerror: usage of `Rc<Box<Box<DynSized>>>`\n  --> tests/ui/redundant_allocation.rs:146:34\n   |\nLL |     pub fn test_rc_box_custom(_: Rc<Box<Box<DynSized>>>) {}\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `Box<Box<DynSized>>` is already on the heap, `Rc<Box<Box<DynSized>>>` makes an extra allocation\n   = help: consider using just `Rc<Box<DynSized>>` or `Box<Box<DynSized>>`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_allocation_fixable.fixed",
    "content": "#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]\n#![allow(clippy::disallowed_names)]\n\npub struct MyStruct;\n\npub struct SubT<T> {\n    foo: T,\n}\n\npub enum MyEnum {\n    One,\n    Two,\n}\n\nmod outer_box {\n    use crate::{MyEnum, MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn box_test1<T>(foo: &T) {}\n    //~^ redundant_allocation\n\n    pub fn box_test2(foo: &MyStruct) {}\n    //~^ redundant_allocation\n\n    pub fn box_test3(foo: &MyEnum) {}\n    //~^ redundant_allocation\n\n    pub fn box_test4_neg(foo: Box<SubT<&usize>>) {}\n\n    pub fn box_test5<T>(foo: Box<T>) {}\n    //~^ redundant_allocation\n}\n\nmod outer_rc {\n    use crate::{MyEnum, MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn rc_test1<T>(foo: &T) {}\n    //~^ redundant_allocation\n\n    pub fn rc_test2(foo: &MyStruct) {}\n    //~^ redundant_allocation\n\n    pub fn rc_test3(foo: &MyEnum) {}\n    //~^ redundant_allocation\n\n    pub fn rc_test4_neg(foo: Rc<SubT<&usize>>) {}\n\n    pub fn rc_test6(a: Rc<bool>) {}\n    //~^ redundant_allocation\n}\n\nmod outer_arc {\n    use crate::{MyEnum, MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn arc_test1<T>(foo: &T) {}\n    //~^ redundant_allocation\n\n    pub fn arc_test2(foo: &MyStruct) {}\n    //~^ redundant_allocation\n\n    pub fn arc_test3(foo: &MyEnum) {}\n    //~^ redundant_allocation\n\n    pub fn arc_test4_neg(foo: Arc<SubT<&usize>>) {}\n\n    pub fn arc_test7(a: Arc<bool>) {}\n    //~^ redundant_allocation\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/redundant_allocation_fixable.rs",
    "content": "#![allow(clippy::boxed_local, clippy::needless_pass_by_value)]\n#![allow(clippy::disallowed_names)]\n\npub struct MyStruct;\n\npub struct SubT<T> {\n    foo: T,\n}\n\npub enum MyEnum {\n    One,\n    Two,\n}\n\nmod outer_box {\n    use crate::{MyEnum, MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn box_test1<T>(foo: Box<&T>) {}\n    //~^ redundant_allocation\n\n    pub fn box_test2(foo: Box<&MyStruct>) {}\n    //~^ redundant_allocation\n\n    pub fn box_test3(foo: Box<&MyEnum>) {}\n    //~^ redundant_allocation\n\n    pub fn box_test4_neg(foo: Box<SubT<&usize>>) {}\n\n    pub fn box_test5<T>(foo: Box<Box<T>>) {}\n    //~^ redundant_allocation\n}\n\nmod outer_rc {\n    use crate::{MyEnum, MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn rc_test1<T>(foo: Rc<&T>) {}\n    //~^ redundant_allocation\n\n    pub fn rc_test2(foo: Rc<&MyStruct>) {}\n    //~^ redundant_allocation\n\n    pub fn rc_test3(foo: Rc<&MyEnum>) {}\n    //~^ redundant_allocation\n\n    pub fn rc_test4_neg(foo: Rc<SubT<&usize>>) {}\n\n    pub fn rc_test6(a: Rc<Rc<bool>>) {}\n    //~^ redundant_allocation\n}\n\nmod outer_arc {\n    use crate::{MyEnum, MyStruct, SubT};\n    use std::boxed::Box;\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    pub fn arc_test1<T>(foo: Arc<&T>) {}\n    //~^ redundant_allocation\n\n    pub fn arc_test2(foo: Arc<&MyStruct>) {}\n    //~^ redundant_allocation\n\n    pub fn arc_test3(foo: Arc<&MyEnum>) {}\n    //~^ redundant_allocation\n\n    pub fn arc_test4_neg(foo: Arc<SubT<&usize>>) {}\n\n    pub fn arc_test7(a: Arc<Arc<bool>>) {}\n    //~^ redundant_allocation\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/redundant_allocation_fixable.stderr",
    "content": "error: usage of `Box<&T>`\n  --> tests/ui/redundant_allocation_fixable.rs:21:30\n   |\nLL |     pub fn box_test1<T>(foo: Box<&T>) {}\n   |                              ^^^^^^^ help: try: `&T`\n   |\n   = note: `&T` is already a pointer, `Box<&T>` allocates a pointer on the heap\n   = note: `-D clippy::redundant-allocation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_allocation)]`\n\nerror: usage of `Box<&MyStruct>`\n  --> tests/ui/redundant_allocation_fixable.rs:24:27\n   |\nLL |     pub fn box_test2(foo: Box<&MyStruct>) {}\n   |                           ^^^^^^^^^^^^^^ help: try: `&MyStruct`\n   |\n   = note: `&MyStruct` is already a pointer, `Box<&MyStruct>` allocates a pointer on the heap\n\nerror: usage of `Box<&MyEnum>`\n  --> tests/ui/redundant_allocation_fixable.rs:27:27\n   |\nLL |     pub fn box_test3(foo: Box<&MyEnum>) {}\n   |                           ^^^^^^^^^^^^ help: try: `&MyEnum`\n   |\n   = note: `&MyEnum` is already a pointer, `Box<&MyEnum>` allocates a pointer on the heap\n\nerror: usage of `Box<Box<T>>`\n  --> tests/ui/redundant_allocation_fixable.rs:32:30\n   |\nLL |     pub fn box_test5<T>(foo: Box<Box<T>>) {}\n   |                              ^^^^^^^^^^^ help: try: `Box<T>`\n   |\n   = note: `Box<T>` is already on the heap, `Box<Box<T>>` makes an extra allocation\n\nerror: usage of `Rc<&T>`\n  --> tests/ui/redundant_allocation_fixable.rs:42:29\n   |\nLL |     pub fn rc_test1<T>(foo: Rc<&T>) {}\n   |                             ^^^^^^ help: try: `&T`\n   |\n   = note: `&T` is already a pointer, `Rc<&T>` allocates a pointer on the heap\n\nerror: usage of `Rc<&MyStruct>`\n  --> tests/ui/redundant_allocation_fixable.rs:45:26\n   |\nLL |     pub fn rc_test2(foo: Rc<&MyStruct>) {}\n   |                          ^^^^^^^^^^^^^ help: try: `&MyStruct`\n   |\n   = note: `&MyStruct` is already a pointer, `Rc<&MyStruct>` allocates a pointer on the heap\n\nerror: usage of `Rc<&MyEnum>`\n  --> tests/ui/redundant_allocation_fixable.rs:48:26\n   |\nLL |     pub fn rc_test3(foo: Rc<&MyEnum>) {}\n   |                          ^^^^^^^^^^^ help: try: `&MyEnum`\n   |\n   = note: `&MyEnum` is already a pointer, `Rc<&MyEnum>` allocates a pointer on the heap\n\nerror: usage of `Rc<Rc<bool>>`\n  --> tests/ui/redundant_allocation_fixable.rs:53:24\n   |\nLL |     pub fn rc_test6(a: Rc<Rc<bool>>) {}\n   |                        ^^^^^^^^^^^^ help: try: `Rc<bool>`\n   |\n   = note: `Rc<bool>` is already on the heap, `Rc<Rc<bool>>` makes an extra allocation\n\nerror: usage of `Arc<&T>`\n  --> tests/ui/redundant_allocation_fixable.rs:63:30\n   |\nLL |     pub fn arc_test1<T>(foo: Arc<&T>) {}\n   |                              ^^^^^^^ help: try: `&T`\n   |\n   = note: `&T` is already a pointer, `Arc<&T>` allocates a pointer on the heap\n\nerror: usage of `Arc<&MyStruct>`\n  --> tests/ui/redundant_allocation_fixable.rs:66:27\n   |\nLL |     pub fn arc_test2(foo: Arc<&MyStruct>) {}\n   |                           ^^^^^^^^^^^^^^ help: try: `&MyStruct`\n   |\n   = note: `&MyStruct` is already a pointer, `Arc<&MyStruct>` allocates a pointer on the heap\n\nerror: usage of `Arc<&MyEnum>`\n  --> tests/ui/redundant_allocation_fixable.rs:69:27\n   |\nLL |     pub fn arc_test3(foo: Arc<&MyEnum>) {}\n   |                           ^^^^^^^^^^^^ help: try: `&MyEnum`\n   |\n   = note: `&MyEnum` is already a pointer, `Arc<&MyEnum>` allocates a pointer on the heap\n\nerror: usage of `Arc<Arc<bool>>`\n  --> tests/ui/redundant_allocation_fixable.rs:74:25\n   |\nLL |     pub fn arc_test7(a: Arc<Arc<bool>>) {}\n   |                         ^^^^^^^^^^^^^^ help: try: `Arc<bool>`\n   |\n   = note: `Arc<bool>` is already on the heap, `Arc<Arc<bool>>` makes an extra allocation\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_as_str.fixed",
    "content": "#![warn(clippy::redundant_as_str)]\n#![allow(clippy::const_is_empty)]\n\nfn main() {\n    let string = \"Hello, world!\".to_owned();\n\n    // These methods are redundant and the `as_str` can be removed\n    let _redundant = string.as_bytes();\n    //~^ redundant_as_str\n    let _redundant = string.is_empty();\n    //~^ redundant_as_str\n\n    // These methods don't use `as_str` when they are redundant\n    let _no_as_str = string.as_bytes();\n    let _no_as_str = string.is_empty();\n\n    // These methods are not redundant, and are equivalent to\n    // doing dereferencing the string and applying the method\n    let _not_redundant = string.as_str().escape_unicode();\n    let _not_redundant = string.as_str().trim();\n    let _not_redundant = string.as_str().split_whitespace();\n\n    // These methods don't use `as_str` and are applied on a `str` directly\n    let borrowed_str = \"Hello, world!\";\n    let _is_str = borrowed_str.as_bytes();\n    let _is_str = borrowed_str.is_empty();\n}\n"
  },
  {
    "path": "tests/ui/redundant_as_str.rs",
    "content": "#![warn(clippy::redundant_as_str)]\n#![allow(clippy::const_is_empty)]\n\nfn main() {\n    let string = \"Hello, world!\".to_owned();\n\n    // These methods are redundant and the `as_str` can be removed\n    let _redundant = string.as_str().as_bytes();\n    //~^ redundant_as_str\n    let _redundant = string.as_str().is_empty();\n    //~^ redundant_as_str\n\n    // These methods don't use `as_str` when they are redundant\n    let _no_as_str = string.as_bytes();\n    let _no_as_str = string.is_empty();\n\n    // These methods are not redundant, and are equivalent to\n    // doing dereferencing the string and applying the method\n    let _not_redundant = string.as_str().escape_unicode();\n    let _not_redundant = string.as_str().trim();\n    let _not_redundant = string.as_str().split_whitespace();\n\n    // These methods don't use `as_str` and are applied on a `str` directly\n    let borrowed_str = \"Hello, world!\";\n    let _is_str = borrowed_str.as_bytes();\n    let _is_str = borrowed_str.is_empty();\n}\n"
  },
  {
    "path": "tests/ui/redundant_as_str.stderr",
    "content": "error: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too\n  --> tests/ui/redundant_as_str.rs:8:29\n   |\nLL |     let _redundant = string.as_str().as_bytes();\n   |                             ^^^^^^^^^^^^^^^^^ help: try: `as_bytes`\n   |\n   = note: `-D clippy::redundant-as-str` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_as_str)]`\n\nerror: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too\n  --> tests/ui/redundant_as_str.rs:10:29\n   |\nLL |     let _redundant = string.as_str().is_empty();\n   |                             ^^^^^^^^^^^^^^^^^ help: try: `is_empty`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_async_block.fixed",
    "content": "#![allow(unused, clippy::manual_async_fn)]\n#![warn(clippy::redundant_async_block)]\n\nuse std::future::{Future, IntoFuture};\n\nasync fn func1(n: usize) -> usize {\n    n + 1\n}\n\nasync fn func2() -> String {\n    let s = String::from(\"some string\");\n    let f = async { (*s).to_owned() };\n    let x = f;\n    //~^ redundant_async_block\n    x.await\n}\n\nfn main() {\n    let fut1 = async { 17 };\n    // Lint\n    let fut2 = fut1;\n    //~^ redundant_async_block\n\n    let fut1 = async { 25 };\n    // Lint\n    let fut2 = fut1;\n    //~^ redundant_async_block\n\n    // Lint\n    let fut = async { 42 };\n    //~^ redundant_async_block\n\n    // Do not lint: not a single expression\n    let fut = async {\n        func1(10).await;\n        func2().await\n    };\n\n    // Do not lint: expression contains `.await`\n    let fut = async { func1(func2().await.len()).await };\n}\n\n#[allow(clippy::let_and_return)]\nfn capture_local() -> impl Future<Output = i32> {\n    let fut = async { 17 };\n    // Lint\n    fut\n    //~^ redundant_async_block\n}\n\nfn capture_local_closure(s: &str) -> impl Future<Output = &str> {\n    let f = move || std::future::ready(s);\n    // Do not lint: `f` would not live long enough\n    async move { f().await }\n}\n\n#[allow(clippy::let_and_return)]\nfn capture_arg(s: &str) -> impl Future<Output = &str> {\n    let fut = async move { s };\n    // Lint\n    fut\n    //~^ redundant_async_block\n}\n\nfn capture_future_arg<T>(f: impl Future<Output = T>) -> impl Future<Output = T> {\n    // Lint\n    f\n    //~^ redundant_async_block\n}\n\nfn capture_func_result<FN, F, T>(f: FN) -> impl Future<Output = T>\nwhere\n    F: Future<Output = T>,\n    FN: FnOnce() -> F,\n{\n    // Do not lint, as f() would be evaluated prematurely\n    async { f().await }\n}\n\nfn double_future(f: impl Future<Output = impl Future<Output = u32>>) -> impl Future<Output = u32> {\n    // Do not lint, we will get a `.await` outside a `.async`\n    async { f.await.await }\n}\n\nfn await_in_async<F, R>(f: F) -> impl Future<Output = u32>\nwhere\n    F: FnOnce() -> R,\n    R: Future<Output = u32>,\n{\n    // Lint\n    async { f().await + 1 }\n    //~^ redundant_async_block\n}\n\n#[derive(Debug, Clone)]\nstruct F {}\n\nimpl F {\n    async fn run(&self) {}\n}\n\npub async fn run() {\n    let f = F {};\n    let c = f.clone();\n    // Do not lint: `c` would not live long enough\n    spawn(async move { c.run().await });\n    let _f = f;\n}\n\nfn spawn<F: Future + 'static>(_: F) {}\n\nasync fn work(_: &str) {}\n\nfn capture() {\n    let val = \"Hello World\".to_owned();\n    // Do not lint: `val` would not live long enough\n    spawn(async { work(&{ val }).await });\n}\n\nfn await_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e:expr) => {\n            $e.await\n        };\n    }\n    // Do not lint: the macro may change in the future\n    // or return different things depending on its argument\n    async { mac!(async { 42 }) }\n}\n\nfn async_expr_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        () => {\n            async { 42 }\n        };\n    }\n    // Do not lint: the macro may change in the future\n    async { mac!().await }\n}\n\nfn async_expr_from_macro_deep() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        () => {\n            async { 42 }\n        };\n    }\n    // Do not lint: the macro may change in the future\n    async { ({ mac!() }).await }\n}\n\nfn all_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        () => {\n            // Lint\n            async { 42 }\n            //~^ redundant_async_block\n        };\n    }\n    mac!()\n}\n\nfn parts_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e: expr) => {\n            // Do not lint: `$e` might not always be side-effect free\n            async { $e.await }\n        };\n    }\n    mac!(async { 42 })\n}\n\nfn safe_parts_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e: expr) => {\n            // Lint\n            async { $e }\n            //~^ redundant_async_block\n        };\n    }\n    mac!(42)\n}\n\nfn parts_from_macro_deep() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e: expr) => {\n            // Do not lint: `$e` might not always be side-effect free\n            async { ($e,).0.await }\n        };\n    }\n    let f = std::future::ready(42);\n    mac!(f)\n}\n\nfn await_from_macro_deep() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e:expr) => {{ $e }.await};\n    }\n    // Do not lint: the macro may change in the future\n    // or return different things depending on its argument\n    async { mac!(async { 42 }) }\n}\n\n// Issue 11959\nfn from_into_future(a: impl IntoFuture<Output = u32>) -> impl Future<Output = u32> {\n    // Do not lint: `a` is not equivalent to this expression\n    async { a.await }\n}\n"
  },
  {
    "path": "tests/ui/redundant_async_block.rs",
    "content": "#![allow(unused, clippy::manual_async_fn)]\n#![warn(clippy::redundant_async_block)]\n\nuse std::future::{Future, IntoFuture};\n\nasync fn func1(n: usize) -> usize {\n    n + 1\n}\n\nasync fn func2() -> String {\n    let s = String::from(\"some string\");\n    let f = async { (*s).to_owned() };\n    let x = async { f.await };\n    //~^ redundant_async_block\n    x.await\n}\n\nfn main() {\n    let fut1 = async { 17 };\n    // Lint\n    let fut2 = async { fut1.await };\n    //~^ redundant_async_block\n\n    let fut1 = async { 25 };\n    // Lint\n    let fut2 = async move { fut1.await };\n    //~^ redundant_async_block\n\n    // Lint\n    let fut = async { async { 42 }.await };\n    //~^ redundant_async_block\n\n    // Do not lint: not a single expression\n    let fut = async {\n        func1(10).await;\n        func2().await\n    };\n\n    // Do not lint: expression contains `.await`\n    let fut = async { func1(func2().await.len()).await };\n}\n\n#[allow(clippy::let_and_return)]\nfn capture_local() -> impl Future<Output = i32> {\n    let fut = async { 17 };\n    // Lint\n    async move { fut.await }\n    //~^ redundant_async_block\n}\n\nfn capture_local_closure(s: &str) -> impl Future<Output = &str> {\n    let f = move || std::future::ready(s);\n    // Do not lint: `f` would not live long enough\n    async move { f().await }\n}\n\n#[allow(clippy::let_and_return)]\nfn capture_arg(s: &str) -> impl Future<Output = &str> {\n    let fut = async move { s };\n    // Lint\n    async move { fut.await }\n    //~^ redundant_async_block\n}\n\nfn capture_future_arg<T>(f: impl Future<Output = T>) -> impl Future<Output = T> {\n    // Lint\n    async { f.await }\n    //~^ redundant_async_block\n}\n\nfn capture_func_result<FN, F, T>(f: FN) -> impl Future<Output = T>\nwhere\n    F: Future<Output = T>,\n    FN: FnOnce() -> F,\n{\n    // Do not lint, as f() would be evaluated prematurely\n    async { f().await }\n}\n\nfn double_future(f: impl Future<Output = impl Future<Output = u32>>) -> impl Future<Output = u32> {\n    // Do not lint, we will get a `.await` outside a `.async`\n    async { f.await.await }\n}\n\nfn await_in_async<F, R>(f: F) -> impl Future<Output = u32>\nwhere\n    F: FnOnce() -> R,\n    R: Future<Output = u32>,\n{\n    // Lint\n    async { async { f().await + 1 }.await }\n    //~^ redundant_async_block\n}\n\n#[derive(Debug, Clone)]\nstruct F {}\n\nimpl F {\n    async fn run(&self) {}\n}\n\npub async fn run() {\n    let f = F {};\n    let c = f.clone();\n    // Do not lint: `c` would not live long enough\n    spawn(async move { c.run().await });\n    let _f = f;\n}\n\nfn spawn<F: Future + 'static>(_: F) {}\n\nasync fn work(_: &str) {}\n\nfn capture() {\n    let val = \"Hello World\".to_owned();\n    // Do not lint: `val` would not live long enough\n    spawn(async { work(&{ val }).await });\n}\n\nfn await_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e:expr) => {\n            $e.await\n        };\n    }\n    // Do not lint: the macro may change in the future\n    // or return different things depending on its argument\n    async { mac!(async { 42 }) }\n}\n\nfn async_expr_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        () => {\n            async { 42 }\n        };\n    }\n    // Do not lint: the macro may change in the future\n    async { mac!().await }\n}\n\nfn async_expr_from_macro_deep() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        () => {\n            async { 42 }\n        };\n    }\n    // Do not lint: the macro may change in the future\n    async { ({ mac!() }).await }\n}\n\nfn all_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        () => {\n            // Lint\n            async { async { 42 }.await }\n            //~^ redundant_async_block\n        };\n    }\n    mac!()\n}\n\nfn parts_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e: expr) => {\n            // Do not lint: `$e` might not always be side-effect free\n            async { $e.await }\n        };\n    }\n    mac!(async { 42 })\n}\n\nfn safe_parts_from_macro() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e: expr) => {\n            // Lint\n            async { async { $e }.await }\n            //~^ redundant_async_block\n        };\n    }\n    mac!(42)\n}\n\nfn parts_from_macro_deep() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e: expr) => {\n            // Do not lint: `$e` might not always be side-effect free\n            async { ($e,).0.await }\n        };\n    }\n    let f = std::future::ready(42);\n    mac!(f)\n}\n\nfn await_from_macro_deep() -> impl Future<Output = u32> {\n    macro_rules! mac {\n        ($e:expr) => {{ $e }.await};\n    }\n    // Do not lint: the macro may change in the future\n    // or return different things depending on its argument\n    async { mac!(async { 42 }) }\n}\n\n// Issue 11959\nfn from_into_future(a: impl IntoFuture<Output = u32>) -> impl Future<Output = u32> {\n    // Do not lint: `a` is not equivalent to this expression\n    async { a.await }\n}\n"
  },
  {
    "path": "tests/ui/redundant_async_block.stderr",
    "content": "error: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:13:13\n   |\nLL |     let x = async { f.await };\n   |             ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f`\n   |\n   = note: `-D clippy::redundant-async-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_async_block)]`\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:21:16\n   |\nLL |     let fut2 = async { fut1.await };\n   |                ^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1`\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:26:16\n   |\nLL |     let fut2 = async move { fut1.await };\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1`\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:30:15\n   |\nLL |     let fut = async { async { 42 }.await };\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }`\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:47:5\n   |\nLL |     async move { fut.await }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut`\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:61:5\n   |\nLL |     async move { fut.await }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut`\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:67:5\n   |\nLL |     async { f.await }\n   |     ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f`\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:91:5\n   |\nLL |     async { async { f().await + 1 }.await }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { f().await + 1 }`\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:155:13\n   |\nLL |             async { async { 42 }.await }\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }`\n...\nLL |     mac!()\n   |     ------ in this macro invocation\n   |\n   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this async expression only awaits a single future\n  --> tests/ui/redundant_async_block.rs:176:13\n   |\nLL |             async { async { $e }.await }\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { $e }`\n...\nLL |     mac!(42)\n   |     -------- in this macro invocation\n   |\n   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_at_rest_pattern.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(irrefutable_let_patterns, unused)]\n#![warn(clippy::redundant_at_rest_pattern)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    if let a = [()] {}\n    //~^ redundant_at_rest_pattern\n    if let ref a = [()] {}\n    //~^ redundant_at_rest_pattern\n    if let mut a = [()] {}\n    //~^ redundant_at_rest_pattern\n    if let ref mut a = [()] {}\n    //~^ redundant_at_rest_pattern\n    let v = vec![()];\n    if let a = &*v {}\n    //~^ redundant_at_rest_pattern\n    let s = &[()];\n    if let a = s {}\n    //~^ redundant_at_rest_pattern\n    // Don't lint\n    if let [..] = &*v {}\n    if let [a] = &*v {}\n    if let [()] = &*v {}\n    if let [first, rest @ ..] = &*v {}\n    if let a = [()] {}\n    external! {\n        if let [a @ ..] = [()] {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/redundant_at_rest_pattern.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(irrefutable_let_patterns, unused)]\n#![warn(clippy::redundant_at_rest_pattern)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    if let [a @ ..] = [()] {}\n    //~^ redundant_at_rest_pattern\n    if let [ref a @ ..] = [()] {}\n    //~^ redundant_at_rest_pattern\n    if let [mut a @ ..] = [()] {}\n    //~^ redundant_at_rest_pattern\n    if let [ref mut a @ ..] = [()] {}\n    //~^ redundant_at_rest_pattern\n    let v = vec![()];\n    if let [a @ ..] = &*v {}\n    //~^ redundant_at_rest_pattern\n    let s = &[()];\n    if let [a @ ..] = s {}\n    //~^ redundant_at_rest_pattern\n    // Don't lint\n    if let [..] = &*v {}\n    if let [a] = &*v {}\n    if let [()] = &*v {}\n    if let [first, rest @ ..] = &*v {}\n    if let a = [()] {}\n    external! {\n        if let [a @ ..] = [()] {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/redundant_at_rest_pattern.stderr",
    "content": "error: using a rest pattern to bind an entire slice to a local\n  --> tests/ui/redundant_at_rest_pattern.rs:9:12\n   |\nLL |     if let [a @ ..] = [()] {}\n   |            ^^^^^^^^ help: this is better represented with just the binding: `a`\n   |\n   = note: `-D clippy::redundant-at-rest-pattern` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_at_rest_pattern)]`\n\nerror: using a rest pattern to bind an entire slice to a local\n  --> tests/ui/redundant_at_rest_pattern.rs:11:12\n   |\nLL |     if let [ref a @ ..] = [()] {}\n   |            ^^^^^^^^^^^^ help: this is better represented with just the binding: `ref a`\n\nerror: using a rest pattern to bind an entire slice to a local\n  --> tests/ui/redundant_at_rest_pattern.rs:13:12\n   |\nLL |     if let [mut a @ ..] = [()] {}\n   |            ^^^^^^^^^^^^ help: this is better represented with just the binding: `mut a`\n\nerror: using a rest pattern to bind an entire slice to a local\n  --> tests/ui/redundant_at_rest_pattern.rs:15:12\n   |\nLL |     if let [ref mut a @ ..] = [()] {}\n   |            ^^^^^^^^^^^^^^^^ help: this is better represented with just the binding: `ref mut a`\n\nerror: using a rest pattern to bind an entire slice to a local\n  --> tests/ui/redundant_at_rest_pattern.rs:18:12\n   |\nLL |     if let [a @ ..] = &*v {}\n   |            ^^^^^^^^ help: this is better represented with just the binding: `a`\n\nerror: using a rest pattern to bind an entire slice to a local\n  --> tests/ui/redundant_at_rest_pattern.rs:21:12\n   |\nLL |     if let [a @ ..] = s {}\n   |            ^^^^^^^^ help: this is better represented with just the binding: `a`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_clone.fixed",
    "content": "// rustfix-only-machine-applicable\n#![warn(clippy::redundant_clone)]\n#![allow(\n    clippy::drop_non_drop,\n    clippy::implicit_clone,\n    clippy::pathbuf_init_then_push,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_literal_unwrap\n)]\n\nuse std::ffi::OsString;\nuse std::path::Path;\n\nfn main() {\n    let _s = [\"lorem\", \"ipsum\"].join(\" \");\n    //~^ redundant_clone\n\n    let s = String::from(\"foo\");\n    let _s = s;\n    //~^ redundant_clone\n\n    let s = String::from(\"foo\");\n    let _s = s;\n    //~^ redundant_clone\n\n    let s = String::from(\"foo\");\n    let _s = s;\n    //~^ redundant_clone\n\n    let _s = Path::new(\"/a/b/\").join(\"c\");\n    //~^ redundant_clone\n\n    let _s = Path::new(\"/a/b/\").join(\"c\");\n    //~^ redundant_clone\n\n    let _s = OsString::new();\n    //~^ redundant_clone\n\n    let _s = OsString::new();\n    //~^ redundant_clone\n\n    // Check that lint level works\n    #[allow(clippy::redundant_clone)]\n    let _s = String::new().to_string();\n\n    // Check that lint level works\n    #[expect(clippy::redundant_clone)]\n    let _s = String::new().to_string();\n\n    let tup = (String::from(\"foo\"),);\n    let _t = tup.0;\n    //~^ redundant_clone\n\n    let tup_ref = &(String::from(\"foo\"),);\n    let _s = tup_ref.0.clone(); // this `.clone()` cannot be removed\n\n    {\n        let x = String::new();\n        let y = &x;\n\n        let _x = x.clone(); // ok; `x` is borrowed by `y`\n\n        let _ = y.len();\n    }\n\n    let x = (String::new(),);\n    let _ = Some(String::new()).unwrap_or_else(|| x.0.clone()); // ok; closure borrows `x`\n\n    with_branch(Alpha, true);\n    cannot_double_move(Alpha);\n    cannot_move_from_type_with_drop();\n    borrower_propagation();\n    not_consumed();\n    issue_5405();\n    manually_drop();\n    clone_then_move_cloned();\n    hashmap_neg();\n    false_negative_5707();\n}\n\n#[derive(Clone)]\nstruct Alpha;\nfn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) {\n    if b { (a.clone(), a) } else { (Alpha, a) }\n    //~^ redundant_clone\n}\n\nfn cannot_double_move(a: Alpha) -> (Alpha, Alpha) {\n    (a.clone(), a)\n}\n\nstruct TypeWithDrop {\n    x: String,\n}\n\nimpl Drop for TypeWithDrop {\n    fn drop(&mut self) {}\n}\n\nfn cannot_move_from_type_with_drop() -> String {\n    let s = TypeWithDrop { x: String::new() };\n    s.x.clone() // removing this `clone()` summons E0509\n}\n\nfn borrower_propagation() {\n    let s = String::new();\n    let t = String::new();\n\n    {\n        fn b() -> bool {\n            unimplemented!()\n        }\n        let _u = if b() { &s } else { &t };\n\n        // ok; `s` and `t` are possibly borrowed\n        let _s = s.clone();\n        let _t = t.clone();\n    }\n\n    {\n        let _u = || s.len();\n        let _v = [&t; 32];\n        let _s = s.clone(); // ok\n        let _t = t.clone(); // ok\n    }\n\n    {\n        let _u = {\n            let u = Some(&s);\n            let _ = s.clone(); // ok\n            u\n        };\n        let _s = s.clone(); // ok\n    }\n\n    {\n        use std::convert::identity as id;\n        let _u = id(id(&s));\n        let _s = s.clone(); // ok, `u` borrows `s`\n    }\n\n    let _s = s;\n    //~^ redundant_clone\n    let _t = t;\n    //~^ redundant_clone\n\n    #[derive(Clone)]\n    struct Foo {\n        x: usize,\n    }\n\n    {\n        let f = Foo { x: 123 };\n        let _x = Some(f.x);\n        let _f = f;\n        //~^ redundant_clone\n    }\n\n    {\n        let f = Foo { x: 123 };\n        let _x = &f.x;\n        let _f = f.clone(); // ok\n    }\n}\n\nfn not_consumed() {\n    let x = std::path::PathBuf::from(\"home\");\n    let y = x.join(\"matthias\");\n    //~^ redundant_clone\n    // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is\n    // redundant. (It also does not consume the PathBuf)\n\n    println!(\"x: {:?}, y: {:?}\", x, y);\n\n    let mut s = String::new();\n    s.clone().push_str(\"foo\"); // OK, removing this `clone()` will change the behavior.\n    s.push_str(\"bar\");\n    assert_eq!(s, \"bar\");\n\n    let t = Some(s);\n    // OK\n    if let Some(x) = t.clone() {\n        println!(\"{}\", x);\n    }\n    if let Some(x) = t {\n        println!(\"{}\", x);\n    }\n}\n\n#[allow(clippy::clone_on_copy)]\nfn issue_5405() {\n    let a: [String; 1] = [String::from(\"foo\")];\n    let _b: String = a[0].clone();\n\n    let c: [usize; 2] = [2, 3];\n    let _d: usize = c[1].clone();\n}\n\nfn manually_drop() {\n    use std::mem::ManuallyDrop;\n    use std::sync::Arc;\n\n    let a = ManuallyDrop::new(Arc::new(\"Hello!\".to_owned()));\n    let _ = a.clone(); // OK\n\n    let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a));\n    unsafe {\n        Arc::from_raw(p);\n        Arc::from_raw(p);\n    }\n}\n\nfn clone_then_move_cloned() {\n    // issue #5973\n    let x = Some(String::new());\n    // ok, x is moved while the clone is in use.\n    assert_eq!(x.clone(), None, \"not equal {}\", x.unwrap());\n\n    // issue #5595\n    fn foo<F: Fn()>(_: &Alpha, _: F) {}\n    let x = Alpha;\n    // ok, data is moved while the clone is in use.\n    foo(&x, move || {\n        //~^ redundant_clone\n        let _ = x;\n    });\n\n    // issue #6998\n    struct S(String);\n    impl S {\n        fn m(&mut self) {}\n    }\n    let mut x = S(String::new());\n    x.0.clone().chars().for_each(|_| x.m());\n}\n\nfn hashmap_neg() {\n    // issue 5707\n    use std::collections::HashMap;\n    use std::path::PathBuf;\n\n    let p = PathBuf::from(\"/\");\n\n    let mut h: HashMap<&str, &str> = HashMap::new();\n    h.insert(\"orig-p\", p.to_str().unwrap());\n\n    let mut q = p.clone();\n    q.push(\"foo\");\n\n    println!(\"{:?} {}\", h, q.display());\n}\n\nfn false_negative_5707() {\n    fn foo(_x: &Alpha, _y: &mut Alpha) {}\n\n    let x = Alpha;\n    let mut y = Alpha;\n    foo(&x, &mut y);\n    let _z = x.clone(); // pr 7346 can't lint on `x`\n    drop(y);\n}\n\nmod issue10074 {\n    #[derive(Debug, Clone)]\n    enum MyEnum {\n        A = 1,\n    }\n\n    fn false_positive_on_as() {\n        let e = MyEnum::A;\n        let v = e.clone() as u16;\n\n        println!(\"{e:?}\");\n        println!(\"{v}\");\n    }\n}\n\nmod issue13900 {\n    use std::fmt::Display;\n\n    fn do_something(f: impl Display + Clone) -> String {\n        let g = f.clone();\n        format!(\"{} + {}\", f, g)\n    }\n\n    fn regression() {\n        let mut a = String::new();\n        let mut b = String::new();\n        for _ in 1..10 {\n            b = a.clone();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/redundant_clone.rs",
    "content": "// rustfix-only-machine-applicable\n#![warn(clippy::redundant_clone)]\n#![allow(\n    clippy::drop_non_drop,\n    clippy::implicit_clone,\n    clippy::pathbuf_init_then_push,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_literal_unwrap\n)]\n\nuse std::ffi::OsString;\nuse std::path::Path;\n\nfn main() {\n    let _s = [\"lorem\", \"ipsum\"].join(\" \").to_string();\n    //~^ redundant_clone\n\n    let s = String::from(\"foo\");\n    let _s = s.clone();\n    //~^ redundant_clone\n\n    let s = String::from(\"foo\");\n    let _s = s.to_string();\n    //~^ redundant_clone\n\n    let s = String::from(\"foo\");\n    let _s = s.to_owned();\n    //~^ redundant_clone\n\n    let _s = Path::new(\"/a/b/\").join(\"c\").to_owned();\n    //~^ redundant_clone\n\n    let _s = Path::new(\"/a/b/\").join(\"c\").to_path_buf();\n    //~^ redundant_clone\n\n    let _s = OsString::new().to_owned();\n    //~^ redundant_clone\n\n    let _s = OsString::new().to_os_string();\n    //~^ redundant_clone\n\n    // Check that lint level works\n    #[allow(clippy::redundant_clone)]\n    let _s = String::new().to_string();\n\n    // Check that lint level works\n    #[expect(clippy::redundant_clone)]\n    let _s = String::new().to_string();\n\n    let tup = (String::from(\"foo\"),);\n    let _t = tup.0.clone();\n    //~^ redundant_clone\n\n    let tup_ref = &(String::from(\"foo\"),);\n    let _s = tup_ref.0.clone(); // this `.clone()` cannot be removed\n\n    {\n        let x = String::new();\n        let y = &x;\n\n        let _x = x.clone(); // ok; `x` is borrowed by `y`\n\n        let _ = y.len();\n    }\n\n    let x = (String::new(),);\n    let _ = Some(String::new()).unwrap_or_else(|| x.0.clone()); // ok; closure borrows `x`\n\n    with_branch(Alpha, true);\n    cannot_double_move(Alpha);\n    cannot_move_from_type_with_drop();\n    borrower_propagation();\n    not_consumed();\n    issue_5405();\n    manually_drop();\n    clone_then_move_cloned();\n    hashmap_neg();\n    false_negative_5707();\n}\n\n#[derive(Clone)]\nstruct Alpha;\nfn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) {\n    if b { (a.clone(), a.clone()) } else { (Alpha, a) }\n    //~^ redundant_clone\n}\n\nfn cannot_double_move(a: Alpha) -> (Alpha, Alpha) {\n    (a.clone(), a)\n}\n\nstruct TypeWithDrop {\n    x: String,\n}\n\nimpl Drop for TypeWithDrop {\n    fn drop(&mut self) {}\n}\n\nfn cannot_move_from_type_with_drop() -> String {\n    let s = TypeWithDrop { x: String::new() };\n    s.x.clone() // removing this `clone()` summons E0509\n}\n\nfn borrower_propagation() {\n    let s = String::new();\n    let t = String::new();\n\n    {\n        fn b() -> bool {\n            unimplemented!()\n        }\n        let _u = if b() { &s } else { &t };\n\n        // ok; `s` and `t` are possibly borrowed\n        let _s = s.clone();\n        let _t = t.clone();\n    }\n\n    {\n        let _u = || s.len();\n        let _v = [&t; 32];\n        let _s = s.clone(); // ok\n        let _t = t.clone(); // ok\n    }\n\n    {\n        let _u = {\n            let u = Some(&s);\n            let _ = s.clone(); // ok\n            u\n        };\n        let _s = s.clone(); // ok\n    }\n\n    {\n        use std::convert::identity as id;\n        let _u = id(id(&s));\n        let _s = s.clone(); // ok, `u` borrows `s`\n    }\n\n    let _s = s.clone();\n    //~^ redundant_clone\n    let _t = t.clone();\n    //~^ redundant_clone\n\n    #[derive(Clone)]\n    struct Foo {\n        x: usize,\n    }\n\n    {\n        let f = Foo { x: 123 };\n        let _x = Some(f.x);\n        let _f = f.clone();\n        //~^ redundant_clone\n    }\n\n    {\n        let f = Foo { x: 123 };\n        let _x = &f.x;\n        let _f = f.clone(); // ok\n    }\n}\n\nfn not_consumed() {\n    let x = std::path::PathBuf::from(\"home\");\n    let y = x.clone().join(\"matthias\");\n    //~^ redundant_clone\n    // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is\n    // redundant. (It also does not consume the PathBuf)\n\n    println!(\"x: {:?}, y: {:?}\", x, y);\n\n    let mut s = String::new();\n    s.clone().push_str(\"foo\"); // OK, removing this `clone()` will change the behavior.\n    s.push_str(\"bar\");\n    assert_eq!(s, \"bar\");\n\n    let t = Some(s);\n    // OK\n    if let Some(x) = t.clone() {\n        println!(\"{}\", x);\n    }\n    if let Some(x) = t {\n        println!(\"{}\", x);\n    }\n}\n\n#[allow(clippy::clone_on_copy)]\nfn issue_5405() {\n    let a: [String; 1] = [String::from(\"foo\")];\n    let _b: String = a[0].clone();\n\n    let c: [usize; 2] = [2, 3];\n    let _d: usize = c[1].clone();\n}\n\nfn manually_drop() {\n    use std::mem::ManuallyDrop;\n    use std::sync::Arc;\n\n    let a = ManuallyDrop::new(Arc::new(\"Hello!\".to_owned()));\n    let _ = a.clone(); // OK\n\n    let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a));\n    unsafe {\n        Arc::from_raw(p);\n        Arc::from_raw(p);\n    }\n}\n\nfn clone_then_move_cloned() {\n    // issue #5973\n    let x = Some(String::new());\n    // ok, x is moved while the clone is in use.\n    assert_eq!(x.clone(), None, \"not equal {}\", x.unwrap());\n\n    // issue #5595\n    fn foo<F: Fn()>(_: &Alpha, _: F) {}\n    let x = Alpha;\n    // ok, data is moved while the clone is in use.\n    foo(&x.clone(), move || {\n        //~^ redundant_clone\n        let _ = x;\n    });\n\n    // issue #6998\n    struct S(String);\n    impl S {\n        fn m(&mut self) {}\n    }\n    let mut x = S(String::new());\n    x.0.clone().chars().for_each(|_| x.m());\n}\n\nfn hashmap_neg() {\n    // issue 5707\n    use std::collections::HashMap;\n    use std::path::PathBuf;\n\n    let p = PathBuf::from(\"/\");\n\n    let mut h: HashMap<&str, &str> = HashMap::new();\n    h.insert(\"orig-p\", p.to_str().unwrap());\n\n    let mut q = p.clone();\n    q.push(\"foo\");\n\n    println!(\"{:?} {}\", h, q.display());\n}\n\nfn false_negative_5707() {\n    fn foo(_x: &Alpha, _y: &mut Alpha) {}\n\n    let x = Alpha;\n    let mut y = Alpha;\n    foo(&x, &mut y);\n    let _z = x.clone(); // pr 7346 can't lint on `x`\n    drop(y);\n}\n\nmod issue10074 {\n    #[derive(Debug, Clone)]\n    enum MyEnum {\n        A = 1,\n    }\n\n    fn false_positive_on_as() {\n        let e = MyEnum::A;\n        let v = e.clone() as u16;\n\n        println!(\"{e:?}\");\n        println!(\"{v}\");\n    }\n}\n\nmod issue13900 {\n    use std::fmt::Display;\n\n    fn do_something(f: impl Display + Clone) -> String {\n        let g = f.clone();\n        format!(\"{} + {}\", f, g)\n    }\n\n    fn regression() {\n        let mut a = String::new();\n        let mut b = String::new();\n        for _ in 1..10 {\n            b = a.clone();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/redundant_clone.stderr",
    "content": "error: redundant clone\n  --> tests/ui/redundant_clone.rs:15:42\n   |\nLL |     let _s = [\"lorem\", \"ipsum\"].join(\" \").to_string();\n   |                                          ^^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:15:14\n   |\nLL |     let _s = [\"lorem\", \"ipsum\"].join(\" \").to_string();\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::redundant-clone` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:19:15\n   |\nLL |     let _s = s.clone();\n   |               ^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:19:14\n   |\nLL |     let _s = s.clone();\n   |              ^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:23:15\n   |\nLL |     let _s = s.to_string();\n   |               ^^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:23:14\n   |\nLL |     let _s = s.to_string();\n   |              ^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:27:15\n   |\nLL |     let _s = s.to_owned();\n   |               ^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:27:14\n   |\nLL |     let _s = s.to_owned();\n   |              ^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:30:42\n   |\nLL |     let _s = Path::new(\"/a/b/\").join(\"c\").to_owned();\n   |                                          ^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:30:14\n   |\nLL |     let _s = Path::new(\"/a/b/\").join(\"c\").to_owned();\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:33:42\n   |\nLL |     let _s = Path::new(\"/a/b/\").join(\"c\").to_path_buf();\n   |                                          ^^^^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:33:14\n   |\nLL |     let _s = Path::new(\"/a/b/\").join(\"c\").to_path_buf();\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:36:29\n   |\nLL |     let _s = OsString::new().to_owned();\n   |                             ^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:36:14\n   |\nLL |     let _s = OsString::new().to_owned();\n   |              ^^^^^^^^^^^^^^^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:39:29\n   |\nLL |     let _s = OsString::new().to_os_string();\n   |                             ^^^^^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:39:14\n   |\nLL |     let _s = OsString::new().to_os_string();\n   |              ^^^^^^^^^^^^^^^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:51:19\n   |\nLL |     let _t = tup.0.clone();\n   |                   ^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:51:14\n   |\nLL |     let _t = tup.0.clone();\n   |              ^^^^^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:84:25\n   |\nLL |     if b { (a.clone(), a.clone()) } else { (Alpha, a) }\n   |                         ^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:84:24\n   |\nLL |     if b { (a.clone(), a.clone()) } else { (Alpha, a) }\n   |                        ^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:142:15\n   |\nLL |     let _s = s.clone();\n   |               ^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:142:14\n   |\nLL |     let _s = s.clone();\n   |              ^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:144:15\n   |\nLL |     let _t = t.clone();\n   |               ^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:144:14\n   |\nLL |     let _t = t.clone();\n   |              ^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:155:19\n   |\nLL |         let _f = f.clone();\n   |                   ^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:155:18\n   |\nLL |         let _f = f.clone();\n   |                  ^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:168:14\n   |\nLL |     let y = x.clone().join(\"matthias\");\n   |              ^^^^^^^^ help: remove this\n   |\nnote: cloned value is neither consumed nor mutated\n  --> tests/ui/redundant_clone.rs:168:13\n   |\nLL |     let y = x.clone().join(\"matthias\");\n   |             ^^^^^^^^^\n\nerror: redundant clone\n  --> tests/ui/redundant_clone.rs:223:11\n   |\nLL |     foo(&x.clone(), move || {\n   |           ^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/redundant_clone.rs:223:10\n   |\nLL |     foo(&x.clone(), move || {\n   |          ^\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_closure_call_early.rs",
    "content": "// non rustfixable, see redundant_closure_call_fixable.rs\n\n#![warn(clippy::redundant_closure_call)]\n\nfn main() {\n    let mut i = 1;\n\n    // lint here\n    let mut k = (|m| m + 1)(i);\n    //~^ redundant_closure_call\n\n    // lint here\n    k = (|a, b| a * b)(1, 5);\n    //~^ redundant_closure_call\n\n    // don't lint these\n    #[allow(clippy::needless_return)]\n    (|| return 2)();\n    (|| -> Option<i32> { None? })();\n    #[allow(clippy::try_err)]\n    (|| -> Result<i32, i32> { Err(2)? })();\n}\n"
  },
  {
    "path": "tests/ui/redundant_closure_call_early.stderr",
    "content": "error: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_early.rs:9:17\n   |\nLL |     let mut k = (|m| m + 1)(i);\n   |                 ^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::redundant-closure-call` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_early.rs:13:9\n   |\nLL |     k = (|a, b| a * b)(1, 5);\n   |         ^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_closure_call_fixable.fixed",
    "content": "#![warn(clippy::redundant_closure_call)]\n#![allow(clippy::redundant_async_block)]\n#![allow(clippy::type_complexity)]\n#![allow(unused)]\n\nasync fn something() -> u32 {\n    21\n}\n\nasync fn something_else() -> u32 {\n    2\n}\n\nfn main() {\n    let a = 42;\n    //~^ redundant_closure_call\n    let b = async {\n        //~^ redundant_closure_call\n        let x = something().await;\n        let y = something_else().await;\n        x * y\n    };\n    let c = {\n        //~^ redundant_closure_call\n        let x = 21;\n        let y = 2;\n        x * y\n    };\n    let d = async { something().await };\n    //~^ redundant_closure_call\n\n    macro_rules! m {\n        () => {\n            0\n        };\n    }\n    macro_rules! m2 {\n        () => {\n            m!()\n            //~^ redundant_closure_call\n        };\n    }\n    m2!();\n    //~^ redundant_closure_call\n    issue9956();\n}\n\nfn issue9956() {\n    assert_eq!(43, 42);\n    //~^ redundant_closure_call\n\n    // ... and some more interesting cases I've found while implementing the fix\n\n    // not actually immediately calling the closure:\n    let a = (|| 42);\n    dbg!(a());\n\n    // immediately calling it inside of a macro\n    dbg!(42);\n    //~^ redundant_closure_call\n\n    // immediately calling only one closure, so we can't remove the other ones\n    let a = || || 123;\n    //~^ redundant_closure_call\n    dbg!(a()());\n\n    // nested async closures\n    let a = async { 1 };\n    //~^ redundant_closure_call\n    let h = async { a.await };\n\n    // macro expansion tests\n    macro_rules! echo {\n        ($e:expr) => {\n            $e\n        };\n    }\n    let a = 1;\n    //~^ redundant_closure_call\n    assert_eq!(a, 1);\n    let a = 123;\n    //~^ redundant_closure_call\n    assert_eq!(a, 123);\n\n    // chaining calls, but not closures\n    fn x() -> fn() -> fn() -> fn() -> i32 {\n        || || || 42\n    }\n    let _ = x()()()();\n\n    fn bar() -> fn(i32, i32) {\n        foo\n    }\n    fn foo(_: i32, _: i32) {}\n    bar()(42, 5);\n    //~^ redundant_closure_call\n    foo(42, 5);\n    //~^ redundant_closure_call\n}\n\nasync fn issue11357() {\n    async {}.await;\n    //~^ redundant_closure_call\n}\n\nmod issue11707 {\n    use core::future::Future;\n\n    fn spawn_on(fut: impl Future<Output = ()>) {}\n\n    fn demo() {\n        spawn_on(async move {});\n        //~^ redundant_closure_call\n    }\n}\n\nfn avoid_double_parens() {\n    std::convert::identity(13_i32 + 36_i32).leading_zeros();\n    //~^ redundant_closure_call\n}\n\nfn fp_11274() {\n    macro_rules! m {\n        ($closure:expr) => {\n            $closure(1)\n        };\n    }\n    m!(|x| println!(\"{x}\"));\n}\n\n// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure\n// triggers the lint.\nfn issue_12358() {\n    macro_rules! make_closure {\n        () => {\n            (|| || {})\n        };\n        (x) => {\n            make_closure!()()\n        };\n    }\n\n    // The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically\n    // different.\n    make_closure!(x)();\n}\n\n#[rustfmt::skip]\nfn issue_9583() {\n    Some(true) == Some(true);\n     //~^ redundant_closure_call\n    Some(true) == Some(true);\n    //~^ redundant_closure_call\n    Some(if 1 > 2 {1} else {2}) == Some(2);\n    //~^ redundant_closure_call\n    Some( 1 > 2 ) == Some(true);\n    //~^ redundant_closure_call\n}\n"
  },
  {
    "path": "tests/ui/redundant_closure_call_fixable.rs",
    "content": "#![warn(clippy::redundant_closure_call)]\n#![allow(clippy::redundant_async_block)]\n#![allow(clippy::type_complexity)]\n#![allow(unused)]\n\nasync fn something() -> u32 {\n    21\n}\n\nasync fn something_else() -> u32 {\n    2\n}\n\nfn main() {\n    let a = (|| 42)();\n    //~^ redundant_closure_call\n    let b = (async || {\n        //~^ redundant_closure_call\n        let x = something().await;\n        let y = something_else().await;\n        x * y\n    })();\n    let c = (|| {\n        //~^ redundant_closure_call\n        let x = 21;\n        let y = 2;\n        x * y\n    })();\n    let d = (async || something().await)();\n    //~^ redundant_closure_call\n\n    macro_rules! m {\n        () => {\n            (|| 0)()\n        };\n    }\n    macro_rules! m2 {\n        () => {\n            (|| m!())()\n            //~^ redundant_closure_call\n        };\n    }\n    m2!();\n    //~^ redundant_closure_call\n    issue9956();\n}\n\nfn issue9956() {\n    assert_eq!((|| || 43)()(), 42);\n    //~^ redundant_closure_call\n\n    // ... and some more interesting cases I've found while implementing the fix\n\n    // not actually immediately calling the closure:\n    let a = (|| 42);\n    dbg!(a());\n\n    // immediately calling it inside of a macro\n    dbg!((|| 42)());\n    //~^ redundant_closure_call\n\n    // immediately calling only one closure, so we can't remove the other ones\n    let a = (|| || || 123)();\n    //~^ redundant_closure_call\n    dbg!(a()());\n\n    // nested async closures\n    let a = (|| || || || async || 1)()()()()();\n    //~^ redundant_closure_call\n    let h = async { a.await };\n\n    // macro expansion tests\n    macro_rules! echo {\n        ($e:expr) => {\n            $e\n        };\n    }\n    let a = (|| echo!(|| echo!(|| 1)))()()();\n    //~^ redundant_closure_call\n    assert_eq!(a, 1);\n    let a = (|| echo!((|| 123)))()();\n    //~^ redundant_closure_call\n    assert_eq!(a, 123);\n\n    // chaining calls, but not closures\n    fn x() -> fn() -> fn() -> fn() -> i32 {\n        || || || 42\n    }\n    let _ = x()()()();\n\n    fn bar() -> fn(i32, i32) {\n        foo\n    }\n    fn foo(_: i32, _: i32) {}\n    bar()((|| || 42)()(), 5);\n    //~^ redundant_closure_call\n    foo((|| || 42)()(), 5);\n    //~^ redundant_closure_call\n}\n\nasync fn issue11357() {\n    (|| async {})().await;\n    //~^ redundant_closure_call\n}\n\nmod issue11707 {\n    use core::future::Future;\n\n    fn spawn_on(fut: impl Future<Output = ()>) {}\n\n    fn demo() {\n        spawn_on((|| async move {})());\n        //~^ redundant_closure_call\n    }\n}\n\nfn avoid_double_parens() {\n    std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();\n    //~^ redundant_closure_call\n}\n\nfn fp_11274() {\n    macro_rules! m {\n        ($closure:expr) => {\n            $closure(1)\n        };\n    }\n    m!(|x| println!(\"{x}\"));\n}\n\n// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure\n// triggers the lint.\nfn issue_12358() {\n    macro_rules! make_closure {\n        () => {\n            (|| || {})\n        };\n        (x) => {\n            make_closure!()()\n        };\n    }\n\n    // The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically\n    // different.\n    make_closure!(x)();\n}\n\n#[rustfmt::skip]\nfn issue_9583() {\n    (|| { Some(true) })() == Some(true);\n     //~^ redundant_closure_call\n    (|| Some(true))() == Some(true);\n    //~^ redundant_closure_call\n    (|| { Some(if 1 > 2 {1} else {2}) })() == Some(2);\n    //~^ redundant_closure_call\n    (|| { Some( 1 > 2 ) })() == Some(true);\n    //~^ redundant_closure_call\n}\n"
  },
  {
    "path": "tests/ui/redundant_closure_call_fixable.stderr",
    "content": "error: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:15:13\n   |\nLL |     let a = (|| 42)();\n   |             ^^^^^^^^^ help: try doing something like: `42`\n   |\n   = note: `-D clippy::redundant-closure-call` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:17:13\n   |\nLL |       let b = (async || {\n   |  _____________^\nLL | |\nLL | |         let x = something().await;\nLL | |         let y = something_else().await;\nLL | |         x * y\nLL | |     })();\n   | |________^\n   |\nhelp: try doing something like\n   |\nLL ~     let b = async {\nLL +\nLL +         let x = something().await;\nLL +         let y = something_else().await;\nLL +         x * y\nLL ~     };\n   |\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:23:13\n   |\nLL |       let c = (|| {\n   |  _____________^\nLL | |\nLL | |         let x = 21;\nLL | |         let y = 2;\nLL | |         x * y\nLL | |     })();\n   | |________^\n   |\nhelp: try doing something like\n   |\nLL ~     let c = {\nLL +\nLL +         let x = 21;\nLL +         let y = 2;\nLL +         x * y\nLL ~     };\n   |\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:29:13\n   |\nLL |     let d = (async || something().await)();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:39:13\n   |\nLL |             (|| m!())()\n   |             ^^^^^^^^^^^ help: try doing something like: `m!()`\n...\nLL |     m2!();\n   |     ----- in this macro invocation\n   |\n   = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:34:13\n   |\nLL |             (|| 0)()\n   |             ^^^^^^^^ help: try doing something like: `0`\n...\nLL |     m2!();\n   |     ----- in this macro invocation\n   |\n   = note: this error originates in the macro `m` which comes from the expansion of the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:49:16\n   |\nLL |     assert_eq!((|| || 43)()(), 42);\n   |                ^^^^^^^^^^^^^^ help: try doing something like: `43`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:59:10\n   |\nLL |     dbg!((|| 42)());\n   |          ^^^^^^^^^ help: try doing something like: `42`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:63:13\n   |\nLL |     let a = (|| || || 123)();\n   |             ^^^^^^^^^^^^^^^^ help: try doing something like: `|| || 123`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:68:13\n   |\nLL |     let a = (|| || || || async || 1)()()()()();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { 1 }`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:78:13\n   |\nLL |     let a = (|| echo!(|| echo!(|| 1)))()()();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `1`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:81:13\n   |\nLL |     let a = (|| echo!((|| 123)))()();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `123`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:95:11\n   |\nLL |     bar()((|| || 42)()(), 5);\n   |           ^^^^^^^^^^^^^^ help: try doing something like: `42`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:97:9\n   |\nLL |     foo((|| || 42)()(), 5);\n   |         ^^^^^^^^^^^^^^ help: try doing something like: `42`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:102:5\n   |\nLL |     (|| async {})().await;\n   |     ^^^^^^^^^^^^^^^ help: try doing something like: `async {}`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:112:18\n   |\nLL |         spawn_on((|| async move {})());\n   |                  ^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async move {}`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:118:28\n   |\nLL |     std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();\n   |                            ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:150:5\n   |\nLL |     (|| { Some(true) })() == Some(true);\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(true)`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:152:5\n   |\nLL |     (|| Some(true))() == Some(true);\n   |     ^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(true)`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:154:5\n   |\nLL |     (|| { Some(if 1 > 2 {1} else {2}) })() == Some(2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(if 1 > 2 {1} else {2})`\n\nerror: try not to call a closure in the expression where it is declared\n  --> tests/ui/redundant_closure_call_fixable.rs:156:5\n   |\nLL |     (|| { Some( 1 > 2 ) })() == Some(true);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some( 1 > 2 )`\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_closure_call_late.rs",
    "content": "// non rustfixable, see redundant_closure_call_fixable.rs\n\n#![warn(clippy::redundant_closure_call)]\n#![allow(clippy::needless_late_init)]\n\nfn main() {\n    let mut i = 1;\n\n    // don't lint here, the closure is used more than once\n    let closure = |i| i + 1;\n    i = closure(3);\n    i = closure(4);\n\n    // lint here\n    let redun_closure = || 1;\n    i = redun_closure();\n    //~^ redundant_closure_call\n\n    // shadowed closures are supported, lint here\n    let shadowed_closure = || 1;\n    i = shadowed_closure();\n    //~^ redundant_closure_call\n\n    let shadowed_closure = || 2;\n    i = shadowed_closure();\n    //~^ redundant_closure_call\n\n    // don't lint here\n    let shadowed_closure = || 2;\n    i = shadowed_closure();\n    i = shadowed_closure();\n\n    // Fix FP in #5916\n    let mut x;\n    let create = || 2 * 2;\n    x = create();\n    fun(move || {\n        x = create();\n    })\n}\n\nfn fun<T: 'static + FnMut()>(mut f: T) {\n    f();\n}\n"
  },
  {
    "path": "tests/ui/redundant_closure_call_late.stderr",
    "content": "error: closure called just once immediately after it was declared\n  --> tests/ui/redundant_closure_call_late.rs:16:5\n   |\nLL |     i = redun_closure();\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::redundant-closure-call` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`\n\nerror: closure called just once immediately after it was declared\n  --> tests/ui/redundant_closure_call_late.rs:21:5\n   |\nLL |     i = shadowed_closure();\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: closure called just once immediately after it was declared\n  --> tests/ui/redundant_closure_call_late.rs:25:5\n   |\nLL |     i = shadowed_closure();\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_else.fixed",
    "content": "#![warn(clippy::redundant_else)]\n#![allow(clippy::needless_return, clippy::if_same_then_else, clippy::needless_late_init)]\n\nfn main() {\n    loop {\n        // break\n        if foo() {\n            println!(\"Love your neighbor;\");\n            break;\n        }\n        //~^ redundant_else\n\n        println!(\"yet don't pull down your hedge.\");\n        // continue\n        if foo() {\n            println!(\"He that lies down with Dogs,\");\n            continue;\n        }\n        //~^ redundant_else\n\n        println!(\"shall rise up with fleas.\");\n        // match block\n        if foo() {\n            match foo() {\n                1 => break,\n                _ => return,\n            }\n        }\n        //~^ redundant_else\n\n        println!(\"You may delay, but time will not.\");\n    }\n    // else if\n    if foo() {\n        return;\n    } else if foo() {\n        return;\n    }\n    //~^ redundant_else\n\n    println!(\"A fat kitchen makes a lean will.\");\n    // let binding outside of block\n    let _ = {\n        if foo() {\n            return;\n        }\n        //~^ redundant_else\n\n        1\n    };\n    // else if with let binding outside of block\n    let _ = {\n        if foo() {\n            return;\n        } else if foo() {\n            return;\n        }\n        //~^ redundant_else\n\n        2\n    };\n    // inside if let\n    let _ = if let Some(1) = foo() {\n        let _ = 1;\n        if foo() {\n            return;\n        }\n        //~^ redundant_else\n\n        1\n    } else {\n        1\n    };\n\n    //\n    // non-lint cases\n    //\n\n    // sanity check\n    if foo() {\n        let _ = 1;\n    } else {\n        println!(\"Who is wise? He that learns from every one.\");\n    }\n    // else if without else\n    if foo() {\n        return;\n    } else if foo() {\n        foo()\n    };\n    // nested if return\n    if foo() {\n        if foo() {\n            return;\n        }\n    } else {\n        foo()\n    };\n    // match with non-breaking branch\n    if foo() {\n        match foo() {\n            1 => foo(),\n            _ => return,\n        }\n    } else {\n        println!(\"Three may keep a secret, if two of them are dead.\");\n    }\n    // let binding\n    let _ = if foo() {\n        return;\n    } else {\n        1\n    };\n    // assign\n    let mut a;\n    a = if foo() {\n        return;\n    } else {\n        1\n    };\n    // assign-op\n    a += if foo() {\n        return;\n    } else {\n        1\n    };\n    // if return else if else\n    if foo() {\n        return;\n    } else if foo() {\n        1\n    } else {\n        2\n    };\n    // if else if return else\n    if foo() {\n        1\n    } else if foo() {\n        return;\n    } else {\n        2\n    };\n    // else if with let binding\n    let _ = if foo() {\n        return;\n    } else if foo() {\n        return;\n    } else {\n        2\n    };\n    // inside function call\n    Box::new(if foo() {\n        return;\n    } else {\n        1\n    });\n}\n\nfn foo<T>() -> T {\n    unimplemented!(\"I'm not Santa Claus\")\n}\n"
  },
  {
    "path": "tests/ui/redundant_else.rs",
    "content": "#![warn(clippy::redundant_else)]\n#![allow(clippy::needless_return, clippy::if_same_then_else, clippy::needless_late_init)]\n\nfn main() {\n    loop {\n        // break\n        if foo() {\n            println!(\"Love your neighbor;\");\n            break;\n        } else {\n            //~^ redundant_else\n\n            println!(\"yet don't pull down your hedge.\");\n        }\n        // continue\n        if foo() {\n            println!(\"He that lies down with Dogs,\");\n            continue;\n        } else {\n            //~^ redundant_else\n\n            println!(\"shall rise up with fleas.\");\n        }\n        // match block\n        if foo() {\n            match foo() {\n                1 => break,\n                _ => return,\n            }\n        } else {\n            //~^ redundant_else\n\n            println!(\"You may delay, but time will not.\");\n        }\n    }\n    // else if\n    if foo() {\n        return;\n    } else if foo() {\n        return;\n    } else {\n        //~^ redundant_else\n\n        println!(\"A fat kitchen makes a lean will.\");\n    }\n    // let binding outside of block\n    let _ = {\n        if foo() {\n            return;\n        } else {\n            //~^ redundant_else\n\n            1\n        }\n    };\n    // else if with let binding outside of block\n    let _ = {\n        if foo() {\n            return;\n        } else if foo() {\n            return;\n        } else {\n            //~^ redundant_else\n\n            2\n        }\n    };\n    // inside if let\n    let _ = if let Some(1) = foo() {\n        let _ = 1;\n        if foo() {\n            return;\n        } else {\n            //~^ redundant_else\n\n            1\n        }\n    } else {\n        1\n    };\n\n    //\n    // non-lint cases\n    //\n\n    // sanity check\n    if foo() {\n        let _ = 1;\n    } else {\n        println!(\"Who is wise? He that learns from every one.\");\n    }\n    // else if without else\n    if foo() {\n        return;\n    } else if foo() {\n        foo()\n    };\n    // nested if return\n    if foo() {\n        if foo() {\n            return;\n        }\n    } else {\n        foo()\n    };\n    // match with non-breaking branch\n    if foo() {\n        match foo() {\n            1 => foo(),\n            _ => return,\n        }\n    } else {\n        println!(\"Three may keep a secret, if two of them are dead.\");\n    }\n    // let binding\n    let _ = if foo() {\n        return;\n    } else {\n        1\n    };\n    // assign\n    let mut a;\n    a = if foo() {\n        return;\n    } else {\n        1\n    };\n    // assign-op\n    a += if foo() {\n        return;\n    } else {\n        1\n    };\n    // if return else if else\n    if foo() {\n        return;\n    } else if foo() {\n        1\n    } else {\n        2\n    };\n    // if else if return else\n    if foo() {\n        1\n    } else if foo() {\n        return;\n    } else {\n        2\n    };\n    // else if with let binding\n    let _ = if foo() {\n        return;\n    } else if foo() {\n        return;\n    } else {\n        2\n    };\n    // inside function call\n    Box::new(if foo() {\n        return;\n    } else {\n        1\n    });\n}\n\nfn foo<T>() -> T {\n    unimplemented!(\"I'm not Santa Claus\")\n}\n"
  },
  {
    "path": "tests/ui/redundant_else.stderr",
    "content": "error: redundant else block\n  --> tests/ui/redundant_else.rs:10:10\n   |\nLL |           } else {\n   |  __________^\nLL | |\nLL | |\nLL | |             println!(\"yet don't pull down your hedge.\");\nLL | |         }\n   | |_________^\n   |\n   = note: `-D clippy::redundant-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_else)]`\nhelp: remove the `else` block and move the contents out\n   |\nLL ~         }\nLL +\nLL + \nLL +         println!(\"yet don't pull down your hedge.\");\n   |\n\nerror: redundant else block\n  --> tests/ui/redundant_else.rs:19:10\n   |\nLL |           } else {\n   |  __________^\nLL | |\nLL | |\nLL | |             println!(\"shall rise up with fleas.\");\nLL | |         }\n   | |_________^\n   |\nhelp: remove the `else` block and move the contents out\n   |\nLL ~         }\nLL +\nLL + \nLL +         println!(\"shall rise up with fleas.\");\n   |\n\nerror: redundant else block\n  --> tests/ui/redundant_else.rs:30:10\n   |\nLL |           } else {\n   |  __________^\nLL | |\nLL | |\nLL | |             println!(\"You may delay, but time will not.\");\nLL | |         }\n   | |_________^\n   |\nhelp: remove the `else` block and move the contents out\n   |\nLL ~         }\nLL +\nLL + \nLL +         println!(\"You may delay, but time will not.\");\n   |\n\nerror: redundant else block\n  --> tests/ui/redundant_else.rs:41:6\n   |\nLL |       } else {\n   |  ______^\nLL | |\nLL | |\nLL | |         println!(\"A fat kitchen makes a lean will.\");\nLL | |     }\n   | |_____^\n   |\nhelp: remove the `else` block and move the contents out\n   |\nLL ~     }\nLL +\nLL + \nLL +     println!(\"A fat kitchen makes a lean will.\");\n   |\n\nerror: redundant else block\n  --> tests/ui/redundant_else.rs:50:10\n   |\nLL |           } else {\n   |  __________^\nLL | |\nLL | |\nLL | |             1\nLL | |         }\n   | |_________^\n   |\nhelp: remove the `else` block and move the contents out\n   |\nLL ~         }\nLL +\nLL + \nLL +         1\n   |\n\nerror: redundant else block\n  --> tests/ui/redundant_else.rs:62:10\n   |\nLL |           } else {\n   |  __________^\nLL | |\nLL | |\nLL | |             2\nLL | |         }\n   | |_________^\n   |\nhelp: remove the `else` block and move the contents out\n   |\nLL ~         }\nLL +\nLL + \nLL +         2\n   |\n\nerror: redundant else block\n  --> tests/ui/redundant_else.rs:73:10\n   |\nLL |           } else {\n   |  __________^\nLL | |\nLL | |\nLL | |             1\nLL | |         }\n   | |_________^\n   |\nhelp: remove the `else` block and move the contents out\n   |\nLL ~         }\nLL +\nLL + \nLL +         1\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_field_names.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::redundant_field_names)]\n#![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)]\n\n#[macro_use]\nextern crate proc_macros;\n\nuse std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};\n\nmod foo {\n    pub const BAR: u8 = 0;\n}\n\nstruct Person {\n    gender: u8,\n    age: u8,\n    name: u8,\n    buzz: u64,\n    foo: u8,\n}\n\npub struct S {\n    v: usize,\n}\n\nfn main() {\n    let gender: u8 = 42;\n    let age = 0;\n    let fizz: u64 = 0;\n    let name: u8 = 0;\n\n    let me = Person {\n        gender,\n        //~^ redundant_field_names\n        age,\n        //~^ redundant_field_names\n        name,          //should be ok\n        buzz: fizz,    //should be ok\n        foo: foo::BAR, //should be ok\n    };\n\n    // Range expressions\n    let (start, end) = (0, 0);\n\n    let _ = start..;\n    let _ = ..end;\n    let _ = start..end;\n\n    let _ = ..=end;\n    let _ = start..=end;\n\n    // Issue #2799\n    let _: Vec<_> = (start..end).collect();\n\n    // hand-written Range family structs are linted\n    let _ = RangeFrom { start };\n    //~^ redundant_field_names\n    let _ = RangeTo { end };\n    //~^ redundant_field_names\n    let _ = Range { start, end };\n    //~^ redundant_field_names\n    //~| redundant_field_names\n    let _ = RangeInclusive::new(start, end);\n    let _ = RangeToInclusive { end };\n    //~^ redundant_field_names\n\n    external! {\n        let v = 1;\n        let _ = S {\n            v: v\n        };\n    }\n\n    let v = 2;\n    macro_rules! internal {\n        ($i:ident) => {\n            let _ = S { v };\n            //~^ redundant_field_names\n            let _ = S { $i: v };\n            let _ = S { v: $i };\n            let _ = S { $i: $i };\n        };\n    }\n    internal!(v);\n}\n\nfn issue_3476() {\n    fn foo<T>() {}\n\n    struct S {\n        foo: fn(),\n    }\n\n    S { foo: foo::<i32> };\n}\n\n#[clippy::msrv = \"1.16\"]\nfn msrv_1_16() {\n    let start = 0;\n    let _ = RangeFrom { start: start };\n}\n\n#[clippy::msrv = \"1.17\"]\nfn msrv_1_17() {\n    let start = 0;\n    let _ = RangeFrom { start };\n    //~^ redundant_field_names\n}\n"
  },
  {
    "path": "tests/ui/redundant_field_names.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::redundant_field_names)]\n#![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)]\n\n#[macro_use]\nextern crate proc_macros;\n\nuse std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};\n\nmod foo {\n    pub const BAR: u8 = 0;\n}\n\nstruct Person {\n    gender: u8,\n    age: u8,\n    name: u8,\n    buzz: u64,\n    foo: u8,\n}\n\npub struct S {\n    v: usize,\n}\n\nfn main() {\n    let gender: u8 = 42;\n    let age = 0;\n    let fizz: u64 = 0;\n    let name: u8 = 0;\n\n    let me = Person {\n        gender: gender,\n        //~^ redundant_field_names\n        age: age,\n        //~^ redundant_field_names\n        name,          //should be ok\n        buzz: fizz,    //should be ok\n        foo: foo::BAR, //should be ok\n    };\n\n    // Range expressions\n    let (start, end) = (0, 0);\n\n    let _ = start..;\n    let _ = ..end;\n    let _ = start..end;\n\n    let _ = ..=end;\n    let _ = start..=end;\n\n    // Issue #2799\n    let _: Vec<_> = (start..end).collect();\n\n    // hand-written Range family structs are linted\n    let _ = RangeFrom { start: start };\n    //~^ redundant_field_names\n    let _ = RangeTo { end: end };\n    //~^ redundant_field_names\n    let _ = Range { start: start, end: end };\n    //~^ redundant_field_names\n    //~| redundant_field_names\n    let _ = RangeInclusive::new(start, end);\n    let _ = RangeToInclusive { end: end };\n    //~^ redundant_field_names\n\n    external! {\n        let v = 1;\n        let _ = S {\n            v: v\n        };\n    }\n\n    let v = 2;\n    macro_rules! internal {\n        ($i:ident) => {\n            let _ = S { v: v };\n            //~^ redundant_field_names\n            let _ = S { $i: v };\n            let _ = S { v: $i };\n            let _ = S { $i: $i };\n        };\n    }\n    internal!(v);\n}\n\nfn issue_3476() {\n    fn foo<T>() {}\n\n    struct S {\n        foo: fn(),\n    }\n\n    S { foo: foo::<i32> };\n}\n\n#[clippy::msrv = \"1.16\"]\nfn msrv_1_16() {\n    let start = 0;\n    let _ = RangeFrom { start: start };\n}\n\n#[clippy::msrv = \"1.17\"]\nfn msrv_1_17() {\n    let start = 0;\n    let _ = RangeFrom { start: start };\n    //~^ redundant_field_names\n}\n"
  },
  {
    "path": "tests/ui/redundant_field_names.stderr",
    "content": "error: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:33:9\n   |\nLL |         gender: gender,\n   |         ^^^^^^^^^^^^^^ help: replace it with: `gender`\n   |\n   = note: `-D clippy::redundant-field-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_field_names)]`\n\nerror: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:35:9\n   |\nLL |         age: age,\n   |         ^^^^^^^^ help: replace it with: `age`\n\nerror: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:56:25\n   |\nLL |     let _ = RangeFrom { start: start };\n   |                         ^^^^^^^^^^^^ help: replace it with: `start`\n\nerror: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:58:23\n   |\nLL |     let _ = RangeTo { end: end };\n   |                       ^^^^^^^^ help: replace it with: `end`\n\nerror: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:60:21\n   |\nLL |     let _ = Range { start: start, end: end };\n   |                     ^^^^^^^^^^^^ help: replace it with: `start`\n\nerror: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:60:35\n   |\nLL |     let _ = Range { start: start, end: end };\n   |                                   ^^^^^^^^ help: replace it with: `end`\n\nerror: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:64:32\n   |\nLL |     let _ = RangeToInclusive { end: end };\n   |                                ^^^^^^^^ help: replace it with: `end`\n\nerror: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:77:25\n   |\nLL |             let _ = S { v: v };\n   |                         ^^^^ help: replace it with: `v`\n...\nLL |     internal!(v);\n   |     ------------ in this macro invocation\n   |\n   = note: this error originates in the macro `internal` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: redundant field names in struct initialization\n  --> tests/ui/redundant_field_names.rs:106:25\n   |\nLL |     let _ = RangeFrom { start: start };\n   |                         ^^^^^^^^^^^^ help: replace it with: `start`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_guards.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::no_effect, unused, clippy::single_match, invalid_nan_comparisons)]\n#![warn(clippy::redundant_guards)]\n\n#[macro_use]\nextern crate proc_macros;\n\nstruct A(u32);\n\nstruct B {\n    e: Option<A>,\n}\n\nstruct C(u32, u32);\n\n#[derive(PartialEq)]\nstruct FloatWrapper(f32);\n\nfn issue11304() {\n    match 0.1 {\n        0.0 => todo!(),\n        //~^ redundant_guards\n        // Pattern matching NAN is illegal\n        x if x == f64::NAN => todo!(),\n        _ => todo!(),\n    }\n    match FloatWrapper(0.1) {\n        FloatWrapper(0.0) => todo!(),\n        //~^ redundant_guards\n        _ => todo!(),\n    }\n}\n\nfn issue13681() {\n    match c\"hi\" {\n        x if x == c\"hi\" => (),\n        _ => (),\n    }\n}\n\nfn main() {\n    let c = C(1, 2);\n    match c {\n        C(x, 1) => ..,\n        //~^ redundant_guards\n        _ => todo!(),\n    };\n\n    let x = Some(Some(1));\n    match x {\n        Some(Some(1)) if true => ..,\n        //~^ redundant_guards\n        Some(Some(1)) => {\n            //~^ redundant_guards\n            println!(\"a\");\n            ..\n        },\n        Some(Some(1)) => ..,\n        //~^ redundant_guards\n        Some(Some(2)) => ..,\n        //~^ redundant_guards\n        Some(Some(2)) => ..,\n        //~^ redundant_guards\n        // Don't lint, since x is used in the body\n        Some(x) if let Some(1) = x => {\n            x;\n            ..\n        },\n        _ => todo!(),\n    };\n    let y = 1;\n    match x {\n        // Don't inline these, since y is not from the pat\n        Some(x) if matches!(y, 1 if true) => ..,\n        Some(x) if let 1 = y => ..,\n        Some(x) if y == 2 => ..,\n        Some(x) if 2 == y => ..,\n        _ => todo!(),\n    };\n    let a = A(1);\n    match a {\n        _ if a.0 == 1 => {},\n        _ if 1 == a.0 => {},\n        _ => todo!(),\n    }\n    let b = B { e: Some(A(0)) };\n    match b {\n        B { e: Some(A(2)) } => ..,\n        //~^ redundant_guards\n        _ => todo!(),\n    };\n    // Do not lint, since we cannot represent this as a pattern (at least, without a conversion)\n    let v = Some(vec![1u8, 2, 3]);\n    match v {\n        Some(x) if x == [1] => {},\n        _ => {},\n    }\n\n    external! {\n        let x = Some(Some(1));\n        match x {\n            Some(x) if let Some(1) = x => ..,\n            _ => todo!(),\n        };\n    }\n    with_span! {\n        span\n        let x = Some(Some(1));\n        match x {\n            Some(x) if let Some(1) = x => ..,\n            _ => todo!(),\n        };\n    }\n}\n\nenum E {\n    A(&'static str),\n    B(&'static str),\n    C(&'static str),\n}\n\nfn i() {\n    match E::A(\"\") {\n        // Do not lint\n        E::A(x) | E::B(x) | E::C(x) if x == \"from an or pattern\" => {},\n        E::A(\"not from an or pattern\") => {},\n        //~^ redundant_guards\n        _ => {},\n    };\n}\n\nfn h(v: Option<u32>) {\n    match v {\n        Some(0) => ..,\n        //~^ redundant_guards\n        _ => ..,\n    };\n}\n\nfn negative_literal(i: i32) {\n    match i {\n        -1 => {},\n        //~^ redundant_guards\n        1 => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n}\n\n// Do not lint\n\nfn f(s: Option<std::ffi::OsString>) {\n    match s {\n        Some(x) if x == \"a\" => {},\n        Some(x) if \"a\" == x => {},\n        _ => {},\n    }\n}\n\nfn not_matches() {\n    match Some(42) {\n        // The pattern + guard is not equivalent to `Some(42)` because of the `panic!`\n        Some(v)\n            if match v {\n                42 => true,\n                _ => panic!(),\n            } => {},\n        _ => {},\n    }\n}\n\nstruct S {\n    a: usize,\n}\n\nimpl PartialEq for S {\n    fn eq(&self, _: &Self) -> bool {\n        true\n    }\n}\n\nimpl Eq for S {}\n\nstatic CONST_S: S = S { a: 1 };\n\nfn g(opt_s: Option<S>) {\n    match opt_s {\n        Some(x) if x == CONST_S => {},\n        Some(x) if CONST_S == x => {},\n        _ => {},\n    }\n}\n\nmod issue11465 {\n    enum A {\n        Foo([u8; 3]),\n    }\n\n    struct B {\n        b: String,\n        c: i32,\n    }\n\n    fn issue11465() {\n        let c = Some(1);\n        match c {\n            Some(1) => {},\n            //~^ redundant_guards\n            Some(1) => {},\n            //~^ redundant_guards\n            Some(2) => {},\n            //~^ redundant_guards\n            Some(3) => {},\n            //~^ redundant_guards\n            _ => {},\n        };\n\n        let enum_a = A::Foo([98, 97, 114]);\n        match enum_a {\n            A::Foo(ref arr) if arr == b\"foo\" => {},\n            A::Foo(ref arr) if b\"foo\" == arr => {},\n            A::Foo(ref arr) if let b\"bar\" = arr => {},\n            A::Foo(ref arr) if matches!(arr, b\"baz\") => {},\n            _ => {},\n        };\n\n        let struct_b = B {\n            b: \"bar\".to_string(),\n            c: 42,\n        };\n        match struct_b {\n            B { ref b, .. } if b == \"bar\" => {},\n            B { ref b, .. } if \"bar\" == b => {},\n            B { c: 1, .. } => {},\n            //~^ redundant_guards\n            B { c: 1, .. } => {},\n            //~^ redundant_guards\n            B { c: 1, .. } => {},\n            //~^ redundant_guards\n            B { c: 1, .. } => {},\n            //~^ redundant_guards\n            _ => {},\n        }\n    }\n}\n\nfn issue11807() {\n    #![allow(clippy::single_match)]\n\n    match Some(Some(\"\")) {\n        Some(Some(\"\")) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(String::new())) {\n        // Do not lint: String deref-coerces to &str\n        Some(Some(x)) if x.is_empty() => {},\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some([])) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some([] as [i32; 0])) {\n        Some(Some([])) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(Vec::<()>::new())) {\n        // Do not lint: Vec deref-coerces to &[T]\n        Some(Some(x)) if x.is_empty() => {},\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some([..])) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some([1, ..])) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some([1, 2, ..])) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some([.., 1, 2])) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(Vec::<i32>::new())) {\n        // Do not lint: deref coercion\n        Some(Some(x)) if x.starts_with(&[1, 2]) => {},\n        _ => {},\n    }\n}\n\nmod issue12243 {\n    pub const fn const_fn(x: &str) {\n        match x {\n            // Shouldn't lint.\n            y if y.is_empty() => {},\n            _ => {},\n        }\n    }\n\n    pub fn non_const_fn(x: &str) {\n        match x {\n            \"\" => {},\n            //~^ ERROR: redundant guard\n            _ => {},\n        }\n    }\n\n    struct Bar;\n\n    impl Bar {\n        pub const fn const_bar(x: &str) {\n            match x {\n                // Shouldn't lint.\n                y if y.is_empty() => {},\n                _ => {},\n            }\n        }\n\n        pub fn non_const_bar(x: &str) {\n            match x {\n                \"\" => {},\n                //~^ ERROR: redundant guard\n                _ => {},\n            }\n        }\n    }\n\n    static FOO: () = {\n        match \"\" {\n            // Shouldn't lint.\n            x if x.is_empty() => {},\n            _ => {},\n        }\n    };\n}\n"
  },
  {
    "path": "tests/ui/redundant_guards.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::no_effect, unused, clippy::single_match, invalid_nan_comparisons)]\n#![warn(clippy::redundant_guards)]\n\n#[macro_use]\nextern crate proc_macros;\n\nstruct A(u32);\n\nstruct B {\n    e: Option<A>,\n}\n\nstruct C(u32, u32);\n\n#[derive(PartialEq)]\nstruct FloatWrapper(f32);\n\nfn issue11304() {\n    match 0.1 {\n        x if x == 0.0 => todo!(),\n        //~^ redundant_guards\n        // Pattern matching NAN is illegal\n        x if x == f64::NAN => todo!(),\n        _ => todo!(),\n    }\n    match FloatWrapper(0.1) {\n        x if x == FloatWrapper(0.0) => todo!(),\n        //~^ redundant_guards\n        _ => todo!(),\n    }\n}\n\nfn issue13681() {\n    match c\"hi\" {\n        x if x == c\"hi\" => (),\n        _ => (),\n    }\n}\n\nfn main() {\n    let c = C(1, 2);\n    match c {\n        C(x, y) if let 1 = y => ..,\n        //~^ redundant_guards\n        _ => todo!(),\n    };\n\n    let x = Some(Some(1));\n    match x {\n        Some(x) if matches!(x, Some(1) if true) => ..,\n        //~^ redundant_guards\n        Some(x) if matches!(x, Some(1)) => {\n            //~^ redundant_guards\n            println!(\"a\");\n            ..\n        },\n        Some(x) if let Some(1) = x => ..,\n        //~^ redundant_guards\n        Some(x) if x == Some(2) => ..,\n        //~^ redundant_guards\n        Some(x) if Some(2) == x => ..,\n        //~^ redundant_guards\n        // Don't lint, since x is used in the body\n        Some(x) if let Some(1) = x => {\n            x;\n            ..\n        },\n        _ => todo!(),\n    };\n    let y = 1;\n    match x {\n        // Don't inline these, since y is not from the pat\n        Some(x) if matches!(y, 1 if true) => ..,\n        Some(x) if let 1 = y => ..,\n        Some(x) if y == 2 => ..,\n        Some(x) if 2 == y => ..,\n        _ => todo!(),\n    };\n    let a = A(1);\n    match a {\n        _ if a.0 == 1 => {},\n        _ if 1 == a.0 => {},\n        _ => todo!(),\n    }\n    let b = B { e: Some(A(0)) };\n    match b {\n        B { e } if matches!(e, Some(A(2))) => ..,\n        //~^ redundant_guards\n        _ => todo!(),\n    };\n    // Do not lint, since we cannot represent this as a pattern (at least, without a conversion)\n    let v = Some(vec![1u8, 2, 3]);\n    match v {\n        Some(x) if x == [1] => {},\n        _ => {},\n    }\n\n    external! {\n        let x = Some(Some(1));\n        match x {\n            Some(x) if let Some(1) = x => ..,\n            _ => todo!(),\n        };\n    }\n    with_span! {\n        span\n        let x = Some(Some(1));\n        match x {\n            Some(x) if let Some(1) = x => ..,\n            _ => todo!(),\n        };\n    }\n}\n\nenum E {\n    A(&'static str),\n    B(&'static str),\n    C(&'static str),\n}\n\nfn i() {\n    match E::A(\"\") {\n        // Do not lint\n        E::A(x) | E::B(x) | E::C(x) if x == \"from an or pattern\" => {},\n        E::A(y) if y == \"not from an or pattern\" => {},\n        //~^ redundant_guards\n        _ => {},\n    };\n}\n\nfn h(v: Option<u32>) {\n    match v {\n        x if matches!(x, Some(0)) => ..,\n        //~^ redundant_guards\n        _ => ..,\n    };\n}\n\nfn negative_literal(i: i32) {\n    match i {\n        i if i == -1 => {},\n        //~^ redundant_guards\n        i if i == 1 => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n}\n\n// Do not lint\n\nfn f(s: Option<std::ffi::OsString>) {\n    match s {\n        Some(x) if x == \"a\" => {},\n        Some(x) if \"a\" == x => {},\n        _ => {},\n    }\n}\n\nfn not_matches() {\n    match Some(42) {\n        // The pattern + guard is not equivalent to `Some(42)` because of the `panic!`\n        Some(v)\n            if match v {\n                42 => true,\n                _ => panic!(),\n            } => {},\n        _ => {},\n    }\n}\n\nstruct S {\n    a: usize,\n}\n\nimpl PartialEq for S {\n    fn eq(&self, _: &Self) -> bool {\n        true\n    }\n}\n\nimpl Eq for S {}\n\nstatic CONST_S: S = S { a: 1 };\n\nfn g(opt_s: Option<S>) {\n    match opt_s {\n        Some(x) if x == CONST_S => {},\n        Some(x) if CONST_S == x => {},\n        _ => {},\n    }\n}\n\nmod issue11465 {\n    enum A {\n        Foo([u8; 3]),\n    }\n\n    struct B {\n        b: String,\n        c: i32,\n    }\n\n    fn issue11465() {\n        let c = Some(1);\n        match c {\n            Some(ref x) if x == &1 => {},\n            //~^ redundant_guards\n            Some(ref x) if &1 == x => {},\n            //~^ redundant_guards\n            Some(ref x) if let &2 = x => {},\n            //~^ redundant_guards\n            Some(ref x) if matches!(x, &3) => {},\n            //~^ redundant_guards\n            _ => {},\n        };\n\n        let enum_a = A::Foo([98, 97, 114]);\n        match enum_a {\n            A::Foo(ref arr) if arr == b\"foo\" => {},\n            A::Foo(ref arr) if b\"foo\" == arr => {},\n            A::Foo(ref arr) if let b\"bar\" = arr => {},\n            A::Foo(ref arr) if matches!(arr, b\"baz\") => {},\n            _ => {},\n        };\n\n        let struct_b = B {\n            b: \"bar\".to_string(),\n            c: 42,\n        };\n        match struct_b {\n            B { ref b, .. } if b == \"bar\" => {},\n            B { ref b, .. } if \"bar\" == b => {},\n            B { ref c, .. } if c == &1 => {},\n            //~^ redundant_guards\n            B { ref c, .. } if &1 == c => {},\n            //~^ redundant_guards\n            B { ref c, .. } if let &1 = c => {},\n            //~^ redundant_guards\n            B { ref c, .. } if matches!(c, &1) => {},\n            //~^ redundant_guards\n            _ => {},\n        }\n    }\n}\n\nfn issue11807() {\n    #![allow(clippy::single_match)]\n\n    match Some(Some(\"\")) {\n        Some(Some(x)) if x.is_empty() => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(String::new())) {\n        // Do not lint: String deref-coerces to &str\n        Some(Some(x)) if x.is_empty() => {},\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some(x)) if x.is_empty() => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some([] as [i32; 0])) {\n        Some(Some(x)) if x.is_empty() => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(Vec::<()>::new())) {\n        // Do not lint: Vec deref-coerces to &[T]\n        Some(Some(x)) if x.is_empty() => {},\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some(x)) if x.starts_with(&[]) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some(x)) if x.starts_with(&[1]) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some(x)) if x.starts_with(&[1, 2]) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(&[] as &[i32])) {\n        Some(Some(x)) if x.ends_with(&[1, 2]) => {},\n        //~^ redundant_guards\n        _ => {},\n    }\n\n    match Some(Some(Vec::<i32>::new())) {\n        // Do not lint: deref coercion\n        Some(Some(x)) if x.starts_with(&[1, 2]) => {},\n        _ => {},\n    }\n}\n\nmod issue12243 {\n    pub const fn const_fn(x: &str) {\n        match x {\n            // Shouldn't lint.\n            y if y.is_empty() => {},\n            _ => {},\n        }\n    }\n\n    pub fn non_const_fn(x: &str) {\n        match x {\n            y if y.is_empty() => {},\n            //~^ ERROR: redundant guard\n            _ => {},\n        }\n    }\n\n    struct Bar;\n\n    impl Bar {\n        pub const fn const_bar(x: &str) {\n            match x {\n                // Shouldn't lint.\n                y if y.is_empty() => {},\n                _ => {},\n            }\n        }\n\n        pub fn non_const_bar(x: &str) {\n            match x {\n                y if y.is_empty() => {},\n                //~^ ERROR: redundant guard\n                _ => {},\n            }\n        }\n    }\n\n    static FOO: () = {\n        match \"\" {\n            // Shouldn't lint.\n            x if x.is_empty() => {},\n            _ => {},\n        }\n    };\n}\n"
  },
  {
    "path": "tests/ui/redundant_guards.stderr",
    "content": "error: redundant guard\n  --> tests/ui/redundant_guards.rs:21:14\n   |\nLL |         x if x == 0.0 => todo!(),\n   |              ^^^^^^^^\n   |\n   = note: `-D clippy::redundant-guards` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_guards)]`\nhelp: try\n   |\nLL -         x if x == 0.0 => todo!(),\nLL +         0.0 => todo!(),\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:28:14\n   |\nLL |         x if x == FloatWrapper(0.0) => todo!(),\n   |              ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         x if x == FloatWrapper(0.0) => todo!(),\nLL +         FloatWrapper(0.0) => todo!(),\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:44:20\n   |\nLL |         C(x, y) if let 1 = y => ..,\n   |                    ^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         C(x, y) if let 1 = y => ..,\nLL +         C(x, 1) => ..,\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:51:20\n   |\nLL |         Some(x) if matches!(x, Some(1) if true) => ..,\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(x) if matches!(x, Some(1) if true) => ..,\nLL +         Some(Some(1)) if true => ..,\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:53:20\n   |\nLL |         Some(x) if matches!(x, Some(1)) => {\n   |                    ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(x) if matches!(x, Some(1)) => {\nLL +         Some(Some(1)) => {\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:58:20\n   |\nLL |         Some(x) if let Some(1) = x => ..,\n   |                    ^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(x) if let Some(1) = x => ..,\nLL +         Some(Some(1)) => ..,\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:60:20\n   |\nLL |         Some(x) if x == Some(2) => ..,\n   |                    ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(x) if x == Some(2) => ..,\nLL +         Some(Some(2)) => ..,\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:62:20\n   |\nLL |         Some(x) if Some(2) == x => ..,\n   |                    ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(x) if Some(2) == x => ..,\nLL +         Some(Some(2)) => ..,\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:88:20\n   |\nLL |         B { e } if matches!(e, Some(A(2))) => ..,\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         B { e } if matches!(e, Some(A(2))) => ..,\nLL +         B { e: Some(A(2)) } => ..,\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:126:20\n   |\nLL |         E::A(y) if y == \"not from an or pattern\" => {},\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         E::A(y) if y == \"not from an or pattern\" => {},\nLL +         E::A(\"not from an or pattern\") => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:134:14\n   |\nLL |         x if matches!(x, Some(0)) => ..,\n   |              ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         x if matches!(x, Some(0)) => ..,\nLL +         Some(0) => ..,\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:142:14\n   |\nLL |         i if i == -1 => {},\n   |              ^^^^^^^\n   |\nhelp: try\n   |\nLL -         i if i == -1 => {},\nLL +         -1 => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:144:14\n   |\nLL |         i if i == 1 => {},\n   |              ^^^^^^\n   |\nhelp: try\n   |\nLL -         i if i == 1 => {},\nLL +         1 => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:207:28\n   |\nLL |             Some(ref x) if x == &1 => {},\n   |                            ^^^^^^^\n   |\nhelp: try\n   |\nLL -             Some(ref x) if x == &1 => {},\nLL +             Some(1) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:209:28\n   |\nLL |             Some(ref x) if &1 == x => {},\n   |                            ^^^^^^^\n   |\nhelp: try\n   |\nLL -             Some(ref x) if &1 == x => {},\nLL +             Some(1) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:211:28\n   |\nLL |             Some(ref x) if let &2 = x => {},\n   |                            ^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -             Some(ref x) if let &2 = x => {},\nLL +             Some(2) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:213:28\n   |\nLL |             Some(ref x) if matches!(x, &3) => {},\n   |                            ^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -             Some(ref x) if matches!(x, &3) => {},\nLL +             Some(3) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:234:32\n   |\nLL |             B { ref c, .. } if c == &1 => {},\n   |                                ^^^^^^^\n   |\nhelp: try\n   |\nLL -             B { ref c, .. } if c == &1 => {},\nLL +             B { c: 1, .. } => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:236:32\n   |\nLL |             B { ref c, .. } if &1 == c => {},\n   |                                ^^^^^^^\n   |\nhelp: try\n   |\nLL -             B { ref c, .. } if &1 == c => {},\nLL +             B { c: 1, .. } => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:238:32\n   |\nLL |             B { ref c, .. } if let &1 = c => {},\n   |                                ^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -             B { ref c, .. } if let &1 = c => {},\nLL +             B { c: 1, .. } => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:240:32\n   |\nLL |             B { ref c, .. } if matches!(c, &1) => {},\n   |                                ^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -             B { ref c, .. } if matches!(c, &1) => {},\nLL +             B { c: 1, .. } => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:251:26\n   |\nLL |         Some(Some(x)) if x.is_empty() => {},\n   |                          ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(Some(x)) if x.is_empty() => {},\nLL +         Some(Some(\"\")) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:263:26\n   |\nLL |         Some(Some(x)) if x.is_empty() => {},\n   |                          ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(Some(x)) if x.is_empty() => {},\nLL +         Some(Some([])) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:269:26\n   |\nLL |         Some(Some(x)) if x.is_empty() => {},\n   |                          ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(Some(x)) if x.is_empty() => {},\nLL +         Some(Some([])) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:281:26\n   |\nLL |         Some(Some(x)) if x.starts_with(&[]) => {},\n   |                          ^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(Some(x)) if x.starts_with(&[]) => {},\nLL +         Some(Some([..])) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:287:26\n   |\nLL |         Some(Some(x)) if x.starts_with(&[1]) => {},\n   |                          ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(Some(x)) if x.starts_with(&[1]) => {},\nLL +         Some(Some([1, ..])) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:293:26\n   |\nLL |         Some(Some(x)) if x.starts_with(&[1, 2]) => {},\n   |                          ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(Some(x)) if x.starts_with(&[1, 2]) => {},\nLL +         Some(Some([1, 2, ..])) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:299:26\n   |\nLL |         Some(Some(x)) if x.ends_with(&[1, 2]) => {},\n   |                          ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         Some(Some(x)) if x.ends_with(&[1, 2]) => {},\nLL +         Some(Some([.., 1, 2])) => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:322:18\n   |\nLL |             y if y.is_empty() => {},\n   |                  ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -             y if y.is_empty() => {},\nLL +             \"\" => {},\n   |\n\nerror: redundant guard\n  --> tests/ui/redundant_guards.rs:341:22\n   |\nLL |                 y if y.is_empty() => {},\n   |                      ^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -                 y if y.is_empty() => {},\nLL +                 \"\" => {},\n   |\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_locals.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)]\n#![warn(clippy::redundant_locals)]\n#![feature(coroutines, stmt_expr_attributes)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nfn main() {}\n\nfn immutable() {\n    let x = 1;\n    let x = x;\n    //~^ redundant_locals\n}\n\nfn mutable() {\n    let mut x = 1;\n    let mut x = x;\n    //~^ redundant_locals\n}\n\nfn upgraded_mutability() {\n    let x = 1;\n    let mut x = x;\n}\n\nfn downgraded_mutability() {\n    let mut x = 1;\n    let x = x;\n}\n\n// see #11290\nfn shadow_mutation() {\n    let mut x = 1;\n    {\n        let mut x = x;\n        x = 2;\n    }\n}\n\nfn coercion(par: &mut i32) {\n    let par: &i32 = par;\n\n    let x: &mut i32 = &mut 1;\n    let x: &i32 = x;\n}\n\nfn parameter(x: i32) {\n    let x = x;\n    //~^ redundant_locals\n}\n\nfn many() {\n    let x = 1;\n    let x = x;\n    //~^ redundant_locals\n    let x = x;\n    //~^ redundant_locals\n    let x = x;\n    //~^ redundant_locals\n    let x = x;\n    //~^ redundant_locals\n}\n\nfn interleaved() {\n    let a = 1;\n    let b = 2;\n    let a = a;\n    //~^ redundant_locals\n    let b = b;\n    //~^ redundant_locals\n}\n\nfn block() {\n    {\n        let x = 1;\n        let x = x;\n        //~^ redundant_locals\n    }\n}\n\nfn closure() {\n    || {\n        let x = 1;\n        let x = x;\n        //~^ redundant_locals\n    };\n    |x: i32| {\n        let x = x;\n        //~^ redundant_locals\n    };\n}\n\nfn consequential_drop_order() {\n    use std::sync::Mutex;\n\n    let mutex = Mutex::new(1);\n    let guard = mutex.lock().unwrap();\n\n    {\n        let guard = guard;\n    }\n}\n\nfn inconsequential_drop_order() {\n    let x = 1;\n\n    {\n        let x = x;\n        //~^ redundant_locals\n    }\n}\n\nfn macros() {\n    macro_rules! rebind {\n        ($x:ident) => {\n            let $x = 1;\n            let $x = $x;\n        };\n    }\n\n    rebind!(x);\n\n    external! {\n        let x = 1;\n        let x = x;\n    }\n    with_span! {\n        span\n        let x = 1;\n        let x = x;\n    }\n\n    let x = 10;\n    macro_rules! rebind_outer_macro {\n        ($x:ident) => {\n            let x = x;\n        };\n    }\n    rebind_outer_macro!(y);\n}\n\nstruct WithDrop(usize);\nimpl Drop for WithDrop {\n    fn drop(&mut self) {}\n}\n\nstruct InnerDrop(WithDrop);\n\nstruct ComposeDrop {\n    d: WithDrop,\n}\n\nstruct WithoutDrop(usize);\n\nfn drop_trait() {\n    let a = WithDrop(1);\n    let b = WithDrop(2);\n    let a = a;\n}\n\nfn without_drop() {\n    let a = WithoutDrop(1);\n    let b = WithoutDrop(2);\n    let a = a;\n    //~^ redundant_locals\n}\n\nfn drop_inner() {\n    let a = InnerDrop(WithDrop(1));\n    let b = InnerDrop(WithDrop(2));\n    let a = a;\n}\n\nfn drop_compose() {\n    let a = ComposeDrop { d: WithDrop(1) };\n    let b = ComposeDrop { d: WithDrop(1) };\n    let a = a;\n}\n\nfn issue12225() {\n    fn assert_static<T: 'static>(_: T) {}\n\n    let v1 = String::new();\n    let v2 = String::new();\n    let v3 = String::new();\n    let v4 = String::new();\n    let v5 = String::new();\n    let v6 = String::new();\n\n    assert_static(|| {\n        let v1 = v1;\n        dbg!(&v1);\n    });\n    assert_static(async {\n        let v2 = v2;\n        dbg!(&v2);\n    });\n    assert_static(|| async {\n        let v3 = v3;\n        dbg!(&v3);\n    });\n    assert_static(async || {\n        let v4 = v4;\n        dbg!(&v4);\n    });\n    assert_static(\n        #[coroutine]\n        static || {\n            let v5 = v5;\n            yield;\n        },\n    );\n    assert_static(\n        #[coroutine]\n        || {\n            let v6 = v6;\n            yield;\n        },\n    );\n\n    fn foo(a: &str, b: &str) {}\n\n    let do_not_move = String::new();\n    let things_to_move = vec![\"a\".to_string(), \"b\".to_string()];\n    let futures = things_to_move.into_iter().map(|move_me| async {\n        let move_me = move_me;\n        foo(&do_not_move, &move_me)\n    });\n}\n"
  },
  {
    "path": "tests/ui/redundant_locals.stderr",
    "content": "error: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:13:5\n   |\nLL |     let x = x;\n   |     ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:12:9\n   |\nLL |     let x = 1;\n   |         ^\n   = note: `-D clippy::redundant-locals` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_locals)]`\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:19:5\n   |\nLL |     let mut x = x;\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:18:9\n   |\nLL |     let mut x = 1;\n   |         ^^^^^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:50:5\n   |\nLL |     let x = x;\n   |     ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:49:14\n   |\nLL | fn parameter(x: i32) {\n   |              ^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:56:5\n   |\nLL |     let x = x;\n   |     ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:55:9\n   |\nLL |     let x = 1;\n   |         ^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:58:5\n   |\nLL |     let x = x;\n   |     ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:56:9\n   |\nLL |     let x = x;\n   |         ^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:60:5\n   |\nLL |     let x = x;\n   |     ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:58:9\n   |\nLL |     let x = x;\n   |         ^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:62:5\n   |\nLL |     let x = x;\n   |     ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:60:9\n   |\nLL |     let x = x;\n   |         ^\n\nerror: redundant redefinition of a binding `a`\n  --> tests/ui/redundant_locals.rs:69:5\n   |\nLL |     let a = a;\n   |     ^^^^^^^^^^\n   |\nhelp: `a` is initially defined here\n  --> tests/ui/redundant_locals.rs:67:9\n   |\nLL |     let a = 1;\n   |         ^\n\nerror: redundant redefinition of a binding `b`\n  --> tests/ui/redundant_locals.rs:71:5\n   |\nLL |     let b = b;\n   |     ^^^^^^^^^^\n   |\nhelp: `b` is initially defined here\n  --> tests/ui/redundant_locals.rs:68:9\n   |\nLL |     let b = 2;\n   |         ^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:78:9\n   |\nLL |         let x = x;\n   |         ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:77:13\n   |\nLL |         let x = 1;\n   |             ^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:86:9\n   |\nLL |         let x = x;\n   |         ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:85:13\n   |\nLL |         let x = 1;\n   |             ^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:90:9\n   |\nLL |         let x = x;\n   |         ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:89:6\n   |\nLL |     |x: i32| {\n   |      ^\n\nerror: redundant redefinition of a binding `x`\n  --> tests/ui/redundant_locals.rs:110:9\n   |\nLL |         let x = x;\n   |         ^^^^^^^^^^\n   |\nhelp: `x` is initially defined here\n  --> tests/ui/redundant_locals.rs:107:9\n   |\nLL |     let x = 1;\n   |         ^\n\nerror: redundant redefinition of a binding `a`\n  --> tests/ui/redundant_locals.rs:166:5\n   |\nLL |     let a = a;\n   |     ^^^^^^^^^^\n   |\nhelp: `a` is initially defined here\n  --> tests/ui/redundant_locals.rs:164:9\n   |\nLL |     let a = WithoutDrop(1);\n   |         ^\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_drop_order.fixed",
    "content": "// Issue #5746\n#![warn(clippy::redundant_pattern_matching)]\n#![allow(\n    clippy::if_same_then_else,\n    clippy::equatable_if_let,\n    clippy::needless_ifs,\n    clippy::needless_else\n)]\nuse std::task::Poll::{Pending, Ready};\n\nfn main() {\n    let m = std::sync::Mutex::new((0, 0));\n\n    // Result\n    if m.lock().is_ok() {}\n    //~^ redundant_pattern_matching\n    if Err::<(), _>(m.lock().unwrap().0).is_err() {}\n    //~^ redundant_pattern_matching\n\n    {\n        if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok() {}\n        //~^ redundant_pattern_matching\n    }\n    if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok() {\n        //~^ redundant_pattern_matching\n    } else {\n    }\n    if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok() {}\n    //~^ redundant_pattern_matching\n    if Err::<std::sync::MutexGuard<()>, _>(()).is_err() {}\n    //~^ redundant_pattern_matching\n\n    if Ok::<_, ()>(String::new()).is_ok() {}\n    //~^ redundant_pattern_matching\n    if Err::<(), _>((String::new(), ())).is_err() {}\n    //~^ redundant_pattern_matching\n\n    // Option\n    if Some(m.lock()).is_some() {}\n    //~^ redundant_pattern_matching\n    if Some(m.lock().unwrap().0).is_some() {}\n    //~^ redundant_pattern_matching\n\n    {\n        if None::<std::sync::MutexGuard<()>>.is_none() {}\n        //~^ redundant_pattern_matching\n    }\n    if None::<std::sync::MutexGuard<()>>.is_none() {\n        //~^ redundant_pattern_matching\n    } else {\n    }\n\n    if None::<std::sync::MutexGuard<()>>.is_none() {}\n    //~^ redundant_pattern_matching\n\n    if Some(String::new()).is_some() {}\n    //~^ redundant_pattern_matching\n    if Some((String::new(), ())).is_some() {}\n    //~^ redundant_pattern_matching\n\n    // Poll\n    if Ready(m.lock()).is_ready() {}\n    //~^ redundant_pattern_matching\n    if Ready(m.lock().unwrap().0).is_ready() {}\n    //~^ redundant_pattern_matching\n\n    {\n        if Pending::<std::sync::MutexGuard<()>>.is_pending() {}\n        //~^ redundant_pattern_matching\n    }\n    if Pending::<std::sync::MutexGuard<()>>.is_pending() {\n        //~^ redundant_pattern_matching\n    } else {\n    }\n\n    if Pending::<std::sync::MutexGuard<()>>.is_pending() {}\n    //~^ redundant_pattern_matching\n\n    if Ready(String::new()).is_ready() {}\n    //~^ redundant_pattern_matching\n    if Ready((String::new(), ())).is_ready() {}\n    //~^ redundant_pattern_matching\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_drop_order.rs",
    "content": "// Issue #5746\n#![warn(clippy::redundant_pattern_matching)]\n#![allow(\n    clippy::if_same_then_else,\n    clippy::equatable_if_let,\n    clippy::needless_ifs,\n    clippy::needless_else\n)]\nuse std::task::Poll::{Pending, Ready};\n\nfn main() {\n    let m = std::sync::Mutex::new((0, 0));\n\n    // Result\n    if let Ok(_) = m.lock() {}\n    //~^ redundant_pattern_matching\n    if let Err(_) = Err::<(), _>(m.lock().unwrap().0) {}\n    //~^ redundant_pattern_matching\n\n    {\n        if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {}\n        //~^ redundant_pattern_matching\n    }\n    if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {\n        //~^ redundant_pattern_matching\n    } else {\n    }\n    if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {}\n    //~^ redundant_pattern_matching\n    if let Err(_) = Err::<std::sync::MutexGuard<()>, _>(()) {}\n    //~^ redundant_pattern_matching\n\n    if let Ok(_) = Ok::<_, ()>(String::new()) {}\n    //~^ redundant_pattern_matching\n    if let Err(_) = Err::<(), _>((String::new(), ())) {}\n    //~^ redundant_pattern_matching\n\n    // Option\n    if let Some(_) = Some(m.lock()) {}\n    //~^ redundant_pattern_matching\n    if let Some(_) = Some(m.lock().unwrap().0) {}\n    //~^ redundant_pattern_matching\n\n    {\n        if let None = None::<std::sync::MutexGuard<()>> {}\n        //~^ redundant_pattern_matching\n    }\n    if let None = None::<std::sync::MutexGuard<()>> {\n        //~^ redundant_pattern_matching\n    } else {\n    }\n\n    if let None = None::<std::sync::MutexGuard<()>> {}\n    //~^ redundant_pattern_matching\n\n    if let Some(_) = Some(String::new()) {}\n    //~^ redundant_pattern_matching\n    if let Some(_) = Some((String::new(), ())) {}\n    //~^ redundant_pattern_matching\n\n    // Poll\n    if let Ready(_) = Ready(m.lock()) {}\n    //~^ redundant_pattern_matching\n    if let Ready(_) = Ready(m.lock().unwrap().0) {}\n    //~^ redundant_pattern_matching\n\n    {\n        if let Pending = Pending::<std::sync::MutexGuard<()>> {}\n        //~^ redundant_pattern_matching\n    }\n    if let Pending = Pending::<std::sync::MutexGuard<()>> {\n        //~^ redundant_pattern_matching\n    } else {\n    }\n\n    if let Pending = Pending::<std::sync::MutexGuard<()>> {}\n    //~^ redundant_pattern_matching\n\n    if let Ready(_) = Ready(String::new()) {}\n    //~^ redundant_pattern_matching\n    if let Ready(_) = Ready((String::new(), ())) {}\n    //~^ redundant_pattern_matching\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_drop_order.stderr",
    "content": "error: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:15:12\n   |\nLL |     if let Ok(_) = m.lock() {}\n   |     -------^^^^^----------- help: try: `if m.lock().is_ok()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:17:12\n   |\nLL |     if let Err(_) = Err::<(), _>(m.lock().unwrap().0) {}\n   |     -------^^^^^^------------------------------------ help: try: `if Err::<(), _>(m.lock().unwrap().0).is_err()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:21:16\n   |\nLL |         if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {}\n   |         -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:24:12\n   |\nLL |     if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {\n   |     -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:28:12\n   |\nLL |     if let Ok(_) = Ok::<_, std::sync::MutexGuard<()>>(()) {}\n   |     -------^^^^^----------------------------------------- help: try: `if Ok::<_, std::sync::MutexGuard<()>>(()).is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:30:12\n   |\nLL |     if let Err(_) = Err::<std::sync::MutexGuard<()>, _>(()) {}\n   |     -------^^^^^^------------------------------------------ help: try: `if Err::<std::sync::MutexGuard<()>, _>(()).is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:33:12\n   |\nLL |     if let Ok(_) = Ok::<_, ()>(String::new()) {}\n   |     -------^^^^^----------------------------- help: try: `if Ok::<_, ()>(String::new()).is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:35:12\n   |\nLL |     if let Err(_) = Err::<(), _>((String::new(), ())) {}\n   |     -------^^^^^^------------------------------------ help: try: `if Err::<(), _>((String::new(), ())).is_err()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:39:12\n   |\nLL |     if let Some(_) = Some(m.lock()) {}\n   |     -------^^^^^^^----------------- help: try: `if Some(m.lock()).is_some()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:41:12\n   |\nLL |     if let Some(_) = Some(m.lock().unwrap().0) {}\n   |     -------^^^^^^^---------------------------- help: try: `if Some(m.lock().unwrap().0).is_some()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:45:16\n   |\nLL |         if let None = None::<std::sync::MutexGuard<()>> {}\n   |         -------^^^^------------------------------------ help: try: `if None::<std::sync::MutexGuard<()>>.is_none()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:48:12\n   |\nLL |     if let None = None::<std::sync::MutexGuard<()>> {\n   |     -------^^^^------------------------------------ help: try: `if None::<std::sync::MutexGuard<()>>.is_none()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:53:12\n   |\nLL |     if let None = None::<std::sync::MutexGuard<()>> {}\n   |     -------^^^^------------------------------------ help: try: `if None::<std::sync::MutexGuard<()>>.is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:56:12\n   |\nLL |     if let Some(_) = Some(String::new()) {}\n   |     -------^^^^^^^---------------------- help: try: `if Some(String::new()).is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:58:12\n   |\nLL |     if let Some(_) = Some((String::new(), ())) {}\n   |     -------^^^^^^^---------------------------- help: try: `if Some((String::new(), ())).is_some()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:62:12\n   |\nLL |     if let Ready(_) = Ready(m.lock()) {}\n   |     -------^^^^^^^^------------------ help: try: `if Ready(m.lock()).is_ready()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:64:12\n   |\nLL |     if let Ready(_) = Ready(m.lock().unwrap().0) {}\n   |     -------^^^^^^^^----------------------------- help: try: `if Ready(m.lock().unwrap().0).is_ready()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:68:16\n   |\nLL |         if let Pending = Pending::<std::sync::MutexGuard<()>> {}\n   |         -------^^^^^^^--------------------------------------- help: try: `if Pending::<std::sync::MutexGuard<()>>.is_pending()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:71:12\n   |\nLL |     if let Pending = Pending::<std::sync::MutexGuard<()>> {\n   |     -------^^^^^^^--------------------------------------- help: try: `if Pending::<std::sync::MutexGuard<()>>.is_pending()`\n   |\n   = note: this will change drop order of the result, as well as all temporaries\n   = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:76:12\n   |\nLL |     if let Pending = Pending::<std::sync::MutexGuard<()>> {}\n   |     -------^^^^^^^--------------------------------------- help: try: `if Pending::<std::sync::MutexGuard<()>>.is_pending()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:79:12\n   |\nLL |     if let Ready(_) = Ready(String::new()) {}\n   |     -------^^^^^^^^----------------------- help: try: `if Ready(String::new()).is_ready()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_drop_order.rs:81:12\n   |\nLL |     if let Ready(_) = Ready((String::new(), ())) {}\n   |     -------^^^^^^^^----------------------------- help: try: `if Ready((String::new(), ())).is_ready()`\n\nerror: aborting due to 22 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_if_let_true.fixed",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(clippy::needless_ifs, clippy::no_effect, clippy::nonminimal_bool)]\n\nmacro_rules! condition {\n    () => {\n        true\n    };\n}\n\nmacro_rules! lettrue {\n    (if) => {\n        if let true = true {}\n    };\n    (while) => {\n        while let true = true {}\n    };\n}\n\nfn main() {\n    let mut k = 5;\n\n    if k > 1 {}\n    //~^ redundant_pattern_matching\n    if !(k > 5) {}\n    //~^ redundant_pattern_matching\n    if k > 1 {}\n    //~^ redundant_pattern_matching\n    if let (true, true) = (k > 1, k > 2) {}\n    while k > 1 {\n        //~^ redundant_pattern_matching\n        k += 1;\n    }\n    while condition!() {\n        //~^ redundant_pattern_matching\n        k += 1;\n    }\n\n    k > 5;\n    //~^ redundant_pattern_matching\n    !(k > 5);\n    //~^ redundant_pattern_matching\n    // Whole loop is from a macro expansion, don't lint:\n    lettrue!(if);\n    lettrue!(while);\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_if_let_true.rs",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(clippy::needless_ifs, clippy::no_effect, clippy::nonminimal_bool)]\n\nmacro_rules! condition {\n    () => {\n        true\n    };\n}\n\nmacro_rules! lettrue {\n    (if) => {\n        if let true = true {}\n    };\n    (while) => {\n        while let true = true {}\n    };\n}\n\nfn main() {\n    let mut k = 5;\n\n    if let true = k > 1 {}\n    //~^ redundant_pattern_matching\n    if let false = k > 5 {}\n    //~^ redundant_pattern_matching\n    if let (true) = k > 1 {}\n    //~^ redundant_pattern_matching\n    if let (true, true) = (k > 1, k > 2) {}\n    while let true = k > 1 {\n        //~^ redundant_pattern_matching\n        k += 1;\n    }\n    while let true = condition!() {\n        //~^ redundant_pattern_matching\n        k += 1;\n    }\n\n    matches!(k > 5, true);\n    //~^ redundant_pattern_matching\n    matches!(k > 5, false);\n    //~^ redundant_pattern_matching\n    // Whole loop is from a macro expansion, don't lint:\n    lettrue!(if);\n    lettrue!(while);\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_if_let_true.stderr",
    "content": "error: using `if let` to pattern match a bool\n  --> tests/ui/redundant_pattern_matching_if_let_true.rs:22:8\n   |\nLL |     if let true = k > 1 {}\n   |        ^^^^^^^^^^^^^^^^ help: consider using the condition directly: `k > 1`\n   |\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: using `if let` to pattern match a bool\n  --> tests/ui/redundant_pattern_matching_if_let_true.rs:24:8\n   |\nLL |     if let false = k > 5 {}\n   |        ^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `!(k > 5)`\n\nerror: using `if let` to pattern match a bool\n  --> tests/ui/redundant_pattern_matching_if_let_true.rs:26:8\n   |\nLL |     if let (true) = k > 1 {}\n   |        ^^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `k > 1`\n\nerror: using `if let` to pattern match a bool\n  --> tests/ui/redundant_pattern_matching_if_let_true.rs:29:11\n   |\nLL |     while let true = k > 1 {\n   |           ^^^^^^^^^^^^^^^^ help: consider using the condition directly: `k > 1`\n\nerror: using `if let` to pattern match a bool\n  --> tests/ui/redundant_pattern_matching_if_let_true.rs:33:11\n   |\nLL |     while let true = condition!() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `condition!()`\n\nerror: using `matches!` to pattern match a bool\n  --> tests/ui/redundant_pattern_matching_if_let_true.rs:38:5\n   |\nLL |     matches!(k > 5, true);\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `k > 5`\n\nerror: using `matches!` to pattern match a bool\n  --> tests/ui/redundant_pattern_matching_if_let_true.rs:40:5\n   |\nLL |     matches!(k > 5, false);\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using the condition directly: `!(k > 5)`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_ipaddr.fixed",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(\n    clippy::match_like_matches_macro,\n    clippy::needless_bool,\n    clippy::needless_ifs,\n    clippy::uninlined_format_args\n)]\n\nuse std::net::IpAddr::{self, V4, V6};\nuse std::net::{Ipv4Addr, Ipv6Addr};\n\nfn main() {\n    let ipaddr: IpAddr = V4(Ipv4Addr::LOCALHOST);\n    if ipaddr.is_ipv4() {}\n    //~^ redundant_pattern_matching\n\n    if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\n    //~^ redundant_pattern_matching\n\n    if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\n    //~^ redundant_pattern_matching\n\n    // Issue 6459\n    if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\n    //~^ redundant_pattern_matching\n\n    // Issue 6459\n    if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\n    //~^ redundant_pattern_matching\n\n    while V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\n    //~^ redundant_pattern_matching\n\n    while V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\n    //~^ redundant_pattern_matching\n\n    if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\n\n    if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\n\n    if let V4(ipaddr) = V4(Ipv4Addr::LOCALHOST) {\n        println!(\"{}\", ipaddr);\n    }\n\n    V4(Ipv4Addr::LOCALHOST).is_ipv4();\n\n    V4(Ipv4Addr::LOCALHOST).is_ipv6();\n\n    V6(Ipv6Addr::LOCALHOST).is_ipv6();\n\n    V6(Ipv6Addr::LOCALHOST).is_ipv4();\n\n    let _ = if V4(Ipv4Addr::LOCALHOST).is_ipv4() {\n        //~^ redundant_pattern_matching\n        true\n    } else {\n        false\n    };\n\n    ipaddr_const();\n\n    let _ = if gen_ipaddr().is_ipv4() {\n        //~^ redundant_pattern_matching\n        1\n    } else if gen_ipaddr().is_ipv6() {\n        //~^ redundant_pattern_matching\n        2\n    } else {\n        3\n    };\n}\n\nfn gen_ipaddr() -> IpAddr {\n    V4(Ipv4Addr::LOCALHOST)\n}\n\nconst fn ipaddr_const() {\n    if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\n    //~^ redundant_pattern_matching\n\n    if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\n    //~^ redundant_pattern_matching\n\n    while V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\n    //~^ redundant_pattern_matching\n\n    while V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\n    //~^ redundant_pattern_matching\n\n    V4(Ipv4Addr::LOCALHOST).is_ipv4();\n\n    V6(Ipv6Addr::LOCALHOST).is_ipv6();\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_ipaddr.rs",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(\n    clippy::match_like_matches_macro,\n    clippy::needless_bool,\n    clippy::needless_ifs,\n    clippy::uninlined_format_args\n)]\n\nuse std::net::IpAddr::{self, V4, V6};\nuse std::net::{Ipv4Addr, Ipv6Addr};\n\nfn main() {\n    let ipaddr: IpAddr = V4(Ipv4Addr::LOCALHOST);\n    if let V4(_) = &ipaddr {}\n    //~^ redundant_pattern_matching\n\n    if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}\n    //~^ redundant_pattern_matching\n\n    if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}\n    //~^ redundant_pattern_matching\n\n    // Issue 6459\n    if matches!(V4(Ipv4Addr::LOCALHOST), V4(_)) {}\n    //~^ redundant_pattern_matching\n\n    // Issue 6459\n    if matches!(V6(Ipv6Addr::LOCALHOST), V6(_)) {}\n    //~^ redundant_pattern_matching\n\n    while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}\n    //~^ redundant_pattern_matching\n\n    while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}\n    //~^ redundant_pattern_matching\n\n    if V4(Ipv4Addr::LOCALHOST).is_ipv4() {}\n\n    if V6(Ipv6Addr::LOCALHOST).is_ipv6() {}\n\n    if let V4(ipaddr) = V4(Ipv4Addr::LOCALHOST) {\n        println!(\"{}\", ipaddr);\n    }\n\n    match V4(Ipv4Addr::LOCALHOST) {\n        //~^ redundant_pattern_matching\n        V4(_) => true,\n        V6(_) => false,\n    };\n\n    match V4(Ipv4Addr::LOCALHOST) {\n        //~^ redundant_pattern_matching\n        V4(_) => false,\n        V6(_) => true,\n    };\n\n    match V6(Ipv6Addr::LOCALHOST) {\n        //~^ redundant_pattern_matching\n        V4(_) => false,\n        V6(_) => true,\n    };\n\n    match V6(Ipv6Addr::LOCALHOST) {\n        //~^ redundant_pattern_matching\n        V4(_) => true,\n        V6(_) => false,\n    };\n\n    let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) {\n        //~^ redundant_pattern_matching\n        true\n    } else {\n        false\n    };\n\n    ipaddr_const();\n\n    let _ = if let V4(_) = gen_ipaddr() {\n        //~^ redundant_pattern_matching\n        1\n    } else if let V6(_) = gen_ipaddr() {\n        //~^ redundant_pattern_matching\n        2\n    } else {\n        3\n    };\n}\n\nfn gen_ipaddr() -> IpAddr {\n    V4(Ipv4Addr::LOCALHOST)\n}\n\nconst fn ipaddr_const() {\n    if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}\n    //~^ redundant_pattern_matching\n\n    if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}\n    //~^ redundant_pattern_matching\n\n    while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}\n    //~^ redundant_pattern_matching\n\n    while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}\n    //~^ redundant_pattern_matching\n\n    match V4(Ipv4Addr::LOCALHOST) {\n        //~^ redundant_pattern_matching\n        V4(_) => true,\n        V6(_) => false,\n    };\n\n    match V6(Ipv6Addr::LOCALHOST) {\n        //~^ redundant_pattern_matching\n        V4(_) => false,\n        V6(_) => true,\n    };\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_ipaddr.stderr",
    "content": "error: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:14:12\n   |\nLL |     if let V4(_) = &ipaddr {}\n   |     -------^^^^^---------- help: try: `if ipaddr.is_ipv4()`\n   |\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:17:12\n   |\nLL |     if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}\n   |     -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:20:12\n   |\nLL |     if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}\n   |     -------^^^^^-------------------------- help: try: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:24:8\n   |\nLL |     if matches!(V4(Ipv4Addr::LOCALHOST), V4(_)) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:28:8\n   |\nLL |     if matches!(V6(Ipv6Addr::LOCALHOST), V6(_)) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv6()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:31:15\n   |\nLL |     while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}\n   |     ----------^^^^^-------------------------- help: try: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:34:15\n   |\nLL |     while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}\n   |     ----------^^^^^-------------------------- help: try: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:45:5\n   |\nLL | /     match V4(Ipv4Addr::LOCALHOST) {\nLL | |\nLL | |         V4(_) => true,\nLL | |         V6(_) => false,\nLL | |     };\n   | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:51:5\n   |\nLL | /     match V4(Ipv4Addr::LOCALHOST) {\nLL | |\nLL | |         V4(_) => false,\nLL | |         V6(_) => true,\nLL | |     };\n   | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv6()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:57:5\n   |\nLL | /     match V6(Ipv6Addr::LOCALHOST) {\nLL | |\nLL | |         V4(_) => false,\nLL | |         V6(_) => true,\nLL | |     };\n   | |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv6()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:63:5\n   |\nLL | /     match V6(Ipv6Addr::LOCALHOST) {\nLL | |\nLL | |         V4(_) => true,\nLL | |         V6(_) => false,\nLL | |     };\n   | |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:69:20\n   |\nLL |     let _ = if let V4(_) = V4(Ipv4Addr::LOCALHOST) {\n   |             -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:78:20\n   |\nLL |     let _ = if let V4(_) = gen_ipaddr() {\n   |             -------^^^^^--------------- help: try: `if gen_ipaddr().is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:81:19\n   |\nLL |     } else if let V6(_) = gen_ipaddr() {\n   |            -------^^^^^--------------- help: try: `if gen_ipaddr().is_ipv6()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:94:12\n   |\nLL |     if let V4(_) = V4(Ipv4Addr::LOCALHOST) {}\n   |     -------^^^^^-------------------------- help: try: `if V4(Ipv4Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:97:12\n   |\nLL |     if let V6(_) = V6(Ipv6Addr::LOCALHOST) {}\n   |     -------^^^^^-------------------------- help: try: `if V6(Ipv6Addr::LOCALHOST).is_ipv6()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:100:15\n   |\nLL |     while let V4(_) = V4(Ipv4Addr::LOCALHOST) {}\n   |     ----------^^^^^-------------------------- help: try: `while V4(Ipv4Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:103:15\n   |\nLL |     while let V6(_) = V6(Ipv6Addr::LOCALHOST) {}\n   |     ----------^^^^^-------------------------- help: try: `while V6(Ipv6Addr::LOCALHOST).is_ipv6()`\n\nerror: redundant pattern matching, consider using `is_ipv4()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:106:5\n   |\nLL | /     match V4(Ipv4Addr::LOCALHOST) {\nLL | |\nLL | |         V4(_) => true,\nLL | |         V6(_) => false,\nLL | |     };\n   | |_____^ help: try: `V4(Ipv4Addr::LOCALHOST).is_ipv4()`\n\nerror: redundant pattern matching, consider using `is_ipv6()`\n  --> tests/ui/redundant_pattern_matching_ipaddr.rs:112:5\n   |\nLL | /     match V6(Ipv6Addr::LOCALHOST) {\nLL | |\nLL | |         V4(_) => false,\nLL | |         V6(_) => true,\nLL | |     };\n   | |_____^ help: try: `V6(Ipv6Addr::LOCALHOST).is_ipv6()`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_option.fixed",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(\n    clippy::needless_bool,\n    clippy::needless_ifs,\n    clippy::match_like_matches_macro,\n    clippy::equatable_if_let,\n    clippy::if_same_then_else\n)]\n\nfn issue_11174<T>(boolean: bool, maybe_some: Option<T>) -> bool {\n    maybe_some.is_none() && (!boolean)\n    //~^ redundant_pattern_matching\n}\n\nfn issue_11174_edge_cases<T>(boolean: bool, boolean2: bool, maybe_some: Option<T>) {\n    let _ = maybe_some.is_none() && (boolean || boolean2); // guard needs parentheses\n    //\n    //~^^ redundant_pattern_matching\n    let _ = match maybe_some {\n        // can't use `matches!` here\n        // because `expr` metavars in macros don't allow let exprs\n        None if let Some(x) = Some(0)\n            && x > 5 =>\n        {\n            true\n        },\n        _ => false,\n    };\n}\n\nfn main() {\n    if None::<()>.is_none() {}\n    //~^ redundant_pattern_matching\n\n    if Some(42).is_some() {}\n    //~^ redundant_pattern_matching\n\n    if Some(42).is_some() {\n        //~^ redundant_pattern_matching\n        foo();\n    } else {\n        bar();\n    }\n\n    while Some(42).is_some() {}\n    //~^ redundant_pattern_matching\n\n    while Some(42).is_none() {}\n    //~^ redundant_pattern_matching\n\n    while None::<()>.is_none() {}\n    //~^ redundant_pattern_matching\n\n    let mut v = vec![1, 2, 3];\n    while v.pop().is_some() {\n        //~^ redundant_pattern_matching\n        foo();\n    }\n\n    if None::<i32>.is_none() {}\n\n    if Some(42).is_some() {}\n\n    Some(42).is_some();\n\n    None::<()>.is_none();\n\n    let _ = None::<()>.is_none();\n\n    let opt = Some(false);\n    let _ = if opt.is_some() { true } else { false };\n    //~^ redundant_pattern_matching\n\n    issue6067();\n    issue10726();\n    issue10803();\n\n    let _ = if gen_opt().is_some() {\n        //~^ redundant_pattern_matching\n        1\n    } else if gen_opt().is_none() {\n        //~^ redundant_pattern_matching\n        2\n    } else {\n        3\n    };\n\n    if gen_opt().is_some() {}\n    //~^ redundant_pattern_matching\n}\n\nfn gen_opt() -> Option<()> {\n    None\n}\n\nfn foo() {}\n\nfn bar() {}\n\n// Methods that are unstable const should not be suggested within a const context, see issue #5697.\n// However, in Rust 1.48.0 the methods `is_some` and `is_none` of `Option` were stabilized as const,\n// so the following should be linted.\nconst fn issue6067() {\n    if Some(42).is_some() {}\n    //~^ redundant_pattern_matching\n\n    if None::<()>.is_none() {}\n    //~^ redundant_pattern_matching\n\n    while Some(42).is_some() {}\n    //~^ redundant_pattern_matching\n\n    while None::<()>.is_none() {}\n    //~^ redundant_pattern_matching\n\n    Some(42).is_some();\n\n    None::<()>.is_none();\n}\n\n#[allow(clippy::deref_addrof, dead_code, clippy::needless_borrow)]\nfn issue7921() {\n    if (&None::<()>).is_none() {}\n    //~^ redundant_pattern_matching\n    if (&None::<()>).is_none() {}\n    //~^ redundant_pattern_matching\n}\n\nfn issue10726() {\n    let x = Some(42);\n\n    x.is_some();\n\n    x.is_none();\n\n    x.is_none();\n\n    x.is_some();\n\n    // Don't lint\n    match x {\n        Some(21) => true,\n        _ => false,\n    };\n}\n\nfn issue10803() {\n    let x = Some(42);\n\n    let _ = x.is_some();\n    //~^ redundant_pattern_matching\n\n    let _ = x.is_none();\n    //~^ redundant_pattern_matching\n\n    // Don't lint\n    let _ = matches!(x, Some(16));\n}\n\nfn issue13902() {\n    let x = Some(0);\n    let p = &raw const x;\n    unsafe {\n        let _ = (*p).is_none();\n        //~^ redundant_pattern_matching\n    }\n}\n\nfn issue16045() {\n    fn f() -> Result<(), ()> {\n        let x = Ok::<_, ()>(Some(123));\n        if x?.is_some() {\n            //~^ redundant_pattern_matching\n        }\n\n        Ok(())\n    }\n\n    async fn g() {\n        struct F {\n            x: Option<u32>,\n        }\n\n        impl Future for F {\n            type Output = Option<u32>;\n\n            fn poll(self: std::pin::Pin<&mut Self>, _: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {\n                std::task::Poll::Ready(self.x)\n            }\n        }\n        let x = F { x: Some(123) };\n        if x.await.is_some() {\n            //~^ redundant_pattern_matching\n        }\n    }\n}\n\nfn issue14989() {\n    macro_rules! x {\n        () => {\n            None::<i32>\n        };\n    }\n\n    if x! {}.is_some() {};\n    //~^ redundant_pattern_matching\n    while x! {}.is_some() {}\n    //~^ redundant_pattern_matching\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_option.rs",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(\n    clippy::needless_bool,\n    clippy::needless_ifs,\n    clippy::match_like_matches_macro,\n    clippy::equatable_if_let,\n    clippy::if_same_then_else\n)]\n\nfn issue_11174<T>(boolean: bool, maybe_some: Option<T>) -> bool {\n    matches!(maybe_some, None if !boolean)\n    //~^ redundant_pattern_matching\n}\n\nfn issue_11174_edge_cases<T>(boolean: bool, boolean2: bool, maybe_some: Option<T>) {\n    let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses\n    //\n    //~^^ redundant_pattern_matching\n    let _ = match maybe_some {\n        // can't use `matches!` here\n        // because `expr` metavars in macros don't allow let exprs\n        None if let Some(x) = Some(0)\n            && x > 5 =>\n        {\n            true\n        },\n        _ => false,\n    };\n}\n\nfn main() {\n    if let None = None::<()> {}\n    //~^ redundant_pattern_matching\n\n    if let Some(_) = Some(42) {}\n    //~^ redundant_pattern_matching\n\n    if let Some(_) = Some(42) {\n        //~^ redundant_pattern_matching\n        foo();\n    } else {\n        bar();\n    }\n\n    while let Some(_) = Some(42) {}\n    //~^ redundant_pattern_matching\n\n    while let None = Some(42) {}\n    //~^ redundant_pattern_matching\n\n    while let None = None::<()> {}\n    //~^ redundant_pattern_matching\n\n    let mut v = vec![1, 2, 3];\n    while let Some(_) = v.pop() {\n        //~^ redundant_pattern_matching\n        foo();\n    }\n\n    if None::<i32>.is_none() {}\n\n    if Some(42).is_some() {}\n\n    match Some(42) {\n        //~^ redundant_pattern_matching\n        Some(_) => true,\n        None => false,\n    };\n\n    match None::<()> {\n        //~^ redundant_pattern_matching\n        Some(_) => false,\n        None => true,\n    };\n\n    let _ = match None::<()> {\n        //~^ redundant_pattern_matching\n        Some(_) => false,\n        None => true,\n    };\n\n    let opt = Some(false);\n    let _ = if let Some(_) = opt { true } else { false };\n    //~^ redundant_pattern_matching\n\n    issue6067();\n    issue10726();\n    issue10803();\n\n    let _ = if let Some(_) = gen_opt() {\n        //~^ redundant_pattern_matching\n        1\n    } else if let None = gen_opt() {\n        //~^ redundant_pattern_matching\n        2\n    } else {\n        3\n    };\n\n    if let Some(..) = gen_opt() {}\n    //~^ redundant_pattern_matching\n}\n\nfn gen_opt() -> Option<()> {\n    None\n}\n\nfn foo() {}\n\nfn bar() {}\n\n// Methods that are unstable const should not be suggested within a const context, see issue #5697.\n// However, in Rust 1.48.0 the methods `is_some` and `is_none` of `Option` were stabilized as const,\n// so the following should be linted.\nconst fn issue6067() {\n    if let Some(_) = Some(42) {}\n    //~^ redundant_pattern_matching\n\n    if let None = None::<()> {}\n    //~^ redundant_pattern_matching\n\n    while let Some(_) = Some(42) {}\n    //~^ redundant_pattern_matching\n\n    while let None = None::<()> {}\n    //~^ redundant_pattern_matching\n\n    match Some(42) {\n        //~^ redundant_pattern_matching\n        Some(_) => true,\n        None => false,\n    };\n\n    match None::<()> {\n        //~^ redundant_pattern_matching\n        Some(_) => false,\n        None => true,\n    };\n}\n\n#[allow(clippy::deref_addrof, dead_code, clippy::needless_borrow)]\nfn issue7921() {\n    if let None = *(&None::<()>) {}\n    //~^ redundant_pattern_matching\n    if let None = *&None::<()> {}\n    //~^ redundant_pattern_matching\n}\n\nfn issue10726() {\n    let x = Some(42);\n\n    match x {\n        //~^ redundant_pattern_matching\n        Some(_) => true,\n        _ => false,\n    };\n\n    match x {\n        //~^ redundant_pattern_matching\n        None => true,\n        _ => false,\n    };\n\n    match x {\n        //~^ redundant_pattern_matching\n        Some(_) => false,\n        _ => true,\n    };\n\n    match x {\n        //~^ redundant_pattern_matching\n        None => false,\n        _ => true,\n    };\n\n    // Don't lint\n    match x {\n        Some(21) => true,\n        _ => false,\n    };\n}\n\nfn issue10803() {\n    let x = Some(42);\n\n    let _ = matches!(x, Some(_));\n    //~^ redundant_pattern_matching\n\n    let _ = matches!(x, None);\n    //~^ redundant_pattern_matching\n\n    // Don't lint\n    let _ = matches!(x, Some(16));\n}\n\nfn issue13902() {\n    let x = Some(0);\n    let p = &raw const x;\n    unsafe {\n        let _ = matches!(*p, None);\n        //~^ redundant_pattern_matching\n    }\n}\n\nfn issue16045() {\n    fn f() -> Result<(), ()> {\n        let x = Ok::<_, ()>(Some(123));\n        if let Some(_) = x? {\n            //~^ redundant_pattern_matching\n        }\n\n        Ok(())\n    }\n\n    async fn g() {\n        struct F {\n            x: Option<u32>,\n        }\n\n        impl Future for F {\n            type Output = Option<u32>;\n\n            fn poll(self: std::pin::Pin<&mut Self>, _: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {\n                std::task::Poll::Ready(self.x)\n            }\n        }\n        let x = F { x: Some(123) };\n        if let Some(_) = x.await {\n            //~^ redundant_pattern_matching\n        }\n    }\n}\n\nfn issue14989() {\n    macro_rules! x {\n        () => {\n            None::<i32>\n        };\n    }\n\n    if let Some(_) = (x! {}) {};\n    //~^ redundant_pattern_matching\n    while let Some(_) = (x! {}) {}\n    //~^ redundant_pattern_matching\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_option.stderr",
    "content": "error: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:11:5\n   |\nLL |     matches!(maybe_some, None if !boolean)\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (!boolean)`\n   |\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:16:13\n   |\nLL |     let _ = matches!(maybe_some, None if boolean || boolean2); // guard needs parentheses\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `maybe_some.is_none() && (boolean || boolean2)`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:32:12\n   |\nLL |     if let None = None::<()> {}\n   |     -------^^^^------------- help: try: `if None::<()>.is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:35:12\n   |\nLL |     if let Some(_) = Some(42) {}\n   |     -------^^^^^^^----------- help: try: `if Some(42).is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:38:12\n   |\nLL |     if let Some(_) = Some(42) {\n   |     -------^^^^^^^----------- help: try: `if Some(42).is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:45:15\n   |\nLL |     while let Some(_) = Some(42) {}\n   |     ----------^^^^^^^----------- help: try: `while Some(42).is_some()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:48:15\n   |\nLL |     while let None = Some(42) {}\n   |     ----------^^^^----------- help: try: `while Some(42).is_none()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:51:15\n   |\nLL |     while let None = None::<()> {}\n   |     ----------^^^^------------- help: try: `while None::<()>.is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:55:15\n   |\nLL |     while let Some(_) = v.pop() {\n   |     ----------^^^^^^^---------- help: try: `while v.pop().is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:64:5\n   |\nLL | /     match Some(42) {\nLL | |\nLL | |         Some(_) => true,\nLL | |         None => false,\nLL | |     };\n   | |_____^ help: try: `Some(42).is_some()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:70:5\n   |\nLL | /     match None::<()> {\nLL | |\nLL | |         Some(_) => false,\nLL | |         None => true,\nLL | |     };\n   | |_____^ help: try: `None::<()>.is_none()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:76:13\n   |\nLL |       let _ = match None::<()> {\n   |  _____________^\nLL | |\nLL | |         Some(_) => false,\nLL | |         None => true,\nLL | |     };\n   | |_____^ help: try: `None::<()>.is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:83:20\n   |\nLL |     let _ = if let Some(_) = opt { true } else { false };\n   |             -------^^^^^^^------ help: try: `if opt.is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:90:20\n   |\nLL |     let _ = if let Some(_) = gen_opt() {\n   |             -------^^^^^^^------------ help: try: `if gen_opt().is_some()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:93:19\n   |\nLL |     } else if let None = gen_opt() {\n   |            -------^^^^------------ help: try: `if gen_opt().is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:100:12\n   |\nLL |     if let Some(..) = gen_opt() {}\n   |     -------^^^^^^^^------------ help: try: `if gen_opt().is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:116:12\n   |\nLL |     if let Some(_) = Some(42) {}\n   |     -------^^^^^^^----------- help: try: `if Some(42).is_some()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:119:12\n   |\nLL |     if let None = None::<()> {}\n   |     -------^^^^------------- help: try: `if None::<()>.is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:122:15\n   |\nLL |     while let Some(_) = Some(42) {}\n   |     ----------^^^^^^^----------- help: try: `while Some(42).is_some()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:125:15\n   |\nLL |     while let None = None::<()> {}\n   |     ----------^^^^------------- help: try: `while None::<()>.is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:128:5\n   |\nLL | /     match Some(42) {\nLL | |\nLL | |         Some(_) => true,\nLL | |         None => false,\nLL | |     };\n   | |_____^ help: try: `Some(42).is_some()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:134:5\n   |\nLL | /     match None::<()> {\nLL | |\nLL | |         Some(_) => false,\nLL | |         None => true,\nLL | |     };\n   | |_____^ help: try: `None::<()>.is_none()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:143:12\n   |\nLL |     if let None = *(&None::<()>) {}\n   |     -------^^^^----------------- help: try: `if (&None::<()>).is_none()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:145:12\n   |\nLL |     if let None = *&None::<()> {}\n   |     -------^^^^--------------- help: try: `if (&None::<()>).is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:152:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Some(_) => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^ help: try: `x.is_some()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:158:5\n   |\nLL | /     match x {\nLL | |\nLL | |         None => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^ help: try: `x.is_none()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:164:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Some(_) => false,\nLL | |         _ => true,\nLL | |     };\n   | |_____^ help: try: `x.is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:170:5\n   |\nLL | /     match x {\nLL | |\nLL | |         None => false,\nLL | |         _ => true,\nLL | |     };\n   | |_____^ help: try: `x.is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:186:13\n   |\nLL |     let _ = matches!(x, Some(_));\n   |             ^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_some()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:189:13\n   |\nLL |     let _ = matches!(x, None);\n   |             ^^^^^^^^^^^^^^^^^ help: try: `x.is_none()`\n\nerror: redundant pattern matching, consider using `is_none()`\n  --> tests/ui/redundant_pattern_matching_option.rs:200:17\n   |\nLL |         let _ = matches!(*p, None);\n   |                 ^^^^^^^^^^^^^^^^^^ help: try: `(*p).is_none()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:208:16\n   |\nLL |         if let Some(_) = x? {\n   |         -------^^^^^^^----- help: try: `if x?.is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:228:16\n   |\nLL |         if let Some(_) = x.await {\n   |         -------^^^^^^^---------- help: try: `if x.await.is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:241:12\n   |\nLL |     if let Some(_) = (x! {}) {};\n   |     -------^^^^^^^---------- help: try: `if x! {}.is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_option.rs:243:15\n   |\nLL |     while let Some(_) = (x! {}) {}\n   |     ----------^^^^^^^---------- help: try: `while x! {}.is_some()`\n\nerror: aborting due to 35 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_poll.fixed",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(\n    clippy::needless_bool,\n    clippy::needless_ifs,\n    clippy::match_like_matches_macro,\n    clippy::equatable_if_let,\n    clippy::if_same_then_else\n)]\n\nuse std::task::Poll::{self, Pending, Ready};\n\nfn main() {\n    if Pending::<()>.is_pending() {}\n    //~^ redundant_pattern_matching\n\n    if Ready(42).is_ready() {}\n    //~^ redundant_pattern_matching\n\n    if Ready(42).is_ready() {\n        //~^ redundant_pattern_matching\n        foo();\n    } else {\n        bar();\n    }\n\n    // Issue 6459\n    if Ready(42).is_ready() {}\n    //~^ redundant_pattern_matching\n\n    // Issue 6459\n    if Pending::<()>.is_pending() {}\n    //~^ redundant_pattern_matching\n\n    while Ready(42).is_ready() {}\n    //~^ redundant_pattern_matching\n\n    while Ready(42).is_pending() {}\n    //~^ redundant_pattern_matching\n\n    while Pending::<()>.is_pending() {}\n    //~^ redundant_pattern_matching\n\n    if Pending::<i32>.is_pending() {}\n\n    if Ready(42).is_ready() {}\n\n    Ready(42).is_ready();\n\n    Pending::<()>.is_pending();\n\n    let _ = Pending::<()>.is_pending();\n\n    let poll = Ready(false);\n    let _ = if poll.is_ready() { true } else { false };\n    //~^ redundant_pattern_matching\n\n    poll_const();\n\n    let _ = if gen_poll().is_ready() {\n        //~^ redundant_pattern_matching\n        1\n    } else if gen_poll().is_pending() {\n        //~^ redundant_pattern_matching\n        2\n    } else {\n        3\n    };\n}\n\nfn gen_poll() -> Poll<()> {\n    Pending\n}\n\nfn foo() {}\n\nfn bar() {}\n\nconst fn poll_const() {\n    if Ready(42).is_ready() {}\n    //~^ redundant_pattern_matching\n\n    if Pending::<()>.is_pending() {}\n    //~^ redundant_pattern_matching\n\n    while Ready(42).is_ready() {}\n    //~^ redundant_pattern_matching\n\n    while Pending::<()>.is_pending() {}\n    //~^ redundant_pattern_matching\n\n    Ready(42).is_ready();\n\n    Pending::<()>.is_pending();\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_poll.rs",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(\n    clippy::needless_bool,\n    clippy::needless_ifs,\n    clippy::match_like_matches_macro,\n    clippy::equatable_if_let,\n    clippy::if_same_then_else\n)]\n\nuse std::task::Poll::{self, Pending, Ready};\n\nfn main() {\n    if let Pending = Pending::<()> {}\n    //~^ redundant_pattern_matching\n\n    if let Ready(_) = Ready(42) {}\n    //~^ redundant_pattern_matching\n\n    if let Ready(_) = Ready(42) {\n        //~^ redundant_pattern_matching\n        foo();\n    } else {\n        bar();\n    }\n\n    // Issue 6459\n    if matches!(Ready(42), Ready(_)) {}\n    //~^ redundant_pattern_matching\n\n    // Issue 6459\n    if matches!(Pending::<()>, Pending) {}\n    //~^ redundant_pattern_matching\n\n    while let Ready(_) = Ready(42) {}\n    //~^ redundant_pattern_matching\n\n    while let Pending = Ready(42) {}\n    //~^ redundant_pattern_matching\n\n    while let Pending = Pending::<()> {}\n    //~^ redundant_pattern_matching\n\n    if Pending::<i32>.is_pending() {}\n\n    if Ready(42).is_ready() {}\n\n    match Ready(42) {\n        //~^ redundant_pattern_matching\n        Ready(_) => true,\n        Pending => false,\n    };\n\n    match Pending::<()> {\n        //~^ redundant_pattern_matching\n        Ready(_) => false,\n        Pending => true,\n    };\n\n    let _ = match Pending::<()> {\n        //~^ redundant_pattern_matching\n        Ready(_) => false,\n        Pending => true,\n    };\n\n    let poll = Ready(false);\n    let _ = if let Ready(_) = poll { true } else { false };\n    //~^ redundant_pattern_matching\n\n    poll_const();\n\n    let _ = if let Ready(_) = gen_poll() {\n        //~^ redundant_pattern_matching\n        1\n    } else if let Pending = gen_poll() {\n        //~^ redundant_pattern_matching\n        2\n    } else {\n        3\n    };\n}\n\nfn gen_poll() -> Poll<()> {\n    Pending\n}\n\nfn foo() {}\n\nfn bar() {}\n\nconst fn poll_const() {\n    if let Ready(_) = Ready(42) {}\n    //~^ redundant_pattern_matching\n\n    if let Pending = Pending::<()> {}\n    //~^ redundant_pattern_matching\n\n    while let Ready(_) = Ready(42) {}\n    //~^ redundant_pattern_matching\n\n    while let Pending = Pending::<()> {}\n    //~^ redundant_pattern_matching\n\n    match Ready(42) {\n        //~^ redundant_pattern_matching\n        Ready(_) => true,\n        Pending => false,\n    };\n\n    match Pending::<()> {\n        //~^ redundant_pattern_matching\n        Ready(_) => false,\n        Pending => true,\n    };\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_poll.stderr",
    "content": "error: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:13:12\n   |\nLL |     if let Pending = Pending::<()> {}\n   |     -------^^^^^^^---------------- help: try: `if Pending::<()>.is_pending()`\n   |\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:16:12\n   |\nLL |     if let Ready(_) = Ready(42) {}\n   |     -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:19:12\n   |\nLL |     if let Ready(_) = Ready(42) {\n   |     -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:27:8\n   |\nLL |     if matches!(Ready(42), Ready(_)) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ready(42).is_ready()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:31:8\n   |\nLL |     if matches!(Pending::<()>, Pending) {}\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Pending::<()>.is_pending()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:34:15\n   |\nLL |     while let Ready(_) = Ready(42) {}\n   |     ----------^^^^^^^^------------ help: try: `while Ready(42).is_ready()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:37:15\n   |\nLL |     while let Pending = Ready(42) {}\n   |     ----------^^^^^^^------------ help: try: `while Ready(42).is_pending()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:40:15\n   |\nLL |     while let Pending = Pending::<()> {}\n   |     ----------^^^^^^^---------------- help: try: `while Pending::<()>.is_pending()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:47:5\n   |\nLL | /     match Ready(42) {\nLL | |\nLL | |         Ready(_) => true,\nLL | |         Pending => false,\nLL | |     };\n   | |_____^ help: try: `Ready(42).is_ready()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:53:5\n   |\nLL | /     match Pending::<()> {\nLL | |\nLL | |         Ready(_) => false,\nLL | |         Pending => true,\nLL | |     };\n   | |_____^ help: try: `Pending::<()>.is_pending()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:59:13\n   |\nLL |       let _ = match Pending::<()> {\n   |  _____________^\nLL | |\nLL | |         Ready(_) => false,\nLL | |         Pending => true,\nLL | |     };\n   | |_____^ help: try: `Pending::<()>.is_pending()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:66:20\n   |\nLL |     let _ = if let Ready(_) = poll { true } else { false };\n   |             -------^^^^^^^^------- help: try: `if poll.is_ready()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:71:20\n   |\nLL |     let _ = if let Ready(_) = gen_poll() {\n   |             -------^^^^^^^^------------- help: try: `if gen_poll().is_ready()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:74:19\n   |\nLL |     } else if let Pending = gen_poll() {\n   |            -------^^^^^^^------------- help: try: `if gen_poll().is_pending()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:91:12\n   |\nLL |     if let Ready(_) = Ready(42) {}\n   |     -------^^^^^^^^------------ help: try: `if Ready(42).is_ready()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:94:12\n   |\nLL |     if let Pending = Pending::<()> {}\n   |     -------^^^^^^^---------------- help: try: `if Pending::<()>.is_pending()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:97:15\n   |\nLL |     while let Ready(_) = Ready(42) {}\n   |     ----------^^^^^^^^------------ help: try: `while Ready(42).is_ready()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:100:15\n   |\nLL |     while let Pending = Pending::<()> {}\n   |     ----------^^^^^^^---------------- help: try: `while Pending::<()>.is_pending()`\n\nerror: redundant pattern matching, consider using `is_ready()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:103:5\n   |\nLL | /     match Ready(42) {\nLL | |\nLL | |         Ready(_) => true,\nLL | |         Pending => false,\nLL | |     };\n   | |_____^ help: try: `Ready(42).is_ready()`\n\nerror: redundant pattern matching, consider using `is_pending()`\n  --> tests/ui/redundant_pattern_matching_poll.rs:109:5\n   |\nLL | /     match Pending::<()> {\nLL | |\nLL | |         Ready(_) => false,\nLL | |         Pending => true,\nLL | |     };\n   | |_____^ help: try: `Pending::<()>.is_pending()`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_result.fixed",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(deprecated)]\n#![allow(\n    clippy::if_same_then_else,\n    clippy::match_like_matches_macro,\n    clippy::needless_bool,\n    clippy::needless_ifs,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_wraps\n)]\n\nfn main() {\n    let result: Result<usize, usize> = Err(5);\n    if result.is_ok() {}\n    //~^ redundant_pattern_matching\n\n    if Ok::<i32, i32>(42).is_ok() {}\n    //~^ redundant_pattern_matching\n\n    if Err::<i32, i32>(42).is_err() {}\n    //~^ redundant_pattern_matching\n\n    while Ok::<i32, i32>(10).is_ok() {}\n    //~^ redundant_pattern_matching\n\n    while Ok::<i32, i32>(10).is_err() {}\n    //~^ redundant_pattern_matching\n\n    if Ok::<i32, i32>(42).is_ok() {}\n\n    if Err::<i32, i32>(42).is_err() {}\n\n    if let Ok(x) = Ok::<i32, i32>(42) {\n        println!(\"{}\", x);\n    }\n\n    Ok::<i32, i32>(42).is_ok();\n\n    Ok::<i32, i32>(42).is_err();\n\n    Err::<i32, i32>(42).is_err();\n\n    Err::<i32, i32>(42).is_ok();\n\n    let _ = if Ok::<usize, ()>(4).is_ok() { true } else { false };\n    //~^ redundant_pattern_matching\n\n    issue5504();\n    issue6067();\n    issue6065();\n    issue10726();\n    issue10803();\n\n    let _ = if gen_res().is_ok() {\n        //~^ redundant_pattern_matching\n        1\n    } else if gen_res().is_err() {\n        //~^ redundant_pattern_matching\n        2\n    } else {\n        3\n    };\n}\n\nfn gen_res() -> Result<(), ()> {\n    Ok(())\n}\n\nmacro_rules! m {\n    () => {\n        Some(42u32)\n    };\n}\n\nfn issue5504() {\n    fn result_opt() -> Result<Option<i32>, i32> {\n        Err(42)\n    }\n\n    fn try_result_opt() -> Result<i32, i32> {\n        while r#try!(result_opt()).is_some() {}\n        //~^ redundant_pattern_matching\n        if r#try!(result_opt()).is_some() {}\n        //~^ redundant_pattern_matching\n        Ok(42)\n    }\n\n    try_result_opt();\n\n    if m!().is_some() {}\n    //~^ redundant_pattern_matching\n    while m!().is_some() {}\n    //~^ redundant_pattern_matching\n}\n\nfn issue6065() {\n    macro_rules! if_let_in_macro {\n        ($pat:pat, $x:expr) => {\n            if let Some($pat) = $x {}\n        };\n    }\n\n    // shouldn't be linted\n    if_let_in_macro!(_, Some(42));\n}\n\n// Methods that are unstable const should not be suggested within a const context, see issue #5697.\n// However, in Rust 1.48.0 the methods `is_ok` and `is_err` of `Result` were stabilized as const,\n// so the following should be linted.\nconst fn issue6067() {\n    if Ok::<i32, i32>(42).is_ok() {}\n    //~^ redundant_pattern_matching\n\n    if Err::<i32, i32>(42).is_err() {}\n    //~^ redundant_pattern_matching\n\n    while Ok::<i32, i32>(10).is_ok() {}\n    //~^ redundant_pattern_matching\n\n    while Ok::<i32, i32>(10).is_err() {}\n    //~^ redundant_pattern_matching\n\n    Ok::<i32, i32>(42).is_ok();\n\n    Err::<i32, i32>(42).is_err();\n}\n\nfn issue10726() {\n    // This is optional, but it makes the examples easier\n    let x: Result<i32, i32> = Ok(42);\n\n    x.is_ok();\n\n    x.is_err();\n\n    x.is_err();\n\n    x.is_ok();\n\n    // Don't lint\n    match x {\n        Err(16) => false,\n        _ => true,\n    };\n\n    // Don't lint\n    match x {\n        Ok(16) => false,\n        _ => true,\n    };\n}\n\nfn issue10803() {\n    let x: Result<i32, i32> = Ok(42);\n\n    let _ = x.is_ok();\n    //~^ redundant_pattern_matching\n\n    let _ = x.is_err();\n    //~^ redundant_pattern_matching\n\n    // Don't lint\n    let _ = matches!(x, Ok(16));\n\n    // Don't lint\n    let _ = matches!(x, Err(16));\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            Ok::<i32, i32>($val)\n        };\n    }\n\n    let _ = test_expr!(42).is_ok();\n\n    macro_rules! test_guard {\n        ($val:expr) => {\n            ($val + 1) > 0\n        };\n    }\n\n    let x: Result<i32, ()> = Ok(42);\n    let _ = x.is_ok() && test_guard!(42);\n    //~^ redundant_pattern_matching\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_result.rs",
    "content": "#![warn(clippy::redundant_pattern_matching)]\n#![allow(deprecated)]\n#![allow(\n    clippy::if_same_then_else,\n    clippy::match_like_matches_macro,\n    clippy::needless_bool,\n    clippy::needless_ifs,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_wraps\n)]\n\nfn main() {\n    let result: Result<usize, usize> = Err(5);\n    if let Ok(_) = &result {}\n    //~^ redundant_pattern_matching\n\n    if let Ok(_) = Ok::<i32, i32>(42) {}\n    //~^ redundant_pattern_matching\n\n    if let Err(_) = Err::<i32, i32>(42) {}\n    //~^ redundant_pattern_matching\n\n    while let Ok(_) = Ok::<i32, i32>(10) {}\n    //~^ redundant_pattern_matching\n\n    while let Err(_) = Ok::<i32, i32>(10) {}\n    //~^ redundant_pattern_matching\n\n    if Ok::<i32, i32>(42).is_ok() {}\n\n    if Err::<i32, i32>(42).is_err() {}\n\n    if let Ok(x) = Ok::<i32, i32>(42) {\n        println!(\"{}\", x);\n    }\n\n    match Ok::<i32, i32>(42) {\n        //~^ redundant_pattern_matching\n        Ok(_) => true,\n        Err(_) => false,\n    };\n\n    match Ok::<i32, i32>(42) {\n        //~^ redundant_pattern_matching\n        Ok(_) => false,\n        Err(_) => true,\n    };\n\n    match Err::<i32, i32>(42) {\n        //~^ redundant_pattern_matching\n        Ok(_) => false,\n        Err(_) => true,\n    };\n\n    match Err::<i32, i32>(42) {\n        //~^ redundant_pattern_matching\n        Ok(_) => true,\n        Err(_) => false,\n    };\n\n    let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };\n    //~^ redundant_pattern_matching\n\n    issue5504();\n    issue6067();\n    issue6065();\n    issue10726();\n    issue10803();\n\n    let _ = if let Ok(_) = gen_res() {\n        //~^ redundant_pattern_matching\n        1\n    } else if let Err(_) = gen_res() {\n        //~^ redundant_pattern_matching\n        2\n    } else {\n        3\n    };\n}\n\nfn gen_res() -> Result<(), ()> {\n    Ok(())\n}\n\nmacro_rules! m {\n    () => {\n        Some(42u32)\n    };\n}\n\nfn issue5504() {\n    fn result_opt() -> Result<Option<i32>, i32> {\n        Err(42)\n    }\n\n    fn try_result_opt() -> Result<i32, i32> {\n        while let Some(_) = r#try!(result_opt()) {}\n        //~^ redundant_pattern_matching\n        if let Some(_) = r#try!(result_opt()) {}\n        //~^ redundant_pattern_matching\n        Ok(42)\n    }\n\n    try_result_opt();\n\n    if let Some(_) = m!() {}\n    //~^ redundant_pattern_matching\n    while let Some(_) = m!() {}\n    //~^ redundant_pattern_matching\n}\n\nfn issue6065() {\n    macro_rules! if_let_in_macro {\n        ($pat:pat, $x:expr) => {\n            if let Some($pat) = $x {}\n        };\n    }\n\n    // shouldn't be linted\n    if_let_in_macro!(_, Some(42));\n}\n\n// Methods that are unstable const should not be suggested within a const context, see issue #5697.\n// However, in Rust 1.48.0 the methods `is_ok` and `is_err` of `Result` were stabilized as const,\n// so the following should be linted.\nconst fn issue6067() {\n    if let Ok(_) = Ok::<i32, i32>(42) {}\n    //~^ redundant_pattern_matching\n\n    if let Err(_) = Err::<i32, i32>(42) {}\n    //~^ redundant_pattern_matching\n\n    while let Ok(_) = Ok::<i32, i32>(10) {}\n    //~^ redundant_pattern_matching\n\n    while let Err(_) = Ok::<i32, i32>(10) {}\n    //~^ redundant_pattern_matching\n\n    match Ok::<i32, i32>(42) {\n        //~^ redundant_pattern_matching\n        Ok(_) => true,\n        Err(_) => false,\n    };\n\n    match Err::<i32, i32>(42) {\n        //~^ redundant_pattern_matching\n        Ok(_) => false,\n        Err(_) => true,\n    };\n}\n\nfn issue10726() {\n    // This is optional, but it makes the examples easier\n    let x: Result<i32, i32> = Ok(42);\n\n    match x {\n        //~^ redundant_pattern_matching\n        Ok(_) => true,\n        _ => false,\n    };\n\n    match x {\n        //~^ redundant_pattern_matching\n        Ok(_) => false,\n        _ => true,\n    };\n\n    match x {\n        //~^ redundant_pattern_matching\n        Err(_) => true,\n        _ => false,\n    };\n\n    match x {\n        //~^ redundant_pattern_matching\n        Err(_) => false,\n        _ => true,\n    };\n\n    // Don't lint\n    match x {\n        Err(16) => false,\n        _ => true,\n    };\n\n    // Don't lint\n    match x {\n        Ok(16) => false,\n        _ => true,\n    };\n}\n\nfn issue10803() {\n    let x: Result<i32, i32> = Ok(42);\n\n    let _ = matches!(x, Ok(_));\n    //~^ redundant_pattern_matching\n\n    let _ = matches!(x, Err(_));\n    //~^ redundant_pattern_matching\n\n    // Don't lint\n    let _ = matches!(x, Ok(16));\n\n    // Don't lint\n    let _ = matches!(x, Err(16));\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($val:expr) => {\n            Ok::<i32, i32>($val)\n        };\n    }\n\n    let _ = match test_expr!(42) {\n        //~^ redundant_pattern_matching\n        Ok(_) => true,\n        Err(_) => false,\n    };\n\n    macro_rules! test_guard {\n        ($val:expr) => {\n            ($val + 1) > 0\n        };\n    }\n\n    let x: Result<i32, ()> = Ok(42);\n    let _ = matches!(x, Ok(_) if test_guard!(42));\n    //~^ redundant_pattern_matching\n}\n"
  },
  {
    "path": "tests/ui/redundant_pattern_matching_result.stderr",
    "content": "error: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:14:12\n   |\nLL |     if let Ok(_) = &result {}\n   |     -------^^^^^---------- help: try: `if result.is_ok()`\n   |\n   = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pattern_matching)]`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:17:12\n   |\nLL |     if let Ok(_) = Ok::<i32, i32>(42) {}\n   |     -------^^^^^--------------------- help: try: `if Ok::<i32, i32>(42).is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:20:12\n   |\nLL |     if let Err(_) = Err::<i32, i32>(42) {}\n   |     -------^^^^^^---------------------- help: try: `if Err::<i32, i32>(42).is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:23:15\n   |\nLL |     while let Ok(_) = Ok::<i32, i32>(10) {}\n   |     ----------^^^^^--------------------- help: try: `while Ok::<i32, i32>(10).is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:26:15\n   |\nLL |     while let Err(_) = Ok::<i32, i32>(10) {}\n   |     ----------^^^^^^--------------------- help: try: `while Ok::<i32, i32>(10).is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:37:5\n   |\nLL | /     match Ok::<i32, i32>(42) {\nLL | |\nLL | |         Ok(_) => true,\nLL | |         Err(_) => false,\nLL | |     };\n   | |_____^ help: try: `Ok::<i32, i32>(42).is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:43:5\n   |\nLL | /     match Ok::<i32, i32>(42) {\nLL | |\nLL | |         Ok(_) => false,\nLL | |         Err(_) => true,\nLL | |     };\n   | |_____^ help: try: `Ok::<i32, i32>(42).is_err()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:49:5\n   |\nLL | /     match Err::<i32, i32>(42) {\nLL | |\nLL | |         Ok(_) => false,\nLL | |         Err(_) => true,\nLL | |     };\n   | |_____^ help: try: `Err::<i32, i32>(42).is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:55:5\n   |\nLL | /     match Err::<i32, i32>(42) {\nLL | |\nLL | |         Ok(_) => true,\nLL | |         Err(_) => false,\nLL | |     };\n   | |_____^ help: try: `Err::<i32, i32>(42).is_ok()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:61:20\n   |\nLL |     let _ = if let Ok(_) = Ok::<usize, ()>(4) { true } else { false };\n   |             -------^^^^^--------------------- help: try: `if Ok::<usize, ()>(4).is_ok()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:70:20\n   |\nLL |     let _ = if let Ok(_) = gen_res() {\n   |             -------^^^^^------------ help: try: `if gen_res().is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:73:19\n   |\nLL |     } else if let Err(_) = gen_res() {\n   |            -------^^^^^^------------ help: try: `if gen_res().is_err()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_result.rs:97:19\n   |\nLL |         while let Some(_) = r#try!(result_opt()) {}\n   |         ----------^^^^^^^----------------------- help: try: `while r#try!(result_opt()).is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_result.rs:99:16\n   |\nLL |         if let Some(_) = r#try!(result_opt()) {}\n   |         -------^^^^^^^----------------------- help: try: `if r#try!(result_opt()).is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_result.rs:106:12\n   |\nLL |     if let Some(_) = m!() {}\n   |     -------^^^^^^^------- help: try: `if m!().is_some()`\n\nerror: redundant pattern matching, consider using `is_some()`\n  --> tests/ui/redundant_pattern_matching_result.rs:108:15\n   |\nLL |     while let Some(_) = m!() {}\n   |     ----------^^^^^^^------- help: try: `while m!().is_some()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:127:12\n   |\nLL |     if let Ok(_) = Ok::<i32, i32>(42) {}\n   |     -------^^^^^--------------------- help: try: `if Ok::<i32, i32>(42).is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:130:12\n   |\nLL |     if let Err(_) = Err::<i32, i32>(42) {}\n   |     -------^^^^^^---------------------- help: try: `if Err::<i32, i32>(42).is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:133:15\n   |\nLL |     while let Ok(_) = Ok::<i32, i32>(10) {}\n   |     ----------^^^^^--------------------- help: try: `while Ok::<i32, i32>(10).is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:136:15\n   |\nLL |     while let Err(_) = Ok::<i32, i32>(10) {}\n   |     ----------^^^^^^--------------------- help: try: `while Ok::<i32, i32>(10).is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:139:5\n   |\nLL | /     match Ok::<i32, i32>(42) {\nLL | |\nLL | |         Ok(_) => true,\nLL | |         Err(_) => false,\nLL | |     };\n   | |_____^ help: try: `Ok::<i32, i32>(42).is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:145:5\n   |\nLL | /     match Err::<i32, i32>(42) {\nLL | |\nLL | |         Ok(_) => false,\nLL | |         Err(_) => true,\nLL | |     };\n   | |_____^ help: try: `Err::<i32, i32>(42).is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:156:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Ok(_) => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^ help: try: `x.is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:162:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Ok(_) => false,\nLL | |         _ => true,\nLL | |     };\n   | |_____^ help: try: `x.is_err()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:168:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Err(_) => true,\nLL | |         _ => false,\nLL | |     };\n   | |_____^ help: try: `x.is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:174:5\n   |\nLL | /     match x {\nLL | |\nLL | |         Err(_) => false,\nLL | |         _ => true,\nLL | |     };\n   | |_____^ help: try: `x.is_ok()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:196:13\n   |\nLL |     let _ = matches!(x, Ok(_));\n   |             ^^^^^^^^^^^^^^^^^^ help: try: `x.is_ok()`\n\nerror: redundant pattern matching, consider using `is_err()`\n  --> tests/ui/redundant_pattern_matching_result.rs:199:13\n   |\nLL |     let _ = matches!(x, Err(_));\n   |             ^^^^^^^^^^^^^^^^^^^ help: try: `x.is_err()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:216:13\n   |\nLL |       let _ = match test_expr!(42) {\n   |  _____________^\nLL | |\nLL | |         Ok(_) => true,\nLL | |         Err(_) => false,\nLL | |     };\n   | |_____^ help: try: `test_expr!(42).is_ok()`\n\nerror: redundant pattern matching, consider using `is_ok()`\n  --> tests/ui/redundant_pattern_matching_result.rs:229:13\n   |\nLL |     let _ = matches!(x, Ok(_) if test_guard!(42));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_ok() && test_guard!(42)`\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_pub_crate.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(dead_code)]\n#![warn(clippy::redundant_pub_crate)]\n\nmod m1 {\n    fn f() {}\n    pub fn g() {} // private due to m1\n    //\n    //~^^ redundant_pub_crate\n    pub fn h() {}\n\n    mod m1_1 {\n        fn f() {}\n        pub fn g() {} // private due to m1_1 and m1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m1_2 {\n        //~^ redundant_pub_crate\n        //:^ private due to m1\n        fn f() {}\n        pub fn g() {} // private due to m1_2 and m1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m1_3 {\n        fn f() {}\n        pub fn g() {} // private due to m1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n}\n\npub(crate) mod m2 {\n    fn f() {}\n    pub fn g() {} // already crate visible due to m2\n    //\n    //~^^ redundant_pub_crate\n    pub fn h() {}\n\n    mod m2_1 {\n        fn f() {}\n        pub fn g() {} // private due to m2_1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m2_2 {\n        //~^ redundant_pub_crate\n        //:^ already crate visible due to m2\n        fn f() {}\n        pub fn g() {} // already crate visible due to m2_2 and m2\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m2_3 {\n        fn f() {}\n        pub fn g() {} // already crate visible due to m2\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n}\n\npub mod m3 {\n    fn f() {}\n    pub(crate) fn g() {} // ok: m3 is exported\n    pub fn h() {}\n\n    mod m3_1 {\n        fn f() {}\n        pub fn g() {} // private due to m3_1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub(crate) mod m3_2 {\n        //:^ ok\n        fn f() {}\n        pub fn g() {} // already crate visible due to m3_2\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m3_3 {\n        fn f() {}\n        pub(crate) fn g() {} // ok: m3 and m3_3 are exported\n        pub fn h() {}\n    }\n}\n\nmod m4 {\n    fn f() {}\n    pub fn g() {} // private: not re-exported by `pub use m4::*`\n    //\n    //~^^ redundant_pub_crate\n    pub fn h() {}\n\n    mod m4_1 {\n        fn f() {}\n        pub fn g() {} // private due to m4_1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m4_2 {\n        //~^ redundant_pub_crate\n        //:^ private: not re-exported by `pub use m4::*`\n        fn f() {}\n        pub fn g() {} // private due to m4_2\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m4_3 {\n        fn f() {}\n        pub(crate) fn g() {} // ok: m4_3 is re-exported by `pub use m4::*`\n        pub fn h() {}\n    }\n}\n\nmod m5 {\n    pub mod m5_1 {}\n    // Test that the primary span isn't butchered for item kinds that don't have an ident.\n    pub use m5_1::*; //~ redundant_pub_crate\n    #[rustfmt::skip]\n    pub use m5_1::{*}; //~ redundant_pub_crate\n}\n\npub use m4::*;\n\nmod issue_8732 {\n    #[allow(unused_macros)]\n    macro_rules! some_macro {\n        () => {};\n    }\n\n    #[allow(unused_imports)]\n    pub(crate) use some_macro; // ok: macro exports are exempt\n}\n\nproc_macros::external! {\n    mod priv_mod {\n        pub(crate) fn dummy() {}\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/redundant_pub_crate.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(dead_code)]\n#![warn(clippy::redundant_pub_crate)]\n\nmod m1 {\n    fn f() {}\n    pub(crate) fn g() {} // private due to m1\n    //\n    //~^^ redundant_pub_crate\n    pub fn h() {}\n\n    mod m1_1 {\n        fn f() {}\n        pub(crate) fn g() {} // private due to m1_1 and m1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub(crate) mod m1_2 {\n        //~^ redundant_pub_crate\n        //:^ private due to m1\n        fn f() {}\n        pub(crate) fn g() {} // private due to m1_2 and m1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m1_3 {\n        fn f() {}\n        pub(crate) fn g() {} // private due to m1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n}\n\npub(crate) mod m2 {\n    fn f() {}\n    pub(crate) fn g() {} // already crate visible due to m2\n    //\n    //~^^ redundant_pub_crate\n    pub fn h() {}\n\n    mod m2_1 {\n        fn f() {}\n        pub(crate) fn g() {} // private due to m2_1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub(crate) mod m2_2 {\n        //~^ redundant_pub_crate\n        //:^ already crate visible due to m2\n        fn f() {}\n        pub(crate) fn g() {} // already crate visible due to m2_2 and m2\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m2_3 {\n        fn f() {}\n        pub(crate) fn g() {} // already crate visible due to m2\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n}\n\npub mod m3 {\n    fn f() {}\n    pub(crate) fn g() {} // ok: m3 is exported\n    pub fn h() {}\n\n    mod m3_1 {\n        fn f() {}\n        pub(crate) fn g() {} // private due to m3_1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub(crate) mod m3_2 {\n        //:^ ok\n        fn f() {}\n        pub(crate) fn g() {} // already crate visible due to m3_2\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m3_3 {\n        fn f() {}\n        pub(crate) fn g() {} // ok: m3 and m3_3 are exported\n        pub fn h() {}\n    }\n}\n\nmod m4 {\n    fn f() {}\n    pub(crate) fn g() {} // private: not re-exported by `pub use m4::*`\n    //\n    //~^^ redundant_pub_crate\n    pub fn h() {}\n\n    mod m4_1 {\n        fn f() {}\n        pub(crate) fn g() {} // private due to m4_1\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub(crate) mod m4_2 {\n        //~^ redundant_pub_crate\n        //:^ private: not re-exported by `pub use m4::*`\n        fn f() {}\n        pub(crate) fn g() {} // private due to m4_2\n        //\n        //~^^ redundant_pub_crate\n        pub fn h() {}\n    }\n\n    pub mod m4_3 {\n        fn f() {}\n        pub(crate) fn g() {} // ok: m4_3 is re-exported by `pub use m4::*`\n        pub fn h() {}\n    }\n}\n\nmod m5 {\n    pub mod m5_1 {}\n    // Test that the primary span isn't butchered for item kinds that don't have an ident.\n    pub(crate) use m5_1::*; //~ redundant_pub_crate\n    #[rustfmt::skip]\n    pub(crate) use m5_1::{*}; //~ redundant_pub_crate\n}\n\npub use m4::*;\n\nmod issue_8732 {\n    #[allow(unused_macros)]\n    macro_rules! some_macro {\n        () => {};\n    }\n\n    #[allow(unused_imports)]\n    pub(crate) use some_macro; // ok: macro exports are exempt\n}\n\nproc_macros::external! {\n    mod priv_mod {\n        pub(crate) fn dummy() {}\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/redundant_pub_crate.stderr",
    "content": "error: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:7:5\n   |\nLL |     pub(crate) fn g() {} // private due to m1\n   |     ----------^^^^^\n   |     |\n   |     help: consider using: `pub`\n   |\n   = note: `-D clippy::redundant-pub-crate` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_pub_crate)]`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:14:9\n   |\nLL |         pub(crate) fn g() {} // private due to m1_1 and m1\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) module inside private module\n  --> tests/ui/redundant_pub_crate.rs:20:5\n   |\nLL |     pub(crate) mod m1_2 {\n   |     ----------^^^^^^^^^\n   |     |\n   |     help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:24:9\n   |\nLL |         pub(crate) fn g() {} // private due to m1_2 and m1\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:32:9\n   |\nLL |         pub(crate) fn g() {} // private due to m1\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:41:5\n   |\nLL |     pub(crate) fn g() {} // already crate visible due to m2\n   |     ----------^^^^^\n   |     |\n   |     help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:48:9\n   |\nLL |         pub(crate) fn g() {} // private due to m2_1\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) module inside private module\n  --> tests/ui/redundant_pub_crate.rs:54:5\n   |\nLL |     pub(crate) mod m2_2 {\n   |     ----------^^^^^^^^^\n   |     |\n   |     help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:58:9\n   |\nLL |         pub(crate) fn g() {} // already crate visible due to m2_2 and m2\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:66:9\n   |\nLL |         pub(crate) fn g() {} // already crate visible due to m2\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:80:9\n   |\nLL |         pub(crate) fn g() {} // private due to m3_1\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:89:9\n   |\nLL |         pub(crate) fn g() {} // already crate visible due to m3_2\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:104:5\n   |\nLL |     pub(crate) fn g() {} // private: not re-exported by `pub use m4::*`\n   |     ----------^^^^^\n   |     |\n   |     help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:111:9\n   |\nLL |         pub(crate) fn g() {} // private due to m4_1\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) module inside private module\n  --> tests/ui/redundant_pub_crate.rs:117:5\n   |\nLL |     pub(crate) mod m4_2 {\n   |     ----------^^^^^^^^^\n   |     |\n   |     help: consider using: `pub`\n\nerror: pub(crate) function inside private module\n  --> tests/ui/redundant_pub_crate.rs:121:9\n   |\nLL |         pub(crate) fn g() {} // private due to m4_2\n   |         ----------^^^^^\n   |         |\n   |         help: consider using: `pub`\n\nerror: pub(crate) import inside private module\n  --> tests/ui/redundant_pub_crate.rs:137:5\n   |\nLL |     pub(crate) use m5_1::*;\n   |     ----------^^^^^^^^^^^^^\n   |     |\n   |     help: consider using: `pub`\n\nerror: pub(crate) import inside private module\n  --> tests/ui/redundant_pub_crate.rs:139:27\n   |\nLL |     pub(crate) use m5_1::{*};\n   |     ----------            ^\n   |     |\n   |     help: consider using: `pub`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_slicing.fixed",
    "content": "#![allow(unused, clippy::deref_by_slicing)]\n#![warn(clippy::redundant_slicing)]\n\nuse std::io::Read;\n\nfn main() {\n    let slice: &[u32] = &[0];\n    let _ = slice; // Redundant slice\n    //\n    //~^^ redundant_slicing\n\n    let v = vec![0];\n    let _ = &v[..]; // Ok, results in `&[_]`\n    let _ = (&*v); // Outer borrow is redundant\n    //\n    //~^^ redundant_slicing\n\n    static S: &[u8] = &[0, 1, 2];\n    let _ = &mut &S[..]; // Ok, re-borrows slice\n\n    let mut vec = vec![0];\n    let mut_slice = &mut vec[..]; // Ok, results in `&mut [_]`\n    let _ = &mut mut_slice[..]; // Ok, re-borrows slice\n\n    let ref_vec = &vec;\n    let _ = &ref_vec[..]; // Ok, results in `&[_]`\n\n    macro_rules! m {\n        ($e:expr) => {\n            $e\n        };\n    }\n    let _ = slice;\n    //~^ redundant_slicing\n\n    macro_rules! m2 {\n        ($e:expr) => {\n            &$e[..]\n        };\n    }\n    let _ = m2!(slice); // Don't lint in a macro\n\n    let slice_ref = &slice;\n    let _ = &slice_ref[..]; // Ok, derefs slice\n\n    // Issue #7972\n    let bytes: &[u8] = &[];\n    let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Ok, re-borrows slice\n}\n"
  },
  {
    "path": "tests/ui/redundant_slicing.rs",
    "content": "#![allow(unused, clippy::deref_by_slicing)]\n#![warn(clippy::redundant_slicing)]\n\nuse std::io::Read;\n\nfn main() {\n    let slice: &[u32] = &[0];\n    let _ = &slice[..]; // Redundant slice\n    //\n    //~^^ redundant_slicing\n\n    let v = vec![0];\n    let _ = &v[..]; // Ok, results in `&[_]`\n    let _ = &(&*v)[..]; // Outer borrow is redundant\n    //\n    //~^^ redundant_slicing\n\n    static S: &[u8] = &[0, 1, 2];\n    let _ = &mut &S[..]; // Ok, re-borrows slice\n\n    let mut vec = vec![0];\n    let mut_slice = &mut vec[..]; // Ok, results in `&mut [_]`\n    let _ = &mut mut_slice[..]; // Ok, re-borrows slice\n\n    let ref_vec = &vec;\n    let _ = &ref_vec[..]; // Ok, results in `&[_]`\n\n    macro_rules! m {\n        ($e:expr) => {\n            $e\n        };\n    }\n    let _ = &m!(slice)[..];\n    //~^ redundant_slicing\n\n    macro_rules! m2 {\n        ($e:expr) => {\n            &$e[..]\n        };\n    }\n    let _ = m2!(slice); // Don't lint in a macro\n\n    let slice_ref = &slice;\n    let _ = &slice_ref[..]; // Ok, derefs slice\n\n    // Issue #7972\n    let bytes: &[u8] = &[];\n    let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap(); // Ok, re-borrows slice\n}\n"
  },
  {
    "path": "tests/ui/redundant_slicing.stderr",
    "content": "error: redundant slicing of the whole range\n  --> tests/ui/redundant_slicing.rs:8:13\n   |\nLL |     let _ = &slice[..]; // Redundant slice\n   |             ^^^^^^^^^^ help: use the original value instead: `slice`\n   |\n   = note: `-D clippy::redundant-slicing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_slicing)]`\n\nerror: redundant slicing of the whole range\n  --> tests/ui/redundant_slicing.rs:14:13\n   |\nLL |     let _ = &(&*v)[..]; // Outer borrow is redundant\n   |             ^^^^^^^^^^ help: use the original value instead: `(&*v)`\n\nerror: redundant slicing of the whole range\n  --> tests/ui/redundant_slicing.rs:33:13\n   |\nLL |     let _ = &m!(slice)[..];\n   |             ^^^^^^^^^^^^^^ help: use the original value instead: `slice`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_static_lifetimes.fixed",
    "content": "#![allow(unused)]\n// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint\n#![allow(static_mut_refs)]\n\n#[derive(Debug)]\nstruct Foo;\n\nconst VAR_ONE: &str = \"Test constant #1\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nconst VAR_TWO: &str = \"Test constant #2\"; // This line should not raise a warning.\n\nconst VAR_THREE: &[&str] = &[\"one\", \"two\"]; // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n\nconst VAR_FOUR: (&str, (&str, &str), &str) = (\"on\", (\"th\", \"th\"), \"on\"); // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n//~| redundant_static_lifetimes\n\nconst VAR_SIX: &u8 = &5;\n//~^ redundant_static_lifetimes\n\nconst VAR_HEIGHT: &Foo = &Foo {};\n//~^ redundant_static_lifetimes\n\nconst VAR_SLICE: &[u8] = b\"Test constant #1\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nconst VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nconst VAR_ARRAY: &[u8; 1] = b\"T\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_ONE: &str = \"Test static #1\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_TWO: &str = \"Test static #2\"; // This line should not raise a warning.\n\nstatic STATIC_VAR_THREE: &[&str] = &[\"one\", \"two\"]; // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_SIX: &u8 = &5;\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_HEIGHT: &Foo = &Foo {};\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_SLICE: &[u8] = b\"Test static #3\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_TUPLE: &(u8, u8) = &(1, 2); // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_ARRAY: &[u8; 1] = b\"T\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic mut STATIC_MUT_SLICE: &mut [u32] = &mut [0];\n//~^ redundant_static_lifetimes\n\nfn main() {\n    let false_positive: &'static str = \"test\";\n\n    unsafe {\n        STATIC_MUT_SLICE[0] = 0;\n    }\n}\n\ntrait Bar {\n    const TRAIT_VAR: &'static str;\n}\n\nimpl Foo {\n    const IMPL_VAR: &'static str = \"var\";\n}\n\nimpl Bar for Foo {\n    const TRAIT_VAR: &'static str = \"foo\";\n}\n\n#[clippy::msrv = \"1.16\"]\nfn msrv_1_16() {\n    static V: &'static u8 = &16;\n}\n\n#[clippy::msrv = \"1.17\"]\nfn msrv_1_17() {\n    static V: &u8 = &17;\n    //~^ redundant_static_lifetimes\n}\n"
  },
  {
    "path": "tests/ui/redundant_static_lifetimes.rs",
    "content": "#![allow(unused)]\n// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint\n#![allow(static_mut_refs)]\n\n#[derive(Debug)]\nstruct Foo;\n\nconst VAR_ONE: &'static str = \"Test constant #1\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nconst VAR_TWO: &str = \"Test constant #2\"; // This line should not raise a warning.\n\nconst VAR_THREE: &[&'static str] = &[\"one\", \"two\"]; // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n\nconst VAR_FOUR: (&str, (&str, &'static str), &'static str) = (\"on\", (\"th\", \"th\"), \"on\"); // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n//~| redundant_static_lifetimes\n\nconst VAR_SIX: &'static u8 = &5;\n//~^ redundant_static_lifetimes\n\nconst VAR_HEIGHT: &'static Foo = &Foo {};\n//~^ redundant_static_lifetimes\n\nconst VAR_SLICE: &'static [u8] = b\"Test constant #1\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nconst VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nconst VAR_ARRAY: &'static [u8; 1] = b\"T\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_ONE: &'static str = \"Test static #1\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_TWO: &str = \"Test static #2\"; // This line should not raise a warning.\n\nstatic STATIC_VAR_THREE: &[&'static str] = &[\"one\", \"two\"]; // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_SIX: &'static u8 = &5;\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_HEIGHT: &'static Foo = &Foo {};\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_SLICE: &'static [u8] = b\"Test static #3\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic STATIC_VAR_ARRAY: &'static [u8; 1] = b\"T\"; // ERROR: Consider removing 'static.\n//~^ redundant_static_lifetimes\n\nstatic mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0];\n//~^ redundant_static_lifetimes\n\nfn main() {\n    let false_positive: &'static str = \"test\";\n\n    unsafe {\n        STATIC_MUT_SLICE[0] = 0;\n    }\n}\n\ntrait Bar {\n    const TRAIT_VAR: &'static str;\n}\n\nimpl Foo {\n    const IMPL_VAR: &'static str = \"var\";\n}\n\nimpl Bar for Foo {\n    const TRAIT_VAR: &'static str = \"foo\";\n}\n\n#[clippy::msrv = \"1.16\"]\nfn msrv_1_16() {\n    static V: &'static u8 = &16;\n}\n\n#[clippy::msrv = \"1.17\"]\nfn msrv_1_17() {\n    static V: &'static u8 = &17;\n    //~^ redundant_static_lifetimes\n}\n"
  },
  {
    "path": "tests/ui/redundant_static_lifetimes.stderr",
    "content": "error: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:8:17\n   |\nLL | const VAR_ONE: &'static str = \"Test constant #1\"; // ERROR: Consider removing 'static.\n   |                -^^^^^^^---- help: consider removing `'static`: `&str`\n   |\n   = note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_static_lifetimes)]`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:13:21\n   |\nLL | const VAR_THREE: &[&'static str] = &[\"one\", \"two\"]; // ERROR: Consider removing 'static\n   |                    -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:16:32\n   |\nLL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = (\"on\", (\"th\", \"th\"), \"on\"); // ERROR: Consider removing 'static\n   |                               -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:16:47\n   |\nLL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = (\"on\", (\"th\", \"th\"), \"on\"); // ERROR: Consider removing 'static\n   |                                              -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:20:17\n   |\nLL | const VAR_SIX: &'static u8 = &5;\n   |                -^^^^^^^--- help: consider removing `'static`: `&u8`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:23:20\n   |\nLL | const VAR_HEIGHT: &'static Foo = &Foo {};\n   |                   -^^^^^^^---- help: consider removing `'static`: `&Foo`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:26:19\n   |\nLL | const VAR_SLICE: &'static [u8] = b\"Test constant #1\"; // ERROR: Consider removing 'static.\n   |                  -^^^^^^^----- help: consider removing `'static`: `&[u8]`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:29:19\n   |\nLL | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.\n   |                  -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:32:19\n   |\nLL | const VAR_ARRAY: &'static [u8; 1] = b\"T\"; // ERROR: Consider removing 'static.\n   |                  -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:35:25\n   |\nLL | static STATIC_VAR_ONE: &'static str = \"Test static #1\"; // ERROR: Consider removing 'static.\n   |                        -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:40:29\n   |\nLL | static STATIC_VAR_THREE: &[&'static str] = &[\"one\", \"two\"]; // ERROR: Consider removing 'static\n   |                            -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:43:25\n   |\nLL | static STATIC_VAR_SIX: &'static u8 = &5;\n   |                        -^^^^^^^--- help: consider removing `'static`: `&u8`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:46:28\n   |\nLL | static STATIC_VAR_HEIGHT: &'static Foo = &Foo {};\n   |                           -^^^^^^^---- help: consider removing `'static`: `&Foo`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:49:27\n   |\nLL | static STATIC_VAR_SLICE: &'static [u8] = b\"Test static #3\"; // ERROR: Consider removing 'static.\n   |                          -^^^^^^^----- help: consider removing `'static`: `&[u8]`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:52:27\n   |\nLL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.\n   |                          -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:55:27\n   |\nLL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b\"T\"; // ERROR: Consider removing 'static.\n   |                          -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:58:31\n   |\nLL | static mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0];\n   |                              -^^^^^^^---------- help: consider removing `'static`: `&mut [u32]`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes.rs:88:16\n   |\nLL |     static V: &'static u8 = &17;\n   |               -^^^^^^^--- help: consider removing `'static`: `&u8`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_static_lifetimes_multiple.rs",
    "content": "//@no-rustfix: overlapping suggestions\n// these are rustfixable, but run-rustfix tests cannot handle them\n\nconst VAR_FIVE: &'static [&[&'static str]] = &[&[\"test\"], &[\"other one\"]]; // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n//~| redundant_static_lifetimes\n\nconst VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&(\"one\", &[\"other one\"])];\n//~^ redundant_static_lifetimes\n//~| redundant_static_lifetimes\n\nstatic STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = (\"on\", (\"th\", \"th\"), \"on\"); // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n//~| redundant_static_lifetimes\n\nstatic STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&[\"test\"], &[\"other one\"]]; // ERROR: Consider removing 'static\n//~^ redundant_static_lifetimes\n//~| redundant_static_lifetimes\n\nstatic STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&(\"one\", &[\"other one\"])];\n//~^ redundant_static_lifetimes\n//~| redundant_static_lifetimes\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/redundant_static_lifetimes_multiple.stderr",
    "content": "error: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:4:18\n   |\nLL | const VAR_FIVE: &'static [&[&'static str]] = &[&[\"test\"], &[\"other one\"]]; // ERROR: Consider removing 'static\n   |                 -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`\n   |\n   = note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_static_lifetimes)]`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:4:30\n   |\nLL | const VAR_FIVE: &'static [&[&'static str]] = &[&[\"test\"], &[\"other one\"]]; // ERROR: Consider removing 'static\n   |                             -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:8:29\n   |\nLL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&(\"one\", &[\"other one\"])];\n   |                            -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`\n\nerror: constants have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:8:39\n   |\nLL | const VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&(\"one\", &[\"other one\"])];\n   |                                      -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:12:40\n   |\nLL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = (\"on\", (\"th\", \"th\"), \"on\"); // ERROR: Consider removing 'static\n   |                                       -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:12:55\n   |\nLL | static STATIC_VAR_FOUR: (&str, (&str, &'static str), &'static str) = (\"on\", (\"th\", \"th\"), \"on\"); // ERROR: Consider removing 'static\n   |                                                      -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:16:26\n   |\nLL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&[\"test\"], &[\"other one\"]]; // ERROR: Consider removing 'static\n   |                         -^^^^^^^------------------ help: consider removing `'static`: `&[&[&'static str]]`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:16:38\n   |\nLL | static STATIC_VAR_FIVE: &'static [&[&'static str]] = &[&[\"test\"], &[\"other one\"]]; // ERROR: Consider removing 'static\n   |                                     -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:20:37\n   |\nLL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&(\"one\", &[\"other one\"])];\n   |                                    -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`\n\nerror: statics have by default a `'static` lifetime\n  --> tests/ui/redundant_static_lifetimes_multiple.rs:20:47\n   |\nLL | static STATIC_VAR_SEVEN: &[&(&str, &'static [&'static str])] = &[&(\"one\", &[\"other one\"])];\n   |                                              -^^^^^^^---- help: consider removing `'static`: `&str`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_test_prefix.fixed",
    "content": "#![allow(dead_code)]\n#![warn(clippy::redundant_test_prefix)]\n\nfn main() {\n    // Normal function, no redundant prefix.\n}\n\nfn f1() {\n    // Normal function, no redundant prefix.\n}\n\nfn test_f2() {\n    // Has prefix, but no `#[test]` attribute, ignore.\n}\n\n#[test]\nfn f3() {\n    //~^ redundant_test_prefix\n\n    // Has prefix, has `#[test]` attribute. Not within a `#[cfg(test)]`.\n    // No collision with other functions, should emit warning.\n}\n\n#[cfg(test)]\n#[test]\nfn f4() {\n    //~^ redundant_test_prefix\n\n    // Has prefix, has `#[test]` attribute, within a `#[cfg(test)]`.\n    // No collision with other functions, should emit warning.\n}\n\nmod m1 {\n    pub fn f5() {}\n}\n\n#[cfg(test)]\n#[test]\nfn f6() {\n    //~^ redundant_test_prefix\n\n    use m1::f5;\n\n    f5();\n    // Has prefix, has `#[test]` attribute, within a `#[cfg(test)]`.\n    // No collision, has function call, but it will not result in recursion.\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn foo() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn foo_with_call() {\n        //~^ redundant_test_prefix\n\n        main();\n    }\n\n    #[test]\n    fn f1() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f2() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f3() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f4() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f5() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f6() {\n        //~^ redundant_test_prefix\n    }\n}\n\nmod tests_no_annotations {\n    use super::*;\n\n    #[test]\n    fn foo() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn foo_with_call() {\n        //~^ redundant_test_prefix\n\n        main();\n    }\n\n    #[test]\n    fn f1() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f2() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f3() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f4() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f5() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn f6() {\n        //~^ redundant_test_prefix\n    }\n}\n\n// This test is inspired by real test in `clippy_utils/src/sugg.rs`.\n// The `is_in_test_function()` checks whether any identifier within a given node's parents is\n// marked with `#[test]` attribute. Thus flagging false positives when nested functions are\n// prefixed with `test_`. Therefore `is_test_function()` has been defined in `clippy_utils`,\n// allowing to select only functions that are immediately marked with `#[test]` annotation.\n//\n// This test case ensures that for such nested functions no error is emitted.\n#[test]\nfn not_op() {\n    fn test_not(foo: bool) {\n        assert!(foo);\n    }\n\n    // Use helper function\n    test_not(true);\n    test_not(false);\n}\n"
  },
  {
    "path": "tests/ui/redundant_test_prefix.rs",
    "content": "#![allow(dead_code)]\n#![warn(clippy::redundant_test_prefix)]\n\nfn main() {\n    // Normal function, no redundant prefix.\n}\n\nfn f1() {\n    // Normal function, no redundant prefix.\n}\n\nfn test_f2() {\n    // Has prefix, but no `#[test]` attribute, ignore.\n}\n\n#[test]\nfn test_f3() {\n    //~^ redundant_test_prefix\n\n    // Has prefix, has `#[test]` attribute. Not within a `#[cfg(test)]`.\n    // No collision with other functions, should emit warning.\n}\n\n#[cfg(test)]\n#[test]\nfn test_f4() {\n    //~^ redundant_test_prefix\n\n    // Has prefix, has `#[test]` attribute, within a `#[cfg(test)]`.\n    // No collision with other functions, should emit warning.\n}\n\nmod m1 {\n    pub fn f5() {}\n}\n\n#[cfg(test)]\n#[test]\nfn test_f6() {\n    //~^ redundant_test_prefix\n\n    use m1::f5;\n\n    f5();\n    // Has prefix, has `#[test]` attribute, within a `#[cfg(test)]`.\n    // No collision, has function call, but it will not result in recursion.\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_foo() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_foo_with_call() {\n        //~^ redundant_test_prefix\n\n        main();\n    }\n\n    #[test]\n    fn test_f1() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f2() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f3() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f4() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f5() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f6() {\n        //~^ redundant_test_prefix\n    }\n}\n\nmod tests_no_annotations {\n    use super::*;\n\n    #[test]\n    fn test_foo() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_foo_with_call() {\n        //~^ redundant_test_prefix\n\n        main();\n    }\n\n    #[test]\n    fn test_f1() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f2() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f3() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f4() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f5() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f6() {\n        //~^ redundant_test_prefix\n    }\n}\n\n// This test is inspired by real test in `clippy_utils/src/sugg.rs`.\n// The `is_in_test_function()` checks whether any identifier within a given node's parents is\n// marked with `#[test]` attribute. Thus flagging false positives when nested functions are\n// prefixed with `test_`. Therefore `is_test_function()` has been defined in `clippy_utils`,\n// allowing to select only functions that are immediately marked with `#[test]` annotation.\n//\n// This test case ensures that for such nested functions no error is emitted.\n#[test]\nfn not_op() {\n    fn test_not(foo: bool) {\n        assert!(foo);\n    }\n\n    // Use helper function\n    test_not(true);\n    test_not(false);\n}\n"
  },
  {
    "path": "tests/ui/redundant_test_prefix.stderr",
    "content": "error: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:17:4\n   |\nLL | fn test_f3() {\n   |    ^^^^^^^ help: consider removing the `test_` prefix: `f3`\n   |\n   = note: `-D clippy::redundant-test-prefix` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_test_prefix)]`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:26:4\n   |\nLL | fn test_f4() {\n   |    ^^^^^^^ help: consider removing the `test_` prefix: `f4`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:39:4\n   |\nLL | fn test_f6() {\n   |    ^^^^^^^ help: consider removing the `test_` prefix: `f6`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:54:8\n   |\nLL |     fn test_foo() {\n   |        ^^^^^^^^ help: consider removing the `test_` prefix: `foo`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:59:8\n   |\nLL |     fn test_foo_with_call() {\n   |        ^^^^^^^^^^^^^^^^^^ help: consider removing the `test_` prefix: `foo_with_call`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:66:8\n   |\nLL |     fn test_f1() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f1`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:71:8\n   |\nLL |     fn test_f2() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f2`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:76:8\n   |\nLL |     fn test_f3() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f3`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:81:8\n   |\nLL |     fn test_f4() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f4`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:86:8\n   |\nLL |     fn test_f5() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f5`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:91:8\n   |\nLL |     fn test_f6() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f6`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:100:8\n   |\nLL |     fn test_foo() {\n   |        ^^^^^^^^ help: consider removing the `test_` prefix: `foo`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:105:8\n   |\nLL |     fn test_foo_with_call() {\n   |        ^^^^^^^^^^^^^^^^^^ help: consider removing the `test_` prefix: `foo_with_call`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:112:8\n   |\nLL |     fn test_f1() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f1`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:117:8\n   |\nLL |     fn test_f2() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f2`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:122:8\n   |\nLL |     fn test_f3() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f3`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:127:8\n   |\nLL |     fn test_f4() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f4`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:132:8\n   |\nLL |     fn test_f5() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f5`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix.rs:137:8\n   |\nLL |     fn test_f6() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f6`\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_test_prefix_noautofix.rs",
    "content": "//@no-rustfix: name conflicts\n\n#![allow(dead_code)]\n#![warn(clippy::redundant_test_prefix)]\n\nfn main() {\n    // Normal function, no redundant prefix.\n}\n\nfn f1() {\n    // Normal function, no redundant prefix.\n}\n\nfn test_f2() {\n    // Has prefix, but no `#[test]` attribute, ignore.\n}\n\n#[test]\nfn test_f3() {\n    //~^ redundant_test_prefix\n\n    // Has prefix, has `#[test]` attribute. Not within a `#[cfg(test)]`.\n    // No collision with other functions, should emit warning.\n}\n\n#[cfg(test)]\n#[test]\nfn test_f4() {\n    //~^ redundant_test_prefix\n\n    // Has prefix, has `#[test]` attribute, within a `#[cfg(test)]`.\n    // No collision with other functions, should emit warning.\n}\n\nfn f5() {}\n\n#[cfg(test)]\n#[test]\nfn test_f5() {\n    //~^ redundant_test_prefix\n\n    // Has prefix, has `#[test]` attribute, within a `#[cfg(test)]`.\n    // Collision with existing function.\n}\n\nmod m1 {\n    pub fn f6() {}\n    pub fn f7() {}\n}\n\n#[cfg(test)]\n#[test]\nfn test_f6() {\n    //~^ redundant_test_prefix\n\n    use m1::f6;\n\n    f6();\n    // Has prefix, has `#[test]` attribute, within a `#[cfg(test)]`.\n    // No collision, but has a function call that will result in recursion.\n}\n\n#[cfg(test)]\n#[test]\nfn test_f8() {\n    //~^ redundant_test_prefix\n\n    use m1::f7;\n\n    f7();\n    // Has prefix, has `#[test]` attribute, within a `#[cfg(test)]`.\n    // No collision, has function call, but it will not result in recursion.\n}\n\n// Although there's no direct call of `f` in the test, name collision still exists,\n// since all `m3` functions are imported and then `map` is used to call `f`.\nmod m2 {\n    mod m3 {\n        pub fn f(_: i32) -> i32 {\n            0\n        }\n    }\n\n    use m3::*;\n\n    #[cfg(test)]\n    #[test]\n    fn test_f() {\n        //~^ redundant_test_prefix\n        let a = Some(3);\n        let _ = a.map(f);\n    }\n}\n\nmod m3 {\n    fn test_m3_1() {\n        // Has prefix, but no `#[test]` attribute, ignore.\n    }\n\n    #[test]\n    fn test_m3_2() {\n        //~^ redundant_test_prefix\n\n        // Has prefix, has `#[test]` attribute. Not within a `#[cfg(test)]`.\n        // No collision with other functions, should emit warning.\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_foo() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_foo_with_call() {\n        //~^ redundant_test_prefix\n\n        main();\n    }\n\n    #[test]\n    fn test_f1() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f2() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f3() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f4() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f5() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f6() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_1() {\n        //~^ redundant_test_prefix\n\n        // `1` is invalid function name, so suggestion to rename is emitted\n    }\n\n    #[test]\n    fn test_const() {\n        //~^ redundant_test_prefix\n\n        // `const` is reserved keyword, so suggestion to rename is emitted\n    }\n\n    #[test]\n    fn test_async() {\n        //~^ redundant_test_prefix\n\n        // `async` is reserved keyword, so suggestion to rename is emitted\n    }\n\n    #[test]\n    fn test_yield() {\n        //~^ redundant_test_prefix\n\n        // `yield` is reserved keyword for future use, so suggestion to rename is emitted\n    }\n\n    #[test]\n    fn test_() {\n        //~^ redundant_test_prefix\n\n        // `` is invalid function name, so suggestion to rename is emitted\n    }\n}\n\nmod tests_no_annotations {\n    use super::*;\n\n    #[test]\n    fn test_foo() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_foo_with_call() {\n        //~^ redundant_test_prefix\n\n        main();\n    }\n\n    #[test]\n    fn test_f1() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f2() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f3() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f4() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f5() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_f6() {\n        //~^ redundant_test_prefix\n    }\n\n    #[test]\n    fn test_1() {\n        //~^ redundant_test_prefix\n\n        // `1` is invalid function name, so suggestion to rename is emitted\n    }\n\n    #[test]\n    fn test_const() {\n        //~^ redundant_test_prefix\n\n        // `const` is reserved keyword, so suggestion to rename is emitted\n    }\n\n    #[test]\n    fn test_async() {\n        //~^ redundant_test_prefix\n\n        // `async` is reserved keyword, so suggestion to rename is emitted\n    }\n\n    #[test]\n    fn test_yield() {\n        //~^ redundant_test_prefix\n\n        // `yield` is reserved keyword for future use, so suggestion to rename is emitted\n    }\n\n    #[test]\n    fn test_() {\n        //~^ redundant_test_prefix\n\n        // `` is invalid function name, so suggestion to rename is emitted\n    }\n}\n\n// This test is inspired by real test in `clippy_utils/src/sugg.rs`.\n// The `is_in_test_function()` checks whether any identifier within a given node's parents is\n// marked with `#[test]` attribute. Thus flagging false positives when nested functions are\n// prefixed with `test_`. Therefore `is_test_function()` has been defined in `clippy_utils`,\n// allowing to select only functions that are immediately marked with `#[test]` annotation.\n//\n// This test case ensures that for such nested functions no error is emitted.\n#[test]\nfn not_op() {\n    fn test_not(foo: bool) {\n        assert!(foo);\n    }\n\n    // Use helper function\n    test_not(true);\n    test_not(false);\n}\n"
  },
  {
    "path": "tests/ui/redundant_test_prefix_noautofix.stderr",
    "content": "error: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:19:4\n   |\nLL | fn test_f3() {\n   |    ^^^^^^^ help: consider removing the `test_` prefix: `f3`\n   |\n   = note: `-D clippy::redundant-test-prefix` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_test_prefix)]`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:28:4\n   |\nLL | fn test_f4() {\n   |    ^^^^^^^ help: consider removing the `test_` prefix: `f4`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:39:4\n   |\nLL | fn test_f5() {\n   |    ^^^^^^^\n   |\nhelp: consider function renaming (just removing `test_` prefix will cause a name conflict)\n   |\nLL - fn test_f5() {\nLL + fn f5_works() {\n   |\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:53:4\n   |\nLL | fn test_f6() {\n   |    ^^^^^^^\n   |\nhelp: consider function renaming (just removing `test_` prefix will cause a name conflict)\n   |\nLL - fn test_f6() {\nLL + fn f6_works() {\n   |\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:65:4\n   |\nLL | fn test_f8() {\n   |    ^^^^^^^ help: consider removing the `test_` prefix: `f8`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:88:8\n   |\nLL |     fn test_f() {\n   |        ^^^^^^\n   |\nhelp: consider function renaming (just removing `test_` prefix will cause a name conflict)\n   |\nLL -     fn test_f() {\nLL +     fn f_works() {\n   |\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:101:8\n   |\nLL |     fn test_m3_2() {\n   |        ^^^^^^^^^ help: consider removing the `test_` prefix: `m3_2`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:114:8\n   |\nLL |     fn test_foo() {\n   |        ^^^^^^^^ help: consider removing the `test_` prefix: `foo`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:119:8\n   |\nLL |     fn test_foo_with_call() {\n   |        ^^^^^^^^^^^^^^^^^^ help: consider removing the `test_` prefix: `foo_with_call`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:126:8\n   |\nLL |     fn test_f1() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f1`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:131:8\n   |\nLL |     fn test_f2() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f2`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:136:8\n   |\nLL |     fn test_f3() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f3`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:141:8\n   |\nLL |     fn test_f4() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f4`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:146:8\n   |\nLL |     fn test_f5() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f5`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:151:8\n   |\nLL |     fn test_f6() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f6`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:156:8\n   |\nLL |     fn test_1() {\n   |        ^^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:163:8\n   |\nLL |     fn test_const() {\n   |        ^^^^^^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:170:8\n   |\nLL |     fn test_async() {\n   |        ^^^^^^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:177:8\n   |\nLL |     fn test_yield() {\n   |        ^^^^^^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:184:8\n   |\nLL |     fn test_() {\n   |        ^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:195:8\n   |\nLL |     fn test_foo() {\n   |        ^^^^^^^^ help: consider removing the `test_` prefix: `foo`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:200:8\n   |\nLL |     fn test_foo_with_call() {\n   |        ^^^^^^^^^^^^^^^^^^ help: consider removing the `test_` prefix: `foo_with_call`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:207:8\n   |\nLL |     fn test_f1() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f1`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:212:8\n   |\nLL |     fn test_f2() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f2`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:217:8\n   |\nLL |     fn test_f3() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f3`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:222:8\n   |\nLL |     fn test_f4() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f4`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:227:8\n   |\nLL |     fn test_f5() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f5`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:232:8\n   |\nLL |     fn test_f6() {\n   |        ^^^^^^^ help: consider removing the `test_` prefix: `f6`\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:237:8\n   |\nLL |     fn test_1() {\n   |        ^^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:244:8\n   |\nLL |     fn test_const() {\n   |        ^^^^^^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:251:8\n   |\nLL |     fn test_async() {\n   |        ^^^^^^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:258:8\n   |\nLL |     fn test_yield() {\n   |        ^^^^^^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: redundant `test_` prefix in test function name\n  --> tests/ui/redundant_test_prefix_noautofix.rs:265:8\n   |\nLL |     fn test_() {\n   |        ^^^^^\n   |\n   = help: consider function renaming (just removing `test_` prefix will produce invalid function name)\n\nerror: aborting due to 33 previous errors\n\n"
  },
  {
    "path": "tests/ui/redundant_type_annotations.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::redundant_type_annotations)]\n\n#[derive(Debug, Default)]\nstruct Cake<T> {\n    _data: T,\n}\n\nfn make_something<T>() -> T {\n    unimplemented!()\n}\n\nfn make_cake<T: Default>() -> Cake<T> {\n    Cake::<T>::default()\n}\n\nfn plus_one<T: std::ops::Add<u8, Output = T>>(val: T) -> T {\n    val + 1\n}\n\n#[derive(Default)]\nstruct Slice {\n    inner: u32,\n}\n\n#[derive(Default)]\nstruct Pie {\n    inner: u32,\n    inner_struct: Slice,\n}\n\nenum Pizza {\n    One,\n    Two,\n}\n\nfn return_a_string() -> String {\n    String::new()\n}\n\nfn return_a_struct() -> Pie {\n    Pie::default()\n}\n\nfn return_an_enum() -> Pizza {\n    Pizza::One\n}\n\nfn return_an_int() -> u32 {\n    5\n}\n\nimpl Pie {\n    fn return_an_int(&self) -> u32 {\n        self.inner\n    }\n\n    fn return_a_ref(&self) -> &u32 {\n        &self.inner\n    }\n\n    fn return_a_ref_to_struct(&self) -> &Slice {\n        &self.inner_struct\n    }\n\n    fn associated_return_an_int() -> u32 {\n        5\n    }\n\n    fn new() -> Self {\n        Self::default()\n    }\n\n    fn associated_return_a_string() -> String {\n        String::from(\"\")\n    }\n\n    fn test_method_call(&self) {\n        // Everything here should be lint\n\n        let v: u32 = self.return_an_int();\n        //~^ redundant_type_annotations\n\n        let v: &u32 = self.return_a_ref();\n        //~^ redundant_type_annotations\n\n        let v: &Slice = self.return_a_ref_to_struct();\n        //~^ redundant_type_annotations\n    }\n}\n\nfn test_generics() {\n    // The type annotation is needed to determine T\n    let _c: Cake<i32> = make_something();\n\n    // The type annotation is needed to determine the topic\n    let _c: Cake<u8> = make_cake();\n\n    // This could be lint, but currently doesn't\n    let _c: Cake<u8> = make_cake::<u8>();\n\n    // This could be lint, but currently doesn't\n    let _c: u8 = make_something::<u8>();\n\n    // This could be lint, but currently doesn't\n    let _c: u8 = plus_one(5_u8);\n\n    // Annotation needed otherwise T is i32\n    let _c: u8 = plus_one(5);\n\n    // This could be lint, but currently doesn't\n    let _return: String = String::from(\"test\");\n}\n\nfn test_non_locals() {\n    // This shouldn't be lint\n    fn _arg(x: u32) -> u32 {\n        x\n    }\n\n    // This could lint, but probably shouldn't\n    let _closure_arg = |x: u32| x;\n}\n\ntrait Trait {\n    type AssocTy;\n}\n\nimpl Trait for () {\n    type AssocTy = String;\n}\n\nfn test_complex_types<T>() {\n    // Shouldn't be lint, since the literal will be i32 otherwise\n    let _u8: u8 = 128;\n\n    // This could be lint, but currently doesn't\n    let _tuple_i32: (i32, i32) = (12, 13);\n\n    // Shouldn't be lint, since the tuple will be i32 otherwise\n    let _tuple_u32: (u32, u32) = (1, 2);\n\n    // Should be lint, since the type is determined by the init value, but currently doesn't\n    let _tuple_u32: (u32, u32) = (3_u32, 4_u32);\n\n    // This could be lint, but currently doesn't\n    let _array: [i32; 3] = [5, 6, 7];\n\n    // Shouldn't be lint\n    let _array: [u32; 2] = [8, 9];\n\n    let ty_param: T = make_something();\n\n    let assoc_ty: <() as Trait>::AssocTy = String::new();\n}\n\nfn test_functions() {\n    // Everything here should be lint\n\n    let _return: String = return_a_string();\n    //~^ redundant_type_annotations\n\n    let _return: Pie = return_a_struct();\n    //~^ redundant_type_annotations\n\n    let _return: Pizza = return_an_enum();\n    //~^ redundant_type_annotations\n\n    let _return: u32 = return_an_int();\n    //~^ redundant_type_annotations\n\n    let _return: String = String::new();\n    //~^ redundant_type_annotations\n\n    let new_pie: Pie = Pie::new();\n    //~^ redundant_type_annotations\n\n    let _return: u32 = new_pie.return_an_int();\n    //~^ redundant_type_annotations\n\n    let _return: u32 = Pie::associated_return_an_int();\n    //~^ redundant_type_annotations\n\n    let _return: String = Pie::associated_return_a_string();\n    //~^ redundant_type_annotations\n}\n\nfn test_simple_types() {\n    // Everything here should be lint\n\n    let _var: u32 = u32::MAX;\n    //~^ redundant_type_annotations\n\n    let _var: u32 = 5_u32;\n    //~^ redundant_type_annotations\n\n    let _var: &str = \"test\";\n    //~^ redundant_type_annotations\n\n    let _var: &[u8; 4] = b\"test\";\n    //~^ redundant_type_annotations\n\n    let _var: bool = false;\n    //~^ redundant_type_annotations\n}\n\nfn issue12212() {\n    // This should not be linted\n    let _var: &[u8] = b\"test\";\n}\n\nfn issue11190() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/redundant_type_annotations.stderr",
    "content": "error: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:81:9\n   |\nLL |         let v: u32 = self.return_an_int();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::redundant-type-annotations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_type_annotations)]`\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:84:9\n   |\nLL |         let v: &u32 = self.return_a_ref();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:87:9\n   |\nLL |         let v: &Slice = self.return_a_ref_to_struct();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:160:5\n   |\nLL |     let _return: String = return_a_string();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:163:5\n   |\nLL |     let _return: Pie = return_a_struct();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:166:5\n   |\nLL |     let _return: Pizza = return_an_enum();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:169:5\n   |\nLL |     let _return: u32 = return_an_int();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:172:5\n   |\nLL |     let _return: String = String::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:175:5\n   |\nLL |     let new_pie: Pie = Pie::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:178:5\n   |\nLL |     let _return: u32 = new_pie.return_an_int();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:181:5\n   |\nLL |     let _return: u32 = Pie::associated_return_an_int();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:184:5\n   |\nLL |     let _return: String = Pie::associated_return_a_string();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:191:5\n   |\nLL |     let _var: u32 = u32::MAX;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:194:5\n   |\nLL |     let _var: u32 = 5_u32;\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:197:5\n   |\nLL |     let _var: &str = \"test\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:200:5\n   |\nLL |     let _var: &[u8; 4] = b\"test\";\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant type annotation\n  --> tests/ui/redundant_type_annotations.rs:203:5\n   |\nLL |     let _var: bool = false;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/ref_as_ptr.fixed",
    "content": "#![warn(clippy::ref_as_ptr)]\n#![allow(clippy::unnecessary_mut_passed, clippy::needless_lifetimes)]\n\nfn f<T>(_: T) {}\n\nfn main() {\n    f(std::ptr::from_ref(&1u8));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<u32>(&2u32));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<f64>(&3.0f64));\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref(&4) as *const f32);\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<f32>(&5.0f32) as *const u32);\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref(&mut 6u8));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<u32>(&mut 7u32));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<f64>(&mut 8.0f64));\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref(&mut 9) as *const f32);\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<f32>(&mut 10.0f32) as *const u32);\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_mut(&mut 11u8));\n    //~^ ref_as_ptr\n    f(std::ptr::from_mut::<u32>(&mut 12u32));\n    //~^ ref_as_ptr\n    f(std::ptr::from_mut::<f64>(&mut 13.0f64));\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_mut(&mut 14) as *const f32);\n    //~^ ref_as_ptr\n    f(std::ptr::from_mut::<f32>(&mut 15.0f32) as *const u32);\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref(&1u8));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<u32>(&2u32));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<f64>(&3.0f64));\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref(&4) as *const f32);\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<f32>(&5.0f32) as *const u32);\n    //~^ ref_as_ptr\n\n    let val = 1;\n    f(std::ptr::from_ref(&val));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<i32>(&val));\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref(&val) as *const f32);\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<i32>(&val) as *const f64);\n    //~^ ref_as_ptr\n\n    let mut val: u8 = 2;\n    f(std::ptr::from_mut::<u8>(&mut val));\n    //~^ ref_as_ptr\n    f(std::ptr::from_mut(&mut val));\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref::<u8>(&mut val));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref(&mut val));\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref::<u8>(&mut val) as *const f64);\n    //~^ ref_as_ptr\n    f::<*const Option<u8>>(std::ptr::from_ref(&mut val) as *const _);\n    //~^ ref_as_ptr\n\n    f(std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i)));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<[usize; 8]>(&mut std::array::from_fn(|i| i * i)));\n    //~^ ref_as_ptr\n    f(std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i)));\n    //~^ ref_as_ptr\n\n    let x = (10, 20);\n    let _ = std::ptr::from_ref(&x);\n    //~^ ref_as_ptr\n    let _ = std::ptr::from_ref(&x.0);\n    //~^ ref_as_ptr\n\n    let x = Box::new(10);\n    let _ = std::ptr::from_ref(&*x);\n    //~^ ref_as_ptr\n\n    let _ = &String::new() as *const _;\n    let _ = &mut String::new() as *mut _;\n    const FOO: *const String = &String::new() as *const _;\n}\n\n#[clippy::msrv = \"1.75\"]\nfn _msrv_1_75() {\n    let val = &42_i32;\n    let mut_val = &mut 42_i32;\n\n    // `std::ptr::from_{ref, mut}` was stabilized in 1.76. Do not lint this\n    f(val as *const i32);\n    f(mut_val as *mut i32);\n}\n\n#[clippy::msrv = \"1.76\"]\nfn _msrv_1_76() {\n    let val = &42_i32;\n    let mut_val = &mut 42_i32;\n\n    f(std::ptr::from_ref::<i32>(val));\n    //~^ ref_as_ptr\n    f(std::ptr::from_mut::<i32>(mut_val));\n    //~^ ref_as_ptr\n}\n\nfn foo(val: &[u8]) {\n    f(std::ptr::from_ref(val));\n    //~^ ref_as_ptr\n    f(std::ptr::from_ref::<[u8]>(val));\n    //~^ ref_as_ptr\n}\n\nfn bar(val: &mut str) {\n    f(std::ptr::from_mut(val));\n    //~^ ref_as_ptr\n    f(std::ptr::from_mut::<str>(val));\n    //~^ ref_as_ptr\n}\n\nstruct X<'a>(&'a i32);\n\nimpl<'a> X<'a> {\n    fn foo(&self) -> *const i64 {\n        std::ptr::from_ref(self.0) as *const _\n        //~^ ref_as_ptr\n    }\n\n    fn bar(&mut self) -> *const i64 {\n        std::ptr::from_ref(self.0) as *const _\n        //~^ ref_as_ptr\n    }\n}\n\nstruct Y<'a>(&'a mut i32);\n\nimpl<'a> Y<'a> {\n    fn foo(&self) -> *const i64 {\n        std::ptr::from_ref(self.0) as *const _\n        //~^ ref_as_ptr\n    }\n\n    fn bar(&mut self) -> *const i64 {\n        std::ptr::from_ref(self.0) as *const _\n        //~^ ref_as_ptr\n    }\n\n    fn baz(&mut self) -> *const i64 {\n        std::ptr::from_mut(self.0) as *mut _\n        //~^ ref_as_ptr\n    }\n}\n"
  },
  {
    "path": "tests/ui/ref_as_ptr.rs",
    "content": "#![warn(clippy::ref_as_ptr)]\n#![allow(clippy::unnecessary_mut_passed, clippy::needless_lifetimes)]\n\nfn f<T>(_: T) {}\n\nfn main() {\n    f(&1u8 as *const _);\n    //~^ ref_as_ptr\n    f(&2u32 as *const u32);\n    //~^ ref_as_ptr\n    f(&3.0f64 as *const f64);\n    //~^ ref_as_ptr\n\n    f(&4 as *const _ as *const f32);\n    //~^ ref_as_ptr\n    f(&5.0f32 as *const f32 as *const u32);\n    //~^ ref_as_ptr\n\n    f(&mut 6u8 as *const _);\n    //~^ ref_as_ptr\n    f(&mut 7u32 as *const u32);\n    //~^ ref_as_ptr\n    f(&mut 8.0f64 as *const f64);\n    //~^ ref_as_ptr\n\n    f(&mut 9 as *const _ as *const f32);\n    //~^ ref_as_ptr\n    f(&mut 10.0f32 as *const f32 as *const u32);\n    //~^ ref_as_ptr\n\n    f(&mut 11u8 as *mut _);\n    //~^ ref_as_ptr\n    f(&mut 12u32 as *mut u32);\n    //~^ ref_as_ptr\n    f(&mut 13.0f64 as *mut f64);\n    //~^ ref_as_ptr\n\n    f(&mut 14 as *mut _ as *const f32);\n    //~^ ref_as_ptr\n    f(&mut 15.0f32 as *mut f32 as *const u32);\n    //~^ ref_as_ptr\n\n    f(&1u8 as *const _);\n    //~^ ref_as_ptr\n    f(&2u32 as *const u32);\n    //~^ ref_as_ptr\n    f(&3.0f64 as *const f64);\n    //~^ ref_as_ptr\n\n    f(&4 as *const _ as *const f32);\n    //~^ ref_as_ptr\n    f(&5.0f32 as *const f32 as *const u32);\n    //~^ ref_as_ptr\n\n    let val = 1;\n    f(&val as *const _);\n    //~^ ref_as_ptr\n    f(&val as *const i32);\n    //~^ ref_as_ptr\n\n    f(&val as *const _ as *const f32);\n    //~^ ref_as_ptr\n    f(&val as *const i32 as *const f64);\n    //~^ ref_as_ptr\n\n    let mut val: u8 = 2;\n    f(&mut val as *mut u8);\n    //~^ ref_as_ptr\n    f(&mut val as *mut _);\n    //~^ ref_as_ptr\n\n    f(&mut val as *const u8);\n    //~^ ref_as_ptr\n    f(&mut val as *const _);\n    //~^ ref_as_ptr\n\n    f(&mut val as *const u8 as *const f64);\n    //~^ ref_as_ptr\n    f::<*const Option<u8>>(&mut val as *const _ as *const _);\n    //~^ ref_as_ptr\n\n    f(&std::array::from_fn(|i| i * i) as *const [usize; 7]);\n    //~^ ref_as_ptr\n    f(&mut std::array::from_fn(|i| i * i) as *const [usize; 8]);\n    //~^ ref_as_ptr\n    f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]);\n    //~^ ref_as_ptr\n\n    let x = (10, 20);\n    let _ = &x as *const _;\n    //~^ ref_as_ptr\n    let _ = &x.0 as *const _;\n    //~^ ref_as_ptr\n\n    let x = Box::new(10);\n    let _ = &*x as *const _;\n    //~^ ref_as_ptr\n\n    let _ = &String::new() as *const _;\n    let _ = &mut String::new() as *mut _;\n    const FOO: *const String = &String::new() as *const _;\n}\n\n#[clippy::msrv = \"1.75\"]\nfn _msrv_1_75() {\n    let val = &42_i32;\n    let mut_val = &mut 42_i32;\n\n    // `std::ptr::from_{ref, mut}` was stabilized in 1.76. Do not lint this\n    f(val as *const i32);\n    f(mut_val as *mut i32);\n}\n\n#[clippy::msrv = \"1.76\"]\nfn _msrv_1_76() {\n    let val = &42_i32;\n    let mut_val = &mut 42_i32;\n\n    f(val as *const i32);\n    //~^ ref_as_ptr\n    f(mut_val as *mut i32);\n    //~^ ref_as_ptr\n}\n\nfn foo(val: &[u8]) {\n    f(val as *const _);\n    //~^ ref_as_ptr\n    f(val as *const [u8]);\n    //~^ ref_as_ptr\n}\n\nfn bar(val: &mut str) {\n    f(val as *mut _);\n    //~^ ref_as_ptr\n    f(val as *mut str);\n    //~^ ref_as_ptr\n}\n\nstruct X<'a>(&'a i32);\n\nimpl<'a> X<'a> {\n    fn foo(&self) -> *const i64 {\n        self.0 as *const _ as *const _\n        //~^ ref_as_ptr\n    }\n\n    fn bar(&mut self) -> *const i64 {\n        self.0 as *const _ as *const _\n        //~^ ref_as_ptr\n    }\n}\n\nstruct Y<'a>(&'a mut i32);\n\nimpl<'a> Y<'a> {\n    fn foo(&self) -> *const i64 {\n        self.0 as *const _ as *const _\n        //~^ ref_as_ptr\n    }\n\n    fn bar(&mut self) -> *const i64 {\n        self.0 as *const _ as *const _\n        //~^ ref_as_ptr\n    }\n\n    fn baz(&mut self) -> *const i64 {\n        self.0 as *mut _ as *mut _\n        //~^ ref_as_ptr\n    }\n}\n"
  },
  {
    "path": "tests/ui/ref_as_ptr.stderr",
    "content": "error: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:7:7\n   |\nLL |     f(&1u8 as *const _);\n   |       ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&1u8)`\n   |\n   = note: `-D clippy::ref-as-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ref_as_ptr)]`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:9:7\n   |\nLL |     f(&2u32 as *const u32);\n   |       ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u32>(&2u32)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:11:7\n   |\nLL |     f(&3.0f64 as *const f64);\n   |       ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f64>(&3.0f64)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:14:7\n   |\nLL |     f(&4 as *const _ as *const f32);\n   |       ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&4)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:16:7\n   |\nLL |     f(&5.0f32 as *const f32 as *const u32);\n   |       ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f32>(&5.0f32)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:19:7\n   |\nLL |     f(&mut 6u8 as *const _);\n   |       ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut 6u8)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:21:7\n   |\nLL |     f(&mut 7u32 as *const u32);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u32>(&mut 7u32)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:23:7\n   |\nLL |     f(&mut 8.0f64 as *const f64);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f64>(&mut 8.0f64)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:26:7\n   |\nLL |     f(&mut 9 as *const _ as *const f32);\n   |       ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut 9)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:28:7\n   |\nLL |     f(&mut 10.0f32 as *const f32 as *const u32);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f32>(&mut 10.0f32)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:31:7\n   |\nLL |     f(&mut 11u8 as *mut _);\n   |       ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut 11u8)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:33:7\n   |\nLL |     f(&mut 12u32 as *mut u32);\n   |       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<u32>(&mut 12u32)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:35:7\n   |\nLL |     f(&mut 13.0f64 as *mut f64);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<f64>(&mut 13.0f64)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:38:7\n   |\nLL |     f(&mut 14 as *mut _ as *const f32);\n   |       ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut 14)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:40:7\n   |\nLL |     f(&mut 15.0f32 as *mut f32 as *const u32);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<f32>(&mut 15.0f32)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:43:7\n   |\nLL |     f(&1u8 as *const _);\n   |       ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&1u8)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:45:7\n   |\nLL |     f(&2u32 as *const u32);\n   |       ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u32>(&2u32)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:47:7\n   |\nLL |     f(&3.0f64 as *const f64);\n   |       ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f64>(&3.0f64)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:50:7\n   |\nLL |     f(&4 as *const _ as *const f32);\n   |       ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&4)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:52:7\n   |\nLL |     f(&5.0f32 as *const f32 as *const u32);\n   |       ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f32>(&5.0f32)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:56:7\n   |\nLL |     f(&val as *const _);\n   |       ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:58:7\n   |\nLL |     f(&val as *const i32);\n   |       ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<i32>(&val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:61:7\n   |\nLL |     f(&val as *const _ as *const f32);\n   |       ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:63:7\n   |\nLL |     f(&val as *const i32 as *const f64);\n   |       ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<i32>(&val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:67:7\n   |\nLL |     f(&mut val as *mut u8);\n   |       ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<u8>(&mut val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:69:7\n   |\nLL |     f(&mut val as *mut _);\n   |       ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:72:7\n   |\nLL |     f(&mut val as *const u8);\n   |       ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u8>(&mut val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:74:7\n   |\nLL |     f(&mut val as *const _);\n   |       ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:77:7\n   |\nLL |     f(&mut val as *const u8 as *const f64);\n   |       ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u8>(&mut val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:79:28\n   |\nLL |     f::<*const Option<u8>>(&mut val as *const _ as *const _);\n   |                            ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:82:7\n   |\nLL |     f(&std::array::from_fn(|i| i * i) as *const [usize; 7]);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i))`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:84:7\n   |\nLL |     f(&mut std::array::from_fn(|i| i * i) as *const [usize; 8]);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[usize; 8]>(&mut std::array::from_fn(|i| i * i))`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:86:7\n   |\nLL |     f(&mut std::array::from_fn(|i| i * i) as *mut [usize; 9]);\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:90:13\n   |\nLL |     let _ = &x as *const _;\n   |             ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&x)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:92:13\n   |\nLL |     let _ = &x.0 as *const _;\n   |             ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&x.0)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:96:13\n   |\nLL |     let _ = &*x as *const _;\n   |             ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&*x)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:119:7\n   |\nLL |     f(val as *const i32);\n   |       ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<i32>(val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:121:7\n   |\nLL |     f(mut_val as *mut i32);\n   |       ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<i32>(mut_val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:126:7\n   |\nLL |     f(val as *const _);\n   |       ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:128:7\n   |\nLL |     f(val as *const [u8]);\n   |       ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[u8]>(val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:133:7\n   |\nLL |     f(val as *mut _);\n   |       ^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:135:7\n   |\nLL |     f(val as *mut str);\n   |       ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<str>(val)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:143:9\n   |\nLL |         self.0 as *const _ as *const _\n   |         ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:148:9\n   |\nLL |         self.0 as *const _ as *const _\n   |         ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:157:9\n   |\nLL |         self.0 as *const _ as *const _\n   |         ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:162:9\n   |\nLL |         self.0 as *const _ as *const _\n   |         ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`\n\nerror: reference as raw pointer\n  --> tests/ui/ref_as_ptr.rs:167:9\n   |\nLL |         self.0 as *mut _ as *mut _\n   |         ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(self.0)`\n\nerror: aborting due to 47 previous errors\n\n"
  },
  {
    "path": "tests/ui/ref_binding_to_reference.rs",
    "content": "// FIXME: run-rustfix waiting on multi-span suggestions\n//@no-rustfix\n#![warn(clippy::ref_binding_to_reference)]\n#![allow(clippy::needless_borrowed_reference, clippy::explicit_auto_deref)]\n\nfn f1(_: &str) {}\nmacro_rules! m2 {\n    ($e:expr) => {\n        f1(*$e)\n    };\n}\nmacro_rules! m3 {\n    ($i:ident) => {\n        Some(ref $i)\n    };\n}\n\n#[allow(dead_code)]\nfn main() {\n    let x = String::new();\n\n    // Ok, the pattern is from a macro\n    let _: &&String = match Some(&x) {\n        m3!(x) => x,\n        None => return,\n    };\n\n    // Err, reference to a &String\n    let _: &&String = match Some(&x) {\n        Some(ref x) => x,\n        //~^ ref_binding_to_reference\n        None => return,\n    };\n\n    // Err, reference to a &String\n    let _: &&String = match Some(&x) {\n        Some(ref x) => {\n            //~^ ref_binding_to_reference\n\n            f1(x);\n            f1(*x);\n            x\n        },\n        None => return,\n    };\n\n    // Err, reference to a &String\n    match Some(&x) {\n        Some(ref x) => m2!(x),\n        //~^ ref_binding_to_reference\n        None => return,\n    }\n\n    // Err, reference to a &String\n    let _ = |&ref x: &&String| {\n        //~^ ref_binding_to_reference\n\n        let _: &&String = x;\n    };\n}\n\n// Err, reference to a &String\nfn f2<'a>(&ref x: &&'a String) -> &'a String {\n    //~^ ref_binding_to_reference\n\n    let _: &&String = x;\n    *x\n}\n\ntrait T1 {\n    // Err, reference to a &String\n    fn f(&ref x: &&String) {\n        //~^ ref_binding_to_reference\n\n        let _: &&String = x;\n    }\n}\n\nstruct S;\nimpl T1 for S {\n    // Err, reference to a &String\n    fn f(&ref x: &&String) {\n        //~^ ref_binding_to_reference\n\n        let _: &&String = x;\n    }\n}\n\nfn check_expect_suppression() {\n    let x = String::new();\n    #[expect(clippy::ref_binding_to_reference)]\n    let _: &&String = match Some(&x) {\n        Some(ref x) => x,\n        None => return,\n    };\n}\n"
  },
  {
    "path": "tests/ui/ref_binding_to_reference.stderr",
    "content": "error: this pattern creates a reference to a reference\n  --> tests/ui/ref_binding_to_reference.rs:30:14\n   |\nLL |         Some(ref x) => x,\n   |              ^^^^^\n   |\n   = note: `-D clippy::ref-binding-to-reference` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ref_binding_to_reference)]`\nhelp: try\n   |\nLL -         Some(ref x) => x,\nLL +         Some(x) => &x,\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/ref_binding_to_reference.rs:37:14\n   |\nLL |         Some(ref x) => {\n   |              ^^^^^\n   |\nhelp: try\n   |\nLL ~         Some(x) => {\nLL |\nLL |\nLL |             f1(x);\nLL ~             f1(x);\nLL ~             &x\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/ref_binding_to_reference.rs:49:14\n   |\nLL |         Some(ref x) => m2!(x),\n   |              ^^^^^\n   |\nhelp: try\n   |\nLL -         Some(ref x) => m2!(x),\nLL +         Some(x) => m2!(&x),\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/ref_binding_to_reference.rs:55:15\n   |\nLL |     let _ = |&ref x: &&String| {\n   |               ^^^^^\n   |\nhelp: try\n   |\nLL ~     let _ = |&x: &&String| {\nLL |\nLL |\nLL ~         let _: &&String = &x;\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/ref_binding_to_reference.rs:63:12\n   |\nLL | fn f2<'a>(&ref x: &&'a String) -> &'a String {\n   |            ^^^^^\n   |\nhelp: try\n   |\nLL ~ fn f2<'a>(&x: &&'a String) -> &'a String {\nLL |\nLL |\nLL ~     let _: &&String = &x;\nLL ~     x\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/ref_binding_to_reference.rs:72:11\n   |\nLL |     fn f(&ref x: &&String) {\n   |           ^^^^^\n   |\nhelp: try\n   |\nLL ~     fn f(&x: &&String) {\nLL |\nLL |\nLL ~         let _: &&String = &x;\n   |\n\nerror: this pattern creates a reference to a reference\n  --> tests/ui/ref_binding_to_reference.rs:82:11\n   |\nLL |     fn f(&ref x: &&String) {\n   |           ^^^^^\n   |\nhelp: try\n   |\nLL ~     fn f(&x: &&String) {\nLL |\nLL |\nLL ~         let _: &&String = &x;\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/ref_option_ref.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::ref_option_ref)]\n//@no-rustfix\n// This lint is not tagged as run-rustfix because automatically\n// changing the type of a variable would also means changing\n// all usages of this variable to match and This is not handled\n// by this lint.\n\nstatic THRESHOLD: i32 = 10;\nstatic REF_THRESHOLD: &Option<&i32> = &Some(&THRESHOLD);\n//~^ ref_option_ref\n\nconst CONST_THRESHOLD: &i32 = &10;\nconst REF_CONST: &Option<&i32> = &Some(CONST_THRESHOLD);\n//~^ ref_option_ref\n\ntype RefOptRefU32<'a> = &'a Option<&'a u32>;\n//~^ ref_option_ref\n\ntype RefOptRef<'a, T> = &'a Option<&'a T>;\n//~^ ref_option_ref\n\nfn foo(data: &Option<&u32>) {}\n//~^ ref_option_ref\n\nfn bar(data: &u32) -> &Option<&u32> {\n    //~^ ref_option_ref\n\n    &None\n}\n\nstruct StructRef<'a> {\n    data: &'a Option<&'a u32>,\n    //~^ ref_option_ref\n}\n\nstruct StructTupleRef<'a>(u32, &'a Option<&'a u32>);\n//~^ ref_option_ref\n\nenum EnumRef<'a> {\n    Variant1(u32),\n    Variant2(&'a Option<&'a u32>),\n    //~^ ref_option_ref\n}\n\ntrait RefOptTrait {\n    type A;\n    fn foo(&self, _: Self::A);\n}\n\nimpl RefOptTrait for u32 {\n    type A = &'static Option<&'static Self>;\n    //~^ ref_option_ref\n\n    fn foo(&self, _: Self::A) {}\n}\n\nfn main() {\n    let x: &Option<&u32> = &None;\n    //~^ ref_option_ref\n}\n\nfn issue9682(arg: &Option<&mut String>) {\n    // Should not lint, as the inner ref is mutable making it non `Copy`\n    println!(\"{arg:?}\");\n}\n"
  },
  {
    "path": "tests/ui/ref_option_ref.stderr",
    "content": "error: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:10:23\n   |\nLL | static REF_THRESHOLD: &Option<&i32> = &Some(&THRESHOLD);\n   |                       ^^^^^^^^^^^^^ help: try: `Option<&i32>`\n   |\n   = note: `-D clippy::ref-option-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ref_option_ref)]`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:14:18\n   |\nLL | const REF_CONST: &Option<&i32> = &Some(CONST_THRESHOLD);\n   |                  ^^^^^^^^^^^^^ help: try: `Option<&i32>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:17:25\n   |\nLL | type RefOptRefU32<'a> = &'a Option<&'a u32>;\n   |                         ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:20:25\n   |\nLL | type RefOptRef<'a, T> = &'a Option<&'a T>;\n   |                         ^^^^^^^^^^^^^^^^^ help: try: `Option<&'a T>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:23:14\n   |\nLL | fn foo(data: &Option<&u32>) {}\n   |              ^^^^^^^^^^^^^ help: try: `Option<&u32>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:26:23\n   |\nLL | fn bar(data: &u32) -> &Option<&u32> {\n   |                       ^^^^^^^^^^^^^ help: try: `Option<&u32>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:33:11\n   |\nLL |     data: &'a Option<&'a u32>,\n   |           ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:37:32\n   |\nLL | struct StructTupleRef<'a>(u32, &'a Option<&'a u32>);\n   |                                ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:42:14\n   |\nLL |     Variant2(&'a Option<&'a u32>),\n   |              ^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'a u32>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:52:14\n   |\nLL |     type A = &'static Option<&'static Self>;\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option<&'static Self>`\n\nerror: since `&` implements the `Copy` trait, `&Option<&T>` can be simplified to `Option<&T>`\n  --> tests/ui/ref_option_ref.rs:59:12\n   |\nLL |     let x: &Option<&u32> = &None;\n   |            ^^^^^^^^^^^^^ help: try: `Option<&u32>`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/ref_patterns.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::ref_patterns)]\n\nfn use_in_pattern() {\n    let opt = Some(5);\n    match opt {\n        None => {},\n        Some(ref opt) => {},\n        //~^ ref_patterns\n    }\n}\n\nfn use_in_binding() {\n    let x = 5;\n    let ref y = x;\n    //~^ ref_patterns\n}\n\nfn use_in_parameter(ref x: i32) {}\n//~^ ref_patterns\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/ref_patterns.stderr",
    "content": "error: usage of ref pattern\n  --> tests/ui/ref_patterns.rs:8:14\n   |\nLL |         Some(ref opt) => {},\n   |              ^^^^^^^\n   |\n   = help: consider using `&` for clarity instead\n   = note: `-D clippy::ref-patterns` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ref_patterns)]`\n\nerror: usage of ref pattern\n  --> tests/ui/ref_patterns.rs:15:9\n   |\nLL |     let ref y = x;\n   |         ^^^^^\n   |\n   = help: consider using `&` for clarity instead\n\nerror: usage of ref pattern\n  --> tests/ui/ref_patterns.rs:19:21\n   |\nLL | fn use_in_parameter(ref x: i32) {}\n   |                     ^^^^^\n   |\n   = help: consider using `&` for clarity instead\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/regex.rs",
    "content": "//@require-annotations-for-level: WARN\n#![allow(\n    unused,\n    clippy::needless_raw_strings,\n    clippy::needless_raw_string_hashes,\n    clippy::needless_borrow,\n    clippy::needless_borrows_for_generic_args\n)]\n#![warn(clippy::invalid_regex, clippy::trivial_regex, clippy::regex_creation_in_loops)]\n\nextern crate regex;\n\nuse regex::bytes::{Regex as BRegex, RegexBuilder as BRegexBuilder, RegexSet as BRegexSet};\nuse regex::{Regex, RegexBuilder, RegexSet};\n\nconst OPENING_PAREN: &str = \"(\";\nconst NOT_A_REAL_REGEX: &str = \"foobar\";\n\nfn syntax_error() {\n    let pipe_in_wrong_position = Regex::new(\"|\");\n    //~^ ERROR: trivial regex\n    let pipe_in_wrong_position_builder = RegexBuilder::new(\"|\");\n    //~^ ERROR: trivial regex\n    let wrong_char_ranice = Regex::new(\"[z-a]\");\n    //~^ ERROR: regex syntax error: invalid character class range, the start must be <= th\n    //~| NOTE: `-D clippy::invalid-regex` implied by `-D warnings`\n    let some_unicode = Regex::new(\"[é-è]\");\n    //~^ ERROR: regex syntax error: invalid character class range, the start must be <= th\n\n    let some_regex = Regex::new(OPENING_PAREN);\n    //~^ invalid_regex\n\n    let binary_pipe_in_wrong_position = BRegex::new(\"|\");\n    //~^ ERROR: trivial regex\n    let some_binary_regex = BRegex::new(OPENING_PAREN);\n    //~^ invalid_regex\n    let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN);\n    //~^ invalid_regex\n\n    let closing_paren = \")\";\n    let not_linted = Regex::new(closing_paren);\n\n    let set = RegexSet::new(&[r\"[a-z]+@[a-z]+\\.(com|org|net)\", r\"[a-z]+\\.(com|org|net)\"]);\n    let bset = BRegexSet::new(&[\n        r\"[a-z]+@[a-z]+\\.(com|org|net)\",\n        r\"[a-z]+\\.(com|org|net)\",\n        r\".\", // regression test\n    ]);\n\n    let set_error = RegexSet::new(&[OPENING_PAREN, r\"[a-z]+\\.(com|org|net)\"]);\n    //~^ invalid_regex\n    let bset_error = BRegexSet::new(&[OPENING_PAREN, r\"[a-z]+\\.(com|org|net)\"]);\n    //~^ invalid_regex\n\n    // These following three cases are considering valid since regex-1.8.0\n    let raw_string_error = Regex::new(r\"[...\\/...]\");\n    let raw_string_error = Regex::new(r#\"[...\\/...]\"#);\n    let _ = Regex::new(r\"(?<hi>hi)\").unwrap();\n\n    let escaped_string_span = Regex::new(\"\\\\b\\\\c\");\n    //~^ invalid_regex\n\n    let aux_span = Regex::new(\"(?ixi)\");\n    //~^ ERROR: regex syntax error: duplicate flag\n\n    let should_not_lint = Regex::new(\"(?u).\");\n    let should_not_lint = BRegex::new(\"(?u).\");\n    let invalid_utf8_should_not_lint = BRegex::new(\"(?-u).\");\n    let invalid_utf8_should_lint = Regex::new(\"(?-u).\");\n    //~^ ERROR: regex syntax error: pattern can match invalid UTF-8\n}\n\nfn trivial_regex() {\n    let trivial_eq = Regex::new(\"^foobar$\");\n    //~^ ERROR: trivial regex\n\n    let trivial_eq_builder = RegexBuilder::new(\"^foobar$\");\n    //~^ ERROR: trivial regex\n\n    let trivial_starts_with = Regex::new(\"^foobar\");\n    //~^ ERROR: trivial regex\n\n    let trivial_ends_with = Regex::new(\"foobar$\");\n    //~^ ERROR: trivial regex\n\n    let trivial_contains = Regex::new(\"foobar\");\n    //~^ ERROR: trivial regex\n\n    let trivial_contains = Regex::new(NOT_A_REAL_REGEX);\n    //~^ ERROR: trivial regex\n\n    let trivial_backslash = Regex::new(\"a\\\\.b\");\n    //~^ ERROR: trivial regex\n\n    // unlikely corner cases\n    let trivial_empty = Regex::new(\"\");\n    //~^ ERROR: trivial regex\n\n    let trivial_empty = Regex::new(\"^\");\n    //~^ ERROR: trivial regex\n\n    let trivial_empty = Regex::new(\"^$\");\n    //~^ ERROR: trivial regex\n\n    let binary_trivial_empty = BRegex::new(\"^$\");\n    //~^ ERROR: trivial regex\n\n    // non-trivial regexes\n    let non_trivial_dot = Regex::new(\"a.b\");\n    let non_trivial_dot_builder = RegexBuilder::new(\"a.b\");\n    let non_trivial_dot = Regex::new(\".\");\n    let non_trivial_dot = BRegex::new(\".\");\n    let non_trivial_eq = Regex::new(\"^foo|bar$\");\n    let non_trivial_starts_with = Regex::new(\"^foo|bar\");\n    let non_trivial_ends_with = Regex::new(\"^foo|bar\");\n    let non_trivial_ends_with = Regex::new(\"foo|bar\");\n    let non_trivial_binary = BRegex::new(\"foo|bar\");\n    let non_trivial_binary_builder = BRegexBuilder::new(\"foo|bar\");\n\n    // #6005: unicode classes in bytes::Regex\n    let a_byte_of_unicode = BRegex::new(r\"\\p{C}\");\n\n    // start and end word boundary, introduced in regex 0.10\n    let _ = BRegex::new(r\"\\<word\\>\");\n    let _ = BRegex::new(r\"\\b{start}word\\b{end}\");\n}\n\nfn regex_creation_in_loops() {\n    loop {\n        static STATIC_REGEX: std::sync::LazyLock<Regex> = std::sync::LazyLock::new(|| Regex::new(\"a.b\").unwrap());\n\n        let regex = Regex::new(\"a.b\");\n        //~^ ERROR: compiling a regex in a loop\n        let regex = BRegex::new(\"a.b\");\n        //~^ ERROR: compiling a regex in a loop\n        #[allow(clippy::regex_creation_in_loops)]\n        let allowed_regex = Regex::new(\"a.b\");\n\n        if true {\n            let regex = Regex::new(\"a.b\");\n            //~^ ERROR: compiling a regex in a loop\n        }\n\n        for _ in 0..10 {\n            let nested_regex = Regex::new(\"a.b\");\n            //~^ ERROR: compiling a regex in a loop\n        }\n    }\n\n    for i in 0..10 {\n        let dependant_regex = Regex::new(&format!(\"{i}\"));\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/regex.stderr",
    "content": "error: trivial regex\n  --> tests/ui/regex.rs:20:45\n   |\nLL |     let pipe_in_wrong_position = Regex::new(\"|\");\n   |                                             ^^^\n   |\n   = help: the regex is unlikely to be useful as it is\n   = note: `-D clippy::trivial-regex` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::trivial_regex)]`\n\nerror: trivial regex\n  --> tests/ui/regex.rs:22:60\n   |\nLL |     let pipe_in_wrong_position_builder = RegexBuilder::new(\"|\");\n   |                                                            ^^^\n   |\n   = help: the regex is unlikely to be useful as it is\n\nerror: regex syntax error: invalid character class range, the start must be <= the end\n  --> tests/ui/regex.rs:24:42\n   |\nLL |     let wrong_char_ranice = Regex::new(\"[z-a]\");\n   |                                          ^^^\n   |\n   = note: `-D clippy::invalid-regex` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::invalid_regex)]`\n\nerror: regex syntax error: invalid character class range, the start must be <= the end\n  --> tests/ui/regex.rs:27:37\n   |\nLL |     let some_unicode = Regex::new(\"[é-è]\");\n   |                                     ^^^\n\nerror: regex parse error:\n           (\n           ^\n       error: unclosed group\n  --> tests/ui/regex.rs:30:33\n   |\nLL |     let some_regex = Regex::new(OPENING_PAREN);\n   |                                 ^^^^^^^^^^^^^\n\nerror: trivial regex\n  --> tests/ui/regex.rs:33:53\n   |\nLL |     let binary_pipe_in_wrong_position = BRegex::new(\"|\");\n   |                                                     ^^^\n   |\n   = help: the regex is unlikely to be useful as it is\n\nerror: regex parse error:\n           (\n           ^\n       error: unclosed group\n  --> tests/ui/regex.rs:35:41\n   |\nLL |     let some_binary_regex = BRegex::new(OPENING_PAREN);\n   |                                         ^^^^^^^^^^^^^\n\nerror: regex parse error:\n           (\n           ^\n       error: unclosed group\n  --> tests/ui/regex.rs:37:56\n   |\nLL |     let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN);\n   |                                                        ^^^^^^^^^^^^^\n\nerror: regex parse error:\n           (\n           ^\n       error: unclosed group\n  --> tests/ui/regex.rs:50:37\n   |\nLL |     let set_error = RegexSet::new(&[OPENING_PAREN, r\"[a-z]+\\.(com|org|net)\"]);\n   |                                     ^^^^^^^^^^^^^\n\nerror: regex parse error:\n           (\n           ^\n       error: unclosed group\n  --> tests/ui/regex.rs:52:39\n   |\nLL |     let bset_error = BRegexSet::new(&[OPENING_PAREN, r\"[a-z]+\\.(com|org|net)\"]);\n   |                                       ^^^^^^^^^^^^^\n\nerror: regex parse error:\n           \\b\\c\n             ^^\n       error: unrecognized escape sequence\n  --> tests/ui/regex.rs:60:42\n   |\nLL |     let escaped_string_span = Regex::new(\"\\\\b\\\\c\");\n   |                                          ^^^^^^^^\n   |\n   = help: consider using a raw string literal: `r\"..\"`\n\nerror: regex syntax error: duplicate flag\n  --> tests/ui/regex.rs:63:34\n   |\nLL |     let aux_span = Regex::new(\"(?ixi)\");\n   |                                  ^ ^\n\nerror: regex syntax error: pattern can match invalid UTF-8\n  --> tests/ui/regex.rs:69:53\n   |\nLL |     let invalid_utf8_should_lint = Regex::new(\"(?-u).\");\n   |                                                     ^\n\nerror: trivial regex\n  --> tests/ui/regex.rs:74:33\n   |\nLL |     let trivial_eq = Regex::new(\"^foobar$\");\n   |                                 ^^^^^^^^^^\n   |\n   = help: consider using `==` on `str`s\n\nerror: trivial regex\n  --> tests/ui/regex.rs:77:48\n   |\nLL |     let trivial_eq_builder = RegexBuilder::new(\"^foobar$\");\n   |                                                ^^^^^^^^^^\n   |\n   = help: consider using `==` on `str`s\n\nerror: trivial regex\n  --> tests/ui/regex.rs:80:42\n   |\nLL |     let trivial_starts_with = Regex::new(\"^foobar\");\n   |                                          ^^^^^^^^^\n   |\n   = help: consider using `str::starts_with`\n\nerror: trivial regex\n  --> tests/ui/regex.rs:83:40\n   |\nLL |     let trivial_ends_with = Regex::new(\"foobar$\");\n   |                                        ^^^^^^^^^\n   |\n   = help: consider using `str::ends_with`\n\nerror: trivial regex\n  --> tests/ui/regex.rs:86:39\n   |\nLL |     let trivial_contains = Regex::new(\"foobar\");\n   |                                       ^^^^^^^^\n   |\n   = help: consider using `str::contains`\n\nerror: trivial regex\n  --> tests/ui/regex.rs:89:39\n   |\nLL |     let trivial_contains = Regex::new(NOT_A_REAL_REGEX);\n   |                                       ^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `str::contains`\n\nerror: trivial regex\n  --> tests/ui/regex.rs:92:40\n   |\nLL |     let trivial_backslash = Regex::new(\"a\\\\.b\");\n   |                                        ^^^^^^^\n   |\n   = help: consider using `str::contains`\n\nerror: trivial regex\n  --> tests/ui/regex.rs:96:36\n   |\nLL |     let trivial_empty = Regex::new(\"\");\n   |                                    ^^\n   |\n   = help: the regex is unlikely to be useful as it is\n\nerror: trivial regex\n  --> tests/ui/regex.rs:99:36\n   |\nLL |     let trivial_empty = Regex::new(\"^\");\n   |                                    ^^^\n   |\n   = help: the regex is unlikely to be useful as it is\n\nerror: trivial regex\n  --> tests/ui/regex.rs:102:36\n   |\nLL |     let trivial_empty = Regex::new(\"^$\");\n   |                                    ^^^^\n   |\n   = help: consider using `str::is_empty`\n\nerror: trivial regex\n  --> tests/ui/regex.rs:105:44\n   |\nLL |     let binary_trivial_empty = BRegex::new(\"^$\");\n   |                                            ^^^^\n   |\n   = help: consider using `str::is_empty`\n\nerror: compiling a regex in a loop\n  --> tests/ui/regex.rs:132:21\n   |\nLL |         let regex = Regex::new(\"a.b\");\n   |                     ^^^^^^^^^^\n   |\nhelp: move the regex construction outside this loop\n  --> tests/ui/regex.rs:129:5\n   |\nLL |     loop {\n   |     ^^^^\n   = note: `-D clippy::regex-creation-in-loops` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::regex_creation_in_loops)]`\n\nerror: compiling a regex in a loop\n  --> tests/ui/regex.rs:134:21\n   |\nLL |         let regex = BRegex::new(\"a.b\");\n   |                     ^^^^^^^^^^^\n   |\nhelp: move the regex construction outside this loop\n  --> tests/ui/regex.rs:129:5\n   |\nLL |     loop {\n   |     ^^^^\n\nerror: compiling a regex in a loop\n  --> tests/ui/regex.rs:140:25\n   |\nLL |             let regex = Regex::new(\"a.b\");\n   |                         ^^^^^^^^^^\n   |\nhelp: move the regex construction outside this loop\n  --> tests/ui/regex.rs:129:5\n   |\nLL |     loop {\n   |     ^^^^\n\nerror: compiling a regex in a loop\n  --> tests/ui/regex.rs:145:32\n   |\nLL |             let nested_regex = Regex::new(\"a.b\");\n   |                                ^^^^^^^^^^\n   |\nhelp: move the regex construction outside this loop\n  --> tests/ui/regex.rs:144:9\n   |\nLL |         for _ in 0..10 {\n   |         ^^^^^^^^^^^^^^\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui/rename.fixed",
    "content": "// This file was generated by `cargo dev update_lints`.\n// Use that command to update this file and do not edit by hand.\n// Manual edits will be overwritten.\n\n#![allow(clippy::duplicated_attributes)]\n#![allow(clippy::almost_complete_range)]\n#![allow(clippy::disallowed_names)]\n#![allow(clippy::blocks_in_conditions)]\n#![allow(clippy::box_collection)]\n#![allow(invalid_reference_casting)]\n#![allow(suspicious_double_ref_op)]\n#![allow(invalid_nan_comparisons)]\n#![allow(clippy::redundant_static_lifetimes)]\n#![allow(clippy::cognitive_complexity)]\n#![allow(clippy::derived_hash_with_manual_eq)]\n#![allow(clippy::disallowed_methods)]\n#![allow(clippy::disallowed_types)]\n#![allow(double_negations)]\n#![allow(drop_bounds)]\n#![allow(dropping_copy_types)]\n#![allow(dropping_references)]\n#![allow(clippy::empty_enums)]\n#![allow(clippy::mixed_read_write_in_expression)]\n#![allow(clippy::manual_filter_map)]\n#![allow(clippy::manual_find_map)]\n#![allow(unpredictable_function_pointer_comparisons)]\n#![allow(useless_ptr_null_checks)]\n#![allow(for_loops_over_fallibles)]\n#![allow(forgetting_copy_types)]\n#![allow(forgetting_references)]\n#![allow(clippy::useless_conversion)]\n#![allow(clippy::redundant_pattern_matching)]\n#![allow(clippy::match_result_ok)]\n#![allow(clippy::non_canonical_clone_impl)]\n#![allow(clippy::non_canonical_partial_ord_impl)]\n#![allow(clippy::arithmetic_side_effects)]\n#![allow(array_into_iter)]\n#![allow(invalid_atomic_ordering)]\n#![allow(invalid_null_arguments)]\n#![allow(invalid_value)]\n#![allow(invalid_from_utf8_unchecked)]\n#![allow(let_underscore_drop)]\n#![allow(clippy::overly_complex_bool_expr)]\n#![allow(unexpected_cfgs)]\n#![allow(enum_intrinsics_non_enums)]\n#![allow(clippy::needless_ifs)]\n#![allow(clippy::new_without_default)]\n#![allow(clippy::bind_instead_of_map)]\n#![allow(clippy::expect_used)]\n#![allow(clippy::map_unwrap_or)]\n#![allow(clippy::unwrap_used)]\n#![allow(clippy::panicking_overflow_checks)]\n#![allow(non_fmt_panics)]\n#![allow(named_arguments_used_positionally)]\n#![allow(clippy::needless_borrow)]\n#![allow(clippy::reversed_empty_ranges)]\n#![allow(clippy::single_char_add_str)]\n#![allow(clippy::module_name_repetitions)]\n#![allow(dangling_pointers_from_temporaries)]\n#![allow(clippy::missing_const_for_thread_local)]\n#![allow(clippy::recursive_format_impl)]\n#![allow(unnecessary_transmutes)]\n#![allow(clippy::unchecked_time_subtraction)]\n#![allow(undropped_manually_drops)]\n#![allow(unknown_lints)]\n#![allow(unused_labels)]\n#![allow(clippy::unwrap_or_default)]\n#![allow(ambiguous_wide_pointer_comparisons)]\n#![allow(clippy::invisible_characters)]\n#![warn(clippy::almost_complete_range)] //~ ERROR: lint `clippy::almost_complete_letter_range`\n#![warn(clippy::disallowed_names)] //~ ERROR: lint `clippy::blacklisted_name`\n#![warn(clippy::blocks_in_conditions)] //~ ERROR: lint `clippy::block_in_if_condition_expr`\n#![warn(clippy::blocks_in_conditions)] //~ ERROR: lint `clippy::block_in_if_condition_stmt`\n#![warn(clippy::blocks_in_conditions)] //~ ERROR: lint `clippy::blocks_in_if_conditions`\n#![warn(clippy::box_collection)] //~ ERROR: lint `clippy::box_vec`\n#![warn(invalid_reference_casting)] //~ ERROR: lint `clippy::cast_ref_to_mut`\n#![warn(suspicious_double_ref_op)] //~ ERROR: lint `clippy::clone_double_ref`\n#![warn(invalid_nan_comparisons)] //~ ERROR: lint `clippy::cmp_nan`\n#![warn(clippy::redundant_static_lifetimes)] //~ ERROR: lint `clippy::const_static_lifetime`\n#![warn(clippy::cognitive_complexity)] //~ ERROR: lint `clippy::cyclomatic_complexity`\n#![warn(clippy::derived_hash_with_manual_eq)] //~ ERROR: lint `clippy::derive_hash_xor_eq`\n#![warn(clippy::disallowed_methods)] //~ ERROR: lint `clippy::disallowed_method`\n#![warn(clippy::disallowed_types)] //~ ERROR: lint `clippy::disallowed_type`\n#![warn(double_negations)] //~ ERROR: lint `clippy::double_neg`\n#![warn(drop_bounds)] //~ ERROR: lint `clippy::drop_bounds`\n#![warn(dropping_copy_types)] //~ ERROR: lint `clippy::drop_copy`\n#![warn(dropping_references)] //~ ERROR: lint `clippy::drop_ref`\n#![warn(clippy::empty_enums)] //~ ERROR: lint `clippy::empty_enum`\n#![warn(clippy::mixed_read_write_in_expression)] //~ ERROR: lint `clippy::eval_order_dependence`\n#![warn(clippy::manual_filter_map)] //~ ERROR: lint `clippy::filter_map`\n#![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map`\n#![warn(unpredictable_function_pointer_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons`\n#![warn(useless_ptr_null_checks)] //~ ERROR: lint `clippy::fn_null_check`\n#![warn(for_loops_over_fallibles)] //~ ERROR: lint `clippy::for_loop_over_option`\n#![warn(for_loops_over_fallibles)] //~ ERROR: lint `clippy::for_loop_over_result`\n#![warn(for_loops_over_fallibles)] //~ ERROR: lint `clippy::for_loops_over_fallibles`\n#![warn(forgetting_copy_types)] //~ ERROR: lint `clippy::forget_copy`\n#![warn(forgetting_references)] //~ ERROR: lint `clippy::forget_ref`\n#![warn(clippy::useless_conversion)] //~ ERROR: lint `clippy::identity_conversion`\n#![warn(clippy::redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching`\n#![warn(clippy::match_result_ok)] //~ ERROR: lint `clippy::if_let_some_result`\n#![warn(clippy::non_canonical_clone_impl)] //~ ERROR: lint `clippy::incorrect_clone_impl_on_copy_type`\n#![warn(clippy::non_canonical_partial_ord_impl)] //~ ERROR: lint `clippy::incorrect_partial_ord_impl_on_ord_type`\n#![warn(clippy::arithmetic_side_effects)] //~ ERROR: lint `clippy::integer_arithmetic`\n#![warn(array_into_iter)] //~ ERROR: lint `clippy::into_iter_on_array`\n#![warn(invalid_atomic_ordering)] //~ ERROR: lint `clippy::invalid_atomic_ordering`\n#![warn(invalid_null_arguments)] //~ ERROR: lint `clippy::invalid_null_ptr_usage`\n#![warn(invalid_value)] //~ ERROR: lint `clippy::invalid_ref`\n#![warn(invalid_from_utf8_unchecked)] //~ ERROR: lint `clippy::invalid_utf8_in_unchecked`\n#![warn(let_underscore_drop)] //~ ERROR: lint `clippy::let_underscore_drop`\n#![warn(clippy::overly_complex_bool_expr)] //~ ERROR: lint `clippy::logic_bug`\n#![warn(unexpected_cfgs)] //~ ERROR: lint `clippy::maybe_misused_cfg`\n#![warn(enum_intrinsics_non_enums)] //~ ERROR: lint `clippy::mem_discriminant_non_enum`\n#![warn(unexpected_cfgs)] //~ ERROR: lint `clippy::mismatched_target_os`\n#![warn(clippy::needless_ifs)] //~ ERROR: lint `clippy::needless_if`\n#![warn(clippy::new_without_default)] //~ ERROR: lint `clippy::new_without_default_derive`\n#![warn(clippy::bind_instead_of_map)] //~ ERROR: lint `clippy::option_and_then_some`\n#![warn(clippy::expect_used)] //~ ERROR: lint `clippy::option_expect_used`\n#![warn(clippy::map_unwrap_or)] //~ ERROR: lint `clippy::option_map_unwrap_or`\n#![warn(clippy::map_unwrap_or)] //~ ERROR: lint `clippy::option_map_unwrap_or_else`\n#![warn(clippy::unwrap_used)] //~ ERROR: lint `clippy::option_unwrap_used`\n#![warn(clippy::panicking_overflow_checks)] //~ ERROR: lint `clippy::overflow_check_conditional`\n#![warn(non_fmt_panics)] //~ ERROR: lint `clippy::panic_params`\n#![warn(named_arguments_used_positionally)] //~ ERROR: lint `clippy::positional_named_format_parameters`\n#![warn(clippy::needless_borrow)] //~ ERROR: lint `clippy::ref_in_deref`\n#![warn(clippy::expect_used)] //~ ERROR: lint `clippy::result_expect_used`\n#![warn(clippy::map_unwrap_or)] //~ ERROR: lint `clippy::result_map_unwrap_or_else`\n#![warn(clippy::unwrap_used)] //~ ERROR: lint `clippy::result_unwrap_used`\n#![warn(clippy::reversed_empty_ranges)] //~ ERROR: lint `clippy::reverse_range_loop`\n#![warn(clippy::single_char_add_str)] //~ ERROR: lint `clippy::single_char_push_str`\n#![warn(clippy::module_name_repetitions)] //~ ERROR: lint `clippy::stutter`\n#![warn(dangling_pointers_from_temporaries)] //~ ERROR: lint `clippy::temporary_cstring_as_ptr`\n#![warn(clippy::missing_const_for_thread_local)] //~ ERROR: lint `clippy::thread_local_initializer_can_be_made_const`\n#![warn(clippy::recursive_format_impl)] //~ ERROR: lint `clippy::to_string_in_display`\n#![warn(unnecessary_transmutes)] //~ ERROR: lint `clippy::transmute_float_to_int`\n#![warn(unnecessary_transmutes)] //~ ERROR: lint `clippy::transmute_int_to_char`\n#![warn(unnecessary_transmutes)] //~ ERROR: lint `clippy::transmute_int_to_float`\n#![warn(unnecessary_transmutes)] //~ ERROR: lint `clippy::transmute_num_to_bytes`\n#![warn(clippy::unchecked_time_subtraction)] //~ ERROR: lint `clippy::unchecked_duration_subtraction`\n#![warn(undropped_manually_drops)] //~ ERROR: lint `clippy::undropped_manually_drops`\n#![warn(unknown_lints)] //~ ERROR: lint `clippy::unknown_clippy_lints`\n#![warn(unused_labels)] //~ ERROR: lint `clippy::unused_label`\n#![warn(clippy::unwrap_or_default)] //~ ERROR: lint `clippy::unwrap_or_else_default`\n#![warn(ambiguous_wide_pointer_comparisons)] //~ ERROR: lint `clippy::vtable_address_comparisons`\n#![warn(clippy::invisible_characters)] //~ ERROR: lint `clippy::zero_width_space`\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rename.rs",
    "content": "// This file was generated by `cargo dev update_lints`.\n// Use that command to update this file and do not edit by hand.\n// Manual edits will be overwritten.\n\n#![allow(clippy::duplicated_attributes)]\n#![allow(clippy::almost_complete_range)]\n#![allow(clippy::disallowed_names)]\n#![allow(clippy::blocks_in_conditions)]\n#![allow(clippy::box_collection)]\n#![allow(invalid_reference_casting)]\n#![allow(suspicious_double_ref_op)]\n#![allow(invalid_nan_comparisons)]\n#![allow(clippy::redundant_static_lifetimes)]\n#![allow(clippy::cognitive_complexity)]\n#![allow(clippy::derived_hash_with_manual_eq)]\n#![allow(clippy::disallowed_methods)]\n#![allow(clippy::disallowed_types)]\n#![allow(double_negations)]\n#![allow(drop_bounds)]\n#![allow(dropping_copy_types)]\n#![allow(dropping_references)]\n#![allow(clippy::empty_enums)]\n#![allow(clippy::mixed_read_write_in_expression)]\n#![allow(clippy::manual_filter_map)]\n#![allow(clippy::manual_find_map)]\n#![allow(unpredictable_function_pointer_comparisons)]\n#![allow(useless_ptr_null_checks)]\n#![allow(for_loops_over_fallibles)]\n#![allow(forgetting_copy_types)]\n#![allow(forgetting_references)]\n#![allow(clippy::useless_conversion)]\n#![allow(clippy::redundant_pattern_matching)]\n#![allow(clippy::match_result_ok)]\n#![allow(clippy::non_canonical_clone_impl)]\n#![allow(clippy::non_canonical_partial_ord_impl)]\n#![allow(clippy::arithmetic_side_effects)]\n#![allow(array_into_iter)]\n#![allow(invalid_atomic_ordering)]\n#![allow(invalid_null_arguments)]\n#![allow(invalid_value)]\n#![allow(invalid_from_utf8_unchecked)]\n#![allow(let_underscore_drop)]\n#![allow(clippy::overly_complex_bool_expr)]\n#![allow(unexpected_cfgs)]\n#![allow(enum_intrinsics_non_enums)]\n#![allow(clippy::needless_ifs)]\n#![allow(clippy::new_without_default)]\n#![allow(clippy::bind_instead_of_map)]\n#![allow(clippy::expect_used)]\n#![allow(clippy::map_unwrap_or)]\n#![allow(clippy::unwrap_used)]\n#![allow(clippy::panicking_overflow_checks)]\n#![allow(non_fmt_panics)]\n#![allow(named_arguments_used_positionally)]\n#![allow(clippy::needless_borrow)]\n#![allow(clippy::reversed_empty_ranges)]\n#![allow(clippy::single_char_add_str)]\n#![allow(clippy::module_name_repetitions)]\n#![allow(dangling_pointers_from_temporaries)]\n#![allow(clippy::missing_const_for_thread_local)]\n#![allow(clippy::recursive_format_impl)]\n#![allow(unnecessary_transmutes)]\n#![allow(clippy::unchecked_time_subtraction)]\n#![allow(undropped_manually_drops)]\n#![allow(unknown_lints)]\n#![allow(unused_labels)]\n#![allow(clippy::unwrap_or_default)]\n#![allow(ambiguous_wide_pointer_comparisons)]\n#![allow(clippy::invisible_characters)]\n#![warn(clippy::almost_complete_letter_range)] //~ ERROR: lint `clippy::almost_complete_letter_range`\n#![warn(clippy::blacklisted_name)] //~ ERROR: lint `clippy::blacklisted_name`\n#![warn(clippy::block_in_if_condition_expr)] //~ ERROR: lint `clippy::block_in_if_condition_expr`\n#![warn(clippy::block_in_if_condition_stmt)] //~ ERROR: lint `clippy::block_in_if_condition_stmt`\n#![warn(clippy::blocks_in_if_conditions)] //~ ERROR: lint `clippy::blocks_in_if_conditions`\n#![warn(clippy::box_vec)] //~ ERROR: lint `clippy::box_vec`\n#![warn(clippy::cast_ref_to_mut)] //~ ERROR: lint `clippy::cast_ref_to_mut`\n#![warn(clippy::clone_double_ref)] //~ ERROR: lint `clippy::clone_double_ref`\n#![warn(clippy::cmp_nan)] //~ ERROR: lint `clippy::cmp_nan`\n#![warn(clippy::const_static_lifetime)] //~ ERROR: lint `clippy::const_static_lifetime`\n#![warn(clippy::cyclomatic_complexity)] //~ ERROR: lint `clippy::cyclomatic_complexity`\n#![warn(clippy::derive_hash_xor_eq)] //~ ERROR: lint `clippy::derive_hash_xor_eq`\n#![warn(clippy::disallowed_method)] //~ ERROR: lint `clippy::disallowed_method`\n#![warn(clippy::disallowed_type)] //~ ERROR: lint `clippy::disallowed_type`\n#![warn(clippy::double_neg)] //~ ERROR: lint `clippy::double_neg`\n#![warn(clippy::drop_bounds)] //~ ERROR: lint `clippy::drop_bounds`\n#![warn(clippy::drop_copy)] //~ ERROR: lint `clippy::drop_copy`\n#![warn(clippy::drop_ref)] //~ ERROR: lint `clippy::drop_ref`\n#![warn(clippy::empty_enum)] //~ ERROR: lint `clippy::empty_enum`\n#![warn(clippy::eval_order_dependence)] //~ ERROR: lint `clippy::eval_order_dependence`\n#![warn(clippy::filter_map)] //~ ERROR: lint `clippy::filter_map`\n#![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map`\n#![warn(clippy::fn_address_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons`\n#![warn(clippy::fn_null_check)] //~ ERROR: lint `clippy::fn_null_check`\n#![warn(clippy::for_loop_over_option)] //~ ERROR: lint `clippy::for_loop_over_option`\n#![warn(clippy::for_loop_over_result)] //~ ERROR: lint `clippy::for_loop_over_result`\n#![warn(clippy::for_loops_over_fallibles)] //~ ERROR: lint `clippy::for_loops_over_fallibles`\n#![warn(clippy::forget_copy)] //~ ERROR: lint `clippy::forget_copy`\n#![warn(clippy::forget_ref)] //~ ERROR: lint `clippy::forget_ref`\n#![warn(clippy::identity_conversion)] //~ ERROR: lint `clippy::identity_conversion`\n#![warn(clippy::if_let_redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching`\n#![warn(clippy::if_let_some_result)] //~ ERROR: lint `clippy::if_let_some_result`\n#![warn(clippy::incorrect_clone_impl_on_copy_type)] //~ ERROR: lint `clippy::incorrect_clone_impl_on_copy_type`\n#![warn(clippy::incorrect_partial_ord_impl_on_ord_type)] //~ ERROR: lint `clippy::incorrect_partial_ord_impl_on_ord_type`\n#![warn(clippy::integer_arithmetic)] //~ ERROR: lint `clippy::integer_arithmetic`\n#![warn(clippy::into_iter_on_array)] //~ ERROR: lint `clippy::into_iter_on_array`\n#![warn(clippy::invalid_atomic_ordering)] //~ ERROR: lint `clippy::invalid_atomic_ordering`\n#![warn(clippy::invalid_null_ptr_usage)] //~ ERROR: lint `clippy::invalid_null_ptr_usage`\n#![warn(clippy::invalid_ref)] //~ ERROR: lint `clippy::invalid_ref`\n#![warn(clippy::invalid_utf8_in_unchecked)] //~ ERROR: lint `clippy::invalid_utf8_in_unchecked`\n#![warn(clippy::let_underscore_drop)] //~ ERROR: lint `clippy::let_underscore_drop`\n#![warn(clippy::logic_bug)] //~ ERROR: lint `clippy::logic_bug`\n#![warn(clippy::maybe_misused_cfg)] //~ ERROR: lint `clippy::maybe_misused_cfg`\n#![warn(clippy::mem_discriminant_non_enum)] //~ ERROR: lint `clippy::mem_discriminant_non_enum`\n#![warn(clippy::mismatched_target_os)] //~ ERROR: lint `clippy::mismatched_target_os`\n#![warn(clippy::needless_if)] //~ ERROR: lint `clippy::needless_if`\n#![warn(clippy::new_without_default_derive)] //~ ERROR: lint `clippy::new_without_default_derive`\n#![warn(clippy::option_and_then_some)] //~ ERROR: lint `clippy::option_and_then_some`\n#![warn(clippy::option_expect_used)] //~ ERROR: lint `clippy::option_expect_used`\n#![warn(clippy::option_map_unwrap_or)] //~ ERROR: lint `clippy::option_map_unwrap_or`\n#![warn(clippy::option_map_unwrap_or_else)] //~ ERROR: lint `clippy::option_map_unwrap_or_else`\n#![warn(clippy::option_unwrap_used)] //~ ERROR: lint `clippy::option_unwrap_used`\n#![warn(clippy::overflow_check_conditional)] //~ ERROR: lint `clippy::overflow_check_conditional`\n#![warn(clippy::panic_params)] //~ ERROR: lint `clippy::panic_params`\n#![warn(clippy::positional_named_format_parameters)] //~ ERROR: lint `clippy::positional_named_format_parameters`\n#![warn(clippy::ref_in_deref)] //~ ERROR: lint `clippy::ref_in_deref`\n#![warn(clippy::result_expect_used)] //~ ERROR: lint `clippy::result_expect_used`\n#![warn(clippy::result_map_unwrap_or_else)] //~ ERROR: lint `clippy::result_map_unwrap_or_else`\n#![warn(clippy::result_unwrap_used)] //~ ERROR: lint `clippy::result_unwrap_used`\n#![warn(clippy::reverse_range_loop)] //~ ERROR: lint `clippy::reverse_range_loop`\n#![warn(clippy::single_char_push_str)] //~ ERROR: lint `clippy::single_char_push_str`\n#![warn(clippy::stutter)] //~ ERROR: lint `clippy::stutter`\n#![warn(clippy::temporary_cstring_as_ptr)] //~ ERROR: lint `clippy::temporary_cstring_as_ptr`\n#![warn(clippy::thread_local_initializer_can_be_made_const)] //~ ERROR: lint `clippy::thread_local_initializer_can_be_made_const`\n#![warn(clippy::to_string_in_display)] //~ ERROR: lint `clippy::to_string_in_display`\n#![warn(clippy::transmute_float_to_int)] //~ ERROR: lint `clippy::transmute_float_to_int`\n#![warn(clippy::transmute_int_to_char)] //~ ERROR: lint `clippy::transmute_int_to_char`\n#![warn(clippy::transmute_int_to_float)] //~ ERROR: lint `clippy::transmute_int_to_float`\n#![warn(clippy::transmute_num_to_bytes)] //~ ERROR: lint `clippy::transmute_num_to_bytes`\n#![warn(clippy::unchecked_duration_subtraction)] //~ ERROR: lint `clippy::unchecked_duration_subtraction`\n#![warn(clippy::undropped_manually_drops)] //~ ERROR: lint `clippy::undropped_manually_drops`\n#![warn(clippy::unknown_clippy_lints)] //~ ERROR: lint `clippy::unknown_clippy_lints`\n#![warn(clippy::unused_label)] //~ ERROR: lint `clippy::unused_label`\n#![warn(clippy::unwrap_or_else_default)] //~ ERROR: lint `clippy::unwrap_or_else_default`\n#![warn(clippy::vtable_address_comparisons)] //~ ERROR: lint `clippy::vtable_address_comparisons`\n#![warn(clippy::zero_width_space)] //~ ERROR: lint `clippy::zero_width_space`\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/rename.stderr",
    "content": "error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`\n  --> tests/ui/rename.rs:70:9\n   |\nLL | #![warn(clippy::almost_complete_letter_range)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`\n   |\n   = note: `-D renamed-and-removed-lints` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`\n\nerror: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`\n  --> tests/ui/rename.rs:71:9\n   |\nLL | #![warn(clippy::blacklisted_name)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`\n\nerror: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_conditions`\n  --> tests/ui/rename.rs:72:9\n   |\nLL | #![warn(clippy::block_in_if_condition_expr)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`\n\nerror: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_conditions`\n  --> tests/ui/rename.rs:73:9\n   |\nLL | #![warn(clippy::block_in_if_condition_stmt)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`\n\nerror: lint `clippy::blocks_in_if_conditions` has been renamed to `clippy::blocks_in_conditions`\n  --> tests/ui/rename.rs:74:9\n   |\nLL | #![warn(clippy::blocks_in_if_conditions)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`\n\nerror: lint `clippy::box_vec` has been renamed to `clippy::box_collection`\n  --> tests/ui/rename.rs:75:9\n   |\nLL | #![warn(clippy::box_vec)]\n   |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`\n\nerror: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting`\n  --> tests/ui/rename.rs:76:9\n   |\nLL | #![warn(clippy::cast_ref_to_mut)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting`\n\nerror: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`\n  --> tests/ui/rename.rs:77:9\n   |\nLL | #![warn(clippy::clone_double_ref)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`\n\nerror: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons`\n  --> tests/ui/rename.rs:78:9\n   |\nLL | #![warn(clippy::cmp_nan)]\n   |         ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons`\n\nerror: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`\n  --> tests/ui/rename.rs:79:9\n   |\nLL | #![warn(clippy::const_static_lifetime)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`\n\nerror: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`\n  --> tests/ui/rename.rs:80:9\n   |\nLL | #![warn(clippy::cyclomatic_complexity)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`\n\nerror: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`\n  --> tests/ui/rename.rs:81:9\n   |\nLL | #![warn(clippy::derive_hash_xor_eq)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`\n\nerror: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`\n  --> tests/ui/rename.rs:82:9\n   |\nLL | #![warn(clippy::disallowed_method)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`\n\nerror: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`\n  --> tests/ui/rename.rs:83:9\n   |\nLL | #![warn(clippy::disallowed_type)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`\n\nerror: lint `clippy::double_neg` has been renamed to `double_negations`\n  --> tests/ui/rename.rs:84:9\n   |\nLL | #![warn(clippy::double_neg)]\n   |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `double_negations`\n\nerror: lint `clippy::drop_bounds` has been renamed to `drop_bounds`\n  --> tests/ui/rename.rs:85:9\n   |\nLL | #![warn(clippy::drop_bounds)]\n   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`\n\nerror: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`\n  --> tests/ui/rename.rs:86:9\n   |\nLL | #![warn(clippy::drop_copy)]\n   |         ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`\n\nerror: lint `clippy::drop_ref` has been renamed to `dropping_references`\n  --> tests/ui/rename.rs:87:9\n   |\nLL | #![warn(clippy::drop_ref)]\n   |         ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`\n\nerror: lint `clippy::empty_enum` has been renamed to `clippy::empty_enums`\n  --> tests/ui/rename.rs:88:9\n   |\nLL | #![warn(clippy::empty_enum)]\n   |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::empty_enums`\n\nerror: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`\n  --> tests/ui/rename.rs:89:9\n   |\nLL | #![warn(clippy::eval_order_dependence)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`\n\nerror: lint `clippy::filter_map` has been renamed to `clippy::manual_filter_map`\n  --> tests/ui/rename.rs:90:9\n   |\nLL | #![warn(clippy::filter_map)]\n   |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_filter_map`\n\nerror: lint `clippy::find_map` has been renamed to `clippy::manual_find_map`\n  --> tests/ui/rename.rs:91:9\n   |\nLL | #![warn(clippy::find_map)]\n   |         ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map`\n\nerror: lint `clippy::fn_address_comparisons` has been renamed to `unpredictable_function_pointer_comparisons`\n  --> tests/ui/rename.rs:92:9\n   |\nLL | #![warn(clippy::fn_address_comparisons)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons`\n\nerror: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks`\n  --> tests/ui/rename.rs:93:9\n   |\nLL | #![warn(clippy::fn_null_check)]\n   |         ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks`\n\nerror: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`\n  --> tests/ui/rename.rs:94:9\n   |\nLL | #![warn(clippy::for_loop_over_option)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`\n\nerror: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`\n  --> tests/ui/rename.rs:95:9\n   |\nLL | #![warn(clippy::for_loop_over_result)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`\n\nerror: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`\n  --> tests/ui/rename.rs:96:9\n   |\nLL | #![warn(clippy::for_loops_over_fallibles)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`\n\nerror: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`\n  --> tests/ui/rename.rs:97:9\n   |\nLL | #![warn(clippy::forget_copy)]\n   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`\n\nerror: lint `clippy::forget_ref` has been renamed to `forgetting_references`\n  --> tests/ui/rename.rs:98:9\n   |\nLL | #![warn(clippy::forget_ref)]\n   |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`\n\nerror: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`\n  --> tests/ui/rename.rs:99:9\n   |\nLL | #![warn(clippy::identity_conversion)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`\n\nerror: lint `clippy::if_let_redundant_pattern_matching` has been renamed to `clippy::redundant_pattern_matching`\n  --> tests/ui/rename.rs:100:9\n   |\nLL | #![warn(clippy::if_let_redundant_pattern_matching)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_pattern_matching`\n\nerror: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`\n  --> tests/ui/rename.rs:101:9\n   |\nLL | #![warn(clippy::if_let_some_result)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`\n\nerror: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl`\n  --> tests/ui/rename.rs:102:9\n   |\nLL | #![warn(clippy::incorrect_clone_impl_on_copy_type)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl`\n\nerror: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl`\n  --> tests/ui/rename.rs:103:9\n   |\nLL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl`\n\nerror: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`\n  --> tests/ui/rename.rs:104:9\n   |\nLL | #![warn(clippy::integer_arithmetic)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects`\n\nerror: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`\n  --> tests/ui/rename.rs:105:9\n   |\nLL | #![warn(clippy::into_iter_on_array)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`\n\nerror: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`\n  --> tests/ui/rename.rs:106:9\n   |\nLL | #![warn(clippy::invalid_atomic_ordering)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`\n\nerror: lint `clippy::invalid_null_ptr_usage` has been renamed to `invalid_null_arguments`\n  --> tests/ui/rename.rs:107:9\n   |\nLL | #![warn(clippy::invalid_null_ptr_usage)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_null_arguments`\n\nerror: lint `clippy::invalid_ref` has been renamed to `invalid_value`\n  --> tests/ui/rename.rs:108:9\n   |\nLL | #![warn(clippy::invalid_ref)]\n   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`\n\nerror: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked`\n  --> tests/ui/rename.rs:109:9\n   |\nLL | #![warn(clippy::invalid_utf8_in_unchecked)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`\n\nerror: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`\n  --> tests/ui/rename.rs:110:9\n   |\nLL | #![warn(clippy::let_underscore_drop)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`\n\nerror: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`\n  --> tests/ui/rename.rs:111:9\n   |\nLL | #![warn(clippy::logic_bug)]\n   |         ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`\n\nerror: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs`\n  --> tests/ui/rename.rs:112:9\n   |\nLL | #![warn(clippy::maybe_misused_cfg)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`\n\nerror: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`\n  --> tests/ui/rename.rs:113:9\n   |\nLL | #![warn(clippy::mem_discriminant_non_enum)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`\n\nerror: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs`\n  --> tests/ui/rename.rs:114:9\n   |\nLL | #![warn(clippy::mismatched_target_os)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`\n\nerror: lint `clippy::needless_if` has been renamed to `clippy::needless_ifs`\n  --> tests/ui/rename.rs:115:9\n   |\nLL | #![warn(clippy::needless_if)]\n   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_ifs`\n\nerror: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`\n  --> tests/ui/rename.rs:116:9\n   |\nLL | #![warn(clippy::new_without_default_derive)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`\n\nerror: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`\n  --> tests/ui/rename.rs:117:9\n   |\nLL | #![warn(clippy::option_and_then_some)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`\n\nerror: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`\n  --> tests/ui/rename.rs:118:9\n   |\nLL | #![warn(clippy::option_expect_used)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`\n\nerror: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`\n  --> tests/ui/rename.rs:119:9\n   |\nLL | #![warn(clippy::option_map_unwrap_or)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`\n\nerror: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`\n  --> tests/ui/rename.rs:120:9\n   |\nLL | #![warn(clippy::option_map_unwrap_or_else)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`\n\nerror: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`\n  --> tests/ui/rename.rs:121:9\n   |\nLL | #![warn(clippy::option_unwrap_used)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`\n\nerror: lint `clippy::overflow_check_conditional` has been renamed to `clippy::panicking_overflow_checks`\n  --> tests/ui/rename.rs:122:9\n   |\nLL | #![warn(clippy::overflow_check_conditional)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::panicking_overflow_checks`\n\nerror: lint `clippy::panic_params` has been renamed to `non_fmt_panics`\n  --> tests/ui/rename.rs:123:9\n   |\nLL | #![warn(clippy::panic_params)]\n   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`\n\nerror: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`\n  --> tests/ui/rename.rs:124:9\n   |\nLL | #![warn(clippy::positional_named_format_parameters)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`\n\nerror: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`\n  --> tests/ui/rename.rs:125:9\n   |\nLL | #![warn(clippy::ref_in_deref)]\n   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`\n\nerror: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`\n  --> tests/ui/rename.rs:126:9\n   |\nLL | #![warn(clippy::result_expect_used)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`\n\nerror: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`\n  --> tests/ui/rename.rs:127:9\n   |\nLL | #![warn(clippy::result_map_unwrap_or_else)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`\n\nerror: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`\n  --> tests/ui/rename.rs:128:9\n   |\nLL | #![warn(clippy::result_unwrap_used)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`\n\nerror: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges`\n  --> tests/ui/rename.rs:129:9\n   |\nLL | #![warn(clippy::reverse_range_loop)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges`\n\nerror: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`\n  --> tests/ui/rename.rs:130:9\n   |\nLL | #![warn(clippy::single_char_push_str)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`\n\nerror: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`\n  --> tests/ui/rename.rs:131:9\n   |\nLL | #![warn(clippy::stutter)]\n   |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`\n\nerror: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries`\n  --> tests/ui/rename.rs:132:9\n   |\nLL | #![warn(clippy::temporary_cstring_as_ptr)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries`\n\nerror: lint `clippy::thread_local_initializer_can_be_made_const` has been renamed to `clippy::missing_const_for_thread_local`\n  --> tests/ui/rename.rs:133:9\n   |\nLL | #![warn(clippy::thread_local_initializer_can_be_made_const)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::missing_const_for_thread_local`\n\nerror: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`\n  --> tests/ui/rename.rs:134:9\n   |\nLL | #![warn(clippy::to_string_in_display)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`\n\nerror: lint `clippy::transmute_float_to_int` has been renamed to `unnecessary_transmutes`\n  --> tests/ui/rename.rs:135:9\n   |\nLL | #![warn(clippy::transmute_float_to_int)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unnecessary_transmutes`\n\nerror: lint `clippy::transmute_int_to_char` has been renamed to `unnecessary_transmutes`\n  --> tests/ui/rename.rs:136:9\n   |\nLL | #![warn(clippy::transmute_int_to_char)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unnecessary_transmutes`\n\nerror: lint `clippy::transmute_int_to_float` has been renamed to `unnecessary_transmutes`\n  --> tests/ui/rename.rs:137:9\n   |\nLL | #![warn(clippy::transmute_int_to_float)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unnecessary_transmutes`\n\nerror: lint `clippy::transmute_num_to_bytes` has been renamed to `unnecessary_transmutes`\n  --> tests/ui/rename.rs:138:9\n   |\nLL | #![warn(clippy::transmute_num_to_bytes)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unnecessary_transmutes`\n\nerror: lint `clippy::unchecked_duration_subtraction` has been renamed to `clippy::unchecked_time_subtraction`\n  --> tests/ui/rename.rs:139:9\n   |\nLL | #![warn(clippy::unchecked_duration_subtraction)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unchecked_time_subtraction`\n\nerror: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`\n  --> tests/ui/rename.rs:140:9\n   |\nLL | #![warn(clippy::undropped_manually_drops)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`\n\nerror: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`\n  --> tests/ui/rename.rs:141:9\n   |\nLL | #![warn(clippy::unknown_clippy_lints)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`\n\nerror: lint `clippy::unused_label` has been renamed to `unused_labels`\n  --> tests/ui/rename.rs:142:9\n   |\nLL | #![warn(clippy::unused_label)]\n   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`\n\nerror: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default`\n  --> tests/ui/rename.rs:143:9\n   |\nLL | #![warn(clippy::unwrap_or_else_default)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default`\n\nerror: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons`\n  --> tests/ui/rename.rs:144:9\n   |\nLL | #![warn(clippy::vtable_address_comparisons)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons`\n\nerror: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`\n  --> tests/ui/rename.rs:145:9\n   |\nLL | #![warn(clippy::zero_width_space)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`\n\nerror: aborting due to 76 previous errors\n\n"
  },
  {
    "path": "tests/ui/renamed_builtin_attr.fixed",
    "content": "//@compile-flags: -Zdeduplicate-diagnostics=yes\n\n#[clippy::cognitive_complexity = \"1\"]\n//~^ ERROR: usage of deprecated attribute\nfn main() {}\n"
  },
  {
    "path": "tests/ui/renamed_builtin_attr.rs",
    "content": "//@compile-flags: -Zdeduplicate-diagnostics=yes\n\n#[clippy::cyclomatic_complexity = \"1\"]\n//~^ ERROR: usage of deprecated attribute\nfn main() {}\n"
  },
  {
    "path": "tests/ui/renamed_builtin_attr.stderr",
    "content": "error: usage of deprecated attribute\n  --> tests/ui/renamed_builtin_attr.rs:3:3\n   |\nLL | #[clippy::cyclomatic_complexity = \"1\"]\n   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `clippy::cognitive_complexity`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/repeat_once.fixed",
    "content": "#![warn(clippy::repeat_once)]\n#[allow(unused, clippy::redundant_clone)]\nfn main() {\n    const N: usize = 1;\n    let s = \"str\";\n    let string = \"String\".to_string();\n    let slice = [1; 5];\n\n    let a = [1; 5].to_vec();\n    //~^ repeat_once\n    let b = slice.to_vec();\n    //~^ repeat_once\n    let c = \"hello\".repeat(N);\n    let d = \"hi\".to_string();\n    //~^ repeat_once\n    let e = s.to_string();\n    //~^ repeat_once\n    let f = string.clone();\n    //~^ repeat_once\n}\n"
  },
  {
    "path": "tests/ui/repeat_once.rs",
    "content": "#![warn(clippy::repeat_once)]\n#[allow(unused, clippy::redundant_clone)]\nfn main() {\n    const N: usize = 1;\n    let s = \"str\";\n    let string = \"String\".to_string();\n    let slice = [1; 5];\n\n    let a = [1; 5].repeat(1);\n    //~^ repeat_once\n    let b = slice.repeat(1);\n    //~^ repeat_once\n    let c = \"hello\".repeat(N);\n    let d = \"hi\".repeat(1);\n    //~^ repeat_once\n    let e = s.repeat(1);\n    //~^ repeat_once\n    let f = string.repeat(1);\n    //~^ repeat_once\n}\n"
  },
  {
    "path": "tests/ui/repeat_once.stderr",
    "content": "error: calling `repeat(1)` on slice\n  --> tests/ui/repeat_once.rs:9:13\n   |\nLL |     let a = [1; 5].repeat(1);\n   |             ^^^^^^^^^^^^^^^^ help: consider using `.to_vec()` instead: `[1; 5].to_vec()`\n   |\n   = note: `-D clippy::repeat-once` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::repeat_once)]`\n\nerror: calling `repeat(1)` on slice\n  --> tests/ui/repeat_once.rs:11:13\n   |\nLL |     let b = slice.repeat(1);\n   |             ^^^^^^^^^^^^^^^ help: consider using `.to_vec()` instead: `slice.to_vec()`\n\nerror: calling `repeat(1)` on str\n  --> tests/ui/repeat_once.rs:14:13\n   |\nLL |     let d = \"hi\".repeat(1);\n   |             ^^^^^^^^^^^^^^ help: consider using `.to_string()` instead: `\"hi\".to_string()`\n\nerror: calling `repeat(1)` on str\n  --> tests/ui/repeat_once.rs:16:13\n   |\nLL |     let e = s.repeat(1);\n   |             ^^^^^^^^^^^ help: consider using `.to_string()` instead: `s.to_string()`\n\nerror: calling `repeat(1)` on a string literal\n  --> tests/ui/repeat_once.rs:18:13\n   |\nLL |     let f = string.repeat(1);\n   |             ^^^^^^^^^^^^^^^^ help: consider using `.clone()` instead: `string.clone()`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/repeat_vec_with_capacity.fixed",
    "content": "#![allow(clippy::map_with_unused_argument_over_ranges)]\n#![warn(clippy::repeat_vec_with_capacity)]\n\nfn main() {\n    {\n        (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();\n        //~^ repeat_vec_with_capacity\n    }\n\n    {\n        let n = 123;\n        (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();\n        //~^ repeat_vec_with_capacity\n    }\n\n    {\n        macro_rules! from_macro {\n            ($x:expr) => {\n                vec![$x; 123];\n            };\n        }\n        // vec expansion is from another macro, don't lint\n        from_macro!(Vec::<()>::with_capacity(42));\n    }\n\n    {\n        std::iter::repeat_with(|| Vec::<()>::with_capacity(42));\n        //~^ repeat_vec_with_capacity\n    }\n\n    {\n        macro_rules! from_macro {\n            ($x:expr) => {\n                std::iter::repeat($x)\n            };\n        }\n        from_macro!(Vec::<()>::with_capacity(42));\n    }\n}\n\n#[clippy::msrv = \"1.27.0\"]\nfn msrv_check() {\n    std::iter::repeat(Vec::<()>::with_capacity(42));\n}\n"
  },
  {
    "path": "tests/ui/repeat_vec_with_capacity.rs",
    "content": "#![allow(clippy::map_with_unused_argument_over_ranges)]\n#![warn(clippy::repeat_vec_with_capacity)]\n\nfn main() {\n    {\n        vec![Vec::<()>::with_capacity(42); 123];\n        //~^ repeat_vec_with_capacity\n    }\n\n    {\n        let n = 123;\n        vec![Vec::<()>::with_capacity(42); n];\n        //~^ repeat_vec_with_capacity\n    }\n\n    {\n        macro_rules! from_macro {\n            ($x:expr) => {\n                vec![$x; 123];\n            };\n        }\n        // vec expansion is from another macro, don't lint\n        from_macro!(Vec::<()>::with_capacity(42));\n    }\n\n    {\n        std::iter::repeat(Vec::<()>::with_capacity(42));\n        //~^ repeat_vec_with_capacity\n    }\n\n    {\n        macro_rules! from_macro {\n            ($x:expr) => {\n                std::iter::repeat($x)\n            };\n        }\n        from_macro!(Vec::<()>::with_capacity(42));\n    }\n}\n\n#[clippy::msrv = \"1.27.0\"]\nfn msrv_check() {\n    std::iter::repeat(Vec::<()>::with_capacity(42));\n}\n"
  },
  {
    "path": "tests/ui/repeat_vec_with_capacity.stderr",
    "content": "error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity\n  --> tests/ui/repeat_vec_with_capacity.rs:6:9\n   |\nLL |         vec![Vec::<()>::with_capacity(42); 123];\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: only the last `Vec` will have the capacity\n   = note: `-D clippy::repeat-vec-with-capacity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]`\nhelp: if you intended to initialize multiple `Vec`s with an initial capacity, try\n   |\nLL -         vec![Vec::<()>::with_capacity(42); 123];\nLL +         (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();\n   |\n\nerror: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity\n  --> tests/ui/repeat_vec_with_capacity.rs:12:9\n   |\nLL |         vec![Vec::<()>::with_capacity(42); n];\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: only the last `Vec` will have the capacity\nhelp: if you intended to initialize multiple `Vec`s with an initial capacity, try\n   |\nLL -         vec![Vec::<()>::with_capacity(42); n];\nLL +         (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();\n   |\n\nerror: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity\n  --> tests/ui/repeat_vec_with_capacity.rs:27:9\n   |\nLL |         std::iter::repeat(Vec::<()>::with_capacity(42));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: none of the yielded `Vec`s will have the requested capacity\nhelp: if you intended to create an iterator that yields `Vec`s with an initial capacity, try\n   |\nLL -         std::iter::repeat(Vec::<()>::with_capacity(42));\nLL +         std::iter::repeat_with(|| Vec::<()>::with_capacity(42));\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/repeat_vec_with_capacity_nostd.fixed",
    "content": "#![warn(clippy::repeat_vec_with_capacity)]\n#![allow(clippy::manual_repeat_n)]\n#![no_std]\nuse core::iter;\nextern crate alloc;\nuse alloc::vec::Vec;\n\nfn nostd() {\n    let _: Vec<Vec<u8>> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect();\n    //~^ repeat_vec_with_capacity\n}\n"
  },
  {
    "path": "tests/ui/repeat_vec_with_capacity_nostd.rs",
    "content": "#![warn(clippy::repeat_vec_with_capacity)]\n#![allow(clippy::manual_repeat_n)]\n#![no_std]\nuse core::iter;\nextern crate alloc;\nuse alloc::vec::Vec;\n\nfn nostd() {\n    let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();\n    //~^ repeat_vec_with_capacity\n}\n"
  },
  {
    "path": "tests/ui/repeat_vec_with_capacity_nostd.stderr",
    "content": "error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity\n  --> tests/ui/repeat_vec_with_capacity_nostd.rs:9:27\n   |\nLL |     let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: none of the yielded `Vec`s will have the requested capacity\n   = note: `-D clippy::repeat-vec-with-capacity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]`\nhelp: if you intended to create an iterator that yields `Vec`s with an initial capacity, try\n   |\nLL -     let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();\nLL +     let _: Vec<Vec<u8>> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect();\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/repl_uninit.rs",
    "content": "#![allow(deprecated, invalid_value, clippy::uninit_assumed_init)]\n#![warn(clippy::mem_replace_with_uninit)]\n//@no-rustfix\nuse std::mem;\n\nfn might_panic<X>(x: X) -> X {\n    // in practice this would be a possibly-panicky operation\n    x\n}\n\nfn main() {\n    let mut v = vec![0i32; 4];\n    // the following is UB if `might_panic` panics\n    unsafe {\n        let taken_v = mem::replace(&mut v, mem::uninitialized());\n        //~^ mem_replace_with_uninit\n\n        let new_v = might_panic(taken_v);\n        std::mem::forget(mem::replace(&mut v, new_v));\n    }\n\n    unsafe {\n        let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init());\n        //~^ mem_replace_with_uninit\n\n        let new_v = might_panic(taken_v);\n        std::mem::forget(mem::replace(&mut v, new_v));\n    }\n\n    unsafe {\n        let taken_v = mem::replace(&mut v, mem::zeroed());\n        //~^ mem_replace_with_uninit\n\n        let new_v = might_panic(taken_v);\n        std::mem::forget(mem::replace(&mut v, new_v));\n    }\n\n    // this is silly but OK, because usize is a primitive type\n    let mut u: usize = 42;\n    let uref = &mut u;\n    let taken_u = unsafe { mem::replace(uref, mem::zeroed()) };\n    *uref = taken_u + 1;\n\n    // this is still not OK, because uninit\n    let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) };\n    //~^ mem_replace_with_uninit\n\n    *uref = taken_u + 1;\n}\n"
  },
  {
    "path": "tests/ui/repl_uninit.stderr",
    "content": "error: replacing with `mem::uninitialized()`\n  --> tests/ui/repl_uninit.rs:15:23\n   |\nLL |         let taken_v = mem::replace(&mut v, mem::uninitialized());\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)`\n   |\n   = note: `-D clippy::mem-replace-with-uninit` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_uninit)]`\n\nerror: replacing with `mem::MaybeUninit::uninit().assume_init()`\n  --> tests/ui/repl_uninit.rs:23:23\n   |\nLL |         let taken_v = mem::replace(&mut v, mem::MaybeUninit::uninit().assume_init());\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(&mut v)`\n\nerror: replacing with `mem::zeroed()`\n  --> tests/ui/repl_uninit.rs:31:23\n   |\nLL |         let taken_v = mem::replace(&mut v, mem::zeroed());\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a default value or the `take_mut` crate instead\n\nerror: replacing with `mem::uninitialized()`\n  --> tests/ui/repl_uninit.rs:45:28\n   |\nLL |     let taken_u = unsafe { mem::replace(uref, mem::uninitialized()) };\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::ptr::read(uref)`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/replace_box.fixed",
    "content": "#![warn(clippy::replace_box)]\n\nfn with_default<T: Default>(b: &mut Box<T>) {\n    **b = T::default();\n    //~^ replace_box\n}\n\nfn with_sized<T>(b: &mut Box<T>, t: T) {\n    **b = t;\n    //~^ replace_box\n}\n\nfn with_unsized<const N: usize>(b: &mut Box<[u32]>) {\n    // No lint for assigning to Box<T> where T: !Default\n    *b = Box::new([42; N]);\n}\n\nmacro_rules! create_default {\n    () => {\n        Default::default()\n    };\n}\n\nmacro_rules! create_zero_box {\n    () => {\n        Box::new(0)\n    };\n}\n\nmacro_rules! same {\n    ($v:ident) => {\n        $v\n    };\n}\n\nmacro_rules! mac {\n    (three) => {\n        3u32\n    };\n}\n\nfn main() {\n    let mut b = Box::new(1u32);\n    *b = Default::default();\n    //~^ replace_box\n    *b = Default::default();\n    //~^ replace_box\n\n    // No lint for assigning to the storage\n    *b = Default::default();\n    *b = u32::default();\n\n    // No lint if either LHS or RHS originates in macro\n    b = create_default!();\n    b = create_zero_box!();\n    same!(b) = Default::default();\n\n    *b = 5;\n    //~^ replace_box\n\n    *b = mac!(three);\n    //~^ replace_box\n\n    // No lint for assigning to Box<T> where T: !Default\n    let mut b = Box::<str>::from(\"hi\".to_string());\n    b = Default::default();\n\n    // No lint for late initializations\n    #[allow(clippy::needless_late_init)]\n    let bb: Box<u32>;\n    bb = Default::default();\n}\n\nfn issue15951() {\n    struct Foo {\n        inner: String,\n    }\n\n    fn embedded_body() {\n        let mut x = Box::new(());\n        let y = x;\n        x = Box::new(());\n\n        let mut x = Box::new(Foo { inner: String::new() });\n        let y = x.inner;\n        *x = Foo { inner: String::new() };\n        //~^ replace_box\n    }\n\n    let mut x = Box::new(Foo { inner: String::new() });\n    let in_closure = || {\n        *x = Foo { inner: String::new() };\n        //~^ replace_box\n    };\n}\n\nstatic R: fn(&mut Box<String>) = |x| **x = String::new();\n//~^ replace_box\n\nfn field() {\n    struct T {\n        content: String,\n    }\n\n    impl T {\n        fn new() -> Self {\n            Self { content: String::new() }\n        }\n    }\n\n    struct S {\n        b: Box<T>,\n    }\n\n    let mut s = S { b: Box::new(T::new()) };\n    let _b = s.b;\n    s.b = Box::new(T::new());\n\n    // Interestingly, the lint and fix are valid here as `s.b` is not really moved\n    let mut s = S { b: Box::new(T::new()) };\n    _ = s.b;\n    *s.b = T::new();\n    //~^ replace_box\n\n    let mut s = S { b: Box::new(T::new()) };\n    *s.b = T::new();\n    //~^ replace_box\n\n    struct Q(Box<T>);\n    let mut q = Q(Box::new(T::new()));\n    let _b = q.0;\n    q.0 = Box::new(T::new());\n\n    let mut q = Q(Box::new(T::new()));\n    _ = q.0;\n    *q.0 = T::new();\n    //~^ replace_box\n\n    // This one is a false negative, but it will need MIR analysis to work properly\n    let mut x = Box::new(String::new());\n    x = Box::new(String::new());\n    x;\n}\n"
  },
  {
    "path": "tests/ui/replace_box.rs",
    "content": "#![warn(clippy::replace_box)]\n\nfn with_default<T: Default>(b: &mut Box<T>) {\n    *b = Box::new(T::default());\n    //~^ replace_box\n}\n\nfn with_sized<T>(b: &mut Box<T>, t: T) {\n    *b = Box::new(t);\n    //~^ replace_box\n}\n\nfn with_unsized<const N: usize>(b: &mut Box<[u32]>) {\n    // No lint for assigning to Box<T> where T: !Default\n    *b = Box::new([42; N]);\n}\n\nmacro_rules! create_default {\n    () => {\n        Default::default()\n    };\n}\n\nmacro_rules! create_zero_box {\n    () => {\n        Box::new(0)\n    };\n}\n\nmacro_rules! same {\n    ($v:ident) => {\n        $v\n    };\n}\n\nmacro_rules! mac {\n    (three) => {\n        3u32\n    };\n}\n\nfn main() {\n    let mut b = Box::new(1u32);\n    b = Default::default();\n    //~^ replace_box\n    b = Box::default();\n    //~^ replace_box\n\n    // No lint for assigning to the storage\n    *b = Default::default();\n    *b = u32::default();\n\n    // No lint if either LHS or RHS originates in macro\n    b = create_default!();\n    b = create_zero_box!();\n    same!(b) = Default::default();\n\n    b = Box::new(5);\n    //~^ replace_box\n\n    b = Box::new(mac!(three));\n    //~^ replace_box\n\n    // No lint for assigning to Box<T> where T: !Default\n    let mut b = Box::<str>::from(\"hi\".to_string());\n    b = Default::default();\n\n    // No lint for late initializations\n    #[allow(clippy::needless_late_init)]\n    let bb: Box<u32>;\n    bb = Default::default();\n}\n\nfn issue15951() {\n    struct Foo {\n        inner: String,\n    }\n\n    fn embedded_body() {\n        let mut x = Box::new(());\n        let y = x;\n        x = Box::new(());\n\n        let mut x = Box::new(Foo { inner: String::new() });\n        let y = x.inner;\n        x = Box::new(Foo { inner: String::new() });\n        //~^ replace_box\n    }\n\n    let mut x = Box::new(Foo { inner: String::new() });\n    let in_closure = || {\n        x = Box::new(Foo { inner: String::new() });\n        //~^ replace_box\n    };\n}\n\nstatic R: fn(&mut Box<String>) = |x| *x = Box::new(String::new());\n//~^ replace_box\n\nfn field() {\n    struct T {\n        content: String,\n    }\n\n    impl T {\n        fn new() -> Self {\n            Self { content: String::new() }\n        }\n    }\n\n    struct S {\n        b: Box<T>,\n    }\n\n    let mut s = S { b: Box::new(T::new()) };\n    let _b = s.b;\n    s.b = Box::new(T::new());\n\n    // Interestingly, the lint and fix are valid here as `s.b` is not really moved\n    let mut s = S { b: Box::new(T::new()) };\n    _ = s.b;\n    s.b = Box::new(T::new());\n    //~^ replace_box\n\n    let mut s = S { b: Box::new(T::new()) };\n    s.b = Box::new(T::new());\n    //~^ replace_box\n\n    struct Q(Box<T>);\n    let mut q = Q(Box::new(T::new()));\n    let _b = q.0;\n    q.0 = Box::new(T::new());\n\n    let mut q = Q(Box::new(T::new()));\n    _ = q.0;\n    q.0 = Box::new(T::new());\n    //~^ replace_box\n\n    // This one is a false negative, but it will need MIR analysis to work properly\n    let mut x = Box::new(String::new());\n    x = Box::new(String::new());\n    x;\n}\n"
  },
  {
    "path": "tests/ui/replace_box.stderr",
    "content": "error: creating a new box\n  --> tests/ui/replace_box.rs:4:5\n   |\nLL |     *b = Box::new(T::default());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `**b = T::default()`\n   |\n   = note: this creates a needless allocation\n   = note: `-D clippy::replace-box` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::replace_box)]`\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:9:5\n   |\nLL |     *b = Box::new(t);\n   |     ^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `**b = t`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box with default content\n  --> tests/ui/replace_box.rs:44:5\n   |\nLL |     b = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with default instead: `*b = Default::default()`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box with default content\n  --> tests/ui/replace_box.rs:46:5\n   |\nLL |     b = Box::default();\n   |     ^^^^^^^^^^^^^^^^^^ help: replace existing content with default instead: `*b = Default::default()`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:58:5\n   |\nLL |     b = Box::new(5);\n   |     ^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `*b = 5`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:61:5\n   |\nLL |     b = Box::new(mac!(three));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `*b = mac!(three)`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:86:9\n   |\nLL |         x = Box::new(Foo { inner: String::new() });\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `*x = Foo { inner: String::new() }`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:92:9\n   |\nLL |         x = Box::new(Foo { inner: String::new() });\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `*x = Foo { inner: String::new() }`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:97:38\n   |\nLL | static R: fn(&mut Box<String>) = |x| *x = Box::new(String::new());\n   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `**x = String::new()`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:122:5\n   |\nLL |     s.b = Box::new(T::new());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `*s.b = T::new()`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:126:5\n   |\nLL |     s.b = Box::new(T::new());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `*s.b = T::new()`\n   |\n   = note: this creates a needless allocation\n\nerror: creating a new box\n  --> tests/ui/replace_box.rs:136:5\n   |\nLL |     q.0 = Box::new(T::new());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace existing content with inner value instead: `*q.0 = T::new()`\n   |\n   = note: this creates a needless allocation\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/repr_packed_without_abi.rs",
    "content": "#![deny(clippy::repr_packed_without_abi)]\n\n#[repr(packed)]\nstruct NetworkPacketHeader {\n    //~^ repr_packed_without_abi\n    header_length: u8,\n    header_version: u16,\n}\n\n#[repr(packed)]\nunion Foo {\n    //~^ repr_packed_without_abi\n    a: u8,\n    b: u16,\n}\n\n#[repr(C, packed)]\nstruct NoLintCNetworkPacketHeader {\n    header_length: u8,\n    header_version: u16,\n}\n\n#[repr(Rust, packed)]\nstruct NoLintRustNetworkPacketHeader {\n    header_length: u8,\n    header_version: u16,\n}\n\n#[repr(packed, C)]\nunion NotLintCFoo {\n    a: u8,\n    b: u16,\n}\n\n#[repr(packed, Rust)]\nunion NotLintRustFoo {\n    a: u8,\n    b: u16,\n}\n"
  },
  {
    "path": "tests/ui/repr_packed_without_abi.stderr",
    "content": "error: item uses `packed` representation without ABI-qualification\n  --> tests/ui/repr_packed_without_abi.rs:4:1\n   |\nLL |   #[repr(packed)]\n   |          ------ `packed` representation set here\nLL | / struct NetworkPacketHeader {\nLL | |\nLL | |     header_length: u8,\nLL | |     header_version: u16,\nLL | | }\n   | |_^\n   |\n   = warning: unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI\n   = help: qualify the desired ABI explicitly via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`\nnote: the lint level is defined here\n  --> tests/ui/repr_packed_without_abi.rs:1:9\n   |\nLL | #![deny(clippy::repr_packed_without_abi)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: item uses `packed` representation without ABI-qualification\n  --> tests/ui/repr_packed_without_abi.rs:11:1\n   |\nLL |   #[repr(packed)]\n   |          ------ `packed` representation set here\nLL | / union Foo {\nLL | |\nLL | |     a: u8,\nLL | |     b: u16,\nLL | | }\n   | |_^\n   |\n   = warning: unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI\n   = help: qualify the desired ABI explicitly via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/reserve_after_initialization.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::reserve_after_initialization)]\n#![no_main]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\n// Should lint\nfn standard() {\n    let mut v1: Vec<usize> = Vec::with_capacity(10);\n}\n\n// Should lint\nfn capacity_as_expr() {\n    let capacity = 10;\n    let mut v2: Vec<usize> = Vec::with_capacity(capacity);\n}\n\n// Shouldn't lint\nfn vec_init_with_argument() {\n    let mut v3 = vec![1];\n    v3.reserve(10);\n}\n\n// Shouldn't lint\nfn called_with_capacity() {\n    let _v4: Vec<usize> = Vec::with_capacity(10);\n}\n\n// Should lint\nfn assign_expression() {\n    let mut v5: Vec<usize> = Vec::new();\n    v5 = Vec::with_capacity(10);\n}\n\nfn in_macros() {\n    external! {\n        let mut v: Vec<usize> = vec![];\n        v.reserve(10);\n    }\n\n    with_span! {\n        span\n\n        let mut v: Vec<usize> = vec![];\n        v.reserve(10);\n    }\n}\n"
  },
  {
    "path": "tests/ui/reserve_after_initialization.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::reserve_after_initialization)]\n#![no_main]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\n// Should lint\nfn standard() {\n    let mut v1: Vec<usize> = vec![];\n    //~^ reserve_after_initialization\n    v1.reserve(10);\n}\n\n// Should lint\nfn capacity_as_expr() {\n    let capacity = 10;\n    let mut v2: Vec<usize> = vec![];\n    //~^ reserve_after_initialization\n    v2.reserve(capacity);\n}\n\n// Shouldn't lint\nfn vec_init_with_argument() {\n    let mut v3 = vec![1];\n    v3.reserve(10);\n}\n\n// Shouldn't lint\nfn called_with_capacity() {\n    let _v4: Vec<usize> = Vec::with_capacity(10);\n}\n\n// Should lint\nfn assign_expression() {\n    let mut v5: Vec<usize> = Vec::new();\n    v5 = Vec::new();\n    //~^ reserve_after_initialization\n    v5.reserve(10);\n}\n\nfn in_macros() {\n    external! {\n        let mut v: Vec<usize> = vec![];\n        v.reserve(10);\n    }\n\n    with_span! {\n        span\n\n        let mut v: Vec<usize> = vec![];\n        v.reserve(10);\n    }\n}\n"
  },
  {
    "path": "tests/ui/reserve_after_initialization.stderr",
    "content": "error: call to `reserve` immediately after creation\n  --> tests/ui/reserve_after_initialization.rs:10:5\n   |\nLL | /     let mut v1: Vec<usize> = vec![];\nLL | |\nLL | |     v1.reserve(10);\n   | |___________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `let mut v1: Vec<usize> = Vec::with_capacity(10);`\n   |\n   = note: `-D clippy::reserve-after-initialization` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::reserve_after_initialization)]`\n\nerror: call to `reserve` immediately after creation\n  --> tests/ui/reserve_after_initialization.rs:18:5\n   |\nLL | /     let mut v2: Vec<usize> = vec![];\nLL | |\nLL | |     v2.reserve(capacity);\n   | |_________________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `let mut v2: Vec<usize> = Vec::with_capacity(capacity);`\n\nerror: call to `reserve` immediately after creation\n  --> tests/ui/reserve_after_initialization.rs:37:5\n   |\nLL | /     v5 = Vec::new();\nLL | |\nLL | |     v5.reserve(10);\n   | |___________________^ help: consider using `Vec::with_capacity(/* Space hint */)`: `v5 = Vec::with_capacity(10);`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/rest_pat_in_fully_bound_structs.fixed",
    "content": "#![warn(clippy::rest_pat_in_fully_bound_structs)]\n#![allow(clippy::struct_field_names)]\n\nstruct A {\n    a: i32,\n    b: i64,\n    c: &'static str,\n}\n\nmacro_rules! foo {\n    ($param:expr) => {\n        match $param {\n            A { a: 0, b: 0, c: \"\", .. } => {},\n            _ => {},\n        }\n    };\n}\n\nfn main() {\n    let a_struct = A { a: 5, b: 42, c: \"A\" };\n\n    match a_struct {\n        A { a: 5, b: 42, c: \"\",  } => {}, // Lint\n        //~^ rest_pat_in_fully_bound_structs\n        A { a: 0, b: 0, c: \"\",  } => {}, // Lint\n        //~^ rest_pat_in_fully_bound_structs\n        _ => {},\n    }\n\n    match a_struct {\n        A { a: 5, b: 42, .. } => {},\n        A { a: 0, b: 0, c: \"\",  } => {}, // Lint\n        //~^ rest_pat_in_fully_bound_structs\n        _ => {},\n    }\n\n    // No lint\n    match a_struct {\n        A { a: 5, .. } => {},\n        A { a: 0, b: 0, .. } => {},\n        _ => {},\n    }\n\n    // No lint\n    foo!(a_struct);\n\n    #[non_exhaustive]\n    struct B {\n        a: u32,\n        b: u32,\n        c: u64,\n    }\n\n    let b_struct = B { a: 5, b: 42, c: 342 };\n\n    match b_struct {\n        B { a: 5, b: 42, .. } => {},\n        B { a: 0, b: 0, c: 128, .. } => {}, // No Lint\n        _ => {},\n    }\n}\n"
  },
  {
    "path": "tests/ui/rest_pat_in_fully_bound_structs.rs",
    "content": "#![warn(clippy::rest_pat_in_fully_bound_structs)]\n#![allow(clippy::struct_field_names)]\n\nstruct A {\n    a: i32,\n    b: i64,\n    c: &'static str,\n}\n\nmacro_rules! foo {\n    ($param:expr) => {\n        match $param {\n            A { a: 0, b: 0, c: \"\", .. } => {},\n            _ => {},\n        }\n    };\n}\n\nfn main() {\n    let a_struct = A { a: 5, b: 42, c: \"A\" };\n\n    match a_struct {\n        A { a: 5, b: 42, c: \"\", .. } => {}, // Lint\n        //~^ rest_pat_in_fully_bound_structs\n        A { a: 0, b: 0, c: \"\", .. } => {}, // Lint\n        //~^ rest_pat_in_fully_bound_structs\n        _ => {},\n    }\n\n    match a_struct {\n        A { a: 5, b: 42, .. } => {},\n        A { a: 0, b: 0, c: \"\", .. } => {}, // Lint\n        //~^ rest_pat_in_fully_bound_structs\n        _ => {},\n    }\n\n    // No lint\n    match a_struct {\n        A { a: 5, .. } => {},\n        A { a: 0, b: 0, .. } => {},\n        _ => {},\n    }\n\n    // No lint\n    foo!(a_struct);\n\n    #[non_exhaustive]\n    struct B {\n        a: u32,\n        b: u32,\n        c: u64,\n    }\n\n    let b_struct = B { a: 5, b: 42, c: 342 };\n\n    match b_struct {\n        B { a: 5, b: 42, .. } => {},\n        B { a: 0, b: 0, c: 128, .. } => {}, // No Lint\n        _ => {},\n    }\n}\n"
  },
  {
    "path": "tests/ui/rest_pat_in_fully_bound_structs.stderr",
    "content": "error: unnecessary use of `..` pattern in struct binding. All fields were already bound\n  --> tests/ui/rest_pat_in_fully_bound_structs.rs:23:9\n   |\nLL |         A { a: 5, b: 42, c: \"\", .. } => {}, // Lint\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::rest-pat-in-fully-bound-structs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::rest_pat_in_fully_bound_structs)]`\nhelp: consider removing `..` from this binding\n   |\nLL -         A { a: 5, b: 42, c: \"\", .. } => {}, // Lint\nLL +         A { a: 5, b: 42, c: \"\",  } => {}, // Lint\n   |\n\nerror: unnecessary use of `..` pattern in struct binding. All fields were already bound\n  --> tests/ui/rest_pat_in_fully_bound_structs.rs:25:9\n   |\nLL |         A { a: 0, b: 0, c: \"\", .. } => {}, // Lint\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing `..` from this binding\n   |\nLL -         A { a: 0, b: 0, c: \"\", .. } => {}, // Lint\nLL +         A { a: 0, b: 0, c: \"\",  } => {}, // Lint\n   |\n\nerror: unnecessary use of `..` pattern in struct binding. All fields were already bound\n  --> tests/ui/rest_pat_in_fully_bound_structs.rs:32:9\n   |\nLL |         A { a: 0, b: 0, c: \"\", .. } => {}, // Lint\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing `..` from this binding\n   |\nLL -         A { a: 0, b: 0, c: \"\", .. } => {}, // Lint\nLL +         A { a: 0, b: 0, c: \"\",  } => {}, // Lint\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/result_filter_map.fixed",
    "content": "#![warn(clippy::result_filter_map)]\n#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]\n\nfn odds_out(x: i32) -> Result<i32, ()> {\n    if x % 2 == 0 { Ok(x) } else { Err(()) }\n}\n\nfn main() {\n    // Unlike the Option version, Result does not have a filter operation => we will check for iterators\n    // only\n    let _ = vec![Ok(1) as Result<i32, ()>]\n        .into_iter()\n        .flatten();\n\n    let _ = vec![Ok(1) as Result<i32, ()>]\n        .into_iter()\n        .flatten();\n\n    let _ = vec![1]\n        .into_iter()\n        .map(odds_out)\n        .flatten();\n    let _ = vec![1]\n        .into_iter()\n        .map(odds_out)\n        .flatten();\n}\n"
  },
  {
    "path": "tests/ui/result_filter_map.rs",
    "content": "#![warn(clippy::result_filter_map)]\n#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]\n\nfn odds_out(x: i32) -> Result<i32, ()> {\n    if x % 2 == 0 { Ok(x) } else { Err(()) }\n}\n\nfn main() {\n    // Unlike the Option version, Result does not have a filter operation => we will check for iterators\n    // only\n    let _ = vec![Ok(1) as Result<i32, ()>]\n        .into_iter()\n        .filter(Result::is_ok)\n        //~^ result_filter_map\n        .map(Result::unwrap);\n\n    let _ = vec![Ok(1) as Result<i32, ()>]\n        .into_iter()\n        .filter(|o| o.is_ok())\n        //~^ result_filter_map\n        .map(|o| o.unwrap());\n\n    let _ = vec![1]\n        .into_iter()\n        .map(odds_out)\n        .filter(Result::is_ok)\n        //~^ result_filter_map\n        .map(Result::unwrap);\n    let _ = vec![1]\n        .into_iter()\n        .map(odds_out)\n        .filter(|o| o.is_ok())\n        //~^ result_filter_map\n        .map(|o| o.unwrap());\n}\n"
  },
  {
    "path": "tests/ui/result_filter_map.stderr",
    "content": "error: `filter` for `Ok` followed by `unwrap`\n  --> tests/ui/result_filter_map.rs:13:10\n   |\nLL |           .filter(Result::is_ok)\n   |  __________^\nLL | |\nLL | |         .map(Result::unwrap);\n   | |____________________________^ help: consider using `flatten` instead: `flatten()`\n   |\n   = note: `-D clippy::result-filter-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_filter_map)]`\n\nerror: `filter` for `Ok` followed by `unwrap`\n  --> tests/ui/result_filter_map.rs:19:10\n   |\nLL |           .filter(|o| o.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|o| o.unwrap());\n   | |____________________________^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `Ok` followed by `unwrap`\n  --> tests/ui/result_filter_map.rs:26:10\n   |\nLL |           .filter(Result::is_ok)\n   |  __________^\nLL | |\nLL | |         .map(Result::unwrap);\n   | |____________________________^ help: consider using `flatten` instead: `flatten()`\n\nerror: `filter` for `Ok` followed by `unwrap`\n  --> tests/ui/result_filter_map.rs:32:10\n   |\nLL |           .filter(|o| o.is_ok())\n   |  __________^\nLL | |\nLL | |         .map(|o| o.unwrap());\n   | |____________________________^ help: consider using `flatten` instead: `flatten()`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/result_large_err.rs",
    "content": "//@ignore-bitwidth: 32\n\n#![warn(clippy::result_large_err)]\n#![allow(clippy::large_enum_variant)]\n\npub fn small_err() -> Result<(), u128> {\n    Ok(())\n}\n\npub fn large_err() -> Result<(), [u8; 512]> {\n    //~^ result_large_err\n\n    Ok(())\n}\n\npub struct FullyDefinedLargeError {\n    _foo: u128,\n    _bar: [u8; 100],\n    _foobar: [u8; 120],\n}\n\nimpl FullyDefinedLargeError {\n    pub fn ret() -> Result<(), Self> {\n        //~^ result_large_err\n\n        Ok(())\n    }\n}\n\npub fn struct_error() -> Result<(), FullyDefinedLargeError> {\n    //~^ result_large_err\n\n    Ok(())\n}\n\ntype Fdlr<T> = std::result::Result<T, FullyDefinedLargeError>;\npub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {\n    //~^ result_large_err\n\n    Ok(x)\n}\n\npub fn param_small_error<R>() -> Result<(), (R, u128)> {\n    Ok(())\n}\n\npub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {\n    //~^ result_large_err\n\n    Ok(())\n}\n\npub enum LargeErrorVariants<T> {\n    _Small(u8),\n    _Omg([u8; 512]),\n    _Param(T),\n}\n\nimpl LargeErrorVariants<()> {\n    pub fn large_enum_error() -> Result<(), Self> {\n        //~^ result_large_err\n\n        Ok(())\n    }\n}\n\nenum MultipleLargeVariants {\n    _Biggest([u8; 1024]),\n    _AlsoBig([u8; 512]),\n    _Ok(usize),\n}\n\nimpl MultipleLargeVariants {\n    fn large_enum_error() -> Result<(), Self> {\n        //~^ result_large_err\n\n        Ok(())\n    }\n}\n\ntrait TraitForcesLargeError {\n    fn large_error() -> Result<(), [u8; 512]> {\n        //~^ result_large_err\n\n        Ok(())\n    }\n}\n\nstruct TraitImpl;\n\nimpl TraitForcesLargeError for TraitImpl {\n    // Should not lint\n    fn large_error() -> Result<(), [u8; 512]> {\n        Ok(())\n    }\n}\n\npub union FullyDefinedUnionError {\n    _maybe: u8,\n    _or_even: [[u8; 16]; 32],\n}\n\npub fn large_union_err() -> Result<(), FullyDefinedUnionError> {\n    //~^ result_large_err\n\n    Ok(())\n}\n\npub union UnionError<T: Copy> {\n    _maybe: T,\n    _or_perhaps_even: (T, [u8; 512]),\n}\n\npub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {\n    //~^ result_large_err\n\n    Ok(())\n}\n\npub struct ArrayError<T, U> {\n    _large_array: [T; 32],\n    _other_stuff: U,\n}\n\npub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {\n    //~^ result_large_err\n\n    Ok(())\n}\n\npub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {\n    //~^ result_large_err\n\n    Ok(())\n}\n\n// Issue #10005\nenum Empty {}\nfn _empty_error() -> Result<(), Empty> {\n    Ok(())\n}\n\nfn main() {}\n\nfn issue16249() {\n    type Large = [u8; 1024];\n\n    let closure = || -> Result<(), Large> { Ok(()) };\n    //~^ result_large_err\n    let closure = || Ok::<(), Large>(());\n    //~^ result_large_err\n}\n"
  },
  {
    "path": "tests/ui/result_large_err.stderr",
    "content": "error: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:10:23\n   |\nLL | pub fn large_err() -> Result<(), [u8; 512]> {\n   |                       ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes\n   |\n   = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`\n   = note: `-D clippy::result-large-err` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_large_err)]`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:23:21\n   |\nLL |     pub fn ret() -> Result<(), Self> {\n   |                     ^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes\n   |\n   = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:30:26\n   |\nLL | pub fn struct_error() -> Result<(), FullyDefinedLargeError> {\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 240 bytes\n   |\n   = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:37:45\n   |\nLL | pub fn large_err_via_type_alias<T>(x: T) -> Fdlr<T> {\n   |                                             ^^^^^^^ the `Err`-variant is at least 240 bytes\n   |\n   = help: try reducing the size of `FullyDefinedLargeError`, for example by boxing large elements or replacing it with `Box<FullyDefinedLargeError>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:47:34\n   |\nLL | pub fn param_large_error<R>() -> Result<(), (u128, R, FullyDefinedLargeError)> {\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 256 bytes\n   |\n   = help: try reducing the size of `(u128, R, FullyDefinedLargeError)`, for example by boxing large elements or replacing it with `Box<(u128, R, FullyDefinedLargeError)>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:60:34\n   |\nLL |     _Omg([u8; 512]),\n   |     --------------- the largest variant contains at least 512 bytes\n...\nLL |     pub fn large_enum_error() -> Result<(), Self> {\n   |                                  ^^^^^^^^^^^^^^^^\n   |\n   = help: try reducing the size of `LargeErrorVariants<()>`, for example by boxing large elements or replacing it with `Box<LargeErrorVariants<()>>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:74:30\n   |\nLL |     _Biggest([u8; 1024]),\n   |     -------------------- the largest variant contains at least 1024 bytes\nLL |     _AlsoBig([u8; 512]),\n   |     ------------------- the variant `_AlsoBig` contains at least 512 bytes\n...\nLL |     fn large_enum_error() -> Result<(), Self> {\n   |                              ^^^^^^^^^^^^^^^^\n   |\n   = help: try reducing the size of `MultipleLargeVariants`, for example by boxing large elements or replacing it with `Box<MultipleLargeVariants>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:82:25\n   |\nLL |     fn large_error() -> Result<(), [u8; 512]> {\n   |                         ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes\n   |\n   = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:103:29\n   |\nLL | pub fn large_union_err() -> Result<(), FullyDefinedUnionError> {\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes\n   |\n   = help: try reducing the size of `FullyDefinedUnionError`, for example by boxing large elements or replacing it with `Box<FullyDefinedUnionError>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:114:40\n   |\nLL | pub fn param_large_union<T: Copy>() -> Result<(), UnionError<T>> {\n   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes\n   |\n   = help: try reducing the size of `UnionError<T>`, for example by boxing large elements or replacing it with `Box<UnionError<T>>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:125:34\n   |\nLL | pub fn array_error_subst<U>() -> Result<(), ArrayError<i32, U>> {\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes\n   |\n   = help: try reducing the size of `ArrayError<i32, U>`, for example by boxing large elements or replacing it with `Box<ArrayError<i32, U>>`\n\nerror: the `Err`-variant returned from this function is very large\n  --> tests/ui/result_large_err.rs:131:31\n   |\nLL | pub fn array_error<T, U>() -> Result<(), ArrayError<(i32, T), U>> {\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 128 bytes\n   |\n   = help: try reducing the size of `ArrayError<(i32, T), U>`, for example by boxing large elements or replacing it with `Box<ArrayError<(i32, T), U>>`\n\nerror: the `Err`-variant returned from this closure is very large\n  --> tests/ui/result_large_err.rs:148:25\n   |\nLL |     let closure = || -> Result<(), Large> { Ok(()) };\n   |                         ^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 1024 bytes\n   |\n   = help: try reducing the size of `[u8; 1024]`, for example by boxing large elements or replacing it with `Box<[u8; 1024]>`\n\nerror: the `Err`-variant returned from this closure is very large\n  --> tests/ui/result_large_err.rs:150:19\n   |\nLL |     let closure = || Ok::<(), Large>(());\n   |                   ^^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 1024 bytes\n   |\n   = help: try reducing the size of `[u8; 1024]`, for example by boxing large elements or replacing it with `Box<[u8; 1024]>`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/result_map_or_into_option.fixed",
    "content": "#![warn(clippy::result_map_or_into_option)]\n\nfn main() {\n    let opt: Result<u32, &str> = Ok(1);\n    let _ = opt.ok();\n    //~^ result_map_or_into_option\n\n    let _ = opt.ok();\n    //~^ result_map_or_into_option\n\n    #[rustfmt::skip]\n    let _ = opt.ok();\n    //~^ result_map_or_into_option\n\n    let rewrap = |s: u32| -> Option<u32> { Some(s) };\n\n    // A non-Some `f` arg should not emit the lint\n    let opt: Result<u32, &str> = Ok(1);\n    let _ = opt.map_or(None, rewrap);\n\n    // A non-Some `f` closure where the argument is not used as the\n    // return should not emit the lint\n    let opt: Result<u32, &str> = Ok(1);\n    _ = opt.map_or(None, |_x| Some(1));\n    let _ = opt.map_or_else(|a| a.parse::<u32>().ok(), Some);\n}\n"
  },
  {
    "path": "tests/ui/result_map_or_into_option.rs",
    "content": "#![warn(clippy::result_map_or_into_option)]\n\nfn main() {\n    let opt: Result<u32, &str> = Ok(1);\n    let _ = opt.map_or(None, Some);\n    //~^ result_map_or_into_option\n\n    let _ = opt.map_or_else(|_| None, Some);\n    //~^ result_map_or_into_option\n\n    #[rustfmt::skip]\n    let _ = opt.map_or_else(|_| { None }, Some);\n    //~^ result_map_or_into_option\n\n    let rewrap = |s: u32| -> Option<u32> { Some(s) };\n\n    // A non-Some `f` arg should not emit the lint\n    let opt: Result<u32, &str> = Ok(1);\n    let _ = opt.map_or(None, rewrap);\n\n    // A non-Some `f` closure where the argument is not used as the\n    // return should not emit the lint\n    let opt: Result<u32, &str> = Ok(1);\n    _ = opt.map_or(None, |_x| Some(1));\n    let _ = opt.map_or_else(|a| a.parse::<u32>().ok(), Some);\n}\n"
  },
  {
    "path": "tests/ui/result_map_or_into_option.stderr",
    "content": "error: called `map_or(None, Some)` on a `Result` value\n  --> tests/ui/result_map_or_into_option.rs:5:13\n   |\nLL |     let _ = opt.map_or(None, Some);\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`\n   |\n   = note: `-D clippy::result-map-or-into-option` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]`\n\nerror: called `map_or_else(|_| None, Some)` on a `Result` value\n  --> tests/ui/result_map_or_into_option.rs:8:13\n   |\nLL |     let _ = opt.map_or_else(|_| None, Some);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`\n\nerror: called `map_or_else(|_| None, Some)` on a `Result` value\n  --> tests/ui/result_map_or_into_option.rs:12:13\n   |\nLL |     let _ = opt.map_or_else(|_| { None }, Some);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/result_map_unit_fn_fixable.fixed",
    "content": "#![warn(clippy::result_map_unit_fn)]\n\nfn do_nothing<T>(_: T) {}\n\nfn diverge<T>(_: T) -> ! {\n    panic!()\n}\n\nfn plus_one(value: usize) -> usize {\n    value + 1\n}\n\nstruct HasResult {\n    field: Result<usize, usize>,\n}\n\nimpl HasResult {\n    fn do_result_nothing(&self, value: usize) {}\n\n    fn do_result_plus_one(&self, value: usize) -> usize {\n        value + 1\n    }\n}\n\n#[rustfmt::skip]\nfn result_map_unit_fn() {\n    let x = HasResult { field: Ok(10) };\n\n    x.field.map(plus_one);\n    let _: Result<(), usize> = x.field.map(do_nothing);\n\n    if let Ok(x_field) = x.field { do_nothing(x_field) }\n    //~^ result_map_unit_fn\n\n    if let Ok(x_field) = x.field { do_nothing(x_field) }\n    //~^ result_map_unit_fn\n\n    if let Ok(x_field) = x.field { diverge(x_field) }\n    //~^ result_map_unit_fn\n\n    let captured = 10;\n    if let Ok(value) = x.field { do_nothing(value + captured) };\n    let _: Result<(), usize> = x.field.map(|value| do_nothing(value + captured));\n\n    if let Ok(value) = x.field { x.do_result_nothing(value + captured) }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }\n    //~^ result_map_unit_fn\n\n\n    if let Ok(value) = x.field { do_nothing(value + captured) }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { do_nothing(value + captured) }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { do_nothing(value + captured); }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { do_nothing(value + captured); }\n    //~^ result_map_unit_fn\n\n\n    if let Ok(value) = x.field { diverge(value + captured) }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { diverge(value + captured) }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { diverge(value + captured); }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { diverge(value + captured); }\n    //~^ result_map_unit_fn\n\n\n    x.field.map(|value| plus_one(value + captured));\n    x.field.map(|value| { plus_one(value + captured) });\n    if let Ok(value) = x.field { let y = plus_one(value + captured); }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { plus_one(value + captured); }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { plus_one(value + captured); }\n    //~^ result_map_unit_fn\n\n\n    if let Ok(ref value) = x.field { do_nothing(value + captured) }\n    //~^ result_map_unit_fn\n\n    if let Ok(value) = x.field { println!(\"{value:?}\") }\n    //~^ result_map_unit_fn\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/result_map_unit_fn_fixable.rs",
    "content": "#![warn(clippy::result_map_unit_fn)]\n\nfn do_nothing<T>(_: T) {}\n\nfn diverge<T>(_: T) -> ! {\n    panic!()\n}\n\nfn plus_one(value: usize) -> usize {\n    value + 1\n}\n\nstruct HasResult {\n    field: Result<usize, usize>,\n}\n\nimpl HasResult {\n    fn do_result_nothing(&self, value: usize) {}\n\n    fn do_result_plus_one(&self, value: usize) -> usize {\n        value + 1\n    }\n}\n\n#[rustfmt::skip]\nfn result_map_unit_fn() {\n    let x = HasResult { field: Ok(10) };\n\n    x.field.map(plus_one);\n    let _: Result<(), usize> = x.field.map(do_nothing);\n\n    x.field.map(do_nothing);\n    //~^ result_map_unit_fn\n\n    x.field.map(do_nothing);\n    //~^ result_map_unit_fn\n\n    x.field.map(diverge);\n    //~^ result_map_unit_fn\n\n    let captured = 10;\n    if let Ok(value) = x.field { do_nothing(value + captured) };\n    let _: Result<(), usize> = x.field.map(|value| do_nothing(value + captured));\n\n    x.field.map(|value| x.do_result_nothing(value + captured));\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { x.do_result_plus_one(value + captured); });\n    //~^ result_map_unit_fn\n\n\n    x.field.map(|value| do_nothing(value + captured));\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { do_nothing(value + captured) });\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { do_nothing(value + captured); });\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { { do_nothing(value + captured); } });\n    //~^ result_map_unit_fn\n\n\n    x.field.map(|value| diverge(value + captured));\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { diverge(value + captured) });\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { diverge(value + captured); });\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { { diverge(value + captured); } });\n    //~^ result_map_unit_fn\n\n\n    x.field.map(|value| plus_one(value + captured));\n    x.field.map(|value| { plus_one(value + captured) });\n    x.field.map(|value| { let y = plus_one(value + captured); });\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { plus_one(value + captured); });\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| { { plus_one(value + captured); } });\n    //~^ result_map_unit_fn\n\n\n    x.field.map(|ref value| { do_nothing(value + captured) });\n    //~^ result_map_unit_fn\n\n    x.field.map(|value| println!(\"{value:?}\"));\n    //~^ result_map_unit_fn\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/result_map_unit_fn_fixable.stderr",
    "content": "error: called `map(f)` on a `Result` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:32:5\n   |\nLL |     x.field.map(do_nothing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::result-map-unit-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_map_unit_fn)]`\nhelp: use `if let` instead\n   |\nLL -     x.field.map(do_nothing);\nLL +     if let Ok(x_field) = x.field { do_nothing(x_field) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:35:5\n   |\nLL |     x.field.map(do_nothing);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(do_nothing);\nLL +     if let Ok(x_field) = x.field { do_nothing(x_field) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:38:5\n   |\nLL |     x.field.map(diverge);\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(diverge);\nLL +     if let Ok(x_field) = x.field { diverge(x_field) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:45:5\n   |\nLL |     x.field.map(|value| x.do_result_nothing(value + captured));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| x.do_result_nothing(value + captured));\nLL +     if let Ok(value) = x.field { x.do_result_nothing(value + captured) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:48:5\n   |\nLL |     x.field.map(|value| { x.do_result_plus_one(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { x.do_result_plus_one(value + captured); });\nLL +     if let Ok(value) = x.field { x.do_result_plus_one(value + captured); }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:52:5\n   |\nLL |     x.field.map(|value| do_nothing(value + captured));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| do_nothing(value + captured));\nLL +     if let Ok(value) = x.field { do_nothing(value + captured) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:55:5\n   |\nLL |     x.field.map(|value| { do_nothing(value + captured) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { do_nothing(value + captured) });\nLL +     if let Ok(value) = x.field { do_nothing(value + captured) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:58:5\n   |\nLL |     x.field.map(|value| { do_nothing(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { do_nothing(value + captured); });\nLL +     if let Ok(value) = x.field { do_nothing(value + captured); }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:61:5\n   |\nLL |     x.field.map(|value| { { do_nothing(value + captured); } });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { { do_nothing(value + captured); } });\nLL +     if let Ok(value) = x.field { do_nothing(value + captured); }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:65:5\n   |\nLL |     x.field.map(|value| diverge(value + captured));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| diverge(value + captured));\nLL +     if let Ok(value) = x.field { diverge(value + captured) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:68:5\n   |\nLL |     x.field.map(|value| { diverge(value + captured) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { diverge(value + captured) });\nLL +     if let Ok(value) = x.field { diverge(value + captured) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:71:5\n   |\nLL |     x.field.map(|value| { diverge(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { diverge(value + captured); });\nLL +     if let Ok(value) = x.field { diverge(value + captured); }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:74:5\n   |\nLL |     x.field.map(|value| { { diverge(value + captured); } });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { { diverge(value + captured); } });\nLL +     if let Ok(value) = x.field { diverge(value + captured); }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:80:5\n   |\nLL |     x.field.map(|value| { let y = plus_one(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { let y = plus_one(value + captured); });\nLL +     if let Ok(value) = x.field { let y = plus_one(value + captured); }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:83:5\n   |\nLL |     x.field.map(|value| { plus_one(value + captured); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { plus_one(value + captured); });\nLL +     if let Ok(value) = x.field { plus_one(value + captured); }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:86:5\n   |\nLL |     x.field.map(|value| { { plus_one(value + captured); } });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { { plus_one(value + captured); } });\nLL +     if let Ok(value) = x.field { plus_one(value + captured); }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:90:5\n   |\nLL |     x.field.map(|ref value| { do_nothing(value + captured) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|ref value| { do_nothing(value + captured) });\nLL +     if let Ok(ref value) = x.field { do_nothing(value + captured) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_fixable.rs:93:5\n   |\nLL |     x.field.map(|value| println!(\"{value:?}\"));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| println!(\"{value:?}\"));\nLL +     if let Ok(value) = x.field { println!(\"{value:?}\") }\n   |\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/result_map_unit_fn_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::result_map_unit_fn)]\n#![feature(never_type)]\n#![allow(clippy::unnecessary_map_on_constructor)]\n\nstruct HasResult {\n    field: Result<usize, usize>,\n}\n\nfn do_nothing<T>(_: T) {}\n\nfn diverge<T>(_: T) -> ! {\n    panic!()\n}\n\nfn plus_one(value: usize) -> usize {\n    value + 1\n}\n\n#[rustfmt::skip]\nfn result_map_unit_fn() {\n    let x = HasResult { field: Ok(10) };\n\n    x.field.map(|value| { do_nothing(value); do_nothing(value) });\n    //~^ result_map_unit_fn\n\n\n\n    x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });\n    //~^ result_map_unit_fn\n\n\n    // Suggestion for the let block should be `{ ... }` as it's too difficult to build a\n    // proper suggestion for these cases\n    x.field.map(|value| {\n    //~^ result_map_unit_fn\n\n        do_nothing(value);\n        do_nothing(value)\n    });\n    x.field.map(|value| { do_nothing(value); do_nothing(value); });\n    //~^ result_map_unit_fn\n\n\n    // The following should suggest `if let Ok(_X) ...` as it's difficult to generate a proper let variable name for them\n    let res: Result<!, usize> = Ok(42).map(diverge);\n    \"12\".parse::<i32>().map(diverge);\n    //~^ result_map_unit_fn\n\n\n    let res: Result<(), usize> = Ok(plus_one(1)).map(do_nothing);\n\n    // Should suggest `if let Ok(_y) ...` to not override the existing foo variable\n    let y: Result<usize, usize> = Ok(42);\n    y.map(do_nothing);\n    //~^ result_map_unit_fn\n\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/result_map_unit_fn_unfixable.stderr",
    "content": "error: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_unfixable.rs:24:5\n   |\nLL |     x.field.map(|value| { do_nothing(value); do_nothing(value) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::result-map-unit-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_map_unit_fn)]`\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { do_nothing(value); do_nothing(value) });\nLL +     if let Ok(value) = x.field { ... }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_unfixable.rs:29:5\n   |\nLL |     x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| if value > 0 { do_nothing(value); do_nothing(value) });\nLL +     if let Ok(value) = x.field { ... }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_unfixable.rs:35:5\n   |\nLL | /     x.field.map(|value| {\nLL | |\nLL | |\nLL | |         do_nothing(value);\nLL | |         do_nothing(value)\nLL | |     });\n   | |______^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| {\nLL -\nLL - \nLL -         do_nothing(value);\nLL -         do_nothing(value)\nLL -     });\nLL +     if let Ok(value) = x.field { ... }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a closure that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_unfixable.rs:41:5\n   |\nLL |     x.field.map(|value| { do_nothing(value); do_nothing(value); });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     x.field.map(|value| { do_nothing(value); do_nothing(value); });\nLL +     if let Ok(value) = x.field { ... }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_unfixable.rs:47:5\n   |\nLL |     \"12\".parse::<i32>().map(diverge);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     \"12\".parse::<i32>().map(diverge);\nLL +     if let Ok(a) = \"12\".parse::<i32>() { diverge(a) }\n   |\n\nerror: called `map(f)` on a `Result` value where `f` is a function that returns the unit type `()`\n  --> tests/ui/result_map_unit_fn_unfixable.rs:55:5\n   |\nLL |     y.map(do_nothing);\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: use `if let` instead\n   |\nLL -     y.map(do_nothing);\nLL +     if let Ok(_y) = y { do_nothing(_y) }\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/result_unit_error.rs",
    "content": "#![warn(clippy::result_unit_err)]\n\npub fn returns_unit_error() -> Result<u32, ()> {\n    //~^ result_unit_err\n\n    Err(())\n}\n\nfn private_unit_errors() -> Result<String, ()> {\n    Err(())\n}\n\npub trait HasUnitError {\n    fn get_that_error(&self) -> Result<bool, ()>;\n    //~^ result_unit_err\n\n    fn get_this_one_too(&self) -> Result<bool, ()> {\n        //~^ result_unit_err\n\n        Err(())\n    }\n}\n\nimpl HasUnitError for () {\n    fn get_that_error(&self) -> Result<bool, ()> {\n        Ok(true)\n    }\n}\n\ntrait PrivateUnitError {\n    fn no_problem(&self) -> Result<usize, ()>;\n}\n\npub struct UnitErrorHolder;\n\nimpl UnitErrorHolder {\n    pub fn unit_error(&self) -> Result<usize, ()> {\n        //~^ result_unit_err\n\n        Ok(0)\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/6546\npub mod issue_6546 {\n    type ResInv<A, B> = Result<B, A>;\n\n    pub fn should_lint() -> ResInv<(), usize> {\n        //~^ result_unit_err\n\n        Ok(0)\n    }\n\n    pub fn should_not_lint() -> ResInv<usize, ()> {\n        Ok(())\n    }\n\n    type MyRes<A, B> = Result<(A, B), Box<dyn std::error::Error>>;\n\n    pub fn should_not_lint2(x: i32) -> MyRes<i32, ()> {\n        Ok((x, ()))\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/result_unit_error.stderr",
    "content": "error: this returns a `Result<_, ()>`\n  --> tests/ui/result_unit_error.rs:3:1\n   |\nLL | pub fn returns_unit_error() -> Result<u32, ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n   = note: `-D clippy::result-unit-err` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]`\n\nerror: this returns a `Result<_, ()>`\n  --> tests/ui/result_unit_error.rs:14:5\n   |\nLL |     fn get_that_error(&self) -> Result<bool, ()>;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n\nerror: this returns a `Result<_, ()>`\n  --> tests/ui/result_unit_error.rs:17:5\n   |\nLL |     fn get_this_one_too(&self) -> Result<bool, ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n\nerror: this returns a `Result<_, ()>`\n  --> tests/ui/result_unit_error.rs:37:5\n   |\nLL |     pub fn unit_error(&self) -> Result<usize, ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n\nerror: this returns a `Result<_, ()>`\n  --> tests/ui/result_unit_error.rs:48:5\n   |\nLL |     pub fn should_lint() -> ResInv<(), usize> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/result_unit_error_no_std.rs",
    "content": "#![feature(lang_items, libc)]\n#![no_std]\n#![no_main]\n#![warn(clippy::result_unit_err)]\n\n#[clippy::msrv = \"1.80\"]\npub fn returns_unit_error_no_lint() -> Result<u32, ()> {\n    Err(())\n}\n\n#[clippy::msrv = \"1.81\"]\npub fn returns_unit_error_lint() -> Result<u32, ()> {\n    //~^ result_unit_err\n    Err(())\n}\n\n#[unsafe(no_mangle)]\nextern \"C\" fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {\n    0\n}\n\n#[panic_handler]\nfn panic(_info: &core::panic::PanicInfo) -> ! {\n    loop {}\n}\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n"
  },
  {
    "path": "tests/ui/result_unit_error_no_std.stderr",
    "content": "error: this returns a `Result<_, ()>`\n  --> tests/ui/result_unit_error_no_std.rs:12:1\n   |\nLL | pub fn returns_unit_error_lint() -> Result<u32, ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a custom `Error` type instead\n   = note: `-D clippy::result-unit-err` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/return_and_then.fixed",
    "content": "#![warn(clippy::return_and_then)]\n\nfn main() {\n    fn test_opt_block(opt: Option<i32>) -> Option<i32> {\n        let n = opt?;\n        //~^ return_and_then\n        let mut ret = n + 1;\n        ret += n;\n        if n > 1 { Some(ret) } else { None }\n    }\n\n    fn test_opt_func(opt: Option<i32>) -> Option<i32> {\n        let n = opt?;\n        test_opt_block(Some(n))\n        //~^ return_and_then\n    }\n\n    fn test_call_chain() -> Option<i32> {\n        let n = gen_option(1)?;\n        test_opt_block(Some(n))\n        //~^ return_and_then\n    }\n\n    fn test_res_block(opt: Result<i32, i32>) -> Result<i32, i32> {\n        let n = opt?;\n        if n > 1 { Ok(n + 1) } else { Err(n) }\n        //~^ return_and_then\n    }\n\n    fn test_res_func(opt: Result<i32, i32>) -> Result<i32, i32> {\n        let n = opt?;\n        test_res_block(Ok(n))\n        //~^ return_and_then\n    }\n\n    fn test_ref_only() -> Option<i32> {\n        // ref: empty string\n        let x = Some(\"\")?;\n        if x.len() > 2 { Some(3) } else { None }\n        //~^ return_and_then\n    }\n\n    fn test_tmp_only() -> Option<i32> {\n        // unused temporary: vec![1, 2, 4]\n        let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) {\n            //~^ return_and_then\n            (a, _) if a.len() > 1 => a,\n            (_, b) => b,\n        })?;\n        if x.len() > 2 { Some(3) } else { None }\n    }\n\n    // should not lint\n    fn test_tmp_ref() -> Option<String> {\n        String::from(\"<BOOM>\")\n            .strip_prefix(\"<\")\n            .and_then(|s| s.strip_suffix(\">\").map(String::from))\n    }\n\n    // should not lint\n    fn test_unconsumed_tmp() -> Option<i32> {\n        [1, 2, 3]\n            .iter()\n            .map(|x| x + 1)\n            .collect::<Vec<_>>() // temporary Vec created here\n            .as_slice() // creates temporary slice\n            .first() // creates temporary reference\n            .and_then(|x| test_opt_block(Some(*x)))\n    }\n\n    fn in_closure() -> bool {\n        let _ = || {\n            let x = Some(\"\")?;\n            if x.len() > 2 { Some(3) } else { None }\n            //~^ return_and_then\n        };\n        true\n    }\n\n    fn with_return(shortcut: bool) -> Option<i32> {\n        if shortcut {\n            return {\n                let x = Some(\"\")?;\n                if x.len() > 2 { Some(3) } else { None }\n            };\n            //~^ return_and_then\n        };\n        None\n    }\n\n    fn with_return_multiline(shortcut: bool) -> Option<i32> {\n        if shortcut {\n            return {\n                let mut x = Some(\"\")?;\n                let x = format!(\"{x}.\");\n                if x.len() > 2 { Some(3) } else { None }\n            };\n            //~^^^^ return_and_then\n        };\n        None\n    }\n\n    #[expect(clippy::diverging_sub_expression)]\n    fn with_return_in_expression() -> Option<i32> {\n        _ = (\n            return {\n                let x = Some(\"\")?;\n                if x.len() > 2 { Some(3) } else { None }\n            },\n            //~^ return_and_then\n            10,\n        );\n    }\n\n    fn inside_if(a: bool, i: Option<u32>) -> Option<u32> {\n        if a {\n            let i = i?;\n            if i > 3 { Some(i) } else { None }\n            //~^ return_and_then\n        } else {\n            Some(42)\n        }\n    }\n\n    fn inside_match(a: u32, i: Option<u32>) -> Option<u32> {\n        match a {\n            1 | 2 => {\n                let i = i?;\n                if i > 3 { Some(i) } else { None }\n            },\n            //~^ return_and_then\n            3 | 4 => Some(42),\n            _ => None,\n        }\n    }\n\n    fn inside_match_and_block_and_if(a: u32, i: Option<u32>) -> Option<u32> {\n        match a {\n            1 | 2 => {\n                let a = a * 3;\n                if a.is_multiple_of(2) {\n                    let i = i?;\n                    if i > 3 { Some(i) } else { None }\n                    //~^ return_and_then\n                } else {\n                    Some(10)\n                }\n            },\n            3 | 4 => Some(42),\n            _ => None,\n        }\n    }\n\n    #[expect(clippy::never_loop)]\n    fn with_break(i: Option<u32>) -> Option<u32> {\n        match i {\n            Some(1) => loop {\n                break ({\n                    let i = i?;\n                    if i > 3 { Some(i) } else { None }\n                });\n                //~^ return_and_then\n            },\n            Some(2) => 'foo: loop {\n                loop {\n                    break 'foo ({\n                        let i = i?;\n                        if i > 3 { Some(i) } else { None }\n                    });\n                    //~^ return_and_then\n                }\n            },\n            Some(3) => 'bar: {\n                break 'bar ({\n                    let i = i?;\n                    if i > 3 { Some(i) } else { None }\n                });\n                //~^ return_and_then\n            },\n            Some(4) => 'baz: loop {\n                _ = loop {\n                    break i.and_then(|i| if i > 3 { Some(i) } else { None });\n                };\n            },\n            _ => None,\n        }\n    }\n}\n\nfn gen_option(n: i32) -> Option<i32> {\n    Some(n)\n}\n\nmod issue14781 {\n    fn foo(_: &str, _: (u32, u32)) -> Result<(u32, u32), ()> {\n        Ok((1, 1))\n    }\n\n    fn bug(_: Option<&str>) -> Result<(), ()> {\n        let year: Option<&str> = None;\n        let month: Option<&str> = None;\n        let day: Option<&str> = None;\n\n        let _day = if let (Some(year), Some(month)) = (year, month) {\n            day.and_then(|day| foo(day, (1, 31)).ok())\n        } else {\n            None\n        };\n\n        Ok(())\n    }\n}\n\nmod issue15111 {\n    #[derive(Debug)]\n    struct EvenOdd {\n        even: Option<u32>,\n        odd: Option<u32>,\n    }\n\n    impl EvenOdd {\n        fn new(i: Option<u32>) -> Self {\n            Self {\n                even: i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }),\n                odd: i.and_then(|i| if i.is_multiple_of(2) { None } else { Some(i) }),\n            }\n        }\n    }\n\n    fn with_if_let(i: Option<u32>) -> u32 {\n        if let Some(x) = i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }) {\n            x\n        } else {\n            std::hint::black_box(0)\n        }\n    }\n\n    fn main() {\n        let _ = EvenOdd::new(Some(2));\n    }\n}\n\nmod issue14927 {\n    use std::path::Path;\n    struct A {\n        pub func: fn(check: bool, a: &Path, b: Option<&Path>),\n    }\n    const MY_A: A = A {\n        func: |check, a, b| {\n            if check {\n                let _ = ();\n            } else if let Some(parent) = b.and_then(|p| p.parent()) {\n                let _ = ();\n            }\n        },\n    };\n}\n"
  },
  {
    "path": "tests/ui/return_and_then.rs",
    "content": "#![warn(clippy::return_and_then)]\n\nfn main() {\n    fn test_opt_block(opt: Option<i32>) -> Option<i32> {\n        opt.and_then(|n| {\n            //~^ return_and_then\n            let mut ret = n + 1;\n            ret += n;\n            if n > 1 { Some(ret) } else { None }\n        })\n    }\n\n    fn test_opt_func(opt: Option<i32>) -> Option<i32> {\n        opt.and_then(|n| test_opt_block(Some(n)))\n        //~^ return_and_then\n    }\n\n    fn test_call_chain() -> Option<i32> {\n        gen_option(1).and_then(|n| test_opt_block(Some(n)))\n        //~^ return_and_then\n    }\n\n    fn test_res_block(opt: Result<i32, i32>) -> Result<i32, i32> {\n        opt.and_then(|n| if n > 1 { Ok(n + 1) } else { Err(n) })\n        //~^ return_and_then\n    }\n\n    fn test_res_func(opt: Result<i32, i32>) -> Result<i32, i32> {\n        opt.and_then(|n| test_res_block(Ok(n)))\n        //~^ return_and_then\n    }\n\n    fn test_ref_only() -> Option<i32> {\n        // ref: empty string\n        Some(\"\").and_then(|x| if x.len() > 2 { Some(3) } else { None })\n        //~^ return_and_then\n    }\n\n    fn test_tmp_only() -> Option<i32> {\n        // unused temporary: vec![1, 2, 4]\n        Some(match (vec![1, 2, 3], vec![1, 2, 4]) {\n            //~^ return_and_then\n            (a, _) if a.len() > 1 => a,\n            (_, b) => b,\n        })\n        .and_then(|x| if x.len() > 2 { Some(3) } else { None })\n    }\n\n    // should not lint\n    fn test_tmp_ref() -> Option<String> {\n        String::from(\"<BOOM>\")\n            .strip_prefix(\"<\")\n            .and_then(|s| s.strip_suffix(\">\").map(String::from))\n    }\n\n    // should not lint\n    fn test_unconsumed_tmp() -> Option<i32> {\n        [1, 2, 3]\n            .iter()\n            .map(|x| x + 1)\n            .collect::<Vec<_>>() // temporary Vec created here\n            .as_slice() // creates temporary slice\n            .first() // creates temporary reference\n            .and_then(|x| test_opt_block(Some(*x)))\n    }\n\n    fn in_closure() -> bool {\n        let _ = || {\n            Some(\"\").and_then(|x| if x.len() > 2 { Some(3) } else { None })\n            //~^ return_and_then\n        };\n        true\n    }\n\n    fn with_return(shortcut: bool) -> Option<i32> {\n        if shortcut {\n            return Some(\"\").and_then(|x| if x.len() > 2 { Some(3) } else { None });\n            //~^ return_and_then\n        };\n        None\n    }\n\n    fn with_return_multiline(shortcut: bool) -> Option<i32> {\n        if shortcut {\n            return Some(\"\").and_then(|mut x| {\n                let x = format!(\"{x}.\");\n                if x.len() > 2 { Some(3) } else { None }\n            });\n            //~^^^^ return_and_then\n        };\n        None\n    }\n\n    #[expect(clippy::diverging_sub_expression)]\n    fn with_return_in_expression() -> Option<i32> {\n        _ = (\n            return Some(\"\").and_then(|x| if x.len() > 2 { Some(3) } else { None }),\n            //~^ return_and_then\n            10,\n        );\n    }\n\n    fn inside_if(a: bool, i: Option<u32>) -> Option<u32> {\n        if a {\n            i.and_then(|i| if i > 3 { Some(i) } else { None })\n            //~^ return_and_then\n        } else {\n            Some(42)\n        }\n    }\n\n    fn inside_match(a: u32, i: Option<u32>) -> Option<u32> {\n        match a {\n            1 | 2 => i.and_then(|i| if i > 3 { Some(i) } else { None }),\n            //~^ return_and_then\n            3 | 4 => Some(42),\n            _ => None,\n        }\n    }\n\n    fn inside_match_and_block_and_if(a: u32, i: Option<u32>) -> Option<u32> {\n        match a {\n            1 | 2 => {\n                let a = a * 3;\n                if a.is_multiple_of(2) {\n                    i.and_then(|i| if i > 3 { Some(i) } else { None })\n                    //~^ return_and_then\n                } else {\n                    Some(10)\n                }\n            },\n            3 | 4 => Some(42),\n            _ => None,\n        }\n    }\n\n    #[expect(clippy::never_loop)]\n    fn with_break(i: Option<u32>) -> Option<u32> {\n        match i {\n            Some(1) => loop {\n                break i.and_then(|i| if i > 3 { Some(i) } else { None });\n                //~^ return_and_then\n            },\n            Some(2) => 'foo: loop {\n                loop {\n                    break 'foo i.and_then(|i| if i > 3 { Some(i) } else { None });\n                    //~^ return_and_then\n                }\n            },\n            Some(3) => 'bar: {\n                break 'bar i.and_then(|i| if i > 3 { Some(i) } else { None });\n                //~^ return_and_then\n            },\n            Some(4) => 'baz: loop {\n                _ = loop {\n                    break i.and_then(|i| if i > 3 { Some(i) } else { None });\n                };\n            },\n            _ => None,\n        }\n    }\n}\n\nfn gen_option(n: i32) -> Option<i32> {\n    Some(n)\n}\n\nmod issue14781 {\n    fn foo(_: &str, _: (u32, u32)) -> Result<(u32, u32), ()> {\n        Ok((1, 1))\n    }\n\n    fn bug(_: Option<&str>) -> Result<(), ()> {\n        let year: Option<&str> = None;\n        let month: Option<&str> = None;\n        let day: Option<&str> = None;\n\n        let _day = if let (Some(year), Some(month)) = (year, month) {\n            day.and_then(|day| foo(day, (1, 31)).ok())\n        } else {\n            None\n        };\n\n        Ok(())\n    }\n}\n\nmod issue15111 {\n    #[derive(Debug)]\n    struct EvenOdd {\n        even: Option<u32>,\n        odd: Option<u32>,\n    }\n\n    impl EvenOdd {\n        fn new(i: Option<u32>) -> Self {\n            Self {\n                even: i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }),\n                odd: i.and_then(|i| if i.is_multiple_of(2) { None } else { Some(i) }),\n            }\n        }\n    }\n\n    fn with_if_let(i: Option<u32>) -> u32 {\n        if let Some(x) = i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }) {\n            x\n        } else {\n            std::hint::black_box(0)\n        }\n    }\n\n    fn main() {\n        let _ = EvenOdd::new(Some(2));\n    }\n}\n\nmod issue14927 {\n    use std::path::Path;\n    struct A {\n        pub func: fn(check: bool, a: &Path, b: Option<&Path>),\n    }\n    const MY_A: A = A {\n        func: |check, a, b| {\n            if check {\n                let _ = ();\n            } else if let Some(parent) = b.and_then(|p| p.parent()) {\n                let _ = ();\n            }\n        },\n    };\n}\n"
  },
  {
    "path": "tests/ui/return_and_then.stderr",
    "content": "error: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:5:9\n   |\nLL | /         opt.and_then(|n| {\nLL | |\nLL | |             let mut ret = n + 1;\nLL | |             ret += n;\nLL | |             if n > 1 { Some(ret) } else { None }\nLL | |         })\n   | |__________^\n   |\n   = note: `-D clippy::return-and-then` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::return_and_then)]`\nhelp: try\n   |\nLL ~         let n = opt?;\nLL +\nLL +         let mut ret = n + 1;\nLL +         ret += n;\nLL +         if n > 1 { Some(ret) } else { None }\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:14:9\n   |\nLL |         opt.and_then(|n| test_opt_block(Some(n)))\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~         let n = opt?;\nLL +         test_opt_block(Some(n))\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:19:9\n   |\nLL |         gen_option(1).and_then(|n| test_opt_block(Some(n)))\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~         let n = gen_option(1)?;\nLL +         test_opt_block(Some(n))\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:24:9\n   |\nLL |         opt.and_then(|n| if n > 1 { Ok(n + 1) } else { Err(n) })\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~         let n = opt?;\nLL +         if n > 1 { Ok(n + 1) } else { Err(n) }\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:29:9\n   |\nLL |         opt.and_then(|n| test_res_block(Ok(n)))\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~         let n = opt?;\nLL +         test_res_block(Ok(n))\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:35:9\n   |\nLL |         Some(\"\").and_then(|x| if x.len() > 2 { Some(3) } else { None })\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~         let x = Some(\"\")?;\nLL +         if x.len() > 2 { Some(3) } else { None }\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:41:9\n   |\nLL | /         Some(match (vec![1, 2, 3], vec![1, 2, 4]) {\nLL | |\nLL | |             (a, _) if a.len() > 1 => a,\nLL | |             (_, b) => b,\nLL | |         })\nLL | |         .and_then(|x| if x.len() > 2 { Some(3) } else { None })\n   | |_______________________________________________________________^\n   |\nhelp: try\n   |\nLL ~         let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) {\nLL +\nLL +             (a, _) if a.len() > 1 => a,\nLL +             (_, b) => b,\nLL +         })?;\nLL +         if x.len() > 2 { Some(3) } else { None }\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:69:13\n   |\nLL |             Some(\"\").and_then(|x| if x.len() > 2 { Some(3) } else { None })\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~             let x = Some(\"\")?;\nLL +             if x.len() > 2 { Some(3) } else { None }\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:77:20\n   |\nLL |             return Some(\"\").and_then(|x| if x.len() > 2 { Some(3) } else { None });\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~             return {\nLL +                 let x = Some(\"\")?;\nLL +                 if x.len() > 2 { Some(3) } else { None }\nLL ~             };\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:85:20\n   |\nLL |               return Some(\"\").and_then(|mut x| {\n   |  ____________________^\nLL | |                 let x = format!(\"{x}.\");\nLL | |                 if x.len() > 2 { Some(3) } else { None }\nLL | |             });\n   | |______________^\n   |\nhelp: try\n   |\nLL ~             return {\nLL +                 let mut x = Some(\"\")?;\nLL +                 let x = format!(\"{x}.\");\nLL +                 if x.len() > 2 { Some(3) } else { None }\nLL ~             };\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:97:20\n   |\nLL |             return Some(\"\").and_then(|x| if x.len() > 2 { Some(3) } else { None }),\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~             return {\nLL +                 let x = Some(\"\")?;\nLL +                 if x.len() > 2 { Some(3) } else { None }\nLL ~             },\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:105:13\n   |\nLL |             i.and_then(|i| if i > 3 { Some(i) } else { None })\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~             let i = i?;\nLL +             if i > 3 { Some(i) } else { None }\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:114:22\n   |\nLL |             1 | 2 => i.and_then(|i| if i > 3 { Some(i) } else { None }),\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~             1 | 2 => {\nLL +                 let i = i?;\nLL +                 if i > 3 { Some(i) } else { None }\nLL ~             },\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:126:21\n   |\nLL |                     i.and_then(|i| if i > 3 { Some(i) } else { None })\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~                     let i = i?;\nLL +                     if i > 3 { Some(i) } else { None }\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:141:23\n   |\nLL |                 break i.and_then(|i| if i > 3 { Some(i) } else { None });\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~                 break ({\nLL +                     let i = i?;\nLL +                     if i > 3 { Some(i) } else { None }\nLL ~                 });\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:146:32\n   |\nLL |                     break 'foo i.and_then(|i| if i > 3 { Some(i) } else { None });\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~                     break 'foo ({\nLL +                         let i = i?;\nLL +                         if i > 3 { Some(i) } else { None }\nLL ~                     });\n   |\n\nerror: use the `?` operator instead of an `and_then` call\n  --> tests/ui/return_and_then.rs:151:28\n   |\nLL |                 break 'bar i.and_then(|i| if i > 3 { Some(i) } else { None });\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL ~                 break 'bar ({\nLL +                     let i = i?;\nLL +                     if i > 3 { Some(i) } else { None }\nLL ~                 });\n   |\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/return_self_not_must_use.rs",
    "content": "#![crate_type = \"lib\"]\n#![warn(clippy::return_self_not_must_use)]\n\n#[derive(Clone)]\npub struct Bar;\n\npub trait Whatever {\n    fn what(&self) -> Self;\n    //~^ return_self_not_must_use\n\n    // There should be no warning here! (returns a reference)\n    fn what2(&self) -> &Self;\n}\n\nimpl Bar {\n    // There should be no warning here! (note taking a self argument)\n    pub fn not_new() -> Self {\n        Self\n    }\n    pub fn foo(&self) -> Self {\n        //~^ return_self_not_must_use\n\n        Self\n    }\n    pub fn bar(self) -> Self {\n        //~^ return_self_not_must_use\n\n        self\n    }\n    // There should be no warning here! (private method)\n    fn foo2(&self) -> Self {\n        Self\n    }\n    // There should be no warning here! (returns a reference)\n    pub fn foo3(&self) -> &Self {\n        self\n    }\n    // There should be no warning here! (already a `must_use` attribute)\n    #[must_use]\n    pub fn foo4(&self) -> Self {\n        Self\n    }\n}\n\nimpl Whatever for Bar {\n    // There should be no warning here! (comes from the trait)\n    fn what(&self) -> Self {\n        self.foo2()\n    }\n    // There should be no warning here! (comes from the trait)\n    fn what2(&self) -> &Self {\n        self\n    }\n}\n\n#[must_use]\npub struct Foo;\n\nimpl Foo {\n    // There should be no warning here! (`Foo` already implements `#[must_use]`)\n    fn foo(&self) -> Self {\n        Self\n    }\n}\n"
  },
  {
    "path": "tests/ui/return_self_not_must_use.stderr",
    "content": "error: missing `#[must_use]` attribute on a method returning `Self`\n  --> tests/ui/return_self_not_must_use.rs:8:5\n   |\nLL |     fn what(&self) -> Self;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type\n   = note: `-D clippy::return-self-not-must-use` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::return_self_not_must_use)]`\n\nerror: missing `#[must_use]` attribute on a method returning `Self`\n  --> tests/ui/return_self_not_must_use.rs:20:5\n   |\nLL | /     pub fn foo(&self) -> Self {\nLL | |\nLL | |\nLL | |         Self\nLL | |     }\n   | |_____^\n   |\n   = help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type\n\nerror: missing `#[must_use]` attribute on a method returning `Self`\n  --> tests/ui/return_self_not_must_use.rs:25:5\n   |\nLL | /     pub fn bar(self) -> Self {\nLL | |\nLL | |\nLL | |         self\nLL | |     }\n   | |_____^\n   |\n   = help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_fixable.fixed",
    "content": "#![warn(clippy::reversed_empty_ranges)]\n#![allow(clippy::uninlined_format_args)]\n\nconst ANSWER: i32 = 42;\n\nfn main() {\n    // These should be linted:\n\n    ((21..=42).rev()).for_each(|x| println!(\"{}\", x));\n    //~^ reversed_empty_ranges\n    let _ = ((21..ANSWER).rev()).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();\n    //~^ reversed_empty_ranges\n\n    for _ in (-42..=-21).rev() {}\n    //~^ reversed_empty_ranges\n    for _ in (21u32..42u32).rev() {}\n    //~^ reversed_empty_ranges\n\n    // These should be ignored as they are not empty ranges:\n\n    (21..=42).for_each(|x| println!(\"{}\", x));\n    (21..42).for_each(|x| println!(\"{}\", x));\n\n    let arr = [1, 2, 3, 4, 5];\n    let _ = &arr[1..=3];\n    let _ = &arr[1..3];\n\n    for _ in 21..=42 {}\n    for _ in 21..42 {}\n\n    // This range is empty but should be ignored, see issue #5689\n    let _ = &arr[0..0];\n}\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_fixable.rs",
    "content": "#![warn(clippy::reversed_empty_ranges)]\n#![allow(clippy::uninlined_format_args)]\n\nconst ANSWER: i32 = 42;\n\nfn main() {\n    // These should be linted:\n\n    (42..=21).for_each(|x| println!(\"{}\", x));\n    //~^ reversed_empty_ranges\n    let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();\n    //~^ reversed_empty_ranges\n\n    for _ in -21..=-42 {}\n    //~^ reversed_empty_ranges\n    for _ in 42u32..21u32 {}\n    //~^ reversed_empty_ranges\n\n    // These should be ignored as they are not empty ranges:\n\n    (21..=42).for_each(|x| println!(\"{}\", x));\n    (21..42).for_each(|x| println!(\"{}\", x));\n\n    let arr = [1, 2, 3, 4, 5];\n    let _ = &arr[1..=3];\n    let _ = &arr[1..3];\n\n    for _ in 21..=42 {}\n    for _ in 21..42 {}\n\n    // This range is empty but should be ignored, see issue #5689\n    let _ = &arr[0..0];\n}\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_fixable.stderr",
    "content": "error: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_fixable.rs:9:6\n   |\nLL |     (42..=21).for_each(|x| println!(\"{}\", x));\n   |      ^^^^^^^\n   |\n   = note: `-D clippy::reversed-empty-ranges` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     (42..=21).for_each(|x| println!(\"{}\", x));\nLL +     ((21..=42).rev()).for_each(|x| println!(\"{}\", x));\n   |\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_fixable.rs:11:14\n   |\nLL |     let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();\n   |              ^^^^^^^^^^\n   |\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();\nLL +     let _ = ((21..ANSWER).rev()).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();\n   |\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_fixable.rs:14:14\n   |\nLL |     for _ in -21..=-42 {}\n   |              ^^^^^^^^^\n   |\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     for _ in -21..=-42 {}\nLL +     for _ in (-42..=-21).rev() {}\n   |\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_fixable.rs:16:14\n   |\nLL |     for _ in 42u32..21u32 {}\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     for _ in 42u32..21u32 {}\nLL +     for _ in (21u32..42u32).rev() {}\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_loops_fixable.fixed",
    "content": "#![warn(clippy::reversed_empty_ranges)]\n#![allow(clippy::uninlined_format_args)]\n\nfn main() {\n    const MAX_LEN: usize = 42;\n\n    for i in (0..10).rev() {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in (0..=10).rev() {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in (0..MAX_LEN).rev() {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in 5..=5 {\n        // not an error, this is the range with only one element “5”\n        println!(\"{}\", i);\n    }\n\n    for i in 0..10 {\n        // not an error, the start index is less than the end index\n        println!(\"{}\", i);\n    }\n\n    for i in -10..0 {\n        // not an error\n        println!(\"{}\", i);\n    }\n\n    for i in ((0..10).rev()).map(|x| x * 2) {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    // testing that the empty range lint folds constants\n    for i in (5 + 4..10).rev() {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in ((3 - 1)..(5 + 2)).rev() {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in (2 * 2)..(2 * 3) {\n        // no error, 4..6 is fine\n        println!(\"{}\", i);\n    }\n\n    let x = 42;\n    for i in x..10 {\n        // no error, not constant-foldable\n        println!(\"{}\", i);\n    }\n}\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_loops_fixable.rs",
    "content": "#![warn(clippy::reversed_empty_ranges)]\n#![allow(clippy::uninlined_format_args)]\n\nfn main() {\n    const MAX_LEN: usize = 42;\n\n    for i in 10..0 {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in 10..=0 {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in MAX_LEN..0 {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in 5..=5 {\n        // not an error, this is the range with only one element “5”\n        println!(\"{}\", i);\n    }\n\n    for i in 0..10 {\n        // not an error, the start index is less than the end index\n        println!(\"{}\", i);\n    }\n\n    for i in -10..0 {\n        // not an error\n        println!(\"{}\", i);\n    }\n\n    for i in (10..0).map(|x| x * 2) {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    // testing that the empty range lint folds constants\n    for i in 10..5 + 4 {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in (5 + 2)..(3 - 1) {\n        //~^ reversed_empty_ranges\n        println!(\"{}\", i);\n    }\n\n    for i in (2 * 2)..(2 * 3) {\n        // no error, 4..6 is fine\n        println!(\"{}\", i);\n    }\n\n    let x = 42;\n    for i in x..10 {\n        // no error, not constant-foldable\n        println!(\"{}\", i);\n    }\n}\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_loops_fixable.stderr",
    "content": "error: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_loops_fixable.rs:7:14\n   |\nLL |     for i in 10..0 {\n   |              ^^^^^\n   |\n   = note: `-D clippy::reversed-empty-ranges` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     for i in 10..0 {\nLL +     for i in (0..10).rev() {\n   |\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_loops_fixable.rs:12:14\n   |\nLL |     for i in 10..=0 {\n   |              ^^^^^^\n   |\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     for i in 10..=0 {\nLL +     for i in (0..=10).rev() {\n   |\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_loops_fixable.rs:17:14\n   |\nLL |     for i in MAX_LEN..0 {\n   |              ^^^^^^^^^^\n   |\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     for i in MAX_LEN..0 {\nLL +     for i in (0..MAX_LEN).rev() {\n   |\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_loops_fixable.rs:37:15\n   |\nLL |     for i in (10..0).map(|x| x * 2) {\n   |               ^^^^^\n   |\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     for i in (10..0).map(|x| x * 2) {\nLL +     for i in ((0..10).rev()).map(|x| x * 2) {\n   |\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_loops_fixable.rs:43:14\n   |\nLL |     for i in 10..5 + 4 {\n   |              ^^^^^^^^^\n   |\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     for i in 10..5 + 4 {\nLL +     for i in (5 + 4..10).rev() {\n   |\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_loops_fixable.rs:48:14\n   |\nLL |     for i in (5 + 2)..(3 - 1) {\n   |              ^^^^^^^^^^^^^^^^\n   |\nhelp: consider using the following if you are attempting to iterate over this range in reverse\n   |\nLL -     for i in (5 + 2)..(3 - 1) {\nLL +     for i in ((3 - 1)..(5 + 2)).rev() {\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_loops_unfixable.rs",
    "content": "#![warn(clippy::reversed_empty_ranges)]\n#![allow(clippy::uninlined_format_args)]\n\nfn main() {\n    for i in 5..5 {\n        //~^ reversed_empty_ranges\n\n        println!(\"{}\", i);\n    }\n\n    for i in (5 + 2)..(8 - 1) {\n        //~^ reversed_empty_ranges\n\n        println!(\"{}\", i);\n    }\n}\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_loops_unfixable.stderr",
    "content": "error: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_loops_unfixable.rs:5:14\n   |\nLL |     for i in 5..5 {\n   |              ^^^^\n   |\n   = note: `-D clippy::reversed-empty-ranges` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_loops_unfixable.rs:11:14\n   |\nLL |     for i in (5 + 2)..(8 - 1) {\n   |              ^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_unfixable.rs",
    "content": "#![warn(clippy::reversed_empty_ranges)]\n\nconst ANSWER: i32 = 42;\nconst SOME_NUM: usize = 3;\n\nfn main() {\n    let arr = [1, 2, 3, 4, 5];\n    let _ = &arr[3usize..=1usize];\n    //~^ reversed_empty_ranges\n\n    let _ = &arr[SOME_NUM..1];\n    //~^ reversed_empty_ranges\n\n    for _ in ANSWER..ANSWER {}\n    //~^ reversed_empty_ranges\n\n    // Should not be linted, see issue #5689\n    let _ = (42 + 10..42 + 10).map(|x| x / 2).find(|&x| x == 21);\n}\n"
  },
  {
    "path": "tests/ui/reversed_empty_ranges_unfixable.stderr",
    "content": "error: this range is reversed and using it to index a slice will panic at run-time\n  --> tests/ui/reversed_empty_ranges_unfixable.rs:8:18\n   |\nLL |     let _ = &arr[3usize..=1usize];\n   |                  ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::reversed-empty-ranges` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`\n\nerror: this range is reversed and using it to index a slice will panic at run-time\n  --> tests/ui/reversed_empty_ranges_unfixable.rs:11:18\n   |\nLL |     let _ = &arr[SOME_NUM..1];\n   |                  ^^^^^^^^^^^\n\nerror: this range is empty so it will yield no values\n  --> tests/ui/reversed_empty_ranges_unfixable.rs:14:14\n   |\nLL |     for _ in ANSWER..ANSWER {}\n   |              ^^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/same_functions_in_if_condition.rs",
    "content": "#![feature(adt_const_params)]\n#![deny(clippy::same_functions_in_if_condition)]\n// ifs_same_cond warning is different from `ifs_same_cond`.\n// clippy::if_same_then_else, clippy::comparison_chain -- all empty blocks\n#![allow(incomplete_features)]\n#![allow(clippy::if_same_then_else, clippy::ifs_same_cond, clippy::uninlined_format_args)]\n\nuse std::marker::ConstParamTy;\n\nfn function() -> bool {\n    true\n}\n\nfn fn_arg(_arg: u8) -> bool {\n    true\n}\n\nstruct Struct;\n\nimpl Struct {\n    fn method(&self) -> bool {\n        true\n    }\n    fn method_arg(&self, _arg: u8) -> bool {\n        true\n    }\n}\n\nfn ifs_same_cond_fn() {\n    let a = 0;\n    let obj = Struct;\n\n    if function() {\n        //~^ same_functions_in_if_condition\n    } else if function() {\n    }\n\n    if fn_arg(a) {\n        //~^ same_functions_in_if_condition\n    } else if fn_arg(a) {\n    }\n\n    if obj.method() {\n        //~^ same_functions_in_if_condition\n    } else if obj.method() {\n    }\n\n    if obj.method_arg(a) {\n        //~^ same_functions_in_if_condition\n    } else if obj.method_arg(a) {\n    }\n\n    let mut v = vec![1];\n    if v.pop().is_none() {\n        //~^ same_functions_in_if_condition\n    } else if v.pop().is_none() {\n    }\n\n    if v.len() == 42 {\n        //~^ same_functions_in_if_condition\n    } else if v.len() == 42 {\n    }\n\n    if v.len() == 1 {\n        // ok, different conditions\n    } else if v.len() == 2 {\n    }\n\n    if fn_arg(0) {\n        // ok, different arguments.\n    } else if fn_arg(1) {\n    }\n\n    if obj.method_arg(0) {\n        // ok, different arguments.\n    } else if obj.method_arg(1) {\n    }\n\n    if a == 1 {\n        // ok, warning is on `ifs_same_cond` behalf.\n    } else if a == 1 {\n    }\n}\n\nfn main() {\n    // macro as condition (see #6168)\n    let os = if cfg!(target_os = \"macos\") {\n        \"macos\"\n    } else if cfg!(target_os = \"windows\") {\n        \"windows\"\n    } else {\n        \"linux\"\n    };\n    println!(\"{}\", os);\n\n    #[derive(PartialEq, Eq, ConstParamTy)]\n    enum E {\n        A,\n        B,\n    }\n    fn generic<const P: E>() -> bool {\n        match P {\n            E::A => true,\n            E::B => false,\n        }\n    }\n    if generic::<{ E::A }>() {\n        println!(\"A\");\n    } else if generic::<{ E::B }>() {\n        println!(\"B\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/same_functions_in_if_condition.stderr",
    "content": "error: these `if` branches have the same function call\n  --> tests/ui/same_functions_in_if_condition.rs:33:8\n   |\nLL |     if function() {\n   |        ^^^^^^^^^^\nLL |\nLL |     } else if function() {\n   |               ^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/same_functions_in_if_condition.rs:2:9\n   |\nLL | #![deny(clippy::same_functions_in_if_condition)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: these `if` branches have the same function call\n  --> tests/ui/same_functions_in_if_condition.rs:38:8\n   |\nLL |     if fn_arg(a) {\n   |        ^^^^^^^^^\nLL |\nLL |     } else if fn_arg(a) {\n   |               ^^^^^^^^^\n\nerror: these `if` branches have the same function call\n  --> tests/ui/same_functions_in_if_condition.rs:43:8\n   |\nLL |     if obj.method() {\n   |        ^^^^^^^^^^^^\nLL |\nLL |     } else if obj.method() {\n   |               ^^^^^^^^^^^^\n\nerror: these `if` branches have the same function call\n  --> tests/ui/same_functions_in_if_condition.rs:48:8\n   |\nLL |     if obj.method_arg(a) {\n   |        ^^^^^^^^^^^^^^^^^\nLL |\nLL |     } else if obj.method_arg(a) {\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: these `if` branches have the same function call\n  --> tests/ui/same_functions_in_if_condition.rs:54:8\n   |\nLL |     if v.pop().is_none() {\n   |        ^^^^^^^^^^^^^^^^^\nLL |\nLL |     } else if v.pop().is_none() {\n   |               ^^^^^^^^^^^^^^^^^\n\nerror: these `if` branches have the same function call\n  --> tests/ui/same_functions_in_if_condition.rs:59:8\n   |\nLL |     if v.len() == 42 {\n   |        ^^^^^^^^^^^^^\nLL |\nLL |     } else if v.len() == 42 {\n   |               ^^^^^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/same_item_push.rs",
    "content": "#![warn(clippy::same_item_push)]\n\nconst VALUE: u8 = 7;\n\nfn mutate_increment(x: &mut u8) -> u8 {\n    *x += 1;\n    *x\n}\n\nfn increment(x: u8) -> u8 {\n    x + 1\n}\n\nfn fun() -> usize {\n    42\n}\n\nfn main() {\n    // ** linted cases **\n    let mut vec: Vec<u8> = Vec::new();\n    let item = 2;\n    for _ in 5..=20 {\n        vec.push(item);\n        //~^ same_item_push\n    }\n\n    let mut vec: Vec<u8> = Vec::new();\n    for _ in 0..15 {\n        let item = 2;\n        vec.push(item);\n        //~^ same_item_push\n    }\n\n    let mut vec: Vec<u8> = Vec::new();\n    for _ in 0..15 {\n        vec.push(13);\n        //~^ same_item_push\n    }\n\n    let mut vec = Vec::new();\n    for _ in 0..20 {\n        vec.push(VALUE);\n        //~^ same_item_push\n    }\n\n    let mut vec = Vec::new();\n    let item = VALUE;\n    for _ in 0..20 {\n        vec.push(item);\n        //~^ same_item_push\n    }\n\n    #[clippy::msrv = \"1.81\"]\n    fn older_msrv() {\n        let mut vec = Vec::new();\n        let item = VALUE;\n        for _ in 0..20 {\n            vec.push(item);\n            //~^ same_item_push\n        }\n    }\n\n    // ** non-linted cases **\n    let mut spaces = Vec::with_capacity(10);\n    for _ in 0..10 {\n        spaces.push(vec![b' ']);\n    }\n\n    // Suggestion should not be given as pushed variable can mutate\n    let mut vec: Vec<u8> = Vec::new();\n    let mut item: u8 = 2;\n    for _ in 0..30 {\n        vec.push(mutate_increment(&mut item));\n    }\n\n    let mut vec: Vec<u8> = Vec::new();\n    let mut item: u8 = 2;\n    let mut item2 = &mut mutate_increment(&mut item);\n    for _ in 0..30 {\n        vec.push(mutate_increment(item2));\n    }\n\n    let mut vec: Vec<usize> = Vec::new();\n    for (a, b) in [0, 1, 4, 9, 16].iter().enumerate() {\n        vec.push(a);\n    }\n\n    let mut vec: Vec<u8> = Vec::new();\n    for i in 0..30 {\n        vec.push(increment(i));\n    }\n\n    let mut vec: Vec<u8> = Vec::new();\n    for i in 0..30 {\n        vec.push(i + i * i);\n    }\n\n    // Suggestion should not be given as there are multiple pushes that are not the same\n    let mut vec: Vec<u8> = Vec::new();\n    let item: u8 = 2;\n    for _ in 0..30 {\n        vec.push(item);\n        vec.push(item * 2);\n    }\n\n    // Suggestion should not be given as Vec is not involved\n    for _ in 0..5 {\n        println!(\"Same Item Push\");\n    }\n\n    struct A {\n        kind: u32,\n    }\n    let mut vec_a: Vec<A> = Vec::new();\n    for i in 0..30 {\n        vec_a.push(A { kind: i });\n    }\n    let mut vec: Vec<u8> = Vec::new();\n    for a in vec_a {\n        vec.push(2u8.pow(a.kind));\n    }\n\n    // Fix #5902\n    let mut vec: Vec<u8> = Vec::new();\n    let mut item = 0;\n    for _ in 0..10 {\n        vec.push(item);\n        item += 10;\n    }\n\n    // Fix #5979\n    let mut vec: Vec<std::fs::File> = Vec::new();\n    for _ in 0..10 {\n        vec.push(std::fs::File::open(\"foobar\").unwrap());\n    }\n    // Fix #5979\n    #[derive(Clone)]\n    struct S;\n\n    trait T {}\n    impl T for S {}\n\n    let mut vec: Vec<Box<dyn T>> = Vec::new();\n    for _ in 0..10 {\n        vec.push(Box::new(S {}));\n    }\n\n    // Fix #5985\n    let mut vec = Vec::new();\n    let item = 42;\n    let item = fun();\n    for _ in 0..20 {\n        vec.push(item);\n    }\n\n    // Fix #5985\n    let mut vec = Vec::new();\n    let key = 1;\n    for _ in 0..20 {\n        let item = match key {\n            1 => 10,\n            _ => 0,\n        };\n        vec.push(item);\n    }\n\n    // Fix #6987\n    let mut vec = Vec::new();\n    #[allow(clippy::needless_borrow)]\n    for _ in 0..10 {\n        vec.push(1);\n        vec.extend(&[2]);\n    }\n}\n"
  },
  {
    "path": "tests/ui/same_item_push.stderr",
    "content": "error: it looks like the same item is being pushed into this `Vec`\n  --> tests/ui/same_item_push.rs:23:9\n   |\nLL |         vec.push(item);\n   |         ^^^\n   |\n   = help: consider using `vec![item;SIZE]`\n   = help: or `vec.extend(std::iter::repeat_n(item, SIZE))`\n   = note: `-D clippy::same-item-push` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::same_item_push)]`\n\nerror: it looks like the same item is being pushed into this `Vec`\n  --> tests/ui/same_item_push.rs:30:9\n   |\nLL |         vec.push(item);\n   |         ^^^\n   |\n   = help: consider using `vec![item;SIZE]`\n   = help: or `vec.extend(std::iter::repeat_n(item, SIZE))`\n\nerror: it looks like the same item is being pushed into this `Vec`\n  --> tests/ui/same_item_push.rs:36:9\n   |\nLL |         vec.push(13);\n   |         ^^^\n   |\n   = help: consider using `vec![13;SIZE]`\n   = help: or `vec.extend(std::iter::repeat_n(13, SIZE))`\n\nerror: it looks like the same item is being pushed into this `Vec`\n  --> tests/ui/same_item_push.rs:42:9\n   |\nLL |         vec.push(VALUE);\n   |         ^^^\n   |\n   = help: consider using `vec![VALUE;SIZE]`\n   = help: or `vec.extend(std::iter::repeat_n(VALUE, SIZE))`\n\nerror: it looks like the same item is being pushed into this `Vec`\n  --> tests/ui/same_item_push.rs:49:9\n   |\nLL |         vec.push(item);\n   |         ^^^\n   |\n   = help: consider using `vec![item;SIZE]`\n   = help: or `vec.extend(std::iter::repeat_n(item, SIZE))`\n\nerror: it looks like the same item is being pushed into this `Vec`\n  --> tests/ui/same_item_push.rs:58:13\n   |\nLL |             vec.push(item);\n   |             ^^^\n   |\n   = help: consider using `vec![item;SIZE]`\n   = help: or `vec.resize(NEW_SIZE, item)`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/same_length_and_capacity.rs",
    "content": "#![warn(clippy::same_length_and_capacity)]\n\nfn main() {\n    let mut my_vec: Vec<i32> = Vec::with_capacity(20);\n    my_vec.extend([1, 2, 3, 4, 5]);\n    let (ptr, mut len, cap) = my_vec.into_raw_parts();\n    len = 8;\n\n    let _reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, len) };\n    //~^ same_length_and_capacity\n\n    // Don't want to lint different expressions for len and cap\n    let _properly_reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, cap) };\n\n    // Don't want to lint if len and cap are distinct variables but happen to be equal\n    let len_from_cap = cap;\n    let _another_properly_reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len_from_cap, cap) };\n\n    let my_string = String::from(\"hello\");\n    let (string_ptr, string_len, string_cap) = my_string.into_raw_parts();\n\n    let _reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_len) };\n    //~^ same_length_and_capacity\n\n    // Don't want to lint different expressions for len and cap\n    let _properly_reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_cap) };\n}\n"
  },
  {
    "path": "tests/ui/same_length_and_capacity.stderr",
    "content": "error: usage of `Vec::from_raw_parts` with the same expression for length and capacity\n  --> tests/ui/same_length_and_capacity.rs:9:39\n   |\nLL |     let _reconstructed_vec = unsafe { Vec::from_raw_parts(ptr, len, len) };\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try `Box::from(slice::from_raw_parts(...)).into::<Vec<_>>()`\n   = note: `-D clippy::same-length-and-capacity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::same_length_and_capacity)]`\n\nerror: usage of `String::from_raw_parts` with the same expression for length and capacity\n  --> tests/ui/same_length_and_capacity.rs:22:42\n   |\nLL |     let _reconstructed_string = unsafe { String::from_raw_parts(string_ptr, string_len, string_len) };\n   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try `String::from(str::from_utf8_unchecked(slice::from_raw_parts(...)))`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/same_name_method.rs",
    "content": "#![warn(clippy::same_name_method)]\n#![allow(dead_code, non_camel_case_types)]\n\ntrait T1 {\n    fn foo() {}\n}\n\ntrait T2 {\n    fn foo() {}\n}\n\nmod should_lint {\n\n    mod test_basic_case {\n        use crate::T1;\n\n        struct S;\n\n        impl S {\n            fn foo() {}\n            //~^ same_name_method\n        }\n\n        impl T1 for S {\n            fn foo() {}\n        }\n    }\n\n    mod test_derive {\n\n        #[derive(Clone)]\n        struct S;\n\n        impl S {\n            fn clone() {}\n            //~^ same_name_method\n        }\n    }\n\n    mod with_generic {\n        use crate::T1;\n\n        struct S<U>(U);\n\n        impl<U> S<U> {\n            fn foo() {}\n            //~^ same_name_method\n        }\n\n        impl<U: Copy> T1 for S<U> {\n            fn foo() {}\n        }\n    }\n\n    mod default_method {\n        use crate::T1;\n\n        struct S;\n\n        impl S {\n            fn foo() {}\n            //~^ same_name_method\n        }\n\n        impl T1 for S {}\n    }\n\n    mod multiple_conflicting_traits {\n        use crate::{T1, T2};\n\n        struct S;\n\n        impl S {\n            fn foo() {}\n            //~^ same_name_method\n            //~| same_name_method\n        }\n\n        impl T1 for S {}\n\n        impl T2 for S {}\n    }\n}\n\nmod should_not_lint {\n\n    mod not_lint_two_trait_method {\n        use crate::{T1, T2};\n\n        struct S;\n\n        impl T1 for S {\n            fn foo() {}\n        }\n\n        impl T2 for S {\n            fn foo() {}\n        }\n    }\n\n    mod only_lint_on_method {\n        trait T3 {\n            type foo;\n        }\n\n        struct S;\n\n        impl S {\n            fn foo() {}\n        }\n        impl T3 for S {\n            type foo = usize;\n        }\n    }\n}\n\nmod check_expect_suppression {\n    use crate::T1;\n\n    struct S;\n\n    impl S {\n        #[expect(clippy::same_name_method)]\n        fn foo() {}\n    }\n\n    impl T1 for S {\n        fn foo() {}\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/same_name_method.stderr",
    "content": "error: method's name is the same as an existing method in a trait\n  --> tests/ui/same_name_method.rs:20:13\n   |\nLL |             fn foo() {}\n   |             ^^^^^^^^\n   |\nnote: existing `foo` defined here\n  --> tests/ui/same_name_method.rs:25:13\n   |\nLL |             fn foo() {}\n   |             ^^^^^^^^\n   = note: `-D clippy::same-name-method` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::same_name_method)]`\n\nerror: method's name is the same as an existing method in a trait\n  --> tests/ui/same_name_method.rs:35:13\n   |\nLL |             fn clone() {}\n   |             ^^^^^^^^^^\n   |\nnote: existing `clone` defined here\n  --> tests/ui/same_name_method.rs:31:18\n   |\nLL |         #[derive(Clone)]\n   |                  ^^^^^\n\nerror: method's name is the same as an existing method in a trait\n  --> tests/ui/same_name_method.rs:46:13\n   |\nLL |             fn foo() {}\n   |             ^^^^^^^^\n   |\nnote: existing `foo` defined here\n  --> tests/ui/same_name_method.rs:51:13\n   |\nLL |             fn foo() {}\n   |             ^^^^^^^^\n\nerror: method's name is the same as an existing method in a trait\n  --> tests/ui/same_name_method.rs:61:13\n   |\nLL |             fn foo() {}\n   |             ^^^^^^^^\n   |\nnote: existing `foo` defined here\n  --> tests/ui/same_name_method.rs:65:9\n   |\nLL |         impl T1 for S {}\n   |         ^^^^^^^^^^^^^^^^\n\nerror: method's name is the same as an existing method in a trait\n  --> tests/ui/same_name_method.rs:74:13\n   |\nLL |             fn foo() {}\n   |             ^^^^^^^^\n   |\nnote: existing `foo` defined here\n  --> tests/ui/same_name_method.rs:79:9\n   |\nLL |         impl T1 for S {}\n   |         ^^^^^^^^^^^^^^^^\n\nerror: method's name is the same as an existing method in a trait\n  --> tests/ui/same_name_method.rs:74:13\n   |\nLL |             fn foo() {}\n   |             ^^^^^^^^\n   |\nnote: existing `foo` defined here\n  --> tests/ui/same_name_method.rs:81:9\n   |\nLL |         impl T2 for S {}\n   |         ^^^^^^^^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/search_is_some.rs",
    "content": "//@aux-build:option_helpers.rs\n#![warn(clippy::search_is_some)]\n#![allow(clippy::manual_pattern_char_comparison)]\n#![allow(clippy::useless_vec)]\n#![allow(dead_code)]\nextern crate option_helpers;\nuse option_helpers::IteratorFalsePositives;\n//@no-rustfix\n#[rustfmt::skip]\nfn main() {\n    // Check that we don't lint if the caller is not an `Iterator` or string\n    let falsepos = IteratorFalsePositives { foo: 0 };\n    let _ = falsepos.find().is_some();\n    let _ = falsepos.position().is_some();\n    let _ = falsepos.rposition().is_some();\n    // check that we don't lint if `find()` is called with\n    // `Pattern` that is not a string\n    let _ = \"hello world\".find(|c: char| c == 'o' || c == 'l').is_some();\n\n    let some_closure = |x: &u32| *x == 0;\n    let _ = (0..1).find(some_closure).is_some();\n    //~^ search_is_some\n}\n\n#[rustfmt::skip]\nfn is_none() {\n    // Check that we don't lint if the caller is not an `Iterator` or string\n    let falsepos = IteratorFalsePositives { foo: 0 };\n    let _ = falsepos.find().is_none();\n    let _ = falsepos.position().is_none();\n    let _ = falsepos.rposition().is_none();\n    // check that we don't lint if `find()` is called with\n    // `Pattern` that is not a string\n    let _ = \"hello world\".find(|c: char| c == 'o' || c == 'l').is_none();\n\n    let some_closure = |x: &u32| *x == 0;\n    let _ = (0..1).find(some_closure).is_none();\n    //~^ search_is_some\n}\n"
  },
  {
    "path": "tests/ui/search_is_some.stderr",
    "content": "error: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some.rs:21:20\n   |\nLL |     let _ = (0..1).find(some_closure).is_some();\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(some_closure)`\n   |\n   = note: `-D clippy::search-is-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some.rs:37:13\n   |\nLL |     let _ = (0..1).find(some_closure).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(some_closure)`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_none.fixed",
    "content": "#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec, clippy::manual_contains)]\n#![warn(clippy::search_is_some)]\n\nfn main() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n    let y = &&42;\n\n    // Check `find().is_none()`, single-line case.\n    let _ = !v.iter().any(|x| *x < 0);\n    //~^ search_is_some\n    let _ = !(0..1).any(|x| **y == x); // one dereference less\n    //\n    //~^^ search_is_some\n    let _ = !(0..1).any(|x| x == 0);\n    //~^ search_is_some\n    let _ = !v.iter().any(|x| *x == 0);\n    //~^ search_is_some\n    let _ = !(4..5).any(|x| x == 1 || x == 3 || x == 5);\n    //~^ search_is_some\n    let _ = !(1..3).any(|x| [1, 2, 3].contains(&x));\n    //~^ search_is_some\n    let _ = !(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x));\n    //~^ search_is_some\n    let _ = !(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0);\n    //~^ search_is_some\n    let _ = !(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1);\n    // Check `find().is_none()`, multi-line case.\n    let _ = !v\n        //~^ search_is_some\n        .iter().any(|x| {\n            *x < 0 //\n        });\n\n    // Check `position().is_none()`, single-line case.\n    let _ = !v.iter().any(|&x| x < 0);\n    //~^ search_is_some\n    // Check `position().is_none()`, multi-line case.\n    let _ = !v\n        //~^ search_is_some\n        .iter().any(|&x| {\n            x < 0 //\n        });\n\n    // Check `rposition().is_none()`, single-line case.\n    let _ = !v.iter().any(|&x| x < 0);\n    //~^ search_is_some\n    // Check `rposition().is_none()`, multi-line case.\n    let _ = !v\n        //~^ search_is_some\n        .iter().any(|&x| {\n            x < 0 //\n        });\n\n    let s1 = String::from(\"hello world\");\n    let s2 = String::from(\"world\");\n\n    // caller of `find()` is a `&`static str`\n    let _ = !\"hello world\".contains(\"world\");\n    //~^ search_is_some\n    let _ = !\"hello world\".contains(&s2);\n    //~^ search_is_some\n    let _ = !\"hello world\".contains(&s2[2..]);\n    //~^ search_is_some\n    // caller of `find()` is a `String`\n    let _ = !s1.contains(\"world\");\n    //~^ search_is_some\n    let _ = !s1.contains(&s2);\n    //~^ search_is_some\n    let _ = !s1.contains(&s2[2..]);\n    //~^ search_is_some\n    // caller of `find()` is slice of `String`\n    let _ = !s1[2..].contains(\"world\");\n    //~^ search_is_some\n    let _ = !s1[2..].contains(&s2);\n    //~^ search_is_some\n    let _ = !s1[2..].contains(&s2[2..]);\n    //~^ search_is_some\n}\n\n#[allow(clippy::clone_on_copy, clippy::map_clone)]\nmod issue7392 {\n    struct Player {\n        hand: Vec<usize>,\n    }\n    fn filter() {\n        let p = Player {\n            hand: vec![1, 2, 3, 4, 5],\n        };\n        let filter_hand = vec![5];\n        let _ = p\n            .hand\n            .iter()\n            .filter(|c| !filter_hand.iter().any(|cc| c == &cc))\n            //~^ search_is_some\n            .map(|c| c.clone())\n            .collect::<Vec<_>>();\n    }\n\n    struct PlayerTuple {\n        hand: Vec<(usize, char)>,\n    }\n    fn filter_tuple() {\n        let p = PlayerTuple {\n            hand: vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')],\n        };\n        let filter_hand = vec![5];\n        let _ = p\n            .hand\n            .iter()\n            .filter(|(c, _)| !filter_hand.iter().any(|cc| c == cc))\n            //~^ search_is_some\n            .map(|c| c.clone())\n            .collect::<Vec<_>>();\n    }\n\n    fn field_projection() {\n        struct Foo {\n            foo: i32,\n            bar: u32,\n        }\n        let vfoo = vec![Foo { foo: 1, bar: 2 }];\n        let _ = !vfoo.iter().any(|v| v.foo == 1 && v.bar == 2);\n        //~^ search_is_some\n\n        let vfoo = vec![(42, Foo { foo: 1, bar: 2 })];\n        let _ = !vfoo\n            //~^ search_is_some\n            .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2);\n    }\n\n    fn index_projection() {\n        let vfoo = vec![[0, 1, 2, 3]];\n        let _ = !vfoo.iter().any(|a| a[0] == 42);\n        //~^ search_is_some\n    }\n\n    #[allow(clippy::match_like_matches_macro)]\n    fn slice_projection() {\n        let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];\n        let _ = !vfoo.iter().any(|sub| sub[1..4].len() == 3);\n        //~^ search_is_some\n    }\n\n    fn please(x: &u32) -> bool {\n        *x == 9\n    }\n\n    fn deref_enough(x: u32) -> bool {\n        x == 78\n    }\n\n    fn arg_no_deref(x: &&u32) -> bool {\n        **x == 78\n    }\n\n    fn more_projections() {\n        let x = 19;\n        let ppx: &u32 = &x;\n        let _ = ![ppx].iter().any(|ppp_x: &&u32| please(ppp_x));\n        //~^ search_is_some\n        let _ = ![String::from(\"Hey hey\")].iter().any(|s| s.len() == 2);\n        //~^ search_is_some\n\n        let v = vec![3, 2, 1, 0];\n        let _ = !v.iter().any(|x| deref_enough(*x));\n        //~^ search_is_some\n        let _ = !v.iter().any(|x: &u32| deref_enough(*x));\n        //~^ search_is_some\n\n        #[allow(clippy::redundant_closure)]\n        let _ = !v.iter().any(|x| arg_no_deref(&x));\n        //~^ search_is_some\n        #[allow(clippy::redundant_closure)]\n        let _ = !v.iter().any(|x: &u32| arg_no_deref(&x));\n        //~^ search_is_some\n    }\n\n    fn field_index_projection() {\n        struct FooDouble {\n            bar: Vec<Vec<i32>>,\n        }\n        struct Foo {\n            bar: Vec<i32>,\n        }\n        struct FooOuter {\n            inner: Foo,\n            inner_double: FooDouble,\n        }\n        let vfoo = vec![FooOuter {\n            inner: Foo { bar: vec![0, 1, 2, 3] },\n            inner_double: FooDouble {\n                bar: vec![vec![0, 1, 2, 3]],\n            },\n        }];\n        let _ = !vfoo\n            //~^ search_is_some\n            .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2);\n    }\n\n    fn index_field_projection() {\n        struct Foo {\n            bar: i32,\n        }\n        struct FooOuter {\n            inner: Vec<Foo>,\n        }\n        let vfoo = vec![FooOuter {\n            inner: vec![Foo { bar: 0 }],\n        }];\n        let _ = !vfoo.iter().any(|v| v.inner[0].bar == 2);\n        //~^ search_is_some\n    }\n\n    fn double_deref_index_projection() {\n        let vfoo = vec![&&[0, 1, 2, 3]];\n        let _ = !vfoo.iter().any(|x| (**x)[0] == 9);\n        //~^ search_is_some\n    }\n\n    fn method_call_by_ref() {\n        struct Foo {\n            bar: u32,\n        }\n        impl Foo {\n            pub fn by_ref(&self, x: &u32) -> bool {\n                *x == self.bar\n            }\n        }\n        let vfoo = vec![Foo { bar: 1 }];\n        let _ = !vfoo.iter().any(|v| v.by_ref(&v.bar));\n        //~^ search_is_some\n    }\n\n    fn ref_bindings() {\n        let _ = ![&(&1, 2), &(&3, 4), &(&5, 4)]\n            //~^ search_is_some\n            .iter().any(|&&(&x, ref y)| x == *y);\n    }\n\n    fn test_string_1(s: &str) -> bool {\n        s.is_empty()\n    }\n\n    fn test_u32_1(s: &u32) -> bool {\n        s.is_power_of_two()\n    }\n\n    fn test_u32_2(s: u32) -> bool {\n        s.is_power_of_two()\n    }\n\n    fn projection_in_args_test() {\n        // Index projections\n        let lst = &[String::from(\"Hello\"), String::from(\"world\")];\n        let v: Vec<&[String]> = vec![lst];\n        let _ = !v.iter().any(|s| s[0].is_empty());\n        //~^ search_is_some\n        let _ = !v.iter().any(|s| test_string_1(&s[0]));\n        //~^ search_is_some\n\n        // Field projections\n        struct FieldProjection<'a> {\n            field: &'a u32,\n        }\n        let field = 123456789;\n        let instance = FieldProjection { field: &field };\n        let v = vec![instance];\n        let _ = !v.iter().any(|fp| fp.field.is_power_of_two());\n        //~^ search_is_some\n        let _ = !v.iter().any(|fp| test_u32_1(fp.field));\n        //~^ search_is_some\n        let _ = !v.iter().any(|fp| test_u32_2(*fp.field));\n        //~^ search_is_some\n    }\n}\n\nmod issue_11910 {\n    fn computations() -> u32 {\n        0\n    }\n\n    struct Foo;\n    impl Foo {\n        fn bar(&self, _: bool) {}\n    }\n\n    fn test_normal_for_iter() {\n        let v = vec![3, 2, 1, 0, -1, -2, -3];\n        let _ = !v.iter().any(|x| *x == 42);\n        //~^ search_is_some\n        Foo.bar(!v.iter().any(|x| *x == 42));\n        //~^ search_is_some\n    }\n\n    fn test_then_for_iter() {\n        let v = vec![3, 2, 1, 0, -1, -2, -3];\n        (!v.iter().any(|x| *x == 42)).then(computations);\n        //~^ search_is_some\n    }\n\n    fn test_then_some_for_iter() {\n        let v = vec![3, 2, 1, 0, -1, -2, -3];\n        (!v.iter().any(|x| *x == 42)).then_some(0);\n        //~^ search_is_some\n    }\n\n    fn test_normal_for_str() {\n        let s = \"hello\";\n        let _ = !s.contains(\"world\");\n        //~^ search_is_some\n        Foo.bar(!s.contains(\"world\"));\n        //~^ search_is_some\n        let s = String::from(\"hello\");\n        let _ = !s.contains(\"world\");\n        //~^ search_is_some\n        Foo.bar(!s.contains(\"world\"));\n        //~^ search_is_some\n    }\n\n    fn test_then_for_str() {\n        let s = \"hello\";\n        let _ = (!s.contains(\"world\")).then(computations);\n        //~^ search_is_some\n        let s = String::from(\"hello\");\n        let _ = (!s.contains(\"world\")).then(computations);\n        //~^ search_is_some\n    }\n\n    fn test_then_some_for_str() {\n        let s = \"hello\";\n        let _ = (!s.contains(\"world\")).then_some(0);\n        //~^ search_is_some\n        let s = String::from(\"hello\");\n        let _ = (!s.contains(\"world\")).then_some(0);\n        //~^ search_is_some\n    }\n}\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_none.rs",
    "content": "#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec, clippy::manual_contains)]\n#![warn(clippy::search_is_some)]\n\nfn main() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n    let y = &&42;\n\n    // Check `find().is_none()`, single-line case.\n    let _ = v.iter().find(|&x| *x < 0).is_none();\n    //~^ search_is_some\n    let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less\n    //\n    //~^^ search_is_some\n    let _ = (0..1).find(|x| *x == 0).is_none();\n    //~^ search_is_some\n    let _ = v.iter().find(|x| **x == 0).is_none();\n    //~^ search_is_some\n    let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none();\n    //~^ search_is_some\n    let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none();\n    //~^ search_is_some\n    let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none();\n    //~^ search_is_some\n    let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none();\n    //~^ search_is_some\n    let _ = (1..3)\n        //~^ search_is_some\n        .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)\n        .is_none();\n    // Check `find().is_none()`, multi-line case.\n    let _ = v\n        //~^ search_is_some\n        .iter()\n        .find(|&x| {\n            *x < 0 //\n        })\n        .is_none();\n\n    // Check `position().is_none()`, single-line case.\n    let _ = v.iter().position(|&x| x < 0).is_none();\n    //~^ search_is_some\n    // Check `position().is_none()`, multi-line case.\n    let _ = v\n        //~^ search_is_some\n        .iter()\n        .position(|&x| {\n            x < 0 //\n        })\n        .is_none();\n\n    // Check `rposition().is_none()`, single-line case.\n    let _ = v.iter().rposition(|&x| x < 0).is_none();\n    //~^ search_is_some\n    // Check `rposition().is_none()`, multi-line case.\n    let _ = v\n        //~^ search_is_some\n        .iter()\n        .rposition(|&x| {\n            x < 0 //\n        })\n        .is_none();\n\n    let s1 = String::from(\"hello world\");\n    let s2 = String::from(\"world\");\n\n    // caller of `find()` is a `&`static str`\n    let _ = \"hello world\".find(\"world\").is_none();\n    //~^ search_is_some\n    let _ = \"hello world\".find(&s2).is_none();\n    //~^ search_is_some\n    let _ = \"hello world\".find(&s2[2..]).is_none();\n    //~^ search_is_some\n    // caller of `find()` is a `String`\n    let _ = s1.find(\"world\").is_none();\n    //~^ search_is_some\n    let _ = s1.find(&s2).is_none();\n    //~^ search_is_some\n    let _ = s1.find(&s2[2..]).is_none();\n    //~^ search_is_some\n    // caller of `find()` is slice of `String`\n    let _ = s1[2..].find(\"world\").is_none();\n    //~^ search_is_some\n    let _ = s1[2..].find(&s2).is_none();\n    //~^ search_is_some\n    let _ = s1[2..].find(&s2[2..]).is_none();\n    //~^ search_is_some\n}\n\n#[allow(clippy::clone_on_copy, clippy::map_clone)]\nmod issue7392 {\n    struct Player {\n        hand: Vec<usize>,\n    }\n    fn filter() {\n        let p = Player {\n            hand: vec![1, 2, 3, 4, 5],\n        };\n        let filter_hand = vec![5];\n        let _ = p\n            .hand\n            .iter()\n            .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none())\n            //~^ search_is_some\n            .map(|c| c.clone())\n            .collect::<Vec<_>>();\n    }\n\n    struct PlayerTuple {\n        hand: Vec<(usize, char)>,\n    }\n    fn filter_tuple() {\n        let p = PlayerTuple {\n            hand: vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')],\n        };\n        let filter_hand = vec![5];\n        let _ = p\n            .hand\n            .iter()\n            .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none())\n            //~^ search_is_some\n            .map(|c| c.clone())\n            .collect::<Vec<_>>();\n    }\n\n    fn field_projection() {\n        struct Foo {\n            foo: i32,\n            bar: u32,\n        }\n        let vfoo = vec![Foo { foo: 1, bar: 2 }];\n        let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none();\n        //~^ search_is_some\n\n        let vfoo = vec![(42, Foo { foo: 1, bar: 2 })];\n        let _ = vfoo\n            //~^ search_is_some\n            .iter()\n            .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)\n            .is_none();\n    }\n\n    fn index_projection() {\n        let vfoo = vec![[0, 1, 2, 3]];\n        let _ = vfoo.iter().find(|a| a[0] == 42).is_none();\n        //~^ search_is_some\n    }\n\n    #[allow(clippy::match_like_matches_macro)]\n    fn slice_projection() {\n        let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];\n        let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();\n        //~^ search_is_some\n    }\n\n    fn please(x: &u32) -> bool {\n        *x == 9\n    }\n\n    fn deref_enough(x: u32) -> bool {\n        x == 78\n    }\n\n    fn arg_no_deref(x: &&u32) -> bool {\n        **x == 78\n    }\n\n    fn more_projections() {\n        let x = 19;\n        let ppx: &u32 = &x;\n        let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none();\n        //~^ search_is_some\n        let _ = [String::from(\"Hey hey\")].iter().find(|s| s.len() == 2).is_none();\n        //~^ search_is_some\n\n        let v = vec![3, 2, 1, 0];\n        let _ = v.iter().find(|x| deref_enough(**x)).is_none();\n        //~^ search_is_some\n        let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none();\n        //~^ search_is_some\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().find(|x| arg_no_deref(x)).is_none();\n        //~^ search_is_some\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none();\n        //~^ search_is_some\n    }\n\n    fn field_index_projection() {\n        struct FooDouble {\n            bar: Vec<Vec<i32>>,\n        }\n        struct Foo {\n            bar: Vec<i32>,\n        }\n        struct FooOuter {\n            inner: Foo,\n            inner_double: FooDouble,\n        }\n        let vfoo = vec![FooOuter {\n            inner: Foo { bar: vec![0, 1, 2, 3] },\n            inner_double: FooDouble {\n                bar: vec![vec![0, 1, 2, 3]],\n            },\n        }];\n        let _ = vfoo\n            //~^ search_is_some\n            .iter()\n            .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)\n            .is_none();\n    }\n\n    fn index_field_projection() {\n        struct Foo {\n            bar: i32,\n        }\n        struct FooOuter {\n            inner: Vec<Foo>,\n        }\n        let vfoo = vec![FooOuter {\n            inner: vec![Foo { bar: 0 }],\n        }];\n        let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none();\n        //~^ search_is_some\n    }\n\n    fn double_deref_index_projection() {\n        let vfoo = vec![&&[0, 1, 2, 3]];\n        let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none();\n        //~^ search_is_some\n    }\n\n    fn method_call_by_ref() {\n        struct Foo {\n            bar: u32,\n        }\n        impl Foo {\n            pub fn by_ref(&self, x: &u32) -> bool {\n                *x == self.bar\n            }\n        }\n        let vfoo = vec![Foo { bar: 1 }];\n        let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none();\n        //~^ search_is_some\n    }\n\n    fn ref_bindings() {\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)]\n            //~^ search_is_some\n            .iter()\n            .find(|&&&(&x, ref y)| x == *y)\n            .is_none();\n    }\n\n    fn test_string_1(s: &str) -> bool {\n        s.is_empty()\n    }\n\n    fn test_u32_1(s: &u32) -> bool {\n        s.is_power_of_two()\n    }\n\n    fn test_u32_2(s: u32) -> bool {\n        s.is_power_of_two()\n    }\n\n    fn projection_in_args_test() {\n        // Index projections\n        let lst = &[String::from(\"Hello\"), String::from(\"world\")];\n        let v: Vec<&[String]> = vec![lst];\n        let _ = v.iter().find(|s| s[0].is_empty()).is_none();\n        //~^ search_is_some\n        let _ = v.iter().find(|s| test_string_1(&s[0])).is_none();\n        //~^ search_is_some\n\n        // Field projections\n        struct FieldProjection<'a> {\n            field: &'a u32,\n        }\n        let field = 123456789;\n        let instance = FieldProjection { field: &field };\n        let v = vec![instance];\n        let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none();\n        //~^ search_is_some\n        let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none();\n        //~^ search_is_some\n        let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none();\n        //~^ search_is_some\n    }\n}\n\nmod issue_11910 {\n    fn computations() -> u32 {\n        0\n    }\n\n    struct Foo;\n    impl Foo {\n        fn bar(&self, _: bool) {}\n    }\n\n    fn test_normal_for_iter() {\n        let v = vec![3, 2, 1, 0, -1, -2, -3];\n        let _ = v.iter().find(|x| **x == 42).is_none();\n        //~^ search_is_some\n        Foo.bar(v.iter().find(|x| **x == 42).is_none());\n        //~^ search_is_some\n    }\n\n    fn test_then_for_iter() {\n        let v = vec![3, 2, 1, 0, -1, -2, -3];\n        v.iter().find(|x| **x == 42).is_none().then(computations);\n        //~^ search_is_some\n    }\n\n    fn test_then_some_for_iter() {\n        let v = vec![3, 2, 1, 0, -1, -2, -3];\n        v.iter().find(|x| **x == 42).is_none().then_some(0);\n        //~^ search_is_some\n    }\n\n    fn test_normal_for_str() {\n        let s = \"hello\";\n        let _ = s.find(\"world\").is_none();\n        //~^ search_is_some\n        Foo.bar(s.find(\"world\").is_none());\n        //~^ search_is_some\n        let s = String::from(\"hello\");\n        let _ = s.find(\"world\").is_none();\n        //~^ search_is_some\n        Foo.bar(s.find(\"world\").is_none());\n        //~^ search_is_some\n    }\n\n    fn test_then_for_str() {\n        let s = \"hello\";\n        let _ = s.find(\"world\").is_none().then(computations);\n        //~^ search_is_some\n        let s = String::from(\"hello\");\n        let _ = s.find(\"world\").is_none().then(computations);\n        //~^ search_is_some\n    }\n\n    fn test_then_some_for_str() {\n        let s = \"hello\";\n        let _ = s.find(\"world\").is_none().then_some(0);\n        //~^ search_is_some\n        let s = String::from(\"hello\");\n        let _ = s.find(\"world\").is_none().then_some(0);\n        //~^ search_is_some\n    }\n}\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_none.stderr",
    "content": "error: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:9:13\n   |\nLL |     let _ = v.iter().find(|&x| *x < 0).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x < 0)`\n   |\n   = note: `-D clippy::search-is-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:11:13\n   |\nLL |     let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| **y == x)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:14:13\n   |\nLL |     let _ = (0..1).find(|x| *x == 0).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| x == 0)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:16:13\n   |\nLL |     let _ = v.iter().find(|x| **x == 0).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 0)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:18:13\n   |\nLL |     let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:20:13\n   |\nLL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:22:13\n   |\nLL |     let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:24:13\n   |\nLL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:26:13\n   |\nLL |       let _ = (1..3)\n   |  _____________^\nLL | |\nLL | |         .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)\nLL | |         .is_none();\n   | |__________________^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:31:13\n   |\nLL |       let _ = v\n   |  _____________^\nLL | |\nLL | |         .iter()\nLL | |         .find(|&x| {\nLL | |             *x < 0 //\nLL | |         })\nLL | |         .is_none();\n   | |__________________^\n   |\nhelp: consider using\n   |\nLL ~     let _ = !v\nLL +\nLL +         .iter().any(|x| {\nLL +             *x < 0 //\nLL ~         });\n   |\n\nerror: called `is_none()` after searching an `Iterator` with `position`\n  --> tests/ui/search_is_some_fixable_none.rs:40:13\n   |\nLL |     let _ = v.iter().position(|&x| x < 0).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)`\n\nerror: called `is_none()` after searching an `Iterator` with `position`\n  --> tests/ui/search_is_some_fixable_none.rs:43:13\n   |\nLL |       let _ = v\n   |  _____________^\nLL | |\nLL | |         .iter()\nLL | |         .position(|&x| {\nLL | |             x < 0 //\nLL | |         })\nLL | |         .is_none();\n   | |__________________^\n   |\nhelp: consider using\n   |\nLL ~     let _ = !v\nLL +\nLL +         .iter().any(|&x| {\nLL +             x < 0 //\nLL ~         });\n   |\n\nerror: called `is_none()` after searching an `Iterator` with `rposition`\n  --> tests/ui/search_is_some_fixable_none.rs:52:13\n   |\nLL |     let _ = v.iter().rposition(|&x| x < 0).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)`\n\nerror: called `is_none()` after searching an `Iterator` with `rposition`\n  --> tests/ui/search_is_some_fixable_none.rs:55:13\n   |\nLL |       let _ = v\n   |  _____________^\nLL | |\nLL | |         .iter()\nLL | |         .rposition(|&x| {\nLL | |             x < 0 //\nLL | |         })\nLL | |         .is_none();\n   | |__________________^\n   |\nhelp: consider using\n   |\nLL ~     let _ = !v\nLL +\nLL +         .iter().any(|&x| {\nLL +             x < 0 //\nLL ~         });\n   |\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:67:13\n   |\nLL |     let _ = \"hello world\".find(\"world\").is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!\"hello world\".contains(\"world\")`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:69:13\n   |\nLL |     let _ = \"hello world\".find(&s2).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!\"hello world\".contains(&s2)`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:71:13\n   |\nLL |     let _ = \"hello world\".find(&s2[2..]).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!\"hello world\".contains(&s2[2..])`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:74:13\n   |\nLL |     let _ = s1.find(\"world\").is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(\"world\")`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:76:13\n   |\nLL |     let _ = s1.find(&s2).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2)`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:78:13\n   |\nLL |     let _ = s1.find(&s2[2..]).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2[2..])`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:81:13\n   |\nLL |     let _ = s1[2..].find(\"world\").is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(\"world\")`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:83:13\n   |\nLL |     let _ = s1[2..].find(&s2).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2)`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:85:13\n   |\nLL |     let _ = s1[2..].find(&s2[2..]).is_none();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2[2..])`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:102:25\n   |\nLL |             .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none())\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == &cc)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:119:30\n   |\nLL |             .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none())\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == cc)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:131:17\n   |\nLL |         let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:135:17\n   |\nLL |           let _ = vfoo\n   |  _________________^\nLL | |\nLL | |             .iter()\nLL | |             .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)\nLL | |             .is_none();\n   | |______________________^\n   |\nhelp: consider using\n   |\nLL ~         let _ = !vfoo\nLL +\nLL ~             .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2);\n   |\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:144:17\n   |\nLL |         let _ = vfoo.iter().find(|a| a[0] == 42).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|a| a[0] == 42)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:151:17\n   |\nLL |         let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:170:17\n   |\nLL |         let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:172:17\n   |\nLL |         let _ = [String::from(\"Hey hey\")].iter().find(|s| s.len() == 2).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![String::from(\"Hey hey\")].iter().any(|s| s.len() == 2)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:176:17\n   |\nLL |         let _ = v.iter().find(|x| deref_enough(**x)).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| deref_enough(*x))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:178:17\n   |\nLL |         let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| deref_enough(*x))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:182:17\n   |\nLL |         let _ = v.iter().find(|x| arg_no_deref(x)).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| arg_no_deref(&x))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:185:17\n   |\nLL |         let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| arg_no_deref(&x))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:206:17\n   |\nLL |           let _ = vfoo\n   |  _________________^\nLL | |\nLL | |             .iter()\nLL | |             .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)\nLL | |             .is_none();\n   | |______________________^\n   |\nhelp: consider using\n   |\nLL ~         let _ = !vfoo\nLL +\nLL ~             .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2);\n   |\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:223:17\n   |\nLL |         let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.inner[0].bar == 2)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:229:17\n   |\nLL |         let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|x| (**x)[0] == 9)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:243:17\n   |\nLL |         let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.by_ref(&v.bar))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:248:17\n   |\nLL |           let _ = [&(&1, 2), &(&3, 4), &(&5, 4)]\n   |  _________________^\nLL | |\nLL | |             .iter()\nLL | |             .find(|&&&(&x, ref y)| x == *y)\nLL | |             .is_none();\n   | |______________________^\n   |\nhelp: consider using\n   |\nLL ~         let _ = ![&(&1, 2), &(&3, 4), &(&5, 4)]\nLL +\nLL ~             .iter().any(|&&(&x, ref y)| x == *y);\n   |\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:271:17\n   |\nLL |         let _ = v.iter().find(|s| s[0].is_empty()).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| s[0].is_empty())`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:273:17\n   |\nLL |         let _ = v.iter().find(|s| test_string_1(&s[0])).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| test_string_1(&s[0]))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:283:17\n   |\nLL |         let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| fp.field.is_power_of_two())`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:285:17\n   |\nLL |         let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_1(fp.field))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:287:17\n   |\nLL |         let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_2(*fp.field))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:304:17\n   |\nLL |         let _ = v.iter().find(|x| **x == 42).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 42)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:306:17\n   |\nLL |         Foo.bar(v.iter().find(|x| **x == 42).is_none());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 42)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:312:9\n   |\nLL |         v.iter().find(|x| **x == 42).is_none().then(computations);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!v.iter().any(|x| *x == 42))`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none.rs:318:9\n   |\nLL |         v.iter().find(|x| **x == 42).is_none().then_some(0);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!v.iter().any(|x| *x == 42))`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:324:17\n   |\nLL |         let _ = s.find(\"world\").is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains(\"world\")`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:326:17\n   |\nLL |         Foo.bar(s.find(\"world\").is_none());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains(\"world\")`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:329:17\n   |\nLL |         let _ = s.find(\"world\").is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains(\"world\")`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:331:17\n   |\nLL |         Foo.bar(s.find(\"world\").is_none());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s.contains(\"world\")`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:337:17\n   |\nLL |         let _ = s.find(\"world\").is_none().then(computations);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains(\"world\"))`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:340:17\n   |\nLL |         let _ = s.find(\"world\").is_none().then(computations);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains(\"world\"))`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:346:17\n   |\nLL |         let _ = s.find(\"world\").is_none().then_some(0);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains(\"world\"))`\n\nerror: called `is_none()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_none.rs:349:17\n   |\nLL |         let _ = s.find(\"world\").is_none().then_some(0);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(!s.contains(\"world\"))`\n\nerror: aborting due to 57 previous errors\n\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_none_2021.fixed",
    "content": "//@edition: 2021\n#![warn(clippy::search_is_some)]\n\nfn main() {\n    fn ref_bindings() {\n        let _ = ![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y);\n        //~^ search_is_some\n        let _ = ![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y);\n        //~^ search_is_some\n        let _ = ![&(&1, 2), &(&3, 4), &(&5, 4)]\n            //~^ search_is_some\n            .iter().any(|&&(&x, ref y)| x == *y);\n    }\n}\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_none_2021.rs",
    "content": "//@edition: 2021\n#![warn(clippy::search_is_some)]\n\nfn main() {\n    fn ref_bindings() {\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none();\n        //~^ search_is_some\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none();\n        //~^ search_is_some\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)]\n            //~^ search_is_some\n            .iter()\n            .find(|&&&(&x, ref y)| x == *y)\n            .is_none();\n    }\n}\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_none_2021.stderr",
    "content": "error: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none_2021.rs:6:17\n   |\nLL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`\n   |\n   = note: `-D clippy::search-is-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none_2021.rs:8:17\n   |\nLL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`\n\nerror: called `is_none()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_none_2021.rs:10:17\n   |\nLL |           let _ = [&(&1, 2), &(&3, 4), &(&5, 4)]\n   |  _________________^\nLL | |\nLL | |             .iter()\nLL | |             .find(|&&&(&x, ref y)| x == *y)\nLL | |             .is_none();\n   | |______________________^\n   |\nhelp: consider using\n   |\nLL ~         let _ = ![&(&1, 2), &(&3, 4), &(&5, 4)]\nLL +\nLL ~             .iter().any(|&&(&x, ref y)| x == *y);\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_some.fixed",
    "content": "#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec, clippy::manual_contains)]\n#![warn(clippy::search_is_some)]\n\nfn main() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n    let y = &&42;\n\n    // Check `find().is_some()`, single-line case.\n    let _ = v.iter().any(|x| *x < 0);\n    //~^ search_is_some\n    let _ = (0..1).any(|x| **y == x); // one dereference less\n    //\n    //~^^ search_is_some\n    let _ = (0..1).any(|x| x == 0);\n    //~^ search_is_some\n    let _ = v.iter().any(|x| *x == 0);\n    //~^ search_is_some\n    let _ = (4..5).any(|x| x == 1 || x == 3 || x == 5);\n    //~^ search_is_some\n    let _ = (1..3).any(|x| [1, 2, 3].contains(&x));\n    //~^ search_is_some\n    let _ = (1..3).any(|x| x == 0 || [1, 2, 3].contains(&x));\n    //~^ search_is_some\n    let _ = (1..3).any(|x| [1, 2, 3].contains(&x) || x == 0);\n    //~^ search_is_some\n    let _ = (1..3)\n        .any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1);\n    // Check `find().is_some()`, multi-line case.\n    let _ = v\n        .iter()\n        .any(|x| {\n            //~^ search_is_some\n            *x < 0\n        });\n\n    // Check `position().is_some()`, single-line case.\n    let _ = v.iter().any(|&x| x < 0);\n    //~^ search_is_some\n    // Check `position().is_some()`, multi-line case.\n    let _ = v\n        .iter()\n        .any(|&x| {\n            //~^ search_is_some\n            x < 0\n        });\n\n    // Check `rposition().is_some()`, single-line case.\n    let _ = v.iter().any(|&x| x < 0);\n    //~^ search_is_some\n    // Check `rposition().is_some()`, multi-line case.\n    let _ = v\n        .iter()\n        .any(|&x| {\n            //~^ search_is_some\n            x < 0\n        });\n\n    let s1 = String::from(\"hello world\");\n    let s2 = String::from(\"world\");\n    // caller of `find()` is a `&`static str`\n    let _ = \"hello world\".contains(\"world\");\n    //~^ search_is_some\n    let _ = \"hello world\".contains(&s2);\n    //~^ search_is_some\n    let _ = \"hello world\".contains(&s2[2..]);\n    //~^ search_is_some\n    // caller of `find()` is a `String`\n    let _ = s1.contains(\"world\");\n    //~^ search_is_some\n    let _ = s1.contains(&s2);\n    //~^ search_is_some\n    let _ = s1.contains(&s2[2..]);\n    //~^ search_is_some\n    // caller of `find()` is slice of `String`\n    let _ = s1[2..].contains(\"world\");\n    //~^ search_is_some\n    let _ = s1[2..].contains(&s2);\n    //~^ search_is_some\n    let _ = s1[2..].contains(&s2[2..]);\n    //~^ search_is_some\n}\n\n#[allow(clippy::clone_on_copy, clippy::map_clone)]\nmod issue7392 {\n    struct Player {\n        hand: Vec<usize>,\n    }\n    fn filter() {\n        let p = Player {\n            hand: vec![1, 2, 3, 4, 5],\n        };\n        let filter_hand = vec![5];\n        let _ = p\n            .hand\n            .iter()\n            .filter(|c| filter_hand.iter().any(|cc| c == &cc))\n            //~^ search_is_some\n            .map(|c| c.clone())\n            .collect::<Vec<_>>();\n    }\n\n    struct PlayerTuple {\n        hand: Vec<(usize, char)>,\n    }\n    fn filter_tuple() {\n        let p = PlayerTuple {\n            hand: vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')],\n        };\n        let filter_hand = vec![5];\n        let _ = p\n            .hand\n            .iter()\n            .filter(|(c, _)| filter_hand.iter().any(|cc| c == cc))\n            //~^ search_is_some\n            .map(|c| c.clone())\n            .collect::<Vec<_>>();\n    }\n\n    fn field_projection() {\n        struct Foo {\n            foo: i32,\n            bar: u32,\n        }\n        let vfoo = vec![Foo { foo: 1, bar: 2 }];\n        let _ = vfoo.iter().any(|v| v.foo == 1 && v.bar == 2);\n        //~^ search_is_some\n\n        let vfoo = vec![(42, Foo { foo: 1, bar: 2 })];\n        let _ = vfoo\n            .iter()\n            .any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2);\n    }\n\n    fn index_projection() {\n        let vfoo = vec![[0, 1, 2, 3]];\n        let _ = vfoo.iter().any(|a| a[0] == 42);\n        //~^ search_is_some\n    }\n\n    #[allow(clippy::match_like_matches_macro)]\n    fn slice_projection() {\n        let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];\n        let _ = vfoo.iter().any(|sub| sub[1..4].len() == 3);\n        //~^ search_is_some\n    }\n\n    fn please(x: &u32) -> bool {\n        *x == 9\n    }\n\n    fn deref_enough(x: u32) -> bool {\n        x == 78\n    }\n\n    fn arg_no_deref(x: &&u32) -> bool {\n        **x == 78\n    }\n\n    fn more_projections() {\n        let x = 19;\n        let ppx: &u32 = &x;\n        let _ = [ppx].iter().any(|ppp_x: &&u32| please(ppp_x));\n        //~^ search_is_some\n        let _ = [String::from(\"Hey hey\")].iter().any(|s| s.len() == 2);\n        //~^ search_is_some\n\n        let v = vec![3, 2, 1, 0];\n        let _ = v.iter().any(|x| deref_enough(*x));\n        //~^ search_is_some\n        let _ = v.iter().any(|x: &u32| deref_enough(*x));\n        //~^ search_is_some\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().any(|x| arg_no_deref(&x));\n        //~^ search_is_some\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().any(|x: &u32| arg_no_deref(&x));\n        //~^ search_is_some\n    }\n\n    fn field_index_projection() {\n        struct FooDouble {\n            bar: Vec<Vec<i32>>,\n        }\n        struct Foo {\n            bar: Vec<i32>,\n        }\n        struct FooOuter {\n            inner: Foo,\n            inner_double: FooDouble,\n        }\n        let vfoo = vec![FooOuter {\n            inner: Foo { bar: vec![0, 1, 2, 3] },\n            inner_double: FooDouble {\n                bar: vec![vec![0, 1, 2, 3]],\n            },\n        }];\n        let _ = vfoo\n            .iter()\n            .any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2);\n    }\n\n    fn index_field_projection() {\n        struct Foo {\n            bar: i32,\n        }\n        struct FooOuter {\n            inner: Vec<Foo>,\n        }\n        let vfoo = vec![FooOuter {\n            inner: vec![Foo { bar: 0 }],\n        }];\n        let _ = vfoo.iter().any(|v| v.inner[0].bar == 2);\n        //~^ search_is_some\n    }\n\n    fn double_deref_index_projection() {\n        let vfoo = vec![&&[0, 1, 2, 3]];\n        let _ = vfoo.iter().any(|x| (**x)[0] == 9);\n        //~^ search_is_some\n    }\n\n    fn method_call_by_ref() {\n        struct Foo {\n            bar: u32,\n        }\n        impl Foo {\n            pub fn by_ref(&self, x: &u32) -> bool {\n                *x == self.bar\n            }\n        }\n        let vfoo = vec![Foo { bar: 1 }];\n        let _ = vfoo.iter().any(|v| v.by_ref(&v.bar));\n        //~^ search_is_some\n    }\n\n    fn ref_bindings() {\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)]\n            .iter()\n            .any(|&&(&x, ref y)| x == *y);\n    }\n\n    fn test_string_1(s: &str) -> bool {\n        s.is_empty()\n    }\n\n    fn test_u32_1(s: &u32) -> bool {\n        s.is_power_of_two()\n    }\n\n    fn test_u32_2(s: u32) -> bool {\n        s.is_power_of_two()\n    }\n\n    fn projection_in_args_test() {\n        // Index projections\n        let lst = &[String::from(\"Hello\"), String::from(\"world\")];\n        let v: Vec<&[String]> = vec![lst];\n        let _ = v.iter().any(|s| s[0].is_empty());\n        //~^ search_is_some\n        let _ = v.iter().any(|s| test_string_1(&s[0]));\n        //~^ search_is_some\n\n        // Field projections\n        struct FieldProjection<'a> {\n            field: &'a u32,\n        }\n        let field = 123456789;\n        let instance = FieldProjection { field: &field };\n        let v = vec![instance];\n        let _ = v.iter().any(|fp| fp.field.is_power_of_two());\n        //~^ search_is_some\n        let _ = v.iter().any(|fp| test_u32_1(fp.field));\n        //~^ search_is_some\n        let _ = v.iter().any(|fp| test_u32_2(*fp.field));\n        //~^ search_is_some\n    }\n}\n\nmod issue9120 {\n    fn make_arg_no_deref_impl() -> impl Fn(&&u32) -> bool {\n        move |x: &&u32| **x == 78\n    }\n\n    fn make_arg_no_deref_dyn() -> Box<dyn Fn(&&u32) -> bool> {\n        Box::new(move |x: &&u32| **x == 78)\n    }\n\n    fn wrapper<T: Fn(&&u32) -> bool>(v: Vec<u32>, func: T) -> bool {\n        #[allow(clippy::redundant_closure)]\n        v.iter().any(|x: &u32| func(&x))\n        //~^ search_is_some\n    }\n\n    fn do_tests() {\n        let v = vec![3, 2, 1, 0];\n        let arg_no_deref_impl = make_arg_no_deref_impl();\n        let arg_no_deref_dyn = make_arg_no_deref_dyn();\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().any(|x: &u32| arg_no_deref_impl(&x));\n        //~^ search_is_some\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().any(|x: &u32| arg_no_deref_dyn(&x));\n        //~^ search_is_some\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().any(|x: &u32| (*arg_no_deref_dyn)(&x));\n        //~^ search_is_some\n    }\n}\n\n// skip this test due to rust-lang/rust-clippy#16086\n/*\n#[allow(clippy::match_like_matches_macro)]\nfn issue15102() {\n    let values = [None, Some(3)];\n    let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some();\n    ~^ search_is_some\n    println!(\"{has_even}\");\n\n    let has_even = values\n        .iter()\n        .find(|v| match v {\n            ~^ search_is_some\n            Some(x) if x % 2 == 0 => true,\n            _ => false,\n        })\n        .is_some();\n    println!(\"{has_even}\");\n}\n*/\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_some.rs",
    "content": "#![allow(dead_code, clippy::explicit_auto_deref, clippy::useless_vec, clippy::manual_contains)]\n#![warn(clippy::search_is_some)]\n\nfn main() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n    let y = &&42;\n\n    // Check `find().is_some()`, single-line case.\n    let _ = v.iter().find(|&x| *x < 0).is_some();\n    //~^ search_is_some\n    let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less\n    //\n    //~^^ search_is_some\n    let _ = (0..1).find(|x| *x == 0).is_some();\n    //~^ search_is_some\n    let _ = v.iter().find(|x| **x == 0).is_some();\n    //~^ search_is_some\n    let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some();\n    //~^ search_is_some\n    let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some();\n    //~^ search_is_some\n    let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some();\n    //~^ search_is_some\n    let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some();\n    //~^ search_is_some\n    let _ = (1..3)\n        .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)\n        //~^ search_is_some\n        .is_some();\n    // Check `find().is_some()`, multi-line case.\n    let _ = v\n        .iter()\n        .find(|&x| {\n            //~^ search_is_some\n            *x < 0\n        })\n        .is_some();\n\n    // Check `position().is_some()`, single-line case.\n    let _ = v.iter().position(|&x| x < 0).is_some();\n    //~^ search_is_some\n    // Check `position().is_some()`, multi-line case.\n    let _ = v\n        .iter()\n        .position(|&x| {\n            //~^ search_is_some\n            x < 0\n        })\n        .is_some();\n\n    // Check `rposition().is_some()`, single-line case.\n    let _ = v.iter().rposition(|&x| x < 0).is_some();\n    //~^ search_is_some\n    // Check `rposition().is_some()`, multi-line case.\n    let _ = v\n        .iter()\n        .rposition(|&x| {\n            //~^ search_is_some\n            x < 0\n        })\n        .is_some();\n\n    let s1 = String::from(\"hello world\");\n    let s2 = String::from(\"world\");\n    // caller of `find()` is a `&`static str`\n    let _ = \"hello world\".find(\"world\").is_some();\n    //~^ search_is_some\n    let _ = \"hello world\".find(&s2).is_some();\n    //~^ search_is_some\n    let _ = \"hello world\".find(&s2[2..]).is_some();\n    //~^ search_is_some\n    // caller of `find()` is a `String`\n    let _ = s1.find(\"world\").is_some();\n    //~^ search_is_some\n    let _ = s1.find(&s2).is_some();\n    //~^ search_is_some\n    let _ = s1.find(&s2[2..]).is_some();\n    //~^ search_is_some\n    // caller of `find()` is slice of `String`\n    let _ = s1[2..].find(\"world\").is_some();\n    //~^ search_is_some\n    let _ = s1[2..].find(&s2).is_some();\n    //~^ search_is_some\n    let _ = s1[2..].find(&s2[2..]).is_some();\n    //~^ search_is_some\n}\n\n#[allow(clippy::clone_on_copy, clippy::map_clone)]\nmod issue7392 {\n    struct Player {\n        hand: Vec<usize>,\n    }\n    fn filter() {\n        let p = Player {\n            hand: vec![1, 2, 3, 4, 5],\n        };\n        let filter_hand = vec![5];\n        let _ = p\n            .hand\n            .iter()\n            .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some())\n            //~^ search_is_some\n            .map(|c| c.clone())\n            .collect::<Vec<_>>();\n    }\n\n    struct PlayerTuple {\n        hand: Vec<(usize, char)>,\n    }\n    fn filter_tuple() {\n        let p = PlayerTuple {\n            hand: vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')],\n        };\n        let filter_hand = vec![5];\n        let _ = p\n            .hand\n            .iter()\n            .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some())\n            //~^ search_is_some\n            .map(|c| c.clone())\n            .collect::<Vec<_>>();\n    }\n\n    fn field_projection() {\n        struct Foo {\n            foo: i32,\n            bar: u32,\n        }\n        let vfoo = vec![Foo { foo: 1, bar: 2 }];\n        let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some();\n        //~^ search_is_some\n\n        let vfoo = vec![(42, Foo { foo: 1, bar: 2 })];\n        let _ = vfoo\n            .iter()\n            .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)\n            //~^ search_is_some\n            .is_some();\n    }\n\n    fn index_projection() {\n        let vfoo = vec![[0, 1, 2, 3]];\n        let _ = vfoo.iter().find(|a| a[0] == 42).is_some();\n        //~^ search_is_some\n    }\n\n    #[allow(clippy::match_like_matches_macro)]\n    fn slice_projection() {\n        let vfoo = vec![[0, 1, 2, 3, 0, 1, 2, 3]];\n        let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();\n        //~^ search_is_some\n    }\n\n    fn please(x: &u32) -> bool {\n        *x == 9\n    }\n\n    fn deref_enough(x: u32) -> bool {\n        x == 78\n    }\n\n    fn arg_no_deref(x: &&u32) -> bool {\n        **x == 78\n    }\n\n    fn more_projections() {\n        let x = 19;\n        let ppx: &u32 = &x;\n        let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some();\n        //~^ search_is_some\n        let _ = [String::from(\"Hey hey\")].iter().find(|s| s.len() == 2).is_some();\n        //~^ search_is_some\n\n        let v = vec![3, 2, 1, 0];\n        let _ = v.iter().find(|x| deref_enough(**x)).is_some();\n        //~^ search_is_some\n        let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some();\n        //~^ search_is_some\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().find(|x| arg_no_deref(x)).is_some();\n        //~^ search_is_some\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some();\n        //~^ search_is_some\n    }\n\n    fn field_index_projection() {\n        struct FooDouble {\n            bar: Vec<Vec<i32>>,\n        }\n        struct Foo {\n            bar: Vec<i32>,\n        }\n        struct FooOuter {\n            inner: Foo,\n            inner_double: FooDouble,\n        }\n        let vfoo = vec![FooOuter {\n            inner: Foo { bar: vec![0, 1, 2, 3] },\n            inner_double: FooDouble {\n                bar: vec![vec![0, 1, 2, 3]],\n            },\n        }];\n        let _ = vfoo\n            .iter()\n            .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)\n            //~^ search_is_some\n            .is_some();\n    }\n\n    fn index_field_projection() {\n        struct Foo {\n            bar: i32,\n        }\n        struct FooOuter {\n            inner: Vec<Foo>,\n        }\n        let vfoo = vec![FooOuter {\n            inner: vec![Foo { bar: 0 }],\n        }];\n        let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some();\n        //~^ search_is_some\n    }\n\n    fn double_deref_index_projection() {\n        let vfoo = vec![&&[0, 1, 2, 3]];\n        let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some();\n        //~^ search_is_some\n    }\n\n    fn method_call_by_ref() {\n        struct Foo {\n            bar: u32,\n        }\n        impl Foo {\n            pub fn by_ref(&self, x: &u32) -> bool {\n                *x == self.bar\n            }\n        }\n        let vfoo = vec![Foo { bar: 1 }];\n        let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some();\n        //~^ search_is_some\n    }\n\n    fn ref_bindings() {\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)]\n            .iter()\n            .find(|&&&(&x, ref y)| x == *y)\n            //~^ search_is_some\n            .is_some();\n    }\n\n    fn test_string_1(s: &str) -> bool {\n        s.is_empty()\n    }\n\n    fn test_u32_1(s: &u32) -> bool {\n        s.is_power_of_two()\n    }\n\n    fn test_u32_2(s: u32) -> bool {\n        s.is_power_of_two()\n    }\n\n    fn projection_in_args_test() {\n        // Index projections\n        let lst = &[String::from(\"Hello\"), String::from(\"world\")];\n        let v: Vec<&[String]> = vec![lst];\n        let _ = v.iter().find(|s| s[0].is_empty()).is_some();\n        //~^ search_is_some\n        let _ = v.iter().find(|s| test_string_1(&s[0])).is_some();\n        //~^ search_is_some\n\n        // Field projections\n        struct FieldProjection<'a> {\n            field: &'a u32,\n        }\n        let field = 123456789;\n        let instance = FieldProjection { field: &field };\n        let v = vec![instance];\n        let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some();\n        //~^ search_is_some\n        let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some();\n        //~^ search_is_some\n        let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some();\n        //~^ search_is_some\n    }\n}\n\nmod issue9120 {\n    fn make_arg_no_deref_impl() -> impl Fn(&&u32) -> bool {\n        move |x: &&u32| **x == 78\n    }\n\n    fn make_arg_no_deref_dyn() -> Box<dyn Fn(&&u32) -> bool> {\n        Box::new(move |x: &&u32| **x == 78)\n    }\n\n    fn wrapper<T: Fn(&&u32) -> bool>(v: Vec<u32>, func: T) -> bool {\n        #[allow(clippy::redundant_closure)]\n        v.iter().find(|x: &&u32| func(x)).is_some()\n        //~^ search_is_some\n    }\n\n    fn do_tests() {\n        let v = vec![3, 2, 1, 0];\n        let arg_no_deref_impl = make_arg_no_deref_impl();\n        let arg_no_deref_dyn = make_arg_no_deref_dyn();\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some();\n        //~^ search_is_some\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some();\n        //~^ search_is_some\n\n        #[allow(clippy::redundant_closure)]\n        let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some();\n        //~^ search_is_some\n    }\n}\n\n// skip this test due to rust-lang/rust-clippy#16086\n/*\n#[allow(clippy::match_like_matches_macro)]\nfn issue15102() {\n    let values = [None, Some(3)];\n    let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some();\n    ~^ search_is_some\n    println!(\"{has_even}\");\n\n    let has_even = values\n        .iter()\n        .find(|v| match v {\n            ~^ search_is_some\n            Some(x) if x % 2 == 0 => true,\n            _ => false,\n        })\n        .is_some();\n    println!(\"{has_even}\");\n}\n*/\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_some.stderr",
    "content": "error: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:9:22\n   |\nLL |     let _ = v.iter().find(|&x| *x < 0).is_some();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| *x < 0)`\n   |\n   = note: `-D clippy::search-is-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:11:20\n   |\nLL |     let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| **y == x)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:14:20\n   |\nLL |     let _ = (0..1).find(|x| *x == 0).is_some();\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:16:22\n   |\nLL |     let _ = v.iter().find(|x| **x == 0).is_some();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| *x == 0)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:18:20\n   |\nLL |     let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some();\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 1 || x == 3 || x == 5)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:20:20\n   |\nLL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some();\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:22:20\n   |\nLL |     let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some();\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0 || [1, 2, 3].contains(&x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:24:20\n   |\nLL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some();\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:27:10\n   |\nLL |           .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)\n   |  __________^\nLL | |\nLL | |         .is_some();\n   | |__________________^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:33:10\n   |\nLL |           .find(|&x| {\n   |  __________^\nLL | |\nLL | |             *x < 0\nLL | |         })\nLL | |         .is_some();\n   | |__________________^\n   |\nhelp: consider using\n   |\nLL ~         .any(|x| {\nLL +\nLL +             *x < 0\nLL ~         });\n   |\n\nerror: called `is_some()` after searching an `Iterator` with `position`\n  --> tests/ui/search_is_some_fixable_some.rs:40:22\n   |\nLL |     let _ = v.iter().position(|&x| x < 0).is_some();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)`\n\nerror: called `is_some()` after searching an `Iterator` with `position`\n  --> tests/ui/search_is_some_fixable_some.rs:45:10\n   |\nLL |           .position(|&x| {\n   |  __________^\nLL | |\nLL | |             x < 0\nLL | |         })\nLL | |         .is_some();\n   | |__________________^\n   |\nhelp: consider using\n   |\nLL ~         .any(|&x| {\nLL +\nLL +             x < 0\nLL ~         });\n   |\n\nerror: called `is_some()` after searching an `Iterator` with `rposition`\n  --> tests/ui/search_is_some_fixable_some.rs:52:22\n   |\nLL |     let _ = v.iter().rposition(|&x| x < 0).is_some();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)`\n\nerror: called `is_some()` after searching an `Iterator` with `rposition`\n  --> tests/ui/search_is_some_fixable_some.rs:57:10\n   |\nLL |           .rposition(|&x| {\n   |  __________^\nLL | |\nLL | |             x < 0\nLL | |         })\nLL | |         .is_some();\n   | |__________________^\n   |\nhelp: consider using\n   |\nLL ~         .any(|&x| {\nLL +\nLL +             x < 0\nLL ~         });\n   |\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:66:27\n   |\nLL |     let _ = \"hello world\".find(\"world\").is_some();\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(\"world\")`\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:68:27\n   |\nLL |     let _ = \"hello world\".find(&s2).is_some();\n   |                           ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:70:27\n   |\nLL |     let _ = \"hello world\".find(&s2[2..]).is_some();\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:73:16\n   |\nLL |     let _ = s1.find(\"world\").is_some();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(\"world\")`\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:75:16\n   |\nLL |     let _ = s1.find(&s2).is_some();\n   |                ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:77:16\n   |\nLL |     let _ = s1.find(&s2[2..]).is_some();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:80:21\n   |\nLL |     let _ = s1[2..].find(\"world\").is_some();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(\"world\")`\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:82:21\n   |\nLL |     let _ = s1[2..].find(&s2).is_some();\n   |                     ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`\n\nerror: called `is_some()` after calling `find()` on a string\n  --> tests/ui/search_is_some_fixable_some.rs:84:21\n   |\nLL |     let _ = s1[2..].find(&s2[2..]).is_some();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:101:44\n   |\nLL |             .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some())\n   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == &cc)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:118:49\n   |\nLL |             .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some())\n   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == cc)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:130:29\n   |\nLL |         let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.foo == 1 && v.bar == 2)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:136:14\n   |\nLL |               .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)\n   |  ______________^\nLL | |\nLL | |             .is_some();\n   | |______________________^ help: consider using: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:143:29\n   |\nLL |         let _ = vfoo.iter().find(|a| a[0] == 42).is_some();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|a| a[0] == 42)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:150:29\n   |\nLL |         let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|sub| sub[1..4].len() == 3)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:169:30\n   |\nLL |         let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some();\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|ppp_x: &&u32| please(ppp_x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:171:50\n   |\nLL |         let _ = [String::from(\"Hey hey\")].iter().find(|s| s.len() == 2).is_some();\n   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s.len() == 2)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:175:26\n   |\nLL |         let _ = v.iter().find(|x| deref_enough(**x)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| deref_enough(*x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:177:26\n   |\nLL |         let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| deref_enough(*x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:181:26\n   |\nLL |         let _ = v.iter().find(|x| arg_no_deref(x)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| arg_no_deref(&x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:184:26\n   |\nLL |         let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref(&x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:207:14\n   |\nLL |               .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)\n   |  ______________^\nLL | |\nLL | |             .is_some();\n   | |______________________^ help: consider using: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:222:29\n   |\nLL |         let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.inner[0].bar == 2)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:228:29\n   |\nLL |         let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| (**x)[0] == 9)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:242:29\n   |\nLL |         let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some();\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.by_ref(&v.bar))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:249:14\n   |\nLL |               .find(|&&&(&x, ref y)| x == *y)\n   |  ______________^\nLL | |\nLL | |             .is_some();\n   | |______________________^ help: consider using: `any(|&&(&x, ref y)| x == *y)`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:270:26\n   |\nLL |         let _ = v.iter().find(|s| s[0].is_empty()).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s[0].is_empty())`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:272:26\n   |\nLL |         let _ = v.iter().find(|s| test_string_1(&s[0])).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| test_string_1(&s[0]))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:282:26\n   |\nLL |         let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| fp.field.is_power_of_two())`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:284:26\n   |\nLL |         let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_1(fp.field))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:286:26\n   |\nLL |         let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_2(*fp.field))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:302:18\n   |\nLL |         v.iter().find(|x: &&u32| func(x)).is_some()\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| func(&x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:312:26\n   |\nLL |         let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_impl(&x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:316:26\n   |\nLL |         let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_dyn(&x))`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some.rs:320:26\n   |\nLL |         let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| (*arg_no_deref_dyn)(&x))`\n\nerror: aborting due to 49 previous errors\n\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_some_2021.fixed",
    "content": "//@edition: 2021\n#![warn(clippy::search_is_some)]\n\nfn main() {\n    fn ref_bindings() {\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y);\n        //~^ search_is_some\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y);\n        //~^ search_is_some\n    }\n}\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_some_2021.rs",
    "content": "//@edition: 2021\n#![warn(clippy::search_is_some)]\n\nfn main() {\n    fn ref_bindings() {\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some();\n        //~^ search_is_some\n        let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some();\n        //~^ search_is_some\n    }\n}\n"
  },
  {
    "path": "tests/ui/search_is_some_fixable_some_2021.stderr",
    "content": "error: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some_2021.rs:6:55\n   |\nLL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some();\n   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)`\n   |\n   = note: `-D clippy::search-is-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`\n\nerror: called `is_some()` after searching an `Iterator` with `find`\n  --> tests/ui/search_is_some_fixable_some_2021.rs:8:55\n   |\nLL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some();\n   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/seek_from_current.fixed",
    "content": "#![warn(clippy::seek_from_current)]\n\nuse std::fs::File;\nuse std::io::{self, Seek, SeekFrom, Write};\n\n#[clippy::msrv = \"1.50\"]\nfn _msrv_1_50() -> io::Result<()> {\n    let mut f = File::create(\"foo.txt\")?;\n    f.write_all(b\"Hi!\")?;\n    f.seek(SeekFrom::Current(0))?;\n    f.seek(SeekFrom::Current(1))?;\n    Ok(())\n}\n\n#[clippy::msrv = \"1.51\"]\nfn _msrv_1_51() -> io::Result<()> {\n    let mut f = File::create(\"foo.txt\")?;\n    f.write_all(b\"Hi!\")?;\n    f.stream_position()?;\n    //~^ seek_from_current\n    f.seek(SeekFrom::Current(1))?;\n    Ok(())\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/seek_from_current.rs",
    "content": "#![warn(clippy::seek_from_current)]\n\nuse std::fs::File;\nuse std::io::{self, Seek, SeekFrom, Write};\n\n#[clippy::msrv = \"1.50\"]\nfn _msrv_1_50() -> io::Result<()> {\n    let mut f = File::create(\"foo.txt\")?;\n    f.write_all(b\"Hi!\")?;\n    f.seek(SeekFrom::Current(0))?;\n    f.seek(SeekFrom::Current(1))?;\n    Ok(())\n}\n\n#[clippy::msrv = \"1.51\"]\nfn _msrv_1_51() -> io::Result<()> {\n    let mut f = File::create(\"foo.txt\")?;\n    f.write_all(b\"Hi!\")?;\n    f.seek(SeekFrom::Current(0))?;\n    //~^ seek_from_current\n    f.seek(SeekFrom::Current(1))?;\n    Ok(())\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/seek_from_current.stderr",
    "content": "error: using `SeekFrom::Current` to start from current position\n  --> tests/ui/seek_from_current.rs:19:5\n   |\nLL |     f.seek(SeekFrom::Current(0))?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `f.stream_position()`\n   |\n   = note: `-D clippy::seek-from-current` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::seek_from_current)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/seek_to_start_instead_of_rewind.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::seek_to_start_instead_of_rewind)]\n\nuse std::fs::OpenOptions;\nuse std::io::{Read, Seek, SeekFrom, Write};\n\nstruct StructWithSeekMethod {}\n\nimpl StructWithSeekMethod {\n    fn seek(&mut self, from: SeekFrom) {}\n}\n\ntrait MySeekTrait {\n    fn seek(&mut self, from: SeekFrom) {}\n}\n\nstruct StructWithSeekTrait {}\nimpl MySeekTrait for StructWithSeekTrait {}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_false_method(t: &mut StructWithSeekMethod) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_method_owned_false(mut t: StructWithSeekMethod) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_false_trait(t: &mut StructWithSeekTrait) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_false_trait_owned(mut t: StructWithSeekTrait) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_false_trait_bound<T: MySeekTrait>(t: &mut T) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should trigger clippy warning\nfn seek_to_start<T: Seek>(t: &mut T) {\n    t.rewind();\n    //~^ seek_to_start_instead_of_rewind\n}\n\n// This should trigger clippy warning\nfn owned_seek_to_start<T: Seek>(mut t: T) {\n    t.rewind();\n    //~^ seek_to_start_instead_of_rewind\n}\n\n// This should NOT trigger clippy warning because\n// it does not seek to start\nfn seek_to_5<T: Seek>(t: &mut T) {\n    t.seek(SeekFrom::Start(5));\n}\n\n// This should NOT trigger clippy warning because\n// it does not seek to start\nfn seek_to_end<T: Seek>(t: &mut T) {\n    t.seek(SeekFrom::End(0));\n}\n\n// This should NOT trigger clippy warning because\n// expr is used here\nfn seek_to_start_in_let<T: Seek>(t: &mut T) {\n    let a = t.seek(SeekFrom::Start(0)).unwrap();\n}\n\nfn main() {\n    let mut f = OpenOptions::new()\n        .write(true)\n        .read(true)\n        .create(true)\n        .truncate(true)\n        .open(\"foo.txt\")\n        .unwrap();\n\n    let mut my_struct_trait = StructWithSeekTrait {};\n    seek_to_start_false_trait_bound(&mut my_struct_trait);\n\n    let hello = \"Hello!\\n\";\n    write!(f, \"{hello}\").unwrap();\n    seek_to_5(&mut f);\n    seek_to_end(&mut f);\n    seek_to_start(&mut f);\n\n    let mut buf = String::new();\n    f.read_to_string(&mut buf).unwrap();\n\n    assert_eq!(&buf, hello);\n}\n\n#[clippy::msrv = \"1.54\"]\nfn msrv_1_54() {\n    let mut f = OpenOptions::new()\n        .write(true)\n        .read(true)\n        .create(true)\n        .truncate(true)\n        .open(\"foo.txt\")\n        .unwrap();\n\n    let hello = \"Hello!\\n\";\n    write!(f, \"{hello}\").unwrap();\n\n    f.seek(SeekFrom::Start(0));\n\n    let mut buf = String::new();\n    f.read_to_string(&mut buf).unwrap();\n\n    assert_eq!(&buf, hello);\n}\n\n#[clippy::msrv = \"1.55\"]\nfn msrv_1_55() {\n    let mut f = OpenOptions::new()\n        .write(true)\n        .read(true)\n        .create(true)\n        .truncate(true)\n        .open(\"foo.txt\")\n        .unwrap();\n\n    let hello = \"Hello!\\n\";\n    write!(f, \"{hello}\").unwrap();\n\n    f.rewind();\n    //~^ seek_to_start_instead_of_rewind\n\n    let mut buf = String::new();\n    f.read_to_string(&mut buf).unwrap();\n\n    assert_eq!(&buf, hello);\n}\n"
  },
  {
    "path": "tests/ui/seek_to_start_instead_of_rewind.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::seek_to_start_instead_of_rewind)]\n\nuse std::fs::OpenOptions;\nuse std::io::{Read, Seek, SeekFrom, Write};\n\nstruct StructWithSeekMethod {}\n\nimpl StructWithSeekMethod {\n    fn seek(&mut self, from: SeekFrom) {}\n}\n\ntrait MySeekTrait {\n    fn seek(&mut self, from: SeekFrom) {}\n}\n\nstruct StructWithSeekTrait {}\nimpl MySeekTrait for StructWithSeekTrait {}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_false_method(t: &mut StructWithSeekMethod) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_method_owned_false(mut t: StructWithSeekMethod) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_false_trait(t: &mut StructWithSeekTrait) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_false_trait_owned(mut t: StructWithSeekTrait) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should NOT trigger clippy warning because\n// StructWithSeekMethod does not implement std::io::Seek;\nfn seek_to_start_false_trait_bound<T: MySeekTrait>(t: &mut T) {\n    t.seek(SeekFrom::Start(0));\n}\n\n// This should trigger clippy warning\nfn seek_to_start<T: Seek>(t: &mut T) {\n    t.seek(SeekFrom::Start(0));\n    //~^ seek_to_start_instead_of_rewind\n}\n\n// This should trigger clippy warning\nfn owned_seek_to_start<T: Seek>(mut t: T) {\n    t.seek(SeekFrom::Start(0));\n    //~^ seek_to_start_instead_of_rewind\n}\n\n// This should NOT trigger clippy warning because\n// it does not seek to start\nfn seek_to_5<T: Seek>(t: &mut T) {\n    t.seek(SeekFrom::Start(5));\n}\n\n// This should NOT trigger clippy warning because\n// it does not seek to start\nfn seek_to_end<T: Seek>(t: &mut T) {\n    t.seek(SeekFrom::End(0));\n}\n\n// This should NOT trigger clippy warning because\n// expr is used here\nfn seek_to_start_in_let<T: Seek>(t: &mut T) {\n    let a = t.seek(SeekFrom::Start(0)).unwrap();\n}\n\nfn main() {\n    let mut f = OpenOptions::new()\n        .write(true)\n        .read(true)\n        .create(true)\n        .truncate(true)\n        .open(\"foo.txt\")\n        .unwrap();\n\n    let mut my_struct_trait = StructWithSeekTrait {};\n    seek_to_start_false_trait_bound(&mut my_struct_trait);\n\n    let hello = \"Hello!\\n\";\n    write!(f, \"{hello}\").unwrap();\n    seek_to_5(&mut f);\n    seek_to_end(&mut f);\n    seek_to_start(&mut f);\n\n    let mut buf = String::new();\n    f.read_to_string(&mut buf).unwrap();\n\n    assert_eq!(&buf, hello);\n}\n\n#[clippy::msrv = \"1.54\"]\nfn msrv_1_54() {\n    let mut f = OpenOptions::new()\n        .write(true)\n        .read(true)\n        .create(true)\n        .truncate(true)\n        .open(\"foo.txt\")\n        .unwrap();\n\n    let hello = \"Hello!\\n\";\n    write!(f, \"{hello}\").unwrap();\n\n    f.seek(SeekFrom::Start(0));\n\n    let mut buf = String::new();\n    f.read_to_string(&mut buf).unwrap();\n\n    assert_eq!(&buf, hello);\n}\n\n#[clippy::msrv = \"1.55\"]\nfn msrv_1_55() {\n    let mut f = OpenOptions::new()\n        .write(true)\n        .read(true)\n        .create(true)\n        .truncate(true)\n        .open(\"foo.txt\")\n        .unwrap();\n\n    let hello = \"Hello!\\n\";\n    write!(f, \"{hello}\").unwrap();\n\n    f.seek(SeekFrom::Start(0));\n    //~^ seek_to_start_instead_of_rewind\n\n    let mut buf = String::new();\n    f.read_to_string(&mut buf).unwrap();\n\n    assert_eq!(&buf, hello);\n}\n"
  },
  {
    "path": "tests/ui/seek_to_start_instead_of_rewind.stderr",
    "content": "error: used `seek` to go to the start of the stream\n  --> tests/ui/seek_to_start_instead_of_rewind.rs:52:7\n   |\nLL |     t.seek(SeekFrom::Start(0));\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`\n   |\n   = note: `-D clippy::seek-to-start-instead-of-rewind` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::seek_to_start_instead_of_rewind)]`\n\nerror: used `seek` to go to the start of the stream\n  --> tests/ui/seek_to_start_instead_of_rewind.rs:58:7\n   |\nLL |     t.seek(SeekFrom::Start(0));\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`\n\nerror: used `seek` to go to the start of the stream\n  --> tests/ui/seek_to_start_instead_of_rewind.rs:138:7\n   |\nLL |     f.seek(SeekFrom::Start(0));\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/self_assignment.rs",
    "content": "#![warn(clippy::self_assignment)]\n#![allow(clippy::useless_vec, clippy::needless_pass_by_ref_mut)]\n\npub struct S<'a> {\n    a: i32,\n    b: [i32; 10],\n    c: Vec<Vec<i32>>,\n    e: &'a mut i32,\n    f: &'a mut i32,\n}\n\npub fn positives(mut a: usize, b: &mut u32, mut s: S) {\n    a = a;\n    //~^ self_assignment\n\n    *b = *b;\n    //~^ self_assignment\n\n    s = s;\n    //~^ self_assignment\n\n    s.a = s.a;\n    //~^ self_assignment\n\n    s.b[9] = s.b[5 + 4];\n    //~^ self_assignment\n\n    s.c[0][1] = s.c[0][1];\n    //~^ self_assignment\n\n    s.b[a] = s.b[a];\n    //~^ self_assignment\n\n    *s.e = *s.e;\n    //~^ self_assignment\n\n    s.b[a + 10] = s.b[10 + a];\n    //~^ self_assignment\n\n    let mut t = (0, 1);\n    t.1 = t.1;\n    //~^ self_assignment\n\n    t.0 = (t.0);\n    //~^ self_assignment\n}\n\npub fn negatives_not_equal(mut a: usize, b: &mut usize, mut s: S) {\n    dbg!(&a);\n    a = *b;\n    dbg!(&a);\n    s.b[1] += s.b[1];\n    s.b[1] = s.b[2];\n    s.c[1][0] = s.c[0][1];\n    s.b[a] = s.b[*b];\n    s.b[a + 10] = s.b[a + 11];\n    *s.e = *s.f;\n\n    let mut t = (0, 1);\n    t.0 = t.1;\n}\n\n#[allow(clippy::mixed_read_write_in_expression)]\npub fn negatives_side_effects() {\n    let mut v = vec![1, 2, 3, 4, 5];\n    let mut i = 0;\n    v[{\n        i += 1;\n        i\n    }] = v[{\n        i += 1;\n        i\n    }];\n\n    fn next(n: &mut usize) -> usize {\n        let v = *n;\n        *n += 1;\n        v\n    }\n\n    let mut w = vec![1, 2, 3, 4, 5];\n    let mut i = 0;\n    let i = &mut i;\n    w[next(i)] = w[next(i)];\n    w[next(i)] = w[next(i)];\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/self_assignment.stderr",
    "content": "error: self-assignment of `a` to `a`\n  --> tests/ui/self_assignment.rs:13:5\n   |\nLL |     a = a;\n   |     ^^^^^\n   |\n   = note: `-D clippy::self-assignment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::self_assignment)]`\n\nerror: self-assignment of `*b` to `*b`\n  --> tests/ui/self_assignment.rs:16:5\n   |\nLL |     *b = *b;\n   |     ^^^^^^^\n\nerror: self-assignment of `s` to `s`\n  --> tests/ui/self_assignment.rs:19:5\n   |\nLL |     s = s;\n   |     ^^^^^\n\nerror: self-assignment of `s.a` to `s.a`\n  --> tests/ui/self_assignment.rs:22:5\n   |\nLL |     s.a = s.a;\n   |     ^^^^^^^^^\n\nerror: self-assignment of `s.b[5 + 4]` to `s.b[9]`\n  --> tests/ui/self_assignment.rs:25:5\n   |\nLL |     s.b[9] = s.b[5 + 4];\n   |     ^^^^^^^^^^^^^^^^^^^\n\nerror: self-assignment of `s.c[0][1]` to `s.c[0][1]`\n  --> tests/ui/self_assignment.rs:28:5\n   |\nLL |     s.c[0][1] = s.c[0][1];\n   |     ^^^^^^^^^^^^^^^^^^^^^\n\nerror: self-assignment of `s.b[a]` to `s.b[a]`\n  --> tests/ui/self_assignment.rs:31:5\n   |\nLL |     s.b[a] = s.b[a];\n   |     ^^^^^^^^^^^^^^^\n\nerror: self-assignment of `*s.e` to `*s.e`\n  --> tests/ui/self_assignment.rs:34:5\n   |\nLL |     *s.e = *s.e;\n   |     ^^^^^^^^^^^\n\nerror: self-assignment of `s.b[10 + a]` to `s.b[a + 10]`\n  --> tests/ui/self_assignment.rs:37:5\n   |\nLL |     s.b[a + 10] = s.b[10 + a];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: self-assignment of `t.1` to `t.1`\n  --> tests/ui/self_assignment.rs:41:5\n   |\nLL |     t.1 = t.1;\n   |     ^^^^^^^^^\n\nerror: self-assignment of `(t.0)` to `t.0`\n  --> tests/ui/self_assignment.rs:44:5\n   |\nLL |     t.0 = (t.0);\n   |     ^^^^^^^^^^^\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/self_named_constructors.rs",
    "content": "#![warn(clippy::self_named_constructors)]\n\nstruct ShouldSpawn;\nstruct ShouldNotSpawn;\n\nimpl ShouldSpawn {\n    pub fn should_spawn() -> ShouldSpawn {\n        //~^ self_named_constructors\n\n        ShouldSpawn\n    }\n\n    fn should_not_spawn() -> ShouldNotSpawn {\n        ShouldNotSpawn\n    }\n}\n\nimpl ShouldNotSpawn {\n    pub fn new() -> ShouldNotSpawn {\n        ShouldNotSpawn\n    }\n}\n\nstruct ShouldNotSpawnWithTrait;\n\ntrait ShouldNotSpawnTrait {\n    type Item;\n}\n\nimpl ShouldNotSpawnTrait for ShouldNotSpawnWithTrait {\n    type Item = Self;\n}\n\nimpl ShouldNotSpawnWithTrait {\n    pub fn should_not_spawn_with_trait() -> impl ShouldNotSpawnTrait<Item = Self> {\n        ShouldNotSpawnWithTrait\n    }\n}\n\n// Same trait name and same type name should not spawn the lint\n#[derive(Default)]\npub struct Default;\n\ntrait TraitSameTypeName {\n    fn should_not_spawn() -> Self;\n}\nimpl TraitSameTypeName for ShouldNotSpawn {\n    fn should_not_spawn() -> Self {\n        ShouldNotSpawn\n    }\n}\n\nstruct SelfMethodShouldNotSpawn;\n\nimpl SelfMethodShouldNotSpawn {\n    fn self_method_should_not_spawn(self) -> Self {\n        SelfMethodShouldNotSpawn\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/self_named_constructors.stderr",
    "content": "error: constructor `should_spawn` has the same name as the type\n  --> tests/ui/self_named_constructors.rs:7:5\n   |\nLL | /     pub fn should_spawn() -> ShouldSpawn {\nLL | |\nLL | |\nLL | |         ShouldSpawn\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::self-named-constructors` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::self_named_constructors)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/semicolon_if_nothing_returned.fixed",
    "content": "//@aux-build:proc_macro_attr.rs\n\n#![warn(clippy::semicolon_if_nothing_returned)]\n#![allow(\n    clippy::redundant_closure,\n    clippy::uninlined_format_args,\n    clippy::needless_late_init,\n    clippy::empty_docs\n)]\n\n#[macro_use]\nextern crate proc_macro_attr;\n\nfn get_unit() {}\n\n// the functions below trigger the lint\nfn main() {\n    println!(\"Hello\");\n    //~^ semicolon_if_nothing_returned\n}\n\nfn hello() {\n    get_unit();\n    //~^ semicolon_if_nothing_returned\n}\n\nfn basic101(x: i32) {\n    let y: i32;\n    y = x + 1;\n    //~^ semicolon_if_nothing_returned\n}\n\n#[rustfmt::skip]\nfn closure_error() {\n    let _d = || {\n        hello();\n        //~^ semicolon_if_nothing_returned\n    };\n}\n\n#[rustfmt::skip]\nfn unsafe_checks_error() {\n    use std::mem::MaybeUninit;\n    use std::ptr;\n\n    let mut s = MaybeUninit::<String>::uninit();\n    let _d = || unsafe {\n        ptr::drop_in_place(s.as_mut_ptr());\n        //~^ semicolon_if_nothing_returned\n    };\n}\n\n// this is fine\nfn print_sum(a: i32, b: i32) {\n    println!(\"{}\", a + b);\n    assert_eq!(true, false);\n}\n\nfn foo(x: i32) {\n    let y: i32;\n    if x < 1 {\n        y = 4;\n    } else {\n        y = 5;\n    }\n}\n\nfn bar(x: i32) {\n    let y: i32;\n    match x {\n        1 => y = 4,\n        _ => y = 32,\n    }\n}\n\nfn foobar(x: i32) {\n    let y: i32;\n    'label: {\n        y = x + 1;\n    }\n}\n\nfn loop_test(x: i32) {\n    let y: i32;\n    for &ext in &[\"stdout\", \"stderr\", \"fixed\"] {\n        println!(\"{}\", ext);\n    }\n}\n\nfn closure() {\n    let _d = || hello();\n}\n\n#[rustfmt::skip]\nfn closure_block() {\n    let _d = || { hello() };\n}\n\nunsafe fn some_unsafe_op() {}\nunsafe fn some_other_unsafe_fn() {}\n\nfn do_something() {\n    unsafe { some_unsafe_op() };\n\n    unsafe { some_other_unsafe_fn() };\n}\n\nfn unsafe_checks() {\n    use std::mem::MaybeUninit;\n    use std::ptr;\n\n    let mut s = MaybeUninit::<String>::uninit();\n    let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()) };\n}\n\n// Issue #7768\n#[rustfmt::skip]\nfn macro_with_semicolon() {\n    macro_rules! repro {\n        () => {\n            while false {\n            }\n        };\n    }\n    repro!();\n}\n\nfn function_returning_option() -> Option<i32> {\n    Some(1)\n}\n\n// No warning\nfn let_else_stmts() {\n    let Some(x) = function_returning_option() else {\n        return;\n    };\n}\n\nmod issue12123 {\n    #[rustfmt::skip]\n    mod this_triggers {\n        #[fake_main]\n        async fn main() {\n\n        }\n    }\n\n    mod and_this {\n        #[fake_main]\n        async fn main() {\n            println!(\"hello\");\n        }\n    }\n\n    #[rustfmt::skip]\n    mod maybe_this {\n        /** */ #[fake_main]\n        async fn main() {\n        }\n    }\n\n    mod but_this_does_not {\n        #[fake_main]\n        async fn main() {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/semicolon_if_nothing_returned.rs",
    "content": "//@aux-build:proc_macro_attr.rs\n\n#![warn(clippy::semicolon_if_nothing_returned)]\n#![allow(\n    clippy::redundant_closure,\n    clippy::uninlined_format_args,\n    clippy::needless_late_init,\n    clippy::empty_docs\n)]\n\n#[macro_use]\nextern crate proc_macro_attr;\n\nfn get_unit() {}\n\n// the functions below trigger the lint\nfn main() {\n    println!(\"Hello\")\n    //~^ semicolon_if_nothing_returned\n}\n\nfn hello() {\n    get_unit()\n    //~^ semicolon_if_nothing_returned\n}\n\nfn basic101(x: i32) {\n    let y: i32;\n    y = x + 1\n    //~^ semicolon_if_nothing_returned\n}\n\n#[rustfmt::skip]\nfn closure_error() {\n    let _d = || {\n        hello()\n        //~^ semicolon_if_nothing_returned\n    };\n}\n\n#[rustfmt::skip]\nfn unsafe_checks_error() {\n    use std::mem::MaybeUninit;\n    use std::ptr;\n\n    let mut s = MaybeUninit::<String>::uninit();\n    let _d = || unsafe {\n        ptr::drop_in_place(s.as_mut_ptr())\n        //~^ semicolon_if_nothing_returned\n    };\n}\n\n// this is fine\nfn print_sum(a: i32, b: i32) {\n    println!(\"{}\", a + b);\n    assert_eq!(true, false);\n}\n\nfn foo(x: i32) {\n    let y: i32;\n    if x < 1 {\n        y = 4;\n    } else {\n        y = 5;\n    }\n}\n\nfn bar(x: i32) {\n    let y: i32;\n    match x {\n        1 => y = 4,\n        _ => y = 32,\n    }\n}\n\nfn foobar(x: i32) {\n    let y: i32;\n    'label: {\n        y = x + 1;\n    }\n}\n\nfn loop_test(x: i32) {\n    let y: i32;\n    for &ext in &[\"stdout\", \"stderr\", \"fixed\"] {\n        println!(\"{}\", ext);\n    }\n}\n\nfn closure() {\n    let _d = || hello();\n}\n\n#[rustfmt::skip]\nfn closure_block() {\n    let _d = || { hello() };\n}\n\nunsafe fn some_unsafe_op() {}\nunsafe fn some_other_unsafe_fn() {}\n\nfn do_something() {\n    unsafe { some_unsafe_op() };\n\n    unsafe { some_other_unsafe_fn() };\n}\n\nfn unsafe_checks() {\n    use std::mem::MaybeUninit;\n    use std::ptr;\n\n    let mut s = MaybeUninit::<String>::uninit();\n    let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()) };\n}\n\n// Issue #7768\n#[rustfmt::skip]\nfn macro_with_semicolon() {\n    macro_rules! repro {\n        () => {\n            while false {\n            }\n        };\n    }\n    repro!();\n}\n\nfn function_returning_option() -> Option<i32> {\n    Some(1)\n}\n\n// No warning\nfn let_else_stmts() {\n    let Some(x) = function_returning_option() else {\n        return;\n    };\n}\n\nmod issue12123 {\n    #[rustfmt::skip]\n    mod this_triggers {\n        #[fake_main]\n        async fn main() {\n\n        }\n    }\n\n    mod and_this {\n        #[fake_main]\n        async fn main() {\n            println!(\"hello\");\n        }\n    }\n\n    #[rustfmt::skip]\n    mod maybe_this {\n        /** */ #[fake_main]\n        async fn main() {\n        }\n    }\n\n    mod but_this_does_not {\n        #[fake_main]\n        async fn main() {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/semicolon_if_nothing_returned.stderr",
    "content": "error: consider adding a `;` to the last statement for consistent formatting\n  --> tests/ui/semicolon_if_nothing_returned.rs:18:5\n   |\nLL |     println!(\"Hello\")\n   |     ^^^^^^^^^^^^^^^^^ help: add a `;` here: `println!(\"Hello\");`\n   |\n   = note: `-D clippy::semicolon-if-nothing-returned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::semicolon_if_nothing_returned)]`\n\nerror: consider adding a `;` to the last statement for consistent formatting\n  --> tests/ui/semicolon_if_nothing_returned.rs:23:5\n   |\nLL |     get_unit()\n   |     ^^^^^^^^^^ help: add a `;` here: `get_unit();`\n\nerror: consider adding a `;` to the last statement for consistent formatting\n  --> tests/ui/semicolon_if_nothing_returned.rs:29:5\n   |\nLL |     y = x + 1\n   |     ^^^^^^^^^ help: add a `;` here: `y = x + 1;`\n\nerror: consider adding a `;` to the last statement for consistent formatting\n  --> tests/ui/semicolon_if_nothing_returned.rs:36:9\n   |\nLL |         hello()\n   |         ^^^^^^^ help: add a `;` here: `hello();`\n\nerror: consider adding a `;` to the last statement for consistent formatting\n  --> tests/ui/semicolon_if_nothing_returned.rs:48:9\n   |\nLL |         ptr::drop_in_place(s.as_mut_ptr())\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/semicolon_inside_block.fixed",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop,\n    clippy::double_parens\n)]\n#![warn(clippy::semicolon_inside_block)]\n#![feature(try_blocks)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block(); }\n    //~^ semicolon_inside_block\n    unsafe { unit_fn_block(); }\n    //~^ semicolon_inside_block\n\n    { unit_fn_block(); }\n    unsafe { unit_fn_block(); }\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n    //~^ semicolon_inside_block\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()); }\n    //~^ semicolon_inside_block\n    { m!(()); }\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unit_fn_block()\n}\n\n#[rustfmt::skip]\nfn issue15380() {\n    ( {0;0});\n\n    ({\n        0;\n        0\n    });\n\n    (({ 0 }))      ;\n\n    ( ( { 0 } ) ) ;\n}\n\npub fn issue15388() {\n    #[rustfmt::skip]\n    {0; 0};\n}\n\nfn issue_try_blocks() {\n    // try blocks should NOT trigger semicolon_inside_block:\n    // moving `;` inside changes the return type (e.g. `Option<i32>` -> `Option<()>`)\n    // which in turn changes the type constraints on `?` operators inside the block,\n    // causing type errors.\n    try { Some(1)? };\n}\n"
  },
  {
    "path": "tests/ui/semicolon_inside_block.rs",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop,\n    clippy::double_parens\n)]\n#![warn(clippy::semicolon_inside_block)]\n#![feature(try_blocks)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    //~^ semicolon_inside_block\n    unsafe { unit_fn_block() };\n    //~^ semicolon_inside_block\n\n    { unit_fn_block(); }\n    unsafe { unit_fn_block(); }\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n    //~^ semicolon_inside_block\n        unit_fn_block();\n        unit_fn_block()\n    };\n    {\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    //~^ semicolon_inside_block\n    { m!(()); }\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unit_fn_block()\n}\n\n#[rustfmt::skip]\nfn issue15380() {\n    ( {0;0});\n\n    ({\n        0;\n        0\n    });\n\n    (({ 0 }))      ;\n\n    ( ( { 0 } ) ) ;\n}\n\npub fn issue15388() {\n    #[rustfmt::skip]\n    {0; 0};\n}\n\nfn issue_try_blocks() {\n    // try blocks should NOT trigger semicolon_inside_block:\n    // moving `;` inside changes the return type (e.g. `Option<i32>` -> `Option<()>`)\n    // which in turn changes the type constraints on `?` operators inside the block,\n    // causing type errors.\n    try { Some(1)? };\n}\n"
  },
  {
    "path": "tests/ui/semicolon_inside_block.stderr",
    "content": "error: consider moving the `;` inside the block for consistent formatting\n  --> tests/ui/semicolon_inside_block.rs:40:5\n   |\nLL |     { unit_fn_block() };\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::semicolon-inside-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::semicolon_inside_block)]`\nhelp: put the `;` here\n   |\nLL -     { unit_fn_block() };\nLL +     { unit_fn_block(); }\n   |\n\nerror: consider moving the `;` inside the block for consistent formatting\n  --> tests/ui/semicolon_inside_block.rs:42:5\n   |\nLL |     unsafe { unit_fn_block() };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: put the `;` here\n   |\nLL -     unsafe { unit_fn_block() };\nLL +     unsafe { unit_fn_block(); }\n   |\n\nerror: consider moving the `;` inside the block for consistent formatting\n  --> tests/ui/semicolon_inside_block.rs:51:5\n   |\nLL | /     {\nLL | |\nLL | |         unit_fn_block();\nLL | |         unit_fn_block()\nLL | |     };\n   | |______^\n   |\nhelp: put the `;` here\n   |\nLL ~         unit_fn_block();\nLL ~     }\n   |\n\nerror: consider moving the `;` inside the block for consistent formatting\n  --> tests/ui/semicolon_inside_block.rs:65:5\n   |\nLL |     { m!(()) };\n   |     ^^^^^^^^^^^\n   |\nhelp: put the `;` here\n   |\nLL -     { m!(()) };\nLL +     { m!(()); }\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/semicolon_inside_block_stmt_expr_attrs.fixed",
    "content": "// Test when the feature `stmt_expr_attributes` is enabled\n\n#![feature(stmt_expr_attributes)]\n#![allow(clippy::no_effect)]\n#![warn(clippy::semicolon_inside_block)]\n\npub fn issue15388() {\n    #[rustfmt::skip]\n    {0; 0;}\n    //~^ semicolon_inside_block\n}\n"
  },
  {
    "path": "tests/ui/semicolon_inside_block_stmt_expr_attrs.rs",
    "content": "// Test when the feature `stmt_expr_attributes` is enabled\n\n#![feature(stmt_expr_attributes)]\n#![allow(clippy::no_effect)]\n#![warn(clippy::semicolon_inside_block)]\n\npub fn issue15388() {\n    #[rustfmt::skip]\n    {0; 0};\n    //~^ semicolon_inside_block\n}\n"
  },
  {
    "path": "tests/ui/semicolon_inside_block_stmt_expr_attrs.stderr",
    "content": "error: consider moving the `;` inside the block for consistent formatting\n  --> tests/ui/semicolon_inside_block_stmt_expr_attrs.rs:9:5\n   |\nLL |     {0; 0};\n   |     ^^^^^^^\n   |\n   = note: `-D clippy::semicolon-inside-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::semicolon_inside_block)]`\nhelp: put the `;` here\n   |\nLL -     {0; 0};\nLL +     {0; 0;}\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/semicolon_outside_block.fixed",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop\n)]\n#![warn(clippy::semicolon_outside_block)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    unsafe { unit_fn_block() };\n\n    { unit_fn_block() };\n    //~^ semicolon_outside_block\n    unsafe { unit_fn_block() };\n    //~^ semicolon_outside_block\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n        unit_fn_block();\n        unit_fn_block()\n    };\n    {\n    //~^ semicolon_outside_block\n        unit_fn_block();\n        unit_fn_block()\n    };\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    { m!(()) };\n    //~^ semicolon_outside_block\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unsafe {\n    //~^ semicolon_outside_block\n        std::arch::asm!(\"\")\n    };\n\n    {\n    //~^ semicolon_outside_block\n        line!()\n    };\n\n    unit_fn_block()\n}\n\nfn issue14926() {\n    macro_rules! gen_code {\n        [$l:lifetime: $b:block, $b2: block $(,)?] => {\n            $l: loop {\n                $b\n                break $l;\n            }\n            $l: loop {\n                $b2\n                break $l;\n            }\n        };\n    }\n\n    gen_code! {\n        'root:\n        {\n            println!(\"Block1\");\n        },\n        {\n            println!(\"Block2\");\n        },\n    }\n}\n"
  },
  {
    "path": "tests/ui/semicolon_outside_block.rs",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop\n)]\n#![warn(clippy::semicolon_outside_block)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    unsafe { unit_fn_block() };\n\n    { unit_fn_block(); }\n    //~^ semicolon_outside_block\n    unsafe { unit_fn_block(); }\n    //~^ semicolon_outside_block\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n        unit_fn_block();\n        unit_fn_block()\n    };\n    {\n    //~^ semicolon_outside_block\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    { m!(()); }\n    //~^ semicolon_outside_block\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unsafe {\n    //~^ semicolon_outside_block\n        std::arch::asm!(\"\");\n    }\n\n    {\n    //~^ semicolon_outside_block\n        line!();\n    }\n\n    unit_fn_block()\n}\n\nfn issue14926() {\n    macro_rules! gen_code {\n        [$l:lifetime: $b:block, $b2: block $(,)?] => {\n            $l: loop {\n                $b\n                break $l;\n            }\n            $l: loop {\n                $b2\n                break $l;\n            }\n        };\n    }\n\n    gen_code! {\n        'root:\n        {\n            println!(\"Block1\");\n        },\n        {\n            println!(\"Block2\");\n        },\n    }\n}\n"
  },
  {
    "path": "tests/ui/semicolon_outside_block.stderr",
    "content": "error: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui/semicolon_outside_block.rs:41:5\n   |\nLL |     { unit_fn_block(); }\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::semicolon-outside-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::semicolon_outside_block)]`\nhelp: put the `;` here\n   |\nLL -     { unit_fn_block(); }\nLL +     { unit_fn_block() };\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui/semicolon_outside_block.rs:43:5\n   |\nLL |     unsafe { unit_fn_block(); }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: put the `;` here\n   |\nLL -     unsafe { unit_fn_block(); }\nLL +     unsafe { unit_fn_block() };\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui/semicolon_outside_block.rs:53:5\n   |\nLL | /     {\nLL | |\nLL | |         unit_fn_block();\nLL | |         unit_fn_block();\nLL | |     }\n   | |_____^\n   |\nhelp: put the `;` here\n   |\nLL ~         unit_fn_block()\nLL ~     };\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui/semicolon_outside_block.rs:64:5\n   |\nLL |     { m!(()); }\n   |     ^^^^^^^^^^^\n   |\nhelp: put the `;` here\n   |\nLL -     { m!(()); }\nLL +     { m!(()) };\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui/semicolon_outside_block.rs:87:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         std::arch::asm!(\"\");\nLL | |     }\n   | |_____^\n   |\nhelp: put the `;` here\n   |\nLL ~         std::arch::asm!(\"\")\nLL ~     };\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui/semicolon_outside_block.rs:92:5\n   |\nLL | /     {\nLL | |\nLL | |         line!();\nLL | |     }\n   | |_____^\n   |\nhelp: put the `;` here\n   |\nLL ~         line!()\nLL ~     };\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/serde.rs",
    "content": "#![warn(clippy::serde_api_misuse)]\n#![allow(dead_code, clippy::needless_lifetimes)]\n\nextern crate serde;\n\nstruct A;\n\nimpl<'de> serde::de::Visitor<'de> for A {\n    type Value = ();\n\n    fn expecting(&self, _: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n        unimplemented!()\n    }\n\n    fn visit_str<E>(self, _v: &str) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        unimplemented!()\n    }\n\n    fn visit_string<E>(self, _v: String) -> Result<Self::Value, E>\n    where\n        E: serde::de::Error,\n    {\n        unimplemented!()\n    }\n}\n\nstruct B;\n\nimpl<'de> serde::de::Visitor<'de> for B {\n    type Value = ();\n\n    fn expecting(&self, _: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {\n        unimplemented!()\n    }\n\n    fn visit_string<E>(self, _v: String) -> Result<Self::Value, E>\n    //~^ serde_api_misuse\n    where\n        E: serde::de::Error,\n    {\n        unimplemented!()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/serde.stderr",
    "content": "error: you should not implement `visit_string` without also implementing `visit_str`\n  --> tests/ui/serde.rs:39:5\n   |\nLL | /     fn visit_string<E>(self, _v: String) -> Result<Self::Value, E>\nLL | |\nLL | |     where\nLL | |         E: serde::de::Error,\n   | |____________________________^\n   |\n   = note: `-D clippy::serde-api-misuse` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::serde_api_misuse)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/set_contains_or_insert.rs",
    "content": "#![allow(unused)]\n#![allow(clippy::nonminimal_bool)]\n#![allow(clippy::needless_borrow)]\n#![warn(clippy::set_contains_or_insert)]\n\nuse std::collections::{BTreeSet, HashSet};\n\nfn should_warn_hashset() {\n    let mut set = HashSet::new();\n    let value = 5;\n\n    if !set.contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n        println!(\"Just a comment\");\n    }\n\n    if set.contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n        println!(\"Just a comment\");\n    }\n\n    if !set.contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n    }\n\n    if !!set.contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n        println!(\"Just a comment\");\n    }\n\n    if (&set).contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n    }\n\n    let borrow_value = &6;\n    if !set.contains(borrow_value) {\n        //~^ set_contains_or_insert\n        set.insert(*borrow_value);\n    }\n\n    let borrow_set = &mut set;\n    if !borrow_set.contains(&value) {\n        //~^ set_contains_or_insert\n        borrow_set.insert(value);\n    }\n}\n\nfn should_not_warn_hashset() {\n    let mut set = HashSet::new();\n    let value = 5;\n    let another_value = 6;\n\n    if !set.contains(&value) {\n        set.insert(another_value);\n    }\n\n    if !set.contains(&value) {\n        println!(\"Just a comment\");\n    }\n\n    if simply_true() {\n        set.insert(value);\n    }\n\n    if !set.contains(&value) {\n        set.replace(value); //it is not insert\n        println!(\"Just a comment\");\n    }\n\n    if set.contains(&value) {\n        println!(\"value is already in set\");\n    } else {\n        set.insert(value);\n    }\n}\n\nfn should_warn_btreeset() {\n    let mut set = BTreeSet::new();\n    let value = 5;\n\n    if !set.contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n        println!(\"Just a comment\");\n    }\n\n    if set.contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n        println!(\"Just a comment\");\n    }\n\n    if !set.contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n    }\n\n    if !!set.contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n        println!(\"Just a comment\");\n    }\n\n    if (&set).contains(&value) {\n        //~^ set_contains_or_insert\n        set.insert(value);\n    }\n\n    let borrow_value = &6;\n    if !set.contains(borrow_value) {\n        //~^ set_contains_or_insert\n        set.insert(*borrow_value);\n    }\n\n    let borrow_set = &mut set;\n    if !borrow_set.contains(&value) {\n        //~^ set_contains_or_insert\n        borrow_set.insert(value);\n    }\n}\n\nfn should_not_warn_btreeset() {\n    let mut set = BTreeSet::new();\n    let value = 5;\n    let another_value = 6;\n\n    if !set.contains(&value) {\n        set.insert(another_value);\n    }\n\n    if !set.contains(&value) {\n        println!(\"Just a comment\");\n    }\n\n    if simply_true() {\n        set.insert(value);\n    }\n\n    if !set.contains(&value) {\n        set.replace(value); //it is not insert\n        println!(\"Just a comment\");\n    }\n\n    if set.contains(&value) {\n        println!(\"value is already in set\");\n    } else {\n        set.insert(value);\n    }\n}\n\nfn simply_true() -> bool {\n    true\n}\n\nfn main() {}\n\nfn issue15990(s: &mut HashSet<usize>, v: usize) {\n    if !s.contains(&v) {\n        s.clear();\n        s.insert(v);\n    }\n\n    fn borrow_as_mut(v: usize, s: &mut HashSet<usize>) {\n        s.clear();\n    }\n    if !s.contains(&v) {\n        borrow_as_mut(v, s);\n        s.insert(v);\n    }\n\n    if !s.contains(&v) {\n        //~^ set_contains_or_insert\n        let _readonly_access = s.contains(&v);\n        s.insert(v);\n    }\n}\n"
  },
  {
    "path": "tests/ui/set_contains_or_insert.stderr",
    "content": "error: usage of `HashSet::insert` after `HashSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:12:13\n   |\nLL |     if !set.contains(&value) {\n   |             ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::set-contains-or-insert` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::set_contains_or_insert)]`\n\nerror: usage of `HashSet::insert` after `HashSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:18:12\n   |\nLL |     if set.contains(&value) {\n   |            ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `HashSet::insert` after `HashSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:24:13\n   |\nLL |     if !set.contains(&value) {\n   |             ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `HashSet::insert` after `HashSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:29:14\n   |\nLL |     if !!set.contains(&value) {\n   |              ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `HashSet::insert` after `HashSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:35:15\n   |\nLL |     if (&set).contains(&value) {\n   |               ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `HashSet::insert` after `HashSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:41:13\n   |\nLL |     if !set.contains(borrow_value) {\n   |             ^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(*borrow_value);\n   |             ^^^^^^^^^^^^^^^^^^^^^\n\nerror: usage of `HashSet::insert` after `HashSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:47:20\n   |\nLL |     if !borrow_set.contains(&value) {\n   |                    ^^^^^^^^^^^^^^^^\nLL |\nLL |         borrow_set.insert(value);\n   |                    ^^^^^^^^^^^^^\n\nerror: usage of `BTreeSet::insert` after `BTreeSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:86:13\n   |\nLL |     if !set.contains(&value) {\n   |             ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `BTreeSet::insert` after `BTreeSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:92:12\n   |\nLL |     if set.contains(&value) {\n   |            ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `BTreeSet::insert` after `BTreeSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:98:13\n   |\nLL |     if !set.contains(&value) {\n   |             ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `BTreeSet::insert` after `BTreeSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:103:14\n   |\nLL |     if !!set.contains(&value) {\n   |              ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `BTreeSet::insert` after `BTreeSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:109:15\n   |\nLL |     if (&set).contains(&value) {\n   |               ^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(value);\n   |             ^^^^^^^^^^^^^\n\nerror: usage of `BTreeSet::insert` after `BTreeSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:115:13\n   |\nLL |     if !set.contains(borrow_value) {\n   |             ^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         set.insert(*borrow_value);\n   |             ^^^^^^^^^^^^^^^^^^^^^\n\nerror: usage of `BTreeSet::insert` after `BTreeSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:121:20\n   |\nLL |     if !borrow_set.contains(&value) {\n   |                    ^^^^^^^^^^^^^^^^\nLL |\nLL |         borrow_set.insert(value);\n   |                    ^^^^^^^^^^^^^\n\nerror: usage of `HashSet::insert` after `HashSet::contains`\n  --> tests/ui/set_contains_or_insert.rs:176:11\n   |\nLL |     if !s.contains(&v) {\n   |           ^^^^^^^^^^^^\n...\nLL |         s.insert(v);\n   |           ^^^^^^^^^\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/shadow.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)]\n#![allow(\n    clippy::let_unit_value,\n    clippy::needless_ifs,\n    clippy::redundant_guards,\n    clippy::redundant_locals\n)]\n\nextern crate proc_macro_derive;\n\n#[derive(proc_macro_derive::ShadowDerive)]\npub struct Nothing;\n\nmacro_rules! reuse {\n    ($v:ident) => {\n        let $v = $v + 1;\n    };\n}\n\nfn shadow_same() {\n    let x = 1;\n    let x = x;\n    //~^ shadow_same\n    let mut x = &x;\n    //~^ shadow_same\n    let x = &mut x;\n    //~^ shadow_same\n    let x = *x;\n    //~^ shadow_same\n}\n\nfn shadow_reuse() -> Option<()> {\n    let x = ([[0]], ());\n    let x = x.0;\n    //~^ shadow_reuse\n    let x = x[0];\n    //~^ shadow_reuse\n    let [x] = x;\n    //~^ shadow_reuse\n    let x = Some(x);\n    //~^ shadow_reuse\n    let x = foo(x);\n    //~^ shadow_reuse\n    let x = || x;\n    //~^ shadow_reuse\n    let x = Some(1).map(|_| x)?;\n    //~^ shadow_reuse\n    let y = 1;\n    let y = match y {\n        //~^ shadow_reuse\n        1 => 2,\n        _ => 3,\n    };\n    None\n}\n\nfn shadow_reuse_macro() {\n    let x = 1;\n    // this should not warn\n    reuse!(x);\n}\n\nfn shadow_unrelated() {\n    let x = 1;\n    let x = 2;\n    //~^ shadow_unrelated\n}\n\nfn syntax() {\n    fn f(x: u32) {\n        let x = 1;\n        //~^ shadow_unrelated\n    }\n    let x = 1;\n    match Some(1) {\n        Some(1) => {},\n        Some(x) => {\n            //~^ shadow_unrelated\n            let x = 1;\n            //~^ shadow_unrelated\n        },\n        _ => {},\n    }\n    if let Some(x) = Some(1) {}\n    //~^ shadow_unrelated\n    while let Some(x) = Some(1) {}\n    //~^ shadow_unrelated\n    let _ = |[x]: [u32; 1]| {\n        //~^ shadow_unrelated\n        let x = 1;\n        //~^ shadow_unrelated\n    };\n    let y = Some(1);\n    if let Some(y) = y {}\n    //~^ shadow_reuse\n}\n\nfn negative() {\n    match Some(1) {\n        Some(x) if x == 1 => {},\n        Some(x) => {},\n        None => {},\n    }\n    match [None, Some(1)] {\n        [Some(x), None] | [None, Some(x)] => {},\n        _ => {},\n    }\n    if let Some(x) = Some(1) {\n        let y = 1;\n    } else {\n        let x = 1;\n        let y = 1;\n    }\n    let x = 1;\n    #[allow(clippy::shadow_unrelated)]\n    let x = 1;\n}\n\nfn foo<T>(_: T) {}\n\nfn question_mark() -> Option<()> {\n    let val = 1;\n    // `?` expands with a `val` binding\n    None?;\n    None\n}\n\npub async fn foo1(_a: i32) {}\n\npub async fn foo2(_a: i32, _b: i64) {\n    let _b = _a;\n    //~^ shadow_unrelated\n}\n\nfn ice_8748() {\n    let _ = [0; {\n        let x = 1;\n        if let Some(x) = Some(1) { x } else { 1 }\n        //~^ shadow_unrelated\n    }];\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/10780\nfn shadow_closure() {\n    // These are not shadow_unrelated; but they are correctly shadow_reuse\n    let x = Some(1);\n    #[allow(clippy::shadow_reuse)]\n    let y = x.map(|x| x + 1);\n    let z = x.map(|x| x + 1);\n    //~^ shadow_reuse\n    let a: Vec<Option<u8>> = [100u8, 120, 140]\n        .iter()\n        .map(|i| i.checked_mul(2))\n        .map(|i| i.map(|i| i - 10))\n        //~^ shadow_reuse\n        .collect();\n}\n\nstruct Issue13795 {\n    value: i32,\n}\n\nfn issue13795(value: Issue13795) {\n    let Issue13795 { value, .. } = value;\n    //~^ shadow_same\n}\n\nfn issue14377() {\n    let a;\n    let b;\n    (a, b) = (0, 1);\n\n    struct S {\n        c: i32,\n        d: i32,\n    }\n\n    let c;\n    let d;\n    S { c, d } = S { c: 1, d: 2 };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/shadow.stderr",
    "content": "error: `x` is shadowed by itself in `x`\n  --> tests/ui/shadow.rs:24:9\n   |\nLL |     let x = x;\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:23:9\n   |\nLL |     let x = 1;\n   |         ^\n   = note: `-D clippy::shadow-same` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::shadow_same)]`\n\nerror: `mut x` is shadowed by itself in `&x`\n  --> tests/ui/shadow.rs:26:13\n   |\nLL |     let mut x = &x;\n   |             ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:24:9\n   |\nLL |     let x = x;\n   |         ^\n\nerror: `x` is shadowed by itself in `&mut x`\n  --> tests/ui/shadow.rs:28:9\n   |\nLL |     let x = &mut x;\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:26:9\n   |\nLL |     let mut x = &x;\n   |         ^^^^^\n\nerror: `x` is shadowed by itself in `*x`\n  --> tests/ui/shadow.rs:30:9\n   |\nLL |     let x = *x;\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:28:9\n   |\nLL |     let x = &mut x;\n   |         ^\n\nerror: `x` is shadowed\n  --> tests/ui/shadow.rs:36:9\n   |\nLL |     let x = x.0;\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:35:9\n   |\nLL |     let x = ([[0]], ());\n   |         ^\n   = note: `-D clippy::shadow-reuse` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::shadow_reuse)]`\n\nerror: `x` is shadowed\n  --> tests/ui/shadow.rs:38:9\n   |\nLL |     let x = x[0];\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:36:9\n   |\nLL |     let x = x.0;\n   |         ^\n\nerror: `x` is shadowed\n  --> tests/ui/shadow.rs:40:10\n   |\nLL |     let [x] = x;\n   |          ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:38:9\n   |\nLL |     let x = x[0];\n   |         ^\n\nerror: `x` is shadowed\n  --> tests/ui/shadow.rs:42:9\n   |\nLL |     let x = Some(x);\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:40:10\n   |\nLL |     let [x] = x;\n   |          ^\n\nerror: `x` is shadowed\n  --> tests/ui/shadow.rs:44:9\n   |\nLL |     let x = foo(x);\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:42:9\n   |\nLL |     let x = Some(x);\n   |         ^\n\nerror: `x` is shadowed\n  --> tests/ui/shadow.rs:46:9\n   |\nLL |     let x = || x;\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:44:9\n   |\nLL |     let x = foo(x);\n   |         ^\n\nerror: `x` is shadowed\n  --> tests/ui/shadow.rs:48:9\n   |\nLL |     let x = Some(1).map(|_| x)?;\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:46:9\n   |\nLL |     let x = || x;\n   |         ^\n\nerror: `y` is shadowed\n  --> tests/ui/shadow.rs:51:9\n   |\nLL |     let y = match y {\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:50:9\n   |\nLL |     let y = 1;\n   |         ^\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:67:9\n   |\nLL |     let x = 2;\n   |         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:66:9\n   |\nLL |     let x = 1;\n   |         ^\n   = note: `-D clippy::shadow-unrelated` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::shadow_unrelated)]`\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:73:13\n   |\nLL |         let x = 1;\n   |             ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:72:10\n   |\nLL |     fn f(x: u32) {\n   |          ^\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:79:14\n   |\nLL |         Some(x) => {\n   |              ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:76:9\n   |\nLL |     let x = 1;\n   |         ^\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:81:17\n   |\nLL |             let x = 1;\n   |                 ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:79:14\n   |\nLL |         Some(x) => {\n   |              ^\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:86:17\n   |\nLL |     if let Some(x) = Some(1) {}\n   |                 ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:76:9\n   |\nLL |     let x = 1;\n   |         ^\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:88:20\n   |\nLL |     while let Some(x) = Some(1) {}\n   |                    ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:76:9\n   |\nLL |     let x = 1;\n   |         ^\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:90:15\n   |\nLL |     let _ = |[x]: [u32; 1]| {\n   |               ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:76:9\n   |\nLL |     let x = 1;\n   |         ^\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:92:13\n   |\nLL |         let x = 1;\n   |             ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:90:15\n   |\nLL |     let _ = |[x]: [u32; 1]| {\n   |               ^\n\nerror: `y` is shadowed\n  --> tests/ui/shadow.rs:96:17\n   |\nLL |     if let Some(y) = y {}\n   |                 ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:95:9\n   |\nLL |     let y = Some(1);\n   |         ^\n\nerror: `_b` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:133:9\n   |\nLL |     let _b = _a;\n   |         ^^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:132:28\n   |\nLL | pub async fn foo2(_a: i32, _b: i64) {\n   |                            ^^\n\nerror: `x` shadows a previous, unrelated binding\n  --> tests/ui/shadow.rs:140:21\n   |\nLL |         if let Some(x) = Some(1) { x } else { 1 }\n   |                     ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:139:13\n   |\nLL |         let x = 1;\n   |             ^\n\nerror: `x` is shadowed\n  --> tests/ui/shadow.rs:151:20\n   |\nLL |     let z = x.map(|x| x + 1);\n   |                    ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:148:9\n   |\nLL |     let x = Some(1);\n   |         ^\n\nerror: `i` is shadowed\n  --> tests/ui/shadow.rs:156:25\n   |\nLL |         .map(|i| i.map(|i| i - 10))\n   |                         ^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:156:15\n   |\nLL |         .map(|i| i.map(|i| i - 10))\n   |               ^\n\nerror: `value` is shadowed by itself in `value`\n  --> tests/ui/shadow.rs:166:22\n   |\nLL |     let Issue13795 { value, .. } = value;\n   |                      ^^^^^\n   |\nnote: previous binding is here\n  --> tests/ui/shadow.rs:165:15\n   |\nLL | fn issue13795(value: Issue13795) {\n   |               ^^^^^\n\nerror: aborting due to 26 previous errors\n\n"
  },
  {
    "path": "tests/ui/short_circuit_statement.fixed",
    "content": "#![warn(clippy::short_circuit_statement)]\n#![allow(clippy::nonminimal_bool)]\n\nfn main() {\n    if f() { g(); }\n    //~^ short_circuit_statement\n\n    if !f() { g(); }\n    //~^ short_circuit_statement\n\n    if 1 != 2 { g(); }\n    //~^ short_circuit_statement\n\n    if f() || g() { H * 2; }\n    //~^ short_circuit_statement\n\n    if !(f() || g()) { H * 2; }\n    //~^ short_circuit_statement\n\n    macro_rules! mac {\n        ($f:ident or $g:ident) => {\n            $f() || $g()\n        };\n        ($f:ident and $g:ident) => {\n            $f() && $g()\n        };\n        () => {\n            f() && g()\n        };\n    }\n\n    if mac!() { mac!(); }\n    //~^ short_circuit_statement\n\n    if !mac!() { mac!(); }\n    //~^ short_circuit_statement\n\n    // Do not lint if the expression comes from a macro\n    mac!();\n}\n\nfn f() -> bool {\n    true\n}\n\nfn g() -> bool {\n    false\n}\n\nstruct H;\n\nimpl std::ops::Mul<u32> for H {\n    type Output = bool;\n    fn mul(self, other: u32) -> Self::Output {\n        true\n    }\n}\n"
  },
  {
    "path": "tests/ui/short_circuit_statement.rs",
    "content": "#![warn(clippy::short_circuit_statement)]\n#![allow(clippy::nonminimal_bool)]\n\nfn main() {\n    f() && g();\n    //~^ short_circuit_statement\n\n    f() || g();\n    //~^ short_circuit_statement\n\n    1 == 2 || g();\n    //~^ short_circuit_statement\n\n    (f() || g()) && (H * 2);\n    //~^ short_circuit_statement\n\n    (f() || g()) || (H * 2);\n    //~^ short_circuit_statement\n\n    macro_rules! mac {\n        ($f:ident or $g:ident) => {\n            $f() || $g()\n        };\n        ($f:ident and $g:ident) => {\n            $f() && $g()\n        };\n        () => {\n            f() && g()\n        };\n    }\n\n    mac!() && mac!();\n    //~^ short_circuit_statement\n\n    mac!() || mac!();\n    //~^ short_circuit_statement\n\n    // Do not lint if the expression comes from a macro\n    mac!();\n}\n\nfn f() -> bool {\n    true\n}\n\nfn g() -> bool {\n    false\n}\n\nstruct H;\n\nimpl std::ops::Mul<u32> for H {\n    type Output = bool;\n    fn mul(self, other: u32) -> Self::Output {\n        true\n    }\n}\n"
  },
  {
    "path": "tests/ui/short_circuit_statement.stderr",
    "content": "error: boolean short circuit operator in statement may be clearer using an explicit test\n  --> tests/ui/short_circuit_statement.rs:5:5\n   |\nLL |     f() && g();\n   |     ^^^^^^^^^^^ help: replace it with: `if f() { g(); }`\n   |\n   = note: `-D clippy::short-circuit-statement` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::short_circuit_statement)]`\n\nerror: boolean short circuit operator in statement may be clearer using an explicit test\n  --> tests/ui/short_circuit_statement.rs:8:5\n   |\nLL |     f() || g();\n   |     ^^^^^^^^^^^ help: replace it with: `if !f() { g(); }`\n\nerror: boolean short circuit operator in statement may be clearer using an explicit test\n  --> tests/ui/short_circuit_statement.rs:11:5\n   |\nLL |     1 == 2 || g();\n   |     ^^^^^^^^^^^^^^ help: replace it with: `if 1 != 2 { g(); }`\n\nerror: boolean short circuit operator in statement may be clearer using an explicit test\n  --> tests/ui/short_circuit_statement.rs:14:5\n   |\nLL |     (f() || g()) && (H * 2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `if f() || g() { H * 2; }`\n\nerror: boolean short circuit operator in statement may be clearer using an explicit test\n  --> tests/ui/short_circuit_statement.rs:17:5\n   |\nLL |     (f() || g()) || (H * 2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `if !(f() || g()) { H * 2; }`\n\nerror: boolean short circuit operator in statement may be clearer using an explicit test\n  --> tests/ui/short_circuit_statement.rs:32:5\n   |\nLL |     mac!() && mac!();\n   |     ^^^^^^^^^^^^^^^^^ help: replace it with: `if mac!() { mac!(); }`\n\nerror: boolean short circuit operator in statement may be clearer using an explicit test\n  --> tests/ui/short_circuit_statement.rs:35:5\n   |\nLL |     mac!() || mac!();\n   |     ^^^^^^^^^^^^^^^^^ help: replace it with: `if !mac!() { mac!(); }`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/should_impl_trait/corner_cases.rs",
    "content": "//@ check-pass\n\n#![allow(\n    clippy::missing_errors_doc,\n    clippy::needless_pass_by_value,\n    clippy::must_use_candidate,\n    clippy::unused_self,\n    clippy::needless_lifetimes,\n    clippy::missing_safety_doc,\n    clippy::wrong_self_convention,\n    clippy::missing_panics_doc,\n    clippy::return_self_not_must_use,\n    clippy::unused_async\n)]\n\nuse std::ops::Mul;\nuse std::rc::{self, Rc};\nuse std::sync::{self, Arc};\n\nfn main() {}\n\npub struct T1;\nimpl T1 {\n    // corner cases: should not lint\n\n    // no error, not public interface\n    pub(crate) fn drop(&mut self) {}\n\n    // no error, private function\n    fn neg(self) -> Self {\n        self\n    }\n\n    // no error, private function\n    fn eq(&self, other: Self) -> bool {\n        true\n    }\n\n    // No error; self is a ref.\n    fn sub(&self, other: Self) -> &Self {\n        self\n    }\n\n    // No error; different number of arguments.\n    fn div(self) -> Self {\n        self\n    }\n\n    // No error; wrong return type.\n    fn rem(self, other: Self) {}\n\n    // Fine\n    fn into_u32(self) -> u32 {\n        0\n    }\n\n    fn into_u16(&self) -> u16 {\n        0\n    }\n\n    fn to_something(self) -> u32 {\n        0\n    }\n\n    fn new(self) -> Self {\n        unimplemented!();\n    }\n\n    pub fn next<'b>(&'b mut self) -> Option<&'b mut T1> {\n        unimplemented!();\n    }\n}\n\npub struct T2;\nimpl T2 {\n    // Shouldn't trigger lint as it is unsafe.\n    pub unsafe fn add(self, rhs: Self) -> Self {\n        self\n    }\n\n    // Should not trigger lint since this is an async function.\n    pub async fn next(&mut self) -> Option<Self> {\n        None\n    }\n}\n"
  },
  {
    "path": "tests/ui/should_impl_trait/method_list_1.edition2015.stderr",
    "content": "error: method `add` can be confused for the standard trait method `std::ops::Add::add`\n  --> tests/ui/should_impl_trait/method_list_1.rs:27:5\n   |\nLL | /     pub fn add(self, other: T) -> T {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Add` or choosing a less ambiguous method name\n   = note: `-D clippy::should-implement-trait` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]`\n\nerror: method `as_mut` can be confused for the standard trait method `std::convert::AsMut::as_mut`\n  --> tests/ui/should_impl_trait/method_list_1.rs:33:5\n   |\nLL | /     pub fn as_mut(&mut self) -> &mut T {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::convert::AsMut` or choosing a less ambiguous method name\n\nerror: method `as_ref` can be confused for the standard trait method `std::convert::AsRef::as_ref`\n  --> tests/ui/should_impl_trait/method_list_1.rs:39:5\n   |\nLL | /     pub fn as_ref(&self) -> &T {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::convert::AsRef` or choosing a less ambiguous method name\n\nerror: method `bitand` can be confused for the standard trait method `std::ops::BitAnd::bitand`\n  --> tests/ui/should_impl_trait/method_list_1.rs:45:5\n   |\nLL | /     pub fn bitand(self, rhs: T) -> T {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::BitAnd` or choosing a less ambiguous method name\n\nerror: method `bitor` can be confused for the standard trait method `std::ops::BitOr::bitor`\n  --> tests/ui/should_impl_trait/method_list_1.rs:51:5\n   |\nLL | /     pub fn bitor(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::BitOr` or choosing a less ambiguous method name\n\nerror: method `bitxor` can be confused for the standard trait method `std::ops::BitXor::bitxor`\n  --> tests/ui/should_impl_trait/method_list_1.rs:57:5\n   |\nLL | /     pub fn bitxor(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::BitXor` or choosing a less ambiguous method name\n\nerror: method `borrow` can be confused for the standard trait method `std::borrow::Borrow::borrow`\n  --> tests/ui/should_impl_trait/method_list_1.rs:63:5\n   |\nLL | /     pub fn borrow(&self) -> &str {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::borrow::Borrow` or choosing a less ambiguous method name\n\nerror: method `borrow_mut` can be confused for the standard trait method `std::borrow::BorrowMut::borrow_mut`\n  --> tests/ui/should_impl_trait/method_list_1.rs:69:5\n   |\nLL | /     pub fn borrow_mut(&mut self) -> &mut str {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::borrow::BorrowMut` or choosing a less ambiguous method name\n\nerror: method `clone` can be confused for the standard trait method `std::clone::Clone::clone`\n  --> tests/ui/should_impl_trait/method_list_1.rs:75:5\n   |\nLL | /     pub fn clone(&self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::clone::Clone` or choosing a less ambiguous method name\n\nerror: method `cmp` can be confused for the standard trait method `std::cmp::Ord::cmp`\n  --> tests/ui/should_impl_trait/method_list_1.rs:81:5\n   |\nLL | /     pub fn cmp(&self, other: &Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::cmp::Ord` or choosing a less ambiguous method name\n\nerror: method `default` can be confused for the standard trait method `std::default::Default::default`\n  --> tests/ui/should_impl_trait/method_list_1.rs:87:5\n   |\nLL | /     pub fn default() -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::default::Default` or choosing a less ambiguous method name\n\nerror: method `deref` can be confused for the standard trait method `std::ops::Deref::deref`\n  --> tests/ui/should_impl_trait/method_list_1.rs:93:5\n   |\nLL | /     pub fn deref(&self) -> &Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Deref` or choosing a less ambiguous method name\n\nerror: method `deref_mut` can be confused for the standard trait method `std::ops::DerefMut::deref_mut`\n  --> tests/ui/should_impl_trait/method_list_1.rs:99:5\n   |\nLL | /     pub fn deref_mut(&mut self) -> &mut Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::DerefMut` or choosing a less ambiguous method name\n\nerror: method `div` can be confused for the standard trait method `std::ops::Div::div`\n  --> tests/ui/should_impl_trait/method_list_1.rs:105:5\n   |\nLL | /     pub fn div(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Div` or choosing a less ambiguous method name\n\nerror: method `drop` can be confused for the standard trait method `std::ops::Drop::drop`\n  --> tests/ui/should_impl_trait/method_list_1.rs:111:5\n   |\nLL | /     pub fn drop(&mut self) {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Drop` or choosing a less ambiguous method name\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/should_impl_trait/method_list_1.edition2021.stderr",
    "content": "error: method `add` can be confused for the standard trait method `std::ops::Add::add`\n  --> tests/ui/should_impl_trait/method_list_1.rs:27:5\n   |\nLL | /     pub fn add(self, other: T) -> T {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Add` or choosing a less ambiguous method name\n   = note: `-D clippy::should-implement-trait` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]`\n\nerror: method `as_mut` can be confused for the standard trait method `std::convert::AsMut::as_mut`\n  --> tests/ui/should_impl_trait/method_list_1.rs:33:5\n   |\nLL | /     pub fn as_mut(&mut self) -> &mut T {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::convert::AsMut` or choosing a less ambiguous method name\n\nerror: method `as_ref` can be confused for the standard trait method `std::convert::AsRef::as_ref`\n  --> tests/ui/should_impl_trait/method_list_1.rs:39:5\n   |\nLL | /     pub fn as_ref(&self) -> &T {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::convert::AsRef` or choosing a less ambiguous method name\n\nerror: method `bitand` can be confused for the standard trait method `std::ops::BitAnd::bitand`\n  --> tests/ui/should_impl_trait/method_list_1.rs:45:5\n   |\nLL | /     pub fn bitand(self, rhs: T) -> T {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::BitAnd` or choosing a less ambiguous method name\n\nerror: method `bitor` can be confused for the standard trait method `std::ops::BitOr::bitor`\n  --> tests/ui/should_impl_trait/method_list_1.rs:51:5\n   |\nLL | /     pub fn bitor(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::BitOr` or choosing a less ambiguous method name\n\nerror: method `bitxor` can be confused for the standard trait method `std::ops::BitXor::bitxor`\n  --> tests/ui/should_impl_trait/method_list_1.rs:57:5\n   |\nLL | /     pub fn bitxor(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::BitXor` or choosing a less ambiguous method name\n\nerror: method `borrow` can be confused for the standard trait method `std::borrow::Borrow::borrow`\n  --> tests/ui/should_impl_trait/method_list_1.rs:63:5\n   |\nLL | /     pub fn borrow(&self) -> &str {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::borrow::Borrow` or choosing a less ambiguous method name\n\nerror: method `borrow_mut` can be confused for the standard trait method `std::borrow::BorrowMut::borrow_mut`\n  --> tests/ui/should_impl_trait/method_list_1.rs:69:5\n   |\nLL | /     pub fn borrow_mut(&mut self) -> &mut str {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::borrow::BorrowMut` or choosing a less ambiguous method name\n\nerror: method `clone` can be confused for the standard trait method `std::clone::Clone::clone`\n  --> tests/ui/should_impl_trait/method_list_1.rs:75:5\n   |\nLL | /     pub fn clone(&self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::clone::Clone` or choosing a less ambiguous method name\n\nerror: method `cmp` can be confused for the standard trait method `std::cmp::Ord::cmp`\n  --> tests/ui/should_impl_trait/method_list_1.rs:81:5\n   |\nLL | /     pub fn cmp(&self, other: &Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::cmp::Ord` or choosing a less ambiguous method name\n\nerror: method `default` can be confused for the standard trait method `std::default::Default::default`\n  --> tests/ui/should_impl_trait/method_list_1.rs:87:5\n   |\nLL | /     pub fn default() -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::default::Default` or choosing a less ambiguous method name\n\nerror: method `deref` can be confused for the standard trait method `std::ops::Deref::deref`\n  --> tests/ui/should_impl_trait/method_list_1.rs:93:5\n   |\nLL | /     pub fn deref(&self) -> &Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Deref` or choosing a less ambiguous method name\n\nerror: method `deref_mut` can be confused for the standard trait method `std::ops::DerefMut::deref_mut`\n  --> tests/ui/should_impl_trait/method_list_1.rs:99:5\n   |\nLL | /     pub fn deref_mut(&mut self) -> &mut Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::DerefMut` or choosing a less ambiguous method name\n\nerror: method `div` can be confused for the standard trait method `std::ops::Div::div`\n  --> tests/ui/should_impl_trait/method_list_1.rs:105:5\n   |\nLL | /     pub fn div(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Div` or choosing a less ambiguous method name\n\nerror: method `drop` can be confused for the standard trait method `std::ops::Drop::drop`\n  --> tests/ui/should_impl_trait/method_list_1.rs:111:5\n   |\nLL | /     pub fn drop(&mut self) {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Drop` or choosing a less ambiguous method name\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/should_impl_trait/method_list_1.rs",
    "content": "//@revisions: edition2015 edition2021\n//@[edition2015] edition:2015\n//@[edition2021] edition:2021\n#![allow(\n    clippy::missing_errors_doc,\n    clippy::needless_pass_by_value,\n    clippy::must_use_candidate,\n    clippy::unused_self,\n    clippy::needless_lifetimes,\n    clippy::missing_safety_doc,\n    clippy::wrong_self_convention,\n    clippy::missing_panics_doc,\n    clippy::return_self_not_must_use\n)]\n\nuse std::ops::Mul;\nuse std::rc::{self, Rc};\nuse std::sync::{self, Arc};\n\nfn main() {}\npub struct T;\n\nimpl T {\n    // *****************************************\n    // trait method list part 1, should lint all\n    // *****************************************\n    pub fn add(self, other: T) -> T {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn as_mut(&mut self) -> &mut T {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn as_ref(&self) -> &T {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn bitand(self, rhs: T) -> T {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn bitor(self, rhs: Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn bitxor(self, rhs: Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn borrow(&self) -> &str {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn borrow_mut(&mut self) -> &mut str {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn clone(&self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn cmp(&self, other: &Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn default() -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn deref(&self) -> &Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn deref_mut(&mut self) -> &mut Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn div(self, rhs: Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn drop(&mut self) {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n    // **********\n    // part 1 end\n    // **********\n}\n"
  },
  {
    "path": "tests/ui/should_impl_trait/method_list_2.edition2015.stderr",
    "content": "error: method `eq` can be confused for the standard trait method `std::cmp::PartialEq::eq`\n  --> tests/ui/should_impl_trait/method_list_2.rs:28:5\n   |\nLL | /     pub fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::cmp::PartialEq` or choosing a less ambiguous method name\n   = note: `-D clippy::should-implement-trait` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]`\n\nerror: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`\n  --> tests/ui/should_impl_trait/method_list_2.rs:40:5\n   |\nLL | /     pub fn from_str(s: &str) -> Result<Self, Self> {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name\n\nerror: method `hash` can be confused for the standard trait method `std::hash::Hash::hash`\n  --> tests/ui/should_impl_trait/method_list_2.rs:46:5\n   |\nLL | /     pub fn hash(&self, state: &mut T) {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name\n\nerror: method `index` can be confused for the standard trait method `std::ops::Index::index`\n  --> tests/ui/should_impl_trait/method_list_2.rs:52:5\n   |\nLL | /     pub fn index(&self, index: usize) -> &Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Index` or choosing a less ambiguous method name\n\nerror: method `index_mut` can be confused for the standard trait method `std::ops::IndexMut::index_mut`\n  --> tests/ui/should_impl_trait/method_list_2.rs:58:5\n   |\nLL | /     pub fn index_mut(&mut self, index: usize) -> &mut Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::IndexMut` or choosing a less ambiguous method name\n\nerror: method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`\n  --> tests/ui/should_impl_trait/method_list_2.rs:64:5\n   |\nLL | /     pub fn into_iter(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::iter::IntoIterator` or choosing a less ambiguous method name\n\nerror: method `mul` can be confused for the standard trait method `std::ops::Mul::mul`\n  --> tests/ui/should_impl_trait/method_list_2.rs:70:5\n   |\nLL | /     pub fn mul(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Mul` or choosing a less ambiguous method name\n\nerror: method `neg` can be confused for the standard trait method `std::ops::Neg::neg`\n  --> tests/ui/should_impl_trait/method_list_2.rs:76:5\n   |\nLL | /     pub fn neg(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Neg` or choosing a less ambiguous method name\n\nerror: method `next` can be confused for the standard trait method `std::iter::Iterator::next`\n  --> tests/ui/should_impl_trait/method_list_2.rs:82:5\n   |\nLL | /     pub fn next(&mut self) -> Option<Self> {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name\n\nerror: method `not` can be confused for the standard trait method `std::ops::Not::not`\n  --> tests/ui/should_impl_trait/method_list_2.rs:88:5\n   |\nLL | /     pub fn not(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Not` or choosing a less ambiguous method name\n\nerror: method `rem` can be confused for the standard trait method `std::ops::Rem::rem`\n  --> tests/ui/should_impl_trait/method_list_2.rs:94:5\n   |\nLL | /     pub fn rem(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Rem` or choosing a less ambiguous method name\n\nerror: method `shl` can be confused for the standard trait method `std::ops::Shl::shl`\n  --> tests/ui/should_impl_trait/method_list_2.rs:100:5\n   |\nLL | /     pub fn shl(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Shl` or choosing a less ambiguous method name\n\nerror: method `shr` can be confused for the standard trait method `std::ops::Shr::shr`\n  --> tests/ui/should_impl_trait/method_list_2.rs:106:5\n   |\nLL | /     pub fn shr(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Shr` or choosing a less ambiguous method name\n\nerror: method `sub` can be confused for the standard trait method `std::ops::Sub::sub`\n  --> tests/ui/should_impl_trait/method_list_2.rs:112:5\n   |\nLL | /     pub fn sub(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Sub` or choosing a less ambiguous method name\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/should_impl_trait/method_list_2.edition2021.stderr",
    "content": "error: method `eq` can be confused for the standard trait method `std::cmp::PartialEq::eq`\n  --> tests/ui/should_impl_trait/method_list_2.rs:28:5\n   |\nLL | /     pub fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::cmp::PartialEq` or choosing a less ambiguous method name\n   = note: `-D clippy::should-implement-trait` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]`\n\nerror: method `from_iter` can be confused for the standard trait method `std::iter::FromIterator::from_iter`\n  --> tests/ui/should_impl_trait/method_list_2.rs:34:5\n   |\nLL | /     pub fn from_iter<T>(iter: T) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::iter::FromIterator` or choosing a less ambiguous method name\n\nerror: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`\n  --> tests/ui/should_impl_trait/method_list_2.rs:40:5\n   |\nLL | /     pub fn from_str(s: &str) -> Result<Self, Self> {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name\n\nerror: method `hash` can be confused for the standard trait method `std::hash::Hash::hash`\n  --> tests/ui/should_impl_trait/method_list_2.rs:46:5\n   |\nLL | /     pub fn hash(&self, state: &mut T) {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name\n\nerror: method `index` can be confused for the standard trait method `std::ops::Index::index`\n  --> tests/ui/should_impl_trait/method_list_2.rs:52:5\n   |\nLL | /     pub fn index(&self, index: usize) -> &Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Index` or choosing a less ambiguous method name\n\nerror: method `index_mut` can be confused for the standard trait method `std::ops::IndexMut::index_mut`\n  --> tests/ui/should_impl_trait/method_list_2.rs:58:5\n   |\nLL | /     pub fn index_mut(&mut self, index: usize) -> &mut Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::IndexMut` or choosing a less ambiguous method name\n\nerror: method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`\n  --> tests/ui/should_impl_trait/method_list_2.rs:64:5\n   |\nLL | /     pub fn into_iter(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::iter::IntoIterator` or choosing a less ambiguous method name\n\nerror: method `mul` can be confused for the standard trait method `std::ops::Mul::mul`\n  --> tests/ui/should_impl_trait/method_list_2.rs:70:5\n   |\nLL | /     pub fn mul(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Mul` or choosing a less ambiguous method name\n\nerror: method `neg` can be confused for the standard trait method `std::ops::Neg::neg`\n  --> tests/ui/should_impl_trait/method_list_2.rs:76:5\n   |\nLL | /     pub fn neg(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Neg` or choosing a less ambiguous method name\n\nerror: method `next` can be confused for the standard trait method `std::iter::Iterator::next`\n  --> tests/ui/should_impl_trait/method_list_2.rs:82:5\n   |\nLL | /     pub fn next(&mut self) -> Option<Self> {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name\n\nerror: method `not` can be confused for the standard trait method `std::ops::Not::not`\n  --> tests/ui/should_impl_trait/method_list_2.rs:88:5\n   |\nLL | /     pub fn not(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Not` or choosing a less ambiguous method name\n\nerror: method `rem` can be confused for the standard trait method `std::ops::Rem::rem`\n  --> tests/ui/should_impl_trait/method_list_2.rs:94:5\n   |\nLL | /     pub fn rem(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Rem` or choosing a less ambiguous method name\n\nerror: method `shl` can be confused for the standard trait method `std::ops::Shl::shl`\n  --> tests/ui/should_impl_trait/method_list_2.rs:100:5\n   |\nLL | /     pub fn shl(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Shl` or choosing a less ambiguous method name\n\nerror: method `shr` can be confused for the standard trait method `std::ops::Shr::shr`\n  --> tests/ui/should_impl_trait/method_list_2.rs:106:5\n   |\nLL | /     pub fn shr(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Shr` or choosing a less ambiguous method name\n\nerror: method `sub` can be confused for the standard trait method `std::ops::Sub::sub`\n  --> tests/ui/should_impl_trait/method_list_2.rs:112:5\n   |\nLL | /     pub fn sub(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Sub` or choosing a less ambiguous method name\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/should_impl_trait/method_list_2.rs",
    "content": "//@revisions: edition2015 edition2021\n//@[edition2015] edition:2015\n//@[edition2021] edition:2021\n#![allow(\n    clippy::missing_errors_doc,\n    clippy::needless_pass_by_value,\n    clippy::must_use_candidate,\n    clippy::unused_self,\n    clippy::needless_lifetimes,\n    clippy::missing_safety_doc,\n    clippy::wrong_self_convention,\n    clippy::missing_panics_doc,\n    clippy::return_self_not_must_use\n)]\n\nuse std::ops::Mul;\nuse std::rc::{self, Rc};\nuse std::sync::{self, Arc};\n\nfn main() {}\npub struct T;\n\nimpl T {\n    // *****************************************\n    // trait method list part 2, should lint all\n    // *****************************************\n\n    pub fn eq(&self, other: &Self) -> bool {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn from_iter<T>(iter: T) -> Self {\n        //~[edition2021]^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn from_str(s: &str) -> Result<Self, Self> {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn hash(&self, state: &mut T) {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn index(&self, index: usize) -> &Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn index_mut(&mut self, index: usize) -> &mut Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn into_iter(self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn mul(self, rhs: Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn neg(self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn next(&mut self) -> Option<Self> {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn not(self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn rem(self, rhs: Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn shl(self, rhs: Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn shr(self, rhs: Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n\n    pub fn sub(self, rhs: Self) -> Self {\n        //~^ should_implement_trait\n\n        unimplemented!()\n    }\n    // **********\n    // part 2 end\n    // **********\n}\n"
  },
  {
    "path": "tests/ui/should_impl_trait/method_list_2.stderr",
    "content": "error: method `eq` can be confused for the standard trait method `std::cmp::PartialEq::eq`\n  --> tests/ui/should_impl_trait/method_list_2.rs:25:5\n   |\nLL | /     pub fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::cmp::PartialEq` or choosing a less ambiguous method name\n   = note: `-D clippy::should-implement-trait` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::should_implement_trait)]`\n\nerror: method `from_iter` can be confused for the standard trait method `std::iter::FromIterator::from_iter`\n  --> tests/ui/should_impl_trait/method_list_2.rs:31:5\n   |\nLL | /     pub fn from_iter<T>(iter: T) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::iter::FromIterator` or choosing a less ambiguous method name\n\nerror: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`\n  --> tests/ui/should_impl_trait/method_list_2.rs:37:5\n   |\nLL | /     pub fn from_str(s: &str) -> Result<Self, Self> {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name\n\nerror: method `hash` can be confused for the standard trait method `std::hash::Hash::hash`\n  --> tests/ui/should_impl_trait/method_list_2.rs:43:5\n   |\nLL | /     pub fn hash(&self, state: &mut T) {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name\n\nerror: method `index` can be confused for the standard trait method `std::ops::Index::index`\n  --> tests/ui/should_impl_trait/method_list_2.rs:49:5\n   |\nLL | /     pub fn index(&self, index: usize) -> &Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Index` or choosing a less ambiguous method name\n\nerror: method `index_mut` can be confused for the standard trait method `std::ops::IndexMut::index_mut`\n  --> tests/ui/should_impl_trait/method_list_2.rs:55:5\n   |\nLL | /     pub fn index_mut(&mut self, index: usize) -> &mut Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::IndexMut` or choosing a less ambiguous method name\n\nerror: method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`\n  --> tests/ui/should_impl_trait/method_list_2.rs:61:5\n   |\nLL | /     pub fn into_iter(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::iter::IntoIterator` or choosing a less ambiguous method name\n\nerror: method `mul` can be confused for the standard trait method `std::ops::Mul::mul`\n  --> tests/ui/should_impl_trait/method_list_2.rs:67:5\n   |\nLL | /     pub fn mul(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Mul` or choosing a less ambiguous method name\n\nerror: method `neg` can be confused for the standard trait method `std::ops::Neg::neg`\n  --> tests/ui/should_impl_trait/method_list_2.rs:73:5\n   |\nLL | /     pub fn neg(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Neg` or choosing a less ambiguous method name\n\nerror: method `next` can be confused for the standard trait method `std::iter::Iterator::next`\n  --> tests/ui/should_impl_trait/method_list_2.rs:79:5\n   |\nLL | /     pub fn next(&mut self) -> Option<Self> {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name\n\nerror: method `not` can be confused for the standard trait method `std::ops::Not::not`\n  --> tests/ui/should_impl_trait/method_list_2.rs:85:5\n   |\nLL | /     pub fn not(self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Not` or choosing a less ambiguous method name\n\nerror: method `rem` can be confused for the standard trait method `std::ops::Rem::rem`\n  --> tests/ui/should_impl_trait/method_list_2.rs:91:5\n   |\nLL | /     pub fn rem(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Rem` or choosing a less ambiguous method name\n\nerror: method `shl` can be confused for the standard trait method `std::ops::Shl::shl`\n  --> tests/ui/should_impl_trait/method_list_2.rs:97:5\n   |\nLL | /     pub fn shl(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Shl` or choosing a less ambiguous method name\n\nerror: method `shr` can be confused for the standard trait method `std::ops::Shr::shr`\n  --> tests/ui/should_impl_trait/method_list_2.rs:103:5\n   |\nLL | /     pub fn shr(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Shr` or choosing a less ambiguous method name\n\nerror: method `sub` can be confused for the standard trait method `std::ops::Sub::sub`\n  --> tests/ui/should_impl_trait/method_list_2.rs:109:5\n   |\nLL | /     pub fn sub(self, rhs: Self) -> Self {\nLL | |\nLL | |\nLL | |         unimplemented!()\nLL | |     }\n   | |_____^\n   |\n   = help: consider implementing the trait `std::ops::Sub` or choosing a less ambiguous method name\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/should_panic_without_expect.rs",
    "content": "//@no-rustfix\n#![deny(clippy::should_panic_without_expect)]\n\n#[test]\n#[should_panic]\n//~^ should_panic_without_expect\nfn no_message() {}\n\n#[test]\n#[should_panic]\n#[cfg(not(test))]\nfn no_message_cfg_false() {}\n\n#[test]\n#[should_panic = \"message\"]\nfn metastr() {}\n\n#[test]\n#[should_panic(expected = \"message\")]\nfn metalist() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/should_panic_without_expect.stderr",
    "content": "error: #[should_panic] attribute without a reason\n  --> tests/ui/should_panic_without_expect.rs:5:1\n   |\nLL | #[should_panic]\n   | ^^^^^^^^^^^^^^^ help: consider specifying the expected panic: `#[should_panic(expected = /* panic message */)]`\n   |\nnote: the lint level is defined here\n  --> tests/ui/should_panic_without_expect.rs:2:9\n   |\nLL | #![deny(clippy::should_panic_without_expect)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/significant_drop_in_scrutinee.rs",
    "content": "// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934\n//@no-rustfix\n#![warn(clippy::significant_drop_in_scrutinee)]\n#![allow(dead_code, unused_assignments)]\n#![allow(\n    clippy::match_single_binding,\n    clippy::single_match,\n    clippy::uninlined_format_args,\n    clippy::needless_lifetimes\n)]\n\nuse std::num::ParseIntError;\nuse std::ops::Deref;\nuse std::sync::atomic::{AtomicU64, Ordering};\nuse std::sync::{Mutex, MutexGuard, RwLock};\n\nstruct State {}\n\nimpl State {\n    fn foo(&self) -> bool {\n        true\n    }\n\n    fn bar(&self) {}\n}\n\nfn should_not_trigger_lint_with_mutex_guard_outside_match() {\n    let mutex = Mutex::new(State {});\n\n    // Should not trigger lint because the temporary should drop at the `;` on line before the match\n    let is_foo = mutex.lock().unwrap().foo();\n    match is_foo {\n        true => {\n            mutex.lock().unwrap().bar();\n        },\n        false => {},\n    };\n}\n\nfn should_not_trigger_lint_with_mutex_guard_when_taking_ownership_in_match() {\n    let mutex = Mutex::new(State {});\n\n    // Should not trigger lint because the scrutinee is explicitly returning the MutexGuard,\n    // so its lifetime should not be surprising.\n    match mutex.lock() {\n        Ok(guard) => {\n            guard.foo();\n            mutex.lock().unwrap().bar();\n        },\n        _ => {},\n    };\n}\n\nfn should_trigger_lint_with_mutex_guard_in_match_scrutinee() {\n    let mutex = Mutex::new(State {});\n\n    // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it\n    // is preserved until the end of the match, but there is no clear indication that this is the\n    // case.\n    match mutex.lock().unwrap().foo() {\n        //~^ significant_drop_in_scrutinee\n        true => {\n            mutex.lock().unwrap().bar();\n        },\n        false => {},\n    };\n}\n\nfn should_not_trigger_lint_with_mutex_guard_in_match_scrutinee_when_lint_allowed() {\n    let mutex = Mutex::new(State {});\n\n    // Lint should not be triggered because it is \"allowed\" below.\n    #[allow(clippy::significant_drop_in_scrutinee)]\n    match mutex.lock().unwrap().foo() {\n        true => {\n            mutex.lock().unwrap().bar();\n        },\n        false => {},\n    };\n}\n\nfn should_not_trigger_lint_for_insignificant_drop() {\n    // Should not trigger lint because there are no temporaries whose drops have a significant\n    // side effect.\n    match 1u64.to_string().is_empty() {\n        true => {\n            println!(\"It was empty\")\n        },\n        false => {\n            println!(\"It was not empty\")\n        },\n    }\n}\n\nstruct StateWithMutex {\n    m: Mutex<u64>,\n}\n\nstruct MutexGuardWrapper<'a> {\n    mg: MutexGuard<'a, u64>,\n}\n\nimpl<'a> MutexGuardWrapper<'a> {\n    fn get_the_value(&self) -> u64 {\n        *self.mg.deref()\n    }\n}\n\nstruct MutexGuardWrapperWrapper<'a> {\n    mg: MutexGuardWrapper<'a>,\n}\n\nimpl<'a> MutexGuardWrapperWrapper<'a> {\n    fn get_the_value(&self) -> u64 {\n        *self.mg.mg.deref()\n    }\n}\n\nimpl StateWithMutex {\n    fn lock_m(&self) -> MutexGuardWrapper<'_> {\n        MutexGuardWrapper {\n            mg: self.m.lock().unwrap(),\n        }\n    }\n\n    fn lock_m_m(&self) -> MutexGuardWrapperWrapper<'_> {\n        MutexGuardWrapperWrapper {\n            mg: MutexGuardWrapper {\n                mg: self.m.lock().unwrap(),\n            },\n        }\n    }\n\n    fn foo(&self) -> bool {\n        true\n    }\n\n    fn bar(&self) {}\n}\n\nfn should_trigger_lint_with_wrapped_mutex() {\n    let s = StateWithMutex { m: Mutex::new(1) };\n\n    // Should trigger lint because a temporary contains a type with a significant drop and its\n    // lifetime is not obvious. Additionally, it is not obvious from looking at the scrutinee that\n    // the temporary contains such a type, making it potentially even more surprising.\n    match s.lock_m().get_the_value() {\n        //~^ significant_drop_in_scrutinee\n        1 => {\n            println!(\"Got 1. Is it still 1?\");\n            println!(\"{}\", s.lock_m().get_the_value());\n        },\n        2 => {\n            println!(\"Got 2. Is it still 2?\");\n            println!(\"{}\", s.lock_m().get_the_value());\n        },\n        _ => {},\n    }\n    println!(\"All done!\");\n}\n\nfn should_trigger_lint_with_double_wrapped_mutex() {\n    let s = StateWithMutex { m: Mutex::new(1) };\n\n    // Should trigger lint because a temporary contains a type which further contains a type with a\n    // significant drop and its lifetime is not obvious. Additionally, it is not obvious from\n    // looking at the scrutinee that the temporary contains such a type, making it potentially even\n    // more surprising.\n    match s.lock_m_m().get_the_value() {\n        //~^ significant_drop_in_scrutinee\n        1 => {\n            println!(\"Got 1. Is it still 1?\");\n            println!(\"{}\", s.lock_m().get_the_value());\n        },\n        2 => {\n            println!(\"Got 2. Is it still 2?\");\n            println!(\"{}\", s.lock_m().get_the_value());\n        },\n        _ => {},\n    }\n    println!(\"All done!\");\n}\n\nstruct Counter {\n    i: AtomicU64,\n}\n\n#[clippy::has_significant_drop]\nstruct CounterWrapper<'a> {\n    counter: &'a Counter,\n}\n\nimpl<'a> CounterWrapper<'a> {\n    fn new(counter: &Counter) -> CounterWrapper<'_> {\n        counter.i.fetch_add(1, Ordering::Relaxed);\n        CounterWrapper { counter }\n    }\n}\n\nimpl<'a> Drop for CounterWrapper<'a> {\n    fn drop(&mut self) {\n        self.counter.i.fetch_sub(1, Ordering::Relaxed);\n    }\n}\n\nimpl Counter {\n    fn temp_increment(&self) -> Vec<CounterWrapper<'_>> {\n        vec![CounterWrapper::new(self), CounterWrapper::new(self)]\n    }\n}\n\nfn should_trigger_lint_for_vec() {\n    let counter = Counter { i: AtomicU64::new(0) };\n\n    // Should trigger lint because the temporary in the scrutinee returns a collection of types\n    // which have significant drops. The types with significant drops are also non-obvious when\n    // reading the expression in the scrutinee.\n    match counter.temp_increment().len() {\n        //~^ significant_drop_in_scrutinee\n        2 => {\n            let current_count = counter.i.load(Ordering::Relaxed);\n            println!(\"Current count {}\", current_count);\n            assert_eq!(current_count, 0);\n        },\n        1 => {},\n        3 => {},\n        _ => {},\n    };\n}\n\nstruct StateWithField {\n    s: String,\n}\n\n// Should trigger lint only on the type in the tuple which is created using a temporary\n// with a significant drop. Additionally, this test ensures that the format of the tuple\n// is preserved correctly in the suggestion.\nfn should_trigger_lint_for_tuple_in_scrutinee() {\n    let mutex1 = Mutex::new(StateWithField { s: \"one\".to_owned() });\n\n    {\n        match (mutex1.lock().unwrap().s.len(), true) {\n            //~^ significant_drop_in_scrutinee\n            (3, _) => {\n                println!(\"started\");\n                mutex1.lock().unwrap().s.len();\n                println!(\"done\");\n            },\n            (_, _) => {},\n        };\n\n        match (true, mutex1.lock().unwrap().s.len(), true) {\n            //~^ significant_drop_in_scrutinee\n            (_, 3, _) => {\n                println!(\"started\");\n                mutex1.lock().unwrap().s.len();\n                println!(\"done\");\n            },\n            (_, _, _) => {},\n        };\n\n        let mutex2 = Mutex::new(StateWithField { s: \"two\".to_owned() });\n        match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {\n            //~^ significant_drop_in_scrutinee\n            //~| significant_drop_in_scrutinee\n            (3, _, 3) => {\n                println!(\"started\");\n                mutex1.lock().unwrap().s.len();\n                mutex2.lock().unwrap().s.len();\n                println!(\"done\");\n            },\n            (_, _, _) => {},\n        };\n    }\n}\n\n// Should not trigger lint since `String::as_str` returns a reference (i.e., `&str`)\n// to the locked data (i.e., the `String`) and it is not surprising that matching such\n// a reference needs to keep the data locked until the end of the match block.\nfn should_not_trigger_lint_for_string_as_str() {\n    let mutex1 = Mutex::new(StateWithField { s: \"one\".to_owned() });\n\n    {\n        let mutex2 = Mutex::new(StateWithField { s: \"two\".to_owned() });\n        let mutex3 = Mutex::new(StateWithField { s: \"three\".to_owned() });\n\n        match mutex3.lock().unwrap().s.as_str() {\n            \"three\" => {\n                println!(\"started\");\n                mutex1.lock().unwrap().s.len();\n                mutex2.lock().unwrap().s.len();\n                println!(\"done\");\n            },\n            _ => {},\n        };\n\n        match (true, mutex3.lock().unwrap().s.as_str()) {\n            (_, \"three\") => {\n                println!(\"started\");\n                mutex1.lock().unwrap().s.len();\n                mutex2.lock().unwrap().s.len();\n                println!(\"done\");\n            },\n            (_, _) => {},\n        };\n    }\n}\n\n// Should trigger lint when either side of a binary operation creates a temporary with a\n// significant drop.\n// To avoid potential unnecessary copies or creating references that would trigger the significant\n// drop problem, the lint recommends moving the entire binary operation.\nfn should_trigger_lint_for_accessing_field_in_mutex_in_one_side_of_binary_op() {\n    let mutex = Mutex::new(StateWithField { s: \"state\".to_owned() });\n\n    match mutex.lock().unwrap().s.len() > 1 {\n        //~^ significant_drop_in_scrutinee\n        true => {\n            mutex.lock().unwrap().s.len();\n        },\n        false => {},\n    };\n\n    match 1 < mutex.lock().unwrap().s.len() {\n        //~^ significant_drop_in_scrutinee\n        true => {\n            mutex.lock().unwrap().s.len();\n        },\n        false => {},\n    };\n}\n\n// Should trigger lint when both sides of a binary operation creates a temporary with a\n// significant drop.\n// To avoid potential unnecessary copies or creating references that would trigger the significant\n// drop problem, the lint recommends moving the entire binary operation.\nfn should_trigger_lint_for_accessing_fields_in_mutex_in_both_sides_of_binary_op() {\n    let mutex1 = Mutex::new(StateWithField { s: \"state\".to_owned() });\n    let mutex2 = Mutex::new(StateWithField {\n        s: \"statewithfield\".to_owned(),\n    });\n\n    match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {\n        //~^ significant_drop_in_scrutinee\n        //~| significant_drop_in_scrutinee\n        true => {\n            println!(\n                \"{} < {}\",\n                mutex1.lock().unwrap().s.len(),\n                mutex2.lock().unwrap().s.len()\n            );\n        },\n        false => {},\n    };\n\n    match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {\n        //~^ significant_drop_in_scrutinee\n        //~| significant_drop_in_scrutinee\n        true => {\n            println!(\n                \"{} >= {}\",\n                mutex1.lock().unwrap().s.len(),\n                mutex2.lock().unwrap().s.len()\n            );\n        },\n        false => {},\n    };\n}\n\nfn should_not_trigger_lint_for_closure_in_scrutinee() {\n    let mutex1 = Mutex::new(StateWithField { s: \"one\".to_owned() });\n\n    let get_mutex_guard = || mutex1.lock().unwrap().s.len();\n\n    // Should not trigger lint because the temporary with a significant drop will be dropped\n    // at the end of the closure, so the MutexGuard will be unlocked and not have a potentially\n    // surprising lifetime.\n    match get_mutex_guard() > 1 {\n        true => {\n            mutex1.lock().unwrap().s.len();\n        },\n        false => {},\n    };\n}\n\nfn should_trigger_lint_for_return_from_closure_in_scrutinee() {\n    let mutex1 = Mutex::new(StateWithField { s: \"one\".to_owned() });\n\n    let get_mutex_guard = || mutex1.lock().unwrap();\n\n    // Should trigger lint because the temporary with a significant drop is returned from the\n    // closure but not used directly in any match arms, so it has a potentially surprising lifetime.\n    match get_mutex_guard().s.len() > 1 {\n        //~^ significant_drop_in_scrutinee\n        true => {\n            mutex1.lock().unwrap().s.len();\n        },\n        false => {},\n    };\n}\n\nfn should_trigger_lint_for_return_from_match_in_scrutinee() {\n    let mutex1 = Mutex::new(StateWithField { s: \"one\".to_owned() });\n    let mutex2 = Mutex::new(StateWithField { s: \"two\".to_owned() });\n\n    let i = 100;\n\n    // Should trigger lint because the nested match within the scrutinee returns a temporary with a\n    // significant drop is but not used directly in any match arms, so it has a potentially\n    // surprising lifetime.\n    match match i {\n        //~^ significant_drop_in_scrutinee\n        100 => mutex1.lock().unwrap(),\n        _ => mutex2.lock().unwrap(),\n    }\n    .s\n    .len()\n        > 1\n    {\n        true => {\n            mutex1.lock().unwrap().s.len();\n        },\n        false => {\n            println!(\"nothing to do here\");\n        },\n    };\n}\n\nfn should_trigger_lint_for_return_from_if_in_scrutinee() {\n    let mutex1 = Mutex::new(StateWithField { s: \"one\".to_owned() });\n    let mutex2 = Mutex::new(StateWithField { s: \"two\".to_owned() });\n\n    let i = 100;\n\n    // Should trigger lint because the nested if-expression within the scrutinee returns a temporary\n    // with a significant drop is but not used directly in any match arms, so it has a potentially\n    // surprising lifetime.\n    match if i > 1 {\n        //~^ significant_drop_in_scrutinee\n        mutex1.lock().unwrap()\n    } else {\n        mutex2.lock().unwrap()\n    }\n    .s\n    .len()\n        > 1\n    {\n        true => {\n            mutex1.lock().unwrap().s.len();\n        },\n        false => {},\n    };\n}\n\nfn should_not_trigger_lint_for_if_in_scrutinee() {\n    let mutex = Mutex::new(StateWithField { s: \"state\".to_owned() });\n\n    let i = 100;\n\n    // Should not trigger the lint because the temporary with a significant drop *is* dropped within\n    // the body of the if-expression nested within the match scrutinee, and therefore does not have\n    // a potentially surprising lifetime.\n    match if i > 1 {\n        mutex.lock().unwrap().s.len() > 1\n    } else {\n        false\n    } {\n        true => {\n            mutex.lock().unwrap().s.len();\n        },\n        false => {},\n    };\n}\n\nstruct StateWithBoxedMutexGuard {\n    u: Mutex<u64>,\n}\n\nimpl StateWithBoxedMutexGuard {\n    fn new() -> StateWithBoxedMutexGuard {\n        StateWithBoxedMutexGuard { u: Mutex::new(42) }\n    }\n    fn lock(&self) -> Box<MutexGuard<'_, u64>> {\n        Box::new(self.u.lock().unwrap())\n    }\n}\n\nfn should_trigger_lint_for_boxed_mutex_guard() {\n    let s = StateWithBoxedMutexGuard::new();\n\n    // Should trigger lint because a temporary Box holding a type with a significant drop in a match\n    // scrutinee may have a potentially surprising lifetime.\n    match s.lock().deref().deref() {\n        //~^ significant_drop_in_scrutinee\n        0 | 1 => println!(\"Value was less than 2\"),\n        _ => println!(\"Value is {}\", s.lock().deref()),\n    };\n}\n\nstruct StateStringWithBoxedMutexGuard {\n    s: Mutex<String>,\n}\n\nimpl StateStringWithBoxedMutexGuard {\n    fn new() -> StateStringWithBoxedMutexGuard {\n        StateStringWithBoxedMutexGuard {\n            s: Mutex::new(\"A String\".to_owned()),\n        }\n    }\n    fn lock(&self) -> Box<MutexGuard<'_, String>> {\n        Box::new(self.s.lock().unwrap())\n    }\n}\n\nfn should_not_trigger_lint_for_string_ref() {\n    let s = StateStringWithBoxedMutexGuard::new();\n\n    let matcher = String::from(\"A String\");\n\n    // Should not trigger lint because the second `deref` returns a string reference (`&String`).\n    // So it is not surprising that matching the reference implies that the lock needs to be held\n    // until the end of the block.\n    match s.lock().deref().deref() {\n        matcher => println!(\"Value is {}\", s.lock().deref()),\n        _ => println!(\"Value was not a match\"),\n    };\n}\n\nstruct StateWithIntField {\n    i: u64,\n}\n\n// Should trigger lint when either side of an assign expression contains a temporary with a\n// significant drop, because the temporary's lifetime will be extended to the end of the match.\n// To avoid potential unnecessary copies or creating references that would trigger the significant\n// drop problem, the lint recommends moving the entire binary operation.\nfn should_trigger_lint_in_assign_expr() {\n    let mutex = Mutex::new(StateWithIntField { i: 10 });\n\n    let mut i = 100;\n\n    match mutex.lock().unwrap().i = i {\n        //~^ significant_drop_in_scrutinee\n        _ => {\n            println!(\"{}\", mutex.lock().unwrap().i);\n        },\n    };\n\n    match i = mutex.lock().unwrap().i {\n        //~^ significant_drop_in_scrutinee\n        _ => {\n            println!(\"{}\", mutex.lock().unwrap().i);\n        },\n    };\n\n    match mutex.lock().unwrap().i += 1 {\n        //~^ significant_drop_in_scrutinee\n        _ => {\n            println!(\"{}\", mutex.lock().unwrap().i);\n        },\n    };\n\n    match i += mutex.lock().unwrap().i {\n        //~^ significant_drop_in_scrutinee\n        _ => {\n            println!(\"{}\", mutex.lock().unwrap().i);\n        },\n    };\n}\n\n#[derive(Debug)]\nenum RecursiveEnum {\n    Foo(Option<Box<RecursiveEnum>>),\n}\n\n#[derive(Debug)]\nenum GenericRecursiveEnum<T> {\n    Foo(T, Option<Box<GenericRecursiveEnum<T>>>),\n}\n\nfn should_not_cause_stack_overflow() {\n    // Test that when a type recursively contains itself, a stack overflow does not occur when\n    // checking sub-types for significant drops.\n    let f = RecursiveEnum::Foo(Some(Box::new(RecursiveEnum::Foo(None))));\n    match f {\n        RecursiveEnum::Foo(Some(f)) => {\n            println!(\"{:?}\", f)\n        },\n        RecursiveEnum::Foo(f) => {\n            println!(\"{:?}\", f)\n        },\n    }\n\n    let f = GenericRecursiveEnum::Foo(1u64, Some(Box::new(GenericRecursiveEnum::Foo(2u64, None))));\n    match f {\n        GenericRecursiveEnum::Foo(i, Some(f)) => {\n            println!(\"{} {:?}\", i, f)\n        },\n        GenericRecursiveEnum::Foo(i, f) => {\n            println!(\"{} {:?}\", i, f)\n        },\n    }\n}\n\nfn should_not_produce_lint_for_try_desugar() -> Result<u64, ParseIntError> {\n    // TryDesugar (i.e. using `?` for a Result type) will turn into a match but is out of scope\n    // for this lint\n    let rwlock = RwLock::new(\"1\".to_string());\n    let result = rwlock.read().unwrap().parse::<u64>()?;\n    println!(\"{}\", result);\n    rwlock.write().unwrap().push('2');\n    Ok(result)\n}\n\nstruct ResultReturner {\n    s: String,\n}\n\nimpl ResultReturner {\n    fn to_number(&self) -> Result<i64, ParseIntError> {\n        self.s.parse::<i64>()\n    }\n}\n\nfn should_trigger_lint_for_non_ref_move_and_clone_suggestion() {\n    let rwlock = RwLock::<ResultReturner>::new(ResultReturner { s: \"1\".to_string() });\n    match rwlock.read().unwrap().to_number() {\n        //~^ significant_drop_in_scrutinee\n        Ok(n) => println!(\"Converted to number: {}\", n),\n        Err(e) => println!(\"Could not convert {} to number\", e),\n    };\n}\n\nfn should_not_trigger_lint_for_read_write_lock_for_loop() {\n    let rwlock = RwLock::<Vec<String>>::new(vec![\"1\".to_string()]);\n    // Should not trigger lint. Since we're iterating over the data, it's obvious that the lock\n    // has to be held until the iteration finishes.\n    // https://github.com/rust-lang/rust-clippy/issues/8987\n    for s in rwlock.read().unwrap().iter() {\n        println!(\"{}\", s);\n    }\n}\n\nfn do_bar(mutex: &Mutex<State>) {\n    mutex.lock().unwrap().bar();\n}\n\nfn should_trigger_lint_without_significant_drop_in_arm() {\n    let mutex = Mutex::new(State {});\n\n    // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it\n    // is preserved until the end of the match, but there is no clear indication that this is the\n    // case.\n    match mutex.lock().unwrap().foo() {\n        //~^ significant_drop_in_scrutinee\n        true => do_bar(&mutex),\n        false => {},\n    };\n}\n\nfn should_not_trigger_on_significant_iterator_drop() {\n    let lines = std::io::stdin().lines();\n    for line in lines {\n        println!(\"foo: {}\", line.unwrap());\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/9072\nfn should_not_trigger_lint_if_place_expr_has_significant_drop() {\n    let x = Mutex::new(vec![1, 2, 3]);\n    let x_guard = x.lock().unwrap();\n\n    match x_guard[0] {\n        1 => println!(\"1!\"),\n        x => println!(\"{x}\"),\n    }\n\n    match x_guard.len() {\n        1 => println!(\"1!\"),\n        x => println!(\"{x}\"),\n    }\n}\n\nstruct Guard<'a, T>(MutexGuard<'a, T>);\n\nstruct Ref<'a, T>(&'a T);\n\nimpl<'a, T> Guard<'a, T> {\n    fn guard(&self) -> &MutexGuard<'_, T> {\n        &self.0\n    }\n\n    fn guard_ref(&self) -> Ref<'_, MutexGuard<'_, T>> {\n        Ref(&self.0)\n    }\n\n    fn take(self) -> Box<MutexGuard<'a, T>> {\n        Box::new(self.0)\n    }\n}\n\nfn should_not_trigger_for_significant_drop_ref() {\n    let mutex = Mutex::new(vec![1, 2]);\n    let guard = Guard(mutex.lock().unwrap());\n\n    match guard.guard().len() {\n        0 => println!(\"empty\"),\n        _ => println!(\"not empty\"),\n    }\n\n    match guard.guard_ref().0.len() {\n        0 => println!(\"empty\"),\n        _ => println!(\"not empty\"),\n    }\n\n    match guard.take().len() {\n        //~^ significant_drop_in_scrutinee\n        0 => println!(\"empty\"),\n        _ => println!(\"not empty\"),\n    };\n}\n\nstruct Foo<'a>(&'a Vec<u32>);\n\nimpl<'a> Foo<'a> {\n    fn copy_old_lifetime(&self) -> &'a Vec<u32> {\n        self.0\n    }\n\n    fn reborrow_new_lifetime(&self) -> &Vec<u32> {\n        self.0\n    }\n}\n\nfn should_trigger_lint_if_and_only_if_lifetime_is_irrelevant() {\n    let vec = Vec::new();\n    let mutex = Mutex::new(Foo(&vec));\n\n    // Should trigger lint even if `copy_old_lifetime()` has a lifetime, as the lifetime of\n    // `&vec` is unrelated to the temporary with significant drop (i.e., the `MutexGuard`).\n    for val in mutex.lock().unwrap().copy_old_lifetime() {\n        //~^ significant_drop_in_scrutinee\n        println!(\"{}\", val);\n    }\n\n    // Should not trigger lint because `reborrow_new_lifetime()` has a lifetime and the\n    // lifetime is related to the temporary with significant drop (i.e., the `MutexGuard`).\n    for val in mutex.lock().unwrap().reborrow_new_lifetime() {\n        println!(\"{}\", val);\n    }\n}\n\nfn should_not_trigger_lint_for_complex_lifetime() {\n    let mutex = Mutex::new(vec![\"hello\".to_owned()]);\n    let string = \"world\".to_owned();\n\n    // Should not trigger lint due to the relevant lifetime.\n    for c in mutex.lock().unwrap().first().unwrap().chars() {\n        println!(\"{}\", c);\n    }\n\n    // Should trigger lint due to the irrelevant lifetime.\n    //\n    // FIXME: The lifetime is too complex to analyze. In order to avoid false positives, we do not\n    // trigger lint.\n    for c in mutex.lock().unwrap().first().map(|_| &string).unwrap().chars() {\n        println!(\"{}\", c);\n    }\n}\n\nfn should_not_trigger_lint_with_explicit_drop() {\n    let mutex = Mutex::new(vec![1]);\n\n    // Should not trigger lint since the drop explicitly happens.\n    for val in [drop(mutex.lock().unwrap()), ()] {\n        println!(\"{:?}\", val);\n    }\n\n    // Should trigger lint if there is no explicit drop.\n    for val in [mutex.lock().unwrap()[0], 2] {\n        //~^ significant_drop_in_scrutinee\n        println!(\"{:?}\", val);\n    }\n}\n\nfn should_trigger_lint_in_if_let() {\n    let mutex = Mutex::new(vec![1]);\n\n    if let Some(val) = mutex.lock().unwrap().first().copied() {\n        //~^ significant_drop_in_scrutinee\n        println!(\"{}\", val);\n    }\n\n    // Should not trigger lint without the final `copied()`, because we actually hold a reference\n    // (i.e., the `val`) to the locked data.\n    if let Some(val) = mutex.lock().unwrap().first() {\n        println!(\"{}\", val);\n    };\n}\n\nfn should_trigger_lint_in_while_let() {\n    let mutex = Mutex::new(vec![1]);\n\n    while let Some(val) = mutex.lock().unwrap().pop() {\n        //~^ significant_drop_in_scrutinee\n        println!(\"{}\", val);\n    }\n}\n\nasync fn foo_async(mutex: &Mutex<i32>) -> Option<MutexGuard<'_, i32>> {\n    Some(mutex.lock().unwrap())\n}\n\nasync fn should_trigger_lint_for_async(mutex: Mutex<i32>) -> i32 {\n    match *foo_async(&mutex).await.unwrap() {\n        //~^ significant_drop_in_scrutinee\n        n if n < 10 => n,\n        _ => 10,\n    }\n}\n\nasync fn should_not_trigger_lint_in_async_expansion(mutex: Mutex<i32>) -> i32 {\n    match foo_async(&mutex).await {\n        Some(guard) => *guard,\n        _ => 0,\n    }\n}\n\nfn should_trigger_lint_in_match_expr() {\n    let mutex = Mutex::new(State {});\n\n    // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it\n    // is preserved until the end of the match, but there is no clear indication that this is the\n    // case.\n    let _ = match mutex.lock().unwrap().foo() {\n        //~^ significant_drop_in_scrutinee\n        true => 0,\n        false => 1,\n    };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/significant_drop_in_scrutinee.stderr",
    "content": "error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:60:11\n   |\nLL |     match mutex.lock().unwrap().foo() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             mutex.lock().unwrap().bar();\n   |             --------------------- another value with significant `Drop` created here\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\n   = note: `-D clippy::significant-drop-in-scrutinee` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::significant_drop_in_scrutinee)]`\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().foo();\nLL ~     match value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:147:11\n   |\nLL |     match s.lock_m().get_the_value() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             println!(\"{}\", s.lock_m().get_the_value());\n   |                            ---------- another value with significant `Drop` created here\n...\nLL |             println!(\"{}\", s.lock_m().get_the_value());\n   |                            ---------- another value with significant `Drop` created here\n...\nLL |     }\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = s.lock_m().get_the_value();\nLL ~     match value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:169:11\n   |\nLL |     match s.lock_m_m().get_the_value() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             println!(\"{}\", s.lock_m().get_the_value());\n   |                            ---------- another value with significant `Drop` created here\n...\nLL |             println!(\"{}\", s.lock_m().get_the_value());\n   |                            ---------- another value with significant `Drop` created here\n...\nLL |     }\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = s.lock_m_m().get_the_value();\nLL ~     match value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:218:11\n   |\nLL |     match counter.temp_increment().len() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = counter.temp_increment().len();\nLL ~     match value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:242:16\n   |\nLL |         match (mutex1.lock().unwrap().s.len(), true) {\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |                 mutex1.lock().unwrap().s.len();\n   |                 ---------------------- another value with significant `Drop` created here\n...\nLL |         };\n   |          - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~         let value = mutex1.lock().unwrap().s.len();\nLL ~         match (value, true) {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:252:22\n   |\nLL |         match (true, mutex1.lock().unwrap().s.len(), true) {\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |                 mutex1.lock().unwrap().s.len();\n   |                 ---------------------- another value with significant `Drop` created here\n...\nLL |         };\n   |          - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~         let value = mutex1.lock().unwrap().s.len();\nLL ~         match (true, value, true) {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:263:16\n   |\nLL |         match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |                 mutex1.lock().unwrap().s.len();\n   |                 ---------------------- another value with significant `Drop` created here\nLL |                 mutex2.lock().unwrap().s.len();\n   |                 ---------------------- another value with significant `Drop` created here\n...\nLL |         };\n   |          - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~         let value = mutex1.lock().unwrap().s.len();\nLL ~         match (value, true, mutex2.lock().unwrap().s.len()) {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:263:54\n   |\nLL |         match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {\n   |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |                 mutex1.lock().unwrap().s.len();\n   |                 ---------------------- another value with significant `Drop` created here\nLL |                 mutex2.lock().unwrap().s.len();\n   |                 ---------------------- another value with significant `Drop` created here\n...\nLL |         };\n   |          - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~         let value = mutex2.lock().unwrap().s.len();\nLL ~         match (mutex1.lock().unwrap().s.len(), true, value) {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:316:11\n   |\nLL |     match mutex.lock().unwrap().s.len() > 1 {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             mutex.lock().unwrap().s.len();\n   |             --------------------- another value with significant `Drop` created here\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().s.len();\nLL ~     match value > 1 {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:324:15\n   |\nLL |     match 1 < mutex.lock().unwrap().s.len() {\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             mutex.lock().unwrap().s.len();\n   |             --------------------- another value with significant `Drop` created here\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().s.len();\nLL ~     match 1 < value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:343:11\n   |\nLL |     match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |                 mutex1.lock().unwrap().s.len(),\n   |                 ---------------------- another value with significant `Drop` created here\nLL |                 mutex2.lock().unwrap().s.len()\n   |                 ---------------------- another value with significant `Drop` created here\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex1.lock().unwrap().s.len();\nLL ~     match value < mutex2.lock().unwrap().s.len() {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:343:44\n   |\nLL |     match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {\n   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |                 mutex1.lock().unwrap().s.len(),\n   |                 ---------------------- another value with significant `Drop` created here\nLL |                 mutex2.lock().unwrap().s.len()\n   |                 ---------------------- another value with significant `Drop` created here\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex2.lock().unwrap().s.len();\nLL ~     match mutex1.lock().unwrap().s.len() < value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:356:11\n   |\nLL |     match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |                 mutex1.lock().unwrap().s.len(),\n   |                 ---------------------- another value with significant `Drop` created here\nLL |                 mutex2.lock().unwrap().s.len()\n   |                 ---------------------- another value with significant `Drop` created here\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex1.lock().unwrap().s.len();\nLL ~     match value >= mutex2.lock().unwrap().s.len() {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:356:45\n   |\nLL |     match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {\n   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |                 mutex1.lock().unwrap().s.len(),\n   |                 ---------------------- another value with significant `Drop` created here\nLL |                 mutex2.lock().unwrap().s.len()\n   |                 ---------------------- another value with significant `Drop` created here\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex2.lock().unwrap().s.len();\nLL ~     match mutex1.lock().unwrap().s.len() >= value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:393:11\n   |\nLL |     match get_mutex_guard().s.len() > 1 {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             mutex1.lock().unwrap().s.len();\n   |             ---------------------- another value with significant `Drop` created here\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = get_mutex_guard().s.len();\nLL ~     match value > 1 {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:411:11\n   |\nLL |       match match i {\n   |  ___________^\nLL | |\nLL | |         100 => mutex1.lock().unwrap(),\nLL | |         _ => mutex2.lock().unwrap(),\nLL | |     }\nLL | |     .s\nLL | |     .len()\n   | |__________^\n...\nLL |               mutex1.lock().unwrap().s.len();\n   |               ---------------------- another value with significant `Drop` created here\n...\nLL |       };\n   |        - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = match i {\nLL +\nLL +         100 => mutex1.lock().unwrap(),\nLL +         _ => mutex2.lock().unwrap(),\nLL +     }\nLL +     .s\nLL +     .len();\nLL ~     match value\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:438:11\n   |\nLL |       match if i > 1 {\n   |  ___________^\nLL | |\nLL | |         mutex1.lock().unwrap()\nLL | |     } else {\n...  |\nLL | |     .s\nLL | |     .len()\n   | |__________^\n...\nLL |               mutex1.lock().unwrap().s.len();\n   |               ---------------------- another value with significant `Drop` created here\n...\nLL |       };\n   |        - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = if i > 1 {\nLL +\nLL +         mutex1.lock().unwrap()\nLL +     } else {\nLL +         mutex2.lock().unwrap()\nLL +     }\nLL +     .s\nLL +     .len();\nLL ~     match value\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:493:11\n   |\nLL |     match s.lock().deref().deref() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         _ => println!(\"Value is {}\", s.lock().deref()),\n   |                                      -------- another value with significant `Drop` created here\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match and create a copy\n   |\nLL ~     let value = *s.lock().deref().deref();\nLL ~     match (&value) {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:542:11\n   |\nLL |     match mutex.lock().unwrap().i = i {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             println!(\"{}\", mutex.lock().unwrap().i);\n   |                            --------------------- another value with significant `Drop` created here\nLL |         },\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     mutex.lock().unwrap().i = i;\nLL ~     match () {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:549:15\n   |\nLL |     match i = mutex.lock().unwrap().i {\n   |               ^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             println!(\"{}\", mutex.lock().unwrap().i);\n   |                            --------------------- another value with significant `Drop` created here\nLL |         },\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().i;\nLL ~     match i = value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:556:11\n   |\nLL |     match mutex.lock().unwrap().i += 1 {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             println!(\"{}\", mutex.lock().unwrap().i);\n   |                            --------------------- another value with significant `Drop` created here\nLL |         },\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     mutex.lock().unwrap().i += 1;\nLL ~     match () {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:563:16\n   |\nLL |     match i += mutex.lock().unwrap().i {\n   |                ^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             println!(\"{}\", mutex.lock().unwrap().i);\n   |                            --------------------- another value with significant `Drop` created here\nLL |         },\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().i;\nLL ~     match i += value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:627:11\n   |\nLL |     match rwlock.read().unwrap().to_number() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = rwlock.read().unwrap().to_number();\nLL ~     match value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:654:11\n   |\nLL |     match mutex.lock().unwrap().foo() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().foo();\nLL ~     match value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:716:11\n   |\nLL |     match guard.take().len() {\n   |           ^^^^^^^^^^^^^^^^^^\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = guard.take().len();\nLL ~     match value {\n   |\n\nerror: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:741:16\n   |\nLL |     for val in mutex.lock().unwrap().copy_old_lifetime() {\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     }\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().copy_old_lifetime();\nLL ~     for val in value {\n   |\n\nerror: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:780:17\n   |\nLL |     for val in [mutex.lock().unwrap()[0], 2] {\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     }\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap()[0];\nLL ~     for val in [value, 2] {\n   |\n\nerror: temporary with significant `Drop` in `if let` scrutinee will live until the end of the `if let` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:789:24\n   |\nLL |     if let Some(val) = mutex.lock().unwrap().first().copied() {\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     }\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().first().copied();\nLL ~     if let Some(val) = value {\n   |\n\nerror: temporary with significant `Drop` in `while let` scrutinee will live until the end of the `while let` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:804:27\n   |\nLL |     while let Some(val) = mutex.lock().unwrap().pop() {\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     }\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:815:11\n   |\nLL |     match *foo_async(&mutex).await.unwrap() {\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     }\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = *foo_async(&mutex).await.unwrap();\nLL ~     match value {\n   |\n\nerror: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression\n  --> tests/ui/significant_drop_in_scrutinee.rs:835:19\n   |\nLL |     let _ = match mutex.lock().unwrap().foo() {\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     };\n   |      - temporary lives until here\n   |\n   = note: this might lead to deadlocks or other unexpected behavior\nhelp: try moving the temporary above the match\n   |\nLL ~     let value = mutex.lock().unwrap().foo();\nLL ~     let _ = match value {\n   |\n\nerror: aborting due to 31 previous errors\n\n"
  },
  {
    "path": "tests/ui/significant_drop_tightening.fixed",
    "content": "#![warn(clippy::significant_drop_tightening)]\n\nuse std::sync::Mutex;\n\npub fn complex_return_triggers_the_lint() -> i32 {\n    fn foo() -> i32 {\n        1\n    }\n    let mutex = Mutex::new(1);\n    let lock = mutex.lock().unwrap();\n    //~^ significant_drop_tightening\n    let _ = *lock;\n    let _ = *lock;\n    drop(lock);\n    foo()\n}\n\npub fn issue_10413() {\n    let mutex = Mutex::new(Some(1));\n    let opt = Some(1);\n    if opt.is_some() {\n        let lock = mutex.lock().unwrap();\n        let _ = *lock;\n        if opt.is_some() {\n            let _ = *lock;\n        }\n    }\n}\n\npub fn issue_11128() {\n    use std::mem::drop as unlock;\n\n    struct Foo {\n        droppable: Option<Vec<i32>>,\n        mutex: Mutex<Vec<i32>>,\n    }\n\n    impl Drop for Foo {\n        fn drop(&mut self) {\n            if let Some(droppable) = self.droppable.take() {\n                let lock = self.mutex.lock().unwrap();\n                let idx_opt = lock.iter().copied().find(|el| Some(el) == droppable.first());\n                if let Some(idx) = idx_opt {\n                    let local_droppable = vec![lock.first().copied().unwrap_or_default()];\n                    unlock(lock);\n                    drop(local_droppable);\n                }\n            }\n        }\n    }\n}\n\npub fn issue_11160() -> bool {\n    let mutex = Mutex::new(1i32);\n    let lock = mutex.lock().unwrap();\n    let _ = lock.abs();\n    true\n}\n\npub fn issue_11189() {\n    struct Number {\n        pub value: u32,\n    }\n\n    fn do_something() -> Result<(), ()> {\n        let number = Mutex::new(Number { value: 1 });\n        let number2 = Mutex::new(Number { value: 2 });\n        let number3 = Mutex::new(Number { value: 3 });\n        let mut lock = number.lock().unwrap();\n        let mut lock2 = number2.lock().unwrap();\n        let mut lock3 = number3.lock().unwrap();\n        lock.value += 1;\n        lock2.value += 1;\n        lock3.value += 1;\n        drop((lock, lock2, lock3));\n        Ok(())\n    }\n}\n\npub fn path_return_can_be_ignored() -> i32 {\n    let mutex = Mutex::new(1);\n    let lock = mutex.lock().unwrap();\n    let rslt = *lock;\n    let _ = *lock;\n    rslt\n}\n\npub fn post_bindings_can_be_ignored() {\n    let mutex = Mutex::new(1);\n    let lock = mutex.lock().unwrap();\n    let rslt = *lock;\n    let another = rslt;\n    let _ = another;\n}\n\npub fn unnecessary_contention_with_multiple_owned_results() {\n    {\n        let mutex = Mutex::new(1i32);\n        let lock = mutex.lock().unwrap();\n        let _ = lock.abs();\n        let _ = lock.is_positive();\n    }\n\n    {\n        let mutex = Mutex::new(1i32);\n        let lock = mutex.lock().unwrap();\n        //~^ significant_drop_tightening\n        let rslt0 = lock.abs();\n        let rslt1 = lock.is_positive();\n        drop(lock);\n        do_heavy_computation_that_takes_time((rslt0, rslt1));\n    }\n}\n\npub fn unnecessary_contention_with_single_owned_results() {\n    {\n        let mutex = Mutex::new(1i32);\n        let lock = mutex.lock().unwrap();\n        let _ = lock.abs();\n    }\n    {\n        let mutex = Mutex::new(vec![1i32]);\n        let mut lock = mutex.lock().unwrap();\n        lock.clear();\n    }\n\n    {\n        let mutex = Mutex::new(1i32);\n        \n        let rslt0 = mutex.lock().unwrap().abs();\n        //~^ significant_drop_tightening\n        \n        do_heavy_computation_that_takes_time(rslt0);\n    }\n    {\n        let mutex = Mutex::new(vec![1i32]);\n        \n        mutex.lock().unwrap().clear();\n        //~^ significant_drop_tightening\n        \n        do_heavy_computation_that_takes_time(());\n    }\n}\n\n// Marker used for illustration purposes.\npub fn do_heavy_computation_that_takes_time<T>(_: T) {}\n\nfn main() {}\n\nfn issue15574() {\n    use std::io::{BufRead, Read, stdin};\n    use std::process;\n\n    println!(\"Hello, what's your name?\");\n    \n    let mut stdin = stdin().lock().take(40);\n    //~^ significant_drop_tightening\n    let mut buffer = String::with_capacity(10);\n\n    \n    //~^ significant_drop_tightening\n    if stdin.read_line(&mut buffer).is_err() {\n        eprintln!(\"An error has occured while reading.\");\n        return;\n    }\n    drop(stdin);\n    println!(\"Our string has a capacity of {}\", buffer.capacity());\n    println!(\"Hello {}!\", buffer);\n}\n\nfn issue16343() {\n    fn get_items(x: &()) -> Vec<()> {\n        vec![*x]\n    }\n\n    let storage = Mutex::new(());\n    let lock = storage.lock().unwrap();\n    //~^ significant_drop_tightening\n    let items = get_items(&lock);\n    drop(lock);\n    for item in items {\n        println!(\"item {:?}\", item);\n    }\n}\n"
  },
  {
    "path": "tests/ui/significant_drop_tightening.rs",
    "content": "#![warn(clippy::significant_drop_tightening)]\n\nuse std::sync::Mutex;\n\npub fn complex_return_triggers_the_lint() -> i32 {\n    fn foo() -> i32 {\n        1\n    }\n    let mutex = Mutex::new(1);\n    let lock = mutex.lock().unwrap();\n    //~^ significant_drop_tightening\n    let _ = *lock;\n    let _ = *lock;\n    foo()\n}\n\npub fn issue_10413() {\n    let mutex = Mutex::new(Some(1));\n    let opt = Some(1);\n    if opt.is_some() {\n        let lock = mutex.lock().unwrap();\n        let _ = *lock;\n        if opt.is_some() {\n            let _ = *lock;\n        }\n    }\n}\n\npub fn issue_11128() {\n    use std::mem::drop as unlock;\n\n    struct Foo {\n        droppable: Option<Vec<i32>>,\n        mutex: Mutex<Vec<i32>>,\n    }\n\n    impl Drop for Foo {\n        fn drop(&mut self) {\n            if let Some(droppable) = self.droppable.take() {\n                let lock = self.mutex.lock().unwrap();\n                let idx_opt = lock.iter().copied().find(|el| Some(el) == droppable.first());\n                if let Some(idx) = idx_opt {\n                    let local_droppable = vec![lock.first().copied().unwrap_or_default()];\n                    unlock(lock);\n                    drop(local_droppable);\n                }\n            }\n        }\n    }\n}\n\npub fn issue_11160() -> bool {\n    let mutex = Mutex::new(1i32);\n    let lock = mutex.lock().unwrap();\n    let _ = lock.abs();\n    true\n}\n\npub fn issue_11189() {\n    struct Number {\n        pub value: u32,\n    }\n\n    fn do_something() -> Result<(), ()> {\n        let number = Mutex::new(Number { value: 1 });\n        let number2 = Mutex::new(Number { value: 2 });\n        let number3 = Mutex::new(Number { value: 3 });\n        let mut lock = number.lock().unwrap();\n        let mut lock2 = number2.lock().unwrap();\n        let mut lock3 = number3.lock().unwrap();\n        lock.value += 1;\n        lock2.value += 1;\n        lock3.value += 1;\n        drop((lock, lock2, lock3));\n        Ok(())\n    }\n}\n\npub fn path_return_can_be_ignored() -> i32 {\n    let mutex = Mutex::new(1);\n    let lock = mutex.lock().unwrap();\n    let rslt = *lock;\n    let _ = *lock;\n    rslt\n}\n\npub fn post_bindings_can_be_ignored() {\n    let mutex = Mutex::new(1);\n    let lock = mutex.lock().unwrap();\n    let rslt = *lock;\n    let another = rslt;\n    let _ = another;\n}\n\npub fn unnecessary_contention_with_multiple_owned_results() {\n    {\n        let mutex = Mutex::new(1i32);\n        let lock = mutex.lock().unwrap();\n        let _ = lock.abs();\n        let _ = lock.is_positive();\n    }\n\n    {\n        let mutex = Mutex::new(1i32);\n        let lock = mutex.lock().unwrap();\n        //~^ significant_drop_tightening\n        let rslt0 = lock.abs();\n        let rslt1 = lock.is_positive();\n        do_heavy_computation_that_takes_time((rslt0, rslt1));\n    }\n}\n\npub fn unnecessary_contention_with_single_owned_results() {\n    {\n        let mutex = Mutex::new(1i32);\n        let lock = mutex.lock().unwrap();\n        let _ = lock.abs();\n    }\n    {\n        let mutex = Mutex::new(vec![1i32]);\n        let mut lock = mutex.lock().unwrap();\n        lock.clear();\n    }\n\n    {\n        let mutex = Mutex::new(1i32);\n        let lock = mutex.lock().unwrap();\n        //~^ significant_drop_tightening\n        let rslt0 = lock.abs();\n        do_heavy_computation_that_takes_time(rslt0);\n    }\n    {\n        let mutex = Mutex::new(vec![1i32]);\n        let mut lock = mutex.lock().unwrap();\n        //~^ significant_drop_tightening\n        lock.clear();\n        do_heavy_computation_that_takes_time(());\n    }\n}\n\n// Marker used for illustration purposes.\npub fn do_heavy_computation_that_takes_time<T>(_: T) {}\n\nfn main() {}\n\nfn issue15574() {\n    use std::io::{BufRead, Read, stdin};\n    use std::process;\n\n    println!(\"Hello, what's your name?\");\n    let stdin = stdin().lock();\n    //~^ significant_drop_tightening\n    let mut buffer = String::with_capacity(10);\n\n    let mut stdin = stdin.take(40);\n    //~^ significant_drop_tightening\n    if stdin.read_line(&mut buffer).is_err() {\n        eprintln!(\"An error has occured while reading.\");\n        return;\n    }\n    println!(\"Our string has a capacity of {}\", buffer.capacity());\n    println!(\"Hello {}!\", buffer);\n}\n\nfn issue16343() {\n    fn get_items(x: &()) -> Vec<()> {\n        vec![*x]\n    }\n\n    let storage = Mutex::new(());\n    let lock = storage.lock().unwrap();\n    //~^ significant_drop_tightening\n    let items = get_items(&lock);\n    for item in items {\n        println!(\"item {:?}\", item);\n    }\n}\n"
  },
  {
    "path": "tests/ui/significant_drop_tightening.stderr",
    "content": "error: temporary with significant `Drop` can be early dropped\n  --> tests/ui/significant_drop_tightening.rs:10:9\n   |\nLL |   pub fn complex_return_triggers_the_lint() -> i32 {\n   |  __________________________________________________-\nLL | |     fn foo() -> i32 {\nLL | |         1\n...  |\nLL | |     let lock = mutex.lock().unwrap();\n   | |         ^^^^\n...  |\nLL | |     foo()\nLL | | }\n   | |_- temporary `lock` is currently being dropped at the end of its contained scope\n   |\n   = note: this might lead to unnecessary resource contention\n   = note: `-D clippy::significant-drop-tightening` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::significant_drop_tightening)]`\nhelp: drop the temporary after the end of its last usage\n   |\nLL ~     let _ = *lock;\nLL +     drop(lock);\n   |\n\nerror: temporary with significant `Drop` can be early dropped\n  --> tests/ui/significant_drop_tightening.rs:105:13\n   |\nLL | /     {\nLL | |         let mutex = Mutex::new(1i32);\nLL | |         let lock = mutex.lock().unwrap();\n   | |             ^^^^\n...  |\nLL | |         do_heavy_computation_that_takes_time((rslt0, rslt1));\nLL | |     }\n   | |_____- temporary `lock` is currently being dropped at the end of its contained scope\n   |\n   = note: this might lead to unnecessary resource contention\nhelp: drop the temporary after the end of its last usage\n   |\nLL ~         let rslt1 = lock.is_positive();\nLL +         drop(lock);\n   |\n\nerror: temporary with significant `Drop` can be early dropped\n  --> tests/ui/significant_drop_tightening.rs:127:13\n   |\nLL | /     {\nLL | |         let mutex = Mutex::new(1i32);\nLL | |         let lock = mutex.lock().unwrap();\n   | |             ^^^^\n...  |\nLL | |         do_heavy_computation_that_takes_time(rslt0);\nLL | |     }\n   | |_____- temporary `lock` is currently being dropped at the end of its contained scope\n   |\n   = note: this might lead to unnecessary resource contention\nhelp: merge the temporary construction with its single usage\n   |\nLL ~         \nLL +         let rslt0 = mutex.lock().unwrap().abs();\nLL |\nLL ~         \n   |\n\nerror: temporary with significant `Drop` can be early dropped\n  --> tests/ui/significant_drop_tightening.rs:134:17\n   |\nLL | /     {\nLL | |         let mutex = Mutex::new(vec![1i32]);\nLL | |         let mut lock = mutex.lock().unwrap();\n   | |                 ^^^^\n...  |\nLL | |         do_heavy_computation_that_takes_time(());\nLL | |     }\n   | |_____- temporary `lock` is currently being dropped at the end of its contained scope\n   |\n   = note: this might lead to unnecessary resource contention\nhelp: merge the temporary construction with its single usage\n   |\nLL ~         \nLL +         mutex.lock().unwrap().clear();\nLL |\nLL ~         \n   |\n\nerror: temporary with significant `Drop` can be early dropped\n  --> tests/ui/significant_drop_tightening.rs:151:9\n   |\nLL |   fn issue15574() {\n   |  _________________-\nLL | |     use std::io::{BufRead, Read, stdin};\nLL | |     use std::process;\n...  |\nLL | |     let stdin = stdin().lock();\n   | |         ^^^^^\n...  |\nLL | |     println!(\"Hello {}!\", buffer);\nLL | | }\n   | |_- temporary `stdin` is currently being dropped at the end of its contained scope\n   |\n   = note: this might lead to unnecessary resource contention\nhelp: merge the temporary construction with its single usage\n   |\nLL ~     \nLL +     let mut stdin = stdin().lock().take(40);\nLL |\nLL |     let mut buffer = String::with_capacity(10);\nLL |\nLL ~     \n   |\n\nerror: temporary with significant `Drop` can be early dropped\n  --> tests/ui/significant_drop_tightening.rs:155:13\n   |\nLL |   fn issue15574() {\n   |  _________________-\nLL | |     use std::io::{BufRead, Read, stdin};\nLL | |     use std::process;\n...  |\nLL | |     let mut stdin = stdin.take(40);\n   | |             ^^^^^\n...  |\nLL | |     println!(\"Hello {}!\", buffer);\nLL | | }\n   | |_- temporary `stdin` is currently being dropped at the end of its contained scope\n   |\n   = note: this might lead to unnecessary resource contention\nhelp: drop the temporary after the end of its last usage\n   |\nLL ~     }\nLL +     drop(stdin);\n   |\n\nerror: temporary with significant `Drop` can be early dropped\n  --> tests/ui/significant_drop_tightening.rs:171:9\n   |\nLL |   fn issue16343() {\n   |  _________________-\nLL | |     fn get_items(x: &()) -> Vec<()> {\nLL | |         vec![*x]\n...  |\nLL | |     let lock = storage.lock().unwrap();\n   | |         ^^^^\n...  |\nLL | | }\n   | |_- temporary `lock` is currently being dropped at the end of its contained scope\n   |\n   = note: this might lead to unnecessary resource contention\nhelp: drop the temporary after the end of its last usage\n   |\nLL ~     let items = get_items(&lock);\nLL +     drop(lock);\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/similar_names.rs",
    "content": "#![warn(clippy::similar_names)]\n#![allow(\n    unused,\n    clippy::println_empty_string,\n    clippy::empty_loop,\n    clippy::never_loop,\n    clippy::diverging_sub_expression,\n    clippy::let_unit_value\n)]\n\nstruct Foo {\n    apple: i32,\n    bpple: i32,\n}\n\nfn main() {\n    let specter: i32;\n    let spectre: i32;\n\n    // ok; first letter is different enough\n    let apple: i32;\n    let bpple: i32;\n    let cpple: i32;\n\n    let a_bar: i32;\n    let b_bar: i32;\n    let c_bar: i32;\n\n    let items = [5];\n    for item in &items {\n        loop {}\n    }\n\n    let foo_x: i32;\n    let foo_y: i32;\n\n    let rhs: i32;\n    let lhs: i32;\n\n    let bla_rhs: i32;\n    let bla_lhs: i32;\n\n    let blubrhs: i32;\n    let blublhs: i32;\n\n    let blubx: i32;\n    let bluby: i32;\n    //~^ similar_names\n\n    let cake: i32;\n    let cakes: i32;\n    let coke: i32;\n    //~^ similar_names\n\n    match 5 {\n        cheese @ 1 => {},\n        rabbit => panic!(),\n    }\n    let cheese: i32;\n    match (42, 43) {\n        (cheese1, 1) => {},\n        (cheese2, 2) => panic!(),\n        _ => println!(\"\"),\n    }\n    let ipv4: i32;\n    let ipv6: i32;\n    let abcd1: i32;\n    let abdc2: i32;\n    let xyz1abc: i32;\n    let xyz2abc: i32;\n    let xyzeabc: i32;\n    //~^ similar_names\n\n    let parser: i32;\n    let parsed: i32;\n    let parsee: i32;\n    //~^ similar_names\n\n    let setter: i32;\n    let getter: i32;\n    let tx1: i32;\n    let rx1: i32;\n    let tx_cake: i32;\n    let rx_cake: i32;\n\n    // names often used in win32 code (for example WindowProc)\n    let wparam: i32;\n    let lparam: i32;\n\n    let iter: i32;\n    let item: i32;\n\n    // 3 letter names are allowed to be similar\n    let kta: i32;\n    let ktv: i32;\n}\n\nfn foo() {\n    let Foo { apple, bpple } = unimplemented!();\n    let Foo {\n        apple: spring,\n        bpple: sprang,\n        //~^ similar_names\n    } = unimplemented!();\n}\n\n// false positive similar_names (#3057, #2651)\n// clippy claimed total_reg_src_size and total_size and\n// numb_reg_src_checkouts and total_bin_size were similar\n#[derive(Debug, Clone)]\npub(crate) struct DirSizes {\n    pub(crate) total_size: u64,\n    pub(crate) numb_bins: u64,\n    pub(crate) total_bin_size: u64,\n    pub(crate) total_reg_size: u64,\n    pub(crate) total_git_db_size: u64,\n    pub(crate) total_git_repos_bare_size: u64,\n    pub(crate) numb_git_repos_bare_repos: u64,\n    pub(crate) numb_git_checkouts: u64,\n    pub(crate) total_git_chk_size: u64,\n    pub(crate) total_reg_cache_size: u64,\n    pub(crate) total_reg_src_size: u64,\n    pub(crate) numb_reg_cache_entries: u64,\n    pub(crate) numb_reg_src_checkouts: u64,\n}\n\nfn ignore_underscore_prefix() {\n    let hello: ();\n    let _hello: ();\n}\n"
  },
  {
    "path": "tests/ui/similar_names.stderr",
    "content": "error: binding's name is too similar to existing binding\n  --> tests/ui/similar_names.rs:47:9\n   |\nLL |     let bluby: i32;\n   |         ^^^^^\n   |\nnote: existing binding defined here\n  --> tests/ui/similar_names.rs:46:9\n   |\nLL |     let blubx: i32;\n   |         ^^^^^\n   = note: `-D clippy::similar-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::similar_names)]`\n\nerror: binding's name is too similar to existing binding\n  --> tests/ui/similar_names.rs:52:9\n   |\nLL |     let coke: i32;\n   |         ^^^^\n   |\nnote: existing binding defined here\n  --> tests/ui/similar_names.rs:50:9\n   |\nLL |     let cake: i32;\n   |         ^^^^\n\nerror: binding's name is too similar to existing binding\n  --> tests/ui/similar_names.rs:71:9\n   |\nLL |     let xyzeabc: i32;\n   |         ^^^^^^^\n   |\nnote: existing binding defined here\n  --> tests/ui/similar_names.rs:69:9\n   |\nLL |     let xyz1abc: i32;\n   |         ^^^^^^^\n\nerror: binding's name is too similar to existing binding\n  --> tests/ui/similar_names.rs:76:9\n   |\nLL |     let parsee: i32;\n   |         ^^^^^^\n   |\nnote: existing binding defined here\n  --> tests/ui/similar_names.rs:74:9\n   |\nLL |     let parser: i32;\n   |         ^^^^^^\n\nerror: binding's name is too similar to existing binding\n  --> tests/ui/similar_names.rs:102:16\n   |\nLL |         bpple: sprang,\n   |                ^^^^^^\n   |\nnote: existing binding defined here\n  --> tests/ui/similar_names.rs:101:16\n   |\nLL |         apple: spring,\n   |                ^^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_call_fn.rs",
    "content": "//@ignore-bitwidth: 32\n//@aux-build:proc_macros.rs\n#![allow(clippy::redundant_closure_call, unused)]\n#![warn(clippy::single_call_fn)]\n#![no_main]\n\n#[macro_use]\nextern crate proc_macros;\n\n// Do not lint since it's public\npub fn f() {}\n\nfn i() {}\n//~^ single_call_fn\nfn j() {}\n//~^ single_call_fn\n\nfn h() {\n    // Linted\n    let a = i;\n    // Do not lint closures\n    let a = (|| {\n        // Not linted\n        a();\n        // Imo, it's reasonable to lint this as the function is still only being used once. Just in\n        // a closure.\n        j();\n    });\n    a();\n}\n\nfn g() {\n    f();\n}\n\nfn c() {\n    //~^ single_call_fn\n    println!(\"really\");\n    println!(\"long\");\n    println!(\"function...\");\n}\n\nfn d() {\n    c();\n}\n\nfn a() {}\n//~^ single_call_fn\n\nfn b() {\n    a();\n\n    external! {\n        fn lol() {\n            lol_inner();\n        }\n        fn lol_inner() {}\n    }\n    with_span! {\n        span\n        fn lol2() {\n            lol2_inner();\n        }\n        fn lol2_inner() {}\n    }\n}\n\nfn e() {\n    b();\n    b();\n}\n\n#[test]\nfn k() {}\n\nmod issue12182 {\n    #[allow(clippy::single_call_fn)]\n    fn print_foo(text: &str) {\n        println!(\"{text}\");\n    }\n\n    fn use_print_foo() {\n        print_foo(\"foo\");\n    }\n}\n\n#[test]\nfn l() {\n    k();\n}\n\ntrait Trait {\n    fn default() {}\n    //~^ single_call_fn\n    fn foo(&self);\n}\nunsafe extern \"C\" {\n    // test some kind of foreign item\n    fn rand() -> std::ffi::c_int;\n}\nfn m<T: Trait>(v: T) {\n    const NOT_A_FUNCTION: i32 = 1;\n    let _ = NOT_A_FUNCTION;\n\n    struct S;\n    impl S {\n        fn foo() {}\n        //~^ single_call_fn\n    }\n    T::default();\n    S::foo();\n    v.foo();\n    unsafe { rand() };\n}\n"
  },
  {
    "path": "tests/ui/single_call_fn.stderr",
    "content": "error: this function is only used once\n  --> tests/ui/single_call_fn.rs:13:1\n   |\nLL | fn i() {}\n   | ^^^^^^^^^\n   |\nnote: used here\n  --> tests/ui/single_call_fn.rs:20:13\n   |\nLL |     let a = i;\n   |             ^\n   = note: `-D clippy::single-call-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_call_fn)]`\n\nerror: this function is only used once\n  --> tests/ui/single_call_fn.rs:15:1\n   |\nLL | fn j() {}\n   | ^^^^^^^^^\n   |\nnote: used here\n  --> tests/ui/single_call_fn.rs:27:9\n   |\nLL |         j();\n   |         ^\n\nerror: this function is only used once\n  --> tests/ui/single_call_fn.rs:36:1\n   |\nLL | / fn c() {\nLL | |\nLL | |     println!(\"really\");\nLL | |     println!(\"long\");\nLL | |     println!(\"function...\");\nLL | | }\n   | |_^\n   |\nnote: used here\n  --> tests/ui/single_call_fn.rs:44:5\n   |\nLL |     c();\n   |     ^\n\nerror: this function is only used once\n  --> tests/ui/single_call_fn.rs:47:1\n   |\nLL | fn a() {}\n   | ^^^^^^^^^\n   |\nnote: used here\n  --> tests/ui/single_call_fn.rs:51:5\n   |\nLL |     a();\n   |     ^\n\nerror: this function is only used once\n  --> tests/ui/single_call_fn.rs:93:5\n   |\nLL |     fn default() {}\n   |     ^^^^^^^^^^^^^^^\n   |\nnote: used here\n  --> tests/ui/single_call_fn.rs:110:5\n   |\nLL |     T::default();\n   |     ^^^^^^^^^^\n\nerror: this function is only used once\n  --> tests/ui/single_call_fn.rs:107:9\n   |\nLL |         fn foo() {}\n   |         ^^^^^^^^^^^\n   |\nnote: used here\n  --> tests/ui/single_call_fn.rs:111:5\n   |\nLL |     S::foo();\n   |     ^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_char_add_str.fixed",
    "content": "#![warn(clippy::single_char_add_str)]\n#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes)]\n\nmacro_rules! get_string {\n    () => {\n        String::from(\"Hello world!\")\n    };\n}\n\nfn main() {\n    // `push_str` tests\n\n    let mut string = String::new();\n    string.push('R');\n    //~^ single_char_add_str\n    string.push('\\'');\n    //~^ single_char_add_str\n\n    string.push('u');\n    string.push_str(\"st\");\n    string.push_str(\"\");\n    string.push('\\x52');\n    //~^ single_char_add_str\n    string.push('\\u{0052}');\n    //~^ single_char_add_str\n    string.push('a');\n    //~^ single_char_add_str\n\n    let c_ref = &'a';\n    string.push(*c_ref);\n    //~^ single_char_add_str\n    let c = 'a';\n    string.push(c);\n    //~^ single_char_add_str\n    string.push('a');\n    //~^ single_char_add_str\n\n    get_string!().push('ö');\n    //~^ single_char_add_str\n\n    // `insert_str` tests\n\n    let mut string = String::new();\n    string.insert(0, 'R');\n    //~^ single_char_add_str\n    string.insert(1, '\\'');\n    //~^ single_char_add_str\n\n    string.insert(0, 'u');\n    string.insert_str(2, \"st\");\n    string.insert_str(0, \"\");\n    string.insert(0, '\\x52');\n    //~^ single_char_add_str\n    string.insert(0, '\\u{0052}');\n    //~^ single_char_add_str\n    let x: usize = 2;\n    string.insert(x, 'a');\n    //~^ single_char_add_str\n    const Y: usize = 1;\n    string.insert(Y, 'a');\n    //~^ single_char_add_str\n    string.insert(Y, '\"');\n    //~^ single_char_add_str\n    string.insert(Y, '\\'');\n    //~^ single_char_add_str\n\n    string.insert(0, *c_ref);\n    //~^ single_char_add_str\n    string.insert(0, c);\n    //~^ single_char_add_str\n    string.insert(0, 'a');\n    //~^ single_char_add_str\n\n    get_string!().insert(1, '?');\n    //~^ single_char_add_str\n}\n"
  },
  {
    "path": "tests/ui/single_char_add_str.rs",
    "content": "#![warn(clippy::single_char_add_str)]\n#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes)]\n\nmacro_rules! get_string {\n    () => {\n        String::from(\"Hello world!\")\n    };\n}\n\nfn main() {\n    // `push_str` tests\n\n    let mut string = String::new();\n    string.push_str(\"R\");\n    //~^ single_char_add_str\n    string.push_str(\"'\");\n    //~^ single_char_add_str\n\n    string.push('u');\n    string.push_str(\"st\");\n    string.push_str(\"\");\n    string.push_str(\"\\x52\");\n    //~^ single_char_add_str\n    string.push_str(\"\\u{0052}\");\n    //~^ single_char_add_str\n    string.push_str(r##\"a\"##);\n    //~^ single_char_add_str\n\n    let c_ref = &'a';\n    string.push_str(&c_ref.to_string());\n    //~^ single_char_add_str\n    let c = 'a';\n    string.push_str(&c.to_string());\n    //~^ single_char_add_str\n    string.push_str(&'a'.to_string());\n    //~^ single_char_add_str\n\n    get_string!().push_str(\"ö\");\n    //~^ single_char_add_str\n\n    // `insert_str` tests\n\n    let mut string = String::new();\n    string.insert_str(0, \"R\");\n    //~^ single_char_add_str\n    string.insert_str(1, \"'\");\n    //~^ single_char_add_str\n\n    string.insert(0, 'u');\n    string.insert_str(2, \"st\");\n    string.insert_str(0, \"\");\n    string.insert_str(0, \"\\x52\");\n    //~^ single_char_add_str\n    string.insert_str(0, \"\\u{0052}\");\n    //~^ single_char_add_str\n    let x: usize = 2;\n    string.insert_str(x, r##\"a\"##);\n    //~^ single_char_add_str\n    const Y: usize = 1;\n    string.insert_str(Y, r##\"a\"##);\n    //~^ single_char_add_str\n    string.insert_str(Y, r##\"\"\"##);\n    //~^ single_char_add_str\n    string.insert_str(Y, r##\"'\"##);\n    //~^ single_char_add_str\n\n    string.insert_str(0, &c_ref.to_string());\n    //~^ single_char_add_str\n    string.insert_str(0, &c.to_string());\n    //~^ single_char_add_str\n    string.insert_str(0, &'a'.to_string());\n    //~^ single_char_add_str\n\n    get_string!().insert_str(1, \"?\");\n    //~^ single_char_add_str\n}\n"
  },
  {
    "path": "tests/ui/single_char_add_str.stderr",
    "content": "error: calling `push_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:14:5\n   |\nLL |     string.push_str(\"R\");\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('R')`\n   |\n   = note: `-D clippy::single-char-add-str` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_char_add_str)]`\n\nerror: calling `push_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:16:5\n   |\nLL |     string.push_str(\"'\");\n   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\\'')`\n\nerror: calling `push_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:22:5\n   |\nLL |     string.push_str(\"\\x52\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\\x52')`\n\nerror: calling `push_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:24:5\n   |\nLL |     string.push_str(\"\\u{0052}\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('\\u{0052}')`\n\nerror: calling `push_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:26:5\n   |\nLL |     string.push_str(r##\"a\"##);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('a')`\n\nerror: calling `push_str()` using a single-character converted to string\n  --> tests/ui/single_char_add_str.rs:30:5\n   |\nLL |     string.push_str(&c_ref.to_string());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push(*c_ref)`\n\nerror: calling `push_str()` using a single-character converted to string\n  --> tests/ui/single_char_add_str.rs:33:5\n   |\nLL |     string.push_str(&c.to_string());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push(c)`\n\nerror: calling `push_str()` using a single-character converted to string\n  --> tests/ui/single_char_add_str.rs:35:5\n   |\nLL |     string.push_str(&'a'.to_string());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push('a')`\n\nerror: calling `push_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:38:5\n   |\nLL |     get_string!().push_str(\"ö\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `get_string!().push('ö')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:44:5\n   |\nLL |     string.insert_str(0, \"R\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, 'R')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:46:5\n   |\nLL |     string.insert_str(1, \"'\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(1, '\\'')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:52:5\n   |\nLL |     string.insert_str(0, \"\\x52\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\\x52')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:54:5\n   |\nLL |     string.insert_str(0, \"\\u{0052}\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\\u{0052}')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:57:5\n   |\nLL |     string.insert_str(x, r##\"a\"##);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(x, 'a')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:60:5\n   |\nLL |     string.insert_str(Y, r##\"a\"##);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, 'a')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:62:5\n   |\nLL |     string.insert_str(Y, r##\"\"\"##);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '\"')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:64:5\n   |\nLL |     string.insert_str(Y, r##\"'\"##);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '\\'')`\n\nerror: calling `insert_str()` using a single-character converted to string\n  --> tests/ui/single_char_add_str.rs:67:5\n   |\nLL |     string.insert_str(0, &c_ref.to_string());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, *c_ref)`\n\nerror: calling `insert_str()` using a single-character converted to string\n  --> tests/ui/single_char_add_str.rs:69:5\n   |\nLL |     string.insert_str(0, &c.to_string());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, c)`\n\nerror: calling `insert_str()` using a single-character converted to string\n  --> tests/ui/single_char_add_str.rs:71:5\n   |\nLL |     string.insert_str(0, &'a'.to_string());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, 'a')`\n\nerror: calling `insert_str()` using a single-character string literal\n  --> tests/ui/single_char_add_str.rs:74:5\n   |\nLL |     get_string!().insert_str(1, \"?\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `get_string!().insert(1, '?')`\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_char_lifetime_names.rs",
    "content": "#![warn(clippy::single_char_lifetime_names)]\n#![allow(clippy::let_unit_value)]\n\n// Lifetimes should only be linted when they're introduced\nstruct DiagnosticCtx<'a, 'b>\n//~^ single_char_lifetime_names\n//~| single_char_lifetime_names\nwhere\n    'a: 'b,\n{\n    _source: &'a str,\n    _unit: &'b (),\n}\n\n// Only the lifetimes on the `impl`'s generics should be linted\nimpl<'a, 'b> DiagnosticCtx<'a, 'b> {\n    //~^ single_char_lifetime_names\n    //~| single_char_lifetime_names\n\n    fn new(source: &'a str, unit: &'b ()) -> DiagnosticCtx<'a, 'b> {\n        Self {\n            _source: source,\n            _unit: unit,\n        }\n    }\n}\n\n// No lifetimes should be linted here\nimpl<'src, 'unit> DiagnosticCtx<'src, 'unit> {\n    fn new_pass(source: &'src str, unit: &'unit ()) -> DiagnosticCtx<'src, 'unit> {\n        Self {\n            _source: source,\n            _unit: unit,\n        }\n    }\n}\n\n// Only 'a should be linted here\nfn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) {\n    //~^ single_char_lifetime_names\n\n    base.split_once(other)\n        .map(|(left, right)| (left, Some(right)))\n        .unwrap_or((base, None))\n}\n\nfn main() {\n    let src = \"loop {}\";\n    let unit = ();\n    DiagnosticCtx::new(src, &unit);\n}\n"
  },
  {
    "path": "tests/ui/single_char_lifetime_names.stderr",
    "content": "error: single-character lifetime names are likely uninformative\n  --> tests/ui/single_char_lifetime_names.rs:5:22\n   |\nLL | struct DiagnosticCtx<'a, 'b>\n   |                      ^^\n   |\n   = help: use a more informative name\n   = note: `-D clippy::single-char-lifetime-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_char_lifetime_names)]`\n\nerror: single-character lifetime names are likely uninformative\n  --> tests/ui/single_char_lifetime_names.rs:5:26\n   |\nLL | struct DiagnosticCtx<'a, 'b>\n   |                          ^^\n   |\n   = help: use a more informative name\n\nerror: single-character lifetime names are likely uninformative\n  --> tests/ui/single_char_lifetime_names.rs:16:6\n   |\nLL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {\n   |      ^^\n   |\n   = help: use a more informative name\n\nerror: single-character lifetime names are likely uninformative\n  --> tests/ui/single_char_lifetime_names.rs:16:10\n   |\nLL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {\n   |          ^^\n   |\n   = help: use a more informative name\n\nerror: single-character lifetime names are likely uninformative\n  --> tests/ui/single_char_lifetime_names.rs:39:15\n   |\nLL | fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) {\n   |               ^^\n   |\n   = help: use a more informative name\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_char_pattern.fixed",
    "content": "#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)]\n#![warn(clippy::single_char_pattern)]\nuse std::collections::HashSet;\n\nfn main() {\n    let x = \"foo\";\n    x.split('x');\n    //~^ single_char_pattern\n    x.split(\"xx\");\n    x.split('x');\n\n    let y = \"x\";\n    x.split(y);\n    x.split(\"ß\");\n    x.split(\"ℝ\");\n    x.split(\"💣\");\n    // Can't use this lint for unicode code points which don't fit in a char\n    x.split(\"❤️\");\n    x.split_inclusive('x');\n    //~^ single_char_pattern\n    x.contains('x');\n    //~^ single_char_pattern\n    x.starts_with('x');\n    //~^ single_char_pattern\n    x.ends_with('x');\n    //~^ single_char_pattern\n    x.find('x');\n    //~^ single_char_pattern\n    x.rfind('x');\n    //~^ single_char_pattern\n    x.rsplit('x');\n    //~^ single_char_pattern\n    x.split_terminator('x');\n    //~^ single_char_pattern\n    x.rsplit_terminator('x');\n    //~^ single_char_pattern\n    x.splitn(2, 'x');\n    //~^ single_char_pattern\n    x.rsplitn(2, 'x');\n    //~^ single_char_pattern\n    x.split_once('x');\n    //~^ single_char_pattern\n    x.rsplit_once('x');\n    //~^ single_char_pattern\n    x.matches('x');\n    //~^ single_char_pattern\n    x.rmatches('x');\n    //~^ single_char_pattern\n    x.match_indices('x');\n    //~^ single_char_pattern\n    x.rmatch_indices('x');\n    //~^ single_char_pattern\n    x.trim_start_matches('x');\n    //~^ single_char_pattern\n    x.trim_end_matches('x');\n    //~^ single_char_pattern\n    x.replace('x', \"y\");\n    //~^ single_char_pattern\n    x.replacen('x', \"y\", 3);\n    //~^ single_char_pattern\n    // Make sure we escape characters correctly.\n    x.split('\\n');\n    //~^ single_char_pattern\n    x.split('\\'');\n    //~^ single_char_pattern\n    x.split('\\'');\n    //~^ single_char_pattern\n    // Issue #11973: Don't escape `\"` in `'\"'`\n    x.split('\"');\n    //~^ single_char_pattern\n\n    let h = HashSet::<String>::new();\n    h.contains(\"X\"); // should not warn\n\n    x.replace(';', \",\").split(','); // issue #2978\n    //\n    //~^^ single_char_pattern\n    x.starts_with('\\x03'); // issue #2996\n    //\n    //~^^ single_char_pattern\n\n    // Issue #3204\n    const S: &str = \"#\";\n    x.find(S);\n\n    // Raw string\n    x.split('a');\n    //~^ single_char_pattern\n    x.split('a');\n    //~^ single_char_pattern\n    x.split('a');\n    //~^ single_char_pattern\n    x.split('\\'');\n    //~^ single_char_pattern\n    x.split('#');\n    //~^ single_char_pattern\n    // Must escape backslash in raw strings when converting to char #8060\n    x.split('\\\\');\n    //~^ single_char_pattern\n    x.split('\\\\');\n    //~^ single_char_pattern\n\n    // should not warn, the char versions are actually slower in some cases\n    x.strip_prefix(\"x\");\n    x.strip_suffix(\"x\");\n}\n"
  },
  {
    "path": "tests/ui/single_char_pattern.rs",
    "content": "#![allow(clippy::needless_raw_strings, clippy::needless_raw_string_hashes, unused_must_use)]\n#![warn(clippy::single_char_pattern)]\nuse std::collections::HashSet;\n\nfn main() {\n    let x = \"foo\";\n    x.split(\"x\");\n    //~^ single_char_pattern\n    x.split(\"xx\");\n    x.split('x');\n\n    let y = \"x\";\n    x.split(y);\n    x.split(\"ß\");\n    x.split(\"ℝ\");\n    x.split(\"💣\");\n    // Can't use this lint for unicode code points which don't fit in a char\n    x.split(\"❤️\");\n    x.split_inclusive(\"x\");\n    //~^ single_char_pattern\n    x.contains(\"x\");\n    //~^ single_char_pattern\n    x.starts_with(\"x\");\n    //~^ single_char_pattern\n    x.ends_with(\"x\");\n    //~^ single_char_pattern\n    x.find(\"x\");\n    //~^ single_char_pattern\n    x.rfind(\"x\");\n    //~^ single_char_pattern\n    x.rsplit(\"x\");\n    //~^ single_char_pattern\n    x.split_terminator(\"x\");\n    //~^ single_char_pattern\n    x.rsplit_terminator(\"x\");\n    //~^ single_char_pattern\n    x.splitn(2, \"x\");\n    //~^ single_char_pattern\n    x.rsplitn(2, \"x\");\n    //~^ single_char_pattern\n    x.split_once(\"x\");\n    //~^ single_char_pattern\n    x.rsplit_once(\"x\");\n    //~^ single_char_pattern\n    x.matches(\"x\");\n    //~^ single_char_pattern\n    x.rmatches(\"x\");\n    //~^ single_char_pattern\n    x.match_indices(\"x\");\n    //~^ single_char_pattern\n    x.rmatch_indices(\"x\");\n    //~^ single_char_pattern\n    x.trim_start_matches(\"x\");\n    //~^ single_char_pattern\n    x.trim_end_matches(\"x\");\n    //~^ single_char_pattern\n    x.replace(\"x\", \"y\");\n    //~^ single_char_pattern\n    x.replacen(\"x\", \"y\", 3);\n    //~^ single_char_pattern\n    // Make sure we escape characters correctly.\n    x.split(\"\\n\");\n    //~^ single_char_pattern\n    x.split(\"'\");\n    //~^ single_char_pattern\n    x.split(\"\\'\");\n    //~^ single_char_pattern\n    // Issue #11973: Don't escape `\"` in `'\"'`\n    x.split(\"\\\"\");\n    //~^ single_char_pattern\n\n    let h = HashSet::<String>::new();\n    h.contains(\"X\"); // should not warn\n\n    x.replace(';', \",\").split(\",\"); // issue #2978\n    //\n    //~^^ single_char_pattern\n    x.starts_with(\"\\x03\"); // issue #2996\n    //\n    //~^^ single_char_pattern\n\n    // Issue #3204\n    const S: &str = \"#\";\n    x.find(S);\n\n    // Raw string\n    x.split(r\"a\");\n    //~^ single_char_pattern\n    x.split(r#\"a\"#);\n    //~^ single_char_pattern\n    x.split(r###\"a\"###);\n    //~^ single_char_pattern\n    x.split(r###\"'\"###);\n    //~^ single_char_pattern\n    x.split(r###\"#\"###);\n    //~^ single_char_pattern\n    // Must escape backslash in raw strings when converting to char #8060\n    x.split(r#\"\\\"#);\n    //~^ single_char_pattern\n    x.split(r\"\\\");\n    //~^ single_char_pattern\n\n    // should not warn, the char versions are actually slower in some cases\n    x.strip_prefix(\"x\");\n    x.strip_suffix(\"x\");\n}\n"
  },
  {
    "path": "tests/ui/single_char_pattern.stderr",
    "content": "error: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:7:13\n   |\nLL |     x.split(\"x\");\n   |             ^^^ help: consider using a `char`: `'x'`\n   |\n   = note: `-D clippy::single-char-pattern` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_char_pattern)]`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:19:23\n   |\nLL |     x.split_inclusive(\"x\");\n   |                       ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:21:16\n   |\nLL |     x.contains(\"x\");\n   |                ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:23:19\n   |\nLL |     x.starts_with(\"x\");\n   |                   ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:25:17\n   |\nLL |     x.ends_with(\"x\");\n   |                 ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:27:12\n   |\nLL |     x.find(\"x\");\n   |            ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:29:13\n   |\nLL |     x.rfind(\"x\");\n   |             ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:31:14\n   |\nLL |     x.rsplit(\"x\");\n   |              ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:33:24\n   |\nLL |     x.split_terminator(\"x\");\n   |                        ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:35:25\n   |\nLL |     x.rsplit_terminator(\"x\");\n   |                         ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:37:17\n   |\nLL |     x.splitn(2, \"x\");\n   |                 ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:39:18\n   |\nLL |     x.rsplitn(2, \"x\");\n   |                  ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:41:18\n   |\nLL |     x.split_once(\"x\");\n   |                  ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:43:19\n   |\nLL |     x.rsplit_once(\"x\");\n   |                   ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:45:15\n   |\nLL |     x.matches(\"x\");\n   |               ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:47:16\n   |\nLL |     x.rmatches(\"x\");\n   |                ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:49:21\n   |\nLL |     x.match_indices(\"x\");\n   |                     ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:51:22\n   |\nLL |     x.rmatch_indices(\"x\");\n   |                      ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:53:26\n   |\nLL |     x.trim_start_matches(\"x\");\n   |                          ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:55:24\n   |\nLL |     x.trim_end_matches(\"x\");\n   |                        ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:57:15\n   |\nLL |     x.replace(\"x\", \"y\");\n   |               ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:59:16\n   |\nLL |     x.replacen(\"x\", \"y\", 3);\n   |                ^^^ help: consider using a `char`: `'x'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:62:13\n   |\nLL |     x.split(\"\\n\");\n   |             ^^^^ help: consider using a `char`: `'\\n'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:64:13\n   |\nLL |     x.split(\"'\");\n   |             ^^^ help: consider using a `char`: `'\\''`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:66:13\n   |\nLL |     x.split(\"\\'\");\n   |             ^^^^ help: consider using a `char`: `'\\''`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:69:13\n   |\nLL |     x.split(\"\\\"\");\n   |             ^^^^ help: consider using a `char`: `'\"'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:75:31\n   |\nLL |     x.replace(';', \",\").split(\",\"); // issue #2978\n   |                               ^^^ help: consider using a `char`: `','`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:78:19\n   |\nLL |     x.starts_with(\"\\x03\"); // issue #2996\n   |                   ^^^^^^ help: consider using a `char`: `'\\x03'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:87:13\n   |\nLL |     x.split(r\"a\");\n   |             ^^^^ help: consider using a `char`: `'a'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:89:13\n   |\nLL |     x.split(r#\"a\"#);\n   |             ^^^^^^ help: consider using a `char`: `'a'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:91:13\n   |\nLL |     x.split(r###\"a\"###);\n   |             ^^^^^^^^^^ help: consider using a `char`: `'a'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:93:13\n   |\nLL |     x.split(r###\"'\"###);\n   |             ^^^^^^^^^^ help: consider using a `char`: `'\\''`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:95:13\n   |\nLL |     x.split(r###\"#\"###);\n   |             ^^^^^^^^^^ help: consider using a `char`: `'#'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:98:13\n   |\nLL |     x.split(r#\"\\\"#);\n   |             ^^^^^^ help: consider using a `char`: `'\\\\'`\n\nerror: single-character string constant used as pattern\n  --> tests/ui/single_char_pattern.rs:100:13\n   |\nLL |     x.split(r\"\\\");\n   |             ^^^^ help: consider using a `char`: `'\\\\'`\n\nerror: aborting due to 35 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_component_path_imports.fixed",
    "content": "#![warn(clippy::single_component_path_imports)]\n#![allow(unused_imports)]\n\nuse core;\n\n//~^ single_component_path_imports\n\nuse serde as edres;\n\npub use serde;\n\nuse std;\n\nmacro_rules! m {\n    () => {\n        use regex;\n    };\n}\n\nfn main() {\n    regex::Regex::new(r\"^\\d{4}-\\d{2}-\\d{2}$\").unwrap();\n\n    // False positive #5154, shouldn't trigger lint.\n    m!();\n\n    // False positive #10549\n    let _ = self::std::io::stdout();\n    let _ = 0 as self::core::ffi::c_uint;\n}\n\nmod hello_mod {\n    \n    //~^ single_component_path_imports\n    #[allow(dead_code)]\n    fn hello_mod() {}\n}\n\nmod hi_mod {\n    use self::regex::{Regex, RegexSet};\n    use regex;\n    #[allow(dead_code)]\n    fn hi_mod() {}\n}\n"
  },
  {
    "path": "tests/ui/single_component_path_imports.rs",
    "content": "#![warn(clippy::single_component_path_imports)]\n#![allow(unused_imports)]\n\nuse core;\n\nuse regex;\n//~^ single_component_path_imports\n\nuse serde as edres;\n\npub use serde;\n\nuse std;\n\nmacro_rules! m {\n    () => {\n        use regex;\n    };\n}\n\nfn main() {\n    regex::Regex::new(r\"^\\d{4}-\\d{2}-\\d{2}$\").unwrap();\n\n    // False positive #5154, shouldn't trigger lint.\n    m!();\n\n    // False positive #10549\n    let _ = self::std::io::stdout();\n    let _ = 0 as self::core::ffi::c_uint;\n}\n\nmod hello_mod {\n    use regex;\n    //~^ single_component_path_imports\n    #[allow(dead_code)]\n    fn hello_mod() {}\n}\n\nmod hi_mod {\n    use self::regex::{Regex, RegexSet};\n    use regex;\n    #[allow(dead_code)]\n    fn hi_mod() {}\n}\n"
  },
  {
    "path": "tests/ui/single_component_path_imports.stderr",
    "content": "error: this import is redundant\n  --> tests/ui/single_component_path_imports.rs:6:1\n   |\nLL | use regex;\n   | ^^^^^^^^^^ help: remove it entirely\n   |\n   = note: `-D clippy::single-component-path-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_component_path_imports)]`\n\nerror: this import is redundant\n  --> tests/ui/single_component_path_imports.rs:33:5\n   |\nLL |     use regex;\n   |     ^^^^^^^^^^ help: remove it entirely\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_component_path_imports_macro.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::single_component_path_imports)]\n#![allow(unused_imports)]\n\n// #7106: use statements exporting a macro within a crate should not trigger lint\n// #7923: normal `use` statements of macros should also not trigger the lint\n\nmacro_rules! m1 {\n    () => {};\n}\npub(crate) use m1; // ok\n\nmacro_rules! m2 {\n    () => {};\n}\nuse m2; // ok\n\nfn main() {\n    m1!();\n    m2!();\n}\n"
  },
  {
    "path": "tests/ui/single_component_path_imports_nested_first.rs",
    "content": "#![warn(clippy::single_component_path_imports)]\n#![allow(unused_imports)]\n//@no-rustfix\nuse regex;\n//~^ single_component_path_imports\n\nuse serde as edres;\n\npub use serde;\n\nfn main() {\n    regex::Regex::new(r\"^\\d{4}-\\d{2}-\\d{2}$\").unwrap();\n}\n\nmod root_nested_use_mod {\n    #[rustfmt::skip]\n    use {regex, serde};\n    //~^ single_component_path_imports\n    //~| single_component_path_imports\n\n    #[allow(dead_code)]\n    fn root_nested_use_mod() {}\n}\n"
  },
  {
    "path": "tests/ui/single_component_path_imports_nested_first.stderr",
    "content": "error: this import is redundant\n  --> tests/ui/single_component_path_imports_nested_first.rs:4:1\n   |\nLL | use regex;\n   | ^^^^^^^^^^ help: remove it entirely\n   |\n   = note: `-D clippy::single-component-path-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_component_path_imports)]`\n\nerror: this import is redundant\n  --> tests/ui/single_component_path_imports_nested_first.rs:17:10\n   |\nLL |     use {regex, serde};\n   |          ^^^^^\n   |\n   = help: remove this import\n\nerror: this import is redundant\n  --> tests/ui/single_component_path_imports_nested_first.rs:17:17\n   |\nLL |     use {regex, serde};\n   |                 ^^^^^\n   |\n   = help: remove this import\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_component_path_imports_self_after.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::single_component_path_imports)]\n#![allow(unused_imports)]\n\nuse self::regex::{Regex as xeger, RegexSet as tesxeger};\n#[rustfmt::skip]\npub use self::{\n    regex::{Regex, RegexSet},\n    some_mod::SomeType,\n};\nuse regex;\n\nmod some_mod {\n    pub struct SomeType;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/single_component_path_imports_self_before.rs",
    "content": "//@ check-pass\n\n#![warn(clippy::single_component_path_imports)]\n#![allow(unused_imports)]\n\nuse regex;\n\nuse self::regex::{Regex as xeger, RegexSet as tesxeger};\n#[rustfmt::skip]\npub use self::{\n    regex::{Regex, RegexSet},\n    some_mod::SomeType,\n};\n\nmod some_mod {\n    pub struct SomeType;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/single_element_loop.fixed",
    "content": "// Tests from for_loop.rs that don't have suggestions\n\n#![allow(clippy::single_range_in_vec_init)]\n\n#[warn(clippy::single_element_loop)]\nfn main() {\n    let item1 = 2;\n    {\n        let item = &item1;\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    {\n        let item = &item1;\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in 0..5 {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in 0..5 {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in 0..5 {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in 0..5 {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    // should not lint (issue #10018)\n    for e in [42] {\n        if e > 0 {\n            continue;\n        }\n    }\n\n    // should not lint (issue #10018)\n    for e in [42] {\n        if e > 0 {\n            break;\n        }\n    }\n\n    // should lint (issue #10018)\n    {\n        let _ = 42;\n        //~^ single_element_loop\n        let _f = |n: u32| {\n            for i in 0..n {\n                if i > 10 {\n                    dbg!(i);\n                    break;\n                }\n            }\n        };\n    }\n\n    // Should lint with correct suggestion (issue #12782)\n    let res_void: Result<bool, bool> = Ok(true);\n\n    {\n        let (Ok(mut _x) | Err(mut _x)) = res_void;\n        //~^ single_element_loop\n        let ptr: *const bool = std::ptr::null();\n    }\n}\n"
  },
  {
    "path": "tests/ui/single_element_loop.rs",
    "content": "// Tests from for_loop.rs that don't have suggestions\n\n#![allow(clippy::single_range_in_vec_init)]\n\n#[warn(clippy::single_element_loop)]\nfn main() {\n    let item1 = 2;\n    for item in &[item1] {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in [item1].iter() {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in &[0..5] {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in [0..5].iter_mut() {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in [0..5] {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    for item in [0..5].into_iter() {\n        //~^ single_element_loop\n        dbg!(item);\n    }\n\n    // should not lint (issue #10018)\n    for e in [42] {\n        if e > 0 {\n            continue;\n        }\n    }\n\n    // should not lint (issue #10018)\n    for e in [42] {\n        if e > 0 {\n            break;\n        }\n    }\n\n    // should lint (issue #10018)\n    for _ in [42] {\n        //~^ single_element_loop\n        let _f = |n: u32| {\n            for i in 0..n {\n                if i > 10 {\n                    dbg!(i);\n                    break;\n                }\n            }\n        };\n    }\n\n    // Should lint with correct suggestion (issue #12782)\n    let res_void: Result<bool, bool> = Ok(true);\n\n    for (Ok(mut _x) | Err(mut _x)) in [res_void] {\n        //~^ single_element_loop\n        let ptr: *const bool = std::ptr::null();\n    }\n}\n"
  },
  {
    "path": "tests/ui/single_element_loop.stderr",
    "content": "error: for loop over a single element\n  --> tests/ui/single_element_loop.rs:8:5\n   |\nLL | /     for item in &[item1] {\nLL | |\nLL | |         dbg!(item);\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::single-element-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_element_loop)]`\nhelp: try\n   |\nLL ~     {\nLL +         let item = &item1;\nLL +\nLL +         dbg!(item);\nLL +     }\n   |\n\nerror: for loop over a single element\n  --> tests/ui/single_element_loop.rs:13:5\n   |\nLL | /     for item in [item1].iter() {\nLL | |\nLL | |         dbg!(item);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     {\nLL +         let item = &item1;\nLL +\nLL +         dbg!(item);\nLL +     }\n   |\n\nerror: this loops only once with `item` being `0..5`\n  --> tests/ui/single_element_loop.rs:18:17\n   |\nLL |     for item in &[0..5] {\n   |                 ^^^^^^^ help: did you mean to iterate over the range instead?: `0..5`\n\nerror: this loops only once with `item` being `0..5`\n  --> tests/ui/single_element_loop.rs:23:17\n   |\nLL |     for item in [0..5].iter_mut() {\n   |                 ^^^^^^^^^^^^^^^^^ help: did you mean to iterate over the range instead?: `0..5`\n\nerror: this loops only once with `item` being `0..5`\n  --> tests/ui/single_element_loop.rs:28:17\n   |\nLL |     for item in [0..5] {\n   |                 ^^^^^^ help: did you mean to iterate over the range instead?: `0..5`\n\nerror: this loops only once with `item` being `0..5`\n  --> tests/ui/single_element_loop.rs:33:17\n   |\nLL |     for item in [0..5].into_iter() {\n   |                 ^^^^^^^^^^^^^^^^^^ help: did you mean to iterate over the range instead?: `0..5`\n\nerror: for loop over a single element\n  --> tests/ui/single_element_loop.rs:53:5\n   |\nLL | /     for _ in [42] {\nLL | |\nLL | |         let _f = |n: u32| {\nLL | |             for i in 0..n {\n...  |\nLL | |         };\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     {\nLL +         let _ = 42;\nLL +\nLL +         let _f = |n: u32| {\nLL +             for i in 0..n {\nLL +                 if i > 10 {\nLL +                     dbg!(i);\nLL +                     break;\nLL +                 }\nLL +             }\nLL +         };\nLL +     }\n   |\n\nerror: for loop over a single element\n  --> tests/ui/single_element_loop.rs:68:5\n   |\nLL | /     for (Ok(mut _x) | Err(mut _x)) in [res_void] {\nLL | |\nLL | |         let ptr: *const bool = std::ptr::null();\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     {\nLL +         let (Ok(mut _x) | Err(mut _x)) = res_void;\nLL +\nLL +         let ptr: *const bool = std::ptr::null();\nLL +     }\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_match.fixed",
    "content": "//@require-annotations-for-level: WARN\n#![warn(clippy::single_match)]\n#![allow(\n    unused,\n    clippy::uninlined_format_args,\n    clippy::needless_ifs,\n    clippy::redundant_guards,\n    clippy::redundant_pattern_matching,\n    clippy::manual_unwrap_or_default\n)]\nfn dummy() {}\n\nfn single_match() {\n    let x = Some(1u8);\n\n    if let Some(y) = x {\n        println!(\"{:?}\", y);\n    };\n    //~^^^^^^ single_match\n\n    let x = Some(1u8);\n    if let Some(y) = x { println!(\"{:?}\", y) }\n    //~^^^^^^^ single_match\n    //~| NOTE: you might want to preserve the comments from inside the `match`\n\n    let z = (1u8, 1u8);\n    if let (2..=3, 7..=9) = z { dummy() };\n    //~^^^^ single_match\n\n    // Not linted (pattern guards used)\n    match x {\n        Some(y) if y == 0 => println!(\"{:?}\", y),\n        _ => (),\n    }\n\n    // Not linted (no block with statements in the single arm)\n    match z {\n        (2..=3, 7..=9) => println!(\"{:?}\", z),\n        _ => println!(\"nope\"),\n    }\n}\n\nenum Foo {\n    Bar,\n    Baz(u8),\n}\nuse Foo::*;\nuse std::borrow::Cow;\n\nfn single_match_know_enum() {\n    let x = Some(1u8);\n    let y: Result<_, i8> = Ok(1i8);\n\n    if let Some(y) = x { dummy() };\n    //~^^^^ single_match\n\n    if let Ok(y) = y { dummy() };\n    //~^^^^ single_match\n\n    let c = Cow::Borrowed(\"\");\n\n    if let Cow::Borrowed(..) = c { dummy() };\n    //~^^^^ single_match\n\n    let z = Foo::Bar;\n    // no warning\n    match z {\n        Bar => println!(\"42\"),\n        Baz(_) => (),\n    }\n\n    match z {\n        Baz(_) => println!(\"42\"),\n        Bar => (),\n    }\n}\n\n// issue #173\nfn if_suggestion() {\n    let x = \"test\";\n    if x == \"test\" { println!() }\n    //~^^^^ single_match\n\n    #[derive(PartialEq, Eq)]\n    enum Foo {\n        A,\n        B,\n        C(u32),\n    }\n\n    let x = Foo::A;\n    if x == Foo::A { println!() }\n    //~^^^^ single_match\n\n    const FOO_C: Foo = Foo::C(0);\n    if x == FOO_C { println!() }\n    //~^^^^ single_match\n\n    if x == Foo::A { println!() }\n    //~^^^^ single_match\n\n    let x = &x;\n    if x == &Foo::A { println!() }\n    //~^^^^ single_match\n\n    enum Bar {\n        A,\n        B,\n    }\n    impl PartialEq for Bar {\n        fn eq(&self, rhs: &Self) -> bool {\n            matches!((self, rhs), (Self::A, Self::A) | (Self::B, Self::B))\n        }\n    }\n    impl Eq for Bar {}\n\n    let x = Bar::A;\n    if let Bar::A = x { println!() }\n    //~^^^^ single_match\n\n    // issue #7038\n    struct X;\n    let x = Some(X);\n    if let None = x { println!() };\n    //~^^^^ single_match\n}\n\n// See: issue #8282\nfn ranges() {\n    enum E {\n        V,\n    }\n    let x = (Some(E::V), Some(42));\n\n    // Don't lint, because the `E` enum can be extended with additional fields later. Thus, the\n    // proposed replacement to `if let Some(E::V)` may hide non-exhaustive warnings that appeared\n    // because of `match` construction.\n    match x {\n        (Some(E::V), _) => {},\n        (None, _) => {},\n    }\n\n    // lint\n    if let (Some(_), _) = x {}\n    //~^^^^ single_match\n\n    // lint\n    if let (Some(E::V), _) = x { todo!() }\n    //~^^^^ single_match\n\n    // lint\n    if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}\n    //~^^^^ single_match\n\n    // Don't lint, see above.\n    match (Some(E::V), Some(E::V), Some(E::V)) {\n        (.., Some(E::V), _) => {},\n        (.., None, _) => {},\n    }\n\n    // Don't lint, see above.\n    match (Some(E::V), Some(E::V), Some(E::V)) {\n        (Some(E::V), ..) => {},\n        (None, ..) => {},\n    }\n\n    // Don't lint, see above.\n    match (Some(E::V), Some(E::V), Some(E::V)) {\n        (_, Some(E::V), ..) => {},\n        (_, None, ..) => {},\n    }\n}\n\nfn skip_type_aliases() {\n    enum OptionEx {\n        Some(i32),\n        None,\n    }\n    enum ResultEx {\n        Err(i32),\n        Ok(i32),\n    }\n\n    use OptionEx::{None, Some};\n    use ResultEx::{Err, Ok};\n\n    // don't lint\n    match Err(42) {\n        Ok(_) => dummy(),\n        Err(_) => (),\n    };\n\n    // don't lint\n    match Some(1i32) {\n        Some(_) => dummy(),\n        None => (),\n    };\n}\n\nmacro_rules! single_match {\n    ($num:literal) => {\n        match $num {\n            15 => println!(\"15\"),\n            _ => (),\n        }\n    };\n}\n\nfn main() {\n    single_match!(5);\n\n    // Don't lint\n    let _ = match Some(0) {\n        #[cfg(feature = \"foo\")]\n        Some(10) => 11,\n        Some(x) => x,\n        _ => 0,\n    };\n}\n\nfn issue10808(bar: Option<i32>) {\n    if let Some(v) = bar { unsafe {\n        let r = &v as *const i32;\n        println!(\"{}\", *r);\n    } }\n    //~^^^^^^^ single_match\n\n    if let Some(v) = bar {\n        unsafe {\n            let r = &v as *const i32;\n            println!(\"{}\", *r);\n        }\n    }\n    //~^^^^^^^^^^ single_match\n}\n\nmod issue8634 {\n    struct SomeError(i32, i32);\n\n    fn foo(x: Result<i32, ()>) {\n        match x {\n            Ok(y) => {\n                println!(\"Yay! {y}\");\n            },\n            Err(()) => {\n                // Ignore this error because blah blah blah.\n            },\n        }\n    }\n\n    fn bar(x: Result<i32, SomeError>) {\n        match x {\n            Ok(y) => {\n                println!(\"Yay! {y}\");\n            },\n            Err(_) => {\n                // TODO: Process the error properly.\n            },\n        }\n    }\n\n    fn block_comment(x: Result<i32, SomeError>) {\n        match x {\n            Ok(y) => {\n                println!(\"Yay! {y}\");\n            },\n            Err(_) => {\n                /*\n                let's make sure that this also\n                does not lint block comments.\n                */\n            },\n        }\n    }\n}\n\nfn issue11365() {\n    enum Foo {\n        A,\n        B,\n        C,\n    }\n    use Foo::{A, B, C};\n\n    match Some(A) {\n        Some(A | B | C) => println!(),\n        None => {},\n    }\n\n    match Some(A) {\n        Some(A | B) => println!(),\n        Some { 0: C } | None => {},\n    }\n\n    match [A, A] {\n        [A, _] => println!(),\n        [_, A | B | C] => {},\n    }\n\n    match Ok::<_, u32>(Some(A)) {\n        Ok(Some(A)) => println!(),\n        Err(_) | Ok(None | Some(B | C)) => {},\n    }\n\n    if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() }\n    //~^^^^ single_match\n\n    match &Some(A) {\n        Some(A | B | C) => println!(),\n        None => {},\n    }\n\n    match &Some(A) {\n        &Some(A | B | C) => println!(),\n        None => {},\n    }\n\n    if let Some(A | B) = &Some(A) { println!() }\n    //~^^^^ single_match\n}\n\nfn issue12758(s: &[u8]) {\n    if &s[0..3] == b\"foo\" { println!() }\n    //~^^^^ single_match\n}\n\n#[derive(Eq, PartialEq)]\npub struct Data([u8; 4]);\n\nconst DATA: Data = Data([1, 2, 3, 4]);\nconst CONST_I32: i32 = 1;\n\n// https://github.com/rust-lang/rust-clippy/issues/13012\nfn irrefutable_match() {\n    println!();\n    //~^^^^ single_match\n\n    println!();\n    //~^^^^ single_match\n\n    let i = 0;\n    {\n        let a = 1;\n        let b = 2;\n    }\n    //~^^^^^^^ single_match\n\n    \n    //~^^^^ single_match\n\n    \n    //~^^^^ single_match\n\n    println!();\n    //~^^^^ single_match\n\n    let mut x = vec![1i8];\n\n    if let Some(u) = x.pop() { println!(\"{u}\") }\n    //~^^^^^^ single_match\n    //~| NOTE: you might want to preserve the comments from inside the `match`\n\n    if let Some(u) = x.pop() {\n        // bla\n        println!(\"{u}\");\n    }\n    //~^^^^^^^^^ single_match\n    //~| NOTE: you might want to preserve the comments from inside the `match`\n}\n\nfn issue14493() {\n    macro_rules! mac {\n        (some) => {\n            Some(42)\n        };\n        (any) => {\n            _\n        };\n        (str) => {\n            \"foo\"\n        };\n    }\n\n    if let Some(u) = mac!(some) { println!(\"{u}\") }\n    //~^^^^ single_match\n\n    // When scrutinee comes from macro, do not tell that arm will always match\n    // and suggest an equality check instead.\n    if mac!(str) == \"foo\" { println!(\"eq\") }\n    //~^^^^ ERROR: for an equality check\n\n    // Do not lint if any match arm come from expansion\n    match Some(0) {\n        mac!(some) => println!(\"eq\"),\n        mac!(any) => println!(\"neq\"),\n    }\n    match Some(0) {\n        Some(42) => println!(\"eq\"),\n        mac!(any) => println!(\"neq\"),\n    }\n    match Some(0) {\n        mac!(some) => println!(\"eq\"),\n        _ => println!(\"neq\"),\n    }\n}\n"
  },
  {
    "path": "tests/ui/single_match.rs",
    "content": "//@require-annotations-for-level: WARN\n#![warn(clippy::single_match)]\n#![allow(\n    unused,\n    clippy::uninlined_format_args,\n    clippy::needless_ifs,\n    clippy::redundant_guards,\n    clippy::redundant_pattern_matching,\n    clippy::manual_unwrap_or_default\n)]\nfn dummy() {}\n\nfn single_match() {\n    let x = Some(1u8);\n\n    match x {\n        Some(y) => {\n            println!(\"{:?}\", y);\n        },\n        _ => (),\n    };\n    //~^^^^^^ single_match\n\n    let x = Some(1u8);\n    match x {\n        // Note the missing block braces.\n        // We suggest `if let Some(y) = x { .. }` because the macro\n        // is expanded before we can do anything.\n        Some(y) => println!(\"{:?}\", y),\n        _ => (),\n    }\n    //~^^^^^^^ single_match\n    //~| NOTE: you might want to preserve the comments from inside the `match`\n\n    let z = (1u8, 1u8);\n    match z {\n        (2..=3, 7..=9) => dummy(),\n        _ => {},\n    };\n    //~^^^^ single_match\n\n    // Not linted (pattern guards used)\n    match x {\n        Some(y) if y == 0 => println!(\"{:?}\", y),\n        _ => (),\n    }\n\n    // Not linted (no block with statements in the single arm)\n    match z {\n        (2..=3, 7..=9) => println!(\"{:?}\", z),\n        _ => println!(\"nope\"),\n    }\n}\n\nenum Foo {\n    Bar,\n    Baz(u8),\n}\nuse Foo::*;\nuse std::borrow::Cow;\n\nfn single_match_know_enum() {\n    let x = Some(1u8);\n    let y: Result<_, i8> = Ok(1i8);\n\n    match x {\n        Some(y) => dummy(),\n        None => (),\n    };\n    //~^^^^ single_match\n\n    match y {\n        Ok(y) => dummy(),\n        Err(..) => (),\n    };\n    //~^^^^ single_match\n\n    let c = Cow::Borrowed(\"\");\n\n    match c {\n        Cow::Borrowed(..) => dummy(),\n        Cow::Owned(..) => (),\n    };\n    //~^^^^ single_match\n\n    let z = Foo::Bar;\n    // no warning\n    match z {\n        Bar => println!(\"42\"),\n        Baz(_) => (),\n    }\n\n    match z {\n        Baz(_) => println!(\"42\"),\n        Bar => (),\n    }\n}\n\n// issue #173\nfn if_suggestion() {\n    let x = \"test\";\n    match x {\n        \"test\" => println!(),\n        _ => (),\n    }\n    //~^^^^ single_match\n\n    #[derive(PartialEq, Eq)]\n    enum Foo {\n        A,\n        B,\n        C(u32),\n    }\n\n    let x = Foo::A;\n    match x {\n        Foo::A => println!(),\n        _ => (),\n    }\n    //~^^^^ single_match\n\n    const FOO_C: Foo = Foo::C(0);\n    match x {\n        FOO_C => println!(),\n        _ => (),\n    }\n    //~^^^^ single_match\n\n    match &&x {\n        Foo::A => println!(),\n        _ => (),\n    }\n    //~^^^^ single_match\n\n    let x = &x;\n    match &x {\n        Foo::A => println!(),\n        _ => (),\n    }\n    //~^^^^ single_match\n\n    enum Bar {\n        A,\n        B,\n    }\n    impl PartialEq for Bar {\n        fn eq(&self, rhs: &Self) -> bool {\n            matches!((self, rhs), (Self::A, Self::A) | (Self::B, Self::B))\n        }\n    }\n    impl Eq for Bar {}\n\n    let x = Bar::A;\n    match x {\n        Bar::A => println!(),\n        _ => (),\n    }\n    //~^^^^ single_match\n\n    // issue #7038\n    struct X;\n    let x = Some(X);\n    match x {\n        None => println!(),\n        _ => (),\n    };\n    //~^^^^ single_match\n}\n\n// See: issue #8282\nfn ranges() {\n    enum E {\n        V,\n    }\n    let x = (Some(E::V), Some(42));\n\n    // Don't lint, because the `E` enum can be extended with additional fields later. Thus, the\n    // proposed replacement to `if let Some(E::V)` may hide non-exhaustive warnings that appeared\n    // because of `match` construction.\n    match x {\n        (Some(E::V), _) => {},\n        (None, _) => {},\n    }\n\n    // lint\n    match x {\n        (Some(_), _) => {},\n        (None, _) => {},\n    }\n    //~^^^^ single_match\n\n    // lint\n    match x {\n        (Some(E::V), _) => todo!(),\n        (_, _) => {},\n    }\n    //~^^^^ single_match\n\n    // lint\n    match (Some(42), Some(E::V), Some(42)) {\n        (.., Some(E::V), _) => {},\n        (..) => {},\n    }\n    //~^^^^ single_match\n\n    // Don't lint, see above.\n    match (Some(E::V), Some(E::V), Some(E::V)) {\n        (.., Some(E::V), _) => {},\n        (.., None, _) => {},\n    }\n\n    // Don't lint, see above.\n    match (Some(E::V), Some(E::V), Some(E::V)) {\n        (Some(E::V), ..) => {},\n        (None, ..) => {},\n    }\n\n    // Don't lint, see above.\n    match (Some(E::V), Some(E::V), Some(E::V)) {\n        (_, Some(E::V), ..) => {},\n        (_, None, ..) => {},\n    }\n}\n\nfn skip_type_aliases() {\n    enum OptionEx {\n        Some(i32),\n        None,\n    }\n    enum ResultEx {\n        Err(i32),\n        Ok(i32),\n    }\n\n    use OptionEx::{None, Some};\n    use ResultEx::{Err, Ok};\n\n    // don't lint\n    match Err(42) {\n        Ok(_) => dummy(),\n        Err(_) => (),\n    };\n\n    // don't lint\n    match Some(1i32) {\n        Some(_) => dummy(),\n        None => (),\n    };\n}\n\nmacro_rules! single_match {\n    ($num:literal) => {\n        match $num {\n            15 => println!(\"15\"),\n            _ => (),\n        }\n    };\n}\n\nfn main() {\n    single_match!(5);\n\n    // Don't lint\n    let _ = match Some(0) {\n        #[cfg(feature = \"foo\")]\n        Some(10) => 11,\n        Some(x) => x,\n        _ => 0,\n    };\n}\n\nfn issue10808(bar: Option<i32>) {\n    match bar {\n        Some(v) => unsafe {\n            let r = &v as *const i32;\n            println!(\"{}\", *r);\n        },\n        _ => {},\n    }\n    //~^^^^^^^ single_match\n\n    match bar {\n        #[rustfmt::skip]\n        Some(v) => {\n            unsafe {\n                let r = &v as *const i32;\n                println!(\"{}\", *r);\n            }\n        },\n        _ => {},\n    }\n    //~^^^^^^^^^^ single_match\n}\n\nmod issue8634 {\n    struct SomeError(i32, i32);\n\n    fn foo(x: Result<i32, ()>) {\n        match x {\n            Ok(y) => {\n                println!(\"Yay! {y}\");\n            },\n            Err(()) => {\n                // Ignore this error because blah blah blah.\n            },\n        }\n    }\n\n    fn bar(x: Result<i32, SomeError>) {\n        match x {\n            Ok(y) => {\n                println!(\"Yay! {y}\");\n            },\n            Err(_) => {\n                // TODO: Process the error properly.\n            },\n        }\n    }\n\n    fn block_comment(x: Result<i32, SomeError>) {\n        match x {\n            Ok(y) => {\n                println!(\"Yay! {y}\");\n            },\n            Err(_) => {\n                /*\n                let's make sure that this also\n                does not lint block comments.\n                */\n            },\n        }\n    }\n}\n\nfn issue11365() {\n    enum Foo {\n        A,\n        B,\n        C,\n    }\n    use Foo::{A, B, C};\n\n    match Some(A) {\n        Some(A | B | C) => println!(),\n        None => {},\n    }\n\n    match Some(A) {\n        Some(A | B) => println!(),\n        Some { 0: C } | None => {},\n    }\n\n    match [A, A] {\n        [A, _] => println!(),\n        [_, A | B | C] => {},\n    }\n\n    match Ok::<_, u32>(Some(A)) {\n        Ok(Some(A)) => println!(),\n        Err(_) | Ok(None | Some(B | C)) => {},\n    }\n\n    match Ok::<_, u32>(Some(A)) {\n        Ok(Some(A)) => println!(),\n        Err(_) | Ok(None | Some(_)) => {},\n    }\n    //~^^^^ single_match\n\n    match &Some(A) {\n        Some(A | B | C) => println!(),\n        None => {},\n    }\n\n    match &Some(A) {\n        &Some(A | B | C) => println!(),\n        None => {},\n    }\n\n    match &Some(A) {\n        Some(A | B) => println!(),\n        None | Some(_) => {},\n    }\n    //~^^^^ single_match\n}\n\nfn issue12758(s: &[u8]) {\n    match &s[0..3] {\n        b\"foo\" => println!(),\n        _ => {},\n    }\n    //~^^^^ single_match\n}\n\n#[derive(Eq, PartialEq)]\npub struct Data([u8; 4]);\n\nconst DATA: Data = Data([1, 2, 3, 4]);\nconst CONST_I32: i32 = 1;\n\n// https://github.com/rust-lang/rust-clippy/issues/13012\nfn irrefutable_match() {\n    match DATA {\n        DATA => println!(),\n        _ => {},\n    }\n    //~^^^^ single_match\n\n    match CONST_I32 {\n        CONST_I32 => println!(),\n        _ => {},\n    }\n    //~^^^^ single_match\n\n    let i = 0;\n    match i {\n        i => {\n            let a = 1;\n            let b = 2;\n        },\n        _ => {},\n    }\n    //~^^^^^^^ single_match\n\n    match i {\n        i => {},\n        _ => {},\n    }\n    //~^^^^ single_match\n\n    match i {\n        i => (),\n        _ => (),\n    }\n    //~^^^^ single_match\n\n    match CONST_I32 {\n        CONST_I32 => println!(),\n        _ => {},\n    }\n    //~^^^^ single_match\n\n    let mut x = vec![1i8];\n\n    match x.pop() {\n        // bla\n        Some(u) => println!(\"{u}\"),\n        // more comments!\n        None => {},\n    }\n    //~^^^^^^ single_match\n    //~| NOTE: you might want to preserve the comments from inside the `match`\n\n    match x.pop() {\n        // bla\n        Some(u) => {\n            // bla\n            println!(\"{u}\");\n        },\n        // bla\n        None => {},\n    }\n    //~^^^^^^^^^ single_match\n    //~| NOTE: you might want to preserve the comments from inside the `match`\n}\n\nfn issue14493() {\n    macro_rules! mac {\n        (some) => {\n            Some(42)\n        };\n        (any) => {\n            _\n        };\n        (str) => {\n            \"foo\"\n        };\n    }\n\n    match mac!(some) {\n        Some(u) => println!(\"{u}\"),\n        _ => (),\n    }\n    //~^^^^ single_match\n\n    // When scrutinee comes from macro, do not tell that arm will always match\n    // and suggest an equality check instead.\n    match mac!(str) {\n        \"foo\" => println!(\"eq\"),\n        _ => (),\n    }\n    //~^^^^ ERROR: for an equality check\n\n    // Do not lint if any match arm come from expansion\n    match Some(0) {\n        mac!(some) => println!(\"eq\"),\n        mac!(any) => println!(\"neq\"),\n    }\n    match Some(0) {\n        Some(42) => println!(\"eq\"),\n        mac!(any) => println!(\"neq\"),\n    }\n    match Some(0) {\n        mac!(some) => println!(\"eq\"),\n        _ => println!(\"neq\"),\n    }\n}\n"
  },
  {
    "path": "tests/ui/single_match.stderr",
    "content": "error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:16:5\n   |\nLL | /     match x {\nLL | |         Some(y) => {\nLL | |             println!(\"{:?}\", y);\nLL | |         },\nLL | |         _ => (),\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::single-match` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_match)]`\nhelp: try\n   |\nLL ~     if let Some(y) = x {\nLL +         println!(\"{:?}\", y);\nLL ~     };\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:25:5\n   |\nLL | /     match x {\n...  |\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if let Some(y) = x { println!(\"{:?}\", y) }`\n   |\n   = note: you might want to preserve the comments from inside the `match`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:36:5\n   |\nLL | /     match z {\nLL | |         (2..=3, 7..=9) => dummy(),\nLL | |         _ => {},\nLL | |     };\n   | |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:66:5\n   |\nLL | /     match x {\nLL | |         Some(y) => dummy(),\nLL | |         None => (),\nLL | |     };\n   | |_____^ help: try: `if let Some(y) = x { dummy() }`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:72:5\n   |\nLL | /     match y {\nLL | |         Ok(y) => dummy(),\nLL | |         Err(..) => (),\nLL | |     };\n   | |_____^ help: try: `if let Ok(y) = y { dummy() }`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:80:5\n   |\nLL | /     match c {\nLL | |         Cow::Borrowed(..) => dummy(),\nLL | |         Cow::Owned(..) => (),\nLL | |     };\n   | |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match.rs:102:5\n   |\nLL | /     match x {\nLL | |         \"test\" => println!(),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if x == \"test\" { println!() }`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match.rs:116:5\n   |\nLL | /     match x {\nLL | |         Foo::A => println!(),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if x == Foo::A { println!() }`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match.rs:123:5\n   |\nLL | /     match x {\nLL | |         FOO_C => println!(),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if x == FOO_C { println!() }`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match.rs:129:5\n   |\nLL | /     match &&x {\nLL | |         Foo::A => println!(),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if x == Foo::A { println!() }`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match.rs:136:5\n   |\nLL | /     match &x {\nLL | |         Foo::A => println!(),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if x == &Foo::A { println!() }`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:154:5\n   |\nLL | /     match x {\nLL | |         Bar::A => println!(),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if let Bar::A = x { println!() }`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:163:5\n   |\nLL | /     match x {\nLL | |         None => println!(),\nLL | |         _ => (),\nLL | |     };\n   | |_____^ help: try: `if let None = x { println!() }`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:186:5\n   |\nLL | /     match x {\nLL | |         (Some(_), _) => {},\nLL | |         (None, _) => {},\nLL | |     }\n   | |_____^ help: try: `if let (Some(_), _) = x {}`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:193:5\n   |\nLL | /     match x {\nLL | |         (Some(E::V), _) => todo!(),\nLL | |         (_, _) => {},\nLL | |     }\n   | |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:200:5\n   |\nLL | /     match (Some(42), Some(E::V), Some(42)) {\nLL | |         (.., Some(E::V), _) => {},\nLL | |         (..) => {},\nLL | |     }\n   | |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:273:5\n   |\nLL | /     match bar {\nLL | |         Some(v) => unsafe {\nLL | |             let r = &v as *const i32;\nLL | |             println!(\"{}\", *r);\nLL | |         },\nLL | |         _ => {},\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Some(v) = bar { unsafe {\nLL +         let r = &v as *const i32;\nLL +         println!(\"{}\", *r);\nLL +     } }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:282:5\n   |\nLL | /     match bar {\nLL | |         #[rustfmt::skip]\nLL | |         Some(v) => {\nLL | |             unsafe {\n...  |\nLL | |         _ => {},\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Some(v) = bar {\nLL +         unsafe {\nLL +             let r = &v as *const i32;\nLL +             println!(\"{}\", *r);\nLL +         }\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:363:5\n   |\nLL | /     match Ok::<_, u32>(Some(A)) {\nLL | |         Ok(Some(A)) => println!(),\nLL | |         Err(_) | Ok(None | Some(_)) => {},\nLL | |     }\n   | |_____^ help: try: `if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() }`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:379:5\n   |\nLL | /     match &Some(A) {\nLL | |         Some(A | B) => println!(),\nLL | |         None | Some(_) => {},\nLL | |     }\n   | |_____^ help: try: `if let Some(A | B) = &Some(A) { println!() }`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match.rs:387:5\n   |\nLL | /     match &s[0..3] {\nLL | |         b\"foo\" => println!(),\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `if &s[0..3] == b\"foo\" { println!() }`\n\nerror: this pattern is irrefutable, `match` is useless\n  --> tests/ui/single_match.rs:402:5\n   |\nLL | /     match DATA {\nLL | |         DATA => println!(),\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `println!();`\n\nerror: this pattern is irrefutable, `match` is useless\n  --> tests/ui/single_match.rs:408:5\n   |\nLL | /     match CONST_I32 {\nLL | |         CONST_I32 => println!(),\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `println!();`\n\nerror: this pattern is irrefutable, `match` is useless\n  --> tests/ui/single_match.rs:415:5\n   |\nLL | /     match i {\nLL | |         i => {\nLL | |             let a = 1;\nLL | |             let b = 2;\nLL | |         },\nLL | |         _ => {},\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     {\nLL +         let a = 1;\nLL +         let b = 2;\nLL +     }\n   |\n\nerror: this pattern is irrefutable, `match` is useless\n  --> tests/ui/single_match.rs:424:5\n   |\nLL | /     match i {\nLL | |         i => {},\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: `match` expression can be removed\n\nerror: this pattern is irrefutable, `match` is useless\n  --> tests/ui/single_match.rs:430:5\n   |\nLL | /     match i {\nLL | |         i => (),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: `match` expression can be removed\n\nerror: this pattern is irrefutable, `match` is useless\n  --> tests/ui/single_match.rs:436:5\n   |\nLL | /     match CONST_I32 {\nLL | |         CONST_I32 => println!(),\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `println!();`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:444:5\n   |\nLL | /     match x.pop() {\nLL | |         // bla\nLL | |         Some(u) => println!(\"{u}\"),\n...  |\nLL | |     }\n   | |_____^ help: try: `if let Some(u) = x.pop() { println!(\"{u}\") }`\n   |\n   = note: you might want to preserve the comments from inside the `match`\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:453:5\n   |\nLL | /     match x.pop() {\nLL | |         // bla\nLL | |         Some(u) => {\n...  |\nLL | |         None => {},\nLL | |     }\n   | |_____^\n   |\n   = note: you might want to preserve the comments from inside the `match`\nhelp: try\n   |\nLL ~     if let Some(u) = x.pop() {\nLL +         // bla\nLL +         println!(\"{u}\");\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match.rs:479:5\n   |\nLL | /     match mac!(some) {\nLL | |         Some(u) => println!(\"{u}\"),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if let Some(u) = mac!(some) { println!(\"{u}\") }`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match.rs:487:5\n   |\nLL | /     match mac!(str) {\nLL | |         \"foo\" => println!(\"eq\"),\nLL | |         _ => (),\nLL | |     }\n   | |_____^ help: try: `if mac!(str) == \"foo\" { println!(\"eq\") }`\n\nerror: aborting due to 31 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_match_else.fixed",
    "content": "//@aux-build: proc_macros.rs\n//@require-annotations-for-level: WARN\n\n#![warn(clippy::single_match_else)]\n#![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nenum ExprNode {\n    ExprAddrOf,\n    Butterflies,\n    Unicorns,\n}\n\nstatic NODE: ExprNode = ExprNode::Unicorns;\n\nfn unwrap_addr() -> Option<&'static ExprNode> {\n    let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else {\n        let x = 5;\n        None\n    };\n    //~^^^^^^^ single_match_else\n\n    // Don't lint\n    with_span!(span match ExprNode::Butterflies {\n        ExprNode::ExprAddrOf => Some(&NODE),\n        _ => {\n            let x = 5;\n            None\n        },\n    })\n}\n\nmacro_rules! unwrap_addr {\n    ($expression:expr) => {\n        match $expression {\n            ExprNode::ExprAddrOf => Some(&NODE),\n            _ => {\n                let x = 5;\n                None\n            },\n        }\n    };\n}\n\n#[rustfmt::skip]\nfn main() {\n    unwrap_addr!(ExprNode::Unicorns);\n\n    //\n    // don't lint single exprs/statements\n    //\n\n    // don't lint here\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        None => return,\n    }\n\n    // don't lint here\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        None => {\n            return\n        },\n    }\n\n    // don't lint here\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        None => {\n            return;\n        },\n    }\n\n    //\n    // lint multiple exprs/statements \"else\" blocks\n    //\n\n    // lint here\n    if let Some(a) = Some(1) { println!(\"${:?}\", a) } else {\n        println!(\"else block\");\n        return\n    }\n    //~^^^^^^^ single_match_else\n\n    // lint here\n    if let Some(a) = Some(1) { println!(\"${:?}\", a) } else {\n        println!(\"else block\");\n        return;\n    }\n    //~^^^^^^^ single_match_else\n\n    if let Some(a) = Some(1) { println!(\"${:?}\", a) } else {\n        println!(\"else block\");\n        return;\n    }\n    //~^^^^^^^^ single_match_else\n    //~| NOTE: you might want to preserve the comments from inside the `match`\n\n    // lint here\n    use std::convert::Infallible;\n    if let Ok(a) = Result::<i32, &Infallible>::Ok(1) { println!(\"${:?}\", a) } else {\n        println!(\"else block\");\n        return;\n    }\n    //~^^^^^^^ single_match_else\n\n    use std::borrow::Cow;\n    if let Cow::Owned(a) = Cow::from(\"moo\") { println!(\"${:?}\", a) } else {\n        println!(\"else block\");\n        return;\n    }\n    //~^^^^^^^ single_match_else\n}\n\nfn issue_10808(bar: Option<i32>) {\n    if let Some(v) = bar { unsafe {\n        let r = &v as *const i32;\n        println!(\"{}\", *r);\n    } } else {\n        println!(\"None1\");\n        println!(\"None2\");\n    }\n    //~^^^^^^^^^^ single_match_else\n\n    if let Some(v) = bar {\n        println!(\"Some\");\n        println!(\"{v}\");\n    } else { unsafe {\n        let v = 0;\n        let r = &v as *const i32;\n        println!(\"{}\", *r);\n    } }\n    //~^^^^^^^^^^^ single_match_else\n\n    if let Some(v) = bar { unsafe {\n        let r = &v as *const i32;\n        println!(\"{}\", *r);\n    } } else { unsafe {\n        let v = 0;\n        let r = &v as *const i32;\n        println!(\"{}\", *r);\n    } }\n    //~^^^^^^^^^^^ single_match_else\n\n    if let Some(v) = bar {\n        unsafe {\n            let r = &v as *const i32;\n            println!(\"{}\", *r);\n        }\n    } else {\n        println!(\"None\");\n        println!(\"None\");\n    }\n    //~^^^^^^^^^^^^^ single_match_else\n\n    match bar {\n        Some(v) => {\n            println!(\"Some\");\n            println!(\"{v}\");\n        },\n        #[rustfmt::skip]\n        None => {\n            unsafe {\n                let v = 0;\n                let r = &v as *const i32;\n                println!(\"{}\", *r);\n            }\n        },\n    }\n\n    match bar {\n        #[rustfmt::skip]\n        Some(v) => {\n            unsafe {\n                let r = &v as *const i32;\n                println!(\"{}\", *r);\n            }\n        },\n        #[rustfmt::skip]\n        None => {\n            unsafe {\n                let v = 0;\n                let r = &v as *const i32;\n                println!(\"{}\", *r);\n            }\n        },\n    }\n}\n\nfn irrefutable_match() -> Option<&'static ExprNode> {\n    Some(&NODE)\n    //~^^^^^^^ single_match_else\n}\n"
  },
  {
    "path": "tests/ui/single_match_else.rs",
    "content": "//@aux-build: proc_macros.rs\n//@require-annotations-for-level: WARN\n\n#![warn(clippy::single_match_else)]\n#![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nenum ExprNode {\n    ExprAddrOf,\n    Butterflies,\n    Unicorns,\n}\n\nstatic NODE: ExprNode = ExprNode::Unicorns;\n\nfn unwrap_addr() -> Option<&'static ExprNode> {\n    let _ = match ExprNode::Butterflies {\n        ExprNode::ExprAddrOf => Some(&NODE),\n        _ => {\n            let x = 5;\n            None\n        },\n    };\n    //~^^^^^^^ single_match_else\n\n    // Don't lint\n    with_span!(span match ExprNode::Butterflies {\n        ExprNode::ExprAddrOf => Some(&NODE),\n        _ => {\n            let x = 5;\n            None\n        },\n    })\n}\n\nmacro_rules! unwrap_addr {\n    ($expression:expr) => {\n        match $expression {\n            ExprNode::ExprAddrOf => Some(&NODE),\n            _ => {\n                let x = 5;\n                None\n            },\n        }\n    };\n}\n\n#[rustfmt::skip]\nfn main() {\n    unwrap_addr!(ExprNode::Unicorns);\n\n    //\n    // don't lint single exprs/statements\n    //\n\n    // don't lint here\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        None => return,\n    }\n\n    // don't lint here\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        None => {\n            return\n        },\n    }\n\n    // don't lint here\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        None => {\n            return;\n        },\n    }\n\n    //\n    // lint multiple exprs/statements \"else\" blocks\n    //\n\n    // lint here\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        None => {\n            println!(\"else block\");\n            return\n        },\n    }\n    //~^^^^^^^ single_match_else\n\n    // lint here\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        None => {\n            println!(\"else block\");\n            return;\n        },\n    }\n    //~^^^^^^^ single_match_else\n\n    match Some(1) {\n        Some(a) => println!(\"${:?}\", a),\n        // This is an inner comment\n        None => {\n            println!(\"else block\");\n            return;\n        },\n    }\n    //~^^^^^^^^ single_match_else\n    //~| NOTE: you might want to preserve the comments from inside the `match`\n\n    // lint here\n    use std::convert::Infallible;\n    match Result::<i32, &Infallible>::Ok(1) {\n        Ok(a) => println!(\"${:?}\", a),\n        Err(_) => {\n            println!(\"else block\");\n            return;\n        }\n    }\n    //~^^^^^^^ single_match_else\n\n    use std::borrow::Cow;\n    match Cow::from(\"moo\") {\n        Cow::Owned(a) => println!(\"${:?}\", a),\n        Cow::Borrowed(_) => {\n            println!(\"else block\");\n            return;\n        }\n    }\n    //~^^^^^^^ single_match_else\n}\n\nfn issue_10808(bar: Option<i32>) {\n    match bar {\n        Some(v) => unsafe {\n            let r = &v as *const i32;\n            println!(\"{}\", *r);\n        },\n        None => {\n            println!(\"None1\");\n            println!(\"None2\");\n        },\n    }\n    //~^^^^^^^^^^ single_match_else\n\n    match bar {\n        Some(v) => {\n            println!(\"Some\");\n            println!(\"{v}\");\n        },\n        None => unsafe {\n            let v = 0;\n            let r = &v as *const i32;\n            println!(\"{}\", *r);\n        },\n    }\n    //~^^^^^^^^^^^ single_match_else\n\n    match bar {\n        Some(v) => unsafe {\n            let r = &v as *const i32;\n            println!(\"{}\", *r);\n        },\n        None => unsafe {\n            let v = 0;\n            let r = &v as *const i32;\n            println!(\"{}\", *r);\n        },\n    }\n    //~^^^^^^^^^^^ single_match_else\n\n    match bar {\n        #[rustfmt::skip]\n        Some(v) => {\n            unsafe {\n                let r = &v as *const i32;\n                println!(\"{}\", *r);\n            }\n        },\n        None => {\n            println!(\"None\");\n            println!(\"None\");\n        },\n    }\n    //~^^^^^^^^^^^^^ single_match_else\n\n    match bar {\n        Some(v) => {\n            println!(\"Some\");\n            println!(\"{v}\");\n        },\n        #[rustfmt::skip]\n        None => {\n            unsafe {\n                let v = 0;\n                let r = &v as *const i32;\n                println!(\"{}\", *r);\n            }\n        },\n    }\n\n    match bar {\n        #[rustfmt::skip]\n        Some(v) => {\n            unsafe {\n                let r = &v as *const i32;\n                println!(\"{}\", *r);\n            }\n        },\n        #[rustfmt::skip]\n        None => {\n            unsafe {\n                let v = 0;\n                let r = &v as *const i32;\n                println!(\"{}\", *r);\n            }\n        },\n    }\n}\n\nfn irrefutable_match() -> Option<&'static ExprNode> {\n    match ExprNode::Butterflies {\n        ExprNode::Butterflies => Some(&NODE),\n        _ => {\n            let x = 5;\n            None\n        },\n    }\n    //~^^^^^^^ single_match_else\n}\n"
  },
  {
    "path": "tests/ui/single_match_else.stderr",
    "content": "error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:18:13\n   |\nLL |       let _ = match ExprNode::Butterflies {\n   |  _____________^\nLL | |         ExprNode::ExprAddrOf => Some(&NODE),\nLL | |         _ => {\nLL | |             let x = 5;\nLL | |             None\nLL | |         },\nLL | |     };\n   | |_____^\n   |\n   = note: `-D clippy::single-match-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_match_else)]`\nhelp: try\n   |\nLL ~     let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else {\nLL +         let x = 5;\nLL +         None\nLL ~     };\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:84:5\n   |\nLL | /     match Some(1) {\nLL | |         Some(a) => println!(\"${:?}\", a),\nLL | |         None => {\nLL | |             println!(\"else block\");\nLL | |             return\nLL | |         },\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Some(a) = Some(1) { println!(\"${:?}\", a) } else {\nLL +         println!(\"else block\");\nLL +         return\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:94:5\n   |\nLL | /     match Some(1) {\nLL | |         Some(a) => println!(\"${:?}\", a),\nLL | |         None => {\nLL | |             println!(\"else block\");\nLL | |             return;\nLL | |         },\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Some(a) = Some(1) { println!(\"${:?}\", a) } else {\nLL +         println!(\"else block\");\nLL +         return;\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:103:5\n   |\nLL | /     match Some(1) {\nLL | |         Some(a) => println!(\"${:?}\", a),\nLL | |         // This is an inner comment\nLL | |         None => {\n...  |\nLL | |         },\nLL | |     }\n   | |_____^\n   |\n   = note: you might want to preserve the comments from inside the `match`\nhelp: try\n   |\nLL ~     if let Some(a) = Some(1) { println!(\"${:?}\", a) } else {\nLL +         println!(\"else block\");\nLL +         return;\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:116:5\n   |\nLL | /     match Result::<i32, &Infallible>::Ok(1) {\nLL | |         Ok(a) => println!(\"${:?}\", a),\nLL | |         Err(_) => {\nLL | |             println!(\"else block\");\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Ok(a) = Result::<i32, &Infallible>::Ok(1) { println!(\"${:?}\", a) } else {\nLL +         println!(\"else block\");\nLL +         return;\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:126:5\n   |\nLL | /     match Cow::from(\"moo\") {\nLL | |         Cow::Owned(a) => println!(\"${:?}\", a),\nLL | |         Cow::Borrowed(_) => {\nLL | |             println!(\"else block\");\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Cow::Owned(a) = Cow::from(\"moo\") { println!(\"${:?}\", a) } else {\nLL +         println!(\"else block\");\nLL +         return;\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:137:5\n   |\nLL | /     match bar {\nLL | |         Some(v) => unsafe {\nLL | |             let r = &v as *const i32;\nLL | |             println!(\"{}\", *r);\n...  |\nLL | |         },\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Some(v) = bar { unsafe {\nLL +         let r = &v as *const i32;\nLL +         println!(\"{}\", *r);\nLL +     } } else {\nLL +         println!(\"None1\");\nLL +         println!(\"None2\");\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:149:5\n   |\nLL | /     match bar {\nLL | |         Some(v) => {\nLL | |             println!(\"Some\");\nLL | |             println!(\"{v}\");\n...  |\nLL | |         },\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Some(v) = bar {\nLL +         println!(\"Some\");\nLL +         println!(\"{v}\");\nLL +     } else { unsafe {\nLL +         let v = 0;\nLL +         let r = &v as *const i32;\nLL +         println!(\"{}\", *r);\nLL +     } }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:162:5\n   |\nLL | /     match bar {\nLL | |         Some(v) => unsafe {\nLL | |             let r = &v as *const i32;\nLL | |             println!(\"{}\", *r);\n...  |\nLL | |         },\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Some(v) = bar { unsafe {\nLL +         let r = &v as *const i32;\nLL +         println!(\"{}\", *r);\nLL +     } } else { unsafe {\nLL +         let v = 0;\nLL +         let r = &v as *const i32;\nLL +         println!(\"{}\", *r);\nLL +     } }\n   |\n\nerror: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`\n  --> tests/ui/single_match_else.rs:175:5\n   |\nLL | /     match bar {\nLL | |         #[rustfmt::skip]\nLL | |         Some(v) => {\nLL | |             unsafe {\n...  |\nLL | |         },\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if let Some(v) = bar {\nLL +         unsafe {\nLL +             let r = &v as *const i32;\nLL +             println!(\"{}\", *r);\nLL +         }\nLL +     } else {\nLL +         println!(\"None\");\nLL +         println!(\"None\");\nLL +     }\n   |\n\nerror: this pattern is irrefutable, `match` is useless\n  --> tests/ui/single_match_else.rs:225:5\n   |\nLL | /     match ExprNode::Butterflies {\nLL | |         ExprNode::Butterflies => Some(&NODE),\nLL | |         _ => {\nLL | |             let x = 5;\nLL | |             None\nLL | |         },\nLL | |     }\n   | |_____^ help: try: `Some(&NODE)`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_match_else_deref_patterns.fixed",
    "content": "#![feature(deref_patterns)]\n#![allow(\n    incomplete_features,\n    clippy::eq_op,\n    clippy::op_ref,\n    clippy::deref_addrof,\n    clippy::borrow_deref_ref,\n    clippy::needless_ifs\n)]\n#![deny(clippy::single_match_else)]\n\nfn string() {\n    if *\"\" == *\"\" {}\n\n    if *&*&*&*\"\" == *\"\" {}\n\n    if ***&&\"\" == *\"\" {}\n\n    if *&*&*\"\" == *\"\" {}\n\n    if **&&*\"\" == *\"\" {}\n}\n\nfn int() {\n    if &&&1 == &&&2 { unreachable!() } else {\n        // ok\n    }\n    //~^^^^^^ single_match_else\n    if &&1 == &&2 { unreachable!() } else {\n        // ok\n    }\n    //~^^^^^^ single_match_else\n    if &&1 == &&2 { unreachable!() } else {\n        // ok\n    }\n    //~^^^^^^ single_match_else\n    if &1 == &2 { unreachable!() } else {\n        // ok\n    }\n    //~^^^^^^ single_match_else\n    if &1 == &2 { unreachable!() } else {\n        // ok\n    }\n    //~^^^^^^ single_match_else\n    if 1 == 2 { unreachable!() } else {\n        // ok\n    }\n    //~^^^^^^ single_match_else\n    if 1 == 2 { unreachable!() } else {\n        // ok\n    }\n    //~^^^^^^ single_match_else\n}\n"
  },
  {
    "path": "tests/ui/single_match_else_deref_patterns.rs",
    "content": "#![feature(deref_patterns)]\n#![allow(\n    incomplete_features,\n    clippy::eq_op,\n    clippy::op_ref,\n    clippy::deref_addrof,\n    clippy::borrow_deref_ref,\n    clippy::needless_ifs\n)]\n#![deny(clippy::single_match_else)]\n\nfn string() {\n    match *\"\" {\n        //~^ single_match\n        \"\" => {},\n        _ => {},\n    }\n\n    match *&*&*&*\"\" {\n        //~^ single_match\n        \"\" => {},\n        _ => {},\n    }\n\n    match ***&&\"\" {\n        //~^ single_match\n        \"\" => {},\n        _ => {},\n    }\n\n    match *&*&*\"\" {\n        //~^ single_match\n        \"\" => {},\n        _ => {},\n    }\n\n    match **&&*\"\" {\n        //~^ single_match\n        \"\" => {},\n        _ => {},\n    }\n}\n\nfn int() {\n    match &&&1 {\n        &&&2 => unreachable!(),\n        _ => {\n            // ok\n        },\n    }\n    //~^^^^^^ single_match_else\n    match &&&1 {\n        &&2 => unreachable!(),\n        _ => {\n            // ok\n        },\n    }\n    //~^^^^^^ single_match_else\n    match &&1 {\n        &&2 => unreachable!(),\n        _ => {\n            // ok\n        },\n    }\n    //~^^^^^^ single_match_else\n    match &&&1 {\n        &2 => unreachable!(),\n        _ => {\n            // ok\n        },\n    }\n    //~^^^^^^ single_match_else\n    match &&1 {\n        &2 => unreachable!(),\n        _ => {\n            // ok\n        },\n    }\n    //~^^^^^^ single_match_else\n    match &&&1 {\n        2 => unreachable!(),\n        _ => {\n            // ok\n        },\n    }\n    //~^^^^^^ single_match_else\n    match &&1 {\n        2 => unreachable!(),\n        _ => {\n            // ok\n        },\n    }\n    //~^^^^^^ single_match_else\n}\n"
  },
  {
    "path": "tests/ui/single_match_else_deref_patterns.stderr",
    "content": "error: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:13:5\n   |\nLL | /     match *\"\" {\nLL | |\nLL | |         \"\" => {},\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `if *\"\" == *\"\" {}`\n   |\n   = note: you might want to preserve the comments from inside the `match`\n   = note: `-D clippy::single-match` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_match)]`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:19:5\n   |\nLL | /     match *&*&*&*\"\" {\nLL | |\nLL | |         \"\" => {},\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `if *&*&*&*\"\" == *\"\" {}`\n   |\n   = note: you might want to preserve the comments from inside the `match`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:25:5\n   |\nLL | /     match ***&&\"\" {\nLL | |\nLL | |         \"\" => {},\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `if ***&&\"\" == *\"\" {}`\n   |\n   = note: you might want to preserve the comments from inside the `match`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:31:5\n   |\nLL | /     match *&*&*\"\" {\nLL | |\nLL | |         \"\" => {},\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `if *&*&*\"\" == *\"\" {}`\n   |\n   = note: you might want to preserve the comments from inside the `match`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:37:5\n   |\nLL | /     match **&&*\"\" {\nLL | |\nLL | |         \"\" => {},\nLL | |         _ => {},\nLL | |     }\n   | |_____^ help: try: `if **&&*\"\" == *\"\" {}`\n   |\n   = note: you might want to preserve the comments from inside the `match`\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:45:5\n   |\nLL | /     match &&&1 {\nLL | |         &&&2 => unreachable!(),\nLL | |         _ => {\n...  |\nLL | |     }\n   | |_____^\n   |\nnote: the lint level is defined here\n  --> tests/ui/single_match_else_deref_patterns.rs:10:9\n   |\nLL | #![deny(clippy::single_match_else)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: try\n   |\nLL ~     if &&&1 == &&&2 { unreachable!() } else {\nLL +         // ok\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:52:5\n   |\nLL | /     match &&&1 {\nLL | |         &&2 => unreachable!(),\nLL | |         _ => {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if &&1 == &&2 { unreachable!() } else {\nLL +         // ok\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:59:5\n   |\nLL | /     match &&1 {\nLL | |         &&2 => unreachable!(),\nLL | |         _ => {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if &&1 == &&2 { unreachable!() } else {\nLL +         // ok\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:66:5\n   |\nLL | /     match &&&1 {\nLL | |         &2 => unreachable!(),\nLL | |         _ => {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if &1 == &2 { unreachable!() } else {\nLL +         // ok\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:73:5\n   |\nLL | /     match &&1 {\nLL | |         &2 => unreachable!(),\nLL | |         _ => {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if &1 == &2 { unreachable!() } else {\nLL +         // ok\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:80:5\n   |\nLL | /     match &&&1 {\nLL | |         2 => unreachable!(),\nLL | |         _ => {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if 1 == 2 { unreachable!() } else {\nLL +         // ok\nLL +     }\n   |\n\nerror: you seem to be trying to use `match` for an equality check. Consider using `if`\n  --> tests/ui/single_match_else_deref_patterns.rs:87:5\n   |\nLL | /     match &&1 {\nLL | |         2 => unreachable!(),\nLL | |         _ => {\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     if 1 == 2 { unreachable!() } else {\nLL +         // ok\nLL +     }\n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_option_map.rs",
    "content": "#![warn(clippy::single_option_map)]\n\nuse std::sync::atomic::{AtomicUsize, Ordering};\n\nstatic ATOM: AtomicUsize = AtomicUsize::new(42);\nstatic MAYBE_ATOMIC: Option<&AtomicUsize> = Some(&ATOM);\n\nfn h(arg: Option<u32>) -> Option<u32> {\n    //~^ single_option_map\n\n    arg.map(|x| x * 2)\n}\n\nfn j(arg: Option<u64>) -> Option<u64> {\n    //~^ single_option_map\n\n    arg.map(|x| x * 2)\n}\n\nfn mul_args(a: String, b: u64) -> String {\n    a\n}\n\nfn mul_args_opt(a: Option<String>, b: u64) -> Option<String> {\n    //~^ single_option_map\n\n    a.map(|val| mul_args(val, b + 1))\n}\n\n// No lint: no `Option` argument argument\nfn maps_static_option() -> Option<usize> {\n    MAYBE_ATOMIC.map(|a| a.load(Ordering::Relaxed))\n}\n\n// No lint: wrapped by another function\nfn manipulate(i: i32) -> i32 {\n    i + 1\n}\n// No lint: wraps another function to do the optional thing\nfn manipulate_opt(opt_i: Option<i32>) -> Option<i32> {\n    opt_i.map(manipulate)\n}\n\n// No lint: maps other than the receiver\nfn map_not_arg(arg: Option<u32>) -> Option<u32> {\n    maps_static_option().map(|_| arg.unwrap())\n}\n\n// No lint: wrapper function with η-expanded form\n#[allow(clippy::redundant_closure)]\nfn manipulate_opt_explicit(opt_i: Option<i32>) -> Option<i32> {\n    opt_i.map(|x| manipulate(x))\n}\n\n// No lint\nfn multi_args(a: String, b: bool, c: u64) -> String {\n    a\n}\n\n// No lint: contains only map of a closure that binds other arguments\nfn multi_args_opt(a: Option<String>, b: bool, c: u64) -> Option<String> {\n    a.map(|a| multi_args(a, b, c))\n}\n\nfn main() {\n    let answer = Some(42u32);\n    let h_result = h(answer);\n\n    let answer = Some(42u64);\n    let j_result = j(answer);\n    maps_static_option();\n}\n"
  },
  {
    "path": "tests/ui/single_option_map.stderr",
    "content": "error: `fn` that only maps over argument\n  --> tests/ui/single_option_map.rs:8:1\n   |\nLL | / fn h(arg: Option<u32>) -> Option<u32> {\nLL | |\nLL | |\nLL | |     arg.map(|x| x * 2)\nLL | | }\n   | |_^\n   |\n   = help: move the `.map` to the caller or to an `_opt` function\n   = note: `-D clippy::single-option-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_option_map)]`\n\nerror: `fn` that only maps over argument\n  --> tests/ui/single_option_map.rs:14:1\n   |\nLL | / fn j(arg: Option<u64>) -> Option<u64> {\nLL | |\nLL | |\nLL | |     arg.map(|x| x * 2)\nLL | | }\n   | |_^\n   |\n   = help: move the `.map` to the caller or to an `_opt` function\n\nerror: `fn` that only maps over argument\n  --> tests/ui/single_option_map.rs:24:1\n   |\nLL | / fn mul_args_opt(a: Option<String>, b: u64) -> Option<String> {\nLL | |\nLL | |\nLL | |     a.map(|val| mul_args(val, b + 1))\nLL | | }\n   | |_^\n   |\n   = help: move the `.map` to the caller or to an `_opt` function\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_range_in_vec_init.1.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec, unused)]\n#![warn(clippy::single_range_in_vec_init)]\n\n#[macro_use]\nextern crate proc_macros;\n\nmacro_rules! a {\n    () => {\n        vec![0..200];\n    };\n}\n\nfn awa<T: PartialOrd>(start: T, end: T) {\n    [start..end];\n}\n\nfn awa_vec<T: PartialOrd>(start: T, end: T) {\n    vec![start..end];\n}\n\nfn main() {\n    // Lint\n    (0..200).collect::<std::vec::Vec<i32>>();\n    //~^ single_range_in_vec_init\n    (0..200).collect::<std::vec::Vec<i32>>();\n    //~^ single_range_in_vec_init\n    (0u8..200).collect::<std::vec::Vec<u8>>();\n    //~^ single_range_in_vec_init\n    (0usize..200).collect::<std::vec::Vec<usize>>();\n    //~^ single_range_in_vec_init\n    (0..200usize).collect::<std::vec::Vec<usize>>();\n    //~^ single_range_in_vec_init\n    (0u8..200).collect::<std::vec::Vec<u8>>();\n    //~^ single_range_in_vec_init\n    (0usize..200).collect::<std::vec::Vec<usize>>();\n    //~^ single_range_in_vec_init\n    (0..200usize).collect::<std::vec::Vec<usize>>();\n    //~^ single_range_in_vec_init\n    // Only suggest collect\n    (0..200isize).collect::<std::vec::Vec<isize>>();\n    //~^ single_range_in_vec_init\n    (0..200isize).collect::<std::vec::Vec<isize>>();\n    //~^ single_range_in_vec_init\n    // Do not lint\n    [0..200, 0..100];\n    vec![0..200, 0..100];\n    [0.0..200.0];\n    vec![0.0..200.0];\n    // `Copy` is not implemented for `Range`, so this doesn't matter\n    // FIXME: [0..200; 2];\n    // FIXME: [vec!0..200; 2];\n\n    // Unfortunately skips any macros\n    a!();\n\n    // Skip external macros and procedural macros\n    external! {\n        [0..200];\n        vec![0..200];\n    }\n    with_span! {\n        span\n        [0..200];\n        vec![0..200];\n    }\n}\n\nfn issue16042() {\n    use std::ops::Range;\n\n    let input = vec![Range { start: 0, end: 5 }];\n}\n\nfn issue16044() {\n    macro_rules! as_i32 {\n        ($x:expr) => {\n            $x as i32\n        };\n    }\n\n    let input = (0..as_i32!(10)).collect::<std::vec::Vec<i32>>();\n    //~^ single_range_in_vec_init\n}\n"
  },
  {
    "path": "tests/ui/single_range_in_vec_init.2.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec, unused)]\n#![warn(clippy::single_range_in_vec_init)]\n\n#[macro_use]\nextern crate proc_macros;\n\nmacro_rules! a {\n    () => {\n        vec![0..200];\n    };\n}\n\nfn awa<T: PartialOrd>(start: T, end: T) {\n    [start..end];\n}\n\nfn awa_vec<T: PartialOrd>(start: T, end: T) {\n    vec![start..end];\n}\n\nfn main() {\n    // Lint\n    [0; 200];\n    //~^ single_range_in_vec_init\n    vec![0; 200];\n    //~^ single_range_in_vec_init\n    [0u8; 200];\n    //~^ single_range_in_vec_init\n    [0usize; 200];\n    //~^ single_range_in_vec_init\n    [0; 200usize];\n    //~^ single_range_in_vec_init\n    vec![0u8; 200];\n    //~^ single_range_in_vec_init\n    vec![0usize; 200];\n    //~^ single_range_in_vec_init\n    vec![0; 200usize];\n    //~^ single_range_in_vec_init\n    // Only suggest collect\n    (0..200isize).collect::<std::vec::Vec<isize>>();\n    //~^ single_range_in_vec_init\n    (0..200isize).collect::<std::vec::Vec<isize>>();\n    //~^ single_range_in_vec_init\n    // Do not lint\n    [0..200, 0..100];\n    vec![0..200, 0..100];\n    [0.0..200.0];\n    vec![0.0..200.0];\n    // `Copy` is not implemented for `Range`, so this doesn't matter\n    // FIXME: [0..200; 2];\n    // FIXME: [vec!0..200; 2];\n\n    // Unfortunately skips any macros\n    a!();\n\n    // Skip external macros and procedural macros\n    external! {\n        [0..200];\n        vec![0..200];\n    }\n    with_span! {\n        span\n        [0..200];\n        vec![0..200];\n    }\n}\n\nfn issue16042() {\n    use std::ops::Range;\n\n    let input = vec![Range { start: 0, end: 5 }];\n}\n\nfn issue16044() {\n    macro_rules! as_i32 {\n        ($x:expr) => {\n            $x as i32\n        };\n    }\n\n    let input = (0..as_i32!(10)).collect::<std::vec::Vec<i32>>();\n    //~^ single_range_in_vec_init\n}\n"
  },
  {
    "path": "tests/ui/single_range_in_vec_init.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec, unused)]\n#![warn(clippy::single_range_in_vec_init)]\n\n#[macro_use]\nextern crate proc_macros;\n\nmacro_rules! a {\n    () => {\n        vec![0..200];\n    };\n}\n\nfn awa<T: PartialOrd>(start: T, end: T) {\n    [start..end];\n}\n\nfn awa_vec<T: PartialOrd>(start: T, end: T) {\n    vec![start..end];\n}\n\nfn main() {\n    // Lint\n    [0..200];\n    //~^ single_range_in_vec_init\n    vec![0..200];\n    //~^ single_range_in_vec_init\n    [0u8..200];\n    //~^ single_range_in_vec_init\n    [0usize..200];\n    //~^ single_range_in_vec_init\n    [0..200usize];\n    //~^ single_range_in_vec_init\n    vec![0u8..200];\n    //~^ single_range_in_vec_init\n    vec![0usize..200];\n    //~^ single_range_in_vec_init\n    vec![0..200usize];\n    //~^ single_range_in_vec_init\n    // Only suggest collect\n    [0..200isize];\n    //~^ single_range_in_vec_init\n    vec![0..200isize];\n    //~^ single_range_in_vec_init\n    // Do not lint\n    [0..200, 0..100];\n    vec![0..200, 0..100];\n    [0.0..200.0];\n    vec![0.0..200.0];\n    // `Copy` is not implemented for `Range`, so this doesn't matter\n    // FIXME: [0..200; 2];\n    // FIXME: [vec!0..200; 2];\n\n    // Unfortunately skips any macros\n    a!();\n\n    // Skip external macros and procedural macros\n    external! {\n        [0..200];\n        vec![0..200];\n    }\n    with_span! {\n        span\n        [0..200];\n        vec![0..200];\n    }\n}\n\nfn issue16042() {\n    use std::ops::Range;\n\n    let input = vec![Range { start: 0, end: 5 }];\n}\n\nfn issue16044() {\n    macro_rules! as_i32 {\n        ($x:expr) => {\n            $x as i32\n        };\n    }\n\n    let input = vec![0..as_i32!(10)];\n    //~^ single_range_in_vec_init\n}\n"
  },
  {
    "path": "tests/ui/single_range_in_vec_init.stderr",
    "content": "error: an array of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:24:5\n   |\nLL |     [0..200];\n   |     ^^^^^^^^\n   |\n   = note: `-D clippy::single-range-in-vec-init` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_range_in_vec_init)]`\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     [0..200];\nLL +     (0..200).collect::<std::vec::Vec<i32>>();\n   |\nhelp: if you wanted an array of len 200, try\n   |\nLL -     [0..200];\nLL +     [0; 200];\n   |\n\nerror: a `Vec` of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:26:5\n   |\nLL |     vec![0..200];\n   |     ^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     vec![0..200];\nLL +     (0..200).collect::<std::vec::Vec<i32>>();\n   |\nhelp: if you wanted a `Vec` of len 200, try\n   |\nLL -     vec![0..200];\nLL +     vec![0; 200];\n   |\n\nerror: an array of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:28:5\n   |\nLL |     [0u8..200];\n   |     ^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     [0u8..200];\nLL +     (0u8..200).collect::<std::vec::Vec<u8>>();\n   |\nhelp: if you wanted an array of len 200, try\n   |\nLL -     [0u8..200];\nLL +     [0u8; 200];\n   |\n\nerror: an array of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:30:5\n   |\nLL |     [0usize..200];\n   |     ^^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     [0usize..200];\nLL +     (0usize..200).collect::<std::vec::Vec<usize>>();\n   |\nhelp: if you wanted an array of len 200, try\n   |\nLL -     [0usize..200];\nLL +     [0usize; 200];\n   |\n\nerror: an array of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:32:5\n   |\nLL |     [0..200usize];\n   |     ^^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     [0..200usize];\nLL +     (0..200usize).collect::<std::vec::Vec<usize>>();\n   |\nhelp: if you wanted an array of len 200usize, try\n   |\nLL -     [0..200usize];\nLL +     [0; 200usize];\n   |\n\nerror: a `Vec` of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:34:5\n   |\nLL |     vec![0u8..200];\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     vec![0u8..200];\nLL +     (0u8..200).collect::<std::vec::Vec<u8>>();\n   |\nhelp: if you wanted a `Vec` of len 200, try\n   |\nLL -     vec![0u8..200];\nLL +     vec![0u8; 200];\n   |\n\nerror: a `Vec` of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:36:5\n   |\nLL |     vec![0usize..200];\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     vec![0usize..200];\nLL +     (0usize..200).collect::<std::vec::Vec<usize>>();\n   |\nhelp: if you wanted a `Vec` of len 200, try\n   |\nLL -     vec![0usize..200];\nLL +     vec![0usize; 200];\n   |\n\nerror: a `Vec` of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:38:5\n   |\nLL |     vec![0..200usize];\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     vec![0..200usize];\nLL +     (0..200usize).collect::<std::vec::Vec<usize>>();\n   |\nhelp: if you wanted a `Vec` of len 200usize, try\n   |\nLL -     vec![0..200usize];\nLL +     vec![0; 200usize];\n   |\n\nerror: an array of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:41:5\n   |\nLL |     [0..200isize];\n   |     ^^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     [0..200isize];\nLL +     (0..200isize).collect::<std::vec::Vec<isize>>();\n   |\n\nerror: a `Vec` of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:43:5\n   |\nLL |     vec![0..200isize];\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     vec![0..200isize];\nLL +     (0..200isize).collect::<std::vec::Vec<isize>>();\n   |\n\nerror: a `Vec` of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init.rs:82:17\n   |\nLL |     let input = vec![0..as_i32!(10)];\n   |                 ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     let input = vec![0..as_i32!(10)];\nLL +     let input = (0..as_i32!(10)).collect::<std::vec::Vec<i32>>();\n   |\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/single_range_in_vec_init_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::single_range_in_vec_init)]\n\nuse std::ops::Range;\n\nfn issue16306(v: &[i32]) {\n    fn takes_range_slice(_: &[Range<i64>]) {}\n\n    let len = v.len();\n    takes_range_slice(&[0..len as i64]);\n    //~^ single_range_in_vec_init\n}\n"
  },
  {
    "path": "tests/ui/single_range_in_vec_init_unfixable.stderr",
    "content": "error: an array of `Range` that is only one element\n  --> tests/ui/single_range_in_vec_init_unfixable.rs:10:24\n   |\nLL |     takes_range_slice(&[0..len as i64]);\n   |                        ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::single-range-in-vec-init` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::single_range_in_vec_init)]`\nhelp: if you wanted a `Vec` that contains the entire range, try\n   |\nLL -     takes_range_slice(&[0..len as i64]);\nLL +     takes_range_slice(&(0..len as i64).collect::<std::vec::Vec<i64>>());\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/size_of_in_element_count/expressions.rs",
    "content": "#![warn(clippy::size_of_in_element_count)]\n#![allow(clippy::ptr_offset_with_cast)]\n\nuse std::mem::{size_of, size_of_val};\nuse std::ptr::{copy, copy_nonoverlapping, write_bytes};\n\nfn main() {\n    const SIZE: usize = 128;\n    const HALF_SIZE: usize = SIZE / 2;\n    const DOUBLE_SIZE: usize = SIZE * 2;\n    let mut x = [2u16; SIZE];\n    let mut y = [2u16; SIZE];\n\n    // Count expression involving multiplication of size_of (Should trigger the lint)\n    unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>() * SIZE) };\n    //~^ size_of_in_element_count\n\n    // Count expression involving nested multiplications of size_of (Should trigger the lint)\n    unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) };\n    //~^ size_of_in_element_count\n\n    // Count expression involving divisions of size_of (Should trigger the lint)\n    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u16>() / 2) };\n    //~^ size_of_in_element_count\n\n    // Count expression involving divisions by size_of (Should not trigger the lint)\n    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / size_of::<u16>()) };\n\n    // Count expression involving divisions by multiple size_of (Should not trigger the lint)\n    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 * size_of::<u16>())) };\n\n    // Count expression involving recursive divisions by size_of (Should trigger the lint)\n    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::<u16>())) };\n    //~^ size_of_in_element_count\n\n    // No size_of calls (Should not trigger the lint)\n    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), SIZE) };\n}\n"
  },
  {
    "path": "tests/ui/size_of_in_element_count/expressions.stderr",
    "content": "error: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/expressions.rs:15:62\n   |\nLL |     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>() * SIZE) };\n   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n   = note: `-D clippy::size-of-in-element-count` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::size_of_in_element_count)]`\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/expressions.rs:19:62\n   |\nLL |     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) };\n   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/expressions.rs:23:47\n   |\nLL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u16>() / 2) };\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/expressions.rs:33:47\n   |\nLL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::<u16>())) };\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/size_of_in_element_count/functions.rs",
    "content": "#![warn(clippy::size_of_in_element_count)]\n#![allow(clippy::ptr_offset_with_cast)]\n\nuse std::mem::{size_of, size_of_val};\nuse std::ptr::{\n    copy, copy_nonoverlapping, slice_from_raw_parts, slice_from_raw_parts_mut, swap_nonoverlapping, write_bytes,\n};\nuse std::slice::{from_raw_parts, from_raw_parts_mut};\n\nfn main() {\n    const SIZE: usize = 128;\n    const HALF_SIZE: usize = SIZE / 2;\n    const DOUBLE_SIZE: usize = SIZE * 2;\n    let mut x = [2u16; SIZE];\n    let mut y = [2u16; SIZE];\n\n    // Count is size_of (Should trigger the lint)\n    unsafe { copy_nonoverlapping::<u16>(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>()) };\n    //~^ size_of_in_element_count\n\n    unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };\n    //~^ size_of_in_element_count\n\n    unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u16>()) };\n    //~^ size_of_in_element_count\n\n    unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u16>()) };\n    //~^ size_of_in_element_count\n\n    unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u16>()) };\n    //~^ size_of_in_element_count\n\n    unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u16>()) };\n    //~^ size_of_in_element_count\n\n    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>()) };\n    //~^ size_of_in_element_count\n\n    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };\n    //~^ size_of_in_element_count\n\n    unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u16>() * SIZE) };\n    //~^ size_of_in_element_count\n\n    slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u16>() * SIZE);\n    //~^ size_of_in_element_count\n\n    slice_from_raw_parts(y.as_ptr(), size_of::<u16>() * SIZE);\n    //~^ size_of_in_element_count\n\n    unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u16>() * SIZE) };\n    //~^ size_of_in_element_count\n\n    unsafe { from_raw_parts(y.as_ptr(), size_of::<u16>() * SIZE) };\n    //~^ size_of_in_element_count\n\n    unsafe { y.as_mut_ptr().sub(size_of::<u16>()) };\n    //~^ size_of_in_element_count\n\n    y.as_ptr().wrapping_sub(size_of::<u16>());\n    //~^ size_of_in_element_count\n\n    unsafe { y.as_ptr().add(size_of::<u16>()) };\n    //~^ size_of_in_element_count\n\n    y.as_mut_ptr().wrapping_add(size_of::<u16>());\n    //~^ size_of_in_element_count\n\n    unsafe { y.as_ptr().offset(size_of::<u16>() as isize) };\n    //~^ size_of_in_element_count\n\n    y.as_mut_ptr().wrapping_offset(size_of::<u16>() as isize);\n    //~^ size_of_in_element_count\n}\n"
  },
  {
    "path": "tests/ui/size_of_in_element_count/functions.stderr",
    "content": "error: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:18:69\n   |\nLL |     unsafe { copy_nonoverlapping::<u16>(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>()) };\n   |                                                                     ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n   = note: `-D clippy::size-of-in-element-count` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::size_of_in_element_count)]`\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:21:62\n   |\nLL |     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };\n   |                                                              ^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:24:49\n   |\nLL |     unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u16>()) };\n   |                                                 ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:27:64\n   |\nLL |     unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u16>()) };\n   |                                                                ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:30:51\n   |\nLL |     unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u16>()) };\n   |                                                   ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:33:66\n   |\nLL |     unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u16>()) };\n   |                                                                  ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:36:47\n   |\nLL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>()) };\n   |                                               ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:39:47\n   |\nLL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };\n   |                                               ^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:42:66\n   |\nLL |     unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u16>() * SIZE) };\n   |                                                                  ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:45:46\n   |\nLL |     slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u16>() * SIZE);\n   |                                              ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:48:38\n   |\nLL |     slice_from_raw_parts(y.as_ptr(), size_of::<u16>() * SIZE);\n   |                                      ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:51:49\n   |\nLL |     unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u16>() * SIZE) };\n   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:54:41\n   |\nLL |     unsafe { from_raw_parts(y.as_ptr(), size_of::<u16>() * SIZE) };\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:57:33\n   |\nLL |     unsafe { y.as_mut_ptr().sub(size_of::<u16>()) };\n   |                                 ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:60:29\n   |\nLL |     y.as_ptr().wrapping_sub(size_of::<u16>());\n   |                             ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:63:29\n   |\nLL |     unsafe { y.as_ptr().add(size_of::<u16>()) };\n   |                             ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:66:33\n   |\nLL |     y.as_mut_ptr().wrapping_add(size_of::<u16>());\n   |                                 ^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:69:32\n   |\nLL |     unsafe { y.as_ptr().offset(size_of::<u16>() as isize) };\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: found a count of bytes instead of a count of elements of `T`\n  --> tests/ui/size_of_in_element_count/functions.rs:72:36\n   |\nLL |     y.as_mut_ptr().wrapping_offset(size_of::<u16>() as isize);\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/size_of_ref.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::size_of_ref)]\n\nuse std::mem::size_of_val;\n\nfn main() {\n    let x = 5;\n    let y = &x;\n\n    size_of_val(&x); // no lint\n    size_of_val(y); // no lint\n\n    size_of_val(&&x);\n    //~^ size_of_ref\n\n    size_of_val(&y);\n    //~^ size_of_ref\n}\n\nstruct S {\n    field: u32,\n    data: Vec<u8>,\n}\n\nimpl S {\n    /// Get size of object including `self`, in bytes.\n    pub fn size(&self) -> usize {\n        std::mem::size_of_val(&self) + (std::mem::size_of::<u8>() * self.data.capacity())\n        //~^ size_of_ref\n    }\n}\n"
  },
  {
    "path": "tests/ui/size_of_ref.stderr",
    "content": "error: argument to `size_of_val()` is a reference to a reference\n  --> tests/ui/size_of_ref.rs:13:5\n   |\nLL |     size_of_val(&&x);\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type\n   = note: `-D clippy::size-of-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::size_of_ref)]`\n\nerror: argument to `size_of_val()` is a reference to a reference\n  --> tests/ui/size_of_ref.rs:16:5\n   |\nLL |     size_of_val(&y);\n   |     ^^^^^^^^^^^^^^^\n   |\n   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type\n\nerror: argument to `size_of_val()` is a reference to a reference\n  --> tests/ui/size_of_ref.rs:28:9\n   |\nLL |         std::mem::size_of_val(&self) + (std::mem::size_of::<u8>() * self.data.capacity())\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/skip_while_next.rs",
    "content": "//@aux-build:option_helpers.rs\n\n#![warn(clippy::skip_while_next)]\n#![allow(clippy::disallowed_names, clippy::useless_vec)]\n\nextern crate option_helpers;\nuse option_helpers::IteratorFalsePositives;\n\n#[rustfmt::skip]\nfn skip_while_next() {\n    let v = vec![3, 2, 1, 0, -1, -2, -3];\n\n    // Single-line case.\n    let _ = v.iter().skip_while(|&x| *x < 0).next();\n    //~^ skip_while_next\n\n    // Multi-line case.\n    let _ = v.iter().skip_while(|&x| {\n    //~^ skip_while_next\n                                *x < 0\n                            }\n                   ).next();\n\n    // Check that hat we don't lint if the caller is not an `Iterator`.\n    let foo = IteratorFalsePositives { foo: 0 };\n    let _ = foo.skip_while().next();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/skip_while_next.stderr",
    "content": "error: called `skip_while(<p>).next()` on an `Iterator`\n  --> tests/ui/skip_while_next.rs:14:13\n   |\nLL |     let _ = v.iter().skip_while(|&x| *x < 0).next();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: this is more succinctly expressed by calling `.find(!<p>)` instead\n   = note: `-D clippy::skip-while-next` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::skip_while_next)]`\n\nerror: called `skip_while(<p>).next()` on an `Iterator`\n  --> tests/ui/skip_while_next.rs:18:13\n   |\nLL |       let _ = v.iter().skip_while(|&x| {\n   |  _____________^\nLL | |\nLL | |                                 *x < 0\nLL | |                             }\nLL | |                    ).next();\n   | |___________________________^\n   |\n   = help: this is more succinctly expressed by calling `.find(!<p>)` instead\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/sliced_string_as_bytes.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::sliced_string_as_bytes)]\n\nuse std::ops::{Index, Range};\n\nstruct Foo;\n\nstruct Bar;\n\nimpl Bar {\n    fn as_bytes(&self) -> &[u8] {\n        &[0, 1, 2, 3]\n    }\n}\n\nimpl Index<Range<usize>> for Foo {\n    type Output = Bar;\n\n    fn index(&self, _: Range<usize>) -> &Self::Output {\n        &Bar\n    }\n}\n\nfn main() {\n    let s = \"Lorem ipsum\";\n    let string: String = \"dolor sit amet\".to_owned();\n\n    let bytes = &s.as_bytes()[1..5];\n    //~^ sliced_string_as_bytes\n    let bytes = &string.as_bytes()[1..];\n    //~^ sliced_string_as_bytes\n    let bytes = &\"consectetur adipiscing\".as_bytes()[..=5];\n    //~^ sliced_string_as_bytes\n\n    // this lint is a perf lint meant to catch utf-8 alignment checks.\n    // while the slicing here *is* redundant, it's more like a needless borrow, and shouldn't affect\n    // perf\n    let bytes = s[..].as_bytes();\n    let bytes = string[..].as_bytes();\n\n    let f = Foo;\n    let bytes = f[0..4].as_bytes();\n}\n"
  },
  {
    "path": "tests/ui/sliced_string_as_bytes.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::sliced_string_as_bytes)]\n\nuse std::ops::{Index, Range};\n\nstruct Foo;\n\nstruct Bar;\n\nimpl Bar {\n    fn as_bytes(&self) -> &[u8] {\n        &[0, 1, 2, 3]\n    }\n}\n\nimpl Index<Range<usize>> for Foo {\n    type Output = Bar;\n\n    fn index(&self, _: Range<usize>) -> &Self::Output {\n        &Bar\n    }\n}\n\nfn main() {\n    let s = \"Lorem ipsum\";\n    let string: String = \"dolor sit amet\".to_owned();\n\n    let bytes = s[1..5].as_bytes();\n    //~^ sliced_string_as_bytes\n    let bytes = string[1..].as_bytes();\n    //~^ sliced_string_as_bytes\n    let bytes = \"consectetur adipiscing\"[..=5].as_bytes();\n    //~^ sliced_string_as_bytes\n\n    // this lint is a perf lint meant to catch utf-8 alignment checks.\n    // while the slicing here *is* redundant, it's more like a needless borrow, and shouldn't affect\n    // perf\n    let bytes = s[..].as_bytes();\n    let bytes = string[..].as_bytes();\n\n    let f = Foo;\n    let bytes = f[0..4].as_bytes();\n}\n"
  },
  {
    "path": "tests/ui/sliced_string_as_bytes.stderr",
    "content": "error: calling `as_bytes` after slicing a string\n  --> tests/ui/sliced_string_as_bytes.rs:28:17\n   |\nLL |     let bytes = s[1..5].as_bytes();\n   |                 ^^^^^^^^^^^^^^^^^^ help: try: `&s.as_bytes()[1..5]`\n   |\n   = note: `-D clippy::sliced-string-as-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::sliced_string_as_bytes)]`\n\nerror: calling `as_bytes` after slicing a string\n  --> tests/ui/sliced_string_as_bytes.rs:30:17\n   |\nLL |     let bytes = string[1..].as_bytes();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&string.as_bytes()[1..]`\n\nerror: calling `as_bytes` after slicing a string\n  --> tests/ui/sliced_string_as_bytes.rs:32:17\n   |\nLL |     let bytes = \"consectetur adipiscing\"[..=5].as_bytes();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&\"consectetur adipiscing\".as_bytes()[..=5]`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/slow_vector_initialization.fixed",
    "content": "#![allow(clippy::useless_vec, clippy::manual_repeat_n)]\n\nuse std::iter::repeat;\n\nfn main() {}\n\nfn extend_vector() {\n    // Extend with constant expression\n    let len = 300;\n    let mut vec1 = vec![0; len];\n\n    // Extend with len expression\n    let mut vec2 = vec![0; len - 10];\n\n    // Extend with mismatching expression should not be warned\n    let mut vec3 = Vec::with_capacity(24322);\n    vec3.extend(repeat(0).take(2));\n\n    let mut vec4 = vec![0; len];\n}\n\nfn mixed_extend_resize_vector() {\n    // Mismatching len\n    let mut mismatching_len = Vec::with_capacity(30);\n    mismatching_len.extend(repeat(0).take(40));\n\n    // Slow initialization\n    let mut resized_vec = vec![0; 30];\n\n    let mut extend_vec = vec![0; 30];\n}\n\nfn resize_vector() {\n    // Resize with constant expression\n    let len = 300;\n    let mut vec1 = vec![0; len];\n\n    // Resize mismatch len\n    let mut vec2 = Vec::with_capacity(200);\n    vec2.resize(10, 0);\n\n    // Resize with len expression\n    let mut vec3 = vec![0; len - 10];\n\n    let mut vec4 = vec![0; len];\n\n    // Reinitialization should be warned\n    vec1 = vec![0; 10];\n}\n\nfn from_empty_vec() {\n    // Resize with constant expression\n    let len = 300;\n    let mut vec1 = vec![0; len];\n\n    // Resize with len expression\n    let mut vec3 = vec![0; len - 10];\n\n    // Reinitialization should be warned\n    vec1 = vec![0; 10];\n\n    vec1 = vec![0; 10];\n\n    macro_rules! x {\n        () => {\n            vec![]\n        };\n    }\n\n    // `vec![]` comes from another macro, don't warn\n    vec1 = x!();\n    vec1.resize(10, 0);\n}\n\nfn do_stuff(vec: &mut [u8]) {}\n\nfn extend_vector_with_manipulations_between() {\n    let len = 300;\n    let mut vec1: Vec<u8> = Vec::with_capacity(len);\n    do_stuff(&mut vec1);\n    vec1.extend(repeat(0).take(len));\n}\n"
  },
  {
    "path": "tests/ui/slow_vector_initialization.rs",
    "content": "#![allow(clippy::useless_vec, clippy::manual_repeat_n)]\n\nuse std::iter::repeat;\n\nfn main() {}\n\nfn extend_vector() {\n    // Extend with constant expression\n    let len = 300;\n    let mut vec1 = Vec::with_capacity(len);\n    //~^ slow_vector_initialization\n\n    vec1.extend(repeat(0).take(len));\n\n    // Extend with len expression\n    let mut vec2 = Vec::with_capacity(len - 10);\n    //~^ slow_vector_initialization\n\n    vec2.extend(repeat(0).take(len - 10));\n\n    // Extend with mismatching expression should not be warned\n    let mut vec3 = Vec::with_capacity(24322);\n    vec3.extend(repeat(0).take(2));\n\n    let mut vec4 = Vec::with_capacity(len);\n    //~^ slow_vector_initialization\n\n    vec4.extend(repeat(0).take(vec4.capacity()));\n}\n\nfn mixed_extend_resize_vector() {\n    // Mismatching len\n    let mut mismatching_len = Vec::with_capacity(30);\n    mismatching_len.extend(repeat(0).take(40));\n\n    // Slow initialization\n    let mut resized_vec = Vec::with_capacity(30);\n    //~^ slow_vector_initialization\n\n    resized_vec.resize(30, 0);\n\n    let mut extend_vec = Vec::with_capacity(30);\n    //~^ slow_vector_initialization\n\n    extend_vec.extend(repeat(0).take(30));\n}\n\nfn resize_vector() {\n    // Resize with constant expression\n    let len = 300;\n    let mut vec1 = Vec::with_capacity(len);\n    //~^ slow_vector_initialization\n\n    vec1.resize(len, 0);\n\n    // Resize mismatch len\n    let mut vec2 = Vec::with_capacity(200);\n    vec2.resize(10, 0);\n\n    // Resize with len expression\n    let mut vec3 = Vec::with_capacity(len - 10);\n    //~^ slow_vector_initialization\n\n    vec3.resize(len - 10, 0);\n\n    let mut vec4 = Vec::with_capacity(len);\n    //~^ slow_vector_initialization\n\n    vec4.resize(vec4.capacity(), 0);\n\n    // Reinitialization should be warned\n    vec1 = Vec::with_capacity(10);\n    //~^ slow_vector_initialization\n\n    vec1.resize(10, 0);\n}\n\nfn from_empty_vec() {\n    // Resize with constant expression\n    let len = 300;\n    let mut vec1 = Vec::new();\n    //~^ slow_vector_initialization\n\n    vec1.resize(len, 0);\n\n    // Resize with len expression\n    let mut vec3 = Vec::new();\n    //~^ slow_vector_initialization\n\n    vec3.resize(len - 10, 0);\n\n    // Reinitialization should be warned\n    vec1 = Vec::new();\n    //~^ slow_vector_initialization\n\n    vec1.resize(10, 0);\n\n    vec1 = vec![];\n    //~^ slow_vector_initialization\n\n    vec1.resize(10, 0);\n\n    macro_rules! x {\n        () => {\n            vec![]\n        };\n    }\n\n    // `vec![]` comes from another macro, don't warn\n    vec1 = x!();\n    vec1.resize(10, 0);\n}\n\nfn do_stuff(vec: &mut [u8]) {}\n\nfn extend_vector_with_manipulations_between() {\n    let len = 300;\n    let mut vec1: Vec<u8> = Vec::with_capacity(len);\n    do_stuff(&mut vec1);\n    vec1.extend(repeat(0).take(len));\n}\n"
  },
  {
    "path": "tests/ui/slow_vector_initialization.stderr",
    "content": "error: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:10:20\n   |\nLL |       let mut vec1 = Vec::with_capacity(len);\n   |  ____________________^\n...  |\nLL | |     vec1.extend(repeat(0).take(len));\n   | |____________________________________^ help: consider replacing this with: `vec![0; len]`\n   |\n   = note: `-D clippy::slow-vector-initialization` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::slow_vector_initialization)]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:16:20\n   |\nLL |       let mut vec2 = Vec::with_capacity(len - 10);\n   |  ____________________^\n...  |\nLL | |     vec2.extend(repeat(0).take(len - 10));\n   | |_________________________________________^ help: consider replacing this with: `vec![0; len - 10]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:25:20\n   |\nLL |       let mut vec4 = Vec::with_capacity(len);\n   |  ____________________^\n...  |\nLL | |     vec4.extend(repeat(0).take(vec4.capacity()));\n   | |________________________________________________^ help: consider replacing this with: `vec![0; len]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:37:27\n   |\nLL |       let mut resized_vec = Vec::with_capacity(30);\n   |  ___________________________^\n...  |\nLL | |     resized_vec.resize(30, 0);\n   | |_____________________________^ help: consider replacing this with: `vec![0; 30]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:42:26\n   |\nLL |       let mut extend_vec = Vec::with_capacity(30);\n   |  __________________________^\n...  |\nLL | |     extend_vec.extend(repeat(0).take(30));\n   | |_________________________________________^ help: consider replacing this with: `vec![0; 30]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:51:20\n   |\nLL |       let mut vec1 = Vec::with_capacity(len);\n   |  ____________________^\n...  |\nLL | |     vec1.resize(len, 0);\n   | |_______________________^ help: consider replacing this with: `vec![0; len]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:61:20\n   |\nLL |       let mut vec3 = Vec::with_capacity(len - 10);\n   |  ____________________^\n...  |\nLL | |     vec3.resize(len - 10, 0);\n   | |____________________________^ help: consider replacing this with: `vec![0; len - 10]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:66:20\n   |\nLL |       let mut vec4 = Vec::with_capacity(len);\n   |  ____________________^\n...  |\nLL | |     vec4.resize(vec4.capacity(), 0);\n   | |___________________________________^ help: consider replacing this with: `vec![0; len]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:72:12\n   |\nLL |       vec1 = Vec::with_capacity(10);\n   |  ____________^\n...  |\nLL | |     vec1.resize(10, 0);\n   | |______________________^ help: consider replacing this with: `vec![0; 10]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:81:20\n   |\nLL |       let mut vec1 = Vec::new();\n   |  ____________________^\n...  |\nLL | |     vec1.resize(len, 0);\n   | |_______________________^ help: consider replacing this with: `vec![0; len]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:87:20\n   |\nLL |       let mut vec3 = Vec::new();\n   |  ____________________^\n...  |\nLL | |     vec3.resize(len - 10, 0);\n   | |____________________________^ help: consider replacing this with: `vec![0; len - 10]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:93:12\n   |\nLL |       vec1 = Vec::new();\n   |  ____________^\n...  |\nLL | |     vec1.resize(10, 0);\n   | |______________________^ help: consider replacing this with: `vec![0; 10]`\n\nerror: slow zero-filling initialization\n  --> tests/ui/slow_vector_initialization.rs:98:12\n   |\nLL |       vec1 = vec![];\n   |  ____________^\n...  |\nLL | |     vec1.resize(10, 0);\n   | |______________________^ help: consider replacing this with: `vec![0; 10]`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/stable_sort_primitive.fixed",
    "content": "#![warn(clippy::stable_sort_primitive)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    // positive examples\n    let mut vec = vec![1, 3, 2];\n    vec.sort_unstable();\n    //~^ stable_sort_primitive\n    let mut vec = vec![false, false, true];\n    vec.sort_unstable();\n    //~^ stable_sort_primitive\n    let mut vec = vec!['a', 'A', 'c'];\n    vec.sort_unstable();\n    //~^ stable_sort_primitive\n    let mut vec = vec![\"ab\", \"cd\", \"ab\", \"bc\"];\n    vec.sort_unstable();\n    //~^ stable_sort_primitive\n    let mut vec = vec![(2, 1), (1, 2), (2, 5)];\n    vec.sort_unstable();\n    //~^ stable_sort_primitive\n    let mut vec = vec![[2, 1], [1, 2], [2, 5]];\n    vec.sort_unstable();\n    //~^ stable_sort_primitive\n    let mut arr = [1, 3, 2];\n    arr.sort_unstable();\n    //~^ stable_sort_primitive\n    // Negative examples: behavior changes if made unstable\n    let mut vec = vec![1, 3, 2];\n    vec.sort_by_key(|i| i / 2);\n    vec.sort_by(|&a, &b| (a + b).cmp(&b));\n    // negative examples - Not of a primitive type\n    let mut vec_of_complex = vec![String::from(\"hello\"), String::from(\"world!\")];\n    vec_of_complex.sort();\n    vec_of_complex.sort_by_key(String::len);\n    let mut vec = vec![(String::from(\"hello\"), String::from(\"world\"))];\n    vec.sort();\n    let mut vec = vec![[String::from(\"hello\"), String::from(\"world\")]];\n    vec.sort();\n}\n"
  },
  {
    "path": "tests/ui/stable_sort_primitive.rs",
    "content": "#![warn(clippy::stable_sort_primitive)]\n#![allow(clippy::useless_vec)]\n\nfn main() {\n    // positive examples\n    let mut vec = vec![1, 3, 2];\n    vec.sort();\n    //~^ stable_sort_primitive\n    let mut vec = vec![false, false, true];\n    vec.sort();\n    //~^ stable_sort_primitive\n    let mut vec = vec!['a', 'A', 'c'];\n    vec.sort();\n    //~^ stable_sort_primitive\n    let mut vec = vec![\"ab\", \"cd\", \"ab\", \"bc\"];\n    vec.sort();\n    //~^ stable_sort_primitive\n    let mut vec = vec![(2, 1), (1, 2), (2, 5)];\n    vec.sort();\n    //~^ stable_sort_primitive\n    let mut vec = vec![[2, 1], [1, 2], [2, 5]];\n    vec.sort();\n    //~^ stable_sort_primitive\n    let mut arr = [1, 3, 2];\n    arr.sort();\n    //~^ stable_sort_primitive\n    // Negative examples: behavior changes if made unstable\n    let mut vec = vec![1, 3, 2];\n    vec.sort_by_key(|i| i / 2);\n    vec.sort_by(|&a, &b| (a + b).cmp(&b));\n    // negative examples - Not of a primitive type\n    let mut vec_of_complex = vec![String::from(\"hello\"), String::from(\"world!\")];\n    vec_of_complex.sort();\n    vec_of_complex.sort_by_key(String::len);\n    let mut vec = vec![(String::from(\"hello\"), String::from(\"world\"))];\n    vec.sort();\n    let mut vec = vec![[String::from(\"hello\"), String::from(\"world\")]];\n    vec.sort();\n}\n"
  },
  {
    "path": "tests/ui/stable_sort_primitive.stderr",
    "content": "error: used `sort` on primitive type `i32`\n  --> tests/ui/stable_sort_primitive.rs:7:5\n   |\nLL |     vec.sort();\n   |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`\n   |\n   = note: an unstable sort typically performs faster without any observable difference for this data type\n   = note: `-D clippy::stable-sort-primitive` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::stable_sort_primitive)]`\n\nerror: used `sort` on primitive type `bool`\n  --> tests/ui/stable_sort_primitive.rs:10:5\n   |\nLL |     vec.sort();\n   |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`\n   |\n   = note: an unstable sort typically performs faster without any observable difference for this data type\n\nerror: used `sort` on primitive type `char`\n  --> tests/ui/stable_sort_primitive.rs:13:5\n   |\nLL |     vec.sort();\n   |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`\n   |\n   = note: an unstable sort typically performs faster without any observable difference for this data type\n\nerror: used `sort` on primitive type `str`\n  --> tests/ui/stable_sort_primitive.rs:16:5\n   |\nLL |     vec.sort();\n   |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`\n   |\n   = note: an unstable sort typically performs faster without any observable difference for this data type\n\nerror: used `sort` on primitive type `tuple`\n  --> tests/ui/stable_sort_primitive.rs:19:5\n   |\nLL |     vec.sort();\n   |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`\n   |\n   = note: an unstable sort typically performs faster without any observable difference for this data type\n\nerror: used `sort` on primitive type `array`\n  --> tests/ui/stable_sort_primitive.rs:22:5\n   |\nLL |     vec.sort();\n   |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`\n   |\n   = note: an unstable sort typically performs faster without any observable difference for this data type\n\nerror: used `sort` on primitive type `i32`\n  --> tests/ui/stable_sort_primitive.rs:25:5\n   |\nLL |     arr.sort();\n   |     ^^^^^^^^^^ help: try: `arr.sort_unstable()`\n   |\n   = note: an unstable sort typically performs faster without any observable difference for this data type\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/starts_ends_with.fixed",
    "content": "#![allow(clippy::needless_ifs, dead_code, unused_must_use, clippy::double_ended_iterator_last)]\n\nfn main() {}\n\n#[allow(clippy::unnecessary_operation)]\nfn starts_with() {\n    \"\".starts_with(' ');\n    //~^ chars_next_cmp\n    !\"\".starts_with(' ');\n    //~^ chars_next_cmp\n\n    // Ensure that suggestion is escaped correctly\n    \"\".starts_with('\\n');\n    //~^ chars_next_cmp\n    !\"\".starts_with('\\n');\n    //~^ chars_next_cmp\n}\n\nfn chars_cmp_with_unwrap() {\n    let s = String::from(\"foo\");\n    if s.starts_with('f') {\n        //~^ chars_next_cmp\n        // s.starts_with('f')\n        // Nothing here\n    }\n    if s.ends_with('o') {\n        //~^ chars_last_cmp\n        // s.ends_with('o')\n        // Nothing here\n    }\n    if s.ends_with('o') {\n        //~^ chars_last_cmp\n        // s.ends_with('o')\n        // Nothing here\n    }\n    if !s.starts_with('f') {\n        //~^ chars_next_cmp\n        // !s.starts_with('f')\n        // Nothing here\n    }\n    if !s.ends_with('o') {\n        //~^ chars_last_cmp\n        // !s.ends_with('o')\n        // Nothing here\n    }\n    if !s.ends_with('\\n') {\n        //~^ chars_last_cmp\n        // !s.ends_with('o')\n        // Nothing here\n    }\n}\n\n#[allow(clippy::unnecessary_operation)]\nfn ends_with() {\n    \"\".ends_with(' ');\n    //~^ chars_last_cmp\n    !\"\".ends_with(' ');\n    //~^ chars_last_cmp\n    \"\".ends_with(' ');\n    //~^ chars_last_cmp\n    !\"\".ends_with(' ');\n    //~^ chars_last_cmp\n\n    // Ensure that suggestion is escaped correctly\n    \"\".ends_with('\\n');\n    //~^ chars_last_cmp\n    !\"\".ends_with('\\n');\n    //~^ chars_last_cmp\n}\n"
  },
  {
    "path": "tests/ui/starts_ends_with.rs",
    "content": "#![allow(clippy::needless_ifs, dead_code, unused_must_use, clippy::double_ended_iterator_last)]\n\nfn main() {}\n\n#[allow(clippy::unnecessary_operation)]\nfn starts_with() {\n    \"\".chars().next() == Some(' ');\n    //~^ chars_next_cmp\n    Some(' ') != \"\".chars().next();\n    //~^ chars_next_cmp\n\n    // Ensure that suggestion is escaped correctly\n    \"\".chars().next() == Some('\\n');\n    //~^ chars_next_cmp\n    Some('\\n') != \"\".chars().next();\n    //~^ chars_next_cmp\n}\n\nfn chars_cmp_with_unwrap() {\n    let s = String::from(\"foo\");\n    if s.chars().next().unwrap() == 'f' {\n        //~^ chars_next_cmp\n        // s.starts_with('f')\n        // Nothing here\n    }\n    if s.chars().next_back().unwrap() == 'o' {\n        //~^ chars_last_cmp\n        // s.ends_with('o')\n        // Nothing here\n    }\n    if s.chars().last().unwrap() == 'o' {\n        //~^ chars_last_cmp\n        // s.ends_with('o')\n        // Nothing here\n    }\n    if s.chars().next().unwrap() != 'f' {\n        //~^ chars_next_cmp\n        // !s.starts_with('f')\n        // Nothing here\n    }\n    if s.chars().next_back().unwrap() != 'o' {\n        //~^ chars_last_cmp\n        // !s.ends_with('o')\n        // Nothing here\n    }\n    if s.chars().last().unwrap() != '\\n' {\n        //~^ chars_last_cmp\n        // !s.ends_with('o')\n        // Nothing here\n    }\n}\n\n#[allow(clippy::unnecessary_operation)]\nfn ends_with() {\n    \"\".chars().last() == Some(' ');\n    //~^ chars_last_cmp\n    Some(' ') != \"\".chars().last();\n    //~^ chars_last_cmp\n    \"\".chars().next_back() == Some(' ');\n    //~^ chars_last_cmp\n    Some(' ') != \"\".chars().next_back();\n    //~^ chars_last_cmp\n\n    // Ensure that suggestion is escaped correctly\n    \"\".chars().last() == Some('\\n');\n    //~^ chars_last_cmp\n    Some('\\n') != \"\".chars().last();\n    //~^ chars_last_cmp\n}\n"
  },
  {
    "path": "tests/ui/starts_ends_with.stderr",
    "content": "error: you should use the `starts_with` method\n  --> tests/ui/starts_ends_with.rs:7:5\n   |\nLL |     \"\".chars().next() == Some(' ');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `\"\".starts_with(' ')`\n   |\n   = note: `-D clippy::chars-next-cmp` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::chars_next_cmp)]`\n\nerror: you should use the `starts_with` method\n  --> tests/ui/starts_ends_with.rs:9:5\n   |\nLL |     Some(' ') != \"\".chars().next();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!\"\".starts_with(' ')`\n\nerror: you should use the `starts_with` method\n  --> tests/ui/starts_ends_with.rs:13:5\n   |\nLL |     \"\".chars().next() == Some('\\n');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `\"\".starts_with('\\n')`\n\nerror: you should use the `starts_with` method\n  --> tests/ui/starts_ends_with.rs:15:5\n   |\nLL |     Some('\\n') != \"\".chars().next();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!\"\".starts_with('\\n')`\n\nerror: you should use the `starts_with` method\n  --> tests/ui/starts_ends_with.rs:21:8\n   |\nLL |     if s.chars().next().unwrap() == 'f' {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.starts_with('f')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:26:8\n   |\nLL |     if s.chars().next_back().unwrap() == 'o' {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.ends_with('o')`\n   |\n   = note: `-D clippy::chars-last-cmp` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::chars_last_cmp)]`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:31:8\n   |\nLL |     if s.chars().last().unwrap() == 'o' {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `s.ends_with('o')`\n\nerror: you should use the `starts_with` method\n  --> tests/ui/starts_ends_with.rs:36:8\n   |\nLL |     if s.chars().next().unwrap() != 'f' {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.starts_with('f')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:41:8\n   |\nLL |     if s.chars().next_back().unwrap() != 'o' {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.ends_with('o')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:46:8\n   |\nLL |     if s.chars().last().unwrap() != '\\n' {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!s.ends_with('\\n')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:55:5\n   |\nLL |     \"\".chars().last() == Some(' ');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `\"\".ends_with(' ')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:57:5\n   |\nLL |     Some(' ') != \"\".chars().last();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!\"\".ends_with(' ')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:59:5\n   |\nLL |     \"\".chars().next_back() == Some(' ');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `\"\".ends_with(' ')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:61:5\n   |\nLL |     Some(' ') != \"\".chars().next_back();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!\"\".ends_with(' ')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:65:5\n   |\nLL |     \"\".chars().last() == Some('\\n');\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `\"\".ends_with('\\n')`\n\nerror: you should use the `ends_with` method\n  --> tests/ui/starts_ends_with.rs:67:5\n   |\nLL |     Some('\\n') != \"\".chars().last();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: like this: `!\"\".ends_with('\\n')`\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/std_instead_of_core.fixed",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::std_instead_of_core)]\n#![allow(unused_imports, deprecated)]\n\nextern crate alloc;\n\n#[macro_use]\nextern crate proc_macro_derive;\n\nfn std_instead_of_core() {\n    // Regular import\n    use core::hash::Hasher;\n    //~^ ERROR: used import from `std` instead of `core`\n    // Absolute path\n    use ::core::hash::Hash;\n    //~^ ERROR: used import from `std` instead of `core`\n    // Don't lint on `env` macro\n    use std::env;\n\n    // Multiple imports\n    use core::fmt::{Debug, Result};\n    //~^ ERROR: used import from `std` instead of `core`\n\n    // Multiple imports multiline\n    #[rustfmt::skip]\n    use core::{\n        //~^ ERROR: used import from `std` instead of `core`\n        fmt::Write as _,\n        ptr::read_unaligned,\n    };\n\n    // Function calls\n    let ptr = core::ptr::null::<u32>();\n    //~^ ERROR: used import from `std` instead of `core`\n    let ptr_mut = ::core::ptr::null_mut::<usize>();\n    //~^ ERROR: used import from `std` instead of `core`\n\n    // Types\n    let cell = core::cell::Cell::new(8u32);\n    //~^ ERROR: used import from `std` instead of `core`\n    let cell_absolute = ::core::cell::Cell::new(8u32);\n    //~^ ERROR: used import from `std` instead of `core`\n\n    let _ = std::env!(\"PATH\");\n\n    use core::error::Error;\n    //~^ ERROR: used import from `std` instead of `core`\n\n    // lint items re-exported from private modules, `core::iter::traits::iterator::Iterator`\n    use core::iter::Iterator;\n    //~^ ERROR: used import from `std` instead of `core`\n}\n\n#[warn(clippy::std_instead_of_alloc)]\nfn std_instead_of_alloc() {\n    // Only lint once.\n    use alloc::vec;\n    //~^ ERROR: used import from `std` instead of `alloc`\n    use alloc::vec::Vec;\n    //~^ ERROR: used import from `std` instead of `alloc`\n}\n\n#[warn(clippy::alloc_instead_of_core)]\nfn alloc_instead_of_core() {\n    use core::slice::from_ref;\n    //~^ ERROR: used import from `alloc` instead of `core`\n}\n\nmod std_in_proc_macro_derive {\n    #[warn(clippy::alloc_instead_of_core)]\n    #[allow(unused)]\n    #[derive(ImplStructWithStdDisplay)]\n    struct B {}\n}\n\n// Some intrinsics are usable on stable but live in an unstable module, but should still suggest\n// replacing std -> core\nfn intrinsic(a: *mut u8, b: *mut u8) {\n    unsafe {\n        core::intrinsics::copy(a, b, 1);\n        //~^ std_instead_of_core\n    }\n}\n\n#[clippy::msrv = \"1.76\"]\nfn msrv_1_76(_: std::net::IpAddr) {}\n\n#[clippy::msrv = \"1.77\"]\nfn msrv_1_77(_: core::net::IpAddr) {}\n//~^ std_instead_of_core\n\n#[warn(clippy::alloc_instead_of_core)]\nfn issue15579() {\n    use std::alloc;\n\n    let layout = alloc::Layout::new::<u8>();\n}\n"
  },
  {
    "path": "tests/ui/std_instead_of_core.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::std_instead_of_core)]\n#![allow(unused_imports, deprecated)]\n\nextern crate alloc;\n\n#[macro_use]\nextern crate proc_macro_derive;\n\nfn std_instead_of_core() {\n    // Regular import\n    use std::hash::Hasher;\n    //~^ ERROR: used import from `std` instead of `core`\n    // Absolute path\n    use ::std::hash::Hash;\n    //~^ ERROR: used import from `std` instead of `core`\n    // Don't lint on `env` macro\n    use std::env;\n\n    // Multiple imports\n    use std::fmt::{Debug, Result};\n    //~^ ERROR: used import from `std` instead of `core`\n\n    // Multiple imports multiline\n    #[rustfmt::skip]\n    use std::{\n        //~^ ERROR: used import from `std` instead of `core`\n        fmt::Write as _,\n        ptr::read_unaligned,\n    };\n\n    // Function calls\n    let ptr = std::ptr::null::<u32>();\n    //~^ ERROR: used import from `std` instead of `core`\n    let ptr_mut = ::std::ptr::null_mut::<usize>();\n    //~^ ERROR: used import from `std` instead of `core`\n\n    // Types\n    let cell = std::cell::Cell::new(8u32);\n    //~^ ERROR: used import from `std` instead of `core`\n    let cell_absolute = ::std::cell::Cell::new(8u32);\n    //~^ ERROR: used import from `std` instead of `core`\n\n    let _ = std::env!(\"PATH\");\n\n    use std::error::Error;\n    //~^ ERROR: used import from `std` instead of `core`\n\n    // lint items re-exported from private modules, `core::iter::traits::iterator::Iterator`\n    use std::iter::Iterator;\n    //~^ ERROR: used import from `std` instead of `core`\n}\n\n#[warn(clippy::std_instead_of_alloc)]\nfn std_instead_of_alloc() {\n    // Only lint once.\n    use std::vec;\n    //~^ ERROR: used import from `std` instead of `alloc`\n    use std::vec::Vec;\n    //~^ ERROR: used import from `std` instead of `alloc`\n}\n\n#[warn(clippy::alloc_instead_of_core)]\nfn alloc_instead_of_core() {\n    use alloc::slice::from_ref;\n    //~^ ERROR: used import from `alloc` instead of `core`\n}\n\nmod std_in_proc_macro_derive {\n    #[warn(clippy::alloc_instead_of_core)]\n    #[allow(unused)]\n    #[derive(ImplStructWithStdDisplay)]\n    struct B {}\n}\n\n// Some intrinsics are usable on stable but live in an unstable module, but should still suggest\n// replacing std -> core\nfn intrinsic(a: *mut u8, b: *mut u8) {\n    unsafe {\n        std::intrinsics::copy(a, b, 1);\n        //~^ std_instead_of_core\n    }\n}\n\n#[clippy::msrv = \"1.76\"]\nfn msrv_1_76(_: std::net::IpAddr) {}\n\n#[clippy::msrv = \"1.77\"]\nfn msrv_1_77(_: std::net::IpAddr) {}\n//~^ std_instead_of_core\n\n#[warn(clippy::alloc_instead_of_core)]\nfn issue15579() {\n    use std::alloc;\n\n    let layout = alloc::Layout::new::<u8>();\n}\n"
  },
  {
    "path": "tests/ui/std_instead_of_core.stderr",
    "content": "error: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:13:9\n   |\nLL |     use std::hash::Hasher;\n   |         ^^^ help: consider importing the item from `core`: `core`\n   |\n   = note: `-D clippy::std-instead-of-core` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:16:11\n   |\nLL |     use ::std::hash::Hash;\n   |           ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:22:9\n   |\nLL |     use std::fmt::{Debug, Result};\n   |         ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:27:9\n   |\nLL |     use std::{\n   |         ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:34:15\n   |\nLL |     let ptr = std::ptr::null::<u32>();\n   |               ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:36:21\n   |\nLL |     let ptr_mut = ::std::ptr::null_mut::<usize>();\n   |                     ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:40:16\n   |\nLL |     let cell = std::cell::Cell::new(8u32);\n   |                ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:42:27\n   |\nLL |     let cell_absolute = ::std::cell::Cell::new(8u32);\n   |                           ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:47:9\n   |\nLL |     use std::error::Error;\n   |         ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:51:9\n   |\nLL |     use std::iter::Iterator;\n   |         ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `alloc`\n  --> tests/ui/std_instead_of_core.rs:58:9\n   |\nLL |     use std::vec;\n   |         ^^^ help: consider importing the item from `alloc`: `alloc`\n   |\n   = note: `-D clippy::std-instead-of-alloc` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`\n\nerror: used import from `std` instead of `alloc`\n  --> tests/ui/std_instead_of_core.rs:60:9\n   |\nLL |     use std::vec::Vec;\n   |         ^^^ help: consider importing the item from `alloc`: `alloc`\n\nerror: used import from `alloc` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:66:9\n   |\nLL |     use alloc::slice::from_ref;\n   |         ^^^^^ help: consider importing the item from `core`: `core`\n   |\n   = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:81:9\n   |\nLL |         std::intrinsics::copy(a, b, 1);\n   |         ^^^ help: consider importing the item from `core`: `core`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core.rs:90:17\n   |\nLL | fn msrv_1_77(_: std::net::IpAddr) {}\n   |                 ^^^ help: consider importing the item from `core`: `core`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/std_instead_of_core_unfixable.rs",
    "content": "#![warn(clippy::std_instead_of_core)]\n#![warn(clippy::std_instead_of_alloc)]\n#![allow(unused_imports)]\n\n#[rustfmt::skip]\nfn issue14982() {\n    use std::{collections::HashMap, hash::Hash};\n    //~^ std_instead_of_core\n}\n\n#[rustfmt::skip]\nfn issue15143() {\n    use std::{error::Error, vec::Vec, fs::File};\n    //~^ std_instead_of_core\n    //~| std_instead_of_alloc\n}\n"
  },
  {
    "path": "tests/ui/std_instead_of_core_unfixable.stderr",
    "content": "error: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core_unfixable.rs:7:43\n   |\nLL |     use std::{collections::HashMap, hash::Hash};\n   |                                           ^^^^\n   |\n   = help: consider importing the item from `core`\n   = note: `-D clippy::std-instead-of-core` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]`\n\nerror: used import from `std` instead of `core`\n  --> tests/ui/std_instead_of_core_unfixable.rs:13:22\n   |\nLL |     use std::{error::Error, vec::Vec, fs::File};\n   |                      ^^^^^\n   |\n   = help: consider importing the item from `core`\n\nerror: used import from `std` instead of `alloc`\n  --> tests/ui/std_instead_of_core_unfixable.rs:13:34\n   |\nLL |     use std::{error::Error, vec::Vec, fs::File};\n   |                                  ^^^\n   |\n   = help: consider importing the item from `alloc`\n   = note: `-D clippy::std-instead-of-alloc` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/str_split.fixed",
    "content": "#![warn(clippy::str_split_at_newline)]\n\nuse std::ops::Deref;\n\nstruct NotStr<'a> {\n    s: &'a str,\n}\n\nimpl<'a> NotStr<'a> {\n    fn trim(&'a self) -> &'a str {\n        self.s\n    }\n}\n\nstruct DerefsIntoNotStr<'a> {\n    not_str: &'a NotStr<'a>,\n}\n\nimpl<'a> Deref for DerefsIntoNotStr<'a> {\n    type Target = NotStr<'a>;\n\n    fn deref(&self) -> &Self::Target {\n        self.not_str\n    }\n}\n\nstruct DerefsIntoStr<'a> {\n    s: &'a str,\n}\n\nimpl<'a> Deref for DerefsIntoStr<'a> {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        self.s\n    }\n}\n\nmacro_rules! trim_split {\n    ( $x:expr, $y:expr ) => {\n        $x.trim().split($y);\n    };\n}\n\nmacro_rules! make_str {\n    ( $x: expr ) => {\n        format!(\"x={}\", $x)\n    };\n}\n\nfn main() {\n    let s1 = \"hello\\nworld\\n\";\n    let s2 = s1.to_owned();\n\n    // CASES THAT SHOULD EMIT A LINT\n\n    // Splitting a `str` variable at \"\\n\" or \"\\r\\n\" after trimming should warn\n    let _ = s1.lines();\n    //~^ str_split_at_newline\n    #[allow(clippy::single_char_pattern)]\n    let _ = s1.lines();\n    //~^ str_split_at_newline\n    let _ = s1.lines();\n    //~^ str_split_at_newline\n\n    // Splitting a `String` variable at \"\\n\" or \"\\r\\n\" after trimming should warn\n    let _ = s2.lines();\n    //~^ str_split_at_newline\n    #[allow(clippy::single_char_pattern)]\n    let _ = s2.lines();\n    //~^ str_split_at_newline\n    let _ = s2.lines();\n    //~^ str_split_at_newline\n\n    // Splitting a variable that derefs into `str` at \"\\n\" or \"\\r\\n\" after trimming should warn.\n    let s3 = DerefsIntoStr { s: s1 };\n    let _ = s3.lines();\n    //~^ str_split_at_newline\n    #[allow(clippy::single_char_pattern)]\n    let _ = s3.lines();\n    //~^ str_split_at_newline\n    let _ = s3.lines();\n    //~^ str_split_at_newline\n\n    // If the `&str` is generated by a macro then the macro should not be expanded in the suggested fix.\n    let _ = make_str!(s1).lines();\n    //~^ str_split_at_newline\n\n    // CASES THAT SHOULD NOT EMIT A LINT\n\n    // Splitting a `str` constant at \"\\n\" or \"\\r\\n\" after trimming should not warn\n    let _ = \"hello\\nworld\\n\".trim().split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = \"hello\\nworld\\n\".trim().split(\"\\n\");\n    let _ = \"hello\\nworld\\n\".trim().split(\"\\r\\n\");\n\n    // Splitting a `str` variable at \"\\n\" or \"\\r\\n\" without trimming should not warn, since it is not\n    // equivalent\n    let _ = s1.split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s1.split(\"\\n\");\n    let _ = s1.split(\"\\r\\n\");\n\n    // Splitting a `String` variable at \"\\n\" or \"\\r\\n\" without trimming should not warn.\n    let _ = s2.split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s2.split(\"\\n\");\n\n    // Splitting a variable that derefs into `str` at \"\\n\" or \"\\r\\n\" without trimming should not warn.\n    let _ = s3.split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s3.split(\"\\n\");\n    let _ = s3.split(\"\\r\\n\");\n    let _ = s2.split(\"\\r\\n\");\n\n    // Splitting a `str` variable at other separators should not warn\n    let _ = s1.trim().split('\\r');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s1.trim().split(\"\\r\");\n    let _ = s1.trim().split(\"\\n\\r\");\n    let _ = s1.trim().split(\"\\r \\n\");\n\n    // Splitting a `String` variable at other separators should not warn\n    let _ = s2.trim().split('\\r');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s2.trim().split(\"\\r\");\n    let _ = s2.trim().split(\"\\n\\r\");\n\n    // Splitting a variable that derefs into `str` at other separators should not warn\n    let _ = s3.trim().split('\\r');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s3.trim().split(\"\\r\");\n    let _ = s3.trim().split(\"\\n\\r\");\n    let _ = s3.trim().split(\"\\r \\n\");\n    let _ = s2.trim().split(\"\\r \\n\");\n\n    // Using `trim` and `split` on other types should not warn\n    let not_str = NotStr { s: s1 };\n    let _ = not_str.trim().split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = not_str.trim().split(\"\\n\");\n    let _ = not_str.trim().split(\"\\r\\n\");\n    let derefs_into_not_str = DerefsIntoNotStr { not_str: &not_str };\n    let _ = derefs_into_not_str.trim().split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = derefs_into_not_str.trim().split(\"\\n\");\n    let _ = derefs_into_not_str.trim().split(\"\\r\\n\");\n\n    // Code generated by macros should not create a warning\n    trim_split!(s1, \"\\r\\n\");\n    trim_split!(\"hello\\nworld\\n\", \"\\r\\n\");\n    trim_split!(s2, \"\\r\\n\");\n    trim_split!(s3, \"\\r\\n\");\n}\n"
  },
  {
    "path": "tests/ui/str_split.rs",
    "content": "#![warn(clippy::str_split_at_newline)]\n\nuse std::ops::Deref;\n\nstruct NotStr<'a> {\n    s: &'a str,\n}\n\nimpl<'a> NotStr<'a> {\n    fn trim(&'a self) -> &'a str {\n        self.s\n    }\n}\n\nstruct DerefsIntoNotStr<'a> {\n    not_str: &'a NotStr<'a>,\n}\n\nimpl<'a> Deref for DerefsIntoNotStr<'a> {\n    type Target = NotStr<'a>;\n\n    fn deref(&self) -> &Self::Target {\n        self.not_str\n    }\n}\n\nstruct DerefsIntoStr<'a> {\n    s: &'a str,\n}\n\nimpl<'a> Deref for DerefsIntoStr<'a> {\n    type Target = str;\n\n    fn deref(&self) -> &Self::Target {\n        self.s\n    }\n}\n\nmacro_rules! trim_split {\n    ( $x:expr, $y:expr ) => {\n        $x.trim().split($y);\n    };\n}\n\nmacro_rules! make_str {\n    ( $x: expr ) => {\n        format!(\"x={}\", $x)\n    };\n}\n\nfn main() {\n    let s1 = \"hello\\nworld\\n\";\n    let s2 = s1.to_owned();\n\n    // CASES THAT SHOULD EMIT A LINT\n\n    // Splitting a `str` variable at \"\\n\" or \"\\r\\n\" after trimming should warn\n    let _ = s1.trim().split('\\n');\n    //~^ str_split_at_newline\n    #[allow(clippy::single_char_pattern)]\n    let _ = s1.trim().split(\"\\n\");\n    //~^ str_split_at_newline\n    let _ = s1.trim().split(\"\\r\\n\");\n    //~^ str_split_at_newline\n\n    // Splitting a `String` variable at \"\\n\" or \"\\r\\n\" after trimming should warn\n    let _ = s2.trim().split('\\n');\n    //~^ str_split_at_newline\n    #[allow(clippy::single_char_pattern)]\n    let _ = s2.trim().split(\"\\n\");\n    //~^ str_split_at_newline\n    let _ = s2.trim().split(\"\\r\\n\");\n    //~^ str_split_at_newline\n\n    // Splitting a variable that derefs into `str` at \"\\n\" or \"\\r\\n\" after trimming should warn.\n    let s3 = DerefsIntoStr { s: s1 };\n    let _ = s3.trim().split('\\n');\n    //~^ str_split_at_newline\n    #[allow(clippy::single_char_pattern)]\n    let _ = s3.trim().split(\"\\n\");\n    //~^ str_split_at_newline\n    let _ = s3.trim().split(\"\\r\\n\");\n    //~^ str_split_at_newline\n\n    // If the `&str` is generated by a macro then the macro should not be expanded in the suggested fix.\n    let _ = make_str!(s1).trim().split('\\n');\n    //~^ str_split_at_newline\n\n    // CASES THAT SHOULD NOT EMIT A LINT\n\n    // Splitting a `str` constant at \"\\n\" or \"\\r\\n\" after trimming should not warn\n    let _ = \"hello\\nworld\\n\".trim().split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = \"hello\\nworld\\n\".trim().split(\"\\n\");\n    let _ = \"hello\\nworld\\n\".trim().split(\"\\r\\n\");\n\n    // Splitting a `str` variable at \"\\n\" or \"\\r\\n\" without trimming should not warn, since it is not\n    // equivalent\n    let _ = s1.split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s1.split(\"\\n\");\n    let _ = s1.split(\"\\r\\n\");\n\n    // Splitting a `String` variable at \"\\n\" or \"\\r\\n\" without trimming should not warn.\n    let _ = s2.split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s2.split(\"\\n\");\n\n    // Splitting a variable that derefs into `str` at \"\\n\" or \"\\r\\n\" without trimming should not warn.\n    let _ = s3.split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s3.split(\"\\n\");\n    let _ = s3.split(\"\\r\\n\");\n    let _ = s2.split(\"\\r\\n\");\n\n    // Splitting a `str` variable at other separators should not warn\n    let _ = s1.trim().split('\\r');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s1.trim().split(\"\\r\");\n    let _ = s1.trim().split(\"\\n\\r\");\n    let _ = s1.trim().split(\"\\r \\n\");\n\n    // Splitting a `String` variable at other separators should not warn\n    let _ = s2.trim().split('\\r');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s2.trim().split(\"\\r\");\n    let _ = s2.trim().split(\"\\n\\r\");\n\n    // Splitting a variable that derefs into `str` at other separators should not warn\n    let _ = s3.trim().split('\\r');\n    #[allow(clippy::single_char_pattern)]\n    let _ = s3.trim().split(\"\\r\");\n    let _ = s3.trim().split(\"\\n\\r\");\n    let _ = s3.trim().split(\"\\r \\n\");\n    let _ = s2.trim().split(\"\\r \\n\");\n\n    // Using `trim` and `split` on other types should not warn\n    let not_str = NotStr { s: s1 };\n    let _ = not_str.trim().split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = not_str.trim().split(\"\\n\");\n    let _ = not_str.trim().split(\"\\r\\n\");\n    let derefs_into_not_str = DerefsIntoNotStr { not_str: &not_str };\n    let _ = derefs_into_not_str.trim().split('\\n');\n    #[allow(clippy::single_char_pattern)]\n    let _ = derefs_into_not_str.trim().split(\"\\n\");\n    let _ = derefs_into_not_str.trim().split(\"\\r\\n\");\n\n    // Code generated by macros should not create a warning\n    trim_split!(s1, \"\\r\\n\");\n    trim_split!(\"hello\\nworld\\n\", \"\\r\\n\");\n    trim_split!(s2, \"\\r\\n\");\n    trim_split!(s3, \"\\r\\n\");\n}\n"
  },
  {
    "path": "tests/ui/str_split.stderr",
    "content": "error: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:58:13\n   |\nLL |     let _ = s1.trim().split('\\n');\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::str-split-at-newline` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::str_split_at_newline)]`\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s1.trim().split('\\n');\nLL +     let _ = s1.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:61:13\n   |\nLL |     let _ = s1.trim().split(\"\\n\");\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s1.trim().split(\"\\n\");\nLL +     let _ = s1.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:63:13\n   |\nLL |     let _ = s1.trim().split(\"\\r\\n\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s1.trim().split(\"\\r\\n\");\nLL +     let _ = s1.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:67:13\n   |\nLL |     let _ = s2.trim().split('\\n');\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s2.trim().split('\\n');\nLL +     let _ = s2.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:70:13\n   |\nLL |     let _ = s2.trim().split(\"\\n\");\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s2.trim().split(\"\\n\");\nLL +     let _ = s2.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:72:13\n   |\nLL |     let _ = s2.trim().split(\"\\r\\n\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s2.trim().split(\"\\r\\n\");\nLL +     let _ = s2.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:77:13\n   |\nLL |     let _ = s3.trim().split('\\n');\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s3.trim().split('\\n');\nLL +     let _ = s3.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:80:13\n   |\nLL |     let _ = s3.trim().split(\"\\n\");\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s3.trim().split(\"\\n\");\nLL +     let _ = s3.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:82:13\n   |\nLL |     let _ = s3.trim().split(\"\\r\\n\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = s3.trim().split(\"\\r\\n\");\nLL +     let _ = s3.lines();\n   |\n\nerror: using `str.trim().split()` with hard-coded newlines\n  --> tests/ui/str_split.rs:86:13\n   |\nLL |     let _ = make_str!(s1).trim().split('\\n');\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `str.lines()` instead\n   |\nLL -     let _ = make_str!(s1).trim().split('\\n');\nLL +     let _ = make_str!(s1).lines();\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/str_to_string.fixed",
    "content": "#![warn(clippy::str_to_string)]\n\nfn main() {\n    let hello: String = \"hello world\".to_owned();\n    //~^ str_to_string\n\n    let msg: &str = &hello[..];\n    msg.to_owned();\n    //~^ str_to_string\n}\n\nfn issue16271(key: &[u8]) {\n    macro_rules! t {\n        ($e:expr) => {\n            match $e {\n                Ok(e) => e,\n                Err(e) => panic!(\"{} failed with {}\", stringify!($e), e),\n            }\n        };\n    }\n\n    let _value: String = t!(str::from_utf8(key)).to_owned();\n    //~^ str_to_string\n}\n\nstruct GenericWrapper<T>(T);\n\nimpl<T> GenericWrapper<T> {\n    fn mapper<U, F: FnOnce(T) -> U>(self, f: F) -> U {\n        f(self.0)\n    }\n}\n\nfn issue16511(x: Option<&str>) {\n    let _: Option<String> = x.map(str::to_owned);\n    //~^ str_to_string\n\n    let _: Option<String> = x.map(str::to_owned);\n    //~^ str_to_string\n\n    // This should not trigger the lint because ToOwned::to_owned would produce &str, not String.\n    let _: Vec<String> = [\"a\", \"b\"].iter().map(ToString::to_string).collect();\n\n    fn mapper<F: Fn(&str) -> String>(f: F) -> String {\n        f(\"hello\")\n    }\n    let _: String = mapper(str::to_owned);\n    //~^ str_to_string\n\n    let w: GenericWrapper<&str> = GenericWrapper(\"hello\");\n    let _: String = w.mapper(str::to_owned);\n    //~^ str_to_string\n}\n\n// No lint: non-str types should not trigger str_to_string. See #16569\nfn no_lint_non_str() {\n    let _: Vec<String> = [1, 2].iter().map(i32::to_string).collect();\n}\n"
  },
  {
    "path": "tests/ui/str_to_string.rs",
    "content": "#![warn(clippy::str_to_string)]\n\nfn main() {\n    let hello: String = \"hello world\".to_string();\n    //~^ str_to_string\n\n    let msg: &str = &hello[..];\n    msg.to_string();\n    //~^ str_to_string\n}\n\nfn issue16271(key: &[u8]) {\n    macro_rules! t {\n        ($e:expr) => {\n            match $e {\n                Ok(e) => e,\n                Err(e) => panic!(\"{} failed with {}\", stringify!($e), e),\n            }\n        };\n    }\n\n    let _value: String = t!(str::from_utf8(key)).to_string();\n    //~^ str_to_string\n}\n\nstruct GenericWrapper<T>(T);\n\nimpl<T> GenericWrapper<T> {\n    fn mapper<U, F: FnOnce(T) -> U>(self, f: F) -> U {\n        f(self.0)\n    }\n}\n\nfn issue16511(x: Option<&str>) {\n    let _: Option<String> = x.map(ToString::to_string);\n    //~^ str_to_string\n\n    let _: Option<String> = x.map(str::to_string);\n    //~^ str_to_string\n\n    // This should not trigger the lint because ToOwned::to_owned would produce &str, not String.\n    let _: Vec<String> = [\"a\", \"b\"].iter().map(ToString::to_string).collect();\n\n    fn mapper<F: Fn(&str) -> String>(f: F) -> String {\n        f(\"hello\")\n    }\n    let _: String = mapper(ToString::to_string);\n    //~^ str_to_string\n\n    let w: GenericWrapper<&str> = GenericWrapper(\"hello\");\n    let _: String = w.mapper(ToString::to_string);\n    //~^ str_to_string\n}\n\n// No lint: non-str types should not trigger str_to_string. See #16569\nfn no_lint_non_str() {\n    let _: Vec<String> = [1, 2].iter().map(i32::to_string).collect();\n}\n"
  },
  {
    "path": "tests/ui/str_to_string.stderr",
    "content": "error: `to_string()` called on a `&str`\n  --> tests/ui/str_to_string.rs:4:25\n   |\nLL |     let hello: String = \"hello world\".to_string();\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `\"hello world\".to_owned()`\n   |\n   = note: `-D clippy::str-to-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::str_to_string)]`\n\nerror: `to_string()` called on a `&str`\n  --> tests/ui/str_to_string.rs:8:5\n   |\nLL |     msg.to_string();\n   |     ^^^^^^^^^^^^^^^ help: try: `msg.to_owned()`\n\nerror: `to_string()` called on a `&str`\n  --> tests/ui/str_to_string.rs:22:26\n   |\nLL |     let _value: String = t!(str::from_utf8(key)).to_string();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t!(str::from_utf8(key)).to_owned()`\n\nerror: `ToString::to_string` used as `&str` to `String` converter\n  --> tests/ui/str_to_string.rs:35:35\n   |\nLL |     let _: Option<String> = x.map(ToString::to_string);\n   |                                   ^^^^^^^^^^^^^^^^^^^ help: try: `str::to_owned`\n\nerror: `ToString::to_string` used as `&str` to `String` converter\n  --> tests/ui/str_to_string.rs:38:35\n   |\nLL |     let _: Option<String> = x.map(str::to_string);\n   |                                   ^^^^^^^^^^^^^^ help: try: `str::to_owned`\n\nerror: `ToString::to_string` used as `&str` to `String` converter\n  --> tests/ui/str_to_string.rs:47:28\n   |\nLL |     let _: String = mapper(ToString::to_string);\n   |                            ^^^^^^^^^^^^^^^^^^^ help: try: `str::to_owned`\n\nerror: `ToString::to_string` used as `&str` to `String` converter\n  --> tests/ui/str_to_string.rs:51:30\n   |\nLL |     let _: String = w.mapper(ToString::to_string);\n   |                              ^^^^^^^^^^^^^^^^^^^ help: try: `str::to_owned`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/string_add.rs",
    "content": "//@aux-build:proc_macros.rs\n\nextern crate proc_macros;\nuse proc_macros::external;\n\n#[warn(clippy::string_add)]\n#[allow(clippy::assign_op_pattern, clippy::string_add_assign, unused)]\nfn main() {\n    // ignores assignment distinction\n    let mut x = String::new();\n\n    for _ in 1..3 {\n        x = x + \".\";\n        //~^ string_add\n    }\n\n    let y = String::new();\n    let z = y + \"...\";\n    //~^ string_add\n\n    assert_eq!(&x, &z);\n\n    let mut x = 1;\n    x = x + 1;\n    assert_eq!(2, x);\n\n    external!({\n        let y = \"\".to_owned();\n        let z = y + \"...\";\n    });\n}\n"
  },
  {
    "path": "tests/ui/string_add.stderr",
    "content": "error: you added something to a string. Consider using `String::push_str()` instead\n  --> tests/ui/string_add.rs:13:13\n   |\nLL |         x = x + \".\";\n   |             ^^^^^^^\n   |\n   = note: `-D clippy::string-add` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::string_add)]`\n\nerror: you added something to a string. Consider using `String::push_str()` instead\n  --> tests/ui/string_add.rs:18:13\n   |\nLL |     let z = y + \"...\";\n   |             ^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/string_add_assign.fixed",
    "content": "#[allow(clippy::string_add, unused)]\n#[warn(clippy::string_add_assign)]\nfn main() {\n    // ignores assignment distinction\n    let mut x = String::new();\n\n    for _ in 1..3 {\n        x += \".\";\n        //~^ string_add_assign\n        //~| assign_op_pattern\n    }\n\n    let y = String::new();\n    let z = y + \"...\";\n\n    assert_eq!(&x, &z);\n\n    let mut x = 1;\n    x += 1;\n    //~^ assign_op_pattern\n    assert_eq!(2, x);\n}\n"
  },
  {
    "path": "tests/ui/string_add_assign.rs",
    "content": "#[allow(clippy::string_add, unused)]\n#[warn(clippy::string_add_assign)]\nfn main() {\n    // ignores assignment distinction\n    let mut x = String::new();\n\n    for _ in 1..3 {\n        x = x + \".\";\n        //~^ string_add_assign\n        //~| assign_op_pattern\n    }\n\n    let y = String::new();\n    let z = y + \"...\";\n\n    assert_eq!(&x, &z);\n\n    let mut x = 1;\n    x = x + 1;\n    //~^ assign_op_pattern\n    assert_eq!(2, x);\n}\n"
  },
  {
    "path": "tests/ui/string_add_assign.stderr",
    "content": "error: you assigned the result of adding something to this string. Consider using `String::push_str()` instead\n  --> tests/ui/string_add_assign.rs:8:9\n   |\nLL |         x = x + \".\";\n   |         ^^^^^^^^^^^\n   |\n   = note: `-D clippy::string-add-assign` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::string_add_assign)]`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/string_add_assign.rs:8:9\n   |\nLL |         x = x + \".\";\n   |         ^^^^^^^^^^^ help: replace it with: `x += \".\"`\n   |\n   = note: `-D clippy::assign-op-pattern` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]`\n\nerror: manual implementation of an assign operation\n  --> tests/ui/string_add_assign.rs:19:5\n   |\nLL |     x = x + 1;\n   |     ^^^^^^^^^ help: replace it with: `x += 1`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/string_extend.fixed",
    "content": "#[derive(Copy, Clone)]\nstruct HasChars;\n\nimpl HasChars {\n    fn chars(self) -> std::str::Chars<'static> {\n        \"HasChars\".chars()\n    }\n}\n\nfn main() {\n    let abc = \"abc\";\n    let def = String::from(\"def\");\n    let mut s = String::new();\n\n    s.push_str(abc);\n    s.push_str(abc);\n    //~^ string_extend_chars\n\n    s.push_str(\"abc\");\n    s.push_str(\"abc\");\n    //~^ string_extend_chars\n\n    s.push_str(&def);\n    s.push_str(&def);\n    //~^ string_extend_chars\n\n    s.extend(abc.chars().skip(1));\n    s.extend(\"abc\".chars().skip(1));\n    s.extend(['a', 'b', 'c'].iter());\n\n    let f = HasChars;\n    s.extend(f.chars());\n\n    // issue #9735\n    s.push_str(&abc[0..2]);\n    //~^ string_extend_chars\n}\n"
  },
  {
    "path": "tests/ui/string_extend.rs",
    "content": "#[derive(Copy, Clone)]\nstruct HasChars;\n\nimpl HasChars {\n    fn chars(self) -> std::str::Chars<'static> {\n        \"HasChars\".chars()\n    }\n}\n\nfn main() {\n    let abc = \"abc\";\n    let def = String::from(\"def\");\n    let mut s = String::new();\n\n    s.push_str(abc);\n    s.extend(abc.chars());\n    //~^ string_extend_chars\n\n    s.push_str(\"abc\");\n    s.extend(\"abc\".chars());\n    //~^ string_extend_chars\n\n    s.push_str(&def);\n    s.extend(def.chars());\n    //~^ string_extend_chars\n\n    s.extend(abc.chars().skip(1));\n    s.extend(\"abc\".chars().skip(1));\n    s.extend(['a', 'b', 'c'].iter());\n\n    let f = HasChars;\n    s.extend(f.chars());\n\n    // issue #9735\n    s.extend(abc[0..2].chars());\n    //~^ string_extend_chars\n}\n"
  },
  {
    "path": "tests/ui/string_extend.stderr",
    "content": "error: calling `.extend(_.chars())`\n  --> tests/ui/string_extend.rs:16:5\n   |\nLL |     s.extend(abc.chars());\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(abc)`\n   |\n   = note: `-D clippy::string-extend-chars` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::string_extend_chars)]`\n\nerror: calling `.extend(_.chars())`\n  --> tests/ui/string_extend.rs:20:5\n   |\nLL |     s.extend(\"abc\".chars());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(\"abc\")`\n\nerror: calling `.extend(_.chars())`\n  --> tests/ui/string_extend.rs:24:5\n   |\nLL |     s.extend(def.chars());\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(&def)`\n\nerror: calling `.extend(_.chars())`\n  --> tests/ui/string_extend.rs:35:5\n   |\nLL |     s.extend(abc[0..2].chars());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.push_str(&abc[0..2])`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/string_from_utf8_as_bytes.fixed",
    "content": "#![warn(clippy::string_from_utf8_as_bytes)]\n\nmacro_rules! test_range {\n    ($start:expr, $end:expr) => {\n        $start..$end\n    };\n}\n\nfn main() {\n    let _ = Some(&\"Hello World!\"[6..11]);\n    //~^ string_from_utf8_as_bytes\n\n    let s = \"Hello World!\";\n    let _ = Some(&s[test_range!(6, 11)]);\n    //~^ string_from_utf8_as_bytes\n}\n"
  },
  {
    "path": "tests/ui/string_from_utf8_as_bytes.rs",
    "content": "#![warn(clippy::string_from_utf8_as_bytes)]\n\nmacro_rules! test_range {\n    ($start:expr, $end:expr) => {\n        $start..$end\n    };\n}\n\nfn main() {\n    let _ = std::str::from_utf8(&\"Hello World!\".as_bytes()[6..11]);\n    //~^ string_from_utf8_as_bytes\n\n    let s = \"Hello World!\";\n    let _ = std::str::from_utf8(&s.as_bytes()[test_range!(6, 11)]);\n    //~^ string_from_utf8_as_bytes\n}\n"
  },
  {
    "path": "tests/ui/string_from_utf8_as_bytes.stderr",
    "content": "error: calling a slice of `as_bytes()` with `from_utf8` should be not necessary\n  --> tests/ui/string_from_utf8_as_bytes.rs:10:13\n   |\nLL |     let _ = std::str::from_utf8(&\"Hello World!\".as_bytes()[6..11]);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&\"Hello World!\"[6..11])`\n   |\n   = note: `-D clippy::string-from-utf8-as-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::string_from_utf8_as_bytes)]`\n\nerror: calling a slice of `as_bytes()` with `from_utf8` should be not necessary\n  --> tests/ui/string_from_utf8_as_bytes.rs:14:13\n   |\nLL |     let _ = std::str::from_utf8(&s.as_bytes()[test_range!(6, 11)]);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(&s[test_range!(6, 11)])`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/string_lit_as_bytes.fixed",
    "content": "//@aux-build:macro_rules.rs\n\n#![allow(clippy::needless_raw_string_hashes, dead_code, unused_variables)]\n#![warn(clippy::string_lit_as_bytes)]\n\n#[macro_use]\nextern crate macro_rules;\n\nmacro_rules! b {\n    ($b:literal) => {\n        const B: &[u8] = b\"warning\";\n        //~^ string_lit_as_bytes\n    };\n}\n\nfn str_lit_as_bytes() {\n    let bs = b\"hello there\";\n    //~^ string_lit_as_bytes\n\n    let bs = br###\"raw string with 3# plus \" \"\"###;\n    //~^ string_lit_as_bytes\n\n    let bs = b\"lit to string\".to_vec();\n    //~^ string_lit_as_bytes\n    let bs = b\"lit to owned\".to_vec();\n    //~^ string_lit_as_bytes\n\n    b!(\"warning\");\n\n    string_lit_as_bytes!(\"no warning\");\n\n    // no warning, because these cannot be written as byte string literals:\n    let ubs = \"☃\".as_bytes();\n    let ubs = \"hello there! this is a very long string\".as_bytes();\n\n    let ubs = \"☃\".to_string().into_bytes();\n    let ubs = \"this is also too long and shouldn't be fixed\".to_string().into_bytes();\n\n    let strify = stringify!(foobar).as_bytes();\n\n    let current_version = env!(\"CARGO_PKG_VERSION\").as_bytes();\n\n    let includestr = include_bytes!(\"string_lit_as_bytes.rs\");\n    //~^ string_lit_as_bytes\n\n    let _ = b\"string with newline\\t\\n\";\n    //~^ string_lit_as_bytes\n\n    let _ = match \"x\".as_bytes() {\n        b\"xx\" => 0,\n        [b'x', ..] => 1,\n        _ => 2,\n    };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/string_lit_as_bytes.rs",
    "content": "//@aux-build:macro_rules.rs\n\n#![allow(clippy::needless_raw_string_hashes, dead_code, unused_variables)]\n#![warn(clippy::string_lit_as_bytes)]\n\n#[macro_use]\nextern crate macro_rules;\n\nmacro_rules! b {\n    ($b:literal) => {\n        const B: &[u8] = $b.as_bytes();\n        //~^ string_lit_as_bytes\n    };\n}\n\nfn str_lit_as_bytes() {\n    let bs = \"hello there\".as_bytes();\n    //~^ string_lit_as_bytes\n\n    let bs = r###\"raw string with 3# plus \" \"\"###.as_bytes();\n    //~^ string_lit_as_bytes\n\n    let bs = \"lit to string\".to_string().into_bytes();\n    //~^ string_lit_as_bytes\n    let bs = \"lit to owned\".to_owned().into_bytes();\n    //~^ string_lit_as_bytes\n\n    b!(\"warning\");\n\n    string_lit_as_bytes!(\"no warning\");\n\n    // no warning, because these cannot be written as byte string literals:\n    let ubs = \"☃\".as_bytes();\n    let ubs = \"hello there! this is a very long string\".as_bytes();\n\n    let ubs = \"☃\".to_string().into_bytes();\n    let ubs = \"this is also too long and shouldn't be fixed\".to_string().into_bytes();\n\n    let strify = stringify!(foobar).as_bytes();\n\n    let current_version = env!(\"CARGO_PKG_VERSION\").as_bytes();\n\n    let includestr = include_str!(\"string_lit_as_bytes.rs\").as_bytes();\n    //~^ string_lit_as_bytes\n\n    let _ = \"string with newline\\t\\n\".as_bytes();\n    //~^ string_lit_as_bytes\n\n    let _ = match \"x\".as_bytes() {\n        b\"xx\" => 0,\n        [b'x', ..] => 1,\n        _ => 2,\n    };\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/string_lit_as_bytes.stderr",
    "content": "error: calling `as_bytes()` on a string literal\n  --> tests/ui/string_lit_as_bytes.rs:17:14\n   |\nLL |     let bs = \"hello there\".as_bytes();\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b\"hello there\"`\n   |\n   = note: `-D clippy::string-lit-as-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::string_lit_as_bytes)]`\n\nerror: calling `as_bytes()` on a string literal\n  --> tests/ui/string_lit_as_bytes.rs:20:14\n   |\nLL |     let bs = r###\"raw string with 3# plus \" \"\"###.as_bytes();\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `br###\"raw string with 3# plus \" \"\"###`\n\nerror: calling `into_bytes()` on a string literal\n  --> tests/ui/string_lit_as_bytes.rs:23:14\n   |\nLL |     let bs = \"lit to string\".to_string().into_bytes();\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b\"lit to string\".to_vec()`\n\nerror: calling `into_bytes()` on a string literal\n  --> tests/ui/string_lit_as_bytes.rs:25:14\n   |\nLL |     let bs = \"lit to owned\".to_owned().into_bytes();\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b\"lit to owned\".to_vec()`\n\nerror: calling `as_bytes()` on a string literal\n  --> tests/ui/string_lit_as_bytes.rs:11:26\n   |\nLL |         const B: &[u8] = $b.as_bytes();\n   |                          ^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b\"warning\"`\n...\nLL |     b!(\"warning\");\n   |     ------------- in this macro invocation\n   |\n   = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: calling `as_bytes()` on `include_str!(..)`\n  --> tests/ui/string_lit_as_bytes.rs:43:22\n   |\nLL |     let includestr = include_str!(\"string_lit_as_bytes.rs\").as_bytes();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `include_bytes!(..)` instead: `include_bytes!(\"string_lit_as_bytes.rs\")`\n\nerror: calling `as_bytes()` on a string literal\n  --> tests/ui/string_lit_as_bytes.rs:46:13\n   |\nLL |     let _ = \"string with newline\\t\\n\".as_bytes();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a byte string literal instead: `b\"string with newline\\t\\n\"`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/string_lit_chars_any.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::eq_op, clippy::needless_raw_string_hashes, clippy::no_effect, unused)]\n#![warn(clippy::string_lit_chars_any)]\n\n#[macro_use]\nextern crate proc_macros;\n\nstruct NotStringLit;\n\nimpl NotStringLit {\n    fn chars(&self) -> impl Iterator<Item = char> {\n        \"c\".chars()\n    }\n}\n\nfn main() {\n    let c = 'c';\n    matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n    //~^ string_lit_chars_any\n    matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n    //~^ string_lit_chars_any\n    matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n    //~^ string_lit_chars_any\n    matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n    //~^ string_lit_chars_any\n    #[rustfmt::skip]\n    matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n    //~^ string_lit_chars_any\n    // Do not lint\n    NotStringLit.chars().any(|x| x == c);\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| {\n        let c = 'c';\n        x == c\n    });\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| {\n        1;\n        x == c\n    });\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == x);\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|_x| c == c);\n    matches!(\n        c,\n        '\\\\' | '.' | '+' | '*' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'\n    );\n    external! {\n        let c = 'c';\n        \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\n    }\n    with_span! {\n        span\n        let c = 'c';\n        \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\n    }\n}\n"
  },
  {
    "path": "tests/ui/string_lit_chars_any.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::eq_op, clippy::needless_raw_string_hashes, clippy::no_effect, unused)]\n#![warn(clippy::string_lit_chars_any)]\n\n#[macro_use]\nextern crate proc_macros;\n\nstruct NotStringLit;\n\nimpl NotStringLit {\n    fn chars(&self) -> impl Iterator<Item = char> {\n        \"c\".chars()\n    }\n}\n\nfn main() {\n    let c = 'c';\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\n    //~^ string_lit_chars_any\n    r#\"\\.+*?()|[]{}^$#&-~\"#.chars().any(|x| x == c);\n    //~^ string_lit_chars_any\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| c == x);\n    //~^ string_lit_chars_any\n    r#\"\\.+*?()|[]{}^$#&-~\"#.chars().any(|x| c == x);\n    //~^ string_lit_chars_any\n    #[rustfmt::skip]\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| { x == c });\n    //~^ string_lit_chars_any\n    // Do not lint\n    NotStringLit.chars().any(|x| x == c);\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| {\n        let c = 'c';\n        x == c\n    });\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| {\n        1;\n        x == c\n    });\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == x);\n    \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|_x| c == c);\n    matches!(\n        c,\n        '\\\\' | '.' | '+' | '*' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~'\n    );\n    external! {\n        let c = 'c';\n        \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\n    }\n    with_span! {\n        span\n        let c = 'c';\n        \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\n    }\n}\n"
  },
  {
    "path": "tests/ui/string_lit_chars_any.stderr",
    "content": "error: usage of `.chars().any(...)` to check if a char matches any from a string literal\n  --> tests/ui/string_lit_chars_any.rs:18:5\n   |\nLL |     \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::string-lit-chars-any` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::string_lit_chars_any)]`\nhelp: use `matches!(...)` instead\n   |\nLL -     \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| x == c);\nLL +     matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n   |\n\nerror: usage of `.chars().any(...)` to check if a char matches any from a string literal\n  --> tests/ui/string_lit_chars_any.rs:20:5\n   |\nLL |     r#\"\\.+*?()|[]{}^$#&-~\"#.chars().any(|x| x == c);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `matches!(...)` instead\n   |\nLL -     r#\"\\.+*?()|[]{}^$#&-~\"#.chars().any(|x| x == c);\nLL +     matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n   |\n\nerror: usage of `.chars().any(...)` to check if a char matches any from a string literal\n  --> tests/ui/string_lit_chars_any.rs:22:5\n   |\nLL |     \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| c == x);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `matches!(...)` instead\n   |\nLL -     \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| c == x);\nLL +     matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n   |\n\nerror: usage of `.chars().any(...)` to check if a char matches any from a string literal\n  --> tests/ui/string_lit_chars_any.rs:24:5\n   |\nLL |     r#\"\\.+*?()|[]{}^$#&-~\"#.chars().any(|x| c == x);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `matches!(...)` instead\n   |\nLL -     r#\"\\.+*?()|[]{}^$#&-~\"#.chars().any(|x| c == x);\nLL +     matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n   |\n\nerror: usage of `.chars().any(...)` to check if a char matches any from a string literal\n  --> tests/ui/string_lit_chars_any.rs:27:5\n   |\nLL |     \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| { x == c });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `matches!(...)` instead\n   |\nLL -     \"\\\\.+*?()|[]{}^$#&-~\".chars().any(|x| { x == c });\nLL +     matches!(c, '\\\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/string_slice.rs",
    "content": "#![warn(clippy::string_slice)]\n#![allow(clippy::no_effect)]\n\nuse std::borrow::Cow;\n\nfn main() {\n    &\"Ölkanne\"[1..];\n    //~^ string_slice\n\n    let m = \"Mötörhead\";\n    &m[2..5];\n    //~^ string_slice\n\n    let s = String::from(m);\n    &s[0..2];\n    //~^ string_slice\n\n    let a = Cow::Borrowed(\"foo\");\n    &a[0..3];\n    //~^ string_slice\n}\n"
  },
  {
    "path": "tests/ui/string_slice.stderr",
    "content": "error: indexing into a string may panic if the index is within a UTF-8 character\n  --> tests/ui/string_slice.rs:7:6\n   |\nLL |     &\"Ölkanne\"[1..];\n   |      ^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::string-slice` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::string_slice)]`\n\nerror: indexing into a string may panic if the index is within a UTF-8 character\n  --> tests/ui/string_slice.rs:11:6\n   |\nLL |     &m[2..5];\n   |      ^^^^^^^\n\nerror: indexing into a string may panic if the index is within a UTF-8 character\n  --> tests/ui/string_slice.rs:15:6\n   |\nLL |     &s[0..2];\n   |      ^^^^^^^\n\nerror: indexing into a string may panic if the index is within a UTF-8 character\n  --> tests/ui/string_slice.rs:19:6\n   |\nLL |     &a[0..3];\n   |      ^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/strlen_on_c_strings.fixed",
    "content": "#![warn(clippy::strlen_on_c_strings)]\n#![allow(clippy::manual_c_str_literals, clippy::boxed_local)]\n\nuse libc::strlen;\nuse std::ffi::{CStr, CString};\n\nfn main() {\n    // CString\n    let cstring = CString::new(\"foo\").expect(\"CString::new failed\");\n    let _ = cstring.count_bytes();\n    //~^ ERROR: using `libc::strlen` on a `CString` value\n\n    // CStr\n    let cstr = CStr::from_bytes_with_nul(b\"foo\\0\").expect(\"CStr::from_bytes_with_nul failed\");\n    let _ = cstr.count_bytes();\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n\n    let _ = cstr.count_bytes();\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n\n    let pcstr: *const &CStr = &cstr;\n    let _ = unsafe { (*pcstr).count_bytes() };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n\n    unsafe fn unsafe_identity<T>(x: T) -> T {\n        x\n    }\n    let _ = unsafe { unsafe_identity(cstr).count_bytes() };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n    let _ = unsafe { unsafe_identity(cstr) }.count_bytes();\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n\n    let f: unsafe fn(_) -> _ = unsafe_identity;\n    let _ = unsafe { f(cstr).count_bytes() };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n}\n\n// make sure we lint types that _adjust_ to `CStr`\nfn adjusted(box_cstring: Box<CString>, box_cstr: Box<CStr>, arc_cstring: std::sync::Arc<CStr>) {\n    let _ = box_cstring.count_bytes();\n    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`\n    let _ = box_cstr.count_bytes();\n    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`\n    let _ = arc_cstring.count_bytes();\n    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`\n}\n\n#[clippy::msrv = \"1.78\"]\nfn msrv_1_78() {\n    let cstr = CStr::from_bytes_with_nul(b\"foo\\0\").expect(\"CStr::from_bytes_with_nul failed\");\n    let _ = cstr.to_bytes().len();\n    //~^ strlen_on_c_strings\n\n    let cstring = CString::new(\"foo\").expect(\"CString::new failed\");\n    let _ = cstring.to_bytes().len();\n    //~^ strlen_on_c_strings\n}\n\n#[clippy::msrv = \"1.79\"]\nfn msrv_1_79() {\n    let cstr = CStr::from_bytes_with_nul(b\"foo\\0\").expect(\"CStr::from_bytes_with_nul failed\");\n    let _ = cstr.count_bytes();\n    //~^ strlen_on_c_strings\n\n    let cstring = CString::new(\"foo\").expect(\"CString::new failed\");\n    let _ = cstring.count_bytes();\n    //~^ strlen_on_c_strings\n}\n"
  },
  {
    "path": "tests/ui/strlen_on_c_strings.rs",
    "content": "#![warn(clippy::strlen_on_c_strings)]\n#![allow(clippy::manual_c_str_literals, clippy::boxed_local)]\n\nuse libc::strlen;\nuse std::ffi::{CStr, CString};\n\nfn main() {\n    // CString\n    let cstring = CString::new(\"foo\").expect(\"CString::new failed\");\n    let _ = unsafe { libc::strlen(cstring.as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a `CString` value\n\n    // CStr\n    let cstr = CStr::from_bytes_with_nul(b\"foo\\0\").expect(\"CStr::from_bytes_with_nul failed\");\n    let _ = unsafe { libc::strlen(cstr.as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n\n    let _ = unsafe { strlen(cstr.as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n\n    let pcstr: *const &CStr = &cstr;\n    let _ = unsafe { strlen((*pcstr).as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n\n    unsafe fn unsafe_identity<T>(x: T) -> T {\n        x\n    }\n    let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n    let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n\n    let f: unsafe fn(_) -> _ = unsafe_identity;\n    let _ = unsafe { strlen(f(cstr).as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a `CStr` value\n}\n\n// make sure we lint types that _adjust_ to `CStr`\nfn adjusted(box_cstring: Box<CString>, box_cstr: Box<CStr>, arc_cstring: std::sync::Arc<CStr>) {\n    let _ = unsafe { libc::strlen(box_cstring.as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`\n    let _ = unsafe { libc::strlen(box_cstr.as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`\n    let _ = unsafe { libc::strlen(arc_cstring.as_ptr()) };\n    //~^ ERROR: using `libc::strlen` on a type that dereferences to `CStr`\n}\n\n#[clippy::msrv = \"1.78\"]\nfn msrv_1_78() {\n    let cstr = CStr::from_bytes_with_nul(b\"foo\\0\").expect(\"CStr::from_bytes_with_nul failed\");\n    let _ = unsafe { libc::strlen(cstr.as_ptr()) };\n    //~^ strlen_on_c_strings\n\n    let cstring = CString::new(\"foo\").expect(\"CString::new failed\");\n    let _ = unsafe { libc::strlen(cstring.as_ptr()) };\n    //~^ strlen_on_c_strings\n}\n\n#[clippy::msrv = \"1.79\"]\nfn msrv_1_79() {\n    let cstr = CStr::from_bytes_with_nul(b\"foo\\0\").expect(\"CStr::from_bytes_with_nul failed\");\n    let _ = unsafe { libc::strlen(cstr.as_ptr()) };\n    //~^ strlen_on_c_strings\n\n    let cstring = CString::new(\"foo\").expect(\"CString::new failed\");\n    let _ = unsafe { libc::strlen(cstring.as_ptr()) };\n    //~^ strlen_on_c_strings\n}\n"
  },
  {
    "path": "tests/ui/strlen_on_c_strings.stderr",
    "content": "error: using `libc::strlen` on a `CString` value\n  --> tests/ui/strlen_on_c_strings.rs:10:13\n   |\nLL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.count_bytes()`\n   |\n   = note: `-D clippy::strlen-on-c-strings` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::strlen_on_c_strings)]`\n\nerror: using `libc::strlen` on a `CStr` value\n  --> tests/ui/strlen_on_c_strings.rs:15:13\n   |\nLL |     let _ = unsafe { libc::strlen(cstr.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.count_bytes()`\n\nerror: using `libc::strlen` on a `CStr` value\n  --> tests/ui/strlen_on_c_strings.rs:18:13\n   |\nLL |     let _ = unsafe { strlen(cstr.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.count_bytes()`\n\nerror: using `libc::strlen` on a `CStr` value\n  --> tests/ui/strlen_on_c_strings.rs:22:22\n   |\nLL |     let _ = unsafe { strlen((*pcstr).as_ptr()) };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `(*pcstr).count_bytes()`\n\nerror: using `libc::strlen` on a `CStr` value\n  --> tests/ui/strlen_on_c_strings.rs:28:22\n   |\nLL |     let _ = unsafe { strlen(unsafe_identity(cstr).as_ptr()) };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe_identity(cstr).count_bytes()`\n\nerror: using `libc::strlen` on a `CStr` value\n  --> tests/ui/strlen_on_c_strings.rs:30:13\n   |\nLL |     let _ = unsafe { strlen(unsafe { unsafe_identity(cstr) }.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `unsafe { unsafe_identity(cstr) }.count_bytes()`\n\nerror: using `libc::strlen` on a `CStr` value\n  --> tests/ui/strlen_on_c_strings.rs:34:22\n   |\nLL |     let _ = unsafe { strlen(f(cstr).as_ptr()) };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `f(cstr).count_bytes()`\n\nerror: using `libc::strlen` on a type that dereferences to `CStr`\n  --> tests/ui/strlen_on_c_strings.rs:40:13\n   |\nLL |     let _ = unsafe { libc::strlen(box_cstring.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `box_cstring.count_bytes()`\n\nerror: using `libc::strlen` on a type that dereferences to `CStr`\n  --> tests/ui/strlen_on_c_strings.rs:42:13\n   |\nLL |     let _ = unsafe { libc::strlen(box_cstr.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `box_cstr.count_bytes()`\n\nerror: using `libc::strlen` on a type that dereferences to `CStr`\n  --> tests/ui/strlen_on_c_strings.rs:44:13\n   |\nLL |     let _ = unsafe { libc::strlen(arc_cstring.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `arc_cstring.count_bytes()`\n\nerror: using `libc::strlen` on a `CStr` value\n  --> tests/ui/strlen_on_c_strings.rs:51:13\n   |\nLL |     let _ = unsafe { libc::strlen(cstr.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.to_bytes().len()`\n\nerror: using `libc::strlen` on a `CString` value\n  --> tests/ui/strlen_on_c_strings.rs:55:13\n   |\nLL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.to_bytes().len()`\n\nerror: using `libc::strlen` on a `CStr` value\n  --> tests/ui/strlen_on_c_strings.rs:62:13\n   |\nLL |     let _ = unsafe { libc::strlen(cstr.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstr.count_bytes()`\n\nerror: using `libc::strlen` on a `CString` value\n  --> tests/ui/strlen_on_c_strings.rs:66:13\n   |\nLL |     let _ = unsafe { libc::strlen(cstring.as_ptr()) };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `cstring.count_bytes()`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/struct_excessive_bools.rs",
    "content": "#![warn(clippy::struct_excessive_bools)]\n\nmacro_rules! foo {\n    () => {\n        struct MacroFoo {\n            a: bool,\n            b: bool,\n            c: bool,\n            d: bool,\n        }\n    };\n}\n\nfoo!();\n\nstruct Foo {\n    a: bool,\n    b: bool,\n    c: bool,\n}\n\nstruct BadFoo {\n    //~^ struct_excessive_bools\n    a: bool,\n    b: bool,\n    c: bool,\n    d: bool,\n}\n\n#[repr(C)]\nstruct Bar {\n    a: bool,\n    b: bool,\n    c: bool,\n    d: bool,\n}\n\nfn main() {\n    struct FooFoo {\n        //~^ struct_excessive_bools\n        a: bool,\n        b: bool,\n        c: bool,\n        d: bool,\n    }\n}\n"
  },
  {
    "path": "tests/ui/struct_excessive_bools.stderr",
    "content": "error: more than 3 bools in a struct\n  --> tests/ui/struct_excessive_bools.rs:22:1\n   |\nLL | / struct BadFoo {\nLL | |\nLL | |     a: bool,\nLL | |     b: bool,\nLL | |     c: bool,\nLL | |     d: bool,\nLL | | }\n   | |_^\n   |\n   = help: consider using a state machine or refactoring bools into two-variant enums\n   = note: `-D clippy::struct-excessive-bools` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::struct_excessive_bools)]`\n\nerror: more than 3 bools in a struct\n  --> tests/ui/struct_excessive_bools.rs:39:5\n   |\nLL | /     struct FooFoo {\nLL | |\nLL | |         a: bool,\nLL | |         b: bool,\nLL | |         c: bool,\nLL | |         d: bool,\nLL | |     }\n   | |_____^\n   |\n   = help: consider using a state machine or refactoring bools into two-variant enums\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/struct_fields.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::struct_field_names)]\n#![allow(unused)]\n\n#[macro_use]\nextern crate proc_macros;\n\nstruct Data1 {\n    field_data1: u8,\n    //~^ ERROR: field name ends with the struct's name\n    another: u8,\n    foo: u8,\n    bar: u8,\n}\n\nstruct Data2 {\n    another: u8,\n    foo: u8,\n    data2_field: u8,\n    //~^ ERROR: field name starts with the struct's name\n    bar: u8,\n}\n\nstruct StructData {\n    //~^ ERROR: all fields have the same postfix: `data`\n    movable_data: u8,\n    fixed_data: u8,\n    invisible_data: u8,\n}\n\nstruct DataStruct {\n    //~^ ERROR: all fields have the same prefix: `data`\n    data_movable: u8,\n    data_fixed: u8,\n    data_invisible: u8,\n}\n\nstruct DoublePrefix {\n    //~^ ERROR: all fields have the same prefix: `some_data`\n    some_data_a: bool,\n    some_data_b: i8,\n    some_data_c: bool,\n}\n\nstruct DoublePostfix {\n    //~^ ERROR: all fields have the same postfix: `some_data`\n    a_some_data: bool,\n    b_some_data: i8,\n    c_some_data: bool,\n}\n\n#[allow(non_snake_case)]\nstruct NotSnakeCase {\n    //~^ ERROR: all fields have the same postfix: `someData`\n    a_someData: bool,\n    b_someData: i8,\n    c_someData: bool,\n}\n#[allow(non_snake_case)]\nstruct NotSnakeCase2 {\n    //~^ ERROR: all fields have the same prefix: `someData`\n    someData_c: bool,\n    someData_b: i8,\n    someData_a_b: bool,\n}\n\n// no error, threshold is 3 fields by default\nstruct Fooo {\n    foo: u8,\n    bar: u8,\n}\n\nstruct NonCaps {\n    //~^ ERROR: all fields have the same prefix: `prefix`\n    prefix_的: u8,\n    prefix_tea: u8,\n    prefix_cake: u8,\n}\n\n// should not lint\n#[allow(clippy::struct_field_names)]\npub mod allowed {\n    pub struct PubAllowed {\n        some_this: u8,\n        some_that: u8,\n        some_other_what: u8,\n    }\n}\n\n// should not lint\nstruct SomeData {\n    foo: u8,\n    bar: bool,\n    path: u8,\n    answer: u8,\n}\n\n// should not lint\npub struct NetworkLayer {\n    layer1: Vec<u8>,\n    layer2: Vec<u8>,\n    layer3: Vec<u8>,\n    layer4: Vec<u8>,\n}\n\n//should not lint\nstruct North {\n    normal: u8,\n    no_left: u8,\n    no_right: u8,\n}\n\nmod issue8324_from_enum_variant_names {\n    // 8324: enum_variant_names warns even if removing the suffix would leave an empty string\n    struct Phase {\n        pre_lookup: u8,\n        lookup: u8,\n        post_lookup: u8,\n    }\n}\n\nmod issue9018_from_enum_variant_names {\n    struct DoLint {\n        //~^ ERROR: all fields have the same prefix: `_type`\n        _type_create: u8,\n        _type_read: u8,\n        _type_update: u8,\n        _type_destroy: u8,\n    }\n\n    struct DoLint2 {\n        //~^ ERROR: all fields have the same prefix: `__type`\n        __type_create: u8,\n        __type_read: u8,\n        __type_update: u8,\n        __type_destroy: u8,\n    }\n\n    struct DoLint3 {\n        //~^ ERROR: all fields have the same prefix: `___type`\n        ___type_create: u8,\n        ___type_read: u8,\n        ___type_update: u8,\n        ___type_destroy: u8,\n    }\n\n    struct DoLint4 {\n        //~^ ERROR: all fields have the same postfix: `_`\n        create_: u8,\n        read_: u8,\n        update_: u8,\n        destroy_: u8,\n    }\n\n    struct DoLint5 {\n        //~^ ERROR: all fields have the same postfix: `__`\n        create__: u8,\n        read__: u8,\n        update__: u8,\n        destroy__: u8,\n    }\n\n    struct DoLint6 {\n        //~^ ERROR: all fields have the same postfix: `___`\n        create___: u8,\n        read___: u8,\n        update___: u8,\n        destroy___: u8,\n    }\n\n    struct DoLintToo {\n        //~^ ERROR: all fields have the same postfix: `type`\n        _create_type: u8,\n        _update_type: u8,\n        _delete_type: u8,\n    }\n\n    struct DoNotLint {\n        _foo: u8,\n        _bar: u8,\n        _baz: u8,\n    }\n\n    struct DoNotLint2 {\n        __foo: u8,\n        __bar: u8,\n        __baz: u8,\n    }\n}\n\nmod allow_attributes_on_fields {\n    struct Struct {\n        #[allow(clippy::struct_field_names)]\n        struct_starts_with: u8,\n        #[allow(clippy::struct_field_names)]\n        ends_with_struct: u8,\n        foo: u8,\n    }\n}\n\n// food field should not lint\nstruct Foo {\n    food: i32,\n    a: i32,\n    b: i32,\n}\n\nstruct Proxy {\n    proxy: i32,\n    //~^ ERROR: field name starts with the struct's name\n    unrelated1: bool,\n    unrelated2: bool,\n}\n\n// should not lint\npub struct RegexT {\n    __buffer: i32,\n    __allocated: i32,\n    __used: i32,\n}\n\nmod macro_tests {\n    macro_rules! mk_struct {\n        () => {\n            struct MacroStruct {\n                //~^ ERROR: all fields have the same prefix: `some`\n                some_a: i32,\n                some_b: i32,\n                some_c: i32,\n            }\n        };\n    }\n    mk_struct!();\n\n    macro_rules! mk_struct2 {\n        () => {\n            struct Macrobaz {\n                macrobaz_a: i32,\n                //~^ ERROR: field name starts with the struct's name\n                some_b: i32,\n                some_c: i32,\n            }\n        };\n    }\n    mk_struct2!();\n\n    macro_rules! mk_struct_with_names {\n        ($struct_name:ident, $field:ident) => {\n            struct $struct_name {\n                $field: i32,\n                //~^ ERROR: field name starts with the struct's name\n                other_something: i32,\n                other_field: i32,\n            }\n        };\n    }\n    // expands to `struct Foo { foo: i32, ... }`\n    mk_struct_with_names!(Foo, foo);\n\n    // expands to a struct with all fields starting with `other` but should not\n    // be linted because some fields come from the macro definition and the other from the input\n    mk_struct_with_names!(Some, other_data);\n\n    // should not lint when names come from different places\n    macro_rules! mk_struct_with_field_name {\n        ($field_name:ident) => {\n            struct Baz {\n                one: i32,\n                two: i32,\n                $field_name: i32,\n            }\n        };\n    }\n    mk_struct_with_field_name!(baz_three);\n\n    // should not lint when names come from different places\n    macro_rules! mk_struct_with_field_name {\n        ($field_name:ident) => {\n            struct Bazilisk {\n                baz_one: i32,\n                baz_two: i32,\n                $field_name: i32,\n            }\n        };\n    }\n    mk_struct_with_field_name!(baz_three);\n\n    macro_rules! mk_struct_full_def {\n        ($struct_name:ident, $field1:ident, $field2:ident, $field3:ident) => {\n            struct $struct_name {\n                //~^ ERROR: all fields have the same prefix: `some`\n                $field1: i32,\n                $field2: i32,\n                $field3: i32,\n            }\n        };\n    }\n    mk_struct_full_def!(PrefixData, some_data, some_meta, some_other);\n}\n\n// should not lint on external code\nexternal! {\n    struct DataExternal {\n        field_data1: u8,\n        another: u8,\n        foo: u8,\n        bar: u8,\n    }\n\n    struct NotSnakeCaseExternal {\n        someData_c: bool,\n        someData_b: bool,\n        someData_a_b: bool,\n    }\n\n    struct DoublePrefixExternal {\n        some_data_a: bool,\n        some_data_b: bool,\n        some_data_c: bool,\n    }\n\n    struct StructDataExternal {\n        movable_data: u8,\n        fixed_data: u8,\n        invisible_data: u8,\n    }\n\n}\n\n// Should not warn\nstruct Config {\n    use_foo: bool,\n    use_bar: bool,\n    use_baz: bool,\n}\n\nstruct Use {\n    use_foo: bool,\n    //~^ ERROR: field name starts with the struct's name\n    use_bar: bool,\n    //~^ struct_field_names\n    use_baz: bool,\n    //~^ struct_field_names\n}\n\n// should lint on private fields of public structs (renaming them is not breaking-exported-api)\npub struct PubStructFieldNamedAfterStruct {\n    pub_struct_field_named_after_struct: bool,\n    //~^ ERROR: field name starts with the struct's name\n    other1: bool,\n    other2: bool,\n}\npub struct PubStructFieldPrefix {\n    //~^ ERROR: all fields have the same prefix: `field`\n    field_foo: u8,\n    field_bar: u8,\n    field_baz: u8,\n}\n// ...but should not lint on structs with public fields.\npub struct PubStructPubAndPrivateFields {\n    /// One could argue that this field should be linted, but currently, any public field stops all\n    /// checking.\n    pub_struct_pub_and_private_fields_1: bool,\n    pub pub_struct_pub_and_private_fields_2: bool,\n}\n// nor on common prefixes if one of the involved fields is public\npub struct PubStructPubAndPrivateFieldPrefix {\n    pub field_foo: u8,\n    field_bar: u8,\n    field_baz: u8,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/struct_fields.stderr",
    "content": "error: field name ends with the struct's name\n  --> tests/ui/struct_fields.rs:10:5\n   |\nLL |     field_data1: u8,\n   |     ^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::struct-field-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::struct_field_names)]`\n\nerror: field name starts with the struct's name\n  --> tests/ui/struct_fields.rs:20:5\n   |\nLL |     data2_field: u8,\n   |     ^^^^^^^^^^^^^^^\n\nerror: all fields have the same postfix: `data`\n  --> tests/ui/struct_fields.rs:25:1\n   |\nLL | / struct StructData {\nLL | |\nLL | |     movable_data: u8,\nLL | |     fixed_data: u8,\nLL | |     invisible_data: u8,\nLL | | }\n   | |_^\n   |\n   = help: remove the postfixes\n\nerror: all fields have the same prefix: `data`\n  --> tests/ui/struct_fields.rs:32:1\n   |\nLL | / struct DataStruct {\nLL | |\nLL | |     data_movable: u8,\nLL | |     data_fixed: u8,\nLL | |     data_invisible: u8,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes\n\nerror: all fields have the same prefix: `some_data`\n  --> tests/ui/struct_fields.rs:39:1\n   |\nLL | / struct DoublePrefix {\nLL | |\nLL | |     some_data_a: bool,\nLL | |     some_data_b: i8,\nLL | |     some_data_c: bool,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes\n\nerror: all fields have the same postfix: `some_data`\n  --> tests/ui/struct_fields.rs:46:1\n   |\nLL | / struct DoublePostfix {\nLL | |\nLL | |     a_some_data: bool,\nLL | |     b_some_data: i8,\nLL | |     c_some_data: bool,\nLL | | }\n   | |_^\n   |\n   = help: remove the postfixes\n\nerror: all fields have the same postfix: `someData`\n  --> tests/ui/struct_fields.rs:54:1\n   |\nLL | / struct NotSnakeCase {\nLL | |\nLL | |     a_someData: bool,\nLL | |     b_someData: i8,\nLL | |     c_someData: bool,\nLL | | }\n   | |_^\n   |\n   = help: remove the postfixes\n\nerror: all fields have the same prefix: `someData`\n  --> tests/ui/struct_fields.rs:61:1\n   |\nLL | / struct NotSnakeCase2 {\nLL | |\nLL | |     someData_c: bool,\nLL | |     someData_b: i8,\nLL | |     someData_a_b: bool,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes\n\nerror: all fields have the same prefix: `prefix`\n  --> tests/ui/struct_fields.rs:74:1\n   |\nLL | / struct NonCaps {\nLL | |\nLL | |     prefix_的: u8,\nLL | |     prefix_tea: u8,\nLL | |     prefix_cake: u8,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes\n\nerror: all fields have the same prefix: `_type`\n  --> tests/ui/struct_fields.rs:124:5\n   |\nLL | /     struct DoLint {\nLL | |\nLL | |         _type_create: u8,\nLL | |         _type_read: u8,\nLL | |         _type_update: u8,\nLL | |         _type_destroy: u8,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the prefixes\n\nerror: all fields have the same prefix: `__type`\n  --> tests/ui/struct_fields.rs:132:5\n   |\nLL | /     struct DoLint2 {\nLL | |\nLL | |         __type_create: u8,\nLL | |         __type_read: u8,\nLL | |         __type_update: u8,\nLL | |         __type_destroy: u8,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the prefixes\n\nerror: all fields have the same prefix: `___type`\n  --> tests/ui/struct_fields.rs:140:5\n   |\nLL | /     struct DoLint3 {\nLL | |\nLL | |         ___type_create: u8,\nLL | |         ___type_read: u8,\nLL | |         ___type_update: u8,\nLL | |         ___type_destroy: u8,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the prefixes\n\nerror: all fields have the same postfix: `_`\n  --> tests/ui/struct_fields.rs:148:5\n   |\nLL | /     struct DoLint4 {\nLL | |\nLL | |         create_: u8,\nLL | |         read_: u8,\nLL | |         update_: u8,\nLL | |         destroy_: u8,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the postfixes\n\nerror: all fields have the same postfix: `__`\n  --> tests/ui/struct_fields.rs:156:5\n   |\nLL | /     struct DoLint5 {\nLL | |\nLL | |         create__: u8,\nLL | |         read__: u8,\nLL | |         update__: u8,\nLL | |         destroy__: u8,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the postfixes\n\nerror: all fields have the same postfix: `___`\n  --> tests/ui/struct_fields.rs:164:5\n   |\nLL | /     struct DoLint6 {\nLL | |\nLL | |         create___: u8,\nLL | |         read___: u8,\nLL | |         update___: u8,\nLL | |         destroy___: u8,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the postfixes\n\nerror: all fields have the same postfix: `type`\n  --> tests/ui/struct_fields.rs:172:5\n   |\nLL | /     struct DoLintToo {\nLL | |\nLL | |         _create_type: u8,\nLL | |         _update_type: u8,\nLL | |         _delete_type: u8,\nLL | |     }\n   | |_____^\n   |\n   = help: remove the postfixes\n\nerror: field name starts with the struct's name\n  --> tests/ui/struct_fields.rs:210:5\n   |\nLL |     proxy: i32,\n   |     ^^^^^^^^^^\n\nerror: all fields have the same prefix: `some`\n  --> tests/ui/struct_fields.rs:226:13\n   |\nLL | /             struct MacroStruct {\nLL | |\nLL | |                 some_a: i32,\nLL | |                 some_b: i32,\nLL | |                 some_c: i32,\nLL | |             }\n   | |_____________^\n...\nLL |       mk_struct!();\n   |       ------------ in this macro invocation\n   |\n   = help: remove the prefixes\n   = note: this error originates in the macro `mk_struct` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: field name starts with the struct's name\n  --> tests/ui/struct_fields.rs:239:17\n   |\nLL |                 macrobaz_a: i32,\n   |                 ^^^^^^^^^^^^^^^\n...\nLL |     mk_struct2!();\n   |     ------------- in this macro invocation\n   |\n   = note: this error originates in the macro `mk_struct2` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: field name starts with the struct's name\n  --> tests/ui/struct_fields.rs:251:17\n   |\nLL |                 $field: i32,\n   |                 ^^^^^^^^^^^\n...\nLL |     mk_struct_with_names!(Foo, foo);\n   |     ------------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `mk_struct_with_names` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: all fields have the same prefix: `some`\n  --> tests/ui/struct_fields.rs:291:13\n   |\nLL | /             struct $struct_name {\nLL | |\nLL | |                 $field1: i32,\nLL | |                 $field2: i32,\nLL | |                 $field3: i32,\nLL | |             }\n   | |_____________^\n...\nLL |       mk_struct_full_def!(PrefixData, some_data, some_meta, some_other);\n   |       ----------------------------------------------------------------- in this macro invocation\n   |\n   = help: remove the prefixes\n   = note: this error originates in the macro `mk_struct_full_def` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: field name starts with the struct's name\n  --> tests/ui/struct_fields.rs:339:5\n   |\nLL |     use_foo: bool,\n   |     ^^^^^^^^^^^^^\n\nerror: field name starts with the struct's name\n  --> tests/ui/struct_fields.rs:341:5\n   |\nLL |     use_bar: bool,\n   |     ^^^^^^^^^^^^^\n\nerror: field name starts with the struct's name\n  --> tests/ui/struct_fields.rs:343:5\n   |\nLL |     use_baz: bool,\n   |     ^^^^^^^^^^^^^\n\nerror: field name starts with the struct's name\n  --> tests/ui/struct_fields.rs:349:5\n   |\nLL |     pub_struct_field_named_after_struct: bool,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: all fields have the same prefix: `field`\n  --> tests/ui/struct_fields.rs:354:1\n   |\nLL | / pub struct PubStructFieldPrefix {\nLL | |\nLL | |     field_foo: u8,\nLL | |     field_bar: u8,\nLL | |     field_baz: u8,\nLL | | }\n   | |_^\n   |\n   = help: remove the prefixes\n\nerror: aborting due to 26 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_arithmetic_impl.rs",
    "content": "#![allow(clippy::legacy_numeric_constants)]\n#![warn(clippy::suspicious_arithmetic_impl)]\nuse std::ops::{\n    Add, AddAssign, BitAnd, BitOr, BitOrAssign, BitXor, Div, DivAssign, Mul, MulAssign, Rem, Shl, Shr, Sub,\n};\n\n#[derive(Copy, Clone)]\nstruct Foo(u32);\n\nimpl Add for Foo {\n    type Output = Foo;\n\n    fn add(self, other: Self) -> Self {\n        Foo(self.0 - other.0)\n        //~^ suspicious_arithmetic_impl\n    }\n}\n\nimpl AddAssign for Foo {\n    fn add_assign(&mut self, other: Foo) {\n        *self = *self - other;\n        //~^ suspicious_op_assign_impl\n    }\n}\n\nimpl BitOrAssign for Foo {\n    fn bitor_assign(&mut self, other: Foo) {\n        let idx = other.0;\n        self.0 |= 1 << idx; // OK: BinOpKind::Shl part of AssignOp as child node\n    }\n}\n\nimpl MulAssign for Foo {\n    fn mul_assign(&mut self, other: Foo) {\n        self.0 /= other.0;\n        //~^ suspicious_op_assign_impl\n    }\n}\n\nimpl DivAssign for Foo {\n    fn div_assign(&mut self, other: Foo) {\n        self.0 /= other.0; // OK: BinOpKind::Div == DivAssign\n    }\n}\n\nimpl Mul for Foo {\n    type Output = Foo;\n\n    fn mul(self, other: Foo) -> Foo {\n        Foo(self.0 * other.0 % 42) // OK: BinOpKind::Rem part of BiExpr as parent node\n    }\n}\n\nimpl Sub for Foo {\n    type Output = Foo;\n\n    fn sub(self, other: Self) -> Self {\n        Foo(self.0 * other.0 - 42) // OK: BinOpKind::Mul part of BiExpr as child node\n    }\n}\n\nimpl Div for Foo {\n    type Output = Foo;\n\n    fn div(self, other: Self) -> Self {\n        Foo(do_nothing(self.0 + other.0) / 42) // OK: BinOpKind::Add part of BiExpr as child node\n    }\n}\n\nimpl Rem for Foo {\n    type Output = Foo;\n\n    fn rem(self, other: Self) -> Self {\n        Foo(self.0 / other.0)\n        //~^ suspicious_arithmetic_impl\n    }\n}\n\nimpl BitAnd for Foo {\n    type Output = Foo;\n\n    fn bitand(self, other: Self) -> Self {\n        Foo(self.0 | other.0)\n        //~^ suspicious_arithmetic_impl\n    }\n}\n\nimpl BitOr for Foo {\n    type Output = Foo;\n\n    fn bitor(self, other: Self) -> Self {\n        Foo(self.0 ^ other.0)\n        //~^ suspicious_arithmetic_impl\n    }\n}\n\nimpl BitXor for Foo {\n    type Output = Foo;\n\n    fn bitxor(self, other: Self) -> Self {\n        Foo(self.0 & other.0)\n        //~^ suspicious_arithmetic_impl\n    }\n}\n\nimpl Shl for Foo {\n    type Output = Foo;\n\n    fn shl(self, other: Self) -> Self {\n        Foo(self.0 >> other.0)\n        //~^ suspicious_arithmetic_impl\n    }\n}\n\nimpl Shr for Foo {\n    type Output = Foo;\n\n    fn shr(self, other: Self) -> Self {\n        Foo(self.0 << other.0)\n        //~^ suspicious_arithmetic_impl\n    }\n}\n\nstruct Bar(i32);\n\nimpl Add for Bar {\n    type Output = Bar;\n\n    fn add(self, other: Self) -> Self {\n        Bar(self.0 & !other.0) // OK: Not part of BiExpr as child node\n    }\n}\n\nimpl Sub for Bar {\n    type Output = Bar;\n\n    fn sub(self, other: Self) -> Self {\n        if self.0 <= other.0 {\n            Bar(-(self.0 & other.0)) // OK: Neg part of BiExpr as parent node\n        } else {\n            Bar(0)\n        }\n    }\n}\n\nfn main() {}\n\nfn do_nothing(x: u32) -> u32 {\n    x\n}\n\nstruct MultipleBinops(u32);\n\nimpl Add for MultipleBinops {\n    type Output = MultipleBinops;\n\n    // OK: multiple Binops in `add` impl\n    fn add(self, other: Self) -> Self::Output {\n        let mut result = self.0 + other.0;\n        if result >= u32::max_value() {\n            result -= u32::max_value();\n        }\n        MultipleBinops(result)\n    }\n}\n\nimpl Mul for MultipleBinops {\n    type Output = MultipleBinops;\n\n    // OK: multiple Binops in `mul` impl\n    fn mul(self, other: Self) -> Self::Output {\n        let mut result: u32 = 0;\n        let size = std::cmp::max(self.0, other.0) as usize;\n        let mut v = vec![0; size + 1];\n        for i in 0..size + 1 {\n            result *= i as u32;\n        }\n        MultipleBinops(result)\n    }\n}\n"
  },
  {
    "path": "tests/ui/suspicious_arithmetic_impl.stderr",
    "content": "error: suspicious use of `-` in `Add` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:14:20\n   |\nLL |         Foo(self.0 - other.0)\n   |                    ^\n   |\n   = note: `-D clippy::suspicious-arithmetic-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_arithmetic_impl)]`\n\nerror: suspicious use of `-` in `AddAssign` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:21:23\n   |\nLL |         *self = *self - other;\n   |                       ^\n   |\n   = note: `-D clippy::suspicious-op-assign-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_op_assign_impl)]`\n\nerror: suspicious use of `/` in `MulAssign` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:35:16\n   |\nLL |         self.0 /= other.0;\n   |                ^^\n\nerror: suspicious use of `/` in `Rem` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:74:20\n   |\nLL |         Foo(self.0 / other.0)\n   |                    ^\n\nerror: suspicious use of `|` in `BitAnd` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:83:20\n   |\nLL |         Foo(self.0 | other.0)\n   |                    ^\n\nerror: suspicious use of `^` in `BitOr` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:92:20\n   |\nLL |         Foo(self.0 ^ other.0)\n   |                    ^\n\nerror: suspicious use of `&` in `BitXor` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:101:20\n   |\nLL |         Foo(self.0 & other.0)\n   |                    ^\n\nerror: suspicious use of `>>` in `Shl` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:110:20\n   |\nLL |         Foo(self.0 >> other.0)\n   |                    ^^\n\nerror: suspicious use of `<<` in `Shr` impl\n  --> tests/ui/suspicious_arithmetic_impl.rs:119:20\n   |\nLL |         Foo(self.0 << other.0)\n   |                    ^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_command_arg_space.fixed",
    "content": "#![allow(clippy::zombie_processes)]\nfn main() {\n    // Things it should warn about:\n    std::process::Command::new(\"echo\").args([\"-n\", \"hello\"]).spawn().unwrap();\n    //~^ suspicious_command_arg_space\n\n    std::process::Command::new(\"cat\").args([\"--number\", \"file\"]).spawn().unwrap();\n    //~^ suspicious_command_arg_space\n\n    // Things it should not warn about:\n    std::process::Command::new(\"echo\").arg(\"hello world\").spawn().unwrap();\n    std::process::Command::new(\"a\").arg(\"--fmt=%a %b %c\").spawn().unwrap();\n    std::process::Command::new(\"b\").arg(\"-ldflags=-s -w\").spawn().unwrap();\n}\n"
  },
  {
    "path": "tests/ui/suspicious_command_arg_space.rs",
    "content": "#![allow(clippy::zombie_processes)]\nfn main() {\n    // Things it should warn about:\n    std::process::Command::new(\"echo\").arg(\"-n hello\").spawn().unwrap();\n    //~^ suspicious_command_arg_space\n\n    std::process::Command::new(\"cat\").arg(\"--number file\").spawn().unwrap();\n    //~^ suspicious_command_arg_space\n\n    // Things it should not warn about:\n    std::process::Command::new(\"echo\").arg(\"hello world\").spawn().unwrap();\n    std::process::Command::new(\"a\").arg(\"--fmt=%a %b %c\").spawn().unwrap();\n    std::process::Command::new(\"b\").arg(\"-ldflags=-s -w\").spawn().unwrap();\n}\n"
  },
  {
    "path": "tests/ui/suspicious_command_arg_space.stderr",
    "content": "error: single argument that looks like it should be multiple arguments\n  --> tests/ui/suspicious_command_arg_space.rs:4:44\n   |\nLL |     std::process::Command::new(\"echo\").arg(\"-n hello\").spawn().unwrap();\n   |                                            ^^^^^^^^^^\n   |\n   = note: `-D clippy::suspicious-command-arg-space` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_command_arg_space)]`\nhelp: consider splitting the argument\n   |\nLL -     std::process::Command::new(\"echo\").arg(\"-n hello\").spawn().unwrap();\nLL +     std::process::Command::new(\"echo\").args([\"-n\", \"hello\"]).spawn().unwrap();\n   |\n\nerror: single argument that looks like it should be multiple arguments\n  --> tests/ui/suspicious_command_arg_space.rs:7:43\n   |\nLL |     std::process::Command::new(\"cat\").arg(\"--number file\").spawn().unwrap();\n   |                                           ^^^^^^^^^^^^^^^\n   |\nhelp: consider splitting the argument\n   |\nLL -     std::process::Command::new(\"cat\").arg(\"--number file\").spawn().unwrap();\nLL +     std::process::Command::new(\"cat\").args([\"--number\", \"file\"]).spawn().unwrap();\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_doc_comments.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::suspicious_doc_comments)]\n#![allow(clippy::empty_line_after_doc_comments)]\n\n//! Real module documentation.\n//! Fake module documentation.\n//~^ suspicious_doc_comments\nfn baz() {}\n\npub mod singleline_outer_doc {\n    //! This module contains useful functions.\n    //~^ suspicious_doc_comments\n\n    pub fn bar() {}\n}\n\npub mod singleline_inner_doc {\n    //! This module contains useful functions.\n\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc {\n    /*! This module contains useful functions.\n     */\n    //~^^ suspicious_doc_comments\n\n    pub fn bar() {}\n}\n\npub mod multiline_inner_doc {\n    /*! This module contains useful functions.\n     */\n\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc2 {\n    //! This module\n    //~^ suspicious_doc_comments\n    //! contains\n    //! useful functions.\n\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc3 {\n    //! a\n    //~^ suspicious_doc_comments\n    //! b\n\n    /// c\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc4 {\n    //! a\n    //~^ suspicious_doc_comments\n    /// b\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc_gap {\n    //! a\n    //~^ suspicious_doc_comments\n\n    //! b\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc_commented {\n    /////! This outer doc comment was commented out.\n    pub fn bar() {}\n}\n\npub mod outer_doc_macro {\n    //! Very cool macro\n    //~^ suspicious_doc_comments\n    macro_rules! x {\n        () => {};\n    }\n}\n\npub mod useless_outer_doc {\n    //! Huh.\n    //~^ suspicious_doc_comments\n    use std::mem;\n}\n\n// Do not lint, this is not a `///!`\n#[doc = \"! here's some docs !\"]\nfn issue14265() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/suspicious_doc_comments.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::suspicious_doc_comments)]\n#![allow(clippy::empty_line_after_doc_comments)]\n\n//! Real module documentation.\n///! Fake module documentation.\n//~^ suspicious_doc_comments\nfn baz() {}\n\npub mod singleline_outer_doc {\n    ///! This module contains useful functions.\n    //~^ suspicious_doc_comments\n\n    pub fn bar() {}\n}\n\npub mod singleline_inner_doc {\n    //! This module contains useful functions.\n\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc {\n    /**! This module contains useful functions.\n     */\n    //~^^ suspicious_doc_comments\n\n    pub fn bar() {}\n}\n\npub mod multiline_inner_doc {\n    /*! This module contains useful functions.\n     */\n\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc2 {\n    ///! This module\n    //~^ suspicious_doc_comments\n    ///! contains\n    ///! useful functions.\n\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc3 {\n    ///! a\n    //~^ suspicious_doc_comments\n    ///! b\n\n    /// c\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc4 {\n    ///! a\n    //~^ suspicious_doc_comments\n    /// b\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc_gap {\n    ///! a\n    //~^ suspicious_doc_comments\n\n    ///! b\n    pub fn bar() {}\n}\n\npub mod multiline_outer_doc_commented {\n    /////! This outer doc comment was commented out.\n    pub fn bar() {}\n}\n\npub mod outer_doc_macro {\n    ///! Very cool macro\n    //~^ suspicious_doc_comments\n    macro_rules! x {\n        () => {};\n    }\n}\n\npub mod useless_outer_doc {\n    ///! Huh.\n    //~^ suspicious_doc_comments\n    use std::mem;\n}\n\n// Do not lint, this is not a `///!`\n#[doc = \"! here's some docs !\"]\nfn issue14265() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/suspicious_doc_comments.stderr",
    "content": "error: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:6:1\n   |\nLL | ///! Fake module documentation.\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::suspicious-doc-comments` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_doc_comments)]`\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL - ///! Fake module documentation.\nLL + //! Fake module documentation.\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:11:5\n   |\nLL |     ///! This module contains useful functions.\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL -     ///! This module contains useful functions.\nLL +     //! This module contains useful functions.\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:24:5\n   |\nLL | /     /**! This module contains useful functions.\nLL | |      */\n   | |_______^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL ~     /*! This module contains useful functions.\nLL +      */\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:39:5\n   |\nLL | /     ///! This module\nLL | |\nLL | |     ///! contains\nLL | |     ///! useful functions.\n   | |__________________________^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL ~     //! This module\nLL |\nLL ~     //! contains\nLL ~     //! useful functions.\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:48:5\n   |\nLL | /     ///! a\nLL | |\nLL | |     ///! b\n   | |__________^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL ~     //! a\nLL |\nLL ~     //! b\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:57:5\n   |\nLL |     ///! a\n   |     ^^^^^^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL -     ///! a\nLL +     //! a\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:64:5\n   |\nLL | /     ///! a\n...  |\nLL | |     ///! b\n   | |__________^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL ~     //! a\nLL |\nLL |\nLL ~     //! b\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:77:5\n   |\nLL |     ///! Very cool macro\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL -     ///! Very cool macro\nLL +     //! Very cool macro\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments.rs:85:5\n   |\nLL |     ///! Huh.\n   |     ^^^^^^^^^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL -     ///! Huh.\nLL +     //! Huh.\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_doc_comments_unfixable.rs",
    "content": "#![allow(unused, clippy::empty_line_after_doc_comments)]\n#![warn(clippy::suspicious_doc_comments)]\n//@no-rustfix\n///! a\n//~^ suspicious_doc_comments\n\n///! b\n/// c\n///! d\npub fn foo() {}\n\n///! a\n//~^ suspicious_doc_comments\n\n///! b\n/// c\n///! d\nuse std::mem;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/suspicious_doc_comments_unfixable.stderr",
    "content": "error: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments_unfixable.rs:4:1\n   |\nLL | / ///! a\nLL | |\nLL | |\nLL | | ///! b\nLL | | /// c\nLL | | ///! d\n   | |______^\n   |\n   = note: `-D clippy::suspicious-doc-comments` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_doc_comments)]`\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL + //! a\nLL |\nLL |\nLL + //! b\nLL | /// c\nLL + //! d\n   |\n\nerror: this is an outer doc comment and does not apply to the parent module or crate\n  --> tests/ui/suspicious_doc_comments_unfixable.rs:12:1\n   |\nLL | / ///! a\nLL | |\nLL | |\nLL | | ///! b\nLL | | /// c\nLL | | ///! d\n   | |______^\n   |\nhelp: use an inner doc comment to document the parent module or crate\n   |\nLL + //! a\nLL |\nLL |\nLL + //! b\nLL | /// c\nLL + //! d\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_else_formatting.rs",
    "content": "//@aux-build:proc_macro_suspicious_else_formatting.rs\n\n#![warn(clippy::suspicious_else_formatting, clippy::possible_missing_else)]\n#![allow(\n    clippy::if_same_then_else,\n    clippy::let_unit_value,\n    clippy::needless_ifs,\n    clippy::needless_else\n)]\n\nextern crate proc_macro_suspicious_else_formatting;\nuse proc_macro_suspicious_else_formatting::DeriveBadSpan;\n\nfn foo() -> bool {\n    true\n}\n\n#[rustfmt::skip]\nfn main() {\n    // weird `else` formatting:\n    if foo() {\n    } {\n    //~^ possible_missing_else\n    }\n\n    if foo() {\n    } if foo() {\n    //~^ possible_missing_else\n    }\n\n    let _ = { // if as the last expression\n        let _ = 0;\n\n        if foo() {\n        } if foo() {\n        //~^ possible_missing_else\n        }\n        else {\n        }\n    };\n\n    let _ = { // if in the middle of a block\n        if foo() {\n        } if foo() {\n        //~^ possible_missing_else\n        }\n        else {\n        }\n\n        let _ = 0;\n    };\n\n    if foo() {\n    } else\n    {\n    }\n    //~^^^ suspicious_else_formatting\n\n    // This is fine, though weird. Allman style braces on the else.\n    if foo() {\n    }\n    else\n    {\n    }\n\n    if foo() {\n    } else\n    if foo() { // the span of the above error should continue here\n    }\n    //~^^^ suspicious_else_formatting\n\n    if foo() {\n    }\n    else\n    if foo() { // the span of the above error should continue here\n    }\n    //~^^^^ suspicious_else_formatting\n\n    // those are ok:\n    if foo() {\n    }\n    {\n    }\n\n    if foo() {\n    } else {\n    }\n\n    if foo() {\n    }\n    else {\n    }\n\n    if foo() {\n    }\n    if foo() {\n    }\n\n    // Almost Allman style braces. Lint these.\n    if foo() {\n    }\n\n    else\n    {\n    }\n    //~^^^^^ suspicious_else_formatting\n\n    if foo() {\n    }\n    else\n\n    {\n\n    }\n    //~^^^^^^ suspicious_else_formatting\n\n    // #3864 - Allman style braces\n    if foo()\n    {\n    }\n    else\n    {\n    }\n\n    //#10273 This is fine. Don't warn\n    if foo() {\n    } else\n    /* whelp */\n    {\n    }\n\n    // #12497 Don't trigger lint as rustfmt wants it\n    if true {\n        println!(\"true\");\n    }\n    /*else if false {\n}*/\n    else {\n        println!(\"false\");\n    }\n\n    if true {\n        println!(\"true\");\n    } // else if false {}\n    else {\n        println!(\"false\");\n    }\n\n    if true {\n        println!(\"true\");\n    } /* if true {\n        println!(\"true\");\n}\n    */\n    else {\n        println!(\"false\");\n    }\n\n}\n\n// #7650 - Don't lint. Proc-macro using bad spans for `if` expressions.\n#[derive(DeriveBadSpan)]\nstruct _Foo(u32, u32);\n"
  },
  {
    "path": "tests/ui/suspicious_else_formatting.stderr",
    "content": "error: this looks like an `else {..}` but the `else` is missing\n  --> tests/ui/suspicious_else_formatting.rs:22:6\n   |\nLL |     } {\n   |      ^\n   |\n   = note: to remove this lint, add the missing `else` or add a new line before the next block\n   = note: `-D clippy::possible-missing-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::possible_missing_else)]`\n\nerror: this looks like an `else if` but the `else` is missing\n  --> tests/ui/suspicious_else_formatting.rs:27:6\n   |\nLL |     } if foo() {\n   |      ^\n   |\n   = note: to remove this lint, add the missing `else` or add a new line before the second `if`\n\nerror: this looks like an `else if` but the `else` is missing\n  --> tests/ui/suspicious_else_formatting.rs:35:10\n   |\nLL |         } if foo() {\n   |          ^\n   |\n   = note: to remove this lint, add the missing `else` or add a new line before the second `if`\n\nerror: this looks like an `else if` but the `else` is missing\n  --> tests/ui/suspicious_else_formatting.rs:44:10\n   |\nLL |         } if foo() {\n   |          ^\n   |\n   = note: to remove this lint, add the missing `else` or add a new line before the second `if`\n\nerror: this is an `else {..}` but the formatting might hide it\n  --> tests/ui/suspicious_else_formatting.rs:54:6\n   |\nLL |       } else\n   |  ______^\nLL | |     {\n   | |____^\n   |\n   = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`\n   = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_else_formatting)]`\n\nerror: this is an `else if` but the formatting might hide it\n  --> tests/ui/suspicious_else_formatting.rs:67:6\n   |\nLL |       } else\n   |  ______^\nLL | |     if foo() { // the span of the above error should continue here\n   | |____^\n   |\n   = note: to remove this lint, remove the `else` or remove the new line between `else` and `if`\n\nerror: this is an `else if` but the formatting might hide it\n  --> tests/ui/suspicious_else_formatting.rs:73:6\n   |\nLL |       }\n   |  ______^\nLL | |     else\nLL | |     if foo() { // the span of the above error should continue here\n   | |____^\n   |\n   = note: to remove this lint, remove the `else` or remove the new line between `else` and `if`\n\nerror: this is an `else {..}` but the formatting might hide it\n  --> tests/ui/suspicious_else_formatting.rs:101:6\n   |\nLL |       }\n   |  ______^\nLL | |\nLL | |     else\nLL | |     {\n   | |____^\n   |\n   = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`\n\nerror: this is an `else {..}` but the formatting might hide it\n  --> tests/ui/suspicious_else_formatting.rs:109:6\n   |\nLL |       }\n   |  ______^\nLL | |     else\nLL | |\nLL | |     {\n   | |____^\n   |\n   = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_map.rs",
    "content": "#![allow(clippy::map_with_unused_argument_over_ranges)]\n#![warn(clippy::suspicious_map)]\n\nfn main() {\n    let _ = (0..3).map(|x| x + 2).count();\n    //~^ suspicious_map\n\n    let f = |x| x + 1;\n    let _ = (0..3).map(f).count();\n    //~^ suspicious_map\n}\n\nfn negative() {\n    // closure with side effects\n    let mut sum = 0;\n    let _ = (0..3).map(|x| sum += x).count();\n\n    // closure variable with side effects\n    let ext_closure = |x| sum += x;\n    let _ = (0..3).map(ext_closure).count();\n\n    // closure that returns unit\n    let _ = (0..3)\n        .map(|x| {\n            // do nothing\n        })\n        .count();\n\n    // external function\n    let _ = (0..3).map(do_something).count();\n}\n\nfn do_something<T>(t: T) -> String {\n    unimplemented!()\n}\n"
  },
  {
    "path": "tests/ui/suspicious_map.stderr",
    "content": "error: this call to `map()` won't have an effect on the call to `count()`\n  --> tests/ui/suspicious_map.rs:5:13\n   |\nLL |     let _ = (0..3).map(|x| x + 2).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect`\n   = note: `-D clippy::suspicious-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]`\n\nerror: this call to `map()` won't have an effect on the call to `count()`\n  --> tests/ui/suspicious_map.rs:9:13\n   |\nLL |     let _ = (0..3).map(f).count();\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_operation_groupings.fixed",
    "content": "//@compile-flags: -Zdeduplicate-diagnostics=yes\n\n#![warn(clippy::suspicious_operation_groupings)]\n#![allow(dead_code, unused_parens, clippy::eq_op, clippy::manual_midpoint)]\n\nstruct Vec3 {\n    x: f64,\n    y: f64,\n    z: f64,\n}\n\nimpl Eq for Vec3 {}\n\nimpl PartialEq for Vec3 {\n    fn eq(&self, other: &Self) -> bool {\n        // This should trigger the lint because `self.x` is compared to `other.y`\n        self.x == other.x && self.y == other.y && self.z == other.z\n        //~^ suspicious_operation_groupings\n    }\n}\n\nstruct S {\n    a: i32,\n    b: i32,\n    c: i32,\n    d: i32,\n}\n\nfn buggy_ab_cmp(s1: &S, s2: &S) -> bool {\n    // There's no `s1.b`\n    s1.a < s2.a && s1.b < s2.b\n    //~^ suspicious_operation_groupings\n}\n\nstruct SaOnly {\n    a: i32,\n}\n\nimpl S {\n    fn a(&self) -> i32 {\n        0\n    }\n}\n\nfn do_not_give_bad_suggestions_for_this_unusual_expr(s1: &S, s2: &SaOnly) -> bool {\n    // This is superficially similar to `buggy_ab_cmp`, but we should not suggest\n    // `s2.b` since that is invalid.\n    s1.a < s2.a && s1.a() < s1.b\n}\n\nfn do_not_give_bad_suggestions_for_this_macro_expr(s1: &S, s2: &SaOnly) -> bool {\n    macro_rules! s1 {\n        () => {\n            S {\n                a: 1,\n                b: 1,\n                c: 1,\n                d: 1,\n            }\n        };\n    }\n\n    // This is superficially similar to `buggy_ab_cmp`, but we should not suggest\n    // `s2.b` since that is invalid.\n    s1.a < s2.a && s1!().a < s1.b\n}\n\nfn do_not_give_bad_suggestions_for_this_incorrect_expr(s1: &S, s2: &SaOnly) -> bool {\n    // There's two `s1.b`, but we should not suggest `s2.b` since that is invalid\n    s1.a < s2.a && s1.b < s1.b\n}\n\nfn permissable(s1: &S, s2: &S) -> bool {\n    // Something like this seems like it might actually be what is desired.\n    s1.a == s2.b\n}\n\nfn non_boolean_operators(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + s1.d * s2.d\n    //~^ suspicious_operation_groupings\n}\n\nfn odd_number_of_pairs(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.b`\n    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n    //~| suspicious_operation_groupings\n}\n\nfn not_caught_by_eq_op_middle_change_left(s1: &S, s2: &S) -> i32 {\n    // There's no `s1.b`\n    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n}\n\nfn not_caught_by_eq_op_middle_change_right(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.b`\n    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n}\n\nfn not_caught_by_eq_op_start(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.a`\n    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n}\n\nfn not_caught_by_eq_op_end(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    s1.a * s2.a + s1.b * s2.b + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n}\n\nfn the_cross_product_should_not_lint(s1: &S, s2: &S) -> (i32, i32, i32) {\n    (\n        s1.b * s2.c - s1.c * s2.b,\n        s1.c * s2.a - s1.a * s2.c,\n        s1.a * s2.b - s1.b * s2.a,\n    )\n}\n\nfn outer_parens_simple(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.b`\n    (s1.a * s2.a + s1.b * s2.b)\n    //~^ suspicious_operation_groupings\n}\n\nfn outer_parens(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    (s1.a * s2.a + s1.b * s2.b + s1.c * s2.c + s1.d * s2.d)\n    //~^ suspicious_operation_groupings\n}\n\nfn inner_parens(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d)\n    //~^ suspicious_operation_groupings\n}\n\nfn outer_and_some_inner_parens(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d))\n    //~^ suspicious_operation_groupings\n}\n\nfn all_parens_balanced_tree(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.c) + (s1.d * s2.d)))\n    //~^ suspicious_operation_groupings\n    //~| suspicious_operation_groupings\n}\n\nfn all_parens_left_tree(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.c)) + (s1.d * s2.d))\n    //~^ suspicious_operation_groupings\n}\n\nfn all_parens_right_tree(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.c) + (s1.d * s2.d)))\n    //~^ suspicious_operation_groupings\n}\n\nfn inside_other_binop_expression(s1: &S, s2: &S) -> i32 {\n    // There's no `s1.b`\n    (s1.a * s2.a + s1.b * s2.b) / 2\n    //~^ suspicious_operation_groupings\n}\n\nfn inside_function_call(s1: &S, s2: &S) -> i32 {\n    // There's no `s1.b`\n    i32::swap_bytes(s1.a * s2.a + s1.b * s2.b)\n    //~^ suspicious_operation_groupings\n}\n\nfn inside_larger_boolean_expression(s1: &S, s2: &S) -> bool {\n    // There's no `s1.c`\n    s1.a > 0 && s1.b > 0 && s1.c == s2.c && s1.d == s2.d\n    //~^ suspicious_operation_groupings\n}\n\nfn inside_larger_boolean_expression_with_unsorted_ops(s1: &S, s2: &S) -> bool {\n    // There's no `s1.c`\n    s1.a > 0 && s1.c == s2.c && s1.b > 0 && s1.d == s2.d\n    //~^ suspicious_operation_groupings\n}\n\nstruct Nested {\n    inner: ((i32,), (i32,), (i32,)),\n}\n\nfn changed_middle_ident(n1: &Nested, n2: &Nested) -> bool {\n    // There's no `n2.inner.2.0`\n    (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0\n    //~^ suspicious_operation_groupings\n}\n\n// `eq_op` should catch this one.\nfn changed_initial_ident(n1: &Nested, n2: &Nested) -> bool {\n    // There's no `n2.inner.0.0`\n    (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0\n}\n\nfn inside_fn_with_similar_expression(s1: &S, s2: &S, strict: bool) -> bool {\n    if strict {\n        s1.a < s2.a && s1.b < s2.b\n    } else {\n        // There's no `s1.b` in this subexpression\n        s1.a <= s2.a && s1.b <= s2.b\n        //~^ suspicious_operation_groupings\n    }\n}\n\nfn inside_an_if_statement(s1: &mut S, s2: &S) {\n    // There's no `s1.b`\n    if s1.a < s2.a && s1.b < s2.b {\n        //~^ suspicious_operation_groupings\n        s1.c = s2.c;\n    }\n}\n\nfn maximum_unary_minus_right_tree(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.c) + -(-s1.d * -s2.d)))\n    //~^ suspicious_operation_groupings\n}\n\nfn unary_minus_and_an_if_expression(s1: &S, s2: &S) -> i32 {\n    // There's no `s1.b`\n    -(if -s1.a < -s2.a && -s1.b < -s2.b { s1.c } else { s2.a })\n    //~^ suspicious_operation_groupings\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/suspicious_operation_groupings.rs",
    "content": "//@compile-flags: -Zdeduplicate-diagnostics=yes\n\n#![warn(clippy::suspicious_operation_groupings)]\n#![allow(dead_code, unused_parens, clippy::eq_op, clippy::manual_midpoint)]\n\nstruct Vec3 {\n    x: f64,\n    y: f64,\n    z: f64,\n}\n\nimpl Eq for Vec3 {}\n\nimpl PartialEq for Vec3 {\n    fn eq(&self, other: &Self) -> bool {\n        // This should trigger the lint because `self.x` is compared to `other.y`\n        self.x == other.y && self.y == other.y && self.z == other.z\n        //~^ suspicious_operation_groupings\n    }\n}\n\nstruct S {\n    a: i32,\n    b: i32,\n    c: i32,\n    d: i32,\n}\n\nfn buggy_ab_cmp(s1: &S, s2: &S) -> bool {\n    // There's no `s1.b`\n    s1.a < s2.a && s1.a < s2.b\n    //~^ suspicious_operation_groupings\n}\n\nstruct SaOnly {\n    a: i32,\n}\n\nimpl S {\n    fn a(&self) -> i32 {\n        0\n    }\n}\n\nfn do_not_give_bad_suggestions_for_this_unusual_expr(s1: &S, s2: &SaOnly) -> bool {\n    // This is superficially similar to `buggy_ab_cmp`, but we should not suggest\n    // `s2.b` since that is invalid.\n    s1.a < s2.a && s1.a() < s1.b\n}\n\nfn do_not_give_bad_suggestions_for_this_macro_expr(s1: &S, s2: &SaOnly) -> bool {\n    macro_rules! s1 {\n        () => {\n            S {\n                a: 1,\n                b: 1,\n                c: 1,\n                d: 1,\n            }\n        };\n    }\n\n    // This is superficially similar to `buggy_ab_cmp`, but we should not suggest\n    // `s2.b` since that is invalid.\n    s1.a < s2.a && s1!().a < s1.b\n}\n\nfn do_not_give_bad_suggestions_for_this_incorrect_expr(s1: &S, s2: &SaOnly) -> bool {\n    // There's two `s1.b`, but we should not suggest `s2.b` since that is invalid\n    s1.a < s2.a && s1.b < s1.b\n}\n\nfn permissable(s1: &S, s2: &S) -> bool {\n    // Something like this seems like it might actually be what is desired.\n    s1.a == s2.b\n}\n\nfn non_boolean_operators(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d\n    //~^ suspicious_operation_groupings\n}\n\nfn odd_number_of_pairs(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.b`\n    s1.a * s2.a + s1.b * s2.c + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n    //~| suspicious_operation_groupings\n}\n\nfn not_caught_by_eq_op_middle_change_left(s1: &S, s2: &S) -> i32 {\n    // There's no `s1.b`\n    s1.a * s2.a + s2.b * s2.b + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n}\n\nfn not_caught_by_eq_op_middle_change_right(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.b`\n    s1.a * s2.a + s1.b * s1.b + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n}\n\nfn not_caught_by_eq_op_start(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.a`\n    s1.a * s1.a + s1.b * s2.b + s1.c * s2.c\n    //~^ suspicious_operation_groupings\n}\n\nfn not_caught_by_eq_op_end(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    s1.a * s2.a + s1.b * s2.b + s1.c * s1.c\n    //~^ suspicious_operation_groupings\n}\n\nfn the_cross_product_should_not_lint(s1: &S, s2: &S) -> (i32, i32, i32) {\n    (\n        s1.b * s2.c - s1.c * s2.b,\n        s1.c * s2.a - s1.a * s2.c,\n        s1.a * s2.b - s1.b * s2.a,\n    )\n}\n\nfn outer_parens_simple(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.b`\n    (s1.a * s2.a + s1.b * s1.b)\n    //~^ suspicious_operation_groupings\n}\n\nfn outer_parens(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d)\n    //~^ suspicious_operation_groupings\n}\n\nfn inner_parens(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)\n    //~^ suspicious_operation_groupings\n}\n\nfn outer_and_some_inner_parens(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))\n    //~^ suspicious_operation_groupings\n}\n\nfn all_parens_balanced_tree(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))\n    //~^ suspicious_operation_groupings\n    //~| suspicious_operation_groupings\n}\n\nfn all_parens_left_tree(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d))\n    //~^ suspicious_operation_groupings\n}\n\nfn all_parens_right_tree(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)))\n    //~^ suspicious_operation_groupings\n}\n\nfn inside_other_binop_expression(s1: &S, s2: &S) -> i32 {\n    // There's no `s1.b`\n    (s1.a * s2.a + s2.b * s2.b) / 2\n    //~^ suspicious_operation_groupings\n}\n\nfn inside_function_call(s1: &S, s2: &S) -> i32 {\n    // There's no `s1.b`\n    i32::swap_bytes(s1.a * s2.a + s2.b * s2.b)\n    //~^ suspicious_operation_groupings\n}\n\nfn inside_larger_boolean_expression(s1: &S, s2: &S) -> bool {\n    // There's no `s1.c`\n    s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d\n    //~^ suspicious_operation_groupings\n}\n\nfn inside_larger_boolean_expression_with_unsorted_ops(s1: &S, s2: &S) -> bool {\n    // There's no `s1.c`\n    s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d\n    //~^ suspicious_operation_groupings\n}\n\nstruct Nested {\n    inner: ((i32,), (i32,), (i32,)),\n}\n\nfn changed_middle_ident(n1: &Nested, n2: &Nested) -> bool {\n    // There's no `n2.inner.2.0`\n    (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0\n    //~^ suspicious_operation_groupings\n}\n\n// `eq_op` should catch this one.\nfn changed_initial_ident(n1: &Nested, n2: &Nested) -> bool {\n    // There's no `n2.inner.0.0`\n    (n1.inner.0).0 == (n1.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.2).0\n}\n\nfn inside_fn_with_similar_expression(s1: &S, s2: &S, strict: bool) -> bool {\n    if strict {\n        s1.a < s2.a && s1.b < s2.b\n    } else {\n        // There's no `s1.b` in this subexpression\n        s1.a <= s2.a && s1.a <= s2.b\n        //~^ suspicious_operation_groupings\n    }\n}\n\nfn inside_an_if_statement(s1: &mut S, s2: &S) {\n    // There's no `s1.b`\n    if s1.a < s2.a && s1.a < s2.b {\n        //~^ suspicious_operation_groupings\n        s1.c = s2.c;\n    }\n}\n\nfn maximum_unary_minus_right_tree(s1: &S, s2: &S) -> i32 {\n    // There's no `s2.c`\n    -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d)))\n    //~^ suspicious_operation_groupings\n}\n\nfn unary_minus_and_an_if_expression(s1: &S, s2: &S) -> i32 {\n    // There's no `s1.b`\n    -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a })\n    //~^ suspicious_operation_groupings\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/suspicious_operation_groupings.stderr",
    "content": "error: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:17:9\n   |\nLL |         self.x == other.y && self.y == other.y && self.z == other.z\n   |         ^^^^^^^^^^^^^^^^^ help: did you mean: `self.x == other.x`\n   |\n   = note: `-D clippy::suspicious-operation-groupings` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_operation_groupings)]`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:31:20\n   |\nLL |     s1.a < s2.a && s1.a < s2.b\n   |                    ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:80:33\n   |\nLL |     s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d\n   |                                 ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:86:19\n   |\nLL |     s1.a * s2.a + s1.b * s2.c + s1.c * s2.c\n   |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:86:19\n   |\nLL |     s1.a * s2.a + s1.b * s2.c + s1.c * s2.c\n   |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:93:19\n   |\nLL |     s1.a * s2.a + s2.b * s2.b + s1.c * s2.c\n   |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:99:19\n   |\nLL |     s1.a * s2.a + s1.b * s1.b + s1.c * s2.c\n   |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:105:5\n   |\nLL |     s1.a * s1.a + s1.b * s2.b + s1.c * s2.c\n   |     ^^^^^^^^^^^ help: did you mean: `s1.a * s2.a`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:111:33\n   |\nLL |     s1.a * s2.a + s1.b * s2.b + s1.c * s1.c\n   |                                 ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:125:20\n   |\nLL |     (s1.a * s2.a + s1.b * s1.b)\n   |                    ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:131:34\n   |\nLL |     (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d)\n   |                                  ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:137:38\n   |\nLL |     (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)\n   |                                      ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:143:39\n   |\nLL |     ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))\n   |                                       ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:149:42\n   |\nLL |     (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))\n   |                                          ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:149:42\n   |\nLL |     (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))\n   |                                          ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:156:40\n   |\nLL |     (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d))\n   |                                        ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:162:40\n   |\nLL |     ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)))\n   |                                        ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:168:20\n   |\nLL |     (s1.a * s2.a + s2.b * s2.b) / 2\n   |                    ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:174:35\n   |\nLL |     i32::swap_bytes(s1.a * s2.a + s2.b * s2.b)\n   |                                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:180:29\n   |\nLL |     s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d\n   |                             ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:186:17\n   |\nLL |     s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d\n   |                 ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:196:77\n   |\nLL |     (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0\n   |                                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `(n1.inner.2).0 == (n2.inner.2).0`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:211:25\n   |\nLL |         s1.a <= s2.a && s1.a <= s2.b\n   |                         ^^^^^^^^^^^^ help: did you mean: `s1.b <= s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:218:23\n   |\nLL |     if s1.a < s2.a && s1.a < s2.b {\n   |                       ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:226:48\n   |\nLL |     -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d)))\n   |                                                ^^^^^^^^^^^^^ help: did you mean: `-s1.c * -s2.c`\n\nerror: this sequence of operators looks suspiciously like a bug\n  --> tests/ui/suspicious_operation_groupings.rs:232:27\n   |\nLL |     -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a })\n   |                           ^^^^^^^^^^^^^ help: did you mean: `-s1.b < -s2.b`\n\nerror: aborting due to 26 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_splitn.rs",
    "content": "#![warn(clippy::suspicious_splitn)]\n#![allow(clippy::needless_splitn)]\n\nfn main() {\n    let _ = \"a,b,c\".splitn(3, ',');\n    let _ = [0, 1, 2, 1, 3].splitn(3, |&x| x == 1);\n    let _ = \"\".splitn(0, ',');\n    let _ = [].splitn(0, |&x: &u32| x == 1);\n\n    let _ = \"a,b\".splitn(0, ',');\n    //~^ suspicious_splitn\n\n    let _ = \"a,b\".rsplitn(0, ',');\n    //~^ suspicious_splitn\n\n    let _ = \"a,b\".splitn(1, ',');\n    //~^ suspicious_splitn\n\n    let _ = [0, 1, 2].splitn(0, |&x| x == 1);\n    //~^ suspicious_splitn\n\n    let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1);\n    //~^ suspicious_splitn\n\n    let _ = [0, 1, 2].splitn(1, |&x| x == 1);\n    //~^ suspicious_splitn\n\n    let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1);\n    //~^ suspicious_splitn\n\n    const X: usize = 0;\n    let _ = \"a,b\".splitn(X + 1, ',');\n    //~^ suspicious_splitn\n\n    let _ = \"a,b\".splitn(X, ',');\n    //~^ suspicious_splitn\n}\n"
  },
  {
    "path": "tests/ui/suspicious_splitn.stderr",
    "content": "error: `splitn` called with `0` splits\n  --> tests/ui/suspicious_splitn.rs:10:13\n   |\nLL |     let _ = \"a,b\".splitn(0, ',');\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return `None`\n   = note: `-D clippy::suspicious-splitn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_splitn)]`\n\nerror: `rsplitn` called with `0` splits\n  --> tests/ui/suspicious_splitn.rs:13:13\n   |\nLL |     let _ = \"a,b\".rsplitn(0, ',');\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return `None`\n\nerror: `splitn` called with `1` split\n  --> tests/ui/suspicious_splitn.rs:16:13\n   |\nLL |     let _ = \"a,b\".splitn(1, ',');\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return the entire string followed by `None`\n\nerror: `splitn` called with `0` splits\n  --> tests/ui/suspicious_splitn.rs:19:13\n   |\nLL |     let _ = [0, 1, 2].splitn(0, |&x| x == 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return `None`\n\nerror: `splitn_mut` called with `0` splits\n  --> tests/ui/suspicious_splitn.rs:22:13\n   |\nLL |     let _ = [0, 1, 2].splitn_mut(0, |&x| x == 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return `None`\n\nerror: `splitn` called with `1` split\n  --> tests/ui/suspicious_splitn.rs:25:13\n   |\nLL |     let _ = [0, 1, 2].splitn(1, |&x| x == 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return the entire slice followed by `None`\n\nerror: `rsplitn_mut` called with `1` split\n  --> tests/ui/suspicious_splitn.rs:28:13\n   |\nLL |     let _ = [0, 1, 2].rsplitn_mut(1, |&x| x == 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return the entire slice followed by `None`\n\nerror: `splitn` called with `1` split\n  --> tests/ui/suspicious_splitn.rs:32:13\n   |\nLL |     let _ = \"a,b\".splitn(X + 1, ',');\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return the entire string followed by `None`\n\nerror: `splitn` called with `0` splits\n  --> tests/ui/suspicious_splitn.rs:35:13\n   |\nLL |     let _ = \"a,b\".splitn(X, ',');\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the resulting iterator will always return `None`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_to_owned.1.fixed",
    "content": "#![warn(clippy::suspicious_to_owned)]\n#![warn(clippy::implicit_clone)]\n#![allow(clippy::redundant_clone)]\nuse std::borrow::Cow;\nuse std::ffi::{CStr, c_char};\n\nfn main() {\n    let moo = \"Moooo\";\n    let c_moo = b\"Moooo\\0\";\n    let c_moo_ptr = c_moo.as_ptr() as *const c_char;\n    let moos = ['M', 'o', 'o'];\n    let moos_vec = moos.to_vec();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.into_owned();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.into_owned();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.into_owned();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.into_owned();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.clone();\n\n    // we expect no lints for these\n    let _ = moo.to_owned();\n    let _ = c_moo.to_owned();\n    let _ = moos.to_owned();\n\n    // we expect implicit_clone lints for these\n    let _ = String::from(moo).clone();\n    //~^ implicit_clone\n\n    let _ = moos_vec.clone();\n    //~^ implicit_clone\n}\n"
  },
  {
    "path": "tests/ui/suspicious_to_owned.2.fixed",
    "content": "#![warn(clippy::suspicious_to_owned)]\n#![warn(clippy::implicit_clone)]\n#![allow(clippy::redundant_clone)]\nuse std::borrow::Cow;\nuse std::ffi::{CStr, c_char};\n\nfn main() {\n    let moo = \"Moooo\";\n    let c_moo = b\"Moooo\\0\";\n    let c_moo_ptr = c_moo.as_ptr() as *const c_char;\n    let moos = ['M', 'o', 'o'];\n    let moos_vec = moos.to_vec();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.clone();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.clone();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.clone();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.clone();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.clone();\n\n    // we expect no lints for these\n    let _ = moo.to_owned();\n    let _ = c_moo.to_owned();\n    let _ = moos.to_owned();\n\n    // we expect implicit_clone lints for these\n    let _ = String::from(moo).clone();\n    //~^ implicit_clone\n\n    let _ = moos_vec.clone();\n    //~^ implicit_clone\n}\n"
  },
  {
    "path": "tests/ui/suspicious_to_owned.rs",
    "content": "#![warn(clippy::suspicious_to_owned)]\n#![warn(clippy::implicit_clone)]\n#![allow(clippy::redundant_clone)]\nuse std::borrow::Cow;\nuse std::ffi::{CStr, c_char};\n\nfn main() {\n    let moo = \"Moooo\";\n    let c_moo = b\"Moooo\\0\";\n    let c_moo_ptr = c_moo.as_ptr() as *const c_char;\n    let moos = ['M', 'o', 'o'];\n    let moos_vec = moos.to_vec();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.to_owned();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(moo);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.to_owned();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.to_owned();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = Cow::Borrowed(&moos_vec);\n    let _ = cow.clone();\n\n    // we expect this to be linted\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.to_owned();\n    //~^ suspicious_to_owned\n\n    // we expect no lints for this\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.into_owned();\n    // we expect no lints for this\n    let cow = unsafe { CStr::from_ptr(c_moo_ptr) }.to_string_lossy();\n    let _ = cow.clone();\n\n    // we expect no lints for these\n    let _ = moo.to_owned();\n    let _ = c_moo.to_owned();\n    let _ = moos.to_owned();\n\n    // we expect implicit_clone lints for these\n    let _ = String::from(moo).to_owned();\n    //~^ implicit_clone\n\n    let _ = moos_vec.to_owned();\n    //~^ implicit_clone\n}\n"
  },
  {
    "path": "tests/ui/suspicious_to_owned.stderr",
    "content": "error: this `to_owned` call clones the `Cow<'_, str>` itself and does not cause its contents to become owned\n  --> tests/ui/suspicious_to_owned.rs:16:13\n   |\nLL |     let _ = cow.to_owned();\n   |             ^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::suspicious-to-owned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]`\nhelp: depending on intent, either make the `Cow` an `Owned` variant\n   |\nLL |     let _ = cow.into_owned();\n   |                 ++\nhelp: or clone the `Cow` itself\n   |\nLL -     let _ = cow.to_owned();\nLL +     let _ = cow.clone();\n   |\n\nerror: this `to_owned` call clones the `Cow<'_, [char; 3]>` itself and does not cause its contents to become owned\n  --> tests/ui/suspicious_to_owned.rs:28:13\n   |\nLL |     let _ = cow.to_owned();\n   |             ^^^^^^^^^^^^^^\n   |\nhelp: depending on intent, either make the `Cow` an `Owned` variant\n   |\nLL |     let _ = cow.into_owned();\n   |                 ++\nhelp: or clone the `Cow` itself\n   |\nLL -     let _ = cow.to_owned();\nLL +     let _ = cow.clone();\n   |\n\nerror: this `to_owned` call clones the `Cow<'_, Vec<char>>` itself and does not cause its contents to become owned\n  --> tests/ui/suspicious_to_owned.rs:40:13\n   |\nLL |     let _ = cow.to_owned();\n   |             ^^^^^^^^^^^^^^\n   |\nhelp: depending on intent, either make the `Cow` an `Owned` variant\n   |\nLL |     let _ = cow.into_owned();\n   |                 ++\nhelp: or clone the `Cow` itself\n   |\nLL -     let _ = cow.to_owned();\nLL +     let _ = cow.clone();\n   |\n\nerror: this `to_owned` call clones the `Cow<'_, str>` itself and does not cause its contents to become owned\n  --> tests/ui/suspicious_to_owned.rs:52:13\n   |\nLL |     let _ = cow.to_owned();\n   |             ^^^^^^^^^^^^^^\n   |\nhelp: depending on intent, either make the `Cow` an `Owned` variant\n   |\nLL |     let _ = cow.into_owned();\n   |                 ++\nhelp: or clone the `Cow` itself\n   |\nLL -     let _ = cow.to_owned();\nLL +     let _ = cow.clone();\n   |\n\nerror: implicitly cloning a `String` by calling `to_owned` on its dereferenced type\n  --> tests/ui/suspicious_to_owned.rs:68:13\n   |\nLL |     let _ = String::from(moo).to_owned();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `String::from(moo).clone()`\n   |\n   = note: `-D clippy::implicit-clone` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::implicit_clone)]`\n\nerror: implicitly cloning a `Vec` by calling `to_owned` on its dereferenced type\n  --> tests/ui/suspicious_to_owned.rs:71:13\n   |\nLL |     let _ = moos_vec.to_owned();\n   |             ^^^^^^^^^^^^^^^^^^^ help: consider using: `moos_vec.clone()`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_unary_op_formatting.rs",
    "content": "#![warn(clippy::suspicious_unary_op_formatting)]\n#![allow(clippy::needless_ifs)]\n\n#[rustfmt::skip]\nfn main() {\n    // weird binary operator formatting:\n    let a = 42;\n\n    if a >- 30 {}\n    //~^ suspicious_unary_op_formatting\n\n    if a >=- 30 {}\n    //~^ suspicious_unary_op_formatting\n\n\n    let b = true;\n    let c = false;\n\n    if b &&! c {}\n    //~^ suspicious_unary_op_formatting\n\n\n    if a >-   30 {}\n    //~^ suspicious_unary_op_formatting\n\n\n    // those are ok:\n    if a >-30 {}\n    if a < -30 {}\n    if b && !c {}\n    if a > -   30 {}\n}\n"
  },
  {
    "path": "tests/ui/suspicious_unary_op_formatting.stderr",
    "content": "error: by not having a space between `>` and `-` it looks like `>-` is a single operator\n  --> tests/ui/suspicious_unary_op_formatting.rs:9:9\n   |\nLL |     if a >- 30 {}\n   |         ^^^^\n   |\n   = help: put a space between `>` and `-` and remove the space after `-`\n   = note: `-D clippy::suspicious-unary-op-formatting` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_unary_op_formatting)]`\n\nerror: by not having a space between `>=` and `-` it looks like `>=-` is a single operator\n  --> tests/ui/suspicious_unary_op_formatting.rs:12:9\n   |\nLL |     if a >=- 30 {}\n   |         ^^^^^\n   |\n   = help: put a space between `>=` and `-` and remove the space after `-`\n\nerror: by not having a space between `&&` and `!` it looks like `&&!` is a single operator\n  --> tests/ui/suspicious_unary_op_formatting.rs:19:9\n   |\nLL |     if b &&! c {}\n   |         ^^^^^\n   |\n   = help: put a space between `&&` and `!` and remove the space after `!`\n\nerror: by not having a space between `>` and `-` it looks like `>-` is a single operator\n  --> tests/ui/suspicious_unary_op_formatting.rs:23:9\n   |\nLL |     if a >-   30 {}\n   |         ^^^^^^\n   |\n   = help: put a space between `>` and `-` and remove the space after `-`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/suspicious_xor_used_as_pow.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::suspicious_xor_used_as_pow)]\n#![allow(clippy::eq_op)]\n//@no-rustfix\nmacro_rules! macro_test {\n    () => {\n        13\n    };\n}\n\nmacro_rules! macro_test_inside {\n    () => {\n        1 ^ 2 // should warn even if inside macro\n        //\n        //~^^ suspicious_xor_used_as_pow\n    };\n}\n\nfn main() {\n    // Should warn:\n    let _ = 2 ^ 5;\n    //~^ suspicious_xor_used_as_pow\n\n    let _ = 2i32 ^ 9i32;\n    //~^ suspicious_xor_used_as_pow\n\n    let _ = 2i32 ^ 2i32;\n    //~^ suspicious_xor_used_as_pow\n\n    let _ = 50i32 ^ 3i32;\n    //~^ suspicious_xor_used_as_pow\n\n    let _ = 5i32 ^ 8i32;\n    //~^ suspicious_xor_used_as_pow\n\n    let _ = 2i32 ^ 32i32;\n    //~^ suspicious_xor_used_as_pow\n\n    macro_test_inside!();\n\n    // Should not warn:\n    let x = 0x02;\n    let _ = x ^ 2;\n    let _ = 2 ^ x;\n    let _ = x ^ 5;\n    let _ = 10 ^ 0b0101;\n    let _ = 2i32 ^ macro_test!();\n}\n"
  },
  {
    "path": "tests/ui/suspicious_xor_used_as_pow.stderr",
    "content": "error: `^` is not the exponentiation operator\n  --> tests/ui/suspicious_xor_used_as_pow.rs:21:13\n   |\nLL |     let _ = 2 ^ 5;\n   |             ^^^^^\n   |\n   = note: `-D clippy::suspicious-xor-used-as-pow` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::suspicious_xor_used_as_pow)]`\nhelp: did you mean to write\n   |\nLL -     let _ = 2 ^ 5;\nLL +     let _ = 2.pow(5);\n   |\n\nerror: `^` is not the exponentiation operator\n  --> tests/ui/suspicious_xor_used_as_pow.rs:24:13\n   |\nLL |     let _ = 2i32 ^ 9i32;\n   |             ^^^^^^^^^^^\n   |\nhelp: did you mean to write\n   |\nLL -     let _ = 2i32 ^ 9i32;\nLL +     let _ = 2i32.pow(9i32);\n   |\n\nerror: `^` is not the exponentiation operator\n  --> tests/ui/suspicious_xor_used_as_pow.rs:27:13\n   |\nLL |     let _ = 2i32 ^ 2i32;\n   |             ^^^^^^^^^^^\n   |\nhelp: did you mean to write\n   |\nLL -     let _ = 2i32 ^ 2i32;\nLL +     let _ = 2i32.pow(2i32);\n   |\n\nerror: `^` is not the exponentiation operator\n  --> tests/ui/suspicious_xor_used_as_pow.rs:30:13\n   |\nLL |     let _ = 50i32 ^ 3i32;\n   |             ^^^^^^^^^^^^\n   |\nhelp: did you mean to write\n   |\nLL -     let _ = 50i32 ^ 3i32;\nLL +     let _ = 50i32.pow(3i32);\n   |\n\nerror: `^` is not the exponentiation operator\n  --> tests/ui/suspicious_xor_used_as_pow.rs:33:13\n   |\nLL |     let _ = 5i32 ^ 8i32;\n   |             ^^^^^^^^^^^\n   |\nhelp: did you mean to write\n   |\nLL -     let _ = 5i32 ^ 8i32;\nLL +     let _ = 5i32.pow(8i32);\n   |\n\nerror: `^` is not the exponentiation operator\n  --> tests/ui/suspicious_xor_used_as_pow.rs:36:13\n   |\nLL |     let _ = 2i32 ^ 32i32;\n   |             ^^^^^^^^^^^^\n   |\nhelp: did you mean to write\n   |\nLL -     let _ = 2i32 ^ 32i32;\nLL +     let _ = 2i32.pow(32i32);\n   |\n\nerror: `^` is not the exponentiation operator\n  --> tests/ui/suspicious_xor_used_as_pow.rs:13:9\n   |\nLL |         1 ^ 2 // should warn even if inside macro\n   |         ^^^^^\n...\nLL |     macro_test_inside!();\n   |     -------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `macro_test_inside` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: did you mean to write\n   |\nLL -         1 ^ 2 // should warn even if inside macro\nLL +         1.pow(2) // should warn even if inside macro\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/swap.fixed",
    "content": "//@aux-build: macro_rules.rs\n\n#![allow(\n    clippy::disallowed_names,\n    clippy::no_effect,\n    clippy::redundant_clone,\n    clippy::let_and_return,\n    clippy::useless_vec,\n    clippy::redundant_locals\n)]\n\nstruct Foo(u32);\n\n#[derive(Clone)]\nstruct Bar {\n    a: u32,\n    b: u32,\n}\n\nfn field() {\n    let mut bar = Bar { a: 1, b: 2 };\n\n    std::mem::swap(&mut bar.a, &mut bar.b);\n\n    let mut baz = vec![bar.clone(), bar.clone()];\n    let temp = baz[0].a;\n    baz[0].a = baz[1].a;\n    baz[1].a = temp;\n}\n\nfn array() {\n    let mut foo = [1, 2];\n    foo.swap(0, 1);\n\n    foo.swap(0, 1);\n}\n\nfn slice() {\n    let foo = &mut [1, 2];\n    foo.swap(0, 1);\n\n    foo.swap(0, 1);\n}\n\nfn unswappable_slice() {\n    let foo = &mut [vec![1, 2], vec![3, 4]];\n    let temp = foo[0][1];\n    foo[0][1] = foo[1][0];\n    foo[1][0] = temp;\n\n    // swap(foo[0][1], foo[1][0]) would fail\n    // this could use split_at_mut and mem::swap, but that is not much simpler.\n}\n\nfn vec() {\n    let mut foo = vec![1, 2];\n    foo.swap(0, 1);\n\n    foo.swap(0, 1);\n}\n\nfn xor_swap_locals() {\n    // This is an xor-based swap of local variables.\n    let mut a = 0;\n    let mut b = 1;\n    std::mem::swap(&mut a, &mut b);\n}\n\nfn xor_field_swap() {\n    // This is an xor-based swap of fields in a struct.\n    let mut bar = Bar { a: 0, b: 1 };\n    std::mem::swap(&mut bar.a, &mut bar.b);\n}\n\nfn xor_slice_swap() {\n    // This is an xor-based swap of a slice\n    let foo = &mut [1, 2];\n    foo.swap(0, 1);\n}\n\nfn xor_no_swap() {\n    // This is a sequence of xor-assignment statements that doesn't result in a swap.\n    let mut a = 0;\n    let mut b = 1;\n    let mut c = 2;\n    a ^= b;\n    b ^= c;\n    a ^= c;\n    c ^= a;\n}\n\nfn xor_unswappable_slice() {\n    let foo = &mut [vec![1, 2], vec![3, 4]];\n    foo[0][1] ^= foo[1][0];\n    foo[1][0] ^= foo[0][0];\n    foo[0][1] ^= foo[1][0];\n\n    // swap(foo[0][1], foo[1][0]) would fail\n    // this could use split_at_mut and mem::swap, but that is not much simpler.\n}\n\nfn distinct_slice() {\n    let foo = &mut [vec![1, 2], vec![3, 4]];\n    let bar = &mut [vec![1, 2], vec![3, 4]];\n    std::mem::swap(&mut foo[0][1], &mut bar[1][0]);\n}\n\n#[rustfmt::skip]\nfn main() {\n\n    let mut a = 42;\n    let mut b = 1337;\n\n    std::mem::swap(&mut a, &mut b);\n\n    ; std::mem::swap(&mut a, &mut b);\n\n    let mut c = Foo(42);\n\n    std::mem::swap(&mut c.0, &mut a);\n\n    ; std::mem::swap(&mut c.0, &mut a);\n\n    std::mem::swap(&mut a, &mut b);\n\n    let mut c = 1;\n    let mut d = 2;\n    std::mem::swap(&mut d, &mut c);\n\n    let mut b = 1;\n    std::mem::swap(&mut a, &mut b);\n\n    let b = 1;\n    let a = 2;\n\n    let t = b;\n    let b = a;\n    let a = t;\n\n    let mut b = 1;\n    let mut a = 2;\n\n    std::mem::swap(&mut b, &mut a);\n}\n\nfn issue_8154() {\n    struct S1 {\n        x: i32,\n        y: i32,\n    }\n    struct S2(S1);\n    struct S3<'a, 'b>(&'a mut &'b mut S1);\n\n    impl std::ops::Deref for S2 {\n        type Target = S1;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl std::ops::DerefMut for S2 {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    // Don't lint. `s.0` is mutably borrowed by `s.x` and `s.y` via the deref impl.\n    let mut s = S2(S1 { x: 0, y: 0 });\n    let t = s.x;\n    s.x = s.y;\n    s.y = t;\n\n    // Accessing through a mutable reference is fine\n    let mut s = S1 { x: 0, y: 0 };\n    let mut s = &mut s;\n    let s = S3(&mut s);\n    std::mem::swap(&mut s.0.x, &mut s.0.y);\n}\n\nconst fn issue_9864(mut u: u32) -> u32 {\n    let mut v = 10;\n\n    let temp = u;\n    u = v;\n    v = temp;\n    u + v\n}\n\n#[macro_use]\nextern crate macro_rules;\n\nconst fn issue_10421(x: u32) -> u32 {\n    issue_10421!();\n    let a = x;\n    let a = a;\n    let a = a;\n    a\n}\n"
  },
  {
    "path": "tests/ui/swap.rs",
    "content": "//@aux-build: macro_rules.rs\n\n#![allow(\n    clippy::disallowed_names,\n    clippy::no_effect,\n    clippy::redundant_clone,\n    clippy::let_and_return,\n    clippy::useless_vec,\n    clippy::redundant_locals\n)]\n\nstruct Foo(u32);\n\n#[derive(Clone)]\nstruct Bar {\n    a: u32,\n    b: u32,\n}\n\nfn field() {\n    let mut bar = Bar { a: 1, b: 2 };\n\n    let temp = bar.a;\n    //~^ manual_swap\n    bar.a = bar.b;\n    bar.b = temp;\n\n    let mut baz = vec![bar.clone(), bar.clone()];\n    let temp = baz[0].a;\n    baz[0].a = baz[1].a;\n    baz[1].a = temp;\n}\n\nfn array() {\n    let mut foo = [1, 2];\n    let temp = foo[0];\n    //~^ manual_swap\n    foo[0] = foo[1];\n    foo[1] = temp;\n\n    foo.swap(0, 1);\n}\n\nfn slice() {\n    let foo = &mut [1, 2];\n    let temp = foo[0];\n    //~^ manual_swap\n    foo[0] = foo[1];\n    foo[1] = temp;\n\n    foo.swap(0, 1);\n}\n\nfn unswappable_slice() {\n    let foo = &mut [vec![1, 2], vec![3, 4]];\n    let temp = foo[0][1];\n    foo[0][1] = foo[1][0];\n    foo[1][0] = temp;\n\n    // swap(foo[0][1], foo[1][0]) would fail\n    // this could use split_at_mut and mem::swap, but that is not much simpler.\n}\n\nfn vec() {\n    let mut foo = vec![1, 2];\n    let temp = foo[0];\n    //~^ manual_swap\n    foo[0] = foo[1];\n    foo[1] = temp;\n\n    foo.swap(0, 1);\n}\n\nfn xor_swap_locals() {\n    // This is an xor-based swap of local variables.\n    let mut a = 0;\n    let mut b = 1;\n    a ^= b;\n    //~^ manual_swap\n    b ^= a;\n    a ^= b;\n}\n\nfn xor_field_swap() {\n    // This is an xor-based swap of fields in a struct.\n    let mut bar = Bar { a: 0, b: 1 };\n    bar.a ^= bar.b;\n    //~^ manual_swap\n    bar.b ^= bar.a;\n    bar.a ^= bar.b;\n}\n\nfn xor_slice_swap() {\n    // This is an xor-based swap of a slice\n    let foo = &mut [1, 2];\n    foo[0] ^= foo[1];\n    //~^ manual_swap\n    foo[1] ^= foo[0];\n    foo[0] ^= foo[1];\n}\n\nfn xor_no_swap() {\n    // This is a sequence of xor-assignment statements that doesn't result in a swap.\n    let mut a = 0;\n    let mut b = 1;\n    let mut c = 2;\n    a ^= b;\n    b ^= c;\n    a ^= c;\n    c ^= a;\n}\n\nfn xor_unswappable_slice() {\n    let foo = &mut [vec![1, 2], vec![3, 4]];\n    foo[0][1] ^= foo[1][0];\n    foo[1][0] ^= foo[0][0];\n    foo[0][1] ^= foo[1][0];\n\n    // swap(foo[0][1], foo[1][0]) would fail\n    // this could use split_at_mut and mem::swap, but that is not much simpler.\n}\n\nfn distinct_slice() {\n    let foo = &mut [vec![1, 2], vec![3, 4]];\n    let bar = &mut [vec![1, 2], vec![3, 4]];\n    let temp = foo[0][1];\n    //~^ manual_swap\n    foo[0][1] = bar[1][0];\n    bar[1][0] = temp;\n}\n\n#[rustfmt::skip]\nfn main() {\n\n    let mut a = 42;\n    let mut b = 1337;\n\n    a = b;\n    //~^ almost_swapped\n    b = a;\n\n    ; let t = a;\n    //~^ manual_swap\n    a = b;\n    b = t;\n\n    let mut c = Foo(42);\n\n    c.0 = a;\n    //~^ almost_swapped\n    a = c.0;\n\n    ; let t = c.0;\n    //~^ manual_swap\n    c.0 = a;\n    a = t;\n\n    let a = b;\n    //~^ almost_swapped\n    let b = a;\n\n    let mut c = 1;\n    let mut d = 2;\n    d = c;\n    //~^ almost_swapped\n    c = d;\n\n    let mut b = 1;\n    let a = b;\n    //~^ almost_swapped\n    b = a;\n\n    let b = 1;\n    let a = 2;\n\n    let t = b;\n    let b = a;\n    let a = t;\n\n    let mut b = 1;\n    let mut a = 2;\n\n    let t = b;\n    //~^ manual_swap\n    b = a;\n    a = t;\n}\n\nfn issue_8154() {\n    struct S1 {\n        x: i32,\n        y: i32,\n    }\n    struct S2(S1);\n    struct S3<'a, 'b>(&'a mut &'b mut S1);\n\n    impl std::ops::Deref for S2 {\n        type Target = S1;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl std::ops::DerefMut for S2 {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    // Don't lint. `s.0` is mutably borrowed by `s.x` and `s.y` via the deref impl.\n    let mut s = S2(S1 { x: 0, y: 0 });\n    let t = s.x;\n    s.x = s.y;\n    s.y = t;\n\n    // Accessing through a mutable reference is fine\n    let mut s = S1 { x: 0, y: 0 };\n    let mut s = &mut s;\n    let s = S3(&mut s);\n    let t = s.0.x;\n    //~^ manual_swap\n    s.0.x = s.0.y;\n    s.0.y = t;\n}\n\nconst fn issue_9864(mut u: u32) -> u32 {\n    let mut v = 10;\n\n    let temp = u;\n    u = v;\n    v = temp;\n    u + v\n}\n\n#[macro_use]\nextern crate macro_rules;\n\nconst fn issue_10421(x: u32) -> u32 {\n    issue_10421!();\n    let a = x;\n    let a = a;\n    let a = a;\n    a\n}\n"
  },
  {
    "path": "tests/ui/swap.stderr",
    "content": "error: this looks like you are swapping `bar.a` and `bar.b` manually\n  --> tests/ui/swap.rs:23:5\n   |\nLL | /     let temp = bar.a;\nLL | |\nLL | |     bar.a = bar.b;\nLL | |     bar.b = temp;\n   | |_________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n   = note: `-D clippy::manual-swap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_swap)]`\n\nerror: this looks like you are swapping elements of `foo` manually\n  --> tests/ui/swap.rs:36:5\n   |\nLL | /     let temp = foo[0];\nLL | |\nLL | |     foo[0] = foo[1];\nLL | |     foo[1] = temp;\n   | |__________________^ help: try: `foo.swap(0, 1);`\n\nerror: this looks like you are swapping elements of `foo` manually\n  --> tests/ui/swap.rs:46:5\n   |\nLL | /     let temp = foo[0];\nLL | |\nLL | |     foo[0] = foo[1];\nLL | |     foo[1] = temp;\n   | |__________________^ help: try: `foo.swap(0, 1);`\n\nerror: this looks like you are swapping elements of `foo` manually\n  --> tests/ui/swap.rs:66:5\n   |\nLL | /     let temp = foo[0];\nLL | |\nLL | |     foo[0] = foo[1];\nLL | |     foo[1] = temp;\n   | |__________________^ help: try: `foo.swap(0, 1);`\n\nerror: this looks like you are swapping `a` and `b` manually\n  --> tests/ui/swap.rs:78:5\n   |\nLL | /     a ^= b;\nLL | |\nLL | |     b ^= a;\nLL | |     a ^= b;\n   | |___________^ help: try: `std::mem::swap(&mut a, &mut b);`\n\nerror: this looks like you are swapping `bar.a` and `bar.b` manually\n  --> tests/ui/swap.rs:87:5\n   |\nLL | /     bar.a ^= bar.b;\nLL | |\nLL | |     bar.b ^= bar.a;\nLL | |     bar.a ^= bar.b;\n   | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);`\n\nerror: this looks like you are swapping elements of `foo` manually\n  --> tests/ui/swap.rs:96:5\n   |\nLL | /     foo[0] ^= foo[1];\nLL | |\nLL | |     foo[1] ^= foo[0];\nLL | |     foo[0] ^= foo[1];\n   | |_____________________^ help: try: `foo.swap(0, 1);`\n\nerror: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually\n  --> tests/ui/swap.rs:126:5\n   |\nLL | /     let temp = foo[0][1];\nLL | |\nLL | |     foo[0][1] = bar[1][0];\nLL | |     bar[1][0] = temp;\n   | |_____________________^ help: try: `std::mem::swap(&mut foo[0][1], &mut bar[1][0]);`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: this looks like you are swapping `a` and `b` manually\n  --> tests/ui/swap.rs:142:7\n   |\nLL |       ; let t = a;\n   |  _______^\nLL | |\nLL | |     a = b;\nLL | |     b = t;\n   | |__________^ help: try: `std::mem::swap(&mut a, &mut b);`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: this looks like you are swapping `c.0` and `a` manually\n  --> tests/ui/swap.rs:153:7\n   |\nLL |       ; let t = c.0;\n   |  _______^\nLL | |\nLL | |     c.0 = a;\nLL | |     a = t;\n   | |__________^ help: try: `std::mem::swap(&mut c.0, &mut a);`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: this looks like you are swapping `b` and `a` manually\n  --> tests/ui/swap.rs:183:5\n   |\nLL | /     let t = b;\nLL | |\nLL | |     b = a;\nLL | |     a = t;\n   | |__________^ help: try: `std::mem::swap(&mut b, &mut a);`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: this looks like you are trying to swap `a` and `b`\n  --> tests/ui/swap.rs:138:5\n   |\nLL | /     a = b;\nLL | |\nLL | |     b = a;\n   | |_________^ help: try: `std::mem::swap(&mut a, &mut b)`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n   = note: `#[deny(clippy::almost_swapped)]` on by default\n\nerror: this looks like you are trying to swap `c.0` and `a`\n  --> tests/ui/swap.rs:149:5\n   |\nLL | /     c.0 = a;\nLL | |\nLL | |     a = c.0;\n   | |___________^ help: try: `std::mem::swap(&mut c.0, &mut a)`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: this looks like you are trying to swap `a` and `b`\n  --> tests/ui/swap.rs:158:5\n   |\nLL | /     let a = b;\nLL | |\nLL | |     let b = a;\n   | |_____________^ help: try: `std::mem::swap(&mut a, &mut b)`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: this looks like you are trying to swap `d` and `c`\n  --> tests/ui/swap.rs:164:5\n   |\nLL | /     d = c;\nLL | |\nLL | |     c = d;\n   | |_________^ help: try: `std::mem::swap(&mut d, &mut c)`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: this looks like you are trying to swap `a` and `b`\n  --> tests/ui/swap.rs:169:5\n   |\nLL | /     let a = b;\nLL | |\nLL | |     b = a;\n   | |_________^ help: try: `std::mem::swap(&mut a, &mut b)`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: this looks like you are swapping `s.0.x` and `s.0.y` manually\n  --> tests/ui/swap.rs:219:5\n   |\nLL | /     let t = s.0.x;\nLL | |\nLL | |     s.0.x = s.0.y;\nLL | |     s.0.y = t;\n   | |______________^ help: try: `std::mem::swap(&mut s.0.x, &mut s.0.y);`\n   |\n   = note: or maybe you should use `std::mem::replace`?\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/swap_ptr_to_ref.fixed",
    "content": "#![warn(clippy::swap_ptr_to_ref)]\n\nuse core::ptr::addr_of_mut;\n\nfn main() {\n    let mut x = 0u32;\n    let y: *mut _ = &mut x;\n    let z: *mut _ = &mut x;\n\n    unsafe {\n        core::ptr::swap(y, z);\n        //~^ swap_ptr_to_ref\n        core::ptr::swap(y, &mut x);\n        //~^ swap_ptr_to_ref\n        core::ptr::swap(&mut x, y);\n        //~^ swap_ptr_to_ref\n        core::ptr::swap(addr_of_mut!(x), addr_of_mut!(x));\n        //~^ swap_ptr_to_ref\n    }\n\n    let y = &mut x;\n    let mut z = 0u32;\n    let z = &mut z;\n\n    core::mem::swap(y, z);\n}\n"
  },
  {
    "path": "tests/ui/swap_ptr_to_ref.rs",
    "content": "#![warn(clippy::swap_ptr_to_ref)]\n\nuse core::ptr::addr_of_mut;\n\nfn main() {\n    let mut x = 0u32;\n    let y: *mut _ = &mut x;\n    let z: *mut _ = &mut x;\n\n    unsafe {\n        core::mem::swap(&mut *y, &mut *z);\n        //~^ swap_ptr_to_ref\n        core::mem::swap(&mut *y, &mut x);\n        //~^ swap_ptr_to_ref\n        core::mem::swap(&mut x, &mut *y);\n        //~^ swap_ptr_to_ref\n        core::mem::swap(&mut *addr_of_mut!(x), &mut *addr_of_mut!(x));\n        //~^ swap_ptr_to_ref\n    }\n\n    let y = &mut x;\n    let mut z = 0u32;\n    let z = &mut z;\n\n    core::mem::swap(y, z);\n}\n"
  },
  {
    "path": "tests/ui/swap_ptr_to_ref.stderr",
    "content": "error: call to `core::mem::swap` with a parameter derived from a raw pointer\n  --> tests/ui/swap_ptr_to_ref.rs:11:9\n   |\nLL |         core::mem::swap(&mut *y, &mut *z);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(y, z)`\n   |\n   = note: `-D clippy::swap-ptr-to-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::swap_ptr_to_ref)]`\n\nerror: call to `core::mem::swap` with a parameter derived from a raw pointer\n  --> tests/ui/swap_ptr_to_ref.rs:13:9\n   |\nLL |         core::mem::swap(&mut *y, &mut x);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(y, &mut x)`\n\nerror: call to `core::mem::swap` with a parameter derived from a raw pointer\n  --> tests/ui/swap_ptr_to_ref.rs:15:9\n   |\nLL |         core::mem::swap(&mut x, &mut *y);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(&mut x, y)`\n\nerror: call to `core::mem::swap` with a parameter derived from a raw pointer\n  --> tests/ui/swap_ptr_to_ref.rs:17:9\n   |\nLL |         core::mem::swap(&mut *addr_of_mut!(x), &mut *addr_of_mut!(x));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use ptr::swap: `core::ptr::swap(addr_of_mut!(x), addr_of_mut!(x))`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/swap_ptr_to_ref_unfixable.rs",
    "content": "#![warn(clippy::swap_ptr_to_ref)]\n\nmacro_rules! addr_of_mut_to_ref {\n    ($e:expr) => {\n        &mut *core::ptr::addr_of_mut!($e)\n    };\n}\n\nfn main() {\n    let mut x = 0u32;\n    let y: *mut _ = &mut x;\n\n    unsafe {\n        core::mem::swap(addr_of_mut_to_ref!(x), &mut *y);\n        //~^ swap_ptr_to_ref\n\n        core::mem::swap(&mut *y, addr_of_mut_to_ref!(x));\n        //~^ swap_ptr_to_ref\n\n        core::mem::swap(addr_of_mut_to_ref!(x), addr_of_mut_to_ref!(x));\n        //~^ swap_ptr_to_ref\n    }\n}\n"
  },
  {
    "path": "tests/ui/swap_ptr_to_ref_unfixable.stderr",
    "content": "error: call to `core::mem::swap` with a parameter derived from a raw pointer\n  --> tests/ui/swap_ptr_to_ref_unfixable.rs:14:9\n   |\nLL |         core::mem::swap(addr_of_mut_to_ref!(x), &mut *y);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::swap-ptr-to-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::swap_ptr_to_ref)]`\n\nerror: call to `core::mem::swap` with a parameter derived from a raw pointer\n  --> tests/ui/swap_ptr_to_ref_unfixable.rs:17:9\n   |\nLL |         core::mem::swap(&mut *y, addr_of_mut_to_ref!(x));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: call to `core::mem::swap` with a parameter derived from a raw pointer\n  --> tests/ui/swap_ptr_to_ref_unfixable.rs:20:9\n   |\nLL |         core::mem::swap(addr_of_mut_to_ref!(x), addr_of_mut_to_ref!(x));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/swap_with_temporary.fixed",
    "content": "#![warn(clippy::swap_with_temporary)]\n\nuse std::mem::swap;\n\nfn func() -> String {\n    String::from(\"func\")\n}\n\nfn func_returning_refmut(s: &mut String) -> &mut String {\n    s\n}\n\nfn main() {\n    let mut x = String::from(\"x\");\n    let mut y = String::from(\"y\");\n    let mut zz = String::from(\"zz\");\n    let z = &mut zz;\n\n    // No lint\n    swap(&mut x, &mut y);\n\n    y = func();\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    x = func();\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    *z = func();\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    // No lint\n    swap(z, func_returning_refmut(&mut x));\n\n    swap(&mut y, z);\n\n    *z = func();\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    macro_rules! mac {\n        (refmut $x:expr) => {\n            &mut $x\n        };\n        (funcall $f:ident) => {\n            $f()\n        };\n        (wholeexpr) => {\n            swap(&mut 42, &mut 0)\n        };\n        (ident $v:ident) => {\n            $v\n        };\n    }\n    *z = mac!(funcall func);\n    //~^ ERROR: swapping with a temporary value is inefficient\n    *mac!(ident z) = mac!(funcall func);\n    //~^ ERROR: swapping with a temporary value is inefficient\n    *mac!(ident z) = mac!(funcall func);\n    //~^ ERROR: swapping with a temporary value is inefficient\n    *mac!(refmut y) = func();\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    // No lint if it comes from a macro as it may depend on the arguments\n    mac!(wholeexpr);\n}\n\nstruct S {\n    t: String,\n}\n\nfn dont_lint_those(s: &mut S, v: &mut [String], w: Option<&mut String>) {\n    swap(&mut s.t, &mut v[0]);\n    swap(&mut s.t, v.get_mut(0).unwrap());\n    swap(w.unwrap(), &mut s.t);\n}\n\nfn issue15166() {\n    use std::sync::Mutex;\n\n    struct A {\n        thing: Mutex<Vec<u8>>,\n    }\n\n    impl A {\n        fn a(&self) {\n            let mut new_vec = vec![42];\n            // Do not lint here, as neither `new_vec` nor the result of `.lock().unwrap()` are temporaries\n            swap(&mut new_vec, &mut self.thing.lock().unwrap());\n            for v in new_vec {\n                // Do something with v\n            }\n            // Here `vec![42]` is temporary though, and a proper dereference will have to be used in the fix\n            *self.thing.lock().unwrap() = vec![42];\n            //~^ ERROR: swapping with a temporary value is inefficient\n        }\n    }\n}\n\nfn multiple_deref() {\n    let mut v1 = &mut &mut &mut vec![42];\n    ***v1 = vec![];\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    struct Wrapper<T: ?Sized>(T);\n    impl<T: ?Sized> std::ops::Deref for Wrapper<T> {\n        type Target = T;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T: ?Sized> std::ops::DerefMut for Wrapper<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    use std::sync::Mutex;\n    let mut v1 = Mutex::new(Wrapper(Wrapper(vec![42])));\n    ***v1.lock().unwrap() = vec![];\n    //~^ ERROR: swapping with a temporary value is inefficient\n}\n"
  },
  {
    "path": "tests/ui/swap_with_temporary.rs",
    "content": "#![warn(clippy::swap_with_temporary)]\n\nuse std::mem::swap;\n\nfn func() -> String {\n    String::from(\"func\")\n}\n\nfn func_returning_refmut(s: &mut String) -> &mut String {\n    s\n}\n\nfn main() {\n    let mut x = String::from(\"x\");\n    let mut y = String::from(\"y\");\n    let mut zz = String::from(\"zz\");\n    let z = &mut zz;\n\n    // No lint\n    swap(&mut x, &mut y);\n\n    swap(&mut func(), &mut y);\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    swap(&mut x, &mut func());\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    swap(z, &mut func());\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    // No lint\n    swap(z, func_returning_refmut(&mut x));\n\n    swap(&mut y, z);\n\n    swap(&mut func(), z);\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    macro_rules! mac {\n        (refmut $x:expr) => {\n            &mut $x\n        };\n        (funcall $f:ident) => {\n            $f()\n        };\n        (wholeexpr) => {\n            swap(&mut 42, &mut 0)\n        };\n        (ident $v:ident) => {\n            $v\n        };\n    }\n    swap(&mut mac!(funcall func), z);\n    //~^ ERROR: swapping with a temporary value is inefficient\n    swap(&mut mac!(funcall func), mac!(ident z));\n    //~^ ERROR: swapping with a temporary value is inefficient\n    swap(mac!(ident z), &mut mac!(funcall func));\n    //~^ ERROR: swapping with a temporary value is inefficient\n    swap(mac!(refmut y), &mut func());\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    // No lint if it comes from a macro as it may depend on the arguments\n    mac!(wholeexpr);\n}\n\nstruct S {\n    t: String,\n}\n\nfn dont_lint_those(s: &mut S, v: &mut [String], w: Option<&mut String>) {\n    swap(&mut s.t, &mut v[0]);\n    swap(&mut s.t, v.get_mut(0).unwrap());\n    swap(w.unwrap(), &mut s.t);\n}\n\nfn issue15166() {\n    use std::sync::Mutex;\n\n    struct A {\n        thing: Mutex<Vec<u8>>,\n    }\n\n    impl A {\n        fn a(&self) {\n            let mut new_vec = vec![42];\n            // Do not lint here, as neither `new_vec` nor the result of `.lock().unwrap()` are temporaries\n            swap(&mut new_vec, &mut self.thing.lock().unwrap());\n            for v in new_vec {\n                // Do something with v\n            }\n            // Here `vec![42]` is temporary though, and a proper dereference will have to be used in the fix\n            swap(&mut vec![42], &mut self.thing.lock().unwrap());\n            //~^ ERROR: swapping with a temporary value is inefficient\n        }\n    }\n}\n\nfn multiple_deref() {\n    let mut v1 = &mut &mut &mut vec![42];\n    swap(&mut ***v1, &mut vec![]);\n    //~^ ERROR: swapping with a temporary value is inefficient\n\n    struct Wrapper<T: ?Sized>(T);\n    impl<T: ?Sized> std::ops::Deref for Wrapper<T> {\n        type Target = T;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T: ?Sized> std::ops::DerefMut for Wrapper<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    use std::sync::Mutex;\n    let mut v1 = Mutex::new(Wrapper(Wrapper(vec![42])));\n    swap(&mut vec![], &mut v1.lock().unwrap());\n    //~^ ERROR: swapping with a temporary value is inefficient\n}\n"
  },
  {
    "path": "tests/ui/swap_with_temporary.stderr",
    "content": "error: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:22:5\n   |\nLL |     swap(&mut func(), &mut y);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `y = func()`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:22:15\n   |\nLL |     swap(&mut func(), &mut y);\n   |               ^^^^^^\n   = note: `-D clippy::swap-with-temporary` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::swap_with_temporary)]`\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:25:5\n   |\nLL |     swap(&mut x, &mut func());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `x = func()`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:25:23\n   |\nLL |     swap(&mut x, &mut func());\n   |                       ^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:28:5\n   |\nLL |     swap(z, &mut func());\n   |     ^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*z = func()`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:28:18\n   |\nLL |     swap(z, &mut func());\n   |                  ^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:36:5\n   |\nLL |     swap(&mut func(), z);\n   |     ^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*z = func()`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:36:15\n   |\nLL |     swap(&mut func(), z);\n   |               ^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:53:5\n   |\nLL |     swap(&mut mac!(funcall func), z);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*z = mac!(funcall func)`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:53:15\n   |\nLL |     swap(&mut mac!(funcall func), z);\n   |               ^^^^^^^^^^^^^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:55:5\n   |\nLL |     swap(&mut mac!(funcall func), mac!(ident z));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*mac!(ident z) = mac!(funcall func)`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:55:15\n   |\nLL |     swap(&mut mac!(funcall func), mac!(ident z));\n   |               ^^^^^^^^^^^^^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:57:5\n   |\nLL |     swap(mac!(ident z), &mut mac!(funcall func));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*mac!(ident z) = mac!(funcall func)`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:57:30\n   |\nLL |     swap(mac!(ident z), &mut mac!(funcall func));\n   |                              ^^^^^^^^^^^^^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:59:5\n   |\nLL |     swap(mac!(refmut y), &mut func());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*mac!(refmut y) = func()`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:59:31\n   |\nLL |     swap(mac!(refmut y), &mut func());\n   |                               ^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:92:13\n   |\nLL |             swap(&mut vec![42], &mut self.thing.lock().unwrap());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*self.thing.lock().unwrap() = vec![42]`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:92:23\n   |\nLL |             swap(&mut vec![42], &mut self.thing.lock().unwrap());\n   |                       ^^^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:100:5\n   |\nLL |     swap(&mut ***v1, &mut vec![]);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `***v1 = vec![]`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:100:27\n   |\nLL |     swap(&mut ***v1, &mut vec![]);\n   |                           ^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary.rs:118:5\n   |\nLL |     swap(&mut vec![], &mut v1.lock().unwrap());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `***v1.lock().unwrap() = vec![]`\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary.rs:118:15\n   |\nLL |     swap(&mut vec![], &mut v1.lock().unwrap());\n   |               ^^^^^^\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/swap_with_temporary_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::swap_with_temporary)]\n\nuse std::mem::swap;\n\nfn func() -> String {\n    String::from(\"func\")\n}\n\nfn func_returning_refmut(s: &mut String) -> &mut String {\n    s\n}\n\nfn main() {\n    let mut x = String::from(\"x\");\n    let mut y = String::from(\"y\");\n    let mut zz = String::from(\"zz\");\n    let z = &mut zz;\n\n    swap(&mut func(), &mut func());\n    //~^ ERROR: swapping temporary values has no effect\n\n    if matches!(swap(&mut func(), &mut func()), ()) {\n        //~^ ERROR: swapping temporary values has no effect\n        println!(\"Yeah\");\n    }\n\n    if matches!(swap(z, &mut func()), ()) {\n        //~^ ERROR: swapping with a temporary value is inefficient\n        println!(\"Yeah\");\n    }\n\n    macro_rules! mac {\n        (refmut $x:expr) => {\n            &mut $x\n        };\n        (refmut) => {\n            mac!(refmut String::new())\n        };\n        (funcall $f:ident) => {\n            $f()\n        };\n    }\n\n    swap(mac!(refmut func()), z);\n    //~^ ERROR: swapping with a temporary value is inefficient\n    swap(&mut mac!(funcall func), &mut mac!(funcall func));\n    //~^ ERROR: swapping temporary values has no effect\n    swap(mac!(refmut), mac!(refmut));\n    //~^ ERROR: swapping temporary values has no effect\n    swap(mac!(refmut y), mac!(refmut));\n    //~^ ERROR: swapping with a temporary value is inefficient\n}\n\nfn bug(v1: &mut [i32], v2: &mut [i32]) {\n    // Incorrect: swapping temporary references (`&mut &mut` passed to swap)\n    std::mem::swap(&mut v1.last_mut().unwrap(), &mut v2.last_mut().unwrap());\n    //~^ ERROR: swapping temporary values has no effect\n\n    // Correct\n    std::mem::swap(v1.last_mut().unwrap(), v2.last_mut().unwrap());\n}\n"
  },
  {
    "path": "tests/ui/swap_with_temporary_unfixable.stderr",
    "content": "error: swapping temporary values has no effect\n  --> tests/ui/swap_with_temporary_unfixable.rs:20:5\n   |\nLL |     swap(&mut func(), &mut func());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:20:15\n   |\nLL |     swap(&mut func(), &mut func());\n   |               ^^^^^^\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:20:28\n   |\nLL |     swap(&mut func(), &mut func());\n   |                            ^^^^^^\n   = note: `-D clippy::swap-with-temporary` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::swap_with_temporary)]`\n\nerror: swapping temporary values has no effect\n  --> tests/ui/swap_with_temporary_unfixable.rs:23:17\n   |\nLL |     if matches!(swap(&mut func(), &mut func()), ()) {\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:23:27\n   |\nLL |     if matches!(swap(&mut func(), &mut func()), ()) {\n   |                           ^^^^^^\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:23:40\n   |\nLL |     if matches!(swap(&mut func(), &mut func()), ()) {\n   |                                        ^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary_unfixable.rs:28:17\n   |\nLL |     if matches!(swap(z, &mut func()), ()) {\n   |                 ^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:28:30\n   |\nLL |     if matches!(swap(z, &mut func()), ()) {\n   |                              ^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary_unfixable.rs:45:5\n   |\nLL |     swap(mac!(refmut func()), z);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this is a mutable reference to a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:45:10\n   |\nLL |     swap(mac!(refmut func()), z);\n   |          ^^^^^^^^^^^^^^^^^^^\n\nerror: swapping temporary values has no effect\n  --> tests/ui/swap_with_temporary_unfixable.rs:47:5\n   |\nLL |     swap(&mut mac!(funcall func), &mut mac!(funcall func));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:47:15\n   |\nLL |     swap(&mut mac!(funcall func), &mut mac!(funcall func));\n   |               ^^^^^^^^^^^^^^^^^^\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:47:40\n   |\nLL |     swap(&mut mac!(funcall func), &mut mac!(funcall func));\n   |                                        ^^^^^^^^^^^^^^^^^^\n\nerror: swapping temporary values has no effect\n  --> tests/ui/swap_with_temporary_unfixable.rs:49:5\n   |\nLL |     swap(mac!(refmut), mac!(refmut));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this is a mutable reference to a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:49:10\n   |\nLL |     swap(mac!(refmut), mac!(refmut));\n   |          ^^^^^^^^^^^^\nnote: this is a mutable reference to a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:49:24\n   |\nLL |     swap(mac!(refmut), mac!(refmut));\n   |                        ^^^^^^^^^^^^\n\nerror: swapping with a temporary value is inefficient\n  --> tests/ui/swap_with_temporary_unfixable.rs:51:5\n   |\nLL |     swap(mac!(refmut y), mac!(refmut));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this is a mutable reference to a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:51:26\n   |\nLL |     swap(mac!(refmut y), mac!(refmut));\n   |                          ^^^^^^^^^^^^\n\nerror: swapping temporary values has no effect\n  --> tests/ui/swap_with_temporary_unfixable.rs:57:5\n   |\nLL |     std::mem::swap(&mut v1.last_mut().unwrap(), &mut v2.last_mut().unwrap());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:57:25\n   |\nLL |     std::mem::swap(&mut v1.last_mut().unwrap(), &mut v2.last_mut().unwrap());\n   |                         ^^^^^^^^^^^^^^^^^^^^^^\nnote: this expression returns a temporary value\n  --> tests/ui/swap_with_temporary_unfixable.rs:57:54\n   |\nLL |     std::mem::swap(&mut v1.last_mut().unwrap(), &mut v2.last_mut().unwrap());\n   |                                                      ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/tabs_in_doc_comments.fixed",
    "content": "#![warn(clippy::tabs_in_doc_comments)]\n\n///\n/// Struct to hold two strings:\n///     - first        one\n//~^ tabs_in_doc_comments\n//~| tabs_in_doc_comments\n///     - second    one\n//~^ tabs_in_doc_comments\n//~| tabs_in_doc_comments\npub struct DoubleString {\n    ///\n    ///     - First String:\n    //~^ tabs_in_doc_comments\n    ///         - needs to be inside here\n    //~^ tabs_in_doc_comments\n    first_string: String,\n    ///\n    ///     - Second String:\n    //~^ tabs_in_doc_comments\n    ///         - needs to be inside here\n    //~^ tabs_in_doc_comments\n    second_string: String,\n}\n\n/// This is main\nfn main() {}\n"
  },
  {
    "path": "tests/ui/tabs_in_doc_comments.rs",
    "content": "#![warn(clippy::tabs_in_doc_comments)]\n\n///\n/// Struct to hold two strings:\n/// \t- first\t\tone\n//~^ tabs_in_doc_comments\n//~| tabs_in_doc_comments\n/// \t- second\tone\n//~^ tabs_in_doc_comments\n//~| tabs_in_doc_comments\npub struct DoubleString {\n    ///\n    /// \t- First String:\n    //~^ tabs_in_doc_comments\n    /// \t\t- needs to be inside here\n    //~^ tabs_in_doc_comments\n    first_string: String,\n    ///\n    /// \t- Second String:\n    //~^ tabs_in_doc_comments\n    /// \t\t- needs to be inside here\n    //~^ tabs_in_doc_comments\n    second_string: String,\n}\n\n/// This is main\nfn main() {}\n"
  },
  {
    "path": "tests/ui/tabs_in_doc_comments.stderr",
    "content": "error: using tabs in doc comments is not recommended\n  --> tests/ui/tabs_in_doc_comments.rs:5:5\n   |\nLL | ///     - first        one\n   |     ^^^^ help: consider using four spaces per tab\n   |\n   = note: `-D clippy::tabs-in-doc-comments` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`\n\nerror: using tabs in doc comments is not recommended\n  --> tests/ui/tabs_in_doc_comments.rs:5:13\n   |\nLL | ///     - first        one\n   |                ^^^^^^^^ help: consider using four spaces per tab\n\nerror: using tabs in doc comments is not recommended\n  --> tests/ui/tabs_in_doc_comments.rs:8:5\n   |\nLL | ///     - second    one\n   |     ^^^^ help: consider using four spaces per tab\n\nerror: using tabs in doc comments is not recommended\n  --> tests/ui/tabs_in_doc_comments.rs:8:14\n   |\nLL | ///     - second    one\n   |                 ^^^^ help: consider using four spaces per tab\n\nerror: using tabs in doc comments is not recommended\n  --> tests/ui/tabs_in_doc_comments.rs:13:9\n   |\nLL |     ///     - First String:\n   |         ^^^^ help: consider using four spaces per tab\n\nerror: using tabs in doc comments is not recommended\n  --> tests/ui/tabs_in_doc_comments.rs:15:9\n   |\nLL |     ///         - needs to be inside here\n   |         ^^^^^^^^ help: consider using four spaces per tab\n\nerror: using tabs in doc comments is not recommended\n  --> tests/ui/tabs_in_doc_comments.rs:19:9\n   |\nLL |     ///     - Second String:\n   |         ^^^^ help: consider using four spaces per tab\n\nerror: using tabs in doc comments is not recommended\n  --> tests/ui/tabs_in_doc_comments.rs:21:9\n   |\nLL |     ///         - needs to be inside here\n   |         ^^^^^^^^ help: consider using four spaces per tab\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/temporary_assignment.rs",
    "content": "#![warn(clippy::temporary_assignment)]\n#![allow(clippy::needless_lifetimes)]\n\nuse std::ops::{Deref, DerefMut};\n\nstruct TupleStruct(i32);\n\nstruct Struct {\n    field: i32,\n}\n\nstruct MultiStruct {\n    structure: Struct,\n}\n\nstruct Wrapper<'a> {\n    inner: &'a mut Struct,\n}\n\nimpl<'a> Deref for Wrapper<'a> {\n    type Target = Struct;\n    fn deref(&self) -> &Struct {\n        self.inner\n    }\n}\n\nimpl<'a> DerefMut for Wrapper<'a> {\n    fn deref_mut(&mut self) -> &mut Struct {\n        self.inner\n    }\n}\n\nstruct ArrayStruct {\n    array: [i32; 1],\n}\n\nconst A: TupleStruct = TupleStruct(1);\nconst B: Struct = Struct { field: 1 };\nconst C: MultiStruct = MultiStruct {\n    structure: Struct { field: 1 },\n};\nconst D: ArrayStruct = ArrayStruct { array: [1] };\n\nfn main() {\n    let mut s = Struct { field: 0 };\n    let mut t = (0, 0);\n\n    Struct { field: 0 }.field = 1;\n    //~^ temporary_assignment\n\n    MultiStruct {\n        //~^ temporary_assignment\n        structure: Struct { field: 0 },\n    }\n    .structure\n    .field = 1;\n    ArrayStruct { array: [0] }.array[0] = 1;\n    //~^ temporary_assignment\n\n    (0, 0).0 = 1;\n    //~^ temporary_assignment\n\n    // no error\n    s.field = 1;\n    t.0 = 1;\n    Wrapper { inner: &mut s }.field = 1;\n    let mut a_mut = TupleStruct(1);\n    a_mut.0 = 2;\n    let mut b_mut = Struct { field: 1 };\n    b_mut.field = 2;\n    let mut c_mut = MultiStruct {\n        structure: Struct { field: 1 },\n    };\n    c_mut.structure.field = 2;\n    let mut d_mut = ArrayStruct { array: [1] };\n    d_mut.array[0] = 2;\n}\n"
  },
  {
    "path": "tests/ui/temporary_assignment.stderr",
    "content": "error: assignment to temporary\n  --> tests/ui/temporary_assignment.rs:48:5\n   |\nLL |     Struct { field: 0 }.field = 1;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::temporary-assignment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::temporary_assignment)]`\n\nerror: assignment to temporary\n  --> tests/ui/temporary_assignment.rs:51:5\n   |\nLL | /     MultiStruct {\nLL | |\nLL | |         structure: Struct { field: 0 },\n...  |\nLL | |     .field = 1;\n   | |______________^\n\nerror: assignment to temporary\n  --> tests/ui/temporary_assignment.rs:57:5\n   |\nLL |     ArrayStruct { array: [0] }.array[0] = 1;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: assignment to temporary\n  --> tests/ui/temporary_assignment.rs:60:5\n   |\nLL |     (0, 0).0 = 1;\n   |     ^^^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/test_attr_in_doctest.rs",
    "content": "/// This is a test for `#[test]` in doctests\n///\n/// # Examples\n///\n/// ```\n/// #[test]\n//~^ test_attr_in_doctest\n/// fn should_be_linted() {\n///     assert_eq!(1, 1);\n/// }\n/// ```\n/// \n/// Make sure we catch multiple tests in one example,\n/// and show that we really parse the attr:\n/// ```\n/// #[test]\n//~^ test_attr_in_doctest\n/// fn should_also_be_linted() {\n///     #[cfg(test)]\n///     assert!(true);\n/// }\n///\n/// #[test]\n/// fn should_be_linted_too() {\n///     assert_eq!(\"#[test]\", \"\n///     #[test]\n///     \");\n/// }\n/// ```\n/// \n/// We don't catch examples that aren't run:\n/// ```ignore\n/// #[test]\n/// fn ignored() { todo!() }\n/// ```\n/// ```no_run\n/// #[test]\n/// fn ignored() { todo!() }\n/// ```\n/// ```compile_fail\n/// #[test]\n/// fn ignored() { Err(()) }\n/// ```\n/// ```txt\n/// #[test]\n/// fn not_even_rust() { panic!(\"Ouch\") }\n/// ```\nfn test_attr_in_doctests() {}\n\n/// ```test_harness\n/// #[test]\n/// fn foo() {\n///     panic!();\n/// }\n/// ```\npub fn issue16447() {}\n"
  },
  {
    "path": "tests/ui/test_attr_in_doctest.stderr",
    "content": "error: unit tests in doctest are not executed\n  --> tests/ui/test_attr_in_doctest.rs:6:5\n   |\nLL | /// #[test]\n   |     ^^^^^^^\n   |\n   = note: `-D clippy::test-attr-in-doctest` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::test_attr_in_doctest)]`\n\nerror: unit tests in doctest are not executed\n  --> tests/ui/test_attr_in_doctest.rs:16:5\n   |\nLL | /// #[test]\n   |     ^^^^^^^\n...\nLL | /// #[test]\n   |     ^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/tests_outside_test_module.rs",
    "content": "//@require-annotations-for-level: WARN\n#![allow(unused)]\n#![warn(clippy::tests_outside_test_module)]\n\nfn main() {\n    // test code goes here\n}\n\n// Should lint\n#[test]\nfn my_test() {}\n//~^ ERROR: this function marked with #[test] is outside a #[cfg(test)] module\n//~| NOTE: move it to a testing module marked with #[cfg(test)]\n\n#[cfg(test)]\nmod tests {\n    // Should not lint\n    #[test]\n    fn my_test() {}\n}\n"
  },
  {
    "path": "tests/ui/tests_outside_test_module.stderr",
    "content": "error: this function marked with #[test] is outside a #[cfg(test)] module\n  --> tests/ui/tests_outside_test_module.rs:11:1\n   |\nLL | fn my_test() {}\n   | ^^^^^^^^^^^^^^^\n   |\n   = note: move it to a testing module marked with #[cfg(test)]\n   = note: `-D clippy::tests-outside-test-module` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::tests_outside_test_module)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/to_digit_is_some.fixed",
    "content": "#![warn(clippy::to_digit_is_some)]\n\nfn main() {\n    let c = 'x';\n    let d = &c;\n\n    let _ = d.is_digit(8);\n    //~^ to_digit_is_some\n    let _ = char::is_digit(c, 8);\n    //~^ to_digit_is_some\n}\n\n#[clippy::msrv = \"1.86\"]\nmod cannot_lint_in_const_context {\n    fn without_const(c: char) -> bool {\n        c.is_digit(8)\n        //~^ to_digit_is_some\n    }\n    const fn with_const(c: char) -> bool {\n        c.to_digit(8).is_some()\n    }\n}\n\n#[clippy::msrv = \"1.87\"]\nconst fn with_const(c: char) -> bool {\n    c.is_digit(8)\n    //~^ to_digit_is_some\n}\n"
  },
  {
    "path": "tests/ui/to_digit_is_some.rs",
    "content": "#![warn(clippy::to_digit_is_some)]\n\nfn main() {\n    let c = 'x';\n    let d = &c;\n\n    let _ = d.to_digit(8).is_some();\n    //~^ to_digit_is_some\n    let _ = char::to_digit(c, 8).is_some();\n    //~^ to_digit_is_some\n}\n\n#[clippy::msrv = \"1.86\"]\nmod cannot_lint_in_const_context {\n    fn without_const(c: char) -> bool {\n        c.to_digit(8).is_some()\n        //~^ to_digit_is_some\n    }\n    const fn with_const(c: char) -> bool {\n        c.to_digit(8).is_some()\n    }\n}\n\n#[clippy::msrv = \"1.87\"]\nconst fn with_const(c: char) -> bool {\n    c.to_digit(8).is_some()\n    //~^ to_digit_is_some\n}\n"
  },
  {
    "path": "tests/ui/to_digit_is_some.stderr",
    "content": "error: use of `.to_digit(..).is_some()`\n  --> tests/ui/to_digit_is_some.rs:7:13\n   |\nLL |     let _ = d.to_digit(8).is_some();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d.is_digit(8)`\n   |\n   = note: `-D clippy::to-digit-is-some` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::to_digit_is_some)]`\n\nerror: use of `.to_digit(..).is_some()`\n  --> tests/ui/to_digit_is_some.rs:9:13\n   |\nLL |     let _ = char::to_digit(c, 8).is_some();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `char::is_digit(c, 8)`\n\nerror: use of `.to_digit(..).is_some()`\n  --> tests/ui/to_digit_is_some.rs:16:9\n   |\nLL |         c.to_digit(8).is_some()\n   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_digit(8)`\n\nerror: use of `.to_digit(..).is_some()`\n  --> tests/ui/to_digit_is_some.rs:26:5\n   |\nLL |     c.to_digit(8).is_some()\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_digit(8)`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/to_string_trait_impl.rs",
    "content": "#![warn(clippy::to_string_trait_impl)]\n#![feature(min_specialization)]\n\nuse std::fmt::{self, Display};\n\nstruct Point {\n    x: usize,\n    y: usize,\n}\n\nimpl ToString for Point {\n    //~^ to_string_trait_impl\n    fn to_string(&self) -> String {\n        format!(\"({}, {})\", self.x, self.y)\n    }\n}\n\nstruct Foo;\n\nimpl Display for Foo {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"Foo\")\n    }\n}\n\nstruct Bar;\n\nimpl Bar {\n    #[allow(clippy::inherent_to_string)]\n    fn to_string(&self) -> String {\n        String::from(\"Bar\")\n    }\n}\n"
  },
  {
    "path": "tests/ui/to_string_trait_impl.stderr",
    "content": "error: direct implementation of `ToString`\n  --> tests/ui/to_string_trait_impl.rs:11:1\n   |\nLL | / impl ToString for Point {\nLL | |\nLL | |     fn to_string(&self) -> String {\nLL | |         format!(\"({}, {})\", self.x, self.y)\nLL | |     }\nLL | | }\n   | |_^\n   |\n   = help: prefer implementing `Display` instead\n   = note: `-D clippy::to-string-trait-impl` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::to_string_trait_impl)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/too_long_first_doc_paragraph-fix.fixed",
    "content": "#![warn(clippy::too_long_first_doc_paragraph)]\n\n/// A very short summary.\n//~^ too_long_first_doc_paragraph\n///\n//~^ too_long_first_doc_paragraph\n/// A much longer explanation that goes into a lot more detail about\n/// how the thing works, possibly with doclinks and so one,\n/// and probably spanning a many rows. Blablabla, it needs to be over\n/// 200 characters so I needed to write something longeeeeeeer.\npub struct Foo;\n"
  },
  {
    "path": "tests/ui/too_long_first_doc_paragraph-fix.rs",
    "content": "#![warn(clippy::too_long_first_doc_paragraph)]\n\n/// A very short summary.\n//~^ too_long_first_doc_paragraph\n/// A much longer explanation that goes into a lot more detail about\n/// how the thing works, possibly with doclinks and so one,\n/// and probably spanning a many rows. Blablabla, it needs to be over\n/// 200 characters so I needed to write something longeeeeeeer.\npub struct Foo;\n"
  },
  {
    "path": "tests/ui/too_long_first_doc_paragraph-fix.stderr",
    "content": "error: first doc comment paragraph is too long\n  --> tests/ui/too_long_first_doc_paragraph-fix.rs:3:1\n   |\nLL | / /// A very short summary.\nLL | |\nLL | | /// A much longer explanation that goes into a lot more detail about\nLL | | /// how the thing works, possibly with doclinks and so one,\nLL | | /// and probably spanning a many rows. Blablabla, it needs to be over\nLL | | /// 200 characters so I needed to write something longeeeeeeer.\n   | |_^\n   |\n   = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`\nhelp: add an empty line\n   |\nLL | /// A very short summary.\nLL |\nLL + ///\nLL +\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/too_long_first_doc_paragraph.rs",
    "content": "//@no-rustfix\n\n#![warn(clippy::too_long_first_doc_paragraph)]\n\npub mod foo {\n\n    // in foo.rs\n    //! A very short summary.\n    //~^ too_long_first_doc_paragraph\n    //! A much longer explanation that goes into a lot more detail about\n    //! how the thing works, possibly with doclinks and so one,\n    //! and probably spanning a many rows. Blablabla, it needs to be over\n    //! 200 characters so I needed to write something longeeeeeeer.\n}\n\n/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia\n//~^ too_long_first_doc_paragraph\n/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,\n/// gravida non lacinia at, rhoncus eu lacus.\npub struct Bar;\n\n// Should not warn! (not an item visible on mod page)\n/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia\n/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,\n/// gravida non lacinia at, rhoncus eu lacus.\nimpl Bar {}\n\n// Should not warn! (less than 80 characters)\n/// Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n///\n/// Nunc turpis nunc, lacinia\n/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,\n/// gravida non lacinia at, rhoncus eu lacus.\npub enum Enum {\n    A,\n}\n\n/// Lorem\n//~^ too_long_first_doc_paragraph\n/// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia\n/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,\n/// gravida non lacinia at, rhoncus eu lacus.\npub union Union {\n    a: u8,\n    b: u8,\n}\n\n// Should not warn! (title)\n/// # bla\n/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia\n/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,\n/// gravida non lacinia at, rhoncus eu lacus.\npub union Union2 {\n    a: u8,\n    b: u8,\n}\n\n// Should not warn! (not public)\n/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia\n/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,\n/// gravida non lacinia at, rhoncus eu lacus.\nfn f() {}\n\n#[rustfmt::skip]\n/// Some function. This doc-string paragraph is too long. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.\n//~^ too_long_first_doc_paragraph\n///\n/// Here's a second paragraph. It would be preferable to put the details here.\npub fn issue_14274() {}\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui/too_long_first_doc_paragraph.stderr",
    "content": "error: first doc comment paragraph is too long\n  --> tests/ui/too_long_first_doc_paragraph.rs:8:5\n   |\nLL | /     //! A very short summary.\nLL | |\nLL | |     //! A much longer explanation that goes into a lot more detail about\nLL | |     //! how the thing works, possibly with doclinks and so one,\nLL | |     //! and probably spanning a many rows. Blablabla, it needs to be over\nLL | |     //! 200 characters so I needed to write something longeeeeeeer.\n   | |____^\n   |\n   = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`\nhelp: add an empty line\n   |\nLL |     //! A very short summary.\nLL |\nLL ~     //!\nLL +\nLL ~     //! A much longer explanation that goes into a lot more detail about\n   |\n\nerror: first doc comment paragraph is too long\n  --> tests/ui/too_long_first_doc_paragraph.rs:16:1\n   |\nLL | / /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia\nLL | |\nLL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,\nLL | | /// gravida non lacinia at, rhoncus eu lacus.\n   | |_^\n\nerror: first doc comment paragraph is too long\n  --> tests/ui/too_long_first_doc_paragraph.rs:38:1\n   |\nLL | / /// Lorem\nLL | |\nLL | | /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia\nLL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,\nLL | | /// gravida non lacinia at, rhoncus eu lacus.\n   | |_^\n\nerror: first doc comment paragraph is too long\n  --> tests/ui/too_long_first_doc_paragraph.rs:65:1\n   |\nLL | / /// Some function. This doc-string paragraph is too long. Lorem Ipsum is simply dummy text of the printing and typesetting industr...\nLL | |\nLL | | ///\nLL | | /// Here's a second paragraph. It would be preferable to put the details here.\n   | |_^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/toplevel_ref_arg.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::toplevel_ref_arg)]\n#![allow(clippy::uninlined_format_args, unused, clippy::useless_vec)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n#[inline_macros]\nfn main() {\n    // Closures should not warn\n    let y = |ref x| println!(\"{:?}\", x);\n    y(1u8);\n\n    let _x = &1;\n    //~^ toplevel_ref_arg\n\n    let _y: &(&_, u8) = &(&1, 2);\n    //~^ toplevel_ref_arg\n\n    let _z = &(1 + 2);\n    //~^ toplevel_ref_arg\n\n    let _z = &mut (1 + 2);\n    //~^ toplevel_ref_arg\n\n    let (ref x, _) = (1, 2); // ok, not top level\n    println!(\"The answer is {}.\", x);\n\n    let _x = &vec![1, 2, 3];\n    //~^ toplevel_ref_arg\n\n    // Make sure that allowing the lint works\n    #[allow(clippy::toplevel_ref_arg)]\n    let ref mut _x = 1_234_543;\n\n    // ok\n    for ref _x in 0..10 {}\n\n    // lint in macro\n    inline!(let _y = &42;);\n    //~^ toplevel_ref_arg\n\n    // do not lint in external macro\n    external!(let ref _y = 42;);\n\n    fn f(#[allow(clippy::toplevel_ref_arg)] ref x: i32) {}\n}\n"
  },
  {
    "path": "tests/ui/toplevel_ref_arg.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::toplevel_ref_arg)]\n#![allow(clippy::uninlined_format_args, unused, clippy::useless_vec)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\n#[inline_macros]\nfn main() {\n    // Closures should not warn\n    let y = |ref x| println!(\"{:?}\", x);\n    y(1u8);\n\n    let ref _x = 1;\n    //~^ toplevel_ref_arg\n\n    let ref _y: (&_, u8) = (&1, 2);\n    //~^ toplevel_ref_arg\n\n    let ref _z = 1 + 2;\n    //~^ toplevel_ref_arg\n\n    let ref mut _z = 1 + 2;\n    //~^ toplevel_ref_arg\n\n    let (ref x, _) = (1, 2); // ok, not top level\n    println!(\"The answer is {}.\", x);\n\n    let ref _x = vec![1, 2, 3];\n    //~^ toplevel_ref_arg\n\n    // Make sure that allowing the lint works\n    #[allow(clippy::toplevel_ref_arg)]\n    let ref mut _x = 1_234_543;\n\n    // ok\n    for ref _x in 0..10 {}\n\n    // lint in macro\n    inline!(let ref _y = 42;);\n    //~^ toplevel_ref_arg\n\n    // do not lint in external macro\n    external!(let ref _y = 42;);\n\n    fn f(#[allow(clippy::toplevel_ref_arg)] ref x: i32) {}\n}\n"
  },
  {
    "path": "tests/ui/toplevel_ref_arg.stderr",
    "content": "error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead\n  --> tests/ui/toplevel_ref_arg.rs:14:9\n   |\nLL |     let ref _x = 1;\n   |     ----^^^^^^----- help: try: `let _x = &1;`\n   |\n   = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::toplevel_ref_arg)]`\n\nerror: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead\n  --> tests/ui/toplevel_ref_arg.rs:17:9\n   |\nLL |     let ref _y: (&_, u8) = (&1, 2);\n   |     ----^^^^^^--------------------- help: try: `let _y: &(&_, u8) = &(&1, 2);`\n\nerror: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead\n  --> tests/ui/toplevel_ref_arg.rs:20:9\n   |\nLL |     let ref _z = 1 + 2;\n   |     ----^^^^^^--------- help: try: `let _z = &(1 + 2);`\n\nerror: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead\n  --> tests/ui/toplevel_ref_arg.rs:23:9\n   |\nLL |     let ref mut _z = 1 + 2;\n   |     ----^^^^^^^^^^--------- help: try: `let _z = &mut (1 + 2);`\n\nerror: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead\n  --> tests/ui/toplevel_ref_arg.rs:29:9\n   |\nLL |     let ref _x = vec![1, 2, 3];\n   |     ----^^^^^^----------------- help: try: `let _x = &vec![1, 2, 3];`\n\nerror: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead\n  --> tests/ui/toplevel_ref_arg.rs:40:17\n   |\nLL |     inline!(let ref _y = 42;);\n   |             ----^^^^^^------ help: try: `let _y = &42;`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/toplevel_ref_arg_non_rustfix.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::toplevel_ref_arg)]\n#![allow(unused)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nfn the_answer(ref mut x: u8) {\n    //~^ toplevel_ref_arg\n    *x = 42;\n}\n\n#[inline_macros]\nfn main() {\n    let mut x = 0;\n    the_answer(x);\n\n    // lint in macro\n    inline! {\n        fn fun_example(ref _x: usize) {}\n        //~^ toplevel_ref_arg\n    }\n\n    // do not lint in external macro\n    external! {\n        fn fun_example2(ref _x: usize) {}\n    }\n}\n"
  },
  {
    "path": "tests/ui/toplevel_ref_arg_non_rustfix.stderr",
    "content": "error: `ref` directly on a function parameter does not prevent taking ownership of the passed argument. Consider using a reference type instead\n  --> tests/ui/toplevel_ref_arg_non_rustfix.rs:9:15\n   |\nLL | fn the_answer(ref mut x: u8) {\n   |               ^^^^^^^^^\n   |\n   = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::toplevel_ref_arg)]`\n\nerror: `ref` directly on a function parameter does not prevent taking ownership of the passed argument. Consider using a reference type instead\n  --> tests/ui/toplevel_ref_arg_non_rustfix.rs:21:24\n   |\nLL |         fn fun_example(ref _x: usize) {}\n   |                        ^^^^^^\n   |\n   = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/track-diagnostics-clippy.fixed",
    "content": "//@compile-flags: -Z track-diagnostics\n\n// Normalize the emitted location so this doesn't need\n// updating everytime someone adds or removes a line.\n//@normalize-stderr-test: \".rs:\\d+:\\d+\" -> \".rs:LL:CC\"\n//@normalize-stderr-test: \"src/tools/clippy/\" -> \"\"\n\n#![warn(clippy::let_and_return, clippy::unnecessary_cast)]\n\nfn main() {\n    // Check the provenance of a lint sent through `LintContext::span_lint()`\n    let a = 3u32;\n    let b = a;\n    //~^ unnecessary_cast\n\n    // Check the provenance of a lint sent through `TyCtxt::node_span_lint()`\n    let c = {\n        \n        42\n        //~^ let_and_return\n    };\n}\n"
  },
  {
    "path": "tests/ui/track-diagnostics-clippy.rs",
    "content": "//@compile-flags: -Z track-diagnostics\n\n// Normalize the emitted location so this doesn't need\n// updating everytime someone adds or removes a line.\n//@normalize-stderr-test: \".rs:\\d+:\\d+\" -> \".rs:LL:CC\"\n//@normalize-stderr-test: \"src/tools/clippy/\" -> \"\"\n\n#![warn(clippy::let_and_return, clippy::unnecessary_cast)]\n\nfn main() {\n    // Check the provenance of a lint sent through `LintContext::span_lint()`\n    let a = 3u32;\n    let b = a as u32;\n    //~^ unnecessary_cast\n\n    // Check the provenance of a lint sent through `TyCtxt::node_span_lint()`\n    let c = {\n        let d = 42;\n        d\n        //~^ let_and_return\n    };\n}\n"
  },
  {
    "path": "tests/ui/track-diagnostics-clippy.stderr",
    "content": "error: casting to the same type is unnecessary (`u32` -> `u32`)\n  --> tests/ui/track-diagnostics-clippy.rs:LL:CC\n   |\nLL |     let b = a as u32;\n   |             ^^^^^^^^ help: try: `a`\n   |\n   = note: -Ztrack-diagnostics: created at clippy_lints/src/casts/unnecessary_cast.rs:LL:CC\n   = note: `-D clippy::unnecessary-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]`\n\nerror: returning the result of a `let` binding from a block\n  --> tests/ui/track-diagnostics-clippy.rs:LL:CC\n   |\nLL |         let d = 42;\n   |         ----------- unnecessary `let` binding\nLL |         d\n   |         ^\n   |\n   = note: -Ztrack-diagnostics: created at clippy_lints/src/returns/let_and_return.rs:LL:CC\n   = note: `-D clippy::let-and-return` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`\nhelp: return the expression directly\n   |\nLL ~         \nLL ~         42\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/track-diagnostics.rs",
    "content": "//@compile-flags: -Z track-diagnostics\n\n// Normalize the emitted location so this doesn't need\n// updating everytime someone adds or removes a line.\n//@normalize-stderr-test: \".rs:\\d+:\\d+\" -> \".rs:LL:CC\"\n//@normalize-stderr-test: \"/rustc-dev/[0-9a-f]+/\" -> \"\"\n\nstruct A;\nstruct B;\nconst S: A = B;\n//~^ ERROR: mismatched types\n//~| NOTE: created at\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/track-diagnostics.stderr",
    "content": "error[E0308]: mismatched types\n  --> tests/ui/track-diagnostics.rs:LL:CC\n   |\nLL | const S: A = B;\n   |              ^ expected `A`, found `B`\n   |\n   = note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC\n\nerror: aborting due to 1 previous error\n\nFor more information about this error, try `rustc --explain E0308`.\n"
  },
  {
    "path": "tests/ui/trailing_empty_array.rs",
    "content": "#![warn(clippy::trailing_empty_array)]\n#![allow(clippy::repr_packed_without_abi)]\n\n// Do lint:\n\nstruct RarelyUseful {\n    //~^ trailing_empty_array\n    field: i32,\n    last: [usize; 0],\n}\n\nstruct OnlyField {\n    //~^ trailing_empty_array\n    first_and_last: [usize; 0],\n}\n\nstruct GenericArrayType<T> {\n    //~^ trailing_empty_array\n    field: i32,\n    last: [T; 0],\n}\n\n#[must_use]\nstruct OnlyAnotherAttribute {\n    //~^ trailing_empty_array\n    field: i32,\n    last: [usize; 0],\n}\n\n#[derive(Debug)]\nstruct OnlyADeriveAttribute {\n    //~^ trailing_empty_array\n    field: i32,\n    last: [usize; 0],\n}\n\nconst ZERO: usize = 0;\nstruct ZeroSizedWithConst {\n    //~^ trailing_empty_array\n    field: i32,\n    last: [usize; ZERO],\n}\n\n#[allow(clippy::eq_op)]\nconst fn compute_zero() -> usize {\n    (4 + 6) - (2 * 5)\n}\nstruct ZeroSizedWithConstFunction {\n    //~^ trailing_empty_array\n    field: i32,\n    last: [usize; compute_zero()],\n}\n\nconst fn compute_zero_from_arg(x: usize) -> usize {\n    x - 1\n}\nstruct ZeroSizedWithConstFunction2 {\n    //~^ trailing_empty_array\n    field: i32,\n    last: [usize; compute_zero_from_arg(1)],\n}\n\nstruct ZeroSizedArrayWrapper([usize; 0]);\n//~^ trailing_empty_array\n\nstruct TupleStruct(i32, [usize; 0]);\n//~^ trailing_empty_array\n\nstruct LotsOfFields {\n    //~^ trailing_empty_array\n    f1: u32,\n    f2: u32,\n    f3: u32,\n    f4: u32,\n    f5: u32,\n    f6: u32,\n    f7: u32,\n    f8: u32,\n    f9: u32,\n    f10: u32,\n    f11: u32,\n    f12: u32,\n    f13: u32,\n    f14: u32,\n    f15: u32,\n    f16: u32,\n    last: [usize; 0],\n}\n\n// Don't lint\n\n#[repr(C)]\nstruct GoodReason {\n    field: i32,\n    last: [usize; 0],\n}\n\n#[repr(C)]\nstruct OnlyFieldWithReprC {\n    first_and_last: [usize; 0],\n}\n\nstruct NonZeroSizedArray {\n    field: i32,\n    last: [usize; 1],\n}\n\nstruct NotLastField {\n    f1: u32,\n    zero_sized: [usize; 0],\n    last: i32,\n}\n\nconst ONE: usize = 1;\nstruct NonZeroSizedWithConst {\n    field: i32,\n    last: [usize; ONE],\n}\n\n#[derive(Debug)]\n#[repr(C)]\nstruct AlsoADeriveAttribute {\n    field: i32,\n    last: [usize; 0],\n}\n\n#[must_use]\n#[repr(C)]\nstruct AlsoAnotherAttribute {\n    field: i32,\n    last: [usize; 0],\n}\n\n#[repr(packed)]\nstruct ReprPacked {\n    field: i32,\n    last: [usize; 0],\n}\n\n#[repr(C, packed)]\nstruct ReprCPacked {\n    field: i32,\n    last: [usize; 0],\n}\n\n#[repr(align(64))]\nstruct ReprAlign {\n    field: i32,\n    last: [usize; 0],\n}\n#[repr(C, align(64))]\nstruct ReprCAlign {\n    field: i32,\n    last: [usize; 0],\n}\n\n// NOTE: because of https://doc.rust-lang.org/stable/reference/type-layout.html#primitive-representation-of-enums-with-fields and I'm not sure when in the compilation pipeline that would happen\n#[repr(C)]\nenum DontLintAnonymousStructsFromDesugaring {\n    A(u32),\n    B(f32, [u64; 0]),\n    C { x: u32, y: [u64; 0] },\n}\n\n#[repr(C)]\nstruct TupleStructReprC(i32, [usize; 0]);\n\ntype NamedTuple = (i32, [usize; 0]);\n\nstruct ConstParamZeroDefault<const N: usize = 0> {\n    field: i32,\n    last: [usize; N],\n}\n\nstruct ConstParamNoDefault<const N: usize> {\n    field: i32,\n    last: [usize; N],\n}\n\nstruct ConstParamNonZeroDefault<const N: usize = 1> {\n    field: i32,\n    last: [usize; N],\n}\n\nstruct TwoGenericParams<T, const N: usize> {\n    field: i32,\n    last: [T; N],\n}\n\ntype A = ConstParamZeroDefault;\ntype B = ConstParamZeroDefault<0>;\ntype C = ConstParamNoDefault<0>;\ntype D = ConstParamNonZeroDefault<0>;\n\nfn main() {}\n\n#[cfg(test)]\nmod tests {\n    pub struct Friend {\n        age: u8,\n    }\n\n    #[test]\n    fn oldest_empty_is_none() {\n        struct Michael {\n            friends: [Friend; 0],\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/trailing_empty_array.stderr",
    "content": "error: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:6:1\n   |\nLL | / struct RarelyUseful {\nLL | |\nLL | |     field: i32,\nLL | |     last: [usize; 0],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `RarelyUseful` with `#[repr(C)]` or another `repr` attribute\n   = note: `-D clippy::trailing-empty-array` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::trailing_empty_array)]`\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:12:1\n   |\nLL | / struct OnlyField {\nLL | |\nLL | |     first_and_last: [usize; 0],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `OnlyField` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:17:1\n   |\nLL | / struct GenericArrayType<T> {\nLL | |\nLL | |     field: i32,\nLL | |     last: [T; 0],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `GenericArrayType` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:24:1\n   |\nLL | / struct OnlyAnotherAttribute {\nLL | |\nLL | |     field: i32,\nLL | |     last: [usize; 0],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `OnlyAnotherAttribute` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:31:1\n   |\nLL | / struct OnlyADeriveAttribute {\nLL | |\nLL | |     field: i32,\nLL | |     last: [usize; 0],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `OnlyADeriveAttribute` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:38:1\n   |\nLL | / struct ZeroSizedWithConst {\nLL | |\nLL | |     field: i32,\nLL | |     last: [usize; ZERO],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `ZeroSizedWithConst` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:48:1\n   |\nLL | / struct ZeroSizedWithConstFunction {\nLL | |\nLL | |     field: i32,\nLL | |     last: [usize; compute_zero()],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `ZeroSizedWithConstFunction` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:57:1\n   |\nLL | / struct ZeroSizedWithConstFunction2 {\nLL | |\nLL | |     field: i32,\nLL | |     last: [usize; compute_zero_from_arg(1)],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `ZeroSizedWithConstFunction2` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:63:1\n   |\nLL | struct ZeroSizedArrayWrapper([usize; 0]);\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider annotating `ZeroSizedArrayWrapper` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:66:1\n   |\nLL | struct TupleStruct(i32, [usize; 0]);\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider annotating `TupleStruct` with `#[repr(C)]` or another `repr` attribute\n\nerror: trailing zero-sized array in a struct which is not marked with a `repr` attribute\n  --> tests/ui/trailing_empty_array.rs:69:1\n   |\nLL | / struct LotsOfFields {\nLL | |\nLL | |     f1: u32,\nLL | |     f2: u32,\n...  |\nLL | |     last: [usize; 0],\nLL | | }\n   | |_^\n   |\n   = help: consider annotating `LotsOfFields` with `#[repr(C)]` or another `repr` attribute\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/trailing_zeros.fixed",
    "content": "#![allow(unused_parens)]\n#![warn(clippy::verbose_bit_mask)]\n\nfn main() {\n    let x: i32 = 42;\n    let _ = x.trailing_zeros() >= 4;\n    //~^ verbose_bit_mask\n\n    let _ = x.trailing_zeros() >= 5;\n    //~^ verbose_bit_mask\n\n    let _ = x & 0b1_1010 == 0; // do not lint\n    let _ = x & 1 == 0; // do not lint\n}\n"
  },
  {
    "path": "tests/ui/trailing_zeros.rs",
    "content": "#![allow(unused_parens)]\n#![warn(clippy::verbose_bit_mask)]\n\nfn main() {\n    let x: i32 = 42;\n    let _ = (x & 0b1111 == 0);\n    //~^ verbose_bit_mask\n\n    let _ = x & 0b1_1111 == 0;\n    //~^ verbose_bit_mask\n\n    let _ = x & 0b1_1010 == 0; // do not lint\n    let _ = x & 1 == 0; // do not lint\n}\n"
  },
  {
    "path": "tests/ui/trailing_zeros.stderr",
    "content": "error: bit mask could be simplified with a call to `trailing_zeros`\n  --> tests/ui/trailing_zeros.rs:6:13\n   |\nLL |     let _ = (x & 0b1111 == 0);\n   |             ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 4`\n   |\n   = note: `-D clippy::verbose-bit-mask` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::verbose_bit_mask)]`\n\nerror: bit mask could be simplified with a call to `trailing_zeros`\n  --> tests/ui/trailing_zeros.rs:9:13\n   |\nLL |     let _ = x & 0b1_1111 == 0;\n   |             ^^^^^^^^^^^^^^^^^ help: try: `x.trailing_zeros() >= 5`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/trait_duplication_in_bounds.fixed",
    "content": "#![deny(clippy::trait_duplication_in_bounds)]\n#![allow(unused)]\n#![feature(const_trait_impl)]\n\nuse std::any::Any;\n\nfn bad_foo<T: Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {\n    //~^ trait_duplication_in_bounds\n    unimplemented!();\n}\n\nfn bad_bar<T, U>(arg0: T, arg1: U)\nwhere\n    T: Clone + Copy,\n    //~^ trait_duplication_in_bounds\n    U: Clone + Copy,\n{\n    unimplemented!();\n}\n\nfn good_bar<T: Clone + Copy, U: Clone + Copy>(arg0: T, arg1: U) {\n    unimplemented!();\n}\n\nfn good_foo<T, U>(arg0: T, arg1: U)\nwhere\n    T: Clone + Copy,\n    U: Clone + Copy,\n{\n    unimplemented!();\n}\n\ntrait GoodSelfTraitBound: Clone + Copy {\n    fn f();\n}\n\ntrait GoodSelfWhereClause {\n    fn f()\n    where\n        Self: Clone + Copy;\n}\n\ntrait BadSelfTraitBound: Clone {\n    //~^ trait_duplication_in_bounds\n    fn f();\n}\n\ntrait BadSelfWhereClause {\n    fn f()\n    where\n        Self: Clone;\n    //~^ trait_duplication_in_bounds\n}\n\ntrait GoodTraitBound<T: Clone + Copy, U: Clone + Copy> {\n    fn f();\n}\n\ntrait GoodWhereClause<T, U> {\n    fn f()\n    where\n        T: Clone + Copy,\n        U: Clone + Copy;\n}\n\ntrait BadTraitBound<T: Clone + Copy, U: Clone + Copy> {\n    //~^ trait_duplication_in_bounds\n    fn f();\n}\n\ntrait BadWhereClause<T, U> {\n    fn f()\n    where\n        T: Clone + Copy,\n        //~^ trait_duplication_in_bounds\n        U: Clone + Copy;\n}\n\nstruct GoodStructBound<T: Clone + Copy, U: Clone + Copy> {\n    t: T,\n    u: U,\n}\n\nimpl<T: Clone + Copy, U: Clone + Copy> GoodTraitBound<T, U> for GoodStructBound<T, U> {\n    // this should not warn\n    fn f() {}\n}\n\nstruct GoodStructWhereClause;\n\nimpl<T, U> GoodTraitBound<T, U> for GoodStructWhereClause\nwhere\n    T: Clone + Copy,\n    U: Clone + Copy,\n{\n    // this should not warn\n    fn f() {}\n}\n\nfn no_error_separate_arg_bounds(program: impl AsRef<()>, dir: impl AsRef<()>, args: &[impl AsRef<()>]) {}\n\ntrait GenericTrait<T> {}\n\nfn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) {\n    unimplemented!();\n}\n\nfn bad_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) {\n    //~^ trait_duplication_in_bounds\n    unimplemented!();\n}\n\nmod foo {\n    pub trait Clone {}\n}\n\nfn qualified_path<T: std::clone::Clone + foo::Clone>(arg0: T) {\n    //~^ trait_duplication_in_bounds\n    unimplemented!();\n}\n\nfn good_trait_object(arg0: &(dyn Any + Send)) {\n    unimplemented!();\n}\n\nfn bad_trait_object(arg0: &(dyn Any + Send)) {\n    //~^ trait_duplication_in_bounds\n    unimplemented!();\n}\n\ntrait Proj {\n    type S;\n}\n\nimpl Proj for () {\n    type S = ();\n}\n\nimpl Proj for i32 {\n    type S = i32;\n}\n\ntrait Base<T> {\n    fn is_base(&self);\n}\n\ntrait Derived<B: Proj>: Base<B::S> + Base<()> {\n    fn is_derived(&self);\n}\n\nfn f<P: Proj>(obj: &dyn Derived<P>) {\n    obj.is_derived();\n    Base::<P::S>::is_base(obj);\n    Base::<()>::is_base(obj);\n}\n\n// #13476\ntrait Value<const N: usize> {}\nfn const_generic<T: Value<0> + Value<1>>() {}\n\n// #11067 and #9626\nfn assoc_tys_generics<'a, 'b, T, U>()\nwhere\n    T: IntoIterator<Item = ()> + IntoIterator<Item = i32>,\n    U: From<&'a str> + From<&'b [u16]>,\n{\n}\n\n// #13476\nconst trait ConstTrait {}\nconst fn const_trait_bounds_good<T: ConstTrait + [const] ConstTrait>() {}\n\nconst fn const_trait_bounds_bad<T: [const] ConstTrait>() {}\n//~^ trait_duplication_in_bounds\n\nfn projections<T, U, V>()\nwhere\n    U: ToOwned,\n    V: ToOwned,\n    T: IntoIterator<Item = U::Owned>,\n    //~^ trait_duplication_in_bounds\n    V: IntoIterator<Item = U::Owned> + IntoIterator<Item = V::Owned>,\n{\n}\n\nfn main() {\n    let _x: fn(_) = f::<()>;\n    let _x: fn(_) = f::<i32>;\n}\n\n// #13706\nfn assoc_tys_bounds<T>()\nwhere\n    T: Iterator<Item: Clone> + Iterator<Item: Clone>,\n{\n}\n"
  },
  {
    "path": "tests/ui/trait_duplication_in_bounds.rs",
    "content": "#![deny(clippy::trait_duplication_in_bounds)]\n#![allow(unused)]\n#![feature(const_trait_impl)]\n\nuse std::any::Any;\n\nfn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {\n    //~^ trait_duplication_in_bounds\n    unimplemented!();\n}\n\nfn bad_bar<T, U>(arg0: T, arg1: U)\nwhere\n    T: Clone + Clone + Clone + Copy,\n    //~^ trait_duplication_in_bounds\n    U: Clone + Copy,\n{\n    unimplemented!();\n}\n\nfn good_bar<T: Clone + Copy, U: Clone + Copy>(arg0: T, arg1: U) {\n    unimplemented!();\n}\n\nfn good_foo<T, U>(arg0: T, arg1: U)\nwhere\n    T: Clone + Copy,\n    U: Clone + Copy,\n{\n    unimplemented!();\n}\n\ntrait GoodSelfTraitBound: Clone + Copy {\n    fn f();\n}\n\ntrait GoodSelfWhereClause {\n    fn f()\n    where\n        Self: Clone + Copy;\n}\n\ntrait BadSelfTraitBound: Clone + Clone + Clone {\n    //~^ trait_duplication_in_bounds\n    fn f();\n}\n\ntrait BadSelfWhereClause {\n    fn f()\n    where\n        Self: Clone + Clone + Clone;\n    //~^ trait_duplication_in_bounds\n}\n\ntrait GoodTraitBound<T: Clone + Copy, U: Clone + Copy> {\n    fn f();\n}\n\ntrait GoodWhereClause<T, U> {\n    fn f()\n    where\n        T: Clone + Copy,\n        U: Clone + Copy;\n}\n\ntrait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {\n    //~^ trait_duplication_in_bounds\n    fn f();\n}\n\ntrait BadWhereClause<T, U> {\n    fn f()\n    where\n        T: Clone + Clone + Clone + Copy,\n        //~^ trait_duplication_in_bounds\n        U: Clone + Copy;\n}\n\nstruct GoodStructBound<T: Clone + Copy, U: Clone + Copy> {\n    t: T,\n    u: U,\n}\n\nimpl<T: Clone + Copy, U: Clone + Copy> GoodTraitBound<T, U> for GoodStructBound<T, U> {\n    // this should not warn\n    fn f() {}\n}\n\nstruct GoodStructWhereClause;\n\nimpl<T, U> GoodTraitBound<T, U> for GoodStructWhereClause\nwhere\n    T: Clone + Copy,\n    U: Clone + Copy,\n{\n    // this should not warn\n    fn f() {}\n}\n\nfn no_error_separate_arg_bounds(program: impl AsRef<()>, dir: impl AsRef<()>, args: &[impl AsRef<()>]) {}\n\ntrait GenericTrait<T> {}\n\nfn good_generic<T: GenericTrait<u64> + GenericTrait<u32>>(arg0: T) {\n    unimplemented!();\n}\n\nfn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {\n    //~^ trait_duplication_in_bounds\n    unimplemented!();\n}\n\nmod foo {\n    pub trait Clone {}\n}\n\nfn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {\n    //~^ trait_duplication_in_bounds\n    unimplemented!();\n}\n\nfn good_trait_object(arg0: &(dyn Any + Send)) {\n    unimplemented!();\n}\n\nfn bad_trait_object(arg0: &(dyn Any + Send + Send)) {\n    //~^ trait_duplication_in_bounds\n    unimplemented!();\n}\n\ntrait Proj {\n    type S;\n}\n\nimpl Proj for () {\n    type S = ();\n}\n\nimpl Proj for i32 {\n    type S = i32;\n}\n\ntrait Base<T> {\n    fn is_base(&self);\n}\n\ntrait Derived<B: Proj>: Base<B::S> + Base<()> {\n    fn is_derived(&self);\n}\n\nfn f<P: Proj>(obj: &dyn Derived<P>) {\n    obj.is_derived();\n    Base::<P::S>::is_base(obj);\n    Base::<()>::is_base(obj);\n}\n\n// #13476\ntrait Value<const N: usize> {}\nfn const_generic<T: Value<0> + Value<1>>() {}\n\n// #11067 and #9626\nfn assoc_tys_generics<'a, 'b, T, U>()\nwhere\n    T: IntoIterator<Item = ()> + IntoIterator<Item = i32>,\n    U: From<&'a str> + From<&'b [u16]>,\n{\n}\n\n// #13476\nconst trait ConstTrait {}\nconst fn const_trait_bounds_good<T: ConstTrait + [const] ConstTrait>() {}\n\nconst fn const_trait_bounds_bad<T: [const] ConstTrait + [const] ConstTrait>() {}\n//~^ trait_duplication_in_bounds\n\nfn projections<T, U, V>()\nwhere\n    U: ToOwned,\n    V: ToOwned,\n    T: IntoIterator<Item = U::Owned> + IntoIterator<Item = U::Owned>,\n    //~^ trait_duplication_in_bounds\n    V: IntoIterator<Item = U::Owned> + IntoIterator<Item = V::Owned>,\n{\n}\n\nfn main() {\n    let _x: fn(_) = f::<()>;\n    let _x: fn(_) = f::<i32>;\n}\n\n// #13706\nfn assoc_tys_bounds<T>()\nwhere\n    T: Iterator<Item: Clone> + Iterator<Item: Clone>,\n{\n}\n"
  },
  {
    "path": "tests/ui/trait_duplication_in_bounds.stderr",
    "content": "error: these bounds contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:7:15\n   |\nLL | fn bad_foo<T: Clone + Clone + Clone + Copy, U: Clone + Copy>(arg0: T, argo1: U) {\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`\n   |\nnote: the lint level is defined here\n  --> tests/ui/trait_duplication_in_bounds.rs:1:9\n   |\nLL | #![deny(clippy::trait_duplication_in_bounds)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: these where clauses contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:14:8\n   |\nLL |     T: Clone + Clone + Clone + Copy,\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`\n\nerror: these bounds contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:43:26\n   |\nLL | trait BadSelfTraitBound: Clone + Clone + Clone {\n   |                          ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`\n\nerror: these where clauses contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:51:15\n   |\nLL |         Self: Clone + Clone + Clone;\n   |               ^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone`\n\nerror: these bounds contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:66:24\n   |\nLL | trait BadTraitBound<T: Clone + Clone + Clone + Copy, U: Clone + Copy> {\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`\n\nerror: these where clauses contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:74:12\n   |\nLL |         T: Clone + Clone + Clone + Copy,\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Clone + Copy`\n\nerror: these bounds contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:108:19\n   |\nLL | fn bad_generic<T: GenericTrait<u64> + GenericTrait<u32> + GenericTrait<u64>>(arg0: T) {\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `GenericTrait<u64> + GenericTrait<u32>`\n\nerror: these bounds contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:117:22\n   |\nLL | fn qualified_path<T: std::clone::Clone + Clone + foo::Clone>(arg0: T) {\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::clone::Clone + foo::Clone`\n\nerror: this trait bound is already specified in trait declaration\n  --> tests/ui/trait_duplication_in_bounds.rs:126:33\n   |\nLL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) {\n   |                                 ^^^^^^^^^^^^^^^^^ help: try: `Any + Send`\n\nerror: these bounds contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:173:36\n   |\nLL | const fn const_trait_bounds_bad<T: [const] ConstTrait + [const] ConstTrait>() {}\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[const] ConstTrait`\n\nerror: these where clauses contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds.rs:180:8\n   |\nLL |     T: IntoIterator<Item = U::Owned> + IntoIterator<Item = U::Owned>,\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator<Item = U::Owned>`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/trait_duplication_in_bounds_assoc_const_eq.fixed",
    "content": "#![deny(clippy::trait_duplication_in_bounds)]\n#![expect(incomplete_features)]\n#![feature(min_generic_const_args)]\n\ntrait AssocConstTrait {\n    type const ASSOC: usize;\n}\nfn assoc_const_args<T>()\nwhere\n    T: AssocConstTrait<ASSOC = 0>,\n    //~^ trait_duplication_in_bounds\n{\n}\n"
  },
  {
    "path": "tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs",
    "content": "#![deny(clippy::trait_duplication_in_bounds)]\n#![expect(incomplete_features)]\n#![feature(min_generic_const_args)]\n\ntrait AssocConstTrait {\n    type const ASSOC: usize;\n}\nfn assoc_const_args<T>()\nwhere\n    T: AssocConstTrait<ASSOC = 0> + AssocConstTrait<ASSOC = 0>,\n    //~^ trait_duplication_in_bounds\n{\n}\n"
  },
  {
    "path": "tests/ui/trait_duplication_in_bounds_assoc_const_eq.stderr",
    "content": "error: these where clauses contain repeated elements\n  --> tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs:10:8\n   |\nLL |     T: AssocConstTrait<ASSOC = 0> + AssocConstTrait<ASSOC = 0>,\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait<ASSOC = 0>`\n   |\nnote: the lint level is defined here\n  --> tests/ui/trait_duplication_in_bounds_assoc_const_eq.rs:1:9\n   |\nLL | #![deny(clippy::trait_duplication_in_bounds)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/trait_duplication_in_bounds_unfixable.rs",
    "content": "#![deny(clippy::trait_duplication_in_bounds)]\n#![allow(clippy::multiple_bound_locations)]\n\nuse std::collections::BTreeMap;\nuse std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};\n\nfn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)\n//~^ trait_duplication_in_bounds\n//~| trait_duplication_in_bounds\nwhere\n    T: Clone,\n    T: Default,\n{\n    unimplemented!();\n}\n\nfn good_bar<T: Clone + Default>(arg: T) {\n    unimplemented!();\n}\n\nfn good_foo<T>(arg: T)\nwhere\n    T: Clone + Default,\n{\n    unimplemented!();\n}\n\nfn good_foobar<T: Default>(arg: T)\nwhere\n    T: Clone,\n{\n    unimplemented!();\n}\n\ntrait T: Default {\n    fn f()\n    where\n        Self: Default;\n    //~^ trait_duplication_in_bounds\n}\n\ntrait U: Default {\n    fn f()\n    where\n        Self: Clone;\n}\n\ntrait ZZ: Default {\n    fn g();\n    fn h();\n    fn f()\n    where\n        Self: Default + Clone;\n    //~^ trait_duplication_in_bounds\n}\n\ntrait BadTrait: Default + Clone {\n    fn f()\n    where\n        Self: Default + Clone;\n    //~^ trait_duplication_in_bounds\n    //~| trait_duplication_in_bounds\n\n    fn g()\n    where\n        Self: Default;\n    //~^ trait_duplication_in_bounds\n\n    fn h()\n    where\n        Self: Copy;\n}\n\n#[derive(Default, Clone)]\nstruct Life;\n\nimpl T for Life {\n    // this should not warn\n    fn f() {}\n}\n\nimpl U for Life {\n    // this should not warn\n    fn f() {}\n}\n\n// should not warn\ntrait Iter: Iterator {\n    fn into_group_btreemap<K, V>(self) -> BTreeMap<K, Vec<V>>\n    where\n        Self: Iterator<Item = (K, V)> + Sized,\n        K: Ord + Eq,\n    {\n        unimplemented!();\n    }\n}\n\nstruct Foo;\n\ntrait FooIter: Iterator<Item = Foo> {\n    fn bar()\n    where\n        Self: Iterator<Item = Foo>,\n        //~^ trait_duplication_in_bounds\n    {\n    }\n}\n\n// The below should not lint and exist to guard against false positives\nfn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}\n\npub mod one {\n    #[derive(Clone, Debug)]\n    struct MultiProductIter<I>\n    where\n        I: Iterator + Clone,\n        I::Item: Clone,\n    {\n        _marker: I,\n    }\n\n    pub struct MultiProduct<I>(Vec<MultiProductIter<I>>)\n    where\n        I: Iterator + Clone,\n        I::Item: Clone;\n\n    pub fn multi_cartesian_product<H>(_: H) -> MultiProduct<<H::Item as IntoIterator>::IntoIter>\n    where\n        H: Iterator,\n        H::Item: IntoIterator,\n        <H::Item as IntoIterator>::IntoIter: Clone,\n        <H::Item as IntoIterator>::Item: Clone,\n    {\n        todo!()\n    }\n}\n\npub mod two {\n    use std::iter::Peekable;\n\n    pub struct MergeBy<I, J, F>\n    where\n        I: Iterator,\n        J: Iterator<Item = I::Item>,\n    {\n        _i: Peekable<I>,\n        _j: Peekable<J>,\n        _f: F,\n    }\n\n    impl<I, J, F> Clone for MergeBy<I, J, F>\n    where\n        I: Iterator,\n        J: Iterator<Item = I::Item>,\n        std::iter::Peekable<I>: Clone,\n        std::iter::Peekable<J>: Clone,\n        F: Clone,\n    {\n        fn clone(&self) -> Self {\n            Self {\n                _i: self._i.clone(),\n                _j: self._j.clone(),\n                _f: self._f.clone(),\n            }\n        }\n    }\n}\n\npub trait Trait {}\n\npub fn f(_a: impl Trait, _b: impl Trait) {}\n\npub trait ImplTrait<T> {}\n\nimpl<A, B> ImplTrait<(A, B)> for Foo where Foo: ImplTrait<A> + ImplTrait<B> {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/trait_duplication_in_bounds_unfixable.stderr",
    "content": "error: this trait bound is already specified in the where clause\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:7:15\n   |\nLL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)\n   |               ^^^^^\n   |\n   = help: consider removing this trait bound\nnote: the lint level is defined here\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:1:9\n   |\nLL | #![deny(clippy::trait_duplication_in_bounds)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this trait bound is already specified in the where clause\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:7:23\n   |\nLL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z)\n   |                       ^^^^^^^\n   |\n   = help: consider removing this trait bound\n\nerror: this trait bound is already specified in trait declaration\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:38:15\n   |\nLL |         Self: Default;\n   |               ^^^^^^^\n   |\n   = help: consider removing this trait bound\n\nerror: this trait bound is already specified in trait declaration\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:53:15\n   |\nLL |         Self: Default + Clone;\n   |               ^^^^^^^\n   |\n   = help: consider removing this trait bound\n\nerror: this trait bound is already specified in trait declaration\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:60:15\n   |\nLL |         Self: Default + Clone;\n   |               ^^^^^^^\n   |\n   = help: consider removing this trait bound\n\nerror: this trait bound is already specified in trait declaration\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:60:25\n   |\nLL |         Self: Default + Clone;\n   |                         ^^^^^\n   |\n   = help: consider removing this trait bound\n\nerror: this trait bound is already specified in trait declaration\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:66:15\n   |\nLL |         Self: Default;\n   |               ^^^^^^^\n   |\n   = help: consider removing this trait bound\n\nerror: this trait bound is already specified in trait declaration\n  --> tests/ui/trait_duplication_in_bounds_unfixable.rs:103:15\n   |\nLL |         Self: Iterator<Item = Foo>,\n   |               ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing this trait bound\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute.rs",
    "content": "#![feature(f128)]\n#![feature(f16)]\n#![allow(\n    dead_code,\n    clippy::borrow_as_ptr,\n    unnecessary_transmutes,\n    integer_to_ptr_transmutes,\n    clippy::needless_lifetimes,\n    clippy::missing_transmute_annotations\n)]\n//@no-rustfix\nextern crate core;\n\nuse std::mem::transmute as my_transmute;\nuse std::vec::Vec as MyVec;\n\nfn my_int() -> Usize {\n    Usize(42)\n}\n\nfn my_vec() -> MyVec<i32> {\n    vec![]\n}\n\n#[allow(clippy::needless_lifetimes, clippy::transmute_ptr_to_ptr)]\n#[warn(clippy::useless_transmute)]\nunsafe fn _generic<'a, T, U: 'a>(t: &'a T) {\n    unsafe {\n        // FIXME: should lint\n        // let _: &'a T = core::mem::transmute(t);\n\n        let _: &'a U = core::mem::transmute(t);\n\n        let _: *const T = core::mem::transmute(t);\n        //~^ useless_transmute\n\n        let _: *mut T = core::mem::transmute(t);\n        //~^ useless_transmute\n\n        let _: *const U = core::mem::transmute(t);\n        //~^ useless_transmute\n    }\n}\n\n#[warn(clippy::useless_transmute)]\nfn useless() {\n    unsafe {\n        let _: Vec<i32> = core::mem::transmute(my_vec());\n        //~^ useless_transmute\n\n        let _: Vec<i32> = core::mem::transmute(my_vec());\n        //~^ useless_transmute\n\n        let _: Vec<i32> = std::mem::transmute(my_vec());\n        //~^ useless_transmute\n\n        let _: Vec<i32> = std::mem::transmute(my_vec());\n        //~^ useless_transmute\n\n        let _: Vec<i32> = my_transmute(my_vec());\n        //~^ useless_transmute\n\n        let _: *const usize = std::mem::transmute(5_isize);\n\n        let _ = std::ptr::dangling::<usize>();\n\n        let _: *const usize = std::mem::transmute(1 + 1usize);\n\n        let _ = (1 + 1_usize) as *const usize;\n    }\n\n    unsafe fn _f<'a, 'b>(x: &'a u32) -> &'b u32 {\n        unsafe { std::mem::transmute(x) }\n    }\n\n    unsafe fn _f2<'a, 'b>(x: *const (dyn Iterator<Item = u32> + 'a)) -> *const (dyn Iterator<Item = u32> + 'b) {\n        unsafe { std::mem::transmute(x) }\n    }\n\n    unsafe fn _f3<'a, 'b>(x: fn(&'a u32)) -> fn(&'b u32) {\n        unsafe { std::mem::transmute(x) }\n    }\n\n    unsafe fn _f4<'a, 'b>(x: std::borrow::Cow<'a, str>) -> std::borrow::Cow<'b, str> {\n        unsafe { std::mem::transmute(x) }\n    }\n}\n\nstruct Usize(usize);\n\n#[warn(clippy::crosspointer_transmute)]\nfn crosspointer() {\n    let mut int: Usize = Usize(0);\n    let int_const_ptr: *const Usize = &int as *const Usize;\n    let int_mut_ptr: *mut Usize = &mut int as *mut Usize;\n\n    unsafe {\n        let _: Usize = core::mem::transmute(int_const_ptr);\n        //~^ crosspointer_transmute\n\n        let _: Usize = core::mem::transmute(int_mut_ptr);\n        //~^ crosspointer_transmute\n\n        let _: *const Usize = core::mem::transmute(my_int());\n        //~^ crosspointer_transmute\n\n        let _: *mut Usize = core::mem::transmute(my_int());\n        //~^ crosspointer_transmute\n    }\n}\n\n#[warn(clippy::transmute_int_to_bool)]\nfn int_to_bool() {\n    let _: bool = unsafe { std::mem::transmute(0_u8) };\n    //~^ transmute_int_to_bool\n}\n\nfn bytes_to_str(mb: &mut [u8]) {\n    const B: &[u8] = b\"\";\n\n    let _: &str = unsafe { std::mem::transmute(B) };\n    //~^ transmute_bytes_to_str\n\n    let _: &mut str = unsafe { std::mem::transmute(mb) };\n    //~^ transmute_bytes_to_str\n\n    const _: &str = unsafe { std::mem::transmute(B) };\n    //~^ transmute_bytes_to_str\n}\n\nfn issue16104() {\n    let b = vec![1_u8, 2_u8];\n    macro_rules! take_ref {\n        ($x:expr) => {\n            $x.as_slice()\n        };\n    }\n    unsafe {\n        let _: &str = std::mem::transmute(take_ref!(b));\n        //~^ transmute_bytes_to_str\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/transmute.stderr",
    "content": "error: transmute from a reference to a pointer\n  --> tests/ui/transmute.rs:34:27\n   |\nLL |         let _: *const T = core::mem::transmute(t);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T`\n   |\n   = note: `-D clippy::useless-transmute` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]`\n\nerror: transmute from a reference to a pointer\n  --> tests/ui/transmute.rs:37:25\n   |\nLL |         let _: *mut T = core::mem::transmute(t);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T`\n\nerror: transmute from a reference to a pointer\n  --> tests/ui/transmute.rs:40:27\n   |\nLL |         let _: *const U = core::mem::transmute(t);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U`\n\nerror: transmute from a type (`std::vec::Vec<i32>`) to itself\n  --> tests/ui/transmute.rs:48:27\n   |\nLL |         let _: Vec<i32> = core::mem::transmute(my_vec());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a type (`std::vec::Vec<i32>`) to itself\n  --> tests/ui/transmute.rs:51:27\n   |\nLL |         let _: Vec<i32> = core::mem::transmute(my_vec());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a type (`std::vec::Vec<i32>`) to itself\n  --> tests/ui/transmute.rs:54:27\n   |\nLL |         let _: Vec<i32> = std::mem::transmute(my_vec());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a type (`std::vec::Vec<i32>`) to itself\n  --> tests/ui/transmute.rs:57:27\n   |\nLL |         let _: Vec<i32> = std::mem::transmute(my_vec());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a type (`std::vec::Vec<i32>`) to itself\n  --> tests/ui/transmute.rs:60:27\n   |\nLL |         let _: Vec<i32> = my_transmute(my_vec());\n   |                           ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a type (`*const Usize`) to the type that it points to (`Usize`)\n  --> tests/ui/transmute.rs:98:24\n   |\nLL |         let _: Usize = core::mem::transmute(int_const_ptr);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::crosspointer-transmute` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::crosspointer_transmute)]`\n\nerror: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`)\n  --> tests/ui/transmute.rs:101:24\n   |\nLL |         let _: Usize = core::mem::transmute(int_mut_ptr);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`)\n  --> tests/ui/transmute.rs:104:31\n   |\nLL |         let _: *const Usize = core::mem::transmute(my_int());\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)\n  --> tests/ui/transmute.rs:107:29\n   |\nLL |         let _: *mut Usize = core::mem::transmute(my_int());\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a `u8` to a `bool`\n  --> tests/ui/transmute.rs:114:28\n   |\nLL |     let _: bool = unsafe { std::mem::transmute(0_u8) };\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`\n   |\n   = note: `-D clippy::transmute-int-to-bool` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]`\n\nerror: transmute from a `&[u8]` to a `&str`\n  --> tests/ui/transmute.rs:121:28\n   |\nLL |     let _: &str = unsafe { std::mem::transmute(B) };\n   |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`\n   |\n   = note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`\n\nerror: transmute from a `&mut [u8]` to a `&mut str`\n  --> tests/ui/transmute.rs:124:32\n   |\nLL |     let _: &mut str = unsafe { std::mem::transmute(mb) };\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`\n\nerror: transmute from a `&[u8]` to a `&str`\n  --> tests/ui/transmute.rs:127:30\n   |\nLL |     const _: &str = unsafe { std::mem::transmute(B) };\n   |                              ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`\n\nerror: transmute from a `&[u8]` to a `&str`\n  --> tests/ui/transmute.rs:139:23\n   |\nLL |         let _: &str = std::mem::transmute(take_ref!(b));\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(take_ref!(b)).unwrap()`\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_32bit.rs",
    "content": "//@ignore-bitwidth: 64\n\n#[warn(clippy::wrong_transmute)]\nfn main() {\n    unsafe {\n        let _: *const usize = std::mem::transmute(6.0f32); //~ wrong_transmute\n\n        let _: *mut usize = std::mem::transmute(6.0f32); //~ wrong_transmute\n\n        let _: *const usize = std::mem::transmute('x'); //~ wrong_transmute\n\n        let _: *mut usize = std::mem::transmute('x'); //~ wrong_transmute\n    }\n}\n"
  },
  {
    "path": "tests/ui/transmute_32bit.stderr",
    "content": "error: transmute from a `f32` to a pointer\n  --> tests/ui/transmute_32bit.rs:6:31\n   |\nLL |         let _: *const usize = std::mem::transmute(6.0f32);\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::wrong-transmute` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wrong_transmute)]`\n\nerror: transmute from a `f32` to a pointer\n  --> tests/ui/transmute_32bit.rs:8:29\n   |\nLL |         let _: *mut usize = std::mem::transmute(6.0f32);\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a `char` to a pointer\n  --> tests/ui/transmute_32bit.rs:10:31\n   |\nLL |         let _: *const usize = std::mem::transmute('x');\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a `char` to a pointer\n  --> tests/ui/transmute_32bit.rs:12:29\n   |\nLL |         let _: *mut usize = std::mem::transmute('x');\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_64bit.rs",
    "content": "//@ignore-bitwidth: 32\n\n#[warn(clippy::wrong_transmute)]\nfn main() {\n    unsafe {\n        let _: *const usize = std::mem::transmute(6.0f64);\n        //~^ wrong_transmute\n\n        let _: *mut usize = std::mem::transmute(6.0f64);\n        //~^ wrong_transmute\n    }\n}\n"
  },
  {
    "path": "tests/ui/transmute_64bit.stderr",
    "content": "error: transmute from a `f64` to a pointer\n  --> tests/ui/transmute_64bit.rs:6:31\n   |\nLL |         let _: *const usize = std::mem::transmute(6.0f64);\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::wrong-transmute` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wrong_transmute)]`\n\nerror: transmute from a `f64` to a pointer\n  --> tests/ui/transmute_64bit.rs:9:29\n   |\nLL |         let _: *mut usize = std::mem::transmute(6.0f64);\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_collection.rs",
    "content": "#![warn(clippy::unsound_collection_transmute)]\n#![allow(clippy::missing_transmute_annotations)]\n\nuse std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};\nuse std::mem::{MaybeUninit, transmute};\n\nfn main() {\n    unsafe {\n        // wrong size\n        let _ = transmute::<_, Vec<u32>>(vec![0u8]);\n        //~^ unsound_collection_transmute\n\n        // wrong layout\n        let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]);\n        //~^ unsound_collection_transmute\n\n        // wrong size\n        let _ = transmute::<_, VecDeque<u32>>(VecDeque::<u8>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong layout\n        let _ = transmute::<_, VecDeque<u32>>(VecDeque::<[u8; 4]>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong size\n        let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<u8>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong layout\n        let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<[u8; 4]>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong size\n        let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<u8>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong layout\n        let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<[u8; 4]>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong size\n        let _ = transmute::<_, HashSet<u32>>(HashSet::<u8>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong layout\n        let _ = transmute::<_, HashSet<u32>>(HashSet::<[u8; 4]>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong size\n        let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, u8>::new());\n        //~^ unsound_collection_transmute\n\n        let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u32, u32>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong layout\n        let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, [u8; 4]>::new());\n        //~^ unsound_collection_transmute\n\n        let _ = transmute::<_, BTreeMap<u32, u32>>(BTreeMap::<[u8; 4], u32>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong size\n        let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, u8>::new());\n        //~^ unsound_collection_transmute\n\n        let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u32, u32>::new());\n        //~^ unsound_collection_transmute\n\n        // wrong layout\n        let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, [u8; 4]>::new());\n        //~^ unsound_collection_transmute\n\n        let _ = transmute::<_, HashMap<u32, u32>>(HashMap::<[u8; 4], u32>::new());\n        //~^ unsound_collection_transmute\n\n        let _ = transmute::<_, Vec<u8>>(Vec::<MaybeUninit<u8>>::new());\n        let _ = transmute::<_, Vec<*mut u32>>(Vec::<Box<u32>>::new());\n    }\n}\n"
  },
  {
    "path": "tests/ui/transmute_collection.stderr",
    "content": "error: transmute from `std::vec::Vec<u8>` to `std::vec::Vec<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:10:17\n   |\nLL |         let _ = transmute::<_, Vec<u32>>(vec![0u8]);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unsound-collection-transmute` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unsound_collection_transmute)]`\n\nerror: transmute from `std::vec::Vec<u32>` to `std::vec::Vec<[u8; 4]>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:14:17\n   |\nLL |         let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::VecDeque<u8>` to `std::collections::VecDeque<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:18:17\n   |\nLL |         let _ = transmute::<_, VecDeque<u32>>(VecDeque::<u8>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::VecDeque<[u8; 4]>` to `std::collections::VecDeque<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:22:17\n   |\nLL |         let _ = transmute::<_, VecDeque<u32>>(VecDeque::<[u8; 4]>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::BinaryHeap<u8>` to `std::collections::BinaryHeap<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:26:17\n   |\nLL |         let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<u8>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::BinaryHeap<[u8; 4]>` to `std::collections::BinaryHeap<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:30:17\n   |\nLL |         let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<[u8; 4]>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::BTreeSet<u8>` to `std::collections::BTreeSet<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:34:17\n   |\nLL |         let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<u8>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::BTreeSet<[u8; 4]>` to `std::collections::BTreeSet<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:38:17\n   |\nLL |         let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<[u8; 4]>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::HashSet<u8>` to `std::collections::HashSet<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:42:17\n   |\nLL |         let _ = transmute::<_, HashSet<u32>>(HashSet::<u8>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::HashSet<[u8; 4]>` to `std::collections::HashSet<u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:46:17\n   |\nLL |         let _ = transmute::<_, HashSet<u32>>(HashSet::<[u8; 4]>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::BTreeMap<u8, u8>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:50:17\n   |\nLL |         let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, u8>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::BTreeMap<u32, u32>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:53:17\n   |\nLL |         let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u32, u32>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::BTreeMap<u8, [u8; 4]>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:57:17\n   |\nLL |         let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, [u8; 4]>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::BTreeMap<[u8; 4], u32>` to `std::collections::BTreeMap<u32, u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:60:17\n   |\nLL |         let _ = transmute::<_, BTreeMap<u32, u32>>(BTreeMap::<[u8; 4], u32>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::HashMap<u8, u8>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:64:17\n   |\nLL |         let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, u8>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::HashMap<u32, u32>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:67:17\n   |\nLL |         let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u32, u32>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::HashMap<u8, [u8; 4]>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:71:17\n   |\nLL |         let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, [u8; 4]>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `std::collections::HashMap<[u8; 4], u32>` to `std::collections::HashMap<u32, u32>` with mismatched layout is unsound\n  --> tests/ui/transmute_collection.rs:74:17\n   |\nLL |         let _ = transmute::<_, HashMap<u32, u32>>(HashMap::<[u8; 4], u32>::new());\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_int_to_non_zero.fixed",
    "content": "#![warn(clippy::transmute_int_to_non_zero)]\n#![allow(clippy::missing_transmute_annotations)]\n\nuse core::num::NonZero;\n\nfn main() {\n    let int_u8: u8 = 1;\n    let int_u16: u16 = 1;\n    let int_u32: u32 = 1;\n    let int_u64: u64 = 1;\n    let int_u128: u128 = 1;\n\n    let int_i8: i8 = 1;\n    let int_i16: i16 = 1;\n    let int_i32: i32 = 1;\n    let int_i64: i64 = 1;\n    let int_i128: i128 = 1;\n\n    let _: NonZero<u8> = unsafe { NonZero::new_unchecked(int_u8) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u16> = unsafe { NonZero::new_unchecked(int_u16) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u32> = unsafe { NonZero::new_unchecked(int_u32) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u64> = unsafe { NonZero::new_unchecked(int_u64) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u128> = unsafe { NonZero::new_unchecked(int_u128) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i8> = unsafe { NonZero::new_unchecked(int_i8) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i16> = unsafe { NonZero::new_unchecked(int_i16) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i32> = unsafe { NonZero::new_unchecked(int_i32) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i64> = unsafe { NonZero::new_unchecked(int_i64) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i128> = unsafe { NonZero::new_unchecked(int_i128) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u8> = unsafe { NonZero::new_unchecked(int_u8) };\n    let _: NonZero<u16> = unsafe { NonZero::new_unchecked(int_u16) };\n    let _: NonZero<u32> = unsafe { NonZero::new_unchecked(int_u32) };\n    let _: NonZero<u64> = unsafe { NonZero::new_unchecked(int_u64) };\n    let _: NonZero<u128> = unsafe { NonZero::new_unchecked(int_u128) };\n\n    let _: NonZero<i8> = unsafe { NonZero::new_unchecked(int_i8) };\n    let _: NonZero<i16> = unsafe { NonZero::new_unchecked(int_i16) };\n    let _: NonZero<i32> = unsafe { NonZero::new_unchecked(int_i32) };\n    let _: NonZero<i64> = unsafe { NonZero::new_unchecked(int_i64) };\n    let _: NonZero<i128> = unsafe { NonZero::new_unchecked(int_i128) };\n}\n"
  },
  {
    "path": "tests/ui/transmute_int_to_non_zero.rs",
    "content": "#![warn(clippy::transmute_int_to_non_zero)]\n#![allow(clippy::missing_transmute_annotations)]\n\nuse core::num::NonZero;\n\nfn main() {\n    let int_u8: u8 = 1;\n    let int_u16: u16 = 1;\n    let int_u32: u32 = 1;\n    let int_u64: u64 = 1;\n    let int_u128: u128 = 1;\n\n    let int_i8: i8 = 1;\n    let int_i16: i16 = 1;\n    let int_i32: i32 = 1;\n    let int_i64: i64 = 1;\n    let int_i128: i128 = 1;\n\n    let _: NonZero<u8> = unsafe { std::mem::transmute(int_u8) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u16> = unsafe { std::mem::transmute(int_u16) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u32> = unsafe { std::mem::transmute(int_u32) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u64> = unsafe { std::mem::transmute(int_u64) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u128> = unsafe { std::mem::transmute(int_u128) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i8> = unsafe { std::mem::transmute(int_i8) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i16> = unsafe { std::mem::transmute(int_i16) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i32> = unsafe { std::mem::transmute(int_i32) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i64> = unsafe { std::mem::transmute(int_i64) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<i128> = unsafe { std::mem::transmute(int_i128) };\n    //~^ transmute_int_to_non_zero\n\n    let _: NonZero<u8> = unsafe { NonZero::new_unchecked(int_u8) };\n    let _: NonZero<u16> = unsafe { NonZero::new_unchecked(int_u16) };\n    let _: NonZero<u32> = unsafe { NonZero::new_unchecked(int_u32) };\n    let _: NonZero<u64> = unsafe { NonZero::new_unchecked(int_u64) };\n    let _: NonZero<u128> = unsafe { NonZero::new_unchecked(int_u128) };\n\n    let _: NonZero<i8> = unsafe { NonZero::new_unchecked(int_i8) };\n    let _: NonZero<i16> = unsafe { NonZero::new_unchecked(int_i16) };\n    let _: NonZero<i32> = unsafe { NonZero::new_unchecked(int_i32) };\n    let _: NonZero<i64> = unsafe { NonZero::new_unchecked(int_i64) };\n    let _: NonZero<i128> = unsafe { NonZero::new_unchecked(int_i128) };\n}\n"
  },
  {
    "path": "tests/ui/transmute_int_to_non_zero.stderr",
    "content": "error: transmute from a `u8` to a `NonZero<u8>`\n  --> tests/ui/transmute_int_to_non_zero.rs:19:35\n   |\nLL |     let _: NonZero<u8> = unsafe { std::mem::transmute(int_u8) };\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u8)`\n   |\n   = note: `-D clippy::transmute-int-to-non-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_non_zero)]`\n\nerror: transmute from a `u16` to a `NonZero<u16>`\n  --> tests/ui/transmute_int_to_non_zero.rs:22:36\n   |\nLL |     let _: NonZero<u16> = unsafe { std::mem::transmute(int_u16) };\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u16)`\n\nerror: transmute from a `u32` to a `NonZero<u32>`\n  --> tests/ui/transmute_int_to_non_zero.rs:25:36\n   |\nLL |     let _: NonZero<u32> = unsafe { std::mem::transmute(int_u32) };\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u32)`\n\nerror: transmute from a `u64` to a `NonZero<u64>`\n  --> tests/ui/transmute_int_to_non_zero.rs:28:36\n   |\nLL |     let _: NonZero<u64> = unsafe { std::mem::transmute(int_u64) };\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u64)`\n\nerror: transmute from a `u128` to a `NonZero<u128>`\n  --> tests/ui/transmute_int_to_non_zero.rs:31:37\n   |\nLL |     let _: NonZero<u128> = unsafe { std::mem::transmute(int_u128) };\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_u128)`\n\nerror: transmute from a `i8` to a `NonZero<i8>`\n  --> tests/ui/transmute_int_to_non_zero.rs:34:35\n   |\nLL |     let _: NonZero<i8> = unsafe { std::mem::transmute(int_i8) };\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i8)`\n\nerror: transmute from a `i16` to a `NonZero<i16>`\n  --> tests/ui/transmute_int_to_non_zero.rs:37:36\n   |\nLL |     let _: NonZero<i16> = unsafe { std::mem::transmute(int_i16) };\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i16)`\n\nerror: transmute from a `i32` to a `NonZero<i32>`\n  --> tests/ui/transmute_int_to_non_zero.rs:40:36\n   |\nLL |     let _: NonZero<i32> = unsafe { std::mem::transmute(int_i32) };\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i32)`\n\nerror: transmute from a `i64` to a `NonZero<i64>`\n  --> tests/ui/transmute_int_to_non_zero.rs:43:36\n   |\nLL |     let _: NonZero<i64> = unsafe { std::mem::transmute(int_i64) };\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i64)`\n\nerror: transmute from a `i128` to a `NonZero<i128>`\n  --> tests/ui/transmute_int_to_non_zero.rs:46:37\n   |\nLL |     let _: NonZero<i128> = unsafe { std::mem::transmute(int_i128) };\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZero::new_unchecked(int_i128)`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_null_to_fn.rs",
    "content": "#![allow(dead_code)]\n#![warn(clippy::transmute_null_to_fn)]\n#![allow(clippy::zero_ptr, clippy::missing_transmute_annotations)]\n#![allow(clippy::manual_dangling_ptr)]\n\n// Easy to lint because these only span one line.\nfn one_liners() {\n    unsafe {\n        let _: fn() = std::mem::transmute(0 as *const ());\n        //~^ transmute_null_to_fn\n\n        let _: fn() = std::mem::transmute(std::ptr::null::<()>());\n        //~^ transmute_null_to_fn\n    }\n}\n\npub const ZPTR: *const usize = 0 as *const _;\npub const NOT_ZPTR: *const usize = 1 as *const _;\n\nfn transmute_const() {\n    unsafe {\n        // Should raise a lint.\n        let _: fn() = std::mem::transmute(ZPTR);\n        //~^ transmute_null_to_fn\n\n        // Should NOT raise a lint.\n        let _: fn() = std::mem::transmute(NOT_ZPTR);\n    }\n}\n\nfn issue_11485() {\n    unsafe {\n        let _: fn() = std::mem::transmute(0 as *const u8 as *const ());\n        //~^ transmute_null_to_fn\n\n        let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);\n        //~^ transmute_null_to_fn\n\n        let _: fn() = std::mem::transmute(ZPTR as *const u8);\n        //~^ transmute_null_to_fn\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/transmute_null_to_fn.stderr",
    "content": "error: transmuting a known null pointer into a function pointer\n  --> tests/ui/transmute_null_to_fn.rs:9:23\n   |\nLL |         let _: fn() = std::mem::transmute(0 as *const ());\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior\n   |\n   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value\n   = note: `-D clippy::transmute-null-to-fn` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmute_null_to_fn)]`\n\nerror: transmuting a known null pointer into a function pointer\n  --> tests/ui/transmute_null_to_fn.rs:12:23\n   |\nLL |         let _: fn() = std::mem::transmute(std::ptr::null::<()>());\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior\n   |\n   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value\n\nerror: transmuting a known null pointer into a function pointer\n  --> tests/ui/transmute_null_to_fn.rs:23:23\n   |\nLL |         let _: fn() = std::mem::transmute(ZPTR);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior\n   |\n   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value\n\nerror: transmuting a known null pointer into a function pointer\n  --> tests/ui/transmute_null_to_fn.rs:33:23\n   |\nLL |         let _: fn() = std::mem::transmute(0 as *const u8 as *const ());\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior\n   |\n   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value\n\nerror: transmuting a known null pointer into a function pointer\n  --> tests/ui/transmute_null_to_fn.rs:36:23\n   |\nLL |         let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior\n   |\n   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value\n\nerror: transmuting a known null pointer into a function pointer\n  --> tests/ui/transmute_null_to_fn.rs:39:23\n   |\nLL |         let _: fn() = std::mem::transmute(ZPTR as *const u8);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior\n   |\n   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_ptr_to_ptr.fixed",
    "content": "#![warn(clippy::transmute_ptr_to_ptr)]\n#![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]\n\nuse std::mem::transmute;\n\n// Make sure we can modify lifetimes, which is one of the recommended uses\n// of transmute\n\n// Make sure we can do static lifetime transmutes\nunsafe fn transmute_lifetime_to_static<'a, T>(t: &'a T) -> &'static T {\n    unsafe { transmute::<&'a T, &'static T>(t) }\n}\n\n// Make sure we can do non-static lifetime transmutes\nunsafe fn transmute_lifetime<'a, 'b, T>(t: &'a T, u: &'b T) -> &'b T {\n    unsafe { transmute::<&'a T, &'b T>(t) }\n}\n\nstruct LifetimeParam<'a> {\n    s: &'a str,\n}\n\nstruct GenericParam<T> {\n    t: T,\n}\n\n#[derive(Clone, Copy)]\nstruct PtrNamed {\n    ptr: *const u32,\n}\n#[derive(Clone, Copy)]\nstruct Ptr(*const u32);\n\nfn transmute_ptr_to_ptr() {\n    let ptr = &1u32 as *const u32;\n    let mut_ptr = &mut 1u32 as *mut u32;\n    unsafe {\n        // pointer-to-pointer transmutes; bad\n        let _: *const f32 = ptr.cast::<f32>();\n        //~^ transmute_ptr_to_ptr\n\n        let _: *mut f32 = mut_ptr.cast::<f32>();\n        //~^ transmute_ptr_to_ptr\n\n        // ref-ref transmutes; bad\n        let _: &f32 = &*(&1u32 as *const u32 as *const f32);\n        //~^ transmute_ptr_to_ptr\n\n        let _: &f32 = &*(&1f64 as *const f64 as *const f32);\n        //~^ transmute_ptr_to_ptr\n\n        //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not\n        // the same type\n        let _: &mut f32 = &mut *(&mut 1u32 as *mut u32 as *mut f32);\n        //~^ transmute_ptr_to_ptr\n\n        let _: &GenericParam<f32> = &*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>);\n        //~^ transmute_ptr_to_ptr\n\n        let u64_ref: &u64 = &0u64;\n        let u8_ref: &u8 = &*(u64_ref as *const u64 as *const u8);\n        //~^ transmute_ptr_to_ptr\n\n        let _: *const u32 = mut_ptr.cast_const();\n        //~^ transmute_ptr_to_ptr\n\n        let _: *mut u32 = ptr.cast_mut();\n        //~^ transmute_ptr_to_ptr\n    }\n\n    // transmute internal lifetimes, should not lint\n    let s = \"hello world\".to_owned();\n    let lp = LifetimeParam { s: &s };\n    let _: &LifetimeParam<'static> = unsafe { transmute(&lp) };\n    let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) };\n}\n\nfn issue1966() {\n    let ptr = &1u32 as *const u32;\n    unsafe {\n        let _: *const f32 = Ptr(ptr).0.cast::<f32>();\n        //~^ transmute_ptr_to_ptr\n        let _: *const f32 = PtrNamed { ptr }.ptr.cast::<f32>();\n        //~^ transmute_ptr_to_ptr\n        let _: *mut u32 = Ptr(ptr).0.cast_mut();\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\nfn lifetime_to_static(v: *mut &()) -> *const &'static () {\n    unsafe { v as *const &() }\n    //~^ transmute_ptr_to_ptr\n}\n\n// dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)\nconst _: &() = {\n    struct Zst;\n    let zst = &Zst;\n\n    unsafe { transmute::<&'static Zst, &'static ()>(zst) }\n};\n\n#[derive(Clone, Copy)]\nstruct Ptr8(*const u8);\n#[clippy::msrv = \"1.37\"]\nfn msrv_1_37(ptr: *const u8) {\n    unsafe {\n        let _: *const i8 = ptr as *const i8;\n        //~^ transmute_ptr_to_ptr\n        let _: *const i8 = Ptr8(ptr).0 as *const i8;\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\n#[clippy::msrv = \"1.38\"]\nfn msrv_1_38(ptr: *const u8) {\n    unsafe {\n        let _: *const i8 = ptr.cast::<i8>();\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\n#[clippy::msrv = \"1.64\"]\nfn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) {\n    unsafe {\n        let _: *mut u8 = ptr as *mut u8;\n        //~^ transmute_ptr_to_ptr\n        let _: *const u8 = mut_ptr as *const u8;\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\n#[clippy::msrv = \"1.65\"]\nfn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) {\n    unsafe {\n        let _: *mut u8 = ptr.cast_mut();\n        //~^ transmute_ptr_to_ptr\n        let _: *const u8 = mut_ptr.cast_const();\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/transmute_ptr_to_ptr.rs",
    "content": "#![warn(clippy::transmute_ptr_to_ptr)]\n#![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]\n\nuse std::mem::transmute;\n\n// Make sure we can modify lifetimes, which is one of the recommended uses\n// of transmute\n\n// Make sure we can do static lifetime transmutes\nunsafe fn transmute_lifetime_to_static<'a, T>(t: &'a T) -> &'static T {\n    unsafe { transmute::<&'a T, &'static T>(t) }\n}\n\n// Make sure we can do non-static lifetime transmutes\nunsafe fn transmute_lifetime<'a, 'b, T>(t: &'a T, u: &'b T) -> &'b T {\n    unsafe { transmute::<&'a T, &'b T>(t) }\n}\n\nstruct LifetimeParam<'a> {\n    s: &'a str,\n}\n\nstruct GenericParam<T> {\n    t: T,\n}\n\n#[derive(Clone, Copy)]\nstruct PtrNamed {\n    ptr: *const u32,\n}\n#[derive(Clone, Copy)]\nstruct Ptr(*const u32);\n\nfn transmute_ptr_to_ptr() {\n    let ptr = &1u32 as *const u32;\n    let mut_ptr = &mut 1u32 as *mut u32;\n    unsafe {\n        // pointer-to-pointer transmutes; bad\n        let _: *const f32 = transmute(ptr);\n        //~^ transmute_ptr_to_ptr\n\n        let _: *mut f32 = transmute(mut_ptr);\n        //~^ transmute_ptr_to_ptr\n\n        // ref-ref transmutes; bad\n        let _: &f32 = transmute(&1u32);\n        //~^ transmute_ptr_to_ptr\n\n        let _: &f32 = transmute(&1f64);\n        //~^ transmute_ptr_to_ptr\n\n        //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not\n        // the same type\n        let _: &mut f32 = transmute(&mut 1u32);\n        //~^ transmute_ptr_to_ptr\n\n        let _: &GenericParam<f32> = transmute(&GenericParam { t: 1u32 });\n        //~^ transmute_ptr_to_ptr\n\n        let u64_ref: &u64 = &0u64;\n        let u8_ref: &u8 = transmute(u64_ref);\n        //~^ transmute_ptr_to_ptr\n\n        let _: *const u32 = transmute(mut_ptr);\n        //~^ transmute_ptr_to_ptr\n\n        let _: *mut u32 = transmute(ptr);\n        //~^ transmute_ptr_to_ptr\n    }\n\n    // transmute internal lifetimes, should not lint\n    let s = \"hello world\".to_owned();\n    let lp = LifetimeParam { s: &s };\n    let _: &LifetimeParam<'static> = unsafe { transmute(&lp) };\n    let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) };\n}\n\nfn issue1966() {\n    let ptr = &1u32 as *const u32;\n    unsafe {\n        let _: *const f32 = transmute(Ptr(ptr));\n        //~^ transmute_ptr_to_ptr\n        let _: *const f32 = transmute(PtrNamed { ptr });\n        //~^ transmute_ptr_to_ptr\n        let _: *mut u32 = transmute(Ptr(ptr));\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\nfn lifetime_to_static(v: *mut &()) -> *const &'static () {\n    unsafe { transmute(v) }\n    //~^ transmute_ptr_to_ptr\n}\n\n// dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)\nconst _: &() = {\n    struct Zst;\n    let zst = &Zst;\n\n    unsafe { transmute::<&'static Zst, &'static ()>(zst) }\n};\n\n#[derive(Clone, Copy)]\nstruct Ptr8(*const u8);\n#[clippy::msrv = \"1.37\"]\nfn msrv_1_37(ptr: *const u8) {\n    unsafe {\n        let _: *const i8 = transmute(ptr);\n        //~^ transmute_ptr_to_ptr\n        let _: *const i8 = transmute(Ptr8(ptr));\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\n#[clippy::msrv = \"1.38\"]\nfn msrv_1_38(ptr: *const u8) {\n    unsafe {\n        let _: *const i8 = transmute(ptr);\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\n#[clippy::msrv = \"1.64\"]\nfn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) {\n    unsafe {\n        let _: *mut u8 = transmute(ptr);\n        //~^ transmute_ptr_to_ptr\n        let _: *const u8 = transmute(mut_ptr);\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\n#[clippy::msrv = \"1.65\"]\nfn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) {\n    unsafe {\n        let _: *mut u8 = transmute(ptr);\n        //~^ transmute_ptr_to_ptr\n        let _: *const u8 = transmute(mut_ptr);\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/transmute_ptr_to_ptr.stderr",
    "content": "error: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:39:29\n   |\nLL |         let _: *const f32 = transmute(ptr);\n   |                             ^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`\nhelp: use `pointer::cast` instead\n   |\nLL -         let _: *const f32 = transmute(ptr);\nLL +         let _: *const f32 = ptr.cast::<f32>();\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:42:27\n   |\nLL |         let _: *mut f32 = transmute(mut_ptr);\n   |                           ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast` instead\n   |\nLL -         let _: *mut f32 = transmute(mut_ptr);\nLL +         let _: *mut f32 = mut_ptr.cast::<f32>();\n   |\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ptr_to_ptr.rs:46:23\n   |\nLL |         let _: &f32 = transmute(&1u32);\n   |                       ^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)`\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ptr_to_ptr.rs:49:23\n   |\nLL |         let _: &f32 = transmute(&1f64);\n   |                       ^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)`\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ptr_to_ptr.rs:54:27\n   |\nLL |         let _: &mut f32 = transmute(&mut 1u32);\n   |                           ^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)`\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ptr_to_ptr.rs:57:37\n   |\nLL |         let _: &GenericParam<f32> = transmute(&GenericParam { t: 1u32 });\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>)`\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ptr_to_ptr.rs:61:27\n   |\nLL |         let u8_ref: &u8 = transmute(u64_ref);\n   |                           ^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)`\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:64:29\n   |\nLL |         let _: *const u32 = transmute(mut_ptr);\n   |                             ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast_const` instead\n   |\nLL -         let _: *const u32 = transmute(mut_ptr);\nLL +         let _: *const u32 = mut_ptr.cast_const();\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:67:27\n   |\nLL |         let _: *mut u32 = transmute(ptr);\n   |                           ^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast_mut` instead\n   |\nLL -         let _: *mut u32 = transmute(ptr);\nLL +         let _: *mut u32 = ptr.cast_mut();\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:81:29\n   |\nLL |         let _: *const f32 = transmute(Ptr(ptr));\n   |                             ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast` instead\n   |\nLL -         let _: *const f32 = transmute(Ptr(ptr));\nLL +         let _: *const f32 = Ptr(ptr).0.cast::<f32>();\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:83:29\n   |\nLL |         let _: *const f32 = transmute(PtrNamed { ptr });\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast` instead\n   |\nLL -         let _: *const f32 = transmute(PtrNamed { ptr });\nLL +         let _: *const f32 = PtrNamed { ptr }.ptr.cast::<f32>();\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:85:27\n   |\nLL |         let _: *mut u32 = transmute(Ptr(ptr));\n   |                           ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast_mut` instead\n   |\nLL -         let _: *mut u32 = transmute(Ptr(ptr));\nLL +         let _: *mut u32 = Ptr(ptr).0.cast_mut();\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:91:14\n   |\nLL |     unsafe { transmute(v) }\n   |              ^^^^^^^^^^^^\n   |\nhelp: use an `as` cast instead\n   |\nLL -     unsafe { transmute(v) }\nLL +     unsafe { v as *const &() }\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:108:28\n   |\nLL |         let _: *const i8 = transmute(ptr);\n   |                            ^^^^^^^^^^^^^^\n   |\nhelp: use an `as` cast instead\n   |\nLL -         let _: *const i8 = transmute(ptr);\nLL +         let _: *const i8 = ptr as *const i8;\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:110:28\n   |\nLL |         let _: *const i8 = transmute(Ptr8(ptr));\n   |                            ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use an `as` cast instead\n   |\nLL -         let _: *const i8 = transmute(Ptr8(ptr));\nLL +         let _: *const i8 = Ptr8(ptr).0 as *const i8;\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:118:28\n   |\nLL |         let _: *const i8 = transmute(ptr);\n   |                            ^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast` instead\n   |\nLL -         let _: *const i8 = transmute(ptr);\nLL +         let _: *const i8 = ptr.cast::<i8>();\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:126:26\n   |\nLL |         let _: *mut u8 = transmute(ptr);\n   |                          ^^^^^^^^^^^^^^\n   |\nhelp: use an `as` cast instead\n   |\nLL -         let _: *mut u8 = transmute(ptr);\nLL +         let _: *mut u8 = ptr as *mut u8;\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:128:28\n   |\nLL |         let _: *const u8 = transmute(mut_ptr);\n   |                            ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use an `as` cast instead\n   |\nLL -         let _: *const u8 = transmute(mut_ptr);\nLL +         let _: *const u8 = mut_ptr as *const u8;\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:136:26\n   |\nLL |         let _: *mut u8 = transmute(ptr);\n   |                          ^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast_mut` instead\n   |\nLL -         let _: *mut u8 = transmute(ptr);\nLL +         let _: *mut u8 = ptr.cast_mut();\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ptr_to_ptr.rs:138:28\n   |\nLL |         let _: *const u8 = transmute(mut_ptr);\n   |                            ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast_const` instead\n   |\nLL -         let _: *const u8 = transmute(mut_ptr);\nLL +         let _: *const u8 = mut_ptr.cast_const();\n   |\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_ptr_to_ref.fixed",
    "content": "#![warn(clippy::transmute_ptr_to_ref)]\n#![allow(\n    clippy::match_single_binding,\n    clippy::unnecessary_cast,\n    clippy::missing_transmute_annotations\n)]\n\nfn ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {\n    unsafe {\n        let _: &T = &*p;\n        //~^ transmute_ptr_to_ref\n        let _: &T = &*p;\n\n        let _: &mut T = &mut *m;\n        //~^ transmute_ptr_to_ref\n        let _: &mut T = &mut *m;\n\n        let _: &T = &*m;\n        //~^ transmute_ptr_to_ref\n        let _: &T = &*m;\n\n        let _: &mut T = &mut *(p as *mut T);\n        //~^ transmute_ptr_to_ref\n        let _ = &mut *(p as *mut T);\n\n        let _: &T = &*(o as *const T);\n        //~^ transmute_ptr_to_ref\n        let _: &T = &*(o as *const T);\n\n        let _: &mut T = &mut *(om as *mut T);\n        //~^ transmute_ptr_to_ref\n        let _: &mut T = &mut *(om as *mut T);\n\n        let _: &T = &*(om as *const T);\n        //~^ transmute_ptr_to_ref\n        let _: &T = &*(om as *const T);\n    }\n}\n\nfn issue1231() {\n    struct Foo<'a, T> {\n        bar: &'a T,\n    }\n\n    let raw = 42 as *const i32;\n    let _: &Foo<u8> = unsafe { &*raw.cast::<Foo<_>>() };\n    //~^ transmute_ptr_to_ref\n\n    let _: &Foo<&u8> = unsafe { &*raw.cast::<Foo<&_>>() };\n    //~^ transmute_ptr_to_ref\n\n    type Bar<'a> = &'a u8;\n    let raw = 42 as *const i32;\n    unsafe { &*(raw as *const u8) };\n    //~^ transmute_ptr_to_ref\n}\n\n#[derive(Clone, Copy)]\nstruct PtrRefNamed<'a> {\n    ptr: *const &'a u32,\n}\n#[derive(Clone, Copy)]\nstruct PtrRef<'a>(*const &'a u32);\n#[derive(Clone, Copy)]\nstruct PtrSliceRef<'a>(*const [&'a str]);\n#[derive(Clone, Copy)]\nstruct PtrSlice(*const [i32]);\n#[derive(Clone, Copy)]\nstruct Ptr(*const u32);\nimpl std::ops::Add for Ptr {\n    type Output = Self;\n    fn add(self, _: Self) -> Self {\n        self\n    }\n}\nmod ptr_mod {\n    #[derive(Clone, Copy)]\n    pub struct Ptr(*const u32);\n}\nfn issue1966(u: PtrSlice, v: PtrSliceRef, w: Ptr, x: PtrRefNamed, y: PtrRef, z: ptr_mod::Ptr) {\n    unsafe {\n        let _: &i32 = &*(w.0 as *const i32);\n        //~^ transmute_ptr_to_ref\n        let _: &u32 = &*w.0;\n        //~^ transmute_ptr_to_ref\n        let _: &&u32 = &*x.ptr.cast::<&u32>();\n        //~^ transmute_ptr_to_ref\n        // The field is not accessible. The program should not generate code\n        // that accesses the field.\n        let _: &u32 = std::mem::transmute(z);\n        let _ = &*w.0.cast::<u32>();\n        //~^ transmute_ptr_to_ref\n        let _: &[&str] = &*(v.0 as *const [&str]);\n        //~^ transmute_ptr_to_ref\n        let _ = &*(u.0 as *const [i32]);\n        //~^ transmute_ptr_to_ref\n        let _: &&u32 = &*y.0.cast::<&u32>();\n        //~^ transmute_ptr_to_ref\n        let _: &u32 = &*(w + w).0;\n        //~^ transmute_ptr_to_ref\n    }\n}\n\nfn issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 {\n    unsafe {\n        match 0 {\n            0 => &*x.cast::<&u32>(),\n            //~^ transmute_ptr_to_ref\n            1 => &*y.cast::<&u32>(),\n            //~^ transmute_ptr_to_ref\n            2 => &*x.cast::<&'b u32>(),\n            //~^ transmute_ptr_to_ref\n            _ => &*y.cast::<&'b u32>(),\n            //~^ transmute_ptr_to_ref\n        }\n    }\n}\n\n#[clippy::msrv = \"1.38\"]\nfn meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 {\n    unsafe {\n        let a = 0u32;\n        let a = &a as *const u32;\n        let _: &u32 = &*a;\n        //~^ transmute_ptr_to_ref\n        let _: &u32 = &*a.cast::<u32>();\n        //~^ transmute_ptr_to_ref\n        match 0 {\n            0 => &*x.cast::<&u32>(),\n            //~^ transmute_ptr_to_ref\n            _ => &*x.cast::<&'b u32>(),\n            //~^ transmute_ptr_to_ref\n        }\n    }\n}\n\n#[clippy::msrv = \"1.37\"]\nfn under_msrv<'a, 'b, 'c>(x: *const &'a u32, y: PtrRef) -> &'c &'b u32 {\n    unsafe {\n        let a = 0u32;\n        let a = &a as *const u32;\n        let _: &u32 = &*a;\n        //~^ transmute_ptr_to_ref\n        let _: &u32 = &*(a as *const u32);\n        //~^ transmute_ptr_to_ref\n        let _ = &*(Ptr(a).0 as *const u32);\n        //~^ transmute_ptr_to_ref\n        match 0 {\n            0 => &*(x as *const () as *const &u32),\n            //~^ transmute_ptr_to_ref\n            1 => &*(x as *const () as *const &'b u32),\n            //~^ transmute_ptr_to_ref\n            2 => &*(y.0 as *const () as *const &u32),\n            //~^ transmute_ptr_to_ref\n            _ => &*(y.0 as *const () as *const &'b u32),\n            //~^ transmute_ptr_to_ref\n        }\n    }\n}\n\n// handle DSTs\nfn issue13357(ptr: *const [i32], s_ptr: *const &str, a_s_ptr: *const [&str]) {\n    unsafe {\n        // different types, without erased regions\n        let _ = &*(ptr as *const [u32]);\n        //~^ transmute_ptr_to_ref\n        let _: &[u32] = &*(ptr as *const [u32]);\n        //~^ transmute_ptr_to_ref\n\n        // different types, with erased regions\n        let _ = &*(a_s_ptr as *const [&[u8]]);\n        //~^ transmute_ptr_to_ref\n        let _: &[&[u8]] = &*(a_s_ptr as *const [&[u8]]);\n        //~^ transmute_ptr_to_ref\n\n        // same type, without erased regions\n        let _ = &*(ptr as *const [i32]);\n        //~^ transmute_ptr_to_ref\n        let _: &[i32] = &*ptr;\n        //~^ transmute_ptr_to_ref\n\n        // same type, with erased regions\n        let _ = &*(a_s_ptr as *const [&str]);\n        //~^ transmute_ptr_to_ref\n        let _: &[&str] = &*(a_s_ptr as *const [&str]);\n        //~^ transmute_ptr_to_ref\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/transmute_ptr_to_ref.rs",
    "content": "#![warn(clippy::transmute_ptr_to_ref)]\n#![allow(\n    clippy::match_single_binding,\n    clippy::unnecessary_cast,\n    clippy::missing_transmute_annotations\n)]\n\nfn ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {\n    unsafe {\n        let _: &T = std::mem::transmute(p);\n        //~^ transmute_ptr_to_ref\n        let _: &T = &*p;\n\n        let _: &mut T = std::mem::transmute(m);\n        //~^ transmute_ptr_to_ref\n        let _: &mut T = &mut *m;\n\n        let _: &T = std::mem::transmute(m);\n        //~^ transmute_ptr_to_ref\n        let _: &T = &*m;\n\n        let _: &mut T = std::mem::transmute(p as *mut T);\n        //~^ transmute_ptr_to_ref\n        let _ = &mut *(p as *mut T);\n\n        let _: &T = std::mem::transmute(o);\n        //~^ transmute_ptr_to_ref\n        let _: &T = &*(o as *const T);\n\n        let _: &mut T = std::mem::transmute(om);\n        //~^ transmute_ptr_to_ref\n        let _: &mut T = &mut *(om as *mut T);\n\n        let _: &T = std::mem::transmute(om);\n        //~^ transmute_ptr_to_ref\n        let _: &T = &*(om as *const T);\n    }\n}\n\nfn issue1231() {\n    struct Foo<'a, T> {\n        bar: &'a T,\n    }\n\n    let raw = 42 as *const i32;\n    let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };\n    //~^ transmute_ptr_to_ref\n\n    let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };\n    //~^ transmute_ptr_to_ref\n\n    type Bar<'a> = &'a u8;\n    let raw = 42 as *const i32;\n    unsafe { std::mem::transmute::<_, Bar>(raw) };\n    //~^ transmute_ptr_to_ref\n}\n\n#[derive(Clone, Copy)]\nstruct PtrRefNamed<'a> {\n    ptr: *const &'a u32,\n}\n#[derive(Clone, Copy)]\nstruct PtrRef<'a>(*const &'a u32);\n#[derive(Clone, Copy)]\nstruct PtrSliceRef<'a>(*const [&'a str]);\n#[derive(Clone, Copy)]\nstruct PtrSlice(*const [i32]);\n#[derive(Clone, Copy)]\nstruct Ptr(*const u32);\nimpl std::ops::Add for Ptr {\n    type Output = Self;\n    fn add(self, _: Self) -> Self {\n        self\n    }\n}\nmod ptr_mod {\n    #[derive(Clone, Copy)]\n    pub struct Ptr(*const u32);\n}\nfn issue1966(u: PtrSlice, v: PtrSliceRef, w: Ptr, x: PtrRefNamed, y: PtrRef, z: ptr_mod::Ptr) {\n    unsafe {\n        let _: &i32 = std::mem::transmute(w);\n        //~^ transmute_ptr_to_ref\n        let _: &u32 = std::mem::transmute(w);\n        //~^ transmute_ptr_to_ref\n        let _: &&u32 = core::mem::transmute(x);\n        //~^ transmute_ptr_to_ref\n        // The field is not accessible. The program should not generate code\n        // that accesses the field.\n        let _: &u32 = std::mem::transmute(z);\n        let _ = std::mem::transmute::<_, &u32>(w);\n        //~^ transmute_ptr_to_ref\n        let _: &[&str] = core::mem::transmute(v);\n        //~^ transmute_ptr_to_ref\n        let _ = std::mem::transmute::<_, &[i32]>(u);\n        //~^ transmute_ptr_to_ref\n        let _: &&u32 = std::mem::transmute(y);\n        //~^ transmute_ptr_to_ref\n        let _: &u32 = std::mem::transmute(w + w);\n        //~^ transmute_ptr_to_ref\n    }\n}\n\nfn issue8924<'a, 'b, 'c>(x: *const &'a u32, y: *const &'b u32) -> &'c &'b u32 {\n    unsafe {\n        match 0 {\n            0 => std::mem::transmute(x),\n            //~^ transmute_ptr_to_ref\n            1 => std::mem::transmute(y),\n            //~^ transmute_ptr_to_ref\n            2 => std::mem::transmute::<_, &&'b u32>(x),\n            //~^ transmute_ptr_to_ref\n            _ => std::mem::transmute::<_, &&'b u32>(y),\n            //~^ transmute_ptr_to_ref\n        }\n    }\n}\n\n#[clippy::msrv = \"1.38\"]\nfn meets_msrv<'a, 'b, 'c>(x: *const &'a u32) -> &'c &'b u32 {\n    unsafe {\n        let a = 0u32;\n        let a = &a as *const u32;\n        let _: &u32 = std::mem::transmute(a);\n        //~^ transmute_ptr_to_ref\n        let _: &u32 = std::mem::transmute::<_, &u32>(a);\n        //~^ transmute_ptr_to_ref\n        match 0 {\n            0 => std::mem::transmute(x),\n            //~^ transmute_ptr_to_ref\n            _ => std::mem::transmute::<_, &&'b u32>(x),\n            //~^ transmute_ptr_to_ref\n        }\n    }\n}\n\n#[clippy::msrv = \"1.37\"]\nfn under_msrv<'a, 'b, 'c>(x: *const &'a u32, y: PtrRef) -> &'c &'b u32 {\n    unsafe {\n        let a = 0u32;\n        let a = &a as *const u32;\n        let _: &u32 = std::mem::transmute(a);\n        //~^ transmute_ptr_to_ref\n        let _: &u32 = std::mem::transmute::<_, &u32>(a);\n        //~^ transmute_ptr_to_ref\n        let _ = std::mem::transmute::<_, &u32>(Ptr(a));\n        //~^ transmute_ptr_to_ref\n        match 0 {\n            0 => std::mem::transmute(x),\n            //~^ transmute_ptr_to_ref\n            1 => std::mem::transmute::<_, &&'b u32>(x),\n            //~^ transmute_ptr_to_ref\n            2 => std::mem::transmute(y),\n            //~^ transmute_ptr_to_ref\n            _ => std::mem::transmute::<_, &&'b u32>(y),\n            //~^ transmute_ptr_to_ref\n        }\n    }\n}\n\n// handle DSTs\nfn issue13357(ptr: *const [i32], s_ptr: *const &str, a_s_ptr: *const [&str]) {\n    unsafe {\n        // different types, without erased regions\n        let _ = core::mem::transmute::<_, &[u32]>(ptr);\n        //~^ transmute_ptr_to_ref\n        let _: &[u32] = core::mem::transmute(ptr);\n        //~^ transmute_ptr_to_ref\n\n        // different types, with erased regions\n        let _ = core::mem::transmute::<_, &[&[u8]]>(a_s_ptr);\n        //~^ transmute_ptr_to_ref\n        let _: &[&[u8]] = core::mem::transmute(a_s_ptr);\n        //~^ transmute_ptr_to_ref\n\n        // same type, without erased regions\n        let _ = core::mem::transmute::<_, &[i32]>(ptr);\n        //~^ transmute_ptr_to_ref\n        let _: &[i32] = core::mem::transmute(ptr);\n        //~^ transmute_ptr_to_ref\n\n        // same type, with erased regions\n        let _ = core::mem::transmute::<_, &[&str]>(a_s_ptr);\n        //~^ transmute_ptr_to_ref\n        let _: &[&str] = core::mem::transmute(a_s_ptr);\n        //~^ transmute_ptr_to_ref\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/transmute_ptr_to_ref.stderr",
    "content": "error: transmute from a pointer type (`*const T`) to a reference type (`&T`)\n  --> tests/ui/transmute_ptr_to_ref.rs:10:21\n   |\nLL |         let _: &T = std::mem::transmute(p);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*p`\n   |\n   = note: `-D clippy::transmute-ptr-to-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ref)]`\n\nerror: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)\n  --> tests/ui/transmute_ptr_to_ref.rs:14:25\n   |\nLL |         let _: &mut T = std::mem::transmute(m);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *m`\n\nerror: transmute from a pointer type (`*mut T`) to a reference type (`&T`)\n  --> tests/ui/transmute_ptr_to_ref.rs:18:21\n   |\nLL |         let _: &T = std::mem::transmute(m);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*m`\n\nerror: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)\n  --> tests/ui/transmute_ptr_to_ref.rs:22:25\n   |\nLL |         let _: &mut T = std::mem::transmute(p as *mut T);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(p as *mut T)`\n\nerror: transmute from a pointer type (`*const U`) to a reference type (`&T`)\n  --> tests/ui/transmute_ptr_to_ref.rs:26:21\n   |\nLL |         let _: &T = std::mem::transmute(o);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(o as *const T)`\n\nerror: transmute from a pointer type (`*mut U`) to a reference type (`&mut T`)\n  --> tests/ui/transmute_ptr_to_ref.rs:30:25\n   |\nLL |         let _: &mut T = std::mem::transmute(om);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(om as *mut T)`\n\nerror: transmute from a pointer type (`*mut U`) to a reference type (`&T`)\n  --> tests/ui/transmute_ptr_to_ref.rs:34:21\n   |\nLL |         let _: &T = std::mem::transmute(om);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(om as *const T)`\n\nerror: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<'_, u8>`)\n  --> tests/ui/transmute_ptr_to_ref.rs:46:32\n   |\nLL |     let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::<Foo<_>>()`\n\nerror: transmute from a pointer type (`*const i32`) to a reference type (`&issue1231::Foo<'_, &u8>`)\n  --> tests/ui/transmute_ptr_to_ref.rs:49:33\n   |\nLL |     let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::<Foo<&_>>()`\n\nerror: transmute from a pointer type (`*const i32`) to a reference type (`&u8`)\n  --> tests/ui/transmute_ptr_to_ref.rs:54:14\n   |\nLL |     unsafe { std::mem::transmute::<_, Bar>(raw) };\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const u8)`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&i32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:82:23\n   |\nLL |         let _: &i32 = std::mem::transmute(w);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(w.0 as *const i32)`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:84:23\n   |\nLL |         let _: &u32 = std::mem::transmute(w);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*w.0`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:86:24\n   |\nLL |         let _: &&u32 = core::mem::transmute(x);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.ptr.cast::<&u32>()`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:91:17\n   |\nLL |         let _ = std::mem::transmute::<_, &u32>(w);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*w.0.cast::<u32>()`\n\nerror: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:93:26\n   |\nLL |         let _: &[&str] = core::mem::transmute(v);\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(v.0 as *const [&str])`\n\nerror: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:95:17\n   |\nLL |         let _ = std::mem::transmute::<_, &[i32]>(u);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(u.0 as *const [i32])`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:97:24\n   |\nLL |         let _: &&u32 = std::mem::transmute(y);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.0.cast::<&u32>()`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:99:23\n   |\nLL |         let _: &u32 = std::mem::transmute(w + w);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(w + w).0`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:107:18\n   |\nLL |             0 => std::mem::transmute(x),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:109:18\n   |\nLL |             1 => std::mem::transmute(y),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&u32>()`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:111:18\n   |\nLL |             2 => std::mem::transmute::<_, &&'b u32>(x),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:113:18\n   |\nLL |             _ => std::mem::transmute::<_, &&'b u32>(y),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&'b u32>()`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:124:23\n   |\nLL |         let _: &u32 = std::mem::transmute(a);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:126:23\n   |\nLL |         let _: &u32 = std::mem::transmute::<_, &u32>(a);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a.cast::<u32>()`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:129:18\n   |\nLL |             0 => std::mem::transmute(x),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:131:18\n   |\nLL |             _ => std::mem::transmute::<_, &&'b u32>(x),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:142:23\n   |\nLL |         let _: &u32 = std::mem::transmute(a);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:144:23\n   |\nLL |         let _: &u32 = std::mem::transmute::<_, &u32>(a);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const u32)`\n\nerror: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:146:17\n   |\nLL |         let _ = std::mem::transmute::<_, &u32>(Ptr(a));\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(Ptr(a).0 as *const u32)`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:149:18\n   |\nLL |             0 => std::mem::transmute(x),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &u32)`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:151:18\n   |\nLL |             1 => std::mem::transmute::<_, &&'b u32>(x),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &'b u32)`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:153:18\n   |\nLL |             2 => std::mem::transmute(y),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(y.0 as *const () as *const &u32)`\n\nerror: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)\n  --> tests/ui/transmute_ptr_to_ref.rs:155:18\n   |\nLL |             _ => std::mem::transmute::<_, &&'b u32>(y),\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(y.0 as *const () as *const &'b u32)`\n\nerror: transmute from a pointer type (`*const [i32]`) to a reference type (`&[u32]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:165:17\n   |\nLL |         let _ = core::mem::transmute::<_, &[u32]>(ptr);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [u32])`\n\nerror: transmute from a pointer type (`*const [i32]`) to a reference type (`&[u32]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:167:25\n   |\nLL |         let _: &[u32] = core::mem::transmute(ptr);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [u32])`\n\nerror: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&[u8]]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:171:17\n   |\nLL |         let _ = core::mem::transmute::<_, &[&[u8]]>(a_s_ptr);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&[u8]])`\n\nerror: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&[u8]]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:173:27\n   |\nLL |         let _: &[&[u8]] = core::mem::transmute(a_s_ptr);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&[u8]])`\n\nerror: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:177:17\n   |\nLL |         let _ = core::mem::transmute::<_, &[i32]>(ptr);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(ptr as *const [i32])`\n\nerror: transmute from a pointer type (`*const [i32]`) to a reference type (`&[i32]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:179:25\n   |\nLL |         let _: &[i32] = core::mem::transmute(ptr);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*ptr`\n\nerror: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:183:17\n   |\nLL |         let _ = core::mem::transmute::<_, &[&str]>(a_s_ptr);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&str])`\n\nerror: transmute from a pointer type (`*const [&str]`) to a reference type (`&[&str]`)\n  --> tests/ui/transmute_ptr_to_ref.rs:185:26\n   |\nLL |         let _: &[&str] = core::mem::transmute(a_s_ptr);\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a_s_ptr as *const [&str])`\n\nerror: aborting due to 41 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_ref_to_ref.fixed",
    "content": "#![deny(clippy::transmute_ptr_to_ptr)]\n#![allow(dead_code, clippy::missing_transmute_annotations, clippy::cast_slice_different_sizes)]\n\nfn main() {\n    unsafe {\n        let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF];\n        let bools: &[bool] = unsafe { &*(single_u64 as *const [u64] as *const [bool]) };\n        //~^ transmute_ptr_to_ptr\n\n        let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321];\n        let b: &[u8] = unsafe { &*(a as *const [u32] as *const [u8]) };\n        //~^ transmute_ptr_to_ptr\n\n        let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];\n        let alt_slice: &[u32] = unsafe { &*(bytes as *const [u8] as *const [u32]) };\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\nfn issue16104(make_ptr: fn() -> *const u32) {\n    macro_rules! call {\n        ($x:expr) => {\n            $x()\n        };\n    }\n    macro_rules! take_ref {\n        ($x:expr) => {\n            &$x\n        };\n    }\n\n    unsafe {\n        let _: *const f32 = call!(make_ptr).cast::<f32>();\n        //~^ transmute_ptr_to_ptr\n        let _: &f32 = &*(take_ref!(1u32) as *const u32 as *const f32);\n        //~^ transmute_ptr_to_ptr\n    }\n}\n"
  },
  {
    "path": "tests/ui/transmute_ref_to_ref.rs",
    "content": "#![deny(clippy::transmute_ptr_to_ptr)]\n#![allow(dead_code, clippy::missing_transmute_annotations, clippy::cast_slice_different_sizes)]\n\nfn main() {\n    unsafe {\n        let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF];\n        let bools: &[bool] = unsafe { std::mem::transmute(single_u64) };\n        //~^ transmute_ptr_to_ptr\n\n        let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321];\n        let b: &[u8] = unsafe { std::mem::transmute(a) };\n        //~^ transmute_ptr_to_ptr\n\n        let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];\n        let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) };\n        //~^ transmute_ptr_to_ptr\n    }\n}\n\nfn issue16104(make_ptr: fn() -> *const u32) {\n    macro_rules! call {\n        ($x:expr) => {\n            $x()\n        };\n    }\n    macro_rules! take_ref {\n        ($x:expr) => {\n            &$x\n        };\n    }\n\n    unsafe {\n        let _: *const f32 = std::mem::transmute(call!(make_ptr));\n        //~^ transmute_ptr_to_ptr\n        let _: &f32 = std::mem::transmute(take_ref!(1u32));\n        //~^ transmute_ptr_to_ptr\n    }\n}\n"
  },
  {
    "path": "tests/ui/transmute_ref_to_ref.stderr",
    "content": "error: transmute from a reference to a reference\n  --> tests/ui/transmute_ref_to_ref.rs:7:39\n   |\nLL |         let bools: &[bool] = unsafe { std::mem::transmute(single_u64) };\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(single_u64 as *const [u64] as *const [bool])`\n   |\nnote: the lint level is defined here\n  --> tests/ui/transmute_ref_to_ref.rs:1:9\n   |\nLL | #![deny(clippy::transmute_ptr_to_ptr)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ref_to_ref.rs:11:33\n   |\nLL |         let b: &[u8] = unsafe { std::mem::transmute(a) };\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])`\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ref_to_ref.rs:15:42\n   |\nLL |         let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) };\n   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmute_ref_to_ref.rs:33:29\n   |\nLL |         let _: *const f32 = std::mem::transmute(call!(make_ptr));\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `pointer::cast` instead\n   |\nLL -         let _: *const f32 = std::mem::transmute(call!(make_ptr));\nLL +         let _: *const f32 = call!(make_ptr).cast::<f32>();\n   |\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ref_to_ref.rs:35:23\n   |\nLL |         let _: &f32 = std::mem::transmute(take_ref!(1u32));\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(take_ref!(1u32) as *const u32 as *const f32)`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_ref_to_ref_no_std.fixed",
    "content": "#![deny(clippy::transmute_ptr_to_ptr)]\n#![allow(dead_code, clippy::missing_transmute_annotations, clippy::cast_slice_different_sizes)]\n#![feature(lang_items)]\n#![no_std]\n\nuse core::panic::PanicInfo;\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n\n#[panic_handler]\nfn panic(info: &PanicInfo) -> ! {\n    loop {}\n}\n\nfn main() {\n    unsafe {\n        let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF];\n        let bools: &[bool] = unsafe { &*(single_u64 as *const [u64] as *const [bool]) };\n        //~^ transmute_ptr_to_ptr\n\n        let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321];\n        let b: &[u8] = unsafe { &*(a as *const [u32] as *const [u8]) };\n        //~^ transmute_ptr_to_ptr\n\n        let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];\n        let alt_slice: &[u32] = unsafe { &*(bytes as *const [u8] as *const [u32]) };\n        //~^ transmute_ptr_to_ptr\n    }\n}\n"
  },
  {
    "path": "tests/ui/transmute_ref_to_ref_no_std.rs",
    "content": "#![deny(clippy::transmute_ptr_to_ptr)]\n#![allow(dead_code, clippy::missing_transmute_annotations, clippy::cast_slice_different_sizes)]\n#![feature(lang_items)]\n#![no_std]\n\nuse core::panic::PanicInfo;\n\n#[lang = \"eh_personality\"]\nextern \"C\" fn eh_personality() {}\n\n#[panic_handler]\nfn panic(info: &PanicInfo) -> ! {\n    loop {}\n}\n\nfn main() {\n    unsafe {\n        let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF];\n        let bools: &[bool] = unsafe { core::mem::transmute(single_u64) };\n        //~^ transmute_ptr_to_ptr\n\n        let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321];\n        let b: &[u8] = unsafe { core::mem::transmute(a) };\n        //~^ transmute_ptr_to_ptr\n\n        let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];\n        let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };\n        //~^ transmute_ptr_to_ptr\n    }\n}\n"
  },
  {
    "path": "tests/ui/transmute_ref_to_ref_no_std.stderr",
    "content": "error: transmute from a reference to a reference\n  --> tests/ui/transmute_ref_to_ref_no_std.rs:19:39\n   |\nLL |         let bools: &[bool] = unsafe { core::mem::transmute(single_u64) };\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(single_u64 as *const [u64] as *const [bool])`\n   |\nnote: the lint level is defined here\n  --> tests/ui/transmute_ref_to_ref_no_std.rs:1:9\n   |\nLL | #![deny(clippy::transmute_ptr_to_ptr)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ref_to_ref_no_std.rs:23:33\n   |\nLL |         let b: &[u8] = unsafe { core::mem::transmute(a) };\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])`\n\nerror: transmute from a reference to a reference\n  --> tests/ui/transmute_ref_to_ref_no_std.rs:27:42\n   |\nLL |         let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };\n   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmute_undefined_repr.rs",
    "content": "#![warn(clippy::transmute_undefined_repr)]\n#![allow(\n    clippy::unit_arg,\n    clippy::transmute_ptr_to_ref,\n    clippy::useless_transmute,\n    clippy::missing_transmute_annotations\n)]\n\nuse core::any::TypeId;\nuse core::ffi::c_void;\nuse core::mem::{MaybeUninit, size_of, transmute};\nuse core::ptr::NonNull;\n\nfn value<T>() -> T {\n    unimplemented!()\n}\n\nstruct Empty;\nstruct Ty<T>(T);\nstruct Ty2<T, U>(T, U);\n\n#[repr(C)]\nstruct Ty2C<T, U>(T, U);\n\nfn main() {\n    unsafe {\n        let _: () = transmute(value::<Empty>());\n        let _: Empty = transmute(value::<()>());\n\n        let _: Ty<u32> = transmute(value::<u32>());\n        let _: Ty<u32> = transmute(value::<u32>());\n\n        // Lint, Ty2 is unordered\n        let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>());\n        //~^ transmute_undefined_repr\n\n        // Lint, Ty2 is unordered\n        let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>());\n        //~^ transmute_undefined_repr\n\n        // Ok, Ty2 types are the same\n        let _: Ty2<u32, i32> = transmute(value::<Ty<Ty2<u32, i32>>>());\n        // Ok, Ty2 types are the same\n        let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, i32>>());\n\n        // Lint, different Ty2 instances\n        let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>());\n        //~^ transmute_undefined_repr\n\n        // Lint, different Ty2 instances\n        let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>());\n        //~^ transmute_undefined_repr\n\n        let _: Ty<&()> = transmute(value::<&()>());\n        let _: &() = transmute(value::<Ty<&()>>());\n\n        // Lint, different Ty2 instances\n        let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>());\n        //~^ transmute_undefined_repr\n\n        // Lint, different Ty2 instances\n        let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>());\n        //~^ transmute_undefined_repr\n\n        // Ok, pointer to usize conversion\n        let _: Ty<usize> = transmute(value::<&Ty2<u32, i32>>());\n        // Ok, pointer to usize conversion\n        let _: &Ty2<u32, i32> = transmute(value::<Ty<usize>>());\n\n        // Ok, transmute to byte array\n        let _: Ty<[u8; 8]> = transmute(value::<Ty2<u32, i32>>());\n        // Ok, transmute from byte array\n        let _: Ty2<u32, i32> = transmute(value::<Ty<[u8; 8]>>());\n\n        // issue #8417\n        // Ok, Ty2 types are the same\n        let _: Ty2C<Ty2<u32, i32>, ()> = transmute(value::<Ty2<u32, i32>>());\n        // Ok, Ty2 types are the same\n        let _: Ty2<u32, i32> = transmute(value::<Ty2C<Ty2<u32, i32>, ()>>());\n\n        // Ok, Ty2 types are the same\n        let _: &'static mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>());\n        // Ok, Ty2 types are the same\n        let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, u32>>());\n        // Ok, Ty2 types are the same\n        let _: *mut Ty2<u32, u32> = transmute(value::<Box<Ty2<u32, u32>>>());\n        // Ok, Ty2 types are the same\n        let _: Box<Ty2<u32, u32>> = transmute(value::<*mut Ty2<u32, u32>>());\n\n        // Lint, different Ty2 instances\n        let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>());\n        //~^ transmute_undefined_repr\n\n        // Lint, different Ty2 instances\n        let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>());\n        //~^ transmute_undefined_repr\n\n        // Ok, type erasure\n        let _: *const () = transmute(value::<Ty<&Ty2<u32, f32>>>());\n        // Ok, reverse type erasure\n        let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const ()>());\n\n        // Ok, type erasure\n        let _: *const c_void = transmute(value::<Ty<&Ty2<u32, f32>>>());\n        // Ok, reverse type erasure\n        let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const c_void>());\n\n        enum Erase {}\n        // Ok, type erasure\n        let _: *const Erase = transmute(value::<Ty<&Ty2<u32, f32>>>());\n        // Ok, reverse type erasure\n        let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase>());\n\n        struct Erase2(\n            [u8; 0],\n            core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,\n        );\n        // Ok, type erasure\n        let _: *const Erase2 = transmute(value::<Ty<&Ty2<u32, f32>>>());\n        // Ok, reverse type erasure\n        let _: Ty<&Ty2<u32, f32>> = transmute(value::<*const Erase2>());\n\n        // Ok, type erasure\n        let _: *const () = transmute(value::<&&[u8]>());\n        // Ok, reverse type erasure\n        let _: &&[u8] = transmute(value::<*const ()>());\n\n        // Ok, type erasure\n        let _: *mut c_void = transmute(value::<&mut &[u8]>());\n        // Ok, reverse type erasure\n        let _: &mut &[u8] = transmute(value::<*mut c_void>());\n\n        // Ok, transmute to byte array\n        let _: [u8; size_of::<&[u8]>()] = transmute(value::<&[u8]>());\n        // Ok, transmute from byte array\n        let _: &[u8] = transmute(value::<[u8; size_of::<&[u8]>()]>());\n\n        // Ok, transmute to int array\n        let _: [usize; 2] = transmute(value::<&[u8]>());\n        // Ok, transmute from int array\n        let _: &[u8] = transmute(value::<[usize; 2]>());\n\n        // Ok\n        let _: *const [u8] = transmute(value::<Box<[u8]>>());\n        // Ok\n        let _: Box<[u8]> = transmute(value::<*mut [u8]>());\n\n        // Ok\n        let _: Ty2<u32, u32> = transmute(value::<(Ty2<u32, u32>,)>());\n        // Ok\n        let _: (Ty2<u32, u32>,) = transmute(value::<Ty2<u32, u32>>());\n\n        // Ok\n        let _: Ty2<u32, u32> = transmute(value::<(Ty2<u32, u32>, ())>());\n        // Ok\n        let _: (Ty2<u32, u32>, ()) = transmute(value::<Ty2<u32, u32>>());\n\n        // Ok\n        let _: Ty2<u32, u32> = transmute(value::<((), Ty2<u32, u32>)>());\n        // Ok\n        let _: ((), Ty2<u32, u32>) = transmute(value::<Ty2<u32, u32>>());\n\n        // Ok\n        let _: (usize, usize) = transmute(value::<&[u8]>());\n        // Ok\n        let _: &[u8] = transmute(value::<(usize, usize)>());\n\n        trait Trait {}\n        // Ok\n        let _: (isize, isize) = transmute(value::<&dyn Trait>());\n        let _: &dyn Trait = transmute(value::<(isize, isize)>());\n\n        // Ok\n        let _: MaybeUninit<Ty2<u32, u32>> = transmute(value::<Ty2<u32, u32>>());\n        // Ok\n        let _: Ty2<u32, u32> = transmute(value::<MaybeUninit<Ty2<u32, u32>>>());\n\n        // Ok\n        let _: Ty<&[u32]> = transmute::<&[u32], _>(value::<&Vec<u32>>());\n\n        // Ok\n        let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<Ty2<u32, u32>, u32>>());\n        // Ok\n        let _: *const Ty2C<Ty2<u32, u32>, u32> = transmute(value::<*const Ty2<u32, u32>>());\n        // Ok\n        let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<(), Ty2<u32, u32>>>());\n        // Ok\n        let _: *const Ty2C<(), Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>());\n\n        // Err\n        let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>());\n        //~^ transmute_undefined_repr\n\n        // Err\n        let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>());\n        //~^ transmute_undefined_repr\n\n        // Ok\n        let _: NonNull<u8> = transmute(value::<NonNull<(String, String)>>());\n        // Ok\n        let _: NonNull<(String, String)> = transmute(value::<NonNull<u8>>());\n    }\n}\n\nfn _with_generics<T: 'static, U: 'static>() {\n    if TypeId::of::<T>() != TypeId::of::<u32>() || TypeId::of::<T>() != TypeId::of::<U>() {\n        return;\n    }\n    unsafe {\n        // Ok\n        let _: &u32 = transmute(value::<&T>());\n        // Ok\n        let _: &T = transmute(value::<&u32>());\n\n        // Ok\n        let _: Vec<U> = transmute(value::<Vec<T>>());\n        // Ok\n        let _: Vec<T> = transmute(value::<Vec<U>>());\n\n        // Ok\n        let _: Ty<&u32> = transmute(value::<&T>());\n        // Ok\n        let _: Ty<&T> = transmute(value::<&u32>());\n\n        // Ok\n        let _: Vec<u32> = transmute(value::<Vec<T>>());\n        // Ok\n        let _: Vec<T> = transmute(value::<Vec<u32>>());\n\n        // Ok\n        let _: &Ty2<u32, u32> = transmute(value::<&Ty2<T, U>>());\n        // Ok\n        let _: &Ty2<T, U> = transmute(value::<&Ty2<u32, u32>>());\n\n        // Ok\n        let _: Vec<Vec<u32>> = transmute(value::<Vec<Vec<T>>>());\n        // Ok\n        let _: Vec<Vec<T>> = transmute(value::<Vec<Vec<u32>>>());\n\n        // Err\n        let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>());\n        //~^ transmute_undefined_repr\n\n        // Err\n        let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>());\n        //~^ transmute_undefined_repr\n\n        // Ok\n        let _: *const u32 = transmute(value::<Box<T>>());\n        // Ok\n        let _: Box<T> = transmute(value::<*const u32>());\n    }\n}\n"
  },
  {
    "path": "tests/ui/transmute_undefined_repr.stderr",
    "content": "error: transmute from `Ty2<u32, i32>` which has an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:34:33\n   |\nLL |         let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>());\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::transmute-undefined-repr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmute_undefined_repr)]`\n\nerror: transmute into `Ty2<u32, i32>` which has an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:38:32\n   |\nLL |         let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>());\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmute from `Ty<Ty2<u32, i32>>` to `Ty2<u32, f32>`, both of which have an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:47:32\n   |\nLL |         let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>());\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: two instances of the same generic type (`Ty2`) may have different layouts\n\nerror: transmute from `Ty2<u32, f32>` to `Ty<Ty2<u32, i32>>`, both of which have an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:51:36\n   |\nLL |         let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>());\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: two instances of the same generic type (`Ty2`) may have different layouts\n\nerror: transmute from `Ty<&Ty2<u32, i32>>` to `&Ty2<u32, f32>`, both of which have an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:58:33\n   |\nLL |         let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>());\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: two instances of the same generic type (`Ty2`) may have different layouts\n\nerror: transmute from `&Ty2<u32, f32>` to `Ty<&Ty2<u32, i32>>`, both of which have an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:62:37\n   |\nLL |         let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>());\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: two instances of the same generic type (`Ty2`) may have different layouts\n\nerror: transmute from `std::boxed::Box<Ty2<u32, u32>>` to `&mut Ty2<u32, f32>`, both of which have an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:91:45\n   |\nLL |         let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>());\n   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: two instances of the same generic type (`Ty2`) may have different layouts\n\nerror: transmute from `&mut Ty2<u32, f32>` to `std::boxed::Box<Ty2<u32, u32>>`, both of which have an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:95:37\n   |\nLL |         let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>());\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: two instances of the same generic type (`Ty2`) may have different layouts\n\nerror: transmute into `*const Ty2<u32, u32>` which has an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:191:39\n   |\nLL |         let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>());\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the contained type `Ty2<u32, u32>` has an undefined layout\n\nerror: transmute from `*const Ty2<u32, u32>` which has an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:195:50\n   |\nLL |         let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>());\n   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the contained type `Ty2<u32, u32>` has an undefined layout\n\nerror: transmute from `std::vec::Vec<Ty2<U, i32>>` to `std::vec::Vec<Ty2<T, u32>>`, both of which have an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:241:35\n   |\nLL |         let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>());\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: two instances of the same generic type (`Vec`) may have different layouts\n\nerror: transmute from `std::vec::Vec<Ty2<T, u32>>` to `std::vec::Vec<Ty2<U, i32>>`, both of which have an undefined layout\n  --> tests/ui/transmute_undefined_repr.rs:245:35\n   |\nLL |         let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>());\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: two instances of the same generic type (`Vec`) may have different layouts\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmutes_expressible_as_ptr_casts.fixed",
    "content": "#![warn(clippy::transmutes_expressible_as_ptr_casts)]\n// These two warnings currently cover the cases transmutes_expressible_as_ptr_casts\n// would otherwise be responsible for\n#![warn(clippy::useless_transmute)]\n#![warn(clippy::transmute_ptr_to_ptr)]\n#![allow(unused, clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]\n#![allow(function_casts_as_integer)]\n\nuse std::mem::{size_of, transmute};\n\n// rustc_hir_analysis::check::cast contains documentation about when a cast `e as U` is\n// valid, which we quote from below.\nfn main() {\n    // We should see an error message for each transmute, and no error messages for\n    // the casts, since the casts are the recommended fixes.\n\n    let ptr_i32 = usize::MAX as *const i32;\n\n    // e has type *T, U is *U_0, and either U_0: Sized ...\n    let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() };\n    //~^ transmute_ptr_to_ptr\n    let _ptr_i8 = ptr_i32 as *const i8;\n\n    let slice_ptr = &[0, 1, 2, 3] as *const [i32];\n\n    // ... or pointer_kind(T) = pointer_kind(U_0); ptr-ptr-cast\n    let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] };\n    //~^ transmute_ptr_to_ptr\n    let _ptr_to_unsized = slice_ptr as *const [u32];\n    // TODO: We could try testing vtable casts here too, but maybe\n    // we should wait until std::raw::TraitObject is stabilized?\n\n    // e has type *T and U is a numeric type, while T: Sized; ptr-addr-cast\n    let _usize_from_int_ptr_transmute = unsafe { ptr_i32 as usize };\n    //~^ transmutes_expressible_as_ptr_casts\n    let _usize_from_int_ptr = ptr_i32 as usize;\n\n    let array_ref: &[i32; 4] = &[1, 2, 3, 4];\n\n    // e has type &[T; n] and U is *const T; array-ptr-cast\n    let _array_ptr_transmute = unsafe { array_ref as *const [i32; 4] };\n    //~^ useless_transmute\n    let _array_ptr = array_ref as *const [i32; 4];\n\n    fn foo(_: usize) -> u8 {\n        42\n    }\n\n    // e is a function pointer type and U has type *T, while T: Sized; fptr-ptr-cast\n    let _usize_ptr_transmute = unsafe { foo as *const usize };\n    //~^ transmutes_expressible_as_ptr_casts\n    let _usize_ptr_transmute = foo as *const usize;\n\n    // e is a function pointer type and U is an integer; fptr-addr-cast\n    let _usize_from_fn_ptr_transmute = unsafe { foo as usize };\n    //~^ transmutes_expressible_as_ptr_casts\n    let _usize_from_fn_ptr = foo as *const usize;\n\n    let _usize_from_ref = unsafe { &1u32 as *const u32 as usize };\n    //~^ transmutes_expressible_as_ptr_casts\n}\n\n// If a ref-to-ptr cast of this form where the pointer type points to a type other\n// than the referenced type, calling `CastCheck::do_check` has been observed to\n// cause an ICE error message. `do_check` is currently called inside the\n// `transmutes_expressible_as_ptr_casts` check, but other, more specific lints\n// currently prevent it from being called in these cases. This test is meant to\n// fail if the ordering of the checks ever changes enough to cause these cases to\n// fall through into `do_check`.\nfn trigger_do_check_to_emit_error(in_param: &[i32; 1]) -> *const u8 {\n    unsafe { in_param as *const [i32; 1] as *const u8 }\n    //~^ useless_transmute\n}\n\n#[repr(C)]\nstruct Single(u64);\n\n#[repr(C)]\nstruct Pair(u32, u32);\n\nfn cannot_be_expressed_as_pointer_cast(in_param: Single) -> Pair {\n    assert_eq!(size_of::<Single>(), size_of::<Pair>());\n\n    unsafe { transmute::<Single, Pair>(in_param) }\n}\n\nfn issue_10449() {\n    fn f() {}\n\n    let _x: u8 = unsafe { *(f as *const u8) };\n    //~^ transmutes_expressible_as_ptr_casts\n}\n\n// Pointers cannot be cast to integers in const contexts\n#[allow(\n    ptr_to_integer_transmute_in_consts,\n    reason = \"This is tested in the compiler test suite\"\n)]\nconst fn issue_12402<P>(ptr: *const P) {\n    // This test exists even though the compiler lints against it\n    // to test that clippy's transmute lints do not trigger on this.\n    unsafe { std::mem::transmute::<*const i32, usize>(&42i32) };\n    unsafe { std::mem::transmute::<fn(*const P), usize>(issue_12402) };\n    let _ = unsafe { std::mem::transmute::<_, usize>(ptr) };\n}\n"
  },
  {
    "path": "tests/ui/transmutes_expressible_as_ptr_casts.rs",
    "content": "#![warn(clippy::transmutes_expressible_as_ptr_casts)]\n// These two warnings currently cover the cases transmutes_expressible_as_ptr_casts\n// would otherwise be responsible for\n#![warn(clippy::useless_transmute)]\n#![warn(clippy::transmute_ptr_to_ptr)]\n#![allow(unused, clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]\n#![allow(function_casts_as_integer)]\n\nuse std::mem::{size_of, transmute};\n\n// rustc_hir_analysis::check::cast contains documentation about when a cast `e as U` is\n// valid, which we quote from below.\nfn main() {\n    // We should see an error message for each transmute, and no error messages for\n    // the casts, since the casts are the recommended fixes.\n\n    let ptr_i32 = usize::MAX as *const i32;\n\n    // e has type *T, U is *U_0, and either U_0: Sized ...\n    let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) };\n    //~^ transmute_ptr_to_ptr\n    let _ptr_i8 = ptr_i32 as *const i8;\n\n    let slice_ptr = &[0, 1, 2, 3] as *const [i32];\n\n    // ... or pointer_kind(T) = pointer_kind(U_0); ptr-ptr-cast\n    let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) };\n    //~^ transmute_ptr_to_ptr\n    let _ptr_to_unsized = slice_ptr as *const [u32];\n    // TODO: We could try testing vtable casts here too, but maybe\n    // we should wait until std::raw::TraitObject is stabilized?\n\n    // e has type *T and U is a numeric type, while T: Sized; ptr-addr-cast\n    let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, usize>(ptr_i32) };\n    //~^ transmutes_expressible_as_ptr_casts\n    let _usize_from_int_ptr = ptr_i32 as usize;\n\n    let array_ref: &[i32; 4] = &[1, 2, 3, 4];\n\n    // e has type &[T; n] and U is *const T; array-ptr-cast\n    let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; 4]>(array_ref) };\n    //~^ useless_transmute\n    let _array_ptr = array_ref as *const [i32; 4];\n\n    fn foo(_: usize) -> u8 {\n        42\n    }\n\n    // e is a function pointer type and U has type *T, while T: Sized; fptr-ptr-cast\n    let _usize_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, *const usize>(foo) };\n    //~^ transmutes_expressible_as_ptr_casts\n    let _usize_ptr_transmute = foo as *const usize;\n\n    // e is a function pointer type and U is an integer; fptr-addr-cast\n    let _usize_from_fn_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, usize>(foo) };\n    //~^ transmutes_expressible_as_ptr_casts\n    let _usize_from_fn_ptr = foo as *const usize;\n\n    let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) };\n    //~^ transmutes_expressible_as_ptr_casts\n}\n\n// If a ref-to-ptr cast of this form where the pointer type points to a type other\n// than the referenced type, calling `CastCheck::do_check` has been observed to\n// cause an ICE error message. `do_check` is currently called inside the\n// `transmutes_expressible_as_ptr_casts` check, but other, more specific lints\n// currently prevent it from being called in these cases. This test is meant to\n// fail if the ordering of the checks ever changes enough to cause these cases to\n// fall through into `do_check`.\nfn trigger_do_check_to_emit_error(in_param: &[i32; 1]) -> *const u8 {\n    unsafe { transmute::<&[i32; 1], *const u8>(in_param) }\n    //~^ useless_transmute\n}\n\n#[repr(C)]\nstruct Single(u64);\n\n#[repr(C)]\nstruct Pair(u32, u32);\n\nfn cannot_be_expressed_as_pointer_cast(in_param: Single) -> Pair {\n    assert_eq!(size_of::<Single>(), size_of::<Pair>());\n\n    unsafe { transmute::<Single, Pair>(in_param) }\n}\n\nfn issue_10449() {\n    fn f() {}\n\n    let _x: u8 = unsafe { *std::mem::transmute::<fn(), *const u8>(f) };\n    //~^ transmutes_expressible_as_ptr_casts\n}\n\n// Pointers cannot be cast to integers in const contexts\n#[allow(\n    ptr_to_integer_transmute_in_consts,\n    reason = \"This is tested in the compiler test suite\"\n)]\nconst fn issue_12402<P>(ptr: *const P) {\n    // This test exists even though the compiler lints against it\n    // to test that clippy's transmute lints do not trigger on this.\n    unsafe { std::mem::transmute::<*const i32, usize>(&42i32) };\n    unsafe { std::mem::transmute::<fn(*const P), usize>(issue_12402) };\n    let _ = unsafe { std::mem::transmute::<_, usize>(ptr) };\n}\n"
  },
  {
    "path": "tests/ui/transmutes_expressible_as_ptr_casts.stderr",
    "content": "error: transmute from a pointer to a pointer\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:20:38\n   |\nLL |     let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) };\n   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`\nhelp: use `pointer::cast` instead\n   |\nLL -     let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) };\nLL +     let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() };\n   |\n\nerror: transmute from a pointer to a pointer\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46\n   |\nLL |     let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) };\n   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use an `as` cast instead\n   |\nLL -     let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) };\nLL +     let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] };\n   |\n\nerror: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:34:50\n   |\nLL |     let _usize_from_int_ptr_transmute = unsafe { transmute::<*const i32, usize>(ptr_i32) };\n   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr_i32 as usize`\n   |\n   = note: `-D clippy::transmutes-expressible-as-ptr-casts` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmutes_expressible_as_ptr_casts)]`\n\nerror: transmute from a reference to a pointer\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:41:41\n   |\nLL |     let _array_ptr_transmute = unsafe { transmute::<&[i32; 4], *const [i32; 4]>(array_ref) };\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `array_ref as *const [i32; 4]`\n   |\n   = note: `-D clippy::useless-transmute` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]`\n\nerror: transmute from `fn(usize) -> u8` to `*const usize` which could be expressed as a pointer cast instead\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:50:41\n   |\nLL |     let _usize_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, *const usize>(foo) };\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as *const usize`\n\nerror: transmute from `fn(usize) -> u8` to `usize` which could be expressed as a pointer cast instead\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:55:49\n   |\nLL |     let _usize_from_fn_ptr_transmute = unsafe { transmute::<fn(usize) -> u8, usize>(foo) };\n   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `foo as usize`\n\nerror: transmute from `*const u32` to `usize` which could be expressed as a pointer cast instead\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:59:36\n   |\nLL |     let _usize_from_ref = unsafe { transmute::<*const u32, usize>(&1u32) };\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&1u32 as *const u32 as usize`\n\nerror: transmute from a reference to a pointer\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:71:14\n   |\nLL |     unsafe { transmute::<&[i32; 1], *const u8>(in_param) }\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `in_param as *const [i32; 1] as *const u8`\n\nerror: transmute from `fn()` to `*const u8` which could be expressed as a pointer cast instead\n  --> tests/ui/transmutes_expressible_as_ptr_casts.rs:90:28\n   |\nLL |     let _x: u8 = unsafe { *std::mem::transmute::<fn(), *const u8>(f) };\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(f as *const u8)`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/transmuting_null.rs",
    "content": "#![allow(dead_code)]\n#![warn(clippy::transmuting_null)]\n#![allow(clippy::zero_ptr)]\n#![allow(clippy::transmute_ptr_to_ref)]\n#![allow(clippy::eq_op, clippy::missing_transmute_annotations)]\n#![allow(clippy::manual_dangling_ptr)]\n\n// Easy to lint because these only span one line.\nfn one_liners() {\n    unsafe {\n        let _: &u64 = std::mem::transmute(0 as *const u64);\n        //~^ transmuting_null\n\n        let _: &u64 = std::mem::transmute(std::ptr::null::<u64>());\n        //~^ transmuting_null\n    }\n}\n\npub const ZPTR: *const usize = 0 as *const _;\npub const NOT_ZPTR: *const usize = 1 as *const _;\n\nfn transmute_const() {\n    unsafe {\n        // Should raise a lint.\n        let _: &u64 = std::mem::transmute(ZPTR);\n        //~^ transmuting_null\n\n        // Should NOT raise a lint.\n        let _: &u64 = std::mem::transmute(NOT_ZPTR);\n    }\n}\n\nfn transmute_const_int() {\n    unsafe {\n        let _: &u64 = std::mem::transmute(u64::MIN as *const u64);\n        //~^ transmuting_null\n    }\n}\n\nfn transumute_single_expr_blocks() {\n    unsafe {\n        let _: &u64 = std::mem::transmute({ 0 as *const u64 });\n        //~^ transmuting_null\n\n        let _: &u64 = std::mem::transmute(const { u64::MIN as *const u64 });\n        //~^ transmuting_null\n    }\n}\n\nfn transmute_pointer_creators() {\n    unsafe {\n        let _: &u64 = std::mem::transmute(std::ptr::without_provenance::<u64>(0));\n        //~^ transmuting_null\n\n        let _: &u64 = std::mem::transmute(std::ptr::without_provenance_mut::<u64>(0));\n        //~^ transmuting_null\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/transmuting_null.stderr",
    "content": "error: transmuting a known null pointer into a reference\n  --> tests/ui/transmuting_null.rs:11:23\n   |\nLL |         let _: &u64 = std::mem::transmute(0 as *const u64);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::transmuting-null` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::transmuting_null)]`\n\nerror: transmuting a known null pointer into a reference\n  --> tests/ui/transmuting_null.rs:14:23\n   |\nLL |         let _: &u64 = std::mem::transmute(std::ptr::null::<u64>());\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmuting a known null pointer into a reference\n  --> tests/ui/transmuting_null.rs:25:23\n   |\nLL |         let _: &u64 = std::mem::transmute(ZPTR);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmuting a known null pointer into a reference\n  --> tests/ui/transmuting_null.rs:35:23\n   |\nLL |         let _: &u64 = std::mem::transmute(u64::MIN as *const u64);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmuting a known null pointer into a reference\n  --> tests/ui/transmuting_null.rs:42:23\n   |\nLL |         let _: &u64 = std::mem::transmute({ 0 as *const u64 });\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmuting a known null pointer into a reference\n  --> tests/ui/transmuting_null.rs:45:23\n   |\nLL |         let _: &u64 = std::mem::transmute(const { u64::MIN as *const u64 });\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmuting a known null pointer into a reference\n  --> tests/ui/transmuting_null.rs:52:23\n   |\nLL |         let _: &u64 = std::mem::transmute(std::ptr::without_provenance::<u64>(0));\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: transmuting a known null pointer into a reference\n  --> tests/ui/transmuting_null.rs:55:23\n   |\nLL |         let _: &u64 = std::mem::transmute(std::ptr::without_provenance_mut::<u64>(0));\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/trim_split_whitespace.fixed",
    "content": "#![warn(clippy::trim_split_whitespace)]\n#![allow(clippy::let_unit_value)]\n\nstruct Custom;\nimpl Custom {\n    fn trim(self) -> Self {\n        self\n    }\n    fn split_whitespace(self) {}\n}\n\nstruct DerefStr(&'static str);\nimpl std::ops::Deref for DerefStr {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.0\n    }\n}\n\nstruct DerefStrAndCustom(&'static str);\nimpl std::ops::Deref for DerefStrAndCustom {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.0\n    }\n}\nimpl DerefStrAndCustom {\n    fn trim(self) -> Self {\n        self\n    }\n    fn split_whitespace(self) {}\n}\n\nstruct DerefStrAndCustomSplit(&'static str);\nimpl std::ops::Deref for DerefStrAndCustomSplit {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.0\n    }\n}\nimpl DerefStrAndCustomSplit {\n    #[allow(dead_code)]\n    fn split_whitespace(self) {}\n}\n\nstruct DerefStrAndCustomTrim(&'static str);\nimpl std::ops::Deref for DerefStrAndCustomTrim {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.0\n    }\n}\nimpl DerefStrAndCustomTrim {\n    fn trim(self) -> Self {\n        self\n    }\n}\n\nfn main() {\n    // &str\n    let _ = \" A B C \".split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    let _ = \" A B C \".split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    let _ = \" A B C \".split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n\n    // String\n    let _ = (\" A B C \").to_string().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    let _ = (\" A B C \").to_string().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    let _ = (\" A B C \").to_string().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n\n    // Custom\n    let _ = Custom.trim().split_whitespace(); // should not trigger lint\n\n    // Deref<Target=str>\n    let s = DerefStr(\" A B C \");\n    let _ = s.split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n\n    // Deref<Target=str> + custom impl\n    let s = DerefStrAndCustom(\" A B C \");\n    let _ = s.trim().split_whitespace(); // should not trigger lint\n\n    // Deref<Target=str> + only custom split_ws() impl\n    let s = DerefStrAndCustomSplit(\" A B C \");\n    let _ = s.split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    // Expl: trim() is called on str (deref) and returns &str.\n    //       Thus split_ws() is called on str as well and the custom impl on S is unused\n\n    // Deref<Target=str> + only custom trim() impl\n    let s = DerefStrAndCustomTrim(\" A B C \");\n    let _ = s.trim().split_whitespace(); // should not trigger lint\n}\n"
  },
  {
    "path": "tests/ui/trim_split_whitespace.rs",
    "content": "#![warn(clippy::trim_split_whitespace)]\n#![allow(clippy::let_unit_value)]\n\nstruct Custom;\nimpl Custom {\n    fn trim(self) -> Self {\n        self\n    }\n    fn split_whitespace(self) {}\n}\n\nstruct DerefStr(&'static str);\nimpl std::ops::Deref for DerefStr {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.0\n    }\n}\n\nstruct DerefStrAndCustom(&'static str);\nimpl std::ops::Deref for DerefStrAndCustom {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.0\n    }\n}\nimpl DerefStrAndCustom {\n    fn trim(self) -> Self {\n        self\n    }\n    fn split_whitespace(self) {}\n}\n\nstruct DerefStrAndCustomSplit(&'static str);\nimpl std::ops::Deref for DerefStrAndCustomSplit {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.0\n    }\n}\nimpl DerefStrAndCustomSplit {\n    #[allow(dead_code)]\n    fn split_whitespace(self) {}\n}\n\nstruct DerefStrAndCustomTrim(&'static str);\nimpl std::ops::Deref for DerefStrAndCustomTrim {\n    type Target = str;\n    fn deref(&self) -> &Self::Target {\n        self.0\n    }\n}\nimpl DerefStrAndCustomTrim {\n    fn trim(self) -> Self {\n        self\n    }\n}\n\nfn main() {\n    // &str\n    let _ = \" A B C \".trim().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    let _ = \" A B C \".trim_start().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    let _ = \" A B C \".trim_end().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n\n    // String\n    let _ = (\" A B C \").to_string().trim().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    let _ = (\" A B C \").to_string().trim_start().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    let _ = (\" A B C \").to_string().trim_end().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n\n    // Custom\n    let _ = Custom.trim().split_whitespace(); // should not trigger lint\n\n    // Deref<Target=str>\n    let s = DerefStr(\" A B C \");\n    let _ = s.trim().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n\n    // Deref<Target=str> + custom impl\n    let s = DerefStrAndCustom(\" A B C \");\n    let _ = s.trim().split_whitespace(); // should not trigger lint\n\n    // Deref<Target=str> + only custom split_ws() impl\n    let s = DerefStrAndCustomSplit(\" A B C \");\n    let _ = s.trim().split_whitespace(); // should trigger lint\n    //\n    //~^^ trim_split_whitespace\n    // Expl: trim() is called on str (deref) and returns &str.\n    //       Thus split_ws() is called on str as well and the custom impl on S is unused\n\n    // Deref<Target=str> + only custom trim() impl\n    let s = DerefStrAndCustomTrim(\" A B C \");\n    let _ = s.trim().split_whitespace(); // should not trigger lint\n}\n"
  },
  {
    "path": "tests/ui/trim_split_whitespace.stderr",
    "content": "error: found call to `str::trim` before `str::split_whitespace`\n  --> tests/ui/trim_split_whitespace.rs:61:23\n   |\nLL |     let _ = \" A B C \".trim().split_whitespace(); // should trigger lint\n   |                       ^^^^^^^ help: remove `trim()`\n   |\n   = note: `-D clippy::trim-split-whitespace` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::trim_split_whitespace)]`\n\nerror: found call to `str::trim_start` before `str::split_whitespace`\n  --> tests/ui/trim_split_whitespace.rs:64:23\n   |\nLL |     let _ = \" A B C \".trim_start().split_whitespace(); // should trigger lint\n   |                       ^^^^^^^^^^^^^ help: remove `trim_start()`\n\nerror: found call to `str::trim_end` before `str::split_whitespace`\n  --> tests/ui/trim_split_whitespace.rs:67:23\n   |\nLL |     let _ = \" A B C \".trim_end().split_whitespace(); // should trigger lint\n   |                       ^^^^^^^^^^^ help: remove `trim_end()`\n\nerror: found call to `str::trim` before `str::split_whitespace`\n  --> tests/ui/trim_split_whitespace.rs:72:37\n   |\nLL |     let _ = (\" A B C \").to_string().trim().split_whitespace(); // should trigger lint\n   |                                     ^^^^^^^ help: remove `trim()`\n\nerror: found call to `str::trim_start` before `str::split_whitespace`\n  --> tests/ui/trim_split_whitespace.rs:75:37\n   |\nLL |     let _ = (\" A B C \").to_string().trim_start().split_whitespace(); // should trigger lint\n   |                                     ^^^^^^^^^^^^^ help: remove `trim_start()`\n\nerror: found call to `str::trim_end` before `str::split_whitespace`\n  --> tests/ui/trim_split_whitespace.rs:78:37\n   |\nLL |     let _ = (\" A B C \").to_string().trim_end().split_whitespace(); // should trigger lint\n   |                                     ^^^^^^^^^^^ help: remove `trim_end()`\n\nerror: found call to `str::trim` before `str::split_whitespace`\n  --> tests/ui/trim_split_whitespace.rs:87:15\n   |\nLL |     let _ = s.trim().split_whitespace(); // should trigger lint\n   |               ^^^^^^^ help: remove `trim()`\n\nerror: found call to `str::trim` before `str::split_whitespace`\n  --> tests/ui/trim_split_whitespace.rs:97:15\n   |\nLL |     let _ = s.trim().split_whitespace(); // should trigger lint\n   |               ^^^^^^^ help: remove `trim()`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/trivially_copy_pass_by_ref.fixed",
    "content": "//@normalize-stderr-test: \"\\(\\d+ byte\\)\" -> \"(N byte)\"\n//@normalize-stderr-test: \"\\(limit: \\d+ byte\\)\" -> \"(limit: N byte)\"\n#![deny(clippy::trivially_copy_pass_by_ref)]\n#![allow(\n    clippy::disallowed_names,\n    clippy::extra_unused_lifetimes,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_ref_mut,\n    clippy::redundant_field_names,\n    clippy::uninlined_format_args\n)]\n\n#[derive(Copy, Clone)]\nstruct Foo(u32);\n\n#[derive(Copy, Clone)]\nstruct Bar([u8; 24]);\n\n#[derive(Copy, Clone)]\npub struct Color {\n    pub r: u8,\n    pub g: u8,\n    pub b: u8,\n    pub a: u8,\n}\n\nstruct FooRef<'a> {\n    foo: &'a Foo,\n}\n\ntype Baz = u32;\n\nfn good(a: &mut u32, b: u32, c: &Bar) {}\n\nfn good_return_implicit_lt_ref(foo: &Foo) -> &u32 {\n    &foo.0\n}\n\n#[allow(clippy::needless_lifetimes)]\nfn good_return_explicit_lt_ref<'a>(foo: &'a Foo) -> &'a u32 {\n    &foo.0\n}\n\n#[allow(mismatched_lifetime_syntaxes)]\nfn good_return_implicit_lt_struct(foo: &Foo) -> FooRef {\n    FooRef { foo }\n}\n\n#[allow(clippy::needless_lifetimes)]\nfn good_return_explicit_lt_struct<'a>(foo: &'a Foo) -> FooRef<'a> {\n    FooRef { foo }\n}\n\nfn bad(x: u32, y: Foo, z: Baz) {}\n//~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n//~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n//~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n\nimpl Foo {\n    fn good(self, a: &mut u32, b: u32, c: &Bar) {}\n\n    fn good2(&mut self) {}\n\n    fn bad(self, x: u32, y: Foo, z: Baz) {}\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n\n    fn bad2(x: u32, y: Foo, z: Baz) {}\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n\n    fn bad_issue7518(self, other: Self) {}\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n}\n\nimpl AsRef<u32> for Foo {\n    fn as_ref(&self) -> &u32 {\n        &self.0\n    }\n}\n\nimpl Bar {\n    fn good(&self, a: &mut u32, b: u32, c: &Bar) {}\n\n    fn bad2(x: u32, y: Foo, z: Baz) {}\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n}\n\ntrait MyTrait {\n    fn trait_method(&self, foo: Foo);\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n}\n\npub trait MyTrait2 {\n    fn trait_method2(&self, color: &Color);\n}\n\ntrait MyTrait3 {\n    #[expect(clippy::trivially_copy_pass_by_ref)]\n    fn trait_method(&self, foo: &Foo);\n}\n\n// Trait impls should not warn\nimpl MyTrait3 for Foo {\n    fn trait_method(&self, foo: &Foo) {\n        unimplemented!()\n    }\n}\n\nmod issue3992 {\n    pub trait A {\n        #[allow(clippy::trivially_copy_pass_by_ref)]\n        fn a(b: &u16) {}\n    }\n\n    #[allow(clippy::trivially_copy_pass_by_ref)]\n    pub fn c(d: &u16) {}\n}\n\nmod issue5876 {\n    // Don't lint here as it is always inlined\n    #[inline(always)]\n    fn foo_always(x: &i32) {\n        println!(\"{}\", x);\n    }\n\n    #[inline(never)]\n    fn foo_never(x: i32) {\n        //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n        println!(\"{}\", x);\n    }\n\n    #[inline]\n    fn foo(x: i32) {\n        //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n        println!(\"{}\", x);\n    }\n}\n\nfn ref_to_opt_ref_implicit(x: &u32) -> Option<&u32> {\n    Some(x)\n}\n\nfn ref_to_opt_ref_explicit<'a>(x: &'a u32) -> Option<&'a u32> {\n    Some(x)\n}\n\nfn with_constraint<'a, 'b: 'a>(x: &'b u32, y: &'a u32) -> &'a u32 {\n    if true { x } else { y }\n}\n\nasync fn async_implicit(x: &u32) -> &u32 {\n    x\n}\n\nasync fn async_explicit<'a>(x: &'a u32) -> &'a u32 {\n    x\n}\n\nfn unrelated_lifetimes<'a, 'b>(_x: u32, y: &'b u32) -> &'b u32 {\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    y\n}\n\nfn return_ptr(x: &u32) -> *const u32 {\n    x\n}\n\nfn return_field_ptr(x: &(u32, u32)) -> *const u32 {\n    &x.0\n}\n\nfn return_field_ptr_addr_of(x: &(u32, u32)) -> *const u32 {\n    core::ptr::addr_of!(x.0)\n}\n"
  },
  {
    "path": "tests/ui/trivially_copy_pass_by_ref.rs",
    "content": "//@normalize-stderr-test: \"\\(\\d+ byte\\)\" -> \"(N byte)\"\n//@normalize-stderr-test: \"\\(limit: \\d+ byte\\)\" -> \"(limit: N byte)\"\n#![deny(clippy::trivially_copy_pass_by_ref)]\n#![allow(\n    clippy::disallowed_names,\n    clippy::extra_unused_lifetimes,\n    clippy::needless_lifetimes,\n    clippy::needless_pass_by_ref_mut,\n    clippy::redundant_field_names,\n    clippy::uninlined_format_args\n)]\n\n#[derive(Copy, Clone)]\nstruct Foo(u32);\n\n#[derive(Copy, Clone)]\nstruct Bar([u8; 24]);\n\n#[derive(Copy, Clone)]\npub struct Color {\n    pub r: u8,\n    pub g: u8,\n    pub b: u8,\n    pub a: u8,\n}\n\nstruct FooRef<'a> {\n    foo: &'a Foo,\n}\n\ntype Baz = u32;\n\nfn good(a: &mut u32, b: u32, c: &Bar) {}\n\nfn good_return_implicit_lt_ref(foo: &Foo) -> &u32 {\n    &foo.0\n}\n\n#[allow(clippy::needless_lifetimes)]\nfn good_return_explicit_lt_ref<'a>(foo: &'a Foo) -> &'a u32 {\n    &foo.0\n}\n\n#[allow(mismatched_lifetime_syntaxes)]\nfn good_return_implicit_lt_struct(foo: &Foo) -> FooRef {\n    FooRef { foo }\n}\n\n#[allow(clippy::needless_lifetimes)]\nfn good_return_explicit_lt_struct<'a>(foo: &'a Foo) -> FooRef<'a> {\n    FooRef { foo }\n}\n\nfn bad(x: &u32, y: &Foo, z: &Baz) {}\n//~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n//~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n//~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n\nimpl Foo {\n    fn good(self, a: &mut u32, b: u32, c: &Bar) {}\n\n    fn good2(&mut self) {}\n\n    fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n\n    fn bad2(x: &u32, y: &Foo, z: &Baz) {}\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n\n    fn bad_issue7518(self, other: &Self) {}\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n}\n\nimpl AsRef<u32> for Foo {\n    fn as_ref(&self) -> &u32 {\n        &self.0\n    }\n}\n\nimpl Bar {\n    fn good(&self, a: &mut u32, b: u32, c: &Bar) {}\n\n    fn bad2(x: &u32, y: &Foo, z: &Baz) {}\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n    //~| ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n}\n\ntrait MyTrait {\n    fn trait_method(&self, foo: &Foo);\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if\n}\n\npub trait MyTrait2 {\n    fn trait_method2(&self, color: &Color);\n}\n\ntrait MyTrait3 {\n    #[expect(clippy::trivially_copy_pass_by_ref)]\n    fn trait_method(&self, foo: &Foo);\n}\n\n// Trait impls should not warn\nimpl MyTrait3 for Foo {\n    fn trait_method(&self, foo: &Foo) {\n        unimplemented!()\n    }\n}\n\nmod issue3992 {\n    pub trait A {\n        #[allow(clippy::trivially_copy_pass_by_ref)]\n        fn a(b: &u16) {}\n    }\n\n    #[allow(clippy::trivially_copy_pass_by_ref)]\n    pub fn c(d: &u16) {}\n}\n\nmod issue5876 {\n    // Don't lint here as it is always inlined\n    #[inline(always)]\n    fn foo_always(x: &i32) {\n        println!(\"{}\", x);\n    }\n\n    #[inline(never)]\n    fn foo_never(x: &i32) {\n        //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n        println!(\"{}\", x);\n    }\n\n    #[inline]\n    fn foo(x: &i32) {\n        //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n        println!(\"{}\", x);\n    }\n}\n\nfn ref_to_opt_ref_implicit(x: &u32) -> Option<&u32> {\n    Some(x)\n}\n\nfn ref_to_opt_ref_explicit<'a>(x: &'a u32) -> Option<&'a u32> {\n    Some(x)\n}\n\nfn with_constraint<'a, 'b: 'a>(x: &'b u32, y: &'a u32) -> &'a u32 {\n    if true { x } else { y }\n}\n\nasync fn async_implicit(x: &u32) -> &u32 {\n    x\n}\n\nasync fn async_explicit<'a>(x: &'a u32) -> &'a u32 {\n    x\n}\n\nfn unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 {\n    //~^ ERROR: this argument (4 byte) is passed by reference, but would be more efficient if passed by\n    y\n}\n\nfn return_ptr(x: &u32) -> *const u32 {\n    x\n}\n\nfn return_field_ptr(x: &(u32, u32)) -> *const u32 {\n    &x.0\n}\n\nfn return_field_ptr_addr_of(x: &(u32, u32)) -> *const u32 {\n    core::ptr::addr_of!(x.0)\n}\n"
  },
  {
    "path": "tests/ui/trivially_copy_pass_by_ref.stderr",
    "content": "error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:54:11\n   |\nLL | fn bad(x: &u32, y: &Foo, z: &Baz) {}\n   |           ^^^^ help: consider passing by value instead: `u32`\n   |\nnote: the lint level is defined here\n  --> tests/ui/trivially_copy_pass_by_ref.rs:3:9\n   |\nLL | #![deny(clippy::trivially_copy_pass_by_ref)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:54:20\n   |\nLL | fn bad(x: &u32, y: &Foo, z: &Baz) {}\n   |                    ^^^^ help: consider passing by value instead: `Foo`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:54:29\n   |\nLL | fn bad(x: &u32, y: &Foo, z: &Baz) {}\n   |                             ^^^^ help: consider passing by value instead: `Baz`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:64:12\n   |\nLL |     fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}\n   |            ^^^^^ help: consider passing by value instead: `self`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:64:22\n   |\nLL |     fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}\n   |                      ^^^^ help: consider passing by value instead: `u32`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:64:31\n   |\nLL |     fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}\n   |                               ^^^^ help: consider passing by value instead: `Foo`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:64:40\n   |\nLL |     fn bad(&self, x: &u32, y: &Foo, z: &Baz) {}\n   |                                        ^^^^ help: consider passing by value instead: `Baz`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:70:16\n   |\nLL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}\n   |                ^^^^ help: consider passing by value instead: `u32`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:70:25\n   |\nLL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}\n   |                         ^^^^ help: consider passing by value instead: `Foo`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:70:34\n   |\nLL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}\n   |                                  ^^^^ help: consider passing by value instead: `Baz`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:75:35\n   |\nLL |     fn bad_issue7518(self, other: &Self) {}\n   |                                   ^^^^^ help: consider passing by value instead: `Self`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:88:16\n   |\nLL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}\n   |                ^^^^ help: consider passing by value instead: `u32`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:88:25\n   |\nLL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}\n   |                         ^^^^ help: consider passing by value instead: `Foo`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:88:34\n   |\nLL |     fn bad2(x: &u32, y: &Foo, z: &Baz) {}\n   |                                  ^^^^ help: consider passing by value instead: `Baz`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:95:33\n   |\nLL |     fn trait_method(&self, foo: &Foo);\n   |                                 ^^^^ help: consider passing by value instead: `Foo`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:133:21\n   |\nLL |     fn foo_never(x: &i32) {\n   |                     ^^^^ help: consider passing by value instead: `i32`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:139:15\n   |\nLL |     fn foo(x: &i32) {\n   |               ^^^^ help: consider passing by value instead: `i32`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui/trivially_copy_pass_by_ref.rs:165:36\n   |\nLL | fn unrelated_lifetimes<'a, 'b>(_x: &'a u32, y: &'b u32) -> &'b u32 {\n   |                                    ^^^^^^^ help: consider passing by value instead: `u32`\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/try_err.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![feature(try_blocks)]\n#![deny(clippy::try_err)]\n#![allow(\n    clippy::unnecessary_wraps,\n    clippy::needless_question_mark,\n    clippy::needless_return_with_question_mark\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nuse std::io;\nuse std::task::Poll;\n\n// Tests that a simple case works\n// Should flag `Err(err)?`\npub fn basic_test() -> Result<i32, i32> {\n    let err: i32 = 1;\n    // To avoid warnings during rustfix\n    if true {\n        return Err(err);\n        //~^ try_err\n    }\n    Ok(0)\n}\n\n// Tests that `.into()` is added when appropriate\npub fn into_test() -> Result<i32, i32> {\n    let err: u8 = 1;\n    // To avoid warnings during rustfix\n    if true {\n        return Err(err.into());\n        //~^ try_err\n    }\n    Ok(0)\n}\n\n// Tests that tries in general don't trigger the error\npub fn negative_test() -> Result<i32, i32> {\n    Ok(nested_error()? + 1)\n}\n\n// Tests that `.into()` isn't added when the error type\n// matches the surrounding closure's return type, even\n// when it doesn't match the surrounding function's.\npub fn closure_matches_test() -> Result<i32, i32> {\n    let res: Result<i32, i8> = Some(1)\n        .into_iter()\n        .map(|i| {\n            let err: i8 = 1;\n            // To avoid warnings during rustfix\n            if true {\n                return Err(err);\n                //~^ try_err\n            }\n            Ok(i)\n        })\n        .next()\n        .unwrap();\n\n    Ok(res?)\n}\n\n// Tests that `.into()` isn't added when the error type\n// doesn't match the surrounding closure's return type.\npub fn closure_into_test() -> Result<i32, i32> {\n    let res: Result<i32, i16> = Some(1)\n        .into_iter()\n        .map(|i| {\n            let err: i8 = 1;\n            // To avoid warnings during rustfix\n            if true {\n                return Err(err.into());\n                //~^ try_err\n            }\n            Ok(i)\n        })\n        .next()\n        .unwrap();\n\n    Ok(res?)\n}\n\nfn nested_error() -> Result<i32, i32> {\n    Ok(1)\n}\n\n#[inline_macros]\nfn calling_macro() -> Result<i32, i32> {\n    // macro\n    inline!(\n        match $(Ok::<_, i32>(5)) {\n            Ok(_) => 0,\n            Err(_) => return Err(1),\n            //~^ try_err\n        }\n    );\n    // `Err` arg is another macro\n    inline!(\n        match $(Ok::<_, i32>(5)) {\n            Ok(_) => 0,\n            Err(_) => return Err(inline!(1)),\n            //~^ try_err\n        }\n    );\n    Ok(5)\n}\n\n// We don't want to lint in external macros\nexternal! {\n    pub fn try_err_fn() -> Result<i32, i32> {\n        let err: i32 = 1;\n        // To avoid warnings during rustfix\n        if true { Err(err)? } else { Ok(2) }\n    }\n}\n\nfn main() {}\n\n#[inline_macros]\npub fn macro_inside(fail: bool) -> Result<i32, String> {\n    if fail {\n        return Err(inline!(inline!(String::from(\"aasdfasdfasdfa\"))));\n        //~^ try_err\n    }\n    Ok(0)\n}\n\npub fn poll_write(n: usize) -> Poll<io::Result<usize>> {\n    if n == 0 {\n        return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))\n        //~^ try_err\n    } else if n == 1 {\n        return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, \"error\")))\n        //~^ try_err\n    };\n\n    Poll::Ready(Ok(n))\n}\n\npub fn poll_next(ready: bool) -> Poll<Option<io::Result<()>>> {\n    if !ready {\n        return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))\n        //~^ try_err\n    }\n\n    Poll::Ready(None)\n}\n\n// Tests that `return` is not duplicated\npub fn try_return(x: bool) -> Result<i32, i32> {\n    if x {\n        return Err(42);\n        //~^ try_err\n    }\n    Ok(0)\n}\n\n// Test that the lint is suppressed in try block.\npub fn try_block() -> Result<(), i32> {\n    let _: Result<_, i32> = try {\n        Err(1)?;\n    };\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/try_err.rs",
    "content": "//@aux-build:proc_macros.rs\n#![feature(try_blocks)]\n#![deny(clippy::try_err)]\n#![allow(\n    clippy::unnecessary_wraps,\n    clippy::needless_question_mark,\n    clippy::needless_return_with_question_mark\n)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros};\n\nuse std::io;\nuse std::task::Poll;\n\n// Tests that a simple case works\n// Should flag `Err(err)?`\npub fn basic_test() -> Result<i32, i32> {\n    let err: i32 = 1;\n    // To avoid warnings during rustfix\n    if true {\n        Err(err)?;\n        //~^ try_err\n    }\n    Ok(0)\n}\n\n// Tests that `.into()` is added when appropriate\npub fn into_test() -> Result<i32, i32> {\n    let err: u8 = 1;\n    // To avoid warnings during rustfix\n    if true {\n        Err(err)?;\n        //~^ try_err\n    }\n    Ok(0)\n}\n\n// Tests that tries in general don't trigger the error\npub fn negative_test() -> Result<i32, i32> {\n    Ok(nested_error()? + 1)\n}\n\n// Tests that `.into()` isn't added when the error type\n// matches the surrounding closure's return type, even\n// when it doesn't match the surrounding function's.\npub fn closure_matches_test() -> Result<i32, i32> {\n    let res: Result<i32, i8> = Some(1)\n        .into_iter()\n        .map(|i| {\n            let err: i8 = 1;\n            // To avoid warnings during rustfix\n            if true {\n                Err(err)?;\n                //~^ try_err\n            }\n            Ok(i)\n        })\n        .next()\n        .unwrap();\n\n    Ok(res?)\n}\n\n// Tests that `.into()` isn't added when the error type\n// doesn't match the surrounding closure's return type.\npub fn closure_into_test() -> Result<i32, i32> {\n    let res: Result<i32, i16> = Some(1)\n        .into_iter()\n        .map(|i| {\n            let err: i8 = 1;\n            // To avoid warnings during rustfix\n            if true {\n                Err(err)?;\n                //~^ try_err\n            }\n            Ok(i)\n        })\n        .next()\n        .unwrap();\n\n    Ok(res?)\n}\n\nfn nested_error() -> Result<i32, i32> {\n    Ok(1)\n}\n\n#[inline_macros]\nfn calling_macro() -> Result<i32, i32> {\n    // macro\n    inline!(\n        match $(Ok::<_, i32>(5)) {\n            Ok(_) => 0,\n            Err(_) => Err(1)?,\n            //~^ try_err\n        }\n    );\n    // `Err` arg is another macro\n    inline!(\n        match $(Ok::<_, i32>(5)) {\n            Ok(_) => 0,\n            Err(_) => Err(inline!(1))?,\n            //~^ try_err\n        }\n    );\n    Ok(5)\n}\n\n// We don't want to lint in external macros\nexternal! {\n    pub fn try_err_fn() -> Result<i32, i32> {\n        let err: i32 = 1;\n        // To avoid warnings during rustfix\n        if true { Err(err)? } else { Ok(2) }\n    }\n}\n\nfn main() {}\n\n#[inline_macros]\npub fn macro_inside(fail: bool) -> Result<i32, String> {\n    if fail {\n        Err(inline!(inline!(String::from(\"aasdfasdfasdfa\"))))?;\n        //~^ try_err\n    }\n    Ok(0)\n}\n\npub fn poll_write(n: usize) -> Poll<io::Result<usize>> {\n    if n == 0 {\n        Err(io::ErrorKind::WriteZero)?\n        //~^ try_err\n    } else if n == 1 {\n        Err(io::Error::new(io::ErrorKind::InvalidInput, \"error\"))?\n        //~^ try_err\n    };\n\n    Poll::Ready(Ok(n))\n}\n\npub fn poll_next(ready: bool) -> Poll<Option<io::Result<()>>> {\n    if !ready {\n        Err(io::ErrorKind::NotFound)?\n        //~^ try_err\n    }\n\n    Poll::Ready(None)\n}\n\n// Tests that `return` is not duplicated\npub fn try_return(x: bool) -> Result<i32, i32> {\n    if x {\n        return Err(42)?;\n        //~^ try_err\n    }\n    Ok(0)\n}\n\n// Test that the lint is suppressed in try block.\npub fn try_block() -> Result<(), i32> {\n    let _: Result<_, i32> = try {\n        Err(1)?;\n    };\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/try_err.stderr",
    "content": "error: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:22:9\n   |\nLL |         Err(err)?;\n   |         ^^^^^^^^^ help: try: `return Err(err)`\n   |\nnote: the lint level is defined here\n  --> tests/ui/try_err.rs:3:9\n   |\nLL | #![deny(clippy::try_err)]\n   |         ^^^^^^^^^^^^^^^\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:33:9\n   |\nLL |         Err(err)?;\n   |         ^^^^^^^^^ help: try: `return Err(err.into())`\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:54:17\n   |\nLL |                 Err(err)?;\n   |                 ^^^^^^^^^ help: try: `return Err(err)`\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:74:17\n   |\nLL |                 Err(err)?;\n   |                 ^^^^^^^^^ help: try: `return Err(err.into())`\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:95:23\n   |\nLL |             Err(_) => Err(1)?,\n   |                       ^^^^^^^ help: try: `return Err(1)`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:103:23\n   |\nLL |             Err(_) => Err(inline!(1))?,\n   |                       ^^^^^^^^^^^^^^^^ help: try: `return Err(inline!(1))`\n   |\n   = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:124:9\n   |\nLL |         Err(inline!(inline!(String::from(\"aasdfasdfasdfa\"))))?;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Err(inline!(inline!(String::from(\"aasdfasdfasdfa\"))))`\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:132:9\n   |\nLL |         Err(io::ErrorKind::WriteZero)?\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))`\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:135:9\n   |\nLL |         Err(io::Error::new(io::ErrorKind::InvalidInput, \"error\"))?\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, \"error\")))`\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:144:9\n   |\nLL |         Err(io::ErrorKind::NotFound)?\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))`\n\nerror: returning an `Err(_)` with the `?` operator\n  --> tests/ui/try_err.rs:154:16\n   |\nLL |         return Err(42)?;\n   |                ^^^^^^^^ help: try: `Err(42)`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/tuple_array_conversions.rs",
    "content": "//@aux-build:proc_macros.rs\n#![allow(clippy::no_effect, clippy::useless_vec, unused)]\n#![warn(clippy::tuple_array_conversions)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    let x = [1, 2];\n    let x = (x[0], x[1]);\n    //~^ tuple_array_conversions\n    let x = [x.0, x.1];\n    //~^ tuple_array_conversions\n    let x = &[1, 2];\n    let x = (x[0], x[1]);\n\n    let t1: &[(u32, u32)] = &[(1, 2), (3, 4)];\n    let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect();\n    //~^ tuple_array_conversions\n    t1.iter().for_each(|&(a, b)| _ = [a, b]);\n    //~^ tuple_array_conversions\n    let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect();\n    //~^ tuple_array_conversions\n    t1.iter().for_each(|&(a, b)| _ = [a, b]);\n    //~^ tuple_array_conversions\n    // Do not lint\n    let v2: Vec<[u32; 2]> = t1.iter().map(|&t| t.into()).collect();\n    let t3: Vec<(u32, u32)> = v2.iter().map(|&v| v.into()).collect();\n    let x = [1; 13];\n    let x = (\n        x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12],\n    );\n    let x = [x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7, x.8, x.9, x.10, x.11, x.12];\n    let x = (1, 2);\n    let x = (x.0, x.1);\n    let x = [1, 2];\n    let x = [x[0], x[1]];\n    let x = vec![1, 2];\n    let x = (x[0], x[1]);\n    let x = [1; 3];\n    let x = (x[0],);\n    let x = (1, 2, 3);\n    let x = [x.0];\n    let x = (1, 2);\n    let y = (1, 2);\n    [x.0, y.0];\n    [x.0, y.1];\n    let x = [x.0, x.0];\n    let x = (x[0], x[0]);\n    external! {\n        let t1: &[(u32, u32)] = &[(1, 2), (3, 4)];\n        let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect();\n        let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect();\n    }\n    with_span! {\n        span\n        let t1: &[(u32, u32)] = &[(1, 2), (3, 4)];\n        let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect();\n        let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect();\n    }\n    // FP #11082; needs discussion\n    let (a, b) = (1.0f64, 2.0f64);\n    let _: &[f64] = &[a, b];\n    //~^ tuple_array_conversions\n    // FP #11085; impossible to fix\n    let [src, dest]: [_; 2] = [1, 2];\n    (src, dest);\n    //~^ tuple_array_conversions\n    // FP #11100\n    fn issue_11100_array_to_tuple(this: [&mut i32; 2]) -> (&i32, &mut i32) {\n        let [input, output] = this;\n        (input, output)\n    }\n\n    fn issue_11100_tuple_to_array<'a>(this: (&'a mut i32, &'a mut i32)) -> [&'a i32; 2] {\n        let (input, output) = this;\n        [input, output]\n    }\n    // FP #11124\n    // tuple=>array\n    let (a, b) = (1, 2);\n    [a, b];\n    let x = a;\n    // array=>tuple\n    let [a, b] = [1, 2];\n    (a, b);\n    let x = a;\n    // FP #11144\n    let (a, (b, c)) = (1, (2, 3));\n    [a, c];\n    let [[a, b], [c, d]] = [[1, 2], [3, 4]];\n    (a, c);\n    // Array length is not usize (#11144)\n    fn generic_array_length<const N: usize>() {\n        let src = [0; N];\n        let dest: (u8,) = (src[0],);\n    }\n}\n\n#[clippy::msrv = \"1.70.0\"]\nfn msrv_too_low() {\n    let x = [1, 2];\n    let x = (x[0], x[1]);\n    let x = [x.0, x.1];\n    let x = &[1, 2];\n    let x = (x[0], x[1]);\n}\n\n#[clippy::msrv = \"1.71.0\"]\nfn msrv_juust_right() {\n    let x = [1, 2];\n    let x = (x[0], x[1]);\n    //~^ tuple_array_conversions\n    let x = [x.0, x.1];\n    //~^ tuple_array_conversions\n    let x = &[1, 2];\n    let x = (x[0], x[1]);\n}\n\nfn issue16192() {\n    fn do_something(tuple: (u32, u32)) {}\n    fn produce_array() -> [u32; 2] {\n        [1, 2]\n    }\n\n    let [a, b] = produce_array();\n    for tuple in [(a, b), (b, a)] {\n        do_something(tuple);\n    }\n\n    let [a, b] = produce_array();\n    let x = b;\n    do_something((a, b));\n\n    let [a, b] = produce_array();\n    do_something((b, a));\n\n    let [a, b] = produce_array();\n    do_something((a, b));\n    //~^ tuple_array_conversions\n}\n"
  },
  {
    "path": "tests/ui/tuple_array_conversions.stderr",
    "content": "error: it looks like you're trying to convert an array to a tuple\n  --> tests/ui/tuple_array_conversions.rs:10:13\n   |\nLL |     let x = (x[0], x[1]);\n   |             ^^^^^^^^^^^^\n   |\n   = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed\n   = note: `-D clippy::tuple-array-conversions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::tuple_array_conversions)]`\n\nerror: it looks like you're trying to convert a tuple to an array\n  --> tests/ui/tuple_array_conversions.rs:12:13\n   |\nLL |     let x = [x.0, x.1];\n   |             ^^^^^^^^^^\n   |\n   = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert a tuple to an array\n  --> tests/ui/tuple_array_conversions.rs:18:53\n   |\nLL |     let v1: Vec<[u32; 2]> = t1.iter().map(|&(a, b)| [a, b]).collect();\n   |                                                     ^^^^^^\n   |\n   = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert a tuple to an array\n  --> tests/ui/tuple_array_conversions.rs:20:38\n   |\nLL |     t1.iter().for_each(|&(a, b)| _ = [a, b]);\n   |                                      ^^^^^^\n   |\n   = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert an array to a tuple\n  --> tests/ui/tuple_array_conversions.rs:22:55\n   |\nLL |     let t2: Vec<(u32, u32)> = v1.iter().map(|&[a, b]| (a, b)).collect();\n   |                                                       ^^^^^^\n   |\n   = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert a tuple to an array\n  --> tests/ui/tuple_array_conversions.rs:24:38\n   |\nLL |     t1.iter().for_each(|&(a, b)| _ = [a, b]);\n   |                                      ^^^^^^\n   |\n   = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert a tuple to an array\n  --> tests/ui/tuple_array_conversions.rs:63:22\n   |\nLL |     let _: &[f64] = &[a, b];\n   |                      ^^^^^^\n   |\n   = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert an array to a tuple\n  --> tests/ui/tuple_array_conversions.rs:67:5\n   |\nLL |     (src, dest);\n   |     ^^^^^^^^^^^\n   |\n   = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert an array to a tuple\n  --> tests/ui/tuple_array_conversions.rs:112:13\n   |\nLL |     let x = (x[0], x[1]);\n   |             ^^^^^^^^^^^^\n   |\n   = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert a tuple to an array\n  --> tests/ui/tuple_array_conversions.rs:114:13\n   |\nLL |     let x = [x.0, x.1];\n   |             ^^^^^^^^^^\n   |\n   = help: use `.into()` instead, or `<[T; N]>::from` if type annotations are needed\n\nerror: it looks like you're trying to convert an array to a tuple\n  --> tests/ui/tuple_array_conversions.rs:139:18\n   |\nLL |     do_something((a, b));\n   |                  ^^^^^^\n   |\n   = help: use `.into()` instead, or `<(T0, T1, ..., Tn)>::from` if type annotations are needed\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/ty_fn_sig.rs",
    "content": "//@ check-pass\n// Regression test\n\npub fn retry<F: Fn()>(f: F) {\n    for _i in 0.. {\n        f();\n    }\n}\n\nfn main() {\n    for y in 0..4 {\n        let func = || ();\n        func();\n    }\n}\n"
  },
  {
    "path": "tests/ui/type_complexity.rs",
    "content": "#![feature(associated_type_defaults)]\n#![allow(clippy::needless_pass_by_value, clippy::vec_box, clippy::useless_vec)]\n\ntype Alias = Vec<Vec<Box<(u32, u32, u32, u32)>>>; // no warning here\n\nconst CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));\n//~^ type_complexity\n\nstatic ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));\n//~^ type_complexity\n\nstruct S {\n    f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,\n    //~^ type_complexity\n}\n\nstruct Ts(Vec<Vec<Box<(u32, u32, u32, u32)>>>);\n//~^ type_complexity\n\nenum E {\n    Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),\n    //~^ type_complexity\n    Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },\n    //~^ type_complexity\n}\n\nimpl S {\n    const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));\n    //~^ type_complexity\n\n    fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}\n    //~^ type_complexity\n}\n\ntrait T {\n    const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;\n    //~^ type_complexity\n\n    type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;\n    //~^ type_complexity\n\n    fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);\n    //~^ type_complexity\n\n    fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}\n    //~^ type_complexity\n}\n\n// Should not warn since there is likely no way to simplify this (#1013)\nimpl T for () {\n    const A: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];\n\n    type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;\n\n    fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}\n}\n\nfn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> {\n    //~^ type_complexity\n\n    vec![]\n}\n\nfn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}\n//~^ type_complexity\n\nfn test3() {\n    let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];\n    //~^ type_complexity\n}\n\n#[repr(C)]\nstruct D {\n    // should not warn, since we don't have control over the signature (#3222)\n    test4: extern \"C\" fn(\n        itself: &D,\n        a: usize,\n        b: usize,\n        c: usize,\n        d: usize,\n        e: usize,\n        f: usize,\n        g: usize,\n        h: usize,\n        i: usize,\n    ),\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/type_complexity.stderr",
    "content": "error: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:6:12\n   |\nLL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::type-complexity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:9:12\n   |\nLL | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:13:8\n   |\nLL |     f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:17:11\n   |\nLL | struct Ts(Vec<Vec<Box<(u32, u32, u32, u32)>>>);\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:21:11\n   |\nLL |     Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:23:17\n   |\nLL |     Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:28:14\n   |\nLL |     const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:31:30\n   |\nLL |     fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:36:14\n   |\nLL |     const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:39:14\n   |\nLL |     type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:42:25\n   |\nLL |     fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:45:29\n   |\nLL |     fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:58:15\n   |\nLL | fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> {\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:64:14\n   |\nLL | fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui/type_complexity.rs:68:13\n   |\nLL |     let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/type_id_on_box.fixed",
    "content": "#![warn(clippy::type_id_on_box)]\n\nuse std::any::{Any, TypeId};\nuse std::ops::Deref;\n\ntype SomeBox = Box<dyn Any>;\n\nstruct BadBox(Box<dyn Any>);\n\nimpl Deref for BadBox {\n    type Target = Box<dyn Any>;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nfn existential() -> impl Any {\n    Box::new(1) as Box<dyn Any>\n}\n\ntrait AnySubTrait: Any {}\nimpl<T: Any> AnySubTrait for T {}\n\nfn main() {\n    // Don't lint, calling `.type_id()` on a `&dyn Any` does the expected thing\n    let ref_dyn: &dyn Any = &42;\n    let _ = ref_dyn.type_id();\n\n    let any_box: Box<dyn Any> = Box::new(0usize);\n    let _ = (*any_box).type_id();\n    //~^ type_id_on_box\n\n    // Don't lint. We explicitly say \"do this instead\" if this is intentional\n    let _ = TypeId::of::<Box<dyn Any>>();\n    let _ = (*any_box).type_id();\n\n    // 2 derefs are needed here to get to the `dyn Any`\n    let any_box: &Box<dyn Any> = &(Box::new(0usize) as Box<dyn Any>);\n    let _ = (**any_box).type_id();\n    //~^ type_id_on_box\n\n    let b = existential();\n    let _ = b.type_id(); // Don't\n\n    let b: Box<dyn AnySubTrait> = Box::new(1);\n    let _ = (*b).type_id();\n    //~^ type_id_on_box\n\n    let b: SomeBox = Box::new(0usize);\n    let _ = (*b).type_id();\n    //~^ type_id_on_box\n\n    let b = BadBox(Box::new(0usize));\n    let _ = b.type_id(); // Don't lint. This is a call to `<BadBox as Any>::type_id`. Not `std::boxed::Box`!\n}\n"
  },
  {
    "path": "tests/ui/type_id_on_box.rs",
    "content": "#![warn(clippy::type_id_on_box)]\n\nuse std::any::{Any, TypeId};\nuse std::ops::Deref;\n\ntype SomeBox = Box<dyn Any>;\n\nstruct BadBox(Box<dyn Any>);\n\nimpl Deref for BadBox {\n    type Target = Box<dyn Any>;\n\n    fn deref(&self) -> &Self::Target {\n        &self.0\n    }\n}\n\nfn existential() -> impl Any {\n    Box::new(1) as Box<dyn Any>\n}\n\ntrait AnySubTrait: Any {}\nimpl<T: Any> AnySubTrait for T {}\n\nfn main() {\n    // Don't lint, calling `.type_id()` on a `&dyn Any` does the expected thing\n    let ref_dyn: &dyn Any = &42;\n    let _ = ref_dyn.type_id();\n\n    let any_box: Box<dyn Any> = Box::new(0usize);\n    let _ = any_box.type_id();\n    //~^ type_id_on_box\n\n    // Don't lint. We explicitly say \"do this instead\" if this is intentional\n    let _ = TypeId::of::<Box<dyn Any>>();\n    let _ = (*any_box).type_id();\n\n    // 2 derefs are needed here to get to the `dyn Any`\n    let any_box: &Box<dyn Any> = &(Box::new(0usize) as Box<dyn Any>);\n    let _ = any_box.type_id();\n    //~^ type_id_on_box\n\n    let b = existential();\n    let _ = b.type_id(); // Don't\n\n    let b: Box<dyn AnySubTrait> = Box::new(1);\n    let _ = b.type_id();\n    //~^ type_id_on_box\n\n    let b: SomeBox = Box::new(0usize);\n    let _ = b.type_id();\n    //~^ type_id_on_box\n\n    let b = BadBox(Box::new(0usize));\n    let _ = b.type_id(); // Don't lint. This is a call to `<BadBox as Any>::type_id`. Not `std::boxed::Box`!\n}\n"
  },
  {
    "path": "tests/ui/type_id_on_box.stderr",
    "content": "error: calling `.type_id()` on `Box<dyn Any>`\n  --> tests/ui/type_id_on_box.rs:31:13\n   |\nLL |     let _ = any_box.type_id();\n   |             -------^^^^^^^^^^\n   |             |\n   |             help: consider dereferencing first: `(*any_box)`\n   |\n   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want\n   = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear\n   = note: `-D clippy::type-id-on-box` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]`\n\nerror: calling `.type_id()` on `Box<dyn Any>`\n  --> tests/ui/type_id_on_box.rs:40:13\n   |\nLL |     let _ = any_box.type_id();\n   |             -------^^^^^^^^^^\n   |             |\n   |             help: consider dereferencing first: `(**any_box)`\n   |\n   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want\n   = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear\n\nerror: calling `.type_id()` on `Box<dyn AnySubTrait>`\n  --> tests/ui/type_id_on_box.rs:47:13\n   |\nLL |     let _ = b.type_id();\n   |             -^^^^^^^^^^\n   |             |\n   |             help: consider dereferencing first: `(*b)`\n   |\n   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want\n   = note: if this is intentional, use `TypeId::of::<Box<dyn AnySubTrait>>()` instead, which makes it more clear\n\nerror: calling `.type_id()` on `Box<dyn Any>`\n  --> tests/ui/type_id_on_box.rs:51:13\n   |\nLL |     let _ = b.type_id();\n   |             -^^^^^^^^^^\n   |             |\n   |             help: consider dereferencing first: `(*b)`\n   |\n   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want\n   = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/type_id_on_box_unfixable.rs",
    "content": "#![warn(clippy::type_id_on_box)]\n\nuse std::any::{Any, TypeId};\nuse std::ops::Deref;\n\ntrait AnySubTrait: Any {}\nimpl<T: Any> AnySubTrait for T {}\n\n// `Any` is an indirect supertrait\ntrait AnySubSubTrait: AnySubTrait {}\nimpl<T: AnySubTrait> AnySubSubTrait for T {}\n\n// This trait mentions `Any` in its predicates, but it is not a subtrait of `Any`.\ntrait NormalTrait\nwhere\n    i32: Any,\n{\n}\nimpl<T> NormalTrait for T {}\n\nfn main() {\n    // (currently we don't look deeper than one level into the supertrait hierarchy, but we probably\n    // could)\n    let b: Box<dyn AnySubSubTrait> = Box::new(1);\n    let _ = b.type_id();\n    //~^ type_id_on_box\n\n    let b: Box<dyn NormalTrait> = Box::new(1);\n    let _ = b.type_id();\n    //~^ type_id_on_box\n}\n"
  },
  {
    "path": "tests/ui/type_id_on_box_unfixable.stderr",
    "content": "error: calling `.type_id()` on `Box<dyn AnySubSubTrait>`\n  --> tests/ui/type_id_on_box_unfixable.rs:25:13\n   |\nLL |     let _ = b.type_id();\n   |             ^^^^^^^^^^^\n   |\n   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want\n   = note: if this is intentional, use `TypeId::of::<Box<dyn AnySubSubTrait>>()` instead, which makes it more clear\n   = note: `-D clippy::type-id-on-box` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]`\n\nerror: calling `.type_id()` on `Box<dyn NormalTrait>`\n  --> tests/ui/type_id_on_box_unfixable.rs:29:13\n   |\nLL |     let _ = b.type_id();\n   |             ^^^^^^^^^^^\n   |\n   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want\n   = note: if this is intentional, use `TypeId::of::<Box<dyn NormalTrait>>()` instead, which makes it more clear\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/type_repetition_in_bounds.rs",
    "content": "#![deny(clippy::type_repetition_in_bounds)]\n#![allow(\n    clippy::extra_unused_type_parameters,\n    clippy::multiple_bound_locations,\n    clippy::needless_maybe_sized\n)]\n\nuse serde::Deserialize;\nuse std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};\n\npub fn foo<T>(_t: T)\nwhere\n    T: Copy,\n    T: Clone,\n    //~^ type_repetition_in_bounds\n{\n    unimplemented!();\n}\n\npub fn bar<T, U>(_t: T, _u: U)\nwhere\n    T: Copy,\n    U: Clone,\n{\n    unimplemented!();\n}\n\n// Threshold test (see #4380)\ntrait LintBounds\nwhere\n    Self: Clone,\n    Self: Copy + Default + Ord,\n    //~^ type_repetition_in_bounds\n    Self: Add<Output = Self> + AddAssign + Sub<Output = Self> + SubAssign,\n    Self: Mul<Output = Self> + MulAssign + Div<Output = Self> + DivAssign,\n{\n}\n\ntrait LotsOfBounds\nwhere\n    Self: Clone + Copy + Default + Ord,\n    Self: Add<Output = Self> + AddAssign + Sub<Output = Self> + SubAssign,\n    Self: Mul<Output = Self> + MulAssign + Div<Output = Self> + DivAssign,\n{\n}\n\n// Generic distinction (see #4323)\nmod issue4323 {\n    pub struct Foo<A>(A);\n    pub struct Bar<A, B> {\n        a: Foo<A>,\n        b: Foo<B>,\n    }\n\n    impl<A, B> Unpin for Bar<A, B>\n    where\n        Foo<A>: Unpin,\n        Foo<B>: Unpin,\n    {\n    }\n}\n\n// Extern macros shouldn't lint (see #4326)\nextern crate serde;\nmod issue4326 {\n    use serde::{Deserialize, Serialize};\n\n    trait Foo {}\n    impl Foo for String {}\n\n    #[derive(Debug, Serialize, Deserialize)]\n    struct Bar<S>\n    where\n        S: Foo,\n    {\n        foo: S,\n    }\n}\n\n// Extern macros shouldn't lint, again (see #10504)\nmod issue10504 {\n    use serde::{Deserialize, Serialize};\n    use std::fmt::Debug;\n    use std::hash::Hash;\n\n    #[derive(Debug, Serialize, Deserialize)]\n    #[serde(bound(\n        serialize = \"T: Serialize + Hash + Eq\",\n        deserialize = \"Box<T>: serde::de::DeserializeOwned + Hash + Eq\"\n    ))]\n    struct OpaqueParams<T: ?Sized + Debug>(std::marker::PhantomData<T>);\n}\n\n// Issue #7360\nstruct Foo<T, U>\nwhere\n    T: Clone,\n    U: Clone,\n{\n    t: T,\n    u: U,\n}\n\n// Check for the `?` in `?Sized`\npub fn f<T: ?Sized>()\nwhere\n    T: Clone,\n    //~^ type_repetition_in_bounds\n{\n}\npub fn g<T: Clone>()\nwhere\n    T: ?Sized,\n    //~^ type_repetition_in_bounds\n{\n}\n\n// This should not lint\nfn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}\n\n#[clippy::msrv = \"1.14.0\"]\nmod issue8772_fail {\n    pub trait Trait<X, Y, Z> {}\n\n    pub fn f<T: ?Sized, U>(arg: usize)\n    where\n        T: Trait<Option<usize>, Box<[String]>, bool> + 'static,\n        U: Clone + Sync + 'static,\n    {\n    }\n}\n\n#[clippy::msrv = \"1.15.0\"]\nmod issue8772_pass {\n    pub trait Trait<X, Y, Z> {}\n\n    pub fn f<T: ?Sized, U>(arg: usize)\n    where\n        T: Trait<Option<usize>, Box<[String]>, bool> + 'static,\n        //~^ type_repetition_in_bounds\n        U: Clone + Sync + 'static,\n    {\n    }\n}\n\nstruct Issue14744<'a, K: 'a>\nwhere\n    K: Clone,\n{\n    phantom: std::marker::PhantomData<&'a K>,\n}\n//~^^^^ type_repetition_in_bounds\n\nstruct ComplexType<T>\nwhere\n    Vec<T>: Clone,\n    Vec<T>: Clone,\n{\n    t: T,\n}\n//~^^^^ type_repetition_in_bounds\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/type_repetition_in_bounds.stderr",
    "content": "error: type `T` has already been used as a bound predicate\n  --> tests/ui/type_repetition_in_bounds.rs:14:5\n   |\nLL |     T: Clone,\n   |     ^^^^^^^^\n   |\n   = help: consider combining the bounds: `T: Copy + Clone`\nnote: the lint level is defined here\n  --> tests/ui/type_repetition_in_bounds.rs:1:9\n   |\nLL | #![deny(clippy::type_repetition_in_bounds)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `Self` has already been used as a bound predicate\n  --> tests/ui/type_repetition_in_bounds.rs:32:5\n   |\nLL |     Self: Copy + Default + Ord,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider combining the bounds: `Self: Clone + Copy + Default + Ord`\n\nerror: type `T` has already been used as a bound predicate\n  --> tests/ui/type_repetition_in_bounds.rs:107:5\n   |\nLL |     T: Clone,\n   |     ^^^^^^^^\n   |\n   = help: consider combining the bounds: `T: ?Sized + Clone`\n\nerror: type `T` has already been used as a bound predicate\n  --> tests/ui/type_repetition_in_bounds.rs:113:5\n   |\nLL |     T: ?Sized,\n   |     ^^^^^^^^^\n   |\n   = help: consider combining the bounds: `T: Clone + ?Sized`\n\nerror: type `T` has already been used as a bound predicate\n  --> tests/ui/type_repetition_in_bounds.rs:139:9\n   |\nLL |         T: Trait<Option<usize>, Box<[String]>, bool> + 'static,\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider combining the bounds: `T: ?Sized + Trait<Option<usize>, Box<[String]>, bool> + 'static`\n\nerror: type `K` has already been used as a bound predicate\n  --> tests/ui/type_repetition_in_bounds.rs:148:5\n   |\nLL |     K: Clone,\n   |     ^^^^^^^^\n   |\n   = help: consider combining the bounds: `K: 'a + Clone`\n\nerror: type `Vec<T>` has already been used as a bound predicate\n  --> tests/ui/type_repetition_in_bounds.rs:157:5\n   |\nLL |     Vec<T>: Clone,\n   |     ^^^^^^^^^^^^^\n   |\n   = help: consider combining the bounds: `Vec<T>: Clone + Clone`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/unbuffered_bytes.rs",
    "content": "#![warn(clippy::unbuffered_bytes)]\n\nuse std::fs::File;\nuse std::io::{BufReader, Cursor, Read, Stdin, stdin};\nuse std::net::TcpStream;\n\nfn main() {\n    // File is not buffered, should complain\n    let file = File::open(\"./bytes.txt\").unwrap();\n    file.bytes();\n    //~^ unbuffered_bytes\n\n    // TcpStream is not buffered, should complain\n    let tcp_stream: TcpStream = TcpStream::connect(\"127.0.0.1:80\").unwrap();\n    tcp_stream.bytes();\n    //~^ unbuffered_bytes\n\n    // BufReader<File> is buffered, should not complain\n    let file = BufReader::new(File::open(\"./bytes.txt\").unwrap());\n    file.bytes();\n\n    // Cursor is buffered, should not complain\n    let cursor = Cursor::new(Vec::new());\n    cursor.bytes();\n\n    // Stdio would acquire the lock for every byte, should complain\n    let s: Stdin = stdin();\n    s.bytes();\n    //~^ unbuffered_bytes\n\n    // But when locking stdin, this is fine so should not complain\n    let s: Stdin = stdin();\n    let s = s.lock();\n    s.bytes();\n}\n\nfn use_read<R: Read>(r: R) {\n    // Callers of `use_read` may choose a `R` that is not buffered\n    r.bytes();\n    //~^ unbuffered_bytes\n}\n"
  },
  {
    "path": "tests/ui/unbuffered_bytes.stderr",
    "content": "error: calling .bytes() is very inefficient when data is not in memory\n  --> tests/ui/unbuffered_bytes.rs:10:5\n   |\nLL |     file.bytes();\n   |     ^^^^^^^^^^^^\n   |\n   = help: consider using `BufReader`\n   = note: `-D clippy::unbuffered-bytes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unbuffered_bytes)]`\n\nerror: calling .bytes() is very inefficient when data is not in memory\n  --> tests/ui/unbuffered_bytes.rs:15:5\n   |\nLL |     tcp_stream.bytes();\n   |     ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `BufReader`\n\nerror: calling .bytes() is very inefficient when data is not in memory\n  --> tests/ui/unbuffered_bytes.rs:28:5\n   |\nLL |     s.bytes();\n   |     ^^^^^^^^^\n   |\n   = help: consider using `BufReader`\n\nerror: calling .bytes() is very inefficient when data is not in memory\n  --> tests/ui/unbuffered_bytes.rs:39:5\n   |\nLL |     r.bytes();\n   |     ^^^^^^^^^\n   |\n   = help: consider using `BufReader`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/unchecked_time_subtraction.fixed",
    "content": "#![warn(clippy::unchecked_time_subtraction)]\n\nuse std::time::{Duration, Instant};\n\nfn main() {\n    let _first = Instant::now();\n    let second = Duration::from_secs(3);\n\n    let _ = _first.checked_sub(second).unwrap();\n    //~^ unchecked_time_subtraction\n\n    let _ = Instant::now().checked_sub(Duration::from_secs(5)).unwrap();\n    //~^ unchecked_time_subtraction\n\n    let _ = _first.checked_sub(Duration::from_secs(5)).unwrap();\n    //~^ unchecked_time_subtraction\n\n    let _ = Instant::now().checked_sub(second).unwrap();\n    //~^ unchecked_time_subtraction\n\n    // Duration - Duration cases\n    let dur1 = Duration::from_secs(5);\n    let dur2 = Duration::from_secs(3);\n\n    let _ = dur1.checked_sub(dur2).unwrap();\n    //~^ unchecked_time_subtraction\n\n    let _ = Duration::from_secs(10) - Duration::from_secs(5);\n\n    let _ = second.checked_sub(dur1).unwrap();\n    //~^ unchecked_time_subtraction\n\n    // Duration multiplication and subtraction\n    let _ = (2 * dur1).checked_sub(dur2).unwrap();\n    //~^ unchecked_time_subtraction\n}\n\nfn issue16230() {\n    use std::ops::Sub as _;\n\n    Duration::ZERO.checked_sub(Duration::MAX).unwrap();\n    //~^ unchecked_time_subtraction\n\n    let _ = Duration::ZERO.checked_sub(Duration::MAX).unwrap();\n    //~^ unchecked_time_subtraction\n}\n\nfn issue16234() {\n    use std::ops::Sub as _;\n\n    macro_rules! duration {\n        ($secs:expr) => {\n            Duration::from_secs($secs)\n        };\n    }\n\n    let d = duration!(0);\n    d.checked_sub(duration!(1)).unwrap();\n    //~^ unchecked_time_subtraction\n    let _ = d.checked_sub(duration!(1)).unwrap();\n    //~^ unchecked_time_subtraction\n}\n\nfn issue16499() {\n    let _ = Duration::from_millis(2) - Duration::from_millis(1);\n    let _ = Duration::new(10000, 0) - Duration::from_secs(1);\n    let _ = Duration::from_nanos_u128(1000) - Duration::from_nanos(100);\n    let _ = Duration::from_secs_f32(1.5) - Duration::from_secs_f64(0.5);\n    let _ = Duration::from_mins(70) - Duration::from_hours(1);\n}\n"
  },
  {
    "path": "tests/ui/unchecked_time_subtraction.rs",
    "content": "#![warn(clippy::unchecked_time_subtraction)]\n\nuse std::time::{Duration, Instant};\n\nfn main() {\n    let _first = Instant::now();\n    let second = Duration::from_secs(3);\n\n    let _ = _first - second;\n    //~^ unchecked_time_subtraction\n\n    let _ = Instant::now() - Duration::from_secs(5);\n    //~^ unchecked_time_subtraction\n\n    let _ = _first - Duration::from_secs(5);\n    //~^ unchecked_time_subtraction\n\n    let _ = Instant::now() - second;\n    //~^ unchecked_time_subtraction\n\n    // Duration - Duration cases\n    let dur1 = Duration::from_secs(5);\n    let dur2 = Duration::from_secs(3);\n\n    let _ = dur1 - dur2;\n    //~^ unchecked_time_subtraction\n\n    let _ = Duration::from_secs(10) - Duration::from_secs(5);\n\n    let _ = second - dur1;\n    //~^ unchecked_time_subtraction\n\n    // Duration multiplication and subtraction\n    let _ = 2 * dur1 - dur2;\n    //~^ unchecked_time_subtraction\n}\n\nfn issue16230() {\n    use std::ops::Sub as _;\n\n    Duration::ZERO.sub(Duration::MAX);\n    //~^ unchecked_time_subtraction\n\n    let _ = Duration::ZERO - Duration::MAX;\n    //~^ unchecked_time_subtraction\n}\n\nfn issue16234() {\n    use std::ops::Sub as _;\n\n    macro_rules! duration {\n        ($secs:expr) => {\n            Duration::from_secs($secs)\n        };\n    }\n\n    let d = duration!(0);\n    d.sub(duration!(1));\n    //~^ unchecked_time_subtraction\n    let _ = d - duration!(1);\n    //~^ unchecked_time_subtraction\n}\n\nfn issue16499() {\n    let _ = Duration::from_millis(2) - Duration::from_millis(1);\n    let _ = Duration::new(10000, 0) - Duration::from_secs(1);\n    let _ = Duration::from_nanos_u128(1000) - Duration::from_nanos(100);\n    let _ = Duration::from_secs_f32(1.5) - Duration::from_secs_f64(0.5);\n    let _ = Duration::from_mins(70) - Duration::from_hours(1);\n}\n"
  },
  {
    "path": "tests/ui/unchecked_time_subtraction.stderr",
    "content": "error: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:9:13\n   |\nLL |     let _ = _first - second;\n   |             ^^^^^^^^^^^^^^^ help: try: `_first.checked_sub(second).unwrap()`\n   |\n   = note: `-D clippy::unchecked-time-subtraction` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unchecked_time_subtraction)]`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:12:13\n   |\nLL |     let _ = Instant::now() - Duration::from_secs(5);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(Duration::from_secs(5)).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:15:13\n   |\nLL |     let _ = _first - Duration::from_secs(5);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `_first.checked_sub(Duration::from_secs(5)).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:18:13\n   |\nLL |     let _ = Instant::now() - second;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(second).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:25:13\n   |\nLL |     let _ = dur1 - dur2;\n   |             ^^^^^^^^^^^ help: try: `dur1.checked_sub(dur2).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:30:13\n   |\nLL |     let _ = second - dur1;\n   |             ^^^^^^^^^^^^^ help: try: `second.checked_sub(dur1).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:34:13\n   |\nLL |     let _ = 2 * dur1 - dur2;\n   |             ^^^^^^^^^^^^^^^ help: try: `(2 * dur1).checked_sub(dur2).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:41:5\n   |\nLL |     Duration::ZERO.sub(Duration::MAX);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::ZERO.checked_sub(Duration::MAX).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:44:13\n   |\nLL |     let _ = Duration::ZERO - Duration::MAX;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::ZERO.checked_sub(Duration::MAX).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:58:5\n   |\nLL |     d.sub(duration!(1));\n   |     ^^^^^^^^^^^^^^^^^^^ help: try: `d.checked_sub(duration!(1)).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction.rs:60:13\n   |\nLL |     let _ = d - duration!(1);\n   |             ^^^^^^^^^^^^^^^^ help: try: `d.checked_sub(duration!(1)).unwrap()`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/unchecked_time_subtraction_unfixable.rs",
    "content": "#![warn(clippy::unchecked_time_subtraction)]\n//@no-rustfix\n\nuse std::time::{Duration, Instant};\n\nfn main() {\n    let dur1 = Duration::from_secs(5);\n    let dur2 = Duration::from_secs(3);\n    let dur3 = Duration::from_secs(1);\n\n    // Chained Duration subtraction - should lint without suggestion due to complexity\n    let _ = dur1 - dur2 - dur3;\n    //~^ unchecked_time_subtraction\n    //~| unchecked_time_subtraction\n\n    // Chained Instant - Duration subtraction - should lint without suggestion due to complexity\n    let instant1 = Instant::now();\n\n    let _ = instant1 - dur2 - dur3;\n    //~^ unchecked_time_subtraction\n    //~| unchecked_time_subtraction\n}\n\nfn issue16499() {\n    let _ = Duration::from_millis(1) - Duration::from_millis(2);\n    //~^ unchecked_time_subtraction\n    let _ = Duration::from_millis(1) - Duration::from_mins(2);\n    //~^ unchecked_time_subtraction\n    let _ = Duration::from_nanos(1) - Duration::from_secs(1);\n    //~^ unchecked_time_subtraction\n}\n"
  },
  {
    "path": "tests/ui/unchecked_time_subtraction_unfixable.stderr",
    "content": "error: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction_unfixable.rs:12:13\n   |\nLL |     let _ = dur1 - dur2 - dur3;\n   |             ^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unchecked-time-subtraction` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unchecked_time_subtraction)]`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction_unfixable.rs:12:13\n   |\nLL |     let _ = dur1 - dur2 - dur3;\n   |             ^^^^^^^^^^^ help: try: `dur1.checked_sub(dur2).unwrap()`\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction_unfixable.rs:19:13\n   |\nLL |     let _ = instant1 - dur2 - dur3;\n   |             ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unchecked subtraction of a `Duration`\n  --> tests/ui/unchecked_time_subtraction_unfixable.rs:19:13\n   |\nLL |     let _ = instant1 - dur2 - dur3;\n   |             ^^^^^^^^^^^^^^^ help: try: `instant1.checked_sub(dur2).unwrap()`\n\nerror: unchecked subtraction of two `Duration` that will underflow\n  --> tests/ui/unchecked_time_subtraction_unfixable.rs:25:13\n   |\nLL |     let _ = Duration::from_millis(1) - Duration::from_millis(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this is intentional, consider allowing the lint\n\nerror: unchecked subtraction of two `Duration` that will underflow\n  --> tests/ui/unchecked_time_subtraction_unfixable.rs:27:13\n   |\nLL |     let _ = Duration::from_millis(1) - Duration::from_mins(2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this is intentional, consider allowing the lint\n\nerror: unchecked subtraction of two `Duration` that will underflow\n  --> tests/ui/unchecked_time_subtraction_unfixable.rs:29:13\n   |\nLL |     let _ = Duration::from_nanos(1) - Duration::from_secs(1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this is intentional, consider allowing the lint\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/unconditional_recursion.rs",
    "content": "#![warn(clippy::unconditional_recursion)]\n#![allow(\n    clippy::partialeq_ne_impl,\n    clippy::default_constructed_unit_structs,\n    clippy::only_used_in_recursion,\n    clippy::needless_lifetimes\n)]\n\nenum Foo {\n    A,\n    B,\n}\n\nimpl PartialEq for Foo {\n    fn ne(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        self != other\n    }\n    fn eq(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        self == other\n    }\n}\n\nenum Foo2 {\n    A,\n    B,\n}\n\nimpl PartialEq for Foo2 {\n    fn ne(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n        self != &Foo2::B // no error here\n    }\n    fn eq(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n        self == &Foo2::B // no error here\n    }\n}\n\nenum Foo3 {\n    A,\n    B,\n}\n\nimpl PartialEq for Foo3 {\n    fn ne(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n        //~| ERROR: function cannot return without recursing\n        self.ne(other)\n    }\n    fn eq(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n        //~| ERROR: function cannot return without recursing\n\n        self.eq(other)\n    }\n}\n\nenum Foo4 {\n    A,\n    B,\n}\n\nimpl PartialEq for Foo4 {\n    fn ne(&self, other: &Self) -> bool {\n        self.eq(other) // no error\n    }\n    fn eq(&self, other: &Self) -> bool {\n        self.ne(other) // no error\n    }\n}\n\nenum Foo5 {\n    A,\n    B,\n}\n\nimpl Foo5 {\n    fn a(&self) -> bool {\n        true\n    }\n}\n\nimpl PartialEq for Foo5 {\n    fn ne(&self, other: &Self) -> bool {\n        self.a() // no error\n    }\n    fn eq(&self, other: &Self) -> bool {\n        self.a() // no error\n    }\n}\n\nstruct S;\n\n// Check the order doesn't matter.\nimpl PartialEq for S {\n    fn ne(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        other != self\n    }\n    fn eq(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        other == self\n    }\n}\n\nstruct S2;\n\n// Check that if the same element is compared, it's also triggering the lint.\nimpl PartialEq for S2 {\n    fn ne(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        other != other\n        //~^ eq_op\n    }\n    fn eq(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        other == other\n        //~^ eq_op\n    }\n}\n\nstruct S3;\n\nimpl PartialEq for S3 {\n    fn ne(&self, _other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        self != self\n        //~^ eq_op\n    }\n    fn eq(&self, _other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        self == self\n        //~^ eq_op\n    }\n}\n\n// There should be no warning here!\n#[derive(PartialEq)]\nenum E {\n    A,\n    B,\n}\n\n#[derive(PartialEq)]\nstruct Bar<T: PartialEq>(T);\n\nstruct S4;\n\nimpl PartialEq for S4 {\n    fn eq(&self, other: &Self) -> bool {\n        // No warning here.\n        Bar(self) == Bar(other)\n    }\n}\n\nmacro_rules! impl_partial_eq {\n    ($ty:ident) => {\n        impl PartialEq for $ty {\n            fn eq(&self, other: &Self) -> bool {\n                //~^ unconditional_recursion\n\n                self == other\n            }\n        }\n    };\n}\n\nstruct S5;\n\nimpl_partial_eq!(S5);\n\nstruct S6 {\n    field: String,\n}\n\nimpl PartialEq for S6 {\n    fn eq(&self, other: &Self) -> bool {\n        let mine = &self.field;\n        let theirs = &other.field;\n        mine == theirs // Should not warn!\n    }\n}\n\nstruct S7<'a> {\n    field: &'a S7<'a>,\n}\n\nimpl<'a> PartialEq for S7<'a> {\n    fn eq(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        let mine = &self.field;\n        let theirs = &other.field;\n        mine == theirs\n    }\n}\n\nstruct S8 {\n    num: i32,\n    field: Option<Box<S8>>,\n}\n\nimpl PartialEq for S8 {\n    fn eq(&self, other: &Self) -> bool {\n        if self.num != other.num {\n            return false;\n        }\n\n        let (this, other) = match (self.field.as_deref(), other.field.as_deref()) {\n            (Some(x1), Some(x2)) => (x1, x2),\n            (None, None) => return true,\n            _ => return false,\n        };\n\n        this == other\n    }\n}\n\nstruct S9;\n\n#[allow(clippy::to_string_trait_impl)]\nimpl std::string::ToString for S9 {\n    fn to_string(&self) -> String {\n        //~^ ERROR: function cannot return without recursing\n        self.to_string()\n    }\n}\n\nstruct S10;\n\n#[allow(clippy::to_string_trait_impl)]\nimpl std::string::ToString for S10 {\n    fn to_string(&self) -> String {\n        //~^ ERROR: function cannot return without recursing\n        let x = self;\n        x.to_string()\n    }\n}\n\nstruct S11;\n\n#[allow(clippy::to_string_trait_impl)]\nimpl std::string::ToString for S11 {\n    fn to_string(&self) -> String {\n        //~^ ERROR: function cannot return without recursing\n        (self as &Self).to_string()\n    }\n}\n\nstruct S12;\n\nimpl std::default::Default for S12 {\n    fn default() -> Self {\n        Self::new()\n    }\n}\n\nimpl S12 {\n    fn new() -> Self {\n        //~^ unconditional_recursion\n\n        Self::default()\n    }\n\n    fn bar() -> Self {\n        // Should not warn!\n        Self::default()\n    }\n}\n\n#[derive(Default)]\nstruct S13 {\n    f: u32,\n}\n\nimpl S13 {\n    fn new() -> Self {\n        // Should not warn!\n        Self::default()\n    }\n}\n\nstruct S14 {\n    field: String,\n}\n\nimpl PartialEq for S14 {\n    fn eq(&self, other: &Self) -> bool {\n        // Should not warn!\n        self.field.eq(&other.field)\n    }\n}\n\nstruct S15<'a> {\n    field: &'a S15<'a>,\n}\n\nimpl PartialEq for S15<'_> {\n    fn eq(&self, other: &Self) -> bool {\n        //~^ unconditional_recursion\n\n        let mine = &self.field;\n        let theirs = &other.field;\n        mine.eq(theirs)\n    }\n}\n\nmod issue12154 {\n    struct MyBox<T>(T);\n\n    impl<T> std::ops::Deref for MyBox<T> {\n        type Target = T;\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n\n    impl<T: PartialEq> PartialEq for MyBox<T> {\n        fn eq(&self, other: &Self) -> bool {\n            (**self).eq(&**other)\n        }\n    }\n\n    // Not necessarily related to the issue but another FP from the http crate that was fixed with it:\n    // https://github.com/hyperium/http/blob/5f0c86642f1dc86f156da82b62aceb2f4fab20e1/src/header/name.rs#L1408-L1420\n    // We used to simply peel refs from the LHS and RHS, so we couldn't differentiate\n    // between `PartialEq<T> for &T` and `PartialEq<&T> for T` impls.\n    #[derive(PartialEq)]\n    struct HeaderName;\n    impl<'a> PartialEq<&'a HeaderName> for HeaderName {\n        fn eq(&self, other: &&'a HeaderName) -> bool {\n            *self == **other\n        }\n    }\n\n    impl<'a> PartialEq<HeaderName> for &'a HeaderName {\n        fn eq(&self, other: &HeaderName) -> bool {\n            *other == *self\n        }\n    }\n\n    // Issue #12181 but also fixed by the same PR\n    struct Foo;\n\n    impl Foo {\n        fn as_str(&self) -> &str {\n            \"Foo\"\n        }\n    }\n\n    impl PartialEq for Foo {\n        fn eq(&self, other: &Self) -> bool {\n            self.as_str().eq(other.as_str())\n        }\n    }\n\n    impl<T> PartialEq<T> for Foo\n    where\n        for<'a> &'a str: PartialEq<T>,\n    {\n        fn eq(&self, other: &T) -> bool {\n            (&self.as_str()).eq(other)\n        }\n    }\n}\n\n// From::from -> Into::into -> From::from\nstruct BadFromTy1<'a>(&'a ());\nstruct BadIntoTy1<'b>(&'b ());\nimpl<'a> From<BadFromTy1<'a>> for BadIntoTy1<'static> {\n    fn from(f: BadFromTy1<'a>) -> Self {\n        //~^ unconditional_recursion\n        f.into()\n    }\n}\n\n// Using UFCS syntax\nstruct BadFromTy2<'a>(&'a ());\nstruct BadIntoTy2<'b>(&'b ());\nimpl<'a> From<BadFromTy2<'a>> for BadIntoTy2<'static> {\n    fn from(f: BadFromTy2<'a>) -> Self {\n        //~^ unconditional_recursion\n        Into::into(f)\n    }\n}\n\n// Different Into impl (<i16 as Into<i32>>), so no infinite recursion\nstruct BadFromTy3;\nimpl From<BadFromTy3> for i32 {\n    fn from(f: BadFromTy3) -> Self {\n        Into::into(1i16)\n    }\n}\n\n// A conditional return that ends the recursion\nstruct BadFromTy4;\nimpl From<BadFromTy4> for i32 {\n    fn from(f: BadFromTy4) -> Self {\n        if true {\n            return 42;\n        }\n        f.into()\n    }\n}\n\n// Types differ in refs, don't lint\nimpl From<&BadFromTy4> for i32 {\n    fn from(f: &BadFromTy4) -> Self {\n        BadFromTy4.into()\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unconditional_recursion.stderr",
    "content": "error: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:49:5\n   |\nLL |     fn ne(&self, other: &Self) -> bool {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing\n...\nLL |         self.ne(other)\n   |         -------------- recursive call site\n   |\n   = help: a `loop` may express intention better if this is on purpose\n   = note: `-D unconditional-recursion` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(unconditional_recursion)]`\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:54:5\n   |\nLL |     fn eq(&self, other: &Self) -> bool {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing\n...\nLL |         self.eq(other)\n   |         -------------- recursive call site\n   |\n   = help: a `loop` may express intention better if this is on purpose\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:233:5\n   |\nLL |     fn to_string(&self) -> String {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing\nLL |\nLL |         self.to_string()\n   |         ---------------- recursive call site\n   |\n   = help: a `loop` may express intention better if this is on purpose\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:243:5\n   |\nLL |     fn to_string(&self) -> String {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing\n...\nLL |         x.to_string()\n   |         ------------- recursive call site\n   |\n   = help: a `loop` may express intention better if this is on purpose\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:254:5\n   |\nLL |     fn to_string(&self) -> String {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing\nLL |\nLL |         (self as &Self).to_string()\n   |         --------------------------- recursive call site\n   |\n   = help: a `loop` may express intention better if this is on purpose\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:15:5\n   |\nLL | /     fn ne(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         self != other\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:18:9\n   |\nLL |         self != other\n   |         ^^^^^^^^^^^^^\n   = note: `-D clippy::unconditional-recursion` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unconditional_recursion)]`\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:20:5\n   |\nLL | /     fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         self == other\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:23:9\n   |\nLL |         self == other\n   |         ^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:33:5\n   |\nLL | /     fn ne(&self, other: &Self) -> bool {\nLL | |\nLL | |         self != &Foo2::B // no error here\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:35:9\n   |\nLL |         self != &Foo2::B // no error here\n   |         ^^^^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:37:5\n   |\nLL | /     fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |         self == &Foo2::B // no error here\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:39:9\n   |\nLL |         self == &Foo2::B // no error here\n   |         ^^^^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:49:5\n   |\nLL | /     fn ne(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         self.ne(other)\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:52:9\n   |\nLL |         self.ne(other)\n   |         ^^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:54:5\n   |\nLL | /     fn eq(&self, other: &Self) -> bool {\n...  |\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:58:9\n   |\nLL |         self.eq(other)\n   |         ^^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:100:5\n   |\nLL | /     fn ne(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         other != self\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:103:9\n   |\nLL |         other != self\n   |         ^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:105:5\n   |\nLL | /     fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         other == self\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:108:9\n   |\nLL |         other == self\n   |         ^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:116:5\n   |\nLL | /     fn ne(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         other != other\nLL | |\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:119:9\n   |\nLL |         other != other\n   |         ^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `!=`\n  --> tests/ui/unconditional_recursion.rs:119:9\n   |\nLL |         other != other\n   |         ^^^^^^^^^^^^^^\n   |\n   = note: `#[deny(clippy::eq_op)]` on by default\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:122:5\n   |\nLL | /     fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         other == other\nLL | |\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:125:9\n   |\nLL |         other == other\n   |         ^^^^^^^^^^^^^^\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/unconditional_recursion.rs:125:9\n   |\nLL |         other == other\n   |         ^^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:133:5\n   |\nLL | /     fn ne(&self, _other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         self != self\nLL | |\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:136:9\n   |\nLL |         self != self\n   |         ^^^^^^^^^^^^\n\nerror: equal expressions as operands to `!=`\n  --> tests/ui/unconditional_recursion.rs:136:9\n   |\nLL |         self != self\n   |         ^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:139:5\n   |\nLL | /     fn eq(&self, _other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         self == self\nLL | |\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:142:9\n   |\nLL |         self == self\n   |         ^^^^^^^^^^^^\n\nerror: equal expressions as operands to `==`\n  --> tests/ui/unconditional_recursion.rs:142:9\n   |\nLL |         self == self\n   |         ^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:169:13\n   |\nLL | /             fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |                 self == other\nLL | |             }\n   | |_____________^\n...\nLL |   impl_partial_eq!(S5);\n   |   -------------------- in this macro invocation\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:172:17\n   |\nLL |                 self == other\n   |                 ^^^^^^^^^^^^^\n...\nLL | impl_partial_eq!(S5);\n   | -------------------- in this macro invocation\n   = note: this error originates in the macro `impl_partial_eq` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:199:5\n   |\nLL | /     fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         let mine = &self.field;\nLL | |         let theirs = &other.field;\nLL | |         mine == theirs\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:204:9\n   |\nLL |         mine == theirs\n   |         ^^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:269:5\n   |\nLL | /     fn new() -> Self {\nLL | |\nLL | |\nLL | |         Self::default()\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:272:9\n   |\nLL |         Self::default()\n   |         ^^^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:309:5\n   |\nLL | /     fn eq(&self, other: &Self) -> bool {\nLL | |\nLL | |\nLL | |         let mine = &self.field;\nLL | |         let theirs = &other.field;\nLL | |         mine.eq(theirs)\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:314:9\n   |\nLL |         mine.eq(theirs)\n   |         ^^^^^^^^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:381:5\n   |\nLL | /     fn from(f: BadFromTy1<'a>) -> Self {\nLL | |\nLL | |         f.into()\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:383:9\n   |\nLL |         f.into()\n   |         ^^^^^^^^\n\nerror: function cannot return without recursing\n  --> tests/ui/unconditional_recursion.rs:391:5\n   |\nLL | /     fn from(f: BadFromTy2<'a>) -> Self {\nLL | |\nLL | |         Into::into(f)\nLL | |     }\n   | |_____^\n   |\nnote: recursive call site\n  --> tests/ui/unconditional_recursion.rs:393:9\n   |\nLL |         Into::into(f)\n   |         ^^^^^^^^^^^^^\n\nerror: aborting due to 27 previous errors\n\n"
  },
  {
    "path": "tests/ui/unicode.fixed",
    "content": "#![allow(dead_code)]\n\n#[warn(clippy::invisible_characters)]\nfn zero() {\n    print!(\"Here >\\u{200B}< is a ZWS, and \\u{200B}another\");\n    //~^ invisible_characters\n    print!(\"This\\u{200B}is\\u{200B}fine\");\n    print!(\"Here >\\u{AD}< is a SHY, and \\u{AD}another\");\n    //~^ invisible_characters\n    print!(\"This\\u{ad}is\\u{ad}fine\");\n    print!(\"Here >\\u{2060}< is a WJ, and \\u{2060}another\");\n    //~^ invisible_characters\n    print!(\"This\\u{2060}is\\u{2060}fine\");\n}\n\n#[warn(clippy::unicode_not_nfc)]\nfn canon() {\n    print!(\"̀àh?\");\n    //~^ unicode_not_nfc\n    print!(\"a\\u{0300}h?\"); // also ok\n}\n\nmod non_ascii_literal {\n    #![deny(clippy::non_ascii_literal)]\n\n    fn uni() {\n        print!(\"\\u{dc}ben!\");\n        //~^ non_ascii_literal\n        print!(\"\\u{DC}ben!\"); // this is ok\n    }\n\n    // issue 8013\n    fn single_quote() {\n        const _EMPTY_BLOCK: char = '\\u{25b1}';\n        //~^ non_ascii_literal\n        const _FULL_BLOCK: char = '\\u{25b0}';\n        //~^ non_ascii_literal\n    }\n\n    #[test]\n    pub fn issue_7739() {\n        // Ryū crate: https://github.com/dtolnay/ryu\n    }\n\n    mod issue_8263 {\n        #![deny(clippy::non_ascii_literal)]\n\n        // Re-allow for a single test\n        #[test]\n        #[allow(clippy::non_ascii_literal)]\n        fn allowed() {\n            let _ = \"悲しいかな、ここに日本語を書くことはできない。\";\n        }\n\n        #[test]\n        fn denied() {\n            let _ = \"\\u{60b2}\\u{3057}\\u{3044}\\u{304b}\\u{306a}\\u{3001}\\u{3053}\\u{3053}\\u{306b}\\u{65e5}\\u{672c}\\u{8a9e}\\u{3092}\\u{66f8}\\u{304f}\\u{3053}\\u{3068}\\u{306f}\\u{3067}\\u{304d}\\u{306a}\\u{3044}\\u{3002}\";\n            //~^ non_ascii_literal\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unicode.rs",
    "content": "#![allow(dead_code)]\n\n#[warn(clippy::invisible_characters)]\nfn zero() {\n    print!(\"Here >​< is a ZWS, and ​another\");\n    //~^ invisible_characters\n    print!(\"This\\u{200B}is\\u{200B}fine\");\n    print!(\"Here >­< is a SHY, and ­another\");\n    //~^ invisible_characters\n    print!(\"This\\u{ad}is\\u{ad}fine\");\n    print!(\"Here >⁠< is a WJ, and ⁠another\");\n    //~^ invisible_characters\n    print!(\"This\\u{2060}is\\u{2060}fine\");\n}\n\n#[warn(clippy::unicode_not_nfc)]\nfn canon() {\n    print!(\"̀àh?\");\n    //~^ unicode_not_nfc\n    print!(\"a\\u{0300}h?\"); // also ok\n}\n\nmod non_ascii_literal {\n    #![deny(clippy::non_ascii_literal)]\n\n    fn uni() {\n        print!(\"Üben!\");\n        //~^ non_ascii_literal\n        print!(\"\\u{DC}ben!\"); // this is ok\n    }\n\n    // issue 8013\n    fn single_quote() {\n        const _EMPTY_BLOCK: char = '▱';\n        //~^ non_ascii_literal\n        const _FULL_BLOCK: char = '▰';\n        //~^ non_ascii_literal\n    }\n\n    #[test]\n    pub fn issue_7739() {\n        // Ryū crate: https://github.com/dtolnay/ryu\n    }\n\n    mod issue_8263 {\n        #![deny(clippy::non_ascii_literal)]\n\n        // Re-allow for a single test\n        #[test]\n        #[allow(clippy::non_ascii_literal)]\n        fn allowed() {\n            let _ = \"悲しいかな、ここに日本語を書くことはできない。\";\n        }\n\n        #[test]\n        fn denied() {\n            let _ = \"悲しいかな、ここに日本語を書くことはできない。\";\n            //~^ non_ascii_literal\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unicode.stderr",
    "content": "error: invisible character detected\n  --> tests/ui/unicode.rs:5:12\n   |\nLL |     print!(\"Here >​< is a ZWS, and ​another\");\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `\"Here >\\u{200B}< is a ZWS, and \\u{200B}another\"`\n   |\n   = note: `-D clippy::invisible-characters` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::invisible_characters)]`\n\nerror: invisible character detected\n  --> tests/ui/unicode.rs:8:12\n   |\nLL |     print!(\"Here >­< is a SHY, and ­another\");\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `\"Here >\\u{AD}< is a SHY, and \\u{AD}another\"`\n\nerror: invisible character detected\n  --> tests/ui/unicode.rs:11:12\n   |\nLL |     print!(\"Here >⁠< is a WJ, and ⁠another\");\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `\"Here >\\u{2060}< is a WJ, and \\u{2060}another\"`\n\nerror: non-NFC Unicode sequence detected\n  --> tests/ui/unicode.rs:18:12\n   |\nLL |     print!(\"̀àh?\");\n   |            ^^^^^ help: consider replacing the string with: `\"̀àh?\"`\n   |\n   = note: `-D clippy::unicode-not-nfc` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unicode_not_nfc)]`\n\nerror: literal non-ASCII character detected\n  --> tests/ui/unicode.rs:27:16\n   |\nLL |         print!(\"Üben!\");\n   |                ^^^^^^^ help: consider replacing the string with: `\"\\u{dc}ben!\"`\n   |\nnote: the lint level is defined here\n  --> tests/ui/unicode.rs:24:13\n   |\nLL |     #![deny(clippy::non_ascii_literal)]\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: literal non-ASCII character detected\n  --> tests/ui/unicode.rs:34:36\n   |\nLL |         const _EMPTY_BLOCK: char = '▱';\n   |                                    ^^^ help: consider replacing the string with: `'\\u{25b1}'`\n\nerror: literal non-ASCII character detected\n  --> tests/ui/unicode.rs:36:35\n   |\nLL |         const _FULL_BLOCK: char = '▰';\n   |                                   ^^^ help: consider replacing the string with: `'\\u{25b0}'`\n\nerror: literal non-ASCII character detected\n  --> tests/ui/unicode.rs:57:21\n   |\nLL |             let _ = \"悲しいかな、ここに日本語を書くことはできない。\";\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `\"\\u{60b2}\\u{3057}\\u{3044}\\u{304b}\\u{306a}\\u{3001}\\u{3053}\\u{3053}\\u{306b}\\u{65e5}\\u{672c}\\u{8a9e}\\u{3092}\\u{66f8}\\u{304f}\\u{3053}\\u{3068}\\u{306f}\\u{3067}\\u{304d}\\u{306a}\\u{3044}\\u{3002}\"`\n   |\nnote: the lint level is defined here\n  --> tests/ui/unicode.rs:46:17\n   |\nLL |         #![deny(clippy::non_ascii_literal)]\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/uninhabited_references.rs",
    "content": "#![warn(clippy::uninhabited_references)]\n#![allow(clippy::missing_transmute_annotations)]\n#![feature(never_type)]\n\nfn ret_uninh_ref() -> &'static std::convert::Infallible {\n    //~^ uninhabited_references\n    unsafe { std::mem::transmute(&()) }\n}\n\nmacro_rules! ret_something {\n    ($name:ident, $ty:ty) => {\n        fn $name(x: &$ty) -> &$ty {\n            //~^ uninhabited_references\n            &*x\n            //~^ uninhabited_references\n        }\n    };\n}\n\nret_something!(id_u32, u32);\nret_something!(id_never, !);\n\nfn main() {\n    let x = ret_uninh_ref();\n    let _ = *x;\n    //~^ uninhabited_references\n}\n"
  },
  {
    "path": "tests/ui/uninhabited_references.stderr",
    "content": "error: dereferencing a reference to an uninhabited type would be undefined behavior\n  --> tests/ui/uninhabited_references.rs:5:23\n   |\nLL | fn ret_uninh_ref() -> &'static std::convert::Infallible {\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::uninhabited-references` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::uninhabited_references)]`\n\nerror: dereferencing a reference to an uninhabited type would be undefined behavior\n  --> tests/ui/uninhabited_references.rs:12:30\n   |\nLL |         fn $name(x: &$ty) -> &$ty {\n   |                              ^^^^\n...\nLL | ret_something!(id_never, !);\n   | --------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: dereferencing a reference to an uninhabited type is undefined behavior\n  --> tests/ui/uninhabited_references.rs:14:14\n   |\nLL |             &*x\n   |              ^^\n...\nLL | ret_something!(id_never, !);\n   | --------------------------- in this macro invocation\n   |\n   = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: dereferencing a reference to an uninhabited type is undefined behavior\n  --> tests/ui/uninhabited_references.rs:25:13\n   |\nLL |     let _ = *x;\n   |             ^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/uninit.rs",
    "content": "#![feature(stmt_expr_attributes)]\n#![allow(clippy::let_unit_value, invalid_value)]\n\nuse std::mem::MaybeUninit;\n\nunion MyOwnMaybeUninit {\n    value: u8,\n    uninit: (),\n}\n\nfn main() {\n    let _: usize = unsafe { MaybeUninit::uninit().assume_init() };\n    //~^ uninit_assumed_init\n\n    // This is OK, because ZSTs do not contain data.\n    let _: () = unsafe { MaybeUninit::uninit().assume_init() };\n\n    // This is OK, because `MaybeUninit` allows uninitialized data.\n    let _: MaybeUninit<usize> = unsafe { MaybeUninit::uninit().assume_init() };\n\n    // This is OK, because all constituent types are uninit-compatible.\n    let _: (MaybeUninit<usize>, MaybeUninit<bool>) = unsafe { MaybeUninit::uninit().assume_init() };\n\n    // This is OK, because all constituent types are uninit-compatible.\n    let _: (MaybeUninit<usize>, [MaybeUninit<bool>; 2]) = unsafe { MaybeUninit::uninit().assume_init() };\n\n    // This is OK, because our own MaybeUninit is just as fine as the one from core.\n    let _: MyOwnMaybeUninit = unsafe { MaybeUninit::uninit().assume_init() };\n\n    // This is OK, because empty arrays don't contain data.\n    let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() };\n\n    // Was a false negative.\n    let _: usize = unsafe { MaybeUninit::uninit().assume_init() };\n    //~^ uninit_assumed_init\n\n    polymorphic::<()>();\n    polymorphic_maybe_uninit_array::<10>();\n    polymorphic_maybe_uninit::<u8>();\n\n    fn polymorphic<T>() {\n        // We are conservative around polymorphic types.\n        let _: T = unsafe { MaybeUninit::uninit().assume_init() };\n        //~^ uninit_assumed_init\n    }\n\n    fn polymorphic_maybe_uninit_array<const N: usize>() {\n        // While the type is polymorphic, MaybeUninit<u8> is not.\n        let _: [MaybeUninit<u8>; N] = unsafe { MaybeUninit::uninit().assume_init() };\n    }\n\n    fn polymorphic_maybe_uninit<T>() {\n        // The entire type is polymorphic, but it's wrapped in a MaybeUninit.\n        let _: MaybeUninit<T> = unsafe { MaybeUninit::uninit().assume_init() };\n    }\n}\n"
  },
  {
    "path": "tests/ui/uninit.stderr",
    "content": "error: this call for this type may be undefined behavior\n  --> tests/ui/uninit.rs:12:29\n   |\nLL |     let _: usize = unsafe { MaybeUninit::uninit().assume_init() };\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `#[deny(clippy::uninit_assumed_init)]` on by default\n\nerror: this call for this type may be undefined behavior\n  --> tests/ui/uninit.rs:34:29\n   |\nLL |     let _: usize = unsafe { MaybeUninit::uninit().assume_init() };\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call for this type may be undefined behavior\n  --> tests/ui/uninit.rs:43:29\n   |\nLL |         let _: T = unsafe { MaybeUninit::uninit().assume_init() };\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/uninit_vec.rs",
    "content": "#![warn(clippy::uninit_vec)]\n\nuse std::cell::UnsafeCell;\nuse std::mem::MaybeUninit;\n\n#[derive(Default)]\nstruct MyVec {\n    vec: Vec<u8>,\n}\n\nunion MyOwnMaybeUninit {\n    value: u8,\n    uninit: (),\n}\n\n// https://github.com/rust-lang/rust/issues/119620\nunsafe fn requires_paramenv<S>() {\n    unsafe {\n        let mut vec = Vec::<UnsafeCell<*mut S>>::with_capacity(1);\n        //~^ uninit_vec\n        vec.set_len(1);\n    }\n\n    let mut vec = Vec::<UnsafeCell<*mut S>>::with_capacity(2);\n    //~^ uninit_vec\n    unsafe {\n        vec.set_len(2);\n    }\n}\n\nfn main() {\n    // with_capacity() -> set_len() should be detected\n    let mut vec: Vec<u8> = Vec::with_capacity(1000);\n    //~^ uninit_vec\n\n    unsafe {\n        vec.set_len(200);\n    }\n\n    // reserve() -> set_len() should be detected\n    vec.reserve(1000);\n    //~^ uninit_vec\n\n    unsafe {\n        vec.set_len(200);\n    }\n\n    // new() -> set_len() should be detected\n    let mut vec: Vec<u8> = Vec::new();\n    //~^ uninit_vec\n\n    unsafe {\n        vec.set_len(200);\n    }\n\n    // default() -> set_len() should be detected\n    let mut vec: Vec<u8> = Default::default();\n    //~^ uninit_vec\n\n    unsafe {\n        vec.set_len(200);\n    }\n\n    let mut vec: Vec<u8> = Vec::default();\n    //~^ uninit_vec\n\n    unsafe {\n        vec.set_len(200);\n    }\n\n    // test when both calls are enclosed in the same unsafe block\n    unsafe {\n        let mut vec: Vec<u8> = Vec::with_capacity(1000);\n        //~^ uninit_vec\n\n        vec.set_len(200);\n\n        vec.reserve(1000);\n        //~^ uninit_vec\n\n        vec.set_len(200);\n    }\n\n    let mut vec: Vec<u8> = Vec::with_capacity(1000);\n    //~^ uninit_vec\n\n    unsafe {\n        // test the case where there are other statements in the following unsafe block\n        vec.set_len(200);\n        assert!(vec.len() == 200);\n    }\n\n    // handle vec stored in the field of a struct\n    let mut my_vec = MyVec::default();\n    my_vec.vec.reserve(1000);\n    //~^ uninit_vec\n\n    unsafe {\n        my_vec.vec.set_len(200);\n    }\n\n    my_vec.vec = Vec::with_capacity(1000);\n    //~^ uninit_vec\n\n    unsafe {\n        my_vec.vec.set_len(200);\n    }\n\n    // Test `#[allow(...)]` attributes on inner unsafe block (shouldn't trigger)\n    let mut vec: Vec<u8> = Vec::with_capacity(1000);\n    #[allow(clippy::uninit_vec)]\n    unsafe {\n        vec.set_len(200);\n    }\n\n    // MaybeUninit-wrapped types should not be detected\n    unsafe {\n        let mut vec: Vec<MaybeUninit<u8>> = Vec::with_capacity(1000);\n        vec.set_len(200);\n\n        let mut vec: Vec<(MaybeUninit<u8>, MaybeUninit<bool>)> = Vec::with_capacity(1000);\n        vec.set_len(200);\n\n        let mut vec: Vec<(MaybeUninit<u8>, [MaybeUninit<bool>; 2])> = Vec::with_capacity(1000);\n        vec.set_len(200);\n    }\n\n    // known false negative\n    let mut vec1: Vec<u8> = Vec::with_capacity(1000);\n    let mut vec2: Vec<u8> = Vec::with_capacity(1000);\n    unsafe {\n        vec1.set_len(200);\n        vec2.set_len(200);\n    }\n\n    // set_len(0) should not be detected\n    let mut vec: Vec<u8> = Vec::with_capacity(1000);\n    unsafe {\n        vec.set_len(0);\n    }\n\n    // ZSTs should not be detected\n    let mut vec: Vec<()> = Vec::with_capacity(1000);\n    unsafe {\n        vec.set_len(10);\n    }\n\n    // unions should not be detected\n    let mut vec: Vec<MyOwnMaybeUninit> = Vec::with_capacity(1000);\n    unsafe {\n        vec.set_len(10);\n    }\n\n    polymorphic::<()>();\n\n    fn polymorphic<T>() {\n        // We are conservative around polymorphic types.\n        let mut vec: Vec<T> = Vec::with_capacity(1000);\n        //~^ uninit_vec\n\n        unsafe {\n            vec.set_len(10);\n        }\n    }\n\n    fn poly_maybe_uninit<T>() {\n        // We are conservative around polymorphic types.\n        let mut vec: Vec<MaybeUninit<T>> = Vec::with_capacity(1000);\n        unsafe {\n            vec.set_len(10);\n        }\n    }\n\n    fn nested_union<T>() {\n        let mut vec: Vec<UnsafeCell<MaybeUninit<T>>> = Vec::with_capacity(1);\n        unsafe {\n            vec.set_len(1);\n        }\n    }\n\n    struct Recursive<T>(*const Recursive<T>, MaybeUninit<T>);\n    fn recursive_union<T>() {\n        // Make sure we don't stack overflow on recursive types.\n        // The pointer acts as the base case because it can't be uninit regardless of its pointee.\n\n        let mut vec: Vec<Recursive<T>> = Vec::with_capacity(1);\n        //~^ uninit_vec\n\n        unsafe {\n            vec.set_len(1);\n        }\n    }\n\n    #[repr(u8)]\n    enum Enum<T> {\n        Variant(T),\n    }\n    fn union_in_enum<T>() {\n        // Enums can have a discriminant that can't be uninit, so this should still warn\n        let mut vec: Vec<Enum<T>> = Vec::with_capacity(1);\n        //~^ uninit_vec\n\n        unsafe {\n            vec.set_len(1);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/uninit_vec.stderr",
    "content": "error: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:24:5\n   |\nLL |     let mut vec = Vec::<UnsafeCell<*mut S>>::with_capacity(2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(2);\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n   = note: `-D clippy::uninit-vec` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::uninit_vec)]`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:19:9\n   |\nLL |         let mut vec = Vec::<UnsafeCell<*mut S>>::with_capacity(1);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nLL |\nLL |         vec.set_len(1);\n   |         ^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:33:5\n   |\nLL |     let mut vec: Vec<u8> = Vec::with_capacity(1000);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:41:5\n   |\nLL |     vec.reserve(1000);\n   |     ^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` on empty `Vec` creates out-of-bound values\n  --> tests/ui/uninit_vec.rs:49:5\n   |\nLL |     let mut vec: Vec<u8> = Vec::new();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^\n\nerror: calling `set_len()` on empty `Vec` creates out-of-bound values\n  --> tests/ui/uninit_vec.rs:57:5\n   |\nLL |     let mut vec: Vec<u8> = Default::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^\n\nerror: calling `set_len()` on empty `Vec` creates out-of-bound values\n  --> tests/ui/uninit_vec.rs:64:5\n   |\nLL |     let mut vec: Vec<u8> = Vec::default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:84:5\n   |\nLL |     let mut vec: Vec<u8> = Vec::with_capacity(1000);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:95:5\n   |\nLL |     my_vec.vec.reserve(1000);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         my_vec.vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:102:5\n   |\nLL |     my_vec.vec = Vec::with_capacity(1000);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         my_vec.vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:73:9\n   |\nLL |         let mut vec: Vec<u8> = Vec::with_capacity(1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:78:9\n   |\nLL |         vec.reserve(1000);\n   |         ^^^^^^^^^^^^^^^^^^\n...\nLL |         vec.set_len(200);\n   |         ^^^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:158:9\n   |\nLL |         let mut vec: Vec<T> = Vec::with_capacity(1000);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             vec.set_len(10);\n   |             ^^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:186:9\n   |\nLL |         let mut vec: Vec<Recursive<T>> = Vec::with_capacity(1);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             vec.set_len(1);\n   |             ^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: calling `set_len()` immediately after reserving a buffer creates uninitialized values\n  --> tests/ui/uninit_vec.rs:200:9\n   |\nLL |         let mut vec: Vec<Enum<T>> = Vec::with_capacity(1);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |             vec.set_len(1);\n   |             ^^^^^^^^^^^^^^\n   |\n   = help: initialize the buffer or wrap the content in `MaybeUninit`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/uninlined_format_args.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::uninlined_format_args)]\n#![allow(named_arguments_used_positionally, unused)]\n#![allow(\n    clippy::eq_op,\n    clippy::format_in_format_args,\n    clippy::print_literal,\n    clippy::unnecessary_literal_unwrap\n)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nmacro_rules! no_param_str {\n    () => {\n        \"{}\"\n    };\n}\n\nmacro_rules! my_println {\n   ($($args:tt),*) => {{\n        println!($($args),*)\n    }};\n}\n\nmacro_rules! my_println_args {\n    ($($args:tt),*) => {{\n        println!(\"foo: {}\", format_args!($($args),*))\n    }};\n}\n\nfn tester(fn_arg: i32) {\n    let local_i32 = 1;\n    let local_f64 = 2.0;\n    let local_opt: Option<i32> = Some(3);\n    let width = 4;\n    let prec = 5;\n    let val = 6;\n\n    // make sure this file hasn't been corrupted with tabs converted to spaces\n    // let _ = '\t';  // <- this is a single tab character\n    let _: &[u8; 3] = b\"\t \t\"; // <- <tab><space><tab>\n\n    println!(\"val='{local_i32}'\");\n    //~^ uninlined_format_args\n    println!(\"val='{local_i32}'\"); // 3 spaces\n    //\n    //~^^ uninlined_format_args\n    println!(\"val='{local_i32}'\"); // tab\n    //\n    //~^^ uninlined_format_args\n    println!(\"val='{local_i32}'\"); // space+tab\n    //\n    //~^^ uninlined_format_args\n    println!(\"val='{local_i32}'\"); // tab+space\n    //\n    //~^^ uninlined_format_args\n    println!(\n        //~^ uninlined_format_args\n        \"val='{local_i32}'\"\n    );\n    println!(\"{local_i32}\");\n    //~^ uninlined_format_args\n    println!(\"{fn_arg}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:?}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:#?}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:4}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:04}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:<3}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:#010x}\");\n    //~^ uninlined_format_args\n    println!(\"{local_f64:.1}\");\n    //~^ uninlined_format_args\n    println!(\"Hello {} is {:.*}\", \"x\", local_i32, local_f64);\n    println!(\"Hello {} is {:.*}\", local_i32, 5, local_f64);\n    println!(\"Hello {} is {2:.*}\", local_i32, 5, local_f64);\n    println!(\"{local_i32} {local_f64}\");\n    //~^ uninlined_format_args\n    println!(\"{}, {}\", local_i32, local_opt.unwrap());\n    println!(\"{val}\");\n    //~^ uninlined_format_args\n    println!(\"{val}\");\n    //~^ uninlined_format_args\n    println!(\"{} {1}\", local_i32, 42);\n    println!(\"val='{local_i32}'\");\n    //~^ uninlined_format_args\n    println!(\"val='{local_i32}'\");\n    //~^ uninlined_format_args\n    println!(\"val='{local_i32}'\");\n    //~^ uninlined_format_args\n    println!(\"val='{fn_arg}'\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:?}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:#?}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:04}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:<3}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:#010x}\");\n    //~^ uninlined_format_args\n    println!(\"{local_f64:.1}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32} {local_i32}\");\n    //~^ uninlined_format_args\n    println!(\"{local_f64} {local_i32} {local_i32} {local_f64}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32} {local_f64}\");\n    //~^ uninlined_format_args\n    println!(\"{local_f64} {local_i32}\");\n    //~^ uninlined_format_args\n    println!(\"{local_f64} {local_i32} {local_f64} {local_i32}\");\n    //~^ uninlined_format_args\n    println!(\"{1} {0}\", \"str\", local_i32);\n    println!(\"{local_i32}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:width$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:width$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$.val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$.val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$.val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$.val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$.val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$.val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$.val$}\");\n    //~^ uninlined_format_args\n    println!(\"{val:val$.val$}\");\n    //~^ uninlined_format_args\n    println!(\"{width:width$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:width$}\");\n    //~^ uninlined_format_args\n    println!(\"{width:width$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:width$}\");\n    //~^ uninlined_format_args\n    println!(\"{prec:.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{prec:.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{width:width$.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{width:width$.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_f64:width$.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_f64:width$.prec$} {local_f64} {width} {prec}\");\n    //~^ uninlined_format_args\n    println!(\n        //~^ uninlined_format_args\n        \"{local_i32:width$.prec$} {local_i32:prec$.width$} {width:local_i32$.prec$} {width:prec$.local_i32$} {prec:local_i32$.width$} {prec:width$.local_i32$}\",\n    );\n    println!(\n        \"{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$} {3}\",\n        local_i32,\n        width,\n        prec,\n        1 + 2\n    );\n    println!(\"Width = {local_i32}, value with width = {local_f64:local_i32$}\");\n    //~^ uninlined_format_args\n    println!(\"{local_i32:width$.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{width:width$.prec$}\");\n    //~^ uninlined_format_args\n    println!(\"{}\", format!(\"{}\", local_i32));\n    my_println!(\"{}\", local_i32);\n    my_println_args!(\"{}\", local_i32);\n\n    // these should NOT be modified by the lint\n    println!(concat!(\"nope \", \"{}\"), local_i32);\n    println!(\"val='{local_i32}'\");\n    println!(\"val='{local_i32 }'\");\n    println!(\"val='{local_i32\t}'\"); // with tab\n    println!(\"val='{local_i32\\n}'\");\n    println!(\"{}\", usize::MAX);\n    println!(\"{}\", local_opt.unwrap());\n    println!(\n        \"val='{local_i32\n    }'\"\n    );\n    println!(no_param_str!(), local_i32);\n\n    println!(\n        //~^ uninlined_format_args\n        \"{val}\",\n    );\n    println!(\"{val}\");\n    //~^ uninlined_format_args\n\n    println!(with_span!(\"{0} {1}\" \"{1} {0}\"), local_i32, local_f64);\n    println!(\"{}\", with_span!(span val));\n\n    if local_i32 > 0 {\n        panic!(\"p1 {local_i32}\");\n        //~^ uninlined_format_args\n    }\n    if local_i32 > 0 {\n        panic!(\"p2 {local_i32}\");\n        //~^ uninlined_format_args\n    }\n    if local_i32 > 0 {\n        panic!(\"p3 {local_i32}\");\n        //~^ uninlined_format_args\n    }\n    if local_i32 > 0 {\n        panic!(\"p4 {local_i32}\");\n    }\n}\n\nfn main() {}\n\n#[clippy::msrv = \"1.57\"]\nfn _under_msrv() {\n    let local_i32 = 1;\n    println!(\"don't expand='{}'\", local_i32);\n}\n\n#[clippy::msrv = \"1.58\"]\nfn _meets_msrv() {\n    let local_i32 = 1;\n    println!(\"expand='{local_i32}'\");\n    //~^ uninlined_format_args\n}\n\nfn _do_not_fire() {\n    println!(\"{:?}\", None::<()>);\n}\n\nmacro_rules! _internal {\n    ($($args:tt)*) => {\n        println!(\"{}\", format_args!($($args)*))\n    };\n}\n\nmacro_rules! my_println2 {\n   ($target:expr, $($args:tt)+) => {{\n       if $target {\n           _internal!($($args)+)\n       }\n    }};\n}\n\nmacro_rules! my_println2_args {\n    ($target:expr, $($args:tt)+) => {{\n       if $target {\n           _internal!(\"foo: {}\", format_args!($($args)+))\n       }\n    }};\n}\n\nmacro_rules! my_concat {\n    ($fmt:literal $(, $e:expr)*) => {\n        println!(concat!(\"ERROR: \", $fmt), $($e,)*)\n    }\n}\n\nmacro_rules! my_good_macro {\n    ($fmt:literal $(, $e:expr)* $(,)?) => {\n        println!($fmt $(, $e)*)\n    }\n}\n\nmacro_rules! my_bad_macro {\n    ($fmt:literal, $($e:expr),*) => {\n        println!($fmt, $($e,)*)\n    }\n}\n\nmacro_rules! my_bad_macro2 {\n    ($fmt:literal) => {\n        let s = $fmt.clone();\n        println!(\"{}\", s);\n    };\n    ($fmt:literal, $($e:expr)+) => {\n        println!($fmt, $($e,)*)\n    };\n}\n\n// This abomination was suggested by @Alexendoo, may the Rust gods have mercy on their soul...\n// https://github.com/rust-lang/rust-clippy/pull/9948#issuecomment-1327965962\nmacro_rules! used_twice {\n    (\n        large = $large:literal,\n        small = $small:literal,\n        $val:expr,\n    ) => {\n        if $val < 5 {\n            println!($small, $val);\n        } else {\n            println!($large, $val);\n        }\n    };\n}\n\nfn tester2() {\n    let local_i32 = 1;\n    my_println2_args!(true, \"{}\", local_i32);\n    my_println2!(true, \"{}\", local_i32);\n    my_concat!(\"{}\", local_i32);\n    my_good_macro!(\"{}\", local_i32);\n    my_good_macro!(\"{}\", local_i32,);\n    my_bad_macro!(\"{}\", local_i32);\n    my_bad_macro2!(\"{}\", local_i32);\n    used_twice! {\n        large = \"large value: {}\",\n        small = \"small value: {}\",\n        local_i32,\n    };\n}\n\n#[clippy::format_args]\nmacro_rules! usr_println {\n    ($target:expr, $($args:tt)*) => {{\n        if $target {\n            println!($($args)*)\n        }\n    }};\n}\n\nfn user_format() {\n    let local_i32 = 1;\n    let local_f64 = 2.0;\n\n    usr_println!(true, \"val='{local_i32}'\");\n    //~^ uninlined_format_args\n    usr_println!(true, \"{local_i32}\");\n    //~^ uninlined_format_args\n    usr_println!(true, \"{local_i32:#010x}\");\n    //~^ uninlined_format_args\n    usr_println!(true, \"{local_f64:.1}\");\n    //~^ uninlined_format_args\n}\n\n// issue #16411: false negative when #[clippy::format_args] macro uses nested format_args\n// without binding the inner args first\n#[clippy::format_args]\nmacro_rules! nested_format_args {\n    ($($arg:tt)*) => {{\n        // Wraps the user args in another format_args call\n        ::core::format_args!(\"{}\\n\", ::core::format_args!($($arg)*))\n    }};\n}\n\nfn nested_format_args_user() {\n    let local_i32 = 1;\n    let local_f64 = 2.0;\n\n    // false negative: should warn but currently doesn't because the inner format_args\n    // is not processed when it's used as an argument to another format_args\n    nested_format_args!(\"{}\", local_i32);\n    nested_format_args!(\"val='{}'\", local_i32);\n    nested_format_args!(\"{:.1}\", local_f64);\n}\n"
  },
  {
    "path": "tests/ui/uninlined_format_args.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::uninlined_format_args)]\n#![allow(named_arguments_used_positionally, unused)]\n#![allow(\n    clippy::eq_op,\n    clippy::format_in_format_args,\n    clippy::print_literal,\n    clippy::unnecessary_literal_unwrap\n)]\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nmacro_rules! no_param_str {\n    () => {\n        \"{}\"\n    };\n}\n\nmacro_rules! my_println {\n   ($($args:tt),*) => {{\n        println!($($args),*)\n    }};\n}\n\nmacro_rules! my_println_args {\n    ($($args:tt),*) => {{\n        println!(\"foo: {}\", format_args!($($args),*))\n    }};\n}\n\nfn tester(fn_arg: i32) {\n    let local_i32 = 1;\n    let local_f64 = 2.0;\n    let local_opt: Option<i32> = Some(3);\n    let width = 4;\n    let prec = 5;\n    let val = 6;\n\n    // make sure this file hasn't been corrupted with tabs converted to spaces\n    // let _ = '\t';  // <- this is a single tab character\n    let _: &[u8; 3] = b\"\t \t\"; // <- <tab><space><tab>\n\n    println!(\"val='{}'\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"val='{   }'\", local_i32); // 3 spaces\n    //\n    //~^^ uninlined_format_args\n    println!(\"val='{\t}'\", local_i32); // tab\n    //\n    //~^^ uninlined_format_args\n    println!(\"val='{ \t}'\", local_i32); // space+tab\n    //\n    //~^^ uninlined_format_args\n    println!(\"val='{\t }'\", local_i32); // tab+space\n    //\n    //~^^ uninlined_format_args\n    println!(\n        //~^ uninlined_format_args\n        \"val='{\n    }'\",\n        local_i32\n    );\n    println!(\"{}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{}\", fn_arg);\n    //~^ uninlined_format_args\n    println!(\"{:?}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{:#?}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{:4}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{:04}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{:<3}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{:#010x}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{:.1}\", local_f64);\n    //~^ uninlined_format_args\n    println!(\"Hello {} is {:.*}\", \"x\", local_i32, local_f64);\n    println!(\"Hello {} is {:.*}\", local_i32, 5, local_f64);\n    println!(\"Hello {} is {2:.*}\", local_i32, 5, local_f64);\n    println!(\"{} {}\", local_i32, local_f64);\n    //~^ uninlined_format_args\n    println!(\"{}, {}\", local_i32, local_opt.unwrap());\n    println!(\"{}\", val);\n    //~^ uninlined_format_args\n    println!(\"{}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{} {1}\", local_i32, 42);\n    println!(\"val='{\\t }'\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"val='{\\n }'\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"val='{local_i32}'\", local_i32 = local_i32);\n    //~^ uninlined_format_args\n    println!(\"val='{local_i32}'\", local_i32 = fn_arg);\n    //~^ uninlined_format_args\n    println!(\"{0}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{0:?}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{0:#?}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{0:04}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{0:<3}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{0:#010x}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{0:.1}\", local_f64);\n    //~^ uninlined_format_args\n    println!(\"{0} {0}\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"{1} {} {0} {}\", local_i32, local_f64);\n    //~^ uninlined_format_args\n    println!(\"{0} {1}\", local_i32, local_f64);\n    //~^ uninlined_format_args\n    println!(\"{1} {0}\", local_i32, local_f64);\n    //~^ uninlined_format_args\n    println!(\"{1} {0} {1} {0}\", local_i32, local_f64);\n    //~^ uninlined_format_args\n    println!(\"{1} {0}\", \"str\", local_i32);\n    println!(\"{v}\", v = local_i32);\n    //~^ uninlined_format_args\n    println!(\"{local_i32:0$}\", width);\n    //~^ uninlined_format_args\n    println!(\"{local_i32:w$}\", w = width);\n    //~^ uninlined_format_args\n    println!(\"{local_i32:.0$}\", prec);\n    //~^ uninlined_format_args\n    println!(\"{local_i32:.p$}\", p = prec);\n    //~^ uninlined_format_args\n    println!(\"{:0$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{0:0$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{:0$.0$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{0:0$.0$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{0:0$.v$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{0:v$.0$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{v:0$.0$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{v:v$.0$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{v:0$.v$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{v:v$.v$}\", v = val);\n    //~^ uninlined_format_args\n    println!(\"{:0$}\", width);\n    //~^ uninlined_format_args\n    println!(\"{:1$}\", local_i32, width);\n    //~^ uninlined_format_args\n    println!(\"{:w$}\", w = width);\n    //~^ uninlined_format_args\n    println!(\"{:w$}\", local_i32, w = width);\n    //~^ uninlined_format_args\n    println!(\"{:.0$}\", prec);\n    //~^ uninlined_format_args\n    println!(\"{:.1$}\", local_i32, prec);\n    //~^ uninlined_format_args\n    println!(\"{:.p$}\", p = prec);\n    //~^ uninlined_format_args\n    println!(\"{:.p$}\", local_i32, p = prec);\n    //~^ uninlined_format_args\n    println!(\"{:0$.1$}\", width, prec);\n    //~^ uninlined_format_args\n    println!(\"{:0$.w$}\", width, w = prec);\n    //~^ uninlined_format_args\n    println!(\"{:1$.2$}\", local_f64, width, prec);\n    //~^ uninlined_format_args\n    println!(\"{:1$.2$} {0} {1} {2}\", local_f64, width, prec);\n    //~^ uninlined_format_args\n    println!(\n        //~^ uninlined_format_args\n        \"{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}\",\n        local_i32, width, prec,\n    );\n    println!(\n        \"{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$} {3}\",\n        local_i32,\n        width,\n        prec,\n        1 + 2\n    );\n    println!(\"Width = {}, value with width = {:0$}\", local_i32, local_f64);\n    //~^ uninlined_format_args\n    println!(\"{:w$.p$}\", local_i32, w = width, p = prec);\n    //~^ uninlined_format_args\n    println!(\"{:w$.p$}\", w = width, p = prec);\n    //~^ uninlined_format_args\n    println!(\"{}\", format!(\"{}\", local_i32));\n    my_println!(\"{}\", local_i32);\n    my_println_args!(\"{}\", local_i32);\n\n    // these should NOT be modified by the lint\n    println!(concat!(\"nope \", \"{}\"), local_i32);\n    println!(\"val='{local_i32}'\");\n    println!(\"val='{local_i32 }'\");\n    println!(\"val='{local_i32\t}'\"); // with tab\n    println!(\"val='{local_i32\\n}'\");\n    println!(\"{}\", usize::MAX);\n    println!(\"{}\", local_opt.unwrap());\n    println!(\n        \"val='{local_i32\n    }'\"\n    );\n    println!(no_param_str!(), local_i32);\n\n    println!(\n        //~^ uninlined_format_args\n        \"{}\",\n        // comment with a comma , in it\n        val,\n    );\n    println!(\"{}\", /* comment with a comma , in it */ val);\n    //~^ uninlined_format_args\n\n    println!(with_span!(\"{0} {1}\" \"{1} {0}\"), local_i32, local_f64);\n    println!(\"{}\", with_span!(span val));\n\n    if local_i32 > 0 {\n        panic!(\"p1 {}\", local_i32);\n        //~^ uninlined_format_args\n    }\n    if local_i32 > 0 {\n        panic!(\"p2 {0}\", local_i32);\n        //~^ uninlined_format_args\n    }\n    if local_i32 > 0 {\n        panic!(\"p3 {local_i32}\", local_i32 = local_i32);\n        //~^ uninlined_format_args\n    }\n    if local_i32 > 0 {\n        panic!(\"p4 {local_i32}\");\n    }\n}\n\nfn main() {}\n\n#[clippy::msrv = \"1.57\"]\nfn _under_msrv() {\n    let local_i32 = 1;\n    println!(\"don't expand='{}'\", local_i32);\n}\n\n#[clippy::msrv = \"1.58\"]\nfn _meets_msrv() {\n    let local_i32 = 1;\n    println!(\"expand='{}'\", local_i32);\n    //~^ uninlined_format_args\n}\n\nfn _do_not_fire() {\n    println!(\"{:?}\", None::<()>);\n}\n\nmacro_rules! _internal {\n    ($($args:tt)*) => {\n        println!(\"{}\", format_args!($($args)*))\n    };\n}\n\nmacro_rules! my_println2 {\n   ($target:expr, $($args:tt)+) => {{\n       if $target {\n           _internal!($($args)+)\n       }\n    }};\n}\n\nmacro_rules! my_println2_args {\n    ($target:expr, $($args:tt)+) => {{\n       if $target {\n           _internal!(\"foo: {}\", format_args!($($args)+))\n       }\n    }};\n}\n\nmacro_rules! my_concat {\n    ($fmt:literal $(, $e:expr)*) => {\n        println!(concat!(\"ERROR: \", $fmt), $($e,)*)\n    }\n}\n\nmacro_rules! my_good_macro {\n    ($fmt:literal $(, $e:expr)* $(,)?) => {\n        println!($fmt $(, $e)*)\n    }\n}\n\nmacro_rules! my_bad_macro {\n    ($fmt:literal, $($e:expr),*) => {\n        println!($fmt, $($e,)*)\n    }\n}\n\nmacro_rules! my_bad_macro2 {\n    ($fmt:literal) => {\n        let s = $fmt.clone();\n        println!(\"{}\", s);\n    };\n    ($fmt:literal, $($e:expr)+) => {\n        println!($fmt, $($e,)*)\n    };\n}\n\n// This abomination was suggested by @Alexendoo, may the Rust gods have mercy on their soul...\n// https://github.com/rust-lang/rust-clippy/pull/9948#issuecomment-1327965962\nmacro_rules! used_twice {\n    (\n        large = $large:literal,\n        small = $small:literal,\n        $val:expr,\n    ) => {\n        if $val < 5 {\n            println!($small, $val);\n        } else {\n            println!($large, $val);\n        }\n    };\n}\n\nfn tester2() {\n    let local_i32 = 1;\n    my_println2_args!(true, \"{}\", local_i32);\n    my_println2!(true, \"{}\", local_i32);\n    my_concat!(\"{}\", local_i32);\n    my_good_macro!(\"{}\", local_i32);\n    my_good_macro!(\"{}\", local_i32,);\n    my_bad_macro!(\"{}\", local_i32);\n    my_bad_macro2!(\"{}\", local_i32);\n    used_twice! {\n        large = \"large value: {}\",\n        small = \"small value: {}\",\n        local_i32,\n    };\n}\n\n#[clippy::format_args]\nmacro_rules! usr_println {\n    ($target:expr, $($args:tt)*) => {{\n        if $target {\n            println!($($args)*)\n        }\n    }};\n}\n\nfn user_format() {\n    let local_i32 = 1;\n    let local_f64 = 2.0;\n\n    usr_println!(true, \"val='{}'\", local_i32);\n    //~^ uninlined_format_args\n    usr_println!(true, \"{}\", local_i32);\n    //~^ uninlined_format_args\n    usr_println!(true, \"{:#010x}\", local_i32);\n    //~^ uninlined_format_args\n    usr_println!(true, \"{:.1}\", local_f64);\n    //~^ uninlined_format_args\n}\n\n// issue #16411: false negative when #[clippy::format_args] macro uses nested format_args\n// without binding the inner args first\n#[clippy::format_args]\nmacro_rules! nested_format_args {\n    ($($arg:tt)*) => {{\n        // Wraps the user args in another format_args call\n        ::core::format_args!(\"{}\\n\", ::core::format_args!($($arg)*))\n    }};\n}\n\nfn nested_format_args_user() {\n    let local_i32 = 1;\n    let local_f64 = 2.0;\n\n    // false negative: should warn but currently doesn't because the inner format_args\n    // is not processed when it's used as an argument to another format_args\n    nested_format_args!(\"{}\", local_i32);\n    nested_format_args!(\"val='{}'\", local_i32);\n    nested_format_args!(\"{:.1}\", local_f64);\n}\n"
  },
  {
    "path": "tests/ui/uninlined_format_args.stderr",
    "content": "error: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:45:5\n   |\nLL |     println!(\"val='{}'\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::uninlined-format-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`\nhelp: change this to\n   |\nLL -     println!(\"val='{}'\", local_i32);\nLL +     println!(\"val='{local_i32}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:47:5\n   |\nLL |     println!(\"val='{   }'\", local_i32); // 3 spaces\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"val='{   }'\", local_i32); // 3 spaces\nLL +     println!(\"val='{local_i32}'\"); // 3 spaces\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:50:5\n   |\nLL |     println!(\"val='{    }'\", local_i32); // tab\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"val='{    }'\", local_i32); // tab\nLL +     println!(\"val='{local_i32}'\"); // tab\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:53:5\n   |\nLL |     println!(\"val='{     }'\", local_i32); // space+tab\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"val='{     }'\", local_i32); // space+tab\nLL +     println!(\"val='{local_i32}'\"); // space+tab\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:56:5\n   |\nLL |     println!(\"val='{     }'\", local_i32); // tab+space\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"val='{     }'\", local_i32); // tab+space\nLL +     println!(\"val='{local_i32}'\"); // tab+space\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:59:5\n   |\nLL | /     println!(\nLL | |\nLL | |         \"val='{\nLL | |     }'\",\nLL | |         local_i32\nLL | |     );\n   | |_____^\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:65:5\n   |\nLL |     println!(\"{}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{}\", local_i32);\nLL +     println!(\"{local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:67:5\n   |\nLL |     println!(\"{}\", fn_arg);\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{}\", fn_arg);\nLL +     println!(\"{fn_arg}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:69:5\n   |\nLL |     println!(\"{:?}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:?}\", local_i32);\nLL +     println!(\"{local_i32:?}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:71:5\n   |\nLL |     println!(\"{:#?}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:#?}\", local_i32);\nLL +     println!(\"{local_i32:#?}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:73:5\n   |\nLL |     println!(\"{:4}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:4}\", local_i32);\nLL +     println!(\"{local_i32:4}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:75:5\n   |\nLL |     println!(\"{:04}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:04}\", local_i32);\nLL +     println!(\"{local_i32:04}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:77:5\n   |\nLL |     println!(\"{:<3}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:<3}\", local_i32);\nLL +     println!(\"{local_i32:<3}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:79:5\n   |\nLL |     println!(\"{:#010x}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:#010x}\", local_i32);\nLL +     println!(\"{local_i32:#010x}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:81:5\n   |\nLL |     println!(\"{:.1}\", local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:.1}\", local_f64);\nLL +     println!(\"{local_f64:.1}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:86:5\n   |\nLL |     println!(\"{} {}\", local_i32, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{} {}\", local_i32, local_f64);\nLL +     println!(\"{local_i32} {local_f64}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:89:5\n   |\nLL |     println!(\"{}\", val);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{}\", val);\nLL +     println!(\"{val}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:91:5\n   |\nLL |     println!(\"{}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{}\", v = val);\nLL +     println!(\"{val}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:94:5\n   |\nLL |     println!(\"val='{\\t }'\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"val='{\\t }'\", local_i32);\nLL +     println!(\"val='{local_i32}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:96:5\n   |\nLL |     println!(\"val='{\\n }'\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"val='{\\n }'\", local_i32);\nLL +     println!(\"val='{local_i32}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:98:5\n   |\nLL |     println!(\"val='{local_i32}'\", local_i32 = local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"val='{local_i32}'\", local_i32 = local_i32);\nLL +     println!(\"val='{local_i32}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:100:5\n   |\nLL |     println!(\"val='{local_i32}'\", local_i32 = fn_arg);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"val='{local_i32}'\", local_i32 = fn_arg);\nLL +     println!(\"val='{fn_arg}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:102:5\n   |\nLL |     println!(\"{0}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0}\", local_i32);\nLL +     println!(\"{local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:104:5\n   |\nLL |     println!(\"{0:?}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:?}\", local_i32);\nLL +     println!(\"{local_i32:?}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:106:5\n   |\nLL |     println!(\"{0:#?}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:#?}\", local_i32);\nLL +     println!(\"{local_i32:#?}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:108:5\n   |\nLL |     println!(\"{0:04}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:04}\", local_i32);\nLL +     println!(\"{local_i32:04}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:110:5\n   |\nLL |     println!(\"{0:<3}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:<3}\", local_i32);\nLL +     println!(\"{local_i32:<3}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:112:5\n   |\nLL |     println!(\"{0:#010x}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:#010x}\", local_i32);\nLL +     println!(\"{local_i32:#010x}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:114:5\n   |\nLL |     println!(\"{0:.1}\", local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:.1}\", local_f64);\nLL +     println!(\"{local_f64:.1}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:116:5\n   |\nLL |     println!(\"{0} {0}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0} {0}\", local_i32);\nLL +     println!(\"{local_i32} {local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:118:5\n   |\nLL |     println!(\"{1} {} {0} {}\", local_i32, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{1} {} {0} {}\", local_i32, local_f64);\nLL +     println!(\"{local_f64} {local_i32} {local_i32} {local_f64}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:120:5\n   |\nLL |     println!(\"{0} {1}\", local_i32, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0} {1}\", local_i32, local_f64);\nLL +     println!(\"{local_i32} {local_f64}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:122:5\n   |\nLL |     println!(\"{1} {0}\", local_i32, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{1} {0}\", local_i32, local_f64);\nLL +     println!(\"{local_f64} {local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:124:5\n   |\nLL |     println!(\"{1} {0} {1} {0}\", local_i32, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{1} {0} {1} {0}\", local_i32, local_f64);\nLL +     println!(\"{local_f64} {local_i32} {local_f64} {local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:127:5\n   |\nLL |     println!(\"{v}\", v = local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{v}\", v = local_i32);\nLL +     println!(\"{local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:129:5\n   |\nLL |     println!(\"{local_i32:0$}\", width);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{local_i32:0$}\", width);\nLL +     println!(\"{local_i32:width$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:131:5\n   |\nLL |     println!(\"{local_i32:w$}\", w = width);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{local_i32:w$}\", w = width);\nLL +     println!(\"{local_i32:width$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:133:5\n   |\nLL |     println!(\"{local_i32:.0$}\", prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{local_i32:.0$}\", prec);\nLL +     println!(\"{local_i32:.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:135:5\n   |\nLL |     println!(\"{local_i32:.p$}\", p = prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{local_i32:.p$}\", p = prec);\nLL +     println!(\"{local_i32:.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:137:5\n   |\nLL |     println!(\"{:0$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:0$}\", v = val);\nLL +     println!(\"{val:val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:139:5\n   |\nLL |     println!(\"{0:0$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:0$}\", v = val);\nLL +     println!(\"{val:val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:141:5\n   |\nLL |     println!(\"{:0$.0$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:0$.0$}\", v = val);\nLL +     println!(\"{val:val$.val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:143:5\n   |\nLL |     println!(\"{0:0$.0$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:0$.0$}\", v = val);\nLL +     println!(\"{val:val$.val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:145:5\n   |\nLL |     println!(\"{0:0$.v$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:0$.v$}\", v = val);\nLL +     println!(\"{val:val$.val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:147:5\n   |\nLL |     println!(\"{0:v$.0$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{0:v$.0$}\", v = val);\nLL +     println!(\"{val:val$.val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:149:5\n   |\nLL |     println!(\"{v:0$.0$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{v:0$.0$}\", v = val);\nLL +     println!(\"{val:val$.val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:151:5\n   |\nLL |     println!(\"{v:v$.0$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{v:v$.0$}\", v = val);\nLL +     println!(\"{val:val$.val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:153:5\n   |\nLL |     println!(\"{v:0$.v$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{v:0$.v$}\", v = val);\nLL +     println!(\"{val:val$.val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:155:5\n   |\nLL |     println!(\"{v:v$.v$}\", v = val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{v:v$.v$}\", v = val);\nLL +     println!(\"{val:val$.val$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:157:5\n   |\nLL |     println!(\"{:0$}\", width);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:0$}\", width);\nLL +     println!(\"{width:width$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:159:5\n   |\nLL |     println!(\"{:1$}\", local_i32, width);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:1$}\", local_i32, width);\nLL +     println!(\"{local_i32:width$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:161:5\n   |\nLL |     println!(\"{:w$}\", w = width);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:w$}\", w = width);\nLL +     println!(\"{width:width$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:163:5\n   |\nLL |     println!(\"{:w$}\", local_i32, w = width);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:w$}\", local_i32, w = width);\nLL +     println!(\"{local_i32:width$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:165:5\n   |\nLL |     println!(\"{:.0$}\", prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:.0$}\", prec);\nLL +     println!(\"{prec:.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:167:5\n   |\nLL |     println!(\"{:.1$}\", local_i32, prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:.1$}\", local_i32, prec);\nLL +     println!(\"{local_i32:.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:169:5\n   |\nLL |     println!(\"{:.p$}\", p = prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:.p$}\", p = prec);\nLL +     println!(\"{prec:.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:171:5\n   |\nLL |     println!(\"{:.p$}\", local_i32, p = prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:.p$}\", local_i32, p = prec);\nLL +     println!(\"{local_i32:.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:173:5\n   |\nLL |     println!(\"{:0$.1$}\", width, prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:0$.1$}\", width, prec);\nLL +     println!(\"{width:width$.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:175:5\n   |\nLL |     println!(\"{:0$.w$}\", width, w = prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:0$.w$}\", width, w = prec);\nLL +     println!(\"{width:width$.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:177:5\n   |\nLL |     println!(\"{:1$.2$}\", local_f64, width, prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:1$.2$}\", local_f64, width, prec);\nLL +     println!(\"{local_f64:width$.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:179:5\n   |\nLL |     println!(\"{:1$.2$} {0} {1} {2}\", local_f64, width, prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:1$.2$} {0} {1} {2}\", local_f64, width, prec);\nLL +     println!(\"{local_f64:width$.prec$} {local_f64} {width} {prec}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:181:5\n   |\nLL | /     println!(\nLL | |\nLL | |         \"{0:1$.2$} {0:2$.1$} {1:0$.2$} {1:2$.0$} {2:0$.1$} {2:1$.0$}\",\nLL | |         local_i32, width, prec,\nLL | |     );\n   | |_____^\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:193:5\n   |\nLL |     println!(\"Width = {}, value with width = {:0$}\", local_i32, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"Width = {}, value with width = {:0$}\", local_i32, local_f64);\nLL +     println!(\"Width = {local_i32}, value with width = {local_f64:local_i32$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:195:5\n   |\nLL |     println!(\"{:w$.p$}\", local_i32, w = width, p = prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:w$.p$}\", local_i32, w = width, p = prec);\nLL +     println!(\"{local_i32:width$.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:197:5\n   |\nLL |     println!(\"{:w$.p$}\", w = width, p = prec);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{:w$.p$}\", w = width, p = prec);\nLL +     println!(\"{width:width$.prec$}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:217:5\n   |\nLL | /     println!(\nLL | |\nLL | |         \"{}\",\n...  |\nLL | |     );\n   | |_____^\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:223:5\n   |\nLL |     println!(\"{}\", /* comment with a comma , in it */ val);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{}\", /* comment with a comma , in it */ val);\nLL +     println!(\"{val}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:230:9\n   |\nLL |         panic!(\"p1 {}\", local_i32);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p1 {}\", local_i32);\nLL +         panic!(\"p1 {local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:234:9\n   |\nLL |         panic!(\"p2 {0}\", local_i32);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p2 {0}\", local_i32);\nLL +         panic!(\"p2 {local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:238:9\n   |\nLL |         panic!(\"p3 {local_i32}\", local_i32 = local_i32);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p3 {local_i32}\", local_i32 = local_i32);\nLL +         panic!(\"p3 {local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:257:5\n   |\nLL |     println!(\"expand='{}'\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"expand='{}'\", local_i32);\nLL +     println!(\"expand='{local_i32}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:360:5\n   |\nLL |     usr_println!(true, \"val='{}'\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     usr_println!(true, \"val='{}'\", local_i32);\nLL +     usr_println!(true, \"val='{local_i32}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:362:5\n   |\nLL |     usr_println!(true, \"{}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     usr_println!(true, \"{}\", local_i32);\nLL +     usr_println!(true, \"{local_i32}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:364:5\n   |\nLL |     usr_println!(true, \"{:#010x}\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     usr_println!(true, \"{:#010x}\", local_i32);\nLL +     usr_println!(true, \"{local_i32:#010x}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args.rs:366:5\n   |\nLL |     usr_println!(true, \"{:.1}\", local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     usr_println!(true, \"{:.1}\", local_f64);\nLL +     usr_println!(true, \"{local_f64:.1}\");\n   |\n\nerror: aborting due to 75 previous errors\n\n"
  },
  {
    "path": "tests/ui/uninlined_format_args_panic.edition2018.fixed",
    "content": "//@revisions: edition2018 edition2021 edition2024\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![warn(clippy::uninlined_format_args)]\n#![allow(clippy::literal_string_with_formatting_args)]\n\nfn main() {\n    let var = 1;\n\n    println!(\"val='{var}'\");\n    //~^ uninlined_format_args\n\n    if var > 0 {\n        panic!(\"p1 {}\", var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        panic!(\"p2 {0}\", var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        panic!(\"p3 {var}\", var = var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n\n    #[allow(non_fmt_panics)]\n    {\n        if var > 0 {\n            panic!(\"p4 {var}\");\n        }\n    }\n\n    assert!(var == 1, \"p5 {}\", var);\n    //~[edition2021]^ uninlined_format_args\n    //~[edition2024]^^ uninlined_format_args\n    debug_assert!(var == 1, \"p6 {}\", var);\n    //~[edition2021]^ uninlined_format_args\n    //~[edition2024]^^ uninlined_format_args\n\n    // core::panic! with format string containing text: should warn on 2021+ (issue #16411)\n    if var > 0 {\n        core::panic!(\"p7 {}\", var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        core::panic!(\"p8 {0}\", var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        core::panic!(\"p9 {var}\", var = var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n\n    // std::panic! and core::panic! with only \"{}\" format string: false negative due to\n    // panic_display special case in panic_2021 macro - no format_args node is created\n    if var > 0 {\n        std::panic!(\"{}\", var);\n    }\n    if var > 0 {\n        core::panic!(\"{}\", var);\n    }\n}\n"
  },
  {
    "path": "tests/ui/uninlined_format_args_panic.edition2018.stderr",
    "content": "error: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:12:5\n   |\nLL |     println!(\"val='{}'\", var);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::uninlined-format-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`\nhelp: change this to\n   |\nLL -     println!(\"val='{}'\", var);\nLL +     println!(\"val='{var}'\");\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/uninlined_format_args_panic.edition2021.fixed",
    "content": "//@revisions: edition2018 edition2021 edition2024\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![warn(clippy::uninlined_format_args)]\n#![allow(clippy::literal_string_with_formatting_args)]\n\nfn main() {\n    let var = 1;\n\n    println!(\"val='{var}'\");\n    //~^ uninlined_format_args\n\n    if var > 0 {\n        panic!(\"p1 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        panic!(\"p2 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        panic!(\"p3 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n\n    #[allow(non_fmt_panics)]\n    {\n        if var > 0 {\n            panic!(\"p4 {var}\");\n        }\n    }\n\n    assert!(var == 1, \"p5 {var}\");\n    //~[edition2021]^ uninlined_format_args\n    //~[edition2024]^^ uninlined_format_args\n    debug_assert!(var == 1, \"p6 {var}\");\n    //~[edition2021]^ uninlined_format_args\n    //~[edition2024]^^ uninlined_format_args\n\n    // core::panic! with format string containing text: should warn on 2021+ (issue #16411)\n    if var > 0 {\n        core::panic!(\"p7 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        core::panic!(\"p8 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        core::panic!(\"p9 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n\n    // std::panic! and core::panic! with only \"{}\" format string: false negative due to\n    // panic_display special case in panic_2021 macro - no format_args node is created\n    if var > 0 {\n        std::panic!(\"{}\", var);\n    }\n    if var > 0 {\n        core::panic!(\"{}\", var);\n    }\n}\n"
  },
  {
    "path": "tests/ui/uninlined_format_args_panic.edition2021.stderr",
    "content": "error: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:12:5\n   |\nLL |     println!(\"val='{}'\", var);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::uninlined-format-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`\nhelp: change this to\n   |\nLL -     println!(\"val='{}'\", var);\nLL +     println!(\"val='{var}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:16:9\n   |\nLL |         panic!(\"p1 {}\", var);\n   |         ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p1 {}\", var);\nLL +         panic!(\"p1 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:21:9\n   |\nLL |         panic!(\"p2 {0}\", var);\n   |         ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p2 {0}\", var);\nLL +         panic!(\"p2 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:26:9\n   |\nLL |         panic!(\"p3 {var}\", var = var);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p3 {var}\", var = var);\nLL +         panic!(\"p3 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:38:5\n   |\nLL |     assert!(var == 1, \"p5 {}\", var);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     assert!(var == 1, \"p5 {}\", var);\nLL +     assert!(var == 1, \"p5 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:41:5\n   |\nLL |     debug_assert!(var == 1, \"p6 {}\", var);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     debug_assert!(var == 1, \"p6 {}\", var);\nLL +     debug_assert!(var == 1, \"p6 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:47:9\n   |\nLL |         core::panic!(\"p7 {}\", var);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         core::panic!(\"p7 {}\", var);\nLL +         core::panic!(\"p7 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:52:9\n   |\nLL |         core::panic!(\"p8 {0}\", var);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         core::panic!(\"p8 {0}\", var);\nLL +         core::panic!(\"p8 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:57:9\n   |\nLL |         core::panic!(\"p9 {var}\", var = var);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         core::panic!(\"p9 {var}\", var = var);\nLL +         core::panic!(\"p9 {var}\");\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/uninlined_format_args_panic.edition2024.fixed",
    "content": "//@revisions: edition2018 edition2021 edition2024\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![warn(clippy::uninlined_format_args)]\n#![allow(clippy::literal_string_with_formatting_args)]\n\nfn main() {\n    let var = 1;\n\n    println!(\"val='{var}'\");\n    //~^ uninlined_format_args\n\n    if var > 0 {\n        panic!(\"p1 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        panic!(\"p2 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        panic!(\"p3 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n\n    #[allow(non_fmt_panics)]\n    {\n        if var > 0 {\n            panic!(\"p4 {var}\");\n        }\n    }\n\n    assert!(var == 1, \"p5 {var}\");\n    //~[edition2021]^ uninlined_format_args\n    //~[edition2024]^^ uninlined_format_args\n    debug_assert!(var == 1, \"p6 {var}\");\n    //~[edition2021]^ uninlined_format_args\n    //~[edition2024]^^ uninlined_format_args\n\n    // core::panic! with format string containing text: should warn on 2021+ (issue #16411)\n    if var > 0 {\n        core::panic!(\"p7 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        core::panic!(\"p8 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        core::panic!(\"p9 {var}\");\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n\n    // std::panic! and core::panic! with only \"{}\" format string: false negative due to\n    // panic_display special case in panic_2021 macro - no format_args node is created\n    if var > 0 {\n        std::panic!(\"{}\", var);\n    }\n    if var > 0 {\n        core::panic!(\"{}\", var);\n    }\n}\n"
  },
  {
    "path": "tests/ui/uninlined_format_args_panic.edition2024.stderr",
    "content": "error: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:12:5\n   |\nLL |     println!(\"val='{}'\", var);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::uninlined-format-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`\nhelp: change this to\n   |\nLL -     println!(\"val='{}'\", var);\nLL +     println!(\"val='{var}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:16:9\n   |\nLL |         panic!(\"p1 {}\", var);\n   |         ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p1 {}\", var);\nLL +         panic!(\"p1 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:21:9\n   |\nLL |         panic!(\"p2 {0}\", var);\n   |         ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p2 {0}\", var);\nLL +         panic!(\"p2 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:26:9\n   |\nLL |         panic!(\"p3 {var}\", var = var);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         panic!(\"p3 {var}\", var = var);\nLL +         panic!(\"p3 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:38:5\n   |\nLL |     assert!(var == 1, \"p5 {}\", var);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     assert!(var == 1, \"p5 {}\", var);\nLL +     assert!(var == 1, \"p5 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:41:5\n   |\nLL |     debug_assert!(var == 1, \"p6 {}\", var);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     debug_assert!(var == 1, \"p6 {}\", var);\nLL +     debug_assert!(var == 1, \"p6 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:47:9\n   |\nLL |         core::panic!(\"p7 {}\", var);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         core::panic!(\"p7 {}\", var);\nLL +         core::panic!(\"p7 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:52:9\n   |\nLL |         core::panic!(\"p8 {0}\", var);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         core::panic!(\"p8 {0}\", var);\nLL +         core::panic!(\"p8 {var}\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui/uninlined_format_args_panic.rs:57:9\n   |\nLL |         core::panic!(\"p9 {var}\", var = var);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -         core::panic!(\"p9 {var}\", var = var);\nLL +         core::panic!(\"p9 {var}\");\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/uninlined_format_args_panic.rs",
    "content": "//@revisions: edition2018 edition2021 edition2024\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![warn(clippy::uninlined_format_args)]\n#![allow(clippy::literal_string_with_formatting_args)]\n\nfn main() {\n    let var = 1;\n\n    println!(\"val='{}'\", var);\n    //~^ uninlined_format_args\n\n    if var > 0 {\n        panic!(\"p1 {}\", var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        panic!(\"p2 {0}\", var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        panic!(\"p3 {var}\", var = var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n\n    #[allow(non_fmt_panics)]\n    {\n        if var > 0 {\n            panic!(\"p4 {var}\");\n        }\n    }\n\n    assert!(var == 1, \"p5 {}\", var);\n    //~[edition2021]^ uninlined_format_args\n    //~[edition2024]^^ uninlined_format_args\n    debug_assert!(var == 1, \"p6 {}\", var);\n    //~[edition2021]^ uninlined_format_args\n    //~[edition2024]^^ uninlined_format_args\n\n    // core::panic! with format string containing text: should warn on 2021+ (issue #16411)\n    if var > 0 {\n        core::panic!(\"p7 {}\", var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        core::panic!(\"p8 {0}\", var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n    if var > 0 {\n        core::panic!(\"p9 {var}\", var = var);\n        //~[edition2021]^ uninlined_format_args\n        //~[edition2024]^^ uninlined_format_args\n    }\n\n    // std::panic! and core::panic! with only \"{}\" format string: false negative due to\n    // panic_display special case in panic_2021 macro - no format_args node is created\n    if var > 0 {\n        std::panic!(\"{}\", var);\n    }\n    if var > 0 {\n        core::panic!(\"{}\", var);\n    }\n}\n"
  },
  {
    "path": "tests/ui/unit_arg.rs",
    "content": "//@aux-build: proc_macros.rs\n//@no-rustfix: overlapping suggestions\n#![warn(clippy::unit_arg)]\n#![allow(unused_must_use, unused_variables)]\n#![allow(\n    clippy::let_unit_value,\n    clippy::needless_question_mark,\n    clippy::never_loop,\n    clippy::no_effect,\n    clippy::or_fun_call,\n    clippy::self_named_constructors,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_wraps,\n    clippy::unused_unit\n)]\n\nextern crate proc_macros;\n\nuse proc_macros::with_span;\nuse std::fmt::Debug;\n\nfn foo<T: Debug>(t: T) {\n    println!(\"{:?}\", t);\n}\n\nfn foo3<T1: Debug, T2: Debug, T3: Debug>(t1: T1, t2: T2, t3: T3) {\n    println!(\"{:?}, {:?}, {:?}\", t1, t2, t3);\n}\n\nstruct Bar;\n\nimpl Bar {\n    fn bar<T: Debug>(&self, t: T) {\n        println!(\"{:?}\", t);\n    }\n}\n\nfn baz<T: Debug>(t: T) {\n    foo(t);\n}\n\ntrait Tr {\n    type Args;\n    fn do_it(args: Self::Args);\n}\n\nstruct A;\nimpl Tr for A {\n    type Args = ();\n    fn do_it(_: Self::Args) {}\n}\n\nstruct B;\nimpl Tr for B {\n    type Args = <A as Tr>::Args;\n\n    fn do_it(args: Self::Args) {\n        A::do_it(args)\n    }\n}\n\nfn bad() {\n    foo({\n        //~^ unit_arg\n        1;\n    });\n    foo(foo(1));\n    //~^ unit_arg\n    foo({\n        //~^ unit_arg\n        foo(1);\n        foo(2);\n    });\n    let b = Bar;\n    b.bar({\n        //~^ unit_arg\n        1;\n    });\n    taking_multiple_units(foo(0), foo(1));\n    //~^ unit_arg\n    taking_multiple_units(foo(0), {\n        //~^ unit_arg\n        foo(1);\n        foo(2);\n    });\n    taking_multiple_units(\n        //~^ unit_arg\n        {\n            foo(0);\n            foo(1);\n        },\n        {\n            foo(2);\n            foo(3);\n        },\n    );\n    // here Some(foo(2)) isn't the top level statement expression, wrap the suggestion in a block\n    None.or(Some(foo(2)));\n    //~^ unit_arg\n    // in this case, the suggestion can be inlined, no need for a surrounding block\n    // foo(()); foo(()) instead of { foo(()); foo(()) }\n    foo(foo(()));\n    //~^ unit_arg\n}\n\nfn ok() {\n    foo(());\n    foo(1);\n    foo({ 1 });\n    foo3(\"a\", 3, vec![3]);\n    let b = Bar;\n    b.bar({ 1 });\n    b.bar(());\n    question_mark();\n    let named_unit_arg = ();\n    foo(named_unit_arg);\n    baz(());\n    B::do_it(());\n}\n\nfn question_mark() -> Result<(), ()> {\n    Ok(Ok(())?)?;\n    Ok(Ok(()))??;\n    Ok(())\n}\n\n#[allow(dead_code)]\nmod issue_2945 {\n    fn unit_fn() -> Result<(), i32> {\n        Ok(())\n    }\n\n    fn fallible() -> Result<(), i32> {\n        Ok(unit_fn()?)\n    }\n}\n\n#[allow(dead_code)]\nfn returning_expr() -> Option<()> {\n    Some(foo(1))\n    //~^ unit_arg\n}\n\nfn taking_multiple_units(a: (), b: ()) {}\n\nfn proc_macro() {\n    with_span!(span taking_multiple_units(unsafe { (); }, 'x: loop { break 'x (); }));\n}\n\nfn main() {}\n\nfn issue14857() {\n    let fn_take_unit = |_: ()| {};\n    fn some_other_fn(_: &i32) {}\n\n    macro_rules! mac {\n        (def) => {\n            Default::default()\n        };\n        (func $f:expr) => {\n            $f()\n        };\n        (nonempty_block $e:expr) => {{\n            some_other_fn(&$e);\n            $e\n        }};\n    }\n    fn_take_unit(mac!(def));\n    //~^ unit_arg\n    fn_take_unit(mac!(func Default::default));\n    //~^ unit_arg\n    fn_take_unit(mac!(nonempty_block Default::default()));\n    //~^ unit_arg\n}\n"
  },
  {
    "path": "tests/ui/unit_arg.stderr",
    "content": "error: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:63:5\n   |\nLL | /     foo({\nLL | |\nLL | |         1;\nLL | |     });\n   | |______^\n   |\n   = note: `-D clippy::unit-arg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unit_arg)]`\nhelp: remove the semicolon from the last statement in the block\n   |\nLL -         1;\nLL +         1\n   |\nhelp: or move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     {\nLL +\nLL +         1;\nLL +     };\nLL ~     foo(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:67:5\n   |\nLL |     foo(foo(1));\n   |     ^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     foo(1);\nLL ~     foo(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:69:5\n   |\nLL | /     foo({\nLL | |\nLL | |         foo(1);\nLL | |         foo(2);\nLL | |     });\n   | |______^\n   |\nhelp: remove the semicolon from the last statement in the block\n   |\nLL -         foo(2);\nLL +         foo(2)\n   |\nhelp: or move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     {\nLL +\nLL +         foo(1);\nLL +         foo(2);\nLL +     };\nLL ~     foo(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:75:5\n   |\nLL | /     b.bar({\nLL | |\nLL | |         1;\nLL | |     });\n   | |______^\n   |\nhelp: remove the semicolon from the last statement in the block\n   |\nLL -         1;\nLL +         1\n   |\nhelp: or move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     {\nLL +\nLL +         1;\nLL +     };\nLL ~     b.bar(());\n   |\n\nerror: passing unit values to a function\n  --> tests/ui/unit_arg.rs:79:5\n   |\nLL |     taking_multiple_units(foo(0), foo(1));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: move the expressions in front of the call and replace them with the unit literal `()`\n   |\nLL ~     foo(0);\nLL +     foo(1);\nLL ~     taking_multiple_units((), ());\n   |\n\nerror: passing unit values to a function\n  --> tests/ui/unit_arg.rs:81:5\n   |\nLL | /     taking_multiple_units(foo(0), {\nLL | |\nLL | |         foo(1);\nLL | |         foo(2);\nLL | |     });\n   | |______^\n   |\nhelp: remove the semicolon from the last statement in the block\n   |\nLL -         foo(2);\nLL +         foo(2)\n   |\nhelp: or move the expressions in front of the call and replace them with the unit literal `()`\n   |\nLL ~     foo(0);\nLL +     {\nLL +\nLL +         foo(1);\nLL +         foo(2);\nLL +     };\nLL ~     taking_multiple_units((), ());\n   |\n\nerror: passing unit values to a function\n  --> tests/ui/unit_arg.rs:86:5\n   |\nLL | /     taking_multiple_units(\nLL | |\nLL | |         {\nLL | |             foo(0);\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: remove the semicolon from the last statement in the block\n   |\nLL -             foo(1);\nLL +             foo(1)\n   |\nhelp: remove the semicolon from the last statement in the block\n   |\nLL -             foo(3);\nLL +             foo(3)\n   |\nhelp: or move the expressions in front of the call and replace them with the unit literal `()`\n   |\nLL ~     {\nLL +         foo(0);\nLL +         foo(1);\nLL +     };\nLL +     {\nLL +         foo(2);\nLL +         foo(3);\nLL +     };\nLL +     taking_multiple_units(\nLL +\nLL +         (),\nLL +         (),\nLL ~     );\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:98:13\n   |\nLL |     None.or(Some(foo(2)));\n   |             ^^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     None.or({\nLL +         foo(2);\nLL +         Some(())\nLL ~     });\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:102:5\n   |\nLL |     foo(foo(()));\n   |     ^^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     foo(());\nLL ~     foo(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:140:5\n   |\nLL |     Some(foo(1))\n   |     ^^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     foo(1);\nLL +     Some(())\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:168:5\n   |\nLL |     fn_take_unit(mac!(def));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:170:5\n   |\nLL |     fn_take_unit(mac!(func Default::default));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg.rs:172:5\n   |\nLL |     fn_take_unit(mac!(nonempty_block Default::default()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/unit_arg_fixable.fixed",
    "content": "#![warn(clippy::unit_arg)]\n#![allow(unused_must_use, unused_variables)]\n#![allow(clippy::no_effect, clippy::uninlined_format_args)]\n\nuse std::fmt::Debug;\n\nfn foo<T: Debug>(t: T) {\n    println!(\"{:?}\", t);\n}\n\nfn foo3<T1: Debug, T2: Debug, T3: Debug>(t1: T1, t2: T2, t3: T3) {\n    println!(\"{:?}, {:?}, {:?}\", t1, t2, t3);\n}\n\nfn bad() {\n    foo(());\n    //~^ unit_arg\n    foo3((), 2, 2);\n    //~^ unit_arg\n    foo(0);\n    taking_two_units((), ());\n    //~^ unit_arg\n    foo(0);\n    foo(1);\n    taking_three_units((), (), ());\n    //~^ unit_arg\n}\n\nfn taking_two_units(a: (), b: ()) {}\nfn taking_three_units(a: (), b: (), c: ()) {}\n\nfn main() {}\n\nfn issue14857() {\n    let fn_take_unit = |_: ()| {};\n    fn_take_unit(());\n    //~^ unit_arg\n\n    fn some_other_fn(_: &i32) {}\n\n    macro_rules! another_mac {\n        () => {\n            some_other_fn(&Default::default())\n        };\n        ($e:expr) => {\n            some_other_fn(&$e)\n        };\n    }\n\n    another_mac!();\n    fn_take_unit(());\n    //~^ unit_arg\n    another_mac!(1);\n    fn_take_unit(());\n    //~^ unit_arg\n\n    macro_rules! mac {\n        (nondef $e:expr) => {\n            $e\n        };\n        (empty_block) => {{}};\n    }\n    fn_take_unit(mac!(nondef ()));\n    //~^ unit_arg\n    mac!(empty_block);\n    fn_take_unit(());\n    //~^ unit_arg\n\n    fn def<T: Default>() -> T {\n        Default::default()\n    }\n\n    let _: () = def();\n    fn_take_unit(());\n    //~^ unit_arg\n}\n"
  },
  {
    "path": "tests/ui/unit_arg_fixable.rs",
    "content": "#![warn(clippy::unit_arg)]\n#![allow(unused_must_use, unused_variables)]\n#![allow(clippy::no_effect, clippy::uninlined_format_args)]\n\nuse std::fmt::Debug;\n\nfn foo<T: Debug>(t: T) {\n    println!(\"{:?}\", t);\n}\n\nfn foo3<T1: Debug, T2: Debug, T3: Debug>(t1: T1, t2: T2, t3: T3) {\n    println!(\"{:?}, {:?}, {:?}\", t1, t2, t3);\n}\n\nfn bad() {\n    foo({});\n    //~^ unit_arg\n    foo3({}, 2, 2);\n    //~^ unit_arg\n    taking_two_units({}, foo(0));\n    //~^ unit_arg\n    taking_three_units({}, foo(0), foo(1));\n    //~^ unit_arg\n}\n\nfn taking_two_units(a: (), b: ()) {}\nfn taking_three_units(a: (), b: (), c: ()) {}\n\nfn main() {}\n\nfn issue14857() {\n    let fn_take_unit = |_: ()| {};\n    fn_take_unit(Default::default());\n    //~^ unit_arg\n\n    fn some_other_fn(_: &i32) {}\n\n    macro_rules! another_mac {\n        () => {\n            some_other_fn(&Default::default())\n        };\n        ($e:expr) => {\n            some_other_fn(&$e)\n        };\n    }\n\n    fn_take_unit(another_mac!());\n    //~^ unit_arg\n    fn_take_unit(another_mac!(1));\n    //~^ unit_arg\n\n    macro_rules! mac {\n        (nondef $e:expr) => {\n            $e\n        };\n        (empty_block) => {{}};\n    }\n    fn_take_unit(mac!(nondef Default::default()));\n    //~^ unit_arg\n    fn_take_unit(mac!(empty_block));\n    //~^ unit_arg\n\n    fn def<T: Default>() -> T {\n        Default::default()\n    }\n\n    fn_take_unit(def());\n    //~^ unit_arg\n}\n"
  },
  {
    "path": "tests/ui/unit_arg_fixable.stderr",
    "content": "error: passing a unit value to a function\n  --> tests/ui/unit_arg_fixable.rs:16:5\n   |\nLL |     foo({});\n   |     ^^^^^^^\n   |\n   = note: `-D clippy::unit-arg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unit_arg)]`\nhelp: use a unit literal instead\n   |\nLL -     foo({});\nLL +     foo(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg_fixable.rs:18:5\n   |\nLL |     foo3({}, 2, 2);\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: use a unit literal instead\n   |\nLL -     foo3({}, 2, 2);\nLL +     foo3((), 2, 2);\n   |\n\nerror: passing unit values to a function\n  --> tests/ui/unit_arg_fixable.rs:20:5\n   |\nLL |     taking_two_units({}, foo(0));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     foo(0);\nLL ~     taking_two_units((), ());\n   |\n\nerror: passing unit values to a function\n  --> tests/ui/unit_arg_fixable.rs:22:5\n   |\nLL |     taking_three_units({}, foo(0), foo(1));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: move the expressions in front of the call and replace them with the unit literal `()`\n   |\nLL ~     foo(0);\nLL +     foo(1);\nLL ~     taking_three_units((), (), ());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg_fixable.rs:33:5\n   |\nLL |     fn_take_unit(Default::default());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a unit literal instead\n   |\nLL -     fn_take_unit(Default::default());\nLL +     fn_take_unit(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg_fixable.rs:47:5\n   |\nLL |     fn_take_unit(another_mac!());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     another_mac!();\nLL ~     fn_take_unit(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg_fixable.rs:49:5\n   |\nLL |     fn_take_unit(another_mac!(1));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     another_mac!(1);\nLL ~     fn_take_unit(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg_fixable.rs:58:5\n   |\nLL |     fn_take_unit(mac!(nondef Default::default()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a unit literal instead\n   |\nLL -     fn_take_unit(mac!(nondef Default::default()));\nLL +     fn_take_unit(mac!(nondef ()));\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg_fixable.rs:60:5\n   |\nLL |     fn_take_unit(mac!(empty_block));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     mac!(empty_block);\nLL ~     fn_take_unit(());\n   |\n\nerror: passing a unit value to a function\n  --> tests/ui/unit_arg_fixable.rs:67:5\n   |\nLL |     fn_take_unit(def());\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: move the expression in front of the call and replace it with the unit literal `()`\n   |\nLL ~     let _: () = def();\nLL ~     fn_take_unit(());\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/unit_cmp.rs",
    "content": "#![warn(clippy::unit_cmp)]\n#![allow(\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::derive_partial_eq_without_eq,\n    clippy::needless_ifs\n)]\n\n#[derive(PartialEq)]\npub struct ContainsUnit(()); // should be fine\n\nfn main() {\n    // this is fine\n    if true == false {}\n\n    // this warns\n    if {\n        //~^ unit_cmp\n\n        true;\n    } == {\n        false;\n    } {}\n\n    if {\n        //~^ unit_cmp\n\n        true;\n    } > {\n        false;\n    } {}\n\n    assert_eq!(\n        //~^ unit_cmp\n        {\n            true;\n        },\n        {\n            false;\n        }\n    );\n    debug_assert_eq!(\n        //~^ unit_cmp\n        {\n            true;\n        },\n        {\n            false;\n        }\n    );\n\n    assert_ne!(\n        //~^ unit_cmp\n        {\n            true;\n        },\n        {\n            false;\n        }\n    );\n    debug_assert_ne!(\n        //~^ unit_cmp\n        {\n            true;\n        },\n        {\n            false;\n        }\n    );\n}\n\nfn issue15559() {\n    fn foo() {}\n    assert_eq!(\n        //~^ unit_cmp\n        {\n            1;\n        },\n        foo()\n    );\n    assert_eq!(foo(), foo());\n    //~^ unit_cmp\n\n    // don't lint on explicitly written unit expr\n    assert_eq!(foo(), ());\n    assert_ne!((), ContainsUnit(()).0);\n}\n"
  },
  {
    "path": "tests/ui/unit_cmp.stderr",
    "content": "error: ==-comparison of unit values detected. This will always be true\n  --> tests/ui/unit_cmp.rs:17:8\n   |\nLL |       if {\n   |  ________^\nLL | |\nLL | |\nLL | |         true;\nLL | |     } == {\nLL | |         false;\nLL | |     } {}\n   | |_____^\n   |\n   = note: `-D clippy::unit-cmp` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unit_cmp)]`\n\nerror: >-comparison of unit values detected. This will always be false\n  --> tests/ui/unit_cmp.rs:25:8\n   |\nLL |       if {\n   |  ________^\nLL | |\nLL | |\nLL | |         true;\nLL | |     } > {\nLL | |         false;\nLL | |     } {}\n   | |_____^\n\nerror: `assert_eq` of unit values detected. This will always succeed\n  --> tests/ui/unit_cmp.rs:33:5\n   |\nLL | /     assert_eq!(\nLL | |\nLL | |         {\nLL | |             true;\n...  |\nLL | |     );\n   | |_____^\n\nerror: `debug_assert_eq` of unit values detected. This will always succeed\n  --> tests/ui/unit_cmp.rs:42:5\n   |\nLL | /     debug_assert_eq!(\nLL | |\nLL | |         {\nLL | |             true;\n...  |\nLL | |     );\n   | |_____^\n\nerror: `assert_ne` of unit values detected. This will always fail\n  --> tests/ui/unit_cmp.rs:52:5\n   |\nLL | /     assert_ne!(\nLL | |\nLL | |         {\nLL | |             true;\n...  |\nLL | |     );\n   | |_____^\n\nerror: `debug_assert_ne` of unit values detected. This will always fail\n  --> tests/ui/unit_cmp.rs:61:5\n   |\nLL | /     debug_assert_ne!(\nLL | |\nLL | |         {\nLL | |             true;\n...  |\nLL | |     );\n   | |_____^\n\nerror: `assert_eq` of unit values detected. This will always succeed\n  --> tests/ui/unit_cmp.rs:74:5\n   |\nLL | /     assert_eq!(\nLL | |\nLL | |         {\nLL | |             1;\nLL | |         },\nLL | |         foo()\nLL | |     );\n   | |_____^\n\nerror: `assert_eq` of unit values detected. This will always succeed\n  --> tests/ui/unit_cmp.rs:81:5\n   |\nLL |     assert_eq!(foo(), foo());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/unit_hash.fixed",
    "content": "#![warn(clippy::unit_hash)]\n#![allow(clippy::let_unit_value)]\n\nuse std::collections::hash_map::DefaultHasher;\nuse std::hash::Hash;\n\nenum Foo {\n    Empty,\n    WithValue(u8),\n}\n\nfn do_nothing() {}\n\nfn main() {\n    let mut state = DefaultHasher::new();\n    let my_enum = Foo::Empty;\n\n    match my_enum {\n        Foo::Empty => 0_u8.hash(&mut state),\n        //~^ unit_hash\n        Foo::WithValue(x) => x.hash(&mut state),\n    }\n\n    let res = ();\n    0_u8.hash(&mut state);\n    //~^ unit_hash\n\n    #[allow(clippy::unit_arg)]\n    0_u8.hash(&mut state);\n    //~^ unit_hash\n}\n"
  },
  {
    "path": "tests/ui/unit_hash.rs",
    "content": "#![warn(clippy::unit_hash)]\n#![allow(clippy::let_unit_value)]\n\nuse std::collections::hash_map::DefaultHasher;\nuse std::hash::Hash;\n\nenum Foo {\n    Empty,\n    WithValue(u8),\n}\n\nfn do_nothing() {}\n\nfn main() {\n    let mut state = DefaultHasher::new();\n    let my_enum = Foo::Empty;\n\n    match my_enum {\n        Foo::Empty => ().hash(&mut state),\n        //~^ unit_hash\n        Foo::WithValue(x) => x.hash(&mut state),\n    }\n\n    let res = ();\n    res.hash(&mut state);\n    //~^ unit_hash\n\n    #[allow(clippy::unit_arg)]\n    do_nothing().hash(&mut state);\n    //~^ unit_hash\n}\n"
  },
  {
    "path": "tests/ui/unit_hash.stderr",
    "content": "error: this call to `hash` on the unit type will do nothing\n  --> tests/ui/unit_hash.rs:19:23\n   |\nLL |         Foo::Empty => ().hash(&mut state),\n   |                       ^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`\n   |\n   = note: the implementation of `Hash` for `()` is a no-op\n   = note: `-D clippy::unit-hash` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unit_hash)]`\n\nerror: this call to `hash` on the unit type will do nothing\n  --> tests/ui/unit_hash.rs:25:5\n   |\nLL |     res.hash(&mut state);\n   |     ^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`\n   |\n   = note: the implementation of `Hash` for `()` is a no-op\n\nerror: this call to `hash` on the unit type will do nothing\n  --> tests/ui/unit_hash.rs:29:5\n   |\nLL |     do_nothing().hash(&mut state);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`\n   |\n   = note: the implementation of `Hash` for `()` is a no-op\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/unit_return_expecting_ord.rs",
    "content": "#![warn(clippy::unit_return_expecting_ord)]\n#![allow(clippy::needless_return)]\n#![allow(clippy::unused_unit)]\n#![allow(clippy::useless_vec)]\n\nstruct Struct {\n    field: isize,\n}\n\nfn double(i: isize) -> isize {\n    i * 2\n}\n\nfn unit(_i: isize) {}\n\nfn main() {\n    let mut structs = vec![Struct { field: 2 }, Struct { field: 1 }];\n    structs.sort_by_key(|s| {\n        //~^ unit_return_expecting_ord\n\n        double(s.field);\n    });\n    structs.sort_by_key(|s| double(s.field));\n    structs.is_sorted_by_key(|s| {\n        //~^ unit_return_expecting_ord\n\n        double(s.field);\n    });\n    structs.is_sorted_by_key(|s| {\n        //~^ unit_return_expecting_ord\n\n        if s.field > 0 {\n            ()\n        } else {\n            return ();\n        }\n    });\n    structs.sort_by_key(|s| {\n        return double(s.field);\n    });\n    structs.sort_by_key(|s| unit(s.field));\n    //~^ unit_return_expecting_ord\n}\n"
  },
  {
    "path": "tests/ui/unit_return_expecting_ord.stderr",
    "content": "error: this closure returns the unit type which also implements Ord\n  --> tests/ui/unit_return_expecting_ord.rs:18:25\n   |\nLL |     structs.sort_by_key(|s| {\n   |                         ^^^\n   |\nhelp: probably caused by this trailing semicolon\n  --> tests/ui/unit_return_expecting_ord.rs:21:24\n   |\nLL |         double(s.field);\n   |                        ^\n   = note: `-D clippy::unit-return-expecting-ord` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unit_return_expecting_ord)]`\n\nerror: this closure returns the unit type which also implements PartialOrd\n  --> tests/ui/unit_return_expecting_ord.rs:24:30\n   |\nLL |     structs.is_sorted_by_key(|s| {\n   |                              ^^^\n   |\nhelp: probably caused by this trailing semicolon\n  --> tests/ui/unit_return_expecting_ord.rs:27:24\n   |\nLL |         double(s.field);\n   |                        ^\n\nerror: this closure returns the unit type which also implements PartialOrd\n  --> tests/ui/unit_return_expecting_ord.rs:29:30\n   |\nLL |     structs.is_sorted_by_key(|s| {\n   |                              ^^^\n\nerror: this closure returns the unit type which also implements Ord\n  --> tests/ui/unit_return_expecting_ord.rs:41:25\n   |\nLL |     structs.sort_by_key(|s| unit(s.field));\n   |                         ^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/unknown_attribute.rs",
    "content": "//@compile-flags: -Zdeduplicate-diagnostics=yes\n\n#[clippy::unknown]\n//~^ ERROR: usage of unknown attribute\n#[clippy::cognitive_complexity = \"1\"]\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unknown_attribute.stderr",
    "content": "error: usage of unknown attribute\n  --> tests/ui/unknown_attribute.rs:3:3\n   |\nLL | #[clippy::unknown]\n   |   ^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/unknown_clippy_lints.fixed",
    "content": "#![warn(clippy::pedantic)]\n// Should suggest lowercase\n#![allow(clippy::all)]\n//~^ ERROR: unknown lint\n#![warn(clippy::cmp_owned)]\n//~^ ERROR: unknown lint\n\n// Should suggest similar clippy lint name\n#[warn(clippy::if_not_else)]\n//~^ ERROR: unknown lint\n#[warn(clippy::unnecessary_cast)]\n//~^ ERROR: unknown lint\n#[warn(clippy::useless_transmute)]\n//~^ ERROR: unknown lint\n// Should suggest rustc lint name(`dead_code`)\n#[warn(dead_code)]\n//~^ ERROR: unknown lint\n// Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`)\n#[warn(clippy::unused_self)]\n//~^ ERROR: unknown lint\n// Shouldn't suggest renamed clippy lint name(`const_static_lifetime`)\n#[warn(clippy::redundant_static_lifetimes)]\n//~^ ERROR: unknown lint\n// issue #118183, should report `missing_docs` from rustc lint\n#[warn(missing_docs)]\n//~^ ERROR: unknown lint\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unknown_clippy_lints.rs",
    "content": "#![warn(clippy::pedantic)]\n// Should suggest lowercase\n#![allow(clippy::All)]\n//~^ ERROR: unknown lint\n#![warn(clippy::CMP_OWNED)]\n//~^ ERROR: unknown lint\n\n// Should suggest similar clippy lint name\n#[warn(clippy::if_not_els)]\n//~^ ERROR: unknown lint\n#[warn(clippy::UNNecsaRy_cAst)]\n//~^ ERROR: unknown lint\n#[warn(clippy::useles_transute)]\n//~^ ERROR: unknown lint\n// Should suggest rustc lint name(`dead_code`)\n#[warn(clippy::dead_cod)]\n//~^ ERROR: unknown lint\n// Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`)\n#[warn(clippy::unused_colle)]\n//~^ ERROR: unknown lint\n// Shouldn't suggest renamed clippy lint name(`const_static_lifetime`)\n#[warn(clippy::const_static_lifetim)]\n//~^ ERROR: unknown lint\n// issue #118183, should report `missing_docs` from rustc lint\n#[warn(clippy::missing_docs)]\n//~^ ERROR: unknown lint\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unknown_clippy_lints.stderr",
    "content": "error: unknown lint: `clippy::All`\n  --> tests/ui/unknown_clippy_lints.rs:3:10\n   |\nLL | #![allow(clippy::All)]\n   |          ^^^^^^^^^^^ help: did you mean: `clippy::all`\n   |\n   = note: `-D unknown-lints` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(unknown_lints)]`\n\nerror: unknown lint: `clippy::CMP_OWNED`\n  --> tests/ui/unknown_clippy_lints.rs:5:9\n   |\nLL | #![warn(clippy::CMP_OWNED)]\n   |         ^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::cmp_owned`\n\nerror: unknown lint: `clippy::if_not_els`\n  --> tests/ui/unknown_clippy_lints.rs:9:8\n   |\nLL | #[warn(clippy::if_not_els)]\n   |        ^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::if_not_else`\n\nerror: unknown lint: `clippy::UNNecsaRy_cAst`\n  --> tests/ui/unknown_clippy_lints.rs:11:8\n   |\nLL | #[warn(clippy::UNNecsaRy_cAst)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::unnecessary_cast`\n\nerror: unknown lint: `clippy::useles_transute`\n  --> tests/ui/unknown_clippy_lints.rs:13:8\n   |\nLL | #[warn(clippy::useles_transute)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::useless_transmute`\n\nerror: unknown lint: `clippy::dead_cod`\n  --> tests/ui/unknown_clippy_lints.rs:16:8\n   |\nLL | #[warn(clippy::dead_cod)]\n   |        ^^^^^^^^^^^^^^^^\n   |\nhelp: a lint with a similar name exists in `rustc` lints\n   |\nLL - #[warn(clippy::dead_cod)]\nLL + #[warn(dead_code)]\n   |\n\nerror: unknown lint: `clippy::unused_colle`\n  --> tests/ui/unknown_clippy_lints.rs:19:8\n   |\nLL | #[warn(clippy::unused_colle)]\n   |        ^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::unused_self`\n\nerror: unknown lint: `clippy::const_static_lifetim`\n  --> tests/ui/unknown_clippy_lints.rs:22:8\n   |\nLL | #[warn(clippy::const_static_lifetim)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `clippy::redundant_static_lifetimes`\n\nerror: unknown lint: `clippy::missing_docs`\n  --> tests/ui/unknown_clippy_lints.rs:25:8\n   |\nLL | #[warn(clippy::missing_docs)]\n   |        ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: a lint with a similar name exists in `rustc` lints\n   |\nLL - #[warn(clippy::missing_docs)]\nLL + #[warn(missing_docs)]\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_box_returns.rs",
    "content": "#![warn(clippy::unnecessary_box_returns)]\n//@no-rustfix\ntrait Bar {\n    // lint\n    fn baz(&self) -> Box<usize>;\n    //~^ unnecessary_box_returns\n}\n\npub struct Foo {}\n\nimpl Bar for Foo {\n    // don't lint: this is a problem with the trait, not the implementation\n    fn baz(&self) -> Box<usize> {\n        Box::new(42)\n    }\n}\n\nimpl Foo {\n    fn baz(&self) -> Box<usize> {\n        //~^ unnecessary_box_returns\n\n        // lint\n        Box::new(13)\n    }\n}\n\n// lint\nfn bxed_usize() -> Box<usize> {\n    //~^ unnecessary_box_returns\n\n    Box::new(5)\n}\n\n// lint\nfn _bxed_foo() -> Box<Foo> {\n    //~^ unnecessary_box_returns\n\n    Box::new(Foo {})\n}\n\n// don't lint: this is exported\npub fn bxed_foo() -> Box<Foo> {\n    Box::new(Foo {})\n}\n\n// don't lint: str is unsized\nfn bxed_str() -> Box<str> {\n    \"Hello, world!\".to_string().into_boxed_str()\n}\n\n// don't lint: function contains the word, \"box\"\nfn boxed_usize() -> Box<usize> {\n    Box::new(7)\n}\n\n// don't lint: this has an unspecified return type\nfn default() {}\n\n// don't lint: this doesn't return a Box\nfn string() -> String {\n    String::from(\"Hello, world\")\n}\n\nstruct Huge([u8; 500]);\nstruct HasHuge(Box<Huge>);\n\nimpl HasHuge {\n    // don't lint: The size of `Huge` is very large\n    fn into_huge(self) -> Box<Huge> {\n        self.0\n    }\n}\n\nfn main() {\n    // don't lint: this is a closure\n    let a = || -> Box<usize> { Box::new(5) };\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_box_returns.stderr",
    "content": "error: boxed return of the sized type `usize`\n  --> tests/ui/unnecessary_box_returns.rs:5:22\n   |\nLL |     fn baz(&self) -> Box<usize>;\n   |                      ^^^^^^^^^^ help: try: `usize`\n   |\n   = help: changing this also requires a change to the return expressions in this function\n   = note: `-D clippy::unnecessary-box-returns` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_box_returns)]`\n\nerror: boxed return of the sized type `usize`\n  --> tests/ui/unnecessary_box_returns.rs:19:22\n   |\nLL |     fn baz(&self) -> Box<usize> {\n   |                      ^^^^^^^^^^ help: try: `usize`\n   |\n   = help: changing this also requires a change to the return expressions in this function\n\nerror: boxed return of the sized type `usize`\n  --> tests/ui/unnecessary_box_returns.rs:28:20\n   |\nLL | fn bxed_usize() -> Box<usize> {\n   |                    ^^^^^^^^^^ help: try: `usize`\n   |\n   = help: changing this also requires a change to the return expressions in this function\n\nerror: boxed return of the sized type `Foo`\n  --> tests/ui/unnecessary_box_returns.rs:35:19\n   |\nLL | fn _bxed_foo() -> Box<Foo> {\n   |                   ^^^^^^^^ help: try: `Foo`\n   |\n   = help: changing this also requires a change to the return expressions in this function\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_cast.fixed",
    "content": "//@aux-build:extern_fake_libc.rs\n#![warn(clippy::unnecessary_cast)]\n#![allow(\n    clippy::borrow_as_ptr,\n    clippy::multiple_bound_locations,\n    clippy::no_effect,\n    clippy::nonstandard_macro_braces,\n    clippy::unnecessary_operation,\n    nonstandard_style,\n    unused\n)]\n\nextern crate extern_fake_libc;\n\ntype PtrConstU8 = *const u8;\ntype PtrMutU8 = *mut u8;\n\nfn owo<T>(ptr: *const T) -> *const T {\n    ptr\n    //~^ unnecessary_cast\n}\n\nfn uwu<T, U>(ptr: *const T) -> *const U {\n    ptr as *const U\n}\n\nmod fake_libc {\n    type pid_t = i32;\n    pub unsafe fn getpid() -> pid_t {\n        pid_t::from(0)\n    }\n    // Make sure a where clause does not break it\n    pub fn getpid_SAFE_TRUTH<T: Clone>(t: &T) -> pid_t\n    where\n        T: Clone,\n    {\n        t;\n        unsafe { getpid() }\n    }\n}\n\nfn aaa() -> ::std::primitive::u32 {\n    0\n}\n\nuse std::primitive::u32 as UnsignedThirtyTwoBitInteger;\n\nfn bbb() -> UnsignedThirtyTwoBitInteger {\n    0\n}\n\n#[rustfmt::skip]\nfn main() {\n    // Test cast_unnecessary\n    1_i32;\n    //~^ unnecessary_cast\n    1_f32;\n    //~^ unnecessary_cast\n    false;\n    //~^ unnecessary_cast\n    &1i32 as &i32;\n\n    -1_i32;\n    //~^ unnecessary_cast\n    - 1_i32;\n    //~^ unnecessary_cast\n    -1_f32;\n    //~^ unnecessary_cast\n    1_i32;\n    //~^ unnecessary_cast\n    1_f32;\n    //~^ unnecessary_cast\n\n    let _: *mut u8 = [1u8, 2].as_ptr() as *mut u8;\n    //~^ unnecessary_cast\n\n    [1u8, 2].as_ptr();\n    //~^ unnecessary_cast\n    [1u8, 2].as_ptr() as *mut u8;\n    [1u8, 2].as_mut_ptr();\n    //~^ unnecessary_cast\n    [1u8, 2].as_mut_ptr() as *const u8;\n    [1u8, 2].as_ptr() as PtrConstU8;\n    [1u8, 2].as_ptr() as PtrMutU8;\n    [1u8, 2].as_mut_ptr() as PtrMutU8;\n    [1u8, 2].as_mut_ptr() as PtrConstU8;\n    let _: *const u8 = [1u8, 2].as_ptr() as _;\n    let _: *mut u8 = [1u8, 2].as_mut_ptr() as _;\n    let _: *const u8 = [1u8, 2].as_ptr() as *const _;\n    let _: *mut u8 = [1u8, 2].as_mut_ptr() as *mut _;\n\n    owo::<u32>([1u32].as_ptr());\n    //~^ unnecessary_cast\n    uwu::<u32, u8>([1u32].as_ptr());\n    //~^ unnecessary_cast\n    // this will not lint in the function body even though they have the same type, instead here\n    uwu::<u32, u32>([1u32].as_ptr());\n    //~^ unnecessary_cast\n\n    // macro version\n    macro_rules! foo {\n        ($a:ident, $b:ident) => {\n            #[allow(unused)]\n            pub fn $a() -> $b {\n                1 as $b\n            }\n        };\n    }\n    foo!(a, i32);\n    foo!(b, f32);\n    foo!(c, f64);\n\n    // do not lint cast from cfg-dependant type\n    let x = 0 as std::ffi::c_ulong;\n    let y = x as u64;\n    let x: std::ffi::c_ulong = 0;\n    let y = x as u64;\n\n    // do not lint cast to cfg-dependant type\n    let x = 1 as std::os::raw::c_char;\n    let y = x as u64;\n\n    // do not lint cast to alias type\n    1 as I32Alias;\n    &1 as &I32Alias;\n    // or from\n    let x: I32Alias = 1;\n    let y = x as u64;\n    fake_libc::getpid_SAFE_TRUTH(&0u32) as i32;\n    extern_fake_libc::getpid_SAFE_TRUTH() as i32;\n    let pid = unsafe { fake_libc::getpid() };\n    pid as i32;\n    aaa();\n    //~^ unnecessary_cast\n    let x = aaa();\n    x;\n    //~^ unnecessary_cast\n    bbb();\n    //~^ unnecessary_cast\n    let x = bbb();\n    x;\n    //~^ unnecessary_cast\n\n    let i8_ptr: *const i8 = &1;\n    let u8_ptr: *const u8 = &1;\n\n    // cfg dependant pointees\n    i8_ptr as *const std::os::raw::c_char;\n    u8_ptr as *const std::os::raw::c_char;\n\n    // type aliased pointees\n    i8_ptr as *const std::ffi::c_char;\n    u8_ptr as *const std::ffi::c_char;\n\n    // issue #9960\n    macro_rules! bind_var {\n        ($id:ident, $e:expr) => {{\n            let $id = 0usize;\n            let _ = $e != 0usize;\n            let $id = 0isize;\n            let _ = $e != 0usize;\n        }}\n    }\n    bind_var!(x, (x as usize) + 1);\n}\n\ntype I32Alias = i32;\n\nmod fixable {\n    #![allow(dead_code)]\n\n    fn main() {\n        // casting integer literal to float is unnecessary\n        100_f32;\n        //~^ unnecessary_cast\n        100_f64;\n        //~^ unnecessary_cast\n        100_f64;\n        //~^ unnecessary_cast\n        let _ = -100_f32;\n        //~^ unnecessary_cast\n        let _ = -100_f64;\n        //~^ unnecessary_cast\n        let _ = -100_f64;\n        //~^ unnecessary_cast\n        100_f32;\n        //~^ unnecessary_cast\n        100_f64;\n        //~^ unnecessary_cast\n        // Should not trigger\n        #[rustfmt::skip]\n        let v = vec!(1);\n        &v as &[i32];\n        0x10 as f32;\n        0o10 as f32;\n        0b10 as f32;\n        0x11 as f64;\n        0o11 as f64;\n        0b11 as f64;\n\n        1_u32;\n        //~^ unnecessary_cast\n        0x10_i32;\n        //~^ unnecessary_cast\n        0b10_usize;\n        //~^ unnecessary_cast\n        0o73_u16;\n        //~^ unnecessary_cast\n        1_000_000_000_u32;\n        //~^ unnecessary_cast\n\n        1.0_f64;\n        //~^ unnecessary_cast\n        0.5_f32;\n        //~^ unnecessary_cast\n\n        1.0 as u16;\n\n        let _ = -1_i32;\n        //~^ unnecessary_cast\n        let _ = -1.0_f32;\n        //~^ unnecessary_cast\n\n        let _ = 1 as I32Alias;\n        let _ = &1 as &I32Alias;\n\n        let x = 1i32;\n        let _ = &{ x };\n        //~^ unnecessary_cast\n    }\n\n    type I32Alias = i32;\n\n    fn issue_9380() {\n        let _: i32 = -1_i32;\n        //~^ unnecessary_cast\n        let _: f32 = -(1) as f32;\n        let _: i64 = -1_i64;\n        //~^ unnecessary_cast\n        let _: i64 = -(1.0) as i64;\n\n        let _ = -(1 + 1) as i64;\n    }\n\n    fn issue_9563() {\n        let _: f64 = (-8.0_f64).exp();\n        //~^ unnecessary_cast\n        #[allow(ambiguous_negative_literals)]\n        let _: f64 = -8.0_f64.exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior\n        //\n        //~^^ unnecessary_cast\n    }\n\n    fn issue_9562_non_literal() {\n        fn foo() -> f32 {\n            0.\n        }\n\n        let _num = foo();\n        //~^ unnecessary_cast\n    }\n\n    fn issue_9603() {\n        let _: f32 = -0x400 as f32;\n    }\n\n    // Issue #11968: The suggestion for this lint removes the parentheses and leave the code as\n    // `*x.pow(2)` which tries to dereference the return value rather than `x`.\n    fn issue_11968(x: &usize) -> usize {\n        (*x).pow(2)\n        //~^ unnecessary_cast\n    }\n\n    #[allow(clippy::cast_lossless)]\n    fn issue_14640() {\n        let x = 5usize;\n        let vec: Vec<u64> = vec![1, 2, 3, 4, 5];\n        assert_eq!(vec.len(), x);\n        //~^ unnecessary_cast\n\n        let _ = (5i32 as i64).abs();\n        //~^ unnecessary_cast\n\n        let _ = 5i32 as i64;\n        //~^ unnecessary_cast\n    }\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_cast.rs",
    "content": "//@aux-build:extern_fake_libc.rs\n#![warn(clippy::unnecessary_cast)]\n#![allow(\n    clippy::borrow_as_ptr,\n    clippy::multiple_bound_locations,\n    clippy::no_effect,\n    clippy::nonstandard_macro_braces,\n    clippy::unnecessary_operation,\n    nonstandard_style,\n    unused\n)]\n\nextern crate extern_fake_libc;\n\ntype PtrConstU8 = *const u8;\ntype PtrMutU8 = *mut u8;\n\nfn owo<T>(ptr: *const T) -> *const T {\n    ptr as *const T\n    //~^ unnecessary_cast\n}\n\nfn uwu<T, U>(ptr: *const T) -> *const U {\n    ptr as *const U\n}\n\nmod fake_libc {\n    type pid_t = i32;\n    pub unsafe fn getpid() -> pid_t {\n        pid_t::from(0)\n    }\n    // Make sure a where clause does not break it\n    pub fn getpid_SAFE_TRUTH<T: Clone>(t: &T) -> pid_t\n    where\n        T: Clone,\n    {\n        t;\n        unsafe { getpid() }\n    }\n}\n\nfn aaa() -> ::std::primitive::u32 {\n    0\n}\n\nuse std::primitive::u32 as UnsignedThirtyTwoBitInteger;\n\nfn bbb() -> UnsignedThirtyTwoBitInteger {\n    0\n}\n\n#[rustfmt::skip]\nfn main() {\n    // Test cast_unnecessary\n    1i32 as i32;\n    //~^ unnecessary_cast\n    1f32 as f32;\n    //~^ unnecessary_cast\n    false as bool;\n    //~^ unnecessary_cast\n    &1i32 as &i32;\n\n    -1_i32 as i32;\n    //~^ unnecessary_cast\n    - 1_i32 as i32;\n    //~^ unnecessary_cast\n    -1f32 as f32;\n    //~^ unnecessary_cast\n    1_i32 as i32;\n    //~^ unnecessary_cast\n    1_f32 as f32;\n    //~^ unnecessary_cast\n\n    let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8;\n    //~^ unnecessary_cast\n\n    [1u8, 2].as_ptr() as *const u8;\n    //~^ unnecessary_cast\n    [1u8, 2].as_ptr() as *mut u8;\n    [1u8, 2].as_mut_ptr() as *mut u8;\n    //~^ unnecessary_cast\n    [1u8, 2].as_mut_ptr() as *const u8;\n    [1u8, 2].as_ptr() as PtrConstU8;\n    [1u8, 2].as_ptr() as PtrMutU8;\n    [1u8, 2].as_mut_ptr() as PtrMutU8;\n    [1u8, 2].as_mut_ptr() as PtrConstU8;\n    let _: *const u8 = [1u8, 2].as_ptr() as _;\n    let _: *mut u8 = [1u8, 2].as_mut_ptr() as _;\n    let _: *const u8 = [1u8, 2].as_ptr() as *const _;\n    let _: *mut u8 = [1u8, 2].as_mut_ptr() as *mut _;\n\n    owo::<u32>([1u32].as_ptr()) as *const u32;\n    //~^ unnecessary_cast\n    uwu::<u32, u8>([1u32].as_ptr()) as *const u8;\n    //~^ unnecessary_cast\n    // this will not lint in the function body even though they have the same type, instead here\n    uwu::<u32, u32>([1u32].as_ptr()) as *const u32;\n    //~^ unnecessary_cast\n\n    // macro version\n    macro_rules! foo {\n        ($a:ident, $b:ident) => {\n            #[allow(unused)]\n            pub fn $a() -> $b {\n                1 as $b\n            }\n        };\n    }\n    foo!(a, i32);\n    foo!(b, f32);\n    foo!(c, f64);\n\n    // do not lint cast from cfg-dependant type\n    let x = 0 as std::ffi::c_ulong;\n    let y = x as u64;\n    let x: std::ffi::c_ulong = 0;\n    let y = x as u64;\n\n    // do not lint cast to cfg-dependant type\n    let x = 1 as std::os::raw::c_char;\n    let y = x as u64;\n\n    // do not lint cast to alias type\n    1 as I32Alias;\n    &1 as &I32Alias;\n    // or from\n    let x: I32Alias = 1;\n    let y = x as u64;\n    fake_libc::getpid_SAFE_TRUTH(&0u32) as i32;\n    extern_fake_libc::getpid_SAFE_TRUTH() as i32;\n    let pid = unsafe { fake_libc::getpid() };\n    pid as i32;\n    aaa() as u32;\n    //~^ unnecessary_cast\n    let x = aaa();\n    x as u32;\n    //~^ unnecessary_cast\n    bbb() as u32;\n    //~^ unnecessary_cast\n    let x = bbb();\n    x as u32;\n    //~^ unnecessary_cast\n\n    let i8_ptr: *const i8 = &1;\n    let u8_ptr: *const u8 = &1;\n\n    // cfg dependant pointees\n    i8_ptr as *const std::os::raw::c_char;\n    u8_ptr as *const std::os::raw::c_char;\n\n    // type aliased pointees\n    i8_ptr as *const std::ffi::c_char;\n    u8_ptr as *const std::ffi::c_char;\n\n    // issue #9960\n    macro_rules! bind_var {\n        ($id:ident, $e:expr) => {{\n            let $id = 0usize;\n            let _ = $e != 0usize;\n            let $id = 0isize;\n            let _ = $e != 0usize;\n        }}\n    }\n    bind_var!(x, (x as usize) + 1);\n}\n\ntype I32Alias = i32;\n\nmod fixable {\n    #![allow(dead_code)]\n\n    fn main() {\n        // casting integer literal to float is unnecessary\n        100 as f32;\n        //~^ unnecessary_cast\n        100 as f64;\n        //~^ unnecessary_cast\n        100_i32 as f64;\n        //~^ unnecessary_cast\n        let _ = -100 as f32;\n        //~^ unnecessary_cast\n        let _ = -100 as f64;\n        //~^ unnecessary_cast\n        let _ = -100_i32 as f64;\n        //~^ unnecessary_cast\n        100. as f32;\n        //~^ unnecessary_cast\n        100. as f64;\n        //~^ unnecessary_cast\n        // Should not trigger\n        #[rustfmt::skip]\n        let v = vec!(1);\n        &v as &[i32];\n        0x10 as f32;\n        0o10 as f32;\n        0b10 as f32;\n        0x11 as f64;\n        0o11 as f64;\n        0b11 as f64;\n\n        1 as u32;\n        //~^ unnecessary_cast\n        0x10 as i32;\n        //~^ unnecessary_cast\n        0b10 as usize;\n        //~^ unnecessary_cast\n        0o73 as u16;\n        //~^ unnecessary_cast\n        1_000_000_000 as u32;\n        //~^ unnecessary_cast\n\n        1.0 as f64;\n        //~^ unnecessary_cast\n        0.5 as f32;\n        //~^ unnecessary_cast\n\n        1.0 as u16;\n\n        let _ = -1 as i32;\n        //~^ unnecessary_cast\n        let _ = -1.0 as f32;\n        //~^ unnecessary_cast\n\n        let _ = 1 as I32Alias;\n        let _ = &1 as &I32Alias;\n\n        let x = 1i32;\n        let _ = &(x as i32);\n        //~^ unnecessary_cast\n    }\n\n    type I32Alias = i32;\n\n    fn issue_9380() {\n        let _: i32 = -(1) as i32;\n        //~^ unnecessary_cast\n        let _: f32 = -(1) as f32;\n        let _: i64 = -(1) as i64;\n        //~^ unnecessary_cast\n        let _: i64 = -(1.0) as i64;\n\n        let _ = -(1 + 1) as i64;\n    }\n\n    fn issue_9563() {\n        let _: f64 = (-8.0 as f64).exp();\n        //~^ unnecessary_cast\n        #[allow(ambiguous_negative_literals)]\n        let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior\n        //\n        //~^^ unnecessary_cast\n    }\n\n    fn issue_9562_non_literal() {\n        fn foo() -> f32 {\n            0.\n        }\n\n        let _num = foo() as f32;\n        //~^ unnecessary_cast\n    }\n\n    fn issue_9603() {\n        let _: f32 = -0x400 as f32;\n    }\n\n    // Issue #11968: The suggestion for this lint removes the parentheses and leave the code as\n    // `*x.pow(2)` which tries to dereference the return value rather than `x`.\n    fn issue_11968(x: &usize) -> usize {\n        (*x as usize).pow(2)\n        //~^ unnecessary_cast\n    }\n\n    #[allow(clippy::cast_lossless)]\n    fn issue_14640() {\n        let x = 5usize;\n        let vec: Vec<u64> = vec![1, 2, 3, 4, 5];\n        assert_eq!(vec.len(), x as usize);\n        //~^ unnecessary_cast\n\n        let _ = (5i32 as i64 as i64).abs();\n        //~^ unnecessary_cast\n\n        let _ = 5i32 as i64 as i64;\n        //~^ unnecessary_cast\n    }\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_cast.stderr",
    "content": "error: casting raw pointers to the same type and constness is unnecessary (`*const T` -> `*const T`)\n  --> tests/ui/unnecessary_cast.rs:19:5\n   |\nLL |     ptr as *const T\n   |     ^^^^^^^^^^^^^^^ help: try: `ptr`\n   |\n   = note: `-D clippy::unnecessary-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]`\n\nerror: casting integer literal to `i32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:55:5\n   |\nLL |     1i32 as i32;\n   |     ^^^^^^^^^^^ help: try: `1_i32`\n\nerror: casting float literal to `f32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:57:5\n   |\nLL |     1f32 as f32;\n   |     ^^^^^^^^^^^ help: try: `1_f32`\n\nerror: casting to the same type is unnecessary (`bool` -> `bool`)\n  --> tests/ui/unnecessary_cast.rs:59:5\n   |\nLL |     false as bool;\n   |     ^^^^^^^^^^^^^ help: try: `false`\n\nerror: casting integer literal to `i32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:63:5\n   |\nLL |     -1_i32 as i32;\n   |     ^^^^^^^^^^^^^ help: try: `-1_i32`\n\nerror: casting integer literal to `i32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:65:5\n   |\nLL |     - 1_i32 as i32;\n   |     ^^^^^^^^^^^^^^ help: try: `- 1_i32`\n\nerror: casting float literal to `f32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:67:5\n   |\nLL |     -1f32 as f32;\n   |     ^^^^^^^^^^^^ help: try: `-1_f32`\n\nerror: casting integer literal to `i32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:69:5\n   |\nLL |     1_i32 as i32;\n   |     ^^^^^^^^^^^^ help: try: `1_i32`\n\nerror: casting float literal to `f32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:71:5\n   |\nLL |     1_f32 as f32;\n   |     ^^^^^^^^^^^^ help: try: `1_f32`\n\nerror: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`)\n  --> tests/ui/unnecessary_cast.rs:74:22\n   |\nLL |     let _: *mut u8 = [1u8, 2].as_ptr() as *const u8 as *mut u8;\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_ptr()`\n\nerror: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`)\n  --> tests/ui/unnecessary_cast.rs:77:5\n   |\nLL |     [1u8, 2].as_ptr() as *const u8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_ptr()`\n\nerror: casting raw pointers to the same type and constness is unnecessary (`*mut u8` -> `*mut u8`)\n  --> tests/ui/unnecessary_cast.rs:80:5\n   |\nLL |     [1u8, 2].as_mut_ptr() as *mut u8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[1u8, 2].as_mut_ptr()`\n\nerror: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`)\n  --> tests/ui/unnecessary_cast.rs:92:5\n   |\nLL |     owo::<u32>([1u32].as_ptr()) as *const u32;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `owo::<u32>([1u32].as_ptr())`\n\nerror: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`)\n  --> tests/ui/unnecessary_cast.rs:94:5\n   |\nLL |     uwu::<u32, u8>([1u32].as_ptr()) as *const u8;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `uwu::<u32, u8>([1u32].as_ptr())`\n\nerror: casting raw pointers to the same type and constness is unnecessary (`*const u32` -> `*const u32`)\n  --> tests/ui/unnecessary_cast.rs:97:5\n   |\nLL |     uwu::<u32, u32>([1u32].as_ptr()) as *const u32;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `uwu::<u32, u32>([1u32].as_ptr())`\n\nerror: casting to the same type is unnecessary (`u32` -> `u32`)\n  --> tests/ui/unnecessary_cast.rs:133:5\n   |\nLL |     aaa() as u32;\n   |     ^^^^^^^^^^^^ help: try: `aaa()`\n\nerror: casting to the same type is unnecessary (`u32` -> `u32`)\n  --> tests/ui/unnecessary_cast.rs:136:5\n   |\nLL |     x as u32;\n   |     ^^^^^^^^ help: try: `x`\n\nerror: casting to the same type is unnecessary (`u32` -> `u32`)\n  --> tests/ui/unnecessary_cast.rs:138:5\n   |\nLL |     bbb() as u32;\n   |     ^^^^^^^^^^^^ help: try: `bbb()`\n\nerror: casting to the same type is unnecessary (`u32` -> `u32`)\n  --> tests/ui/unnecessary_cast.rs:141:5\n   |\nLL |     x as u32;\n   |     ^^^^^^^^ help: try: `x`\n\nerror: casting integer literal to `f32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:174:9\n   |\nLL |         100 as f32;\n   |         ^^^^^^^^^^ help: try: `100_f32`\n\nerror: casting integer literal to `f64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:176:9\n   |\nLL |         100 as f64;\n   |         ^^^^^^^^^^ help: try: `100_f64`\n\nerror: casting integer literal to `f64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:178:9\n   |\nLL |         100_i32 as f64;\n   |         ^^^^^^^^^^^^^^ help: try: `100_f64`\n\nerror: casting integer literal to `f32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:180:17\n   |\nLL |         let _ = -100 as f32;\n   |                 ^^^^^^^^^^^ help: try: `-100_f32`\n\nerror: casting integer literal to `f64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:182:17\n   |\nLL |         let _ = -100 as f64;\n   |                 ^^^^^^^^^^^ help: try: `-100_f64`\n\nerror: casting integer literal to `f64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:184:17\n   |\nLL |         let _ = -100_i32 as f64;\n   |                 ^^^^^^^^^^^^^^^ help: try: `-100_f64`\n\nerror: casting float literal to `f32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:186:9\n   |\nLL |         100. as f32;\n   |         ^^^^^^^^^^^ help: try: `100_f32`\n\nerror: casting float literal to `f64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:188:9\n   |\nLL |         100. as f64;\n   |         ^^^^^^^^^^^ help: try: `100_f64`\n\nerror: casting integer literal to `u32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:201:9\n   |\nLL |         1 as u32;\n   |         ^^^^^^^^ help: try: `1_u32`\n\nerror: casting integer literal to `i32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:203:9\n   |\nLL |         0x10 as i32;\n   |         ^^^^^^^^^^^ help: try: `0x10_i32`\n\nerror: casting integer literal to `usize` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:205:9\n   |\nLL |         0b10 as usize;\n   |         ^^^^^^^^^^^^^ help: try: `0b10_usize`\n\nerror: casting integer literal to `u16` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:207:9\n   |\nLL |         0o73 as u16;\n   |         ^^^^^^^^^^^ help: try: `0o73_u16`\n\nerror: casting integer literal to `u32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:209:9\n   |\nLL |         1_000_000_000 as u32;\n   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `1_000_000_000_u32`\n\nerror: casting float literal to `f64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:212:9\n   |\nLL |         1.0 as f64;\n   |         ^^^^^^^^^^ help: try: `1.0_f64`\n\nerror: casting float literal to `f32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:214:9\n   |\nLL |         0.5 as f32;\n   |         ^^^^^^^^^^ help: try: `0.5_f32`\n\nerror: casting integer literal to `i32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:219:17\n   |\nLL |         let _ = -1 as i32;\n   |                 ^^^^^^^^^ help: try: `-1_i32`\n\nerror: casting float literal to `f32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:221:17\n   |\nLL |         let _ = -1.0 as f32;\n   |                 ^^^^^^^^^^^ help: try: `-1.0_f32`\n\nerror: casting to the same type is unnecessary (`i32` -> `i32`)\n  --> tests/ui/unnecessary_cast.rs:228:18\n   |\nLL |         let _ = &(x as i32);\n   |                  ^^^^^^^^^^ help: try: `{ x }`\n\nerror: casting integer literal to `i32` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:235:22\n   |\nLL |         let _: i32 = -(1) as i32;\n   |                      ^^^^^^^^^^^ help: try: `-1_i32`\n\nerror: casting integer literal to `i64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:238:22\n   |\nLL |         let _: i64 = -(1) as i64;\n   |                      ^^^^^^^^^^^ help: try: `-1_i64`\n\nerror: casting float literal to `f64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:246:22\n   |\nLL |         let _: f64 = (-8.0 as f64).exp();\n   |                      ^^^^^^^^^^^^^ help: try: `(-8.0_f64)`\n\nerror: casting float literal to `f64` is unnecessary\n  --> tests/ui/unnecessary_cast.rs:249:23\n   |\nLL |         let _: f64 = -(8.0 as f64).exp(); // should suggest `-8.0_f64.exp()` here not to change code behavior\n   |                       ^^^^^^^^^^^^ help: try: `8.0_f64`\n\nerror: casting to the same type is unnecessary (`f32` -> `f32`)\n  --> tests/ui/unnecessary_cast.rs:259:20\n   |\nLL |         let _num = foo() as f32;\n   |                    ^^^^^^^^^^^^ help: try: `foo()`\n\nerror: casting to the same type is unnecessary (`usize` -> `usize`)\n  --> tests/ui/unnecessary_cast.rs:270:9\n   |\nLL |         (*x as usize).pow(2)\n   |         ^^^^^^^^^^^^^ help: try: `(*x)`\n\nerror: casting to the same type is unnecessary (`usize` -> `usize`)\n  --> tests/ui/unnecessary_cast.rs:278:31\n   |\nLL |         assert_eq!(vec.len(), x as usize);\n   |                               ^^^^^^^^^^ help: try: `x`\n\nerror: casting to the same type is unnecessary (`i64` -> `i64`)\n  --> tests/ui/unnecessary_cast.rs:281:17\n   |\nLL |         let _ = (5i32 as i64 as i64).abs();\n   |                 ^^^^^^^^^^^^^^^^^^^^ help: try: `(5i32 as i64)`\n\nerror: casting to the same type is unnecessary (`i64` -> `i64`)\n  --> tests/ui/unnecessary_cast.rs:284:17\n   |\nLL |         let _ = 5i32 as i64 as i64;\n   |                 ^^^^^^^^^^^^^^^^^^ help: try: `5i32 as i64`\n\nerror: aborting due to 46 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_cast_unfixable.rs",
    "content": "#![warn(clippy::unnecessary_cast)]\n//@no-rustfix\nfn main() {\n    let _ = std::ptr::null() as *const u8;\n    //~^ unnecessary_cast\n}\n\nmod issue11113 {\n    #[repr(C)]\n    struct Vtbl {\n        query: unsafe extern \"system\" fn(),\n    }\n\n    struct TearOff {\n        object: *mut std::ffi::c_void,\n    }\n\n    impl TearOff {\n        unsafe fn query(&self) {\n            unsafe {\n                ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)()\n                //~^ unnecessary_cast\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_cast_unfixable.stderr",
    "content": "error: casting raw pointers to the same type and constness is unnecessary (`*const u8` -> `*const u8`)\n  --> tests/ui/unnecessary_cast_unfixable.rs:4:13\n   |\nLL |     let _ = std::ptr::null() as *const u8;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::null()`\n   |\n   = note: `-D clippy::unnecessary-cast` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]`\n\nerror: casting raw pointers to the same type and constness is unnecessary (`*mut issue11113::Vtbl` -> `*mut issue11113::Vtbl`)\n  --> tests/ui/unnecessary_cast_unfixable.rs:21:20\n   |\nLL |                 ((*(*(self.object as *mut *mut _) as *mut Vtbl)).query)()\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `*(self.object as *mut *mut _)`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_clippy_cfg.rs",
    "content": "//@no-rustfix\n\n#![allow(clippy::duplicated_attributes)]\n#![warn(clippy::unnecessary_clippy_cfg)]\n#![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]\n//~^ unnecessary_clippy_cfg\n#![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]\n//~^ unnecessary_clippy_cfg\n#![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]\n//~^ unnecessary_clippy_cfg\n#![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]\n//~^ unnecessary_clippy_cfg\n\n#[cfg_attr(clippy, deny(clippy::non_minimal_cfg))]\n//~^ unnecessary_clippy_cfg\n#[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]\n//~^ unnecessary_clippy_cfg\n#[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]\n//~^ unnecessary_clippy_cfg\n#[cfg_attr(clippy, deny(clippy::non_minimal_cfg))]\n//~^ unnecessary_clippy_cfg\n\npub struct Bar;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_clippy_cfg.stderr",
    "content": "error: no need to put clippy lints behind a `clippy` cfg\n  --> tests/ui/unnecessary_clippy_cfg.rs:5:1\n   |\nLL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]`\n   |\n   = note: `-D clippy::unnecessary-clippy-cfg` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_clippy_cfg)]`\n\nerror: no need to put clippy lints behind a `clippy` cfg\n  --> tests/ui/unnecessary_clippy_cfg.rs:7:37\n   |\nLL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: write instead: `#![deny(clippy::non_minimal_cfg)]`\n\nerror: no need to put clippy lints behind a `clippy` cfg\n  --> tests/ui/unnecessary_clippy_cfg.rs:9:37\n   |\nLL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: write instead: `#![deny(clippy::non_minimal_cfg)]`\n\nerror: no need to put clippy lints behind a `clippy` cfg\n  --> tests/ui/unnecessary_clippy_cfg.rs:11:1\n   |\nLL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]`\n\nerror: no need to put clippy lints behind a `clippy` cfg\n  --> tests/ui/unnecessary_clippy_cfg.rs:14:1\n   |\nLL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]`\n\nerror: no need to put clippy lints behind a `clippy` cfg\n  --> tests/ui/unnecessary_clippy_cfg.rs:16:36\n   |\nLL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: write instead: `#[deny(clippy::non_minimal_cfg)]`\n\nerror: no need to put clippy lints behind a `clippy` cfg\n  --> tests/ui/unnecessary_clippy_cfg.rs:18:36\n   |\nLL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]\n   |                                    ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: write instead: `#[deny(clippy::non_minimal_cfg)]`\n\nerror: no need to put clippy lints behind a `clippy` cfg\n  --> tests/ui/unnecessary_clippy_cfg.rs:20:1\n   |\nLL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_fallible_conversions.fixed",
    "content": "#![warn(clippy::unnecessary_fallible_conversions)]\n\nfn main() {\n    // --- TryFromMethod `T::try_from(u)` ---\n\n    let _: i64 = 0i32.into();\n    //~^ unnecessary_fallible_conversions\n\n    let _: i64 = 0i32.into();\n    //~^ unnecessary_fallible_conversions\n\n    // --- TryFromFunction `T::try_from(U)` ---\n\n    let _ = i64::from(0i32);\n    //~^ unnecessary_fallible_conversions\n\n    let _ = i64::from(0i32);\n    //~^ unnecessary_fallible_conversions\n\n    // --- TryIntoFunction `U::try_into(t)` ---\n\n    let _: i64 = i32::into(0);\n    //~^ unnecessary_fallible_conversions\n\n    let _: i64 = i32::into(0i32);\n    //~^ unnecessary_fallible_conversions\n\n    // --- TryFromFunction `<T as TryFrom<U>>::try_from(U)` ---\n\n    let _ = <i64 as From<i32>>::from(0);\n    //~^ unnecessary_fallible_conversions\n\n    let _ = <i64 as From<i32>>::from(0);\n    //~^ unnecessary_fallible_conversions\n\n    // --- TryIntoFunction `<U as TryInto<_>>::try_into(U)` ---\n\n    let _: i64 = <i32 as Into<_>>::into(0);\n    //~^ unnecessary_fallible_conversions\n\n    let _: i64 = <i32 as Into<_>>::into(0);\n    //~^ unnecessary_fallible_conversions\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_fallible_conversions.rs",
    "content": "#![warn(clippy::unnecessary_fallible_conversions)]\n\nfn main() {\n    // --- TryFromMethod `T::try_from(u)` ---\n\n    let _: i64 = 0i32.try_into().unwrap();\n    //~^ unnecessary_fallible_conversions\n\n    let _: i64 = 0i32.try_into().expect(\"can't happen\");\n    //~^ unnecessary_fallible_conversions\n\n    // --- TryFromFunction `T::try_from(U)` ---\n\n    let _ = i64::try_from(0i32).unwrap();\n    //~^ unnecessary_fallible_conversions\n\n    let _ = i64::try_from(0i32).expect(\"can't happen\");\n    //~^ unnecessary_fallible_conversions\n\n    // --- TryIntoFunction `U::try_into(t)` ---\n\n    let _: i64 = i32::try_into(0).unwrap();\n    //~^ unnecessary_fallible_conversions\n\n    let _: i64 = i32::try_into(0i32).expect(\"can't happen\");\n    //~^ unnecessary_fallible_conversions\n\n    // --- TryFromFunction `<T as TryFrom<U>>::try_from(U)` ---\n\n    let _ = <i64 as TryFrom<i32>>::try_from(0).unwrap();\n    //~^ unnecessary_fallible_conversions\n\n    let _ = <i64 as TryFrom<i32>>::try_from(0).expect(\"can't happen\");\n    //~^ unnecessary_fallible_conversions\n\n    // --- TryIntoFunction `<U as TryInto<_>>::try_into(U)` ---\n\n    let _: i64 = <i32 as TryInto<_>>::try_into(0).unwrap();\n    //~^ unnecessary_fallible_conversions\n\n    let _: i64 = <i32 as TryInto<_>>::try_into(0).expect(\"can't happen\");\n    //~^ unnecessary_fallible_conversions\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_fallible_conversions.stderr",
    "content": "error: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:6:23\n   |\nLL |     let _: i64 = 0i32.try_into().unwrap();\n   |                       ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\n   = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`\nhelp: use\n   |\nLL -     let _: i64 = 0i32.try_into().unwrap();\nLL +     let _: i64 = 0i32.into();\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:9:23\n   |\nLL |     let _: i64 = 0i32.try_into().expect(\"can't happen\");\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _: i64 = 0i32.try_into().expect(\"can't happen\");\nLL +     let _: i64 = 0i32.into();\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:14:13\n   |\nLL |     let _ = i64::try_from(0i32).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _ = i64::try_from(0i32).unwrap();\nLL +     let _ = i64::from(0i32);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:17:13\n   |\nLL |     let _ = i64::try_from(0i32).expect(\"can't happen\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _ = i64::try_from(0i32).expect(\"can't happen\");\nLL +     let _ = i64::from(0i32);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:22:18\n   |\nLL |     let _: i64 = i32::try_into(0).unwrap();\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _: i64 = i32::try_into(0).unwrap();\nLL +     let _: i64 = i32::into(0);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:25:18\n   |\nLL |     let _: i64 = i32::try_into(0i32).expect(\"can't happen\");\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _: i64 = i32::try_into(0i32).expect(\"can't happen\");\nLL +     let _: i64 = i32::into(0i32);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:30:13\n   |\nLL |     let _ = <i64 as TryFrom<i32>>::try_from(0).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _ = <i64 as TryFrom<i32>>::try_from(0).unwrap();\nLL +     let _ = <i64 as From<i32>>::from(0);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:33:13\n   |\nLL |     let _ = <i64 as TryFrom<i32>>::try_from(0).expect(\"can't happen\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _ = <i64 as TryFrom<i32>>::try_from(0).expect(\"can't happen\");\nLL +     let _ = <i64 as From<i32>>::from(0);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:38:18\n   |\nLL |     let _: i64 = <i32 as TryInto<_>>::try_into(0).unwrap();\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _: i64 = <i32 as TryInto<_>>::try_into(0).unwrap();\nLL +     let _: i64 = <i32 as Into<_>>::into(0);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions.rs:41:18\n   |\nLL |     let _: i64 = <i32 as TryInto<_>>::try_into(0).expect(\"can't happen\");\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _: i64 = <i32 as TryInto<_>>::try_into(0).expect(\"can't happen\");\nLL +     let _: i64 = <i32 as Into<_>>::into(0);\n   |\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_fallible_conversions_unfixable.rs",
    "content": "//@aux-build:proc_macros.rs\n//@no-rustfix\n#![warn(clippy::unnecessary_fallible_conversions)]\n\nextern crate proc_macros;\n\nstruct Foo;\nimpl TryFrom<i32> for Foo {\n    type Error = ();\n    fn try_from(_: i32) -> Result<Self, Self::Error> {\n        Ok(Foo)\n    }\n}\nimpl From<i64> for Foo {\n    fn from(_: i64) -> Self {\n        Foo\n    }\n}\n\nfn main() {\n    // `Foo` only implements `TryFrom<i32>` and not `From<i32>`, so don't lint\n    let _: Result<Foo, _> = 0i32.try_into();\n    let _: Result<Foo, _> = i32::try_into(0i32);\n    let _: Result<Foo, _> = Foo::try_from(0i32);\n\n    // ... it does impl From<i64> however\n    let _: Result<Foo, _> = 0i64.try_into();\n    //~^ ERROR: use of a fallible conversion when an infallible one could be used\n    let _: Result<Foo, _> = i64::try_into(0i64);\n    //~^ ERROR: use of a fallible conversion when an infallible one could be used\n    let _: Result<Foo, _> = Foo::try_from(0i64);\n    //~^ ERROR: use of a fallible conversion when an infallible one could be used\n\n    let _: Result<i64, _> = 0i32.try_into();\n    //~^ ERROR: use of a fallible conversion when an infallible one could be used\n    let _: Result<i64, _> = i32::try_into(0i32);\n    //~^ ERROR: use of a fallible conversion when an infallible one could be used\n    let _: Result<i64, _> = <_>::try_from(0i32);\n    //~^ ERROR: use of a fallible conversion when an infallible one could be used\n\n    // From a macro\n    let _: Result<i64, _> = proc_macros::external!(0i32).try_into();\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_fallible_conversions_unfixable.stderr",
    "content": "error: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions_unfixable.rs:27:34\n   |\nLL |     let _: Result<Foo, _> = 0i64.try_into();\n   |                                  ^^^^^^^^\n   |\n   = note: converting `i64` to `Foo` cannot fail\n   = note: `-D clippy::unnecessary-fallible-conversions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fallible_conversions)]`\nhelp: use\n   |\nLL -     let _: Result<Foo, _> = 0i64.try_into();\nLL +     let _: Result<Foo, _> = 0i64.into();\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions_unfixable.rs:29:29\n   |\nLL |     let _: Result<Foo, _> = i64::try_into(0i64);\n   |                             ^^^^^^^^^^^^^\n   |\n   = note: converting `i64` to `Foo` cannot fail\nhelp: use\n   |\nLL -     let _: Result<Foo, _> = i64::try_into(0i64);\nLL +     let _: Result<Foo, _> = Into::into(0i64);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions_unfixable.rs:31:29\n   |\nLL |     let _: Result<Foo, _> = Foo::try_from(0i64);\n   |                             ^^^^^^^^^^^^^\n   |\n   = note: converting `i64` to `Foo` cannot fail\nhelp: use\n   |\nLL -     let _: Result<Foo, _> = Foo::try_from(0i64);\nLL +     let _: Result<Foo, _> = From::from(0i64);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions_unfixable.rs:34:34\n   |\nLL |     let _: Result<i64, _> = 0i32.try_into();\n   |                                  ^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _: Result<i64, _> = 0i32.try_into();\nLL +     let _: Result<i64, _> = 0i32.into();\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions_unfixable.rs:36:29\n   |\nLL |     let _: Result<i64, _> = i32::try_into(0i32);\n   |                             ^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _: Result<i64, _> = i32::try_into(0i32);\nLL +     let _: Result<i64, _> = Into::into(0i32);\n   |\n\nerror: use of a fallible conversion when an infallible one could be used\n  --> tests/ui/unnecessary_fallible_conversions_unfixable.rs:38:29\n   |\nLL |     let _: Result<i64, _> = <_>::try_from(0i32);\n   |                             ^^^^^^^^^^^^^\n   |\n   = note: converting `i32` to `i64` cannot fail\nhelp: use\n   |\nLL -     let _: Result<i64, _> = <_>::try_from(0i32);\nLL +     let _: Result<i64, _> = From::from(0i32);\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_filter_map.rs",
    "content": "#![allow(clippy::redundant_closure)]\n\nfn main() {\n    let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None });\n    //~^ unnecessary_filter_map\n\n    let _ = (0..4).filter_map(|x| {\n        //~^ unnecessary_filter_map\n\n        if x > 1 {\n            return Some(x);\n        };\n        None\n    });\n    let _ = (0..4).filter_map(|x| match x {\n        //~^ unnecessary_filter_map\n        0 | 1 => None,\n        _ => Some(x),\n    });\n\n    let _ = (0..4).filter_map(|x| Some(x + 1));\n    //~^ unnecessary_filter_map\n\n    let _ = (0..4).filter_map(i32::checked_abs);\n\n    let _ = (0..4).filter_map(Some);\n\n    let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));\n    //~^ unnecessary_filter_map\n}\n\nfn filter_map_none_changes_item_type() -> impl Iterator<Item = bool> {\n    \"\".chars().filter_map(|_| None)\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/4433#issue-483920107\nmod comment_483920107 {\n    enum Severity {\n        Warning,\n        Other,\n    }\n\n    struct ServerError;\n\n    impl ServerError {\n        fn severity(&self) -> Severity {\n            Severity::Warning\n        }\n    }\n\n    struct S {\n        warnings: Vec<ServerError>,\n    }\n\n    impl S {\n        fn foo(&mut self, server_errors: Vec<ServerError>) {\n            #[allow(unused_variables)]\n            let errors: Vec<ServerError> = server_errors\n                .into_iter()\n                .filter_map(|se| match se.severity() {\n                    Severity::Warning => {\n                        self.warnings.push(se);\n                        None\n                    },\n                    _ => Some(se),\n                })\n                .collect();\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/4433#issuecomment-611006622\nmod comment_611006622 {\n    struct PendingRequest {\n        reply_to: u8,\n        token: u8,\n        expires: u8,\n        group_id: u8,\n    }\n\n    enum Value {\n        Null,\n    }\n\n    struct Node;\n\n    impl Node {\n        fn send_response(&self, _reply_to: u8, _token: u8, _value: Value) -> &Self {\n            self\n        }\n        fn on_error_warn(&self) -> &Self {\n            self\n        }\n    }\n\n    struct S {\n        pending_requests: Vec<PendingRequest>,\n    }\n\n    impl S {\n        fn foo(&mut self, node: Node, now: u8, group_id: u8) {\n            // \"drain_filter\"\n            self.pending_requests = self\n                .pending_requests\n                .drain(..)\n                .filter_map(|pending| {\n                    if pending.expires <= now {\n                        return None; // Expired, remove\n                    }\n\n                    if pending.group_id == group_id {\n                        // Matched - reuse strings and remove\n                        node.send_response(pending.reply_to, pending.token, Value::Null)\n                            .on_error_warn();\n                        None\n                    } else {\n                        // Keep waiting\n                        Some(pending)\n                    }\n                })\n                .collect();\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/4433#issuecomment-621925270\n// This extrapolation doesn't reproduce the false positive. Additional context seems necessary.\nmod comment_621925270 {\n    struct Signature(u8);\n\n    fn foo(sig_packets: impl Iterator<Item = Result<Signature, ()>>) -> impl Iterator<Item = u8> {\n        sig_packets.filter_map(|res| match res {\n            Ok(Signature(sig_packet)) => Some(sig_packet),\n            _ => None,\n        })\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/4433#issuecomment-1052978898\nmod comment_1052978898 {\n    #![allow(clippy::redundant_closure)]\n\n    pub struct S(u8);\n\n    impl S {\n        pub fn consume(self) {\n            println!(\"yum\");\n        }\n    }\n\n    pub fn filter_owned() -> impl Iterator<Item = S> {\n        (0..10).map(|i| S(i)).filter_map(|s| {\n            if s.0 & 1 == 0 {\n                s.consume();\n                None\n            } else {\n                Some(s)\n            }\n        })\n    }\n}\n\nfn issue11260() {\n    // #11260 is about unnecessary_find_map, but the fix also kind of applies to\n    // unnecessary_filter_map\n    let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n));\n    //~^ unnecessary_filter_map\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_filter_map.stderr",
    "content": "error: this `.filter_map(..)` can be written more simply using `.filter(..)`\n  --> tests/ui/unnecessary_filter_map.rs:4:20\n   |\nLL |     let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None });\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-filter-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_filter_map)]`\n\nerror: this `.filter_map(..)` can be written more simply using `.filter(..)`\n  --> tests/ui/unnecessary_filter_map.rs:7:20\n   |\nLL |       let _ = (0..4).filter_map(|x| {\n   |  ____________________^\nLL | |\nLL | |\nLL | |         if x > 1 {\n...  |\nLL | |         None\nLL | |     });\n   | |______^\n\nerror: this `.filter_map(..)` can be written more simply using `.filter(..)`\n  --> tests/ui/unnecessary_filter_map.rs:15:20\n   |\nLL |       let _ = (0..4).filter_map(|x| match x {\n   |  ____________________^\nLL | |\nLL | |         0 | 1 => None,\nLL | |         _ => Some(x),\nLL | |     });\n   | |______^\n\nerror: this `.filter_map(..)` can be written more simply using `.map(..)`\n  --> tests/ui/unnecessary_filter_map.rs:21:20\n   |\nLL |     let _ = (0..4).filter_map(|x| Some(x + 1));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `.filter_map(..)` is unnecessary\n  --> tests/ui/unnecessary_filter_map.rs:28:46\n   |\nLL |     let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));\n   |                                              ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `.filter_map(..)` can be written more simply using `.filter(..)`\n  --> tests/ui/unnecessary_filter_map.rs:166:33\n   |\nLL |     let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n));\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_find_map.rs",
    "content": "fn main() {\n    let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None });\n    //~^ unnecessary_find_map\n\n    let _ = (0..4).find_map(|x| {\n        //~^ unnecessary_find_map\n\n        if x > 1 {\n            return Some(x);\n        };\n        None\n    });\n    let _ = (0..4).find_map(|x| match x {\n        //~^ unnecessary_find_map\n        0 | 1 => None,\n        _ => Some(x),\n    });\n\n    let _ = (0..4).find_map(|x| Some(x + 1));\n    //~^ unnecessary_find_map\n\n    let _ = (0..4).find_map(i32::checked_abs);\n}\n\nfn find_map_none_changes_item_type() -> Option<bool> {\n    \"\".chars().find_map(|_| None)\n}\n\nfn issue11260() {\n    let y = Some(1);\n    let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n));\n    //~^ unnecessary_find_map\n    let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(y)); // different option, so can't be just `.find()`\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_find_map.stderr",
    "content": "error: this `.find_map(..)` can be written more simply using `.find(..)`\n  --> tests/ui/unnecessary_find_map.rs:2:20\n   |\nLL |     let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None });\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-find-map` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_find_map)]`\n\nerror: this `.find_map(..)` can be written more simply using `.find(..)`\n  --> tests/ui/unnecessary_find_map.rs:5:20\n   |\nLL |       let _ = (0..4).find_map(|x| {\n   |  ____________________^\nLL | |\nLL | |\nLL | |         if x > 1 {\n...  |\nLL | |         None\nLL | |     });\n   | |______^\n\nerror: this `.find_map(..)` can be written more simply using `.find(..)`\n  --> tests/ui/unnecessary_find_map.rs:13:20\n   |\nLL |       let _ = (0..4).find_map(|x| match x {\n   |  ____________________^\nLL | |\nLL | |         0 | 1 => None,\nLL | |         _ => Some(x),\nLL | |     });\n   | |______^\n\nerror: this `.find_map(..)` can be written more simply using `.map(..).next()`\n  --> tests/ui/unnecessary_find_map.rs:19:20\n   |\nLL |     let _ = (0..4).find_map(|x| Some(x + 1));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this `.find_map(..)` can be written more simply using `.find(..)`\n  --> tests/ui/unnecessary_find_map.rs:31:33\n   |\nLL |     let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n));\n   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_first_then_check.fixed",
    "content": "#![warn(clippy::unnecessary_first_then_check)]\n#![allow(clippy::useless_vec, clippy::const_is_empty)]\n\nfn main() {\n    let s = [1, 2, 3];\n    let _: bool = !s.is_empty();\n    //~^ unnecessary_first_then_check\n    let _: bool = s.is_empty();\n    //~^ unnecessary_first_then_check\n\n    let v = vec![1, 2, 3];\n    let _: bool = !v.is_empty();\n    //~^ unnecessary_first_then_check\n\n    let n = [[1, 2, 3], [4, 5, 6]];\n    let _: bool = !n[0].is_empty();\n    //~^ unnecessary_first_then_check\n    let _: bool = n[0].is_empty();\n    //~^ unnecessary_first_then_check\n\n    struct Foo {\n        bar: &'static [i32],\n    }\n    let f = [Foo { bar: &[] }];\n    let _: bool = !f[0].bar.is_empty();\n    //~^ unnecessary_first_then_check\n    let _: bool = f[0].bar.is_empty();\n    //~^ unnecessary_first_then_check\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_first_then_check.rs",
    "content": "#![warn(clippy::unnecessary_first_then_check)]\n#![allow(clippy::useless_vec, clippy::const_is_empty)]\n\nfn main() {\n    let s = [1, 2, 3];\n    let _: bool = s.first().is_some();\n    //~^ unnecessary_first_then_check\n    let _: bool = s.first().is_none();\n    //~^ unnecessary_first_then_check\n\n    let v = vec![1, 2, 3];\n    let _: bool = v.first().is_some();\n    //~^ unnecessary_first_then_check\n\n    let n = [[1, 2, 3], [4, 5, 6]];\n    let _: bool = n[0].first().is_some();\n    //~^ unnecessary_first_then_check\n    let _: bool = n[0].first().is_none();\n    //~^ unnecessary_first_then_check\n\n    struct Foo {\n        bar: &'static [i32],\n    }\n    let f = [Foo { bar: &[] }];\n    let _: bool = f[0].bar.first().is_some();\n    //~^ unnecessary_first_then_check\n    let _: bool = f[0].bar.first().is_none();\n    //~^ unnecessary_first_then_check\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_first_then_check.stderr",
    "content": "error: unnecessary use of `first().is_some()` to check if slice is not empty\n  --> tests/ui/unnecessary_first_then_check.rs:6:19\n   |\nLL |     let _: bool = s.first().is_some();\n   |                   ^^^^^^^^^^^^^^^^^^^ help: replace this with: `!s.is_empty()`\n   |\n   = note: `-D clippy::unnecessary-first-then-check` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_first_then_check)]`\n\nerror: unnecessary use of `first().is_none()` to check if slice is empty\n  --> tests/ui/unnecessary_first_then_check.rs:8:21\n   |\nLL |     let _: bool = s.first().is_none();\n   |                     ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()`\n\nerror: unnecessary use of `first().is_some()` to check if slice is not empty\n  --> tests/ui/unnecessary_first_then_check.rs:12:19\n   |\nLL |     let _: bool = v.first().is_some();\n   |                   ^^^^^^^^^^^^^^^^^^^ help: replace this with: `!v.is_empty()`\n\nerror: unnecessary use of `first().is_some()` to check if slice is not empty\n  --> tests/ui/unnecessary_first_then_check.rs:16:19\n   |\nLL |     let _: bool = n[0].first().is_some();\n   |                   ^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `!n[0].is_empty()`\n\nerror: unnecessary use of `first().is_none()` to check if slice is empty\n  --> tests/ui/unnecessary_first_then_check.rs:18:24\n   |\nLL |     let _: bool = n[0].first().is_none();\n   |                        ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()`\n\nerror: unnecessary use of `first().is_some()` to check if slice is not empty\n  --> tests/ui/unnecessary_first_then_check.rs:25:19\n   |\nLL |     let _: bool = f[0].bar.first().is_some();\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `!f[0].bar.is_empty()`\n\nerror: unnecessary use of `first().is_none()` to check if slice is empty\n  --> tests/ui/unnecessary_first_then_check.rs:27:28\n   |\nLL |     let _: bool = f[0].bar.first().is_none();\n   |                            ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()`\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_fold.fixed",
    "content": "#![allow(dead_code)]\n\nfn is_any(acc: bool, x: usize) -> bool {\n    acc || x > 2\n}\n\n/// Calls which should trigger the `UNNECESSARY_FOLD` lint\nfn unnecessary_fold() {\n    use std::ops::{Add, Mul};\n\n    // Can be replaced by .any\n    let _ = (0..3).any(|x| x > 2);\n    //~^ unnecessary_fold\n\n    // Can be replaced by .any (checking suggestion)\n    let _ = (0..3).fold(false, is_any);\n    //~^ redundant_closure\n\n    // Can be replaced by .all\n    let _ = (0..3).all(|x| x > 2);\n    //~^ unnecessary_fold\n\n    // Can be replaced by .sum\n    let _: i32 = (0..3).sum();\n    //~^ unnecessary_fold\n    let _: i32 = (0..3).sum();\n    //~^ unnecessary_fold\n    let _: i32 = (0..3).sum();\n    //~^ unnecessary_fold\n\n    // Can be replaced by .product\n    let _: i32 = (0..3).product();\n    //~^ unnecessary_fold\n    let _: i32 = (0..3).product();\n    //~^ unnecessary_fold\n    let _: i32 = (0..3).product();\n    //~^ unnecessary_fold\n}\n\n/// Should trigger the `UNNECESSARY_FOLD` lint, with an error span including exactly `.fold(...)`\nfn unnecessary_fold_span_for_multi_element_chain() {\n    let _: bool = (0..3).map(|x| 2 * x).any(|x| x > 2);\n    //~^ unnecessary_fold\n}\n\n/// Calls which should not trigger the `UNNECESSARY_FOLD` lint\nfn unnecessary_fold_should_ignore() {\n    let _ = (0..3).fold(true, |acc, x| acc || x > 2);\n    let _ = (0..3).fold(false, |acc, x| acc && x > 2);\n    let _ = (0..3).fold(1, |acc, x| acc + x);\n    let _ = (0..3).fold(0, |acc, x| acc * x);\n    let _ = (0..3).fold(0, |acc, x| 1 + acc + x);\n\n    struct Adder;\n    impl Adder {\n        fn add(lhs: i32, rhs: i32) -> i32 {\n            unimplemented!()\n        }\n        fn mul(lhs: i32, rhs: i32) -> i32 {\n            unimplemented!()\n        }\n    }\n    // `add`/`mul` are inherent methods\n    let _: i32 = (0..3).fold(0, Adder::add);\n    let _: i32 = (0..3).fold(1, Adder::mul);\n\n    trait FakeAdd<Rhs = Self> {\n        type Output;\n        fn add(self, other: Rhs) -> Self::Output;\n    }\n    impl FakeAdd for i32 {\n        type Output = Self;\n        fn add(self, other: i32) -> Self::Output {\n            self + other\n        }\n    }\n    trait FakeMul<Rhs = Self> {\n        type Output;\n        fn mul(self, other: Rhs) -> Self::Output;\n    }\n    impl FakeMul for i32 {\n        type Output = Self;\n        fn mul(self, other: i32) -> Self::Output {\n            self * other\n        }\n    }\n    // `add`/`mul` come from an unrelated trait\n    let _: i32 = (0..3).fold(0, FakeAdd::add);\n    let _: i32 = (0..3).fold(1, FakeMul::mul);\n\n    let _ = [(0..2), (0..3)].iter().fold(0, |a, b| a + b.len());\n    let _ = [(0..2), (0..3)].iter().fold(1, |a, b| a * b.len());\n}\n\n/// Should lint only the line containing the fold\nfn unnecessary_fold_over_multiple_lines() {\n    let _ = (0..3)\n        .map(|x| x + 1)\n        .filter(|x| x % 2 == 0)\n        .any(|x| x > 2);\n    //~^ unnecessary_fold\n}\n\nfn issue10000() {\n    use std::collections::HashMap;\n    use std::hash::BuildHasher;\n    use std::ops::{Add, Mul};\n\n    fn anything<T>(_: T) {}\n    fn num(_: i32) {}\n    fn smoketest_map<S: BuildHasher>(mut map: HashMap<i32, i32, S>) {\n        map.insert(0, 0);\n        assert_eq!(map.values().sum::<i32>(), 0);\n        //~^ unnecessary_fold\n\n        // more cases:\n        let _ = map.values().sum::<i32>();\n        //~^ unnecessary_fold\n        let _ = map.values().sum::<i32>();\n        //~^ unnecessary_fold\n        let _ = map.values().product::<i32>();\n        //~^ unnecessary_fold\n        let _ = map.values().product::<i32>();\n        //~^ unnecessary_fold\n        let _: i32 = map.values().sum();\n        //~^ unnecessary_fold\n        let _: i32 = map.values().sum();\n        //~^ unnecessary_fold\n        let _: i32 = map.values().product();\n        //~^ unnecessary_fold\n        let _: i32 = map.values().product();\n        //~^ unnecessary_fold\n        anything(map.values().sum::<i32>());\n        //~^ unnecessary_fold\n        anything(map.values().sum::<i32>());\n        //~^ unnecessary_fold\n        anything(map.values().product::<i32>());\n        //~^ unnecessary_fold\n        anything(map.values().product::<i32>());\n        //~^ unnecessary_fold\n        num(map.values().sum());\n        //~^ unnecessary_fold\n        num(map.values().sum());\n        //~^ unnecessary_fold\n        num(map.values().product());\n        //~^ unnecessary_fold\n        num(map.values().product());\n        //~^ unnecessary_fold\n    }\n\n    smoketest_map(HashMap::new());\n\n    fn add_turbofish_not_necessary() -> i32 {\n        (0..3).sum()\n        //~^ unnecessary_fold\n    }\n    fn mul_turbofish_not_necessary() -> i32 {\n        (0..3).product()\n        //~^ unnecessary_fold\n    }\n    fn add_turbofish_necessary() -> impl Add {\n        (0..3).sum::<i32>()\n        //~^ unnecessary_fold\n    }\n    fn mul_turbofish_necessary() -> impl Mul {\n        (0..3).product::<i32>()\n        //~^ unnecessary_fold\n    }\n}\n\nfn issue16581() {\n    let _ = (2..=3).product::<i32>();\n    //~^ unnecessary_fold\n    let _ = (1..=3).sum::<i32>();\n    //~^ unnecessary_fold\n    let _ = (2..=3).product::<i32>();\n    //~^ unnecessary_fold\n    let _ = (1..=3).sum::<i32>();\n    //~^ unnecessary_fold\n\n    let _ = (0..3).any(|x| x > 2);\n    //~^ unnecessary_fold\n    let _ = (0..3).all(|x| x > 2);\n    //~^ unnecessary_fold\n    let _ = (0..3).sum::<i32>();\n    //~^ unnecessary_fold\n    let _ = (0..3).product::<i32>();\n    //~^ unnecessary_fold\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($e:expr) => {\n            ($e + 1) > 2\n        };\n    }\n\n    let _ = (0..3).any(|x| test_expr!(x));\n    //~^ unnecessary_fold\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_fold.rs",
    "content": "#![allow(dead_code)]\n\nfn is_any(acc: bool, x: usize) -> bool {\n    acc || x > 2\n}\n\n/// Calls which should trigger the `UNNECESSARY_FOLD` lint\nfn unnecessary_fold() {\n    use std::ops::{Add, Mul};\n\n    // Can be replaced by .any\n    let _ = (0..3).fold(false, |acc, x| acc || x > 2);\n    //~^ unnecessary_fold\n\n    // Can be replaced by .any (checking suggestion)\n    let _ = (0..3).fold(false, |acc, x| is_any(acc, x));\n    //~^ redundant_closure\n\n    // Can be replaced by .all\n    let _ = (0..3).fold(true, |acc, x| acc && x > 2);\n    //~^ unnecessary_fold\n\n    // Can be replaced by .sum\n    let _: i32 = (0..3).fold(0, |acc, x| acc + x);\n    //~^ unnecessary_fold\n    let _: i32 = (0..3).fold(0, Add::add);\n    //~^ unnecessary_fold\n    let _: i32 = (0..3).fold(0, i32::add);\n    //~^ unnecessary_fold\n\n    // Can be replaced by .product\n    let _: i32 = (0..3).fold(1, |acc, x| acc * x);\n    //~^ unnecessary_fold\n    let _: i32 = (0..3).fold(1, Mul::mul);\n    //~^ unnecessary_fold\n    let _: i32 = (0..3).fold(1, i32::mul);\n    //~^ unnecessary_fold\n}\n\n/// Should trigger the `UNNECESSARY_FOLD` lint, with an error span including exactly `.fold(...)`\nfn unnecessary_fold_span_for_multi_element_chain() {\n    let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2);\n    //~^ unnecessary_fold\n}\n\n/// Calls which should not trigger the `UNNECESSARY_FOLD` lint\nfn unnecessary_fold_should_ignore() {\n    let _ = (0..3).fold(true, |acc, x| acc || x > 2);\n    let _ = (0..3).fold(false, |acc, x| acc && x > 2);\n    let _ = (0..3).fold(1, |acc, x| acc + x);\n    let _ = (0..3).fold(0, |acc, x| acc * x);\n    let _ = (0..3).fold(0, |acc, x| 1 + acc + x);\n\n    struct Adder;\n    impl Adder {\n        fn add(lhs: i32, rhs: i32) -> i32 {\n            unimplemented!()\n        }\n        fn mul(lhs: i32, rhs: i32) -> i32 {\n            unimplemented!()\n        }\n    }\n    // `add`/`mul` are inherent methods\n    let _: i32 = (0..3).fold(0, Adder::add);\n    let _: i32 = (0..3).fold(1, Adder::mul);\n\n    trait FakeAdd<Rhs = Self> {\n        type Output;\n        fn add(self, other: Rhs) -> Self::Output;\n    }\n    impl FakeAdd for i32 {\n        type Output = Self;\n        fn add(self, other: i32) -> Self::Output {\n            self + other\n        }\n    }\n    trait FakeMul<Rhs = Self> {\n        type Output;\n        fn mul(self, other: Rhs) -> Self::Output;\n    }\n    impl FakeMul for i32 {\n        type Output = Self;\n        fn mul(self, other: i32) -> Self::Output {\n            self * other\n        }\n    }\n    // `add`/`mul` come from an unrelated trait\n    let _: i32 = (0..3).fold(0, FakeAdd::add);\n    let _: i32 = (0..3).fold(1, FakeMul::mul);\n\n    let _ = [(0..2), (0..3)].iter().fold(0, |a, b| a + b.len());\n    let _ = [(0..2), (0..3)].iter().fold(1, |a, b| a * b.len());\n}\n\n/// Should lint only the line containing the fold\nfn unnecessary_fold_over_multiple_lines() {\n    let _ = (0..3)\n        .map(|x| x + 1)\n        .filter(|x| x % 2 == 0)\n        .fold(false, |acc, x| acc || x > 2);\n    //~^ unnecessary_fold\n}\n\nfn issue10000() {\n    use std::collections::HashMap;\n    use std::hash::BuildHasher;\n    use std::ops::{Add, Mul};\n\n    fn anything<T>(_: T) {}\n    fn num(_: i32) {}\n    fn smoketest_map<S: BuildHasher>(mut map: HashMap<i32, i32, S>) {\n        map.insert(0, 0);\n        assert_eq!(map.values().fold(0, |x, y| x + y), 0);\n        //~^ unnecessary_fold\n\n        // more cases:\n        let _ = map.values().fold(0, |x, y| x + y);\n        //~^ unnecessary_fold\n        let _ = map.values().fold(0, Add::add);\n        //~^ unnecessary_fold\n        let _ = map.values().fold(1, |x, y| x * y);\n        //~^ unnecessary_fold\n        let _ = map.values().fold(1, Mul::mul);\n        //~^ unnecessary_fold\n        let _: i32 = map.values().fold(0, |x, y| x + y);\n        //~^ unnecessary_fold\n        let _: i32 = map.values().fold(0, Add::add);\n        //~^ unnecessary_fold\n        let _: i32 = map.values().fold(1, |x, y| x * y);\n        //~^ unnecessary_fold\n        let _: i32 = map.values().fold(1, Mul::mul);\n        //~^ unnecessary_fold\n        anything(map.values().fold(0, |x, y| x + y));\n        //~^ unnecessary_fold\n        anything(map.values().fold(0, Add::add));\n        //~^ unnecessary_fold\n        anything(map.values().fold(1, |x, y| x * y));\n        //~^ unnecessary_fold\n        anything(map.values().fold(1, Mul::mul));\n        //~^ unnecessary_fold\n        num(map.values().fold(0, |x, y| x + y));\n        //~^ unnecessary_fold\n        num(map.values().fold(0, Add::add));\n        //~^ unnecessary_fold\n        num(map.values().fold(1, |x, y| x * y));\n        //~^ unnecessary_fold\n        num(map.values().fold(1, Mul::mul));\n        //~^ unnecessary_fold\n    }\n\n    smoketest_map(HashMap::new());\n\n    fn add_turbofish_not_necessary() -> i32 {\n        (0..3).fold(0, |acc, x| acc + x)\n        //~^ unnecessary_fold\n    }\n    fn mul_turbofish_not_necessary() -> i32 {\n        (0..3).fold(1, |acc, x| acc * x)\n        //~^ unnecessary_fold\n    }\n    fn add_turbofish_necessary() -> impl Add {\n        (0..3).fold(0, |acc, x| acc + x)\n        //~^ unnecessary_fold\n    }\n    fn mul_turbofish_necessary() -> impl Mul {\n        (0..3).fold(1, |acc, x| acc * x)\n        //~^ unnecessary_fold\n    }\n}\n\nfn issue16581() {\n    let _ = (2..=3).fold(1, |a, b| a * b);\n    //~^ unnecessary_fold\n    let _ = (1..=3).fold(0, |a, b| a + b);\n    //~^ unnecessary_fold\n    let _ = (2..=3).fold(1, |b, a| a * b);\n    //~^ unnecessary_fold\n    let _ = (1..=3).fold(0, |b, a| a + b);\n    //~^ unnecessary_fold\n\n    let _ = (0..3).fold(false, |acc, x| x > 2 || acc);\n    //~^ unnecessary_fold\n    let _ = (0..3).fold(true, |acc, x| x > 2 && acc);\n    //~^ unnecessary_fold\n    let _ = (0..3).fold(0, |acc, x| x + acc);\n    //~^ unnecessary_fold\n    let _ = (0..3).fold(1, |acc, x| x * acc);\n    //~^ unnecessary_fold\n}\n\nfn wrongly_unmangled_macros() {\n    macro_rules! test_expr {\n        ($e:expr) => {\n            ($e + 1) > 2\n        };\n    }\n\n    let _ = (0..3).fold(false, |acc: bool, x| acc || test_expr!(x));\n    //~^ unnecessary_fold\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_fold.stderr",
    "content": "error: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:12:20\n   |\nLL |     let _ = (0..3).fold(false, |acc, x| acc || x > 2);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`\n   |\n   = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects\n   = note: `-D clippy::unnecessary-fold` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fold)]`\n\nerror: redundant closure\n  --> tests/ui/unnecessary_fold.rs:16:32\n   |\nLL |     let _ = (0..3).fold(false, |acc, x| is_any(acc, x));\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `is_any`\n   |\n   = note: `-D clippy::redundant-closure` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:20:20\n   |\nLL |     let _ = (0..3).fold(true, |acc, x| acc && x > 2);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)`\n   |\n   = note: the `all` method is short circuiting and may change the program semantics if the iterator has side effects\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:24:25\n   |\nLL |     let _: i32 = (0..3).fold(0, |acc, x| acc + x);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:26:25\n   |\nLL |     let _: i32 = (0..3).fold(0, Add::add);\n   |                         ^^^^^^^^^^^^^^^^^ help: try: `sum()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:28:25\n   |\nLL |     let _: i32 = (0..3).fold(0, i32::add);\n   |                         ^^^^^^^^^^^^^^^^^ help: try: `sum()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:32:25\n   |\nLL |     let _: i32 = (0..3).fold(1, |acc, x| acc * x);\n   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:34:25\n   |\nLL |     let _: i32 = (0..3).fold(1, Mul::mul);\n   |                         ^^^^^^^^^^^^^^^^^ help: try: `product()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:36:25\n   |\nLL |     let _: i32 = (0..3).fold(1, i32::mul);\n   |                         ^^^^^^^^^^^^^^^^^ help: try: `product()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:42:41\n   |\nLL |     let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2);\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`\n   |\n   = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:100:10\n   |\nLL |         .fold(false, |acc, x| acc || x > 2);\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`\n   |\n   = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:113:33\n   |\nLL |         assert_eq!(map.values().fold(0, |x, y| x + y), 0);\n   |                                 ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:117:30\n   |\nLL |         let _ = map.values().fold(0, |x, y| x + y);\n   |                              ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:119:30\n   |\nLL |         let _ = map.values().fold(0, Add::add);\n   |                              ^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:121:30\n   |\nLL |         let _ = map.values().fold(1, |x, y| x * y);\n   |                              ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:123:30\n   |\nLL |         let _ = map.values().fold(1, Mul::mul);\n   |                              ^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:125:35\n   |\nLL |         let _: i32 = map.values().fold(0, |x, y| x + y);\n   |                                   ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:127:35\n   |\nLL |         let _: i32 = map.values().fold(0, Add::add);\n   |                                   ^^^^^^^^^^^^^^^^^ help: try: `sum()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:129:35\n   |\nLL |         let _: i32 = map.values().fold(1, |x, y| x * y);\n   |                                   ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:131:35\n   |\nLL |         let _: i32 = map.values().fold(1, Mul::mul);\n   |                                   ^^^^^^^^^^^^^^^^^ help: try: `product()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:133:31\n   |\nLL |         anything(map.values().fold(0, |x, y| x + y));\n   |                               ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:135:31\n   |\nLL |         anything(map.values().fold(0, Add::add));\n   |                               ^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:137:31\n   |\nLL |         anything(map.values().fold(1, |x, y| x * y));\n   |                               ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:139:31\n   |\nLL |         anything(map.values().fold(1, Mul::mul));\n   |                               ^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:141:26\n   |\nLL |         num(map.values().fold(0, |x, y| x + y));\n   |                          ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:143:26\n   |\nLL |         num(map.values().fold(0, Add::add));\n   |                          ^^^^^^^^^^^^^^^^^ help: try: `sum()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:145:26\n   |\nLL |         num(map.values().fold(1, |x, y| x * y));\n   |                          ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:147:26\n   |\nLL |         num(map.values().fold(1, Mul::mul));\n   |                          ^^^^^^^^^^^^^^^^^ help: try: `product()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:154:16\n   |\nLL |         (0..3).fold(0, |acc, x| acc + x)\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:158:16\n   |\nLL |         (0..3).fold(1, |acc, x| acc * x)\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:162:16\n   |\nLL |         (0..3).fold(0, |acc, x| acc + x)\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:166:16\n   |\nLL |         (0..3).fold(1, |acc, x| acc * x)\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:172:21\n   |\nLL |     let _ = (2..=3).fold(1, |a, b| a * b);\n   |                     ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:174:21\n   |\nLL |     let _ = (1..=3).fold(0, |a, b| a + b);\n   |                     ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:176:21\n   |\nLL |     let _ = (2..=3).fold(1, |b, a| a * b);\n   |                     ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:178:21\n   |\nLL |     let _ = (1..=3).fold(0, |b, a| a + b);\n   |                     ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:181:20\n   |\nLL |     let _ = (0..3).fold(false, |acc, x| x > 2 || acc);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`\n   |\n   = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:183:20\n   |\nLL |     let _ = (0..3).fold(true, |acc, x| x > 2 && acc);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)`\n   |\n   = note: the `all` method is short circuiting and may change the program semantics if the iterator has side effects\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:185:20\n   |\nLL |     let _ = (0..3).fold(0, |acc, x| x + acc);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:187:20\n   |\nLL |     let _ = (0..3).fold(1, |acc, x| x * acc);\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`\n\nerror: this `.fold` can be written more succinctly using another method\n  --> tests/ui/unnecessary_fold.rs:198:20\n   |\nLL |     let _ = (0..3).fold(false, |acc: bool, x| acc || test_expr!(x));\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| test_expr!(x))`\n   |\n   = note: the `any` method is short circuiting and may change the program semantics if the iterator has side effects\n\nerror: aborting due to 41 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_get_then_check.fixed",
    "content": "#![warn(clippy::unnecessary_get_then_check)]\n\nuse std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};\n\nfn main() {\n    let s: HashSet<String> = HashSet::new();\n    let _ = s.contains(\"a\");\n    //~^ unnecessary_get_then_check\n    let _ = !s.contains(\"a\");\n    //~^ unnecessary_get_then_check\n\n    let s: HashMap<String, ()> = HashMap::new();\n    let _ = s.contains_key(\"a\");\n    //~^ unnecessary_get_then_check\n    let _ = !s.contains_key(\"a\");\n    //~^ unnecessary_get_then_check\n\n    let s: BTreeSet<String> = BTreeSet::new();\n    let _ = s.contains(\"a\");\n    //~^ unnecessary_get_then_check\n    let _ = !s.contains(\"a\");\n    //~^ unnecessary_get_then_check\n\n    let s: BTreeMap<String, ()> = BTreeMap::new();\n    let _ = s.contains_key(\"a\");\n    //~^ unnecessary_get_then_check\n    let _ = !s.contains_key(\"a\");\n    //~^ unnecessary_get_then_check\n\n    // Import to check that the generic annotations are kept!\n    let s: HashSet<String> = HashSet::new();\n    let _ = s.contains::<str>(\"a\");\n    //~^ unnecessary_get_then_check\n    let _ = !s.contains::<str>(\"a\");\n    //~^ unnecessary_get_then_check\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_get_then_check.rs",
    "content": "#![warn(clippy::unnecessary_get_then_check)]\n\nuse std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};\n\nfn main() {\n    let s: HashSet<String> = HashSet::new();\n    let _ = s.get(\"a\").is_some();\n    //~^ unnecessary_get_then_check\n    let _ = s.get(\"a\").is_none();\n    //~^ unnecessary_get_then_check\n\n    let s: HashMap<String, ()> = HashMap::new();\n    let _ = s.get(\"a\").is_some();\n    //~^ unnecessary_get_then_check\n    let _ = s.get(\"a\").is_none();\n    //~^ unnecessary_get_then_check\n\n    let s: BTreeSet<String> = BTreeSet::new();\n    let _ = s.get(\"a\").is_some();\n    //~^ unnecessary_get_then_check\n    let _ = s.get(\"a\").is_none();\n    //~^ unnecessary_get_then_check\n\n    let s: BTreeMap<String, ()> = BTreeMap::new();\n    let _ = s.get(\"a\").is_some();\n    //~^ unnecessary_get_then_check\n    let _ = s.get(\"a\").is_none();\n    //~^ unnecessary_get_then_check\n\n    // Import to check that the generic annotations are kept!\n    let s: HashSet<String> = HashSet::new();\n    let _ = s.get::<str>(\"a\").is_some();\n    //~^ unnecessary_get_then_check\n    let _ = s.get::<str>(\"a\").is_none();\n    //~^ unnecessary_get_then_check\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_get_then_check.stderr",
    "content": "error: unnecessary use of `get(\"a\").is_some()`\n  --> tests/ui/unnecessary_get_then_check.rs:7:15\n   |\nLL |     let _ = s.get(\"a\").is_some();\n   |               ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains(\"a\")`\n   |\n   = note: `-D clippy::unnecessary-get-then-check` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_get_then_check)]`\n\nerror: unnecessary use of `get(\"a\").is_none()`\n  --> tests/ui/unnecessary_get_then_check.rs:9:15\n   |\nLL |     let _ = s.get(\"a\").is_none();\n   |             --^^^^^^^^^^^^^^^^^^\n   |             |\n   |             help: replace it with: `!s.contains(\"a\")`\n\nerror: unnecessary use of `get(\"a\").is_some()`\n  --> tests/ui/unnecessary_get_then_check.rs:13:15\n   |\nLL |     let _ = s.get(\"a\").is_some();\n   |               ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key(\"a\")`\n\nerror: unnecessary use of `get(\"a\").is_none()`\n  --> tests/ui/unnecessary_get_then_check.rs:15:15\n   |\nLL |     let _ = s.get(\"a\").is_none();\n   |             --^^^^^^^^^^^^^^^^^^\n   |             |\n   |             help: replace it with: `!s.contains_key(\"a\")`\n\nerror: unnecessary use of `get(\"a\").is_some()`\n  --> tests/ui/unnecessary_get_then_check.rs:19:15\n   |\nLL |     let _ = s.get(\"a\").is_some();\n   |               ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains(\"a\")`\n\nerror: unnecessary use of `get(\"a\").is_none()`\n  --> tests/ui/unnecessary_get_then_check.rs:21:15\n   |\nLL |     let _ = s.get(\"a\").is_none();\n   |             --^^^^^^^^^^^^^^^^^^\n   |             |\n   |             help: replace it with: `!s.contains(\"a\")`\n\nerror: unnecessary use of `get(\"a\").is_some()`\n  --> tests/ui/unnecessary_get_then_check.rs:25:15\n   |\nLL |     let _ = s.get(\"a\").is_some();\n   |               ^^^^^^^^^^^^^^^^^^ help: replace it with: `contains_key(\"a\")`\n\nerror: unnecessary use of `get(\"a\").is_none()`\n  --> tests/ui/unnecessary_get_then_check.rs:27:15\n   |\nLL |     let _ = s.get(\"a\").is_none();\n   |             --^^^^^^^^^^^^^^^^^^\n   |             |\n   |             help: replace it with: `!s.contains_key(\"a\")`\n\nerror: unnecessary use of `get::<str>(\"a\").is_some()`\n  --> tests/ui/unnecessary_get_then_check.rs:32:15\n   |\nLL |     let _ = s.get::<str>(\"a\").is_some();\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `contains::<str>(\"a\")`\n\nerror: unnecessary use of `get::<str>(\"a\").is_none()`\n  --> tests/ui/unnecessary_get_then_check.rs:34:15\n   |\nLL |     let _ = s.get::<str>(\"a\").is_none();\n   |             --^^^^^^^^^^^^^^^^^^^^^^^^^\n   |             |\n   |             help: replace it with: `!s.contains::<str>(\"a\")`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_iter_cloned.fixed",
    "content": "#![allow(unused_assignments, clippy::uninlined_format_args)]\n#![warn(clippy::unnecessary_to_owned)]\n\n#[allow(dead_code)]\n#[derive(Clone, Copy)]\nenum FileType {\n    Account,\n    PrivateKey,\n    Certificate,\n}\n\nfn main() {\n    let path = std::path::Path::new(\"x\");\n\n    let _ = check_files(&[(FileType::Account, path)]);\n    let _ = check_files_vec(vec![(FileType::Account, path)]);\n\n    // negative tests\n    let _ = check_files_ref(&[(FileType::Account, path)]);\n    let _ = check_files_mut(&[(FileType::Account, path)]);\n    let _ = check_files_ref_mut(&[(FileType::Account, path)]);\n    let _ = check_files_self_and_arg(&[(FileType::Account, path)]);\n    let _ = check_files_mut_path_buf(&[(FileType::Account, std::path::PathBuf::new())]);\n\n    check_mut_iteratee_and_modify_inner_variable();\n}\n\n// `check_files` and its variants are based on:\n// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262\nfn check_files(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (t, path) in files {\n        //~^ unnecessary_to_owned\n        let other = match get_file_path(t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool {\n    for (t, path) in files.iter() {\n        //~^ unnecessary_to_owned\n        let other = match get_file_path(t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn check_files_ref(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (ref t, path) in files.iter().copied() {\n        let other = match get_file_path(t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\n#[allow(unused_assignments)]\nfn check_files_mut(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (mut t, path) in files.iter().copied() {\n        t = FileType::PrivateKey;\n        let other = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn check_files_ref_mut(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (ref mut t, path) in files.iter().copied() {\n        *t = FileType::PrivateKey;\n        let other = match get_file_path(t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn check_files_self_and_arg(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (t, path) in files.iter().copied() {\n        let other = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.join(path).is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\n#[allow(unused_assignments)]\nfn check_files_mut_path_buf(files: &[(FileType, std::path::PathBuf)]) -> bool {\n    for (mut t, path) in files.iter().cloned() {\n        t = FileType::PrivateKey;\n        let other = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {\n    Ok(std::path::PathBuf::new())\n}\n\n// Issue 12098\n// https://github.com/rust-lang/rust-clippy/issues/12098\n// no message emits\nfn check_mut_iteratee_and_modify_inner_variable() {\n    struct Test {\n        list: Vec<String>,\n        mut_this: bool,\n    }\n\n    impl Test {\n        fn list(&self) -> &[String] {\n            &self.list\n        }\n    }\n\n    let mut test = Test {\n        list: vec![String::from(\"foo\"), String::from(\"bar\")],\n        mut_this: false,\n    };\n\n    for _item in test.list().to_vec() {\n        println!(\"{}\", _item);\n\n        test.mut_this = true;\n        {\n            test.mut_this = true;\n        }\n    }\n}\n\nmod issue_12821 {\n    fn foo() {\n        let v: Vec<_> = \"hello\".chars().collect();\n        for c in v.iter() {\n            //~^ unnecessary_to_owned\n\n            println!(\"{c}\"); // should not suggest to remove `&`\n        }\n    }\n\n    fn bar() {\n        let v: Vec<_> = \"hello\".chars().collect();\n        for c in v.iter() {\n            //~^ unnecessary_to_owned\n\n            let ref_c = c;\n            println!(\"{ref_c}\");\n        }\n    }\n\n    fn baz() {\n        let v: Vec<_> = \"hello\".chars().enumerate().collect();\n        for (i, c) in v.iter() {\n            //~^ unnecessary_to_owned\n\n            let ref_c = c;\n            let ref_i = i;\n            println!(\"{i} {ref_c}\"); // should not suggest to remove `&` from `i`\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_iter_cloned.rs",
    "content": "#![allow(unused_assignments, clippy::uninlined_format_args)]\n#![warn(clippy::unnecessary_to_owned)]\n\n#[allow(dead_code)]\n#[derive(Clone, Copy)]\nenum FileType {\n    Account,\n    PrivateKey,\n    Certificate,\n}\n\nfn main() {\n    let path = std::path::Path::new(\"x\");\n\n    let _ = check_files(&[(FileType::Account, path)]);\n    let _ = check_files_vec(vec![(FileType::Account, path)]);\n\n    // negative tests\n    let _ = check_files_ref(&[(FileType::Account, path)]);\n    let _ = check_files_mut(&[(FileType::Account, path)]);\n    let _ = check_files_ref_mut(&[(FileType::Account, path)]);\n    let _ = check_files_self_and_arg(&[(FileType::Account, path)]);\n    let _ = check_files_mut_path_buf(&[(FileType::Account, std::path::PathBuf::new())]);\n\n    check_mut_iteratee_and_modify_inner_variable();\n}\n\n// `check_files` and its variants are based on:\n// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262\nfn check_files(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (t, path) in files.iter().copied() {\n        //~^ unnecessary_to_owned\n        let other = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool {\n    for (t, path) in files.iter().copied() {\n        //~^ unnecessary_to_owned\n        let other = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn check_files_ref(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (ref t, path) in files.iter().copied() {\n        let other = match get_file_path(t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\n#[allow(unused_assignments)]\nfn check_files_mut(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (mut t, path) in files.iter().copied() {\n        t = FileType::PrivateKey;\n        let other = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn check_files_ref_mut(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (ref mut t, path) in files.iter().copied() {\n        *t = FileType::PrivateKey;\n        let other = match get_file_path(t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn check_files_self_and_arg(files: &[(FileType, &std::path::Path)]) -> bool {\n    for (t, path) in files.iter().copied() {\n        let other = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.join(path).is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\n#[allow(unused_assignments)]\nfn check_files_mut_path_buf(files: &[(FileType, std::path::PathBuf)]) -> bool {\n    for (mut t, path) in files.iter().cloned() {\n        t = FileType::PrivateKey;\n        let other = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() || !other.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {\n    Ok(std::path::PathBuf::new())\n}\n\n// Issue 12098\n// https://github.com/rust-lang/rust-clippy/issues/12098\n// no message emits\nfn check_mut_iteratee_and_modify_inner_variable() {\n    struct Test {\n        list: Vec<String>,\n        mut_this: bool,\n    }\n\n    impl Test {\n        fn list(&self) -> &[String] {\n            &self.list\n        }\n    }\n\n    let mut test = Test {\n        list: vec![String::from(\"foo\"), String::from(\"bar\")],\n        mut_this: false,\n    };\n\n    for _item in test.list().to_vec() {\n        println!(\"{}\", _item);\n\n        test.mut_this = true;\n        {\n            test.mut_this = true;\n        }\n    }\n}\n\nmod issue_12821 {\n    fn foo() {\n        let v: Vec<_> = \"hello\".chars().collect();\n        for c in v.iter().cloned() {\n            //~^ unnecessary_to_owned\n\n            println!(\"{c}\"); // should not suggest to remove `&`\n        }\n    }\n\n    fn bar() {\n        let v: Vec<_> = \"hello\".chars().collect();\n        for c in v.iter().cloned() {\n            //~^ unnecessary_to_owned\n\n            let ref_c = &c;\n            println!(\"{ref_c}\");\n        }\n    }\n\n    fn baz() {\n        let v: Vec<_> = \"hello\".chars().enumerate().collect();\n        for (i, c) in v.iter().cloned() {\n            //~^ unnecessary_to_owned\n\n            let ref_c = &c;\n            let ref_i = &i;\n            println!(\"{i} {ref_c}\"); // should not suggest to remove `&` from `i`\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_iter_cloned.stderr",
    "content": "error: unnecessary use of `copied`\n  --> tests/ui/unnecessary_iter_cloned.rs:31:22\n   |\nLL |     for (t, path) in files.iter().copied() {\n   |                      ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`\nhelp: remove any references to the binding\n   |\nLL ~     for (t, path) in files {\nLL |\nLL ~         let other = match get_file_path(t) {\n   |\n\nerror: unnecessary use of `copied`\n  --> tests/ui/unnecessary_iter_cloned.rs:47:22\n   |\nLL |     for (t, path) in files.iter().copied() {\n   |                      ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove any references to the binding\n   |\nLL ~     for (t, path) in files.iter() {\nLL |\nLL ~         let other = match get_file_path(t) {\n   |\n\nerror: unnecessary use of `cloned`\n  --> tests/ui/unnecessary_iter_cloned.rs:179:18\n   |\nLL |         for c in v.iter().cloned() {\n   |                  ^^^^^^^^^^^^^^^^^\n   |\nhelp: remove any references to the binding\n   |\nLL -         for c in v.iter().cloned() {\nLL +         for c in v.iter() {\n   |\n\nerror: unnecessary use of `cloned`\n  --> tests/ui/unnecessary_iter_cloned.rs:188:18\n   |\nLL |         for c in v.iter().cloned() {\n   |                  ^^^^^^^^^^^^^^^^^\n   |\nhelp: remove any references to the binding\n   |\nLL ~         for c in v.iter() {\nLL |\nLL |\nLL ~             let ref_c = c;\n   |\n\nerror: unnecessary use of `cloned`\n  --> tests/ui/unnecessary_iter_cloned.rs:198:23\n   |\nLL |         for (i, c) in v.iter().cloned() {\n   |                       ^^^^^^^^^^^^^^^^^\n   |\nhelp: remove any references to the binding\n   |\nLL ~         for (i, c) in v.iter() {\nLL |\nLL |\nLL ~             let ref_c = c;\nLL ~             let ref_i = i;\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_join.fixed",
    "content": "#![warn(clippy::unnecessary_join)]\n#![allow(clippy::uninlined_format_args, clippy::useless_vec)]\n\nfn main() {\n    // should be linted\n    let vector = vec![\"hello\", \"world\"];\n    let output = vector\n        .iter()\n        .map(|item| item.to_uppercase())\n        .collect::<String>();\n    println!(\"{}\", output);\n\n    // should be linted\n    let vector = vec![\"hello\", \"world\"];\n    let output = vector\n        .iter()\n        .map(|item| item.to_uppercase())\n        .collect::<String>();\n    println!(\"{}\", output);\n\n    // should not be linted\n    let vector = vec![\"hello\", \"world\"];\n    let output = vector\n        .iter()\n        .map(|item| item.to_uppercase())\n        .collect::<Vec<String>>()\n        .join(\"\\n\");\n    println!(\"{}\", output);\n\n    // should not be linted\n    let vector = vec![\"hello\", \"world\"];\n    let output = vector.iter().map(|item| item.to_uppercase()).collect::<String>();\n    println!(\"{}\", output);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_join.rs",
    "content": "#![warn(clippy::unnecessary_join)]\n#![allow(clippy::uninlined_format_args, clippy::useless_vec)]\n\nfn main() {\n    // should be linted\n    let vector = vec![\"hello\", \"world\"];\n    let output = vector\n        .iter()\n        .map(|item| item.to_uppercase())\n        .collect::<Vec<String>>()\n        //~^ unnecessary_join\n        .join(\"\");\n    println!(\"{}\", output);\n\n    // should be linted\n    let vector = vec![\"hello\", \"world\"];\n    let output = vector\n        .iter()\n        .map(|item| item.to_uppercase())\n        .collect::<Vec<_>>()\n        //~^ unnecessary_join\n        .join(\"\");\n    println!(\"{}\", output);\n\n    // should not be linted\n    let vector = vec![\"hello\", \"world\"];\n    let output = vector\n        .iter()\n        .map(|item| item.to_uppercase())\n        .collect::<Vec<String>>()\n        .join(\"\\n\");\n    println!(\"{}\", output);\n\n    // should not be linted\n    let vector = vec![\"hello\", \"world\"];\n    let output = vector.iter().map(|item| item.to_uppercase()).collect::<String>();\n    println!(\"{}\", output);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_join.stderr",
    "content": "error: called `.collect::<Vec<String>>().join(\"\")` on an iterator\n  --> tests/ui/unnecessary_join.rs:10:10\n   |\nLL |           .collect::<Vec<String>>()\n   |  __________^\nLL | |\nLL | |         .join(\"\");\n   | |_________________^ help: consider using: `collect::<String>()`\n   |\n   = note: `-D clippy::unnecessary-join` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_join)]`\n\nerror: called `.collect::<Vec<String>>().join(\"\")` on an iterator\n  --> tests/ui/unnecessary_join.rs:20:10\n   |\nLL |           .collect::<Vec<_>>()\n   |  __________^\nLL | |\nLL | |         .join(\"\");\n   | |_________________^ help: consider using: `collect::<String>()`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_lazy_eval.fixed",
    "content": "//@aux-build: proc_macros.rs\n#![warn(clippy::unnecessary_lazy_evaluations)]\n#![allow(clippy::redundant_closure)]\n#![allow(clippy::bind_instead_of_map)]\n#![allow(clippy::map_identity)]\n#![allow(clippy::needless_borrow)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n#![allow(clippy::unit_arg)]\n#![allow(arithmetic_overflow)]\n#![allow(unconditional_panic)]\n\nuse std::ops::Deref;\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nstruct Deep(Option<usize>);\n\n#[derive(Copy, Clone)]\nstruct SomeStruct {\n    some_field: usize,\n}\n\nimpl SomeStruct {\n    fn return_some_field(&self) -> usize {\n        self.some_field\n    }\n}\n\nfn some_call<T: Default>() -> T {\n    T::default()\n}\n\nstruct Issue9427(i32);\n\nimpl Drop for Issue9427 {\n    fn drop(&mut self) {\n        println!(\"{}\", self.0);\n    }\n}\n\nstruct Issue9427FollowUp;\n\nimpl Drop for Issue9427FollowUp {\n    fn drop(&mut self) {\n        panic!(\"side effect drop\");\n    }\n}\n\nstruct Issue9427Followup2 {\n    ptr: *const (),\n}\nimpl Issue9427Followup2 {\n    fn from_owned(ptr: *const ()) -> Option<Self> {\n        (!ptr.is_null()).then(|| Self { ptr })\n    }\n}\nimpl Drop for Issue9427Followup2 {\n    fn drop(&mut self) {}\n}\n\nstruct Issue10437;\nimpl Deref for Issue10437 {\n    type Target = u32;\n    fn deref(&self) -> &Self::Target {\n        println!(\"side effect deref\");\n        &0\n    }\n}\n\nfn main() {\n    let astronomers_pi = 10;\n    let ext_arr: [usize; 1] = [2];\n    let ext_str = SomeStruct { some_field: 10 };\n\n    let mut opt = Some(42);\n    let ext_opt = Some(42);\n    let nested_opt = Some(Some(42));\n    let nested_tuple_opt = Some(Some((42, 43)));\n    let cond = true;\n\n    // Should lint - Option\n    let _ = opt.unwrap_or(2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.unwrap_or(astronomers_pi);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.unwrap_or(ext_str.some_field);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.unwrap_or_else(|| ext_arr[0]);\n    let _ = opt.and(ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.or(ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.or(None);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.get_or_insert(2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.ok_or(2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = nested_tuple_opt.unwrap_or(Some((1, 2)));\n    //~^ unnecessary_lazy_evaluations\n    let _ = cond.then_some(astronomers_pi);\n    //~^ unnecessary_lazy_evaluations\n    let _ = true.then_some({});\n    //~^ unnecessary_lazy_evaluations\n    let _ = true.then_some({});\n    //~^ unnecessary_lazy_evaluations\n\n    // Should lint - Builtin deref\n    let r = &1;\n    let _ = Some(1).unwrap_or(*r);\n    //~^ unnecessary_lazy_evaluations\n    let b = Box::new(1);\n    let _ = Some(1).unwrap_or(*b);\n    //~^ unnecessary_lazy_evaluations\n    // Should lint - Builtin deref through autoderef\n    let _ = Some(1).as_ref().unwrap_or(&r);\n    //~^ unnecessary_lazy_evaluations\n    let _ = Some(1).as_ref().unwrap_or(&b);\n    //~^ unnecessary_lazy_evaluations\n\n    // Cases when unwrap is not called on a simple variable\n    let _ = Some(10).unwrap_or(2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = Some(10).and(ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _: Option<usize> = None.or(ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _ = None.get_or_insert(2);\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = None.ok_or(2);\n    //~^ unnecessary_lazy_evaluations\n    let _: Option<usize> = None.or(None);\n    //~^ unnecessary_lazy_evaluations\n\n    let mut deep = Deep(Some(42));\n    let _ = deep.0.unwrap_or(2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.and(ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.or(None);\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.get_or_insert(2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.ok_or(2);\n    //~^ unnecessary_lazy_evaluations\n\n    // Should not lint - Option\n    let _ = opt.unwrap_or_else(|| ext_str.return_some_field());\n    let _ = nested_opt.unwrap_or_else(|| Some(some_call()));\n    let _ = nested_tuple_opt.unwrap_or_else(|| Some((some_call(), some_call())));\n    let _ = opt.or_else(some_call);\n    let _ = opt.or_else(|| some_call());\n    let _: Result<usize, usize> = opt.ok_or_else(|| some_call());\n    let _: Result<usize, usize> = opt.ok_or_else(some_call);\n    let _ = deep.0.get_or_insert_with(|| some_call());\n    let _ = deep.0.or_else(some_call);\n    let _ = deep.0.or_else(|| some_call());\n    let _ = opt.ok_or_else(|| ext_arr[0]);\n\n    let _ = Some(1).unwrap_or_else(|| *Issue10437); // Issue10437 has a deref impl\n    let _ = Some(1).unwrap_or(*Issue10437);\n\n    let _ = Some(1).as_ref().unwrap_or_else(|| &Issue10437);\n    let _ = Some(1).as_ref().unwrap_or(&Issue10437);\n\n    // Should not lint - bool\n    let _ = (0 == 1).then(|| Issue9427(0)); // Issue9427 has a significant drop\n    let _ = false.then(|| Issue9427FollowUp); // Issue9427FollowUp has a significant drop\n    let _ = false.then(|| Issue9427Followup2 { ptr: std::ptr::null() });\n\n    // should not lint, bind_instead_of_map takes priority\n    let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));\n    let _ = Some(10).and_then(|idx| Some(idx));\n\n    // should lint, bind_instead_of_map doesn't apply\n    let _: Option<usize> = None.or(Some(3));\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.or(Some(3));\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.or(Some(3));\n    //~^ unnecessary_lazy_evaluations\n\n    // Should lint - Result\n    let res: Result<usize, usize> = Err(5);\n    let res2: Result<usize, SomeStruct> = Err(SomeStruct { some_field: 5 });\n\n    let _ = res2.unwrap_or(2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = res2.unwrap_or(astronomers_pi);\n    //~^ unnecessary_lazy_evaluations\n    let _ = res2.unwrap_or(ext_str.some_field);\n    //~^ unnecessary_lazy_evaluations\n\n    // Should not lint - Result\n    let _ = res.unwrap_or_else(|err| err);\n    let _ = res.unwrap_or_else(|err| ext_arr[err]);\n    let _ = res2.unwrap_or_else(|err| err.some_field);\n    let _ = res2.unwrap_or_else(|err| err.return_some_field());\n    let _ = res2.unwrap_or_else(|_| ext_str.return_some_field());\n\n    // should not lint, bind_instead_of_map takes priority\n    let _: Result<usize, usize> = res.and_then(|x| Ok(x));\n    let _: Result<usize, usize> = res.or_else(|err| Err(err));\n\n    let _: Result<usize, usize> = res.and_then(|_| Ok(2));\n    let _: Result<usize, usize> = res.and_then(|_| Ok(astronomers_pi));\n    let _: Result<usize, usize> = res.and_then(|_| Ok(ext_str.some_field));\n\n    let _: Result<usize, usize> = res.or_else(|_| Err(2));\n    let _: Result<usize, usize> = res.or_else(|_| Err(astronomers_pi));\n    let _: Result<usize, usize> = res.or_else(|_| Err(ext_str.some_field));\n\n    // should lint, bind_instead_of_map doesn't apply\n    let _: Result<usize, usize> = res.and(Err(2));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.and(Err(astronomers_pi));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.and(Err(ext_str.some_field));\n    //~^ unnecessary_lazy_evaluations\n\n    let _: Result<usize, usize> = res.or(Ok(2));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.or(Ok(astronomers_pi));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.\n    //~^ unnecessary_lazy_evaluations\n    // some lines\n    // some lines\n    // some lines\n    // some lines\n    // some lines\n    // some lines\n    or(Ok(ext_str.some_field));\n\n    // neither bind_instead_of_map nor unnecessary_lazy_eval applies here\n    let _: Result<usize, usize> = res.and_then(|x| Err(x));\n    let _: Result<usize, usize> = res.or_else(|err| Ok(err));\n}\n\n#[allow(unused)]\nfn issue9485() {\n    // should not lint, is in proc macro\n    with_span!(span Some(42).unwrap_or_else(|| 2););\n}\n\nfn issue9422(x: usize) -> Option<usize> {\n    (x >= 5).then(|| x - 5)\n    // (x >= 5).then_some(x - 5)  // clippy suggestion panics\n}\n\nfn panicky_arithmetic_ops(x: usize, y: isize) {\n    #![allow(clippy::identity_op, clippy::eq_op)]\n\n    // See comments in `eager_or_lazy.rs` for the rules that this is meant to follow\n\n    let _x = false.then_some(i32::MAX + 1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(i32::MAX * 2);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(i32::MAX - 1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(i32::MIN - 1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(255u8 << 7);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(255u8 << 8);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(255u8 >> 8);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 255u8 >> x);\n    let _x = false.then_some(i32::MAX + -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(-i32::MAX);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(-i32::MIN);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| -y);\n    let _x = false.then_some(255 >> -7);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(255 << -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(1 / 0);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(x << -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(x << 2);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| x + x);\n    let _x = false.then(|| x * x);\n    let _x = false.then(|| x - x);\n    let _x = false.then(|| x / x);\n    let _x = false.then(|| x % x);\n    let _x = false.then(|| x + 1);\n    let _x = false.then(|| 1 + x);\n\n    let _x = false.then_some(x / 0);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(x % 0);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| y / -1);\n    let _x = false.then_some(1 / -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(i32::MIN / -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| i32::MIN / x as i32);\n    let _x = false.then_some(i32::MIN / 0);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then_some(4 / 2);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 1 / x);\n\n    // const eval doesn't read variables, but floating point math never panics, so we can still emit a\n    // warning\n    let f1 = 1.0;\n    let f2 = 2.0;\n    let _x = false.then_some(f1 + f2);\n    //~^ unnecessary_lazy_evaluations\n}\n\nfn issue14578() {\n    let _: Box<dyn std::future::Future<Output = i32>> = Box::new(true.then(async || 42).unwrap());\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_lazy_eval.rs",
    "content": "//@aux-build: proc_macros.rs\n#![warn(clippy::unnecessary_lazy_evaluations)]\n#![allow(clippy::redundant_closure)]\n#![allow(clippy::bind_instead_of_map)]\n#![allow(clippy::map_identity)]\n#![allow(clippy::needless_borrow)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n#![allow(clippy::unit_arg)]\n#![allow(arithmetic_overflow)]\n#![allow(unconditional_panic)]\n\nuse std::ops::Deref;\n\nextern crate proc_macros;\nuse proc_macros::with_span;\n\nstruct Deep(Option<usize>);\n\n#[derive(Copy, Clone)]\nstruct SomeStruct {\n    some_field: usize,\n}\n\nimpl SomeStruct {\n    fn return_some_field(&self) -> usize {\n        self.some_field\n    }\n}\n\nfn some_call<T: Default>() -> T {\n    T::default()\n}\n\nstruct Issue9427(i32);\n\nimpl Drop for Issue9427 {\n    fn drop(&mut self) {\n        println!(\"{}\", self.0);\n    }\n}\n\nstruct Issue9427FollowUp;\n\nimpl Drop for Issue9427FollowUp {\n    fn drop(&mut self) {\n        panic!(\"side effect drop\");\n    }\n}\n\nstruct Issue9427Followup2 {\n    ptr: *const (),\n}\nimpl Issue9427Followup2 {\n    fn from_owned(ptr: *const ()) -> Option<Self> {\n        (!ptr.is_null()).then(|| Self { ptr })\n    }\n}\nimpl Drop for Issue9427Followup2 {\n    fn drop(&mut self) {}\n}\n\nstruct Issue10437;\nimpl Deref for Issue10437 {\n    type Target = u32;\n    fn deref(&self) -> &Self::Target {\n        println!(\"side effect deref\");\n        &0\n    }\n}\n\nfn main() {\n    let astronomers_pi = 10;\n    let ext_arr: [usize; 1] = [2];\n    let ext_str = SomeStruct { some_field: 10 };\n\n    let mut opt = Some(42);\n    let ext_opt = Some(42);\n    let nested_opt = Some(Some(42));\n    let nested_tuple_opt = Some(Some((42, 43)));\n    let cond = true;\n\n    // Should lint - Option\n    let _ = opt.unwrap_or_else(|| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.unwrap_or_else(|| astronomers_pi);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.unwrap_or_else(|| ext_str.some_field);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.unwrap_or_else(|| ext_arr[0]);\n    let _ = opt.and_then(|_| ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.or_else(|| ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.or_else(|| None);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.get_or_insert_with(|| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.ok_or_else(|| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));\n    //~^ unnecessary_lazy_evaluations\n    let _ = cond.then(|| astronomers_pi);\n    //~^ unnecessary_lazy_evaluations\n    let _ = true.then(|| -> _ {});\n    //~^ unnecessary_lazy_evaluations\n    let _ = true.then(|| {});\n    //~^ unnecessary_lazy_evaluations\n\n    // Should lint - Builtin deref\n    let r = &1;\n    let _ = Some(1).unwrap_or_else(|| *r);\n    //~^ unnecessary_lazy_evaluations\n    let b = Box::new(1);\n    let _ = Some(1).unwrap_or_else(|| *b);\n    //~^ unnecessary_lazy_evaluations\n    // Should lint - Builtin deref through autoderef\n    let _ = Some(1).as_ref().unwrap_or_else(|| &r);\n    //~^ unnecessary_lazy_evaluations\n    let _ = Some(1).as_ref().unwrap_or_else(|| &b);\n    //~^ unnecessary_lazy_evaluations\n\n    // Cases when unwrap is not called on a simple variable\n    let _ = Some(10).unwrap_or_else(|| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = Some(10).and_then(|_| ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _: Option<usize> = None.or_else(|| ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _ = None.get_or_insert_with(|| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = None.ok_or_else(|| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _: Option<usize> = None.or_else(|| None);\n    //~^ unnecessary_lazy_evaluations\n\n    let mut deep = Deep(Some(42));\n    let _ = deep.0.unwrap_or_else(|| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.and_then(|_| ext_opt);\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.or_else(|| None);\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.get_or_insert_with(|| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.ok_or_else(|| 2);\n    //~^ unnecessary_lazy_evaluations\n\n    // Should not lint - Option\n    let _ = opt.unwrap_or_else(|| ext_str.return_some_field());\n    let _ = nested_opt.unwrap_or_else(|| Some(some_call()));\n    let _ = nested_tuple_opt.unwrap_or_else(|| Some((some_call(), some_call())));\n    let _ = opt.or_else(some_call);\n    let _ = opt.or_else(|| some_call());\n    let _: Result<usize, usize> = opt.ok_or_else(|| some_call());\n    let _: Result<usize, usize> = opt.ok_or_else(some_call);\n    let _ = deep.0.get_or_insert_with(|| some_call());\n    let _ = deep.0.or_else(some_call);\n    let _ = deep.0.or_else(|| some_call());\n    let _ = opt.ok_or_else(|| ext_arr[0]);\n\n    let _ = Some(1).unwrap_or_else(|| *Issue10437); // Issue10437 has a deref impl\n    let _ = Some(1).unwrap_or(*Issue10437);\n\n    let _ = Some(1).as_ref().unwrap_or_else(|| &Issue10437);\n    let _ = Some(1).as_ref().unwrap_or(&Issue10437);\n\n    // Should not lint - bool\n    let _ = (0 == 1).then(|| Issue9427(0)); // Issue9427 has a significant drop\n    let _ = false.then(|| Issue9427FollowUp); // Issue9427FollowUp has a significant drop\n    let _ = false.then(|| Issue9427Followup2 { ptr: std::ptr::null() });\n\n    // should not lint, bind_instead_of_map takes priority\n    let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));\n    let _ = Some(10).and_then(|idx| Some(idx));\n\n    // should lint, bind_instead_of_map doesn't apply\n    let _: Option<usize> = None.or_else(|| Some(3));\n    //~^ unnecessary_lazy_evaluations\n    let _ = deep.0.or_else(|| Some(3));\n    //~^ unnecessary_lazy_evaluations\n    let _ = opt.or_else(|| Some(3));\n    //~^ unnecessary_lazy_evaluations\n\n    // Should lint - Result\n    let res: Result<usize, usize> = Err(5);\n    let res2: Result<usize, SomeStruct> = Err(SomeStruct { some_field: 5 });\n\n    let _ = res2.unwrap_or_else(|_| 2);\n    //~^ unnecessary_lazy_evaluations\n    let _ = res2.unwrap_or_else(|_| astronomers_pi);\n    //~^ unnecessary_lazy_evaluations\n    let _ = res2.unwrap_or_else(|_| ext_str.some_field);\n    //~^ unnecessary_lazy_evaluations\n\n    // Should not lint - Result\n    let _ = res.unwrap_or_else(|err| err);\n    let _ = res.unwrap_or_else(|err| ext_arr[err]);\n    let _ = res2.unwrap_or_else(|err| err.some_field);\n    let _ = res2.unwrap_or_else(|err| err.return_some_field());\n    let _ = res2.unwrap_or_else(|_| ext_str.return_some_field());\n\n    // should not lint, bind_instead_of_map takes priority\n    let _: Result<usize, usize> = res.and_then(|x| Ok(x));\n    let _: Result<usize, usize> = res.or_else(|err| Err(err));\n\n    let _: Result<usize, usize> = res.and_then(|_| Ok(2));\n    let _: Result<usize, usize> = res.and_then(|_| Ok(astronomers_pi));\n    let _: Result<usize, usize> = res.and_then(|_| Ok(ext_str.some_field));\n\n    let _: Result<usize, usize> = res.or_else(|_| Err(2));\n    let _: Result<usize, usize> = res.or_else(|_| Err(astronomers_pi));\n    let _: Result<usize, usize> = res.or_else(|_| Err(ext_str.some_field));\n\n    // should lint, bind_instead_of_map doesn't apply\n    let _: Result<usize, usize> = res.and_then(|_| Err(2));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));\n    //~^ unnecessary_lazy_evaluations\n\n    let _: Result<usize, usize> = res.or_else(|_| Ok(2));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));\n    //~^ unnecessary_lazy_evaluations\n    let _: Result<usize, usize> = res.\n    //~^ unnecessary_lazy_evaluations\n    // some lines\n    // some lines\n    // some lines\n    // some lines\n    // some lines\n    // some lines\n    or_else(|_| Ok(ext_str.some_field));\n\n    // neither bind_instead_of_map nor unnecessary_lazy_eval applies here\n    let _: Result<usize, usize> = res.and_then(|x| Err(x));\n    let _: Result<usize, usize> = res.or_else(|err| Ok(err));\n}\n\n#[allow(unused)]\nfn issue9485() {\n    // should not lint, is in proc macro\n    with_span!(span Some(42).unwrap_or_else(|| 2););\n}\n\nfn issue9422(x: usize) -> Option<usize> {\n    (x >= 5).then(|| x - 5)\n    // (x >= 5).then_some(x - 5)  // clippy suggestion panics\n}\n\nfn panicky_arithmetic_ops(x: usize, y: isize) {\n    #![allow(clippy::identity_op, clippy::eq_op)]\n\n    // See comments in `eager_or_lazy.rs` for the rules that this is meant to follow\n\n    let _x = false.then(|| i32::MAX + 1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| i32::MAX * 2);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| i32::MAX - 1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| i32::MIN - 1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 255u8 << 7);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 255u8 << 8);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 255u8 >> 8);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 255u8 >> x);\n    let _x = false.then(|| i32::MAX + -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| -i32::MAX);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| -i32::MIN);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| -y);\n    let _x = false.then(|| 255 >> -7);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 255 << -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 1 / 0);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| x << -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| x << 2);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| x + x);\n    let _x = false.then(|| x * x);\n    let _x = false.then(|| x - x);\n    let _x = false.then(|| x / x);\n    let _x = false.then(|| x % x);\n    let _x = false.then(|| x + 1);\n    let _x = false.then(|| 1 + x);\n\n    let _x = false.then(|| x / 0);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| x % 0);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| y / -1);\n    let _x = false.then(|| 1 / -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| i32::MIN / -1);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| i32::MIN / x as i32);\n    let _x = false.then(|| i32::MIN / 0);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 4 / 2);\n    //~^ unnecessary_lazy_evaluations\n    let _x = false.then(|| 1 / x);\n\n    // const eval doesn't read variables, but floating point math never panics, so we can still emit a\n    // warning\n    let f1 = 1.0;\n    let f2 = 2.0;\n    let _x = false.then(|| f1 + f2);\n    //~^ unnecessary_lazy_evaluations\n}\n\nfn issue14578() {\n    let _: Box<dyn std::future::Future<Output = i32>> = Box::new(true.then(async || 42).unwrap());\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_lazy_eval.stderr",
    "content": "error: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:83:13\n   |\nLL |     let _ = opt.unwrap_or_else(|| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = opt.unwrap_or_else(|| 2);\nLL +     let _ = opt.unwrap_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:85:13\n   |\nLL |     let _ = opt.unwrap_or_else(|| astronomers_pi);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = opt.unwrap_or_else(|| astronomers_pi);\nLL +     let _ = opt.unwrap_or(astronomers_pi);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:87:13\n   |\nLL |     let _ = opt.unwrap_or_else(|| ext_str.some_field);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = opt.unwrap_or_else(|| ext_str.some_field);\nLL +     let _ = opt.unwrap_or(ext_str.some_field);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:90:13\n   |\nLL |     let _ = opt.and_then(|_| ext_opt);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `and` instead\n   |\nLL -     let _ = opt.and_then(|_| ext_opt);\nLL +     let _ = opt.and(ext_opt);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:92:13\n   |\nLL |     let _ = opt.or_else(|| ext_opt);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _ = opt.or_else(|| ext_opt);\nLL +     let _ = opt.or(ext_opt);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:94:13\n   |\nLL |     let _ = opt.or_else(|| None);\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _ = opt.or_else(|| None);\nLL +     let _ = opt.or(None);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:96:13\n   |\nLL |     let _ = opt.get_or_insert_with(|| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `get_or_insert` instead\n   |\nLL -     let _ = opt.get_or_insert_with(|| 2);\nLL +     let _ = opt.get_or_insert(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:98:13\n   |\nLL |     let _ = opt.ok_or_else(|| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `ok_or` instead\n   |\nLL -     let _ = opt.ok_or_else(|| 2);\nLL +     let _ = opt.ok_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:100:13\n   |\nLL |     let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));\nLL +     let _ = nested_tuple_opt.unwrap_or(Some((1, 2)));\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:102:13\n   |\nLL |     let _ = cond.then(|| astronomers_pi);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _ = cond.then(|| astronomers_pi);\nLL +     let _ = cond.then_some(astronomers_pi);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:104:13\n   |\nLL |     let _ = true.then(|| -> _ {});\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _ = true.then(|| -> _ {});\nLL +     let _ = true.then_some({});\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:106:13\n   |\nLL |     let _ = true.then(|| {});\n   |             ^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _ = true.then(|| {});\nLL +     let _ = true.then_some({});\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:111:13\n   |\nLL |     let _ = Some(1).unwrap_or_else(|| *r);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = Some(1).unwrap_or_else(|| *r);\nLL +     let _ = Some(1).unwrap_or(*r);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:114:13\n   |\nLL |     let _ = Some(1).unwrap_or_else(|| *b);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = Some(1).unwrap_or_else(|| *b);\nLL +     let _ = Some(1).unwrap_or(*b);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:117:13\n   |\nLL |     let _ = Some(1).as_ref().unwrap_or_else(|| &r);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = Some(1).as_ref().unwrap_or_else(|| &r);\nLL +     let _ = Some(1).as_ref().unwrap_or(&r);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:119:13\n   |\nLL |     let _ = Some(1).as_ref().unwrap_or_else(|| &b);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = Some(1).as_ref().unwrap_or_else(|| &b);\nLL +     let _ = Some(1).as_ref().unwrap_or(&b);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:123:13\n   |\nLL |     let _ = Some(10).unwrap_or_else(|| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = Some(10).unwrap_or_else(|| 2);\nLL +     let _ = Some(10).unwrap_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:125:13\n   |\nLL |     let _ = Some(10).and_then(|_| ext_opt);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `and` instead\n   |\nLL -     let _ = Some(10).and_then(|_| ext_opt);\nLL +     let _ = Some(10).and(ext_opt);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:127:28\n   |\nLL |     let _: Option<usize> = None.or_else(|| ext_opt);\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _: Option<usize> = None.or_else(|| ext_opt);\nLL +     let _: Option<usize> = None.or(ext_opt);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:129:13\n   |\nLL |     let _ = None.get_or_insert_with(|| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `get_or_insert` instead\n   |\nLL -     let _ = None.get_or_insert_with(|| 2);\nLL +     let _ = None.get_or_insert(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:131:35\n   |\nLL |     let _: Result<usize, usize> = None.ok_or_else(|| 2);\n   |                                   ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `ok_or` instead\n   |\nLL -     let _: Result<usize, usize> = None.ok_or_else(|| 2);\nLL +     let _: Result<usize, usize> = None.ok_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:133:28\n   |\nLL |     let _: Option<usize> = None.or_else(|| None);\n   |                            ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _: Option<usize> = None.or_else(|| None);\nLL +     let _: Option<usize> = None.or(None);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:137:13\n   |\nLL |     let _ = deep.0.unwrap_or_else(|| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = deep.0.unwrap_or_else(|| 2);\nLL +     let _ = deep.0.unwrap_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:139:13\n   |\nLL |     let _ = deep.0.and_then(|_| ext_opt);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `and` instead\n   |\nLL -     let _ = deep.0.and_then(|_| ext_opt);\nLL +     let _ = deep.0.and(ext_opt);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:141:13\n   |\nLL |     let _ = deep.0.or_else(|| None);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _ = deep.0.or_else(|| None);\nLL +     let _ = deep.0.or(None);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:143:13\n   |\nLL |     let _ = deep.0.get_or_insert_with(|| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `get_or_insert` instead\n   |\nLL -     let _ = deep.0.get_or_insert_with(|| 2);\nLL +     let _ = deep.0.get_or_insert(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:145:13\n   |\nLL |     let _ = deep.0.ok_or_else(|| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `ok_or` instead\n   |\nLL -     let _ = deep.0.ok_or_else(|| 2);\nLL +     let _ = deep.0.ok_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:177:28\n   |\nLL |     let _: Option<usize> = None.or_else(|| Some(3));\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _: Option<usize> = None.or_else(|| Some(3));\nLL +     let _: Option<usize> = None.or(Some(3));\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:179:13\n   |\nLL |     let _ = deep.0.or_else(|| Some(3));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _ = deep.0.or_else(|| Some(3));\nLL +     let _ = deep.0.or(Some(3));\n   |\n\nerror: unnecessary closure used to substitute value for `Option::None`\n  --> tests/ui/unnecessary_lazy_eval.rs:181:13\n   |\nLL |     let _ = opt.or_else(|| Some(3));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _ = opt.or_else(|| Some(3));\nLL +     let _ = opt.or(Some(3));\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:188:13\n   |\nLL |     let _ = res2.unwrap_or_else(|_| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = res2.unwrap_or_else(|_| 2);\nLL +     let _ = res2.unwrap_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:190:13\n   |\nLL |     let _ = res2.unwrap_or_else(|_| astronomers_pi);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = res2.unwrap_or_else(|_| astronomers_pi);\nLL +     let _ = res2.unwrap_or(astronomers_pi);\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:192:13\n   |\nLL |     let _ = res2.unwrap_or_else(|_| ext_str.some_field);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = res2.unwrap_or_else(|_| ext_str.some_field);\nLL +     let _ = res2.unwrap_or(ext_str.some_field);\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:215:35\n   |\nLL |     let _: Result<usize, usize> = res.and_then(|_| Err(2));\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `and` instead\n   |\nLL -     let _: Result<usize, usize> = res.and_then(|_| Err(2));\nLL +     let _: Result<usize, usize> = res.and(Err(2));\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:217:35\n   |\nLL |     let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `and` instead\n   |\nLL -     let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));\nLL +     let _: Result<usize, usize> = res.and(Err(astronomers_pi));\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:219:35\n   |\nLL |     let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `and` instead\n   |\nLL -     let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));\nLL +     let _: Result<usize, usize> = res.and(Err(ext_str.some_field));\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:222:35\n   |\nLL |     let _: Result<usize, usize> = res.or_else(|_| Ok(2));\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _: Result<usize, usize> = res.or_else(|_| Ok(2));\nLL +     let _: Result<usize, usize> = res.or(Ok(2));\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:224:35\n   |\nLL |     let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));\nLL +     let _: Result<usize, usize> = res.or(Ok(astronomers_pi));\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:226:35\n   |\nLL |     let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `or` instead\n   |\nLL -     let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));\nLL +     let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval.rs:228:35\n   |\nLL |       let _: Result<usize, usize> = res.\n   |  ___________________________________^\n...  |\nLL | |     or_else(|_| Ok(ext_str.some_field));\n   | |_______________________________________^\n   |\nhelp: use `or` instead\n   |\nLL -     or_else(|_| Ok(ext_str.some_field));\nLL +     or(Ok(ext_str.some_field));\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:259:14\n   |\nLL |     let _x = false.then(|| i32::MAX + 1);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| i32::MAX + 1);\nLL +     let _x = false.then_some(i32::MAX + 1);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:261:14\n   |\nLL |     let _x = false.then(|| i32::MAX * 2);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| i32::MAX * 2);\nLL +     let _x = false.then_some(i32::MAX * 2);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:263:14\n   |\nLL |     let _x = false.then(|| i32::MAX - 1);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| i32::MAX - 1);\nLL +     let _x = false.then_some(i32::MAX - 1);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:265:14\n   |\nLL |     let _x = false.then(|| i32::MIN - 1);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| i32::MIN - 1);\nLL +     let _x = false.then_some(i32::MIN - 1);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:267:14\n   |\nLL |     let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);\nLL +     let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:269:14\n   |\nLL |     let _x = false.then(|| 255u8 << 7);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| 255u8 << 7);\nLL +     let _x = false.then_some(255u8 << 7);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:271:14\n   |\nLL |     let _x = false.then(|| 255u8 << 8);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| 255u8 << 8);\nLL +     let _x = false.then_some(255u8 << 8);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:273:14\n   |\nLL |     let _x = false.then(|| 255u8 >> 8);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| 255u8 >> 8);\nLL +     let _x = false.then_some(255u8 >> 8);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:276:14\n   |\nLL |     let _x = false.then(|| i32::MAX + -1);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| i32::MAX + -1);\nLL +     let _x = false.then_some(i32::MAX + -1);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:278:14\n   |\nLL |     let _x = false.then(|| -i32::MAX);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| -i32::MAX);\nLL +     let _x = false.then_some(-i32::MAX);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:280:14\n   |\nLL |     let _x = false.then(|| -i32::MIN);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| -i32::MIN);\nLL +     let _x = false.then_some(-i32::MIN);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:283:14\n   |\nLL |     let _x = false.then(|| 255 >> -7);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| 255 >> -7);\nLL +     let _x = false.then_some(255 >> -7);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:285:14\n   |\nLL |     let _x = false.then(|| 255 << -1);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| 255 << -1);\nLL +     let _x = false.then_some(255 << -1);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:287:14\n   |\nLL |     let _x = false.then(|| 1 / 0);\n   |              ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| 1 / 0);\nLL +     let _x = false.then_some(1 / 0);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:289:14\n   |\nLL |     let _x = false.then(|| x << -1);\n   |              ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| x << -1);\nLL +     let _x = false.then_some(x << -1);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:291:14\n   |\nLL |     let _x = false.then(|| x << 2);\n   |              ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| x << 2);\nLL +     let _x = false.then_some(x << 2);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:301:14\n   |\nLL |     let _x = false.then(|| x / 0);\n   |              ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| x / 0);\nLL +     let _x = false.then_some(x / 0);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:303:14\n   |\nLL |     let _x = false.then(|| x % 0);\n   |              ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| x % 0);\nLL +     let _x = false.then_some(x % 0);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:306:14\n   |\nLL |     let _x = false.then(|| 1 / -1);\n   |              ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| 1 / -1);\nLL +     let _x = false.then_some(1 / -1);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:308:14\n   |\nLL |     let _x = false.then(|| i32::MIN / -1);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| i32::MIN / -1);\nLL +     let _x = false.then_some(i32::MIN / -1);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:311:14\n   |\nLL |     let _x = false.then(|| i32::MIN / 0);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| i32::MIN / 0);\nLL +     let _x = false.then_some(i32::MIN / 0);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:313:14\n   |\nLL |     let _x = false.then(|| 4 / 2);\n   |              ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| 4 / 2);\nLL +     let _x = false.then_some(4 / 2);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval.rs:321:14\n   |\nLL |     let _x = false.then(|| f1 + f2);\n   |              ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _x = false.then(|| f1 + f2);\nLL +     let _x = false.then_some(f1 + f2);\n   |\n\nerror: aborting due to 63 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_lazy_eval_unfixable.rs",
    "content": "#![warn(clippy::unnecessary_lazy_evaluations)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n//@no-rustfix\nstruct Deep(Option<usize>);\n\n#[derive(Copy, Clone)]\nstruct SomeStruct {\n    some_field: usize,\n}\n\nfn main() {\n    // fix will break type inference\n    let _ = Ok(1).unwrap_or_else(|()| 2);\n    //~^ unnecessary_lazy_evaluations\n\n    mod e {\n        pub struct E;\n    }\n    let _ = Ok(1).unwrap_or_else(|e::E| 2);\n    //~^ unnecessary_lazy_evaluations\n\n    let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);\n    //~^ unnecessary_lazy_evaluations\n\n    // Fix #6343\n    let arr = [(Some(1),)];\n    Some(&0).and_then(|&i| arr[i].0);\n}\n\nfn issue11672() {\n    // Return type annotation helps type inference and removing it can break code\n    let _ = true.then(|| -> &[u8] { &[] });\n    //~^ unnecessary_lazy_evaluations\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_lazy_eval_unfixable.stderr",
    "content": "error: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval_unfixable.rs:13:13\n   |\nLL |     let _ = Ok(1).unwrap_or_else(|()| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = Ok(1).unwrap_or_else(|()| 2);\nLL +     let _ = Ok(1).unwrap_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13\n   |\nLL |     let _ = Ok(1).unwrap_or_else(|e::E| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = Ok(1).unwrap_or_else(|e::E| 2);\nLL +     let _ = Ok(1).unwrap_or(2);\n   |\n\nerror: unnecessary closure used to substitute value for `Result::Err`\n  --> tests/ui/unnecessary_lazy_eval_unfixable.rs:22:13\n   |\nLL |     let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `unwrap_or` instead\n   |\nLL -     let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);\nLL +     let _ = Ok(1).unwrap_or(2);\n   |\n\nerror: unnecessary closure used with `bool::then`\n  --> tests/ui/unnecessary_lazy_eval_unfixable.rs:32:13\n   |\nLL |     let _ = true.then(|| -> &[u8] { &[] });\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `then_some` instead\n   |\nLL -     let _ = true.then(|| -> &[u8] { &[] });\nLL +     let _ = true.then_some({ &[] });\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_literal_bound.fixed",
    "content": "#![warn(clippy::unnecessary_literal_bound)]\n\nstruct Struct<'a> {\n    not_literal: &'a str,\n}\n\nimpl Struct<'_> {\n    // Should warn\n    fn returns_lit(&self) -> &'static str {\n        //~^ unnecessary_literal_bound\n        \"Hello\"\n    }\n\n    // Should NOT warn\n    fn returns_non_lit(&self) -> &str {\n        self.not_literal\n    }\n\n    // Should warn, does not currently\n    fn conditionally_returns_lit(&self, cond: bool) -> &str {\n        if cond { \"Literal\" } else { \"also a literal\" }\n    }\n\n    // Should NOT warn\n    fn conditionally_returns_non_lit(&self, cond: bool) -> &str {\n        if cond { \"Literal\" } else { self.not_literal }\n    }\n\n    // Should warn\n    fn contionally_returns_literals_explicit(&self, cond: bool) -> &'static str {\n        //~^ unnecessary_literal_bound\n        if cond {\n            return \"Literal\";\n        }\n\n        \"also a literal\"\n    }\n\n    // Should NOT warn\n    fn conditionally_returns_non_lit_explicit(&self, cond: bool) -> &str {\n        if cond {\n            return self.not_literal;\n        }\n\n        \"Literal\"\n    }\n}\n\ntrait ReturnsStr {\n    fn trait_method(&self) -> &str;\n}\n\nimpl ReturnsStr for u8 {\n    // Should warn, even though not useful without trait refinement\n    fn trait_method(&self) -> &'static str {\n        //~^ unnecessary_literal_bound\n        \"Literal\"\n    }\n}\n\nimpl ReturnsStr for Struct<'_> {\n    // Should NOT warn\n    fn trait_method(&self) -> &str {\n        self.not_literal\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_literal_bound.rs",
    "content": "#![warn(clippy::unnecessary_literal_bound)]\n\nstruct Struct<'a> {\n    not_literal: &'a str,\n}\n\nimpl Struct<'_> {\n    // Should warn\n    fn returns_lit(&self) -> &str {\n        //~^ unnecessary_literal_bound\n        \"Hello\"\n    }\n\n    // Should NOT warn\n    fn returns_non_lit(&self) -> &str {\n        self.not_literal\n    }\n\n    // Should warn, does not currently\n    fn conditionally_returns_lit(&self, cond: bool) -> &str {\n        if cond { \"Literal\" } else { \"also a literal\" }\n    }\n\n    // Should NOT warn\n    fn conditionally_returns_non_lit(&self, cond: bool) -> &str {\n        if cond { \"Literal\" } else { self.not_literal }\n    }\n\n    // Should warn\n    fn contionally_returns_literals_explicit(&self, cond: bool) -> &str {\n        //~^ unnecessary_literal_bound\n        if cond {\n            return \"Literal\";\n        }\n\n        \"also a literal\"\n    }\n\n    // Should NOT warn\n    fn conditionally_returns_non_lit_explicit(&self, cond: bool) -> &str {\n        if cond {\n            return self.not_literal;\n        }\n\n        \"Literal\"\n    }\n}\n\ntrait ReturnsStr {\n    fn trait_method(&self) -> &str;\n}\n\nimpl ReturnsStr for u8 {\n    // Should warn, even though not useful without trait refinement\n    fn trait_method(&self) -> &str {\n        //~^ unnecessary_literal_bound\n        \"Literal\"\n    }\n}\n\nimpl ReturnsStr for Struct<'_> {\n    // Should NOT warn\n    fn trait_method(&self) -> &str {\n        self.not_literal\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_literal_bound.stderr",
    "content": "error: returning a `str` unnecessarily tied to the lifetime of arguments\n  --> tests/ui/unnecessary_literal_bound.rs:9:30\n   |\nLL |     fn returns_lit(&self) -> &str {\n   |                              ^^^^ help: try: `&'static str`\n   |\n   = note: `-D clippy::unnecessary-literal-bound` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_literal_bound)]`\n\nerror: returning a `str` unnecessarily tied to the lifetime of arguments\n  --> tests/ui/unnecessary_literal_bound.rs:30:68\n   |\nLL |     fn contionally_returns_literals_explicit(&self, cond: bool) -> &str {\n   |                                                                    ^^^^ help: try: `&'static str`\n\nerror: returning a `str` unnecessarily tied to the lifetime of arguments\n  --> tests/ui/unnecessary_literal_bound.rs:55:31\n   |\nLL |     fn trait_method(&self) -> &str {\n   |                               ^^^^ help: try: `&'static str`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_literal_unwrap.fixed",
    "content": "#![warn(clippy::unnecessary_literal_unwrap)]\n#![allow(unreachable_code)]\n#![allow(\n    clippy::unnecessary_lazy_evaluations,\n    clippy::diverging_sub_expression,\n    clippy::let_unit_value,\n    clippy::no_effect\n)]\n\nfn unwrap_option_some() {\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n\n    1;\n    //~^ unnecessary_literal_unwrap\n    1;\n    //~^ unnecessary_literal_unwrap\n}\n\n#[rustfmt::skip] // force rustfmt not to remove braces in `|| { 234 }`\nfn unwrap_option_none() {\n    let _val = panic!();\n    //~^ unnecessary_literal_unwrap\n    let _val = panic!(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n    let _val: String = String::default();\n    //~^ unnecessary_literal_unwrap\n    let _val: u16 = 234;\n    //~^ unnecessary_literal_unwrap\n    let _val: u16 = 234;\n    //~^ unnecessary_literal_unwrap\n    let _val: u16 = { 234 };\n    //~^ unnecessary_literal_unwrap\n    let _val: u16 = { 234 };\n    //~^ unnecessary_literal_unwrap\n\n    panic!();\n    //~^ unnecessary_literal_unwrap\n    panic!(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n    String::default();\n    //~^ unnecessary_literal_unwrap\n    234;\n    //~^ unnecessary_literal_unwrap\n    234;\n    //~^ unnecessary_literal_unwrap\n    { 234 };\n    //~^ unnecessary_literal_unwrap\n    { 234 };\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_result_ok() {\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = panic!(\"{:?}\", 1);\n    //~^ unnecessary_literal_unwrap\n    let _val = panic!(\"{1}: {:?}\", 1, \"this always happens\");\n    //~^ unnecessary_literal_unwrap\n\n    1;\n    //~^ unnecessary_literal_unwrap\n    1;\n    //~^ unnecessary_literal_unwrap\n    panic!(\"{:?}\", 1);\n    //~^ unnecessary_literal_unwrap\n    panic!(\"{1}: {:?}\", 1, \"this always happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_result_err() {\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = panic!(\"{:?}\", 1);\n    //~^ unnecessary_literal_unwrap\n    let _val = panic!(\"{1}: {:?}\", 1, \"this always happens\");\n    //~^ unnecessary_literal_unwrap\n\n    1;\n    //~^ unnecessary_literal_unwrap\n    1;\n    //~^ unnecessary_literal_unwrap\n    panic!(\"{:?}\", 1);\n    //~^ unnecessary_literal_unwrap\n    panic!(\"{1}: {:?}\", 1, \"this always happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_methods_option() {\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n\n    1;\n    //~^ unnecessary_literal_unwrap\n    1;\n    //~^ unnecessary_literal_unwrap\n    1;\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_methods_result() {\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n    let _val = 1;\n    //~^ unnecessary_literal_unwrap\n\n    1;\n    //~^ unnecessary_literal_unwrap\n    1;\n    //~^ unnecessary_literal_unwrap\n    1;\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_from_binding() {\n    macro_rules! from_macro {\n        () => {\n            Some(\"\")\n        };\n    }\n    let val = from_macro!();\n    let _ = val.unwrap_or(\"\");\n}\n\nfn unwrap_unchecked() {\n    let _ = 1;\n    //~^ unnecessary_literal_unwrap\n    let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe block\n    //\n    //~^^ unnecessary_literal_unwrap\n    let _ = 1 + 1;\n    //~^ unnecessary_literal_unwrap\n    let _ = 1;\n    //~^ unnecessary_literal_unwrap\n    let _ = unsafe { 1 + *(&1 as *const i32) };\n    //~^ unnecessary_literal_unwrap\n    let _ = 1 + 1;\n    //~^ unnecessary_literal_unwrap\n    let _ = 123;\n    //~^ unnecessary_literal_unwrap\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_literal_unwrap.rs",
    "content": "#![warn(clippy::unnecessary_literal_unwrap)]\n#![allow(unreachable_code)]\n#![allow(\n    clippy::unnecessary_lazy_evaluations,\n    clippy::diverging_sub_expression,\n    clippy::let_unit_value,\n    clippy::no_effect\n)]\n\nfn unwrap_option_some() {\n    let _val = Some(1).unwrap();\n    //~^ unnecessary_literal_unwrap\n    let _val = Some(1).expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n\n    Some(1).unwrap();\n    //~^ unnecessary_literal_unwrap\n    Some(1).expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\n#[rustfmt::skip] // force rustfmt not to remove braces in `|| { 234 }`\nfn unwrap_option_none() {\n    let _val = None::<()>.unwrap();\n    //~^ unnecessary_literal_unwrap\n    let _val = None::<()>.expect(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n    let _val: String = None.unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n    let _val: u16 = None.unwrap_or(234);\n    //~^ unnecessary_literal_unwrap\n    let _val: u16 = None.unwrap_or_else(|| 234);\n    //~^ unnecessary_literal_unwrap\n    let _val: u16 = None.unwrap_or_else(|| { 234 });\n    //~^ unnecessary_literal_unwrap\n    let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 });\n    //~^ unnecessary_literal_unwrap\n\n    None::<()>.unwrap();\n    //~^ unnecessary_literal_unwrap\n    None::<()>.expect(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n    None::<String>.unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n    None::<u16>.unwrap_or(234);\n    //~^ unnecessary_literal_unwrap\n    None::<u16>.unwrap_or_else(|| 234);\n    //~^ unnecessary_literal_unwrap\n    None::<u16>.unwrap_or_else(|| { 234 });\n    //~^ unnecessary_literal_unwrap\n    None::<u16>.unwrap_or_else(|| -> u16 { 234 });\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_result_ok() {\n    let _val = Ok::<_, ()>(1).unwrap();\n    //~^ unnecessary_literal_unwrap\n    let _val = Ok::<_, ()>(1).expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n    let _val = Ok::<_, ()>(1).unwrap_err();\n    //~^ unnecessary_literal_unwrap\n    let _val = Ok::<_, ()>(1).expect_err(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n\n    Ok::<_, ()>(1).unwrap();\n    //~^ unnecessary_literal_unwrap\n    Ok::<_, ()>(1).expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n    Ok::<_, ()>(1).unwrap_err();\n    //~^ unnecessary_literal_unwrap\n    Ok::<_, ()>(1).expect_err(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_result_err() {\n    let _val = Err::<(), _>(1).unwrap_err();\n    //~^ unnecessary_literal_unwrap\n    let _val = Err::<(), _>(1).expect_err(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n    let _val = Err::<(), _>(1).unwrap();\n    //~^ unnecessary_literal_unwrap\n    let _val = Err::<(), _>(1).expect(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n\n    Err::<(), _>(1).unwrap_err();\n    //~^ unnecessary_literal_unwrap\n    Err::<(), _>(1).expect_err(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n    Err::<(), _>(1).unwrap();\n    //~^ unnecessary_literal_unwrap\n    Err::<(), _>(1).expect(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_methods_option() {\n    let _val = Some(1).unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n    let _val = Some(1).unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n    let _val = Some(1).unwrap_or_else(|| 2);\n    //~^ unnecessary_literal_unwrap\n\n    Some(1).unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n    Some(1).unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n    Some(1).unwrap_or_else(|| 2);\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_methods_result() {\n    let _val = Ok::<_, ()>(1).unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n    let _val = Ok::<_, ()>(1).unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n    let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2);\n    //~^ unnecessary_literal_unwrap\n\n    Ok::<_, ()>(1).unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n    Ok::<_, ()>(1).unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n    Ok::<_, ()>(1).unwrap_or_else(|_| 2);\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_from_binding() {\n    macro_rules! from_macro {\n        () => {\n            Some(\"\")\n        };\n    }\n    let val = from_macro!();\n    let _ = val.unwrap_or(\"\");\n}\n\nfn unwrap_unchecked() {\n    let _ = unsafe { Some(1).unwrap_unchecked() };\n    //~^ unnecessary_literal_unwrap\n    let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block\n    //\n    //~^^ unnecessary_literal_unwrap\n    let _ = unsafe { Some(1).unwrap_unchecked() } + 1;\n    //~^ unnecessary_literal_unwrap\n    let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() };\n    //~^ unnecessary_literal_unwrap\n    let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) };\n    //~^ unnecessary_literal_unwrap\n    let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1;\n    //~^ unnecessary_literal_unwrap\n    let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() };\n    //~^ unnecessary_literal_unwrap\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_literal_unwrap.stderr",
    "content": "error: used `unwrap()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:11:16\n   |\nLL |     let _val = Some(1).unwrap();\n   |                ^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-literal-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_literal_unwrap)]`\nhelp: remove the `Some` and `unwrap()`\n   |\nLL -     let _val = Some(1).unwrap();\nLL +     let _val = 1;\n   |\n\nerror: used `expect()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:13:16\n   |\nLL |     let _val = Some(1).expect(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `expect()`\n   |\nLL -     let _val = Some(1).expect(\"this never happens\");\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:16:5\n   |\nLL |     Some(1).unwrap();\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap()`\n   |\nLL -     Some(1).unwrap();\nLL +     1;\n   |\n\nerror: used `expect()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:18:5\n   |\nLL |     Some(1).expect(\"this never happens\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `expect()`\n   |\nLL -     Some(1).expect(\"this never happens\");\nLL +     1;\n   |\n\nerror: used `unwrap()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:24:16\n   |\nLL |     let _val = None::<()>.unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap()`\n   |\nLL -     let _val = None::<()>.unwrap();\nLL +     let _val = panic!();\n   |\n\nerror: used `expect()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:26:16\n   |\nLL |     let _val = None::<()>.expect(\"this always happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `expect()`\n   |\nLL -     let _val = None::<()>.expect(\"this always happens\");\nLL +     let _val = panic!(\"this always happens\");\n   |\n\nerror: used `unwrap_or_default()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:28:24\n   |\nLL |     let _val: String = None.unwrap_or_default();\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_default()`\n   |\nLL -     let _val: String = None.unwrap_or_default();\nLL +     let _val: String = String::default();\n   |\n\nerror: used `unwrap_or()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:30:21\n   |\nLL |     let _val: u16 = None.unwrap_or(234);\n   |                     ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or()`\n   |\nLL -     let _val: u16 = None.unwrap_or(234);\nLL +     let _val: u16 = 234;\n   |\n\nerror: used `unwrap_or_else()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:32:21\n   |\nLL |     let _val: u16 = None.unwrap_or_else(|| 234);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_else()`\n   |\nLL -     let _val: u16 = None.unwrap_or_else(|| 234);\nLL +     let _val: u16 = 234;\n   |\n\nerror: used `unwrap_or_else()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:34:21\n   |\nLL |     let _val: u16 = None.unwrap_or_else(|| { 234 });\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_else()`\n   |\nLL -     let _val: u16 = None.unwrap_or_else(|| { 234 });\nLL +     let _val: u16 = { 234 };\n   |\n\nerror: used `unwrap_or_else()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:36:21\n   |\nLL |     let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 });\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_else()`\n   |\nLL -     let _val: u16 = None.unwrap_or_else(|| -> u16 { 234 });\nLL +     let _val: u16 = { 234 };\n   |\n\nerror: used `unwrap()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:39:5\n   |\nLL |     None::<()>.unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap()`\n   |\nLL -     None::<()>.unwrap();\nLL +     panic!();\n   |\n\nerror: used `expect()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:41:5\n   |\nLL |     None::<()>.expect(\"this always happens\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `expect()`\n   |\nLL -     None::<()>.expect(\"this always happens\");\nLL +     panic!(\"this always happens\");\n   |\n\nerror: used `unwrap_or_default()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:43:5\n   |\nLL |     None::<String>.unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_default()`\n   |\nLL -     None::<String>.unwrap_or_default();\nLL +     String::default();\n   |\n\nerror: used `unwrap_or()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:45:5\n   |\nLL |     None::<u16>.unwrap_or(234);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or()`\n   |\nLL -     None::<u16>.unwrap_or(234);\nLL +     234;\n   |\n\nerror: used `unwrap_or_else()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:47:5\n   |\nLL |     None::<u16>.unwrap_or_else(|| 234);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_else()`\n   |\nLL -     None::<u16>.unwrap_or_else(|| 234);\nLL +     234;\n   |\n\nerror: used `unwrap_or_else()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:49:5\n   |\nLL |     None::<u16>.unwrap_or_else(|| { 234 });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_else()`\n   |\nLL -     None::<u16>.unwrap_or_else(|| { 234 });\nLL +     { 234 };\n   |\n\nerror: used `unwrap_or_else()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:51:5\n   |\nLL |     None::<u16>.unwrap_or_else(|| -> u16 { 234 });\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_else()`\n   |\nLL -     None::<u16>.unwrap_or_else(|| -> u16 { 234 });\nLL +     { 234 };\n   |\n\nerror: used `unwrap()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:56:16\n   |\nLL |     let _val = Ok::<_, ()>(1).unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap()`\n   |\nLL -     let _val = Ok::<_, ()>(1).unwrap();\nLL +     let _val = 1;\n   |\n\nerror: used `expect()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:58:16\n   |\nLL |     let _val = Ok::<_, ()>(1).expect(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect()`\n   |\nLL -     let _val = Ok::<_, ()>(1).expect(\"this never happens\");\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:60:16\n   |\nLL |     let _val = Ok::<_, ()>(1).unwrap_err();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_err()`\n   |\nLL -     let _val = Ok::<_, ()>(1).unwrap_err();\nLL +     let _val = panic!(\"{:?}\", 1);\n   |\n\nerror: used `expect_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:62:16\n   |\nLL |     let _val = Ok::<_, ()>(1).expect_err(\"this always happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect_err()`\n   |\nLL -     let _val = Ok::<_, ()>(1).expect_err(\"this always happens\");\nLL +     let _val = panic!(\"{1}: {:?}\", 1, \"this always happens\");\n   |\n\nerror: used `unwrap()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:65:5\n   |\nLL |     Ok::<_, ()>(1).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap()`\n   |\nLL -     Ok::<_, ()>(1).unwrap();\nLL +     1;\n   |\n\nerror: used `expect()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:67:5\n   |\nLL |     Ok::<_, ()>(1).expect(\"this never happens\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect()`\n   |\nLL -     Ok::<_, ()>(1).expect(\"this never happens\");\nLL +     1;\n   |\n\nerror: used `unwrap_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:69:5\n   |\nLL |     Ok::<_, ()>(1).unwrap_err();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_err()`\n   |\nLL -     Ok::<_, ()>(1).unwrap_err();\nLL +     panic!(\"{:?}\", 1);\n   |\n\nerror: used `expect_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:71:5\n   |\nLL |     Ok::<_, ()>(1).expect_err(\"this always happens\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect_err()`\n   |\nLL -     Ok::<_, ()>(1).expect_err(\"this always happens\");\nLL +     panic!(\"{1}: {:?}\", 1, \"this always happens\");\n   |\n\nerror: used `unwrap_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:76:16\n   |\nLL |     let _val = Err::<(), _>(1).unwrap_err();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap_err()`\n   |\nLL -     let _val = Err::<(), _>(1).unwrap_err();\nLL +     let _val = 1;\n   |\n\nerror: used `expect_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:78:16\n   |\nLL |     let _val = Err::<(), _>(1).expect_err(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect_err()`\n   |\nLL -     let _val = Err::<(), _>(1).expect_err(\"this never happens\");\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:80:16\n   |\nLL |     let _val = Err::<(), _>(1).unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap()`\n   |\nLL -     let _val = Err::<(), _>(1).unwrap();\nLL +     let _val = panic!(\"{:?}\", 1);\n   |\n\nerror: used `expect()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:82:16\n   |\nLL |     let _val = Err::<(), _>(1).expect(\"this always happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect()`\n   |\nLL -     let _val = Err::<(), _>(1).expect(\"this always happens\");\nLL +     let _val = panic!(\"{1}: {:?}\", 1, \"this always happens\");\n   |\n\nerror: used `unwrap_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:85:5\n   |\nLL |     Err::<(), _>(1).unwrap_err();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap_err()`\n   |\nLL -     Err::<(), _>(1).unwrap_err();\nLL +     1;\n   |\n\nerror: used `expect_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:87:5\n   |\nLL |     Err::<(), _>(1).expect_err(\"this never happens\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect_err()`\n   |\nLL -     Err::<(), _>(1).expect_err(\"this never happens\");\nLL +     1;\n   |\n\nerror: used `unwrap()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:89:5\n   |\nLL |     Err::<(), _>(1).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap()`\n   |\nLL -     Err::<(), _>(1).unwrap();\nLL +     panic!(\"{:?}\", 1);\n   |\n\nerror: used `expect()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:91:5\n   |\nLL |     Err::<(), _>(1).expect(\"this always happens\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect()`\n   |\nLL -     Err::<(), _>(1).expect(\"this always happens\");\nLL +     panic!(\"{1}: {:?}\", 1, \"this always happens\");\n   |\n\nerror: used `unwrap_or()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:96:16\n   |\nLL |     let _val = Some(1).unwrap_or(2);\n   |                ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or()`\n   |\nLL -     let _val = Some(1).unwrap_or(2);\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap_or_default()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:98:16\n   |\nLL |     let _val = Some(1).unwrap_or_default();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_default()`\n   |\nLL -     let _val = Some(1).unwrap_or_default();\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap_or_else()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:100:16\n   |\nLL |     let _val = Some(1).unwrap_or_else(|| 2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_else()`\n   |\nLL -     let _val = Some(1).unwrap_or_else(|| 2);\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap_or()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:103:5\n   |\nLL |     Some(1).unwrap_or(2);\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or()`\n   |\nLL -     Some(1).unwrap_or(2);\nLL +     1;\n   |\n\nerror: used `unwrap_or_default()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:105:5\n   |\nLL |     Some(1).unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_default()`\n   |\nLL -     Some(1).unwrap_or_default();\nLL +     1;\n   |\n\nerror: used `unwrap_or_else()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:107:5\n   |\nLL |     Some(1).unwrap_or_else(|| 2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_else()`\n   |\nLL -     Some(1).unwrap_or_else(|| 2);\nLL +     1;\n   |\n\nerror: used `unwrap_or()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:112:16\n   |\nLL |     let _val = Ok::<_, ()>(1).unwrap_or(2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or()`\n   |\nLL -     let _val = Ok::<_, ()>(1).unwrap_or(2);\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap_or_default()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:114:16\n   |\nLL |     let _val = Ok::<_, ()>(1).unwrap_or_default();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_default()`\n   |\nLL -     let _val = Ok::<_, ()>(1).unwrap_or_default();\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap_or_else()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:116:16\n   |\nLL |     let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_else()`\n   |\nLL -     let _val = Ok::<_, ()>(1).unwrap_or_else(|_| 2);\nLL +     let _val = 1;\n   |\n\nerror: used `unwrap_or()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:119:5\n   |\nLL |     Ok::<_, ()>(1).unwrap_or(2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or()`\n   |\nLL -     Ok::<_, ()>(1).unwrap_or(2);\nLL +     1;\n   |\n\nerror: used `unwrap_or_default()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:121:5\n   |\nLL |     Ok::<_, ()>(1).unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_default()`\n   |\nLL -     Ok::<_, ()>(1).unwrap_or_default();\nLL +     1;\n   |\n\nerror: used `unwrap_or_else()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:123:5\n   |\nLL |     Ok::<_, ()>(1).unwrap_or_else(|_| 2);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_else()`\n   |\nLL -     Ok::<_, ()>(1).unwrap_or_else(|_| 2);\nLL +     1;\n   |\n\nerror: used `unwrap_unchecked()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:138:22\n   |\nLL |     let _ = unsafe { Some(1).unwrap_unchecked() };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_unchecked()`\n   |\nLL -     let _ = unsafe { Some(1).unwrap_unchecked() };\nLL +     let _ = 1;\n   |\n\nerror: used `unwrap_unchecked()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:140:22\n   |\nLL |     let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_unchecked()`\n   |\nLL -     let _ = unsafe { Some(1).unwrap_unchecked() + *(&1 as *const i32) }; // needs to keep the unsafe block\nLL +     let _ = unsafe { 1 + *(&1 as *const i32) }; // needs to keep the unsafe block\n   |\n\nerror: used `unwrap_unchecked()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:143:22\n   |\nLL |     let _ = unsafe { Some(1).unwrap_unchecked() } + 1;\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_unchecked()`\n   |\nLL -     let _ = unsafe { Some(1).unwrap_unchecked() } + 1;\nLL +     let _ = 1 + 1;\n   |\n\nerror: used `unwrap_unchecked()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:145:22\n   |\nLL |     let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_unchecked()`\n   |\nLL -     let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() };\nLL +     let _ = 1;\n   |\n\nerror: used `unwrap_unchecked()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:147:22\n   |\nLL |     let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_unchecked()`\n   |\nLL -     let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() + *(&1 as *const i32) };\nLL +     let _ = unsafe { 1 + *(&1 as *const i32) };\n   |\n\nerror: used `unwrap_unchecked()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:149:22\n   |\nLL |     let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1;\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_unchecked()`\n   |\nLL -     let _ = unsafe { Ok::<_, ()>(1).unwrap_unchecked() } + 1;\nLL +     let _ = 1 + 1;\n   |\n\nerror: used `unwrap_err_unchecked()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap.rs:151:22\n   |\nLL |     let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() };\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap_err_unchecked()`\n   |\nLL -     let _ = unsafe { Err::<(), i32>(123).unwrap_err_unchecked() };\nLL +     let _ = 123;\n   |\n\nerror: aborting due to 53 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_literal_unwrap_unfixable.rs",
    "content": "#![warn(clippy::unnecessary_literal_unwrap)]\n#![allow(unreachable_code)]\n#![allow(clippy::unnecessary_lazy_evaluations, clippy::let_unit_value)]\n//@no-rustfix\nfn unwrap_option_some() {\n    let val = Some(1);\n    let _val2 = val.unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_option_some_context() {\n    let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Some::<usize>([1, 2, 3].iter().sum()).expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let val = Some::<usize>([1, 2, 3].iter().sum());\n    let _val2 = val.unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_option_none() {\n    let val = None::<()>;\n    let _val2 = val.unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let _val3: u8 = None.unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n\n    None::<()>.unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_result_ok() {\n    let val = Ok::<_, ()>(1);\n    let _val2 = val.unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_err();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect_err(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_result_ok_context() {\n    let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_err();\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect_err(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n    let _val2 = val.unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_err();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect_err(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_result_err() {\n    let val = Err::<(), _>(1);\n    let _val2 = val.unwrap_err();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect_err(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_result_err_context() {\n    let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err();\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let val = Err::<(), usize>([1, 2, 3].iter().sum());\n    let _val2 = val.unwrap_err();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect_err(\"this never happens\");\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.expect(\"this always happens\");\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_methods_option() {\n    let val = Some(1);\n    let _val2 = val.unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_or_else(|| 2);\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_methods_option_context() {\n    let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_else(|| 2);\n    //~^ unnecessary_literal_unwrap\n\n    let val = Some::<usize>([1, 2, 3].iter().sum());\n    let _val2 = val.unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_or_else(|| 2);\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_methods_result() {\n    let val = Ok::<_, ()>(1);\n    let _val2 = val.unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_or_else(|_| 2);\n    //~^ unnecessary_literal_unwrap\n}\n\nfn unwrap_methods_result_context() {\n    let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n\n    let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2);\n    //~^ unnecessary_literal_unwrap\n\n    let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n    let _val2 = val.unwrap_or(2);\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_or_default();\n    //~^ unnecessary_literal_unwrap\n\n    let _val2 = val.unwrap_or_else(|_| 2);\n    //~^ unnecessary_literal_unwrap\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_literal_unwrap_unfixable.stderr",
    "content": "error: used `unwrap()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:7:17\n   |\nLL |     let _val2 = val.unwrap();\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:6:15\n   |\nLL |     let val = Some(1);\n   |               ^^^^^^^\n   = note: `-D clippy::unnecessary-literal-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_literal_unwrap)]`\n\nerror: used `expect()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:10:17\n   |\nLL |     let _val2 = val.expect(\"this never happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:6:15\n   |\nLL |     let val = Some(1);\n   |               ^^^^^^^\n\nerror: used `unwrap()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:15:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:15:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:18:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).expect(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:18:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).expect(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:22:17\n   |\nLL |     let _val2 = val.unwrap();\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:21:15\n   |\nLL |     let val = Some::<usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:25:17\n   |\nLL |     let _val2 = val.expect(\"this never happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:21:15\n   |\nLL |     let val = Some::<usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:31:17\n   |\nLL |     let _val2 = val.unwrap();\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:30:15\n   |\nLL |     let val = None::<()>;\n   |               ^^^^^^^^^^\n\nerror: used `expect()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:34:17\n   |\nLL |     let _val2 = val.expect(\"this always happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:30:15\n   |\nLL |     let val = None::<()>;\n   |               ^^^^^^^^^^\n\nerror: used `unwrap_or_default()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:37:21\n   |\nLL |     let _val3: u8 = None.unwrap_or_default();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_default()`\n   |\nLL -     let _val3: u8 = None.unwrap_or_default();\nLL +     let _val3: u8 = Default::default();\n   |\n\nerror: used `unwrap_or_default()` on `None` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:40:5\n   |\nLL |     None::<()>.unwrap_or_default();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `None` and `unwrap_or_default()`\n   |\nLL -     None::<()>.unwrap_or_default();\nLL +     Default::default();\n   |\n\nerror: used `unwrap()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:46:17\n   |\nLL |     let _val2 = val.unwrap();\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:45:15\n   |\nLL |     let val = Ok::<_, ()>(1);\n   |               ^^^^^^^^^^^^^^\n\nerror: used `expect()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:49:17\n   |\nLL |     let _val2 = val.expect(\"this never happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:45:15\n   |\nLL |     let val = Ok::<_, ()>(1);\n   |               ^^^^^^^^^^^^^^\n\nerror: used `unwrap_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:52:17\n   |\nLL |     let _val2 = val.unwrap_err();\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:45:15\n   |\nLL |     let val = Ok::<_, ()>(1);\n   |               ^^^^^^^^^^^^^^\n\nerror: used `expect_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:55:17\n   |\nLL |     let _val2 = val.expect_err(\"this always happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:45:15\n   |\nLL |     let val = Ok::<_, ()>(1);\n   |               ^^^^^^^^^^^^^^\n\nerror: used `unwrap()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:60:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:60:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:63:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:63:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:66:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_err();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:66:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_err();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:69:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect_err(\"this always happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:69:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).expect_err(\"this always happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:73:17\n   |\nLL |     let _val2 = val.unwrap();\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15\n   |\nLL |     let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:76:17\n   |\nLL |     let _val2 = val.expect(\"this never happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15\n   |\nLL |     let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:79:17\n   |\nLL |     let _val2 = val.unwrap_err();\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15\n   |\nLL |     let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect_err()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:82:17\n   |\nLL |     let _val2 = val.expect_err(\"this always happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `expect_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:72:15\n   |\nLL |     let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:88:17\n   |\nLL |     let _val2 = val.unwrap_err();\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:87:15\n   |\nLL |     let val = Err::<(), _>(1);\n   |               ^^^^^^^^^^^^^^^\n\nerror: used `expect_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:91:17\n   |\nLL |     let _val2 = val.expect_err(\"this never happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:87:15\n   |\nLL |     let val = Err::<(), _>(1);\n   |               ^^^^^^^^^^^^^^^\n\nerror: used `unwrap()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:94:17\n   |\nLL |     let _val2 = val.unwrap();\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:87:15\n   |\nLL |     let val = Err::<(), _>(1);\n   |               ^^^^^^^^^^^^^^^\n\nerror: used `expect()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:97:17\n   |\nLL |     let _val2 = val.expect(\"this always happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:87:15\n   |\nLL |     let val = Err::<(), _>(1);\n   |               ^^^^^^^^^^^^^^^\n\nerror: used `unwrap_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:102:16\n   |\nLL |     let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:102:16\n   |\nLL |     let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap_err();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:105:16\n   |\nLL |     let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:105:16\n   |\nLL |     let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect_err(\"this never happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:108:16\n   |\nLL |     let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:108:16\n   |\nLL |     let _val = Err::<(), usize>([1, 2, 3].iter().sum()).unwrap();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:111:16\n   |\nLL |     let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect(\"this always happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:111:16\n   |\nLL |     let _val = Err::<(), usize>([1, 2, 3].iter().sum()).expect(\"this always happens\");\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:115:17\n   |\nLL |     let _val2 = val.unwrap_err();\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:114:15\n   |\nLL |     let val = Err::<(), usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect_err()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:118:17\n   |\nLL |     let _val2 = val.expect_err(\"this never happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect_err()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:114:15\n   |\nLL |     let val = Err::<(), usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:121:17\n   |\nLL |     let _val2 = val.unwrap();\n   |                 ^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `unwrap()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:114:15\n   |\nLL |     let val = Err::<(), usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `expect()` on `Err` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:124:17\n   |\nLL |     let _val2 = val.expect(\"this always happens\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Err` and `expect()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:114:15\n   |\nLL |     let val = Err::<(), usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:130:17\n   |\nLL |     let _val2 = val.unwrap_or(2);\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:129:15\n   |\nLL |     let val = Some(1);\n   |               ^^^^^^^\n\nerror: used `unwrap_or_default()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:133:17\n   |\nLL |     let _val2 = val.unwrap_or_default();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_default()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:129:15\n   |\nLL |     let val = Some(1);\n   |               ^^^^^^^\n\nerror: used `unwrap_or_else()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:136:17\n   |\nLL |     let _val2 = val.unwrap_or_else(|| 2);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_else()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:129:15\n   |\nLL |     let val = Some(1);\n   |               ^^^^^^^\n\nerror: used `unwrap_or()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:141:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or(2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:141:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or(2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_default()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:144:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_default();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_default()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:144:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_default();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_else()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:147:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_else(|| 2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_else()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:147:16\n   |\nLL |     let _val = Some::<usize>([1, 2, 3].iter().sum()).unwrap_or_else(|| 2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:151:17\n   |\nLL |     let _val2 = val.unwrap_or(2);\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:150:15\n   |\nLL |     let val = Some::<usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_default()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:154:17\n   |\nLL |     let _val2 = val.unwrap_or_default();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_default()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:150:15\n   |\nLL |     let val = Some::<usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_else()` on `Some` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:157:17\n   |\nLL |     let _val2 = val.unwrap_or_else(|| 2);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Some` and `unwrap_or_else()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:150:15\n   |\nLL |     let val = Some::<usize>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:163:17\n   |\nLL |     let _val2 = val.unwrap_or(2);\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15\n   |\nLL |     let val = Ok::<_, ()>(1);\n   |               ^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_default()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:166:17\n   |\nLL |     let _val2 = val.unwrap_or_default();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_default()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15\n   |\nLL |     let val = Ok::<_, ()>(1);\n   |               ^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_else()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:169:17\n   |\nLL |     let _val2 = val.unwrap_or_else(|_| 2);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_else()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:162:15\n   |\nLL |     let val = Ok::<_, ()>(1);\n   |               ^^^^^^^^^^^^^^\n\nerror: used `unwrap_or()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:174:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or(2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:174:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or(2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_default()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:177:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_default();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_default()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:177:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_default();\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_else()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:180:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_else()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:180:16\n   |\nLL |     let _val = Ok::<usize, ()>([1, 2, 3].iter().sum()).unwrap_or_else(|_| 2);\n   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:184:17\n   |\nLL |     let _val2 = val.unwrap_or(2);\n   |                 ^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:183:15\n   |\nLL |     let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_default()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:187:17\n   |\nLL |     let _val2 = val.unwrap_or_default();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_default()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:183:15\n   |\nLL |     let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used `unwrap_or_else()` on `Ok` value\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:190:17\n   |\nLL |     let _val2 = val.unwrap_or_else(|_| 2);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the `Ok` and `unwrap_or_else()`\n  --> tests/ui/unnecessary_literal_unwrap_unfixable.rs:183:15\n   |\nLL |     let val = Ok::<usize, ()>([1, 2, 3].iter().sum());\n   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 52 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_map_on_constructor.fixed",
    "content": "#![allow(unused)]\n#![warn(clippy::unnecessary_map_on_constructor)]\n\nuse std::ffi::OsStr;\n\nfn fun(t: i32) -> i32 {\n    t\n}\n\nfn notfun(e: SimpleError) -> SimpleError {\n    e\n}\nmacro_rules! expands_to_fun {\n    () => {\n        fun\n    };\n}\n\n#[derive(Copy, Clone)]\nstruct SimpleError {}\n\ntype SimpleResult = std::result::Result<i32, SimpleError>;\n\nfn main() {\n    let x: i32 = 4;\n\n    let err = SimpleError {};\n    let a = Some(x);\n    let b: SimpleResult = Ok(x);\n    let c: SimpleResult = Err(err);\n\n    let a = Some(fun(x));\n    //~^ unnecessary_map_on_constructor\n    let b: SimpleResult = Ok(fun(x));\n    //~^ unnecessary_map_on_constructor\n    let c: SimpleResult = Err(notfun(err));\n    //~^ unnecessary_map_on_constructor\n\n    let a = Option::Some(fun(x));\n    //~^ unnecessary_map_on_constructor\n    let b: SimpleResult = SimpleResult::Ok(fun(x));\n    //~^ unnecessary_map_on_constructor\n    let c: SimpleResult = SimpleResult::Err(notfun(err));\n    //~^ unnecessary_map_on_constructor\n    let b: std::result::Result<i32, SimpleError> = Ok(fun(x));\n    //~^ unnecessary_map_on_constructor\n    let c: std::result::Result<i32, SimpleError> = Err(notfun(err));\n    //~^ unnecessary_map_on_constructor\n\n    let a = Some(fun(x));\n    let b: SimpleResult = Ok(fun(x));\n    let c: SimpleResult = Err(notfun(err));\n\n    // Should not trigger warning\n    a.map(fun);\n    b.map(fun);\n    c.map_err(notfun);\n\n    b.map_err(notfun); // Ok(_).map_err\n    c.map(fun); // Err(_).map()\n\n    option_env!(\"PATH\").map(OsStr::new);\n    Some(x).map(expands_to_fun!());\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_map_on_constructor.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::unnecessary_map_on_constructor)]\n\nuse std::ffi::OsStr;\n\nfn fun(t: i32) -> i32 {\n    t\n}\n\nfn notfun(e: SimpleError) -> SimpleError {\n    e\n}\nmacro_rules! expands_to_fun {\n    () => {\n        fun\n    };\n}\n\n#[derive(Copy, Clone)]\nstruct SimpleError {}\n\ntype SimpleResult = std::result::Result<i32, SimpleError>;\n\nfn main() {\n    let x: i32 = 4;\n\n    let err = SimpleError {};\n    let a = Some(x);\n    let b: SimpleResult = Ok(x);\n    let c: SimpleResult = Err(err);\n\n    let a = Some(x).map(fun);\n    //~^ unnecessary_map_on_constructor\n    let b: SimpleResult = Ok(x).map(fun);\n    //~^ unnecessary_map_on_constructor\n    let c: SimpleResult = Err(err).map_err(notfun);\n    //~^ unnecessary_map_on_constructor\n\n    let a = Option::Some(x).map(fun);\n    //~^ unnecessary_map_on_constructor\n    let b: SimpleResult = SimpleResult::Ok(x).map(fun);\n    //~^ unnecessary_map_on_constructor\n    let c: SimpleResult = SimpleResult::Err(err).map_err(notfun);\n    //~^ unnecessary_map_on_constructor\n    let b: std::result::Result<i32, SimpleError> = Ok(x).map(fun);\n    //~^ unnecessary_map_on_constructor\n    let c: std::result::Result<i32, SimpleError> = Err(err).map_err(notfun);\n    //~^ unnecessary_map_on_constructor\n\n    let a = Some(fun(x));\n    let b: SimpleResult = Ok(fun(x));\n    let c: SimpleResult = Err(notfun(err));\n\n    // Should not trigger warning\n    a.map(fun);\n    b.map(fun);\n    c.map_err(notfun);\n\n    b.map_err(notfun); // Ok(_).map_err\n    c.map(fun); // Err(_).map()\n\n    option_env!(\"PATH\").map(OsStr::new);\n    Some(x).map(expands_to_fun!());\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_map_on_constructor.stderr",
    "content": "error: unnecessary `map` on constructor `Some(_)`\n  --> tests/ui/unnecessary_map_on_constructor.rs:32:13\n   |\nLL |     let a = Some(x).map(fun);\n   |             ^^^^^^^^^^^^^^^^ help: try: `Some(fun(x))`\n   |\n   = note: `-D clippy::unnecessary-map-on-constructor` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_on_constructor)]`\n\nerror: unnecessary `map` on constructor `Ok(_)`\n  --> tests/ui/unnecessary_map_on_constructor.rs:34:27\n   |\nLL |     let b: SimpleResult = Ok(x).map(fun);\n   |                           ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))`\n\nerror: unnecessary `map_err` on constructor `Err(_)`\n  --> tests/ui/unnecessary_map_on_constructor.rs:36:27\n   |\nLL |     let c: SimpleResult = Err(err).map_err(notfun);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))`\n\nerror: unnecessary `map` on constructor `Option::Some(_)`\n  --> tests/ui/unnecessary_map_on_constructor.rs:39:13\n   |\nLL |     let a = Option::Some(x).map(fun);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option::Some(fun(x))`\n\nerror: unnecessary `map` on constructor `SimpleResult::Ok(_)`\n  --> tests/ui/unnecessary_map_on_constructor.rs:41:27\n   |\nLL |     let b: SimpleResult = SimpleResult::Ok(x).map(fun);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Ok(fun(x))`\n\nerror: unnecessary `map_err` on constructor `SimpleResult::Err(_)`\n  --> tests/ui/unnecessary_map_on_constructor.rs:43:27\n   |\nLL |     let c: SimpleResult = SimpleResult::Err(err).map_err(notfun);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Err(notfun(err))`\n\nerror: unnecessary `map` on constructor `Ok(_)`\n  --> tests/ui/unnecessary_map_on_constructor.rs:45:52\n   |\nLL |     let b: std::result::Result<i32, SimpleError> = Ok(x).map(fun);\n   |                                                    ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))`\n\nerror: unnecessary `map_err` on constructor `Err(_)`\n  --> tests/ui/unnecessary_map_on_constructor.rs:47:52\n   |\nLL |     let c: std::result::Result<i32, SimpleError> = Err(err).map_err(notfun);\n   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_map_or.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::unnecessary_map_or)]\n#![allow(clippy::no_effect)]\n#![allow(clippy::eq_op)]\n#![allow(clippy::unnecessary_lazy_evaluations)]\n#![allow(clippy::nonminimal_bool)]\n#[clippy::msrv = \"1.70.0\"]\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    // should trigger\n    let _ = Some(5) == Some(5);\n    //~^ unnecessary_map_or\n    let _ = Some(5) != Some(5);\n    //~^ unnecessary_map_or\n    let _ = Some(5) == Some(5);\n    let _ = Some(5).is_some_and(|n| {\n        //~^ unnecessary_map_or\n        let _ = n;\n        6 >= 5\n    });\n    let _ = Some(vec![5]).is_some_and(|n| n == [5]);\n    //~^ unnecessary_map_or\n    let _ = Some(vec![1]).is_some_and(|n| vec![2] == n);\n    //~^ unnecessary_map_or\n    let _ = Some(5).is_some_and(|n| n == n);\n    //~^ unnecessary_map_or\n    let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 });\n    //~^ unnecessary_map_or\n    let _ = Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5]);\n    //~^ unnecessary_map_or\n    let _ = Ok::<i32, i32>(5) == Ok(5);\n    //~^ unnecessary_map_or\n    let _ = (Some(5) == Some(5)).then(|| 1);\n    //~^ unnecessary_map_or\n    let _ = Some(5).is_none_or(|n| n == 5);\n    //~^ unnecessary_map_or\n    let _ = Some(5).is_none_or(|n| 5 == n);\n    //~^ unnecessary_map_or\n    let _ = !(Some(5) == Some(5));\n    //~^ unnecessary_map_or\n    let _ = (Some(5) == Some(5)) || false;\n    //~^ unnecessary_map_or\n    let _ = (Some(5) == Some(5)) as usize;\n    //~^ unnecessary_map_or\n\n    macro_rules! x {\n        () => {\n            Some(1)\n        };\n    }\n    // methods lints dont fire on macros\n    let _ = x!().map_or(false, |n| n == 1);\n    let _ = x!().map_or(false, |n| n == vec![1][0]);\n\n    msrv_1_69();\n\n    external! {\n        let _ = Some(5).map_or(false, |n| n == 5);\n    }\n\n    with_span! {\n        let _ = Some(5).map_or(false, |n| n == 5);\n    }\n\n    // check for presence of PartialEq, and alter suggestion to use `is_ok_and` if absent\n    struct S;\n    let r: Result<i32, S> = Ok(3);\n    let _ = r.is_ok_and(|x| x == 7);\n    //~^ unnecessary_map_or\n\n    // lint constructs that are not comparisons as well\n    let func = |_x| true;\n    let r: Result<i32, S> = Ok(3);\n    let _ = r.is_ok_and(func);\n    //~^ unnecessary_map_or\n    let _ = Some(5).is_some_and(func);\n    //~^ unnecessary_map_or\n    let _ = Some(5).is_none_or(func);\n    //~^ unnecessary_map_or\n\n    #[derive(PartialEq)]\n    struct S2;\n    let r: Result<i32, S2> = Ok(4);\n    let _ = r == Ok(8);\n    //~^ unnecessary_map_or\n\n    // do not lint `Result::map_or(true, …)`\n    let r: Result<i32, S2> = Ok(4);\n    let _ = r.map_or(true, |x| x == 8);\n}\n\n#[clippy::msrv = \"1.69.0\"]\nfn msrv_1_69() {\n    // is_some_and added in 1.70.0\n    let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });\n}\n\n#[clippy::msrv = \"1.81.0\"]\nfn msrv_1_81() {\n    // is_none_or added in 1.82.0\n    let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 });\n}\n\nfn with_refs(o: &mut Option<u32>) -> bool {\n    o.is_none_or(|n| n > 5) || (o as &Option<u32>).is_none_or(|n| n < 5)\n    //~^ unnecessary_map_or\n    //~| unnecessary_map_or\n}\n\nstruct S;\n\nimpl std::ops::Deref for S {\n    type Target = Option<u32>;\n    fn deref(&self) -> &Self::Target {\n        &Some(0)\n    }\n}\n\nfn with_deref(o: &S) -> bool {\n    o.is_none_or(|n| n > 5)\n    //~^ unnecessary_map_or\n}\n\nfn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {\n    let x = a.is_some_and(|a| a == *s);\n    //~^ unnecessary_map_or\n    let y = b.is_none_or(|b| b == *s);\n    //~^ unnecessary_map_or\n    x && y\n}\n\nfn issue14714() {\n    assert!(Some(\"test\") == Some(\"test\"));\n    //~^ unnecessary_map_or\n\n    // even though we're in a macro context, we still need to parenthesise because of the `then`\n    assert!((Some(\"test\") == Some(\"test\")).then(|| 1).is_some());\n    //~^ unnecessary_map_or\n\n    // method lints don't fire on macros\n    macro_rules! m {\n        ($x:expr) => {\n            // should become !($x == Some(1))\n            let _ = !$x.map_or(false, |v| v == 1);\n            // should become $x == Some(1)\n            let _ = $x.map_or(false, |v| v == 1);\n        };\n    }\n    m!(Some(5));\n}\n\nfn issue15180() {\n    let s = std::sync::Mutex::new(Some(\"foo\"));\n    _ = s.lock().unwrap().is_some_and(|s| s == \"foo\");\n    //~^ unnecessary_map_or\n\n    let s = &&&&Some(\"foo\");\n    _ = s.is_some_and(|s| s == \"foo\");\n    //~^ unnecessary_map_or\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_map_or.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::unnecessary_map_or)]\n#![allow(clippy::no_effect)]\n#![allow(clippy::eq_op)]\n#![allow(clippy::unnecessary_lazy_evaluations)]\n#![allow(clippy::nonminimal_bool)]\n#[clippy::msrv = \"1.70.0\"]\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    // should trigger\n    let _ = Some(5).map_or(false, |n| n == 5);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(true, |n| n != 5);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(false, |n| {\n        //~^ unnecessary_map_or\n        let _ = 1;\n        n == 5\n    });\n    let _ = Some(5).map_or(false, |n| {\n        //~^ unnecessary_map_or\n        let _ = n;\n        6 >= 5\n    });\n    let _ = Some(vec![5]).map_or(false, |n| n == [5]);\n    //~^ unnecessary_map_or\n    let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(false, |n| n == n);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });\n    //~^ unnecessary_map_or\n    let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);\n    //~^ unnecessary_map_or\n    let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(true, |n| n == 5);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(true, |n| 5 == n);\n    //~^ unnecessary_map_or\n    let _ = !Some(5).map_or(false, |n| n == 5);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(false, |n| n == 5) || false;\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(false, |n| n == 5) as usize;\n    //~^ unnecessary_map_or\n\n    macro_rules! x {\n        () => {\n            Some(1)\n        };\n    }\n    // methods lints dont fire on macros\n    let _ = x!().map_or(false, |n| n == 1);\n    let _ = x!().map_or(false, |n| n == vec![1][0]);\n\n    msrv_1_69();\n\n    external! {\n        let _ = Some(5).map_or(false, |n| n == 5);\n    }\n\n    with_span! {\n        let _ = Some(5).map_or(false, |n| n == 5);\n    }\n\n    // check for presence of PartialEq, and alter suggestion to use `is_ok_and` if absent\n    struct S;\n    let r: Result<i32, S> = Ok(3);\n    let _ = r.map_or(false, |x| x == 7);\n    //~^ unnecessary_map_or\n\n    // lint constructs that are not comparisons as well\n    let func = |_x| true;\n    let r: Result<i32, S> = Ok(3);\n    let _ = r.map_or(false, func);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(false, func);\n    //~^ unnecessary_map_or\n    let _ = Some(5).map_or(true, func);\n    //~^ unnecessary_map_or\n\n    #[derive(PartialEq)]\n    struct S2;\n    let r: Result<i32, S2> = Ok(4);\n    let _ = r.map_or(false, |x| x == 8);\n    //~^ unnecessary_map_or\n\n    // do not lint `Result::map_or(true, …)`\n    let r: Result<i32, S2> = Ok(4);\n    let _ = r.map_or(true, |x| x == 8);\n}\n\n#[clippy::msrv = \"1.69.0\"]\nfn msrv_1_69() {\n    // is_some_and added in 1.70.0\n    let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });\n}\n\n#[clippy::msrv = \"1.81.0\"]\nfn msrv_1_81() {\n    // is_none_or added in 1.82.0\n    let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 });\n}\n\nfn with_refs(o: &mut Option<u32>) -> bool {\n    o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)\n    //~^ unnecessary_map_or\n    //~| unnecessary_map_or\n}\n\nstruct S;\n\nimpl std::ops::Deref for S {\n    type Target = Option<u32>;\n    fn deref(&self) -> &Self::Target {\n        &Some(0)\n    }\n}\n\nfn with_deref(o: &S) -> bool {\n    o.map_or(true, |n| n > 5)\n    //~^ unnecessary_map_or\n}\n\nfn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {\n    let x = a.map_or(false, |a| a == *s);\n    //~^ unnecessary_map_or\n    let y = b.map_or(true, |b| b == *s);\n    //~^ unnecessary_map_or\n    x && y\n}\n\nfn issue14714() {\n    assert!(Some(\"test\").map_or(false, |x| x == \"test\"));\n    //~^ unnecessary_map_or\n\n    // even though we're in a macro context, we still need to parenthesise because of the `then`\n    assert!(Some(\"test\").map_or(false, |x| x == \"test\").then(|| 1).is_some());\n    //~^ unnecessary_map_or\n\n    // method lints don't fire on macros\n    macro_rules! m {\n        ($x:expr) => {\n            // should become !($x == Some(1))\n            let _ = !$x.map_or(false, |v| v == 1);\n            // should become $x == Some(1)\n            let _ = $x.map_or(false, |v| v == 1);\n        };\n    }\n    m!(Some(5));\n}\n\nfn issue15180() {\n    let s = std::sync::Mutex::new(Some(\"foo\"));\n    _ = s.lock().unwrap().map_or(false, |s| s == \"foo\");\n    //~^ unnecessary_map_or\n\n    let s = &&&&Some(\"foo\");\n    _ = s.map_or(false, |s| s == \"foo\");\n    //~^ unnecessary_map_or\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_map_or.stderr",
    "content": "error: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:13:13\n   |\nLL |     let _ = Some(5).map_or(false, |n| n == 5);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-map-or` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]`\nhelp: use a standard comparison instead\n   |\nLL -     let _ = Some(5).map_or(false, |n| n == 5);\nLL +     let _ = Some(5) == Some(5);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:15:13\n   |\nLL |     let _ = Some(5).map_or(true, |n| n != 5);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     let _ = Some(5).map_or(true, |n| n != 5);\nLL +     let _ = Some(5) != Some(5);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:17:13\n   |\nLL |       let _ = Some(5).map_or(false, |n| {\n   |  _____________^\nLL | |\nLL | |         let _ = 1;\nLL | |         n == 5\nLL | |     });\n   | |______^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     let _ = Some(5).map_or(false, |n| {\nLL -\nLL -         let _ = 1;\nLL -         n == 5\nLL -     });\nLL +     let _ = Some(5) == Some(5);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:22:13\n   |\nLL |       let _ = Some(5).map_or(false, |n| {\n   |  _____________^\nLL | |\nLL | |         let _ = n;\nLL | |         6 >= 5\nLL | |     });\n   | |______^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     let _ = Some(5).map_or(false, |n| {\nLL +     let _ = Some(5).is_some_and(|n| {\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:27:13\n   |\nLL |     let _ = Some(vec![5]).map_or(false, |n| n == [5]);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     let _ = Some(vec![5]).map_or(false, |n| n == [5]);\nLL +     let _ = Some(vec![5]).is_some_and(|n| n == [5]);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:29:13\n   |\nLL |     let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);\nLL +     let _ = Some(vec![1]).is_some_and(|n| vec![2] == n);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:31:13\n   |\nLL |     let _ = Some(5).map_or(false, |n| n == n);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     let _ = Some(5).map_or(false, |n| n == n);\nLL +     let _ = Some(5).is_some_and(|n| n == n);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:33:13\n   |\nLL |     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });\nLL +     let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 });\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:35:13\n   |\nLL |     let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_ok_and` instead\n   |\nLL -     let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);\nLL +     let _ = Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5]);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:37:13\n   |\nLL |     let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);\nLL +     let _ = Ok::<i32, i32>(5) == Ok(5);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:39:13\n   |\nLL |     let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);\nLL +     let _ = (Some(5) == Some(5)).then(|| 1);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:41:13\n   |\nLL |     let _ = Some(5).map_or(true, |n| n == 5);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_none_or` instead\n   |\nLL -     let _ = Some(5).map_or(true, |n| n == 5);\nLL +     let _ = Some(5).is_none_or(|n| n == 5);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:43:13\n   |\nLL |     let _ = Some(5).map_or(true, |n| 5 == n);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_none_or` instead\n   |\nLL -     let _ = Some(5).map_or(true, |n| 5 == n);\nLL +     let _ = Some(5).is_none_or(|n| 5 == n);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:45:14\n   |\nLL |     let _ = !Some(5).map_or(false, |n| n == 5);\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     let _ = !Some(5).map_or(false, |n| n == 5);\nLL +     let _ = !(Some(5) == Some(5));\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:47:13\n   |\nLL |     let _ = Some(5).map_or(false, |n| n == 5) || false;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     let _ = Some(5).map_or(false, |n| n == 5) || false;\nLL +     let _ = (Some(5) == Some(5)) || false;\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:49:13\n   |\nLL |     let _ = Some(5).map_or(false, |n| n == 5) as usize;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     let _ = Some(5).map_or(false, |n| n == 5) as usize;\nLL +     let _ = (Some(5) == Some(5)) as usize;\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:74:13\n   |\nLL |     let _ = r.map_or(false, |x| x == 7);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_ok_and` instead\n   |\nLL -     let _ = r.map_or(false, |x| x == 7);\nLL +     let _ = r.is_ok_and(|x| x == 7);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:80:13\n   |\nLL |     let _ = r.map_or(false, func);\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_ok_and` instead\n   |\nLL -     let _ = r.map_or(false, func);\nLL +     let _ = r.is_ok_and(func);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:82:13\n   |\nLL |     let _ = Some(5).map_or(false, func);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     let _ = Some(5).map_or(false, func);\nLL +     let _ = Some(5).is_some_and(func);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:84:13\n   |\nLL |     let _ = Some(5).map_or(true, func);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_none_or` instead\n   |\nLL -     let _ = Some(5).map_or(true, func);\nLL +     let _ = Some(5).is_none_or(func);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:90:13\n   |\nLL |     let _ = r.map_or(false, |x| x == 8);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     let _ = r.map_or(false, |x| x == 8);\nLL +     let _ = r == Ok(8);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:111:5\n   |\nLL |     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_none_or` instead\n   |\nLL -     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)\nLL +     o.is_none_or(|n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:111:34\n   |\nLL |     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_none_or` instead\n   |\nLL -     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)\nLL +     o.map_or(true, |n| n > 5) || (o as &Option<u32>).is_none_or(|n| n < 5)\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:126:5\n   |\nLL |     o.map_or(true, |n| n > 5)\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_none_or` instead\n   |\nLL -     o.map_or(true, |n| n > 5)\nLL +     o.is_none_or(|n| n > 5)\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:131:13\n   |\nLL |     let x = a.map_or(false, |a| a == *s);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     let x = a.map_or(false, |a| a == *s);\nLL +     let x = a.is_some_and(|a| a == *s);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:133:13\n   |\nLL |     let y = b.map_or(true, |b| b == *s);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_none_or` instead\n   |\nLL -     let y = b.map_or(true, |b| b == *s);\nLL +     let y = b.is_none_or(|b| b == *s);\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:139:13\n   |\nLL |     assert!(Some(\"test\").map_or(false, |x| x == \"test\"));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     assert!(Some(\"test\").map_or(false, |x| x == \"test\"));\nLL +     assert!(Some(\"test\") == Some(\"test\"));\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:143:13\n   |\nLL |     assert!(Some(\"test\").map_or(false, |x| x == \"test\").then(|| 1).is_some());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use a standard comparison instead\n   |\nLL -     assert!(Some(\"test\").map_or(false, |x| x == \"test\").then(|| 1).is_some());\nLL +     assert!((Some(\"test\") == Some(\"test\")).then(|| 1).is_some());\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:160:9\n   |\nLL |     _ = s.lock().unwrap().map_or(false, |s| s == \"foo\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     _ = s.lock().unwrap().map_or(false, |s| s == \"foo\");\nLL +     _ = s.lock().unwrap().is_some_and(|s| s == \"foo\");\n   |\n\nerror: this `map_or` can be simplified\n  --> tests/ui/unnecessary_map_or.rs:164:9\n   |\nLL |     _ = s.map_or(false, |s| s == \"foo\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `is_some_and` instead\n   |\nLL -     _ = s.map_or(false, |s| s == \"foo\");\nLL +     _ = s.is_some_and(|s| s == \"foo\");\n   |\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_min_or_max.fixed",
    "content": "//@aux-build:external_consts.rs\n\n#![allow(unused)]\n#![warn(clippy::unnecessary_min_or_max)]\n#![allow(clippy::identity_op)]\n\nextern crate external_consts;\n\nconst X: i32 = 1;\n\nfn main() {\n    // Both are Literals\n    let _ = (-6_i32);\n    //~^ unnecessary_min_or_max\n    let _ = 9;\n    //~^ unnecessary_min_or_max\n    let _ = 6;\n    //~^ unnecessary_min_or_max\n    let _ = 9_u32;\n    //~^ unnecessary_min_or_max\n    let _ = 6;\n    //~^ unnecessary_min_or_max\n    let _ = 7_u8;\n    //~^ unnecessary_min_or_max\n\n    let x: u32 = 42;\n    // unsigned with zero\n    let _ = 0;\n    //~^ unnecessary_min_or_max\n    let _ = x;\n    //~^ unnecessary_min_or_max\n    let _ = 0_u32;\n    //~^ unnecessary_min_or_max\n    let _ = x;\n    //~^ unnecessary_min_or_max\n\n    let x: i32 = 42;\n    // signed MIN\n    let _ = i32::MIN;\n    //~^ unnecessary_min_or_max\n    let _ = x;\n    //~^ unnecessary_min_or_max\n    let _ = i32::MIN;\n    //~^ unnecessary_min_or_max\n    let _ = x;\n    //~^ unnecessary_min_or_max\n\n    let _ = i32::MIN - 0;\n    //~^ unnecessary_min_or_max\n    let _ = x;\n    //~^ unnecessary_min_or_max\n\n    let _ = i32::MIN - 0;\n    //~^ unnecessary_min_or_max\n\n    // The below cases shouldn't be lint\n    let mut min = u32::MAX;\n    for _ in 0..1000 {\n        min = min.min(random_u32());\n    }\n\n    let _ = 2.min(external_consts::MAGIC_NUMBER);\n    let _ = 2.max(external_consts::MAGIC_NUMBER);\n    let _ = external_consts::MAGIC_NUMBER.min(2);\n    let _ = external_consts::MAGIC_NUMBER.max(2);\n\n    let _ = X.min(external_consts::MAGIC_NUMBER);\n    let _ = X.max(external_consts::MAGIC_NUMBER);\n    let _ = external_consts::MAGIC_NUMBER.min(X);\n    let _ = external_consts::MAGIC_NUMBER.max(X);\n\n    let _ = X.max(12);\n    let _ = X.min(12);\n    let _ = 12.min(X);\n    let _ = 12.max(X);\n    let _ = (X + 1).max(12);\n    let _ = (X + 1).min(12);\n    let _ = 12.min(X - 1);\n    let _ = 12.max(X - 1);\n\n    let n: usize = 42;\n\n    let _ = 0;\n    //~^ unnecessary_min_or_max\n\n    let _ = 0usize;\n    //~^ unnecessary_min_or_max\n\n    let _ = (0usize);\n    //~^ unnecessary_min_or_max\n\n    let _ = usize::MIN;\n    //~^ unnecessary_min_or_max\n\n    let _ = usize::MAX;\n    //~^ unnecessary_min_or_max\n\n    let _ = (usize::MAX);\n    //~^ unnecessary_min_or_max\n\n    let _ = !0usize;\n    //~^ unnecessary_min_or_max\n\n    let _ = n;\n    //~^ unnecessary_min_or_max\n}\nfn random_u32() -> u32 {\n    // random number generator\n    0\n}\n\nstruct Issue13191 {\n    min: u16,\n    max: u16,\n}\n\nimpl Issue13191 {\n    fn new() -> Self {\n        Self { min: 0, max: 0 }\n    }\n\n    fn min(mut self, value: u16) -> Self {\n        self.min = value;\n        self\n    }\n\n    fn max(mut self, value: u16) -> Self {\n        self.max = value;\n        self\n    }\n}\n\nfn issue_13191() {\n    // should not fixed\n    Issue13191::new().min(0);\n\n    // should not fixed\n    Issue13191::new().max(0);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_min_or_max.rs",
    "content": "//@aux-build:external_consts.rs\n\n#![allow(unused)]\n#![warn(clippy::unnecessary_min_or_max)]\n#![allow(clippy::identity_op)]\n\nextern crate external_consts;\n\nconst X: i32 = 1;\n\nfn main() {\n    // Both are Literals\n    let _ = (-6_i32).min(9);\n    //~^ unnecessary_min_or_max\n    let _ = (-6_i32).max(9);\n    //~^ unnecessary_min_or_max\n    let _ = 9_u32.min(6);\n    //~^ unnecessary_min_or_max\n    let _ = 9_u32.max(6);\n    //~^ unnecessary_min_or_max\n    let _ = 6.min(7_u8);\n    //~^ unnecessary_min_or_max\n    let _ = 6.max(7_u8);\n    //~^ unnecessary_min_or_max\n\n    let x: u32 = 42;\n    // unsigned with zero\n    let _ = 0.min(x);\n    //~^ unnecessary_min_or_max\n    let _ = 0.max(x);\n    //~^ unnecessary_min_or_max\n    let _ = x.min(0_u32);\n    //~^ unnecessary_min_or_max\n    let _ = x.max(0_u32);\n    //~^ unnecessary_min_or_max\n\n    let x: i32 = 42;\n    // signed MIN\n    let _ = i32::MIN.min(x);\n    //~^ unnecessary_min_or_max\n    let _ = i32::MIN.max(x);\n    //~^ unnecessary_min_or_max\n    let _ = x.min(i32::MIN);\n    //~^ unnecessary_min_or_max\n    let _ = x.max(i32::MIN);\n    //~^ unnecessary_min_or_max\n\n    let _ = x.min(i32::MIN - 0);\n    //~^ unnecessary_min_or_max\n    let _ = x.max(i32::MIN);\n    //~^ unnecessary_min_or_max\n\n    let _ = x.min(i32::MIN - 0);\n    //~^ unnecessary_min_or_max\n\n    // The below cases shouldn't be lint\n    let mut min = u32::MAX;\n    for _ in 0..1000 {\n        min = min.min(random_u32());\n    }\n\n    let _ = 2.min(external_consts::MAGIC_NUMBER);\n    let _ = 2.max(external_consts::MAGIC_NUMBER);\n    let _ = external_consts::MAGIC_NUMBER.min(2);\n    let _ = external_consts::MAGIC_NUMBER.max(2);\n\n    let _ = X.min(external_consts::MAGIC_NUMBER);\n    let _ = X.max(external_consts::MAGIC_NUMBER);\n    let _ = external_consts::MAGIC_NUMBER.min(X);\n    let _ = external_consts::MAGIC_NUMBER.max(X);\n\n    let _ = X.max(12);\n    let _ = X.min(12);\n    let _ = 12.min(X);\n    let _ = 12.max(X);\n    let _ = (X + 1).max(12);\n    let _ = (X + 1).min(12);\n    let _ = 12.min(X - 1);\n    let _ = 12.max(X - 1);\n\n    let n: usize = 42;\n\n    let _ = n.min(0);\n    //~^ unnecessary_min_or_max\n\n    let _ = n.min(0usize);\n    //~^ unnecessary_min_or_max\n\n    let _ = (0usize).min(n);\n    //~^ unnecessary_min_or_max\n\n    let _ = n.min(usize::MIN);\n    //~^ unnecessary_min_or_max\n\n    let _ = n.max(usize::MAX);\n    //~^ unnecessary_min_or_max\n\n    let _ = (usize::MAX).max(n);\n    //~^ unnecessary_min_or_max\n\n    let _ = n.max(!0usize);\n    //~^ unnecessary_min_or_max\n\n    let _ = n.max(0);\n    //~^ unnecessary_min_or_max\n}\nfn random_u32() -> u32 {\n    // random number generator\n    0\n}\n\nstruct Issue13191 {\n    min: u16,\n    max: u16,\n}\n\nimpl Issue13191 {\n    fn new() -> Self {\n        Self { min: 0, max: 0 }\n    }\n\n    fn min(mut self, value: u16) -> Self {\n        self.min = value;\n        self\n    }\n\n    fn max(mut self, value: u16) -> Self {\n        self.max = value;\n        self\n    }\n}\n\nfn issue_13191() {\n    // should not fixed\n    Issue13191::new().min(0);\n\n    // should not fixed\n    Issue13191::new().max(0);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_min_or_max.stderr",
    "content": "error: `(-6_i32)` is never greater than `9` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:13:13\n   |\nLL |     let _ = (-6_i32).min(9);\n   |             ^^^^^^^^^^^^^^^ help: try: `(-6_i32)`\n   |\n   = note: `-D clippy::unnecessary-min-or-max` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_min_or_max)]`\n\nerror: `(-6_i32)` is never greater than `9` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:15:13\n   |\nLL |     let _ = (-6_i32).max(9);\n   |             ^^^^^^^^^^^^^^^ help: try: `9`\n\nerror: `9_u32` is never smaller than `6` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:17:13\n   |\nLL |     let _ = 9_u32.min(6);\n   |             ^^^^^^^^^^^^ help: try: `6`\n\nerror: `9_u32` is never smaller than `6` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:19:13\n   |\nLL |     let _ = 9_u32.max(6);\n   |             ^^^^^^^^^^^^ help: try: `9_u32`\n\nerror: `6` is never greater than `7_u8` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:21:13\n   |\nLL |     let _ = 6.min(7_u8);\n   |             ^^^^^^^^^^^ help: try: `6`\n\nerror: `6` is never greater than `7_u8` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:23:13\n   |\nLL |     let _ = 6.max(7_u8);\n   |             ^^^^^^^^^^^ help: try: `7_u8`\n\nerror: `0` is never greater than `x` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:28:13\n   |\nLL |     let _ = 0.min(x);\n   |             ^^^^^^^^ help: try: `0`\n\nerror: `0` is never greater than `x` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:30:13\n   |\nLL |     let _ = 0.max(x);\n   |             ^^^^^^^^ help: try: `x`\n\nerror: `x` is never smaller than `0_u32` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:32:13\n   |\nLL |     let _ = x.min(0_u32);\n   |             ^^^^^^^^^^^^ help: try: `0_u32`\n\nerror: `x` is never smaller than `0_u32` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:34:13\n   |\nLL |     let _ = x.max(0_u32);\n   |             ^^^^^^^^^^^^ help: try: `x`\n\nerror: `i32::MIN` is never greater than `x` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:39:13\n   |\nLL |     let _ = i32::MIN.min(x);\n   |             ^^^^^^^^^^^^^^^ help: try: `i32::MIN`\n\nerror: `i32::MIN` is never greater than `x` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:41:13\n   |\nLL |     let _ = i32::MIN.max(x);\n   |             ^^^^^^^^^^^^^^^ help: try: `x`\n\nerror: `x` is never smaller than `i32::MIN` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:43:13\n   |\nLL |     let _ = x.min(i32::MIN);\n   |             ^^^^^^^^^^^^^^^ help: try: `i32::MIN`\n\nerror: `x` is never smaller than `i32::MIN` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:45:13\n   |\nLL |     let _ = x.max(i32::MIN);\n   |             ^^^^^^^^^^^^^^^ help: try: `x`\n\nerror: `x` is never smaller than `i32::MIN - 0` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:48:13\n   |\nLL |     let _ = x.min(i32::MIN - 0);\n   |             ^^^^^^^^^^^^^^^^^^^ help: try: `i32::MIN - 0`\n\nerror: `x` is never smaller than `i32::MIN` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:50:13\n   |\nLL |     let _ = x.max(i32::MIN);\n   |             ^^^^^^^^^^^^^^^ help: try: `x`\n\nerror: `x` is never smaller than `i32::MIN - 0` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:53:13\n   |\nLL |     let _ = x.min(i32::MIN - 0);\n   |             ^^^^^^^^^^^^^^^^^^^ help: try: `i32::MIN - 0`\n\nerror: `n` is never smaller than `0` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:83:13\n   |\nLL |     let _ = n.min(0);\n   |             ^^^^^^^^ help: try: `0`\n\nerror: `n` is never smaller than `0usize` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:86:13\n   |\nLL |     let _ = n.min(0usize);\n   |             ^^^^^^^^^^^^^ help: try: `0usize`\n\nerror: `(0usize)` is never greater than `n` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:89:13\n   |\nLL |     let _ = (0usize).min(n);\n   |             ^^^^^^^^^^^^^^^ help: try: `(0usize)`\n\nerror: `n` is never smaller than `usize::MIN` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:92:13\n   |\nLL |     let _ = n.min(usize::MIN);\n   |             ^^^^^^^^^^^^^^^^^ help: try: `usize::MIN`\n\nerror: `n` is never greater than `usize::MAX` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:95:13\n   |\nLL |     let _ = n.max(usize::MAX);\n   |             ^^^^^^^^^^^^^^^^^ help: try: `usize::MAX`\n\nerror: `(usize::MAX)` is never smaller than `n` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:98:13\n   |\nLL |     let _ = (usize::MAX).max(n);\n   |             ^^^^^^^^^^^^^^^^^^^ help: try: `(usize::MAX)`\n\nerror: `n` is never greater than `!0usize` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:101:13\n   |\nLL |     let _ = n.max(!0usize);\n   |             ^^^^^^^^^^^^^^ help: try: `!0usize`\n\nerror: `n` is never smaller than `0` and has therefore no effect\n  --> tests/ui/unnecessary_min_or_max.rs:104:13\n   |\nLL |     let _ = n.max(0);\n   |             ^^^^^^^^ help: try: `n`\n\nerror: aborting due to 25 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_mut_passed.fixed",
    "content": "#![allow(clippy::mut_mut)]\n\nfn takes_ref(a: &i32) {}\nfn takes_refmut(a: &mut i32) {}\nfn takes_ref_ref(a: &&i32) {}\nfn takes_refmut_ref(a: &mut &i32) {}\nfn takes_ref_refmut(a: &&mut i32) {}\nfn takes_refmut_refmut(a: &mut &mut i32) {}\nfn takes_raw_const(a: *const i32) {}\nfn takes_raw_mut(a: *mut i32) {}\n\nmod issue11268 {\n    macro_rules! x {\n        (1 $f:expr) => {\n            $f(&mut 1);\n        };\n        (2 $f:expr) => {\n            $f(&mut &1)\n        };\n        (3 $f:expr) => {\n            $f(&mut &mut 1)\n        };\n        (4 $f:expr) => {\n            let mut a = 1;\n            $f(&raw mut a)\n        };\n    }\n\n    fn f() {\n        x!(1 super::takes_ref);\n        x!(1 super::takes_refmut);\n        x!(2 super::takes_refmut_ref);\n        x!(3 super::takes_ref_refmut);\n        x!(3 super::takes_refmut_refmut);\n        x!(4 super::takes_raw_const);\n        x!(4 super::takes_raw_mut);\n    }\n}\n\nstruct MyStruct;\n\nimpl MyStruct {\n    fn takes_nothing(&self) {}\n    fn takes_ref(&self, a: &i32) {}\n    fn takes_refmut(&self, a: &mut i32) {}\n    fn takes_ref_ref(&self, a: &&i32) {}\n    fn takes_refmut_ref(&self, a: &mut &i32) {}\n    fn takes_ref_refmut(&self, a: &&mut i32) {}\n    fn takes_refmut_refmut(&self, a: &mut &mut i32) {}\n    fn takes_raw_const(&self, a: *const i32) {}\n    fn takes_raw_mut(&self, a: *mut i32) {}\n}\n\n#[warn(clippy::unnecessary_mut_passed)]\nfn main() {\n    // Functions\n    takes_ref(&42);\n    //~^ unnecessary_mut_passed\n    takes_ref_ref(&&42);\n    //~^ unnecessary_mut_passed\n    takes_ref_refmut(&&mut 42);\n    //~^ unnecessary_mut_passed\n    takes_raw_const(&42);\n    //~^ unnecessary_mut_passed\n\n    let as_ptr: fn(&i32) = takes_ref;\n    as_ptr(&42);\n    //~^ unnecessary_mut_passed\n    let as_ptr: fn(&&i32) = takes_ref_ref;\n    as_ptr(&&42);\n    //~^ unnecessary_mut_passed\n    let as_ptr: fn(&&mut i32) = takes_ref_refmut;\n    as_ptr(&&mut 42);\n    //~^ unnecessary_mut_passed\n    let as_ptr: fn(*const i32) = takes_raw_const;\n    as_ptr(&42);\n    //~^ unnecessary_mut_passed\n\n    // Methods\n    let my_struct = MyStruct;\n    my_struct.takes_ref(&42);\n    //~^ unnecessary_mut_passed\n    my_struct.takes_ref_ref(&&42);\n    //~^ unnecessary_mut_passed\n    my_struct.takes_ref_refmut(&&mut 42);\n    //~^ unnecessary_mut_passed\n    my_struct.takes_raw_const(&42);\n    //~^ unnecessary_mut_passed\n\n    // No error\n\n    // Functions\n    takes_ref(&42);\n    let as_ptr: fn(&i32) = takes_ref;\n    as_ptr(&42);\n\n    takes_refmut(&mut 42);\n    let as_ptr: fn(&mut i32) = takes_refmut;\n    as_ptr(&mut 42);\n\n    takes_ref_ref(&&42);\n    let as_ptr: fn(&&i32) = takes_ref_ref;\n    as_ptr(&&42);\n\n    takes_refmut_ref(&mut &42);\n    let as_ptr: fn(&mut &i32) = takes_refmut_ref;\n    as_ptr(&mut &42);\n\n    takes_ref_refmut(&&mut 42);\n    let as_ptr: fn(&&mut i32) = takes_ref_refmut;\n    as_ptr(&&mut 42);\n\n    takes_refmut_refmut(&mut &mut 42);\n    let as_ptr: fn(&mut &mut i32) = takes_refmut_refmut;\n    as_ptr(&mut &mut 42);\n\n    takes_raw_const(&42);\n    let as_ptr: fn(*const i32) = takes_raw_const;\n    as_ptr(&42);\n\n    takes_raw_mut(&mut 42);\n    let as_ptr: fn(*mut i32) = takes_raw_mut;\n    as_ptr(&mut 42);\n\n    let a = &mut 42;\n    let b = &mut &42;\n    let c = &mut &mut 42;\n    takes_ref(a);\n    takes_ref_ref(b);\n    takes_ref_refmut(c);\n    takes_raw_const(a);\n\n    // Methods\n    my_struct.takes_ref(&42);\n    my_struct.takes_refmut(&mut 42);\n    my_struct.takes_ref_ref(&&42);\n    my_struct.takes_refmut_ref(&mut &42);\n    my_struct.takes_ref_refmut(&&mut 42);\n    my_struct.takes_refmut_refmut(&mut &mut 42);\n    my_struct.takes_raw_const(&42);\n    my_struct.takes_raw_mut(&mut 42);\n    my_struct.takes_ref(a);\n    my_struct.takes_ref_ref(b);\n    my_struct.takes_ref_refmut(c);\n    my_struct.takes_raw_const(a);\n    my_struct.takes_raw_mut(a);\n}\n\n// These shouldn't be linted, see https://github.com/rust-lang/rust-clippy/pull/15962#issuecomment-3503704832\nfn raw_ptrs(my_struct: MyStruct) {\n    let mut n = 42;\n\n    takes_raw_const(&raw mut n);\n\n    let as_ptr: fn(*const i32) = takes_raw_const;\n    as_ptr(&raw mut n);\n\n    my_struct.takes_raw_const(&raw mut n);\n\n    // No error\n\n    takes_raw_const(&raw const n);\n    takes_raw_mut(&raw mut n);\n\n    let a = &raw mut n;\n    takes_raw_const(a);\n\n    my_struct.takes_raw_const(&raw const n);\n    my_struct.takes_raw_mut(&raw mut n);\n    my_struct.takes_raw_const(a);\n}\n\n#[expect(clippy::needless_borrow)]\nfn issue15722(mut my_struct: MyStruct) {\n    (&my_struct).takes_nothing();\n    //~^ unnecessary_mut_passed\n    (&my_struct).takes_nothing();\n\n    // Only put parens around the argument that used to have it\n    (&my_struct).takes_ref(&42);\n    //~^ unnecessary_mut_passed\n    //~| unnecessary_mut_passed\n    #[expect(clippy::double_parens)]\n    (&my_struct).takes_ref((&42));\n    //~^ unnecessary_mut_passed\n    //~| unnecessary_mut_passed\n    #[expect(clippy::double_parens)]\n    my_struct.takes_ref((&42));\n    //~^ unnecessary_mut_passed\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_mut_passed.rs",
    "content": "#![allow(clippy::mut_mut)]\n\nfn takes_ref(a: &i32) {}\nfn takes_refmut(a: &mut i32) {}\nfn takes_ref_ref(a: &&i32) {}\nfn takes_refmut_ref(a: &mut &i32) {}\nfn takes_ref_refmut(a: &&mut i32) {}\nfn takes_refmut_refmut(a: &mut &mut i32) {}\nfn takes_raw_const(a: *const i32) {}\nfn takes_raw_mut(a: *mut i32) {}\n\nmod issue11268 {\n    macro_rules! x {\n        (1 $f:expr) => {\n            $f(&mut 1);\n        };\n        (2 $f:expr) => {\n            $f(&mut &1)\n        };\n        (3 $f:expr) => {\n            $f(&mut &mut 1)\n        };\n        (4 $f:expr) => {\n            let mut a = 1;\n            $f(&raw mut a)\n        };\n    }\n\n    fn f() {\n        x!(1 super::takes_ref);\n        x!(1 super::takes_refmut);\n        x!(2 super::takes_refmut_ref);\n        x!(3 super::takes_ref_refmut);\n        x!(3 super::takes_refmut_refmut);\n        x!(4 super::takes_raw_const);\n        x!(4 super::takes_raw_mut);\n    }\n}\n\nstruct MyStruct;\n\nimpl MyStruct {\n    fn takes_nothing(&self) {}\n    fn takes_ref(&self, a: &i32) {}\n    fn takes_refmut(&self, a: &mut i32) {}\n    fn takes_ref_ref(&self, a: &&i32) {}\n    fn takes_refmut_ref(&self, a: &mut &i32) {}\n    fn takes_ref_refmut(&self, a: &&mut i32) {}\n    fn takes_refmut_refmut(&self, a: &mut &mut i32) {}\n    fn takes_raw_const(&self, a: *const i32) {}\n    fn takes_raw_mut(&self, a: *mut i32) {}\n}\n\n#[warn(clippy::unnecessary_mut_passed)]\nfn main() {\n    // Functions\n    takes_ref(&mut 42);\n    //~^ unnecessary_mut_passed\n    takes_ref_ref(&mut &42);\n    //~^ unnecessary_mut_passed\n    takes_ref_refmut(&mut &mut 42);\n    //~^ unnecessary_mut_passed\n    takes_raw_const(&mut 42);\n    //~^ unnecessary_mut_passed\n\n    let as_ptr: fn(&i32) = takes_ref;\n    as_ptr(&mut 42);\n    //~^ unnecessary_mut_passed\n    let as_ptr: fn(&&i32) = takes_ref_ref;\n    as_ptr(&mut &42);\n    //~^ unnecessary_mut_passed\n    let as_ptr: fn(&&mut i32) = takes_ref_refmut;\n    as_ptr(&mut &mut 42);\n    //~^ unnecessary_mut_passed\n    let as_ptr: fn(*const i32) = takes_raw_const;\n    as_ptr(&mut 42);\n    //~^ unnecessary_mut_passed\n\n    // Methods\n    let my_struct = MyStruct;\n    my_struct.takes_ref(&mut 42);\n    //~^ unnecessary_mut_passed\n    my_struct.takes_ref_ref(&mut &42);\n    //~^ unnecessary_mut_passed\n    my_struct.takes_ref_refmut(&mut &mut 42);\n    //~^ unnecessary_mut_passed\n    my_struct.takes_raw_const(&mut 42);\n    //~^ unnecessary_mut_passed\n\n    // No error\n\n    // Functions\n    takes_ref(&42);\n    let as_ptr: fn(&i32) = takes_ref;\n    as_ptr(&42);\n\n    takes_refmut(&mut 42);\n    let as_ptr: fn(&mut i32) = takes_refmut;\n    as_ptr(&mut 42);\n\n    takes_ref_ref(&&42);\n    let as_ptr: fn(&&i32) = takes_ref_ref;\n    as_ptr(&&42);\n\n    takes_refmut_ref(&mut &42);\n    let as_ptr: fn(&mut &i32) = takes_refmut_ref;\n    as_ptr(&mut &42);\n\n    takes_ref_refmut(&&mut 42);\n    let as_ptr: fn(&&mut i32) = takes_ref_refmut;\n    as_ptr(&&mut 42);\n\n    takes_refmut_refmut(&mut &mut 42);\n    let as_ptr: fn(&mut &mut i32) = takes_refmut_refmut;\n    as_ptr(&mut &mut 42);\n\n    takes_raw_const(&42);\n    let as_ptr: fn(*const i32) = takes_raw_const;\n    as_ptr(&42);\n\n    takes_raw_mut(&mut 42);\n    let as_ptr: fn(*mut i32) = takes_raw_mut;\n    as_ptr(&mut 42);\n\n    let a = &mut 42;\n    let b = &mut &42;\n    let c = &mut &mut 42;\n    takes_ref(a);\n    takes_ref_ref(b);\n    takes_ref_refmut(c);\n    takes_raw_const(a);\n\n    // Methods\n    my_struct.takes_ref(&42);\n    my_struct.takes_refmut(&mut 42);\n    my_struct.takes_ref_ref(&&42);\n    my_struct.takes_refmut_ref(&mut &42);\n    my_struct.takes_ref_refmut(&&mut 42);\n    my_struct.takes_refmut_refmut(&mut &mut 42);\n    my_struct.takes_raw_const(&42);\n    my_struct.takes_raw_mut(&mut 42);\n    my_struct.takes_ref(a);\n    my_struct.takes_ref_ref(b);\n    my_struct.takes_ref_refmut(c);\n    my_struct.takes_raw_const(a);\n    my_struct.takes_raw_mut(a);\n}\n\n// These shouldn't be linted, see https://github.com/rust-lang/rust-clippy/pull/15962#issuecomment-3503704832\nfn raw_ptrs(my_struct: MyStruct) {\n    let mut n = 42;\n\n    takes_raw_const(&raw mut n);\n\n    let as_ptr: fn(*const i32) = takes_raw_const;\n    as_ptr(&raw mut n);\n\n    my_struct.takes_raw_const(&raw mut n);\n\n    // No error\n\n    takes_raw_const(&raw const n);\n    takes_raw_mut(&raw mut n);\n\n    let a = &raw mut n;\n    takes_raw_const(a);\n\n    my_struct.takes_raw_const(&raw const n);\n    my_struct.takes_raw_mut(&raw mut n);\n    my_struct.takes_raw_const(a);\n}\n\n#[expect(clippy::needless_borrow)]\nfn issue15722(mut my_struct: MyStruct) {\n    (&mut my_struct).takes_nothing();\n    //~^ unnecessary_mut_passed\n    (&my_struct).takes_nothing();\n\n    // Only put parens around the argument that used to have it\n    (&mut my_struct).takes_ref(&mut 42);\n    //~^ unnecessary_mut_passed\n    //~| unnecessary_mut_passed\n    #[expect(clippy::double_parens)]\n    (&mut my_struct).takes_ref((&mut 42));\n    //~^ unnecessary_mut_passed\n    //~| unnecessary_mut_passed\n    #[expect(clippy::double_parens)]\n    my_struct.takes_ref((&mut 42));\n    //~^ unnecessary_mut_passed\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_mut_passed.stderr",
    "content": "error: the function `takes_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:57:15\n   |\nLL |     takes_ref(&mut 42);\n   |               ^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-mut-passed` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_mut_passed)]`\nhelp: remove this `mut`\n   |\nLL -     takes_ref(&mut 42);\nLL +     takes_ref(&42);\n   |\n\nerror: the function `takes_ref_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:59:19\n   |\nLL |     takes_ref_ref(&mut &42);\n   |                   ^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     takes_ref_ref(&mut &42);\nLL +     takes_ref_ref(&&42);\n   |\n\nerror: the function `takes_ref_refmut` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:61:22\n   |\nLL |     takes_ref_refmut(&mut &mut 42);\n   |                      ^^^^^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     takes_ref_refmut(&mut &mut 42);\nLL +     takes_ref_refmut(&&mut 42);\n   |\n\nerror: the function `takes_raw_const` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:63:21\n   |\nLL |     takes_raw_const(&mut 42);\n   |                     ^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     takes_raw_const(&mut 42);\nLL +     takes_raw_const(&42);\n   |\n\nerror: the function `as_ptr` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:67:12\n   |\nLL |     as_ptr(&mut 42);\n   |            ^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     as_ptr(&mut 42);\nLL +     as_ptr(&42);\n   |\n\nerror: the function `as_ptr` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:70:12\n   |\nLL |     as_ptr(&mut &42);\n   |            ^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     as_ptr(&mut &42);\nLL +     as_ptr(&&42);\n   |\n\nerror: the function `as_ptr` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:73:12\n   |\nLL |     as_ptr(&mut &mut 42);\n   |            ^^^^^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     as_ptr(&mut &mut 42);\nLL +     as_ptr(&&mut 42);\n   |\n\nerror: the function `as_ptr` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:76:12\n   |\nLL |     as_ptr(&mut 42);\n   |            ^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     as_ptr(&mut 42);\nLL +     as_ptr(&42);\n   |\n\nerror: the method `takes_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:81:25\n   |\nLL |     my_struct.takes_ref(&mut 42);\n   |                         ^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     my_struct.takes_ref(&mut 42);\nLL +     my_struct.takes_ref(&42);\n   |\n\nerror: the method `takes_ref_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:83:29\n   |\nLL |     my_struct.takes_ref_ref(&mut &42);\n   |                             ^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     my_struct.takes_ref_ref(&mut &42);\nLL +     my_struct.takes_ref_ref(&&42);\n   |\n\nerror: the method `takes_ref_refmut` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:85:32\n   |\nLL |     my_struct.takes_ref_refmut(&mut &mut 42);\n   |                                ^^^^^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     my_struct.takes_ref_refmut(&mut &mut 42);\nLL +     my_struct.takes_ref_refmut(&&mut 42);\n   |\n\nerror: the method `takes_raw_const` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:87:31\n   |\nLL |     my_struct.takes_raw_const(&mut 42);\n   |                               ^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     my_struct.takes_raw_const(&mut 42);\nLL +     my_struct.takes_raw_const(&42);\n   |\n\nerror: the method `takes_nothing` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:175:5\n   |\nLL |     (&mut my_struct).takes_nothing();\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     (&mut my_struct).takes_nothing();\nLL +     (&my_struct).takes_nothing();\n   |\n\nerror: the method `takes_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:180:5\n   |\nLL |     (&mut my_struct).takes_ref(&mut 42);\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     (&mut my_struct).takes_ref(&mut 42);\nLL +     (&my_struct).takes_ref(&mut 42);\n   |\n\nerror: the method `takes_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:180:32\n   |\nLL |     (&mut my_struct).takes_ref(&mut 42);\n   |                                ^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     (&mut my_struct).takes_ref(&mut 42);\nLL +     (&mut my_struct).takes_ref(&42);\n   |\n\nerror: the method `takes_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:184:5\n   |\nLL |     (&mut my_struct).takes_ref((&mut 42));\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     (&mut my_struct).takes_ref((&mut 42));\nLL +     (&my_struct).takes_ref((&mut 42));\n   |\n\nerror: the method `takes_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:184:32\n   |\nLL |     (&mut my_struct).takes_ref((&mut 42));\n   |                                ^^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     (&mut my_struct).takes_ref((&mut 42));\nLL +     (&mut my_struct).takes_ref((&42));\n   |\n\nerror: the method `takes_ref` doesn't need a mutable reference\n  --> tests/ui/unnecessary_mut_passed.rs:188:25\n   |\nLL |     my_struct.takes_ref((&mut 42));\n   |                         ^^^^^^^^^\n   |\nhelp: remove this `mut`\n   |\nLL -     my_struct.takes_ref((&mut 42));\nLL +     my_struct.takes_ref((&42));\n   |\n\nerror: aborting due to 18 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_operation.fixed",
    "content": "#![allow(\n    clippy::deref_addrof,\n    clippy::no_effect,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_struct_initialization,\n    dead_code,\n    unused\n)]\n#![warn(clippy::unnecessary_operation)]\n\nuse std::fmt::Display;\nuse std::ops::Shl;\n\nstruct Tuple(i32);\nstruct Struct {\n    field: i32,\n}\nenum Enum {\n    Tuple(i32),\n    Struct { field: i32 },\n}\nstruct DropStruct {\n    field: i32,\n}\nimpl Drop for DropStruct {\n    fn drop(&mut self) {}\n}\nstruct DropTuple(i32);\nimpl Drop for DropTuple {\n    fn drop(&mut self) {}\n}\nenum DropEnum {\n    Tuple(i32),\n    Struct { field: i32 },\n}\nimpl Drop for DropEnum {\n    fn drop(&mut self) {}\n}\nstruct FooString {\n    s: String,\n}\n\nfn get_number() -> i32 {\n    0\n}\n\nconst fn get_usize() -> usize {\n    0\n}\nfn get_struct() -> Struct {\n    Struct { field: 0 }\n}\nfn get_drop_struct() -> DropStruct {\n    DropStruct { field: 0 }\n}\n\nstruct Cout;\n\nimpl<T> Shl<T> for Cout\nwhere\n    T: Display,\n{\n    type Output = Self;\n    fn shl(self, rhs: T) -> Self::Output {\n        println!(\"{}\", rhs);\n        self\n    }\n}\n\nfn main() {\n    get_number();\n    //~^ unnecessary_operation\n    get_number();\n    //~^ unnecessary_operation\n    get_struct();\n    //~^ unnecessary_operation\n    get_number();\n    //~^ unnecessary_operation\n    get_number();\n    //~^ unnecessary_operation\n    5; get_number();\n    //~^ unnecessary_operation\n    get_number();\n    //~^ unnecessary_operation\n    get_number();\n    //~^ unnecessary_operation\n    5; 6; get_number();\n    //~^ unnecessary_operation\n    get_number();\n    //~^ unnecessary_operation\n    get_number();\n    //~^ unnecessary_operation\n    5; get_number();\n    //~^ unnecessary_operation\n    42; get_number();\n    //~^ unnecessary_operation\n    assert!([42, 55].len() > get_usize());\n    //~^ unnecessary_operation\n    42; get_number();\n    //~^ unnecessary_operation\n    get_number();\n    //~^ unnecessary_operation\n    assert!([42; 55].len() > get_usize());\n    //~^ unnecessary_operation\n    get_number();\n    String::from(\"blah\");\n\n    // Do not warn\n    DropTuple(get_number());\n    DropStruct { field: get_number() };\n    DropStruct { field: get_number() };\n    DropStruct { ..get_drop_struct() };\n    DropEnum::Tuple(get_number());\n    DropEnum::Struct { field: get_number() };\n\n    // Issue #9954\n    fn one() -> i8 {\n        1\n    }\n    macro_rules! use_expr {\n        ($($e:expr),*) => {{ $($e;)* }}\n    }\n    use_expr!(isize::MIN / -(one() as isize), i8::MIN / -one());\n\n    // Issue #11885\n    Cout << 16;\n\n    // Issue #11575\n    // Bad formatting is required to trigger the bug\n    #[rustfmt::skip]\n    'label: {\n        break 'label\n    };\n    let () = const {\n        [42, 55][get_usize()];\n    };\n}\n\nconst _: () = {\n    [42, 55][get_usize()];\n};\n\nconst fn foo() {\n    assert!([42, 55].len() > get_usize());\n    //~^ unnecessary_operation\n}\n\nfn issue15173() {\n    // No lint as `Box::new(None)` alone would be ambiguous\n    Box::new(None) as Box<Option<i32>>;\n}\n\n#[expect(clippy::redundant_closure_call)]\nfn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {\n    Box::new(move |value| {\n        (|_| handler.clone()())(value);\n        None\n    }) as Box<dyn Fn(i32) -> Option<i32>>;\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_operation.rs",
    "content": "#![allow(\n    clippy::deref_addrof,\n    clippy::no_effect,\n    clippy::uninlined_format_args,\n    clippy::unnecessary_struct_initialization,\n    dead_code,\n    unused\n)]\n#![warn(clippy::unnecessary_operation)]\n\nuse std::fmt::Display;\nuse std::ops::Shl;\n\nstruct Tuple(i32);\nstruct Struct {\n    field: i32,\n}\nenum Enum {\n    Tuple(i32),\n    Struct { field: i32 },\n}\nstruct DropStruct {\n    field: i32,\n}\nimpl Drop for DropStruct {\n    fn drop(&mut self) {}\n}\nstruct DropTuple(i32);\nimpl Drop for DropTuple {\n    fn drop(&mut self) {}\n}\nenum DropEnum {\n    Tuple(i32),\n    Struct { field: i32 },\n}\nimpl Drop for DropEnum {\n    fn drop(&mut self) {}\n}\nstruct FooString {\n    s: String,\n}\n\nfn get_number() -> i32 {\n    0\n}\n\nconst fn get_usize() -> usize {\n    0\n}\nfn get_struct() -> Struct {\n    Struct { field: 0 }\n}\nfn get_drop_struct() -> DropStruct {\n    DropStruct { field: 0 }\n}\n\nstruct Cout;\n\nimpl<T> Shl<T> for Cout\nwhere\n    T: Display,\n{\n    type Output = Self;\n    fn shl(self, rhs: T) -> Self::Output {\n        println!(\"{}\", rhs);\n        self\n    }\n}\n\nfn main() {\n    Tuple(get_number());\n    //~^ unnecessary_operation\n    Struct { field: get_number() };\n    //~^ unnecessary_operation\n    Struct { ..get_struct() };\n    //~^ unnecessary_operation\n    Enum::Tuple(get_number());\n    //~^ unnecessary_operation\n    Enum::Struct { field: get_number() };\n    //~^ unnecessary_operation\n    5 + get_number();\n    //~^ unnecessary_operation\n    *&get_number();\n    //~^ unnecessary_operation\n    &get_number();\n    //~^ unnecessary_operation\n    (5, 6, get_number());\n    //~^ unnecessary_operation\n    get_number()..;\n    //~^ unnecessary_operation\n    ..get_number();\n    //~^ unnecessary_operation\n    5..get_number();\n    //~^ unnecessary_operation\n    [42, get_number()];\n    //~^ unnecessary_operation\n    [42, 55][get_usize()];\n    //~^ unnecessary_operation\n    (42, get_number()).1;\n    //~^ unnecessary_operation\n    [get_number(); 55];\n    //~^ unnecessary_operation\n    [42; 55][get_usize()];\n    //~^ unnecessary_operation\n    {\n        //~^ unnecessary_operation\n        get_number()\n    };\n    FooString {\n        //~^ unnecessary_operation\n        s: String::from(\"blah\"),\n    };\n\n    // Do not warn\n    DropTuple(get_number());\n    DropStruct { field: get_number() };\n    DropStruct { field: get_number() };\n    DropStruct { ..get_drop_struct() };\n    DropEnum::Tuple(get_number());\n    DropEnum::Struct { field: get_number() };\n\n    // Issue #9954\n    fn one() -> i8 {\n        1\n    }\n    macro_rules! use_expr {\n        ($($e:expr),*) => {{ $($e;)* }}\n    }\n    use_expr!(isize::MIN / -(one() as isize), i8::MIN / -one());\n\n    // Issue #11885\n    Cout << 16;\n\n    // Issue #11575\n    // Bad formatting is required to trigger the bug\n    #[rustfmt::skip]\n    'label: {\n        break 'label\n    };\n    let () = const {\n        [42, 55][get_usize()];\n    };\n}\n\nconst _: () = {\n    [42, 55][get_usize()];\n};\n\nconst fn foo() {\n    [42, 55][get_usize()];\n    //~^ unnecessary_operation\n}\n\nfn issue15173() {\n    // No lint as `Box::new(None)` alone would be ambiguous\n    Box::new(None) as Box<Option<i32>>;\n}\n\n#[expect(clippy::redundant_closure_call)]\nfn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {\n    Box::new(move |value| {\n        (|_| handler.clone()())(value);\n        None\n    }) as Box<dyn Fn(i32) -> Option<i32>>;\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_operation.stderr",
    "content": "error: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:71:5\n   |\nLL |     Tuple(get_number());\n   |     ^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n   |\n   = note: `-D clippy::unnecessary-operation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_operation)]`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:73:5\n   |\nLL |     Struct { field: get_number() };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:75:5\n   |\nLL |     Struct { ..get_struct() };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_struct();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:77:5\n   |\nLL |     Enum::Tuple(get_number());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:79:5\n   |\nLL |     Enum::Struct { field: get_number() };\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:81:5\n   |\nLL |     5 + get_number();\n   |     ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5; get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:83:5\n   |\nLL |     *&get_number();\n   |     ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:85:5\n   |\nLL |     &get_number();\n   |     ^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:87:5\n   |\nLL |     (5, 6, get_number());\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5; 6; get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:89:5\n   |\nLL |     get_number()..;\n   |     ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:91:5\n   |\nLL |     ..get_number();\n   |     ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:93:5\n   |\nLL |     5..get_number();\n   |     ^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5; get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:95:5\n   |\nLL |     [42, get_number()];\n   |     ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42; get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:97:5\n   |\nLL |     [42, 55][get_usize()];\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:99:5\n   |\nLL |     (42, get_number()).1;\n   |     ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42; get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:101:5\n   |\nLL |     [get_number(); 55];\n   |     ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:103:5\n   |\nLL |     [42; 55][get_usize()];\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42; 55].len() > get_usize());`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:105:5\n   |\nLL | /     {\nLL | |\nLL | |         get_number()\nLL | |     };\n   | |______^ help: statement can be reduced to: `get_number();`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:109:5\n   |\nLL | /     FooString {\nLL | |\nLL | |         s: String::from(\"blah\"),\nLL | |     };\n   | |______^ help: statement can be reduced to: `String::from(\"blah\");`\n\nerror: unnecessary operation\n  --> tests/ui/unnecessary_operation.rs:150:5\n   |\nLL |     [42, 55][get_usize()];\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_option_map_or_else.fixed",
    "content": "#![warn(clippy::unnecessary_option_map_or_else)]\n#![allow(\n    clippy::let_and_return,\n    clippy::let_unit_value,\n    clippy::unnecessary_lazy_evaluations,\n    clippy::unnecessary_literal_unwrap,\n    clippy::needless_return\n)]\n\nconst fn double_it(x: i32) -> i32 {\n    x * 2\n}\n\nfn main() {\n    // Expected errors\n    // Basic scenario\n    let option = Some(());\n    option.unwrap_or_else(|| ()); //~ unnecessary_option_map_or_else\n\n    // Type ascription\n    let option = Some(());\n    option.unwrap_or_else(|| ()); //~ unnecessary_option_map_or_else\n\n    // Auto-deref\n    let string = String::new();\n    let option = Some(&string);\n    let _: &str = option.map_or_else(|| &string, |x| x);\n    // This should in theory lint with a smarter check\n\n    // Temporary variable\n    let option = Some(());\n    option.unwrap_or_else(|| ());\n\n    // Temporary variable with pattern\n    let option = Some(((), ()));\n    option.unwrap_or_else(|| ((), ()));\n\n    // std::convert::identity\n    let string = String::new();\n    let option = Some(&string);\n    let _: &str = option.unwrap_or_else(|| &string); //~ unnecessary_option_map_or_else\n\n    let x: Option<((), ())> = Some(((), ()));\n    x.unwrap_or_else(|| ((), ()));\n    //~^ unnecessary_option_map_or_else\n\n    // Returned temporary variable.\n    let x: Option<()> = Some(());\n    x.unwrap_or_else(|| ());\n\n    // Returned temporary variable with pattern\n    let x: Option<((), ())> = Some(((), ()));\n    x.unwrap_or_else(|| ((), ()));\n\n    // Correct usages\n    let option = Some(());\n    option.map_or_else(|| (), |_| ());\n\n    let option = Some(());\n    option.map_or_else(|| (), |_: ()| ());\n\n    let string = String::new();\n    let option = Some(&string);\n    let _: &str = option.map_or_else(|| &string, |_| &string);\n\n    let option = Some(());\n    option.map_or_else(\n        || (),\n        |_| {\n            let tmp = ();\n            tmp\n        },\n    );\n\n    let num = 5;\n    let option = Some(num);\n    let _: i32 = option.map_or_else(|| 0, double_it);\n\n    let increase = |x: i32| x + 1;\n    let num = 5;\n    let option = Some(num);\n    let _: i32 = option.map_or_else(|| 0, increase);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_option_map_or_else.rs",
    "content": "#![warn(clippy::unnecessary_option_map_or_else)]\n#![allow(\n    clippy::let_and_return,\n    clippy::let_unit_value,\n    clippy::unnecessary_lazy_evaluations,\n    clippy::unnecessary_literal_unwrap,\n    clippy::needless_return\n)]\n\nconst fn double_it(x: i32) -> i32 {\n    x * 2\n}\n\nfn main() {\n    // Expected errors\n    // Basic scenario\n    let option = Some(());\n    option.map_or_else(|| (), |x| x); //~ unnecessary_option_map_or_else\n\n    // Type ascription\n    let option = Some(());\n    option.map_or_else(|| (), |x: ()| x); //~ unnecessary_option_map_or_else\n\n    // Auto-deref\n    let string = String::new();\n    let option = Some(&string);\n    let _: &str = option.map_or_else(|| &string, |x| x);\n    // This should in theory lint with a smarter check\n\n    // Temporary variable\n    let option = Some(());\n    option.map_or_else(\n        //~^ unnecessary_option_map_or_else\n        || (),\n        |x| {\n            let tmp = x;\n            tmp\n        },\n    );\n\n    // Temporary variable with pattern\n    let option = Some(((), ()));\n    option.map_or_else(\n        //~^ unnecessary_option_map_or_else\n        || ((), ()),\n        |x| {\n            let tmp = x;\n            let (a, b) = tmp;\n            (a, b)\n        },\n    );\n\n    // std::convert::identity\n    let string = String::new();\n    let option = Some(&string);\n    let _: &str = option.map_or_else(|| &string, std::convert::identity); //~ unnecessary_option_map_or_else\n\n    let x: Option<((), ())> = Some(((), ()));\n    x.map_or_else(|| ((), ()), |(a, b)| (a, b));\n    //~^ unnecessary_option_map_or_else\n\n    // Returned temporary variable.\n    let x: Option<()> = Some(());\n    x.map_or_else(\n        //~^ unnecessary_option_map_or_else\n        || (),\n        |n| {\n            let tmp = n;\n            let tmp2 = tmp;\n            return tmp2;\n        },\n    );\n\n    // Returned temporary variable with pattern\n    let x: Option<((), ())> = Some(((), ()));\n    x.map_or_else(\n        //~^ unnecessary_option_map_or_else\n        || ((), ()),\n        |n| {\n            let tmp = n;\n            let (a, b) = tmp;\n            return (a, b);\n        },\n    );\n\n    // Correct usages\n    let option = Some(());\n    option.map_or_else(|| (), |_| ());\n\n    let option = Some(());\n    option.map_or_else(|| (), |_: ()| ());\n\n    let string = String::new();\n    let option = Some(&string);\n    let _: &str = option.map_or_else(|| &string, |_| &string);\n\n    let option = Some(());\n    option.map_or_else(\n        || (),\n        |_| {\n            let tmp = ();\n            tmp\n        },\n    );\n\n    let num = 5;\n    let option = Some(num);\n    let _: i32 = option.map_or_else(|| 0, double_it);\n\n    let increase = |x: i32| x + 1;\n    let num = 5;\n    let option = Some(num);\n    let _: i32 = option.map_or_else(|| 0, increase);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_option_map_or_else.stderr",
    "content": "error: unused \"map closure\" when calling `Option::map_or_else` value\n  --> tests/ui/unnecessary_option_map_or_else.rs:18:5\n   |\nLL |     option.map_or_else(|| (), |x| x);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-option-map-or-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_option_map_or_else)]`\nhelp: consider using `unwrap_or_else`\n   |\nLL -     option.map_or_else(|| (), |x| x);\nLL +     option.unwrap_or_else(|| ());\n   |\n\nerror: unused \"map closure\" when calling `Option::map_or_else` value\n  --> tests/ui/unnecessary_option_map_or_else.rs:22:5\n   |\nLL |     option.map_or_else(|| (), |x: ()| x);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     option.map_or_else(|| (), |x: ()| x);\nLL +     option.unwrap_or_else(|| ());\n   |\n\nerror: unused \"map closure\" when calling `Option::map_or_else` value\n  --> tests/ui/unnecessary_option_map_or_else.rs:32:5\n   |\nLL | /     option.map_or_else(\nLL | |\nLL | |         || (),\nLL | |         |x| {\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     option.map_or_else(\nLL -\nLL -         || (),\nLL -         |x| {\nLL -             let tmp = x;\nLL -             tmp\nLL -         },\nLL -     );\nLL +     option.unwrap_or_else(|| ());\n   |\n\nerror: unused \"map closure\" when calling `Option::map_or_else` value\n  --> tests/ui/unnecessary_option_map_or_else.rs:43:5\n   |\nLL | /     option.map_or_else(\nLL | |\nLL | |         || ((), ()),\nLL | |         |x| {\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     option.map_or_else(\nLL -\nLL -         || ((), ()),\nLL -         |x| {\nLL -             let tmp = x;\nLL -             let (a, b) = tmp;\nLL -             (a, b)\nLL -         },\nLL -     );\nLL +     option.unwrap_or_else(|| ((), ()));\n   |\n\nerror: unused \"map closure\" when calling `Option::map_or_else` value\n  --> tests/ui/unnecessary_option_map_or_else.rs:56:19\n   |\nLL |     let _: &str = option.map_or_else(|| &string, std::convert::identity);\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     let _: &str = option.map_or_else(|| &string, std::convert::identity);\nLL +     let _: &str = option.unwrap_or_else(|| &string);\n   |\n\nerror: unused \"map closure\" when calling `Option::map_or_else` value\n  --> tests/ui/unnecessary_option_map_or_else.rs:59:5\n   |\nLL |     x.map_or_else(|| ((), ()), |(a, b)| (a, b));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(|| ((), ()), |(a, b)| (a, b));\nLL +     x.unwrap_or_else(|| ((), ()));\n   |\n\nerror: unused \"map closure\" when calling `Option::map_or_else` value\n  --> tests/ui/unnecessary_option_map_or_else.rs:64:5\n   |\nLL | /     x.map_or_else(\nLL | |\nLL | |         || (),\nLL | |         |n| {\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(\nLL -\nLL -         || (),\nLL -         |n| {\nLL -             let tmp = n;\nLL -             let tmp2 = tmp;\nLL -             return tmp2;\nLL -         },\nLL -     );\nLL +     x.unwrap_or_else(|| ());\n   |\n\nerror: unused \"map closure\" when calling `Option::map_or_else` value\n  --> tests/ui/unnecessary_option_map_or_else.rs:76:5\n   |\nLL | /     x.map_or_else(\nLL | |\nLL | |         || ((), ()),\nLL | |         |n| {\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(\nLL -\nLL -         || ((), ()),\nLL -         |n| {\nLL -             let tmp = n;\nLL -             let (a, b) = tmp;\nLL -             return (a, b);\nLL -         },\nLL -     );\nLL +     x.unwrap_or_else(|| ((), ()));\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_os_str_debug_formatting.rs",
    "content": "#![warn(clippy::unnecessary_debug_formatting)]\n#![allow(clippy::uninlined_format_args)]\n\nuse std::ffi::{OsStr, OsString};\n\nfn main() {\n    let os_str = OsStr::new(\"abc\");\n    let os_string = os_str.to_os_string();\n\n    // negative tests\n    println!(\"{}\", os_str.display());\n    println!(\"{}\", os_string.display());\n\n    // positive tests\n    println!(\"{:?}\", os_str); //~ unnecessary_debug_formatting\n    println!(\"{:?}\", os_string); //~ unnecessary_debug_formatting\n\n    println!(\"{os_str:?}\"); //~ unnecessary_debug_formatting\n    println!(\"{os_string:?}\"); //~ unnecessary_debug_formatting\n\n    let _: String = format!(\"{:?}\", os_str); //~ unnecessary_debug_formatting\n    let _: String = format!(\"{:?}\", os_string); //~ unnecessary_debug_formatting\n}\n\n#[clippy::msrv = \"1.86\"]\nfn msrv_1_86() {\n    let os_str = OsStr::new(\"test\");\n    println!(\"{:?}\", os_str);\n}\n\n#[clippy::msrv = \"1.87\"]\nfn msrv_1_87() {\n    let os_str = OsStr::new(\"test\");\n    println!(\"{:?}\", os_str);\n    //~^ unnecessary_debug_formatting\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_os_str_debug_formatting.stderr",
    "content": "error: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_os_str_debug_formatting.rs:15:22\n   |\nLL |     println!(\"{:?}\", os_str);\n   |                      ^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_str.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n   = note: `-D clippy::unnecessary-debug-formatting` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_debug_formatting)]`\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_os_str_debug_formatting.rs:16:22\n   |\nLL |     println!(\"{:?}\", os_string);\n   |                      ^^^^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_string.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_os_str_debug_formatting.rs:18:16\n   |\nLL |     println!(\"{os_str:?}\");\n   |                ^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_str.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_os_str_debug_formatting.rs:19:16\n   |\nLL |     println!(\"{os_string:?}\");\n   |                ^^^^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_string.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `format!` args\n  --> tests/ui/unnecessary_os_str_debug_formatting.rs:21:37\n   |\nLL |     let _: String = format!(\"{:?}\", os_str);\n   |                                     ^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_str.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `format!` args\n  --> tests/ui/unnecessary_os_str_debug_formatting.rs:22:37\n   |\nLL |     let _: String = format!(\"{:?}\", os_string);\n   |                                     ^^^^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_string.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_os_str_debug_formatting.rs:34:22\n   |\nLL |     println!(\"{:?}\", os_str);\n   |                      ^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_str.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_owned_empty_strings.fixed",
    "content": "#![warn(clippy::unnecessary_owned_empty_strings)]\n\nfn ref_str_argument(_value: &str) {}\n\n#[allow(clippy::ptr_arg)]\nfn ref_string_argument(_value: &String) {}\n\nfn main() {\n    // should be linted\n    ref_str_argument(\"\");\n    //~^ unnecessary_owned_empty_strings\n\n    // should be linted\n    #[allow(clippy::manual_string_new)]\n    ref_str_argument(\"\");\n    //~^ unnecessary_owned_empty_strings\n\n    // should not be linted\n    ref_str_argument(\"\");\n\n    // should not be linted\n    ref_string_argument(&String::new());\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_owned_empty_strings.rs",
    "content": "#![warn(clippy::unnecessary_owned_empty_strings)]\n\nfn ref_str_argument(_value: &str) {}\n\n#[allow(clippy::ptr_arg)]\nfn ref_string_argument(_value: &String) {}\n\nfn main() {\n    // should be linted\n    ref_str_argument(&String::new());\n    //~^ unnecessary_owned_empty_strings\n\n    // should be linted\n    #[allow(clippy::manual_string_new)]\n    ref_str_argument(&String::from(\"\"));\n    //~^ unnecessary_owned_empty_strings\n\n    // should not be linted\n    ref_str_argument(\"\");\n\n    // should not be linted\n    ref_string_argument(&String::new());\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_owned_empty_strings.stderr",
    "content": "error: usage of `&String::new()` for a function expecting a `&str` argument\n  --> tests/ui/unnecessary_owned_empty_strings.rs:10:22\n   |\nLL |     ref_str_argument(&String::new());\n   |                      ^^^^^^^^^^^^^^ help: try: `\"\"`\n   |\n   = note: `-D clippy::unnecessary-owned-empty-strings` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_owned_empty_strings)]`\n\nerror: usage of `&String::from(\"\")` for a function expecting a `&str` argument\n  --> tests/ui/unnecessary_owned_empty_strings.rs:15:22\n   |\nLL |     ref_str_argument(&String::from(\"\"));\n   |                      ^^^^^^^^^^^^^^^^^ help: try: `\"\"`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_path_debug_formatting.rs",
    "content": "#![warn(clippy::unnecessary_debug_formatting)]\n#![allow(clippy::uninlined_format_args)]\n\nuse std::ffi::{OsStr, OsString};\nuse std::ops::Deref;\nuse std::path::{Path, PathBuf};\n\nstruct DerefPath<'a> {\n    path: &'a Path,\n}\n\nimpl Deref for DerefPath<'_> {\n    type Target = Path;\n    fn deref(&self) -> &Self::Target {\n        self.path\n    }\n}\n\nfn main() {\n    let path = Path::new(\"/a/b/c\");\n    let path_buf = path.to_path_buf();\n    let os_str = OsStr::new(\"abc\");\n    let os_string = os_str.to_os_string();\n\n    // negative tests\n    println!(\"{}\", path.display());\n    println!(\"{}\", path_buf.display());\n\n    // positive tests\n    println!(\"{:?}\", os_str); //~ unnecessary_debug_formatting\n    println!(\"{:?}\", os_string); //~ unnecessary_debug_formatting\n\n    println!(\"{:?}\", path); //~ unnecessary_debug_formatting\n    println!(\"{:?}\", path_buf); //~ unnecessary_debug_formatting\n\n    println!(\"{path:?}\"); //~ unnecessary_debug_formatting\n    println!(\"{path_buf:?}\"); //~ unnecessary_debug_formatting\n\n    let _: String = format!(\"{:?}\", path); //~ unnecessary_debug_formatting\n    let _: String = format!(\"{:?}\", path_buf); //~ unnecessary_debug_formatting\n\n    let deref_path = DerefPath { path };\n    println!(\"{:?}\", &*deref_path); //~ unnecessary_debug_formatting\n}\n\n#[test]\nfn issue_14345() {\n    let input = std::path::Path::new(\"/foo/bar\");\n    assert!(input.ends_with(\"baz\"), \"{input:?}\");\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_path_debug_formatting.stderr",
    "content": "error: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:30:22\n   |\nLL |     println!(\"{:?}\", os_str);\n   |                      ^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_str.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n   = note: `-D clippy::unnecessary-debug-formatting` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_debug_formatting)]`\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:31:22\n   |\nLL |     println!(\"{:?}\", os_string);\n   |                      ^^^^^^^^^\n   |\n   = help: use `Display` formatting and change this to `os_string.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:33:22\n   |\nLL |     println!(\"{:?}\", path);\n   |                      ^^^^\n   |\n   = help: use `Display` formatting and change this to `path.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:34:22\n   |\nLL |     println!(\"{:?}\", path_buf);\n   |                      ^^^^^^^^\n   |\n   = help: use `Display` formatting and change this to `path_buf.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:36:16\n   |\nLL |     println!(\"{path:?}\");\n   |                ^^^^\n   |\n   = help: use `Display` formatting and change this to `path.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:37:16\n   |\nLL |     println!(\"{path_buf:?}\");\n   |                ^^^^^^^^\n   |\n   = help: use `Display` formatting and change this to `path_buf.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `format!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:39:37\n   |\nLL |     let _: String = format!(\"{:?}\", path);\n   |                                     ^^^^\n   |\n   = help: use `Display` formatting and change this to `path.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `format!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:40:37\n   |\nLL |     let _: String = format!(\"{:?}\", path_buf);\n   |                                     ^^^^^^^^\n   |\n   = help: use `Display` formatting and change this to `path_buf.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: unnecessary `Debug` formatting in `println!` args\n  --> tests/ui/unnecessary_path_debug_formatting.rs:43:22\n   |\nLL |     println!(\"{:?}\", &*deref_path);\n   |                      ^^^^^^^^^^^^\n   |\n   = help: use `Display` formatting and change this to `&*deref_path.display()`\n   = note: switching to `Display` formatting will change how the value is shown; escaped characters will no longer be escaped and surrounding quotes will be removed\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_result_map_or_else.fixed",
    "content": "#![warn(clippy::unnecessary_result_map_or_else)]\n#![allow(\n    clippy::unnecessary_literal_unwrap,\n    clippy::let_and_return,\n    clippy::let_unit_value,\n    clippy::needless_return\n)]\n\nfn main() {\n    let x: Result<(), ()> = Ok(());\n    x.unwrap_or_else(|err| err);\n    //~^ unnecessary_result_map_or_else\n\n    // Type ascribtion.\n    let x: Result<(), ()> = Ok(());\n    x.unwrap_or_else(|err: ()| err);\n    //~^ unnecessary_result_map_or_else\n\n    // Auto-deref.\n    let y = String::new();\n    let x: Result<&String, &String> = Ok(&y);\n    let y: &str = x.map_or_else(|err| err, |n| n);\n    // This should lint with a smarter check\n\n    // Temporary variable.\n    let x: Result<(), ()> = Ok(());\n    x.unwrap_or_else(|err| err);\n\n    // Temporary variable with pattern\n    let x: Result<((), ()), ((), ())> = Ok(((), ()));\n    x.unwrap_or_else(|err| err);\n\n    // Should not warn.\n    let x: Result<usize, usize> = Ok(0);\n    x.map_or_else(|err| err, |n| n + 1);\n\n    // Should not warn.\n    let y = ();\n    let x: Result<(), ()> = Ok(());\n    x.map_or_else(|err| err, |_| y);\n\n    // Should not warn.\n    let y = ();\n    let x: Result<(), ()> = Ok(());\n    x.map_or_else(\n        |err| err,\n        |_| {\n            let tmp = y;\n            tmp\n        },\n    );\n\n    // Should not warn.\n    let x: Result<usize, usize> = Ok(1);\n    x.map_or_else(\n        |err| err,\n        |n| {\n            let tmp = n + 1;\n            tmp\n        },\n    );\n\n    // Should not warn.\n    let y = 0;\n    let x: Result<usize, usize> = Ok(1);\n    x.map_or_else(\n        |err| err,\n        |n| {\n            let tmp = n;\n            y\n        },\n    );\n\n    let x: Result<((), ()), ((), ())> = Ok(((), ()));\n    x.unwrap_or_else(|err| err);\n    //~^ unnecessary_result_map_or_else\n\n    // Returned temporary variable.\n    let x: Result<(), ()> = Ok(());\n    x.unwrap_or_else(|err| err);\n\n    // Returned temporary variable with pattern\n    let x: Result<((), ()), ((), ())> = Ok(((), ()));\n    x.unwrap_or_else(|err| err);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_result_map_or_else.rs",
    "content": "#![warn(clippy::unnecessary_result_map_or_else)]\n#![allow(\n    clippy::unnecessary_literal_unwrap,\n    clippy::let_and_return,\n    clippy::let_unit_value,\n    clippy::needless_return\n)]\n\nfn main() {\n    let x: Result<(), ()> = Ok(());\n    x.map_or_else(|err| err, |n| n);\n    //~^ unnecessary_result_map_or_else\n\n    // Type ascribtion.\n    let x: Result<(), ()> = Ok(());\n    x.map_or_else(|err: ()| err, |n: ()| n);\n    //~^ unnecessary_result_map_or_else\n\n    // Auto-deref.\n    let y = String::new();\n    let x: Result<&String, &String> = Ok(&y);\n    let y: &str = x.map_or_else(|err| err, |n| n);\n    // This should lint with a smarter check\n\n    // Temporary variable.\n    let x: Result<(), ()> = Ok(());\n    x.map_or_else(\n        //~^ unnecessary_result_map_or_else\n        |err| err,\n        |n| {\n            let tmp = n;\n            let tmp2 = tmp;\n            tmp2\n        },\n    );\n\n    // Temporary variable with pattern\n    let x: Result<((), ()), ((), ())> = Ok(((), ()));\n    x.map_or_else(\n        //~^ unnecessary_result_map_or_else\n        |err| err,\n        |n| {\n            let tmp = n;\n            let (a, b) = tmp;\n            (a, b)\n        },\n    );\n\n    // Should not warn.\n    let x: Result<usize, usize> = Ok(0);\n    x.map_or_else(|err| err, |n| n + 1);\n\n    // Should not warn.\n    let y = ();\n    let x: Result<(), ()> = Ok(());\n    x.map_or_else(|err| err, |_| y);\n\n    // Should not warn.\n    let y = ();\n    let x: Result<(), ()> = Ok(());\n    x.map_or_else(\n        |err| err,\n        |_| {\n            let tmp = y;\n            tmp\n        },\n    );\n\n    // Should not warn.\n    let x: Result<usize, usize> = Ok(1);\n    x.map_or_else(\n        |err| err,\n        |n| {\n            let tmp = n + 1;\n            tmp\n        },\n    );\n\n    // Should not warn.\n    let y = 0;\n    let x: Result<usize, usize> = Ok(1);\n    x.map_or_else(\n        |err| err,\n        |n| {\n            let tmp = n;\n            y\n        },\n    );\n\n    let x: Result<((), ()), ((), ())> = Ok(((), ()));\n    x.map_or_else(|err| err, |(a, b)| (a, b));\n    //~^ unnecessary_result_map_or_else\n\n    // Returned temporary variable.\n    let x: Result<(), ()> = Ok(());\n    x.map_or_else(\n        //~^ unnecessary_result_map_or_else\n        |err| err,\n        |n| {\n            let tmp = n;\n            let tmp2 = tmp;\n            return tmp2;\n        },\n    );\n\n    // Returned temporary variable with pattern\n    let x: Result<((), ()), ((), ())> = Ok(((), ()));\n    x.map_or_else(\n        //~^ unnecessary_result_map_or_else\n        |err| err,\n        |n| {\n            let tmp = n;\n            let (a, b) = tmp;\n            return (a, b);\n        },\n    );\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_result_map_or_else.stderr",
    "content": "error: unused \"map closure\" when calling `Result::map_or_else` value\n  --> tests/ui/unnecessary_result_map_or_else.rs:11:5\n   |\nLL |     x.map_or_else(|err| err, |n| n);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-result-map-or-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_result_map_or_else)]`\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(|err| err, |n| n);\nLL +     x.unwrap_or_else(|err| err);\n   |\n\nerror: unused \"map closure\" when calling `Result::map_or_else` value\n  --> tests/ui/unnecessary_result_map_or_else.rs:16:5\n   |\nLL |     x.map_or_else(|err: ()| err, |n: ()| n);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(|err: ()| err, |n: ()| n);\nLL +     x.unwrap_or_else(|err: ()| err);\n   |\n\nerror: unused \"map closure\" when calling `Result::map_or_else` value\n  --> tests/ui/unnecessary_result_map_or_else.rs:27:5\n   |\nLL | /     x.map_or_else(\nLL | |\nLL | |         |err| err,\nLL | |         |n| {\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(\nLL -\nLL -         |err| err,\nLL -         |n| {\nLL -             let tmp = n;\nLL -             let tmp2 = tmp;\nLL -             tmp2\nLL -         },\nLL -     );\nLL +     x.unwrap_or_else(|err| err);\n   |\n\nerror: unused \"map closure\" when calling `Result::map_or_else` value\n  --> tests/ui/unnecessary_result_map_or_else.rs:39:5\n   |\nLL | /     x.map_or_else(\nLL | |\nLL | |         |err| err,\nLL | |         |n| {\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(\nLL -\nLL -         |err| err,\nLL -         |n| {\nLL -             let tmp = n;\nLL -             let (a, b) = tmp;\nLL -             (a, b)\nLL -         },\nLL -     );\nLL +     x.unwrap_or_else(|err| err);\n   |\n\nerror: unused \"map closure\" when calling `Result::map_or_else` value\n  --> tests/ui/unnecessary_result_map_or_else.rs:91:5\n   |\nLL |     x.map_or_else(|err| err, |(a, b)| (a, b));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(|err| err, |(a, b)| (a, b));\nLL +     x.unwrap_or_else(|err| err);\n   |\n\nerror: unused \"map closure\" when calling `Result::map_or_else` value\n  --> tests/ui/unnecessary_result_map_or_else.rs:96:5\n   |\nLL | /     x.map_or_else(\nLL | |\nLL | |         |err| err,\nLL | |         |n| {\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(\nLL -\nLL -         |err| err,\nLL -         |n| {\nLL -             let tmp = n;\nLL -             let tmp2 = tmp;\nLL -             return tmp2;\nLL -         },\nLL -     );\nLL +     x.unwrap_or_else(|err| err);\n   |\n\nerror: unused \"map closure\" when calling `Result::map_or_else` value\n  --> tests/ui/unnecessary_result_map_or_else.rs:108:5\n   |\nLL | /     x.map_or_else(\nLL | |\nLL | |         |err| err,\nLL | |         |n| {\n...  |\nLL | |         },\nLL | |     );\n   | |_____^\n   |\nhelp: consider using `unwrap_or_else`\n   |\nLL -     x.map_or_else(\nLL -\nLL -         |err| err,\nLL -         |n| {\nLL -             let tmp = n;\nLL -             let (a, b) = tmp;\nLL -             return (a, b);\nLL -         },\nLL -     );\nLL +     x.unwrap_or_else(|err| err);\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_safety_comment.rs",
    "content": "#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]\n#![allow(clippy::let_unit_value, clippy::missing_safety_doc, clippy::needless_ifs)]\n\nmod unsafe_items_invalid_comment {\n    // SAFETY:\n    const CONST: u32 = 0;\n    //~^ unnecessary_safety_comment\n\n    // SAFETY:\n    static STATIC: u32 = 0;\n    //~^ unnecessary_safety_comment\n\n    // SAFETY:\n    struct Struct;\n    //~^ unnecessary_safety_comment\n\n    // SAFETY:\n    enum Enum {}\n    //~^ unnecessary_safety_comment\n\n    // SAFETY:\n    mod module {}\n    //~^ unnecessary_safety_comment\n}\n\nmod unnecessary_from_macro {\n    trait T {}\n\n    macro_rules! no_safety_comment {\n        ($t:ty) => {\n            impl T for $t {}\n        };\n    }\n\n    // FIXME: This is not caught\n    // Safety: unnecessary\n    no_safety_comment!(());\n\n    macro_rules! with_safety_comment {\n        ($t:ty) => {\n            // Safety: unnecessary\n            impl T for $t {}\n            //~^ unnecessary_safety_comment\n        };\n    }\n\n    with_safety_comment!(i32);\n}\n\nfn unnecessary_on_stmt_and_expr() -> u32 {\n    // SAFETY: unnecessary\n    let num = 42;\n    //~^ unnecessary_safety_comment\n\n    // SAFETY: unnecessary\n    if num > 24 {}\n    //~^ unnecessary_safety_comment\n\n    // SAFETY: unnecessary\n    24\n    //~^ unnecessary_safety_comment\n}\n\nmod issue_10084 {\n    unsafe fn bar() -> i32 {\n        42\n    }\n\n    macro_rules! foo {\n        () => {\n            // SAFETY: This is necessary\n            unsafe { bar() }\n        };\n    }\n\n    fn main() {\n        foo!();\n    }\n}\n\nmod issue_12048 {\n    pub const X: u8 = 0;\n\n    /// Returns a pointer to five.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use foo::point_to_five;\n    ///\n    /// let five_pointer = point_to_five();\n    /// // Safety: this pointer always points to a valid five.\n    /// let five = unsafe { *five_pointer };\n    /// assert_eq!(five, 5);\n    /// ```\n    pub fn point_to_five() -> *const u8 {\n        static FIVE: u8 = 5;\n        &FIVE\n    }\n}\n\nfn main() {}\n\nmod issue16553 {\n    //! ```\n    //! // SAFETY: All is well.\n    //! unsafe {\n    //!    foo()\n    //! }\n    //! ```\n    mod blah {}\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_safety_comment.stderr",
    "content": "error: constant has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:6:5\n   |\nLL |     const CONST: u32 = 0;\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:5:8\n   |\nLL |     // SAFETY:\n   |        ^^^^^^^\n   = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`\n\nerror: static has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:10:5\n   |\nLL |     static STATIC: u32 = 0;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:9:8\n   |\nLL |     // SAFETY:\n   |        ^^^^^^^\n\nerror: struct has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:14:5\n   |\nLL |     struct Struct;\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:13:8\n   |\nLL |     // SAFETY:\n   |        ^^^^^^^\n\nerror: enum has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:18:5\n   |\nLL |     enum Enum {}\n   |     ^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:17:8\n   |\nLL |     // SAFETY:\n   |        ^^^^^^^\n\nerror: module has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:22:5\n   |\nLL |     mod module {}\n   |     ^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:21:8\n   |\nLL |     // SAFETY:\n   |        ^^^^^^^\n\nerror: impl has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:42:13\n   |\nLL |             impl T for $t {}\n   |             ^^^^^^^^^^^^^^^^\n...\nLL |     with_safety_comment!(i32);\n   |     ------------------------- in this macro invocation\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:41:16\n   |\nLL |             // Safety: unnecessary\n   |                ^^^^^^^\n   = note: this error originates in the macro `with_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: expression has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:60:5\n   |\nLL |     24\n   |     ^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:59:8\n   |\nLL |     // SAFETY: unnecessary\n   |        ^^^^^^^^^^^^^^^^^^^\n\nerror: statement has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:52:5\n   |\nLL |     let num = 42;\n   |     ^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:51:8\n   |\nLL |     // SAFETY: unnecessary\n   |        ^^^^^^^^^^^^^^^^^^^\n\nerror: statement has unnecessary safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:56:5\n   |\nLL |     if num > 24 {}\n   |     ^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui/unnecessary_safety_comment.rs:55:8\n   |\nLL |     // SAFETY: unnecessary\n   |        ^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_self_imports.fixed",
    "content": "#![warn(clippy::unnecessary_self_imports)]\n#![allow(unused_imports, dead_code)]\n\nuse std::collections::hash_map::{self, *};\nuse std::fs as alias;\n//~^ unnecessary_self_imports\nuse std::io::{self, Read};\nuse std::rc;\n//~^ unnecessary_self_imports\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_self_imports.rs",
    "content": "#![warn(clippy::unnecessary_self_imports)]\n#![allow(unused_imports, dead_code)]\n\nuse std::collections::hash_map::{self, *};\nuse std::fs::{self as alias};\n//~^ unnecessary_self_imports\nuse std::io::{self, Read};\nuse std::rc::{self};\n//~^ unnecessary_self_imports\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unnecessary_self_imports.stderr",
    "content": "error: import ending with `::{self}`\n  --> tests/ui/unnecessary_self_imports.rs:5:1\n   |\nLL | use std::fs::{self as alias};\n   | ^^^^^^^^^--------------------\n   |          |\n   |          help: consider omitting `::{self}`: `fs as alias;`\n   |\n   = note: this will slightly change semantics; any non-module items at the same path will also be imported\n   = note: `-D clippy::unnecessary-self-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_self_imports)]`\n\nerror: import ending with `::{self}`\n  --> tests/ui/unnecessary_self_imports.rs:8:1\n   |\nLL | use std::rc::{self};\n   | ^^^^^^^^^-----------\n   |          |\n   |          help: consider omitting `::{self}`: `rc;`\n   |\n   = note: this will slightly change semantics; any non-module items at the same path will also be imported\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon.edition2021.fixed",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![warn(clippy::unnecessary_semicolon)]\n#![feature(postfix_match)]\n#![allow(clippy::single_match)]\n\nfn no_lint(mut x: u32) -> Option<u32> {\n    Some(())?;\n\n    {\n        let y = 3;\n        dbg!(x + y)\n    };\n\n    {\n        let (mut a, mut b) = (10, 20);\n        (a, b) = (b + 1, a + 1);\n    }\n\n    Some(0)\n}\n\nfn main() {\n    let mut a = 3;\n    if a == 2 {\n        println!(\"This is weird\");\n    }\n    //~^ unnecessary_semicolon\n\n    a.match {\n        3 => println!(\"three\"),\n        _ => println!(\"not three\"),\n    }\n    //~^ unnecessary_semicolon\n}\n\n// This is a problem in edition 2021 and below\nfn borrow_issue() {\n    let v = std::cell::RefCell::new(Some(vec![1]));\n    match &*v.borrow() {\n        Some(v) => {\n            dbg!(v);\n        },\n        None => {},\n    };\n    //~[edition2024]^ unnecessary_semicolon\n}\n\nfn no_borrow_issue(a: u32, b: u32) {\n    match Some(a + b) {\n        Some(v) => {\n            dbg!(v);\n        },\n        None => {},\n    }\n    //~^ unnecessary_semicolon\n}\n\nfn issue14100() -> bool {\n    // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be\n    // cast into the `bool` function return type.\n    if return true {};\n}\n\nfn issue15426(x: u32) {\n    // removing the `;` would turn the stmt into an expr, but attrs aren't allowed on exprs\n    #[rustfmt::skip]\n    match x {\n        0b00 => {}  0b01 => {}\n        0b11 => {}  _    => {}\n    };\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon.edition2021.stderr",
    "content": "error: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:29:6\n   |\nLL |     };\n   |      ^ help: remove\n   |\n   = note: `-D clippy::unnecessary-semicolon` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]`\n\nerror: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:35:6\n   |\nLL |     };\n   |      ^ help: remove\n\nerror: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:57:6\n   |\nLL |     };\n   |      ^ help: remove\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon.edition2024.fixed",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![warn(clippy::unnecessary_semicolon)]\n#![feature(postfix_match)]\n#![allow(clippy::single_match)]\n\nfn no_lint(mut x: u32) -> Option<u32> {\n    Some(())?;\n\n    {\n        let y = 3;\n        dbg!(x + y)\n    };\n\n    {\n        let (mut a, mut b) = (10, 20);\n        (a, b) = (b + 1, a + 1);\n    }\n\n    Some(0)\n}\n\nfn main() {\n    let mut a = 3;\n    if a == 2 {\n        println!(\"This is weird\");\n    }\n    //~^ unnecessary_semicolon\n\n    a.match {\n        3 => println!(\"three\"),\n        _ => println!(\"not three\"),\n    }\n    //~^ unnecessary_semicolon\n}\n\n// This is a problem in edition 2021 and below\nfn borrow_issue() {\n    let v = std::cell::RefCell::new(Some(vec![1]));\n    match &*v.borrow() {\n        Some(v) => {\n            dbg!(v);\n        },\n        None => {},\n    }\n    //~[edition2024]^ unnecessary_semicolon\n}\n\nfn no_borrow_issue(a: u32, b: u32) {\n    match Some(a + b) {\n        Some(v) => {\n            dbg!(v);\n        },\n        None => {},\n    }\n    //~^ unnecessary_semicolon\n}\n\nfn issue14100() -> bool {\n    // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be\n    // cast into the `bool` function return type.\n    if return true {};\n}\n\nfn issue15426(x: u32) {\n    // removing the `;` would turn the stmt into an expr, but attrs aren't allowed on exprs\n    #[rustfmt::skip]\n    match x {\n        0b00 => {}  0b01 => {}\n        0b11 => {}  _    => {}\n    };\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon.edition2024.stderr",
    "content": "error: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:29:6\n   |\nLL |     };\n   |      ^ help: remove\n   |\n   = note: `-D clippy::unnecessary-semicolon` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]`\n\nerror: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:35:6\n   |\nLL |     };\n   |      ^ help: remove\n\nerror: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:47:6\n   |\nLL |     };\n   |      ^ help: remove\n\nerror: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:57:6\n   |\nLL |     };\n   |      ^ help: remove\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon.fixed",
    "content": "#![warn(clippy::unnecessary_semicolon)]\n#![feature(postfix_match)]\n\nfn no_lint(mut x: u32) -> Option<u32> {\n    Some(())?;\n\n    {\n        let y = 3;\n        dbg!(x + y)\n    };\n\n    {\n        let (mut a, mut b) = (10, 20);\n        (a, b) = (b + 1, a + 1);\n    }\n\n    Some(0)\n}\n\nfn main() {\n    let mut a = 3;\n    if a == 2 {\n        println!(\"This is weird\");\n    }\n    //~^ ERROR: unnecessary semicolon\n\n    a.match {\n        3 => println!(\"three\"),\n        _ => println!(\"not three\"),\n    }\n    //~^ ERROR: unnecessary semicolon\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon.rs",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n#![warn(clippy::unnecessary_semicolon)]\n#![feature(postfix_match)]\n#![allow(clippy::single_match)]\n\nfn no_lint(mut x: u32) -> Option<u32> {\n    Some(())?;\n\n    {\n        let y = 3;\n        dbg!(x + y)\n    };\n\n    {\n        let (mut a, mut b) = (10, 20);\n        (a, b) = (b + 1, a + 1);\n    }\n\n    Some(0)\n}\n\nfn main() {\n    let mut a = 3;\n    if a == 2 {\n        println!(\"This is weird\");\n    };\n    //~^ unnecessary_semicolon\n\n    a.match {\n        3 => println!(\"three\"),\n        _ => println!(\"not three\"),\n    };\n    //~^ unnecessary_semicolon\n}\n\n// This is a problem in edition 2021 and below\nfn borrow_issue() {\n    let v = std::cell::RefCell::new(Some(vec![1]));\n    match &*v.borrow() {\n        Some(v) => {\n            dbg!(v);\n        },\n        None => {},\n    };\n    //~[edition2024]^ unnecessary_semicolon\n}\n\nfn no_borrow_issue(a: u32, b: u32) {\n    match Some(a + b) {\n        Some(v) => {\n            dbg!(v);\n        },\n        None => {},\n    };\n    //~^ unnecessary_semicolon\n}\n\nfn issue14100() -> bool {\n    // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be\n    // cast into the `bool` function return type.\n    if return true {};\n}\n\nfn issue15426(x: u32) {\n    // removing the `;` would turn the stmt into an expr, but attrs aren't allowed on exprs\n    #[rustfmt::skip]\n    match x {\n        0b00 => {}  0b01 => {}\n        0b11 => {}  _    => {}\n    };\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon.stderr",
    "content": "error: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:24:6\n   |\nLL |     };\n   |      ^ help: remove\n   |\n   = note: `-D clippy::unnecessary-semicolon` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]`\n\nerror: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon.rs:30:6\n   |\nLL |     };\n   |      ^ help: remove\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon_feature_stmt_expr_attributes.fixed",
    "content": "#![warn(clippy::unnecessary_semicolon)]\n#![feature(stmt_expr_attributes)]\n\nfn main() {\n    // removing the `;` would turn the stmt into an expr, but attrs aren't allowed on exprs\n    // -- unless the feature `stmt_expr_attributes` is enabled\n    #[rustfmt::skip]\n    match 0 {\n        0b00 => {}  0b01 => {}\n        0b11 => {}  _    => {}\n    }\n    //~^ unnecessary_semicolon\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon_feature_stmt_expr_attributes.rs",
    "content": "#![warn(clippy::unnecessary_semicolon)]\n#![feature(stmt_expr_attributes)]\n\nfn main() {\n    // removing the `;` would turn the stmt into an expr, but attrs aren't allowed on exprs\n    // -- unless the feature `stmt_expr_attributes` is enabled\n    #[rustfmt::skip]\n    match 0 {\n        0b00 => {}  0b01 => {}\n        0b11 => {}  _    => {}\n    };\n    //~^ unnecessary_semicolon\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_semicolon_feature_stmt_expr_attributes.stderr",
    "content": "error: unnecessary semicolon\n  --> tests/ui/unnecessary_semicolon_feature_stmt_expr_attributes.rs:11:6\n   |\nLL |     };\n   |      ^ help: remove\n   |\n   = note: `-D clippy::unnecessary-semicolon` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/unnecessary_sort_by.fixed",
    "content": "#![allow(clippy::stable_sort_primitive, clippy::useless_vec)]\n\nuse std::cell::Ref;\n\nfn unnecessary_sort_by() {\n    fn id(x: isize) -> isize {\n        x\n    }\n\n    let mut vec: Vec<isize> = vec![3, 6, 1, 2, 5];\n    // Forward examples\n    vec.sort();\n    //~^ unnecessary_sort_by\n    vec.sort_unstable();\n    //~^ unnecessary_sort_by\n    vec.sort_by_key(|a| (a + 5).abs());\n    //~^ unnecessary_sort_by\n    vec.sort_unstable_by_key(|a| id(-a));\n    //~^ unnecessary_sort_by\n    // Reverse examples\n    vec.sort_by(|a, b| b.cmp(a)); // not linted to avoid suggesting `Reverse(b)` which would borrow\n    vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs()));\n    //~^ unnecessary_sort_by\n    vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b)));\n    //~^ unnecessary_sort_by\n    // Negative examples (shouldn't be changed)\n    let c = &7;\n    vec.sort_by(|a, b| (b - a).cmp(&(a - b)));\n    vec.sort_by(|_, b| b.cmp(&5));\n    vec.sort_by(|_, b| b.cmp(c));\n    vec.sort_unstable_by(|a, _| a.cmp(c));\n\n    // Vectors of references are fine as long as the resulting key does not borrow\n    let mut vec: Vec<&&&isize> = vec![&&&3, &&&6, &&&1, &&&2, &&&5];\n    vec.sort_by_key(|a| (***a).abs());\n    //~^ unnecessary_sort_by\n    vec.sort_unstable_by_key(|a| (***a).abs());\n    //~^ unnecessary_sort_by\n    // `Reverse(b)` would borrow in the following cases, don't lint\n    vec.sort_by(|a, b| b.cmp(a));\n    vec.sort_unstable_by(|a, b| b.cmp(a));\n\n    // No warning if element does not implement `Ord`\n    let mut vec: Vec<Ref<usize>> = Vec::new();\n    vec.sort_unstable_by(|a, b| a.cmp(b));\n}\n\n// Do not suggest returning a reference to the closure parameter of `Vec::sort_by_key`\nmod issue_5754 {\n    #[derive(Clone, Copy)]\n    struct Test(usize);\n\n    #[derive(PartialOrd, Ord, PartialEq, Eq)]\n    struct Wrapper<'a>(&'a usize);\n\n    impl Test {\n        fn name(&self) -> &usize {\n            &self.0\n        }\n\n        fn wrapped(&self) -> Wrapper<'_> {\n            Wrapper(&self.0)\n        }\n    }\n\n    pub fn test() {\n        let mut args: Vec<Test> = vec![];\n\n        // Forward\n        args.sort_by(|a, b| a.name().cmp(b.name()));\n        args.sort_by(|a, b| a.wrapped().cmp(&b.wrapped()));\n        args.sort_unstable_by(|a, b| a.name().cmp(b.name()));\n        args.sort_unstable_by(|a, b| a.wrapped().cmp(&b.wrapped()));\n        // Reverse\n        args.sort_by(|a, b| b.name().cmp(a.name()));\n        args.sort_by(|a, b| b.wrapped().cmp(&a.wrapped()));\n        args.sort_unstable_by(|a, b| b.name().cmp(a.name()));\n        args.sort_unstable_by(|a, b| b.wrapped().cmp(&a.wrapped()));\n    }\n}\n\n// The closure parameter is not dereferenced anymore, so non-Copy types can be linted\nmod issue_6001 {\n    struct Test(String);\n\n    impl Test {\n        // Return an owned type so that we don't hit the fix for 5754\n        fn name(&self) -> String {\n            self.0.clone()\n        }\n    }\n\n    pub fn test() {\n        let mut args: Vec<Test> = vec![];\n\n        // Forward\n        args.sort_by_key(|a| a.name());\n        //~^ unnecessary_sort_by\n        args.sort_unstable_by_key(|a| a.name());\n        //~^ unnecessary_sort_by\n        // Reverse\n        args.sort_by_key(|b| std::cmp::Reverse(b.name()));\n        //~^ unnecessary_sort_by\n        args.sort_unstable_by_key(|b| std::cmp::Reverse(b.name()));\n        //~^ unnecessary_sort_by\n    }\n}\n\nfn main() {}\n\nfn issue16405() {\n    let mut v: Vec<(i32, &str)> = vec![(1, \"foo\"), (2, \"bar\")];\n\n    v.sort_by_key(|a| a.0);\n    //~^ unnecessary_sort_by\n\n    struct Item {\n        key: i32,\n        value: String,\n    }\n\n    let mut items = vec![\n        Item {\n            key: 2,\n            value: \"b\".to_string(),\n        },\n        Item {\n            key: 1,\n            value: \"a\".to_string(),\n        },\n    ];\n    items.sort_by_key(|item1| item1.key);\n    //~^ unnecessary_sort_by\n\n    items.sort_by(|item1, item2| item1.value.cmp(&item2.value));\n\n    items.sort_by_key(|item1| item1.value.clone());\n    //~^ unnecessary_sort_by\n}\n\nfn issue16348() {\n    let mut v: Vec<(i32, &str)> = vec![(1, \"foo\"), (2, \"bar\")];\n    v.sort_by_key(|(_, s1)| *s1);\n    //~^ unnecessary_sort_by\n\n    struct Foo {\n        bar: i32,\n    }\n    let mut v: Vec<Foo> = vec![Foo { bar: 1 }, Foo { bar: 2 }];\n    v.sort_by_key(|Foo { bar: b1 }| *b1);\n    //~^ unnecessary_sort_by\n\n    struct Baz(i32);\n    let mut v: Vec<Baz> = vec![Baz(1), Baz(2)];\n    v.sort_by_key(|Baz(b1)| *b1);\n    //~^ unnecessary_sort_by\n\n    v.sort_by_key(|&Baz(b1)| b1);\n    //~^ unnecessary_sort_by\n\n    let mut v: Vec<&i32> = vec![&1, &2];\n    v.sort_by_key(|&&b1| b1);\n    //~^ unnecessary_sort_by\n\n    let mut v: Vec<[i32; 2]> = vec![[1, 2], [3, 4]];\n    v.sort_by_key(|[a1, b1]| *a1);\n    //~^ unnecessary_sort_by\n\n    v.sort_by_key(|[a1, b1]| a1 - b1);\n    //~^ unnecessary_sort_by\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_sort_by.rs",
    "content": "#![allow(clippy::stable_sort_primitive, clippy::useless_vec)]\n\nuse std::cell::Ref;\n\nfn unnecessary_sort_by() {\n    fn id(x: isize) -> isize {\n        x\n    }\n\n    let mut vec: Vec<isize> = vec![3, 6, 1, 2, 5];\n    // Forward examples\n    vec.sort_by(|a, b| a.cmp(b));\n    //~^ unnecessary_sort_by\n    vec.sort_unstable_by(|a, b| a.cmp(b));\n    //~^ unnecessary_sort_by\n    vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs()));\n    //~^ unnecessary_sort_by\n    vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b)));\n    //~^ unnecessary_sort_by\n    // Reverse examples\n    vec.sort_by(|a, b| b.cmp(a)); // not linted to avoid suggesting `Reverse(b)` which would borrow\n    vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs()));\n    //~^ unnecessary_sort_by\n    vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a)));\n    //~^ unnecessary_sort_by\n    // Negative examples (shouldn't be changed)\n    let c = &7;\n    vec.sort_by(|a, b| (b - a).cmp(&(a - b)));\n    vec.sort_by(|_, b| b.cmp(&5));\n    vec.sort_by(|_, b| b.cmp(c));\n    vec.sort_unstable_by(|a, _| a.cmp(c));\n\n    // Vectors of references are fine as long as the resulting key does not borrow\n    let mut vec: Vec<&&&isize> = vec![&&&3, &&&6, &&&1, &&&2, &&&5];\n    vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));\n    //~^ unnecessary_sort_by\n    vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));\n    //~^ unnecessary_sort_by\n    // `Reverse(b)` would borrow in the following cases, don't lint\n    vec.sort_by(|a, b| b.cmp(a));\n    vec.sort_unstable_by(|a, b| b.cmp(a));\n\n    // No warning if element does not implement `Ord`\n    let mut vec: Vec<Ref<usize>> = Vec::new();\n    vec.sort_unstable_by(|a, b| a.cmp(b));\n}\n\n// Do not suggest returning a reference to the closure parameter of `Vec::sort_by_key`\nmod issue_5754 {\n    #[derive(Clone, Copy)]\n    struct Test(usize);\n\n    #[derive(PartialOrd, Ord, PartialEq, Eq)]\n    struct Wrapper<'a>(&'a usize);\n\n    impl Test {\n        fn name(&self) -> &usize {\n            &self.0\n        }\n\n        fn wrapped(&self) -> Wrapper<'_> {\n            Wrapper(&self.0)\n        }\n    }\n\n    pub fn test() {\n        let mut args: Vec<Test> = vec![];\n\n        // Forward\n        args.sort_by(|a, b| a.name().cmp(b.name()));\n        args.sort_by(|a, b| a.wrapped().cmp(&b.wrapped()));\n        args.sort_unstable_by(|a, b| a.name().cmp(b.name()));\n        args.sort_unstable_by(|a, b| a.wrapped().cmp(&b.wrapped()));\n        // Reverse\n        args.sort_by(|a, b| b.name().cmp(a.name()));\n        args.sort_by(|a, b| b.wrapped().cmp(&a.wrapped()));\n        args.sort_unstable_by(|a, b| b.name().cmp(a.name()));\n        args.sort_unstable_by(|a, b| b.wrapped().cmp(&a.wrapped()));\n    }\n}\n\n// The closure parameter is not dereferenced anymore, so non-Copy types can be linted\nmod issue_6001 {\n    struct Test(String);\n\n    impl Test {\n        // Return an owned type so that we don't hit the fix for 5754\n        fn name(&self) -> String {\n            self.0.clone()\n        }\n    }\n\n    pub fn test() {\n        let mut args: Vec<Test> = vec![];\n\n        // Forward\n        args.sort_by(|a, b| a.name().cmp(&b.name()));\n        //~^ unnecessary_sort_by\n        args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));\n        //~^ unnecessary_sort_by\n        // Reverse\n        args.sort_by(|a, b| b.name().cmp(&a.name()));\n        //~^ unnecessary_sort_by\n        args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));\n        //~^ unnecessary_sort_by\n    }\n}\n\nfn main() {}\n\nfn issue16405() {\n    let mut v: Vec<(i32, &str)> = vec![(1, \"foo\"), (2, \"bar\")];\n\n    v.sort_by(|a, b| a.0.cmp(&b.0));\n    //~^ unnecessary_sort_by\n\n    struct Item {\n        key: i32,\n        value: String,\n    }\n\n    let mut items = vec![\n        Item {\n            key: 2,\n            value: \"b\".to_string(),\n        },\n        Item {\n            key: 1,\n            value: \"a\".to_string(),\n        },\n    ];\n    items.sort_by(|item1, item2| item1.key.cmp(&item2.key));\n    //~^ unnecessary_sort_by\n\n    items.sort_by(|item1, item2| item1.value.cmp(&item2.value));\n\n    items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone()));\n    //~^ unnecessary_sort_by\n}\n\nfn issue16348() {\n    let mut v: Vec<(i32, &str)> = vec![(1, \"foo\"), (2, \"bar\")];\n    v.sort_by(|(_, s1), (_, s2)| s1.cmp(s2));\n    //~^ unnecessary_sort_by\n\n    struct Foo {\n        bar: i32,\n    }\n    let mut v: Vec<Foo> = vec![Foo { bar: 1 }, Foo { bar: 2 }];\n    v.sort_by(|Foo { bar: b1 }, Foo { bar: b2 }| b1.cmp(b2));\n    //~^ unnecessary_sort_by\n\n    struct Baz(i32);\n    let mut v: Vec<Baz> = vec![Baz(1), Baz(2)];\n    v.sort_by(|Baz(b1), Baz(b2)| b1.cmp(b2));\n    //~^ unnecessary_sort_by\n\n    v.sort_by(|&Baz(b1), &Baz(b2)| b1.cmp(&b2));\n    //~^ unnecessary_sort_by\n\n    let mut v: Vec<&i32> = vec![&1, &2];\n    v.sort_by(|&&b1, &&b2| b1.cmp(&b2));\n    //~^ unnecessary_sort_by\n\n    let mut v: Vec<[i32; 2]> = vec![[1, 2], [3, 4]];\n    v.sort_by(|[a1, b1], [a2, b2]| a1.cmp(a2));\n    //~^ unnecessary_sort_by\n\n    v.sort_by(|[a1, b1], [a2, b2]| (a1 - b1).cmp(&(a2 - b2)));\n    //~^ unnecessary_sort_by\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_sort_by.stderr",
    "content": "error: consider using `sort`\n  --> tests/ui/unnecessary_sort_by.rs:12:5\n   |\nLL |     vec.sort_by(|a, b| a.cmp(b));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-sort-by` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]`\nhelp: try\n   |\nLL -     vec.sort_by(|a, b| a.cmp(b));\nLL +     vec.sort();\n   |\n\nerror: consider using `sort_unstable`\n  --> tests/ui/unnecessary_sort_by.rs:14:5\n   |\nLL |     vec.sort_unstable_by(|a, b| a.cmp(b));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     vec.sort_unstable_by(|a, b| a.cmp(b));\nLL +     vec.sort_unstable();\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:16:5\n   |\nLL |     vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs()));\nLL +     vec.sort_by_key(|a| (a + 5).abs());\n   |\n\nerror: consider using `sort_unstable_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:18:5\n   |\nLL |     vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b)));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b)));\nLL +     vec.sort_unstable_by_key(|a| id(-a));\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:22:5\n   |\nLL |     vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs()));\nLL +     vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs()));\n   |\n\nerror: consider using `sort_unstable_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:24:5\n   |\nLL |     vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a)));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a)));\nLL +     vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b)));\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:35:5\n   |\nLL |     vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));\nLL +     vec.sort_by_key(|a| (***a).abs());\n   |\n\nerror: consider using `sort_unstable_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:37:5\n   |\nLL |     vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));\nLL +     vec.sort_unstable_by_key(|a| (***a).abs());\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:97:9\n   |\nLL |         args.sort_by(|a, b| a.name().cmp(&b.name()));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         args.sort_by(|a, b| a.name().cmp(&b.name()));\nLL +         args.sort_by_key(|a| a.name());\n   |\n\nerror: consider using `sort_unstable_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:99:9\n   |\nLL |         args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));\nLL +         args.sort_unstable_by_key(|a| a.name());\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:102:9\n   |\nLL |         args.sort_by(|a, b| b.name().cmp(&a.name()));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         args.sort_by(|a, b| b.name().cmp(&a.name()));\nLL +         args.sort_by_key(|b| std::cmp::Reverse(b.name()));\n   |\n\nerror: consider using `sort_unstable_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:104:9\n   |\nLL |         args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -         args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));\nLL +         args.sort_unstable_by_key(|b| std::cmp::Reverse(b.name()));\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:114:5\n   |\nLL |     v.sort_by(|a, b| a.0.cmp(&b.0));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     v.sort_by(|a, b| a.0.cmp(&b.0));\nLL +     v.sort_by_key(|a| a.0);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:132:5\n   |\nLL |     items.sort_by(|item1, item2| item1.key.cmp(&item2.key));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     items.sort_by(|item1, item2| item1.key.cmp(&item2.key));\nLL +     items.sort_by_key(|item1| item1.key);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:137:5\n   |\nLL |     items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     items.sort_by(|item1, item2| item1.value.clone().cmp(&item2.value.clone()));\nLL +     items.sort_by_key(|item1| item1.value.clone());\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:143:5\n   |\nLL |     v.sort_by(|(_, s1), (_, s2)| s1.cmp(s2));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     v.sort_by(|(_, s1), (_, s2)| s1.cmp(s2));\nLL +     v.sort_by_key(|(_, s1)| *s1);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:150:5\n   |\nLL |     v.sort_by(|Foo { bar: b1 }, Foo { bar: b2 }| b1.cmp(b2));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     v.sort_by(|Foo { bar: b1 }, Foo { bar: b2 }| b1.cmp(b2));\nLL +     v.sort_by_key(|Foo { bar: b1 }| *b1);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:155:5\n   |\nLL |     v.sort_by(|Baz(b1), Baz(b2)| b1.cmp(b2));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     v.sort_by(|Baz(b1), Baz(b2)| b1.cmp(b2));\nLL +     v.sort_by_key(|Baz(b1)| *b1);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:158:5\n   |\nLL |     v.sort_by(|&Baz(b1), &Baz(b2)| b1.cmp(&b2));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     v.sort_by(|&Baz(b1), &Baz(b2)| b1.cmp(&b2));\nLL +     v.sort_by_key(|&Baz(b1)| b1);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:162:5\n   |\nLL |     v.sort_by(|&&b1, &&b2| b1.cmp(&b2));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     v.sort_by(|&&b1, &&b2| b1.cmp(&b2));\nLL +     v.sort_by_key(|&&b1| b1);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:166:5\n   |\nLL |     v.sort_by(|[a1, b1], [a2, b2]| a1.cmp(a2));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     v.sort_by(|[a1, b1], [a2, b2]| a1.cmp(a2));\nLL +     v.sort_by_key(|[a1, b1]| *a1);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by.rs:169:5\n   |\nLL |     v.sort_by(|[a1, b1], [a2, b2]| (a1 - b1).cmp(&(a2 - b2)));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     v.sort_by(|[a1, b1], [a2, b2]| (a1 - b1).cmp(&(a2 - b2)));\nLL +     v.sort_by_key(|[a1, b1]| a1 - b1);\n   |\n\nerror: aborting due to 22 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_sort_by_no_core.rs",
    "content": "//@check-pass\n#![feature(no_core)]\n#![no_std]\n#![no_core]\nextern crate alloc;\nextern crate core as mycore;\nuse alloc::vec;\nuse alloc::vec::Vec;\nuse mycore::cmp::Ord as _;\n\nfn issue_11524() -> Vec<i32> {\n    let mut vec = vec![1, 2, 3];\n\n    // We could lint and suggest `vec.sort_by_key(|a| a + 1);`, but we don't bother to -- see the\n    // comment in the lint at line 194\n    vec.sort_by(|a, b| (a + 1).cmp(&(b + 1)));\n    vec\n}\n\nfn issue_11524_2() -> Vec<i32> {\n    let mut vec = vec![1, 2, 3];\n\n    // Should not lint, as even `vec.sort_by_key(|b| core::cmp::Reverse(b + 1));` would not compile\n    vec.sort_by(|a, b| (b + 1).cmp(&(a + 1)));\n    vec\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_sort_by_no_std.fixed",
    "content": "#![no_std]\nextern crate alloc;\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nfn issue_11524() -> Vec<i32> {\n    let mut vec = vec![1, 2, 3];\n\n    // Should lint and suggest `vec.sort_by_key(|a| a + 1);`\n    vec.sort_by_key(|a| a + 1);\n    //~^ unnecessary_sort_by\n    vec\n}\n\nfn issue_11524_2() -> Vec<i32> {\n    let mut vec = vec![1, 2, 3];\n\n    // Should lint and suggest `vec.sort_by_key(|b| core::cmp::Reverse(b + 1));`\n    vec.sort_by_key(|b| core::cmp::Reverse(b + 1));\n    //~^ unnecessary_sort_by\n    vec\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_sort_by_no_std.rs",
    "content": "#![no_std]\nextern crate alloc;\nuse alloc::vec;\nuse alloc::vec::Vec;\n\nfn issue_11524() -> Vec<i32> {\n    let mut vec = vec![1, 2, 3];\n\n    // Should lint and suggest `vec.sort_by_key(|a| a + 1);`\n    vec.sort_by(|a, b| (a + 1).cmp(&(b + 1)));\n    //~^ unnecessary_sort_by\n    vec\n}\n\nfn issue_11524_2() -> Vec<i32> {\n    let mut vec = vec![1, 2, 3];\n\n    // Should lint and suggest `vec.sort_by_key(|b| core::cmp::Reverse(b + 1));`\n    vec.sort_by(|a, b| (b + 1).cmp(&(a + 1)));\n    //~^ unnecessary_sort_by\n    vec\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_sort_by_no_std.stderr",
    "content": "error: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by_no_std.rs:10:5\n   |\nLL |     vec.sort_by(|a, b| (a + 1).cmp(&(b + 1)));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-sort-by` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]`\nhelp: try\n   |\nLL -     vec.sort_by(|a, b| (a + 1).cmp(&(b + 1)));\nLL +     vec.sort_by_key(|a| a + 1);\n   |\n\nerror: consider using `sort_by_key`\n  --> tests/ui/unnecessary_sort_by_no_std.rs:19:5\n   |\nLL |     vec.sort_by(|a, b| (b + 1).cmp(&(a + 1)));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     vec.sort_by(|a, b| (b + 1).cmp(&(a + 1)));\nLL +     vec.sort_by_key(|b| core::cmp::Reverse(b + 1));\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_struct_initialization.fixed",
    "content": "#![allow(clippy::non_canonical_clone_impl, unused)]\n#![warn(clippy::unnecessary_struct_initialization)]\n\nstruct S {\n    f: String,\n}\n\n#[derive(Clone, Copy)]\nstruct T {\n    f: u32,\n}\n\nstruct U {\n    f: u32,\n}\n\nimpl Clone for U {\n    fn clone(&self) -> Self {\n        // Do not lint: `Self` does not implement `Copy`\n        Self { ..*self }\n    }\n}\n\n#[derive(Copy)]\nstruct V {\n    f: u32,\n}\n\nstruct W {\n    f1: u32,\n    f2: u32,\n}\n\nimpl Clone for V {\n    fn clone(&self) -> Self {\n        // Lint: `Self` implements `Copy`\n        *self\n        //~^ unnecessary_struct_initialization\n    }\n}\n\nfn main() {\n    // Should lint: `a` would be consumed anyway\n    let a = S { f: String::from(\"foo\") };\n    let mut b = a;\n    //~^ unnecessary_struct_initialization\n\n    // Should lint: `b` would be consumed, and is mutable\n    let c = &mut b;\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint as `d` is not mutable\n    let d = S { f: String::from(\"foo\") };\n    let e = &mut S { ..d };\n\n    // Should lint as `f` would be consumed anyway\n    let f = S { f: String::from(\"foo\") };\n    let g = &f;\n    //~^ unnecessary_struct_initialization\n\n    // Should lint: the result of an expression is mutable\n    let h = &mut *Box::new(S { f: String::from(\"foo\") });\n\n    // Should not lint: `m` would be both alive and borrowed\n    let m = T { f: 17 };\n    let n = &T { ..m };\n\n    // Should not lint: `m` should not be modified\n    let o = &mut T { ..m };\n    o.f = 32;\n    assert_eq!(m.f, 17);\n\n    // Should not lint: `m` should not be modified\n    let o = &mut T { ..m } as *mut T;\n    unsafe { &mut *o }.f = 32;\n    assert_eq!(m.f, 17);\n\n    // Should lint: the result of an expression is mutable and temporary\n    let p = &mut *Box::new(T { f: 5 });\n\n    // Should lint: all fields of `q` would be consumed anyway\n    let q = W { f1: 42, f2: 1337 };\n    let r = q;\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint: not all fields of `t` from same source\n    let s = W { f1: 1337, f2: 42 };\n    let t = W { f1: s.f1, f2: r.f2 };\n\n    // Should not lint: different fields of `s` assigned\n    let u = W { f1: s.f2, f2: s.f1 };\n\n    // Should lint: all fields of `v` would be consumed anyway\n    let v = W { f1: 42, f2: 1337 };\n    let w = v;\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint: source differs between fields and base\n    let x = W { f1: 42, f2: 1337 };\n    let y = W { f1: w.f1, ..x };\n\n    // Should lint: range desugars to struct\n    let r1 = 0..5;\n    let r2 = r1;\n    //~^ unnecessary_struct_initialization\n\n    references();\n    shorthand();\n}\n\nfn references() {\n    // Should not lint as `a` is not mutable\n    let a = W { f1: 42, f2: 1337 };\n    let b = &mut W { f1: a.f1, f2: a.f2 };\n\n    // Should lint as `d` is a shared reference\n    let c = W { f1: 42, f2: 1337 };\n    let d = &c;\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint as `e` is not mutable\n    let e = W { f1: 42, f2: 1337 };\n    let f = &mut W { f1: e.f1, ..e };\n\n    // Should lint as `h` is a shared reference\n    let g = W { f1: 42, f2: 1337 };\n    let h = &g;\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint as `j` is copy\n    let i = V { f: 0x1701d };\n    let j = &V { ..i };\n\n    // Should not lint as `k` is copy\n    let k = V { f: 0x1701d };\n    let l = &V { f: k.f };\n}\n\nfn shorthand() {\n    struct S1 {\n        a: i32,\n        b: i32,\n    }\n\n    let a = 42;\n    let s = S1 { a: 3, b: 4 };\n\n    // Should not lint: `a` is not from `s`\n    let s = S1 { a, b: s.b };\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_struct_initialization.rs",
    "content": "#![allow(clippy::non_canonical_clone_impl, unused)]\n#![warn(clippy::unnecessary_struct_initialization)]\n\nstruct S {\n    f: String,\n}\n\n#[derive(Clone, Copy)]\nstruct T {\n    f: u32,\n}\n\nstruct U {\n    f: u32,\n}\n\nimpl Clone for U {\n    fn clone(&self) -> Self {\n        // Do not lint: `Self` does not implement `Copy`\n        Self { ..*self }\n    }\n}\n\n#[derive(Copy)]\nstruct V {\n    f: u32,\n}\n\nstruct W {\n    f1: u32,\n    f2: u32,\n}\n\nimpl Clone for V {\n    fn clone(&self) -> Self {\n        // Lint: `Self` implements `Copy`\n        Self { ..*self }\n        //~^ unnecessary_struct_initialization\n    }\n}\n\nfn main() {\n    // Should lint: `a` would be consumed anyway\n    let a = S { f: String::from(\"foo\") };\n    let mut b = S { ..a };\n    //~^ unnecessary_struct_initialization\n\n    // Should lint: `b` would be consumed, and is mutable\n    let c = &mut S { ..b };\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint as `d` is not mutable\n    let d = S { f: String::from(\"foo\") };\n    let e = &mut S { ..d };\n\n    // Should lint as `f` would be consumed anyway\n    let f = S { f: String::from(\"foo\") };\n    let g = &S { ..f };\n    //~^ unnecessary_struct_initialization\n\n    // Should lint: the result of an expression is mutable\n    let h = &mut S {\n        //~^ unnecessary_struct_initialization\n        ..*Box::new(S { f: String::from(\"foo\") })\n    };\n\n    // Should not lint: `m` would be both alive and borrowed\n    let m = T { f: 17 };\n    let n = &T { ..m };\n\n    // Should not lint: `m` should not be modified\n    let o = &mut T { ..m };\n    o.f = 32;\n    assert_eq!(m.f, 17);\n\n    // Should not lint: `m` should not be modified\n    let o = &mut T { ..m } as *mut T;\n    unsafe { &mut *o }.f = 32;\n    assert_eq!(m.f, 17);\n\n    // Should lint: the result of an expression is mutable and temporary\n    let p = &mut T {\n        //~^ unnecessary_struct_initialization\n        ..*Box::new(T { f: 5 })\n    };\n\n    // Should lint: all fields of `q` would be consumed anyway\n    let q = W { f1: 42, f2: 1337 };\n    let r = W { f1: q.f1, f2: q.f2 };\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint: not all fields of `t` from same source\n    let s = W { f1: 1337, f2: 42 };\n    let t = W { f1: s.f1, f2: r.f2 };\n\n    // Should not lint: different fields of `s` assigned\n    let u = W { f1: s.f2, f2: s.f1 };\n\n    // Should lint: all fields of `v` would be consumed anyway\n    let v = W { f1: 42, f2: 1337 };\n    let w = W { f1: v.f1, ..v };\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint: source differs between fields and base\n    let x = W { f1: 42, f2: 1337 };\n    let y = W { f1: w.f1, ..x };\n\n    // Should lint: range desugars to struct\n    let r1 = 0..5;\n    let r2 = r1.start..r1.end;\n    //~^ unnecessary_struct_initialization\n\n    references();\n    shorthand();\n}\n\nfn references() {\n    // Should not lint as `a` is not mutable\n    let a = W { f1: 42, f2: 1337 };\n    let b = &mut W { f1: a.f1, f2: a.f2 };\n\n    // Should lint as `d` is a shared reference\n    let c = W { f1: 42, f2: 1337 };\n    let d = &W { f1: c.f1, f2: c.f2 };\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint as `e` is not mutable\n    let e = W { f1: 42, f2: 1337 };\n    let f = &mut W { f1: e.f1, ..e };\n\n    // Should lint as `h` is a shared reference\n    let g = W { f1: 42, f2: 1337 };\n    let h = &W { f1: g.f1, ..g };\n    //~^ unnecessary_struct_initialization\n\n    // Should not lint as `j` is copy\n    let i = V { f: 0x1701d };\n    let j = &V { ..i };\n\n    // Should not lint as `k` is copy\n    let k = V { f: 0x1701d };\n    let l = &V { f: k.f };\n}\n\nfn shorthand() {\n    struct S1 {\n        a: i32,\n        b: i32,\n    }\n\n    let a = 42;\n    let s = S1 { a: 3, b: 4 };\n\n    // Should not lint: `a` is not from `s`\n    let s = S1 { a, b: s.b };\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_struct_initialization.stderr",
    "content": "error: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:37:9\n   |\nLL |         Self { ..*self }\n   |         ^^^^^^^^^^^^^^^^ help: replace with: `*self`\n   |\n   = note: `-D clippy::unnecessary-struct-initialization` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_struct_initialization)]`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:45:17\n   |\nLL |     let mut b = S { ..a };\n   |                 ^^^^^^^^^ help: replace with: `a`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:49:18\n   |\nLL |     let c = &mut S { ..b };\n   |                  ^^^^^^^^^ help: replace with: `b`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:58:14\n   |\nLL |     let g = &S { ..f };\n   |              ^^^^^^^^^ help: replace with: `f`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:62:18\n   |\nLL |       let h = &mut S {\n   |  __________________^\nLL | |\nLL | |         ..*Box::new(S { f: String::from(\"foo\") })\nLL | |     };\n   | |_____^ help: replace with: `*Box::new(S { f: String::from(\"foo\") })`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:82:18\n   |\nLL |       let p = &mut T {\n   |  __________________^\nLL | |\nLL | |         ..*Box::new(T { f: 5 })\nLL | |     };\n   | |_____^ help: replace with: `*Box::new(T { f: 5 })`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:89:13\n   |\nLL |     let r = W { f1: q.f1, f2: q.f2 };\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `q`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:101:13\n   |\nLL |     let w = W { f1: v.f1, ..v };\n   |             ^^^^^^^^^^^^^^^^^^^ help: replace with: `v`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:110:14\n   |\nLL |     let r2 = r1.start..r1.end;\n   |              ^^^^^^^^^^^^^^^^ help: replace with: `r1`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:124:14\n   |\nLL |     let d = &W { f1: c.f1, f2: c.f2 };\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `c`\n\nerror: unnecessary struct building\n  --> tests/ui/unnecessary_struct_initialization.rs:133:14\n   |\nLL |     let h = &W { f1: g.f1, ..g };\n   |              ^^^^^^^^^^^^^^^^^^^ help: replace with: `g`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_to_owned.fixed",
    "content": "#![allow(\n    clippy::manual_async_fn,\n    clippy::needless_borrow,\n    clippy::needless_borrows_for_generic_args,\n    clippy::needless_lifetimes,\n    clippy::owned_cow,\n    clippy::ptr_arg,\n    clippy::uninlined_format_args\n)]\n#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]\n\nuse std::borrow::Cow;\nuse std::ffi::{CStr, CString, OsStr, OsString};\nuse std::ops::Deref;\n\n#[derive(Clone)]\nstruct X(String);\n\nimpl Deref for X {\n    type Target = [u8];\n    fn deref(&self) -> &[u8] {\n        self.0.as_bytes()\n    }\n}\n\nimpl AsRef<str> for X {\n    fn as_ref(&self) -> &str {\n        self.0.as_str()\n    }\n}\n\n#[allow(clippy::to_string_trait_impl)]\nimpl ToString for X {\n    fn to_string(&self) -> String {\n        self.0.to_string()\n    }\n}\n\nimpl X {\n    fn join(&self, other: impl AsRef<str>) -> Self {\n        let mut s = self.0.clone();\n        s.push_str(other.as_ref());\n        Self(s)\n    }\n}\n\n#[allow(dead_code)]\n#[derive(Clone)]\nenum FileType {\n    Account,\n    PrivateKey,\n    Certificate,\n}\n\nfn main() {\n    let c_str = CStr::from_bytes_with_nul(&[0]).unwrap();\n    let os_str = OsStr::new(\"x\");\n    let path = std::path::Path::new(\"x\");\n    let s = \"x\";\n    let array = [\"x\"];\n    let array_ref = &[\"x\"];\n    let slice = &[\"x\"][..];\n    let x = X(String::from(\"x\"));\n    let x_ref = &x;\n\n    require_c_str(&Cow::from(c_str));\n    //~^ unnecessary_to_owned\n    require_c_str(c_str);\n    //~^ unnecessary_to_owned\n\n    require_os_str(os_str);\n    //~^ unnecessary_to_owned\n    require_os_str(&Cow::from(os_str));\n    //~^ unnecessary_to_owned\n    require_os_str(os_str);\n    //~^ unnecessary_to_owned\n\n    require_path(path);\n    //~^ unnecessary_to_owned\n    require_path(&Cow::from(path));\n    //~^ unnecessary_to_owned\n    require_path(path);\n    //~^ unnecessary_to_owned\n\n    require_str(s);\n    //~^ unnecessary_to_owned\n    require_str(&Cow::from(s));\n    //~^ unnecessary_to_owned\n    require_str(s);\n    //~^ unnecessary_to_owned\n    require_str(x_ref.as_ref());\n    //~^ unnecessary_to_owned\n\n    require_slice(slice);\n    //~^ unnecessary_to_owned\n    require_slice(&Cow::from(slice));\n    //~^ unnecessary_to_owned\n    require_slice(array.as_ref());\n    //~^ unnecessary_to_owned\n    require_slice(array_ref.as_ref());\n    //~^ unnecessary_to_owned\n    require_slice(slice);\n    //~^ unnecessary_to_owned\n    require_slice(&x_ref.to_owned()); // No longer flagged because of #8759.\n\n    require_x(&Cow::<X>::Owned(x.clone()));\n    //~^ unnecessary_to_owned\n    require_x(&x_ref.to_owned()); // No longer flagged because of #8759.\n\n    require_deref_c_str(c_str);\n    //~^ unnecessary_to_owned\n    require_deref_os_str(os_str);\n    //~^ unnecessary_to_owned\n    require_deref_path(path);\n    //~^ unnecessary_to_owned\n    require_deref_str(s);\n    //~^ unnecessary_to_owned\n    require_deref_slice(slice);\n    //~^ unnecessary_to_owned\n\n    require_impl_deref_c_str(c_str);\n    //~^ unnecessary_to_owned\n    require_impl_deref_os_str(os_str);\n    //~^ unnecessary_to_owned\n    require_impl_deref_path(path);\n    //~^ unnecessary_to_owned\n    require_impl_deref_str(s);\n    //~^ unnecessary_to_owned\n    require_impl_deref_slice(slice);\n    //~^ unnecessary_to_owned\n\n    require_deref_str_slice(s, slice);\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_deref_slice_str(slice, s);\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n\n    require_as_ref_c_str(c_str);\n    //~^ unnecessary_to_owned\n    require_as_ref_os_str(os_str);\n    //~^ unnecessary_to_owned\n    require_as_ref_path(path);\n    //~^ unnecessary_to_owned\n    require_as_ref_str(s);\n    //~^ unnecessary_to_owned\n    require_as_ref_str(&x);\n    //~^ unnecessary_to_owned\n    require_as_ref_slice(array);\n    //~^ unnecessary_to_owned\n    require_as_ref_slice(array_ref);\n    //~^ unnecessary_to_owned\n    require_as_ref_slice(slice);\n    //~^ unnecessary_to_owned\n\n    require_impl_as_ref_c_str(c_str);\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_os_str(os_str);\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_path(path);\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_str(s);\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_str(&x);\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_slice(array);\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_slice(array_ref);\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_slice(slice);\n    //~^ unnecessary_to_owned\n\n    require_as_ref_str_slice(s, array);\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_str_slice(s, array_ref);\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_str_slice(s, slice);\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_slice_str(array, s);\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_slice_str(array_ref, s);\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_slice_str(slice, s);\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n\n    let _ = x.join(x_ref);\n    //~^ unnecessary_to_owned\n\n    let _ = slice.iter().copied();\n    //~^ unnecessary_to_owned\n    let _ = slice.iter().copied();\n    //~^ unnecessary_to_owned\n\n    let _ = slice.iter().copied();\n    //~^ unnecessary_to_owned\n    let _ = slice.iter().copied();\n    //~^ unnecessary_to_owned\n\n    let _ = check_files(&[FileType::Account]);\n\n    // negative tests\n    require_string(&s.to_string());\n    require_string(&Cow::from(s).into_owned());\n    require_string(&s.to_owned());\n    require_string(&x_ref.to_string());\n\n    // `X` isn't copy.\n    require_slice(&x.to_owned());\n    require_deref_slice(x.to_owned());\n\n    // The following should be flagged by `redundant_clone`, but not by this lint.\n    require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap());\n    //~^ redundant_clone\n    require_os_str(&OsString::from(\"x\"));\n    //~^ redundant_clone\n    require_path(&std::path::PathBuf::from(\"x\"));\n    //~^ redundant_clone\n    require_str(&String::from(\"x\"));\n    //~^ redundant_clone\n    require_slice(&[String::from(\"x\")]);\n    //~^ redundant_clone\n\n    let slice = [0u8; 1024];\n    let _ref_str: &str = core::str::from_utf8(&slice).expect(\"not UTF-8\");\n    //~^ unnecessary_to_owned\n    let _ref_str: &str = core::str::from_utf8(b\"foo\").unwrap();\n    //~^ unnecessary_to_owned\n    let _ref_str: &str = core::str::from_utf8(b\"foo\".as_slice()).unwrap();\n    //~^ unnecessary_to_owned\n    // Expression is of type `&String`, can't suggest `str::from_utf8` here\n    let _ref_string = &String::from_utf8(b\"foo\".to_vec()).unwrap();\n    macro_rules! arg_from_macro {\n        () => {\n            b\"foo\".to_vec()\n        };\n    }\n    macro_rules! string_from_utf8_from_macro {\n        () => {\n            &String::from_utf8(b\"foo\".to_vec()).unwrap()\n        };\n    }\n    let _ref_str: &str = &String::from_utf8(arg_from_macro!()).unwrap();\n    let _ref_str: &str = string_from_utf8_from_macro!();\n}\n\nfn require_c_str(_: &CStr) {}\nfn require_os_str(_: &OsStr) {}\nfn require_path(_: &std::path::Path) {}\nfn require_str(_: &str) {}\nfn require_slice<T>(_: &[T]) {}\nfn require_x(_: &X) {}\n\nfn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {}\nfn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {}\nfn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {}\nfn require_deref_str<T: Deref<Target = str>>(_: T) {}\nfn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {}\n\nfn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {}\nfn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {}\nfn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {}\nfn require_impl_deref_str(_: impl Deref<Target = str>) {}\nfn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {}\n\nfn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {}\nfn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {}\n\nfn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {}\nfn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {}\nfn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {}\nfn require_as_ref_str<T: AsRef<str>>(_: T) {}\nfn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {}\n\nfn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {}\nfn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {}\nfn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {}\nfn require_impl_as_ref_str(_: impl AsRef<str>) {}\nfn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {}\n\nfn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {}\nfn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {}\n\n// `check_files` is based on:\n// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262\nfn check_files(file_types: &[FileType]) -> bool {\n    for t in file_types {\n        //~^ unnecessary_to_owned\n        let path = match get_file_path(t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {\n    Ok(std::path::PathBuf::new())\n}\n\nfn require_string(_: &String) {}\n\n// https://github.com/rust-lang/rust-clippy/issues/8507\nmod issue_8507 {\n    #![allow(dead_code)]\n\n    struct Opaque<P>(P);\n\n    pub trait Abstracted {}\n\n    impl<P> Abstracted for Opaque<P> {}\n\n    fn build<P>(p: P) -> Opaque<P>\n    where\n        P: AsRef<str>,\n    {\n        Opaque(p)\n    }\n\n    // Should not lint.\n    fn test_str(s: &str) -> Box<dyn Abstracted> {\n        Box::new(build(s.to_string()))\n    }\n\n    // Should not lint.\n    fn test_x(x: super::X) -> Box<dyn Abstracted> {\n        Box::new(build(x))\n    }\n\n    #[derive(Clone, Copy)]\n    struct Y(&'static str);\n\n    impl AsRef<str> for Y {\n        fn as_ref(&self) -> &str {\n            self.0\n        }\n    }\n\n    #[allow(clippy::to_string_trait_impl)]\n    impl ToString for Y {\n        fn to_string(&self) -> String {\n            self.0.to_string()\n        }\n    }\n\n    // Should lint because Y is copy.\n    fn test_y(y: Y) -> Box<dyn Abstracted> {\n        Box::new(build(y))\n        //~^ unnecessary_to_owned\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/8759\nmod issue_8759 {\n    #![allow(dead_code)]\n\n    #[derive(Default)]\n    struct View {}\n\n    impl std::borrow::ToOwned for View {\n        type Owned = View;\n        fn to_owned(&self) -> Self::Owned {\n            View {}\n        }\n    }\n\n    #[derive(Default)]\n    struct RenderWindow {\n        default_view: View,\n    }\n\n    impl RenderWindow {\n        fn default_view(&self) -> &View {\n            &self.default_view\n        }\n        fn set_view(&mut self, _view: &View) {}\n    }\n\n    fn main() {\n        let mut rw = RenderWindow::default();\n        rw.set_view(&rw.default_view().to_owned());\n    }\n}\n\nmod issue_8759_variant {\n    #![allow(dead_code)]\n\n    #[derive(Clone, Default)]\n    struct View {}\n\n    #[derive(Default)]\n    struct RenderWindow {\n        default_view: View,\n    }\n\n    impl RenderWindow {\n        fn default_view(&self) -> &View {\n            &self.default_view\n        }\n        fn set_view(&mut self, _view: &View) {}\n    }\n\n    fn main() {\n        let mut rw = RenderWindow::default();\n        rw.set_view(&rw.default_view().to_owned());\n    }\n}\n\nmod issue_9317 {\n    #![allow(dead_code)]\n\n    struct Bytes {}\n\n    #[allow(clippy::to_string_trait_impl)]\n    impl ToString for Bytes {\n        fn to_string(&self) -> String {\n            \"123\".to_string()\n        }\n    }\n\n    impl AsRef<[u8]> for Bytes {\n        fn as_ref(&self) -> &[u8] {\n            &[1, 2, 3]\n        }\n    }\n\n    fn consume<C: AsRef<[u8]>>(c: C) {\n        let _ = c;\n    }\n\n    pub fn main() {\n        let b = Bytes {};\n        // Should not lint.\n        consume(b.to_string());\n    }\n}\n\nmod issue_9351 {\n    #![allow(dead_code)]\n\n    use std::ops::Deref;\n    use std::path::{Path, PathBuf};\n\n    fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {\n        x\n    }\n\n    fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}\n\n    fn id<T: AsRef<str>>(x: T) -> T {\n        x\n    }\n\n    fn predicates_are_satisfied(_x: impl std::fmt::Write) {}\n\n    // Should lint\n    fn single_return() -> impl AsRef<str> {\n        id(\"abc\")\n        //~^ unnecessary_to_owned\n    }\n\n    // Should not lint\n    fn multiple_returns(b: bool) -> impl AsRef<str> {\n        if b {\n            return String::new();\n        }\n\n        id(\"abc\".to_string())\n    }\n\n    struct S1(String);\n\n    // Should not lint\n    fn fields1() -> S1 {\n        S1(id(\"abc\".to_string()))\n    }\n\n    struct S2 {\n        s: String,\n    }\n\n    // Should not lint\n    fn fields2() {\n        let mut s = S2 { s: \"abc\".into() };\n        s.s = id(\"abc\".to_string());\n    }\n\n    pub fn main() {\n        let path = std::path::Path::new(\"x\");\n        let path_buf = path.to_owned();\n\n        // Should not lint.\n        let _x: PathBuf = require_deref_path(path.to_owned());\n        generic_arg_used_elsewhere(path.to_owned(), path_buf);\n        predicates_are_satisfied(id(\"abc\".to_string()));\n    }\n}\n\nmod issue_9504 {\n    #![allow(dead_code)]\n\n    async fn foo<S: AsRef<str>>(_: S) {}\n    async fn bar() {\n        foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;\n    }\n}\n\nmod issue_9771a {\n    #![allow(dead_code)]\n\n    use std::marker::PhantomData;\n\n    pub struct Key<K: AsRef<[u8]>, V: ?Sized>(K, PhantomData<V>);\n\n    impl<K: AsRef<[u8]>, V: ?Sized> Key<K, V> {\n        pub fn new(key: K) -> Key<K, V> {\n            Key(key, PhantomData)\n        }\n    }\n\n    pub fn pkh(pkh: &[u8]) -> Key<Vec<u8>, String> {\n        Key::new([b\"pkh-\", pkh].concat().to_vec())\n    }\n}\n\nmod issue_9771b {\n    #![allow(dead_code)]\n\n    pub struct Key<K: AsRef<[u8]>>(K);\n\n    pub fn from(c: &[u8]) -> Key<Vec<u8>> {\n        let v = [c].concat();\n        Key(v.to_vec())\n    }\n}\n\n// This is a watered down version of the code in: https://github.com/oxigraph/rio\n// The ICE is triggered by the call to `to_owned` on this line:\n// https://github.com/oxigraph/rio/blob/66635b9ff8e5423e58932353fa40d6e64e4820f7/testsuite/src/parser_evaluator.rs#L116\nmod issue_10021 {\n    #![allow(unused)]\n\n    pub struct Iri<T>(T);\n\n    impl<T: AsRef<str>> Iri<T> {\n        pub fn parse(iri: T) -> Result<Self, ()> {\n            unimplemented!()\n        }\n    }\n\n    pub fn parse_w3c_rdf_test_file(url: &str) -> Result<(), ()> {\n        let base_iri = Iri::parse(url.to_owned())?;\n        Ok(())\n    }\n}\n\nmod issue_10033 {\n    #![allow(dead_code)]\n    use std::fmt::Display;\n    use std::ops::Deref;\n\n    fn _main() {\n        let f = Foo;\n\n        // Not actually unnecessary - this calls `Foo`'s `Display` impl, not `str`'s (even though `Foo` does\n        // deref to `str`)\n        foo(&f.to_string());\n    }\n\n    fn foo(s: &str) {\n        println!(\"{}\", s);\n    }\n\n    struct Foo;\n\n    impl Deref for Foo {\n        type Target = str;\n\n        fn deref(&self) -> &Self::Target {\n            \"str\"\n        }\n    }\n\n    impl Display for Foo {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            write!(f, \"Foo\")\n        }\n    }\n}\n\nmod issue_11952 {\n    use core::future::{Future, IntoFuture};\n\n    fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {\n        async move {\n            let _y = y;\n            Ok(())\n        }\n    }\n\n    fn bar() {\n        IntoFuture::into_future(foo([], &0));\n        //~^ unnecessary_to_owned\n    }\n}\n\nfn borrow_checks() {\n    use std::borrow::Borrow;\n    use std::collections::HashSet;\n\n    fn inner(a: &[&str]) {\n        let mut s = HashSet::from([vec![\"a\"]]);\n        s.remove(a);\n        //~^ unnecessary_to_owned\n    }\n\n    let mut s = HashSet::from([\"a\".to_string()]);\n    s.remove(\"b\");\n    //~^ unnecessary_to_owned\n    s.remove(\"b\");\n    //~^ unnecessary_to_owned\n    // Should not warn.\n    s.remove(\"b\");\n\n    let mut s = HashSet::from([vec![\"a\"]]);\n    s.remove([\"b\"].as_slice());\n    //~^ unnecessary_to_owned\n    s.remove((&[\"b\"]).as_slice());\n    //~^ unnecessary_to_owned\n\n    // Should not warn.\n    s.remove(&[\"b\"].to_vec().clone());\n    s.remove([\"a\"].as_slice());\n\n    trait SetExt {\n        fn foo<Q: Borrow<str>>(&self, _: &String);\n    }\n\n    impl<K> SetExt for HashSet<K> {\n        fn foo<Q: Borrow<str>>(&self, _: &String) {}\n    }\n\n    // Should not lint!\n    HashSet::<i32>::new().foo::<&str>(&\"\".to_owned());\n    HashSet::<String>::new().get(&1.to_string());\n}\n\nfn issue13624() -> impl IntoIterator {\n    let cow: Cow<'_, Vec<String>> = Cow::Owned(vec![String::from(\"foo\")]);\n\n    cow.into_owned().into_iter()\n}\n\nmod issue_14242 {\n    use std::rc::Rc;\n\n    #[derive(Copy, Clone)]\n    struct Foo;\n\n    fn rc_slice_provider() -> Rc<[Foo]> {\n        Rc::from([Foo])\n    }\n\n    fn iterator_provider() -> impl Iterator<Item = Foo> {\n        rc_slice_provider().to_vec().into_iter()\n    }\n}\n\nfn issue14833() {\n    use std::collections::HashSet;\n    let mut s = HashSet::<&String>::new();\n    s.remove(&\"hello\".to_owned());\n}\n\n#[allow(clippy::redundant_clone)]\nfn issue16351() {\n    fn take(_: impl AsRef<str>) {}\n\n    let dot = \".\";\n    take(&format!(\"ouch{dot}\"));\n    //~^ unnecessary_to_owned\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_to_owned.rs",
    "content": "#![allow(\n    clippy::manual_async_fn,\n    clippy::needless_borrow,\n    clippy::needless_borrows_for_generic_args,\n    clippy::needless_lifetimes,\n    clippy::owned_cow,\n    clippy::ptr_arg,\n    clippy::uninlined_format_args\n)]\n#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]\n\nuse std::borrow::Cow;\nuse std::ffi::{CStr, CString, OsStr, OsString};\nuse std::ops::Deref;\n\n#[derive(Clone)]\nstruct X(String);\n\nimpl Deref for X {\n    type Target = [u8];\n    fn deref(&self) -> &[u8] {\n        self.0.as_bytes()\n    }\n}\n\nimpl AsRef<str> for X {\n    fn as_ref(&self) -> &str {\n        self.0.as_str()\n    }\n}\n\n#[allow(clippy::to_string_trait_impl)]\nimpl ToString for X {\n    fn to_string(&self) -> String {\n        self.0.to_string()\n    }\n}\n\nimpl X {\n    fn join(&self, other: impl AsRef<str>) -> Self {\n        let mut s = self.0.clone();\n        s.push_str(other.as_ref());\n        Self(s)\n    }\n}\n\n#[allow(dead_code)]\n#[derive(Clone)]\nenum FileType {\n    Account,\n    PrivateKey,\n    Certificate,\n}\n\nfn main() {\n    let c_str = CStr::from_bytes_with_nul(&[0]).unwrap();\n    let os_str = OsStr::new(\"x\");\n    let path = std::path::Path::new(\"x\");\n    let s = \"x\";\n    let array = [\"x\"];\n    let array_ref = &[\"x\"];\n    let slice = &[\"x\"][..];\n    let x = X(String::from(\"x\"));\n    let x_ref = &x;\n\n    require_c_str(&Cow::from(c_str).into_owned());\n    //~^ unnecessary_to_owned\n    require_c_str(&c_str.to_owned());\n    //~^ unnecessary_to_owned\n\n    require_os_str(&os_str.to_os_string());\n    //~^ unnecessary_to_owned\n    require_os_str(&Cow::from(os_str).into_owned());\n    //~^ unnecessary_to_owned\n    require_os_str(&os_str.to_owned());\n    //~^ unnecessary_to_owned\n\n    require_path(&path.to_path_buf());\n    //~^ unnecessary_to_owned\n    require_path(&Cow::from(path).into_owned());\n    //~^ unnecessary_to_owned\n    require_path(&path.to_owned());\n    //~^ unnecessary_to_owned\n\n    require_str(&s.to_string());\n    //~^ unnecessary_to_owned\n    require_str(&Cow::from(s).into_owned());\n    //~^ unnecessary_to_owned\n    require_str(&s.to_owned());\n    //~^ unnecessary_to_owned\n    require_str(&x_ref.to_string());\n    //~^ unnecessary_to_owned\n\n    require_slice(&slice.to_vec());\n    //~^ unnecessary_to_owned\n    require_slice(&Cow::from(slice).into_owned());\n    //~^ unnecessary_to_owned\n    require_slice(&array.to_owned());\n    //~^ unnecessary_to_owned\n    require_slice(&array_ref.to_owned());\n    //~^ unnecessary_to_owned\n    require_slice(&slice.to_owned());\n    //~^ unnecessary_to_owned\n    require_slice(&x_ref.to_owned()); // No longer flagged because of #8759.\n\n    require_x(&Cow::<X>::Owned(x.clone()).into_owned());\n    //~^ unnecessary_to_owned\n    require_x(&x_ref.to_owned()); // No longer flagged because of #8759.\n\n    require_deref_c_str(c_str.to_owned());\n    //~^ unnecessary_to_owned\n    require_deref_os_str(os_str.to_owned());\n    //~^ unnecessary_to_owned\n    require_deref_path(path.to_owned());\n    //~^ unnecessary_to_owned\n    require_deref_str(s.to_owned());\n    //~^ unnecessary_to_owned\n    require_deref_slice(slice.to_owned());\n    //~^ unnecessary_to_owned\n\n    require_impl_deref_c_str(c_str.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_deref_os_str(os_str.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_deref_path(path.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_deref_str(s.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_deref_slice(slice.to_owned());\n    //~^ unnecessary_to_owned\n\n    require_deref_str_slice(s.to_owned(), slice.to_owned());\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_deref_slice_str(slice.to_owned(), s.to_owned());\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n\n    require_as_ref_c_str(c_str.to_owned());\n    //~^ unnecessary_to_owned\n    require_as_ref_os_str(os_str.to_owned());\n    //~^ unnecessary_to_owned\n    require_as_ref_path(path.to_owned());\n    //~^ unnecessary_to_owned\n    require_as_ref_str(s.to_owned());\n    //~^ unnecessary_to_owned\n    require_as_ref_str(x.to_owned());\n    //~^ unnecessary_to_owned\n    require_as_ref_slice(array.to_owned());\n    //~^ unnecessary_to_owned\n    require_as_ref_slice(array_ref.to_owned());\n    //~^ unnecessary_to_owned\n    require_as_ref_slice(slice.to_owned());\n    //~^ unnecessary_to_owned\n\n    require_impl_as_ref_c_str(c_str.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_os_str(os_str.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_path(path.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_str(s.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_str(x.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_slice(array.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_slice(array_ref.to_owned());\n    //~^ unnecessary_to_owned\n    require_impl_as_ref_slice(slice.to_owned());\n    //~^ unnecessary_to_owned\n\n    require_as_ref_str_slice(s.to_owned(), array.to_owned());\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_str_slice(s.to_owned(), slice.to_owned());\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_slice_str(array.to_owned(), s.to_owned());\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n    require_as_ref_slice_str(slice.to_owned(), s.to_owned());\n    //~^ unnecessary_to_owned\n    //~| unnecessary_to_owned\n\n    let _ = x.join(&x_ref.to_string());\n    //~^ unnecessary_to_owned\n\n    let _ = slice.to_vec().into_iter();\n    //~^ unnecessary_to_owned\n    let _ = slice.to_owned().into_iter();\n    //~^ unnecessary_to_owned\n\n    let _ = IntoIterator::into_iter(slice.to_vec());\n    //~^ unnecessary_to_owned\n    let _ = IntoIterator::into_iter(slice.to_owned());\n    //~^ unnecessary_to_owned\n\n    let _ = check_files(&[FileType::Account]);\n\n    // negative tests\n    require_string(&s.to_string());\n    require_string(&Cow::from(s).into_owned());\n    require_string(&s.to_owned());\n    require_string(&x_ref.to_string());\n\n    // `X` isn't copy.\n    require_slice(&x.to_owned());\n    require_deref_slice(x.to_owned());\n\n    // The following should be flagged by `redundant_clone`, but not by this lint.\n    require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());\n    //~^ redundant_clone\n    require_os_str(&OsString::from(\"x\").to_os_string());\n    //~^ redundant_clone\n    require_path(&std::path::PathBuf::from(\"x\").to_path_buf());\n    //~^ redundant_clone\n    require_str(&String::from(\"x\").to_string());\n    //~^ redundant_clone\n    require_slice(&[String::from(\"x\")].to_owned());\n    //~^ redundant_clone\n\n    let slice = [0u8; 1024];\n    let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect(\"not UTF-8\");\n    //~^ unnecessary_to_owned\n    let _ref_str: &str = &String::from_utf8(b\"foo\".to_vec()).unwrap();\n    //~^ unnecessary_to_owned\n    let _ref_str: &str = &String::from_utf8(b\"foo\".as_slice().to_owned()).unwrap();\n    //~^ unnecessary_to_owned\n    // Expression is of type `&String`, can't suggest `str::from_utf8` here\n    let _ref_string = &String::from_utf8(b\"foo\".to_vec()).unwrap();\n    macro_rules! arg_from_macro {\n        () => {\n            b\"foo\".to_vec()\n        };\n    }\n    macro_rules! string_from_utf8_from_macro {\n        () => {\n            &String::from_utf8(b\"foo\".to_vec()).unwrap()\n        };\n    }\n    let _ref_str: &str = &String::from_utf8(arg_from_macro!()).unwrap();\n    let _ref_str: &str = string_from_utf8_from_macro!();\n}\n\nfn require_c_str(_: &CStr) {}\nfn require_os_str(_: &OsStr) {}\nfn require_path(_: &std::path::Path) {}\nfn require_str(_: &str) {}\nfn require_slice<T>(_: &[T]) {}\nfn require_x(_: &X) {}\n\nfn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {}\nfn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {}\nfn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {}\nfn require_deref_str<T: Deref<Target = str>>(_: T) {}\nfn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {}\n\nfn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {}\nfn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {}\nfn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {}\nfn require_impl_deref_str(_: impl Deref<Target = str>) {}\nfn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {}\n\nfn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {}\nfn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {}\n\nfn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {}\nfn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {}\nfn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {}\nfn require_as_ref_str<T: AsRef<str>>(_: T) {}\nfn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {}\n\nfn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {}\nfn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {}\nfn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {}\nfn require_impl_as_ref_str(_: impl AsRef<str>) {}\nfn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {}\n\nfn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {}\nfn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {}\n\n// `check_files` is based on:\n// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262\nfn check_files(file_types: &[FileType]) -> bool {\n    for t in file_types.to_vec() {\n        //~^ unnecessary_to_owned\n        let path = match get_file_path(&t) {\n            Ok(p) => p,\n            Err(_) => {\n                return false;\n            },\n        };\n        if !path.is_file() {\n            return false;\n        }\n    }\n    true\n}\n\nfn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {\n    Ok(std::path::PathBuf::new())\n}\n\nfn require_string(_: &String) {}\n\n// https://github.com/rust-lang/rust-clippy/issues/8507\nmod issue_8507 {\n    #![allow(dead_code)]\n\n    struct Opaque<P>(P);\n\n    pub trait Abstracted {}\n\n    impl<P> Abstracted for Opaque<P> {}\n\n    fn build<P>(p: P) -> Opaque<P>\n    where\n        P: AsRef<str>,\n    {\n        Opaque(p)\n    }\n\n    // Should not lint.\n    fn test_str(s: &str) -> Box<dyn Abstracted> {\n        Box::new(build(s.to_string()))\n    }\n\n    // Should not lint.\n    fn test_x(x: super::X) -> Box<dyn Abstracted> {\n        Box::new(build(x))\n    }\n\n    #[derive(Clone, Copy)]\n    struct Y(&'static str);\n\n    impl AsRef<str> for Y {\n        fn as_ref(&self) -> &str {\n            self.0\n        }\n    }\n\n    #[allow(clippy::to_string_trait_impl)]\n    impl ToString for Y {\n        fn to_string(&self) -> String {\n            self.0.to_string()\n        }\n    }\n\n    // Should lint because Y is copy.\n    fn test_y(y: Y) -> Box<dyn Abstracted> {\n        Box::new(build(y.to_string()))\n        //~^ unnecessary_to_owned\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/8759\nmod issue_8759 {\n    #![allow(dead_code)]\n\n    #[derive(Default)]\n    struct View {}\n\n    impl std::borrow::ToOwned for View {\n        type Owned = View;\n        fn to_owned(&self) -> Self::Owned {\n            View {}\n        }\n    }\n\n    #[derive(Default)]\n    struct RenderWindow {\n        default_view: View,\n    }\n\n    impl RenderWindow {\n        fn default_view(&self) -> &View {\n            &self.default_view\n        }\n        fn set_view(&mut self, _view: &View) {}\n    }\n\n    fn main() {\n        let mut rw = RenderWindow::default();\n        rw.set_view(&rw.default_view().to_owned());\n    }\n}\n\nmod issue_8759_variant {\n    #![allow(dead_code)]\n\n    #[derive(Clone, Default)]\n    struct View {}\n\n    #[derive(Default)]\n    struct RenderWindow {\n        default_view: View,\n    }\n\n    impl RenderWindow {\n        fn default_view(&self) -> &View {\n            &self.default_view\n        }\n        fn set_view(&mut self, _view: &View) {}\n    }\n\n    fn main() {\n        let mut rw = RenderWindow::default();\n        rw.set_view(&rw.default_view().to_owned());\n    }\n}\n\nmod issue_9317 {\n    #![allow(dead_code)]\n\n    struct Bytes {}\n\n    #[allow(clippy::to_string_trait_impl)]\n    impl ToString for Bytes {\n        fn to_string(&self) -> String {\n            \"123\".to_string()\n        }\n    }\n\n    impl AsRef<[u8]> for Bytes {\n        fn as_ref(&self) -> &[u8] {\n            &[1, 2, 3]\n        }\n    }\n\n    fn consume<C: AsRef<[u8]>>(c: C) {\n        let _ = c;\n    }\n\n    pub fn main() {\n        let b = Bytes {};\n        // Should not lint.\n        consume(b.to_string());\n    }\n}\n\nmod issue_9351 {\n    #![allow(dead_code)]\n\n    use std::ops::Deref;\n    use std::path::{Path, PathBuf};\n\n    fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {\n        x\n    }\n\n    fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}\n\n    fn id<T: AsRef<str>>(x: T) -> T {\n        x\n    }\n\n    fn predicates_are_satisfied(_x: impl std::fmt::Write) {}\n\n    // Should lint\n    fn single_return() -> impl AsRef<str> {\n        id(\"abc\".to_string())\n        //~^ unnecessary_to_owned\n    }\n\n    // Should not lint\n    fn multiple_returns(b: bool) -> impl AsRef<str> {\n        if b {\n            return String::new();\n        }\n\n        id(\"abc\".to_string())\n    }\n\n    struct S1(String);\n\n    // Should not lint\n    fn fields1() -> S1 {\n        S1(id(\"abc\".to_string()))\n    }\n\n    struct S2 {\n        s: String,\n    }\n\n    // Should not lint\n    fn fields2() {\n        let mut s = S2 { s: \"abc\".into() };\n        s.s = id(\"abc\".to_string());\n    }\n\n    pub fn main() {\n        let path = std::path::Path::new(\"x\");\n        let path_buf = path.to_owned();\n\n        // Should not lint.\n        let _x: PathBuf = require_deref_path(path.to_owned());\n        generic_arg_used_elsewhere(path.to_owned(), path_buf);\n        predicates_are_satisfied(id(\"abc\".to_string()));\n    }\n}\n\nmod issue_9504 {\n    #![allow(dead_code)]\n\n    async fn foo<S: AsRef<str>>(_: S) {}\n    async fn bar() {\n        foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;\n    }\n}\n\nmod issue_9771a {\n    #![allow(dead_code)]\n\n    use std::marker::PhantomData;\n\n    pub struct Key<K: AsRef<[u8]>, V: ?Sized>(K, PhantomData<V>);\n\n    impl<K: AsRef<[u8]>, V: ?Sized> Key<K, V> {\n        pub fn new(key: K) -> Key<K, V> {\n            Key(key, PhantomData)\n        }\n    }\n\n    pub fn pkh(pkh: &[u8]) -> Key<Vec<u8>, String> {\n        Key::new([b\"pkh-\", pkh].concat().to_vec())\n    }\n}\n\nmod issue_9771b {\n    #![allow(dead_code)]\n\n    pub struct Key<K: AsRef<[u8]>>(K);\n\n    pub fn from(c: &[u8]) -> Key<Vec<u8>> {\n        let v = [c].concat();\n        Key(v.to_vec())\n    }\n}\n\n// This is a watered down version of the code in: https://github.com/oxigraph/rio\n// The ICE is triggered by the call to `to_owned` on this line:\n// https://github.com/oxigraph/rio/blob/66635b9ff8e5423e58932353fa40d6e64e4820f7/testsuite/src/parser_evaluator.rs#L116\nmod issue_10021 {\n    #![allow(unused)]\n\n    pub struct Iri<T>(T);\n\n    impl<T: AsRef<str>> Iri<T> {\n        pub fn parse(iri: T) -> Result<Self, ()> {\n            unimplemented!()\n        }\n    }\n\n    pub fn parse_w3c_rdf_test_file(url: &str) -> Result<(), ()> {\n        let base_iri = Iri::parse(url.to_owned())?;\n        Ok(())\n    }\n}\n\nmod issue_10033 {\n    #![allow(dead_code)]\n    use std::fmt::Display;\n    use std::ops::Deref;\n\n    fn _main() {\n        let f = Foo;\n\n        // Not actually unnecessary - this calls `Foo`'s `Display` impl, not `str`'s (even though `Foo` does\n        // deref to `str`)\n        foo(&f.to_string());\n    }\n\n    fn foo(s: &str) {\n        println!(\"{}\", s);\n    }\n\n    struct Foo;\n\n    impl Deref for Foo {\n        type Target = str;\n\n        fn deref(&self) -> &Self::Target {\n            \"str\"\n        }\n    }\n\n    impl Display for Foo {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            write!(f, \"Foo\")\n        }\n    }\n}\n\nmod issue_11952 {\n    use core::future::{Future, IntoFuture};\n\n    fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {\n        async move {\n            let _y = y;\n            Ok(())\n        }\n    }\n\n    fn bar() {\n        IntoFuture::into_future(foo([].to_vec(), &0));\n        //~^ unnecessary_to_owned\n    }\n}\n\nfn borrow_checks() {\n    use std::borrow::Borrow;\n    use std::collections::HashSet;\n\n    fn inner(a: &[&str]) {\n        let mut s = HashSet::from([vec![\"a\"]]);\n        s.remove(&a.to_vec());\n        //~^ unnecessary_to_owned\n    }\n\n    let mut s = HashSet::from([\"a\".to_string()]);\n    s.remove(&\"b\".to_owned());\n    //~^ unnecessary_to_owned\n    s.remove(&\"b\".to_string());\n    //~^ unnecessary_to_owned\n    // Should not warn.\n    s.remove(\"b\");\n\n    let mut s = HashSet::from([vec![\"a\"]]);\n    s.remove(&[\"b\"].to_vec());\n    //~^ unnecessary_to_owned\n    s.remove(&(&[\"b\"]).to_vec());\n    //~^ unnecessary_to_owned\n\n    // Should not warn.\n    s.remove(&[\"b\"].to_vec().clone());\n    s.remove([\"a\"].as_slice());\n\n    trait SetExt {\n        fn foo<Q: Borrow<str>>(&self, _: &String);\n    }\n\n    impl<K> SetExt for HashSet<K> {\n        fn foo<Q: Borrow<str>>(&self, _: &String) {}\n    }\n\n    // Should not lint!\n    HashSet::<i32>::new().foo::<&str>(&\"\".to_owned());\n    HashSet::<String>::new().get(&1.to_string());\n}\n\nfn issue13624() -> impl IntoIterator {\n    let cow: Cow<'_, Vec<String>> = Cow::Owned(vec![String::from(\"foo\")]);\n\n    cow.into_owned().into_iter()\n}\n\nmod issue_14242 {\n    use std::rc::Rc;\n\n    #[derive(Copy, Clone)]\n    struct Foo;\n\n    fn rc_slice_provider() -> Rc<[Foo]> {\n        Rc::from([Foo])\n    }\n\n    fn iterator_provider() -> impl Iterator<Item = Foo> {\n        rc_slice_provider().to_vec().into_iter()\n    }\n}\n\nfn issue14833() {\n    use std::collections::HashSet;\n    let mut s = HashSet::<&String>::new();\n    s.remove(&\"hello\".to_owned());\n}\n\n#[allow(clippy::redundant_clone)]\nfn issue16351() {\n    fn take(_: impl AsRef<str>) {}\n\n    let dot = \".\";\n    take(format!(\"ouch{dot}\").to_string());\n    //~^ unnecessary_to_owned\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_to_owned.stderr",
    "content": "error: redundant clone\n  --> tests/ui/unnecessary_to_owned.rs:218:64\n   |\nLL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());\n   |                                                                ^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/unnecessary_to_owned.rs:218:20\n   |\nLL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::redundant-clone` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`\n\nerror: redundant clone\n  --> tests/ui/unnecessary_to_owned.rs:220:40\n   |\nLL |     require_os_str(&OsString::from(\"x\").to_os_string());\n   |                                        ^^^^^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/unnecessary_to_owned.rs:220:21\n   |\nLL |     require_os_str(&OsString::from(\"x\").to_os_string());\n   |                     ^^^^^^^^^^^^^^^^^^^\n\nerror: redundant clone\n  --> tests/ui/unnecessary_to_owned.rs:222:48\n   |\nLL |     require_path(&std::path::PathBuf::from(\"x\").to_path_buf());\n   |                                                ^^^^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/unnecessary_to_owned.rs:222:19\n   |\nLL |     require_path(&std::path::PathBuf::from(\"x\").to_path_buf());\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: redundant clone\n  --> tests/ui/unnecessary_to_owned.rs:224:35\n   |\nLL |     require_str(&String::from(\"x\").to_string());\n   |                                   ^^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/unnecessary_to_owned.rs:224:18\n   |\nLL |     require_str(&String::from(\"x\").to_string());\n   |                  ^^^^^^^^^^^^^^^^^\n\nerror: redundant clone\n  --> tests/ui/unnecessary_to_owned.rs:226:39\n   |\nLL |     require_slice(&[String::from(\"x\")].to_owned());\n   |                                       ^^^^^^^^^^^ help: remove this\n   |\nnote: this value is dropped without further use\n  --> tests/ui/unnecessary_to_owned.rs:226:20\n   |\nLL |     require_slice(&[String::from(\"x\")].to_owned());\n   |                    ^^^^^^^^^^^^^^^^^^^\n\nerror: unnecessary use of `into_owned`\n  --> tests/ui/unnecessary_to_owned.rs:66:36\n   |\nLL |     require_c_str(&Cow::from(c_str).into_owned());\n   |                                    ^^^^^^^^^^^^^ help: remove this\n   |\n   = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:68:19\n   |\nLL |     require_c_str(&c_str.to_owned());\n   |                   ^^^^^^^^^^^^^^^^^ help: use: `c_str`\n\nerror: unnecessary use of `to_os_string`\n  --> tests/ui/unnecessary_to_owned.rs:71:20\n   |\nLL |     require_os_str(&os_str.to_os_string());\n   |                    ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str`\n\nerror: unnecessary use of `into_owned`\n  --> tests/ui/unnecessary_to_owned.rs:73:38\n   |\nLL |     require_os_str(&Cow::from(os_str).into_owned());\n   |                                      ^^^^^^^^^^^^^ help: remove this\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:75:20\n   |\nLL |     require_os_str(&os_str.to_owned());\n   |                    ^^^^^^^^^^^^^^^^^^ help: use: `os_str`\n\nerror: unnecessary use of `to_path_buf`\n  --> tests/ui/unnecessary_to_owned.rs:78:18\n   |\nLL |     require_path(&path.to_path_buf());\n   |                  ^^^^^^^^^^^^^^^^^^^ help: use: `path`\n\nerror: unnecessary use of `into_owned`\n  --> tests/ui/unnecessary_to_owned.rs:80:34\n   |\nLL |     require_path(&Cow::from(path).into_owned());\n   |                                  ^^^^^^^^^^^^^ help: remove this\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:82:18\n   |\nLL |     require_path(&path.to_owned());\n   |                  ^^^^^^^^^^^^^^^^ help: use: `path`\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned.rs:85:17\n   |\nLL |     require_str(&s.to_string());\n   |                 ^^^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `into_owned`\n  --> tests/ui/unnecessary_to_owned.rs:87:30\n   |\nLL |     require_str(&Cow::from(s).into_owned());\n   |                              ^^^^^^^^^^^^^ help: remove this\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:89:17\n   |\nLL |     require_str(&s.to_owned());\n   |                 ^^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned.rs:91:17\n   |\nLL |     require_str(&x_ref.to_string());\n   |                 ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned.rs:94:19\n   |\nLL |     require_slice(&slice.to_vec());\n   |                   ^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `into_owned`\n  --> tests/ui/unnecessary_to_owned.rs:96:36\n   |\nLL |     require_slice(&Cow::from(slice).into_owned());\n   |                                    ^^^^^^^^^^^^^ help: remove this\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:98:19\n   |\nLL |     require_slice(&array.to_owned());\n   |                   ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:100:19\n   |\nLL |     require_slice(&array_ref.to_owned());\n   |                   ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:102:19\n   |\nLL |     require_slice(&slice.to_owned());\n   |                   ^^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `into_owned`\n  --> tests/ui/unnecessary_to_owned.rs:106:42\n   |\nLL |     require_x(&Cow::<X>::Owned(x.clone()).into_owned());\n   |                                          ^^^^^^^^^^^^^ help: remove this\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:110:25\n   |\nLL |     require_deref_c_str(c_str.to_owned());\n   |                         ^^^^^^^^^^^^^^^^ help: use: `c_str`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:112:26\n   |\nLL |     require_deref_os_str(os_str.to_owned());\n   |                          ^^^^^^^^^^^^^^^^^ help: use: `os_str`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:114:24\n   |\nLL |     require_deref_path(path.to_owned());\n   |                        ^^^^^^^^^^^^^^^ help: use: `path`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:116:23\n   |\nLL |     require_deref_str(s.to_owned());\n   |                       ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:118:25\n   |\nLL |     require_deref_slice(slice.to_owned());\n   |                         ^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:121:30\n   |\nLL |     require_impl_deref_c_str(c_str.to_owned());\n   |                              ^^^^^^^^^^^^^^^^ help: use: `c_str`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:123:31\n   |\nLL |     require_impl_deref_os_str(os_str.to_owned());\n   |                               ^^^^^^^^^^^^^^^^^ help: use: `os_str`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:125:29\n   |\nLL |     require_impl_deref_path(path.to_owned());\n   |                             ^^^^^^^^^^^^^^^ help: use: `path`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:127:28\n   |\nLL |     require_impl_deref_str(s.to_owned());\n   |                            ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:129:30\n   |\nLL |     require_impl_deref_slice(slice.to_owned());\n   |                              ^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:132:29\n   |\nLL |     require_deref_str_slice(s.to_owned(), slice.to_owned());\n   |                             ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:132:43\n   |\nLL |     require_deref_str_slice(s.to_owned(), slice.to_owned());\n   |                                           ^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:135:29\n   |\nLL |     require_deref_slice_str(slice.to_owned(), s.to_owned());\n   |                             ^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:135:47\n   |\nLL |     require_deref_slice_str(slice.to_owned(), s.to_owned());\n   |                                               ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:139:26\n   |\nLL |     require_as_ref_c_str(c_str.to_owned());\n   |                          ^^^^^^^^^^^^^^^^ help: use: `c_str`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:141:27\n   |\nLL |     require_as_ref_os_str(os_str.to_owned());\n   |                           ^^^^^^^^^^^^^^^^^ help: use: `os_str`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:143:25\n   |\nLL |     require_as_ref_path(path.to_owned());\n   |                         ^^^^^^^^^^^^^^^ help: use: `path`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:145:24\n   |\nLL |     require_as_ref_str(s.to_owned());\n   |                        ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:147:24\n   |\nLL |     require_as_ref_str(x.to_owned());\n   |                        ^^^^^^^^^^^^ help: use: `&x`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:149:26\n   |\nLL |     require_as_ref_slice(array.to_owned());\n   |                          ^^^^^^^^^^^^^^^^ help: use: `array`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:151:26\n   |\nLL |     require_as_ref_slice(array_ref.to_owned());\n   |                          ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:153:26\n   |\nLL |     require_as_ref_slice(slice.to_owned());\n   |                          ^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:156:31\n   |\nLL |     require_impl_as_ref_c_str(c_str.to_owned());\n   |                               ^^^^^^^^^^^^^^^^ help: use: `c_str`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:158:32\n   |\nLL |     require_impl_as_ref_os_str(os_str.to_owned());\n   |                                ^^^^^^^^^^^^^^^^^ help: use: `os_str`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:160:30\n   |\nLL |     require_impl_as_ref_path(path.to_owned());\n   |                              ^^^^^^^^^^^^^^^ help: use: `path`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:162:29\n   |\nLL |     require_impl_as_ref_str(s.to_owned());\n   |                             ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:164:29\n   |\nLL |     require_impl_as_ref_str(x.to_owned());\n   |                             ^^^^^^^^^^^^ help: use: `&x`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:166:31\n   |\nLL |     require_impl_as_ref_slice(array.to_owned());\n   |                               ^^^^^^^^^^^^^^^^ help: use: `array`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:168:31\n   |\nLL |     require_impl_as_ref_slice(array_ref.to_owned());\n   |                               ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:170:31\n   |\nLL |     require_impl_as_ref_slice(slice.to_owned());\n   |                               ^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:173:30\n   |\nLL |     require_as_ref_str_slice(s.to_owned(), array.to_owned());\n   |                              ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:173:44\n   |\nLL |     require_as_ref_str_slice(s.to_owned(), array.to_owned());\n   |                                            ^^^^^^^^^^^^^^^^ help: use: `array`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:176:30\n   |\nLL |     require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());\n   |                              ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:176:44\n   |\nLL |     require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());\n   |                                            ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:179:30\n   |\nLL |     require_as_ref_str_slice(s.to_owned(), slice.to_owned());\n   |                              ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:179:44\n   |\nLL |     require_as_ref_str_slice(s.to_owned(), slice.to_owned());\n   |                                            ^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:182:30\n   |\nLL |     require_as_ref_slice_str(array.to_owned(), s.to_owned());\n   |                              ^^^^^^^^^^^^^^^^ help: use: `array`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:182:48\n   |\nLL |     require_as_ref_slice_str(array.to_owned(), s.to_owned());\n   |                                                ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:185:30\n   |\nLL |     require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());\n   |                              ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:185:52\n   |\nLL |     require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());\n   |                                                    ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:188:30\n   |\nLL |     require_as_ref_slice_str(slice.to_owned(), s.to_owned());\n   |                              ^^^^^^^^^^^^^^^^ help: use: `slice`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:188:48\n   |\nLL |     require_as_ref_slice_str(slice.to_owned(), s.to_owned());\n   |                                                ^^^^^^^^^^^^ help: use: `s`\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned.rs:192:20\n   |\nLL |     let _ = x.join(&x_ref.to_string());\n   |                    ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned.rs:195:13\n   |\nLL |     let _ = slice.to_vec().into_iter();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:197:13\n   |\nLL |     let _ = slice.to_owned().into_iter();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned.rs:200:13\n   |\nLL |     let _ = IntoIterator::into_iter(slice.to_vec());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:202:13\n   |\nLL |     let _ = IntoIterator::into_iter(slice.to_owned());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`\n\nerror: allocating a new `String` only to create a temporary `&str` from it\n  --> tests/ui/unnecessary_to_owned.rs:230:26\n   |\nLL |     let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect(\"not UTF-8\");\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: convert from `&[u8]` to `&str` directly\n   |\nLL -     let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect(\"not UTF-8\");\nLL +     let _ref_str: &str = core::str::from_utf8(&slice).expect(\"not UTF-8\");\n   |\n\nerror: allocating a new `String` only to create a temporary `&str` from it\n  --> tests/ui/unnecessary_to_owned.rs:232:26\n   |\nLL |     let _ref_str: &str = &String::from_utf8(b\"foo\".to_vec()).unwrap();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: convert from `&[u8]` to `&str` directly\n   |\nLL -     let _ref_str: &str = &String::from_utf8(b\"foo\".to_vec()).unwrap();\nLL +     let _ref_str: &str = core::str::from_utf8(b\"foo\").unwrap();\n   |\n\nerror: allocating a new `String` only to create a temporary `&str` from it\n  --> tests/ui/unnecessary_to_owned.rs:234:26\n   |\nLL |     let _ref_str: &str = &String::from_utf8(b\"foo\".as_slice().to_owned()).unwrap();\n   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: convert from `&[u8]` to `&str` directly\n   |\nLL -     let _ref_str: &str = &String::from_utf8(b\"foo\".as_slice().to_owned()).unwrap();\nLL +     let _ref_str: &str = core::str::from_utf8(b\"foo\".as_slice()).unwrap();\n   |\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned.rs:292:14\n   |\nLL |     for t in file_types.to_vec() {\n   |              ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove any references to the binding\n   |\nLL ~     for t in file_types {\nLL |\nLL ~         let path = match get_file_path(t) {\n   |\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned.rs:358:24\n   |\nLL |         Box::new(build(y.to_string()))\n   |                        ^^^^^^^^^^^^^ help: use: `y`\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned.rs:468:12\n   |\nLL |         id(\"abc\".to_string())\n   |            ^^^^^^^^^^^^^^^^^ help: use: `\"abc\"`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned.rs:612:37\n   |\nLL |         IntoFuture::into_future(foo([].to_vec(), &0));\n   |                                     ^^^^^^^^^^^ help: use: `[]`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned.rs:623:18\n   |\nLL |         s.remove(&a.to_vec());\n   |                  ^^^^^^^^^^^ help: replace it with: `a`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned.rs:628:14\n   |\nLL |     s.remove(&\"b\".to_owned());\n   |              ^^^^^^^^^^^^^^^ help: replace it with: `\"b\"`\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned.rs:630:14\n   |\nLL |     s.remove(&\"b\".to_string());\n   |              ^^^^^^^^^^^^^^^^ help: replace it with: `\"b\"`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned.rs:636:14\n   |\nLL |     s.remove(&[\"b\"].to_vec());\n   |              ^^^^^^^^^^^^^^^ help: replace it with: `[\"b\"].as_slice()`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned.rs:638:14\n   |\nLL |     s.remove(&(&[\"b\"]).to_vec());\n   |              ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&[\"b\"]).as_slice()`\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned.rs:690:10\n   |\nLL |     take(format!(\"ouch{dot}\").to_string());\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `&format!(\"ouch{dot}\")`\n\nerror: aborting due to 83 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_to_owned_on_split.fixed",
    "content": "#![allow(clippy::single_char_pattern)]\n\nstruct Issue12068;\n\nimpl AsRef<str> for Issue12068 {\n    fn as_ref(&self) -> &str {\n        \"\"\n    }\n}\n\n#[allow(clippy::to_string_trait_impl)]\nimpl ToString for Issue12068 {\n    fn to_string(&self) -> String {\n        String::new()\n    }\n}\n\nfn main() {\n    let _ = \"a\".split('a').next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = \"a\".split(\"a\").next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = \"a\".split('a').next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = \"a\".split(\"a\").next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = Issue12068.as_ref().split('a').next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = [1].split(|x| *x == 2).next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = [1].split(|x| *x == 2).next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = [1].split(|x| *x == 2).next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = [1].split(|x| *x == 2).next().unwrap();\n    //~^ unnecessary_to_owned\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_to_owned_on_split.rs",
    "content": "#![allow(clippy::single_char_pattern)]\n\nstruct Issue12068;\n\nimpl AsRef<str> for Issue12068 {\n    fn as_ref(&self) -> &str {\n        \"\"\n    }\n}\n\n#[allow(clippy::to_string_trait_impl)]\nimpl ToString for Issue12068 {\n    fn to_string(&self) -> String {\n        String::new()\n    }\n}\n\nfn main() {\n    let _ = \"a\".to_string().split('a').next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = \"a\".to_string().split(\"a\").next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = \"a\".to_owned().split('a').next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = \"a\".to_owned().split(\"a\").next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = Issue12068.to_string().split('a').next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = [1].to_vec().split(|x| *x == 2).next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = [1].to_vec().split(|x| *x == 2).next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = [1].to_owned().split(|x| *x == 2).next().unwrap();\n    //~^ unnecessary_to_owned\n\n    let _ = [1].to_owned().split(|x| *x == 2).next().unwrap();\n    //~^ unnecessary_to_owned\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_to_owned_on_split.stderr",
    "content": "error: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:19:13\n   |\nLL |     let _ = \"a\".to_string().split('a').next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `\"a\".split('a')`\n   |\n   = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:22:13\n   |\nLL |     let _ = \"a\".to_string().split(\"a\").next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `\"a\".split(\"a\")`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:25:13\n   |\nLL |     let _ = \"a\".to_owned().split('a').next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `\"a\".split('a')`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:28:13\n   |\nLL |     let _ = \"a\".to_owned().split(\"a\").next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `\"a\".split(\"a\")`\n\nerror: unnecessary use of `to_string`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:31:13\n   |\nLL |     let _ = Issue12068.to_string().split('a').next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Issue12068.as_ref().split('a')`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:34:13\n   |\nLL |     let _ = [1].to_vec().split(|x| *x == 2).next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)`\n\nerror: unnecessary use of `to_vec`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:37:13\n   |\nLL |     let _ = [1].to_vec().split(|x| *x == 2).next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:40:13\n   |\nLL |     let _ = [1].to_owned().split(|x| *x == 2).next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)`\n\nerror: unnecessary use of `to_owned`\n  --> tests/ui/unnecessary_to_owned_on_split.rs:43:13\n   |\nLL |     let _ = [1].to_owned().split(|x| *x == 2).next().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_trailing_comma.fixed",
    "content": "// run-rustfix\n#![warn(clippy::unnecessary_trailing_comma)]\n\nfn main() {}\n\n// fmt breaks - https://github.com/rust-lang/rustfmt/issues/6797\n#[rustfmt::skip]\nfn simple() {\n    println![\"Foo(,)\"];\n    println!(\"Foo\"); //~ unnecessary_trailing_comma\n    println!{\"Foo\"}; //~ unnecessary_trailing_comma\n    println![\"Foo\"]; //~ unnecessary_trailing_comma\n    println!(\"Foo={}\",   1); //~ unnecessary_trailing_comma\n    println!(concat!(\"b\", \"o\", \"o\")); //~ unnecessary_trailing_comma\n    println!(\"Foo(,)\"); //~ unnecessary_trailing_comma\n    println!(\"Foo[,]\"); //~ unnecessary_trailing_comma\n    println![\"Foo(,)\"]; //~ unnecessary_trailing_comma\n    println![\"Foo[,]\"]; //~ unnecessary_trailing_comma\n    println![\"Foo{{,}}\"]; //~ unnecessary_trailing_comma\n    println!{\"Foo{{,}}\"}; //~ unnecessary_trailing_comma\n    println!{\"Foo(,)\"}; //~ unnecessary_trailing_comma\n    println!{\"Foo[,]\"}; //~ unnecessary_trailing_comma\n    println![\"Foo(,\"]; //~ unnecessary_trailing_comma\n    println![\"Foo[,\"]; //~ unnecessary_trailing_comma\n    println![\"Foo{{,}}\"]; //~ unnecessary_trailing_comma\n    println!{\"Foo{{,}}\"}; //~ unnecessary_trailing_comma\n    println!{\"Foo(,\"}; //~ unnecessary_trailing_comma\n    println!{\"Foo[,\"}; //~ unnecessary_trailing_comma\n\n    // This should eventually work, but requires more work\n    println!(concat!(\"Foo\", \"=\", \"{}\"), 1,);\n    println!(\"No params\", /*\"a,){ */);\n    println!(\"No params\" /* \"a,){*/, /*\"a,){ */);\n\n    // No trailing comma - no lint\n    println!(\"{}\", 1);\n    println!(concat!(\"b\", \"o\", \"o\"));\n    println!(concat!(\"Foo\", \"=\", \"{}\"), 1);\n\n    println!(\"Foo\" );\n    println!{\"Foo\" };\n    println![\"Foo\" ];\n    println!(\"Foo={}\", 1);\n    println!(concat!(\"b\", \"o\", \"o\"));\n    println!(\"Foo(,)\");\n    println!(\"Foo[,]\");\n    println![\"Foo(,)\"];\n    println![\"Foo[,]\"];\n    println![\"Foo{{,}}\"];\n    println!{\"Foo{{,}}\"};\n    println!{\"Foo(,)\"};\n    println!{\"Foo[,]\"};\n    println![\"Foo(,\"];\n    println![\"Foo[,\"];\n    println![\"Foo{{,}}\"];\n    println!{\"Foo{{,}}\"};\n    println!{\"Foo(,\"};\n    println!{\"Foo[,\"};\n\n    // Multi-line macro - must NOT lint (single-line only)\n    println!(\n        \"very long string to prevent fmt from making it into a single line: {}\",\n        1,\n    );\n\n    print!(\"{}\"\n        , 1\n        ,);\n}\n\n// The macro invocation itself should never be fixed\n// The call to println! on the other hand might be ok to suggest in the future\n\nmacro_rules! from_macro {\n    (0,) => {\n        println!(\"Foo\",);\n    };\n    (1,) => {\n        println!(\"Foo={}\", 1,);\n    };\n}\n\nfn from_macro() {\n    from_macro!(0,);\n    from_macro!(1,);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_trailing_comma.rs",
    "content": "// run-rustfix\n#![warn(clippy::unnecessary_trailing_comma)]\n\nfn main() {}\n\n// fmt breaks - https://github.com/rust-lang/rustfmt/issues/6797\n#[rustfmt::skip]\nfn simple() {\n    println![\"Foo(,)\"];\n    println!(\"Foo\" , ); //~ unnecessary_trailing_comma\n    println!{\"Foo\" , }; //~ unnecessary_trailing_comma\n    println![\"Foo\" , ]; //~ unnecessary_trailing_comma\n    println!(\"Foo={}\",   1  ,  ); //~ unnecessary_trailing_comma\n    println!(concat!(\"b\", \"o\", \"o\")  , ); //~ unnecessary_trailing_comma\n    println!(\"Foo(,)\",); //~ unnecessary_trailing_comma\n    println!(\"Foo[,]\" , ); //~ unnecessary_trailing_comma\n    println![\"Foo(,)\", ]; //~ unnecessary_trailing_comma\n    println![\"Foo[,]\", ]; //~ unnecessary_trailing_comma\n    println![\"Foo{{,}}\", ]; //~ unnecessary_trailing_comma\n    println!{\"Foo{{,}}\", }; //~ unnecessary_trailing_comma\n    println!{\"Foo(,)\", }; //~ unnecessary_trailing_comma\n    println!{\"Foo[,]\", }; //~ unnecessary_trailing_comma\n    println![\"Foo(,\", ]; //~ unnecessary_trailing_comma\n    println![\"Foo[,\", ]; //~ unnecessary_trailing_comma\n    println![\"Foo{{,}}\", ]; //~ unnecessary_trailing_comma\n    println!{\"Foo{{,}}\", }; //~ unnecessary_trailing_comma\n    println!{\"Foo(,\", }; //~ unnecessary_trailing_comma\n    println!{\"Foo[,\", }; //~ unnecessary_trailing_comma\n\n    // This should eventually work, but requires more work\n    println!(concat!(\"Foo\", \"=\", \"{}\"), 1,);\n    println!(\"No params\", /*\"a,){ */);\n    println!(\"No params\" /* \"a,){*/, /*\"a,){ */);\n\n    // No trailing comma - no lint\n    println!(\"{}\", 1);\n    println!(concat!(\"b\", \"o\", \"o\"));\n    println!(concat!(\"Foo\", \"=\", \"{}\"), 1);\n\n    println!(\"Foo\" );\n    println!{\"Foo\" };\n    println![\"Foo\" ];\n    println!(\"Foo={}\", 1);\n    println!(concat!(\"b\", \"o\", \"o\"));\n    println!(\"Foo(,)\");\n    println!(\"Foo[,]\");\n    println![\"Foo(,)\"];\n    println![\"Foo[,]\"];\n    println![\"Foo{{,}}\"];\n    println!{\"Foo{{,}}\"};\n    println!{\"Foo(,)\"};\n    println!{\"Foo[,]\"};\n    println![\"Foo(,\"];\n    println![\"Foo[,\"];\n    println![\"Foo{{,}}\"];\n    println!{\"Foo{{,}}\"};\n    println!{\"Foo(,\"};\n    println!{\"Foo[,\"};\n\n    // Multi-line macro - must NOT lint (single-line only)\n    println!(\n        \"very long string to prevent fmt from making it into a single line: {}\",\n        1,\n    );\n\n    print!(\"{}\"\n        , 1\n        ,);\n}\n\n// The macro invocation itself should never be fixed\n// The call to println! on the other hand might be ok to suggest in the future\n\nmacro_rules! from_macro {\n    (0,) => {\n        println!(\"Foo\",);\n    };\n    (1,) => {\n        println!(\"Foo={}\", 1,);\n    };\n}\n\nfn from_macro() {\n    from_macro!(0,);\n    from_macro!(1,);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_trailing_comma.stderr",
    "content": "error: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:10:19\n   |\nLL |     println!(\"Foo\" , );\n   |                   ^^^ help: remove the trailing comma\n   |\n   = note: `-D clippy::unnecessary-trailing-comma` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_trailing_comma)]`\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:11:19\n   |\nLL |     println!{\"Foo\" , };\n   |                   ^^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:12:19\n   |\nLL |     println![\"Foo\" , ];\n   |                   ^^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:13:27\n   |\nLL |     println!(\"Foo={}\",   1  ,  );\n   |                           ^^^^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:14:36\n   |\nLL |     println!(concat!(\"b\", \"o\", \"o\")  , );\n   |                                    ^^^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:15:22\n   |\nLL |     println!(\"Foo(,)\",);\n   |                      ^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:16:22\n   |\nLL |     println!(\"Foo[,]\" , );\n   |                      ^^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:17:22\n   |\nLL |     println![\"Foo(,)\", ];\n   |                      ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:18:22\n   |\nLL |     println![\"Foo[,]\", ];\n   |                      ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:19:24\n   |\nLL |     println![\"Foo{{,}}\", ];\n   |                        ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:20:24\n   |\nLL |     println!{\"Foo{{,}}\", };\n   |                        ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:21:22\n   |\nLL |     println!{\"Foo(,)\", };\n   |                      ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:22:22\n   |\nLL |     println!{\"Foo[,]\", };\n   |                      ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:23:21\n   |\nLL |     println![\"Foo(,\", ];\n   |                     ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:24:21\n   |\nLL |     println![\"Foo[,\", ];\n   |                     ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:25:24\n   |\nLL |     println![\"Foo{{,}}\", ];\n   |                        ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:26:24\n   |\nLL |     println!{\"Foo{{,}}\", };\n   |                        ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:27:21\n   |\nLL |     println!{\"Foo(,\", };\n   |                     ^^ help: remove the trailing comma\n\nerror: unnecessary trailing comma\n  --> tests/ui/unnecessary_trailing_comma.rs:28:21\n   |\nLL |     println!{\"Foo[,\", };\n   |                     ^^ help: remove the trailing comma\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_unsafety_doc.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![allow(clippy::let_unit_value, clippy::needless_pass_by_ref_mut)]\n#![warn(clippy::unnecessary_safety_doc)]\n\nextern crate proc_macros;\nuse proc_macros::external;\n\n/// This is has no safety section, and does not need one either\npub fn destroy_the_planet() {\n    unimplemented!();\n}\n\n/// This one does not need a `Safety` section\n///\n/// # Safety\n///\n/// This function shouldn't be called unless the horsemen are ready\npub fn apocalypse(universe: &mut ()) {\n    //~^ unnecessary_safety_doc\n    unimplemented!();\n}\n\n/// This is a private function, skip to match behavior with `missing_safety_doc`.\n///\n/// # Safety\n///\n/// Boo!\nfn you_dont_see_me() {\n    unimplemented!();\n}\n\nmod private_mod {\n    /// This is public but unexported function, skip to match behavior with `missing_safety_doc`.\n    ///\n    /// # Safety\n    ///\n    /// Very safe!\n    pub fn only_crate_wide_accessible() {\n        unimplemented!();\n    }\n\n    /// # Safety\n    ///\n    /// Unnecessary safety!\n    pub fn republished() {\n        //~^ unnecessary_safety_doc\n        unimplemented!();\n    }\n}\n\npub use private_mod::republished;\n\npub trait SafeTraitSafeMethods {\n    fn woefully_underdocumented(self);\n\n    /// # Safety\n    ///\n    /// Unnecessary!\n    fn documented(self);\n    //~^ unnecessary_safety_doc\n}\n\npub trait SafeTrait {\n    fn method();\n}\n\n/// # Safety\n///\n/// Unnecessary!\npub trait DocumentedSafeTrait {\n    //~^ unnecessary_safety_doc\n    fn method2();\n}\n\npub struct Struct;\n\nimpl SafeTraitSafeMethods for Struct {\n    fn woefully_underdocumented(self) {\n        // all is well\n    }\n\n    fn documented(self) {\n        // all is still well\n    }\n}\n\nimpl SafeTrait for Struct {\n    fn method() {}\n}\n\nimpl DocumentedSafeTrait for Struct {\n    fn method2() {}\n}\n\nimpl Struct {\n    /// # Safety\n    ///\n    /// Unnecessary!\n    pub fn documented() -> Self {\n        //~^ unnecessary_safety_doc\n        unimplemented!();\n    }\n\n    pub fn undocumented(&self) {\n        unimplemented!();\n    }\n\n    /// Private, fine again to stay consistent with `missing_safety_doc`.\n    ///\n    /// # Safety\n    ///\n    /// Unnecessary!\n    fn private(&self) {\n        unimplemented!();\n    }\n}\n\nmacro_rules! very_safe {\n    () => {\n        pub fn whee() {\n            unimplemented!()\n        }\n\n        /// # Safety\n        ///\n        /// Driving is very safe already!\n        pub fn drive() {\n            //~^ unnecessary_safety_doc\n            whee()\n        }\n    };\n}\n\nvery_safe!();\n\n// we don't lint code from external macros\nexternal!(\n    pub fn vey_oy() {\n        unimplemented!();\n    }\n);\n\nfn main() {}\n\n// do not lint if any parent has `#[doc(hidden)]` attribute\n// see #7347\n#[doc(hidden)]\npub mod __macro {\n    pub struct T;\n    impl T {\n        pub unsafe fn f() {}\n    }\n}\n\n/// # Implementation safety\npub trait DocumentedSafeTraitWithImplementationHeader {\n    //~^ unnecessary_safety_doc\n    fn method();\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_unsafety_doc.stderr",
    "content": "error: safe function's docs have unnecessary `# Safety` section\n  --> tests/ui/unnecessary_unsafety_doc.rs:19:1\n   |\nLL | pub fn apocalypse(universe: &mut ()) {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-safety-doc` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_doc)]`\n\nerror: safe function's docs have unnecessary `# Safety` section\n  --> tests/ui/unnecessary_unsafety_doc.rs:46:5\n   |\nLL |     pub fn republished() {\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nerror: safe function's docs have unnecessary `# Safety` section\n  --> tests/ui/unnecessary_unsafety_doc.rs:60:5\n   |\nLL |     fn documented(self);\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for safe trait have unnecessary `# Safety` section\n  --> tests/ui/unnecessary_unsafety_doc.rs:71:1\n   |\nLL | pub trait DocumentedSafeTrait {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: safe function's docs have unnecessary `# Safety` section\n  --> tests/ui/unnecessary_unsafety_doc.rs:100:5\n   |\nLL |     pub fn documented() -> Self {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: safe function's docs have unnecessary `# Safety` section\n  --> tests/ui/unnecessary_unsafety_doc.rs:128:9\n   |\nLL |         pub fn drive() {\n   |         ^^^^^^^^^^^^^^\n...\nLL | very_safe!();\n   | ------------ in this macro invocation\n   |\n   = note: this error originates in the macro `very_safe` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: docs for safe trait have unnecessary `# Safety` section\n  --> tests/ui/unnecessary_unsafety_doc.rs:157:1\n   |\nLL | pub trait DocumentedSafeTraitWithImplementationHeader {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnecessary_wraps.rs",
    "content": "//@no-rustfix: overlapping suggestions\n#![warn(clippy::unnecessary_wraps)]\n#![allow(clippy::no_effect)]\n#![allow(clippy::needless_return)]\n#![allow(clippy::if_same_then_else)]\n#![allow(dead_code)]\n\n// should be linted\nfn func1(a: bool, b: bool) -> Option<i32> {\n    //~^ unnecessary_wraps\n\n    if a && b {\n        return Some(42);\n    }\n    if a {\n        Some(-1);\n        Some(2)\n    } else {\n        return Some(1337);\n    }\n}\n\n// should be linted\nfn func2(a: bool, b: bool) -> Option<i32> {\n    //~^ unnecessary_wraps\n\n    if a && b {\n        return Some(10);\n    }\n    if a { Some(20) } else { Some(30) }\n}\n\n// public fns should not be linted\npub fn func3(a: bool) -> Option<i32> {\n    if a { Some(1) } else { Some(1) }\n}\n\n// should not be linted\nfn func4(a: bool) -> Option<i32> {\n    if a { Some(1) } else { None }\n}\n\n// should be linted\nfn func5() -> Option<i32> {\n    //~^ unnecessary_wraps\n\n    Some(1)\n}\n\n// should not be linted\nfn func6() -> Option<i32> {\n    None\n}\n\n// should be linted\nfn func7() -> Result<i32, ()> {\n    //~^ unnecessary_wraps\n\n    Ok(1)\n}\n\n// should not be linted\nfn func8(a: bool) -> Result<i32, ()> {\n    if a { Ok(1) } else { Err(()) }\n}\n\n// should not be linted\nfn func9(a: bool) -> Result<i32, ()> {\n    Err(())\n}\n\n// should not be linted\nfn func10() -> Option<()> {\n    unimplemented!()\n}\n\npub struct A;\n\nimpl A {\n    // should not be linted\n    pub fn func11() -> Option<i32> {\n        Some(1)\n    }\n\n    // should be linted\n    fn func12() -> Option<i32> {\n        //~^ unnecessary_wraps\n\n        Some(1)\n    }\n}\n\ntrait B {\n    // trait impls are not linted\n    fn func13() -> Option<i32> {\n        Some(1)\n    }\n}\n\nimpl B for A {\n    // trait impls are not linted\n    fn func13() -> Option<i32> {\n        Some(0)\n    }\n}\n\nfn issue_6384(s: &str) -> Option<&str> {\n    Some(match s {\n        \"a\" => \"A\",\n        _ => return None,\n    })\n}\n\n// should be linted\nfn issue_6640_1(a: bool, b: bool) -> Option<()> {\n    //~^ unnecessary_wraps\n\n    if a && b {\n        return Some(());\n    }\n    if a {\n        Some(());\n        Some(())\n    } else {\n        return Some(());\n    }\n}\n\n// should be linted\nfn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {\n    //~^ unnecessary_wraps\n\n    if a && b {\n        return Ok(());\n    }\n    if a {\n        Ok(())\n    } else {\n        return Ok(());\n    }\n}\n\n// should not be linted\nfn issue_6640_3() -> Option<()> {\n    if true { Some(()) } else { None }\n}\n\n// should not be linted\nfn issue_6640_4() -> Result<(), ()> {\n    if true { Ok(()) } else { Err(()) }\n}\n\nfn main() {\n    // method calls are not linted\n    func1(true, true);\n    func2(true, true);\n    issue_6640_1(true, true);\n    issue_6640_2(true, true);\n}\n"
  },
  {
    "path": "tests/ui/unnecessary_wraps.stderr",
    "content": "error: this function's return value is unnecessarily wrapped by `Option`\n  --> tests/ui/unnecessary_wraps.rs:9:1\n   |\nLL | fn func1(a: bool, b: bool) -> Option<i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-wraps` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_wraps)]`\nhelp: remove `Option` from the return type...\n   |\nLL - fn func1(a: bool, b: bool) -> Option<i32> {\nLL + fn func1(a: bool, b: bool) -> i32 {\n   |\nhelp: ...and then remove the surrounding `Some()` from returning expressions\n   |\nLL ~         return 42;\nLL |     }\nLL |     if a {\nLL |         Some(-1);\nLL ~         2\nLL |     } else {\nLL ~         return 1337;\n   |\n\nerror: this function's return value is unnecessarily wrapped by `Option`\n  --> tests/ui/unnecessary_wraps.rs:24:1\n   |\nLL | fn func2(a: bool, b: bool) -> Option<i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `Option` from the return type...\n   |\nLL - fn func2(a: bool, b: bool) -> Option<i32> {\nLL + fn func2(a: bool, b: bool) -> i32 {\n   |\nhelp: ...and then remove the surrounding `Some()` from returning expressions\n   |\nLL ~         return 10;\nLL |     }\nLL ~     if a { 20 } else { 30 }\n   |\n\nerror: this function's return value is unnecessarily wrapped by `Option`\n  --> tests/ui/unnecessary_wraps.rs:44:1\n   |\nLL | fn func5() -> Option<i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `Option` from the return type...\n   |\nLL - fn func5() -> Option<i32> {\nLL + fn func5() -> i32 {\n   |\nhelp: ...and then remove the surrounding `Some()` from returning expressions\n   |\nLL -     Some(1)\nLL +     1\n   |\n\nerror: this function's return value is unnecessarily wrapped by `Result`\n  --> tests/ui/unnecessary_wraps.rs:56:1\n   |\nLL | fn func7() -> Result<i32, ()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `Result` from the return type...\n   |\nLL - fn func7() -> Result<i32, ()> {\nLL + fn func7() -> i32 {\n   |\nhelp: ...and then remove the surrounding `Ok()` from returning expressions\n   |\nLL -     Ok(1)\nLL +     1\n   |\n\nerror: this function's return value is unnecessarily wrapped by `Option`\n  --> tests/ui/unnecessary_wraps.rs:86:5\n   |\nLL |     fn func12() -> Option<i32> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove `Option` from the return type...\n   |\nLL -     fn func12() -> Option<i32> {\nLL +     fn func12() -> i32 {\n   |\nhelp: ...and then remove the surrounding `Some()` from returning expressions\n   |\nLL -         Some(1)\nLL +         1\n   |\n\nerror: this function's return value is unnecessary\n  --> tests/ui/unnecessary_wraps.rs:115:1\n   |\nLL | fn issue_6640_1(a: bool, b: bool) -> Option<()> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the return type...\n   |\nLL - fn issue_6640_1(a: bool, b: bool) -> Option<()> {\nLL + fn issue_6640_1(a: bool, b: bool) -> () {\n   |\nhelp: ...and then remove returned values\n   |\nLL ~         return ;\nLL |     }\nLL |     if a {\nLL |         Some(());\nLL ~         \nLL |     } else {\nLL ~         return ;\n   |\n\nerror: this function's return value is unnecessary\n  --> tests/ui/unnecessary_wraps.rs:130:1\n   |\nLL | fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the return type...\n   |\nLL - fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {\nLL + fn issue_6640_2(a: bool, b: bool) -> () {\n   |\nhelp: ...and then remove returned values\n   |\nLL ~         return ;\nLL |     }\nLL |     if a {\nLL ~         \nLL |     } else {\nLL ~         return ;\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui/unneeded_field_pattern.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::unneeded_field_pattern)]\n#![allow(dead_code, unused, clippy::single_match)]\n\n#[macro_use]\nextern crate proc_macros;\n\nstruct Foo {\n    a: i32,\n    b: i32,\n    c: i32,\n}\n\nfn main() {\n    let f = Foo { a: 0, b: 0, c: 0 };\n\n    match f {\n        Foo { a: _, b: 0, .. } => {},\n        //~^ unneeded_field_pattern\n        Foo { a: _, b: _, c: _ } => {},\n        //~^ unneeded_field_pattern\n    }\n    match f {\n        Foo { b: 0, .. } => {}, // should be OK\n        Foo { .. } => {},       // and the Force might be with this one\n    }\n    external! {\n        let f = Foo { a: 0, b: 0, c: 0 };\n        match f {\n            Foo { a: _, b: 0, .. } => {},\n\n            Foo { a: _, b: _, c: _ } => {},\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/unneeded_field_pattern.stderr",
    "content": "error: you matched a field with a wildcard pattern, consider using `..` instead\n  --> tests/ui/unneeded_field_pattern.rs:18:15\n   |\nLL |         Foo { a: _, b: 0, .. } => {},\n   |               ^^^^\n   |\n   = help: try with `Foo { b: 0, .. }`\n   = note: `-D clippy::unneeded-field-pattern` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unneeded_field_pattern)]`\n\nerror: all the struct fields are matched to a wildcard pattern, consider using `..`\n  --> tests/ui/unneeded_field_pattern.rs:20:9\n   |\nLL |         Foo { a: _, b: _, c: _ } => {},\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try with `Foo { .. }` instead\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/unneeded_struct_pattern.fixed",
    "content": "//@aux-build:non-exhaustive-enum.rs\n#![allow(\n    clippy::manual_unwrap_or_default,\n    clippy::manual_unwrap_or,\n    clippy::redundant_pattern_matching\n)]\n#![warn(clippy::unneeded_struct_pattern)]\n\nextern crate non_exhaustive_enum;\nuse non_exhaustive_enum::*;\n\nfn noop() {}\n\nfn main() {\n    match Some(114514) {\n        Some(v) => v,\n        None => 0,\n        //~^ unneeded_struct_pattern\n    };\n\n    match Some(1919810) {\n        Some(v) => v,\n        None => 0,\n        //~^ unneeded_struct_pattern\n    };\n\n    match Some(123456) {\n        Some(v) => v,\n        None => 0,\n    };\n\n    match Some(Some(123456)) {\n        Some(Some(v)) => v,\n        Some(None) => 0,\n        //~^ unneeded_struct_pattern\n        None => 0,\n        //~^ unneeded_struct_pattern\n    };\n\n    if let None = Some(0) {}\n    //~^ unneeded_struct_pattern\n    if let None = Some(0) {}\n    //~^ unneeded_struct_pattern\n    if let Some(None) = Some(Some(0)) {}\n    //~^ unneeded_struct_pattern\n    let None = Some(0) else { panic!() };\n    //~^ unneeded_struct_pattern\n    let None = Some(0) else { panic!() };\n    //~^ unneeded_struct_pattern\n    let Some(None) = Some(Some(0)) else { panic!() };\n    //~^ unneeded_struct_pattern\n\n    enum Custom {\n        HasFields {\n            field: i32,\n        },\n        HasBracketsNoFields {},\n        NoBrackets,\n        #[non_exhaustive]\n        NoBracketsNonExhaustive,\n        Init,\n    };\n\n    match Custom::Init {\n        Custom::HasFields { field: value } => value,\n        Custom::HasBracketsNoFields {} => 0,\n        Custom::NoBrackets => 0,              //~ unneeded_struct_pattern\n        Custom::NoBracketsNonExhaustive => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match Custom::Init {\n        Custom::HasFields { field: value } => value,\n        Custom::HasBracketsNoFields { .. } => 0,\n        Custom::NoBrackets => 0,              //~ unneeded_struct_pattern\n        Custom::NoBracketsNonExhaustive => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match Custom::Init {\n        Custom::NoBrackets if true => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match Custom::Init {\n        Custom::NoBrackets | Custom::NoBracketsNonExhaustive => 0,\n        //~^ unneeded_struct_pattern\n        //~| unneeded_struct_pattern\n        _ => 0,\n    };\n\n    if let Custom::HasFields { field: value } = Custom::Init {\n        noop();\n    }\n    if let Custom::HasBracketsNoFields {} = Custom::Init {\n        noop();\n    }\n    if let Custom::HasBracketsNoFields { .. } = Custom::Init {\n        noop();\n    }\n    if let Custom::NoBrackets = Custom::Init {\n        //~^ unneeded_struct_pattern\n        noop();\n    }\n    if let Custom::NoBrackets = Custom::Init {\n        //~^ unneeded_struct_pattern\n        noop();\n    }\n    if let Custom::NoBrackets | Custom::NoBracketsNonExhaustive = Custom::Init {\n        //~^ unneeded_struct_pattern\n        //~| unneeded_struct_pattern\n        noop();\n    }\n    if let Custom::NoBracketsNonExhaustive = Custom::Init {\n        //~^ unneeded_struct_pattern\n        noop();\n    }\n    if let Custom::NoBracketsNonExhaustive = Custom::Init {\n        //~^ unneeded_struct_pattern\n        noop();\n    }\n\n    let Custom::HasFields { field: value } = Custom::Init else {\n        panic!()\n    };\n\n    let Custom::HasBracketsNoFields {} = Custom::Init else {\n        panic!()\n    };\n\n    let Custom::HasBracketsNoFields { .. } = Custom::Init else {\n        panic!()\n    };\n    let Custom::NoBrackets = Custom::Init else { panic!() }; //~ unneeded_struct_pattern\n\n    let Custom::NoBrackets = Custom::Init else {\n        //~^ unneeded_struct_pattern\n        panic!()\n    };\n    let Custom::NoBracketsNonExhaustive = Custom::Init else {\n        //~^ unneeded_struct_pattern\n        panic!()\n    };\n    let Custom::NoBracketsNonExhaustive = Custom::Init else {\n        //~^ unneeded_struct_pattern\n        panic!()\n    };\n\n    enum Refutable {\n        Variant,\n    }\n\n    fn pat_in_fn_param_1(Refutable::Variant: Refutable) {} //~ unneeded_struct_pattern\n    fn pat_in_fn_param_2(Refutable::Variant: Refutable) {} //~ unneeded_struct_pattern\n\n    for Refutable::Variant in [] {} //~ unneeded_struct_pattern\n    for Refutable::Variant in [] {} //~ unneeded_struct_pattern\n}\n\nfn external_crate() {\n    use ExtNonExhaustiveVariant::*;\n\n    match ExhaustiveUnit {\n        // Expected\n        ExhaustiveUnit => 0,\n        _ => 0,\n    };\n\n    match ExhaustiveUnit {\n        // Exhaustive variant\n        ExhaustiveUnit => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match ExhaustiveUnit {\n        // Exhaustive variant\n        ExhaustiveUnit => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match ExhaustiveUnit {\n        ExhaustiveUnit => 0,\n        // vvvvv Non-exhaustive variants, should all be ignored\n        Unit { .. } => 0,\n        Tuple { 0: field, .. } => field,\n        StructNoField { .. } => 0,\n        Struct { field, .. } => field,\n        _ => 0,\n    };\n}\n"
  },
  {
    "path": "tests/ui/unneeded_struct_pattern.rs",
    "content": "//@aux-build:non-exhaustive-enum.rs\n#![allow(\n    clippy::manual_unwrap_or_default,\n    clippy::manual_unwrap_or,\n    clippy::redundant_pattern_matching\n)]\n#![warn(clippy::unneeded_struct_pattern)]\n\nextern crate non_exhaustive_enum;\nuse non_exhaustive_enum::*;\n\nfn noop() {}\n\nfn main() {\n    match Some(114514) {\n        Some(v) => v,\n        None {} => 0,\n        //~^ unneeded_struct_pattern\n    };\n\n    match Some(1919810) {\n        Some(v) => v,\n        None { .. } => 0,\n        //~^ unneeded_struct_pattern\n    };\n\n    match Some(123456) {\n        Some(v) => v,\n        None => 0,\n    };\n\n    match Some(Some(123456)) {\n        Some(Some(v)) => v,\n        Some(None {}) => 0,\n        //~^ unneeded_struct_pattern\n        None {} => 0,\n        //~^ unneeded_struct_pattern\n    };\n\n    if let None {} = Some(0) {}\n    //~^ unneeded_struct_pattern\n    if let None { .. } = Some(0) {}\n    //~^ unneeded_struct_pattern\n    if let Some(None {}) = Some(Some(0)) {}\n    //~^ unneeded_struct_pattern\n    let None {} = Some(0) else { panic!() };\n    //~^ unneeded_struct_pattern\n    let None { .. } = Some(0) else { panic!() };\n    //~^ unneeded_struct_pattern\n    let Some(None {}) = Some(Some(0)) else { panic!() };\n    //~^ unneeded_struct_pattern\n\n    enum Custom {\n        HasFields {\n            field: i32,\n        },\n        HasBracketsNoFields {},\n        NoBrackets,\n        #[non_exhaustive]\n        NoBracketsNonExhaustive,\n        Init,\n    };\n\n    match Custom::Init {\n        Custom::HasFields { field: value } => value,\n        Custom::HasBracketsNoFields {} => 0,\n        Custom::NoBrackets {} => 0,              //~ unneeded_struct_pattern\n        Custom::NoBracketsNonExhaustive {} => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match Custom::Init {\n        Custom::HasFields { field: value } => value,\n        Custom::HasBracketsNoFields { .. } => 0,\n        Custom::NoBrackets { .. } => 0,              //~ unneeded_struct_pattern\n        Custom::NoBracketsNonExhaustive { .. } => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match Custom::Init {\n        Custom::NoBrackets {} if true => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match Custom::Init {\n        Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0,\n        //~^ unneeded_struct_pattern\n        //~| unneeded_struct_pattern\n        _ => 0,\n    };\n\n    if let Custom::HasFields { field: value } = Custom::Init {\n        noop();\n    }\n    if let Custom::HasBracketsNoFields {} = Custom::Init {\n        noop();\n    }\n    if let Custom::HasBracketsNoFields { .. } = Custom::Init {\n        noop();\n    }\n    if let Custom::NoBrackets {} = Custom::Init {\n        //~^ unneeded_struct_pattern\n        noop();\n    }\n    if let Custom::NoBrackets { .. } = Custom::Init {\n        //~^ unneeded_struct_pattern\n        noop();\n    }\n    if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init {\n        //~^ unneeded_struct_pattern\n        //~| unneeded_struct_pattern\n        noop();\n    }\n    if let Custom::NoBracketsNonExhaustive {} = Custom::Init {\n        //~^ unneeded_struct_pattern\n        noop();\n    }\n    if let Custom::NoBracketsNonExhaustive { .. } = Custom::Init {\n        //~^ unneeded_struct_pattern\n        noop();\n    }\n\n    let Custom::HasFields { field: value } = Custom::Init else {\n        panic!()\n    };\n\n    let Custom::HasBracketsNoFields {} = Custom::Init else {\n        panic!()\n    };\n\n    let Custom::HasBracketsNoFields { .. } = Custom::Init else {\n        panic!()\n    };\n    let Custom::NoBrackets {} = Custom::Init else { panic!() }; //~ unneeded_struct_pattern\n\n    let Custom::NoBrackets { .. } = Custom::Init else {\n        //~^ unneeded_struct_pattern\n        panic!()\n    };\n    let Custom::NoBracketsNonExhaustive {} = Custom::Init else {\n        //~^ unneeded_struct_pattern\n        panic!()\n    };\n    let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else {\n        //~^ unneeded_struct_pattern\n        panic!()\n    };\n\n    enum Refutable {\n        Variant,\n    }\n\n    fn pat_in_fn_param_1(Refutable::Variant {}: Refutable) {} //~ unneeded_struct_pattern\n    fn pat_in_fn_param_2(Refutable::Variant { .. }: Refutable) {} //~ unneeded_struct_pattern\n\n    for Refutable::Variant {} in [] {} //~ unneeded_struct_pattern\n    for Refutable::Variant { .. } in [] {} //~ unneeded_struct_pattern\n}\n\nfn external_crate() {\n    use ExtNonExhaustiveVariant::*;\n\n    match ExhaustiveUnit {\n        // Expected\n        ExhaustiveUnit => 0,\n        _ => 0,\n    };\n\n    match ExhaustiveUnit {\n        // Exhaustive variant\n        ExhaustiveUnit { .. } => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match ExhaustiveUnit {\n        // Exhaustive variant\n        ExhaustiveUnit {} => 0, //~ unneeded_struct_pattern\n        _ => 0,\n    };\n\n    match ExhaustiveUnit {\n        ExhaustiveUnit => 0,\n        // vvvvv Non-exhaustive variants, should all be ignored\n        Unit { .. } => 0,\n        Tuple { 0: field, .. } => field,\n        StructNoField { .. } => 0,\n        Struct { field, .. } => field,\n        _ => 0,\n    };\n}\n"
  },
  {
    "path": "tests/ui/unneeded_struct_pattern.stderr",
    "content": "error: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:17:13\n   |\nLL |         None {} => 0,\n   |             ^^^ help: remove the struct pattern\n   |\n   = note: `-D clippy::unneeded-struct-pattern` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unneeded_struct_pattern)]`\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:23:13\n   |\nLL |         None { .. } => 0,\n   |             ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:34:18\n   |\nLL |         Some(None {}) => 0,\n   |                  ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:36:13\n   |\nLL |         None {} => 0,\n   |             ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:40:16\n   |\nLL |     if let None {} = Some(0) {}\n   |                ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:42:16\n   |\nLL |     if let None { .. } = Some(0) {}\n   |                ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:44:21\n   |\nLL |     if let Some(None {}) = Some(Some(0)) {}\n   |                     ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:46:13\n   |\nLL |     let None {} = Some(0) else { panic!() };\n   |             ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:48:13\n   |\nLL |     let None { .. } = Some(0) else { panic!() };\n   |             ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:50:18\n   |\nLL |     let Some(None {}) = Some(Some(0)) else { panic!() };\n   |                  ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:67:27\n   |\nLL |         Custom::NoBrackets {} => 0,\n   |                           ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:68:40\n   |\nLL |         Custom::NoBracketsNonExhaustive {} => 0,\n   |                                        ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:75:27\n   |\nLL |         Custom::NoBrackets { .. } => 0,\n   |                           ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:76:40\n   |\nLL |         Custom::NoBracketsNonExhaustive { .. } => 0,\n   |                                        ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:81:27\n   |\nLL |         Custom::NoBrackets {} if true => 0,\n   |                           ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:86:27\n   |\nLL |         Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0,\n   |                           ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:86:64\n   |\nLL |         Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0,\n   |                                                                ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:101:30\n   |\nLL |     if let Custom::NoBrackets {} = Custom::Init {\n   |                              ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:105:30\n   |\nLL |     if let Custom::NoBrackets { .. } = Custom::Init {\n   |                              ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:109:30\n   |\nLL |     if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init {\n   |                              ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:109:67\n   |\nLL |     if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init {\n   |                                                                   ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:114:43\n   |\nLL |     if let Custom::NoBracketsNonExhaustive {} = Custom::Init {\n   |                                           ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:118:43\n   |\nLL |     if let Custom::NoBracketsNonExhaustive { .. } = Custom::Init {\n   |                                           ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:134:27\n   |\nLL |     let Custom::NoBrackets {} = Custom::Init else { panic!() };\n   |                           ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:136:27\n   |\nLL |     let Custom::NoBrackets { .. } = Custom::Init else {\n   |                           ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:140:40\n   |\nLL |     let Custom::NoBracketsNonExhaustive {} = Custom::Init else {\n   |                                        ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:144:40\n   |\nLL |     let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else {\n   |                                        ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:153:44\n   |\nLL |     fn pat_in_fn_param_1(Refutable::Variant {}: Refutable) {}\n   |                                            ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:154:44\n   |\nLL |     fn pat_in_fn_param_2(Refutable::Variant { .. }: Refutable) {}\n   |                                            ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:156:27\n   |\nLL |     for Refutable::Variant {} in [] {}\n   |                           ^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:157:27\n   |\nLL |     for Refutable::Variant { .. } in [] {}\n   |                           ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:171:23\n   |\nLL |         ExhaustiveUnit { .. } => 0,\n   |                       ^^^^^^^ help: remove the struct pattern\n\nerror: struct pattern is not needed for a unit variant\n  --> tests/ui/unneeded_struct_pattern.rs:177:23\n   |\nLL |         ExhaustiveUnit {} => 0,\n   |                       ^^^ help: remove the struct pattern\n\nerror: aborting due to 33 previous errors\n\n"
  },
  {
    "path": "tests/ui/unneeded_wildcard_pattern.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![feature(stmt_expr_attributes)]\n#![deny(clippy::unneeded_wildcard_pattern)]\n#![allow(clippy::needless_ifs)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    let t = (0, 1, 2, 3);\n\n    if let (0, ..) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (0, ..) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (.., 0) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (.., 0) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (0, ..) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (0, ..) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (_, 0, ..) = t {};\n    if let (.., 0, _) = t {};\n    if let (0, _, _, _) = t {};\n    if let (0, ..) = t {};\n    if let (.., 0) = t {};\n\n    #[rustfmt::skip]\n    {\n        if let (0, ..,) = t {};\n        //~^ unneeded_wildcard_pattern\n    }\n\n    struct S(usize, usize, usize, usize);\n\n    let s = S(0, 1, 2, 3);\n\n    if let S(0, ..) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(0, ..) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(.., 0) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(.., 0) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(0, ..) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(0, ..) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(_, 0, ..) = s {};\n    if let S(.., 0, _) = s {};\n    if let S(0, _, _, _) = s {};\n    if let S(0, ..) = s {};\n    if let S(.., 0) = s {};\n\n    #[rustfmt::skip]\n    {\n        if let S(0, ..,) = s {};\n        //~^ unneeded_wildcard_pattern\n    }\n    external! {\n        let t = (0, 1, 2, 3);\n        if let (0, _, ..) = t {};\n    }\n}\n"
  },
  {
    "path": "tests/ui/unneeded_wildcard_pattern.rs",
    "content": "//@aux-build:proc_macros.rs\n#![feature(stmt_expr_attributes)]\n#![deny(clippy::unneeded_wildcard_pattern)]\n#![allow(clippy::needless_ifs)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn main() {\n    let t = (0, 1, 2, 3);\n\n    if let (0, .., _) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (0, _, ..) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (_, .., 0) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (.., _, 0) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (0, _, _, ..) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (0, .., _, _) = t {};\n    //~^ unneeded_wildcard_pattern\n    if let (_, 0, ..) = t {};\n    if let (.., 0, _) = t {};\n    if let (0, _, _, _) = t {};\n    if let (0, ..) = t {};\n    if let (.., 0) = t {};\n\n    #[rustfmt::skip]\n    {\n        if let (0, .., _, _,) = t {};\n        //~^ unneeded_wildcard_pattern\n    }\n\n    struct S(usize, usize, usize, usize);\n\n    let s = S(0, 1, 2, 3);\n\n    if let S(0, .., _) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(0, _, ..) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(_, .., 0) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(.., _, 0) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(0, _, _, ..) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(0, .., _, _) = s {};\n    //~^ unneeded_wildcard_pattern\n    if let S(_, 0, ..) = s {};\n    if let S(.., 0, _) = s {};\n    if let S(0, _, _, _) = s {};\n    if let S(0, ..) = s {};\n    if let S(.., 0) = s {};\n\n    #[rustfmt::skip]\n    {\n        if let S(0, .., _, _,) = s {};\n        //~^ unneeded_wildcard_pattern\n    }\n    external! {\n        let t = (0, 1, 2, 3);\n        if let (0, _, ..) = t {};\n    }\n}\n"
  },
  {
    "path": "tests/ui/unneeded_wildcard_pattern.stderr",
    "content": "error: this pattern is unneeded as the `..` pattern can match that element\n  --> tests/ui/unneeded_wildcard_pattern.rs:12:18\n   |\nLL |     if let (0, .., _) = t {};\n   |                  ^^^ help: remove it\n   |\nnote: the lint level is defined here\n  --> tests/ui/unneeded_wildcard_pattern.rs:3:9\n   |\nLL | #![deny(clippy::unneeded_wildcard_pattern)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this pattern is unneeded as the `..` pattern can match that element\n  --> tests/ui/unneeded_wildcard_pattern.rs:14:16\n   |\nLL |     if let (0, _, ..) = t {};\n   |                ^^^ help: remove it\n\nerror: this pattern is unneeded as the `..` pattern can match that element\n  --> tests/ui/unneeded_wildcard_pattern.rs:16:13\n   |\nLL |     if let (_, .., 0) = t {};\n   |             ^^^ help: remove it\n\nerror: this pattern is unneeded as the `..` pattern can match that element\n  --> tests/ui/unneeded_wildcard_pattern.rs:18:15\n   |\nLL |     if let (.., _, 0) = t {};\n   |               ^^^ help: remove it\n\nerror: these patterns are unneeded as the `..` pattern can match those elements\n  --> tests/ui/unneeded_wildcard_pattern.rs:20:16\n   |\nLL |     if let (0, _, _, ..) = t {};\n   |                ^^^^^^ help: remove them\n\nerror: these patterns are unneeded as the `..` pattern can match those elements\n  --> tests/ui/unneeded_wildcard_pattern.rs:22:18\n   |\nLL |     if let (0, .., _, _) = t {};\n   |                  ^^^^^^ help: remove them\n\nerror: these patterns are unneeded as the `..` pattern can match those elements\n  --> tests/ui/unneeded_wildcard_pattern.rs:32:22\n   |\nLL |         if let (0, .., _, _,) = t {};\n   |                      ^^^^^^ help: remove them\n\nerror: this pattern is unneeded as the `..` pattern can match that element\n  --> tests/ui/unneeded_wildcard_pattern.rs:40:19\n   |\nLL |     if let S(0, .., _) = s {};\n   |                   ^^^ help: remove it\n\nerror: this pattern is unneeded as the `..` pattern can match that element\n  --> tests/ui/unneeded_wildcard_pattern.rs:42:17\n   |\nLL |     if let S(0, _, ..) = s {};\n   |                 ^^^ help: remove it\n\nerror: this pattern is unneeded as the `..` pattern can match that element\n  --> tests/ui/unneeded_wildcard_pattern.rs:44:14\n   |\nLL |     if let S(_, .., 0) = s {};\n   |              ^^^ help: remove it\n\nerror: this pattern is unneeded as the `..` pattern can match that element\n  --> tests/ui/unneeded_wildcard_pattern.rs:46:16\n   |\nLL |     if let S(.., _, 0) = s {};\n   |                ^^^ help: remove it\n\nerror: these patterns are unneeded as the `..` pattern can match those elements\n  --> tests/ui/unneeded_wildcard_pattern.rs:48:17\n   |\nLL |     if let S(0, _, _, ..) = s {};\n   |                 ^^^^^^ help: remove them\n\nerror: these patterns are unneeded as the `..` pattern can match those elements\n  --> tests/ui/unneeded_wildcard_pattern.rs:50:19\n   |\nLL |     if let S(0, .., _, _) = s {};\n   |                   ^^^^^^ help: remove them\n\nerror: these patterns are unneeded as the `..` pattern can match those elements\n  --> tests/ui/unneeded_wildcard_pattern.rs:60:23\n   |\nLL |         if let S(0, .., _, _,) = s {};\n   |                       ^^^^^^ help: remove them\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnested_or_patterns.fixed",
    "content": "#![feature(box_patterns)]\n#![warn(clippy::unnested_or_patterns)]\n#![allow(\n    clippy::cognitive_complexity,\n    clippy::match_ref_pats,\n    clippy::upper_case_acronyms,\n    clippy::needless_ifs,\n    clippy::manual_range_patterns\n)]\n#![allow(unreachable_patterns, irrefutable_let_patterns, unused)]\n\nstruct S {\n    x: u8,\n    y: u8,\n}\n\nfn main() {\n    // Should be ignored by this lint, as nesting requires more characters.\n    if let &0 | &2 = &0 {}\n\n    if let box (0 | 2) = Box::new(0) {}\n    //~^ unnested_or_patterns\n    if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}\n    //~^ unnested_or_patterns\n    const C0: Option<u8> = Some(1);\n    if let Some(1 | 2) | C0 = None {}\n    //~^ unnested_or_patterns\n    if let &mut (0 | 2) = &mut 0 {}\n    //~^ unnested_or_patterns\n    if let x @ (0 | 2) = 0 {}\n    //~^ unnested_or_patterns\n    if let (0, 1 | 2 | 3) = (0, 0) {}\n    //~^ unnested_or_patterns\n    if let (1 | 2 | 3, 0) = (0, 0) {}\n    //~^ unnested_or_patterns\n    if let (x, ..) | (x, 1 | 2) = (0, 1) {}\n    //~^ unnested_or_patterns\n    if let [0 | 1] = [0] {}\n    //~^ unnested_or_patterns\n    if let [x, 0 | 1] = [0, 1] {}\n    //~^ unnested_or_patterns\n    if let [x, 0 | 1 | 2] = [0, 1] {}\n    //~^ unnested_or_patterns\n    if let [x, ..] | [x, 1 | 2] = [0, 1] {}\n    //~^ unnested_or_patterns\n    struct TS(u8, u8);\n    if let TS(0 | 1, x) = TS(0, 0) {}\n    //~^ unnested_or_patterns\n    if let TS(1 | 2 | 3, 0) = TS(0, 0) {}\n    //~^ unnested_or_patterns\n    if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}\n    //~^ unnested_or_patterns\n    if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}\n    //~^ unnested_or_patterns\n    if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}\n}\n\n#[clippy::msrv = \"1.52\"]\nfn msrv_1_52() {\n    if let [1] | [52] = [0] {}\n}\n\n#[clippy::msrv = \"1.53\"]\nfn msrv_1_53() {\n    if let [1 | 53] = [0] {}\n    //~^ unnested_or_patterns\n}\n\nmod issue9952 {\n    fn or_in_local() {\n        let (0 | 1 | _) = 0;\n        //~^ unnested_or_patterns\n\n        if let (0 | 1 | _) = 0 {}\n        //~^ unnested_or_patterns\n    }\n\n    fn or_in_param((x | x | x): i32) {}\n    //~^ unnested_or_patterns\n}\n\nfn issue15219() {\n    struct Foo {\n        x: u8,\n    }\n\n    // the original repro\n    if let Foo { x } | Foo { x } = (Foo { x: 0 }) {}\n\n    // also works with more fields\n    if let S { x, y } | S { x, y } = (S { x: 0, y: 0 }) {}\n\n    // `y` not triggering the lint doesn't stop the `x` from getting flagged\n    if let S { y, x: 0 | 1 } = (S { x: 0, y: 1 }) {}\n    //~^ unnested_or_patterns\n}\n"
  },
  {
    "path": "tests/ui/unnested_or_patterns.rs",
    "content": "#![feature(box_patterns)]\n#![warn(clippy::unnested_or_patterns)]\n#![allow(\n    clippy::cognitive_complexity,\n    clippy::match_ref_pats,\n    clippy::upper_case_acronyms,\n    clippy::needless_ifs,\n    clippy::manual_range_patterns\n)]\n#![allow(unreachable_patterns, irrefutable_let_patterns, unused)]\n\nstruct S {\n    x: u8,\n    y: u8,\n}\n\nfn main() {\n    // Should be ignored by this lint, as nesting requires more characters.\n    if let &0 | &2 = &0 {}\n\n    if let box 0 | box 2 = Box::new(0) {}\n    //~^ unnested_or_patterns\n    if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}\n    //~^ unnested_or_patterns\n    const C0: Option<u8> = Some(1);\n    if let Some(1) | C0 | Some(2) = None {}\n    //~^ unnested_or_patterns\n    if let &mut 0 | &mut 2 = &mut 0 {}\n    //~^ unnested_or_patterns\n    if let x @ 0 | x @ 2 = 0 {}\n    //~^ unnested_or_patterns\n    if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}\n    //~^ unnested_or_patterns\n    if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}\n    //~^ unnested_or_patterns\n    if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}\n    //~^ unnested_or_patterns\n    if let [0] | [1] = [0] {}\n    //~^ unnested_or_patterns\n    if let [x, 0] | [x, 1] = [0, 1] {}\n    //~^ unnested_or_patterns\n    if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}\n    //~^ unnested_or_patterns\n    if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}\n    //~^ unnested_or_patterns\n    struct TS(u8, u8);\n    if let TS(0, x) | TS(1, x) = TS(0, 0) {}\n    //~^ unnested_or_patterns\n    if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}\n    //~^ unnested_or_patterns\n    if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}\n    //~^ unnested_or_patterns\n    if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}\n    //~^ unnested_or_patterns\n    if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}\n}\n\n#[clippy::msrv = \"1.52\"]\nfn msrv_1_52() {\n    if let [1] | [52] = [0] {}\n}\n\n#[clippy::msrv = \"1.53\"]\nfn msrv_1_53() {\n    if let [1] | [53] = [0] {}\n    //~^ unnested_or_patterns\n}\n\nmod issue9952 {\n    fn or_in_local() {\n        let (0 | (1 | _)) = 0;\n        //~^ unnested_or_patterns\n\n        if let (0 | (1 | _)) = 0 {}\n        //~^ unnested_or_patterns\n    }\n\n    fn or_in_param((x | (x | x)): i32) {}\n    //~^ unnested_or_patterns\n}\n\nfn issue15219() {\n    struct Foo {\n        x: u8,\n    }\n\n    // the original repro\n    if let Foo { x } | Foo { x } = (Foo { x: 0 }) {}\n\n    // also works with more fields\n    if let S { x, y } | S { x, y } = (S { x: 0, y: 0 }) {}\n\n    // `y` not triggering the lint doesn't stop the `x` from getting flagged\n    if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}\n    //~^ unnested_or_patterns\n}\n"
  },
  {
    "path": "tests/ui/unnested_or_patterns.stderr",
    "content": "error: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:21:12\n   |\nLL |     if let box 0 | box 2 = Box::new(0) {}\n   |            ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnested-or-patterns` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]`\nhelp: nest the patterns\n   |\nLL -     if let box 0 | box 2 = Box::new(0) {}\nLL +     if let box (0 | 2) = Box::new(0) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:23:12\n   |\nLL |     if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}\nLL +     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:26:12\n   |\nLL |     if let Some(1) | C0 | Some(2) = None {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let Some(1) | C0 | Some(2) = None {}\nLL +     if let Some(1 | 2) | C0 = None {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:28:12\n   |\nLL |     if let &mut 0 | &mut 2 = &mut 0 {}\n   |            ^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let &mut 0 | &mut 2 = &mut 0 {}\nLL +     if let &mut (0 | 2) = &mut 0 {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:30:12\n   |\nLL |     if let x @ 0 | x @ 2 = 0 {}\n   |            ^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let x @ 0 | x @ 2 = 0 {}\nLL +     if let x @ (0 | 2) = 0 {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:32:12\n   |\nLL |     if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}\nLL +     if let (0, 1 | 2 | 3) = (0, 0) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:34:12\n   |\nLL |     if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}\nLL +     if let (1 | 2 | 3, 0) = (0, 0) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:36:12\n   |\nLL |     if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}\nLL +     if let (x, ..) | (x, 1 | 2) = (0, 1) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:38:12\n   |\nLL |     if let [0] | [1] = [0] {}\n   |            ^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let [0] | [1] = [0] {}\nLL +     if let [0 | 1] = [0] {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:40:12\n   |\nLL |     if let [x, 0] | [x, 1] = [0, 1] {}\n   |            ^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let [x, 0] | [x, 1] = [0, 1] {}\nLL +     if let [x, 0 | 1] = [0, 1] {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:42:12\n   |\nLL |     if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}\nLL +     if let [x, 0 | 1 | 2] = [0, 1] {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:44:12\n   |\nLL |     if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}\nLL +     if let [x, ..] | [x, 1 | 2] = [0, 1] {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:47:12\n   |\nLL |     if let TS(0, x) | TS(1, x) = TS(0, 0) {}\n   |            ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let TS(0, x) | TS(1, x) = TS(0, 0) {}\nLL +     if let TS(0 | 1, x) = TS(0, 0) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:49:12\n   |\nLL |     if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}\nLL +     if let TS(1 | 2 | 3, 0) = TS(0, 0) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:51:12\n   |\nLL |     if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}\nLL +     if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:53:12\n   |\nLL |     if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}\nLL +     if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:65:12\n   |\nLL |     if let [1] | [53] = [0] {}\n   |            ^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let [1] | [53] = [0] {}\nLL +     if let [1 | 53] = [0] {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:71:13\n   |\nLL |         let (0 | (1 | _)) = 0;\n   |             ^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -         let (0 | (1 | _)) = 0;\nLL +         let (0 | 1 | _) = 0;\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:74:16\n   |\nLL |         if let (0 | (1 | _)) = 0 {}\n   |                ^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -         if let (0 | (1 | _)) = 0 {}\nLL +         if let (0 | 1 | _) = 0 {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:78:20\n   |\nLL |     fn or_in_param((x | (x | x)): i32) {}\n   |                    ^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     fn or_in_param((x | (x | x)): i32) {}\nLL +     fn or_in_param((x | x | x): i32) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns.rs:94:12\n   |\nLL |     if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}\nLL +     if let S { y, x: 0 | 1 } = (S { x: 0, y: 1 }) {}\n   |\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui/unnested_or_patterns2.fixed",
    "content": "#![feature(box_patterns)]\n#![warn(clippy::unnested_or_patterns)]\n#![allow(\n    clippy::cognitive_complexity,\n    clippy::match_ref_pats,\n    clippy::needless_ifs,\n    clippy::manual_range_patterns\n)]\n#![allow(unreachable_patterns, irrefutable_let_patterns, unused_variables)]\n\nfn main() {\n    if let Some(Some(0 | 1)) = None {}\n    //~^ unnested_or_patterns\n    if let Some(Some(0 | 1 | 2)) = None {}\n    //~^ unnested_or_patterns\n    if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {}\n    //~^ unnested_or_patterns\n    if let Some(Some(0 | 1 | 2)) = None {}\n    //~^ unnested_or_patterns\n    if let ((0 | 1 | 2,),) = ((0,),) {}\n    //~^ unnested_or_patterns\n    if let 0 | 1 | 2 = 0 {}\n    //~^ unnested_or_patterns\n    if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}\n    //~^ unnested_or_patterns\n    if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {}\n    //~^ unnested_or_patterns\n}\n"
  },
  {
    "path": "tests/ui/unnested_or_patterns2.rs",
    "content": "#![feature(box_patterns)]\n#![warn(clippy::unnested_or_patterns)]\n#![allow(\n    clippy::cognitive_complexity,\n    clippy::match_ref_pats,\n    clippy::needless_ifs,\n    clippy::manual_range_patterns\n)]\n#![allow(unreachable_patterns, irrefutable_let_patterns, unused_variables)]\n\nfn main() {\n    if let Some(Some(0)) | Some(Some(1)) = None {}\n    //~^ unnested_or_patterns\n    if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {}\n    //~^ unnested_or_patterns\n    if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {}\n    //~^ unnested_or_patterns\n    if let Some(Some(0) | Some(1 | 2)) = None {}\n    //~^ unnested_or_patterns\n    if let ((0,),) | ((1,) | (2,),) = ((0,),) {}\n    //~^ unnested_or_patterns\n    if let 0 | (1 | 2) = 0 {}\n    //~^ unnested_or_patterns\n    if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {}\n    //~^ unnested_or_patterns\n    if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {}\n    //~^ unnested_or_patterns\n}\n"
  },
  {
    "path": "tests/ui/unnested_or_patterns2.stderr",
    "content": "error: unnested or-patterns\n  --> tests/ui/unnested_or_patterns2.rs:12:12\n   |\nLL |     if let Some(Some(0)) | Some(Some(1)) = None {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnested-or-patterns` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]`\nhelp: nest the patterns\n   |\nLL -     if let Some(Some(0)) | Some(Some(1)) = None {}\nLL +     if let Some(Some(0 | 1)) = None {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns2.rs:14:12\n   |\nLL |     if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {}\nLL +     if let Some(Some(0 | 1 | 2)) = None {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns2.rs:16:12\n   |\nLL |     if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {}\nLL +     if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns2.rs:18:12\n   |\nLL |     if let Some(Some(0) | Some(1 | 2)) = None {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let Some(Some(0) | Some(1 | 2)) = None {}\nLL +     if let Some(Some(0 | 1 | 2)) = None {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns2.rs:20:12\n   |\nLL |     if let ((0,),) | ((1,) | (2,),) = ((0,),) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let ((0,),) | ((1,) | (2,),) = ((0,),) {}\nLL +     if let ((0 | 1 | 2,),) = ((0,),) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns2.rs:22:12\n   |\nLL |     if let 0 | (1 | 2) = 0 {}\n   |            ^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let 0 | (1 | 2) = 0 {}\nLL +     if let 0 | 1 | 2 = 0 {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns2.rs:24:12\n   |\nLL |     if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {}\nLL +     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}\n   |\n\nerror: unnested or-patterns\n  --> tests/ui/unnested_or_patterns2.rs:26:12\n   |\nLL |     if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {}\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: nest the patterns\n   |\nLL -     if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {}\nLL +     if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {}\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/unreadable_literal.fixed",
    "content": "#![warn(clippy::unreadable_literal)]\n\nstruct Foo(u64);\n\nmacro_rules! foo {\n    () => {\n        Foo(123123123123)\n    };\n}\n\nstruct Bar(f32);\n\nmacro_rules! bar {\n    () => {\n        Bar(100200300400.100200300400500)\n    };\n}\n\nfn main() {\n    let _good = (\n        0b1011_i64,\n        0o1_234_u32,\n        0x1_234_567,\n        65536,\n        1_2345_6789,\n        1234_f32,\n        1_234.12_f32,\n        1_234.123_f32,\n        1.123_4_f32,\n    );\n    let _bad = (0b11_0110_i64, 0x1234_5678_usize, 123_456_f32, 1.234_567_f32);\n    //~^ unreadable_literal\n    //~| unreadable_literal\n    //~| unreadable_literal\n    //~| unreadable_literal\n    let _good_sci = 1.1234e1;\n    let _bad_sci = 1.123_456e1;\n    //~^ unreadable_literal\n\n    let _fail1 = 0x00ab_cdef;\n    //~^ unreadable_literal\n    let _fail2: u32 = 0xBAFE_BAFE;\n    //~^ unreadable_literal\n    let _fail3 = 0x0abc_deff;\n    //~^ unreadable_literal\n    let _fail4: i128 = 0x00ab_cabc_abca_bcab_cabc;\n    //~^ unreadable_literal\n    let _fail5 = 1.100_300_400;\n    //~^ unreadable_literal\n\n    let _ = foo!();\n    let _ = bar!();\n}\n"
  },
  {
    "path": "tests/ui/unreadable_literal.rs",
    "content": "#![warn(clippy::unreadable_literal)]\n\nstruct Foo(u64);\n\nmacro_rules! foo {\n    () => {\n        Foo(123123123123)\n    };\n}\n\nstruct Bar(f32);\n\nmacro_rules! bar {\n    () => {\n        Bar(100200300400.100200300400500)\n    };\n}\n\nfn main() {\n    let _good = (\n        0b1011_i64,\n        0o1_234_u32,\n        0x1_234_567,\n        65536,\n        1_2345_6789,\n        1234_f32,\n        1_234.12_f32,\n        1_234.123_f32,\n        1.123_4_f32,\n    );\n    let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);\n    //~^ unreadable_literal\n    //~| unreadable_literal\n    //~| unreadable_literal\n    //~| unreadable_literal\n    let _good_sci = 1.1234e1;\n    let _bad_sci = 1.123456e1;\n    //~^ unreadable_literal\n\n    let _fail1 = 0xabcdef;\n    //~^ unreadable_literal\n    let _fail2: u32 = 0xBAFEBAFE;\n    //~^ unreadable_literal\n    let _fail3 = 0xabcdeff;\n    //~^ unreadable_literal\n    let _fail4: i128 = 0xabcabcabcabcabcabc;\n    //~^ unreadable_literal\n    let _fail5 = 1.100300400;\n    //~^ unreadable_literal\n\n    let _ = foo!();\n    let _ = bar!();\n}\n"
  },
  {
    "path": "tests/ui/unreadable_literal.stderr",
    "content": "error: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:31:17\n   |\nLL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);\n   |                 ^^^^^^^^^^^^ help: consider: `0b11_0110_i64`\n   |\n   = note: `-D clippy::unreadable-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unreadable_literal)]`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:31:31\n   |\nLL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);\n   |                               ^^^^^^^^^^^^^^^^ help: consider: `0x1234_5678_usize`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:31:49\n   |\nLL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);\n   |                                                 ^^^^^^^^^^ help: consider: `123_456_f32`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:31:61\n   |\nLL |     let _bad = (0b110110_i64, 0x12345678_usize, 123456_f32, 1.234567_f32);\n   |                                                             ^^^^^^^^^^^^ help: consider: `1.234_567_f32`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:37:20\n   |\nLL |     let _bad_sci = 1.123456e1;\n   |                    ^^^^^^^^^^ help: consider: `1.123_456e1`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:40:18\n   |\nLL |     let _fail1 = 0xabcdef;\n   |                  ^^^^^^^^ help: consider: `0x00ab_cdef`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:42:23\n   |\nLL |     let _fail2: u32 = 0xBAFEBAFE;\n   |                       ^^^^^^^^^^ help: consider: `0xBAFE_BAFE`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:44:18\n   |\nLL |     let _fail3 = 0xabcdeff;\n   |                  ^^^^^^^^^ help: consider: `0x0abc_deff`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:46:24\n   |\nLL |     let _fail4: i128 = 0xabcabcabcabcabcabc;\n   |                        ^^^^^^^^^^^^^^^^^^^^ help: consider: `0x00ab_cabc_abca_bcab_cabc`\n\nerror: long literal lacking separators\n  --> tests/ui/unreadable_literal.rs:48:18\n   |\nLL |     let _fail5 = 1.100300400;\n   |                  ^^^^^^^^^^^ help: consider: `1.100_300_400`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui/unsafe_derive_deserialize.rs",
    "content": "#![warn(clippy::unsafe_derive_deserialize)]\n#![allow(unused, clippy::missing_safety_doc)]\n\nextern crate serde;\n\nuse serde::Deserialize;\n\n#[derive(Deserialize)]\n//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe\npub struct A;\nimpl A {\n    pub unsafe fn new(_a: i32, _b: i32) -> Self {\n        Self {}\n    }\n}\n\n#[derive(Deserialize)]\n//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe\npub struct B;\nimpl B {\n    pub unsafe fn unsafe_method(&self) {}\n}\n\n#[derive(Deserialize)]\n//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe\npub struct C;\nimpl C {\n    pub fn unsafe_block(&self) {\n        unsafe {}\n    }\n}\n\n#[derive(Deserialize)]\n//~^ ERROR: you are deriving `serde::Deserialize` on a type that has methods using `unsafe\npub struct D;\nimpl D {\n    pub fn inner_unsafe_fn(&self) {\n        unsafe fn inner() {}\n    }\n}\n\n// Does not derive `Deserialize`, should be ignored\npub struct E;\nimpl E {\n    pub unsafe fn new(_a: i32, _b: i32) -> Self {\n        Self {}\n    }\n\n    pub unsafe fn unsafe_method(&self) {}\n\n    pub fn unsafe_block(&self) {\n        unsafe {}\n    }\n\n    pub fn inner_unsafe_fn(&self) {\n        unsafe fn inner() {}\n    }\n}\n\n// Does not have methods using `unsafe`, should be ignored\n#[derive(Deserialize)]\npub struct F;\n\n// Check that we honor the `allow` attribute on the ADT\n#[allow(clippy::unsafe_derive_deserialize)]\n#[derive(Deserialize)]\npub struct G;\nimpl G {\n    pub fn unsafe_block(&self) {\n        unsafe {}\n    }\n}\n\n// Check that we honor the `expect` attribute on the ADT\n#[expect(clippy::unsafe_derive_deserialize)]\n#[derive(Deserialize)]\npub struct H;\nimpl H {\n    pub fn unsafe_block(&self) {\n        unsafe {}\n    }\n}\n\nfn main() {}\n\nmod issue15120 {\n    macro_rules! uns {\n        ($e:expr) => {\n            unsafe { $e }\n        };\n    }\n\n    #[derive(serde::Deserialize)]\n    struct Foo;\n\n    impl Foo {\n        fn foo(&self) {\n            // Do not lint if `unsafe` comes from the `core::pin::pin!()` macro\n            std::pin::pin!(());\n        }\n    }\n\n    //~v unsafe_derive_deserialize\n    #[derive(serde::Deserialize)]\n    struct Bar;\n\n    impl Bar {\n        fn bar(&self) {\n            // Lint if `unsafe` comes from the another macro\n            _ = uns!(42);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/unsafe_derive_deserialize.stderr",
    "content": "error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`\n  --> tests/ui/unsafe_derive_deserialize.rs:8:10\n   |\nLL | #[derive(Deserialize)]\n   |          ^^^^^^^^^^^\n   |\n   = help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html\n   = note: `-D clippy::unsafe-derive-deserialize` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unsafe_derive_deserialize)]`\n   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`\n  --> tests/ui/unsafe_derive_deserialize.rs:17:10\n   |\nLL | #[derive(Deserialize)]\n   |          ^^^^^^^^^^^\n   |\n   = help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html\n   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`\n  --> tests/ui/unsafe_derive_deserialize.rs:24:10\n   |\nLL | #[derive(Deserialize)]\n   |          ^^^^^^^^^^^\n   |\n   = help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html\n   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`\n  --> tests/ui/unsafe_derive_deserialize.rs:33:10\n   |\nLL | #[derive(Deserialize)]\n   |          ^^^^^^^^^^^\n   |\n   = help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html\n   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`\n  --> tests/ui/unsafe_derive_deserialize.rs:104:14\n   |\nLL |     #[derive(serde::Deserialize)]\n   |              ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html\n   = note: this error originates in the derive macro `serde::Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/unsafe_removed_from_name.rs",
    "content": "#![allow(unused_imports)]\n#![allow(dead_code)]\n#![warn(clippy::unsafe_removed_from_name)]\n\nuse std::cell::UnsafeCell as TotallySafeCell;\n//~^ unsafe_removed_from_name\n\nuse std::cell::UnsafeCell as TotallySafeCellAgain;\n//~^ unsafe_removed_from_name\n\n// Shouldn't error\nuse std::cell::RefCell as ProbablyNotUnsafe;\n\nuse std::cell::RefCell as RefCellThatCantBeUnsafe;\n\nuse std::cell::UnsafeCell as SuperDangerousUnsafeCell;\n\nuse std::cell::UnsafeCell as Dangerunsafe;\n\nuse std::cell::UnsafeCell as Bombsawayunsafe;\n\nmod mod_with_some_unsafe_things {\n    pub struct Safe;\n    pub struct Unsafe;\n}\n\nuse mod_with_some_unsafe_things::Unsafe as LieAboutModSafety;\n//~^ unsafe_removed_from_name\n\n// merged imports\nuse mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B};\n//~^ unsafe_removed_from_name\n//~| unsafe_removed_from_name\n\n// Shouldn't error\nuse mod_with_some_unsafe_things::Safe as IPromiseItsSafeThisTime;\n\nuse mod_with_some_unsafe_things::Unsafe as SuperUnsafeModThing;\n\n#[allow(clippy::unsafe_removed_from_name)]\nuse mod_with_some_unsafe_things::Unsafe as SuperSafeThing;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unsafe_removed_from_name.stderr",
    "content": "error: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCell`\n  --> tests/ui/unsafe_removed_from_name.rs:5:1\n   |\nLL | use std::cell::UnsafeCell as TotallySafeCell;\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unsafe-removed-from-name` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unsafe_removed_from_name)]`\n\nerror: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCellAgain`\n  --> tests/ui/unsafe_removed_from_name.rs:8:1\n   |\nLL | use std::cell::UnsafeCell as TotallySafeCellAgain;\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: removed `unsafe` from the name of `Unsafe` in use as `LieAboutModSafety`\n  --> tests/ui/unsafe_removed_from_name.rs:27:1\n   |\nLL | use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety;\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: removed `unsafe` from the name of `Unsafe` in use as `A`\n  --> tests/ui/unsafe_removed_from_name.rs:31:1\n   |\nLL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B};\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: removed `unsafe` from the name of `Unsafe` in use as `B`\n  --> tests/ui/unsafe_removed_from_name.rs:31:1\n   |\nLL | use mod_with_some_unsafe_things::{Unsafe as A, Unsafe as B};\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/unseparated_prefix_literals.fixed",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::unseparated_literal_suffix)]\n#![allow(dead_code)]\n\n#[macro_use]\nextern crate proc_macro_derive;\n\n// Test for proc-macro attribute\n#[derive(ClippyMiniMacroTest)]\nstruct Foo;\n\nmacro_rules! lit_from_macro {\n    () => {\n        42_usize\n        //~^ unseparated_literal_suffix\n    };\n}\n\nfn main() {\n    let _ok1 = 1234_i32;\n    let _ok2 = 1234_isize;\n    let _ok3 = 0x123_isize;\n    let _fail1 = 1234_i32;\n    //~^ unseparated_literal_suffix\n    let _fail2 = 1234_u32;\n    //~^ unseparated_literal_suffix\n    let _fail3 = 1234_isize;\n    //~^ unseparated_literal_suffix\n    let _fail4 = 1234_usize;\n    //~^ unseparated_literal_suffix\n    let _fail5 = 0x123_isize;\n    //~^ unseparated_literal_suffix\n\n    let _okf1 = 1.5_f32;\n    let _okf2 = 1_f32;\n    let _failf1 = 1.5_f32;\n    //~^ unseparated_literal_suffix\n    let _failf2 = 1_f32;\n    //~^ unseparated_literal_suffix\n\n    // Test for macro\n    let _ = lit_from_macro!();\n\n    // Counter example\n    let _ = line!();\n    // Because `assert!` contains `line!()` macro.\n    assert_eq!(4897_u32, 32223);\n    //~^ unseparated_literal_suffix\n}\n"
  },
  {
    "path": "tests/ui/unseparated_prefix_literals.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::unseparated_literal_suffix)]\n#![allow(dead_code)]\n\n#[macro_use]\nextern crate proc_macro_derive;\n\n// Test for proc-macro attribute\n#[derive(ClippyMiniMacroTest)]\nstruct Foo;\n\nmacro_rules! lit_from_macro {\n    () => {\n        42usize\n        //~^ unseparated_literal_suffix\n    };\n}\n\nfn main() {\n    let _ok1 = 1234_i32;\n    let _ok2 = 1234_isize;\n    let _ok3 = 0x123_isize;\n    let _fail1 = 1234i32;\n    //~^ unseparated_literal_suffix\n    let _fail2 = 1234u32;\n    //~^ unseparated_literal_suffix\n    let _fail3 = 1234isize;\n    //~^ unseparated_literal_suffix\n    let _fail4 = 1234usize;\n    //~^ unseparated_literal_suffix\n    let _fail5 = 0x123isize;\n    //~^ unseparated_literal_suffix\n\n    let _okf1 = 1.5_f32;\n    let _okf2 = 1_f32;\n    let _failf1 = 1.5f32;\n    //~^ unseparated_literal_suffix\n    let _failf2 = 1f32;\n    //~^ unseparated_literal_suffix\n\n    // Test for macro\n    let _ = lit_from_macro!();\n\n    // Counter example\n    let _ = line!();\n    // Because `assert!` contains `line!()` macro.\n    assert_eq!(4897u32, 32223);\n    //~^ unseparated_literal_suffix\n}\n"
  },
  {
    "path": "tests/ui/unseparated_prefix_literals.stderr",
    "content": "error: integer type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:24:18\n   |\nLL |     let _fail1 = 1234i32;\n   |                  ^^^^^^^ help: add an underscore: `1234_i32`\n   |\n   = note: `-D clippy::unseparated-literal-suffix` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]`\n\nerror: integer type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:26:18\n   |\nLL |     let _fail2 = 1234u32;\n   |                  ^^^^^^^ help: add an underscore: `1234_u32`\n\nerror: integer type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:28:18\n   |\nLL |     let _fail3 = 1234isize;\n   |                  ^^^^^^^^^ help: add an underscore: `1234_isize`\n\nerror: integer type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:30:18\n   |\nLL |     let _fail4 = 1234usize;\n   |                  ^^^^^^^^^ help: add an underscore: `1234_usize`\n\nerror: integer type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:32:18\n   |\nLL |     let _fail5 = 0x123isize;\n   |                  ^^^^^^^^^^ help: add an underscore: `0x123_isize`\n\nerror: float type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:37:19\n   |\nLL |     let _failf1 = 1.5f32;\n   |                   ^^^^^^ help: add an underscore: `1.5_f32`\n\nerror: float type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:39:19\n   |\nLL |     let _failf2 = 1f32;\n   |                   ^^^^ help: add an underscore: `1_f32`\n\nerror: integer type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:15:9\n   |\nLL |         42usize\n   |         ^^^^^^^ help: add an underscore: `42_usize`\n...\nLL |     let _ = lit_from_macro!();\n   |             ----------------- in this macro invocation\n   |\n   = note: this error originates in the macro `lit_from_macro` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: integer type suffix should be separated by an underscore\n  --> tests/ui/unseparated_prefix_literals.rs:48:16\n   |\nLL |     assert_eq!(4897u32, 32223);\n   |                ^^^^^^^ help: add an underscore: `4897_u32`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_async.rs",
    "content": "#![warn(clippy::unused_async)]\n#![allow(incomplete_features)]\n\nuse std::future::Future;\nuse std::pin::Pin;\n\nmod issue10800 {\n    #![allow(dead_code, unused_must_use, clippy::no_effect)]\n\n    use std::future::ready;\n\n    async fn async_block_await() {\n        //~^ unused_async\n\n        async {\n            ready(()).await;\n        };\n    }\n\n    async fn normal_block_await() {\n        {\n            {\n                ready(()).await;\n            }\n        }\n    }\n}\n\nmod issue10459 {\n    trait HasAsyncMethod {\n        async fn do_something() -> u32;\n    }\n\n    impl HasAsyncMethod for () {\n        async fn do_something() -> u32 {\n            1\n        }\n    }\n}\n\nmod issue9695 {\n    use std::future::Future;\n\n    async fn f() {}\n    async fn f2() {}\n    async fn f3() {}\n    //~^ unused_async\n\n    fn needs_async_fn<F: Future<Output = ()>>(_: fn() -> F) {}\n\n    fn test() {\n        let x = f;\n        needs_async_fn(x); // async needed in f\n        needs_async_fn(f2); // async needed in f2\n        f3(); // async not needed in f3\n    }\n}\n\nmod issue13466 {\n    use std::future::Future;\n\n    struct Wrap<F>(F);\n    impl<F> From<F> for Wrap<F> {\n        fn from(f: F) -> Self {\n            Self(f)\n        }\n    }\n    fn takes_fut<F: Fn() -> Fut, Fut: Future>(_: Wrap<F>) {}\n    async fn unused_async() {}\n    fn fp() {\n        takes_fut(unused_async.into());\n    }\n}\n\nasync fn foo() -> i32 {\n    //~^ unused_async\n\n    4\n}\n\nasync fn bar() -> i32 {\n    foo().await\n}\n\nstruct S;\n\nimpl S {\n    async fn unused(&self) -> i32 {\n        //~^ unused_async\n\n        1\n    }\n\n    async fn used(&self) -> i32 {\n        self.unused().await\n    }\n}\n\ntrait AsyncTrait {\n    fn trait_method() -> Pin<Box<dyn Future<Output = i32>>>;\n}\n\nmacro_rules! async_trait_impl {\n    () => {\n        impl AsyncTrait for S {\n            fn trait_method() -> Pin<Box<dyn Future<Output = i32>>> {\n                async fn unused() -> i32 {\n                    5\n                }\n\n                Box::pin(unused())\n            }\n        }\n    };\n}\nasync_trait_impl!();\n\nfn main() {}\n\nmod issue14704 {\n    use std::sync::Arc;\n\n    trait Action {\n        async fn cancel(self: Arc<Self>) {}\n    }\n}\n\nmod issue15305 {\n    async fn todo_task() -> Result<(), String> {\n        todo!(\"Implement task\");\n    }\n\n    async fn unimplemented_task() -> Result<(), String> {\n        unimplemented!(\"Implement task\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/unused_async.stderr",
    "content": "error: unused `async` for function with no await statements\n  --> tests/ui/unused_async.rs:12:5\n   |\nLL | /     async fn async_block_await() {\nLL | |\nLL | |\nLL | |         async {\nLL | |             ready(()).await;\nLL | |         };\nLL | |     }\n   | |_____^\n   |\n   = help: consider removing the `async` from this function\nnote: `await` used in an async block, which does not require the enclosing function to be `async`\n  --> tests/ui/unused_async.rs:16:23\n   |\nLL |             ready(()).await;\n   |                       ^^^^^\n   = note: `-D clippy::unused-async` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_async)]`\n\nerror: unused `async` for function with no await statements\n  --> tests/ui/unused_async.rs:46:5\n   |\nLL |     async fn f3() {}\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing the `async` from this function\n\nerror: unused `async` for function with no await statements\n  --> tests/ui/unused_async.rs:75:1\n   |\nLL | / async fn foo() -> i32 {\nLL | |\nLL | |\nLL | |     4\nLL | | }\n   | |_^\n   |\n   = help: consider removing the `async` from this function\n\nerror: unused `async` for function with no await statements\n  --> tests/ui/unused_async.rs:88:5\n   |\nLL | /     async fn unused(&self) -> i32 {\nLL | |\nLL | |\nLL | |         1\nLL | |     }\n   | |_____^\n   |\n   = help: consider removing the `async` from this function\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_enumerate_index.fixed",
    "content": "#![allow(unused, clippy::map_identity)]\n#![warn(clippy::unused_enumerate_index)]\n\nuse std::iter::Enumerate;\n\nfn get_enumerate() -> Enumerate<std::vec::IntoIter<i32>> {\n    vec![1].into_iter().enumerate()\n}\n\nfn main() {\n    let v = [1, 2, 3];\n    for x in v.iter() {\n        //~^ unused_enumerate_index\n        println!(\"{x}\");\n    }\n\n    struct Dummy1;\n    impl Dummy1 {\n        fn enumerate(self) -> Vec<usize> {\n            vec![]\n        }\n    }\n    let dummy = Dummy1;\n    for x in dummy.enumerate() {\n        println!(\"{x}\");\n    }\n\n    struct Dummy2;\n    impl Dummy2 {\n        fn enumerate(self) -> Enumerate<std::vec::IntoIter<usize>> {\n            vec![1, 2].into_iter().enumerate()\n        }\n    }\n    let dummy = Dummy2;\n    for (_, x) in dummy.enumerate() {\n        println!(\"{x}\");\n    }\n\n    let mut with_used_iterator = [1, 2, 3].into_iter().enumerate();\n    with_used_iterator.next();\n    for (_, x) in with_used_iterator {\n        println!(\"{x}\");\n    }\n\n    struct Dummy3(std::vec::IntoIter<usize>);\n\n    impl Iterator for Dummy3 {\n        type Item = usize;\n\n        fn next(&mut self) -> Option<Self::Item> {\n            self.0.next()\n        }\n\n        fn size_hint(&self) -> (usize, Option<usize>) {\n            self.0.size_hint()\n        }\n    }\n\n    let dummy = Dummy3(vec![1, 2, 3].into_iter());\n    for x in dummy {\n        //~^ unused_enumerate_index\n        println!(\"{x}\");\n    }\n\n    let _ = vec![1, 2, 3].into_iter().map(|x| println!(\"{x}\"));\n    //~^ unused_enumerate_index\n\n    let p = vec![1, 2, 3].into_iter();\n    //~^ unused_enumerate_index\n    p.map(|x| println!(\"{x}\"));\n\n    // This shouldn't trigger the lint. `get_enumerate` may come from an external library on which we\n    // have no control.\n    let p = get_enumerate();\n    p.map(|(_, x)| println!(\"{x}\"));\n\n    // This shouldn't trigger the lint. The `enumerate` call is in a different context.\n    macro_rules! mac {\n        () => {\n            [1].iter().enumerate()\n        };\n    }\n    _ = mac!().map(|(_, v)| v);\n\n    macro_rules! mac2 {\n        () => {\n            [1].iter()\n        };\n    }\n    _ = mac2!().map(|_v| {});\n    //~^ unused_enumerate_index\n\n    // This shouldn't trigger the lint because of the `allow`.\n    #[allow(clippy::unused_enumerate_index)]\n    let v = [1].iter().enumerate();\n    v.map(|(_, _x)| {});\n\n    // This should keep the explicit type of `x`.\n    let v = [1, 2, 3].iter().copied();\n    //~^ unused_enumerate_index\n    let x = v.map(|x: i32| x).sum::<i32>();\n    assert_eq!(x, 6);\n\n    // This should keep the explicit type of `x`.\n    let v = [1, 2, 3].iter().copied();\n    //~^ unused_enumerate_index\n    let x = v.map(|x: i32| x).sum::<i32>();\n    assert_eq!(x, 6);\n\n    let v = [1, 2, 3].iter().copied();\n    //~^ unused_enumerate_index\n    let x = v.map(|x| x).sum::<i32>();\n    assert_eq!(x, 6);\n}\n"
  },
  {
    "path": "tests/ui/unused_enumerate_index.rs",
    "content": "#![allow(unused, clippy::map_identity)]\n#![warn(clippy::unused_enumerate_index)]\n\nuse std::iter::Enumerate;\n\nfn get_enumerate() -> Enumerate<std::vec::IntoIter<i32>> {\n    vec![1].into_iter().enumerate()\n}\n\nfn main() {\n    let v = [1, 2, 3];\n    for (_, x) in v.iter().enumerate() {\n        //~^ unused_enumerate_index\n        println!(\"{x}\");\n    }\n\n    struct Dummy1;\n    impl Dummy1 {\n        fn enumerate(self) -> Vec<usize> {\n            vec![]\n        }\n    }\n    let dummy = Dummy1;\n    for x in dummy.enumerate() {\n        println!(\"{x}\");\n    }\n\n    struct Dummy2;\n    impl Dummy2 {\n        fn enumerate(self) -> Enumerate<std::vec::IntoIter<usize>> {\n            vec![1, 2].into_iter().enumerate()\n        }\n    }\n    let dummy = Dummy2;\n    for (_, x) in dummy.enumerate() {\n        println!(\"{x}\");\n    }\n\n    let mut with_used_iterator = [1, 2, 3].into_iter().enumerate();\n    with_used_iterator.next();\n    for (_, x) in with_used_iterator {\n        println!(\"{x}\");\n    }\n\n    struct Dummy3(std::vec::IntoIter<usize>);\n\n    impl Iterator for Dummy3 {\n        type Item = usize;\n\n        fn next(&mut self) -> Option<Self::Item> {\n            self.0.next()\n        }\n\n        fn size_hint(&self) -> (usize, Option<usize>) {\n            self.0.size_hint()\n        }\n    }\n\n    let dummy = Dummy3(vec![1, 2, 3].into_iter());\n    for (_, x) in dummy.enumerate() {\n        //~^ unused_enumerate_index\n        println!(\"{x}\");\n    }\n\n    let _ = vec![1, 2, 3].into_iter().enumerate().map(|(_, x)| println!(\"{x}\"));\n    //~^ unused_enumerate_index\n\n    let p = vec![1, 2, 3].into_iter().enumerate();\n    //~^ unused_enumerate_index\n    p.map(|(_, x)| println!(\"{x}\"));\n\n    // This shouldn't trigger the lint. `get_enumerate` may come from an external library on which we\n    // have no control.\n    let p = get_enumerate();\n    p.map(|(_, x)| println!(\"{x}\"));\n\n    // This shouldn't trigger the lint. The `enumerate` call is in a different context.\n    macro_rules! mac {\n        () => {\n            [1].iter().enumerate()\n        };\n    }\n    _ = mac!().map(|(_, v)| v);\n\n    macro_rules! mac2 {\n        () => {\n            [1].iter()\n        };\n    }\n    _ = mac2!().enumerate().map(|(_, _v)| {});\n    //~^ unused_enumerate_index\n\n    // This shouldn't trigger the lint because of the `allow`.\n    #[allow(clippy::unused_enumerate_index)]\n    let v = [1].iter().enumerate();\n    v.map(|(_, _x)| {});\n\n    // This should keep the explicit type of `x`.\n    let v = [1, 2, 3].iter().copied().enumerate();\n    //~^ unused_enumerate_index\n    let x = v.map(|(_, x): (usize, i32)| x).sum::<i32>();\n    assert_eq!(x, 6);\n\n    // This should keep the explicit type of `x`.\n    let v = [1, 2, 3].iter().copied().enumerate();\n    //~^ unused_enumerate_index\n    let x = v.map(|(_, x): (_, i32)| x).sum::<i32>();\n    assert_eq!(x, 6);\n\n    let v = [1, 2, 3].iter().copied().enumerate();\n    //~^ unused_enumerate_index\n    let x = v.map(|(_, x)| x).sum::<i32>();\n    assert_eq!(x, 6);\n}\n"
  },
  {
    "path": "tests/ui/unused_enumerate_index.stderr",
    "content": "error: you seem to use `.enumerate()` and immediately discard the index\n  --> tests/ui/unused_enumerate_index.rs:12:27\n   |\nLL |     for (_, x) in v.iter().enumerate() {\n   |                           ^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unused-enumerate-index` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_enumerate_index)]`\nhelp: remove the `.enumerate()` call\n   |\nLL -     for (_, x) in v.iter().enumerate() {\nLL +     for x in v.iter() {\n   |\n\nerror: you seem to use `.enumerate()` and immediately discard the index\n  --> tests/ui/unused_enumerate_index.rs:60:24\n   |\nLL |     for (_, x) in dummy.enumerate() {\n   |                        ^^^^^^^^^^^^\n   |\nhelp: remove the `.enumerate()` call\n   |\nLL -     for (_, x) in dummy.enumerate() {\nLL +     for x in dummy {\n   |\n\nerror: you seem to use `.enumerate()` and immediately discard the index\n  --> tests/ui/unused_enumerate_index.rs:65:38\n   |\nLL |     let _ = vec![1, 2, 3].into_iter().enumerate().map(|(_, x)| println!(\"{x}\"));\n   |                                      ^^^^^^^^^^^^\n   |\nhelp: remove the `.enumerate()` call\n   |\nLL -     let _ = vec![1, 2, 3].into_iter().enumerate().map(|(_, x)| println!(\"{x}\"));\nLL +     let _ = vec![1, 2, 3].into_iter().map(|x| println!(\"{x}\"));\n   |\n\nerror: you seem to use `.enumerate()` and immediately discard the index\n  --> tests/ui/unused_enumerate_index.rs:68:38\n   |\nLL |     let p = vec![1, 2, 3].into_iter().enumerate();\n   |                                      ^^^^^^^^^^^^\n   |\nhelp: remove the `.enumerate()` call\n   |\nLL ~     let p = vec![1, 2, 3].into_iter();\nLL |\nLL ~     p.map(|x| println!(\"{x}\"));\n   |\n\nerror: you seem to use `.enumerate()` and immediately discard the index\n  --> tests/ui/unused_enumerate_index.rs:90:16\n   |\nLL |     _ = mac2!().enumerate().map(|(_, _v)| {});\n   |                ^^^^^^^^^^^^\n   |\nhelp: remove the `.enumerate()` call\n   |\nLL -     _ = mac2!().enumerate().map(|(_, _v)| {});\nLL +     _ = mac2!().map(|_v| {});\n   |\n\nerror: you seem to use `.enumerate()` and immediately discard the index\n  --> tests/ui/unused_enumerate_index.rs:99:38\n   |\nLL |     let v = [1, 2, 3].iter().copied().enumerate();\n   |                                      ^^^^^^^^^^^^\n   |\nhelp: remove the `.enumerate()` call\n   |\nLL ~     let v = [1, 2, 3].iter().copied();\nLL |\nLL ~     let x = v.map(|x: i32| x).sum::<i32>();\n   |\n\nerror: you seem to use `.enumerate()` and immediately discard the index\n  --> tests/ui/unused_enumerate_index.rs:105:38\n   |\nLL |     let v = [1, 2, 3].iter().copied().enumerate();\n   |                                      ^^^^^^^^^^^^\n   |\nhelp: remove the `.enumerate()` call\n   |\nLL ~     let v = [1, 2, 3].iter().copied();\nLL |\nLL ~     let x = v.map(|x: i32| x).sum::<i32>();\n   |\n\nerror: you seem to use `.enumerate()` and immediately discard the index\n  --> tests/ui/unused_enumerate_index.rs:110:38\n   |\nLL |     let v = [1, 2, 3].iter().copied().enumerate();\n   |                                      ^^^^^^^^^^^^\n   |\nhelp: remove the `.enumerate()` call\n   |\nLL ~     let v = [1, 2, 3].iter().copied();\nLL |\nLL ~     let x = v.map(|x| x).sum::<i32>();\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_format_specs.1.fixed",
    "content": "#![warn(clippy::unused_format_specs)]\n#![allow(unused)]\n\nmacro_rules! format_args_from_macro {\n    () => {\n        format_args!(\"from macro\")\n    };\n}\n\nfn main() {\n    // prints `.`, not `     .`\n    println!(\"{:5}.\", format!(\"\"));\n    //~^ unused_format_specs\n\n    //prints `abcde`, not `abc`\n    println!(\"{:.3}\", format!(\"abcde\"));\n    //~^ unused_format_specs\n\n    println!(\"{}.\", format_args_from_macro!());\n    //~^ unused_format_specs\n\n    let args = format_args!(\"\");\n    println!(\"{args}\");\n    //~^ unused_format_specs\n}\n\nfn should_not_lint() {\n    println!(\"{}\", format_args!(\"\"));\n    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use\n    // debug formatting so allow it\n    println!(\"{:?}\", format_args!(\"\"));\n\n    let args = format_args!(\"\");\n    println!(\"{args}\");\n}\n\n#[clippy::format_args]\nmacro_rules! usr_println {\n    ($target:expr, $($args:tt)*) => {{\n        if $target {\n            println!($($args)*)\n        }\n    }};\n}\n\nfn should_lint_user() {\n    // prints `.`, not `     .`\n    usr_println!(true, \"{:5}.\", format!(\"\"));\n    //~^ unused_format_specs\n\n    //prints `abcde`, not `abc`\n    usr_println!(true, \"{:.3}\", format!(\"abcde\"));\n    //~^ unused_format_specs\n\n    usr_println!(true, \"{}.\", format_args_from_macro!());\n    //~^ unused_format_specs\n\n    let args = format_args!(\"\");\n    usr_println!(true, \"{args}\");\n    //~^ unused_format_specs\n}\n\nfn should_not_lint_user() {\n    usr_println!(true, \"{}\", format_args!(\"\"));\n    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use\n    // debug formatting so allow it\n    usr_println!(true, \"{:?}\", format_args!(\"\"));\n\n    let args = format_args!(\"\");\n    usr_println!(true, \"{args}\");\n}\n"
  },
  {
    "path": "tests/ui/unused_format_specs.2.fixed",
    "content": "#![warn(clippy::unused_format_specs)]\n#![allow(unused)]\n\nmacro_rules! format_args_from_macro {\n    () => {\n        format_args!(\"from macro\")\n    };\n}\n\nfn main() {\n    // prints `.`, not `     .`\n    println!(\"{}.\", format_args!(\"\"));\n    //~^ unused_format_specs\n\n    //prints `abcde`, not `abc`\n    println!(\"{}\", format_args!(\"abcde\"));\n    //~^ unused_format_specs\n\n    println!(\"{}.\", format_args_from_macro!());\n    //~^ unused_format_specs\n\n    let args = format_args!(\"\");\n    println!(\"{args}\");\n    //~^ unused_format_specs\n}\n\nfn should_not_lint() {\n    println!(\"{}\", format_args!(\"\"));\n    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use\n    // debug formatting so allow it\n    println!(\"{:?}\", format_args!(\"\"));\n\n    let args = format_args!(\"\");\n    println!(\"{args}\");\n}\n\n#[clippy::format_args]\nmacro_rules! usr_println {\n    ($target:expr, $($args:tt)*) => {{\n        if $target {\n            println!($($args)*)\n        }\n    }};\n}\n\nfn should_lint_user() {\n    // prints `.`, not `     .`\n    usr_println!(true, \"{}.\", format_args!(\"\"));\n    //~^ unused_format_specs\n\n    //prints `abcde`, not `abc`\n    usr_println!(true, \"{}\", format_args!(\"abcde\"));\n    //~^ unused_format_specs\n\n    usr_println!(true, \"{}.\", format_args_from_macro!());\n    //~^ unused_format_specs\n\n    let args = format_args!(\"\");\n    usr_println!(true, \"{args}\");\n    //~^ unused_format_specs\n}\n\nfn should_not_lint_user() {\n    usr_println!(true, \"{}\", format_args!(\"\"));\n    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use\n    // debug formatting so allow it\n    usr_println!(true, \"{:?}\", format_args!(\"\"));\n\n    let args = format_args!(\"\");\n    usr_println!(true, \"{args}\");\n}\n"
  },
  {
    "path": "tests/ui/unused_format_specs.rs",
    "content": "#![warn(clippy::unused_format_specs)]\n#![allow(unused)]\n\nmacro_rules! format_args_from_macro {\n    () => {\n        format_args!(\"from macro\")\n    };\n}\n\nfn main() {\n    // prints `.`, not `     .`\n    println!(\"{:5}.\", format_args!(\"\"));\n    //~^ unused_format_specs\n\n    //prints `abcde`, not `abc`\n    println!(\"{:.3}\", format_args!(\"abcde\"));\n    //~^ unused_format_specs\n\n    println!(\"{:5}.\", format_args_from_macro!());\n    //~^ unused_format_specs\n\n    let args = format_args!(\"\");\n    println!(\"{args:5}\");\n    //~^ unused_format_specs\n}\n\nfn should_not_lint() {\n    println!(\"{}\", format_args!(\"\"));\n    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use\n    // debug formatting so allow it\n    println!(\"{:?}\", format_args!(\"\"));\n\n    let args = format_args!(\"\");\n    println!(\"{args}\");\n}\n\n#[clippy::format_args]\nmacro_rules! usr_println {\n    ($target:expr, $($args:tt)*) => {{\n        if $target {\n            println!($($args)*)\n        }\n    }};\n}\n\nfn should_lint_user() {\n    // prints `.`, not `     .`\n    usr_println!(true, \"{:5}.\", format_args!(\"\"));\n    //~^ unused_format_specs\n\n    //prints `abcde`, not `abc`\n    usr_println!(true, \"{:.3}\", format_args!(\"abcde\"));\n    //~^ unused_format_specs\n\n    usr_println!(true, \"{:5}.\", format_args_from_macro!());\n    //~^ unused_format_specs\n\n    let args = format_args!(\"\");\n    usr_println!(true, \"{args:5}\");\n    //~^ unused_format_specs\n}\n\nfn should_not_lint_user() {\n    usr_println!(true, \"{}\", format_args!(\"\"));\n    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use\n    // debug formatting so allow it\n    usr_println!(true, \"{:?}\", format_args!(\"\"));\n\n    let args = format_args!(\"\");\n    usr_println!(true, \"{args}\");\n}\n"
  },
  {
    "path": "tests/ui/unused_format_specs.stderr",
    "content": "error: format specifiers have no effect on `format_args!()`\n  --> tests/ui/unused_format_specs.rs:12:15\n   |\nLL |     println!(\"{:5}.\", format_args!(\"\"));\n   |               ^^^^\n   |\n   = note: `-D clippy::unused-format-specs` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_format_specs)]`\nhelp: for the width to apply consider using `format!()`\n   |\nLL -     println!(\"{:5}.\", format_args!(\"\"));\nLL +     println!(\"{:5}.\", format!(\"\"));\n   |\nhelp: if the current behavior is intentional, remove the format specifiers\n   |\nLL -     println!(\"{:5}.\", format_args!(\"\"));\nLL +     println!(\"{}.\", format_args!(\"\"));\n   |\n\nerror: format specifiers have no effect on `format_args!()`\n  --> tests/ui/unused_format_specs.rs:16:15\n   |\nLL |     println!(\"{:.3}\", format_args!(\"abcde\"));\n   |               ^^^^^\n   |\nhelp: for the precision to apply consider using `format!()`\n   |\nLL -     println!(\"{:.3}\", format_args!(\"abcde\"));\nLL +     println!(\"{:.3}\", format!(\"abcde\"));\n   |\nhelp: if the current behavior is intentional, remove the format specifiers\n   |\nLL -     println!(\"{:.3}\", format_args!(\"abcde\"));\nLL +     println!(\"{}\", format_args!(\"abcde\"));\n   |\n\nerror: format specifiers have no effect on `format_args!()`\n  --> tests/ui/unused_format_specs.rs:19:15\n   |\nLL |     println!(\"{:5}.\", format_args_from_macro!());\n   |               ^^^^\n   |\n   = help: for the width to apply consider using `format!()`\nhelp: if the current behavior is intentional, remove the format specifiers\n   |\nLL -     println!(\"{:5}.\", format_args_from_macro!());\nLL +     println!(\"{}.\", format_args_from_macro!());\n   |\n\nerror: format specifiers have no effect on `format_args!()`\n  --> tests/ui/unused_format_specs.rs:23:15\n   |\nLL |     println!(\"{args:5}\");\n   |               ^^^^^^^^\n   |\n   = help: for the width to apply consider using `format!()`\nhelp: if the current behavior is intentional, remove the format specifiers\n   |\nLL -     println!(\"{args:5}\");\nLL +     println!(\"{args}\");\n   |\n\nerror: format specifiers have no effect on `format_args!()`\n  --> tests/ui/unused_format_specs.rs:48:25\n   |\nLL |     usr_println!(true, \"{:5}.\", format_args!(\"\"));\n   |                         ^^^^\n   |\nhelp: for the width to apply consider using `format!()`\n   |\nLL -     usr_println!(true, \"{:5}.\", format_args!(\"\"));\nLL +     usr_println!(true, \"{:5}.\", format!(\"\"));\n   |\nhelp: if the current behavior is intentional, remove the format specifiers\n   |\nLL -     usr_println!(true, \"{:5}.\", format_args!(\"\"));\nLL +     usr_println!(true, \"{}.\", format_args!(\"\"));\n   |\n\nerror: format specifiers have no effect on `format_args!()`\n  --> tests/ui/unused_format_specs.rs:52:25\n   |\nLL |     usr_println!(true, \"{:.3}\", format_args!(\"abcde\"));\n   |                         ^^^^^\n   |\nhelp: for the precision to apply consider using `format!()`\n   |\nLL -     usr_println!(true, \"{:.3}\", format_args!(\"abcde\"));\nLL +     usr_println!(true, \"{:.3}\", format!(\"abcde\"));\n   |\nhelp: if the current behavior is intentional, remove the format specifiers\n   |\nLL -     usr_println!(true, \"{:.3}\", format_args!(\"abcde\"));\nLL +     usr_println!(true, \"{}\", format_args!(\"abcde\"));\n   |\n\nerror: format specifiers have no effect on `format_args!()`\n  --> tests/ui/unused_format_specs.rs:55:25\n   |\nLL |     usr_println!(true, \"{:5}.\", format_args_from_macro!());\n   |                         ^^^^\n   |\n   = help: for the width to apply consider using `format!()`\nhelp: if the current behavior is intentional, remove the format specifiers\n   |\nLL -     usr_println!(true, \"{:5}.\", format_args_from_macro!());\nLL +     usr_println!(true, \"{}.\", format_args_from_macro!());\n   |\n\nerror: format specifiers have no effect on `format_args!()`\n  --> tests/ui/unused_format_specs.rs:59:25\n   |\nLL |     usr_println!(true, \"{args:5}\");\n   |                         ^^^^^^^^\n   |\n   = help: for the width to apply consider using `format!()`\nhelp: if the current behavior is intentional, remove the format specifiers\n   |\nLL -     usr_println!(true, \"{args:5}\");\nLL +     usr_println!(true, \"{args}\");\n   |\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_io_amount.rs",
    "content": "#![allow(dead_code, clippy::needless_pass_by_ref_mut)]\n#![allow(clippy::redundant_pattern_matching)]\n#![warn(clippy::unused_io_amount)]\n\nextern crate futures;\nuse futures::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};\nuse std::io::{self, Read};\n\nfn question_mark<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {\n    s.write(b\"test\")?;\n    //~^ unused_io_amount\n    let mut buf = [0u8; 4];\n    s.read(&mut buf)?;\n    //~^ unused_io_amount\n    Ok(())\n}\n\nfn unwrap<T: io::Read + io::Write>(s: &mut T) {\n    s.write(b\"test\").unwrap();\n    //~^ unused_io_amount\n    let mut buf = [0u8; 4];\n    s.read(&mut buf).unwrap();\n    //~^ unused_io_amount\n}\n\nfn vectored<T: io::Read + io::Write>(s: &mut T) -> io::Result<()> {\n    s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?;\n    //~^ unused_io_amount\n    s.write_vectored(&[io::IoSlice::new(&[])])?;\n    //~^ unused_io_amount\n    Ok(())\n}\n\nfn ok(file: &str) -> Option<()> {\n    let mut reader = std::fs::File::open(file).ok()?;\n    let mut result = [0u8; 0];\n    reader.read(&mut result).ok()?;\n    //~^ unused_io_amount\n    Some(())\n}\n\n#[allow(clippy::redundant_closure)]\n#[allow(clippy::bind_instead_of_map)]\nfn or_else(file: &str) -> io::Result<()> {\n    let mut reader = std::fs::File::open(file)?;\n    let mut result = [0u8; 0];\n    reader.read(&mut result).or_else(|err| Err(err))?;\n    //~^ unused_io_amount\n    Ok(())\n}\n\n#[derive(Debug)]\nenum Error {\n    Kind,\n}\n\nfn or(file: &str) -> Result<(), Error> {\n    let mut reader = std::fs::File::open(file).unwrap();\n    let mut result = [0u8; 0];\n    reader.read(&mut result).or(Err(Error::Kind))?;\n    //~^ unused_io_amount\n    Ok(())\n}\n\nfn combine_or(file: &str) -> Result<(), Error> {\n    let mut reader = std::fs::File::open(file).unwrap();\n    let mut result = [0u8; 0];\n    reader\n        //~^ unused_io_amount\n        .read(&mut result)\n        .or(Err(Error::Kind))\n        .or(Err(Error::Kind))\n        .expect(\"error\");\n    Ok(())\n}\n\nfn is_ok_err<T: io::Read + io::Write>(s: &mut T) {\n    s.write(b\"ok\").is_ok();\n    //~^ unused_io_amount\n    s.write(b\"err\").is_err();\n    //~^ unused_io_amount\n    let mut buf = [0u8; 0];\n    s.read(&mut buf).is_ok();\n    //~^ unused_io_amount\n    s.read(&mut buf).is_err();\n    //~^ unused_io_amount\n}\n\nasync fn bad_async_write<W: AsyncWrite + Unpin>(w: &mut W) {\n    w.write(b\"hello world\").await.unwrap();\n    //~^ unused_io_amount\n}\n\nasync fn bad_async_read<R: AsyncRead + Unpin>(r: &mut R) {\n    let mut buf = [0u8; 0];\n    r.read(&mut buf[..]).await.unwrap();\n    //~^ unused_io_amount\n}\n\nasync fn io_not_ignored_async_write<W: AsyncWrite + Unpin>(mut w: W) {\n    // Here we're forgetting to await the future, so we should get a\n    // warning about _that_ (or we would, if it were enabled), but we\n    // won't get one about ignoring the return value.\n    w.write(b\"hello world\");\n    //~^ unused_io_amount\n}\n\nfn bad_async_write_closure<W: AsyncWrite + Unpin + 'static>(w: W) -> impl futures::Future<Output = io::Result<()>> {\n    let mut w = w;\n    async move {\n        w.write(b\"hello world\").await?;\n        //~^ unused_io_amount\n        Ok(())\n    }\n}\n\nasync fn async_read_nested_or<R: AsyncRead + Unpin>(r: &mut R, do_it: bool) -> Result<[u8; 1], Error> {\n    let mut buf = [0u8; 1];\n    if do_it {\n        r.read(&mut buf[..]).await.or(Err(Error::Kind))?;\n        //~^ unused_io_amount\n    }\n    Ok(buf)\n}\n\nuse tokio::io::{AsyncRead as TokioAsyncRead, AsyncReadExt as _, AsyncWrite as TokioAsyncWrite, AsyncWriteExt as _};\n\nasync fn bad_async_write_tokio<W: TokioAsyncWrite + Unpin>(w: &mut W) {\n    w.write(b\"hello world\").await.unwrap();\n    //~^ unused_io_amount\n}\n\nasync fn bad_async_read_tokio<R: TokioAsyncRead + Unpin>(r: &mut R) {\n    let mut buf = [0u8; 0];\n    r.read(&mut buf[..]).await.unwrap();\n    //~^ unused_io_amount\n}\n\nasync fn undetected_bad_async_write<W: AsyncWrite + Unpin>(w: &mut W) {\n    // It would be good to detect this case some day, but the current lint\n    // doesn't handle it. (The documentation says that this lint \"detects\n    // only common patterns\".)\n    let future = w.write(b\"Hello world\");\n    future.await.unwrap();\n}\n\nfn match_okay_underscore<T: io::Read + io::Write>(s: &mut T) {\n    match s.write(b\"test\") {\n        //~^ unused_io_amount\n        Ok(_) => todo!(),\n        Err(_) => todo!(),\n    };\n\n    let mut buf = [0u8; 4];\n    match s.read(&mut buf) {\n        //~^ unused_io_amount\n        Ok(_) => todo!(),\n        Err(_) => todo!(),\n    }\n}\n\nfn match_okay_underscore_read_expr<T: io::Read + io::Write>(s: &mut T) {\n    match s.read(&mut [0u8; 4]) {\n        //~^ unused_io_amount\n        Ok(_) => todo!(),\n        Err(_) => todo!(),\n    }\n}\n\nfn match_okay_underscore_write_expr<T: io::Read + io::Write>(s: &mut T) {\n    match s.write(b\"test\") {\n        //~^ unused_io_amount\n        Ok(_) => todo!(),\n        Err(_) => todo!(),\n    }\n}\n\nfn returned_value_should_not_lint<T: io::Read + io::Write>(s: &mut T) -> Result<usize, std::io::Error> {\n    s.write(b\"test\")\n}\n\nfn if_okay_underscore_read_expr<T: io::Read + io::Write>(s: &mut T) {\n    if let Ok(_) = s.read(&mut [0u8; 4]) {\n        //~^ unused_io_amount\n        todo!()\n    }\n}\n\nfn if_okay_underscore_write_expr<T: io::Read + io::Write>(s: &mut T) {\n    if let Ok(_) = s.write(b\"test\") {\n        //~^ unused_io_amount\n        todo!()\n    }\n}\n\nfn if_okay_dots_write_expr<T: io::Read + io::Write>(s: &mut T) {\n    if let Ok(..) = s.write(b\"test\") {\n        //~^ unused_io_amount\n        todo!()\n    }\n}\n\nfn if_okay_underscore_write_expr_true_negative<T: io::Read + io::Write>(s: &mut T) {\n    if let Ok(bound) = s.write(b\"test\") {\n        todo!()\n    }\n}\n\nfn match_okay_underscore_true_neg<T: io::Read + io::Write>(s: &mut T) {\n    match s.write(b\"test\") {\n        Ok(bound) => todo!(),\n        Err(_) => todo!(),\n    };\n}\n\nfn true_negative<T: io::Read + io::Write>(s: &mut T) {\n    let mut buf = [0u8; 4];\n    let read_amount = s.read(&mut buf).unwrap();\n}\n\nfn on_return_should_not_raise<T: io::Read + io::Write>(s: &mut T) -> io::Result<usize> {\n    /// this is bad code because it goes around the problem of handling the read amount\n    /// by returning it, which makes it impossible to know this is a resonpose from the\n    /// correct account.\n    let mut buf = [0u8; 4];\n    s.read(&mut buf)\n}\n\npub fn unwrap_in_block(rdr: &mut dyn std::io::Read) -> std::io::Result<usize> {\n    let read = { rdr.read(&mut [0])? };\n    Ok(read)\n}\n\npub fn consumed_example(rdr: &mut dyn std::io::Read) {\n    match rdr.read(&mut [0]) {\n        Ok(0) => println!(\"EOF\"),\n        Ok(_) => println!(\"fully read\"),\n        Err(_) => println!(\"fail\"),\n    };\n    match rdr.read(&mut [0]) {\n        Ok(0) => println!(\"EOF\"),\n        Ok(_) => println!(\"fully read\"),\n        Err(_) => println!(\"fail\"),\n    }\n}\n\npub fn unreachable_or_panic(rdr: &mut dyn std::io::Read) {\n    {\n        match rdr.read(&mut [0]) {\n            Ok(_) => unreachable!(),\n            Err(_) => println!(\"expected\"),\n        }\n    }\n\n    {\n        match rdr.read(&mut [0]) {\n            Ok(_) => panic!(),\n            Err(_) => println!(\"expected\"),\n        }\n    }\n}\n\npub fn wildcards(rdr: &mut dyn std::io::Read) {\n    {\n        match rdr.read(&mut [0]) {\n            Ok(1) => todo!(),\n            _ => todo!(),\n        }\n    }\n}\nfn allow_works<F: std::io::Read>(mut f: F) {\n    let mut data = Vec::with_capacity(100);\n    #[allow(clippy::unused_io_amount)]\n    f.read(&mut data).unwrap();\n}\n\nstruct Reader {}\n\nimpl Read for Reader {\n    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n        todo!()\n    }\n\n    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {\n        // We shouldn't recommend using Read::read_exact inside Read::read_exact!\n        self.read(buf).unwrap();\n        Ok(())\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unused_io_amount.stderr",
    "content": "error: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:10:5\n   |\nLL |     s.write(b\"test\")?;\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Write::write_all` instead, or handle partial writes\n   = note: `-D clippy::unused-io-amount` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_io_amount)]`\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:13:5\n   |\nLL |     s.read(&mut buf)?;\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:19:5\n   |\nLL |     s.write(b\"test\").unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Write::write_all` instead, or handle partial writes\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:22:5\n   |\nLL |     s.read(&mut buf).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:27:5\n   |\nLL |     s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:29:5\n   |\nLL |     s.write_vectored(&[io::IoSlice::new(&[])])?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:37:5\n   |\nLL |     reader.read(&mut result).ok()?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:47:5\n   |\nLL |     reader.read(&mut result).or_else(|err| Err(err))?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:60:5\n   |\nLL |     reader.read(&mut result).or(Err(Error::Kind))?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:68:5\n   |\nLL | /     reader\nLL | |\nLL | |         .read(&mut result)\nLL | |         .or(Err(Error::Kind))\nLL | |         .or(Err(Error::Kind))\nLL | |         .expect(\"error\");\n   | |________________________^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:78:5\n   |\nLL |     s.write(b\"ok\").is_ok();\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Write::write_all` instead, or handle partial writes\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:80:5\n   |\nLL |     s.write(b\"err\").is_err();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Write::write_all` instead, or handle partial writes\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:83:5\n   |\nLL |     s.read(&mut buf).is_ok();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:85:5\n   |\nLL |     s.read(&mut buf).is_err();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:90:5\n   |\nLL |     w.write(b\"hello world\").await.unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `AsyncWriteExt::write_all` instead, or handle partial writes\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:96:5\n   |\nLL |     r.read(&mut buf[..]).await.unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `AsyncReadExt::read_exact` instead, or handle partial reads\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:104:5\n   |\nLL |     w.write(b\"hello world\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `AsyncWriteExt::write_all` instead, or handle partial writes\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:111:9\n   |\nLL |         w.write(b\"hello world\").await?;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `AsyncWriteExt::write_all` instead, or handle partial writes\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:120:9\n   |\nLL |         r.read(&mut buf[..]).await.or(Err(Error::Kind))?;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `AsyncReadExt::read_exact` instead, or handle partial reads\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:129:5\n   |\nLL |     w.write(b\"hello world\").await.unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `AsyncWriteExt::write_all` instead, or handle partial writes\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:135:5\n   |\nLL |     r.read(&mut buf[..]).await.unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `AsyncReadExt::read_exact` instead, or handle partial reads\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:148:11\n   |\nLL |     match s.write(b\"test\") {\n   |           ^^^^^^^^^^^^^^^^\n   |\n   = help: use `Write::write_all` instead, or handle partial writes\nnote: the result is consumed here, but the amount of I/O bytes remains unhandled\n  --> tests/ui/unused_io_amount.rs:150:9\n   |\nLL |         Ok(_) => todo!(),\n   |         ^^^^^\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:155:11\n   |\nLL |     match s.read(&mut buf) {\n   |           ^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\nnote: the result is consumed here, but the amount of I/O bytes remains unhandled\n  --> tests/ui/unused_io_amount.rs:157:9\n   |\nLL |         Ok(_) => todo!(),\n   |         ^^^^^\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:163:11\n   |\nLL |     match s.read(&mut [0u8; 4]) {\n   |           ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\nnote: the result is consumed here, but the amount of I/O bytes remains unhandled\n  --> tests/ui/unused_io_amount.rs:165:9\n   |\nLL |         Ok(_) => todo!(),\n   |         ^^^^^\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:171:11\n   |\nLL |     match s.write(b\"test\") {\n   |           ^^^^^^^^^^^^^^^^\n   |\n   = help: use `Write::write_all` instead, or handle partial writes\nnote: the result is consumed here, but the amount of I/O bytes remains unhandled\n  --> tests/ui/unused_io_amount.rs:173:9\n   |\nLL |         Ok(_) => todo!(),\n   |         ^^^^^\n\nerror: read amount is not handled\n  --> tests/ui/unused_io_amount.rs:183:8\n   |\nLL |     if let Ok(_) = s.read(&mut [0u8; 4]) {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Read::read_exact` instead, or handle partial reads\nnote: the result is consumed here, but the amount of I/O bytes remains unhandled\n  --> tests/ui/unused_io_amount.rs:183:12\n   |\nLL |     if let Ok(_) = s.read(&mut [0u8; 4]) {\n   |            ^^^^^\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:190:8\n   |\nLL |     if let Ok(_) = s.write(b\"test\") {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Write::write_all` instead, or handle partial writes\nnote: the result is consumed here, but the amount of I/O bytes remains unhandled\n  --> tests/ui/unused_io_amount.rs:190:12\n   |\nLL |     if let Ok(_) = s.write(b\"test\") {\n   |            ^^^^^\n\nerror: written amount is not handled\n  --> tests/ui/unused_io_amount.rs:197:8\n   |\nLL |     if let Ok(..) = s.write(b\"test\") {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: use `Write::write_all` instead, or handle partial writes\nnote: the result is consumed here, but the amount of I/O bytes remains unhandled\n  --> tests/ui/unused_io_amount.rs:197:12\n   |\nLL |     if let Ok(..) = s.write(b\"test\") {\n   |            ^^^^^^\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_peekable.rs",
    "content": "#![warn(clippy::unused_peekable)]\n#![allow(clippy::no_effect)]\n\nuse std::iter::{Empty, Peekable};\n\nfn main() {}\n\n#[allow(clippy::unused_unit)]\nfn invalid() {\n    let peekable = std::iter::empty::<u32>().peekable();\n    //~^ unused_peekable\n\n    // Only lint `new_local`\n    let old_local = std::iter::empty::<u32>().peekable();\n    let new_local = old_local;\n    //~^ unused_peekable\n\n    // Behind mut ref\n    let mut by_mut_ref_test = std::iter::empty::<u32>().peekable();\n    let by_mut_ref = &mut by_mut_ref_test;\n    //~^ unused_peekable\n\n    // Explicitly returns `Peekable`\n    fn returns_peekable() -> Peekable<Empty<u32>> {\n        std::iter::empty().peekable()\n    }\n\n    let peekable_from_fn = returns_peekable();\n    //~^ unused_peekable\n\n    // Using a method not exclusive to `Peekable`\n    let mut peekable_using_iterator_method = std::iter::empty::<u32>().peekable();\n    //~^ unused_peekable\n\n    peekable_using_iterator_method.next();\n\n    // Passed by ref to another function\n    fn takes_ref(_peek: &Peekable<Empty<u32>>) {}\n    let passed_along_ref = std::iter::empty::<u32>().peekable();\n    //~^ unused_peekable\n\n    takes_ref(&passed_along_ref);\n\n    // `by_ref` without `peek`\n    let mut by_ref_test = std::iter::empty::<u32>().peekable();\n    let _by_ref = by_ref_test.by_ref();\n    //~^ unused_peekable\n\n    let mut peekable_in_for_loop = std::iter::empty::<u32>().peekable();\n    //~^ unused_peekable\n\n    for x in peekable_in_for_loop {}\n}\n\nfn valid() {\n    fn takes_peekable(_peek: Peekable<Empty<u32>>) {}\n\n    // Passed to another function\n    let passed_along = std::iter::empty::<u32>().peekable();\n    takes_peekable(passed_along);\n\n    // Passed to another method\n    struct PeekableConsumer;\n    impl PeekableConsumer {\n        fn consume(&self, _: Peekable<Empty<u32>>) {}\n        fn consume_mut_ref(&self, _: &mut Peekable<Empty<u32>>) {}\n        fn consume_assoc(_: Peekable<Empty<u32>>) {}\n        fn consume_assoc_mut_ref(_: &mut Peekable<Empty<u32>>) {}\n    }\n    let peekable_consumer = PeekableConsumer;\n\n    let peekable = std::iter::empty::<u32>().peekable();\n    peekable_consumer.consume(peekable);\n\n    let mut peekable = std::iter::empty::<u32>().peekable();\n    peekable_consumer.consume_mut_ref(&mut peekable);\n\n    let peekable = std::iter::empty::<u32>().peekable();\n    PeekableConsumer::consume_assoc(peekable);\n\n    let mut peekable = std::iter::empty::<u32>().peekable();\n    PeekableConsumer::consume_assoc_mut_ref(&mut peekable);\n\n    // `peek` called in another block\n    let mut peekable_in_block = std::iter::empty::<u32>().peekable();\n    {\n        peekable_in_block.peek();\n    }\n\n    // Check the other `Peekable` methods :)\n    {\n        let mut peekable_with_peek_mut = std::iter::empty::<u32>().peekable();\n        peekable_with_peek_mut.peek_mut();\n\n        let mut peekable_with_next_if = std::iter::empty::<u32>().peekable();\n        peekable_with_next_if.next_if(|_| true);\n\n        let mut peekable_with_next_if_eq = std::iter::empty::<u32>().peekable();\n        peekable_with_next_if_eq.next_if_eq(&3);\n    }\n\n    let mut peekable_in_closure = std::iter::empty::<u32>().peekable();\n    let call_peek = |p: &mut Peekable<Empty<u32>>| {\n        p.peek();\n    };\n    call_peek(&mut peekable_in_closure);\n\n    // From a macro\n    macro_rules! make_me_a_peekable_please {\n        () => {\n            std::iter::empty::<u32>().peekable()\n        };\n    }\n\n    let _unsuspecting_macro_user = make_me_a_peekable_please!();\n\n    // Generic Iterator returned\n    fn return_an_iter() -> impl Iterator<Item = u32> {\n        std::iter::empty::<u32>().peekable()\n    }\n\n    let _unsuspecting_user = return_an_iter();\n\n    // Call `peek` in a macro\n    macro_rules! peek_iter {\n        ($iter:ident) => {\n            $iter.peek();\n        };\n    }\n\n    let mut peek_in_macro = std::iter::empty::<u32>().peekable();\n    peek_iter!(peek_in_macro);\n\n    // Behind mut ref\n    let mut by_mut_ref_test = std::iter::empty::<u32>().peekable();\n    let by_mut_ref = &mut by_mut_ref_test;\n    by_mut_ref.peek();\n\n    // Behind ref\n    let mut by_ref_test = std::iter::empty::<u32>().peekable();\n    let by_ref = &by_ref_test;\n    by_ref_test.peek();\n\n    // In struct\n    struct PeekableWrapper {\n        f: Peekable<Empty<u32>>,\n    }\n\n    let struct_test = std::iter::empty::<u32>().peekable();\n    PeekableWrapper { f: struct_test };\n\n    // `by_ref` before `peek`\n    let mut by_ref_test = std::iter::empty::<u32>().peekable();\n    let peeked_val = by_ref_test.by_ref().peek();\n\n    // `peek` called in another block as the last expression\n    let mut peekable_last_expr = std::iter::empty::<u32>().peekable();\n    {\n        peekable_last_expr.peek();\n    }\n\n    let mut peek_in_closure = std::iter::empty::<u32>().peekable();\n    let _ = || {\n        let _ = peek_in_closure.peek();\n    };\n\n    trait PeekTrait {}\n    impl<I> PeekTrait for Peekable<I> where I: Iterator {}\n\n    let mut peekable = std::iter::empty::<u32>().peekable();\n    let _dyn = &mut peekable as &mut dyn PeekTrait;\n\n    fn takes_dyn(_: &mut dyn PeekTrait) {}\n    let mut peekable = std::iter::empty::<u32>().peekable();\n    takes_dyn(&mut peekable);\n}\n\nfn allow_works() {\n    #[allow(clippy::unused_peekable)]\n    let iter = [1, 2, 3].iter().peekable();\n    iter;\n}\n"
  },
  {
    "path": "tests/ui/unused_peekable.stderr",
    "content": "error: `peek` never called on `Peekable` iterator\n  --> tests/ui/unused_peekable.rs:10:9\n   |\nLL |     let peekable = std::iter::empty::<u32>().peekable();\n   |         ^^^^^^^^\n   |\n   = help: consider removing the call to `peekable`\n   = note: `-D clippy::unused-peekable` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_peekable)]`\n\nerror: `peek` never called on `Peekable` iterator\n  --> tests/ui/unused_peekable.rs:15:9\n   |\nLL |     let new_local = old_local;\n   |         ^^^^^^^^^\n   |\n   = help: consider removing the call to `peekable`\n\nerror: `peek` never called on `Peekable` iterator\n  --> tests/ui/unused_peekable.rs:20:9\n   |\nLL |     let by_mut_ref = &mut by_mut_ref_test;\n   |         ^^^^^^^^^^\n   |\n   = help: consider removing the call to `peekable`\n\nerror: `peek` never called on `Peekable` iterator\n  --> tests/ui/unused_peekable.rs:28:9\n   |\nLL |     let peekable_from_fn = returns_peekable();\n   |         ^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing the call to `peekable`\n\nerror: `peek` never called on `Peekable` iterator\n  --> tests/ui/unused_peekable.rs:32:13\n   |\nLL |     let mut peekable_using_iterator_method = std::iter::empty::<u32>().peekable();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing the call to `peekable`\n\nerror: `peek` never called on `Peekable` iterator\n  --> tests/ui/unused_peekable.rs:39:9\n   |\nLL |     let passed_along_ref = std::iter::empty::<u32>().peekable();\n   |         ^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing the call to `peekable`\n\nerror: `peek` never called on `Peekable` iterator\n  --> tests/ui/unused_peekable.rs:46:9\n   |\nLL |     let _by_ref = by_ref_test.by_ref();\n   |         ^^^^^^^\n   |\n   = help: consider removing the call to `peekable`\n\nerror: `peek` never called on `Peekable` iterator\n  --> tests/ui/unused_peekable.rs:49:13\n   |\nLL |     let mut peekable_in_for_loop = std::iter::empty::<u32>().peekable();\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing the call to `peekable`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_result_ok.fixed",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::unused_result_ok)]\n#![allow(dead_code)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn bad_style(x: &str) {\n    let _ = x.parse::<u32>();\n    //~^ unused_result_ok\n}\n\nfn good_style(x: &str) -> Option<u32> {\n    x.parse::<u32>().ok()\n}\n\n#[rustfmt::skip]\nfn strange_parse(x: &str) {\n    let _ = x   .   parse::<i32>();\n    //~^ unused_result_ok\n}\n\nmacro_rules! v {\n    () => {\n        Ok::<(), ()>(())\n    };\n}\n\nmacro_rules! w {\n    () => {\n        let _ = Ok::<(), ()>(());\n        //~^ unused_result_ok\n    };\n}\n\nfn main() {\n    let _ = v!();\n    //~^ unused_result_ok\n    w!();\n\n    external! {\n        Ok::<(),()>(()).ok();\n    };\n}\n"
  },
  {
    "path": "tests/ui/unused_result_ok.rs",
    "content": "//@aux-build:proc_macros.rs\n#![warn(clippy::unused_result_ok)]\n#![allow(dead_code)]\n\n#[macro_use]\nextern crate proc_macros;\n\nfn bad_style(x: &str) {\n    x.parse::<u32>().ok();\n    //~^ unused_result_ok\n}\n\nfn good_style(x: &str) -> Option<u32> {\n    x.parse::<u32>().ok()\n}\n\n#[rustfmt::skip]\nfn strange_parse(x: &str) {\n    x   .   parse::<i32>()   .   ok   ();\n    //~^ unused_result_ok\n}\n\nmacro_rules! v {\n    () => {\n        Ok::<(), ()>(())\n    };\n}\n\nmacro_rules! w {\n    () => {\n        Ok::<(), ()>(()).ok();\n        //~^ unused_result_ok\n    };\n}\n\nfn main() {\n    v!().ok();\n    //~^ unused_result_ok\n    w!();\n\n    external! {\n        Ok::<(),()>(()).ok();\n    };\n}\n"
  },
  {
    "path": "tests/ui/unused_result_ok.stderr",
    "content": "error: ignoring a result with `.ok()` is misleading\n  --> tests/ui/unused_result_ok.rs:9:5\n   |\nLL |     x.parse::<u32>().ok();\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unused-result-ok` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_result_ok)]`\nhelp: consider using `let _ =` and removing the call to `.ok()` instead\n   |\nLL -     x.parse::<u32>().ok();\nLL +     let _ = x.parse::<u32>();\n   |\n\nerror: ignoring a result with `.ok()` is misleading\n  --> tests/ui/unused_result_ok.rs:19:5\n   |\nLL |     x   .   parse::<i32>()   .   ok   ();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using `let _ =` and removing the call to `.ok()` instead\n   |\nLL -     x   .   parse::<i32>()   .   ok   ();\nLL +     let _ = x   .   parse::<i32>();\n   |\n\nerror: ignoring a result with `.ok()` is misleading\n  --> tests/ui/unused_result_ok.rs:37:5\n   |\nLL |     v!().ok();\n   |     ^^^^^^^^^\n   |\nhelp: consider using `let _ =` and removing the call to `.ok()` instead\n   |\nLL -     v!().ok();\nLL +     let _ = v!();\n   |\n\nerror: ignoring a result with `.ok()` is misleading\n  --> tests/ui/unused_result_ok.rs:31:9\n   |\nLL |         Ok::<(), ()>(()).ok();\n   |         ^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     w!();\n   |     ---- in this macro invocation\n   |\n   = note: this error originates in the macro `w` (in Nightly builds, run with -Z macro-backtrace for more info)\nhelp: consider using `let _ =` and removing the call to `.ok()` instead\n   |\nLL -         Ok::<(), ()>(()).ok();\nLL +         let _ = Ok::<(), ()>(());\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_rounding.fixed",
    "content": "// FIXME(f16_f128): add tests when math functions are available\n\n#![warn(clippy::unused_rounding)]\n\nfn main() {\n    let _ = 1f32;\n    //~^ unused_rounding\n    let _ = 1.0f64;\n    //~^ unused_rounding\n    let _ = 1.00f32;\n    //~^ unused_rounding\n    let _ = 2e-54f64.floor();\n\n    // issue9866\n    let _ = 3.3_f32.round();\n    let _ = 3.3_f64.round();\n    let _ = 3.0_f32;\n    //~^ unused_rounding\n\n    let _ = 3_3.0_0_f32;\n    //~^ unused_rounding\n    let _ = 3_3.0_1_f64.round();\n}\n"
  },
  {
    "path": "tests/ui/unused_rounding.rs",
    "content": "// FIXME(f16_f128): add tests when math functions are available\n\n#![warn(clippy::unused_rounding)]\n\nfn main() {\n    let _ = 1f32.ceil();\n    //~^ unused_rounding\n    let _ = 1.0f64.floor();\n    //~^ unused_rounding\n    let _ = 1.00f32.round();\n    //~^ unused_rounding\n    let _ = 2e-54f64.floor();\n\n    // issue9866\n    let _ = 3.3_f32.round();\n    let _ = 3.3_f64.round();\n    let _ = 3.0_f32.round();\n    //~^ unused_rounding\n\n    let _ = 3_3.0_0_f32.round();\n    //~^ unused_rounding\n    let _ = 3_3.0_1_f64.round();\n}\n"
  },
  {
    "path": "tests/ui/unused_rounding.stderr",
    "content": "error: used the `ceil` method with a whole number float\n  --> tests/ui/unused_rounding.rs:6:13\n   |\nLL |     let _ = 1f32.ceil();\n   |             ^^^^^^^^^^^ help: remove the `ceil` method call: `1f32`\n   |\n   = note: `-D clippy::unused-rounding` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_rounding)]`\n\nerror: used the `floor` method with a whole number float\n  --> tests/ui/unused_rounding.rs:8:13\n   |\nLL |     let _ = 1.0f64.floor();\n   |             ^^^^^^^^^^^^^^ help: remove the `floor` method call: `1.0f64`\n\nerror: used the `round` method with a whole number float\n  --> tests/ui/unused_rounding.rs:10:13\n   |\nLL |     let _ = 1.00f32.round();\n   |             ^^^^^^^^^^^^^^^ help: remove the `round` method call: `1.00f32`\n\nerror: used the `round` method with a whole number float\n  --> tests/ui/unused_rounding.rs:17:13\n   |\nLL |     let _ = 3.0_f32.round();\n   |             ^^^^^^^^^^^^^^^ help: remove the `round` method call: `3.0_f32`\n\nerror: used the `round` method with a whole number float\n  --> tests/ui/unused_rounding.rs:20:13\n   |\nLL |     let _ = 3_3.0_0_f32.round();\n   |             ^^^^^^^^^^^^^^^^^^^ help: remove the `round` method call: `3_3.0_0_f32`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_self.rs",
    "content": "#![warn(clippy::unused_self)]\n#![allow(clippy::boxed_local, clippy::fn_params_excessive_bools)]\n\nmod unused_self {\n    use std::pin::Pin;\n    use std::sync::{Arc, Mutex};\n\n    struct A;\n\n    impl A {\n        fn unused_self_move(self) {}\n        //~^ unused_self\n\n        fn unused_self_ref(&self) {}\n        //~^ unused_self\n\n        fn unused_self_mut_ref(&mut self) {}\n        //~^ unused_self\n\n        fn unused_self_pin_ref(self: Pin<&Self>) {}\n        //~^ unused_self\n\n        fn unused_self_pin_mut_ref(self: Pin<&mut Self>) {}\n        //~^ unused_self\n\n        fn unused_self_pin_nested(self: Pin<Arc<Self>>) {}\n        //~^ unused_self\n\n        fn unused_self_box(self: Box<Self>) {}\n        //~^ unused_self\n\n        fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 {\n            //~^ unused_self\n\n            x + y\n        }\n        fn unused_self_class_method(&self) {\n            //~^ unused_self\n\n            Self::static_method();\n        }\n\n        fn static_method() {}\n    }\n}\n\nmod unused_self_allow {\n    struct A;\n\n    impl A {\n        // shouldn't trigger\n        #[allow(clippy::unused_self)]\n        fn unused_self_move(self) {}\n    }\n\n    struct B;\n\n    // shouldn't trigger\n    #[allow(clippy::unused_self)]\n    impl B {\n        fn unused_self_move(self) {}\n    }\n\n    struct C;\n\n    #[allow(clippy::unused_self)]\n    impl C {\n        #[warn(clippy::unused_self)]\n        fn some_fn((): ()) {}\n\n        // shouldn't trigger\n        fn unused_self_move(self) {}\n    }\n\n    pub struct D;\n\n    impl D {\n        // shouldn't trigger for public methods\n        pub fn unused_self_move(self) {}\n    }\n\n    pub struct E;\n\n    impl E {\n        // shouldn't trigger if body contains todo!()\n        pub fn unused_self_todo(self) {\n            let x = 42;\n            todo!()\n        }\n    }\n}\n\npub use unused_self_allow::D;\n\nmod used_self {\n    use std::pin::Pin;\n\n    struct A {\n        x: u8,\n    }\n\n    impl A {\n        fn used_self_move(self) -> u8 {\n            self.x\n        }\n        fn used_self_ref(&self) -> u8 {\n            self.x\n        }\n        fn used_self_mut_ref(&mut self) {\n            self.x += 1\n        }\n        fn used_self_pin_ref(self: Pin<&Self>) -> u8 {\n            self.x\n        }\n        fn used_self_box(self: Box<Self>) -> u8 {\n            self.x\n        }\n        fn used_self_with_other_unused_args(&self, x: u8, y: u8) -> u8 {\n            self.x\n        }\n        fn used_in_nested_closure(&self) -> u8 {\n            let mut a = || -> u8 { self.x };\n            a()\n        }\n\n        #[allow(clippy::collapsible_if)]\n        fn used_self_method_nested_conditions(&self, a: bool, b: bool, c: bool, d: bool) {\n            if a {\n                if b {\n                    if c {\n                        if d {\n                            self.used_self_ref();\n                        }\n                    }\n                }\n            }\n        }\n\n        fn foo(&self) -> u32 {\n            let mut sum = 0u32;\n            for i in 0..self.x {\n                sum += i as u32;\n            }\n            sum\n        }\n\n        fn bar(&mut self, x: u8) -> u32 {\n            let mut y = 0u32;\n            for i in 0..x {\n                y += self.foo()\n            }\n            y\n        }\n    }\n}\n\nmod not_applicable {\n    use std::fmt;\n\n    struct A;\n\n    impl fmt::Debug for A {\n        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n            write!(f, \"A\")\n        }\n    }\n\n    impl A {\n        fn method(x: u8, y: u8) {}\n    }\n\n    trait B {\n        fn method(&self) {}\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unused_self.stderr",
    "content": "error: unused `self` argument\n  --> tests/ui/unused_self.rs:11:29\n   |\nLL |         fn unused_self_move(self) {}\n   |                             ^^^^\n   |\n   = help: consider refactoring to an associated function\n   = note: `-D clippy::unused-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_self)]`\n\nerror: unused `self` argument\n  --> tests/ui/unused_self.rs:14:28\n   |\nLL |         fn unused_self_ref(&self) {}\n   |                            ^^^^^\n   |\n   = help: consider refactoring to an associated function\n\nerror: unused `self` argument\n  --> tests/ui/unused_self.rs:17:32\n   |\nLL |         fn unused_self_mut_ref(&mut self) {}\n   |                                ^^^^^^^^^\n   |\n   = help: consider refactoring to an associated function\n\nerror: unused `self` argument\n  --> tests/ui/unused_self.rs:20:32\n   |\nLL |         fn unused_self_pin_ref(self: Pin<&Self>) {}\n   |                                ^^^^\n   |\n   = help: consider refactoring to an associated function\n\nerror: unused `self` argument\n  --> tests/ui/unused_self.rs:23:36\n   |\nLL |         fn unused_self_pin_mut_ref(self: Pin<&mut Self>) {}\n   |                                    ^^^^\n   |\n   = help: consider refactoring to an associated function\n\nerror: unused `self` argument\n  --> tests/ui/unused_self.rs:26:35\n   |\nLL |         fn unused_self_pin_nested(self: Pin<Arc<Self>>) {}\n   |                                   ^^^^\n   |\n   = help: consider refactoring to an associated function\n\nerror: unused `self` argument\n  --> tests/ui/unused_self.rs:29:28\n   |\nLL |         fn unused_self_box(self: Box<Self>) {}\n   |                            ^^^^\n   |\n   = help: consider refactoring to an associated function\n\nerror: unused `self` argument\n  --> tests/ui/unused_self.rs:32:40\n   |\nLL |         fn unused_with_other_used_args(&self, x: u8, y: u8) -> u8 {\n   |                                        ^^^^^\n   |\n   = help: consider refactoring to an associated function\n\nerror: unused `self` argument\n  --> tests/ui/unused_self.rs:37:37\n   |\nLL |         fn unused_self_class_method(&self) {\n   |                                     ^^^^^\n   |\n   = help: consider refactoring to an associated function\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_trait_names.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![allow(unused)]\n#![warn(clippy::unused_trait_names)]\n#![feature(decl_macro)]\n\nextern crate proc_macros;\n\nfn main() {}\n\nfn bad() {\n    use std::any::Any as _;\n    //~^ unused_trait_names\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn good() {\n    use std::any::Any as _;\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn used_good() {\n    use std::any::Any;\n\n    println!(\"{:?}\", Any::type_id(\"foo\"));\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn multi_bad() {\n    use std::any::{self, Any as _, TypeId};\n    //~^ unused_trait_names\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn multi_good() {\n    use std::any::{self, Any as _, TypeId};\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn renamed_bad() {\n    use std::any::Any as _;\n    //~^ unused_trait_names\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn multi_renamed_bad() {\n    use std::any::{Any as _, TypeId as MyTypeId};\n    //~^ unused_trait_names\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nmod pub_good {\n    pub use std::any::Any;\n\n    fn foo() {\n        println!(\"{:?}\", \"foo\".type_id());\n    }\n}\n\nmod used_mod_good {\n    use std::any::Any;\n\n    fn foo() {\n        println!(\"{:?}\", Any::type_id(\"foo\"));\n    }\n}\n\nmod mod_import_bad {\n    fn mod_import_bad() {\n        use std::any::Any as _;\n        //~^ unused_trait_names\n\n        println!(\"{:?}\", \"foo\".type_id());\n    }\n}\n\nmod nested_mod_used_good1 {\n    use std::any::Any;\n\n    mod foo {\n        fn foo() {\n            super::Any::type_id(\"foo\");\n        }\n    }\n}\n\nmod nested_mod_used_good2 {\n    use std::any::Any;\n\n    mod foo {\n        use super::Any;\n\n        fn foo() {\n            Any::type_id(\"foo\");\n        }\n    }\n}\n\nmod nested_mod_used_good3 {\n    use std::any::Any;\n\n    mod foo {\n        use crate::nested_mod_used_good3::Any;\n\n        fn foo() {\n            println!(\"{:?}\", Any::type_id(\"foo\"));\n        }\n    }\n}\n\nmod nested_mod_used_bad {\n    use std::any::Any as _;\n    //~^ unused_trait_names\n\n    fn bar() {\n        println!(\"{:?}\", \"foo\".type_id());\n    }\n\n    mod foo {\n        use std::any::Any;\n\n        fn foo() {\n            println!(\"{:?}\", Any::type_id(\"foo\"));\n        }\n    }\n}\n\n// More complex example where `use std::any::Any;` should be anonymised but `use std::any::Any as\n// MyAny;` should not as it is used by a sub module. Even though if you removed `use std::any::Any;`\n// the code would still compile.\nmod nested_mod_used_bad1 {\n    use std::any::Any as _;\n    //~^ unused_trait_names\n\n    use std::any::Any as MyAny;\n\n    fn baz() {\n        println!(\"{:?}\", \"baz\".type_id());\n    }\n\n    mod foo {\n        use crate::nested_mod_used_bad1::MyAny;\n\n        fn foo() {\n            println!(\"{:?}\", MyAny::type_id(\"foo\"));\n        }\n    }\n}\n\n// Example of nested import with an unused import to try and trick it\nmod nested_mod_used_good5 {\n    use std::any::Any;\n\n    mod foo {\n        use std::any::Any;\n\n        fn baz() {\n            println!(\"{:?}\", \"baz\".type_id());\n        }\n\n        mod bar {\n            use crate::nested_mod_used_good5::foo::Any;\n\n            fn foo() {\n                println!(\"{:?}\", Any::type_id(\"foo\"));\n            }\n        }\n    }\n}\n\nmod simple_trait {\n    pub trait MyTrait {\n        fn do_things(&self);\n    }\n\n    pub struct MyStruct;\n\n    impl MyTrait for MyStruct {\n        fn do_things(&self) {}\n    }\n}\n\n// Underscore imports were stabilized in 1.33\n#[clippy::msrv = \"1.32\"]\nfn msrv_1_32() {\n    use simple_trait::{MyStruct, MyTrait};\n    MyStruct.do_things();\n}\n\n#[clippy::msrv = \"1.33\"]\nfn msrv_1_33() {\n    use simple_trait::{MyStruct, MyTrait as _};\n    //~^ unused_trait_names\n    MyStruct.do_things();\n}\n\n// Linting inside macro expansion is no longer supported\nmod lint_inside_macro_expansion_bad {\n    macro_rules! foo {\n        () => {\n            use std::any::Any;\n            fn bar() {\n                \"bar\".type_id();\n            }\n        };\n    }\n\n    foo!();\n}\n\nmod macro_and_trait_same_name {\n    pub macro Foo() {}\n    pub trait Foo {\n        fn bar(&self);\n    }\n    impl Foo for () {\n        fn bar(&self) {}\n    }\n}\n\nfn call_macro_and_trait_good() {\n    // importing trait and macro but only using macro by path won't allow us to change this to\n    // `use macro_and_trait_same_name::Foo as _;`\n    use macro_and_trait_same_name::Foo;\n    Foo!();\n    ().bar();\n}\n\nproc_macros::external!(\n    fn ignore_inside_external_proc_macro() {\n        use std::any::Any;\n        \"foo\".type_id();\n    }\n);\n\nproc_macros::with_span!(\n    span\n\n    fn ignore_inside_with_span_proc_macro() {\n        use std::any::Any;\n        \"foo\".type_id();\n    }\n);\n\n// This should warn the import is unused but should not trigger unused_trait_names\n#[warn(unused)]\nmod unused_import {\n    \n    //~^ ERROR: unused import\n}\n\n#[allow(clippy::unused_trait_names)]\nfn allow_lint_fn() {\n    use std::any::Any;\n\n    \"foo\".type_id();\n}\n\n#[allow(clippy::unused_trait_names)]\nmod allow_lint_mod {\n    use std::any::Any;\n\n    fn foo() {\n        \"foo\".type_id();\n    }\n}\n\nmod allow_lint_import {\n    #[allow(clippy::unused_trait_names)]\n    use std::any::Any;\n\n    fn foo() {\n        \"foo\".type_id();\n    }\n}\n\n// Limitation: Suggests `use std::any::Any as _::{self};` which looks weird\n// fn use_trait_self_good() {\n//     use std::any::Any::{self};\n//     \"foo\".type_id();\n// }\n\n// Limitation: Suggests `use std::any::{Any as _, Any as _};`\n// mod repeated_renamed {\n//     use std::any::{Any, Any as MyAny};\n\n//     fn foo() {\n//         \"foo\".type_id();\n//     }\n// }\n"
  },
  {
    "path": "tests/ui/unused_trait_names.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![allow(unused)]\n#![warn(clippy::unused_trait_names)]\n#![feature(decl_macro)]\n\nextern crate proc_macros;\n\nfn main() {}\n\nfn bad() {\n    use std::any::Any;\n    //~^ unused_trait_names\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn good() {\n    use std::any::Any as _;\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn used_good() {\n    use std::any::Any;\n\n    println!(\"{:?}\", Any::type_id(\"foo\"));\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn multi_bad() {\n    use std::any::{self, Any, TypeId};\n    //~^ unused_trait_names\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn multi_good() {\n    use std::any::{self, Any as _, TypeId};\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn renamed_bad() {\n    use std::any::Any as MyAny;\n    //~^ unused_trait_names\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nfn multi_renamed_bad() {\n    use std::any::{Any as MyAny, TypeId as MyTypeId};\n    //~^ unused_trait_names\n\n    println!(\"{:?}\", \"foo\".type_id());\n}\n\nmod pub_good {\n    pub use std::any::Any;\n\n    fn foo() {\n        println!(\"{:?}\", \"foo\".type_id());\n    }\n}\n\nmod used_mod_good {\n    use std::any::Any;\n\n    fn foo() {\n        println!(\"{:?}\", Any::type_id(\"foo\"));\n    }\n}\n\nmod mod_import_bad {\n    fn mod_import_bad() {\n        use std::any::Any;\n        //~^ unused_trait_names\n\n        println!(\"{:?}\", \"foo\".type_id());\n    }\n}\n\nmod nested_mod_used_good1 {\n    use std::any::Any;\n\n    mod foo {\n        fn foo() {\n            super::Any::type_id(\"foo\");\n        }\n    }\n}\n\nmod nested_mod_used_good2 {\n    use std::any::Any;\n\n    mod foo {\n        use super::Any;\n\n        fn foo() {\n            Any::type_id(\"foo\");\n        }\n    }\n}\n\nmod nested_mod_used_good3 {\n    use std::any::Any;\n\n    mod foo {\n        use crate::nested_mod_used_good3::Any;\n\n        fn foo() {\n            println!(\"{:?}\", Any::type_id(\"foo\"));\n        }\n    }\n}\n\nmod nested_mod_used_bad {\n    use std::any::Any;\n    //~^ unused_trait_names\n\n    fn bar() {\n        println!(\"{:?}\", \"foo\".type_id());\n    }\n\n    mod foo {\n        use std::any::Any;\n\n        fn foo() {\n            println!(\"{:?}\", Any::type_id(\"foo\"));\n        }\n    }\n}\n\n// More complex example where `use std::any::Any;` should be anonymised but `use std::any::Any as\n// MyAny;` should not as it is used by a sub module. Even though if you removed `use std::any::Any;`\n// the code would still compile.\nmod nested_mod_used_bad1 {\n    use std::any::Any;\n    //~^ unused_trait_names\n\n    use std::any::Any as MyAny;\n\n    fn baz() {\n        println!(\"{:?}\", \"baz\".type_id());\n    }\n\n    mod foo {\n        use crate::nested_mod_used_bad1::MyAny;\n\n        fn foo() {\n            println!(\"{:?}\", MyAny::type_id(\"foo\"));\n        }\n    }\n}\n\n// Example of nested import with an unused import to try and trick it\nmod nested_mod_used_good5 {\n    use std::any::Any;\n\n    mod foo {\n        use std::any::Any;\n\n        fn baz() {\n            println!(\"{:?}\", \"baz\".type_id());\n        }\n\n        mod bar {\n            use crate::nested_mod_used_good5::foo::Any;\n\n            fn foo() {\n                println!(\"{:?}\", Any::type_id(\"foo\"));\n            }\n        }\n    }\n}\n\nmod simple_trait {\n    pub trait MyTrait {\n        fn do_things(&self);\n    }\n\n    pub struct MyStruct;\n\n    impl MyTrait for MyStruct {\n        fn do_things(&self) {}\n    }\n}\n\n// Underscore imports were stabilized in 1.33\n#[clippy::msrv = \"1.32\"]\nfn msrv_1_32() {\n    use simple_trait::{MyStruct, MyTrait};\n    MyStruct.do_things();\n}\n\n#[clippy::msrv = \"1.33\"]\nfn msrv_1_33() {\n    use simple_trait::{MyStruct, MyTrait};\n    //~^ unused_trait_names\n    MyStruct.do_things();\n}\n\n// Linting inside macro expansion is no longer supported\nmod lint_inside_macro_expansion_bad {\n    macro_rules! foo {\n        () => {\n            use std::any::Any;\n            fn bar() {\n                \"bar\".type_id();\n            }\n        };\n    }\n\n    foo!();\n}\n\nmod macro_and_trait_same_name {\n    pub macro Foo() {}\n    pub trait Foo {\n        fn bar(&self);\n    }\n    impl Foo for () {\n        fn bar(&self) {}\n    }\n}\n\nfn call_macro_and_trait_good() {\n    // importing trait and macro but only using macro by path won't allow us to change this to\n    // `use macro_and_trait_same_name::Foo as _;`\n    use macro_and_trait_same_name::Foo;\n    Foo!();\n    ().bar();\n}\n\nproc_macros::external!(\n    fn ignore_inside_external_proc_macro() {\n        use std::any::Any;\n        \"foo\".type_id();\n    }\n);\n\nproc_macros::with_span!(\n    span\n\n    fn ignore_inside_with_span_proc_macro() {\n        use std::any::Any;\n        \"foo\".type_id();\n    }\n);\n\n// This should warn the import is unused but should not trigger unused_trait_names\n#[warn(unused)]\nmod unused_import {\n    use std::any::Any;\n    //~^ ERROR: unused import\n}\n\n#[allow(clippy::unused_trait_names)]\nfn allow_lint_fn() {\n    use std::any::Any;\n\n    \"foo\".type_id();\n}\n\n#[allow(clippy::unused_trait_names)]\nmod allow_lint_mod {\n    use std::any::Any;\n\n    fn foo() {\n        \"foo\".type_id();\n    }\n}\n\nmod allow_lint_import {\n    #[allow(clippy::unused_trait_names)]\n    use std::any::Any;\n\n    fn foo() {\n        \"foo\".type_id();\n    }\n}\n\n// Limitation: Suggests `use std::any::Any as _::{self};` which looks weird\n// fn use_trait_self_good() {\n//     use std::any::Any::{self};\n//     \"foo\".type_id();\n// }\n\n// Limitation: Suggests `use std::any::{Any as _, Any as _};`\n// mod repeated_renamed {\n//     use std::any::{Any, Any as MyAny};\n\n//     fn foo() {\n//         \"foo\".type_id();\n//     }\n// }\n"
  },
  {
    "path": "tests/ui/unused_trait_names.stderr",
    "content": "error: unused import: `std::any::Any`\n  --> tests/ui/unused_trait_names.rs:254:9\n   |\nLL |     use std::any::Any;\n   |         ^^^^^^^^^^^^^\n   |\n   = note: `-D unused-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(unused_imports)]`\n\nerror: importing trait that is only used anonymously\n  --> tests/ui/unused_trait_names.rs:12:19\n   |\nLL |     use std::any::Any;\n   |                   ^^^ help: use: `Any as _`\n   |\n   = note: `-D clippy::unused-trait-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unused_trait_names)]`\n\nerror: importing trait that is only used anonymously\n  --> tests/ui/unused_trait_names.rs:32:26\n   |\nLL |     use std::any::{self, Any, TypeId};\n   |                          ^^^ help: use: `Any as _`\n\nerror: importing trait that is only used anonymously\n  --> tests/ui/unused_trait_names.rs:45:19\n   |\nLL |     use std::any::Any as MyAny;\n   |                   ^^^^^^^^^^^^ help: use: `Any as _`\n\nerror: importing trait that is only used anonymously\n  --> tests/ui/unused_trait_names.rs:52:20\n   |\nLL |     use std::any::{Any as MyAny, TypeId as MyTypeId};\n   |                    ^^^^^^^^^^^^ help: use: `Any as _`\n\nerror: importing trait that is only used anonymously\n  --> tests/ui/unused_trait_names.rs:76:23\n   |\nLL |         use std::any::Any;\n   |                       ^^^ help: use: `Any as _`\n\nerror: importing trait that is only used anonymously\n  --> tests/ui/unused_trait_names.rs:118:19\n   |\nLL |     use std::any::Any;\n   |                   ^^^ help: use: `Any as _`\n\nerror: importing trait that is only used anonymously\n  --> tests/ui/unused_trait_names.rs:138:19\n   |\nLL |     use std::any::Any;\n   |                   ^^^ help: use: `Any as _`\n\nerror: importing trait that is only used anonymously\n  --> tests/ui/unused_trait_names.rs:198:34\n   |\nLL |     use simple_trait::{MyStruct, MyTrait};\n   |                                  ^^^^^^^ help: use: `MyTrait as _`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_unit.edition2021.fixed",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n// The output for humans should just highlight the whole span without showing\n// the suggested replacement, but we also want to test that suggested\n// replacement only removes one set of parentheses, rather than naïvely\n// stripping away any starting or ending parenthesis characters—hence this\n// test of the JSON error format.\n\n#![feature(custom_inner_attributes)]\n#![feature(closure_lifetime_binder)]\n#![rustfmt::skip]\n\n#![deny(clippy::unused_unit)]\n#![allow(dead_code)]\n#![allow(clippy::from_over_into)]\n\nstruct Unitter;\nimpl Unitter {\n    #[allow(clippy::no_effect)]\n    pub fn get_unit<F: Fn(), G>(&self, f: F, _g: G)\n    //~^ unused_unit\n    //~| unused_unit\n    where G: Fn() {\n    //~^ unused_unit\n        let _y: &dyn Fn() = &f;\n        //~^ unused_unit\n        (); // this should not lint, as it's not in return type position\n    }\n}\n\nimpl Into<()> for Unitter {\n    #[rustfmt::skip]\n    fn into(self) {\n    //~^ unused_unit\n        \n        //~^ unused_unit\n    }\n}\n\ntrait Trait {\n    fn redundant<F: FnOnce(), G, H>(&self, _f: F, _g: G, _h: H)\n    //~^ unused_unit\n    where\n        G: FnMut(),\n        //~^ unused_unit\n        H: Fn();\n        //~^ unused_unit\n}\n\nimpl Trait for Unitter {\n    fn redundant<F: FnOnce(), G, H>(&self, _f: F, _g: G, _h: H)\n    //~^ unused_unit\n    where\n        G: FnMut(),\n        //~^ unused_unit\n        H: Fn() {}\n        //~^ unused_unit\n}\n\nfn return_unit() {  }\n//~^ unused_unit\n//~| unused_unit\n\n#[allow(clippy::needless_return)]\n#[allow(clippy::never_loop)]\n#[allow(clippy::unit_cmp)]\nfn main() {\n    let u = Unitter;\n    assert_eq!(u.get_unit(|| {}, return_unit), u.into());\n    return_unit();\n    loop {\n        break;\n        //~^ unused_unit\n    }\n    return;\n    //~^ unused_unit\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/4076\nfn foo() {\n    macro_rules! foo {\n        (recv($r:expr) -> $res:pat => $body:expr) => {\n            $body\n        }\n    }\n\n    foo! {\n        recv(rx) -> _x => ()\n    }\n}\n\n#[rustfmt::skip]\nfn test(){}\n//~^ unused_unit\n\n#[rustfmt::skip]\nfn test2(){}\n//~^ unused_unit\n\n#[rustfmt::skip]\nfn test3(){}\n//~^ unused_unit\n\nfn macro_expr() {\n    macro_rules! e {\n        () => (());\n    }\n    e!()\n}\n\nmod issue9748 {\n    fn main() {\n        let _ = for<'a> |_: &'a u32| -> () {};\n    }\n}\n\nmod issue9949 {\n    fn main() {\n        #[doc = \"documentation\"]\n        ()\n    }\n}\n\nmod issue14577 {\n    trait Unit {}\n    impl Unit for () {}\n\n    #[allow(dependency_on_unit_never_type_fallback)]\n    fn bar() {\n        //~[edition2021]^ unused_unit\n        panic!()\n    }\n\n    struct UnitStruct;\n    impl UnitStruct {\n        fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {\n            todo!()\n        }\n    }\n}\n\nmod pr14962 {\n    #[allow(unused_parens)]\n    type UnusedParensButNoUnit = Box<dyn (Fn())>;\n}\n\n\nmod issue15035 {\n\n    trait Convert<T> {\n        fn from(value: T) -> Self;\n    }\n\n    impl Convert<u64> for () {\n        fn from(_value: u64) -> Self {}\n    }\n\n    fn handle<T: Convert<u64>>(value: u64) -> T {\n        Convert::from(value)\n    }\n\n    pub fn f() -> Option<bool> {\n        let result: Result<bool, u64> = Err(42);\n        // the `-> ()` is required for the inference of `handle`'s return type\n        result.map_err(|err| -> () { handle(err) }).ok()\n    }\n}\n"
  },
  {
    "path": "tests/ui/unused_unit.edition2021.stderr",
    "content": "error: unneeded unit expression\n  --> tests/ui/unused_unit.rs:37:9\n   |\nLL |         ()\n   |         ^^ help: remove the final `()`\n   |\nnote: the lint level is defined here\n  --> tests/ui/unused_unit.rs:15:9\n   |\nLL | #![deny(clippy::unused_unit)]\n   |         ^^^^^^^^^^^^^^^^^^^\n\nerror: unneeded unit expression\n  --> tests/ui/unused_unit.rs:62:26\n   |\nLL | fn return_unit() -> () { () }\n   |                          ^^ help: remove the final `()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:22:28\n   |\nLL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()\n   |                            ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:25:18\n   |\nLL |     where G: Fn() -> () {\n   |                  ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:22:58\n   |\nLL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()\n   |                                                          ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:27:26\n   |\nLL |         let _y: &dyn Fn() -> () = &f;\n   |                          ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:35:18\n   |\nLL |     fn into(self) -> () {\n   |                  ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:43:29\n   |\nLL |     fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)\n   |                             ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:46:19\n   |\nLL |         G: FnMut() -> (),\n   |                   ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:48:16\n   |\nLL |         H: Fn() -> ();\n   |                ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:53:29\n   |\nLL |     fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)\n   |                             ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:56:19\n   |\nLL |         G: FnMut() -> (),\n   |                   ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:58:16\n   |\nLL |         H: Fn() -> () {}\n   |                ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:62:17\n   |\nLL | fn return_unit() -> () { () }\n   |                 ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded `()`\n  --> tests/ui/unused_unit.rs:74:14\n   |\nLL |         break();\n   |              ^^ help: remove the `()`\n\nerror: unneeded `()`\n  --> tests/ui/unused_unit.rs:77:11\n   |\nLL |     return();\n   |           ^^ help: remove the `()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:95:10\n   |\nLL | fn test()->(){}\n   |          ^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:99:11\n   |\nLL | fn test2() ->(){}\n   |           ^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:103:11\n   |\nLL | fn test3()-> (){}\n   |           ^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:131:13\n   |\nLL |     fn bar() -> () {\n   |             ^^^^^^ help: remove the `-> ()`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_unit.edition2024.fixed",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n// The output for humans should just highlight the whole span without showing\n// the suggested replacement, but we also want to test that suggested\n// replacement only removes one set of parentheses, rather than naïvely\n// stripping away any starting or ending parenthesis characters—hence this\n// test of the JSON error format.\n\n#![feature(custom_inner_attributes)]\n#![feature(closure_lifetime_binder)]\n#![rustfmt::skip]\n\n#![deny(clippy::unused_unit)]\n#![allow(dead_code)]\n#![allow(clippy::from_over_into)]\n\nstruct Unitter;\nimpl Unitter {\n    #[allow(clippy::no_effect)]\n    pub fn get_unit<F: Fn(), G>(&self, f: F, _g: G)\n    //~^ unused_unit\n    //~| unused_unit\n    where G: Fn() {\n    //~^ unused_unit\n        let _y: &dyn Fn() = &f;\n        //~^ unused_unit\n        (); // this should not lint, as it's not in return type position\n    }\n}\n\nimpl Into<()> for Unitter {\n    #[rustfmt::skip]\n    fn into(self) {\n    //~^ unused_unit\n        \n        //~^ unused_unit\n    }\n}\n\ntrait Trait {\n    fn redundant<F: FnOnce(), G, H>(&self, _f: F, _g: G, _h: H)\n    //~^ unused_unit\n    where\n        G: FnMut(),\n        //~^ unused_unit\n        H: Fn();\n        //~^ unused_unit\n}\n\nimpl Trait for Unitter {\n    fn redundant<F: FnOnce(), G, H>(&self, _f: F, _g: G, _h: H)\n    //~^ unused_unit\n    where\n        G: FnMut(),\n        //~^ unused_unit\n        H: Fn() {}\n        //~^ unused_unit\n}\n\nfn return_unit() {  }\n//~^ unused_unit\n//~| unused_unit\n\n#[allow(clippy::needless_return)]\n#[allow(clippy::never_loop)]\n#[allow(clippy::unit_cmp)]\nfn main() {\n    let u = Unitter;\n    assert_eq!(u.get_unit(|| {}, return_unit), u.into());\n    return_unit();\n    loop {\n        break;\n        //~^ unused_unit\n    }\n    return;\n    //~^ unused_unit\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/4076\nfn foo() {\n    macro_rules! foo {\n        (recv($r:expr) -> $res:pat => $body:expr) => {\n            $body\n        }\n    }\n\n    foo! {\n        recv(rx) -> _x => ()\n    }\n}\n\n#[rustfmt::skip]\nfn test(){}\n//~^ unused_unit\n\n#[rustfmt::skip]\nfn test2(){}\n//~^ unused_unit\n\n#[rustfmt::skip]\nfn test3(){}\n//~^ unused_unit\n\nfn macro_expr() {\n    macro_rules! e {\n        () => (());\n    }\n    e!()\n}\n\nmod issue9748 {\n    fn main() {\n        let _ = for<'a> |_: &'a u32| -> () {};\n    }\n}\n\nmod issue9949 {\n    fn main() {\n        #[doc = \"documentation\"]\n        ()\n    }\n}\n\nmod issue14577 {\n    trait Unit {}\n    impl Unit for () {}\n\n    #[allow(dependency_on_unit_never_type_fallback)]\n    fn bar() -> () {\n        //~[edition2021]^ unused_unit\n        panic!()\n    }\n\n    struct UnitStruct;\n    impl UnitStruct {\n        fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {\n            todo!()\n        }\n    }\n}\n\nmod pr14962 {\n    #[allow(unused_parens)]\n    type UnusedParensButNoUnit = Box<dyn (Fn())>;\n}\n\n\nmod issue15035 {\n\n    trait Convert<T> {\n        fn from(value: T) -> Self;\n    }\n\n    impl Convert<u64> for () {\n        fn from(_value: u64) -> Self {}\n    }\n\n    fn handle<T: Convert<u64>>(value: u64) -> T {\n        Convert::from(value)\n    }\n\n    pub fn f() -> Option<bool> {\n        let result: Result<bool, u64> = Err(42);\n        // the `-> ()` is required for the inference of `handle`'s return type\n        result.map_err(|err| -> () { handle(err) }).ok()\n    }\n}\n"
  },
  {
    "path": "tests/ui/unused_unit.edition2024.stderr",
    "content": "error: unneeded unit expression\n  --> tests/ui/unused_unit.rs:37:9\n   |\nLL |         ()\n   |         ^^ help: remove the final `()`\n   |\nnote: the lint level is defined here\n  --> tests/ui/unused_unit.rs:15:9\n   |\nLL | #![deny(clippy::unused_unit)]\n   |         ^^^^^^^^^^^^^^^^^^^\n\nerror: unneeded unit expression\n  --> tests/ui/unused_unit.rs:62:26\n   |\nLL | fn return_unit() -> () { () }\n   |                          ^^ help: remove the final `()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:22:28\n   |\nLL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()\n   |                            ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:25:18\n   |\nLL |     where G: Fn() -> () {\n   |                  ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:22:58\n   |\nLL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()\n   |                                                          ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:27:26\n   |\nLL |         let _y: &dyn Fn() -> () = &f;\n   |                          ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:35:18\n   |\nLL |     fn into(self) -> () {\n   |                  ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:43:29\n   |\nLL |     fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)\n   |                             ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:46:19\n   |\nLL |         G: FnMut() -> (),\n   |                   ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:48:16\n   |\nLL |         H: Fn() -> ();\n   |                ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:53:29\n   |\nLL |     fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)\n   |                             ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:56:19\n   |\nLL |         G: FnMut() -> (),\n   |                   ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:58:16\n   |\nLL |         H: Fn() -> () {}\n   |                ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:62:17\n   |\nLL | fn return_unit() -> () { () }\n   |                 ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded `()`\n  --> tests/ui/unused_unit.rs:74:14\n   |\nLL |         break();\n   |              ^^ help: remove the `()`\n\nerror: unneeded `()`\n  --> tests/ui/unused_unit.rs:77:11\n   |\nLL |     return();\n   |           ^^ help: remove the `()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:95:10\n   |\nLL | fn test()->(){}\n   |          ^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:99:11\n   |\nLL | fn test2() ->(){}\n   |           ^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:103:11\n   |\nLL | fn test3()-> (){}\n   |           ^^^^^ help: remove the `-> ()`\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/unused_unit.fixed",
    "content": "\n\n// The output for humans should just highlight the whole span without showing\n// the suggested replacement, but we also want to test that suggested\n// replacement only removes one set of parentheses, rather than naïvely\n// stripping away any starting or ending parenthesis characters—hence this\n// test of the JSON error format.\n\n#![feature(custom_inner_attributes)]\n#![feature(closure_lifetime_binder)]\n#![rustfmt::skip]\n\n#![deny(clippy::unused_unit)]\n#![allow(dead_code)]\n#![allow(clippy::from_over_into)]\n\nstruct Unitter;\nimpl Unitter {\n    #[allow(clippy::no_effect)]\n    pub fn get_unit<F: Fn(), G>(&self, f: F, _g: G)\n    //~^ unused_unit\n    //~| unused_unit\n    where G: Fn() {\n    //~^ unused_unit\n        let _y: &dyn Fn() = &f;\n        //~^ unused_unit\n        (); // this should not lint, as it's not in return type position\n    }\n}\n\nimpl Into<()> for Unitter {\n    #[rustfmt::skip]\n    fn into(self) {\n    //~^ unused_unit\n        \n        //~^ unused_unit\n    }\n}\n\ntrait Trait {\n    fn redundant<F: FnOnce(), G, H>(&self, _f: F, _g: G, _h: H)\n    //~^ unused_unit\n    where\n        G: FnMut(),\n        //~^ unused_unit\n        H: Fn();\n        //~^ unused_unit\n}\n\nimpl Trait for Unitter {\n    fn redundant<F: FnOnce(), G, H>(&self, _f: F, _g: G, _h: H)\n    //~^ unused_unit\n    where\n        G: FnMut(),\n        //~^ unused_unit\n        H: Fn() {}\n        //~^ unused_unit\n}\n\nfn return_unit() {  }\n//~^ unused_unit\n//~| unused_unit\n\n#[allow(clippy::needless_return)]\n#[allow(clippy::never_loop)]\n#[allow(clippy::unit_cmp)]\nfn main() {\n    let u = Unitter;\n    assert_eq!(u.get_unit(|| {}, return_unit), u.into());\n    return_unit();\n    loop {\n        break;\n        //~^ unused_unit\n    }\n    return;\n    //~^ unused_unit\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/4076\nfn foo() {\n    macro_rules! foo {\n        (recv($r:expr) -> $res:pat => $body:expr) => {\n            $body\n        }\n    }\n\n    foo! {\n        recv(rx) -> _x => ()\n    }\n}\n\n#[rustfmt::skip]\nfn test(){}\n//~^ unused_unit\n\n#[rustfmt::skip]\nfn test2(){}\n//~^ unused_unit\n\n#[rustfmt::skip]\nfn test3(){}\n//~^ unused_unit\n\nfn macro_expr() {\n    macro_rules! e {\n        () => (());\n    }\n    e!()\n}\n\nmod issue9748 {\n    fn main() {\n        let _ = for<'a> |_: &'a u32| -> () {};\n    }\n}\n\nmod issue9949 {\n    fn main() {\n        #[doc = \"documentation\"]\n        ()\n    }\n}\n\n#[clippy::msrv = \"1.85\"]\nmod issue14577 {\n    trait Unit {}\n    impl Unit for () {}\n\n    fn run<R: Unit>(f: impl FnOnce() -> R) {\n        f();\n    }\n\n    fn bar() {\n        run(|| -> () { todo!() });\n    }\n\n    struct UnitStruct;\n    impl UnitStruct {\n        fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {\n            todo!()\n        }\n    }\n}"
  },
  {
    "path": "tests/ui/unused_unit.rs",
    "content": "//@revisions: edition2021 edition2024\n//@[edition2021] edition:2021\n//@[edition2024] edition:2024\n\n// The output for humans should just highlight the whole span without showing\n// the suggested replacement, but we also want to test that suggested\n// replacement only removes one set of parentheses, rather than naïvely\n// stripping away any starting or ending parenthesis characters—hence this\n// test of the JSON error format.\n\n#![feature(custom_inner_attributes)]\n#![feature(closure_lifetime_binder)]\n#![rustfmt::skip]\n\n#![deny(clippy::unused_unit)]\n#![allow(dead_code)]\n#![allow(clippy::from_over_into)]\n\nstruct Unitter;\nimpl Unitter {\n    #[allow(clippy::no_effect)]\n    pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()\n    //~^ unused_unit\n    //~| unused_unit\n    where G: Fn() -> () {\n    //~^ unused_unit\n        let _y: &dyn Fn() -> () = &f;\n        //~^ unused_unit\n        (); // this should not lint, as it's not in return type position\n    }\n}\n\nimpl Into<()> for Unitter {\n    #[rustfmt::skip]\n    fn into(self) -> () {\n    //~^ unused_unit\n        ()\n        //~^ unused_unit\n    }\n}\n\ntrait Trait {\n    fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)\n    //~^ unused_unit\n    where\n        G: FnMut() -> (),\n        //~^ unused_unit\n        H: Fn() -> ();\n        //~^ unused_unit\n}\n\nimpl Trait for Unitter {\n    fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)\n    //~^ unused_unit\n    where\n        G: FnMut() -> (),\n        //~^ unused_unit\n        H: Fn() -> () {}\n        //~^ unused_unit\n}\n\nfn return_unit() -> () { () }\n//~^ unused_unit\n//~| unused_unit\n\n#[allow(clippy::needless_return)]\n#[allow(clippy::never_loop)]\n#[allow(clippy::unit_cmp)]\nfn main() {\n    let u = Unitter;\n    assert_eq!(u.get_unit(|| {}, return_unit), u.into());\n    return_unit();\n    loop {\n        break();\n        //~^ unused_unit\n    }\n    return();\n    //~^ unused_unit\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/4076\nfn foo() {\n    macro_rules! foo {\n        (recv($r:expr) -> $res:pat => $body:expr) => {\n            $body\n        }\n    }\n\n    foo! {\n        recv(rx) -> _x => ()\n    }\n}\n\n#[rustfmt::skip]\nfn test()->(){}\n//~^ unused_unit\n\n#[rustfmt::skip]\nfn test2() ->(){}\n//~^ unused_unit\n\n#[rustfmt::skip]\nfn test3()-> (){}\n//~^ unused_unit\n\nfn macro_expr() {\n    macro_rules! e {\n        () => (());\n    }\n    e!()\n}\n\nmod issue9748 {\n    fn main() {\n        let _ = for<'a> |_: &'a u32| -> () {};\n    }\n}\n\nmod issue9949 {\n    fn main() {\n        #[doc = \"documentation\"]\n        ()\n    }\n}\n\nmod issue14577 {\n    trait Unit {}\n    impl Unit for () {}\n\n    #[allow(dependency_on_unit_never_type_fallback)]\n    fn bar() -> () {\n        //~[edition2021]^ unused_unit\n        panic!()\n    }\n\n    struct UnitStruct;\n    impl UnitStruct {\n        fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {\n            todo!()\n        }\n    }\n}\n\nmod pr14962 {\n    #[allow(unused_parens)]\n    type UnusedParensButNoUnit = Box<dyn (Fn())>;\n}\n\n\nmod issue15035 {\n\n    trait Convert<T> {\n        fn from(value: T) -> Self;\n    }\n\n    impl Convert<u64> for () {\n        fn from(_value: u64) -> Self {}\n    }\n\n    fn handle<T: Convert<u64>>(value: u64) -> T {\n        Convert::from(value)\n    }\n\n    pub fn f() -> Option<bool> {\n        let result: Result<bool, u64> = Err(42);\n        // the `-> ()` is required for the inference of `handle`'s return type\n        result.map_err(|err| -> () { handle(err) }).ok()\n    }\n}\n"
  },
  {
    "path": "tests/ui/unused_unit.stderr",
    "content": "error: unneeded unit expression\n  --> tests/ui/unused_unit.rs:35:9\n   |\nLL |         ()\n   |         ^^ help: remove the final `()`\n   |\nnote: the lint level is defined here\n  --> tests/ui/unused_unit.rs:13:9\n   |\nLL | #![deny(clippy::unused_unit)]\n   |         ^^^^^^^^^^^^^^^^^^^\n\nerror: unneeded unit expression\n  --> tests/ui/unused_unit.rs:60:26\n   |\nLL | fn return_unit() -> () { () }\n   |                          ^^ help: remove the final `()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:20:28\n   |\nLL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()\n   |                            ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:23:18\n   |\nLL |     where G: Fn() -> () {\n   |                  ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:20:58\n   |\nLL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()\n   |                                                          ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:25:26\n   |\nLL |         let _y: &dyn Fn() -> () = &f;\n   |                          ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:33:18\n   |\nLL |     fn into(self) -> () {\n   |                  ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:41:29\n   |\nLL |     fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)\n   |                             ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:44:19\n   |\nLL |         G: FnMut() -> (),\n   |                   ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:46:16\n   |\nLL |         H: Fn() -> ();\n   |                ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:51:29\n   |\nLL |     fn redundant<F: FnOnce() -> (), G, H>(&self, _f: F, _g: G, _h: H)\n   |                             ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:54:19\n   |\nLL |         G: FnMut() -> (),\n   |                   ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:56:16\n   |\nLL |         H: Fn() -> () {}\n   |                ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:60:17\n   |\nLL | fn return_unit() -> () { () }\n   |                 ^^^^^^ help: remove the `-> ()`\n\nerror: unneeded `()`\n  --> tests/ui/unused_unit.rs:72:14\n   |\nLL |         break();\n   |              ^^ help: remove the `()`\n\nerror: unneeded `()`\n  --> tests/ui/unused_unit.rs:75:11\n   |\nLL |     return();\n   |           ^^ help: remove the `()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:93:10\n   |\nLL | fn test()->(){}\n   |          ^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:97:11\n   |\nLL | fn test2() ->(){}\n   |           ^^^^^ help: remove the `-> ()`\n\nerror: unneeded unit return type\n  --> tests/ui/unused_unit.rs:101:11\n   |\nLL | fn test3()-> (){}\n   |           ^^^^^ help: remove the `-> ()`\n\nerror: aborting due to 19 previous errors\n\n"
  },
  {
    "path": "tests/ui/unwrap_expect_used.rs",
    "content": "#![warn(clippy::unwrap_used, clippy::expect_used)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n#![feature(never_type)]\n\nuse std::convert::Infallible;\n\ntrait OptionExt {\n    type Item;\n\n    fn unwrap_err(self) -> Self::Item;\n\n    fn expect_err(self, msg: &str) -> Self::Item;\n}\n\nimpl<T> OptionExt for Option<T> {\n    type Item = T;\n    fn unwrap_err(self) -> T {\n        panic!();\n    }\n\n    fn expect_err(self, msg: &str) -> T {\n        panic!();\n    }\n}\n\nfn main() {\n    Some(3).unwrap();\n    //~^ unwrap_used\n\n    Some(3).expect(\"Hello world!\");\n    //~^ expect_used\n\n    // Don't trigger on unwrap_err on an option\n    Some(3).unwrap_err();\n    Some(3).expect_err(\"Hello none!\");\n\n    // Issue #11245: The `Err` variant can never be constructed so do not lint this.\n    let x: Result<(), !> = Ok(());\n    x.unwrap();\n    x.expect(\"is `!` (never)\");\n    let x: Result<(), Infallible> = Ok(());\n    x.unwrap();\n    x.expect(\"is never-like (0 variants)\");\n\n    let a: Result<i32, i32> = Ok(3);\n    a.unwrap();\n    //~^ unwrap_used\n\n    a.expect(\"Hello world!\");\n    //~^ expect_used\n\n    a.unwrap_err();\n    //~^ unwrap_used\n\n    a.expect_err(\"Hello error!\");\n    //~^ expect_used\n\n    // Don't trigger in compile time contexts by default\n    const SOME: Option<i32> = Some(3);\n    const UNWRAPPED: i32 = SOME.unwrap();\n    const EXPECTED: i32 = SOME.expect(\"Not three?\");\n    const {\n        SOME.unwrap();\n    }\n    const {\n        SOME.expect(\"Still not three?\");\n    }\n}\n\nmod with_expansion {\n    macro_rules! open {\n        ($file:expr) => {\n            std::fs::File::open($file)\n        };\n    }\n\n    fn test(file: &str) {\n        use std::io::Read;\n        let mut s = String::new();\n        let _ = open!(file).unwrap(); //~ unwrap_used\n        let _ = open!(file).expect(\"can open\"); //~ expect_used\n        let _ = open!(file).unwrap_err(); //~ unwrap_used\n        let _ = open!(file).expect_err(\"can open\"); //~ expect_used\n    }\n}\n\nfn issue16484() {\n    let opt = Some(());\n    Option::unwrap(opt); //~ unwrap_used\n    Option::expect(opt, \"error message\"); //~ expect_used\n\n    let res: Result<(), i32> = Ok(());\n    Result::unwrap(res); //~ unwrap_used\n    Result::expect(res, \"error message\"); //~ expect_used\n    Result::unwrap_err(res); //~ unwrap_used\n    Result::expect_err(res, \"error message\"); //~ expect_used\n}\n"
  },
  {
    "path": "tests/ui/unwrap_expect_used.stderr",
    "content": "error: used `unwrap()` on an `Option` value\n  --> tests/ui/unwrap_expect_used.rs:27:5\n   |\nLL |     Some(3).unwrap();\n   |     ^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = note: `-D clippy::unwrap-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`\n\nerror: used `expect()` on an `Option` value\n  --> tests/ui/unwrap_expect_used.rs:30:5\n   |\nLL |     Some(3).expect(\"Hello world!\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = note: `-D clippy::expect-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::expect_used)]`\n\nerror: used `unwrap()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:46:5\n   |\nLL |     a.unwrap();\n   |     ^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n\nerror: used `expect()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:49:5\n   |\nLL |     a.expect(\"Hello world!\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n\nerror: used `unwrap_err()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:52:5\n   |\nLL |     a.unwrap_err();\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Ok`, it will panic\n\nerror: used `expect_err()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:55:5\n   |\nLL |     a.expect_err(\"Hello error!\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Ok`, it will panic\n\nerror: used `unwrap()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:80:17\n   |\nLL |         let _ = open!(file).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n\nerror: used `expect()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:81:17\n   |\nLL |         let _ = open!(file).expect(\"can open\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n\nerror: used `unwrap_err()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:82:17\n   |\nLL |         let _ = open!(file).unwrap_err();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Ok`, it will panic\n\nerror: used `expect_err()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:83:17\n   |\nLL |         let _ = open!(file).expect_err(\"can open\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Ok`, it will panic\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui/unwrap_expect_used.rs:89:5\n   |\nLL |     Option::unwrap(opt);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n\nerror: used `expect()` on an `Option` value\n  --> tests/ui/unwrap_expect_used.rs:90:5\n   |\nLL |     Option::expect(opt, \"error message\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n\nerror: used `unwrap()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:93:5\n   |\nLL |     Result::unwrap(res);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n\nerror: used `expect()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:94:5\n   |\nLL |     Result::expect(res, \"error message\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n\nerror: used `unwrap_err()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:95:5\n   |\nLL |     Result::unwrap_err(res);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Ok`, it will panic\n\nerror: used `expect_err()` on a `Result` value\n  --> tests/ui/unwrap_expect_used.rs:96:5\n   |\nLL |     Result::expect_err(res, \"error message\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Ok`, it will panic\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/unwrap_in_result.rs",
    "content": "#![warn(clippy::unwrap_in_result)]\n#![allow(clippy::ok_expect)]\n\nstruct A;\n\nimpl A {\n    // should not be detected\n    fn good_divisible_by_3(i_str: String) -> Result<bool, String> {\n        // checks whether a string represents a number divisible by 3\n        let i_result = i_str.parse::<i32>();\n        match i_result {\n            Err(_e) => Err(\"Not a number\".to_string()),\n            Ok(i) => {\n                if i % 3 == 0 {\n                    return Ok(true);\n                }\n                Err(\"Number is not divisible by 3\".to_string())\n            },\n        }\n    }\n\n    // should be detected\n    fn bad_divisible_by_3(i_str: String) -> Result<bool, String> {\n        // checks whether a string represents a number divisible by 3\n        let i = i_str.parse::<i32>().unwrap();\n        //~^ unwrap_in_result\n        if i % 3 == 0 {\n            Ok(true)\n        } else {\n            Err(\"Number is not divisible by 3\".to_string())\n        }\n    }\n\n    fn example_option_expect(i_str: String) -> Option<bool> {\n        let i = i_str.parse::<i32>().ok().expect(\"not a number\");\n        //~^ unwrap_in_result\n        if i % 3 == 0 {\n            return Some(true);\n        }\n        None\n    }\n\n    fn in_closure(a: Option<bool>) -> Option<bool> {\n        // No lint inside a closure\n        let c = || a.unwrap();\n\n        // But lint outside\n        let a = c().then_some(true);\n        let _ = a.unwrap();\n        //~^ unwrap_in_result\n\n        None\n    }\n\n    const fn in_const_inside_fn() -> bool {\n        const A: bool = {\n            const fn inner(b: Option<bool>) -> Option<bool> {\n                Some(b.unwrap())\n                //~^ unwrap_in_result\n            }\n\n            // No lint inside `const`\n            inner(Some(true)).unwrap()\n        };\n        A\n    }\n\n    fn in_static_inside_fn() -> bool {\n        static A: bool = {\n            const fn inner(b: Option<bool>) -> Option<bool> {\n                Some(b.unwrap())\n                //~^ unwrap_in_result\n            }\n\n            // No lint inside `static`\n            inner(Some(true)).unwrap()\n        };\n        A\n    }\n}\n\nmacro_rules! mac {\n    () => {\n        Option::unwrap(Some(3))\n    };\n}\n\nfn type_relative_unwrap() -> Option<()> {\n    _ = Option::unwrap(Some(3));\n    //~^ unwrap_in_result\n\n    // Do not lint macro output\n    _ = mac!();\n\n    None\n}\n\nfn main() -> Result<(), ()> {\n    A::bad_divisible_by_3(\"3\".to_string()).unwrap();\n    //~^ unwrap_in_result\n    A::good_divisible_by_3(\"3\".to_string()).unwrap();\n    //~^ unwrap_in_result\n    Result::unwrap(A::good_divisible_by_3(\"3\".to_string()));\n    //~^ unwrap_in_result\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/unwrap_in_result.stderr",
    "content": "error: `unwrap` used in a function that returns a `Result`\n  --> tests/ui/unwrap_in_result.rs:25:17\n   |\nLL |         let i = i_str.parse::<i32>().unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: in this function signature\n  --> tests/ui/unwrap_in_result.rs:23:45\n   |\nLL |     fn bad_divisible_by_3(i_str: String) -> Result<bool, String> {\n   |                                             ^^^^^^^^^^^^^^^^^^^^\n   = help: consider using the `?` operator or calling the `.map_err()` method\n   = note: `-D clippy::unwrap-in-result` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unwrap_in_result)]`\n\nerror: `expect` used in a function that returns an `Option`\n  --> tests/ui/unwrap_in_result.rs:35:17\n   |\nLL |         let i = i_str.parse::<i32>().ok().expect(\"not a number\");\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: in this function signature\n  --> tests/ui/unwrap_in_result.rs:34:48\n   |\nLL |     fn example_option_expect(i_str: String) -> Option<bool> {\n   |                                                ^^^^^^^^^^^^\n   = help: consider using the `?` operator\n\nerror: `unwrap` used in a function that returns an `Option`\n  --> tests/ui/unwrap_in_result.rs:49:17\n   |\nLL |         let _ = a.unwrap();\n   |                 ^^^^^^^^^^\n   |\nnote: in this function signature\n  --> tests/ui/unwrap_in_result.rs:43:39\n   |\nLL |     fn in_closure(a: Option<bool>) -> Option<bool> {\n   |                                       ^^^^^^^^^^^^\n   = help: consider using the `?` operator\n\nerror: `unwrap` used in a function that returns an `Option`\n  --> tests/ui/unwrap_in_result.rs:58:22\n   |\nLL |                 Some(b.unwrap())\n   |                      ^^^^^^^^^^\n   |\nnote: in this function signature\n  --> tests/ui/unwrap_in_result.rs:57:48\n   |\nLL |             const fn inner(b: Option<bool>) -> Option<bool> {\n   |                                                ^^^^^^^^^^^^\n   = help: consider using the `?` operator\n\nerror: `unwrap` used in a function that returns an `Option`\n  --> tests/ui/unwrap_in_result.rs:71:22\n   |\nLL |                 Some(b.unwrap())\n   |                      ^^^^^^^^^^\n   |\nnote: in this function signature\n  --> tests/ui/unwrap_in_result.rs:70:48\n   |\nLL |             const fn inner(b: Option<bool>) -> Option<bool> {\n   |                                                ^^^^^^^^^^^^\n   = help: consider using the `?` operator\n\nerror: `unwrap` used in a function that returns an `Option`\n  --> tests/ui/unwrap_in_result.rs:89:9\n   |\nLL |     _ = Option::unwrap(Some(3));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: in this function signature\n  --> tests/ui/unwrap_in_result.rs:88:30\n   |\nLL | fn type_relative_unwrap() -> Option<()> {\n   |                              ^^^^^^^^^^\n   = help: consider using the `?` operator\n\nerror: `unwrap` used in a function that returns a `Result`\n  --> tests/ui/unwrap_in_result.rs:99:5\n   |\nLL |     A::bad_divisible_by_3(\"3\".to_string()).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: in this function signature\n  --> tests/ui/unwrap_in_result.rs:98:14\n   |\nLL | fn main() -> Result<(), ()> {\n   |              ^^^^^^^^^^^^^^\n   = help: consider using the `?` operator or calling the `.map_err()` method\n\nerror: `unwrap` used in a function that returns a `Result`\n  --> tests/ui/unwrap_in_result.rs:101:5\n   |\nLL |     A::good_divisible_by_3(\"3\".to_string()).unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: `unwrap` used in a function that returns a `Result`\n  --> tests/ui/unwrap_in_result.rs:103:5\n   |\nLL |     Result::unwrap(A::good_divisible_by_3(\"3\".to_string()));\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/unwrap_or.fixed",
    "content": "#![warn(clippy::or_fun_call)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nfn main() {\n    let s = Some(String::from(\"test string\")).unwrap_or_else(|| \"Fail\".to_string()).len();\n    //~^ or_fun_call\n}\n\nfn new_lines() {\n    let s = Some(String::from(\"test string\")).unwrap_or_else(|| \"Fail\".to_string()).len();\n    //~^ or_fun_call\n}\n"
  },
  {
    "path": "tests/ui/unwrap_or.rs",
    "content": "#![warn(clippy::or_fun_call)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nfn main() {\n    let s = Some(String::from(\"test string\")).unwrap_or(\"Fail\".to_string()).len();\n    //~^ or_fun_call\n}\n\nfn new_lines() {\n    let s = Some(String::from(\"test string\")).unwrap_or(\"Fail\".to_string()).len();\n    //~^ or_fun_call\n}\n"
  },
  {
    "path": "tests/ui/unwrap_or.stderr",
    "content": "error: function call inside of `unwrap_or`\n  --> tests/ui/unwrap_or.rs:5:47\n   |\nLL |     let s = Some(String::from(\"test string\")).unwrap_or(\"Fail\".to_string()).len();\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| \"Fail\".to_string())`\n   |\n   = note: `-D clippy::or-fun-call` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::or_fun_call)]`\n\nerror: function call inside of `unwrap_or`\n  --> tests/ui/unwrap_or.rs:10:47\n   |\nLL |     let s = Some(String::from(\"test string\")).unwrap_or(\"Fail\".to_string()).len();\n   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| \"Fail\".to_string())`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/unwrap_or_else_default.fixed",
    "content": "#![warn(clippy::unwrap_or_default)]\n#![allow(dead_code)]\n#![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)]\n\n/// Checks implementation of the `UNWRAP_OR_DEFAULT` lint.\nfn unwrap_or_else_default() {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Foo {\n            Foo\n        }\n\n        // fake default, we should not trigger on this\n        fn default() -> Foo {\n            Foo\n        }\n    }\n\n    struct HasDefaultAndDuplicate;\n\n    impl HasDefaultAndDuplicate {\n        fn default() -> Self {\n            HasDefaultAndDuplicate\n        }\n    }\n\n    impl Default for HasDefaultAndDuplicate {\n        fn default() -> Self {\n            HasDefaultAndDuplicate\n        }\n    }\n\n    enum Enum {\n        A(),\n    }\n\n    fn make<T, V>(_: V) -> T {\n        unimplemented!();\n    }\n\n    let with_enum = Some(Enum::A());\n    with_enum.unwrap_or_else(Enum::A);\n\n    let with_new = Some(vec![1]);\n    with_new.unwrap_or_else(Vec::new);\n\n    let with_err: Result<_, ()> = Ok(vec![1]);\n    with_err.unwrap_or_else(make);\n\n    // should not be changed\n    let with_fake_default = None::<Foo>;\n    with_fake_default.unwrap_or_else(Foo::default);\n\n    // should not be changed\n    let with_fake_default2 = None::<HasDefaultAndDuplicate>;\n    with_fake_default2.unwrap_or_else(<HasDefaultAndDuplicate>::default);\n\n    let with_real_default = None::<HasDefaultAndDuplicate>;\n    with_real_default.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let with_default_trait = Some(1);\n    with_default_trait.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let with_default_type = Some(1);\n    with_default_type.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let with_default_type: Option<Vec<u64>> = None;\n    with_default_type.unwrap_or_default();\n    //~^ unwrap_or_default\n\n    let empty_string = None::<String>;\n    empty_string.unwrap_or_default();\n    //~^ unwrap_or_default\n}\n\nfn type_certainty(option: Option<Vec<u64>>) {\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n\n    let option: std::option::Option<std::vec::Vec<u64>> = None;\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n\n    let option: Option<Vec<u64>> = None;\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n\n    let option = std::option::Option::<std::vec::Vec<u64>>::None;\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n\n    let option = Option::<Vec<u64>>::None;\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n\n    let option = std::option::Option::None::<std::vec::Vec<u64>>;\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n\n    let option = Option::None::<Vec<u64>>;\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n\n    let option = None::<Vec<u64>>;\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n\n    // should not be changed: type annotation with infer, unconcretized initializer\n    let option: Option<Vec<_>> = None;\n    option.unwrap_or_else(Vec::new).push(1);\n\n    // should not be changed: no type annotation, unconcretized initializer\n    let option = Option::None;\n    option.unwrap_or_else(Vec::new).push(1);\n\n    // should not be changed: no type annotation, unconcretized initializer\n    let option = None;\n    option.unwrap_or_else(Vec::new).push(1);\n\n    type Alias = Option<Vec<u32>>;\n    let option: Alias = Option::<Vec<u32>>::Some(Vec::new());\n    option.unwrap_or_default().push(1);\n    //~^ unwrap_or_default\n}\n\nfn method_call_with_deref() {\n    use std::cell::RefCell;\n    use std::collections::HashMap;\n\n    let cell = RefCell::new(HashMap::<u64, HashMap<u64, String>>::new());\n\n    let mut outer_map = cell.borrow_mut();\n\n    #[allow(unused_assignments)]\n    let mut option = None;\n    option = Some(0);\n\n    let inner_map = outer_map.get_mut(&option.unwrap()).unwrap();\n\n    let _ = inner_map.entry(0).or_default();\n    //~^ unwrap_or_default\n}\n\nfn missing_suggested_method() {\n    #[derive(Copy, Clone)]\n    struct S<T>(T);\n\n    impl<T> S<T> {\n        fn or_insert_with(&mut self, default: impl FnOnce() -> T) -> &mut T {\n            &mut self.0\n        }\n\n        fn or_insert(&mut self, default: T) -> &mut T {\n            &mut self.0\n        }\n\n        fn unwrap_or_else(self, default: impl FnOnce() -> T) -> T {\n            self.0\n        }\n\n        fn unwrap_or(self, default: T) -> T {\n            self.0\n        }\n    }\n\n    // Don't lint when or_default/unwrap_or_default do not exist on the type\n    let mut s = S(1);\n    s.or_insert_with(Default::default);\n    s.or_insert(Default::default());\n    s.unwrap_or_else(Default::default);\n    s.unwrap_or(Default::default());\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unwrap_or_else_default.rs",
    "content": "#![warn(clippy::unwrap_or_default)]\n#![allow(dead_code)]\n#![allow(clippy::unnecessary_wraps, clippy::unnecessary_literal_unwrap)]\n\n/// Checks implementation of the `UNWRAP_OR_DEFAULT` lint.\nfn unwrap_or_else_default() {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Foo {\n            Foo\n        }\n\n        // fake default, we should not trigger on this\n        fn default() -> Foo {\n            Foo\n        }\n    }\n\n    struct HasDefaultAndDuplicate;\n\n    impl HasDefaultAndDuplicate {\n        fn default() -> Self {\n            HasDefaultAndDuplicate\n        }\n    }\n\n    impl Default for HasDefaultAndDuplicate {\n        fn default() -> Self {\n            HasDefaultAndDuplicate\n        }\n    }\n\n    enum Enum {\n        A(),\n    }\n\n    fn make<T, V>(_: V) -> T {\n        unimplemented!();\n    }\n\n    let with_enum = Some(Enum::A());\n    with_enum.unwrap_or_else(Enum::A);\n\n    let with_new = Some(vec![1]);\n    with_new.unwrap_or_else(Vec::new);\n\n    let with_err: Result<_, ()> = Ok(vec![1]);\n    with_err.unwrap_or_else(make);\n\n    // should not be changed\n    let with_fake_default = None::<Foo>;\n    with_fake_default.unwrap_or_else(Foo::default);\n\n    // should not be changed\n    let with_fake_default2 = None::<HasDefaultAndDuplicate>;\n    with_fake_default2.unwrap_or_else(<HasDefaultAndDuplicate>::default);\n\n    let with_real_default = None::<HasDefaultAndDuplicate>;\n    with_real_default.unwrap_or_else(<HasDefaultAndDuplicate as Default>::default);\n    //~^ unwrap_or_default\n\n    let with_default_trait = Some(1);\n    with_default_trait.unwrap_or_else(Default::default);\n    //~^ unwrap_or_default\n\n    let with_default_type = Some(1);\n    with_default_type.unwrap_or_else(u64::default);\n    //~^ unwrap_or_default\n\n    let with_default_type: Option<Vec<u64>> = None;\n    with_default_type.unwrap_or_else(Vec::new);\n    //~^ unwrap_or_default\n\n    let empty_string = None::<String>;\n    empty_string.unwrap_or_else(|| \"\".to_string());\n    //~^ unwrap_or_default\n}\n\nfn type_certainty(option: Option<Vec<u64>>) {\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n\n    let option: std::option::Option<std::vec::Vec<u64>> = None;\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n\n    let option: Option<Vec<u64>> = None;\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n\n    let option = std::option::Option::<std::vec::Vec<u64>>::None;\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n\n    let option = Option::<Vec<u64>>::None;\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n\n    let option = std::option::Option::None::<std::vec::Vec<u64>>;\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n\n    let option = Option::None::<Vec<u64>>;\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n\n    let option = None::<Vec<u64>>;\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n\n    // should not be changed: type annotation with infer, unconcretized initializer\n    let option: Option<Vec<_>> = None;\n    option.unwrap_or_else(Vec::new).push(1);\n\n    // should not be changed: no type annotation, unconcretized initializer\n    let option = Option::None;\n    option.unwrap_or_else(Vec::new).push(1);\n\n    // should not be changed: no type annotation, unconcretized initializer\n    let option = None;\n    option.unwrap_or_else(Vec::new).push(1);\n\n    type Alias = Option<Vec<u32>>;\n    let option: Alias = Option::<Vec<u32>>::Some(Vec::new());\n    option.unwrap_or_else(Vec::new).push(1);\n    //~^ unwrap_or_default\n}\n\nfn method_call_with_deref() {\n    use std::cell::RefCell;\n    use std::collections::HashMap;\n\n    let cell = RefCell::new(HashMap::<u64, HashMap<u64, String>>::new());\n\n    let mut outer_map = cell.borrow_mut();\n\n    #[allow(unused_assignments)]\n    let mut option = None;\n    option = Some(0);\n\n    let inner_map = outer_map.get_mut(&option.unwrap()).unwrap();\n\n    let _ = inner_map.entry(0).or_insert_with(Default::default);\n    //~^ unwrap_or_default\n}\n\nfn missing_suggested_method() {\n    #[derive(Copy, Clone)]\n    struct S<T>(T);\n\n    impl<T> S<T> {\n        fn or_insert_with(&mut self, default: impl FnOnce() -> T) -> &mut T {\n            &mut self.0\n        }\n\n        fn or_insert(&mut self, default: T) -> &mut T {\n            &mut self.0\n        }\n\n        fn unwrap_or_else(self, default: impl FnOnce() -> T) -> T {\n            self.0\n        }\n\n        fn unwrap_or(self, default: T) -> T {\n            self.0\n        }\n    }\n\n    // Don't lint when or_default/unwrap_or_default do not exist on the type\n    let mut s = S(1);\n    s.or_insert_with(Default::default);\n    s.or_insert(Default::default());\n    s.unwrap_or_else(Default::default);\n    s.unwrap_or(Default::default());\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/unwrap_or_else_default.stderr",
    "content": "error: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:60:23\n   |\nLL |     with_real_default.unwrap_or_else(<HasDefaultAndDuplicate as Default>::default);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n   |\n   = note: `-D clippy::unwrap-or-default` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unwrap_or_default)]`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:64:24\n   |\nLL |     with_default_trait.unwrap_or_else(Default::default);\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:68:23\n   |\nLL |     with_default_type.unwrap_or_else(u64::default);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:72:23\n   |\nLL |     with_default_type.unwrap_or_else(Vec::new);\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:76:18\n   |\nLL |     empty_string.unwrap_or_else(|| \"\".to_string());\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:81:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:85:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:89:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:93:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:97:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:101:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:105:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:109:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `unwrap_or_else` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:126:12\n   |\nLL |     option.unwrap_or_else(Vec::new).push(1);\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`\n\nerror: use of `or_insert_with` to construct default value\n  --> tests/ui/unwrap_or_else_default.rs:144:32\n   |\nLL |     let _ = inner_map.entry(0).or_insert_with(Default::default);\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui/update-all-references.sh",
    "content": "#!/bin/bash\n\necho \"Please use 'cargo bless' instead.\"\n"
  },
  {
    "path": "tests/ui/upper_case_acronyms.fixed",
    "content": "#![warn(clippy::upper_case_acronyms)]\n\nstruct HTTPResponse; // not linted by default, but with cfg option\n\nstruct CString; // not linted\n\nenum Flags {\n    NS, // not linted\n    Cwr,\n    //~^ upper_case_acronyms\n    Ece,\n    //~^ upper_case_acronyms\n    Urg,\n    //~^ upper_case_acronyms\n    Ack,\n    //~^ upper_case_acronyms\n    Psh,\n    //~^ upper_case_acronyms\n    Rst,\n    //~^ upper_case_acronyms\n    Syn,\n    //~^ upper_case_acronyms\n    Fin,\n    //~^ upper_case_acronyms\n}\n\n// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of\n// `GccLlvmSomething`\nstruct GCCLLVMSomething;\n\n// public items must not be linted\npub struct NOWARNINGHERE;\npub struct ALSONoWarningHERE;\n\n// enum variants should not be linted if the num is pub\npub enum ParseError<T> {\n    YDB(u8),\n    Utf8(std::string::FromUtf8Error),\n    Parse(T, String),\n}\n\n// private, do lint here\nenum ParseErrorPrivate<T> {\n    Wasd(u8),\n    //~^ upper_case_acronyms\n    Utf8(std::string::FromUtf8Error),\n    Parse(T, String),\n}\n\n// do lint here\nstruct Json;\n//~^ upper_case_acronyms\n\n// do lint here\nenum Yaml {\n    //~^ upper_case_acronyms\n    Num(u32),\n    Str(String),\n}\n\n// test for issue #7708\nenum AllowOnField {\n    Disallow,\n    //~^ upper_case_acronyms\n    #[allow(clippy::upper_case_acronyms)]\n    ALLOW,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/upper_case_acronyms.rs",
    "content": "#![warn(clippy::upper_case_acronyms)]\n\nstruct HTTPResponse; // not linted by default, but with cfg option\n\nstruct CString; // not linted\n\nenum Flags {\n    NS, // not linted\n    CWR,\n    //~^ upper_case_acronyms\n    ECE,\n    //~^ upper_case_acronyms\n    URG,\n    //~^ upper_case_acronyms\n    ACK,\n    //~^ upper_case_acronyms\n    PSH,\n    //~^ upper_case_acronyms\n    RST,\n    //~^ upper_case_acronyms\n    SYN,\n    //~^ upper_case_acronyms\n    FIN,\n    //~^ upper_case_acronyms\n}\n\n// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of\n// `GccLlvmSomething`\nstruct GCCLLVMSomething;\n\n// public items must not be linted\npub struct NOWARNINGHERE;\npub struct ALSONoWarningHERE;\n\n// enum variants should not be linted if the num is pub\npub enum ParseError<T> {\n    YDB(u8),\n    Utf8(std::string::FromUtf8Error),\n    Parse(T, String),\n}\n\n// private, do lint here\nenum ParseErrorPrivate<T> {\n    WASD(u8),\n    //~^ upper_case_acronyms\n    Utf8(std::string::FromUtf8Error),\n    Parse(T, String),\n}\n\n// do lint here\nstruct JSON;\n//~^ upper_case_acronyms\n\n// do lint here\nenum YAML {\n    //~^ upper_case_acronyms\n    Num(u32),\n    Str(String),\n}\n\n// test for issue #7708\nenum AllowOnField {\n    DISALLOW,\n    //~^ upper_case_acronyms\n    #[allow(clippy::upper_case_acronyms)]\n    ALLOW,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/upper_case_acronyms.stderr",
    "content": "error: name `CWR` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:9:5\n   |\nLL |     CWR,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Cwr`\n   |\n   = note: `-D clippy::upper-case-acronyms` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::upper_case_acronyms)]`\n\nerror: name `ECE` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:11:5\n   |\nLL |     ECE,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Ece`\n\nerror: name `URG` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:13:5\n   |\nLL |     URG,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Urg`\n\nerror: name `ACK` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:15:5\n   |\nLL |     ACK,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ack`\n\nerror: name `PSH` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:17:5\n   |\nLL |     PSH,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Psh`\n\nerror: name `RST` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:19:5\n   |\nLL |     RST,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Rst`\n\nerror: name `SYN` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:21:5\n   |\nLL |     SYN,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Syn`\n\nerror: name `FIN` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:23:5\n   |\nLL |     FIN,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin`\n\nerror: name `WASD` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:44:5\n   |\nLL |     WASD(u8),\n   |     ^^^^ help: consider making the acronym lowercase, except the initial letter: `Wasd`\n\nerror: name `JSON` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:51:8\n   |\nLL | struct JSON;\n   |        ^^^^ help: consider making the acronym lowercase, except the initial letter: `Json`\n\nerror: name `YAML` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:55:6\n   |\nLL | enum YAML {\n   |      ^^^^ help: consider making the acronym lowercase, except the initial letter: `Yaml`\n\nerror: name `DISALLOW` contains a capitalized acronym\n  --> tests/ui/upper_case_acronyms.rs:63:5\n   |\nLL |     DISALLOW,\n   |     ^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `Disallow`\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/use_debug.rs",
    "content": "#![warn(clippy::use_debug)]\n\nuse std::fmt::{Debug, Display, Formatter, Result};\n\nstruct Foo;\n\nimpl Display for Foo {\n    fn fmt(&self, f: &mut Formatter) -> Result {\n        write!(f, \"{:?}\", 43.1415)\n        //~^ use_debug\n    }\n}\n\nimpl Debug for Foo {\n    fn fmt(&self, f: &mut Formatter) -> Result {\n        // ok, we can use `Debug` formatting in `Debug` implementations\n        write!(f, \"{:?}\", 42.718)\n    }\n}\n\nfn main() {\n    print!(\"Hello {:?}\", \"World\");\n    //~^ use_debug\n\n    print!(\"Hello {:#?}\", \"#orld\");\n    //~^ use_debug\n\n    assert_eq!(42, 1337);\n\n    vec![1, 2];\n}\n\n// don't get confused by nested impls\nfn issue15942() {\n    struct Bar;\n    impl Debug for Bar {\n        fn fmt(&self, f: &mut Formatter) -> Result {\n            struct Baz;\n            impl Debug for Baz {\n                fn fmt(&self, f: &mut Formatter) -> Result {\n                    // ok, we can use `Debug` formatting in `Debug` implementations\n                    write!(f, \"{:?}\", 42.718)\n                }\n            }\n\n            // ok, we can use `Debug` formatting in `Debug` implementations\n            write!(f, \"{:?}\", 42.718)\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/use_debug.stderr",
    "content": "error: use of `Debug`-based formatting\n  --> tests/ui/use_debug.rs:9:20\n   |\nLL |         write!(f, \"{:?}\", 43.1415)\n   |                    ^^^^\n   |\n   = note: `-D clippy::use-debug` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::use_debug)]`\n\nerror: use of `Debug`-based formatting\n  --> tests/ui/use_debug.rs:22:19\n   |\nLL |     print!(\"Hello {:?}\", \"World\");\n   |                   ^^^^\n\nerror: use of `Debug`-based formatting\n  --> tests/ui/use_debug.rs:25:19\n   |\nLL |     print!(\"Hello {:#?}\", \"#orld\");\n   |                   ^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/use_self.fixed",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::use_self)]\n#![allow(dead_code, unreachable_code)]\n#![allow(\n    clippy::should_implement_trait,\n    clippy::upper_case_acronyms,\n    clippy::from_over_into,\n    clippy::self_named_constructors,\n    clippy::needless_lifetimes,\n    clippy::missing_transmute_annotations\n)]\n#![allow(incomplete_features)]\n#![feature(adt_const_params)]\n#![feature(unsized_const_params)]\n\n#[macro_use]\nextern crate proc_macro_derive;\n\nfn main() {}\n\nmod use_self {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Self {\n            //~^ use_self\n            Self {}\n            //~^ use_self\n        }\n        fn test() -> Self {\n            //~^ use_self\n            Self::new()\n            //~^ use_self\n        }\n    }\n\n    impl Default for Foo {\n        fn default() -> Self {\n            //~^ use_self\n            Self::new()\n            //~^ use_self\n        }\n    }\n}\n\nmod better {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Self {\n            Self {}\n        }\n        fn test() -> Self {\n            Self::new()\n        }\n    }\n\n    impl Default for Foo {\n        fn default() -> Self {\n            Self::new()\n        }\n    }\n}\n\nmod lifetimes {\n    #[derive(Clone, Copy)]\n    struct Foo<'a> {\n        foo_str: &'a str,\n    }\n\n    impl<'a> Foo<'a> {\n        // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->\n        // Foo<'b>`\n        fn foo(s: &str) -> Foo<'_> {\n            Foo { foo_str: s }\n        }\n        // cannot replace with `Self`, because that's `Foo<'a>`\n        fn bar() -> Foo<'static> {\n            Foo { foo_str: \"foo\" }\n        }\n\n        fn clone(&self) -> Self {\n            //~^ use_self\n            Foo { foo_str: self.foo_str }\n        }\n\n        // Cannot replace with `Self` because the lifetime is not `'a`.\n        fn eq<'b>(&self, other: Foo<'b>) -> bool {\n            let x: Foo<'_> = other;\n            self.foo_str == other.foo_str\n        }\n\n        fn f(&self) -> Foo<'_> {\n            *self\n        }\n    }\n}\n\nmod issue2894 {\n    trait IntoBytes {\n        fn to_bytes(self) -> Vec<u8>;\n    }\n\n    // This should not be linted\n    impl IntoBytes for u8 {\n        fn to_bytes(self) -> Vec<u8> {\n            vec![self]\n        }\n    }\n}\n\nmod existential {\n    struct Foo;\n\n    impl Foo {\n        fn bad(foos: &[Self]) -> impl Iterator<Item = &Self> {\n            //~^ use_self\n            //~| use_self\n            foos.iter()\n        }\n\n        fn good(foos: &[Self]) -> impl Iterator<Item = &Self> {\n            foos.iter()\n        }\n    }\n}\n\nmod tuple_structs {\n    pub struct TS(i32);\n\n    impl TS {\n        pub fn ts() -> Self {\n            Self(0)\n            //~^ use_self\n        }\n    }\n}\n\nmod macros {\n    macro_rules! use_self_expand {\n        () => {\n            fn new() -> Foo {\n                Foo {}\n            }\n        };\n    }\n\n    struct Foo;\n\n    impl Foo {\n        use_self_expand!(); // Should not lint in local macros\n    }\n\n    #[derive(StructAUseSelf)] // Should not lint in derives\n    struct A;\n}\n\nmod nesting {\n    struct Foo;\n    impl Foo {\n        fn foo() {\n            #[allow(unused_imports)]\n            use self::Foo; // Can't use Self here\n            struct Bar {\n                foo: Foo, // Foo != Self\n            }\n\n            impl Bar {\n                fn bar() -> Self {\n                    //~^ use_self\n                    Self { foo: Foo {} }\n                    //~^ use_self\n                }\n            }\n\n            // Can't use Self here\n            fn baz() -> Foo {\n                Foo {}\n            }\n        }\n\n        // Should lint here\n        fn baz() -> Self {\n            //~^ use_self\n            Self {}\n            //~^ use_self\n        }\n    }\n\n    enum Enum {\n        A,\n        B(u64),\n        C { field: bool },\n    }\n    impl Enum {\n        fn method() {\n            #[allow(unused_imports)]\n            use self::Enum::*; // Issue 3425\n            static STATIC: Enum = Enum::A; // Can't use Self as type\n        }\n\n        fn method2() {\n            let _ = Self::B(42);\n            //~^ use_self\n            let _ = Self::C { field: true };\n            //~^ use_self\n            let _ = Self::A;\n            //~^ use_self\n        }\n    }\n}\n\nmod issue3410 {\n\n    struct A;\n    struct B;\n\n    trait Trait<T> {\n        fn a(v: T) -> Self;\n    }\n\n    impl Trait<Vec<A>> for Vec<B> {\n        fn a(_: Vec<A>) -> Self {\n            unimplemented!()\n        }\n    }\n\n    impl<T> Trait<Vec<A>> for Vec<T>\n    where\n        T: Trait<B>,\n    {\n        fn a(v: Vec<A>) -> Self {\n            <Vec<B>>::a(v).into_iter().map(Trait::a).collect()\n        }\n    }\n}\n\n#[allow(clippy::no_effect, path_statements)]\nmod rustfix {\n    mod nested {\n        pub struct A;\n    }\n\n    impl nested::A {\n        const A: bool = true;\n\n        fn fun_1() {}\n\n        fn fun_2() {\n            Self::fun_1();\n            //~^ use_self\n            Self::A;\n            //~^ use_self\n\n            Self {};\n            //~^ use_self\n        }\n    }\n}\n\nmod issue3567 {\n    struct TestStruct;\n    impl TestStruct {\n        fn from_something() -> Self {\n            Self {}\n        }\n    }\n\n    trait Test {\n        fn test() -> TestStruct;\n    }\n\n    impl Test for TestStruct {\n        fn test() -> TestStruct {\n            Self::from_something()\n            //~^ use_self\n        }\n    }\n}\n\nmod paths_created_by_lowering {\n    use std::ops::Range;\n\n    struct S;\n\n    impl S {\n        const A: usize = 0;\n        const B: usize = 1;\n\n        async fn g() -> Self {\n            //~^ use_self\n            Self {}\n            //~^ use_self\n        }\n\n        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {\n            &p[Self::A..Self::B]\n            //~^ use_self\n            //~| use_self\n        }\n    }\n\n    trait T {\n        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8];\n    }\n\n    impl T for Range<u8> {\n        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {\n            &p[0..1]\n        }\n    }\n}\n\n// reused from #1997\nmod generics {\n    struct Foo<T> {\n        value: T,\n    }\n\n    impl<T> Foo<T> {\n        // `Self` is applicable here\n        fn foo(value: T) -> Self {\n            //~^ use_self\n            Self { value }\n            //~^ use_self\n        }\n\n        // `Cannot` use `Self` as a return type as the generic types are different\n        fn bar(value: i32) -> Foo<i32> {\n            Foo { value }\n        }\n    }\n}\n\nmod issue4140 {\n    pub struct Error<From, To> {\n        _from: From,\n        _too: To,\n    }\n\n    pub trait From<T> {\n        type From;\n        type To;\n\n        fn from(value: T) -> Self;\n    }\n\n    pub trait TryFrom<T>\n    where\n        Self: Sized,\n    {\n        type From;\n        type To;\n\n        fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;\n    }\n\n    // FIXME: Suggested fix results in infinite recursion.\n    // impl<F, T> TryFrom<F> for T\n    // where\n    //     T: From<F>,\n    // {\n    //     type From = Self::From;\n    //     type To = Self::To;\n\n    //     fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {\n    //         Ok(From::from(value))\n    //     }\n    // }\n\n    impl From<bool> for i64 {\n        type From = bool;\n        type To = Self;\n\n        fn from(value: bool) -> Self {\n            if value { 100 } else { 0 }\n        }\n    }\n}\n\nmod issue2843 {\n    trait Foo {\n        type Bar;\n    }\n\n    impl Foo for usize {\n        type Bar = u8;\n    }\n\n    impl<T: Foo> Foo for Option<T> {\n        type Bar = Option<T::Bar>;\n    }\n}\n\nmod issue3859 {\n    pub struct Foo;\n    pub struct Bar([usize; 3]);\n\n    impl Foo {\n        pub const BAR: usize = 3;\n\n        pub fn foo() {\n            const _X: usize = Foo::BAR;\n            // const _Y: usize = Self::BAR;\n        }\n    }\n}\n\nmod issue4305 {\n    trait Foo: 'static {}\n\n    struct Bar;\n\n    impl Foo for Bar {}\n\n    impl<T: Foo> From<T> for Box<dyn Foo> {\n        fn from(t: T) -> Self {\n            Box::new(t)\n        }\n    }\n}\n\nmod lint_at_item_level {\n    struct Foo;\n\n    #[allow(clippy::use_self)]\n    impl Foo {\n        fn new() -> Foo {\n            Foo {}\n        }\n    }\n\n    #[allow(clippy::use_self)]\n    impl Default for Foo {\n        fn default() -> Foo {\n            Foo::new()\n        }\n    }\n}\n\nmod lint_at_impl_item_level {\n    struct Foo;\n\n    impl Foo {\n        #[allow(clippy::use_self)]\n        fn new() -> Foo {\n            Foo {}\n        }\n    }\n\n    impl Default for Foo {\n        #[allow(clippy::use_self)]\n        fn default() -> Foo {\n            Foo::new()\n        }\n    }\n}\n\nmod issue4734 {\n    #[repr(C, packed)]\n    pub struct X {\n        pub x: u32,\n    }\n\n    impl From<X> for u32 {\n        fn from(c: X) -> Self {\n            unsafe { core::mem::transmute(c) }\n        }\n    }\n}\n\nmod nested_paths {\n    use std::convert::Into;\n    mod submod {\n        pub struct B;\n        pub struct C;\n\n        impl Into<C> for B {\n            fn into(self) -> C {\n                C {}\n            }\n        }\n    }\n\n    struct A<T> {\n        t: T,\n    }\n\n    impl<T> A<T> {\n        fn new<V: Into<T>>(v: V) -> Self {\n            Self { t: Into::into(v) }\n        }\n    }\n\n    impl A<submod::C> {\n        fn test() -> Self {\n            Self::new::<submod::B>(submod::B {})\n            //~^ use_self\n        }\n    }\n}\n\nmod issue6818 {\n    #[derive(serde::Deserialize)]\n    struct A {\n        a: i32,\n    }\n}\n\nmod issue7206 {\n    struct MyStruct<const C: char>;\n    impl From<MyStruct<'a'>> for MyStruct<'b'> {\n        fn from(_s: MyStruct<'a'>) -> Self {\n            Self\n        }\n    }\n\n    // keep linting non-`Const` generic args\n    struct S<'a> {\n        inner: &'a str,\n    }\n\n    struct S2<T> {\n        inner: T,\n    }\n\n    impl<T> S2<T> {\n        fn new() -> Self {\n            unimplemented!();\n        }\n    }\n\n    impl<'a> S2<S<'a>> {\n        fn new_again() -> Self {\n            S2::new()\n            // FIXME: ^Broken by PR #15611\n        }\n    }\n}\n\nmod self_is_ty_param {\n    trait Trait {\n        type Type;\n        type Hi;\n\n        fn test();\n    }\n\n    impl<I> Trait for I\n    where\n        I: Iterator,\n        I::Item: Trait, // changing this to Self would require <Self as Iterator>\n    {\n        type Type = I;\n        type Hi = I::Item;\n\n        fn test() {\n            let _: I::Item;\n            let _: I; // this could lint, but is questionable\n        }\n    }\n}\n\nmod use_self_in_pat {\n    enum Foo {\n        Bar,\n        Baz,\n    }\n\n    impl Foo {\n        fn do_stuff(self) {\n            match self {\n                Self::Bar => unimplemented!(),\n                //~^ use_self\n                Self::Baz => unimplemented!(),\n                //~^ use_self\n            }\n            match Some(1) {\n                Some(_) => unimplemented!(),\n                None => unimplemented!(),\n            }\n            if let Self::Bar = self {\n                //~^ use_self\n                unimplemented!()\n            }\n        }\n    }\n}\n\nmod issue8845 {\n    pub enum Something {\n        Num(u8),\n        TupleNums(u8, u8),\n        StructNums { one: u8, two: u8 },\n    }\n\n    struct Foo(u8);\n\n    struct Bar {\n        x: u8,\n        y: usize,\n    }\n\n    impl Something {\n        fn get_value(&self) -> u8 {\n            match self {\n                Self::Num(n) => *n,\n                //~^ use_self\n                Self::TupleNums(n, _m) => *n,\n                //~^ use_self\n                Self::StructNums { one, two: _ } => *one,\n                //~^ use_self\n            }\n        }\n\n        fn use_crate(&self) -> u8 {\n            match self {\n                Self::Num(n) => *n,\n                //~^ use_self\n                Self::TupleNums(n, _m) => *n,\n                //~^ use_self\n                Self::StructNums { one, two: _ } => *one,\n                //~^ use_self\n            }\n        }\n\n        fn imported_values(&self) -> u8 {\n            use Something::*;\n            match self {\n                Num(n) => *n,\n                TupleNums(n, _m) => *n,\n                StructNums { one, two: _ } => *one,\n            }\n        }\n    }\n\n    impl Foo {\n        fn get_value(&self) -> u8 {\n            let Self(x) = self;\n            //~^ use_self\n            *x\n        }\n\n        fn use_crate(&self) -> u8 {\n            let Self(x) = self;\n            //~^ use_self\n            *x\n        }\n    }\n\n    impl Bar {\n        fn get_value(&self) -> u8 {\n            let Self { x, .. } = self;\n            //~^ use_self\n            *x\n        }\n\n        fn use_crate(&self) -> u8 {\n            let Self { x, .. } = self;\n            //~^ use_self\n            *x\n        }\n    }\n}\n\nmod issue6902 {\n    use serde::Serialize;\n\n    #[derive(Serialize)]\n    pub enum Foo {\n        Bar = 1,\n    }\n}\n\n#[clippy::msrv = \"1.36\"]\nfn msrv_1_36() {\n    enum E {\n        A,\n    }\n\n    impl E {\n        fn foo(self) {\n            match self {\n                E::A => {},\n            }\n        }\n    }\n}\n\n#[clippy::msrv = \"1.37\"]\nfn msrv_1_37() {\n    enum E {\n        A,\n    }\n\n    impl E {\n        fn foo(self) {\n            match self {\n                Self::A => {},\n                //~^ use_self\n            }\n        }\n    }\n}\n\nmod issue_10371 {\n    struct Val<const V: i32> {}\n\n    impl<const V: i32> From<Val<V>> for i32 {\n        fn from(_: Val<V>) -> Self {\n            todo!()\n        }\n    }\n}\n\nmod issue_13092 {\n    use std::cell::RefCell;\n    macro_rules! macro_inner_item {\n        ($ty:ty) => {\n            fn foo(_: $ty) {\n                fn inner(_: $ty) {}\n            }\n        };\n    }\n\n    #[derive(Default)]\n    struct MyStruct;\n\n    impl MyStruct {\n        macro_inner_item!(MyStruct);\n    }\n\n    impl MyStruct {\n        thread_local! {\n            static SPECIAL: RefCell<MyStruct> = RefCell::default();\n        }\n    }\n}\n\nmod crash_check_13128 {\n    struct A;\n\n    impl A {\n        fn a() {\n            struct B;\n\n            // pushes a NoCheck\n            impl Iterator for &B {\n                // Pops the NoCheck\n                type Item = A;\n\n                // Lints A -> Self\n                fn next(&mut self) -> Option<A> {\n                    Some(A)\n                }\n            }\n        }\n    }\n}\n\nmod issue_13277 {\n    trait Foo {\n        type Item<'foo>;\n    }\n    struct Bar<'b> {\n        content: &'b str,\n    }\n    impl<'b> Foo for Option<Bar<'b>> {\n        // when checking whether `Option<Bar<'foo>>` has a lifetime, check not only the outer\n        // `Option<T>`, but also the inner `Bar<'foo>`\n        type Item<'foo> = Option<Bar<'foo>>;\n    }\n}\n\nmod issue16164 {\n    trait Bits {\n        fn bit<const I: u8>(self) -> bool;\n    }\n\n    impl Bits for u8 {\n        fn bit<const I: u8>(self) -> bool {\n            todo!()\n        }\n    }\n\n    trait T {\n        fn f<const C: (u8, u8)>(self) -> bool;\n    }\n\n    impl T for u8 {\n        fn f<const C: (u8, u8)>(self) -> bool {\n            todo!()\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/use_self.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::use_self)]\n#![allow(dead_code, unreachable_code)]\n#![allow(\n    clippy::should_implement_trait,\n    clippy::upper_case_acronyms,\n    clippy::from_over_into,\n    clippy::self_named_constructors,\n    clippy::needless_lifetimes,\n    clippy::missing_transmute_annotations\n)]\n#![allow(incomplete_features)]\n#![feature(adt_const_params)]\n#![feature(unsized_const_params)]\n\n#[macro_use]\nextern crate proc_macro_derive;\n\nfn main() {}\n\nmod use_self {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Foo {\n            //~^ use_self\n            Foo {}\n            //~^ use_self\n        }\n        fn test() -> Foo {\n            //~^ use_self\n            Foo::new()\n            //~^ use_self\n        }\n    }\n\n    impl Default for Foo {\n        fn default() -> Foo {\n            //~^ use_self\n            Foo::new()\n            //~^ use_self\n        }\n    }\n}\n\nmod better {\n    struct Foo;\n\n    impl Foo {\n        fn new() -> Self {\n            Self {}\n        }\n        fn test() -> Self {\n            Self::new()\n        }\n    }\n\n    impl Default for Foo {\n        fn default() -> Self {\n            Self::new()\n        }\n    }\n}\n\nmod lifetimes {\n    #[derive(Clone, Copy)]\n    struct Foo<'a> {\n        foo_str: &'a str,\n    }\n\n    impl<'a> Foo<'a> {\n        // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->\n        // Foo<'b>`\n        fn foo(s: &str) -> Foo<'_> {\n            Foo { foo_str: s }\n        }\n        // cannot replace with `Self`, because that's `Foo<'a>`\n        fn bar() -> Foo<'static> {\n            Foo { foo_str: \"foo\" }\n        }\n\n        fn clone(&self) -> Foo<'a> {\n            //~^ use_self\n            Foo { foo_str: self.foo_str }\n        }\n\n        // Cannot replace with `Self` because the lifetime is not `'a`.\n        fn eq<'b>(&self, other: Foo<'b>) -> bool {\n            let x: Foo<'_> = other;\n            self.foo_str == other.foo_str\n        }\n\n        fn f(&self) -> Foo<'_> {\n            *self\n        }\n    }\n}\n\nmod issue2894 {\n    trait IntoBytes {\n        fn to_bytes(self) -> Vec<u8>;\n    }\n\n    // This should not be linted\n    impl IntoBytes for u8 {\n        fn to_bytes(self) -> Vec<u8> {\n            vec![self]\n        }\n    }\n}\n\nmod existential {\n    struct Foo;\n\n    impl Foo {\n        fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {\n            //~^ use_self\n            //~| use_self\n            foos.iter()\n        }\n\n        fn good(foos: &[Self]) -> impl Iterator<Item = &Self> {\n            foos.iter()\n        }\n    }\n}\n\nmod tuple_structs {\n    pub struct TS(i32);\n\n    impl TS {\n        pub fn ts() -> Self {\n            TS(0)\n            //~^ use_self\n        }\n    }\n}\n\nmod macros {\n    macro_rules! use_self_expand {\n        () => {\n            fn new() -> Foo {\n                Foo {}\n            }\n        };\n    }\n\n    struct Foo;\n\n    impl Foo {\n        use_self_expand!(); // Should not lint in local macros\n    }\n\n    #[derive(StructAUseSelf)] // Should not lint in derives\n    struct A;\n}\n\nmod nesting {\n    struct Foo;\n    impl Foo {\n        fn foo() {\n            #[allow(unused_imports)]\n            use self::Foo; // Can't use Self here\n            struct Bar {\n                foo: Foo, // Foo != Self\n            }\n\n            impl Bar {\n                fn bar() -> Bar {\n                    //~^ use_self\n                    Bar { foo: Foo {} }\n                    //~^ use_self\n                }\n            }\n\n            // Can't use Self here\n            fn baz() -> Foo {\n                Foo {}\n            }\n        }\n\n        // Should lint here\n        fn baz() -> Foo {\n            //~^ use_self\n            Foo {}\n            //~^ use_self\n        }\n    }\n\n    enum Enum {\n        A,\n        B(u64),\n        C { field: bool },\n    }\n    impl Enum {\n        fn method() {\n            #[allow(unused_imports)]\n            use self::Enum::*; // Issue 3425\n            static STATIC: Enum = Enum::A; // Can't use Self as type\n        }\n\n        fn method2() {\n            let _ = Enum::B(42);\n            //~^ use_self\n            let _ = Enum::C { field: true };\n            //~^ use_self\n            let _ = Enum::A;\n            //~^ use_self\n        }\n    }\n}\n\nmod issue3410 {\n\n    struct A;\n    struct B;\n\n    trait Trait<T> {\n        fn a(v: T) -> Self;\n    }\n\n    impl Trait<Vec<A>> for Vec<B> {\n        fn a(_: Vec<A>) -> Self {\n            unimplemented!()\n        }\n    }\n\n    impl<T> Trait<Vec<A>> for Vec<T>\n    where\n        T: Trait<B>,\n    {\n        fn a(v: Vec<A>) -> Self {\n            <Vec<B>>::a(v).into_iter().map(Trait::a).collect()\n        }\n    }\n}\n\n#[allow(clippy::no_effect, path_statements)]\nmod rustfix {\n    mod nested {\n        pub struct A;\n    }\n\n    impl nested::A {\n        const A: bool = true;\n\n        fn fun_1() {}\n\n        fn fun_2() {\n            nested::A::fun_1();\n            //~^ use_self\n            nested::A::A;\n            //~^ use_self\n\n            nested::A {};\n            //~^ use_self\n        }\n    }\n}\n\nmod issue3567 {\n    struct TestStruct;\n    impl TestStruct {\n        fn from_something() -> Self {\n            Self {}\n        }\n    }\n\n    trait Test {\n        fn test() -> TestStruct;\n    }\n\n    impl Test for TestStruct {\n        fn test() -> TestStruct {\n            TestStruct::from_something()\n            //~^ use_self\n        }\n    }\n}\n\nmod paths_created_by_lowering {\n    use std::ops::Range;\n\n    struct S;\n\n    impl S {\n        const A: usize = 0;\n        const B: usize = 1;\n\n        async fn g() -> S {\n            //~^ use_self\n            S {}\n            //~^ use_self\n        }\n\n        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {\n            &p[S::A..S::B]\n            //~^ use_self\n            //~| use_self\n        }\n    }\n\n    trait T {\n        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8];\n    }\n\n    impl T for Range<u8> {\n        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {\n            &p[0..1]\n        }\n    }\n}\n\n// reused from #1997\nmod generics {\n    struct Foo<T> {\n        value: T,\n    }\n\n    impl<T> Foo<T> {\n        // `Self` is applicable here\n        fn foo(value: T) -> Foo<T> {\n            //~^ use_self\n            Foo::<T> { value }\n            //~^ use_self\n        }\n\n        // `Cannot` use `Self` as a return type as the generic types are different\n        fn bar(value: i32) -> Foo<i32> {\n            Foo { value }\n        }\n    }\n}\n\nmod issue4140 {\n    pub struct Error<From, To> {\n        _from: From,\n        _too: To,\n    }\n\n    pub trait From<T> {\n        type From;\n        type To;\n\n        fn from(value: T) -> Self;\n    }\n\n    pub trait TryFrom<T>\n    where\n        Self: Sized,\n    {\n        type From;\n        type To;\n\n        fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;\n    }\n\n    // FIXME: Suggested fix results in infinite recursion.\n    // impl<F, T> TryFrom<F> for T\n    // where\n    //     T: From<F>,\n    // {\n    //     type From = Self::From;\n    //     type To = Self::To;\n\n    //     fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {\n    //         Ok(From::from(value))\n    //     }\n    // }\n\n    impl From<bool> for i64 {\n        type From = bool;\n        type To = Self;\n\n        fn from(value: bool) -> Self {\n            if value { 100 } else { 0 }\n        }\n    }\n}\n\nmod issue2843 {\n    trait Foo {\n        type Bar;\n    }\n\n    impl Foo for usize {\n        type Bar = u8;\n    }\n\n    impl<T: Foo> Foo for Option<T> {\n        type Bar = Option<T::Bar>;\n    }\n}\n\nmod issue3859 {\n    pub struct Foo;\n    pub struct Bar([usize; 3]);\n\n    impl Foo {\n        pub const BAR: usize = 3;\n\n        pub fn foo() {\n            const _X: usize = Foo::BAR;\n            // const _Y: usize = Self::BAR;\n        }\n    }\n}\n\nmod issue4305 {\n    trait Foo: 'static {}\n\n    struct Bar;\n\n    impl Foo for Bar {}\n\n    impl<T: Foo> From<T> for Box<dyn Foo> {\n        fn from(t: T) -> Self {\n            Box::new(t)\n        }\n    }\n}\n\nmod lint_at_item_level {\n    struct Foo;\n\n    #[allow(clippy::use_self)]\n    impl Foo {\n        fn new() -> Foo {\n            Foo {}\n        }\n    }\n\n    #[allow(clippy::use_self)]\n    impl Default for Foo {\n        fn default() -> Foo {\n            Foo::new()\n        }\n    }\n}\n\nmod lint_at_impl_item_level {\n    struct Foo;\n\n    impl Foo {\n        #[allow(clippy::use_self)]\n        fn new() -> Foo {\n            Foo {}\n        }\n    }\n\n    impl Default for Foo {\n        #[allow(clippy::use_self)]\n        fn default() -> Foo {\n            Foo::new()\n        }\n    }\n}\n\nmod issue4734 {\n    #[repr(C, packed)]\n    pub struct X {\n        pub x: u32,\n    }\n\n    impl From<X> for u32 {\n        fn from(c: X) -> Self {\n            unsafe { core::mem::transmute(c) }\n        }\n    }\n}\n\nmod nested_paths {\n    use std::convert::Into;\n    mod submod {\n        pub struct B;\n        pub struct C;\n\n        impl Into<C> for B {\n            fn into(self) -> C {\n                C {}\n            }\n        }\n    }\n\n    struct A<T> {\n        t: T,\n    }\n\n    impl<T> A<T> {\n        fn new<V: Into<T>>(v: V) -> Self {\n            Self { t: Into::into(v) }\n        }\n    }\n\n    impl A<submod::C> {\n        fn test() -> Self {\n            A::new::<submod::B>(submod::B {})\n            //~^ use_self\n        }\n    }\n}\n\nmod issue6818 {\n    #[derive(serde::Deserialize)]\n    struct A {\n        a: i32,\n    }\n}\n\nmod issue7206 {\n    struct MyStruct<const C: char>;\n    impl From<MyStruct<'a'>> for MyStruct<'b'> {\n        fn from(_s: MyStruct<'a'>) -> Self {\n            Self\n        }\n    }\n\n    // keep linting non-`Const` generic args\n    struct S<'a> {\n        inner: &'a str,\n    }\n\n    struct S2<T> {\n        inner: T,\n    }\n\n    impl<T> S2<T> {\n        fn new() -> Self {\n            unimplemented!();\n        }\n    }\n\n    impl<'a> S2<S<'a>> {\n        fn new_again() -> Self {\n            S2::new()\n            // FIXME: ^Broken by PR #15611\n        }\n    }\n}\n\nmod self_is_ty_param {\n    trait Trait {\n        type Type;\n        type Hi;\n\n        fn test();\n    }\n\n    impl<I> Trait for I\n    where\n        I: Iterator,\n        I::Item: Trait, // changing this to Self would require <Self as Iterator>\n    {\n        type Type = I;\n        type Hi = I::Item;\n\n        fn test() {\n            let _: I::Item;\n            let _: I; // this could lint, but is questionable\n        }\n    }\n}\n\nmod use_self_in_pat {\n    enum Foo {\n        Bar,\n        Baz,\n    }\n\n    impl Foo {\n        fn do_stuff(self) {\n            match self {\n                Foo::Bar => unimplemented!(),\n                //~^ use_self\n                Foo::Baz => unimplemented!(),\n                //~^ use_self\n            }\n            match Some(1) {\n                Some(_) => unimplemented!(),\n                None => unimplemented!(),\n            }\n            if let Foo::Bar = self {\n                //~^ use_self\n                unimplemented!()\n            }\n        }\n    }\n}\n\nmod issue8845 {\n    pub enum Something {\n        Num(u8),\n        TupleNums(u8, u8),\n        StructNums { one: u8, two: u8 },\n    }\n\n    struct Foo(u8);\n\n    struct Bar {\n        x: u8,\n        y: usize,\n    }\n\n    impl Something {\n        fn get_value(&self) -> u8 {\n            match self {\n                Something::Num(n) => *n,\n                //~^ use_self\n                Something::TupleNums(n, _m) => *n,\n                //~^ use_self\n                Something::StructNums { one, two: _ } => *one,\n                //~^ use_self\n            }\n        }\n\n        fn use_crate(&self) -> u8 {\n            match self {\n                crate::issue8845::Something::Num(n) => *n,\n                //~^ use_self\n                crate::issue8845::Something::TupleNums(n, _m) => *n,\n                //~^ use_self\n                crate::issue8845::Something::StructNums { one, two: _ } => *one,\n                //~^ use_self\n            }\n        }\n\n        fn imported_values(&self) -> u8 {\n            use Something::*;\n            match self {\n                Num(n) => *n,\n                TupleNums(n, _m) => *n,\n                StructNums { one, two: _ } => *one,\n            }\n        }\n    }\n\n    impl Foo {\n        fn get_value(&self) -> u8 {\n            let Foo(x) = self;\n            //~^ use_self\n            *x\n        }\n\n        fn use_crate(&self) -> u8 {\n            let crate::issue8845::Foo(x) = self;\n            //~^ use_self\n            *x\n        }\n    }\n\n    impl Bar {\n        fn get_value(&self) -> u8 {\n            let Bar { x, .. } = self;\n            //~^ use_self\n            *x\n        }\n\n        fn use_crate(&self) -> u8 {\n            let crate::issue8845::Bar { x, .. } = self;\n            //~^ use_self\n            *x\n        }\n    }\n}\n\nmod issue6902 {\n    use serde::Serialize;\n\n    #[derive(Serialize)]\n    pub enum Foo {\n        Bar = 1,\n    }\n}\n\n#[clippy::msrv = \"1.36\"]\nfn msrv_1_36() {\n    enum E {\n        A,\n    }\n\n    impl E {\n        fn foo(self) {\n            match self {\n                E::A => {},\n            }\n        }\n    }\n}\n\n#[clippy::msrv = \"1.37\"]\nfn msrv_1_37() {\n    enum E {\n        A,\n    }\n\n    impl E {\n        fn foo(self) {\n            match self {\n                E::A => {},\n                //~^ use_self\n            }\n        }\n    }\n}\n\nmod issue_10371 {\n    struct Val<const V: i32> {}\n\n    impl<const V: i32> From<Val<V>> for i32 {\n        fn from(_: Val<V>) -> Self {\n            todo!()\n        }\n    }\n}\n\nmod issue_13092 {\n    use std::cell::RefCell;\n    macro_rules! macro_inner_item {\n        ($ty:ty) => {\n            fn foo(_: $ty) {\n                fn inner(_: $ty) {}\n            }\n        };\n    }\n\n    #[derive(Default)]\n    struct MyStruct;\n\n    impl MyStruct {\n        macro_inner_item!(MyStruct);\n    }\n\n    impl MyStruct {\n        thread_local! {\n            static SPECIAL: RefCell<MyStruct> = RefCell::default();\n        }\n    }\n}\n\nmod crash_check_13128 {\n    struct A;\n\n    impl A {\n        fn a() {\n            struct B;\n\n            // pushes a NoCheck\n            impl Iterator for &B {\n                // Pops the NoCheck\n                type Item = A;\n\n                // Lints A -> Self\n                fn next(&mut self) -> Option<A> {\n                    Some(A)\n                }\n            }\n        }\n    }\n}\n\nmod issue_13277 {\n    trait Foo {\n        type Item<'foo>;\n    }\n    struct Bar<'b> {\n        content: &'b str,\n    }\n    impl<'b> Foo for Option<Bar<'b>> {\n        // when checking whether `Option<Bar<'foo>>` has a lifetime, check not only the outer\n        // `Option<T>`, but also the inner `Bar<'foo>`\n        type Item<'foo> = Option<Bar<'foo>>;\n    }\n}\n\nmod issue16164 {\n    trait Bits {\n        fn bit<const I: u8>(self) -> bool;\n    }\n\n    impl Bits for u8 {\n        fn bit<const I: u8>(self) -> bool {\n            todo!()\n        }\n    }\n\n    trait T {\n        fn f<const C: (u8, u8)>(self) -> bool;\n    }\n\n    impl T for u8 {\n        fn f<const C: (u8, u8)>(self) -> bool {\n            todo!()\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/use_self.stderr",
    "content": "error: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:26:21\n   |\nLL |         fn new() -> Foo {\n   |                     ^^^ help: use the applicable keyword: `Self`\n   |\n   = note: `-D clippy::use-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::use_self)]`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:28:13\n   |\nLL |             Foo {}\n   |             ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:31:22\n   |\nLL |         fn test() -> Foo {\n   |                      ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:33:13\n   |\nLL |             Foo::new()\n   |             ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:39:25\n   |\nLL |         fn default() -> Foo {\n   |                         ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:41:13\n   |\nLL |             Foo::new()\n   |             ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:83:28\n   |\nLL |         fn clone(&self) -> Foo<'a> {\n   |                            ^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:117:24\n   |\nLL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {\n   |                        ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:117:55\n   |\nLL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {\n   |                                                       ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:134:13\n   |\nLL |             TS(0)\n   |             ^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:170:29\n   |\nLL |                 fn bar() -> Bar {\n   |                             ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:172:21\n   |\nLL |                     Bar { foo: Foo {} }\n   |                     ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:184:21\n   |\nLL |         fn baz() -> Foo {\n   |                     ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:186:13\n   |\nLL |             Foo {}\n   |             ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:204:21\n   |\nLL |             let _ = Enum::B(42);\n   |                     ^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:206:21\n   |\nLL |             let _ = Enum::C { field: true };\n   |                     ^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:208:21\n   |\nLL |             let _ = Enum::A;\n   |                     ^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:251:13\n   |\nLL |             nested::A::fun_1();\n   |             ^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:253:13\n   |\nLL |             nested::A::A;\n   |             ^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:256:13\n   |\nLL |             nested::A {};\n   |             ^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:276:13\n   |\nLL |             TestStruct::from_something()\n   |             ^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:291:25\n   |\nLL |         async fn g() -> S {\n   |                         ^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:293:13\n   |\nLL |             S {}\n   |             ^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:298:16\n   |\nLL |             &p[S::A..S::B]\n   |                ^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:298:22\n   |\nLL |             &p[S::A..S::B]\n   |                      ^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:323:29\n   |\nLL |         fn foo(value: T) -> Foo<T> {\n   |                             ^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:325:13\n   |\nLL |             Foo::<T> { value }\n   |             ^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:498:13\n   |\nLL |             A::new::<submod::B>(submod::B {})\n   |             ^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:574:17\n   |\nLL |                 Foo::Bar => unimplemented!(),\n   |                 ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:576:17\n   |\nLL |                 Foo::Baz => unimplemented!(),\n   |                 ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:583:20\n   |\nLL |             if let Foo::Bar = self {\n   |                    ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:608:17\n   |\nLL |                 Something::Num(n) => *n,\n   |                 ^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:610:17\n   |\nLL |                 Something::TupleNums(n, _m) => *n,\n   |                 ^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:612:17\n   |\nLL |                 Something::StructNums { one, two: _ } => *one,\n   |                 ^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:619:17\n   |\nLL |                 crate::issue8845::Something::Num(n) => *n,\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:621:17\n   |\nLL |                 crate::issue8845::Something::TupleNums(n, _m) => *n,\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:623:17\n   |\nLL |                 crate::issue8845::Something::StructNums { one, two: _ } => *one,\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:640:17\n   |\nLL |             let Foo(x) = self;\n   |                 ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:646:17\n   |\nLL |             let crate::issue8845::Foo(x) = self;\n   |                 ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:654:17\n   |\nLL |             let Bar { x, .. } = self;\n   |                 ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:660:17\n   |\nLL |             let crate::issue8845::Bar { x, .. } = self;\n   |                 ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self.rs:700:17\n   |\nLL |                 E::A => {},\n   |                 ^ help: use the applicable keyword: `Self`\n\nerror: aborting due to 42 previous errors\n\n"
  },
  {
    "path": "tests/ui/use_self_structs.fixed",
    "content": "#![warn(clippy::use_self)]\n#![allow(clippy::type_complexity)]\n\nfn main() {}\n\nstruct Basic {\n    flag: Option<Box<Self>>,\n    //~^ use_self\n}\n\nstruct BasicSelf {\n    okay: Option<Box<Self>>,\n}\n\nstruct Generic<'q, T: From<u8>> {\n    t: &'q T,\n    flag: Option<Box<Self>>,\n    //~^ use_self\n}\n\nstruct GenericSelf<'q, T: From<u8>> {\n    t: &'q T,\n    okay: Option<Box<Self>>,\n}\n\nstruct MixedLifetimes<'q, T: From<u8> + 'static> {\n    t: &'q T,\n    okay: Option<Box<MixedLifetimes<'static, T>>>,\n}\n\nstruct ConcreteType<'q, T: From<u8>> {\n    t: &'q T,\n    okay: Option<Box<ConcreteType<'q, u64>>>,\n}\n\nstruct ConcreteAndGeneric<'q, T: From<u8>> {\n    t: &'q T,\n    flag: Option<Box<Self>>,\n    //~^ use_self\n    okay: Option<Box<ConcreteAndGeneric<'q, u64>>>,\n}\n\nstruct ConcreteAndGenericSelf<'q, T: From<u8>> {\n    t: &'q T,\n    okay_1: Option<Box<Self>>,\n    okay_2: Option<Box<ConcreteAndGeneric<'q, u64>>>,\n}\n\nmacro_rules! recursive_struct {\n    ($name:ident) => {\n        struct $name {\n            okay: Option<Box<$name>>,\n        }\n    };\n}\n\nrecursive_struct!(X);\nrecursive_struct!(Y);\nrecursive_struct!(Z);\n\nstruct Tree {\n    left: Option<Box<Self>>,\n    //~^ use_self\n    right: Option<Box<Self>>,\n    //~^ use_self\n}\n\nstruct TreeSelf {\n    left: Option<Box<Self>>,\n    right: Option<Box<Self>>,\n}\n\nstruct TreeMixed {\n    left: Option<Box<Self>>,\n    right: Option<Box<Self>>,\n    //~^ use_self\n}\n\nstruct Nested {\n    flag: Option<Box<Option<Box<Self>>>>,\n    //~^ use_self\n}\n\nstruct NestedSelf {\n    okay: Option<Box<Option<Box<Self>>>>,\n}\n\nstruct Tuple(Option<Box<Self>>);\n//~^ use_self\n\nstruct TupleSelf(Option<Box<Self>>);\n\nuse std::cell::RefCell;\nuse std::rc::{Rc, Weak};\n\nstruct Containers {\n    flag: Vec<Option<Rc<RefCell<Weak<Vec<Box<Self>>>>>>>,\n    //~^ use_self\n}\n\nstruct ContainersSelf {\n    okay: Vec<Option<Rc<RefCell<Weak<Vec<Box<Self>>>>>>>,\n}\n\ntype Wrappers<T> = Vec<Option<Rc<RefCell<Weak<Vec<Box<T>>>>>>>;\n\nstruct Alias {\n    flag: Wrappers<Self>,\n    //~^ use_self\n}\n\nstruct AliasSelf {\n    okay: Wrappers<Self>,\n}\n\nstruct Array<const N: usize> {\n    flag: [Option<Box<Self>>; N],\n    //~^ use_self\n}\n\nstruct ArraySelf<const N: usize> {\n    okay: [Option<Box<Self>>; N],\n}\n\nenum Enum {\n    Nil,\n    Cons(Box<Self>),\n    //~^ use_self\n}\n\nenum EnumSelf {\n    Nil,\n    Cons(Box<Self>),\n}\n"
  },
  {
    "path": "tests/ui/use_self_structs.rs",
    "content": "#![warn(clippy::use_self)]\n#![allow(clippy::type_complexity)]\n\nfn main() {}\n\nstruct Basic {\n    flag: Option<Box<Basic>>,\n    //~^ use_self\n}\n\nstruct BasicSelf {\n    okay: Option<Box<Self>>,\n}\n\nstruct Generic<'q, T: From<u8>> {\n    t: &'q T,\n    flag: Option<Box<Generic<'q, T>>>,\n    //~^ use_self\n}\n\nstruct GenericSelf<'q, T: From<u8>> {\n    t: &'q T,\n    okay: Option<Box<Self>>,\n}\n\nstruct MixedLifetimes<'q, T: From<u8> + 'static> {\n    t: &'q T,\n    okay: Option<Box<MixedLifetimes<'static, T>>>,\n}\n\nstruct ConcreteType<'q, T: From<u8>> {\n    t: &'q T,\n    okay: Option<Box<ConcreteType<'q, u64>>>,\n}\n\nstruct ConcreteAndGeneric<'q, T: From<u8>> {\n    t: &'q T,\n    flag: Option<Box<ConcreteAndGeneric<'q, T>>>,\n    //~^ use_self\n    okay: Option<Box<ConcreteAndGeneric<'q, u64>>>,\n}\n\nstruct ConcreteAndGenericSelf<'q, T: From<u8>> {\n    t: &'q T,\n    okay_1: Option<Box<Self>>,\n    okay_2: Option<Box<ConcreteAndGeneric<'q, u64>>>,\n}\n\nmacro_rules! recursive_struct {\n    ($name:ident) => {\n        struct $name {\n            okay: Option<Box<$name>>,\n        }\n    };\n}\n\nrecursive_struct!(X);\nrecursive_struct!(Y);\nrecursive_struct!(Z);\n\nstruct Tree {\n    left: Option<Box<Tree>>,\n    //~^ use_self\n    right: Option<Box<Tree>>,\n    //~^ use_self\n}\n\nstruct TreeSelf {\n    left: Option<Box<Self>>,\n    right: Option<Box<Self>>,\n}\n\nstruct TreeMixed {\n    left: Option<Box<Self>>,\n    right: Option<Box<TreeMixed>>,\n    //~^ use_self\n}\n\nstruct Nested {\n    flag: Option<Box<Option<Box<Nested>>>>,\n    //~^ use_self\n}\n\nstruct NestedSelf {\n    okay: Option<Box<Option<Box<Self>>>>,\n}\n\nstruct Tuple(Option<Box<Tuple>>);\n//~^ use_self\n\nstruct TupleSelf(Option<Box<Self>>);\n\nuse std::cell::RefCell;\nuse std::rc::{Rc, Weak};\n\nstruct Containers {\n    flag: Vec<Option<Rc<RefCell<Weak<Vec<Box<Containers>>>>>>>,\n    //~^ use_self\n}\n\nstruct ContainersSelf {\n    okay: Vec<Option<Rc<RefCell<Weak<Vec<Box<Self>>>>>>>,\n}\n\ntype Wrappers<T> = Vec<Option<Rc<RefCell<Weak<Vec<Box<T>>>>>>>;\n\nstruct Alias {\n    flag: Wrappers<Alias>,\n    //~^ use_self\n}\n\nstruct AliasSelf {\n    okay: Wrappers<Self>,\n}\n\nstruct Array<const N: usize> {\n    flag: [Option<Box<Array<N>>>; N],\n    //~^ use_self\n}\n\nstruct ArraySelf<const N: usize> {\n    okay: [Option<Box<Self>>; N],\n}\n\nenum Enum {\n    Nil,\n    Cons(Box<Enum>),\n    //~^ use_self\n}\n\nenum EnumSelf {\n    Nil,\n    Cons(Box<Self>),\n}\n"
  },
  {
    "path": "tests/ui/use_self_structs.stderr",
    "content": "error: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:7:22\n   |\nLL |     flag: Option<Box<Basic>>,\n   |                      ^^^^^ help: use the applicable keyword: `Self`\n   |\n   = note: `-D clippy::use-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::use_self)]`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:17:22\n   |\nLL |     flag: Option<Box<Generic<'q, T>>>,\n   |                      ^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:38:22\n   |\nLL |     flag: Option<Box<ConcreteAndGeneric<'q, T>>>,\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:62:22\n   |\nLL |     left: Option<Box<Tree>>,\n   |                      ^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:64:23\n   |\nLL |     right: Option<Box<Tree>>,\n   |                       ^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:75:23\n   |\nLL |     right: Option<Box<TreeMixed>>,\n   |                       ^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:80:33\n   |\nLL |     flag: Option<Box<Option<Box<Nested>>>>,\n   |                                 ^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:88:25\n   |\nLL | struct Tuple(Option<Box<Tuple>>);\n   |                         ^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:97:46\n   |\nLL |     flag: Vec<Option<Rc<RefCell<Weak<Vec<Box<Containers>>>>>>>,\n   |                                              ^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:108:20\n   |\nLL |     flag: Wrappers<Alias>,\n   |                    ^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:117:23\n   |\nLL |     flag: [Option<Box<Array<N>>>; N],\n   |                       ^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_structs.rs:127:14\n   |\nLL |     Cons(Box<Enum>),\n   |              ^^^^ help: use the applicable keyword: `Self`\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/use_self_trait.fixed",
    "content": "#![warn(clippy::use_self)]\n#![allow(dead_code)]\n#![allow(clippy::should_implement_trait, clippy::boxed_local)]\n\nuse std::ops::Mul;\n\ntrait SelfTrait {\n    fn refs(p1: &Self) -> &Self;\n    fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self;\n    fn mut_refs(p1: &mut Self) -> &mut Self;\n    fn nested(p1: Box<Self>, p2: (&u8, &Self));\n    fn vals(r: Self) -> Self;\n}\n\n#[derive(Default)]\nstruct Bad;\n\nimpl SelfTrait for Bad {\n    fn refs(p1: &Self) -> &Self {\n        //~^ use_self\n        //~| use_self\n        p1\n    }\n\n    fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {\n        //~^ use_self\n        //~| use_self\n        p1\n    }\n\n    fn mut_refs(p1: &mut Self) -> &mut Self {\n        //~^ use_self\n        //~| use_self\n        p1\n    }\n\n    fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}\n    //~^ use_self\n    //~| use_self\n\n    fn vals(_: Self) -> Self {\n        //~^ use_self\n        //~| use_self\n        Self\n        //~^ use_self\n    }\n}\n\nimpl Mul for Bad {\n    type Output = Self;\n    //~^ use_self\n\n    fn mul(self, rhs: Self) -> Self {\n        //~^ use_self\n        //~| use_self\n        rhs\n    }\n}\n\nimpl Clone for Bad {\n    fn clone(&self) -> Self {\n        Self\n        //~^ use_self\n    }\n}\n\n#[derive(Default)]\nstruct Good;\n\nimpl SelfTrait for Good {\n    fn refs(p1: &Self) -> &Self {\n        p1\n    }\n\n    fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {\n        p1\n    }\n\n    fn mut_refs(p1: &mut Self) -> &mut Self {\n        p1\n    }\n\n    fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}\n\n    fn vals(_: Self) -> Self {\n        Self\n    }\n}\n\nimpl Mul for Good {\n    type Output = Self;\n\n    fn mul(self, rhs: Self) -> Self {\n        rhs\n    }\n}\n\ntrait NameTrait {\n    fn refs(p1: &u8) -> &u8;\n    fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8;\n    fn mut_refs(p1: &mut u8) -> &mut u8;\n    fn nested(p1: Box<u8>, p2: (&u8, &u8));\n    fn vals(p1: u8) -> u8;\n}\n\n// Using `Self` instead of the type name is OK\nimpl NameTrait for u8 {\n    fn refs(p1: &Self) -> &Self {\n        p1\n    }\n\n    fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {\n        p1\n    }\n\n    fn mut_refs(p1: &mut Self) -> &mut Self {\n        p1\n    }\n\n    fn nested(_p1: Box<Self>, _p2: (&Self, &Self)) {}\n\n    fn vals(_: Self) -> Self {\n        Self::default()\n    }\n}\n\nmod impl_in_macro {\n    macro_rules! parse_ip_impl {\n        // minimized from serde=1.0.118\n        ($ty:ty) => {\n            impl FooTrait for $ty {\n                fn new() -> Self {\n                    <$ty>::bar()\n                }\n            }\n        };\n    }\n\n    struct Foo;\n\n    trait FooTrait {\n        fn new() -> Self;\n    }\n\n    impl Foo {\n        fn bar() -> Self {\n            Self\n        }\n    }\n    parse_ip_impl!(Foo); // Should not lint\n}\n\nmod full_path_replacement {\n    trait Error {\n        fn custom<T: std::fmt::Display>(_msg: T) -> Self;\n    }\n\n    impl Error for std::fmt::Error {\n        fn custom<T: std::fmt::Display>(_msg: T) -> Self {\n            Self // Should lint\n            //\n            //~^^ use_self\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/use_self_trait.rs",
    "content": "#![warn(clippy::use_self)]\n#![allow(dead_code)]\n#![allow(clippy::should_implement_trait, clippy::boxed_local)]\n\nuse std::ops::Mul;\n\ntrait SelfTrait {\n    fn refs(p1: &Self) -> &Self;\n    fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self;\n    fn mut_refs(p1: &mut Self) -> &mut Self;\n    fn nested(p1: Box<Self>, p2: (&u8, &Self));\n    fn vals(r: Self) -> Self;\n}\n\n#[derive(Default)]\nstruct Bad;\n\nimpl SelfTrait for Bad {\n    fn refs(p1: &Bad) -> &Bad {\n        //~^ use_self\n        //~| use_self\n        p1\n    }\n\n    fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {\n        //~^ use_self\n        //~| use_self\n        p1\n    }\n\n    fn mut_refs(p1: &mut Bad) -> &mut Bad {\n        //~^ use_self\n        //~| use_self\n        p1\n    }\n\n    fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}\n    //~^ use_self\n    //~| use_self\n\n    fn vals(_: Bad) -> Bad {\n        //~^ use_self\n        //~| use_self\n        Bad\n        //~^ use_self\n    }\n}\n\nimpl Mul for Bad {\n    type Output = Bad;\n    //~^ use_self\n\n    fn mul(self, rhs: Bad) -> Bad {\n        //~^ use_self\n        //~| use_self\n        rhs\n    }\n}\n\nimpl Clone for Bad {\n    fn clone(&self) -> Self {\n        Bad\n        //~^ use_self\n    }\n}\n\n#[derive(Default)]\nstruct Good;\n\nimpl SelfTrait for Good {\n    fn refs(p1: &Self) -> &Self {\n        p1\n    }\n\n    fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {\n        p1\n    }\n\n    fn mut_refs(p1: &mut Self) -> &mut Self {\n        p1\n    }\n\n    fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}\n\n    fn vals(_: Self) -> Self {\n        Self\n    }\n}\n\nimpl Mul for Good {\n    type Output = Self;\n\n    fn mul(self, rhs: Self) -> Self {\n        rhs\n    }\n}\n\ntrait NameTrait {\n    fn refs(p1: &u8) -> &u8;\n    fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8;\n    fn mut_refs(p1: &mut u8) -> &mut u8;\n    fn nested(p1: Box<u8>, p2: (&u8, &u8));\n    fn vals(p1: u8) -> u8;\n}\n\n// Using `Self` instead of the type name is OK\nimpl NameTrait for u8 {\n    fn refs(p1: &Self) -> &Self {\n        p1\n    }\n\n    fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {\n        p1\n    }\n\n    fn mut_refs(p1: &mut Self) -> &mut Self {\n        p1\n    }\n\n    fn nested(_p1: Box<Self>, _p2: (&Self, &Self)) {}\n\n    fn vals(_: Self) -> Self {\n        Self::default()\n    }\n}\n\nmod impl_in_macro {\n    macro_rules! parse_ip_impl {\n        // minimized from serde=1.0.118\n        ($ty:ty) => {\n            impl FooTrait for $ty {\n                fn new() -> Self {\n                    <$ty>::bar()\n                }\n            }\n        };\n    }\n\n    struct Foo;\n\n    trait FooTrait {\n        fn new() -> Self;\n    }\n\n    impl Foo {\n        fn bar() -> Self {\n            Self\n        }\n    }\n    parse_ip_impl!(Foo); // Should not lint\n}\n\nmod full_path_replacement {\n    trait Error {\n        fn custom<T: std::fmt::Display>(_msg: T) -> Self;\n    }\n\n    impl Error for std::fmt::Error {\n        fn custom<T: std::fmt::Display>(_msg: T) -> Self {\n            std::fmt::Error // Should lint\n            //\n            //~^^ use_self\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/use_self_trait.stderr",
    "content": "error: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:19:18\n   |\nLL |     fn refs(p1: &Bad) -> &Bad {\n   |                  ^^^ help: use the applicable keyword: `Self`\n   |\n   = note: `-D clippy::use-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::use_self)]`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:19:27\n   |\nLL |     fn refs(p1: &Bad) -> &Bad {\n   |                           ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:25:33\n   |\nLL |     fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {\n   |                                 ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:25:49\n   |\nLL |     fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {\n   |                                                 ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:31:26\n   |\nLL |     fn mut_refs(p1: &mut Bad) -> &mut Bad {\n   |                          ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:31:39\n   |\nLL |     fn mut_refs(p1: &mut Bad) -> &mut Bad {\n   |                                       ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:37:24\n   |\nLL |     fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}\n   |                        ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:37:42\n   |\nLL |     fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}\n   |                                          ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:41:16\n   |\nLL |     fn vals(_: Bad) -> Bad {\n   |                ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:41:24\n   |\nLL |     fn vals(_: Bad) -> Bad {\n   |                        ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:44:9\n   |\nLL |         Bad\n   |         ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:50:19\n   |\nLL |     type Output = Bad;\n   |                   ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:53:23\n   |\nLL |     fn mul(self, rhs: Bad) -> Bad {\n   |                       ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:53:31\n   |\nLL |     fn mul(self, rhs: Bad) -> Bad {\n   |                               ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:62:9\n   |\nLL |         Bad\n   |         ^^^ help: use the applicable keyword: `Self`\n\nerror: unnecessary structure name repetition\n  --> tests/ui/use_self_trait.rs:160:13\n   |\nLL |             std::fmt::Error // Should lint\n   |             ^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui/used_underscore_binding.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n#![feature(rustc_private)]\n#![warn(clippy::used_underscore_binding)]\n#![allow(clippy::disallowed_names, clippy::eq_op, clippy::uninlined_format_args)]\n\n#[macro_use]\nextern crate proc_macro_derive;\n\n// This should not trigger the lint. There's underscore binding inside the external derive that\n// would trigger the `used_underscore_binding` lint.\n#[derive(DeriveSomething)]\nstruct Baz;\n\nmacro_rules! test_macro {\n    () => {{\n        let _foo = 42;\n        _foo + 1\n    }};\n}\n\n/// Tests that we lint if we use a binding with a single leading underscore\nfn prefix_underscore(_foo: u32) -> u32 {\n    _foo + 1\n    //~^ used_underscore_binding\n}\n\n/// Tests that we lint if we use a `_`-variable defined outside within a macro expansion\nfn in_macro_or_desugar(_foo: u32) {\n    println!(\"{}\", _foo);\n    //~^ used_underscore_binding\n    assert_eq!(_foo, _foo);\n    //~^ used_underscore_binding\n    //~| used_underscore_binding\n\n    test_macro!() + 1;\n}\n\n// Struct for testing use of fields prefixed with an underscore\nstruct StructFieldTest {\n    _underscore_field: u32,\n}\n\n/// Tests that we lint the use of a struct field which is prefixed with an underscore\nfn in_struct_field() {\n    let mut s = StructFieldTest { _underscore_field: 0 };\n    s._underscore_field += 1;\n    //~^ used_underscore_binding\n}\n\n/// Tests that we do not lint if the struct field is used in code created with derive.\n#[derive(Clone, Debug)]\npub struct UnderscoreInStruct {\n    _foo: u32,\n}\n\n/// Tests that we do not lint if the underscore is not a prefix\nfn non_prefix_underscore(some_foo: u32) -> u32 {\n    some_foo + 1\n}\n\n/// Tests that we do not lint if we do not use the binding (simple case)\nfn unused_underscore_simple(_foo: u32) -> u32 {\n    1\n}\n\n/// Tests that we do not lint if we do not use the binding (complex case). This checks for\n/// compatibility with the built-in `unused_variables` lint.\nfn unused_underscore_complex(mut _foo: u32) -> u32 {\n    _foo += 1;\n    _foo = 2;\n    1\n}\n\n/// Test that we do not lint for multiple underscores\nfn multiple_underscores(__foo: u32) -> u32 {\n    __foo + 1\n}\n\n// Non-variable bindings with preceding underscore\nfn _fn_test() {}\nstruct _StructTest;\nenum _EnumTest {\n    _Empty,\n    _Value(_StructTest),\n}\n\n/// Tests that we do not lint for non-variable bindings\nfn non_variables() {\n    _fn_test();\n    let _s = _StructTest;\n    let _e = match _EnumTest::_Value(_StructTest) {\n        _EnumTest::_Empty => 0,\n        _EnumTest::_Value(_st) => 1,\n    };\n    let f = _fn_test;\n    f();\n}\n\n// Tests that we do not lint if the binding comes from await desugaring,\n// but we do lint the awaited expression. See issue 5360.\nasync fn await_desugaring() {\n    async fn foo() {}\n    fn uses_i(_i: i32) {}\n\n    foo().await;\n    ({\n        let _i = 5;\n        uses_i(_i);\n        //~^ used_underscore_binding\n        foo()\n    })\n    .await\n}\n\nstruct PhantomField<T> {\n    _marker: std::marker::PhantomData<T>,\n}\n\nimpl<T> std::fmt::Debug for PhantomField<T> {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        f.debug_struct(\"PhantomField\").field(\"_marker\", &self._marker).finish()\n    }\n}\n\nstruct AllowedField {\n    #[allow(clippy::used_underscore_binding)]\n    _allowed: usize,\n}\n\nstruct ExpectedField {\n    #[expect(clippy::used_underscore_binding)]\n    _expected: usize,\n}\n\nfn lint_levels(allowed: AllowedField, expected: ExpectedField) {\n    let _ = allowed._allowed;\n    let _ = expected._expected;\n}\n\nfn main() {\n    let foo = 0u32;\n    // tests of unused_underscore lint\n    let _ = prefix_underscore(foo);\n    in_macro_or_desugar(foo);\n    in_struct_field();\n    // possible false positives\n    let _ = non_prefix_underscore(foo);\n    let _ = unused_underscore_simple(foo);\n    let _ = unused_underscore_complex(foo);\n    let _ = multiple_underscores(foo);\n    non_variables();\n    await_desugaring();\n}\n"
  },
  {
    "path": "tests/ui/used_underscore_binding.stderr",
    "content": "error: used underscore-prefixed binding\n  --> tests/ui/used_underscore_binding.rs:23:5\n   |\nLL |     _foo + 1\n   |     ^^^^\n   |\nnote: binding is defined here\n  --> tests/ui/used_underscore_binding.rs:22:22\n   |\nLL | fn prefix_underscore(_foo: u32) -> u32 {\n   |                      ^^^^\n   = note: `-D clippy::used-underscore-binding` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::used_underscore_binding)]`\n\nerror: used underscore-prefixed binding\n  --> tests/ui/used_underscore_binding.rs:29:20\n   |\nLL |     println!(\"{}\", _foo);\n   |                    ^^^^\n   |\nnote: binding is defined here\n  --> tests/ui/used_underscore_binding.rs:28:24\n   |\nLL | fn in_macro_or_desugar(_foo: u32) {\n   |                        ^^^^\n\nerror: used underscore-prefixed binding\n  --> tests/ui/used_underscore_binding.rs:31:16\n   |\nLL |     assert_eq!(_foo, _foo);\n   |                ^^^^\n   |\nnote: binding is defined here\n  --> tests/ui/used_underscore_binding.rs:28:24\n   |\nLL | fn in_macro_or_desugar(_foo: u32) {\n   |                        ^^^^\n\nerror: used underscore-prefixed binding\n  --> tests/ui/used_underscore_binding.rs:31:22\n   |\nLL |     assert_eq!(_foo, _foo);\n   |                      ^^^^\n   |\nnote: binding is defined here\n  --> tests/ui/used_underscore_binding.rs:28:24\n   |\nLL | fn in_macro_or_desugar(_foo: u32) {\n   |                        ^^^^\n\nerror: used underscore-prefixed binding\n  --> tests/ui/used_underscore_binding.rs:46:5\n   |\nLL |     s._underscore_field += 1;\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\nnote: binding is defined here\n  --> tests/ui/used_underscore_binding.rs:40:5\n   |\nLL |     _underscore_field: u32,\n   |     ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used underscore-prefixed binding\n  --> tests/ui/used_underscore_binding.rs:108:16\n   |\nLL |         uses_i(_i);\n   |                ^^\n   |\nnote: binding is defined here\n  --> tests/ui/used_underscore_binding.rs:107:13\n   |\nLL |         let _i = 5;\n   |             ^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/used_underscore_items.rs",
    "content": "//@aux-build:external_item.rs\n#![allow(unused)]\n#![warn(clippy::used_underscore_items)]\n\nextern crate external_item;\n\n// should not lint macro\nmacro_rules! macro_wrap_func {\n    () => {\n        fn _marco_foo() {}\n    };\n}\n\nmacro_wrap_func!();\n\nstruct _FooStruct {}\n\nimpl _FooStruct {\n    fn _method_call(self) {}\n}\n\nfn _foo1() {}\n\nfn _foo2() -> i32 {\n    0\n}\n\nmod a {\n    pub mod b {\n        pub mod c {\n            pub fn _foo3() {}\n\n            pub struct _FooStruct2 {}\n\n            impl _FooStruct2 {\n                pub fn _method_call(self) {}\n            }\n        }\n    }\n}\n\nfn main() {\n    _foo1();\n    //~^ used_underscore_items\n    let _ = _foo2();\n    //~^ used_underscore_items\n    a::b::c::_foo3();\n    //~^ used_underscore_items\n    let _ = &_FooStruct {};\n    //~^ used_underscore_items\n    let _ = _FooStruct {};\n    //~^ used_underscore_items\n\n    let foo_struct = _FooStruct {};\n    //~^ used_underscore_items\n    foo_struct._method_call();\n    //~^ used_underscore_items\n\n    let foo_struct2 = a::b::c::_FooStruct2 {};\n    //~^ used_underscore_items\n    foo_struct2._method_call();\n    //~^ used_underscore_items\n}\n\n// should not lint external crate.\n// user cannot control how others name their items\nfn external_item_call() {\n    let foo_struct3 = external_item::_ExternalStruct {};\n    foo_struct3._foo();\n\n    external_item::_external_foo();\n}\n\n// should not lint foreign functions.\n// issue #14156\nunsafe extern \"C\" {\n    pub fn _exit(code: i32) -> !;\n}\n\nfn _f() {\n    unsafe { _exit(1) }\n}\n"
  },
  {
    "path": "tests/ui/used_underscore_items.stderr",
    "content": "error: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:43:5\n   |\nLL |     _foo1();\n   |     ^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:22:1\n   |\nLL | fn _foo1() {}\n   | ^^^^^^^^^^\n   = note: `-D clippy::used-underscore-items` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::used_underscore_items)]`\n\nerror: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:45:13\n   |\nLL |     let _ = _foo2();\n   |             ^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:24:1\n   |\nLL | fn _foo2() -> i32 {\n   | ^^^^^^^^^^^^^^^^^\n\nerror: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:47:5\n   |\nLL |     a::b::c::_foo3();\n   |     ^^^^^^^^^^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:31:13\n   |\nLL |             pub fn _foo3() {}\n   |             ^^^^^^^^^^^^^^\n\nerror: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:49:14\n   |\nLL |     let _ = &_FooStruct {};\n   |              ^^^^^^^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:16:1\n   |\nLL | struct _FooStruct {}\n   | ^^^^^^^^^^^^^^^^^\n\nerror: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:51:13\n   |\nLL |     let _ = _FooStruct {};\n   |             ^^^^^^^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:16:1\n   |\nLL | struct _FooStruct {}\n   | ^^^^^^^^^^^^^^^^^\n\nerror: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:54:22\n   |\nLL |     let foo_struct = _FooStruct {};\n   |                      ^^^^^^^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:16:1\n   |\nLL | struct _FooStruct {}\n   | ^^^^^^^^^^^^^^^^^\n\nerror: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:56:5\n   |\nLL |     foo_struct._method_call();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:19:5\n   |\nLL |     fn _method_call(self) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^\n\nerror: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:59:23\n   |\nLL |     let foo_struct2 = a::b::c::_FooStruct2 {};\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:33:13\n   |\nLL |             pub struct _FooStruct2 {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: used underscore-prefixed item\n  --> tests/ui/used_underscore_items.rs:61:5\n   |\nLL |     foo_struct2._method_call();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: item is defined here\n  --> tests/ui/used_underscore_items.rs:36:17\n   |\nLL |                 pub fn _method_call(self) {}\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/useful_asref.rs",
    "content": "//@ check-pass\n\n#![deny(clippy::useless_asref)]\n#![allow(clippy::needless_lifetimes)]\n\ntrait Trait {\n    fn as_ptr(&self);\n}\n\nimpl<'a> Trait for &'a [u8] {\n    fn as_ptr(&self) {\n        self.as_ref().as_ptr();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/useless_asref.fixed",
    "content": "#![deny(clippy::useless_asref)]\n#![allow(\n    clippy::explicit_auto_deref,\n    clippy::uninlined_format_args,\n    clippy::map_clone,\n    clippy::needless_pass_by_ref_mut,\n    clippy::redundant_closure\n)]\n\nuse std::fmt::Debug;\nuse std::ops::Deref;\nuse std::rc::{Rc, Weak as RcWeak};\nuse std::sync::{Arc, Weak as ArcWeak};\n\nstruct FakeAsRef;\n\n#[allow(clippy::should_implement_trait)]\nimpl FakeAsRef {\n    fn as_ref(&self) -> &Self {\n        self\n    }\n}\n\nstruct MoreRef;\n\nimpl<'a, 'b, 'c> AsRef<&'a &'b &'c MoreRef> for MoreRef {\n    fn as_ref(&self) -> &&'a &'b &'c MoreRef {\n        &&&&MoreRef\n    }\n}\n\nfn foo_rstr(x: &str) {\n    println!(\"{:?}\", x);\n}\nfn foo_rslice(x: &[i32]) {\n    println!(\"{:?}\", x);\n}\nfn foo_mrslice(x: &mut [i32]) {\n    println!(\"{:?}\", x);\n}\nfn foo_rrrrmr(_: &&&&MoreRef) {\n    println!(\"so many refs\");\n}\n\nfn not_ok() {\n    let rstr: &str = \"hello\";\n    let mut mrslice: &mut [i32] = &mut [1, 2, 3];\n\n    {\n        let rslice: &[i32] = &*mrslice;\n        foo_rstr(rstr);\n        //~^ useless_asref\n        foo_rstr(rstr);\n        foo_rslice(rslice);\n        //~^ useless_asref\n        foo_rslice(rslice);\n    }\n    {\n        foo_mrslice(mrslice);\n        //~^ useless_asref\n        foo_mrslice(mrslice);\n        foo_rslice(mrslice);\n        //~^ useless_asref\n        foo_rslice(mrslice);\n    }\n\n    {\n        let rrrrrstr = &&&&rstr;\n        let rrrrrslice = &&&&&*mrslice;\n        foo_rslice(rrrrrslice);\n        //~^ useless_asref\n        foo_rslice(rrrrrslice);\n        foo_rstr(rrrrrstr);\n        //~^ useless_asref\n        foo_rstr(rrrrrstr);\n    }\n    {\n        let mrrrrrslice = &mut &mut &mut &mut mrslice;\n        foo_mrslice(mrrrrrslice);\n        //~^ useless_asref\n        foo_mrslice(mrrrrrslice);\n        foo_rslice(mrrrrrslice);\n        //~^ useless_asref\n        foo_rslice(mrrrrrslice);\n    }\n    #[allow(unused_parens, clippy::double_parens, clippy::needless_borrow)]\n    foo_rrrrmr((&&&&MoreRef));\n    //~^ useless_asref\n\n    generic_not_ok(mrslice);\n    generic_ok(mrslice);\n}\n\nfn ok() {\n    let string = \"hello\".to_owned();\n    let mut arr = [1, 2, 3];\n    let mut vec = vec![1, 2, 3];\n\n    {\n        foo_rstr(string.as_ref());\n        foo_rslice(arr.as_ref());\n        foo_rslice(vec.as_ref());\n    }\n    {\n        foo_mrslice(arr.as_mut());\n        foo_mrslice(vec.as_mut());\n    }\n\n    {\n        let rrrrstring = &&&&string;\n        let rrrrarr = &&&&arr;\n        let rrrrvec = &&&&vec;\n        foo_rstr(rrrrstring.as_ref());\n        foo_rslice(rrrrarr.as_ref());\n        foo_rslice(rrrrvec.as_ref());\n    }\n    {\n        let mrrrrarr = &mut &mut &mut &mut arr;\n        let mrrrrvec = &mut &mut &mut &mut vec;\n        foo_mrslice(mrrrrarr.as_mut());\n        foo_mrslice(mrrrrvec.as_mut());\n    }\n    FakeAsRef.as_ref();\n    foo_rrrrmr(MoreRef.as_ref());\n\n    generic_not_ok(arr.as_mut());\n    generic_ok(&mut arr);\n}\n\nfn foo_mrt<T: Debug + ?Sized>(t: &mut T) {\n    println!(\"{:?}\", t);\n}\nfn foo_rt<T: Debug + ?Sized>(t: &T) {\n    println!(\"{:?}\", t);\n}\n\nfn generic_not_ok<T: AsMut<T> + AsRef<T> + Debug + ?Sized>(mrt: &mut T) {\n    foo_mrt(mrt);\n    //~^ useless_asref\n    foo_mrt(mrt);\n    foo_rt(mrt);\n    //~^ useless_asref\n    foo_rt(mrt);\n}\n\nfn generic_ok<U: AsMut<T> + AsRef<T> + ?Sized, T: Debug + ?Sized>(mru: &mut U) {\n    foo_mrt(mru.as_mut());\n    foo_rt(mru.as_ref());\n}\n\nfn foo() {\n    let x = Some(String::new());\n    let z = x.clone();\n    //~^ useless_asref\n\n    let z = x.clone();\n    //~^ useless_asref\n\n    let z = x.clone();\n    //~^ useless_asref\n}\n\nmod issue12135 {\n    pub struct Struct {\n        field: Option<InnerStruct>,\n    }\n\n    #[derive(Clone)]\n    pub struct Foo;\n\n    #[derive(Clone)]\n    struct InnerStruct {\n        x: Foo,\n    }\n\n    impl InnerStruct {\n        fn method(&self) -> &Foo {\n            &self.x\n        }\n    }\n\n    pub fn f(x: &Struct) -> Option<Foo> {\n        x.field.clone();\n        //~^ useless_asref\n\n        x.field.clone();\n        //~^ useless_asref\n\n        x.field.clone();\n        //~^ useless_asref\n\n        // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223\n        #[allow(clippy::clone_on_copy)]\n        Some(1).clone();\n        //~^ useless_asref\n\n        x.field.as_ref().map(|v| v.method().clone())\n    }\n}\n\nfn issue_12528() {\n    struct Foo;\n\n    let opt = Some(Arc::new(Foo));\n    let _ = opt.as_ref().map(Arc::clone);\n\n    let opt = Some(Rc::new(Foo));\n    let _ = opt.as_ref().map(Rc::clone);\n\n    let opt = Some(Arc::downgrade(&Arc::new(Foo)));\n    let _ = opt.as_ref().map(ArcWeak::clone);\n\n    let opt = Some(Rc::downgrade(&Rc::new(Foo)));\n    let _ = opt.as_ref().map(RcWeak::clone);\n}\n\nfn issue_14088() {\n    let s = Some(\"foo\");\n    let _: Option<&str> = s.as_ref().map(|x| x.as_ref());\n}\n\npub struct Wrap<T> {\n    inner: T,\n}\n\nimpl<T> Deref for Wrap<T> {\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        &self.inner\n    }\n}\n\nstruct NonCloneableError;\n\npub struct Issue12357 {\n    current: Option<Wrap<Arc<u32>>>,\n}\n\nimpl Issue12357 {\n    fn f(&self) -> Option<Arc<u32>> {\n        self.current.as_ref().map(|p| Arc::clone(p))\n    }\n\n    fn g(&self) {\n        let result: Result<String, NonCloneableError> = Ok(\"Hello\".to_string());\n        let cloned = result.as_ref().map(|s| s.clone());\n    }\n}\n\nfn issue_14828() {\n    pub trait T {\n        fn as_ref(&self) {}\n    }\n\n    impl T for () {}\n\n    ().as_ref();\n}\n\nfn issue16098(exts: Vec<&str>) {\n    use std::borrow::Cow;\n\n    let v: Vec<Cow<'_, str>> = exts.iter().map(|s| Cow::Borrowed(*s)).collect();\n    //~^ useless_asref\n\n    trait Identity {\n        fn id(self) -> Self\n        where\n            Self: Sized,\n        {\n            self\n        }\n    }\n    impl Identity for &str {}\n\n    let v: Vec<Cow<'_, str>> = exts.iter().map(|s| Cow::Borrowed(s.id())).collect();\n    //~^ useless_asref\n\n    let v: Vec<Cow<'_, str>> = exts\n        .iter()\n        .map(|s| Cow::Borrowed(*std::convert::identity(s)))\n        //~^ useless_asref\n        .collect();\n\n    struct Wrapper<'a>(&'a str);\n    let exts_field: Vec<Wrapper> = exts.iter().map(|s| Wrapper(s)).collect();\n    let v: Vec<Cow<'_, str>> = exts_field.iter().map(|w| Cow::Borrowed(w.0)).collect();\n    //~^ useless_asref\n\n    let exts_index: Vec<&[&str]> = exts.iter().map(|s| std::slice::from_ref(s)).collect();\n    let v: Vec<Cow<'_, str>> = exts_index.iter().map(|arr| Cow::Borrowed(arr[0])).collect();\n    //~^ useless_asref\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/useless_asref.rs",
    "content": "#![deny(clippy::useless_asref)]\n#![allow(\n    clippy::explicit_auto_deref,\n    clippy::uninlined_format_args,\n    clippy::map_clone,\n    clippy::needless_pass_by_ref_mut,\n    clippy::redundant_closure\n)]\n\nuse std::fmt::Debug;\nuse std::ops::Deref;\nuse std::rc::{Rc, Weak as RcWeak};\nuse std::sync::{Arc, Weak as ArcWeak};\n\nstruct FakeAsRef;\n\n#[allow(clippy::should_implement_trait)]\nimpl FakeAsRef {\n    fn as_ref(&self) -> &Self {\n        self\n    }\n}\n\nstruct MoreRef;\n\nimpl<'a, 'b, 'c> AsRef<&'a &'b &'c MoreRef> for MoreRef {\n    fn as_ref(&self) -> &&'a &'b &'c MoreRef {\n        &&&&MoreRef\n    }\n}\n\nfn foo_rstr(x: &str) {\n    println!(\"{:?}\", x);\n}\nfn foo_rslice(x: &[i32]) {\n    println!(\"{:?}\", x);\n}\nfn foo_mrslice(x: &mut [i32]) {\n    println!(\"{:?}\", x);\n}\nfn foo_rrrrmr(_: &&&&MoreRef) {\n    println!(\"so many refs\");\n}\n\nfn not_ok() {\n    let rstr: &str = \"hello\";\n    let mut mrslice: &mut [i32] = &mut [1, 2, 3];\n\n    {\n        let rslice: &[i32] = &*mrslice;\n        foo_rstr(rstr.as_ref());\n        //~^ useless_asref\n        foo_rstr(rstr);\n        foo_rslice(rslice.as_ref());\n        //~^ useless_asref\n        foo_rslice(rslice);\n    }\n    {\n        foo_mrslice(mrslice.as_mut());\n        //~^ useless_asref\n        foo_mrslice(mrslice);\n        foo_rslice(mrslice.as_ref());\n        //~^ useless_asref\n        foo_rslice(mrslice);\n    }\n\n    {\n        let rrrrrstr = &&&&rstr;\n        let rrrrrslice = &&&&&*mrslice;\n        foo_rslice(rrrrrslice.as_ref());\n        //~^ useless_asref\n        foo_rslice(rrrrrslice);\n        foo_rstr(rrrrrstr.as_ref());\n        //~^ useless_asref\n        foo_rstr(rrrrrstr);\n    }\n    {\n        let mrrrrrslice = &mut &mut &mut &mut mrslice;\n        foo_mrslice(mrrrrrslice.as_mut());\n        //~^ useless_asref\n        foo_mrslice(mrrrrrslice);\n        foo_rslice(mrrrrrslice.as_ref());\n        //~^ useless_asref\n        foo_rslice(mrrrrrslice);\n    }\n    #[allow(unused_parens, clippy::double_parens, clippy::needless_borrow)]\n    foo_rrrrmr((&&&&MoreRef).as_ref());\n    //~^ useless_asref\n\n    generic_not_ok(mrslice);\n    generic_ok(mrslice);\n}\n\nfn ok() {\n    let string = \"hello\".to_owned();\n    let mut arr = [1, 2, 3];\n    let mut vec = vec![1, 2, 3];\n\n    {\n        foo_rstr(string.as_ref());\n        foo_rslice(arr.as_ref());\n        foo_rslice(vec.as_ref());\n    }\n    {\n        foo_mrslice(arr.as_mut());\n        foo_mrslice(vec.as_mut());\n    }\n\n    {\n        let rrrrstring = &&&&string;\n        let rrrrarr = &&&&arr;\n        let rrrrvec = &&&&vec;\n        foo_rstr(rrrrstring.as_ref());\n        foo_rslice(rrrrarr.as_ref());\n        foo_rslice(rrrrvec.as_ref());\n    }\n    {\n        let mrrrrarr = &mut &mut &mut &mut arr;\n        let mrrrrvec = &mut &mut &mut &mut vec;\n        foo_mrslice(mrrrrarr.as_mut());\n        foo_mrslice(mrrrrvec.as_mut());\n    }\n    FakeAsRef.as_ref();\n    foo_rrrrmr(MoreRef.as_ref());\n\n    generic_not_ok(arr.as_mut());\n    generic_ok(&mut arr);\n}\n\nfn foo_mrt<T: Debug + ?Sized>(t: &mut T) {\n    println!(\"{:?}\", t);\n}\nfn foo_rt<T: Debug + ?Sized>(t: &T) {\n    println!(\"{:?}\", t);\n}\n\nfn generic_not_ok<T: AsMut<T> + AsRef<T> + Debug + ?Sized>(mrt: &mut T) {\n    foo_mrt(mrt.as_mut());\n    //~^ useless_asref\n    foo_mrt(mrt);\n    foo_rt(mrt.as_ref());\n    //~^ useless_asref\n    foo_rt(mrt);\n}\n\nfn generic_ok<U: AsMut<T> + AsRef<T> + ?Sized, T: Debug + ?Sized>(mru: &mut U) {\n    foo_mrt(mru.as_mut());\n    foo_rt(mru.as_ref());\n}\n\nfn foo() {\n    let x = Some(String::new());\n    let z = x.as_ref().map(String::clone);\n    //~^ useless_asref\n\n    let z = x.as_ref().map(|z| z.clone());\n    //~^ useless_asref\n\n    let z = x.as_ref().map(|z| String::clone(z));\n    //~^ useless_asref\n}\n\nmod issue12135 {\n    pub struct Struct {\n        field: Option<InnerStruct>,\n    }\n\n    #[derive(Clone)]\n    pub struct Foo;\n\n    #[derive(Clone)]\n    struct InnerStruct {\n        x: Foo,\n    }\n\n    impl InnerStruct {\n        fn method(&self) -> &Foo {\n            &self.x\n        }\n    }\n\n    pub fn f(x: &Struct) -> Option<Foo> {\n        x.field.as_ref().map(|v| v.clone());\n        //~^ useless_asref\n\n        x.field.as_ref().map(Clone::clone);\n        //~^ useless_asref\n\n        x.field.as_ref().map(|v| Clone::clone(v));\n        //~^ useless_asref\n\n        // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223\n        #[allow(clippy::clone_on_copy)]\n        Some(1).as_ref().map(|&x| x.clone());\n        //~^ useless_asref\n\n        x.field.as_ref().map(|v| v.method().clone())\n    }\n}\n\nfn issue_12528() {\n    struct Foo;\n\n    let opt = Some(Arc::new(Foo));\n    let _ = opt.as_ref().map(Arc::clone);\n\n    let opt = Some(Rc::new(Foo));\n    let _ = opt.as_ref().map(Rc::clone);\n\n    let opt = Some(Arc::downgrade(&Arc::new(Foo)));\n    let _ = opt.as_ref().map(ArcWeak::clone);\n\n    let opt = Some(Rc::downgrade(&Rc::new(Foo)));\n    let _ = opt.as_ref().map(RcWeak::clone);\n}\n\nfn issue_14088() {\n    let s = Some(\"foo\");\n    let _: Option<&str> = s.as_ref().map(|x| x.as_ref());\n}\n\npub struct Wrap<T> {\n    inner: T,\n}\n\nimpl<T> Deref for Wrap<T> {\n    type Target = T;\n\n    fn deref(&self) -> &Self::Target {\n        &self.inner\n    }\n}\n\nstruct NonCloneableError;\n\npub struct Issue12357 {\n    current: Option<Wrap<Arc<u32>>>,\n}\n\nimpl Issue12357 {\n    fn f(&self) -> Option<Arc<u32>> {\n        self.current.as_ref().map(|p| Arc::clone(p))\n    }\n\n    fn g(&self) {\n        let result: Result<String, NonCloneableError> = Ok(\"Hello\".to_string());\n        let cloned = result.as_ref().map(|s| s.clone());\n    }\n}\n\nfn issue_14828() {\n    pub trait T {\n        fn as_ref(&self) {}\n    }\n\n    impl T for () {}\n\n    ().as_ref();\n}\n\nfn issue16098(exts: Vec<&str>) {\n    use std::borrow::Cow;\n\n    let v: Vec<Cow<'_, str>> = exts.iter().map(|s| Cow::Borrowed(s.as_ref())).collect();\n    //~^ useless_asref\n\n    trait Identity {\n        fn id(self) -> Self\n        where\n            Self: Sized,\n        {\n            self\n        }\n    }\n    impl Identity for &str {}\n\n    let v: Vec<Cow<'_, str>> = exts.iter().map(|s| Cow::Borrowed(s.id().as_ref())).collect();\n    //~^ useless_asref\n\n    let v: Vec<Cow<'_, str>> = exts\n        .iter()\n        .map(|s| Cow::Borrowed(std::convert::identity(s).as_ref()))\n        //~^ useless_asref\n        .collect();\n\n    struct Wrapper<'a>(&'a str);\n    let exts_field: Vec<Wrapper> = exts.iter().map(|s| Wrapper(s)).collect();\n    let v: Vec<Cow<'_, str>> = exts_field.iter().map(|w| Cow::Borrowed(w.0.as_ref())).collect();\n    //~^ useless_asref\n\n    let exts_index: Vec<&[&str]> = exts.iter().map(|s| std::slice::from_ref(s)).collect();\n    let v: Vec<Cow<'_, str>> = exts_index.iter().map(|arr| Cow::Borrowed(arr[0].as_ref())).collect();\n    //~^ useless_asref\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/useless_asref.stderr",
    "content": "error: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:51:18\n   |\nLL |         foo_rstr(rstr.as_ref());\n   |                  ^^^^^^^^^^^^^ help: try: `rstr`\n   |\nnote: the lint level is defined here\n  --> tests/ui/useless_asref.rs:1:9\n   |\nLL | #![deny(clippy::useless_asref)]\n   |         ^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:54:20\n   |\nLL |         foo_rslice(rslice.as_ref());\n   |                    ^^^^^^^^^^^^^^^ help: try: `rslice`\n\nerror: this call to `as_mut` does nothing\n  --> tests/ui/useless_asref.rs:59:21\n   |\nLL |         foo_mrslice(mrslice.as_mut());\n   |                     ^^^^^^^^^^^^^^^^ help: try: `mrslice`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:62:20\n   |\nLL |         foo_rslice(mrslice.as_ref());\n   |                    ^^^^^^^^^^^^^^^^ help: try: `mrslice`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:70:20\n   |\nLL |         foo_rslice(rrrrrslice.as_ref());\n   |                    ^^^^^^^^^^^^^^^^^^^ help: try: `rrrrrslice`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:73:18\n   |\nLL |         foo_rstr(rrrrrstr.as_ref());\n   |                  ^^^^^^^^^^^^^^^^^ help: try: `rrrrrstr`\n\nerror: this call to `as_mut` does nothing\n  --> tests/ui/useless_asref.rs:79:21\n   |\nLL |         foo_mrslice(mrrrrrslice.as_mut());\n   |                     ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:82:20\n   |\nLL |         foo_rslice(mrrrrrslice.as_ref());\n   |                    ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:87:16\n   |\nLL |     foo_rrrrmr((&&&&MoreRef).as_ref());\n   |                ^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&&&&MoreRef)`\n\nerror: this call to `as_mut` does nothing\n  --> tests/ui/useless_asref.rs:138:13\n   |\nLL |     foo_mrt(mrt.as_mut());\n   |             ^^^^^^^^^^^^ help: try: `mrt`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:141:12\n   |\nLL |     foo_rt(mrt.as_ref());\n   |            ^^^^^^^^^^^^ help: try: `mrt`\n\nerror: this call to `as_ref.map(...)` does nothing\n  --> tests/ui/useless_asref.rs:153:13\n   |\nLL |     let z = x.as_ref().map(String::clone);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()`\n\nerror: this call to `as_ref.map(...)` does nothing\n  --> tests/ui/useless_asref.rs:156:13\n   |\nLL |     let z = x.as_ref().map(|z| z.clone());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()`\n\nerror: this call to `as_ref.map(...)` does nothing\n  --> tests/ui/useless_asref.rs:159:13\n   |\nLL |     let z = x.as_ref().map(|z| String::clone(z));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()`\n\nerror: this call to `as_ref.map(...)` does nothing\n  --> tests/ui/useless_asref.rs:183:9\n   |\nLL |         x.field.as_ref().map(|v| v.clone());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`\n\nerror: this call to `as_ref.map(...)` does nothing\n  --> tests/ui/useless_asref.rs:186:9\n   |\nLL |         x.field.as_ref().map(Clone::clone);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`\n\nerror: this call to `as_ref.map(...)` does nothing\n  --> tests/ui/useless_asref.rs:189:9\n   |\nLL |         x.field.as_ref().map(|v| Clone::clone(v));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`\n\nerror: this call to `as_ref.map(...)` does nothing\n  --> tests/ui/useless_asref.rs:194:9\n   |\nLL |         Some(1).as_ref().map(|&x| x.clone());\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(1).clone()`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:264:66\n   |\nLL |     let v: Vec<Cow<'_, str>> = exts.iter().map(|s| Cow::Borrowed(s.as_ref())).collect();\n   |                                                                  ^^^^^^^^^^ help: try: `*s`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:277:66\n   |\nLL |     let v: Vec<Cow<'_, str>> = exts.iter().map(|s| Cow::Borrowed(s.id().as_ref())).collect();\n   |                                                                  ^^^^^^^^^^^^^^^ help: try: `s.id()`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:282:32\n   |\nLL |         .map(|s| Cow::Borrowed(std::convert::identity(s).as_ref()))\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `*std::convert::identity(s)`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:288:72\n   |\nLL |     let v: Vec<Cow<'_, str>> = exts_field.iter().map(|w| Cow::Borrowed(w.0.as_ref())).collect();\n   |                                                                        ^^^^^^^^^^^^ help: try: `w.0`\n\nerror: this call to `as_ref` does nothing\n  --> tests/ui/useless_asref.rs:292:74\n   |\nLL |     let v: Vec<Cow<'_, str>> = exts_index.iter().map(|arr| Cow::Borrowed(arr[0].as_ref())).collect();\n   |                                                                          ^^^^^^^^^^^^^^^ help: try: `arr[0]`\n\nerror: aborting due to 23 previous errors\n\n"
  },
  {
    "path": "tests/ui/useless_attribute.fixed",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![allow(unused, clippy::duplicated_attributes)]\n#![warn(clippy::useless_attribute)]\n#![warn(unreachable_pub)]\n#![feature(rustc_private)]\n\n#![allow(dead_code)]\n//~^ useless_attribute\n#![cfg_attr(clippy, allow(dead_code))]\n//~^ useless_attribute\n#[rustfmt::skip]\n#[allow(unused_imports)]\n#[allow(unused_extern_crates)]\n#[macro_use]\nextern crate regex as regex_crate;\n\n#[macro_use]\nextern crate proc_macro_derive;\n\nfn test_indented_attr() {\n    #![allow(clippy::almost_swapped)]\n    //~^ useless_attribute\n    use std::collections::HashSet;\n\n    let _ = HashSet::<u32>::default();\n}\n\n// don't lint on unused_import for `use` items\n#[allow(unused_imports)]\nuse std::collections;\n\n// don't lint on unused for `use` items\n#[allow(unused)]\nuse std::option;\n\n// don't lint on deprecated for `use` items\nmod foo {\n    #[deprecated]\n    pub struct Bar;\n}\n#[allow(deprecated)]\npub use foo::Bar;\n\n// don't lint on exported_private_dependencies for `use` items\n#[allow(exported_private_dependencies)]\nuse {};\n\n// This should not trigger the lint. There's lint level definitions inside the external derive\n// that would trigger the useless_attribute lint.\n#[derive(DeriveSomething)]\nstruct Baz;\n\n// don't lint on unreachable_pub for `use` items\nmod a {\n    mod b {\n        #[allow(dead_code)]\n        #[allow(unreachable_pub)]\n        pub struct C;\n    }\n\n    #[allow(unreachable_pub)]\n    pub use self::b::C;\n}\n\n// don't lint on clippy::wildcard_imports for `use` items\n#[allow(clippy::wildcard_imports)]\npub use std::io::prelude::*;\n\n// don't lint on clippy::enum_glob_use for `use` items\n#[allow(clippy::enum_glob_use)]\npub use std::cmp::Ordering::*;\n\n// don't lint on clippy::redundant_pub_crate\nmod c {\n    #[allow(clippy::redundant_pub_crate)]\n    pub(crate) struct S;\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7511\npub mod split {\n    #[allow(clippy::module_name_repetitions)]\n    pub use regex::SplitN;\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/8768\n#[allow(clippy::single_component_path_imports)]\nuse regex;\n\nmod module {\n    pub(crate) struct Struct;\n}\n\n#[rustfmt::skip]\n#[allow(unused_import_braces)]\n#[allow(unused_braces)]\nuse module::{Struct};\n\nfn main() {}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/4467\n#[allow(dead_code)]\nuse std::collections as puppy_doggy;\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/11595\npub mod hidden_glob_reexports {\n    #![allow(unreachable_pub)]\n\n    mod my_prelude {\n        pub struct MyCoolTypeInternal;\n        pub use MyCoolTypeInternal as MyCoolType;\n    }\n\n    mod my_uncool_type {\n        pub(crate) struct MyUncoolType;\n    }\n\n    // This exports `MyCoolType`.\n    pub use my_prelude::*;\n\n    // This hides `my_prelude::MyCoolType`.\n    #[allow(hidden_glob_reexports)]\n    use my_uncool_type::MyUncoolType as MyCoolType;\n}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/10878\npub mod ambiguous_glob_exports {\n    #![allow(unreachable_pub)]\n\n    mod my_prelude {\n        pub struct MyType;\n    }\n\n    mod my_type {\n        pub struct MyType;\n    }\n\n    #[allow(ambiguous_glob_reexports)]\n    pub use my_prelude::*;\n    pub use my_type::*;\n}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/13764\npub mod unknown_namespace {\n    pub mod some_module {\n        pub struct SomeType;\n    }\n    #[allow(rustc::non_glob_import_of_type_ir_inherent)]\n    use some_module::SomeType;\n}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/15316\npub mod redundant_imports_issue {\n    macro_rules! empty {\n        () => {};\n    }\n\n    #[expect(unused_imports)]\n    pub(crate) use empty;\n\n    empty!();\n}\n\npub mod issue15636 {\n    pub mod f {\n        #[deprecated(since = \"TBD\")]\n        pub mod deprec {}\n    }\n\n    #[allow(deprecated_in_future)]\n    pub use f::deprec;\n}\n"
  },
  {
    "path": "tests/ui/useless_attribute.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![allow(unused, clippy::duplicated_attributes)]\n#![warn(clippy::useless_attribute)]\n#![warn(unreachable_pub)]\n#![feature(rustc_private)]\n\n#[allow(dead_code)]\n//~^ useless_attribute\n#[cfg_attr(clippy, allow(dead_code))]\n//~^ useless_attribute\n#[rustfmt::skip]\n#[allow(unused_imports)]\n#[allow(unused_extern_crates)]\n#[macro_use]\nextern crate regex as regex_crate;\n\n#[macro_use]\nextern crate proc_macro_derive;\n\nfn test_indented_attr() {\n    #[allow(clippy::almost_swapped)]\n    //~^ useless_attribute\n    use std::collections::HashSet;\n\n    let _ = HashSet::<u32>::default();\n}\n\n// don't lint on unused_import for `use` items\n#[allow(unused_imports)]\nuse std::collections;\n\n// don't lint on unused for `use` items\n#[allow(unused)]\nuse std::option;\n\n// don't lint on deprecated for `use` items\nmod foo {\n    #[deprecated]\n    pub struct Bar;\n}\n#[allow(deprecated)]\npub use foo::Bar;\n\n// don't lint on exported_private_dependencies for `use` items\n#[allow(exported_private_dependencies)]\nuse {};\n\n// This should not trigger the lint. There's lint level definitions inside the external derive\n// that would trigger the useless_attribute lint.\n#[derive(DeriveSomething)]\nstruct Baz;\n\n// don't lint on unreachable_pub for `use` items\nmod a {\n    mod b {\n        #[allow(dead_code)]\n        #[allow(unreachable_pub)]\n        pub struct C;\n    }\n\n    #[allow(unreachable_pub)]\n    pub use self::b::C;\n}\n\n// don't lint on clippy::wildcard_imports for `use` items\n#[allow(clippy::wildcard_imports)]\npub use std::io::prelude::*;\n\n// don't lint on clippy::enum_glob_use for `use` items\n#[allow(clippy::enum_glob_use)]\npub use std::cmp::Ordering::*;\n\n// don't lint on clippy::redundant_pub_crate\nmod c {\n    #[allow(clippy::redundant_pub_crate)]\n    pub(crate) struct S;\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/7511\npub mod split {\n    #[allow(clippy::module_name_repetitions)]\n    pub use regex::SplitN;\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/8768\n#[allow(clippy::single_component_path_imports)]\nuse regex;\n\nmod module {\n    pub(crate) struct Struct;\n}\n\n#[rustfmt::skip]\n#[allow(unused_import_braces)]\n#[allow(unused_braces)]\nuse module::{Struct};\n\nfn main() {}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/4467\n#[allow(dead_code)]\nuse std::collections as puppy_doggy;\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/11595\npub mod hidden_glob_reexports {\n    #![allow(unreachable_pub)]\n\n    mod my_prelude {\n        pub struct MyCoolTypeInternal;\n        pub use MyCoolTypeInternal as MyCoolType;\n    }\n\n    mod my_uncool_type {\n        pub(crate) struct MyUncoolType;\n    }\n\n    // This exports `MyCoolType`.\n    pub use my_prelude::*;\n\n    // This hides `my_prelude::MyCoolType`.\n    #[allow(hidden_glob_reexports)]\n    use my_uncool_type::MyUncoolType as MyCoolType;\n}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/10878\npub mod ambiguous_glob_exports {\n    #![allow(unreachable_pub)]\n\n    mod my_prelude {\n        pub struct MyType;\n    }\n\n    mod my_type {\n        pub struct MyType;\n    }\n\n    #[allow(ambiguous_glob_reexports)]\n    pub use my_prelude::*;\n    pub use my_type::*;\n}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/13764\npub mod unknown_namespace {\n    pub mod some_module {\n        pub struct SomeType;\n    }\n    #[allow(rustc::non_glob_import_of_type_ir_inherent)]\n    use some_module::SomeType;\n}\n\n// Regression test for https://github.com/rust-lang/rust-clippy/issues/15316\npub mod redundant_imports_issue {\n    macro_rules! empty {\n        () => {};\n    }\n\n    #[expect(unused_imports)]\n    pub(crate) use empty;\n\n    empty!();\n}\n\npub mod issue15636 {\n    pub mod f {\n        #[deprecated(since = \"TBD\")]\n        pub mod deprec {}\n    }\n\n    #[allow(deprecated_in_future)]\n    pub use f::deprec;\n}\n"
  },
  {
    "path": "tests/ui/useless_attribute.stderr",
    "content": "error: useless lint attribute\n  --> tests/ui/useless_attribute.rs:8:1\n   |\nLL | #[allow(dead_code)]\n   | ^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(dead_code)]`\n   |\n   = note: `-D clippy::useless-attribute` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_attribute)]`\n\nerror: useless lint attribute\n  --> tests/ui/useless_attribute.rs:10:1\n   |\nLL | #[cfg_attr(clippy, allow(dead_code))]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![cfg_attr(clippy, allow(dead_code)`\n\nerror: useless lint attribute\n  --> tests/ui/useless_attribute.rs:22:5\n   |\nLL |     #[allow(clippy::almost_swapped)]\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(clippy::almost_swapped)]`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/useless_concat.fixed",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::useless_concat)]\n#![allow(clippy::print_literal)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nmacro_rules! my_concat {\n    ($fmt:literal $(, $e:expr)*) => {\n        println!(concat!(\"ERROR: \", $fmt), $($e,)*);\n    }\n}\n\nfn main() {\n    let x = \"\"; //~ useless_concat\n    let x = \"c\"; //~ useless_concat\n    let x = \"\\\"\"; //~ useless_concat\n    let x = \"true\"; //~ useless_concat\n    let x = \"1\"; //~ useless_concat\n    let x = \"1.0000\"; //~ useless_concat\n    let x = \"1\"; //~ useless_concat\n    let x = \"1\"; //~ useless_concat\n    let x = \"1.0000\"; //~ useless_concat\n    let x = \"1.0000\"; //~ useless_concat\n    let x = \"a😀\\n\"; //~ useless_concat\n    let x = \"a\"; //~ useless_concat\n    let x = \"1\"; //~ useless_concat\n    println!(\"b: {}\", \"a\"); //~ useless_concat\n    // Should not lint.\n    let x = concat!(\"a\", \"b\");\n    let local_i32 = 1;\n    my_concat!(\"{}\", local_i32);\n    let x = concat!(file!(), \"#L\", line!());\n\n    external! { concat!(); }\n    with_span! {\n        span\n        concat!();\n    }\n}\n"
  },
  {
    "path": "tests/ui/useless_concat.rs",
    "content": "//@aux-build:proc_macros.rs\n\n#![warn(clippy::useless_concat)]\n#![allow(clippy::print_literal)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nmacro_rules! my_concat {\n    ($fmt:literal $(, $e:expr)*) => {\n        println!(concat!(\"ERROR: \", $fmt), $($e,)*);\n    }\n}\n\nfn main() {\n    let x = concat!(); //~ useless_concat\n    let x = concat!('c'); //~ useless_concat\n    let x = concat!('\"'); //~ useless_concat\n    let x = concat!(true); //~ useless_concat\n    let x = concat!(1f32); //~ useless_concat\n    let x = concat!(1.0000f32); //~ useless_concat\n    let x = concat!(1_f32); //~ useless_concat\n    let x = concat!(1_); //~ useless_concat\n    let x = concat!(1.0000_f32); //~ useless_concat\n    let x = concat!(1.0000_); //~ useless_concat\n    let x = concat!(\"a\\u{1f600}\\n\"); //~ useless_concat\n    let x = concat!(r##\"a\"##); //~ useless_concat\n    let x = concat!(1); //~ useless_concat\n    println!(\"b: {}\", concat!(\"a\")); //~ useless_concat\n    // Should not lint.\n    let x = concat!(\"a\", \"b\");\n    let local_i32 = 1;\n    my_concat!(\"{}\", local_i32);\n    let x = concat!(file!(), \"#L\", line!());\n\n    external! { concat!(); }\n    with_span! {\n        span\n        concat!();\n    }\n}\n"
  },
  {
    "path": "tests/ui/useless_concat.stderr",
    "content": "error: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:16:13\n   |\nLL |     let x = concat!();\n   |             ^^^^^^^^^ help: replace with: `\"\"`\n   |\n   = note: `-D clippy::useless-concat` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_concat)]`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:17:13\n   |\nLL |     let x = concat!('c');\n   |             ^^^^^^^^^^^^ help: replace with: `\"c\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:18:13\n   |\nLL |     let x = concat!('\"');\n   |             ^^^^^^^^^^^^ help: replace with: `\"\\\"\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:19:13\n   |\nLL |     let x = concat!(true);\n   |             ^^^^^^^^^^^^^ help: replace with: `\"true\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:20:13\n   |\nLL |     let x = concat!(1f32);\n   |             ^^^^^^^^^^^^^ help: replace with: `\"1\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:21:13\n   |\nLL |     let x = concat!(1.0000f32);\n   |             ^^^^^^^^^^^^^^^^^^ help: replace with: `\"1.0000\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:22:13\n   |\nLL |     let x = concat!(1_f32);\n   |             ^^^^^^^^^^^^^^ help: replace with: `\"1\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:23:13\n   |\nLL |     let x = concat!(1_);\n   |             ^^^^^^^^^^^ help: replace with: `\"1\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:24:13\n   |\nLL |     let x = concat!(1.0000_f32);\n   |             ^^^^^^^^^^^^^^^^^^^ help: replace with: `\"1.0000\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:25:13\n   |\nLL |     let x = concat!(1.0000_);\n   |             ^^^^^^^^^^^^^^^^ help: replace with: `\"1.0000\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:26:13\n   |\nLL |     let x = concat!(\"a\\u{1f600}\\n\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `\"a😀\\n\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:27:13\n   |\nLL |     let x = concat!(r##\"a\"##);\n   |             ^^^^^^^^^^^^^^^^^ help: replace with: `\"a\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:28:13\n   |\nLL |     let x = concat!(1);\n   |             ^^^^^^^^^^ help: replace with: `\"1\"`\n\nerror: unneeded use of `concat!` macro\n  --> tests/ui/useless_concat.rs:29:23\n   |\nLL |     println!(\"b: {}\", concat!(\"a\"));\n   |                       ^^^^^^^^^^^^ help: replace with: `\"a\"`\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/useless_conversion.fixed",
    "content": "#![deny(clippy::useless_conversion)]\n#![allow(clippy::into_iter_on_ref)]\n#![allow(clippy::needless_ifs, clippy::unnecessary_wraps, unused)]\n// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint\n#![allow(static_mut_refs)]\n\nuse std::ops::ControlFlow;\n\nfn test_generic<T: Copy>(val: T) -> T {\n    let _ = val;\n    //~^ useless_conversion\n    val\n    //~^ useless_conversion\n}\n\nfn test_generic2<T: Copy + Into<i32> + Into<U>, U: From<T>>(val: T) {\n    // ok\n    let _: i32 = val.into();\n    let _: U = val.into();\n    let _ = U::from(val);\n}\n\nfn test_questionmark() -> Result<(), ()> {\n    {\n        let _: i32 = 0i32;\n        //~^ useless_conversion\n        Ok(Ok(()))\n    }??;\n    Ok(())\n}\n\nfn test_issue_3913() -> Result<(), std::io::Error> {\n    use std::fs;\n    use std::path::Path;\n\n    let path = Path::new(\".\");\n    for _ in fs::read_dir(path)? {}\n\n    Ok(())\n}\n\nfn dont_lint_on_type_alias() {\n    type A = i32;\n    _ = A::from(0i32);\n}\n\nfn dont_lint_into_iter_on_immutable_local_implementing_iterator_in_expr() {\n    let text = \"foo\\r\\nbar\\n\\nbaz\\n\";\n    let lines = text.lines();\n    if Some(\"ok\") == lines.into_iter().next() {}\n}\n\nfn lint_into_iter_on_mutable_local_implementing_iterator_in_expr() {\n    let text = \"foo\\r\\nbar\\n\\nbaz\\n\";\n    let mut lines = text.lines();\n    if Some(\"ok\") == lines.next() {}\n    //~^ useless_conversion\n}\n\nfn lint_into_iter_on_expr_implementing_iterator() {\n    let text = \"foo\\r\\nbar\\n\\nbaz\\n\";\n    let mut lines = text.lines();\n    //~^ useless_conversion\n    if Some(\"ok\") == lines.next() {}\n}\n\nfn lint_into_iter_on_expr_implementing_iterator_2() {\n    let text = \"foo\\r\\nbar\\n\\nbaz\\n\";\n    if Some(\"ok\") == text.lines().next() {}\n    //~^ useless_conversion\n}\n\n#[allow(const_item_mutation)]\nfn lint_into_iter_on_const_implementing_iterator() {\n    const NUMBERS: std::ops::Range<i32> = 0..10;\n    let _ = NUMBERS.next();\n    //~^ useless_conversion\n}\n\nfn lint_into_iter_on_const_implementing_iterator_2() {\n    const NUMBERS: std::ops::Range<i32> = 0..10;\n    let mut n = NUMBERS;\n    //~^ useless_conversion\n    n.next();\n}\n\n#[derive(Clone, Copy)]\nstruct CopiableCounter {\n    counter: u32,\n}\n\nimpl Iterator for CopiableCounter {\n    type Item = u32;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.counter = self.counter.wrapping_add(1);\n        Some(self.counter)\n    }\n}\n\nfn dont_lint_into_iter_on_copy_iter() {\n    let mut c = CopiableCounter { counter: 0 };\n    assert_eq!(c.into_iter().next(), Some(1));\n    assert_eq!(c.into_iter().next(), Some(1));\n    assert_eq!(c.next(), Some(1));\n    assert_eq!(c.next(), Some(2));\n}\n\nfn dont_lint_into_iter_on_static_copy_iter() {\n    static mut C: CopiableCounter = CopiableCounter { counter: 0 };\n    unsafe {\n        assert_eq!(C.into_iter().next(), Some(1));\n        assert_eq!(C.into_iter().next(), Some(1));\n        assert_eq!(C.next(), Some(1));\n        assert_eq!(C.next(), Some(2));\n    }\n}\n\nfn main() {\n    {\n        // triggers the IntoIterator trait\n        fn consume(_: impl IntoIterator) {}\n\n        // Should suggest `*items` instead of `&**items`\n        let items = &&[1, 2, 3];\n        consume(*items); //~ useless_conversion\n    }\n\n    let _: String = \"foo\".into();\n    let _: String = From::from(\"foo\");\n    let _ = String::from(\"foo\");\n    #[allow(clippy::useless_conversion)]\n    {\n        let _: String = \"foo\".into();\n        let _ = String::from(\"foo\");\n        let _ = \"\".lines().into_iter();\n    }\n\n    let _: String = \"foo\".to_string();\n    //~^ useless_conversion\n    let _: String = \"foo\".to_string();\n    //~^ useless_conversion\n    let _ = \"foo\".to_string();\n    //~^ useless_conversion\n    let _ = format!(\"A: {:04}\", 123);\n    //~^ useless_conversion\n    let _ = \"\".lines();\n    //~^ useless_conversion\n    let _ = vec![1, 2, 3].into_iter();\n    //~^ useless_conversion\n    let _: String = format!(\"Hello {}\", \"world\");\n    //~^ useless_conversion\n\n    // keep parentheses around `a + b` for suggestion (see #4750)\n    let a: i32 = 1;\n    let b: i32 = 1;\n    let _ = (a + b) * 3;\n    //~^ useless_conversion\n\n    // see #7205\n    let s: Foo<'a'> = Foo;\n    let _: Foo<'b'> = s.into();\n    let s2: Foo<'a'> = Foo;\n    let _: Foo<'a'> = s2;\n    //~^ useless_conversion\n    let s3: Foo<'a'> = Foo;\n    let _ = s3;\n    //~^ useless_conversion\n    let s4: Foo<'a'> = Foo;\n    let _ = vec![s4, s4, s4].into_iter();\n    //~^ useless_conversion\n\n    issue11300::bar();\n}\n\n#[allow(dead_code)]\nfn issue11065_fp() {\n    use std::option::IntoIter;\n    fn takes_into_iter(_: impl IntoIterator<Item = i32>) {}\n\n    macro_rules! x {\n        ($e:expr) => {\n            takes_into_iter($e);\n            let _: IntoIter<i32> = $e; // removing `.into_iter()` leads to a type error here\n        };\n    }\n    x!(Some(5).into_iter());\n}\n\n#[allow(dead_code)]\nfn explicit_into_iter_fn_arg() {\n    fn a<T>(_: T) {}\n    fn b<T: IntoIterator<Item = i32>>(_: T) {}\n    fn c(_: impl IntoIterator<Item = i32>) {}\n    fn d<T>(_: T)\n    where\n        T: IntoIterator<Item = i32>,\n    {\n    }\n    fn f(_: std::vec::IntoIter<i32>) {}\n\n    a(vec![1, 2].into_iter());\n    b(vec![1, 2]);\n    //~^ useless_conversion\n    c(vec![1, 2]);\n    //~^ useless_conversion\n    d(vec![1, 2]);\n    //~^ useless_conversion\n    b([&1, &2, &3].into_iter().cloned());\n\n    b(vec![1, 2]);\n    //~^ useless_conversion\n    b(vec![1, 2]);\n    //~^ useless_conversion\n\n    macro_rules! macro_generated {\n        () => {\n            vec![1, 2].into_iter()\n        };\n    }\n    b(macro_generated!());\n}\n\nmod issue11300 {\n    pub fn foo<I>(i: I)\n    where\n        I: IntoIterator<Item = i32> + ExactSizeIterator,\n    {\n        assert_eq!(i.len(), 3);\n    }\n\n    trait Helper<T: ?Sized> {}\n    impl Helper<i32> for [i32; 3] {}\n    impl Helper<i32> for std::array::IntoIter<i32, 3> {}\n    impl Helper<()> for std::array::IntoIter<i32, 3> {}\n\n    fn foo2<X: ?Sized, I>(_: I)\n    where\n        I: IntoIterator<Item = i32> + Helper<X>,\n    {\n    }\n\n    trait Helper2<T> {}\n    impl Helper2<std::array::IntoIter<i32, 3>> for i32 {}\n    impl Helper2<[i32; 3]> for i32 {}\n    fn foo3<I>(_: I)\n    where\n        I: IntoIterator<Item = i32>,\n        i32: Helper2<I>,\n    {\n    }\n\n    pub fn bar() {\n        // This should not trigger the lint:\n        // `[i32, 3]` does not satisfy the `ExactSizeIterator` bound, so the into_iter call cannot be\n        // removed and is not useless.\n        foo([1, 2, 3].into_iter());\n\n        // This should trigger the lint, receiver type [i32; 3] also implements `Helper`\n        foo2::<i32, _>([1, 2, 3]);\n        //~^ useless_conversion\n\n        // This again should *not* lint, since X = () and I = std::array::IntoIter<i32, 3>,\n        // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter<i32, 3>: Helper<()>` is).\n        foo2::<(), _>([1, 2, 3].into_iter());\n\n        // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`,\n        // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unnecessary.\n        foo3([1, 2, 3]);\n        //~^ useless_conversion\n    }\n\n    fn ice() {\n        struct S1;\n        impl S1 {\n            pub fn foo<I: IntoIterator>(&self, _: I) {}\n        }\n\n        S1.foo([1, 2]);\n        //~^ useless_conversion\n\n        // ICE that occurred in itertools\n        trait Itertools {\n            fn interleave_shortest<J>(self, other: J)\n            where\n                J: IntoIterator,\n                Self: Sized;\n        }\n        impl<I: Iterator> Itertools for I {\n            fn interleave_shortest<J>(self, other: J)\n            where\n                J: IntoIterator,\n                Self: Sized,\n            {\n            }\n        }\n        let v0: Vec<i32> = vec![0, 2, 4];\n        let v1: Vec<i32> = vec![1, 3, 5, 7];\n        v0.into_iter().interleave_shortest(v1);\n        //~^ useless_conversion\n\n        trait TraitWithLifetime<'a> {}\n        impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {}\n\n        struct Helper;\n        impl<'a> Helper {\n            fn with_lt<I>(&self, _: I)\n            where\n                I: IntoIterator + TraitWithLifetime<'a>,\n            {\n            }\n        }\n        Helper.with_lt([&1, &2].into_iter());\n    }\n}\n\n#[derive(Copy, Clone)]\nstruct Foo<const C: char>;\n\nimpl From<Foo<'a'>> for Foo<'b'> {\n    fn from(_s: Foo<'a'>) -> Self {\n        Foo\n    }\n}\n\nfn direct_application() {\n    let _: Result<(), std::io::Error> = test_issue_3913();\n    //~^ useless_conversion\n\n    let _: Result<(), std::io::Error> = test_issue_3913();\n    //~^ useless_conversion\n\n    let _: Result<(), std::io::Error> = test_issue_3913();\n    //~^ useless_conversion\n\n    let _: Result<(), std::io::Error> = test_issue_3913();\n    //~^ useless_conversion\n\n    let c: ControlFlow<()> = ControlFlow::Continue(());\n    let _: ControlFlow<()> = c;\n    //~^ useless_conversion\n\n    let c: ControlFlow<()> = ControlFlow::Continue(());\n    let _: ControlFlow<()> = c;\n    //~^ useless_conversion\n\n    struct Absorb;\n    impl From<()> for Absorb {\n        fn from(_: ()) -> Self {\n            Self\n        }\n    }\n    impl From<std::io::Error> for Absorb {\n        fn from(_: std::io::Error) -> Self {\n            Self\n        }\n    }\n    let _: Vec<u32> = [1u32].into_iter().collect();\n    //~^ useless_conversion\n\n    // No lint for those\n    let _: Result<Absorb, std::io::Error> = test_issue_3913().map(Into::into);\n    let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into);\n    let _: Result<Absorb, std::io::Error> = test_issue_3913().map(From::from);\n    let _: Result<(), Absorb> = test_issue_3913().map_err(From::from);\n}\n\nfn gen_identity<T>(x: [T; 3]) -> Vec<T> {\n    x.into_iter().collect()\n    //~^ useless_conversion\n}\n\nmod issue11819 {\n    fn takes_into_iter(_: impl IntoIterator<Item = String>) {}\n\n    pub struct MyStruct<T> {\n        my_field: T,\n    }\n\n    impl<T> MyStruct<T> {\n        pub fn with_ref<'a>(&'a mut self)\n        where\n            &'a T: IntoIterator<Item = String>,\n        {\n            takes_into_iter(&self.my_field);\n            //~^ useless_conversion\n        }\n\n        pub fn with_ref_mut<'a>(&'a mut self)\n        where\n            &'a mut T: IntoIterator<Item = String>,\n        {\n            takes_into_iter(&mut self.my_field);\n            //~^ useless_conversion\n        }\n\n        pub fn with_deref<Y>(&mut self)\n        where\n            T: std::ops::Deref<Target = Y>,\n            Y: IntoIterator<Item = String> + Copy,\n        {\n            takes_into_iter(*self.my_field);\n            //~^ useless_conversion\n        }\n\n        pub fn with_reborrow<'a, Y: 'a>(&'a mut self)\n        where\n            T: std::ops::Deref<Target = Y>,\n            &'a Y: IntoIterator<Item = String>,\n        {\n            takes_into_iter(&*self.my_field);\n            //~^ useless_conversion\n        }\n\n        pub fn with_reborrow_mut<'a, Y: 'a>(&'a mut self)\n        where\n            T: std::ops::Deref<Target = Y> + std::ops::DerefMut,\n            &'a mut Y: IntoIterator<Item = String>,\n        {\n            takes_into_iter(&mut *self.my_field);\n            //~^ useless_conversion\n        }\n    }\n}\n\nfn issue14739() {\n    use std::ops::Range;\n\n    const R: Range<u32> = 2..7;\n\n    R.into_iter().all(|_x| true); // no lint\n\n    R.into_iter().any(|_x| true); // no lint\n\n    R.for_each(|_x| {});\n    //~^ useless_conversion\n    let _ = R.map(|_x| 0);\n    //~^ useless_conversion\n}\n\nfn issue16165() {\n    macro_rules! mac {\n        (iter $e:expr) => {\n            $e.iter()\n        };\n    }\n\n    for _ in mac!(iter [1, 2]) {}\n    //~^ useless_conversion\n}\n\nfn takes_into_iter_usize(_: impl IntoIterator<Item = usize>) {}\nfn takes_into_iter_usize_result(_: impl IntoIterator<Item = usize>) -> Result<(), ()> {\n    Ok(())\n}\n\nasync fn issue16590() {\n    let a: Vec<usize> = vec![];\n    let b: Vec<usize> = vec![];\n\n    takes_into_iter_usize(b);\n    //~^ useless_conversion\n}\n\nfn in_for_loop() {\n    let a: Vec<usize> = vec![1, 2, 3];\n    let b: Vec<usize> = vec![4, 5, 6];\n\n    for _ in &a {\n        takes_into_iter_usize(b.clone());\n        //~^ useless_conversion\n    }\n}\n\nfn after_question_mark() -> Result<(), ()> {\n    let b: Vec<usize> = vec![4, 5, 6];\n\n    takes_into_iter_usize_result(b.clone())?;\n    //~^ useless_conversion\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/useless_conversion.rs",
    "content": "#![deny(clippy::useless_conversion)]\n#![allow(clippy::into_iter_on_ref)]\n#![allow(clippy::needless_ifs, clippy::unnecessary_wraps, unused)]\n// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint\n#![allow(static_mut_refs)]\n\nuse std::ops::ControlFlow;\n\nfn test_generic<T: Copy>(val: T) -> T {\n    let _ = T::from(val);\n    //~^ useless_conversion\n    val.into()\n    //~^ useless_conversion\n}\n\nfn test_generic2<T: Copy + Into<i32> + Into<U>, U: From<T>>(val: T) {\n    // ok\n    let _: i32 = val.into();\n    let _: U = val.into();\n    let _ = U::from(val);\n}\n\nfn test_questionmark() -> Result<(), ()> {\n    {\n        let _: i32 = 0i32.into();\n        //~^ useless_conversion\n        Ok(Ok(()))\n    }??;\n    Ok(())\n}\n\nfn test_issue_3913() -> Result<(), std::io::Error> {\n    use std::fs;\n    use std::path::Path;\n\n    let path = Path::new(\".\");\n    for _ in fs::read_dir(path)? {}\n\n    Ok(())\n}\n\nfn dont_lint_on_type_alias() {\n    type A = i32;\n    _ = A::from(0i32);\n}\n\nfn dont_lint_into_iter_on_immutable_local_implementing_iterator_in_expr() {\n    let text = \"foo\\r\\nbar\\n\\nbaz\\n\";\n    let lines = text.lines();\n    if Some(\"ok\") == lines.into_iter().next() {}\n}\n\nfn lint_into_iter_on_mutable_local_implementing_iterator_in_expr() {\n    let text = \"foo\\r\\nbar\\n\\nbaz\\n\";\n    let mut lines = text.lines();\n    if Some(\"ok\") == lines.into_iter().next() {}\n    //~^ useless_conversion\n}\n\nfn lint_into_iter_on_expr_implementing_iterator() {\n    let text = \"foo\\r\\nbar\\n\\nbaz\\n\";\n    let mut lines = text.lines().into_iter();\n    //~^ useless_conversion\n    if Some(\"ok\") == lines.next() {}\n}\n\nfn lint_into_iter_on_expr_implementing_iterator_2() {\n    let text = \"foo\\r\\nbar\\n\\nbaz\\n\";\n    if Some(\"ok\") == text.lines().into_iter().next() {}\n    //~^ useless_conversion\n}\n\n#[allow(const_item_mutation)]\nfn lint_into_iter_on_const_implementing_iterator() {\n    const NUMBERS: std::ops::Range<i32> = 0..10;\n    let _ = NUMBERS.into_iter().next();\n    //~^ useless_conversion\n}\n\nfn lint_into_iter_on_const_implementing_iterator_2() {\n    const NUMBERS: std::ops::Range<i32> = 0..10;\n    let mut n = NUMBERS.into_iter();\n    //~^ useless_conversion\n    n.next();\n}\n\n#[derive(Clone, Copy)]\nstruct CopiableCounter {\n    counter: u32,\n}\n\nimpl Iterator for CopiableCounter {\n    type Item = u32;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.counter = self.counter.wrapping_add(1);\n        Some(self.counter)\n    }\n}\n\nfn dont_lint_into_iter_on_copy_iter() {\n    let mut c = CopiableCounter { counter: 0 };\n    assert_eq!(c.into_iter().next(), Some(1));\n    assert_eq!(c.into_iter().next(), Some(1));\n    assert_eq!(c.next(), Some(1));\n    assert_eq!(c.next(), Some(2));\n}\n\nfn dont_lint_into_iter_on_static_copy_iter() {\n    static mut C: CopiableCounter = CopiableCounter { counter: 0 };\n    unsafe {\n        assert_eq!(C.into_iter().next(), Some(1));\n        assert_eq!(C.into_iter().next(), Some(1));\n        assert_eq!(C.next(), Some(1));\n        assert_eq!(C.next(), Some(2));\n    }\n}\n\nfn main() {\n    {\n        // triggers the IntoIterator trait\n        fn consume(_: impl IntoIterator) {}\n\n        // Should suggest `*items` instead of `&**items`\n        let items = &&[1, 2, 3];\n        consume(items.into_iter()); //~ useless_conversion\n    }\n\n    let _: String = \"foo\".into();\n    let _: String = From::from(\"foo\");\n    let _ = String::from(\"foo\");\n    #[allow(clippy::useless_conversion)]\n    {\n        let _: String = \"foo\".into();\n        let _ = String::from(\"foo\");\n        let _ = \"\".lines().into_iter();\n    }\n\n    let _: String = \"foo\".to_string().into();\n    //~^ useless_conversion\n    let _: String = From::from(\"foo\".to_string());\n    //~^ useless_conversion\n    let _ = String::from(\"foo\".to_string());\n    //~^ useless_conversion\n    let _ = String::from(format!(\"A: {:04}\", 123));\n    //~^ useless_conversion\n    let _ = \"\".lines().into_iter();\n    //~^ useless_conversion\n    let _ = vec![1, 2, 3].into_iter().into_iter();\n    //~^ useless_conversion\n    let _: String = format!(\"Hello {}\", \"world\").into();\n    //~^ useless_conversion\n\n    // keep parentheses around `a + b` for suggestion (see #4750)\n    let a: i32 = 1;\n    let b: i32 = 1;\n    let _ = i32::from(a + b) * 3;\n    //~^ useless_conversion\n\n    // see #7205\n    let s: Foo<'a'> = Foo;\n    let _: Foo<'b'> = s.into();\n    let s2: Foo<'a'> = Foo;\n    let _: Foo<'a'> = s2.into();\n    //~^ useless_conversion\n    let s3: Foo<'a'> = Foo;\n    let _ = Foo::<'a'>::from(s3);\n    //~^ useless_conversion\n    let s4: Foo<'a'> = Foo;\n    let _ = vec![s4, s4, s4].into_iter().into_iter();\n    //~^ useless_conversion\n\n    issue11300::bar();\n}\n\n#[allow(dead_code)]\nfn issue11065_fp() {\n    use std::option::IntoIter;\n    fn takes_into_iter(_: impl IntoIterator<Item = i32>) {}\n\n    macro_rules! x {\n        ($e:expr) => {\n            takes_into_iter($e);\n            let _: IntoIter<i32> = $e; // removing `.into_iter()` leads to a type error here\n        };\n    }\n    x!(Some(5).into_iter());\n}\n\n#[allow(dead_code)]\nfn explicit_into_iter_fn_arg() {\n    fn a<T>(_: T) {}\n    fn b<T: IntoIterator<Item = i32>>(_: T) {}\n    fn c(_: impl IntoIterator<Item = i32>) {}\n    fn d<T>(_: T)\n    where\n        T: IntoIterator<Item = i32>,\n    {\n    }\n    fn f(_: std::vec::IntoIter<i32>) {}\n\n    a(vec![1, 2].into_iter());\n    b(vec![1, 2].into_iter());\n    //~^ useless_conversion\n    c(vec![1, 2].into_iter());\n    //~^ useless_conversion\n    d(vec![1, 2].into_iter());\n    //~^ useless_conversion\n    b([&1, &2, &3].into_iter().cloned());\n\n    b(vec![1, 2].into_iter().into_iter());\n    //~^ useless_conversion\n    b(vec![1, 2].into_iter().into_iter().into_iter());\n    //~^ useless_conversion\n\n    macro_rules! macro_generated {\n        () => {\n            vec![1, 2].into_iter()\n        };\n    }\n    b(macro_generated!());\n}\n\nmod issue11300 {\n    pub fn foo<I>(i: I)\n    where\n        I: IntoIterator<Item = i32> + ExactSizeIterator,\n    {\n        assert_eq!(i.len(), 3);\n    }\n\n    trait Helper<T: ?Sized> {}\n    impl Helper<i32> for [i32; 3] {}\n    impl Helper<i32> for std::array::IntoIter<i32, 3> {}\n    impl Helper<()> for std::array::IntoIter<i32, 3> {}\n\n    fn foo2<X: ?Sized, I>(_: I)\n    where\n        I: IntoIterator<Item = i32> + Helper<X>,\n    {\n    }\n\n    trait Helper2<T> {}\n    impl Helper2<std::array::IntoIter<i32, 3>> for i32 {}\n    impl Helper2<[i32; 3]> for i32 {}\n    fn foo3<I>(_: I)\n    where\n        I: IntoIterator<Item = i32>,\n        i32: Helper2<I>,\n    {\n    }\n\n    pub fn bar() {\n        // This should not trigger the lint:\n        // `[i32, 3]` does not satisfy the `ExactSizeIterator` bound, so the into_iter call cannot be\n        // removed and is not useless.\n        foo([1, 2, 3].into_iter());\n\n        // This should trigger the lint, receiver type [i32; 3] also implements `Helper`\n        foo2::<i32, _>([1, 2, 3].into_iter());\n        //~^ useless_conversion\n\n        // This again should *not* lint, since X = () and I = std::array::IntoIter<i32, 3>,\n        // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter<i32, 3>: Helper<()>` is).\n        foo2::<(), _>([1, 2, 3].into_iter());\n\n        // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`,\n        // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unnecessary.\n        foo3([1, 2, 3].into_iter());\n        //~^ useless_conversion\n    }\n\n    fn ice() {\n        struct S1;\n        impl S1 {\n            pub fn foo<I: IntoIterator>(&self, _: I) {}\n        }\n\n        S1.foo([1, 2].into_iter());\n        //~^ useless_conversion\n\n        // ICE that occurred in itertools\n        trait Itertools {\n            fn interleave_shortest<J>(self, other: J)\n            where\n                J: IntoIterator,\n                Self: Sized;\n        }\n        impl<I: Iterator> Itertools for I {\n            fn interleave_shortest<J>(self, other: J)\n            where\n                J: IntoIterator,\n                Self: Sized,\n            {\n            }\n        }\n        let v0: Vec<i32> = vec![0, 2, 4];\n        let v1: Vec<i32> = vec![1, 3, 5, 7];\n        v0.into_iter().interleave_shortest(v1.into_iter());\n        //~^ useless_conversion\n\n        trait TraitWithLifetime<'a> {}\n        impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {}\n\n        struct Helper;\n        impl<'a> Helper {\n            fn with_lt<I>(&self, _: I)\n            where\n                I: IntoIterator + TraitWithLifetime<'a>,\n            {\n            }\n        }\n        Helper.with_lt([&1, &2].into_iter());\n    }\n}\n\n#[derive(Copy, Clone)]\nstruct Foo<const C: char>;\n\nimpl From<Foo<'a'>> for Foo<'b'> {\n    fn from(_s: Foo<'a'>) -> Self {\n        Foo\n    }\n}\n\nfn direct_application() {\n    let _: Result<(), std::io::Error> = test_issue_3913().map(Into::into);\n    //~^ useless_conversion\n\n    let _: Result<(), std::io::Error> = test_issue_3913().map_err(Into::into);\n    //~^ useless_conversion\n\n    let _: Result<(), std::io::Error> = test_issue_3913().map(From::from);\n    //~^ useless_conversion\n\n    let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from);\n    //~^ useless_conversion\n\n    let c: ControlFlow<()> = ControlFlow::Continue(());\n    let _: ControlFlow<()> = c.map_break(Into::into);\n    //~^ useless_conversion\n\n    let c: ControlFlow<()> = ControlFlow::Continue(());\n    let _: ControlFlow<()> = c.map_continue(Into::into);\n    //~^ useless_conversion\n\n    struct Absorb;\n    impl From<()> for Absorb {\n        fn from(_: ()) -> Self {\n            Self\n        }\n    }\n    impl From<std::io::Error> for Absorb {\n        fn from(_: std::io::Error) -> Self {\n            Self\n        }\n    }\n    let _: Vec<u32> = [1u32].into_iter().map(Into::into).collect();\n    //~^ useless_conversion\n\n    // No lint for those\n    let _: Result<Absorb, std::io::Error> = test_issue_3913().map(Into::into);\n    let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into);\n    let _: Result<Absorb, std::io::Error> = test_issue_3913().map(From::from);\n    let _: Result<(), Absorb> = test_issue_3913().map_err(From::from);\n}\n\nfn gen_identity<T>(x: [T; 3]) -> Vec<T> {\n    x.into_iter().map(Into::into).collect()\n    //~^ useless_conversion\n}\n\nmod issue11819 {\n    fn takes_into_iter(_: impl IntoIterator<Item = String>) {}\n\n    pub struct MyStruct<T> {\n        my_field: T,\n    }\n\n    impl<T> MyStruct<T> {\n        pub fn with_ref<'a>(&'a mut self)\n        where\n            &'a T: IntoIterator<Item = String>,\n        {\n            takes_into_iter(self.my_field.into_iter());\n            //~^ useless_conversion\n        }\n\n        pub fn with_ref_mut<'a>(&'a mut self)\n        where\n            &'a mut T: IntoIterator<Item = String>,\n        {\n            takes_into_iter(self.my_field.into_iter());\n            //~^ useless_conversion\n        }\n\n        pub fn with_deref<Y>(&mut self)\n        where\n            T: std::ops::Deref<Target = Y>,\n            Y: IntoIterator<Item = String> + Copy,\n        {\n            takes_into_iter(self.my_field.into_iter());\n            //~^ useless_conversion\n        }\n\n        pub fn with_reborrow<'a, Y: 'a>(&'a mut self)\n        where\n            T: std::ops::Deref<Target = Y>,\n            &'a Y: IntoIterator<Item = String>,\n        {\n            takes_into_iter(self.my_field.into_iter());\n            //~^ useless_conversion\n        }\n\n        pub fn with_reborrow_mut<'a, Y: 'a>(&'a mut self)\n        where\n            T: std::ops::Deref<Target = Y> + std::ops::DerefMut,\n            &'a mut Y: IntoIterator<Item = String>,\n        {\n            takes_into_iter(self.my_field.into_iter());\n            //~^ useless_conversion\n        }\n    }\n}\n\nfn issue14739() {\n    use std::ops::Range;\n\n    const R: Range<u32> = 2..7;\n\n    R.into_iter().all(|_x| true); // no lint\n\n    R.into_iter().any(|_x| true); // no lint\n\n    R.into_iter().for_each(|_x| {});\n    //~^ useless_conversion\n    let _ = R.into_iter().map(|_x| 0);\n    //~^ useless_conversion\n}\n\nfn issue16165() {\n    macro_rules! mac {\n        (iter $e:expr) => {\n            $e.iter()\n        };\n    }\n\n    for _ in mac!(iter [1, 2]).into_iter() {}\n    //~^ useless_conversion\n}\n\nfn takes_into_iter_usize(_: impl IntoIterator<Item = usize>) {}\nfn takes_into_iter_usize_result(_: impl IntoIterator<Item = usize>) -> Result<(), ()> {\n    Ok(())\n}\n\nasync fn issue16590() {\n    let a: Vec<usize> = vec![];\n    let b: Vec<usize> = vec![];\n\n    takes_into_iter_usize(b.into_iter());\n    //~^ useless_conversion\n}\n\nfn in_for_loop() {\n    let a: Vec<usize> = vec![1, 2, 3];\n    let b: Vec<usize> = vec![4, 5, 6];\n\n    for _ in &a {\n        takes_into_iter_usize(b.clone().into_iter());\n        //~^ useless_conversion\n    }\n}\n\nfn after_question_mark() -> Result<(), ()> {\n    let b: Vec<usize> = vec![4, 5, 6];\n\n    takes_into_iter_usize_result(b.clone().into_iter())?;\n    //~^ useless_conversion\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/useless_conversion.stderr",
    "content": "error: useless conversion to the same type: `T`\n  --> tests/ui/useless_conversion.rs:10:13\n   |\nLL |     let _ = T::from(val);\n   |             ^^^^^^^^^^^^ help: consider removing `T::from()`: `val`\n   |\nnote: the lint level is defined here\n  --> tests/ui/useless_conversion.rs:1:9\n   |\nLL | #![deny(clippy::useless_conversion)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: useless conversion to the same type: `T`\n  --> tests/ui/useless_conversion.rs:12:5\n   |\nLL |     val.into()\n   |     ^^^^^^^^^^ help: consider removing `.into()`: `val`\n\nerror: useless conversion to the same type: `i32`\n  --> tests/ui/useless_conversion.rs:25:22\n   |\nLL |         let _: i32 = 0i32.into();\n   |                      ^^^^^^^^^^^ help: consider removing `.into()`: `0i32`\n\nerror: useless conversion to the same type: `std::str::Lines<'_>`\n  --> tests/ui/useless_conversion.rs:56:22\n   |\nLL |     if Some(\"ok\") == lines.into_iter().next() {}\n   |                      ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines`\n\nerror: useless conversion to the same type: `std::str::Lines<'_>`\n  --> tests/ui/useless_conversion.rs:62:21\n   |\nLL |     let mut lines = text.lines().into_iter();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`\n\nerror: useless conversion to the same type: `std::str::Lines<'_>`\n  --> tests/ui/useless_conversion.rs:69:22\n   |\nLL |     if Some(\"ok\") == text.lines().into_iter().next() {}\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`\n\nerror: useless conversion to the same type: `std::ops::Range<i32>`\n  --> tests/ui/useless_conversion.rs:76:13\n   |\nLL |     let _ = NUMBERS.into_iter().next();\n   |             ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`\n\nerror: useless conversion to the same type: `std::ops::Range<i32>`\n  --> tests/ui/useless_conversion.rs:82:17\n   |\nLL |     let mut n = NUMBERS.into_iter();\n   |                 ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:126:17\n   |\nLL |         consume(items.into_iter());\n   |                 ^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:122:28\n   |\nLL |         fn consume(_: impl IntoIterator) {}\n   |                            ^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -         consume(items.into_iter());\nLL +         consume(*items);\n   |\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion.rs:139:21\n   |\nLL |     let _: String = \"foo\".to_string().into();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `\"foo\".to_string()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion.rs:141:21\n   |\nLL |     let _: String = From::from(\"foo\".to_string());\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `\"foo\".to_string()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion.rs:143:13\n   |\nLL |     let _ = String::from(\"foo\".to_string());\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `\"foo\".to_string()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion.rs:145:13\n   |\nLL |     let _ = String::from(format!(\"A: {:04}\", 123));\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!(\"A: {:04}\", 123)`\n\nerror: useless conversion to the same type: `std::str::Lines<'_>`\n  --> tests/ui/useless_conversion.rs:147:13\n   |\nLL |     let _ = \"\".lines().into_iter();\n   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `\"\".lines()`\n\nerror: useless conversion to the same type: `std::vec::IntoIter<i32>`\n  --> tests/ui/useless_conversion.rs:149:13\n   |\nLL |     let _ = vec![1, 2, 3].into_iter().into_iter();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion.rs:151:21\n   |\nLL |     let _: String = format!(\"Hello {}\", \"world\").into();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!(\"Hello {}\", \"world\")`\n\nerror: useless conversion to the same type: `i32`\n  --> tests/ui/useless_conversion.rs:157:13\n   |\nLL |     let _ = i32::from(a + b) * 3;\n   |             ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)`\n\nerror: useless conversion to the same type: `Foo<'a'>`\n  --> tests/ui/useless_conversion.rs:164:23\n   |\nLL |     let _: Foo<'a'> = s2.into();\n   |                       ^^^^^^^^^ help: consider removing `.into()`: `s2`\n\nerror: useless conversion to the same type: `Foo<'a'>`\n  --> tests/ui/useless_conversion.rs:167:13\n   |\nLL |     let _ = Foo::<'a'>::from(s3);\n   |             ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3`\n\nerror: useless conversion to the same type: `std::vec::IntoIter<Foo<'a'>>`\n  --> tests/ui/useless_conversion.rs:170:13\n   |\nLL |     let _ = vec![s4, s4, s4].into_iter().into_iter();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()`\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:203:7\n   |\nLL |     b(vec![1, 2].into_iter());\n   |       ^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:193:13\n   |\nLL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -     b(vec![1, 2].into_iter());\nLL +     b(vec![1, 2]);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:205:7\n   |\nLL |     c(vec![1, 2].into_iter());\n   |       ^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:194:18\n   |\nLL |     fn c(_: impl IntoIterator<Item = i32>) {}\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -     c(vec![1, 2].into_iter());\nLL +     c(vec![1, 2]);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:207:7\n   |\nLL |     d(vec![1, 2].into_iter());\n   |       ^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:197:12\n   |\nLL |         T: IntoIterator<Item = i32>,\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -     d(vec![1, 2].into_iter());\nLL +     d(vec![1, 2]);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:211:7\n   |\nLL |     b(vec![1, 2].into_iter().into_iter());\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:193:13\n   |\nLL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`s\n   |\nLL -     b(vec![1, 2].into_iter().into_iter());\nLL +     b(vec![1, 2]);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:213:7\n   |\nLL |     b(vec![1, 2].into_iter().into_iter().into_iter());\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:193:13\n   |\nLL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`s\n   |\nLL -     b(vec![1, 2].into_iter().into_iter().into_iter());\nLL +     b(vec![1, 2]);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:260:24\n   |\nLL |         foo2::<i32, _>([1, 2, 3].into_iter());\n   |                        ^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:239:12\n   |\nLL |         I: IntoIterator<Item = i32> + Helper<X>,\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -         foo2::<i32, _>([1, 2, 3].into_iter());\nLL +         foo2::<i32, _>([1, 2, 3]);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:269:14\n   |\nLL |         foo3([1, 2, 3].into_iter());\n   |              ^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:248:12\n   |\nLL |         I: IntoIterator<Item = i32>,\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -         foo3([1, 2, 3].into_iter());\nLL +         foo3([1, 2, 3]);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:279:16\n   |\nLL |         S1.foo([1, 2].into_iter());\n   |                ^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:276:27\n   |\nLL |             pub fn foo<I: IntoIterator>(&self, _: I) {}\n   |                           ^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -         S1.foo([1, 2].into_iter());\nLL +         S1.foo([1, 2]);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:299:44\n   |\nLL |         v0.into_iter().interleave_shortest(v1.into_iter());\n   |                                            ^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:286:20\n   |\nLL |                 J: IntoIterator,\n   |                    ^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -         v0.into_iter().interleave_shortest(v1.into_iter());\nLL +         v0.into_iter().interleave_shortest(v1);\n   |\n\nerror: useless conversion to the same type: `()`\n  --> tests/ui/useless_conversion.rs:327:58\n   |\nLL |     let _: Result<(), std::io::Error> = test_issue_3913().map(Into::into);\n   |                                                          ^^^^^^^^^^^^^^^^ help: consider removing\n\nerror: useless conversion to the same type: `std::io::Error`\n  --> tests/ui/useless_conversion.rs:330:58\n   |\nLL |     let _: Result<(), std::io::Error> = test_issue_3913().map_err(Into::into);\n   |                                                          ^^^^^^^^^^^^^^^^^^^^ help: consider removing\n\nerror: useless conversion to the same type: `()`\n  --> tests/ui/useless_conversion.rs:333:58\n   |\nLL |     let _: Result<(), std::io::Error> = test_issue_3913().map(From::from);\n   |                                                          ^^^^^^^^^^^^^^^^ help: consider removing\n\nerror: useless conversion to the same type: `std::io::Error`\n  --> tests/ui/useless_conversion.rs:336:58\n   |\nLL |     let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from);\n   |                                                          ^^^^^^^^^^^^^^^^^^^^ help: consider removing\n\nerror: useless conversion to the same type: `()`\n  --> tests/ui/useless_conversion.rs:340:31\n   |\nLL |     let _: ControlFlow<()> = c.map_break(Into::into);\n   |                               ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing\n\nerror: useless conversion to the same type: `()`\n  --> tests/ui/useless_conversion.rs:344:31\n   |\nLL |     let _: ControlFlow<()> = c.map_continue(Into::into);\n   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing\n\nerror: useless conversion to the same type: `u32`\n  --> tests/ui/useless_conversion.rs:358:41\n   |\nLL |     let _: Vec<u32> = [1u32].into_iter().map(Into::into).collect();\n   |                                         ^^^^^^^^^^^^^^^^ help: consider removing\n\nerror: useless conversion to the same type: `T`\n  --> tests/ui/useless_conversion.rs:369:18\n   |\nLL |     x.into_iter().map(Into::into).collect()\n   |                  ^^^^^^^^^^^^^^^^ help: consider removing\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:385:29\n   |\nLL |             takes_into_iter(self.my_field.into_iter());\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:374:32\n   |\nLL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -             takes_into_iter(self.my_field.into_iter());\nLL +             takes_into_iter(&self.my_field);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:393:29\n   |\nLL |             takes_into_iter(self.my_field.into_iter());\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:374:32\n   |\nLL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -             takes_into_iter(self.my_field.into_iter());\nLL +             takes_into_iter(&mut self.my_field);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:402:29\n   |\nLL |             takes_into_iter(self.my_field.into_iter());\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:374:32\n   |\nLL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -             takes_into_iter(self.my_field.into_iter());\nLL +             takes_into_iter(*self.my_field);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:411:29\n   |\nLL |             takes_into_iter(self.my_field.into_iter());\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:374:32\n   |\nLL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -             takes_into_iter(self.my_field.into_iter());\nLL +             takes_into_iter(&*self.my_field);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:420:29\n   |\nLL |             takes_into_iter(self.my_field.into_iter());\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:374:32\n   |\nLL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -             takes_into_iter(self.my_field.into_iter());\nLL +             takes_into_iter(&mut *self.my_field);\n   |\n\nerror: useless conversion to the same type: `std::ops::Range<u32>`\n  --> tests/ui/useless_conversion.rs:435:5\n   |\nLL |     R.into_iter().for_each(|_x| {});\n   |     ^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `R`\n\nerror: useless conversion to the same type: `std::ops::Range<u32>`\n  --> tests/ui/useless_conversion.rs:437:13\n   |\nLL |     let _ = R.into_iter().map(|_x| 0);\n   |             ^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `R`\n\nerror: useless conversion to the same type: `std::slice::Iter<'_, i32>`\n  --> tests/ui/useless_conversion.rs:448:14\n   |\nLL |     for _ in mac!(iter [1, 2]).into_iter() {}\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `mac!(iter [1, 2])`\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:461:27\n   |\nLL |     takes_into_iter_usize(b.into_iter());\n   |                           ^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:452:34\n   |\nLL | fn takes_into_iter_usize(_: impl IntoIterator<Item = usize>) {}\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -     takes_into_iter_usize(b.into_iter());\nLL +     takes_into_iter_usize(b);\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:470:31\n   |\nLL |         takes_into_iter_usize(b.clone().into_iter());\n   |                               ^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:452:34\n   |\nLL | fn takes_into_iter_usize(_: impl IntoIterator<Item = usize>) {}\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -         takes_into_iter_usize(b.clone().into_iter());\nLL +         takes_into_iter_usize(b.clone());\n   |\n\nerror: explicit call to `.into_iter()` in function argument accepting `IntoIterator`\n  --> tests/ui/useless_conversion.rs:478:34\n   |\nLL |     takes_into_iter_usize_result(b.clone().into_iter())?;\n   |                                  ^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`\n  --> tests/ui/useless_conversion.rs:453:41\n   |\nLL | fn takes_into_iter_usize_result(_: impl IntoIterator<Item = usize>) -> Result<(), ()> {\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider removing the `.into_iter()`\n   |\nLL -     takes_into_iter_usize_result(b.clone().into_iter())?;\nLL +     takes_into_iter_usize_result(b.clone())?;\n   |\n\nerror: aborting due to 48 previous errors\n\n"
  },
  {
    "path": "tests/ui/useless_conversion_try.rs",
    "content": "#![deny(clippy::useless_conversion)]\n#![allow(\n    clippy::needless_ifs,\n    clippy::unnecessary_fallible_conversions,\n    clippy::manual_unwrap_or_default\n)]\n\nfn test_generic<T: Copy>(val: T) -> T {\n    let _ = T::try_from(val).unwrap();\n    //~^ useless_conversion\n\n    val.try_into().unwrap()\n    //~^ useless_conversion\n}\n\nfn test_generic2<T: Copy + Into<i32> + Into<U>, U: From<T>>(val: T) {\n    // ok\n    let _: i32 = val.try_into().unwrap();\n    let _: U = val.try_into().unwrap();\n    let _ = U::try_from(val).unwrap();\n}\n\nfn main() {\n    test_generic(10i32);\n    test_generic2::<i32, i32>(10i32);\n\n    let _: String = \"foo\".try_into().unwrap();\n    let _: String = TryFrom::try_from(\"foo\").unwrap();\n    let _ = String::try_from(\"foo\").unwrap();\n    #[allow(clippy::useless_conversion)]\n    {\n        let _ = String::try_from(\"foo\").unwrap();\n        let _: String = \"foo\".try_into().unwrap();\n    }\n    let _: String = \"foo\".to_string().try_into().unwrap();\n    //~^ useless_conversion\n\n    let _: String = TryFrom::try_from(\"foo\".to_string()).unwrap();\n    //~^ useless_conversion\n\n    let _ = String::try_from(\"foo\".to_string()).unwrap();\n    //~^ useless_conversion\n\n    let _ = String::try_from(format!(\"A: {:04}\", 123)).unwrap();\n    //~^ useless_conversion\n\n    let _: String = format!(\"Hello {}\", \"world\").try_into().unwrap();\n    //~^ useless_conversion\n\n    let _: String = String::new().try_into().unwrap();\n    //~^ useless_conversion\n\n    let _: String = match String::from(\"_\").try_into() {\n        //~^ useless_conversion\n        Ok(a) => a,\n        Err(_) => String::new(),\n    };\n    // FIXME this is a false negative\n    #[allow(clippy::cmp_owned)]\n    if String::from(\"a\") == TryInto::<String>::try_into(String::from(\"a\")).unwrap() {}\n}\n"
  },
  {
    "path": "tests/ui/useless_conversion_try.stderr",
    "content": "error: useless conversion to the same type: `T`\n  --> tests/ui/useless_conversion_try.rs:9:13\n   |\nLL |     let _ = T::try_from(val).unwrap();\n   |             ^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing `T::try_from()`\nnote: the lint level is defined here\n  --> tests/ui/useless_conversion_try.rs:1:9\n   |\nLL | #![deny(clippy::useless_conversion)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: useless conversion to the same type: `T`\n  --> tests/ui/useless_conversion_try.rs:12:5\n   |\nLL |     val.try_into().unwrap()\n   |     ^^^^^^^^^^^^^^\n   |\n   = help: consider removing `.try_into()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion_try.rs:35:21\n   |\nLL |     let _: String = \"foo\".to_string().try_into().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing `.try_into()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion_try.rs:38:21\n   |\nLL |     let _: String = TryFrom::try_from(\"foo\".to_string()).unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing `TryFrom::try_from()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion_try.rs:41:13\n   |\nLL |     let _ = String::try_from(\"foo\".to_string()).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing `String::try_from()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion_try.rs:44:13\n   |\nLL |     let _ = String::try_from(format!(\"A: {:04}\", 123)).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing `String::try_from()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion_try.rs:47:21\n   |\nLL |     let _: String = format!(\"Hello {}\", \"world\").try_into().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing `.try_into()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion_try.rs:50:21\n   |\nLL |     let _: String = String::new().try_into().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing `.try_into()`\n\nerror: useless conversion to the same type: `std::string::String`\n  --> tests/ui/useless_conversion_try.rs:53:27\n   |\nLL |     let _: String = match String::from(\"_\").try_into() {\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing `.try_into()`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/useless_nonzero_new_unchecked.fixed",
    "content": "#![warn(clippy::useless_nonzero_new_unchecked)]\n\nuse std::num::{NonZero, NonZeroUsize};\n\n#[clippy::msrv = \"1.83\"]\nconst fn func() -> NonZeroUsize {\n    const { NonZeroUsize::new(3).unwrap() }\n    //~^ useless_nonzero_new_unchecked\n}\n\n#[clippy::msrv = \"1.82\"]\nconst fn func_older() -> NonZeroUsize {\n    unsafe { NonZeroUsize::new_unchecked(3) }\n}\n\nconst fn func_performance_hit_if_linted() -> NonZeroUsize {\n    unsafe { NonZeroUsize::new_unchecked(3) }\n}\n\nconst fn func_may_panic_at_run_time_if_linted(x: usize) -> NonZeroUsize {\n    unsafe { NonZeroUsize::new_unchecked(x) }\n}\n\nmacro_rules! uns {\n    ($expr:expr) => {\n        unsafe { $expr }\n    };\n}\n\nmacro_rules! nzu {\n    () => {\n        NonZeroUsize::new_unchecked(1)\n    };\n}\n\nfn main() {\n    const _A: NonZeroUsize = NonZeroUsize::new(3).unwrap();\n    //~^ useless_nonzero_new_unchecked\n\n    static _B: NonZero<u8> = NonZero::<u8>::new(42).unwrap();\n    //~^ useless_nonzero_new_unchecked\n\n    const _C: usize = unsafe { NonZeroUsize::new(3).unwrap().get() };\n    //~^ useless_nonzero_new_unchecked\n\n    const AUX: usize = 3;\n    const _D: NonZeroUsize = NonZeroUsize::new(AUX).unwrap();\n    //~^ useless_nonzero_new_unchecked\n\n    const _X: NonZeroUsize = uns!(NonZeroUsize::new_unchecked(3));\n    const _Y: NonZeroUsize = unsafe { nzu!() };\n}\n"
  },
  {
    "path": "tests/ui/useless_nonzero_new_unchecked.rs",
    "content": "#![warn(clippy::useless_nonzero_new_unchecked)]\n\nuse std::num::{NonZero, NonZeroUsize};\n\n#[clippy::msrv = \"1.83\"]\nconst fn func() -> NonZeroUsize {\n    const { unsafe { NonZeroUsize::new_unchecked(3) } }\n    //~^ useless_nonzero_new_unchecked\n}\n\n#[clippy::msrv = \"1.82\"]\nconst fn func_older() -> NonZeroUsize {\n    unsafe { NonZeroUsize::new_unchecked(3) }\n}\n\nconst fn func_performance_hit_if_linted() -> NonZeroUsize {\n    unsafe { NonZeroUsize::new_unchecked(3) }\n}\n\nconst fn func_may_panic_at_run_time_if_linted(x: usize) -> NonZeroUsize {\n    unsafe { NonZeroUsize::new_unchecked(x) }\n}\n\nmacro_rules! uns {\n    ($expr:expr) => {\n        unsafe { $expr }\n    };\n}\n\nmacro_rules! nzu {\n    () => {\n        NonZeroUsize::new_unchecked(1)\n    };\n}\n\nfn main() {\n    const _A: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };\n    //~^ useless_nonzero_new_unchecked\n\n    static _B: NonZero<u8> = unsafe { NonZero::<u8>::new_unchecked(42) };\n    //~^ useless_nonzero_new_unchecked\n\n    const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() };\n    //~^ useless_nonzero_new_unchecked\n\n    const AUX: usize = 3;\n    const _D: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(AUX) };\n    //~^ useless_nonzero_new_unchecked\n\n    const _X: NonZeroUsize = uns!(NonZeroUsize::new_unchecked(3));\n    const _Y: NonZeroUsize = unsafe { nzu!() };\n}\n"
  },
  {
    "path": "tests/ui/useless_nonzero_new_unchecked.stderr",
    "content": "error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context\n  --> tests/ui/useless_nonzero_new_unchecked.rs:7:13\n   |\nLL |     const { unsafe { NonZeroUsize::new_unchecked(3) } }\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()`\n   |\n   = note: `-D clippy::useless-nonzero-new-unchecked` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_nonzero_new_unchecked)]`\n\nerror: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context\n  --> tests/ui/useless_nonzero_new_unchecked.rs:37:30\n   |\nLL |     const _A: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()`\n\nerror: `NonZero::<u8>::new()` and `Option::unwrap()` can be safely used in a `const` context\n  --> tests/ui/useless_nonzero_new_unchecked.rs:40:30\n   |\nLL |     static _B: NonZero<u8> = unsafe { NonZero::<u8>::new_unchecked(42) };\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZero::<u8>::new(42).unwrap()`\n\nerror: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context\n  --> tests/ui/useless_nonzero_new_unchecked.rs:43:32\n   |\nLL |     const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() };\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()`\n   |\n   = note: the fixed expression does not require an `unsafe` context\n\nerror: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context\n  --> tests/ui/useless_nonzero_new_unchecked.rs:47:30\n   |\nLL |     const _D: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(AUX) };\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(AUX).unwrap()`\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui/useless_vec.fixed",
    "content": "#![warn(clippy::useless_vec)]\n\nuse std::rc::Rc;\n\nstruct StructWithVec {\n    _x: Vec<i32>,\n}\n\nfn on_slice(_: &[u8]) {}\n\nfn on_mut_slice(_: &mut [u8]) {}\n\n#[allow(clippy::ptr_arg)]\nfn on_vec(_: &Vec<u8>) {}\n\nfn on_mut_vec(_: &mut Vec<u8>) {}\n\nstruct Line {\n    length: usize,\n}\n\nimpl Line {\n    fn length(&self) -> usize {\n        self.length\n    }\n}\n\nfn main() {\n    on_slice(&[]);\n    //~^ useless_vec\n    on_slice(&[]);\n    on_mut_slice(&mut []);\n    //~^ useless_vec\n\n    on_slice(&[1, 2]);\n    //~^ useless_vec\n    on_slice(&[1, 2]);\n    on_mut_slice(&mut [1, 2]);\n    //~^ useless_vec\n\n    #[rustfmt::skip]\n    #[allow(clippy::nonstandard_macro_braces)] // not an `expect` as it will only lint _before_ the fix\n    {\n        on_slice(&[1, 2]);\n        //~^ useless_vec\n        on_mut_slice(&mut [1, 2]);\n        //~^ useless_vec\n    };\n\n    on_slice(&[1; 2]);\n    //~^ useless_vec\n    on_slice(&[1; 2]);\n    on_mut_slice(&mut [1; 2]);\n    //~^ useless_vec\n\n    on_vec(&vec![]);\n    on_vec(&vec![1, 2]);\n    on_vec(&vec![1; 2]);\n    on_mut_vec(&mut vec![]);\n    on_mut_vec(&mut vec![1, 2]);\n    on_mut_vec(&mut vec![1; 2]);\n\n    // Now with non-constant expressions\n    let line = Line { length: 2 };\n\n    on_slice(&vec![2; line.length]);\n    on_slice(&vec![2; line.length()]);\n    on_mut_slice(&mut vec![2; line.length]);\n    on_mut_slice(&mut vec![2; line.length()]);\n\n    on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack`\n    on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack`\n\n    // Ok, size of `vec` higher than `too_large_for_stack`\n    for a in vec![1; 201] {\n        println!(\"{a:?}\");\n    }\n\n    // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246\n    let _x: i32 = [1, 2, 3].iter().sum();\n    //~^ useless_vec\n\n    // Do lint, only used as slice\n    {\n        let mut x = [1, 2, 3];\n        //~^ useless_vec\n        x.fill(123);\n        dbg!(x[0]);\n        dbg!(x.len());\n        dbg!(x.iter().sum::<i32>());\n    }\n\n    let _x: &[i32] = &[1, 2, 3];\n    //~^ useless_vec\n\n    for _ in [1, 2, 3] {}\n    //~^ useless_vec\n\n    // Don't lint\n    let x = vec![1, 2, 3];\n    let _v: Vec<i32> = x;\n\n    let x = vec![1, 2, 3];\n    let _s = StructWithVec { _x: x };\n\n    // Explicit type annotation would make the change to [1, 2, 3]\n    // a compile error.\n    let _x: Vec<i32> = vec![1, 2, 3];\n\n    // Calling a Vec method through a mutable reference\n    let mut x = vec![1, 2, 3];\n    let re = &mut x;\n    re.push(4);\n\n    // Comparing arrays whose length is not equal is a compile error\n    let x = vec![1, 2, 3];\n    let y = vec![1, 2, 3, 4];\n    dbg!(x == y);\n\n    // Non-copy types\n    let _x = vec![String::new(); 10];\n    #[allow(clippy::rc_clone_in_vec_init)]\n    let _x = vec![Rc::new(1); 10];\n\n    // Too large\n    let _x = vec![1; 201];\n}\n\nfn issue11075() {\n    macro_rules! repro {\n        ($e:expr) => {\n            stringify!($e)\n        };\n    }\n    #[allow(clippy::never_loop)]\n    for _string in [repro!(true), repro!(null)] {\n        //~^ useless_vec\n        unimplemented!();\n    }\n\n    macro_rules! in_macro {\n        ($e:expr, $vec:expr, $vec2:expr) => {{\n            vec![1; 2].fill(3);\n            vec![1, 2].fill(3);\n            for _ in vec![1, 2] {}\n            for _ in vec![1; 2] {}\n            for _ in vec![$e, $e] {}\n            for _ in vec![$e; 2] {}\n            for _ in $vec {}\n            for _ in $vec2 {}\n        }};\n    }\n\n    in_macro!(1, [1, 2], [1; 2]);\n    //~^ useless_vec\n    //~| useless_vec\n\n    macro_rules! from_macro {\n        () => {\n            vec![1, 2, 3]\n        };\n    }\n    macro_rules! from_macro_repeat {\n        () => {\n            vec![1; 3]\n        };\n    }\n\n    for _ in from_macro!() {}\n    for _ in from_macro_repeat!() {}\n}\n\n#[clippy::msrv = \"1.53\"]\nfn above() {\n    for a in [1, 2, 3] {\n        //~^ useless_vec\n        let _: usize = a;\n    }\n\n    for a in [String::new(), String::new()] {\n        //~^ useless_vec\n        let _: String = a;\n    }\n}\n\n#[clippy::msrv = \"1.52\"]\nfn below() {\n    for a in vec![1, 2, 3] {\n        let _: usize = a;\n    }\n\n    for a in vec![String::new(), String::new()] {\n        let _: String = a;\n    }\n}\n\nfn func_needing_vec(_bar: usize, _baz: Vec<usize>) {}\nfn func_not_needing_vec(_bar: usize, _baz: usize) {}\n\nfn issue11861() {\n    macro_rules! this_macro_needs_vec {\n        ($x:expr) => {{\n            func_needing_vec($x.iter().sum(), $x);\n            for _ in $x {}\n        }};\n    }\n    macro_rules! this_macro_doesnt_need_vec {\n        ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }};\n    }\n\n    // Do not lint the next line\n    this_macro_needs_vec!(vec![1]);\n    this_macro_doesnt_need_vec!([1]);\n    //~^ useless_vec\n\n    macro_rules! m {\n        ($x:expr) => {\n            fn f2() {\n                let _x: Vec<i32> = $x;\n            }\n            fn f() {\n                let _x = $x;\n                $x.starts_with(&[]);\n            }\n        };\n    }\n\n    // should not lint\n    m!(vec![1]);\n}\n\nfn issue_11958() {\n    fn f(_s: &[String]) {}\n\n    // should not lint, `String` is not `Copy`\n    f(&vec![\"test\".to_owned(); 2]);\n}\n\nfn issue_12101() {\n    for a in &[1, 2] {}\n    //~^ useless_vec\n}\n\nfn issue_14531() {\n    // The lint used to suggest using an array rather than a reference to a slice.\n\n    fn requires_ref_slice(v: &[()]) {}\n    let v = &[];\n    //~^ useless_vec\n    requires_ref_slice(v);\n}\n"
  },
  {
    "path": "tests/ui/useless_vec.rs",
    "content": "#![warn(clippy::useless_vec)]\n\nuse std::rc::Rc;\n\nstruct StructWithVec {\n    _x: Vec<i32>,\n}\n\nfn on_slice(_: &[u8]) {}\n\nfn on_mut_slice(_: &mut [u8]) {}\n\n#[allow(clippy::ptr_arg)]\nfn on_vec(_: &Vec<u8>) {}\n\nfn on_mut_vec(_: &mut Vec<u8>) {}\n\nstruct Line {\n    length: usize,\n}\n\nimpl Line {\n    fn length(&self) -> usize {\n        self.length\n    }\n}\n\nfn main() {\n    on_slice(&vec![]);\n    //~^ useless_vec\n    on_slice(&[]);\n    on_mut_slice(&mut vec![]);\n    //~^ useless_vec\n\n    on_slice(&vec![1, 2]);\n    //~^ useless_vec\n    on_slice(&[1, 2]);\n    on_mut_slice(&mut vec![1, 2]);\n    //~^ useless_vec\n\n    #[rustfmt::skip]\n    #[allow(clippy::nonstandard_macro_braces)] // not an `expect` as it will only lint _before_ the fix\n    {\n        on_slice(&vec!(1, 2));\n        //~^ useless_vec\n        on_mut_slice(&mut vec!(1, 2));\n        //~^ useless_vec\n    };\n\n    on_slice(&vec![1; 2]);\n    //~^ useless_vec\n    on_slice(&[1; 2]);\n    on_mut_slice(&mut vec![1; 2]);\n    //~^ useless_vec\n\n    on_vec(&vec![]);\n    on_vec(&vec![1, 2]);\n    on_vec(&vec![1; 2]);\n    on_mut_vec(&mut vec![]);\n    on_mut_vec(&mut vec![1, 2]);\n    on_mut_vec(&mut vec![1; 2]);\n\n    // Now with non-constant expressions\n    let line = Line { length: 2 };\n\n    on_slice(&vec![2; line.length]);\n    on_slice(&vec![2; line.length()]);\n    on_mut_slice(&mut vec![2; line.length]);\n    on_mut_slice(&mut vec![2; line.length()]);\n\n    on_vec(&vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack`\n    on_mut_vec(&mut vec![1; 201]); // Ok, size of `vec` higher than `too_large_for_stack`\n\n    // Ok, size of `vec` higher than `too_large_for_stack`\n    for a in vec![1; 201] {\n        println!(\"{a:?}\");\n    }\n\n    // https://github.com/rust-lang/rust-clippy/issues/2262#issuecomment-783979246\n    let _x: i32 = vec![1, 2, 3].iter().sum();\n    //~^ useless_vec\n\n    // Do lint, only used as slice\n    {\n        let mut x = vec![1, 2, 3];\n        //~^ useless_vec\n        x.fill(123);\n        dbg!(x[0]);\n        dbg!(x.len());\n        dbg!(x.iter().sum::<i32>());\n    }\n\n    let _x: &[i32] = &vec![1, 2, 3];\n    //~^ useless_vec\n\n    for _ in vec![1, 2, 3] {}\n    //~^ useless_vec\n\n    // Don't lint\n    let x = vec![1, 2, 3];\n    let _v: Vec<i32> = x;\n\n    let x = vec![1, 2, 3];\n    let _s = StructWithVec { _x: x };\n\n    // Explicit type annotation would make the change to [1, 2, 3]\n    // a compile error.\n    let _x: Vec<i32> = vec![1, 2, 3];\n\n    // Calling a Vec method through a mutable reference\n    let mut x = vec![1, 2, 3];\n    let re = &mut x;\n    re.push(4);\n\n    // Comparing arrays whose length is not equal is a compile error\n    let x = vec![1, 2, 3];\n    let y = vec![1, 2, 3, 4];\n    dbg!(x == y);\n\n    // Non-copy types\n    let _x = vec![String::new(); 10];\n    #[allow(clippy::rc_clone_in_vec_init)]\n    let _x = vec![Rc::new(1); 10];\n\n    // Too large\n    let _x = vec![1; 201];\n}\n\nfn issue11075() {\n    macro_rules! repro {\n        ($e:expr) => {\n            stringify!($e)\n        };\n    }\n    #[allow(clippy::never_loop)]\n    for _string in vec![repro!(true), repro!(null)] {\n        //~^ useless_vec\n        unimplemented!();\n    }\n\n    macro_rules! in_macro {\n        ($e:expr, $vec:expr, $vec2:expr) => {{\n            vec![1; 2].fill(3);\n            vec![1, 2].fill(3);\n            for _ in vec![1, 2] {}\n            for _ in vec![1; 2] {}\n            for _ in vec![$e, $e] {}\n            for _ in vec![$e; 2] {}\n            for _ in $vec {}\n            for _ in $vec2 {}\n        }};\n    }\n\n    in_macro!(1, vec![1, 2], vec![1; 2]);\n    //~^ useless_vec\n    //~| useless_vec\n\n    macro_rules! from_macro {\n        () => {\n            vec![1, 2, 3]\n        };\n    }\n    macro_rules! from_macro_repeat {\n        () => {\n            vec![1; 3]\n        };\n    }\n\n    for _ in from_macro!() {}\n    for _ in from_macro_repeat!() {}\n}\n\n#[clippy::msrv = \"1.53\"]\nfn above() {\n    for a in vec![1, 2, 3] {\n        //~^ useless_vec\n        let _: usize = a;\n    }\n\n    for a in vec![String::new(), String::new()] {\n        //~^ useless_vec\n        let _: String = a;\n    }\n}\n\n#[clippy::msrv = \"1.52\"]\nfn below() {\n    for a in vec![1, 2, 3] {\n        let _: usize = a;\n    }\n\n    for a in vec![String::new(), String::new()] {\n        let _: String = a;\n    }\n}\n\nfn func_needing_vec(_bar: usize, _baz: Vec<usize>) {}\nfn func_not_needing_vec(_bar: usize, _baz: usize) {}\n\nfn issue11861() {\n    macro_rules! this_macro_needs_vec {\n        ($x:expr) => {{\n            func_needing_vec($x.iter().sum(), $x);\n            for _ in $x {}\n        }};\n    }\n    macro_rules! this_macro_doesnt_need_vec {\n        ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }};\n    }\n\n    // Do not lint the next line\n    this_macro_needs_vec!(vec![1]);\n    this_macro_doesnt_need_vec!(vec![1]);\n    //~^ useless_vec\n\n    macro_rules! m {\n        ($x:expr) => {\n            fn f2() {\n                let _x: Vec<i32> = $x;\n            }\n            fn f() {\n                let _x = $x;\n                $x.starts_with(&[]);\n            }\n        };\n    }\n\n    // should not lint\n    m!(vec![1]);\n}\n\nfn issue_11958() {\n    fn f(_s: &[String]) {}\n\n    // should not lint, `String` is not `Copy`\n    f(&vec![\"test\".to_owned(); 2]);\n}\n\nfn issue_12101() {\n    for a in &(vec![1, 2]) {}\n    //~^ useless_vec\n}\n\nfn issue_14531() {\n    // The lint used to suggest using an array rather than a reference to a slice.\n\n    fn requires_ref_slice(v: &[()]) {}\n    let v = &vec![];\n    //~^ useless_vec\n    requires_ref_slice(v);\n}\n"
  },
  {
    "path": "tests/ui/useless_vec.stderr",
    "content": "error: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:29:14\n   |\nLL |     on_slice(&vec![]);\n   |              ^^^^^^^ help: you can use a slice directly: `&[]`\n   |\n   = note: `-D clippy::useless-vec` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:32:18\n   |\nLL |     on_mut_slice(&mut vec![]);\n   |                  ^^^^^^^^^^^ help: you can use a slice directly: `&mut []`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:35:14\n   |\nLL |     on_slice(&vec![1, 2]);\n   |              ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:38:18\n   |\nLL |     on_mut_slice(&mut vec![1, 2]);\n   |                  ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:44:18\n   |\nLL |         on_slice(&vec!(1, 2));\n   |                  ^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:46:22\n   |\nLL |         on_mut_slice(&mut vec!(1, 2));\n   |                      ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1, 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:50:14\n   |\nLL |     on_slice(&vec![1; 2]);\n   |              ^^^^^^^^^^^ help: you can use a slice directly: `&[1; 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:53:18\n   |\nLL |     on_mut_slice(&mut vec![1; 2]);\n   |                  ^^^^^^^^^^^^^^^ help: you can use a slice directly: `&mut [1; 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:80:19\n   |\nLL |     let _x: i32 = vec![1, 2, 3].iter().sum();\n   |                   ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:85:21\n   |\nLL |         let mut x = vec![1, 2, 3];\n   |                     ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:93:22\n   |\nLL |     let _x: &[i32] = &vec![1, 2, 3];\n   |                      ^^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2, 3]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:96:14\n   |\nLL |     for _ in vec![1, 2, 3] {}\n   |              ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:136:20\n   |\nLL |     for _string in vec![repro!(true), repro!(null)] {\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[repro!(true), repro!(null)]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:154:18\n   |\nLL |     in_macro!(1, vec![1, 2], vec![1; 2]);\n   |                  ^^^^^^^^^^ help: you can use an array directly: `[1, 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:154:30\n   |\nLL |     in_macro!(1, vec![1, 2], vec![1; 2]);\n   |                              ^^^^^^^^^^ help: you can use an array directly: `[1; 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:175:14\n   |\nLL |     for a in vec![1, 2, 3] {\n   |              ^^^^^^^^^^^^^ help: you can use an array directly: `[1, 2, 3]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:180:14\n   |\nLL |     for a in vec![String::new(), String::new()] {\n   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:213:33\n   |\nLL |     this_macro_doesnt_need_vec!(vec![1]);\n   |                                 ^^^^^^^ help: you can use an array directly: `[1]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:240:14\n   |\nLL |     for a in &(vec![1, 2]) {}\n   |              ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`\n\nerror: useless use of `vec!`\n  --> tests/ui/useless_vec.rs:248:13\n   |\nLL |     let v = &vec![];\n   |             ^^^^^^^ help: you can use a slice directly: `&[]`\n\nerror: aborting due to 20 previous errors\n\n"
  },
  {
    "path": "tests/ui/useless_vec_unfixable.rs",
    "content": "//@no-rustfix: no suggestions\n#![warn(clippy::useless_vec)]\n\n// Regression test for <https://github.com/rust-lang/rust-clippy/issues/13692>.\nfn foo() {\n    // There should be no suggestion in this case.\n    let _some_variable = vec![\n        //~^ useless_vec\n        1, 2, // i'm here to stay\n        3, 4, // but this one going away ;-;\n    ]; // that is life anyways\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/useless_vec_unfixable.stderr",
    "content": "error: useless use of `vec!`\n  --> tests/ui/useless_vec_unfixable.rs:7:26\n   |\nLL |       let _some_variable = vec![\n   |  __________________________^\nLL | |\nLL | |         1, 2, // i'm here to stay\nLL | |         3, 4, // but this one going away ;-;\nLL | |     ]; // that is life anyways\n   | |_____^\n   |\n   = note: `-D clippy::useless-vec` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`\nhelp: you can use an array directly\n   |\nLL ~     let _some_variable = [1, 2, // i'm here to stay\nLL ~         3, 4]; // that is life anyways\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/vec_box_sized.rs",
    "content": "//@no-rustfix\n\n#![allow(dead_code)]\n#![feature(allocator_api)]\n\nuse std::alloc::{AllocError, Allocator, Layout};\nuse std::ptr::NonNull;\n\nstruct SizedStruct(i32);\nstruct UnsizedStruct([i32]);\nstruct BigStruct([i32; 10000]);\n\nstruct DummyAllocator;\nunsafe impl Allocator for DummyAllocator {\n    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {\n        todo!()\n    }\n    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {\n        todo!()\n    }\n}\n\n/// The following should trigger the lint\nmod should_trigger {\n    use super::{DummyAllocator, SizedStruct};\n    const C: Vec<Box<i32>> = Vec::new();\n    //~^ vec_box\n    static S: Vec<Box<i32>> = Vec::new();\n    //~^ vec_box\n\n    struct StructWithVecBox {\n        sized_type: Vec<Box<SizedStruct>>,\n        //~^ vec_box\n    }\n\n    struct A(Vec<Box<SizedStruct>>);\n    //~^ vec_box\n    struct B(Vec<Vec<Box<(u32)>>>);\n    //~^ vec_box\n\n    fn allocator_global_defined_vec() -> Vec<Box<i32>, std::alloc::Global> {\n        //~^ vec_box\n        Vec::new()\n    }\n    fn allocator_global_defined_box() -> Vec<Box<i32, std::alloc::Global>> {\n        //~^ vec_box\n        Vec::new()\n    }\n    fn allocator_match() -> Vec<Box<i32, DummyAllocator>, DummyAllocator> {\n        //~^ vec_box\n        Vec::new_in(DummyAllocator)\n    }\n}\n\n/// The following should not trigger the lint\nmod should_not_trigger {\n    use super::{BigStruct, DummyAllocator, UnsizedStruct};\n\n    struct C(Vec<Box<UnsizedStruct>>);\n    struct D(Vec<Box<BigStruct>>);\n\n    struct StructWithVecBoxButItsUnsized {\n        unsized_type: Vec<Box<UnsizedStruct>>,\n    }\n\n    struct TraitVec<T: ?Sized> {\n        // Regression test for #3720. This was causing an ICE.\n        inner: Vec<Box<T>>,\n    }\n\n    fn allocator_mismatch() -> Vec<Box<i32, DummyAllocator>> {\n        Vec::new()\n    }\n    fn allocator_mismatch_2() -> Vec<Box<i32>, DummyAllocator> {\n        Vec::new_in(DummyAllocator)\n    }\n}\n\nmod inner_mod {\n    mod inner {\n        pub struct S;\n    }\n\n    mod inner2 {\n        use super::inner::S;\n\n        pub fn f() -> Vec<Box<S>> {\n            //~^ vec_box\n            vec![]\n        }\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/issues/11417\nfn in_closure() {\n    let _ = |_: Vec<Box<dyn ToString>>| {};\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/vec_box_sized.stderr",
    "content": "error: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:26:14\n   |\nLL |     const C: Vec<Box<i32>> = Vec::new();\n   |              ^^^^^^^^^^^^^ help: try: `Vec<i32>`\n   |\n   = note: `-D clippy::vec-box` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::vec_box)]`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:28:15\n   |\nLL |     static S: Vec<Box<i32>> = Vec::new();\n   |               ^^^^^^^^^^^^^ help: try: `Vec<i32>`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:32:21\n   |\nLL |         sized_type: Vec<Box<SizedStruct>>,\n   |                     ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<SizedStruct>`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:36:14\n   |\nLL |     struct A(Vec<Box<SizedStruct>>);\n   |              ^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<SizedStruct>`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:38:18\n   |\nLL |     struct B(Vec<Vec<Box<(u32)>>>);\n   |                  ^^^^^^^^^^^^^^^ help: try: `Vec<u32>`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:41:42\n   |\nLL |     fn allocator_global_defined_vec() -> Vec<Box<i32>, std::alloc::Global> {\n   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<i32>`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:45:42\n   |\nLL |     fn allocator_global_defined_box() -> Vec<Box<i32, std::alloc::Global>> {\n   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<i32>`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:49:29\n   |\nLL |     fn allocator_match() -> Vec<Box<i32, DummyAllocator>, DummyAllocator> {\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Vec<i32>`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui/vec_box_sized.rs:87:23\n   |\nLL |         pub fn f() -> Vec<Box<S>> {\n   |                       ^^^^^^^^^^^ help: try: `Vec<S>`\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/vec_init_then_push.rs",
    "content": "#![allow(unused_variables)]\n#![warn(clippy::vec_init_then_push)]\n//@no-rustfix\nfn main() {\n    let mut def_err: Vec<u32> = Default::default();\n    //~^ vec_init_then_push\n\n    def_err.push(0);\n\n    let mut new_err = Vec::<u32>::new();\n    //~^ vec_init_then_push\n\n    new_err.push(1);\n\n    let mut cap_err = Vec::with_capacity(2);\n    //~^ vec_init_then_push\n\n    cap_err.push(0);\n    cap_err.push(1);\n    cap_err.push(2);\n    if true {\n        // don't include this one\n        cap_err.push(3);\n    }\n\n    let mut cap_ok = Vec::with_capacity(10);\n    cap_ok.push(0);\n\n    new_err = Vec::new();\n    //~^ vec_init_then_push\n\n    new_err.push(0);\n\n    let mut vec = Vec::new();\n    // control flow at block final expression\n    if true {\n        // no lint\n        vec.push(1);\n    }\n\n    let mut vec = Vec::with_capacity(5);\n    vec.push(1);\n    vec.push(2);\n    vec.push(3);\n    vec.push(4);\n}\n\npub fn no_lint() -> Vec<i32> {\n    let mut p = Some(1);\n    let mut vec = Vec::new();\n    loop {\n        match p {\n            None => return vec,\n            Some(i) => {\n                vec.push(i);\n                p = None;\n            },\n        }\n    }\n}\n\nfn _from_iter(items: impl Iterator<Item = u32>) -> Vec<u32> {\n    let mut v = Vec::new();\n    v.push(0);\n    v.push(1);\n    v.extend(items);\n    v\n}\n\nfn _cond_push(x: bool) -> Vec<u32> {\n    let mut v = Vec::new();\n    v.push(0);\n    if x {\n        v.push(1);\n    }\n    v.push(2);\n    v\n}\n\nfn _push_then_edit(x: u32) -> Vec<u32> {\n    let mut v = Vec::new();\n    //~^ vec_init_then_push\n\n    v.push(x);\n    v.push(1);\n    v[0] = v[1] + 5;\n    v\n}\n\nfn _cond_push_with_large_start(x: bool) -> Vec<u32> {\n    let mut v = Vec::new();\n    //~^ vec_init_then_push\n\n    v.push(0);\n    v.push(1);\n    v.push(0);\n    v.push(1);\n    v.push(0);\n    v.push(0);\n    v.push(1);\n    v.push(0);\n    if x {\n        v.push(1);\n    }\n\n    let mut v2 = Vec::new();\n    //~^ vec_init_then_push\n\n    v2.push(0);\n    v2.push(1);\n    v2.push(0);\n    v2.push(1);\n    v2.push(0);\n    v2.push(0);\n    v2.push(1);\n    v2.push(0);\n    v2.extend(&v);\n\n    v2\n}\n\nfn f() {\n    let mut v = Vec::new();\n    //~^ vec_init_then_push\n\n    v.push((0i32, 0i32));\n    let y = v[0].0.abs();\n}\n"
  },
  {
    "path": "tests/ui/vec_init_then_push.stderr",
    "content": "error: calls to `push` immediately after creation\n  --> tests/ui/vec_init_then_push.rs:5:5\n   |\nLL | /     let mut def_err: Vec<u32> = Default::default();\n...  |\nLL | |     def_err.push(0);\n   | |____________________^ help: consider using the `vec![]` macro: `let def_err: Vec<u32> = vec![..];`\n   |\n   = note: `-D clippy::vec-init-then-push` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::vec_init_then_push)]`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/vec_init_then_push.rs:10:5\n   |\nLL | /     let mut new_err = Vec::<u32>::new();\n...  |\nLL | |     new_err.push(1);\n   | |____________________^ help: consider using the `vec![]` macro: `let mut new_err = vec![..];`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/vec_init_then_push.rs:15:5\n   |\nLL | /     let mut cap_err = Vec::with_capacity(2);\nLL | |\nLL | |\nLL | |     cap_err.push(0);\nLL | |     cap_err.push(1);\nLL | |     cap_err.push(2);\n   | |____________________^ help: consider using the `vec![]` macro: `let mut cap_err = vec![..];`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/vec_init_then_push.rs:29:5\n   |\nLL | /     new_err = Vec::new();\n...  |\nLL | |     new_err.push(0);\n   | |____________________^ help: consider using the `vec![]` macro: `new_err = vec![..];`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/vec_init_then_push.rs:81:5\n   |\nLL | /     let mut v = Vec::new();\nLL | |\nLL | |\nLL | |     v.push(x);\nLL | |     v.push(1);\n   | |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/vec_init_then_push.rs:91:5\n   |\nLL | /     let mut v = Vec::new();\nLL | |\nLL | |\nLL | |     v.push(0);\n...  |\nLL | |     v.push(1);\nLL | |     v.push(0);\n   | |______________^ help: consider using the `vec![]` macro: `let mut v = vec![..];`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/vec_init_then_push.rs:106:5\n   |\nLL | /     let mut v2 = Vec::new();\nLL | |\nLL | |\nLL | |     v2.push(0);\n...  |\nLL | |     v2.push(1);\nLL | |     v2.push(0);\n   | |_______________^ help: consider using the `vec![]` macro: `let mut v2 = vec![..];`\n\nerror: calls to `push` immediately after creation\n  --> tests/ui/vec_init_then_push.rs:123:5\n   |\nLL | /     let mut v = Vec::new();\n...  |\nLL | |     v.push((0i32, 0i32));\n   | |_________________________^ help: consider using the `vec![]` macro: `let v = vec![..];`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/vec_resize_to_zero.fixed",
    "content": "#![warn(clippy::vec_resize_to_zero)]\n\nfn main() {\n    let mut v = vec![1, 2, 3, 4, 5];\n\n    // applicable here\n    v.clear();\n    //~^ vec_resize_to_zero\n\n    // not applicable\n    v.resize(2, 5);\n\n    let mut v = vec![\"foo\", \"bar\", \"baz\"];\n\n    // applicable here, but only implemented for integer literals for now\n    v.resize(0, \"bar\");\n\n    // not applicable\n    v.resize(2, \"bar\")\n}\n"
  },
  {
    "path": "tests/ui/vec_resize_to_zero.rs",
    "content": "#![warn(clippy::vec_resize_to_zero)]\n\nfn main() {\n    let mut v = vec![1, 2, 3, 4, 5];\n\n    // applicable here\n    v.resize(0, 5);\n    //~^ vec_resize_to_zero\n\n    // not applicable\n    v.resize(2, 5);\n\n    let mut v = vec![\"foo\", \"bar\", \"baz\"];\n\n    // applicable here, but only implemented for integer literals for now\n    v.resize(0, \"bar\");\n\n    // not applicable\n    v.resize(2, \"bar\")\n}\n"
  },
  {
    "path": "tests/ui/vec_resize_to_zero.stderr",
    "content": "error: emptying a vector with `resize`\n  --> tests/ui/vec_resize_to_zero.rs:7:5\n   |\nLL |     v.resize(0, 5);\n   |     ^^------------\n   |       |\n   |       help: ...or you can empty the vector with: `clear()`\n   |\n   = help: the arguments may be inverted...\n   = note: `-D clippy::vec-resize-to-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::vec_resize_to_zero)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/verbose_file_reads.rs",
    "content": "#![warn(clippy::verbose_file_reads)]\nuse std::env::temp_dir;\nuse std::fs::File;\nuse std::io::Read;\n\nstruct Struct;\n// To make sure we only warn on File::{read_to_end, read_to_string} calls\nimpl Struct {\n    pub fn read_to_end(&self) {}\n\n    pub fn read_to_string(&self) {}\n}\n\nfn main() -> std::io::Result<()> {\n    let path = \"foo.txt\";\n    // Lint shouldn't catch this\n    let s = Struct;\n    s.read_to_end();\n    s.read_to_string();\n    // Should catch this\n    let mut f = File::open(path)?;\n    let mut buffer = Vec::new();\n    f.read_to_end(&mut buffer)?;\n    //~^ verbose_file_reads\n\n    // ...and this\n    let mut string_buffer = String::new();\n    f.read_to_string(&mut string_buffer)?;\n    //~^ verbose_file_reads\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/ui/verbose_file_reads.stderr",
    "content": "error: use of `File::read_to_end`\n  --> tests/ui/verbose_file_reads.rs:23:5\n   |\nLL |     f.read_to_end(&mut buffer)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `fs::read` instead\n   = note: `-D clippy::verbose-file-reads` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::verbose_file_reads)]`\n\nerror: use of `File::read_to_string`\n  --> tests/ui/verbose_file_reads.rs:28:5\n   |\nLL |     f.read_to_string(&mut string_buffer)?;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `fs::read_to_string` instead\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/volatile_composites.rs",
    "content": "#![feature(ptr_metadata)]\n#![feature(portable_simd)]\n#![warn(clippy::volatile_composites)]\n\nuse std::ptr::null_mut;\n\n#[repr(C)]\n#[derive(Copy, Clone, Default)]\nstruct MyDevRegisters {\n    baseaddr: usize,\n    count: usize,\n}\n\n#[repr(transparent)]\nstruct Wrapper<T>((), T, ());\n\n// Not to be confused with std::ptr::NonNull\nstruct NonNull<T>(T);\n\nimpl<T> NonNull<T> {\n    fn write_volatile(&self, _arg: &T) {\n        unimplemented!(\"Something entirely unrelated to std::ptr::NonNull\");\n    }\n}\n\nfn main() {\n    let regs = MyDevRegisters {\n        baseaddr: 0xabc123,\n        count: 42,\n    };\n\n    const DEVICE_ADDR: *mut MyDevRegisters = 0xdead as *mut _;\n\n    // Raw pointer methods\n    unsafe {\n        (&raw mut (*DEVICE_ADDR).baseaddr).write_volatile(regs.baseaddr); // OK\n        (&raw mut (*DEVICE_ADDR).count).write_volatile(regs.count); // OK\n\n        DEVICE_ADDR.write_volatile(regs);\n        //~^ volatile_composites\n\n        let _regs = MyDevRegisters {\n            baseaddr: (&raw const (*DEVICE_ADDR).baseaddr).read_volatile(), // OK\n            count: (&raw const (*DEVICE_ADDR).count).read_volatile(),       // OK\n        };\n\n        let _regs = DEVICE_ADDR.read_volatile();\n        //~^ volatile_composites\n    }\n\n    // std::ptr functions\n    unsafe {\n        std::ptr::write_volatile(&raw mut (*DEVICE_ADDR).baseaddr, regs.baseaddr); // OK\n        std::ptr::write_volatile(&raw mut (*DEVICE_ADDR).count, regs.count); // OK\n\n        std::ptr::write_volatile(DEVICE_ADDR, regs);\n        //~^ volatile_composites\n\n        let _regs = MyDevRegisters {\n            baseaddr: std::ptr::read_volatile(&raw const (*DEVICE_ADDR).baseaddr), // OK\n            count: std::ptr::read_volatile(&raw const (*DEVICE_ADDR).count),       // OK\n        };\n\n        let _regs = std::ptr::read_volatile(DEVICE_ADDR);\n        //~^ volatile_composites\n    }\n\n    // core::ptr functions\n    unsafe {\n        core::ptr::write_volatile(&raw mut (*DEVICE_ADDR).baseaddr, regs.baseaddr); // OK\n        core::ptr::write_volatile(&raw mut (*DEVICE_ADDR).count, regs.count); // OK\n\n        core::ptr::write_volatile(DEVICE_ADDR, regs);\n        //~^ volatile_composites\n\n        let _regs = MyDevRegisters {\n            baseaddr: core::ptr::read_volatile(&raw const (*DEVICE_ADDR).baseaddr), // OK\n            count: core::ptr::read_volatile(&raw const (*DEVICE_ADDR).count),       // OK\n        };\n\n        let _regs = core::ptr::read_volatile(DEVICE_ADDR);\n        //~^ volatile_composites\n    }\n\n    // std::ptr::NonNull\n    unsafe {\n        let ptr = std::ptr::NonNull::new(DEVICE_ADDR).unwrap();\n\n        ptr.write_volatile(regs);\n        //~^ volatile_composites\n\n        let _regs = ptr.read_volatile();\n        //~^ volatile_composites\n    }\n\n    // Red herring\n    {\n        let thing = NonNull(\"hello\".to_string());\n\n        thing.write_volatile(&\"goodbye\".into()); // OK\n    }\n\n    // Zero size types OK\n    unsafe {\n        struct Empty;\n\n        (0xdead as *mut Empty).write_volatile(Empty); // OK\n        // Note that this is OK because Wrapper<Empty> is itself ZST, not because of the repr transparent\n        // handling tested below.\n        (0xdead as *mut Wrapper<Empty>).write_volatile(Wrapper((), Empty, ())); // OK\n    }\n\n    // Via repr transparent newtype\n    unsafe {\n        (0xdead as *mut Wrapper<usize>).write_volatile(Wrapper((), 123, ())); // OK\n        (0xdead as *mut Wrapper<Wrapper<usize>>).write_volatile(Wrapper((), Wrapper((), 123, ()), ())); // OK\n\n        (0xdead as *mut Wrapper<MyDevRegisters>).write_volatile(Wrapper((), MyDevRegisters::default(), ()));\n        //~^ volatile_composites\n    }\n\n    // Plain type alias OK\n    unsafe {\n        type MyU64 = u64;\n\n        (0xdead as *mut MyU64).write_volatile(123); // OK\n    }\n\n    // Wide pointers are not OK as data\n    unsafe {\n        let things: &[u32] = &[1, 2, 3];\n\n        (0xdead as *mut *const u32).write_volatile(things.as_ptr()); // OK\n\n        let wideptr: *const [u32] = std::ptr::from_raw_parts(things.as_ptr(), things.len());\n        (0xdead as *mut *const [u32]).write_volatile(wideptr);\n        //~^ volatile_composites\n    }\n\n    // Plain pointers and pointers with lifetimes are OK\n    unsafe {\n        let v: u32 = 123;\n        let rv: &u32 = &v;\n\n        (0xdead as *mut &u32).write_volatile(rv); // OK\n    }\n\n    // C-style enums are OK\n    unsafe {\n        // Bad: need some specific repr\n        enum PlainEnum {\n            A = 1,\n            B = 2,\n            C = 3,\n        }\n\n        (0xdead as *mut PlainEnum).write_volatile(PlainEnum::A);\n        //~^ volatile_composites\n\n        // OK\n        #[repr(u32)]\n        enum U32Enum {\n            A = 1,\n            B = 2,\n            C = 3,\n        }\n\n        (0xdead as *mut U32Enum).write_volatile(U32Enum::A); // OK\n\n        // OK\n        #[repr(C)]\n        enum CEnum {\n            A = 1,\n            B = 2,\n            C = 3,\n        }\n        (0xdead as *mut CEnum).write_volatile(CEnum::A); // OK\n\n        // Nope\n        enum SumType {\n            A(String),\n            B(u32),\n            C,\n        }\n        (0xdead as *mut SumType).write_volatile(SumType::C);\n        //~^ volatile_composites\n\n        // A repr on a complex sum type is not good enough\n        #[repr(C)]\n        enum ReprSumType {\n            A(String),\n            B(u32),\n            C,\n        }\n        (0xdead as *mut ReprSumType).write_volatile(ReprSumType::C);\n        //~^ volatile_composites\n    }\n\n    // SIMD is OK\n    unsafe {\n        (0xdead as *mut std::simd::u32x4).write_volatile(std::simd::u32x4::splat(1)); // OK\n    }\n\n    // Can't see through generic wrapper\n    unsafe {\n        do_device_write::<MyDevRegisters>(0xdead as *mut _, Default::default()); // OK\n    }\n\n    let mut s = String::from(\"foo\");\n    unsafe {\n        std::ptr::write_volatile(&mut s, String::from(\"bar\"));\n        //~^ volatile_composites\n    }\n}\n\n// Generic OK\nunsafe fn do_device_write<T>(ptr: *mut T, v: T) {\n    unsafe {\n        ptr.write_volatile(v); // OK\n    }\n}\n"
  },
  {
    "path": "tests/ui/volatile_composites.stderr",
    "content": "error: type `MyDevRegisters` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:39:9\n   |\nLL |         DEVICE_ADDR.write_volatile(regs);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::volatile-composites` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::volatile_composites)]`\n\nerror: type `MyDevRegisters` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:47:21\n   |\nLL |         let _regs = DEVICE_ADDR.read_volatile();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `MyDevRegisters` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:56:9\n   |\nLL |         std::ptr::write_volatile(DEVICE_ADDR, regs);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `MyDevRegisters` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:64:21\n   |\nLL |         let _regs = std::ptr::read_volatile(DEVICE_ADDR);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `MyDevRegisters` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:73:9\n   |\nLL |         core::ptr::write_volatile(DEVICE_ADDR, regs);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `MyDevRegisters` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:81:21\n   |\nLL |         let _regs = core::ptr::read_volatile(DEVICE_ADDR);\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `MyDevRegisters` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:89:9\n   |\nLL |         ptr.write_volatile(regs);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `MyDevRegisters` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:92:21\n   |\nLL |         let _regs = ptr.read_volatile();\n   |                     ^^^^^^^^^^^^^^^^^^^\n\nerror: type `Wrapper<MyDevRegisters>` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:118:9\n   |\nLL |         (0xdead as *mut Wrapper<MyDevRegisters>).write_volatile(Wrapper((), MyDevRegisters::default(), ()));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `*const [u32]` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:136:9\n   |\nLL |         (0xdead as *mut *const [u32]).write_volatile(wideptr);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `main::PlainEnum` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:157:9\n   |\nLL |         (0xdead as *mut PlainEnum).write_volatile(PlainEnum::A);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `main::SumType` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:185:9\n   |\nLL |         (0xdead as *mut SumType).write_volatile(SumType::C);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `main::ReprSumType` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:195:9\n   |\nLL |         (0xdead as *mut ReprSumType).write_volatile(ReprSumType::C);\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: type `std::string::String` is not volatile-compatible\n  --> tests/ui/volatile_composites.rs:211:9\n   |\nLL |         std::ptr::write_volatile(&mut s, String::from(\"bar\"));\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/waker_clone_wake.fixed",
    "content": "#[derive(Clone)]\npub struct Custom;\n\nimpl Custom {\n    pub fn wake(self) {}\n}\n\nmacro_rules! mac {\n    ($cx:ident) => {\n        $cx.waker()\n    };\n}\n\npub fn wake(cx: &mut std::task::Context) {\n    cx.waker().wake_by_ref();\n    //~^ waker_clone_wake\n\n    mac!(cx).wake_by_ref();\n    //~^ waker_clone_wake\n}\n\npub fn no_lint(cx: &mut std::task::Context, c: &Custom) {\n    c.clone().wake();\n\n    let w = cx.waker().clone();\n    w.wake();\n\n    cx.waker().clone().wake_by_ref();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/waker_clone_wake.rs",
    "content": "#[derive(Clone)]\npub struct Custom;\n\nimpl Custom {\n    pub fn wake(self) {}\n}\n\nmacro_rules! mac {\n    ($cx:ident) => {\n        $cx.waker()\n    };\n}\n\npub fn wake(cx: &mut std::task::Context) {\n    cx.waker().clone().wake();\n    //~^ waker_clone_wake\n\n    mac!(cx).clone().wake();\n    //~^ waker_clone_wake\n}\n\npub fn no_lint(cx: &mut std::task::Context, c: &Custom) {\n    c.clone().wake();\n\n    let w = cx.waker().clone();\n    w.wake();\n\n    cx.waker().clone().wake_by_ref();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/waker_clone_wake.stderr",
    "content": "error: cloning a `Waker` only to wake it\n  --> tests/ui/waker_clone_wake.rs:15:5\n   |\nLL |     cx.waker().clone().wake();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `cx.waker().wake_by_ref()`\n   |\n   = note: `-D clippy::waker-clone-wake` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::waker_clone_wake)]`\n\nerror: cloning a `Waker` only to wake it\n  --> tests/ui/waker_clone_wake.rs:18:5\n   |\nLL |     mac!(cx).clone().wake();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `mac!(cx).wake_by_ref()`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/while_float.rs",
    "content": "#[deny(clippy::while_float)]\nfn main() {\n    let mut x = 0.0_f32;\n    while x < 42.0_f32 {\n        //~^ while_float\n        x += 0.5;\n    }\n    while x < 42.0 {\n        //~^ while_float\n        x += 1.0;\n    }\n    let mut x = 0;\n    while x < 42 {\n        x += 1;\n    }\n}\n"
  },
  {
    "path": "tests/ui/while_float.stderr",
    "content": "error: while condition comparing floats\n  --> tests/ui/while_float.rs:4:11\n   |\nLL |     while x < 42.0_f32 {\n   |           ^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui/while_float.rs:1:8\n   |\nLL | #[deny(clippy::while_float)]\n   |        ^^^^^^^^^^^^^^^^^^^\n\nerror: while condition comparing floats\n  --> tests/ui/while_float.rs:8:11\n   |\nLL |     while x < 42.0 {\n   |           ^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/while_immutable_condition.rs",
    "content": "#![warn(clippy::while_immutable_condition)]\n\nfn fn_val(i: i32) -> i32 {\n    unimplemented!()\n}\nfn fn_constref(i: &i32) -> i32 {\n    unimplemented!()\n}\nfn fn_mutref(i: &mut i32) {\n    unimplemented!()\n}\nfn fooi() -> i32 {\n    unimplemented!()\n}\nfn foob() -> bool {\n    unimplemented!()\n}\n\nfn immutable_condition() {\n    // Should warn when all vars mentioned are immutable\n    let y = 0;\n    while y < 10 {\n        //~^ while_immutable_condition\n\n        println!(\"KO - y is immutable\");\n    }\n\n    let x = 0;\n    while y < 10 && x < 3 {\n        //~^ while_immutable_condition\n\n        let mut k = 1;\n        k += 2;\n        println!(\"KO - x and y immutable\");\n    }\n\n    let cond = false;\n    while !cond {\n        //~^ while_immutable_condition\n\n        println!(\"KO - cond immutable\");\n    }\n\n    let mut i = 0;\n    while y < 10 && i < 3 {\n        i += 1;\n        println!(\"OK - i is mutable\");\n    }\n\n    let mut mut_cond = false;\n    while !mut_cond || cond {\n        mut_cond = true;\n        println!(\"OK - mut_cond is mutable\");\n    }\n\n    while fooi() < x {\n        println!(\"OK - Fn call results may vary\");\n    }\n\n    while foob() {\n        println!(\"OK - Fn call results may vary\");\n    }\n\n    let mut a = 0;\n    let mut c = move || {\n        while a < 5 {\n            a += 1;\n            println!(\"OK - a is mutable\");\n        }\n    };\n    c();\n\n    let mut tup = (0, 0);\n    while tup.0 < 5 {\n        tup.0 += 1;\n        println!(\"OK - tup.0 gets mutated\")\n    }\n}\n\nfn unused_var() {\n    // Should warn when a (mutable) var is not used in while body\n    let (mut i, mut j) = (0, 0);\n\n    while i < 3 {\n        //~^ while_immutable_condition\n\n        j = 3;\n        println!(\"KO - i not mentioned\");\n    }\n\n    while i < 3 && j > 0 {\n        //~^ while_immutable_condition\n\n        println!(\"KO - i and j not mentioned\");\n    }\n\n    while i < 3 {\n        //~^ while_immutable_condition\n\n        let mut i = 5;\n        fn_mutref(&mut i);\n        println!(\"KO - shadowed\");\n    }\n\n    while i < 3 && j > 0 {\n        i = 5;\n        println!(\"OK - i in cond and mentioned\");\n    }\n}\n\nfn used_immutable() {\n    let mut i = 0;\n\n    while i < 3 {\n        //~^ while_immutable_condition\n\n        fn_constref(&i);\n        println!(\"KO - const reference\");\n    }\n\n    while i < 3 {\n        //~^ while_immutable_condition\n\n        fn_val(i);\n        println!(\"KO - passed by value\");\n    }\n\n    while i < 3 {\n        println!(\"OK - passed by mutable reference\");\n        fn_mutref(&mut i)\n    }\n\n    while i < 3 {\n        fn_mutref(&mut i);\n        println!(\"OK - passed by mutable reference\");\n    }\n}\n\nconst N: i32 = 5;\nconst B: bool = false;\n\nfn consts() {\n    while false {\n        println!(\"Constants are not linted\");\n    }\n\n    while B {\n        println!(\"Constants are not linted\");\n    }\n\n    while N > 0 {\n        println!(\"Constants are not linted\");\n    }\n}\n\nuse std::cell::Cell;\n\nfn maybe_i_mutate(i: &Cell<bool>) {\n    unimplemented!()\n}\n\nfn internally_mutable() {\n    let b = Cell::new(true);\n\n    while b.get() {\n        // b cannot be silently coerced to `bool`\n        maybe_i_mutate(&b);\n        println!(\"OK - Method call within condition\");\n    }\n}\n\nstruct Counter {\n    count: usize,\n}\n\nimpl Counter {\n    fn inc(&mut self) {\n        self.count += 1;\n    }\n\n    fn inc_n(&mut self, n: usize) {\n        while self.count < n {\n            self.inc();\n        }\n        println!(\"OK - self borrowed mutably\");\n    }\n\n    fn print_n(&self, n: usize) {\n        while self.count < n {\n            //~^ while_immutable_condition\n\n            println!(\"KO - {} is not mutated\", self.count);\n        }\n    }\n}\n\nfn while_loop_with_break_and_return() {\n    let y = 0;\n    while y < 10 {\n        //~^ while_immutable_condition\n\n        if y == 0 {\n            break;\n        }\n        println!(\"KO - loop contains break\");\n    }\n\n    while y < 10 {\n        //~^ while_immutable_condition\n\n        if y == 0 {\n            return;\n        }\n        println!(\"KO - loop contains return\");\n    }\n}\n\nfn immutable_condition_false_positive(mut n: u64) -> u32 {\n    let mut count = 0;\n    while {\n        n >>= 1;\n        n != 0\n    } {\n        count += 1;\n    }\n    count\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/while_immutable_condition.stderr",
    "content": "error: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:22:11\n   |\nLL |     while y < 10 {\n   |           ^^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n   = note: `-D clippy::while-immutable-condition` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::while_immutable_condition)]`\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:29:11\n   |\nLL |     while y < 10 && x < 3 {\n   |           ^^^^^^^^^^^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:38:11\n   |\nLL |     while !cond {\n   |           ^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:84:11\n   |\nLL |     while i < 3 {\n   |           ^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:91:11\n   |\nLL |     while i < 3 && j > 0 {\n   |           ^^^^^^^^^^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:97:11\n   |\nLL |     while i < 3 {\n   |           ^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:114:11\n   |\nLL |     while i < 3 {\n   |           ^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:121:11\n   |\nLL |     while i < 3 {\n   |           ^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:189:15\n   |\nLL |         while self.count < n {\n   |               ^^^^^^^^^^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:199:11\n   |\nLL |     while y < 10 {\n   |           ^^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n   = note: this loop contains `return`s or `break`s\n   = help: rewrite it as `if cond { loop { } }`\n\nerror: variables in the condition are not mutated in the loop body\n  --> tests/ui/while_immutable_condition.rs:208:11\n   |\nLL |     while y < 10 {\n   |           ^^^^^^\n   |\n   = note: this may lead to an infinite or to a never running loop\n   = note: this loop contains `return`s or `break`s\n   = help: rewrite it as `if cond { loop { } }`\n\nerror: aborting due to 11 previous errors\n\n"
  },
  {
    "path": "tests/ui/while_let_loop.rs",
    "content": "#![warn(clippy::while_let_loop)]\n#![allow(clippy::uninlined_format_args)]\n//@no-rustfix\nfn main() {\n    let y = Some(true);\n    loop {\n        //~^ while_let_loop\n\n        if let Some(_x) = y {\n            let _v = 1;\n        } else {\n            break;\n        }\n    }\n\n    #[allow(clippy::never_loop)]\n    loop {\n        // no error, break is not in else clause\n        if let Some(_x) = y {\n            let _v = 1;\n        }\n        break;\n    }\n\n    loop {\n        //~^ while_let_loop\n        let Some(_x) = y else { break };\n    }\n\n    loop {\n        // no error, else branch does something other than break\n        let Some(_x) = y else {\n            let _z = 1;\n            break;\n        };\n    }\n\n    loop {\n        //~^ while_let_loop\n\n        match y {\n            Some(_x) => true,\n            None => break,\n        };\n    }\n\n    loop {\n        //~^ while_let_loop\n\n        let x = match y {\n            Some(x) => x,\n            None => break,\n        };\n        let _x = x;\n        let _str = \"foo\";\n    }\n\n    loop {\n        //~^ while_let_loop\n\n        let x = match y {\n            Some(x) => x,\n            None => break,\n        };\n        {\n            let _a = \"bar\";\n        };\n        {\n            let _b = \"foobar\";\n        }\n    }\n\n    loop {\n        // no error, else branch does something other than break\n        match y {\n            Some(_x) => true,\n            _ => {\n                let _z = 1;\n                break;\n            },\n        };\n    }\n\n    while let Some(x) = y {\n        // no error, obviously\n        println!(\"{}\", x);\n    }\n\n    // #675, this used to have a wrong suggestion\n    loop {\n        //~^ while_let_loop\n\n        let (e, l) = match \"\".split_whitespace().next() {\n            Some(word) => (word.is_empty(), word.len()),\n            None => break,\n        };\n\n        let _ = (e, l);\n    }\n}\n\nfn issue771() {\n    let mut a = 100;\n    let b = Some(true);\n    loop {\n        if a > 10 {\n            break;\n        }\n\n        match b {\n            Some(_) => a = 0,\n            None => break,\n        }\n    }\n}\n\nfn issue1017() {\n    let r: Result<u32, u32> = Ok(42);\n    let mut len = 1337;\n\n    loop {\n        match r {\n            Err(_) => len = 0,\n            Ok(length) => {\n                len = length;\n                break;\n            },\n        }\n    }\n}\n\n#[allow(clippy::never_loop)]\nfn issue1948() {\n    // should not trigger clippy::while_let_loop lint because break passes an expression\n    let a = Some(10);\n    let b = loop {\n        if let Some(c) = a {\n            break Some(c);\n        } else {\n            break None;\n        }\n    };\n}\n\nfn issue_7913(m: &std::sync::Mutex<Vec<u32>>) {\n    // Don't lint. The lock shouldn't be held while printing.\n    loop {\n        let x = if let Some(x) = m.lock().unwrap().pop() {\n            x\n        } else {\n            break;\n        };\n\n        println!(\"{}\", x);\n    }\n}\n\nfn issue_5715(mut m: core::cell::RefCell<Option<u32>>) {\n    // Don't lint. The temporary from `borrow_mut` must be dropped before overwriting the `RefCell`.\n    loop {\n        let x = if let &mut Some(x) = &mut *m.borrow_mut() {\n            x\n        } else {\n            break;\n        };\n\n        m = core::cell::RefCell::new(Some(x + 1));\n    }\n}\n\nmod issue_362 {\n    pub fn merge_sorted<T>(xs: Vec<T>, ys: Vec<T>) -> Vec<T>\n    where\n        T: PartialOrd,\n    {\n        let total_len = xs.len() + ys.len();\n        let mut res = Vec::with_capacity(total_len);\n        let mut ix = xs.into_iter().peekable();\n        let mut iy = ys.into_iter().peekable();\n        loop {\n            //~^ while_let_loop\n            let lt = match (ix.peek(), iy.peek()) {\n                (Some(x), Some(y)) => x < y,\n                _ => break,\n            };\n            res.push(if lt { &mut ix } else { &mut iy }.next().unwrap());\n        }\n        res.extend(ix);\n        res.extend(iy);\n        res\n    }\n}\n\nfn let_assign() {\n    loop {\n        //~^ while_let_loop\n        let x = if let Some(y) = Some(3) {\n            y\n        } else {\n            break;\n        };\n        if x == 3 {\n            break;\n        }\n    }\n\n    loop {\n        //~^ while_let_loop\n        let x: u32 = if let Some(y) = Some(3) {\n            y\n        } else {\n            break;\n        };\n        if x == 3 {\n            break;\n        }\n    }\n\n    loop {\n        //~^ while_let_loop\n        let x = if let Some(x) = Some(3) {\n            x\n        } else {\n            break;\n        };\n        if x == 3 {\n            break;\n        }\n    }\n\n    loop {\n        //~^ while_let_loop\n        let x: u32 = if let Some(x) = Some(3) {\n            x\n        } else {\n            break;\n        };\n        if x == 3 {\n            break;\n        }\n    }\n\n    loop {\n        //~^ while_let_loop\n        let x = if let Some(x) = Some(2) {\n            let t = 1;\n            t + x\n        } else {\n            break;\n        };\n        if x == 3 {\n            break;\n        }\n    }\n}\n\nfn issue16378() {\n    // This does not lint today because of the extra statement(s)\n    // before the `break`.\n    // TODO: When the `break` statement/expr in the `let`/`else` is the\n    // only way to leave the loop, the lint could trigger and move\n    // the statements preceeding the `break` after the loop, as in:\n    // ```rust\n    // while let Some(x) = std::hint::black_box(None::<i32>) {\n    //     println!(\"x = {x}\");\n    // }\n    // println!(\"fail\");\n    // ```\n    loop {\n        let Some(x) = std::hint::black_box(None::<i32>) else {\n            println!(\"fail\");\n            break;\n        };\n        println!(\"x = {x}\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/while_let_loop.stderr",
    "content": "error: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:6:5\n   |\nLL | /     loop {\nLL | |\nLL | |\nLL | |         if let Some(_x) = y {\n...  |\nLL | |     }\n   | |_____^ help: try: `while let Some(_x) = y { .. }`\n   |\n   = note: `-D clippy::while-let-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::while_let_loop)]`\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:25:5\n   |\nLL | /     loop {\nLL | |\nLL | |         let Some(_x) = y else { break };\nLL | |     }\n   | |_____^ help: try: `while let Some(_x) = y { .. }`\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:38:5\n   |\nLL | /     loop {\nLL | |\nLL | |\nLL | |         match y {\n...  |\nLL | |         };\nLL | |     }\n   | |_____^ help: try: `while let Some(_x) = y { .. }`\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:47:5\n   |\nLL | /     loop {\nLL | |\nLL | |\nLL | |         let x = match y {\n...  |\nLL | |         let _str = \"foo\";\nLL | |     }\n   | |_____^ help: try: `while let Some(x) = y { .. }`\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:58:5\n   |\nLL | /     loop {\nLL | |\nLL | |\nLL | |         let x = match y {\n...  |\nLL | |     }\n   | |_____^ help: try: `while let Some(x) = y { .. }`\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:90:5\n   |\nLL | /     loop {\nLL | |\nLL | |\nLL | |         let (e, l) = match \"\".split_whitespace().next() {\n...  |\nLL | |         let _ = (e, l);\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     while let Some(word) = \"\".split_whitespace().next() {\nLL +         let (e, l) = (word.is_empty(), word.len());\nLL +         ..\nLL +     }\n   |\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:180:9\n   |\nLL | /         loop {\nLL | |\nLL | |             let lt = match (ix.peek(), iy.peek()) {\nLL | |                 (Some(x), Some(y)) => x < y,\n...  |\nLL | |             res.push(if lt { &mut ix } else { &mut iy }.next().unwrap());\nLL | |         }\n   | |_________^\n   |\nhelp: try\n   |\nLL ~         while let (Some(x), Some(y)) = (ix.peek(), iy.peek()) {\nLL +             let lt = x < y;\nLL +             ..\nLL +         }\n   |\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:195:5\n   |\nLL | /     loop {\nLL | |\nLL | |         let x = if let Some(y) = Some(3) {\nLL | |             y\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     while let Some(y) = Some(3) {\nLL +         let x = y;\nLL +         ..\nLL +     }\n   |\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:207:5\n   |\nLL | /     loop {\nLL | |\nLL | |         let x: u32 = if let Some(y) = Some(3) {\nLL | |             y\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     while let Some(y) = Some(3) {\nLL +         let x: u32 = y;\nLL +         ..\nLL +     }\n   |\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:219:5\n   |\nLL | /     loop {\nLL | |\nLL | |         let x = if let Some(x) = Some(3) {\nLL | |             x\n...  |\nLL | |     }\n   | |_____^ help: try: `while let Some(x) = Some(3) { .. }`\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:231:5\n   |\nLL | /     loop {\nLL | |\nLL | |         let x: u32 = if let Some(x) = Some(3) {\nLL | |             x\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     while let Some(x) = Some(3) {\nLL +         let x: u32 = x;\nLL +         ..\nLL +     }\n   |\n\nerror: this loop could be written as a `while let` loop\n  --> tests/ui/while_let_loop.rs:243:5\n   |\nLL | /     loop {\nLL | |\nLL | |         let x = if let Some(x) = Some(2) {\nLL | |             let t = 1;\n...  |\nLL | |     }\n   | |_____^\n   |\nhelp: try\n   |\nLL ~     while let Some(x) = Some(2) {\nLL +         let x = {\nLL +             let t = 1;\nLL +             t + x\nLL +         };\nLL +         ..\nLL +     }\n   |\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui/while_let_on_iterator.fixed",
    "content": "#![warn(clippy::while_let_on_iterator)]\n#![allow(dead_code, unreachable_code, unused_mut)]\n#![allow(\n    clippy::equatable_if_let,\n    clippy::manual_find,\n    clippy::never_loop,\n    clippy::redundant_closure_call,\n    clippy::single_range_in_vec_init,\n    clippy::uninlined_format_args,\n    clippy::useless_vec\n)]\n\nfn base() {\n    let mut iter = 1..20;\n    for x in iter {\n        //~^ while_let_on_iterator\n        println!(\"{}\", x);\n    }\n\n    let mut iter = 1..20;\n    for x in iter {\n        //~^ while_let_on_iterator\n        println!(\"{}\", x);\n    }\n\n    let mut iter = 1..20;\n    for _ in iter {}\n    //~^ while_let_on_iterator\n\n    let mut iter = 1..20;\n    while let None = iter.next() {} // this is fine (if nonsensical)\n\n    let mut iter = 1..20;\n    if let Some(x) = iter.next() {\n        // also fine\n        println!(\"{}\", x)\n    }\n\n    // the following shouldn't warn because it can't be written with a for loop\n    let mut iter = 1u32..20;\n    while let Some(_) = iter.next() {\n        println!(\"next: {:?}\", iter.next())\n    }\n\n    // neither can this\n    let mut iter = 1u32..20;\n    while let Some(_) = iter.next() {\n        println!(\"next: {:?}\", iter.next());\n    }\n\n    // or this\n    let mut iter = 1u32..20;\n    while let Some(_) = iter.next() {\n        iter = 1..20;\n    }\n}\n\n// Issue #1188\nfn refutable() {\n    let a = [42, 1337];\n    let mut b = a.iter();\n\n    // consume all the 42s\n    while let Some(&42) = b.next() {}\n\n    let a = [(1, 2, 3)];\n    let mut b = a.iter();\n\n    while let Some(&(1, 2, 3)) = b.next() {}\n\n    let a = [Some(42)];\n    let mut b = a.iter();\n\n    while let Some(&None) = b.next() {}\n\n    /* This gives “refutable pattern in `for` loop binding: `&_` not covered”\n    for &42 in b {}\n    for &(1, 2, 3) in b {}\n    for &Option::None in b.next() {}\n    // */\n}\n\nfn refutable2() {\n    // Issue 3780\n    {\n        let v = vec![1, 2, 3];\n        let mut it = v.windows(2);\n        while let Some([x, y]) = it.next() {\n            println!(\"x: {}\", x);\n            println!(\"y: {}\", y);\n        }\n\n        let mut it = v.windows(2);\n        while let Some([x, ..]) = it.next() {\n            println!(\"x: {}\", x);\n        }\n\n        let mut it = v.windows(2);\n        while let Some([.., y]) = it.next() {\n            println!(\"y: {}\", y);\n        }\n\n        let mut it = v.windows(2);\n        for [..] in it {}\n        //~^ while_let_on_iterator\n\n        let v = vec![[1], [2], [3]];\n        let mut it = v.iter();\n        while let Some([1]) = it.next() {}\n\n        let mut it = v.iter();\n        for [_x] in it {}\n        //~^ while_let_on_iterator\n    }\n\n    // binding\n    {\n        let v = vec![1, 2, 3];\n        let mut it = v.iter();\n        while let Some(x @ 1) = it.next() {\n            println!(\"{}\", x);\n        }\n\n        let v = vec![[1], [2], [3]];\n        let mut it = v.iter();\n        for x @ [_] in it {\n            //~^ while_let_on_iterator\n            println!(\"{:?}\", x);\n        }\n    }\n\n    // false negative\n    {\n        let v = vec![1, 2, 3];\n        let mut it = v.iter().map(Some);\n        while let Some(Some(_) | None) = it.next() {\n            println!(\"1\");\n        }\n    }\n}\n\nfn nested_loops() {\n    let a = [42, 1337];\n\n    loop {\n        let mut y = a.iter();\n        for _ in y {\n            //~^ while_let_on_iterator\n            // use a for loop here\n        }\n    }\n}\n\nfn issue1121() {\n    use std::collections::HashSet;\n    let mut values = HashSet::new();\n    values.insert(1);\n\n    while let Some(&value) = values.iter().next() {\n        values.remove(&value);\n    }\n}\n\nfn issue2965() {\n    // This should not cause an ICE\n\n    use std::collections::HashSet;\n    let mut values = HashSet::new();\n    values.insert(1);\n\n    while let Some(..) = values.iter().next() {}\n}\n\nfn issue3670() {\n    let array = [Some(0), None, Some(1)];\n    let mut iter = array.iter();\n\n    while let Some(elem) = iter.next() {\n        let _ = elem.or_else(|| *iter.next()?);\n    }\n}\n\nfn issue1654() {\n    // should not lint if the iterator is generated on every iteration\n    use std::collections::HashSet;\n    let mut values = HashSet::new();\n    values.insert(1);\n\n    while let Some(..) = values.iter().next() {\n        values.remove(&1);\n    }\n\n    while let Some(..) = values.iter().map(|x| x + 1).next() {}\n\n    let chars = \"Hello, World!\".char_indices();\n    while let Some((i, ch)) = chars.clone().next() {\n        println!(\"{}: {}\", i, ch);\n    }\n}\n\nfn issue6491() {\n    // Used in outer loop, needs &mut\n    let mut it = 1..40;\n    while let Some(n) = it.next() {\n        for m in it.by_ref() {\n            //~^ while_let_on_iterator\n            if m % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n        println!(\"n still is {}\", n);\n    }\n\n    // This is fine, inner loop uses a new iterator.\n    let mut it = 1..40;\n    for n in it {\n        //~^ while_let_on_iterator\n        let mut it = 1..40;\n        for m in it {\n            //~^ while_let_on_iterator\n            if m % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n\n        // Weird binding shouldn't change anything.\n        let (mut it, _) = (1..40, 0);\n        for m in it {\n            //~^ while_let_on_iterator\n            if m % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n\n        // Used after the loop, needs &mut.\n        let mut it = 1..40;\n        for m in it.by_ref() {\n            //~^ while_let_on_iterator\n            if m % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n        println!(\"next item {}\", it.next().unwrap());\n\n        println!(\"n still is {}\", n);\n    }\n}\n\nfn issue6231() {\n    // Closure in the outer loop, needs &mut\n    let mut it = 1..40;\n    let mut opt = Some(0);\n    while let Some(n) = opt.take().or_else(|| it.next()) {\n        for m in it.by_ref() {\n            //~^ while_let_on_iterator\n            if n % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n        println!(\"n still is {}\", n);\n    }\n}\n\nfn issue1924() {\n    struct S<T>(T);\n    impl<T: Iterator<Item = u32>> S<T> {\n        fn f(&mut self) -> Option<u32> {\n            // Used as a field.\n            for i in self.0.by_ref() {\n                //~^ while_let_on_iterator\n                if !(3..8).contains(&i) {\n                    return Some(i);\n                }\n            }\n            None\n        }\n\n        fn f2(&mut self) -> Option<u32> {\n            // Don't lint, self borrowed inside the loop\n            while let Some(i) = self.0.next() {\n                if i == 1 {\n                    return self.f();\n                }\n            }\n            None\n        }\n    }\n    impl<T: Iterator<Item = u32>> S<(S<T>, Option<u32>)> {\n        fn f3(&mut self) -> Option<u32> {\n            // Don't lint, self borrowed inside the loop\n            while let Some(i) = self.0.0.0.next() {\n                if i == 1 {\n                    return self.0.0.f();\n                }\n            }\n            while let Some(i) = self.0.0.0.next() {\n                if i == 1 {\n                    return self.f3();\n                }\n            }\n            // This one is fine, a different field is borrowed\n            for i in self.0.0.0.by_ref() {\n                //~^ while_let_on_iterator\n                if i == 1 {\n                    return self.0.1.take();\n                } else {\n                    self.0.1 = Some(i);\n                }\n            }\n            None\n        }\n    }\n\n    struct S2<T>(T, u32);\n    impl<T: Iterator<Item = u32>> Iterator for S2<T> {\n        type Item = u32;\n        fn next(&mut self) -> Option<u32> {\n            self.0.next()\n        }\n    }\n\n    // Don't lint, field of the iterator is accessed in the loop\n    let mut it = S2(1..40, 0);\n    while let Some(n) = it.next() {\n        if n == it.1 {\n            break;\n        }\n    }\n\n    // Needs &mut, field of the iterator is accessed after the loop\n    let mut it = S2(1..40, 0);\n    for n in it.by_ref() {\n        //~^ while_let_on_iterator\n        if n == 0 {\n            break;\n        }\n    }\n    println!(\"iterator field {}\", it.1);\n}\n\nfn issue7249() {\n    let mut it = 0..10;\n    let mut x = || {\n        // Needs &mut, the closure can be called multiple times\n        for x in it.by_ref() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    };\n    x();\n    x();\n}\n\nfn issue7510() {\n    let mut it = 0..10;\n    let it = &mut it;\n    // Needs to reborrow `it` as the binding isn't mutable\n    for x in it.by_ref() {\n        //~^ while_let_on_iterator\n        if x % 2 == 0 {\n            break;\n        }\n    }\n    println!(\"{}\", it.next().unwrap());\n\n    struct S<T>(T);\n    let mut it = 0..10;\n    let it = S(&mut it);\n    // Needs to reborrow `it.0` as the binding isn't mutable\n    for x in it.0.by_ref() {\n        //~^ while_let_on_iterator\n        if x % 2 == 0 {\n            break;\n        }\n    }\n    println!(\"{}\", it.0.next().unwrap());\n}\n\nfn exact_match_with_single_field() {\n    struct S<T>(T);\n    let mut s = S(0..10);\n    // Don't lint. `s.0` is used inside the loop.\n    while let Some(_) = s.0.next() {\n        let _ = &mut s.0;\n    }\n}\n\nfn custom_deref() {\n    struct S1<T> {\n        x: T,\n    }\n    struct S2<T>(S1<T>);\n    impl<T> core::ops::Deref for S2<T> {\n        type Target = S1<T>;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for S2<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    let mut s = S2(S1 { x: 0..10 });\n    for x in s.x.by_ref() {\n        //~^ while_let_on_iterator\n        println!(\"{}\", x);\n    }\n}\n\nfn issue_8113() {\n    let mut x = [0..10];\n    for x in x[0].by_ref() {\n        //~^ while_let_on_iterator\n        println!(\"{}\", x);\n    }\n}\n\nfn fn_once_closure() {\n    let mut it = 0..10;\n    (|| {\n        for x in it.by_ref() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    })();\n\n    fn f(_: impl FnOnce()) {}\n    let mut it = 0..10;\n    f(|| {\n        for x in it {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    });\n\n    fn f2(_: impl FnMut()) {}\n    let mut it = 0..10;\n    f2(|| {\n        for x in it.by_ref() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    });\n\n    fn f3(_: fn()) {}\n    f3(|| {\n        let mut it = 0..10;\n        for x in it {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    });\n\n    trait MySpecialFnMut: FnOnce() {}\n    impl<T: FnOnce()> MySpecialFnMut for T {}\n    fn f4(_: impl MySpecialFnMut) {}\n    let mut it = 0..10;\n    f4(|| {\n        for x in it {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    });\n}\n\nfn issue13123() {\n    let mut it = 0..20;\n    'label: for n in it {\n        //~^ while_let_on_iterator\n        if n % 25 == 0 {\n            break 'label;\n        }\n    }\n}\n\nfn issue16089() {\n    trait CertainTrait: Iterator<Item = u8> {\n        fn iter_over_self(&mut self) {\n            let mut a = 0;\n            for r in &mut *self {\n                //~^ while_let_on_iterator\n                a = r;\n            }\n            self.use_after_iter()\n        }\n\n        fn use_after_iter(&mut self) {}\n    }\n}\n\nfn issue16089_sized_trait_not_reborrowed() {\n    trait CertainTrait: Iterator<Item = u8> + Sized {\n        fn iter_over_self(&mut self) {\n            let mut a = 0;\n            // Check that the suggestion is just \"self\", since the trait is sized.\n            for r in self.by_ref() {\n                //~^ while_let_on_iterator\n                a = r;\n            }\n            self.use_after_iter()\n        }\n\n        fn use_after_iter(&mut self) {}\n    }\n}\n\nfn issue16089_nested_derefs() {\n    struct S<T>(T);\n    impl<T> core::ops::Deref for S<T> {\n        type Target = T;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for S<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    fn f(mut x: S<S<&mut dyn Iterator<Item = u32>>>) {\n        for _ in &mut ***x {}\n        //~^ while_let_on_iterator\n    }\n}\n\nfn issue16089_nested_derefs_last_not_sized() {\n    struct WithSize<T>(T);\n    impl<T> core::ops::Deref for WithSize<T> {\n        type Target = T;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for WithSize<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n    // The suggestion must use `&mut **x`. Using `x.by_ref()` doesn't work in this\n    // case, since the last type adjustment for `x` in the expression `x.next()` is\n    // to dereference a `?Sized` trait.\n    fn f(mut x: WithSize<&mut dyn Iterator<Item = u32>>) {\n        for _ in &mut **x {}\n        //~^ while_let_on_iterator\n    }\n}\n\nfn issue16089_nested_derefs_last_sized() {\n    struct NoSize<T: ?Sized>(T);\n    impl<T: ?Sized> core::ops::Deref for NoSize<T> {\n        type Target = T;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T: ?Sized> core::ops::DerefMut for NoSize<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    struct SizedIter {}\n\n    impl Iterator for SizedIter {\n        type Item = u32;\n        fn next(&mut self) -> Option<u32> {\n            Some(0)\n        }\n    }\n\n    // We want the suggestion to be `x.by_ref()`. It works in this case since the last type\n    // adjustment for `x` in the expression `x.next()` is to dereference a Sized type.\n    fn f(mut x: NoSize<NoSize<SizedIter>>) {\n        for _ in x.by_ref() {}\n        //~^ while_let_on_iterator\n    }\n}\n\nfn main() {\n    let mut it = 0..20;\n    for _ in it {\n        //~^ while_let_on_iterator\n        println!(\"test\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/while_let_on_iterator.rs",
    "content": "#![warn(clippy::while_let_on_iterator)]\n#![allow(dead_code, unreachable_code, unused_mut)]\n#![allow(\n    clippy::equatable_if_let,\n    clippy::manual_find,\n    clippy::never_loop,\n    clippy::redundant_closure_call,\n    clippy::single_range_in_vec_init,\n    clippy::uninlined_format_args,\n    clippy::useless_vec\n)]\n\nfn base() {\n    let mut iter = 1..20;\n    while let Option::Some(x) = iter.next() {\n        //~^ while_let_on_iterator\n        println!(\"{}\", x);\n    }\n\n    let mut iter = 1..20;\n    while let Some(x) = iter.next() {\n        //~^ while_let_on_iterator\n        println!(\"{}\", x);\n    }\n\n    let mut iter = 1..20;\n    while let Some(_) = iter.next() {}\n    //~^ while_let_on_iterator\n\n    let mut iter = 1..20;\n    while let None = iter.next() {} // this is fine (if nonsensical)\n\n    let mut iter = 1..20;\n    if let Some(x) = iter.next() {\n        // also fine\n        println!(\"{}\", x)\n    }\n\n    // the following shouldn't warn because it can't be written with a for loop\n    let mut iter = 1u32..20;\n    while let Some(_) = iter.next() {\n        println!(\"next: {:?}\", iter.next())\n    }\n\n    // neither can this\n    let mut iter = 1u32..20;\n    while let Some(_) = iter.next() {\n        println!(\"next: {:?}\", iter.next());\n    }\n\n    // or this\n    let mut iter = 1u32..20;\n    while let Some(_) = iter.next() {\n        iter = 1..20;\n    }\n}\n\n// Issue #1188\nfn refutable() {\n    let a = [42, 1337];\n    let mut b = a.iter();\n\n    // consume all the 42s\n    while let Some(&42) = b.next() {}\n\n    let a = [(1, 2, 3)];\n    let mut b = a.iter();\n\n    while let Some(&(1, 2, 3)) = b.next() {}\n\n    let a = [Some(42)];\n    let mut b = a.iter();\n\n    while let Some(&None) = b.next() {}\n\n    /* This gives “refutable pattern in `for` loop binding: `&_` not covered”\n    for &42 in b {}\n    for &(1, 2, 3) in b {}\n    for &Option::None in b.next() {}\n    // */\n}\n\nfn refutable2() {\n    // Issue 3780\n    {\n        let v = vec![1, 2, 3];\n        let mut it = v.windows(2);\n        while let Some([x, y]) = it.next() {\n            println!(\"x: {}\", x);\n            println!(\"y: {}\", y);\n        }\n\n        let mut it = v.windows(2);\n        while let Some([x, ..]) = it.next() {\n            println!(\"x: {}\", x);\n        }\n\n        let mut it = v.windows(2);\n        while let Some([.., y]) = it.next() {\n            println!(\"y: {}\", y);\n        }\n\n        let mut it = v.windows(2);\n        while let Some([..]) = it.next() {}\n        //~^ while_let_on_iterator\n\n        let v = vec![[1], [2], [3]];\n        let mut it = v.iter();\n        while let Some([1]) = it.next() {}\n\n        let mut it = v.iter();\n        while let Some([_x]) = it.next() {}\n        //~^ while_let_on_iterator\n    }\n\n    // binding\n    {\n        let v = vec![1, 2, 3];\n        let mut it = v.iter();\n        while let Some(x @ 1) = it.next() {\n            println!(\"{}\", x);\n        }\n\n        let v = vec![[1], [2], [3]];\n        let mut it = v.iter();\n        while let Some(x @ [_]) = it.next() {\n            //~^ while_let_on_iterator\n            println!(\"{:?}\", x);\n        }\n    }\n\n    // false negative\n    {\n        let v = vec![1, 2, 3];\n        let mut it = v.iter().map(Some);\n        while let Some(Some(_) | None) = it.next() {\n            println!(\"1\");\n        }\n    }\n}\n\nfn nested_loops() {\n    let a = [42, 1337];\n\n    loop {\n        let mut y = a.iter();\n        while let Some(_) = y.next() {\n            //~^ while_let_on_iterator\n            // use a for loop here\n        }\n    }\n}\n\nfn issue1121() {\n    use std::collections::HashSet;\n    let mut values = HashSet::new();\n    values.insert(1);\n\n    while let Some(&value) = values.iter().next() {\n        values.remove(&value);\n    }\n}\n\nfn issue2965() {\n    // This should not cause an ICE\n\n    use std::collections::HashSet;\n    let mut values = HashSet::new();\n    values.insert(1);\n\n    while let Some(..) = values.iter().next() {}\n}\n\nfn issue3670() {\n    let array = [Some(0), None, Some(1)];\n    let mut iter = array.iter();\n\n    while let Some(elem) = iter.next() {\n        let _ = elem.or_else(|| *iter.next()?);\n    }\n}\n\nfn issue1654() {\n    // should not lint if the iterator is generated on every iteration\n    use std::collections::HashSet;\n    let mut values = HashSet::new();\n    values.insert(1);\n\n    while let Some(..) = values.iter().next() {\n        values.remove(&1);\n    }\n\n    while let Some(..) = values.iter().map(|x| x + 1).next() {}\n\n    let chars = \"Hello, World!\".char_indices();\n    while let Some((i, ch)) = chars.clone().next() {\n        println!(\"{}: {}\", i, ch);\n    }\n}\n\nfn issue6491() {\n    // Used in outer loop, needs &mut\n    let mut it = 1..40;\n    while let Some(n) = it.next() {\n        while let Some(m) = it.next() {\n            //~^ while_let_on_iterator\n            if m % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n        println!(\"n still is {}\", n);\n    }\n\n    // This is fine, inner loop uses a new iterator.\n    let mut it = 1..40;\n    while let Some(n) = it.next() {\n        //~^ while_let_on_iterator\n        let mut it = 1..40;\n        while let Some(m) = it.next() {\n            //~^ while_let_on_iterator\n            if m % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n\n        // Weird binding shouldn't change anything.\n        let (mut it, _) = (1..40, 0);\n        while let Some(m) = it.next() {\n            //~^ while_let_on_iterator\n            if m % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n\n        // Used after the loop, needs &mut.\n        let mut it = 1..40;\n        while let Some(m) = it.next() {\n            //~^ while_let_on_iterator\n            if m % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n        println!(\"next item {}\", it.next().unwrap());\n\n        println!(\"n still is {}\", n);\n    }\n}\n\nfn issue6231() {\n    // Closure in the outer loop, needs &mut\n    let mut it = 1..40;\n    let mut opt = Some(0);\n    while let Some(n) = opt.take().or_else(|| it.next()) {\n        while let Some(m) = it.next() {\n            //~^ while_let_on_iterator\n            if n % 10 == 0 {\n                break;\n            }\n            println!(\"doing something with m: {}\", m);\n        }\n        println!(\"n still is {}\", n);\n    }\n}\n\nfn issue1924() {\n    struct S<T>(T);\n    impl<T: Iterator<Item = u32>> S<T> {\n        fn f(&mut self) -> Option<u32> {\n            // Used as a field.\n            while let Some(i) = self.0.next() {\n                //~^ while_let_on_iterator\n                if !(3..8).contains(&i) {\n                    return Some(i);\n                }\n            }\n            None\n        }\n\n        fn f2(&mut self) -> Option<u32> {\n            // Don't lint, self borrowed inside the loop\n            while let Some(i) = self.0.next() {\n                if i == 1 {\n                    return self.f();\n                }\n            }\n            None\n        }\n    }\n    impl<T: Iterator<Item = u32>> S<(S<T>, Option<u32>)> {\n        fn f3(&mut self) -> Option<u32> {\n            // Don't lint, self borrowed inside the loop\n            while let Some(i) = self.0.0.0.next() {\n                if i == 1 {\n                    return self.0.0.f();\n                }\n            }\n            while let Some(i) = self.0.0.0.next() {\n                if i == 1 {\n                    return self.f3();\n                }\n            }\n            // This one is fine, a different field is borrowed\n            while let Some(i) = self.0.0.0.next() {\n                //~^ while_let_on_iterator\n                if i == 1 {\n                    return self.0.1.take();\n                } else {\n                    self.0.1 = Some(i);\n                }\n            }\n            None\n        }\n    }\n\n    struct S2<T>(T, u32);\n    impl<T: Iterator<Item = u32>> Iterator for S2<T> {\n        type Item = u32;\n        fn next(&mut self) -> Option<u32> {\n            self.0.next()\n        }\n    }\n\n    // Don't lint, field of the iterator is accessed in the loop\n    let mut it = S2(1..40, 0);\n    while let Some(n) = it.next() {\n        if n == it.1 {\n            break;\n        }\n    }\n\n    // Needs &mut, field of the iterator is accessed after the loop\n    let mut it = S2(1..40, 0);\n    while let Some(n) = it.next() {\n        //~^ while_let_on_iterator\n        if n == 0 {\n            break;\n        }\n    }\n    println!(\"iterator field {}\", it.1);\n}\n\nfn issue7249() {\n    let mut it = 0..10;\n    let mut x = || {\n        // Needs &mut, the closure can be called multiple times\n        while let Some(x) = it.next() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    };\n    x();\n    x();\n}\n\nfn issue7510() {\n    let mut it = 0..10;\n    let it = &mut it;\n    // Needs to reborrow `it` as the binding isn't mutable\n    while let Some(x) = it.next() {\n        //~^ while_let_on_iterator\n        if x % 2 == 0 {\n            break;\n        }\n    }\n    println!(\"{}\", it.next().unwrap());\n\n    struct S<T>(T);\n    let mut it = 0..10;\n    let it = S(&mut it);\n    // Needs to reborrow `it.0` as the binding isn't mutable\n    while let Some(x) = it.0.next() {\n        //~^ while_let_on_iterator\n        if x % 2 == 0 {\n            break;\n        }\n    }\n    println!(\"{}\", it.0.next().unwrap());\n}\n\nfn exact_match_with_single_field() {\n    struct S<T>(T);\n    let mut s = S(0..10);\n    // Don't lint. `s.0` is used inside the loop.\n    while let Some(_) = s.0.next() {\n        let _ = &mut s.0;\n    }\n}\n\nfn custom_deref() {\n    struct S1<T> {\n        x: T,\n    }\n    struct S2<T>(S1<T>);\n    impl<T> core::ops::Deref for S2<T> {\n        type Target = S1<T>;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for S2<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    let mut s = S2(S1 { x: 0..10 });\n    while let Some(x) = s.x.next() {\n        //~^ while_let_on_iterator\n        println!(\"{}\", x);\n    }\n}\n\nfn issue_8113() {\n    let mut x = [0..10];\n    while let Some(x) = x[0].next() {\n        //~^ while_let_on_iterator\n        println!(\"{}\", x);\n    }\n}\n\nfn fn_once_closure() {\n    let mut it = 0..10;\n    (|| {\n        while let Some(x) = it.next() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    })();\n\n    fn f(_: impl FnOnce()) {}\n    let mut it = 0..10;\n    f(|| {\n        while let Some(x) = it.next() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    });\n\n    fn f2(_: impl FnMut()) {}\n    let mut it = 0..10;\n    f2(|| {\n        while let Some(x) = it.next() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    });\n\n    fn f3(_: fn()) {}\n    f3(|| {\n        let mut it = 0..10;\n        while let Some(x) = it.next() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    });\n\n    trait MySpecialFnMut: FnOnce() {}\n    impl<T: FnOnce()> MySpecialFnMut for T {}\n    fn f4(_: impl MySpecialFnMut) {}\n    let mut it = 0..10;\n    f4(|| {\n        while let Some(x) = it.next() {\n            //~^ while_let_on_iterator\n            if x % 2 == 0 {\n                break;\n            }\n        }\n    });\n}\n\nfn issue13123() {\n    let mut it = 0..20;\n    'label: while let Some(n) = it.next() {\n        //~^ while_let_on_iterator\n        if n % 25 == 0 {\n            break 'label;\n        }\n    }\n}\n\nfn issue16089() {\n    trait CertainTrait: Iterator<Item = u8> {\n        fn iter_over_self(&mut self) {\n            let mut a = 0;\n            while let Some(r) = self.next() {\n                //~^ while_let_on_iterator\n                a = r;\n            }\n            self.use_after_iter()\n        }\n\n        fn use_after_iter(&mut self) {}\n    }\n}\n\nfn issue16089_sized_trait_not_reborrowed() {\n    trait CertainTrait: Iterator<Item = u8> + Sized {\n        fn iter_over_self(&mut self) {\n            let mut a = 0;\n            // Check that the suggestion is just \"self\", since the trait is sized.\n            while let Some(r) = self.next() {\n                //~^ while_let_on_iterator\n                a = r;\n            }\n            self.use_after_iter()\n        }\n\n        fn use_after_iter(&mut self) {}\n    }\n}\n\nfn issue16089_nested_derefs() {\n    struct S<T>(T);\n    impl<T> core::ops::Deref for S<T> {\n        type Target = T;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for S<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    fn f(mut x: S<S<&mut dyn Iterator<Item = u32>>>) {\n        while let Some(_) = x.next() {}\n        //~^ while_let_on_iterator\n    }\n}\n\nfn issue16089_nested_derefs_last_not_sized() {\n    struct WithSize<T>(T);\n    impl<T> core::ops::Deref for WithSize<T> {\n        type Target = T;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T> core::ops::DerefMut for WithSize<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n    // The suggestion must use `&mut **x`. Using `x.by_ref()` doesn't work in this\n    // case, since the last type adjustment for `x` in the expression `x.next()` is\n    // to dereference a `?Sized` trait.\n    fn f(mut x: WithSize<&mut dyn Iterator<Item = u32>>) {\n        while let Some(_) = x.next() {}\n        //~^ while_let_on_iterator\n    }\n}\n\nfn issue16089_nested_derefs_last_sized() {\n    struct NoSize<T: ?Sized>(T);\n    impl<T: ?Sized> core::ops::Deref for NoSize<T> {\n        type Target = T;\n        fn deref(&self) -> &Self::Target {\n            &self.0\n        }\n    }\n    impl<T: ?Sized> core::ops::DerefMut for NoSize<T> {\n        fn deref_mut(&mut self) -> &mut Self::Target {\n            &mut self.0\n        }\n    }\n\n    struct SizedIter {}\n\n    impl Iterator for SizedIter {\n        type Item = u32;\n        fn next(&mut self) -> Option<u32> {\n            Some(0)\n        }\n    }\n\n    // We want the suggestion to be `x.by_ref()`. It works in this case since the last type\n    // adjustment for `x` in the expression `x.next()` is to dereference a Sized type.\n    fn f(mut x: NoSize<NoSize<SizedIter>>) {\n        while let Some(_) = x.next() {}\n        //~^ while_let_on_iterator\n    }\n}\n\nfn main() {\n    let mut it = 0..20;\n    while let Some(..) = it.next() {\n        //~^ while_let_on_iterator\n        println!(\"test\");\n    }\n}\n"
  },
  {
    "path": "tests/ui/while_let_on_iterator.stderr",
    "content": "error: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:15:5\n   |\nLL |     while let Option::Some(x) = iter.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter`\n   |\n   = note: `-D clippy::while-let-on-iterator` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::while_let_on_iterator)]`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:21:5\n   |\nLL |     while let Some(x) = iter.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:27:5\n   |\nLL |     while let Some(_) = iter.next() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in iter`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:104:9\n   |\nLL |         while let Some([..]) = it.next() {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [..] in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:112:9\n   |\nLL |         while let Some([_x]) = it.next() {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [_x] in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:126:9\n   |\nLL |         while let Some(x @ [_]) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x @ [_] in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:147:9\n   |\nLL |         while let Some(_) = y.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in y`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:205:9\n   |\nLL |         while let Some(m) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:217:5\n   |\nLL |     while let Some(n) = it.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:220:9\n   |\nLL |         while let Some(m) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:230:9\n   |\nLL |         while let Some(m) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:240:9\n   |\nLL |         while let Some(m) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:258:9\n   |\nLL |         while let Some(m) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:274:13\n   |\nLL |             while let Some(i) = self.0.next() {\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:307:13\n   |\nLL |             while let Some(i) = self.0.0.0.next() {\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.0.0.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:337:5\n   |\nLL |     while let Some(n) = it.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:350:9\n   |\nLL |         while let Some(x) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:365:5\n   |\nLL |     while let Some(x) = it.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:377:5\n   |\nLL |     while let Some(x) = it.0.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.0.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:413:5\n   |\nLL |     while let Some(x) = s.x.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in s.x.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:421:5\n   |\nLL |     while let Some(x) = x[0].next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in x[0].by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:430:9\n   |\nLL |         while let Some(x) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:441:9\n   |\nLL |         while let Some(x) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:452:9\n   |\nLL |         while let Some(x) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:463:9\n   |\nLL |         while let Some(x) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:476:9\n   |\nLL |         while let Some(x) = it.next() {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:487:5\n   |\nLL |     'label: while let Some(n) = it.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'label: for n in it`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:499:13\n   |\nLL |             while let Some(r) = self.next() {\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for r in &mut *self`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:515:13\n   |\nLL |             while let Some(r) = self.next() {\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for r in self.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:541:9\n   |\nLL |         while let Some(_) = x.next() {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in &mut ***x`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:563:9\n   |\nLL |         while let Some(_) = x.next() {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in &mut **x`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:594:9\n   |\nLL |         while let Some(_) = x.next() {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in x.by_ref()`\n\nerror: this loop could be written as a `for` loop\n  --> tests/ui/while_let_on_iterator.rs:601:5\n   |\nLL |     while let Some(..) = it.next() {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it`\n\nerror: aborting due to 33 previous errors\n\n"
  },
  {
    "path": "tests/ui/wild_in_or_pats.rs",
    "content": "#![warn(clippy::wildcard_in_or_patterns)]\n\nfn main() {\n    match \"foo\" {\n        \"a\" => {\n            dbg!(\"matched a\");\n        },\n        \"bar\" | _ => {\n            //~^ wildcard_in_or_patterns\n\n            dbg!(\"matched (bar or) wild\");\n        },\n    };\n    match \"foo\" {\n        \"a\" => {\n            dbg!(\"matched a\");\n        },\n        \"bar\" | \"bar2\" | _ => {\n            //~^ wildcard_in_or_patterns\n\n            dbg!(\"matched (bar or bar2 or) wild\");\n        },\n    };\n    match \"foo\" {\n        \"a\" => {\n            dbg!(\"matched a\");\n        },\n        _ | \"bar\" | _ => {\n            //~^ wildcard_in_or_patterns\n\n            dbg!(\"matched (bar or) wild\");\n        },\n    };\n    match \"foo\" {\n        \"a\" => {\n            dbg!(\"matched a\");\n        },\n        _ | \"bar\" => {\n            //~^ wildcard_in_or_patterns\n\n            dbg!(\"matched (bar or) wild\");\n        },\n    };\n\n    // shouldn't lint\n    #[non_exhaustive]\n    pub enum NonExhaustiveEnum<'a> {\n        Message(&'a str),\n        Quit(&'a str),\n        Other,\n    }\n\n    match NonExhaustiveEnum::Message(\"Pass\") {\n        NonExhaustiveEnum::Message(_) => dbg!(\"message\"),\n        NonExhaustiveEnum::Quit(_) => dbg!(\"quit\"),\n        NonExhaustiveEnum::Other | _ => dbg!(\"wildcard\"),\n    };\n\n    // should lint\n    enum ExhaustiveEnum {\n        Quit,\n        Write(String),\n        ChangeColor(i32, i32, i32),\n    }\n\n    match ExhaustiveEnum::ChangeColor(0, 160, 255) {\n        ExhaustiveEnum::Write(text) => {\n            dbg!(\"Write\");\n        },\n        ExhaustiveEnum::ChangeColor(r, g, b) => {\n            dbg!(\"Change the color\");\n        },\n        ExhaustiveEnum::Quit | _ => {\n            //~^ wildcard_in_or_patterns\n            dbg!(\"Quit or other\");\n        },\n    };\n\n    // shouldn't lint\n    #[non_exhaustive]\n    struct NonExhaustiveStruct {\n        a: u32,\n        b: u32,\n        c: u64,\n    }\n\n    let b = NonExhaustiveStruct { a: 5, b: 42, c: 342 };\n\n    match b {\n        NonExhaustiveStruct { a: 5, b: 42, .. } => {},\n        NonExhaustiveStruct { a: 0, b: 0, c: 128 } => {},\n        NonExhaustiveStruct { a: 0, b: 0, c: 128, .. } | _ => {},\n    }\n\n    // should lint\n    struct ExhaustiveStruct {\n        x: i32,\n        y: i32,\n    }\n\n    let p = ExhaustiveStruct { x: 0, y: 7 };\n    match p {\n        ExhaustiveStruct { x: 0, y: 0 } => {\n            dbg!(\"On the x axis at {x}\");\n        },\n        ExhaustiveStruct { x: 0, y: 1 } => {\n            dbg!(\"On the y axis at {y}\");\n        },\n        ExhaustiveStruct { x: 1, y: 1 } | _ => {\n            //~^ wildcard_in_or_patterns\n            dbg!(\"On neither axis: ({x}, {y})\");\n        },\n    }\n}\n"
  },
  {
    "path": "tests/ui/wild_in_or_pats.stderr",
    "content": "error: wildcard pattern covers any other pattern as it will match anyway\n  --> tests/ui/wild_in_or_pats.rs:8:9\n   |\nLL |         \"bar\" | _ => {\n   |         ^^^^^^^^^\n   |\n   = help: consider handling `_` separately\n   = note: `-D clippy::wildcard-in-or-patterns` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wildcard_in_or_patterns)]`\n\nerror: wildcard pattern covers any other pattern as it will match anyway\n  --> tests/ui/wild_in_or_pats.rs:18:9\n   |\nLL |         \"bar\" | \"bar2\" | _ => {\n   |         ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider handling `_` separately\n\nerror: wildcard pattern covers any other pattern as it will match anyway\n  --> tests/ui/wild_in_or_pats.rs:28:9\n   |\nLL |         _ | \"bar\" | _ => {\n   |         ^^^^^^^^^^^^^\n   |\n   = help: consider handling `_` separately\n\nerror: wildcard pattern covers any other pattern as it will match anyway\n  --> tests/ui/wild_in_or_pats.rs:38:9\n   |\nLL |         _ | \"bar\" => {\n   |         ^^^^^^^^^\n   |\n   = help: consider handling `_` separately\n\nerror: wildcard pattern covers any other pattern as it will match anyway\n  --> tests/ui/wild_in_or_pats.rs:73:9\n   |\nLL |         ExhaustiveEnum::Quit | _ => {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider handling `_` separately\n\nerror: wildcard pattern covers any other pattern as it will match anyway\n  --> tests/ui/wild_in_or_pats.rs:109:9\n   |\nLL |         ExhaustiveStruct { x: 1, y: 1 } | _ => {\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider handling `_` separately\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/wildcard_enum_match_arm.fixed",
    "content": "//@aux-build:non-exhaustive-enum.rs\n#![deny(clippy::wildcard_enum_match_arm)]\n#![allow(dead_code, unreachable_code, unused_variables)]\n#![allow(\n    clippy::diverging_sub_expression,\n    clippy::single_match,\n    clippy::uninlined_format_args,\n    clippy::unnested_or_patterns,\n    clippy::wildcard_in_or_patterns\n)]\n\nextern crate non_exhaustive_enum;\n\nuse non_exhaustive_enum::ErrorKind;\n\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\nenum Color {\n    Red,\n    Green,\n    Blue,\n    Rgb(u8, u8, u8),\n    Cyan,\n}\n\nimpl Color {\n    fn is_monochrome(self) -> bool {\n        match self {\n            Color::Red | Color::Green | Color::Blue => true,\n            Color::Rgb(r, g, b) => r | g == 0 || r | b == 0 || g | b == 0,\n            Color::Cyan => false,\n        }\n    }\n}\n\nfn main() {\n    let color = Color::Rgb(0, 0, 127);\n    match color {\n        Color::Red => println!(\"Red\"),\n        Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan => eprintln!(\"Not red\"),\n        //~^ wildcard_enum_match_arm\n    };\n    match color {\n        Color::Red => println!(\"Red\"),\n        _not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan => eprintln!(\"Not red\"),\n        //~^ wildcard_enum_match_arm\n    };\n    let _str = match color {\n        Color::Red => \"Red\".to_owned(),\n        not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan => format!(\"{:?}\", not_red),\n        //~^ wildcard_enum_match_arm\n    };\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Blue => {},\n        Color::Cyan => {},\n        c if c.is_monochrome() => {},\n        Color::Rgb(_, _, _) => {},\n    };\n    let _str = match color {\n        Color::Red => \"Red\",\n        c @ Color::Green | c @ Color::Blue | c @ Color::Rgb(_, _, _) | c @ Color::Cyan => \"Not red\",\n    };\n    match color {\n        Color::Rgb(r, _, _) if r > 0 => \"Some red\",\n        Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan => \"No red\",\n        //~^ wildcard_enum_match_arm\n    };\n    match color {\n        Color::Red | Color::Green | Color::Blue | Color::Cyan => {},\n        Color::Rgb(..) => {},\n    };\n    let x: u8 = unimplemented!();\n    match x {\n        0 => {},\n        140 => {},\n        _ => {},\n    };\n    // We need to use an enum not defined in this test because non_exhaustive is ignored for the\n    // purposes of dead code analysis within a crate.\n    let error_kind = ErrorKind::NotFound;\n    match error_kind {\n        ErrorKind::NotFound => {},\n        ErrorKind::PermissionDenied | _ => {},\n        //~^ wildcard_enum_match_arm\n    }\n    match error_kind {\n        ErrorKind::NotFound => {},\n        ErrorKind::PermissionDenied => {},\n        _ => {},\n    }\n\n    {\n        pub enum Enum {\n            A,\n            B,\n            C(u8),\n            D(u8, u8),\n            E { e: u8 },\n        };\n        match Enum::A {\n            Enum::A => (),\n            Enum::B | Enum::C(_) | Enum::D(..) | Enum::E { .. } => (),\n            //~^ wildcard_enum_match_arm\n        }\n    }\n\n    {\n        #![allow(clippy::manual_non_exhaustive)]\n        pub enum Enum {\n            A,\n            B,\n            #[doc(hidden)]\n            __Private,\n        }\n        match Enum::A {\n            Enum::A => (),\n            Enum::B | Enum::__Private => (),\n            //~^ wildcard_enum_match_arm\n        }\n    }\n}\n\nfn issue15091() {\n    enum Foo {\n        A,\n        B,\n        C,\n    }\n\n    match Foo::A {\n        Foo::A => {},\n        r#type @ Foo::B | r#type @ Foo::C => {},\n        //~^ wildcard_enum_match_arm\n    }\n}\n"
  },
  {
    "path": "tests/ui/wildcard_enum_match_arm.rs",
    "content": "//@aux-build:non-exhaustive-enum.rs\n#![deny(clippy::wildcard_enum_match_arm)]\n#![allow(dead_code, unreachable_code, unused_variables)]\n#![allow(\n    clippy::diverging_sub_expression,\n    clippy::single_match,\n    clippy::uninlined_format_args,\n    clippy::unnested_or_patterns,\n    clippy::wildcard_in_or_patterns\n)]\n\nextern crate non_exhaustive_enum;\n\nuse non_exhaustive_enum::ErrorKind;\n\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\nenum Color {\n    Red,\n    Green,\n    Blue,\n    Rgb(u8, u8, u8),\n    Cyan,\n}\n\nimpl Color {\n    fn is_monochrome(self) -> bool {\n        match self {\n            Color::Red | Color::Green | Color::Blue => true,\n            Color::Rgb(r, g, b) => r | g == 0 || r | b == 0 || g | b == 0,\n            Color::Cyan => false,\n        }\n    }\n}\n\nfn main() {\n    let color = Color::Rgb(0, 0, 127);\n    match color {\n        Color::Red => println!(\"Red\"),\n        _ => eprintln!(\"Not red\"),\n        //~^ wildcard_enum_match_arm\n    };\n    match color {\n        Color::Red => println!(\"Red\"),\n        _not_red => eprintln!(\"Not red\"),\n        //~^ wildcard_enum_match_arm\n    };\n    let _str = match color {\n        Color::Red => \"Red\".to_owned(),\n        not_red => format!(\"{:?}\", not_red),\n        //~^ wildcard_enum_match_arm\n    };\n    match color {\n        Color::Red => {},\n        Color::Green => {},\n        Color::Blue => {},\n        Color::Cyan => {},\n        c if c.is_monochrome() => {},\n        Color::Rgb(_, _, _) => {},\n    };\n    let _str = match color {\n        Color::Red => \"Red\",\n        c @ Color::Green | c @ Color::Blue | c @ Color::Rgb(_, _, _) | c @ Color::Cyan => \"Not red\",\n    };\n    match color {\n        Color::Rgb(r, _, _) if r > 0 => \"Some red\",\n        _ => \"No red\",\n        //~^ wildcard_enum_match_arm\n    };\n    match color {\n        Color::Red | Color::Green | Color::Blue | Color::Cyan => {},\n        Color::Rgb(..) => {},\n    };\n    let x: u8 = unimplemented!();\n    match x {\n        0 => {},\n        140 => {},\n        _ => {},\n    };\n    // We need to use an enum not defined in this test because non_exhaustive is ignored for the\n    // purposes of dead code analysis within a crate.\n    let error_kind = ErrorKind::NotFound;\n    match error_kind {\n        ErrorKind::NotFound => {},\n        _ => {},\n        //~^ wildcard_enum_match_arm\n    }\n    match error_kind {\n        ErrorKind::NotFound => {},\n        ErrorKind::PermissionDenied => {},\n        _ => {},\n    }\n\n    {\n        pub enum Enum {\n            A,\n            B,\n            C(u8),\n            D(u8, u8),\n            E { e: u8 },\n        };\n        match Enum::A {\n            Enum::A => (),\n            _ => (),\n            //~^ wildcard_enum_match_arm\n        }\n    }\n\n    {\n        #![allow(clippy::manual_non_exhaustive)]\n        pub enum Enum {\n            A,\n            B,\n            #[doc(hidden)]\n            __Private,\n        }\n        match Enum::A {\n            Enum::A => (),\n            _ => (),\n            //~^ wildcard_enum_match_arm\n        }\n    }\n}\n\nfn issue15091() {\n    enum Foo {\n        A,\n        B,\n        C,\n    }\n\n    match Foo::A {\n        Foo::A => {},\n        r#type => {},\n        //~^ wildcard_enum_match_arm\n    }\n}\n"
  },
  {
    "path": "tests/ui/wildcard_enum_match_arm.stderr",
    "content": "error: wildcard match will also match any future added variants\n  --> tests/ui/wildcard_enum_match_arm.rs:39:9\n   |\nLL |         _ => eprintln!(\"Not red\"),\n   |         ^ help: try: `Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan`\n   |\nnote: the lint level is defined here\n  --> tests/ui/wildcard_enum_match_arm.rs:2:9\n   |\nLL | #![deny(clippy::wildcard_enum_match_arm)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: wildcard match will also match any future added variants\n  --> tests/ui/wildcard_enum_match_arm.rs:44:9\n   |\nLL |         _not_red => eprintln!(\"Not red\"),\n   |         ^^^^^^^^ help: try: `_not_red @ Color::Green | _not_red @ Color::Blue | _not_red @ Color::Rgb(..) | _not_red @ Color::Cyan`\n\nerror: wildcard match will also match any future added variants\n  --> tests/ui/wildcard_enum_match_arm.rs:49:9\n   |\nLL |         not_red => format!(\"{:?}\", not_red),\n   |         ^^^^^^^ help: try: `not_red @ Color::Green | not_red @ Color::Blue | not_red @ Color::Rgb(..) | not_red @ Color::Cyan`\n\nerror: wildcard match will also match any future added variants\n  --> tests/ui/wildcard_enum_match_arm.rs:66:9\n   |\nLL |         _ => \"No red\",\n   |         ^ help: try: `Color::Red | Color::Green | Color::Blue | Color::Rgb(..) | Color::Cyan`\n\nerror: wildcard matches known variants and will also match future added variants\n  --> tests/ui/wildcard_enum_match_arm.rs:84:9\n   |\nLL |         _ => {},\n   |         ^ help: try: `ErrorKind::PermissionDenied | _`\n\nerror: wildcard match will also match any future added variants\n  --> tests/ui/wildcard_enum_match_arm.rs:103:13\n   |\nLL |             _ => (),\n   |             ^ help: try: `Enum::B | Enum::C(_) | Enum::D(..) | Enum::E { .. }`\n\nerror: wildcard match will also match any future added variants\n  --> tests/ui/wildcard_enum_match_arm.rs:118:13\n   |\nLL |             _ => (),\n   |             ^ help: try: `Enum::B | Enum::__Private`\n\nerror: wildcard match will also match any future added variants\n  --> tests/ui/wildcard_enum_match_arm.rs:133:9\n   |\nLL |         r#type => {},\n   |         ^^^^^^ help: try: `r#type @ Foo::B | r#type @ Foo::C`\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/wildcard_imports.fixed",
    "content": "//@edition:2015\n\n//@aux-build:wildcard_imports_helper.rs\n\n// the 2015 edition here is needed because edition 2018 changed the module system\n// (see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html) which means the lint\n// no longer detects some of the cases starting with Rust 2018.\n\n#![warn(clippy::wildcard_imports)]\n#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]\n#![warn(unused_imports)]\n\nextern crate wildcard_imports_helper;\n\nuse crate::fn_mod::foo;\n//~^ wildcard_imports\nuse crate::mod_mod::inner_mod;\n//~^ wildcard_imports\nuse crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod};\n//~^ wildcard_imports\n#[macro_use]\nuse crate::struct_mod::{A, inner_struct_mod};\n//~^ wildcard_imports\n\n#[allow(unused_imports)]\nuse wildcard_imports_helper::inner::inner_for_self_import;\nuse wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar;\n//~^ wildcard_imports\nuse wildcard_imports_helper::{extern_foo, ExternA};\n//~^ wildcard_imports\n\nuse std::io::prelude::*;\nuse wildcard_imports_helper::extern_prelude::v1::*;\nuse wildcard_imports_helper::prelude::v1::*;\n\nstruct ReadFoo;\n\nimpl Read for ReadFoo {\n    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {\n        Ok(0)\n    }\n}\n\nmod fn_mod {\n    pub fn foo() {}\n}\n\nmod mod_mod {\n    pub mod inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod multi_fn_mod {\n    pub fn multi_foo() {}\n    pub fn multi_bar() {}\n    pub fn multi_baz() {}\n    pub mod multi_inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod struct_mod {\n    pub struct A;\n    pub struct B;\n    pub mod inner_struct_mod {\n        pub struct C;\n    }\n\n    #[macro_export]\n    macro_rules! double_struct_import_test {\n        () => {\n            let _ = A;\n        };\n    }\n}\n\n// issue 9942\nmod underscore_mod {\n    // allow use of `deref` so that `clippy --fix` includes `Deref`.\n    #![allow(noop_method_call)]\n\n    mod exports_underscore {\n        pub use std::ops::Deref as _;\n        pub fn dummy() {}\n    }\n\n    mod exports_underscore_ish {\n        pub use std::ops::Deref as _Deref;\n        pub fn dummy() {}\n    }\n\n    fn does_not_lint() {\n        use self::exports_underscore::*;\n        let _ = (&0).deref();\n        dummy();\n    }\n\n    fn does_lint() {\n        use self::exports_underscore_ish::{_Deref, dummy};\n        //~^ wildcard_imports\n        let _ = (&0).deref();\n        dummy();\n    }\n}\n\nfn main() {\n    foo();\n    multi_foo();\n    multi_bar();\n    multi_inner_mod::foo();\n    inner_mod::foo();\n    extern_foo();\n    inner_extern_bar();\n\n    let _ = A;\n    let _ = inner_struct_mod::C;\n    let _ = ExternA;\n    let _ = PreludeModAnywhere;\n    let _ = ExternPreludeModAnywhere;\n\n    double_struct_import_test!();\n    double_struct_import_test!();\n}\n\nmod in_fn_test {\n    pub use self::inner_exported::*;\n    #[allow(unused_imports)]\n    pub(crate) use self::inner_exported2::*;\n\n    fn test_intern() {\n        use crate::fn_mod::foo;\n        //~^ wildcard_imports\n\n        foo();\n    }\n\n    fn test_extern() {\n        use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo};\n        //~^ wildcard_imports\n        use wildcard_imports_helper::{extern_foo, ExternA};\n        //~^ wildcard_imports\n\n        inner_for_self_import::inner_extern_foo();\n        inner_extern_foo();\n\n        extern_foo();\n\n        let _ = ExternA;\n    }\n\n    fn test_inner_nested() {\n        #[rustfmt::skip]\n        use self::{inner::inner_foo, inner2::inner_bar};\n        //~^ wildcard_imports\n        //~| wildcard_imports\n\n        inner_foo();\n        inner_bar();\n    }\n\n    fn test_extern_reexported() {\n        use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum};\n        //~^ wildcard_imports\n\n        extern_exported();\n        let _ = ExternExportedStruct;\n        let _ = ExternExportedEnum::A;\n    }\n\n    mod inner_exported {\n        pub fn exported() {}\n        pub struct ExportedStruct;\n        pub enum ExportedEnum {\n            A,\n        }\n    }\n\n    mod inner_exported2 {\n        pub(crate) fn exported2() {}\n    }\n\n    mod inner {\n        pub fn inner_foo() {}\n    }\n\n    mod inner2 {\n        pub fn inner_bar() {}\n    }\n}\n\nfn test_reexported() {\n    use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum};\n    //~^ wildcard_imports\n\n    exported();\n    let _ = ExportedStruct;\n    let _ = ExportedEnum::A;\n}\n\n#[rustfmt::skip]\nfn test_weird_formatting() {\n    use crate:: in_fn_test::exported;\n    //~^ wildcard_imports\n    use crate:: fn_mod::foo;\n\n    exported();\n    foo();\n}\n\nmod super_imports {\n    fn foofoo() {}\n\n    mod should_be_replaced {\n        use super::foofoo;\n        //~^ wildcard_imports\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass {\n        use super::*;\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_inside_function {\n        fn with_super_inside_function() {\n            use super::*;\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::*;\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod should_be_replaced_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::insidefoo;\n            //~^ wildcard_imports\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod use_explicit_should_be_replaced {\n        use crate::super_imports::foofoo;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod use_double_super_should_be_replaced {\n        mod inner {\n            use super::super::foofoo;\n            //~^ wildcard_imports\n\n            fn with_double_super() {\n                let _ = foofoo();\n            }\n        }\n    }\n\n    mod use_super_explicit_should_be_replaced {\n        use super::super::super_imports::foofoo;\n        //~^ wildcard_imports\n\n        fn with_super_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod attestation_should_be_replaced {\n        use super::foofoo;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/wildcard_imports.rs",
    "content": "//@edition:2015\n\n//@aux-build:wildcard_imports_helper.rs\n\n// the 2015 edition here is needed because edition 2018 changed the module system\n// (see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html) which means the lint\n// no longer detects some of the cases starting with Rust 2018.\n\n#![warn(clippy::wildcard_imports)]\n#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]\n#![warn(unused_imports)]\n\nextern crate wildcard_imports_helper;\n\nuse crate::fn_mod::*;\n//~^ wildcard_imports\nuse crate::mod_mod::*;\n//~^ wildcard_imports\nuse crate::multi_fn_mod::*;\n//~^ wildcard_imports\n#[macro_use]\nuse crate::struct_mod::*;\n//~^ wildcard_imports\n\n#[allow(unused_imports)]\nuse wildcard_imports_helper::inner::inner_for_self_import;\nuse wildcard_imports_helper::inner::inner_for_self_import::*;\n//~^ wildcard_imports\nuse wildcard_imports_helper::*;\n//~^ wildcard_imports\n\nuse std::io::prelude::*;\nuse wildcard_imports_helper::extern_prelude::v1::*;\nuse wildcard_imports_helper::prelude::v1::*;\n\nstruct ReadFoo;\n\nimpl Read for ReadFoo {\n    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {\n        Ok(0)\n    }\n}\n\nmod fn_mod {\n    pub fn foo() {}\n}\n\nmod mod_mod {\n    pub mod inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod multi_fn_mod {\n    pub fn multi_foo() {}\n    pub fn multi_bar() {}\n    pub fn multi_baz() {}\n    pub mod multi_inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod struct_mod {\n    pub struct A;\n    pub struct B;\n    pub mod inner_struct_mod {\n        pub struct C;\n    }\n\n    #[macro_export]\n    macro_rules! double_struct_import_test {\n        () => {\n            let _ = A;\n        };\n    }\n}\n\n// issue 9942\nmod underscore_mod {\n    // allow use of `deref` so that `clippy --fix` includes `Deref`.\n    #![allow(noop_method_call)]\n\n    mod exports_underscore {\n        pub use std::ops::Deref as _;\n        pub fn dummy() {}\n    }\n\n    mod exports_underscore_ish {\n        pub use std::ops::Deref as _Deref;\n        pub fn dummy() {}\n    }\n\n    fn does_not_lint() {\n        use self::exports_underscore::*;\n        let _ = (&0).deref();\n        dummy();\n    }\n\n    fn does_lint() {\n        use self::exports_underscore_ish::*;\n        //~^ wildcard_imports\n        let _ = (&0).deref();\n        dummy();\n    }\n}\n\nfn main() {\n    foo();\n    multi_foo();\n    multi_bar();\n    multi_inner_mod::foo();\n    inner_mod::foo();\n    extern_foo();\n    inner_extern_bar();\n\n    let _ = A;\n    let _ = inner_struct_mod::C;\n    let _ = ExternA;\n    let _ = PreludeModAnywhere;\n    let _ = ExternPreludeModAnywhere;\n\n    double_struct_import_test!();\n    double_struct_import_test!();\n}\n\nmod in_fn_test {\n    pub use self::inner_exported::*;\n    #[allow(unused_imports)]\n    pub(crate) use self::inner_exported2::*;\n\n    fn test_intern() {\n        use crate::fn_mod::*;\n        //~^ wildcard_imports\n\n        foo();\n    }\n\n    fn test_extern() {\n        use wildcard_imports_helper::inner::inner_for_self_import::{self, *};\n        //~^ wildcard_imports\n        use wildcard_imports_helper::*;\n        //~^ wildcard_imports\n\n        inner_for_self_import::inner_extern_foo();\n        inner_extern_foo();\n\n        extern_foo();\n\n        let _ = ExternA;\n    }\n\n    fn test_inner_nested() {\n        #[rustfmt::skip]\n        use self::{inner::*, inner2::*};\n        //~^ wildcard_imports\n        //~| wildcard_imports\n\n        inner_foo();\n        inner_bar();\n    }\n\n    fn test_extern_reexported() {\n        use wildcard_imports_helper::*;\n        //~^ wildcard_imports\n\n        extern_exported();\n        let _ = ExternExportedStruct;\n        let _ = ExternExportedEnum::A;\n    }\n\n    mod inner_exported {\n        pub fn exported() {}\n        pub struct ExportedStruct;\n        pub enum ExportedEnum {\n            A,\n        }\n    }\n\n    mod inner_exported2 {\n        pub(crate) fn exported2() {}\n    }\n\n    mod inner {\n        pub fn inner_foo() {}\n    }\n\n    mod inner2 {\n        pub fn inner_bar() {}\n    }\n}\n\nfn test_reexported() {\n    use crate::in_fn_test::*;\n    //~^ wildcard_imports\n\n    exported();\n    let _ = ExportedStruct;\n    let _ = ExportedEnum::A;\n}\n\n#[rustfmt::skip]\nfn test_weird_formatting() {\n    use crate:: in_fn_test::  * ;\n    //~^ wildcard_imports\n    use crate:: fn_mod::\n    //~^ wildcard_imports\n        *;\n\n    exported();\n    foo();\n}\n\nmod super_imports {\n    fn foofoo() {}\n\n    mod should_be_replaced {\n        use super::*;\n        //~^ wildcard_imports\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass {\n        use super::*;\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_inside_function {\n        fn with_super_inside_function() {\n            use super::*;\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::*;\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod should_be_replaced_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::*;\n            //~^ wildcard_imports\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod use_explicit_should_be_replaced {\n        use crate::super_imports::*;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod use_double_super_should_be_replaced {\n        mod inner {\n            use super::super::*;\n            //~^ wildcard_imports\n\n            fn with_double_super() {\n                let _ = foofoo();\n            }\n        }\n    }\n\n    mod use_super_explicit_should_be_replaced {\n        use super::super::super_imports::*;\n        //~^ wildcard_imports\n\n        fn with_super_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod attestation_should_be_replaced {\n        use super::*;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/wildcard_imports.stderr",
    "content": "error: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:15:5\n   |\nLL | use crate::fn_mod::*;\n   |     ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`\n   |\n   = note: `-D clippy::wildcard-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:17:5\n   |\nLL | use crate::mod_mod::*;\n   |     ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:19:5\n   |\nLL | use crate::multi_fn_mod::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:22:5\n   |\nLL | use crate::struct_mod::*;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:27:5\n   |\nLL | use wildcard_imports_helper::inner::inner_for_self_import::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:29:5\n   |\nLL | use wildcard_imports_helper::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:100:13\n   |\nLL |         use self::exports_underscore_ish::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `self::exports_underscore_ish::{_Deref, dummy}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:132:13\n   |\nLL |         use crate::fn_mod::*;\n   |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:139:75\n   |\nLL |         use wildcard_imports_helper::inner::inner_for_self_import::{self, *};\n   |                                                                           ^ help: try: `inner_extern_foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:141:13\n   |\nLL |         use wildcard_imports_helper::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:154:20\n   |\nLL |         use self::{inner::*, inner2::*};\n   |                    ^^^^^^^^ help: try: `inner::inner_foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:154:30\n   |\nLL |         use self::{inner::*, inner2::*};\n   |                              ^^^^^^^^^ help: try: `inner2::inner_bar`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:163:13\n   |\nLL |         use wildcard_imports_helper::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:193:9\n   |\nLL |     use crate::in_fn_test::*;\n   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:203:9\n   |\nLL |     use crate:: in_fn_test::  * ;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:205:9\n   |\nLL |       use crate:: fn_mod::\n   |  _________^\nLL | |\nLL | |         *;\n   | |_________^ help: try: `crate:: fn_mod::foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:217:13\n   |\nLL |         use super::*;\n   |             ^^^^^^^^ help: try: `super::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:256:17\n   |\nLL |             use super::*;\n   |                 ^^^^^^^^ help: try: `super::insidefoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:265:13\n   |\nLL |         use crate::super_imports::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:275:17\n   |\nLL |             use super::super::*;\n   |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:285:13\n   |\nLL |         use super::super::super_imports::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports.rs:294:13\n   |\nLL |         use super::*;\n   |             ^^^^^^^^ help: try: `super::foofoo`\n\nerror: aborting due to 22 previous errors\n\n"
  },
  {
    "path": "tests/ui/wildcard_imports_2021.edition2018.fixed",
    "content": "//@revisions: edition2018 edition2021\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n\n//@aux-build:wildcard_imports_helper.rs\n\n#![warn(clippy::wildcard_imports)]\n#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]\n#![warn(unused_imports)]\n\nextern crate wildcard_imports_helper;\n\nuse crate::fn_mod::foo;\n//~^ wildcard_imports\nuse crate::mod_mod::inner_mod;\n//~^ wildcard_imports\nuse crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod};\n//~^ wildcard_imports\nuse crate::struct_mod::{A, inner_struct_mod};\n//~^ wildcard_imports\n\n#[allow(unused_imports)]\nuse wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar;\n//~^ wildcard_imports\nuse wildcard_imports_helper::prelude::v1::*;\nuse wildcard_imports_helper::{extern_foo, ExternA};\n//~^ wildcard_imports\n\nuse std::io::prelude::*;\n\nstruct ReadFoo;\n\nimpl Read for ReadFoo {\n    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {\n        Ok(0)\n    }\n}\n\nmod fn_mod {\n    pub fn foo() {}\n}\n\nmod mod_mod {\n    pub mod inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod multi_fn_mod {\n    pub fn multi_foo() {}\n    pub fn multi_bar() {}\n    pub fn multi_baz() {}\n    pub mod multi_inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod struct_mod {\n    pub struct A;\n    pub struct B;\n    pub mod inner_struct_mod {\n        pub struct C;\n    }\n\n    #[macro_export]\n    macro_rules! double_struct_import_test {\n        () => {\n            let _ = A;\n        };\n    }\n}\n\n// issue 9942\nmod underscore_mod {\n    // allow use of `deref` so that `clippy --fix` includes `Deref`.\n    #![allow(noop_method_call)]\n\n    mod exports_underscore {\n        pub use std::ops::Deref as _;\n        pub fn dummy() {}\n    }\n\n    mod exports_underscore_ish {\n        pub use std::ops::Deref as _Deref;\n        pub fn dummy() {}\n    }\n\n    fn does_not_lint() {\n        use exports_underscore::*;\n        let _ = (&0).deref();\n        dummy();\n    }\n\n    fn does_lint() {\n        use exports_underscore_ish::{_Deref, dummy};\n        //~^ wildcard_imports\n        let _ = (&0).deref();\n        dummy();\n    }\n}\n\nfn main() {\n    foo();\n    multi_foo();\n    multi_bar();\n    multi_inner_mod::foo();\n    inner_mod::foo();\n    extern_foo();\n    inner_extern_bar();\n\n    let _ = A;\n    let _ = inner_struct_mod::C;\n    let _ = ExternA;\n    let _ = PreludeModAnywhere;\n\n    double_struct_import_test!();\n    double_struct_import_test!();\n}\n\nmod in_fn_test {\n    pub use self::inner_exported::*;\n    #[allow(unused_imports)]\n    pub(crate) use self::inner_exported2::*;\n\n    fn test_intern() {\n        use crate::fn_mod::foo;\n        //~^ wildcard_imports\n\n        foo();\n    }\n\n    fn test_extern() {\n        use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo};\n        //~^ wildcard_imports\n        use wildcard_imports_helper::{extern_foo, ExternA};\n        //~^ wildcard_imports\n\n        inner_for_self_import::inner_extern_foo();\n        inner_extern_foo();\n\n        extern_foo();\n\n        let _ = ExternA;\n    }\n\n    fn test_inner_nested() {\n        #[rustfmt::skip]\n        use self::{inner::inner_foo, inner2::inner_bar};\n        //~^ wildcard_imports\n        //~| wildcard_imports\n\n        inner_foo();\n        inner_bar();\n    }\n\n    fn test_extern_reexported() {\n        use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum};\n        //~^ wildcard_imports\n\n        extern_exported();\n        let _ = ExternExportedStruct;\n        let _ = ExternExportedEnum::A;\n    }\n\n    mod inner_exported {\n        pub fn exported() {}\n        pub struct ExportedStruct;\n        pub enum ExportedEnum {\n            A,\n        }\n    }\n\n    mod inner_exported2 {\n        pub(crate) fn exported2() {}\n    }\n\n    mod inner {\n        pub fn inner_foo() {}\n    }\n\n    mod inner2 {\n        pub fn inner_bar() {}\n    }\n}\n\nfn test_reexported() {\n    use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum};\n    //~^ wildcard_imports\n\n    exported();\n    let _ = ExportedStruct;\n    let _ = ExportedEnum::A;\n}\n\n#[rustfmt::skip]\nfn test_weird_formatting() {\n    use crate:: in_fn_test::exported;\n    //~^ wildcard_imports\n    use crate:: fn_mod::foo;\n\n    exported();\n    foo();\n}\n\nmod super_imports {\n    fn foofoo() {}\n\n    mod should_be_replaced {\n        use super::foofoo;\n        //~^ wildcard_imports\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass {\n        use super::*;\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_inside_function {\n        fn with_super_inside_function() {\n            use super::*;\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::*;\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod should_be_replaced_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::insidefoo;\n            //~^ wildcard_imports\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod use_explicit_should_be_replaced {\n        use crate::super_imports::foofoo;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod use_double_super_should_be_replaced {\n        mod inner {\n            use super::super::foofoo;\n            //~^ wildcard_imports\n\n            fn with_double_super() {\n                let _ = foofoo();\n            }\n        }\n    }\n\n    mod use_super_explicit_should_be_replaced {\n        use super::super::super_imports::foofoo;\n        //~^ wildcard_imports\n\n        fn with_super_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod attestation_should_be_replaced {\n        use super::foofoo;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/wildcard_imports_2021.edition2018.stderr",
    "content": "error: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:13:5\n   |\nLL | use crate::fn_mod::*;\n   |     ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`\n   |\n   = note: `-D clippy::wildcard-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:15:5\n   |\nLL | use crate::mod_mod::*;\n   |     ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:17:5\n   |\nLL | use crate::multi_fn_mod::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:19:5\n   |\nLL | use crate::struct_mod::*;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:23:5\n   |\nLL | use wildcard_imports_helper::inner::inner_for_self_import::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:26:5\n   |\nLL | use wildcard_imports_helper::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:95:13\n   |\nLL |         use exports_underscore_ish::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `exports_underscore_ish::{_Deref, dummy}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:126:13\n   |\nLL |         use crate::fn_mod::*;\n   |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:133:75\n   |\nLL |         use wildcard_imports_helper::inner::inner_for_self_import::{self, *};\n   |                                                                           ^ help: try: `inner_extern_foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:135:13\n   |\nLL |         use wildcard_imports_helper::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:148:20\n   |\nLL |         use self::{inner::*, inner2::*};\n   |                    ^^^^^^^^ help: try: `inner::inner_foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:148:30\n   |\nLL |         use self::{inner::*, inner2::*};\n   |                              ^^^^^^^^^ help: try: `inner2::inner_bar`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:157:13\n   |\nLL |         use wildcard_imports_helper::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:187:9\n   |\nLL |     use crate::in_fn_test::*;\n   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:197:9\n   |\nLL |     use crate:: in_fn_test::  * ;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:199:9\n   |\nLL |       use crate:: fn_mod::\n   |  _________^\nLL | |\nLL | |         *;\n   | |_________^ help: try: `crate:: fn_mod::foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:211:13\n   |\nLL |         use super::*;\n   |             ^^^^^^^^ help: try: `super::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:250:17\n   |\nLL |             use super::*;\n   |                 ^^^^^^^^ help: try: `super::insidefoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:259:13\n   |\nLL |         use crate::super_imports::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:269:17\n   |\nLL |             use super::super::*;\n   |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:279:13\n   |\nLL |         use super::super::super_imports::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:288:13\n   |\nLL |         use super::*;\n   |             ^^^^^^^^ help: try: `super::foofoo`\n\nerror: aborting due to 22 previous errors\n\n"
  },
  {
    "path": "tests/ui/wildcard_imports_2021.edition2021.fixed",
    "content": "//@revisions: edition2018 edition2021\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n\n//@aux-build:wildcard_imports_helper.rs\n\n#![warn(clippy::wildcard_imports)]\n#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]\n#![warn(unused_imports)]\n\nextern crate wildcard_imports_helper;\n\nuse crate::fn_mod::foo;\n//~^ wildcard_imports\nuse crate::mod_mod::inner_mod;\n//~^ wildcard_imports\nuse crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod};\n//~^ wildcard_imports\nuse crate::struct_mod::{A, inner_struct_mod};\n//~^ wildcard_imports\n\n#[allow(unused_imports)]\nuse wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar;\n//~^ wildcard_imports\nuse wildcard_imports_helper::prelude::v1::*;\nuse wildcard_imports_helper::{extern_foo, ExternA};\n//~^ wildcard_imports\n\nuse std::io::prelude::*;\n\nstruct ReadFoo;\n\nimpl Read for ReadFoo {\n    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {\n        Ok(0)\n    }\n}\n\nmod fn_mod {\n    pub fn foo() {}\n}\n\nmod mod_mod {\n    pub mod inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod multi_fn_mod {\n    pub fn multi_foo() {}\n    pub fn multi_bar() {}\n    pub fn multi_baz() {}\n    pub mod multi_inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod struct_mod {\n    pub struct A;\n    pub struct B;\n    pub mod inner_struct_mod {\n        pub struct C;\n    }\n\n    #[macro_export]\n    macro_rules! double_struct_import_test {\n        () => {\n            let _ = A;\n        };\n    }\n}\n\n// issue 9942\nmod underscore_mod {\n    // allow use of `deref` so that `clippy --fix` includes `Deref`.\n    #![allow(noop_method_call)]\n\n    mod exports_underscore {\n        pub use std::ops::Deref as _;\n        pub fn dummy() {}\n    }\n\n    mod exports_underscore_ish {\n        pub use std::ops::Deref as _Deref;\n        pub fn dummy() {}\n    }\n\n    fn does_not_lint() {\n        use exports_underscore::*;\n        let _ = (&0).deref();\n        dummy();\n    }\n\n    fn does_lint() {\n        use exports_underscore_ish::{_Deref, dummy};\n        //~^ wildcard_imports\n        let _ = (&0).deref();\n        dummy();\n    }\n}\n\nfn main() {\n    foo();\n    multi_foo();\n    multi_bar();\n    multi_inner_mod::foo();\n    inner_mod::foo();\n    extern_foo();\n    inner_extern_bar();\n\n    let _ = A;\n    let _ = inner_struct_mod::C;\n    let _ = ExternA;\n    let _ = PreludeModAnywhere;\n\n    double_struct_import_test!();\n    double_struct_import_test!();\n}\n\nmod in_fn_test {\n    pub use self::inner_exported::*;\n    #[allow(unused_imports)]\n    pub(crate) use self::inner_exported2::*;\n\n    fn test_intern() {\n        use crate::fn_mod::foo;\n        //~^ wildcard_imports\n\n        foo();\n    }\n\n    fn test_extern() {\n        use wildcard_imports_helper::inner::inner_for_self_import::{self, inner_extern_foo};\n        //~^ wildcard_imports\n        use wildcard_imports_helper::{extern_foo, ExternA};\n        //~^ wildcard_imports\n\n        inner_for_self_import::inner_extern_foo();\n        inner_extern_foo();\n\n        extern_foo();\n\n        let _ = ExternA;\n    }\n\n    fn test_inner_nested() {\n        #[rustfmt::skip]\n        use self::{inner::inner_foo, inner2::inner_bar};\n        //~^ wildcard_imports\n        //~| wildcard_imports\n\n        inner_foo();\n        inner_bar();\n    }\n\n    fn test_extern_reexported() {\n        use wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum};\n        //~^ wildcard_imports\n\n        extern_exported();\n        let _ = ExternExportedStruct;\n        let _ = ExternExportedEnum::A;\n    }\n\n    mod inner_exported {\n        pub fn exported() {}\n        pub struct ExportedStruct;\n        pub enum ExportedEnum {\n            A,\n        }\n    }\n\n    mod inner_exported2 {\n        pub(crate) fn exported2() {}\n    }\n\n    mod inner {\n        pub fn inner_foo() {}\n    }\n\n    mod inner2 {\n        pub fn inner_bar() {}\n    }\n}\n\nfn test_reexported() {\n    use crate::in_fn_test::{exported, ExportedStruct, ExportedEnum};\n    //~^ wildcard_imports\n\n    exported();\n    let _ = ExportedStruct;\n    let _ = ExportedEnum::A;\n}\n\n#[rustfmt::skip]\nfn test_weird_formatting() {\n    use crate:: in_fn_test::exported;\n    //~^ wildcard_imports\n    use crate:: fn_mod::foo;\n\n    exported();\n    foo();\n}\n\nmod super_imports {\n    fn foofoo() {}\n\n    mod should_be_replaced {\n        use super::foofoo;\n        //~^ wildcard_imports\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass {\n        use super::*;\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_inside_function {\n        fn with_super_inside_function() {\n            use super::*;\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::*;\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod should_be_replaced_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::insidefoo;\n            //~^ wildcard_imports\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod use_explicit_should_be_replaced {\n        use crate::super_imports::foofoo;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod use_double_super_should_be_replaced {\n        mod inner {\n            use super::super::foofoo;\n            //~^ wildcard_imports\n\n            fn with_double_super() {\n                let _ = foofoo();\n            }\n        }\n    }\n\n    mod use_super_explicit_should_be_replaced {\n        use super::super::super_imports::foofoo;\n        //~^ wildcard_imports\n\n        fn with_super_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod attestation_should_be_replaced {\n        use super::foofoo;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/wildcard_imports_2021.edition2021.stderr",
    "content": "error: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:13:5\n   |\nLL | use crate::fn_mod::*;\n   |     ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`\n   |\n   = note: `-D clippy::wildcard-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:15:5\n   |\nLL | use crate::mod_mod::*;\n   |     ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:17:5\n   |\nLL | use crate::multi_fn_mod::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_foo, multi_bar, multi_inner_mod}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:19:5\n   |\nLL | use crate::struct_mod::*;\n   |     ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:23:5\n   |\nLL | use wildcard_imports_helper::inner::inner_for_self_import::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:26:5\n   |\nLL | use wildcard_imports_helper::*;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:95:13\n   |\nLL |         use exports_underscore_ish::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `exports_underscore_ish::{_Deref, dummy}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:126:13\n   |\nLL |         use crate::fn_mod::*;\n   |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:133:75\n   |\nLL |         use wildcard_imports_helper::inner::inner_for_self_import::{self, *};\n   |                                                                           ^ help: try: `inner_extern_foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:135:13\n   |\nLL |         use wildcard_imports_helper::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_foo, ExternA}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:148:20\n   |\nLL |         use self::{inner::*, inner2::*};\n   |                    ^^^^^^^^ help: try: `inner::inner_foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:148:30\n   |\nLL |         use self::{inner::*, inner2::*};\n   |                              ^^^^^^^^^ help: try: `inner2::inner_bar`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:157:13\n   |\nLL |         use wildcard_imports_helper::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{extern_exported, ExternExportedStruct, ExternExportedEnum}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:187:9\n   |\nLL |     use crate::in_fn_test::*;\n   |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{exported, ExportedStruct, ExportedEnum}`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:197:9\n   |\nLL |     use crate:: in_fn_test::  * ;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:199:9\n   |\nLL |       use crate:: fn_mod::\n   |  _________^\nLL | |\nLL | |         *;\n   | |_________^ help: try: `crate:: fn_mod::foo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:211:13\n   |\nLL |         use super::*;\n   |             ^^^^^^^^ help: try: `super::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:250:17\n   |\nLL |             use super::*;\n   |                 ^^^^^^^^ help: try: `super::insidefoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:259:13\n   |\nLL |         use crate::super_imports::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:269:17\n   |\nLL |             use super::super::*;\n   |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:279:13\n   |\nLL |         use super::super::super_imports::*;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`\n\nerror: usage of wildcard import\n  --> tests/ui/wildcard_imports_2021.rs:288:13\n   |\nLL |         use super::*;\n   |             ^^^^^^^^ help: try: `super::foofoo`\n\nerror: aborting due to 22 previous errors\n\n"
  },
  {
    "path": "tests/ui/wildcard_imports_2021.rs",
    "content": "//@revisions: edition2018 edition2021\n//@[edition2018] edition:2018\n//@[edition2021] edition:2021\n\n//@aux-build:wildcard_imports_helper.rs\n\n#![warn(clippy::wildcard_imports)]\n#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]\n#![warn(unused_imports)]\n\nextern crate wildcard_imports_helper;\n\nuse crate::fn_mod::*;\n//~^ wildcard_imports\nuse crate::mod_mod::*;\n//~^ wildcard_imports\nuse crate::multi_fn_mod::*;\n//~^ wildcard_imports\nuse crate::struct_mod::*;\n//~^ wildcard_imports\n\n#[allow(unused_imports)]\nuse wildcard_imports_helper::inner::inner_for_self_import::*;\n//~^ wildcard_imports\nuse wildcard_imports_helper::prelude::v1::*;\nuse wildcard_imports_helper::*;\n//~^ wildcard_imports\n\nuse std::io::prelude::*;\n\nstruct ReadFoo;\n\nimpl Read for ReadFoo {\n    fn read(&mut self, _buf: &mut [u8]) -> std::io::Result<usize> {\n        Ok(0)\n    }\n}\n\nmod fn_mod {\n    pub fn foo() {}\n}\n\nmod mod_mod {\n    pub mod inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod multi_fn_mod {\n    pub fn multi_foo() {}\n    pub fn multi_bar() {}\n    pub fn multi_baz() {}\n    pub mod multi_inner_mod {\n        pub fn foo() {}\n    }\n}\n\nmod struct_mod {\n    pub struct A;\n    pub struct B;\n    pub mod inner_struct_mod {\n        pub struct C;\n    }\n\n    #[macro_export]\n    macro_rules! double_struct_import_test {\n        () => {\n            let _ = A;\n        };\n    }\n}\n\n// issue 9942\nmod underscore_mod {\n    // allow use of `deref` so that `clippy --fix` includes `Deref`.\n    #![allow(noop_method_call)]\n\n    mod exports_underscore {\n        pub use std::ops::Deref as _;\n        pub fn dummy() {}\n    }\n\n    mod exports_underscore_ish {\n        pub use std::ops::Deref as _Deref;\n        pub fn dummy() {}\n    }\n\n    fn does_not_lint() {\n        use exports_underscore::*;\n        let _ = (&0).deref();\n        dummy();\n    }\n\n    fn does_lint() {\n        use exports_underscore_ish::*;\n        //~^ wildcard_imports\n        let _ = (&0).deref();\n        dummy();\n    }\n}\n\nfn main() {\n    foo();\n    multi_foo();\n    multi_bar();\n    multi_inner_mod::foo();\n    inner_mod::foo();\n    extern_foo();\n    inner_extern_bar();\n\n    let _ = A;\n    let _ = inner_struct_mod::C;\n    let _ = ExternA;\n    let _ = PreludeModAnywhere;\n\n    double_struct_import_test!();\n    double_struct_import_test!();\n}\n\nmod in_fn_test {\n    pub use self::inner_exported::*;\n    #[allow(unused_imports)]\n    pub(crate) use self::inner_exported2::*;\n\n    fn test_intern() {\n        use crate::fn_mod::*;\n        //~^ wildcard_imports\n\n        foo();\n    }\n\n    fn test_extern() {\n        use wildcard_imports_helper::inner::inner_for_self_import::{self, *};\n        //~^ wildcard_imports\n        use wildcard_imports_helper::*;\n        //~^ wildcard_imports\n\n        inner_for_self_import::inner_extern_foo();\n        inner_extern_foo();\n\n        extern_foo();\n\n        let _ = ExternA;\n    }\n\n    fn test_inner_nested() {\n        #[rustfmt::skip]\n        use self::{inner::*, inner2::*};\n        //~^ wildcard_imports\n        //~| wildcard_imports\n\n        inner_foo();\n        inner_bar();\n    }\n\n    fn test_extern_reexported() {\n        use wildcard_imports_helper::*;\n        //~^ wildcard_imports\n\n        extern_exported();\n        let _ = ExternExportedStruct;\n        let _ = ExternExportedEnum::A;\n    }\n\n    mod inner_exported {\n        pub fn exported() {}\n        pub struct ExportedStruct;\n        pub enum ExportedEnum {\n            A,\n        }\n    }\n\n    mod inner_exported2 {\n        pub(crate) fn exported2() {}\n    }\n\n    mod inner {\n        pub fn inner_foo() {}\n    }\n\n    mod inner2 {\n        pub fn inner_bar() {}\n    }\n}\n\nfn test_reexported() {\n    use crate::in_fn_test::*;\n    //~^ wildcard_imports\n\n    exported();\n    let _ = ExportedStruct;\n    let _ = ExportedEnum::A;\n}\n\n#[rustfmt::skip]\nfn test_weird_formatting() {\n    use crate:: in_fn_test::  * ;\n    //~^ wildcard_imports\n    use crate:: fn_mod::\n    //~^ wildcard_imports\n        *;\n\n    exported();\n    foo();\n}\n\nmod super_imports {\n    fn foofoo() {}\n\n    mod should_be_replaced {\n        use super::*;\n        //~^ wildcard_imports\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass {\n        use super::*;\n\n        fn with_super() {\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_inside_function {\n        fn with_super_inside_function() {\n            use super::*;\n            let _ = foofoo();\n        }\n    }\n\n    #[cfg(test)]\n    mod test_should_pass_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::*;\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod should_be_replaced_further_inside {\n        fn insidefoo() {}\n        mod inner {\n            use super::*;\n            //~^ wildcard_imports\n            fn with_super() {\n                let _ = insidefoo();\n            }\n        }\n    }\n\n    mod use_explicit_should_be_replaced {\n        use crate::super_imports::*;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod use_double_super_should_be_replaced {\n        mod inner {\n            use super::super::*;\n            //~^ wildcard_imports\n\n            fn with_double_super() {\n                let _ = foofoo();\n            }\n        }\n    }\n\n    mod use_super_explicit_should_be_replaced {\n        use super::super::super_imports::*;\n        //~^ wildcard_imports\n\n        fn with_super_explicit() {\n            let _ = foofoo();\n        }\n    }\n\n    mod attestation_should_be_replaced {\n        use super::*;\n        //~^ wildcard_imports\n\n        fn with_explicit() {\n            let _ = foofoo();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/wildcard_imports_cfgtest.rs",
    "content": "//@check-pass\n//@compile-flags: --test\n\n#![warn(clippy::wildcard_imports)]\n#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]\n\n// Test for #10580, the lint should ignore it because of the crate's cfg test flag.\n\nfn foofoo() {}\n\nmod outer {\n    mod inner {\n        use super::super::*;\n        fn barbar() {\n            let _ = foofoo();\n        }\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui/write_literal.fixed",
    "content": "#![warn(clippy::write_literal)]\n#![allow(clippy::uninlined_format_args, unused_must_use)]\n\nuse std::io::Write;\n\nfn main() {\n    let mut v = Vec::new();\n\n    // these should be fine\n    write!(v, \"Hello\");\n    writeln!(v, \"Hello\");\n    let world = \"world\";\n    writeln!(v, \"Hello {}\", world);\n    writeln!(v, \"Hello {world}\", world = world);\n    writeln!(v, \"3 in hex is {:X}\", 3);\n    writeln!(v, \"2 + 1 = {:.4}\", 3);\n    writeln!(v, \"2 + 1 = {:5.4}\", 3);\n    writeln!(v, \"Debug test {:?}\", \"hello, world\");\n    writeln!(v, \"{0:8} {1:>8}\", \"hello\", \"world\");\n    writeln!(v, \"{1:8} {0:>8}\", \"hello\", \"world\");\n    writeln!(v, \"{foo:8} {bar:>8}\", foo = \"hello\", bar = \"world\");\n    writeln!(v, \"{bar:8} {foo:>8}\", foo = \"hello\", bar = \"world\");\n    writeln!(v, \"{number:>width$}\", number = 1, width = 6);\n    writeln!(v, \"{number:>0width$}\", number = 1, width = 6);\n    writeln!(v, \"{} of {:b} people know binary, the other half doesn't\", 1, 2);\n    writeln!(v, \"10 / 4 is {}\", 2.5);\n    writeln!(v, \"2 + 1 = {}\", 3);\n    writeln!(v, \"From expansion {}\", stringify!(not a string literal));\n\n    // these should throw warnings\n    write!(v, \"Hello world\");\n    //~^ write_literal\n\n    writeln!(v, \"Hello {} world\", world);\n    //~^ write_literal\n\n    writeln!(v, \"Hello world\");\n    //~^ write_literal\n\n    writeln!(v, \"a literal {:.4}\", 5);\n    //~^ write_literal\n\n    // positional args don't change the fact\n    // that we're using a literal -- this should\n    // throw a warning\n    writeln!(v, \"hello world\");\n    //~^ write_literal\n\n    writeln!(v, \"world hello\");\n    //~^ write_literal\n\n    // named args shouldn't change anything either\n    writeln!(v, \"hello world\");\n    //~^ write_literal\n\n    writeln!(v, \"world hello\");\n    //~^ write_literal\n\n    // #10128\n    writeln!(v, \"hello {0} world\", 2);\n    //~^ write_literal\n\n    writeln!(v, \"world {0} hello\", 2);\n    //~^ write_literal\n\n    writeln!(v, \"hello {0} {1}, {bar}\", 2, 3, bar = 4);\n    //~^ write_literal\n\n    writeln!(v, \"hello {0} {1}, world {2}\", 2, 3, 4);\n    //~^ write_literal\n}\n\nfn escaping() {\n    let mut v = Vec::new();\n\n    writeln!(v, \"{{hello}}\");\n    //~^ write_literal\n\n    writeln!(v, r\"{{hello}}\");\n    //~^ write_literal\n\n    writeln!(v, \"'\");\n    //~^ write_literal\n\n    writeln!(v, \"\\\"\");\n    //~^ write_literal\n\n    writeln!(v, r\"'\");\n    //~^ write_literal\n\n    writeln!(\n        v,\n        \"some hello \\\n        //~^ write_literal\n        world!\",\n    );\n    writeln!(\n        v,\n        \"some 1\\\n        2 \\\\ 3\",\n        //~^^^ write_literal\n    );\n    writeln!(v, \"\\\\\");\n    //~^ write_literal\n\n    writeln!(v, r\"\\\");\n    //~^ write_literal\n\n    writeln!(v, r#\"\\\"#);\n    //~^ write_literal\n\n    writeln!(v, \"\\\\\");\n    //~^ write_literal\n\n    writeln!(v, \"\\r\");\n    //~^ write_literal\n\n    // should not lint\n    writeln!(v, r\"{}\", \"\\r\");\n}\n\nfn issue_13959() {\n    let mut v = Vec::new();\n    writeln!(v, \"\\\"\");\n    //~^ write_literal\n    writeln!(\n        v,\n        \"\n        //~^ write_literal\n        foo\n        \\\\\n        \\\\\\\\\n        \\\"\n        \\\\\\\"\n        bar\n\"\n    );\n}\n\nfn issue_14930() {\n    let mut v = Vec::new();\n    writeln!(v, \"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n    //~^ write_literal\n    writeln!(v, \"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n    //~^ write_literal\n    writeln!(v, \"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n    //~^ write_literal\n    writeln!(v, \"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n    //~^ write_literal\n}\n"
  },
  {
    "path": "tests/ui/write_literal.rs",
    "content": "#![warn(clippy::write_literal)]\n#![allow(clippy::uninlined_format_args, unused_must_use)]\n\nuse std::io::Write;\n\nfn main() {\n    let mut v = Vec::new();\n\n    // these should be fine\n    write!(v, \"Hello\");\n    writeln!(v, \"Hello\");\n    let world = \"world\";\n    writeln!(v, \"Hello {}\", world);\n    writeln!(v, \"Hello {world}\", world = world);\n    writeln!(v, \"3 in hex is {:X}\", 3);\n    writeln!(v, \"2 + 1 = {:.4}\", 3);\n    writeln!(v, \"2 + 1 = {:5.4}\", 3);\n    writeln!(v, \"Debug test {:?}\", \"hello, world\");\n    writeln!(v, \"{0:8} {1:>8}\", \"hello\", \"world\");\n    writeln!(v, \"{1:8} {0:>8}\", \"hello\", \"world\");\n    writeln!(v, \"{foo:8} {bar:>8}\", foo = \"hello\", bar = \"world\");\n    writeln!(v, \"{bar:8} {foo:>8}\", foo = \"hello\", bar = \"world\");\n    writeln!(v, \"{number:>width$}\", number = 1, width = 6);\n    writeln!(v, \"{number:>0width$}\", number = 1, width = 6);\n    writeln!(v, \"{} of {:b} people know binary, the other half doesn't\", 1, 2);\n    writeln!(v, \"10 / 4 is {}\", 2.5);\n    writeln!(v, \"2 + 1 = {}\", 3);\n    writeln!(v, \"From expansion {}\", stringify!(not a string literal));\n\n    // these should throw warnings\n    write!(v, \"Hello {}\", \"world\");\n    //~^ write_literal\n\n    writeln!(v, \"Hello {} {}\", world, \"world\");\n    //~^ write_literal\n\n    writeln!(v, \"Hello {}\", \"world\");\n    //~^ write_literal\n\n    writeln!(v, \"{} {:.4}\", \"a literal\", 5);\n    //~^ write_literal\n\n    // positional args don't change the fact\n    // that we're using a literal -- this should\n    // throw a warning\n    writeln!(v, \"{0} {1}\", \"hello\", \"world\");\n    //~^ write_literal\n\n    writeln!(v, \"{1} {0}\", \"hello\", \"world\");\n    //~^ write_literal\n\n    // named args shouldn't change anything either\n    writeln!(v, \"{foo} {bar}\", foo = \"hello\", bar = \"world\");\n    //~^ write_literal\n\n    writeln!(v, \"{bar} {foo}\", foo = \"hello\", bar = \"world\");\n    //~^ write_literal\n\n    // #10128\n    writeln!(v, \"{0} {1} {2}\", \"hello\", 2, \"world\");\n    //~^ write_literal\n\n    writeln!(v, \"{2} {1} {0}\", \"hello\", 2, \"world\");\n    //~^ write_literal\n\n    writeln!(v, \"{0} {1} {2}, {bar}\", \"hello\", 2, 3, bar = 4);\n    //~^ write_literal\n\n    writeln!(v, \"{0} {1} {2}, {3} {4}\", \"hello\", 2, 3, \"world\", 4);\n    //~^ write_literal\n}\n\nfn escaping() {\n    let mut v = Vec::new();\n\n    writeln!(v, \"{}\", \"{hello}\");\n    //~^ write_literal\n\n    writeln!(v, r\"{}\", r\"{hello}\");\n    //~^ write_literal\n\n    writeln!(v, \"{}\", '\\'');\n    //~^ write_literal\n\n    writeln!(v, \"{}\", '\"');\n    //~^ write_literal\n\n    writeln!(v, r\"{}\", '\\'');\n    //~^ write_literal\n\n    writeln!(\n        v,\n        \"some {}\",\n        \"hello \\\n        //~^ write_literal\n        world!\",\n    );\n    writeln!(\n        v,\n        \"some {}\\\n        {} \\\\ {}\",\n        \"1\",\n        \"2\",\n        \"3\",\n        //~^^^ write_literal\n    );\n    writeln!(v, \"{}\", \"\\\\\");\n    //~^ write_literal\n\n    writeln!(v, r\"{}\", \"\\\\\");\n    //~^ write_literal\n\n    writeln!(v, r#\"{}\"#, \"\\\\\");\n    //~^ write_literal\n\n    writeln!(v, \"{}\", r\"\\\");\n    //~^ write_literal\n\n    writeln!(v, \"{}\", \"\\r\");\n    //~^ write_literal\n\n    // should not lint\n    writeln!(v, r\"{}\", \"\\r\");\n}\n\nfn issue_13959() {\n    let mut v = Vec::new();\n    writeln!(v, \"{}\", r#\"\"\"#);\n    //~^ write_literal\n    writeln!(\n        v,\n        \"{}\",\n        r#\"\n        //~^ write_literal\n        foo\n        \\\n        \\\\\n        \"\n        \\\"\n        bar\n\"#\n    );\n}\n\nfn issue_14930() {\n    let mut v = Vec::new();\n    writeln!(v, \"Hello {3} is {0:2$.1$}\", 0.01, 2, 3, \"x\");\n    //~^ write_literal\n    writeln!(v, \"Hello {2} is {0:3$.1$}\", 0.01, 2, \"x\", 3);\n    //~^ write_literal\n    writeln!(v, \"Hello {1} is {0:3$.2$}\", 0.01, \"x\", 2, 3);\n    //~^ write_literal\n    writeln!(v, \"Hello {0} is {1:3$.2$}\", \"x\", 0.01, 2, 3);\n    //~^ write_literal\n}\n"
  },
  {
    "path": "tests/ui/write_literal.stderr",
    "content": "error: literal with an empty format string\n  --> tests/ui/write_literal.rs:31:27\n   |\nLL |     write!(v, \"Hello {}\", \"world\");\n   |                           ^^^^^^^\n   |\n   = note: `-D clippy::write-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::write_literal)]`\nhelp: try\n   |\nLL -     write!(v, \"Hello {}\", \"world\");\nLL +     write!(v, \"Hello world\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:34:39\n   |\nLL |     writeln!(v, \"Hello {} {}\", world, \"world\");\n   |                                       ^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"Hello {} {}\", world, \"world\");\nLL +     writeln!(v, \"Hello {} world\", world);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:37:29\n   |\nLL |     writeln!(v, \"Hello {}\", \"world\");\n   |                             ^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"Hello {}\", \"world\");\nLL +     writeln!(v, \"Hello world\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:40:29\n   |\nLL |     writeln!(v, \"{} {:.4}\", \"a literal\", 5);\n   |                             ^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{} {:.4}\", \"a literal\", 5);\nLL +     writeln!(v, \"a literal {:.4}\", 5);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:46:28\n   |\nLL |     writeln!(v, \"{0} {1}\", \"hello\", \"world\");\n   |                            ^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{0} {1}\", \"hello\", \"world\");\nLL +     writeln!(v, \"hello world\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:49:28\n   |\nLL |     writeln!(v, \"{1} {0}\", \"hello\", \"world\");\n   |                            ^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{1} {0}\", \"hello\", \"world\");\nLL +     writeln!(v, \"world hello\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:53:38\n   |\nLL |     writeln!(v, \"{foo} {bar}\", foo = \"hello\", bar = \"world\");\n   |                                      ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{foo} {bar}\", foo = \"hello\", bar = \"world\");\nLL +     writeln!(v, \"hello world\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:56:38\n   |\nLL |     writeln!(v, \"{bar} {foo}\", foo = \"hello\", bar = \"world\");\n   |                                      ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{bar} {foo}\", foo = \"hello\", bar = \"world\");\nLL +     writeln!(v, \"world hello\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:60:32\n   |\nLL |     writeln!(v, \"{0} {1} {2}\", \"hello\", 2, \"world\");\n   |                                ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{0} {1} {2}\", \"hello\", 2, \"world\");\nLL +     writeln!(v, \"hello {0} world\", 2);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:63:32\n   |\nLL |     writeln!(v, \"{2} {1} {0}\", \"hello\", 2, \"world\");\n   |                                ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{2} {1} {0}\", \"hello\", 2, \"world\");\nLL +     writeln!(v, \"world {0} hello\", 2);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:66:39\n   |\nLL |     writeln!(v, \"{0} {1} {2}, {bar}\", \"hello\", 2, 3, bar = 4);\n   |                                       ^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{0} {1} {2}, {bar}\", \"hello\", 2, 3, bar = 4);\nLL +     writeln!(v, \"hello {0} {1}, {bar}\", 2, 3, bar = 4);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:69:41\n   |\nLL |     writeln!(v, \"{0} {1} {2}, {3} {4}\", \"hello\", 2, 3, \"world\", 4);\n   |                                         ^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{0} {1} {2}, {3} {4}\", \"hello\", 2, 3, \"world\", 4);\nLL +     writeln!(v, \"hello {0} {1}, world {2}\", 2, 3, 4);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:76:23\n   |\nLL |     writeln!(v, \"{}\", \"{hello}\");\n   |                       ^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{}\", \"{hello}\");\nLL +     writeln!(v, \"{{hello}}\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:79:24\n   |\nLL |     writeln!(v, r\"{}\", r\"{hello}\");\n   |                        ^^^^^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, r\"{}\", r\"{hello}\");\nLL +     writeln!(v, r\"{{hello}}\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:82:23\n   |\nLL |     writeln!(v, \"{}\", '\\'');\n   |                       ^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{}\", '\\'');\nLL +     writeln!(v, \"'\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:85:23\n   |\nLL |     writeln!(v, \"{}\", '\"');\n   |                       ^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{}\", '\"');\nLL +     writeln!(v, \"\\\"\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:88:24\n   |\nLL |     writeln!(v, r\"{}\", '\\'');\n   |                        ^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, r\"{}\", '\\'');\nLL +     writeln!(v, r\"'\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:94:9\n   |\nLL | /         \"hello \\\nLL | |\nLL | |         world!\",\n   | |_______________^\n   |\nhelp: try\n   |\nLL ~         \"some hello \\\nLL +\nLL ~         world!\",\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:102:9\n   |\nLL | /         \"1\",\nLL | |         \"2\",\nLL | |         \"3\",\n   | |___________^\n   |\nhelp: try\n   |\nLL ~         \"some 1\\\nLL ~         2 \\\\ 3\",\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:107:23\n   |\nLL |     writeln!(v, \"{}\", \"\\\\\");\n   |                       ^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{}\", \"\\\\\");\nLL +     writeln!(v, \"\\\\\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:110:24\n   |\nLL |     writeln!(v, r\"{}\", \"\\\\\");\n   |                        ^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, r\"{}\", \"\\\\\");\nLL +     writeln!(v, r\"\\\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:113:26\n   |\nLL |     writeln!(v, r#\"{}\"#, \"\\\\\");\n   |                          ^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, r#\"{}\"#, \"\\\\\");\nLL +     writeln!(v, r#\"\\\"#);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:116:23\n   |\nLL |     writeln!(v, \"{}\", r\"\\\");\n   |                       ^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{}\", r\"\\\");\nLL +     writeln!(v, \"\\\\\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:119:23\n   |\nLL |     writeln!(v, \"{}\", \"\\r\");\n   |                       ^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{}\", \"\\r\");\nLL +     writeln!(v, \"\\r\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:128:23\n   |\nLL |     writeln!(v, \"{}\", r#\"\"\"#);\n   |                       ^^^^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"{}\", r#\"\"\"#);\nLL +     writeln!(v, \"\\\"\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:133:9\n   |\nLL | /         r#\"\nLL | |\nLL | |         foo\nLL | |         \\\n...  |\nLL | |         bar\nLL | | \"#\n   | |__^\n   |\nhelp: try\n   |\nLL ~         \"\nLL +\nLL +         foo\nLL +         \\\\\nLL +         \\\\\\\\\nLL +         \\\"\nLL +         \\\\\\\"\nLL +         bar\nLL ~ \"\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:147:55\n   |\nLL |     writeln!(v, \"Hello {3} is {0:2$.1$}\", 0.01, 2, 3, \"x\");\n   |                                                       ^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"Hello {3} is {0:2$.1$}\", 0.01, 2, 3, \"x\");\nLL +     writeln!(v, \"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:149:52\n   |\nLL |     writeln!(v, \"Hello {2} is {0:3$.1$}\", 0.01, 2, \"x\", 3);\n   |                                                    ^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"Hello {2} is {0:3$.1$}\", 0.01, 2, \"x\", 3);\nLL +     writeln!(v, \"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:151:49\n   |\nLL |     writeln!(v, \"Hello {1} is {0:3$.2$}\", 0.01, \"x\", 2, 3);\n   |                                                 ^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"Hello {1} is {0:3$.2$}\", 0.01, \"x\", 2, 3);\nLL +     writeln!(v, \"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n   |\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal.rs:153:43\n   |\nLL |     writeln!(v, \"Hello {0} is {1:3$.2$}\", \"x\", 0.01, 2, 3);\n   |                                           ^^^\n   |\nhelp: try\n   |\nLL -     writeln!(v, \"Hello {0} is {1:3$.2$}\", \"x\", 0.01, 2, 3);\nLL +     writeln!(v, \"Hello x is {0:2$.1$}\", 0.01, 2, 3);\n   |\n\nerror: aborting due to 30 previous errors\n\n"
  },
  {
    "path": "tests/ui/write_literal_unfixable.rs",
    "content": "//@no-rustfix\n#![allow(unused_must_use)]\n#![warn(clippy::write_literal)]\n\nuse std::io::Write;\n\nfn escaping() {\n    let mut v = vec![];\n\n    writeln!(v, r\"{}\", '\"');\n    //~^ write_literal\n\n    // hard mode\n    writeln!(v, r#\"{}{}\"#, '#', '\"');\n    //~^ write_literal\n}\n"
  },
  {
    "path": "tests/ui/write_literal_unfixable.stderr",
    "content": "error: literal with an empty format string\n  --> tests/ui/write_literal_unfixable.rs:10:24\n   |\nLL |     writeln!(v, r\"{}\", '\"');\n   |                        ^^^\n   |\n   = note: `-D clippy::write-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::write_literal)]`\n\nerror: literal with an empty format string\n  --> tests/ui/write_literal_unfixable.rs:14:28\n   |\nLL |     writeln!(v, r#\"{}{}\"#, '#', '\"');\n   |                            ^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/write_with_newline.fixed",
    "content": "// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934\n\n#![allow(clippy::write_literal)]\n#![warn(clippy::write_with_newline)]\n\nuse std::io::Write;\n\nfn main() {\n    let mut v = Vec::new();\n\n    // These should fail\n    writeln!(v, \"Hello\");\n    //~^ write_with_newline\n\n    writeln!(v, \"Hello {}\", \"world\");\n    //~^ write_with_newline\n\n    writeln!(v, \"Hello {} {}\", \"world\", \"#2\");\n    //~^ write_with_newline\n\n    writeln!(v, \"{}\", 1265);\n    //~^ write_with_newline\n\n    writeln!(v);\n    //~^ write_with_newline\n\n    // These should be fine\n    write!(v, \"\");\n    write!(v, \"Hello\");\n    writeln!(v, \"Hello\");\n    writeln!(v, \"Hello\\n\");\n    writeln!(v, \"Hello {}\\n\", \"world\");\n    write!(v, \"Issue\\n{}\", 1265);\n    write!(v, \"{}\", 1265);\n    write!(v, \"\\n{}\", 1275);\n    write!(v, \"\\n\\n\");\n    write!(v, \"like eof\\n\\n\");\n    write!(v, \"Hello {} {}\\n\\n\", \"world\", \"#2\");\n    // #3126\n    writeln!(v, \"\\ndon't\\nwarn\\nfor\\nmultiple\\nnewlines\\n\");\n    // #3126\n    writeln!(v, \"\\nbla\\n\\n\");\n\n    // Escaping\n    // #3514\n    write!(v, \"\\\\n\");\n    writeln!(v, \"\\\\\");\n    //~^ write_with_newline\n\n    write!(v, \"\\\\\\\\n\");\n\n    // Raw strings\n    // #3778\n    write!(v, r\"\\n\");\n\n    // Literal newlines should also fail\n    writeln!(\n        //~^ write_with_newline\n        v\n    );\n    writeln!(\n        //~^ write_with_newline\n        v\n    );\n\n    // Don't warn on CRLF (#4208)\n    write!(v, \"\\r\\n\");\n    write!(v, \"foo\\r\\n\");\n    writeln!(v, \"\\\\r\");\n    //~^ write_with_newline\n\n    write!(v, \"foo\\rbar\\n\");\n\n    // Ignore expanded format strings\n    macro_rules! newline {\n        () => {\n            \"\\n\"\n        };\n    }\n    write!(v, newline!());\n}\n"
  },
  {
    "path": "tests/ui/write_with_newline.rs",
    "content": "// FIXME: Ideally these suggestions would be fixed via rustfix. Blocked by rust-lang/rust#53934\n\n#![allow(clippy::write_literal)]\n#![warn(clippy::write_with_newline)]\n\nuse std::io::Write;\n\nfn main() {\n    let mut v = Vec::new();\n\n    // These should fail\n    write!(v, \"Hello\\n\");\n    //~^ write_with_newline\n\n    write!(v, \"Hello {}\\n\", \"world\");\n    //~^ write_with_newline\n\n    write!(v, \"Hello {} {}\\n\", \"world\", \"#2\");\n    //~^ write_with_newline\n\n    write!(v, \"{}\\n\", 1265);\n    //~^ write_with_newline\n\n    write!(v, \"\\n\");\n    //~^ write_with_newline\n\n    // These should be fine\n    write!(v, \"\");\n    write!(v, \"Hello\");\n    writeln!(v, \"Hello\");\n    writeln!(v, \"Hello\\n\");\n    writeln!(v, \"Hello {}\\n\", \"world\");\n    write!(v, \"Issue\\n{}\", 1265);\n    write!(v, \"{}\", 1265);\n    write!(v, \"\\n{}\", 1275);\n    write!(v, \"\\n\\n\");\n    write!(v, \"like eof\\n\\n\");\n    write!(v, \"Hello {} {}\\n\\n\", \"world\", \"#2\");\n    // #3126\n    writeln!(v, \"\\ndon't\\nwarn\\nfor\\nmultiple\\nnewlines\\n\");\n    // #3126\n    writeln!(v, \"\\nbla\\n\\n\");\n\n    // Escaping\n    // #3514\n    write!(v, \"\\\\n\");\n    write!(v, \"\\\\\\n\");\n    //~^ write_with_newline\n\n    write!(v, \"\\\\\\\\n\");\n\n    // Raw strings\n    // #3778\n    write!(v, r\"\\n\");\n\n    // Literal newlines should also fail\n    write!(\n        //~^ write_with_newline\n        v,\n        \"\n\"\n    );\n    write!(\n        //~^ write_with_newline\n        v,\n        r\"\n\"\n    );\n\n    // Don't warn on CRLF (#4208)\n    write!(v, \"\\r\\n\");\n    write!(v, \"foo\\r\\n\");\n    write!(v, \"\\\\r\\n\");\n    //~^ write_with_newline\n\n    write!(v, \"foo\\rbar\\n\");\n\n    // Ignore expanded format strings\n    macro_rules! newline {\n        () => {\n            \"\\n\"\n        };\n    }\n    write!(v, newline!());\n}\n"
  },
  {
    "path": "tests/ui/write_with_newline.stderr",
    "content": "error: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:12:5\n   |\nLL |     write!(v, \"Hello\\n\");\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::write-with-newline` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::write_with_newline)]`\nhelp: use `writeln!` instead\n   |\nLL -     write!(v, \"Hello\\n\");\nLL +     writeln!(v, \"Hello\");\n   |\n\nerror: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:15:5\n   |\nLL |     write!(v, \"Hello {}\\n\", \"world\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `writeln!` instead\n   |\nLL -     write!(v, \"Hello {}\\n\", \"world\");\nLL +     writeln!(v, \"Hello {}\", \"world\");\n   |\n\nerror: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:18:5\n   |\nLL |     write!(v, \"Hello {} {}\\n\", \"world\", \"#2\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `writeln!` instead\n   |\nLL -     write!(v, \"Hello {} {}\\n\", \"world\", \"#2\");\nLL +     writeln!(v, \"Hello {} {}\", \"world\", \"#2\");\n   |\n\nerror: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:21:5\n   |\nLL |     write!(v, \"{}\\n\", 1265);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `writeln!` instead\n   |\nLL -     write!(v, \"{}\\n\", 1265);\nLL +     writeln!(v, \"{}\", 1265);\n   |\n\nerror: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:24:5\n   |\nLL |     write!(v, \"\\n\");\n   |     ^^^^^^^^^^^^^^^\n   |\nhelp: use `writeln!` instead\n   |\nLL -     write!(v, \"\\n\");\nLL +     writeln!(v);\n   |\n\nerror: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:47:5\n   |\nLL |     write!(v, \"\\\\\\n\");\n   |     ^^^^^^^^^^^^^^^^^\n   |\nhelp: use `writeln!` instead\n   |\nLL -     write!(v, \"\\\\\\n\");\nLL +     writeln!(v, \"\\\\\");\n   |\n\nerror: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:57:5\n   |\nLL | /     write!(\nLL | |\nLL | |         v,\nLL | |         \"\nLL | | \"\nLL | |     );\n   | |_____^\n   |\nhelp: use `writeln!` instead\n   |\nLL ~     writeln!(\nLL |\nLL ~         v\n   |\n\nerror: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:63:5\n   |\nLL | /     write!(\nLL | |\nLL | |         v,\nLL | |         r\"\nLL | | \"\nLL | |     );\n   | |_____^\n   |\nhelp: use `writeln!` instead\n   |\nLL ~     writeln!(\nLL |\nLL ~         v\n   |\n\nerror: using `write!()` with a format string that ends in a single newline\n  --> tests/ui/write_with_newline.rs:73:5\n   |\nLL |     write!(v, \"\\\\r\\n\");\n   |     ^^^^^^^^^^^^^^^^^^\n   |\nhelp: use `writeln!` instead\n   |\nLL -     write!(v, \"\\\\r\\n\");\nLL +     writeln!(v, \"\\\\r\");\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui/writeln_empty_string.fixed",
    "content": "#![allow(unused_must_use)]\n#![warn(clippy::writeln_empty_string)]\nuse std::io::Write;\n\nfn main() {\n    let mut v = Vec::new();\n\n    // These should fail\n    writeln!(v);\n    //~^ writeln_empty_string\n\n    let mut suggestion = Vec::new();\n    writeln!(suggestion);\n    //~^ writeln_empty_string\n\n    // These should be fine\n    writeln!(v);\n    writeln!(v, \" \");\n    write!(v, \"\");\n}\n"
  },
  {
    "path": "tests/ui/writeln_empty_string.rs",
    "content": "#![allow(unused_must_use)]\n#![warn(clippy::writeln_empty_string)]\nuse std::io::Write;\n\nfn main() {\n    let mut v = Vec::new();\n\n    // These should fail\n    writeln!(v, \"\");\n    //~^ writeln_empty_string\n\n    let mut suggestion = Vec::new();\n    writeln!(suggestion, \"\");\n    //~^ writeln_empty_string\n\n    // These should be fine\n    writeln!(v);\n    writeln!(v, \" \");\n    write!(v, \"\");\n}\n"
  },
  {
    "path": "tests/ui/writeln_empty_string.stderr",
    "content": "error: empty string literal in `writeln!`\n  --> tests/ui/writeln_empty_string.rs:9:5\n   |\nLL |     writeln!(v, \"\");\n   |     ^^^^^^^^^^----^\n   |               |\n   |               help: remove the empty string\n   |\n   = note: `-D clippy::writeln-empty-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::writeln_empty_string)]`\n\nerror: empty string literal in `writeln!`\n  --> tests/ui/writeln_empty_string.rs:13:5\n   |\nLL |     writeln!(suggestion, \"\");\n   |     ^^^^^^^^^^^^^^^^^^^----^\n   |                        |\n   |                        help: remove the empty string\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/writeln_empty_string_unfixable.rs",
    "content": "#![allow(unused_must_use)]\n#![warn(clippy::writeln_empty_string)]\n\nuse std::io::Write;\n\n// If there is a comment in the span of macro call, we don't provide an auto-fix suggestion.\n#[rustfmt::skip]\nfn issue_16251() {\n    let mut v = Vec::new();\n\n    writeln!(v, /* comment */ \"\");\n    //~^ writeln_empty_string\n\n    writeln!(v, \"\" /* comment */);\n    //~^ writeln_empty_string\n\n    //~v writeln_empty_string\n    writeln!(v,\n        \"\\\n            \\\n            \"\n\n    // there is a comment in the macro span regardless of its position\n\n    );\n}\n"
  },
  {
    "path": "tests/ui/writeln_empty_string_unfixable.stderr",
    "content": "error: empty string literal in `writeln!`\n  --> tests/ui/writeln_empty_string_unfixable.rs:11:5\n   |\nLL |     writeln!(v, /* comment */ \"\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: remove the empty string\n  --> tests/ui/writeln_empty_string_unfixable.rs:11:31\n   |\nLL |     writeln!(v, /* comment */ \"\");\n   |                               ^^\n   = note: `-D clippy::writeln-empty-string` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::writeln_empty_string)]`\n\nerror: empty string literal in `writeln!`\n  --> tests/ui/writeln_empty_string_unfixable.rs:14:5\n   |\nLL |     writeln!(v, \"\" /* comment */);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: remove the empty string\n  --> tests/ui/writeln_empty_string_unfixable.rs:14:17\n   |\nLL |     writeln!(v, \"\" /* comment */);\n   |                 ^^\n\nerror: empty string literal in `writeln!`\n  --> tests/ui/writeln_empty_string_unfixable.rs:18:5\n   |\nLL | /     writeln!(v,\nLL | |         \"\\\nLL | |             \\\nLL | |             \"\n...  |\nLL | |     );\n   | |_____^\n   |\nnote: remove the empty string\n  --> tests/ui/writeln_empty_string_unfixable.rs:19:9\n   |\nLL | /         \"\\\nLL | |             \\\nLL | |             \"\n   | |_____________^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/wrong_self_convention.rs",
    "content": "#![warn(clippy::wrong_self_convention)]\n#![allow(dead_code)]\n\nfn main() {}\n\n#[derive(Clone, Copy)]\nstruct Foo;\n\nimpl Foo {\n    fn as_i32(self) {}\n    fn as_u32(&self) {}\n    fn into_i32(self) {}\n    fn is_i32(self) {}\n    fn is_u32(&self) {}\n    fn to_i32(self) {}\n    fn from_i32(self) {}\n    //~^ wrong_self_convention\n\n    pub fn as_i64(self) {}\n    pub fn into_i64(self) {}\n    pub fn is_i64(self) {}\n    pub fn to_i64(self) {}\n    pub fn from_i64(self) {}\n    //~^ wrong_self_convention\n\n    // check whether the lint can be allowed at the function level\n    #[allow(clippy::wrong_self_convention)]\n    pub fn from_cake(self) {}\n\n    fn as_x<F: AsRef<Self>>(_: F) {}\n    fn as_y<F: AsRef<Foo>>(_: F) {}\n}\n\nstruct Bar;\n\nimpl Bar {\n    fn as_i32(self) {}\n    //~^ wrong_self_convention\n\n    fn as_u32(&self) {}\n    fn into_i32(&self) {}\n    //~^ wrong_self_convention\n\n    fn into_u32(self) {}\n    fn is_i32(self) {}\n    //~^ wrong_self_convention\n\n    fn is_u32(&self) {}\n    fn to_i32(self) {}\n    //~^ wrong_self_convention\n\n    fn to_u32(&self) {}\n    fn from_i32(self) {}\n    //~^ wrong_self_convention\n\n    pub fn as_i64(self) {}\n    //~^ wrong_self_convention\n\n    pub fn into_i64(&self) {}\n    //~^ wrong_self_convention\n\n    pub fn is_i64(self) {}\n    //~^ wrong_self_convention\n\n    pub fn to_i64(self) {}\n    //~^ wrong_self_convention\n\n    pub fn from_i64(self) {}\n    //~^ wrong_self_convention\n\n    // test for false positives\n    fn as_(self) {}\n    fn into_(&self) {}\n    fn is_(self) {}\n    fn to_(self) {}\n    fn from_(self) {}\n    fn to_mut(&mut self) {}\n}\n\n// Allow Box<Self>, Rc<Self>, Arc<Self> for methods that take conventionally take Self by value\n#[allow(clippy::boxed_local)]\nmod issue4293 {\n    use std::rc::Rc;\n    use std::sync::Arc;\n\n    struct T;\n\n    impl T {\n        fn into_s1(self: Box<Self>) {}\n        fn into_s2(self: Rc<Self>) {}\n        fn into_s3(self: Arc<Self>) {}\n\n        fn into_t1(self: Box<T>) {}\n        fn into_t2(self: Rc<T>) {}\n        fn into_t3(self: Arc<T>) {}\n    }\n}\n\n// False positive for async (see #4037)\nmod issue4037 {\n    pub struct Foo;\n    pub struct Bar;\n\n    impl Foo {\n        pub async fn into_bar(self) -> Bar {\n            Bar\n        }\n    }\n}\n\n// Lint also in trait definition (see #6307)\nmod issue6307 {\n    trait T: Sized {\n        fn as_i32(self) {}\n        //~^ wrong_self_convention\n\n        fn as_u32(&self) {}\n        fn into_i32(self) {}\n        fn into_i32_ref(&self) {}\n        //~^ wrong_self_convention\n\n        fn into_u32(self) {}\n        fn is_i32(self) {}\n        //~^ wrong_self_convention\n\n        fn is_u32(&self) {}\n        fn to_i32(self) {}\n        fn to_u32(&self) {}\n        fn from_i32(self) {}\n        //~^ wrong_self_convention\n\n        // check whether the lint can be allowed at the function level\n        #[allow(clippy::wrong_self_convention)]\n        fn from_cake(self) {}\n\n        // test for false positives\n        fn as_(self) {}\n        fn into_(&self) {}\n        fn is_(self) {}\n        fn to_(self) {}\n        fn from_(self) {}\n        fn to_mut(&mut self) {}\n    }\n\n    trait U {\n        fn as_i32(self);\n        //~^ wrong_self_convention\n\n        fn as_u32(&self);\n        fn into_i32(self);\n        fn into_i32_ref(&self);\n        //~^ wrong_self_convention\n\n        fn into_u32(self);\n        fn is_i32(self);\n        //~^ wrong_self_convention\n\n        fn is_u32(&self);\n        fn to_i32(self);\n        fn to_u32(&self);\n        fn from_i32(self);\n        //~^ wrong_self_convention\n\n        // check whether the lint can be allowed at the function level\n        #[allow(clippy::wrong_self_convention)]\n        fn from_cake(self);\n\n        // test for false positives\n        fn as_(self);\n        fn into_(&self);\n        fn is_(self);\n        fn to_(self);\n        fn from_(self);\n        fn to_mut(&mut self);\n    }\n\n    trait C: Copy {\n        fn as_i32(self);\n        fn as_u32(&self);\n        fn into_i32(self);\n        fn into_i32_ref(&self);\n        //~^ wrong_self_convention\n\n        fn into_u32(self);\n        fn is_i32(self);\n        fn is_u32(&self);\n        fn to_i32(self);\n        fn to_u32(&self);\n        fn from_i32(self);\n        //~^ wrong_self_convention\n\n        // check whether the lint can be allowed at the function level\n        #[allow(clippy::wrong_self_convention)]\n        fn from_cake(self);\n\n        // test for false positives\n        fn as_(self);\n        fn into_(&self);\n        fn is_(self);\n        fn to_(self);\n        fn from_(self);\n        fn to_mut(&mut self);\n    }\n}\n\nmod issue6727 {\n    #[derive(Clone, Copy)]\n    struct FooCopy;\n\n    impl FooCopy {\n        fn to_u64(self) -> u64 {\n            1\n        }\n        // trigger lint\n        fn to_u64_v2(&self) -> u64 {\n            //~^ wrong_self_convention\n\n            1\n        }\n    }\n\n    struct FooNoCopy;\n\n    impl FooNoCopy {\n        // trigger lint\n        fn to_u64(self) -> u64 {\n            //~^ wrong_self_convention\n\n            2\n        }\n        fn to_u64_v2(&self) -> u64 {\n            2\n        }\n    }\n}\n\npub mod issue8142 {\n    struct S;\n\n    impl S {\n        // Should not lint: \"no self at all\" is allowed.\n        fn is_forty_two(x: u32) -> bool {\n            x == 42\n        }\n\n        // Should not lint: &self is allowed.\n        fn is_test_code(&self) -> bool {\n            true\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/wrong_self_convention.stderr",
    "content": "error: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention.rs:16:17\n   |\nLL |     fn from_i32(self) {}\n   |                 ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`\n\nerror: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention.rs:23:21\n   |\nLL |     pub fn from_i64(self) {}\n   |                     ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `as_*` usually take `self` by reference or `self` by mutable reference\n  --> tests/ui/wrong_self_convention.rs:37:15\n   |\nLL |     fn as_i32(self) {}\n   |               ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `into_*` usually take `self` by value\n  --> tests/ui/wrong_self_convention.rs:41:17\n   |\nLL |     fn into_i32(&self) {}\n   |                 ^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`\n  --> tests/ui/wrong_self_convention.rs:45:15\n   |\nLL |     fn is_i32(self) {}\n   |               ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference\n  --> tests/ui/wrong_self_convention.rs:49:15\n   |\nLL |     fn to_i32(self) {}\n   |               ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention.rs:53:17\n   |\nLL |     fn from_i32(self) {}\n   |                 ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `as_*` usually take `self` by reference or `self` by mutable reference\n  --> tests/ui/wrong_self_convention.rs:56:19\n   |\nLL |     pub fn as_i64(self) {}\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `into_*` usually take `self` by value\n  --> tests/ui/wrong_self_convention.rs:59:21\n   |\nLL |     pub fn into_i64(&self) {}\n   |                     ^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`\n  --> tests/ui/wrong_self_convention.rs:62:19\n   |\nLL |     pub fn is_i64(self) {}\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference\n  --> tests/ui/wrong_self_convention.rs:65:19\n   |\nLL |     pub fn to_i64(self) {}\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention.rs:68:21\n   |\nLL |     pub fn from_i64(self) {}\n   |                     ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `as_*` usually take `self` by reference or `self` by mutable reference\n  --> tests/ui/wrong_self_convention.rs:114:19\n   |\nLL |         fn as_i32(self) {}\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `into_*` usually take `self` by value\n  --> tests/ui/wrong_self_convention.rs:119:25\n   |\nLL |         fn into_i32_ref(&self) {}\n   |                         ^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`\n  --> tests/ui/wrong_self_convention.rs:123:19\n   |\nLL |         fn is_i32(self) {}\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention.rs:129:21\n   |\nLL |         fn from_i32(self) {}\n   |                     ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `as_*` usually take `self` by reference or `self` by mutable reference\n  --> tests/ui/wrong_self_convention.rs:146:19\n   |\nLL |         fn as_i32(self);\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `into_*` usually take `self` by value\n  --> tests/ui/wrong_self_convention.rs:151:25\n   |\nLL |         fn into_i32_ref(&self);\n   |                         ^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`\n  --> tests/ui/wrong_self_convention.rs:155:19\n   |\nLL |         fn is_i32(self);\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention.rs:161:21\n   |\nLL |         fn from_i32(self);\n   |                     ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `into_*` usually take `self` by value\n  --> tests/ui/wrong_self_convention.rs:181:25\n   |\nLL |         fn into_i32_ref(&self);\n   |                         ^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention.rs:189:21\n   |\nLL |         fn from_i32(self);\n   |                     ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods with the following characteristics: (`to_*` and `self` type is `Copy`) usually take `self` by value\n  --> tests/ui/wrong_self_convention.rs:215:22\n   |\nLL |         fn to_u64_v2(&self) -> u64 {\n   |                      ^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference\n  --> tests/ui/wrong_self_convention.rs:226:19\n   |\nLL |         fn to_u64(self) -> u64 {\n   |                   ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: aborting due to 24 previous errors\n\n"
  },
  {
    "path": "tests/ui/wrong_self_convention2.rs",
    "content": "#![warn(clippy::wrong_self_convention)]\n#![allow(dead_code)]\n\nfn main() {}\n\nmod issue6983 {\n    pub struct Thing;\n    pub trait Trait {\n        fn to_thing(&self) -> Thing;\n    }\n\n    impl Trait for u8 {\n        // don't trigger, e.g. `ToString` from `std` requires `&self`\n        fn to_thing(&self) -> Thing {\n            Thing\n        }\n    }\n\n    trait ToU64 {\n        fn to_u64(self) -> u64;\n    }\n\n    struct FooNoCopy;\n    // don't trigger\n    impl ToU64 for FooNoCopy {\n        fn to_u64(self) -> u64 {\n            2\n        }\n    }\n}\n\nmod issue7032 {\n    trait Foo {\n        fn from_usize(x: usize) -> Self;\n    }\n    // don't trigger\n    impl Foo for usize {\n        fn from_usize(x: usize) -> Self {\n            x\n        }\n    }\n}\n\nmod issue7179 {\n    pub struct S(i32);\n\n    impl S {\n        // don't trigger (`s` is not `self`)\n        pub fn from_be(s: Self) -> Self {\n            S(i32::from_be(s.0))\n        }\n\n        // lint\n        pub fn from_be_self(self) -> Self {\n            //~^ wrong_self_convention\n\n            S(i32::from_be(self.0))\n        }\n    }\n\n    trait T {\n        // don't trigger (`s` is not `self`)\n        fn from_be(s: Self) -> Self;\n        // lint\n        fn from_be_self(self) -> Self;\n        //~^ wrong_self_convention\n    }\n\n    trait Foo: Sized {\n        fn as_byte_slice(slice: &[Self]) -> &[u8];\n    }\n}\n\nmod issue3414 {\n    struct CellLikeThing<T>(T);\n\n    impl<T> CellLikeThing<T> {\n        // don't trigger\n        fn into_inner(this: Self) -> T {\n            this.0\n        }\n    }\n\n    impl<T> std::ops::Deref for CellLikeThing<T> {\n        type Target = T;\n\n        fn deref(&self) -> &T {\n            &self.0\n        }\n    }\n}\n\n// don't trigger\nmod issue4546 {\n    use std::pin::Pin;\n\n    struct S;\n    impl S {\n        pub fn as_mut(self: Pin<&mut Self>) {}\n\n        pub fn as_other_thingy(self: Pin<&Self>) {}\n\n        pub fn is_other_thingy(self: Pin<&Self>) {}\n\n        pub fn to_mut(self: Pin<&mut Self>) {}\n\n        pub fn to_other_thingy(self: Pin<&Self>) {}\n    }\n}\n\nmod issue_8480_8513 {\n    struct Cat(String);\n\n    impl Cat {\n        fn is_animal(&mut self) -> bool {\n            todo!();\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/wrong_self_convention2.stderr",
    "content": "error: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention2.rs:54:29\n   |\nLL |         pub fn from_be_self(self) -> Self {\n   |                             ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`\n\nerror: methods called `from_*` usually take no `self`\n  --> tests/ui/wrong_self_convention2.rs:65:25\n   |\nLL |         fn from_be_self(self) -> Self;\n   |                         ^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/wrong_self_conventions_mut.rs",
    "content": "#![warn(clippy::wrong_self_convention)]\n#![allow(dead_code)]\n\nfn main() {}\n\nmod issue6758 {\n    pub enum Test<T> {\n        One(T),\n        Many(Vec<T>),\n    }\n\n    impl<T> Test<T> {\n        // If a method starts with `to_` and not ends with `_mut` it should expect `&self`\n        pub fn to_many(&mut self) -> Option<&mut [T]> {\n            //~^ wrong_self_convention\n\n            match self {\n                Self::Many(data) => Some(data),\n                _ => None,\n            }\n        }\n\n        // If a method starts with `to_` and ends with `_mut` it should expect `&mut self`\n        pub fn to_many_mut(&self) -> Option<&[T]> {\n            //~^ wrong_self_convention\n\n            match self {\n                Self::Many(data) => Some(data),\n                _ => None,\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui/wrong_self_conventions_mut.stderr",
    "content": "error: methods with the following characteristics: (`to_*` and `self` type is not `Copy`) usually take `self` by reference\n  --> tests/ui/wrong_self_conventions_mut.rs:14:24\n   |\nLL |         pub fn to_many(&mut self) -> Option<&mut [T]> {\n   |                        ^^^^^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n   = note: `-D clippy::wrong-self-convention` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wrong_self_convention)]`\n\nerror: methods with the following characteristics: (`to_*` and `*_mut`) usually take `self` by mutable reference\n  --> tests/ui/wrong_self_conventions_mut.rs:24:28\n   |\nLL |         pub fn to_many_mut(&self) -> Option<&[T]> {\n   |                            ^^^^^\n   |\n   = help: consider choosing a less ambiguous name\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/zero_div_zero.rs",
    "content": "#[allow(unused_variables, clippy::eq_op)]\n#[warn(clippy::zero_divided_by_zero)]\nfn main() {\n    let nan = 0.0 / 0.0;\n    //~^ zero_divided_by_zero\n\n    let f64_nan = 0.0 / 0.0f64;\n    //~^ zero_divided_by_zero\n\n    let other_f64_nan = 0.0f64 / 0.0;\n    //~^ zero_divided_by_zero\n\n    let one_more_f64_nan = 0.0f64 / 0.0f64;\n    //~^ zero_divided_by_zero\n\n    let zero = 0.0;\n    let other_zero = 0.0;\n    let other_nan = zero / other_zero; // fine - this lint doesn't propagate constants.\n    let not_nan = 2.0 / 0.0; // not an error: 2/0 = inf\n    let also_not_nan = 0.0 / 2.0; // not an error: 0/2 = 0\n}\n"
  },
  {
    "path": "tests/ui/zero_div_zero.stderr",
    "content": "error: constant division of `0.0` with `0.0` will always result in NaN\n  --> tests/ui/zero_div_zero.rs:4:15\n   |\nLL |     let nan = 0.0 / 0.0;\n   |               ^^^^^^^^^\n   |\n   = help: consider using `f64::NAN` if you would like a constant representing NaN\n   = note: `-D clippy::zero-divided-by-zero` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zero_divided_by_zero)]`\n\nerror: constant division of `0.0` with `0.0` will always result in NaN\n  --> tests/ui/zero_div_zero.rs:7:19\n   |\nLL |     let f64_nan = 0.0 / 0.0f64;\n   |                   ^^^^^^^^^^^^\n   |\n   = help: consider using `f64::NAN` if you would like a constant representing NaN\n\nerror: constant division of `0.0` with `0.0` will always result in NaN\n  --> tests/ui/zero_div_zero.rs:10:25\n   |\nLL |     let other_f64_nan = 0.0f64 / 0.0;\n   |                         ^^^^^^^^^^^^\n   |\n   = help: consider using `f64::NAN` if you would like a constant representing NaN\n\nerror: constant division of `0.0` with `0.0` will always result in NaN\n  --> tests/ui/zero_div_zero.rs:13:28\n   |\nLL |     let one_more_f64_nan = 0.0f64 / 0.0f64;\n   |                            ^^^^^^^^^^^^^^^\n   |\n   = help: consider using `f64::NAN` if you would like a constant representing NaN\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/zero_offset.rs",
    "content": "#[allow(clippy::borrow_as_ptr, clippy::ptr_offset_by_literal)]\nfn main() {\n    unsafe {\n        let m = &mut () as *mut ();\n        m.offset(0);\n        //~^ zst_offset\n\n        m.wrapping_add(0);\n        //~^ zst_offset\n\n        m.sub(0);\n        //~^ zst_offset\n\n        m.wrapping_sub(0);\n        //~^ zst_offset\n\n        let c = &() as *const ();\n        c.offset(0);\n        //~^ zst_offset\n\n        c.wrapping_add(0);\n        //~^ zst_offset\n\n        c.sub(0);\n        //~^ zst_offset\n\n        c.wrapping_sub(0);\n        //~^ zst_offset\n\n        let sized = &1 as *const i32;\n        sized.offset(0);\n    }\n}\n"
  },
  {
    "path": "tests/ui/zero_offset.stderr",
    "content": "error: offset calculation on zero-sized value\n  --> tests/ui/zero_offset.rs:5:9\n   |\nLL |         m.offset(0);\n   |         ^^^^^^^^^^^\n   |\n   = note: `#[deny(clippy::zst_offset)]` on by default\n\nerror: offset calculation on zero-sized value\n  --> tests/ui/zero_offset.rs:8:9\n   |\nLL |         m.wrapping_add(0);\n   |         ^^^^^^^^^^^^^^^^^\n\nerror: offset calculation on zero-sized value\n  --> tests/ui/zero_offset.rs:11:9\n   |\nLL |         m.sub(0);\n   |         ^^^^^^^^\n\nerror: offset calculation on zero-sized value\n  --> tests/ui/zero_offset.rs:14:9\n   |\nLL |         m.wrapping_sub(0);\n   |         ^^^^^^^^^^^^^^^^^\n\nerror: offset calculation on zero-sized value\n  --> tests/ui/zero_offset.rs:18:9\n   |\nLL |         c.offset(0);\n   |         ^^^^^^^^^^^\n\nerror: offset calculation on zero-sized value\n  --> tests/ui/zero_offset.rs:21:9\n   |\nLL |         c.wrapping_add(0);\n   |         ^^^^^^^^^^^^^^^^^\n\nerror: offset calculation on zero-sized value\n  --> tests/ui/zero_offset.rs:24:9\n   |\nLL |         c.sub(0);\n   |         ^^^^^^^^\n\nerror: offset calculation on zero-sized value\n  --> tests/ui/zero_offset.rs:27:9\n   |\nLL |         c.wrapping_sub(0);\n   |         ^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/zero_ptr.fixed",
    "content": "pub fn foo(_const: *const f32, _mut: *mut i64) {}\n\nfn main() {\n    let _ = std::ptr::null::<usize>();\n    //~^ zero_ptr\n    let _ = std::ptr::null_mut::<f64>();\n    //~^ zero_ptr\n    let _: *const u8 = std::ptr::null();\n    //~^ zero_ptr\n\n    foo(0 as _, 0 as _);\n    foo(std::ptr::null(), std::ptr::null_mut());\n    //~^ zero_ptr\n    //~| zero_ptr\n\n    let z = 0;\n    let _ = z as *const usize; // this is currently not caught\n}\n\nconst fn in_const_context() {\n    #[clippy::msrv = \"1.23\"]\n    let _: *const usize = 0 as *const _;\n    #[clippy::msrv = \"1.24\"]\n    let _: *const usize = std::ptr::null();\n    //~^ zero_ptr\n}\n"
  },
  {
    "path": "tests/ui/zero_ptr.rs",
    "content": "pub fn foo(_const: *const f32, _mut: *mut i64) {}\n\nfn main() {\n    let _ = 0 as *const usize;\n    //~^ zero_ptr\n    let _ = 0 as *mut f64;\n    //~^ zero_ptr\n    let _: *const u8 = 0 as *const _;\n    //~^ zero_ptr\n\n    foo(0 as _, 0 as _);\n    foo(0 as *const _, 0 as *mut _);\n    //~^ zero_ptr\n    //~| zero_ptr\n\n    let z = 0;\n    let _ = z as *const usize; // this is currently not caught\n}\n\nconst fn in_const_context() {\n    #[clippy::msrv = \"1.23\"]\n    let _: *const usize = 0 as *const _;\n    #[clippy::msrv = \"1.24\"]\n    let _: *const usize = 0 as *const _;\n    //~^ zero_ptr\n}\n"
  },
  {
    "path": "tests/ui/zero_ptr.stderr",
    "content": "error: `0 as *const _` detected\n  --> tests/ui/zero_ptr.rs:4:13\n   |\nLL |     let _ = 0 as *const usize;\n   |             ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::null::<usize>()`\n   |\n   = note: `-D clippy::zero-ptr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zero_ptr)]`\n\nerror: `0 as *mut _` detected\n  --> tests/ui/zero_ptr.rs:6:13\n   |\nLL |     let _ = 0 as *mut f64;\n   |             ^^^^^^^^^^^^^ help: try: `std::ptr::null_mut::<f64>()`\n\nerror: `0 as *const _` detected\n  --> tests/ui/zero_ptr.rs:8:24\n   |\nLL |     let _: *const u8 = 0 as *const _;\n   |                        ^^^^^^^^^^^^^ help: try: `std::ptr::null()`\n\nerror: `0 as *const _` detected\n  --> tests/ui/zero_ptr.rs:12:9\n   |\nLL |     foo(0 as *const _, 0 as *mut _);\n   |         ^^^^^^^^^^^^^ help: try: `std::ptr::null()`\n\nerror: `0 as *mut _` detected\n  --> tests/ui/zero_ptr.rs:12:24\n   |\nLL |     foo(0 as *const _, 0 as *mut _);\n   |                        ^^^^^^^^^^^ help: try: `std::ptr::null_mut()`\n\nerror: `0 as *const _` detected\n  --> tests/ui/zero_ptr.rs:24:27\n   |\nLL |     let _: *const usize = 0 as *const _;\n   |                           ^^^^^^^^^^^^^ help: try: `std::ptr::null()`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui/zero_ptr_no_std.fixed",
    "content": "#![crate_type = \"lib\"]\n#![no_std]\n#![deny(clippy::zero_ptr)]\n\npub fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    let _ = core::ptr::null::<usize>();\n    //~^ zero_ptr\n    let _ = core::ptr::null_mut::<f64>();\n    //~^ zero_ptr\n    let _: *const u8 = core::ptr::null();\n    //~^ zero_ptr\n    0\n}\n"
  },
  {
    "path": "tests/ui/zero_ptr_no_std.rs",
    "content": "#![crate_type = \"lib\"]\n#![no_std]\n#![deny(clippy::zero_ptr)]\n\npub fn main(_argc: isize, _argv: *const *const u8) -> isize {\n    let _ = 0 as *const usize;\n    //~^ zero_ptr\n    let _ = 0 as *mut f64;\n    //~^ zero_ptr\n    let _: *const u8 = 0 as *const _;\n    //~^ zero_ptr\n    0\n}\n"
  },
  {
    "path": "tests/ui/zero_ptr_no_std.stderr",
    "content": "error: `0 as *const _` detected\n  --> tests/ui/zero_ptr_no_std.rs:6:13\n   |\nLL |     let _ = 0 as *const usize;\n   |             ^^^^^^^^^^^^^^^^^ help: try: `core::ptr::null::<usize>()`\n   |\nnote: the lint level is defined here\n  --> tests/ui/zero_ptr_no_std.rs:3:9\n   |\nLL | #![deny(clippy::zero_ptr)]\n   |         ^^^^^^^^^^^^^^^^\n\nerror: `0 as *mut _` detected\n  --> tests/ui/zero_ptr_no_std.rs:8:13\n   |\nLL |     let _ = 0 as *mut f64;\n   |             ^^^^^^^^^^^^^ help: try: `core::ptr::null_mut::<f64>()`\n\nerror: `0 as *const _` detected\n  --> tests/ui/zero_ptr_no_std.rs:10:24\n   |\nLL |     let _: *const u8 = 0 as *const _;\n   |                        ^^^^^^^^^^^^^ help: try: `core::ptr::null()`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui/zero_repeat_side_effects.fixed",
    "content": "#![warn(clippy::zero_repeat_side_effects)]\n#![allow(\n    clippy::unnecessary_operation,\n    clippy::useless_vec,\n    clippy::needless_late_init,\n    clippy::single_match,\n    clippy::no_effect // only fires _after_ the fix\n)]\n\nfn f() -> i32 {\n    println!(\"side effect\");\n    10\n}\n\nfn main() {\n    const N: usize = 0;\n    const M: usize = 1;\n\n    // should trigger\n\n    // on arrays\n    f();\n    let a: [i32; 0] = [];\n    //~^ zero_repeat_side_effects\n    let mut b;\n    f();\n    b = [] as [i32; 0];\n    //~^ zero_repeat_side_effects\n\n    // on vecs\n    // vecs dont support inferring value of consts\n    f();\n    let c: std::vec::Vec<i32> = vec![];\n    //~^ zero_repeat_side_effects\n    let d;\n    f();\n    d = vec![] as std::vec::Vec<i32>;\n    //~^ zero_repeat_side_effects\n\n    // for macros\n    println!(\"side effect\");\n    let e: [(); 0] = [];\n    //~^ zero_repeat_side_effects\n\n    // for nested calls\n    { f() };\n    let g: [i32; 0] = [];\n    //~^ zero_repeat_side_effects\n\n    // as function param\n    drop({\n        f();\n        vec![] as std::vec::Vec<i32>\n    });\n    //~^ zero_repeat_side_effects\n\n    // when singled out/not part of assignment/local\n    f();\n    vec![] as std::vec::Vec<i32>;\n    //~^ zero_repeat_side_effects\n    f();\n    [] as [i32; 0];\n    //~^ zero_repeat_side_effects\n\n    // should not trigger\n    let a = [f(); N];\n    b = [f(); N];\n    [f(); N];\n\n    // on arrays with > 0 repeat\n    let a = [f(); 1];\n    let a = [f(); M];\n    let mut b;\n    b = [f(); 1];\n    b = [f(); M];\n\n    // on vecs with > 0 repeat\n    let c = vec![f(); 1];\n    let d;\n    d = vec![f(); 1];\n\n    // as function param\n    drop(vec![f(); 1]);\n}\n\nmacro_rules! LEN {\n    () => {\n        0\n    };\n}\n\nfn issue_13110() {\n    let _data = [f(); LEN!()];\n    const LENGTH: usize = LEN!();\n    let _data = [f(); LENGTH];\n}\n\n// TODO: consider moving the defintion+impl inside `issue_14681`\n// once https://github.com/rust-lang/rust/issues/146786 is fixed\n#[derive(Clone, Copy)]\nstruct S;\n\nimpl S {\n    fn new() -> Self {\n        println!(\"This is a side effect\");\n        S\n    }\n}\n\n// should not trigger on non-function calls\nfn issue_14681() {\n    fn foo<T>(_s: &[Option<T>]) {}\n\n    foo(&[Some(0i64); 0]);\n    foo(&[Some(Some(0i64)); 0]);\n    foo(&{\n        Some(f());\n        [] as [std::option::Option<i32>; 0]\n    });\n    //~^ zero_repeat_side_effects\n    foo(&{\n        Some(Some(S::new()));\n        [] as [std::option::Option<std::option::Option<S>>; 0]\n    });\n    //~^ zero_repeat_side_effects\n}\n\nfn issue_15824() {\n    fn f() {}\n\n    match 0 {\n        0 => {\n            f();\n            _ = [] as [(); 0]\n        },\n        //~^ zero_repeat_side_effects\n        _ => {},\n    }\n\n    let mut a = [(); 0];\n    match 0 {\n        0 => {\n            f();\n            a = [] as [(); 0]\n        },\n        //~^ zero_repeat_side_effects\n        _ => {},\n    }\n}\n"
  },
  {
    "path": "tests/ui/zero_repeat_side_effects.rs",
    "content": "#![warn(clippy::zero_repeat_side_effects)]\n#![allow(\n    clippy::unnecessary_operation,\n    clippy::useless_vec,\n    clippy::needless_late_init,\n    clippy::single_match,\n    clippy::no_effect // only fires _after_ the fix\n)]\n\nfn f() -> i32 {\n    println!(\"side effect\");\n    10\n}\n\nfn main() {\n    const N: usize = 0;\n    const M: usize = 1;\n\n    // should trigger\n\n    // on arrays\n    let a = [f(); 0];\n    //~^ zero_repeat_side_effects\n    let mut b;\n    b = [f(); 0];\n    //~^ zero_repeat_side_effects\n\n    // on vecs\n    // vecs dont support inferring value of consts\n    let c = vec![f(); 0];\n    //~^ zero_repeat_side_effects\n    let d;\n    d = vec![f(); 0];\n    //~^ zero_repeat_side_effects\n\n    // for macros\n    let e = [println!(\"side effect\"); 0];\n    //~^ zero_repeat_side_effects\n\n    // for nested calls\n    let g = [{ f() }; 0];\n    //~^ zero_repeat_side_effects\n\n    // as function param\n    drop(vec![f(); 0]);\n    //~^ zero_repeat_side_effects\n\n    // when singled out/not part of assignment/local\n    vec![f(); 0];\n    //~^ zero_repeat_side_effects\n    [f(); 0];\n    //~^ zero_repeat_side_effects\n\n    // should not trigger\n    let a = [f(); N];\n    b = [f(); N];\n    [f(); N];\n\n    // on arrays with > 0 repeat\n    let a = [f(); 1];\n    let a = [f(); M];\n    let mut b;\n    b = [f(); 1];\n    b = [f(); M];\n\n    // on vecs with > 0 repeat\n    let c = vec![f(); 1];\n    let d;\n    d = vec![f(); 1];\n\n    // as function param\n    drop(vec![f(); 1]);\n}\n\nmacro_rules! LEN {\n    () => {\n        0\n    };\n}\n\nfn issue_13110() {\n    let _data = [f(); LEN!()];\n    const LENGTH: usize = LEN!();\n    let _data = [f(); LENGTH];\n}\n\n// TODO: consider moving the defintion+impl inside `issue_14681`\n// once https://github.com/rust-lang/rust/issues/146786 is fixed\n#[derive(Clone, Copy)]\nstruct S;\n\nimpl S {\n    fn new() -> Self {\n        println!(\"This is a side effect\");\n        S\n    }\n}\n\n// should not trigger on non-function calls\nfn issue_14681() {\n    fn foo<T>(_s: &[Option<T>]) {}\n\n    foo(&[Some(0i64); 0]);\n    foo(&[Some(Some(0i64)); 0]);\n    foo(&[Some(f()); 0]);\n    //~^ zero_repeat_side_effects\n    foo(&[Some(Some(S::new())); 0]);\n    //~^ zero_repeat_side_effects\n}\n\nfn issue_15824() {\n    fn f() {}\n\n    match 0 {\n        0 => _ = [f(); 0],\n        //~^ zero_repeat_side_effects\n        _ => {},\n    }\n\n    let mut a = [(); 0];\n    match 0 {\n        0 => a = [f(); 0],\n        //~^ zero_repeat_side_effects\n        _ => {},\n    }\n}\n"
  },
  {
    "path": "tests/ui/zero_repeat_side_effects.stderr",
    "content": "error: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:22:5\n   |\nLL |     let a = [f(); 0];\n   |     ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::zero-repeat-side-effects` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`\nhelp: consider performing the side effect separately\n   |\nLL ~     f();\nLL +     let a: [i32; 0] = [];\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:25:5\n   |\nLL |     b = [f(); 0];\n   |     ^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     f();\nLL ~     b = [] as [i32; 0];\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:30:5\n   |\nLL |     let c = vec![f(); 0];\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     f();\nLL +     let c: std::vec::Vec<i32> = vec![];\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:33:5\n   |\nLL |     d = vec![f(); 0];\n   |     ^^^^^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     f();\nLL ~     d = vec![] as std::vec::Vec<i32>;\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:37:5\n   |\nLL |     let e = [println!(\"side effect\"); 0];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     println!(\"side effect\");\nLL +     let e: [(); 0] = [];\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:41:5\n   |\nLL |     let g = [{ f() }; 0];\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     { f() };\nLL +     let g: [i32; 0] = [];\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:45:10\n   |\nLL |     drop(vec![f(); 0]);\n   |          ^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     drop({\nLL +         f();\nLL +         vec![] as std::vec::Vec<i32>\nLL ~     });\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:49:5\n   |\nLL |     vec![f(); 0];\n   |     ^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     f();\nLL ~     vec![] as std::vec::Vec<i32>;\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:51:5\n   |\nLL |     [f(); 0];\n   |     ^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     f();\nLL ~     [] as [i32; 0];\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:105:10\n   |\nLL |     foo(&[Some(f()); 0]);\n   |          ^^^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     foo(&{\nLL +         Some(f());\nLL +         [] as [std::option::Option<i32>; 0]\nLL ~     });\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:107:10\n   |\nLL |     foo(&[Some(Some(S::new())); 0]);\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~     foo(&{\nLL +         Some(Some(S::new()));\nLL +         [] as [std::option::Option<std::option::Option<S>>; 0]\nLL ~     });\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:115:14\n   |\nLL |         0 => _ = [f(); 0],\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~         0 => {\nLL +             f();\nLL +             _ = [] as [(); 0]\nLL ~         },\n   |\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects.rs:122:14\n   |\nLL |         0 => a = [f(); 0],\n   |              ^^^^^^^^^^^^\n   |\nhelp: consider performing the side effect separately\n   |\nLL ~         0 => {\nLL +             f();\nLL +             a = [] as [(); 0]\nLL ~         },\n   |\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/zero_repeat_side_effects_never_pattern.fixed",
    "content": "#![warn(clippy::zero_repeat_side_effects)]\n#![allow(clippy::diverging_sub_expression)]\n#![feature(never_type)]\n\nfn issue_14998() {\n    // nameable type thanks to `never_type` being enabled, suggest\n    panic!();\n    let _data: [!; 0] = [];\n    //~^ zero_repeat_side_effects\n}\n"
  },
  {
    "path": "tests/ui/zero_repeat_side_effects_never_pattern.rs",
    "content": "#![warn(clippy::zero_repeat_side_effects)]\n#![allow(clippy::diverging_sub_expression)]\n#![feature(never_type)]\n\nfn issue_14998() {\n    // nameable type thanks to `never_type` being enabled, suggest\n    let _data = [panic!(); 0];\n    //~^ zero_repeat_side_effects\n}\n"
  },
  {
    "path": "tests/ui/zero_repeat_side_effects_never_pattern.stderr",
    "content": "error: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects_never_pattern.rs:7:5\n   |\nLL |     let _data = [panic!(); 0];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::zero-repeat-side-effects` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`\nhelp: consider performing the side effect separately\n   |\nLL ~     panic!();\nLL +     let _data: [!; 0] = [];\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui/zero_repeat_side_effects_unfixable.rs",
    "content": "//@no-rustfix\n#![warn(clippy::zero_repeat_side_effects)]\n#![expect(clippy::diverging_sub_expression)]\n\nfn issue_14998() {\n    // unnameable types, don't suggest\n    let _data = [|| 3i32; 0];\n    //~^ zero_repeat_side_effects\n\n    // unnameable type because `never_type` is not enabled, don't suggest\n    let _data = [panic!(); 0];\n    //~^ zero_repeat_side_effects\n}\n"
  },
  {
    "path": "tests/ui/zero_repeat_side_effects_unfixable.stderr",
    "content": "error: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects_unfixable.rs:7:5\n   |\nLL |     let _data = [|| 3i32; 0];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider performing the side effect separately\n   = note: `-D clippy::zero-repeat-side-effects` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zero_repeat_side_effects)]`\n\nerror: expression with side effects as the initial value in a zero-sized array initializer\n  --> tests/ui/zero_repeat_side_effects_unfixable.rs:11:5\n   |\nLL |     let _data = [panic!(); 0];\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider performing the side effect separately\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui/zero_sized_btreemap_values.rs",
    "content": "#![warn(clippy::zero_sized_map_values)]\nuse std::collections::BTreeMap;\n\nconst CONST_OK: Option<BTreeMap<String, usize>> = None;\nconst CONST_NOT_OK: Option<BTreeMap<String, ()>> = None;\n//~^ zero_sized_map_values\n\nstatic STATIC_OK: Option<BTreeMap<String, usize>> = None;\nstatic STATIC_NOT_OK: Option<BTreeMap<String, ()>> = None;\n//~^ zero_sized_map_values\n\ntype OkMap = BTreeMap<String, usize>;\ntype NotOkMap = BTreeMap<String, ()>;\n//~^ zero_sized_map_values\n\nenum TestEnum {\n    Ok(BTreeMap<String, usize>),\n    NotOk(BTreeMap<String, ()>),\n    //~^ zero_sized_map_values\n}\n\nstruct Test {\n    ok: BTreeMap<String, usize>,\n    not_ok: BTreeMap<String, ()>,\n    //~^ zero_sized_map_values\n    also_not_ok: Vec<BTreeMap<usize, ()>>,\n    //~^ zero_sized_map_values\n}\n\ntrait TestTrait {\n    type Output;\n\n    fn produce_output() -> Self::Output;\n\n    fn weird_map(&self, map: BTreeMap<usize, ()>);\n    //~^ zero_sized_map_values\n}\n\nimpl Test {\n    fn ok(&self) -> BTreeMap<String, usize> {\n        todo!()\n    }\n\n    fn not_ok(&self) -> BTreeMap<String, ()> {\n        //~^ zero_sized_map_values\n\n        todo!()\n    }\n}\n\nimpl TestTrait for Test {\n    type Output = BTreeMap<String, ()>;\n\n    fn produce_output() -> Self::Output {\n        todo!();\n    }\n\n    fn weird_map(&self, map: BTreeMap<usize, ()>) {\n        todo!();\n    }\n}\n\nfn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {\n    //~^ zero_sized_map_values\n    //~| zero_sized_map_values\n\n    todo!();\n}\n\nfn test2(map: BTreeMap<String, usize>, key: &str) -> BTreeMap<String, usize> {\n    todo!();\n}\n\nfn main() {\n    let _: BTreeMap<String, ()> = BTreeMap::new();\n    //~^ zero_sized_map_values\n    //~| zero_sized_map_values\n\n    let _: BTreeMap<String, usize> = BTreeMap::new();\n\n    let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect();\n    //~^ zero_sized_map_values\n}\n"
  },
  {
    "path": "tests/ui/zero_sized_btreemap_values.stderr",
    "content": "error: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:5:28\n   |\nLL | const CONST_NOT_OK: Option<BTreeMap<String, ()>> = None;\n   |                            ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n   = note: `-D clippy::zero-sized-map-values` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zero_sized_map_values)]`\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:9:30\n   |\nLL | static STATIC_NOT_OK: Option<BTreeMap<String, ()>> = None;\n   |                              ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:13:17\n   |\nLL | type NotOkMap = BTreeMap<String, ()>;\n   |                 ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:18:11\n   |\nLL |     NotOk(BTreeMap<String, ()>),\n   |           ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:24:13\n   |\nLL |     not_ok: BTreeMap<String, ()>,\n   |             ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:26:22\n   |\nLL |     also_not_ok: Vec<BTreeMap<usize, ()>>,\n   |                      ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:35:30\n   |\nLL |     fn weird_map(&self, map: BTreeMap<usize, ()>);\n   |                              ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:44:25\n   |\nLL |     fn not_ok(&self) -> BTreeMap<String, ()> {\n   |                         ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:63:14\n   |\nLL | fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {\n   |              ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:63:50\n   |\nLL | fn test(map: BTreeMap<String, ()>, key: &str) -> BTreeMap<String, ()> {\n   |                                                  ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:75:35\n   |\nLL |     let _: BTreeMap<String, ()> = BTreeMap::new();\n   |                                   ^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:75:12\n   |\nLL |     let _: BTreeMap<String, ()> = BTreeMap::new();\n   |            ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_btreemap_values.rs:81:12\n   |\nLL |     let _: BTreeMap<_, _> = std::iter::empty::<(String, ())>().collect();\n   |            ^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui/zero_sized_hashmap_values.rs",
    "content": "#![warn(clippy::zero_sized_map_values)]\nuse std::collections::HashMap;\n\nconst CONST_OK: Option<HashMap<String, usize>> = None;\nconst CONST_NOT_OK: Option<HashMap<String, ()>> = None;\n//~^ zero_sized_map_values\n\nstatic STATIC_OK: Option<HashMap<String, usize>> = None;\nstatic STATIC_NOT_OK: Option<HashMap<String, ()>> = None;\n//~^ zero_sized_map_values\n\ntype OkMap = HashMap<String, usize>;\ntype NotOkMap = HashMap<String, ()>;\n//~^ zero_sized_map_values\n\nenum TestEnum {\n    Ok(HashMap<String, usize>),\n    NotOk(HashMap<String, ()>),\n    //~^ zero_sized_map_values\n}\n\nstruct Test {\n    ok: HashMap<String, usize>,\n    not_ok: HashMap<String, ()>,\n    //~^ zero_sized_map_values\n    also_not_ok: Vec<HashMap<usize, ()>>,\n    //~^ zero_sized_map_values\n}\n\ntrait TestTrait {\n    type Output;\n\n    fn produce_output() -> Self::Output;\n\n    fn weird_map(&self, map: HashMap<usize, ()>);\n    //~^ zero_sized_map_values\n}\n\nimpl Test {\n    fn ok(&self) -> HashMap<String, usize> {\n        todo!()\n    }\n\n    fn not_ok(&self) -> HashMap<String, ()> {\n        //~^ zero_sized_map_values\n\n        todo!()\n    }\n}\n\nimpl TestTrait for Test {\n    type Output = HashMap<String, ()>;\n\n    fn produce_output() -> Self::Output {\n        todo!();\n    }\n\n    fn weird_map(&self, map: HashMap<usize, ()>) {\n        todo!();\n    }\n}\n\nfn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {\n    //~^ zero_sized_map_values\n    //~| zero_sized_map_values\n\n    todo!();\n}\n\nfn test2(map: HashMap<String, usize>, key: &str) -> HashMap<String, usize> {\n    todo!();\n}\n\nfn issue14822() {\n    trait Trait {\n        type T;\n    }\n    struct S<T: Trait>(T::T);\n\n    // The `delay_bug` happens when evaluating the pointer metadata of `S<T>` which depends on\n    // whether `T::T` is `Sized`. Since the type alias doesn't have a trait bound of `T: Trait`\n    // evaluating `T::T: Sized` ultimately fails with `NoSolution`.\n    type A<T> = HashMap<u32, *const S<T>>;\n    type B<T> = HashMap<u32, S<T>>;\n\n    enum E {}\n    impl Trait for E {\n        type T = ();\n    }\n    type C = HashMap<u32, *const S<E>>;\n    type D = HashMap<u32, S<E>>;\n    //~^ zero_sized_map_values\n}\n\nfn issue15429() {\n    struct E<'a>(&'a [E<'a>]);\n\n    // The assertion error happens when the type being evaluated has escaping bound vars\n    // as it cannot be wrapped in a dummy binder during size computation.\n    type F = dyn for<'a> FnOnce(HashMap<u32, E<'a>>) -> u32;\n}\n\nfn main() {\n    let _: HashMap<String, ()> = HashMap::new();\n    //~^ zero_sized_map_values\n    //~| zero_sized_map_values\n\n    let _: HashMap<String, usize> = HashMap::new();\n\n    let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect();\n    //~^ zero_sized_map_values\n}\n"
  },
  {
    "path": "tests/ui/zero_sized_hashmap_values.stderr",
    "content": "error: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:5:28\n   |\nLL | const CONST_NOT_OK: Option<HashMap<String, ()>> = None;\n   |                            ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n   = note: `-D clippy::zero-sized-map-values` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zero_sized_map_values)]`\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:9:30\n   |\nLL | static STATIC_NOT_OK: Option<HashMap<String, ()>> = None;\n   |                              ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:13:17\n   |\nLL | type NotOkMap = HashMap<String, ()>;\n   |                 ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:18:11\n   |\nLL |     NotOk(HashMap<String, ()>),\n   |           ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:24:13\n   |\nLL |     not_ok: HashMap<String, ()>,\n   |             ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:26:22\n   |\nLL |     also_not_ok: Vec<HashMap<usize, ()>>,\n   |                      ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:35:30\n   |\nLL |     fn weird_map(&self, map: HashMap<usize, ()>);\n   |                              ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:44:25\n   |\nLL |     fn not_ok(&self) -> HashMap<String, ()> {\n   |                         ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:63:14\n   |\nLL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {\n   |              ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:63:49\n   |\nLL | fn test(map: HashMap<String, ()>, key: &str) -> HashMap<String, ()> {\n   |                                                 ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:91:14\n   |\nLL |     type D = HashMap<u32, S<E>>;\n   |              ^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:104:34\n   |\nLL |     let _: HashMap<String, ()> = HashMap::new();\n   |                                  ^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:104:12\n   |\nLL |     let _: HashMap<String, ()> = HashMap::new();\n   |            ^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: map with zero-sized value type\n  --> tests/ui/zero_sized_hashmap_values.rs:110:12\n   |\nLL |     let _: HashMap<_, _> = std::iter::empty::<(String, ())>().collect();\n   |            ^^^^^^^^^^^^^\n   |\n   = help: consider using a set instead\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui/zombie_processes.rs",
    "content": "#![warn(clippy::zombie_processes)]\n#![allow(clippy::if_same_then_else, clippy::ifs_same_cond, clippy::needless_return)]\n\nuse std::process::{Child, Command, ExitStatus};\n\nfn main() {\n    {\n        // Check that #[expect] works\n        #[expect(clippy::zombie_processes)]\n        let mut x = Command::new(\"\").spawn().unwrap();\n    }\n\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        //~^ zombie_processes\n\n        x.kill();\n        x.id();\n    }\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        x.wait().unwrap(); // OK\n    }\n    {\n        let x = Command::new(\"\").spawn().unwrap();\n        x.wait_with_output().unwrap(); // OK\n    }\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        x.try_wait().unwrap(); // OK\n    }\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        let mut r = &mut x;\n        r.wait().unwrap(); // OK, not calling `.wait()` directly on `x` but through `r` -> `x`\n    }\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        process_child(x); // OK, other function might call `.wait()` so assume it does\n    }\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        //~^ zombie_processes\n\n        let v = &x;\n        // (allow shared refs is fine because one cannot call `.wait()` through that)\n    }\n\n    // https://github.com/rust-lang/rust-clippy/pull/11476#issuecomment-1718456033\n    // Unconditionally exiting the process in various ways (should not lint)\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        std::process::exit(0);\n    }\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        std::process::abort(); // same as above, but abort instead of exit\n    }\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        if true { /* nothing */ }\n        std::process::abort(); // still unconditionally exits\n    }\n\n    // Conditionally exiting\n    // It should assume that it might not exit and still lint\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        //~^ zombie_processes\n\n        if true {\n            std::process::exit(0);\n        }\n    }\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        //~^ zombie_processes\n\n        if true {\n            while false {}\n            // Calling `exit()` after leaving a while loop should still be linted.\n            std::process::exit(0);\n        }\n    }\n\n    {\n        let mut x = { Command::new(\"\").spawn().unwrap() };\n        x.wait().unwrap();\n    }\n\n    {\n        struct S {\n            c: Child,\n        }\n\n        let mut s = S {\n            c: Command::new(\"\").spawn().unwrap(),\n        };\n        s.c.wait().unwrap();\n    }\n\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        //~^ zombie_processes\n\n        if true {\n            return;\n        }\n        x.wait().unwrap();\n    }\n\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        //~^ zombie_processes\n\n        if true {\n            x.wait().unwrap();\n        }\n    }\n\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        //~^ zombie_processes\n\n        if true {\n            x.wait().unwrap();\n        } else {\n            // this else block exists to test the other help message\n        }\n    }\n\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        //~^ zombie_processes\n\n        if true {\n            // this else block exists to test the other help message\n        } else {\n            x.wait().unwrap();\n        }\n    }\n\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        if true {\n            x.wait().unwrap();\n        } else if true {\n            x.wait().unwrap();\n        } else {\n            x.wait().unwrap();\n        }\n    }\n\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        if true {\n            x.wait().unwrap();\n            return;\n        }\n        x.wait().unwrap();\n    }\n\n    {\n        let mut x = Command::new(\"\").spawn().unwrap();\n        std::thread::spawn(move || {\n            x.wait().unwrap();\n        });\n    }\n}\n\nfn process_child(c: Child) {\n    todo!()\n}\n\nfn return_wait() -> ExitStatus {\n    let mut x = Command::new(\"\").spawn().unwrap();\n    return x.wait().unwrap();\n}\n\nmod issue14677 {\n    use std::io;\n    use std::process::Command;\n\n    fn do_something<F: Fn() -> Result<(), ()>>(f: F) {\n        todo!()\n    }\n\n    fn foo() {\n        let mut child = Command::new(\"true\").spawn().unwrap();\n        let some_condition = true;\n        do_something(|| {\n            if some_condition {\n                return Err(());\n            }\n            Ok(())\n        });\n        child.kill().unwrap();\n        child.wait().unwrap();\n    }\n}\n\nfn issue14911() -> std::io::Result<String> {\n    let (mut recv, send) = std::io::pipe()?;\n    let mut command = Command::new(\"ls\")\n        .stdout(send.try_clone()?)\n        .spawn()\n        .expect(\"Could not spawn new process...\");\n    command.wait()?;\n    Ok(\"\".into())\n}\n"
  },
  {
    "path": "tests/ui/zombie_processes.stderr",
    "content": "error: spawned process is never `wait()`ed on\n  --> tests/ui/zombie_processes.rs:14:21\n   |\nLL |         let mut x = Command::new(\"\").spawn().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider calling `.wait()`\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n   = note: `-D clippy::zombie-processes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zombie_processes)]`\n\nerror: spawned process is never `wait()`ed on\n  --> tests/ui/zombie_processes.rs:42:21\n   |\nLL |         let mut x = Command::new(\"\").spawn().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider calling `.wait()`\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: spawned process is never `wait()`ed on\n  --> tests/ui/zombie_processes.rs:68:21\n   |\nLL |         let mut x = Command::new(\"\").spawn().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider calling `.wait()`\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: spawned process is never `wait()`ed on\n  --> tests/ui/zombie_processes.rs:76:21\n   |\nLL |         let mut x = Command::new(\"\").spawn().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider calling `.wait()`\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: spawned process is not `wait()`ed on in all code paths\n  --> tests/ui/zombie_processes.rs:103:21\n   |\nLL |         let mut x = Command::new(\"\").spawn().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: no `wait()` call exists on the code path to this early return\n  --> tests/ui/zombie_processes.rs:107:13\n   |\nLL |             return;\n   |             ^^^^^^\nnote: `wait()` call exists, but it is unreachable due to the early return\n  --> tests/ui/zombie_processes.rs:109:9\n   |\nLL |         x.wait().unwrap();\n   |         ^\n   = help: consider calling `.wait()` in all code paths\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: spawned process is not `wait()`ed on in all code paths\n  --> tests/ui/zombie_processes.rs:113:21\n   |\nLL |         let mut x = Command::new(\"\").spawn().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: this if expression has a `wait()` call, but it is missing an else block\n  --> tests/ui/zombie_processes.rs:116:9\n   |\nLL | /         if true {\nLL | |             x.wait().unwrap();\nLL | |         }\n   | |_________^\nnote: `wait()` called here\n  --> tests/ui/zombie_processes.rs:117:13\n   |\nLL |             x.wait().unwrap();\n   |             ^\n   = help: consider calling `.wait()` in all code paths\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: spawned process is not `wait()`ed on in all code paths\n  --> tests/ui/zombie_processes.rs:122:21\n   |\nLL |         let mut x = Command::new(\"\").spawn().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `wait()` is not called in this if branch\n  --> tests/ui/zombie_processes.rs:127:10\n   |\nLL |           } else {\n   |  __________^\nLL | |             // this else block exists to test the other help message\nLL | |         }\n   | |_________^\nnote: `wait()` is called in the other branch\n  --> tests/ui/zombie_processes.rs:126:13\n   |\nLL |             x.wait().unwrap();\n   |             ^\n   = help: consider calling `.wait()` in all code paths\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: spawned process is not `wait()`ed on in all code paths\n  --> tests/ui/zombie_processes.rs:133:21\n   |\nLL |         let mut x = Command::new(\"\").spawn().unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: `wait()` is not called in this if branch\n  --> tests/ui/zombie_processes.rs:136:9\n   |\nLL | /         if true {\nLL | |             // this else block exists to test the other help message\nLL | |         } else {\n   | |_________^\nnote: `wait()` is called in the other branch\n  --> tests/ui/zombie_processes.rs:139:13\n   |\nLL |             x.wait().unwrap();\n   |             ^\n   = help: consider calling `.wait()` in all code paths\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui/zombie_processes_fixable.fixed",
    "content": "#![warn(clippy::zombie_processes)]\n#![allow(clippy::needless_return)]\n\nuse std::process::{Child, Command};\n\nfn main() {\n    let _ = Command::new(\"\").spawn().unwrap().wait();\n    //~^ zombie_processes\n\n    Command::new(\"\").spawn().unwrap().wait();\n    //~^ zombie_processes\n\n    spawn_proc().wait();\n    //~^ zombie_processes\n\n    spawn_proc().wait().unwrap(); // OK\n}\n\nfn not_main() {\n    Command::new(\"\").spawn().unwrap().wait();\n    //~^ zombie_processes\n}\n\nfn spawn_proc() -> Child {\n    Command::new(\"\").spawn().unwrap()\n}\n\nfn spawn_proc_2() -> Child {\n    return Command::new(\"\").spawn().unwrap();\n}\n"
  },
  {
    "path": "tests/ui/zombie_processes_fixable.rs",
    "content": "#![warn(clippy::zombie_processes)]\n#![allow(clippy::needless_return)]\n\nuse std::process::{Child, Command};\n\nfn main() {\n    let _ = Command::new(\"\").spawn().unwrap();\n    //~^ zombie_processes\n\n    Command::new(\"\").spawn().unwrap();\n    //~^ zombie_processes\n\n    spawn_proc();\n    //~^ zombie_processes\n\n    spawn_proc().wait().unwrap(); // OK\n}\n\nfn not_main() {\n    Command::new(\"\").spawn().unwrap();\n    //~^ zombie_processes\n}\n\nfn spawn_proc() -> Child {\n    Command::new(\"\").spawn().unwrap()\n}\n\nfn spawn_proc_2() -> Child {\n    return Command::new(\"\").spawn().unwrap();\n}\n"
  },
  {
    "path": "tests/ui/zombie_processes_fixable.stderr",
    "content": "error: spawned process is never `wait()`ed on\n  --> tests/ui/zombie_processes_fixable.rs:7:13\n   |\nLL |     let _ = Command::new(\"\").spawn().unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try: `.wait()`\n   |\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n   = note: `-D clippy::zombie-processes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::zombie_processes)]`\n\nerror: spawned process is never `wait()`ed on\n  --> tests/ui/zombie_processes_fixable.rs:10:5\n   |\nLL |     Command::new(\"\").spawn().unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try: `.wait()`\n   |\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: spawned process is never `wait()`ed on\n  --> tests/ui/zombie_processes_fixable.rs:13:5\n   |\nLL |     spawn_proc();\n   |     ^^^^^^^^^^^^- help: try: `.wait()`\n   |\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: spawned process is never `wait()`ed on\n  --> tests/ui/zombie_processes_fixable.rs:20:5\n   |\nLL |     Command::new(\"\").spawn().unwrap();\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try: `.wait()`\n   |\n   = note: not doing so might leave behind zombie processes\n   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui/{literal_string_with_formatting_args}.rs",
    "content": "//@check-pass\n\n// Regression test for <https://github.com/rust-lang/rust-clippy/issues/13885>.\n// The `dbg` macro generates a literal with the name of the current file, so\n// we need to ensure the lint is not emitted in this case.\n\n// Clippy sets `-Zflatten_format_args=no`, which changes the default behavior of how format args\n// are lowered and only that one has this non-macro span. Adding the flag makes it repro on\n// godbolt and shows a root context span for the file name string.\n//\n// So instead of having:\n//\n// ```\n// Lit(\n//     Spanned {\n//         node: Str(\n//             \"[/app/example.rs:2:5] \\\"something\\\" = \",\n//             Cooked,\n//         ),\n//         span: /rustc/eb54a50837ad4bcc9842924f27e7287ca66e294c/library/std/src/macros.rs:365:35: 365:58 (#4),\n//     },\n// ),\n// ```\n//\n// We get:\n//\n// ```\n// Lit(\n//     Spanned {\n//         node: Str(\n//             \"/app/example.rs\",\n//             Cooked,\n//         ),\n//         span: /app/example.rs:2:5: 2:22 (#0),\n//     },\n// )\n// ```\n\n#![crate_name = \"foo\"]\n#![allow(unused)]\n#![warn(clippy::literal_string_with_formatting_args)]\n\nfn another_bad() {\n    let literal_string_with_formatting_args = 0;\n    dbg!(\"something\");\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail/Cargo.stderr",
    "content": "error: package `cargo_common_metadata_fail` is missing `package.description` metadata\n  |\n  = note: `-D clippy::cargo-common-metadata` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::cargo_common_metadata)]`\n\nerror: package `cargo_common_metadata_fail` is missing `either package.license or package.license_file` metadata\n\nerror: package `cargo_common_metadata_fail` is missing `package.repository` metadata\n\nerror: package `cargo_common_metadata_fail` is missing `package.readme` metadata\n\nerror: package `cargo_common_metadata_fail` is missing `package.keywords` metadata\n\nerror: package `cargo_common_metadata_fail` is missing `package.categories` metadata\n\nerror: could not compile `cargo_common_metadata_fail` (bin \"cargo_common_metadata_fail\") due to 6 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail/Cargo.toml",
    "content": "[package]\nname = \"cargo_common_metadata_fail\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail/clippy.toml",
    "content": "cargo-ignore-publish = true\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail/src/main.rs",
    "content": "#![warn(clippy::cargo_common_metadata)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.stderr",
    "content": "error: package `cargo_common_metadata_fail_publish` is missing `package.description` metadata\n  |\n  = note: `-D clippy::cargo-common-metadata` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::cargo_common_metadata)]`\n\nerror: package `cargo_common_metadata_fail_publish` is missing `either package.license or package.license_file` metadata\n\nerror: package `cargo_common_metadata_fail_publish` is missing `package.repository` metadata\n\nerror: package `cargo_common_metadata_fail_publish` is missing `package.readme` metadata\n\nerror: package `cargo_common_metadata_fail_publish` is missing `package.keywords` metadata\n\nerror: package `cargo_common_metadata_fail_publish` is missing `package.categories` metadata\n\nerror: could not compile `cargo_common_metadata_fail_publish` (bin \"cargo_common_metadata_fail_publish\") due to 6 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail_publish/Cargo.toml",
    "content": "[package]\nname = \"cargo_common_metadata_fail_publish\"\nversion = \"0.1.0\"\npublish = [\"some-registry-name\"]\n\n[workspace]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail_publish/src/main.rs",
    "content": "#![warn(clippy::cargo_common_metadata)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.stderr",
    "content": "error: package `cargo_common_metadata_fail_publish_true` is missing `package.description` metadata\n  |\n  = note: `-D clippy::cargo-common-metadata` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::cargo_common_metadata)]`\n\nerror: package `cargo_common_metadata_fail_publish_true` is missing `either package.license or package.license_file` metadata\n\nerror: package `cargo_common_metadata_fail_publish_true` is missing `package.repository` metadata\n\nerror: package `cargo_common_metadata_fail_publish_true` is missing `package.readme` metadata\n\nerror: package `cargo_common_metadata_fail_publish_true` is missing `package.keywords` metadata\n\nerror: package `cargo_common_metadata_fail_publish_true` is missing `package.categories` metadata\n\nerror: could not compile `cargo_common_metadata_fail_publish_true` (bin \"cargo_common_metadata_fail_publish_true\") due to 6 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail_publish_true/Cargo.toml",
    "content": "[package]\nname = \"cargo_common_metadata_fail_publish_true\"\nversion = \"0.1.0\"\npublish = true\n\n[workspace]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/fail_publish_true/src/main.rs",
    "content": "#![warn(clippy::cargo_common_metadata)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/pass/Cargo.toml",
    "content": "[package]\nname = \"cargo_common_metadata_pass\"\nversion = \"0.1.0\"\npublish = false\ndescription = \"A test package for the cargo_common_metadata lint\"\nrepository = \"https://github.com/someone/cargo_common_metadata\"\nreadme = \"README.md\"\nlicense = \"MIT OR Apache-2.0\"\nkeywords = [\"metadata\", \"lint\", \"clippy\"]\ncategories = [\"development-tools::testing\"]\n\n[workspace]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/pass/clippy.toml",
    "content": "cargo-ignore-publish = true\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/pass/src/main.rs",
    "content": "#![warn(clippy::cargo_common_metadata)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/pass_publish_empty/Cargo.toml",
    "content": "[package]\nname = \"cargo_common_metadata_pass_publish_empty\"\nversion = \"0.1.0\"\npublish = []\n\n[workspace]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/pass_publish_empty/src/main.rs",
    "content": "#![warn(clippy::cargo_common_metadata)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/pass_publish_false/Cargo.toml",
    "content": "[package]\nname = \"cargo_common_metadata_pass_publish_false\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_common_metadata/pass_publish_false/src/main.rs",
    "content": "#![warn(clippy::cargo_common_metadata)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_both_diff/Cargo.stderr",
    "content": "warning: the MSRV in `clippy.toml` and `Cargo.toml` differ; using `1.59.0` from `clippy.toml`\n\nerror: unnecessary structure name repetition\n --> src/main.rs:6:21\n  |\n6 |     pub fn bar() -> Foo {\n  |                     ^^^ help: use the applicable keyword: `Self`\n  |\nnote: the lint level is defined here\n --> src/main.rs:1:9\n  |\n1 | #![deny(clippy::use_self)]\n  |         ^^^^^^^^^^^^^^^^\n\nerror: unnecessary structure name repetition\n --> src/main.rs:7:9\n  |\n7 |         Foo\n  |         ^^^ help: use the applicable keyword: `Self`\n\nerror: could not compile `fail-both-diff` (bin \"fail-both-diff\") due to 2 previous errors; 1 warning emitted\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_both_diff/Cargo.toml",
    "content": "[package]\nname = \"fail-both-diff\"\nversion = \"0.1.0\"\nrust-version = \"1.56\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_both_diff/clippy.toml",
    "content": "msrv = \"1.59\"\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_both_diff/src/main.rs",
    "content": "#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_both_same/Cargo.stderr",
    "content": "error: unnecessary structure name repetition\n --> src/main.rs:6:21\n  |\n6 |     pub fn bar() -> Foo {\n  |                     ^^^ help: use the applicable keyword: `Self`\n  |\nnote: the lint level is defined here\n --> src/main.rs:1:9\n  |\n1 | #![deny(clippy::use_self)]\n  |         ^^^^^^^^^^^^^^^^\n\nerror: unnecessary structure name repetition\n --> src/main.rs:7:9\n  |\n7 |         Foo\n  |         ^^^ help: use the applicable keyword: `Self`\n\nerror: could not compile `fail-both-same` (bin \"fail-both-same\") due to 2 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_both_same/Cargo.toml",
    "content": "[package]\nname = \"fail-both-same\"\nversion = \"0.1.0\"\nrust-version = \"1.57.0\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_both_same/clippy.toml",
    "content": "msrv = \"1.57\"\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_both_same/src/main.rs",
    "content": "#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_cargo/Cargo.stderr",
    "content": "error: unnecessary structure name repetition\n --> src/main.rs:6:21\n  |\n6 |     pub fn bar() -> Foo {\n  |                     ^^^ help: use the applicable keyword: `Self`\n  |\nnote: the lint level is defined here\n --> src/main.rs:1:9\n  |\n1 | #![deny(clippy::use_self)]\n  |         ^^^^^^^^^^^^^^^^\n\nerror: unnecessary structure name repetition\n --> src/main.rs:7:9\n  |\n7 |         Foo\n  |         ^^^ help: use the applicable keyword: `Self`\n\nerror: could not compile `fail-cargo` (bin \"fail-cargo\") due to 2 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_cargo/Cargo.toml",
    "content": "[package]\nname = \"fail-cargo\"\nversion = \"0.1.0\"\nrust-version = \"1.56.1\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_cargo/src/main.rs",
    "content": "#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_clippy/Cargo.stderr",
    "content": "error: unnecessary structure name repetition\n --> src/main.rs:6:21\n  |\n6 |     pub fn bar() -> Foo {\n  |                     ^^^ help: use the applicable keyword: `Self`\n  |\nnote: the lint level is defined here\n --> src/main.rs:1:9\n  |\n1 | #![deny(clippy::use_self)]\n  |         ^^^^^^^^^^^^^^^^\n\nerror: unnecessary structure name repetition\n --> src/main.rs:7:9\n  |\n7 |         Foo\n  |         ^^^ help: use the applicable keyword: `Self`\n\nerror: could not compile `fail-clippy` (bin \"fail-clippy\") due to 2 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_clippy/Cargo.toml",
    "content": "[package]\nname = \"fail-clippy\"\nversion = \"0.1.0\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_clippy/clippy.toml",
    "content": "msrv = \"1.58\"\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_clippy/src/main.rs",
    "content": "#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr",
    "content": "error: unnecessary structure name repetition\n  --> src/main.rs:11:21\n   |\n11 |     pub fn bar() -> Foo {\n   |                     ^^^ help: use the applicable keyword: `Self`\n   |\nnote: the lint level is defined here\n  --> src/main.rs:6:9\n   |\n 6 | #![deny(clippy::use_self)]\n   |         ^^^^^^^^^^^^^^^^\n\nerror: unnecessary structure name repetition\n  --> src/main.rs:12:9\n   |\n12 |         Foo\n   |         ^^^ help: use the applicable keyword: `Self`\n\nerror: could not compile `fail-file-attr` (bin \"fail-file-attr\") due to 2 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.toml",
    "content": "[package]\nname = \"fail-file-attr\"\nversion = \"0.1.0\"\nrust-version = \"1.13\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_file_attr/clippy.toml",
    "content": "msrv = \"1.13.0\"\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/fail_file_attr/src/main.rs",
    "content": "// FIXME: this should produce a warning, because the attribute says 1.58 and the cargo.toml file\n// says 1.13\n\n#![feature(custom_inner_attributes)]\n#![clippy::msrv = \"1.58.0\"]\n#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_both_same/Cargo.toml",
    "content": "[package]\nname = \"pass-both-same\"\nversion = \"0.1.0\"\nrust-version = \"1.13.0\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_both_same/clippy.toml",
    "content": "msrv = \"1.13\"\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_both_same/src/main.rs",
    "content": "#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_cargo/Cargo.toml",
    "content": "[package]\nname = \"pass-cargo\"\nversion = \"0.1.0\"\nrust-version = \"1.13.0\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_cargo/src/main.rs",
    "content": "#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_clippy/Cargo.toml",
    "content": "[package]\nname = \"pass-clippy\"\nversion = \"0.1.0\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_clippy/clippy.toml",
    "content": "msrv = \"1.13\"\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_clippy/src/main.rs",
    "content": "#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_file_attr/Cargo.toml",
    "content": "[package]\nname = \"pass-file-attr\"\nversion = \"0.1.0\"\nrust-version = \"1.59\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/pass_file_attr/src/main.rs",
    "content": "#![feature(custom_inner_attributes)]\n#![clippy::msrv = \"1.13.0\"]\n#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/warn_both_diff/Cargo.stderr",
    "content": "warning: the MSRV in `clippy.toml` and `Cargo.toml` differ; using `1.13.0` from `clippy.toml`\n\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/warn_both_diff/Cargo.toml",
    "content": "[package]\nname = \"warn-both-diff\"\nversion = \"0.1.0\"\nrust-version = \"1.56.0\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/warn_both_diff/clippy.toml",
    "content": "msrv = \"1.13\"\n"
  },
  {
    "path": "tests/ui-cargo/cargo_rust_version/warn_both_diff/src/main.rs",
    "content": "#![deny(clippy::use_self)]\n\npub struct Foo;\n\nimpl Foo {\n    pub fn bar() -> Foo {\n        Foo\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/Cargo.stderr",
    "content": "error: file is loaded as a module multiple times: `src/b.rs`\n --> src/main.rs:3:1\n  |\n3 |   mod b;\n  |   ^^^^^^ first loaded here\n4 | / #[path = \"b.rs\"]\n5 | | mod b2;\n  | |_______^ loaded again here\n  |\n  = help: replace all but one `mod` item with `use` items\n  = note: `-D clippy::duplicate-mod` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::duplicate_mod)]`\n\nerror: file is loaded as a module multiple times: `src/c.rs`\n  --> src/main.rs:7:1\n   |\n 7 |   mod c;\n   |   ^^^^^^ first loaded here\n 8 | / #[path = \"c.rs\"]\n 9 | | mod c2;\n   | |_______^ loaded again here\n10 | / #[path = \"c.rs\"]\n11 | | mod c3;\n   | |_______^ loaded again here\n   |\n   = help: replace all but one `mod` item with `use` items\n\nerror: file is loaded as a module multiple times: `src/d.rs`\n  --> src/main.rs:16:1\n   |\n16 |   mod d;\n   |   ^^^^^^ first loaded here\n17 | / #[path = \"d.rs\"]\n18 | | mod d2;\n   | |_______^ loaded again here\n   |\n   = help: replace all but one `mod` item with `use` items\n\nerror: file is loaded as a module multiple times: `src/from_other_module.rs`\n  --> src/main.rs:13:1\n   |\n13 |   mod from_other_module;\n   |   ^^^^^^^^^^^^^^^^^^^^^^ first loaded here\n   |\n  ::: src/other_module/mod.rs:1:1\n   |\n 1 | / #[path = \"../from_other_module.rs\"]\n 2 | | mod m;\n   | |______^ loaded again here\n   |\n   = help: replace all but one `mod` item with `use` items\n\nerror: could not compile `duplicate_mod` (bin \"duplicate_mod\") due to 4 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/Cargo.toml",
    "content": "[package]\nname = \"duplicate_mod\"\nedition = \"2021\"\npublish = false\nversion = \"0.1.0\"\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/src/a.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/src/b.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/src/c.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/src/d.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/src/from_other_module.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/src/main.rs",
    "content": "mod a;\n\nmod b;\n#[path = \"b.rs\"]\nmod b2;\n\nmod c;\n#[path = \"c.rs\"]\nmod c2;\n#[path = \"c.rs\"]\nmod c3;\n\nmod from_other_module;\nmod other_module;\n\nmod d;\n#[path = \"d.rs\"]\nmod d2;\n#[path = \"d.rs\"]\n#[expect(clippy::duplicate_mod)]\nmod d3;\n#[path = \"d.rs\"]\n#[allow(clippy::duplicate_mod)]\nmod d4;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/duplicate_mod/fail/src/other_module/mod.rs",
    "content": "#[path = \"../from_other_module.rs\"]\nmod m;\n"
  },
  {
    "path": "tests/ui-cargo/feature_name/fail/Cargo.stderr",
    "content": "error: the \"no-\" prefix in the feature name \"no-qaq\" is negative\n  |\n  = help: consider renaming the feature to \"qaq\", but make sure the feature adds functionality\n  = note: `-D clippy::negative-feature-names` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::negative_feature_names)]`\n\nerror: the \"no_\" prefix in the feature name \"no_qaq\" is negative\n  |\n  = help: consider renaming the feature to \"qaq\", but make sure the feature adds functionality\n\nerror: the \"not-\" prefix in the feature name \"not-orz\" is negative\n  |\n  = help: consider renaming the feature to \"orz\", but make sure the feature adds functionality\n\nerror: the \"not_\" prefix in the feature name \"not_orz\" is negative\n  |\n  = help: consider renaming the feature to \"orz\", but make sure the feature adds functionality\n\nerror: the \"-support\" suffix in the feature name \"qvq-support\" is redundant\n  |\n  = help: consider renaming the feature to \"qvq\"\n  = note: `-D clippy::redundant-feature-names` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::redundant_feature_names)]`\n\nerror: the \"_support\" suffix in the feature name \"qvq_support\" is redundant\n  |\n  = help: consider renaming the feature to \"qvq\"\n\nerror: the \"use-\" prefix in the feature name \"use-qwq\" is redundant\n  |\n  = help: consider renaming the feature to \"qwq\"\n\nerror: the \"use_\" prefix in the feature name \"use_qwq\" is redundant\n  |\n  = help: consider renaming the feature to \"qwq\"\n\nerror: the \"with-\" prefix in the feature name \"with-owo\" is redundant\n  |\n  = help: consider renaming the feature to \"owo\"\n\nerror: the \"with_\" prefix in the feature name \"with_owo\" is redundant\n  |\n  = help: consider renaming the feature to \"owo\"\n\nerror: could not compile `feature_name` (bin \"feature_name\") due to 10 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/feature_name/fail/Cargo.toml",
    "content": "\n# Content that triggers the lint goes here\n\n[package]\nname = \"feature_name\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n\n[features]\nuse-qwq = []\nuse_qwq = []\nwith-owo = []\nwith_owo = []\nqvq-support = []\nqvq_support = []\nno-qaq = []\nno_qaq = []\nnot-orz = []\nnot_orz = []\n"
  },
  {
    "path": "tests/ui-cargo/feature_name/fail/src/main.rs",
    "content": "#![warn(clippy::redundant_feature_names)]\n#![warn(clippy::negative_feature_names)]\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui-cargo/feature_name/pass/Cargo.toml",
    "content": "\n# This file should not trigger the lint\n\n[package]\nname = \"feature_name\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n"
  },
  {
    "path": "tests/ui-cargo/feature_name/pass/src/main.rs",
    "content": "#![warn(clippy::redundant_feature_names)]\n#![warn(clippy::negative_feature_names)]\n\nfn main() {\n    // test code goes here\n}\n"
  },
  {
    "path": "tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr",
    "content": "error: lint group `rust_2018_idioms` has the same priority (0) as a lint\n  --> Cargo.toml:7:1\n   |\n 7 | rust_2018_idioms = \"warn\"\n   | ^^^^^^^^^^^^^^^^   ------ has an implicit priority of 0\n...\n12 | unused_attributes = { level = \"allow\" }\n   | ----------------- has the same priority as this lint\n   |\n   = note: the order of the lints in the table is ignored by Cargo\n   = note: `#[deny(clippy::lint_groups_priority)]` on by default\nhelp: to have lints override the group set `rust_2018_idioms` to a lower priority\n   |\n 7 - rust_2018_idioms = \"warn\"\n 7 + rust_2018_idioms = { level = \"warn\", priority = -1 }\n   |\n\nerror: lint group `unused` has the same priority (0) as a lint\n  --> Cargo.toml:10:1\n   |\n10 | unused = { level = \"deny\" }\n   | ^^^^^^   ------------------ has an implicit priority of 0\n11 | unused_braces = { level = \"allow\", priority = 1 }\n12 | unused_attributes = { level = \"allow\" }\n   | ----------------- has the same priority as this lint\n   |\n   = note: the order of the lints in the table is ignored by Cargo\nhelp: to have lints override the group set `unused` to a lower priority\n   |\n10 | unused = { level = \"deny\", priority = -1 }\n   |                          +++++++++++++++\n\nerror: lint group `pedantic` has the same priority (-1) as a lint\n  --> Cargo.toml:15:1\n   |\n15 | pedantic = { level = \"warn\", priority = -1 }\n   | ^^^^^^^^\n16 | similar_names = { level = \"allow\", priority = -1 }\n   | ------------- has the same priority as this lint\n   |\n   = note: the order of the lints in the table is ignored by Cargo\nhelp: to have lints override the group set `pedantic` to a lower priority\n   |\n15 - pedantic = { level = \"warn\", priority = -1 }\n15 + pedantic = { level = \"warn\", priority = -2 }\n   |\n\nerror: lint group `rust_2018_idioms` has the same priority (0) as a lint\n  --> Cargo.toml:19:1\n   |\n19 | rust_2018_idioms = \"warn\"\n   | ^^^^^^^^^^^^^^^^   ------ has an implicit priority of 0\n20 | bare_trait_objects = \"allow\"\n   | ------------------ has the same priority as this lint\n   |\n   = note: the order of the lints in the table is ignored by Cargo\nhelp: to have lints override the group set `rust_2018_idioms` to a lower priority\n   |\n19 - rust_2018_idioms = \"warn\"\n19 + rust_2018_idioms = { level = \"warn\", priority = -1 }\n   |\n\nerror: lint group `pedantic` has the same priority (0) as a lint\n  --> Cargo.toml:23:1\n   |\n23 | pedantic = \"warn\"\n   | ^^^^^^^^   ------ has an implicit priority of 0\n24 | similar_names = \"allow\"\n   | ------------- has the same priority as this lint\n   |\n   = note: the order of the lints in the table is ignored by Cargo\nhelp: to have lints override the group set `pedantic` to a lower priority\n   |\n23 - pedantic = \"warn\"\n23 + pedantic = { level = \"warn\", priority = -1 }\n   |\n\nerror: could not compile `fail` (lib) due to 5 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/lint_groups_priority/fail/Cargo.toml",
    "content": "[package]\nname = \"fail\"\nversion = \"0.1.0\"\npublish = false\n\n[lints.rust]\nrust_2018_idioms = \"warn\"\nbare_trait_objects = \"allow\"\n\nunused = { level = \"deny\" }\nunused_braces = { level = \"allow\", priority = 1 }\nunused_attributes = { level = \"allow\" }\n\n[lints.clippy]\npedantic = { level = \"warn\", priority = -1 }\nsimilar_names = { level = \"allow\", priority = -1 }\n\n[workspace.lints.rust]\nrust_2018_idioms = \"warn\"\nbare_trait_objects = \"allow\"\n\n[workspace.lints.clippy]\npedantic = \"warn\"\nsimilar_names = \"allow\"\n"
  },
  {
    "path": "tests/ui-cargo/lint_groups_priority/fail/src/lib.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/lint_groups_priority/pass/Cargo.toml",
    "content": "[package]\nname = \"pass\"\nversion = \"0.1.0\"\npublish = false\n\n[lints.rust]\n# Warnings does not conflict with any group or lint\nwarnings = \"deny\"\n# Groups & lints at the same level do not conflict\nrust_2018_idioms = \"warn\"\nunsafe_code = \"warn\"\n\n[lints.clippy]\npedantic = { level = \"warn\", priority = -1 }\nstyle = { level = \"warn\", priority = 1 }\nsimilar_names = \"allow\"\ndbg_macro = { level = \"warn\", priority = 2 }\n"
  },
  {
    "path": "tests/ui-cargo/lint_groups_priority/pass/src/lib.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/module_style/duplicated_mod_names_14697/Cargo.stderr",
    "content": "error: `mod.rs` files are required, found `src/foo.rs`\n --> src/foo.rs:1:1\n  |\n1 | pub mod bar;\n  | ^\n  |\n  = help: move `src/foo.rs` to `src/foo/mod.rs`\n  = note: `-D clippy::self-named-module-files` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::self_named_module_files)]`\n\nerror: could not compile `duplicated-mod-names-14697` (lib) due to 1 previous error\n"
  },
  {
    "path": "tests/ui-cargo/module_style/duplicated_mod_names_14697/Cargo.toml",
    "content": "# Should trigger when multiple mods with the same name exist and not all of them follow self-named convention.\n# See issue #14697.\n[package]\nname = \"duplicated-mod-names-14697\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/module_style/duplicated_mod_names_14697/src/foo/bar.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/module_style/duplicated_mod_names_14697/src/foo.rs",
    "content": "pub mod bar;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/duplicated_mod_names_14697/src/lib.rs",
    "content": "#![warn(clippy::self_named_module_files)]\n\npub mod foo;\npub mod other;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/duplicated_mod_names_14697/src/other/foo/mod.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/module_style/duplicated_mod_names_14697/src/other/mod.rs",
    "content": "pub mod foo;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod/Cargo.stderr",
    "content": "error: `mod.rs` files are required, found `src/bad/inner/stuff.rs`\n --> src/bad/inner/stuff.rs:1:1\n  |\n1 | pub mod most;\n  | ^\n  |\n  = help: move `src/bad/inner/stuff.rs` to `src/bad/inner/stuff/mod.rs`\n  = note: `-D clippy::self-named-module-files` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::self_named_module_files)]`\n\nerror: `mod.rs` files are required, found `src/bad/inner.rs`\n --> src/bad/inner.rs:1:1\n  |\n1 | pub mod stuff;\n  | ^\n  |\n  = help: move `src/bad/inner.rs` to `src/bad/inner/mod.rs`\n\nerror: could not compile `fail-mod` (bin \"fail-mod\") due to 2 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod/Cargo.toml",
    "content": "[package]\nname = \"fail-mod\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod/src/bad/inner/stuff/most.rs",
    "content": "pub struct Snarks;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod/src/bad/inner/stuff.rs",
    "content": "pub mod most;\n\npub struct Inner;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod/src/bad/inner.rs",
    "content": "pub mod stuff;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod/src/bad/mod.rs",
    "content": "pub mod inner;\n\npub struct Thing;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod/src/main.rs",
    "content": "#![warn(clippy::self_named_module_files)]\n\nmod bad;\n\nfn main() {\n    let _ = bad::Thing;\n    let _ = bad::inner::stuff::Inner;\n    let _ = bad::inner::stuff::most::Snarks;\n}\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr",
    "content": "error: `mod.rs` files are required, found `src/bad.rs`\n --> src/bad.rs:1:1\n  |\n1 | pub mod inner;\n  | ^\n  |\n  = help: move `src/bad.rs` to `src/bad/mod.rs`\n  = note: `-D clippy::self-named-module-files` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::self_named_module_files)]`\n\nerror: could not compile `fail-mod-remap` (bin \"fail-mod-remap\") due to 1 previous error\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod_remap/Cargo.toml",
    "content": "[package]\nname = \"fail-mod-remap\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod_remap/src/bad/inner.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod_remap/src/bad.rs",
    "content": "pub mod inner;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_mod_remap/src/main.rs",
    "content": "// FIXME: find a way to add rustflags to ui-cargo tests\n//@compile-flags: --remap-path-prefix {{src-base}}=/remapped\n\n#![warn(clippy::self_named_module_files)]\n\nmod bad;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr",
    "content": "error: `mod.rs` files are not allowed, found `src/bad/mod.rs`\n --> src/bad/mod.rs:1:1\n  |\n1 | pub struct Thing;\n  | ^\n  |\n  = help: move `src/bad/mod.rs` to `src/bad.rs`\n  = note: `-D clippy::mod-module-files` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::mod_module_files)]`\n\nerror: could not compile `fail-no-mod` (bin \"fail-no-mod\") due to 1 previous error\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_no_mod/Cargo.toml",
    "content": "[package]\nname = \"fail-no-mod\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_no_mod/src/bad/mod.rs",
    "content": "pub struct Thing;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/fail_no_mod/src/main.rs",
    "content": "#![warn(clippy::mod_module_files)]\n\nmod bad;\n\nfn main() {\n    let _ = bad::Thing;\n}\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_mod/Cargo.toml",
    "content": "[package]\nname = \"pass-mod\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_mod/src/bad/mod.rs",
    "content": "pub struct Thing;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_mod/src/main.rs",
    "content": "#![warn(clippy::self_named_module_files)]\n\nmod bad;\nmod more;\n\nfn main() {\n    let _ = bad::Thing;\n    let _ = more::foo::Foo;\n    let _ = more::inner::Inner;\n}\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_mod/src/more/foo.rs",
    "content": "pub struct Foo;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_mod/src/more/inner/mod.rs",
    "content": "pub struct Inner;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_mod/src/more/mod.rs",
    "content": "pub mod foo;\npub mod inner;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_no_mod/Cargo.toml",
    "content": "[package]\nname = \"pass-no-mod\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_no_mod/src/good.rs",
    "content": "pub struct Thing;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/pass_no_mod/src/main.rs",
    "content": "#![warn(clippy::mod_module_files)]\n\nmod good;\n\nfn main() {\n    let _ = good::Thing;\n}\n"
  },
  {
    "path": "tests/ui-cargo/module_style/segment_with_mod_name_10271_11916/Cargo.toml",
    "content": "# Should not produce FP when irrelavant path segment shares the same name with module.\n# See issue #10271 and #11916.\n[package]\nname = \"segment-with-mod-name-10271-11916\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[workspace]\nmembers = [\"foo/bar\"]"
  },
  {
    "path": "tests/ui-cargo/module_style/segment_with_mod_name_10271_11916/foo/bar/Cargo.toml",
    "content": "[package]\nname = \"bar\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n"
  },
  {
    "path": "tests/ui-cargo/module_style/segment_with_mod_name_10271_11916/foo/bar/src/foo.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/module_style/segment_with_mod_name_10271_11916/foo/bar/src/lib.rs",
    "content": "pub mod foo;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/segment_with_mod_name_10271_11916/src/lib.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/module_style/with_path_attr_mod/Cargo.toml",
    "content": "# Should not lint mod tagged with `#[path = ...]` \n[package]\nname = \"with-path-attr-mod\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/module_style/with_path_attr_mod/src/bar/mod.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/module_style/with_path_attr_mod/src/lib.rs",
    "content": "#![warn(clippy::mod_module_files)]\n\n#[path = \"bar/mod.rs\"]\npub mod foo;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/with_path_attr_no_mod/Cargo.toml",
    "content": "# Should not lint mod tagged with `#[path = ...]` \n[package]\nname = \"with-path-attr-no-mod\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/module_style/with_path_attr_no_mod/src/bar.rs",
    "content": "\n"
  },
  {
    "path": "tests/ui-cargo/module_style/with_path_attr_no_mod/src/foo.rs",
    "content": "#[path = \"bar.rs\"]\nmod bar;\n"
  },
  {
    "path": "tests/ui-cargo/module_style/with_path_attr_no_mod/src/lib.rs",
    "content": "#![warn(clippy::self_named_module_files)]\n\npub mod foo;\n"
  },
  {
    "path": "tests/ui-cargo/multiple_config_files/no_warn/Cargo.toml",
    "content": "[package]\nname = \"no_warn\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/multiple_config_files/no_warn/clippy.toml",
    "content": "avoid-breaking-exported-api = false\n"
  },
  {
    "path": "tests/ui-cargo/multiple_config_files/no_warn/src/main.rs",
    "content": "fn main() {\n    println!(\"Hello, world!\");\n}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_config_files/warn/.clippy.toml",
    "content": "avoid-breaking-exported-api = false\n"
  },
  {
    "path": "tests/ui-cargo/multiple_config_files/warn/Cargo.stderr",
    "content": "warning: using config file `$DIR/tests/ui-cargo/multiple_config_files/warn/.clippy.toml`, `$DIR/tests/ui-cargo/multiple_config_files/warn/clippy.toml` will be ignored\n\n"
  },
  {
    "path": "tests/ui-cargo/multiple_config_files/warn/Cargo.toml",
    "content": "[package]\nname = \"warn\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/multiple_config_files/warn/clippy.toml",
    "content": "avoid-breaking-exported-api = false\n"
  },
  {
    "path": "tests/ui-cargo/multiple_config_files/warn/src/main.rs",
    "content": "fn main() {\n    println!(\"Hello, world!\");\n}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr",
    "content": "error: multiple versions for dependency `winapi`: 0.2.8, 0.3.9\n  |\n  = note: `-D clippy::multiple-crate-versions` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::multiple_crate_versions)]`\n\nerror: could not compile `multiple-crate-versions` (bin \"multiple-crate-versions\") due to 1 previous error\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml",
    "content": "# Should not lint for dev or build dependencies. See issue 5041.\n\n[package]\n# purposefully separated by - instead of _\nname = \"multiple-crate-versions\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n\n# One of the versions of winapi is only a dev dependency: allowed\n[dependencies]\nwinapi = \"0.2\"\nansi_term = \"=0.11.0\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs",
    "content": "#![warn(clippy::multiple_crate_versions)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml",
    "content": "[package]\nname = \"multiple_crate_versions\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n\n[dependencies]\nwinapi = \"0.2\"\nansi_term = \"=0.11.0\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml",
    "content": "allowed-duplicate-crates = [\"winapi\"]\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs",
    "content": "#![warn(clippy::multiple_crate_versions)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/Cargo.toml",
    "content": "# Should not lint for dev or build dependencies. See issue 5041.\n\n[package]\nname = \"multiple_crate_versions\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n\n# One of the versions of winapi is only a dev dependency: allowed\n[dependencies]\nctrlc = \"=3.1.0\"\n[dev-dependencies]\nansi_term = \"=0.11.0\"\n\n# Both versions of winapi are a build dependency: allowed\n[build-dependencies]\nctrlc = \"=3.1.0\"\nansi_term = \"=0.11.0\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/5041_allow_dev_build/src/main.rs",
    "content": "#![warn(clippy::multiple_crate_versions)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr",
    "content": "error: multiple versions for dependency `winapi`: 0.2.8, 0.3.9\n  |\n  = note: `-D clippy::multiple-crate-versions` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::multiple_crate_versions)]`\n\nerror: could not compile `multiple_crate_versions` (bin \"multiple_crate_versions\") due to 1 previous error\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/fail/Cargo.toml",
    "content": "[package]\nname = \"multiple_crate_versions\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n\n[dependencies]\nwinapi = \"0.2\"\nansi_term = \"=0.11.0\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/fail/src/main.rs",
    "content": "#![warn(clippy::multiple_crate_versions)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/pass/Cargo.toml",
    "content": "[package]\nname = \"multiple_crate_versions\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n\n[dependencies]\nregex = \"1.3.7\"\nserde = \"1.0.110\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_crate_versions/pass/src/main.rs",
    "content": "#![warn(clippy::multiple_crate_versions)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/config_fail/Cargo.stderr",
    "content": "error: error reading Clippy's configuration file: unknown variant `FooBar`, expected one of `crate`, `file`, `module`\n --> $DIR/tests/ui-cargo/multiple_inherent_impl/config_fail/clippy.toml:1:28\n  |\n1 | inherent-impl-lint-scope = \"FooBar\"\n  |                            ^^^^^^^^\n\nerror: could not compile `config_fail` (bin \"config_fail\") due to 1 previous error\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/config_fail/Cargo.toml",
    "content": "[package]\nname = \"config_fail\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/config_fail/clippy.toml",
    "content": "inherent-impl-lint-scope = \"FooBar\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/config_fail/src/main.rs",
    "content": "#![allow(dead_code)]\n#![deny(clippy::multiple_inherent_impl)]\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/crate_fail/Cargo.stderr",
    "content": "error: multiple implementations of this structure\n  --> src/main.rs:11:1\n   |\n11 | / impl S {\n12 | |     //^ Must trigger\n13 | |     fn second() {}\n14 | | }\n   | |_^\n   |\nnote: first implementation here\n  --> src/main.rs:7:1\n   |\n 7 | / impl S {\n 8 | |     fn first() {}\n 9 | | }\n   | |_^\nnote: the lint level is defined here\n  --> src/main.rs:2:9\n   |\n 2 | #![deny(clippy::multiple_inherent_impl)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> src/main.rs:22:5\n   |\n22 | /     impl T {\n23 | |         //^ Must trigger\n24 | |         fn second() {}\n25 | |     }\n   | |_____^\n   |\nnote: first implementation here\n  --> src/main.rs:16:1\n   |\n16 | / impl T {\n17 | |     fn first() {}\n18 | | }\n   | |_^\n\nerror: multiple implementations of this structure\n  --> src/main.rs:36:1\n   |\n36 | / impl b::T {\n37 | |     //^ Must trigger\n38 | |     fn second() {}\n39 | | }\n   | |_^\n   |\nnote: first implementation here\n  --> src/b.rs:4:1\n   |\n 4 | / impl T {\n 5 | |     fn first() {}\n 6 | | }\n   | |_^\n\nerror: could not compile `crate_fail` (bin \"crate_fail\") due to 3 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/crate_fail/Cargo.toml",
    "content": "[package]\nname = \"crate_fail\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/crate_fail/clippy.toml",
    "content": "inherent-impl-lint-scope = \"crate\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/crate_fail/src/b.rs",
    "content": "pub struct S;\npub struct T;\n\nimpl T {\n    fn first() {}\n}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/crate_fail/src/main.rs",
    "content": "#![allow(dead_code)]\n#![deny(clippy::multiple_inherent_impl)]\n\nstruct S;\nstruct T;\n\nimpl S {\n    fn first() {}\n}\n\nimpl S {\n    //^ Must trigger\n    fn second() {}\n}\n\nimpl T {\n    fn first() {}\n}\n\nmod a {\n    use super::T;\n    impl T {\n        //^ Must trigger\n        fn second() {}\n    }\n}\n\nmod b;\n\nimpl b::S {\n    //^ Must NOT trigger\n    fn first() {}\n    fn second() {}\n}\n\nimpl b::T {\n    //^ Must trigger\n    fn second() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/file_fail/Cargo.stderr",
    "content": "error: multiple implementations of this structure\n  --> src/main.rs:13:5\n   |\n13 | /     impl S {\n14 | |         //^ Must trigger\n15 | |         fn second() {}\n16 | |     }\n   | |_____^\n   |\nnote: first implementation here\n  --> src/main.rs:6:1\n   |\n 6 | / impl S {\n 7 | |     fn first() {}\n 8 | | }\n   | |_^\nnote: the lint level is defined here\n  --> src/main.rs:2:9\n   |\n 2 | #![deny(clippy::multiple_inherent_impl)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> src/main.rs:26:5\n   |\n26 | /     impl S {\n27 | |         //^ Must trigger\n28 | |\n29 | |         fn second() {}\n30 | |     }\n   | |_____^\n   |\nnote: first implementation here\n  --> src/main.rs:22:5\n   |\n22 | /     impl S {\n23 | |         fn first() {}\n24 | |     }\n   | |_____^\n\nerror: multiple implementations of this structure\n  --> src/c.rs:17:5\n   |\n17 | /     impl T {\n18 | |         //^ Must trigger\n19 | |         fn second() {}\n20 | |     }\n   | |_____^\n   |\nnote: first implementation here\n  --> src/c.rs:10:5\n   |\n10 | /     impl T {\n11 | |         fn first() {}\n12 | |     }\n   | |_____^\n\nerror: could not compile `file_fail` (bin \"file_fail\") due to 3 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/file_fail/Cargo.toml",
    "content": "[package]\nname = \"file_fail\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/file_fail/clippy.toml",
    "content": "inherent-impl-lint-scope = \"file\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/file_fail/src/c.rs",
    "content": "pub struct S;\nstruct T;\n\nimpl S {\n    fn first() {}\n}\n\nmod d {\n    use super::T;\n    impl T {\n        fn first() {}\n    }\n}\n\nmod e {\n    use super::T;\n    impl T {\n        //^ Must trigger\n        fn second() {}\n    }\n}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/file_fail/src/main.rs",
    "content": "#![allow(dead_code)]\n#![deny(clippy::multiple_inherent_impl)]\n\nstruct S;\n\nimpl S {\n    fn first() {}\n}\n\nmod a {\n    use super::S;\n\n    impl S {\n        //^ Must trigger\n        fn second() {}\n    }\n}\n\nmod b {\n    struct S;\n\n    impl S {\n        fn first() {}\n    }\n\n    impl S {\n        //^ Must trigger\n\n        fn second() {}\n    }\n}\n\nmod c;\n\nimpl c::S {\n    //^ Must NOT trigger\n    fn second() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/module_fail/Cargo.stderr",
    "content": "error: multiple implementations of this structure\n  --> src/main.rs:26:5\n   |\n26 | /     impl S {\n27 | |         //^ Must trigger\n28 | |\n29 | |         fn second() {}\n30 | |     }\n   | |_____^\n   |\nnote: first implementation here\n  --> src/main.rs:22:5\n   |\n22 | /     impl S {\n23 | |         fn first() {}\n24 | |     }\n   | |_____^\nnote: the lint level is defined here\n  --> src/main.rs:2:9\n   |\n 2 | #![deny(clippy::multiple_inherent_impl)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: multiple implementations of this structure\n  --> src/c.rs:12:1\n   |\n12 | / impl T {\n13 | |     //^ Must trigger\n14 | |     fn second() {}\n15 | | }\n   | |_^\n   |\nnote: first implementation here\n  --> src/c.rs:8:1\n   |\n 8 | / impl T {\n 9 | |     fn first() {}\n10 | | }\n   | |_^\n\nerror: could not compile `module_fail` (bin \"module_fail\") due to 2 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/module_fail/Cargo.toml",
    "content": "[package]\nname = \"module_fail\"\nversion = \"0.1.0\"\nedition = \"2024\"\npublish = false\n\n[dependencies]\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/module_fail/clippy.toml",
    "content": "inherent-impl-lint-scope = \"module\"\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/module_fail/src/c.rs",
    "content": "pub struct S;\nstruct T;\n\nimpl S {\n    fn first() {}\n}\n\nimpl T {\n    fn first() {}\n}\n\nimpl T {\n    //^ Must trigger\n    fn second() {}\n}\n"
  },
  {
    "path": "tests/ui-cargo/multiple_inherent_impl/module_fail/src/main.rs",
    "content": "#![allow(dead_code)]\n#![deny(clippy::multiple_inherent_impl)]\n\nstruct S;\n\nimpl S {\n    fn first() {}\n}\n\nmod a {\n    use super::S;\n\n    impl S {\n        //^ Must NOT trigger\n        fn second() {}\n    }\n}\n\nmod b {\n    struct S;\n\n    impl S {\n        fn first() {}\n    }\n\n    impl S {\n        //^ Must trigger\n\n        fn second() {}\n    }\n}\n\nmod c;\n\nimpl c::S {\n    //^ Must NOT trigger\n    fn second() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/undocumented_unsafe_blocks/fail/Cargo.stderr",
    "content": "error: module has unnecessary safety comment\n --> src/main.rs:2:1\n  |\n2 | mod x {}\n  | ^^^^^^^^\n  |\nhelp: consider removing the safety comment\n --> src/main.rs:1:4\n  |\n1 | // SAFETY: ...\n  |    ^^^^^^^\n  = note: requested on the command line with `-D clippy::unnecessary-safety-comment`\n\nerror: module has unnecessary safety comment\n --> src/main.rs:5:1\n  |\n5 | mod y {}\n  | ^^^^^^^^\n  |\nhelp: consider removing the safety comment\n --> src/main.rs:4:4\n  |\n4 | // SAFETY: ...\n  |    ^^^^^^^\n\nerror: could not compile `undocumented_unsafe_blocks` (bin \"undocumented_unsafe_blocks\") due to 2 previous errors\n"
  },
  {
    "path": "tests/ui-cargo/undocumented_unsafe_blocks/fail/Cargo.toml",
    "content": "# Reproducing #14553 requires the `# Safety` comment to be in the first line of \n# the file. Since `unnecessary_safety_comment` is not enabled by default, we\n# will set it up here.\n\n[package]\nname = \"undocumented_unsafe_blocks\"\nedition = \"2024\"\npublish = false\nversion = \"0.1.0\"\n\n[lints.clippy]\nunnecessary_safety_comment = \"deny\"\n"
  },
  {
    "path": "tests/ui-cargo/undocumented_unsafe_blocks/fail/src/main.rs",
    "content": "// SAFETY: ...\nmod x {}\n\n// SAFETY: ...\nmod y {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/update-all-references.sh",
    "content": "#!/bin/bash\n\necho \"Please use 'cargo bless' instead.\"\n"
  },
  {
    "path": "tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr",
    "content": "error: wildcard dependency for `regex`\n  |\n  = note: `-D clippy::wildcard-dependencies` implied by `-D warnings`\n  = help: to override `-D warnings` add `#[allow(clippy::wildcard_dependencies)]`\n\nerror: could not compile `wildcard_dependencies` (bin \"wildcard_dependencies\") due to 1 previous error\n"
  },
  {
    "path": "tests/ui-cargo/wildcard_dependencies/fail/Cargo.toml",
    "content": "[package]\nname = \"wildcard_dependencies\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n\n[dependencies]\nregex = \"*\"\n"
  },
  {
    "path": "tests/ui-cargo/wildcard_dependencies/fail/src/main.rs",
    "content": "#![warn(clippy::wildcard_dependencies)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-cargo/wildcard_dependencies/pass/Cargo.toml",
    "content": "[package]\nname = \"wildcard_dependencies\"\nversion = \"0.1.0\"\npublish = false\n\n[workspace]\n\n[dependencies]\nregex = \"1\"\n"
  },
  {
    "path": "tests/ui-cargo/wildcard_dependencies/pass/src/main.rs",
    "content": "#![warn(clippy::wildcard_dependencies)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/check_clippy_version_attribute.rs",
    "content": "#![feature(rustc_private)]\n#![deny(clippy::invalid_clippy_version_attribute, clippy::missing_clippy_version_attribute)]\n\n#[macro_use]\nextern crate rustc_middle;\n#[macro_use]\nextern crate rustc_session;\nextern crate rustc_lint;\n\n///////////////////////\n// Valid descriptions\n///////////////////////\ndeclare_tool_lint! {\n    #[clippy::version = \"pre 1.29.0\"]\n    pub clippy::VALID_ONE,\n    Warn,\n    \"One\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    #[clippy::version = \"1.29.0\"]\n    pub clippy::VALID_TWO,\n    Warn,\n    \"Two\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    #[clippy::version = \"1.59.0\"]\n    pub clippy::VALID_THREE,\n    Warn,\n    \"Three\",\n    report_in_external_macro: true\n}\n\n///////////////////////\n// Invalid attributes\n///////////////////////\ndeclare_tool_lint! {\n//~^ invalid_clippy_version_attribute\n    #[clippy::version = \"1.2.3.4.5.6\"]\n    pub clippy::INVALID_ONE,\n    Warn,\n    \"One\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n//~^ invalid_clippy_version_attribute\n    #[clippy::version = \"I'm a string\"]\n    pub clippy::INVALID_TWO,\n    Warn,\n    \"Two\",\n    report_in_external_macro: true\n}\n\n///////////////////////\n// Missing attribute test\n///////////////////////\ndeclare_tool_lint! {\n//~^ missing_clippy_version_attribute\n    #[clippy::version]\n    pub clippy::MISSING_ATTRIBUTE_ONE,\n    Warn,\n    \"Two\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n//~^ missing_clippy_version_attribute\n    pub clippy::MISSING_ATTRIBUTE_TWO,\n    Warn,\n    \"Two\",\n    report_in_external_macro: true\n}\n\n#[allow(clippy::missing_clippy_version_attribute)]\nmod internal_clippy_lints {\n    declare_tool_lint! {\n        pub clippy::ALLOW_MISSING_ATTRIBUTE_ONE,\n        Warn,\n        \"Two\",\n        report_in_external_macro: true\n    }\n}\n\nuse crate::internal_clippy_lints::ALLOW_MISSING_ATTRIBUTE_ONE;\ndeclare_lint_pass!(Pass2 => [\n    VALID_ONE,\n    VALID_TWO,\n    VALID_THREE,\n    INVALID_ONE,\n    INVALID_TWO,\n    MISSING_ATTRIBUTE_ONE,\n    MISSING_ATTRIBUTE_TWO,\n    ALLOW_MISSING_ATTRIBUTE_ONE,\n]);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/check_clippy_version_attribute.stderr",
    "content": "error: this item has an invalid `clippy::version` attribute\n  --> tests/ui-internal/check_clippy_version_attribute.rs:40:1\n   |\nLL | / declare_tool_lint! {\nLL | |\nLL | |     #[clippy::version = \"1.2.3.4.5.6\"]\nLL | |     pub clippy::INVALID_ONE,\n...  |\nLL | |     report_in_external_macro: true\nLL | | }\n   | |_^\n   |\n   = help: please use a valid semantic version, see `doc/adding_lints.md`\nnote: the lint level is defined here\n  --> tests/ui-internal/check_clippy_version_attribute.rs:2:9\n   |\nLL | #![deny(clippy::invalid_clippy_version_attribute, clippy::missing_clippy_version_attribute)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this item has an invalid `clippy::version` attribute\n  --> tests/ui-internal/check_clippy_version_attribute.rs:49:1\n   |\nLL | / declare_tool_lint! {\nLL | |\nLL | |     #[clippy::version = \"I'm a string\"]\nLL | |     pub clippy::INVALID_TWO,\n...  |\nLL | |     report_in_external_macro: true\nLL | | }\n   | |_^\n   |\n   = help: please use a valid semantic version, see `doc/adding_lints.md`\n   = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this lint is missing the `clippy::version` attribute or version value\n  --> tests/ui-internal/check_clippy_version_attribute.rs:61:1\n   |\nLL | / declare_tool_lint! {\nLL | |\nLL | |     #[clippy::version]\nLL | |     pub clippy::MISSING_ATTRIBUTE_ONE,\n...  |\nLL | |     report_in_external_macro: true\nLL | | }\n   | |_^\n   |\n   = help: please use a `clippy::version` attribute, see `doc/adding_lints.md`\nnote: the lint level is defined here\n  --> tests/ui-internal/check_clippy_version_attribute.rs:2:51\n   |\nLL | #![deny(clippy::invalid_clippy_version_attribute, clippy::missing_clippy_version_attribute)]\n   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: this lint is missing the `clippy::version` attribute or version value\n  --> tests/ui-internal/check_clippy_version_attribute.rs:70:1\n   |\nLL | / declare_tool_lint! {\nLL | |\nLL | |     pub clippy::MISSING_ATTRIBUTE_TWO,\nLL | |     Warn,\nLL | |     \"Two\",\nLL | |     report_in_external_macro: true\nLL | | }\n   | |_^\n   |\n   = help: please use a `clippy::version` attribute, see `doc/adding_lints.md`\n   = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/check_formulation.rs",
    "content": "#![deny(clippy::almost_standard_lint_formulation)]\n#![allow(clippy::lint_without_lint_pass)]\n#![feature(rustc_private)]\n\n#[macro_use]\nextern crate rustc_middle;\n#[macro_use]\nextern crate rustc_session;\nextern crate rustc_lint;\n\ndeclare_tool_lint! {\n    /// # What it does\n    ///\n    /// Checks for usage of correct lint formulations\n    #[clippy::version = \"pre 1.29.0\"]\n    pub clippy::VALID,\n    Warn,\n    \"One\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    /// # What it does\n    /// Check for lint formulations that are correct\n    //~^ almost_standard_lint_formulation\n    #[clippy::version = \"pre 1.29.0\"]\n    pub clippy::INVALID1,\n    Warn,\n    \"One\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    /// # What it does\n    /// Detects uses of incorrect formulations\n    //~^ almost_standard_lint_formulation\n    #[clippy::version = \"pre 1.29.0\"]\n    pub clippy::INVALID2,\n    Warn,\n    \"One\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    /// # What it does\n    /// Detects uses of incorrect formulations (allowed with attribute)\n    #[allow(clippy::almost_standard_lint_formulation)]\n    #[clippy::version = \"pre 1.29.0\"]\n    pub clippy::ALLOWED_INVALID,\n    Warn,\n    \"One\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(Pass => [VALID, INVALID1, INVALID2]);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/check_formulation.stderr",
    "content": "error: non-standard lint formulation\n  --> tests/ui-internal/check_formulation.rs:24:5\n   |\nLL |     /// Check for lint formulations that are correct\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Checks for`\nnote: the lint level is defined here\n  --> tests/ui-internal/check_formulation.rs:1:9\n   |\nLL | #![deny(clippy::almost_standard_lint_formulation)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: non-standard lint formulation\n  --> tests/ui-internal/check_formulation.rs:35:5\n   |\nLL |     /// Detects uses of incorrect formulations\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider using `Checks for`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/collapsible_span_lint_calls.fixed",
    "content": "#![deny(clippy::collapsible_span_lint_calls)]\n#![allow(clippy::missing_clippy_version_attribute)]\n#![feature(rustc_private)]\n\nextern crate clippy_utils;\nextern crate rustc_ast;\nextern crate rustc_errors;\nextern crate rustc_lint;\nextern crate rustc_session;\nextern crate rustc_span;\n\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};\nuse rustc_ast::ast::Expr;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::{declare_lint_pass, declare_tool_lint};\n\ndeclare_tool_lint! {\n    pub clippy::TEST_LINT,\n    Warn,\n    \"\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(Pass => [TEST_LINT]);\n\nimpl EarlyLintPass for Pass {\n    fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {\n        let lint_msg = \"lint message\";\n        let help_msg = \"help message\";\n        let note_msg = \"note message\";\n        let sugg = \"new_call()\";\n        let predicate = true;\n\n        span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, help_msg, sugg.to_string(), Applicability::MachineApplicable);\n        span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg);\n        span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg);\n        span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg);\n        span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, note_msg);\n\n        // This expr shouldn't trigger this lint.\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            db.note(note_msg);\n            if predicate {\n                db.note(note_msg);\n            }\n        });\n\n        // Issue #8798\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            db.help(help_msg).help(help_msg);\n        });\n\n        // Issue #15880\n        #[expect(clippy::disallowed_names)]\n        let foo = \"foo\";\n        span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, format!(\"try using {foo}\"), format!(\"{foo}.use\"), Applicability::MachineApplicable);\n        span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), format!(\"try using {foo}\"));\n        span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, format!(\"try using {foo}\"));\n        span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), format!(\"required because of {foo}\"));\n        span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, format!(\"required because of {foo}\"));\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/collapsible_span_lint_calls.rs",
    "content": "#![deny(clippy::collapsible_span_lint_calls)]\n#![allow(clippy::missing_clippy_version_attribute)]\n#![feature(rustc_private)]\n\nextern crate clippy_utils;\nextern crate rustc_ast;\nextern crate rustc_errors;\nextern crate rustc_lint;\nextern crate rustc_session;\nextern crate rustc_span;\n\nuse clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};\nuse rustc_ast::ast::Expr;\nuse rustc_errors::Applicability;\nuse rustc_lint::{EarlyContext, EarlyLintPass};\nuse rustc_session::{declare_lint_pass, declare_tool_lint};\n\ndeclare_tool_lint! {\n    pub clippy::TEST_LINT,\n    Warn,\n    \"\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(Pass => [TEST_LINT]);\n\nimpl EarlyLintPass for Pass {\n    fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {\n        let lint_msg = \"lint message\";\n        let help_msg = \"help message\";\n        let note_msg = \"note message\";\n        let sugg = \"new_call()\";\n        let predicate = true;\n\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);\n        });\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.span_help(expr.span, help_msg);\n        });\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.help(help_msg);\n        });\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.span_note(expr.span, note_msg);\n        });\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.note(note_msg);\n        });\n\n        // This expr shouldn't trigger this lint.\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            db.note(note_msg);\n            if predicate {\n                db.note(note_msg);\n            }\n        });\n\n        // Issue #8798\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            db.help(help_msg).help(help_msg);\n        });\n\n        // Issue #15880\n        #[expect(clippy::disallowed_names)]\n        let foo = \"foo\";\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.span_suggestion(\n                expr.span,\n                format!(\"try using {foo}\"),\n                format!(\"{foo}.use\"),\n                Applicability::MachineApplicable,\n            );\n        });\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.span_help(expr.span, format!(\"try using {foo}\"));\n        });\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.help(format!(\"try using {foo}\"));\n        });\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.span_note(expr.span, format!(\"required because of {foo}\"));\n        });\n        span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\n            //~^ collapsible_span_lint_calls\n            db.note(format!(\"required because of {foo}\"));\n        });\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/collapsible_span_lint_calls.stderr",
    "content": "error: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:35:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.span_suggestion(expr.span, help_msg, sugg.to_string(), Applicability::MachineApplicable);\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, help_msg, sugg.to_string(), Applicability::MachineApplicable)`\n   |\nnote: the lint level is defined here\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:1:9\n   |\nLL | #![deny(clippy::collapsible_span_lint_calls)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:39:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.span_help(expr.span, help_msg);\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), help_msg)`\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:43:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.help(help_msg);\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg)`\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:47:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.span_note(expr.span, note_msg);\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg)`\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:51:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.note(note_msg);\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, note_msg)`\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:72:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.span_suggestion(\nLL | |                 expr.span,\n...  |\nLL | |             );\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_sugg(cx, TEST_LINT, expr.span, lint_msg, format!(\"try using {foo}\"), format!(\"{foo}.use\"), Applicability::MachineApplicable)`\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:81:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.span_help(expr.span, format!(\"try using {foo}\"));\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), format!(\"try using {foo}\"))`\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:85:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.help(format!(\"try using {foo}\"));\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, format!(\"try using {foo}\"))`\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:89:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.span_note(expr.span, format!(\"required because of {foo}\"));\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), format!(\"required because of {foo}\"))`\n\nerror: this call is collapsible\n  --> tests/ui-internal/collapsible_span_lint_calls.rs:93:9\n   |\nLL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {\nLL | |\nLL | |             db.note(format!(\"required because of {foo}\"));\nLL | |         });\n   | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, None, format!(\"required because of {foo}\"))`\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/custom_ice_message.rs",
    "content": "//@rustc-env:RUST_BACKTRACE=0\n//@normalize-stderr-test: \"Clippy version: .*\" -> \"Clippy version: foo\"\n//@normalize-stderr-test: \"produce_ice.rs:\\d*:\\d*\" -> \"produce_ice.rs\"\n//@normalize-stderr-test: \"', .*clippy_lints\" -> \"', clippy_lints\"\n//@normalize-stderr-test: \"'rustc'\" -> \"'<unnamed>'\"\n//@normalize-stderr-test: \"rustc 1\\.\\d+.* running on .*\" -> \"rustc <version> running on <target>\"\n//@normalize-stderr-test: \"(?ms)query stack during panic:\\n.*end of query stack\\n\" -> \"\"\n\n#![deny(clippy::produce_ice)]\n#![allow(clippy::missing_clippy_version_attribute)]\n\nfn it_looks_like_you_are_trying_to_kill_clippy() {}\n//~^ ice: Would you like some help with that?\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/custom_ice_message.stderr",
    "content": "note: no errors encountered even though delayed bugs were created\n\nnote: those delayed bugs will now be shown as internal compiler errors\n\nerror: internal compiler error: Would you like some help with that?\n  --> tests/ui-internal/custom_ice_message.rs:12:1\n   |\nLL | fn it_looks_like_you_are_trying_to_kill_clippy() {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: delayed at clippy_lints_internal/src/produce_ice.rs - disabled backtrace\n  --> tests/ui-internal/custom_ice_message.rs:12:1\n   |\nLL | fn it_looks_like_you_are_trying_to_kill_clippy() {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nnote: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml\n\nnote: please make sure that you have updated to the latest nightly\n\nnote: rustc <version> running on <target>\n\nnote: compiler flags: -Z ui-testing -Z deduplicate-diagnostics=no\n\nnote: Clippy version: foo\n\n"
  },
  {
    "path": "tests/ui-internal/default_lint.rs",
    "content": "#![deny(clippy::default_lint)]\n#![allow(clippy::missing_clippy_version_attribute)]\n#![feature(rustc_private)]\n\n#[macro_use]\nextern crate rustc_middle;\n#[macro_use]\nextern crate rustc_session;\nextern crate rustc_lint;\n\ndeclare_tool_lint! {\n    pub clippy::TEST_LINT,\n    Warn,\n    \"\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n//~^ default_lint\n    pub clippy::TEST_LINT_DEFAULT,\n    Warn,\n    \"default lint description\",\n    report_in_external_macro: true\n}\n\ndeclare_lint_pass!(Pass => [TEST_LINT]);\ndeclare_lint_pass!(Pass2 => [TEST_LINT_DEFAULT]);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/default_lint.stderr",
    "content": "error: the lint `TEST_LINT_DEFAULT` has the default lint description\n  --> tests/ui-internal/default_lint.rs:18:1\n   |\nLL | / declare_tool_lint! {\nLL | |\nLL | |     pub clippy::TEST_LINT_DEFAULT,\nLL | |     Warn,\nLL | |     \"default lint description\",\nLL | |     report_in_external_macro: true\nLL | | }\n   | |_^\n   |\nnote: the lint level is defined here\n  --> tests/ui-internal/default_lint.rs:1:9\n   |\nLL | #![deny(clippy::default_lint)]\n   |         ^^^^^^^^^^^^^^^^^^^^\n   = note: this error originates in the macro `$crate::declare_tool_lint` which comes from the expansion of the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-internal/derive_deserialize_allowing_unknown.rs",
    "content": "#![deny(clippy::derive_deserialize_allowing_unknown)]\n\nuse serde::{Deserialize, Deserializer};\n\n#[derive(Deserialize)] //~ derive_deserialize_allowing_unknown\nstruct Struct {\n    flag: bool,\n    limit: u64,\n}\n\n#[derive(Deserialize)] //~ derive_deserialize_allowing_unknown\nenum Enum {\n    A(bool),\n    B { limit: u64 },\n}\n\n// negative tests\n\n#[derive(Deserialize)]\n#[serde(deny_unknown_fields)]\nstruct StructWithDenyUnknownFields {\n    flag: bool,\n    limit: u64,\n}\n\n#[derive(Deserialize)]\n#[serde(deny_unknown_fields)]\nenum EnumWithDenyUnknownFields {\n    A(bool),\n    B { limit: u64 },\n}\n\n#[derive(Deserialize)]\n#[serde(untagged, deny_unknown_fields)]\nenum MultipleSerdeAttributes {\n    A(bool),\n    B { limit: u64 },\n}\n\n#[derive(Deserialize)]\nstruct TupleStruct(u64, bool);\n\n#[derive(Deserialize)]\n#[serde(deny_unknown_fields)]\nenum EnumWithOnlyTupleVariants {\n    A(bool),\n    B(u64),\n}\n\nstruct ManualSerdeImplementation;\n\nimpl<'de> Deserialize<'de> for ManualSerdeImplementation {\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: Deserializer<'de>,\n    {\n        let () = <() as Deserialize>::deserialize(deserializer)?;\n        Ok(ManualSerdeImplementation)\n    }\n}\n"
  },
  {
    "path": "tests/ui-internal/derive_deserialize_allowing_unknown.stderr",
    "content": "error: `#[derive(serde::Deserialize)]` without `#[serde(deny_unknown_fields)]`\n  --> tests/ui-internal/derive_deserialize_allowing_unknown.rs:5:10\n   |\nLL | #[derive(Deserialize)]\n   |          ^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-internal/derive_deserialize_allowing_unknown.rs:1:9\n   |\nLL | #![deny(clippy::derive_deserialize_allowing_unknown)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: `#[derive(serde::Deserialize)]` without `#[serde(deny_unknown_fields)]`\n  --> tests/ui-internal/derive_deserialize_allowing_unknown.rs:11:10\n   |\nLL | #[derive(Deserialize)]\n   |          ^^^^^^^^^^^\n   |\n   = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/disallow_span_lint.rs",
    "content": "#![feature(rustc_private)]\n#![deny(clippy::disallowed_methods)]\n\nextern crate rustc_errors;\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_middle;\n\nuse rustc_errors::{DiagMessage, MultiSpan};\nuse rustc_hir::hir_id::HirId;\nuse rustc_lint::{Lint, LintContext};\nuse rustc_middle::ty::TyCtxt;\n\npub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {\n    cx.span_lint(lint, span, |lint| {\n        //~^ disallowed_methods\n        lint.primary_message(msg);\n    });\n}\n\npub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {\n    tcx.node_span_lint(lint, hir_id, span, |lint| {\n        //~^ disallowed_methods\n        lint.primary_message(msg);\n    });\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/disallow_span_lint.stderr",
    "content": "error: use of a disallowed method `rustc_lint::context::LintContext::span_lint`\n  --> tests/ui-internal/disallow_span_lint.rs:15:8\n   |\nLL |     cx.span_lint(lint, span, |lint| {\n   |        ^^^^^^^^^\n   |\n   = note: this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead\nnote: the lint level is defined here\n  --> tests/ui-internal/disallow_span_lint.rs:2:9\n   |\nLL | #![deny(clippy::disallowed_methods)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint`\n  --> tests/ui-internal/disallow_span_lint.rs:22:9\n   |\nLL |     tcx.node_span_lint(lint, hir_id, span, |lint| {\n   |         ^^^^^^^^^^^^^^\n   |\n   = note: this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/interning_literals.fixed",
    "content": "#![allow(clippy::let_unit_value)]\n#![feature(rustc_private)]\n\nextern crate rustc_span;\n\nuse clippy_utils::sym;\nuse rustc_span::{Symbol, kw};\n\nfn main() {\n    let _ = sym::f32;\n    //~^ interning_literals\n\n    // Correct suggestion when symbol isn't stringified constant name\n    let _ = sym::proc_dash_macro;\n    //~^ interning_literals\n\n    // Interning a keyword\n    let _ = kw::SelfLower;\n    //~^ interning_literals\n\n    // Defined in clippy_utils\n    let _ = sym::msrv;\n    //~^ interning_literals\n    let _ = sym::Cargo_toml;\n    //~^ interning_literals\n\n    // Using a different `intern` function\n    let _ = intern(\"f32\");\n}\n\nfn intern(_: &str) {}\n"
  },
  {
    "path": "tests/ui-internal/interning_literals.rs",
    "content": "#![allow(clippy::let_unit_value)]\n#![feature(rustc_private)]\n\nextern crate rustc_span;\n\nuse clippy_utils::sym;\nuse rustc_span::{Symbol, kw};\n\nfn main() {\n    let _ = Symbol::intern(\"f32\");\n    //~^ interning_literals\n\n    // Correct suggestion when symbol isn't stringified constant name\n    let _ = Symbol::intern(\"proc-macro\");\n    //~^ interning_literals\n\n    // Interning a keyword\n    let _ = Symbol::intern(\"self\");\n    //~^ interning_literals\n\n    // Defined in clippy_utils\n    let _ = Symbol::intern(\"msrv\");\n    //~^ interning_literals\n    let _ = Symbol::intern(\"Cargo.toml\");\n    //~^ interning_literals\n\n    // Using a different `intern` function\n    let _ = intern(\"f32\");\n}\n\nfn intern(_: &str) {}\n"
  },
  {
    "path": "tests/ui-internal/interning_literals.stderr",
    "content": "error: interning a string literal\n  --> tests/ui-internal/interning_literals.rs:10:13\n   |\nLL |     let _ = Symbol::intern(\"f32\");\n   |             ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: add the symbol to `clippy_utils/src/sym.rs` if needed\n   = note: `-D clippy::interning-literals` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::interning_literals)]`\nhelp: use a preinterned symbol instead\n   |\nLL -     let _ = Symbol::intern(\"f32\");\nLL +     let _ = sym::f32;\n   |\n\nerror: interning a string literal\n  --> tests/ui-internal/interning_literals.rs:14:13\n   |\nLL |     let _ = Symbol::intern(\"proc-macro\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: add the symbol to `clippy_utils/src/sym.rs` if needed\nhelp: use a preinterned symbol instead\n   |\nLL -     let _ = Symbol::intern(\"proc-macro\");\nLL +     let _ = sym::proc_dash_macro;\n   |\n\nerror: interning a string literal\n  --> tests/ui-internal/interning_literals.rs:18:13\n   |\nLL |     let _ = Symbol::intern(\"self\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: add the symbol to `clippy_utils/src/sym.rs` if needed\nhelp: use a preinterned symbol instead\n   |\nLL -     let _ = Symbol::intern(\"self\");\nLL +     let _ = kw::SelfLower;\n   |\n\nerror: interning a string literal\n  --> tests/ui-internal/interning_literals.rs:22:13\n   |\nLL |     let _ = Symbol::intern(\"msrv\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: add the symbol to `clippy_utils/src/sym.rs` if needed\nhelp: use a preinterned symbol instead\n   |\nLL -     let _ = Symbol::intern(\"msrv\");\nLL +     let _ = sym::msrv;\n   |\n\nerror: interning a string literal\n  --> tests/ui-internal/interning_literals.rs:24:13\n   |\nLL |     let _ = Symbol::intern(\"Cargo.toml\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: add the symbol to `clippy_utils/src/sym.rs` if needed\nhelp: use a preinterned symbol instead\n   |\nLL -     let _ = Symbol::intern(\"Cargo.toml\");\nLL +     let _ = sym::Cargo_toml;\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/interning_literals_unfixable.rs",
    "content": "//@no-rustfix: paths that don't exist yet\n#![feature(rustc_private)]\n\nextern crate rustc_span;\n\nuse rustc_span::Symbol;\n\nfn main() {\n    // Not yet defined\n    let _ = Symbol::intern(\"xyz123\");\n    //~^ interning_literals\n    let _ = Symbol::intern(\"with-dash\");\n    //~^ interning_literals\n    let _ = Symbol::intern(\"with.dot\");\n    //~^ interning_literals\n}\n"
  },
  {
    "path": "tests/ui-internal/interning_literals_unfixable.stderr",
    "content": "error: interning a string literal\n  --> tests/ui-internal/interning_literals_unfixable.rs:10:13\n   |\nLL |     let _ = Symbol::intern(\"xyz123\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: add the symbol to `clippy_utils/src/sym.rs` if needed\n   = note: `-D clippy::interning-literals` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::interning_literals)]`\nhelp: use a preinterned symbol instead\n   |\nLL -     let _ = Symbol::intern(\"xyz123\");\nLL +     let _ = sym::xyz123;\n   |\n\nerror: interning a string literal\n  --> tests/ui-internal/interning_literals_unfixable.rs:12:13\n   |\nLL |     let _ = Symbol::intern(\"with-dash\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: add the symbol to `clippy_utils/src/sym.rs` if needed\nhelp: use a preinterned symbol instead\n   |\nLL -     let _ = Symbol::intern(\"with-dash\");\nLL +     let _ = sym::with_dash;\n   |\n\nerror: interning a string literal\n  --> tests/ui-internal/interning_literals_unfixable.rs:14:13\n   |\nLL |     let _ = Symbol::intern(\"with.dot\");\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: add the symbol to `clippy_utils/src/sym.rs` if needed\nhelp: use a preinterned symbol instead\n   |\nLL -     let _ = Symbol::intern(\"with.dot\");\nLL +     let _ = sym::with_dot;\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/invalid_msrv_attr_impl.fixed",
    "content": "#![deny(clippy::missing_msrv_attr_impl)]\n#![allow(clippy::missing_clippy_version_attribute)]\n#![feature(rustc_private)]\n\nextern crate rustc_ast;\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_middle;\n#[macro_use]\nextern crate rustc_session;\nuse clippy_utils::extract_msrv_attr;\nuse clippy_utils::msrvs::MsrvStack;\nuse rustc_hir::Expr;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};\n\ndeclare_lint! {\n    pub TEST_LINT,\n    Warn,\n    \"\"\n}\n\nstruct Pass {\n    msrv: MsrvStack,\n}\n\nimpl_lint_pass!(Pass => [TEST_LINT]);\n\nimpl EarlyLintPass for Pass {\n    extract_msrv_attr!();\n    //~^ missing_msrv_attr_impl\n    fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/invalid_msrv_attr_impl.rs",
    "content": "#![deny(clippy::missing_msrv_attr_impl)]\n#![allow(clippy::missing_clippy_version_attribute)]\n#![feature(rustc_private)]\n\nextern crate rustc_ast;\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_middle;\n#[macro_use]\nextern crate rustc_session;\nuse clippy_utils::extract_msrv_attr;\nuse clippy_utils::msrvs::MsrvStack;\nuse rustc_hir::Expr;\nuse rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};\n\ndeclare_lint! {\n    pub TEST_LINT,\n    Warn,\n    \"\"\n}\n\nstruct Pass {\n    msrv: MsrvStack,\n}\n\nimpl_lint_pass!(Pass => [TEST_LINT]);\n\nimpl EarlyLintPass for Pass {\n    //~^ missing_msrv_attr_impl\n    fn check_expr(&mut self, _: &EarlyContext<'_>, _: &rustc_ast::Expr) {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/invalid_msrv_attr_impl.stderr",
    "content": "error: `extract_msrv_attr!` macro missing from `EarlyLintPass` implementation\n  --> tests/ui-internal/invalid_msrv_attr_impl.rs:28:1\n   |\nLL | impl EarlyLintPass for Pass {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-internal/invalid_msrv_attr_impl.rs:1:9\n   |\nLL | #![deny(clippy::missing_msrv_attr_impl)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: add `extract_msrv_attr!()` to the `EarlyLintPass` implementation\n   |\nLL ~ impl EarlyLintPass for Pass {\nLL +     extract_msrv_attr!();\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-internal/lint_without_lint_pass.rs",
    "content": "#![deny(clippy::lint_without_lint_pass)]\n#![allow(clippy::missing_clippy_version_attribute)]\n#![feature(rustc_private)]\n\n#[macro_use]\nextern crate rustc_middle;\n#[macro_use]\nextern crate rustc_session;\nextern crate rustc_lint;\nuse rustc_lint::{LintPass, LintVec};\n\ndeclare_tool_lint! {\n//~^ lint_without_lint_pass\n    pub clippy::TEST_LINT,\n    Warn,\n    \"\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    pub clippy::TEST_LINT_REGISTERED,\n    Warn,\n    \"\",\n    report_in_external_macro: true\n}\n\ndeclare_tool_lint! {\n    pub clippy::TEST_LINT_REGISTERED_ONLY_IMPL,\n    Warn,\n    \"\",\n    report_in_external_macro: true\n}\n\npub struct Pass;\nimpl LintPass for Pass {\n    fn name(&self) -> &'static str {\n        \"TEST_LINT\"\n    }\n    fn get_lints(&self) -> LintVec {\n        vec![TEST_LINT]\n    }\n}\n\ndeclare_lint_pass!(Pass2 => [TEST_LINT_REGISTERED]);\n\npub struct Pass3;\nimpl_lint_pass!(Pass3 => [TEST_LINT_REGISTERED_ONLY_IMPL]);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/lint_without_lint_pass.stderr",
    "content": "error: the lint `TEST_LINT` is not added to any `LintPass`\n  --> tests/ui-internal/lint_without_lint_pass.rs:12:1\n   |\nLL | / declare_tool_lint! {\nLL | |\nLL | |     pub clippy::TEST_LINT,\nLL | |     Warn,\nLL | |     \"\",\nLL | |     report_in_external_macro: true\nLL | | }\n   | |_^\n   |\nnote: the lint level is defined here\n  --> tests/ui-internal/lint_without_lint_pass.rs:1:9\n   |\nLL | #![deny(clippy::lint_without_lint_pass)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: this error originates in the macro `declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-internal/outer_expn_data.fixed",
    "content": "#![deny(clippy::outer_expn_expn_data)]\n#![allow(clippy::missing_clippy_version_attribute)]\n#![feature(rustc_private)]\n\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_middle;\n#[macro_use]\nextern crate rustc_session;\nuse rustc_hir::Expr;\nuse rustc_lint::{LateContext, LateLintPass};\n\ndeclare_lint! {\n    pub TEST_LINT,\n    Warn,\n    \"\"\n}\n\ndeclare_lint_pass!(Pass => [TEST_LINT]);\n\nimpl<'tcx> LateLintPass<'tcx> for Pass {\n    fn check_expr(&mut self, _cx: &LateContext<'tcx>, expr: &'tcx Expr) {\n        let _ = expr.span.ctxt().outer_expn_data();\n        //~^ outer_expn_expn_data\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/outer_expn_data.rs",
    "content": "#![deny(clippy::outer_expn_expn_data)]\n#![allow(clippy::missing_clippy_version_attribute)]\n#![feature(rustc_private)]\n\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_middle;\n#[macro_use]\nextern crate rustc_session;\nuse rustc_hir::Expr;\nuse rustc_lint::{LateContext, LateLintPass};\n\ndeclare_lint! {\n    pub TEST_LINT,\n    Warn,\n    \"\"\n}\n\ndeclare_lint_pass!(Pass => [TEST_LINT]);\n\nimpl<'tcx> LateLintPass<'tcx> for Pass {\n    fn check_expr(&mut self, _cx: &LateContext<'tcx>, expr: &'tcx Expr) {\n        let _ = expr.span.ctxt().outer_expn().expn_data();\n        //~^ outer_expn_expn_data\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/outer_expn_data.stderr",
    "content": "error: usage of `outer_expn().expn_data()`\n  --> tests/ui-internal/outer_expn_data.rs:23:34\n   |\nLL |         let _ = expr.span.ctxt().outer_expn().expn_data();\n   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `outer_expn_data()`\n   |\nnote: the lint level is defined here\n  --> tests/ui-internal/outer_expn_data.rs:1:9\n   |\nLL | #![deny(clippy::outer_expn_expn_data)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-internal/repeated_is_diagnostic_item.fixed",
    "content": "#![feature(rustc_private)]\n\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_middle;\nextern crate rustc_span;\n\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_hir::def_id::DefId;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{AdtDef, Ty, TyCtxt};\nuse rustc_span::Symbol;\n\nfn binops(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) {\n    let did = ty.opt_def_id().unwrap();\n\n    let _ = matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result));\n    //~^ repeated_is_diagnostic_item\n    let _ = !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result));\n    //~^ repeated_is_diagnostic_item\n    let _ = matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result));\n    //~^ repeated_is_diagnostic_item\n    let _ = !matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result));\n    //~^ repeated_is_diagnostic_item\n    let _ = matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result));\n    //~^ repeated_is_diagnostic_item\n    let _ = !matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result));\n    //~^ repeated_is_diagnostic_item\n\n    // Don't lint: `is_diagnostic_item` is called not on `TyCtxt`\n    struct FakeTyCtxt;\n    impl FakeTyCtxt {\n        fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool {\n            unimplemented!()\n        }\n    }\n    let f = FakeTyCtxt;\n    let _ = f.is_diagnostic_item(sym::Option, did) || f.is_diagnostic_item(sym::Result, did);\n\n    // Don't lint: `is_diagnostic_item` on `TyCtxt` comes from a(n unrelated) trait\n    trait IsDiagnosticItem {\n        fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool;\n    }\n    impl IsDiagnosticItem for TyCtxt<'_> {\n        fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool {\n            unimplemented!()\n        }\n    }\n    let _ = IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Option, did)\n        || IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Result, did);\n\n    // Don't lint: `is_diag_item` is an inherent method\n    struct DoesntImplMaybeDef;\n    impl DoesntImplMaybeDef {\n        fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool {\n            unimplemented!()\n        }\n    }\n    let d = DoesntImplMaybeDef;\n    let _ = d.is_diag_item(cx, sym::Option) || d.is_diag_item(cx, sym::Result);\n\n    // Don't lint: `is_diag_item` comes from a trait other than `MaybeDef`\n    trait FakeMaybeDef {\n        fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool;\n    }\n    struct Bar;\n    impl FakeMaybeDef for Bar {\n        fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool {\n            unimplemented!()\n        }\n    }\n    let b = Bar;\n    let _ = b.is_diag_item(cx, sym::Option) || b.is_diag_item(cx, sym::Result);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/repeated_is_diagnostic_item.rs",
    "content": "#![feature(rustc_private)]\n\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_middle;\nextern crate rustc_span;\n\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_hir::def_id::DefId;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{AdtDef, Ty, TyCtxt};\nuse rustc_span::Symbol;\n\nfn binops(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) {\n    let did = ty.opt_def_id().unwrap();\n\n    let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result);\n    //~^ repeated_is_diagnostic_item\n    let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result);\n    //~^ repeated_is_diagnostic_item\n    let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result);\n    //~^ repeated_is_diagnostic_item\n    let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result);\n    //~^ repeated_is_diagnostic_item\n    let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did);\n    //~^ repeated_is_diagnostic_item\n    let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did);\n    //~^ repeated_is_diagnostic_item\n\n    // Don't lint: `is_diagnostic_item` is called not on `TyCtxt`\n    struct FakeTyCtxt;\n    impl FakeTyCtxt {\n        fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool {\n            unimplemented!()\n        }\n    }\n    let f = FakeTyCtxt;\n    let _ = f.is_diagnostic_item(sym::Option, did) || f.is_diagnostic_item(sym::Result, did);\n\n    // Don't lint: `is_diagnostic_item` on `TyCtxt` comes from a(n unrelated) trait\n    trait IsDiagnosticItem {\n        fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool;\n    }\n    impl IsDiagnosticItem for TyCtxt<'_> {\n        fn is_diagnostic_item(&self, sym: Symbol, did: DefId) -> bool {\n            unimplemented!()\n        }\n    }\n    let _ = IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Option, did)\n        || IsDiagnosticItem::is_diagnostic_item(&cx.tcx, sym::Result, did);\n\n    // Don't lint: `is_diag_item` is an inherent method\n    struct DoesntImplMaybeDef;\n    impl DoesntImplMaybeDef {\n        fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool {\n            unimplemented!()\n        }\n    }\n    let d = DoesntImplMaybeDef;\n    let _ = d.is_diag_item(cx, sym::Option) || d.is_diag_item(cx, sym::Result);\n\n    // Don't lint: `is_diag_item` comes from a trait other than `MaybeDef`\n    trait FakeMaybeDef {\n        fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool;\n    }\n    struct Bar;\n    impl FakeMaybeDef for Bar {\n        fn is_diag_item(&self, cx: &LateContext, sym: Symbol) -> bool {\n            unimplemented!()\n        }\n    }\n    let b = Bar;\n    let _ = b.is_diag_item(cx, sym::Option) || b.is_diag_item(cx, sym::Result);\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-internal/repeated_is_diagnostic_item.stderr",
    "content": "error: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item.rs:18:13\n   |\nLL |     let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\n   = note: `-D clippy::repeated-is-diagnostic-item` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::repeated_is_diagnostic_item)]`\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL -     let _ = ty.is_diag_item(cx, sym::Option) || ty.is_diag_item(cx, sym::Result);\nLL +     let _ = matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result));\n   |\n\nerror: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item.rs:20:13\n   |\nLL |     let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL -     let _ = !ty.is_diag_item(cx, sym::Option) && !ty.is_diag_item(cx, sym::Result);\nLL +     let _ = !matches!(ty.opt_diag_name(cx), Some(sym::Option | sym::Result));\n   |\n\nerror: repeated calls to `AdtDef::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item.rs:22:13\n   |\nLL |     let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `AdtDef::opt_diag_name`, and reuse the results\n   |\nLL -     let _ = adt_def.is_diag_item(cx, sym::Option) || adt_def.is_diag_item(cx, sym::Result);\nLL +     let _ = matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result));\n   |\n\nerror: repeated calls to `AdtDef::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item.rs:24:13\n   |\nLL |     let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `AdtDef::opt_diag_name`, and reuse the results\n   |\nLL -     let _ = !adt_def.is_diag_item(cx, sym::Option) && !adt_def.is_diag_item(cx, sym::Result);\nLL +     let _ = !matches!(adt_def.opt_diag_name(cx), Some(sym::Option | sym::Result));\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item.rs:26:13\n   |\nLL |     let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL -     let _ = cx.tcx.is_diagnostic_item(sym::Option, did) || cx.tcx.is_diagnostic_item(sym::Result, did);\nLL +     let _ = matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result));\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item.rs:28:13\n   |\nLL |     let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL -     let _ = !cx.tcx.is_diagnostic_item(sym::Option, did) && !cx.tcx.is_diagnostic_item(sym::Result, did);\nLL +     let _ = !matches!(cx.tcx.get_diagnostic_name(did), Some(sym::Option | sym::Result));\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs",
    "content": "//@no-rustfix\n#![feature(rustc_private)]\n\nextern crate rustc_hir;\nextern crate rustc_lint;\nextern crate rustc_middle;\nextern crate rustc_span;\n\nuse clippy_utils::res::MaybeDef;\nuse clippy_utils::sym;\nuse rustc_hir::def_id::DefId;\nuse rustc_lint::LateContext;\nuse rustc_middle::ty::{AdtDef, Ty, TyCtxt};\nuse rustc_span::Symbol;\n\nfn main() {}\n\n// if-chains with repeated calls on the same `ty`\nfn if_chains(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) {\n    let did = ty.opt_def_id().unwrap();\n\n    let _ = if ty.is_diag_item(cx, sym::Option) {\n        //~^ repeated_is_diagnostic_item\n        \"Option\"\n    } else if ty.is_diag_item(cx, sym::Result) {\n        \"Result\"\n    } else {\n        return;\n    };\n    // should ideally suggest the following:\n    // let _ = match ty.opt_diag_name() {\n    //     Some(sym::Option) => {\n    //         \"Option\"\n    //     }\n    //     Some(sym::Result) => {\n    //         \"Result\"\n    //     }\n    //     _ => {\n    //         return;\n    //     }\n    // };\n\n    // same but in a stmt\n    if ty.is_diag_item(cx, sym::Option) {\n        //~^ repeated_is_diagnostic_item\n        eprintln!(\"Option\");\n    } else if ty.is_diag_item(cx, sym::Result) {\n        eprintln!(\"Result\");\n    }\n    // should ideally suggest the following:\n    // match ty.opt_diag_name() {\n    //     Some(sym::Option) => {\n    //         \"Option\"\n    //     }\n    //     Some(sym::Result) => {\n    //         \"Result\"\n    //     }\n    //     _ => {}\n    // };\n\n    // nested conditions\n    let _ = if ty.is_diag_item(cx, sym::Option) && 4 == 5 {\n        //~^ repeated_is_diagnostic_item\n        \"Option\"\n    } else if ty.is_diag_item(cx, sym::Result) && 4 == 5 {\n        \"Result\"\n    } else {\n        return;\n    };\n\n    let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) {\n        //~^ repeated_is_diagnostic_item\n        \"Option\"\n    } else if cx.tcx.is_diagnostic_item(sym::Result, did) {\n        \"Result\"\n    } else {\n        return;\n    };\n    // should ideally suggest the following:\n    // let _ = match cx.get_diagnostic_name(did) {\n    //     Some(sym::Option) => {\n    //         \"Option\"\n    //     }\n    //     Some(sym::Result) => {\n    //         \"Result\"\n    //     }\n    //     _ => {\n    //         return;\n    //     }\n    // };\n\n    // same but in a stmt\n    if cx.tcx.is_diagnostic_item(sym::Option, did) {\n        //~^ repeated_is_diagnostic_item\n        eprintln!(\"Option\");\n    } else if cx.tcx.is_diagnostic_item(sym::Result, did) {\n        eprintln!(\"Result\");\n    }\n    // should ideally suggest the following:\n    // match cx.tcx.get_diagnostic_name(did) {\n    //     Some(sym::Option) => {\n    //         \"Option\"\n    //     }\n    //     Some(sym::Result) => {\n    //         \"Result\"\n    //     }\n    //     _ => {}\n    // };\n\n    // nested conditions\n    let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 {\n        //~^ repeated_is_diagnostic_item\n        \"Option\"\n    } else if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 {\n        \"Result\"\n    } else {\n        return;\n    };\n}\n\n// if-chains with repeated calls on the same `ty`\nfn consecutive_ifs(cx: &LateContext<'_>, ty: Ty<'_>, adt_def: &AdtDef<'_>) {\n    let did = ty.opt_def_id().unwrap();\n\n    {\n        if ty.is_diag_item(cx, sym::Option) {\n            //~^ repeated_is_diagnostic_item\n            println!(\"Option\");\n        }\n        if ty.is_diag_item(cx, sym::Result) {\n            println!(\"Result\");\n        }\n        println!(\"done!\")\n    }\n\n    // nested conditions\n    {\n        if ty.is_diag_item(cx, sym::Option) && 4 == 5 {\n            //~^ repeated_is_diagnostic_item\n            println!(\"Option\");\n        }\n        if ty.is_diag_item(cx, sym::Result) && 4 == 5 {\n            println!(\"Result\");\n        }\n        println!(\"done!\")\n    }\n\n    {\n        if cx.tcx.is_diagnostic_item(sym::Option, did) {\n            //~^ repeated_is_diagnostic_item\n            println!(\"Option\");\n        }\n        if cx.tcx.is_diagnostic_item(sym::Result, did) {\n            println!(\"Result\");\n        }\n        println!(\"done!\")\n    }\n\n    // nested conditions\n    {\n        if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 {\n            //~^ repeated_is_diagnostic_item\n            println!(\"Option\");\n        }\n        if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 {\n            println!(\"Result\");\n        }\n        println!(\"done!\")\n    }\n\n    // All the same, but the second if is the final expression\n    {\n        if ty.is_diag_item(cx, sym::Option) {\n            //~^ repeated_is_diagnostic_item\n            println!(\"Option\");\n        }\n        if ty.is_diag_item(cx, sym::Result) {\n            println!(\"Result\");\n        }\n    }\n\n    // nested conditions\n    {\n        if ty.is_diag_item(cx, sym::Option) && 4 == 5 {\n            //~^ repeated_is_diagnostic_item\n            println!(\"Option\");\n        }\n        if ty.is_diag_item(cx, sym::Result) && 4 == 5 {\n            println!(\"Result\");\n        }\n    }\n\n    {\n        if cx.tcx.is_diagnostic_item(sym::Option, did) {\n            //~^ repeated_is_diagnostic_item\n            println!(\"Option\");\n        }\n        if cx.tcx.is_diagnostic_item(sym::Result, did) {\n            println!(\"Result\");\n        }\n    }\n\n    // nested conditions\n    {\n        if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 {\n            //~^ repeated_is_diagnostic_item\n            println!(\"Option\");\n        }\n        if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 {\n            println!(\"Result\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui-internal/repeated_is_diagnostic_item_unfixable.stderr",
    "content": "error: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:22:13\n   |\nLL |       let _ = if ty.is_diag_item(cx, sym::Option) {\n   |               ^  -------------------------------- called here\n   |  _____________|\n   | |\nLL | |\nLL | |         \"Option\"\nLL | |     } else if ty.is_diag_item(cx, sym::Result) {\n   | |               -------------------------------- called here\n...  |\nLL | |         return;\nLL | |     };\n   | |_____^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\n   = note: `-D clippy::repeated-is-diagnostic-item` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::repeated_is_diagnostic_item)]`\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL ~     let /* name */ = ty.opt_diag_name(cx);\nLL ~     let _ = if /* name */ == Some(sym::Option) {\nLL |\nLL |         \"Option\"\nLL ~     } else if /* name */ == Some(sym::Result) {\n   |\n\nerror: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:44:5\n   |\nLL |       if ty.is_diag_item(cx, sym::Option) {\n   |       ^  -------------------------------- called here\n   |  _____|\n   | |\nLL | |\nLL | |         eprintln!(\"Option\");\nLL | |     } else if ty.is_diag_item(cx, sym::Result) {\n   | |               -------------------------------- called here\nLL | |         eprintln!(\"Result\");\nLL | |     }\n   | |_____^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL ~     let /* name */ = ty.opt_diag_name(cx);\nLL ~     if /* name */ == Some(sym::Option) {\nLL |\nLL |         eprintln!(\"Option\");\nLL ~     } else if /* name */ == Some(sym::Result) {\n   |\n\nerror: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:62:13\n   |\nLL |       let _ = if ty.is_diag_item(cx, sym::Option) && 4 == 5 {\n   |               ^  -------------------------------- called here\n   |  _____________|\n   | |\nLL | |\nLL | |         \"Option\"\nLL | |     } else if ty.is_diag_item(cx, sym::Result) && 4 == 5 {\n   | |               -------------------------------- called here\n...  |\nLL | |         return;\nLL | |     };\n   | |_____^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL ~     let /* name */ = ty.opt_diag_name(cx);\nLL ~     let _ = if /* name */ == Some(sym::Option) && 4 == 5 {\nLL |\nLL |         \"Option\"\nLL ~     } else if /* name */ == Some(sym::Result) && 4 == 5 {\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:71:13\n   |\nLL |       let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) {\n   |               ^  ------------------------------------------- called here\n   |  _____________|\n   | |\nLL | |\nLL | |         \"Option\"\nLL | |     } else if cx.tcx.is_diagnostic_item(sym::Result, did) {\n   | |               ------------------------------------------- called here\n...  |\nLL | |         return;\nLL | |     };\n   | |_____^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL ~     let /* name */ = cx.tcx.get_diagnostic_name(did);\nLL ~     let _ = if /* name */ == Some(sym::Option) {\nLL |\nLL |         \"Option\"\nLL ~     } else if /* name */ == Some(sym::Result) {\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:93:5\n   |\nLL |       if cx.tcx.is_diagnostic_item(sym::Option, did) {\n   |       ^  ------------------------------------------- called here\n   |  _____|\n   | |\nLL | |\nLL | |         eprintln!(\"Option\");\nLL | |     } else if cx.tcx.is_diagnostic_item(sym::Result, did) {\n   | |               ------------------------------------------- called here\nLL | |         eprintln!(\"Result\");\nLL | |     }\n   | |_____^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL ~     let /* name */ = cx.tcx.get_diagnostic_name(did);\nLL ~     if /* name */ == Some(sym::Option) {\nLL |\nLL |         eprintln!(\"Option\");\nLL ~     } else if /* name */ == Some(sym::Result) {\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:111:13\n   |\nLL |       let _ = if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 {\n   |               ^  ------------------------------------------- called here\n   |  _____________|\n   | |\nLL | |\nLL | |         \"Option\"\nLL | |     } else if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 {\n   | |               ------------------------------------------- called here\n...  |\nLL | |         return;\nLL | |     };\n   | |_____^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL ~     let /* name */ = cx.tcx.get_diagnostic_name(did);\nLL ~     let _ = if /* name */ == Some(sym::Option) && 4 == 5 {\nLL |\nLL |         \"Option\"\nLL ~     } else if /* name */ == Some(sym::Result) && 4 == 5 {\n   |\n\nerror: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:126:9\n   |\nLL |           if ty.is_diag_item(cx, sym::Option) {\n   |           ^  -------------------------------- called here\n   |  _________|\n   | |\nLL | |\nLL | |             println!(\"Option\");\nLL | |         }\nLL | |         if ty.is_diag_item(cx, sym::Result) {\n   | |            -------------------------------- called here\nLL | |             println!(\"Result\");\nLL | |         }\n   | |_________^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL ~         let /* name */ = ty.opt_diag_name(cx);\nLL ~         if /* name */ == Some(sym::Option) {\nLL |\nLL |             println!(\"Option\");\nLL |         }\nLL ~         if /* name */ == Some(sym::Result) {\n   |\n\nerror: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:138:9\n   |\nLL |           if ty.is_diag_item(cx, sym::Option) && 4 == 5 {\n   |           ^  -------------------------------- called here\n   |  _________|\n   | |\nLL | |\nLL | |             println!(\"Option\");\nLL | |         }\nLL | |         if ty.is_diag_item(cx, sym::Result) && 4 == 5 {\n   | |            -------------------------------- called here\nLL | |             println!(\"Result\");\nLL | |         }\n   | |_________^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL ~         let /* name */ = ty.opt_diag_name(cx);\nLL ~         if /* name */ == Some(sym::Option) && 4 == 5 {\nLL |\nLL |             println!(\"Option\");\nLL |         }\nLL ~         if /* name */ == Some(sym::Result) && 4 == 5 {\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:149:9\n   |\nLL |           if cx.tcx.is_diagnostic_item(sym::Option, did) {\n   |           ^  ------------------------------------------- called here\n   |  _________|\n   | |\nLL | |\nLL | |             println!(\"Option\");\nLL | |         }\nLL | |         if cx.tcx.is_diagnostic_item(sym::Result, did) {\n   | |            ------------------------------------------- called here\nLL | |             println!(\"Result\");\nLL | |         }\n   | |_________^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL ~         let /* name */ = cx.tcx.get_diagnostic_name(did);\nLL ~         if /* name */ == Some(sym::Option) {\nLL |\nLL |             println!(\"Option\");\nLL |         }\nLL ~         if /* name */ == Some(sym::Result) {\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:161:9\n   |\nLL |           if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 {\n   |           ^  ------------------------------------------- called here\n   |  _________|\n   | |\nLL | |\nLL | |             println!(\"Option\");\nLL | |         }\nLL | |         if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 {\n   | |            ------------------------------------------- called here\nLL | |             println!(\"Result\");\nLL | |         }\n   | |_________^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL ~         let /* name */ = cx.tcx.get_diagnostic_name(did);\nLL ~         if /* name */ == Some(sym::Option) && 4 == 5 {\nLL |\nLL |             println!(\"Option\");\nLL |         }\nLL ~         if /* name */ == Some(sym::Result) && 4 == 5 {\n   |\n\nerror: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:173:9\n   |\nLL |           if ty.is_diag_item(cx, sym::Option) {\n   |           ^  -------------------------------- called here\n   |  _________|\n   | |\nLL | |\nLL | |             println!(\"Option\");\nLL | |         }\nLL | |         if ty.is_diag_item(cx, sym::Result) {\n   | |            -------------------------------- called here\nLL | |             println!(\"Result\");\nLL | |         }\n   | |_________^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL ~         let /* name */ = ty.opt_diag_name(cx);\nLL ~         if /* name */ == Some(sym::Option) {\nLL |\nLL |             println!(\"Option\");\nLL |         }\nLL ~         if /* name */ == Some(sym::Result) {\n   |\n\nerror: repeated calls to `Ty::is_diag_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:184:9\n   |\nLL |           if ty.is_diag_item(cx, sym::Option) && 4 == 5 {\n   |           ^  -------------------------------- called here\n   |  _________|\n   | |\nLL | |\nLL | |             println!(\"Option\");\nLL | |         }\nLL | |         if ty.is_diag_item(cx, sym::Result) && 4 == 5 {\n   | |            -------------------------------- called here\nLL | |             println!(\"Result\");\nLL | |         }\n   | |_________^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `Ty::opt_diag_name`, and reuse the results\n   |\nLL ~         let /* name */ = ty.opt_diag_name(cx);\nLL ~         if /* name */ == Some(sym::Option) && 4 == 5 {\nLL |\nLL |             println!(\"Option\");\nLL |         }\nLL ~         if /* name */ == Some(sym::Result) && 4 == 5 {\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:194:9\n   |\nLL |           if cx.tcx.is_diagnostic_item(sym::Option, did) {\n   |           ^  ------------------------------------------- called here\n   |  _________|\n   | |\nLL | |\nLL | |             println!(\"Option\");\nLL | |         }\nLL | |         if cx.tcx.is_diagnostic_item(sym::Result, did) {\n   | |            ------------------------------------------- called here\nLL | |             println!(\"Result\");\nLL | |         }\n   | |_________^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL ~         let /* name */ = cx.tcx.get_diagnostic_name(did);\nLL ~         if /* name */ == Some(sym::Option) {\nLL |\nLL |             println!(\"Option\");\nLL |         }\nLL ~         if /* name */ == Some(sym::Result) {\n   |\n\nerror: repeated calls to `TyCtxt::is_diagnostic_item`\n  --> tests/ui-internal/repeated_is_diagnostic_item_unfixable.rs:205:9\n   |\nLL |           if cx.tcx.is_diagnostic_item(sym::Option, did) && 4 == 5 {\n   |           ^  ------------------------------------------- called here\n   |  _________|\n   | |\nLL | |\nLL | |             println!(\"Option\");\nLL | |         }\nLL | |         if cx.tcx.is_diagnostic_item(sym::Result, did) && 4 == 5 {\n   | |            ------------------------------------------- called here\nLL | |             println!(\"Result\");\nLL | |         }\n   | |_________^\n   |\n   = note: each call performs the same compiler query -- it's faster to query once, and reuse the results\nhelp: call `TyCtxt::get_diagnostic_name`, and reuse the results\n   |\nLL ~         let /* name */ = cx.tcx.get_diagnostic_name(did);\nLL ~         if /* name */ == Some(sym::Option) && 4 == 5 {\nLL |\nLL |             println!(\"Option\");\nLL |         }\nLL ~         if /* name */ == Some(sym::Result) && 4 == 5 {\n   |\n\nerror: aborting due to 14 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/symbol_as_str.fixed",
    "content": "#![feature(rustc_private)]\n\nextern crate rustc_span;\n\nuse clippy_utils::sym;\nuse rustc_span::{Symbol, kw};\n\nfn f(s: Symbol) {\n    s == sym::f32;\n    //~^ symbol_as_str\n    s == sym::proc_dash_macro;\n    //~^ symbol_as_str\n    s == kw::SelfLower;\n    //~^ symbol_as_str\n    s == sym::msrv;\n    //~^ symbol_as_str\n    s == sym::Cargo_toml;\n    //~^ symbol_as_str\n    sym::get == s;\n    //~^ symbol_as_str\n\n    let _ = match s {\n        //~^ symbol_as_str\n        sym::unwrap_err => 1,\n        sym::unwrap_or_default | sym::unwrap_or_else => 2,\n        _ => 3,\n    };\n}\n"
  },
  {
    "path": "tests/ui-internal/symbol_as_str.rs",
    "content": "#![feature(rustc_private)]\n\nextern crate rustc_span;\n\nuse clippy_utils::sym;\nuse rustc_span::{Symbol, kw};\n\nfn f(s: Symbol) {\n    s.as_str() == \"f32\";\n    //~^ symbol_as_str\n    s.as_str() == \"proc-macro\";\n    //~^ symbol_as_str\n    s.as_str() == \"self\";\n    //~^ symbol_as_str\n    s.as_str() == \"msrv\";\n    //~^ symbol_as_str\n    s.as_str() == \"Cargo.toml\";\n    //~^ symbol_as_str\n    \"get\" == s.as_str();\n    //~^ symbol_as_str\n\n    let _ = match s.as_str() {\n        //~^ symbol_as_str\n        \"unwrap_err\" => 1,\n        \"unwrap_or_default\" | \"unwrap_or_else\" => 2,\n        _ => 3,\n    };\n}\n"
  },
  {
    "path": "tests/ui-internal/symbol_as_str.stderr",
    "content": "error: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str.rs:9:5\n   |\nLL |     s.as_str() == \"f32\";\n   |     ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\n   = note: `-D clippy::symbol-as-str` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::symbol_as_str)]`\nhelp: use preinterned symbols instead\n   |\nLL -     s.as_str() == \"f32\";\nLL +     s == sym::f32;\n   |\n\nerror: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str.rs:11:5\n   |\nLL |     s.as_str() == \"proc-macro\";\n   |     ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\nhelp: use preinterned symbols instead\n   |\nLL -     s.as_str() == \"proc-macro\";\nLL +     s == sym::proc_dash_macro;\n   |\n\nerror: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str.rs:13:5\n   |\nLL |     s.as_str() == \"self\";\n   |     ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\nhelp: use preinterned symbols instead\n   |\nLL -     s.as_str() == \"self\";\nLL +     s == kw::SelfLower;\n   |\n\nerror: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str.rs:15:5\n   |\nLL |     s.as_str() == \"msrv\";\n   |     ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\nhelp: use preinterned symbols instead\n   |\nLL -     s.as_str() == \"msrv\";\nLL +     s == sym::msrv;\n   |\n\nerror: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str.rs:17:5\n   |\nLL |     s.as_str() == \"Cargo.toml\";\n   |     ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\nhelp: use preinterned symbols instead\n   |\nLL -     s.as_str() == \"Cargo.toml\";\nLL +     s == sym::Cargo_toml;\n   |\n\nerror: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str.rs:19:14\n   |\nLL |     \"get\" == s.as_str();\n   |              ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\nhelp: use preinterned symbols instead\n   |\nLL -     \"get\" == s.as_str();\nLL +     sym::get == s;\n   |\n\nerror: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str.rs:22:19\n   |\nLL |     let _ = match s.as_str() {\n   |                   ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\nhelp: use preinterned symbols instead\n   |\nLL ~     let _ = match s {\nLL |\nLL ~         sym::unwrap_err => 1,\nLL ~         sym::unwrap_or_default | sym::unwrap_or_else => 2,\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/symbol_as_str_unfixable.rs",
    "content": "//@no-rustfix: paths that don't exist yet\n#![feature(rustc_private)]\n\nextern crate rustc_span;\n\nuse rustc_span::Symbol;\n\nfn f(s: Symbol) {\n    s.as_str() == \"xyz123\";\n    //~^ symbol_as_str\n    s.as_str() == \"with-dash\";\n    //~^ symbol_as_str\n    s.as_str() == \"with.dot\";\n    //~^ symbol_as_str\n}\n"
  },
  {
    "path": "tests/ui-internal/symbol_as_str_unfixable.stderr",
    "content": "error: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str_unfixable.rs:9:5\n   |\nLL |     s.as_str() == \"xyz123\";\n   |     ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\n   = note: `-D clippy::symbol-as-str` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::symbol_as_str)]`\nhelp: use preinterned symbols instead\n   |\nLL -     s.as_str() == \"xyz123\";\nLL +     s == sym::xyz123;\n   |\n\nerror: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str_unfixable.rs:11:5\n   |\nLL |     s.as_str() == \"with-dash\";\n   |     ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\nhelp: use preinterned symbols instead\n   |\nLL -     s.as_str() == \"with-dash\";\nLL +     s == sym::with_dash;\n   |\n\nerror: converting a Symbol to a string\n  --> tests/ui-internal/symbol_as_str_unfixable.rs:13:5\n   |\nLL |     s.as_str() == \"with.dot\";\n   |     ^^^^^^^^^^\n   |\n   = help: add the symbols to `clippy_utils/src/sym.rs` if needed\nhelp: use preinterned symbols instead\n   |\nLL -     s.as_str() == \"with.dot\";\nLL +     s == sym::with_dot;\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-internal/unnecessary_def_path.rs",
    "content": "#![feature(rustc_private)]\n\nuse clippy_utils::paths::{PathLookup, PathNS};\nuse clippy_utils::{macro_path, sym, type_path, value_path};\n\nstatic OPTION: PathLookup = type_path!(core::option::Option);\n//~^ unnecessary_def_path\nstatic SOME: PathLookup = type_path!(core::option::Option::Some);\n//~^ unnecessary_def_path\n\nstatic RESULT: PathLookup = type_path!(core::result::Result);\n//~^ unnecessary_def_path\nstatic RESULT_VIA_STD: PathLookup = type_path!(std::result::Result);\n//~^ unnecessary_def_path\n\nstatic VEC_NEW: PathLookup = value_path!(alloc::vec::Vec::new);\n//~^ unnecessary_def_path\n\nstatic VEC_MACRO: PathLookup = macro_path!(std::vec);\n//~^ unnecessary_def_path\n"
  },
  {
    "path": "tests/ui-internal/unnecessary_def_path.stderr",
    "content": "error: a diagnostic name exists for this path: sym::Option\n  --> tests/ui-internal/unnecessary_def_path.rs:6:29\n   |\nLL | static OPTION: PathLookup = type_path!(core::option::Option);\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead\n   = help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils\n   = note: `-D clippy::unnecessary-def-path` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_def_path)]`\n\nerror: a language item exists for this path: LangItem::OptionSome\n  --> tests/ui-internal/unnecessary_def_path.rs:8:27\n   |\nLL | static SOME: PathLookup = type_path!(core::option::Option::Some);\n   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the `PathLookup` and use utilities such as `cx.tcx.lang_items` instead\n   = help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=lang&filter-crate=clippy_utils\n\nerror: a diagnostic name exists for this path: sym::Result\n  --> tests/ui-internal/unnecessary_def_path.rs:11:29\n   |\nLL | static RESULT: PathLookup = type_path!(core::result::Result);\n   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead\n   = help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils\n\nerror: a diagnostic name exists for this path: sym::Result\n  --> tests/ui-internal/unnecessary_def_path.rs:13:37\n   |\nLL | static RESULT_VIA_STD: PathLookup = type_path!(std::result::Result);\n   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead\n   = help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils\n\nerror: a diagnostic name exists for this path: sym::vec_new\n  --> tests/ui-internal/unnecessary_def_path.rs:16:30\n   |\nLL | static VEC_NEW: PathLookup = value_path!(alloc::vec::Vec::new);\n   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead\n   = help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils\n\nerror: a diagnostic name exists for this path: sym::vec_macro\n  --> tests/ui-internal/unnecessary_def_path.rs:19:32\n   |\nLL | static VEC_MACRO: PathLookup = macro_path!(std::vec);\n   |                                ^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: remove the `PathLookup` and use utilities such as `cx.tcx.is_diagnostic_item` instead\n   = help: see also https://doc.rust-lang.org/nightly/nightly-rustc/?search=diag&filter-crate=clippy_utils\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr",
    "content": "error: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13\n   |\nLL |     let _ = std::path::is_separator(' ');\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9\n   |\nLL | #![deny(clippy::absolute_paths)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13\n   |\nLL |     let _ = ::std::path::MAIN_SEPARATOR;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13\n   |\nLL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31\n   |\nLL |     let _: &std::path::Path = std::path::Path::new(\"\");\n   |                               ^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13\n   |\nLL |     let _: &std::path::Path = std::path::Path::new(\"\");\n   |             ^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13\n   |\nLL |     let _ = std::option::Option::None::<i32>;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr",
    "content": "error: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13\n   |\nLL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9\n   |\nLL | #![deny(clippy::absolute_paths)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/absolute_paths.default.stderr",
    "content": "error: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13\n   |\nLL |     let _ = std::path::is_separator(' ');\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9\n   |\nLL | #![deny(clippy::absolute_paths)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13\n   |\nLL |     let _ = ::std::path::MAIN_SEPARATOR;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13\n   |\nLL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31\n   |\nLL |     let _: &std::path::Path = std::path::Path::new(\"\");\n   |                               ^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13\n   |\nLL |     let _: &std::path::Path = std::path::Path::new(\"\");\n   |             ^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13\n   |\nLL |     let _ = ::core::clone::Clone::clone(&0i32);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13\n   |\nLL |     let _ = <i32 as core::clone::Clone>::clone(&0i32);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13\n   |\nLL |     let _ = std::option::Option::None::<i32>;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17\n   |\nLL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>\n   |                 ^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18\n   |\nLL |         where T: core::clone::Clone\n   |                  ^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32\n   |\nLL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>\n   |                                ^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5\n   |\nLL |     crate::m1::S\n   |     ^^^^^^^^^^^^\n\nerror: aborting due to 12 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr",
    "content": "error: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13\n   |\nLL |     let _ = std::path::is_separator(' ');\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9\n   |\nLL | #![deny(clippy::absolute_paths)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13\n   |\nLL |     let _ = ::std::path::MAIN_SEPARATOR;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13\n   |\nLL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31\n   |\nLL |     let _: &std::path::Path = std::path::Path::new(\"\");\n   |                               ^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13\n   |\nLL |     let _: &std::path::Path = std::path::Path::new(\"\");\n   |             ^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13\n   |\nLL |     let _ = ::core::clone::Clone::clone(&0i32);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13\n   |\nLL |     let _ = <i32 as core::clone::Clone>::clone(&0i32);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13\n   |\nLL |     let _ = std::option::Option::None::<i32>;\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17\n   |\nLL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>\n   |                 ^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18\n   |\nLL |         where T: core::clone::Clone\n   |                  ^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32\n   |\nLL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>\n   |                                ^^^^^^^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:10\n   |\nLL | const _: crate::S = {\n   |          ^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:114:9\n   |\nLL |     let crate::S = m1::S;\n   |         ^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5\n   |\nLL |     crate::m1::S\n   |     ^^^^^^^^^^^^\n\nerror: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths.rs:122:14\n   |\nLL |     let _ = <crate::S as Clone>::clone(&m1::S);\n   |              ^^^^^^^^\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/absolute_paths.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: default allow_crates allow_long no_short\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default\n//@[allow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates\n//@[allow_long] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_long\n//@[no_short] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/no_short\n#![deny(clippy::absolute_paths)]\n\nextern crate proc_macros;\nuse proc_macros::{external, inline_macros, with_span};\n\n#[inline_macros]\nfn main() {\n    let _ = std::path::is_separator(' ');\n    //~[default]^ absolute_paths\n    //~[allow_crates]| absolute_paths\n    //~[no_short]| absolute_paths\n\n    // Make sure this is treated as having three path segments, not four.\n    let _ = ::std::path::MAIN_SEPARATOR;\n    //~[default]^ absolute_paths\n    //~[allow_crates]| absolute_paths\n    //~[no_short]| absolute_paths\n\n    let _ = std::collections::hash_map::HashMap::<i32, i32>::new(); //~ absolute_paths\n\n    // Note `std::path::Path::new` is treated as having three parts\n    let _: &std::path::Path = std::path::Path::new(\"\");\n    //~[default]^ absolute_paths\n    //~[default]| absolute_paths\n    //~[allow_crates]| absolute_paths\n    //~[allow_crates]| absolute_paths\n    //~[no_short]| absolute_paths\n    //~[no_short]| absolute_paths\n\n    // Treated as having three parts.\n    let _ = ::core::clone::Clone::clone(&0i32);\n    //~[default]^ absolute_paths\n    //~[no_short]| absolute_paths\n    let _ = <i32 as core::clone::Clone>::clone(&0i32);\n    //~[default]^ absolute_paths\n    //~[no_short]| absolute_paths\n    let _ = std::option::Option::None::<i32>;\n    //~[default]^ absolute_paths\n    //~[allow_crates]| absolute_paths\n    //~[no_short]| absolute_paths\n\n    {\n        // FIXME: macro calls should be checked.\n        let x = 1i32;\n        let _ = core::ptr::addr_of!(x);\n    }\n\n    {\n        // FIXME: derive macro paths should be checked.\n        #[derive(core::clone::Clone)]\n        struct S;\n    }\n\n    {\n        use core::fmt;\n        use core::marker::PhantomData;\n\n        struct X<T>(PhantomData<T>);\n        impl<T: core::cmp::Eq> core::fmt::Display for X<T>\n        //~[default]^ absolute_paths\n        //~[default]| absolute_paths\n        //~[no_short]| absolute_paths\n        //~[no_short]| absolute_paths\n        where T: core::clone::Clone\n        //~[no_short]^ absolute_paths\n        //~[default]| absolute_paths\n        {\n            fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {\n                Ok(())\n            }\n        }\n    }\n\n    {\n        mod m1 {\n            pub(crate) mod m2 {\n                pub(crate) const FOO: i32 = 0;\n            }\n        }\n        let _ = m1::m2::FOO;\n    }\n\n    with_span! {\n        span\n        let _ = std::path::is_separator(' ');\n    }\n\n    external! {\n        let _ = std::path::is_separator(' ');\n    }\n\n    inline! {\n        let _ = std::path::is_separator(' ');\n    }\n}\n\npub use core::cmp::Ordering;\npub use std::fs::File;\n\n#[derive(Clone)]\npub struct S;\nmod m1 {\n    pub use crate::S;\n}\n\n//~[no_short]v absolute_paths\nconst _: crate::S = {\n    let crate::S = m1::S; //~[no_short] absolute_paths\n\n    crate::m1::S\n    //~[default]^ absolute_paths\n    //~[no_short]| absolute_paths\n};\n\npub fn f() {\n    let _ = <crate::S as Clone>::clone(&m1::S); //~[no_short] absolute_paths\n}\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr",
    "content": "error: consider bringing this path into scope with the `use` keyword\n  --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:16:13\n   |\nLL |     let _ = ::m1::m2::X;\n   |             ^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:7:9\n   |\nLL | #![deny(clippy::absolute_paths)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/absolute_paths_2015.rs",
    "content": "//@revisions: default allow_crates\n//@[default]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default\n//@[allow_crates]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates\n//@[allow_crates]check-pass\n//@edition:2015\n\n#![deny(clippy::absolute_paths)]\n\nmod m1 {\n    pub mod m2 {\n        pub struct X;\n    }\n}\n\nfn main() {\n    let _ = ::m1::m2::X; //~[default] absolute_paths\n}\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/allow_crates/clippy.toml",
    "content": "absolute-paths-allowed-crates = [\"core\", \"crate\"]\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/allow_long/clippy.toml",
    "content": "absolute-paths-max-segments = 3\n"
  },
  {
    "path": "tests/ui-toml/absolute_paths/default/clippy.toml",
    "content": ""
  },
  {
    "path": "tests/ui-toml/absolute_paths/no_short/clippy.toml",
    "content": "absolute-paths-max-segments = 0\n"
  },
  {
    "path": "tests/ui-toml/allow_mixed_uninlined_format_args/clippy.toml",
    "content": "allow-mixed-uninlined-format-args = false\n"
  },
  {
    "path": "tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.fixed",
    "content": "#![warn(clippy::uninlined_format_args)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nfn main() {\n    let local_i32 = 1;\n    let local_f64 = 2.0;\n    let local_opt: Option<i32> = Some(3);\n\n    println!(\"val='{local_i32}'\");\n    //~^ uninlined_format_args\n    println!(\"Hello x is {local_f64:.local_i32$}\");\n    //~^ uninlined_format_args\n    //~| print_literal\n    println!(\"Hello {local_i32} is {local_f64:.*}\", 5);\n    //~^ uninlined_format_args\n    println!(\"Hello {local_i32} is {local_f64:.*}\", 5);\n    //~^ uninlined_format_args\n    println!(\"{local_i32}, {}\", local_opt.unwrap());\n    //~^ uninlined_format_args\n}\n"
  },
  {
    "path": "tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs",
    "content": "#![warn(clippy::uninlined_format_args)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nfn main() {\n    let local_i32 = 1;\n    let local_f64 = 2.0;\n    let local_opt: Option<i32> = Some(3);\n\n    println!(\"val='{}'\", local_i32);\n    //~^ uninlined_format_args\n    println!(\"Hello {} is {:.*}\", \"x\", local_i32, local_f64);\n    //~^ uninlined_format_args\n    //~| print_literal\n    println!(\"Hello {} is {:.*}\", local_i32, 5, local_f64);\n    //~^ uninlined_format_args\n    println!(\"Hello {} is {2:.*}\", local_i32, 5, local_f64);\n    //~^ uninlined_format_args\n    println!(\"{}, {}\", local_i32, local_opt.unwrap());\n    //~^ uninlined_format_args\n}\n"
  },
  {
    "path": "tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.stderr",
    "content": "error: variables can be used directly in the `format!` string\n  --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:9:5\n   |\nLL |     println!(\"val='{}'\", local_i32);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::uninlined-format-args` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::uninlined_format_args)]`\nhelp: change this to\n   |\nLL -     println!(\"val='{}'\", local_i32);\nLL +     println!(\"val='{local_i32}'\");\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:11:5\n   |\nLL |     println!(\"Hello {} is {:.*}\", \"x\", local_i32, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"Hello {} is {:.*}\", \"x\", local_i32, local_f64);\nLL +     println!(\"Hello {} is {local_f64:.local_i32$}\", \"x\");\n   |\n\nerror: literal with an empty format string\n  --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:11:35\n   |\nLL |     println!(\"Hello {} is {:.*}\", \"x\", local_i32, local_f64);\n   |                                   ^^^\n   |\n   = note: `-D clippy::print-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_literal)]`\nhelp: try\n   |\nLL -     println!(\"Hello {} is {:.*}\", \"x\", local_i32, local_f64);\nLL +     println!(\"Hello x is {:.*}\", local_i32, local_f64);\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:14:5\n   |\nLL |     println!(\"Hello {} is {:.*}\", local_i32, 5, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"Hello {} is {:.*}\", local_i32, 5, local_f64);\nLL +     println!(\"Hello {local_i32} is {local_f64:.*}\", 5);\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:16:5\n   |\nLL |     println!(\"Hello {} is {2:.*}\", local_i32, 5, local_f64);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"Hello {} is {2:.*}\", local_i32, 5, local_f64);\nLL +     println!(\"Hello {local_i32} is {local_f64:.*}\", 5);\n   |\n\nerror: variables can be used directly in the `format!` string\n  --> tests/ui-toml/allow_mixed_uninlined_format_args/uninlined_format_args.rs:18:5\n   |\nLL |     println!(\"{}, {}\", local_i32, local_opt.unwrap());\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     println!(\"{}, {}\", local_i32, local_opt.unwrap());\nLL +     println!(\"{local_i32}, {}\", local_opt.unwrap());\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1/clippy.toml",
    "content": "trait-assoc-item-kinds-order = [\"fn\", \"type\", \"const\", \"type\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2/clippy.toml",
    "content": "trait-assoc-item-kinds-order = [\"const\", \"type\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3/clippy.toml",
    "content": "source-item-ordering = [\"enum\", \"impl\", \"module\", \"struct\", \"trait\", \"struct\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml",
    "content": "module-items-ordered-within-groupings = true\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5/clippy.toml",
    "content": "module-items-ordered-within-groupings = [\"madules\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6/clippy.toml",
    "content": "module-items-ordered-within-groupings = [\"entirely garbled\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/default/clippy.toml",
    "content": ""
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml",
    "content": "trait-assoc-item-kinds-order = [\"const\", \"type\", \"fn\"]\nsource-item-ordering = [\"enum\", \"impl\", \"module\", \"struct\", \"trait\"]\nmodule-item-order-groupings = [\n    [\"modules\", [\"extern_crate\", \"mod\", \"foreign_mod\"]],\n    [\"use\", [\"use\"]],\n    [\"macros\", [\"macro\"]],\n    [\"global_asm\", [\"global_asm\"]],\n    [\"UPPER_SNAKE_CASE\", [\"static\", \"const\"]],\n    [\"PascalCase\", [\"ty_alias\", \"enum\", \"struct\", \"union\", \"trait\", \"trait_alias\", \"impl\"]],\n    [\"lower_snake_case\", [\"fn\"]]\n]\nmodule-items-ordered-within-groupings = \"none\"\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/only_enum/clippy.toml",
    "content": "source-item-ordering = [\"enum\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/only_impl/clippy.toml",
    "content": "source-item-ordering = [\"impl\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/only_trait/clippy.toml",
    "content": "source-item-ordering = [\"trait\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ord_in_2/clippy.toml",
    "content": "module-items-ordered-within-groupings = [\"PascalCase\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ord_in_3/clippy.toml",
    "content": "source-item-ordering = [\"module\"]\nmodule-items-ordered-within-groupings = [\"PascalCase\"]\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ord_within/clippy.toml",
    "content": "module-items-ordered-within-groupings = \"all\"\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_1.stderr",
    "content": "error: error reading Clippy's configuration file: Some trait associated item kinds were configured more than once, or were missing, in the source ordering configuration. The trait associated item kinds are: [Const, Fn, Type]\n  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1/clippy.toml:1:32\n   |\nLL | trait-assoc-item-kinds-order = [\"fn\", \"type\", \"const\", \"type\"]\n   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_2.stderr",
    "content": "error: error reading Clippy's configuration file: Some trait associated item kinds were configured more than once, or were missing, in the source ordering configuration. The trait associated item kinds are: [Const, Fn, Type]\n  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2/clippy.toml:1:32\n   |\nLL | trait-assoc-item-kinds-order = [\"const\", \"type\"]\n   |                                ^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_3.stderr",
    "content": "error: error reading Clippy's configuration file: The category \"Struct\" was enabled more than once in the source ordering configuration.\n  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3/clippy.toml:1:24\n   |\nLL | source-item-ordering = [\"enum\", \"impl\", \"module\", \"struct\", \"trait\", \"struct\"]\n   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_4.stderr",
    "content": "error: error reading Clippy's configuration file: data did not match any variant of untagged enum StringOrVecOfString  The available options for configuring an ordering within module item groups are: \"all\", \"none\", or a list of module item group names (as configured with the `module-item-order-groupings` configuration option).\n  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4/clippy.toml:1:41\n   |\nLL | module-items-ordered-within-groupings = true\n   |                                         ^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_5.stderr",
    "content": "error: error reading Clippy's configuration file: unknown ordering group: `madules` was not specified in `module-items-ordered-within-groupings`, perhaps you meant `modules`? expected one of: `modules`, `use`, `macros`, `global_asm`, `UPPER_SNAKE_CASE`, `PascalCase`, `lower_snake_case`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_6.stderr",
    "content": "error: error reading Clippy's configuration file: unknown ordering group: `entirely garbled` was not specified in `module-items-ordered-within-groupings`, expected one of: `modules`, `use`, `macros`, `global_asm`, `UPPER_SNAKE_CASE`, `PascalCase`, `lower_snake_case`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: default default_exp bad_conf_1 bad_conf_2 bad_conf_3 bad_conf_4 bad_conf_5 bad_conf_6\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default\n//@[default_exp] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default_exp\n//@[bad_conf_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1\n//@[bad_conf_2] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2\n//@[bad_conf_3] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3\n//@[bad_conf_4] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_4\n//@[bad_conf_5] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_5\n//@[bad_conf_6] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_6\n//@[default] check-pass\n//@[default_exp] check-pass\n//@[bad_conf_1] error-in-other-file:\n//@[bad_conf_2] error-in-other-file:\n//@[bad_conf_3] error-in-other-file:\n//@[bad_conf_4] error-in-other-file:\n//@[bad_conf_5] error-in-other-file:\n//@[bad_conf_6] error-in-other-file:\n//@compile-flags: --test\n\n#![allow(dead_code)]\n#![warn(clippy::arbitrary_source_item_ordering)]\n\n/// This module gets linted before clippy gives up.\nmod i_am_just_right {\n    const AFTER: i8 = 0;\n\n    const BEFORE: i8 = 0;\n}\n\n/// Since the upper module passes linting, the lint now recurses into this module.\nmod this_is_in_the_wrong_position {\n    const A: i8 = 1;\n    const C: i8 = 0;\n}\n\n// Use statements should not be linted internally - this is normally auto-sorted using rustfmt.\nuse std::rc::{Rc, Weak};\nuse std::sync::{Arc, Barrier, RwLock};\n\nconst SNAKE_CASE: &str = \"zzzzzzzz\";\n\nconst ZIS_SHOULD_BE_EVEN_EARLIER: () = ();\n\nconst ZIS_SHOULD_BE_REALLY_EARLY: () = ();\n\ntrait BasicEmptyTrait {}\n\ntrait CloneSelf {\n    fn clone_self(&self) -> Self;\n}\n\nenum EnumOrdered {\n    A,\n    B,\n    C,\n}\n\nenum EnumUnordered {\n    A,\n    B,\n    C,\n}\n\n#[allow(clippy::arbitrary_source_item_ordering)]\nenum EnumUnorderedAllowed {\n    A,\n    B,\n    C,\n}\n\nstruct StructOrdered {\n    a: bool,\n    b: bool,\n    c: bool,\n}\n\nimpl BasicEmptyTrait for StructOrdered {}\n\nimpl CloneSelf for StructOrdered {\n    fn clone_self(&self) -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\nimpl Default for StructOrdered {\n    fn default() -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\nimpl std::clone::Clone for StructOrdered {\n    fn clone(&self) -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\n#[derive(Clone, Default)]\nstruct StructUnordered {\n    a: bool,\n    b: bool,\n    c: bool,\n    d: bool,\n}\n\nimpl TraitUnordered for StructUnordered {\n    const A: bool = false;\n    const B: bool = false;\n    const C: bool = false;\n\n    type SomeType = ();\n\n    fn a() {}\n    fn b() {}\n    fn c() {}\n}\n\nimpl TraitUnorderedItemKinds for StructUnordered {\n    const A: bool = false;\n    const B: bool = false;\n    const C: bool = false;\n\n    type SomeType = ();\n\n    fn a() {}\n    fn b() {}\n    fn c() {}\n}\n\nstruct StructUnorderedGeneric<T> {\n    _1: std::marker::PhantomData<T>,\n    a: bool,\n    b: bool,\n    c: bool,\n    d: bool,\n}\n\ntrait TraitOrdered {\n    const A: bool;\n    const B: bool;\n    const C: bool;\n\n    type SomeType;\n\n    fn a();\n    fn b();\n    fn c();\n}\n\ntrait TraitUnordered {\n    const A: bool;\n    const B: bool;\n    const C: bool;\n\n    type SomeType;\n\n    fn a();\n    fn b();\n    fn c();\n}\n\ntrait TraitUnorderedItemKinds {\n    const A: bool;\n    const B: bool;\n    const C: bool;\n\n    type SomeType;\n\n    fn a();\n    fn b();\n    fn c();\n}\n\n#[derive(std::clone::Clone, Default)]\nstruct ZisShouldBeBeforeZeMainFn;\n\nfn main() {\n    // test code goes here\n}\n\n#[cfg(test)]\nmod test {\n    const B: i8 = 1;\n\n    const A: i8 = 0;\n}\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: var_1\n//@[var_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/var_1\n//@check-pass\n\n#![allow(dead_code)]\n#![warn(clippy::arbitrary_source_item_ordering)]\n\n/// This module gets linted before clippy gives up.\nmod i_am_just_right {\n    const AFTER: i8 = 0;\n\n    const BEFORE: i8 = 0;\n}\n\n/// Since the upper module passes linting, the lint now recurses into this module.\nmod this_is_in_the_wrong_position {\n    const A: i8 = 1;\n    const C: i8 = 0;\n}\n\n// Use statements should not be linted internally - this is normally auto-sorted using rustfmt.\nuse std::rc::{Rc, Weak};\nuse std::sync::{Arc, Barrier, RwLock};\n\nconst SNAKE_CASE: &str = \"zzzzzzzz\";\n\nconst ZIS_SHOULD_BE_EVEN_EARLIER: () = ();\n\nconst ZIS_SHOULD_BE_REALLY_EARLY: () = ();\n\ntrait BasicEmptyTrait {}\n\ntrait CloneSelf {\n    fn clone_self(&self) -> Self;\n}\n\nenum EnumOrdered {\n    A,\n    B,\n    C,\n}\n\nenum EnumUnordered {\n    A,\n    B,\n    C,\n}\n\n#[allow(clippy::arbitrary_source_item_ordering)]\nenum EnumUnorderedAllowed {\n    A,\n    B,\n    C,\n}\n\nstruct StructOrdered {\n    a: bool,\n    b: bool,\n    c: bool,\n}\n\nimpl BasicEmptyTrait for StructOrdered {}\n\nimpl CloneSelf for StructOrdered {\n    fn clone_self(&self) -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\nimpl Default for StructOrdered {\n    fn default() -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\nimpl std::clone::Clone for StructOrdered {\n    fn clone(&self) -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\n#[derive(Clone, Default)]\nstruct StructUnordered {\n    a: bool,\n    b: bool,\n    c: bool,\n    d: bool,\n}\n\nimpl TraitUnordered for StructUnordered {\n    fn a() {}\n    fn b() {}\n    fn c() {}\n\n    type SomeType = ();\n\n    const A: bool = false;\n    const B: bool = false;\n    const C: bool = false;\n}\n\nimpl TraitUnorderedItemKinds for StructUnordered {\n    fn a() {}\n\n    type SomeType = ();\n\n    const A: bool = false;\n}\n\nstruct StructUnorderedGeneric<T> {\n    _1: std::marker::PhantomData<T>,\n    a: bool,\n    b: bool,\n    c: bool,\n    d: bool,\n}\n\ntrait TraitOrdered {\n    fn a();\n    fn b();\n    fn c();\n\n    type SomeType;\n\n    const A: bool;\n    const B: bool;\n    const C: bool;\n}\n\ntrait TraitUnordered {\n    fn a();\n    fn b();\n    fn c();\n\n    type SomeType;\n\n    const A: bool;\n    const B: bool;\n    const C: bool;\n}\n\ntrait TraitUnorderedItemKinds {\n    fn a();\n\n    type SomeType;\n\n    const A: bool;\n}\n\n#[derive(std::clone::Clone, Default)]\nstruct ZisShouldBeBeforeZeMainFn;\n\nfn main() {\n    // test code goes here\n}\n\n#[cfg(test)]\nmod test {\n    const B: i8 = 1;\n\n    const A: i8 = 0;\n}\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr",
    "content": "error: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14\n   |\nLL | use std::rc::Weak;\n   |              ^^^^\n   |\nnote: should be placed before `SNAKE_CASE`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7\n   |\nLL | const SNAKE_CASE: &str = \"zzzzzzzz\";\n   |       ^^^^^^^^^^\n   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:165:7\n   |\nLL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `TraitUnorderedItemKinds`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:152:7\n   |\nLL | trait TraitUnorderedItemKinds {\n   |       ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:204:5\n   |\nLL | mod this_is_in_the_wrong_position {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `main`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:199:4\n   |\nLL | fn main() {\n   |    ^^^^\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:214:7\n   |\nLL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `ZisShouldBeBeforeZeMainFn`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:212:8\n   |\nLL | struct ZisShouldBeBeforeZeMainFn;\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5\n   |\nLL |     B,\n   |     ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5\n   |\nLL |     C,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:5\n   |\nLL |     g: u8,\n   |     ^\n   |\nnote: should be placed before `r`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:56:5\n   |\nLL |     r: u8,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:59:5\n   |\nLL |     b: u8,\n   |     ^\n   |\nnote: should be placed before `g`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:5\n   |\nLL |     g: u8,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:112:5\n   |\nLL |     b: bool,\n   |     ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:111:5\n   |\nLL |     c: bool,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:121:5\n   |\nLL |     b: bool,\n   |     ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:120:5\n   |\nLL |     c: bool,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:141:11\n   |\nLL |     const B: bool;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:140:11\n   |\nLL |     const C: bool;\n   |           ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:148:8\n   |\nLL |     fn b();\n   |        ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:147:8\n   |\nLL |     fn c();\n   |        ^\n\nerror: incorrect ordering of trait items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5\n   |\nLL |     const A: bool;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5\n   |\nLL |     type SomeType;\n   |     ^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11\n   |\nLL |     const B: bool = false;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:170:11\n   |\nLL |     const C: bool = false;\n   |           ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:178:8\n   |\nLL |     fn b() {}\n   |        ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:177:8\n   |\nLL |     fn c() {}\n   |        ^\n\nerror: incorrect ordering of impl items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5\n   |\nLL |     const A: bool = false;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5\n   |\nLL |     type SomeType = ();\n   |     ^^^^^^^^^^^^^\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr",
    "content": "error: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14\n   |\nLL | use std::rc::Weak;\n   |              ^^^^\n   |\nnote: should be placed before `SNAKE_CASE`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7\n   |\nLL | const SNAKE_CASE: &str = \"zzzzzzzz\";\n   |       ^^^^^^^^^^\n   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:165:7\n   |\nLL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `TraitUnorderedItemKinds`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:152:7\n   |\nLL | trait TraitUnorderedItemKinds {\n   |       ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:204:5\n   |\nLL | mod this_is_in_the_wrong_position {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `main`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:199:4\n   |\nLL | fn main() {\n   |    ^^^^\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:214:7\n   |\nLL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `ZisShouldBeBeforeZeMainFn`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:212:8\n   |\nLL | struct ZisShouldBeBeforeZeMainFn;\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5\n   |\nLL |     B,\n   |     ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5\n   |\nLL |     C,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:5\n   |\nLL |     g: u8,\n   |     ^\n   |\nnote: should be placed before `r`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:56:5\n   |\nLL |     r: u8,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:59:5\n   |\nLL |     b: u8,\n   |     ^\n   |\nnote: should be placed before `g`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:5\n   |\nLL |     g: u8,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:112:5\n   |\nLL |     b: bool,\n   |     ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:111:5\n   |\nLL |     c: bool,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:121:5\n   |\nLL |     b: bool,\n   |     ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:120:5\n   |\nLL |     c: bool,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:141:11\n   |\nLL |     const B: bool;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:140:11\n   |\nLL |     const C: bool;\n   |           ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:148:8\n   |\nLL |     fn b();\n   |        ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:147:8\n   |\nLL |     fn c();\n   |        ^\n\nerror: incorrect ordering of trait items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5\n   |\nLL |     const A: bool;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5\n   |\nLL |     type SomeType;\n   |     ^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11\n   |\nLL |     const B: bool = false;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:170:11\n   |\nLL |     const C: bool = false;\n   |           ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:178:8\n   |\nLL |     fn b() {}\n   |        ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:177:8\n   |\nLL |     fn c() {}\n   |        ^\n\nerror: incorrect ordering of impl items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5\n   |\nLL |     const A: bool = false;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5\n   |\nLL |     type SomeType = ();\n   |     ^^^^^^^^^^^^^\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7\n   |\nLL | const SNAKE_CASE: &str = \"zzzzzzzz\";\n   |       ^^^^^^^^^^\n   |\nnote: should be placed before `ZNAKE_CASE`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:22:7\n   |\nLL | const ZNAKE_CASE: &str = \"123\";\n   |       ^^^^^^^^^^\n   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:26:14\n   |\nLL | use std::rc::Weak;\n   |              ^^^^\n   |\nnote: should be placed before `SNAKE_CASE`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:23:7\n   |\nLL | const SNAKE_CASE: &str = \"zzzzzzzz\";\n   |       ^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:64:8\n   |\nLL | struct EnumWithExternButAtWrongPosition {\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `EnumWithoutExtern`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:55:8\n   |\nLL | struct EnumWithoutExtern {\n   |        ^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:87:1\n   |\nLL | / impl CloneSelf for StructOrdered {\nLL | |\nLL | |     fn clone_self(&self) -> Self {\nLL | |         Self {\n...  |\nLL | | }\n   | |_^\n   |\nnote: should be placed before the following item\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:77:1\n   |\nLL | / impl Default for StructOrdered {\nLL | |     fn default() -> Self {\nLL | |         Self {\nLL | |             a: true,\n...  |\nLL | | }\n   | |_^\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:165:7\n   |\nLL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `TraitUnorderedItemKinds`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:152:7\n   |\nLL | trait TraitUnorderedItemKinds {\n   |       ^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:183:1\n   |\nLL | impl BasicEmptyTrait for StructOrdered {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before the following item\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:168:1\n   |\nLL | / impl TraitUnordered for StructUnordered {\nLL | |     const A: bool = false;\nLL | |     const C: bool = false;\nLL | |     const B: bool = false;\n...  |\nLL | | }\n   | |_^\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:204:5\n   |\nLL | mod this_is_in_the_wrong_position {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `main`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:199:4\n   |\nLL | fn main() {\n   |    ^^^^\n\nerror: incorrect ordering of items (module item groupings specify another order)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:214:7\n   |\nLL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();\n   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: should be placed before `ZisShouldBeBeforeZeMainFn`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:212:8\n   |\nLL | struct ZisShouldBeBeforeZeMainFn;\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:14:11\n   |\nLL |     const AFTER: i8 = 0;\n   |           ^^^^^\n   |\nnote: should be placed before `BEFORE`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:12:11\n   |\nLL |     const BEFORE: i8 = 0;\n   |           ^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:44:5\n   |\nLL |     B,\n   |     ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:43:5\n   |\nLL |     C,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:5\n   |\nLL |     g: u8,\n   |     ^\n   |\nnote: should be placed before `r`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:56:5\n   |\nLL |     r: u8,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:59:5\n   |\nLL |     b: u8,\n   |     ^\n   |\nnote: should be placed before `g`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:57:5\n   |\nLL |     g: u8,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:112:5\n   |\nLL |     b: bool,\n   |     ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:111:5\n   |\nLL |     c: bool,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:121:5\n   |\nLL |     b: bool,\n   |     ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:120:5\n   |\nLL |     c: bool,\n   |     ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:141:11\n   |\nLL |     const B: bool;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:140:11\n   |\nLL |     const C: bool;\n   |           ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:148:8\n   |\nLL |     fn b();\n   |        ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:147:8\n   |\nLL |     fn c();\n   |        ^\n\nerror: incorrect ordering of trait items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5\n   |\nLL |     const A: bool;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5\n   |\nLL |     type SomeType;\n   |     ^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11\n   |\nLL |     const B: bool = false;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:170:11\n   |\nLL |     const C: bool = false;\n   |           ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:178:8\n   |\nLL |     fn b() {}\n   |        ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:177:8\n   |\nLL |     fn c() {}\n   |        ^\n\nerror: incorrect ordering of impl items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5\n   |\nLL |     const A: bool = false;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5\n   |\nLL |     type SomeType = ();\n   |     ^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:207:11\n   |\nLL |     const A: i8 = 1;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:206:11\n   |\nLL |     const C: i8 = 0;\n   |           ^\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: default default_exp ord_within\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default\n//@[default_exp] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default_exp\n//@[ord_within] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_within\n\n#![allow(dead_code)]\n#![warn(clippy::arbitrary_source_item_ordering)]\n\n/// This module gets linted before clippy gives up.\nmod i_am_just_right {\n    const BEFORE: i8 = 0;\n\n    const AFTER: i8 = 0;\n    //~[ord_within]^ arbitrary_source_item_ordering\n}\n\n// Use statements should not be linted internally - this is normally auto-sorted using rustfmt.\nuse std::rc::Rc;\nuse std::sync::{Arc, Barrier, RwLock};\n\nconst ZNAKE_CASE: &str = \"123\";\nconst SNAKE_CASE: &str = \"zzzzzzzz\";\n//~[ord_within]^ arbitrary_source_item_ordering\n\nuse std::rc::Weak;\n//~^ arbitrary_source_item_ordering\n\ntrait BasicEmptyTrait {}\n\ntrait CloneSelf {\n    fn clone_self(&self) -> Self;\n}\n\nenum EnumOrdered {\n    A,\n    B,\n    C,\n}\n\nenum EnumUnordered {\n    A,\n    C,\n    B,\n    //~^ arbitrary_source_item_ordering\n}\n\n#[allow(clippy::arbitrary_source_item_ordering)]\nenum EnumUnorderedAllowed {\n    A,\n    C,\n    B,\n}\n\nstruct EnumWithoutExtern {\n    r: u8,\n    g: u8,\n    //~^ arbitrary_source_item_ordering\n    b: u8,\n    //~^ arbitrary_source_item_ordering\n}\n\n#[repr(C)]\nstruct EnumWithExternButAtWrongPosition {\n    //~[ord_within]^ arbitrary_source_item_ordering\n    r: u8,\n    g: u8,\n    b: u8,\n}\n\nstruct StructOrdered {\n    a: bool,\n    b: bool,\n    c: bool,\n}\n\nimpl Default for StructOrdered {\n    fn default() -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\nimpl CloneSelf for StructOrdered {\n    //~[ord_within]^ arbitrary_source_item_ordering\n    fn clone_self(&self) -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\nimpl std::clone::Clone for StructOrdered {\n    fn clone(&self) -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\n#[derive(Default, Clone)]\nstruct StructUnordered {\n    a: bool,\n    c: bool,\n    b: bool,\n    //~^ arbitrary_source_item_ordering\n    d: bool,\n}\n\nstruct StructUnorderedGeneric<T> {\n    _1: std::marker::PhantomData<T>,\n    a: bool,\n    c: bool,\n    b: bool,\n    //~^ arbitrary_source_item_ordering\n    d: bool,\n}\n\ntrait TraitOrdered {\n    const A: bool;\n    const B: bool;\n    const C: bool;\n\n    type SomeType;\n\n    fn a();\n    fn b();\n    fn c();\n}\n\ntrait TraitUnordered {\n    const A: bool;\n    const C: bool;\n    const B: bool;\n    //~^ arbitrary_source_item_ordering\n\n    type SomeType;\n\n    fn a();\n    fn c();\n    fn b();\n    //~^ arbitrary_source_item_ordering\n}\n\ntrait TraitUnorderedItemKinds {\n    type SomeType;\n\n    const A: bool;\n    //~^ arbitrary_source_item_ordering\n    const B: bool;\n    const C: bool;\n\n    fn a();\n    fn b();\n    fn c();\n}\n\nconst ZIS_SHOULD_BE_REALLY_EARLY: () = ();\n//~^ arbitrary_source_item_ordering\n\nimpl TraitUnordered for StructUnordered {\n    const A: bool = false;\n    const C: bool = false;\n    const B: bool = false;\n    //~^ arbitrary_source_item_ordering\n\n    type SomeType = ();\n\n    fn a() {}\n    fn c() {}\n    fn b() {}\n    //~^ arbitrary_source_item_ordering\n}\n\n// Trait impls should be located just after the type they implement it for.\nimpl BasicEmptyTrait for StructOrdered {}\n//~[ord_within]^ arbitrary_source_item_ordering\n\nimpl TraitUnorderedItemKinds for StructUnordered {\n    type SomeType = ();\n\n    const A: bool = false;\n    //~^ arbitrary_source_item_ordering\n    const B: bool = false;\n    const C: bool = false;\n\n    fn a() {}\n    fn b() {}\n    fn c() {}\n}\n\nfn main() {\n    // test code goes here\n}\n\n/// Note that the linting pass is stopped before recursing into this module.\nmod this_is_in_the_wrong_position {\n    //~^ arbitrary_source_item_ordering\n    const C: i8 = 0;\n    const A: i8 = 1;\n    //~[ord_within]^ arbitrary_source_item_ordering\n}\n\n#[derive(Default, std::clone::Clone)]\nstruct ZisShouldBeBeforeZeMainFn;\n\nconst ZIS_SHOULD_BE_EVEN_EARLIER: () = ();\n//~^ arbitrary_source_item_ordering\n\n#[cfg(test)]\nmod test {\n    const B: i8 = 1;\n\n    const A: i8 = 0;\n}\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: var_1\n//@[var_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/var_1\n\n#![allow(dead_code)]\n#![warn(clippy::arbitrary_source_item_ordering)]\n\n/// This module gets linted before clippy gives up.\nmod i_am_just_right {\n    const AFTER: i8 = 0;\n\n    const BEFORE: i8 = 0;\n}\n\n/// Since the upper module passes linting, the lint now recurses into this module.\nmod this_is_in_the_wrong_position {\n    const A: i8 = 1;\n    const C: i8 = 0;\n}\n\n// Use statements should not be linted internally - this is normally auto-sorted using rustfmt.\nuse std::rc::{Rc, Weak};\nuse std::sync::{Arc, Barrier, RwLock};\n\nconst SNAKE_CASE: &str = \"zzzzzzzz\";\n\nconst ZIS_SHOULD_BE_EVEN_EARLIER: () = ();\n\nconst ZIS_SHOULD_BE_REALLY_EARLY: () = ();\n\ntrait BasicEmptyTrait {}\n\ntrait CloneSelf {\n    fn clone_self(&self) -> Self;\n}\n\nenum EnumOrdered {\n    A,\n    B,\n    C,\n}\n\nenum EnumUnordered {\n    A,\n    B,\n    C,\n}\n\n#[allow(clippy::arbitrary_source_item_ordering)]\nenum EnumUnorderedAllowed {\n    A,\n    B,\n    C,\n}\n\nstruct StructOrdered {\n    a: bool,\n    b: bool,\n    c: bool,\n}\n\nimpl BasicEmptyTrait for StructOrdered {}\n\nimpl CloneSelf for StructOrdered {\n    fn clone_self(&self) -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\nimpl Default for StructOrdered {\n    fn default() -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\nimpl std::clone::Clone for StructOrdered {\n    fn clone(&self) -> Self {\n        Self {\n            a: true,\n            b: true,\n            c: true,\n        }\n    }\n}\n\n#[derive(Clone, Default)]\nstruct StructUnordered {\n    a: bool,\n    b: bool,\n    c: bool,\n    d: bool,\n}\n\nimpl TraitUnordered for StructUnordered {\n    fn a() {}\n    fn c() {}\n    fn b() {}\n    //~^ arbitrary_source_item_ordering\n\n    type SomeType = ();\n\n    const A: bool = false;\n    const C: bool = false;\n    const B: bool = false;\n    //~^ arbitrary_source_item_ordering\n}\n\nimpl TraitUnorderedItemKinds for StructUnordered {\n    const A: bool = false;\n\n    type SomeType = ();\n    //~^ arbitrary_source_item_ordering\n\n    fn a() {}\n    //~^ arbitrary_source_item_ordering\n}\n\nstruct StructUnorderedGeneric<T> {\n    _1: std::marker::PhantomData<T>,\n    a: bool,\n    b: bool,\n    c: bool,\n    d: bool,\n}\n\ntrait TraitOrdered {\n    fn a();\n    fn b();\n    fn c();\n\n    type SomeType;\n\n    const A: bool;\n    const B: bool;\n    const C: bool;\n}\n\ntrait TraitUnordered {\n    fn a();\n    fn c();\n    fn b();\n    //~^ arbitrary_source_item_ordering\n\n    type SomeType;\n\n    const A: bool;\n    const C: bool;\n    const B: bool;\n    //~^ arbitrary_source_item_ordering\n}\n\ntrait TraitUnorderedItemKinds {\n    const A: bool;\n\n    type SomeType;\n    //~^ arbitrary_source_item_ordering\n\n    fn a();\n    //~^ arbitrary_source_item_ordering\n}\n\n#[derive(std::clone::Clone, Default)]\nstruct ZisShouldBeBeforeZeMainFn;\n\nfn main() {\n    // test code goes here\n}\n\n#[cfg(test)]\nmod test {\n    const B: i8 = 1;\n\n    const A: i8 = 0;\n}\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:105:8\n   |\nLL |     fn b() {}\n   |        ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:104:8\n   |\nLL |     fn c() {}\n   |        ^\n   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:112:11\n   |\nLL |     const B: bool = false;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:111:11\n   |\nLL |     const C: bool = false;\n   |           ^\n\nerror: incorrect ordering of impl items (defined order: [Fn, Type, Const])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5\n   |\nLL |     type SomeType = ();\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `A`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5\n   |\nLL |     const A: bool = false;\n   |     ^^^^^^^^^^^^^\n\nerror: incorrect ordering of impl items (defined order: [Fn, Type, Const])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:122:5\n   |\nLL |     fn a() {}\n   |     ^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5\n   |\nLL |     type SomeType = ();\n   |     ^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:149:8\n   |\nLL |     fn b();\n   |        ^\n   |\nnote: should be placed before `c`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:148:8\n   |\nLL |     fn c();\n   |        ^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:156:11\n   |\nLL |     const B: bool;\n   |           ^\n   |\nnote: should be placed before `C`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:155:11\n   |\nLL |     const C: bool;\n   |           ^\n\nerror: incorrect ordering of trait items (defined order: [Fn, Type, Const])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5\n   |\nLL |     type SomeType;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `A`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:161:5\n   |\nLL |     const A: bool;\n   |     ^^^^^^^^^^^^^\n\nerror: incorrect ordering of trait items (defined order: [Fn, Type, Const])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:166:5\n   |\nLL |     fn a();\n   |     ^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5\n   |\nLL |     type SomeType;\n   |     ^^^^^^^^^^^^^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.only_enum.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs:22:5\n   |\nLL |     A,\n   |     ^\n   |\nnote: should be placed before `B`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs:21:5\n   |\nLL |     B,\n   |     ^\n   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: only_enum\n//@[only_enum] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/only_enum\n\n#![allow(dead_code)]\n#![warn(clippy::arbitrary_source_item_ordering)]\n\nfn main() {}\n\nstruct StructUnordered {\n    b: bool,\n    a: bool,\n}\n\nenum EnumOrdered {\n    A,\n    B,\n}\n\nenum EnumUnordered {\n    B,\n    A,\n    //~^ arbitrary_source_item_ordering\n}\n\ntrait TraitUnordered {\n    const B: bool;\n    const A: bool;\n\n    type SomeType;\n\n    fn b();\n    fn a();\n}\n\ntrait TraitUnorderedItemKinds {\n    type SomeType;\n\n    const A: bool;\n\n    fn a();\n}\n\nconst ZIS_SHOULD_BE_AT_THE_TOP: () = ();\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:43:8\n   |\nLL |     fn a() {}\n   |        ^\n   |\nnote: should be placed before `b`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:42:8\n   |\nLL |     fn b() {}\n   |        ^\n   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`\n\nerror: incorrect ordering of impl items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5\n   |\nLL |     type SomeType = i8;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `a`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:43:5\n   |\nLL |     fn a() {}\n   |     ^^^^^^\n\nerror: incorrect ordering of impl items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:49:5\n   |\nLL |     const A: bool = true;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5\n   |\nLL |     type SomeType = i8;\n   |     ^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: only_impl\n//@[only_impl] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/only_impl\n\n#![allow(dead_code)]\n#![warn(clippy::arbitrary_source_item_ordering)]\n\nfn main() {}\n\nstruct StructUnordered {\n    b: bool,\n    a: bool,\n}\n\nstruct BasicStruct {}\n\ntrait BasicTrait {\n    const A: bool;\n\n    type SomeType;\n\n    fn b();\n    fn a();\n}\n\nenum EnumUnordered {\n    B,\n    A,\n}\n\ntrait TraitUnordered {\n    const B: bool;\n    const A: bool;\n\n    type SomeType;\n\n    fn b();\n    fn a();\n}\n\nimpl BasicTrait for StructUnordered {\n    fn b() {}\n    fn a() {}\n    //~^ arbitrary_source_item_ordering\n\n    type SomeType = i8;\n    //~^ arbitrary_source_item_ordering\n\n    const A: bool = true;\n    //~^ arbitrary_source_item_ordering\n}\n\ntrait TraitUnorderedItemKinds {\n    type SomeType;\n\n    const A: bool;\n\n    fn a();\n}\n\nconst ZIS_SHOULD_BE_AT_THE_TOP: () = ();\n\nimpl BasicTrait for BasicStruct {\n    const A: bool = true;\n\n    type SomeType = i8;\n\n    fn a() {}\n    fn b() {}\n}\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:32:11\n   |\nLL |     const A: bool;\n   |           ^\n   |\nnote: should be placed before `B`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:31:11\n   |\nLL |     const B: bool;\n   |           ^\n   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:38:8\n   |\nLL |     fn a();\n   |        ^\n   |\nnote: should be placed before `b`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:37:8\n   |\nLL |     fn b();\n   |        ^\n\nerror: incorrect ordering of trait items (defined order: [Const, Type, Fn])\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:45:5\n   |\nLL |     const A: bool;\n   |     ^^^^^^^^^^^^^\n   |\nnote: should be placed before `SomeType`\n  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:43:5\n   |\nLL |     type SomeType;\n   |     ^^^^^^^^^^^^^\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: only_trait\n//@[only_trait] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/only_trait\n\n#![allow(dead_code)]\n#![warn(clippy::arbitrary_source_item_ordering)]\n\nfn main() {}\n\nstruct StructUnordered {\n    b: bool,\n    a: bool,\n}\n\ntrait TraitOrdered {\n    const A: bool;\n    const B: bool;\n\n    type SomeType;\n\n    fn a();\n    fn b();\n}\n\nenum EnumUnordered {\n    B,\n    A,\n}\n\ntrait TraitUnordered {\n    const B: bool;\n    const A: bool;\n    //~^ arbitrary_source_item_ordering\n\n    type SomeType;\n\n    fn b();\n    fn a();\n    //~^ arbitrary_source_item_ordering\n}\n\ntrait TraitUnorderedItemKinds {\n    type SomeType;\n\n    const A: bool;\n    //~^ arbitrary_source_item_ordering\n\n    fn a();\n}\n\nconst ZIS_SHOULD_BE_AT_THE_TOP: () = ();\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.default.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:36:5\n   |\nLL |     a: bool,\n   |     ^\n   |\nnote: should be placed before `b`\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5\n   |\nLL |     b: bool,\n   |     ^\nnote: the lint level is defined here\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:33:8\n   |\nLL | #[deny(clippy::arbitrary_source_item_ordering)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_2.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:25:8\n   |\nLL | struct OrderedChecked {\n   |        ^^^^^^^^^^^^^^\n   |\nnote: should be placed before `Unordered`\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:19:8\n   |\nLL | struct Unordered {\n   |        ^^^^^^^^^\nnote: the lint level is defined here\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:10:9\n   |\nLL | #![deny(clippy::arbitrary_source_item_ordering)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:36:5\n   |\nLL |     a: bool,\n   |     ^\n   |\nnote: should be placed before `b`\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5\n   |\nLL |     b: bool,\n   |     ^\nnote: the lint level is defined here\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:33:8\n   |\nLL | #[deny(clippy::arbitrary_source_item_ordering)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_in_3.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:25:8\n   |\nLL | struct OrderedChecked {\n   |        ^^^^^^^^^^^^^^\n   |\nnote: should be placed before `Unordered`\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:19:8\n   |\nLL | struct Unordered {\n   |        ^^^^^^^^^\nnote: the lint level is defined here\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:10:9\n   |\nLL | #![deny(clippy::arbitrary_source_item_ordering)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.ord_within.stderr",
    "content": "error: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:25:8\n   |\nLL | struct OrderedChecked {\n   |        ^^^^^^^^^^^^^^\n   |\nnote: should be placed before `Unordered`\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:19:8\n   |\nLL | struct Unordered {\n   |        ^^^^^^^^^\nnote: the lint level is defined here\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:10:9\n   |\nLL | #![deny(clippy::arbitrary_source_item_ordering)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:46:4\n   |\nLL | fn before_main() {}\n   |    ^^^^^^^^^^^\n   |\nnote: should be placed before `main`\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:42:4\n   |\nLL | fn main() {\n   |    ^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:36:5\n   |\nLL |     a: bool,\n   |     ^\n   |\nnote: should be placed before `b`\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:35:5\n   |\nLL |     b: bool,\n   |     ^\nnote: the lint level is defined here\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:33:8\n   |\nLL | #[deny(clippy::arbitrary_source_item_ordering)]\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: incorrect ordering of items (must be alphabetically ordered)\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:52:11\n   |\nLL |     const A: i8 = 0;\n   |           ^\n   |\nnote: should be placed before `B`\n  --> tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs:51:11\n   |\nLL |     const B: i8 = 1;\n   |           ^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/selective_ordering.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: default ord_within ord_in_2 ord_in_3\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default\n//@[ord_within] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_within\n//@[ord_in_2] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_in_2\n//@[ord_in_3] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/ord_in_3\n//@compile-flags: --test\n\n#![allow(dead_code)]\n#![deny(clippy::arbitrary_source_item_ordering)]\n\n#[allow(clippy::arbitrary_source_item_ordering)]\nstruct Ordered {\n    a: bool,\n    b: bool,\n}\n\n#[allow(clippy::arbitrary_source_item_ordering)]\nstruct Unordered {\n    b: bool,\n    a: bool,\n}\n\n#[deny(clippy::arbitrary_source_item_ordering)]\nstruct OrderedChecked {\n    //~[ord_within]^ arbitrary_source_item_ordering\n    //~[ord_in_2]| arbitrary_source_item_ordering\n    //~[ord_in_3]| arbitrary_source_item_ordering\n    a: bool,\n    b: bool,\n}\n\n#[deny(clippy::arbitrary_source_item_ordering)]\nstruct UnorderedChecked {\n    b: bool,\n    a: bool,\n    //~[ord_within]^ arbitrary_source_item_ordering\n    //~[default]| arbitrary_source_item_ordering\n    //~[ord_in_2]| arbitrary_source_item_ordering\n}\n\nfn main() {\n    // test code goes here\n}\n\nfn before_main() {}\n//~[ord_within]^ arbitrary_source_item_ordering\n\n#[cfg(test)]\nmod test {\n    const B: i8 = 1;\n    const A: i8 = 0;\n    //~[ord_within]^ arbitrary_source_item_ordering\n}\n"
  },
  {
    "path": "tests/ui-toml/arbitrary_source_item_ordering/var_1/clippy.toml",
    "content": "trait-assoc-item-kinds-order = [\"fn\", \"type\", \"const\"]\n"
  },
  {
    "path": "tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs",
    "content": "#![warn(clippy::arithmetic_side_effects)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nuse core::ops::{Add, Neg};\n\nmacro_rules! create {\n    ($name:ident) => {\n        #[allow(clippy::arithmetic_side_effects)]\n        #[derive(Clone, Copy)]\n        struct $name;\n\n        impl Add<$name> for $name {\n            type Output = $name;\n            fn add(self, other: $name) -> Self::Output {\n                todo!()\n            }\n        }\n\n        impl Add<i32> for $name {\n            type Output = $name;\n            fn add(self, other: i32) -> Self::Output {\n                todo!()\n            }\n        }\n\n        impl Add<$name> for i32 {\n            type Output = $name;\n            fn add(self, other: $name) -> Self::Output {\n                todo!()\n            }\n        }\n\n        impl Add<i64> for $name {\n            type Output = $name;\n            fn add(self, other: i64) -> Self::Output {\n                todo!()\n            }\n        }\n\n        impl Add<$name> for i64 {\n            type Output = $name;\n            fn add(self, other: $name) -> Self::Output {\n                todo!()\n            }\n        }\n\n        impl Neg for $name {\n            type Output = $name;\n            fn neg(self) -> Self::Output {\n                todo!()\n            }\n        }\n    };\n}\n\ncreate!(Foo);\ncreate!(Bar);\ncreate!(Baz);\ncreate!(OutOfNames);\n\nfn lhs_and_rhs_are_equal() {\n    // is explicitly on the list\n    let _ = OutOfNames + OutOfNames;\n    // is explicitly on the list\n    let _ = Foo + Foo;\n    // is implicitly on the list\n    let _ = Bar + Bar;\n    // not on the list\n    let _ = Baz + Baz;\n    //~^ arithmetic_side_effects\n}\n\nfn lhs_is_different() {\n    // is explicitly on the list\n    let _ = 1i32 + OutOfNames;\n    // is explicitly on the list\n    let _ = 1i32 + Foo;\n    // is implicitly on the list\n    let _ = 1i32 + Bar;\n    // not on the list\n    let _ = 1i32 + Baz;\n    //~^ arithmetic_side_effects\n\n    // not on the list\n    let _ = 1i64 + Foo;\n    //~^ arithmetic_side_effects\n    // is implicitly on the list\n    let _ = 1i64 + Bar;\n    // not on the list\n    let _ = 1i64 + Baz;\n    //~^ arithmetic_side_effects\n}\n\nfn rhs_is_different() {\n    // is explicitly on the list\n    let _ = OutOfNames + 1i32;\n    // is explicitly on the list\n    let _ = Foo + 1i32;\n    // is implicitly on the list\n    let _ = Bar + 1i32;\n    // not on the list\n    let _ = Baz + 1i32;\n    //~^ arithmetic_side_effects\n\n    // not on the list\n    let _ = Foo + 1i64;\n    //~^ arithmetic_side_effects\n    // is implicitly on the list\n    let _ = Bar + 1i64;\n    // not on the list\n    let _ = Baz + 1i64;\n    //~^ arithmetic_side_effects\n}\n\nfn unary() {\n    // is explicitly on the list\n    let _ = -OutOfNames;\n    // is explicitly on the list\n    let _ = -Foo;\n    // not on the list\n    let _ = -Bar;\n    //~^ arithmetic_side_effects\n    // not on the list\n    let _ = -Baz;\n    //~^ arithmetic_side_effects\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.stderr",
    "content": "error: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:69:13\n   |\nLL |     let _ = Baz + Baz;\n   |             ^^^^^^^^^\n   |\n   = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:81:13\n   |\nLL |     let _ = 1i32 + Baz;\n   |             ^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:85:13\n   |\nLL |     let _ = 1i64 + Foo;\n   |             ^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:90:13\n   |\nLL |     let _ = 1i64 + Baz;\n   |             ^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:102:13\n   |\nLL |     let _ = Baz + 1i32;\n   |             ^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:106:13\n   |\nLL |     let _ = Foo + 1i64;\n   |             ^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:111:13\n   |\nLL |     let _ = Baz + 1i64;\n   |             ^^^^^^^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:121:13\n   |\nLL |     let _ = -Bar;\n   |             ^^^^\n\nerror: arithmetic operation that can potentially result in unexpected side-effects\n  --> tests/ui-toml/arithmetic_side_effects_allowed/arithmetic_side_effects_allowed.rs:124:13\n   |\nLL |     let _ = -Baz;\n   |             ^^^^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/arithmetic_side_effects_allowed/clippy.toml",
    "content": "arithmetic-side-effects-allowed = [\n    \"OutOfNames\"\n]\narithmetic-side-effects-allowed-binary = [\n    [\"Foo\", \"Foo\"],\n    [\"Foo\", \"i32\"],\n    [\"i32\", \"Foo\"],\n    [\"Bar\", \"*\"],\n    [\"*\", \"Bar\"],\n]\narithmetic-side-effects-allowed-unary = [\"Foo\"]\n"
  },
  {
    "path": "tests/ui-toml/array_size_threshold/array_size_threshold.rs",
    "content": "#![allow(unused)]\n#![warn(clippy::large_const_arrays, clippy::large_stack_arrays)]\n//@no-rustfix\nconst ABOVE: [u8; 11] = [0; 11];\n//~^ large_const_arrays\nconst BELOW: [u8; 10] = [0; 10];\n\nfn main() {\n    let above = [0u8; 11];\n    //~^ large_stack_arrays\n    let below = [0u8; 10];\n}\n"
  },
  {
    "path": "tests/ui-toml/array_size_threshold/array_size_threshold.stderr",
    "content": "error: large array defined as const\n  --> tests/ui-toml/array_size_threshold/array_size_threshold.rs:4:1\n   |\nLL | const ABOVE: [u8; 11] = [0; 11];\n   | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   | |\n   | help: make this a static item: `static`\n   |\n   = note: `-D clippy::large-const-arrays` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_const_arrays)]`\n\nerror: allocating a local array larger than 10 bytes\n  --> tests/ui-toml/array_size_threshold/array_size_threshold.rs:9:17\n   |\nLL |     let above = [0u8; 11];\n   |                 ^^^^^^^^^\n   |\n   = help: consider allocating on the heap with `vec![0u8; 11].into_boxed_slice()`\n   = note: `-D clippy::large-stack-arrays` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_stack_arrays)]`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/array_size_threshold/clippy.toml",
    "content": "array-size-threshold = 10\n"
  },
  {
    "path": "tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs",
    "content": "#![warn(clippy::await_holding_invalid_type)]\n#![allow(clippy::ip_constant)]\nuse std::net::Ipv4Addr;\n\nasync fn bad() -> u32 {\n    let _x = String::from(\"hello\");\n    //~^ await_holding_invalid_type\n    baz().await\n}\n\nasync fn bad_reason() -> u32 {\n    let x = Ipv4Addr::new(127, 0, 0, 1);\n    //~^ await_holding_invalid_type\n    let y = baz().await;\n    let _x = x;\n    y\n}\n\nasync fn good() -> u32 {\n    {\n        let _x = String::from(\"hi!\");\n        let _y = Ipv4Addr::new(127, 0, 0, 1);\n    }\n    baz().await;\n    let _x = String::from(\"hi!\");\n    47\n}\n\nasync fn baz() -> u32 {\n    42\n}\n\n#[allow(clippy::manual_async_fn)]\nfn block_bad() -> impl std::future::Future<Output = u32> {\n    async move {\n        let _x = String::from(\"hi!\");\n        //~^ await_holding_invalid_type\n        baz().await\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr",
    "content": "error: holding a disallowed type across an await point `std::string::String`\n  --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:6:9\n   |\nLL |     let _x = String::from(\"hello\");\n   |         ^^\n   |\n   = note: strings are bad\n   = note: `-D clippy::await-holding-invalid-type` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::await_holding_invalid_type)]`\n\nerror: holding a disallowed type across an await point `std::net::Ipv4Addr`\n  --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:12:9\n   |\nLL |     let x = Ipv4Addr::new(127, 0, 0, 1);\n   |         ^\n\nerror: holding a disallowed type across an await point `std::string::String`\n  --> tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs:36:13\n   |\nLL |         let _x = String::from(\"hi!\");\n   |             ^^\n   |\n   = note: strings are bad\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/await_holding_invalid_type/clippy.toml",
    "content": "await-holding-invalid-types = [\n    { path = \"std::string::String\", reason = \"strings are bad\" },\n    \"std::net::Ipv4Addr\",\n]\n"
  },
  {
    "path": "tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.rs",
    "content": "//@error-in-other-file:\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/await_holding_invalid_type_with_replacement/await_holding_invalid_type.stderr",
    "content": "error: error reading Clippy's configuration file: replacement not allowed for this configuration\n  --> $DIR/tests/ui-toml/await_holding_invalid_type_with_replacement/clippy.toml:2:5\n   |\nLL |     { path = \"std::string::String\", replacement = \"std::net::Ipv4Addr\" },\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/await_holding_invalid_type_with_replacement/clippy.toml",
    "content": "await-holding-invalid-types = [\n    { path = \"std::string::String\", replacement = \"std::net::Ipv4Addr\" },\n]\n"
  },
  {
    "path": "tests/ui-toml/bad_toml/clippy.toml",
    "content": "fn this_is_obviously(not: a, toml: file) {\n}\n"
  },
  {
    "path": "tests/ui-toml/bad_toml/conf_bad_toml.rs",
    "content": "//@error-in-other-file: error reading Clippy's configuration file: expected `.`, `=`\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/bad_toml/conf_bad_toml.stderr",
    "content": "error: error reading Clippy's configuration file: expected `.`, `=`\n  --> $DIR/tests/ui-toml/bad_toml/clippy.toml:1:4\n   |\nLL | fn this_is_obviously(not: a, toml: file) {\n   |    ^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/bad_toml_type/clippy.toml",
    "content": "disallowed-names = 42\n"
  },
  {
    "path": "tests/ui-toml/bad_toml_type/conf_bad_type.rs",
    "content": "//@error-in-other-file: invalid type: integer `42`, expected a sequence\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/bad_toml_type/conf_bad_type.stderr",
    "content": "error: error reading Clippy's configuration file: invalid type: integer `42`, expected a sequence\n  --> $DIR/tests/ui-toml/bad_toml_type/clippy.toml:1:20\n   |\nLL | disallowed-names = 42\n   |                    ^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/borrow_interior_mutable_const/clippy.toml",
    "content": "ignore-interior-mutability = [\"borrow_interior_mutable_const_ignore::Counted\"]"
  },
  {
    "path": "tests/ui-toml/borrow_interior_mutable_const/ignore.rs",
    "content": "//@compile-flags: --crate-name borrow_interior_mutable_const_ignore\n//@check-pass\n\n#![warn(clippy::borrow_interior_mutable_const)]\n#![allow(clippy::declare_interior_mutable_const)]\n\nuse core::cell::Cell;\nuse std::cmp::{Eq, PartialEq};\nuse std::collections::{HashMap, HashSet};\nuse std::hash::{Hash, Hasher};\nuse std::ops::Deref;\nuse std::sync::atomic::{AtomicUsize, Ordering};\n\nstruct Counted<T> {\n    count: AtomicUsize,\n    val: T,\n}\n\nimpl<T> Counted<T> {\n    const fn new(val: T) -> Self {\n        Self {\n            count: AtomicUsize::new(0),\n            val,\n        }\n    }\n}\n\nenum OptionalCell {\n    Unfrozen(Counted<bool>),\n    Frozen,\n}\n\nconst UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Counted::new(true));\nconst FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen;\n\nfn main() {\n    let _ = &UNFROZEN_VARIANT;\n}\n"
  },
  {
    "path": "tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.default.stderr",
    "content": "error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`\n  --> tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs:14:5\n   |\nLL |     sleep(Duration::new(1, 0))\n   |     ^^^^^\n   |\n   = note: `-D clippy::incompatible-msrv` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr",
    "content": "error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`\n  --> tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs:14:5\n   |\nLL |     sleep(Duration::new(1, 0))\n   |     ^^^^^\n   |\n   = note: `-D clippy::incompatible-msrv` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`\n  --> tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs:20:5\n   |\nLL |     sleep(Duration::new(1, 0));\n   |     ^^^^^\n\nerror: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`\n  --> tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs:28:9\n   |\nLL |         sleep(Duration::new(1, 0));\n   |         ^^^^^\n   |\n   = note: you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.rs",
    "content": "//@compile-flags: --test\n//@revisions: default enabled\n//@[enabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/check_incompatible_msrv_in_tests/enabled\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/check_incompatible_msrv_in_tests/default\n\n#![warn(clippy::incompatible_msrv)]\n#![feature(custom_inner_attributes)]\n#![clippy::msrv = \"1.3.0\"]\n\nuse std::thread::sleep;\nuse std::time::Duration;\n\nfn main() {\n    sleep(Duration::new(1, 0))\n    //~^ incompatible_msrv\n}\n\n#[test]\nfn test() {\n    sleep(Duration::new(1, 0));\n    //~[enabled]^ incompatible_msrv\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    fn helper() {\n        sleep(Duration::new(1, 0));\n        //~[enabled]^ incompatible_msrv\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/check_incompatible_msrv_in_tests/default/clippy.toml",
    "content": "# default config has check-incompatible-msrv-in-tests as false\n"
  },
  {
    "path": "tests/ui-toml/check_incompatible_msrv_in_tests/enabled/clippy.toml",
    "content": "check-incompatible-msrv-in-tests = true\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/clippy.toml",
    "content": "lint-commented-code = true\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_else_if.fixed",
    "content": "#![allow(clippy::eq_op, clippy::nonminimal_bool)]\n#![warn(clippy::collapsible_else_if)]\n\n#[rustfmt::skip]\nfn main() {\n    let (x, y) = (\"hello\", \"world\");\n\n    if x == \"hello\" {\n        todo!()\n    }\n        // Comment must be kept\n        else if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        todo!()\n    } // Inner comment\n        else if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        todo!()\n    }\n        /* Inner comment */\n        else if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^^ collapsible_else_if\n\n    if x == \"hello\" { \n        todo!()\n    } /* Inner comment */\n        else if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        todo!()\n    } /* This should not be removed */ /* So does this */\n        // Comment must be kept\n        else if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^^ collapsible_else_if\n}\n\nfn issue_13365() {\n    // the comments don't stop us from linting, so the the `expect` *will* be fulfilled\n    if true {\n    } else {\n        // some other text before\n        #[expect(clippy::collapsible_else_if)]\n        if false {}\n    }\n\n    if true {\n    } else {\n        #[expect(clippy::collapsible_else_if)]\n        // some other text after\n        if false {}\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_else_if.rs",
    "content": "#![allow(clippy::eq_op, clippy::nonminimal_bool)]\n#![warn(clippy::collapsible_else_if)]\n\n#[rustfmt::skip]\nfn main() {\n    let (x, y) = (\"hello\", \"world\");\n\n    if x == \"hello\" {\n        todo!()\n    } else {\n        // Comment must be kept\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        todo!()\n    } else { // Inner comment\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        todo!()\n    } else {\n        /* Inner comment */\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^^ collapsible_else_if\n\n    if x == \"hello\" { \n        todo!()\n    } else { /* Inner comment */\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_else_if\n\n    if x == \"hello\" {\n        todo!()\n    } /* This should not be removed */ else /* So does this */ {\n        // Comment must be kept\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^^ collapsible_else_if\n}\n\nfn issue_13365() {\n    // the comments don't stop us from linting, so the the `expect` *will* be fulfilled\n    if true {\n    } else {\n        // some other text before\n        #[expect(clippy::collapsible_else_if)]\n        if false {}\n    }\n\n    if true {\n    } else {\n        #[expect(clippy::collapsible_else_if)]\n        // some other text after\n        if false {}\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_else_if.stderr",
    "content": "error: this `else { if .. }` block can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_else_if.rs:10:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         // Comment must be kept\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::collapsible-else-if` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_else_if)]`\nhelp: collapse nested if block\n   |\nLL ~     }\nLL |         // Comment must be kept\nLL ~         else if y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_else_if.rs:20:12\n   |\nLL |       } else { // Inner comment\n   |  ____________^\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } // Inner comment\nLL ~         else if y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_else_if.rs:29:12\n   |\nLL |       } else {\n   |  ____________^\nLL | |         /* Inner comment */\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     }\nLL |         /* Inner comment */\nLL ~         else if y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_else_if.rs:39:12\n   |\nLL |       } else { /* Inner comment */\n   |  ____________^\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } /* Inner comment */\nLL ~         else if y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `else { if .. }` block can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_else_if.rs:48:64\n   |\nLL |       } /* This should not be removed */ else /* So does this */ {\n   |  ________________________________________________________________^\nLL | |         // Comment must be kept\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     } /* This should not be removed */ /* So does this */\nLL |         // Comment must be kept\nLL ~         else if y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_if.fixed",
    "content": "#![allow(clippy::eq_op, clippy::nonminimal_bool)]\n\n#[rustfmt::skip]\n#[warn(clippy::collapsible_if)]\nfn main() {\n    let (x, y) = (\"hello\", \"world\");\n\n    if x == \"hello\"\n        // Comment must be kept\n        && y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^^ collapsible_if\n\n    // The following tests check for the fix of https://github.com/rust-lang/rust-clippy/issues/798\n    if x == \"hello\" // Inner comment\n        && y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\"\n        /* Inner comment */\n        && y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^^ collapsible_if\n\n    if x == \"hello\" /* Inner comment */\n        && y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    //~^^^^^ collapsible_if\n}\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_if.rs",
    "content": "#![allow(clippy::eq_op, clippy::nonminimal_bool)]\n\n#[rustfmt::skip]\n#[warn(clippy::collapsible_if)]\nfn main() {\n    let (x, y) = (\"hello\", \"world\");\n\n    if x == \"hello\" {\n        // Comment must be kept\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^^ collapsible_if\n\n    // The following tests check for the fix of https://github.com/rust-lang/rust-clippy/issues/798\n    if x == \"hello\" { // Inner comment\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_if\n\n    if x == \"hello\" {\n        /* Inner comment */\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^^ collapsible_if\n\n    if x == \"hello\" { /* Inner comment */\n        if y == \"world\" {\n            println!(\"Hello world!\");\n        }\n    }\n    //~^^^^^ collapsible_if\n}\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_if.stderr",
    "content": "error: this `if` statement can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_if.rs:8:5\n   |\nLL | /     if x == \"hello\" {\nLL | |         // Comment must be kept\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::collapsible-if` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]`\nhelp: collapse nested if block\n   |\nLL ~     if x == \"hello\"\nLL |         // Comment must be kept\nLL ~         && y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_if.rs:17:5\n   |\nLL | /     if x == \"hello\" { // Inner comment\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if x == \"hello\" // Inner comment\nLL ~         && y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_if.rs:24:5\n   |\nLL | /     if x == \"hello\" {\nLL | |         /* Inner comment */\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if x == \"hello\"\nLL |         /* Inner comment */\nLL ~         && y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_if.rs:32:5\n   |\nLL | /     if x == \"hello\" { /* Inner comment */\nLL | |         if y == \"world\" {\nLL | |             println!(\"Hello world!\");\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if x == \"hello\" /* Inner comment */\nLL ~         && y == \"world\" {\nLL |             println!(\"Hello world!\");\nLL ~         }\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_if_let_chains.fixed",
    "content": "#![warn(clippy::collapsible_if)]\n\nfn main() {\n    if let Some(a) = Some(3)\n        // with comment\n        && let Some(b) = Some(4) {\n            let _ = a + b;\n        }\n    //~^^^^^^ collapsible_if\n\n    if let Some(a) = Some(3)\n        // with comment\n        && a + 1 == 4 {\n            let _ = a;\n        }\n    //~^^^^^^ collapsible_if\n\n    if Some(3) == Some(4).map(|x| x - 1)\n        // with comment\n        && let Some(b) = Some(4) {\n            let _ = b;\n        }\n    //~^^^^^^ collapsible_if\n}\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs",
    "content": "#![warn(clippy::collapsible_if)]\n\nfn main() {\n    if let Some(a) = Some(3) {\n        // with comment\n        if let Some(b) = Some(4) {\n            let _ = a + b;\n        }\n    }\n    //~^^^^^^ collapsible_if\n\n    if let Some(a) = Some(3) {\n        // with comment\n        if a + 1 == 4 {\n            let _ = a;\n        }\n    }\n    //~^^^^^^ collapsible_if\n\n    if Some(3) == Some(4).map(|x| x - 1) {\n        // with comment\n        if let Some(b) = Some(4) {\n            let _ = b;\n        }\n    }\n    //~^^^^^^ collapsible_if\n}\n"
  },
  {
    "path": "tests/ui-toml/collapsible_if/collapsible_if_let_chains.stderr",
    "content": "error: this `if` statement can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:4:5\n   |\nLL | /     if let Some(a) = Some(3) {\nLL | |         // with comment\nLL | |         if let Some(b) = Some(4) {\nLL | |             let _ = a + b;\nLL | |         }\nLL | |     }\n   | |_____^\n   |\n   = note: `-D clippy::collapsible-if` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::collapsible_if)]`\nhelp: collapse nested if block\n   |\nLL ~     if let Some(a) = Some(3)\nLL |         // with comment\nLL ~         && let Some(b) = Some(4) {\nLL |             let _ = a + b;\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:12:5\n   |\nLL | /     if let Some(a) = Some(3) {\nLL | |         // with comment\nLL | |         if a + 1 == 4 {\nLL | |             let _ = a;\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if let Some(a) = Some(3)\nLL |         // with comment\nLL ~         && a + 1 == 4 {\nLL |             let _ = a;\nLL ~         }\n   |\n\nerror: this `if` statement can be collapsed\n  --> tests/ui-toml/collapsible_if/collapsible_if_let_chains.rs:20:5\n   |\nLL | /     if Some(3) == Some(4).map(|x| x - 1) {\nLL | |         // with comment\nLL | |         if let Some(b) = Some(4) {\nLL | |             let _ = b;\nLL | |         }\nLL | |     }\n   | |_____^\n   |\nhelp: collapse nested if block\n   |\nLL ~     if Some(3) == Some(4).map(|x| x - 1)\nLL |         // with comment\nLL ~         && let Some(b) = Some(4) {\nLL |             let _ = b;\nLL ~         }\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/conf_deprecated_key/clippy.toml",
    "content": "# Expect errors from these deprecated configs\ncyclomatic-complexity-threshold = 2\nblacklisted-names = [ \"..\", \"wibble\" ]\n\n# that one is white-listed\n[third-party]\nclippy-feature = \"nightly\"\n"
  },
  {
    "path": "tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs",
    "content": "fn main() {}\n\n#[warn(clippy::cognitive_complexity)]\nfn cognitive_complexity() {\n    //~^ cognitive_complexity\n    let x = vec![1, 2, 3];\n    for i in x {\n        if i == 1 {\n            println!(\"{i}\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr",
    "content": "warning: error reading Clippy's configuration file: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead\n  --> $DIR/tests/ui-toml/conf_deprecated_key/clippy.toml:2:1\n   |\nLL | cyclomatic-complexity-threshold = 2\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nwarning: error reading Clippy's configuration file: deprecated field `blacklisted-names`. Please use `disallowed-names` instead\n  --> $DIR/tests/ui-toml/conf_deprecated_key/clippy.toml:3:1\n   |\nLL | blacklisted-names = [ \"..\", \"wibble\" ]\n   | ^^^^^^^^^^^^^^^^^\n\nerror: the function has a cognitive complexity of (3/2)\n  --> tests/ui-toml/conf_deprecated_key/conf_deprecated_key.rs:4:4\n   |\nLL | fn cognitive_complexity() {\n   |    ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: you could split it up into multiple smaller functions\n   = note: `-D clippy::cognitive-complexity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::cognitive_complexity)]`\n\nerror: aborting due to 1 previous error; 2 warnings emitted\n\n"
  },
  {
    "path": "tests/ui-toml/dbg_macro/clippy.toml",
    "content": "allow-dbg-in-tests = true\n"
  },
  {
    "path": "tests/ui-toml/dbg_macro/dbg_macro.fixed",
    "content": "//@compile-flags: --test\n#![warn(clippy::dbg_macro)]\n#![allow(clippy::unnecessary_operation, clippy::no_effect)]\n\nfn foo(n: u32) -> u32 {\n    if let Some(n) = n.checked_sub(4) { n } else { n }\n    //~^ dbg_macro\n}\n\nfn factorial(n: u32) -> u32 {\n    if n <= 1 {\n        //~^ dbg_macro\n        1\n        //~^ dbg_macro\n    } else {\n        n * factorial(n - 1)\n        //~^ dbg_macro\n    }\n}\n\nfn main() {\n    42;\n    //~^ dbg_macro\n    foo(3) + factorial(4);\n    //~^ dbg_macro\n    (1, 2, 3, 4, 5);\n    //~^ dbg_macro\n}\n\n#[test]\npub fn issue8481() {\n    dbg!(1);\n}\n\n#[cfg(test)]\nfn foo2() {\n    dbg!(1);\n}\n\n#[cfg(test)]\nmod mod1 {\n    fn func() {\n        dbg!(1);\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/dbg_macro/dbg_macro.rs",
    "content": "//@compile-flags: --test\n#![warn(clippy::dbg_macro)]\n#![allow(clippy::unnecessary_operation, clippy::no_effect)]\n\nfn foo(n: u32) -> u32 {\n    if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }\n    //~^ dbg_macro\n}\n\nfn factorial(n: u32) -> u32 {\n    if dbg!(n <= 1) {\n        //~^ dbg_macro\n        dbg!(1)\n        //~^ dbg_macro\n    } else {\n        dbg!(n * factorial(n - 1))\n        //~^ dbg_macro\n    }\n}\n\nfn main() {\n    dbg!(42);\n    //~^ dbg_macro\n    foo(3) + dbg!(factorial(4));\n    //~^ dbg_macro\n    dbg!(1, 2, 3, 4, 5);\n    //~^ dbg_macro\n}\n\n#[test]\npub fn issue8481() {\n    dbg!(1);\n}\n\n#[cfg(test)]\nfn foo2() {\n    dbg!(1);\n}\n\n#[cfg(test)]\nmod mod1 {\n    fn func() {\n        dbg!(1);\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/dbg_macro/dbg_macro.stderr",
    "content": "error: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui-toml/dbg_macro/dbg_macro.rs:6:22\n   |\nLL |     if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }\n   |                      ^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::dbg-macro` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]`\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }\nLL +     if let Some(n) = n.checked_sub(4) { n } else { n }\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui-toml/dbg_macro/dbg_macro.rs:11:8\n   |\nLL |     if dbg!(n <= 1) {\n   |        ^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     if dbg!(n <= 1) {\nLL +     if n <= 1 {\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui-toml/dbg_macro/dbg_macro.rs:13:9\n   |\nLL |         dbg!(1)\n   |         ^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         dbg!(1)\nLL +         1\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui-toml/dbg_macro/dbg_macro.rs:16:9\n   |\nLL |         dbg!(n * factorial(n - 1))\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -         dbg!(n * factorial(n - 1))\nLL +         n * factorial(n - 1)\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui-toml/dbg_macro/dbg_macro.rs:22:5\n   |\nLL |     dbg!(42);\n   |     ^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(42);\nLL +     42;\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui-toml/dbg_macro/dbg_macro.rs:24:14\n   |\nLL |     foo(3) + dbg!(factorial(4));\n   |              ^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     foo(3) + dbg!(factorial(4));\nLL +     foo(3) + factorial(4);\n   |\n\nerror: the `dbg!` macro is intended as a debugging tool\n  --> tests/ui-toml/dbg_macro/dbg_macro.rs:26:5\n   |\nLL |     dbg!(1, 2, 3, 4, 5);\n   |     ^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove the invocation before committing it to a version control system\n   |\nLL -     dbg!(1, 2, 3, 4, 5);\nLL +     (1, 2, 3, 4, 5);\n   |\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/decimal_literal_representation/clippy.toml",
    "content": "literal-representation-threshold = 0xFFFFFF\n"
  },
  {
    "path": "tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed",
    "content": "#![warn(clippy::decimal_literal_representation)]\nfn main() {\n    let _ = 8388608;\n    let _ = 0x00FF_FFFF;\n    //~^ ERROR: integer literal has a better hexadecimal representation\n}\n"
  },
  {
    "path": "tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs",
    "content": "#![warn(clippy::decimal_literal_representation)]\nfn main() {\n    let _ = 8388608;\n    let _ = 16777215;\n    //~^ ERROR: integer literal has a better hexadecimal representation\n}\n"
  },
  {
    "path": "tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr",
    "content": "error: integer literal has a better hexadecimal representation\n  --> tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs:4:13\n   |\nLL |     let _ = 16777215;\n   |             ^^^^^^^^ help: consider: `0x00FF_FFFF`\n   |\n   = note: `-D clippy::decimal-literal-representation` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::decimal_literal_representation)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/declare_interior_mutable_const/clippy.toml",
    "content": "ignore-interior-mutability = [\"declare_interior_mutable_const_ignore::Counted\"]"
  },
  {
    "path": "tests/ui-toml/declare_interior_mutable_const/ignore.rs",
    "content": "//@compile-flags: --crate-name declare_interior_mutable_const_ignore\n//@check-pass\n\n#![warn(clippy::declare_interior_mutable_const)]\n#![allow(clippy::borrow_interior_mutable_const)]\n\nuse core::cell::Cell;\nuse std::cmp::{Eq, PartialEq};\nuse std::collections::{HashMap, HashSet};\nuse std::hash::{Hash, Hasher};\nuse std::ops::Deref;\nuse std::sync::atomic::{AtomicUsize, Ordering};\n\nstruct Counted<T> {\n    count: AtomicUsize,\n    val: T,\n}\n\nimpl<T> Counted<T> {\n    const fn new(val: T) -> Self {\n        Self {\n            count: AtomicUsize::new(0),\n            val,\n        }\n    }\n}\n\nenum OptionalCell {\n    Unfrozen(Counted<bool>),\n    Frozen,\n}\n\nconst UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Counted::new(true));\nconst FROZEN_VARIANT: OptionalCell = OptionalCell::Frozen;\n\nconst fn unfrozen_variant() -> OptionalCell {\n    OptionalCell::Unfrozen(Counted::new(true))\n}\n\nconst fn frozen_variant() -> OptionalCell {\n    OptionalCell::Frozen\n}\n\nconst UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant();\nconst FROZEN_VARIANT_FROM_FN: OptionalCell = frozen_variant();\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/disallowed_macros/auxiliary/macros.rs",
    "content": "#[macro_export]\nmacro_rules! expr {\n    () => {\n        1\n    };\n}\n\n#[macro_export]\nmacro_rules! stmt {\n    () => {\n        let _x = ();\n    };\n}\n\n#[macro_export]\nmacro_rules! ty {\n    () => { &'static str };\n}\n\n#[macro_export]\nmacro_rules! pat {\n    () => {\n        _\n    };\n}\n\n#[macro_export]\nmacro_rules! item {\n    () => {\n        const ITEM: usize = 1;\n    };\n}\n\n#[macro_export]\nmacro_rules! binop {\n    ($t:tt) => {\n        $t + $t\n    };\n}\n\n#[macro_export]\nmacro_rules! attr {\n    ($i:item) => {\n        #[repr(C)]\n        $i\n    };\n}\n"
  },
  {
    "path": "tests/ui-toml/disallowed_macros/auxiliary/proc_macros.rs",
    "content": "extern crate proc_macro;\nuse proc_macro::Delimiter::{Brace, Bracket, Parenthesis};\nuse proc_macro::Spacing::{Alone, Joint};\nuse proc_macro::{Group, Ident, Punct, Span, TokenStream, TokenTree as TT};\n\n#[proc_macro_derive(Derive)]\npub fn derive(_: TokenStream) -> TokenStream {\n    TokenStream::from_iter([\n        TT::from(Punct::new('#', Alone)),\n        TT::from(Group::new(\n            Bracket,\n            TokenStream::from_iter([\n                TT::from(Ident::new(\"allow\", Span::call_site())),\n                TT::from(Group::new(\n                    Parenthesis,\n                    TokenStream::from_iter([\n                        TT::from(Ident::new(\"clippy\", Span::call_site())),\n                        TT::from(Punct::new(':', Joint)),\n                        TT::from(Punct::new(':', Alone)),\n                        TT::from(Ident::new(\"disallowed_macros\", Span::call_site())),\n                    ]),\n                )),\n            ]),\n        )),\n        TT::from(Ident::new(\"impl\", Span::call_site())),\n        TT::from(Ident::new(\"Foo\", Span::call_site())),\n        TT::from(Group::new(Brace, TokenStream::new())),\n    ])\n}\n"
  },
  {
    "path": "tests/ui-toml/disallowed_macros/clippy.toml",
    "content": "disallowed-macros = [\n    \"std::println\",\n    \"std::vec\",\n    { path = \"std::cfg\" },\n    { path = \"serde::Serialize\", reason = \"no serializing\" },\n    \"macros::expr\",\n    \"macros::stmt\",\n    \"macros::ty\",\n    \"macros::pat\",\n    \"macros::item\",\n    \"macros::binop\",\n    \"macros::attr\",\n    \"proc_macros::Derive\",\n]\n"
  },
  {
    "path": "tests/ui-toml/disallowed_macros/disallowed_macros.rs",
    "content": "//@aux-build:macros.rs\n//@aux-build:proc_macros.rs\n\n#![allow(unused)]\n\nextern crate macros;\nextern crate proc_macros;\n\nuse proc_macros::Derive;\nuse serde::Serialize;\n\nfn main() {\n    println!(\"one\");\n    //~^ disallowed_macros\n    println!(\"two\");\n    //~^ disallowed_macros\n    cfg!(unix);\n    //~^ disallowed_macros\n    vec![1, 2, 3];\n    //~^ disallowed_macros\n\n    #[derive(Serialize)]\n    //~^ disallowed_macros\n    struct Derive;\n\n    let _ = macros::expr!();\n    //~^ disallowed_macros\n    macros::stmt!();\n    //~^ disallowed_macros\n    let macros::pat!() = 1;\n    //~^ disallowed_macros\n    let _: macros::ty!() = \"\";\n    //~^ disallowed_macros\n    macros::item!();\n    //~^ disallowed_macros\n    let _ = macros::binop!(1);\n    //~^ disallowed_macros\n\n    eprintln!(\"allowed\");\n}\n\nmacros::attr! {\n//~^ disallowed_macros\n    struct S;\n}\n\nimpl S {\n    macros::item!();\n    //~^ disallowed_macros\n}\n\ntrait Y {\n    macros::item!();\n    //~^ disallowed_macros\n}\n\nimpl Y for S {\n    macros::item!();\n    //~^ disallowed_macros\n}\n\n#[derive(Derive)]\n//~^ disallowed_macros\nstruct Foo;\n"
  },
  {
    "path": "tests/ui-toml/disallowed_macros/disallowed_macros.stderr",
    "content": "error: use of a disallowed macro `serde::Serialize`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:22:14\n   |\nLL |     #[derive(Serialize)]\n   |              ^^^^^^^^^\n   |\n   = note: no serializing\n   = note: `-D clippy::disallowed-macros` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]`\n\nerror: use of a disallowed macro `macros::attr`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:42:1\n   |\nLL | / macros::attr! {\nLL | |\nLL | |     struct S;\nLL | | }\n   | |_^\n\nerror: use of a disallowed macro `proc_macros::Derive`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:62:10\n   |\nLL | #[derive(Derive)]\n   |          ^^^^^^\n\nerror: use of a disallowed macro `std::println`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:13:5\n   |\nLL |     println!(\"one\");\n   |     ^^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `std::println`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:15:5\n   |\nLL |     println!(\"two\");\n   |     ^^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `std::cfg`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:17:5\n   |\nLL |     cfg!(unix);\n   |     ^^^^^^^^^^\n\nerror: use of a disallowed macro `std::vec`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:19:5\n   |\nLL |     vec![1, 2, 3];\n   |     ^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::expr`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:26:13\n   |\nLL |     let _ = macros::expr!();\n   |             ^^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::stmt`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:28:5\n   |\nLL |     macros::stmt!();\n   |     ^^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::pat`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:30:9\n   |\nLL |     let macros::pat!() = 1;\n   |         ^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::ty`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:32:12\n   |\nLL |     let _: macros::ty!() = \"\";\n   |            ^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::item`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:34:5\n   |\nLL |     macros::item!();\n   |     ^^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::binop`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:36:13\n   |\nLL |     let _ = macros::binop!(1);\n   |             ^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::item`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:48:5\n   |\nLL |     macros::item!();\n   |     ^^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::item`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:53:5\n   |\nLL |     macros::item!();\n   |     ^^^^^^^^^^^^^^^\n\nerror: use of a disallowed macro `macros::item`\n  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:58:5\n   |\nLL |     macros::item!();\n   |     ^^^^^^^^^^^^^^^\n\nerror: aborting due to 16 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/disallowed_names_append/clippy.toml",
    "content": "disallowed-names = [\"ducks\", \"..\"]\n"
  },
  {
    "path": "tests/ui-toml/disallowed_names_append/disallowed_names.rs",
    "content": "#![warn(clippy::disallowed_names)]\n\nfn main() {\n    // `foo` is part of the default configuration\n    let foo = \"bar\";\n    //~^ disallowed_names\n    // `ducks` was unrightfully disallowed\n    let ducks = [\"quack\", \"quack\"];\n    //~^ disallowed_names\n    // `fox` is okay\n    let fox = [\"what\", \"does\", \"the\", \"fox\", \"say\", \"?\"];\n}\n"
  },
  {
    "path": "tests/ui-toml/disallowed_names_append/disallowed_names.stderr",
    "content": "error: use of a disallowed/placeholder name `foo`\n  --> tests/ui-toml/disallowed_names_append/disallowed_names.rs:5:9\n   |\nLL |     let foo = \"bar\";\n   |         ^^^\n   |\n   = note: `-D clippy::disallowed-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]`\n\nerror: use of a disallowed/placeholder name `ducks`\n  --> tests/ui-toml/disallowed_names_append/disallowed_names.rs:8:9\n   |\nLL |     let ducks = [\"quack\", \"quack\"];\n   |         ^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/disallowed_names_replace/clippy.toml",
    "content": "disallowed-names = [\"ducks\"]\n"
  },
  {
    "path": "tests/ui-toml/disallowed_names_replace/disallowed_names.rs",
    "content": "#![warn(clippy::disallowed_names)]\n\nfn main() {\n    // `foo` is part of the default configuration\n    let foo = \"bar\";\n    // `ducks` was unrightfully disallowed\n    let ducks = [\"quack\", \"quack\"];\n    //~^ disallowed_names\n    // `fox` is okay\n    let fox = [\"what\", \"does\", \"the\", \"fox\", \"say\", \"?\"];\n}\n"
  },
  {
    "path": "tests/ui-toml/disallowed_names_replace/disallowed_names.stderr",
    "content": "error: use of a disallowed/placeholder name `ducks`\n  --> tests/ui-toml/disallowed_names_replace/disallowed_names.rs:7:9\n   |\nLL |     let ducks = [\"quack\", \"quack\"];\n   |         ^^^^^\n   |\n   = note: `-D clippy::disallowed-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/disallowed_script_idents/clippy.toml",
    "content": "allowed-scripts = [\"Cyrillic\"]\n"
  },
  {
    "path": "tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs",
    "content": "#![warn(clippy::disallowed_script_idents)]\nfn main() {\n    let счётчик = 10;\n    let カウンタ = 10;\n    //~^ ERROR: identifier `カウンタ` has a Unicode script that is not allowed by configuration\n}\n"
  },
  {
    "path": "tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr",
    "content": "error: identifier `カウンタ` has a Unicode script that is not allowed by configuration: Katakana\n  --> tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs:4:9\n   |\nLL |     let カウンタ = 10;\n   |         ^^^^^^^^\n   |\n   = note: `-D clippy::disallowed-script-idents` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_script_idents)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/doc_valid_idents_append/clippy.toml",
    "content": "doc-valid-idents = [\"ClipPy\", \"..\"]\n"
  },
  {
    "path": "tests/ui-toml/doc_valid_idents_append/doc_markdown.fixed",
    "content": "#![warn(clippy::doc_markdown)]\n\n/// This is a special interface for ClipPy which doesn't require backticks\nfn allowed_name() {}\n\n/// OAuth and LaTeX are inside Clippy's default list.\nfn default_name() {}\n\n/// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.\n//~^ doc_markdown\nfn unknown_name() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/doc_valid_idents_append/doc_markdown.rs",
    "content": "#![warn(clippy::doc_markdown)]\n\n/// This is a special interface for ClipPy which doesn't require backticks\nfn allowed_name() {}\n\n/// OAuth and LaTeX are inside Clippy's default list.\nfn default_name() {}\n\n/// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted.\n//~^ doc_markdown\nfn unknown_name() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr",
    "content": "error: item in documentation is missing backticks\n  --> tests/ui-toml/doc_valid_idents_append/doc_markdown.rs:9:5\n   |\nLL | /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted.\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::doc-markdown` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`\nhelp: try\n   |\nLL - /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted.\nLL + /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/doc_valid_idents_replace/clippy.toml",
    "content": "doc-valid-idents = [\"ClipPy\"]\n"
  },
  {
    "path": "tests/ui-toml/doc_valid_idents_replace/doc_markdown.fixed",
    "content": "#![warn(clippy::doc_markdown)]\n\n/// This is a special interface for ClipPy which doesn't require backticks\nfn allowed_name() {}\n\n/// `OAuth` and `LaTeX` are inside Clippy's default list.\n//~^ doc_markdown\n//~| doc_markdown\nfn default_name() {}\n\n/// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.\n//~^ doc_markdown\nfn unknown_name() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs",
    "content": "#![warn(clippy::doc_markdown)]\n\n/// This is a special interface for ClipPy which doesn't require backticks\nfn allowed_name() {}\n\n/// OAuth and LaTeX are inside Clippy's default list.\n//~^ doc_markdown\n//~| doc_markdown\nfn default_name() {}\n\n/// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted.\n//~^ doc_markdown\nfn unknown_name() {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr",
    "content": "error: item in documentation is missing backticks\n  --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:6:5\n   |\nLL | /// OAuth and LaTeX are inside Clippy's default list.\n   |     ^^^^^\n   |\n   = note: `-D clippy::doc-markdown` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`\nhelp: try\n   |\nLL - /// OAuth and LaTeX are inside Clippy's default list.\nLL + /// `OAuth` and LaTeX are inside Clippy's default list.\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:6:15\n   |\nLL | /// OAuth and LaTeX are inside Clippy's default list.\n   |               ^^^^^\n   |\nhelp: try\n   |\nLL - /// OAuth and LaTeX are inside Clippy's default list.\nLL + /// OAuth and `LaTeX` are inside Clippy's default list.\n   |\n\nerror: item in documentation is missing backticks\n  --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:11:5\n   |\nLL | /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted.\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: try\n   |\nLL - /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted.\nLL + /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys/clippy.toml",
    "content": "cognitive-complexity-threshold = 2\ncognitive-complexity-threshold = 4\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys/duplicated_keys.rs",
    "content": "//@error-in-other-file: duplicate key `cognitive-complexity-threshold`\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys/duplicated_keys.stderr",
    "content": "error: error reading Clippy's configuration file: duplicate key `cognitive-complexity-threshold` in document root\n  --> $DIR/tests/ui-toml/duplicated_keys/clippy.toml:2:1\n   |\nLL | cognitive-complexity-threshold = 4\n   | ^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys_deprecated/clippy.toml",
    "content": "cognitive-complexity-threshold = 2\n# This is the deprecated name for the same key\ncyclomatic-complexity-threshold = 3\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.rs",
    "content": "//@error-in-other-file:\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys_deprecated/duplicated_keys.stderr",
    "content": "error: error reading Clippy's configuration file: duplicate field `cognitive_complexity_threshold` (provided as `cyclomatic_complexity_threshold`)\n  --> $DIR/tests/ui-toml/duplicated_keys_deprecated/clippy.toml:3:1\n   |\nLL | cyclomatic-complexity-threshold = 3\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nwarning: error reading Clippy's configuration file: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead\n  --> $DIR/tests/ui-toml/duplicated_keys_deprecated/clippy.toml:3:1\n   |\nLL | cyclomatic-complexity-threshold = 3\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error; 1 warning emitted\n\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys_deprecated_2/clippy.toml",
    "content": "# This is the deprecated name for cognitive-complexity-threshold\ncyclomatic-complexity-threshold = 3\n# Check we get duplication warning regardless of order\ncognitive-complexity-threshold = 4\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.rs",
    "content": "//@error-in-other-file:\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/duplicated_keys_deprecated_2/duplicated_keys.stderr",
    "content": "error: error reading Clippy's configuration file: duplicate field `cognitive-complexity-threshold`\n  --> $DIR/tests/ui-toml/duplicated_keys_deprecated_2/clippy.toml:4:1\n   |\nLL | cognitive-complexity-threshold = 4\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nwarning: error reading Clippy's configuration file: deprecated field `cyclomatic-complexity-threshold`. Please use `cognitive-complexity-threshold` instead\n  --> $DIR/tests/ui-toml/duplicated_keys_deprecated_2/clippy.toml:2:1\n   |\nLL | cyclomatic-complexity-threshold = 3\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error; 1 warning emitted\n\n"
  },
  {
    "path": "tests/ui-toml/enum_variant_size/clippy.toml",
    "content": "enum-variant-size-threshold = 500\n"
  },
  {
    "path": "tests/ui-toml/enum_variant_size/enum_variant_size.fixed",
    "content": "enum Fine {\n    A(()),\n    B([u8; 500]),\n}\nenum Bad {\n    //~^ ERROR: large size difference between variants\n    A(()),\n    B(Box<[u8; 501]>),\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/enum_variant_size/enum_variant_size.rs",
    "content": "enum Fine {\n    A(()),\n    B([u8; 500]),\n}\nenum Bad {\n    //~^ ERROR: large size difference between variants\n    A(()),\n    B([u8; 501]),\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/enum_variant_size/enum_variant_size.stderr",
    "content": "error: large size difference between variants\n  --> tests/ui-toml/enum_variant_size/enum_variant_size.rs:5:1\n   |\nLL | / enum Bad {\nLL | |\nLL | |     A(()),\n   | |     ----- the second-largest variant contains at least 0 bytes\nLL | |     B([u8; 501]),\n   | |     ------------ the largest variant contains at least 501 bytes\nLL | | }\n   | |_^ the entire enum is at least 502 bytes\n   |\n   = note: `-D clippy::large-enum-variant` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`\nhelp: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum\n   |\nLL -     B([u8; 501]),\nLL +     B(Box<[u8; 501]>),\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/excessive_nesting/clippy.toml",
    "content": "excessive-nesting-threshold = 4\n"
  },
  {
    "path": "tests/ui-toml/excessive_nesting/excessive_nesting.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n#![rustfmt::skip]\n#![feature(custom_inner_attributes)]\n#![warn(clippy::excessive_nesting)]\n#![allow(\n    unused,\n    clippy::let_and_return,\n    clippy::redundant_closure_call,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::never_loop,\n    clippy::needless_ifs,\n    clippy::collapsible_if,\n    clippy::blocks_in_conditions,\n    clippy::single_match,\n)]\n\n#[macro_use]\nextern crate proc_macros;\n\nstatic X: u32 = {\n    let x = {\n        let y = {\n            let z = {\n                let w = { 3 };\n                //~^ excessive_nesting\n                w\n            };\n            z\n        };\n        y\n    };\n    x\n};\n\nmacro_rules! xx {\n    () => {{\n        {\n            {\n                {\n                    {\n                        {\n                            {\n                                {\n                                    {\n                                        {\n                                            {\n                                                println!(\"ehe\"); // should not lint\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }};\n}\n\nstruct A;\n\nimpl A {\n    pub fn a(&self, v: u32) {\n        struct B;\n\n        impl B {\n            pub fn b() {\n                struct C;\n\n                impl C {\n                //~^ excessive_nesting\n                    pub fn c() {}\n                }\n            }\n        }\n    }\n}\n\nstruct D { d: u32 }\n\ntrait Lol {\n    fn lmao() {\n        fn bb() {\n            fn cc() {\n                let x = { 1 }; // not a warning, but cc is\n                //~^ excessive_nesting\n            }\n\n            let x = { 1 }; // warning\n        }\n    }\n}\n\n#[allow(clippy::excessive_nesting)]\nfn l() {{{{{{{{{}}}}}}}}}\n\nuse a::{b::{c::{d::{e::{f::{}}}}}}; // should not lint\n\npub mod a {\n    pub mod b {\n        pub mod c {\n            pub mod d {\n                pub mod e {\n                //~^ excessive_nesting\n                    pub mod f {}\n                } // not here\n            } // only warning should be here\n        }\n    }\n}\n\nfn a_but_not(v: u32) {}\n\nfn main() {\n    let a = A;\n\n    a_but_not({{{{{{{{0}}}}}}}});\n    //~^ excessive_nesting\n    a.a({{{{{{{{{0}}}}}}}}});\n    //~^ excessive_nesting\n    (0, {{{{{{{1}}}}}}});\n    //~^ excessive_nesting\n\n    if true {\n        if true {\n            if true {\n                if true {\n                //~^ excessive_nesting\n                    if true {\n\n                    }\n                }\n            }\n        }\n    }\n\n    let y = (|| {\n        let x = (|| {\n            let y = (|| {\n                let z = (|| {\n                //~^ excessive_nesting\n                    let w = { 3 };\n                    w\n                })();\n                z\n            })();\n            y\n        })();\n        x\n    })();\n\n    external! { {{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}} }; // ensure this isn't linted in external macros\n    with_span! { span {{{{{{{{{{{{}}}}}}}}}}}} }; // don't lint for proc macros\n    xx!(); // ensure this is never linted\n    let boo = true;\n    !{boo as u32 + !{boo as u32 + !{boo as u32}}};\n\n    // this is a mess, but that's intentional\n    let mut y = 1;\n    y += {{{{{5}}}}};\n    //~^ excessive_nesting\n    let z = y + {{{{{{{{{5}}}}}}}}};\n    //~^ excessive_nesting\n    [0, {{{{{{{{{{0}}}}}}}}}}];\n    //~^ excessive_nesting\n    let mut xx = [0; {{{{{{{{100}}}}}}}}];\n    //~^ excessive_nesting\n    xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}];\n    //~^ excessive_nesting\n    &mut {{{{{{{{{{y}}}}}}}}}};\n    //~^ excessive_nesting\n\n    for i in {{{{xx}}}} {{{{{{{{}}}}}}}}\n    //~^ excessive_nesting\n    //~| excessive_nesting\n\n    while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}}\n    //~^ excessive_nesting\n    //~| excessive_nesting\n\n    while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}}\n    //~^ excessive_nesting\n    //~| excessive_nesting\n\n    let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} };\n    //~^ excessive_nesting\n\n    {{{{1;}}}}..{{{{{{3}}}}}};\n    //~^ excessive_nesting\n    //~| excessive_nesting\n    {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}};\n    //~^ excessive_nesting\n    //~| excessive_nesting\n    ..{{{{{{{5}}}}}}};\n    //~^ excessive_nesting\n    ..={{{{{3}}}}};\n    //~^ excessive_nesting\n    {{{{{1;}}}}}..;\n    //~^ excessive_nesting\n\n    loop { break {{{{1}}}} };\n    //~^ excessive_nesting\n    loop {{{{{{}}}}}}\n    //~^ excessive_nesting\n\n    match {{{{{{true}}}}}} {\n    //~^ excessive_nesting\n        true => {{{{}}}},\n        //~^ excessive_nesting\n        false => {{{{}}}},\n        //~^ excessive_nesting\n    }\n\n    {\n        {\n            {\n                {\n                //~^ excessive_nesting\n                    println!(\"warning! :)\");\n                }\n            }\n        }\n    }\n}\n\nasync fn b() -> u32 {\n    async fn c() -> u32 {{{{{{{0}}}}}}}\n    //~^ excessive_nesting\n\n    c().await\n}\n\nasync fn a() {\n    {{{{b().await}}}};\n    //~^ excessive_nesting\n}\n"
  },
  {
    "path": "tests/ui-toml/excessive_nesting/excessive_nesting.stderr",
    "content": "error: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:25:25\n   |\nLL |                 let w = { 3 };\n   |                         ^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n   = note: `-D clippy::excessive-nesting` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::excessive_nesting)]`\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:72:17\n   |\nLL | /                 impl C {\nLL | |\nLL | |                     pub fn c() {}\nLL | |                 }\n   | |_________________^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:87:25\n   |\nLL |                 let x = { 1 }; // not a warning, but cc is\n   |                         ^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:105:17\n   |\nLL | /                 pub mod e {\nLL | |\nLL | |                     pub mod f {}\nLL | |                 } // not here\n   | |_________________^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:119:18\n   |\nLL |     a_but_not({{{{{{{{0}}}}}}}});\n   |                  ^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:121:12\n   |\nLL |     a.a({{{{{{{{{0}}}}}}}}});\n   |            ^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:123:12\n   |\nLL |     (0, {{{{{{{1}}}}}}});\n   |            ^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:129:25\n   |\nLL |                   if true {\n   |  _________________________^\nLL | |\nLL | |                     if true {\n...  |\nLL | |                 }\n   | |_________________^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:142:29\n   |\nLL |                   let z = (|| {\n   |  _____________________________^\nLL | |\nLL | |                     let w = { 3 };\nLL | |                     w\nLL | |                 })();\n   | |_________________^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:162:13\n   |\nLL |     y += {{{{{5}}}}};\n   |             ^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:164:20\n   |\nLL |     let z = y + {{{{{{{{{5}}}}}}}}};\n   |                    ^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:166:12\n   |\nLL |     [0, {{{{{{{{{{0}}}}}}}}}}];\n   |            ^^^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:168:25\n   |\nLL |     let mut xx = [0; {{{{{{{{100}}}}}}}}];\n   |                         ^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:170:11\n   |\nLL |     xx[{{{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}}}];\n   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:172:13\n   |\nLL |     &mut {{{{{{{{{{y}}}}}}}}}};\n   |             ^^^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:17\n   |\nLL |     for i in {{{{xx}}}} {{{{{{{{}}}}}}}}\n   |                 ^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:175:28\n   |\nLL |     for i in {{{{xx}}}} {{{{{{{{}}}}}}}}\n   |                            ^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:179:28\n   |\nLL |     while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}}\n   |                            ^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:179:48\n   |\nLL |     while let Some(i) = {{{{{{Some(1)}}}}}} {{{{{{{}}}}}}}\n   |                                                ^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:183:14\n   |\nLL |     while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}}\n   |              ^^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:183:35\n   |\nLL |     while {{{{{{{{true}}}}}}}} {{{{{{{{{}}}}}}}}}\n   |                                   ^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:187:23\n   |\nLL |     let d = D { d: {{{{{{{{{{{{{{{{{{{{{{{3}}}}}}}}}}}}}}}}}}}}}}} };\n   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:190:8\n   |\nLL |     {{{{1;}}}}..{{{{{{3}}}}}};\n   |        ^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:190:20\n   |\nLL |     {{{{1;}}}}..{{{{{{3}}}}}};\n   |                    ^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:193:8\n   |\nLL |     {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}};\n   |        ^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:193:21\n   |\nLL |     {{{{1;}}}}..={{{{{{{{{{{{{{{{{{{{{{{{{{6}}}}}}}}}}}}}}}}}}}}}}}}}};\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:196:10\n   |\nLL |     ..{{{{{{{5}}}}}}};\n   |          ^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:198:11\n   |\nLL |     ..={{{{{3}}}}};\n   |           ^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:200:8\n   |\nLL |     {{{{{1;}}}}}..;\n   |        ^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:203:20\n   |\nLL |     loop { break {{{{1}}}} };\n   |                    ^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:205:13\n   |\nLL |     loop {{{{{{}}}}}}\n   |             ^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:208:14\n   |\nLL |     match {{{{{{true}}}}}} {\n   |              ^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:210:20\n   |\nLL |         true => {{{{}}}},\n   |                    ^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:212:21\n   |\nLL |         false => {{{{}}}},\n   |                     ^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:219:17\n   |\nLL | /                 {\nLL | |\nLL | |                     println!(\"warning! :)\");\nLL | |                 }\n   | |_________________^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:229:28\n   |\nLL |     async fn c() -> u32 {{{{{{{0}}}}}}}\n   |                            ^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: this block is too nested\n  --> tests/ui-toml/excessive_nesting/excessive_nesting.rs:236:8\n   |\nLL |     {{{{b().await}}}};\n   |        ^^^^^^^^^^^\n   |\n   = help: try refactoring your code to minimize nesting\n\nerror: aborting due to 37 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/excessive_precision/clippy.toml",
    "content": "const-literal-digits-threshold = 20\n"
  },
  {
    "path": "tests/ui-toml/excessive_precision/excessive_precision.fixed",
    "content": "#![warn(clippy::excessive_precision)]\n#![allow(\n    dead_code,\n    overflowing_literals,\n    unused_variables,\n    clippy::print_literal,\n    clippy::useless_vec\n)]\n\nfn main() {\n    // Overly specified constants\n    let _: f32 = 1.012_345_7;\n    //~^ excessive_precision\n    let _: f64 = 1.012_345_678_901_234_6;\n    //~^ excessive_precision\n    const _: f32 = 1.012345678901234567890;\n    const _: f64 = 1.012345678901234567890;\n\n    static STATIC1: f32 = 1.012345678901234567890;\n    static STATIC2: f64 = 1.012345678901234567890;\n\n    static mut STATIC_MUT1: f32 = 1.012345678901234567890;\n    static mut STATIC_MUT2: f64 = 1.012345678901234567890;\n}\n\ntrait ExcessivelyPreciseTrait {\n    // Overly specified constants\n    const GOOD1: f32 = 1.012345678901234567890;\n    const GOOD2: f64 = 1.012345678901234567890;\n}\n\nstruct ExcessivelyPreciseStruct;\n\nimpl ExcessivelyPreciseStruct {\n    // Overly specified constants\n    const GOOD1: f32 = 1.012345678901234567890;\n    const GOOD2: f64 = 1.012345678901234567890;\n}\n"
  },
  {
    "path": "tests/ui-toml/excessive_precision/excessive_precision.rs",
    "content": "#![warn(clippy::excessive_precision)]\n#![allow(\n    dead_code,\n    overflowing_literals,\n    unused_variables,\n    clippy::print_literal,\n    clippy::useless_vec\n)]\n\nfn main() {\n    // Overly specified constants\n    let _: f32 = 1.012345678901234567890;\n    //~^ excessive_precision\n    let _: f64 = 1.012345678901234567890;\n    //~^ excessive_precision\n    const _: f32 = 1.012345678901234567890;\n    const _: f64 = 1.012345678901234567890;\n\n    static STATIC1: f32 = 1.012345678901234567890;\n    static STATIC2: f64 = 1.012345678901234567890;\n\n    static mut STATIC_MUT1: f32 = 1.012345678901234567890;\n    static mut STATIC_MUT2: f64 = 1.012345678901234567890;\n}\n\ntrait ExcessivelyPreciseTrait {\n    // Overly specified constants\n    const GOOD1: f32 = 1.012345678901234567890;\n    const GOOD2: f64 = 1.012345678901234567890;\n}\n\nstruct ExcessivelyPreciseStruct;\n\nimpl ExcessivelyPreciseStruct {\n    // Overly specified constants\n    const GOOD1: f32 = 1.012345678901234567890;\n    const GOOD2: f64 = 1.012345678901234567890;\n}\n"
  },
  {
    "path": "tests/ui-toml/excessive_precision/excessive_precision.stderr",
    "content": "error: float has excessive precision\n  --> tests/ui-toml/excessive_precision/excessive_precision.rs:12:18\n   |\nLL |     let _: f32 = 1.012345678901234567890;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider making it a `const` item\n  --> tests/ui-toml/excessive_precision/excessive_precision.rs:12:5\n   |\nLL |     let _: f32 = 1.012345678901234567890;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = note: `-D clippy::excessive-precision` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::excessive_precision)]`\nhelp: consider changing the type or truncating it to\n   |\nLL -     let _: f32 = 1.012345678901234567890;\nLL +     let _: f32 = 1.012_345_7;\n   |\n\nerror: float has excessive precision\n  --> tests/ui-toml/excessive_precision/excessive_precision.rs:14:18\n   |\nLL |     let _: f64 = 1.012345678901234567890;\n   |                  ^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: consider making it a `const` item\n  --> tests/ui-toml/excessive_precision/excessive_precision.rs:14:5\n   |\nLL |     let _: f64 = 1.012345678901234567890;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: consider changing the type or truncating it to\n   |\nLL -     let _: f64 = 1.012345678901234567890;\nLL +     let _: f64 = 1.012_345_678_901_234_6;\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/expect_used/clippy.toml",
    "content": "allow-expect-in-consts = false\nallow-expect-in-tests = true\n"
  },
  {
    "path": "tests/ui-toml/expect_used/expect_used.rs",
    "content": "//@compile-flags: --test\n#![warn(clippy::expect_used)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n\nfn expect_option() {\n    let opt = Some(0);\n    let _ = opt.expect(\"\");\n    //~^ expect_used\n}\n\nfn expect_result() {\n    let res: Result<u8, ()> = Ok(0);\n    let _ = res.expect(\"\");\n    //~^ expect_used\n}\n\nfn main() {\n    const SOME: Option<i32> = Some(3);\n    const UNWRAPPED: i32 = SOME.expect(\"Not three?\");\n    //~^ expect_used\n    const {\n        SOME.expect(\"Still not three?\");\n        //~^ expect_used\n    }\n}\n\n#[test]\nfn test_expect_option() {\n    let opt = Some(0);\n    let _ = opt.expect(\"\");\n}\n\n#[test]\nfn test_expect_result() {\n    let res: Result<u8, ()> = Ok(0);\n    let _ = res.expect(\"\");\n}\n\n#[cfg(test)]\nmod issue9612 {\n    // should not lint in `#[cfg(test)]` modules\n    #[test]\n    fn test_fn() {\n        let _a: u8 = 2.try_into().unwrap();\n        let _a: u8 = 3.try_into().expect(\"\");\n\n        util();\n    }\n\n    fn util() {\n        let _a: u8 = 4.try_into().unwrap();\n        let _a: u8 = 5.try_into().expect(\"\");\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/expect_used/expect_used.stderr",
    "content": "error: used `expect()` on an `Option` value\n  --> tests/ui-toml/expect_used/expect_used.rs:7:13\n   |\nLL |     let _ = opt.expect(\"\");\n   |             ^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = note: `-D clippy::expect-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::expect_used)]`\n\nerror: used `expect()` on a `Result` value\n  --> tests/ui-toml/expect_used/expect_used.rs:13:13\n   |\nLL |     let _ = res.expect(\"\");\n   |             ^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n\nerror: used `expect()` on an `Option` value\n  --> tests/ui-toml/expect_used/expect_used.rs:19:28\n   |\nLL |     const UNWRAPPED: i32 = SOME.expect(\"Not three?\");\n   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n\nerror: used `expect()` on an `Option` value\n  --> tests/ui-toml/expect_used/expect_used.rs:22:9\n   |\nLL |         SOME.expect(\"Still not three?\");\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/explicit_iter_loop/clippy.toml",
    "content": "enforce-iter-loop-reborrow = true\n"
  },
  {
    "path": "tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed",
    "content": "#![warn(clippy::explicit_iter_loop)]\n\nfn main() {\n    let mut vec = vec![1, 2, 3];\n    let rmvec = &mut vec;\n    for _ in &*rmvec {}\n    //~^ ERROR: it is more concise to loop over references to containers\n    for _ in &mut *rmvec {}\n    //~^ ERROR: it is more concise to loop over references to containers\n}\n"
  },
  {
    "path": "tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs",
    "content": "#![warn(clippy::explicit_iter_loop)]\n\nfn main() {\n    let mut vec = vec![1, 2, 3];\n    let rmvec = &mut vec;\n    for _ in rmvec.iter() {}\n    //~^ ERROR: it is more concise to loop over references to containers\n    for _ in rmvec.iter_mut() {}\n    //~^ ERROR: it is more concise to loop over references to containers\n}\n"
  },
  {
    "path": "tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr",
    "content": "error: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs:6:14\n   |\nLL |     for _ in rmvec.iter() {}\n   |              ^^^^^^^^^^^^ help: to write this more concisely, try: `&*rmvec`\n   |\n   = note: `-D clippy::explicit-iter-loop` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::explicit_iter_loop)]`\n\nerror: it is more concise to loop over references to containers instead of using explicit iteration methods\n  --> tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs:8:14\n   |\nLL |     for _ in rmvec.iter_mut() {}\n   |              ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *rmvec`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/extra_unused_type_parameters/clippy.toml",
    "content": "avoid-breaking-exported-api = true\n"
  },
  {
    "path": "tests/ui-toml/extra_unused_type_parameters/extra_unused_type_parameters.rs",
    "content": "//@check-pass\npub struct S;\n\nimpl S {\n    pub fn exported_fn<T>() {\n        unimplemented!();\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/fn_params_excessive_bools/clippy.toml",
    "content": "max-fn-params-bools = 1\n"
  },
  {
    "path": "tests/ui-toml/fn_params_excessive_bools/test.rs",
    "content": "#![warn(clippy::fn_params_excessive_bools)]\n\nfn f(_: bool) {}\nfn g(_: bool, _: bool) {}\n//~^ fn_params_excessive_bools\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/fn_params_excessive_bools/test.stderr",
    "content": "error: more than 1 bools in function parameters\n  --> tests/ui-toml/fn_params_excessive_bools/test.rs:4:1\n   |\nLL | fn g(_: bool, _: bool) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider refactoring bools into two-variant enums\n   = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::fn_params_excessive_bools)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/functions_maxlines/clippy.toml",
    "content": "too-many-lines-threshold = 1\n"
  },
  {
    "path": "tests/ui-toml/functions_maxlines/test.rs",
    "content": "#![warn(clippy::too_many_lines)]\n#![allow(clippy::let_unit_value)]\n\n// This function should be considered one line.\nfn many_comments_but_one_line_of_code() {\n    /* println!(\"This is good.\"); */\n    // println!(\"This is good.\");\n    /* */ // println!(\"This is good.\");\n    /* */ // println!(\"This is good.\");\n    /* */ // println!(\"This is good.\");\n    /* */ // println!(\"This is good.\");\n    /* println!(\"This is good.\");\n    println!(\"This is good.\");\n    println!(\"This is good.\"); */\n    println!(\"This is good.\");\n}\n\n// This should be considered two and a fail.\nfn too_many_lines() {\n    //~^ too_many_lines\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n}\n\n// This should only fail once (#7517).\nasync fn async_too_many_lines() {\n    //~^ too_many_lines\n    println!(\"This is bad.\");\n    println!(\"This is bad.\");\n}\n\n// This should fail only once, without failing on the closure.\nfn closure_too_many_lines() {\n    //~^ too_many_lines\n    let _ = {\n        println!(\"This is bad.\");\n        println!(\"This is bad.\");\n    };\n}\n\n// This should be considered one line.\n#[rustfmt::skip]\nfn comment_starts_after_code() {\n    let _ = 5; /* closing comment. */ /*\n    this line shouldn't be counted theoretically.\n    */\n}\n\n// This should be considered one line.\nfn comment_after_code() {\n    let _ = 5; /* this line should get counted once. */\n}\n\n// This should fail since it is technically two lines.\n#[rustfmt::skip]\nfn comment_before_code() {\n//~^ too_many_lines\n    let _ = \"test\";\n    /* This comment extends to the front of\n    the code but this line should still count. */ let _ = 5;\n}\n\n// This should be considered one line.\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/functions_maxlines/test.stderr",
    "content": "error: this function has too many lines (2/1)\n  --> tests/ui-toml/functions_maxlines/test.rs:19:1\n   |\nLL | fn too_many_lines() {\n   | ^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::too-many-lines` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::too_many_lines)]`\n\nerror: this function has too many lines (4/1)\n  --> tests/ui-toml/functions_maxlines/test.rs:26:1\n   |\nLL | async fn async_too_many_lines() {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this function has too many lines (4/1)\n  --> tests/ui-toml/functions_maxlines/test.rs:33:1\n   |\nLL | fn closure_too_many_lines() {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: this function has too many lines (2/1)\n  --> tests/ui-toml/functions_maxlines/test.rs:56:1\n   |\nLL | fn comment_before_code() {\n   | ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/good_toml_no_false_negatives/clippy.toml",
    "content": "# that one is white-listed\n[third-party]\nclippy-feature = \"nightly\"\n"
  },
  {
    "path": "tests/ui-toml/good_toml_no_false_negatives/conf_no_false_negatives.rs",
    "content": "//@check-pass\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/ifs_same_cond/clippy.toml",
    "content": "ignore-interior-mutability = [\"std::cell::Cell\"]\n"
  },
  {
    "path": "tests/ui-toml/ifs_same_cond/ifs_same_cond.rs",
    "content": "#![warn(clippy::ifs_same_cond)]\n#![allow(clippy::if_same_then_else, clippy::comparison_chain, clippy::needless_else)]\n\nfn main() {}\n\nfn issue10272() {\n    use std::cell::Cell;\n\n    // Because the `ignore-interior-mutability` configuration\n    // is set to ignore for `std::cell::Cell`, the following `get()` calls\n    // should trigger warning\n    let x = Cell::new(true);\n    if x.get() {\n        //~^ ifs_same_cond\n    } else if !x.take() {\n    } else if x.get() {\n    } else {\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr",
    "content": "error: these `if` branches have the same condition\n  --> tests/ui-toml/ifs_same_cond/ifs_same_cond.rs:13:8\n   |\nLL |     if x.get() {\n   |        ^^^^^^^\n...\nLL |     } else if x.get() {\n   |               ^^^^^^^\n   |\n   = note: `-D clippy::ifs-same-cond` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/impl_trait_in_params/clippy.toml",
    "content": "avoid-breaking-exported-api = false"
  },
  {
    "path": "tests/ui-toml/impl_trait_in_params/impl_trait_in_params.rs",
    "content": "//! As avoid-breaking-exported-api is `false`, nothing here should lint\n#![warn(clippy::impl_trait_in_params)]\n#![no_main]\n//@no-rustfix\n\npub trait Trait {}\n\ntrait Private {\n    fn t(_: impl Trait);\n    fn tt<T: Trait>(_: T);\n}\n\npub trait Public {\n    fn t(_: impl Trait); //~ ERROR: `impl Trait` used as a function parameter\n    fn tt<T: Trait>(_: T);\n}\n"
  },
  {
    "path": "tests/ui-toml/impl_trait_in_params/impl_trait_in_params.stderr",
    "content": "error: `impl Trait` used as a function parameter\n  --> tests/ui-toml/impl_trait_in_params/impl_trait_in_params.rs:14:13\n   |\nLL |     fn t(_: impl Trait);\n   |             ^^^^^^^^^^\n   |\n   = note: `-D clippy::impl-trait-in-params` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::impl_trait_in_params)]`\nhelp: add a type parameter\n   |\nLL |     fn t<{ /* Generic name */ }: Trait>(_: impl Trait);\n   |         +++++++++++++++++++++++++++++++\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/indexing_slicing/clippy.toml",
    "content": "allow-indexing-slicing-in-tests = true\n"
  },
  {
    "path": "tests/ui-toml/indexing_slicing/indexing_slicing.rs",
    "content": "//@compile-flags: --test\n#![warn(clippy::indexing_slicing)]\n#![allow(clippy::no_effect)]\n\nfn main() {\n    let x = [1, 2, 3, 4];\n    let index: usize = 1;\n    &x[index..];\n    //~^ indexing_slicing\n}\n\n#[cfg(test)]\nmod tests {\n    #[test]\n    fn test_fn() {\n        let x = [1, 2, 3, 4];\n        let index: usize = 1;\n        &x[index..];\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/indexing_slicing/indexing_slicing.stderr",
    "content": "error: slicing may panic\n  --> tests/ui-toml/indexing_slicing/indexing_slicing.rs:8:6\n   |\nLL |     &x[index..];\n   |      ^^^^^^^^^^\n   |\n   = help: consider using `.get(n..)` or .get_mut(n..)` instead\n   = note: `-D clippy::indexing-slicing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/invalid_min_rust_version/clippy.toml",
    "content": "msrv = \"invalid.version\"\n"
  },
  {
    "path": "tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.rs",
    "content": "//@error-in-other-file: not a valid Rust version\n\n#![allow(clippy::redundant_clone)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/invalid_min_rust_version/invalid_min_rust_version.stderr",
    "content": "error: error reading Clippy's configuration file: not a valid Rust version\n  --> $DIR/tests/ui-toml/invalid_min_rust_version/clippy.toml:1:8\n   |\nLL | msrv = \"invalid.version\"\n   |        ^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allow_exact_repetitions/clippy.toml",
    "content": "allow-exact-repetitions = false\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allow_exact_repetitions/item_name_repetitions.rs",
    "content": "#![warn(clippy::module_name_repetitions)]\n#![allow(dead_code)]\n\npub mod foo {\n    // this line should produce a warning:\n    pub fn foo() {}\n    //~^ module_name_repetitions\n\n    // but this line shouldn't\n    pub fn to_foo() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allow_exact_repetitions/item_name_repetitions.stderr",
    "content": "error: item name is the same as its containing module's name\n  --> tests/ui-toml/item_name_repetitions/allow_exact_repetitions/item_name_repetitions.rs:6:12\n   |\nLL |     pub fn foo() {}\n   |            ^^^\n   |\n   = note: `-D clippy::module-name-repetitions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allowed_prefixes/clippy.toml",
    "content": "allowed-prefixes = [\"bar\"]\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs",
    "content": "#![warn(clippy::module_name_repetitions)]\n#![allow(dead_code)]\n\npub mod foo {\n    // #12544 - shouldn't warn if item name consists only of an allowed prefix and a module name.\n    // In this test, allowed prefixes are configured to be [\"bar\"].\n\n    // this line should produce a warning:\n    pub fn to_foo() {}\n    //~^ module_name_repetitions\n\n    // but this line shouldn't\n    pub fn bar_foo() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.stderr",
    "content": "error: item name ends with its containing module's name\n  --> tests/ui-toml/item_name_repetitions/allowed_prefixes/item_name_repetitions.rs:9:12\n   |\nLL |     pub fn to_foo() {}\n   |            ^^^^^^\n   |\n   = note: `-D clippy::module-name-repetitions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/clippy.toml",
    "content": "allowed-prefixes = [\"..\", \"bar\"]\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs",
    "content": "#![warn(clippy::module_name_repetitions)]\n#![allow(dead_code)]\n\npub mod foo {\n    // #12544 - shouldn't warn if item name consists only of an allowed prefix and a module name.\n    // In this test, allowed prefixes are configured to be all of the default prefixes and [\"bar\"].\n\n    // this line should produce a warning:\n    pub fn something_foo() {}\n    //~^ module_name_repetitions\n\n    // but none of the following should:\n    pub fn bar_foo() {}\n    pub fn to_foo() {}\n    pub fn as_foo() {}\n    pub fn into_foo() {}\n    pub fn from_foo() {}\n    pub fn try_into_foo() {}\n    pub fn try_from_foo() {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.stderr",
    "content": "error: item name ends with its containing module's name\n  --> tests/ui-toml/item_name_repetitions/allowed_prefixes_extend/item_name_repetitions.rs:9:12\n   |\nLL |     pub fn something_foo() {}\n   |            ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::module-name-repetitions` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::module_name_repetitions)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/threshold0/clippy.toml",
    "content": "struct-field-name-threshold = 0\nenum-variant-name-threshold = 0\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/threshold0/item_name_repetitions.rs",
    "content": "//@check-pass\n\nstruct Data {}\n\nenum Actions {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/threshold5/clippy.toml",
    "content": "enum-variant-name-threshold = 5\nstruct-field-name-threshold = 5\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.rs",
    "content": "#![warn(clippy::struct_field_names)]\n\nstruct Data {\n    a_data: u8,\n    b_data: u8,\n    c_data: u8,\n    d_data: u8,\n}\nstruct Data2 {\n    //~^ ERROR: all fields have the same postfix\n    a_data: u8,\n    b_data: u8,\n    c_data: u8,\n    d_data: u8,\n    e_data: u8,\n}\nenum Foo {\n    AFoo,\n    BFoo,\n    CFoo,\n    DFoo,\n}\nenum Foo2 {\n    //~^ ERROR: all variants have the same postfix\n    AFoo,\n    BFoo,\n    CFoo,\n    DFoo,\n    EFoo,\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.stderr",
    "content": "error: all fields have the same postfix: `data`\n  --> tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.rs:9:1\n   |\nLL | / struct Data2 {\nLL | |\nLL | |     a_data: u8,\nLL | |     b_data: u8,\n...  |\nLL | |     e_data: u8,\nLL | | }\n   | |_^\n   |\n   = help: remove the postfixes\n   = note: `-D clippy::struct-field-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::struct_field_names)]`\n\nerror: all variants have the same postfix: `Foo`\n  --> tests/ui-toml/item_name_repetitions/threshold5/item_name_repetitions.rs:23:1\n   |\nLL | / enum Foo2 {\nLL | |\nLL | |     AFoo,\nLL | |     BFoo,\n...  |\nLL | |     EFoo,\nLL | | }\n   | |_^\n   |\n   = help: remove the postfixes and use full paths to the variants instead of glob imports\n   = note: `-D clippy::enum-variant-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/large_futures/clippy.toml",
    "content": "future-size-threshold = 1024\n"
  },
  {
    "path": "tests/ui-toml/large_futures/large_futures.fixed",
    "content": "#![warn(clippy::large_futures)]\n\nfn main() {}\n\npub async fn should_warn() {\n    let x = [0u8; 1024];\n    async {}.await;\n    dbg!(x);\n}\n\npub async fn should_not_warn() {\n    let x = [0u8; 1020];\n    async {}.await;\n    dbg!(x);\n}\n\npub async fn bar() {\n    Box::pin(should_warn()).await;\n    //~^ large_futures\n\n    async {\n        let x = [0u8; 1024];\n        dbg!(x);\n    }\n    .await;\n\n    should_not_warn().await;\n}\n"
  },
  {
    "path": "tests/ui-toml/large_futures/large_futures.rs",
    "content": "#![warn(clippy::large_futures)]\n\nfn main() {}\n\npub async fn should_warn() {\n    let x = [0u8; 1024];\n    async {}.await;\n    dbg!(x);\n}\n\npub async fn should_not_warn() {\n    let x = [0u8; 1020];\n    async {}.await;\n    dbg!(x);\n}\n\npub async fn bar() {\n    should_warn().await;\n    //~^ large_futures\n\n    async {\n        let x = [0u8; 1024];\n        dbg!(x);\n    }\n    .await;\n\n    should_not_warn().await;\n}\n"
  },
  {
    "path": "tests/ui-toml/large_futures/large_futures.stderr",
    "content": "error: large future with a size of 1026 bytes\n  --> tests/ui-toml/large_futures/large_futures.rs:18:5\n   |\nLL |     should_warn().await;\n   |     ^^^^^^^^^^^^^ help: consider `Box::pin` on it: `Box::pin(should_warn())`\n   |\n   = note: `-D clippy::large-futures` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_futures)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/large_include_file/clippy.toml",
    "content": "max-include-file-size = 600\n"
  },
  {
    "path": "tests/ui-toml/large_include_file/empty.txt",
    "content": ""
  },
  {
    "path": "tests/ui-toml/large_include_file/large_include_file.rs",
    "content": "#![warn(clippy::large_include_file)]\n#![allow(clippy::literal_string_with_formatting_args)]\n\n// Good\nconst GOOD_INCLUDE_BYTES: &[u8; 84] = include_bytes!(\"../../ui/author.rs\");\nconst GOOD_INCLUDE_STR: &str = include_str!(\"../../ui/author.rs\");\n\n#[allow(clippy::large_include_file)]\nconst ALLOWED_TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!(\"too_big.txt\");\n#[allow(clippy::large_include_file)]\nconst ALLOWED_TOO_BIG_INCLUDE_STR: &str = include_str!(\"too_big.txt\");\n\n// Bad\nconst TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!(\"too_big.txt\");\n//~^ large_include_file\nconst TOO_BIG_INCLUDE_STR: &str = include_str!(\"too_big.txt\");\n//~^ large_include_file\n\n#[doc = include_str!(\"too_big.txt\")]\n//~^ large_include_file\n// Should not lint!\n// Regression test for <https://github.com/rust-lang/rust-clippy/issues/13670>.\n#[doc = include_str!(\"empty.txt\")]\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/large_include_file/large_include_file.stderr",
    "content": "error: attempted to include a large file\n  --> tests/ui-toml/large_include_file/large_include_file.rs:19:1\n   |\nLL | #[doc = include_str!(\"too_big.txt\")]\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the configuration allows a maximum size of 600 bytes\n   = note: `-D clippy::large-include-file` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_include_file)]`\n\nerror: attempted to include a large file\n  --> tests/ui-toml/large_include_file/large_include_file.rs:14:43\n   |\nLL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!(\"too_big.txt\");\n   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the configuration allows a maximum size of 600 bytes\n\nerror: attempted to include a large file\n  --> tests/ui-toml/large_include_file/large_include_file.rs:16:35\n   |\nLL | const TOO_BIG_INCLUDE_STR: &str = include_str!(\"too_big.txt\");\n   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: the configuration allows a maximum size of 600 bytes\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/large_include_file/too_big.txt",
    "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Maecenas accumsan lacus vel facilisis volutpat. Etiam dignissim diam quis enim lobortis scelerisque fermentum dui faucibus. Tellus id interdum velit laoreet id donec ultrices. Est ultricies integer quis auctor elit sed vulputate. Erat velit scelerisque in dictum non consectetur a erat nam. Sed blandit libero volutpat sed. Tortor condimentum lacinia quis vel eros. Enim ut tellus elementum sagittis vitae et leo duis. Congue mauris rhoncus aenean vel elit scelerisque. Id consectetur purus ut faucibus pulvinar elementum integer."
  },
  {
    "path": "tests/ui-toml/large_stack_frames/clippy.toml",
    "content": "stack-size-threshold = 1000\n"
  },
  {
    "path": "tests/ui-toml/large_stack_frames/large_stack_frames.rs",
    "content": "#![warn(clippy::large_stack_frames)]\n\n// We use this helper function instead of writing [0; 4294967297] directly to represent a\n// case that large_stack_arrays can't catch\nfn create_array<const N: usize>() -> [u8; N] {\n    [0; N]\n}\n\nfn f() {\n    let _x = create_array::<1000>();\n}\nfn f2() {\n    //~^ ERROR: this function may allocate 1001 bytes on the stack\n    let _x = create_array::<1001>();\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/large_stack_frames/large_stack_frames.stderr",
    "content": "error: this function may allocate 1001 bytes on the stack\n  --> tests/ui-toml/large_stack_frames/large_stack_frames.rs:12:4\n   |\nLL | fn f2() {\n   |    ^^\nLL |\nLL |     let _x = create_array::<1001>();\n   |         -- `_x` is the largest part, at 1001 bytes for type `[u8; 1001]`\n   |\n   = note: 1001 bytes is larger than Clippy's configured `stack-size-threshold` of 1000\n   = note: allocating large amounts of stack space can overflow the stack and cause the program to abort\n   = note: `-D clippy::large-stack-frames` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/large_stack_frames_for_macros/clippy.toml",
    "content": "stack-size-threshold = 0\n"
  },
  {
    "path": "tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs",
    "content": "//@ignore-target: i686\n//@normalize-stderr-test: \"\\b10000(08|16|32)\\b\" -> \"100$$PTR\"\n//@normalize-stderr-test: \"\\b2500(060|120)\\b\" -> \"250$$PTR\"\n\n#![warn(clippy::large_stack_frames)]\n\nextern crate serde;\nuse serde::{Deserialize, Serialize};\n\nstruct ArrayDefault<const N: usize>([u8; N]);\n\nmacro_rules! mac {\n    ($name:ident) => {\n        fn foo() {\n            let $name = 1;\n            println!(\"macro_name called\");\n        }\n\n        fn bar() {\n            let $name = ArrayDefault([0; 1000]);\n        }\n    };\n}\n\nmac!(something);\n//~^ large_stack_frames\n//~| large_stack_frames\n\n#[derive(Deserialize, Serialize)]\n//~^ large_stack_frames\n//~| large_stack_frames\n//~| large_stack_frames\n//~| large_stack_frames\n//~| large_stack_frames\n//~| large_stack_frames\n//~| large_stack_frames\n//~| large_stack_frames\nstruct S {\n    a: [u128; 31],\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.stderr",
    "content": "error: function `foo` generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:25:1\n   |\nLL |         fn foo() {\n   |            --- this function has a stack frame size of 20 bytes\n...\nLL | mac!(something);\n   | ^^^^^^^^^^^^^^^\n   |\n   = note: 20 bytes is larger than Clippy's configured `stack-size-threshold` of 0\n   = note: allocating large amounts of stack space can overflow the stack and cause the program to abort\n   = note: `-D clippy::large-stack-frames` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`\n\nerror: function `bar` generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:25:1\n   |\nLL |         fn bar() {\n   |            --- this function has a stack frame size of 2000 bytes\nLL |             let $name = ArrayDefault([0; 1000]);\n   |                                      --------- this is the largest part, at 1000 bytes for type `[u8; 1000]`\n...\nLL | mac!(something);\n   | ^^^^^^^^^^^^^^^\n   |\n   = note: 2000 bytes is larger than Clippy's configured `stack-size-threshold` of 0\n\nerror: method generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10\n   |\nLL | #[derive(Deserialize, Serialize)]\n   |          ^^^^^^^^^^^\n\nerror: method generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10\n   |\nLL | #[derive(Deserialize, Serialize)]\n   |          ^^^^^^^^^^^\n   |\n   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n\nerror: method generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10\n   |\nLL | #[derive(Deserialize, Serialize)]\n   |          ^^^^^^^^^^^\n   |\n   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n\nerror: method generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10\n   |\nLL | #[derive(Deserialize, Serialize)]\n   |          ^^^^^^^^^^^\n   |\n   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n\nerror: method generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10\n   |\nLL | #[derive(Deserialize, Serialize)]\n   |          ^^^^^^^^^^^\n   |\n   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n\nerror: method generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10\n   |\nLL | #[derive(Deserialize, Serialize)]\n   |          ^^^^^^^^^^^\n   |\n   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n\nerror: method generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:10\n   |\nLL | #[derive(Deserialize, Serialize)]\n   |          ^^^^^^^^^^^\n   |\n   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`\n\nerror: method generated by this macro may allocate a lot of stack space\n  --> tests/ui-toml/large_stack_frames_for_macros/large_stack_frames.rs:29:23\n   |\nLL | #[derive(Deserialize, Serialize)]\n   |                       ^^^^^^^^^\n\nerror: aborting due to 10 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/large_stack_frames_for_special_targets/clippy.toml",
    "content": "stack-size-threshold = 0\nallow-large-stack-frames-in-tests = false\n"
  },
  {
    "path": "tests/ui-toml/large_stack_frames_for_special_targets/large_stack_frames.rs",
    "content": "// This test checks if `clippy::large_stack_frames` is working correctly when encountering functions\n// generated by special compiling targets like `--test`.\n//@compile-flags: --test\n//@check-pass\n\n#![warn(clippy::large_stack_frames)]\n\n#[cfg(test)]\n#[expect(clippy::large_stack_frames)]\nmod test {\n    #[test]\n    fn main_test() {}\n}\n"
  },
  {
    "path": "tests/ui-toml/large_types_passed_by_value/clippy.toml",
    "content": "pass-by-value-size-limit = 512\n"
  },
  {
    "path": "tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed",
    "content": "#![warn(clippy::large_types_passed_by_value)]\n\nfn f(_v: [u8; 512]) {}\nfn f2(_v: &[u8; 513]) {}\n//~^ ERROR: this argument (513 byte) is passed by value\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs",
    "content": "#![warn(clippy::large_types_passed_by_value)]\n\nfn f(_v: [u8; 512]) {}\nfn f2(_v: [u8; 513]) {}\n//~^ ERROR: this argument (513 byte) is passed by value\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr",
    "content": "error: this argument (513 byte) is passed by value, but might be more efficient if passed by reference (limit: 512 byte)\n  --> tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs:4:11\n   |\nLL | fn f2(_v: [u8; 513]) {}\n   |           ^^^^^^^^^ help: consider passing by reference instead: `&[u8; 513]`\n   |\n   = note: `-D clippy::large-types-passed-by-value` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::large_types_passed_by_value)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/lint_decimal_readability/clippy.toml",
    "content": "unreadable-literal-lint-fractions = false"
  },
  {
    "path": "tests/ui-toml/lint_decimal_readability/test.fixed",
    "content": "#![allow(clippy::excessive_precision)]\n#![warn(clippy::unreadable_literal)]\n\nfn allow_inconsistent_digit_grouping() {\n    #![allow(clippy::inconsistent_digit_grouping)]\n    let _pass1 = 100_200_300.123456789;\n}\n\nfn main() {\n    let _pass1 = 100_200_300.100_200_300;\n    let _pass2 = 1.123456789;\n    let _pass3 = 1.0;\n    let _pass4 = 10000.00001;\n    let _pass5 = 1.123456789e1;\n\n    // due to clippy::inconsistent-digit-grouping\n    let _fail1 = 100_200_300.123_456_789;\n    //~^ inconsistent_digit_grouping\n\n    // fail due to the integer part\n    let _fail2 = 100_200_300.300_200_100;\n    //~^ unreadable_literal\n}\n"
  },
  {
    "path": "tests/ui-toml/lint_decimal_readability/test.rs",
    "content": "#![allow(clippy::excessive_precision)]\n#![warn(clippy::unreadable_literal)]\n\nfn allow_inconsistent_digit_grouping() {\n    #![allow(clippy::inconsistent_digit_grouping)]\n    let _pass1 = 100_200_300.123456789;\n}\n\nfn main() {\n    let _pass1 = 100_200_300.100_200_300;\n    let _pass2 = 1.123456789;\n    let _pass3 = 1.0;\n    let _pass4 = 10000.00001;\n    let _pass5 = 1.123456789e1;\n\n    // due to clippy::inconsistent-digit-grouping\n    let _fail1 = 100_200_300.123456789;\n    //~^ inconsistent_digit_grouping\n\n    // fail due to the integer part\n    let _fail2 = 100200300.300200100;\n    //~^ unreadable_literal\n}\n"
  },
  {
    "path": "tests/ui-toml/lint_decimal_readability/test.stderr",
    "content": "error: digits grouped inconsistently by underscores\n  --> tests/ui-toml/lint_decimal_readability/test.rs:17:18\n   |\nLL |     let _fail1 = 100_200_300.123456789;\n   |                  ^^^^^^^^^^^^^^^^^^^^^ help: consider: `100_200_300.123_456_789`\n   |\n   = note: `-D clippy::inconsistent-digit-grouping` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]`\n\nerror: long literal lacking separators\n  --> tests/ui-toml/lint_decimal_readability/test.rs:21:18\n   |\nLL |     let _fail2 = 100200300.300200100;\n   |                  ^^^^^^^^^^^^^^^^^^^ help: consider: `100_200_300.300_200_100`\n   |\n   = note: `-D clippy::unreadable-literal` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unreadable_literal)]`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/macro_metavars_in_unsafe/default/test.rs",
    "content": "//! Tests macro_metavars_in_unsafe with default configuration\n#![feature(decl_macro)]\n#![warn(clippy::macro_metavars_in_unsafe)]\n#![allow(clippy::no_effect, clippy::not_unsafe_ptr_arg_deref)]\n\n#[macro_export]\nmacro_rules! allow_works {\n    ($v:expr) => {\n        #[expect(clippy::macro_metavars_in_unsafe)]\n        unsafe {\n            $v;\n        };\n    };\n}\n\n#[macro_export]\nmacro_rules! simple {\n    ($v:expr) => {\n        unsafe {\n            //~^ macro_metavars_in_unsafe\n            dbg!($v);\n        }\n    };\n}\n\n#[macro_export]\n#[rustfmt::skip] // for some reason rustfmt rewrites $r#unsafe to r#u$nsafe, bug?\nmacro_rules! raw_symbol {\n    ($r#mod:expr, $r#unsafe:expr) => {\n        unsafe {\n        //~^ macro_metavars_in_unsafe\n            $r#mod;\n        }\n        $r#unsafe;\n    };\n}\n\n#[macro_export]\nmacro_rules! multilevel_unsafe {\n    ($v:expr) => {\n        unsafe {\n            unsafe {\n                //~^ macro_metavars_in_unsafe\n                $v;\n            }\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! in_function {\n    ($v:expr) => {\n        unsafe {\n            fn f() {\n                // function introduces a new body, so don't lint.\n                $v;\n            }\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! in_function_with_unsafe {\n    ($v:expr) => {\n        unsafe {\n            fn f() {\n                unsafe {\n                    //~^ macro_metavars_in_unsafe\n                    $v;\n                }\n            }\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! const_static {\n    ($c:expr, $s:expr) => {\n        unsafe {\n            // const and static introduces new body, don't lint\n            const _X: i32 = $c;\n            static _Y: i32 = $s;\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! const_generic_in_struct {\n    ($inside_unsafe:expr, $outside_unsafe:expr) => {\n        unsafe {\n            struct Ty<\n                const L: i32 = 1,\n                const M: i32 = {\n                    1;\n                    unsafe { $inside_unsafe }\n                    //~^ macro_metavars_in_unsafe\n                },\n                const N: i32 = { $outside_unsafe },\n            >;\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! fn_with_const_generic {\n    ($inside_unsafe:expr, $outside_unsafe:expr) => {\n        unsafe {\n            fn f<const N: usize>() {\n                $outside_unsafe;\n                unsafe {\n                    //~^ macro_metavars_in_unsafe\n                    $inside_unsafe;\n                }\n            }\n        }\n    };\n}\n\n#[macro_export]\nmacro_rules! variables {\n    ($inside_unsafe:expr, $outside_unsafe:expr) => {\n        unsafe {\n            //~^ macro_metavars_in_unsafe\n            $inside_unsafe;\n            let inside_unsafe = 1;\n            inside_unsafe;\n        }\n        $outside_unsafe;\n        let outside_unsafe = 1;\n        outside_unsafe;\n    };\n}\n\n#[macro_export]\nmacro_rules! multiple_matchers {\n    ($inside_unsafe:expr, $outside_unsafe:expr) => {\n        unsafe {\n        //~^ macro_metavars_in_unsafe\n            $inside_unsafe;\n        }\n        $outside_unsafe;\n    };\n    ($($v:expr, $x:expr),+) => {\n        $(\n            $v;\n            unsafe {\n            //~^ macro_metavars_in_unsafe\n                $x;\n            }\n        );+\n    };\n}\n\n#[macro_export]\nmacro_rules! multiple_unsafe_blocks {\n    ($w:expr, $x:expr, $y:expr) => {\n        $w;\n        unsafe {\n            //~^ macro_metavars_in_unsafe\n            $x;\n        }\n        unsafe {\n            //~^ macro_metavars_in_unsafe\n            $x;\n            $y;\n        }\n    };\n}\n\npub macro macro2_0($v:expr) {\n    unsafe {\n        //~^ macro_metavars_in_unsafe\n        $v;\n    }\n}\n\n// don't lint private macros with the default configuration\nmacro_rules! private_mac {\n    ($v:expr) => {\n        unsafe {\n            $v;\n        }\n    };\n}\n\n// don't lint exported macros that are doc(hidden) because they also aren't part of the public API\n#[macro_export]\n#[doc(hidden)]\nmacro_rules! exported_but_hidden {\n    ($v:expr) => {\n        unsafe {\n            $v;\n        }\n    };\n}\n\n// don't lint if the same metavariable is expanded in an unsafe block and then outside of one:\n// unsafe {} is still needed at callsite so not problematic\n#[macro_export]\nmacro_rules! does_require_unsafe {\n    ($v:expr) => {\n        unsafe {\n            $v;\n        }\n        $v;\n    };\n}\n\n#[macro_export]\nmacro_rules! unsafe_from_root_ctxt {\n    ($v:expr) => {\n        // Expands to unsafe { 1 }, but the unsafe block is from the root ctxt and not this macro,\n        // so no warning.\n        $v;\n    };\n}\n\n// invoked from another macro, should still generate a warning\n#[macro_export]\nmacro_rules! nested_macro_helper {\n    ($v:expr) => {{\n        unsafe {\n            //~^ macro_metavars_in_unsafe\n            $v;\n        }\n    }};\n}\n\n#[macro_export]\nmacro_rules! nested_macros {\n    ($v:expr, $v2:expr) => {{\n        unsafe {\n            //~^ macro_metavars_in_unsafe\n            nested_macro_helper!($v);\n            $v;\n        }\n    }};\n}\n\npub mod issue13219 {\n    #[macro_export]\n    macro_rules! m {\n        ($e:expr) => {\n            // Metavariable in a block tail expression\n            unsafe { $e }\n            //~^ macro_metavars_in_unsafe\n        };\n    }\n    pub fn f(p: *const i32) -> i32 {\n        m!(*p)\n    }\n}\n\n#[macro_export]\nmacro_rules! issue14488 {\n    ($e:expr) => {\n        #[expect(clippy::macro_metavars_in_unsafe)]\n        unsafe {\n            $e\n        }\n    };\n}\n\nfn main() {\n    allow_works!(1);\n    simple!(1);\n    raw_symbol!(1, 1);\n    multilevel_unsafe!(1);\n    in_function!(1);\n    in_function_with_unsafe!(1);\n    const_static!(1, 1);\n    const_generic_in_struct!(1, 1);\n    fn_with_const_generic!(1, 1);\n    variables!(1, 1);\n    multiple_matchers!(1, 1);\n    multiple_matchers!(1, 1, 1, 1);\n    macro2_0!(1);\n    private_mac!(1);\n    exported_but_hidden!(1);\n    does_require_unsafe!(1);\n    multiple_unsafe_blocks!(1, 1, 1);\n    unsafe_from_root_ctxt!(unsafe { 1 });\n    nested_macros!(1, 1);\n\n    // These two invocations lead to two expanded unsafe blocks, each with an `#[expect]` on it.\n    // Only of them gets a warning, which used to result in an unfulfilled expectation for the other\n    // expanded unsafe block.\n    issue14488!(1);\n    issue14488!(2);\n}\n"
  },
  {
    "path": "tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr",
    "content": "error: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:245:13\n   |\nLL |             unsafe { $e }\n   |             ^^^^^^^^^^^^^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n   = note: `-D clippy::macro-metavars-in-unsafe` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::macro_metavars_in_unsafe)]`\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:19:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             dbg!($v);\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:30:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             $r#mod;\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:42:13\n   |\nLL | /             unsafe {\nLL | |\nLL | |                 $v;\nLL | |             }\n   | |_____________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:67:17\n   |\nLL | /                 unsafe {\nLL | |\nLL | |                     $v;\nLL | |                 }\n   | |_________________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:95:21\n   |\nLL |                     unsafe { $inside_unsafe }\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:110:17\n   |\nLL | /                 unsafe {\nLL | |\nLL | |                     $inside_unsafe;\nLL | |                 }\n   | |_________________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:122:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             $inside_unsafe;\nLL | |             let inside_unsafe = 1;\nLL | |             inside_unsafe;\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:137:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             $inside_unsafe;\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:146:13\n   |\nLL | /             unsafe {\nLL | |\nLL | |                 $x;\nLL | |             }\n   | |_____________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:171:5\n   |\nLL | /     unsafe {\nLL | |\nLL | |         $v;\nLL | |     }\n   | |_____^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:158:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             $x;\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:162:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             $x;\nLL | |             $y;\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:222:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             $v;\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:232:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             nested_macro_helper!($v);\nLL | |             $v;\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n\nerror: aborting due to 15 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/macro_metavars_in_unsafe/private/clippy.toml",
    "content": "warn-unsafe-macro-metavars-in-private-macros = true\n"
  },
  {
    "path": "tests/ui-toml/macro_metavars_in_unsafe/private/test.rs",
    "content": "//! Tests macro_metavars_in_unsafe with private (non-exported) macros\n#![warn(clippy::macro_metavars_in_unsafe)]\n\nmacro_rules! mac {\n    ($v:expr) => {\n        unsafe {\n            //~^ ERROR: this macro expands metavariables in an unsafe block\n            dbg!($v);\n        }\n    };\n}\n\nfn main() {\n    mac!(1);\n}\n"
  },
  {
    "path": "tests/ui-toml/macro_metavars_in_unsafe/private/test.stderr",
    "content": "error: this macro expands metavariables in an unsafe block\n  --> tests/ui-toml/macro_metavars_in_unsafe/private/test.rs:6:9\n   |\nLL | /         unsafe {\nLL | |\nLL | |             dbg!($v);\nLL | |         }\n   | |_________^\n   |\n   = note: this allows the user of the macro to write unsafe code outside of an unsafe block\n   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable\n   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite\n   = note: `-D clippy::macro-metavars-in-unsafe` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::macro_metavars_in_unsafe)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/manual_let_else/clippy.toml",
    "content": "matches-for-let-else = \"AllTypes\"\n"
  },
  {
    "path": "tests/ui-toml/manual_let_else/manual_let_else.fixed",
    "content": "#![warn(clippy::manual_let_else)]\n\nenum Foo {\n    A(u8),\n    B,\n}\n\nfn main() {\n    let Foo::A(x) = Foo::A(1) else { return };\n}\n"
  },
  {
    "path": "tests/ui-toml/manual_let_else/manual_let_else.rs",
    "content": "#![warn(clippy::manual_let_else)]\n\nenum Foo {\n    A(u8),\n    B,\n}\n\nfn main() {\n    let x = match Foo::A(1) {\n        //~^ ERROR: this could be rewritten as `let...else`\n        Foo::A(x) => x,\n        Foo::B => return,\n    };\n}\n"
  },
  {
    "path": "tests/ui-toml/manual_let_else/manual_let_else.stderr",
    "content": "error: this could be rewritten as `let...else`\n  --> tests/ui-toml/manual_let_else/manual_let_else.rs:9:5\n   |\nLL | /     let x = match Foo::A(1) {\nLL | |\nLL | |         Foo::A(x) => x,\nLL | |         Foo::B => return,\nLL | |     };\n   | |______^ help: consider writing: `let Foo::A(x) = Foo::A(1) else { return };`\n   |\n   = note: `-D clippy::manual-let-else` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/max_suggested_slice_pattern_length/clippy.toml",
    "content": "max-suggested-slice-pattern-length = 8\n"
  },
  {
    "path": "tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed",
    "content": "#![deny(clippy::index_refutable_slice)]\n\nfn below_limit() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {\n        //~^ ERROR: binding can be a slice pattern\n        // This would usually not be linted but is included now due to the\n        // index limit in the config file\n        println!(\"{}\", slice_7);\n    }\n}\n\nfn above_limit() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        // This will not be linted as 8 is above the limit\n        println!(\"{}\", slice[8]);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs",
    "content": "#![deny(clippy::index_refutable_slice)]\n\nfn below_limit() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        //~^ ERROR: binding can be a slice pattern\n        // This would usually not be linted but is included now due to the\n        // index limit in the config file\n        println!(\"{}\", slice[7]);\n    }\n}\n\nfn above_limit() {\n    let slice: Option<&[u32]> = Some(&[1, 2, 3]);\n    if let Some(slice) = slice {\n        // This will not be linted as 8 is above the limit\n        println!(\"{}\", slice[8]);\n    }\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.stderr",
    "content": "error: this binding can be a slice pattern to avoid indexing\n  --> tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs:5:17\n   |\nLL |     if let Some(slice) = slice {\n   |                 ^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs:1:9\n   |\nLL | #![deny(clippy::index_refutable_slice)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nhelp: replace the binding and indexed access with a slice pattern\n   |\nLL ~     if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {\nLL |\nLL |         // This would usually not be linted but is included now due to the\nLL |         // index limit in the config file\nLL ~         println!(\"{}\", slice_7);\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/min_ident_chars/auxiliary/extern_types.rs",
    "content": "#![allow(nonstandard_style, unused)]\n\npub struct Aaa;\npub struct Bbb;\n\npub const N: u32 = 3;\n\npub const M: u32 = 2;\npub const LONGER: u32 = 32;\n"
  },
  {
    "path": "tests/ui-toml/min_ident_chars/clippy.toml",
    "content": "allowed-idents-below-min-chars = [\"Owo\", \"Uwu\", \"wha\", \"t_e\", \"lse\", \"_do\", \"_i_\", \"put\", \"her\", \"_e\"]\nmin-ident-chars-threshold = 3\n"
  },
  {
    "path": "tests/ui-toml/min_ident_chars/min_ident_chars.rs",
    "content": "//@aux-build:extern_types.rs\n#![allow(nonstandard_style, unused)]\n#![warn(clippy::min_ident_chars)]\n\nextern crate extern_types;\nuse extern_types::{Aaa, LONGER, M, N as W};\n//~^ min_ident_chars\n\npub const N: u32 = 0;\n//~^ min_ident_chars\npub const LONG: u32 = 32;\n\nstruct Owo {\n    Uwu: u128,\n    aaa: Aaa,\n    //~^ min_ident_chars\n}\n\nfn main() {\n    let wha = 1;\n    let vvv = 1;\n    //~^ min_ident_chars\n    let uuu = 1;\n    //~^ min_ident_chars\n    let (mut a, mut b) = (1, 2);\n    //~^ min_ident_chars\n    //~| min_ident_chars\n    for i in 0..1000 {}\n    //~^ min_ident_chars\n}\n"
  },
  {
    "path": "tests/ui-toml/min_ident_chars/min_ident_chars.stderr",
    "content": "error: this ident is too short (1 <= 3)\n  --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:6:41\n   |\nLL | use extern_types::{Aaa, LONGER, M, N as W};\n   |                                         ^\n   |\n   = note: `-D clippy::min-ident-chars` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::min_ident_chars)]`\n\nerror: this ident is too short (1 <= 3)\n  --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:9:11\n   |\nLL | pub const N: u32 = 0;\n   |           ^\n\nerror: this ident is too short (3 <= 3)\n  --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:15:5\n   |\nLL |     aaa: Aaa,\n   |     ^^^\n\nerror: this ident is too short (3 <= 3)\n  --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:21:9\n   |\nLL |     let vvv = 1;\n   |         ^^^\n\nerror: this ident is too short (3 <= 3)\n  --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:23:9\n   |\nLL |     let uuu = 1;\n   |         ^^^\n\nerror: this ident is too short (1 <= 3)\n  --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:25:14\n   |\nLL |     let (mut a, mut b) = (1, 2);\n   |              ^\n\nerror: this ident is too short (1 <= 3)\n  --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:25:21\n   |\nLL |     let (mut a, mut b) = (1, 2);\n   |                     ^\n\nerror: this ident is too short (1 <= 3)\n  --> tests/ui-toml/min_ident_chars/min_ident_chars.rs:28:9\n   |\nLL |     for i in 0..1000 {}\n   |         ^\n\nerror: aborting due to 8 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/min_rust_version/clippy.toml",
    "content": "msrv = \"1.0.0\"\n"
  },
  {
    "path": "tests/ui-toml/min_rust_version/min_rust_version.fixed",
    "content": "#![allow(clippy::redundant_clone, clippy::unnecessary_operation, clippy::incompatible_msrv)]\n#![warn(clippy::manual_non_exhaustive, clippy::borrow_as_ptr, clippy::manual_bits)]\n\nuse std::mem::{size_of, size_of_val};\nuse std::ops::Deref;\n\nmod enums {\n    enum E {\n        A,\n        B,\n        #[doc(hidden)]\n        _C,\n    }\n\n    // user forgot to remove the marker\n    #[non_exhaustive]\n    enum Ep {\n        A,\n        B,\n        #[doc(hidden)]\n        _C,\n    }\n}\n\nfn option_as_ref_deref() {\n    let mut opt = Some(String::from(\"123\"));\n\n    let _ = opt.as_ref().map(String::as_str);\n    let _ = opt.as_ref().map(|x| x.as_str());\n    let _ = opt.as_mut().map(String::as_mut_str);\n    let _ = opt.as_mut().map(|x| x.as_mut_str());\n}\n\nfn match_like_matches() {\n    let _y = match Some(5) {\n        Some(0) => true,\n        _ => false,\n    };\n}\n\nfn match_same_arms() {\n    match (1, 2, 3) {\n        (1, .., 3) => 42,\n        (.., 3) => 42,\n        _ => 0,\n    };\n}\n\nfn match_same_arms2() {\n    let _ = match Some(42) {\n        Some(_) => 24,\n        None => 24,\n    };\n}\n\nfn manual_strip_msrv() {\n    let s = \"hello, world!\";\n    if s.starts_with(\"hello, \") {\n        assert_eq!(s[\"hello, \".len()..].to_uppercase(), \"WORLD!\");\n    }\n}\n\nfn check_index_refutable_slice() {\n    // This shouldn't trigger `clippy::index_refutable_slice` as the suggestion\n    // would only be valid from 1.42.0 onward\n    let slice: Option<&[u32]> = Some(&[1]);\n    if let Some(slice) = slice {\n        println!(\"{}\", slice[0]);\n    }\n}\n\nfn map_clone_suggest_copied() {\n    // This should still trigger the lint but suggest `cloned()` instead of `copied()`\n    let _: Option<u64> = Some(&16).cloned();\n    //~^ map_clone\n}\n\nfn borrow_as_ptr() {\n    let val = 1;\n    let _p = &val as *const i32;\n\n    let mut val_mut = 1;\n    let _p_mut = &mut val_mut as *mut i32;\n}\n\nfn manual_bits() {\n    size_of::<i8>() * 8;\n    size_of_val(&0u32) * 8;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/min_rust_version/min_rust_version.rs",
    "content": "#![allow(clippy::redundant_clone, clippy::unnecessary_operation, clippy::incompatible_msrv)]\n#![warn(clippy::manual_non_exhaustive, clippy::borrow_as_ptr, clippy::manual_bits)]\n\nuse std::mem::{size_of, size_of_val};\nuse std::ops::Deref;\n\nmod enums {\n    enum E {\n        A,\n        B,\n        #[doc(hidden)]\n        _C,\n    }\n\n    // user forgot to remove the marker\n    #[non_exhaustive]\n    enum Ep {\n        A,\n        B,\n        #[doc(hidden)]\n        _C,\n    }\n}\n\nfn option_as_ref_deref() {\n    let mut opt = Some(String::from(\"123\"));\n\n    let _ = opt.as_ref().map(String::as_str);\n    let _ = opt.as_ref().map(|x| x.as_str());\n    let _ = opt.as_mut().map(String::as_mut_str);\n    let _ = opt.as_mut().map(|x| x.as_mut_str());\n}\n\nfn match_like_matches() {\n    let _y = match Some(5) {\n        Some(0) => true,\n        _ => false,\n    };\n}\n\nfn match_same_arms() {\n    match (1, 2, 3) {\n        (1, .., 3) => 42,\n        (.., 3) => 42,\n        _ => 0,\n    };\n}\n\nfn match_same_arms2() {\n    let _ = match Some(42) {\n        Some(_) => 24,\n        None => 24,\n    };\n}\n\nfn manual_strip_msrv() {\n    let s = \"hello, world!\";\n    if s.starts_with(\"hello, \") {\n        assert_eq!(s[\"hello, \".len()..].to_uppercase(), \"WORLD!\");\n    }\n}\n\nfn check_index_refutable_slice() {\n    // This shouldn't trigger `clippy::index_refutable_slice` as the suggestion\n    // would only be valid from 1.42.0 onward\n    let slice: Option<&[u32]> = Some(&[1]);\n    if let Some(slice) = slice {\n        println!(\"{}\", slice[0]);\n    }\n}\n\nfn map_clone_suggest_copied() {\n    // This should still trigger the lint but suggest `cloned()` instead of `copied()`\n    let _: Option<u64> = Some(&16).map(|b| *b);\n    //~^ map_clone\n}\n\nfn borrow_as_ptr() {\n    let val = 1;\n    let _p = &val as *const i32;\n\n    let mut val_mut = 1;\n    let _p_mut = &mut val_mut as *mut i32;\n}\n\nfn manual_bits() {\n    size_of::<i8>() * 8;\n    size_of_val(&0u32) * 8;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/min_rust_version/min_rust_version.stderr",
    "content": "error: you are using an explicit closure for cloning elements\n  --> tests/ui-toml/min_rust_version/min_rust_version.rs:74:26\n   |\nLL |     let _: Option<u64> = Some(&16).map(|b| *b);\n   |                          ^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `Some(&16).cloned()`\n   |\n   = note: `-D clippy::map-clone` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::map_clone)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/missing_docs_in_private_items/allow_unused/clippy.toml",
    "content": "missing-docs-allow-unused = true\n"
  },
  {
    "path": "tests/ui-toml/missing_docs_in_private_items/crate_root/clippy.toml",
    "content": "missing-docs-in-crate-items = true\n"
  },
  {
    "path": "tests/ui-toml/missing_docs_in_private_items/default/clippy.toml",
    "content": ""
  },
  {
    "path": "tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.allow_unused.stderr",
    "content": "error: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:26:5\n   |\nLL |     f3: u32,\n   |     ^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:8:9\n   |\nLL | #![deny(clippy::missing_docs_in_private_items)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:60:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:77:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:78:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:117:4\n   |\nLL | fn fn_crate() {}\n   |    ^^^^^^^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:118:7\n   |\nLL | const CONST_CRATE: u32 = 0;\n   |       ^^^^^^^^^^^\n\nerror: missing documentation for a static\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:119:8\n   |\nLL | static STATIC_CRATE: u32 = 0;\n   |        ^^^^^^^^^^^^\n\nerror: missing documentation for a type alias\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:120:6\n   |\nLL | type TyAliasCrate = u32;\n   |      ^^^^^^^^^^^^\n\nerror: missing documentation for a trait alias\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:121:7\n   |\nLL | trait TraitAliasCrate = Iterator;\n   |       ^^^^^^^^^^^^^^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:122:8\n   |\nLL | struct StructCrate;\n   |        ^^^^^^^^^^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:124:8\n   |\nLL | struct StructFieldCrate {\n   |        ^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:125:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:128:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:138:8\n   |\nLL | struct StructTupleCrate(u32, pub u32);\n   |        ^^^^^^^^^^^^^^^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:140:6\n   |\nLL | enum EnumCrate {\n   |      ^^^^^^^^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:141:5\n   |\nLL |     V1,\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:142:5\n   |\nLL |     V2(u32),\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:144:5\n   |\nLL |     V3 {\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:145:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:155:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a union\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:161:7\n   |\nLL | union UnionCrate {\n   |       ^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:162:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:165:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:176:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:177:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:182:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:183:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a trait\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:190:7\n   |\nLL | trait TraitCrate {\n   |       ^^^^^^^^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:191:8\n   |\nLL |     fn f1();\n   |        ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:192:8\n   |\nLL |     fn f2() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:193:11\n   |\nLL |     const C1: u32;\n   |           ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:194:11\n   |\nLL |     const C2: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated type\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:195:10\n   |\nLL |     type T1;\n   |          ^^\n\nerror: missing documentation for a macro\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:216:14\n   |\nLL | macro_rules! mac_rules_crate {\n   |              ^^^^^^^^^^^^^^^\n\nerror: missing documentation for a macro\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:220:7\n   |\nLL | macro mac_crate {\n   |       ^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:238:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:241:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:255:5\n   |\nLL |     V1,\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:256:5\n   |\nLL |     V2(u32),\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:258:5\n   |\nLL |     V3 {\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:259:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:269:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:276:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:279:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:290:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:291:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:296:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:297:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:305:8\n   |\nLL |     fn f1();\n   |        ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:306:8\n   |\nLL |     fn f2() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:307:11\n   |\nLL |     const C1: u32;\n   |           ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:308:11\n   |\nLL |     const C2: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated type\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:309:10\n   |\nLL |     type T1;\n   |          ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:541:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:567:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:588:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:591:12\n   |\nLL |     struct S3 {\n   |            ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:592:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:595:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:600:10\n   |\nLL |     enum E3 {\n   |          ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:602:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:603:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:609:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:614:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:620:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:623:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:630:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:631:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:637:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a module\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:647:5\n   |\nLL | mod mod_crate {\n   |     ^^^^^^^^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:648:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:651:16\n   |\nLL |     pub struct S1 {\n   |                ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:652:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:655:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:660:14\n   |\nLL |     pub enum E1 {\n   |              ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:662:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:663:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:669:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:674:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:680:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:683:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:690:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:691:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:697:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:705:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:708:12\n   |\nLL |     struct S3 {\n   |            ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:709:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:712:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:717:10\n   |\nLL |     enum E3 {\n   |          ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:719:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:720:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:726:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:731:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:737:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:740:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:747:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:748:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:754:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1061:9\n   |\nLL |         f2: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1062:20\n   |\nLL |         pub(crate) f3: u32,\n   |                    ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1069:23\n   |\nLL |         pub(crate) fn f2() {}\n   |                       ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1072:18\n   |\nLL |         pub enum E1 {\n   |                  ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1074:13\n   |\nLL |             V2,\n   |             ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1077:20\n   |\nLL |         pub struct S2;\n   |                    ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1096:18\n   |\nLL |         $(pub fn f2() {})\n   |                  ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1165:20\n   |\nLL |         pub struct VisFromOutside;\n   |                    ^^^^^^^^^^^^^^\n\nerror: aborting due to 106 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.crate_root.stderr",
    "content": "error: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:26:5\n   |\nLL |     f3: u32,\n   |     ^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:8:9\n   |\nLL | #![deny(clippy::missing_docs_in_private_items)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:32:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:60:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:66:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:77:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:78:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:117:4\n   |\nLL | fn fn_crate() {}\n   |    ^^^^^^^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:118:7\n   |\nLL | const CONST_CRATE: u32 = 0;\n   |       ^^^^^^^^^^^\n\nerror: missing documentation for a static\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:119:8\n   |\nLL | static STATIC_CRATE: u32 = 0;\n   |        ^^^^^^^^^^^^\n\nerror: missing documentation for a type alias\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:120:6\n   |\nLL | type TyAliasCrate = u32;\n   |      ^^^^^^^^^^^^\n\nerror: missing documentation for a trait alias\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:121:7\n   |\nLL | trait TraitAliasCrate = Iterator;\n   |       ^^^^^^^^^^^^^^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:122:8\n   |\nLL | struct StructCrate;\n   |        ^^^^^^^^^^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:124:8\n   |\nLL | struct StructFieldCrate {\n   |        ^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:125:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:128:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:131:9\n   |\nLL |     pub _f5: u32,\n   |         ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:134:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:138:8\n   |\nLL | struct StructTupleCrate(u32, pub u32);\n   |        ^^^^^^^^^^^^^^^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:140:6\n   |\nLL | enum EnumCrate {\n   |      ^^^^^^^^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:141:5\n   |\nLL |     V1,\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:142:5\n   |\nLL |     V2(u32),\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:144:5\n   |\nLL |     V3 {\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:145:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:155:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a union\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:161:7\n   |\nLL | union UnionCrate {\n   |       ^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:162:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:165:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:168:9\n   |\nLL |     pub _f5: u32,\n   |         ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:171:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:176:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:177:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:182:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:183:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a trait\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:190:7\n   |\nLL | trait TraitCrate {\n   |       ^^^^^^^^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:191:8\n   |\nLL |     fn f1();\n   |        ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:192:8\n   |\nLL |     fn f2() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:193:11\n   |\nLL |     const C1: u32;\n   |           ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:194:11\n   |\nLL |     const C2: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated type\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:195:10\n   |\nLL |     type T1;\n   |          ^^\n\nerror: missing documentation for a macro\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:216:14\n   |\nLL | macro_rules! mac_rules_crate {\n   |              ^^^^^^^^^^^^^^^\n\nerror: missing documentation for a macro\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:220:7\n   |\nLL | macro mac_crate {\n   |       ^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:238:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:241:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:244:9\n   |\nLL |     pub _f5: u32,\n   |         ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:247:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:255:5\n   |\nLL |     V1,\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:256:5\n   |\nLL |     V2(u32),\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:258:5\n   |\nLL |     V3 {\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:259:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:269:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:276:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:279:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:282:9\n   |\nLL |     pub _f5: u32,\n   |         ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:285:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:290:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:291:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:296:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:297:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:305:8\n   |\nLL |     fn f1();\n   |        ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:306:8\n   |\nLL |     fn f2() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:307:11\n   |\nLL |     const C1: u32;\n   |           ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:308:11\n   |\nLL |     const C2: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated type\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:309:10\n   |\nLL |     type T1;\n   |          ^^\n\nerror: missing documentation for a module\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:647:5\n   |\nLL | mod mod_crate {\n   |     ^^^^^^^^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:648:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:651:16\n   |\nLL |     pub struct S1 {\n   |                ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:652:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:660:14\n   |\nLL |     pub enum E1 {\n   |              ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:662:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:663:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:669:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:674:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:680:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:690:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:691:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:697:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1062:20\n   |\nLL |         pub(crate) f3: u32,\n   |                    ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1072:18\n   |\nLL |         pub enum E1 {\n   |                  ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1074:13\n   |\nLL |             V2,\n   |             ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1077:20\n   |\nLL |         pub struct S2;\n   |                    ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1096:18\n   |\nLL |         $(pub fn f2() {})\n   |                  ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1165:20\n   |\nLL |         pub struct VisFromOutside;\n   |                    ^^^^^^^^^^^^^^\n\nerror: aborting due to 82 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.default.stderr",
    "content": "error: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:26:5\n   |\nLL |     f3: u32,\n   |     ^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:8:9\n   |\nLL | #![deny(clippy::missing_docs_in_private_items)]\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:32:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:60:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:66:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:77:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:78:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:117:4\n   |\nLL | fn fn_crate() {}\n   |    ^^^^^^^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:118:7\n   |\nLL | const CONST_CRATE: u32 = 0;\n   |       ^^^^^^^^^^^\n\nerror: missing documentation for a static\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:119:8\n   |\nLL | static STATIC_CRATE: u32 = 0;\n   |        ^^^^^^^^^^^^\n\nerror: missing documentation for a type alias\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:120:6\n   |\nLL | type TyAliasCrate = u32;\n   |      ^^^^^^^^^^^^\n\nerror: missing documentation for a trait alias\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:121:7\n   |\nLL | trait TraitAliasCrate = Iterator;\n   |       ^^^^^^^^^^^^^^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:122:8\n   |\nLL | struct StructCrate;\n   |        ^^^^^^^^^^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:124:8\n   |\nLL | struct StructFieldCrate {\n   |        ^^^^^^^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:125:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:128:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:131:9\n   |\nLL |     pub _f5: u32,\n   |         ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:134:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:138:8\n   |\nLL | struct StructTupleCrate(u32, pub u32);\n   |        ^^^^^^^^^^^^^^^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:140:6\n   |\nLL | enum EnumCrate {\n   |      ^^^^^^^^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:141:5\n   |\nLL |     V1,\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:142:5\n   |\nLL |     V2(u32),\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:144:5\n   |\nLL |     V3 {\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:145:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:155:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a union\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:161:7\n   |\nLL | union UnionCrate {\n   |       ^^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:162:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:165:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:168:9\n   |\nLL |     pub _f5: u32,\n   |         ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:171:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:176:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:177:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:182:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:183:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a trait\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:190:7\n   |\nLL | trait TraitCrate {\n   |       ^^^^^^^^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:191:8\n   |\nLL |     fn f1();\n   |        ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:192:8\n   |\nLL |     fn f2() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:193:11\n   |\nLL |     const C1: u32;\n   |           ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:194:11\n   |\nLL |     const C2: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated type\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:195:10\n   |\nLL |     type T1;\n   |          ^^\n\nerror: missing documentation for a macro\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:216:14\n   |\nLL | macro_rules! mac_rules_crate {\n   |              ^^^^^^^^^^^^^^^\n\nerror: missing documentation for a macro\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:220:7\n   |\nLL | macro mac_crate {\n   |       ^^^^^^^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:238:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:241:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:244:9\n   |\nLL |     pub _f5: u32,\n   |         ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:247:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:255:5\n   |\nLL |     V1,\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:256:5\n   |\nLL |     V2(u32),\n   |     ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:258:5\n   |\nLL |     V3 {\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:259:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:269:9\n   |\nLL |         f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:276:9\n   |\nLL |     pub f1: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:279:5\n   |\nLL |     f3: u32,\n   |     ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:282:9\n   |\nLL |     pub _f5: u32,\n   |         ^^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:285:5\n   |\nLL |     _f7: u32,\n   |     ^^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:290:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:291:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:296:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:297:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:305:8\n   |\nLL |     fn f1();\n   |        ^^\n\nerror: missing documentation for an associated function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:306:8\n   |\nLL |     fn f2() {}\n   |        ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:307:11\n   |\nLL |     const C1: u32;\n   |           ^^\n\nerror: missing documentation for an associated constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:308:11\n   |\nLL |     const C2: u32 = 0;\n   |           ^^\n\nerror: missing documentation for an associated type\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:309:10\n   |\nLL |     type T1;\n   |          ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:541:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:567:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:588:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:591:12\n   |\nLL |     struct S3 {\n   |            ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:592:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:595:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:600:10\n   |\nLL |     enum E3 {\n   |          ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:602:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:603:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:609:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:614:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:620:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:623:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:630:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:631:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:637:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a module\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:647:5\n   |\nLL | mod mod_crate {\n   |     ^^^^^^^^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:648:12\n   |\nLL |     pub fn f1() {}\n   |            ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:651:16\n   |\nLL |     pub struct S1 {\n   |                ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:652:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:655:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:660:14\n   |\nLL |     pub enum E1 {\n   |              ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:662:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:663:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:669:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:674:15\n   |\nLL |     pub const C1: u32 = 0;\n   |               ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:680:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:683:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:690:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:691:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:697:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:705:8\n   |\nLL |     fn f3() {}\n   |        ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:708:12\n   |\nLL |     struct S3 {\n   |            ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:709:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:712:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:717:10\n   |\nLL |     enum E3 {\n   |          ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:719:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:720:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:726:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a constant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:731:11\n   |\nLL |     const C3: u32 = 0;\n   |           ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:737:13\n   |\nLL |         pub f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:740:9\n   |\nLL |         f3: u32,\n   |         ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:747:9\n   |\nLL |         V1 {\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:748:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:754:13\n   |\nLL |             f1: u32,\n   |             ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1061:9\n   |\nLL |         f2: u32,\n   |         ^^\n\nerror: missing documentation for a field\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1062:20\n   |\nLL |         pub(crate) f3: u32,\n   |                    ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1069:23\n   |\nLL |         pub(crate) fn f2() {}\n   |                       ^^\n\nerror: missing documentation for an enum\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1072:18\n   |\nLL |         pub enum E1 {\n   |                  ^^\n\nerror: missing documentation for a variant\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1074:13\n   |\nLL |             V2,\n   |             ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1077:20\n   |\nLL |         pub struct S2;\n   |                    ^^\n\nerror: missing documentation for a function\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1096:18\n   |\nLL |         $(pub fn f2() {})\n   |                  ^^\n\nerror: missing documentation for a struct\n  --> tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs:1165:20\n   |\nLL |         pub struct VisFromOutside;\n   |                    ^^^^^^^^^^^^^^\n\nerror: aborting due to 116 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/missing_docs_in_private_items/missing_docs_in_private_items.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: default crate_root allow_unused\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/missing_docs_in_private_items/default\n//@[crate_root] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/missing_docs_in_private_items/crate_root\n//@[allow_unused] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/missing_docs_in_private_items/allow_unused\n\n#![feature(decl_macro, trait_alias)]\n#![deny(clippy::missing_docs_in_private_items)]\n#![allow(non_local_definitions)]\n\nextern crate proc_macros;\nuse proc_macros::{external, with_span};\n\nfn main() {}\n\npub fn fn_pub() {}\npub const CONST_PUB: u32 = 0;\npub static STATIC_PUB: u32 = 0;\npub type TyAliasPub = u32;\npub trait TraitAliasPub = Iterator;\npub struct StructPub;\npub struct StructFieldPub {\n    pub f1: u32,\n    /// docs\n    pub f2: u32,\n    f3: u32, //~ missing_docs_in_private_items\n    /// docs\n    f4: u32,\n    pub _f5: u32,\n    /// docs\n    pub _f6: u32,\n    _f7: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    _f8: u32,\n}\npub struct StructTuplePub(u32, pub u32);\npub enum EnumPub {\n    V1,\n    V2(u32),\n    V3 {\n        f1: u32,\n        /// docs\n        f2: u32,\n    },\n    /// docs\n    V4,\n    /// docs\n    V5(u32),\n    /// docs\n    V6 {\n        f1: u32,\n        /// docs\n        f2: u32,\n    },\n}\npub union UnionPub {\n    pub f1: u32,\n    /// docs\n    pub f2: u32,\n    f3: u32, //~ missing_docs_in_private_items\n    /// docs\n    f4: u32,\n    pub _f5: u32,\n    /// docs\n    pub _f6: u32,\n    _f7: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    _f8: u32,\n}\nimpl StructFieldPub {\n    pub fn f1() {}\n    pub const C1: u32 = 0;\n    /// docs\n    pub fn f2() {}\n    /// docs\n    pub const C2: u32 = 0;\n    fn f3() {} //~ missing_docs_in_private_items\n    const C3: u32 = 0; //~ missing_docs_in_private_items\n    /// docs\n    fn f4() {}\n    /// docs\n    const C4: u32 = 0;\n}\npub trait TraitPub {\n    fn f1();\n    fn f2() {}\n    const C1: u32;\n    const C2: u32 = 0;\n    type T1;\n    /// docs\n    fn f3();\n    /// docs\n    fn f4() {}\n    /// docs\n    const C3: u32;\n    /// docs\n    const C4: u32 = 0;\n    /// docs\n    type T2;\n}\nimpl TraitPub for StructPub {\n    fn f1() {}\n    const C1: u32 = 0;\n    type T1 = u32;\n    fn f3() {}\n    const C3: u32 = 0;\n    type T2 = u32;\n}\n#[macro_export]\nmacro_rules! mac_rules_pub {\n    () => {};\n}\npub macro mac_pub {\n    () => {},\n}\n\nfn fn_crate() {} //~ missing_docs_in_private_items\nconst CONST_CRATE: u32 = 0; //~ missing_docs_in_private_items\nstatic STATIC_CRATE: u32 = 0; //~ missing_docs_in_private_items\ntype TyAliasCrate = u32; //~ missing_docs_in_private_items\ntrait TraitAliasCrate = Iterator; //~ missing_docs_in_private_items\nstruct StructCrate; //~ missing_docs_in_private_items\n//~v missing_docs_in_private_items\nstruct StructFieldCrate {\n    pub f1: u32, //~ missing_docs_in_private_items\n    /// docs\n    pub f2: u32,\n    f3: u32, //~ missing_docs_in_private_items\n    /// docs\n    f4: u32,\n    pub _f5: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    pub _f6: u32,\n    _f7: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    _f8: u32,\n}\nstruct StructTupleCrate(u32, pub u32); //~ missing_docs_in_private_items\n//~v missing_docs_in_private_items\nenum EnumCrate {\n    V1,      //~ missing_docs_in_private_items\n    V2(u32), //~ missing_docs_in_private_items\n    //~v missing_docs_in_private_items\n    V3 {\n        f1: u32, //~ missing_docs_in_private_items\n        /// docs\n        f2: u32,\n    },\n    /// docs\n    V4,\n    /// docs\n    V5(u32),\n    /// docs\n    V6 {\n        f1: u32, //~ missing_docs_in_private_items\n        /// docs\n        f2: u32,\n    },\n}\n//~v missing_docs_in_private_items\nunion UnionCrate {\n    pub f1: u32, //~ missing_docs_in_private_items\n    /// docs\n    pub f2: u32,\n    f3: u32, //~ missing_docs_in_private_items\n    /// docs\n    f4: u32,\n    pub _f5: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    pub _f6: u32,\n    _f7: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    _f8: u32,\n}\nimpl StructFieldCrate {\n    pub fn f1() {} //~ missing_docs_in_private_items\n    pub const C1: u32 = 0; //~ missing_docs_in_private_items\n    /// docs\n    pub fn f2() {}\n    /// docs\n    pub const C2: u32 = 0;\n    fn f3() {} //~ missing_docs_in_private_items\n    const C3: u32 = 0; //~ missing_docs_in_private_items\n    /// docs\n    fn f4() {}\n    /// docs\n    const C4: u32 = 0;\n}\n//~v missing_docs_in_private_items\ntrait TraitCrate {\n    fn f1(); //~ missing_docs_in_private_items\n    fn f2() {} //~ missing_docs_in_private_items\n    const C1: u32; //~ missing_docs_in_private_items\n    const C2: u32 = 0; //~ missing_docs_in_private_items\n    type T1; //~ missing_docs_in_private_items\n    /// docs\n    fn f3();\n    /// docs\n    fn f4() {}\n    /// docs\n    const C3: u32;\n    /// docs\n    const C4: u32 = 0;\n    /// docs\n    type T2;\n}\nimpl TraitCrate for StructCrate {\n    fn f1() {}\n    const C1: u32 = 0;\n    type T1 = u32;\n    fn f3() {}\n    const C3: u32 = 0;\n    type T2 = u32;\n}\n//~v missing_docs_in_private_items\nmacro_rules! mac_rules_crate {\n    () => {};\n}\n//~v missing_docs_in_private_items\nmacro mac_crate {\n    () => {},\n}\n\n/// docs\nfn fn_crate_doc() {}\n/// docs\nconst CONST_CRATE_DOC: u32 = 0;\n/// docs\nstatic STATIC_CRATE_DOC: u32 = 0;\n/// docs\ntype TyAliasCrateDoc = u32;\n/// docs\ntrait TraitAliasCrateDoc = Iterator;\n/// docs\nstruct StructCrateDoc;\n/// docs\nstruct StructFieldCrateDoc {\n    pub f1: u32, //~ missing_docs_in_private_items\n    /// docs\n    pub f2: u32,\n    f3: u32, //~ missing_docs_in_private_items\n    /// docs\n    f4: u32,\n    pub _f5: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    pub _f6: u32,\n    _f7: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    _f8: u32,\n}\n/// docs\nstruct StructTupleCrateDoc(u32, pub u32);\n/// docs\nenum EnumCrateDoc {\n    V1,      //~ missing_docs_in_private_items\n    V2(u32), //~ missing_docs_in_private_items\n    //~v missing_docs_in_private_items\n    V3 {\n        f1: u32, //~ missing_docs_in_private_items\n        /// docs\n        f2: u32,\n    },\n    /// docs\n    V4,\n    /// docs\n    V5(u32),\n    /// docs\n    V6 {\n        f1: u32, //~ missing_docs_in_private_items\n        /// docs\n        f2: u32,\n    },\n}\n/// docs\nunion UnionCrateDoc {\n    pub f1: u32, //~ missing_docs_in_private_items\n    /// docs\n    pub f2: u32,\n    f3: u32, //~ missing_docs_in_private_items\n    /// docs\n    f4: u32,\n    pub _f5: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    pub _f6: u32,\n    _f7: u32, //~[default,crate_root] missing_docs_in_private_items\n    /// docs\n    _f8: u32,\n}\nimpl StructFieldCrateDoc {\n    pub fn f1() {} //~ missing_docs_in_private_items\n    pub const C1: u32 = 0; //~ missing_docs_in_private_items\n    /// docs\n    pub fn f2() {}\n    /// docs\n    pub const C2: u32 = 0;\n    fn f3() {} //~ missing_docs_in_private_items\n    const C3: u32 = 0; //~ missing_docs_in_private_items\n    /// docs\n    fn f4() {}\n    /// docs\n    const C4: u32 = 0;\n}\n/// docs\ntrait TraitCrateDoc {\n    fn f1(); //~ missing_docs_in_private_items\n    fn f2() {} //~ missing_docs_in_private_items\n    const C1: u32; //~ missing_docs_in_private_items\n    const C2: u32 = 0; //~ missing_docs_in_private_items\n    type T1; //~ missing_docs_in_private_items\n    /// docs\n    fn f3();\n    /// docs\n    fn f4() {}\n    /// docs\n    const C3: u32;\n    /// docs\n    const C4: u32 = 0;\n    /// docs\n    type T2;\n}\nimpl TraitCrate for StructCrateDoc {\n    fn f1() {}\n    const C1: u32 = 0;\n    type T1 = u32;\n    fn f3() {}\n    const C3: u32 = 0;\n    type T2 = u32;\n}\n/// docs\nmacro_rules! mac_rules_crate_doc {\n    () => {};\n}\n/// docs\nmacro mac_crate_doc {\n    () => {},\n}\n\n#[doc(hidden)]\nfn fn_crate_hidden() {}\n#[doc(hidden)]\nconst CONST_CRATE_HIDDEN: u32 = 0;\n#[doc(hidden)]\nstatic STATIC_CRATE_HIDDEN: u32 = 0;\n#[doc(hidden)]\ntype TyAliasCrateHidden = u32;\n#[doc(hidden)]\ntrait TraitAliasCrateHidden = Iterator;\n#[doc(hidden)]\nstruct StructCrateHidden;\n#[doc(hidden)]\nstruct StructFieldCrateHidden {\n    pub f1: u32,\n    /// docs\n    pub f2: u32,\n    f3: u32,\n    /// docs\n    f4: u32,\n    pub _f5: u32,\n    /// docs\n    pub _f6: u32,\n    _f7: u32,\n    /// docs\n    _f8: u32,\n}\n#[doc(hidden)]\nstruct StructTupleCrateHidden(u32, pub u32);\n#[doc(hidden)]\nenum EnumCrateHidden {\n    V1,\n    V2(u32),\n    V3 {\n        f1: u32,\n        /// docs\n        f2: u32,\n    },\n    V4,\n    V5(u32),\n    /// docs\n    V6 {\n        f1: u32,\n        /// docs\n        f2: u32,\n    },\n}\n#[doc(hidden)]\nunion UnionCrateHidden {\n    pub f1: u32,\n    /// docs\n    pub f2: u32,\n    f3: u32,\n    /// docs\n    f4: u32,\n    pub _f5: u32,\n    /// docs\n    pub _f6: u32,\n    _f7: u32,\n    /// docs\n    _f8: u32,\n}\n#[doc(hidden)]\nimpl StructFieldCrateHidden {\n    pub fn f1() {}\n    pub const C1: u32 = 0;\n    /// docs\n    pub fn f2() {}\n    /// docs\n    pub const C2: u32 = 0;\n    fn f3() {}\n    const C3: u32 = 0;\n    /// docs\n    fn f4() {}\n    /// docs\n    const C4: u32 = 0;\n}\n#[doc(hidden)]\ntrait TraitCrateHidden {\n    fn f1();\n    fn f2() {}\n    const C1: u32;\n    const C2: u32 = 0;\n    type T1;\n    /// docs\n    fn f3();\n    /// docs\n    fn f4() {}\n    /// docs\n    const C3: u32;\n    /// docs\n    const C4: u32 = 0;\n    /// docs\n    type T2;\n}\n#[doc(hidden)]\nmacro_rules! mac_rules_crate_hidden {\n    () => {};\n}\n#[doc(hidden)]\nmacro mac_crate_hidden {\n    () => {},\n}\n\n#[expect(clippy::missing_docs_in_private_items)]\nfn fn_crate_expect() {}\n#[expect(clippy::missing_docs_in_private_items)]\nconst CONST_CRATE_EXPECT: u32 = 0;\n#[expect(clippy::missing_docs_in_private_items)]\nstatic STATIC_CRATE_EXPECT: u32 = 0;\n#[expect(clippy::missing_docs_in_private_items)]\ntype TyAliasCrateExpect = u32;\n#[expect(clippy::missing_docs_in_private_items)]\ntrait TraitAliasCrateExpect = Iterator;\n#[expect(clippy::missing_docs_in_private_items)]\nstruct StructCrateExpect;\n#[expect(clippy::missing_docs_in_private_items)]\nstruct StructFieldCrateExpect {\n    #[expect(clippy::missing_docs_in_private_items)]\n    pub f1: u32,\n    /// docs\n    pub f2: u32,\n    #[expect(clippy::missing_docs_in_private_items)]\n    f3: u32,\n    /// docs\n    f4: u32,\n}\n#[expect(clippy::missing_docs_in_private_items)]\nstruct StructTupleCrateExpect(u32, pub u32);\n#[expect(clippy::missing_docs_in_private_items)]\nenum EnumCrateExpect {\n    #[expect(clippy::missing_docs_in_private_items)]\n    V1,\n    #[expect(clippy::missing_docs_in_private_items)]\n    V2(u32),\n    #[expect(clippy::missing_docs_in_private_items)]\n    V3 {\n        #[expect(clippy::missing_docs_in_private_items)]\n        f1: u32,\n        /// docs\n        f2: u32,\n    },\n    /// docs\n    V4,\n    /// docs\n    V5(u32),\n    /// docs\n    V6 {\n        #[expect(clippy::missing_docs_in_private_items)]\n        f1: u32,\n        /// docs\n        f2: u32,\n    },\n}\n#[expect(clippy::missing_docs_in_private_items)]\nunion UnionCrateExpect {\n    #[expect(clippy::missing_docs_in_private_items)]\n    pub f1: u32,\n    /// docs\n    pub f2: u32,\n    #[expect(clippy::missing_docs_in_private_items)]\n    f3: u32,\n    /// docs\n    f4: u32,\n}\nimpl StructFieldCrateExpect {\n    #[expect(clippy::missing_docs_in_private_items)]\n    pub fn f1() {}\n    #[expect(clippy::missing_docs_in_private_items)]\n    pub const C1: u32 = 0;\n    #[expect(clippy::missing_docs_in_private_items)]\n    fn f2() {}\n    #[expect(clippy::missing_docs_in_private_items)]\n    const C2: u32 = 0;\n}\n#[expect(clippy::missing_docs_in_private_items)]\ntrait TraitCrateExpect {\n    #[expect(clippy::missing_docs_in_private_items)]\n    fn f1();\n    #[expect(clippy::missing_docs_in_private_items)]\n    fn f2() {}\n    #[expect(clippy::missing_docs_in_private_items)]\n    const C1: u32;\n    #[expect(clippy::missing_docs_in_private_items)]\n    const C2: u32 = 0;\n    #[expect(clippy::missing_docs_in_private_items)]\n    type T1;\n}\n#[expect(clippy::missing_docs_in_private_items)]\nmacro_rules! mac_rules_crate_expect {\n    () => {};\n}\n#[expect(clippy::missing_docs_in_private_items)]\nmacro mac_crate_expect {\n    () => {},\n}\n\npub mod mod_pub {\n    pub fn f1() {}\n    pub struct S1 {\n        pub f1: u32,\n        /// docs\n        pub f2: u32,\n        f3: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n    pub enum E1 {\n        V1 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n    }\n    pub const C1: u32 = 0;\n\n    /// docs\n    pub fn f2() {}\n    /// docs\n    pub struct S2 {\n        pub f1: u32,\n        /// docs\n        pub f2: u32,\n        f3: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n    /// docs\n    pub enum E2 {\n        V1 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n    }\n    /// docs\n    pub const C2: u32 = 0;\n\n    fn f3() {} //~[default,allow_unused] missing_docs_in_private_items\n    //\n    //~[default,allow_unused]v missing_docs_in_private_items\n    struct S3 {\n        pub f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        pub f2: u32,\n        f3: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n    //~[default,allow_unused]v missing_docs_in_private_items\n    enum E3 {\n        //~[default,allow_unused]v missing_docs_in_private_items\n        V1 {\n            f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n    }\n    const C3: u32 = 0; //~[default,allow_unused] missing_docs_in_private_items\n\n    /// docs\n    fn f4() {}\n    /// docs\n    struct S4 {\n        pub f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        pub f2: u32,\n        f3: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n    /// docs\n    enum E4 {\n        //~[default,allow_unused]v missing_docs_in_private_items\n        V1 {\n            f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n    }\n    /// docs\n    const C4: u32 = 0;\n}\n\n//~v missing_docs_in_private_items\nmod mod_crate {\n    pub fn f1() {} //~ missing_docs_in_private_items\n    //\n    //~v missing_docs_in_private_items\n    pub struct S1 {\n        pub f1: u32, //~ missing_docs_in_private_items\n        /// docs\n        pub f2: u32,\n        f3: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n    //~v missing_docs_in_private_items\n    pub enum E1 {\n        //~v missing_docs_in_private_items\n        V1 {\n            f1: u32, //~ missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32, //~ missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n    }\n    pub const C1: u32 = 0; //~ missing_docs_in_private_items\n\n    /// docs\n    pub fn f2() {}\n    /// docs\n    pub struct S2 {\n        pub f1: u32, //~ missing_docs_in_private_items\n        /// docs\n        pub f2: u32,\n        f3: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n    /// docs\n    pub enum E2 {\n        //~v missing_docs_in_private_items\n        V1 {\n            f1: u32, //~ missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32, //~ missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n    }\n    /// docs\n    pub const C2: u32 = 0;\n\n    fn f3() {} //~[default,allow_unused] missing_docs_in_private_items\n    //\n    //~[default,allow_unused]v missing_docs_in_private_items\n    struct S3 {\n        pub f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        pub f2: u32,\n        f3: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n    //~[default,allow_unused]v missing_docs_in_private_items\n    enum E3 {\n        //~[default,allow_unused]v missing_docs_in_private_items\n        V1 {\n            f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n    }\n    const C3: u32 = 0; //~[default,allow_unused] missing_docs_in_private_items\n\n    /// docs\n    fn f4() {}\n    /// docs\n    struct S4 {\n        pub f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        pub f2: u32,\n        f3: u32, //~[default,allow_unused] missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n    /// docs\n    enum E4 {\n        //~[default,allow_unused]v missing_docs_in_private_items\n        V1 {\n            f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32, //~[default,allow_unused] missing_docs_in_private_items\n            /// docs\n            f2: u32,\n        },\n    }\n    /// docs\n    const C4: u32 = 0;\n}\n\n/// docs\nmod mod_crate_doc {}\n\n#[doc(hidden)]\nmod mod_crate_hidden {\n    pub fn f1() {}\n    pub struct S1 {\n        pub f1: u32,\n        /// docs\n        pub f2: u32,\n        f3: u32,\n        /// docs\n        f4: u32,\n    }\n    pub enum E1 {\n        V1 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n    }\n    pub const C1: u32 = 0;\n\n    /// docs\n    pub fn f2() {}\n    /// docs\n    pub struct S2 {\n        pub f1: u32,\n        /// docs\n        pub f2: u32,\n        f3: u32,\n        /// docs\n        f4: u32,\n    }\n    /// docs\n    pub enum E2 {\n        V1 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n    }\n    /// docs\n    pub const C2: u32 = 0;\n\n    fn f3() {}\n    struct S3 {\n        pub f1: u32,\n        /// docs\n        pub f2: u32,\n        f3: u32,\n        /// docs\n        f4: u32,\n    }\n    enum E3 {\n        V1 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n    }\n    const C3: u32 = 0;\n\n    /// docs\n    fn f4() {}\n    /// docs\n    struct S4 {\n        pub f1: u32,\n        /// docs\n        pub f2: u32,\n        f3: u32,\n        /// docs\n        f4: u32,\n    }\n    /// docs\n    enum E4 {\n        V1 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n        /// docs\n        V2 {\n            f1: u32,\n            /// docs\n            f2: u32,\n        },\n    }\n    /// docs\n    const C4: u32 = 0;\n}\n\n#[expect(clippy::missing_docs_in_private_items)]\nmod mod_crate_expect {}\n\n#[doc = \"docs\"]\nmod explicit_doc_attr {}\n\nwith_span! {\n    sp\n    fn fn_pm() {}\n    const CONST_PM: u32 = 0;\n    static STATIC_PM: u32 = 0;\n    type TyAliasPm = u32;\n    trait TraitAliasPm = Iterator;\n    struct StructPm;\n    struct StructFieldPm {\n        pub f1: u32,\n        f2: u32,\n        pub _f3: u32,\n        _f4: u32,\n    }\n    struct StructTuplePm(u32, pub u32);\n    enum EnumPm {\n        V1,\n        V2(u32),\n        V3 { f1: u32, },\n    }\n    union UnionPm {\n        pub f1: u32,\n        f2: u32,\n        pub _f3: u32,\n        _f4: u32,\n    }\n    impl StructFieldPm {\n        pub fn f1() {}\n        pub const C1: u32 = 0;\n        fn f2() {}\n        const C2: u32 = 0;\n    }\n    trait TraitPm {\n        fn f1();\n        fn f2() {}\n        const C1: u32;\n        const C2: u32 = 0;\n        type T1;\n    }\n    impl TraitPm for StructPm {\n        fn f1() {}\n        const C1: u32 = 0;\n        type T1 = u32;\n    }\n    macro_rules! mac_rules_pm {\n        () => {};\n    }\n    macro mac_pm {\n        () => {},\n    }\n    mod mod_pm {}\n}\n\nexternal! {\n    fn fn_external() {}\n    const CONST_EXTERNAL: u32 = 0;\n    static STATIC_EXTERNAL: u32 = 0;\n    type TyAliasExternal = u32;\n    trait TraitAliasExternal = Iterator;\n    struct StructExternal;\n    struct StructFieldExternal {\n        pub f1: u32,\n        f2: u32,\n        pub _f3: u32,\n        _f4: u32,\n    }\n    struct StructTupleExternal(u32, pub u32);\n    enum EnumExternal {\n        V1,\n        V2(u32),\n        V3 { f1: u32, },\n    }\n    union UnionExternal {\n        pub f1: u32,\n        f2: u32,\n        pub _f3: u32,\n        _f4: u32,\n    }\n    impl StructFieldExternal {\n        pub fn f1() {}\n        pub const C1: u32 = 0;\n        fn f2() {}\n        const C2: u32 = 0;\n    }\n    trait TraitExternal {\n        fn f1();\n        fn f2() {}\n        const C1: u32;\n        const C2: u32 = 0;\n        type T1;\n    }\n    impl TraitExternal for StructExternal {\n        fn f1() {}\n        const C1: u32 = 0;\n        type T1 = u32;\n    }\n    macro_rules! mac_rules_external {\n        () => {};\n    }\n    macro mac_external {\n        () => {},\n    }\n    mod mod_external {}\n}\n\npub const _: () = {};\nconst _: () = {};\n\n/// docs\nfn fn_with_items() {\n    fn f() {}\n    type T = u32;\n    struct S {\n        f1: u32,\n        f2: u32,\n    }\n    enum E {\n        V { f: u32 },\n    }\n    impl S {\n        fn f() {}\n        const C: u32 = 0;\n    }\n    const C: u32 = 0;\n    static ST: u32 = 0;\n    trait Tr {\n        fn f();\n        type T;\n        const C: u32;\n    }\n    trait Tr2 = Tr;\n    mod m {}\n    macro_rules! m2 {\n        () => {};\n    }\n    macro m3 { () => {}, }\n    union U {\n        f: u32,\n    }\n}\n/// docs\nconst CONST_WITH_ITEMS: () = {\n    fn f() {}\n};\n/// docs\nstatic STATIC_WITH_ITEMS: () = {\n    fn f() {}\n};\n/// docs\ntrait TraitWithItems {\n    /// docs\n    fn f() {\n        fn f() {}\n    }\n    /// docs\n    const C: () = {\n        fn f() {}\n    };\n}\n/// docs\nstruct StructWithItems;\nimpl StructWithItems {\n    /// docs\n    fn f() {\n        fn f() {}\n    }\n    /// docs\n    const C: () = {\n        fn f() {}\n    };\n}\n/// docs\ntype TypeAliasWithItems = [u32; {\n    fn f() {}\n    1\n}];\n\n/// docs\nmod with_reexports {\n    pub fn f1_reexport() {}\n    pub struct S1Reexport {\n        pub f1: u32,\n        f2: u32,            //~[default,allow_unused] missing_docs_in_private_items\n        pub(crate) f3: u32, //~ missing_docs_in_private_items\n        /// docs\n        f4: u32,\n    }\n\n    /// docs\n    mod m1 {\n        pub(crate) fn f2() {} //~[default,allow_unused] missing_docs_in_private_items\n\n        //~v missing_docs_in_private_items\n        pub enum E1 {\n            V1Reexport,\n            V2, //~ missing_docs_in_private_items\n        }\n\n        pub struct S2; //~ missing_docs_in_private_items\n        pub fn f3_reexport() -> S2 {\n            S2\n        }\n    }\n    pub use m1::E1::{V1Reexport, V2};\n    use m1::f2;\n    pub use m1::f3_reexport;\n}\npub use with_reexports::{S1Reexport, V1Reexport, f1_reexport, f3_reexport};\n\nexternal! {\n    mod mod_generated {\n        $(type T = u32;)\n        struct S {\n            $(f1: u32,)\n            f2: u32,\n        }\n        pub fn f() {}\n        $(pub fn f2() {}) //~ missing_docs_in_private_items\n        #[doc(hidden)]\n        $(pub fn f3() {})\n    }\n}\n\n/// docs\nmod mod_with_hidden {\n    #[doc(hidden)]\n    pub mod m {\n        pub struct S {\n            #[doc(hidden)]\n            pub f: u32,\n        }\n        #[automatically_derived]\n        impl S {\n            #[doc(hidden)]\n            pub fn f() {}\n            pub const C: () = {\n                #[automatically_derived]\n                impl S {\n                    #[doc(hidden)]\n                    pub fn f2() {\n                        mod m {\n                            pub(crate) union U {\n                                pub f: u32,\n                            }\n                        }\n                    }\n                }\n            };\n        }\n    }\n    #[doc(hidden)]\n    pub(crate) fn f() {}\n}\n\n/// docs\nstruct WithProject {\n    /// docs\n    a: u32,\n    /// docs\n    b: u32,\n}\nwith_span! {\n    span\n    const _: () = {\n        // Similar output to pin_project\n        struct Project<'a> {\n            $(a: &'a u32),\n            $(b: &'a u32),\n        }\n        impl $(WithProject) {\n            fn project(&self) -> Project<'_> {\n                Project {\n                    a: &self.a,\n                    b: &self.b,\n                }\n            }\n        }\n    };\n}\n\nexternal! {\n    mod mod_mac_with_pub {$(\n        struct DerivedFromInput;\n        impl DerivedFromInput {\n            pub fn foo() {}\n        }\n        pub struct VisFromOutside; //~ missing_docs_in_private_items\n    )}\n}\n"
  },
  {
    "path": "tests/ui-toml/missing_enforced_import_rename/clippy.toml",
    "content": "enforced-import-renames = [\n    { path = \"std::option::Option\", rename = \"Maybe\" },\n    { path = \"std::process::Child\", rename = \"Kid\" },\n    { path = \"std::process::exit\", rename = \"goodbye\" },\n    { path = \"std::collections::BTreeMap\", rename = \"Map\" },\n    { path = \"std::clone\", rename = \"foo\" },\n    { path = \"std::thread::sleep\", rename = \"thread_sleep\" },\n    { path = \"std::any::type_name\", rename = \"ident\" },\n    { path = \"std::sync::Mutex\", rename = \"StdMutie\" },\n    { path = \"std::io::Write\", rename = \"to_test_rename_as_underscore\" }\n]\n"
  },
  {
    "path": "tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed",
    "content": "#![warn(clippy::missing_enforced_import_renames)]\n\nuse std::alloc as colla;\nuse std::option::Option as Maybe;\nuse std::process::{Child as Kid, exit as goodbye};\n//~^ missing_enforced_import_renames\nuse std::thread::sleep as thread_sleep;\n//~^ missing_enforced_import_renames\n#[rustfmt::skip]\nuse std::{\n    any::{type_name as ident, Any},\n    //~^ missing_enforced_import_renames\n    clone as foo,\n    //~^ missing_enforced_import_renames\n    sync :: Mutex as StdMutie,\n    //~^ missing_enforced_import_renames\n};\nuse std::io::Write as _;\n\nfn main() {\n    use std::collections::BTreeMap as Map;\n    //~^ missing_enforced_import_renames\n}\n"
  },
  {
    "path": "tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs",
    "content": "#![warn(clippy::missing_enforced_import_renames)]\n\nuse std::alloc as colla;\nuse std::option::Option as Maybe;\nuse std::process::{Child as Kid, exit as wrong_exit};\n//~^ missing_enforced_import_renames\nuse std::thread::sleep;\n//~^ missing_enforced_import_renames\n#[rustfmt::skip]\nuse std::{\n    any::{type_name, Any},\n    //~^ missing_enforced_import_renames\n    clone,\n    //~^ missing_enforced_import_renames\n    sync :: Mutex,\n    //~^ missing_enforced_import_renames\n};\nuse std::io::Write as _;\n\nfn main() {\n    use std::collections::BTreeMap as OopsWrongRename;\n    //~^ missing_enforced_import_renames\n}\n"
  },
  {
    "path": "tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr",
    "content": "error: this import should be renamed\n  --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:5:34\n   |\nLL | use std::process::{Child as Kid, exit as wrong_exit};\n   |                                  ^^^^^^^^^^^^^^^^^^ help: try: `exit as goodbye`\n   |\n   = note: `-D clippy::missing-enforced-import-renames` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_enforced_import_renames)]`\n\nerror: this import should be renamed\n  --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:7:1\n   |\nLL | use std::thread::sleep;\n   | ^^^^^^^^^^^^^^^^^^^^^^ help: try: `use std::thread::sleep as thread_sleep`\n\nerror: this import should be renamed\n  --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:11:11\n   |\nLL |     any::{type_name, Any},\n   |           ^^^^^^^^^ help: try: `type_name as ident`\n\nerror: this import should be renamed\n  --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:13:5\n   |\nLL |     clone,\n   |     ^^^^^ help: try: `clone as foo`\n\nerror: this import should be renamed\n  --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:15:5\n   |\nLL |     sync :: Mutex,\n   |     ^^^^^^^^^^^^^ help: try: `sync :: Mutex as StdMutie`\n\nerror: this import should be renamed\n  --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:21:5\n   |\nLL |     use std::collections::BTreeMap as OopsWrongRename;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `use std::collections::BTreeMap as Map`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/module_inception/clippy.toml",
    "content": "allow-private-module-inception = true\n"
  },
  {
    "path": "tests/ui-toml/module_inception/module_inception.rs",
    "content": "#![warn(clippy::module_inception)]\n\n// Lint\npub mod foo2 {\n    pub mod bar2 {\n        pub mod bar2 {\n            //~^ module_inception\n            pub mod foo2 {}\n        }\n        pub mod foo2 {}\n    }\n    pub mod foo2 {\n        //~^ module_inception\n        pub mod bar2 {}\n    }\n}\n\n// Don't lint\nmod foo {\n    pub mod bar {\n        pub mod foo {\n            pub mod bar {}\n        }\n    }\n    pub mod foo {\n        pub mod bar {}\n    }\n}\n\n// No warning. See <https://github.com/rust-lang/rust-clippy/issues/1220>.\npub mod bar {\n    #[allow(clippy::module_inception)]\n    pub mod bar {}\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/module_inception/module_inception.stderr",
    "content": "error: module has the same name as its containing module\n  --> tests/ui-toml/module_inception/module_inception.rs:6:9\n   |\nLL | /         pub mod bar2 {\nLL | |\nLL | |             pub mod foo2 {}\nLL | |         }\n   | |_________^\n   |\n   = note: `-D clippy::module-inception` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::module_inception)]`\n\nerror: module has the same name as its containing module\n  --> tests/ui-toml/module_inception/module_inception.rs:12:5\n   |\nLL | /     pub mod foo2 {\nLL | |\nLL | |         pub mod bar2 {}\nLL | |     }\n   | |_____^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/modulo_arithmetic/clippy.toml",
    "content": "allow-comparison-to-zero = false\n"
  },
  {
    "path": "tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs",
    "content": "#![warn(clippy::modulo_arithmetic)]\n\nfn main() {\n    let a = -1;\n    let b = 2;\n    let c = a % b == 0;\n    //~^ modulo_arithmetic\n    let c = a % b != 0;\n    //~^ modulo_arithmetic\n    let c = 0 == a % b;\n    //~^ modulo_arithmetic\n    let c = 0 != a % b;\n    //~^ modulo_arithmetic\n}\n"
  },
  {
    "path": "tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr",
    "content": "error: you are using modulo operator on types that might have different signs\n  --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:6:13\n   |\nLL |     let c = a % b == 0;\n   |             ^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:8:13\n   |\nLL |     let c = a % b != 0;\n   |             ^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:10:18\n   |\nLL |     let c = 0 == a % b;\n   |                  ^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: you are using modulo operator on types that might have different signs\n  --> tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs:12:18\n   |\nLL |     let c = 0 != a % b;\n   |                  ^^^^^\n   |\n   = note: double check for expected result especially when interoperating with different languages\n   = note: or consider using `rem_euclid` or similar function\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/mut_key/clippy.toml",
    "content": "ignore-interior-mutability = [\"mut_key::Counted\"]"
  },
  {
    "path": "tests/ui-toml/mut_key/mut_key.rs",
    "content": "//@compile-flags: --crate-name mut_key\n//@check-pass\n\n#![warn(clippy::mutable_key_type)]\n\nuse std::cmp::{Eq, PartialEq};\nuse std::collections::{HashMap, HashSet};\nuse std::hash::{Hash, Hasher};\nuse std::ops::Deref;\nuse std::sync::atomic::{AtomicUsize, Ordering};\n\nstruct Counted<T> {\n    count: AtomicUsize,\n    val: T,\n}\n\nimpl<T: Clone> Clone for Counted<T> {\n    fn clone(&self) -> Self {\n        Self {\n            count: AtomicUsize::new(0),\n            val: self.val.clone(),\n        }\n    }\n}\n\nimpl<T: PartialEq> PartialEq for Counted<T> {\n    fn eq(&self, other: &Self) -> bool {\n        self.val == other.val\n    }\n}\nimpl<T: PartialEq + Eq> Eq for Counted<T> {}\n\nimpl<T: Hash> Hash for Counted<T> {\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        self.val.hash(state);\n    }\n}\n\nimpl<T> Deref for Counted<T> {\n    type Target = T;\n\n    fn deref(&self) -> &T {\n        self.count.fetch_add(1, Ordering::AcqRel);\n        &self.val\n    }\n}\n\n#[derive(Hash, PartialEq, Eq)]\nstruct ContainsCounted {\n    inner: Counted<String>,\n}\n\n// This is not linted because `\"mut_key::Counted\"` is in\n// `arc_like_types` in `clippy.toml`\nfn should_not_take_this_arg(_v: HashSet<Counted<String>>) {}\n\nfn indirect(_: HashMap<ContainsCounted, usize>) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/needless_pass_by_ref_mut/clippy.toml",
    "content": "avoid-breaking-exported-api = false\n"
  },
  {
    "path": "tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed",
    "content": "#![warn(clippy::needless_pass_by_ref_mut)]\n#![allow(clippy::ptr_arg)]\n\n// Should warn\npub fn pub_foo(s: &Vec<u32>, b: &u32, x: &mut u32) {\n    //~^ needless_pass_by_ref_mut\n    *x += *b + s.len() as u32;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs",
    "content": "#![warn(clippy::needless_pass_by_ref_mut)]\n#![allow(clippy::ptr_arg)]\n\n// Should warn\npub fn pub_foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {\n    //~^ needless_pass_by_ref_mut\n    *x += *b + s.len() as u32;\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr",
    "content": "error: this parameter is a mutable reference but is not used mutably\n  --> tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs:5:19\n   |\nLL | pub fn pub_foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {\n   |                   ^----^^^^^^^^\n   |                    |\n   |                    help: consider removing this `mut`\n   |\n   = warning: changing this function will impact semver compatibility\n   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/needless_raw_string_hashes_one_allowed/clippy.toml",
    "content": "allow-one-hash-in-raw-strings = true\n"
  },
  {
    "path": "tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed",
    "content": "#![allow(clippy::no_effect, unused)]\n#![warn(clippy::needless_raw_string_hashes)]\n\nfn main() {\n    r#\"\\aaa\"#;\n    r#\"\\aaa\"#;\n    //~^ needless_raw_string_hashes\n    r#\"Hello \"world\"!\"#;\n    //~^ needless_raw_string_hashes\n    r####\" \"### \"## \"# \"####;\n    //~^ needless_raw_string_hashes\n}\n"
  },
  {
    "path": "tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs",
    "content": "#![allow(clippy::no_effect, unused)]\n#![warn(clippy::needless_raw_string_hashes)]\n\nfn main() {\n    r#\"\\aaa\"#;\n    r##\"\\aaa\"##;\n    //~^ needless_raw_string_hashes\n    r##\"Hello \"world\"!\"##;\n    //~^ needless_raw_string_hashes\n    r######\" \"### \"## \"# \"######;\n    //~^ needless_raw_string_hashes\n}\n"
  },
  {
    "path": "tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr",
    "content": "error: unnecessary hashes around raw string literal\n  --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:6:5\n   |\nLL |     r##\"\\aaa\"##;\n   |     ^^^^^^^^^^^\n   |\n   = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::needless_raw_string_hashes)]`\nhelp: remove one hash from both sides of the string literal\n   |\nLL -     r##\"\\aaa\"##;\nLL +     r#\"\\aaa\"#;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:8:5\n   |\nLL |     r##\"Hello \"world\"!\"##;\n   |     ^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove one hash from both sides of the string literal\n   |\nLL -     r##\"Hello \"world\"!\"##;\nLL +     r#\"Hello \"world\"!\"#;\n   |\n\nerror: unnecessary hashes around raw string literal\n  --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:10:5\n   |\nLL |     r######\" \"### \"## \"# \"######;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: remove 2 hashes from both sides of the string literal\n   |\nLL -     r######\" \"### \"## \"# \"######;\nLL +     r####\" \"### \"## \"# \"####;\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/nonstandard_macro_braces/auxiliary/proc_macro_derive.rs",
    "content": "extern crate proc_macro;\n\nuse proc_macro::TokenStream;\n\n#[proc_macro_derive(DeriveSomething)]\npub fn derive(_: TokenStream) -> TokenStream {\n    \"fn _f() -> Vec<u8> { vec![] }\".parse().unwrap()\n}\n\n#[proc_macro]\npub fn foo_bar(_: TokenStream) -> TokenStream {\n    \"fn issue_7422() { eprintln!(); }\".parse().unwrap()\n}\n"
  },
  {
    "path": "tests/ui-toml/nonstandard_macro_braces/clippy.toml",
    "content": "standard-macro-braces = [\n    { name = \"quote\", brace = \"{\" },\n    { name = \"quote::quote\", brace = \"{\" },\n    { name = \"eprint\", brace = \"[\" },\n    { name = \"type_pos\", brace = \"[\" },\n]\n"
  },
  {
    "path": "tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.fixed",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::nonstandard_macro_braces)]\n#![allow(clippy::println_empty_string)]\n\nextern crate proc_macro_derive;\nextern crate quote;\n\nuse quote::quote;\n\n#[derive(proc_macro_derive::DeriveSomething)]\npub struct S;\n\nproc_macro_derive::foo_bar!();\n\n#[rustfmt::skip]\nmacro_rules! test {\n    () => {\n        vec![0, 0, 0]\n        //~^ nonstandard_macro_braces\n    };\n}\n\n#[rustfmt::skip]\nmacro_rules! test2 {\n    ($($arg:tt)*) => {\n        format_args!($($arg)*)\n    };\n}\n\nmacro_rules! type_pos {\n    ($what:ty) => {\n        Vec<$what>\n    };\n}\n\nmacro_rules! printlnfoo {\n    ($thing:expr) => {\n        println!(\"{}\", $thing)\n    };\n}\n\n#[rustfmt::skip]\nfn main() {\n    let _ = vec![1, 2, 3];\n    //~^ nonstandard_macro_braces\n    let _ = format!(\"ugh {} stop being such a good compiler\", \"hello\");\n    //~^ nonstandard_macro_braces\n    let _ = matches!({}, ());\n    //~^ nonstandard_macro_braces\n    let _ = quote!{let x = 1;};\n    //~^ nonstandard_macro_braces\n    let _ = quote::quote!{match match match};\n    //~^ nonstandard_macro_braces\n    let _ = test!(); // trigger when macro def is inside our own crate\n    let _ = vec![1,2,3];\n\n    let _ = quote::quote! {true || false};\n    let _ = vec! [0 ,0 ,0];\n    let _ = format!(\"fds{}fds\", 10);\n    let _ = test2![\"{}{}{}\", 1, 2, 3];\n\n    let _: type_pos![usize] = vec![];\n    //~^ nonstandard_macro_braces\n\n    eprint![\"test if user config overrides defaults\"];\n    //~^ nonstandard_macro_braces\n\n    printlnfoo![\"test if printlnfoo is triggered by println\"];\n}\n\n#[rustfmt::skip]\n#[expect(clippy::no_effect)]\nfn issue9913() {\n    println!(\"hello world\");\n    [0]; // separate statement, not indexing into the result of println.\n    //~^^ nonstandard_macro_braces\n}\n\nfn issue15594() {\n    println!();\n    println!(\"\");\n    println!();\n    //~^ nonstandard_macro_braces\n    println!(\"\");\n    //~^ nonstandard_macro_braces\n    println!();\n    //~^ nonstandard_macro_braces\n    println!(\"\");\n    //~^ nonstandard_macro_braces\n}\n"
  },
  {
    "path": "tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs",
    "content": "//@aux-build:proc_macro_derive.rs\n\n#![warn(clippy::nonstandard_macro_braces)]\n#![allow(clippy::println_empty_string)]\n\nextern crate proc_macro_derive;\nextern crate quote;\n\nuse quote::quote;\n\n#[derive(proc_macro_derive::DeriveSomething)]\npub struct S;\n\nproc_macro_derive::foo_bar!();\n\n#[rustfmt::skip]\nmacro_rules! test {\n    () => {\n        vec!{0, 0, 0}\n        //~^ nonstandard_macro_braces\n    };\n}\n\n#[rustfmt::skip]\nmacro_rules! test2 {\n    ($($arg:tt)*) => {\n        format_args!($($arg)*)\n    };\n}\n\nmacro_rules! type_pos {\n    ($what:ty) => {\n        Vec<$what>\n    };\n}\n\nmacro_rules! printlnfoo {\n    ($thing:expr) => {\n        println!(\"{}\", $thing)\n    };\n}\n\n#[rustfmt::skip]\nfn main() {\n    let _ = vec! {1, 2, 3};\n    //~^ nonstandard_macro_braces\n    let _ = format![\"ugh {} stop being such a good compiler\", \"hello\"];\n    //~^ nonstandard_macro_braces\n    let _ = matches!{{}, ()};\n    //~^ nonstandard_macro_braces\n    let _ = quote!(let x = 1;);\n    //~^ nonstandard_macro_braces\n    let _ = quote::quote!(match match match);\n    //~^ nonstandard_macro_braces\n    let _ = test!(); // trigger when macro def is inside our own crate\n    let _ = vec![1,2,3];\n\n    let _ = quote::quote! {true || false};\n    let _ = vec! [0 ,0 ,0];\n    let _ = format!(\"fds{}fds\", 10);\n    let _ = test2![\"{}{}{}\", 1, 2, 3];\n\n    let _: type_pos!(usize) = vec![];\n    //~^ nonstandard_macro_braces\n\n    eprint!(\"test if user config overrides defaults\");\n    //~^ nonstandard_macro_braces\n\n    printlnfoo![\"test if printlnfoo is triggered by println\"];\n}\n\n#[rustfmt::skip]\n#[expect(clippy::no_effect)]\nfn issue9913() {\n    println! {\"hello world\"}\n    [0]; // separate statement, not indexing into the result of println.\n    //~^^ nonstandard_macro_braces\n}\n\nfn issue15594() {\n    println!();\n    println!(\"\");\n    println![];\n    //~^ nonstandard_macro_braces\n    println![\"\"];\n    //~^ nonstandard_macro_braces\n    println! {};\n    //~^ nonstandard_macro_braces\n    println! {\"\"};\n    //~^ nonstandard_macro_braces\n}\n"
  },
  {
    "path": "tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr",
    "content": "error: use of irregular braces for `vec!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:45:13\n   |\nLL |     let _ = vec! {1, 2, 3};\n   |             ^^^^^^^^^^^^^^ help: consider writing: `vec![1, 2, 3]`\n   |\n   = note: `-D clippy::nonstandard-macro-braces` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::nonstandard_macro_braces)]`\n\nerror: use of irregular braces for `format!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:47:13\n   |\nLL |     let _ = format![\"ugh {} stop being such a good compiler\", \"hello\"];\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `format!(\"ugh {} stop being such a good compiler\", \"hello\")`\n\nerror: use of irregular braces for `matches!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:49:13\n   |\nLL |     let _ = matches!{{}, ()};\n   |             ^^^^^^^^^^^^^^^^ help: consider writing: `matches!({}, ())`\n\nerror: use of irregular braces for `quote!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:51:13\n   |\nLL |     let _ = quote!(let x = 1;);\n   |             ^^^^^^^^^^^^^^^^^^ help: consider writing: `quote!{let x = 1;}`\n\nerror: use of irregular braces for `quote::quote!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:53:13\n   |\nLL |     let _ = quote::quote!(match match match);\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `quote::quote!{match match match}`\n\nerror: use of irregular braces for `vec!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:19:9\n   |\nLL |         vec!{0, 0, 0}\n   |         ^^^^^^^^^^^^^ help: consider writing: `vec![0, 0, 0]`\n...\nLL |     let _ = test!(); // trigger when macro def is inside our own crate\n   |             ------- in this macro invocation\n   |\n   = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: use of irregular braces for `type_pos!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:63:12\n   |\nLL |     let _: type_pos!(usize) = vec![];\n   |            ^^^^^^^^^^^^^^^^ help: consider writing: `type_pos![usize]`\n\nerror: use of irregular braces for `eprint!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:66:5\n   |\nLL |     eprint!(\"test if user config overrides defaults\");\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `eprint![\"test if user config overrides defaults\"]`\n\nerror: use of irregular braces for `println!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:75:5\n   |\nLL |     println! {\"hello world\"}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `println!(\"hello world\");`\n\nerror: use of irregular braces for `println!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:83:5\n   |\nLL |     println![];\n   |     ^^^^^^^^^^ help: consider writing: `println!()`\n\nerror: use of irregular braces for `println!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:85:5\n   |\nLL |     println![\"\"];\n   |     ^^^^^^^^^^^^ help: consider writing: `println!(\"\")`\n\nerror: use of irregular braces for `println!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:87:5\n   |\nLL |     println! {};\n   |     ^^^^^^^^^^^ help: consider writing: `println!()`\n\nerror: use of irregular braces for `println!` macro\n  --> tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.rs:89:5\n   |\nLL |     println! {\"\"};\n   |     ^^^^^^^^^^^^^ help: consider writing: `println!(\"\")`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/panic/clippy.toml",
    "content": "allow-panic-in-tests = true\n"
  },
  {
    "path": "tests/ui-toml/panic/panic.rs",
    "content": "//@compile-flags: --test\n#![warn(clippy::panic)]\nuse std::panic::panic_any;\n\nfn main() {\n    enum Enam {\n        A,\n    }\n    let a = Enam::A;\n    match a {\n        Enam::A => {},\n        _ => panic!(\"\"),\n        //~^ panic\n    }\n}\n\nfn issue_13292() {\n    panic_any(\"should lint\")\n    //~^ panic\n}\n\n#[test]\nfn lonely_test() {\n    enum Enam {\n        A,\n    }\n    let a = Enam::A;\n    match a {\n        Enam::A => {},\n        _ => panic!(\"\"),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    // should not lint in `#[cfg(test)]` modules\n    #[test]\n    fn test_fn() {\n        enum Enam {\n            A,\n        }\n        let a = Enam::A;\n        match a {\n            Enam::A => {},\n            _ => panic!(\"\"),\n        }\n\n        bar();\n    }\n\n    fn bar() {\n        enum Enam {\n            A,\n        }\n        let a = Enam::A;\n        match a {\n            Enam::A => {},\n            _ => panic!(\"\"),\n        }\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/panic/panic.stderr",
    "content": "error: `panic` should not be present in production code\n  --> tests/ui-toml/panic/panic.rs:12:14\n   |\nLL |         _ => panic!(\"\"),\n   |              ^^^^^^^^^^\n   |\n   = note: `-D clippy::panic` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::panic)]`\n\nerror: `panic_any` should not be present in production code\n  --> tests/ui-toml/panic/panic.rs:18:5\n   |\nLL |     panic_any(\"should lint\")\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/path_ends_with_ext/clippy.toml",
    "content": "allowed-dotfiles = [\"dot\"]\n"
  },
  {
    "path": "tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs",
    "content": "//@check-pass\n\n#![warn(clippy::path_ends_with_ext)]\n\nuse std::path::Path;\n\nfn f(p: &Path) {\n    p.ends_with(\".dot\");\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/print_macro/clippy.toml",
    "content": "allow-print-in-tests = true\n"
  },
  {
    "path": "tests/ui-toml/print_macro/print_macro.rs",
    "content": "//@compile-flags: --test\n#![warn(clippy::print_stdout)]\n#![warn(clippy::print_stderr)]\n\nfn foo(n: u32) {\n    print!(\"{n}\");\n    //~^ print_stdout\n    eprint!(\"{n}\");\n    //~^ print_stderr\n}\n\n#[test]\npub fn foo1() {\n    print!(\"{}\", 1);\n    eprint!(\"{}\", 1);\n}\n\n#[cfg(test)]\nfn foo3() {\n    print!(\"{}\", 1);\n    eprint!(\"{}\", 1);\n}\n"
  },
  {
    "path": "tests/ui-toml/print_macro/print_macro.stderr",
    "content": "error: use of `print!`\n  --> tests/ui-toml/print_macro/print_macro.rs:6:5\n   |\nLL |     print!(\"{n}\");\n   |     ^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::print-stdout` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_stdout)]`\n\nerror: use of `eprint!`\n  --> tests/ui-toml/print_macro/print_macro.rs:8:5\n   |\nLL |     eprint!(\"{n}\");\n   |     ^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::print-stderr` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::print_stderr)]`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/private-doc-errors/clippy.toml",
    "content": "check-private-items = true\n"
  },
  {
    "path": "tests/ui-toml/private-doc-errors/doc_lints.rs",
    "content": "#![deny(\n    clippy::unnecessary_safety_doc,\n    clippy::missing_errors_doc,\n    clippy::missing_panics_doc\n)]\n\n/// This is a private function, skip to match behavior with `missing_safety_doc`.\n///\n/// # Safety\n///\n/// Boo!\nfn you_dont_see_me() {\n    //~^ ERROR: safe function's docs have unnecessary `# Safety` section\n    unimplemented!();\n}\n\nmod private_mod {\n    /// This is public but unexported function.\n    ///\n    /// # Safety\n    ///\n    /// Very safe!\n    pub fn only_crate_wide_accessible() -> Result<(), ()> {\n        //~^ ERROR: safe function's docs have unnecessary `# Safety` section\n        //~| ERROR: docs for function returning `Result` missing `# Errors` section\n        unimplemented!();\n    }\n}\n\npub struct S;\n\nimpl S {\n    /// Private, fine again to stay consistent with `missing_safety_doc`.\n    ///\n    /// # Safety\n    ///\n    /// Unnecessary!\n    fn private(&self) {\n        //~^ ERROR: safe function's docs have unnecessary `# Safety` section\n        //~| ERROR: docs for function which may panic missing `# Panics` section\n        panic!();\n    }\n}\n\n#[doc(hidden)]\npub mod __macro {\n    pub struct T;\n    impl T {\n        pub unsafe fn f() {}\n        //~^ ERROR: unsafe function's docs are missing a `# Safety` section\n    }\n}\n\n#[warn(clippy::missing_errors_doc)]\n#[test]\nfn test() -> Result<(), ()> {\n    Ok(())\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/private-doc-errors/doc_lints.stderr",
    "content": "error: safe function's docs have unnecessary `# Safety` section\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:12:1\n   |\nLL | fn you_dont_see_me() {\n   | ^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:2:5\n   |\nLL |     clippy::unnecessary_safety_doc,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: safe function's docs have unnecessary `# Safety` section\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:23:5\n   |\nLL |     pub fn only_crate_wide_accessible() -> Result<(), ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: docs for function returning `Result` missing `# Errors` section\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:23:5\n   |\nLL |     pub fn only_crate_wide_accessible() -> Result<(), ()> {\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: the lint level is defined here\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:3:5\n   |\nLL |     clippy::missing_errors_doc,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: safe function's docs have unnecessary `# Safety` section\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:38:5\n   |\nLL |     fn private(&self) {\n   |     ^^^^^^^^^^^^^^^^^\n\nerror: docs for function which may panic missing `# Panics` section\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:38:5\n   |\nLL |     fn private(&self) {\n   |     ^^^^^^^^^^^^^^^^^\n   |\nnote: first possible panic found here\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:41:9\n   |\nLL |         panic!();\n   |         ^^^^^^^^\nnote: the lint level is defined here\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:4:5\n   |\nLL |     clippy::missing_panics_doc\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unsafe function's docs are missing a `# Safety` section\n  --> tests/ui-toml/private-doc-errors/doc_lints.rs:49:9\n   |\nLL |         pub unsafe fn f() {}\n   |         ^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::missing-safety-doc` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::missing_safety_doc)]`\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/pub_underscore_fields/all_pub_fields/clippy.toml",
    "content": "pub-underscore-fields-behavior = \"AllPubFields\""
  },
  {
    "path": "tests/ui-toml/pub_underscore_fields/exported/clippy.toml",
    "content": "pub-underscore-fields-behavior = \"PubliclyExported\"\n"
  },
  {
    "path": "tests/ui-toml/pub_underscore_fields/pub_underscore_fields.all_pub_fields.stderr",
    "content": "error: field marked as public but also inferred as unused because it's prefixed with `_`\n  --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:15:9\n   |\nLL |         pub _b: u8,\n   |         ^^^^^^\n   |\n   = help: consider removing the underscore, or making the field private\n   = note: `-D clippy::pub-underscore-fields` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pub_underscore_fields)]`\n\nerror: field marked as public but also inferred as unused because it's prefixed with `_`\n  --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:24:13\n   |\nLL |             pub(in crate::inner) _f: Option<()>,\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider removing the underscore, or making the field private\n\nerror: field marked as public but also inferred as unused because it's prefixed with `_`\n  --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:29:13\n   |\nLL |             pub _g: String,\n   |             ^^^^^^\n   |\n   = help: consider removing the underscore, or making the field private\n\nerror: field marked as public but also inferred as unused because it's prefixed with `_`\n  --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:37:9\n   |\nLL |         pub _a: usize,\n   |         ^^^^^^\n   |\n   = help: consider removing the underscore, or making the field private\n\nerror: field marked as public but also inferred as unused because it's prefixed with `_`\n  --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:45:9\n   |\nLL |         pub _c: i64,\n   |         ^^^^^^\n   |\n   = help: consider removing the underscore, or making the field private\n\nerror: field marked as public but also inferred as unused because it's prefixed with `_`\n  --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:49:9\n   |\nLL |         pub _e: Option<u8>,\n   |         ^^^^^^\n   |\n   = help: consider removing the underscore, or making the field private\n\nerror: field marked as public but also inferred as unused because it's prefixed with `_`\n  --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:63:9\n   |\nLL |         pub(crate) _b: Option<String>,\n   |         ^^^^^^^^^^^^^\n   |\n   = help: consider removing the underscore, or making the field private\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/pub_underscore_fields/pub_underscore_fields.exported.stderr",
    "content": "error: field marked as public but also inferred as unused because it's prefixed with `_`\n  --> tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs:15:9\n   |\nLL |         pub _b: u8,\n   |         ^^^^^^\n   |\n   = help: consider removing the underscore, or making the field private\n   = note: `-D clippy::pub-underscore-fields` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::pub_underscore_fields)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/pub_underscore_fields/pub_underscore_fields.rs",
    "content": "//@revisions: exported all_pub_fields\n//@[all_pub_fields] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/pub_underscore_fields/all_pub_fields\n//@[exported] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/pub_underscore_fields/exported\n\n#![allow(unused)]\n#![warn(clippy::pub_underscore_fields)]\n\nuse std::marker::PhantomData;\n\npub mod inner {\n    use std::marker;\n\n    pub struct PubSuper {\n        pub(super) a: usize,\n        pub _b: u8,\n        //~^ pub_underscore_fields\n        _c: i32,\n        pub _mark: marker::PhantomData<u8>,\n    }\n\n    mod inner2 {\n        pub struct PubModVisibility {\n            pub(in crate::inner) e: bool,\n            pub(in crate::inner) _f: Option<()>,\n            //~[all_pub_fields]^ pub_underscore_fields\n        }\n\n        struct PrivateStructPubField {\n            pub _g: String,\n            //~[all_pub_fields]^ pub_underscore_fields\n        }\n    }\n}\n\nfn main() {\n    pub struct StructWithOneViolation {\n        pub _a: usize,\n        //~[all_pub_fields]^ pub_underscore_fields\n    }\n\n    // should handle structs with multiple violations\n    pub struct StructWithMultipleViolations {\n        a: u8,\n        _b: usize,\n        pub _c: i64,\n        //~[all_pub_fields]^ pub_underscore_fields\n        #[doc(hidden)]\n        pub d: String,\n        pub _e: Option<u8>,\n        //~[all_pub_fields]^ pub_underscore_fields\n    }\n\n    // shouldn't warn on anonymous fields\n    pub struct AnonymousFields(pub usize, i32);\n\n    // don't warn on empty structs\n    pub struct Empty1;\n    pub struct Empty2();\n    pub struct Empty3 {};\n\n    pub struct PubCrate {\n        pub(crate) a: String,\n        pub(crate) _b: Option<String>,\n        //~[all_pub_fields]^ pub_underscore_fields\n    }\n\n    // shouldn't warn on fields named pub\n    pub struct NamedPub {\n        r#pub: bool,\n        _pub: String,\n        pub(crate) _mark: PhantomData<u8>,\n    }\n\n    // shouldn't warn when `#[allow]` is used on field level\n    pub struct AllowedViolations {\n        #[allow(clippy::pub_underscore_fields)]\n        pub _first: u32,\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/ref_option/all/clippy.toml",
    "content": "avoid-breaking-exported-api = false\n"
  },
  {
    "path": "tests/ui-toml/ref_option/private/clippy.toml",
    "content": "avoid-breaking-exported-api = true\n"
  },
  {
    "path": "tests/ui-toml/ref_option/ref_option.all.fixed",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: private all\n//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/ref_option/private\n//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/ref_option/all\n\n#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]\n#![warn(clippy::ref_option)]\n\nfn opt_u8(a: Option<&u8>) {}\n//~^ ref_option\nfn opt_gen<T>(a: Option<&T>) {}\n//~^ ref_option\nfn opt_string(a: std::option::Option<&String>) {}\n//~^ ref_option\nfn ret_u8<'a>(p: &'a str) -> Option<&'a u8> {\n    //~^ ref_option\n    panic!()\n}\nfn ret_u8_static() -> Option<&'static u8> {\n    //~^ ref_option\n    panic!()\n}\nfn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}\n//~^ ref_option\nfn ret_box<'a>() -> Option<&'a Box<u8>> {\n    //~^ ref_option\n    panic!()\n}\n\npub fn pub_opt_string(a: Option<&String>) {}\n//~[all]^ ref_option\npub fn pub_mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}\n//~[all]^ ref_option\n\npub struct PubStruct;\n\nimpl PubStruct {\n    pub fn pub_opt_params(&self, a: Option<&()>) {}\n    //~[all]^ ref_option\n    pub fn pub_opt_ret(&self) -> Option<&String> {\n        //~[all]^ ref_option\n        panic!()\n    }\n\n    fn private_opt_params(&self, a: Option<&()>) {}\n    //~^ ref_option\n    fn private_opt_ret(&self) -> Option<&String> {\n        //~^ ref_option\n        panic!()\n    }\n}\n\n// valid, don't change\nfn mut_u8(a: &mut Option<u8>) {}\npub fn pub_mut_u8(a: &mut Option<String>) {}\n\n// might be good to catch in the future\nfn mut_u8_ref(a: &mut &Option<u8>) {}\npub fn pub_mut_u8_ref(a: &mut &Option<String>) {}\nfn lambdas() {\n    // Not handled for now, not sure if we should\n    let x = |a: &Option<String>| {};\n    let x = |a: &Option<String>| -> &Option<String> { panic!() };\n}\n\npub mod external {\n    proc_macros::external!(\n        fn opt_u8(a: &Option<u8>) {}\n        fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\n            panic!()\n        }\n        pub fn pub_opt_u8(a: &Option<u8>) {}\n\n        pub struct PubStruct;\n        impl PubStruct {\n            pub fn pub_opt_params(&self, a: &Option<()>) {}\n            pub fn pub_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n\n            fn private_opt_params(&self, a: &Option<()>) {}\n            fn private_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n        }\n    );\n}\n\npub mod proc_macros {\n    proc_macros::with_span!(\n        span\n\n        fn opt_u8(a: &Option<u8>) {}\n        fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\n            panic!()\n        }\n        pub fn pub_opt_u8(a: &Option<u8>) {}\n\n        pub struct PubStruct;\n        impl PubStruct {\n            pub fn pub_opt_params(&self, a: &Option<()>) {}\n            pub fn pub_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n\n            fn private_opt_params(&self, a: &Option<()>) {}\n            fn private_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n        }\n    );\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/ref_option/ref_option.all.stderr",
    "content": "error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:9:1\n   |\nLL | fn opt_u8(a: &Option<u8>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::ref-option` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`\nhelp: change this to\n   |\nLL - fn opt_u8(a: &Option<u8>) {}\nLL + fn opt_u8(a: Option<&u8>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:11:1\n   |\nLL | fn opt_gen<T>(a: &Option<T>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn opt_gen<T>(a: &Option<T>) {}\nLL + fn opt_gen<T>(a: Option<&T>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:13:1\n   |\nLL | fn opt_string(a: &std::option::Option<String>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn opt_string(a: &std::option::Option<String>) {}\nLL + fn opt_string(a: std::option::Option<&String>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:15:1\n   |\nLL | / fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\nLL | |\nLL | |     panic!()\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL - fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\nLL + fn ret_u8<'a>(p: &'a str) -> Option<&'a u8> {\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:19:1\n   |\nLL | / fn ret_u8_static() -> &'static Option<u8> {\nLL | |\nLL | |     panic!()\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL - fn ret_u8_static() -> &'static Option<u8> {\nLL + fn ret_u8_static() -> Option<&'static u8> {\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:23:1\n   |\nLL | fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\nLL + fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:25:1\n   |\nLL | / fn ret_box<'a>() -> &'a Option<Box<u8>> {\nLL | |\nLL | |     panic!()\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL - fn ret_box<'a>() -> &'a Option<Box<u8>> {\nLL + fn ret_box<'a>() -> Option<&'a Box<u8>> {\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:30:1\n   |\nLL | pub fn pub_opt_string(a: &Option<String>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - pub fn pub_opt_string(a: &Option<String>) {}\nLL + pub fn pub_opt_string(a: Option<&String>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:32:1\n   |\nLL | pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\nLL + pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:38:5\n   |\nLL |     pub fn pub_opt_params(&self, a: &Option<()>) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     pub fn pub_opt_params(&self, a: &Option<()>) {}\nLL +     pub fn pub_opt_params(&self, a: Option<&()>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:40:5\n   |\nLL | /     pub fn pub_opt_ret(&self) -> &Option<String> {\nLL | |\nLL | |         panic!()\nLL | |     }\n   | |_____^\n   |\nhelp: change this to\n   |\nLL -     pub fn pub_opt_ret(&self) -> &Option<String> {\nLL +     pub fn pub_opt_ret(&self) -> Option<&String> {\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:45:5\n   |\nLL |     fn private_opt_params(&self, a: &Option<()>) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn private_opt_params(&self, a: &Option<()>) {}\nLL +     fn private_opt_params(&self, a: Option<&()>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:47:5\n   |\nLL | /     fn private_opt_ret(&self) -> &Option<String> {\nLL | |\nLL | |         panic!()\nLL | |     }\n   | |_____^\n   |\nhelp: change this to\n   |\nLL -     fn private_opt_ret(&self) -> &Option<String> {\nLL +     fn private_opt_ret(&self) -> Option<&String> {\n   |\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/ref_option/ref_option.private.fixed",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: private all\n//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/ref_option/private\n//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/ref_option/all\n\n#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]\n#![warn(clippy::ref_option)]\n\nfn opt_u8(a: Option<&u8>) {}\n//~^ ref_option\nfn opt_gen<T>(a: Option<&T>) {}\n//~^ ref_option\nfn opt_string(a: std::option::Option<&String>) {}\n//~^ ref_option\nfn ret_u8<'a>(p: &'a str) -> Option<&'a u8> {\n    //~^ ref_option\n    panic!()\n}\nfn ret_u8_static() -> Option<&'static u8> {\n    //~^ ref_option\n    panic!()\n}\nfn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}\n//~^ ref_option\nfn ret_box<'a>() -> Option<&'a Box<u8>> {\n    //~^ ref_option\n    panic!()\n}\n\npub fn pub_opt_string(a: &Option<String>) {}\n//~[all]^ ref_option\npub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\n//~[all]^ ref_option\n\npub struct PubStruct;\n\nimpl PubStruct {\n    pub fn pub_opt_params(&self, a: &Option<()>) {}\n    //~[all]^ ref_option\n    pub fn pub_opt_ret(&self) -> &Option<String> {\n        //~[all]^ ref_option\n        panic!()\n    }\n\n    fn private_opt_params(&self, a: Option<&()>) {}\n    //~^ ref_option\n    fn private_opt_ret(&self) -> Option<&String> {\n        //~^ ref_option\n        panic!()\n    }\n}\n\n// valid, don't change\nfn mut_u8(a: &mut Option<u8>) {}\npub fn pub_mut_u8(a: &mut Option<String>) {}\n\n// might be good to catch in the future\nfn mut_u8_ref(a: &mut &Option<u8>) {}\npub fn pub_mut_u8_ref(a: &mut &Option<String>) {}\nfn lambdas() {\n    // Not handled for now, not sure if we should\n    let x = |a: &Option<String>| {};\n    let x = |a: &Option<String>| -> &Option<String> { panic!() };\n}\n\npub mod external {\n    proc_macros::external!(\n        fn opt_u8(a: &Option<u8>) {}\n        fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\n            panic!()\n        }\n        pub fn pub_opt_u8(a: &Option<u8>) {}\n\n        pub struct PubStruct;\n        impl PubStruct {\n            pub fn pub_opt_params(&self, a: &Option<()>) {}\n            pub fn pub_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n\n            fn private_opt_params(&self, a: &Option<()>) {}\n            fn private_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n        }\n    );\n}\n\npub mod proc_macros {\n    proc_macros::with_span!(\n        span\n\n        fn opt_u8(a: &Option<u8>) {}\n        fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\n            panic!()\n        }\n        pub fn pub_opt_u8(a: &Option<u8>) {}\n\n        pub struct PubStruct;\n        impl PubStruct {\n            pub fn pub_opt_params(&self, a: &Option<()>) {}\n            pub fn pub_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n\n            fn private_opt_params(&self, a: &Option<()>) {}\n            fn private_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n        }\n    );\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/ref_option/ref_option.private.stderr",
    "content": "error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:9:1\n   |\nLL | fn opt_u8(a: &Option<u8>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::ref-option` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`\nhelp: change this to\n   |\nLL - fn opt_u8(a: &Option<u8>) {}\nLL + fn opt_u8(a: Option<&u8>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:11:1\n   |\nLL | fn opt_gen<T>(a: &Option<T>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn opt_gen<T>(a: &Option<T>) {}\nLL + fn opt_gen<T>(a: Option<&T>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:13:1\n   |\nLL | fn opt_string(a: &std::option::Option<String>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn opt_string(a: &std::option::Option<String>) {}\nLL + fn opt_string(a: std::option::Option<&String>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:15:1\n   |\nLL | / fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\nLL | |\nLL | |     panic!()\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL - fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\nLL + fn ret_u8<'a>(p: &'a str) -> Option<&'a u8> {\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:19:1\n   |\nLL | / fn ret_u8_static() -> &'static Option<u8> {\nLL | |\nLL | |     panic!()\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL - fn ret_u8_static() -> &'static Option<u8> {\nLL + fn ret_u8_static() -> Option<&'static u8> {\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:23:1\n   |\nLL | fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL - fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\nLL + fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:25:1\n   |\nLL | / fn ret_box<'a>() -> &'a Option<Box<u8>> {\nLL | |\nLL | |     panic!()\nLL | | }\n   | |_^\n   |\nhelp: change this to\n   |\nLL - fn ret_box<'a>() -> &'a Option<Box<u8>> {\nLL + fn ret_box<'a>() -> Option<&'a Box<u8>> {\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:45:5\n   |\nLL |     fn private_opt_params(&self, a: &Option<()>) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn private_opt_params(&self, a: &Option<()>) {}\nLL +     fn private_opt_params(&self, a: Option<&()>) {}\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option.rs:47:5\n   |\nLL | /     fn private_opt_ret(&self) -> &Option<String> {\nLL | |\nLL | |         panic!()\nLL | |     }\n   | |_____^\n   |\nhelp: change this to\n   |\nLL -     fn private_opt_ret(&self) -> &Option<String> {\nLL +     fn private_opt_ret(&self) -> Option<&String> {\n   |\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/ref_option/ref_option.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: private all\n//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/ref_option/private\n//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/ref_option/all\n\n#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]\n#![warn(clippy::ref_option)]\n\nfn opt_u8(a: &Option<u8>) {}\n//~^ ref_option\nfn opt_gen<T>(a: &Option<T>) {}\n//~^ ref_option\nfn opt_string(a: &std::option::Option<String>) {}\n//~^ ref_option\nfn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\n    //~^ ref_option\n    panic!()\n}\nfn ret_u8_static() -> &'static Option<u8> {\n    //~^ ref_option\n    panic!()\n}\nfn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\n//~^ ref_option\nfn ret_box<'a>() -> &'a Option<Box<u8>> {\n    //~^ ref_option\n    panic!()\n}\n\npub fn pub_opt_string(a: &Option<String>) {}\n//~[all]^ ref_option\npub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}\n//~[all]^ ref_option\n\npub struct PubStruct;\n\nimpl PubStruct {\n    pub fn pub_opt_params(&self, a: &Option<()>) {}\n    //~[all]^ ref_option\n    pub fn pub_opt_ret(&self) -> &Option<String> {\n        //~[all]^ ref_option\n        panic!()\n    }\n\n    fn private_opt_params(&self, a: &Option<()>) {}\n    //~^ ref_option\n    fn private_opt_ret(&self) -> &Option<String> {\n        //~^ ref_option\n        panic!()\n    }\n}\n\n// valid, don't change\nfn mut_u8(a: &mut Option<u8>) {}\npub fn pub_mut_u8(a: &mut Option<String>) {}\n\n// might be good to catch in the future\nfn mut_u8_ref(a: &mut &Option<u8>) {}\npub fn pub_mut_u8_ref(a: &mut &Option<String>) {}\nfn lambdas() {\n    // Not handled for now, not sure if we should\n    let x = |a: &Option<String>| {};\n    let x = |a: &Option<String>| -> &Option<String> { panic!() };\n}\n\npub mod external {\n    proc_macros::external!(\n        fn opt_u8(a: &Option<u8>) {}\n        fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\n            panic!()\n        }\n        pub fn pub_opt_u8(a: &Option<u8>) {}\n\n        pub struct PubStruct;\n        impl PubStruct {\n            pub fn pub_opt_params(&self, a: &Option<()>) {}\n            pub fn pub_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n\n            fn private_opt_params(&self, a: &Option<()>) {}\n            fn private_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n        }\n    );\n}\n\npub mod proc_macros {\n    proc_macros::with_span!(\n        span\n\n        fn opt_u8(a: &Option<u8>) {}\n        fn ret_u8<'a>(p: &'a str) -> &'a Option<u8> {\n            panic!()\n        }\n        pub fn pub_opt_u8(a: &Option<u8>) {}\n\n        pub struct PubStruct;\n        impl PubStruct {\n            pub fn pub_opt_params(&self, a: &Option<()>) {}\n            pub fn pub_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n\n            fn private_opt_params(&self, a: &Option<()>) {}\n            fn private_opt_ret(&self) -> &Option<String> {\n                panic!()\n            }\n        }\n    );\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/ref_option/ref_option_traits.all.stderr",
    "content": "error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option_traits.rs:10:5\n   |\nLL |     fn pub_trait_opt(&self, a: &Option<Vec<u8>>);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::ref-option` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`\nhelp: change this to\n   |\nLL -     fn pub_trait_opt(&self, a: &Option<Vec<u8>>);\nLL +     fn pub_trait_opt(&self, a: Option<&Vec<u8>>);\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option_traits.rs:12:5\n   |\nLL |     fn pub_trait_ret(&self) -> &Option<Vec<u8>>;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn pub_trait_ret(&self) -> &Option<Vec<u8>>;\nLL +     fn pub_trait_ret(&self) -> Option<&Vec<u8>>;\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option_traits.rs:17:5\n   |\nLL |     fn trait_opt(&self, a: &Option<String>);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn trait_opt(&self, a: &Option<String>);\nLL +     fn trait_opt(&self, a: Option<&String>);\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option_traits.rs:19:5\n   |\nLL |     fn trait_ret(&self) -> &Option<String>;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn trait_ret(&self) -> &Option<String>;\nLL +     fn trait_ret(&self) -> Option<&String>;\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/ref_option/ref_option_traits.private.stderr",
    "content": "error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option_traits.rs:17:5\n   |\nLL |     fn trait_opt(&self, a: &Option<String>);\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::ref-option` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`\nhelp: change this to\n   |\nLL -     fn trait_opt(&self, a: &Option<String>);\nLL +     fn trait_opt(&self, a: Option<&String>);\n   |\n\nerror: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`\n  --> tests/ui-toml/ref_option/ref_option_traits.rs:19:5\n   |\nLL |     fn trait_ret(&self) -> &Option<String>;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: change this to\n   |\nLL -     fn trait_ret(&self) -> &Option<String>;\nLL +     fn trait_ret(&self) -> Option<&String>;\n   |\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/ref_option/ref_option_traits.rs",
    "content": "//@no-rustfix: fixes are only done to traits, not the impls\n//@aux-build:../../ui/auxiliary/proc_macros.rs\n//@revisions: private all\n//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/ref_option/private\n//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/ref_option/all\n\n#![warn(clippy::ref_option)]\n\npub trait PubTrait {\n    fn pub_trait_opt(&self, a: &Option<Vec<u8>>);\n    //~[all]^ ref_option\n    fn pub_trait_ret(&self) -> &Option<Vec<u8>>;\n    //~[all]^ ref_option\n}\n\ntrait PrivateTrait {\n    fn trait_opt(&self, a: &Option<String>);\n    //~^ ref_option\n    fn trait_ret(&self) -> &Option<String>;\n    //~^ ref_option\n}\n\npub struct PubStruct;\n\nimpl PubTrait for PubStruct {\n    fn pub_trait_opt(&self, a: &Option<Vec<u8>>) {}\n    fn pub_trait_ret(&self) -> &Option<Vec<u8>> {\n        panic!()\n    }\n}\n\nstruct PrivateStruct;\n\nimpl PrivateTrait for PrivateStruct {\n    fn trait_opt(&self, a: &Option<String>) {}\n    fn trait_ret(&self) -> &Option<String> {\n        panic!()\n    }\n}\n\npub mod external {\n    proc_macros::external!(\n        pub trait PubTrait {\n            fn pub_trait_opt(&self, a: &Option<Vec<u8>>);\n            fn pub_trait_ret(&self) -> &Option<Vec<u8>>;\n        }\n\n        trait PrivateTrait {\n            fn trait_opt(&self, a: &Option<String>);\n            fn trait_ret(&self) -> &Option<String>;\n        }\n    );\n}\n\npub mod proc_macros {\n    proc_macros::with_span!(\n        span\n\n        pub trait PubTrait {\n            fn pub_trait_opt(&self, a: &Option<Vec<u8>>);\n            fn pub_trait_ret(&self) -> &Option<Vec<u8>>;\n        }\n\n        trait PrivateTrait {\n            fn trait_opt(&self, a: &Option<String>);\n            fn trait_ret(&self) -> &Option<String>;\n        }\n    );\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/renamed_function_params/default/clippy.toml",
    "content": "# Ignore `From`, `TryFrom`, `FromStr` by default\n# allow-renamed-params-for = []\n"
  },
  {
    "path": "tests/ui-toml/renamed_function_params/extend/clippy.toml",
    "content": "# Ignore `From`, `TryFrom`, `FromStr` by default\nallow-renamed-params-for = [ \"..\", \"std::ops::Add\", \"renamed_function_params::MyTrait\" ]\n"
  },
  {
    "path": "tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr",
    "content": "error: renamed function parameter of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:30:18\n   |\nLL |     fn eq(&self, rhs: &Self) -> bool {\n   |                  ^^^\n   |\n   = note: `-D clippy::renamed-function-params` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::renamed_function_params)]`\nhelp: consider using the default name\n   |\nLL -     fn eq(&self, rhs: &Self) -> bool {\nLL +     fn eq(&self, other: &Self) -> bool {\n   |\n\nerror: renamed function parameter of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:34:18\n   |\nLL |     fn ne(&self, rhs: &Self) -> bool {\n   |                  ^^^\n   |\nhelp: consider using the default name\n   |\nLL -     fn ne(&self, rhs: &Self) -> bool {\nLL +     fn ne(&self, other: &Self) -> bool {\n   |\n\nerror: renamed function parameter of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:48:19\n   |\nLL |     fn foo(&self, i_dont_wanna_use_your_name: u8) {} // only lint in `extend`\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider using the default name\n   |\nLL -     fn foo(&self, i_dont_wanna_use_your_name: u8) {} // only lint in `extend`\nLL +     fn foo(&self, val: u8) {} // only lint in `extend`\n   |\n\nerror: renamed function parameter of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:57:31\n   |\nLL |     fn hash<H: Hasher>(&self, states: &mut H) {\n   |                               ^^^^^^\n   |\nhelp: consider using the default name\n   |\nLL -     fn hash<H: Hasher>(&self, states: &mut H) {\nLL +     fn hash<H: Hasher>(&self, state: &mut H) {\n   |\n\nerror: renamed function parameters of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:61:30\n   |\nLL |     fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {\n   |                              ^^^^           ^^^^^^\n   |\nhelp: consider using the default names\n   |\nLL -     fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {\nLL +     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) {\n   |\n\nerror: renamed function parameter of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:82:18\n   |\nLL |     fn add(self, b: B) -> C {\n   |                  ^\n   |\nhelp: consider using the default name\n   |\nLL -     fn add(self, b: B) -> C {\nLL +     fn add(self, rhs: B) -> C {\n   |\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr",
    "content": "error: renamed function parameter of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:30:18\n   |\nLL |     fn eq(&self, rhs: &Self) -> bool {\n   |                  ^^^\n   |\n   = note: `-D clippy::renamed-function-params` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::renamed_function_params)]`\nhelp: consider using the default name\n   |\nLL -     fn eq(&self, rhs: &Self) -> bool {\nLL +     fn eq(&self, other: &Self) -> bool {\n   |\n\nerror: renamed function parameter of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:34:18\n   |\nLL |     fn ne(&self, rhs: &Self) -> bool {\n   |                  ^^^\n   |\nhelp: consider using the default name\n   |\nLL -     fn ne(&self, rhs: &Self) -> bool {\nLL +     fn ne(&self, other: &Self) -> bool {\n   |\n\nerror: renamed function parameter of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:57:31\n   |\nLL |     fn hash<H: Hasher>(&self, states: &mut H) {\n   |                               ^^^^^^\n   |\nhelp: consider using the default name\n   |\nLL -     fn hash<H: Hasher>(&self, states: &mut H) {\nLL +     fn hash<H: Hasher>(&self, state: &mut H) {\n   |\n\nerror: renamed function parameters of trait impl\n  --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:61:30\n   |\nLL |     fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {\n   |                              ^^^^           ^^^^^^\n   |\nhelp: consider using the default names\n   |\nLL -     fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {\nLL +     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) {\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/renamed_function_params/renamed_function_params.rs",
    "content": "//@no-rustfix\n//@revisions: default extend\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/renamed_function_params/default\n//@[extend] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/renamed_function_params/extend\n#![warn(clippy::renamed_function_params)]\n#![allow(clippy::partialeq_ne_impl, clippy::to_string_trait_impl)]\n#![allow(unused)]\n\nuse std::hash::{Hash, Hasher};\n\nstruct A;\nimpl From<A> for String {\n    fn from(_value: A) -> Self {\n        String::new()\n    }\n}\nimpl ToString for A {\n    fn to_string(&self) -> String {\n        String::new()\n    }\n}\n\nstruct B(u32);\nimpl std::convert::From<B> for String {\n    fn from(b: B) -> Self {\n        b.0.to_string()\n    }\n}\nimpl PartialEq for B {\n    fn eq(&self, rhs: &Self) -> bool {\n        //~^ renamed_function_params\n        self.0 == rhs.0\n    }\n    fn ne(&self, rhs: &Self) -> bool {\n        //~^ renamed_function_params\n        self.0 != rhs.0\n    }\n}\n\ntrait MyTrait {\n    fn foo(&self, val: u8);\n    fn bar(a: u8, b: u8);\n    fn baz(self, _val: u8);\n    fn quz(&self, _: u8);\n}\n\nimpl MyTrait for B {\n    fn foo(&self, i_dont_wanna_use_your_name: u8) {} // only lint in `extend`\n    //\n    //~[default]^^ renamed_function_params\n    fn bar(_a: u8, _: u8) {}\n    fn baz(self, val: u8) {}\n    fn quz(&self, val: u8) {}\n}\n\nimpl Hash for B {\n    fn hash<H: Hasher>(&self, states: &mut H) {\n        //~^ renamed_function_params\n        self.0.hash(states);\n    }\n    fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {\n        //~^ renamed_function_params\n        for d in date {\n            d.hash(states);\n        }\n    }\n}\n\nimpl B {\n    fn totally_irrelevant(&self, right: bool) {}\n    fn some_fn(&self, other: impl MyTrait) {}\n}\n\n#[derive(Copy, Clone)]\nenum C {\n    A,\n    B(u32),\n}\n\nimpl std::ops::Add<B> for C {\n    type Output = C;\n    fn add(self, b: B) -> C {\n        //~[default]^ renamed_function_params\n        // only lint in `extend`\n        C::B(b.0)\n    }\n}\n\nimpl From<A> for C {\n    fn from(_: A) -> C {\n        C::A\n    }\n}\n\ntrait CustomTraitA {\n    fn foo(&self, other: u32);\n}\ntrait CustomTraitB {\n    fn bar(&self, value: u8);\n}\n\nmacro_rules! impl_trait {\n    ($impl_for:ident, $tr:ty, $fn_name:ident, $t:ty) => {\n        impl $tr for $impl_for {\n            fn $fn_name(&self, v: $t) {}\n        }\n    };\n}\n\nimpl_trait!(C, CustomTraitA, foo, u32);\nimpl_trait!(C, CustomTraitB, bar, u8);\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/replaceable_disallowed_types/clippy.toml",
    "content": "disallowed-types = [\n    { path = \"std::string::String\", replacement = \"wrapper::String\" },\n]\n"
  },
  {
    "path": "tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.fixed",
    "content": "#![warn(clippy::disallowed_types)]\n\n#[allow(clippy::disallowed_types)]\nmod wrapper {\n    pub struct String(std::string::String);\n\n    impl From<&str> for String {\n        fn from(value: &str) -> Self {\n            Self(std::string::String::from(value))\n        }\n    }\n}\n\nfn main() {\n    let _ = wrapper::String::from(\"x\");\n    //~^ disallowed_types\n}\n"
  },
  {
    "path": "tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs",
    "content": "#![warn(clippy::disallowed_types)]\n\n#[allow(clippy::disallowed_types)]\nmod wrapper {\n    pub struct String(std::string::String);\n\n    impl From<&str> for String {\n        fn from(value: &str) -> Self {\n            Self(std::string::String::from(value))\n        }\n    }\n}\n\nfn main() {\n    let _ = String::from(\"x\");\n    //~^ disallowed_types\n}\n"
  },
  {
    "path": "tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.stderr",
    "content": "error: use of a disallowed type `std::string::String`\n  --> tests/ui-toml/replaceable_disallowed_types/replaceable_disallowed_types.rs:15:13\n   |\nLL |     let _ = String::from(\"x\");\n   |             ^^^^^^ help: use: `wrapper::String`\n   |\n   = note: `-D clippy::disallowed-types` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_types)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/result_large_err/clippy.toml",
    "content": "large-error-threshold = 512\nlarge-error-ignored = [\"result_large_err::IgnoredError\", \"result_large_err::IgnoredErrorEnum\"]\n"
  },
  {
    "path": "tests/ui-toml/result_large_err/result_large_err.rs",
    "content": "//@compile-flags: --crate-name result_large_err\n#![warn(clippy::result_large_err)]\n#![allow(clippy::large_enum_variant)]\n\nfn f() -> Result<(), [u8; 511]> {\n    todo!()\n}\nfn f2() -> Result<(), [u8; 512]> {\n    //~^ ERROR: the `Err`-variant returned from this function is very large\n    todo!()\n}\n\nstruct IgnoredError {\n    inner: [u8; 512],\n}\n\nfn f3() -> Result<(), IgnoredError> {\n    todo!()\n}\n\nenum IgnoredErrorEnum {\n    V1,\n    V2 { inner: [u8; 512] },\n}\n\nfn f4() -> Result<(), IgnoredErrorEnum> {\n    todo!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/result_large_err/result_large_err.stderr",
    "content": "error: the `Err`-variant returned from this function is very large\n  --> tests/ui-toml/result_large_err/result_large_err.rs:8:12\n   |\nLL | fn f2() -> Result<(), [u8; 512]> {\n   |            ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes\n   |\n   = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`\n   = note: `-D clippy::result-large-err` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::result_large_err)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/both.fixed",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop\n)]\n#![warn(clippy::semicolon_inside_block)]\n#![warn(clippy::semicolon_outside_block)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    unsafe { unit_fn_block() };\n\n    { unit_fn_block() };\n    //~^ semicolon_outside_block\n    unsafe { unit_fn_block() };\n    //~^ semicolon_outside_block\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n    //~^ semicolon_inside_block\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    { m!(()) };\n    //~^ semicolon_outside_block\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unit_fn_block()\n}\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/both.rs",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop\n)]\n#![warn(clippy::semicolon_inside_block)]\n#![warn(clippy::semicolon_outside_block)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    unsafe { unit_fn_block() };\n\n    { unit_fn_block(); }\n    //~^ semicolon_outside_block\n    unsafe { unit_fn_block(); }\n    //~^ semicolon_outside_block\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n    //~^ semicolon_inside_block\n        unit_fn_block();\n        unit_fn_block()\n    };\n    {\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    { m!(()); }\n    //~^ semicolon_outside_block\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unit_fn_block()\n}\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/both.stderr",
    "content": "error: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui-toml/semicolon_block/both.rs:42:5\n   |\nLL |     { unit_fn_block(); }\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::semicolon-outside-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::semicolon_outside_block)]`\nhelp: put the `;` here\n   |\nLL -     { unit_fn_block(); }\nLL +     { unit_fn_block() };\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui-toml/semicolon_block/both.rs:44:5\n   |\nLL |     unsafe { unit_fn_block(); }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: put the `;` here\n   |\nLL -     unsafe { unit_fn_block(); }\nLL +     unsafe { unit_fn_block() };\n   |\n\nerror: consider moving the `;` inside the block for consistent formatting\n  --> tests/ui-toml/semicolon_block/both.rs:50:5\n   |\nLL | /     {\nLL | |\nLL | |         unit_fn_block();\nLL | |         unit_fn_block()\nLL | |     };\n   | |______^\n   |\n   = note: `-D clippy::semicolon-inside-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::semicolon_inside_block)]`\nhelp: put the `;` here\n   |\nLL ~         unit_fn_block();\nLL ~     }\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui-toml/semicolon_block/both.rs:65:5\n   |\nLL |     { m!(()); }\n   |     ^^^^^^^^^^^\n   |\nhelp: put the `;` here\n   |\nLL -     { m!(()); }\nLL +     { m!(()) };\n   |\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/clippy.toml",
    "content": "semicolon-inside-block-ignore-singleline = true\nsemicolon-outside-block-ignore-multiline = true\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/semicolon_inside_block.fixed",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop\n)]\n#![warn(clippy::semicolon_inside_block)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    unsafe { unit_fn_block() };\n\n    { unit_fn_block(); }\n    unsafe { unit_fn_block(); }\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n    //~^ semicolon_inside_block\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    { m!(()); }\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unit_fn_block()\n}\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/semicolon_inside_block.rs",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop\n)]\n#![warn(clippy::semicolon_inside_block)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    unsafe { unit_fn_block() };\n\n    { unit_fn_block(); }\n    unsafe { unit_fn_block(); }\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n    //~^ semicolon_inside_block\n        unit_fn_block();\n        unit_fn_block()\n    };\n    {\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    { m!(()); }\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unit_fn_block()\n}\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/semicolon_inside_block.stderr",
    "content": "error: consider moving the `;` inside the block for consistent formatting\n  --> tests/ui-toml/semicolon_block/semicolon_inside_block.rs:47:5\n   |\nLL | /     {\nLL | |\nLL | |         unit_fn_block();\nLL | |         unit_fn_block()\nLL | |     };\n   | |______^\n   |\n   = note: `-D clippy::semicolon-inside-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::semicolon_inside_block)]`\nhelp: put the `;` here\n   |\nLL ~         unit_fn_block();\nLL ~     }\n   |\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/semicolon_outside_block.fixed",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop\n)]\n#![warn(clippy::semicolon_outside_block)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    unsafe { unit_fn_block() };\n\n    { unit_fn_block() };\n    //~^ semicolon_outside_block\n    unsafe { unit_fn_block() };\n    //~^ semicolon_outside_block\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n        unit_fn_block();\n        unit_fn_block()\n    };\n    {\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    { m!(()) };\n    //~^ semicolon_outside_block\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unit_fn_block()\n}\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/semicolon_outside_block.rs",
    "content": "#![allow(\n    unused,\n    clippy::unused_unit,\n    clippy::unnecessary_operation,\n    clippy::no_effect,\n    clippy::single_element_loop\n)]\n#![warn(clippy::semicolon_outside_block)]\n\nmacro_rules! m {\n    (()) => {\n        ()\n    };\n    (0) => {{\n        0\n    };};\n    (1) => {{\n        1;\n    }};\n    (2) => {{\n        2;\n    }};\n}\n\nfn unit_fn_block() {\n    ()\n}\n\n#[rustfmt::skip]\nfn main() {\n    { unit_fn_block() }\n    unsafe { unit_fn_block() }\n\n    {\n        unit_fn_block()\n    }\n\n    { unit_fn_block() };\n    unsafe { unit_fn_block() };\n\n    { unit_fn_block(); }\n    //~^ semicolon_outside_block\n    unsafe { unit_fn_block(); }\n    //~^ semicolon_outside_block\n\n    { unit_fn_block(); };\n    unsafe { unit_fn_block(); };\n\n    {\n        unit_fn_block();\n        unit_fn_block()\n    };\n    {\n        unit_fn_block();\n        unit_fn_block();\n    }\n    {\n        unit_fn_block();\n        unit_fn_block();\n    };\n\n    { m!(()) };\n    { m!(()); }\n    //~^ semicolon_outside_block\n    { m!(()); };\n    m!(0);\n    m!(1);\n    m!(2);\n\n    for _ in [()] {\n        unit_fn_block();\n    }\n    for _ in [()] {\n        unit_fn_block()\n    }\n\n    let _d = || {\n        unit_fn_block();\n    };\n    let _d = || {\n        unit_fn_block()\n    };\n\n    { unit_fn_block(); };\n\n    unit_fn_block()\n}\n"
  },
  {
    "path": "tests/ui-toml/semicolon_block/semicolon_outside_block.stderr",
    "content": "error: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui-toml/semicolon_block/semicolon_outside_block.rs:41:5\n   |\nLL |     { unit_fn_block(); }\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::semicolon-outside-block` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::semicolon_outside_block)]`\nhelp: put the `;` here\n   |\nLL -     { unit_fn_block(); }\nLL +     { unit_fn_block() };\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui-toml/semicolon_block/semicolon_outside_block.rs:43:5\n   |\nLL |     unsafe { unit_fn_block(); }\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: put the `;` here\n   |\nLL -     unsafe { unit_fn_block(); }\nLL +     unsafe { unit_fn_block() };\n   |\n\nerror: consider moving the `;` outside the block for consistent formatting\n  --> tests/ui-toml/semicolon_block/semicolon_outside_block.rs:63:5\n   |\nLL |     { m!(()); }\n   |     ^^^^^^^^^^^\n   |\nhelp: put the `;` here\n   |\nLL -     { m!(()); }\nLL +     { m!(()) };\n   |\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/strict_non_send_fields_in_send_ty/clippy.toml",
    "content": "enable-raw-pointer-heuristic-for-send = false\n"
  },
  {
    "path": "tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs",
    "content": "#![warn(clippy::non_send_fields_in_send_ty)]\n#![feature(extern_types)]\n\nuse std::rc::Rc;\n\n// Basic tests should not be affected\npub struct NoGeneric {\n    rc_is_not_send: Rc<String>,\n}\n\nunsafe impl Send for NoGeneric {}\n//~^ non_send_fields_in_send_ty\n\npub struct MultiField<T> {\n    field1: T,\n    field2: T,\n    field3: T,\n}\n\nunsafe impl<T> Send for MultiField<T> {}\n//~^ non_send_fields_in_send_ty\n\npub enum MyOption<T> {\n    MySome(T),\n    MyNone,\n}\n\nunsafe impl<T> Send for MyOption<T> {}\n//~^ non_send_fields_in_send_ty\n\n// All fields are disallowed when raw pointer heuristic is off\nunsafe extern \"C\" {\n    type NonSend;\n}\n\npub struct HeuristicTest {\n    field1: Vec<*const NonSend>,\n    field2: [*const NonSend; 3],\n    field3: (*const NonSend, *const NonSend, *const NonSend),\n    field4: (*const NonSend, Rc<u8>),\n    field5: Vec<Vec<*const NonSend>>,\n}\n\nunsafe impl Send for HeuristicTest {}\n//~^ non_send_fields_in_send_ty\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr",
    "content": "error: some fields in `NoGeneric` are not safe to be sent to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:11:1\n   |\nLL | unsafe impl Send for NoGeneric {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `rc_is_not_send` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:8:5\n   |\nLL |     rc_is_not_send: Rc<String>,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\n   = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::non_send_fields_in_send_ty)]`\n\nerror: some fields in `MultiField<T>` are not safe to be sent to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:20:1\n   |\nLL | unsafe impl<T> Send for MultiField<T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `field1` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:15:5\n   |\nLL |     field1: T,\n   |     ^^^^^^^^^\n   = help: add `T: Send` bound in `Send` impl\nnote: it is not safe to send field `field2` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:16:5\n   |\nLL |     field2: T,\n   |     ^^^^^^^^^\n   = help: add `T: Send` bound in `Send` impl\nnote: it is not safe to send field `field3` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:17:5\n   |\nLL |     field3: T,\n   |     ^^^^^^^^^\n   = help: add `T: Send` bound in `Send` impl\n\nerror: some fields in `MyOption<T>` are not safe to be sent to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:28:1\n   |\nLL | unsafe impl<T> Send for MyOption<T> {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `0` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:24:12\n   |\nLL |     MySome(T),\n   |            ^\n   = help: add `T: Send` bound in `Send` impl\n\nerror: some fields in `HeuristicTest` are not safe to be sent to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:44:1\n   |\nLL | unsafe impl Send for HeuristicTest {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nnote: it is not safe to send field `field1` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:37:5\n   |\nLL |     field1: Vec<*const NonSend>,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\nnote: it is not safe to send field `field2` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:38:5\n   |\nLL |     field2: [*const NonSend; 3],\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\nnote: it is not safe to send field `field3` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:39:5\n   |\nLL |     field3: (*const NonSend, *const NonSend, *const NonSend),\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\nnote: it is not safe to send field `field4` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:40:5\n   |\nLL |     field4: (*const NonSend, Rc<u8>),\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\nnote: it is not safe to send field `field5` to another thread\n  --> tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs:41:5\n   |\nLL |     field5: Vec<Vec<*const NonSend>>,\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   = help: use a thread-safe type that implements `Send`\n\nerror: aborting due to 4 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/struct_excessive_bools/clippy.toml",
    "content": "max-struct-bools = 0\n"
  },
  {
    "path": "tests/ui-toml/struct_excessive_bools/test.rs",
    "content": "#![warn(clippy::struct_excessive_bools)]\n\nstruct S {\n    //~^ struct_excessive_bools\n    a: bool,\n}\n\nstruct Foo;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/struct_excessive_bools/test.stderr",
    "content": "error: more than 0 bools in a struct\n  --> tests/ui-toml/struct_excessive_bools/test.rs:3:1\n   |\nLL | / struct S {\nLL | |\nLL | |     a: bool,\nLL | | }\n   | |_^\n   |\n   = help: consider using a state machine or refactoring bools into two-variant enums\n   = note: `-D clippy::struct-excessive-bools` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::struct_excessive_bools)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/suppress_lint_in_const/clippy.toml",
    "content": "suppress-restriction-lint-in-const = true\n"
  },
  {
    "path": "tests/ui-toml/suppress_lint_in_const/test.rs",
    "content": "#![warn(clippy::indexing_slicing)]\n// We also check the out_of_bounds_indexing lint here, because it lints similar things and\n// we want to avoid false positives.\n#![warn(clippy::out_of_bounds_indexing)]\n#![allow(\n    unconditional_panic,\n    clippy::no_effect,\n    clippy::unnecessary_operation,\n    clippy::useless_vec,\n    clippy::out_of_bounds_indexing,\n    clippy::needless_lifetimes\n)]\n\nconst ARR: [i32; 2] = [1, 2];\nconst REF: &i32 = &ARR[idx()]; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.\n\nconst fn idx() -> usize {\n    1\n}\nconst fn idx4() -> usize {\n    4\n}\n\nfn main() {\n    let x = [1, 2, 3, 4];\n    let index: usize = 1;\n    x[index];\n    //~^ indexing_slicing\n    x[4]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.\n    x[1 << 3]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.\n\n    x[0]; // Ok, should not produce stderr.\n    x[3]; // Ok, should not produce stderr.\n    x[const { idx() }]; // Ok, should not produce stderr.\n    x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.\n    const { &ARR[idx()] }; // Ok, should not produce stderr, since `suppress-restriction-lint-in-const` is set true.\n\n    let y = &x;\n    y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021\n    y[4]; // Ok, rustc will handle references too.\n\n    let v = vec![0; 5];\n    v[0];\n    //~^ indexing_slicing\n    v[10];\n    //~^ indexing_slicing\n    v[1 << 3];\n    //~^ indexing_slicing\n\n    const N: usize = 15; // Out of bounds\n    const M: usize = 3; // In bounds\n    x[N]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.\n    x[M]; // Ok, should not produce stderr.\n    v[N];\n    //~^ indexing_slicing\n    v[M];\n    //~^ indexing_slicing\n}\n\n/// An opaque integer representation\npub struct Integer<'a> {\n    /// The underlying data\n    value: &'a [u8],\n}\nimpl<'a> Integer<'a> {\n    // Check whether `self` holds a negative number or not\n    pub const fn is_negative(&self) -> bool {\n        self.value[0] & 0b1000_0000 != 0\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/suppress_lint_in_const/test.stderr",
    "content": "error: indexing may panic\n  --> tests/ui-toml/suppress_lint_in_const/test.rs:27:5\n   |\nLL |     x[index];\n   |     ^^^^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n   = note: `-D clippy::indexing-slicing` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`\n\nerror: indexing may panic\n  --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5\n   |\nLL |     v[0];\n   |     ^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui-toml/suppress_lint_in_const/test.rs:45:5\n   |\nLL |     v[10];\n   |     ^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui-toml/suppress_lint_in_const/test.rs:47:5\n   |\nLL |     v[1 << 3];\n   |     ^^^^^^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui-toml/suppress_lint_in_const/test.rs:54:5\n   |\nLL |     v[N];\n   |     ^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: indexing may panic\n  --> tests/ui-toml/suppress_lint_in_const/test.rs:56:5\n   |\nLL |     v[M];\n   |     ^^^^\n   |\n   = help: consider using `.get(n)` or `.get_mut(n)` instead\n\nerror: aborting due to 6 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_disallow/clippy.toml",
    "content": "disallowed-names = [\"toto\", \"tata\", \"titi\"]\n"
  },
  {
    "path": "tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs",
    "content": "#![allow(dead_code)]\n#![allow(clippy::single_match)]\n#![allow(unused_variables)]\n#![warn(clippy::disallowed_names)]\n\nfn test(toto: ()) {}\n//~^ disallowed_names\n\nfn main() {\n    let toto = 42;\n    //~^ disallowed_names\n    let tata = 42;\n    //~^ disallowed_names\n    let titi = 42;\n    //~^ disallowed_names\n\n    let tatab = 42;\n    let tatatataic = 42;\n\n    match (42, Some(1337), Some(0)) {\n        (toto, Some(tata), titi @ Some(_)) => (),\n        //~^ disallowed_names\n        //~| disallowed_names\n        //~| disallowed_names\n        _ => (),\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_disallow/conf_french_disallowed_name.stderr",
    "content": "error: use of a disallowed/placeholder name `toto`\n  --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:6:9\n   |\nLL | fn test(toto: ()) {}\n   |         ^^^^\n   |\n   = note: `-D clippy::disallowed-names` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_names)]`\n\nerror: use of a disallowed/placeholder name `toto`\n  --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:10:9\n   |\nLL |     let toto = 42;\n   |         ^^^^\n\nerror: use of a disallowed/placeholder name `tata`\n  --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:12:9\n   |\nLL |     let tata = 42;\n   |         ^^^^\n\nerror: use of a disallowed/placeholder name `titi`\n  --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:14:9\n   |\nLL |     let titi = 42;\n   |         ^^^^\n\nerror: use of a disallowed/placeholder name `toto`\n  --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:21:10\n   |\nLL |         (toto, Some(tata), titi @ Some(_)) => (),\n   |          ^^^^\n\nerror: use of a disallowed/placeholder name `tata`\n  --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:21:21\n   |\nLL |         (toto, Some(tata), titi @ Some(_)) => (),\n   |                     ^^^^\n\nerror: use of a disallowed/placeholder name `titi`\n  --> tests/ui-toml/toml_disallow/conf_french_disallowed_name.rs:21:28\n   |\nLL |         (toto, Some(tata), titi @ Some(_)) => (),\n   |                            ^^^^\n\nerror: aborting due to 7 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_fields/clippy.toml",
    "content": "disallowed-fields = [\n    # just a string is shorthand for path only\n    \"std::ops::Range::start\",\n    # can give path and reason with an inline table\n    { path = \"std::ops::Range::end\", reason = \"no end allowed\" },\n    # can use an inline table but omit reason\n    { path = \"std::ops::RangeTo::end\" },\n    # local paths\n    \"conf_disallowed_fields::X::y\",\n    # re-exports\n    \"conf_disallowed_fields::Y::y\",\n    # field of a variant\n    \"conf_disallowed_fields::Z::B::x\",\n]\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs",
    "content": "#![warn(clippy::disallowed_fields)]\n#![allow(clippy::match_single_binding)]\n\nuse std::ops::{Range, RangeTo};\n\nstruct X {\n    y: u32,\n}\n\nenum Z {\n    A { x: u32 },\n    B { x: u32 },\n}\n\nuse crate::X as Y;\n\nfn b(X { y }: X) {}\n//~^ disallowed_fields\n\nfn main() {\n    let x = X { y: 0 };\n    let _ = x.y;\n    //~^ disallowed_fields\n\n    let x = Y { y: 0 };\n    let _ = x.y;\n    //~^ disallowed_fields\n\n    let x = Range { start: 0, end: 0 };\n    let _ = x.start;\n    //~^ disallowed_fields\n    let _ = x.end;\n    //~^ disallowed_fields\n    let Range { start, .. } = x;\n    //~^ disallowed_fields\n\n    let x = RangeTo { end: 0 };\n    let _ = x.end;\n    //~^ disallowed_fields\n\n    match x {\n        RangeTo { end } => {}, //~ disallowed_fields\n    }\n\n    let x = Z::B { x: 0 };\n    match x {\n        Z::A { x } => {},\n        Z::B { x } => {}, //~ disallowed_fields\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.stderr",
    "content": "error: use of a disallowed field `conf_disallowed_fields::Y::y`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:17:10\n   |\nLL | fn b(X { y }: X) {}\n   |          ^\n   |\n   = note: `-D clippy::disallowed-fields` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_fields)]`\n\nerror: use of a disallowed field `conf_disallowed_fields::Y::y`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:22:15\n   |\nLL |     let _ = x.y;\n   |               ^\n\nerror: use of a disallowed field `conf_disallowed_fields::Y::y`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:26:15\n   |\nLL |     let _ = x.y;\n   |               ^\n\nerror: use of a disallowed field `std::ops::Range::start`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:30:15\n   |\nLL |     let _ = x.start;\n   |               ^^^^^\n\nerror: use of a disallowed field `std::ops::Range::end`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:32:15\n   |\nLL |     let _ = x.end;\n   |               ^^^\n   |\n   = note: no end allowed\n\nerror: use of a disallowed field `std::ops::Range::start`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:34:17\n   |\nLL |     let Range { start, .. } = x;\n   |                 ^^^^^\n\nerror: use of a disallowed field `std::ops::RangeTo::end`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:38:15\n   |\nLL |     let _ = x.end;\n   |               ^^^\n\nerror: use of a disallowed field `std::ops::RangeTo::end`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:42:19\n   |\nLL |         RangeTo { end } => {},\n   |                   ^^^\n\nerror: use of a disallowed field `conf_disallowed_fields::Z::B::x`\n  --> tests/ui-toml/toml_disallowed_fields/conf_disallowed_fields.rs:48:16\n   |\nLL |         Z::B { x } => {},\n   |                ^\n\nerror: aborting due to 9 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_methods/clippy.toml",
    "content": "disallowed-methods = [\n    # just a string is shorthand for path only\n    \"std::iter::Iterator::sum\",\n    \"f32::clamp\",\n    \"slice::sort_unstable\",\n    \"futures::stream::select_all\",\n    # can give path and reason with an inline table\n    { path = \"regex::Regex::is_match\", reason = \"no matching allowed\" },\n    # can use an inline table but omit reason\n    { path = \"regex::Regex::new\" },\n    # local paths\n    \"conf_disallowed_methods::local_fn\",\n    \"conf_disallowed_methods::local_mod::f\",\n    \"conf_disallowed_methods::Struct::method\",\n    \"conf_disallowed_methods::Trait::provided_method\",\n    \"conf_disallowed_methods::Trait::implemented_method\",\n    # re-exports\n    \"conf_disallowed_methods::identity\",\n    \"conf_disallowed_methods::renamed\",\n    # also used in desugaring\n    \"std::future::Future::poll\",\n]\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs",
    "content": "#![allow(clippy::needless_raw_strings)]\n#![warn(clippy::disallowed_methods)]\n#![allow(clippy::useless_vec)]\n\nextern crate futures;\nextern crate regex;\n\nuse futures::stream::{empty, select_all};\nuse regex::Regex;\n\nuse std::convert::identity;\nuse std::hint::black_box as renamed;\n\nfn local_fn() {}\n\nstruct Struct;\n\nimpl Struct {\n    fn method(&self) {}\n}\n\ntrait Trait {\n    fn provided_method(&self) {}\n    fn implemented_method(&self);\n}\n\nimpl Trait for Struct {\n    fn implemented_method(&self) {}\n}\n\nmod local_mod {\n    pub fn f() {}\n}\n\nfn main() {\n    let re = Regex::new(r\"ab.*c\").unwrap();\n    //~^ disallowed_methods\n    re.is_match(\"abc\");\n    //~^ disallowed_methods\n\n    let mut a = vec![1, 2, 3, 4];\n    a.iter().sum::<i32>();\n    //~^ disallowed_methods\n\n    a.sort_unstable();\n    //~^ disallowed_methods\n\n    // FIXME(f16_f128): add a clamp test once the function is available\n    let _ = 2.0f32.clamp(3.0f32, 4.0f32);\n    //~^ disallowed_methods\n    let _ = 2.0f64.clamp(3.0f64, 4.0f64);\n\n    let indirect: fn(&str) -> Result<Regex, regex::Error> = Regex::new;\n    //~^ disallowed_methods\n    let re = indirect(\".\").unwrap();\n\n    let in_call = Box::new(f32::clamp);\n    //~^ disallowed_methods\n    let in_method_call = [\"^\", \"$\"].into_iter().map(Regex::new);\n    //~^ disallowed_methods\n\n    // resolve ambiguity between `futures::stream::select_all` the module and the function\n    let same_name_as_module = select_all(vec![empty::<()>()]);\n    //~^ disallowed_methods\n\n    local_fn();\n    //~^ disallowed_methods\n    local_mod::f();\n    //~^ disallowed_methods\n    let s = Struct;\n    s.method();\n    //~^ disallowed_methods\n    s.provided_method();\n    //~^ disallowed_methods\n    s.implemented_method();\n    //~^ disallowed_methods\n\n    identity(());\n    //~^ disallowed_methods\n    renamed(1);\n    //~^ disallowed_methods\n}\n\nmod issue16185 {\n    use std::pin::Pin;\n    use std::task::Context;\n\n    async fn test(f: impl Future<Output = ()>) {\n        // Should not lint even though desugaring uses\n        // disallowed method `std::future::Future::poll()`.\n        f.await\n    }\n\n    fn explicit<F: Future<Output = ()>>(f: Pin<&mut F>, cx: &mut Context<'_>) {\n        f.poll(cx);\n        //~^ disallowed_methods\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.stderr",
    "content": "error: use of a disallowed method `regex::Regex::new`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:36:14\n   |\nLL |     let re = Regex::new(r\"ab.*c\").unwrap();\n   |              ^^^^^^^^^^\n   |\n   = note: `-D clippy::disallowed-methods` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`\n\nerror: use of a disallowed method `regex::Regex::is_match`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:38:8\n   |\nLL |     re.is_match(\"abc\");\n   |        ^^^^^^^^\n   |\n   = note: no matching allowed\n\nerror: use of a disallowed method `std::iter::Iterator::sum`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:42:14\n   |\nLL |     a.iter().sum::<i32>();\n   |              ^^^\n\nerror: use of a disallowed method `slice::sort_unstable`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:45:7\n   |\nLL |     a.sort_unstable();\n   |       ^^^^^^^^^^^^^\n\nerror: use of a disallowed method `f32::clamp`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:49:20\n   |\nLL |     let _ = 2.0f32.clamp(3.0f32, 4.0f32);\n   |                    ^^^^^\n\nerror: use of a disallowed method `regex::Regex::new`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:53:61\n   |\nLL |     let indirect: fn(&str) -> Result<Regex, regex::Error> = Regex::new;\n   |                                                             ^^^^^^^^^^\n\nerror: use of a disallowed method `f32::clamp`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:57:28\n   |\nLL |     let in_call = Box::new(f32::clamp);\n   |                            ^^^^^^^^^^\n\nerror: use of a disallowed method `regex::Regex::new`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:59:53\n   |\nLL |     let in_method_call = [\"^\", \"$\"].into_iter().map(Regex::new);\n   |                                                     ^^^^^^^^^^\n\nerror: use of a disallowed method `futures::stream::select_all`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:63:31\n   |\nLL |     let same_name_as_module = select_all(vec![empty::<()>()]);\n   |                               ^^^^^^^^^^\n\nerror: use of a disallowed method `conf_disallowed_methods::local_fn`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:66:5\n   |\nLL |     local_fn();\n   |     ^^^^^^^^\n\nerror: use of a disallowed method `conf_disallowed_methods::local_mod::f`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:68:5\n   |\nLL |     local_mod::f();\n   |     ^^^^^^^^^^^^\n\nerror: use of a disallowed method `conf_disallowed_methods::Struct::method`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:71:7\n   |\nLL |     s.method();\n   |       ^^^^^^\n\nerror: use of a disallowed method `conf_disallowed_methods::Trait::provided_method`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:73:7\n   |\nLL |     s.provided_method();\n   |       ^^^^^^^^^^^^^^^\n\nerror: use of a disallowed method `conf_disallowed_methods::Trait::implemented_method`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:75:7\n   |\nLL |     s.implemented_method();\n   |       ^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed method `conf_disallowed_methods::identity`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:78:5\n   |\nLL |     identity(());\n   |     ^^^^^^^^\n\nerror: use of a disallowed method `conf_disallowed_methods::renamed`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:80:5\n   |\nLL |     renamed(1);\n   |     ^^^^^^^\n\nerror: use of a disallowed method `std::future::Future::poll`\n  --> tests/ui-toml/toml_disallowed_methods/conf_disallowed_methods.rs:95:11\n   |\nLL |         f.poll(cx);\n   |           ^^^^\n\nerror: aborting due to 17 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_types/clippy.toml",
    "content": "disallowed-types = [\n    \"std::collections::HashMap\",\n    \"std::sync::atomic::AtomicU32\",\n    \"syn::TypePath\",\n    \"proc_macro2::Ident\",\n    \"std::thread::Thread\",\n    \"std::time::Instant\",\n    \"std::io::Read\",\n    \"usize\",\n    \"bool\",\n    # can give path and reason with an inline table\n    { path = \"std::net::Ipv4Addr\", reason = \"no IPv4 allowed\" },\n    # can use an inline table but omit reason\n    { path = \"std::net::TcpListener\" },\n]\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs",
    "content": "#![warn(clippy::disallowed_types)]\n\nextern crate quote;\nextern crate syn;\n\nuse std::sync as foo;\nuse std::sync::atomic::AtomicU32;\n//~^ disallowed_types\nuse std::time::Instant as Sneaky;\n//~^ disallowed_types\n\nstruct HashMap;\n\nfn bad_return_type() -> fn() -> Sneaky {\n    //~^ disallowed_types\n    todo!()\n}\n\nfn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {}\n//~^ disallowed_types\n//~| disallowed_types\n\nfn trait_obj(_: &dyn std::io::Read) {}\n//~^ disallowed_types\n\nfn full_and_single_path_prim(_: usize, _: bool) {}\n//~^ disallowed_types\n//~| disallowed_types\n\nfn const_generics<const C: usize>() {}\n//~^ disallowed_types\n\nstruct GenArg<const U: usize>([u8; U]);\n//~^ disallowed_types\n\nstatic BAD: foo::atomic::AtomicPtr<()> = foo::atomic::AtomicPtr::new(std::ptr::null_mut());\n\nfn ip(_: std::net::Ipv4Addr) {}\n//~^ disallowed_types\n\nfn listener(_: std::net::TcpListener) {}\n//~^ disallowed_types\n\n#[allow(clippy::diverging_sub_expression)]\nfn main() {\n    let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();\n    //~^ disallowed_types\n    //~| disallowed_types\n    let _ = Sneaky::now();\n    //~^ disallowed_types\n    let _ = foo::atomic::AtomicU32::new(0);\n    //~^ disallowed_types\n    static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);\n    //~^ disallowed_types\n    //~| disallowed_types\n    let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default();\n    //~^ disallowed_types\n    let _ = syn::Ident::new(\"\", todo!());\n    //~^ disallowed_types\n    let _ = HashMap;\n    let _: usize = 64_usize;\n    //~^ disallowed_types\n}\n\nmod useless_attribute {\n    // Regression test for https://github.com/rust-lang/rust-clippy/issues/12753\n    #[allow(clippy::disallowed_types)]\n    use std::collections::HashMap;\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_disallowed_types/conf_disallowed_types.stderr",
    "content": "error: use of a disallowed type `std::sync::atomic::AtomicU32`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:7:1\n   |\nLL | use std::sync::atomic::AtomicU32;\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::disallowed-types` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_types)]`\n\nerror: use of a disallowed type `std::time::Instant`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:9:1\n   |\nLL | use std::time::Instant as Sneaky;\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed type `std::time::Instant`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:14:33\n   |\nLL | fn bad_return_type() -> fn() -> Sneaky {\n   |                                 ^^^^^^\n\nerror: use of a disallowed type `std::time::Instant`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:19:28\n   |\nLL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {}\n   |                            ^^^^^^\n\nerror: use of a disallowed type `std::sync::atomic::AtomicU32`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:19:39\n   |\nLL | fn bad_arg_type(_: impl Fn(Sneaky) -> foo::atomic::AtomicU32) {}\n   |                                       ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed type `std::io::Read`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:23:22\n   |\nLL | fn trait_obj(_: &dyn std::io::Read) {}\n   |                      ^^^^^^^^^^^^^\n\nerror: use of a disallowed type `usize`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:26:33\n   |\nLL | fn full_and_single_path_prim(_: usize, _: bool) {}\n   |                                 ^^^^^\n\nerror: use of a disallowed type `bool`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:26:43\n   |\nLL | fn full_and_single_path_prim(_: usize, _: bool) {}\n   |                                           ^^^^\n\nerror: use of a disallowed type `usize`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:30:28\n   |\nLL | fn const_generics<const C: usize>() {}\n   |                            ^^^^^\n\nerror: use of a disallowed type `usize`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:33:24\n   |\nLL | struct GenArg<const U: usize>([u8; U]);\n   |                        ^^^^^\n\nerror: use of a disallowed type `std::net::Ipv4Addr`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:38:10\n   |\nLL | fn ip(_: std::net::Ipv4Addr) {}\n   |          ^^^^^^^^^^^^^^^^^^\n   |\n   = note: no IPv4 allowed\n\nerror: use of a disallowed type `std::net::TcpListener`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:41:16\n   |\nLL | fn listener(_: std::net::TcpListener) {}\n   |                ^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed type `std::collections::HashMap`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:46:48\n   |\nLL |     let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();\n   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed type `std::collections::HashMap`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:46:12\n   |\nLL |     let _: std::collections::HashMap<(), ()> = std::collections::HashMap::new();\n   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed type `std::time::Instant`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:49:13\n   |\nLL |     let _ = Sneaky::now();\n   |             ^^^^^^\n\nerror: use of a disallowed type `std::sync::atomic::AtomicU32`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:51:13\n   |\nLL |     let _ = foo::atomic::AtomicU32::new(0);\n   |             ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed type `std::sync::atomic::AtomicU32`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:53:17\n   |\nLL |     static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed type `std::sync::atomic::AtomicU32`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:53:48\n   |\nLL |     static FOO: std::sync::atomic::AtomicU32 = foo::atomic::AtomicU32::new(1);\n   |                                                ^^^^^^^^^^^^^^^^^^^^^^\n\nerror: use of a disallowed type `syn::TypePath`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:56:43\n   |\nLL |     let _: std::collections::BTreeMap<(), syn::TypePath> = Default::default();\n   |                                           ^^^^^^^^^^^^^\n\nerror: use of a disallowed type `proc_macro2::Ident`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:58:13\n   |\nLL |     let _ = syn::Ident::new(\"\", todo!());\n   |             ^^^^^^^^^^\n\nerror: use of a disallowed type `usize`\n  --> tests/ui-toml/toml_disallowed_types/conf_disallowed_types.rs:61:12\n   |\nLL |     let _: usize = 64_usize;\n   |            ^^^^^\n\nerror: aborting due to 21 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_inconsistent_struct_constructor/clippy.toml",
    "content": "check-inconsistent-struct-field-initializers = true\n"
  },
  {
    "path": "tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.fixed",
    "content": "#![warn(clippy::inconsistent_struct_constructor)]\n#![allow(clippy::redundant_field_names)]\n#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::no_effect)]\n\n#[derive(Default)]\nstruct Foo {\n    x: i32,\n    y: i32,\n    z: i32,\n}\n\nfn main() {\n    let x = 1;\n    let y = 1;\n    let z = 1;\n\n    Foo { x, y, z: z };\n    //~^ inconsistent_struct_constructor\n\n    Foo {\n        x,\n        //~^ inconsistent_struct_constructor\n        z: z,\n        ..Default::default()\n    };\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/13737#discussion_r1859261645\nmod field_attributes {\n    struct HirId;\n    struct BodyVisitor {\n        macro_unsafe_blocks: Vec<HirId>,\n        expn_depth: u32,\n    }\n    fn check_body(condition: bool) {\n        BodyVisitor {\n            macro_unsafe_blocks: Vec::new(),\n            #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning\n            //~^ inconsistent_struct_constructor\n            expn_depth: if condition { 1 } else { 0 },\n        };\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/13737#discussion_r1874539800\nmod cfgs_between_fields {\n    #[allow(clippy::non_minimal_cfg)]\n    fn cfg_all() {\n        struct S {\n            a: i32,\n            b: i32,\n            #[cfg(all())]\n            c: i32,\n            d: i32,\n        }\n        let s = S {\n            a: 3,\n            //~^ inconsistent_struct_constructor\n            b: 2,\n            #[cfg(all())]\n            c: 1,\n            d: 0,\n        };\n    }\n\n    fn cfg_any() {\n        struct S {\n            a: i32,\n            b: i32,\n            #[cfg(any())]\n            c: i32,\n            d: i32,\n        }\n        let s = S {\n            a: 3,\n            //~^ inconsistent_struct_constructor\n            #[cfg(any())]\n            c: 1,\n            b: 2,\n            d: 0,\n        };\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs",
    "content": "#![warn(clippy::inconsistent_struct_constructor)]\n#![allow(clippy::redundant_field_names)]\n#![allow(clippy::unnecessary_operation)]\n#![allow(clippy::no_effect)]\n\n#[derive(Default)]\nstruct Foo {\n    x: i32,\n    y: i32,\n    z: i32,\n}\n\nfn main() {\n    let x = 1;\n    let y = 1;\n    let z = 1;\n\n    Foo { y, x, z: z };\n    //~^ inconsistent_struct_constructor\n\n    Foo {\n        z: z,\n        //~^ inconsistent_struct_constructor\n        x,\n        ..Default::default()\n    };\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/13737#discussion_r1859261645\nmod field_attributes {\n    struct HirId;\n    struct BodyVisitor {\n        macro_unsafe_blocks: Vec<HirId>,\n        expn_depth: u32,\n    }\n    fn check_body(condition: bool) {\n        BodyVisitor {\n            #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning\n            //~^ inconsistent_struct_constructor\n            expn_depth: if condition { 1 } else { 0 },\n            macro_unsafe_blocks: Vec::new(),\n        };\n    }\n}\n\n// https://github.com/rust-lang/rust-clippy/pull/13737#discussion_r1874539800\nmod cfgs_between_fields {\n    #[allow(clippy::non_minimal_cfg)]\n    fn cfg_all() {\n        struct S {\n            a: i32,\n            b: i32,\n            #[cfg(all())]\n            c: i32,\n            d: i32,\n        }\n        let s = S {\n            d: 0,\n            //~^ inconsistent_struct_constructor\n            #[cfg(all())]\n            c: 1,\n            b: 2,\n            a: 3,\n        };\n    }\n\n    fn cfg_any() {\n        struct S {\n            a: i32,\n            b: i32,\n            #[cfg(any())]\n            c: i32,\n            d: i32,\n        }\n        let s = S {\n            d: 0,\n            //~^ inconsistent_struct_constructor\n            #[cfg(any())]\n            c: 1,\n            b: 2,\n            a: 3,\n        };\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.stderr",
    "content": "error: struct constructor field order is inconsistent with struct definition field order\n  --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:18:11\n   |\nLL |     Foo { y, x, z: z };\n   |           ^^^^^^^^^^ help: if the field evaluation order doesn't matter, try: `x, y, z: z`\n   |\n   = note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::inconsistent_struct_constructor)]`\n\nerror: struct constructor field order is inconsistent with struct definition field order\n  --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:22:9\n   |\nLL | /         z: z,\nLL | |\nLL | |         x,\n   | |_________^\n   |\nhelp: if the field evaluation order doesn't matter, try\n   |\nLL ~         x,\nLL +\nLL ~         z: z,\n   |\n\nerror: struct constructor field order is inconsistent with struct definition field order\n  --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:38:13\n   |\nLL | /             #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning\nLL | |\nLL | |             expn_depth: if condition { 1 } else { 0 },\nLL | |             macro_unsafe_blocks: Vec::new(),\n   | |___________________________________________^\n   |\nhelp: if the field evaluation order doesn't matter, try\n   |\nLL ~             macro_unsafe_blocks: Vec::new(),\nLL +             #[expect(clippy::bool_to_int_with_if)] // obfuscates the meaning\nLL +\nLL ~             expn_depth: if condition { 1 } else { 0 },\n   |\n\nerror: struct constructor field order is inconsistent with struct definition field order\n  --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:58:13\n   |\nLL | /             d: 0,\nLL | |\nLL | |             #[cfg(all())]\nLL | |             c: 1,\nLL | |             b: 2,\nLL | |             a: 3,\n   | |________________^\n   |\nhelp: if the field evaluation order doesn't matter, try\n   |\nLL ~             a: 3,\nLL +\nLL +             b: 2,\nLL +             #[cfg(all())]\nLL +             c: 1,\nLL ~             d: 0,\n   |\n\nerror: struct constructor field order is inconsistent with struct definition field order\n  --> tests/ui-toml/toml_inconsistent_struct_constructor/conf_inconsistent_struct_constructor.rs:76:13\n   |\nLL | /             d: 0,\nLL | |\nLL | |             #[cfg(any())]\nLL | |             c: 1,\nLL | |             b: 2,\nLL | |             a: 3,\n   | |________________^\n   |\nhelp: if the field evaluation order doesn't matter, try\n   |\nLL ~             a: 3,\nLL +\nLL +             #[cfg(any())]\nLL +             c: 1,\nLL +             b: 2,\nLL ~             d: 0,\n   |\n\nerror: aborting due to 5 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_invalid_path/clippy.toml",
    "content": "[[disallowed-macros]]\npath = \"bool\"\n\n[[disallowed-methods]]\npath = \"std::process::current_exe\"\n\n[[disallowed-methods]]\npath = \"\"\n\n[[disallowed-types]]\npath = \"std::result::Result::Err\"\n\n# negative test\n\n[[disallowed-methods]]\npath = \"std::current_exe\"\nallow-invalid = true\n"
  },
  {
    "path": "tests/ui-toml/toml_invalid_path/conf_invalid_path.rs",
    "content": "//@error-in-other-file: expected a macro, found a primitive type\n//@error-in-other-file: `std::process::current_exe` does not refer to a reachable function\n//@error-in-other-file: `` does not refer to a reachable function\n//@error-in-other-file: expected a type, found a variant\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/toml_invalid_path/conf_invalid_path.stderr",
    "content": "warning: expected a macro, found a primitive type\n  --> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:1:1\n   |\nLL | / [[disallowed-macros]]\nLL | | path = \"bool\"\n   | |_____________^\n   |\n   = help: add `allow-invalid = true` to the entry to suppress this warning\n\nwarning: `std::process::current_exe` does not refer to a reachable function\n  --> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:4:1\n   |\nLL | / [[disallowed-methods]]\nLL | | path = \"std::process::current_exe\"\n   | |__________________________________^\n   |\n   = help: add `allow-invalid = true` to the entry to suppress this warning\n\nwarning: `` does not refer to a reachable function\n  --> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:7:1\n   |\nLL | / [[disallowed-methods]]\nLL | | path = \"\"\n   | |_________^\n   |\n   = help: add `allow-invalid = true` to the entry to suppress this warning\n\nwarning: expected a type, found a variant\n  --> $DIR/tests/ui-toml/toml_invalid_path/clippy.toml:10:1\n   |\nLL | / [[disallowed-types]]\nLL | | path = \"std::result::Result::Err\"\n   | |_________________________________^\n   |\n   = help: add `allow-invalid = true` to the entry to suppress this warning\n\nwarning: 4 warnings emitted\n\n"
  },
  {
    "path": "tests/ui-toml/toml_replaceable_disallowed_methods/clippy.toml",
    "content": "disallowed-methods = [\n    { path = \"replaceable_disallowed_methods::bad\", replacement = \"good\" },\n    { path = \"replaceable_disallowed_methods::questionable\", replacement = \"good\", reason = \"a better function exists\" },\n]\n"
  },
  {
    "path": "tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.fixed",
    "content": "fn bad() {}\nfn questionable() {}\nfn good() {}\n\nfn main() {\n    good();\n    //~^ disallowed_methods\n    good();\n    //~^ disallowed_methods\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs",
    "content": "fn bad() {}\nfn questionable() {}\nfn good() {}\n\nfn main() {\n    bad();\n    //~^ disallowed_methods\n    questionable();\n    //~^ disallowed_methods\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.stderr",
    "content": "error: use of a disallowed method `replaceable_disallowed_methods::bad`\n  --> tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs:6:5\n   |\nLL |     bad();\n   |     ^^^ help: use: `good`\n   |\n   = note: `-D clippy::disallowed-methods` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`\n\nerror: use of a disallowed method `replaceable_disallowed_methods::questionable`\n  --> tests/ui-toml/toml_replaceable_disallowed_methods/replaceable_disallowed_methods.rs:8:5\n   |\nLL |     questionable();\n   |     ^^^^^^^^^^^^ help: a better function exists: `good`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_trivially_copy/clippy.toml",
    "content": "trivial-copy-size-limit = 2\n"
  },
  {
    "path": "tests/ui-toml/toml_trivially_copy/test.rs",
    "content": "//@normalize-stderr-test: \"\\(\\d+ byte\\)\" -> \"(N byte)\"\n//@normalize-stderr-test: \"\\(limit: \\d+ byte\\)\" -> \"(limit: N byte)\"\n//@no-rustfix\n#![warn(clippy::trivially_copy_pass_by_ref)]\n#![allow(clippy::needless_pass_by_ref_mut)]\n\n#[derive(Copy, Clone)]\nstruct Foo(u8);\n\n#[derive(Copy, Clone)]\nstruct Bar(u32);\n\nfn good(a: &mut u32, b: u32, c: &Bar, d: &u32) {}\n\nfn bad(x: &u16, y: &Foo) {}\n//~^ trivially_copy_pass_by_ref\n//~| trivially_copy_pass_by_ref\n\nfn main() {\n    let (mut a, b, c, d, x, y) = (0, 0, Bar(0), 0, 0, Foo(0));\n    good(&mut a, b, &c, &d);\n    bad(&x, &y);\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_trivially_copy/test.stderr",
    "content": "error: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui-toml/toml_trivially_copy/test.rs:15:11\n   |\nLL | fn bad(x: &u16, y: &Foo) {}\n   |           ^^^^ help: consider passing by value instead: `u16`\n   |\n   = note: `-D clippy::trivially-copy-pass-by-ref` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::trivially_copy_pass_by_ref)]`\n\nerror: this argument (N byte) is passed by reference, but would be more efficient if passed by value (limit: N byte)\n  --> tests/ui-toml/toml_trivially_copy/test.rs:15:20\n   |\nLL | fn bad(x: &u16, y: &Foo) {}\n   |                    ^^^^ help: consider passing by value instead: `Foo`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_unknown_config_struct_field/clippy.toml",
    "content": "# In the following configuration, \"recommendation\" should be \"reason\" or \"replacement\".\ndisallowed-macros = [\n    { path = \"std::panic\", recommendation = \"return a `std::result::Result::Error` instead\" },\n]\n"
  },
  {
    "path": "tests/ui-toml/toml_unknown_config_struct_field/toml_unknown_config_struct_field.rs",
    "content": "#[rustfmt::skip]\n//@error-in-other-file: error reading Clippy's configuration file: data did not match any variant of untagged enum DisallowedPathEnum\nfn main() {\n    panic!();\n}\n"
  },
  {
    "path": "tests/ui-toml/toml_unknown_config_struct_field/toml_unknown_config_struct_field.stderr",
    "content": "error: error reading Clippy's configuration file: data did not match any variant of untagged enum DisallowedPathEnum\n  --> $DIR/tests/ui-toml/toml_unknown_config_struct_field/clippy.toml:3:5\n   |\nLL |     { path = \"std::panic\", recommendation = \"return a `std::result::Result::Error` instead\" },\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/toml_unknown_key/clippy.toml",
    "content": "# that one is an error\nfoobar = 42\n# so is this one\nbarfoo = 53\n\n# when using underscores instead of dashes, suggest the correct one\nallow_mixed_uninlined_format_args = true\n\n# that one is ignored\n[third-party]\nclippy-feature = \"nightly\"\n"
  },
  {
    "path": "tests/ui-toml/toml_unknown_key/conf_unknown_key.rs",
    "content": "//@no-rustfix\n//@error-in-other-file: unknown field\n//@error-in-other-file: error reading Clippy\n//@error-in-other-file: error reading Clippy\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr",
    "content": "error: error reading Clippy's configuration file: unknown field `foobar`, expected one of\n           absolute-paths-allowed-crates\n           absolute-paths-max-segments\n           accept-comment-above-attributes\n           accept-comment-above-statement\n           allow-comparison-to-zero\n           allow-dbg-in-tests\n           allow-exact-repetitions\n           allow-expect-in-consts\n           allow-expect-in-tests\n           allow-indexing-slicing-in-tests\n           allow-large-stack-frames-in-tests\n           allow-mixed-uninlined-format-args\n           allow-one-hash-in-raw-strings\n           allow-panic-in-tests\n           allow-print-in-tests\n           allow-private-module-inception\n           allow-renamed-params-for\n           allow-unwrap-in-consts\n           allow-unwrap-in-tests\n           allow-unwrap-types\n           allow-useless-vec-in-tests\n           allowed-dotfiles\n           allowed-duplicate-crates\n           allowed-idents-below-min-chars\n           allowed-prefixes\n           allowed-scripts\n           allowed-wildcard-imports\n           arithmetic-side-effects-allowed\n           arithmetic-side-effects-allowed-binary\n           arithmetic-side-effects-allowed-unary\n           array-size-threshold\n           avoid-breaking-exported-api\n           await-holding-invalid-types\n           cargo-ignore-publish\n           check-incompatible-msrv-in-tests\n           check-inconsistent-struct-field-initializers\n           check-private-items\n           cognitive-complexity-threshold\n           const-literal-digits-threshold\n           disallowed-fields\n           disallowed-macros\n           disallowed-methods\n           disallowed-names\n           disallowed-types\n           doc-valid-idents\n           enable-raw-pointer-heuristic-for-send\n           enforce-iter-loop-reborrow\n           enforced-import-renames\n           enum-variant-name-threshold\n           enum-variant-size-threshold\n           excessive-nesting-threshold\n           future-size-threshold\n           ignore-interior-mutability\n           inherent-impl-lint-scope\n           large-error-ignored\n           large-error-threshold\n           lint-commented-code\n           literal-representation-threshold\n           matches-for-let-else\n           max-fn-params-bools\n           max-include-file-size\n           max-struct-bools\n           max-suggested-slice-pattern-length\n           max-trait-bounds\n           min-ident-chars-threshold\n           missing-docs-allow-unused\n           missing-docs-in-crate-items\n           module-item-order-groupings\n           module-items-ordered-within-groupings\n           msrv\n           pass-by-value-size-limit\n           pub-underscore-fields-behavior\n           recursive-self-in-type-definitions\n           semicolon-inside-block-ignore-singleline\n           semicolon-outside-block-ignore-multiline\n           single-char-binding-names-threshold\n           source-item-ordering\n           stack-size-threshold\n           standard-macro-braces\n           struct-field-name-threshold\n           suppress-restriction-lint-in-const\n           third-party\n           too-large-for-stack\n           too-many-arguments-threshold\n           too-many-lines-threshold\n           trait-assoc-item-kinds-order\n           trivial-copy-size-limit\n           type-complexity-threshold\n           unnecessary-box-size\n           unreadable-literal-lint-fractions\n           upper-case-acronyms-aggressive\n           vec-box-size-threshold\n           verbose-bit-mask-threshold\n           warn-on-all-wildcard-imports\n           warn-unsafe-macro-metavars-in-private-macros\n  --> $DIR/tests/ui-toml/toml_unknown_key/clippy.toml:2:1\n   |\nLL | foobar = 42\n   | ^^^^^^\n\nerror: error reading Clippy's configuration file: unknown field `barfoo`, expected one of\n           absolute-paths-allowed-crates\n           absolute-paths-max-segments\n           accept-comment-above-attributes\n           accept-comment-above-statement\n           allow-comparison-to-zero\n           allow-dbg-in-tests\n           allow-exact-repetitions\n           allow-expect-in-consts\n           allow-expect-in-tests\n           allow-indexing-slicing-in-tests\n           allow-large-stack-frames-in-tests\n           allow-mixed-uninlined-format-args\n           allow-one-hash-in-raw-strings\n           allow-panic-in-tests\n           allow-print-in-tests\n           allow-private-module-inception\n           allow-renamed-params-for\n           allow-unwrap-in-consts\n           allow-unwrap-in-tests\n           allow-unwrap-types\n           allow-useless-vec-in-tests\n           allowed-dotfiles\n           allowed-duplicate-crates\n           allowed-idents-below-min-chars\n           allowed-prefixes\n           allowed-scripts\n           allowed-wildcard-imports\n           arithmetic-side-effects-allowed\n           arithmetic-side-effects-allowed-binary\n           arithmetic-side-effects-allowed-unary\n           array-size-threshold\n           avoid-breaking-exported-api\n           await-holding-invalid-types\n           cargo-ignore-publish\n           check-incompatible-msrv-in-tests\n           check-inconsistent-struct-field-initializers\n           check-private-items\n           cognitive-complexity-threshold\n           const-literal-digits-threshold\n           disallowed-fields\n           disallowed-macros\n           disallowed-methods\n           disallowed-names\n           disallowed-types\n           doc-valid-idents\n           enable-raw-pointer-heuristic-for-send\n           enforce-iter-loop-reborrow\n           enforced-import-renames\n           enum-variant-name-threshold\n           enum-variant-size-threshold\n           excessive-nesting-threshold\n           future-size-threshold\n           ignore-interior-mutability\n           inherent-impl-lint-scope\n           large-error-ignored\n           large-error-threshold\n           lint-commented-code\n           literal-representation-threshold\n           matches-for-let-else\n           max-fn-params-bools\n           max-include-file-size\n           max-struct-bools\n           max-suggested-slice-pattern-length\n           max-trait-bounds\n           min-ident-chars-threshold\n           missing-docs-allow-unused\n           missing-docs-in-crate-items\n           module-item-order-groupings\n           module-items-ordered-within-groupings\n           msrv\n           pass-by-value-size-limit\n           pub-underscore-fields-behavior\n           recursive-self-in-type-definitions\n           semicolon-inside-block-ignore-singleline\n           semicolon-outside-block-ignore-multiline\n           single-char-binding-names-threshold\n           source-item-ordering\n           stack-size-threshold\n           standard-macro-braces\n           struct-field-name-threshold\n           suppress-restriction-lint-in-const\n           third-party\n           too-large-for-stack\n           too-many-arguments-threshold\n           too-many-lines-threshold\n           trait-assoc-item-kinds-order\n           trivial-copy-size-limit\n           type-complexity-threshold\n           unnecessary-box-size\n           unreadable-literal-lint-fractions\n           upper-case-acronyms-aggressive\n           vec-box-size-threshold\n           verbose-bit-mask-threshold\n           warn-on-all-wildcard-imports\n           warn-unsafe-macro-metavars-in-private-macros\n  --> $DIR/tests/ui-toml/toml_unknown_key/clippy.toml:4:1\n   |\nLL | barfoo = 53\n   | ^^^^^^\n\nerror: error reading Clippy's configuration file: unknown field `allow_mixed_uninlined_format_args`, expected one of\n           absolute-paths-allowed-crates\n           absolute-paths-max-segments\n           accept-comment-above-attributes\n           accept-comment-above-statement\n           allow-comparison-to-zero\n           allow-dbg-in-tests\n           allow-exact-repetitions\n           allow-expect-in-consts\n           allow-expect-in-tests\n           allow-indexing-slicing-in-tests\n           allow-large-stack-frames-in-tests\n           allow-mixed-uninlined-format-args\n           allow-one-hash-in-raw-strings\n           allow-panic-in-tests\n           allow-print-in-tests\n           allow-private-module-inception\n           allow-renamed-params-for\n           allow-unwrap-in-consts\n           allow-unwrap-in-tests\n           allow-unwrap-types\n           allow-useless-vec-in-tests\n           allowed-dotfiles\n           allowed-duplicate-crates\n           allowed-idents-below-min-chars\n           allowed-prefixes\n           allowed-scripts\n           allowed-wildcard-imports\n           arithmetic-side-effects-allowed\n           arithmetic-side-effects-allowed-binary\n           arithmetic-side-effects-allowed-unary\n           array-size-threshold\n           avoid-breaking-exported-api\n           await-holding-invalid-types\n           cargo-ignore-publish\n           check-incompatible-msrv-in-tests\n           check-inconsistent-struct-field-initializers\n           check-private-items\n           cognitive-complexity-threshold\n           const-literal-digits-threshold\n           disallowed-fields\n           disallowed-macros\n           disallowed-methods\n           disallowed-names\n           disallowed-types\n           doc-valid-idents\n           enable-raw-pointer-heuristic-for-send\n           enforce-iter-loop-reborrow\n           enforced-import-renames\n           enum-variant-name-threshold\n           enum-variant-size-threshold\n           excessive-nesting-threshold\n           future-size-threshold\n           ignore-interior-mutability\n           inherent-impl-lint-scope\n           large-error-ignored\n           large-error-threshold\n           lint-commented-code\n           literal-representation-threshold\n           matches-for-let-else\n           max-fn-params-bools\n           max-include-file-size\n           max-struct-bools\n           max-suggested-slice-pattern-length\n           max-trait-bounds\n           min-ident-chars-threshold\n           missing-docs-allow-unused\n           missing-docs-in-crate-items\n           module-item-order-groupings\n           module-items-ordered-within-groupings\n           msrv\n           pass-by-value-size-limit\n           pub-underscore-fields-behavior\n           recursive-self-in-type-definitions\n           semicolon-inside-block-ignore-singleline\n           semicolon-outside-block-ignore-multiline\n           single-char-binding-names-threshold\n           source-item-ordering\n           stack-size-threshold\n           standard-macro-braces\n           struct-field-name-threshold\n           suppress-restriction-lint-in-const\n           third-party\n           too-large-for-stack\n           too-many-arguments-threshold\n           too-many-lines-threshold\n           trait-assoc-item-kinds-order\n           trivial-copy-size-limit\n           type-complexity-threshold\n           unnecessary-box-size\n           unreadable-literal-lint-fractions\n           upper-case-acronyms-aggressive\n           vec-box-size-threshold\n           verbose-bit-mask-threshold\n           warn-on-all-wildcard-imports\n           warn-unsafe-macro-metavars-in-private-macros\n  --> $DIR/tests/ui-toml/toml_unknown_key/clippy.toml:7:1\n   |\nLL | allow_mixed_uninlined_format_args = true\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: perhaps you meant: `allow-mixed-uninlined-format-args`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/toml_unloaded_crate/clippy.toml",
    "content": "# The first two `disallowed-methods` paths should generate warnings, but the third should not.\n\n[[disallowed-methods]]\npath = \"regex::Regex::new_\"\n\n[[disallowed-methods]]\npath = \"regex::Regex_::new\"\n\n[[disallowed-methods]]\npath = \"regex_::Regex::new\"\n"
  },
  {
    "path": "tests/ui-toml/toml_unloaded_crate/conf_unloaded_crate.rs",
    "content": "//@error-in-other-file: `regex::Regex::new_` does not refer to a reachable function\n//@error-in-other-file: `regex::Regex_::new` does not refer to a reachable function\n\nextern crate regex;\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/toml_unloaded_crate/conf_unloaded_crate.stderr",
    "content": "warning: `regex::Regex::new_` does not refer to a reachable function\n  --> $DIR/tests/ui-toml/toml_unloaded_crate/clippy.toml:3:1\n   |\nLL | / [[disallowed-methods]]\nLL | | path = \"regex::Regex::new_\"\n   | |___________________________^\n   |\n   = help: add `allow-invalid = true` to the entry to suppress this warning\n\nwarning: `regex::Regex_::new` does not refer to a reachable function\n  --> $DIR/tests/ui-toml/toml_unloaded_crate/clippy.toml:6:1\n   |\nLL | / [[disallowed-methods]]\nLL | | path = \"regex::Regex_::new\"\n   | |___________________________^\n   |\n   = help: add `allow-invalid = true` to the entry to suppress this warning\n\nwarning: 2 warnings emitted\n\n"
  },
  {
    "path": "tests/ui-toml/too_large_for_stack/boxed_local.rs",
    "content": "fn f(x: Box<[u8; 500]>) {}\n//~^ ERROR: local variable doesn't need to be boxed here\nfn f2(x: Box<[u8; 501]>) {}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/too_large_for_stack/boxed_local.stderr",
    "content": "error: local variable doesn't need to be boxed here\n  --> tests/ui-toml/too_large_for_stack/boxed_local.rs:1:6\n   |\nLL | fn f(x: Box<[u8; 500]>) {}\n   |      ^\n   |\n   = note: `-D clippy::boxed-local` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/too_large_for_stack/clippy.toml",
    "content": "too-large-for-stack = 500\n"
  },
  {
    "path": "tests/ui-toml/too_large_for_stack/useless_vec.fixed",
    "content": "#![warn(clippy::useless_vec)]\n\nfn main() {\n    let x = [0u8; 500];\n    //~^ ERROR: useless use of `vec!`\n    x.contains(&1);\n    let y = vec![0u8; 501];\n    y.contains(&1);\n}\n"
  },
  {
    "path": "tests/ui-toml/too_large_for_stack/useless_vec.rs",
    "content": "#![warn(clippy::useless_vec)]\n\nfn main() {\n    let x = vec![0u8; 500];\n    //~^ ERROR: useless use of `vec!`\n    x.contains(&1);\n    let y = vec![0u8; 501];\n    y.contains(&1);\n}\n"
  },
  {
    "path": "tests/ui-toml/too_large_for_stack/useless_vec.stderr",
    "content": "error: useless use of `vec!`\n  --> tests/ui-toml/too_large_for_stack/useless_vec.rs:4:13\n   |\nLL |     let x = vec![0u8; 500];\n   |             ^^^^^^^^^^^^^^ help: you can use an array directly: `[0u8; 500]`\n   |\n   = note: `-D clippy::useless-vec` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/too_many_arguments/clippy.toml",
    "content": "too-many-arguments-threshold = 10\n"
  },
  {
    "path": "tests/ui-toml/too_many_arguments/too_many_arguments.rs",
    "content": "#![warn(clippy::too_many_arguments)]\n\nfn not_too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8) {}\nfn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {}\n//~^ ERROR: this function has too many arguments\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/too_many_arguments/too_many_arguments.stderr",
    "content": "error: this function has too many arguments (11/10)\n  --> tests/ui-toml/too_many_arguments/too_many_arguments.rs:4:1\n   |\nLL | fn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::too-many-arguments` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/type_complexity/clippy.toml",
    "content": "type-complexity-threshold = 500\n"
  },
  {
    "path": "tests/ui-toml/type_complexity/type_complexity.rs",
    "content": "// 480\nfn f(_: (u8, (u8, (u8, (u8, (u8, (u8,))))))) {}\n// 550\nfn f2(_: (u8, (u8, (u8, (u8, (u8, (u8, u8))))))) {}\n//~^ ERROR: very complex type used\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/type_complexity/type_complexity.stderr",
    "content": "error: very complex type used. Consider factoring parts into `type` definitions\n  --> tests/ui-toml/type_complexity/type_complexity.rs:4:10\n   |\nLL | fn f2(_: (u8, (u8, (u8, (u8, (u8, (u8, u8))))))) {}\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::type-complexity` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/type_repetition_in_bounds/clippy.toml",
    "content": "max-trait-bounds = 5\n"
  },
  {
    "path": "tests/ui-toml/type_repetition_in_bounds/main.rs",
    "content": "#![allow(clippy::needless_maybe_sized)]\n#![warn(clippy::type_repetition_in_bounds)]\n\nfn f<T>()\nwhere\n    T: Copy + Clone + Sync + Send + ?Sized + Unpin,\n    T: PartialEq,\n{\n}\n\nfn f2<T>()\nwhere\n    T: Copy + Clone + Sync + Send + ?Sized,\n    T: Unpin + PartialEq,\n    //~^ type_repetition_in_bounds\n{\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/type_repetition_in_bounds/main.stderr",
    "content": "error: type `T` has already been used as a bound predicate\n  --> tests/ui-toml/type_repetition_in_bounds/main.rs:14:5\n   |\nLL |     T: Unpin + PartialEq,\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider combining the bounds: `T: Copy + Clone + Sync + Send + ?Sized + Unpin + PartialEq`\n   = note: `-D clippy::type-repetition-in-bounds` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::type_repetition_in_bounds)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml",
    "content": "# default configuration has `accept-comment-above-statement` and\n# `accept-comment-above-attributes` true\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml",
    "content": "# test with these options disabled\naccept-comment-above-statement = false\naccept-comment-above-attributes = false\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr",
    "content": "error: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:244:22\n   |\nLL |             let _x = unsafe { 1 };\n   |                      ^^^^^^^^^^^^\n...\nLL |     t!();\n   |     ---- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`\n   = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:256:13\n   |\nLL |             unsafe { 1 };\n   |             ^^^^^^^^^^^^\n...\nLL |     t!();\n   |     ---- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:337:19\n   |\nLL |     /* Safety: */ unsafe {}\n   |                   ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:342:5\n   |\nLL |     unsafe {}\n   |     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:14\n   |\nLL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];\n   |              ^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:29\n   |\nLL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];\n   |                             ^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:48\n   |\nLL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];\n   |                                                ^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:18\n   |\nLL |     let _ = (42, unsafe {}, \"test\", unsafe {});\n   |                  ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:37\n   |\nLL |     let _ = (42, unsafe {}, \"test\", unsafe {});\n   |                                     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:360:14\n   |\nLL |     let _ = *unsafe { &42 };\n   |              ^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:366:19\n   |\nLL |     let _ = match unsafe {} {\n   |                   ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:373:14\n   |\nLL |     let _ = &unsafe {};\n   |              ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:378:14\n   |\nLL |     let _ = [unsafe {}; 5];\n   |              ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383:13\n   |\nLL |     let _ = unsafe {};\n   |             ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:394:8\n   |\nLL |     t!(unsafe {});\n   |        ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:401:13\n   |\nLL |             unsafe {}\n   |             ^^^^^^^^^\n...\nLL |     t!();\n   |     ---- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:410:5\n   |\nLL |     unsafe {} // SAFETY:\n   |     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416:5\n   |\nLL |     unsafe {\n   |     ^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:427:5\n   |\nLL |     unsafe {};\n   |     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:432:20\n   |\nLL |     println!(\"{}\", unsafe { String::from_utf8_unchecked(vec![]) });\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:440:5\n   |\nLL |     unsafe impl A for () {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:448:9\n   |\nLL |         unsafe impl B for (u32) {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:470:13\n   |\nLL |             unsafe impl T for $t {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     no_safety_comment!(());\n   |     ---------------------- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:13\n   |\nLL |             unsafe impl T for $t {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     no_safety_comment!(());\n   |     ---------------------- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:5\n   |\nLL |     unsafe impl T for (i32) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:13\n   |\nLL |             unsafe impl T for $t {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     no_safety_comment!(u32);\n   |     ----------------------- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:513:5\n   |\nLL |     unsafe impl T for (bool) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:560:5\n   |\nLL |     unsafe impl NoComment for () {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:565:19\n   |\nLL |     /* SAFETY: */ unsafe impl InlineComment for () {}\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:570:5\n   |\nLL |     unsafe impl TrailingComment for () {} // SAFETY:\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: constant has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:575:5\n   |\nLL |     const BIG_NUMBER: i32 = 1000000;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:574:8\n   |\nLL |     // SAFETY:\n   |        ^^^^^^^\n   = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:577:5\n   |\nLL |     unsafe impl Interference for () {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:585:5\n   |\nLL |     unsafe impl ImplInFn for () {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:595:1\n   |\nLL | unsafe impl CrateRoot for () {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: statement has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:610:5\n   |\nLL | /     let _ = {\nLL | |\nLL | |         if unsafe { true } {\n...  |\nLL | |     };\n   | |______^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:609:8\n   |\nLL |     // SAFETY: this is more than one level away, so it should warn\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:612:12\n   |\nLL |         if unsafe { true } {\n   |            ^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:616:23\n   |\nLL |             let bar = unsafe {};\n   |                       ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:705:52\n   |\nLL |         const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };\n   |                                                    ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:714:41\n   |\nLL |         const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };\n   |                                         ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:724:42\n   |\nLL |         const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };\n   |                                          ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:729:40\n   |\nLL |         const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };\n   |                                        ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: constant has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:768:5\n   |\nLL |     const UNIX_EPOCH_JULIAN_DAY: i32 =\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:766:8\n   |\nLL |     // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n   |        ^^^^^^^\n\nerror: statement has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:788:5\n   |\nLL |     _ = bar();\n   |     ^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:787:8\n   |\nLL |     // SAFETY: unnecessary_safety_comment triggers here\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: module has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:808:5\n   |\nLL |     mod x {}\n   |     ^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:807:8\n   |\nLL |     // SAFETY: ...\n   |        ^^^^^^^\n\nerror: module has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:813:5\n   |\nLL |     mod y {}\n   |     ^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:811:8\n   |\nLL |     // SAFETY: ...\n   |        ^^^^^^^\n\nerror: module has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:818:5\n   |\nLL |     mod z {}\n   |     ^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:817:8\n   |\nLL |     // SAFETY: ...\n   |        ^^^^^^^\n\nerror: module has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:826:5\n   |\nLL |     mod y {}\n   |     ^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:824:8\n   |\nLL |     // SAFETY: ...\n   |        ^^^^^^^\n\nerror: statement has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:841:9\n   |\nLL |         let x = 34;\n   |         ^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:839:12\n   |\nLL |         // SAFETY: ...\n   |            ^^^^^^^^^^^\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:848:5\n   |\nLL |     unsafe fn unsafe_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the `safety` comment for a `# Safety` doc comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:847:8\n   |\nLL |     // SAFETY: Bla\n   |        ^^^^^^^\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:854:5\n   |\nLL |     unsafe fn unsafe_block_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the `safety` comment for a `# Safety` doc comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:852:8\n   |\nLL |        SAFETY: Bla\n   |        ^^^^^^^\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:858:5\n   |\nLL |     fn safe_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:857:8\n   |\nLL |     // SAFETY: Bla\n   |        ^^^^^^^\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:862:5\n   |\nLL |     fn safe_doc_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:861:9\n   |\nLL |     /// SAFETY: Bla\n   |         ^^^^^^^\n\nerror: aborting due to 52 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr",
    "content": "error: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:244:22\n   |\nLL |             let _x = unsafe { 1 };\n   |                      ^^^^^^^^^^^^\n...\nLL |     t!();\n   |     ---- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`\n   = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:256:13\n   |\nLL |             unsafe { 1 };\n   |             ^^^^^^^^^^^^\n...\nLL |     t!();\n   |     ---- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:337:19\n   |\nLL |     /* Safety: */ unsafe {}\n   |                   ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:342:5\n   |\nLL |     unsafe {}\n   |     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:14\n   |\nLL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];\n   |              ^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:29\n   |\nLL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];\n   |                             ^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:347:48\n   |\nLL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];\n   |                                                ^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:18\n   |\nLL |     let _ = (42, unsafe {}, \"test\", unsafe {});\n   |                  ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:354:37\n   |\nLL |     let _ = (42, unsafe {}, \"test\", unsafe {});\n   |                                     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:360:14\n   |\nLL |     let _ = *unsafe { &42 };\n   |              ^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:366:19\n   |\nLL |     let _ = match unsafe {} {\n   |                   ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:373:14\n   |\nLL |     let _ = &unsafe {};\n   |              ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:378:14\n   |\nLL |     let _ = [unsafe {}; 5];\n   |              ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383:13\n   |\nLL |     let _ = unsafe {};\n   |             ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:394:8\n   |\nLL |     t!(unsafe {});\n   |        ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:401:13\n   |\nLL |             unsafe {}\n   |             ^^^^^^^^^\n...\nLL |     t!();\n   |     ---- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:410:5\n   |\nLL |     unsafe {} // SAFETY:\n   |     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416:5\n   |\nLL |     unsafe {\n   |     ^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:427:5\n   |\nLL |     unsafe {};\n   |     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:432:20\n   |\nLL |     println!(\"{}\", unsafe { String::from_utf8_unchecked(vec![]) });\n   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:440:5\n   |\nLL |     unsafe impl A for () {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:448:9\n   |\nLL |         unsafe impl B for (u32) {}\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:470:13\n   |\nLL |             unsafe impl T for $t {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     no_safety_comment!(());\n   |     ---------------------- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:13\n   |\nLL |             unsafe impl T for $t {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     no_safety_comment!(());\n   |     ---------------------- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:5\n   |\nLL |     unsafe impl T for (i32) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:496:13\n   |\nLL |             unsafe impl T for $t {}\n   |             ^^^^^^^^^^^^^^^^^^^^^^^\n...\nLL |     no_safety_comment!(u32);\n   |     ----------------------- in this macro invocation\n   |\n   = help: consider adding a safety comment on the preceding line\n   = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:513:5\n   |\nLL |     unsafe impl T for (bool) {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:560:5\n   |\nLL |     unsafe impl NoComment for () {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:565:19\n   |\nLL |     /* SAFETY: */ unsafe impl InlineComment for () {}\n   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:570:5\n   |\nLL |     unsafe impl TrailingComment for () {} // SAFETY:\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: constant has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:575:5\n   |\nLL |     const BIG_NUMBER: i32 = 1000000;\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:574:8\n   |\nLL |     // SAFETY:\n   |        ^^^^^^^\n   = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:577:5\n   |\nLL |     unsafe impl Interference for () {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:585:5\n   |\nLL |     unsafe impl ImplInFn for () {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe impl missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:595:1\n   |\nLL | unsafe impl CrateRoot for () {}\n   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:606:9\n   |\nLL |         unsafe {};\n   |         ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: statement has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:610:5\n   |\nLL | /     let _ = {\nLL | |\nLL | |         if unsafe { true } {\n...  |\nLL | |     };\n   | |______^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:609:8\n   |\nLL |     // SAFETY: this is more than one level away, so it should warn\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:612:12\n   |\nLL |         if unsafe { true } {\n   |            ^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:616:23\n   |\nLL |             let bar = unsafe {};\n   |                       ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:635:9\n   |\nLL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:640:9\n   |\nLL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:645:9\n   |\nLL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:652:5\n   |\nLL |     unsafe {}\n   |     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:657:5\n   |\nLL |     unsafe {\n   |     ^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:665:9\n   |\nLL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:671:9\n   |\nLL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:678:9\n   |\nLL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:684:5\n   |\nLL |     unsafe {}\n   |     ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:705:52\n   |\nLL |         const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };\n   |                                                    ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:714:41\n   |\nLL |         const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };\n   |                                         ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:724:42\n   |\nLL |         const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };\n   |                                          ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:729:40\n   |\nLL |         const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };\n   |                                        ^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:740:9\n   |\nLL |         unsafe { here_is_another_variable_with_long_name };\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:769:9\n   |\nLL |         unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer();\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: statement has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:788:5\n   |\nLL |     _ = bar();\n   |     ^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:787:8\n   |\nLL |     // SAFETY: unnecessary_safety_comment triggers here\n   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:802:12\n   |\nLL |     return unsafe { h() };\n   |            ^^^^^^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: module has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:808:5\n   |\nLL |     mod x {}\n   |     ^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:807:8\n   |\nLL |     // SAFETY: ...\n   |        ^^^^^^^\n\nerror: module has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:818:5\n   |\nLL |     mod z {}\n   |     ^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:817:8\n   |\nLL |     // SAFETY: ...\n   |        ^^^^^^^\n\nerror: unsafe block missing a safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:833:9\n   |\nLL |         unsafe {}\n   |         ^^^^^^^^^\n   |\n   = help: consider adding a safety comment on the preceding line\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:848:5\n   |\nLL |     unsafe fn unsafe_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the `safety` comment for a `# Safety` doc comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:847:8\n   |\nLL |     // SAFETY: Bla\n   |        ^^^^^^^\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:854:5\n   |\nLL |     unsafe fn unsafe_block_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider changing the `safety` comment for a `# Safety` doc comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:852:8\n   |\nLL |        SAFETY: Bla\n   |        ^^^^^^^\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:858:5\n   |\nLL |     fn safe_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:857:8\n   |\nLL |     // SAFETY: Bla\n   |        ^^^^^^^\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:862:5\n   |\nLL |     fn safe_doc_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: consider removing the safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:861:9\n   |\nLL |     /// SAFETY: Bla\n   |         ^^^^^^^\n\nerror: aborting due to 62 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macro_unsafe.rs\n//@revisions: default disabled\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/default\n//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled\n\n#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]\n#![allow(\n    deref_nullptr,\n    non_local_definitions,\n    clippy::let_unit_value,\n    clippy::missing_safety_doc\n)]\n\nextern crate proc_macro_unsafe;\n\n// Valid comments\n\nfn nested_local() {\n    let _ = {\n        let _ = {\n            // SAFETY:\n            let _ = unsafe {};\n        };\n    };\n}\n\nfn deep_nest() {\n    let _ = {\n        let _ = {\n            // SAFETY:\n            let _ = unsafe {};\n\n            // Safety:\n            unsafe {};\n\n            let _ = {\n                let _ = {\n                    let _ = {\n                        let _ = {\n                            let _ = {\n                                // Safety:\n                                let _ = unsafe {};\n\n                                // SAFETY:\n                                unsafe {};\n                            };\n                        };\n                    };\n\n                    // Safety:\n                    unsafe {};\n                };\n            };\n        };\n\n        // Safety:\n        unsafe {};\n    };\n\n    // SAFETY:\n    unsafe {};\n}\n\nfn local_tuple_expression() {\n    // Safety:\n    let _ = (42, unsafe {});\n}\n\nfn line_comment() {\n    // Safety:\n    unsafe {}\n}\n\nfn line_comment_newlines() {\n    // SAFETY:\n\n    unsafe {}\n}\n\nfn line_comment_empty() {\n    // Safety:\n    //\n    //\n    //\n    unsafe {}\n}\n\nfn line_comment_with_extras() {\n    // This is a description\n    // Safety:\n    unsafe {}\n}\n\nfn block_comment() {\n    /* Safety: */\n    unsafe {}\n}\n\nfn block_comment_newlines() {\n    /* SAFETY: */\n\n    unsafe {}\n}\n\nfn block_comment_with_extras() {\n    /* This is a description\n     * SAFETY:\n     */\n    unsafe {}\n}\n\nfn block_comment_terminator_same_line() {\n    /* This is a description\n     * Safety: */\n    unsafe {}\n}\n\nfn buried_safety() {\n    // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\n    // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation\n    // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in\n    // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n    // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est\n    // laborum. Safety:\n    // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi\n    // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio\n    // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl\n    // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.\n    unsafe {}\n}\n\nfn safety_with_prepended_text() {\n    // This is a test. safety:\n    unsafe {}\n}\n\nfn local_line_comment() {\n    // Safety:\n    let _ = unsafe {};\n}\n\nfn local_block_comment() {\n    /* SAFETY: */\n    let _ = unsafe {};\n}\n\nfn comment_array() {\n    // Safety:\n    let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];\n}\n\nfn comment_tuple() {\n    // sAFETY:\n    let _ = (42, unsafe {}, \"test\", unsafe {});\n}\n\nfn comment_unary() {\n    // SAFETY:\n    let _ = *unsafe { &42 };\n}\n\n#[allow(clippy::match_single_binding)]\nfn comment_match() {\n    // SAFETY:\n    let _ = match unsafe {} {\n        _ => {},\n    };\n}\n\nfn comment_addr_of() {\n    // Safety:\n    let _ = &unsafe {};\n}\n\nfn comment_repeat() {\n    // Safety:\n    let _ = [unsafe {}; 5];\n}\n\nfn comment_macro_call() {\n    macro_rules! t {\n        ($b:expr) => {\n            $b\n        };\n    }\n\n    t!(\n        // SAFETY:\n        unsafe {}\n    );\n}\n\nfn comment_macro_def() {\n    macro_rules! t {\n        () => {\n            // Safety:\n            unsafe {}\n        };\n    }\n\n    t!();\n}\n\nfn comment_macro_def_with_let() {\n    macro_rules! t {\n        () => {\n            let _x =\n                // SAFETY: here be exactly one dragon\n                unsafe { 1 };\n        };\n    }\n\n    t!();\n}\n\n#[rustfmt::skip]\nfn comment_macro_def_with_let_same_line() {\n    macro_rules! t {\n        () => {\n            let _x =// SAFETY: same line comment\n            unsafe { 1 };\n        };\n    }\n\n    t!();\n}\n\nfn inner_comment_macro_def_with_let() {\n    macro_rules! t {\n        () => {\n            let _x = unsafe {\n                // SAFETY: inside the block\n                1\n            };\n        };\n    }\n\n    t!();\n}\n\nfn no_comment_macro_def_with_let() {\n    macro_rules! t {\n        () => {\n            let _x = unsafe { 1 };\n            //~^ undocumented_unsafe_blocks\n        };\n    }\n\n    t!();\n}\n\nfn prefixed_safety_comment_macro_def_with_let() {\n    macro_rules! t {\n        () => {\n            let _x =// not a SAFETY: comment, should lint\n            unsafe { 1 };\n            //~^ undocumented_unsafe_blocks\n        };\n    }\n\n    t!();\n}\n\nfn non_ascii_comment() {\n    // ॐ᧻໒ SaFeTy: ௵∰\n    unsafe {};\n}\n\nfn local_commented_block() {\n    let _ =\n        // safety:\n        unsafe {};\n}\n\nfn local_nest() {\n    // safety:\n    let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})];\n}\n\nfn in_fn_call(x: *const u32) {\n    fn f(x: u32) {}\n\n    // Safety: reason\n    f(unsafe { *x });\n}\n\nfn multi_in_fn_call(x: *const u32) {\n    fn f(x: u32, y: u32) {}\n\n    // Safety: reason\n    f(unsafe { *x }, unsafe { *x });\n}\n\nfn in_multiline_fn_call(x: *const u32) {\n    fn f(x: u32, y: u32) {}\n\n    f(\n        // Safety: reason\n        unsafe { *x },\n        0,\n    );\n}\n\nfn in_macro_call(x: *const u32) {\n    // Safety: reason\n    println!(\"{}\", unsafe { *x });\n}\n\nfn in_multiline_macro_call(x: *const u32) {\n    println!(\n        \"{}\",\n        // Safety: reason\n        unsafe { *x },\n    );\n}\n\nfn from_proc_macro() {\n    proc_macro_unsafe::unsafe_block!(token);\n}\n\nfn in_closure(x: *const u32) {\n    // Safety: reason\n    let _ = || unsafe { *x };\n}\n\nfn inner_block_comment_block_style(x: *const u32) {\n    let _ = unsafe {\n        /* SAFETY: block comment inside */\n        *x\n    };\n}\n\n// Invalid comments\n\n#[rustfmt::skip]\nfn inline_block_comment() {\n    /* Safety: */ unsafe {}\n    //~^ undocumented_unsafe_blocks\n}\n\nfn no_comment() {\n    unsafe {}\n    //~^ undocumented_unsafe_blocks\n}\n\nfn no_comment_array() {\n    let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];\n    //~^ undocumented_unsafe_blocks\n    //~| undocumented_unsafe_blocks\n    //~| undocumented_unsafe_blocks\n}\n\nfn no_comment_tuple() {\n    let _ = (42, unsafe {}, \"test\", unsafe {});\n    //~^ undocumented_unsafe_blocks\n    //~| undocumented_unsafe_blocks\n}\n\nfn no_comment_unary() {\n    let _ = *unsafe { &42 };\n    //~^ undocumented_unsafe_blocks\n}\n\n#[allow(clippy::match_single_binding)]\nfn no_comment_match() {\n    let _ = match unsafe {} {\n        //~^ undocumented_unsafe_blocks\n        _ => {},\n    };\n}\n\nfn no_comment_addr_of() {\n    let _ = &unsafe {};\n    //~^ undocumented_unsafe_blocks\n}\n\nfn no_comment_repeat() {\n    let _ = [unsafe {}; 5];\n    //~^ undocumented_unsafe_blocks\n}\n\nfn local_no_comment() {\n    let _ = unsafe {};\n    //~^ undocumented_unsafe_blocks\n}\n\nfn no_comment_macro_call() {\n    macro_rules! t {\n        ($b:expr) => {\n            $b\n        };\n    }\n\n    t!(unsafe {});\n    //~^ undocumented_unsafe_blocks\n}\n\nfn no_comment_macro_def() {\n    macro_rules! t {\n        () => {\n            unsafe {}\n            //~^ undocumented_unsafe_blocks\n        };\n    }\n\n    t!();\n}\n\nfn trailing_comment() {\n    unsafe {} // SAFETY:\n    //\n    //~^^ undocumented_unsafe_blocks\n}\n\nfn internal_comment() {\n    unsafe {\n        //~^ undocumented_unsafe_blocks\n        // SAFETY:\n    }\n}\n\nfn interference() {\n    // SAFETY\n\n    let _ = 42;\n\n    unsafe {};\n    //~^ undocumented_unsafe_blocks\n}\n\npub fn print_binary_tree() {\n    println!(\"{}\", unsafe { String::from_utf8_unchecked(vec![]) });\n    //~^ undocumented_unsafe_blocks\n}\n\nmod unsafe_impl_smoke_test {\n    unsafe trait A {}\n\n    // error: no safety comment\n    unsafe impl A for () {}\n    //~^ undocumented_unsafe_blocks\n\n    // Safety: ok\n    unsafe impl A for (i32) {}\n\n    mod sub_mod {\n        // error:\n        unsafe impl B for (u32) {}\n        //~^ undocumented_unsafe_blocks\n        unsafe trait B {}\n    }\n\n    #[rustfmt::skip]\n    mod sub_mod2 {\n        //\n        // SAFETY: ok\n        //\n\n        unsafe impl B for (u32) {}\n        unsafe trait B {}\n    }\n}\n\nmod unsafe_impl_from_macro {\n    unsafe trait T {}\n\n    // error\n    macro_rules! no_safety_comment {\n        ($t:ty) => {\n            unsafe impl T for $t {}\n            //~^ undocumented_unsafe_blocks\n        };\n    }\n\n    // ok\n    no_safety_comment!(());\n\n    // ok\n    macro_rules! with_safety_comment {\n        ($t:ty) => {\n            // SAFETY:\n            unsafe impl T for $t {}\n        };\n    }\n\n    // ok\n    with_safety_comment!((i32));\n}\n\nmod unsafe_impl_macro_and_not_macro {\n    unsafe trait T {}\n\n    // error\n    macro_rules! no_safety_comment {\n        ($t:ty) => {\n            unsafe impl T for $t {}\n            //~^ undocumented_unsafe_blocks\n            //~| undocumented_unsafe_blocks\n        };\n    }\n\n    // ok\n    no_safety_comment!(());\n\n    // error\n    unsafe impl T for (i32) {}\n    //~^ undocumented_unsafe_blocks\n\n    // ok\n    no_safety_comment!(u32);\n\n    // error\n    unsafe impl T for (bool) {}\n    //~^ undocumented_unsafe_blocks\n}\n\n#[rustfmt::skip]\nmod unsafe_impl_valid_comment {\n    unsafe trait SaFety {}\n    // SaFety:\n    unsafe impl SaFety for () {}\n\n    unsafe trait MultiLineComment {}\n    // The following impl is safe\n    // ...\n    // Safety: reason\n    unsafe impl MultiLineComment for () {}\n\n    unsafe trait NoAscii {}\n    // 安全 SAFETY: 以下のコードは安全です\n    unsafe impl NoAscii for () {}\n\n    unsafe trait InlineAndPrecedingComment {}\n    // SAFETY:\n    /* comment */ unsafe impl InlineAndPrecedingComment for () {}\n\n    unsafe trait BuriedSafety {}\n    // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\n    // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation\n    // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in\n    // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint\n    // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est\n    // laborum. Safety:\n    // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi\n    // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio\n    // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl\n    // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.\n    unsafe impl BuriedSafety for () {}\n\n    unsafe trait MultiLineBlockComment {}\n    /* This is a description\n     * Safety: */\n    unsafe impl MultiLineBlockComment for () {}\n}\n\n#[rustfmt::skip]\nmod unsafe_impl_invalid_comment {\n    unsafe trait NoComment {}\n\n    unsafe impl NoComment for () {}\n    //~^ undocumented_unsafe_blocks\n\n    unsafe trait InlineComment {}\n\n    /* SAFETY: */ unsafe impl InlineComment for () {}\n    //~^ undocumented_unsafe_blocks\n\n    unsafe trait TrailingComment {}\n\n    unsafe impl TrailingComment for () {} // SAFETY:\n    //~^ undocumented_unsafe_blocks\n\n    unsafe trait Interference {}\n    // SAFETY:\n    const BIG_NUMBER: i32 = 1000000;\n    //~^ unnecessary_safety_comment\n    unsafe impl Interference for () {}\n    //~^ undocumented_unsafe_blocks\n}\n\nunsafe trait ImplInFn {}\n\nfn impl_in_fn() {\n    // error\n    unsafe impl ImplInFn for () {}\n    //~^ undocumented_unsafe_blocks\n\n    // SAFETY: ok\n    unsafe impl ImplInFn for (i32) {}\n}\n\nunsafe trait CrateRoot {}\n\n// error\nunsafe impl CrateRoot for () {}\n//~^ undocumented_unsafe_blocks\n\n// SAFETY: ok\nunsafe impl CrateRoot for (i32) {}\n\nfn nested_block_separation_issue_9142() {\n    // SAFETY: ok\n    let _ =\n        // we need this comment to avoid rustfmt putting\n        // it all on one line\n        unsafe {};\n    //~[disabled]^ undocumented_unsafe_blocks\n\n    // SAFETY: this is more than one level away, so it should warn\n    let _ = {\n        //~^ unnecessary_safety_comment\n        if unsafe { true } {\n            //~^ undocumented_unsafe_blocks\n            todo!();\n        } else {\n            let bar = unsafe {};\n            //~^ undocumented_unsafe_blocks\n            todo!();\n            bar\n        }\n    };\n}\n\npub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 {\n    1\n}\n\npub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 {\n    2\n}\n\nfn separate_line_from_let_issue_10832() {\n    // SAFETY: fail ONLY if `accept-comment-above-statement = false`\n    let _some_variable_with_a_very_long_name_to_break_the_line =\n        unsafe { a_function_with_a_very_long_name_to_break_the_line() };\n    //~[disabled]^ undocumented_unsafe_blocks\n\n    // SAFETY: fail ONLY if `accept-comment-above-statement = false`\n    const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =\n        unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };\n    //~[disabled]^ undocumented_unsafe_blocks\n\n    // SAFETY: fail ONLY if `accept-comment-above-statement = false`\n    static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =\n        unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };\n    //~[disabled]^ undocumented_unsafe_blocks\n}\n\nfn above_expr_attribute_issue_8679<T: Copy>() {\n    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n    #[allow(unsafe_code)]\n    unsafe {}\n    //~[disabled]^ undocumented_unsafe_blocks\n\n    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n    #[expect(unsafe_code, reason = \"totally safe\")]\n    unsafe {\n        //~[disabled]^ undocumented_unsafe_blocks\n        *std::ptr::null::<T>()\n    };\n\n    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n    #[allow(unsafe_code)]\n    let _some_variable_with_a_very_long_name_to_break_the_line =\n        unsafe { a_function_with_a_very_long_name_to_break_the_line() };\n    //~[disabled]^ undocumented_unsafe_blocks\n\n    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n    #[allow(unsafe_code)]\n    const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =\n        unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };\n    //~[disabled]^ undocumented_unsafe_blocks\n\n    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n    #[allow(unsafe_code)]\n    #[allow(non_upper_case_globals)]\n    static _some_static_with_a_very_long_name_to_break_the_line: u32 =\n        unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };\n    //~[disabled]^ undocumented_unsafe_blocks\n\n    // SAFETY:\n    #[allow(unsafe_code)]\n    // This shouldn't work either\n    unsafe {}\n    //~[disabled]^ undocumented_unsafe_blocks\n}\n\nmod issue_11246 {\n    // Safety: foo\n    const _: () = unsafe {};\n\n    // Safety: A safety comment\n    const FOO: () = unsafe {};\n\n    // Safety: bar\n    static BAR: u8 = unsafe { 0 };\n}\n\n// Safety: Another safety comment\nconst FOO: () = unsafe {};\n\n// trait items and impl items\nmod issue_11709 {\n    trait MyTrait {\n        const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };\n        //~^ ERROR: unsafe block missing a safety comment\n\n        // SAFETY: safe\n        const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 1 };\n\n        // SAFETY: unrelated\n        unsafe fn unsafe_fn() {}\n\n        const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };\n        //~^ ERROR: unsafe block missing a safety comment\n    }\n\n    struct UnsafeStruct;\n\n    impl MyTrait for UnsafeStruct {\n        // SAFETY: safe in this impl\n        const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 2 };\n\n        const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };\n        //~^ ERROR: unsafe block missing a safety comment\n    }\n\n    impl UnsafeStruct {\n        const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };\n        //~^ ERROR: unsafe block missing a safety comment\n    }\n}\n\nfn issue_13024() {\n    let mut just_a_simple_variable_with_a_very_long_name_that_has_seventy_eight_characters = 0;\n    let here_is_another_variable_with_long_name = 100;\n\n    // SAFETY: fail ONLY if `accept-comment-above-statement = false`\n    just_a_simple_variable_with_a_very_long_name_that_has_seventy_eight_characters =\n        unsafe { here_is_another_variable_with_long_name };\n    //~[disabled]^ undocumented_unsafe_blocks\n}\n\n// https://docs.rs/time/0.3.36/src/time/offset_date_time.rs.html#35\nmod issue_11709_regression {\n    use std::num::NonZeroI32;\n\n    struct Date {\n        value: NonZeroI32,\n    }\n\n    impl Date {\n        const unsafe fn __from_ordinal_date_unchecked(year: i32, ordinal: u16) -> Self {\n            Self {\n                // Safety: The caller must guarantee that `ordinal` is not zero.\n                value: unsafe { NonZeroI32::new_unchecked((year << 9) | ordinal as i32) },\n            }\n        }\n\n        const fn into_julian_day_just_make_this_line_longer(self) -> i32 {\n            42\n        }\n    }\n\n    /// The Julian day of the Unix epoch.\n    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`\n    #[allow(unsafe_code)]\n    const UNIX_EPOCH_JULIAN_DAY: i32 =\n        unsafe { Date::__from_ordinal_date_unchecked(1970, 1) }.into_julian_day_just_make_this_line_longer();\n    //~[disabled]^ undocumented_unsafe_blocks\n    // This shouldn't be linted, Issue #15755\n    //~[default]^^^^ unnecessary_safety_comment\n}\n\nfn issue_13039() {\n    unsafe fn foo() -> usize {\n        1234\n    }\n\n    fn bar() -> usize {\n        1234\n    }\n\n    // SAFETY: unnecessary_safety_comment should not trigger here\n    _ = unsafe { foo() };\n\n    // SAFETY: unnecessary_safety_comment triggers here\n    _ = bar();\n    //~^ unnecessary_safety_comment\n\n    // SAFETY: unnecessary_safety_comment should not trigger here\n    _ = unsafe { foo() }\n}\n\nfn rfl_issue15034() -> i32 {\n    unsafe fn h() -> i32 {\n        1i32\n    }\n    // This shouldn't lint with accept-comment-above-attributes! Thus fixing a false positive!\n    // SAFETY: My safety comment!\n    #[allow(clippy::unnecessary_cast)]\n    return unsafe { h() };\n    //~[disabled]^ ERROR: unsafe block missing a safety comment\n}\n\nmod issue_14555 {\n    // SAFETY: ...\n    mod x {}\n    //~^ unnecessary_safety_comment\n\n    // SAFETY: ...\n    #[doc(hidden)]\n    mod y {}\n    //~[default]^ unnecessary_safety_comment\n\n    #[doc(hidden)]\n    // SAFETY: ...\n    mod z {}\n    //~^ unnecessary_safety_comment\n}\n\nmod issue_15754 {\n    #[must_use]\n    // SAFETY: ...\n    #[doc(hidden)]\n    mod y {}\n    //~[default]^ unnecessary_safety_comment\n\n    fn foo() {\n        #[doc(hidden)]\n        // SAFETY: unnecessary_safety_comment should not trigger here\n        #[allow(unsafe_code)]\n        unsafe {}\n        //~[disabled]^ undocumented_unsafe_blocks\n    }\n\n    fn bar() {\n        #[doc(hidden)]\n        // SAFETY: ...\n        #[allow(clippy::unnecessary_cast)]\n        let x = 34;\n        //~[default]^ unnecessary_safety_comment\n    }\n}\n\nmod unsafe_fns {\n    // SAFETY: Bla\n    unsafe fn unsafe_comment() {}\n    //~^ unnecessary_safety_comment\n\n    /*\n       SAFETY: Bla\n    */\n    unsafe fn unsafe_block_comment() {}\n    //~^ unnecessary_safety_comment\n\n    // SAFETY: Bla\n    fn safe_comment() {}\n    //~^ unnecessary_safety_comment\n\n    /// SAFETY: Bla\n    fn safe_doc_comment() {}\n    //~^ unnecessary_safety_comment\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.default.fixed",
    "content": "//@aux-build:../../ui/auxiliary/proc_macro_unsafe.rs\n//@revisions: default disabled\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/default\n//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled\n\n#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]\n\nmod unsafe_fns {\n    /// # Safety Bla\n    unsafe fn unsafe_doc_comment() {}\n    //~^ unnecessary_safety_comment\n\n    /**\n     * # Safety Bla\n     */\n    unsafe fn unsafe_block_doc_comment() {}\n    //~^ unnecessary_safety_comment\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.default.stderr",
    "content": "error: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.rs:10:5\n   |\nLL |     /// SAFETY: Bla\n   |         ------- help: consider changing it to a `# Safety` section: `# Safety`\nLL |     unsafe fn unsafe_doc_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.rs:16:5\n   |\nLL |      * SAFETY: Bla\n   |        ------- help: consider changing it to a `# Safety` section: `# Safety`\nLL |      */\nLL |     unsafe fn unsafe_block_doc_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.disabled.fixed",
    "content": "//@aux-build:../../ui/auxiliary/proc_macro_unsafe.rs\n//@revisions: default disabled\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/default\n//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled\n\n#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]\n\nmod unsafe_fns {\n    /// # Safety Bla\n    unsafe fn unsafe_doc_comment() {}\n    //~^ unnecessary_safety_comment\n\n    /**\n     * # Safety Bla\n     */\n    unsafe fn unsafe_block_doc_comment() {}\n    //~^ unnecessary_safety_comment\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.disabled.stderr",
    "content": "error: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.rs:10:5\n   |\nLL |     /// SAFETY: Bla\n   |         ------- help: consider changing it to a `# Safety` section: `# Safety`\nLL |     unsafe fn unsafe_doc_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`\n\nerror: function has unnecessary safety comment\n  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.rs:16:5\n   |\nLL |      * SAFETY: Bla\n   |        ------- help: consider changing it to a `# Safety` section: `# Safety`\nLL |      */\nLL |     unsafe fn unsafe_block_doc_comment() {}\n   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks_fixable.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macro_unsafe.rs\n//@revisions: default disabled\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/default\n//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled\n\n#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]\n\nmod unsafe_fns {\n    /// SAFETY: Bla\n    unsafe fn unsafe_doc_comment() {}\n    //~^ unnecessary_safety_comment\n\n    /**\n     * SAFETY: Bla\n     */\n    unsafe fn unsafe_block_doc_comment() {}\n    //~^ unnecessary_safety_comment\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/unnecessary_box_returns/clippy.toml",
    "content": "unnecessary-box-size = 64\n"
  },
  {
    "path": "tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed",
    "content": "#![warn(clippy::unnecessary_box_returns)]\n\nfn f() -> [u8; 64] {\n    //~^ ERROR: boxed return of the sized type `[u8; 64]`\n    todo!()\n}\nfn f2() -> Box<[u8; 65]> {\n    todo!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs",
    "content": "#![warn(clippy::unnecessary_box_returns)]\n\nfn f() -> Box<[u8; 64]> {\n    //~^ ERROR: boxed return of the sized type `[u8; 64]`\n    todo!()\n}\nfn f2() -> Box<[u8; 65]> {\n    todo!()\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr",
    "content": "error: boxed return of the sized type `[u8; 64]`\n  --> tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs:3:11\n   |\nLL | fn f() -> Box<[u8; 64]> {\n   |           ^^^^^^^^^^^^^ help: try: `[u8; 64]`\n   |\n   = help: changing this also requires a change to the return expressions in this function\n   = note: `-D clippy::unnecessary-box-returns` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_box_returns)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/unwrap_used/clippy.toml",
    "content": "allow-unwrap-in-consts = false\nallow-unwrap-in-tests = true\n"
  },
  {
    "path": "tests/ui-toml/unwrap_used/unwrap_used.fixed",
    "content": "//@compile-flags: --test\n\n#![allow(\n    unused_mut,\n    clippy::get_first,\n    clippy::from_iter_instead_of_collect,\n    clippy::useless_vec\n)]\n#![warn(clippy::unwrap_used)]\n#![warn(clippy::get_unwrap)]\n\nuse std::collections::{BTreeMap, HashMap, VecDeque};\n\nstruct GetFalsePositive {\n    arr: [u32; 3],\n}\n\nimpl GetFalsePositive {\n    fn get(&self, pos: usize) -> Option<&u32> {\n        self.arr.get(pos)\n    }\n    fn get_mut(&mut self, pos: usize) -> Option<&mut u32> {\n        self.arr.get_mut(pos)\n    }\n}\n\nfn main() {\n    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let mut some_slice = &mut [0, 1, 2, 3];\n    let mut some_vec = vec![0, 1, 2, 3];\n    let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect();\n    let mut some_hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(1, 'a'), (2, 'b')]);\n    let mut some_btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(1, 'a'), (2, 'b')]);\n    let mut false_positive = GetFalsePositive { arr: [0, 1, 2] };\n\n    {\n        // Test `get().unwrap()`\n        let _ = &boxed_slice[1];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_slice[0];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_vec[0];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_vecdeque[0];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_hashmap[&1];\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = &some_btreemap[&1];\n        //~^ get_unwrap\n        //~| unwrap_used\n        #[allow(clippy::unwrap_used)]\n        let _ = false_positive.get(0).unwrap();\n        // Test with deref\n        let _: u8 = boxed_slice[1];\n        //~^ get_unwrap\n        //~| unwrap_used\n    }\n\n    {\n        // Test `get_mut().unwrap()`\n        boxed_slice[0] = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        some_slice[0] = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        some_vec[0] = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        some_vecdeque[0] = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        // Check false positives\n        #[allow(clippy::unwrap_used)]\n        {\n            *some_hashmap.get_mut(&1).unwrap() = 'b';\n            *some_btreemap.get_mut(&1).unwrap() = 'b';\n            *false_positive.get_mut(0).unwrap() = 1;\n        }\n    }\n\n    {\n        // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()`\n        let _ = some_vec[0..1].to_vec();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_vec[0..1].to_vec();\n        //~^ get_unwrap\n        //~| unwrap_used\n    }\n}\n\n#[test]\nfn test() {\n    let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let _ = &boxed_slice[1];\n    //~^ get_unwrap\n}\n\n#[cfg(test)]\nmod issue9612 {\n    // should not lint in `#[cfg(test)]` modules\n    #[test]\n    fn test_fn() {\n        let _a: u8 = 2.try_into().unwrap();\n        let _a: u8 = 3.try_into().expect(\"\");\n\n        util();\n    }\n\n    #[allow(unconditional_panic)]\n    fn util() {\n        let _a: u8 = 4.try_into().unwrap();\n        let _a: u8 = 5.try_into().expect(\"\");\n        // should still warn\n        let _ = &Box::new([0])[1];\n        //~^ get_unwrap\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/unwrap_used/unwrap_used.rs",
    "content": "//@compile-flags: --test\n\n#![allow(\n    unused_mut,\n    clippy::get_first,\n    clippy::from_iter_instead_of_collect,\n    clippy::useless_vec\n)]\n#![warn(clippy::unwrap_used)]\n#![warn(clippy::get_unwrap)]\n\nuse std::collections::{BTreeMap, HashMap, VecDeque};\n\nstruct GetFalsePositive {\n    arr: [u32; 3],\n}\n\nimpl GetFalsePositive {\n    fn get(&self, pos: usize) -> Option<&u32> {\n        self.arr.get(pos)\n    }\n    fn get_mut(&mut self, pos: usize) -> Option<&mut u32> {\n        self.arr.get_mut(pos)\n    }\n}\n\nfn main() {\n    let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let mut some_slice = &mut [0, 1, 2, 3];\n    let mut some_vec = vec![0, 1, 2, 3];\n    let mut some_vecdeque: VecDeque<_> = some_vec.iter().cloned().collect();\n    let mut some_hashmap: HashMap<u8, char> = HashMap::from_iter(vec![(1, 'a'), (2, 'b')]);\n    let mut some_btreemap: BTreeMap<u8, char> = BTreeMap::from_iter(vec![(1, 'a'), (2, 'b')]);\n    let mut false_positive = GetFalsePositive { arr: [0, 1, 2] };\n\n    {\n        // Test `get().unwrap()`\n        let _ = boxed_slice.get(1).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_slice.get(0).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_vec.get(0).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_vecdeque.get(0).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_hashmap.get(&1).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_btreemap.get(&1).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n        #[allow(clippy::unwrap_used)]\n        let _ = false_positive.get(0).unwrap();\n        // Test with deref\n        let _: u8 = *boxed_slice.get(1).unwrap();\n        //~^ get_unwrap\n        //~| unwrap_used\n    }\n\n    {\n        // Test `get_mut().unwrap()`\n        *boxed_slice.get_mut(0).unwrap() = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        *some_slice.get_mut(0).unwrap() = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        *some_vec.get_mut(0).unwrap() = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        *some_vecdeque.get_mut(0).unwrap() = 1;\n        //~^ get_unwrap\n        //~| unwrap_used\n        // Check false positives\n        #[allow(clippy::unwrap_used)]\n        {\n            *some_hashmap.get_mut(&1).unwrap() = 'b';\n            *some_btreemap.get_mut(&1).unwrap() = 'b';\n            *false_positive.get_mut(0).unwrap() = 1;\n        }\n    }\n\n    {\n        // Test `get().unwrap().foo()` and `get_mut().unwrap().bar()`\n        let _ = some_vec.get(0..1).unwrap().to_vec();\n        //~^ get_unwrap\n        //~| unwrap_used\n        let _ = some_vec.get_mut(0..1).unwrap().to_vec();\n        //~^ get_unwrap\n        //~| unwrap_used\n    }\n}\n\n#[test]\nfn test() {\n    let boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);\n    let _ = boxed_slice.get(1).unwrap();\n    //~^ get_unwrap\n}\n\n#[cfg(test)]\nmod issue9612 {\n    // should not lint in `#[cfg(test)]` modules\n    #[test]\n    fn test_fn() {\n        let _a: u8 = 2.try_into().unwrap();\n        let _a: u8 = 3.try_into().expect(\"\");\n\n        util();\n    }\n\n    #[allow(unconditional_panic)]\n    fn util() {\n        let _a: u8 = 4.try_into().unwrap();\n        let _a: u8 = 5.try_into().expect(\"\");\n        // should still warn\n        let _ = Box::new([0]).get(1).unwrap();\n        //~^ get_unwrap\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/unwrap_used/unwrap_used.stderr",
    "content": "error: called `.get().unwrap()` on a slice\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:38:17\n   |\nLL |         let _ = boxed_slice.get(1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: `-D clippy::get-unwrap` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::get_unwrap)]`\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = boxed_slice.get(1).unwrap();\nLL +         let _ = &boxed_slice[1];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:38:17\n   |\nLL |         let _ = boxed_slice.get(1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n   = note: `-D clippy::unwrap-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17\n   |\nLL |         let _ = some_slice.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_slice.get(0).unwrap();\nLL +         let _ = &some_slice[0];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17\n   |\nLL |         let _ = some_slice.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a Vec\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:44:17\n   |\nLL |         let _ = some_vec.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_vec.get(0).unwrap();\nLL +         let _ = &some_vec[0];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:44:17\n   |\nLL |         let _ = some_vec.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a VecDeque\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:17\n   |\nLL |         let _ = some_vecdeque.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_vecdeque.get(0).unwrap();\nLL +         let _ = &some_vecdeque[0];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:17\n   |\nLL |         let _ = some_vecdeque.get(0).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a HashMap\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:50:17\n   |\nLL |         let _ = some_hashmap.get(&1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_hashmap.get(&1).unwrap();\nLL +         let _ = &some_hashmap[&1];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:50:17\n   |\nLL |         let _ = some_hashmap.get(&1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a BTreeMap\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:17\n   |\nLL |         let _ = some_btreemap.get(&1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_btreemap.get(&1).unwrap();\nLL +         let _ = &some_btreemap[&1];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:17\n   |\nLL |         let _ = some_btreemap.get(&1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:59:21\n   |\nLL |         let _: u8 = *boxed_slice.get(1).unwrap();\n   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _: u8 = *boxed_slice.get(1).unwrap();\nLL +         let _: u8 = boxed_slice[1];\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:59:22\n   |\nLL |         let _: u8 = *boxed_slice.get(1).unwrap();\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a slice\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:66:9\n   |\nLL |         *boxed_slice.get_mut(0).unwrap() = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         *boxed_slice.get_mut(0).unwrap() = 1;\nLL +         boxed_slice[0] = 1;\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:66:10\n   |\nLL |         *boxed_slice.get_mut(0).unwrap() = 1;\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a slice\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:69:9\n   |\nLL |         *some_slice.get_mut(0).unwrap() = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         *some_slice.get_mut(0).unwrap() = 1;\nLL +         some_slice[0] = 1;\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:69:10\n   |\nLL |         *some_slice.get_mut(0).unwrap() = 1;\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a Vec\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:72:9\n   |\nLL |         *some_vec.get_mut(0).unwrap() = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         *some_vec.get_mut(0).unwrap() = 1;\nLL +         some_vec[0] = 1;\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:72:10\n   |\nLL |         *some_vec.get_mut(0).unwrap() = 1;\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a VecDeque\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:75:9\n   |\nLL |         *some_vecdeque.get_mut(0).unwrap() = 1;\n   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         *some_vecdeque.get_mut(0).unwrap() = 1;\nLL +         some_vecdeque[0] = 1;\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:75:10\n   |\nLL |         *some_vecdeque.get_mut(0).unwrap() = 1;\n   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a Vec\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:89:17\n   |\nLL |         let _ = some_vec.get(0..1).unwrap().to_vec();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_vec.get(0..1).unwrap().to_vec();\nLL +         let _ = some_vec[0..1].to_vec();\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:89:17\n   |\nLL |         let _ = some_vec.get(0..1).unwrap().to_vec();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get_mut().unwrap()` on a Vec\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:92:17\n   |\nLL |         let _ = some_vec.get_mut(0..1).unwrap().to_vec();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = some_vec.get_mut(0..1).unwrap().to_vec();\nLL +         let _ = some_vec[0..1].to_vec();\n   |\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:92:17\n   |\nLL |         let _ = some_vec.get_mut(0..1).unwrap().to_vec();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:101:13\n   |\nLL |     let _ = boxed_slice.get(1).unwrap();\n   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -     let _ = boxed_slice.get(1).unwrap();\nLL +     let _ = &boxed_slice[1];\n   |\n\nerror: called `.get().unwrap()` on a slice\n  --> tests/ui-toml/unwrap_used/unwrap_used.rs:121:17\n   |\nLL |         let _ = Box::new([0]).get(1).unwrap();\n   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n   |\nhelp: using `[]` is clearer and more concise\n   |\nLL -         let _ = Box::new([0]).get(1).unwrap();\nLL +         let _ = &Box::new([0])[1];\n   |\n\nerror: aborting due to 28 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/unwrap_used/unwrap_used_const.rs",
    "content": "#![warn(clippy::unwrap_used)]\n\nfn main() {\n    const SOME: Option<i32> = Some(3);\n    const UNWRAPPED: i32 = SOME.unwrap();\n    //~^ ERROR: used `unwrap()` on an `Option` value\n    const {\n        SOME.unwrap();\n        //~^ ERROR: used `unwrap()` on an `Option` value\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/unwrap_used/unwrap_used_const.stderr",
    "content": "error: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used_const.rs:5:28\n   |\nLL |     const UNWRAPPED: i32 = SOME.unwrap();\n   |                            ^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n   = note: `-D clippy::unwrap-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`\n\nerror: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used/unwrap_used_const.rs:8:9\n   |\nLL |         SOME.unwrap();\n   |         ^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/unwrap_used_allowed/clippy.toml",
    "content": "allow-unwrap-types = [\"std::sync::LockResult\"]"
  },
  {
    "path": "tests/ui-toml/unwrap_used_allowed/unwrap_used_allowed.rs",
    "content": "#![warn(clippy::unwrap_used)]\n#![allow(clippy::unnecessary_literal_unwrap)]\n#![allow(unused_variables)]\nuse std::sync::Mutex;\n\nfn main() {\n    let m = Mutex::new(0);\n    // This is allowed because `LockResult` is configured!\n    let _guard = m.lock().unwrap();\n\n    let optional: Option<i32> = Some(1);\n    // This is not allowed!\n    let _opt = optional.unwrap();\n    //~^ ERROR: used `unwrap()` on an `Option` value\n\n    let result: Result<i32, ()> = Ok(1);\n    // This is not allowed!\n    let _res = result.unwrap();\n    //~^ ERROR: used `unwrap()` on a `Result` value\n}\n"
  },
  {
    "path": "tests/ui-toml/unwrap_used_allowed/unwrap_used_allowed.stderr",
    "content": "error: used `unwrap()` on an `Option` value\n  --> tests/ui-toml/unwrap_used_allowed/unwrap_used_allowed.rs:13:16\n   |\nLL |     let _opt = optional.unwrap();\n   |                ^^^^^^^^^^^^^^^^^\n   |\n   = note: if this value is `None`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n   = note: `-D clippy::unwrap-used` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::unwrap_used)]`\n\nerror: used `unwrap()` on a `Result` value\n  --> tests/ui-toml/unwrap_used_allowed/unwrap_used_allowed.rs:18:16\n   |\nLL |     let _res = result.unwrap();\n   |                ^^^^^^^^^^^^^^^\n   |\n   = note: if this value is an `Err`, it will panic\n   = help: consider using `expect()` to provide a better panic message\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/update-all-references.sh",
    "content": "#!/bin/bash\n\necho \"Please use 'cargo bless' instead.\"\n"
  },
  {
    "path": "tests/ui-toml/upper_case_acronyms_aggressive/clippy.toml",
    "content": "upper-case-acronyms-aggressive = true\n"
  },
  {
    "path": "tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.fixed",
    "content": "#![warn(clippy::upper_case_acronyms)]\n\nstruct HttpResponse; // not linted by default, but with cfg option\n//~^ upper_case_acronyms\n\nstruct CString; // not linted\n\nenum Flags {\n    Ns, // not linted\n    //~^ upper_case_acronyms\n    Cwr,\n    //~^ upper_case_acronyms\n    Ece,\n    //~^ upper_case_acronyms\n    Urg,\n    //~^ upper_case_acronyms\n    Ack,\n    //~^ upper_case_acronyms\n    Psh,\n    //~^ upper_case_acronyms\n    Rst,\n    //~^ upper_case_acronyms\n    Syn,\n    //~^ upper_case_acronyms\n    Fin,\n    //~^ upper_case_acronyms\n}\n\n// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of\n// `GccLlvmSomething`\nstruct GccllvmSomething;\n//~^ upper_case_acronyms\n\n// don't warn on public items\npub struct MIXEDCapital;\n\npub struct FULLCAPITAL;\n\n// enum variants should not be linted if the num is pub\npub enum ParseError<T> {\n    FULLCAPITAL(u8),\n    MIXEDCapital(String),\n    Utf8(std::string::FromUtf8Error),\n    Parse(T, String),\n}\n\n// private, do lint here\nenum ParseErrorPrivate<T> {\n    Wasd(u8),\n    //~^ upper_case_acronyms\n    WasdMixed(String),\n    //~^ upper_case_acronyms\n    Utf8(std::string::FromUtf8Error),\n    Parse(T, String),\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs",
    "content": "#![warn(clippy::upper_case_acronyms)]\n\nstruct HTTPResponse; // not linted by default, but with cfg option\n//~^ upper_case_acronyms\n\nstruct CString; // not linted\n\nenum Flags {\n    NS, // not linted\n    //~^ upper_case_acronyms\n    CWR,\n    //~^ upper_case_acronyms\n    ECE,\n    //~^ upper_case_acronyms\n    URG,\n    //~^ upper_case_acronyms\n    ACK,\n    //~^ upper_case_acronyms\n    PSH,\n    //~^ upper_case_acronyms\n    RST,\n    //~^ upper_case_acronyms\n    SYN,\n    //~^ upper_case_acronyms\n    FIN,\n    //~^ upper_case_acronyms\n}\n\n// linted with cfg option, beware that lint suggests `GccllvmSomething` instead of\n// `GccLlvmSomething`\nstruct GCCLLVMSomething;\n//~^ upper_case_acronyms\n\n// don't warn on public items\npub struct MIXEDCapital;\n\npub struct FULLCAPITAL;\n\n// enum variants should not be linted if the num is pub\npub enum ParseError<T> {\n    FULLCAPITAL(u8),\n    MIXEDCapital(String),\n    Utf8(std::string::FromUtf8Error),\n    Parse(T, String),\n}\n\n// private, do lint here\nenum ParseErrorPrivate<T> {\n    WASD(u8),\n    //~^ upper_case_acronyms\n    WASDMixed(String),\n    //~^ upper_case_acronyms\n    Utf8(std::string::FromUtf8Error),\n    Parse(T, String),\n}\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.stderr",
    "content": "error: name `HTTPResponse` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:3:8\n   |\nLL | struct HTTPResponse; // not linted by default, but with cfg option\n   |        ^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `HttpResponse`\n   |\n   = note: `-D clippy::upper-case-acronyms` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::upper_case_acronyms)]`\n\nerror: name `NS` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:9:5\n   |\nLL |     NS, // not linted\n   |     ^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ns`\n\nerror: name `CWR` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:11:5\n   |\nLL |     CWR,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Cwr`\n\nerror: name `ECE` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:13:5\n   |\nLL |     ECE,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Ece`\n\nerror: name `URG` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:15:5\n   |\nLL |     URG,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Urg`\n\nerror: name `ACK` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:17:5\n   |\nLL |     ACK,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter (notice the capitalization): `Ack`\n\nerror: name `PSH` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:19:5\n   |\nLL |     PSH,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Psh`\n\nerror: name `RST` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:21:5\n   |\nLL |     RST,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Rst`\n\nerror: name `SYN` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:23:5\n   |\nLL |     SYN,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Syn`\n\nerror: name `FIN` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:25:5\n   |\nLL |     FIN,\n   |     ^^^ help: consider making the acronym lowercase, except the initial letter: `Fin`\n\nerror: name `GCCLLVMSomething` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:31:8\n   |\nLL | struct GCCLLVMSomething;\n   |        ^^^^^^^^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `GccllvmSomething`\n\nerror: name `WASD` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:49:5\n   |\nLL |     WASD(u8),\n   |     ^^^^ help: consider making the acronym lowercase, except the initial letter: `Wasd`\n\nerror: name `WASDMixed` contains a capitalized acronym\n  --> tests/ui-toml/upper_case_acronyms_aggressive/upper_case_acronyms.rs:51:5\n   |\nLL |     WASDMixed(String),\n   |     ^^^^^^^^^ help: consider making the acronym lowercase, except the initial letter: `WasdMixed`\n\nerror: aborting due to 13 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/use_self/default/clippy.toml",
    "content": ""
  },
  {
    "path": "tests/ui-toml/use_self/disabled/clippy.toml",
    "content": "recursive-self-in-type-definitions = false\n"
  },
  {
    "path": "tests/ui-toml/use_self/use_self.default.fixed",
    "content": "//@revisions: default disabled\n//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/use_self/disabled\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/use_self/default\n\n#![warn(clippy::use_self)]\n\nfn main() {}\n\nstruct Basic {\n    flag: Option<Box<Self>>,\n    //~[default]^ use_self\n}\n\nimpl Basic {\n    fn x(_: Self) {}\n    //~[default,disabled]^ use_self\n}\n"
  },
  {
    "path": "tests/ui-toml/use_self/use_self.default.stderr",
    "content": "error: unnecessary structure name repetition\n  --> tests/ui-toml/use_self/use_self.rs:10:22\n   |\nLL |     flag: Option<Box<Basic>>,\n   |                      ^^^^^ help: use the applicable keyword: `Self`\n   |\n   = note: `-D clippy::use-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::use_self)]`\n\nerror: unnecessary structure name repetition\n  --> tests/ui-toml/use_self/use_self.rs:15:13\n   |\nLL |     fn x(_: Basic) {}\n   |             ^^^^^ help: use the applicable keyword: `Self`\n\nerror: aborting due to 2 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/use_self/use_self.disabled.fixed",
    "content": "//@revisions: default disabled\n//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/use_self/disabled\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/use_self/default\n\n#![warn(clippy::use_self)]\n\nfn main() {}\n\nstruct Basic {\n    flag: Option<Box<Basic>>,\n    //~[default]^ use_self\n}\n\nimpl Basic {\n    fn x(_: Self) {}\n    //~[default,disabled]^ use_self\n}\n"
  },
  {
    "path": "tests/ui-toml/use_self/use_self.disabled.stderr",
    "content": "error: unnecessary structure name repetition\n  --> tests/ui-toml/use_self/use_self.rs:15:13\n   |\nLL |     fn x(_: Basic) {}\n   |             ^^^^^ help: use the applicable keyword: `Self`\n   |\n   = note: `-D clippy::use-self` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::use_self)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/use_self/use_self.rs",
    "content": "//@revisions: default disabled\n//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/use_self/disabled\n//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/use_self/default\n\n#![warn(clippy::use_self)]\n\nfn main() {}\n\nstruct Basic {\n    flag: Option<Box<Basic>>,\n    //~[default]^ use_self\n}\n\nimpl Basic {\n    fn x(_: Basic) {}\n    //~[default,disabled]^ use_self\n}\n"
  },
  {
    "path": "tests/ui-toml/useless_vec/clippy.toml",
    "content": "allow-useless-vec-in-tests = true\n"
  },
  {
    "path": "tests/ui-toml/useless_vec/useless_vec.fixed",
    "content": "//@compile-flags: --test\n#![warn(clippy::useless_vec)]\n#![allow(clippy::unnecessary_operation, clippy::no_effect)]\n\nfn foo(_: &[u32]) {}\n\nfn main() {\n    foo(&[1_u32]);\n    //~^ useless_vec\n}\n\n#[test]\npub fn in_test() {\n    foo(&vec![2_u32]);\n}\n\n#[cfg(test)]\nfn in_cfg_test() {\n    foo(&vec![3_u32]);\n}\n\n#[cfg(test)]\nmod mod1 {\n    fn in_cfg_test_mod() {\n        super::foo(&vec![4_u32]);\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/useless_vec/useless_vec.rs",
    "content": "//@compile-flags: --test\n#![warn(clippy::useless_vec)]\n#![allow(clippy::unnecessary_operation, clippy::no_effect)]\n\nfn foo(_: &[u32]) {}\n\nfn main() {\n    foo(&vec![1_u32]);\n    //~^ useless_vec\n}\n\n#[test]\npub fn in_test() {\n    foo(&vec![2_u32]);\n}\n\n#[cfg(test)]\nfn in_cfg_test() {\n    foo(&vec![3_u32]);\n}\n\n#[cfg(test)]\nmod mod1 {\n    fn in_cfg_test_mod() {\n        super::foo(&vec![4_u32]);\n    }\n}\n"
  },
  {
    "path": "tests/ui-toml/useless_vec/useless_vec.stderr",
    "content": "error: useless use of `vec!`\n  --> tests/ui-toml/useless_vec/useless_vec.rs:8:9\n   |\nLL |     foo(&vec![1_u32]);\n   |         ^^^^^^^^^^^^ help: you can use a slice directly: `&[1_u32]`\n   |\n   = note: `-D clippy::useless-vec` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/vec_box_sized/clippy.toml",
    "content": "vec-box-size-threshold = 4\n"
  },
  {
    "path": "tests/ui-toml/vec_box_sized/test.fixed",
    "content": "struct S {\n    x: u64,\n}\n\nstruct C {\n    y: u16,\n}\n\nstruct Foo(Vec<u8>);\n//~^ vec_box\nstruct Bar(Vec<u16>);\n//~^ vec_box\nstruct Quux(Vec<Box<u32>>);\nstruct Baz(Vec<Box<(u16, u16)>>);\nstruct BarBaz(Vec<Box<S>>);\nstruct FooBarBaz(Vec<C>);\n//~^ vec_box\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/vec_box_sized/test.rs",
    "content": "struct S {\n    x: u64,\n}\n\nstruct C {\n    y: u16,\n}\n\nstruct Foo(Vec<Box<u8>>);\n//~^ vec_box\nstruct Bar(Vec<Box<u16>>);\n//~^ vec_box\nstruct Quux(Vec<Box<u32>>);\nstruct Baz(Vec<Box<(u16, u16)>>);\nstruct BarBaz(Vec<Box<S>>);\nstruct FooBarBaz(Vec<Box<C>>);\n//~^ vec_box\n\nfn main() {}\n"
  },
  {
    "path": "tests/ui-toml/vec_box_sized/test.stderr",
    "content": "error: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui-toml/vec_box_sized/test.rs:9:12\n   |\nLL | struct Foo(Vec<Box<u8>>);\n   |            ^^^^^^^^^^^^ help: try: `Vec<u8>`\n   |\n   = note: `-D clippy::vec-box` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::vec_box)]`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui-toml/vec_box_sized/test.rs:11:12\n   |\nLL | struct Bar(Vec<Box<u16>>);\n   |            ^^^^^^^^^^^^^ help: try: `Vec<u16>`\n\nerror: `Vec<T>` is already on the heap, the boxing is unnecessary\n  --> tests/ui-toml/vec_box_sized/test.rs:16:18\n   |\nLL | struct FooBarBaz(Vec<Box<C>>);\n   |                  ^^^^^^^^^^^ help: try: `Vec<C>`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/verbose_bit_mask/clippy.toml",
    "content": "verbose-bit-mask-threshold = 31\n"
  },
  {
    "path": "tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed",
    "content": "#![warn(clippy::verbose_bit_mask)]\nfn main() {\n    let v: i32 = 0;\n    let _ = v & 0b11111 == 0;\n    let _ = v.trailing_zeros() >= 6;\n    //~^ ERROR: bit mask could be simplified\n}\n"
  },
  {
    "path": "tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs",
    "content": "#![warn(clippy::verbose_bit_mask)]\nfn main() {\n    let v: i32 = 0;\n    let _ = v & 0b11111 == 0;\n    let _ = v & 0b111111 == 0;\n    //~^ ERROR: bit mask could be simplified\n}\n"
  },
  {
    "path": "tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr",
    "content": "error: bit mask could be simplified with a call to `trailing_zeros`\n  --> tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs:5:13\n   |\nLL |     let _ = v & 0b111111 == 0;\n   |             ^^^^^^^^^^^^^^^^^ help: try: `v.trailing_zeros() >= 6`\n   |\n   = note: `-D clippy::verbose-bit-mask` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::verbose_bit_mask)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/wildcard_imports/clippy.toml",
    "content": "warn-on-all-wildcard-imports = true\n\n# This should be ignored since `warn-on-all-wildcard-imports` has higher precedence\nallowed-wildcard-imports = [\"utils\"]\n"
  },
  {
    "path": "tests/ui-toml/wildcard_imports/wildcard_imports.fixed",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n#![warn(clippy::wildcard_imports)]\n\nmod prelude {\n    pub const FOO: u8 = 1;\n}\n\nmod utils {\n    pub const BAR: u8 = 1;\n    pub fn print() {}\n}\n\nmod my_crate {\n    pub mod utils {\n        pub fn my_util_fn() {}\n    }\n\n    pub mod utils2 {\n        pub const SOME_CONST: u32 = 1;\n    }\n}\n\npub use utils::{BAR, print};\n//~^ ERROR: usage of wildcard import\nuse my_crate::utils::my_util_fn;\n//~^ ERROR: usage of wildcard import\nuse prelude::FOO;\n//~^ ERROR: usage of wildcard import\n\nproc_macros::external! {\n    use my_crate::utils2::*;\n\n    static SOME_STATIC: u32 = SOME_CONST;\n}\n\nfn main() {\n    let _ = FOO;\n    let _ = BAR;\n    print();\n    my_util_fn();\n}\n"
  },
  {
    "path": "tests/ui-toml/wildcard_imports/wildcard_imports.rs",
    "content": "//@aux-build:../../ui/auxiliary/proc_macros.rs\n#![warn(clippy::wildcard_imports)]\n\nmod prelude {\n    pub const FOO: u8 = 1;\n}\n\nmod utils {\n    pub const BAR: u8 = 1;\n    pub fn print() {}\n}\n\nmod my_crate {\n    pub mod utils {\n        pub fn my_util_fn() {}\n    }\n\n    pub mod utils2 {\n        pub const SOME_CONST: u32 = 1;\n    }\n}\n\npub use utils::*;\n//~^ ERROR: usage of wildcard import\nuse my_crate::utils::*;\n//~^ ERROR: usage of wildcard import\nuse prelude::*;\n//~^ ERROR: usage of wildcard import\n\nproc_macros::external! {\n    use my_crate::utils2::*;\n\n    static SOME_STATIC: u32 = SOME_CONST;\n}\n\nfn main() {\n    let _ = FOO;\n    let _ = BAR;\n    print();\n    my_util_fn();\n}\n"
  },
  {
    "path": "tests/ui-toml/wildcard_imports/wildcard_imports.stderr",
    "content": "error: usage of wildcard import\n  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:23:9\n   |\nLL | pub use utils::*;\n   |         ^^^^^^^^ help: try: `utils::{BAR, print}`\n   |\n   = note: `-D clippy::wildcard-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`\n\nerror: usage of wildcard import\n  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:25:5\n   |\nLL | use my_crate::utils::*;\n   |     ^^^^^^^^^^^^^^^^^^ help: try: `my_crate::utils::my_util_fn`\n\nerror: usage of wildcard import\n  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:27:5\n   |\nLL | use prelude::*;\n   |     ^^^^^^^^^^ help: try: `prelude::FOO`\n\nerror: aborting due to 3 previous errors\n\n"
  },
  {
    "path": "tests/ui-toml/wildcard_imports_whitelist/clippy.toml",
    "content": "allowed-wildcard-imports = [\"utils\"]\n"
  },
  {
    "path": "tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed",
    "content": "#![warn(clippy::wildcard_imports)]\n\nmod utils {\n    pub fn print() {}\n}\n\nmod utils_plus {\n    pub fn do_something() {}\n}\n\nmod my_crate {\n    pub mod utils {\n        pub fn my_util_fn() {}\n    }\n}\n\nuse my_crate::utils::*;\nuse utils::*;\nuse utils_plus::do_something;\n//~^ ERROR: usage of wildcard import\n\nfn main() {\n    print();\n    my_util_fn();\n    do_something();\n}\n"
  },
  {
    "path": "tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs",
    "content": "#![warn(clippy::wildcard_imports)]\n\nmod utils {\n    pub fn print() {}\n}\n\nmod utils_plus {\n    pub fn do_something() {}\n}\n\nmod my_crate {\n    pub mod utils {\n        pub fn my_util_fn() {}\n    }\n}\n\nuse my_crate::utils::*;\nuse utils::*;\nuse utils_plus::*;\n//~^ ERROR: usage of wildcard import\n\nfn main() {\n    print();\n    my_util_fn();\n    do_something();\n}\n"
  },
  {
    "path": "tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr",
    "content": "error: usage of wildcard import\n  --> tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs:19:5\n   |\nLL | use utils_plus::*;\n   |     ^^^^^^^^^^^^^ help: try: `utils_plus::do_something`\n   |\n   = note: `-D clippy::wildcard-imports` implied by `-D warnings`\n   = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`\n\nerror: aborting due to 1 previous error\n\n"
  },
  {
    "path": "tests/ui-toml/zero_single_char_names/clippy.toml",
    "content": "single-char-binding-names-threshold = 0\n"
  },
  {
    "path": "tests/ui-toml/zero_single_char_names/zero_single_char_names.rs",
    "content": "//@check-pass\n#![warn(clippy::many_single_char_names)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/versioncheck.rs",
    "content": "#![warn(rust_2018_idioms, unused_lifetimes)]\n#![allow(clippy::single_match_else)]\n\nuse std::fs;\n\n#[test]\nfn consistent_clippy_crate_versions() {\n    fn read_version(path: &str) -> String {\n        let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!(\"error reading `{path}`: {e:?}\"));\n        contents\n            .lines()\n            .filter_map(|l| l.split_once('='))\n            .find_map(|(k, v)| (k.trim() == \"version\").then(|| v.trim()))\n            .unwrap_or_else(|| panic!(\"error finding version in `{path}`\"))\n            .to_string()\n    }\n\n    // do not run this test inside the upstream rustc repo:\n    // https://github.com/rust-lang/rust-clippy/issues/6683\n    if option_env!(\"RUSTC_TEST_SUITE\").is_some() {\n        return;\n    }\n\n    let clippy_version = read_version(\"Cargo.toml\");\n\n    let paths = [\n        \"clippy_config/Cargo.toml\",\n        \"clippy_lints/Cargo.toml\",\n        \"clippy_utils/Cargo.toml\",\n        \"declare_clippy_lint/Cargo.toml\",\n    ];\n\n    for path in paths {\n        assert_eq!(clippy_version, read_version(path), \"{path} version differs\");\n    }\n}\n\n#[test]\nfn check_that_clippy_has_the_same_major_version_as_rustc() {\n    // do not run this test inside the upstream rustc repo:\n    // https://github.com/rust-lang/rust-clippy/issues/6683\n    if option_env!(\"RUSTC_TEST_SUITE\").is_some() {\n        return;\n    }\n\n    let clippy_version = rustc_tools_util::get_version_info!();\n    let clippy_major = clippy_version.major;\n    let clippy_minor = clippy_version.minor;\n    let clippy_patch = clippy_version.patch;\n\n    // get the rustc version either from the rustc installed with the toolchain file or from\n    // `RUSTC_REAL` if Clippy is build in the Rust repo with `./x.py`.\n    let rustc = std::env::var(\"RUSTC_REAL\").unwrap_or_else(|_| \"rustc\".to_string());\n    let rustc_version = String::from_utf8(\n        std::process::Command::new(rustc)\n            .arg(\"--version\")\n            .output()\n            .expect(\"failed to run `rustc --version`\")\n            .stdout,\n    )\n    .unwrap();\n    // extract \"1 XX 0\" from \"rustc 1.XX.0-nightly (<commit> <date>)\"\n    let vsplit: Vec<&str> = rustc_version\n        .split(' ')\n        .nth(1)\n        .unwrap()\n        .split('-')\n        .next()\n        .unwrap()\n        .split('.')\n        .collect();\n    match vsplit.as_slice() {\n        [rustc_major, rustc_minor, _rustc_patch] => {\n            // clippy 0.1.XX should correspond to rustc 1.XX.0\n            assert_eq!(clippy_major, 0); // this will probably stay the same for a long time\n            assert_eq!(\n                clippy_minor.to_string(),\n                *rustc_major,\n                \"clippy minor version does not equal rustc major version\"\n            );\n            assert_eq!(\n                clippy_patch.to_string(),\n                *rustc_minor,\n                \"clippy patch version does not equal rustc minor version\"\n            );\n            // do not check rustc_patch because when a stable-patch-release is made (like 1.50.2),\n            // we don't want our tests failing suddenly\n        },\n        _ => {\n            panic!(\"Failed to parse rustc version: {vsplit:?}\");\n        },\n    }\n}\n\n#[test]\nfn check_host_compiler() {\n    // do not run this test inside the upstream rustc repo:\n    if option_env!(\"RUSTC_TEST_SUITE\").is_some() {\n        return;\n    }\n\n    let version = rustc_tools_util::get_version_info!();\n    assert_eq!(version.host_compiler, Some(\"nightly\".to_string()));\n}\n"
  },
  {
    "path": "tests/workspace.rs",
    "content": "use std::path::PathBuf;\nuse std::process::Command;\nuse test_utils::{CARGO_CLIPPY_PATH, IS_RUSTC_TEST_SUITE};\n\nmod test_utils;\n\n#[test]\nfn test_module_style_with_dep_in_subdir() {\n    if IS_RUSTC_TEST_SUITE {\n        return;\n    }\n    let root = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"));\n    let target_dir = root.join(\"target\").join(\"workspace_test\");\n    let cwd = root.join(\"tests/workspace_test\");\n\n    // Make sure we start with a clean state\n    Command::new(\"cargo\")\n        .current_dir(&cwd)\n        .env(\"CARGO_TARGET_DIR\", &target_dir)\n        .arg(\"clean\")\n        .args([\"-p\", \"pass-no-mod-with-dep-in-subdir\"])\n        .args([\"-p\", \"pass-mod-with-dep-in-subdir\"])\n        .output()\n        .unwrap();\n\n    // [#8887](https://github.com/rust-lang/rust-clippy/issues/8887)\n    // `mod.rs` checks should not be applied to crate dependencies\n    // located in the subdirectory of workspace\n    let output = Command::new(&*CARGO_CLIPPY_PATH)\n        .current_dir(&cwd)\n        .env(\"CARGO_INCREMENTAL\", \"0\")\n        .env(\"CARGO_TARGET_DIR\", &target_dir)\n        .arg(\"clippy\")\n        .args([\"-p\", \"pass-no-mod-with-dep-in-subdir\"])\n        .args([\"-p\", \"pass-mod-with-dep-in-subdir\"])\n        .arg(\"--\")\n        .arg(\"-Cdebuginfo=0\") // disable debuginfo to generate less data in the target dir\n        .output()\n        .unwrap();\n\n    println!(\"status: {}\", output.status);\n    println!(\"stdout: {}\", String::from_utf8_lossy(&output.stdout));\n    println!(\"stderr: {}\", String::from_utf8_lossy(&output.stderr));\n    assert!(output.status.success());\n}\n\n#[test]\nfn test_no_deps_ignores_path_deps_in_workspaces() {\n    if IS_RUSTC_TEST_SUITE {\n        return;\n    }\n    let root = PathBuf::from(env!(\"CARGO_MANIFEST_DIR\"));\n    let target_dir = root.join(\"target\").join(\"workspace_test\");\n    let cwd = root.join(\"tests/workspace_test\");\n\n    // Make sure we start with a clean state\n    Command::new(\"cargo\")\n        .current_dir(&cwd)\n        .env(\"CARGO_TARGET_DIR\", &target_dir)\n        .arg(\"clean\")\n        .args([\"-p\", \"subcrate\"])\n        .args([\"-p\", \"path_dep\"])\n        .output()\n        .unwrap();\n\n    // `path_dep` is a path dependency of `subcrate` that would trigger a denied lint.\n    // Make sure that with the `--no-deps` argument Clippy does not run on `path_dep`.\n    let output = Command::new(&*CARGO_CLIPPY_PATH)\n        .current_dir(&cwd)\n        .env(\"CARGO_INCREMENTAL\", \"0\")\n        .env(\"CARGO_TARGET_DIR\", &target_dir)\n        .arg(\"clippy\")\n        .args([\"-p\", \"subcrate\"])\n        .arg(\"--no-deps\")\n        .arg(\"--\")\n        .arg(\"-Cdebuginfo=0\") // disable debuginfo to generate less data in the target dir\n        .args([\"--cfg\", r#\"feature=\"primary_package_test\"\"#])\n        .output()\n        .unwrap();\n    println!(\"status: {}\", output.status);\n    println!(\"stdout: {}\", String::from_utf8_lossy(&output.stdout));\n    println!(\"stderr: {}\", String::from_utf8_lossy(&output.stderr));\n\n    assert!(output.status.success());\n\n    let lint_path_dep = || {\n        // Test that without the `--no-deps` argument, `path_dep` is linted.\n        let output = Command::new(&*CARGO_CLIPPY_PATH)\n            .current_dir(&cwd)\n            .env(\"CARGO_INCREMENTAL\", \"0\")\n            .env(\"CARGO_TARGET_DIR\", &target_dir)\n            .arg(\"clippy\")\n            .args([\"-p\", \"subcrate\"])\n            .arg(\"--\")\n            .arg(\"-Cdebuginfo=0\") // disable debuginfo to generate less data in the target dir\n            .args([\"--cfg\", r#\"feature=\"primary_package_test\"\"#])\n            .output()\n            .unwrap();\n        println!(\"status: {}\", output.status);\n        println!(\"stdout: {}\", String::from_utf8_lossy(&output.stdout));\n        println!(\"stderr: {}\", String::from_utf8_lossy(&output.stderr));\n\n        assert!(!output.status.success());\n        assert!(\n            String::from_utf8(output.stderr)\n                .unwrap()\n                .contains(\"error: empty `loop {}` wastes CPU cycles\")\n        );\n    };\n\n    // Make sure Cargo is aware of the removal of `--no-deps`.\n    lint_path_dep();\n\n    let successful_build = || {\n        let output = Command::new(&*CARGO_CLIPPY_PATH)\n            .current_dir(&cwd)\n            .env(\"CARGO_INCREMENTAL\", \"0\")\n            .env(\"CARGO_TARGET_DIR\", &target_dir)\n            .arg(\"clippy\")\n            .args([\"-p\", \"subcrate\"])\n            .arg(\"--\")\n            .arg(\"-Cdebuginfo=0\") // disable debuginfo to generate less data in the target dir\n            .output()\n            .unwrap();\n        println!(\"status: {}\", output.status);\n        println!(\"stdout: {}\", String::from_utf8_lossy(&output.stdout));\n        println!(\"stderr: {}\", String::from_utf8_lossy(&output.stderr));\n\n        assert!(output.status.success());\n\n        output\n    };\n\n    // Trigger a successful build, so Cargo would like to cache the build result.\n    successful_build();\n\n    // Make sure there's no spurious rebuild when nothing changes.\n    let stderr = String::from_utf8(successful_build().stderr).unwrap();\n    assert!(!stderr.contains(\"Compiling\"));\n    assert!(!stderr.contains(\"Checking\"));\n    assert!(stderr.contains(\"Finished\"));\n\n    // Make sure Cargo is aware of the new `--cfg` flag.\n    lint_path_dep();\n}\n"
  },
  {
    "path": "tests/workspace_test/Cargo.toml",
    "content": "[package]\nname = \"workspace_test\"\nversion = \"0.1.0\"\nedition = \"2018\"\n\n[workspace]\nmembers = [\"subcrate\", \"module_style/pass_no_mod_with_dep_in_subdir\", \"module_style/pass_mod_with_dep_in_subdir\"]\n"
  },
  {
    "path": "tests/workspace_test/build.rs",
    "content": "#![deny(clippy::print_stdout)]\n\nfn main() {\n    // Test for #6041\n    println!(\"Hello\");\n    print!(\"Hello\");\n}\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/Cargo.toml",
    "content": "[package]\nname = \"pass-mod-with-dep-in-subdir\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\ndep-no-mod = { path = \"dep_no_mod\"}\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/Cargo.toml",
    "content": "[package]\nname = \"dep-no-mod\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo/hello.rs",
    "content": "pub struct Hello;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/foo.rs",
    "content": "pub mod hello;\npub struct Thing;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/dep_no_mod/src/lib.rs",
    "content": "pub mod foo;\n\npub fn foo() {\n    let _ = foo::Thing;\n}\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/bad/mod.rs",
    "content": "pub struct Thing;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/main.rs",
    "content": "#![deny(clippy::self_named_module_files)]\n\nmod bad;\nmod more;\nextern crate dep_no_mod;\n\nfn main() {\n    let _ = bad::Thing;\n    let _ = more::foo::Foo;\n    let _ = more::inner::Inner;\n    let _ = dep_no_mod::foo::Thing;\n    let _ = dep_no_mod::foo::hello::Hello;\n}\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/foo.rs",
    "content": "pub struct Foo;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/inner/mod.rs",
    "content": "pub struct Inner;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_mod_with_dep_in_subdir/src/more/mod.rs",
    "content": "pub mod foo;\npub mod inner;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/Cargo.toml",
    "content": "[package]\nname = \"pass-no-mod-with-dep-in-subdir\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\ndep-with-mod = { path = \"dep_with_mod\"}\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/Cargo.toml",
    "content": "[package]\nname = \"dep-with-mod\"\nversion = \"0.1.0\"\nedition = \"2018\"\npublish = false\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/lib.rs",
    "content": "pub mod with_mod;\n\npub fn foo() {\n    let _ = with_mod::Thing;\n    let _ = with_mod::inner::stuff::Inner;\n    let _ = with_mod::inner::stuff::most::Snarks;\n}\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff/most.rs",
    "content": "pub struct Snarks;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner/stuff.rs",
    "content": "pub mod most;\n\npub struct Inner;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/inner.rs",
    "content": "pub mod stuff;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/dep_with_mod/src/with_mod/mod.rs",
    "content": "pub mod inner;\n\npub struct Thing;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/good.rs",
    "content": "pub struct Thing;\n"
  },
  {
    "path": "tests/workspace_test/module_style/pass_no_mod_with_dep_in_subdir/src/main.rs",
    "content": "#![deny(clippy::mod_module_files)]\n\nmod good;\npub use dep_with_mod::with_mod::Thing;\n\nfn main() {\n    let _ = good::Thing;\n    let _ = dep_with_mod::with_mod::Thing;\n}\n"
  },
  {
    "path": "tests/workspace_test/path_dep/Cargo.toml",
    "content": "[package]\nname = \"path_dep\"\nversion = \"0.1.0\"\n\n[features]\nprimary_package_test = []\n"
  },
  {
    "path": "tests/workspace_test/path_dep/src/lib.rs",
    "content": "#![deny(clippy::empty_loop)]\n\n#[cfg(feature = \"primary_package_test\")]\npub fn lint_me() {\n    loop {}\n}\n"
  },
  {
    "path": "tests/workspace_test/src/main.rs",
    "content": "#![deny(rust_2018_idioms)]\n\nfn main() {}\n"
  },
  {
    "path": "tests/workspace_test/subcrate/Cargo.toml",
    "content": "[package]\nname = \"subcrate\"\nversion = \"0.1.0\"\n\n[dependencies]\npath_dep = { path = \"../path_dep\" }\n"
  },
  {
    "path": "tests/workspace_test/subcrate/src/lib.rs",
    "content": "\n"
  },
  {
    "path": "triagebot.toml",
    "content": "[relabel]\nallow-unauthenticated = [\n    \"A-*\", \"C-*\", \"E-*\", \"I-*\", \"L-*\", \"P-*\", \"S-*\", \"T-*\",\n    \"good first issue\", \"beta-nominated\"\n]\n\n# Allows shortcuts like `@rustbot ready`\n#\n# See https://forge.rust-lang.org/triagebot/shortcuts.html\n[shortcut]\n\n[merge-conflicts]\n\n[note]\n\n[close]\n\n[transfer]\n\n[issue-links]\n\n[mentions.\"clippy_lints/src/doc\"]\ncc = [\"@notriddle\"]\n\n# Have rustbot inform users about the *No Merge Policy*\n[no-merges]\nexclude_titles = [\"Rustup\"] # exclude syncs from rust-lang/rust\nlabels = [\"has-merge-commits\", \"S-waiting-on-author\"]\n\n[review-requested]\n# Those labels are removed when PR author requests a review from an assignee\nremove_labels = [\"S-waiting-on-author\"]\n# Those labels are added when PR author requests a review from an assignee\nadd_labels = [\"S-waiting-on-review\"]\n\n[review-submitted]\n# These labels are removed when a review is submitted.\nreview_labels = [\"S-waiting-on-review\"]\n# This label is added when a review is submitted.\nreviewed_label = \"S-waiting-on-author\"\n\n[autolabel.\"S-waiting-on-review\"]\nnew_pr = true\n\n[autolabel.\"needs-fcp\"]\ntrigger_files = [\"clippy_lints/src/declared_lints.rs\"]\n\n[concern]\n# These labels are set when there are unresolved concerns, removed otherwise\nlabels = [\"S-waiting-on-concerns\"]\n\n# Show differences when a PR is rebased\n[range-diff]\n\n# Amend a review to include a link to what was changed since the review\n[review-changes-since]\n\n# Adds a \"View all comments\" link on the issue/PR body that shows all the comments of it\n# Documentation at: https://forge.rust-lang.org/triagebot/view-all-comments-link.html\n[view-all-comments-link]\nthreshold = 20\n\n[notify-zulip.\"lint-nominated\"]\nzulip_stream = 577190 # #clippy/fcp\ntopic = \"FCP rust-clippy#{number}: {title}\"\ngithub_comment = \"\"\"\\\nThis lint has been nominated for inclusion.\n\n[A FCP topic has been created on Zulip]({zulip_topic_url}).\n\"\"\"\n# Zulip polls may not be preceded by any other text and pings & short links inside\n# the title of a poll don't get recognized. Therefore we need to send two messages.\nmessage_on_add = [\n    \"\"\"\\\nPR rust-clippy#{number} \"{title}\" has been nominated for lint inclusion.\n\"\"\",\n    \"\"\"\\\n/poll Approve lint inclusion of rust-clippy#{number}?\napprove\ndecline\ndon't know\n\"\"\",\n]\nmessage_on_remove = \"PR rust-clippy#{number} lint nomination has been removed.\"\nmessage_on_close = \"PR rust-clippy#{number} has been closed. Thanks for participating!\"\nmessage_on_reopen = \"PR rust-clippy#{number} has been reopened.\"\n\n[assign]\ncontributing_url = \"https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md\"\nusers_on_vacation = [\n    \"matthiaskrgr\",\n    \"Manishearth\",\n    \"Alexendoo\",\n    \"y21\",\n    \"blyxyas\",\n]\n\n[assign.owners]\n\"/.github\" = [\"@flip1995\"]\n\"/triagebot.toml\" = [\"@flip1995\"]\n\"/book\" = [\"@flip1995\"]\n\"*\" = [\n    \"@Manishearth\",\n    \"@llogiq\",\n    \"@Alexendoo\",\n    \"@dswij\",\n    \"@Jarcho\",\n    \"@y21\",\n    \"@samueltardieu\",\n]\n"
  },
  {
    "path": "util/etc/pre-commit.sh",
    "content": "#!/bin/sh\n\n# hide output\nset -e\n\n# Update lints\ncargo dev update_lints\ngit add clippy_lints/src/lib.rs\n\n# Formatting:\n#     Git will not automatically add the formatted code to the staged changes once\n#     fmt was executed. This collects all staged files rs files that are currently staged.\n#     They will later be added back.\n#\n#     This was proudly stolen and adjusted from here:\n#     https://medium.com/@harshitbangar/automatic-code-formatting-with-git-66c3c5c26798\nfiles=$( (git diff --cached --name-only --diff-filter=ACMR | grep -Ei \"\\.rs$\") || true)\nif [ ! -z \"${files}\" ]; then\n    cargo dev fmt\n    git add $(echo \"$files\" | paste -s -d \" \" -)\nfi\n"
  },
  {
    "path": "util/etc/vscode-tasks.json",
    "content": "{\n    \"version\": \"2.0.0\",\n    \"tasks\": [\n        {\n            \"label\": \"cargo check\",\n            \"type\": \"shell\",\n            \"command\": \"cargo check\",\n            \"problemMatcher\": [],\n            \"group\": {\n                \"kind\": \"build\",\n                \"isDefault\": true\n            }\n        },\n        {\n            \"label\": \"cargo dev fmt\",\n            \"type\": \"shell\",\n            \"command\": \"cargo dev fmt\",\n            \"problemMatcher\": [],\n            \"group\": \"none\"\n        },\n        {\n            \"label\": \"cargo uitest\",\n            \"type\": \"shell\",\n            \"command\": \"cargo uitest\",\n            \"options\": {\n                \"env\": {\n                    // This task will usually execute all UI tests inside `tests/ui` you can\n                    // optionally uncomment the line below and only run a specific test.\n                    //\n                    // See: https://github.com/rust-lang/rust-clippy/blob/master/book/src/development/adding_lints.md#testing\n                    //\n                    // \"TESTNAME\": \"<TODO>\",\n                    \"RUST_BACKTRACE\": \"1\"\n                }\n            },\n            \"problemMatcher\": [],\n            \"group\": {\n                \"kind\": \"test\",\n                \"isDefault\": true\n            }\n        },\n        {\n            \"label\": \"cargo test\",\n            \"type\": \"shell\",\n            \"command\": \"cargo test\",\n            \"problemMatcher\": [],\n            \"group\": \"test\"\n        },\n        {\n            \"label\": \"bless ui tests\",\n            \"type\": \"shell\",\n            \"command\": \"cargo bless\",\n            \"problemMatcher\": [],\n            \"group\": \"none\"\n        }\n    ]\n}\n"
  },
  {
    "path": "util/fetch_prs_between.sh",
    "content": "#!/bin/bash\n\n# Fetches the merge commits between two git commits and prints the PR URL\n# together with the full commit message\n#\n# If you want to use this to update the Clippy changelog, be sure to manually\n# exclude the non-user facing changes like 'rustup' PRs, typo fixes, etc.\n\nset -e\n\nIFS='\n'\nfor pr in $(git log --oneline --merges --first-parent \"$1...$2\"); do\n  id=$(echo \"$pr\" | rg -o '#[0-9]{3,5}' | cut -c 2-)\n  commit=$(echo \"$pr\" | cut -d' ' -f 1)\n  message=$(git --no-pager show --pretty=medium \"$commit\")\n\n  if [[ -z \"$newest_pr\" ]]; then\n    newest_pr=\"$id\"\n  fi\n  oldest_pr=\"$id\"\n\n  if [[ -n $(echo \"$message\" | rg \"^[\\s]{4}changelog: [nN]one\\.*$\") ]]; then\n    continue\n  fi\n\n  echo \"URL: https://github.com/rust-lang/rust-clippy/pull/$id\"\n  echo \"Markdown URL: [#$id](https://github.com/rust-lang/rust-clippy/pull/$id)\"\n  echo \"$message\"\n  echo \"---------------------------------------------------------\"\n  echo\ndone\n\nnewest_merged_at=\"$(gh pr view -R rust-lang/rust-clippy --json mergedAt $newest_pr -q .mergedAt)\"\noldest_merged_at=\"$(gh pr view -R rust-lang/rust-clippy --json mergedAt $oldest_pr -q .mergedAt)\"\n\nquery=\"merged:$oldest_merged_at..$newest_merged_at base:master\"\nencoded_query=\"$(echo $query | sed 's/ /+/g; s/:/%3A/g')\"\n\npr_link=\"https://github.com/rust-lang/rust-clippy/pulls?q=$encoded_query\"\ncount=\"$(gh api -X GET search/issues -f \"q=$query repo:rust-lang/rust-clippy\" -q .total_count)\"\n\necho \"[View all $count merged pull requests]($pr_link)\"\n"
  },
  {
    "path": "util/gh-pages/index_template.html",
    "content": "<!DOCTYPE html>\n<!--\nWelcome to a Clippy's lint list, at least the source code of it. If you are\ninterested in contributing to this website checkout `util/gh-pages/index_template.html`\ninside the rust-clippy repository.\n\nOtherwise, have a great day =^.^=\n-->\n<html lang=\"en\"> {# #}\n<head> {# #}\n    <meta charset=\"UTF-8\"/> {# #}\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/> {# #}\n    <meta name=\"description\" content=\"A collection of lints to catch common mistakes and improve your Rust code.\"> {# #}\n\n    <title>Clippy Lints</title> {# #}\n\n    <link id=\"githubLightHighlight\" rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github.min.css\" disabled=\"true\" /> {# #}\n    <link id=\"githubDarkHighlight\" rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github-dark.min.css\" disabled=\"true\" /> {# #}\n\n    <!-- The files are not copied over into the Clippy project since they use the MPL-2.0 License -->\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/rust-lang/mdBook@0.4.46/src/theme/css/variables.css\"/> {# #}\n    <link id=\"styleHighlight\" rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/rust-lang/mdBook@0.4.46/src/theme/highlight.css\"> {# #}\n    <link id=\"styleNight\" rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/rust-lang/mdBook@0.4.46/src/theme/tomorrow-night.css\" disabled=\"true\"> {# #}\n    <link id=\"styleAyu\" rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/rust-lang/mdBook@0.4.46/src/theme/ayu-highlight.css\" disabled=\"true\"> {# #}\n    <link rel=\"stylesheet\" href=\"style.css\"> {# #}\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js\" defer></script> {# #}\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/rust.min.js\" defer></script> {# #}\n    <script src=\"script.js\" defer></script> {# #}\n</head> {# #}\n<body> {# #}\n    <div id=\"settings-dropdown\" class=\"dropdown\"> {# #}\n        <button class=\"settings-icon\" tabindex=\"-1\"></button> {# #}\n        <div class=\"settings-menu\" tabindex=\"-1\"> {# #}\n            <div class=\"setting-radio-name\">Theme</div> {# #}\n            <select id=\"theme-choice\"> {# #}\n                <option value=\"ayu\">Ayu</option> {# #}\n                <option value=\"coal\">Coal</option> {# #}\n                <option value=\"light\">Light</option> {# #}\n                <option value=\"navy\">Navy</option> {# #}\n                <option value=\"rust\">Rust</option> {# #}\n            </select> {# #}\n            <label> {# #}\n                <input type=\"checkbox\" id=\"disable-shortcuts\"> {#+ #}\n                <span>Disable keyboard shortcuts</span> {# #}\n            </label> {# #}\n        </div> {# #}\n    </div> {# #}\n    <script src=\"theme.js\"></script> {# #}\n\n    <div class=\"container\"> {# #}\n        <h1 class=\"page-header\">Clippy Lints <span class=\"badge\">Total number: {{+ count }}</span></h1> {# #}\n\n        <noscript> {# #}\n            <div class=\"alert alert-danger\" role=\"alert\"> {# #}\n                Lints search and filtering only works with JS enabled. :( {# #}\n            </div> {# #}\n        </noscript> {# #}\n\n        <div id=\"menu-filters\"> {# #}\n            <div id=\"upper-filters\"> {# #}\n                <div class=\"dropdown\" data-filter=\"levels\" tabindex=\"-1\"> {# #}\n                    <button type=\"button\" class=\"btn-default dropdown-toggle\"> {# #}\n                        Lint levels <span id=\"levels-count\" class=\"badge\">4</span> <span class=\"caret\"></span> {# #}\n                    </button> {# #}\n                    <ul class=\"dropdown-menu\"> {# #}\n                        <li class=\"checkbox\"> {# #}\n                            <button class=\"reset-all\">All</button> {# #}\n                        </li> {# #}\n                        <li class=\"checkbox\"> {# #}\n                            <button class=\"reset-none\">None</button> {# #}\n                        </li> {# #}\n                        <li role=\"separator\" class=\"divider\"></li> {# #}\n                        {% for level in [\"allow\", \"warn\", \"deny\", \"none\"] %}\n                            <li class=\"checkbox\"> {# #}\n                                <label> {# #}\n                                    <input type=\"checkbox\" name=\"{{ level }}\" checked />\n                                    {{ level | capitalize }}\n                                </label> {# #}\n                            </li> {# #}\n                        {% endfor %}\n                    </ul> {# #}\n                </div> {# #}\n                <div class=\"dropdown\" data-filter=\"groups\" tabindex=\"-1\"> {# #}\n                    <button type=\"button\" class=\"btn-default dropdown-toggle\"> {# #}\n                        Lint groups <span id=\"groups-count\" class=\"badge\">9</span> <span class=\"caret\"></span> {# #}\n                    </button> {# #}\n                    <ul class=\"dropdown-menu\"> {# #}\n                        <li class=\"checkbox\"> {# #}\n                            <button class=\"reset-all\">All</button> {# #}\n                        </li> {# #}\n                        <li class=\"checkbox\"> {# #}\n                            <button class=\"reset-default\">Default</button> {# #}\n                        </li> {# #}\n                        <li class=\"checkbox\"> {# #}\n                            <button class=\"reset-none\">None</button> {# #}\n                        </li> {# #}\n                        <li role=\"separator\" class=\"divider\"></li> {# #}\n                        {% for group in [\"cargo\", \"complexity\", \"correctness\", \"nursery\", \"pedantic\", \"perf\", \"restriction\", \"style\", \"suspicious\", \"deprecated\"] %}\n                            <li class=\"checkbox\"> {# #}\n                                <label> {# #}\n                                    <input type=\"checkbox\" name=\"{{ group }}\" {% if *group != \"deprecated\" +%} checked {% endif %} />\n                                    {{ group | capitalize }}\n                                </label> {# #}\n                            </li> {# #}\n                        {% endfor %}\n                    </ul> {# #}\n                </div> {# #}\n                <div id=\"version-filter\" class=\"dropdown\" tabindex=\"-1\"> {# #}\n                    <button type=\"button\" class=\"btn-default dropdown-toggle\"> {# #}\n                        Version {#+ #}\n                        <span id=\"versions-count\" class=\"badge\">0</span> {#+ #}\n                        <span class=\"caret\"></span> {# #}\n                    </button> {# #}\n                    <ul class=\"dropdown-menu\"> {# #}\n                        <li class=\"checkbox\"> {# #}\n                            <button id=\"reset-versions\">Clear filters</button> {# #}\n                        </li> {# #}\n                        <li role=\"separator\" class=\"divider\"></li> {# #}\n                        {% for (sym, name) in [(\"≥\", \"gte\"), (\"≤\", \"lte\"), (\"=\", \"eq\")] %}\n                            <li class=\"checkbox\"> {# #}\n                                <label>{{ sym }}</label> {#+ #}\n                                <span>1.</span> {# #}\n                                <input type=\"number\" name=\"{{ name }}\" min=\"29\" maxlength=\"2\" class=\"version-filter-input form-control filter-input\" /> {# #}\n                                <span>.0</span> {# #}\n                            </li> {# #}\n                        {% endfor %}\n                    </ul> {# #}\n                </div> {# #}\n                <div class=\"dropdown\" data-filter=\"applicabilities\" tabindex=\"-1\"> {# #}\n                    <button type=\"button\" class=\"btn-default dropdown-toggle\"> {# #}\n                        Applicability {#+ #}\n                        <span id=\"applicabilities-count\" class=\"badge\">4</span> {#+ #}\n                        <span class=\"caret\"></span> {# #}\n                    </button> {# #}\n                    <ul class=\"dropdown-menu\"> {# #}\n                        <li class=\"checkbox\"> {# #}\n                            <button class=\"reset-all\">All</button> {# #}\n                        </li> {# #}\n                        <li class=\"checkbox\"> {# #}\n                            <button class=\"reset-none\">None</button> {# #}\n                        </li> {# #}\n                        <li role=\"separator\" class=\"divider\"></li> {# #}\n                        {% for applicability in [\"Unspecified\", \"MachineApplicable\", \"MaybeIncorrect\", \"HasPlaceholders\"] %}\n                            <li class=\"checkbox\"> {# #}\n                                <label> {# #}\n                                    <input type=\"checkbox\" name=\"{{ applicability }}\" checked />\n                                    {{ applicability }}\n                                </label> {# #}\n                            </li> {# #}\n                        {% endfor %}\n                    </ul> {# #}\n                </div> {# #}\n            </div> {# #}\n            <div class=\"search-control\"> {# #}\n                <label class=\"input-group-addon\" id=\"filter-label\" for=\"search-input\">Filter:</label> {# #}\n                <input type=\"text\" class=\"form-control filter-input\" placeholder=\"Keywords or search string (`S` or `/` to focus)\" id=\"search-input\" /> {# #}\n                <button id=\"filter-clear\" type=\"button\"> {# #}\n                    Clear {# #}\n                </button> {# #}\n            </div> {# #}\n            <div class=\"btn-group expansion-group\"> {# #}\n                <button title=\"Collapse All\" class=\"btn-default expansion-control\" type=\"button\" id=\"collapse-all\"> {# #}\n                    <span class=\"glyphicon glyphicon-collapse-up\"></span> {# #}\n                </button> {# #}\n                <button title=\"Expand All\" class=\"btn-default expansion-control\" type=\"button\" id=\"expand-all\"> {# #}\n                    <span class=\"glyphicon glyphicon-collapse-down\"></span> {# #}\n                </button> {# #}\n            </div> {# #}\n        </div>\n        {% for lint in lints %}\n            <article id=\"{{lint.id}}\"> {# #}\n                <input id=\"label-{{lint.id}}\" type=\"checkbox\"> {# #}\n                <label for=\"label-{{lint.id}}\"> {# #}\n                    <h2 class=\"lint-title\"> {# #}\n                        <div class=\"panel-title-name\" id=\"lint-{{lint.id}}\"> {# #}\n                            {{lint.id ~}}\n                            <a href=\"#{{lint.id}}\" class=\"anchor label\">&para;</a> {#+ #}\n                            <a href=\"\" class=\"copy-to-clipboard anchor label\"> {# #}\n                                &#128203; {# #}\n                            </a> {# #}\n                        </div> {# #}\n\n                        <span class=\"label lint-group group-{{lint.group}}\">{{lint.group}}</span> {#+ #}\n\n                        <span class=\"label lint-level level-{{lint.level}}\">{{lint.level}}</span> {#+ #}\n\n                        <span class=\"label doc-folding\"></span> {# #}\n                    </h2> {# #}\n                </label> {# #}\n\n                <div class=\"lint-docs\"> {# #}\n                    <div class=\"lint-doc-md\">{{Self::markdown(lint.docs)}}</div> {# #}\n                    <div class=\"lint-additional-info\">\n                        {# Applicability #}\n                        <div> {# #}\n                            Applicability: {#+ #}\n                            <span class=\"label applicability\">{{ lint.applicability_str() }}</span> {# #}\n                            <a href=\"https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.Applicability.html#variants\">(?)</a> {# #}\n                        </div>\n                        {# Clippy version #}\n                        <div> {# #}\n                            {% if lint.group == \"deprecated\" %}Deprecated{% else %} Added{% endif +%} in: {#+ #}\n                            <span class=\"label label-version\">{{lint.version}}</span> {# #}\n                        </div>\n                        {# Open related issues #}\n                        <a href=\"https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+{{lint.id}}\">Related Issues</a>\n\n                        {# Jump to source #}\n                        {% if let Some(id_location) = lint.id_location %}\n                            <a href=\"https://github.com/rust-lang/rust-clippy/blob/master/{{id_location}}\">View Source</a>\n                        {% endif %}\n                    </div> {# #}\n                </div> {# #}\n            </article>\n        {% endfor %}\n    </div> {# #}\n\n    <a {#+ #}\n        aria-label=\"View source on GitHub\" {#+ #}\n        class=\"github-corner\" {#+ #}\n        href=\"https://github.com/rust-lang/rust-clippy\" {#+ #}\n        rel=\"noopener noreferrer\" {#+ #}\n        target=\"_blank\" {# #}\n    > {# #}\n        <svg {#+ #}\n            width=\"80\" {#+ #}\n            height=\"80\" {#+ #}\n            viewBox=\"0 0 250 250\" {#+ #}\n            style=\"position: absolute; top: 0; border: 0; right: 0\" {#+ #}\n            aria-hidden=\"true\" {# #}\n        > {# #}\n            <path d=\"M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z\" fill=\"var(--theme-color)\"></path> {# #}\n            <path {#+ #}\n                d=\"M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2\" {#+ #}\n                fill=\"currentColor\" {#+ #}\n                style=\"transform-origin: 130px 106px\" {#+ #}\n                class=\"octo-arm\" {# #}\n            ></path> {# #}\n            <path {#+ #}\n                d=\"M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z\" {#+ #}\n                fill=\"currentColor\" {#+ #}\n                class=\"octo-body\" {# #}\n            ></path> {# #}\n        </svg> {# #}\n    </a> {# #}\n</body> {# #}\n</html> {# #}\n"
  },
  {
    "path": "util/gh-pages/script.js",
    "content": "\"use strict\";\n\nconst searchState = {\n    lastSearch: '',\n    filterLints: (updateURL = true) => {\n        function matchesSearch(lint, terms, searchStr) {\n            // Search by id\n            if (lint.elem.id.indexOf(searchStr) !== -1) {\n                return true;\n            }\n            // Search the description\n            // The use of `for`-loops instead of `foreach` enables us to return early\n            const docsLowerCase = lint.elem.textContent.toLowerCase();\n            for (const term of terms) {\n                // This is more likely and will therefore be checked first\n                if (docsLowerCase.indexOf(term) !== -1) {\n                    return true;\n                }\n\n                if (lint.elem.id.indexOf(term) !== -1) {\n                    return true;\n                }\n\n                return false;\n            }\n            return true;\n        }\n\n        let searchStr = elements.search.value.trim().toLowerCase();\n        if (searchStr.startsWith(\"clippy::\")) {\n            searchStr = searchStr.slice(8);\n        }\n        if (searchState.lastSearch === searchStr) {\n            return;\n        }\n        searchState.lastSearch = searchStr;\n        const terms = searchStr.split(\" \");\n        const cleanedSearchStr = searchStr.replaceAll(\"-\", \"_\");\n\n        for (const lint of filters.getAllLints()) {\n            lint.searchFilteredOut = !matchesSearch(lint, terms, cleanedSearchStr);\n            if (lint.searchFilteredOut || lint.filteredOut) {\n                lint.elem.style.display = \"none\";\n            } else {\n                lint.elem.style.display = \"\";\n            }\n        }\n\n        if (updateURL) {\n            setURL();\n        }\n    },\n};\n\nfunction handleInputChanged(event) {\n    if (event.target !== document.activeElement) {\n        return;\n    }\n    searchState.filterLints();\n}\n\nfunction handleShortcut(ev) {\n    if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) {\n        return;\n    }\n\n    if (document.activeElement.tagName === \"INPUT\") {\n        if (ev.key === \"Escape\") {\n            document.activeElement.blur();\n        }\n    } else {\n        switch (ev.key) {\n            case \"s\":\n            case \"S\":\n            case \"/\":\n                ev.preventDefault(); // To prevent the key to be put into the input.\n                elements.search.focus();\n                break;\n            default:\n                break;\n        }\n    }\n}\n\n/**\n * When `value` is `null` the default value is used - true for all but the `deprecated` lint group\n */\nfunction resetCheckboxes(filter, value) {\n    for (const element of elements.checkboxes[filter]) {\n        const checked = value ?? element.name !== \"deprecated\";\n        element.checked = checked;\n    }\n}\n\nfunction onEachLazy(lazyArray, func) {\n    const arr = Array.prototype.slice.call(lazyArray);\n    for (const el of arr) {\n        func(el);\n    }\n}\n\nfunction expandLint(lintId) {\n    const elem = document.querySelector(`#${lintId} > input[type=\"checkbox\"]`);\n    if (elem) {\n        elem.checked = true;\n    }\n}\n\nconst clipboardTimeouts = new Map();\nfunction copyToClipboard(event) {\n    event.preventDefault();\n    event.stopPropagation();\n\n    const clipboard = event.target;\n\n    navigator.clipboard.writeText(\"clippy::\" + clipboard.parentElement.id.slice(5));\n\n    clipboard.textContent = \"✓\";\n\n    clearTimeout(clipboardTimeouts.get(clipboard));\n    clipboardTimeouts.set(\n        clipboard,\n        setTimeout(() => {\n            clipboard.textContent = \"📋\";\n            clipboardTimeouts.delete(clipboard);\n        }, 1000)\n    );\n}\n\nfunction toggleExpansion(expand) {\n    for (const checkbox of document.querySelectorAll(\"article input[type=checkbox]\")) {\n        checkbox.checked = expand;\n    }\n}\n\nconst filters = {\n    allLints: null,\n    getAllLints: () => {\n        if (filters.allLints === null) {\n            filters.allLints = Array.prototype.slice.call(\n                document.getElementsByTagName(\"article\"),\n            ).map(elem => {\n                let version = elem.querySelector(\".label-version\").innerText;\n                // Strip the \"pre \" prefix for pre 1.29.0 lints\n                if (version.startsWith(\"pre \")) {\n                    version = version.slice(4);\n                }\n                return {\n                    elem: elem,\n                    group: elem.querySelector(\".lint-group\").innerText,\n                    level: elem.querySelector(\".lint-level\").innerText,\n                    version: parseInt(version.split(\".\")[1]),\n                    applicability: elem.querySelector(\".applicability\").innerText,\n                    filteredOut: false,\n                    searchFilteredOut: false,\n                };\n            });\n        }\n        return filters.allLints;\n    },\n    filterLints: (updateURL = true) => {\n        const [levels, groups, applicabilities] = [\"levels\", \"groups\", \"applicabilities\"].map(key => new Set(\n            elements.checkboxes[key]\n                .filter(checkbox => checkbox.checked)\n                .map(checkbox => checkbox.name)\n        ));\n\n        const [lte, gte, eq] = [\"lte\", \"gte\", \"eq\"].map(key => Number(elements.versions[key].value));\n\n        elements.counts.versions.textContent = (lte > 0) + (gte > 0) + (eq > 0);\n        elements.counts.groups.textContent = groups.size;\n        elements.counts.levels.textContent = levels.size;\n        elements.counts.applicabilities.textContent = applicabilities.size;\n\n        for (const lint of filters.getAllLints()) {\n            lint.filteredOut = (!groups.has(lint.group)\n                || !levels.has(lint.level)\n                || !applicabilities.has(lint.applicability)\n                || !(eq === 0 || lint.version === eq)\n                || !(gte === 0 || lint.version >= gte)\n                || !(lte === 0 || lint.version <= lte)\n            );\n            if (lint.filteredOut || lint.searchFilteredOut) {\n                lint.elem.style.display = \"none\";\n            } else {\n                lint.elem.style.display = \"\";\n            }\n        }\n\n        if (updateURL) {\n            setURL();\n        }\n    },\n};\n\nfunction setupDropdown(elem) {\n    const button = elem.querySelector(\"button\");\n    button.onclick = () => elem.classList.toggle(\"open\");\n\n    const setBlur = child => {\n        child.onblur = event => {\n            if (!elem.contains(document.activeElement) &&\n                !elem.contains(event.relatedTarget)\n            ) {\n                elem.classList.remove(\"open\");\n            }\n        }\n    };\n    onEachLazy(elem.children, setBlur);\n    onEachLazy(elem.querySelectorAll(\"select\"), setBlur);\n    onEachLazy(elem.querySelectorAll(\"input\"), setBlur);\n    onEachLazy(elem.querySelectorAll(\"ul button\"), setBlur);\n}\n\nfunction setURL() {\n    const url = new URL(location);\n\n    function nonDefault(filter) {\n        return elements.checkboxes[filter]\n            .some(element => element.checked === (element.name === \"deprecated\"));\n    }\n    function setBoolean(filter) {\n        if (nonDefault(filter)) {\n            const value = elements.checkboxes[filter]\n                .filter(el => el.checked)\n                .map(el => el.name)\n                .join(\",\");\n            url.searchParams.set(filter, value);\n        }\n    }\n\n    url.search = \"\";\n    setBoolean(\"groups\");\n    setBoolean(\"levels\");\n    setBoolean(\"applicabilities\");\n\n    const versions = [\"eq\", \"gte\", \"lte\"]\n        .filter(op => elements.versions[op].value)\n        .map(op => `${op}:${elements.versions[op].value}`)\n        .join(\",\");\n    if (versions) {\n        url.searchParams.set(\"versions\", versions);\n    }\n\n    const search = elements.search.value;\n    if (search) {\n        url.searchParams.set(\"search\", search)\n    }\n\n    url.hash = \"\";\n\n    if (!history.state) {\n        history.pushState(true, \"\", url);\n    } else {\n        history.replaceState(true, \"\", url);\n    }\n}\n\nfunction parseURL() {\n    const params = new URLSearchParams(window.location.search);\n\n    for (const [filter, checkboxes] of Object.entries(elements.checkboxes)) {\n        if (params.has(filter)) {\n            const settings = new Set(params.get(filter).split(\",\"));\n\n            for (const checkbox of checkboxes) {\n                checkbox.checked = settings.has(checkbox.name);\n            }\n        } else {\n            resetCheckboxes(filter, null);\n        }\n    }\n\n    const versionStr = params.get(\"versions\") ?? \"\";\n    const versions = new Map(versionStr.split(\",\").map(elem => elem.split(\":\")));\n    for (const element of Object.values(elements.versions)) {\n        element.value = versions.get(element.name) ?? \"\";\n    }\n\n    elements.search.value = params.get(\"search\");\n\n    if (location.hash) {\n        expandLint(location.hash.slice(1));\n    }\n\n    filters.filterLints(false);\n    searchState.filterLints(false);\n}\n\nfunction addResetListeners(selector, value) {\n    for (const button of document.querySelectorAll(selector)) {\n        button.addEventListener(\"click\", event => {\n            const container = event.target.closest(\"[data-filter]\");\n            const filter = container.dataset.filter;\n            resetCheckboxes(filter, value);\n            filters.filterLints();\n        })\n    }\n}\n\nfunction addListeners() {\n    document.getElementById(\"upper-filters\").addEventListener(\"input\", () => {\n        filters.filterLints();\n    });\n    elements.search.addEventListener(\"input\", handleInputChanged);\n\n    elements.disableShortcuts.addEventListener(\"change\", () => {\n        disableShortcuts = elements.disableShortcuts.checked;\n        storeValue(\"disable-shortcuts\", disableShortcuts);\n    });\n\n    document.getElementById(\"expand-all\").addEventListener(\"click\", () => toggleExpansion(true));\n    document.getElementById(\"collapse-all\").addEventListener(\"click\", () => toggleExpansion(false));\n\n    // A delegated listener to avoid the upfront cost of >1000 listeners\n    document.addEventListener(\"click\", event => {\n        if (!event.target instanceof HTMLAnchorElement) {\n            return;\n        }\n\n        if (event.target.classList.contains(\"copy-to-clipboard\")) {\n            copyToClipboard(event);\n        } else if (event.target.classList.contains(\"anchor\")) {\n            event.target.closest(\"article\")\n                .querySelector(`input[type=\"checkbox\"]`)\n                .checked = true;\n        }\n    });\n\n    document.getElementById(\"filter-clear\").addEventListener(\"click\", () => {\n        elements.search.value = \"\";\n        searchState.filterLints();\n    })\n\n    addResetListeners(\".reset-all\", true);\n    addResetListeners(\".reset-none\", false);\n    addResetListeners(\".reset-default\", null);\n\n    document.getElementById(\"reset-versions\").addEventListener(\"click\", () => {\n        for (const input of Object.values(elements.versions)) {\n            input.value = \"\";\n        }\n        filters.filterLints();\n    });\n\n    document.addEventListener(\"keypress\", handleShortcut);\n    document.addEventListener(\"keydown\", handleShortcut);\n\n    document.querySelectorAll(\".dropdown\").forEach(setupDropdown);\n\n    addEventListener(\"popstate\", parseURL);\n}\n\n// Highlight code blocks only when they approach the viewport so that clicking the \"Expand All\"\n// button doesn't take a long time\nfunction highlightLazily() {\n    if (!'IntersectionObserver' in window) {\n        return;\n    }\n    const observer = new IntersectionObserver((entries) => {\n        for (const entry of entries) {\n            if (entry.isIntersecting) {\n                observer.unobserve(entry.target);\n                for (const code of entry.target.querySelectorAll(\"pre code\")) {\n                    hljs.highlightElement(code);\n                }\n            }\n        }\n    });\n    for (const docs of document.querySelectorAll(\".lint-docs\")) {\n        observer.observe(docs);\n    }\n}\n\nfunction findCheckboxes(filter) {\n    return [...document.querySelectorAll(`.dropdown[data-filter=\"${filter}\"] input[type=\"checkbox\"]`)];\n}\n\nlet disableShortcuts = loadValue(\"disable-shortcuts\") === \"true\";\n\nconst elements = {\n    search: document.getElementById(\"search-input\"),\n    disableShortcuts: document.getElementById(\"disable-shortcuts\"),\n    checkboxes: {\n        levels: findCheckboxes(\"levels\"),\n        groups: findCheckboxes(\"groups\"),\n        applicabilities: findCheckboxes(\"applicabilities\"),\n    },\n    versions: {\n        gte: document.querySelector(`input[name=\"gte\"]`),\n        lte: document.querySelector(`input[name=\"lte\"]`),\n        eq: document.querySelector(`input[name=\"eq\"]`),\n    },\n    counts: {\n        levels: document.getElementById(\"levels-count\"),\n        groups: document.getElementById(\"groups-count\"),\n        applicabilities: document.getElementById(\"applicabilities-count\"),\n        versions: document.getElementById(\"versions-count\"),\n    },\n};\n\nelements.disableShortcuts.checked = disableShortcuts;\n\naddListeners();\nhighlightLazily();\nparseURL();\n"
  },
  {
    "path": "util/gh-pages/style.css",
    "content": "body {\n    --icon-filter: initial;\n    --label-background: #777;\n}\n\nbody.ayu {\n    --icon-filter: invert(100%);\n}\n\n* {\n    box-sizing: border-box;\n}\n\nblockquote { font-size: 1em; }\n\nh1, h2, h3, h4, h5, h6 {\n    font-family: inherit;\n    font-weight: 500;\n    line-height: 1.1;\n    color: inherit;\n}\nh1 {\n    font-size: 36px;\n}\n\na {\n    color: #337ab7;\n    text-decoration: none;\n}\n\nbutton {\n    cursor: pointer;\n    margin: 0;\n    font-family: inherit;\n    font-size: inherit;\n    line-height: inherit;\n}\n\nlabel {\n    display: inline-block;\n    max-width: 100%;\n}\n\n.dropdown-menu {\n    color: var(--fg);\n    background: var(--theme-popup-bg);\n    border: 1px solid var(--theme-popup-border);\n    border-radius: 4px;\n    position: absolute;\n    top: 100%;\n    left: 0;\n    z-index: 1000;\n    display: none;\n    float: left;\n    min-width: 160px;\n    padding: 5px 0;\n    margin: 2px 0 0;\n    font-size: 14px;\n    text-align: left;\n    list-style: none;\n    box-shadow: 0 6px 12px rgba(0,0,0,.175);\n}\n.open > .dropdown-menu {\n  display: block;\n}\n\n.dropdown-menu .divider {\n    background-color: var(--theme-popup-border);\n    height: 1px;\n    margin: 9px 0;\n    overflow: hidden;\n}\n\n.dropdown-menu .checkbox {\n    display: block;\n    white-space: nowrap;\n    margin: 0;\n}\n.dropdown-menu .checkbox label {\n    padding: 3px 20px;\n    width: 100%;\n}\n\n.dropdown-menu .checkbox input {\n    position: relative;\n    margin: 0 0.5rem 0;\n    padding: 0;\n}\n\n.dropdown-menu .checkbox:hover {\n    background-color: var(--theme-hover);\n}\n\n.checkbox label {\n    min-height: 20px;\n    margin-bottom: 0;\n    font-weight: 400;\n    cursor: pointer;\n}\n\n.container {\n    padding-right: 15px;\n    padding-left: 15px;\n    margin-right: auto;\n    margin-left: auto;\n}\n.container::before {\n    display: table;\n    content: \" \";\n}\n.container > * {\n    margin-bottom: 20px;\n    border-radius: 4px;\n    background: var(--bg);\n    border: 1px solid var(--theme-popup-border);\n    box-shadow: 0 1px 1px rgba(0,0,0,.05);\n    display: block;\n}\n\n#menu-filters {\n    padding: 15px 0;\n    display: flex;\n    flex-direction: column;\n}\n\n#menu-filters button {\n    background: var(--searchbar-bg);\n    border-color: var(--theme-popup-border);\n    color: var(--searchbar-fg);\n}\n\n#menu-filters button:hover {\n    box-shadow: 0 0 3px var(--searchbar-shadow-color);\n}\n\n#menu-filters  button.open {\n    filter: brightness(90%);\n}\n\n.row {\n    margin-right: -15px;\n    margin-left: -15px;\n}\n\n#upper-filters {\n    position: relative;\n    min-height: 1px;\n    padding-right: 15px;\n    padding-left: 15px;\n}\n\n#upper-filters > * {\n    position: relative;\n}\n\n.btn-group {\n    position: relative;\n    display: inline-block;\n}\nbutton {\n    display: inline-block;\n    padding: 6px 12px;\n    margin-bottom: 0;\n    font-size: 14px;\n    font-weight: 400;\n    line-height: 1.42857143;\n    text-align: center;\n    white-space: nowrap;\n    vertical-align: middle;\n    touch-action: manipulation;\n    cursor: pointer;\n    user-select: none;\n    border: 1px solid transparent;\n    border-radius: 4px;\n}\nbutton:hover {\n    text-decoration: none;\n}\n.badge {\n    color: #fff;\n    position: relative;\n    top: -1px;\n    display: inline-block;\n    min-width: 10px;\n    padding: 3px 7px;\n    font-size: 12px;\n    font-weight: 700;\n    line-height: 1;\n    text-align: center;\n    white-space: nowrap;\n    vertical-align: middle;\n    border-radius: 10px;\n    background-color: #777;\n}\n.btn-default:hover {\n    color: #333;\n    background-color: #e6e6e6;\n    border-color: #adadad;\n}\n.btn-default .badge {\n    color: #fff;\n}\nbutton .caret {\n    display: inline-block;\n    width: 0;\n    height: 0;\n    margin-left: 0;\n    vertical-align: middle;\n    border-top: 4px dashed;\n    border-right: 4px solid transparent;\n    border-left: 4px solid transparent;\n}\n\n.lint-title {\n    cursor: pointer;\n    margin-top: 0;\n    margin-bottom: 0;\n    font-size: 16px;\n    display: flex;\n    flex-wrap: wrap;\n    background: var(--theme-hover);\n    color: var(--fg);\n    border: 1px solid var(--theme-popup-border);\n    padding: 10px 15px;\n    border-top-left-radius: 3px;\n    border-top-right-radius: 3px;\n    gap: 4px;\n}\n\n.lint-title .label { display: inline-block; }\n\n.panel-title-name { flex: 1; min-width: 400px;}\n\n.panel-title-name .anchor {\n    display: none;\n    background-color: var(--label-background);\n}\narticle:hover .panel-title-name .anchor { display: inline;}\n\n.search-control {\n    margin-top: 15px;\n    position: relative;\n    min-height: 1px;\n    padding-right: 15px;\n    padding-left: 15px;\n    display: flex;\n}\n\n#filter-label {\n    padding: 6px 12px;\n    font-size: 14px;\n    font-weight: 400;\n    line-height: 1;\n    text-align: center;\n    border: 1px solid #ccc;\n    border-radius: 4px;\n    white-space: nowrap;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    border-right: 0;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n}\n.search-control > :last-child {\n    border-left: 0;\n}\n.btn-group > :first-child {\n    border-right: 0;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n}\n.search-control > :last-child, .btn-group > :last-child {\n    border-top-left-radius: 0;\n    border-bottom-left-radius: 0;\n}\n.search-control .form-control:not(:first-child):not(:last-child) {\n    border-radius: 0;\n}\n.form-control:focus {\n    border-color: #66afe9;\n    outline: 0;\n    box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);\n}\n\n.glyphicon.glyphicon-collapse-up::before, .glyphicon.glyphicon-collapse-down::before {\n    --background-img-size: 14px;\n    background-repeat: no-repeat;\n    background-size: var(--background-img-size);\n    height: calc(var(--background-img-size) + 6px);\n    display: block;\n    background-position: 50%;\n    content: \"\";\n    filter: var(--icon-filter);\n}\n.glyphicon.glyphicon-collapse-up:hover::before, .glyphicon.glyphicon-collapse-down:hover::before {\n    filter: initial;\n}\n.glyphicon.glyphicon-collapse-up::before {\n    /* Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -\n       https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc. */\n    background-image: url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 \\\n        448 512\"><path d=\"M64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l320 0c8.8 0 16-7.2 \\\n        16-16l0-320c0-8.8-7.2-16-16-16L64 80zM0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 \\\n        64l0 320c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96zm224 64c6.7 0 13 2.8 17.6 \\\n        7.7l104 112c6.5 7 8.2 17.2 4.4 25.9s-12.5 14.4-22 14.4l-208 0c-9.5 0-18.2-5.7-22-14.4s-2.\\\n        1-18.9 4.4-25.9l104-112c4.5-4.9 10.9-7.7 17.6-7.7z\"/></svg>');\n}\n.glyphicon.glyphicon-collapse-down::before {\n    /* Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -\n       https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc. */\n    background-image: url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" \\\n        viewBox=\"0 0 448 512\"><path d=\"M384 432c8.8 0 16-7.2 16-16l0-320c0-8.8-7.2-16-16-16L64 \\\n        80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l320 0zm64-16c0 35.3-28.7 64-64 64L64 \\\n        480c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 320zM224 \\\n        352c-6.7 0-13-2.8-17.6-7.7l-104-112c-6.5-7-8.2-17.2-4.4-25.9s12.5-14.4 22-14.4l208 0c9.5 0 \\\n        18.2 5.7 22 14.4s2.1 18.9-4.4 25.9l-104 112c-4.5 4.9-10.9 7.7-17.6 7.7z\"/></svg>');\n}\n\n.expansion-group {\n    margin-top: 15px;\n    padding: 0px 8px;\n    display: flex;\n    flex-wrap: nowrap;\n}\n\n.expansion-control {\n    width: 50%;\n}\n\n@media (min-width: 405px) {\n    #upper-filters {\n        display: flex;\n        flex-wrap: wrap;\n    }\n}\n\n@media (min-width: 768px) {\n    .container {\n        width: 750px;\n    }\n}\n\n@media (min-width: 992px) {\n    .search-control {\n        margin-top: 0;\n        align-self: flex-start;\n    }\n    .container {\n        width: 970px;\n    }\n    #upper-filters, .search-control, .expansion-group {\n        float: left;\n    }\n    #upper-filters, .search-control {\n        width: 41.66666667%;\n    }\n    .expansion-group {\n        margin-top: 0;\n        padding: 0px 15px;\n        width: 16.66666667%;\n        align-self: flex-start;\n    }\n    #menu-filters {\n        flex-direction: row;\n    }\n}\n\n@media (min-width: 1200px) {\n    .container {\n        width: 1170px;\n    }\n}\n\n@media (max-width: 430px) {\n    /* Turn the version filter list to the left */\n    #version-filter .dropdown-menu {\n        right: 0;\n        left: auto;\n    }\n}\n\n@media (max-width: 412px) {\n    #upper-filters,\n    #menu-filters .search-control  {\n        padding-right: 8px;\n        padding-left: 8px;\n    }\n}\n\n.label {\n    padding: 0.3em 0.6em;\n    font-size: 75%;\n    font-weight: 700;\n    line-height: 1;\n    color: #fff;\n    text-align: center;\n    white-space: nowrap;\n    vertical-align: baseline;\n    border-radius: .25em;\n    text-decoration: none;\n}\n\n.lint-level {\n    min-width: 4em;\n}\n.level-allow {\n    background-color: #5cb85c;\n}\n.level-warn {\n    background-color: #f0ad4e;\n}\n.level-deny {\n    background-color: #d9534f;\n}\n.level-none {\n    background-color: #777777;\n    opacity: 0.5;\n}\n\n.lint-group {\n    min-width: 8em;\n    background-color: var(--label-background);\n}\n.group-deprecated {\n    opacity: 0.5;\n}\n\n.doc-folding {\n    color: #000;\n    background-color: #fff;\n    border: 1px solid var(--theme-popup-border);\n}\n.doc-folding:hover {\n    background-color: #e6e6e6;\n}\n\n.lint-doc-md {\n    position: relative;\n    display: block;\n    padding: 10px 15px;\n    margin-bottom: -1px;\n    background: 0%;\n    border-bottom: 1px solid var(--theme-popup-border);\n    border-top: 1px solid var(--theme-popup-border);\n}\n.lint-doc-md > h3 {\n    border-top: 1px solid var(--theme-popup-border);\n    padding: 10px 15px;\n    margin: 0 -15px;\n    font-size: 18px;\n}\n.lint-doc-md > h3:first-child {\n    border-top: none;\n    padding-top: 0px;\n}\n\n@media (max-width:749px) {\n    .lint-additional-info {\n        display: flex;\n        flex-flow: column;\n    }\n    .lint-additional-info > * + * {\n        border-top: 1px solid var(--theme-popup-border);\n    }\n}\n@media (min-width:750px) {\n    .lint-additional-info {\n        display: flex;\n        flex-flow: row;\n    }\n    .lint-additional-info > * + * {\n        border-left: 1px solid var(--theme-popup-border);\n    }\n}\n\n.lint-additional-info > * {\n    display: inline-flex;\n    min-width: 200px;\n    flex-grow: 1;\n    padding: 9px 5px 5px 15px;\n}\n\n.applicability {\n    background-color: #777777;\n    margin: auto 5px;\n}\n\n.label-version {\n    background-color: #777777;\n    margin: auto 5px;\n    font-family: monospace;\n}\n\npre {\n    padding: 0;\n}\n\nsummary {\n    font-weight: bold;\n    margin: -.5em -.5em 0;\n    padding: .5em;\n    display: revert;\n}\n\n/* Expanding the mdBook theme*/\n.light, body:not([class]) {\n    --inline-code-bg: #f6f7f6;\n}\n.rust {\n    --inline-code-bg: #f6f7f6;\n}\n.coal {\n    --inline-code-bg: #1d1f21;\n}\n.navy {\n    --inline-code-bg: #1d1f21;\n}\n.ayu {\n    --inline-code-bg: #191f26;\n}\n\n@media (prefers-color-scheme: dark) {\n    body:not([class]) {\n        /*\n        In case JS is disabled and the user's system is in dark mode, we take \"coal\" as default\n        dark theme.\n        */\n        --inline-code-bg: #1d1f21;\n    }\n}\n\nhtml:not(.js) #settings-dropdown,\nhtml:not(.js) #menu-filters {\n    display: none;\n}\n\n#settings-dropdown {\n    position: absolute;\n    margin: 0.7em;\n    z-index: 10;\n    display: flex;\n}\n\n/* Applying the mdBook theme */\n.settings-icon {\n    text-align: center;\n    width: 2em;\n    height: 2em;\n    line-height: 2em;\n    border: solid 1px var(--icons);\n    border-radius: 5px;\n    user-select: none;\n    cursor: pointer;\n    background: var(--theme-hover);\n}\n.settings-menu {\n    display: none;\n    list-style: none;\n    border: 1px solid var(--theme-popup-border);\n    border-radius: 5px;\n    color: var(--fg);\n    background: var(--theme-popup-bg);\n    overflow: hidden;\n    padding: 9px;\n    width: 207px;\n    position: absolute;\n    top: 28px;\n}\n\n.settings-icon::before {\n    /* Wheel <https://www.svgrepo.com/svg/384069/settings-cog-gear> */\n    content: url('data:image/svg+xml,<svg width=\"18\" height=\"18\" viewBox=\"0 0 12 12\" \\\nenable-background=\"new 0 0 12 12\" xmlns=\"http://www.w3.org/2000/svg\">\\\n<path d=\"M10.25,6c0-0.1243286-0.0261841-0.241333-0.0366211-0.362915l1.6077881-1.5545654l\\\n-1.25-2.1650391  c0,0-1.2674561,0.3625488-2.1323853,0.6099854c-0.2034912-0.1431885-0.421875\\\n-0.2639771-0.6494751-0.3701782L7.25,0h-2.5 c0,0-0.3214111,1.2857666-0.5393066,2.1572876\\\nC3.9830933,2.2634888,3.7647095,2.3842773,3.5612183,2.5274658L1.428833,1.9174805 \\\nl-1.25,2.1650391c0,0,0.9641113,0.9321899,1.6077881,1.5545654C1.7761841,5.758667,\\\n1.75,5.8756714,1.75,6  s0.0261841,0.241333,0.0366211,0.362915L0.178833,7.9174805l1.25,\\\n2.1650391l2.1323853-0.6099854  c0.2034912,0.1432495,0.421875,0.2639771,0.6494751,0.3701782\\\nL4.75,12h2.5l0.5393066-2.1572876  c0.2276001-0.1062012,0.4459839-0.2269287,0.6494751\\\n-0.3701782l2.1323853,0.6099854l1.25-2.1650391L10.2133789,6.362915  C10.2238159,6.241333,\\\n10.25,6.1243286,10.25,6z M6,7.5C5.1715698,7.5,4.5,6.8284302,4.5,6S5.1715698,4.5,6,4.5S7.5\\\n,5.1715698,7.5,6  S6.8284302,7.5,6,7.5z\" fill=\"black\"/></svg>');\n    width: 18px;\n    height: 18px;\n    display: block;\n    filter: invert(0.7);\n    position: absolute;\n    top: 4px;\n    left: 5px;\n}\n\n.settings-menu * {\n    font-weight: normal;\n}\n\n.settings-menu label {\n    cursor: pointer;\n}\n\n#settings-dropdown.open .settings-menu {\n    display: block;\n}\n\n#theme-choice {\n    margin-bottom: 10px;\n    background: var(--searchbar-bg);\n    color: var(--searchbar-fg);\n    border-color: var(--theme-popup-border);\n    border-radius: 5px;\n    cursor: pointer;\n    width: 100%;\n    border-width: 1px;\n    padding: 5px;\n}\n\n.alert {\n    color: var(--fg);\n    background: var(--theme-hover);\n    border: 1px solid var(--theme-popup-border);\n    padding: 8px;\n}\n.page-header {\n    border: 0;\n    border-bottom: 1px solid var(--theme-popup-border);\n    padding-bottom: 19px;\n    border-radius: 0;\n    margin: 40px 0 20px;\n}\npre, hr {\n    background: var(--bg);\n    border: 1px solid var(--theme-popup-border);\n}\n\n#version-filter .checkbox {\n    display: flex;\n}\n\n#menu-filters ul.dropdown-menu li.checkbox > button {\n    border: 0;\n    width: 100%;\n    background: var(--theme-popup-bg);\n    color: var(--fg);\n}\n\n#menu-filters ul.dropdown-menu li.checkbox > button:hover {\n    background: var(--theme-hover);\n    box-shadow: none;\n}\n\n#version-filter {\n    min-width: available;\n}\n\n#version-filter li label {\n    padding-right: 0;\n    width: 35%;\n}\n\n.version-filter-input {\n    height: 60%;\n    width: 30%;\n    text-align: center;\n    border: none;\n    border-bottom: 1px solid #000000;\n}\n\n#filter-label, #filter-clear {\n    background: var(--searchbar-bg);\n    color: var(--searchbar-fg);\n    border-color: var(--theme-popup-border);\n    filter: brightness(95%);\n}\n#filter-label:hover, #filter-clear:hover {\n    filter: brightness(90%);\n}\n.filter-input {\n    background: var(--searchbar-bg);\n    color: var(--searchbar-fg);\n    position: relative;\n    width: 100%;\n    margin-bottom: 0;\n    height: 34px;\n    padding: 6px 12px;\n    font-size: 14px;\n    line-height: 1.42857143;\n    border: 1px solid var(--theme-popup-border);\n    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);\n    transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;\n}\n\n.filter-input::-webkit-input-placeholder,\n.filter-input::-moz-placeholder {\n    color: var(--searchbar-fg);\n    opacity: 30%;\n}\n\n:not(pre) > code {\n    color: var(--inline-code-color);\n    background-color: var(--inline-code-bg);\n}\nhtml {\n    scrollbar-color: var(--scrollbar) var(--bg);\n}\nbody {\n    background: var(--bg);\n    color: var(--fg);\n    font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n    font-size: 14px;\n    line-height: 1.42857143;\n    margin: 0;\n}\n\narticle > label {\n    width: 100%;\n    margin: 0;\n}\narticle > input[type=\"checkbox\"] {\n    display: none;\n}\narticle > input[type=\"checkbox\"] + label .doc-folding::before {\n    content: \"+\";\n}\narticle > input[type=\"checkbox\"]:checked + label .doc-folding::before {\n    content: \"−\";\n}\n.lint-docs {\n    display: none;\n    margin-bottom: 0;\n}\narticle > input[type=\"checkbox\"]:checked ~ .lint-docs {\n    display: block;\n}\n\n.github-corner svg {\n    fill: var(--fg);\n    color: var(--bg);\n}\n.github-corner:hover .octo-arm {\n    animation: octocat-wave 560ms ease-in-out;\n}\n@keyframes octocat-wave {\n    0%,\n    100% {\n        transform: rotate(0);\n    }\n    20%,\n    60% {\n        transform: rotate(-25deg);\n    }\n    40%,\n    80% {\n        transform: rotate(10deg);\n    }\n}\n@media (max-width: 500px) {\n    .github-corner:hover .octo-arm {\n        animation: none;\n    }\n    .github-corner .octo-arm {\n        animation: octocat-wave 560ms ease-in-out;\n    }\n}\n"
  },
  {
    "path": "util/gh-pages/theme.js",
    "content": "\"use strict\";\n\nfunction storeValue(settingName, value) {\n    try {\n        localStorage.setItem(`clippy-lint-list-${settingName}`, value);\n    } catch (e) { }\n}\n\nfunction loadValue(settingName) {\n    return localStorage.getItem(`clippy-lint-list-${settingName}`);\n}\n\nfunction setTheme(theme, store) {\n    let enableHighlight = false;\n    let enableNight = false;\n    let enableAyu = false;\n\n    switch(theme) {\n        case \"ayu\":\n            enableAyu = true;\n            break;\n        case \"coal\":\n        case \"navy\":\n            enableNight = true;\n            break;\n        case \"rust\":\n            enableHighlight = true;\n            break;\n        default:\n            enableHighlight = true;\n            theme = \"light\";\n            break;\n    }\n\n    document.body.className = theme;\n\n    document.getElementById(\"githubLightHighlight\").disabled = enableNight || !enableHighlight;\n    document.getElementById(\"githubDarkHighlight\").disabled = !enableNight && !enableAyu;\n\n    document.getElementById(\"styleHighlight\").disabled = !enableHighlight;\n    document.getElementById(\"styleNight\").disabled = !enableNight;\n    document.getElementById(\"styleAyu\").disabled = !enableAyu;\n\n    if (store) {\n        storeValue(\"theme\", theme);\n    }\n}\n\n(function() {\n    // This file is loaded first. If so, we add the `js` class on the `<html>`\n    // element.\n    document.documentElement.classList.add(\"js\");\n\n    // loading the theme after the initial load\n    const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\");\n    const theme = loadValue(\"theme\");\n    if (prefersDark.matches && !theme) {\n        setTheme(\"coal\", false);\n    } else {\n        setTheme(theme, false);\n    }\n\n    const themeChoice = document.getElementById(\"theme-choice\");\n\n    themeChoice.value = loadValue(\"theme\");\n    document.getElementById(\"theme-choice\").addEventListener(\"change\", (e) => {\n        setTheme(themeChoice.value, true);\n    });\n})();\n"
  },
  {
    "path": "util/gh-pages/versions.html",
    "content": "<!DOCTYPE html>\n<!-- Expanded by util/versions.py into the HTML file seen at https://rust-lang.github.io/rust-clippy/ -->\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\"/>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n\n    <title>Clippy lints documentation</title>\n\n    <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css\"/>\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"page-header\">\n            <h1>Clippy lints documentation</h1>\n        </div>\n\n        <div>\n            <article class=\"panel panel-default\">\n                <div class=\"panel-heading\">\n                    <h3 class=\"panel-title\">\n                        Available versions\n                    </h3>\n                </div>\n\n                <ul class=\"list-group\">\n                    $list\n                </ul>\n            </article>\n        </div>\n    </div>\n\n    <a\n        aria-label=\"View source on GitHub\"\n        class=\"github-corner\"\n        href=\"https://github.com/rust-lang/rust-clippy\"\n        rel=\"noopener noreferrer\"\n        target=\"_blank\"\n    >\n        <svg\n            width=\"80\"\n            height=\"80\"\n            viewBox=\"0 0 250 250\"\n            style=\"position: absolute; top: 0; border: 0; right: 0\"\n            aria-hidden=\"true\"\n        >\n            <path d=\"M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z\" fill=\"var(--theme-color)\"></path>\n            <path\n                d=\"M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2\"\n                fill=\"currentColor\"\n                style=\"transform-origin: 130px 106px\"\n                class=\"octo-arm\"\n            ></path>\n            <path\n                d=\"M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z\"\n                fill=\"currentColor\"\n                class=\"octo-body\"\n            ></path>\n        </svg>\n        <style>\n            .github-corner svg {\n                fill: black;\n                color: white;\n            }\n            .github-corner:hover .octo-arm {\n                animation: octocat-wave 560ms ease-in-out;\n            }\n            @keyframes octocat-wave {\n                0%,\n                100% {\n                    transform: rotate(0);\n                }\n                20%,\n                60% {\n                    transform: rotate(-25deg);\n                }\n                40%,\n                80% {\n                    transform: rotate(10deg);\n                }\n            }\n            @media (max-width: 500px) {\n                .github-corner:hover .octo-arm {\n                    animation: none;\n                }\n                .github-corner .octo-arm {\n                    animation: octocat-wave 560ms ease-in-out;\n                }\n            }\n        </style>\n    </a>\n</body>\n</html>\n"
  },
  {
    "path": "util/versions.py",
    "content": "#!/usr/bin/env python\n\nfrom string import Template\nimport argparse\nimport os\nimport sys\n\ndef key(v):\n    if v == \"stable\":\n        return sys.maxsize \n    if v == \"beta\":\n        return sys.maxsize - 1\n    if v == \"master\":\n        return sys.maxsize - 2\n    if v == \"pre-1.29.0\":\n        return -1\n    if not v.startswith(\"rust-\"):\n        return None\n\n    v = v.replace(\"rust-\", \"\")\n\n    s = 0\n    for i, val in enumerate(v.split(\".\")[::-1]):\n        s += int(val) * 100**i\n\n    return s\n\ndef main():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\"input\", help=\"path to the versions.html template\", type=argparse.FileType(\"r\"))\n    parser.add_argument(\"outdir\", help=\"path to write the output HTML\")\n    args = parser.parse_args()\n\n    versions = [\n        dir\n        for dir in os.listdir(args.outdir)\n        if key(dir) is not None\n    ]\n    versions.sort(key=key, reverse=True)\n    links = [f'<a class=\"list-group-item\" href=\"./{version}/index.html\">{version}</a>' for version in versions]\n\n    template = Template(args.input.read())\n    html = template.substitute(list=\"\\n\".join(links))\n\n    path = os.path.join(args.outdir, \"index.html\")\n    with open(path, \"w\") as out:\n        out.write(html)\n        print(f\"wrote HTML to {path}\")\n\nif __name__ == \"__main__\":\n    main()\n"
  }
]